aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAlexey Efimov <xeno@prnwatch.com>2022-02-10 16:49:42 +0300
committerDaniil Cherednik <dcherednik@yandex-team.ru>2022-02-10 16:49:42 +0300
commit0fd1998e1b2369f50fb694556f817d3c7fef10c8 (patch)
tree5d5cb817648f650d76cf1076100726fd9b8448e8
parent26e0e4fb5e5cd6b4d7f4c21f9fcd7978891bf946 (diff)
downloadydb-0fd1998e1b2369f50fb694556f817d3c7fef10c8.tar.gz
Restoring authorship annotation for Alexey Efimov <xeno@prnwatch.com>. Commit 2 of 2.
-rw-r--r--build/rules/kikimr.policy4
-rw-r--r--library/cpp/actors/core/actor.h2
-rw-r--r--library/cpp/actors/core/actorsystem.h8
-rw-r--r--library/cpp/actors/core/event_local.h2
-rw-r--r--library/cpp/actors/core/event_pb.h104
-rw-r--r--library/cpp/actors/core/executor_pool_base.cpp8
-rw-r--r--library/cpp/actors/core/executor_pool_base.h2
-rw-r--r--library/cpp/actors/core/interconnect.h24
-rw-r--r--library/cpp/actors/core/log.cpp10
-rw-r--r--library/cpp/actors/core/mon.h40
-rw-r--r--library/cpp/actors/core/process_stats.cpp68
-rw-r--r--library/cpp/actors/core/process_stats.h102
-rw-r--r--library/cpp/actors/helpers/future_callback.h62
-rw-r--r--library/cpp/actors/helpers/ya.make2
-rw-r--r--library/cpp/actors/http/http.cpp1188
-rw-r--r--library/cpp/actors/http/http.h1394
-rw-r--r--library/cpp/actors/http/http_cache.cpp1178
-rw-r--r--library/cpp/actors/http/http_cache.h50
-rw-r--r--library/cpp/actors/http/http_config.h34
-rw-r--r--library/cpp/actors/http/http_proxy.cpp564
-rw-r--r--library/cpp/actors/http/http_proxy.h424
-rw-r--r--library/cpp/actors/http/http_proxy_acceptor.cpp210
-rw-r--r--library/cpp/actors/http/http_proxy_incoming.cpp376
-rw-r--r--library/cpp/actors/http/http_proxy_outgoing.cpp450
-rw-r--r--library/cpp/actors/http/http_proxy_sock_impl.h472
-rw-r--r--library/cpp/actors/http/http_proxy_ssl.h148
-rw-r--r--library/cpp/actors/http/http_static.cpp176
-rw-r--r--library/cpp/actors/http/http_static.h16
-rw-r--r--library/cpp/actors/http/http_ut.cpp632
-rw-r--r--library/cpp/actors/http/ut/ya.make26
-rw-r--r--library/cpp/actors/http/ya.make56
-rw-r--r--library/cpp/actors/interconnect/interconnect_common.h6
-rw-r--r--library/cpp/actors/interconnect/interconnect_tcp_server.cpp6
-rw-r--r--library/cpp/actors/protos/interconnect.proto4
-rw-r--r--library/cpp/actors/testlib/test_runtime.cpp272
-rw-r--r--library/cpp/actors/testlib/test_runtime.h120
-rw-r--r--library/cpp/grpc/client/grpc_client_low.h190
-rw-r--r--library/cpp/http/fetch/httpagent.h630
-rw-r--r--library/cpp/http/fetch/sockhandler.h260
-rw-r--r--library/cpp/http/io/stream.cpp18
-rw-r--r--library/cpp/http/ya.make2
-rw-r--r--library/cpp/messagebus/message.h4
-rw-r--r--library/cpp/monlib/service/mon_service_http_request.cpp74
-rw-r--r--library/cpp/monlib/service/mon_service_http_request.h6
-rw-r--r--library/cpp/monlib/service/monservice.cpp16
-rw-r--r--library/cpp/monlib/service/monservice.h20
-rw-r--r--library/cpp/monlib/service/pages/index_mon_page.cpp22
-rw-r--r--library/cpp/monlib/service/pages/index_mon_page.h2
-rw-r--r--library/cpp/monlib/service/pages/templates.h28
-rw-r--r--library/cpp/monlib/service/service.cpp70
-rw-r--r--library/cpp/monlib/service/service.h6
-rw-r--r--library/cpp/threading/future/core/future-inl.h22
-rw-r--r--library/cpp/threading/future/future_ut.cpp14
-rw-r--r--util/network/address.cpp20
-rw-r--r--util/network/address.h2
-rw-r--r--util/network/sock.h16
-rw-r--r--ydb/core/actorlib_impl/node_identifier.cpp308
-rw-r--r--ydb/core/actorlib_impl/node_identifier.h20
-rw-r--r--ydb/core/actorlib_impl/ya.make2
-rw-r--r--ydb/core/base/appdata.cpp10
-rw-r--r--ydb/core/base/appdata.h32
-rw-r--r--ydb/core/base/blobstorage.h118
-rw-r--r--ydb/core/base/channel_profiles.h18
-rw-r--r--ydb/core/base/events.h22
-rw-r--r--ydb/core/base/hive.h616
-rw-r--r--ydb/core/base/localdb.cpp14
-rw-r--r--ydb/core/base/localdb.h34
-rw-r--r--ydb/core/base/pathid.h18
-rw-r--r--ydb/core/base/pool_stats_collector.cpp6
-rw-r--r--ydb/core/base/statestorage.cpp8
-rw-r--r--ydb/core/base/statestorage.h124
-rw-r--r--ydb/core/base/statestorage_impl.h32
-rw-r--r--ydb/core/base/statestorage_proxy.cpp188
-rw-r--r--ydb/core/base/statestorage_replica.cpp40
-rw-r--r--ydb/core/base/storage_pools.h2
-rw-r--r--ydb/core/base/subdomain.h10
-rw-r--r--ydb/core/base/tablet.h80
-rw-r--r--ydb/core/base/tablet_killer.cpp72
-rw-r--r--ydb/core/base/tablet_pipe.h80
-rw-r--r--ydb/core/base/tablet_status_checker.cpp2
-rw-r--r--ydb/core/base/tablet_types.h58
-rw-r--r--ydb/core/base/tabletid.h8
-rw-r--r--ydb/core/base/ticket_parser.h260
-rw-r--r--ydb/core/blobstorage/base/html.cpp10
-rw-r--r--ydb/core/blobstorage/base/html.h2
-rw-r--r--ydb/core/blobstorage/dsproxy/dsproxy_get_impl.cpp2
-rw-r--r--ydb/core/blobstorage/dsproxy/dsproxy_mon.cpp4
-rw-r--r--ydb/core/blobstorage/nodewarden/blobstorage_node_warden_ut.cpp50
-rw-r--r--ydb/core/blobstorage/nodewarden/node_warden.h2
-rw-r--r--ydb/core/blobstorage/nodewarden/node_warden_impl.cpp6
-rw-r--r--ydb/core/blobstorage/pdisk/blobstorage_pdisk_actor.cpp8
-rw-r--r--ydb/core/blobstorage/pdisk/blobstorage_pdisk_impl.cpp10
-rw-r--r--ydb/core/blobstorage/pdisk/blobstorage_pdisk_internal_interface.cpp2
-rw-r--r--ydb/core/blobstorage/pdisk/blobstorage_pdisk_mon.h4
-rw-r--r--ydb/core/blobstorage/pdisk/blobstorage_pdisk_ut_http_request.h8
-rw-r--r--ydb/core/blobstorage/pdisk/blobstorage_pdisk_ut_run.cpp8
-rw-r--r--ydb/core/blobstorage/ut_vdisk/lib/astest.h8
-rw-r--r--ydb/core/blobstorage/ut_vdisk/lib/prepare.cpp8
-rw-r--r--ydb/core/blobstorage/vdisk/common/vdisk_config.cpp32
-rw-r--r--ydb/core/blobstorage/vdisk/common/vdisk_config.h6
-rw-r--r--ydb/core/blobstorage/vdisk/hulldb/base/blobstorage_hullsatisfactionrank.cpp4
-rw-r--r--ydb/core/blobstorage/vdisk/hulldb/base/blobstorage_hullsatisfactionrank.h8
-rw-r--r--ydb/core/blobstorage/vdisk/skeleton/blobstorage_skeleton.cpp10
-rw-r--r--ydb/core/client/client_ut.cpp44
-rw-r--r--ydb/core/client/flat_ut.cpp136
-rw-r--r--ydb/core/client/flat_ut_client.h46
-rw-r--r--ydb/core/client/minikql_compile/mkql_compile_service.cpp6
-rw-r--r--ydb/core/client/minikql_result_lib/converter.cpp4
-rw-r--r--ydb/core/client/minikql_result_lib/converter.h4
-rw-r--r--ydb/core/client/minikql_result_lib/converter_ut.cpp4
-rw-r--r--ydb/core/client/minikql_result_lib/objects.h4
-rw-r--r--ydb/core/client/minikql_result_lib/objects_ut.cpp2
-rw-r--r--ydb/core/client/server/grpc_server.cpp10
-rw-r--r--ydb/core/client/server/http_ping.cpp40
-rw-r--r--ydb/core/client/server/http_ping.h28
-rw-r--r--ydb/core/client/server/msgbus_bsadm.cpp22
-rw-r--r--ydb/core/client/server/msgbus_http_server.cpp402
-rw-r--r--ydb/core/client/server/msgbus_http_server.h66
-rw-r--r--ydb/core/client/server/msgbus_securereq.h204
-rw-r--r--ydb/core/client/server/msgbus_server.cpp230
-rw-r--r--ydb/core/client/server/msgbus_server.h322
-rw-r--r--ydb/core/client/server/msgbus_server_cms.cpp24
-rw-r--r--ydb/core/client/server/msgbus_server_console.cpp32
-rw-r--r--ydb/core/client/server/msgbus_server_db.cpp1772
-rw-r--r--ydb/core/client/server/msgbus_server_drain_node.cpp112
-rw-r--r--ydb/core/client/server/msgbus_server_fill_node.cpp112
-rw-r--r--ydb/core/client/server/msgbus_server_hive_create_tablet.cpp142
-rw-r--r--ydb/core/client/server/msgbus_server_keyvalue.cpp28
-rw-r--r--ydb/core/client/server/msgbus_server_local_enumerate_tablets.cpp36
-rw-r--r--ydb/core/client/server/msgbus_server_local_minikql.cpp10
-rw-r--r--ydb/core/client/server/msgbus_server_local_scheme_tx.cpp10
-rw-r--r--ydb/core/client/server/msgbus_server_node_registration.cpp2
-rw-r--r--ydb/core/client/server/msgbus_server_pq_metarequest.cpp2
-rw-r--r--ydb/core/client/server/msgbus_server_proxy.cpp154
-rw-r--r--ydb/core/client/server/msgbus_server_proxy.h160
-rw-r--r--ydb/core/client/server/msgbus_server_request.cpp172
-rw-r--r--ydb/core/client/server/msgbus_server_request.h62
-rw-r--r--ydb/core/client/server/msgbus_server_resolve_node.cpp170
-rw-r--r--ydb/core/client/server/msgbus_server_scheme_initroot.cpp122
-rw-r--r--ydb/core/client/server/msgbus_server_scheme_request.cpp308
-rw-r--r--ydb/core/client/server/msgbus_server_tablet_kill.cpp54
-rw-r--r--ydb/core/client/server/msgbus_server_tablet_state.cpp254
-rw-r--r--ydb/core/client/server/msgbus_server_tracer.cpp424
-rw-r--r--ydb/core/client/server/msgbus_server_tracer.h164
-rw-r--r--ydb/core/client/server/msgbus_server_tx_request.cpp92
-rw-r--r--ydb/core/client/server/msgbus_server_types.cpp6
-rw-r--r--ydb/core/client/server/msgbus_server_whoami.cpp106
-rw-r--r--ydb/core/client/server/msgbus_servicereq.h8
-rw-r--r--ydb/core/client/server/msgbus_tabletreq.h6
-rw-r--r--ydb/core/client/server/ya.make36
-rw-r--r--ydb/core/cms/cluster_info.h4
-rw-r--r--ydb/core/cms/cluster_info_ut.cpp6
-rw-r--r--ydb/core/cms/cms.h42
-rw-r--r--ydb/core/cms/console/console.cpp2
-rw-r--r--ydb/core/cms/console/console__create_tenant.cpp8
-rw-r--r--ydb/core/cms/console/console__scheme.h6
-rw-r--r--ydb/core/cms/console/console_tenants_manager.cpp22
-rw-r--r--ydb/core/cms/console/console_tenants_manager.h8
-rw-r--r--ydb/core/cms/console/console_ut_tenants.cpp2
-rw-r--r--ydb/core/cms/http.cpp2
-rw-r--r--ydb/core/cms/json_proxy.h2
-rw-r--r--ydb/core/cms/sentinel.cpp2
-rw-r--r--ydb/core/cms/walle_api_handler.cpp8
-rw-r--r--ydb/core/control/immediate_control_board_actor_ut.cpp18
-rw-r--r--ydb/core/control/ut/ya.make2
-rw-r--r--ydb/core/driver_lib/cli_base/cli_cmds_db.cpp940
-rw-r--r--ydb/core/driver_lib/cli_base/cli_cmds_whoami.cpp80
-rw-r--r--ydb/core/driver_lib/cli_base/cli_kicli.cpp4
-rw-r--r--ydb/core/driver_lib/cli_base/cli_kicli.h6
-rw-r--r--ydb/core/driver_lib/cli_config_base/config_base.cpp50
-rw-r--r--ydb/core/driver_lib/cli_config_base/config_base.h22
-rw-r--r--ydb/core/driver_lib/cli_utils/cli.h2
-rw-r--r--ydb/core/driver_lib/cli_utils/cli_cmd_config.cpp32
-rw-r--r--ydb/core/driver_lib/cli_utils/cli_cmds.h68
-rw-r--r--ydb/core/driver_lib/cli_utils/cli_cmds_admin.cpp26
-rw-r--r--ydb/core/driver_lib/cli_utils/cli_cmds_bs.cpp32
-rw-r--r--ydb/core/driver_lib/cli_utils/cli_cmds_debug.cpp22
-rw-r--r--ydb/core/driver_lib/cli_utils/cli_cmds_disk.cpp272
-rw-r--r--ydb/core/driver_lib/cli_utils/cli_cmds_group.cpp38
-rw-r--r--ydb/core/driver_lib/cli_utils/cli_cmds_node.cpp192
-rw-r--r--ydb/core/driver_lib/cli_utils/cli_cmds_root.cpp50
-rw-r--r--ydb/core/driver_lib/cli_utils/cli_cmds_server.cpp268
-rw-r--r--ydb/core/driver_lib/cli_utils/cli_cmds_tablet.cpp398
-rw-r--r--ydb/core/driver_lib/cli_utils/cli_mb_trace.cpp178
-rw-r--r--ydb/core/driver_lib/cli_utils/ya.make20
-rw-r--r--ydb/core/driver_lib/run/config.h6
-rw-r--r--ydb/core/driver_lib/run/config_parser.cpp46
-rw-r--r--ydb/core/driver_lib/run/config_parser.h4
-rw-r--r--ydb/core/driver_lib/run/driver.h16
-rw-r--r--ydb/core/driver_lib/run/dummy.cpp16
-rw-r--r--ydb/core/driver_lib/run/dummy.h2
-rw-r--r--ydb/core/driver_lib/run/factories.h4
-rw-r--r--ydb/core/driver_lib/run/kikimr_services_initializers.cpp154
-rw-r--r--ydb/core/driver_lib/run/kikimr_services_initializers.h58
-rw-r--r--ydb/core/driver_lib/run/main.cpp32
-rw-r--r--ydb/core/driver_lib/run/run.cpp318
-rw-r--r--ydb/core/driver_lib/run/run.h8
-rw-r--r--ydb/core/engine/mkql_engine_flat_host_ut.cpp26
-rw-r--r--ydb/core/engine/mkql_engine_flat_ut.cpp20
-rw-r--r--ydb/core/engine/mkql_proto.cpp34
-rw-r--r--ydb/core/grpc_services/base/base.h86
-rw-r--r--ydb/core/grpc_services/grpc_endpoint.h54
-rw-r--r--ydb/core/grpc_services/grpc_endpoint_publish_actor.cpp302
-rw-r--r--ydb/core/grpc_services/grpc_proxy_counters.h92
-rw-r--r--ydb/core/grpc_services/grpc_publisher_service_actor.cpp110
-rw-r--r--ydb/core/grpc_services/grpc_request_check_actor.h608
-rw-r--r--ydb/core/grpc_services/grpc_request_proxy.cpp850
-rw-r--r--ydb/core/grpc_services/grpc_request_proxy.h8
-rw-r--r--ydb/core/grpc_services/local_rate_limiter.cpp4
-rw-r--r--ydb/core/grpc_services/operation_helpers.cpp16
-rw-r--r--ydb/core/grpc_services/rpc_calls.h2
-rw-r--r--ydb/core/grpc_services/rpc_cms.cpp2
-rw-r--r--ydb/core/grpc_services/rpc_describe_path.cpp2
-rw-r--r--ydb/core/grpc_services/rpc_describe_table.cpp2
-rw-r--r--ydb/core/grpc_services/rpc_get_shard_locations.cpp8
-rw-r--r--ydb/core/grpc_services/rpc_login.cpp224
-rw-r--r--ydb/core/grpc_services/rpc_monitoring.cpp148
-rw-r--r--ydb/core/grpc_services/rpc_operation_request_base.h2
-rw-r--r--ydb/core/grpc_services/rpc_rate_limiter_api.cpp6
-rw-r--r--ydb/core/grpc_services/rpc_whoami.cpp18
-rw-r--r--ydb/core/grpc_services/ya.make10
-rw-r--r--ydb/core/health_check/health_check.cpp3768
-rw-r--r--ydb/core/health_check/health_check.h64
-rw-r--r--ydb/core/health_check/health_check_ut.cpp66
-rw-r--r--ydb/core/health_check/ut/ya.make32
-rw-r--r--ydb/core/health_check/ya.make32
-rw-r--r--ydb/core/keyvalue/keyvalue_flat_impl.h8
-rw-r--r--ydb/core/keyvalue/keyvalue_intermediate.h2
-rw-r--r--ydb/core/keyvalue/keyvalue_request_stat.h4
-rw-r--r--ydb/core/keyvalue/keyvalue_state.cpp56
-rw-r--r--ydb/core/keyvalue/keyvalue_state.h20
-rw-r--r--ydb/core/keyvalue/keyvalue_storage_request.cpp6
-rw-r--r--ydb/core/kqp/counters/kqp_counters.cpp2
-rw-r--r--ydb/core/kqp/kqp_ic_gateway.cpp2
-rw-r--r--ydb/core/kqp/provider/yql_kikimr_gateway_ut.cpp2
-rw-r--r--ydb/core/mind/bscontroller/impl.h2
-rw-r--r--ydb/core/mind/bscontroller/load_everything.cpp4
-rw-r--r--ydb/core/mind/bscontroller/monitoring.cpp6
-rw-r--r--ydb/core/mind/bscontroller/ut/ya.make2
-rw-r--r--ydb/core/mind/dynamic_nameserver.cpp10
-rw-r--r--ydb/core/mind/hive/balancer.cpp654
-rw-r--r--ydb/core/mind/hive/balancer.h30
-rw-r--r--ydb/core/mind/hive/boot_queue.cpp56
-rw-r--r--ydb/core/mind/hive/boot_queue.h114
-rw-r--r--ydb/core/mind/hive/domain_info.h28
-rw-r--r--ydb/core/mind/hive/drain.cpp422
-rw-r--r--ydb/core/mind/hive/fill.cpp268
-rw-r--r--ydb/core/mind/hive/follower_group.h78
-rw-r--r--ydb/core/mind/hive/follower_tablet_info.cpp18
-rw-r--r--ydb/core/mind/hive/follower_tablet_info.h30
-rw-r--r--ydb/core/mind/hive/hive.cpp132
-rw-r--r--ydb/core/mind/hive/hive.h226
-rw-r--r--ydb/core/mind/hive/hive_domains.cpp164
-rw-r--r--ydb/core/mind/hive/hive_domains.h96
-rw-r--r--ydb/core/mind/hive/hive_events.h160
-rw-r--r--ydb/core/mind/hive/hive_impl.cpp4442
-rw-r--r--ydb/core/mind/hive/hive_impl.h1372
-rw-r--r--ydb/core/mind/hive/hive_impl_ut.cpp318
-rw-r--r--ydb/core/mind/hive/hive_log.cpp26
-rw-r--r--ydb/core/mind/hive/hive_log.h78
-rw-r--r--ydb/core/mind/hive/hive_schema.h540
-rw-r--r--ydb/core/mind/hive/hive_statics.cpp684
-rw-r--r--ydb/core/mind/hive/hive_transactions.h22
-rw-r--r--ydb/core/mind/hive/hive_ut.cpp4844
-rw-r--r--ydb/core/mind/hive/leader_tablet_info.cpp430
-rw-r--r--ydb/core/mind/hive/leader_tablet_info.h506
-rw-r--r--ydb/core/mind/hive/metrics.h34
-rw-r--r--ydb/core/mind/hive/monitoring.cpp6064
-rw-r--r--ydb/core/mind/hive/node_info.cpp816
-rw-r--r--ydb/core/mind/hive/node_info.h496
-rw-r--r--ydb/core/mind/hive/sequencer.cpp360
-rw-r--r--ydb/core/mind/hive/sequencer.h262
-rw-r--r--ydb/core/mind/hive/sequencer_ut.cpp130
-rw-r--r--ydb/core/mind/hive/storage_group_info.cpp216
-rw-r--r--ydb/core/mind/hive/storage_group_info.h80
-rw-r--r--ydb/core/mind/hive/storage_pool_info.cpp346
-rw-r--r--ydb/core/mind/hive/storage_pool_info.h156
-rw-r--r--ydb/core/mind/hive/storage_pool_info_ut.cpp450
-rw-r--r--ydb/core/mind/hive/tablet_info.cpp862
-rw-r--r--ydb/core/mind/hive/tablet_info.h516
-rw-r--r--ydb/core/mind/hive/tx__adopt_tablet.cpp34
-rw-r--r--ydb/core/mind/hive/tx__block_storage_result.cpp114
-rw-r--r--ydb/core/mind/hive/tx__configure_subdomain.cpp88
-rw-r--r--ydb/core/mind/hive/tx__create_tablet.cpp764
-rw-r--r--ydb/core/mind/hive/tx__cut_tablet_history.cpp90
-rw-r--r--ydb/core/mind/hive/tx__delete_tablet.cpp282
-rw-r--r--ydb/core/mind/hive/tx__delete_tablet_result.cpp124
-rw-r--r--ydb/core/mind/hive/tx__disconnect_node.cpp100
-rw-r--r--ydb/core/mind/hive/tx__init_scheme.cpp160
-rw-r--r--ydb/core/mind/hive/tx__kill_node.cpp140
-rw-r--r--ydb/core/mind/hive/tx__load_everything.cpp1094
-rw-r--r--ydb/core/mind/hive/tx__lock_tablet.cpp28
-rw-r--r--ydb/core/mind/hive/tx__process_boot_queue.cpp58
-rw-r--r--ydb/core/mind/hive/tx__process_pending_operations.cpp78
-rw-r--r--ydb/core/mind/hive/tx__reassign_groups.cpp142
-rw-r--r--ydb/core/mind/hive/tx__register_node.cpp152
-rw-r--r--ydb/core/mind/hive/tx__release_tablets.cpp168
-rw-r--r--ydb/core/mind/hive/tx__release_tablets_reply.cpp238
-rw-r--r--ydb/core/mind/hive/tx__request_tablet_seq.cpp146
-rw-r--r--ydb/core/mind/hive/tx__response_tablet_seq.cpp134
-rw-r--r--ydb/core/mind/hive/tx__restart_tablet.cpp120
-rw-r--r--ydb/core/mind/hive/tx__resume_tablet.cpp174
-rw-r--r--ydb/core/mind/hive/tx__seize_tablets.cpp288
-rw-r--r--ydb/core/mind/hive/tx__seize_tablets_reply.cpp290
-rw-r--r--ydb/core/mind/hive/tx__start_tablet.cpp154
-rw-r--r--ydb/core/mind/hive/tx__status.cpp122
-rw-r--r--ydb/core/mind/hive/tx__stop_tablet.cpp170
-rw-r--r--ydb/core/mind/hive/tx__switch_drain.cpp226
-rw-r--r--ydb/core/mind/hive/tx__sync_tablets.cpp204
-rw-r--r--ydb/core/mind/hive/tx__unlock_tablet.cpp38
-rw-r--r--ydb/core/mind/hive/tx__update_domain.cpp80
-rw-r--r--ydb/core/mind/hive/tx__update_tablet_groups.cpp550
-rw-r--r--ydb/core/mind/hive/tx__update_tablet_metrics.cpp142
-rw-r--r--ydb/core/mind/hive/tx__update_tablet_status.cpp354
-rw-r--r--ydb/core/mind/hive/ut/ya.make8
-rw-r--r--ydb/core/mind/hive/ya.make126
-rw-r--r--ydb/core/mind/lease_holder.cpp2
-rw-r--r--ydb/core/mind/local.cpp1024
-rw-r--r--ydb/core/mind/local.h126
-rw-r--r--ydb/core/mind/node_broker.h20
-rw-r--r--ydb/core/mind/tenant_pool.cpp8
-rw-r--r--ydb/core/mind/tenant_slot_broker.cpp14
-rw-r--r--ydb/core/mind/ut_fat/blobstorage_node_warden_ut_fat.cpp24
-rw-r--r--ydb/core/mind/ya.make2
-rw-r--r--ydb/core/mon/mon.cpp568
-rw-r--r--ydb/core/mon/mon.h66
-rw-r--r--ydb/core/node_whiteboard/node_whiteboard.h434
-rw-r--r--ydb/core/persqueue/events/global.h20
-rw-r--r--ydb/core/persqueue/events/internal.h12
-rw-r--r--ydb/core/persqueue/partition.cpp32
-rw-r--r--ydb/core/persqueue/partition.h8
-rw-r--r--ydb/core/persqueue/pq_impl.cpp30
-rw-r--r--ydb/core/persqueue/pq_impl.h2
-rw-r--r--ydb/core/persqueue/pq_ut.cpp2
-rw-r--r--ydb/core/persqueue/read_balancer.cpp2
-rw-r--r--ydb/core/persqueue/user_info.h22
-rw-r--r--ydb/core/protos/alloc.proto14
-rw-r--r--ydb/core/protos/auth.proto78
-rw-r--r--ydb/core/protos/bind_channel_storage_pool.proto8
-rw-r--r--ydb/core/protos/blobstorage.proto84
-rw-r--r--ydb/core/protos/blobstorage_vdisk_config.proto2
-rw-r--r--ydb/core/protos/config.proto254
-rw-r--r--ydb/core/protos/console_config.proto2
-rw-r--r--ydb/core/protos/counters_datashard.proto46
-rw-r--r--ydb/core/protos/counters_hive.proto140
-rw-r--r--ydb/core/protos/counters_keyvalue.proto1602
-rw-r--r--ydb/core/protos/counters_schemeshard.proto6
-rw-r--r--ydb/core/protos/flat_scheme_op.proto132
-rw-r--r--ydb/core/protos/flat_tx_scheme.proto46
-rw-r--r--ydb/core/protos/grpc.proto8
-rw-r--r--ydb/core/protos/hive.proto584
-rw-r--r--ydb/core/protos/local.proto76
-rw-r--r--ydb/core/protos/metrics.proto12
-rw-r--r--ydb/core/protos/msgbus.proto310
-rw-r--r--ydb/core/protos/msgbus_pq.proto4
-rw-r--r--ydb/core/protos/node_whiteboard.proto378
-rw-r--r--ydb/core/protos/pqconfig.proto24
-rw-r--r--ydb/core/protos/scheme_log.proto38
-rw-r--r--ydb/core/protos/services.proto24
-rw-r--r--ydb/core/protos/statestorage.proto26
-rw-r--r--ydb/core/protos/subdomains.proto10
-rw-r--r--ydb/core/protos/tablet.proto136
-rw-r--r--ydb/core/protos/tablet_counters.proto58
-rw-r--r--ydb/core/protos/tablet_counters_aggregator.proto58
-rw-r--r--ydb/core/protos/tablet_tx.proto58
-rw-r--r--ydb/core/protos/tenant_slot_broker.proto2
-rw-r--r--ydb/core/protos/tx_datashard.proto4
-rw-r--r--ydb/core/protos/tx_proxy.proto26
-rw-r--r--ydb/core/protos/tx_scheme.proto4
-rw-r--r--ydb/core/protos/ya.make12
-rw-r--r--ydb/core/quoter/kesus_quoter_proxy.cpp8
-rw-r--r--ydb/core/scheme/scheme_tablecell.h26
-rw-r--r--ydb/core/scheme/scheme_tabledefs.h30
-rw-r--r--ydb/core/security/login_page.cpp794
-rw-r--r--ydb/core/security/login_page.h18
-rw-r--r--ydb/core/security/secure_request.h320
-rw-r--r--ydb/core/security/ticket_parser.cpp1174
-rw-r--r--ydb/core/security/ticket_parser.h12
-rw-r--r--ydb/core/security/ticket_parser_ut.cpp244
-rw-r--r--ydb/core/security/ya.make12
-rw-r--r--ydb/core/sys_view/ut_kqp.cpp2
-rw-r--r--ydb/core/tablet/node_tablet_monitor.cpp616
-rw-r--r--ydb/core/tablet/node_tablet_monitor.h26
-rw-r--r--ydb/core/tablet/node_whiteboard.cpp1270
-rw-r--r--ydb/core/tablet/pipe_tracker.cpp12
-rw-r--r--ydb/core/tablet/pipe_tracker.h18
-rw-r--r--ydb/core/tablet/pipe_tracker_ut.cpp14
-rw-r--r--ydb/core/tablet/tablet_counters.cpp24
-rw-r--r--ydb/core/tablet/tablet_counters.h120
-rw-r--r--ydb/core/tablet/tablet_counters_aggregator.cpp1194
-rw-r--r--ydb/core/tablet/tablet_counters_aggregator.h42
-rw-r--r--ydb/core/tablet/tablet_counters_aggregator_ut.cpp118
-rw-r--r--ydb/core/tablet/tablet_counters_protobuf.h16
-rw-r--r--ydb/core/tablet/tablet_impl.h34
-rw-r--r--ydb/core/tablet/tablet_list_renderer.cpp4
-rw-r--r--ydb/core/tablet/tablet_list_renderer.h2
-rw-r--r--ydb/core/tablet/tablet_metrics.cpp362
-rw-r--r--ydb/core/tablet/tablet_metrics.h166
-rw-r--r--ydb/core/tablet/tablet_metrics_ut.cpp718
-rw-r--r--ydb/core/tablet/tablet_monitoring_proxy.cpp52
-rw-r--r--ydb/core/tablet/tablet_monitoring_proxy.h4
-rw-r--r--ydb/core/tablet/tablet_pipe_client.cpp74
-rw-r--r--ydb/core/tablet/tablet_pipe_server.cpp8
-rw-r--r--ydb/core/tablet/tablet_pipe_ut.cpp2
-rw-r--r--ydb/core/tablet/tablet_req_blockbs.cpp4
-rw-r--r--ydb/core/tablet/tablet_req_delete.cpp218
-rw-r--r--ydb/core/tablet/tablet_req_rebuildhistory.cpp8
-rw-r--r--ydb/core/tablet/tablet_req_reset.cpp192
-rw-r--r--ydb/core/tablet/tablet_req_writelog.cpp6
-rw-r--r--ydb/core/tablet/tablet_resolver.cpp2
-rw-r--r--ydb/core/tablet/tablet_sys.cpp46
-rw-r--r--ydb/core/tablet/tablet_sys.h16
-rw-r--r--ydb/core/tablet/ut/ya.make2
-rw-r--r--ydb/core/tablet/ya.make18
-rw-r--r--ydb/core/tablet_flat/flat_cxx_database.h2660
-rw-r--r--ydb/core/tablet_flat/flat_cxx_database_ut.cpp634
-rw-r--r--ydb/core/tablet_flat/flat_database.h2
-rw-r--r--ydb/core/tablet_flat/flat_dbase_apply.cpp12
-rw-r--r--ydb/core/tablet_flat/flat_dbase_scheme.cpp86
-rw-r--r--ydb/core/tablet_flat/flat_dbase_scheme.h52
-rw-r--r--ydb/core/tablet_flat/flat_executor.cpp102
-rw-r--r--ydb/core/tablet_flat/flat_executor.h6
-rw-r--r--ydb/core/tablet_flat/flat_executor_bootlogic.cpp4
-rw-r--r--ydb/core/tablet_flat/flat_executor_counters.cpp84
-rw-r--r--ydb/core/tablet_flat/flat_executor_counters.h16
-rw-r--r--ydb/core/tablet_flat/flat_executor_db_mon.cpp312
-rw-r--r--ydb/core/tablet_flat/flat_executor_gclogic.cpp240
-rw-r--r--ydb/core/tablet_flat/flat_executor_gclogic.h106
-rw-r--r--ydb/core/tablet_flat/flat_executor_gclogic_ut.cpp18
-rw-r--r--ydb/core/tablet_flat/flat_executor_txloglogic.cpp12
-rw-r--r--ydb/core/tablet_flat/flat_executor_ut.cpp12
-rw-r--r--ydb/core/tablet_flat/protos/ya.make22
-rw-r--r--ydb/core/tablet_flat/tablet_flat_executed.cpp12
-rw-r--r--ydb/core/tablet_flat/tablet_flat_executor.h28
-rw-r--r--ydb/core/tablet_flat/ut/flat_test_db.cpp4
-rw-r--r--ydb/core/tablet_flat/ut/flat_test_db_helpers.h4
-rw-r--r--ydb/core/tablet_flat/ut/ut_db_scheme.cpp36
-rw-r--r--ydb/core/tablet_flat/ut/ya.make4
-rw-r--r--ydb/core/tablet_flat/ya.make8
-rw-r--r--ydb/core/testlib/actors/test_runtime.cpp14
-rw-r--r--ydb/core/testlib/actors/test_runtime_ut.cpp36
-rw-r--r--ydb/core/testlib/basics/appdata.h2
-rw-r--r--ydb/core/testlib/basics/helpers.cpp2
-rw-r--r--ydb/core/testlib/basics/storage.h22
-rw-r--r--ydb/core/testlib/fake_coordinator.h12
-rw-r--r--ydb/core/testlib/fake_scheme_shard.h2
-rw-r--r--ydb/core/testlib/service_mocks/access_service_mock.h50
-rw-r--r--ydb/core/testlib/service_mocks/folder_service_mock.h46
-rw-r--r--ydb/core/testlib/service_mocks/service_account_service_mock.h38
-rw-r--r--ydb/core/testlib/service_mocks/user_account_service_mock.h44
-rw-r--r--ydb/core/testlib/tablet_flat_dummy.cpp4
-rw-r--r--ydb/core/testlib/tablet_helpers.cpp68
-rw-r--r--ydb/core/testlib/tablet_helpers.h66
-rw-r--r--ydb/core/testlib/tenant_runtime.cpp24
-rw-r--r--ydb/core/testlib/test_client.cpp412
-rw-r--r--ydb/core/testlib/test_client.h96
-rw-r--r--ydb/core/tx/columnshard/columnshard_impl.cpp8
-rw-r--r--ydb/core/tx/coordinator/coordinator.h12
-rw-r--r--ydb/core/tx/coordinator/coordinator__check.cpp18
-rw-r--r--ydb/core/tx/coordinator/coordinator__check.h118
-rw-r--r--ydb/core/tx/coordinator/coordinator__mediators_confirmations.cpp50
-rw-r--r--ydb/core/tx/coordinator/coordinator__monitoring.cpp70
-rw-r--r--ydb/core/tx/coordinator/coordinator__plan_step.cpp228
-rw-r--r--ydb/core/tx/coordinator/coordinator__restart_mediator.cpp78
-rw-r--r--ydb/core/tx/coordinator/coordinator__restore_transaction.cpp98
-rw-r--r--ydb/core/tx/coordinator/coordinator__schema.cpp48
-rw-r--r--ydb/core/tx/coordinator/coordinator__schema_upgrade.cpp56
-rw-r--r--ydb/core/tx/coordinator/coordinator_impl.cpp50
-rw-r--r--ydb/core/tx/coordinator/coordinator_impl.h132
-rw-r--r--ydb/core/tx/coordinator/mediator_queue.cpp12
-rw-r--r--ydb/core/tx/datashard/datashard.cpp14
-rw-r--r--ydb/core/tx/datashard/datashard__cleanup_borrowed.cpp10
-rw-r--r--ydb/core/tx/datashard/datashard__init.cpp4
-rw-r--r--ydb/core/tx/datashard/datashard_impl.h94
-rw-r--r--ydb/core/tx/datashard/datashard_txs.h4
-rw-r--r--ydb/core/tx/datashard/datashard_ut_common.cpp6
-rw-r--r--ydb/core/tx/datashard/datashard_ut_locks.cpp2
-rw-r--r--ydb/core/tx/datashard/datashard_ut_minstep.cpp2
-rw-r--r--ydb/core/tx/mediator/execute_queue.cpp14
-rw-r--r--ydb/core/tx/mediator/mediator.cpp10
-rw-r--r--ydb/core/tx/mediator/mediator_impl.h50
-rw-r--r--ydb/core/tx/mediator/tablet_queue.cpp82
-rw-r--r--ydb/core/tx/scheme_board/cache.cpp16
-rw-r--r--ydb/core/tx/scheme_cache/scheme_cache.cpp4
-rw-r--r--ydb/core/tx/scheme_cache/scheme_cache.h16
-rw-r--r--ydb/core/tx/schemeshard/schemeshard.h84
-rw-r--r--ydb/core/tx/schemeshard/schemeshard__clean_pathes.cpp14
-rw-r--r--ydb/core/tx/schemeshard/schemeshard__delete_tablet_reply.cpp32
-rw-r--r--ydb/core/tx/schemeshard/schemeshard__init.cpp150
-rw-r--r--ydb/core/tx/schemeshard/schemeshard__init_root.cpp12
-rw-r--r--ydb/core/tx/schemeshard/schemeshard__init_schema.cpp2
-rw-r--r--ydb/core/tx/schemeshard/schemeshard__login.cpp170
-rw-r--r--ydb/core/tx/schemeshard/schemeshard__monitoring.cpp6
-rw-r--r--ydb/core/tx/schemeshard/schemeshard__operation.cpp6
-rw-r--r--ydb/core/tx/schemeshard/schemeshard__operation_alter_extsubdomain.cpp6
-rw-r--r--ydb/core/tx/schemeshard/schemeshard__operation_alter_login.cpp348
-rw-r--r--ydb/core/tx/schemeshard/schemeshard__operation_alter_pq.cpp92
-rw-r--r--ydb/core/tx/schemeshard/schemeshard__operation_alter_subdomain.cpp2
-rw-r--r--ydb/core/tx/schemeshard/schemeshard__operation_common.h70
-rw-r--r--ydb/core/tx/schemeshard/schemeshard__operation_create_pq.cpp24
-rw-r--r--ydb/core/tx/schemeshard/schemeshard__operation_part.h6
-rw-r--r--ydb/core/tx/schemeshard/schemeshard__table_stats.cpp28
-rw-r--r--ydb/core/tx/schemeshard/schemeshard_domain_links.cpp8
-rw-r--r--ydb/core/tx/schemeshard/schemeshard_impl.cpp130
-rw-r--r--ydb/core/tx/schemeshard/schemeshard_impl.h22
-rw-r--r--ydb/core/tx/schemeshard/schemeshard_info_types.cpp16
-rw-r--r--ydb/core/tx/schemeshard/schemeshard_info_types.h90
-rw-r--r--ydb/core/tx/schemeshard/schemeshard_path_describer.cpp42
-rw-r--r--ydb/core/tx/schemeshard/schemeshard_path_describer.h2
-rw-r--r--ydb/core/tx/schemeshard/schemeshard_schema.h64
-rw-r--r--ydb/core/tx/schemeshard/schemeshard_utils.cpp148
-rw-r--r--ydb/core/tx/schemeshard/schemeshard_utils.h20
-rw-r--r--ydb/core/tx/schemeshard/ut_base.cpp48
-rw-r--r--ydb/core/tx/schemeshard/ut_extsubdomain.cpp16
-rw-r--r--ydb/core/tx/schemeshard/ut_helpers/helpers.cpp28
-rw-r--r--ydb/core/tx/schemeshard/ut_helpers/helpers.h4
-rw-r--r--ydb/core/tx/schemeshard/ut_login.cpp54
-rw-r--r--ydb/core/tx/schemeshard/ut_login/ya.make50
-rw-r--r--ydb/core/tx/schemeshard/ut_pq_reboots.cpp126
-rw-r--r--ydb/core/tx/schemeshard/ut_subdomain.cpp124
-rw-r--r--ydb/core/tx/schemeshard/ya.make8
-rw-r--r--ydb/core/tx/tx_allocator/txallocator_impl.h4
-rw-r--r--ydb/core/tx/tx_allocator/txallocator_ut_helpers.cpp20
-rw-r--r--ydb/core/tx/tx_allocator_client/actor_client.cpp12
-rw-r--r--ydb/core/tx/tx_proxy/datareq.cpp12
-rw-r--r--ydb/core/tx/tx_proxy/describe.cpp136
-rw-r--r--ydb/core/tx/tx_proxy/encrypted_storage_ut.cpp8
-rw-r--r--ydb/core/tx/tx_proxy/proxy.h16
-rw-r--r--ydb/core/tx/tx_proxy/proxy_ext_tenant_ut.cpp372
-rw-r--r--ydb/core/tx/tx_proxy/proxy_impl.cpp28
-rw-r--r--ydb/core/tx/tx_proxy/proxy_ut.cpp46
-rw-r--r--ydb/core/tx/tx_proxy/proxy_ut_helpers.cpp38
-rw-r--r--ydb/core/tx/tx_proxy/proxy_ut_helpers.h22
-rw-r--r--ydb/core/tx/tx_proxy/schemereq.cpp46
-rw-r--r--ydb/core/tx/tx_proxy/storage_tenant_ut.cpp6
-rw-r--r--ydb/core/util/metrics.h902
-rw-r--r--ydb/core/util/proto_duration.h50
-rw-r--r--ydb/core/util/simple_cache.h148
-rw-r--r--ydb/core/util/simple_cache_ut.cpp52
-rw-r--r--ydb/core/util/templates.h82
-rw-r--r--ydb/core/util/testactorsys.cpp2
-rw-r--r--ydb/core/util/tuples.h634
-rw-r--r--ydb/core/util/ut/ya.make2
-rw-r--r--ydb/core/util/wildcard.h100
-rw-r--r--ydb/core/util/wildcard_ut.cpp54
-rw-r--r--ydb/core/util/ya.make10
-rw-r--r--ydb/core/viewer/browse.h1038
-rw-r--r--ydb/core/viewer/browse_db.h342
-rw-r--r--ydb/core/viewer/browse_events.h68
-rw-r--r--ydb/core/viewer/browse_pq.h748
-rw-r--r--ydb/core/viewer/content/api/css/print.css2734
-rw-r--r--ydb/core/viewer/content/api/css/reset.css250
-rw-r--r--ydb/core/viewer/content/api/css/screen.css2988
-rw-r--r--ydb/core/viewer/content/api/css/style.css500
-rw-r--r--ydb/core/viewer/content/api/css/typography.css28
-rw-r--r--ydb/core/viewer/content/api/index.html214
-rw-r--r--ydb/core/viewer/content/api/lang/ca.js106
-rw-r--r--ydb/core/viewer/content/api/lang/en.js112
-rw-r--r--ydb/core/viewer/content/api/lang/es.js106
-rw-r--r--ydb/core/viewer/content/api/lang/fr.js108
-rw-r--r--ydb/core/viewer/content/api/lang/geo.js112
-rw-r--r--ydb/core/viewer/content/api/lang/it.js104
-rwxr-xr-xydb/core/viewer/content/api/lang/ja.js106
-rw-r--r--ydb/core/viewer/content/api/lang/ko-kr.js106
-rw-r--r--ydb/core/viewer/content/api/lang/pl.js106
-rw-r--r--ydb/core/viewer/content/api/lang/pt.js106
-rw-r--r--ydb/core/viewer/content/api/lang/ru.js112
-rw-r--r--ydb/core/viewer/content/api/lang/tr.js106
-rw-r--r--ydb/core/viewer/content/api/lang/translator.js78
-rw-r--r--ydb/core/viewer/content/api/lang/zh-cn.js106
-rw-r--r--ydb/core/viewer/content/api/lib/backbone-min.js30
-rw-r--r--ydb/core/viewer/content/api/lib/es5-shim.js4130
-rw-r--r--ydb/core/viewer/content/api/lib/handlebars-4.0.5.js9216
-rw-r--r--ydb/core/viewer/content/api/lib/highlight.9.1.0.pack.js4
-rw-r--r--ydb/core/viewer/content/api/lib/highlight.9.1.0.pack_extended.js68
-rw-r--r--ydb/core/viewer/content/api/lib/jquery-1.8.0.min.js4
-rw-r--r--ydb/core/viewer/content/api/lib/jquery.ba-bbq.min.js36
-rw-r--r--ydb/core/viewer/content/api/lib/jquery.slideto.min.js2
-rw-r--r--ydb/core/viewer/content/api/lib/jquery.wiggle.min.js16
-rw-r--r--ydb/core/viewer/content/api/lib/js-yaml.min.js6
-rw-r--r--ydb/core/viewer/content/api/lib/jsoneditor.min.js22
-rw-r--r--ydb/core/viewer/content/api/lib/lodash.min.js204
-rw-r--r--ydb/core/viewer/content/api/lib/marked.js2544
-rw-r--r--ydb/core/viewer/content/api/lib/object-assign-pollyfill.js46
-rw-r--r--ydb/core/viewer/content/api/lib/sanitize-html.min.js12
-rw-r--r--ydb/core/viewer/content/api/lib/swagger-oauth.js694
-rw-r--r--ydb/core/viewer/content/api/swagger-ui.min.js28
-rw-r--r--ydb/core/viewer/content/index.html1336
-rw-r--r--ydb/core/viewer/content/jstree.min.js12
-rw-r--r--ydb/core/viewer/content/style.min.css2
-rw-r--r--ydb/core/viewer/content/v2/cpu142
-rw-r--r--ydb/core/viewer/content/v2/cpu_view.js196
-rw-r--r--ydb/core/viewer/content/v2/disk_cell.js390
-rw-r--r--ydb/core/viewer/content/v2/disk_map.js228
-rw-r--r--ydb/core/viewer/content/v2/index.html14
-rw-r--r--ydb/core/viewer/content/v2/net_view.js298
-rw-r--r--ydb/core/viewer/content/v2/network142
-rw-r--r--ydb/core/viewer/content/v2/node.js1758
-rw-r--r--ydb/core/viewer/content/v2/node_group.js434
-rw-r--r--ydb/core/viewer/content/v2/node_map.js226
-rw-r--r--ydb/core/viewer/content/v2/node_view.js526
-rw-r--r--ydb/core/viewer/content/v2/nodes168
-rw-r--r--ydb/core/viewer/content/v2/overview142
-rw-r--r--ydb/core/viewer/content/v2/overview.js216
-rw-r--r--ydb/core/viewer/content/v2/pdisk.js406
-rw-r--r--ydb/core/viewer/content/v2/pool_block.js76
-rw-r--r--ydb/core/viewer/content/v2/pool_map.js108
-rw-r--r--ydb/core/viewer/content/v2/runner.html382
-rw-r--r--ydb/core/viewer/content/v2/stats.js84
-rw-r--r--ydb/core/viewer/content/v2/storage238
-rw-r--r--ydb/core/viewer/content/v2/storage.js764
-rw-r--r--ydb/core/viewer/content/v2/storage_group.js488
-rw-r--r--ydb/core/viewer/content/v2/storage_view.js534
-rw-r--r--ydb/core/viewer/content/v2/tablet_cell.js176
-rw-r--r--ydb/core/viewer/content/v2/tablet_map.js90
-rw-r--r--ydb/core/viewer/content/v2/tenant.js462
-rw-r--r--ydb/core/viewer/content/v2/tenant_view.js274
-rw-r--r--ydb/core/viewer/content/v2/tenants142
-rw-r--r--ydb/core/viewer/content/v2/util.js592
-rw-r--r--ydb/core/viewer/content/v2/vdisk.js352
-rw-r--r--ydb/core/viewer/content/v2/viewer.css1930
-rw-r--r--ydb/core/viewer/content/v2/viewer.js1414
-rw-r--r--ydb/core/viewer/content/viewer.js5872
-rw-r--r--ydb/core/viewer/counters_hosts.h302
-rw-r--r--ydb/core/viewer/json/json.cpp972
-rw-r--r--ydb/core/viewer/json/json.h66
-rw-r--r--ydb/core/viewer/json/json_ut.cpp88
-rw-r--r--ydb/core/viewer/json/ut/ya.make20
-rw-r--r--ydb/core/viewer/json/ya.make36
-rw-r--r--ydb/core/viewer/json_browse.h424
-rw-r--r--ydb/core/viewer/json_bscontrollerinfo.h188
-rw-r--r--ydb/core/viewer/json_bsgroupinfo.h130
-rw-r--r--ydb/core/viewer/json_cluster.h816
-rw-r--r--ydb/core/viewer/json_compute.h758
-rw-r--r--ydb/core/viewer/json_config.h110
-rw-r--r--ydb/core/viewer/json_content.h142
-rw-r--r--ydb/core/viewer/json_counters.h814
-rw-r--r--ydb/core/viewer/json_describe.h276
-rw-r--r--ydb/core/viewer/json_healthcheck.h220
-rw-r--r--ydb/core/viewer/json_hiveinfo.h250
-rw-r--r--ydb/core/viewer/json_hivestats.h202
-rw-r--r--ydb/core/viewer/json_hotkeys.h52
-rw-r--r--ydb/core/viewer/json_labeledcounters.h312
-rw-r--r--ydb/core/viewer/json_metainfo.h276
-rw-r--r--ydb/core/viewer/json_netinfo.h642
-rw-r--r--ydb/core/viewer/json_nodeinfo.h100
-rw-r--r--ydb/core/viewer/json_nodelist.h176
-rw-r--r--ydb/core/viewer/json_nodes.h716
-rw-r--r--ydb/core/viewer/json_pdiskinfo.h102
-rw-r--r--ydb/core/viewer/json_pipe_req.h440
-rw-r--r--ydb/core/viewer/json_pqconsumerinfo.h72
-rw-r--r--ydb/core/viewer/json_query.h560
-rw-r--r--ydb/core/viewer/json_storage.h1166
-rw-r--r--ydb/core/viewer/json_sysinfo.h128
-rw-r--r--ydb/core/viewer/json_tabletcounters.h340
-rw-r--r--ydb/core/viewer/json_tabletinfo.h336
-rw-r--r--ydb/core/viewer/json_tenantinfo.h1050
-rw-r--r--ydb/core/viewer/json_tenants.h244
-rw-r--r--ydb/core/viewer/json_topicinfo.h50
-rw-r--r--ydb/core/viewer/json_vdiskinfo.h174
-rw-r--r--ydb/core/viewer/json_wb_req.h742
-rw-r--r--ydb/core/viewer/json_whoami.h148
-rw-r--r--ydb/core/viewer/protos/viewer.proto640
-rw-r--r--ydb/core/viewer/protos/ya.make22
-rw-r--r--ydb/core/viewer/ut/ya.make28
-rw-r--r--ydb/core/viewer/viewer.cpp1274
-rw-r--r--ydb/core/viewer/viewer.h312
-rw-r--r--ydb/core/viewer/viewer_ut.cpp172
-rw-r--r--ydb/core/viewer/wb_aggregate.cpp360
-rw-r--r--ydb/core/viewer/wb_aggregate.h84
-rw-r--r--ydb/core/viewer/wb_filter.cpp198
-rw-r--r--ydb/core/viewer/wb_filter.h948
-rw-r--r--ydb/core/viewer/wb_group.h562
-rw-r--r--ydb/core/viewer/wb_merge.cpp438
-rw-r--r--ydb/core/viewer/wb_merge.h420
-rw-r--r--ydb/core/viewer/ya.make308
-rw-r--r--ydb/core/ydb_convert/table_description.cpp16
-rw-r--r--ydb/core/ydb_convert/ydb_convert.cpp10
-rw-r--r--ydb/core/ymq/actor/action.h8
-rw-r--r--ydb/core/ymq/actor/executor.cpp2
-rw-r--r--ydb/core/ymq/actor/schema.cpp2
-rw-r--r--ydb/core/ymq/actor/service.cpp2
-rw-r--r--ydb/core/yql_testlib/yql_testlib.cpp2
-rw-r--r--ydb/library/aclib/aclib.cpp1378
-rw-r--r--ydb/library/aclib/aclib.h254
-rw-r--r--ydb/library/aclib/aclib_ut.cpp464
-rw-r--r--ydb/library/aclib/protos/aclib.proto88
-rw-r--r--ydb/library/aclib/protos/ya.make8
-rw-r--r--ydb/library/aclib/ut/ya.make20
-rw-r--r--ydb/library/aclib/ya.make18
-rw-r--r--ydb/library/binary_json/ut/ya.make2
-rw-r--r--ydb/library/dynumber/ut/ya.make2
-rw-r--r--ydb/library/keys/ut/ya.make2
-rw-r--r--ydb/library/login/login.cpp1122
-rw-r--r--ydb/library/login/login.h322
-rw-r--r--ydb/library/login/login_ut.cpp404
-rw-r--r--ydb/library/login/protos/login.proto64
-rw-r--r--ydb/library/login/protos/ya.make16
-rw-r--r--ydb/library/login/ut/ya.make22
-rw-r--r--ydb/library/login/ya.make28
-rw-r--r--ydb/library/mkql_proto/protos/minikql.proto10
-rw-r--r--ydb/library/mkql_proto/ut/ya.make2
-rw-r--r--ydb/library/persqueue/topic_parser/ut/ya.make2
-rw-r--r--ydb/library/security/util.h24
-rw-r--r--ydb/library/yql/minikql/mkql_node.cpp108
-rw-r--r--ydb/library/yql/minikql/mkql_node.h50
-rw-r--r--ydb/library/yql/minikql/mkql_node_builder.cpp34
-rw-r--r--ydb/library/yql/minikql/mkql_node_builder.h18
-rw-r--r--ydb/library/yql/minikql/mkql_node_builder_ut.cpp10
-rw-r--r--ydb/library/yql/minikql/mkql_node_cast_ut.cpp2
-rw-r--r--ydb/library/yql/minikql/mkql_node_printer.cpp22
-rw-r--r--ydb/library/yql/minikql/mkql_node_printer_ut.cpp28
-rw-r--r--ydb/library/yql/minikql/mkql_node_serialization.cpp30
-rw-r--r--ydb/library/yql/minikql/mkql_node_ut.cpp112
-rw-r--r--ydb/library/yql/minikql/mkql_opt_literal.cpp2
-rw-r--r--ydb/library/yql/minikql/mkql_program_builder.cpp52
-rw-r--r--ydb/library/yql/minikql/mkql_program_builder.h6
-rw-r--r--ydb/library/yql/minikql/mkql_type_builder.cpp22
-rw-r--r--ydb/library/yql/providers/common/mkql/yql_type_mkql.cpp2
-rw-r--r--ydb/library/yql/providers/common/schema/mkql/yql_mkql_schema.cpp6
-rw-r--r--ydb/library/yql/public/issue/protos/issue_message.proto2
-rw-r--r--ydb/library/yql/public/issue/yql_issue_message.cpp2
-rw-r--r--ydb/library/yql/public/udf/udf_type_builder.h12
-rw-r--r--ydb/library/yql/udfs/common/stat/stat_udf.cpp6
-rw-r--r--ydb/library/yql/udfs/common/stat/stat_udf_ut.cpp44
-rw-r--r--ydb/library/yql/udfs/common/stat/static/stat_udf.h44
-rw-r--r--ydb/library/yql/udfs/common/stat/static/static_udf.cpp8
-rw-r--r--ydb/library/yql/udfs/common/stat/static/tdigest.cpp168
-rw-r--r--ydb/library/yql/udfs/common/stat/static/tdigest.h76
-rw-r--r--ydb/library/yql/udfs/common/stat/static/tdigest.proto22
-rw-r--r--ydb/library/yql/udfs/common/stat/static/ya.make32
-rw-r--r--ydb/library/yql/udfs/common/stat/ut/ya.make20
-rw-r--r--ydb/library/yql/udfs/common/stat/ya.make20
-rw-r--r--ydb/public/api/grpc/ya.make4
-rw-r--r--ydb/public/api/grpc/ydb_auth_v1.proto20
-rw-r--r--ydb/public/api/grpc/ydb_monitoring_v1.proto20
-rw-r--r--ydb/public/api/protos/ya.make4
-rw-r--r--ydb/public/api/protos/ydb_auth.proto42
-rw-r--r--ydb/public/api/protos/ydb_issue_message.proto2
-rw-r--r--ydb/public/api/protos/ydb_monitoring.proto378
-rw-r--r--ydb/public/api/ya.make6
-rw-r--r--ydb/public/lib/base/msgbus.h144
-rw-r--r--ydb/public/lib/deprecated/client/grpc_client.cpp20
-rw-r--r--ydb/public/lib/deprecated/client/grpc_client.h16
-rw-r--r--ydb/public/lib/deprecated/client/msgbus_client.cpp132
-rw-r--r--ydb/public/lib/deprecated/client/msgbus_client.h10
-rw-r--r--ydb/public/lib/deprecated/client/msgbus_player.cpp290
-rw-r--r--ydb/public/lib/deprecated/client/msgbus_player.h34
-rw-r--r--ydb/public/lib/deprecated/kicli/cpp_ut.cpp2424
-rw-r--r--ydb/public/lib/deprecated/kicli/error.cpp510
-rw-r--r--ydb/public/lib/deprecated/kicli/kicli.h1000
-rw-r--r--ydb/public/lib/deprecated/kicli/kikimr.cpp978
-rw-r--r--ydb/public/lib/deprecated/kicli/query.cpp134
-rw-r--r--ydb/public/lib/deprecated/kicli/result.cpp144
-rw-r--r--ydb/public/lib/deprecated/kicli/schema.cpp194
-rw-r--r--ydb/public/lib/deprecated/kicli/ut/ya.make20
-rw-r--r--ydb/public/lib/deprecated/kicli/ya.make30
-rw-r--r--ydb/public/lib/json_value/ydb_json_value.cpp4
-rw-r--r--ydb/public/lib/value/value.cpp1088
-rw-r--r--ydb/public/lib/value/value.h28
-rw-r--r--ydb/public/lib/ydb_cli/common/command.cpp292
-rw-r--r--ydb/public/lib/ydb_cli/common/command.h4
-rw-r--r--ydb/public/sdk/cpp/client/ydb_proto/accessor.h4
-rw-r--r--ydb/public/sdk/cpp/client/ydb_types/credentials/credentials.h14
-rw-r--r--ydb/public/sdk/cpp/client/ydb_types/credentials/login.cpp426
-rw-r--r--ydb/public/sdk/cpp/client/ydb_types/credentials/ya.make4
-rw-r--r--ydb/services/auth/grpc_service.cpp126
-rw-r--r--ydb/services/auth/grpc_service.h64
-rw-r--r--ydb/services/auth/ya.make26
-rw-r--r--ydb/services/cms/cms_ut.cpp34
-rw-r--r--ydb/services/datastreams/put_records_actor.h14
-rw-r--r--ydb/services/monitoring/grpc_service.cpp108
-rw-r--r--ydb/services/monitoring/grpc_service.h54
-rw-r--r--ydb/services/monitoring/ya.make24
-rw-r--r--ydb/services/persqueue_v1/grpc_pq_read_actor.cpp42
-rw-r--r--ydb/services/persqueue_v1/grpc_pq_write_actor.cpp14
-rw-r--r--ydb/services/persqueue_v1/persqueue_ut.cpp16
-rw-r--r--ydb/services/ydb/ydb_common_ut.h74
-rw-r--r--ydb/services/ydb/ydb_coordination_ut.cpp20
-rw-r--r--ydb/services/ydb/ydb_table_ut.cpp8
-rw-r--r--ydb/services/ydb/ydb_ut.cpp24
-rw-r--r--ydb/tests/library/harness/kikimr_runner.py4
782 files changed, 85107 insertions, 85107 deletions
diff --git a/build/rules/kikimr.policy b/build/rules/kikimr.policy
index 62daf5790fc..5bb6426e306 100644
--- a/build/rules/kikimr.policy
+++ b/build/rules/kikimr.policy
@@ -89,7 +89,7 @@ ALLOW cloud/kms/benchcrypto/cpp -> kikimr/core/blobstorage/crypto
ALLOW rtmapreduce -> kikimr/yf
ALLOW rtmapreduce/libs -> kikimr/core
-ALLOW rtmapreduce/libs -> kikimr/yndx
+ALLOW rtmapreduce/libs -> kikimr/yndx
ALLOW rtmapreduce/libs -> kikimr/library/shop
ALLOW rtmapreduce/libs -> kikimr/driver_lib/run
ALLOW rtmapreduce/libs -> kikimr/library/aclib
@@ -159,7 +159,7 @@ ALLOW ydb/library/yql/dq/actors/compute -> kikimr/core/protos
ALLOW yql/ -> kikimr/library/mkql_proto
ALLOW yql/ -> kikimr/library/binary_json
ALLOW yql/ -> kikimr/library/dynumber
-ALLOW yql/ -> kikimr/yndx/security
+ALLOW yql/ -> kikimr/yndx/security
ALLOW ydb/library/yql/providers/ydb -> kikimr/yq
ALLOW ydb/library/yql/providers/ydb -> kikimr/public/lib/experimental
diff --git a/library/cpp/actors/core/actor.h b/library/cpp/actors/core/actor.h
index dcdaf07e93e..ed29bd14b9e 100644
--- a/library/cpp/actors/core/actor.h
+++ b/library/cpp/actors/core/actor.h
@@ -239,7 +239,7 @@ namespace NActors {
INTERCONNECT_POLLER = 285,
INTERCONNECT_SESSION_KILLER = 286,
ACTOR_SYSTEM_SCHEDULER_ACTOR = 312,
- ACTOR_FUTURE_CALLBACK = 337,
+ ACTOR_FUTURE_CALLBACK = 337,
INTERCONNECT_MONACTOR = 362,
INTERCONNECT_LOAD_ACTOR = 376,
INTERCONNECT_LOAD_RESPONDER = 377,
diff --git a/library/cpp/actors/core/actorsystem.h b/library/cpp/actors/core/actorsystem.h
index 48482dc66b0..40499d7586f 100644
--- a/library/cpp/actors/core/actorsystem.h
+++ b/library/cpp/actors/core/actorsystem.h
@@ -120,10 +120,10 @@ namespace NActors {
return TString();
}
- virtual ui32 GetThreads() const {
- return 1;
- }
-
+ virtual ui32 GetThreads() const {
+ return 1;
+ }
+
// generic
virtual TAffinity* Affinity() const = 0;
diff --git a/library/cpp/actors/core/event_local.h b/library/cpp/actors/core/event_local.h
index a7870e10af0..2845aa94dd9 100644
--- a/library/cpp/actors/core/event_local.h
+++ b/library/cpp/actors/core/event_local.h
@@ -66,7 +66,7 @@ namespace NActors {
static IEventBase* Load(NActors::TEventSerializedData*) {
return new TEv();
}
-
+
static IEventBase* Load(const TString&) {
return new TEv();
}
diff --git a/library/cpp/actors/core/event_pb.h b/library/cpp/actors/core/event_pb.h
index d104517e5dc..d7546b901a0 100644
--- a/library/cpp/actors/core/event_pb.h
+++ b/library/cpp/actors/core/event_pb.h
@@ -157,7 +157,7 @@ namespace NActors {
TString ToString() const override {
return Record.ShortDebugString();
}
-
+
bool IsSerializable() const override {
return true;
}
@@ -422,72 +422,72 @@ namespace NActors {
return TypeName<TEv>() + " { " + TBase::Record.ShortDebugString() + " }";
}
};
-
- template <typename TEv, typename TRecord, ui32 TEventType>
+
+ template <typename TEv, typename TRecord, ui32 TEventType>
class TEventPreSerializedPB: public TEventPB<TEv, TRecord, TEventType> {
- protected:
- using TBase = TEventPB<TEv, TRecord, TEventType>;
- using TSelf = TEventPreSerializedPB<TEv, TRecord, TEventType>;
- using TBase::Record;
-
- public:
- TString PreSerializedData; // already serialized PB data (using message::SerializeToString)
-
- TEventPreSerializedPB() = default;
-
- explicit TEventPreSerializedPB(const TRecord& rec)
- : TBase(rec)
+ protected:
+ using TBase = TEventPB<TEv, TRecord, TEventType>;
+ using TSelf = TEventPreSerializedPB<TEv, TRecord, TEventType>;
+ using TBase::Record;
+
+ public:
+ TString PreSerializedData; // already serialized PB data (using message::SerializeToString)
+
+ TEventPreSerializedPB() = default;
+
+ explicit TEventPreSerializedPB(const TRecord& rec)
+ : TBase(rec)
{
}
-
- explicit TEventPreSerializedPB(TRecord&& rec)
- : TBase(std::move(rec))
+
+ explicit TEventPreSerializedPB(TRecord&& rec)
+ : TBase(std::move(rec))
{
}
-
- // when remote event received locally this method will merge preserialized data
- const TRecord& GetRecord() {
- TRecord& base(TBase::Record);
- if (!PreSerializedData.empty()) {
- TRecord copy;
+
+ // when remote event received locally this method will merge preserialized data
+ const TRecord& GetRecord() {
+ TRecord& base(TBase::Record);
+ if (!PreSerializedData.empty()) {
+ TRecord copy;
Y_PROTOBUF_SUPPRESS_NODISCARD copy.ParseFromString(PreSerializedData);
- copy.MergeFrom(base);
- base.Swap(&copy);
- PreSerializedData.clear();
- }
+ copy.MergeFrom(base);
+ base.Swap(&copy);
+ PreSerializedData.clear();
+ }
return TBase::Record;
- }
-
- const TRecord& GetRecord() const {
- return const_cast<TSelf*>(this)->GetRecord();
- }
-
- TRecord* MutableRecord() {
+ }
+
+ const TRecord& GetRecord() const {
+ return const_cast<TSelf*>(this)->GetRecord();
+ }
+
+ TRecord* MutableRecord() {
GetRecord(); // Make sure PreSerializedData is parsed
- return &(TBase::Record);
- }
-
- TString ToString() const override {
+ return &(TBase::Record);
+ }
+
+ TString ToString() const override {
return GetRecord().ShortDebugString();
- }
-
+ }
+
bool SerializeToArcadiaStream(TChunkSerializer* chunker) const override {
return chunker->WriteString(&PreSerializedData) && TBase::SerializeToArcadiaStream(chunker);
- }
-
- ui32 CalculateSerializedSize() const override {
- return PreSerializedData.size() + TBase::CalculateSerializedSize();
- }
-
- size_t GetCachedByteSize() const {
- return PreSerializedData.size() + TBase::GetCachedByteSize();
- }
+ }
+
+ ui32 CalculateSerializedSize() const override {
+ return PreSerializedData.size() + TBase::CalculateSerializedSize();
+ }
+
+ size_t GetCachedByteSize() const {
+ return PreSerializedData.size() + TBase::GetCachedByteSize();
+ }
ui32 CalculateSerializedSizeCached() const override {
return GetCachedByteSize();
}
- };
-
+ };
+
inline TActorId ActorIdFromProto(const NActorsProto::TActorId& actorId) {
return TActorId(actorId.GetRawX1(), actorId.GetRawX2());
}
diff --git a/library/cpp/actors/core/executor_pool_base.cpp b/library/cpp/actors/core/executor_pool_base.cpp
index 9d50d702e6c..c3b99991680 100644
--- a/library/cpp/actors/core/executor_pool_base.cpp
+++ b/library/cpp/actors/core/executor_pool_base.cpp
@@ -161,8 +161,8 @@ namespace NActors {
bool TExecutorPoolBaseMailboxed::Cleanup() {
return MailboxTable->Cleanup();
}
-
- ui32 TExecutorPoolBase::GetThreads() const {
- return PoolThreads;
- }
+
+ ui32 TExecutorPoolBase::GetThreads() const {
+ return PoolThreads;
+ }
}
diff --git a/library/cpp/actors/core/executor_pool_base.h b/library/cpp/actors/core/executor_pool_base.h
index 7f19188ae13..c84ce1af779 100644
--- a/library/cpp/actors/core/executor_pool_base.h
+++ b/library/cpp/actors/core/executor_pool_base.h
@@ -42,7 +42,7 @@ namespace NActors {
~TExecutorPoolBase();
void ScheduleActivation(ui32 activation) override;
TAffinity* Affinity() const override;
- ui32 GetThreads() const override;
+ ui32 GetThreads() const override;
};
void DoActorInit(TActorSystem*, IActor*, const TActorId&, const TActorId&);
diff --git a/library/cpp/actors/core/interconnect.h b/library/cpp/actors/core/interconnect.h
index d71fe02c48f..679a4b8cc6f 100644
--- a/library/cpp/actors/core/interconnect.h
+++ b/library/cpp/actors/core/interconnect.h
@@ -60,7 +60,7 @@ namespace NActors {
// protobuf-parser ctor
explicit TNodeLocation(const NActorsInterconnect::TNodeLocation& location);
-
+
// serialized protobuf ctor
static constexpr struct TFromSerialized {} FromSerialized {};
TNodeLocation(TFromSerialized, const TString& s);
@@ -114,7 +114,7 @@ namespace NActors {
friend bool operator > (const TNodeLocation& x, const TNodeLocation& y) { return x.Compare(y) > 0; }
friend bool operator >=(const TNodeLocation& x, const TNodeLocation& y) { return x.Compare(y) >= 0; }
};
-
+
struct TEvInterconnect {
enum EEv {
EvForward = EventSpaceBegin(TEvents::ES_INTERCONNECT),
@@ -177,7 +177,7 @@ namespace NActors {
struct TEvListNodes: public TEventLocal<TEvListNodes, EvListNodes> {
};
-
+
struct TNodeInfo {
ui32 NodeId;
TString Address;
@@ -185,10 +185,10 @@ namespace NActors {
TString ResolveHost;
ui16 Port;
TNodeLocation Location;
-
- TNodeInfo() = default;
- TNodeInfo(const TNodeInfo&) = default;
- TNodeInfo& operator =(const TNodeInfo&) = default;
+
+ TNodeInfo() = default;
+ TNodeInfo(const TNodeInfo&) = default;
+ TNodeInfo& operator =(const TNodeInfo&) = default;
TNodeInfo(ui32 nodeId,
const TString& address,
const TString& host,
@@ -203,12 +203,12 @@ namespace NActors {
, Location(location)
{
}
-
+
operator ui32() const {
return NodeId;
}
};
-
+
struct TEvNodesInfo: public TEventLocal<TEvNodesInfo, EvNodesInfo> {
TVector<TNodeInfo> Nodes;
@@ -218,8 +218,8 @@ namespace NActors {
return &x;
}
return nullptr;
- }
- };
+ }
+ };
struct TEvDisconnect;
@@ -251,5 +251,5 @@ namespace NActors {
struct TEvPoisonSession : TEventLocal<TEvPoisonSession, EvPoisonSession> {};
struct TEvTerminate : TEventLocal<TEvTerminate, EvTerminate> {};
- };
+ };
}
diff --git a/library/cpp/actors/core/log.cpp b/library/cpp/actors/core/log.cpp
index 312baa767a3..5f63b5af580 100644
--- a/library/cpp/actors/core/log.cpp
+++ b/library/cpp/actors/core/log.cpp
@@ -11,7 +11,7 @@ static_assert(int(NActors::NLog::PRI_WARN) == int(::TLOG_WARNING), "expect int(N
static_assert(int(NActors::NLog::PRI_NOTICE) == int(::TLOG_NOTICE), "expect int(NActors::NLog::PRI_NOTICE) == int(::TLOG_NOTICE)");
static_assert(int(NActors::NLog::PRI_INFO) == int(::TLOG_INFO), "expect int(NActors::NLog::PRI_INFO) == int(::TLOG_INFO)");
static_assert(int(NActors::NLog::PRI_DEBUG) == int(::TLOG_DEBUG), "expect int(NActors::NLog::PRI_DEBUG) == int(::TLOG_DEBUG)");
-static_assert(int(NActors::NLog::PRI_TRACE) == int(::TLOG_RESOURCES), "expect int(NActors::NLog::PRI_TRACE) == int(::TLOG_RESOURCES)");
+static_assert(int(NActors::NLog::PRI_TRACE) == int(::TLOG_RESOURCES), "expect int(NActors::NLog::PRI_TRACE) == int(::TLOG_RESOURCES)");
namespace {
struct TRecordWithNewline {
@@ -441,7 +441,7 @@ namespace NActors {
str << "Change priority" << Endl;
}
UL() {
- for (int p = NLog::PRI_EMERG; p <= NLog::PRI_TRACE; ++p) {
+ for (int p = NLog::PRI_EMERG; p <= NLog::PRI_TRACE; ++p) {
LI() {
str << "<a href='logger?c=" << component << "&p=" << p << "'>"
<< NLog::PriorityToString(NLog::EPrio(p)) << "</a>";
@@ -452,7 +452,7 @@ namespace NActors {
str << "Change sampling priority" << Endl;
}
UL() {
- for (int p = NLog::PRI_EMERG; p <= NLog::PRI_TRACE; ++p) {
+ for (int p = NLog::PRI_EMERG; p <= NLog::PRI_TRACE; ++p) {
LI() {
str << "<a href='logger?c=" << component << "&sp=" << p << "'>"
<< NLog::PriorityToString(NLog::EPrio(p)) << "</a>";
@@ -515,7 +515,7 @@ namespace NActors {
}
}
TABLEBODY() {
- for (int p = NLog::PRI_EMERG; p <= NLog::PRI_TRACE; ++p) {
+ for (int p = NLog::PRI_EMERG; p <= NLog::PRI_TRACE; ++p) {
TABLER() {
TABLED() {
str << "<a href = 'logger?c=-1&p=" << p << "'>"
@@ -537,7 +537,7 @@ namespace NActors {
}
}
TABLEBODY() {
- for (int p = NLog::PRI_EMERG; p <= NLog::PRI_TRACE; ++p) {
+ for (int p = NLog::PRI_EMERG; p <= NLog::PRI_TRACE; ++p) {
TABLER() {
TABLED() {
str << "<a href = 'logger?c=-1&sp=" << p << "'>"
diff --git a/library/cpp/actors/core/mon.h b/library/cpp/actors/core/mon.h
index d17b2311078..c450f2338eb 100644
--- a/library/cpp/actors/core/mon.h
+++ b/library/cpp/actors/core/mon.h
@@ -12,7 +12,7 @@ namespace NActors {
HttpInfoRes,
RemoteHttpInfo,
RemoteHttpInfoRes,
- RemoteJsonInfoRes,
+ RemoteJsonInfoRes,
RemoteBinaryInfoRes,
End
};
@@ -28,14 +28,14 @@ namespace NActors {
}
TEvHttpInfo(const NMonitoring::IMonHttpRequest& request, const TString& userToken)
- : Request(request)
- , UserToken(userToken)
- , SubRequestId(0)
- {
- }
-
+ : Request(request)
+ , UserToken(userToken)
+ , SubRequestId(0)
+ {
+ }
+
const NMonitoring::IMonHttpRequest& Request;
- TString UserToken; // built and serialized
+ TString UserToken; // built and serialized
// SubRequestId != 0 means that we assemble reply from multiple parts and SubRequestId contains this part id
int SubRequestId;
};
@@ -168,22 +168,22 @@ namespace NActors {
struct TEvRemoteJsonInfoRes: public NActors::TEventBase<TEvRemoteJsonInfoRes, RemoteJsonInfoRes> {
TEvRemoteJsonInfoRes() {
}
-
+
TEvRemoteJsonInfoRes(const TString& json)
- : Json(json)
+ : Json(json)
{
}
-
+
TString Json;
-
+
TString ToStringHeader() const override {
- return "TEvRemoteJsonInfoRes";
- }
-
+ return "TEvRemoteJsonInfoRes";
+ }
+
bool SerializeToArcadiaStream(TChunkSerializer *serializer) const override {
return serializer->WriteString(&Json);
- }
-
+ }
+
ui32 CalculateSerializedSize() const override {
return Json.size();
}
@@ -194,9 +194,9 @@ namespace NActors {
static IEventBase* Load(TEventSerializedData* bufs) {
return new TEvRemoteJsonInfoRes(bufs->GetString());
- }
- };
-
+ }
+ };
+
struct TEvRemoteBinaryInfoRes: public NActors::TEventBase<TEvRemoteBinaryInfoRes, RemoteBinaryInfoRes> {
TEvRemoteBinaryInfoRes() {
}
diff --git a/library/cpp/actors/core/process_stats.cpp b/library/cpp/actors/core/process_stats.cpp
index 688a9de6b31..0e1dbd00314 100644
--- a/library/cpp/actors/core/process_stats.cpp
+++ b/library/cpp/actors/core/process_stats.cpp
@@ -1,7 +1,7 @@
#include "actorsystem.h"
#include "actor_bootstrapped.h"
#include "hfunc.h"
-#include "process_stats.h"
+#include "process_stats.h"
#include <library/cpp/monlib/dynamic_counters/counters.h>
#include <library/cpp/monlib/metrics/metric_registry.h>
@@ -44,8 +44,8 @@ namespace NActors {
bool TProcStat::Fill(pid_t pid) {
try {
- TString strPid(ToString(pid));
- TFileInput proc("/proc/" + strPid + "/status");
+ TString strPid(ToString(pid));
+ TFileInput proc("/proc/" + strPid + "/status");
TString str;
while (proc.ReadLine(str)) {
if (ExtractVal(str, "VmRSS:", Rss))
@@ -60,7 +60,7 @@ namespace NActors {
float tickPerMillisec = TicksPerMillisec();
- TFileInput procStat("/proc/" + strPid + "/stat");
+ TFileInput procStat("/proc/" + strPid + "/stat");
procStat.ReadLine(str);
if (!str.empty()) {
sscanf(str.data(),
@@ -78,7 +78,7 @@ namespace NActors {
Uptime = SystemUptime - TDuration::MilliSeconds(StartTime / TicksPerMillisec());
}
- TFileInput statm("/proc/" + strPid + "/statm");
+ TFileInput statm("/proc/" + strPid + "/statm");
statm.ReadLine(str);
TVector<TString> fields;
StringSplitter(str).Split(' ').SkipEmpty().Collect(&fields);
@@ -91,27 +91,27 @@ namespace NActors {
FileRss = shared * PageSize;
AnonRss = (resident - shared) * PageSize;
}
-
- TFileInput cgroup("/proc/" + strPid + "/cgroup");
- TString line;
- TString memoryCGroup;
- while (cgroup.ReadLine(line) > 0) {
- StringSplitter(line).Split(':').Collect(&fields);
- if (fields.size() > 2 && fields[1] == "memory") {
- memoryCGroup = fields[2];
- break;
- }
- }
- if (!memoryCGroup.empty()) {
- TFileInput limit("/sys/fs/cgroup/memory" + memoryCGroup + "/memory.limit_in_bytes");
- if (limit.ReadLine(line) > 0) {
- CGroupMemLim = FromString<ui64>(line);
- if (CGroupMemLim > (1ULL << 40)) {
- CGroupMemLim = 0;
- }
- }
- }
-
+
+ TFileInput cgroup("/proc/" + strPid + "/cgroup");
+ TString line;
+ TString memoryCGroup;
+ while (cgroup.ReadLine(line) > 0) {
+ StringSplitter(line).Split(':').Collect(&fields);
+ if (fields.size() > 2 && fields[1] == "memory") {
+ memoryCGroup = fields[2];
+ break;
+ }
+ }
+ if (!memoryCGroup.empty()) {
+ TFileInput limit("/sys/fs/cgroup/memory" + memoryCGroup + "/memory.limit_in_bytes");
+ if (limit.ReadLine(line) > 0) {
+ CGroupMemLim = FromString<ui64>(line);
+ if (CGroupMemLim > (1ULL << 40)) {
+ CGroupMemLim = 0;
+ }
+ }
+ }
+
} catch (...) {
return false;
}
@@ -191,7 +191,7 @@ namespace {
VmSize = ProcStatGroup->GetCounter("Process/VmSize", false);
AnonRssSize = ProcStatGroup->GetCounter("Process/AnonRssSize", false);
FileRssSize = ProcStatGroup->GetCounter("Process/FileRssSize", false);
- CGroupMemLimit = ProcStatGroup->GetCounter("Process/CGroupMemLimit", false);
+ CGroupMemLimit = ProcStatGroup->GetCounter("Process/CGroupMemLimit", false);
UserTime = ProcStatGroup->GetCounter("Process/UserTime", true);
SysTime = ProcStatGroup->GetCounter("Process/SystemTime", true);
MinorPageFaults = ProcStatGroup->GetCounter("Process/MinorPageFaults", true);
@@ -205,9 +205,9 @@ namespace {
*VmSize = procStat.Vsize;
*AnonRssSize = procStat.AnonRss;
*FileRssSize = procStat.FileRss;
- if (procStat.CGroupMemLim) {
- *CGroupMemLimit = procStat.CGroupMemLim;
- }
+ if (procStat.CGroupMemLim) {
+ *CGroupMemLimit = procStat.CGroupMemLim;
+ }
*UserTime = procStat.Utime;
*SysTime = procStat.Stime;
*MinorPageFaults = procStat.MinFlt;
@@ -222,7 +222,7 @@ namespace {
NMonitoring::TDynamicCounters::TCounterPtr VmSize;
NMonitoring::TDynamicCounters::TCounterPtr AnonRssSize;
NMonitoring::TDynamicCounters::TCounterPtr FileRssSize;
- NMonitoring::TDynamicCounters::TCounterPtr CGroupMemLimit;
+ NMonitoring::TDynamicCounters::TCounterPtr CGroupMemLimit;
NMonitoring::TDynamicCounters::TCounterPtr UserTime;
NMonitoring::TDynamicCounters::TCounterPtr SysTime;
NMonitoring::TDynamicCounters::TCounterPtr MinorPageFaults;
@@ -242,7 +242,7 @@ namespace {
VmSize = registry.IntGauge({{"sensor", "process.VmSize"}});
AnonRssSize = registry.IntGauge({{"sensor", "process.AnonRssSize"}});
FileRssSize = registry.IntGauge({{"sensor", "process.FileRssSize"}});
- CGroupMemLimit = registry.IntGauge({{"sensor", "process.CGroupMemLimit"}});
+ CGroupMemLimit = registry.IntGauge({{"sensor", "process.CGroupMemLimit"}});
UptimeSeconds = registry.IntGauge({{"sensor", "process.UptimeSeconds"}});
NumThreads = registry.IntGauge({{"sensor", "process.NumThreads"}});
SystemUptimeSeconds = registry.IntGauge({{"sensor", "system.UptimeSeconds"}});
@@ -257,7 +257,7 @@ namespace {
VmSize->Set(procStat.Vsize);
AnonRssSize->Set(procStat.AnonRss);
FileRssSize->Set(procStat.FileRss);
- CGroupMemLimit->Set(procStat.CGroupMemLim);
+ CGroupMemLimit->Set(procStat.CGroupMemLim);
UptimeSeconds->Set(procStat.Uptime.Seconds());
NumThreads->Set(procStat.NumThreads);
SystemUptimeSeconds->Set(procStat.SystemUptime.Seconds());
@@ -282,7 +282,7 @@ namespace {
NMonitoring::TIntGauge* VmSize;
NMonitoring::TIntGauge* AnonRssSize;
NMonitoring::TIntGauge* FileRssSize;
- NMonitoring::TIntGauge* CGroupMemLimit;
+ NMonitoring::TIntGauge* CGroupMemLimit;
NMonitoring::TRate* UserTime;
NMonitoring::TRate* SysTime;
NMonitoring::TRate* MinorPageFaults;
diff --git a/library/cpp/actors/core/process_stats.h b/library/cpp/actors/core/process_stats.h
index 7b329d6bb47..66346d0b5aa 100644
--- a/library/cpp/actors/core/process_stats.h
+++ b/library/cpp/actors/core/process_stats.h
@@ -10,57 +10,57 @@ namespace NMonitoring {
}
namespace NActors {
- struct TProcStat {
- ui64 Rss;
- ui64 VolCtxSwtch;
- ui64 NonvolCtxSwtch;
-
- int Pid;
- char State;
- int Ppid;
- int Pgrp;
- int Session;
- int TtyNr;
- int TPgid;
- unsigned Flags;
- unsigned long MinFlt;
- unsigned long CMinFlt;
- unsigned long MajFlt;
- unsigned long CMajFlt;
- unsigned long Utime;
- unsigned long Stime;
- long CUtime;
- long CStime;
- long Priority;
- long Nice;
- long NumThreads;
- long ItRealValue;
- // StartTime is measured from system boot
- unsigned long long StartTime;
- unsigned long Vsize;
- long RssPages;
- unsigned long RssLim;
- ui64 FileRss;
- ui64 AnonRss;
- ui64 CGroupMemLim = 0;
-
- TDuration Uptime;
- TDuration SystemUptime;
- // ...
-
- TProcStat() {
- Zero(*this);
- Y_UNUSED(PageSize);
- }
-
- bool Fill(pid_t pid);
-
- private:
- long PageSize = 0;
-
- long ObtainPageSize();
- };
-
+ struct TProcStat {
+ ui64 Rss;
+ ui64 VolCtxSwtch;
+ ui64 NonvolCtxSwtch;
+
+ int Pid;
+ char State;
+ int Ppid;
+ int Pgrp;
+ int Session;
+ int TtyNr;
+ int TPgid;
+ unsigned Flags;
+ unsigned long MinFlt;
+ unsigned long CMinFlt;
+ unsigned long MajFlt;
+ unsigned long CMajFlt;
+ unsigned long Utime;
+ unsigned long Stime;
+ long CUtime;
+ long CStime;
+ long Priority;
+ long Nice;
+ long NumThreads;
+ long ItRealValue;
+ // StartTime is measured from system boot
+ unsigned long long StartTime;
+ unsigned long Vsize;
+ long RssPages;
+ unsigned long RssLim;
+ ui64 FileRss;
+ ui64 AnonRss;
+ ui64 CGroupMemLim = 0;
+
+ TDuration Uptime;
+ TDuration SystemUptime;
+ // ...
+
+ TProcStat() {
+ Zero(*this);
+ Y_UNUSED(PageSize);
+ }
+
+ bool Fill(pid_t pid);
+
+ private:
+ long PageSize = 0;
+
+ long ObtainPageSize();
+ };
+
IActor* CreateProcStatCollector(ui32 intervalSec, NMonitoring::TDynamicCounterPtr counters);
IActor* CreateProcStatCollector(TDuration interval, NMonitoring::TMetricRegistry& registry);
}
diff --git a/library/cpp/actors/helpers/future_callback.h b/library/cpp/actors/helpers/future_callback.h
index ecaf25d144b..8ca0d99fdae 100644
--- a/library/cpp/actors/helpers/future_callback.h
+++ b/library/cpp/actors/helpers/future_callback.h
@@ -1,33 +1,33 @@
-#pragma once
-
+#pragma once
+
#include <library/cpp/actors/core/actor.h>
#include <library/cpp/actors/core/hfunc.h>
-
-namespace NActors {
-
-template <typename EventType>
-struct TActorFutureCallback : TActor<TActorFutureCallback<EventType>> {
- using TCallback = std::function<void(TAutoPtr<TEventHandle<EventType>>&)>;
- using TBase = TActor<TActorFutureCallback<EventType>>;
- TCallback Callback;
-
- static constexpr IActor::EActivityType ActorActivityType() {
- return IActor::ACTOR_FUTURE_CALLBACK;
- }
-
- TActorFutureCallback(TCallback&& callback)
- : TBase(&TActorFutureCallback::StateWaitForEvent)
- , Callback(std::move(callback))
- {}
-
- STRICT_STFUNC(StateWaitForEvent,
- HFunc(EventType, Handle)
- )
-
- void Handle(typename EventType::TPtr ev, const TActorContext& ctx) {
- Callback(ev);
- TBase::Die(ctx);
- }
-};
-
-} // NActors
+
+namespace NActors {
+
+template <typename EventType>
+struct TActorFutureCallback : TActor<TActorFutureCallback<EventType>> {
+ using TCallback = std::function<void(TAutoPtr<TEventHandle<EventType>>&)>;
+ using TBase = TActor<TActorFutureCallback<EventType>>;
+ TCallback Callback;
+
+ static constexpr IActor::EActivityType ActorActivityType() {
+ return IActor::ACTOR_FUTURE_CALLBACK;
+ }
+
+ TActorFutureCallback(TCallback&& callback)
+ : TBase(&TActorFutureCallback::StateWaitForEvent)
+ , Callback(std::move(callback))
+ {}
+
+ STRICT_STFUNC(StateWaitForEvent,
+ HFunc(EventType, Handle)
+ )
+
+ void Handle(typename EventType::TPtr ev, const TActorContext& ctx) {
+ Callback(ev);
+ TBase::Die(ctx);
+ }
+};
+
+} // NActors
diff --git a/library/cpp/actors/helpers/ya.make b/library/cpp/actors/helpers/ya.make
index e7302cea096..d8771179de8 100644
--- a/library/cpp/actors/helpers/ya.make
+++ b/library/cpp/actors/helpers/ya.make
@@ -7,7 +7,7 @@ SRCS(
activeactors.h
flow_controlled_queue.cpp
flow_controlled_queue.h
- future_callback.h
+ future_callback.h
mon_histogram_helper.h
selfping_actor.cpp
)
diff --git a/library/cpp/actors/http/http.cpp b/library/cpp/actors/http/http.cpp
index 90fdd161ed5..7125f9d8b04 100644
--- a/library/cpp/actors/http/http.cpp
+++ b/library/cpp/actors/http/http.cpp
@@ -1,116 +1,116 @@
-#include "http.h"
+#include "http.h"
#include <library/cpp/string_utils/quote/quote.h>
-
-inline TStringBuf operator +(TStringBuf l, TStringBuf r) {
- if (l.empty()) {
- return r;
- }
- if (r.empty()) {
- return l;
- }
- if (l.end() == r.begin()) {
- return TStringBuf(l.data(), l.size() + r.size());
- }
- if (r.end() == l.begin()) {
- return TStringBuf(r.data(), l.size() + r.size());
- }
- Y_FAIL("oops");
- return TStringBuf();
-}
-
-inline TStringBuf operator +=(TStringBuf& l, TStringBuf r) {
- return l = l + r;
-}
-
-namespace NHttp {
-
-template <> TStringBuf THttpRequest::GetName<&THttpRequest::Host>() { return "Host"; }
-template <> TStringBuf THttpRequest::GetName<&THttpRequest::Accept>() { return "Accept"; }
-template <> TStringBuf THttpRequest::GetName<&THttpRequest::Connection>() { return "Connection"; }
-template <> TStringBuf THttpRequest::GetName<&THttpRequest::ContentType>() { return "Content-Type"; }
-template <> TStringBuf THttpRequest::GetName<&THttpRequest::ContentLength>() { return "Content-Length"; }
-template <> TStringBuf THttpRequest::GetName<&THttpRequest::TransferEncoding>() { return "Transfer-Encoding"; }
-
-const TMap<TStringBuf, TStringBuf THttpRequest::*, TLessNoCase> THttpRequest::HeadersLocation = {
- { THttpRequest::GetName<&THttpRequest::Host>(), &THttpRequest::Host },
- { THttpRequest::GetName<&THttpRequest::Accept>(), &THttpRequest::Accept },
- { THttpRequest::GetName<&THttpRequest::Connection>(), &THttpRequest::Connection },
- { THttpRequest::GetName<&THttpRequest::ContentType>(), &THttpRequest::ContentType },
- { THttpRequest::GetName<&THttpRequest::ContentLength>(), &THttpRequest::ContentLength },
- { THttpRequest::GetName<&THttpRequest::TransferEncoding>(), &THttpRequest::TransferEncoding },
-};
-
-template <> TStringBuf THttpResponse::GetName<&THttpResponse::Connection>() { return "Connection"; }
-template <> TStringBuf THttpResponse::GetName<&THttpResponse::ContentType>() { return "Content-Type"; }
-template <> TStringBuf THttpResponse::GetName<&THttpResponse::ContentLength>() { return "Content-Length"; }
-template <> TStringBuf THttpResponse::GetName<&THttpResponse::TransferEncoding>() { return "Transfer-Encoding"; }
-template <> TStringBuf THttpResponse::GetName<&THttpResponse::LastModified>() { return "Last-Modified"; }
+
+inline TStringBuf operator +(TStringBuf l, TStringBuf r) {
+ if (l.empty()) {
+ return r;
+ }
+ if (r.empty()) {
+ return l;
+ }
+ if (l.end() == r.begin()) {
+ return TStringBuf(l.data(), l.size() + r.size());
+ }
+ if (r.end() == l.begin()) {
+ return TStringBuf(r.data(), l.size() + r.size());
+ }
+ Y_FAIL("oops");
+ return TStringBuf();
+}
+
+inline TStringBuf operator +=(TStringBuf& l, TStringBuf r) {
+ return l = l + r;
+}
+
+namespace NHttp {
+
+template <> TStringBuf THttpRequest::GetName<&THttpRequest::Host>() { return "Host"; }
+template <> TStringBuf THttpRequest::GetName<&THttpRequest::Accept>() { return "Accept"; }
+template <> TStringBuf THttpRequest::GetName<&THttpRequest::Connection>() { return "Connection"; }
+template <> TStringBuf THttpRequest::GetName<&THttpRequest::ContentType>() { return "Content-Type"; }
+template <> TStringBuf THttpRequest::GetName<&THttpRequest::ContentLength>() { return "Content-Length"; }
+template <> TStringBuf THttpRequest::GetName<&THttpRequest::TransferEncoding>() { return "Transfer-Encoding"; }
+
+const TMap<TStringBuf, TStringBuf THttpRequest::*, TLessNoCase> THttpRequest::HeadersLocation = {
+ { THttpRequest::GetName<&THttpRequest::Host>(), &THttpRequest::Host },
+ { THttpRequest::GetName<&THttpRequest::Accept>(), &THttpRequest::Accept },
+ { THttpRequest::GetName<&THttpRequest::Connection>(), &THttpRequest::Connection },
+ { THttpRequest::GetName<&THttpRequest::ContentType>(), &THttpRequest::ContentType },
+ { THttpRequest::GetName<&THttpRequest::ContentLength>(), &THttpRequest::ContentLength },
+ { THttpRequest::GetName<&THttpRequest::TransferEncoding>(), &THttpRequest::TransferEncoding },
+};
+
+template <> TStringBuf THttpResponse::GetName<&THttpResponse::Connection>() { return "Connection"; }
+template <> TStringBuf THttpResponse::GetName<&THttpResponse::ContentType>() { return "Content-Type"; }
+template <> TStringBuf THttpResponse::GetName<&THttpResponse::ContentLength>() { return "Content-Length"; }
+template <> TStringBuf THttpResponse::GetName<&THttpResponse::TransferEncoding>() { return "Transfer-Encoding"; }
+template <> TStringBuf THttpResponse::GetName<&THttpResponse::LastModified>() { return "Last-Modified"; }
template <> TStringBuf THttpResponse::GetName<&THttpResponse::ContentEncoding>() { return "Content-Encoding"; }
-
-const TMap<TStringBuf, TStringBuf THttpResponse::*, TLessNoCase> THttpResponse::HeadersLocation = {
- { THttpResponse::GetName<&THttpResponse::Connection>(), &THttpResponse::Connection },
- { THttpResponse::GetName<&THttpResponse::ContentType>(), &THttpResponse::ContentType },
- { THttpResponse::GetName<&THttpResponse::ContentLength>(), &THttpResponse::ContentLength },
- { THttpResponse::GetName<&THttpResponse::TransferEncoding>(), &THttpResponse::TransferEncoding },
- { THttpResponse::GetName<&THttpResponse::LastModified>(), &THttpResponse::LastModified },
+
+const TMap<TStringBuf, TStringBuf THttpResponse::*, TLessNoCase> THttpResponse::HeadersLocation = {
+ { THttpResponse::GetName<&THttpResponse::Connection>(), &THttpResponse::Connection },
+ { THttpResponse::GetName<&THttpResponse::ContentType>(), &THttpResponse::ContentType },
+ { THttpResponse::GetName<&THttpResponse::ContentLength>(), &THttpResponse::ContentLength },
+ { THttpResponse::GetName<&THttpResponse::TransferEncoding>(), &THttpResponse::TransferEncoding },
+ { THttpResponse::GetName<&THttpResponse::LastModified>(), &THttpResponse::LastModified },
{ THttpResponse::GetName<&THttpResponse::ContentEncoding>(), &THttpResponse::ContentEncoding }
-};
-
-void THttpRequest::Clear() {
- // a dirty little trick
- this->~THttpRequest(); // basically, do nothing
- new (this) THttpRequest(); // reset all fields
-}
-
-template <>
-void THttpParser<THttpRequest, TSocketBuffer>::Advance(size_t len) {
- TStringBuf data(Pos(), len);
- while (!data.empty()) {
- if (Stage != EParseStage::Error) {
- LastSuccessStage = Stage;
- }
- switch (Stage) {
- case EParseStage::Method: {
- if (ProcessData(Method, data, ' ', MaxMethodSize)) {
- Stage = EParseStage::URL;
- }
- break;
- }
- case EParseStage::URL: {
- if (ProcessData(URL, data, ' ', MaxURLSize)) {
- Stage = EParseStage::Protocol;
- }
- break;
- }
- case EParseStage::Protocol: {
- if (ProcessData(Protocol, data, '/', MaxProtocolSize)) {
- Stage = EParseStage::Version;
- }
- break;
- }
- case EParseStage::Version: {
- if (ProcessData(Version, data, "\r\n", MaxVersionSize)) {
- Stage = EParseStage::Header;
- Headers = data;
- }
- break;
- }
- case EParseStage::Header: {
- if (ProcessData(Header, data, "\r\n", MaxHeaderSize)) {
- if (Header.empty()) {
- Headers = TStringBuf(Headers.data(), data.begin() - Headers.begin());
- if (HaveBody()) {
- Stage = EParseStage::Body;
- } else {
- Stage = EParseStage::Done;
- }
- } else {
- ProcessHeader(Header);
- }
- }
- break;
- }
- case EParseStage::Body: {
+};
+
+void THttpRequest::Clear() {
+ // a dirty little trick
+ this->~THttpRequest(); // basically, do nothing
+ new (this) THttpRequest(); // reset all fields
+}
+
+template <>
+void THttpParser<THttpRequest, TSocketBuffer>::Advance(size_t len) {
+ TStringBuf data(Pos(), len);
+ while (!data.empty()) {
+ if (Stage != EParseStage::Error) {
+ LastSuccessStage = Stage;
+ }
+ switch (Stage) {
+ case EParseStage::Method: {
+ if (ProcessData(Method, data, ' ', MaxMethodSize)) {
+ Stage = EParseStage::URL;
+ }
+ break;
+ }
+ case EParseStage::URL: {
+ if (ProcessData(URL, data, ' ', MaxURLSize)) {
+ Stage = EParseStage::Protocol;
+ }
+ break;
+ }
+ case EParseStage::Protocol: {
+ if (ProcessData(Protocol, data, '/', MaxProtocolSize)) {
+ Stage = EParseStage::Version;
+ }
+ break;
+ }
+ case EParseStage::Version: {
+ if (ProcessData(Version, data, "\r\n", MaxVersionSize)) {
+ Stage = EParseStage::Header;
+ Headers = data;
+ }
+ break;
+ }
+ case EParseStage::Header: {
+ if (ProcessData(Header, data, "\r\n", MaxHeaderSize)) {
+ if (Header.empty()) {
+ Headers = TStringBuf(Headers.data(), data.begin() - Headers.begin());
+ if (HaveBody()) {
+ Stage = EParseStage::Body;
+ } else {
+ Stage = EParseStage::Done;
+ }
+ } else {
+ ProcessHeader(Header);
+ }
+ }
+ break;
+ }
+ case EParseStage::Body: {
if (!ContentLength.empty()) {
if (ProcessData(Content, data, FromString(ContentLength))) {
Body = Content;
@@ -121,9 +121,9 @@ void THttpParser<THttpRequest, TSocketBuffer>::Advance(size_t len) {
} else {
// Invalid body encoding
Stage = EParseStage::Error;
- }
- break;
- }
+ }
+ break;
+ }
case EParseStage::ChunkLength: {
if (ProcessData(Line, data, "\r\n", MaxChunkLengthSize)) {
if (!Line.empty()) {
@@ -170,484 +170,484 @@ void THttpParser<THttpRequest, TSocketBuffer>::Advance(size_t len) {
break;
}
- case EParseStage::Done:
- case EParseStage::Error: {
- data.Clear();
- break;
- }
- default:
- Y_FAIL("Invalid processing sequence");
- break;
- }
- }
- TSocketBuffer::Advance(len);
-}
-
-template <>
-THttpParser<THttpRequest, TSocketBuffer>::EParseStage THttpParser<THttpRequest, TSocketBuffer>::GetInitialStage() {
- return EParseStage::Method;
-}
-
-template <>
-THttpParser<THttpResponse, TSocketBuffer>::EParseStage THttpParser<THttpResponse, TSocketBuffer>::GetInitialStage() {
- return EParseStage::Protocol;
-}
-
-void THttpResponse::Clear() {
- // a dirty little trick
- this->~THttpResponse(); // basically, do nothing
- new (this) THttpResponse(); // reset all fields
-}
-
-template <>
-void THttpParser<THttpResponse, TSocketBuffer>::Advance(size_t len) {
- TStringBuf data(Pos(), len);
- while (!data.empty()) {
- if (Stage != EParseStage::Error) {
- LastSuccessStage = Stage;
- }
- switch (Stage) {
- case EParseStage::Protocol: {
- if (ProcessData(Protocol, data, '/', MaxProtocolSize)) {
- Stage = EParseStage::Version;
- }
- break;
- }
- case EParseStage::Version: {
- if (ProcessData(Version, data, ' ', MaxVersionSize)) {
- Stage = EParseStage::Status;
- }
- break;
- }
- case EParseStage::Status: {
- if (ProcessData(Status, data, ' ', MaxStatusSize)) {
- Stage = EParseStage::Message;
- }
- break;
- }
- case EParseStage::Message: {
- if (ProcessData(Message, data, "\r\n", MaxMessageSize)) {
- Stage = EParseStage::Header;
- Headers = TStringBuf(data.data(), size_t(0));
- }
- break;
- }
- case EParseStage::Header: {
- if (ProcessData(Header, data, "\r\n", MaxHeaderSize)) {
- if (Header.empty()) {
- if (HaveBody() && (ContentLength.empty() || ContentLength != "0")) {
- Stage = EParseStage::Body;
- } else {
- Stage = EParseStage::Done;
- }
- } else {
- ProcessHeader(Header);
- }
- Headers = TStringBuf(Headers.data(), data.data() - Headers.data());
- }
- break;
- }
- case EParseStage::Body: {
- if (!ContentLength.empty()) {
- if (ProcessData(Body, data, FromString(ContentLength))) {
- Stage = EParseStage::Done;
- }
- } else if (TransferEncoding == "chunked") {
- Stage = EParseStage::ChunkLength;
- } else {
- // Invalid body encoding
- Stage = EParseStage::Error;
- }
- break;
- }
- case EParseStage::ChunkLength: {
- if (ProcessData(Line, data, "\r\n", MaxChunkLengthSize)) {
- if (!Line.empty()) {
- ChunkLength = ParseHex(Line);
- if (ChunkLength <= MaxChunkSize) {
- ContentSize = Content.size() + ChunkLength;
- if (ContentSize <= MaxChunkContentSize) {
- Stage = EParseStage::ChunkData;
- Line.Clear();
- } else {
- // Invalid chunk content length
- Stage = EParseStage::Error;
- }
- } else {
- // Invalid chunk length
- Stage = EParseStage::Error;
- }
- } else {
- // Invalid body encoding
- Stage = EParseStage::Error;
- }
- }
- break;
- }
- case EParseStage::ChunkData: {
- if (!IsError()) {
- if (ProcessData(Content, data, ContentSize)) {
- if (ProcessData(Line, data, 2)) {
- if (Line == "\r\n") {
- if (ChunkLength == 0) {
- Body = Content;
- Stage = EParseStage::Done;
- } else {
- Stage = EParseStage::ChunkLength;
- }
- Line.Clear();
- } else {
- // Invalid body encoding
- Stage = EParseStage::Error;
- }
- }
- }
- }
- break;
- }
- case EParseStage::Done:
- case EParseStage::Error:
- data.Clear();
- break;
- default:
- // Invalid processing sequence
- Stage = EParseStage::Error;
- break;
- }
- }
- TSocketBuffer::Advance(len);
-}
-
-template <>
-void THttpParser<THttpResponse, TSocketBuffer>::ConnectionClosed() {
- if (Stage == EParseStage::Done) {
- return;
- }
- if (Stage == EParseStage::Body) {
- // ?
- Stage = EParseStage::Done;
- } else {
- LastSuccessStage = Stage;
- Stage = EParseStage::Error;
- }
-}
-
-THttpOutgoingResponsePtr THttpIncomingRequest::CreateResponseString(TStringBuf data) {
- THttpOutgoingResponsePtr response = new THttpOutgoingResponse(this);
- response->Append(data);
- response->Reparse();
- return response;
-}
-
-THttpOutgoingResponsePtr THttpIncomingRequest::CreateResponseOK(TStringBuf body, TStringBuf contentType, TInstant lastModified) {
- return CreateResponse("200", "OK", contentType, body, lastModified);
-}
-
-THttpOutgoingResponsePtr THttpIncomingRequest::CreateResponseBadRequest(TStringBuf html, TStringBuf contentType) {
- if (html.empty() && IsError()) {
- contentType = "text/plain";
- html = GetErrorText();
- }
- return CreateResponse("400", "Bad Request", contentType, html);
-}
-
-THttpOutgoingResponsePtr THttpIncomingRequest::CreateResponseNotFound(TStringBuf html, TStringBuf contentType) {
- return CreateResponse("404", "Not Found", contentType, html);
-}
-
-THttpOutgoingResponsePtr THttpIncomingRequest::CreateResponseServiceUnavailable(TStringBuf html, TStringBuf contentType) {
- return CreateResponse("503", "Service Unavailable", contentType, html);
-}
-
-THttpOutgoingResponsePtr THttpIncomingRequest::CreateResponseGatewayTimeout(TStringBuf html, TStringBuf contentType) {
- return CreateResponse("504", "Gateway Timeout", contentType, html);
-}
-
-THttpIncomingResponse::THttpIncomingResponse(THttpOutgoingRequestPtr request)
- : Request(request)
-{}
-
-THttpOutgoingResponsePtr THttpIncomingRequest::CreateResponse(TStringBuf status, TStringBuf message, TStringBuf contentType, TStringBuf body, TInstant lastModified) {
- TStringBuf version = Version;
- if (version != "1.0" && version != "1.1") {
- version = "1.1";
- }
- THttpOutgoingResponsePtr response = new THttpOutgoingResponse(this, "HTTP", version, status, message);
- response->Set<&THttpResponse::Connection>(GetConnection());
- if (!WorkerName.empty()) {
- response->Set("X-Worker-Name", WorkerName);
- }
- if (!contentType.empty() && !body.empty()) {
- response->Set<&THttpResponse::ContentType>(contentType);
- }
- if (lastModified) {
- response->Set<&THttpResponse::LastModified>(lastModified.FormatGmTime("%a, %d %b %Y %H:%M:%S GMT"));
- }
- if (response->IsNeedBody() || !body.empty()) {
- if (Method == "HEAD") {
- response->Set<&THttpResponse::ContentLength>(ToString(body.size()));
- } else {
- response->Set<&THttpResponse::Body>(body);
- }
- }
- return response;
-}
-
-THttpIncomingRequestPtr THttpIncomingRequest::Duplicate() {
- THttpIncomingRequestPtr request = new THttpIncomingRequest(*this);
- request->Reparse();
- request->Timer.Reset();
- return request;
-}
-
-THttpIncomingResponsePtr THttpIncomingResponse::Duplicate(THttpOutgoingRequestPtr request) {
- THttpIncomingResponsePtr response = new THttpIncomingResponse(*this);
- response->Reparse();
- response->Request = request;
- return response;
-}
-
-THttpOutgoingResponsePtr THttpOutgoingResponse::Duplicate(THttpIncomingRequestPtr request) {
- THttpOutgoingResponsePtr response = new THttpOutgoingResponse(*this);
- response->Reparse();
- response->Request = request;
- return response;
-}
-
-
-THttpOutgoingResponsePtr THttpIncomingResponse::Reverse(THttpIncomingRequestPtr request) {
- THttpOutgoingResponsePtr response = new THttpOutgoingResponse(request);
- response->Assign(Data(), Size());
- response->Reparse();
- return response;
-}
-
-THttpOutgoingRequest::THttpOutgoingRequest(TStringBuf method, TStringBuf scheme, TStringBuf host, TStringBuf uri, TStringBuf protocol, TStringBuf version) {
- Secure = (scheme == "https");
- TString urie = UrlEscapeRet(uri);
- InitRequest(method, urie, protocol, version);
- if (host) {
- Set<&THttpRequest::Host>(host);
- }
-}
-
-THttpOutgoingRequest::THttpOutgoingRequest(TStringBuf method, TStringBuf url, TStringBuf protocol, TStringBuf version) {
- TStringBuf scheme, host, uri;
- if (!CrackURL(url, scheme, host, uri)) {
- Y_FAIL("Invalid URL specified");
- }
- if (!scheme.empty() && scheme != "http" && scheme != "https") {
- Y_FAIL("Invalid URL specified");
- }
- Secure = (scheme == "https");
- TString urie = UrlEscapeRet(uri);
- InitRequest(method, urie, protocol, version);
- if (host) {
- Set<&THttpRequest::Host>(host);
- }
-}
-
-THttpOutgoingRequestPtr THttpOutgoingRequest::CreateRequestString(const TString& data) {
- THttpOutgoingRequestPtr request = new THttpOutgoingRequest();
- request->Assign(data.data(), data.size());
- request->Reparse();
- return request;
-}
-
-THttpOutgoingRequestPtr THttpOutgoingRequest::CreateRequestGet(TStringBuf url) {
- return CreateRequest("GET", url);
-}
-
-THttpOutgoingRequestPtr THttpOutgoingRequest::CreateRequestGet(TStringBuf host, TStringBuf uri) {
- return CreateHttpRequest("GET", host, uri);
-}
-
-THttpOutgoingRequestPtr THttpOutgoingRequest::CreateRequestPost(TStringBuf url, TStringBuf contentType, TStringBuf body) {
- return CreateRequest("POST", url, contentType, body);
-}
-
-THttpOutgoingRequestPtr THttpOutgoingRequest::CreateRequestPost(TStringBuf host, TStringBuf uri, TStringBuf contentType, TStringBuf body) {
- return CreateHttpRequest("POST", host, uri, contentType, body);
-}
-
-THttpOutgoingRequestPtr THttpOutgoingRequest::CreateRequest(TStringBuf method, TStringBuf url, TStringBuf contentType, TStringBuf body) {
- THttpOutgoingRequestPtr request = new THttpOutgoingRequest(method, url, "HTTP", "1.1");
- request->Set<&THttpRequest::Accept>("*/*");
- if (!contentType.empty()) {
- request->Set<&THttpRequest::ContentType>(contentType);
- request->Set<&THttpRequest::Body>(body);
- }
- return request;
-}
-
-THttpOutgoingRequestPtr THttpOutgoingRequest::CreateHttpRequest(TStringBuf method, TStringBuf host, TStringBuf uri, TStringBuf contentType, TStringBuf body) {
- THttpOutgoingRequestPtr request = new THttpOutgoingRequest(method, "http", host, uri, "HTTP", "1.1");
- request->Set<&THttpRequest::Accept>("*/*");
- if (!contentType.empty()) {
- request->Set<&THttpRequest::ContentType>(contentType);
- request->Set<&THttpRequest::Body>(body);
- }
- return request;
-}
-
-THttpOutgoingRequestPtr THttpOutgoingRequest::Duplicate() {
- THttpOutgoingRequestPtr request = new THttpOutgoingRequest(*this);
- request->Reparse();
- return request;
-}
-
-THttpOutgoingResponse::THttpOutgoingResponse(THttpIncomingRequestPtr request)
- : Request(request)
-{}
-
-THttpOutgoingResponse::THttpOutgoingResponse(THttpIncomingRequestPtr request, TStringBuf protocol, TStringBuf version, TStringBuf status, TStringBuf message)
- : Request(request)
-{
- InitResponse(protocol, version, status, message);
-}
-
-const size_t THttpConfig::BUFFER_MIN_STEP;
-const TDuration THttpConfig::CONNECTION_TIMEOUT;
-
-TUrlParameters::TUrlParameters(TStringBuf url) {
- TStringBuf base;
- TStringBuf params;
- if (url.TrySplit('?', base, params)) {
- for (TStringBuf param = params.NextTok('&'); !param.empty(); param = params.NextTok('&')) {
- TStringBuf name = param.NextTok('=');
- Parameters[name] = param;
- }
- }
-}
-
-TString TUrlParameters::operator [](TStringBuf name) const {
- TString value(Get(name));
- CGIUnescape(value);
- return value;
-}
-
-bool TUrlParameters::Has(TStringBuf name) const {
- return Parameters.count(name) != 0;
-}
-
-TStringBuf TUrlParameters::Get(TStringBuf name) const {
- auto it = Parameters.find(name);
- if (it != Parameters.end()) {
- return it->second;
- }
- return TStringBuf();
-}
-
-TString TUrlParameters::Render() const {
- TStringBuilder parameters;
- for (const std::pair<TStringBuf, TStringBuf> parameter : Parameters) {
- if (parameters.empty()) {
- parameters << '?';
- } else {
- parameters << '&';
- }
- parameters << parameter.first;
- parameters << '=';
- parameters << parameter.second;
- }
- return parameters;
-}
-
-TCookies::TCookies(TStringBuf cookie) {
- for (TStringBuf param = cookie.NextTok(';'); !param.empty(); param = cookie.NextTok(';')) {
- param.SkipPrefix(" ");
- TStringBuf name = param.NextTok('=');
- Cookies[name] = param;
- }
-}
-
-TStringBuf TCookies::operator [](TStringBuf name) const {
- return Get(name);
-}
-
-bool TCookies::Has(TStringBuf name) const {
- return Cookies.count(name) != 0;
-}
-
-TStringBuf TCookies::Get(TStringBuf name) const {
- auto it = Cookies.find(name);
- if (it != Cookies.end()) {
- return it->second;
- }
- return TStringBuf();
-}
-
-TString TCookies::Render() const {
- TStringBuilder cookies;
- for (const std::pair<TStringBuf, TStringBuf> cookie : Cookies) {
- if (!cookies.empty()) {
- cookies << ' ';
- }
- cookies << cookie.first;
- cookies << '=';
- cookies << cookie.second;
- cookies << ';';
- }
- return cookies;
-}
-
-TCookiesBuilder::TCookiesBuilder()
- :TCookies(TStringBuf())
-{}
-
-void TCookiesBuilder::Set(TStringBuf name, TStringBuf data) {
- Data.emplace_back(name, data);
- Cookies[Data.back().first] = Data.back().second;
-}
-
-THeaders::THeaders(TStringBuf headers) {
- for (TStringBuf param = headers.NextTok("\r\n"); !param.empty(); param = headers.NextTok("\r\n")) {
- TStringBuf name = param.NextTok(":");
- param.SkipPrefix(" ");
- Headers[name] = param;
- }
-}
-
-TStringBuf THeaders::operator [](TStringBuf name) const {
- return Get(name);
-}
-
-bool THeaders::Has(TStringBuf name) const {
- return Headers.count(name) != 0;
-}
-
-TStringBuf THeaders::Get(TStringBuf name) const {
- auto it = Headers.find(name);
- if (it != Headers.end()) {
- return it->second;
- }
- return TStringBuf();
-}
-
-TString THeaders::Render() const {
- TStringBuilder headers;
- for (const std::pair<TStringBuf, TStringBuf> header : Headers) {
- headers << header.first;
- headers << ": ";
- headers << header.second;
- headers << "\r\n";
- }
- return headers;
-}
-
-THeadersBuilder::THeadersBuilder()
- :THeaders(TStringBuf())
-{}
-
-THeadersBuilder::THeadersBuilder(const THeadersBuilder& builder) {
- for (const auto& pr : builder.Headers) {
- Set(pr.first, pr.second);
- }
-}
-
-void THeadersBuilder::Set(TStringBuf name, TStringBuf data) {
- Data.emplace_back(name, data);
- Headers[Data.back().first] = Data.back().second;
-}
-
-}
+ case EParseStage::Done:
+ case EParseStage::Error: {
+ data.Clear();
+ break;
+ }
+ default:
+ Y_FAIL("Invalid processing sequence");
+ break;
+ }
+ }
+ TSocketBuffer::Advance(len);
+}
+
+template <>
+THttpParser<THttpRequest, TSocketBuffer>::EParseStage THttpParser<THttpRequest, TSocketBuffer>::GetInitialStage() {
+ return EParseStage::Method;
+}
+
+template <>
+THttpParser<THttpResponse, TSocketBuffer>::EParseStage THttpParser<THttpResponse, TSocketBuffer>::GetInitialStage() {
+ return EParseStage::Protocol;
+}
+
+void THttpResponse::Clear() {
+ // a dirty little trick
+ this->~THttpResponse(); // basically, do nothing
+ new (this) THttpResponse(); // reset all fields
+}
+
+template <>
+void THttpParser<THttpResponse, TSocketBuffer>::Advance(size_t len) {
+ TStringBuf data(Pos(), len);
+ while (!data.empty()) {
+ if (Stage != EParseStage::Error) {
+ LastSuccessStage = Stage;
+ }
+ switch (Stage) {
+ case EParseStage::Protocol: {
+ if (ProcessData(Protocol, data, '/', MaxProtocolSize)) {
+ Stage = EParseStage::Version;
+ }
+ break;
+ }
+ case EParseStage::Version: {
+ if (ProcessData(Version, data, ' ', MaxVersionSize)) {
+ Stage = EParseStage::Status;
+ }
+ break;
+ }
+ case EParseStage::Status: {
+ if (ProcessData(Status, data, ' ', MaxStatusSize)) {
+ Stage = EParseStage::Message;
+ }
+ break;
+ }
+ case EParseStage::Message: {
+ if (ProcessData(Message, data, "\r\n", MaxMessageSize)) {
+ Stage = EParseStage::Header;
+ Headers = TStringBuf(data.data(), size_t(0));
+ }
+ break;
+ }
+ case EParseStage::Header: {
+ if (ProcessData(Header, data, "\r\n", MaxHeaderSize)) {
+ if (Header.empty()) {
+ if (HaveBody() && (ContentLength.empty() || ContentLength != "0")) {
+ Stage = EParseStage::Body;
+ } else {
+ Stage = EParseStage::Done;
+ }
+ } else {
+ ProcessHeader(Header);
+ }
+ Headers = TStringBuf(Headers.data(), data.data() - Headers.data());
+ }
+ break;
+ }
+ case EParseStage::Body: {
+ if (!ContentLength.empty()) {
+ if (ProcessData(Body, data, FromString(ContentLength))) {
+ Stage = EParseStage::Done;
+ }
+ } else if (TransferEncoding == "chunked") {
+ Stage = EParseStage::ChunkLength;
+ } else {
+ // Invalid body encoding
+ Stage = EParseStage::Error;
+ }
+ break;
+ }
+ case EParseStage::ChunkLength: {
+ if (ProcessData(Line, data, "\r\n", MaxChunkLengthSize)) {
+ if (!Line.empty()) {
+ ChunkLength = ParseHex(Line);
+ if (ChunkLength <= MaxChunkSize) {
+ ContentSize = Content.size() + ChunkLength;
+ if (ContentSize <= MaxChunkContentSize) {
+ Stage = EParseStage::ChunkData;
+ Line.Clear();
+ } else {
+ // Invalid chunk content length
+ Stage = EParseStage::Error;
+ }
+ } else {
+ // Invalid chunk length
+ Stage = EParseStage::Error;
+ }
+ } else {
+ // Invalid body encoding
+ Stage = EParseStage::Error;
+ }
+ }
+ break;
+ }
+ case EParseStage::ChunkData: {
+ if (!IsError()) {
+ if (ProcessData(Content, data, ContentSize)) {
+ if (ProcessData(Line, data, 2)) {
+ if (Line == "\r\n") {
+ if (ChunkLength == 0) {
+ Body = Content;
+ Stage = EParseStage::Done;
+ } else {
+ Stage = EParseStage::ChunkLength;
+ }
+ Line.Clear();
+ } else {
+ // Invalid body encoding
+ Stage = EParseStage::Error;
+ }
+ }
+ }
+ }
+ break;
+ }
+ case EParseStage::Done:
+ case EParseStage::Error:
+ data.Clear();
+ break;
+ default:
+ // Invalid processing sequence
+ Stage = EParseStage::Error;
+ break;
+ }
+ }
+ TSocketBuffer::Advance(len);
+}
+
+template <>
+void THttpParser<THttpResponse, TSocketBuffer>::ConnectionClosed() {
+ if (Stage == EParseStage::Done) {
+ return;
+ }
+ if (Stage == EParseStage::Body) {
+ // ?
+ Stage = EParseStage::Done;
+ } else {
+ LastSuccessStage = Stage;
+ Stage = EParseStage::Error;
+ }
+}
+
+THttpOutgoingResponsePtr THttpIncomingRequest::CreateResponseString(TStringBuf data) {
+ THttpOutgoingResponsePtr response = new THttpOutgoingResponse(this);
+ response->Append(data);
+ response->Reparse();
+ return response;
+}
+
+THttpOutgoingResponsePtr THttpIncomingRequest::CreateResponseOK(TStringBuf body, TStringBuf contentType, TInstant lastModified) {
+ return CreateResponse("200", "OK", contentType, body, lastModified);
+}
+
+THttpOutgoingResponsePtr THttpIncomingRequest::CreateResponseBadRequest(TStringBuf html, TStringBuf contentType) {
+ if (html.empty() && IsError()) {
+ contentType = "text/plain";
+ html = GetErrorText();
+ }
+ return CreateResponse("400", "Bad Request", contentType, html);
+}
+
+THttpOutgoingResponsePtr THttpIncomingRequest::CreateResponseNotFound(TStringBuf html, TStringBuf contentType) {
+ return CreateResponse("404", "Not Found", contentType, html);
+}
+
+THttpOutgoingResponsePtr THttpIncomingRequest::CreateResponseServiceUnavailable(TStringBuf html, TStringBuf contentType) {
+ return CreateResponse("503", "Service Unavailable", contentType, html);
+}
+
+THttpOutgoingResponsePtr THttpIncomingRequest::CreateResponseGatewayTimeout(TStringBuf html, TStringBuf contentType) {
+ return CreateResponse("504", "Gateway Timeout", contentType, html);
+}
+
+THttpIncomingResponse::THttpIncomingResponse(THttpOutgoingRequestPtr request)
+ : Request(request)
+{}
+
+THttpOutgoingResponsePtr THttpIncomingRequest::CreateResponse(TStringBuf status, TStringBuf message, TStringBuf contentType, TStringBuf body, TInstant lastModified) {
+ TStringBuf version = Version;
+ if (version != "1.0" && version != "1.1") {
+ version = "1.1";
+ }
+ THttpOutgoingResponsePtr response = new THttpOutgoingResponse(this, "HTTP", version, status, message);
+ response->Set<&THttpResponse::Connection>(GetConnection());
+ if (!WorkerName.empty()) {
+ response->Set("X-Worker-Name", WorkerName);
+ }
+ if (!contentType.empty() && !body.empty()) {
+ response->Set<&THttpResponse::ContentType>(contentType);
+ }
+ if (lastModified) {
+ response->Set<&THttpResponse::LastModified>(lastModified.FormatGmTime("%a, %d %b %Y %H:%M:%S GMT"));
+ }
+ if (response->IsNeedBody() || !body.empty()) {
+ if (Method == "HEAD") {
+ response->Set<&THttpResponse::ContentLength>(ToString(body.size()));
+ } else {
+ response->Set<&THttpResponse::Body>(body);
+ }
+ }
+ return response;
+}
+
+THttpIncomingRequestPtr THttpIncomingRequest::Duplicate() {
+ THttpIncomingRequestPtr request = new THttpIncomingRequest(*this);
+ request->Reparse();
+ request->Timer.Reset();
+ return request;
+}
+
+THttpIncomingResponsePtr THttpIncomingResponse::Duplicate(THttpOutgoingRequestPtr request) {
+ THttpIncomingResponsePtr response = new THttpIncomingResponse(*this);
+ response->Reparse();
+ response->Request = request;
+ return response;
+}
+
+THttpOutgoingResponsePtr THttpOutgoingResponse::Duplicate(THttpIncomingRequestPtr request) {
+ THttpOutgoingResponsePtr response = new THttpOutgoingResponse(*this);
+ response->Reparse();
+ response->Request = request;
+ return response;
+}
+
+
+THttpOutgoingResponsePtr THttpIncomingResponse::Reverse(THttpIncomingRequestPtr request) {
+ THttpOutgoingResponsePtr response = new THttpOutgoingResponse(request);
+ response->Assign(Data(), Size());
+ response->Reparse();
+ return response;
+}
+
+THttpOutgoingRequest::THttpOutgoingRequest(TStringBuf method, TStringBuf scheme, TStringBuf host, TStringBuf uri, TStringBuf protocol, TStringBuf version) {
+ Secure = (scheme == "https");
+ TString urie = UrlEscapeRet(uri);
+ InitRequest(method, urie, protocol, version);
+ if (host) {
+ Set<&THttpRequest::Host>(host);
+ }
+}
+
+THttpOutgoingRequest::THttpOutgoingRequest(TStringBuf method, TStringBuf url, TStringBuf protocol, TStringBuf version) {
+ TStringBuf scheme, host, uri;
+ if (!CrackURL(url, scheme, host, uri)) {
+ Y_FAIL("Invalid URL specified");
+ }
+ if (!scheme.empty() && scheme != "http" && scheme != "https") {
+ Y_FAIL("Invalid URL specified");
+ }
+ Secure = (scheme == "https");
+ TString urie = UrlEscapeRet(uri);
+ InitRequest(method, urie, protocol, version);
+ if (host) {
+ Set<&THttpRequest::Host>(host);
+ }
+}
+
+THttpOutgoingRequestPtr THttpOutgoingRequest::CreateRequestString(const TString& data) {
+ THttpOutgoingRequestPtr request = new THttpOutgoingRequest();
+ request->Assign(data.data(), data.size());
+ request->Reparse();
+ return request;
+}
+
+THttpOutgoingRequestPtr THttpOutgoingRequest::CreateRequestGet(TStringBuf url) {
+ return CreateRequest("GET", url);
+}
+
+THttpOutgoingRequestPtr THttpOutgoingRequest::CreateRequestGet(TStringBuf host, TStringBuf uri) {
+ return CreateHttpRequest("GET", host, uri);
+}
+
+THttpOutgoingRequestPtr THttpOutgoingRequest::CreateRequestPost(TStringBuf url, TStringBuf contentType, TStringBuf body) {
+ return CreateRequest("POST", url, contentType, body);
+}
+
+THttpOutgoingRequestPtr THttpOutgoingRequest::CreateRequestPost(TStringBuf host, TStringBuf uri, TStringBuf contentType, TStringBuf body) {
+ return CreateHttpRequest("POST", host, uri, contentType, body);
+}
+
+THttpOutgoingRequestPtr THttpOutgoingRequest::CreateRequest(TStringBuf method, TStringBuf url, TStringBuf contentType, TStringBuf body) {
+ THttpOutgoingRequestPtr request = new THttpOutgoingRequest(method, url, "HTTP", "1.1");
+ request->Set<&THttpRequest::Accept>("*/*");
+ if (!contentType.empty()) {
+ request->Set<&THttpRequest::ContentType>(contentType);
+ request->Set<&THttpRequest::Body>(body);
+ }
+ return request;
+}
+
+THttpOutgoingRequestPtr THttpOutgoingRequest::CreateHttpRequest(TStringBuf method, TStringBuf host, TStringBuf uri, TStringBuf contentType, TStringBuf body) {
+ THttpOutgoingRequestPtr request = new THttpOutgoingRequest(method, "http", host, uri, "HTTP", "1.1");
+ request->Set<&THttpRequest::Accept>("*/*");
+ if (!contentType.empty()) {
+ request->Set<&THttpRequest::ContentType>(contentType);
+ request->Set<&THttpRequest::Body>(body);
+ }
+ return request;
+}
+
+THttpOutgoingRequestPtr THttpOutgoingRequest::Duplicate() {
+ THttpOutgoingRequestPtr request = new THttpOutgoingRequest(*this);
+ request->Reparse();
+ return request;
+}
+
+THttpOutgoingResponse::THttpOutgoingResponse(THttpIncomingRequestPtr request)
+ : Request(request)
+{}
+
+THttpOutgoingResponse::THttpOutgoingResponse(THttpIncomingRequestPtr request, TStringBuf protocol, TStringBuf version, TStringBuf status, TStringBuf message)
+ : Request(request)
+{
+ InitResponse(protocol, version, status, message);
+}
+
+const size_t THttpConfig::BUFFER_MIN_STEP;
+const TDuration THttpConfig::CONNECTION_TIMEOUT;
+
+TUrlParameters::TUrlParameters(TStringBuf url) {
+ TStringBuf base;
+ TStringBuf params;
+ if (url.TrySplit('?', base, params)) {
+ for (TStringBuf param = params.NextTok('&'); !param.empty(); param = params.NextTok('&')) {
+ TStringBuf name = param.NextTok('=');
+ Parameters[name] = param;
+ }
+ }
+}
+
+TString TUrlParameters::operator [](TStringBuf name) const {
+ TString value(Get(name));
+ CGIUnescape(value);
+ return value;
+}
+
+bool TUrlParameters::Has(TStringBuf name) const {
+ return Parameters.count(name) != 0;
+}
+
+TStringBuf TUrlParameters::Get(TStringBuf name) const {
+ auto it = Parameters.find(name);
+ if (it != Parameters.end()) {
+ return it->second;
+ }
+ return TStringBuf();
+}
+
+TString TUrlParameters::Render() const {
+ TStringBuilder parameters;
+ for (const std::pair<TStringBuf, TStringBuf> parameter : Parameters) {
+ if (parameters.empty()) {
+ parameters << '?';
+ } else {
+ parameters << '&';
+ }
+ parameters << parameter.first;
+ parameters << '=';
+ parameters << parameter.second;
+ }
+ return parameters;
+}
+
+TCookies::TCookies(TStringBuf cookie) {
+ for (TStringBuf param = cookie.NextTok(';'); !param.empty(); param = cookie.NextTok(';')) {
+ param.SkipPrefix(" ");
+ TStringBuf name = param.NextTok('=');
+ Cookies[name] = param;
+ }
+}
+
+TStringBuf TCookies::operator [](TStringBuf name) const {
+ return Get(name);
+}
+
+bool TCookies::Has(TStringBuf name) const {
+ return Cookies.count(name) != 0;
+}
+
+TStringBuf TCookies::Get(TStringBuf name) const {
+ auto it = Cookies.find(name);
+ if (it != Cookies.end()) {
+ return it->second;
+ }
+ return TStringBuf();
+}
+
+TString TCookies::Render() const {
+ TStringBuilder cookies;
+ for (const std::pair<TStringBuf, TStringBuf> cookie : Cookies) {
+ if (!cookies.empty()) {
+ cookies << ' ';
+ }
+ cookies << cookie.first;
+ cookies << '=';
+ cookies << cookie.second;
+ cookies << ';';
+ }
+ return cookies;
+}
+
+TCookiesBuilder::TCookiesBuilder()
+ :TCookies(TStringBuf())
+{}
+
+void TCookiesBuilder::Set(TStringBuf name, TStringBuf data) {
+ Data.emplace_back(name, data);
+ Cookies[Data.back().first] = Data.back().second;
+}
+
+THeaders::THeaders(TStringBuf headers) {
+ for (TStringBuf param = headers.NextTok("\r\n"); !param.empty(); param = headers.NextTok("\r\n")) {
+ TStringBuf name = param.NextTok(":");
+ param.SkipPrefix(" ");
+ Headers[name] = param;
+ }
+}
+
+TStringBuf THeaders::operator [](TStringBuf name) const {
+ return Get(name);
+}
+
+bool THeaders::Has(TStringBuf name) const {
+ return Headers.count(name) != 0;
+}
+
+TStringBuf THeaders::Get(TStringBuf name) const {
+ auto it = Headers.find(name);
+ if (it != Headers.end()) {
+ return it->second;
+ }
+ return TStringBuf();
+}
+
+TString THeaders::Render() const {
+ TStringBuilder headers;
+ for (const std::pair<TStringBuf, TStringBuf> header : Headers) {
+ headers << header.first;
+ headers << ": ";
+ headers << header.second;
+ headers << "\r\n";
+ }
+ return headers;
+}
+
+THeadersBuilder::THeadersBuilder()
+ :THeaders(TStringBuf())
+{}
+
+THeadersBuilder::THeadersBuilder(const THeadersBuilder& builder) {
+ for (const auto& pr : builder.Headers) {
+ Set(pr.first, pr.second);
+ }
+}
+
+void THeadersBuilder::Set(TStringBuf name, TStringBuf data) {
+ Data.emplace_back(name, data);
+ Headers[Data.back().first] = Data.back().second;
+}
+
+}
diff --git a/library/cpp/actors/http/http.h b/library/cpp/actors/http/http.h
index a11d6158ee0..96c5c1ec48e 100644
--- a/library/cpp/actors/http/http.h
+++ b/library/cpp/actors/http/http.h
@@ -1,703 +1,703 @@
-#pragma once
-#include <util/datetime/base.h>
-#include <util/string/builder.h>
-#include <util/system/thread.h>
-#include <util/system/hp_timer.h>
-#include <util/generic/hash_set.h>
-#include <util/generic/buffer.h>
-#include <util/generic/intrlist.h>
-#include "http_config.h"
-
-// TODO(xenoxeno): hide in implementation
-template <typename Type>
-struct THash<TIntrusivePtr<Type>> {
- size_t operator ()(const TIntrusivePtr<Type>& ptr) const { return reinterpret_cast<size_t>(ptr.Get()); }
-};
-
-template<>
-inline void Out<TSockAddrInet6>(IOutputStream& o, const TSockAddrInet6& x) {
- o << x.ToString();
-}
-
-namespace NHttp {
-
-bool IsIPv6(const TString& host);
-bool CrackURL(TStringBuf url, TStringBuf& scheme, TStringBuf& host, TStringBuf& uri);
-void CrackAddress(const TString& address, TString& hostname, TIpPort& port);
-void TrimBegin(TStringBuf& target, char delim);
-void TrimEnd(TStringBuf& target, char delim);
-void Trim(TStringBuf& target, char delim);
-void TrimEnd(TString& target, char delim);
-
-struct TLessNoCase {
- bool operator()(TStringBuf l, TStringBuf r) const {
- auto ll = l.length();
- auto rl = r.length();
- if (ll != rl) {
- return ll < rl;
- }
- return strnicmp(l.data(), r.data(), ll) < 0;
- }
-};
-
-struct TUrlParameters {
- THashMap<TStringBuf, TStringBuf> Parameters;
-
- TUrlParameters(TStringBuf url);
- TString operator [](TStringBuf name) const;
- bool Has(TStringBuf name) const;
- TStringBuf Get(TStringBuf name) const; // raw
- TString Render() const;
-};
-
-struct TCookies {
- THashMap<TStringBuf, TStringBuf> Cookies;
-
- TCookies(TStringBuf cookie);
- TCookies(const TCookies&) = delete;
- TStringBuf operator [](TStringBuf name) const;
- bool Has(TStringBuf name) const;
- TStringBuf Get(TStringBuf name) const; // raw
- TString Render() const;
-};
-
-struct TCookiesBuilder : TCookies {
+#pragma once
+#include <util/datetime/base.h>
+#include <util/string/builder.h>
+#include <util/system/thread.h>
+#include <util/system/hp_timer.h>
+#include <util/generic/hash_set.h>
+#include <util/generic/buffer.h>
+#include <util/generic/intrlist.h>
+#include "http_config.h"
+
+// TODO(xenoxeno): hide in implementation
+template <typename Type>
+struct THash<TIntrusivePtr<Type>> {
+ size_t operator ()(const TIntrusivePtr<Type>& ptr) const { return reinterpret_cast<size_t>(ptr.Get()); }
+};
+
+template<>
+inline void Out<TSockAddrInet6>(IOutputStream& o, const TSockAddrInet6& x) {
+ o << x.ToString();
+}
+
+namespace NHttp {
+
+bool IsIPv6(const TString& host);
+bool CrackURL(TStringBuf url, TStringBuf& scheme, TStringBuf& host, TStringBuf& uri);
+void CrackAddress(const TString& address, TString& hostname, TIpPort& port);
+void TrimBegin(TStringBuf& target, char delim);
+void TrimEnd(TStringBuf& target, char delim);
+void Trim(TStringBuf& target, char delim);
+void TrimEnd(TString& target, char delim);
+
+struct TLessNoCase {
+ bool operator()(TStringBuf l, TStringBuf r) const {
+ auto ll = l.length();
+ auto rl = r.length();
+ if (ll != rl) {
+ return ll < rl;
+ }
+ return strnicmp(l.data(), r.data(), ll) < 0;
+ }
+};
+
+struct TUrlParameters {
+ THashMap<TStringBuf, TStringBuf> Parameters;
+
+ TUrlParameters(TStringBuf url);
+ TString operator [](TStringBuf name) const;
+ bool Has(TStringBuf name) const;
+ TStringBuf Get(TStringBuf name) const; // raw
+ TString Render() const;
+};
+
+struct TCookies {
+ THashMap<TStringBuf, TStringBuf> Cookies;
+
+ TCookies(TStringBuf cookie);
+ TCookies(const TCookies&) = delete;
+ TStringBuf operator [](TStringBuf name) const;
+ bool Has(TStringBuf name) const;
+ TStringBuf Get(TStringBuf name) const; // raw
+ TString Render() const;
+};
+
+struct TCookiesBuilder : TCookies {
TDeque<std::pair<TString, TString>> Data;
-
- TCookiesBuilder();
- void Set(TStringBuf name, TStringBuf data);
-};
-
-struct THeaders {
- TMap<TStringBuf, TStringBuf, TLessNoCase> Headers;
-
- THeaders() = default;
- THeaders(TStringBuf headers);
- THeaders(const THeaders&) = delete;
- TStringBuf operator [](TStringBuf name) const;
- bool Has(TStringBuf name) const;
- TStringBuf Get(TStringBuf name) const; // raw
- TString Render() const;
-};
-
-struct THeadersBuilder : THeaders {
- TDeque<std::pair<TString, TString>> Data;
-
- THeadersBuilder();
- THeadersBuilder(const THeadersBuilder& builder);
- void Set(TStringBuf name, TStringBuf data);
-};
-
-class TSocketBuffer : public TBuffer, public THttpConfig {
-public:
- TSocketBuffer()
- : TBuffer(BUFFER_SIZE)
- {}
-
- bool EnsureEnoughSpaceAvailable(size_t need) {
- size_t avail = Avail();
- if (avail < need) {
- Reserve(Capacity() + std::max(need, BUFFER_MIN_STEP));
- return false;
- }
- return true;
- }
-};
-
-class THttpRequest {
-public:
- TStringBuf Method;
- TStringBuf URL;
- TStringBuf Protocol;
- TStringBuf Version;
- TStringBuf Headers;
-
- TStringBuf Host;
- TStringBuf Accept;
- TStringBuf Connection;
- TStringBuf ContentType;
- TStringBuf ContentLength;
- TStringBuf TransferEncoding;
-
- TStringBuf Body;
-
- static const TMap<TStringBuf, TStringBuf THttpRequest::*, TLessNoCase> HeadersLocation;
-
- template <TStringBuf THttpRequest::* Header>
- static TStringBuf GetName();
- void Clear();
-};
-
-class THttpResponse {
-public:
- TStringBuf Protocol;
- TStringBuf Version;
- TStringBuf Status;
- TStringBuf Message;
- TStringBuf Headers;
-
- TStringBuf Connection;
- TStringBuf ContentType;
- TStringBuf ContentLength;
- TStringBuf TransferEncoding;
- TStringBuf LastModified;
+
+ TCookiesBuilder();
+ void Set(TStringBuf name, TStringBuf data);
+};
+
+struct THeaders {
+ TMap<TStringBuf, TStringBuf, TLessNoCase> Headers;
+
+ THeaders() = default;
+ THeaders(TStringBuf headers);
+ THeaders(const THeaders&) = delete;
+ TStringBuf operator [](TStringBuf name) const;
+ bool Has(TStringBuf name) const;
+ TStringBuf Get(TStringBuf name) const; // raw
+ TString Render() const;
+};
+
+struct THeadersBuilder : THeaders {
+ TDeque<std::pair<TString, TString>> Data;
+
+ THeadersBuilder();
+ THeadersBuilder(const THeadersBuilder& builder);
+ void Set(TStringBuf name, TStringBuf data);
+};
+
+class TSocketBuffer : public TBuffer, public THttpConfig {
+public:
+ TSocketBuffer()
+ : TBuffer(BUFFER_SIZE)
+ {}
+
+ bool EnsureEnoughSpaceAvailable(size_t need) {
+ size_t avail = Avail();
+ if (avail < need) {
+ Reserve(Capacity() + std::max(need, BUFFER_MIN_STEP));
+ return false;
+ }
+ return true;
+ }
+};
+
+class THttpRequest {
+public:
+ TStringBuf Method;
+ TStringBuf URL;
+ TStringBuf Protocol;
+ TStringBuf Version;
+ TStringBuf Headers;
+
+ TStringBuf Host;
+ TStringBuf Accept;
+ TStringBuf Connection;
+ TStringBuf ContentType;
+ TStringBuf ContentLength;
+ TStringBuf TransferEncoding;
+
+ TStringBuf Body;
+
+ static const TMap<TStringBuf, TStringBuf THttpRequest::*, TLessNoCase> HeadersLocation;
+
+ template <TStringBuf THttpRequest::* Header>
+ static TStringBuf GetName();
+ void Clear();
+};
+
+class THttpResponse {
+public:
+ TStringBuf Protocol;
+ TStringBuf Version;
+ TStringBuf Status;
+ TStringBuf Message;
+ TStringBuf Headers;
+
+ TStringBuf Connection;
+ TStringBuf ContentType;
+ TStringBuf ContentLength;
+ TStringBuf TransferEncoding;
+ TStringBuf LastModified;
TStringBuf ContentEncoding;
-
- TStringBuf Body;
-
- static const TMap<TStringBuf, TStringBuf THttpResponse::*, TLessNoCase> HeadersLocation;
-
- template <TStringBuf THttpResponse::* Header>
- static TStringBuf GetName();
- void Clear();
-};
-
-template <typename HeaderType, typename BufferType>
-class THttpParser : public HeaderType, public BufferType {
-public:
- enum class EParseStage : ui8 {
- Method,
- URL,
- Protocol,
- Version,
- Status,
- Message,
- Header,
- Body,
- ChunkLength,
- ChunkData,
- Done,
- Error,
- };
-
- static constexpr size_t MaxMethodSize = 6;
- static constexpr size_t MaxURLSize = 1024;
- static constexpr size_t MaxProtocolSize = 4;
- static constexpr size_t MaxVersionSize = 4;
- static constexpr size_t MaxStatusSize = 3;
- static constexpr size_t MaxMessageSize = 1024;
+
+ TStringBuf Body;
+
+ static const TMap<TStringBuf, TStringBuf THttpResponse::*, TLessNoCase> HeadersLocation;
+
+ template <TStringBuf THttpResponse::* Header>
+ static TStringBuf GetName();
+ void Clear();
+};
+
+template <typename HeaderType, typename BufferType>
+class THttpParser : public HeaderType, public BufferType {
+public:
+ enum class EParseStage : ui8 {
+ Method,
+ URL,
+ Protocol,
+ Version,
+ Status,
+ Message,
+ Header,
+ Body,
+ ChunkLength,
+ ChunkData,
+ Done,
+ Error,
+ };
+
+ static constexpr size_t MaxMethodSize = 6;
+ static constexpr size_t MaxURLSize = 1024;
+ static constexpr size_t MaxProtocolSize = 4;
+ static constexpr size_t MaxVersionSize = 4;
+ static constexpr size_t MaxStatusSize = 3;
+ static constexpr size_t MaxMessageSize = 1024;
static constexpr size_t MaxHeaderSize = 8192;
- static constexpr size_t MaxChunkLengthSize = 8;
- static constexpr size_t MaxChunkSize = 256 * 1024 * 1024;
- static constexpr size_t MaxChunkContentSize = 1 * 1024 * 1024 * 1024;
-
- EParseStage Stage;
- EParseStage LastSuccessStage;
- TStringBuf Line;
- TStringBuf& Header = Line;
- size_t ChunkLength = 0;
- size_t ContentSize = 0;
- TString Content;
-
- THttpParser(const THttpParser& src)
- : HeaderType(src)
- , BufferType(src)
- , Stage(src.Stage)
- , LastSuccessStage(src.LastSuccessStage)
- , Line()
- , Header(Line)
- , ChunkLength(src.ChunkLength)
- , ContentSize(src.ContentSize)
- , Content(src.Content)
- {}
-
- template <typename StringType>
- bool ProcessData(StringType& target, TStringBuf& source, char delim, size_t maxLen) {
- TStringBuf maxSource(source.substr(0, maxLen + 1 - target.size()));
- size_t pos = maxSource.find(delim);
- target += maxSource.substr(0, pos);
- source.Skip(pos);
- if (target.size() > maxLen) {
- Stage = EParseStage::Error;
- return false;
- }
- if (!source.empty() && *source.begin() == delim) {
- source.Skip(1);
- }
- return pos != TStringBuf::npos;
- }
-
- template <typename StringType>
- bool ProcessData(StringType& target, TStringBuf& source, TStringBuf delim, size_t maxLen) {
- if (delim.empty()) {
- return false;
- }
- if (delim.size() == 1) {
- return ProcessData(target, source, delim[0], maxLen);
- }
+ static constexpr size_t MaxChunkLengthSize = 8;
+ static constexpr size_t MaxChunkSize = 256 * 1024 * 1024;
+ static constexpr size_t MaxChunkContentSize = 1 * 1024 * 1024 * 1024;
+
+ EParseStage Stage;
+ EParseStage LastSuccessStage;
+ TStringBuf Line;
+ TStringBuf& Header = Line;
+ size_t ChunkLength = 0;
+ size_t ContentSize = 0;
+ TString Content;
+
+ THttpParser(const THttpParser& src)
+ : HeaderType(src)
+ , BufferType(src)
+ , Stage(src.Stage)
+ , LastSuccessStage(src.LastSuccessStage)
+ , Line()
+ , Header(Line)
+ , ChunkLength(src.ChunkLength)
+ , ContentSize(src.ContentSize)
+ , Content(src.Content)
+ {}
+
+ template <typename StringType>
+ bool ProcessData(StringType& target, TStringBuf& source, char delim, size_t maxLen) {
+ TStringBuf maxSource(source.substr(0, maxLen + 1 - target.size()));
+ size_t pos = maxSource.find(delim);
+ target += maxSource.substr(0, pos);
+ source.Skip(pos);
+ if (target.size() > maxLen) {
+ Stage = EParseStage::Error;
+ return false;
+ }
+ if (!source.empty() && *source.begin() == delim) {
+ source.Skip(1);
+ }
+ return pos != TStringBuf::npos;
+ }
+
+ template <typename StringType>
+ bool ProcessData(StringType& target, TStringBuf& source, TStringBuf delim, size_t maxLen) {
+ if (delim.empty()) {
+ return false;
+ }
+ if (delim.size() == 1) {
+ return ProcessData(target, source, delim[0], maxLen);
+ }
if (ProcessData(target, source, delim.back(), maxLen + 1)) {
- for (signed i = delim.size() - 2; i >= 0; --i) {
- TrimEnd(target, delim[i]);
- }
- return true;
- }
- return false;
- }
-
- template <typename StringType>
- bool ProcessData(StringType& target, TStringBuf& source, size_t size) {
- TStringBuf maxSource(source.substr(0, size - target.size()));
- target += maxSource;
- source.Skip(maxSource.size());
- if (target.size() > size && !source.empty()) {
- Stage = EParseStage::Error;
- return false;
- }
- return target.size() == size;
- }
-
- void ProcessHeader(TStringBuf& header) {
- TStringBuf name = header.NextTok(':');
- TrimBegin(name, ' ');
- TStringBuf value = header;
- Trim(value, ' ');
- auto cit = HeaderType::HeadersLocation.find(name);
- if (cit != HeaderType::HeadersLocation.end()) {
- this->*cit->second = value;
- }
- header.Clear();
- }
-
- size_t ParseHex(TStringBuf value) {
- size_t result = 0;
- for (char ch : value) {
- if (ch >= '0' && ch <= '9') {
- result *= 16;
- result += ch - '0';
- } else if (ch >= 'a' && ch <= 'f') {
- result *= 16;
- result += 10 + ch - 'a';
- } else if (ch >= 'A' && ch <= 'F') {
- result *= 16;
- result += 10 + ch - 'A';
- } else if (ch == ';') {
- break;
- } else if (isspace(ch)) {
- continue;
- } else {
- Stage = EParseStage::Error;
- return 0;
- }
- }
- return result;
- }
-
- void Advance(size_t len);
- void ConnectionClosed();
-
- void Clear() {
- BufferType::Clear();
- HeaderType::Clear();
- Stage = GetInitialStage();
- Line.Clear();
- Content.clear();
- }
-
- bool IsReady() const {
- return Stage == EParseStage::Done;
- }
-
- bool IsError() const {
- return Stage == EParseStage::Error;
- }
-
- TStringBuf GetErrorText() const {
- switch (LastSuccessStage) {
- case EParseStage::Method:
- return "Invalid http method";
- case EParseStage::URL:
- return "Invalid url";
- case EParseStage::Protocol:
- return "Invalid http protocol";
- case EParseStage::Version:
- return "Invalid http version";
- case EParseStage::Status:
- return "Invalid http status";
- case EParseStage::Message:
- return "Invalid http message";
- case EParseStage::Header:
- return "Invalid http header";
- case EParseStage::Body:
- return "Invalid content body";
- case EParseStage::ChunkLength:
- case EParseStage::ChunkData:
- return "Broken chunked data";
- case EParseStage::Done:
- return "Everything is fine";
- case EParseStage::Error:
- return "Error on error"; // wat? ...because we don't want to include default label here
- }
- }
-
- bool IsDone() const {
- return IsReady() || IsError();
- }
-
- bool HaveBody() const {
- return !HeaderType::ContentType.empty() || !HeaderType::ContentLength.empty() || !HeaderType::TransferEncoding.empty();
- }
-
- bool EnsureEnoughSpaceAvailable(size_t need = BufferType::BUFFER_MIN_STEP) {
- bool result = BufferType::EnsureEnoughSpaceAvailable(need);
- if (!result && !BufferType::Empty()) {
- Reparse();
- }
- return true;
- }
-
- void Reparse() {
- size_t size = BufferType::Size();
- Clear();
- Advance(size);
- }
-
- TStringBuf GetRawData() const {
- return TStringBuf(BufferType::Data(), BufferType::Size());
- }
-
- TString GetObfuscatedData() const {
- THeaders headers(HeaderType::Headers);
- TStringBuf authorization(headers["Authorization"]);
- TStringBuf cookie(headers["Cookie"]);
- TStringBuf x_ydb_auth_ticket(headers["x-ydb-auth-ticket"]);
- TStringBuf x_yacloud_subjecttoken(headers["x-yacloud-subjecttoken"]);
- TString data(GetRawData());
- if (!authorization.empty()) {
- auto pos = data.find(authorization);
- if (pos != TString::npos) {
- data.replace(pos, authorization.size(), TString("<obfuscated>"));
- }
- }
- if (!cookie.empty()) {
- auto pos = data.find(cookie);
- if (pos != TString::npos) {
- data.replace(pos, cookie.size(), TString("<obfuscated>"));
- }
- }
- if (!x_ydb_auth_ticket.empty()) {
- auto pos = data.find(x_ydb_auth_ticket);
- if (pos != TString::npos) {
- data.replace(pos, x_ydb_auth_ticket.size(), TString("<obfuscated>"));
- }
- }
- if (!x_yacloud_subjecttoken.empty()) {
- auto pos = data.find(x_yacloud_subjecttoken);
- if (pos != TString::npos) {
- data.replace(pos, x_yacloud_subjecttoken.size(), TString("<obfuscated>"));
- }
- }
- return data;
- }
-
- static EParseStage GetInitialStage();
-
- THttpParser()
- : Stage(GetInitialStage())
- , LastSuccessStage(Stage)
- {}
-};
-
-template <typename HeaderType, typename BufferType>
-class THttpRenderer : public HeaderType, public BufferType {
-public:
- enum class ERenderStage {
- Init,
- Header,
- Body,
- Done,
- Error,
- };
-
- ERenderStage Stage = ERenderStage::Init;
-
- void Append(TStringBuf text) {
- EnsureEnoughSpaceAvailable(text.size());
- BufferType::Append(text.data(), text.size());
- }
-
- void Append(char c) {
- EnsureEnoughSpaceAvailable(sizeof(c));
- BufferType::Append(c);
- }
-
- template <TStringBuf HeaderType::* string>
- void AppendParsedValue(TStringBuf value) {
- Append(value);
- static_cast<HeaderType*>(this)->*string = TStringBuf(BufferType::Pos() - value.size(), value.size());
- }
-
- template <TStringBuf HeaderType::* name>
- void Set(TStringBuf value) {
- Y_VERIFY_DEBUG(Stage == ERenderStage::Header);
- Append(HeaderType::template GetName<name>());
- Append(": ");
- AppendParsedValue<name>(value);
- Append("\r\n");
- HeaderType::Headers = TStringBuf(HeaderType::Headers.Data(), BufferType::Pos() - HeaderType::Headers.Data());
- }
-
- void Set(TStringBuf name, TStringBuf value) {
- Y_VERIFY_DEBUG(Stage == ERenderStage::Header);
- Append(name);
- Append(": ");
- Append(value);
- Append("\r\n");
- HeaderType::Headers = TStringBuf(HeaderType::Headers.Data(), BufferType::Pos() - HeaderType::Headers.Data());
- }
-
- void Set(const THeaders& headers) {
- Y_VERIFY_DEBUG(Stage == ERenderStage::Header);
- Append(headers.Render());
- HeaderType::Headers = TStringBuf(HeaderType::Headers.Data(), BufferType::Pos() - HeaderType::Headers.Data());
- }
-
- //THttpRenderer(TStringBuf method, TStringBuf url, TStringBuf protocol, TStringBuf version); // request
- void InitRequest(TStringBuf method, TStringBuf url, TStringBuf protocol, TStringBuf version) {
- Y_VERIFY_DEBUG(Stage == ERenderStage::Init);
- AppendParsedValue<&THttpRequest::Method>(method);
- Append(' ');
- AppendParsedValue<&THttpRequest::URL>(url);
- Append(' ');
- AppendParsedValue<&THttpRequest::Protocol>(protocol);
- Append('/');
- AppendParsedValue<&THttpRequest::Version>(version);
- Append("\r\n");
- Stage = ERenderStage::Header;
- HeaderType::Headers = TStringBuf(BufferType::Pos(), size_t(0));
- }
-
- //THttpRenderer(TStringBuf protocol, TStringBuf version, TStringBuf status, TStringBuf message); // response
- void InitResponse(TStringBuf protocol, TStringBuf version, TStringBuf status, TStringBuf message) {
- Y_VERIFY_DEBUG(Stage == ERenderStage::Init);
- AppendParsedValue<&THttpResponse::Protocol>(protocol);
- Append('/');
- AppendParsedValue<&THttpResponse::Version>(version);
- Append(' ');
- AppendParsedValue<&THttpResponse::Status>(status);
- Append(' ');
- AppendParsedValue<&THttpResponse::Message>(message);
- Append("\r\n");
- Stage = ERenderStage::Header;
- HeaderType::Headers = TStringBuf(BufferType::Pos(), size_t(0));
- }
-
- void FinishHeader() {
- Append("\r\n");
- HeaderType::Headers = TStringBuf(HeaderType::Headers.Data(), BufferType::Pos() - HeaderType::Headers.Data());
- Stage = ERenderStage::Body;
- }
-
- void SetBody(TStringBuf body) {
- Y_VERIFY_DEBUG(Stage == ERenderStage::Header);
- if (HeaderType::ContentLength.empty()) {
- Set<&HeaderType::ContentLength>(ToString(body.size()));
- }
- FinishHeader();
- AppendParsedValue<&HeaderType::Body>(body);
- Stage = ERenderStage::Done;
- }
-
- bool IsDone() const {
- return Stage == ERenderStage::Done;
- }
-
- void Finish() {
- switch (Stage) {
- case ERenderStage::Header:
- FinishHeader();
+ for (signed i = delim.size() - 2; i >= 0; --i) {
+ TrimEnd(target, delim[i]);
+ }
+ return true;
+ }
+ return false;
+ }
+
+ template <typename StringType>
+ bool ProcessData(StringType& target, TStringBuf& source, size_t size) {
+ TStringBuf maxSource(source.substr(0, size - target.size()));
+ target += maxSource;
+ source.Skip(maxSource.size());
+ if (target.size() > size && !source.empty()) {
+ Stage = EParseStage::Error;
+ return false;
+ }
+ return target.size() == size;
+ }
+
+ void ProcessHeader(TStringBuf& header) {
+ TStringBuf name = header.NextTok(':');
+ TrimBegin(name, ' ');
+ TStringBuf value = header;
+ Trim(value, ' ');
+ auto cit = HeaderType::HeadersLocation.find(name);
+ if (cit != HeaderType::HeadersLocation.end()) {
+ this->*cit->second = value;
+ }
+ header.Clear();
+ }
+
+ size_t ParseHex(TStringBuf value) {
+ size_t result = 0;
+ for (char ch : value) {
+ if (ch >= '0' && ch <= '9') {
+ result *= 16;
+ result += ch - '0';
+ } else if (ch >= 'a' && ch <= 'f') {
+ result *= 16;
+ result += 10 + ch - 'a';
+ } else if (ch >= 'A' && ch <= 'F') {
+ result *= 16;
+ result += 10 + ch - 'A';
+ } else if (ch == ';') {
+ break;
+ } else if (isspace(ch)) {
+ continue;
+ } else {
+ Stage = EParseStage::Error;
+ return 0;
+ }
+ }
+ return result;
+ }
+
+ void Advance(size_t len);
+ void ConnectionClosed();
+
+ void Clear() {
+ BufferType::Clear();
+ HeaderType::Clear();
+ Stage = GetInitialStage();
+ Line.Clear();
+ Content.clear();
+ }
+
+ bool IsReady() const {
+ return Stage == EParseStage::Done;
+ }
+
+ bool IsError() const {
+ return Stage == EParseStage::Error;
+ }
+
+ TStringBuf GetErrorText() const {
+ switch (LastSuccessStage) {
+ case EParseStage::Method:
+ return "Invalid http method";
+ case EParseStage::URL:
+ return "Invalid url";
+ case EParseStage::Protocol:
+ return "Invalid http protocol";
+ case EParseStage::Version:
+ return "Invalid http version";
+ case EParseStage::Status:
+ return "Invalid http status";
+ case EParseStage::Message:
+ return "Invalid http message";
+ case EParseStage::Header:
+ return "Invalid http header";
+ case EParseStage::Body:
+ return "Invalid content body";
+ case EParseStage::ChunkLength:
+ case EParseStage::ChunkData:
+ return "Broken chunked data";
+ case EParseStage::Done:
+ return "Everything is fine";
+ case EParseStage::Error:
+ return "Error on error"; // wat? ...because we don't want to include default label here
+ }
+ }
+
+ bool IsDone() const {
+ return IsReady() || IsError();
+ }
+
+ bool HaveBody() const {
+ return !HeaderType::ContentType.empty() || !HeaderType::ContentLength.empty() || !HeaderType::TransferEncoding.empty();
+ }
+
+ bool EnsureEnoughSpaceAvailable(size_t need = BufferType::BUFFER_MIN_STEP) {
+ bool result = BufferType::EnsureEnoughSpaceAvailable(need);
+ if (!result && !BufferType::Empty()) {
+ Reparse();
+ }
+ return true;
+ }
+
+ void Reparse() {
+ size_t size = BufferType::Size();
+ Clear();
+ Advance(size);
+ }
+
+ TStringBuf GetRawData() const {
+ return TStringBuf(BufferType::Data(), BufferType::Size());
+ }
+
+ TString GetObfuscatedData() const {
+ THeaders headers(HeaderType::Headers);
+ TStringBuf authorization(headers["Authorization"]);
+ TStringBuf cookie(headers["Cookie"]);
+ TStringBuf x_ydb_auth_ticket(headers["x-ydb-auth-ticket"]);
+ TStringBuf x_yacloud_subjecttoken(headers["x-yacloud-subjecttoken"]);
+ TString data(GetRawData());
+ if (!authorization.empty()) {
+ auto pos = data.find(authorization);
+ if (pos != TString::npos) {
+ data.replace(pos, authorization.size(), TString("<obfuscated>"));
+ }
+ }
+ if (!cookie.empty()) {
+ auto pos = data.find(cookie);
+ if (pos != TString::npos) {
+ data.replace(pos, cookie.size(), TString("<obfuscated>"));
+ }
+ }
+ if (!x_ydb_auth_ticket.empty()) {
+ auto pos = data.find(x_ydb_auth_ticket);
+ if (pos != TString::npos) {
+ data.replace(pos, x_ydb_auth_ticket.size(), TString("<obfuscated>"));
+ }
+ }
+ if (!x_yacloud_subjecttoken.empty()) {
+ auto pos = data.find(x_yacloud_subjecttoken);
+ if (pos != TString::npos) {
+ data.replace(pos, x_yacloud_subjecttoken.size(), TString("<obfuscated>"));
+ }
+ }
+ return data;
+ }
+
+ static EParseStage GetInitialStage();
+
+ THttpParser()
+ : Stage(GetInitialStage())
+ , LastSuccessStage(Stage)
+ {}
+};
+
+template <typename HeaderType, typename BufferType>
+class THttpRenderer : public HeaderType, public BufferType {
+public:
+ enum class ERenderStage {
+ Init,
+ Header,
+ Body,
+ Done,
+ Error,
+ };
+
+ ERenderStage Stage = ERenderStage::Init;
+
+ void Append(TStringBuf text) {
+ EnsureEnoughSpaceAvailable(text.size());
+ BufferType::Append(text.data(), text.size());
+ }
+
+ void Append(char c) {
+ EnsureEnoughSpaceAvailable(sizeof(c));
+ BufferType::Append(c);
+ }
+
+ template <TStringBuf HeaderType::* string>
+ void AppendParsedValue(TStringBuf value) {
+ Append(value);
+ static_cast<HeaderType*>(this)->*string = TStringBuf(BufferType::Pos() - value.size(), value.size());
+ }
+
+ template <TStringBuf HeaderType::* name>
+ void Set(TStringBuf value) {
+ Y_VERIFY_DEBUG(Stage == ERenderStage::Header);
+ Append(HeaderType::template GetName<name>());
+ Append(": ");
+ AppendParsedValue<name>(value);
+ Append("\r\n");
+ HeaderType::Headers = TStringBuf(HeaderType::Headers.Data(), BufferType::Pos() - HeaderType::Headers.Data());
+ }
+
+ void Set(TStringBuf name, TStringBuf value) {
+ Y_VERIFY_DEBUG(Stage == ERenderStage::Header);
+ Append(name);
+ Append(": ");
+ Append(value);
+ Append("\r\n");
+ HeaderType::Headers = TStringBuf(HeaderType::Headers.Data(), BufferType::Pos() - HeaderType::Headers.Data());
+ }
+
+ void Set(const THeaders& headers) {
+ Y_VERIFY_DEBUG(Stage == ERenderStage::Header);
+ Append(headers.Render());
+ HeaderType::Headers = TStringBuf(HeaderType::Headers.Data(), BufferType::Pos() - HeaderType::Headers.Data());
+ }
+
+ //THttpRenderer(TStringBuf method, TStringBuf url, TStringBuf protocol, TStringBuf version); // request
+ void InitRequest(TStringBuf method, TStringBuf url, TStringBuf protocol, TStringBuf version) {
+ Y_VERIFY_DEBUG(Stage == ERenderStage::Init);
+ AppendParsedValue<&THttpRequest::Method>(method);
+ Append(' ');
+ AppendParsedValue<&THttpRequest::URL>(url);
+ Append(' ');
+ AppendParsedValue<&THttpRequest::Protocol>(protocol);
+ Append('/');
+ AppendParsedValue<&THttpRequest::Version>(version);
+ Append("\r\n");
+ Stage = ERenderStage::Header;
+ HeaderType::Headers = TStringBuf(BufferType::Pos(), size_t(0));
+ }
+
+ //THttpRenderer(TStringBuf protocol, TStringBuf version, TStringBuf status, TStringBuf message); // response
+ void InitResponse(TStringBuf protocol, TStringBuf version, TStringBuf status, TStringBuf message) {
+ Y_VERIFY_DEBUG(Stage == ERenderStage::Init);
+ AppendParsedValue<&THttpResponse::Protocol>(protocol);
+ Append('/');
+ AppendParsedValue<&THttpResponse::Version>(version);
+ Append(' ');
+ AppendParsedValue<&THttpResponse::Status>(status);
+ Append(' ');
+ AppendParsedValue<&THttpResponse::Message>(message);
+ Append("\r\n");
+ Stage = ERenderStage::Header;
+ HeaderType::Headers = TStringBuf(BufferType::Pos(), size_t(0));
+ }
+
+ void FinishHeader() {
+ Append("\r\n");
+ HeaderType::Headers = TStringBuf(HeaderType::Headers.Data(), BufferType::Pos() - HeaderType::Headers.Data());
+ Stage = ERenderStage::Body;
+ }
+
+ void SetBody(TStringBuf body) {
+ Y_VERIFY_DEBUG(Stage == ERenderStage::Header);
+ if (HeaderType::ContentLength.empty()) {
+ Set<&HeaderType::ContentLength>(ToString(body.size()));
+ }
+ FinishHeader();
+ AppendParsedValue<&HeaderType::Body>(body);
+ Stage = ERenderStage::Done;
+ }
+
+ bool IsDone() const {
+ return Stage == ERenderStage::Done;
+ }
+
+ void Finish() {
+ switch (Stage) {
+ case ERenderStage::Header:
+ FinishHeader();
+ break;
+ default:
+ break;
+ }
+ }
+
+ bool EnsureEnoughSpaceAvailable(size_t need = BufferType::BUFFER_MIN_STEP) {
+ bool result = BufferType::EnsureEnoughSpaceAvailable(need);
+ if (!result && !BufferType::Empty()) {
+ Reparse();
+ }
+ return true;
+ }
+
+ void Clear() {
+ BufferType::Clear();
+ HeaderType::Clear();
+ }
+
+ void Reparse() {
+ // move-magic
+ size_t size = BufferType::Size();
+ THttpParser<HeaderType, BufferType> parser;
+ // move the buffer to parser
+ static_cast<BufferType&>(parser) = std::move(static_cast<BufferType&>(*this));
+ // reparse
+ parser.Clear();
+ parser.Advance(size);
+ // move buffer and result back
+ static_cast<HeaderType&>(*this) = std::move(static_cast<HeaderType&>(parser));
+ static_cast<BufferType&>(*this) = std::move(static_cast<BufferType&>(parser));
+ switch (parser.Stage) {
+ case THttpParser<HeaderType, BufferType>::EParseStage::Method:
+ case THttpParser<HeaderType, BufferType>::EParseStage::URL:
+ case THttpParser<HeaderType, BufferType>::EParseStage::Protocol:
+ case THttpParser<HeaderType, BufferType>::EParseStage::Version:
+ case THttpParser<HeaderType, BufferType>::EParseStage::Status:
+ case THttpParser<HeaderType, BufferType>::EParseStage::Message:
+ Stage = ERenderStage::Init;
+ break;
+ case THttpParser<HeaderType, BufferType>::EParseStage::Header:
+ Stage = ERenderStage::Header;
break;
- default:
- break;
- }
- }
-
- bool EnsureEnoughSpaceAvailable(size_t need = BufferType::BUFFER_MIN_STEP) {
- bool result = BufferType::EnsureEnoughSpaceAvailable(need);
- if (!result && !BufferType::Empty()) {
- Reparse();
- }
- return true;
- }
-
- void Clear() {
- BufferType::Clear();
- HeaderType::Clear();
- }
-
- void Reparse() {
- // move-magic
- size_t size = BufferType::Size();
- THttpParser<HeaderType, BufferType> parser;
- // move the buffer to parser
- static_cast<BufferType&>(parser) = std::move(static_cast<BufferType&>(*this));
- // reparse
- parser.Clear();
- parser.Advance(size);
- // move buffer and result back
- static_cast<HeaderType&>(*this) = std::move(static_cast<HeaderType&>(parser));
- static_cast<BufferType&>(*this) = std::move(static_cast<BufferType&>(parser));
- switch (parser.Stage) {
- case THttpParser<HeaderType, BufferType>::EParseStage::Method:
- case THttpParser<HeaderType, BufferType>::EParseStage::URL:
- case THttpParser<HeaderType, BufferType>::EParseStage::Protocol:
- case THttpParser<HeaderType, BufferType>::EParseStage::Version:
- case THttpParser<HeaderType, BufferType>::EParseStage::Status:
- case THttpParser<HeaderType, BufferType>::EParseStage::Message:
- Stage = ERenderStage::Init;
- break;
- case THttpParser<HeaderType, BufferType>::EParseStage::Header:
- Stage = ERenderStage::Header;
- break;
- case THttpParser<HeaderType, BufferType>::EParseStage::Body:
- case THttpParser<HeaderType, BufferType>::EParseStage::ChunkLength:
- case THttpParser<HeaderType, BufferType>::EParseStage::ChunkData:
- Stage = ERenderStage::Body;
- break;
- case THttpParser<HeaderType, BufferType>::EParseStage::Done:
- Stage = ERenderStage::Done;
- break;
- case THttpParser<HeaderType, BufferType>::EParseStage::Error:
- Stage = ERenderStage::Error;
- break;
- }
- Y_VERIFY(size == BufferType::Size());
- }
-
- TStringBuf GetRawData() const {
- return TStringBuf(BufferType::Data(), BufferType::Size());
- }
-};
-
-template <>
-template <>
-inline void THttpRenderer<THttpResponse, TSocketBuffer>::Set<&THttpResponse::Body>(TStringBuf value) {
- SetBody(value);
-}
-
-template <>
-template <>
-inline void THttpRenderer<THttpRequest, TSocketBuffer>::Set<&THttpRequest::Body>(TStringBuf value) {
- SetBody(value);
-}
-
-class THttpIncomingRequest;
-using THttpIncomingRequestPtr = TIntrusivePtr<THttpIncomingRequest>;
-
-class THttpOutgoingResponse;
-using THttpOutgoingResponsePtr = TIntrusivePtr<THttpOutgoingResponse>;
-
-class THttpIncomingRequest :
- public THttpParser<THttpRequest, TSocketBuffer>,
- public TRefCounted<THttpIncomingRequest, TAtomicCounter> {
-public:
- THttpConfig::SocketAddressType Address;
- TString WorkerName;
- THPTimer Timer;
+ case THttpParser<HeaderType, BufferType>::EParseStage::Body:
+ case THttpParser<HeaderType, BufferType>::EParseStage::ChunkLength:
+ case THttpParser<HeaderType, BufferType>::EParseStage::ChunkData:
+ Stage = ERenderStage::Body;
+ break;
+ case THttpParser<HeaderType, BufferType>::EParseStage::Done:
+ Stage = ERenderStage::Done;
+ break;
+ case THttpParser<HeaderType, BufferType>::EParseStage::Error:
+ Stage = ERenderStage::Error;
+ break;
+ }
+ Y_VERIFY(size == BufferType::Size());
+ }
+
+ TStringBuf GetRawData() const {
+ return TStringBuf(BufferType::Data(), BufferType::Size());
+ }
+};
+
+template <>
+template <>
+inline void THttpRenderer<THttpResponse, TSocketBuffer>::Set<&THttpResponse::Body>(TStringBuf value) {
+ SetBody(value);
+}
+
+template <>
+template <>
+inline void THttpRenderer<THttpRequest, TSocketBuffer>::Set<&THttpRequest::Body>(TStringBuf value) {
+ SetBody(value);
+}
+
+class THttpIncomingRequest;
+using THttpIncomingRequestPtr = TIntrusivePtr<THttpIncomingRequest>;
+
+class THttpOutgoingResponse;
+using THttpOutgoingResponsePtr = TIntrusivePtr<THttpOutgoingResponse>;
+
+class THttpIncomingRequest :
+ public THttpParser<THttpRequest, TSocketBuffer>,
+ public TRefCounted<THttpIncomingRequest, TAtomicCounter> {
+public:
+ THttpConfig::SocketAddressType Address;
+ TString WorkerName;
+ THPTimer Timer;
+ bool Secure = false;
+
+ bool IsConnectionClose() const {
+ if (Connection.empty()) {
+ return Version == "1.0";
+ } else {
+ return Connection == "close";
+ }
+ }
+
+ TStringBuf GetConnection() const {
+ if (!Connection.empty()) {
+ return Connection;
+ }
+ return Version == "1.0" ? "close" : "keep-alive";
+ }
+
+ THttpOutgoingResponsePtr CreateResponseOK(TStringBuf body, TStringBuf contentType = "text/html", TInstant lastModified = TInstant());
+ THttpOutgoingResponsePtr CreateResponseString(TStringBuf data);
+ THttpOutgoingResponsePtr CreateResponseBadRequest(TStringBuf html = TStringBuf(), TStringBuf contentType = "text/html"); // 400
+ THttpOutgoingResponsePtr CreateResponseNotFound(TStringBuf html = TStringBuf(), TStringBuf contentType = "text/html"); // 404
+ THttpOutgoingResponsePtr CreateResponseServiceUnavailable(TStringBuf html = TStringBuf(), TStringBuf contentType = "text/html"); // 503
+ THttpOutgoingResponsePtr CreateResponseGatewayTimeout(TStringBuf html = TStringBuf(), TStringBuf contentType = "text/html"); // 504
+ THttpOutgoingResponsePtr CreateResponse(
+ TStringBuf status,
+ TStringBuf message,
+ TStringBuf contentType = TStringBuf(),
+ TStringBuf body = TStringBuf(),
+ TInstant lastModified = TInstant());
+
+ THttpIncomingRequestPtr Duplicate();
+};
+
+class THttpIncomingResponse;
+using THttpIncomingResponsePtr = TIntrusivePtr<THttpIncomingResponse>;
+
+class THttpOutgoingRequest;
+using THttpOutgoingRequestPtr = TIntrusivePtr<THttpOutgoingRequest>;
+
+class THttpIncomingResponse :
+ public THttpParser<THttpResponse, TSocketBuffer>,
+ public TRefCounted<THttpIncomingResponse, TAtomicCounter> {
+public:
+ THttpIncomingResponse(THttpOutgoingRequestPtr request);
+
+ THttpOutgoingRequestPtr GetRequest() const {
+ return Request;
+ }
+
+ THttpIncomingResponsePtr Duplicate(THttpOutgoingRequestPtr request);
+ THttpOutgoingResponsePtr Reverse(THttpIncomingRequestPtr request);
+
+protected:
+ THttpOutgoingRequestPtr Request;
+};
+
+class THttpOutgoingRequest :
+ public THttpRenderer<THttpRequest, TSocketBuffer>,
+ public TRefCounted<THttpOutgoingRequest, TAtomicCounter> {
+public:
+ THPTimer Timer;
bool Secure = false;
-
- bool IsConnectionClose() const {
- if (Connection.empty()) {
- return Version == "1.0";
- } else {
- return Connection == "close";
- }
- }
-
- TStringBuf GetConnection() const {
- if (!Connection.empty()) {
- return Connection;
- }
- return Version == "1.0" ? "close" : "keep-alive";
- }
-
- THttpOutgoingResponsePtr CreateResponseOK(TStringBuf body, TStringBuf contentType = "text/html", TInstant lastModified = TInstant());
- THttpOutgoingResponsePtr CreateResponseString(TStringBuf data);
- THttpOutgoingResponsePtr CreateResponseBadRequest(TStringBuf html = TStringBuf(), TStringBuf contentType = "text/html"); // 400
- THttpOutgoingResponsePtr CreateResponseNotFound(TStringBuf html = TStringBuf(), TStringBuf contentType = "text/html"); // 404
- THttpOutgoingResponsePtr CreateResponseServiceUnavailable(TStringBuf html = TStringBuf(), TStringBuf contentType = "text/html"); // 503
- THttpOutgoingResponsePtr CreateResponseGatewayTimeout(TStringBuf html = TStringBuf(), TStringBuf contentType = "text/html"); // 504
- THttpOutgoingResponsePtr CreateResponse(
- TStringBuf status,
- TStringBuf message,
- TStringBuf contentType = TStringBuf(),
- TStringBuf body = TStringBuf(),
- TInstant lastModified = TInstant());
-
- THttpIncomingRequestPtr Duplicate();
-};
-
-class THttpIncomingResponse;
-using THttpIncomingResponsePtr = TIntrusivePtr<THttpIncomingResponse>;
-
-class THttpOutgoingRequest;
-using THttpOutgoingRequestPtr = TIntrusivePtr<THttpOutgoingRequest>;
-
-class THttpIncomingResponse :
- public THttpParser<THttpResponse, TSocketBuffer>,
- public TRefCounted<THttpIncomingResponse, TAtomicCounter> {
-public:
- THttpIncomingResponse(THttpOutgoingRequestPtr request);
-
- THttpOutgoingRequestPtr GetRequest() const {
- return Request;
- }
-
- THttpIncomingResponsePtr Duplicate(THttpOutgoingRequestPtr request);
- THttpOutgoingResponsePtr Reverse(THttpIncomingRequestPtr request);
-
-protected:
- THttpOutgoingRequestPtr Request;
-};
-
-class THttpOutgoingRequest :
- public THttpRenderer<THttpRequest, TSocketBuffer>,
- public TRefCounted<THttpOutgoingRequest, TAtomicCounter> {
-public:
- THPTimer Timer;
- bool Secure = false;
-
- THttpOutgoingRequest() = default;
- THttpOutgoingRequest(TStringBuf method, TStringBuf url, TStringBuf protocol, TStringBuf version);
- THttpOutgoingRequest(TStringBuf method, TStringBuf scheme, TStringBuf host, TStringBuf uri, TStringBuf protocol, TStringBuf version);
- static THttpOutgoingRequestPtr CreateRequestString(TStringBuf data);
- static THttpOutgoingRequestPtr CreateRequestString(const TString& data);
- static THttpOutgoingRequestPtr CreateRequestGet(TStringBuf url);
- static THttpOutgoingRequestPtr CreateRequestGet(TStringBuf host, TStringBuf uri); // http only
- static THttpOutgoingRequestPtr CreateRequestPost(TStringBuf url, TStringBuf contentType = {}, TStringBuf body = {});
- static THttpOutgoingRequestPtr CreateRequestPost(TStringBuf host, TStringBuf uri, TStringBuf contentType, TStringBuf body); // http only
- static THttpOutgoingRequestPtr CreateRequest(TStringBuf method, TStringBuf url, TStringBuf contentType = TStringBuf(), TStringBuf body = TStringBuf());
- static THttpOutgoingRequestPtr CreateHttpRequest(TStringBuf method, TStringBuf host, TStringBuf uri, TStringBuf contentType = TStringBuf(), TStringBuf body = TStringBuf());
- THttpOutgoingRequestPtr Duplicate();
-};
-
-class THttpOutgoingResponse :
- public THttpRenderer<THttpResponse, TSocketBuffer>,
- public TRefCounted<THttpOutgoingResponse, TAtomicCounter> {
-public:
- THttpOutgoingResponse(THttpIncomingRequestPtr request);
- THttpOutgoingResponse(THttpIncomingRequestPtr request, TStringBuf protocol, TStringBuf version, TStringBuf status, TStringBuf message);
-
- bool IsConnectionClose() const {
- if (!Connection.empty()) {
- return Connection == "close";
- } else {
- return Request->IsConnectionClose();
- }
- }
-
- bool IsNeedBody() const {
- return Status != "204";
- }
-
- THttpIncomingRequestPtr GetRequest() const {
- return Request;
- }
-
- THttpOutgoingResponsePtr Duplicate(THttpIncomingRequestPtr request);
-
-// it's temporary accessible for cleanup
-//protected:
- THttpIncomingRequestPtr Request;
-};
-
-}
+
+ THttpOutgoingRequest() = default;
+ THttpOutgoingRequest(TStringBuf method, TStringBuf url, TStringBuf protocol, TStringBuf version);
+ THttpOutgoingRequest(TStringBuf method, TStringBuf scheme, TStringBuf host, TStringBuf uri, TStringBuf protocol, TStringBuf version);
+ static THttpOutgoingRequestPtr CreateRequestString(TStringBuf data);
+ static THttpOutgoingRequestPtr CreateRequestString(const TString& data);
+ static THttpOutgoingRequestPtr CreateRequestGet(TStringBuf url);
+ static THttpOutgoingRequestPtr CreateRequestGet(TStringBuf host, TStringBuf uri); // http only
+ static THttpOutgoingRequestPtr CreateRequestPost(TStringBuf url, TStringBuf contentType = {}, TStringBuf body = {});
+ static THttpOutgoingRequestPtr CreateRequestPost(TStringBuf host, TStringBuf uri, TStringBuf contentType, TStringBuf body); // http only
+ static THttpOutgoingRequestPtr CreateRequest(TStringBuf method, TStringBuf url, TStringBuf contentType = TStringBuf(), TStringBuf body = TStringBuf());
+ static THttpOutgoingRequestPtr CreateHttpRequest(TStringBuf method, TStringBuf host, TStringBuf uri, TStringBuf contentType = TStringBuf(), TStringBuf body = TStringBuf());
+ THttpOutgoingRequestPtr Duplicate();
+};
+
+class THttpOutgoingResponse :
+ public THttpRenderer<THttpResponse, TSocketBuffer>,
+ public TRefCounted<THttpOutgoingResponse, TAtomicCounter> {
+public:
+ THttpOutgoingResponse(THttpIncomingRequestPtr request);
+ THttpOutgoingResponse(THttpIncomingRequestPtr request, TStringBuf protocol, TStringBuf version, TStringBuf status, TStringBuf message);
+
+ bool IsConnectionClose() const {
+ if (!Connection.empty()) {
+ return Connection == "close";
+ } else {
+ return Request->IsConnectionClose();
+ }
+ }
+
+ bool IsNeedBody() const {
+ return Status != "204";
+ }
+
+ THttpIncomingRequestPtr GetRequest() const {
+ return Request;
+ }
+
+ THttpOutgoingResponsePtr Duplicate(THttpIncomingRequestPtr request);
+
+// it's temporary accessible for cleanup
+//protected:
+ THttpIncomingRequestPtr Request;
+};
+
+}
diff --git a/library/cpp/actors/http/http_cache.cpp b/library/cpp/actors/http/http_cache.cpp
index 8fe67832602..27c4eeb6f32 100644
--- a/library/cpp/actors/http/http_cache.cpp
+++ b/library/cpp/actors/http/http_cache.cpp
@@ -1,4 +1,4 @@
-#include "http.h"
+#include "http.h"
#include "http_proxy.h"
#include "http_cache.h"
#include <library/cpp/actors/core/actor_bootstrapped.h>
@@ -6,594 +6,594 @@
#include <library/cpp/actors/core/log.h>
#include <library/cpp/actors/core/scheduler_basic.h>
#include <library/cpp/actors/http/http.h>
-#include <library/cpp/digest/md5/md5.h>
-#include <util/digest/multi.h>
-#include <util/generic/queue.h>
+#include <library/cpp/digest/md5/md5.h>
+#include <util/digest/multi.h>
+#include <util/generic/queue.h>
#include <util/string/cast.h>
-
-namespace NHttp {
-
-class THttpOutgoingCacheActor : public NActors::TActorBootstrapped<THttpOutgoingCacheActor>, THttpConfig {
-public:
- using TBase = NActors::TActorBootstrapped<THttpOutgoingCacheActor>;
+
+namespace NHttp {
+
+class THttpOutgoingCacheActor : public NActors::TActorBootstrapped<THttpOutgoingCacheActor>, THttpConfig {
+public:
+ using TBase = NActors::TActorBootstrapped<THttpOutgoingCacheActor>;
NActors::TActorId HttpProxyId;
- TGetCachePolicy GetCachePolicy;
- static constexpr TDuration RefreshTimeout = TDuration::Seconds(1);
-
- struct TCacheKey {
- TString Host;
- TString URL;
- TString Headers;
-
- operator size_t() const {
- return MultiHash(Host, URL, Headers);
- }
-
- TString GetId() const {
- return MD5::Calc(Host + ':' + URL + ':' + Headers);
- }
- };
-
- struct TCacheRecord {
- TInstant RefreshTime;
- TInstant DeathTime;
- TCachePolicy CachePolicy;
- NHttp::THttpOutgoingRequestPtr Request;
- NHttp::THttpOutgoingRequestPtr OutgoingRequest;
- TDuration Timeout;
- NHttp::THttpIncomingResponsePtr Response;
- TString Error;
- TVector<NHttp::TEvHttpProxy::TEvHttpOutgoingRequest::TPtr> Waiters;
-
- TCacheRecord(const TCachePolicy cachePolicy)
- : CachePolicy(cachePolicy)
- {}
-
- bool IsValid() const {
- return Response != nullptr || !Error.empty();
- }
-
- void UpdateResponse(NHttp::THttpIncomingResponsePtr response, const TString& error, TInstant now) {
- if (error.empty() || Response == nullptr || !CachePolicy.KeepOnError) {
- Response = response;
- Error = error;
- }
- RefreshTime = now + CachePolicy.TimeToRefresh;
- if (CachePolicy.PaceToRefresh) {
- RefreshTime += TDuration::MilliSeconds(RandomNumber<ui64>() % CachePolicy.PaceToRefresh.MilliSeconds());
- }
- }
-
- TString GetName() const {
- return TStringBuilder() << (Request->Secure ? "https://" : "http://") << Request->Host << Request->URL;
- }
- };
-
- struct TRefreshRecord {
- TCacheKey Key;
- TInstant RefreshTime;
-
- bool operator <(const TRefreshRecord& b) const {
- return RefreshTime > b.RefreshTime;
- }
- };
-
- THashMap<TCacheKey, TCacheRecord> Cache;
- TPriorityQueue<TRefreshRecord> RefreshQueue;
- THashMap<THttpOutgoingRequest*, TCacheKey> OutgoingRequests;
-
- THttpOutgoingCacheActor(const NActors::TActorId& httpProxyId, TGetCachePolicy getCachePolicy)
- : HttpProxyId(httpProxyId)
- , GetCachePolicy(std::move(getCachePolicy))
- {}
-
- void Bootstrap(const NActors::TActorContext&) {
- //
- Become(&THttpOutgoingCacheActor::StateWork, RefreshTimeout, new NActors::TEvents::TEvWakeup());
- }
-
- static TString GetCacheHeadersKey(const NHttp::THttpOutgoingRequest* request, const TCachePolicy& policy) {
- TStringBuilder key;
- if (!policy.HeadersToCacheKey.empty()) {
- NHttp::THeaders headers(request->Headers);
- for (const TString& header : policy.HeadersToCacheKey) {
- key << headers[header];
- }
- }
- return key;
- }
-
- static TCacheKey GetCacheKey(const NHttp::THttpOutgoingRequest* request, const TCachePolicy& policy) {
- return { ToString(request->Host), ToString(request->URL), GetCacheHeadersKey(request, policy) };
- }
-
- void Handle(NHttp::TEvHttpProxy::TEvHttpOutgoingResponse::TPtr event, const NActors::TActorContext& ctx) {
- ctx.Send(event->Forward(HttpProxyId));
- }
-
- void Handle(NHttp::TEvHttpProxy::TEvHttpIncomingRequest::TPtr event, const NActors::TActorContext& ctx) {
- ctx.Send(event->Forward(HttpProxyId));
- }
-
- void Handle(NHttp::TEvHttpProxy::TEvAddListeningPort::TPtr event, const NActors::TActorContext& ctx) {
- ctx.Send(event->Forward(HttpProxyId));
- }
-
- void Handle(NHttp::TEvHttpProxy::TEvRegisterHandler::TPtr event, const NActors::TActorContext& ctx) {
- ctx.Send(event->Forward(HttpProxyId));
- }
-
- void Handle(NHttp::TEvHttpProxy::TEvHttpIncomingResponse::TPtr event, const NActors::TActorContext& ctx) {
- NHttp::THttpOutgoingRequestPtr request(event->Get()->Request);
- NHttp::THttpIncomingResponsePtr response(event->Get()->Response);
- auto itRequests = OutgoingRequests.find(request.Get());
- if (itRequests == OutgoingRequests.end()) {
- LOG_ERROR_S(ctx, HttpLog, "Cache received response to unknown request " << request->Host << request->URL);
- return;
- }
- auto key = itRequests->second;
- OutgoingRequests.erase(itRequests);
- auto it = Cache.find(key);
- if (it == Cache.end()) {
- LOG_ERROR_S(ctx, HttpLog, "Cache received response to unknown cache key " << request->Host << request->URL);
- return;
- }
- TCacheRecord& cacheRecord = it->second;
- cacheRecord.OutgoingRequest.Reset();
- for (auto& waiter : cacheRecord.Waiters) {
- NHttp::THttpIncomingResponsePtr response2;
- TString error2;
- if (response != nullptr) {
- response2 = response->Duplicate(waiter->Get()->Request);
- }
- if (!event->Get()->Error.empty()) {
- error2 = event->Get()->Error;
- }
- ctx.Send(waiter->Sender, new NHttp::TEvHttpProxy::TEvHttpIncomingResponse(waiter->Get()->Request, response2, error2));
- }
- cacheRecord.Waiters.clear();
- TString error;
- if (event->Get()->Error.empty()) {
- if (event->Get()->Response != nullptr && event->Get()->Response->Status != "200") {
- error = event->Get()->Response->Message;
- }
- } else {
- error = event->Get()->Error;
- }
- if (!error.empty()) {
- LOG_WARN_S(ctx, HttpLog, "Error from " << cacheRecord.GetName() << ": " << error);
- }
- LOG_DEBUG_S(ctx, HttpLog, "OutgoingUpdate " << cacheRecord.GetName());
- cacheRecord.UpdateResponse(response, event->Get()->Error, ctx.Now());
- RefreshQueue.push({it->first, it->second.RefreshTime});
- LOG_DEBUG_S(ctx, HttpLog, "OutgoingSchedule " << cacheRecord.GetName() << " at " << cacheRecord.RefreshTime << " until " << cacheRecord.DeathTime);
- }
-
- void Handle(NHttp::TEvHttpProxy::TEvHttpOutgoingRequest::TPtr event, const NActors::TActorContext& ctx) {
- const NHttp::THttpOutgoingRequest* request = event->Get()->Request.Get();
- auto policy = GetCachePolicy(request);
- if (policy.TimeToExpire == TDuration()) {
- ctx.Send(event->Forward(HttpProxyId));
- return;
- }
- auto key = GetCacheKey(request, policy);
- auto it = Cache.find(key);
- if (it != Cache.end()) {
- if (it->second.IsValid()) {
- LOG_DEBUG_S(ctx, HttpLog, "OutgoingRespond "
- << it->second.GetName()
- << " ("
- << ((it->second.Response != nullptr) ? ToString(it->second.Response->Size()) : TString("error"))
- << ")");
- NHttp::THttpIncomingResponsePtr response = it->second.Response;
- if (response != nullptr) {
- response = response->Duplicate(event->Get()->Request);
- }
- ctx.Send(event->Sender,
- new NHttp::TEvHttpProxy::TEvHttpIncomingResponse(event->Get()->Request,
- response,
- it->second.Error));
- it->second.DeathTime = ctx.Now() + it->second.CachePolicy.TimeToExpire; // prolong active cache items
- return;
- }
- } else {
- it = Cache.emplace(key, policy).first;
- it->second.Request = event->Get()->Request;
- it->second.Timeout = event->Get()->Timeout;
- it->second.OutgoingRequest = it->second.Request->Duplicate();
- OutgoingRequests[it->second.OutgoingRequest.Get()] = key;
- LOG_DEBUG_S(ctx, HttpLog, "OutgoingInitiate " << it->second.GetName());
- ctx.Send(HttpProxyId, new NHttp::TEvHttpProxy::TEvHttpOutgoingRequest(it->second.OutgoingRequest, it->second.Timeout));
- }
- it->second.DeathTime = ctx.Now() + it->second.CachePolicy.TimeToExpire;
- it->second.Waiters.emplace_back(std::move(event));
- }
-
- void HandleRefresh(const NActors::TActorContext& ctx) {
- while (!RefreshQueue.empty() && RefreshQueue.top().RefreshTime <= ctx.Now()) {
- TRefreshRecord rrec = RefreshQueue.top();
- RefreshQueue.pop();
- auto it = Cache.find(rrec.Key);
- if (it != Cache.end()) {
- if (it->second.DeathTime > ctx.Now()) {
- LOG_DEBUG_S(ctx, HttpLog, "OutgoingRefresh " << it->second.GetName());
- it->second.OutgoingRequest = it->second.Request->Duplicate();
- OutgoingRequests[it->second.OutgoingRequest.Get()] = it->first;
- ctx.Send(HttpProxyId, new NHttp::TEvHttpProxy::TEvHttpOutgoingRequest(it->second.OutgoingRequest, it->second.Timeout));
- } else {
- LOG_DEBUG_S(ctx, HttpLog, "OutgoingForget " << it->second.GetName());
- if (it->second.OutgoingRequest) {
- OutgoingRequests.erase(it->second.OutgoingRequest.Get());
- }
- Cache.erase(it);
- }
- }
- }
- ctx.Schedule(RefreshTimeout, new NActors::TEvents::TEvWakeup());
- }
-
- STFUNC(StateWork) {
- switch (ev->GetTypeRewrite()) {
- HFunc(NHttp::TEvHttpProxy::TEvHttpIncomingResponse, Handle);
- HFunc(NHttp::TEvHttpProxy::TEvHttpOutgoingRequest, Handle);
- HFunc(NHttp::TEvHttpProxy::TEvAddListeningPort, Handle);
- HFunc(NHttp::TEvHttpProxy::TEvRegisterHandler, Handle);
- HFunc(NHttp::TEvHttpProxy::TEvHttpIncomingRequest, Handle);
- HFunc(NHttp::TEvHttpProxy::TEvHttpOutgoingResponse, Handle);
- CFunc(NActors::TEvents::TSystem::Wakeup, HandleRefresh);
- }
- }
-};
-
-const TDuration THttpOutgoingCacheActor::RefreshTimeout;
-
-class THttpIncomingCacheActor : public NActors::TActorBootstrapped<THttpIncomingCacheActor>, THttpConfig {
-public:
- using TBase = NActors::TActorBootstrapped<THttpIncomingCacheActor>;
- NActors::TActorId HttpProxyId;
- TGetCachePolicy GetCachePolicy;
- static constexpr TDuration RefreshTimeout = TDuration::Seconds(1);
- THashMap<TString, TActorId> Handlers;
-
- struct TCacheKey {
- TString Host;
- TString URL;
- TString Headers;
-
- operator size_t() const {
- return MultiHash(Host, URL, Headers);
- }
-
- TString GetId() const {
- return MD5::Calc(Host + ':' + URL + ':' + Headers);
- }
- };
-
- struct TCacheRecord {
- TInstant RefreshTime;
- TInstant DeathTime;
- TCachePolicy CachePolicy;
- TString CacheId;
- NHttp::THttpIncomingRequestPtr Request;
- TDuration Timeout;
- NHttp::THttpOutgoingResponsePtr Response;
- TVector<NHttp::TEvHttpProxy::TEvHttpIncomingRequest::TPtr> Waiters;
- ui32 Retries = 0;
- bool Enqueued = false;
-
- TCacheRecord(const TCachePolicy cachePolicy)
- : CachePolicy(cachePolicy)
- {}
-
- bool IsValid() const {
- return Response != nullptr;
- }
-
- void InitRequest(NHttp::THttpIncomingRequestPtr request) {
- Request = request;
- if (CachePolicy.TimeToExpire) {
- DeathTime = NActors::TlsActivationContext->Now() + CachePolicy.TimeToExpire;
- }
- }
-
- void UpdateResponse(NHttp::THttpOutgoingResponsePtr response, const TString& error, TInstant now) {
- if (error.empty() || !CachePolicy.KeepOnError) {
- Response = response;
- }
- Retries = 0;
- if (CachePolicy.TimeToRefresh) {
- RefreshTime = now + CachePolicy.TimeToRefresh;
- if (CachePolicy.PaceToRefresh) {
- RefreshTime += TDuration::MilliSeconds(RandomNumber<ui64>() % CachePolicy.PaceToRefresh.MilliSeconds());
- }
- }
- }
-
- void UpdateExpireTime() {
- if (CachePolicy.TimeToExpire) {
- DeathTime = NActors::TlsActivationContext->Now() + CachePolicy.TimeToExpire;
- }
- }
-
- TString GetName() const {
- return TStringBuilder() << (Request->Secure ? "https://" : "http://") << Request->Host << Request->URL
- << " (" << CacheId << ")";
- }
- };
-
- struct TRefreshRecord {
- TCacheKey Key;
- TInstant RefreshTime;
-
- bool operator <(const TRefreshRecord& b) const {
- return RefreshTime > b.RefreshTime;
- }
- };
-
- THashMap<TCacheKey, TCacheRecord> Cache;
- TPriorityQueue<TRefreshRecord> RefreshQueue;
- THashMap<THttpIncomingRequest*, TCacheKey> IncomingRequests;
-
- THttpIncomingCacheActor(const NActors::TActorId& httpProxyId, TGetCachePolicy getCachePolicy)
- : HttpProxyId(httpProxyId)
- , GetCachePolicy(std::move(getCachePolicy))
- {}
-
- void Bootstrap(const NActors::TActorContext&) {
- //
- Become(&THttpIncomingCacheActor::StateWork, RefreshTimeout, new NActors::TEvents::TEvWakeup());
- }
-
- static TString GetCacheHeadersKey(const NHttp::THttpIncomingRequest* request, const TCachePolicy& policy) {
- TStringBuilder key;
- if (!policy.HeadersToCacheKey.empty()) {
- NHttp::THeaders headers(request->Headers);
- for (const TString& header : policy.HeadersToCacheKey) {
- key << headers[header];
- }
- }
- return key;
- }
-
- static TCacheKey GetCacheKey(const NHttp::THttpIncomingRequest* request, const TCachePolicy& policy) {
- return { ToString(request->Host), ToString(request->URL), GetCacheHeadersKey(request, policy) };
- }
-
- TActorId GetRequestHandler(NHttp::THttpIncomingRequestPtr request) {
- TStringBuf url = request->URL.Before('?');
- THashMap<TString, TActorId>::iterator it;
- while (!url.empty()) {
- it = Handlers.find(url);
- if (it != Handlers.end()) {
- return it->second;
- } else {
- if (url.EndsWith('/')) {
- url.Trunc(url.size() - 1);
- }
- size_t pos = url.rfind('/');
- if (pos == TStringBuf::npos) {
- break;
- } else {
- url = url.substr(0, pos + 1);
- }
- }
- }
- return {};
- }
-
- void SendCacheRequest(const TCacheKey& cacheKey, TCacheRecord& cacheRecord, const NActors::TActorContext& ctx) {
- cacheRecord.Request = cacheRecord.Request->Duplicate();
- IncomingRequests[cacheRecord.Request.Get()] = cacheKey;
- TActorId handler = GetRequestHandler(cacheRecord.Request);
- if (handler) {
- Send(handler, new NHttp::TEvHttpProxy::TEvHttpIncomingRequest(cacheRecord.Request));
- } else {
- LOG_ERROR_S(ctx, HttpLog, "Can't find cache handler for " << cacheRecord.GetName());
- }
- }
-
- void DropCacheRecord(THashMap<TCacheKey, TCacheRecord>::iterator it) {
- if (it->second.Request) {
- IncomingRequests.erase(it->second.Request.Get());
- }
- for (auto& waiter : it->second.Waiters) {
- NHttp::THttpOutgoingResponsePtr response;
- response = waiter->Get()->Request->CreateResponseGatewayTimeout("Timeout", "text/plain");
- Send(waiter->Sender, new NHttp::TEvHttpProxy::TEvHttpOutgoingResponse(response));
- }
- Cache.erase(it);
- }
-
- void Handle(NHttp::TEvHttpProxy::TEvHttpIncomingResponse::TPtr event, const NActors::TActorContext& ctx) {
- ctx.Send(event->Forward(HttpProxyId));
- }
-
- void Handle(NHttp::TEvHttpProxy::TEvHttpOutgoingRequest::TPtr event, const NActors::TActorContext& ctx) {
- ctx.Send(event->Forward(HttpProxyId));
- }
-
- void Handle(NHttp::TEvHttpProxy::TEvAddListeningPort::TPtr event, const NActors::TActorContext& ctx) {
- ctx.Send(event->Forward(HttpProxyId));
- }
-
- void Handle(NHttp::TEvHttpProxy::TEvRegisterHandler::TPtr event, const NActors::TActorContext& ctx) {
- Handlers[event->Get()->Path] = event->Get()->Handler;
- ctx.Send(HttpProxyId, new NHttp::TEvHttpProxy::TEvRegisterHandler(event->Get()->Path, ctx.SelfID));
- }
-
- void Handle(NHttp::TEvHttpProxy::TEvHttpOutgoingResponse::TPtr event, const NActors::TActorContext& ctx) {
- NHttp::THttpIncomingRequestPtr request(event->Get()->Response->GetRequest());
- NHttp::THttpOutgoingResponsePtr response(event->Get()->Response);
- auto itRequests = IncomingRequests.find(request.Get());
- if (itRequests == IncomingRequests.end()) {
- LOG_ERROR_S(ctx, HttpLog, "Cache received response to unknown request " << request->Host << request->URL);
- return;
- }
-
- TCacheKey key = itRequests->second;
- auto it = Cache.find(key);
- if (it == Cache.end()) {
- LOG_ERROR_S(ctx, HttpLog, "Cache received response to unknown cache key " << request->Host << request->URL);
- return;
- }
-
- IncomingRequests.erase(itRequests);
- TCacheRecord& cacheRecord = it->second;
- TStringBuf status;
- TString error;
-
- if (event->Get()->Response != nullptr) {
- status = event->Get()->Response->Status;
- if (!status.StartsWith("2")) {
- error = event->Get()->Response->Message;
- }
- }
- if (cacheRecord.CachePolicy.RetriesCount > 0) {
- auto itStatusToRetry = std::find(cacheRecord.CachePolicy.StatusesToRetry.begin(), cacheRecord.CachePolicy.StatusesToRetry.end(), status);
- if (itStatusToRetry != cacheRecord.CachePolicy.StatusesToRetry.end()) {
- if (cacheRecord.Retries < cacheRecord.CachePolicy.RetriesCount) {
- ++cacheRecord.Retries;
- LOG_WARN_S(ctx, HttpLog, "IncomingRetry " << cacheRecord.GetName() << ": " << status << " " << error);
- SendCacheRequest(key, cacheRecord, ctx);
- return;
- }
- }
- }
- for (auto& waiter : cacheRecord.Waiters) {
- NHttp::THttpOutgoingResponsePtr response2;
- response2 = response->Duplicate(waiter->Get()->Request);
- ctx.Send(waiter->Sender, new NHttp::TEvHttpProxy::TEvHttpOutgoingResponse(response2));
- }
- cacheRecord.Waiters.clear();
- if (!error.empty()) {
- LOG_WARN_S(ctx, HttpLog, "Error from " << cacheRecord.GetName() << ": " << error);
- if (!cacheRecord.Response) {
- LOG_DEBUG_S(ctx, HttpLog, "IncomingDiscard " << cacheRecord.GetName());
- DropCacheRecord(it);
- return;
- }
- }
- if (cacheRecord.CachePolicy.TimeToRefresh) {
- LOG_DEBUG_S(ctx, HttpLog, "IncomingUpdate " << cacheRecord.GetName());
- cacheRecord.UpdateResponse(response, error, ctx.Now());
- if (!cacheRecord.Enqueued) {
- RefreshQueue.push({it->first, it->second.RefreshTime});
- cacheRecord.Enqueued = true;
- }
- LOG_DEBUG_S(ctx, HttpLog, "IncomingSchedule " << cacheRecord.GetName() << " at " << cacheRecord.RefreshTime << " until " << cacheRecord.DeathTime);
- } else {
- LOG_DEBUG_S(ctx, HttpLog, "IncomingDrop " << cacheRecord.GetName());
- DropCacheRecord(it);
- }
- }
-
- void Handle(NHttp::TEvHttpProxy::TEvHttpIncomingRequest::TPtr event, const NActors::TActorContext& ctx) {
- const NHttp::THttpIncomingRequest* request = event->Get()->Request.Get();
- TCachePolicy policy = GetCachePolicy(request);
- if (policy.TimeToExpire == TDuration() && policy.RetriesCount == 0) {
- TActorId handler = GetRequestHandler(event->Get()->Request);
- if (handler) {
- ctx.Send(event->Forward(handler));
- }
- return;
- }
- auto key = GetCacheKey(request, policy);
- auto it = Cache.find(key);
- if (it != Cache.end() && !policy.DiscardCache) {
- it->second.UpdateExpireTime();
- if (it->second.IsValid()) {
- LOG_DEBUG_S(ctx, HttpLog, "IncomingRespond "
- << it->second.GetName()
- << " ("
- << ((it->second.Response != nullptr) ? ToString(it->second.Response->Size()) : TString("error"))
- << ")");
- NHttp::THttpOutgoingResponsePtr response = it->second.Response;
- if (response != nullptr) {
- response = response->Duplicate(event->Get()->Request);
- }
- ctx.Send(event->Sender, new NHttp::TEvHttpProxy::TEvHttpOutgoingResponse(response));
- return;
- }
- } else {
- it = Cache.emplace(key, policy).first;
- it->second.CacheId = key.GetId(); // for debugging
- it->second.InitRequest(event->Get()->Request);
- if (policy.DiscardCache) {
- LOG_DEBUG_S(ctx, HttpLog, "IncomingDiscardCache " << it->second.GetName());
- }
- LOG_DEBUG_S(ctx, HttpLog, "IncomingInitiate " << it->second.GetName());
- SendCacheRequest(key, it->second, ctx);
- }
- it->second.Waiters.emplace_back(std::move(event));
- }
-
- void HandleRefresh(const NActors::TActorContext& ctx) {
- while (!RefreshQueue.empty() && RefreshQueue.top().RefreshTime <= ctx.Now()) {
- TRefreshRecord rrec = RefreshQueue.top();
- RefreshQueue.pop();
- auto it = Cache.find(rrec.Key);
- if (it != Cache.end()) {
- it->second.Enqueued = false;
- if (it->second.DeathTime > ctx.Now()) {
- LOG_DEBUG_S(ctx, HttpLog, "IncomingRefresh " << it->second.GetName());
- SendCacheRequest(it->first, it->second, ctx);
- } else {
- LOG_DEBUG_S(ctx, HttpLog, "IncomingForget " << it->second.GetName());
- DropCacheRecord(it);
- }
- }
- }
- ctx.Schedule(RefreshTimeout, new NActors::TEvents::TEvWakeup());
- }
-
- STFUNC(StateWork) {
- switch (ev->GetTypeRewrite()) {
- HFunc(NHttp::TEvHttpProxy::TEvHttpIncomingResponse, Handle);
- HFunc(NHttp::TEvHttpProxy::TEvHttpOutgoingRequest, Handle);
- HFunc(NHttp::TEvHttpProxy::TEvAddListeningPort, Handle);
- HFunc(NHttp::TEvHttpProxy::TEvRegisterHandler, Handle);
- HFunc(NHttp::TEvHttpProxy::TEvHttpIncomingRequest, Handle);
- HFunc(NHttp::TEvHttpProxy::TEvHttpOutgoingResponse, Handle);
- CFunc(NActors::TEvents::TSystem::Wakeup, HandleRefresh);
- }
- }
-};
-
-TCachePolicy GetDefaultCachePolicy(const THttpRequest* request, const TCachePolicy& defaultPolicy) {
- TCachePolicy policy = defaultPolicy;
- THeaders headers(request->Headers);
- TStringBuf cacheControl(headers["Cache-Control"]);
- while (TStringBuf cacheItem = cacheControl.NextTok(',')) {
- Trim(cacheItem, ' ');
- if (cacheItem == "no-store" || cacheItem == "no-cache") {
- policy.DiscardCache = true;
- }
- TStringBuf itemName = cacheItem.NextTok('=');
- TrimEnd(itemName, ' ');
- TrimBegin(cacheItem, ' ');
- if (itemName == "max-age") {
- policy.TimeToRefresh = policy.TimeToExpire = TDuration::Seconds(FromString(cacheItem));
- }
- if (itemName == "min-fresh") {
- policy.TimeToRefresh = policy.TimeToExpire = TDuration::Seconds(FromString(cacheItem));
- }
- if (itemName == "stale-if-error") {
- policy.KeepOnError = true;
- }
- }
- return policy;
-}
-
+ TGetCachePolicy GetCachePolicy;
+ static constexpr TDuration RefreshTimeout = TDuration::Seconds(1);
+
+ struct TCacheKey {
+ TString Host;
+ TString URL;
+ TString Headers;
+
+ operator size_t() const {
+ return MultiHash(Host, URL, Headers);
+ }
+
+ TString GetId() const {
+ return MD5::Calc(Host + ':' + URL + ':' + Headers);
+ }
+ };
+
+ struct TCacheRecord {
+ TInstant RefreshTime;
+ TInstant DeathTime;
+ TCachePolicy CachePolicy;
+ NHttp::THttpOutgoingRequestPtr Request;
+ NHttp::THttpOutgoingRequestPtr OutgoingRequest;
+ TDuration Timeout;
+ NHttp::THttpIncomingResponsePtr Response;
+ TString Error;
+ TVector<NHttp::TEvHttpProxy::TEvHttpOutgoingRequest::TPtr> Waiters;
+
+ TCacheRecord(const TCachePolicy cachePolicy)
+ : CachePolicy(cachePolicy)
+ {}
+
+ bool IsValid() const {
+ return Response != nullptr || !Error.empty();
+ }
+
+ void UpdateResponse(NHttp::THttpIncomingResponsePtr response, const TString& error, TInstant now) {
+ if (error.empty() || Response == nullptr || !CachePolicy.KeepOnError) {
+ Response = response;
+ Error = error;
+ }
+ RefreshTime = now + CachePolicy.TimeToRefresh;
+ if (CachePolicy.PaceToRefresh) {
+ RefreshTime += TDuration::MilliSeconds(RandomNumber<ui64>() % CachePolicy.PaceToRefresh.MilliSeconds());
+ }
+ }
+
+ TString GetName() const {
+ return TStringBuilder() << (Request->Secure ? "https://" : "http://") << Request->Host << Request->URL;
+ }
+ };
+
+ struct TRefreshRecord {
+ TCacheKey Key;
+ TInstant RefreshTime;
+
+ bool operator <(const TRefreshRecord& b) const {
+ return RefreshTime > b.RefreshTime;
+ }
+ };
+
+ THashMap<TCacheKey, TCacheRecord> Cache;
+ TPriorityQueue<TRefreshRecord> RefreshQueue;
+ THashMap<THttpOutgoingRequest*, TCacheKey> OutgoingRequests;
+
+ THttpOutgoingCacheActor(const NActors::TActorId& httpProxyId, TGetCachePolicy getCachePolicy)
+ : HttpProxyId(httpProxyId)
+ , GetCachePolicy(std::move(getCachePolicy))
+ {}
+
+ void Bootstrap(const NActors::TActorContext&) {
+ //
+ Become(&THttpOutgoingCacheActor::StateWork, RefreshTimeout, new NActors::TEvents::TEvWakeup());
+ }
+
+ static TString GetCacheHeadersKey(const NHttp::THttpOutgoingRequest* request, const TCachePolicy& policy) {
+ TStringBuilder key;
+ if (!policy.HeadersToCacheKey.empty()) {
+ NHttp::THeaders headers(request->Headers);
+ for (const TString& header : policy.HeadersToCacheKey) {
+ key << headers[header];
+ }
+ }
+ return key;
+ }
+
+ static TCacheKey GetCacheKey(const NHttp::THttpOutgoingRequest* request, const TCachePolicy& policy) {
+ return { ToString(request->Host), ToString(request->URL), GetCacheHeadersKey(request, policy) };
+ }
+
+ void Handle(NHttp::TEvHttpProxy::TEvHttpOutgoingResponse::TPtr event, const NActors::TActorContext& ctx) {
+ ctx.Send(event->Forward(HttpProxyId));
+ }
+
+ void Handle(NHttp::TEvHttpProxy::TEvHttpIncomingRequest::TPtr event, const NActors::TActorContext& ctx) {
+ ctx.Send(event->Forward(HttpProxyId));
+ }
+
+ void Handle(NHttp::TEvHttpProxy::TEvAddListeningPort::TPtr event, const NActors::TActorContext& ctx) {
+ ctx.Send(event->Forward(HttpProxyId));
+ }
+
+ void Handle(NHttp::TEvHttpProxy::TEvRegisterHandler::TPtr event, const NActors::TActorContext& ctx) {
+ ctx.Send(event->Forward(HttpProxyId));
+ }
+
+ void Handle(NHttp::TEvHttpProxy::TEvHttpIncomingResponse::TPtr event, const NActors::TActorContext& ctx) {
+ NHttp::THttpOutgoingRequestPtr request(event->Get()->Request);
+ NHttp::THttpIncomingResponsePtr response(event->Get()->Response);
+ auto itRequests = OutgoingRequests.find(request.Get());
+ if (itRequests == OutgoingRequests.end()) {
+ LOG_ERROR_S(ctx, HttpLog, "Cache received response to unknown request " << request->Host << request->URL);
+ return;
+ }
+ auto key = itRequests->second;
+ OutgoingRequests.erase(itRequests);
+ auto it = Cache.find(key);
+ if (it == Cache.end()) {
+ LOG_ERROR_S(ctx, HttpLog, "Cache received response to unknown cache key " << request->Host << request->URL);
+ return;
+ }
+ TCacheRecord& cacheRecord = it->second;
+ cacheRecord.OutgoingRequest.Reset();
+ for (auto& waiter : cacheRecord.Waiters) {
+ NHttp::THttpIncomingResponsePtr response2;
+ TString error2;
+ if (response != nullptr) {
+ response2 = response->Duplicate(waiter->Get()->Request);
+ }
+ if (!event->Get()->Error.empty()) {
+ error2 = event->Get()->Error;
+ }
+ ctx.Send(waiter->Sender, new NHttp::TEvHttpProxy::TEvHttpIncomingResponse(waiter->Get()->Request, response2, error2));
+ }
+ cacheRecord.Waiters.clear();
+ TString error;
+ if (event->Get()->Error.empty()) {
+ if (event->Get()->Response != nullptr && event->Get()->Response->Status != "200") {
+ error = event->Get()->Response->Message;
+ }
+ } else {
+ error = event->Get()->Error;
+ }
+ if (!error.empty()) {
+ LOG_WARN_S(ctx, HttpLog, "Error from " << cacheRecord.GetName() << ": " << error);
+ }
+ LOG_DEBUG_S(ctx, HttpLog, "OutgoingUpdate " << cacheRecord.GetName());
+ cacheRecord.UpdateResponse(response, event->Get()->Error, ctx.Now());
+ RefreshQueue.push({it->first, it->second.RefreshTime});
+ LOG_DEBUG_S(ctx, HttpLog, "OutgoingSchedule " << cacheRecord.GetName() << " at " << cacheRecord.RefreshTime << " until " << cacheRecord.DeathTime);
+ }
+
+ void Handle(NHttp::TEvHttpProxy::TEvHttpOutgoingRequest::TPtr event, const NActors::TActorContext& ctx) {
+ const NHttp::THttpOutgoingRequest* request = event->Get()->Request.Get();
+ auto policy = GetCachePolicy(request);
+ if (policy.TimeToExpire == TDuration()) {
+ ctx.Send(event->Forward(HttpProxyId));
+ return;
+ }
+ auto key = GetCacheKey(request, policy);
+ auto it = Cache.find(key);
+ if (it != Cache.end()) {
+ if (it->second.IsValid()) {
+ LOG_DEBUG_S(ctx, HttpLog, "OutgoingRespond "
+ << it->second.GetName()
+ << " ("
+ << ((it->second.Response != nullptr) ? ToString(it->second.Response->Size()) : TString("error"))
+ << ")");
+ NHttp::THttpIncomingResponsePtr response = it->second.Response;
+ if (response != nullptr) {
+ response = response->Duplicate(event->Get()->Request);
+ }
+ ctx.Send(event->Sender,
+ new NHttp::TEvHttpProxy::TEvHttpIncomingResponse(event->Get()->Request,
+ response,
+ it->second.Error));
+ it->second.DeathTime = ctx.Now() + it->second.CachePolicy.TimeToExpire; // prolong active cache items
+ return;
+ }
+ } else {
+ it = Cache.emplace(key, policy).first;
+ it->second.Request = event->Get()->Request;
+ it->second.Timeout = event->Get()->Timeout;
+ it->second.OutgoingRequest = it->second.Request->Duplicate();
+ OutgoingRequests[it->second.OutgoingRequest.Get()] = key;
+ LOG_DEBUG_S(ctx, HttpLog, "OutgoingInitiate " << it->second.GetName());
+ ctx.Send(HttpProxyId, new NHttp::TEvHttpProxy::TEvHttpOutgoingRequest(it->second.OutgoingRequest, it->second.Timeout));
+ }
+ it->second.DeathTime = ctx.Now() + it->second.CachePolicy.TimeToExpire;
+ it->second.Waiters.emplace_back(std::move(event));
+ }
+
+ void HandleRefresh(const NActors::TActorContext& ctx) {
+ while (!RefreshQueue.empty() && RefreshQueue.top().RefreshTime <= ctx.Now()) {
+ TRefreshRecord rrec = RefreshQueue.top();
+ RefreshQueue.pop();
+ auto it = Cache.find(rrec.Key);
+ if (it != Cache.end()) {
+ if (it->second.DeathTime > ctx.Now()) {
+ LOG_DEBUG_S(ctx, HttpLog, "OutgoingRefresh " << it->second.GetName());
+ it->second.OutgoingRequest = it->second.Request->Duplicate();
+ OutgoingRequests[it->second.OutgoingRequest.Get()] = it->first;
+ ctx.Send(HttpProxyId, new NHttp::TEvHttpProxy::TEvHttpOutgoingRequest(it->second.OutgoingRequest, it->second.Timeout));
+ } else {
+ LOG_DEBUG_S(ctx, HttpLog, "OutgoingForget " << it->second.GetName());
+ if (it->second.OutgoingRequest) {
+ OutgoingRequests.erase(it->second.OutgoingRequest.Get());
+ }
+ Cache.erase(it);
+ }
+ }
+ }
+ ctx.Schedule(RefreshTimeout, new NActors::TEvents::TEvWakeup());
+ }
+
+ STFUNC(StateWork) {
+ switch (ev->GetTypeRewrite()) {
+ HFunc(NHttp::TEvHttpProxy::TEvHttpIncomingResponse, Handle);
+ HFunc(NHttp::TEvHttpProxy::TEvHttpOutgoingRequest, Handle);
+ HFunc(NHttp::TEvHttpProxy::TEvAddListeningPort, Handle);
+ HFunc(NHttp::TEvHttpProxy::TEvRegisterHandler, Handle);
+ HFunc(NHttp::TEvHttpProxy::TEvHttpIncomingRequest, Handle);
+ HFunc(NHttp::TEvHttpProxy::TEvHttpOutgoingResponse, Handle);
+ CFunc(NActors::TEvents::TSystem::Wakeup, HandleRefresh);
+ }
+ }
+};
+
+const TDuration THttpOutgoingCacheActor::RefreshTimeout;
+
+class THttpIncomingCacheActor : public NActors::TActorBootstrapped<THttpIncomingCacheActor>, THttpConfig {
+public:
+ using TBase = NActors::TActorBootstrapped<THttpIncomingCacheActor>;
+ NActors::TActorId HttpProxyId;
+ TGetCachePolicy GetCachePolicy;
+ static constexpr TDuration RefreshTimeout = TDuration::Seconds(1);
+ THashMap<TString, TActorId> Handlers;
+
+ struct TCacheKey {
+ TString Host;
+ TString URL;
+ TString Headers;
+
+ operator size_t() const {
+ return MultiHash(Host, URL, Headers);
+ }
+
+ TString GetId() const {
+ return MD5::Calc(Host + ':' + URL + ':' + Headers);
+ }
+ };
+
+ struct TCacheRecord {
+ TInstant RefreshTime;
+ TInstant DeathTime;
+ TCachePolicy CachePolicy;
+ TString CacheId;
+ NHttp::THttpIncomingRequestPtr Request;
+ TDuration Timeout;
+ NHttp::THttpOutgoingResponsePtr Response;
+ TVector<NHttp::TEvHttpProxy::TEvHttpIncomingRequest::TPtr> Waiters;
+ ui32 Retries = 0;
+ bool Enqueued = false;
+
+ TCacheRecord(const TCachePolicy cachePolicy)
+ : CachePolicy(cachePolicy)
+ {}
+
+ bool IsValid() const {
+ return Response != nullptr;
+ }
+
+ void InitRequest(NHttp::THttpIncomingRequestPtr request) {
+ Request = request;
+ if (CachePolicy.TimeToExpire) {
+ DeathTime = NActors::TlsActivationContext->Now() + CachePolicy.TimeToExpire;
+ }
+ }
+
+ void UpdateResponse(NHttp::THttpOutgoingResponsePtr response, const TString& error, TInstant now) {
+ if (error.empty() || !CachePolicy.KeepOnError) {
+ Response = response;
+ }
+ Retries = 0;
+ if (CachePolicy.TimeToRefresh) {
+ RefreshTime = now + CachePolicy.TimeToRefresh;
+ if (CachePolicy.PaceToRefresh) {
+ RefreshTime += TDuration::MilliSeconds(RandomNumber<ui64>() % CachePolicy.PaceToRefresh.MilliSeconds());
+ }
+ }
+ }
+
+ void UpdateExpireTime() {
+ if (CachePolicy.TimeToExpire) {
+ DeathTime = NActors::TlsActivationContext->Now() + CachePolicy.TimeToExpire;
+ }
+ }
+
+ TString GetName() const {
+ return TStringBuilder() << (Request->Secure ? "https://" : "http://") << Request->Host << Request->URL
+ << " (" << CacheId << ")";
+ }
+ };
+
+ struct TRefreshRecord {
+ TCacheKey Key;
+ TInstant RefreshTime;
+
+ bool operator <(const TRefreshRecord& b) const {
+ return RefreshTime > b.RefreshTime;
+ }
+ };
+
+ THashMap<TCacheKey, TCacheRecord> Cache;
+ TPriorityQueue<TRefreshRecord> RefreshQueue;
+ THashMap<THttpIncomingRequest*, TCacheKey> IncomingRequests;
+
+ THttpIncomingCacheActor(const NActors::TActorId& httpProxyId, TGetCachePolicy getCachePolicy)
+ : HttpProxyId(httpProxyId)
+ , GetCachePolicy(std::move(getCachePolicy))
+ {}
+
+ void Bootstrap(const NActors::TActorContext&) {
+ //
+ Become(&THttpIncomingCacheActor::StateWork, RefreshTimeout, new NActors::TEvents::TEvWakeup());
+ }
+
+ static TString GetCacheHeadersKey(const NHttp::THttpIncomingRequest* request, const TCachePolicy& policy) {
+ TStringBuilder key;
+ if (!policy.HeadersToCacheKey.empty()) {
+ NHttp::THeaders headers(request->Headers);
+ for (const TString& header : policy.HeadersToCacheKey) {
+ key << headers[header];
+ }
+ }
+ return key;
+ }
+
+ static TCacheKey GetCacheKey(const NHttp::THttpIncomingRequest* request, const TCachePolicy& policy) {
+ return { ToString(request->Host), ToString(request->URL), GetCacheHeadersKey(request, policy) };
+ }
+
+ TActorId GetRequestHandler(NHttp::THttpIncomingRequestPtr request) {
+ TStringBuf url = request->URL.Before('?');
+ THashMap<TString, TActorId>::iterator it;
+ while (!url.empty()) {
+ it = Handlers.find(url);
+ if (it != Handlers.end()) {
+ return it->second;
+ } else {
+ if (url.EndsWith('/')) {
+ url.Trunc(url.size() - 1);
+ }
+ size_t pos = url.rfind('/');
+ if (pos == TStringBuf::npos) {
+ break;
+ } else {
+ url = url.substr(0, pos + 1);
+ }
+ }
+ }
+ return {};
+ }
+
+ void SendCacheRequest(const TCacheKey& cacheKey, TCacheRecord& cacheRecord, const NActors::TActorContext& ctx) {
+ cacheRecord.Request = cacheRecord.Request->Duplicate();
+ IncomingRequests[cacheRecord.Request.Get()] = cacheKey;
+ TActorId handler = GetRequestHandler(cacheRecord.Request);
+ if (handler) {
+ Send(handler, new NHttp::TEvHttpProxy::TEvHttpIncomingRequest(cacheRecord.Request));
+ } else {
+ LOG_ERROR_S(ctx, HttpLog, "Can't find cache handler for " << cacheRecord.GetName());
+ }
+ }
+
+ void DropCacheRecord(THashMap<TCacheKey, TCacheRecord>::iterator it) {
+ if (it->second.Request) {
+ IncomingRequests.erase(it->second.Request.Get());
+ }
+ for (auto& waiter : it->second.Waiters) {
+ NHttp::THttpOutgoingResponsePtr response;
+ response = waiter->Get()->Request->CreateResponseGatewayTimeout("Timeout", "text/plain");
+ Send(waiter->Sender, new NHttp::TEvHttpProxy::TEvHttpOutgoingResponse(response));
+ }
+ Cache.erase(it);
+ }
+
+ void Handle(NHttp::TEvHttpProxy::TEvHttpIncomingResponse::TPtr event, const NActors::TActorContext& ctx) {
+ ctx.Send(event->Forward(HttpProxyId));
+ }
+
+ void Handle(NHttp::TEvHttpProxy::TEvHttpOutgoingRequest::TPtr event, const NActors::TActorContext& ctx) {
+ ctx.Send(event->Forward(HttpProxyId));
+ }
+
+ void Handle(NHttp::TEvHttpProxy::TEvAddListeningPort::TPtr event, const NActors::TActorContext& ctx) {
+ ctx.Send(event->Forward(HttpProxyId));
+ }
+
+ void Handle(NHttp::TEvHttpProxy::TEvRegisterHandler::TPtr event, const NActors::TActorContext& ctx) {
+ Handlers[event->Get()->Path] = event->Get()->Handler;
+ ctx.Send(HttpProxyId, new NHttp::TEvHttpProxy::TEvRegisterHandler(event->Get()->Path, ctx.SelfID));
+ }
+
+ void Handle(NHttp::TEvHttpProxy::TEvHttpOutgoingResponse::TPtr event, const NActors::TActorContext& ctx) {
+ NHttp::THttpIncomingRequestPtr request(event->Get()->Response->GetRequest());
+ NHttp::THttpOutgoingResponsePtr response(event->Get()->Response);
+ auto itRequests = IncomingRequests.find(request.Get());
+ if (itRequests == IncomingRequests.end()) {
+ LOG_ERROR_S(ctx, HttpLog, "Cache received response to unknown request " << request->Host << request->URL);
+ return;
+ }
+
+ TCacheKey key = itRequests->second;
+ auto it = Cache.find(key);
+ if (it == Cache.end()) {
+ LOG_ERROR_S(ctx, HttpLog, "Cache received response to unknown cache key " << request->Host << request->URL);
+ return;
+ }
+
+ IncomingRequests.erase(itRequests);
+ TCacheRecord& cacheRecord = it->second;
+ TStringBuf status;
+ TString error;
+
+ if (event->Get()->Response != nullptr) {
+ status = event->Get()->Response->Status;
+ if (!status.StartsWith("2")) {
+ error = event->Get()->Response->Message;
+ }
+ }
+ if (cacheRecord.CachePolicy.RetriesCount > 0) {
+ auto itStatusToRetry = std::find(cacheRecord.CachePolicy.StatusesToRetry.begin(), cacheRecord.CachePolicy.StatusesToRetry.end(), status);
+ if (itStatusToRetry != cacheRecord.CachePolicy.StatusesToRetry.end()) {
+ if (cacheRecord.Retries < cacheRecord.CachePolicy.RetriesCount) {
+ ++cacheRecord.Retries;
+ LOG_WARN_S(ctx, HttpLog, "IncomingRetry " << cacheRecord.GetName() << ": " << status << " " << error);
+ SendCacheRequest(key, cacheRecord, ctx);
+ return;
+ }
+ }
+ }
+ for (auto& waiter : cacheRecord.Waiters) {
+ NHttp::THttpOutgoingResponsePtr response2;
+ response2 = response->Duplicate(waiter->Get()->Request);
+ ctx.Send(waiter->Sender, new NHttp::TEvHttpProxy::TEvHttpOutgoingResponse(response2));
+ }
+ cacheRecord.Waiters.clear();
+ if (!error.empty()) {
+ LOG_WARN_S(ctx, HttpLog, "Error from " << cacheRecord.GetName() << ": " << error);
+ if (!cacheRecord.Response) {
+ LOG_DEBUG_S(ctx, HttpLog, "IncomingDiscard " << cacheRecord.GetName());
+ DropCacheRecord(it);
+ return;
+ }
+ }
+ if (cacheRecord.CachePolicy.TimeToRefresh) {
+ LOG_DEBUG_S(ctx, HttpLog, "IncomingUpdate " << cacheRecord.GetName());
+ cacheRecord.UpdateResponse(response, error, ctx.Now());
+ if (!cacheRecord.Enqueued) {
+ RefreshQueue.push({it->first, it->second.RefreshTime});
+ cacheRecord.Enqueued = true;
+ }
+ LOG_DEBUG_S(ctx, HttpLog, "IncomingSchedule " << cacheRecord.GetName() << " at " << cacheRecord.RefreshTime << " until " << cacheRecord.DeathTime);
+ } else {
+ LOG_DEBUG_S(ctx, HttpLog, "IncomingDrop " << cacheRecord.GetName());
+ DropCacheRecord(it);
+ }
+ }
+
+ void Handle(NHttp::TEvHttpProxy::TEvHttpIncomingRequest::TPtr event, const NActors::TActorContext& ctx) {
+ const NHttp::THttpIncomingRequest* request = event->Get()->Request.Get();
+ TCachePolicy policy = GetCachePolicy(request);
+ if (policy.TimeToExpire == TDuration() && policy.RetriesCount == 0) {
+ TActorId handler = GetRequestHandler(event->Get()->Request);
+ if (handler) {
+ ctx.Send(event->Forward(handler));
+ }
+ return;
+ }
+ auto key = GetCacheKey(request, policy);
+ auto it = Cache.find(key);
+ if (it != Cache.end() && !policy.DiscardCache) {
+ it->second.UpdateExpireTime();
+ if (it->second.IsValid()) {
+ LOG_DEBUG_S(ctx, HttpLog, "IncomingRespond "
+ << it->second.GetName()
+ << " ("
+ << ((it->second.Response != nullptr) ? ToString(it->second.Response->Size()) : TString("error"))
+ << ")");
+ NHttp::THttpOutgoingResponsePtr response = it->second.Response;
+ if (response != nullptr) {
+ response = response->Duplicate(event->Get()->Request);
+ }
+ ctx.Send(event->Sender, new NHttp::TEvHttpProxy::TEvHttpOutgoingResponse(response));
+ return;
+ }
+ } else {
+ it = Cache.emplace(key, policy).first;
+ it->second.CacheId = key.GetId(); // for debugging
+ it->second.InitRequest(event->Get()->Request);
+ if (policy.DiscardCache) {
+ LOG_DEBUG_S(ctx, HttpLog, "IncomingDiscardCache " << it->second.GetName());
+ }
+ LOG_DEBUG_S(ctx, HttpLog, "IncomingInitiate " << it->second.GetName());
+ SendCacheRequest(key, it->second, ctx);
+ }
+ it->second.Waiters.emplace_back(std::move(event));
+ }
+
+ void HandleRefresh(const NActors::TActorContext& ctx) {
+ while (!RefreshQueue.empty() && RefreshQueue.top().RefreshTime <= ctx.Now()) {
+ TRefreshRecord rrec = RefreshQueue.top();
+ RefreshQueue.pop();
+ auto it = Cache.find(rrec.Key);
+ if (it != Cache.end()) {
+ it->second.Enqueued = false;
+ if (it->second.DeathTime > ctx.Now()) {
+ LOG_DEBUG_S(ctx, HttpLog, "IncomingRefresh " << it->second.GetName());
+ SendCacheRequest(it->first, it->second, ctx);
+ } else {
+ LOG_DEBUG_S(ctx, HttpLog, "IncomingForget " << it->second.GetName());
+ DropCacheRecord(it);
+ }
+ }
+ }
+ ctx.Schedule(RefreshTimeout, new NActors::TEvents::TEvWakeup());
+ }
+
+ STFUNC(StateWork) {
+ switch (ev->GetTypeRewrite()) {
+ HFunc(NHttp::TEvHttpProxy::TEvHttpIncomingResponse, Handle);
+ HFunc(NHttp::TEvHttpProxy::TEvHttpOutgoingRequest, Handle);
+ HFunc(NHttp::TEvHttpProxy::TEvAddListeningPort, Handle);
+ HFunc(NHttp::TEvHttpProxy::TEvRegisterHandler, Handle);
+ HFunc(NHttp::TEvHttpProxy::TEvHttpIncomingRequest, Handle);
+ HFunc(NHttp::TEvHttpProxy::TEvHttpOutgoingResponse, Handle);
+ CFunc(NActors::TEvents::TSystem::Wakeup, HandleRefresh);
+ }
+ }
+};
+
+TCachePolicy GetDefaultCachePolicy(const THttpRequest* request, const TCachePolicy& defaultPolicy) {
+ TCachePolicy policy = defaultPolicy;
+ THeaders headers(request->Headers);
+ TStringBuf cacheControl(headers["Cache-Control"]);
+ while (TStringBuf cacheItem = cacheControl.NextTok(',')) {
+ Trim(cacheItem, ' ');
+ if (cacheItem == "no-store" || cacheItem == "no-cache") {
+ policy.DiscardCache = true;
+ }
+ TStringBuf itemName = cacheItem.NextTok('=');
+ TrimEnd(itemName, ' ');
+ TrimBegin(cacheItem, ' ');
+ if (itemName == "max-age") {
+ policy.TimeToRefresh = policy.TimeToExpire = TDuration::Seconds(FromString(cacheItem));
+ }
+ if (itemName == "min-fresh") {
+ policy.TimeToRefresh = policy.TimeToExpire = TDuration::Seconds(FromString(cacheItem));
+ }
+ if (itemName == "stale-if-error") {
+ policy.KeepOnError = true;
+ }
+ }
+ return policy;
+}
+
NActors::IActor* CreateHttpCache(const NActors::TActorId& httpProxyId, TGetCachePolicy cachePolicy) {
- return new THttpOutgoingCacheActor(httpProxyId, std::move(cachePolicy));
-}
-
-NActors::IActor* CreateOutgoingHttpCache(const NActors::TActorId& httpProxyId, TGetCachePolicy cachePolicy) {
- return new THttpOutgoingCacheActor(httpProxyId, std::move(cachePolicy));
-}
-
-NActors::IActor* CreateIncomingHttpCache(const NActors::TActorId& httpProxyId, TGetCachePolicy cachePolicy) {
- return new THttpIncomingCacheActor(httpProxyId, std::move(cachePolicy));
-}
-
-}
+ return new THttpOutgoingCacheActor(httpProxyId, std::move(cachePolicy));
+}
+
+NActors::IActor* CreateOutgoingHttpCache(const NActors::TActorId& httpProxyId, TGetCachePolicy cachePolicy) {
+ return new THttpOutgoingCacheActor(httpProxyId, std::move(cachePolicy));
+}
+
+NActors::IActor* CreateIncomingHttpCache(const NActors::TActorId& httpProxyId, TGetCachePolicy cachePolicy) {
+ return new THttpIncomingCacheActor(httpProxyId, std::move(cachePolicy));
+}
+
+}
diff --git a/library/cpp/actors/http/http_cache.h b/library/cpp/actors/http/http_cache.h
index 567a8105f0b..ac38bdcac89 100644
--- a/library/cpp/actors/http/http_cache.h
+++ b/library/cpp/actors/http/http_cache.h
@@ -1,27 +1,27 @@
-#pragma once
+#pragma once
#include <library/cpp/actors/core/actor.h>
-#include "http.h"
-
-namespace NHttp {
-
-struct TCachePolicy {
- TDuration TimeToExpire;
- TDuration TimeToRefresh;
- TDuration PaceToRefresh;
- bool KeepOnError = false;
- bool DiscardCache = false;
- TArrayRef<TString> HeadersToCacheKey;
- TArrayRef<TString> StatusesToRetry;
- ui32 RetriesCount = 0;
-
- TCachePolicy() = default;
-};
-
-using TGetCachePolicy = std::function<TCachePolicy(const THttpRequest*)>;
-
+#include "http.h"
+
+namespace NHttp {
+
+struct TCachePolicy {
+ TDuration TimeToExpire;
+ TDuration TimeToRefresh;
+ TDuration PaceToRefresh;
+ bool KeepOnError = false;
+ bool DiscardCache = false;
+ TArrayRef<TString> HeadersToCacheKey;
+ TArrayRef<TString> StatusesToRetry;
+ ui32 RetriesCount = 0;
+
+ TCachePolicy() = default;
+};
+
+using TGetCachePolicy = std::function<TCachePolicy(const THttpRequest*)>;
+
NActors::IActor* CreateHttpCache(const NActors::TActorId& httpProxyId, TGetCachePolicy cachePolicy);
-NActors::IActor* CreateOutgoingHttpCache(const NActors::TActorId& httpProxyId, TGetCachePolicy cachePolicy);
-NActors::IActor* CreateIncomingHttpCache(const NActors::TActorId& httpProxyId, TGetCachePolicy cachePolicy);
-TCachePolicy GetDefaultCachePolicy(const THttpRequest* request, const TCachePolicy& policy = TCachePolicy());
-
-}
+NActors::IActor* CreateOutgoingHttpCache(const NActors::TActorId& httpProxyId, TGetCachePolicy cachePolicy);
+NActors::IActor* CreateIncomingHttpCache(const NActors::TActorId& httpProxyId, TGetCachePolicy cachePolicy);
+TCachePolicy GetDefaultCachePolicy(const THttpRequest* request, const TCachePolicy& policy = TCachePolicy());
+
+}
diff --git a/library/cpp/actors/http/http_config.h b/library/cpp/actors/http/http_config.h
index eeafd2a0199..faeff79449a 100644
--- a/library/cpp/actors/http/http_config.h
+++ b/library/cpp/actors/http/http_config.h
@@ -1,19 +1,19 @@
-#pragma once
-#include <util/network/sock.h>
+#pragma once
+#include <util/network/sock.h>
#include <library/cpp/actors/core/log.h>
#include <library/cpp/actors/protos/services_common.pb.h>
-
-namespace NHttp {
-
-struct THttpConfig {
- static constexpr NActors::NLog::EComponent HttpLog = NActorsServices::EServiceCommon::HTTP;
- static constexpr size_t BUFFER_SIZE = 64 * 1024;
- static constexpr size_t BUFFER_MIN_STEP = 10 * 1024;
- static constexpr int LISTEN_QUEUE = 10;
- static constexpr TDuration SOCKET_TIMEOUT = TDuration::MilliSeconds(60000);
- static constexpr TDuration CONNECTION_TIMEOUT = TDuration::MilliSeconds(60000);
- using SocketType = TInet6StreamSocket;
- using SocketAddressType = TSockAddrInet6;
-};
-
-}
+
+namespace NHttp {
+
+struct THttpConfig {
+ static constexpr NActors::NLog::EComponent HttpLog = NActorsServices::EServiceCommon::HTTP;
+ static constexpr size_t BUFFER_SIZE = 64 * 1024;
+ static constexpr size_t BUFFER_MIN_STEP = 10 * 1024;
+ static constexpr int LISTEN_QUEUE = 10;
+ static constexpr TDuration SOCKET_TIMEOUT = TDuration::MilliSeconds(60000);
+ static constexpr TDuration CONNECTION_TIMEOUT = TDuration::MilliSeconds(60000);
+ using SocketType = TInet6StreamSocket;
+ using SocketAddressType = TSockAddrInet6;
+};
+
+}
diff --git a/library/cpp/actors/http/http_proxy.cpp b/library/cpp/actors/http/http_proxy.cpp
index 2217838624c..36c6855d93f 100644
--- a/library/cpp/actors/http/http_proxy.cpp
+++ b/library/cpp/actors/http/http_proxy.cpp
@@ -1,314 +1,314 @@
#include <library/cpp/actors/core/events.h>
#include <library/cpp/monlib/metrics/metric_registry.h>
-#include "http_proxy.h"
-
-namespace NHttp {
-
-class THttpProxy : public NActors::TActorBootstrapped<THttpProxy>, public THttpConfig {
-public:
- IActor* AddListeningPort(TEvHttpProxy::TEvAddListeningPort::TPtr event, const NActors::TActorContext& ctx) {
- IActor* listeningSocket = CreateHttpAcceptorActor(ctx.SelfID, Poller);
+#include "http_proxy.h"
+
+namespace NHttp {
+
+class THttpProxy : public NActors::TActorBootstrapped<THttpProxy>, public THttpConfig {
+public:
+ IActor* AddListeningPort(TEvHttpProxy::TEvAddListeningPort::TPtr event, const NActors::TActorContext& ctx) {
+ IActor* listeningSocket = CreateHttpAcceptorActor(ctx.SelfID, Poller);
TActorId acceptorId = ctx.Register(listeningSocket);
- ctx.Send(event->Forward(acceptorId));
- Acceptors.emplace_back(acceptorId);
- return listeningSocket;
- }
-
- IActor* AddOutgoingConnection(const TString& address, bool secure, const NActors::TActorContext& ctx) {
- IActor* connectionSocket = CreateOutgoingConnectionActor(ctx.SelfID, address, secure, Poller);
+ ctx.Send(event->Forward(acceptorId));
+ Acceptors.emplace_back(acceptorId);
+ return listeningSocket;
+ }
+
+ IActor* AddOutgoingConnection(const TString& address, bool secure, const NActors::TActorContext& ctx) {
+ IActor* connectionSocket = CreateOutgoingConnectionActor(ctx.SelfID, address, secure, Poller);
TActorId connectionId = ctx.Register(connectionSocket);
- Connections.emplace(connectionId);
- return connectionSocket;
- }
-
- void Bootstrap(const NActors::TActorContext& ctx) {
- Poller = ctx.Register(NActors::CreatePollerActor());
- Become(&THttpProxy::StateWork);
- }
-
+ Connections.emplace(connectionId);
+ return connectionSocket;
+ }
+
+ void Bootstrap(const NActors::TActorContext& ctx) {
+ Poller = ctx.Register(NActors::CreatePollerActor());
+ Become(&THttpProxy::StateWork);
+ }
+
THttpProxy(NMonitoring::TMetricRegistry& sensors)
- : Sensors(sensors)
- {}
-
-protected:
- STFUNC(StateWork) {
- switch (ev->GetTypeRewrite()) {
- HFunc(TEvHttpProxy::TEvAddListeningPort, Handle);
- HFunc(TEvHttpProxy::TEvRegisterHandler, Handle);
- HFunc(TEvHttpProxy::TEvHttpIncomingRequest, Handle);
- HFunc(TEvHttpProxy::TEvHttpOutgoingRequest, Handle);
- HFunc(TEvHttpProxy::TEvHttpIncomingResponse, Handle);
- HFunc(TEvHttpProxy::TEvHttpOutgoingResponse, Handle);
- HFunc(TEvHttpProxy::TEvHttpAcceptorClosed, Handle);
- HFunc(TEvHttpProxy::TEvHttpConnectionClosed, Handle);
- HFunc(TEvHttpProxy::TEvResolveHostRequest, Handle);
- HFunc(TEvHttpProxy::TEvReportSensors, Handle);
+ : Sensors(sensors)
+ {}
+
+protected:
+ STFUNC(StateWork) {
+ switch (ev->GetTypeRewrite()) {
+ HFunc(TEvHttpProxy::TEvAddListeningPort, Handle);
+ HFunc(TEvHttpProxy::TEvRegisterHandler, Handle);
+ HFunc(TEvHttpProxy::TEvHttpIncomingRequest, Handle);
+ HFunc(TEvHttpProxy::TEvHttpOutgoingRequest, Handle);
+ HFunc(TEvHttpProxy::TEvHttpIncomingResponse, Handle);
+ HFunc(TEvHttpProxy::TEvHttpOutgoingResponse, Handle);
+ HFunc(TEvHttpProxy::TEvHttpAcceptorClosed, Handle);
+ HFunc(TEvHttpProxy::TEvHttpConnectionClosed, Handle);
+ HFunc(TEvHttpProxy::TEvResolveHostRequest, Handle);
+ HFunc(TEvHttpProxy::TEvReportSensors, Handle);
HFunc(NActors::TEvents::TEvPoison, Handle);
- }
- }
-
+ }
+ }
+
void PassAway() override {
Send(Poller, new NActors::TEvents::TEvPoisonPill());
for (const NActors::TActorId& connection : Connections) {
Send(connection, new NActors::TEvents::TEvPoisonPill());
- }
+ }
for (const NActors::TActorId& acceptor : Acceptors) {
Send(acceptor, new NActors::TEvents::TEvPoisonPill());
- }
+ }
NActors::TActorBootstrapped<THttpProxy>::PassAway();
- }
-
- void Handle(TEvHttpProxy::TEvHttpIncomingRequest::TPtr event, const NActors::TActorContext& ctx) {
- TStringBuf url = event->Get()->Request->URL.Before('?');
+ }
+
+ void Handle(TEvHttpProxy::TEvHttpIncomingRequest::TPtr event, const NActors::TActorContext& ctx) {
+ TStringBuf url = event->Get()->Request->URL.Before('?');
THashMap<TString, TActorId>::iterator it;
- while (!url.empty()) {
- it = Handlers.find(url);
- if (it != Handlers.end()) {
- ctx.Send(event->Forward(it->second));
- return;
- } else {
- if (url.EndsWith('/')) {
- url.Trunc(url.size() - 1);
- }
- size_t pos = url.rfind('/');
- if (pos == TStringBuf::npos) {
- break;
- } else {
- url = url.substr(0, pos + 1);
- }
- }
- }
- ctx.Send(event->Sender, new TEvHttpProxy::TEvHttpOutgoingResponse(event->Get()->Request->CreateResponseNotFound()));
- }
-
- void Handle(TEvHttpProxy::TEvHttpIncomingResponse::TPtr event, const NActors::TActorContext& ctx) {
- Y_UNUSED(event);
- Y_UNUSED(ctx);
- Y_FAIL("This event shouldn't be there, it should go to the http connection owner directly");
- }
-
- void Handle(TEvHttpProxy::TEvHttpOutgoingResponse::TPtr event, const NActors::TActorContext& ctx) {
- Y_UNUSED(event);
- Y_UNUSED(ctx);
- Y_FAIL("This event shouldn't be there, it should go to the http connection directly");
- }
-
- void Handle(TEvHttpProxy::TEvHttpOutgoingRequest::TPtr event, const NActors::TActorContext& ctx) {
- TStringBuf host(event->Get()->Request->Host);
- bool secure(event->Get()->Request->Secure);
- NActors::IActor* actor = AddOutgoingConnection(TString(host), secure, ctx);
- ctx.Send(event->Forward(actor->SelfId()));
- }
-
- void Handle(TEvHttpProxy::TEvAddListeningPort::TPtr event, const NActors::TActorContext& ctx) {
- AddListeningPort(event, ctx);
- }
-
- void Handle(TEvHttpProxy::TEvHttpAcceptorClosed::TPtr event, const NActors::TActorContext&) {
- for (auto it = Acceptors.begin(); it != Acceptors.end(); ++it) {
- if (*it == event->Get()->ConnectionID) {
- Acceptors.erase(it);
- break;
- }
- }
- }
-
- void Handle(TEvHttpProxy::TEvHttpConnectionClosed::TPtr event, const NActors::TActorContext&) {
- Connections.erase(event->Get()->ConnectionID);
- }
-
- void Handle(TEvHttpProxy::TEvRegisterHandler::TPtr event, const NActors::TActorContext&) {
- Handlers[event->Get()->Path] = event->Get()->Handler;
- }
-
- void Handle(TEvHttpProxy::TEvResolveHostRequest::TPtr event, const NActors::TActorContext& ctx) {
- const TString& host(event->Get()->Host);
- auto it = Hosts.find(host);
- if (it == Hosts.end() || it->second.DeadlineTime > ctx.Now()) {
- TString addressPart;
- TIpPort portPart = 0;
- CrackAddress(host, addressPart, portPart);
- if (IsIPv6(addressPart)) {
- TSockAddrInet6 address(addressPart.c_str(), portPart);
- if (it == Hosts.end()) {
- it = Hosts.emplace(host, THostEntry()).first;
- }
- it->second.Address = address;
- it->second.DeadlineTime = ctx.Now() + HostsTimeToLive;
- } else {
- // TODO(xenoxeno): move to another, possible blocking actor
- try {
- const NDns::TResolvedHost* result = NDns::CachedResolve(NDns::TResolveInfo(addressPart, portPart));
- if (result != nullptr) {
- auto pAddr = result->Addr.Begin();
- while (pAddr != result->Addr.End() && pAddr->ai_family != AF_INET6) {
- ++pAddr;
- }
- if (pAddr == result->Addr.End()) {
- ctx.Send(event->Sender, new TEvHttpProxy::TEvResolveHostResponse("Invalid address family resolved"));
- return;
- }
- TSockAddrInet6 address = {};
- static_cast<sockaddr_in6&>(address) = *reinterpret_cast<sockaddr_in6*>(pAddr->ai_addr);
- LOG_DEBUG_S(ctx, HttpLog, "Host " << host << " resolved to " << address.ToString());
- if (it == Hosts.end()) {
- it = Hosts.emplace(host, THostEntry()).first;
- }
- it->second.Address = address;
- it->second.DeadlineTime = ctx.Now() + HostsTimeToLive;
- } else {
- ctx.Send(event->Sender, new TEvHttpProxy::TEvResolveHostResponse("Error resolving host"));
- return;
- }
- }
- catch (const yexception& e) {
- ctx.Send(event->Sender, new TEvHttpProxy::TEvResolveHostResponse(e.what()));
- return;
- }
- }
- }
- ctx.Send(event->Sender, new TEvHttpProxy::TEvResolveHostResponse(it->first, it->second.Address));
- }
-
- void Handle(TEvHttpProxy::TEvReportSensors::TPtr event, const NActors::TActorContext&) {
- const TEvHttpProxy::TEvReportSensors& sensors(*event->Get());
+ while (!url.empty()) {
+ it = Handlers.find(url);
+ if (it != Handlers.end()) {
+ ctx.Send(event->Forward(it->second));
+ return;
+ } else {
+ if (url.EndsWith('/')) {
+ url.Trunc(url.size() - 1);
+ }
+ size_t pos = url.rfind('/');
+ if (pos == TStringBuf::npos) {
+ break;
+ } else {
+ url = url.substr(0, pos + 1);
+ }
+ }
+ }
+ ctx.Send(event->Sender, new TEvHttpProxy::TEvHttpOutgoingResponse(event->Get()->Request->CreateResponseNotFound()));
+ }
+
+ void Handle(TEvHttpProxy::TEvHttpIncomingResponse::TPtr event, const NActors::TActorContext& ctx) {
+ Y_UNUSED(event);
+ Y_UNUSED(ctx);
+ Y_FAIL("This event shouldn't be there, it should go to the http connection owner directly");
+ }
+
+ void Handle(TEvHttpProxy::TEvHttpOutgoingResponse::TPtr event, const NActors::TActorContext& ctx) {
+ Y_UNUSED(event);
+ Y_UNUSED(ctx);
+ Y_FAIL("This event shouldn't be there, it should go to the http connection directly");
+ }
+
+ void Handle(TEvHttpProxy::TEvHttpOutgoingRequest::TPtr event, const NActors::TActorContext& ctx) {
+ TStringBuf host(event->Get()->Request->Host);
+ bool secure(event->Get()->Request->Secure);
+ NActors::IActor* actor = AddOutgoingConnection(TString(host), secure, ctx);
+ ctx.Send(event->Forward(actor->SelfId()));
+ }
+
+ void Handle(TEvHttpProxy::TEvAddListeningPort::TPtr event, const NActors::TActorContext& ctx) {
+ AddListeningPort(event, ctx);
+ }
+
+ void Handle(TEvHttpProxy::TEvHttpAcceptorClosed::TPtr event, const NActors::TActorContext&) {
+ for (auto it = Acceptors.begin(); it != Acceptors.end(); ++it) {
+ if (*it == event->Get()->ConnectionID) {
+ Acceptors.erase(it);
+ break;
+ }
+ }
+ }
+
+ void Handle(TEvHttpProxy::TEvHttpConnectionClosed::TPtr event, const NActors::TActorContext&) {
+ Connections.erase(event->Get()->ConnectionID);
+ }
+
+ void Handle(TEvHttpProxy::TEvRegisterHandler::TPtr event, const NActors::TActorContext&) {
+ Handlers[event->Get()->Path] = event->Get()->Handler;
+ }
+
+ void Handle(TEvHttpProxy::TEvResolveHostRequest::TPtr event, const NActors::TActorContext& ctx) {
+ const TString& host(event->Get()->Host);
+ auto it = Hosts.find(host);
+ if (it == Hosts.end() || it->second.DeadlineTime > ctx.Now()) {
+ TString addressPart;
+ TIpPort portPart = 0;
+ CrackAddress(host, addressPart, portPart);
+ if (IsIPv6(addressPart)) {
+ TSockAddrInet6 address(addressPart.c_str(), portPart);
+ if (it == Hosts.end()) {
+ it = Hosts.emplace(host, THostEntry()).first;
+ }
+ it->second.Address = address;
+ it->second.DeadlineTime = ctx.Now() + HostsTimeToLive;
+ } else {
+ // TODO(xenoxeno): move to another, possible blocking actor
+ try {
+ const NDns::TResolvedHost* result = NDns::CachedResolve(NDns::TResolveInfo(addressPart, portPart));
+ if (result != nullptr) {
+ auto pAddr = result->Addr.Begin();
+ while (pAddr != result->Addr.End() && pAddr->ai_family != AF_INET6) {
+ ++pAddr;
+ }
+ if (pAddr == result->Addr.End()) {
+ ctx.Send(event->Sender, new TEvHttpProxy::TEvResolveHostResponse("Invalid address family resolved"));
+ return;
+ }
+ TSockAddrInet6 address = {};
+ static_cast<sockaddr_in6&>(address) = *reinterpret_cast<sockaddr_in6*>(pAddr->ai_addr);
+ LOG_DEBUG_S(ctx, HttpLog, "Host " << host << " resolved to " << address.ToString());
+ if (it == Hosts.end()) {
+ it = Hosts.emplace(host, THostEntry()).first;
+ }
+ it->second.Address = address;
+ it->second.DeadlineTime = ctx.Now() + HostsTimeToLive;
+ } else {
+ ctx.Send(event->Sender, new TEvHttpProxy::TEvResolveHostResponse("Error resolving host"));
+ return;
+ }
+ }
+ catch (const yexception& e) {
+ ctx.Send(event->Sender, new TEvHttpProxy::TEvResolveHostResponse(e.what()));
+ return;
+ }
+ }
+ }
+ ctx.Send(event->Sender, new TEvHttpProxy::TEvResolveHostResponse(it->first, it->second.Address));
+ }
+
+ void Handle(TEvHttpProxy::TEvReportSensors::TPtr event, const NActors::TActorContext&) {
+ const TEvHttpProxy::TEvReportSensors& sensors(*event->Get());
const static TString urlNotFound = "not-found";
const TString& url = (sensors.Status == "404" ? urlNotFound : sensors.Url);
- Sensors.Rate({
- {"sensor", "count"},
- {"direction", sensors.Direction},
- {"peer", sensors.Host},
+ Sensors.Rate({
+ {"sensor", "count"},
+ {"direction", sensors.Direction},
+ {"peer", sensors.Host},
{"url", url},
- {"status", sensors.Status}
- })->Inc();
- Sensors.HistogramRate({
- {"sensor", "time_us"},
- {"direction", sensors.Direction},
- {"peer", sensors.Host},
+ {"status", sensors.Status}
+ })->Inc();
+ Sensors.HistogramRate({
+ {"sensor", "time_us"},
+ {"direction", sensors.Direction},
+ {"peer", sensors.Host},
{"url", url},
- {"status", sensors.Status}
- },
- NMonitoring::ExplicitHistogram({1, 5, 10, 50, 100, 500, 1000, 5000, 10000, 30000, 60000}))->Record(sensors.Time.MicroSeconds());
- Sensors.HistogramRate({
- {"sensor", "time_ms"},
- {"direction", sensors.Direction},
- {"peer", sensors.Host},
+ {"status", sensors.Status}
+ },
+ NMonitoring::ExplicitHistogram({1, 5, 10, 50, 100, 500, 1000, 5000, 10000, 30000, 60000}))->Record(sensors.Time.MicroSeconds());
+ Sensors.HistogramRate({
+ {"sensor", "time_ms"},
+ {"direction", sensors.Direction},
+ {"peer", sensors.Host},
{"url", url},
- {"status", sensors.Status}
- },
- NMonitoring::ExplicitHistogram({1, 5, 10, 50, 100, 500, 1000, 5000, 10000, 30000, 60000}))->Record(sensors.Time.MilliSeconds());
- }
-
+ {"status", sensors.Status}
+ },
+ NMonitoring::ExplicitHistogram({1, 5, 10, 50, 100, 500, 1000, 5000, 10000, 30000, 60000}))->Record(sensors.Time.MilliSeconds());
+ }
+
void Handle(NActors::TEvents::TEvPoison::TPtr, const NActors::TActorContext&) {
PassAway();
}
NActors::TActorId Poller;
TVector<TActorId> Acceptors;
-
- struct THostEntry {
- TSockAddrInet6 Address;
- TInstant DeadlineTime;
- };
-
- static constexpr TDuration HostsTimeToLive = TDuration::Seconds(60);
-
- THashMap<TString, THostEntry> Hosts;
+
+ struct THostEntry {
+ TSockAddrInet6 Address;
+ TInstant DeadlineTime;
+ };
+
+ static constexpr TDuration HostsTimeToLive = TDuration::Seconds(60);
+
+ THashMap<TString, THostEntry> Hosts;
THashMap<TString, TActorId> Handlers;
THashSet<TActorId> Connections; // outgoing
NMonitoring::TMetricRegistry& Sensors;
-};
-
-TEvHttpProxy::TEvReportSensors* BuildOutgoingRequestSensors(const THttpOutgoingRequestPtr& request, const THttpIncomingResponsePtr& response) {
- return new TEvHttpProxy::TEvReportSensors(
- "out",
- request->Host,
- request->URL.Before('?'),
- response ? response->Status : "504",
+};
+
+TEvHttpProxy::TEvReportSensors* BuildOutgoingRequestSensors(const THttpOutgoingRequestPtr& request, const THttpIncomingResponsePtr& response) {
+ return new TEvHttpProxy::TEvReportSensors(
+ "out",
+ request->Host,
+ request->URL.Before('?'),
+ response ? response->Status : "504",
TDuration::Seconds(std::abs(request->Timer.Passed()))
- );
-}
-
-TEvHttpProxy::TEvReportSensors* BuildIncomingRequestSensors(const THttpIncomingRequestPtr& request, const THttpOutgoingResponsePtr& response) {
- return new TEvHttpProxy::TEvReportSensors(
- "in",
- request->Host,
- request->URL.Before('?'),
- response->Status,
+ );
+}
+
+TEvHttpProxy::TEvReportSensors* BuildIncomingRequestSensors(const THttpIncomingRequestPtr& request, const THttpOutgoingResponsePtr& response) {
+ return new TEvHttpProxy::TEvReportSensors(
+ "in",
+ request->Host,
+ request->URL.Before('?'),
+ response->Status,
TDuration::Seconds(std::abs(request->Timer.Passed()))
- );
-}
-
+ );
+}
+
NActors::IActor* CreateHttpProxy(NMonitoring::TMetricRegistry& sensors) {
- return new THttpProxy(sensors);
-}
-
-bool IsIPv6(const TString& host) {
- return host.find_first_not_of(":0123456789abcdef") == TString::npos;
-}
-
-bool CrackURL(TStringBuf url, TStringBuf& scheme, TStringBuf& host, TStringBuf& uri) {
- url.TrySplit("://", scheme, url);
- auto pos = url.find('/');
- if (pos == TStringBuf::npos) {
- host = url;
- } else {
- host = url.substr(0, pos);
- uri = url.substr(pos);
- }
- return true;
-}
-
-void CrackAddress(const TString& address, TString& hostname, TIpPort& port) {
- size_t first_colon_pos = address.find(':');
- if (first_colon_pos != TString::npos) {
- size_t last_colon_pos = address.rfind(':');
- if (last_colon_pos == first_colon_pos) {
- // only one colon, simple case
- port = FromStringWithDefault<TIpPort>(address.substr(first_colon_pos + 1), 0);
- hostname = address.substr(0, first_colon_pos);
- } else {
- // ipv6?
- size_t closing_bracket_pos = address.rfind(']');
- if (closing_bracket_pos == TString::npos || closing_bracket_pos > last_colon_pos) {
- // whole address is ipv6 host
- hostname = address;
- } else {
- port = FromStringWithDefault<TIpPort>(address.substr(last_colon_pos + 1), 0);
- hostname = address.substr(0, last_colon_pos);
- }
- if (hostname.StartsWith('[') && hostname.EndsWith(']')) {
- hostname = hostname.substr(1, hostname.size() - 2);
- }
- }
- } else {
- hostname = address;
- }
-}
-
-
-void TrimBegin(TStringBuf& target, char delim) {
- while (!target.empty() && *target.begin() == delim) {
- target.Skip(1);
- }
-}
-
-void TrimEnd(TStringBuf& target, char delim) {
- while (!target.empty() && target.back() == delim) {
- target.Trunc(target.size() - 1);
- }
-}
-
-void Trim(TStringBuf& target, char delim) {
- TrimBegin(target, delim);
- TrimEnd(target, delim);
-}
-
-void TrimEnd(TString& target, char delim) {
- while (!target.empty() && target.back() == delim) {
- target.resize(target.size() - 1);
- }
-}
-
-}
+ return new THttpProxy(sensors);
+}
+
+bool IsIPv6(const TString& host) {
+ return host.find_first_not_of(":0123456789abcdef") == TString::npos;
+}
+
+bool CrackURL(TStringBuf url, TStringBuf& scheme, TStringBuf& host, TStringBuf& uri) {
+ url.TrySplit("://", scheme, url);
+ auto pos = url.find('/');
+ if (pos == TStringBuf::npos) {
+ host = url;
+ } else {
+ host = url.substr(0, pos);
+ uri = url.substr(pos);
+ }
+ return true;
+}
+
+void CrackAddress(const TString& address, TString& hostname, TIpPort& port) {
+ size_t first_colon_pos = address.find(':');
+ if (first_colon_pos != TString::npos) {
+ size_t last_colon_pos = address.rfind(':');
+ if (last_colon_pos == first_colon_pos) {
+ // only one colon, simple case
+ port = FromStringWithDefault<TIpPort>(address.substr(first_colon_pos + 1), 0);
+ hostname = address.substr(0, first_colon_pos);
+ } else {
+ // ipv6?
+ size_t closing_bracket_pos = address.rfind(']');
+ if (closing_bracket_pos == TString::npos || closing_bracket_pos > last_colon_pos) {
+ // whole address is ipv6 host
+ hostname = address;
+ } else {
+ port = FromStringWithDefault<TIpPort>(address.substr(last_colon_pos + 1), 0);
+ hostname = address.substr(0, last_colon_pos);
+ }
+ if (hostname.StartsWith('[') && hostname.EndsWith(']')) {
+ hostname = hostname.substr(1, hostname.size() - 2);
+ }
+ }
+ } else {
+ hostname = address;
+ }
+}
+
+
+void TrimBegin(TStringBuf& target, char delim) {
+ while (!target.empty() && *target.begin() == delim) {
+ target.Skip(1);
+ }
+}
+
+void TrimEnd(TStringBuf& target, char delim) {
+ while (!target.empty() && target.back() == delim) {
+ target.Trunc(target.size() - 1);
+ }
+}
+
+void Trim(TStringBuf& target, char delim) {
+ TrimBegin(target, delim);
+ TrimEnd(target, delim);
+}
+
+void TrimEnd(TString& target, char delim) {
+ while (!target.empty() && target.back() == delim) {
+ target.resize(target.size() - 1);
+ }
+}
+
+}
diff --git a/library/cpp/actors/http/http_proxy.h b/library/cpp/actors/http/http_proxy.h
index ce77bf8d5f7..afd0170997e 100644
--- a/library/cpp/actors/http/http_proxy.h
+++ b/library/cpp/actors/http/http_proxy.h
@@ -1,4 +1,4 @@
-#pragma once
+#pragma once
#include <library/cpp/actors/core/actorsystem.h>
#include <library/cpp/actors/core/actor.h>
#include <library/cpp/actors/core/hfunc.h>
@@ -9,231 +9,231 @@
#include <library/cpp/actors/interconnect/poller_actor.h>
#include <library/cpp/dns/cache.h>
#include <library/cpp/monlib/metrics/metric_registry.h>
-#include <util/generic/variant.h>
-#include "http.h"
-#include "http_proxy_ssl.h"
-
-namespace NHttp {
-
-struct TSocketDescriptor : NActors::TSharedDescriptor, THttpConfig {
- SocketType Socket;
-
- int GetDescriptor() override {
- return static_cast<SOCKET>(Socket);
- }
-};
-
-struct TEvHttpProxy {
- enum EEv {
+#include <util/generic/variant.h>
+#include "http.h"
+#include "http_proxy_ssl.h"
+
+namespace NHttp {
+
+struct TSocketDescriptor : NActors::TSharedDescriptor, THttpConfig {
+ SocketType Socket;
+
+ int GetDescriptor() override {
+ return static_cast<SOCKET>(Socket);
+ }
+};
+
+struct TEvHttpProxy {
+ enum EEv {
EvAddListeningPort = EventSpaceBegin(NActors::TEvents::ES_HTTP),
- EvConfirmListen,
- EvRegisterHandler,
- EvHttpIncomingRequest,
- EvHttpOutgoingRequest,
- EvHttpIncomingResponse,
- EvHttpOutgoingResponse,
- EvHttpConnectionOpened,
- EvHttpConnectionClosed,
- EvHttpAcceptorClosed,
- EvResolveHostRequest,
- EvResolveHostResponse,
- EvReportSensors,
- EvEnd
- };
-
+ EvConfirmListen,
+ EvRegisterHandler,
+ EvHttpIncomingRequest,
+ EvHttpOutgoingRequest,
+ EvHttpIncomingResponse,
+ EvHttpOutgoingResponse,
+ EvHttpConnectionOpened,
+ EvHttpConnectionClosed,
+ EvHttpAcceptorClosed,
+ EvResolveHostRequest,
+ EvResolveHostResponse,
+ EvReportSensors,
+ EvEnd
+ };
+
static_assert(EvEnd < EventSpaceEnd(NActors::TEvents::ES_HTTP), "ES_HTTP event space is too small.");
-
- struct TEvAddListeningPort : NActors::TEventLocal<TEvAddListeningPort, EvAddListeningPort> {
- TIpPort Port;
- TString WorkerName;
- bool Secure = false;
- TString CertificateFile;
- TString PrivateKeyFile;
+
+ struct TEvAddListeningPort : NActors::TEventLocal<TEvAddListeningPort, EvAddListeningPort> {
+ TIpPort Port;
+ TString WorkerName;
+ bool Secure = false;
+ TString CertificateFile;
+ TString PrivateKeyFile;
TString SslCertificatePem;
-
- TEvAddListeningPort(TIpPort port)
- : Port(port)
- {}
-
- TEvAddListeningPort(TIpPort port, const TString& workerName)
- : Port(port)
- , WorkerName(workerName)
- {}
- };
-
- struct TEvConfirmListen : NActors::TEventLocal<TEvConfirmListen, EvConfirmListen> {
- THttpConfig::SocketAddressType Address;
-
- TEvConfirmListen(const THttpConfig::SocketAddressType& address)
- : Address(address)
- {}
- };
-
- struct TEvRegisterHandler : NActors::TEventLocal<TEvRegisterHandler, EvRegisterHandler> {
- TString Path;
+
+ TEvAddListeningPort(TIpPort port)
+ : Port(port)
+ {}
+
+ TEvAddListeningPort(TIpPort port, const TString& workerName)
+ : Port(port)
+ , WorkerName(workerName)
+ {}
+ };
+
+ struct TEvConfirmListen : NActors::TEventLocal<TEvConfirmListen, EvConfirmListen> {
+ THttpConfig::SocketAddressType Address;
+
+ TEvConfirmListen(const THttpConfig::SocketAddressType& address)
+ : Address(address)
+ {}
+ };
+
+ struct TEvRegisterHandler : NActors::TEventLocal<TEvRegisterHandler, EvRegisterHandler> {
+ TString Path;
TActorId Handler;
-
+
TEvRegisterHandler(const TString& path, const TActorId& handler)
- : Path(path)
- , Handler(handler)
- {}
- };
-
- struct TEvHttpIncomingRequest : NActors::TEventLocal<TEvHttpIncomingRequest, EvHttpIncomingRequest> {
- THttpIncomingRequestPtr Request;
-
- TEvHttpIncomingRequest(THttpIncomingRequestPtr request)
- : Request(std::move(request))
- {}
- };
-
- struct TEvHttpOutgoingRequest : NActors::TEventLocal<TEvHttpOutgoingRequest, EvHttpOutgoingRequest> {
- THttpOutgoingRequestPtr Request;
- TDuration Timeout;
-
- TEvHttpOutgoingRequest(THttpOutgoingRequestPtr request)
- : Request(std::move(request))
- {}
-
- TEvHttpOutgoingRequest(THttpOutgoingRequestPtr request, TDuration timeout)
- : Request(std::move(request))
- , Timeout(timeout)
- {}
- };
-
- struct TEvHttpIncomingResponse : NActors::TEventLocal<TEvHttpIncomingResponse, EvHttpIncomingResponse> {
- THttpOutgoingRequestPtr Request;
- THttpIncomingResponsePtr Response;
- TString Error;
-
- TEvHttpIncomingResponse(THttpOutgoingRequestPtr request, THttpIncomingResponsePtr response, const TString& error)
- : Request(std::move(request))
- , Response(std::move(response))
- , Error(error)
- {}
-
- TEvHttpIncomingResponse(THttpOutgoingRequestPtr request, THttpIncomingResponsePtr response)
- : Request(std::move(request))
- , Response(std::move(response))
- {}
-
- TString GetError() const {
- TStringBuilder error;
- if (Response != nullptr && !Response->Status.StartsWith('2')) {
- error << Response->Status << ' ' << Response->Message;
- }
- if (!Error.empty()) {
- if (!error.empty()) {
- error << ';';
- }
- error << Error;
- }
- return error;
- }
- };
-
- struct TEvHttpOutgoingResponse : NActors::TEventLocal<TEvHttpOutgoingResponse, EvHttpOutgoingResponse> {
- THttpOutgoingResponsePtr Response;
-
- TEvHttpOutgoingResponse(THttpOutgoingResponsePtr response)
- : Response(std::move(response))
- {}
- };
-
- struct TEvHttpConnectionOpened : NActors::TEventLocal<TEvHttpConnectionOpened, EvHttpConnectionOpened> {
- TString PeerAddress;
+ : Path(path)
+ , Handler(handler)
+ {}
+ };
+
+ struct TEvHttpIncomingRequest : NActors::TEventLocal<TEvHttpIncomingRequest, EvHttpIncomingRequest> {
+ THttpIncomingRequestPtr Request;
+
+ TEvHttpIncomingRequest(THttpIncomingRequestPtr request)
+ : Request(std::move(request))
+ {}
+ };
+
+ struct TEvHttpOutgoingRequest : NActors::TEventLocal<TEvHttpOutgoingRequest, EvHttpOutgoingRequest> {
+ THttpOutgoingRequestPtr Request;
+ TDuration Timeout;
+
+ TEvHttpOutgoingRequest(THttpOutgoingRequestPtr request)
+ : Request(std::move(request))
+ {}
+
+ TEvHttpOutgoingRequest(THttpOutgoingRequestPtr request, TDuration timeout)
+ : Request(std::move(request))
+ , Timeout(timeout)
+ {}
+ };
+
+ struct TEvHttpIncomingResponse : NActors::TEventLocal<TEvHttpIncomingResponse, EvHttpIncomingResponse> {
+ THttpOutgoingRequestPtr Request;
+ THttpIncomingResponsePtr Response;
+ TString Error;
+
+ TEvHttpIncomingResponse(THttpOutgoingRequestPtr request, THttpIncomingResponsePtr response, const TString& error)
+ : Request(std::move(request))
+ , Response(std::move(response))
+ , Error(error)
+ {}
+
+ TEvHttpIncomingResponse(THttpOutgoingRequestPtr request, THttpIncomingResponsePtr response)
+ : Request(std::move(request))
+ , Response(std::move(response))
+ {}
+
+ TString GetError() const {
+ TStringBuilder error;
+ if (Response != nullptr && !Response->Status.StartsWith('2')) {
+ error << Response->Status << ' ' << Response->Message;
+ }
+ if (!Error.empty()) {
+ if (!error.empty()) {
+ error << ';';
+ }
+ error << Error;
+ }
+ return error;
+ }
+ };
+
+ struct TEvHttpOutgoingResponse : NActors::TEventLocal<TEvHttpOutgoingResponse, EvHttpOutgoingResponse> {
+ THttpOutgoingResponsePtr Response;
+
+ TEvHttpOutgoingResponse(THttpOutgoingResponsePtr response)
+ : Response(std::move(response))
+ {}
+ };
+
+ struct TEvHttpConnectionOpened : NActors::TEventLocal<TEvHttpConnectionOpened, EvHttpConnectionOpened> {
+ TString PeerAddress;
TActorId ConnectionID;
-
+
TEvHttpConnectionOpened(const TString& peerAddress, const TActorId& connectionID)
- : PeerAddress(peerAddress)
- , ConnectionID(connectionID)
- {}
- };
-
- struct TEvHttpConnectionClosed : NActors::TEventLocal<TEvHttpConnectionClosed, EvHttpConnectionClosed> {
+ : PeerAddress(peerAddress)
+ , ConnectionID(connectionID)
+ {}
+ };
+
+ struct TEvHttpConnectionClosed : NActors::TEventLocal<TEvHttpConnectionClosed, EvHttpConnectionClosed> {
TActorId ConnectionID;
- TDeque<THttpIncomingRequestPtr> RecycledRequests;
-
+ TDeque<THttpIncomingRequestPtr> RecycledRequests;
+
TEvHttpConnectionClosed(const TActorId& connectionID)
- : ConnectionID(connectionID)
- {}
-
+ : ConnectionID(connectionID)
+ {}
+
TEvHttpConnectionClosed(const TActorId& connectionID, TDeque<THttpIncomingRequestPtr> recycledRequests)
- : ConnectionID(connectionID)
- , RecycledRequests(std::move(recycledRequests))
- {}
- };
-
- struct TEvHttpAcceptorClosed : NActors::TEventLocal<TEvHttpAcceptorClosed, EvHttpAcceptorClosed> {
+ : ConnectionID(connectionID)
+ , RecycledRequests(std::move(recycledRequests))
+ {}
+ };
+
+ struct TEvHttpAcceptorClosed : NActors::TEventLocal<TEvHttpAcceptorClosed, EvHttpAcceptorClosed> {
TActorId ConnectionID;
-
+
TEvHttpAcceptorClosed(const TActorId& connectionID)
- : ConnectionID(connectionID)
- {}
- };
-
- struct TEvResolveHostRequest : NActors::TEventLocal<TEvResolveHostRequest, EvResolveHostRequest> {
- TString Host;
-
- TEvResolveHostRequest(const TString& host)
- : Host(host)
- {}
- };
-
- struct TEvResolveHostResponse : NActors::TEventLocal<TEvResolveHostResponse, EvResolveHostResponse> {
- TString Host;
- TSockAddrInet6 Address;
- TString Error;
-
- TEvResolveHostResponse(const TString& host, const TSockAddrInet6& address)
- : Host(host)
- , Address(address)
- {}
-
- TEvResolveHostResponse(const TString& error)
- : Error(error)
- {}
- };
-
- struct TEvReportSensors : NActors::TEventLocal<TEvReportSensors, EvReportSensors> {
- TString Direction;
- TString Host;
- TString Url;
- TString Status;
- TDuration Time;
-
- TEvReportSensors(
- TStringBuf direction,
- TStringBuf host,
- TStringBuf url,
- TStringBuf status,
- TDuration time)
- : Direction(direction)
- , Host(host)
- , Url(url)
- , Status(status)
- , Time(time)
- {}
- };
-};
-
-struct TEndpointInfo {
+ : ConnectionID(connectionID)
+ {}
+ };
+
+ struct TEvResolveHostRequest : NActors::TEventLocal<TEvResolveHostRequest, EvResolveHostRequest> {
+ TString Host;
+
+ TEvResolveHostRequest(const TString& host)
+ : Host(host)
+ {}
+ };
+
+ struct TEvResolveHostResponse : NActors::TEventLocal<TEvResolveHostResponse, EvResolveHostResponse> {
+ TString Host;
+ TSockAddrInet6 Address;
+ TString Error;
+
+ TEvResolveHostResponse(const TString& host, const TSockAddrInet6& address)
+ : Host(host)
+ , Address(address)
+ {}
+
+ TEvResolveHostResponse(const TString& error)
+ : Error(error)
+ {}
+ };
+
+ struct TEvReportSensors : NActors::TEventLocal<TEvReportSensors, EvReportSensors> {
+ TString Direction;
+ TString Host;
+ TString Url;
+ TString Status;
+ TDuration Time;
+
+ TEvReportSensors(
+ TStringBuf direction,
+ TStringBuf host,
+ TStringBuf url,
+ TStringBuf status,
+ TDuration time)
+ : Direction(direction)
+ , Host(host)
+ , Url(url)
+ , Status(status)
+ , Time(time)
+ {}
+ };
+};
+
+struct TEndpointInfo {
TActorId Proxy;
TActorId Owner;
- TString WorkerName;
- bool Secure;
- TSslHelpers::TSslHolder<SSL_CTX> SecureContext;
-};
-
+ TString WorkerName;
+ bool Secure;
+ TSslHelpers::TSslHolder<SSL_CTX> SecureContext;
+};
+
NActors::IActor* CreateHttpProxy(NMonitoring::TMetricRegistry& sensors);
NActors::IActor* CreateHttpAcceptorActor(const TActorId& owner, const TActorId& poller);
NActors::IActor* CreateOutgoingConnectionActor(const TActorId& owner, const TString& host, bool secure, const TActorId& poller);
-NActors::IActor* CreateIncomingConnectionActor(
- const TEndpointInfo& endpoint,
- TIntrusivePtr<TSocketDescriptor> socket,
- THttpConfig::SocketAddressType address,
- THttpIncomingRequestPtr recycledRequest = nullptr);
-TEvHttpProxy::TEvReportSensors* BuildOutgoingRequestSensors(const THttpOutgoingRequestPtr& request, const THttpIncomingResponsePtr& response);
-TEvHttpProxy::TEvReportSensors* BuildIncomingRequestSensors(const THttpIncomingRequestPtr& request, const THttpOutgoingResponsePtr& response);
-
-}
+NActors::IActor* CreateIncomingConnectionActor(
+ const TEndpointInfo& endpoint,
+ TIntrusivePtr<TSocketDescriptor> socket,
+ THttpConfig::SocketAddressType address,
+ THttpIncomingRequestPtr recycledRequest = nullptr);
+TEvHttpProxy::TEvReportSensors* BuildOutgoingRequestSensors(const THttpOutgoingRequestPtr& request, const THttpIncomingResponsePtr& response);
+TEvHttpProxy::TEvReportSensors* BuildIncomingRequestSensors(const THttpIncomingRequestPtr& request, const THttpOutgoingResponsePtr& response);
+
+}
diff --git a/library/cpp/actors/http/http_proxy_acceptor.cpp b/library/cpp/actors/http/http_proxy_acceptor.cpp
index 3d2557c6fec..9780541b71f 100644
--- a/library/cpp/actors/http/http_proxy_acceptor.cpp
+++ b/library/cpp/actors/http/http_proxy_acceptor.cpp
@@ -1,135 +1,135 @@
-#include <util/network/sock.h>
-#include "http_proxy.h"
-#include "http_proxy_ssl.h"
-
-namespace NHttp {
-
-class TAcceptorActor : public NActors::TActor<TAcceptorActor>, public THttpConfig {
-public:
- using TBase = NActors::TActor<TAcceptorActor>;
+#include <util/network/sock.h>
+#include "http_proxy.h"
+#include "http_proxy_ssl.h"
+
+namespace NHttp {
+
+class TAcceptorActor : public NActors::TActor<TAcceptorActor>, public THttpConfig {
+public:
+ using TBase = NActors::TActor<TAcceptorActor>;
const TActorId Owner;
const TActorId Poller;
- TIntrusivePtr<TSocketDescriptor> Socket;
+ TIntrusivePtr<TSocketDescriptor> Socket;
NActors::TPollerToken::TPtr PollerToken;
THashSet<TActorId> Connections;
- TDeque<THttpIncomingRequestPtr> RecycledRequests;
- TEndpointInfo Endpoint;
-
+ TDeque<THttpIncomingRequestPtr> RecycledRequests;
+ TEndpointInfo Endpoint;
+
TAcceptorActor(const TActorId& owner, const TActorId& poller)
- : NActors::TActor<TAcceptorActor>(&TAcceptorActor::StateInit)
- , Owner(owner)
- , Poller(poller)
- , Socket(new TSocketDescriptor())
- {
- // for unit tests :(
- CheckedSetSockOpt(Socket->Socket, SOL_SOCKET, SO_REUSEADDR, (int)true, "reuse address");
-#ifdef SO_REUSEPORT
- CheckedSetSockOpt(Socket->Socket, SOL_SOCKET, SO_REUSEPORT, (int)true, "reuse port");
-#endif
- }
-
-protected:
- STFUNC(StateListening) {
- switch (ev->GetTypeRewrite()) {
+ : NActors::TActor<TAcceptorActor>(&TAcceptorActor::StateInit)
+ , Owner(owner)
+ , Poller(poller)
+ , Socket(new TSocketDescriptor())
+ {
+ // for unit tests :(
+ CheckedSetSockOpt(Socket->Socket, SOL_SOCKET, SO_REUSEADDR, (int)true, "reuse address");
+#ifdef SO_REUSEPORT
+ CheckedSetSockOpt(Socket->Socket, SOL_SOCKET, SO_REUSEPORT, (int)true, "reuse port");
+#endif
+ }
+
+protected:
+ STFUNC(StateListening) {
+ switch (ev->GetTypeRewrite()) {
HFunc(NActors::TEvPollerRegisterResult, Handle);
HFunc(NActors::TEvPollerReady, Handle);
- HFunc(TEvHttpProxy::TEvHttpConnectionClosed, Handle);
- HFunc(TEvHttpProxy::TEvReportSensors, Handle);
- }
- }
-
- STFUNC(StateInit) {
- switch (ev->GetTypeRewrite()) {
- HFunc(TEvHttpProxy::TEvAddListeningPort, HandleInit);
- }
- }
-
- void HandleInit(TEvHttpProxy::TEvAddListeningPort::TPtr event, const NActors::TActorContext& ctx) {
- SocketAddressType bindAddress("::", event->Get()->Port);
- Endpoint.Owner = ctx.SelfID;
- Endpoint.Proxy = Owner;
- Endpoint.WorkerName = event->Get()->WorkerName;
- Endpoint.Secure = event->Get()->Secure;
- int err = 0;
- if (Endpoint.Secure) {
+ HFunc(TEvHttpProxy::TEvHttpConnectionClosed, Handle);
+ HFunc(TEvHttpProxy::TEvReportSensors, Handle);
+ }
+ }
+
+ STFUNC(StateInit) {
+ switch (ev->GetTypeRewrite()) {
+ HFunc(TEvHttpProxy::TEvAddListeningPort, HandleInit);
+ }
+ }
+
+ void HandleInit(TEvHttpProxy::TEvAddListeningPort::TPtr event, const NActors::TActorContext& ctx) {
+ SocketAddressType bindAddress("::", event->Get()->Port);
+ Endpoint.Owner = ctx.SelfID;
+ Endpoint.Proxy = Owner;
+ Endpoint.WorkerName = event->Get()->WorkerName;
+ Endpoint.Secure = event->Get()->Secure;
+ int err = 0;
+ if (Endpoint.Secure) {
if (!event->Get()->SslCertificatePem.empty()) {
Endpoint.SecureContext = TSslHelpers::CreateServerContext(event->Get()->SslCertificatePem);
} else {
Endpoint.SecureContext = TSslHelpers::CreateServerContext(event->Get()->CertificateFile, event->Get()->PrivateKeyFile);
}
- if (Endpoint.SecureContext == nullptr) {
- err = -1;
- LOG_WARN_S(ctx, HttpLog, "Failed to construct server security context");
- }
- }
- if (err == 0) {
- err = Socket->Socket.Bind(&bindAddress);
- }
- if (err == 0) {
- err = Socket->Socket.Listen(LISTEN_QUEUE);
- if (err == 0) {
- LOG_INFO_S(ctx, HttpLog, "Listening on " << bindAddress.ToString());
- SetNonBlock(Socket->Socket);
+ if (Endpoint.SecureContext == nullptr) {
+ err = -1;
+ LOG_WARN_S(ctx, HttpLog, "Failed to construct server security context");
+ }
+ }
+ if (err == 0) {
+ err = Socket->Socket.Bind(&bindAddress);
+ }
+ if (err == 0) {
+ err = Socket->Socket.Listen(LISTEN_QUEUE);
+ if (err == 0) {
+ LOG_INFO_S(ctx, HttpLog, "Listening on " << bindAddress.ToString());
+ SetNonBlock(Socket->Socket);
ctx.Send(Poller, new NActors::TEvPollerRegister(Socket, SelfId(), SelfId()));
- TBase::Become(&TAcceptorActor::StateListening);
- ctx.Send(event->Sender, new TEvHttpProxy::TEvConfirmListen(bindAddress), 0, event->Cookie);
- return;
- }
- }
- LOG_WARN_S(ctx, HttpLog, "Failed to listen on " << bindAddress.ToString() << " - retrying...");
+ TBase::Become(&TAcceptorActor::StateListening);
+ ctx.Send(event->Sender, new TEvHttpProxy::TEvConfirmListen(bindAddress), 0, event->Cookie);
+ return;
+ }
+ }
+ LOG_WARN_S(ctx, HttpLog, "Failed to listen on " << bindAddress.ToString() << " - retrying...");
ctx.ExecutorThread.Schedule(TDuration::Seconds(1), event.Release());
- }
-
- void Die(const NActors::TActorContext& ctx) override {
- ctx.Send(Owner, new TEvHttpProxy::TEvHttpAcceptorClosed(ctx.SelfID));
+ }
+
+ void Die(const NActors::TActorContext& ctx) override {
+ ctx.Send(Owner, new TEvHttpProxy::TEvHttpAcceptorClosed(ctx.SelfID));
for (const NActors::TActorId& connection : Connections) {
- ctx.Send(connection, new NActors::TEvents::TEvPoisonPill());
- }
- }
-
+ ctx.Send(connection, new NActors::TEvents::TEvPoisonPill());
+ }
+ }
+
void Handle(NActors::TEvPollerRegisterResult::TPtr ev, const NActors::TActorContext& /*ctx*/) {
PollerToken = std::move(ev->Get()->PollerToken);
PollerToken->Request(true, false); // request read polling
}
void Handle(NActors::TEvPollerReady::TPtr, const NActors::TActorContext& ctx) {
- TIntrusivePtr<TSocketDescriptor> socket = new TSocketDescriptor();
- SocketAddressType addr;
+ TIntrusivePtr<TSocketDescriptor> socket = new TSocketDescriptor();
+ SocketAddressType addr;
int err;
while ((err = Socket->Socket.Accept(&socket->Socket, &addr)) == 0) {
- NActors::IActor* connectionSocket = nullptr;
- if (RecycledRequests.empty()) {
- connectionSocket = CreateIncomingConnectionActor(Endpoint, socket, addr);
- } else {
- connectionSocket = CreateIncomingConnectionActor(Endpoint, socket, addr, std::move(RecycledRequests.front()));
- RecycledRequests.pop_front();
- }
+ NActors::IActor* connectionSocket = nullptr;
+ if (RecycledRequests.empty()) {
+ connectionSocket = CreateIncomingConnectionActor(Endpoint, socket, addr);
+ } else {
+ connectionSocket = CreateIncomingConnectionActor(Endpoint, socket, addr, std::move(RecycledRequests.front()));
+ RecycledRequests.pop_front();
+ }
NActors::TActorId connectionId = ctx.Register(connectionSocket);
ctx.Send(Poller, new NActors::TEvPollerRegister(socket, connectionId, connectionId));
- Connections.emplace(connectionId);
- socket = new TSocketDescriptor();
- }
+ Connections.emplace(connectionId);
+ socket = new TSocketDescriptor();
+ }
if (err == -EAGAIN || err == -EWOULDBLOCK) { // request poller for further connection polling
Y_VERIFY(PollerToken);
PollerToken->Request(true, false);
}
- }
-
- void Handle(TEvHttpProxy::TEvHttpConnectionClosed::TPtr event, const NActors::TActorContext&) {
- Connections.erase(event->Get()->ConnectionID);
- for (auto& req : event->Get()->RecycledRequests) {
- req->Clear();
- RecycledRequests.push_back(std::move(req));
- }
- }
-
- void Handle(TEvHttpProxy::TEvReportSensors::TPtr event, const NActors::TActorContext& ctx) {
- ctx.Send(event->Forward(Owner));
- }
-};
-
+ }
+
+ void Handle(TEvHttpProxy::TEvHttpConnectionClosed::TPtr event, const NActors::TActorContext&) {
+ Connections.erase(event->Get()->ConnectionID);
+ for (auto& req : event->Get()->RecycledRequests) {
+ req->Clear();
+ RecycledRequests.push_back(std::move(req));
+ }
+ }
+
+ void Handle(TEvHttpProxy::TEvReportSensors::TPtr event, const NActors::TActorContext& ctx) {
+ ctx.Send(event->Forward(Owner));
+ }
+};
+
NActors::IActor* CreateHttpAcceptorActor(const TActorId& owner, const TActorId& poller) {
- return new TAcceptorActor(owner, poller);
-}
-
-}
+ return new TAcceptorActor(owner, poller);
+}
+
+}
diff --git a/library/cpp/actors/http/http_proxy_incoming.cpp b/library/cpp/actors/http/http_proxy_incoming.cpp
index 0608e0e25b5..80fe2af53d0 100644
--- a/library/cpp/actors/http/http_proxy_incoming.cpp
+++ b/library/cpp/actors/http/http_proxy_incoming.cpp
@@ -1,80 +1,80 @@
-#include "http_proxy.h"
-#include "http_proxy_sock_impl.h"
-
-namespace NHttp {
-
+#include "http_proxy.h"
+#include "http_proxy_sock_impl.h"
+
+namespace NHttp {
+
using namespace NActors;
-template <typename TSocketImpl>
-class TIncomingConnectionActor : public TActor<TIncomingConnectionActor<TSocketImpl>>, public TSocketImpl, virtual public THttpConfig {
-public:
- using TBase = TActor<TIncomingConnectionActor<TSocketImpl>>;
- static constexpr bool RecycleRequests = true;
-
- const TEndpointInfo& Endpoint;
- SocketAddressType Address;
- TList<THttpIncomingRequestPtr> Requests;
- THashMap<THttpIncomingRequestPtr, THttpOutgoingResponsePtr> Responses;
- THttpIncomingRequestPtr CurrentRequest;
- THttpOutgoingResponsePtr CurrentResponse;
- TDeque<THttpIncomingRequestPtr> RecycledRequests;
-
+template <typename TSocketImpl>
+class TIncomingConnectionActor : public TActor<TIncomingConnectionActor<TSocketImpl>>, public TSocketImpl, virtual public THttpConfig {
+public:
+ using TBase = TActor<TIncomingConnectionActor<TSocketImpl>>;
+ static constexpr bool RecycleRequests = true;
+
+ const TEndpointInfo& Endpoint;
+ SocketAddressType Address;
+ TList<THttpIncomingRequestPtr> Requests;
+ THashMap<THttpIncomingRequestPtr, THttpOutgoingResponsePtr> Responses;
+ THttpIncomingRequestPtr CurrentRequest;
+ THttpOutgoingResponsePtr CurrentResponse;
+ TDeque<THttpIncomingRequestPtr> RecycledRequests;
+
THPTimer InactivityTimer;
static constexpr TDuration InactivityTimeout = TDuration::Minutes(2);
TEvPollerReady* InactivityEvent = nullptr;
TPollerToken::TPtr PollerToken;
- TIncomingConnectionActor(
- const TEndpointInfo& endpoint,
- TIntrusivePtr<TSocketDescriptor> socket,
- SocketAddressType address,
- THttpIncomingRequestPtr recycledRequest = nullptr)
- : TBase(&TIncomingConnectionActor::StateAccepting)
- , TSocketImpl(std::move(socket))
- , Endpoint(endpoint)
- , Address(address)
- {
- if (recycledRequest != nullptr) {
- RecycledRequests.emplace_back(std::move(recycledRequest));
- }
- TSocketImpl::SetNonBlock();
- }
-
- void CleanupRequest(THttpIncomingRequestPtr& request) {
- if (RecycleRequests) {
- request->Clear();
- RecycledRequests.push_back(std::move(request));
- } else {
- request = nullptr;
- }
- }
-
- void CleanupResponse(THttpOutgoingResponsePtr& response) {
- CleanupRequest(response->Request);
- // TODO: maybe recycle too?
- response = nullptr;
- }
-
+ TIncomingConnectionActor(
+ const TEndpointInfo& endpoint,
+ TIntrusivePtr<TSocketDescriptor> socket,
+ SocketAddressType address,
+ THttpIncomingRequestPtr recycledRequest = nullptr)
+ : TBase(&TIncomingConnectionActor::StateAccepting)
+ , TSocketImpl(std::move(socket))
+ , Endpoint(endpoint)
+ , Address(address)
+ {
+ if (recycledRequest != nullptr) {
+ RecycledRequests.emplace_back(std::move(recycledRequest));
+ }
+ TSocketImpl::SetNonBlock();
+ }
+
+ void CleanupRequest(THttpIncomingRequestPtr& request) {
+ if (RecycleRequests) {
+ request->Clear();
+ RecycledRequests.push_back(std::move(request));
+ } else {
+ request = nullptr;
+ }
+ }
+
+ void CleanupResponse(THttpOutgoingResponsePtr& response) {
+ CleanupRequest(response->Request);
+ // TODO: maybe recycle too?
+ response = nullptr;
+ }
+
TAutoPtr<IEventHandle> AfterRegister(const TActorId& self, const TActorId& parent) override {
return new IEventHandle(self, parent, new TEvents::TEvBootstrap());
}
void Die(const TActorContext& ctx) override {
- ctx.Send(Endpoint.Owner, new TEvHttpProxy::TEvHttpConnectionClosed(ctx.SelfID, std::move(RecycledRequests)));
- TSocketImpl::Shutdown();
- TBase::Die(ctx);
- }
-
-protected:
+ ctx.Send(Endpoint.Owner, new TEvHttpProxy::TEvHttpConnectionClosed(ctx.SelfID, std::move(RecycledRequests)));
+ TSocketImpl::Shutdown();
+ TBase::Die(ctx);
+ }
+
+protected:
void Bootstrap(const TActorContext& ctx) {
InactivityTimer.Reset();
ctx.Schedule(InactivityTimeout, InactivityEvent = new TEvPollerReady(nullptr, false, false));
- LOG_DEBUG_S(ctx, HttpLog, "(#" << TSocketImpl::GetRawSocket() << "," << Address << ") incoming connection opened");
- OnAccept(ctx);
+ LOG_DEBUG_S(ctx, HttpLog, "(#" << TSocketImpl::GetRawSocket() << "," << Address << ") incoming connection opened");
+ OnAccept(ctx);
}
- void OnAccept(const NActors::TActorContext& ctx) {
+ void OnAccept(const NActors::TActorContext& ctx) {
int res;
bool read = false, write = false;
if ((res = TSocketImpl::OnAccept(Endpoint, read, write)) != 1) {
@@ -86,21 +86,21 @@ protected:
} else {
LOG_ERROR_S(ctx, HttpLog, "(#" << TSocketImpl::GetRawSocket() << "," << Address << ") connection closed - error in Accept: " << strerror(-res));
return Die(ctx);
- }
- }
- TBase::Become(&TIncomingConnectionActor::StateConnected);
+ }
+ }
+ TBase::Become(&TIncomingConnectionActor::StateConnected);
ctx.Send(ctx.SelfID, new TEvPollerReady(nullptr, true, true));
- }
-
+ }
+
void HandleAccepting(TEvPollerRegisterResult::TPtr ev, const NActors::TActorContext& ctx) {
PollerToken = std::move(ev->Get()->PollerToken);
- OnAccept(ctx);
- }
-
+ OnAccept(ctx);
+ }
+
void HandleAccepting(NActors::TEvPollerReady::TPtr, const NActors::TActorContext& ctx) {
- OnAccept(ctx);
- }
-
+ OnAccept(ctx);
+ }
+
void HandleConnected(TEvPollerReady::TPtr event, const TActorContext& ctx) {
if (event->Get()->Read) {
for (;;) {
@@ -114,7 +114,7 @@ protected:
CurrentRequest->Address = Address;
CurrentRequest->WorkerName = Endpoint.WorkerName;
CurrentRequest->Secure = Endpoint.Secure;
- }
+ }
if (!CurrentRequest->EnsureEnoughSpaceAvailable()) {
LOG_DEBUG_S(ctx, HttpLog, "(#" << TSocketImpl::GetRawSocket() << "," << Address << ") connection closed - not enough space available");
return Die(ctx);
@@ -134,13 +134,13 @@ protected:
CurrentRequest = nullptr;
} else if (CurrentRequest->IsError()) {
LOG_DEBUG_S(ctx, HttpLog, "(#" << TSocketImpl::GetRawSocket() << "," << Address << ") -! (" << CurrentRequest->Method << " " << CurrentRequest->URL << ")");
- bool success = Respond(CurrentRequest->CreateResponseBadRequest(), ctx);
- if (!success) {
- return;
- }
+ bool success = Respond(CurrentRequest->CreateResponseBadRequest(), ctx);
+ if (!success) {
+ return;
+ }
CurrentRequest = nullptr;
}
- }
+ }
} else if (-res == EAGAIN || -res == EWOULDBLOCK) {
if (PollerToken) {
if (!read && !write) {
@@ -148,18 +148,18 @@ protected:
}
PollerToken->Request(read, write);
}
- break;
+ break;
} else if (-res == EINTR) {
continue;
} else if (!res) {
// connection closed
- LOG_DEBUG_S(ctx, HttpLog, "(#" << TSocketImpl::GetRawSocket() << "," << Address << ") connection closed");
- return Die(ctx);
+ LOG_DEBUG_S(ctx, HttpLog, "(#" << TSocketImpl::GetRawSocket() << "," << Address << ") connection closed");
+ return Die(ctx);
} else {
- LOG_ERROR_S(ctx, HttpLog, "(#" << TSocketImpl::GetRawSocket() << "," << Address << ") connection closed - error in Receive: " << strerror(-res));
- return Die(ctx);
- }
- }
+ LOG_ERROR_S(ctx, HttpLog, "(#" << TSocketImpl::GetRawSocket() << "," << Address << ") connection closed - error in Receive: " << strerror(-res));
+ return Die(ctx);
+ }
+ }
if (event->Get() == InactivityEvent) {
const TDuration passed = TDuration::Seconds(std::abs(InactivityTimer.Passed()));
if (passed >= InactivityTimeout) {
@@ -173,83 +173,83 @@ protected:
if (event->Get()->Write) {
FlushOutput(ctx);
}
- }
-
+ }
+
void HandleConnected(TEvPollerRegisterResult::TPtr ev, const TActorContext& /*ctx*/) {
PollerToken = std::move(ev->Get()->PollerToken);
PollerToken->Request(true, true);
- }
-
- void HandleConnected(TEvHttpProxy::TEvHttpOutgoingResponse::TPtr event, const TActorContext& ctx) {
- Respond(event->Get()->Response, ctx);
- }
-
- bool Respond(THttpOutgoingResponsePtr response, const TActorContext& ctx) {
- THttpIncomingRequestPtr request = response->GetRequest();
- response->Finish();
- LOG_DEBUG_S(ctx, HttpLog, "(#" << TSocketImpl::GetRawSocket() << "," << Address << ") <- (" << response->Status << " " << response->Message << ")");
- if (response->Status != "200" && response->Status != "404") {
- static constexpr size_t MAX_LOGGED_SIZE = 1024;
- LOG_DEBUG_S(ctx, HttpLog,
- "(#"
- << TSocketImpl::GetRawSocket()
- << ","
- << Address
- << ") Request: "
- << request->GetObfuscatedData().substr(0, MAX_LOGGED_SIZE));
- LOG_DEBUG_S(ctx, HttpLog,
- "(#"
- << TSocketImpl::GetRawSocket()
- << ","
- << Address
- << ") Response: "
- << TString(response->GetRawData()).substr(0, MAX_LOGGED_SIZE));
- }
+ }
+
+ void HandleConnected(TEvHttpProxy::TEvHttpOutgoingResponse::TPtr event, const TActorContext& ctx) {
+ Respond(event->Get()->Response, ctx);
+ }
+
+ bool Respond(THttpOutgoingResponsePtr response, const TActorContext& ctx) {
+ THttpIncomingRequestPtr request = response->GetRequest();
+ response->Finish();
+ LOG_DEBUG_S(ctx, HttpLog, "(#" << TSocketImpl::GetRawSocket() << "," << Address << ") <- (" << response->Status << " " << response->Message << ")");
+ if (response->Status != "200" && response->Status != "404") {
+ static constexpr size_t MAX_LOGGED_SIZE = 1024;
+ LOG_DEBUG_S(ctx, HttpLog,
+ "(#"
+ << TSocketImpl::GetRawSocket()
+ << ","
+ << Address
+ << ") Request: "
+ << request->GetObfuscatedData().substr(0, MAX_LOGGED_SIZE));
+ LOG_DEBUG_S(ctx, HttpLog,
+ "(#"
+ << TSocketImpl::GetRawSocket()
+ << ","
+ << Address
+ << ") Response: "
+ << TString(response->GetRawData()).substr(0, MAX_LOGGED_SIZE));
+ }
THolder<TEvHttpProxy::TEvReportSensors> sensors(BuildIncomingRequestSensors(request, response));
- ctx.Send(Endpoint.Owner, sensors.Release());
- if (request == Requests.front() && CurrentResponse == nullptr) {
- CurrentResponse = response;
- return FlushOutput(ctx);
- } else {
- // we are ahead of our pipeline
- Responses.emplace(request, response);
- return true;
- }
- }
-
- bool FlushOutput(const TActorContext& ctx) {
- while (CurrentResponse != nullptr) {
- size_t size = CurrentResponse->Size();
- if (size == 0) {
- Y_VERIFY(Requests.front() == CurrentResponse->GetRequest());
- bool close = CurrentResponse->IsConnectionClose();
- Requests.pop_front();
- CleanupResponse(CurrentResponse);
- if (!Requests.empty()) {
- auto it = Responses.find(Requests.front());
- if (it != Responses.end()) {
- CurrentResponse = it->second;
- Responses.erase(it);
- continue;
- } else {
- LOG_ERROR_S(ctx, HttpLog, "(#" << TSocketImpl::GetRawSocket() << "," << Address << ") connection closed - FlushOutput request not found");
- Die(ctx);
- return false;
- }
- } else {
- if (close) {
- LOG_DEBUG_S(ctx, HttpLog, "(#" << TSocketImpl::GetRawSocket() << "," << Address << ") connection closed");
- Die(ctx);
- return false;
- } else {
- continue;
- }
- }
- }
+ ctx.Send(Endpoint.Owner, sensors.Release());
+ if (request == Requests.front() && CurrentResponse == nullptr) {
+ CurrentResponse = response;
+ return FlushOutput(ctx);
+ } else {
+ // we are ahead of our pipeline
+ Responses.emplace(request, response);
+ return true;
+ }
+ }
+
+ bool FlushOutput(const TActorContext& ctx) {
+ while (CurrentResponse != nullptr) {
+ size_t size = CurrentResponse->Size();
+ if (size == 0) {
+ Y_VERIFY(Requests.front() == CurrentResponse->GetRequest());
+ bool close = CurrentResponse->IsConnectionClose();
+ Requests.pop_front();
+ CleanupResponse(CurrentResponse);
+ if (!Requests.empty()) {
+ auto it = Responses.find(Requests.front());
+ if (it != Responses.end()) {
+ CurrentResponse = it->second;
+ Responses.erase(it);
+ continue;
+ } else {
+ LOG_ERROR_S(ctx, HttpLog, "(#" << TSocketImpl::GetRawSocket() << "," << Address << ") connection closed - FlushOutput request not found");
+ Die(ctx);
+ return false;
+ }
+ } else {
+ if (close) {
+ LOG_DEBUG_S(ctx, HttpLog, "(#" << TSocketImpl::GetRawSocket() << "," << Address << ") connection closed");
+ Die(ctx);
+ return false;
+ } else {
+ continue;
+ }
+ }
+ }
bool read = false, write = false;
ssize_t res = TSocketImpl::Send(CurrentResponse->Data(), size, read, write);
- if (res > 0) {
- CurrentResponse->ChopHead(res);
+ if (res > 0) {
+ CurrentResponse->ChopHead(res);
} else if (-res == EINTR) {
continue;
} else if (-res == EAGAIN || -res == EWOULDBLOCK) {
@@ -258,45 +258,45 @@ protected:
write = true;
}
PollerToken->Request(read, write);
- }
- break;
+ }
+ break;
} else {
CleanupResponse(CurrentResponse);
LOG_ERROR_S(ctx, HttpLog, "(#" << TSocketImpl::GetRawSocket() << "," << Address << ") connection closed - error in FlushOutput: " << strerror(-res));
- Die(ctx);
- return false;
- }
- }
- return true;
- }
-
- STFUNC(StateAccepting) {
- switch (ev->GetTypeRewrite()) {
+ Die(ctx);
+ return false;
+ }
+ }
+ return true;
+ }
+
+ STFUNC(StateAccepting) {
+ switch (ev->GetTypeRewrite()) {
CFunc(TEvents::TEvBootstrap::EventType, Bootstrap);
HFunc(TEvPollerReady, HandleAccepting);
HFunc(TEvPollerRegisterResult, HandleAccepting);
- }
- }
-
- STFUNC(StateConnected) {
- switch (ev->GetTypeRewrite()) {
+ }
+ }
+
+ STFUNC(StateConnected) {
+ switch (ev->GetTypeRewrite()) {
HFunc(TEvPollerReady, HandleConnected);
- HFunc(TEvHttpProxy::TEvHttpOutgoingResponse, HandleConnected);
+ HFunc(TEvHttpProxy::TEvHttpOutgoingResponse, HandleConnected);
HFunc(TEvPollerRegisterResult, HandleConnected);
- }
- }
-};
-
-IActor* CreateIncomingConnectionActor(
- const TEndpointInfo& endpoint,
- TIntrusivePtr<TSocketDescriptor> socket,
- THttpConfig::SocketAddressType address,
- THttpIncomingRequestPtr recycledRequest) {
- if (endpoint.Secure) {
- return new TIncomingConnectionActor<TSecureSocketImpl>(endpoint, std::move(socket), address, std::move(recycledRequest));
- } else {
- return new TIncomingConnectionActor<TPlainSocketImpl>(endpoint, std::move(socket), address, std::move(recycledRequest));
- }
-}
-
-}
+ }
+ }
+};
+
+IActor* CreateIncomingConnectionActor(
+ const TEndpointInfo& endpoint,
+ TIntrusivePtr<TSocketDescriptor> socket,
+ THttpConfig::SocketAddressType address,
+ THttpIncomingRequestPtr recycledRequest) {
+ if (endpoint.Secure) {
+ return new TIncomingConnectionActor<TSecureSocketImpl>(endpoint, std::move(socket), address, std::move(recycledRequest));
+ } else {
+ return new TIncomingConnectionActor<TPlainSocketImpl>(endpoint, std::move(socket), address, std::move(recycledRequest));
+ }
+}
+
+}
diff --git a/library/cpp/actors/http/http_proxy_outgoing.cpp b/library/cpp/actors/http/http_proxy_outgoing.cpp
index 5b3d07c6149..d9189dba8ab 100644
--- a/library/cpp/actors/http/http_proxy_outgoing.cpp
+++ b/library/cpp/actors/http/http_proxy_outgoing.cpp
@@ -1,92 +1,92 @@
-#include "http_proxy.h"
-#include "http_proxy_sock_impl.h"
-
-namespace NHttp {
-
-template <typename TSocketImpl>
-class TOutgoingConnectionActor : public NActors::TActor<TOutgoingConnectionActor<TSocketImpl>>, public TSocketImpl, virtual public THttpConfig {
-public:
- using TBase = NActors::TActor<TOutgoingConnectionActor<TSocketImpl>>;
- using TSelf = TOutgoingConnectionActor<TSocketImpl>;
+#include "http_proxy.h"
+#include "http_proxy_sock_impl.h"
+
+namespace NHttp {
+
+template <typename TSocketImpl>
+class TOutgoingConnectionActor : public NActors::TActor<TOutgoingConnectionActor<TSocketImpl>>, public TSocketImpl, virtual public THttpConfig {
+public:
+ using TBase = NActors::TActor<TOutgoingConnectionActor<TSocketImpl>>;
+ using TSelf = TOutgoingConnectionActor<TSocketImpl>;
const TActorId Owner;
const TActorId Poller;
- SocketAddressType Address;
- TString Host;
+ SocketAddressType Address;
+ TString Host;
TActorId RequestOwner;
- THttpOutgoingRequestPtr Request;
- THttpIncomingResponsePtr Response;
- TInstant LastActivity;
- TDuration ConnectionTimeout = CONNECTION_TIMEOUT;
+ THttpOutgoingRequestPtr Request;
+ THttpIncomingResponsePtr Response;
+ TInstant LastActivity;
+ TDuration ConnectionTimeout = CONNECTION_TIMEOUT;
NActors::TPollerToken::TPtr PollerToken;
-
+
TOutgoingConnectionActor(const TActorId& owner, const TString& host, const TActorId& poller)
- : TBase(&TSelf::StateWaiting)
- , Owner(owner)
- , Poller(poller)
- , Host(host)
- {
- TSocketImpl::SetNonBlock();
- TSocketImpl::SetTimeout(SOCKET_TIMEOUT);
- }
-
+ : TBase(&TSelf::StateWaiting)
+ , Owner(owner)
+ , Poller(poller)
+ , Host(host)
+ {
+ TSocketImpl::SetNonBlock();
+ TSocketImpl::SetTimeout(SOCKET_TIMEOUT);
+ }
+
void Die(const NActors::TActorContext& ctx) override {
- ctx.Send(Owner, new TEvHttpProxy::TEvHttpConnectionClosed(ctx.SelfID));
- TSocketImpl::Shutdown(); // to avoid errors when connection already closed
- TBase::Die(ctx);
- }
-
- void ReplyAndDie(const NActors::TActorContext& ctx) {
- LOG_DEBUG_S(ctx, HttpLog, "(#" << TSocketImpl::GetRawSocket() << "," << Address << ") -> (" << Response->Status << " " << Response->Message << ")");
- ctx.Send(RequestOwner, new TEvHttpProxy::TEvHttpIncomingResponse(Request, Response));
+ ctx.Send(Owner, new TEvHttpProxy::TEvHttpConnectionClosed(ctx.SelfID));
+ TSocketImpl::Shutdown(); // to avoid errors when connection already closed
+ TBase::Die(ctx);
+ }
+
+ void ReplyAndDie(const NActors::TActorContext& ctx) {
+ LOG_DEBUG_S(ctx, HttpLog, "(#" << TSocketImpl::GetRawSocket() << "," << Address << ") -> (" << Response->Status << " " << Response->Message << ")");
+ ctx.Send(RequestOwner, new TEvHttpProxy::TEvHttpIncomingResponse(Request, Response));
RequestOwner = TActorId();
THolder<TEvHttpProxy::TEvReportSensors> sensors(BuildOutgoingRequestSensors(Request, Response));
- ctx.Send(Owner, sensors.Release());
- LOG_DEBUG_S(ctx, HttpLog, "(#" << TSocketImpl::GetRawSocket() << "," << Address << ") connection closed");
- Die(ctx);
- }
-
- void ReplyErrorAndDie(const NActors::TActorContext& ctx, const TString& error) {
- LOG_ERROR_S(ctx, HttpLog, "(#" << TSocketImpl::GetRawSocket() << "," << Address << ") connection closed with error: " << error);
- if (RequestOwner) {
- ctx.Send(RequestOwner, new TEvHttpProxy::TEvHttpIncomingResponse(Request, Response, error));
+ ctx.Send(Owner, sensors.Release());
+ LOG_DEBUG_S(ctx, HttpLog, "(#" << TSocketImpl::GetRawSocket() << "," << Address << ") connection closed");
+ Die(ctx);
+ }
+
+ void ReplyErrorAndDie(const NActors::TActorContext& ctx, const TString& error) {
+ LOG_ERROR_S(ctx, HttpLog, "(#" << TSocketImpl::GetRawSocket() << "," << Address << ") connection closed with error: " << error);
+ if (RequestOwner) {
+ ctx.Send(RequestOwner, new TEvHttpProxy::TEvHttpIncomingResponse(Request, Response, error));
RequestOwner = TActorId();
THolder<TEvHttpProxy::TEvReportSensors> sensors(BuildOutgoingRequestSensors(Request, Response));
- ctx.Send(Owner, sensors.Release());
- Die(ctx);
- }
- }
-
-protected:
- void FailConnection(const NActors::TActorContext& ctx, const TString& error) {
- if (Request) {
- return ReplyErrorAndDie(ctx, error);
- }
- return TBase::Become(&TOutgoingConnectionActor::StateFailed);
- }
-
- void Connect(const NActors::TActorContext& ctx) {
- LOG_DEBUG_S(ctx, HttpLog, "(#" << TSocketImpl::GetRawSocket() << "," << Address << ") connecting");
- int res = TSocketImpl::Connect(Address);
- RegisterPoller(ctx);
- switch (-res) {
- case 0:
- return OnConnect(ctx);
- case EINPROGRESS:
- case EAGAIN:
- return TBase::Become(&TOutgoingConnectionActor::StateConnecting);
- default:
- return ReplyErrorAndDie(ctx, strerror(-res));
- }
- }
-
- void FlushOutput(const NActors::TActorContext& ctx) {
- if (Request != nullptr) {
- Request->Finish();
+ ctx.Send(Owner, sensors.Release());
+ Die(ctx);
+ }
+ }
+
+protected:
+ void FailConnection(const NActors::TActorContext& ctx, const TString& error) {
+ if (Request) {
+ return ReplyErrorAndDie(ctx, error);
+ }
+ return TBase::Become(&TOutgoingConnectionActor::StateFailed);
+ }
+
+ void Connect(const NActors::TActorContext& ctx) {
+ LOG_DEBUG_S(ctx, HttpLog, "(#" << TSocketImpl::GetRawSocket() << "," << Address << ") connecting");
+ int res = TSocketImpl::Connect(Address);
+ RegisterPoller(ctx);
+ switch (-res) {
+ case 0:
+ return OnConnect(ctx);
+ case EINPROGRESS:
+ case EAGAIN:
+ return TBase::Become(&TOutgoingConnectionActor::StateConnecting);
+ default:
+ return ReplyErrorAndDie(ctx, strerror(-res));
+ }
+ }
+
+ void FlushOutput(const NActors::TActorContext& ctx) {
+ if (Request != nullptr) {
+ Request->Finish();
while (auto size = Request->Size()) {
bool read = false, write = false;
ssize_t res = TSocketImpl::Send(Request->Data(), size, read, write);
- if (res > 0) {
- Request->ChopHead(res);
+ if (res > 0) {
+ Request->ChopHead(res);
} else if (-res == EINTR) {
continue;
} else if (-res == EAGAIN || -res == EWOULDBLOCK) {
@@ -97,30 +97,30 @@ protected:
PollerToken->Request(read, write);
}
break;
- } else {
+ } else {
if (!res) {
- ReplyAndDie(ctx);
+ ReplyAndDie(ctx);
} else {
- ReplyErrorAndDie(ctx, strerror(-res));
- }
+ ReplyErrorAndDie(ctx, strerror(-res));
+ }
break;
- }
- }
- }
- }
-
- void PullInput(const NActors::TActorContext& ctx) {
+ }
+ }
+ }
+ }
+
+ void PullInput(const NActors::TActorContext& ctx) {
for (;;) {
- if (Response == nullptr) {
- Response = new THttpIncomingResponse(Request);
- }
- if (!Response->EnsureEnoughSpaceAvailable()) {
- return ReplyErrorAndDie(ctx, "Not enough space in socket buffer");
- }
+ if (Response == nullptr) {
+ Response = new THttpIncomingResponse(Request);
+ }
+ if (!Response->EnsureEnoughSpaceAvailable()) {
+ return ReplyErrorAndDie(ctx, "Not enough space in socket buffer");
+ }
bool read = false, write = false;
ssize_t res = TSocketImpl::Recv(Response->Pos(), Response->Avail(), read, write);
- if (res > 0) {
- Response->Advance(res);
+ if (res > 0) {
+ Response->Advance(res);
if (Response->IsDone() && Response->IsReady()) {
return ReplyAndDie(ctx);
}
@@ -130,169 +130,169 @@ protected:
if (PollerToken) {
if (!read && !write) {
read = true;
- }
+ }
PollerToken->Request(read, write);
- }
+ }
return;
- } else {
+ } else {
if (!res) {
- Response->ConnectionClosed();
- }
+ Response->ConnectionClosed();
+ }
if (Response->IsDone() && Response->IsReady()) {
return ReplyAndDie(ctx);
}
return ReplyErrorAndDie(ctx, strerror(-res));
- }
+ }
}
- }
-
- void RegisterPoller(const NActors::TActorContext& ctx) {
+ }
+
+ void RegisterPoller(const NActors::TActorContext& ctx) {
ctx.Send(Poller, new NActors::TEvPollerRegister(TSocketImpl::Socket, ctx.SelfID, ctx.SelfID));
- }
-
- void OnConnect(const NActors::TActorContext& ctx) {
+ }
+
+ void OnConnect(const NActors::TActorContext& ctx) {
bool read = false, write = false;
if (int res = TSocketImpl::OnConnect(read, write); res != 1) {
if (-res == EAGAIN) {
if (PollerToken) {
PollerToken->Request(read, write);
}
- return;
+ return;
} else {
return ReplyErrorAndDie(ctx, strerror(-res));
- }
- }
- LOG_DEBUG_S(ctx, HttpLog, "(#" << TSocketImpl::GetRawSocket() << "," << Address << ") outgoing connection opened");
- TBase::Become(&TOutgoingConnectionActor::StateConnected);
- LOG_DEBUG_S(ctx, HttpLog, "(#" << TSocketImpl::GetRawSocket() << "," << Address << ") <- (" << Request->Method << " " << Request->URL << ")");
+ }
+ }
+ LOG_DEBUG_S(ctx, HttpLog, "(#" << TSocketImpl::GetRawSocket() << "," << Address << ") outgoing connection opened");
+ TBase::Become(&TOutgoingConnectionActor::StateConnected);
+ LOG_DEBUG_S(ctx, HttpLog, "(#" << TSocketImpl::GetRawSocket() << "," << Address << ") <- (" << Request->Method << " " << Request->URL << ")");
ctx.Send(ctx.SelfID, new NActors::TEvPollerReady(nullptr, true, true));
- }
-
- void HandleResolving(TEvHttpProxy::TEvResolveHostResponse::TPtr event, const NActors::TActorContext& ctx) {
- LastActivity = ctx.Now();
- if (!event->Get()->Error.empty()) {
- return FailConnection(ctx, event->Get()->Error);
- }
- Address = event->Get()->Address;
- if (Address.GetPort() == 0) {
- Address.SetPort(Request->Secure ? 443 : 80);
- }
- Connect(ctx);
- }
-
+ }
+
+ void HandleResolving(TEvHttpProxy::TEvResolveHostResponse::TPtr event, const NActors::TActorContext& ctx) {
+ LastActivity = ctx.Now();
+ if (!event->Get()->Error.empty()) {
+ return FailConnection(ctx, event->Get()->Error);
+ }
+ Address = event->Get()->Address;
+ if (Address.GetPort() == 0) {
+ Address.SetPort(Request->Secure ? 443 : 80);
+ }
+ Connect(ctx);
+ }
+
void HandleConnecting(NActors::TEvPollerReady::TPtr, const NActors::TActorContext& ctx) {
- LastActivity = ctx.Now();
- int res = TSocketImpl::GetError();
- if (res == 0) {
- OnConnect(ctx);
- } else {
- FailConnection(ctx, TStringBuilder() << strerror(res));
- }
- }
-
+ LastActivity = ctx.Now();
+ int res = TSocketImpl::GetError();
+ if (res == 0) {
+ OnConnect(ctx);
+ } else {
+ FailConnection(ctx, TStringBuilder() << strerror(res));
+ }
+ }
+
void HandleConnecting(NActors::TEvPollerRegisterResult::TPtr ev, const NActors::TActorContext& ctx) {
PollerToken = std::move(ev->Get()->PollerToken);
- LastActivity = ctx.Now();
- int res = TSocketImpl::GetError();
- if (res == 0) {
- OnConnect(ctx);
- } else {
- FailConnection(ctx, TStringBuilder() << strerror(res));
- }
- }
-
- void HandleWaiting(TEvHttpProxy::TEvHttpOutgoingRequest::TPtr event, const NActors::TActorContext& ctx) {
- LastActivity = ctx.Now();
- Request = std::move(event->Get()->Request);
- Host = Request->Host;
- LOG_DEBUG_S(ctx, HttpLog, "(#" << TSocketImpl::GetRawSocket() << ") resolving " << Host);
- Request->Timer.Reset();
- RequestOwner = event->Sender;
- ctx.Send(Owner, new TEvHttpProxy::TEvResolveHostRequest(Host));
- if (event->Get()->Timeout) {
- ConnectionTimeout = event->Get()->Timeout;
- TSocketImpl::SetTimeout(ConnectionTimeout);
- }
- ctx.Schedule(ConnectionTimeout, new NActors::TEvents::TEvWakeup());
- LastActivity = ctx.Now();
- TBase::Become(&TOutgoingConnectionActor::StateResolving);
- }
-
+ LastActivity = ctx.Now();
+ int res = TSocketImpl::GetError();
+ if (res == 0) {
+ OnConnect(ctx);
+ } else {
+ FailConnection(ctx, TStringBuilder() << strerror(res));
+ }
+ }
+
+ void HandleWaiting(TEvHttpProxy::TEvHttpOutgoingRequest::TPtr event, const NActors::TActorContext& ctx) {
+ LastActivity = ctx.Now();
+ Request = std::move(event->Get()->Request);
+ Host = Request->Host;
+ LOG_DEBUG_S(ctx, HttpLog, "(#" << TSocketImpl::GetRawSocket() << ") resolving " << Host);
+ Request->Timer.Reset();
+ RequestOwner = event->Sender;
+ ctx.Send(Owner, new TEvHttpProxy::TEvResolveHostRequest(Host));
+ if (event->Get()->Timeout) {
+ ConnectionTimeout = event->Get()->Timeout;
+ TSocketImpl::SetTimeout(ConnectionTimeout);
+ }
+ ctx.Schedule(ConnectionTimeout, new NActors::TEvents::TEvWakeup());
+ LastActivity = ctx.Now();
+ TBase::Become(&TOutgoingConnectionActor::StateResolving);
+ }
+
void HandleConnected(NActors::TEvPollerReady::TPtr event, const NActors::TActorContext& ctx) {
- LastActivity = ctx.Now();
+ LastActivity = ctx.Now();
if (event->Get()->Read) {
PullInput(ctx);
- }
+ }
if (event->Get()->Write) {
FlushOutput(ctx);
}
- }
-
+ }
+
void HandleConnected(NActors::TEvPollerRegisterResult::TPtr ev, const NActors::TActorContext& ctx) {
PollerToken = std::move(ev->Get()->PollerToken);
- LastActivity = ctx.Now();
+ LastActivity = ctx.Now();
PullInput(ctx);
- FlushOutput(ctx);
- }
-
- void HandleFailed(TEvHttpProxy::TEvHttpOutgoingRequest::TPtr event, const NActors::TActorContext& ctx) {
- Request = std::move(event->Get()->Request);
- RequestOwner = event->Sender;
- ReplyErrorAndDie(ctx, "Failed");
- }
-
- void HandleTimeout(const NActors::TActorContext& ctx) {
- TDuration inactivityTime = ctx.Now() - LastActivity;
- if (inactivityTime >= ConnectionTimeout) {
- FailConnection(ctx, "Connection timed out");
- } else {
- ctx.Schedule(Min(ConnectionTimeout - inactivityTime, TDuration::MilliSeconds(100)), new NActors::TEvents::TEvWakeup());
- }
- }
-
- STFUNC(StateWaiting) {
- switch (ev->GetTypeRewrite()) {
- HFunc(TEvHttpProxy::TEvHttpOutgoingRequest, HandleWaiting);
- CFunc(NActors::TEvents::TEvWakeup::EventType, HandleTimeout);
- }
- }
-
- STFUNC(StateResolving) {
- switch (ev->GetTypeRewrite()) {
- HFunc(TEvHttpProxy::TEvResolveHostResponse, HandleResolving);
- CFunc(NActors::TEvents::TEvWakeup::EventType, HandleTimeout);
- }
- }
-
- STFUNC(StateConnecting) {
- switch (ev->GetTypeRewrite()) {
+ FlushOutput(ctx);
+ }
+
+ void HandleFailed(TEvHttpProxy::TEvHttpOutgoingRequest::TPtr event, const NActors::TActorContext& ctx) {
+ Request = std::move(event->Get()->Request);
+ RequestOwner = event->Sender;
+ ReplyErrorAndDie(ctx, "Failed");
+ }
+
+ void HandleTimeout(const NActors::TActorContext& ctx) {
+ TDuration inactivityTime = ctx.Now() - LastActivity;
+ if (inactivityTime >= ConnectionTimeout) {
+ FailConnection(ctx, "Connection timed out");
+ } else {
+ ctx.Schedule(Min(ConnectionTimeout - inactivityTime, TDuration::MilliSeconds(100)), new NActors::TEvents::TEvWakeup());
+ }
+ }
+
+ STFUNC(StateWaiting) {
+ switch (ev->GetTypeRewrite()) {
+ HFunc(TEvHttpProxy::TEvHttpOutgoingRequest, HandleWaiting);
+ CFunc(NActors::TEvents::TEvWakeup::EventType, HandleTimeout);
+ }
+ }
+
+ STFUNC(StateResolving) {
+ switch (ev->GetTypeRewrite()) {
+ HFunc(TEvHttpProxy::TEvResolveHostResponse, HandleResolving);
+ CFunc(NActors::TEvents::TEvWakeup::EventType, HandleTimeout);
+ }
+ }
+
+ STFUNC(StateConnecting) {
+ switch (ev->GetTypeRewrite()) {
HFunc(NActors::TEvPollerReady, HandleConnecting);
- CFunc(NActors::TEvents::TEvWakeup::EventType, HandleTimeout);
+ CFunc(NActors::TEvents::TEvWakeup::EventType, HandleTimeout);
HFunc(NActors::TEvPollerRegisterResult, HandleConnecting);
- }
- }
-
- STFUNC(StateConnected) {
- switch (ev->GetTypeRewrite()) {
+ }
+ }
+
+ STFUNC(StateConnected) {
+ switch (ev->GetTypeRewrite()) {
HFunc(NActors::TEvPollerReady, HandleConnected);
- CFunc(NActors::TEvents::TEvWakeup::EventType, HandleTimeout);
+ CFunc(NActors::TEvents::TEvWakeup::EventType, HandleTimeout);
HFunc(NActors::TEvPollerRegisterResult, HandleConnected);
- }
- }
-
- STFUNC(StateFailed) {
- switch (ev->GetTypeRewrite()) {
- HFunc(TEvHttpProxy::TEvHttpOutgoingRequest, HandleFailed);
- }
- }
-};
-
+ }
+ }
+
+ STFUNC(StateFailed) {
+ switch (ev->GetTypeRewrite()) {
+ HFunc(TEvHttpProxy::TEvHttpOutgoingRequest, HandleFailed);
+ }
+ }
+};
+
NActors::IActor* CreateOutgoingConnectionActor(const TActorId& owner, const TString& host, bool secure, const TActorId& poller) {
- if (secure) {
- return new TOutgoingConnectionActor<TSecureSocketImpl>(owner, host, poller);
- } else {
- return new TOutgoingConnectionActor<TPlainSocketImpl>(owner, host, poller);
- }
-}
-
-}
+ if (secure) {
+ return new TOutgoingConnectionActor<TSecureSocketImpl>(owner, host, poller);
+ } else {
+ return new TOutgoingConnectionActor<TPlainSocketImpl>(owner, host, poller);
+ }
+}
+
+}
diff --git a/library/cpp/actors/http/http_proxy_sock_impl.h b/library/cpp/actors/http/http_proxy_sock_impl.h
index e7812cc5e18..bf8c71d05ad 100644
--- a/library/cpp/actors/http/http_proxy_sock_impl.h
+++ b/library/cpp/actors/http/http_proxy_sock_impl.h
@@ -1,262 +1,262 @@
-#pragma once
-
-#include "http.h"
-#include "http_proxy.h"
-
-namespace NHttp {
-
-struct TPlainSocketImpl : virtual public THttpConfig {
- TIntrusivePtr<TSocketDescriptor> Socket;
-
- TPlainSocketImpl()
- : Socket(new TSocketDescriptor())
- {}
-
- TPlainSocketImpl(TIntrusivePtr<TSocketDescriptor> socket)
- : Socket(std::move(socket))
- {}
-
- SOCKET GetRawSocket() const {
- return static_cast<SOCKET>(Socket->Socket);
- }
-
- void SetNonBlock(bool nonBlock = true) noexcept {
- try {
- ::SetNonBlock(Socket->Socket, nonBlock);
- }
- catch (const yexception&) {
- }
- }
-
- void SetTimeout(TDuration timeout) noexcept {
- try {
- ::SetSocketTimeout(Socket->Socket, timeout.Seconds(), timeout.MilliSecondsOfSecond());
- }
- catch (const yexception&) {
- }
- }
-
- void Shutdown() {
- //Socket->Socket.ShutDown(SHUT_RDWR); // KIKIMR-3895
- ::shutdown(Socket->Socket, SHUT_RDWR);
- }
-
- int Connect(const SocketAddressType& address) {
- return Socket->Socket.Connect(&address);
- }
-
+#pragma once
+
+#include "http.h"
+#include "http_proxy.h"
+
+namespace NHttp {
+
+struct TPlainSocketImpl : virtual public THttpConfig {
+ TIntrusivePtr<TSocketDescriptor> Socket;
+
+ TPlainSocketImpl()
+ : Socket(new TSocketDescriptor())
+ {}
+
+ TPlainSocketImpl(TIntrusivePtr<TSocketDescriptor> socket)
+ : Socket(std::move(socket))
+ {}
+
+ SOCKET GetRawSocket() const {
+ return static_cast<SOCKET>(Socket->Socket);
+ }
+
+ void SetNonBlock(bool nonBlock = true) noexcept {
+ try {
+ ::SetNonBlock(Socket->Socket, nonBlock);
+ }
+ catch (const yexception&) {
+ }
+ }
+
+ void SetTimeout(TDuration timeout) noexcept {
+ try {
+ ::SetSocketTimeout(Socket->Socket, timeout.Seconds(), timeout.MilliSecondsOfSecond());
+ }
+ catch (const yexception&) {
+ }
+ }
+
+ void Shutdown() {
+ //Socket->Socket.ShutDown(SHUT_RDWR); // KIKIMR-3895
+ ::shutdown(Socket->Socket, SHUT_RDWR);
+ }
+
+ int Connect(const SocketAddressType& address) {
+ return Socket->Socket.Connect(&address);
+ }
+
static constexpr int OnConnect(bool&, bool&) {
return 1;
- }
-
+ }
+
static constexpr int OnAccept(const TEndpointInfo&, bool&, bool&) {
return 1;
- }
-
- bool IsGood() {
- int res;
- GetSockOpt(Socket->Socket, SOL_SOCKET, SO_ERROR, res);
- return res == 0;
- }
-
- int GetError() {
- int res;
- GetSockOpt(Socket->Socket, SOL_SOCKET, SO_ERROR, res);
- return res;
- }
-
+ }
+
+ bool IsGood() {
+ int res;
+ GetSockOpt(Socket->Socket, SOL_SOCKET, SO_ERROR, res);
+ return res == 0;
+ }
+
+ int GetError() {
+ int res;
+ GetSockOpt(Socket->Socket, SOL_SOCKET, SO_ERROR, res);
+ return res;
+ }
+
ssize_t Send(const void* data, size_t size, bool&, bool&) {
- return Socket->Socket.Send(data, size);
- }
-
+ return Socket->Socket.Send(data, size);
+ }
+
ssize_t Recv(void* data, size_t size, bool&, bool&) {
- return Socket->Socket.Recv(data, size);
- }
-};
-
-struct TSecureSocketImpl : TPlainSocketImpl, TSslHelpers {
- static TSecureSocketImpl* IO(BIO* bio) noexcept {
- return static_cast<TSecureSocketImpl*>(BIO_get_data(bio));
- }
-
- static int IoWrite(BIO* bio, const char* data, int dlen) noexcept {
- BIO_clear_retry_flags(bio);
- int res = IO(bio)->Socket->Socket.Send(data, dlen);
- if (-res == EAGAIN) {
- BIO_set_retry_write(bio);
- }
- return res;
- }
-
- static int IoRead(BIO* bio, char* data, int dlen) noexcept {
- BIO_clear_retry_flags(bio);
- int res = IO(bio)->Socket->Socket.Recv(data, dlen);
- if (-res == EAGAIN) {
- BIO_set_retry_read(bio);
- }
- return res;
- }
-
- static int IoPuts(BIO* bio, const char* buf) noexcept {
- Y_UNUSED(bio);
- Y_UNUSED(buf);
- return -2;
- }
-
- static int IoGets(BIO* bio, char* buf, int size) noexcept {
- Y_UNUSED(bio);
- Y_UNUSED(buf);
- Y_UNUSED(size);
- return -2;
- }
-
- static long IoCtrl(BIO* bio, int cmd, long larg, void* parg) noexcept {
- Y_UNUSED(larg);
- Y_UNUSED(parg);
-
- if (cmd == BIO_CTRL_FLUSH) {
- IO(bio)->Flush();
- return 1;
- }
-
- return -2;
- }
-
- static int IoCreate(BIO* bio) noexcept {
- BIO_set_data(bio, nullptr);
- BIO_set_init(bio, 1);
- return 1;
- }
-
- static int IoDestroy(BIO* bio) noexcept {
- BIO_set_data(bio, nullptr);
- BIO_set_init(bio, 0);
- return 1;
- }
-
- static BIO_METHOD* CreateIoMethod() {
- BIO_METHOD* method = BIO_meth_new(BIO_get_new_index() | BIO_TYPE_SOURCE_SINK, "SecureSocketImpl");
- BIO_meth_set_write(method, IoWrite);
- BIO_meth_set_read(method, IoRead);
- BIO_meth_set_puts(method, IoPuts);
- BIO_meth_set_gets(method, IoGets);
- BIO_meth_set_ctrl(method, IoCtrl);
- BIO_meth_set_create(method, IoCreate);
- BIO_meth_set_destroy(method, IoDestroy);
- return method;
- }
-
- static BIO_METHOD* IoMethod() {
- static BIO_METHOD* method = CreateIoMethod();
- return method;
- }
-
- TSslHolder<BIO> Bio;
- TSslHolder<SSL_CTX> Ctx;
- TSslHolder<SSL> Ssl;
-
- TSecureSocketImpl() = default;
-
- TSecureSocketImpl(TIntrusivePtr<TSocketDescriptor> socket)
- : TPlainSocketImpl(std::move(socket))
- {}
-
- void InitClientSsl() {
+ return Socket->Socket.Recv(data, size);
+ }
+};
+
+struct TSecureSocketImpl : TPlainSocketImpl, TSslHelpers {
+ static TSecureSocketImpl* IO(BIO* bio) noexcept {
+ return static_cast<TSecureSocketImpl*>(BIO_get_data(bio));
+ }
+
+ static int IoWrite(BIO* bio, const char* data, int dlen) noexcept {
+ BIO_clear_retry_flags(bio);
+ int res = IO(bio)->Socket->Socket.Send(data, dlen);
+ if (-res == EAGAIN) {
+ BIO_set_retry_write(bio);
+ }
+ return res;
+ }
+
+ static int IoRead(BIO* bio, char* data, int dlen) noexcept {
+ BIO_clear_retry_flags(bio);
+ int res = IO(bio)->Socket->Socket.Recv(data, dlen);
+ if (-res == EAGAIN) {
+ BIO_set_retry_read(bio);
+ }
+ return res;
+ }
+
+ static int IoPuts(BIO* bio, const char* buf) noexcept {
+ Y_UNUSED(bio);
+ Y_UNUSED(buf);
+ return -2;
+ }
+
+ static int IoGets(BIO* bio, char* buf, int size) noexcept {
+ Y_UNUSED(bio);
+ Y_UNUSED(buf);
+ Y_UNUSED(size);
+ return -2;
+ }
+
+ static long IoCtrl(BIO* bio, int cmd, long larg, void* parg) noexcept {
+ Y_UNUSED(larg);
+ Y_UNUSED(parg);
+
+ if (cmd == BIO_CTRL_FLUSH) {
+ IO(bio)->Flush();
+ return 1;
+ }
+
+ return -2;
+ }
+
+ static int IoCreate(BIO* bio) noexcept {
+ BIO_set_data(bio, nullptr);
+ BIO_set_init(bio, 1);
+ return 1;
+ }
+
+ static int IoDestroy(BIO* bio) noexcept {
+ BIO_set_data(bio, nullptr);
+ BIO_set_init(bio, 0);
+ return 1;
+ }
+
+ static BIO_METHOD* CreateIoMethod() {
+ BIO_METHOD* method = BIO_meth_new(BIO_get_new_index() | BIO_TYPE_SOURCE_SINK, "SecureSocketImpl");
+ BIO_meth_set_write(method, IoWrite);
+ BIO_meth_set_read(method, IoRead);
+ BIO_meth_set_puts(method, IoPuts);
+ BIO_meth_set_gets(method, IoGets);
+ BIO_meth_set_ctrl(method, IoCtrl);
+ BIO_meth_set_create(method, IoCreate);
+ BIO_meth_set_destroy(method, IoDestroy);
+ return method;
+ }
+
+ static BIO_METHOD* IoMethod() {
+ static BIO_METHOD* method = CreateIoMethod();
+ return method;
+ }
+
+ TSslHolder<BIO> Bio;
+ TSslHolder<SSL_CTX> Ctx;
+ TSslHolder<SSL> Ssl;
+
+ TSecureSocketImpl() = default;
+
+ TSecureSocketImpl(TIntrusivePtr<TSocketDescriptor> socket)
+ : TPlainSocketImpl(std::move(socket))
+ {}
+
+ void InitClientSsl() {
Bio.Reset(BIO_new(IoMethod()));
- BIO_set_data(Bio.Get(), this);
- BIO_set_nbio(Bio.Get(), 1);
- Ctx = CreateClientContext();
- Ssl = ConstructSsl(Ctx.Get(), Bio.Get());
- SSL_set_connect_state(Ssl.Get());
- }
-
- void InitServerSsl(SSL_CTX* ctx) {
+ BIO_set_data(Bio.Get(), this);
+ BIO_set_nbio(Bio.Get(), 1);
+ Ctx = CreateClientContext();
+ Ssl = ConstructSsl(Ctx.Get(), Bio.Get());
+ SSL_set_connect_state(Ssl.Get());
+ }
+
+ void InitServerSsl(SSL_CTX* ctx) {
Bio.Reset(BIO_new(IoMethod()));
- BIO_set_data(Bio.Get(), this);
- BIO_set_nbio(Bio.Get(), 1);
- Ssl = ConstructSsl(ctx, Bio.Get());
- SSL_set_accept_state(Ssl.Get());
- }
-
- void Flush() {}
-
+ BIO_set_data(Bio.Get(), this);
+ BIO_set_nbio(Bio.Get(), 1);
+ Ssl = ConstructSsl(ctx, Bio.Get());
+ SSL_set_accept_state(Ssl.Get());
+ }
+
+ void Flush() {}
+
ssize_t Send(const void* data, size_t size, bool& read, bool& write) {
- ssize_t res = SSL_write(Ssl.Get(), data, size);
- if (res < 0) {
- res = SSL_get_error(Ssl.Get(), res);
- switch(res) {
- case SSL_ERROR_WANT_READ:
+ ssize_t res = SSL_write(Ssl.Get(), data, size);
+ if (res < 0) {
+ res = SSL_get_error(Ssl.Get(), res);
+ switch(res) {
+ case SSL_ERROR_WANT_READ:
read = true;
return -EAGAIN;
- case SSL_ERROR_WANT_WRITE:
+ case SSL_ERROR_WANT_WRITE:
write = true;
- return -EAGAIN;
- default:
- return -EIO;
- }
- }
- return res;
- }
-
+ return -EAGAIN;
+ default:
+ return -EIO;
+ }
+ }
+ return res;
+ }
+
ssize_t Recv(void* data, size_t size, bool& read, bool& write) {
- ssize_t res = SSL_read(Ssl.Get(), data, size);
- if (res < 0) {
- res = SSL_get_error(Ssl.Get(), res);
- switch(res) {
- case SSL_ERROR_WANT_READ:
+ ssize_t res = SSL_read(Ssl.Get(), data, size);
+ if (res < 0) {
+ res = SSL_get_error(Ssl.Get(), res);
+ switch(res) {
+ case SSL_ERROR_WANT_READ:
read = true;
return -EAGAIN;
- case SSL_ERROR_WANT_WRITE:
+ case SSL_ERROR_WANT_WRITE:
write = true;
- return -EAGAIN;
- default:
- return -EIO;
- }
- }
- return res;
- }
-
+ return -EAGAIN;
+ default:
+ return -EIO;
+ }
+ }
+ return res;
+ }
+
int OnConnect(bool& read, bool& write) {
- if (!Ssl) {
- InitClientSsl();
- }
- int res = SSL_connect(Ssl.Get());
+ if (!Ssl) {
+ InitClientSsl();
+ }
+ int res = SSL_connect(Ssl.Get());
if (res <= 0) {
- res = SSL_get_error(Ssl.Get(), res);
- switch(res) {
- case SSL_ERROR_WANT_READ:
+ res = SSL_get_error(Ssl.Get(), res);
+ switch(res) {
+ case SSL_ERROR_WANT_READ:
read = true;
return -EAGAIN;
- case SSL_ERROR_WANT_WRITE:
+ case SSL_ERROR_WANT_WRITE:
write = true;
- return -EAGAIN;
- default:
- return -EIO;
- }
- }
- return res;
- }
-
+ return -EAGAIN;
+ default:
+ return -EIO;
+ }
+ }
+ return res;
+ }
+
int OnAccept(const TEndpointInfo& endpoint, bool& read, bool& write) {
- if (!Ssl) {
- InitServerSsl(endpoint.SecureContext.Get());
- }
- int res = SSL_accept(Ssl.Get());
+ if (!Ssl) {
+ InitServerSsl(endpoint.SecureContext.Get());
+ }
+ int res = SSL_accept(Ssl.Get());
if (res <= 0) {
- res = SSL_get_error(Ssl.Get(), res);
- switch(res) {
- case SSL_ERROR_WANT_READ:
+ res = SSL_get_error(Ssl.Get(), res);
+ switch(res) {
+ case SSL_ERROR_WANT_READ:
read = true;
return -EAGAIN;
- case SSL_ERROR_WANT_WRITE:
+ case SSL_ERROR_WANT_WRITE:
write = true;
- return -EAGAIN;
- default:
- return -EIO;
- }
- }
- return res;
- }
-};
-
-}
+ return -EAGAIN;
+ default:
+ return -EIO;
+ }
+ }
+ return res;
+ }
+};
+
+}
diff --git a/library/cpp/actors/http/http_proxy_ssl.h b/library/cpp/actors/http/http_proxy_ssl.h
index 12fb372b3c6..ffce12997f7 100644
--- a/library/cpp/actors/http/http_proxy_ssl.h
+++ b/library/cpp/actors/http/http_proxy_ssl.h
@@ -1,22 +1,22 @@
-#pragma once
-
-#include <openssl/bio.h>
-#include <openssl/ssl.h>
-#include <openssl/err.h>
-#include <openssl/tls1.h>
-
-namespace NHttp {
-
-struct TSslHelpers {
- struct TSslDestroy {
- static void Destroy(SSL_CTX* ctx) noexcept {
- SSL_CTX_free(ctx);
- }
-
- static void Destroy(SSL* ssl) noexcept {
- SSL_free(ssl);
- }
-
+#pragma once
+
+#include <openssl/bio.h>
+#include <openssl/ssl.h>
+#include <openssl/err.h>
+#include <openssl/tls1.h>
+
+namespace NHttp {
+
+struct TSslHelpers {
+ struct TSslDestroy {
+ static void Destroy(SSL_CTX* ctx) noexcept {
+ SSL_CTX_free(ctx);
+ }
+
+ static void Destroy(SSL* ssl) noexcept {
+ SSL_free(ssl);
+ }
+
static void Destroy(X509* cert) noexcept {
X509_free(cert);
}
@@ -25,48 +25,48 @@ struct TSslHelpers {
EVP_PKEY_free(pkey);
}
- static void Destroy(BIO* bio) noexcept {
- BIO_free(bio);
- }
- };
-
- template <typename T>
- using TSslHolder = THolder<T, TSslDestroy>;
-
- static TSslHolder<SSL_CTX> CreateSslCtx(const SSL_METHOD* method) {
- TSslHolder<SSL_CTX> ctx(SSL_CTX_new(method));
-
- if (ctx) {
- SSL_CTX_set_options(ctx.Get(), SSL_OP_NO_SSLv2);
- SSL_CTX_set_options(ctx.Get(), SSL_OP_NO_SSLv3);
- SSL_CTX_set_options(ctx.Get(), SSL_OP_MICROSOFT_SESS_ID_BUG);
- SSL_CTX_set_options(ctx.Get(), SSL_OP_NETSCAPE_CHALLENGE_BUG);
- }
-
- return ctx;
- }
-
- static TSslHolder<SSL_CTX> CreateClientContext() {
- return CreateSslCtx(SSLv23_client_method());
- }
-
- static TSslHolder<SSL_CTX> CreateServerContext(const TString& certificate, const TString& key) {
- TSslHolder<SSL_CTX> ctx = CreateSslCtx(SSLv23_server_method());
- SSL_CTX_set_ecdh_auto(ctx.Get(), 1);
- int res;
- res = SSL_CTX_use_certificate_chain_file(ctx.Get(), certificate.c_str());
- if (res < 0) {
- // TODO(xenoxeno): more diagnostics?
- return nullptr;
- }
- res = SSL_CTX_use_PrivateKey_file(ctx.Get(), key.c_str(), SSL_FILETYPE_PEM);
- if (res < 0) {
- // TODO(xenoxeno): more diagnostics?
- return nullptr;
- }
- return ctx;
- }
-
+ static void Destroy(BIO* bio) noexcept {
+ BIO_free(bio);
+ }
+ };
+
+ template <typename T>
+ using TSslHolder = THolder<T, TSslDestroy>;
+
+ static TSslHolder<SSL_CTX> CreateSslCtx(const SSL_METHOD* method) {
+ TSslHolder<SSL_CTX> ctx(SSL_CTX_new(method));
+
+ if (ctx) {
+ SSL_CTX_set_options(ctx.Get(), SSL_OP_NO_SSLv2);
+ SSL_CTX_set_options(ctx.Get(), SSL_OP_NO_SSLv3);
+ SSL_CTX_set_options(ctx.Get(), SSL_OP_MICROSOFT_SESS_ID_BUG);
+ SSL_CTX_set_options(ctx.Get(), SSL_OP_NETSCAPE_CHALLENGE_BUG);
+ }
+
+ return ctx;
+ }
+
+ static TSslHolder<SSL_CTX> CreateClientContext() {
+ return CreateSslCtx(SSLv23_client_method());
+ }
+
+ static TSslHolder<SSL_CTX> CreateServerContext(const TString& certificate, const TString& key) {
+ TSslHolder<SSL_CTX> ctx = CreateSslCtx(SSLv23_server_method());
+ SSL_CTX_set_ecdh_auto(ctx.Get(), 1);
+ int res;
+ res = SSL_CTX_use_certificate_chain_file(ctx.Get(), certificate.c_str());
+ if (res < 0) {
+ // TODO(xenoxeno): more diagnostics?
+ return nullptr;
+ }
+ res = SSL_CTX_use_PrivateKey_file(ctx.Get(), key.c_str(), SSL_FILETYPE_PEM);
+ if (res < 0) {
+ // TODO(xenoxeno): more diagnostics?
+ return nullptr;
+ }
+ return ctx;
+ }
+
static bool LoadX509Chain(TSslHolder<SSL_CTX>& ctx, const TString& pem) {
TSslHolder<BIO> bio(BIO_new_mem_buf(pem.c_str(), pem.size()));
if (bio == nullptr) {
@@ -116,16 +116,16 @@ struct TSslHelpers {
return ctx;
}
- static TSslHolder<SSL> ConstructSsl(SSL_CTX* ctx, BIO* bio) {
- TSslHolder<SSL> ssl(SSL_new(ctx));
-
- if (ssl) {
- BIO_up_ref(bio); // SSL_set_bio consumes only one reference if rbio and wbio are the same
- SSL_set_bio(ssl.Get(), bio, bio);
- }
-
- return ssl;
- }
-};
-
-}
+ static TSslHolder<SSL> ConstructSsl(SSL_CTX* ctx, BIO* bio) {
+ TSslHolder<SSL> ssl(SSL_new(ctx));
+
+ if (ssl) {
+ BIO_up_ref(bio); // SSL_set_bio consumes only one reference if rbio and wbio are the same
+ SSL_set_bio(ssl.Get(), bio, bio);
+ }
+
+ return ssl;
+ }
+};
+
+}
diff --git a/library/cpp/actors/http/http_static.cpp b/library/cpp/actors/http/http_static.cpp
index 452b0a84985..c075c5f6935 100644
--- a/library/cpp/actors/http/http_static.cpp
+++ b/library/cpp/actors/http/http_static.cpp
@@ -5,91 +5,91 @@
#include <library/cpp/actors/core/scheduler_basic.h>
#include <library/cpp/actors/http/http.h>
#include <library/cpp/resource/resource.h>
-#include <util/folder/path.h>
-#include <util/stream/file.h>
-
-namespace NHttp {
-
-class THttpStaticContentHandler : public NActors::TActor<THttpStaticContentHandler> {
-public:
- using TBase = NActors::TActor<THttpStaticContentHandler>;
- const TFsPath URL;
- const TFsPath FilePath;
- const TFsPath ResourcePath;
- const TFsPath Index;
-
- THttpStaticContentHandler(const TString& url, const TString& filePath, const TString& resourcePath, const TString& index)
- : TBase(&THttpStaticContentHandler::StateWork)
- , URL(url)
- , FilePath(filePath)
- , ResourcePath(resourcePath)
- , Index(index)
- {}
-
- static TInstant GetCompileTime() {
- tm compileTime;
- strptime(__DATE__ " " __TIME__, "%B %d %Y %H:%M:%S", &compileTime);
- return TInstant::Seconds(mktime(&compileTime));
- }
-
- void Handle(NHttp::TEvHttpProxy::TEvHttpIncomingRequest::TPtr event, const NActors::TActorContext& ctx) {
- THttpOutgoingResponsePtr response;
- if (event->Get()->Request->Method != "GET") {
- response = event->Get()->Request->CreateResponseBadRequest("Wrong request");
- ctx.Send(event->Sender, new NHttp::TEvHttpProxy::TEvHttpOutgoingResponse(response));
- return;
- }
- TFsPath url(event->Get()->Request->URL.Before('?'));
- if (!url.IsAbsolute()) {
- response = event->Get()->Request->CreateResponseBadRequest("Completely wrong URL");
- ctx.Send(event->Sender, new NHttp::TEvHttpProxy::TEvHttpOutgoingResponse(response));
- return;
- }
- if (url.GetPath().EndsWith('/') && Index.IsDefined()) {
- url /= Index;
- }
- url = url.RelativeTo(URL);
- try {
- // TODO: caching?
- TString contentType = mimetypeByExt(url.GetExtension().c_str());
- TString data;
- TFileStat filestat;
- TFsPath resourcename(ResourcePath / url);
- if (NResource::FindExact(resourcename.GetPath(), &data)) {
- static TInstant compileTime(GetCompileTime());
- filestat.MTime = compileTime.Seconds();
- } else {
- TFsPath filename(FilePath / url);
- if (!filename.IsSubpathOf(FilePath) && filename != FilePath) {
- response = event->Get()->Request->CreateResponseBadRequest("Wrong URL");
- ctx.Send(event->Sender, new NHttp::TEvHttpProxy::TEvHttpOutgoingResponse(response));
- return;
- }
- if (filename.Stat(filestat) && filestat.IsFile()) {
- data = TUnbufferedFileInput(filename).ReadAll();
- }
- }
- if (!filestat.IsNull()) {
- response = event->Get()->Request->CreateResponseOK(data, contentType, TInstant::Seconds(filestat.MTime));
- } else {
- response = event->Get()->Request->CreateResponseNotFound("File not found");
- }
- }
- catch (const yexception&) {
- response = event->Get()->Request->CreateResponseServiceUnavailable("Not available");
- }
- ctx.Send(event->Sender, new NHttp::TEvHttpProxy::TEvHttpOutgoingResponse(response));
- }
-
- STFUNC(StateWork) {
- switch (ev->GetTypeRewrite()) {
- HFunc(NHttp::TEvHttpProxy::TEvHttpIncomingRequest, Handle);
- }
- }
-};
-
-NActors::IActor* CreateHttpStaticContentHandler(const TString& url, const TString& filePath, const TString& resourcePath, const TString& index) {
- return new THttpStaticContentHandler(url, filePath, resourcePath, index);
-}
-
-}
+#include <util/folder/path.h>
+#include <util/stream/file.h>
+
+namespace NHttp {
+
+class THttpStaticContentHandler : public NActors::TActor<THttpStaticContentHandler> {
+public:
+ using TBase = NActors::TActor<THttpStaticContentHandler>;
+ const TFsPath URL;
+ const TFsPath FilePath;
+ const TFsPath ResourcePath;
+ const TFsPath Index;
+
+ THttpStaticContentHandler(const TString& url, const TString& filePath, const TString& resourcePath, const TString& index)
+ : TBase(&THttpStaticContentHandler::StateWork)
+ , URL(url)
+ , FilePath(filePath)
+ , ResourcePath(resourcePath)
+ , Index(index)
+ {}
+
+ static TInstant GetCompileTime() {
+ tm compileTime;
+ strptime(__DATE__ " " __TIME__, "%B %d %Y %H:%M:%S", &compileTime);
+ return TInstant::Seconds(mktime(&compileTime));
+ }
+
+ void Handle(NHttp::TEvHttpProxy::TEvHttpIncomingRequest::TPtr event, const NActors::TActorContext& ctx) {
+ THttpOutgoingResponsePtr response;
+ if (event->Get()->Request->Method != "GET") {
+ response = event->Get()->Request->CreateResponseBadRequest("Wrong request");
+ ctx.Send(event->Sender, new NHttp::TEvHttpProxy::TEvHttpOutgoingResponse(response));
+ return;
+ }
+ TFsPath url(event->Get()->Request->URL.Before('?'));
+ if (!url.IsAbsolute()) {
+ response = event->Get()->Request->CreateResponseBadRequest("Completely wrong URL");
+ ctx.Send(event->Sender, new NHttp::TEvHttpProxy::TEvHttpOutgoingResponse(response));
+ return;
+ }
+ if (url.GetPath().EndsWith('/') && Index.IsDefined()) {
+ url /= Index;
+ }
+ url = url.RelativeTo(URL);
+ try {
+ // TODO: caching?
+ TString contentType = mimetypeByExt(url.GetExtension().c_str());
+ TString data;
+ TFileStat filestat;
+ TFsPath resourcename(ResourcePath / url);
+ if (NResource::FindExact(resourcename.GetPath(), &data)) {
+ static TInstant compileTime(GetCompileTime());
+ filestat.MTime = compileTime.Seconds();
+ } else {
+ TFsPath filename(FilePath / url);
+ if (!filename.IsSubpathOf(FilePath) && filename != FilePath) {
+ response = event->Get()->Request->CreateResponseBadRequest("Wrong URL");
+ ctx.Send(event->Sender, new NHttp::TEvHttpProxy::TEvHttpOutgoingResponse(response));
+ return;
+ }
+ if (filename.Stat(filestat) && filestat.IsFile()) {
+ data = TUnbufferedFileInput(filename).ReadAll();
+ }
+ }
+ if (!filestat.IsNull()) {
+ response = event->Get()->Request->CreateResponseOK(data, contentType, TInstant::Seconds(filestat.MTime));
+ } else {
+ response = event->Get()->Request->CreateResponseNotFound("File not found");
+ }
+ }
+ catch (const yexception&) {
+ response = event->Get()->Request->CreateResponseServiceUnavailable("Not available");
+ }
+ ctx.Send(event->Sender, new NHttp::TEvHttpProxy::TEvHttpOutgoingResponse(response));
+ }
+
+ STFUNC(StateWork) {
+ switch (ev->GetTypeRewrite()) {
+ HFunc(NHttp::TEvHttpProxy::TEvHttpIncomingRequest, Handle);
+ }
+ }
+};
+
+NActors::IActor* CreateHttpStaticContentHandler(const TString& url, const TString& filePath, const TString& resourcePath, const TString& index) {
+ return new THttpStaticContentHandler(url, filePath, resourcePath, index);
+}
+
+}
diff --git a/library/cpp/actors/http/http_static.h b/library/cpp/actors/http/http_static.h
index f2ee13d0036..f91e15dfb10 100644
--- a/library/cpp/actors/http/http_static.h
+++ b/library/cpp/actors/http/http_static.h
@@ -1,9 +1,9 @@
-#pragma once
+#pragma once
#include <library/cpp/actors/core/actor.h>
-#include "http.h"
-
-namespace NHttp {
-
-NActors::IActor* CreateHttpStaticContentHandler(const TString& url, const TString& filePath, const TString& resourcePath, const TString& index = TString());
-
-}
+#include "http.h"
+
+namespace NHttp {
+
+NActors::IActor* CreateHttpStaticContentHandler(const TString& url, const TString& filePath, const TString& resourcePath, const TString& index = TString());
+
+}
diff --git a/library/cpp/actors/http/http_ut.cpp b/library/cpp/actors/http/http_ut.cpp
index 209f61f4de6..4c922f8d0fc 100644
--- a/library/cpp/actors/http/http_ut.cpp
+++ b/library/cpp/actors/http/http_ut.cpp
@@ -3,86 +3,86 @@
#include <library/cpp/actors/core/executor_pool_basic.h>
#include <library/cpp/actors/core/scheduler_basic.h>
#include <library/cpp/actors/testlib/test_runtime.h>
-#include <util/system/tempfile.h>
-#include "http.h"
-#include "http_proxy.h"
-
-
-
-enum EService : NActors::NLog::EComponent {
- MIN,
- Logger,
- MVP,
- MAX
-};
-
-namespace {
-
-template <typename HttpType>
-void EatWholeString(TIntrusivePtr<HttpType>& request, const TString& data) {
- request->EnsureEnoughSpaceAvailable(data.size());
- auto size = std::min(request->Avail(), data.size());
- memcpy(request->Pos(), data.data(), size);
- request->Advance(size);
-}
-
-template <typename HttpType>
-void EatPartialString(TIntrusivePtr<HttpType>& request, const TString& data) {
- for (char c : data) {
- request->EnsureEnoughSpaceAvailable(1);
- memcpy(request->Pos(), &c, 1);
- request->Advance(1);
- }
-}
-
-}
-
+#include <util/system/tempfile.h>
+#include "http.h"
+#include "http_proxy.h"
+
+
+
+enum EService : NActors::NLog::EComponent {
+ MIN,
+ Logger,
+ MVP,
+ MAX
+};
+
+namespace {
+
+template <typename HttpType>
+void EatWholeString(TIntrusivePtr<HttpType>& request, const TString& data) {
+ request->EnsureEnoughSpaceAvailable(data.size());
+ auto size = std::min(request->Avail(), data.size());
+ memcpy(request->Pos(), data.data(), size);
+ request->Advance(size);
+}
+
+template <typename HttpType>
+void EatPartialString(TIntrusivePtr<HttpType>& request, const TString& data) {
+ for (char c : data) {
+ request->EnsureEnoughSpaceAvailable(1);
+ memcpy(request->Pos(), &c, 1);
+ request->Advance(1);
+ }
+}
+
+}
+
Y_UNIT_TEST_SUITE(HttpProxy) {
Y_UNIT_TEST(BasicParsing) {
- NHttp::THttpIncomingRequestPtr request = new NHttp::THttpIncomingRequest();
- EatWholeString(request, "GET /test HTTP/1.1\r\nHost: test\r\nSome-Header: 32344\r\n\r\n");
- UNIT_ASSERT_EQUAL(request->Stage, NHttp::THttpIncomingRequest::EParseStage::Done);
- UNIT_ASSERT_EQUAL(request->Method, "GET");
- UNIT_ASSERT_EQUAL(request->URL, "/test");
- UNIT_ASSERT_EQUAL(request->Protocol, "HTTP");
- UNIT_ASSERT_EQUAL(request->Version, "1.1");
- UNIT_ASSERT_EQUAL(request->Host, "test");
- UNIT_ASSERT_EQUAL(request->Headers, "Host: test\r\nSome-Header: 32344\r\n\r\n");
- }
-
+ NHttp::THttpIncomingRequestPtr request = new NHttp::THttpIncomingRequest();
+ EatWholeString(request, "GET /test HTTP/1.1\r\nHost: test\r\nSome-Header: 32344\r\n\r\n");
+ UNIT_ASSERT_EQUAL(request->Stage, NHttp::THttpIncomingRequest::EParseStage::Done);
+ UNIT_ASSERT_EQUAL(request->Method, "GET");
+ UNIT_ASSERT_EQUAL(request->URL, "/test");
+ UNIT_ASSERT_EQUAL(request->Protocol, "HTTP");
+ UNIT_ASSERT_EQUAL(request->Version, "1.1");
+ UNIT_ASSERT_EQUAL(request->Host, "test");
+ UNIT_ASSERT_EQUAL(request->Headers, "Host: test\r\nSome-Header: 32344\r\n\r\n");
+ }
+
Y_UNIT_TEST(BasicParsingChunkedBody) {
- NHttp::THttpOutgoingRequestPtr request = nullptr; //new NHttp::THttpOutgoingRequest();
- NHttp::THttpIncomingResponsePtr response = new NHttp::THttpIncomingResponse(request);
- EatWholeString(response, "HTTP/1.1 200 OK\r\nConnection: close\r\nTransfer-Encoding: chunked\r\n\r\n4\r\nthis\r\n4\r\n is \r\n5\r\ntest.\r\n0\r\n\r\n");
- UNIT_ASSERT_EQUAL(response->Stage, NHttp::THttpIncomingResponse::EParseStage::Done);
- UNIT_ASSERT_EQUAL(response->Status, "200");
- UNIT_ASSERT_EQUAL(response->Connection, "close");
- UNIT_ASSERT_EQUAL(response->Protocol, "HTTP");
- UNIT_ASSERT_EQUAL(response->Version, "1.1");
- UNIT_ASSERT_EQUAL(response->TransferEncoding, "chunked");
- UNIT_ASSERT_EQUAL(response->Body, "this is test.");
- }
-
- Y_UNIT_TEST(InvalidParsingChunkedBody) {
- NHttp::THttpOutgoingRequestPtr request = nullptr; //new NHttp::THttpOutgoingRequest();
- NHttp::THttpIncomingResponsePtr response = new NHttp::THttpIncomingResponse(request);
- EatWholeString(response, "HTTP/1.1 200 OK\r\nConnection: close\r\nTransfer-Encoding: chunked\r\n\r\n5\r\nthis\r\n4\r\n is \r\n5\r\ntest.\r\n0\r\n\r\n");
- UNIT_ASSERT(response->IsError());
- }
-
- Y_UNIT_TEST(AdvancedParsingChunkedBody) {
- NHttp::THttpOutgoingRequestPtr request = nullptr; //new NHttp::THttpOutgoingRequest();
- NHttp::THttpIncomingResponsePtr response = new NHttp::THttpIncomingResponse(request);
- EatWholeString(response, "HTTP/1.1 200 OK\r\nConnection: close\r\nTransfer-Encoding: chunked\r\n\r\n6\r\nthis\r\n\r\n4\r\n is \r\n5\r\ntest.\r\n0\r\n\r\n");
- UNIT_ASSERT_EQUAL(response->Stage, NHttp::THttpIncomingResponse::EParseStage::Done);
- UNIT_ASSERT_EQUAL(response->Status, "200");
- UNIT_ASSERT_EQUAL(response->Connection, "close");
- UNIT_ASSERT_EQUAL(response->Protocol, "HTTP");
- UNIT_ASSERT_EQUAL(response->Version, "1.1");
- UNIT_ASSERT_EQUAL(response->TransferEncoding, "chunked");
- UNIT_ASSERT_EQUAL(response->Body, "this\r\n is test.");
- }
-
+ NHttp::THttpOutgoingRequestPtr request = nullptr; //new NHttp::THttpOutgoingRequest();
+ NHttp::THttpIncomingResponsePtr response = new NHttp::THttpIncomingResponse(request);
+ EatWholeString(response, "HTTP/1.1 200 OK\r\nConnection: close\r\nTransfer-Encoding: chunked\r\n\r\n4\r\nthis\r\n4\r\n is \r\n5\r\ntest.\r\n0\r\n\r\n");
+ UNIT_ASSERT_EQUAL(response->Stage, NHttp::THttpIncomingResponse::EParseStage::Done);
+ UNIT_ASSERT_EQUAL(response->Status, "200");
+ UNIT_ASSERT_EQUAL(response->Connection, "close");
+ UNIT_ASSERT_EQUAL(response->Protocol, "HTTP");
+ UNIT_ASSERT_EQUAL(response->Version, "1.1");
+ UNIT_ASSERT_EQUAL(response->TransferEncoding, "chunked");
+ UNIT_ASSERT_EQUAL(response->Body, "this is test.");
+ }
+
+ Y_UNIT_TEST(InvalidParsingChunkedBody) {
+ NHttp::THttpOutgoingRequestPtr request = nullptr; //new NHttp::THttpOutgoingRequest();
+ NHttp::THttpIncomingResponsePtr response = new NHttp::THttpIncomingResponse(request);
+ EatWholeString(response, "HTTP/1.1 200 OK\r\nConnection: close\r\nTransfer-Encoding: chunked\r\n\r\n5\r\nthis\r\n4\r\n is \r\n5\r\ntest.\r\n0\r\n\r\n");
+ UNIT_ASSERT(response->IsError());
+ }
+
+ Y_UNIT_TEST(AdvancedParsingChunkedBody) {
+ NHttp::THttpOutgoingRequestPtr request = nullptr; //new NHttp::THttpOutgoingRequest();
+ NHttp::THttpIncomingResponsePtr response = new NHttp::THttpIncomingResponse(request);
+ EatWholeString(response, "HTTP/1.1 200 OK\r\nConnection: close\r\nTransfer-Encoding: chunked\r\n\r\n6\r\nthis\r\n\r\n4\r\n is \r\n5\r\ntest.\r\n0\r\n\r\n");
+ UNIT_ASSERT_EQUAL(response->Stage, NHttp::THttpIncomingResponse::EParseStage::Done);
+ UNIT_ASSERT_EQUAL(response->Status, "200");
+ UNIT_ASSERT_EQUAL(response->Connection, "close");
+ UNIT_ASSERT_EQUAL(response->Protocol, "HTTP");
+ UNIT_ASSERT_EQUAL(response->Version, "1.1");
+ UNIT_ASSERT_EQUAL(response->TransferEncoding, "chunked");
+ UNIT_ASSERT_EQUAL(response->Body, "this\r\n is test.");
+ }
+
Y_UNIT_TEST(CreateRepsonseWithCompressedBody) {
NHttp::THttpIncomingRequestPtr request = nullptr;
NHttp::THttpOutgoingResponsePtr response = new NHttp::THttpOutgoingResponse(request, "HTTP", "1.1", "200", "OK");
@@ -95,264 +95,264 @@ Y_UNIT_TEST_SUITE(HttpProxy) {
}
Y_UNIT_TEST(BasicPartialParsing) {
- NHttp::THttpIncomingRequestPtr request = new NHttp::THttpIncomingRequest();
- EatPartialString(request, "GET /test HTTP/1.1\r\nHost: test\r\nSome-Header: 32344\r\n\r\n");
- UNIT_ASSERT_EQUAL(request->Stage, NHttp::THttpIncomingRequest::EParseStage::Done);
- UNIT_ASSERT_EQUAL(request->Method, "GET");
- UNIT_ASSERT_EQUAL(request->URL, "/test");
- UNIT_ASSERT_EQUAL(request->Protocol, "HTTP");
- UNIT_ASSERT_EQUAL(request->Version, "1.1");
- UNIT_ASSERT_EQUAL(request->Host, "test");
- UNIT_ASSERT_EQUAL(request->Headers, "Host: test\r\nSome-Header: 32344\r\n\r\n");
- }
-
+ NHttp::THttpIncomingRequestPtr request = new NHttp::THttpIncomingRequest();
+ EatPartialString(request, "GET /test HTTP/1.1\r\nHost: test\r\nSome-Header: 32344\r\n\r\n");
+ UNIT_ASSERT_EQUAL(request->Stage, NHttp::THttpIncomingRequest::EParseStage::Done);
+ UNIT_ASSERT_EQUAL(request->Method, "GET");
+ UNIT_ASSERT_EQUAL(request->URL, "/test");
+ UNIT_ASSERT_EQUAL(request->Protocol, "HTTP");
+ UNIT_ASSERT_EQUAL(request->Version, "1.1");
+ UNIT_ASSERT_EQUAL(request->Host, "test");
+ UNIT_ASSERT_EQUAL(request->Headers, "Host: test\r\nSome-Header: 32344\r\n\r\n");
+ }
+
Y_UNIT_TEST(BasicPartialParsingChunkedBody) {
- NHttp::THttpOutgoingRequestPtr request = nullptr; //new NHttp::THttpOutgoingRequest();
- NHttp::THttpIncomingResponsePtr response = new NHttp::THttpIncomingResponse(request);
- EatPartialString(response, "HTTP/1.1 200 OK\r\nConnection: close\r\nTransfer-Encoding: chunked\r\n\r\n4\r\nthis\r\n4\r\n is \r\n5\r\ntest.\r\n0\r\n\r\n");
- UNIT_ASSERT_EQUAL(response->Stage, NHttp::THttpIncomingResponse::EParseStage::Done);
- UNIT_ASSERT_EQUAL(response->Status, "200");
- UNIT_ASSERT_EQUAL(response->Connection, "close");
- UNIT_ASSERT_EQUAL(response->Protocol, "HTTP");
- UNIT_ASSERT_EQUAL(response->Version, "1.1");
- UNIT_ASSERT_EQUAL(response->TransferEncoding, "chunked");
- UNIT_ASSERT_EQUAL(response->Body, "this is test.");
- }
-
+ NHttp::THttpOutgoingRequestPtr request = nullptr; //new NHttp::THttpOutgoingRequest();
+ NHttp::THttpIncomingResponsePtr response = new NHttp::THttpIncomingResponse(request);
+ EatPartialString(response, "HTTP/1.1 200 OK\r\nConnection: close\r\nTransfer-Encoding: chunked\r\n\r\n4\r\nthis\r\n4\r\n is \r\n5\r\ntest.\r\n0\r\n\r\n");
+ UNIT_ASSERT_EQUAL(response->Stage, NHttp::THttpIncomingResponse::EParseStage::Done);
+ UNIT_ASSERT_EQUAL(response->Status, "200");
+ UNIT_ASSERT_EQUAL(response->Connection, "close");
+ UNIT_ASSERT_EQUAL(response->Protocol, "HTTP");
+ UNIT_ASSERT_EQUAL(response->Version, "1.1");
+ UNIT_ASSERT_EQUAL(response->TransferEncoding, "chunked");
+ UNIT_ASSERT_EQUAL(response->Body, "this is test.");
+ }
+
Y_UNIT_TEST(AdvancedParsing) {
- NHttp::THttpIncomingRequestPtr request = new NHttp::THttpIncomingRequest();
- EatWholeString(request, "GE");
- EatWholeString(request, "T");
- EatWholeString(request, " ");
- EatWholeString(request, "/test");
- EatWholeString(request, " HTTP/1.1\r");
- EatWholeString(request, "\nHo");
- EatWholeString(request, "st: test");
- EatWholeString(request, "\r\n");
- EatWholeString(request, "Some-Header: 32344\r\n\r");
- EatWholeString(request, "\n");
- UNIT_ASSERT_EQUAL(request->Stage, NHttp::THttpIncomingRequest::EParseStage::Done);
- UNIT_ASSERT_EQUAL(request->Method, "GET");
- UNIT_ASSERT_EQUAL(request->URL, "/test");
- UNIT_ASSERT_EQUAL(request->Protocol, "HTTP");
- UNIT_ASSERT_EQUAL(request->Version, "1.1");
- UNIT_ASSERT_EQUAL(request->Host, "test");
- UNIT_ASSERT_EQUAL(request->Headers, "Host: test\r\nSome-Header: 32344\r\n\r\n");
- }
-
+ NHttp::THttpIncomingRequestPtr request = new NHttp::THttpIncomingRequest();
+ EatWholeString(request, "GE");
+ EatWholeString(request, "T");
+ EatWholeString(request, " ");
+ EatWholeString(request, "/test");
+ EatWholeString(request, " HTTP/1.1\r");
+ EatWholeString(request, "\nHo");
+ EatWholeString(request, "st: test");
+ EatWholeString(request, "\r\n");
+ EatWholeString(request, "Some-Header: 32344\r\n\r");
+ EatWholeString(request, "\n");
+ UNIT_ASSERT_EQUAL(request->Stage, NHttp::THttpIncomingRequest::EParseStage::Done);
+ UNIT_ASSERT_EQUAL(request->Method, "GET");
+ UNIT_ASSERT_EQUAL(request->URL, "/test");
+ UNIT_ASSERT_EQUAL(request->Protocol, "HTTP");
+ UNIT_ASSERT_EQUAL(request->Version, "1.1");
+ UNIT_ASSERT_EQUAL(request->Host, "test");
+ UNIT_ASSERT_EQUAL(request->Headers, "Host: test\r\nSome-Header: 32344\r\n\r\n");
+ }
+
Y_UNIT_TEST(AdvancedPartialParsing) {
- NHttp::THttpIncomingRequestPtr request = new NHttp::THttpIncomingRequest();
- EatPartialString(request, "GE");
- EatPartialString(request, "T");
- EatPartialString(request, " ");
- EatPartialString(request, "/test");
- EatPartialString(request, " HTTP/1.1\r");
- EatPartialString(request, "\nHo");
- EatPartialString(request, "st: test");
- EatPartialString(request, "\r\n");
- EatPartialString(request, "Some-Header: 32344\r\n\r");
- EatPartialString(request, "\n");
- UNIT_ASSERT_EQUAL(request->Stage, NHttp::THttpIncomingRequest::EParseStage::Done);
- UNIT_ASSERT_EQUAL(request->Method, "GET");
- UNIT_ASSERT_EQUAL(request->URL, "/test");
- UNIT_ASSERT_EQUAL(request->Protocol, "HTTP");
- UNIT_ASSERT_EQUAL(request->Version, "1.1");
- UNIT_ASSERT_EQUAL(request->Host, "test");
- UNIT_ASSERT_EQUAL(request->Headers, "Host: test\r\nSome-Header: 32344\r\n\r\n");
- }
-
- Y_UNIT_TEST(BasicRenderBodyWithHeadersAndCookies) {
- NHttp::THttpOutgoingRequestPtr request = NHttp::THttpOutgoingRequest::CreateRequestGet("http://www.yandex.ru/data/url");
- NHttp::THeadersBuilder headers;
- NHttp::TCookiesBuilder cookies;
- cookies.Set("cookie1", "123456");
- cookies.Set("cookie2", "45678");
- headers.Set("Cookie", cookies.Render());
- request->Set(headers);
- TString requestData;
- request->AsString(requestData);
- UNIT_ASSERT_VALUES_EQUAL(requestData, "GET /data/url HTTP/1.1\r\nHost: www.yandex.ru\r\nAccept: */*\r\nCookie: cookie1=123456; cookie2=45678;\r\n");
- }
-
+ NHttp::THttpIncomingRequestPtr request = new NHttp::THttpIncomingRequest();
+ EatPartialString(request, "GE");
+ EatPartialString(request, "T");
+ EatPartialString(request, " ");
+ EatPartialString(request, "/test");
+ EatPartialString(request, " HTTP/1.1\r");
+ EatPartialString(request, "\nHo");
+ EatPartialString(request, "st: test");
+ EatPartialString(request, "\r\n");
+ EatPartialString(request, "Some-Header: 32344\r\n\r");
+ EatPartialString(request, "\n");
+ UNIT_ASSERT_EQUAL(request->Stage, NHttp::THttpIncomingRequest::EParseStage::Done);
+ UNIT_ASSERT_EQUAL(request->Method, "GET");
+ UNIT_ASSERT_EQUAL(request->URL, "/test");
+ UNIT_ASSERT_EQUAL(request->Protocol, "HTTP");
+ UNIT_ASSERT_EQUAL(request->Version, "1.1");
+ UNIT_ASSERT_EQUAL(request->Host, "test");
+ UNIT_ASSERT_EQUAL(request->Headers, "Host: test\r\nSome-Header: 32344\r\n\r\n");
+ }
+
+ Y_UNIT_TEST(BasicRenderBodyWithHeadersAndCookies) {
+ NHttp::THttpOutgoingRequestPtr request = NHttp::THttpOutgoingRequest::CreateRequestGet("http://www.yandex.ru/data/url");
+ NHttp::THeadersBuilder headers;
+ NHttp::TCookiesBuilder cookies;
+ cookies.Set("cookie1", "123456");
+ cookies.Set("cookie2", "45678");
+ headers.Set("Cookie", cookies.Render());
+ request->Set(headers);
+ TString requestData;
+ request->AsString(requestData);
+ UNIT_ASSERT_VALUES_EQUAL(requestData, "GET /data/url HTTP/1.1\r\nHost: www.yandex.ru\r\nAccept: */*\r\nCookie: cookie1=123456; cookie2=45678;\r\n");
+ }
+
Y_UNIT_TEST(BasicRunning) {
NActors::TTestActorRuntimeBase actorSystem;
- TPortManager portManager;
- TIpPort port = portManager.GetTcpPort();
- TAutoPtr<NActors::IEventHandle> handle;
+ TPortManager portManager;
+ TIpPort port = portManager.GetTcpPort();
+ TAutoPtr<NActors::IEventHandle> handle;
actorSystem.Initialize();
NMonitoring::TMetricRegistry sensors;
-
- NActors::IActor* proxy = NHttp::CreateHttpProxy(sensors);
+
+ NActors::IActor* proxy = NHttp::CreateHttpProxy(sensors);
NActors::TActorId proxyId = actorSystem.Register(proxy);
actorSystem.Send(new NActors::IEventHandle(proxyId, TActorId(), new NHttp::TEvHttpProxy::TEvAddListeningPort(port)), 0, true);
- actorSystem.DispatchEvents();
-
+ actorSystem.DispatchEvents();
+
NActors::TActorId serverId = actorSystem.AllocateEdgeActor();
- actorSystem.Send(new NActors::IEventHandle(proxyId, serverId, new NHttp::TEvHttpProxy::TEvRegisterHandler("/test", serverId)), 0, true);
-
+ actorSystem.Send(new NActors::IEventHandle(proxyId, serverId, new NHttp::TEvHttpProxy::TEvRegisterHandler("/test", serverId)), 0, true);
+
NActors::TActorId clientId = actorSystem.AllocateEdgeActor();
- NHttp::THttpOutgoingRequestPtr httpRequest = NHttp::THttpOutgoingRequest::CreateRequestGet("http://[::1]:" + ToString(port) + "/test");
- actorSystem.Send(new NActors::IEventHandle(proxyId, clientId, new NHttp::TEvHttpProxy::TEvHttpOutgoingRequest(httpRequest)), 0, true);
-
- NHttp::TEvHttpProxy::TEvHttpIncomingRequest* request = actorSystem.GrabEdgeEvent<NHttp::TEvHttpProxy::TEvHttpIncomingRequest>(handle);
-
- UNIT_ASSERT_EQUAL(request->Request->URL, "/test");
-
- NHttp::THttpOutgoingResponsePtr httpResponse = request->Request->CreateResponseString("HTTP/1.1 200 Found\r\nConnection: Close\r\nTransfer-Encoding: chunked\r\n\r\n6\r\npassed\r\n0\r\n\r\n");
- actorSystem.Send(new NActors::IEventHandle(handle->Sender, serverId, new NHttp::TEvHttpProxy::TEvHttpOutgoingResponse(httpResponse)), 0, true);
-
- NHttp::TEvHttpProxy::TEvHttpIncomingResponse* response = actorSystem.GrabEdgeEvent<NHttp::TEvHttpProxy::TEvHttpIncomingResponse>(handle);
-
- UNIT_ASSERT_EQUAL(response->Response->Status, "200");
- UNIT_ASSERT_EQUAL(response->Response->Body, "passed");
- }
-
- Y_UNIT_TEST(TlsRunning) {
- NActors::TTestActorRuntimeBase actorSystem;
- TPortManager portManager;
- TIpPort port = portManager.GetTcpPort();
- TAutoPtr<NActors::IEventHandle> handle;
- actorSystem.Initialize();
+ NHttp::THttpOutgoingRequestPtr httpRequest = NHttp::THttpOutgoingRequest::CreateRequestGet("http://[::1]:" + ToString(port) + "/test");
+ actorSystem.Send(new NActors::IEventHandle(proxyId, clientId, new NHttp::TEvHttpProxy::TEvHttpOutgoingRequest(httpRequest)), 0, true);
+
+ NHttp::TEvHttpProxy::TEvHttpIncomingRequest* request = actorSystem.GrabEdgeEvent<NHttp::TEvHttpProxy::TEvHttpIncomingRequest>(handle);
+
+ UNIT_ASSERT_EQUAL(request->Request->URL, "/test");
+
+ NHttp::THttpOutgoingResponsePtr httpResponse = request->Request->CreateResponseString("HTTP/1.1 200 Found\r\nConnection: Close\r\nTransfer-Encoding: chunked\r\n\r\n6\r\npassed\r\n0\r\n\r\n");
+ actorSystem.Send(new NActors::IEventHandle(handle->Sender, serverId, new NHttp::TEvHttpProxy::TEvHttpOutgoingResponse(httpResponse)), 0, true);
+
+ NHttp::TEvHttpProxy::TEvHttpIncomingResponse* response = actorSystem.GrabEdgeEvent<NHttp::TEvHttpProxy::TEvHttpIncomingResponse>(handle);
+
+ UNIT_ASSERT_EQUAL(response->Response->Status, "200");
+ UNIT_ASSERT_EQUAL(response->Response->Body, "passed");
+ }
+
+ Y_UNIT_TEST(TlsRunning) {
+ NActors::TTestActorRuntimeBase actorSystem;
+ TPortManager portManager;
+ TIpPort port = portManager.GetTcpPort();
+ TAutoPtr<NActors::IEventHandle> handle;
+ actorSystem.Initialize();
NMonitoring::TMetricRegistry sensors;
-
- TString certificateContent = R"___(-----BEGIN PRIVATE KEY-----
-MIIEvwIBADANBgkqhkiG9w0BAQEFAASCBKkwggSlAgEAAoIBAQCzRZjodO7Aqe1w
-RyOj6kG6g2nn8ZGAxfao4mLT0jDTbVksrhV/h2s3uldLkFo5WrNQ8WZe+iIbXeFL
-s8tO6hslzreo9sih2IHoRcH5KnS/6YTqVhRTJb1jE2dM8NwYbwTi+T2Pe0FrBPjI
-kgVO50gAtYl9C+fc715uZiSKW+rRlP5OoFTwxrOjiU27RPZjFYyWK9wTI1Es9uRr
-lbZbLl5cY6dK2J1AViRraaYKCWO26VbOPWLsY4OD3e+ZXIc3OMCz6Yb0wmRPeJ60
-bbbkGfI8O27kDdv69MAWHIm0yYMzKEnom1dce7rNQNDEqJfocsYIsg+EvayT1yQ9
-KTBegw7LAgMBAAECggEBAKaOCrotqYQmXArsjRhFFDwMy+BKdzyEr93INrlFl0dX
-WHpCYobRcbOc1G3H94tB0UdqgAnNqtJyLlb+++ydZAuEOu4oGc8EL+10ofq0jzOd
-6Xct8kQt0/6wkFDTlii9PHUDy0X65ZRgUiNGRtg/2I2QG+SpowmI+trm2xwQueFs
-VaWrjc3cVvXx0b8Lu7hqZUv08kgC38stzuRk/n2T5VWSAr7Z4ZWQbO918Dv35HUw
-Wy/0jNUFP9CBCvFJ4l0OoH9nYhWFG+HXWzNdw6/Hca4jciRKo6esCiOZ9uWYv/ec
-/NvX9rgFg8G8/SrTisX10+Bbeq+R1RKwq/IG409TH4ECgYEA14L+3QsgNIUMeYAx
-jSCyk22R/tOHI1BM+GtKPUhnwHlAssrcPcxXMJovl6WL93VauYjym0wpCz9urSpA
-I2CqTsG8GYciA6Dr3mHgD6cK0jj9UPAU6EnZ5S0mjhPqKZqutu9QegzD2uESvuN8
-36xezwQthzAf0nI/P3sJGjVXjikCgYEA1POm5xcV6SmM6HnIdadEebhzZIJ9TXQz
-ry3Jj3a7CKyD5C7fAdkHUTCjgT/2ElxPi9ABkZnC+d/cW9GtJFa0II5qO/agm3KQ
-ZXYiutu9A7xACHYFXRiJEjVUdGG9dKMVOHUEa8IHEgrrcUVM/suy/GgutywIfaXs
-y58IFP24K9MCgYEAk6zjz7wL+XEiNy+sxLQfKf7vB9sSwxQHakK6wHuY/L8Zomp3
-uLEJHfjJm/SIkK0N2g0JkXkCtv5kbKyC/rsCeK0wo52BpVLjzaLr0k34kE0U6B1b
-dkEE2pGx1bG3x4KDLj+Wuct9ecK5Aa0IqIyI+vo16GkFpUM8K9e3SQo8UOECgYEA
-sCZYAkILYtJ293p9giz5rIISGasDAUXE1vxWBXEeJ3+kneTTnZCrx9Im/ewtnWR0
-fF90XL9HFDDD88POqAd8eo2zfKR2l/89SGBfPBg2EtfuU9FkgGyiPciVcqvC7q9U
-B15saMKX3KnhtdGwbfeLt9RqCCTJZT4SUSDcq5hwdvcCgYAxY4Be8mNipj8Cgg22
-mVWSolA0TEzbtUcNk6iGodpi+Z0LKpsPC0YRqPRyh1K+rIltG1BVdmUBHcMlOYxl
-lWWvbJH6PkJWy4n2MF7PO45kjN3pPZg4hgH63JjZeAineBwEArUGb9zHnvzcdRvF
-wuQ2pZHL/HJ0laUSieHDJ5917w==
------END PRIVATE KEY-----
-
-
------BEGIN CERTIFICATE-----
-MIIDjTCCAnWgAwIBAgIURt5IBx0J3xgEaQvmyrFH2A+NkpMwDQYJKoZIhvcNAQEL
-BQAwVjELMAkGA1UEBhMCUlUxDzANBgNVBAgMBk1vc2NvdzEPMA0GA1UEBwwGTW9z
-Y293MQ8wDQYDVQQKDAZZYW5kZXgxFDASBgNVBAMMC3Rlc3Qtc2VydmVyMB4XDTE5
-MDkyMDE3MTQ0MVoXDTQ3MDIwNDE3MTQ0MVowVjELMAkGA1UEBhMCUlUxDzANBgNV
-BAgMBk1vc2NvdzEPMA0GA1UEBwwGTW9zY293MQ8wDQYDVQQKDAZZYW5kZXgxFDAS
-BgNVBAMMC3Rlc3Qtc2VydmVyMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKC
-AQEAs0WY6HTuwKntcEcjo+pBuoNp5/GRgMX2qOJi09Iw021ZLK4Vf4drN7pXS5Ba
-OVqzUPFmXvoiG13hS7PLTuobJc63qPbIodiB6EXB+Sp0v+mE6lYUUyW9YxNnTPDc
-GG8E4vk9j3tBawT4yJIFTudIALWJfQvn3O9ebmYkilvq0ZT+TqBU8Mazo4lNu0T2
-YxWMlivcEyNRLPbka5W2Wy5eXGOnStidQFYka2mmCgljtulWzj1i7GODg93vmVyH
-NzjAs+mG9MJkT3ietG225BnyPDtu5A3b+vTAFhyJtMmDMyhJ6JtXXHu6zUDQxKiX
-6HLGCLIPhL2sk9ckPSkwXoMOywIDAQABo1MwUTAdBgNVHQ4EFgQUDv/xuJ4CvCgG
-fPrZP3hRAt2+/LwwHwYDVR0jBBgwFoAUDv/xuJ4CvCgGfPrZP3hRAt2+/LwwDwYD
-VR0TAQH/BAUwAwEB/zANBgkqhkiG9w0BAQsFAAOCAQEAinKpMYaA2tjLpAnPVbjy
-/ZxSBhhB26RiQp3Re8XOKyhTWqgYE6kldYT0aXgK9x9mPC5obQannDDYxDc7lX+/
-qP/u1X81ZcDRo/f+qQ3iHfT6Ftt/4O3qLnt45MFM6Q7WabRm82x3KjZTqpF3QUdy
-tumWiuAP5DMd1IRDtnKjFHO721OsEsf6NLcqdX89bGeqXDvrkwg3/PNwTyW5E7cj
-feY8L2eWtg6AJUnIBu11wvfzkLiH3QKzHvO/SIZTGf5ihDsJ3aKEE9UNauTL3bVc
-CRA/5XcX13GJwHHj6LCoc3sL7mt8qV9HKY2AOZ88mpObzISZxgPpdKCfjsrdm63V
-6g==
------END CERTIFICATE-----)___";
-
- TTempFileHandle certificateFile;
-
- certificateFile.Write(certificateContent.data(), certificateContent.size());
-
- NActors::IActor* proxy = NHttp::CreateHttpProxy(sensors);
+
+ TString certificateContent = R"___(-----BEGIN PRIVATE KEY-----
+MIIEvwIBADANBgkqhkiG9w0BAQEFAASCBKkwggSlAgEAAoIBAQCzRZjodO7Aqe1w
+RyOj6kG6g2nn8ZGAxfao4mLT0jDTbVksrhV/h2s3uldLkFo5WrNQ8WZe+iIbXeFL
+s8tO6hslzreo9sih2IHoRcH5KnS/6YTqVhRTJb1jE2dM8NwYbwTi+T2Pe0FrBPjI
+kgVO50gAtYl9C+fc715uZiSKW+rRlP5OoFTwxrOjiU27RPZjFYyWK9wTI1Es9uRr
+lbZbLl5cY6dK2J1AViRraaYKCWO26VbOPWLsY4OD3e+ZXIc3OMCz6Yb0wmRPeJ60
+bbbkGfI8O27kDdv69MAWHIm0yYMzKEnom1dce7rNQNDEqJfocsYIsg+EvayT1yQ9
+KTBegw7LAgMBAAECggEBAKaOCrotqYQmXArsjRhFFDwMy+BKdzyEr93INrlFl0dX
+WHpCYobRcbOc1G3H94tB0UdqgAnNqtJyLlb+++ydZAuEOu4oGc8EL+10ofq0jzOd
+6Xct8kQt0/6wkFDTlii9PHUDy0X65ZRgUiNGRtg/2I2QG+SpowmI+trm2xwQueFs
+VaWrjc3cVvXx0b8Lu7hqZUv08kgC38stzuRk/n2T5VWSAr7Z4ZWQbO918Dv35HUw
+Wy/0jNUFP9CBCvFJ4l0OoH9nYhWFG+HXWzNdw6/Hca4jciRKo6esCiOZ9uWYv/ec
+/NvX9rgFg8G8/SrTisX10+Bbeq+R1RKwq/IG409TH4ECgYEA14L+3QsgNIUMeYAx
+jSCyk22R/tOHI1BM+GtKPUhnwHlAssrcPcxXMJovl6WL93VauYjym0wpCz9urSpA
+I2CqTsG8GYciA6Dr3mHgD6cK0jj9UPAU6EnZ5S0mjhPqKZqutu9QegzD2uESvuN8
+36xezwQthzAf0nI/P3sJGjVXjikCgYEA1POm5xcV6SmM6HnIdadEebhzZIJ9TXQz
+ry3Jj3a7CKyD5C7fAdkHUTCjgT/2ElxPi9ABkZnC+d/cW9GtJFa0II5qO/agm3KQ
+ZXYiutu9A7xACHYFXRiJEjVUdGG9dKMVOHUEa8IHEgrrcUVM/suy/GgutywIfaXs
+y58IFP24K9MCgYEAk6zjz7wL+XEiNy+sxLQfKf7vB9sSwxQHakK6wHuY/L8Zomp3
+uLEJHfjJm/SIkK0N2g0JkXkCtv5kbKyC/rsCeK0wo52BpVLjzaLr0k34kE0U6B1b
+dkEE2pGx1bG3x4KDLj+Wuct9ecK5Aa0IqIyI+vo16GkFpUM8K9e3SQo8UOECgYEA
+sCZYAkILYtJ293p9giz5rIISGasDAUXE1vxWBXEeJ3+kneTTnZCrx9Im/ewtnWR0
+fF90XL9HFDDD88POqAd8eo2zfKR2l/89SGBfPBg2EtfuU9FkgGyiPciVcqvC7q9U
+B15saMKX3KnhtdGwbfeLt9RqCCTJZT4SUSDcq5hwdvcCgYAxY4Be8mNipj8Cgg22
+mVWSolA0TEzbtUcNk6iGodpi+Z0LKpsPC0YRqPRyh1K+rIltG1BVdmUBHcMlOYxl
+lWWvbJH6PkJWy4n2MF7PO45kjN3pPZg4hgH63JjZeAineBwEArUGb9zHnvzcdRvF
+wuQ2pZHL/HJ0laUSieHDJ5917w==
+-----END PRIVATE KEY-----
+
+
+-----BEGIN CERTIFICATE-----
+MIIDjTCCAnWgAwIBAgIURt5IBx0J3xgEaQvmyrFH2A+NkpMwDQYJKoZIhvcNAQEL
+BQAwVjELMAkGA1UEBhMCUlUxDzANBgNVBAgMBk1vc2NvdzEPMA0GA1UEBwwGTW9z
+Y293MQ8wDQYDVQQKDAZZYW5kZXgxFDASBgNVBAMMC3Rlc3Qtc2VydmVyMB4XDTE5
+MDkyMDE3MTQ0MVoXDTQ3MDIwNDE3MTQ0MVowVjELMAkGA1UEBhMCUlUxDzANBgNV
+BAgMBk1vc2NvdzEPMA0GA1UEBwwGTW9zY293MQ8wDQYDVQQKDAZZYW5kZXgxFDAS
+BgNVBAMMC3Rlc3Qtc2VydmVyMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKC
+AQEAs0WY6HTuwKntcEcjo+pBuoNp5/GRgMX2qOJi09Iw021ZLK4Vf4drN7pXS5Ba
+OVqzUPFmXvoiG13hS7PLTuobJc63qPbIodiB6EXB+Sp0v+mE6lYUUyW9YxNnTPDc
+GG8E4vk9j3tBawT4yJIFTudIALWJfQvn3O9ebmYkilvq0ZT+TqBU8Mazo4lNu0T2
+YxWMlivcEyNRLPbka5W2Wy5eXGOnStidQFYka2mmCgljtulWzj1i7GODg93vmVyH
+NzjAs+mG9MJkT3ietG225BnyPDtu5A3b+vTAFhyJtMmDMyhJ6JtXXHu6zUDQxKiX
+6HLGCLIPhL2sk9ckPSkwXoMOywIDAQABo1MwUTAdBgNVHQ4EFgQUDv/xuJ4CvCgG
+fPrZP3hRAt2+/LwwHwYDVR0jBBgwFoAUDv/xuJ4CvCgGfPrZP3hRAt2+/LwwDwYD
+VR0TAQH/BAUwAwEB/zANBgkqhkiG9w0BAQsFAAOCAQEAinKpMYaA2tjLpAnPVbjy
+/ZxSBhhB26RiQp3Re8XOKyhTWqgYE6kldYT0aXgK9x9mPC5obQannDDYxDc7lX+/
+qP/u1X81ZcDRo/f+qQ3iHfT6Ftt/4O3qLnt45MFM6Q7WabRm82x3KjZTqpF3QUdy
+tumWiuAP5DMd1IRDtnKjFHO721OsEsf6NLcqdX89bGeqXDvrkwg3/PNwTyW5E7cj
+feY8L2eWtg6AJUnIBu11wvfzkLiH3QKzHvO/SIZTGf5ihDsJ3aKEE9UNauTL3bVc
+CRA/5XcX13GJwHHj6LCoc3sL7mt8qV9HKY2AOZ88mpObzISZxgPpdKCfjsrdm63V
+6g==
+-----END CERTIFICATE-----)___";
+
+ TTempFileHandle certificateFile;
+
+ certificateFile.Write(certificateContent.data(), certificateContent.size());
+
+ NActors::IActor* proxy = NHttp::CreateHttpProxy(sensors);
NActors::TActorId proxyId = actorSystem.Register(proxy);
-
+
THolder<NHttp::TEvHttpProxy::TEvAddListeningPort> add = MakeHolder<NHttp::TEvHttpProxy::TEvAddListeningPort>(port);
- ///////// https configuration
- add->Secure = true;
- add->CertificateFile = certificateFile.Name();
- add->PrivateKeyFile = certificateFile.Name();
- /////////
+ ///////// https configuration
+ add->Secure = true;
+ add->CertificateFile = certificateFile.Name();
+ add->PrivateKeyFile = certificateFile.Name();
+ /////////
actorSystem.Send(new NActors::IEventHandle(proxyId, TActorId(), add.Release()), 0, true);
- actorSystem.DispatchEvents();
-
+ actorSystem.DispatchEvents();
+
NActors::TActorId serverId = actorSystem.AllocateEdgeActor();
- actorSystem.Send(new NActors::IEventHandle(proxyId, serverId, new NHttp::TEvHttpProxy::TEvRegisterHandler("/test", serverId)), 0, true);
-
+ actorSystem.Send(new NActors::IEventHandle(proxyId, serverId, new NHttp::TEvHttpProxy::TEvRegisterHandler("/test", serverId)), 0, true);
+
NActors::TActorId clientId = actorSystem.AllocateEdgeActor();
- NHttp::THttpOutgoingRequestPtr httpRequest = NHttp::THttpOutgoingRequest::CreateRequestGet("https://[::1]:" + ToString(port) + "/test");
- actorSystem.Send(new NActors::IEventHandle(proxyId, clientId, new NHttp::TEvHttpProxy::TEvHttpOutgoingRequest(httpRequest)), 0, true);
-
- NHttp::TEvHttpProxy::TEvHttpIncomingRequest* request = actorSystem.GrabEdgeEvent<NHttp::TEvHttpProxy::TEvHttpIncomingRequest>(handle);
-
- UNIT_ASSERT_EQUAL(request->Request->URL, "/test");
-
- NHttp::THttpOutgoingResponsePtr httpResponse = request->Request->CreateResponseString("HTTP/1.1 200 Found\r\nConnection: Close\r\nTransfer-Encoding: chunked\r\n\r\n6\r\npassed\r\n0\r\n\r\n");
- actorSystem.Send(new NActors::IEventHandle(handle->Sender, serverId, new NHttp::TEvHttpProxy::TEvHttpOutgoingResponse(httpResponse)), 0, true);
-
- NHttp::TEvHttpProxy::TEvHttpIncomingResponse* response = actorSystem.GrabEdgeEvent<NHttp::TEvHttpProxy::TEvHttpIncomingResponse>(handle);
-
- UNIT_ASSERT_EQUAL(response->Response->Status, "200");
- UNIT_ASSERT_EQUAL(response->Response->Body, "passed");
- }
-
+ NHttp::THttpOutgoingRequestPtr httpRequest = NHttp::THttpOutgoingRequest::CreateRequestGet("https://[::1]:" + ToString(port) + "/test");
+ actorSystem.Send(new NActors::IEventHandle(proxyId, clientId, new NHttp::TEvHttpProxy::TEvHttpOutgoingRequest(httpRequest)), 0, true);
+
+ NHttp::TEvHttpProxy::TEvHttpIncomingRequest* request = actorSystem.GrabEdgeEvent<NHttp::TEvHttpProxy::TEvHttpIncomingRequest>(handle);
+
+ UNIT_ASSERT_EQUAL(request->Request->URL, "/test");
+
+ NHttp::THttpOutgoingResponsePtr httpResponse = request->Request->CreateResponseString("HTTP/1.1 200 Found\r\nConnection: Close\r\nTransfer-Encoding: chunked\r\n\r\n6\r\npassed\r\n0\r\n\r\n");
+ actorSystem.Send(new NActors::IEventHandle(handle->Sender, serverId, new NHttp::TEvHttpProxy::TEvHttpOutgoingResponse(httpResponse)), 0, true);
+
+ NHttp::TEvHttpProxy::TEvHttpIncomingResponse* response = actorSystem.GrabEdgeEvent<NHttp::TEvHttpProxy::TEvHttpIncomingResponse>(handle);
+
+ UNIT_ASSERT_EQUAL(response->Response->Status, "200");
+ UNIT_ASSERT_EQUAL(response->Response->Body, "passed");
+ }
+
/*Y_UNIT_TEST(AdvancedRunning) {
THolder<NActors::TActorSystemSetup> setup = MakeHolder<NActors::TActorSystemSetup>();
- setup->NodeId = 1;
- setup->ExecutorsCount = 1;
- setup->Executors = new TAutoPtr<NActors::IExecutorPool>[1];
- setup->Executors[0] = new NActors::TBasicExecutorPool(0, 2, 10);
- setup->Scheduler = new NActors::TBasicSchedulerThread(NActors::TSchedulerConfig(512, 100));
- NActors::TActorSystem actorSystem(setup);
- actorSystem.Start();
- NHttp::THttpProxy* incomingProxy = new NHttp::THttpProxy();
+ setup->NodeId = 1;
+ setup->ExecutorsCount = 1;
+ setup->Executors = new TAutoPtr<NActors::IExecutorPool>[1];
+ setup->Executors[0] = new NActors::TBasicExecutorPool(0, 2, 10);
+ setup->Scheduler = new NActors::TBasicSchedulerThread(NActors::TSchedulerConfig(512, 100));
+ NActors::TActorSystem actorSystem(setup);
+ actorSystem.Start();
+ NHttp::THttpProxy* incomingProxy = new NHttp::THttpProxy();
NActors::TActorId incomingProxyId = actorSystem.Register(incomingProxy);
- actorSystem.Send(incomingProxyId, new NHttp::TEvHttpProxy::TEvAddListeningPort(13337));
-
- NHttp::THttpProxy* outgoingProxy = new NHttp::THttpProxy();
+ actorSystem.Send(incomingProxyId, new NHttp::TEvHttpProxy::TEvAddListeningPort(13337));
+
+ NHttp::THttpProxy* outgoingProxy = new NHttp::THttpProxy();
NActors::TActorId outgoingProxyId = actorSystem.Register(outgoingProxy);
-
+
THolder<NHttp::THttpStaticStringRequest> httpRequest = MakeHolder<NHttp::THttpStaticStringRequest>("GET /test HTTP/1.1\r\n\r\n");
- actorSystem.Send(outgoingProxyId, new NHttp::TEvHttpProxy::TEvHttpOutgoingRequest("[::]:13337", std::move(httpRequest)));
-
- Sleep(TDuration::Minutes(60));
- }*/
-
- Y_UNIT_TEST(TooLongHeader) {
- NActors::TTestActorRuntimeBase actorSystem;
- TPortManager portManager;
- TIpPort port = portManager.GetTcpPort();
- TAutoPtr<NActors::IEventHandle> handle;
- actorSystem.Initialize();
- NMonitoring::TMetricRegistry sensors;
-
- NActors::IActor* proxy = NHttp::CreateHttpProxy(sensors);
- NActors::TActorId proxyId = actorSystem.Register(proxy);
- actorSystem.Send(new NActors::IEventHandle(proxyId, TActorId(), new NHttp::TEvHttpProxy::TEvAddListeningPort(port)), 0, true);
- actorSystem.DispatchEvents();
-
- NActors::TActorId serverId = actorSystem.AllocateEdgeActor();
- actorSystem.Send(new NActors::IEventHandle(proxyId, serverId, new NHttp::TEvHttpProxy::TEvRegisterHandler("/test", serverId)), 0, true);
-
- NActors::TActorId clientId = actorSystem.AllocateEdgeActor();
- NHttp::THttpOutgoingRequestPtr httpRequest = NHttp::THttpOutgoingRequest::CreateRequestGet("http://[::1]:" + ToString(port) + "/test");
- httpRequest->Set("Connection", "close");
- TString longHeader;
- longHeader.append(9000, 'X');
- httpRequest->Set(longHeader, "data");
- actorSystem.Send(new NActors::IEventHandle(proxyId, clientId, new NHttp::TEvHttpProxy::TEvHttpOutgoingRequest(httpRequest)), 0, true);
-
- NHttp::TEvHttpProxy::TEvHttpIncomingResponse* response = actorSystem.GrabEdgeEvent<NHttp::TEvHttpProxy::TEvHttpIncomingResponse>(handle);
-
- UNIT_ASSERT_EQUAL(response->Response->Status, "400");
- UNIT_ASSERT_EQUAL(response->Response->Body, "Invalid http header");
- }
-}
+ actorSystem.Send(outgoingProxyId, new NHttp::TEvHttpProxy::TEvHttpOutgoingRequest("[::]:13337", std::move(httpRequest)));
+
+ Sleep(TDuration::Minutes(60));
+ }*/
+
+ Y_UNIT_TEST(TooLongHeader) {
+ NActors::TTestActorRuntimeBase actorSystem;
+ TPortManager portManager;
+ TIpPort port = portManager.GetTcpPort();
+ TAutoPtr<NActors::IEventHandle> handle;
+ actorSystem.Initialize();
+ NMonitoring::TMetricRegistry sensors;
+
+ NActors::IActor* proxy = NHttp::CreateHttpProxy(sensors);
+ NActors::TActorId proxyId = actorSystem.Register(proxy);
+ actorSystem.Send(new NActors::IEventHandle(proxyId, TActorId(), new NHttp::TEvHttpProxy::TEvAddListeningPort(port)), 0, true);
+ actorSystem.DispatchEvents();
+
+ NActors::TActorId serverId = actorSystem.AllocateEdgeActor();
+ actorSystem.Send(new NActors::IEventHandle(proxyId, serverId, new NHttp::TEvHttpProxy::TEvRegisterHandler("/test", serverId)), 0, true);
+
+ NActors::TActorId clientId = actorSystem.AllocateEdgeActor();
+ NHttp::THttpOutgoingRequestPtr httpRequest = NHttp::THttpOutgoingRequest::CreateRequestGet("http://[::1]:" + ToString(port) + "/test");
+ httpRequest->Set("Connection", "close");
+ TString longHeader;
+ longHeader.append(9000, 'X');
+ httpRequest->Set(longHeader, "data");
+ actorSystem.Send(new NActors::IEventHandle(proxyId, clientId, new NHttp::TEvHttpProxy::TEvHttpOutgoingRequest(httpRequest)), 0, true);
+
+ NHttp::TEvHttpProxy::TEvHttpIncomingResponse* response = actorSystem.GrabEdgeEvent<NHttp::TEvHttpProxy::TEvHttpIncomingResponse>(handle);
+
+ UNIT_ASSERT_EQUAL(response->Response->Status, "400");
+ UNIT_ASSERT_EQUAL(response->Response->Body, "Invalid http header");
+ }
+}
diff --git a/library/cpp/actors/http/ut/ya.make b/library/cpp/actors/http/ut/ya.make
index 12d360dabfa..8b4c04c4d3a 100644
--- a/library/cpp/actors/http/ut/ya.make
+++ b/library/cpp/actors/http/ut/ya.make
@@ -1,18 +1,18 @@
UNITTEST_FOR(library/cpp/actors/http)
-
-OWNER(xenoxeno)
-
-SIZE(SMALL)
-
-PEERDIR(
+
+OWNER(xenoxeno)
+
+SIZE(SMALL)
+
+PEERDIR(
library/cpp/actors/testlib
-)
-
+)
+
IF (NOT OS_WINDOWS)
-SRCS(
- http_ut.cpp
-)
+SRCS(
+ http_ut.cpp
+)
ELSE()
ENDIF()
-
-END()
+
+END()
diff --git a/library/cpp/actors/http/ya.make b/library/cpp/actors/http/ya.make
index 60c9c93a09d..7ce68b7a757 100644
--- a/library/cpp/actors/http/ya.make
+++ b/library/cpp/actors/http/ya.make
@@ -1,33 +1,33 @@
-RECURSE_FOR_TESTS(ut)
-
-LIBRARY()
-
-OWNER(xenoxeno g:kikimr)
-
-SRCS(
- http_cache.cpp
- http_cache.h
- http_config.h
- http_proxy_acceptor.cpp
- http_proxy_incoming.cpp
- http_proxy_outgoing.cpp
- http_proxy_sock_impl.h
- http_proxy_ssl.h
- http_proxy.cpp
- http_proxy.h
- http_static.cpp
- http_static.h
- http.cpp
- http.h
-)
-
-PEERDIR(
- contrib/libs/openssl
+RECURSE_FOR_TESTS(ut)
+
+LIBRARY()
+
+OWNER(xenoxeno g:kikimr)
+
+SRCS(
+ http_cache.cpp
+ http_cache.h
+ http_config.h
+ http_proxy_acceptor.cpp
+ http_proxy_incoming.cpp
+ http_proxy_outgoing.cpp
+ http_proxy_sock_impl.h
+ http_proxy_ssl.h
+ http_proxy.cpp
+ http_proxy.h
+ http_static.cpp
+ http_static.h
+ http.cpp
+ http.h
+)
+
+PEERDIR(
+ contrib/libs/openssl
library/cpp/actors/core
library/cpp/actors/interconnect
library/cpp/dns
library/cpp/monlib/metrics
library/cpp/string_utils/quote
-)
-
-END()
+)
+
+END()
diff --git a/library/cpp/actors/interconnect/interconnect_common.h b/library/cpp/actors/interconnect/interconnect_common.h
index 30e36c42421..285709a00cf 100644
--- a/library/cpp/actors/interconnect/interconnect_common.h
+++ b/library/cpp/actors/interconnect/interconnect_common.h
@@ -65,8 +65,8 @@ namespace NActors {
using TRegisterMonPageCallback = std::function<void(const TString& path, const TString& title,
TActorSystem* actorSystem, const TActorId& actorId)>;
- using TInitWhiteboardCallback = std::function<void(ui16 icPort, TActorSystem* actorSystem)>;
-
+ using TInitWhiteboardCallback = std::function<void(ui16 icPort, TActorSystem* actorSystem)>;
+
using TUpdateWhiteboardCallback = std::function<void(const TString& peer, bool connected, bool green, bool yellow,
bool orange, bool red, TActorSystem* actorSystem)>;
@@ -84,7 +84,7 @@ namespace NActors {
TVector<TString> AcceptUUID;
ui64 StartTime = GetCycleCountFast();
TString TechnicalSelfHostName;
- TInitWhiteboardCallback InitWhiteboard;
+ TInitWhiteboardCallback InitWhiteboard;
TUpdateWhiteboardCallback UpdateWhiteboard;
ui32 HandshakeBallastSize = 0;
TAtomic StartedSessionKiller = 0;
diff --git a/library/cpp/actors/interconnect/interconnect_tcp_server.cpp b/library/cpp/actors/interconnect/interconnect_tcp_server.cpp
index 557092a13cc..b95c994598d 100644
--- a/library/cpp/actors/interconnect/interconnect_tcp_server.cpp
+++ b/library/cpp/actors/interconnect/interconnect_tcp_server.cpp
@@ -79,9 +79,9 @@ namespace NActors {
return;
}
}
- if (const auto& callback = ProxyCommonCtx->InitWhiteboard) {
- callback(Address.GetPort(), TlsActivationContext->ExecutorThread.ActorSystem);
- }
+ if (const auto& callback = ProxyCommonCtx->InitWhiteboard) {
+ callback(Address.GetPort(), TlsActivationContext->ExecutorThread.ActorSystem);
+ }
const bool success = ctx.Send(MakePollerActorId(), new TEvPollerRegister(Listener, SelfId(), {}));
Y_VERIFY(success);
Become(&TThis::Listen);
diff --git a/library/cpp/actors/protos/interconnect.proto b/library/cpp/actors/protos/interconnect.proto
index 76885ef5bd3..2e3b0d0d15d 100644
--- a/library/cpp/actors/protos/interconnect.proto
+++ b/library/cpp/actors/protos/interconnect.proto
@@ -17,8 +17,8 @@ message TEvNodeInfo {
extend google.protobuf.FieldOptions {
optional string PrintName = 50376;
-}
-
+}
+
message TNodeLocation {
// compatibility section -- will be removed in future versions
optional uint32 DataCenterNum = 1 [deprecated=true];
diff --git a/library/cpp/actors/testlib/test_runtime.cpp b/library/cpp/actors/testlib/test_runtime.cpp
index 0010a1a1357..6fa25b99656 100644
--- a/library/cpp/actors/testlib/test_runtime.cpp
+++ b/library/cpp/actors/testlib/test_runtime.cpp
@@ -36,24 +36,24 @@ namespace NActors {
ui64 TScheduledEventQueueItem::NextUniqueId = 0;
void PrintEvent(TAutoPtr<IEventHandle>& ev, const TTestActorRuntimeBase* runtime) {
- Cerr << "mailbox: " << ev->GetRecipientRewrite().Hint() << ", type: " << Sprintf("%08x", ev->GetTypeRewrite())
- << ", from " << ev->Sender.LocalId();
+ Cerr << "mailbox: " << ev->GetRecipientRewrite().Hint() << ", type: " << Sprintf("%08x", ev->GetTypeRewrite())
+ << ", from " << ev->Sender.LocalId();
TString name = runtime->GetActorName(ev->Sender);
- if (!name.empty())
- Cerr << " \"" << name << "\"";
- Cerr << ", to " << ev->GetRecipientRewrite().LocalId();
- name = runtime->GetActorName(ev->GetRecipientRewrite());
- if (!name.empty())
- Cerr << " \"" << name << "\"";
- Cerr << ", ";
+ if (!name.empty())
+ Cerr << " \"" << name << "\"";
+ Cerr << ", to " << ev->GetRecipientRewrite().LocalId();
+ name = runtime->GetActorName(ev->GetRecipientRewrite());
+ if (!name.empty())
+ Cerr << " \"" << name << "\"";
+ Cerr << ", ";
if (ev->HasEvent())
- Cerr << " : " << (PRINT_EVENT_BODY ? ev->GetBase()->ToString() : ev->GetBase()->ToStringHeader());
+ Cerr << " : " << (PRINT_EVENT_BODY ? ev->GetBase()->ToString() : ev->GetBase()->ToStringHeader());
else if (ev->HasBuffer())
- Cerr << " : BUFFER";
+ Cerr << " : BUFFER";
else
- Cerr << " : EMPTY";
+ Cerr << " : EMPTY";
- Cerr << "\n";
+ Cerr << "\n";
}
TTestActorRuntimeBase::TNodeDataBase::TNodeDataBase() {
@@ -103,8 +103,8 @@ namespace NActors {
}
if (verbose) {
- Cerr << "Got event at " << TInstant::MicroSeconds(Runtime->CurrentTimestamp) << ", ";
- PrintEvent(ev, Runtime);
+ Cerr << "Got event at " << TInstant::MicroSeconds(Runtime->CurrentTimestamp) << ", ";
+ PrintEvent(ev, Runtime);
}
if (!Runtime->EventFilterFunc(*Runtime, ev)) {
@@ -114,11 +114,11 @@ namespace NActors {
Runtime->GetMailbox(nodeId, mailboxHint).Send(ev);
Runtime->MailboxesHasEvents.Signal();
if (verbose)
- Cerr << "Event was added to sent queue\n";
+ Cerr << "Event was added to sent queue\n";
}
else {
if (verbose)
- Cerr << "Event was dropped\n";
+ Cerr << "Event was dropped\n";
}
}
@@ -316,8 +316,8 @@ namespace NActors {
}
if (verbose) {
- Cerr << "Got scheduled event at " << TInstant::MicroSeconds(Runtime->CurrentTimestamp) << ", ";
- PrintEvent(ev, Runtime);
+ Cerr << "Got scheduled event at " << TInstant::MicroSeconds(Runtime->CurrentTimestamp) << ", ";
+ PrintEvent(ev, Runtime);
}
auto now = Runtime->GetTimeProvider()->Now();
@@ -331,13 +331,13 @@ namespace NActors {
Runtime->GetMailbox(Runtime->FirstNodeId + NodeIndex, mailboxHint).Schedule(TScheduledEventQueueItem(deadline, ev, cookie));
Runtime->MailboxesHasEvents.Signal();
if (verbose)
- Cerr << "Event was added to scheduled queue\n";
+ Cerr << "Event was added to scheduled queue\n";
} else {
if (cookie) {
cookie->Detach();
}
if (verbose) {
- Cerr << "Scheduled event for " << ev->GetRecipientRewrite().ToString() << " was dropped\n";
+ Cerr << "Scheduled event for " << ev->GetRecipientRewrite().ToString() << " was dropped\n";
}
}
}
@@ -351,8 +351,8 @@ namespace NActors {
}
if (verbose) {
- Cerr << "Got event at " << TInstant::MicroSeconds(Runtime->CurrentTimestamp) << ", ";
- PrintEvent(ev, Runtime);
+ Cerr << "Got event at " << TInstant::MicroSeconds(Runtime->CurrentTimestamp) << ", ";
+ PrintEvent(ev, Runtime);
}
if (!Runtime->EventFilterFunc(*Runtime, ev)) {
@@ -385,10 +385,10 @@ namespace NActors {
Runtime->MailboxesHasEvents.Signal();
}
if (verbose)
- Cerr << "Event was added to sent queue\n";
+ Cerr << "Event was added to sent queue\n";
} else {
if (verbose)
- Cerr << "Event was dropped\n";
+ Cerr << "Event was dropped\n";
}
return true;
}
@@ -462,7 +462,7 @@ namespace NActors {
, ClusterUUID(MakeClusterId())
, FirstNodeId(NextNodeId)
, NodeCount(nodeCount)
- , DataCenterCount(dataCenterCount)
+ , DataCenterCount(dataCenterCount)
, UseRealThreads(useRealThreads)
, LocalId(0)
, DispatchCyclesCount(0)
@@ -529,16 +529,16 @@ namespace NActors {
TTestActorRuntimeBase::TTestActorRuntimeBase(ui32 nodeCount, ui32 dataCenterCount)
: TTestActorRuntimeBase(nodeCount, dataCenterCount, false) {
- }
-
+ }
+
TTestActorRuntimeBase::TTestActorRuntimeBase(ui32 nodeCount, bool useRealThreads)
: TTestActorRuntimeBase(nodeCount, nodeCount, useRealThreads) {
- }
-
+ }
+
TTestActorRuntimeBase::~TTestActorRuntimeBase() {
CleanupNodes();
Cerr.Flush();
- Cerr.Flush();
+ Cerr.Flush();
Clog.Flush();
DisableActorCallstack();
@@ -582,58 +582,58 @@ namespace NActors {
void TTestActorRuntimeBase::DefaultRegistrationObserver(TTestActorRuntimeBase& runtime, const TActorId& parentId, const TActorId& actorId) {
if (runtime.ScheduleWhiteList.find(parentId) != runtime.ScheduleWhiteList.end()) {
runtime.ScheduleWhiteList.insert(actorId);
- runtime.ScheduleWhiteListParent[actorId] = parentId;
+ runtime.ScheduleWhiteListParent[actorId] = parentId;
}
}
- class TScheduledTreeItem {
- public:
+ class TScheduledTreeItem {
+ public:
TString Name;
- ui64 Count;
+ ui64 Count;
TVector<TScheduledTreeItem> Children;
-
+
TScheduledTreeItem(const TString& name)
- : Name(name)
- , Count(0)
- {}
-
+ : Name(name)
+ , Count(0)
+ {}
+
TScheduledTreeItem* GetItem(const TString& name) {
- TScheduledTreeItem* item = nullptr;
- for (TScheduledTreeItem& i : Children) {
- if (i.Name == name) {
- item = &i;
- break;
- }
- }
- if (item != nullptr)
- return item;
- Children.emplace_back(name);
- return &Children.back();
- }
-
- void RecursiveSort() {
- Sort(Children, [](const TScheduledTreeItem& a, const TScheduledTreeItem& b) -> bool { return a.Count > b.Count; });
- for (TScheduledTreeItem& item : Children) {
- item.RecursiveSort();
- }
- }
-
+ TScheduledTreeItem* item = nullptr;
+ for (TScheduledTreeItem& i : Children) {
+ if (i.Name == name) {
+ item = &i;
+ break;
+ }
+ }
+ if (item != nullptr)
+ return item;
+ Children.emplace_back(name);
+ return &Children.back();
+ }
+
+ void RecursiveSort() {
+ Sort(Children, [](const TScheduledTreeItem& a, const TScheduledTreeItem& b) -> bool { return a.Count > b.Count; });
+ for (TScheduledTreeItem& item : Children) {
+ item.RecursiveSort();
+ }
+ }
+
void Print(IOutputStream& stream, const TString& prefix) {
- for (auto it = Children.begin(); it != Children.end(); ++it) {
- bool lastChild = (std::next(it) == Children.end());
+ for (auto it = Children.begin(); it != Children.end(); ++it) {
+ bool lastChild = (std::next(it) == Children.end());
TString connectionPrefix = lastChild ? "└─ " : "├─ ";
TString subChildPrefix = lastChild ? " " : "│ ";
- stream << prefix << connectionPrefix << it->Name << " (" << it->Count << ")\n";
- it->Print(stream, prefix + subChildPrefix);
- }
- }
-
+ stream << prefix << connectionPrefix << it->Name << " (" << it->Count << ")\n";
+ it->Print(stream, prefix + subChildPrefix);
+ }
+ }
+
void Print(IOutputStream& stream) {
- stream << Name << " (" << Count << ")\n";
+ stream << Name << " (" << Count << ")\n";
Print(stream, TString());
- }
- };
-
+ }
+ };
+
void TTestActorRuntimeBase::CollapsedTimeScheduledEventsSelector(TTestActorRuntimeBase& runtime, TScheduledEventsList& scheduledEvents, TEventsList& queue) {
if (scheduledEvents.empty())
return;
@@ -641,30 +641,30 @@ namespace NActors {
TInstant time = scheduledEvents.begin()->Deadline;
while (!scheduledEvents.empty() && scheduledEvents.begin()->Deadline == time) {
static THashMap<std::pair<TActorId, TString>, ui64> eventTypes;
- auto& item = *scheduledEvents.begin();
+ auto& item = *scheduledEvents.begin();
TString name = item.Event->GetBase() ? TypeName(*item.Event->GetBase()) : Sprintf("%08" PRIx32, item.Event->Type);
eventTypes[std::make_pair(item.Event->Recipient, name)]++;
runtime.ScheduledCount++;
if (runtime.ScheduledCount > runtime.ScheduledLimit) {
-// TScheduledTreeItem root("Root");
+// TScheduledTreeItem root("Root");
// TVector<TString> path;
-// for (const auto& pr : eventTypes) {
-// path.clear();
-// path.push_back(runtime.GetActorName(pr.first.first));
-// for (auto it = runtime.ScheduleWhiteListParent.find(pr.first.first); it != runtime.ScheduleWhiteListParent.end(); it = runtime.ScheduleWhiteListParent.find(it->second)) {
-// path.insert(path.begin(), runtime.GetActorName(it->second));
-// }
-// path.push_back("<" + pr.first.second + ">"); // event name;
-// ui64 count = pr.second;
-// TScheduledTreeItem* item = &root;
-// item->Count += count;
+// for (const auto& pr : eventTypes) {
+// path.clear();
+// path.push_back(runtime.GetActorName(pr.first.first));
+// for (auto it = runtime.ScheduleWhiteListParent.find(pr.first.first); it != runtime.ScheduleWhiteListParent.end(); it = runtime.ScheduleWhiteListParent.find(it->second)) {
+// path.insert(path.begin(), runtime.GetActorName(it->second));
+// }
+// path.push_back("<" + pr.first.second + ">"); // event name;
+// ui64 count = pr.second;
+// TScheduledTreeItem* item = &root;
+// item->Count += count;
// for (TString name : path) {
-// item = item->GetItem(name);
-// item->Count += count;
-// }
-// }
-// root.RecursiveSort();
-// root.Print(Cerr);
+// item = item->GetItem(name);
+// item->Count += count;
+// }
+// }
+// root.RecursiveSort();
+// root.Print(Cerr);
ythrow TSchedulingLimitReachedException(runtime.ScheduledLimit);
}
@@ -755,10 +755,10 @@ namespace NActors {
IsInitialized = true;
}
- void SetupCrossDC() {
-
- }
-
+ void SetupCrossDC() {
+
+ }
+
TDuration TTestActorRuntimeBase::SetDispatchTimeout(TDuration timeout) {
TGuard<TMutex> guard(Mutex);
TDuration oldTimeout = DispatchTimeout;
@@ -798,11 +798,11 @@ namespace NActors {
}
void TTestActorRuntimeBase::UpdateCurrentTime(TInstant newTime) {
- static int counter = 0;
- ++counter;
- if (VERBOSE) {
- Cerr << "UpdateCurrentTime(" << counter << "," << newTime << ")\n";
- }
+ static int counter = 0;
+ ++counter;
+ if (VERBOSE) {
+ Cerr << "UpdateCurrentTime(" << counter << "," << newTime << ")\n";
+ }
TGuard<TMutex> guard(Mutex);
Y_VERIFY(!UseRealThreads);
if (newTime.MicroSeconds() > CurrentTimestamp) {
@@ -836,7 +836,7 @@ namespace NActors {
TGuard<TMutex> guard(Mutex);
ui64 nextId = ++LocalId;
if (VERBOSE) {
- Cerr << "Allocated id: " << nextId << "\n";
+ Cerr << "Allocated id: " << nextId << "\n";
}
return nextId;
@@ -1068,7 +1068,7 @@ namespace NActors {
const TDuration scheduledEventsInspectInterval = TDuration::MilliSeconds(10);
TInstant inspectScheduledEventsAt = dispatchTime + scheduledEventsInspectInterval;
if (verbose) {
- Cerr << "Start dispatch at " << TInstant::MicroSeconds(CurrentTimestamp) << ", deadline is " << deadline << "\n";
+ Cerr << "Start dispatch at " << TInstant::MicroSeconds(CurrentTimestamp) << ", deadline is " << deadline << "\n";
}
struct TTempEdgeEventsCaptor {
@@ -1181,14 +1181,14 @@ namespace NActors {
ythrow TWithBackTrace<yexception>() << "Dispatched "
<< DispatchedEventsLimit << " events, limit reached.";
}
-
+
auto ev = mbox.second->Pop();
- if (BlockedOutput.find(ev->Sender) == BlockedOutput.end()) {
- //UpdateCurrentTime(TInstant::MicroSeconds(CurrentTimestamp + 10));
- if (verbose) {
- Cerr << "Process event at " << TInstant::MicroSeconds(CurrentTimestamp) << ", ";
- PrintEvent(ev, this);
- }
+ if (BlockedOutput.find(ev->Sender) == BlockedOutput.end()) {
+ //UpdateCurrentTime(TInstant::MicroSeconds(CurrentTimestamp + 10));
+ if (verbose) {
+ Cerr << "Process event at " << TInstant::MicroSeconds(CurrentTimestamp) << ", ";
+ PrintEvent(ev, this);
+ }
}
hasProgress = true;
@@ -1263,7 +1263,7 @@ namespace NActors {
if (!mbox.second->IsEmpty()) {
if (verbose) {
- Cerr << "Dispatch complete with non-empty queue at " << TInstant::MicroSeconds(CurrentTimestamp) << "\n";
+ Cerr << "Dispatch complete with non-empty queue at " << TInstant::MicroSeconds(CurrentTimestamp) << "\n";
}
return true;
@@ -1277,7 +1277,7 @@ namespace NActors {
if (dispatchTime >= deadline) {
if (verbose) {
- Cerr << "Reach deadline at " << TInstant::MicroSeconds(CurrentTimestamp) << "\n";
+ Cerr << "Reach deadline at " << TInstant::MicroSeconds(CurrentTimestamp) << "\n";
}
ythrow TWithBackTrace<TEmptyEventQueueException>();
@@ -1319,8 +1319,8 @@ namespace NActors {
nextScheduleMbox->PushScheduled(capturedScheduledEvents);
for (auto& event : selectedEvents) {
if (verbose && (BlockedOutput.find(event->Sender) == BlockedOutput.end())) {
- Cerr << "Selected scheduled event at " << TInstant::MicroSeconds(CurrentTimestamp) << ", ";
- PrintEvent(event, this);
+ Cerr << "Selected scheduled event at " << TInstant::MicroSeconds(CurrentTimestamp) << ", ";
+ PrintEvent(event, this);
}
nextScheduleMbox->Send(event);
@@ -1330,7 +1330,7 @@ namespace NActors {
if (!isEmpty) {
if (verbose) {
- Cerr << "Process selected events at " << TInstant::MicroSeconds(CurrentTimestamp) << "\n";
+ Cerr << "Process selected events at " << TInstant::MicroSeconds(CurrentTimestamp) << "\n";
}
deadline = dispatchTime + DispatchTimeout;
@@ -1339,7 +1339,7 @@ namespace NActors {
if (nearestMailboxDeadline.Defined()) {
if (verbose) {
- Cerr << "Forward time to " << *nearestMailboxDeadline.Get() << "\n";
+ Cerr << "Forward time to " << *nearestMailboxDeadline.Get() << "\n";
}
UpdateCurrentTime(*nearestMailboxDeadline.Get());
@@ -1369,8 +1369,8 @@ namespace NActors {
void TTestActorRuntimeBase::UpdateFinalEventsStatsForEachContext(IEventHandle& ev) {
TDispatchContext* context = CurrentDispatchContext;
while (context) {
- for (const auto& finalEvent : context->Options->FinalEvents) {
- if (finalEvent.EventCheck(ev)) {
+ for (const auto& finalEvent : context->Options->FinalEvents) {
+ if (finalEvent.EventCheck(ev)) {
auto& freq = context->FinalEventFrequency[&finalEvent];
if (++freq >= finalEvent.RequiredCount) {
context->FinalEventFound = true;
@@ -1397,7 +1397,7 @@ namespace NActors {
TInstant deadline = TInstant::MicroSeconds(CurrentTimestamp) + duration;
GetMailbox(nodeId, mailboxHint).Schedule(TScheduledEventQueueItem(deadline, ev, nullptr));
if (VERBOSE)
- Cerr << "Event was added to scheduled queue\n";
+ Cerr << "Event was added to scheduled queue\n";
}
void TTestActorRuntimeBase::ClearCounters() {
@@ -1497,14 +1497,14 @@ namespace NActors {
void TTestActorRuntimeBase::EnableScheduleForActor(const TActorId& actorId, bool allow) {
TGuard<TMutex> guard(Mutex);
if (allow) {
- if (VERBOSE) {
- Cerr << "Actor " << actorId << " added to schedule whitelist";
- }
+ if (VERBOSE) {
+ Cerr << "Actor " << actorId << " added to schedule whitelist";
+ }
ScheduleWhiteList.insert(actorId);
} else {
- if (VERBOSE) {
- Cerr << "Actor " << actorId << " removed from schedule whitelist";
- }
+ if (VERBOSE) {
+ Cerr << "Actor " << actorId << " removed from schedule whitelist";
+ }
ScheduleWhiteList.erase(actorId);
}
}
@@ -1560,8 +1560,8 @@ namespace NActors {
ui64 recipientLocalId = ev->GetRecipientRewrite().LocalId();
if ((BlockedOutput.find(ev->Sender) == BlockedOutput.end()) && VERBOSE) {
- Cerr << "Send event, ";
- PrintEvent(evHolder, this);
+ Cerr << "Send event, ";
+ PrintEvent(evHolder, this);
}
EvCounters[ev->GetTypeRewrite()]++;
@@ -1589,7 +1589,7 @@ namespace NActors {
TlsActivationContext = prevTlsActivationContext;
} else {
if (VERBOSE) {
- Cerr << "Failed to find actor with local id: " << recipientLocalId << "\n";
+ Cerr << "Failed to find actor with local id: " << recipientLocalId << "\n";
}
auto forwardedEv = ev->ForwardOnNondelivery(TEvents::TEvUndelivered::ReasonActorUnknown);
@@ -1727,18 +1727,18 @@ namespace NActors {
}
void TTestActorRuntimeBase::ClearMailbox(ui32 nodeId, ui32 hint) {
- TGuard<TMutex> guard(Mutex);
- auto mboxId = TEventMailboxId(nodeId, hint);
- Mailboxes.erase(mboxId);
- }
-
+ TGuard<TMutex> guard(Mutex);
+ auto mboxId = TEventMailboxId(nodeId, hint);
+ Mailboxes.erase(mboxId);
+ }
+
TString TTestActorRuntimeBase::GetActorName(const TActorId& actorId) const {
- auto it = ActorNames.find(actorId);
- if (it != ActorNames.end())
- return it->second;
- return actorId.ToString();
- }
-
+ auto it = ActorNames.find(actorId);
+ if (it != ActorNames.end())
+ return it->second;
+ return actorId.ToString();
+ }
+
struct TStrandingActorDecoratorContext : public TThrRefBase {
TStrandingActorDecoratorContext()
: Queue(new TQueueType)
diff --git a/library/cpp/actors/testlib/test_runtime.h b/library/cpp/actors/testlib/test_runtime.h
index 589309afd76..26e3b45c984 100644
--- a/library/cpp/actors/testlib/test_runtime.h
+++ b/library/cpp/actors/testlib/test_runtime.h
@@ -74,20 +74,20 @@ namespace NActors {
struct TDispatchOptions {
struct TFinalEventCondition {
- std::function<bool(IEventHandle& ev)> EventCheck;
+ std::function<bool(IEventHandle& ev)> EventCheck;
ui32 RequiredCount;
TFinalEventCondition(ui32 eventType, ui32 requiredCount = 1)
- : EventCheck([eventType](IEventHandle& ev) -> bool { return ev.GetTypeRewrite() == eventType; })
+ : EventCheck([eventType](IEventHandle& ev) -> bool { return ev.GetTypeRewrite() == eventType; })
+ , RequiredCount(requiredCount)
+ {
+ }
+
+ TFinalEventCondition(std::function<bool(IEventHandle& ev)> eventCheck, ui32 requiredCount = 1)
+ : EventCheck(eventCheck)
, RequiredCount(requiredCount)
{
}
-
- TFinalEventCondition(std::function<bool(IEventHandle& ev)> eventCheck, ui32 requiredCount = 1)
- : EventCheck(eventCheck)
- , RequiredCount(requiredCount)
- {
- }
};
TVector<TFinalEventCondition> FinalEvents;
@@ -359,14 +359,14 @@ namespace NActors {
return GrabEdgeEventIf(handle, truth, simTimeout);
}
- template <typename TEvent>
- THolder<TEvent> GrabEdgeEvent(TDuration simTimeout = TDuration::Max()) {
- TAutoPtr<IEventHandle> handle;
- std::function<bool(const TEvent&)> truth = [](const TEvent&) { return true; };
- GrabEdgeEventIf(handle, truth, simTimeout);
+ template <typename TEvent>
+ THolder<TEvent> GrabEdgeEvent(TDuration simTimeout = TDuration::Max()) {
+ TAutoPtr<IEventHandle> handle;
+ std::function<bool(const TEvent&)> truth = [](const TEvent&) { return true; };
+ GrabEdgeEventIf(handle, truth, simTimeout);
return THolder(handle ? handle->Release<TEvent>().Release() : nullptr);
- }
-
+ }
+
template<class TEvent>
typename TEvent::TPtr GrabEdgeEvent(const TSet<TActorId>& edgeFilter, TDuration simTimeout = TDuration::Max()) {
return GrabEdgeEventIf<TEvent>(edgeFilter, [](const typename TEvent::TPtr&) { return true; }, simTimeout);
@@ -378,33 +378,33 @@ namespace NActors {
return GrabEdgeEvent<TEvent>(edgeFilter, simTimeout);
}
- // replace with std::variant<>
- template <typename... TEvents>
- std::tuple<TEvents*...> GrabEdgeEvents(TAutoPtr<IEventHandle>& handle, TDuration simTimeout = TDuration::Max()) {
- handle.Destroy();
- auto eventTypes = { TEvents::EventType... };
+ // replace with std::variant<>
+ template <typename... TEvents>
+ std::tuple<TEvents*...> GrabEdgeEvents(TAutoPtr<IEventHandle>& handle, TDuration simTimeout = TDuration::Max()) {
+ handle.Destroy();
+ auto eventTypes = { TEvents::EventType... };
WaitForEdgeEvents([&](TTestActorRuntimeBase&, TAutoPtr<IEventHandle>& event) {
- if (std::find(std::begin(eventTypes), std::end(eventTypes), event->GetTypeRewrite()) == std::end(eventTypes))
- return false;
- handle = event;
- return true;
+ if (std::find(std::begin(eventTypes), std::end(eventTypes), event->GetTypeRewrite()) == std::end(eventTypes))
+ return false;
+ handle = event;
+ return true;
}, {}, simTimeout);
- if (simTimeout == TDuration::Max())
- Y_VERIFY(handle);
- if (handle) {
- return std::make_tuple(handle->Type == TEvents::EventType
- ? reinterpret_cast<TAutoPtr<TEventHandle<TEvents>>&>(handle)->Get()
- : static_cast<TEvents*>(nullptr)...);
- }
- return {};
- }
-
+ if (simTimeout == TDuration::Max())
+ Y_VERIFY(handle);
+ if (handle) {
+ return std::make_tuple(handle->Type == TEvents::EventType
+ ? reinterpret_cast<TAutoPtr<TEventHandle<TEvents>>&>(handle)->Get()
+ : static_cast<TEvents*>(nullptr)...);
+ }
+ return {};
+ }
+
template <typename TEvent>
TEvent* GrabEdgeEventRethrow(TAutoPtr<IEventHandle>& handle, TDuration simTimeout = TDuration::Max()) {
try {
return GrabEdgeEvent<TEvent>(handle, simTimeout);
} catch (...) {
- ythrow TWithBackTrace<yexception>() << "Exception occured while waiting for " << TypeName<TEvent>() << ": " << CurrentExceptionMessage();
+ ythrow TWithBackTrace<yexception>() << "Exception occured while waiting for " << TypeName<TEvent>() << ": " << CurrentExceptionMessage();
}
}
@@ -426,33 +426,33 @@ namespace NActors {
}
}
- template <typename... TEvents>
+ template <typename... TEvents>
static TString TypeNames() {
static TString names[] = { TypeName<TEvents>()... };
TString result;
for (const TString& s : names) {
- if (result.empty()) {
- result += '<';
- } else {
- result += ',';
- }
- result += s;
- }
- if (!result.empty()) {
- result += '>';
- }
- return result;
- }
-
- template <typename... TEvents>
- std::tuple<TEvents*...> GrabEdgeEventsRethrow(TAutoPtr<IEventHandle>& handle, TDuration simTimeout = TDuration::Max()) {
- try {
- return GrabEdgeEvents<TEvents...>(handle, simTimeout);
- } catch (...) {
- ythrow TWithBackTrace<yexception>() << "Exception occured while waiting for " << TypeNames<TEvents...>() << ": " << CurrentExceptionMessage();
- }
- }
-
+ if (result.empty()) {
+ result += '<';
+ } else {
+ result += ',';
+ }
+ result += s;
+ }
+ if (!result.empty()) {
+ result += '>';
+ }
+ return result;
+ }
+
+ template <typename... TEvents>
+ std::tuple<TEvents*...> GrabEdgeEventsRethrow(TAutoPtr<IEventHandle>& handle, TDuration simTimeout = TDuration::Max()) {
+ try {
+ return GrabEdgeEvents<TEvents...>(handle, simTimeout);
+ } catch (...) {
+ ythrow TWithBackTrace<yexception>() << "Exception occured while waiting for " << TypeNames<TEvents...>() << ": " << CurrentExceptionMessage();
+ }
+ }
+
void ResetScheduledCount() {
ScheduledCount = 0;
}
@@ -496,7 +496,7 @@ namespace NActors {
IActor* FindActor(const TActorId& actorId, TNodeDataBase* node) const;
void SendInternal(IEventHandle* ev, ui32 nodeIndex, bool viaActorSystem);
TEventMailBox& GetMailbox(ui32 nodeId, ui32 hint);
- void ClearMailbox(ui32 nodeId, ui32 hint);
+ void ClearMailbox(ui32 nodeId, ui32 hint);
void HandleNonEmptyMailboxesForEachContext(TEventMailboxId mboxId);
void UpdateFinalEventsStatsForEachContext(IEventHandle& ev);
bool DispatchEventsInternal(const TDispatchOptions& options, TInstant simDeadline);
@@ -515,7 +515,7 @@ namespace NActors {
const TString ClusterUUID;
const ui32 FirstNodeId;
const ui32 NodeCount;
- const ui32 DataCenterCount;
+ const ui32 DataCenterCount;
const bool UseRealThreads;
ui64 LocalId;
diff --git a/library/cpp/grpc/client/grpc_client_low.h b/library/cpp/grpc/client/grpc_client_low.h
index d5ffe74736a..ab0a0627be0 100644
--- a/library/cpp/grpc/client/grpc_client_low.h
+++ b/library/cpp/grpc/client/grpc_client_low.h
@@ -126,7 +126,7 @@ public:
// Represents grpc status and error message string
struct TGrpcStatus {
TString Msg;
- TString Details;
+ TString Details;
int GRpcStatusCode;
bool InternalError;
@@ -141,20 +141,20 @@ struct TGrpcStatus {
, InternalError(internalError)
{ }
- TGrpcStatus(grpc::StatusCode status, TString msg, TString details = {})
+ TGrpcStatus(grpc::StatusCode status, TString msg, TString details = {})
: Msg(std::move(msg))
- , Details(std::move(details))
+ , Details(std::move(details))
, GRpcStatusCode(status)
, InternalError(false)
{ }
TGrpcStatus(const grpc::Status& status)
- : TGrpcStatus(status.error_code(), TString(status.error_message()), TString(status.error_details()))
+ : TGrpcStatus(status.error_code(), TString(status.error_message()), TString(status.error_details()))
{ }
TGrpcStatus& operator=(const grpc::Status& status) {
Msg = TString(status.error_message());
- Details = TString(status.error_details());
+ Details = TString(status.error_details());
GRpcStatusCode = status.error_code();
InternalError = false;
return *this;
@@ -178,9 +178,9 @@ bool inline IsGRpcStatusGood(const TGrpcStatus& status) {
template<typename TResponse>
using TResponseCallback = std::function<void (TGrpcStatus&&, TResponse&&)>;
-template<typename TResponse>
-using TAdvancedResponseCallback = std::function<void (const grpc::ClientContext&, TGrpcStatus&&, TResponse&&)>;
-
+template<typename TResponse>
+using TAdvancedResponseCallback = std::function<void (const grpc::ClientContext&, TGrpcStatus&&, TResponse&&)>;
+
// Call associated metadata
struct TCallMeta {
std::shared_ptr<grpc::CallCredentials> CallCredentials;
@@ -305,86 +305,86 @@ private:
bool Replied_ = false;
};
-template<typename TStub, typename TRequest, typename TResponse>
-class TAdvancedRequestProcessor
- : public TThrRefBase
- , public IQueueClientEvent
- , public TGRpcRequestProcessorCommon {
- using TAsyncReaderPtr = std::unique_ptr<grpc::ClientAsyncResponseReader<TResponse>>;
- template<typename> friend class TServiceConnection;
-public:
- using TPtr = TIntrusivePtr<TAdvancedRequestProcessor>;
- using TAsyncRequest = TAsyncReaderPtr (TStub::*)(grpc::ClientContext*, const TRequest&, grpc::CompletionQueue*);
-
+template<typename TStub, typename TRequest, typename TResponse>
+class TAdvancedRequestProcessor
+ : public TThrRefBase
+ , public IQueueClientEvent
+ , public TGRpcRequestProcessorCommon {
+ using TAsyncReaderPtr = std::unique_ptr<grpc::ClientAsyncResponseReader<TResponse>>;
+ template<typename> friend class TServiceConnection;
+public:
+ using TPtr = TIntrusivePtr<TAdvancedRequestProcessor>;
+ using TAsyncRequest = TAsyncReaderPtr (TStub::*)(grpc::ClientContext*, const TRequest&, grpc::CompletionQueue*);
+
explicit TAdvancedRequestProcessor(TAdvancedResponseCallback<TResponse>&& callback)
: Callback_(std::move(callback))
- { }
-
- ~TAdvancedRequestProcessor() {
- if (!Replied_ && Callback_) {
- Callback_(Context, TGrpcStatus::Internal("request left unhandled"), std::move(Reply_));
- Callback_ = nullptr; // free resources as early as possible
- }
- }
-
- bool Execute(bool ok) override {
+ { }
+
+ ~TAdvancedRequestProcessor() {
+ if (!Replied_ && Callback_) {
+ Callback_(Context, TGrpcStatus::Internal("request left unhandled"), std::move(Reply_));
+ Callback_ = nullptr; // free resources as early as possible
+ }
+ }
+
+ bool Execute(bool ok) override {
{
std::unique_lock<std::mutex> guard(Mutex_);
- LocalContext.reset();
- }
- TGrpcStatus status;
- if (ok) {
- status = Status;
- } else {
- status = TGrpcStatus::Internal("Unexpected error");
- }
- Replied_ = true;
- Callback_(Context, std::move(status), std::move(Reply_));
- Callback_ = nullptr; // free resources as early as possible
- return false;
- }
-
- void Destroy() override {
- UnRef();
- }
-
-private:
- IQueueClientEvent* FinishedEvent() {
- Ref();
- return this;
- }
-
- void Start(TStub& stub, TAsyncRequest asyncRequest, const TRequest& request, IQueueClientContextProvider* provider) {
- auto context = provider->CreateContext();
- if (!context) {
- Replied_ = true;
- Callback_(Context, TGrpcStatus(grpc::StatusCode::CANCELLED, "Client is shutting down"), std::move(Reply_));
- Callback_ = nullptr;
- return;
- }
+ LocalContext.reset();
+ }
+ TGrpcStatus status;
+ if (ok) {
+ status = Status;
+ } else {
+ status = TGrpcStatus::Internal("Unexpected error");
+ }
+ Replied_ = true;
+ Callback_(Context, std::move(status), std::move(Reply_));
+ Callback_ = nullptr; // free resources as early as possible
+ return false;
+ }
+
+ void Destroy() override {
+ UnRef();
+ }
+
+private:
+ IQueueClientEvent* FinishedEvent() {
+ Ref();
+ return this;
+ }
+
+ void Start(TStub& stub, TAsyncRequest asyncRequest, const TRequest& request, IQueueClientContextProvider* provider) {
+ auto context = provider->CreateContext();
+ if (!context) {
+ Replied_ = true;
+ Callback_(Context, TGrpcStatus(grpc::StatusCode::CANCELLED, "Client is shutting down"), std::move(Reply_));
+ Callback_ = nullptr;
+ return;
+ }
{
std::unique_lock<std::mutex> guard(Mutex_);
- LocalContext = context;
- Reader_ = (stub.*asyncRequest)(&Context, request, context->CompletionQueue());
- Reader_->Finish(&Reply_, &Status, FinishedEvent());
- }
- context->SubscribeStop([self = TPtr(this)] {
- self->Stop();
- });
- }
-
- void Stop() {
- Context.TryCancel();
- }
-
- TAdvancedResponseCallback<TResponse> Callback_;
- TResponse Reply_;
+ LocalContext = context;
+ Reader_ = (stub.*asyncRequest)(&Context, request, context->CompletionQueue());
+ Reader_->Finish(&Reply_, &Status, FinishedEvent());
+ }
+ context->SubscribeStop([self = TPtr(this)] {
+ self->Stop();
+ });
+ }
+
+ void Stop() {
+ Context.TryCancel();
+ }
+
+ TAdvancedResponseCallback<TResponse> Callback_;
+ TResponse Reply_;
std::mutex Mutex_;
- TAsyncReaderPtr Reader_;
-
- bool Replied_ = false;
-};
-
+ TAsyncReaderPtr Reader_;
+
+ bool Replied_ = false;
+};
+
template<class TResponse>
class IStreamRequestReadProcessor : public TThrRefBase {
public:
@@ -1255,21 +1255,21 @@ public:
}
/*
- * Start simple request
- */
- template<typename TRequest, typename TResponse>
- void DoAdvancedRequest(const TRequest& request,
+ * Start simple request
+ */
+ template<typename TRequest, typename TResponse>
+ void DoAdvancedRequest(const TRequest& request,
TAdvancedResponseCallback<TResponse> callback,
- typename TAdvancedRequestProcessor<TStub, TRequest, TResponse>::TAsyncRequest asyncRequest,
- const TCallMeta& metas = { },
- IQueueClientContextProvider* provider = nullptr)
- {
- auto processor = MakeIntrusive<TAdvancedRequestProcessor<TStub, TRequest, TResponse>>(std::move(callback));
- processor->ApplyMeta(metas);
- processor->Start(*Stub_, asyncRequest, request, provider ? provider : Provider_);
- }
-
- /*
+ typename TAdvancedRequestProcessor<TStub, TRequest, TResponse>::TAsyncRequest asyncRequest,
+ const TCallMeta& metas = { },
+ IQueueClientContextProvider* provider = nullptr)
+ {
+ auto processor = MakeIntrusive<TAdvancedRequestProcessor<TStub, TRequest, TResponse>>(std::move(callback));
+ processor->ApplyMeta(metas);
+ processor->Start(*Stub_, asyncRequest, request, provider ? provider : Provider_);
+ }
+
+ /*
* Start bidirectional streamming
*/
template<typename TRequest, typename TResponse>
diff --git a/library/cpp/http/fetch/httpagent.h b/library/cpp/http/fetch/httpagent.h
index 10696b6a3ad..96475cc05d9 100644
--- a/library/cpp/http/fetch/httpagent.h
+++ b/library/cpp/http/fetch/httpagent.h
@@ -1,316 +1,316 @@
-#pragma once
-
-#include <cstdio>
-#include <cstring>
-#include <cstdlib>
-
-#include <library/cpp/uri/http_url.h>
-#include <util/datetime/base.h>
-#include <util/network/hostip.h>
-#include <util/network/ip.h>
-#include <util/network/sock.h>
-#include <util/generic/scope.h>
-#include <util/generic/utility.h>
-#include <util/string/cast.h>
-
-#include "exthttpcodes.h"
-#include "sockhandler.h"
-
-class TIpResolver {
-public:
- TAddrList Resolve(const char* host, TIpPort port) const {
- try {
- TAddrList result;
- TNetworkAddress na(host, port);
- for (auto i = na.Begin(); i != na.End(); ++i) {
- const struct addrinfo& ai = *i;
- switch (ai.ai_family) {
- case AF_INET:
- result.push_back(new NAddr::TIPv4Addr(*(sockaddr_in*)ai.ai_addr));
- break;
- case AF_INET6:
- result.push_back(new NAddr::TIPv6Addr(*(sockaddr_in6*)ai.ai_addr));
- break;
- }
- }
- return result;
- } catch (const TNetworkResolutionError&) {
- }
- return TAddrList();
- }
-};
-
-namespace NResolverHelpers {
- Y_HAS_MEMBER(Resolve);
-
- template <typename TResolver>
- std::enable_if_t<TClassHasResolve<TResolver>::value, TAddrList> Resolve(const TResolver& r, const char* host, TIpPort port) {
- return r.Resolve(host, port);
- }
-
- template <typename TResolver>
- std::enable_if_t<!TClassHasResolve<TResolver>::value, TAddrList> Resolve(const TResolver& r, const char* host, TIpPort port) {
- ui32 ip = 0;
- if (r.GetHostIP(host, &ip)) {
- // error
- return TAddrList();
- }
- if (!ip) {
- return TAddrList();
- }
-
- return TAddrList::MakeV4Addr(ip, port);
- }
-}
-
-template <typename TBase>
-class TIpResolverWrapper {
-private:
- TBase Base;
-
-public:
- TIpResolverWrapper() = default;
-
- template <typename T>
- TIpResolverWrapper(T&& base)
- : Base(std::forward(base))
- {
- }
-
- TAddrList Resolve(const char* host, TIpPort port) const {
- return NResolverHelpers::Resolve(Base, host, port);
- }
-};
-
-template <class TSocketHandler = TSimpleSocketHandler, class TDnsClient = TIpResolver>
-class THttpAgent {
-public:
- THttpAgent()
- : Persistent(0)
- , Timeout(TDuration::MicroSeconds(150))
- , Hostheader(nullptr)
- , Footer(nullptr)
- , AltFooter(nullptr)
- , PostData(nullptr)
- , PostDataLen(0)
- , Method(nullptr)
- , MethodLen(0)
- , HostheaderLen(0)
- {
- SetIdentification("YandexSomething/1.0", "webadmin@yandex.ru");
- }
-
- ~THttpAgent() {
- Disconnect();
- free(Hostheader);
- free(Footer);
- }
-
- void SetIdentification(const char* user_agent, const char* http_from) {
- free(Footer);
- size_t len = user_agent ? strlen(user_agent) + 15 : 0;
- len += http_from ? strlen(http_from) + 9 : 0;
- len += 3;
- Footer = (char*)malloc(len);
- if (user_agent)
- strcat(strcat(strcpy(Footer, "User-Agent: "), user_agent), "\r\n");
- if (http_from)
- strcat(strcat(strcat(Footer, "From: "), http_from), "\r\n");
- }
-
- void SetUserAgentFooter(const char* altFooter) {
- AltFooter = altFooter;
- }
-
- void SetPostData(const char* postData, size_t postDataLen) {
- PostData = postData;
- PostDataLen = postDataLen;
- }
-
- void SetMethod(const char* method, size_t methodLen) {
- Method = method;
- MethodLen = methodLen;
- }
-
- // deprecated
- ui32 GetIp() const {
- return Addrs.GetV4Addr().first;
- }
-
- int GetScheme() const {
- return THttpURL::SchemeHTTP;
- }
- void SetTimeout(TDuration tim) {
- Timeout = tim;
- }
-
- void SetConnectTimeout(TDuration timeout) {
- ConnectTimeout = timeout;
- }
-
- int Disconnected() {
- return !Persistent || !Socket.Good();
- }
-
- int SetHost(const char* hostname, TIpPort port) {
- Disconnect();
- TAddrList addrs = DnsClient.Resolve(hostname, port);
- if (!addrs.size()) {
- return 1;
- }
-
- SetHost(hostname, port, addrs);
- return 0;
- }
-
- int SetHost(const char* hostname, TIpPort port, const TAddrList& addrs) {
- Disconnect();
- Addrs = addrs;
- size_t reqHostheaderLen = strlen(hostname) + 20;
- if (HostheaderLen < reqHostheaderLen) {
- free(Hostheader);
- Hostheader = (char*)malloc((HostheaderLen = reqHostheaderLen));
- }
- if (port == 80)
- sprintf(Hostheader, "Host: %s\r\n", hostname);
- else
- sprintf(Hostheader, "Host: %s:%u\r\n", hostname, port);
- pHostBeg = strchr(Hostheader, ' ') + 1;
- pHostEnd = strchr(pHostBeg, '\r');
- // convert hostname to lower case since some web server don't like
- // uppper case (Task ROBOT-562)
- for (char* p = pHostBeg; p < pHostEnd; p++)
- *p = tolower(*p);
- return 0;
- }
-
- // deprecated v4-only
- int SetHost(const char* hostname, TIpPort port, ui32 ip) {
- return SetHost(hostname, port, TAddrList::MakeV4Addr(ip, port));
- }
-
- void SetHostHeader(const char* host) {
- size_t reqHostheaderLen = strlen(host) + 20;
- if (HostheaderLen < reqHostheaderLen) {
- delete[] Hostheader;
- Hostheader = new char[(HostheaderLen = reqHostheaderLen)];
- }
- sprintf(Hostheader, "Host: %s\r\n", host);
- }
-
- void SetSocket(SOCKET fd) {
- Socket.SetSocket(fd);
- }
-
- SOCKET PickOutSocket() {
- return Socket.PickOutSocket();
- }
-
- void Disconnect() {
- Socket.Disconnect();
- }
-
- ssize_t read(void* buffer, size_t buflen) {
- return Socket.read(buffer, buflen);
- }
-
- int RequestGet(const char* url, const char* const* headers, int persistent = 1, bool head_request = false) {
- if (!Addrs.size())
- return HTTP_DNS_FAILURE;
- char message[MessageMax];
- ssize_t messlen = 0;
- if (Method) {
- strncpy(message, Method, MethodLen);
- message[MethodLen] = ' ';
- messlen = MethodLen + 1;
- } else if (PostData) {
- strcpy(message, "POST ");
- messlen = 5;
- } else if (head_request) {
- strcpy(message, "HEAD ");
- messlen = 5;
- } else {
- strcpy(message, "GET ");
- messlen = 4;
- }
-#define _AppendMessage(mes) messlen += Min(MessageMax - messlen, \
- (ssize_t)strlcpy(message + messlen, (mes), MessageMax - messlen))
- _AppendMessage(url);
- _AppendMessage(" HTTP/1.1\r\n");
- if (*url == '/') //if not then Host is a proxy
- _AppendMessage(Hostheader);
- _AppendMessage("Connection: ");
- _AppendMessage(persistent ? "Keep-Alive\r\n" : "Close\r\n");
- while (headers && *headers)
- _AppendMessage(*headers++);
- if (AltFooter)
- _AppendMessage(AltFooter);
- else
- _AppendMessage(Footer);
- _AppendMessage("\r\n");
-#undef _AppendMessage
- if (messlen >= MessageMax)
- return HTTP_HEADER_TOO_LARGE;
-
- if (!Persistent)
- Disconnect();
- Persistent = persistent;
- int connected = Socket.Good();
- for (int attempt = !connected; attempt < 2; attempt++) {
- const auto connectTimeout = ConnectTimeout ? ConnectTimeout : Timeout;
- if (!Socket.Good() && Socket.Connect(Addrs, connectTimeout))
- return HTTP_CONNECT_FAILED;
-
- int sendOk = Socket.send(message, messlen);
- if (sendOk && PostData && PostDataLen)
- sendOk = Socket.send(PostData, PostDataLen);
- if (!sendOk) {
- int err = errno;
- Disconnect();
- errno = err;
- continue;
- }
-
- if (!Socket.peek()) {
- int err = errno;
- Disconnect();
- if (err == EINTR) {
- errno = err;
- return HTTP_INTERRUPTED;
- }
- } else {
- if (!persistent)
- Socket.shutdown();
- return 0;
- }
- }
- return connected ? HTTP_CONNECTION_LOST : HTTP_CONNECT_FAILED;
- }
-
-protected:
- TSocketHandler Socket;
- TIpResolverWrapper<TDnsClient> DnsClient;
- TAddrList Addrs;
- int Persistent;
- TDuration Timeout;
- TDuration ConnectTimeout;
- char *Hostheader, *Footer, *pHostBeg, *pHostEnd;
- const char* AltFooter; // alternative footer can be set by the caller
- const char* PostData;
- size_t PostDataLen;
- const char* Method;
- size_t MethodLen;
- unsigned short HostheaderLen;
+#pragma once
+
+#include <cstdio>
+#include <cstring>
+#include <cstdlib>
+
+#include <library/cpp/uri/http_url.h>
+#include <util/datetime/base.h>
+#include <util/network/hostip.h>
+#include <util/network/ip.h>
+#include <util/network/sock.h>
+#include <util/generic/scope.h>
+#include <util/generic/utility.h>
+#include <util/string/cast.h>
+
+#include "exthttpcodes.h"
+#include "sockhandler.h"
+
+class TIpResolver {
+public:
+ TAddrList Resolve(const char* host, TIpPort port) const {
+ try {
+ TAddrList result;
+ TNetworkAddress na(host, port);
+ for (auto i = na.Begin(); i != na.End(); ++i) {
+ const struct addrinfo& ai = *i;
+ switch (ai.ai_family) {
+ case AF_INET:
+ result.push_back(new NAddr::TIPv4Addr(*(sockaddr_in*)ai.ai_addr));
+ break;
+ case AF_INET6:
+ result.push_back(new NAddr::TIPv6Addr(*(sockaddr_in6*)ai.ai_addr));
+ break;
+ }
+ }
+ return result;
+ } catch (const TNetworkResolutionError&) {
+ }
+ return TAddrList();
+ }
+};
+
+namespace NResolverHelpers {
+ Y_HAS_MEMBER(Resolve);
+
+ template <typename TResolver>
+ std::enable_if_t<TClassHasResolve<TResolver>::value, TAddrList> Resolve(const TResolver& r, const char* host, TIpPort port) {
+ return r.Resolve(host, port);
+ }
+
+ template <typename TResolver>
+ std::enable_if_t<!TClassHasResolve<TResolver>::value, TAddrList> Resolve(const TResolver& r, const char* host, TIpPort port) {
+ ui32 ip = 0;
+ if (r.GetHostIP(host, &ip)) {
+ // error
+ return TAddrList();
+ }
+ if (!ip) {
+ return TAddrList();
+ }
+
+ return TAddrList::MakeV4Addr(ip, port);
+ }
+}
+
+template <typename TBase>
+class TIpResolverWrapper {
+private:
+ TBase Base;
+
+public:
+ TIpResolverWrapper() = default;
+
+ template <typename T>
+ TIpResolverWrapper(T&& base)
+ : Base(std::forward(base))
+ {
+ }
+
+ TAddrList Resolve(const char* host, TIpPort port) const {
+ return NResolverHelpers::Resolve(Base, host, port);
+ }
+};
+
+template <class TSocketHandler = TSimpleSocketHandler, class TDnsClient = TIpResolver>
+class THttpAgent {
+public:
+ THttpAgent()
+ : Persistent(0)
+ , Timeout(TDuration::MicroSeconds(150))
+ , Hostheader(nullptr)
+ , Footer(nullptr)
+ , AltFooter(nullptr)
+ , PostData(nullptr)
+ , PostDataLen(0)
+ , Method(nullptr)
+ , MethodLen(0)
+ , HostheaderLen(0)
+ {
+ SetIdentification("YandexSomething/1.0", "webadmin@yandex.ru");
+ }
+
+ ~THttpAgent() {
+ Disconnect();
+ free(Hostheader);
+ free(Footer);
+ }
+
+ void SetIdentification(const char* user_agent, const char* http_from) {
+ free(Footer);
+ size_t len = user_agent ? strlen(user_agent) + 15 : 0;
+ len += http_from ? strlen(http_from) + 9 : 0;
+ len += 3;
+ Footer = (char*)malloc(len);
+ if (user_agent)
+ strcat(strcat(strcpy(Footer, "User-Agent: "), user_agent), "\r\n");
+ if (http_from)
+ strcat(strcat(strcat(Footer, "From: "), http_from), "\r\n");
+ }
+
+ void SetUserAgentFooter(const char* altFooter) {
+ AltFooter = altFooter;
+ }
+
+ void SetPostData(const char* postData, size_t postDataLen) {
+ PostData = postData;
+ PostDataLen = postDataLen;
+ }
+
+ void SetMethod(const char* method, size_t methodLen) {
+ Method = method;
+ MethodLen = methodLen;
+ }
+
+ // deprecated
+ ui32 GetIp() const {
+ return Addrs.GetV4Addr().first;
+ }
+
+ int GetScheme() const {
+ return THttpURL::SchemeHTTP;
+ }
+ void SetTimeout(TDuration tim) {
+ Timeout = tim;
+ }
+
+ void SetConnectTimeout(TDuration timeout) {
+ ConnectTimeout = timeout;
+ }
+
+ int Disconnected() {
+ return !Persistent || !Socket.Good();
+ }
+
+ int SetHost(const char* hostname, TIpPort port) {
+ Disconnect();
+ TAddrList addrs = DnsClient.Resolve(hostname, port);
+ if (!addrs.size()) {
+ return 1;
+ }
+
+ SetHost(hostname, port, addrs);
+ return 0;
+ }
+
+ int SetHost(const char* hostname, TIpPort port, const TAddrList& addrs) {
+ Disconnect();
+ Addrs = addrs;
+ size_t reqHostheaderLen = strlen(hostname) + 20;
+ if (HostheaderLen < reqHostheaderLen) {
+ free(Hostheader);
+ Hostheader = (char*)malloc((HostheaderLen = reqHostheaderLen));
+ }
+ if (port == 80)
+ sprintf(Hostheader, "Host: %s\r\n", hostname);
+ else
+ sprintf(Hostheader, "Host: %s:%u\r\n", hostname, port);
+ pHostBeg = strchr(Hostheader, ' ') + 1;
+ pHostEnd = strchr(pHostBeg, '\r');
+ // convert hostname to lower case since some web server don't like
+ // uppper case (Task ROBOT-562)
+ for (char* p = pHostBeg; p < pHostEnd; p++)
+ *p = tolower(*p);
+ return 0;
+ }
+
+ // deprecated v4-only
+ int SetHost(const char* hostname, TIpPort port, ui32 ip) {
+ return SetHost(hostname, port, TAddrList::MakeV4Addr(ip, port));
+ }
+
+ void SetHostHeader(const char* host) {
+ size_t reqHostheaderLen = strlen(host) + 20;
+ if (HostheaderLen < reqHostheaderLen) {
+ delete[] Hostheader;
+ Hostheader = new char[(HostheaderLen = reqHostheaderLen)];
+ }
+ sprintf(Hostheader, "Host: %s\r\n", host);
+ }
+
+ void SetSocket(SOCKET fd) {
+ Socket.SetSocket(fd);
+ }
+
+ SOCKET PickOutSocket() {
+ return Socket.PickOutSocket();
+ }
+
+ void Disconnect() {
+ Socket.Disconnect();
+ }
+
+ ssize_t read(void* buffer, size_t buflen) {
+ return Socket.read(buffer, buflen);
+ }
+
+ int RequestGet(const char* url, const char* const* headers, int persistent = 1, bool head_request = false) {
+ if (!Addrs.size())
+ return HTTP_DNS_FAILURE;
+ char message[MessageMax];
+ ssize_t messlen = 0;
+ if (Method) {
+ strncpy(message, Method, MethodLen);
+ message[MethodLen] = ' ';
+ messlen = MethodLen + 1;
+ } else if (PostData) {
+ strcpy(message, "POST ");
+ messlen = 5;
+ } else if (head_request) {
+ strcpy(message, "HEAD ");
+ messlen = 5;
+ } else {
+ strcpy(message, "GET ");
+ messlen = 4;
+ }
+#define _AppendMessage(mes) messlen += Min(MessageMax - messlen, \
+ (ssize_t)strlcpy(message + messlen, (mes), MessageMax - messlen))
+ _AppendMessage(url);
+ _AppendMessage(" HTTP/1.1\r\n");
+ if (*url == '/') //if not then Host is a proxy
+ _AppendMessage(Hostheader);
+ _AppendMessage("Connection: ");
+ _AppendMessage(persistent ? "Keep-Alive\r\n" : "Close\r\n");
+ while (headers && *headers)
+ _AppendMessage(*headers++);
+ if (AltFooter)
+ _AppendMessage(AltFooter);
+ else
+ _AppendMessage(Footer);
+ _AppendMessage("\r\n");
+#undef _AppendMessage
+ if (messlen >= MessageMax)
+ return HTTP_HEADER_TOO_LARGE;
+
+ if (!Persistent)
+ Disconnect();
+ Persistent = persistent;
+ int connected = Socket.Good();
+ for (int attempt = !connected; attempt < 2; attempt++) {
+ const auto connectTimeout = ConnectTimeout ? ConnectTimeout : Timeout;
+ if (!Socket.Good() && Socket.Connect(Addrs, connectTimeout))
+ return HTTP_CONNECT_FAILED;
+
+ int sendOk = Socket.send(message, messlen);
+ if (sendOk && PostData && PostDataLen)
+ sendOk = Socket.send(PostData, PostDataLen);
+ if (!sendOk) {
+ int err = errno;
+ Disconnect();
+ errno = err;
+ continue;
+ }
+
+ if (!Socket.peek()) {
+ int err = errno;
+ Disconnect();
+ if (err == EINTR) {
+ errno = err;
+ return HTTP_INTERRUPTED;
+ }
+ } else {
+ if (!persistent)
+ Socket.shutdown();
+ return 0;
+ }
+ }
+ return connected ? HTTP_CONNECTION_LOST : HTTP_CONNECT_FAILED;
+ }
+
+protected:
+ TSocketHandler Socket;
+ TIpResolverWrapper<TDnsClient> DnsClient;
+ TAddrList Addrs;
+ int Persistent;
+ TDuration Timeout;
+ TDuration ConnectTimeout;
+ char *Hostheader, *Footer, *pHostBeg, *pHostEnd;
+ const char* AltFooter; // alternative footer can be set by the caller
+ const char* PostData;
+ size_t PostDataLen;
+ const char* Method;
+ size_t MethodLen;
+ unsigned short HostheaderLen;
static const ssize_t MessageMax = 32768;
-};
-
-struct TNoTimer {
- inline void OnBeforeSend() {
- }
- inline void OnAfterSend() {
- }
- inline void OnBeforeRecv() {
- }
- inline void OnAfterRecv() {
- }
-};
+};
+
+struct TNoTimer {
+ inline void OnBeforeSend() {
+ }
+ inline void OnAfterSend() {
+ }
+ inline void OnBeforeRecv() {
+ }
+ inline void OnAfterRecv() {
+ }
+};
diff --git a/library/cpp/http/fetch/sockhandler.h b/library/cpp/http/fetch/sockhandler.h
index 776704ba8c4..e18149f6571 100644
--- a/library/cpp/http/fetch/sockhandler.h
+++ b/library/cpp/http/fetch/sockhandler.h
@@ -1,130 +1,130 @@
-#pragma once
-
-#include <library/cpp/logger/all.h>
-
-#include <util/generic/buffer.h>
-#include <util/generic/map.h>
-#include <util/generic/vector.h>
-#include <util/network/address.h>
-#include <util/network/ip.h>
-#include <util/network/socket.h>
-#include <util/system/mutex.h>
-#include <util/system/yassert.h>
-
-#include <cerrno>
-#include <util/generic/noncopyable.h>
-
-class TAddrList: public TVector<NAddr::IRemoteAddrRef> {
-private:
- using TBase = TVector<NAddr::IRemoteAddrRef>;
-
-public:
- //msvc doesn't support base class constructor inheritance
- TAddrList() = default;
-
- template <typename T>
- TAddrList(T&& arg)
- : TBase(std::forward<T>(arg))
- {
- }
-
- template <typename T1, typename T2>
- TAddrList(T1&& arg1, T2&& arg2)
- : TBase(std::forward<T1>(arg1), std::forward<T2>(arg2))
- {
- }
-
- TAddrList(std::initializer_list<NAddr::IRemoteAddrRef> list)
- : TBase(list)
- {
- }
-
- static TAddrList MakeV4Addr(ui32 ip, TIpPort port) {
- return TAddrList({new NAddr::TIPv4Addr(TIpAddress(htonl(ip), htons(port)))});
- }
-
- std::pair<ui32, TIpPort> GetV4Addr() const {
- for (const auto& addrRef : *this) {
- const sockaddr* sa = addrRef->Addr();
- if (sa->sa_family == AF_INET) {
- const sockaddr_in* sin = reinterpret_cast<const sockaddr_in*>(sa);
- return std::make_pair(ntohl(sin->sin_addr.s_addr), ntohs(sin->sin_port));
- }
- }
- return std::make_pair(0, 0);
- }
-};
-
-class TSimpleSocketHandler {
-public:
- TSimpleSocketHandler() = default;
-
- int Good() const {
- return static_cast<bool>(Socket);
- }
-
- int Connect(const TAddrList& addrs, TDuration timeout) {
- try {
- for (const auto& item : addrs) {
- const sockaddr* sa = item->Addr();
- TSocketHolder s(socket(sa->sa_family, SOCK_STREAM, 0));
- if (s.Closed()) {
- continue;
- }
-
-#ifndef WIN32
- if (fcntl(s, F_SETFD, FD_CLOEXEC)) // no inherit on fork()/exec()
- return errno ? errno : EBADF;
-#endif
- if (connect(s, sa, item->Len())) {
- s.Close();
- continue;
- }
-
- Socket.Reset(new TSocket(s.Release()));
- Socket->SetSocketTimeout(timeout.Seconds(), timeout.MilliSecondsOfSecond());
- Socket->SetZeroLinger();
- Socket->SetKeepAlive(true);
- return 0;
- }
- } catch (...) {
- return EBADF;
- }
- return errno ? errno : EBADF;
- }
-
- void Disconnect() {
- if (!Socket)
- return;
- Socket->ShutDown(SHUT_RDWR);
- Socket.Destroy();
- }
-
- void SetSocket(SOCKET fd) {
- Socket.Reset(new TSocket(fd));
- }
-
- void shutdown() {
- Socket->ShutDown(SHUT_WR);
- }
-
- int send(const void* message, size_t messlen) {
- return ((ssize_t)messlen == Socket->Send(message, messlen));
- }
-
- int peek() {
- char buf[1];
- return (1 == recv(*Socket, buf, 1, MSG_PEEK));
- }
-
- ssize_t read(void* buffer, size_t buflen) {
- return Socket->Recv(buffer, buflen);
- }
-
- THolder<TSocket> PickOutSocket() {
- return std::move(Socket);
- }
-
-protected:
- THolder<TSocket> Socket;
-};
+#pragma once
+
+#include <library/cpp/logger/all.h>
+
+#include <util/generic/buffer.h>
+#include <util/generic/map.h>
+#include <util/generic/vector.h>
+#include <util/network/address.h>
+#include <util/network/ip.h>
+#include <util/network/socket.h>
+#include <util/system/mutex.h>
+#include <util/system/yassert.h>
+
+#include <cerrno>
+#include <util/generic/noncopyable.h>
+
+class TAddrList: public TVector<NAddr::IRemoteAddrRef> {
+private:
+ using TBase = TVector<NAddr::IRemoteAddrRef>;
+
+public:
+ //msvc doesn't support base class constructor inheritance
+ TAddrList() = default;
+
+ template <typename T>
+ TAddrList(T&& arg)
+ : TBase(std::forward<T>(arg))
+ {
+ }
+
+ template <typename T1, typename T2>
+ TAddrList(T1&& arg1, T2&& arg2)
+ : TBase(std::forward<T1>(arg1), std::forward<T2>(arg2))
+ {
+ }
+
+ TAddrList(std::initializer_list<NAddr::IRemoteAddrRef> list)
+ : TBase(list)
+ {
+ }
+
+ static TAddrList MakeV4Addr(ui32 ip, TIpPort port) {
+ return TAddrList({new NAddr::TIPv4Addr(TIpAddress(htonl(ip), htons(port)))});
+ }
+
+ std::pair<ui32, TIpPort> GetV4Addr() const {
+ for (const auto& addrRef : *this) {
+ const sockaddr* sa = addrRef->Addr();
+ if (sa->sa_family == AF_INET) {
+ const sockaddr_in* sin = reinterpret_cast<const sockaddr_in*>(sa);
+ return std::make_pair(ntohl(sin->sin_addr.s_addr), ntohs(sin->sin_port));
+ }
+ }
+ return std::make_pair(0, 0);
+ }
+};
+
+class TSimpleSocketHandler {
+public:
+ TSimpleSocketHandler() = default;
+
+ int Good() const {
+ return static_cast<bool>(Socket);
+ }
+
+ int Connect(const TAddrList& addrs, TDuration timeout) {
+ try {
+ for (const auto& item : addrs) {
+ const sockaddr* sa = item->Addr();
+ TSocketHolder s(socket(sa->sa_family, SOCK_STREAM, 0));
+ if (s.Closed()) {
+ continue;
+ }
+
+#ifndef WIN32
+ if (fcntl(s, F_SETFD, FD_CLOEXEC)) // no inherit on fork()/exec()
+ return errno ? errno : EBADF;
+#endif
+ if (connect(s, sa, item->Len())) {
+ s.Close();
+ continue;
+ }
+
+ Socket.Reset(new TSocket(s.Release()));
+ Socket->SetSocketTimeout(timeout.Seconds(), timeout.MilliSecondsOfSecond());
+ Socket->SetZeroLinger();
+ Socket->SetKeepAlive(true);
+ return 0;
+ }
+ } catch (...) {
+ return EBADF;
+ }
+ return errno ? errno : EBADF;
+ }
+
+ void Disconnect() {
+ if (!Socket)
+ return;
+ Socket->ShutDown(SHUT_RDWR);
+ Socket.Destroy();
+ }
+
+ void SetSocket(SOCKET fd) {
+ Socket.Reset(new TSocket(fd));
+ }
+
+ void shutdown() {
+ Socket->ShutDown(SHUT_WR);
+ }
+
+ int send(const void* message, size_t messlen) {
+ return ((ssize_t)messlen == Socket->Send(message, messlen));
+ }
+
+ int peek() {
+ char buf[1];
+ return (1 == recv(*Socket, buf, 1, MSG_PEEK));
+ }
+
+ ssize_t read(void* buffer, size_t buflen) {
+ return Socket->Recv(buffer, buflen);
+ }
+
+ THolder<TSocket> PickOutSocket() {
+ return std::move(Socket);
+ }
+
+protected:
+ THolder<TSocket> Socket;
+};
diff --git a/library/cpp/http/io/stream.cpp b/library/cpp/http/io/stream.cpp
index 115bc9b0665..6689be684fc 100644
--- a/library/cpp/http/io/stream.cpp
+++ b/library/cpp/http/io/stream.cpp
@@ -640,15 +640,15 @@ private:
return IsRequest(FirstLine_);
}
- inline bool HasResponseBody() const noexcept {
- if (IsHttpResponse()) {
+ inline bool HasResponseBody() const noexcept {
+ if (IsHttpResponse()) {
if (Request_ && Request_->FirstLine().StartsWith(TStringBuf("HEAD")))
- return false;
+ return false;
if (FirstLine_.size() > 9 && strncmp(FirstLine_.data() + 9, "204", 3) == 0)
- return false;
- return true;
- }
- return false;
+ return false;
+ return true;
+ }
+ return false;
}
inline bool IsHttpResponse() const noexcept {
@@ -772,7 +772,7 @@ private:
}
if (IsHttpResponse()) {
- if (Request_ && IsCompressionEnabled() && HasResponseBody()) {
+ if (Request_ && IsCompressionEnabled() && HasResponseBody()) {
TString scheme = Request_->BestCompressionScheme(ComprSchemas_);
if (scheme != "identity") {
AddOrReplaceHeader(THttpInputHeader("Content-Encoding", scheme));
@@ -826,7 +826,7 @@ private:
}
}
- if (!haveContentLength && !chunked && (IsHttpRequest() || HasResponseBody()) && SupportChunkedTransfer() && (keepAlive || encoder || IsHttpRequest())) {
+ if (!haveContentLength && !chunked && (IsHttpRequest() || HasResponseBody()) && SupportChunkedTransfer() && (keepAlive || encoder || IsHttpRequest())) {
AddHeader(THttpInputHeader("Transfer-Encoding", "chunked"));
chunked = true;
}
diff --git a/library/cpp/http/ya.make b/library/cpp/http/ya.make
index 6027c72bc46..fa2d1edef68 100644
--- a/library/cpp/http/ya.make
+++ b/library/cpp/http/ya.make
@@ -5,7 +5,7 @@ RECURSE(
coro
examples
fetch
- fetch_gpl
+ fetch_gpl
io
io/fuzz
io/list_codings
diff --git a/library/cpp/messagebus/message.h b/library/cpp/messagebus/message.h
index 2d2c08fc096..005ca10c652 100644
--- a/library/cpp/messagebus/message.h
+++ b/library/cpp/messagebus/message.h
@@ -56,12 +56,12 @@ namespace NBus {
void BeginWork() {
SetInWork(true);
}
-
+
// for internal use only
void EndWork() {
SetInWork(false);
}
-
+
TBusIdentity();
~TBusIdentity();
diff --git a/library/cpp/monlib/service/mon_service_http_request.cpp b/library/cpp/monlib/service/mon_service_http_request.cpp
index b22e53d3705..5d805631d9d 100644
--- a/library/cpp/monlib/service/mon_service_http_request.cpp
+++ b/library/cpp/monlib/service/mon_service_http_request.cpp
@@ -42,44 +42,44 @@ const TCgiParameters& TMonService2HttpRequest::GetPostParams() const {
}
TStringBuf TMonService2HttpRequest::GetHeader(TStringBuf name) const {
- const THttpHeaders& headers = HttpRequest->GetHeaders();
- const THttpInputHeader* header = headers.FindHeader(name);
- if (header != nullptr) {
- return header->Value();
- }
- return TStringBuf();
-}
-
+ const THttpHeaders& headers = HttpRequest->GetHeaders();
+ const THttpInputHeader* header = headers.FindHeader(name);
+ if (header != nullptr) {
+ return header->Value();
+ }
+ return TStringBuf();
+}
+
const THttpHeaders& TMonService2HttpRequest::GetHeaders() const {
return HttpRequest->GetHeaders();
}
-
-TString TMonService2HttpRequest::GetRemoteAddr() const {
- return HttpRequest->GetRemoteAddr();
-}
-
+
+TString TMonService2HttpRequest::GetRemoteAddr() const {
+ return HttpRequest->GetRemoteAddr();
+}
+
TStringBuf TMonService2HttpRequest::GetCookie(TStringBuf name) const {
- TStringBuf cookie = GetHeader("Cookie");
- size_t size = cookie.size();
- size_t start = 0;
- while (start < size) {
- size_t semicolon = cookie.find(';', start);
- auto pair = cookie.substr(start, semicolon - start);
- if (!pair.empty()) {
- size_t equal = pair.find('=');
- if (equal != TStringBuf::npos) {
- auto cookieName = pair.substr(0, equal);
- if (cookieName == name) {
- size_t valueStart = equal + 1;
- auto cookieValue = pair.substr(valueStart, semicolon - valueStart);
- return cookieValue;
- }
- }
- start = semicolon;
- while (start < size && (cookie[start] == ' ' || cookie[start] == ';')) {
- ++start;
- }
- }
- }
- return TStringBuf();
-}
+ TStringBuf cookie = GetHeader("Cookie");
+ size_t size = cookie.size();
+ size_t start = 0;
+ while (start < size) {
+ size_t semicolon = cookie.find(';', start);
+ auto pair = cookie.substr(start, semicolon - start);
+ if (!pair.empty()) {
+ size_t equal = pair.find('=');
+ if (equal != TStringBuf::npos) {
+ auto cookieName = pair.substr(0, equal);
+ if (cookieName == name) {
+ size_t valueStart = equal + 1;
+ auto cookieValue = pair.substr(valueStart, semicolon - valueStart);
+ return cookieValue;
+ }
+ }
+ start = semicolon;
+ while (start < size && (cookie[start] == ' ' || cookie[start] == ';')) {
+ ++start;
+ }
+ }
+ }
+ return TStringBuf();
+}
diff --git a/library/cpp/monlib/service/mon_service_http_request.h b/library/cpp/monlib/service/mon_service_http_request.h
index d46e2bcd314..b4f2f8f0c59 100644
--- a/library/cpp/monlib/service/mon_service_http_request.h
+++ b/library/cpp/monlib/service/mon_service_http_request.h
@@ -24,7 +24,7 @@ namespace NMonitoring {
virtual const THttpHeaders& GetHeaders() const = 0;
virtual TStringBuf GetHeader(TStringBuf name) const = 0;
virtual TStringBuf GetCookie(TStringBuf name) const = 0;
- virtual TString GetRemoteAddr() const = 0;
+ virtual TString GetRemoteAddr() const = 0;
virtual TString GetServiceTitle() const = 0;
@@ -71,8 +71,8 @@ namespace NMonitoring {
TStringBuf GetHeader(TStringBuf name) const override;
TStringBuf GetCookie(TStringBuf name) const override;
const THttpHeaders& GetHeaders() const override;
- TString GetRemoteAddr() const override;
-
+ TString GetRemoteAddr() const override;
+
IMonPage* GetPage() const override {
return MonPage;
}
diff --git a/library/cpp/monlib/service/monservice.cpp b/library/cpp/monlib/service/monservice.cpp
index b45ba2c19b3..d1b9cda1d21 100644
--- a/library/cpp/monlib/service/monservice.cpp
+++ b/library/cpp/monlib/service/monservice.cpp
@@ -41,14 +41,14 @@ TMonService2::TMonService2(const THttpServerOptions& options, TSimpleSharedPtr<I
TMonService2::TMonService2(ui16 port, ui32 threads, const TString& title, THolder<IAuthProvider> auth)
: TMonService2(port, TString(), threads, title, std::move(auth))
-{
-}
-
+{
+}
+
TMonService2::TMonService2(ui16 port, const TString& title, THolder<IAuthProvider> auth)
: TMonService2(port, TString(), 0, title, std::move(auth))
{
}
-
+
void TMonService2::OutputIndex(IOutputStream& out) {
IndexMonPage->OutputIndex(out, true);
}
@@ -123,7 +123,7 @@ IMonPage* TMonService2::FindPage(const TString& relativePath) {
TIndexMonPage* TMonService2::FindIndexPage(const TString& relativePath) {
return IndexMonPage->FindIndexPage(relativePath);
}
-
-void TMonService2::SortPages() {
- IndexMonPage->SortPages();
-}
+
+void TMonService2::SortPages() {
+ IndexMonPage->SortPages();
+}
diff --git a/library/cpp/monlib/service/monservice.h b/library/cpp/monlib/service/monservice.h
index 7a6c0383eb6..8f5e52fcdb2 100644
--- a/library/cpp/monlib/service/monservice.h
+++ b/library/cpp/monlib/service/monservice.h
@@ -20,23 +20,23 @@ namespace NMonitoring {
THolder<IAuthProvider> AuthProvider_;
public:
- static THttpServerOptions HttpServerOptions(ui16 port, const TString& host, ui32 threads) {
+ static THttpServerOptions HttpServerOptions(ui16 port, const TString& host, ui32 threads) {
THttpServerOptions opts(port);
- if (!host.empty()) {
- opts.SetHost(host);
- }
+ if (!host.empty()) {
+ opts.SetHost(host);
+ }
opts.SetClientTimeout(TDuration::Minutes(1));
opts.EnableCompression(true);
opts.SetThreads(threads);
- opts.SetMaxConnections(std::max<ui32>(100, threads));
- opts.EnableRejectExcessConnections(true);
+ opts.SetMaxConnections(std::max<ui32>(100, threads));
+ opts.EnableRejectExcessConnections(true);
return opts;
}
- static THttpServerOptions HttpServerOptions(ui16 port, ui32 threads) {
- return HttpServerOptions(port, TString(), threads);
- }
-
+ static THttpServerOptions HttpServerOptions(ui16 port, ui32 threads) {
+ return HttpServerOptions(port, TString(), threads);
+ }
+
public:
explicit TMonService2(ui16 port, const TString& title = GetProgramName(), THolder<IAuthProvider> auth = nullptr);
explicit TMonService2(ui16 port, ui32 threads, const TString& title = GetProgramName(), THolder<IAuthProvider> auth = nullptr);
diff --git a/library/cpp/monlib/service/pages/index_mon_page.cpp b/library/cpp/monlib/service/pages/index_mon_page.cpp
index 461cd306983..83ff8b529ae 100644
--- a/library/cpp/monlib/service/pages/index_mon_page.cpp
+++ b/library/cpp/monlib/service/pages/index_mon_page.cpp
@@ -136,16 +136,16 @@ void TIndexMonPage::OutputBody(IMonHttpRequest& req) {
out << "<div>\n"
<< "</body>\n";
}
-
+
void TIndexMonPage::SortPages() {
- TGuard<TMutex> g(Mtx);
- std::sort(Pages.begin(), Pages.end(), [](const TMonPagePtr& a, const TMonPagePtr& b) {
+ TGuard<TMutex> g(Mtx);
+ std::sort(Pages.begin(), Pages.end(), [](const TMonPagePtr& a, const TMonPagePtr& b) {
return AsciiCompareIgnoreCase(a->GetTitle(), b->GetTitle()) < 0;
- });
-}
-
-void TIndexMonPage::ClearPages() {
- TGuard<TMutex> g(Mtx);
- Pages.clear();
- PagesByPath.clear();
-}
+ });
+}
+
+void TIndexMonPage::ClearPages() {
+ TGuard<TMutex> g(Mtx);
+ Pages.clear();
+ PagesByPath.clear();
+}
diff --git a/library/cpp/monlib/service/pages/index_mon_page.h b/library/cpp/monlib/service/pages/index_mon_page.h
index ea4df882ad3..bf514a31056 100644
--- a/library/cpp/monlib/service/pages/index_mon_page.h
+++ b/library/cpp/monlib/service/pages/index_mon_page.h
@@ -32,7 +32,7 @@ namespace NMonitoring {
TIndexMonPage* FindIndexPage(const TString& relativePath);
void SortPages();
- void ClearPages();
+ void ClearPages();
};
}
diff --git a/library/cpp/monlib/service/pages/templates.h b/library/cpp/monlib/service/pages/templates.h
index 6a48a9229e9..b4656f059fa 100644
--- a/library/cpp/monlib/service/pages/templates.h
+++ b/library/cpp/monlib/service/pages/templates.h
@@ -123,32 +123,32 @@ namespace NMonitoring {
{
Str << "<" << tag;
- if (!cls.empty()) {
+ if (!cls.empty()) {
Str << " class=\"" << cls << "\"";
}
- if (!for0.empty()) {
+ if (!for0.empty()) {
Str << " for=\"" << for0 << "\"";
}
- if (!id.empty()) {
+ if (!id.empty()) {
Str << "id=\"" << id << "\"";
}
Str << ">";
}
TTag(IOutputStream& str, std::initializer_list<std::pair<TStringBuf, TStringBuf>> attributes)
- : Str(str)
- {
- Str << "<" << tag;
- for (const std::pair<TStringBuf, TStringBuf>& attr : attributes) {
- if (!attr.second.empty()) {
- Str << ' ' << attr.first << "=\"" << attr.second << "\"";
- }
- }
- Str << ">";
- }
-
+ : Str(str)
+ {
+ Str << "<" << tag;
+ for (const std::pair<TStringBuf, TStringBuf>& attr : attributes) {
+ if (!attr.second.empty()) {
+ Str << ' ' << attr.first << "=\"" << attr.second << "\"";
+ }
+ }
+ Str << ">";
+ }
+
~TTag() {
try {
Str << "</" << tag << ">";
diff --git a/library/cpp/monlib/service/service.cpp b/library/cpp/monlib/service/service.cpp
index 0a87d8dff41..929efbf8162 100644
--- a/library/cpp/monlib/service/service.cpp
+++ b/library/cpp/monlib/service/service.cpp
@@ -15,10 +15,10 @@
namespace NMonitoring {
class THttpClient: public IHttpRequest {
public:
- void ServeRequest(THttpInput& in, IOutputStream& out, const NAddr::IRemoteAddr* remoteAddr, const THandler& Handler) {
+ void ServeRequest(THttpInput& in, IOutputStream& out, const NAddr::IRemoteAddr* remoteAddr, const THandler& Handler) {
try {
try {
- RemoteAddr = remoteAddr;
+ RemoteAddr = remoteAddr;
THttpHeaderParser parser;
parser.Init(&Header);
if (parser.Execute(in.FirstLine().data(), in.FirstLine().size()) < 0) {
@@ -34,15 +34,15 @@ namespace NMonitoring {
out << "HTTP/1.1 400 Bad request\r\nConnection: Close\r\n\r\n";
return;
}
- Headers = &in.Headers();
+ Headers = &in.Headers();
CgiParams.Scan(Url.Get(THttpURL::FieldQuery));
} catch (...) {
out << "HTTP/1.1 500 Internal server error\r\nConnection: Close\r\n\r\n";
YSYSLOG(TLOG_ERR, "THttpClient: internal error while serving monitoring request: %s", CurrentExceptionMessage().data());
}
- if (Header.http_method == HTTP_METHOD_POST)
- TransferData(&in, &PostContent);
+ if (Header.http_method == HTTP_METHOD_POST)
+ TransferData(&in, &PostContent);
Handler(out, *this);
out.Finish();
@@ -64,49 +64,49 @@ namespace NMonitoring {
return CgiParams;
}
const TCgiParameters& GetPostParams() const override {
- if (PostParams.empty() && !PostContent.Buffer().Empty())
- const_cast<THttpClient*>(this)->ScanPostParams();
+ if (PostParams.empty() && !PostContent.Buffer().Empty())
+ const_cast<THttpClient*>(this)->ScanPostParams();
return PostParams;
}
- TStringBuf GetPostContent() const override {
- return TStringBuf(PostContent.Buffer().Data(), PostContent.Buffer().Size());
- }
+ TStringBuf GetPostContent() const override {
+ return TStringBuf(PostContent.Buffer().Data(), PostContent.Buffer().Size());
+ }
HTTP_METHOD GetMethod() const override {
return (HTTP_METHOD)Header.http_method;
}
- void ScanPostParams() {
+ void ScanPostParams() {
PostParams.Scan(TStringBuf(PostContent.Buffer().data(), PostContent.Buffer().size()));
- }
-
- const THttpHeaders& GetHeaders() const override {
- if (Headers != nullptr) {
- return *Headers;
- }
- static THttpHeaders defaultHeaders;
- return defaultHeaders;
- }
-
- TString GetRemoteAddr() const override {
- return RemoteAddr ? NAddr::PrintHostAndPort(*RemoteAddr) : TString();
- }
-
+ }
+
+ const THttpHeaders& GetHeaders() const override {
+ if (Headers != nullptr) {
+ return *Headers;
+ }
+ static THttpHeaders defaultHeaders;
+ return defaultHeaders;
+ }
+
+ TString GetRemoteAddr() const override {
+ return RemoteAddr ? NAddr::PrintHostAndPort(*RemoteAddr) : TString();
+ }
+
private:
THttpRequestHeader Header;
- const THttpHeaders* Headers = nullptr;
+ const THttpHeaders* Headers = nullptr;
THttpURL Url;
TCgiParameters CgiParams;
TCgiParameters PostParams;
- TBufferOutput PostContent;
- const NAddr::IRemoteAddr* RemoteAddr = nullptr;
+ TBufferOutput PostContent;
+ const NAddr::IRemoteAddr* RemoteAddr = nullptr;
};
/* TCoHttpServer */
class TCoHttpServer::TConnection: public THttpClient {
public:
- TConnection(const TCoHttpServer::TAcceptFull& acc, const TCoHttpServer& parent)
- : Socket(acc.S->Release())
- , RemoteAddr(acc.Remote)
+ TConnection(const TCoHttpServer::TAcceptFull& acc, const TCoHttpServer& parent)
+ : Socket(acc.S->Release())
+ , RemoteAddr(acc.Remote)
, Parent(parent)
{
}
@@ -119,7 +119,7 @@ namespace NMonitoring {
THttpOutput out(&io, &in);
// buffer reply so there will be ne context switching
TStringStream s;
- ServeRequest(in, s, RemoteAddr, Parent.Handler);
+ ServeRequest(in, s, RemoteAddr, Parent.Handler);
out << s.Str();
out.Finish();
} catch (...) {
@@ -129,7 +129,7 @@ namespace NMonitoring {
private:
TSocketHolder Socket;
- const NAddr::IRemoteAddr* RemoteAddr;
+ const NAddr::IRemoteAddr* RemoteAddr;
const TCoHttpServer& Parent;
};
@@ -156,7 +156,7 @@ namespace NMonitoring {
}
void TCoHttpServer::OnAcceptFull(const TAcceptFull& acc) {
- THolder<TConnection> conn(new TConnection(acc, *this));
+ THolder<TConnection> conn(new TConnection(acc, *this));
Executor.Create(*conn, "client");
Y_UNUSED(conn.Release());
}
@@ -195,7 +195,7 @@ namespace NMonitoring {
}
bool Reply(void*) override {
- ServeRequest(Input(), Output(), NAddr::GetPeerAddr(Socket()).Get(), Parent.Handler);
+ ServeRequest(Input(), Output(), NAddr::GetPeerAddr(Socket()).Get(), Parent.Handler);
return true;
}
diff --git a/library/cpp/monlib/service/service.h b/library/cpp/monlib/service/service.h
index 0a10cf2a3d4..2f66dddaf87 100644
--- a/library/cpp/monlib/service/service.h
+++ b/library/cpp/monlib/service/service.h
@@ -21,10 +21,10 @@ namespace NMonitoring {
virtual const char* GetPath() const = 0;
virtual const TCgiParameters& GetParams() const = 0;
virtual const TCgiParameters& GetPostParams() const = 0;
- virtual TStringBuf GetPostContent() const = 0;
+ virtual TStringBuf GetPostContent() const = 0;
virtual HTTP_METHOD GetMethod() const = 0;
- virtual const THttpHeaders& GetHeaders() const = 0;
- virtual TString GetRemoteAddr() const = 0;
+ virtual const THttpHeaders& GetHeaders() const = 0;
+ virtual TString GetRemoteAddr() const = 0;
};
// first param - output stream to write result to
// second param - URL of request
diff --git a/library/cpp/threading/future/core/future-inl.h b/library/cpp/threading/future/core/future-inl.h
index b67d79e3010..5fd4296a93c 100644
--- a/library/cpp/threading/future/core/future-inl.h
+++ b/library/cpp/threading/future/core/future-inl.h
@@ -73,22 +73,22 @@ namespace NThreading {
default:
Y_ASSERT(state == ValueSet);
}
- }
-
+ }
+
public:
TFutureState()
: State(NotReady)
, NullValue(0)
{
- }
-
+ }
+
template <typename TT>
TFutureState(TT&& value)
: State(ValueSet)
, Value(std::forward<TT>(value))
{
}
-
+
TFutureState(std::exception_ptr exception, TError)
: State(ExceptionSet)
, Exception(std::move(exception))
@@ -101,11 +101,11 @@ namespace NThreading {
Value.~T();
}
}
-
+
bool HasValue() const {
return AtomicGet(State) >= ValueMoved; // ValueMoved, ValueSet, ValueRead
- }
-
+ }
+
void TryRethrow() const {
int state = AtomicGet(State);
TryRethrowWithState(state);
@@ -148,7 +148,7 @@ namespace NThreading {
readyEvent = ReadyEvent.Get();
callbacks = std::move(Callbacks);
-
+
AtomicSet(State, ValueSet);
}
@@ -635,7 +635,7 @@ namespace NThreading {
});
return promise;
}
-
+
template <typename T>
inline bool TFuture<T>::Initialized() const {
return bool(State);
@@ -790,7 +790,7 @@ namespace NThreading {
EnsureInitialized();
State->SetValue(value);
}
-
+
template <typename T>
inline void TPromise<T>::SetValue(T&& value) {
EnsureInitialized();
diff --git a/library/cpp/threading/future/future_ut.cpp b/library/cpp/threading/future/future_ut.cpp
index 8dc87880866..05950a568d4 100644
--- a/library/cpp/threading/future/future_ut.cpp
+++ b/library/cpp/threading/future/future_ut.cpp
@@ -447,15 +447,15 @@ namespace {
explicit TRec(int) {
}
};
-
+
auto promise = NewPromise<TRec>();
promise.SetValue(TRec(1));
-
+
auto future = MakeFuture(TRec(1));
auto rec = future.ExtractValue();
Y_UNUSED(rec);
}
-
+
Y_UNIT_TEST(ShouldNotExtractAfterGet) {
TPromise<int> promise = NewPromise<int>();
promise.SetValue(123);
@@ -463,7 +463,7 @@ namespace {
UNIT_ASSERT_EQUAL(promise.GetValue(), 123);
UNIT_CHECK_GENERATED_EXCEPTION(promise.ExtractValue(), TFutureException);
}
-
+
Y_UNIT_TEST(ShouldNotGetAfterExtract) {
TPromise<int> promise = NewPromise<int>();
promise.SetValue(123);
@@ -471,7 +471,7 @@ namespace {
UNIT_ASSERT_EQUAL(promise.ExtractValue(), 123);
UNIT_CHECK_GENERATED_EXCEPTION(promise.GetValue(), TFutureException);
}
-
+
Y_UNIT_TEST(ShouldNotExtractAfterExtract) {
TPromise<int> promise = NewPromise<int>();
promise.SetValue(123);
@@ -635,6 +635,6 @@ namespace {
TestApplyLvalueCopyImpl<void>();
TestApplyLvalueCopyImpl<int>();
}
- }
-
+ }
+
}
diff --git a/util/network/address.cpp b/util/network/address.cpp
index 08fc8139eec..a81a9e69941 100644
--- a/util/network/address.cpp
+++ b/util/network/address.cpp
@@ -140,16 +140,16 @@ IRemoteAddrPtr NAddr::GetSockAddr(SOCKET s) {
return addr;
}
-IRemoteAddrPtr NAddr::GetPeerAddr(SOCKET s) {
- auto addr = MakeHolder<TOpaqueAddr>();
-
- if (getpeername(s, addr->MutableAddr(), addr->LenPtr()) < 0) {
- ythrow TSystemError() << "getpeername() failed";
- }
-
- return addr;
-}
-
+IRemoteAddrPtr NAddr::GetPeerAddr(SOCKET s) {
+ auto addr = MakeHolder<TOpaqueAddr>();
+
+ if (getpeername(s, addr->MutableAddr(), addr->LenPtr()) < 0) {
+ ythrow TSystemError() << "getpeername() failed";
+ }
+
+ return addr;
+}
+
static const in_addr& InAddr(const IRemoteAddr& addr) {
return ((const sockaddr_in*)addr.Addr())->sin_addr;
}
diff --git a/util/network/address.h b/util/network/address.h
index 3a52bb37142..448fcac0c9d 100644
--- a/util/network/address.h
+++ b/util/network/address.h
@@ -19,7 +19,7 @@ namespace NAddr {
using IRemoteAddrRef = TAtomicSharedPtr<NAddr::IRemoteAddr>;
IRemoteAddrPtr GetSockAddr(SOCKET s);
- IRemoteAddrPtr GetPeerAddr(SOCKET s);
+ IRemoteAddrPtr GetPeerAddr(SOCKET s);
void PrintHost(IOutputStream& out, const IRemoteAddr& addr);
TString PrintHost(const IRemoteAddr& addr);
diff --git a/util/network/sock.h b/util/network/sock.h
index 52c9c346237..b10be2f7156 100644
--- a/util/network/sock.h
+++ b/util/network/sock.h
@@ -265,10 +265,10 @@ struct TSockAddrInet: public sockaddr_in, public ISockAddr {
TIpPort GetPort() const noexcept {
return InetToHost(sin_port);
}
-
- void SetPort(TIpPort port) noexcept {
- sin_port = HostToInet(port);
- }
+
+ void SetPort(TIpPort port) noexcept {
+ sin_port = HostToInet(port);
+ }
};
struct TSockAddrInet6: public sockaddr_in6, public ISockAddr {
@@ -333,10 +333,10 @@ struct TSockAddrInet6: public sockaddr_in6, public ISockAddr {
TIpPort GetPort() const noexcept {
return InetToHost(sin6_port);
}
-
- void SetPort(TIpPort port) noexcept {
- sin6_port = HostToInet(port);
- }
+
+ void SetPort(TIpPort port) noexcept {
+ sin6_port = HostToInet(port);
+ }
};
using TSockAddrLocalStream = TSockAddrLocal;
diff --git a/ydb/core/actorlib_impl/node_identifier.cpp b/ydb/core/actorlib_impl/node_identifier.cpp
index 98085058875..410fbede7cc 100644
--- a/ydb/core/actorlib_impl/node_identifier.cpp
+++ b/ydb/core/actorlib_impl/node_identifier.cpp
@@ -7,159 +7,159 @@
#include <library/cpp/http/io/stream.h>
#include <library/cpp/openssl/init/init.h>
#include <library/cpp/openssl/io/stream.h>
-#include <util/network/sock.h>
-#include <util/system/hostname.h>
-
-using namespace NActors;
-
-namespace NKikimr {
-
-class TNodeIdentifier : public TActorBootstrapped<TNodeIdentifier> {
- using TThis = TNodeIdentifier;
- using TBase = TActorBootstrapped<TNodeIdentifier>;
-
- struct TEvPrivate {
- enum EEv {
- EvUpdateNodeInfo = EventSpaceBegin(TEvents::ES_PRIVATE),
- EvEnd
- };
-
- static_assert(EvEnd < EventSpaceEnd(TEvents::ES_PRIVATE), "expected EvEnd < EventSpaceEnd");
-
- struct TEvUpdateNodeInfo : TEventLocal<TEvUpdateNodeInfo, EvUpdateNodeInfo> {};
- };
-
- static const NJson::TJsonReaderConfig& GetJsonConfig() {
- static NJson::TJsonReaderConfig jsonConfig;
- return jsonConfig;
- }
-
- const TString& GetWallEServiceHost() const {
- static const TString host("api.wall-e.yandex-team.ru");
- return host;
- }
-
- const TNetworkAddress& GetWallENetworkAddress() const {
- static const TNetworkAddress address(GetWallEServiceHost(), 443);
- return address;
- }
-
- const TString& GetConductorServiceHost() const {
- static const TString host("c.yandex-team.ru");
- return host;
- }
-
- const TNetworkAddress& GetConductorNetworkAddress() const {
- static const TNetworkAddress address(GetConductorServiceHost(), 443);
- return address;
- }
-
- TDuration GetTimeout() const {
- return TDuration::Seconds(10);
- }
-
- void Handle(TEvPrivate::TEvUpdateNodeInfo::TPtr&, const TActorContext& ctx) {
- NKikimrWhiteboard::TSystemStateInfo systemStateInfo;
- TString hostname = FQDNHostName();
- systemStateInfo.SetHost(hostname);
-
- try {
- TSocket s(GetWallENetworkAddress(), GetTimeout());
- s.SetSocketTimeout(GetTimeout().Seconds());
- TSocketOutput so(s);
- TSocketInput si(s);
- TOpenSslClientIO ssl(&si, &so);
- THttpOutput output(&ssl);
- output << "GET /v1/hosts/" << hostname << "?fields=location HTTP/1.1\r\n"
- << "Host: " << GetWallEServiceHost() << "\r\n"
- << "\r\n";
- output.Finish();
- THttpInput input(&ssl);
- unsigned status = ParseHttpRetCode(input.FirstLine());
- if (status == 200) {
- NJson::TJsonValue response;
- bool success = NJson::ReadJsonTree(input.ReadAll(), &GetJsonConfig(), &response);
- if (success) {
- NJson::TJsonValue* jsonLocation;
- if (response.GetValuePointer("location", &jsonLocation)) {
- NJson::TJsonValue* jsonValue;
- if (jsonLocation->GetValuePointer("short_datacenter_name", &jsonValue)) {
- if (jsonValue->GetType() == NJson::EJsonValueType::JSON_STRING) {
- systemStateInfo.SetDataCenter(jsonValue->GetStringRobust());
- }
- }
- if (jsonLocation->GetValuePointer("queue", &jsonValue)) {
- systemStateInfo.SetDataCenterDescription(jsonValue->GetStringRobust());
- }
- if (jsonLocation->GetValuePointer("rack", &jsonValue)) {
- systemStateInfo.SetRack(jsonValue->GetStringRobust());
- }
- }
-
- }
- }
- }
- catch (const std::exception&) {
- }
-
- try {
- TSocket s(GetConductorNetworkAddress(), GetTimeout());
- s.SetSocketTimeout(GetTimeout().Seconds());
- TSocketOutput so(s);
- TSocketInput si(s);
- TOpenSslClientIO ssl(&si, &so);
- THttpOutput output(&ssl);
-
- output << "GET /api/hosts/" << hostname << "?format=json HTTP/1.1\r\n"
- << "Host: " << GetConductorServiceHost() << "\r\n"
- << "\r\n";
- output.Finish();
- THttpInput input(&ssl);
- unsigned status = ParseHttpRetCode(input.FirstLine());
- if (status == 200) {
- NJson::TJsonValue response;
- bool success = NJson::ReadJsonTree(input.ReadAll(), &GetJsonConfig(), &response);
- if (success && response.IsArray()) {
- const NJson::TJsonValue& first = response.GetArray().front();
- const NJson::TJsonValue* jsonGroup;
- if (first.GetValuePointer("group", &jsonGroup)) {
- systemStateInfo.SetClusterName(jsonGroup->GetStringRobust());
- }
- const NJson::TJsonValue* jsonRootDatacenter;
- if (!systemStateInfo.HasDataCenter() && first.GetValuePointer("root_datacenter", &jsonRootDatacenter)) {
- if (jsonRootDatacenter->GetType() == NJson::EJsonValueType::JSON_STRING) {
- systemStateInfo.SetDataCenter(jsonRootDatacenter->GetStringRobust());
- }
- }
- }
- }
- }
- catch (const std::exception&) {
- }
-
+#include <util/network/sock.h>
+#include <util/system/hostname.h>
+
+using namespace NActors;
+
+namespace NKikimr {
+
+class TNodeIdentifier : public TActorBootstrapped<TNodeIdentifier> {
+ using TThis = TNodeIdentifier;
+ using TBase = TActorBootstrapped<TNodeIdentifier>;
+
+ struct TEvPrivate {
+ enum EEv {
+ EvUpdateNodeInfo = EventSpaceBegin(TEvents::ES_PRIVATE),
+ EvEnd
+ };
+
+ static_assert(EvEnd < EventSpaceEnd(TEvents::ES_PRIVATE), "expected EvEnd < EventSpaceEnd");
+
+ struct TEvUpdateNodeInfo : TEventLocal<TEvUpdateNodeInfo, EvUpdateNodeInfo> {};
+ };
+
+ static const NJson::TJsonReaderConfig& GetJsonConfig() {
+ static NJson::TJsonReaderConfig jsonConfig;
+ return jsonConfig;
+ }
+
+ const TString& GetWallEServiceHost() const {
+ static const TString host("api.wall-e.yandex-team.ru");
+ return host;
+ }
+
+ const TNetworkAddress& GetWallENetworkAddress() const {
+ static const TNetworkAddress address(GetWallEServiceHost(), 443);
+ return address;
+ }
+
+ const TString& GetConductorServiceHost() const {
+ static const TString host("c.yandex-team.ru");
+ return host;
+ }
+
+ const TNetworkAddress& GetConductorNetworkAddress() const {
+ static const TNetworkAddress address(GetConductorServiceHost(), 443);
+ return address;
+ }
+
+ TDuration GetTimeout() const {
+ return TDuration::Seconds(10);
+ }
+
+ void Handle(TEvPrivate::TEvUpdateNodeInfo::TPtr&, const TActorContext& ctx) {
+ NKikimrWhiteboard::TSystemStateInfo systemStateInfo;
+ TString hostname = FQDNHostName();
+ systemStateInfo.SetHost(hostname);
+
+ try {
+ TSocket s(GetWallENetworkAddress(), GetTimeout());
+ s.SetSocketTimeout(GetTimeout().Seconds());
+ TSocketOutput so(s);
+ TSocketInput si(s);
+ TOpenSslClientIO ssl(&si, &so);
+ THttpOutput output(&ssl);
+ output << "GET /v1/hosts/" << hostname << "?fields=location HTTP/1.1\r\n"
+ << "Host: " << GetWallEServiceHost() << "\r\n"
+ << "\r\n";
+ output.Finish();
+ THttpInput input(&ssl);
+ unsigned status = ParseHttpRetCode(input.FirstLine());
+ if (status == 200) {
+ NJson::TJsonValue response;
+ bool success = NJson::ReadJsonTree(input.ReadAll(), &GetJsonConfig(), &response);
+ if (success) {
+ NJson::TJsonValue* jsonLocation;
+ if (response.GetValuePointer("location", &jsonLocation)) {
+ NJson::TJsonValue* jsonValue;
+ if (jsonLocation->GetValuePointer("short_datacenter_name", &jsonValue)) {
+ if (jsonValue->GetType() == NJson::EJsonValueType::JSON_STRING) {
+ systemStateInfo.SetDataCenter(jsonValue->GetStringRobust());
+ }
+ }
+ if (jsonLocation->GetValuePointer("queue", &jsonValue)) {
+ systemStateInfo.SetDataCenterDescription(jsonValue->GetStringRobust());
+ }
+ if (jsonLocation->GetValuePointer("rack", &jsonValue)) {
+ systemStateInfo.SetRack(jsonValue->GetStringRobust());
+ }
+ }
+
+ }
+ }
+ }
+ catch (const std::exception&) {
+ }
+
+ try {
+ TSocket s(GetConductorNetworkAddress(), GetTimeout());
+ s.SetSocketTimeout(GetTimeout().Seconds());
+ TSocketOutput so(s);
+ TSocketInput si(s);
+ TOpenSslClientIO ssl(&si, &so);
+ THttpOutput output(&ssl);
+
+ output << "GET /api/hosts/" << hostname << "?format=json HTTP/1.1\r\n"
+ << "Host: " << GetConductorServiceHost() << "\r\n"
+ << "\r\n";
+ output.Finish();
+ THttpInput input(&ssl);
+ unsigned status = ParseHttpRetCode(input.FirstLine());
+ if (status == 200) {
+ NJson::TJsonValue response;
+ bool success = NJson::ReadJsonTree(input.ReadAll(), &GetJsonConfig(), &response);
+ if (success && response.IsArray()) {
+ const NJson::TJsonValue& first = response.GetArray().front();
+ const NJson::TJsonValue* jsonGroup;
+ if (first.GetValuePointer("group", &jsonGroup)) {
+ systemStateInfo.SetClusterName(jsonGroup->GetStringRobust());
+ }
+ const NJson::TJsonValue* jsonRootDatacenter;
+ if (!systemStateInfo.HasDataCenter() && first.GetValuePointer("root_datacenter", &jsonRootDatacenter)) {
+ if (jsonRootDatacenter->GetType() == NJson::EJsonValueType::JSON_STRING) {
+ systemStateInfo.SetDataCenter(jsonRootDatacenter->GetStringRobust());
+ }
+ }
+ }
+ }
+ }
+ catch (const std::exception&) {
+ }
+
TActorId whiteboardServiceId = NNodeWhiteboard::MakeNodeWhiteboardServiceId(ctx.SelfID.NodeId());
- ctx.Send(whiteboardServiceId, new NNodeWhiteboard::TEvWhiteboard::TEvSystemStateUpdate(systemStateInfo));
- }
-
-public:
+ ctx.Send(whiteboardServiceId, new NNodeWhiteboard::TEvWhiteboard::TEvSystemStateUpdate(systemStateInfo));
+ }
+
+public:
static constexpr NKikimrServices::TActivity::EType ActorActivityType() { return NKikimrServices::TActivity::NODE_IDENTIFIER; }
-
- void StateWork(TAutoPtr<IEventHandle>& ev, const TActorContext& ctx) {
- switch (ev->GetTypeRewrite()) {
- HFunc(TEvPrivate::TEvUpdateNodeInfo, Handle);
- CFunc(TEvents::TSystem::PoisonPill, Die);
- }
- }
-
- void Bootstrap(const TActorContext& ctx) {
- ctx.Send(ctx.SelfID, new TEvPrivate::TEvUpdateNodeInfo());
- Become(&TThis::StateWork);
- }
-};
-
-IActor* CreateNodeIdentifier() {
- InitOpenSSL();
- return new TNodeIdentifier();
-}
-
-}
+
+ void StateWork(TAutoPtr<IEventHandle>& ev, const TActorContext& ctx) {
+ switch (ev->GetTypeRewrite()) {
+ HFunc(TEvPrivate::TEvUpdateNodeInfo, Handle);
+ CFunc(TEvents::TSystem::PoisonPill, Die);
+ }
+ }
+
+ void Bootstrap(const TActorContext& ctx) {
+ ctx.Send(ctx.SelfID, new TEvPrivate::TEvUpdateNodeInfo());
+ Become(&TThis::StateWork);
+ }
+};
+
+IActor* CreateNodeIdentifier() {
+ InitOpenSSL();
+ return new TNodeIdentifier();
+}
+
+}
diff --git a/ydb/core/actorlib_impl/node_identifier.h b/ydb/core/actorlib_impl/node_identifier.h
index 97c315e6e1d..7981886b93a 100644
--- a/ydb/core/actorlib_impl/node_identifier.h
+++ b/ydb/core/actorlib_impl/node_identifier.h
@@ -1,13 +1,13 @@
-#pragma once
+#pragma once
#include <library/cpp/actors/core/actor.h>
-
-namespace NKikimr {
-
+
+namespace NKikimr {
+
inline NActors::TActorId MakeNodeIdentifierServiceId() {
- char x[12] = {'n','o','d','e','i','d','e','n','t','i','f','r'};
+ char x[12] = {'n','o','d','e','i','d','e','n','t','i','f','r'};
return TActorId(0, TStringBuf(x, 12));
-}
-
-NActors::IActor* CreateNodeIdentifier();
-
-}
+}
+
+NActors::IActor* CreateNodeIdentifier();
+
+}
diff --git a/ydb/core/actorlib_impl/ya.make b/ydb/core/actorlib_impl/ya.make
index 97152afc235..ba63f39617f 100644
--- a/ydb/core/actorlib_impl/ya.make
+++ b/ydb/core/actorlib_impl/ya.make
@@ -25,7 +25,7 @@ SRCS(
name_service_client_protocol.cpp
name_service_client_protocol.h
node_identifier.cpp
- node_identifier.h
+ node_identifier.h
proto_ready_actor.h
read_data_protocol.cpp
read_data_protocol.h
diff --git a/ydb/core/base/appdata.cpp b/ydb/core/base/appdata.cpp
index aa7684bdaea..f9e517fc424 100644
--- a/ydb/core/base/appdata.cpp
+++ b/ydb/core/base/appdata.cpp
@@ -32,16 +32,16 @@ TAppData::TAppData(
{}
TAppData::TDefaultTabletTypes::TDefaultTabletTypes()
- : SchemeShard(TTabletTypes::FLAT_SCHEMESHARD)
- , DataShard(TTabletTypes::FLAT_DATASHARD)
- , KeyValue(TTabletTypes::KEYVALUEFLAT)
+ : SchemeShard(TTabletTypes::FLAT_SCHEMESHARD)
+ , DataShard(TTabletTypes::FLAT_DATASHARD)
+ , KeyValue(TTabletTypes::KEYVALUEFLAT)
, PersQueue(TTabletTypes::PERSQUEUE)
, PersQueueReadBalancer(TTabletTypes::PERSQUEUE_READ_BALANCER)
- , Dummy(TTabletTypes::TX_DUMMY)
+ , Dummy(TTabletTypes::TX_DUMMY)
, Coordinator(TTabletTypes::FLAT_TX_COORDINATOR)
, Mediator(TTabletTypes::TX_MEDIATOR)
, Kesus(TTabletTypes::KESUS)
- , Hive(TTabletTypes::Hive)
+ , Hive(TTabletTypes::Hive)
, SysViewProcessor(TTabletTypes::SysViewProcessor)
, ColumnShard(TTabletTypes::COLUMNSHARD)
, TestShard(TTabletTypes::TestShard)
diff --git a/ydb/core/base/appdata.h b/ydb/core/base/appdata.h
index dc93b959489..c666f7468c0 100644
--- a/ydb/core/base/appdata.h
+++ b/ydb/core/base/appdata.h
@@ -5,7 +5,7 @@
#include "domain.h"
#include "feature_flags.h"
#include "nameservice.h"
-#include "tablet_types.h"
+#include "tablet_types.h"
#include "resource_profile.h"
#include "event_filter.h"
@@ -88,16 +88,16 @@ struct TAppData {
const NPDisk::IIoContextFactory* IoContextFactory = nullptr;
struct TDefaultTabletTypes {
- TTabletTypes::EType SchemeShard;
- TTabletTypes::EType DataShard;
- TTabletTypes::EType KeyValue;
- TTabletTypes::EType PersQueue;
- TTabletTypes::EType PersQueueReadBalancer;
- TTabletTypes::EType Dummy;
- TTabletTypes::EType Coordinator;
- TTabletTypes::EType Mediator;
+ TTabletTypes::EType SchemeShard;
+ TTabletTypes::EType DataShard;
+ TTabletTypes::EType KeyValue;
+ TTabletTypes::EType PersQueue;
+ TTabletTypes::EType PersQueueReadBalancer;
+ TTabletTypes::EType Dummy;
+ TTabletTypes::EType Coordinator;
+ TTabletTypes::EType Mediator;
TTabletTypes::EType Kesus;
- TTabletTypes::EType Hive;
+ TTabletTypes::EType Hive;
TTabletTypes::EType SysViewProcessor;
TTabletTypes::EType ColumnShard;
TTabletTypes::EType TestShard;
@@ -138,22 +138,22 @@ struct TAppData {
NKikimrNetClassifier::TNetClassifierConfig NetClassifierConfig;
NKikimrNetClassifier::TNetClassifierDistributableConfig NetClassifierDistributableConfig;
NKikimrConfig::TSqsConfig SqsConfig;
- NKikimrProto::TAuthConfig AuthConfig;
+ NKikimrProto::TAuthConfig AuthConfig;
NKikimrProto::TKeyConfig KeyConfig;
NKikimrProto::TKeyConfig PDiskKeyConfig;
TFeatureFlags FeatureFlags;
- NKikimrConfig::THiveConfig HiveConfig;
+ NKikimrConfig::THiveConfig HiveConfig;
NKikimrConfig::TDataShardConfig DataShardConfig;
NKikimrConfig::TMeteringConfig MeteringConfig;
NKikimrConfig::TCompactionConfig CompactionConfig;
- bool EnforceUserTokenRequirement = false;
+ bool EnforceUserTokenRequirement = false;
bool AllowHugeKeyValueDeletes = true; // delete when all clients limit deletes per request
bool EnableKqpSpilling = false;
bool AllowShadowDataInSchemeShardForTests = false;
bool EnableMvccSnapshotWithLegacyDomainRoot = false;
- TVector<TString> AdministrationAllowedSIDs; // users/groups which allowed to perform administrative tasks
- TVector<TString> DefaultUserSIDs;
- TString AllAuthenticatedUsers;
+ TVector<TString> AdministrationAllowedSIDs; // users/groups which allowed to perform administrative tasks
+ TVector<TString> DefaultUserSIDs;
+ TString AllAuthenticatedUsers;
TResourceProfilesPtr ResourceProfiles;
TProgramShouldContinue * const KikimrShouldContinue;
diff --git a/ydb/core/base/blobstorage.h b/ydb/core/base/blobstorage.h
index db629201a86..a2faee326e5 100644
--- a/ydb/core/base/blobstorage.h
+++ b/ydb/core/base/blobstorage.h
@@ -193,17 +193,17 @@ struct TTabletChannelInfo {
struct THistoryEntry {
ui32 FromGeneration;
ui32 GroupID;
- TInstant Timestamp; // for diagnostics usage only
+ TInstant Timestamp; // for diagnostics usage only
THistoryEntry()
: FromGeneration(0)
, GroupID(0)
{}
- THistoryEntry(ui32 fromGeneration, ui32 groupId, TInstant timestamp = TInstant()) // groupId could be zero
+ THistoryEntry(ui32 fromGeneration, ui32 groupId, TInstant timestamp = TInstant()) // groupId could be zero
: FromGeneration(fromGeneration)
, GroupID(groupId)
- , Timestamp(timestamp)
+ , Timestamp(timestamp)
{}
struct TCmp {
@@ -216,15 +216,15 @@ struct TTabletChannelInfo {
TStringStream str;
str << "{FromGeneration# " << FromGeneration;
str << " GroupID# " << GroupID;
- str << " Timestamp# " << Timestamp.ToString();
+ str << " Timestamp# " << Timestamp.ToString();
str << "}";
return str.Str();
}
-
- bool operator ==(const THistoryEntry& other) const {
- return FromGeneration == other.FromGeneration
- && (GroupID == other.GroupID || GroupID == 0 || other.GroupID == 0);
- }
+
+ bool operator ==(const THistoryEntry& other) const {
+ return FromGeneration == other.FromGeneration
+ && (GroupID == other.GroupID || GroupID == 0 || other.GroupID == 0);
+ }
};
ui32 Channel;
@@ -232,21 +232,21 @@ struct TTabletChannelInfo {
TString StoragePool;
TVector<THistoryEntry> History;
- TTabletChannelInfo()
- : Channel()
- , Type()
- {}
-
- TTabletChannelInfo(ui32 channel, TBlobStorageGroupType type)
- : Channel(channel)
- , Type(type)
- {}
-
- TTabletChannelInfo(ui32 channel, TBlobStorageGroupType::EErasureSpecies erasureSpecies)
- : Channel(channel)
+ TTabletChannelInfo()
+ : Channel()
+ , Type()
+ {}
+
+ TTabletChannelInfo(ui32 channel, TBlobStorageGroupType type)
+ : Channel(channel)
+ , Type(type)
+ {}
+
+ TTabletChannelInfo(ui32 channel, TBlobStorageGroupType::EErasureSpecies erasureSpecies)
+ : Channel(channel)
, Type(erasureSpecies)
{}
-
+
TTabletChannelInfo(ui32 channel, TString storagePool)
: Channel(channel)
, Type(TBlobStorageGroupType::ErasureNone)
@@ -279,19 +279,19 @@ struct TTabletChannelInfo {
}
const THistoryEntry* LatestEntry() const {
- if (!History.empty())
+ if (!History.empty())
return &History.back();
else
return nullptr;
}
- const THistoryEntry* PreviousEntry() const {
- if (History.size() > 1)
- return &*(History.rbegin() + 1);
- else
- return nullptr;
- }
-
+ const THistoryEntry* PreviousEntry() const {
+ if (History.size() > 1)
+ return &*(History.rbegin() + 1);
+ else
+ return nullptr;
+ }
+
TString ToString() const {
TStringStream str;
str << "{Channel# " << Channel;
@@ -300,7 +300,7 @@ struct TTabletChannelInfo {
str << " History# {";
const size_t historySize = History.size();
for (size_t historyIdx = 0; historyIdx < historySize; ++historyIdx) {
- if (historyIdx != 0) {
+ if (historyIdx != 0) {
str <<", ";
}
str << historyIdx << ":" << History[historyIdx].ToString();
@@ -316,13 +316,13 @@ public:
TTabletStorageInfo()
: TabletID(Max<ui64>())
, TabletType(TTabletTypes::TYPE_INVALID)
- , Version(0)
+ , Version(0)
+ {}
+ TTabletStorageInfo(ui64 tabletId, TTabletTypes::EType tabletType)
+ : TabletID(tabletId)
+ , TabletType(tabletType)
+ , Version(0)
{}
- TTabletStorageInfo(ui64 tabletId, TTabletTypes::EType tabletType)
- : TabletID(tabletId)
- , TabletType(tabletType)
- , Version(0)
- {}
virtual ~TTabletStorageInfo() {}
const TTabletChannelInfo* ChannelInfo(ui32 channel) const {
@@ -330,7 +330,7 @@ public:
return nullptr;
}
const TTabletChannelInfo &info = Channels[channel];
- if (info.History.empty()) {
+ if (info.History.empty()) {
return nullptr;
}
return &info;
@@ -345,13 +345,13 @@ public:
TString ToString() const {
TStringStream str;
- str << "{Version# " << Version;
- str << " TabletID# " << TabletID;
+ str << "{Version# " << Version;
+ str << " TabletID# " << TabletID;
str << " TabletType# " << TabletType;
str << " Channels# {";
const size_t channelsSize = Channels.size();
for (size_t channelIdx = 0; channelIdx < channelsSize; ++channelIdx) {
- if (channelIdx != 0) {
+ if (channelIdx != 0) {
str <<", ";
}
str << channelIdx << ":" << Channels[channelIdx].ToString();
@@ -365,9 +365,9 @@ public:
TActorId BSProxyIDForChannel(ui32 channel, ui32 generation) const;
bool operator<(const TTabletStorageInfo &other) const noexcept {
- if (Version != 0 && other.Version != 0) {
- return Version < other.Version;
- }
+ if (Version != 0 && other.Version != 0) {
+ return Version < other.Version;
+ }
const size_t selfSize = Channels.size();
const size_t otherSize = other.Channels.size();
if (selfSize != otherSize)
@@ -386,10 +386,10 @@ public:
//
ui64 TabletID;
TVector<TTabletChannelInfo> Channels;
- TTabletTypes::EType TabletType;
- ui32 Version;
+ TTabletTypes::EType TabletType;
+ ui32 Version;
TPathId TenantPathId;
- ui64 HiveId = 0;
+ ui64 HiveId = 0;
};
inline TActorId TTabletStorageInfo::BSProxyIDForChannel(ui32 channel, ui32 generation) const {
@@ -783,8 +783,8 @@ struct TEvBlobStorage {
EvControllerCreateVDiskSlotsResult,
EvControllerCreateGroupResult,
EvControllerSelectGroupsResult,
- EvRequestControllerInfo,
- EvResponseControllerInfo,
+ EvRequestControllerInfo,
+ EvResponseControllerInfo,
EvControllerGroupReconfigureReplace, // Not used.
EvControllerGroupReconfigureReplaceResult, // Not used.
EvControllerGroupReconfigureWipe,
@@ -939,7 +939,7 @@ struct TEvBlobStorage {
NKikimrProto::EReplyStatus Status;
const TLogoBlobID Id;
const TStorageStatusFlags StatusFlags;
- const ui32 GroupId;
+ const ui32 GroupId;
const float ApproximateFreeSpaceShare; // 0.f has special meaning 'data could not be obtained'
TString ErrorReason;
mutable NLWTrace::TOrbit Orbit;
@@ -949,7 +949,7 @@ struct TEvBlobStorage {
: Status(status)
, Id(id)
, StatusFlags(statusFlags)
- , GroupId(groupId)
+ , GroupId(groupId)
, ApproximateFreeSpaceShare(approximateFreeSpaceShare)
{}
@@ -1141,7 +1141,7 @@ struct TEvBlobStorage {
// todo: replace with queue-like thing
ui32 ResponseSz;
TArrayHolder<TResponse> Responses;
- const ui32 GroupId;
+ const ui32 GroupId;
ui32 BlockedGeneration = 0; // valid only for requests with non-zero TabletId and true AcquireBlockedGeneration.
TString DebugInfo;
TString ErrorReason;
@@ -1150,11 +1150,11 @@ struct TEvBlobStorage {
// to measure blobstorage->client hop
TInstant Sent;
- TEvGetResult(NKikimrProto::EReplyStatus status, ui32 sz, ui32 groupId)
+ TEvGetResult(NKikimrProto::EReplyStatus status, ui32 sz, ui32 groupId)
: Status(status)
, ResponseSz(sz)
, Responses(sz == 0 ? nullptr : new TResponse[sz])
- , GroupId(groupId)
+ , GroupId(groupId)
{}
TString Print(bool isFull) const {
@@ -1720,14 +1720,14 @@ struct TEvBlobStorage {
TLogoBlobID To;
TVector<TResponse> Responses;
- const ui32 GroupId;
+ const ui32 GroupId;
TString ErrorReason;
- TEvRangeResult(NKikimrProto::EReplyStatus status, const TLogoBlobID &from, const TLogoBlobID &to, ui32 groupId)
+ TEvRangeResult(NKikimrProto::EReplyStatus status, const TLogoBlobID &from, const TLogoBlobID &to, ui32 groupId)
: Status(status)
, From(from)
, To(to)
- , GroupId(groupId)
+ , GroupId(groupId)
{}
TString Print(bool isFull) const {
@@ -2049,8 +2049,8 @@ struct TEvBlobStorage {
struct TEvControllerScrubStartQuantum;
struct TEvControllerScrubQuantumFinished;
struct TEvControllerScrubReportQuantumInProgress;
- struct TEvRequestControllerInfo;
- struct TEvResponseControllerInfo;
+ struct TEvRequestControllerInfo;
+ struct TEvResponseControllerInfo;
struct TEvTestLoadRequest;
struct TEvTestLoadResponse;
diff --git a/ydb/core/base/channel_profiles.h b/ydb/core/base/channel_profiles.h
index 7a7f5294a7d..e10d6a3f91e 100644
--- a/ydb/core/base/channel_profiles.h
+++ b/ydb/core/base/channel_profiles.h
@@ -10,7 +10,7 @@ struct TChannelProfiles : public TThrRefBase {
struct TChannel {
TBlobStorageGroupType::EErasureSpecies Erasure;
ui64 PDiskCategory;
- NKikimrBlobStorage::TVDiskKind::EVDiskKind VDiskCategory;
+ NKikimrBlobStorage::TVDiskKind::EVDiskKind VDiskCategory;
TString PoolKind;
@@ -20,20 +20,20 @@ struct TChannelProfiles : public TThrRefBase {
TString poolKind = TString())
: Erasure(erasure)
, PDiskCategory(pDiskCategory)
- , VDiskCategory(vDiskCategory)
+ , VDiskCategory(vDiskCategory)
, PoolKind(poolKind)
{}
-
- bool operator ==(const TChannel& a) const {
+
+ bool operator ==(const TChannel& a) const {
return Erasure == a.Erasure
&& PDiskCategory == a.PDiskCategory
&& VDiskCategory == a.VDiskCategory
&& PoolKind == a.PoolKind;
- }
-
- bool operator !=(const TChannel& a) const {
- return !operator ==(a);
- }
+ }
+
+ bool operator !=(const TChannel& a) const {
+ return !operator ==(a);
+ }
};
TVector<TChannel> Channels;
diff --git a/ydb/core/base/events.h b/ydb/core/base/events.h
index 4119d3dbe51..f5fedfe19b2 100644
--- a/ydb/core/base/events.h
+++ b/ydb/core/base/events.h
@@ -53,20 +53,20 @@ struct TKikimrEvents : TEvents {
ES_DEPRECATED_4130,
ES_DEPRECATED_4131,
ES_KEYVALUE, //4132
- ES_MSGBUS_TRACER,
+ ES_MSGBUS_TRACER,
ES_RTMR_TABLET,
ES_FLAT_EXECUTOR,
- ES_NODE_WHITEBOARD,
+ ES_NODE_WHITEBOARD,
ES_FLAT_TX_SCHEMESHARD, // 4137
ES_PQ,
ES_YQL_KIKIMR_PROXY,
ES_PQ_META_CACHE,
ES_DEPRECATED_4141,
ES_PQ_L2_CACHE, //4142
- ES_TOKEN_BUILDER,
- ES_TICKET_PARSER,
+ ES_TOKEN_BUILDER,
+ ES_TICKET_PARSER,
ES_KQP = NYql::NDq::TDqEvents::ES_DQ_COMPUTE_KQP_COMPATIBLE, // 4145
- ES_BLACKBOX_VALIDATOR,
+ ES_BLACKBOX_VALIDATOR,
ES_SELF_PING,
ES_PIPECACHE,
ES_PQ_PROXY,
@@ -95,13 +95,13 @@ struct TKikimrEvents : TEvents {
ES_KESUS_PROXY,
ES_KESUS,
ES_CONFIGS_DISPATCHER,
- ES_IAM_SERVICE,
- ES_FOLDER_SERVICE,
+ ES_IAM_SERVICE,
+ ES_FOLDER_SERVICE,
ES_GRPC_MON,
ES_QUOTA,
ES_COORDINATED_QUOTA,
- ES_ACCESS_SERVICE,
- ES_USER_ACCOUNT_SERVICE,
+ ES_ACCESS_SERVICE,
+ ES_USER_ACCOUNT_SERVICE,
ES_PQ_PROXY_NEW,
ES_GRPC_STREAMING,
ES_SCHEME_BOARD,
@@ -113,7 +113,7 @@ struct TKikimrEvents : TEvents {
ES_NET_CLASSIFIER,
ES_SYSTEM_VIEW,
ES_TENANT_NODE_ENUMERATOR,
- ES_SERVICE_ACCOUNT_SERVICE,
+ ES_SERVICE_ACCOUNT_SERVICE,
ES_INDEX_BUILD,
ES_BLOCKSTORE_PRIVATE,
ES_YT_WRAPPER,
@@ -132,7 +132,7 @@ struct TKikimrEvents : TEvents {
ES_TEST_SHARD,
ES_DATASTREAMS_PROXY,
ES_IAM_TOKEN_SERVICE,
- ES_HEALTH_CHECK,
+ ES_HEALTH_CHECK,
ES_DQ = NYql::NDq::TDqEvents::ES_DQ_COMPUTE, // 4212
ES_YQ, // 4213
ES_CHANGE_EXCHANGE,
diff --git a/ydb/core/base/hive.h b/ydb/core/base/hive.h
index ae8d2da8652..7464c76699d 100644
--- a/ydb/core/base/hive.h
+++ b/ydb/core/base/hive.h
@@ -1,9 +1,9 @@
#pragma once
#include "defs.h"
-#include "blobstorage.h"
+#include "blobstorage.h"
#include "events.h"
#include "storage_pools.h"
-#include "subdomain.h"
+#include "subdomain.h"
#include <ydb/core/protos/hive.pb.h>
#include <ydb/core/base/tablet.h>
#include <util/stream/str.h>
@@ -19,31 +19,31 @@ namespace NKikimr {
EvLookupChannelInfo,
EvStopTablet,
- EvTabletMetrics = EvStopTablet + 7, // review 194375
- EvReassignTablet,
- EvInitiateBlockStorage,
+ EvTabletMetrics = EvStopTablet + 7, // review 194375
+ EvReassignTablet,
+ EvInitiateBlockStorage,
EvDeleteTablet,
- EvRequestHiveInfo,
- EvLookupTablet,
- EvDrainNode,
- EvFillNode,
- EvInitiateDeleteStorage,
+ EvRequestHiveInfo,
+ EvLookupTablet,
+ EvDrainNode,
+ EvFillNode,
+ EvInitiateDeleteStorage,
EvGetTabletStorageInfo,
EvLockTabletExecution,
EvUnlockTabletExecution,
EvInitiateTabletExternalBoot,
- EvRequestHiveDomainStats,
+ EvRequestHiveDomainStats,
EvAdoptTable,
- EvInvalidateStoragePools,
- EvRequestHiveNodeStats,
- EvRequestHiveStorageStats,
+ EvInvalidateStoragePools,
+ EvRequestHiveNodeStats,
+ EvRequestHiveStorageStats,
EvDeleteOwnerTablets,
- EvRequestTabletIdSequence,
- EvSeizeTablets,
- EvReleaseTablets,
- EvConfigureHive,
- EvInitMigration,
- EvQueryMigration,
+ EvRequestTabletIdSequence,
+ EvSeizeTablets,
+ EvReleaseTablets,
+ EvConfigureHive,
+ EvInitMigration,
+ EvQueryMigration,
// replies
EvBootTabletReply = EvBootTablet + 512,
@@ -54,25 +54,25 @@ namespace NKikimr {
EvStopTabletResult,
EvDeleteTabletReply,
EvTabletCreationResult,
- EvResponseHiveInfo,
- EvDrainNodeResult,
- EvFillNodeResult,
+ EvResponseHiveInfo,
+ EvDrainNodeResult,
+ EvFillNodeResult,
EvGetTabletStorageInfoResult,
EvGetTabletStorageInfoRegistered,
EvLockTabletExecutionResult,
EvUnlockTabletExecutionResult,
EvLockTabletExecutionLost,
- EvResponseHiveDomainStats,
+ EvResponseHiveDomainStats,
EvAdoptTabletReply,
- EvResponseHiveNodeStats,
- EvResponseHiveStorageStats,
+ EvResponseHiveNodeStats,
+ EvResponseHiveStorageStats,
EvDeleteOwnerTabletsReply,
- EvResponseTabletIdSequence,
- EvResumeTabletResult,
- EvSeizeTabletsReply,
- EvReleaseTabletsReply,
- EvInitMigrationReply,
- EvQueryMigrationReply,
+ EvResponseTabletIdSequence,
+ EvResumeTabletResult,
+ EvSeizeTabletsReply,
+ EvReleaseTabletsReply,
+ EvInitMigrationReply,
+ EvQueryMigrationReply,
EvEnd
};
@@ -122,36 +122,36 @@ namespace NKikimr {
{}
TEvCreateTablet(ui64 ownerId, ui64 ownerIdx,
- TTabletTypes::EType tabletType,
- const TChannelsBindings& bindedChannels) {
+ TTabletTypes::EType tabletType,
+ const TChannelsBindings& bindedChannels) {
Record.SetOwner(ownerId);
Record.SetOwnerIdx(ownerIdx);
Record.SetTabletType(tabletType);
- for (auto& channel : bindedChannels) {
- *Record.AddBindedChannels() = channel;
- }
- }
-
- // deprecated
- TEvCreateTablet(ui64 ownerId,
- ui64 ownerIdx,
- TTabletTypes::EType tabletType) {
- Record.SetOwner(ownerId);
- Record.SetOwnerIdx(ownerIdx);
- Record.SetTabletType(tabletType);
- }
-
- // deprecated
- TEvCreateTablet(ui64 ownerId, ui64 ownerIdx,
- TTabletTypes::EType tabletType,
- const TChannelsBindings& bindedChannels,
- const TVector<ui32>& allowedNodeIDs) {
- Record.SetOwner(ownerId);
- Record.SetOwnerIdx(ownerIdx);
- Record.SetTabletType(tabletType);
- for (ui32 nodeId : allowedNodeIDs) {
- Record.AddAllowedNodeIDs(nodeId);
- }
+ for (auto& channel : bindedChannels) {
+ *Record.AddBindedChannels() = channel;
+ }
+ }
+
+ // deprecated
+ TEvCreateTablet(ui64 ownerId,
+ ui64 ownerIdx,
+ TTabletTypes::EType tabletType) {
+ Record.SetOwner(ownerId);
+ Record.SetOwnerIdx(ownerIdx);
+ Record.SetTabletType(tabletType);
+ }
+
+ // deprecated
+ TEvCreateTablet(ui64 ownerId, ui64 ownerIdx,
+ TTabletTypes::EType tabletType,
+ const TChannelsBindings& bindedChannels,
+ const TVector<ui32>& allowedNodeIDs) {
+ Record.SetOwner(ownerId);
+ Record.SetOwnerIdx(ownerIdx);
+ Record.SetTabletType(tabletType);
+ for (ui32 nodeId : allowedNodeIDs) {
+ Record.AddAllowedNodeIDs(nodeId);
+ }
for (auto& channel : bindedChannels) {
*Record.AddBindedChannels() = channel;
}
@@ -186,25 +186,25 @@ namespace NKikimr {
}
};
- struct TEvCreateTabletReply : TEventPB<TEvCreateTabletReply, NKikimrHive::TEvCreateTabletReply, EvCreateTabletReply> {
- TEvCreateTabletReply() = default;
+ struct TEvCreateTabletReply : TEventPB<TEvCreateTabletReply, NKikimrHive::TEvCreateTabletReply, EvCreateTabletReply> {
+ TEvCreateTabletReply() = default;
- TEvCreateTabletReply(NKikimrProto::EReplyStatus status, ui64 ownerId, ui64 ownerIdx) {
+ TEvCreateTabletReply(NKikimrProto::EReplyStatus status, ui64 ownerId, ui64 ownerIdx) {
Record.SetStatus(status);
Record.SetOwner(ownerId);
Record.SetOwnerIdx(ownerIdx);
- }
-
- TEvCreateTabletReply(NKikimrProto::EReplyStatus status, ui64 ownerId, ui64 ownerIdx, ui64 tabletId)
- : TEvCreateTabletReply(status, ownerId, ownerIdx)
- {
+ }
+
+ TEvCreateTabletReply(NKikimrProto::EReplyStatus status, ui64 ownerId, ui64 ownerIdx, ui64 tabletId)
+ : TEvCreateTabletReply(status, ownerId, ownerIdx)
+ {
if (tabletId != 0)
Record.SetTabletID(tabletId);
- }
-
- TEvCreateTabletReply(NKikimrProto::EReplyStatus status, ui64 ownerId, ui64 ownerIdx, ui64 tabletId, ui64 origin)
- : TEvCreateTabletReply(status, ownerId, ownerIdx, tabletId)
- {
+ }
+
+ TEvCreateTabletReply(NKikimrProto::EReplyStatus status, ui64 ownerId, ui64 ownerIdx, ui64 tabletId, ui64 origin)
+ : TEvCreateTabletReply(status, ownerId, ownerIdx, tabletId)
+ {
Record.SetOrigin(origin);
}
@@ -230,9 +230,9 @@ namespace NKikimr {
if (Record.HasTabletID()) {
str << " TabletID: " << Record.GetTabletID();
}
- if (Record.HasOrigin()) {
- str << " Origin: " << Record.GetOrigin();
- }
+ if (Record.HasOrigin()) {
+ str << " Origin: " << Record.GetOrigin();
+ }
str << "}";
return str.Str();
}
@@ -285,8 +285,8 @@ namespace NKikimr {
}
};
- struct TEvStopTabletResult : TEventPB<TEvStopTabletResult, NKikimrHive::TEvStopTabletResult, EvStopTabletResult> {
- TEvStopTabletResult() = default;
+ struct TEvStopTabletResult : TEventPB<TEvStopTabletResult, NKikimrHive::TEvStopTabletResult, EvStopTabletResult> {
+ TEvStopTabletResult() = default;
TEvStopTabletResult(NKikimrProto::EReplyStatus status, ui64 tabletId) {
Record.SetStatus(status);
@@ -295,30 +295,30 @@ namespace NKikimr {
TString ToString() const {
TStringStream str;
- str << "{EvStopTabletResult Status: " << NKikimrProto::EReplyStatus_Name(Record.GetStatus());
+ str << "{EvStopTabletResult Status: " << NKikimrProto::EReplyStatus_Name(Record.GetStatus());
+ str << " TabletID: " << Record.GetTabletID();
+ str << "}";
+ return str.Str();
+ }
+ };
+
+ struct TEvResumeTabletResult : TEventPB<TEvResumeTabletResult, NKikimrHive::TEvResumeTabletResult, EvResumeTabletResult> {
+ TEvResumeTabletResult() = default;
+
+ TEvResumeTabletResult(NKikimrProto::EReplyStatus status, ui64 tabletId) {
+ Record.SetStatus(status);
+ Record.SetTabletID(tabletId);
+ }
+
+ TString ToString() const {
+ TStringStream str;
+ str << "{EvResumeTabletResult Status: " << NKikimrProto::EReplyStatus_Name(Record.GetStatus());
str << " TabletID: " << Record.GetTabletID();
str << "}";
return str.Str();
}
};
- struct TEvResumeTabletResult : TEventPB<TEvResumeTabletResult, NKikimrHive::TEvResumeTabletResult, EvResumeTabletResult> {
- TEvResumeTabletResult() = default;
-
- TEvResumeTabletResult(NKikimrProto::EReplyStatus status, ui64 tabletId) {
- Record.SetStatus(status);
- Record.SetTabletID(tabletId);
- }
-
- TString ToString() const {
- TStringStream str;
- str << "{EvResumeTabletResult Status: " << NKikimrProto::EReplyStatus_Name(Record.GetStatus());
- str << " TabletID: " << Record.GetTabletID();
- str << "}";
- return str.Str();
- }
- };
-
struct TEvAdoptTablet
: public TEventPB<TEvAdoptTablet, NKikimrHive::TEvAdoptTablet, EvAdoptTable> {
TEvAdoptTablet()
@@ -406,19 +406,19 @@ namespace NKikimr {
struct TEvDeleteTablet : public TEventPB<TEvDeleteTablet, NKikimrHive::TEvDeleteTablet, EvDeleteTablet> {
TEvDeleteTablet()
{}
-
- TEvDeleteTablet(ui64 ownerId, ui64 ownerIdx, ui64 txId) {
+
+ TEvDeleteTablet(ui64 ownerId, ui64 ownerIdx, ui64 txId) {
Record.SetShardOwnerId(ownerId);
Record.AddShardLocalIdx(ownerIdx);
Record.SetTxId_Deprecated(txId);
- }
-
- TEvDeleteTablet(ui64 ownerId, ui64 ownerIdx, ui64 tabletId, ui64 txId) {
- Record.SetShardOwnerId(ownerId);
- Record.AddShardLocalIdx(ownerIdx);
- Record.AddTabletID(tabletId);
- Record.SetTxId_Deprecated(txId);
- }
+ }
+
+ TEvDeleteTablet(ui64 ownerId, ui64 ownerIdx, ui64 tabletId, ui64 txId) {
+ Record.SetShardOwnerId(ownerId);
+ Record.AddShardLocalIdx(ownerIdx);
+ Record.AddTabletID(tabletId);
+ Record.SetTxId_Deprecated(txId);
+ }
};
struct TEvDeleteTabletReply : public TEventPB<TEvDeleteTabletReply,
@@ -428,7 +428,7 @@ namespace NKikimr {
TEvDeleteTabletReply(NKikimrProto::EReplyStatus status, ui64 hiveID, ui64 txId, ui64 ownerId, const TVector<ui64>& localIdxs) {
Record.SetStatus(status);
- Record.SetOrigin(hiveID);
+ Record.SetOrigin(hiveID);
Record.SetTxId_Deprecated(txId);
Record.SetShardOwnerId(ownerId);
for (auto& idx: localIdxs) {
@@ -461,8 +461,8 @@ namespace NKikimr {
}
};
- struct TEvLookupChannelInfo : TEventPB<TEvLookupChannelInfo, NKikimrHive::TEvLookupChannelInfo, EvLookupChannelInfo> {
- TEvLookupChannelInfo() = default;
+ struct TEvLookupChannelInfo : TEventPB<TEvLookupChannelInfo, NKikimrHive::TEvLookupChannelInfo, EvLookupChannelInfo> {
+ TEvLookupChannelInfo() = default;
TEvLookupChannelInfo(ui64 tabletId) {
Record.SetTabletID(tabletId);
@@ -476,8 +476,8 @@ namespace NKikimr {
}
};
- struct TEvChannelInfo : TEventPB<TEvChannelInfo, NKikimrHive::TEvChannelInfo, EvChannelInfo> {
- TEvChannelInfo() = default;
+ struct TEvChannelInfo : TEventPB<TEvChannelInfo, NKikimrHive::TEvChannelInfo, EvChannelInfo> {
+ TEvChannelInfo() = default;
TEvChannelInfo(NKikimrProto::EReplyStatus status, ui64 tabletId) {
Record.SetStatus(status);
@@ -493,115 +493,115 @@ namespace NKikimr {
}
};
- struct TEvTabletMetrics : public TEventPB<TEvTabletMetrics, NKikimrHive::TEvTabletMetrics, EvTabletMetrics> {
-
- };
-
- struct TEvReassignTablet : TEventPB<TEvReassignTablet, NKikimrHive::TEvReassignTablet, EvReassignTablet> {
- TEvReassignTablet() = default;
-
- TEvReassignTablet(ui64 tabletId,
- const TVector<ui32>& channels = {},
- const TVector<ui32>& forcedGroupIds = {})
- {
- Record.SetTabletID(tabletId);
- for (ui32 channel : channels) {
- Record.AddChannels(channel);
- }
- for (ui32 forcedGroupId : forcedGroupIds) {
- Record.AddForcedGroupIDs(forcedGroupId);
- }
- }
- };
-
- struct TEvReassignTabletSpace : TEvReassignTablet {
- TEvReassignTabletSpace(ui64 tabletId,
- const TVector<ui32>& channels = {},
- const TVector<ui32>& forcedGroupIds = {})
- : TEvReassignTablet(tabletId, channels, forcedGroupIds)
- {
- Record.SetReassignReason(NKikimrHive::TEvReassignTablet::HIVE_REASSIGN_REASON_SPACE);
- }
- };
-
- struct TEvInitiateBlockStorage : public TEventLocal<TEvInitiateBlockStorage, EvInitiateBlockStorage> {
- ui64 TabletId;
-
- TEvInitiateBlockStorage(ui64 tabletId)
- : TabletId(tabletId)
- {}
- };
-
- struct TEvInitiateDeleteStorage : public TEventLocal<TEvInitiateDeleteStorage, EvInitiateDeleteStorage> {
- ui64 TabletId;
-
- TEvInitiateDeleteStorage(ui64 tabletId)
- : TabletId(tabletId)
- {}
- };
-
- struct TEvRequestHiveInfo : TEventPB<TEvRequestHiveInfo, NKikimrHive::TEvRequestHiveInfo, EvRequestHiveInfo> {
- TEvRequestHiveInfo() = default;
-
+ struct TEvTabletMetrics : public TEventPB<TEvTabletMetrics, NKikimrHive::TEvTabletMetrics, EvTabletMetrics> {
+
+ };
+
+ struct TEvReassignTablet : TEventPB<TEvReassignTablet, NKikimrHive::TEvReassignTablet, EvReassignTablet> {
+ TEvReassignTablet() = default;
+
+ TEvReassignTablet(ui64 tabletId,
+ const TVector<ui32>& channels = {},
+ const TVector<ui32>& forcedGroupIds = {})
+ {
+ Record.SetTabletID(tabletId);
+ for (ui32 channel : channels) {
+ Record.AddChannels(channel);
+ }
+ for (ui32 forcedGroupId : forcedGroupIds) {
+ Record.AddForcedGroupIDs(forcedGroupId);
+ }
+ }
+ };
+
+ struct TEvReassignTabletSpace : TEvReassignTablet {
+ TEvReassignTabletSpace(ui64 tabletId,
+ const TVector<ui32>& channels = {},
+ const TVector<ui32>& forcedGroupIds = {})
+ : TEvReassignTablet(tabletId, channels, forcedGroupIds)
+ {
+ Record.SetReassignReason(NKikimrHive::TEvReassignTablet::HIVE_REASSIGN_REASON_SPACE);
+ }
+ };
+
+ struct TEvInitiateBlockStorage : public TEventLocal<TEvInitiateBlockStorage, EvInitiateBlockStorage> {
+ ui64 TabletId;
+
+ TEvInitiateBlockStorage(ui64 tabletId)
+ : TabletId(tabletId)
+ {}
+ };
+
+ struct TEvInitiateDeleteStorage : public TEventLocal<TEvInitiateDeleteStorage, EvInitiateDeleteStorage> {
+ ui64 TabletId;
+
+ TEvInitiateDeleteStorage(ui64 tabletId)
+ : TabletId(tabletId)
+ {}
+ };
+
+ struct TEvRequestHiveInfo : TEventPB<TEvRequestHiveInfo, NKikimrHive::TEvRequestHiveInfo, EvRequestHiveInfo> {
+ TEvRequestHiveInfo() = default;
+
TEvRequestHiveInfo(bool returnFollowers) {
Record.SetReturnFollowers(returnFollowers);
- }
+ }
TEvRequestHiveInfo(ui64 tabletId, bool returnFollowers) {
Record.SetTabletID(tabletId);
Record.SetReturnFollowers(returnFollowers);
}
- };
-
- struct TEvResponseHiveInfo : TEventPB<TEvResponseHiveInfo, NKikimrHive::TEvResponseHiveInfo, EvResponseHiveInfo> {};
-
- struct TEvLookupTablet : public TEventPB<TEvLookupTablet, NKikimrHive::TEvLookupTablet, EvLookupTablet> {
- TEvLookupTablet() = default;
-
- TEvLookupTablet(ui64 ownerId, ui64 ownerIdx) {
- Record.SetOwner(ownerId);
- Record.SetOwnerIdx(ownerIdx);
- }
- };
-
- using TEvCutTabletHistory = TEvTablet::TEvCutTabletHistory;
-
- struct TEvDrainNode : TEventPB<TEvDrainNode, NKikimrHive::TEvDrainNode, EvDrainNode> {
- TEvDrainNode() = default;
-
- TEvDrainNode(ui32 nodeId) {
- Record.SetNodeID(nodeId);
- }
- };
-
- struct TEvDrainNodeResult : TEventPB<TEvDrainNodeResult, NKikimrHive::TEvDrainNodeResult, EvDrainNodeResult> {
- TEvDrainNodeResult() = default;
-
- TEvDrainNodeResult(NKikimrProto::EReplyStatus status) {
- Record.SetStatus(status);
- }
-
- TEvDrainNodeResult(NKikimrProto::EReplyStatus status, ui32 movements)
- : TEvDrainNodeResult(status)
- {
- Record.SetMovements(movements);
- }
- };
-
- struct TEvFillNode : TEventPB<TEvFillNode, NKikimrHive::TEvFillNode, EvFillNode> {
- TEvFillNode() = default;
-
- TEvFillNode(ui32 nodeId) {
- Record.SetNodeID(nodeId);
- }
- };
-
- struct TEvFillNodeResult : TEventPB<TEvFillNodeResult, NKikimrHive::TEvFillNodeResult, EvFillNodeResult> {
- TEvFillNodeResult() = default;
-
- TEvFillNodeResult(NKikimrProto::EReplyStatus status) {
- Record.SetStatus(status);
- }
- };
+ };
+
+ struct TEvResponseHiveInfo : TEventPB<TEvResponseHiveInfo, NKikimrHive::TEvResponseHiveInfo, EvResponseHiveInfo> {};
+
+ struct TEvLookupTablet : public TEventPB<TEvLookupTablet, NKikimrHive::TEvLookupTablet, EvLookupTablet> {
+ TEvLookupTablet() = default;
+
+ TEvLookupTablet(ui64 ownerId, ui64 ownerIdx) {
+ Record.SetOwner(ownerId);
+ Record.SetOwnerIdx(ownerIdx);
+ }
+ };
+
+ using TEvCutTabletHistory = TEvTablet::TEvCutTabletHistory;
+
+ struct TEvDrainNode : TEventPB<TEvDrainNode, NKikimrHive::TEvDrainNode, EvDrainNode> {
+ TEvDrainNode() = default;
+
+ TEvDrainNode(ui32 nodeId) {
+ Record.SetNodeID(nodeId);
+ }
+ };
+
+ struct TEvDrainNodeResult : TEventPB<TEvDrainNodeResult, NKikimrHive::TEvDrainNodeResult, EvDrainNodeResult> {
+ TEvDrainNodeResult() = default;
+
+ TEvDrainNodeResult(NKikimrProto::EReplyStatus status) {
+ Record.SetStatus(status);
+ }
+
+ TEvDrainNodeResult(NKikimrProto::EReplyStatus status, ui32 movements)
+ : TEvDrainNodeResult(status)
+ {
+ Record.SetMovements(movements);
+ }
+ };
+
+ struct TEvFillNode : TEventPB<TEvFillNode, NKikimrHive::TEvFillNode, EvFillNode> {
+ TEvFillNode() = default;
+
+ TEvFillNode(ui32 nodeId) {
+ Record.SetNodeID(nodeId);
+ }
+ };
+
+ struct TEvFillNodeResult : TEventPB<TEvFillNodeResult, NKikimrHive::TEvFillNodeResult, EvFillNodeResult> {
+ TEvFillNodeResult() = default;
+
+ TEvFillNodeResult(NKikimrProto::EReplyStatus status) {
+ Record.SetStatus(status);
+ }
+ };
struct TEvGetTabletStorageInfo : public TEventPB<TEvGetTabletStorageInfo,
NKikimrHive::TEvGetTabletStorageInfo, EvGetTabletStorageInfo>
@@ -709,101 +709,101 @@ namespace NKikimr {
Record.SetTabletID(tabletId);
}
};
-
- struct TEvRequestHiveDomainStats : TEventPB<TEvRequestHiveDomainStats, NKikimrHive::TEvRequestHiveDomainStats, EvRequestHiveDomainStats> {
- TEvRequestHiveDomainStats() = default;
- };
-
- struct TEvResponseHiveDomainStats : TEventPB<TEvResponseHiveDomainStats, NKikimrHive::TEvResponseHiveDomainStats, EvResponseHiveDomainStats> {
- TEvResponseHiveDomainStats() = default;
- };
-
- struct TEvInvalidateStoragePools : TEventPB<TEvInvalidateStoragePools, NKikimrHive::TEvInvalidateStoragePools, EvInvalidateStoragePools> {
- TEvInvalidateStoragePools() = default;
- };
-
- struct TEvRequestHiveNodeStats : TEventPB<TEvRequestHiveNodeStats, NKikimrHive::TEvRequestHiveNodeStats, EvRequestHiveNodeStats> {
- TEvRequestHiveNodeStats() = default;
- };
-
- struct TEvResponseHiveNodeStats : TEventPB<TEvResponseHiveNodeStats, NKikimrHive::TEvResponseHiveNodeStats, EvResponseHiveNodeStats> {
- TEvResponseHiveNodeStats() = default;
- };
-
- struct TEvRequestHiveStorageStats : TEventPB<TEvRequestHiveStorageStats, NKikimrHive::TEvRequestHiveStorageStats, EvRequestHiveStorageStats> {
- TEvRequestHiveStorageStats() = default;
- };
-
- struct TEvResponseHiveStorageStats : TEventPB<TEvResponseHiveStorageStats, NKikimrHive::TEvResponseHiveStorageStats, EvResponseHiveStorageStats> {
- TEvResponseHiveStorageStats() = default;
- };
-
- struct TEvRequestTabletIdSequence : TEventPB<TEvRequestTabletIdSequence, NKikimrHive::TEvRequestTabletIdSequence, EvRequestTabletIdSequence> {
- TEvRequestTabletIdSequence() = default;
-
- TEvRequestTabletIdSequence(ui64 ownerId, ui64 ownerIdx, size_t size) {
- Record.MutableOwner()->SetOwner(ownerId);
- Record.MutableOwner()->SetOwnerIdx(ownerIdx);
- Record.SetSize(size);
- }
- };
-
- struct TEvResponseTabletIdSequence : TEventPB<TEvResponseTabletIdSequence, NKikimrHive::TEvResponseTabletIdSequence, EvResponseTabletIdSequence> {
- TEvResponseTabletIdSequence() = default;
- };
-
- struct TEvSeizeTablets : TEventPB<TEvSeizeTablets, NKikimrHive::TEvSeizeTablets, EvSeizeTablets> {
- TEvSeizeTablets() = default;
-
- TEvSeizeTablets(const NKikimrHive::TEvSeizeTablets& settings) {
- Record = settings;
- }
- };
-
- struct TEvSeizeTabletsReply : TEventPB<TEvSeizeTabletsReply, NKikimrHive::TEvSeizeTabletsReply, EvSeizeTabletsReply> {
- TEvSeizeTabletsReply() = default;
- };
-
- struct TEvReleaseTablets : TEventPB<TEvReleaseTablets, NKikimrHive::TEvReleaseTablets, EvReleaseTablets> {
- TEvReleaseTablets() = default;
- };
-
- struct TEvReleaseTabletsReply : TEventPB<TEvReleaseTabletsReply, NKikimrHive::TEvReleaseTabletsReply, EvReleaseTabletsReply> {
- TEvReleaseTabletsReply() = default;
- };
-
- struct TEvConfigureHive : TEventPB<TEvConfigureHive, NKikimrHive::TEvConfigureHive, EvConfigureHive> {
- TEvConfigureHive() = default;
-
- TEvConfigureHive(TSubDomainKey subdomain) {
- Record.MutableDomain()->CopyFrom(subdomain);
- }
- };
-
- struct TEvInitMigration : TEventPB<TEvInitMigration, NKikimrHive::TEvInitMigration, EvInitMigration> {
- TEvInitMigration() = default;
- };
-
- struct TEvInitMigrationReply : TEventPB<TEvInitMigrationReply, NKikimrHive::TEvInitMigrationReply, EvInitMigrationReply> {
- TEvInitMigrationReply() = default;
-
- TEvInitMigrationReply(NKikimrProto::EReplyStatus status) {
- Record.SetStatus(status);
- }
- };
-
- struct TEvQueryMigration : TEventPB<TEvQueryMigration, NKikimrHive::TEvQueryMigration, EvQueryMigration> {
- TEvQueryMigration() = default;
- };
-
- struct TEvQueryMigrationReply : TEventPB<TEvQueryMigrationReply, NKikimrHive::TEvQueryMigrationReply, EvQueryMigrationReply> {
- TEvQueryMigrationReply() = default;
-
- TEvQueryMigrationReply(NKikimrHive::EMigrationState state, i32 progress) {
- Record.SetMigrationState(state);
- Record.SetMigrationProgress(progress);
- }
- };
+
+ struct TEvRequestHiveDomainStats : TEventPB<TEvRequestHiveDomainStats, NKikimrHive::TEvRequestHiveDomainStats, EvRequestHiveDomainStats> {
+ TEvRequestHiveDomainStats() = default;
+ };
+
+ struct TEvResponseHiveDomainStats : TEventPB<TEvResponseHiveDomainStats, NKikimrHive::TEvResponseHiveDomainStats, EvResponseHiveDomainStats> {
+ TEvResponseHiveDomainStats() = default;
+ };
+
+ struct TEvInvalidateStoragePools : TEventPB<TEvInvalidateStoragePools, NKikimrHive::TEvInvalidateStoragePools, EvInvalidateStoragePools> {
+ TEvInvalidateStoragePools() = default;
+ };
+
+ struct TEvRequestHiveNodeStats : TEventPB<TEvRequestHiveNodeStats, NKikimrHive::TEvRequestHiveNodeStats, EvRequestHiveNodeStats> {
+ TEvRequestHiveNodeStats() = default;
+ };
+
+ struct TEvResponseHiveNodeStats : TEventPB<TEvResponseHiveNodeStats, NKikimrHive::TEvResponseHiveNodeStats, EvResponseHiveNodeStats> {
+ TEvResponseHiveNodeStats() = default;
+ };
+
+ struct TEvRequestHiveStorageStats : TEventPB<TEvRequestHiveStorageStats, NKikimrHive::TEvRequestHiveStorageStats, EvRequestHiveStorageStats> {
+ TEvRequestHiveStorageStats() = default;
+ };
+
+ struct TEvResponseHiveStorageStats : TEventPB<TEvResponseHiveStorageStats, NKikimrHive::TEvResponseHiveStorageStats, EvResponseHiveStorageStats> {
+ TEvResponseHiveStorageStats() = default;
+ };
+
+ struct TEvRequestTabletIdSequence : TEventPB<TEvRequestTabletIdSequence, NKikimrHive::TEvRequestTabletIdSequence, EvRequestTabletIdSequence> {
+ TEvRequestTabletIdSequence() = default;
+
+ TEvRequestTabletIdSequence(ui64 ownerId, ui64 ownerIdx, size_t size) {
+ Record.MutableOwner()->SetOwner(ownerId);
+ Record.MutableOwner()->SetOwnerIdx(ownerIdx);
+ Record.SetSize(size);
+ }
+ };
+
+ struct TEvResponseTabletIdSequence : TEventPB<TEvResponseTabletIdSequence, NKikimrHive::TEvResponseTabletIdSequence, EvResponseTabletIdSequence> {
+ TEvResponseTabletIdSequence() = default;
+ };
+
+ struct TEvSeizeTablets : TEventPB<TEvSeizeTablets, NKikimrHive::TEvSeizeTablets, EvSeizeTablets> {
+ TEvSeizeTablets() = default;
+
+ TEvSeizeTablets(const NKikimrHive::TEvSeizeTablets& settings) {
+ Record = settings;
+ }
+ };
+
+ struct TEvSeizeTabletsReply : TEventPB<TEvSeizeTabletsReply, NKikimrHive::TEvSeizeTabletsReply, EvSeizeTabletsReply> {
+ TEvSeizeTabletsReply() = default;
+ };
+
+ struct TEvReleaseTablets : TEventPB<TEvReleaseTablets, NKikimrHive::TEvReleaseTablets, EvReleaseTablets> {
+ TEvReleaseTablets() = default;
+ };
+
+ struct TEvReleaseTabletsReply : TEventPB<TEvReleaseTabletsReply, NKikimrHive::TEvReleaseTabletsReply, EvReleaseTabletsReply> {
+ TEvReleaseTabletsReply() = default;
+ };
+
+ struct TEvConfigureHive : TEventPB<TEvConfigureHive, NKikimrHive::TEvConfigureHive, EvConfigureHive> {
+ TEvConfigureHive() = default;
+
+ TEvConfigureHive(TSubDomainKey subdomain) {
+ Record.MutableDomain()->CopyFrom(subdomain);
+ }
+ };
+
+ struct TEvInitMigration : TEventPB<TEvInitMigration, NKikimrHive::TEvInitMigration, EvInitMigration> {
+ TEvInitMigration() = default;
+ };
+
+ struct TEvInitMigrationReply : TEventPB<TEvInitMigrationReply, NKikimrHive::TEvInitMigrationReply, EvInitMigrationReply> {
+ TEvInitMigrationReply() = default;
+
+ TEvInitMigrationReply(NKikimrProto::EReplyStatus status) {
+ Record.SetStatus(status);
+ }
+ };
+
+ struct TEvQueryMigration : TEventPB<TEvQueryMigration, NKikimrHive::TEvQueryMigration, EvQueryMigration> {
+ TEvQueryMigration() = default;
+ };
+
+ struct TEvQueryMigrationReply : TEventPB<TEvQueryMigrationReply, NKikimrHive::TEvQueryMigrationReply, EvQueryMigrationReply> {
+ TEvQueryMigrationReply() = default;
+
+ TEvQueryMigrationReply(NKikimrHive::EMigrationState state, i32 progress) {
+ Record.SetMigrationState(state);
+ Record.SetMigrationProgress(progress);
+ }
+ };
};
IActor* CreateDefaultHive(const TActorId &tablet, TTabletStorageInfo *info);
diff --git a/ydb/core/base/localdb.cpp b/ydb/core/base/localdb.cpp
index 4e4a7dcfd7a..d07ee26fc1f 100644
--- a/ydb/core/base/localdb.cpp
+++ b/ydb/core/base/localdb.cpp
@@ -1,11 +1,11 @@
#include "localdb.h"
#include "compile_time_flags.h"
-
+
#include <ydb/core/protos/resource_broker.pb.h>
-namespace NKikimr {
+namespace NKikimr {
namespace NLocalDb {
-
+
TCompactionPolicy::TBackgroundPolicy::TBackgroundPolicy()
: Threshold(101)
, PriorityBase(100)
@@ -201,8 +201,8 @@ TCompactionPolicyPtr CreateDefaultTablePolicy() {
policy->ShardPolicy.SetTaskPriorityBase(100);
#endif
return policy;
-}
-
+}
+
TCompactionPolicyPtr CreateDefaultUserTablePolicy() {
TCompactionPolicyPtr userPolicy = new TCompactionPolicy();
userPolicy->Generations.reserve(3);
@@ -216,8 +216,8 @@ TCompactionPolicyPtr CreateDefaultUserTablePolicy() {
userPolicy->CompactionStrategy = NKikimrSchemeOp::CompactionStrategySharded;
#endif
return userPolicy;
-}
-
+}
+
bool ValidateCompactionPolicyChange(const TCompactionPolicy& oldPolicy, const TCompactionPolicy& newPolicy, TString& err) {
if (newPolicy.Generations.size() < oldPolicy.Generations.size()) {
err = Sprintf("Decreasing number of levels in compaction policy in not supported, old level count %u, new level count %u",
diff --git a/ydb/core/base/localdb.h b/ydb/core/base/localdb.h
index 7170aebe8bd..8679cb286fc 100644
--- a/ydb/core/base/localdb.h
+++ b/ydb/core/base/localdb.h
@@ -1,8 +1,8 @@
#pragma once
#include "defs.h"
#include <util/generic/map.h>
-#include <util/generic/hash_set.h>
-#include <util/generic/list.h>
+#include <util/generic/hash_set.h>
+#include <util/generic/list.h>
#include <ydb/core/protos/flat_scheme_op.pb.h>
#include <ydb/core/util/yverify_stream.h>
#include <google/protobuf/util/message_differencer.h>
@@ -45,7 +45,7 @@ struct TCompactionPolicy : public TThrRefBase {
ui64 ExtraCompactionMinSize;
ui64 ExtraCompactionExpMaxSize;
ui64 UpliftPartSize;
-
+
TGenerationPolicy(ui64 sizeToCompact, ui32 countToCompact, ui32 forceCountToCompact,
ui64 forceSizeToCompact, const TString &resourceBrokerTask,
bool keepInCache,
@@ -54,11 +54,11 @@ struct TCompactionPolicy : public TThrRefBase {
void Serialize(NKikimrSchemeOp::TCompactionPolicy::TGenerationPolicy& policyPb) const;
- bool operator ==(const TGenerationPolicy& p) const {
- return SizeToCompact == p.SizeToCompact
- && CountToCompact == p.CountToCompact
- && ForceCountToCompact == p.ForceCountToCompact
- && ForceSizeToCompact == p.ForceSizeToCompact
+ bool operator ==(const TGenerationPolicy& p) const {
+ return SizeToCompact == p.SizeToCompact
+ && CountToCompact == p.CountToCompact
+ && ForceCountToCompact == p.ForceCountToCompact
+ && ForceSizeToCompact == p.ForceSizeToCompact
&& CompactionBrokerQueue == p.CompactionBrokerQueue
&& ResourceBrokerTask == p.ResourceBrokerTask
&& KeepInCache == p.KeepInCache
@@ -68,7 +68,7 @@ struct TCompactionPolicy : public TThrRefBase {
&& ExtraCompactionMinSize == p.ExtraCompactionMinSize
&& ExtraCompactionExpMaxSize == p.ExtraCompactionExpMaxSize
&& UpliftPartSize == p.UpliftPartSize;
- }
+ }
};
ui64 InMemSizeToSnapshot;
@@ -99,12 +99,12 @@ struct TCompactionPolicy : public TThrRefBase {
explicit TCompactionPolicy(const NKikimrSchemeOp::TCompactionPolicy& policyPb);
void Serialize(NKikimrSchemeOp::TCompactionPolicy& policyPb) const;
-
- bool operator ==(const TCompactionPolicy& p) const {
- return InMemSizeToSnapshot == p.InMemSizeToSnapshot
- && InMemStepsToSnapshot == p.InMemStepsToSnapshot
- && InMemForceStepsToSnapshot == p.InMemForceStepsToSnapshot
- && InMemForceSizeToSnapshot == p.InMemForceSizeToSnapshot
+
+ bool operator ==(const TCompactionPolicy& p) const {
+ return InMemSizeToSnapshot == p.InMemSizeToSnapshot
+ && InMemStepsToSnapshot == p.InMemStepsToSnapshot
+ && InMemForceStepsToSnapshot == p.InMemForceStepsToSnapshot
+ && InMemForceSizeToSnapshot == p.InMemForceSizeToSnapshot
&& InMemCompactionBrokerQueue == p.InMemCompactionBrokerQueue
&& InMemResourceBrokerTask == p.InMemResourceBrokerTask
&& ReadAheadHiThreshold == p.ReadAheadHiThreshold
@@ -123,11 +123,11 @@ struct TCompactionPolicy : public TThrRefBase {
&& CompactionStrategy == p.CompactionStrategy
&& KeepEraseMarkers == p.KeepEraseMarkers
&& ::google::protobuf::util::MessageDifferencer::Equals(ShardPolicy, p.ShardPolicy);
- }
+ }
};
typedef TIntrusivePtr<TCompactionPolicy> TCompactionPolicyPtr;
-
+
TCompactionPolicyPtr CreateDefaultTablePolicy();
TCompactionPolicyPtr CreateDefaultUserTablePolicy();
diff --git a/ydb/core/base/pathid.h b/ydb/core/base/pathid.h
index d2ef8faced6..e974f846134 100644
--- a/ydb/core/base/pathid.h
+++ b/ydb/core/base/pathid.h
@@ -55,15 +55,15 @@ struct THash<NKikimr::TPathId> {
}
};
-namespace std {
-template <>
-struct hash<NKikimr::TPathId> {
- size_t operator()(const NKikimr::TPathId& x) const {
- return x.Hash();
- }
-};
-}
-
+namespace std {
+template <>
+struct hash<NKikimr::TPathId> {
+ size_t operator()(const NKikimr::TPathId& x) const {
+ return x.Hash();
+ }
+};
+}
+
template<>
inline void Out<NKikimr::TPathId>(IOutputStream& o, const NKikimr::TPathId& x) {
return x.Out(o);
diff --git a/ydb/core/base/pool_stats_collector.cpp b/ydb/core/base/pool_stats_collector.cpp
index aa0bac28cd1..7dcbf28954d 100644
--- a/ydb/core/base/pool_stats_collector.cpp
+++ b/ydb/core/base/pool_stats_collector.cpp
@@ -43,12 +43,12 @@ private:
void OnWakeup(const TActorContext &ctx) override {
MiniKQLPoolStats.Update();
- TVector<std::tuple<TString, double, ui32>> pools;
+ TVector<std::tuple<TString, double, ui32>> pools;
for (const auto& pool : PoolCounters) {
- pools.emplace_back(pool.Name, pool.Usage, pool.Threads);
+ pools.emplace_back(pool.Name, pool.Usage, pool.Threads);
}
- ctx.Send(NNodeWhiteboard::MakeNodeWhiteboardServiceId(ctx.SelfID.NodeId()), new NNodeWhiteboard::TEvWhiteboard::TEvSystemStateUpdate(pools));
+ ctx.Send(NNodeWhiteboard::MakeNodeWhiteboardServiceId(ctx.SelfID.NodeId()), new NNodeWhiteboard::TEvWhiteboard::TEvSystemStateUpdate(pools));
}
private:
diff --git a/ydb/core/base/statestorage.cpp b/ydb/core/base/statestorage.cpp
index 7674a887a94..de39a327ae1 100644
--- a/ydb/core/base/statestorage.cpp
+++ b/ydb/core/base/statestorage.cpp
@@ -108,11 +108,11 @@ TList<TActorId> TStateStorageInfo::SelectAllReplicas() const {
for (auto &ring : Rings) {
for (TActorId replica : ring.Replicas)
replicas.push_back(replica);
- }
+ }
+
+ return replicas;
+}
- return replicas;
-}
-
ui32 TStateStorageInfo::TRing::ContentHash() const {
ui64 hash = 17;
for (TActorId replica : Replicas) {
diff --git a/ydb/core/base/statestorage.h b/ydb/core/base/statestorage.h
index 0cb853f5264..9b3e3b6b1b7 100644
--- a/ydb/core/base/statestorage.h
+++ b/ydb/core/base/statestorage.h
@@ -5,7 +5,7 @@
#include <ydb/core/protos/config.pb.h>
#include <library/cpp/actors/interconnect/event_filter.h>
#include <util/stream/str.h>
-#include <util/generic/list.h>
+#include <util/generic/list.h>
#include <util/generic/map.h>
namespace NKikimr {
@@ -17,8 +17,8 @@ struct TEvStateStorage {
EvUpdate,
EvLock,
EvResolveReplicas,
- EvRequestReplicasDumps,
- EvDelete,
+ EvRequestReplicasDumps,
+ EvDelete,
EvCleanup,
EvResolveBoard,
EvBoardInfo,
@@ -30,8 +30,8 @@ struct TEvStateStorage {
EvInfo = EvLookup + 512,
EvUpdateSignature,
EvResolveReplicasList,
- EvResponseReplicasDumps,
- EvDeleteResult,
+ EvResponseReplicasDumps,
+ EvDeleteResult,
EvListSchemeBoardResult,
// replicas interface
@@ -39,11 +39,11 @@ struct TEvStateStorage {
EvReplicaUpdate,
EvReplicaLock,
EvReplicaLeaderDemoted,
- EvReplicaDumpRequest,
- EvReplicaDump,
+ EvReplicaDumpRequest,
+ EvReplicaDump,
EvReplicaRegFollower,
EvReplicaUnregFollower,
- EvReplicaDelete,
+ EvReplicaDelete,
EvReplicaCleanup,
EvReplicaInfo = EvLock + 3 * 512,
@@ -157,24 +157,24 @@ struct TEvStateStorage {
}
};
- struct TEvDelete : TEventLocal<TEvDelete, EvDelete> {
- const ui64 TabletID;
- const ui64 Cookie;
-
- TEvDelete(ui64 tabletId, ui64 cookie = 0)
- : TabletID(tabletId)
- , Cookie(cookie)
- {}
-
+ struct TEvDelete : TEventLocal<TEvDelete, EvDelete> {
+ const ui64 TabletID;
+ const ui64 Cookie;
+
+ TEvDelete(ui64 tabletId, ui64 cookie = 0)
+ : TabletID(tabletId)
+ , Cookie(cookie)
+ {}
+
TString ToString() const {
- TStringStream str;
- str << "{EvDelete TabletID: " << TabletID;
- str << " Cookie: " << Cookie;
- str << "}";
- return str.Str();
- }
- };
-
+ TStringStream str;
+ str << "{EvDelete TabletID: " << TabletID;
+ str << " Cookie: " << Cookie;
+ str << "}";
+ return str.Str();
+ }
+ };
+
struct TEvCleanup : TEventLocal<TEvCleanup, EvCleanup> {
const ui64 TabletID;
const TActorId ProposedLeader;
@@ -185,24 +185,24 @@ struct TEvStateStorage {
{}
};
- struct TEvDeleteResult : TEventLocal<TEvDeleteResult, EvDeleteResult> {
- const ui64 TabletID;
- const NKikimrProto::EReplyStatus Status;
-
- TEvDeleteResult(ui64 tabletId, NKikimrProto::EReplyStatus status)
- : TabletID(tabletId)
- , Status(status)
- {}
-
+ struct TEvDeleteResult : TEventLocal<TEvDeleteResult, EvDeleteResult> {
+ const ui64 TabletID;
+ const NKikimrProto::EReplyStatus Status;
+
+ TEvDeleteResult(ui64 tabletId, NKikimrProto::EReplyStatus status)
+ : TabletID(tabletId)
+ , Status(status)
+ {}
+
TString ToString() const {
- TStringStream str;
- str << "{EvDeleteResult TabletID: " << TabletID;
- str << " Status: " << (ui32)Status;
- str << "}";
- return str.Str();
- }
- };
-
+ TStringStream str;
+ str << "{EvDeleteResult TabletID: " << TabletID;
+ str << " Status: " << (ui32)Status;
+ str << "}";
+ return str.Str();
+ }
+ };
+
struct TEvLock : public TEventLocal<TEvLock, EvLock> {
const ui64 TabletID;
const ui64 Cookie;
@@ -307,12 +307,12 @@ struct TEvStateStorage {
str << " Followers: [";
for (auto it = Followers.begin(); it != Followers.end(); ++it) {
if (it != Followers.begin()) {
- str << ',';
- }
- str << '{' << it->first.ToString() << ',' << it->second.ToString() << '}';
- }
- str << "]";
- }
+ str << ',';
+ }
+ str << '{' << it->first.ToString() << ',' << it->second.ToString() << '}';
+ }
+ str << "]";
+ }
str << "}";
return str.Str();
}
@@ -364,7 +364,7 @@ struct TEvStateStorage {
struct TEvReplicaInfo;
struct TEvReplicaUpdate;
struct TEvReplicaLock;
- struct TEvReplicaDelete;
+ struct TEvReplicaDelete;
struct TEvReplicaCleanup;
struct TEvReplicaBoardPublish;
struct TEvReplicaBoardLookup;
@@ -378,23 +378,23 @@ struct TEvStateStorage {
struct TEvReplicaProbeUnsubscribe;
struct TEvReplicaProbeConnected;
struct TEvReplicaProbeDisconnected;
-
+
struct TEvReplicaShutdown : public TEventPB<TEvStateStorage::TEvReplicaShutdown, NKikimrStateStorage::TEvReplicaShutdown, TEvStateStorage::EvReplicaShutdown> {
};
- struct TEvReplicaDumpRequest : public TEventPB<TEvReplicaDumpRequest, NKikimrStateStorage::TEvDumpRequest, EvReplicaDumpRequest> {
- };
-
- struct TEvReplicaDump : public TEventPB<TEvReplicaDump, NKikimrStateStorage::TEvDump, EvReplicaDump> {
- };
-
- struct TEvRequestReplicasDumps : public TEventLocal<TEvRequestReplicasDumps, EvRequestReplicasDumps> {
-
- };
-
- struct TEvResponseReplicasDumps : public TEventLocal<TEvResponseReplicasDumps, EvResponseReplicasDumps> {
+ struct TEvReplicaDumpRequest : public TEventPB<TEvReplicaDumpRequest, NKikimrStateStorage::TEvDumpRequest, EvReplicaDumpRequest> {
+ };
+
+ struct TEvReplicaDump : public TEventPB<TEvReplicaDump, NKikimrStateStorage::TEvDump, EvReplicaDump> {
+ };
+
+ struct TEvRequestReplicasDumps : public TEventLocal<TEvRequestReplicasDumps, EvRequestReplicasDumps> {
+
+ };
+
+ struct TEvResponseReplicasDumps : public TEventLocal<TEvResponseReplicasDumps, EvResponseReplicasDumps> {
TVector<std::pair<TActorId, TAutoPtr<TEvReplicaDump>>> ReplicasDumps;
- };
+ };
struct TEvReplicaRegFollower : public TEventPB<TEvReplicaRegFollower, NKikimrStateStorage::TEvRegisterFollower, EvReplicaRegFollower> {
TEvReplicaRegFollower()
diff --git a/ydb/core/base/statestorage_impl.h b/ydb/core/base/statestorage_impl.h
index 0beea790b03..2a2aa22f6a7 100644
--- a/ydb/core/base/statestorage_impl.h
+++ b/ydb/core/base/statestorage_impl.h
@@ -216,23 +216,23 @@ struct TEvStateStorage::TEvReplicaUpdate : public TEventPB<TEvStateStorage::TEvR
}
};
-struct TEvStateStorage::TEvReplicaDelete : public TEventPB<TEvStateStorage::TEvReplicaDelete, NKikimrStateStorage::TEvDelete, TEvStateStorage::EvReplicaDelete> {
- TEvReplicaDelete()
- {}
-
- TEvReplicaDelete(ui64 tabletId)
- {
- Record.SetTabletID(tabletId);
- }
-
+struct TEvStateStorage::TEvReplicaDelete : public TEventPB<TEvStateStorage::TEvReplicaDelete, NKikimrStateStorage::TEvDelete, TEvStateStorage::EvReplicaDelete> {
+ TEvReplicaDelete()
+ {}
+
+ TEvReplicaDelete(ui64 tabletId)
+ {
+ Record.SetTabletID(tabletId);
+ }
+
TString ToString() const {
- TStringStream str;
- str << "{EvReplicaUpdate TabletID: " << Record.GetTabletID();
- str << "}";
- return str.Str();
- }
-};
-
+ TStringStream str;
+ str << "{EvReplicaUpdate TabletID: " << Record.GetTabletID();
+ str << "}";
+ return str.Str();
+ }
+};
+
struct TEvStateStorage::TEvReplicaCleanup : public TEventPB<TEvStateStorage::TEvReplicaCleanup, NKikimrStateStorage::TEvCleanup, TEvStateStorage::EvReplicaCleanup> {
TEvReplicaCleanup()
{}
diff --git a/ydb/core/base/statestorage_proxy.cpp b/ydb/core/base/statestorage_proxy.cpp
index 68e00a671a7..13d396cb0f1 100644
--- a/ydb/core/base/statestorage_proxy.cpp
+++ b/ydb/core/base/statestorage_proxy.cpp
@@ -538,9 +538,9 @@ public:
hFunc(TEvStateStorage::TEvLock, HandleInit);
default:
BLOG_W("ProxyRequest::StateInit unexpected event type# "
- << ev->GetTypeRewrite()
- << " event: "
- << TString(ev->HasEvent() ? ev->GetBase()->ToString() : "serialized?"));
+ << ev->GetTypeRewrite()
+ << " event: "
+ << TString(ev->HasEvent() ? ev->GetBase()->ToString() : "serialized?"));
break;
}
}
@@ -556,9 +556,9 @@ public:
cFunc(TEvents::TSystem::Wakeup, HandleLookupTimeout);
default:
BLOG_W("ProxyRequest::StateLookup unexpected event type# "
- << ev->GetTypeRewrite()
- << " event: "
- << TString(ev->HasEvent() ? ev->GetBase()->ToString() : "serialized?"));
+ << ev->GetTypeRewrite()
+ << " event: "
+ << TString(ev->HasEvent() ? ev->GetBase()->ToString() : "serialized?"));
break;
}
}
@@ -573,9 +573,9 @@ public:
cFunc(TEvents::TSystem::Wakeup, HandleUpdateTimeout);
default:
BLOG_W("ProxyRequest::StateUpdate unexpected event type# "
- << ev->GetTypeRewrite()
- << " event: "
- << TString(ev->HasEvent() ? ev->GetBase()->ToString() : "serialized?"));
+ << ev->GetTypeRewrite()
+ << " event: "
+ << TString(ev->HasEvent() ? ev->GetBase()->ToString() : "serialized?"));
break;
}
}
@@ -591,148 +591,148 @@ public:
default:
BLOG_W("ProxyRequest::StateUpdateSig unexpected event type# "
<< ev->GetTypeRewrite()
- << " event: "
- << TString(ev->HasEvent() ? ev->GetBase()->ToString() : "serialized?"));
+ << " event: "
+ << TString(ev->HasEvent() ? ev->GetBase()->ToString() : "serialized?"));
break;
}
}
};
-class TStateStorageDumpRequest : public TActorBootstrapped<TStateStorageDumpRequest> {
-protected:
+class TStateStorageDumpRequest : public TActorBootstrapped<TStateStorageDumpRequest> {
+protected:
const TActorId Sender;
- TIntrusivePtr<TStateStorageInfo> Info;
+ TIntrusivePtr<TStateStorageInfo> Info;
TList<TActorId> AllReplicas;
- TAutoPtr<TEvStateStorage::TEvResponseReplicasDumps> Response;
- ui64 UndeliveredCount;
-
-public:
+ TAutoPtr<TEvStateStorage::TEvResponseReplicasDumps> Response;
+ ui64 UndeliveredCount;
+
+public:
static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
return NKikimrServices::TActivity::TABLET_FORWARDING_ACTOR;
}
TStateStorageDumpRequest(const TActorId &sender, const TIntrusivePtr<TStateStorageInfo> &info)
- : Sender(sender)
- , Info(info)
- , UndeliveredCount(0)
+ : Sender(sender)
+ , Info(info)
+ , UndeliveredCount(0)
{}
-
+
void SendResponse() {
Send(Sender, Response.Release());
PassAway();
- }
-
+ }
+
void Bootstrap() {
- Response = new TEvStateStorage::TEvResponseReplicasDumps();
+ Response = new TEvStateStorage::TEvResponseReplicasDumps();
AllReplicas = Info->SelectAllReplicas();
- if (!AllReplicas.empty()) {
- Response->ReplicasDumps.reserve(AllReplicas.size());
+ if (!AllReplicas.empty()) {
+ Response->ReplicasDumps.reserve(AllReplicas.size());
for (const TActorId &replica : AllReplicas) {
Send(replica, new TEvStateStorage::TEvReplicaDumpRequest(), IEventHandle::FlagTrackDelivery);
- }
+ }
Schedule(TDuration::Seconds(60), new TEvents::TEvWakeup());
- Become(&TThis::StateRequestedDumps);
- } else {
+ Become(&TThis::StateRequestedDumps);
+ } else {
SendResponse();
- }
- }
-
+ }
+ }
+
STATEFN(StateRequestedDumps) {
- switch (ev->GetTypeRewrite()) {
+ switch (ev->GetTypeRewrite()) {
hFunc(TEvStateStorage::TEvReplicaDump, Handle);
hFunc(TEvents::TEvUndelivered, Undelivered);
cFunc(TEvents::TSystem::Wakeup, Timeout);
- }
- }
-
+ }
+ }
+
void OnResponseReceived() {
- if (Response->ReplicasDumps.size() + UndeliveredCount >= AllReplicas.size())
+ if (Response->ReplicasDumps.size() + UndeliveredCount >= AllReplicas.size())
SendResponse();
- }
-
+ }
+
void Undelivered(TEvents::TEvUndelivered::TPtr &) {
- ++UndeliveredCount;
+ ++UndeliveredCount;
OnResponseReceived();
- }
-
+ }
+
void Handle(TEvStateStorage::TEvReplicaDump::TPtr &ev) {
- Response->ReplicasDumps.emplace_back(std::make_pair(ev->Sender, ev->Release()));
+ Response->ReplicasDumps.emplace_back(std::make_pair(ev->Sender, ev->Release()));
OnResponseReceived();
- }
-
+ }
+
void Timeout() {
SendResponse();
- }
-};
-
-class TStateStorageDeleteRequest : public TActorBootstrapped<TStateStorageDeleteRequest> {
-protected:
+ }
+};
+
+class TStateStorageDeleteRequest : public TActorBootstrapped<TStateStorageDeleteRequest> {
+protected:
const TActorId Sender;
- TIntrusivePtr<TStateStorageInfo> Info;
+ TIntrusivePtr<TStateStorageInfo> Info;
TList<TActorId> AllReplicas;
- ui32 Count;
- ui32 UndeliveredCount;
- ui64 TabletID;
-
-public:
+ ui32 Count;
+ ui32 UndeliveredCount;
+ ui64 TabletID;
+
+public:
static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
return NKikimrServices::TActivity::TABLET_FORWARDING_ACTOR;
- }
-
+ }
+
TStateStorageDeleteRequest(const TActorId &sender, const TIntrusivePtr<TStateStorageInfo> &info, ui64 tabletId)
- : Sender(sender)
- , Info(info)
- , Count(0)
- , UndeliveredCount(0)
- , TabletID(tabletId)
- {}
-
+ : Sender(sender)
+ , Info(info)
+ , Count(0)
+ , UndeliveredCount(0)
+ , TabletID(tabletId)
+ {}
+
void SendResponse() {
Send(Sender, new TEvStateStorage::TEvDeleteResult(TabletID, Count > AllReplicas.size() / 2 ? NKikimrProto::OK : NKikimrProto::ERROR));
PassAway();
- }
-
+ }
+
void Bootstrap() {
AllReplicas = Info->SelectAllReplicas();
- if (!AllReplicas.empty()) {
+ if (!AllReplicas.empty()) {
for (const TActorId &replica : AllReplicas) {
Send(replica, new TEvStateStorage::TEvReplicaDelete(TabletID), IEventHandle::FlagTrackDelivery);
- }
+ }
Schedule(TDuration::Seconds(60), new TEvents::TEvWakeup());
- Become(&TThis::StateRequestedDelete);
- } else {
+ Become(&TThis::StateRequestedDelete);
+ } else {
SendResponse();
- }
- }
-
+ }
+ }
+
STATEFN(StateRequestedDelete) {
- switch (ev->GetTypeRewrite()) {
+ switch (ev->GetTypeRewrite()) {
hFunc(TEvStateStorage::TEvReplicaInfo, Handle);
hFunc(TEvents::TEvUndelivered, Undelivered);
cFunc(TEvents::TSystem::Wakeup, Timeout);
- }
- }
-
+ }
+ }
+
void OnResponseReceived() {
- if (Count + UndeliveredCount >= AllReplicas.size())
+ if (Count + UndeliveredCount >= AllReplicas.size())
SendResponse();
- }
-
+ }
+
void Undelivered(TEvents::TEvUndelivered::TPtr &) {
- ++UndeliveredCount;
+ ++UndeliveredCount;
OnResponseReceived();
- }
-
+ }
+
void Handle(TEvStateStorage::TEvReplicaInfo::TPtr &) {
- ++Count;
+ ++Count;
OnResponseReceived();
- }
-
+ }
+
void Timeout() {
SendResponse();
- }
-};
-
+ }
+};
+
class TStateStorageProxy : public TActor<TStateStorageProxy> {
TIntrusivePtr<TStateStorageInfo> Info;
TIntrusivePtr<TStateStorageInfo> BoardInfo;
@@ -962,7 +962,7 @@ public:
STATEFN(StateInit) {
BLOG_TRACE("Proxy::StateInit ev type# " << ev->GetTypeRewrite() << " event: "
- << TString(ev->HasEvent() ? ev->GetBase()->ToString() : "serialized?"));
+ << TString(ev->HasEvent() ? ev->GetBase()->ToString() : "serialized?"));
switch (ev->GetTypeRewrite()) {
hFunc(TEvStateStorage::TEvRequestReplicasDumps, Handle);
@@ -1010,8 +1010,8 @@ public:
default:
BLOG_W("ProxyStub::StateFunc unexpected event type# "
<< ev->GetTypeRewrite()
- << " event: "
- << TString(ev->HasEvent() ? ev->GetBase()->ToString() : "serialized?"));
+ << " event: "
+ << TString(ev->HasEvent() ? ev->GetBase()->ToString() : "serialized?"));
break;
}
}
diff --git a/ydb/core/base/statestorage_replica.cpp b/ydb/core/base/statestorage_replica.cpp
index c2ccd9aa272..aca41acb16a 100644
--- a/ydb/core/base/statestorage_replica.cpp
+++ b/ydb/core/base/statestorage_replica.cpp
@@ -112,13 +112,13 @@ class TStateStorageReplica : public TActor<TStateStorageReplica> {
}
void ReplyWithStatus(const TActorId &recp, ui64 tabletId, ui64 cookie, NKikimrProto::EReplyStatus status) {
- THolder<TEvStateStorage::TEvReplicaInfo> msg(new TEvStateStorage::TEvReplicaInfo(tabletId, status));
- msg->Record.SetCookie(cookie);
+ THolder<TEvStateStorage::TEvReplicaInfo> msg(new TEvStateStorage::TEvReplicaInfo(tabletId, status));
+ msg->Record.SetCookie(cookie);
msg->Record.SetSignature(Signature());
msg->Record.SetConfigContentHash(Info->ContentHash());
Send(recp, msg.Release());
- }
-
+ }
+
bool EraseFollowerAndNotify(ui64 tabletId, TEntry &tabletEntry, TActorId followerGuardian) {
if (!tabletEntry.Followers.erase(followerGuardian))
return false;
@@ -191,21 +191,21 @@ class TStateStorageReplica : public TActor<TStateStorageReplica> {
}
void Handle(TEvStateStorage::TEvReplicaDumpRequest::TPtr &ev) {
- TAutoPtr<TEvStateStorage::TEvReplicaDump> dump = new TEvStateStorage::TEvReplicaDump();
- for (const auto &it : Tablets) {
- NKikimrStateStorage::TEvInfo& info = *dump->Record.AddInfo();
- info.SetTabletID(it.first);
- info.SetCurrentGeneration(it.second.CurrentGeneration);
- info.SetCurrentStep(it.second.CurrentStep);
+ TAutoPtr<TEvStateStorage::TEvReplicaDump> dump = new TEvStateStorage::TEvReplicaDump();
+ for (const auto &it : Tablets) {
+ NKikimrStateStorage::TEvInfo& info = *dump->Record.AddInfo();
+ info.SetTabletID(it.first);
+ info.SetCurrentGeneration(it.second.CurrentGeneration);
+ info.SetCurrentStep(it.second.CurrentStep);
ActorIdToProto(it.second.CurrentLeader, info.MutableCurrentLeader());
ActorIdToProto(it.second.CurrentLeaderTablet, info.MutableCurrentLeaderTablet());
- if (it.second.TabletState == TTabletState::Locked) {
+ if (it.second.TabletState == TTabletState::Locked) {
info.SetLockedFor(TActivationContext::Now().MicroSeconds() - it.second.LockedFrom);
- }
- }
+ }
+ }
Send(ev->Sender, dump.Release(), 0, ev->Cookie);
- }
-
+ }
+
void Handle(TEvStateStorage::TEvReplicaUpdate::TPtr &ev) {
TEvStateStorage::TEvReplicaUpdate *msg = ev->Get();
BLOG_D("Replica::Handle ev: " << msg->ToString());
@@ -273,10 +273,10 @@ class TStateStorageReplica : public TActor<TStateStorageReplica> {
}
void Handle(TEvStateStorage::TEvReplicaDelete::TPtr &ev) {
- TEvStateStorage::TEvReplicaDelete *msg = ev->Get();
+ TEvStateStorage::TEvReplicaDelete *msg = ev->Get();
BLOG_D("Replica::Handle ev: " << msg->ToString());
- const ui64 tabletId = msg->Record.GetTabletID();
- Y_VERIFY_DEBUG(StateStorageGroupFromTabletID(tabletId) == Info->StateStorageGroup);
+ const ui64 tabletId = msg->Record.GetTabletID();
+ Y_VERIFY_DEBUG(StateStorageGroupFromTabletID(tabletId) == Info->StateStorageGroup);
auto tabletIt = Tablets.find(tabletId);
if (tabletIt == Tablets.end()) {
@@ -292,8 +292,8 @@ class TStateStorageReplica : public TActor<TStateStorageReplica> {
Tablets.erase(tabletIt);
ReplyWithStatus(ev->Sender, tabletId, 0/*msg->Record.GetCookie()*/, NKikimrProto::OK);
- }
-
+ }
+
void Handle(TEvStateStorage::TEvReplicaLock::TPtr &ev) {
TEvStateStorage::TEvReplicaLock *msg = ev->Get();
BLOG_D("Replica::Handle ev: " << msg->ToString());
diff --git a/ydb/core/base/storage_pools.h b/ydb/core/base/storage_pools.h
index 3f683a25a28..e8a997c7251 100644
--- a/ydb/core/base/storage_pools.h
+++ b/ydb/core/base/storage_pools.h
@@ -28,7 +28,7 @@ struct TStoragePool: public std::pair<TString, TString> {
using TStoragePools = TVector<TStoragePool>;
-using TChannelBind = NKikimrStoragePool::TChannelBind;
+using TChannelBind = NKikimrStoragePool::TChannelBind;
using TChannelsBindings = TVector<TChannelBind>;
diff --git a/ydb/core/base/subdomain.h b/ydb/core/base/subdomain.h
index 3d849b0849e..0e1101bc781 100644
--- a/ydb/core/base/subdomain.h
+++ b/ydb/core/base/subdomain.h
@@ -11,14 +11,14 @@ struct TSubDomainKey : public std::pair<ui64, ui64> {
using TBase::TBase;
TSubDomainKey() = default;
- TSubDomainKey(const TSubDomainKey&) = default;
- TSubDomainKey(TSubDomainKey&&) = default;
+ TSubDomainKey(const TSubDomainKey&) = default;
+ TSubDomainKey(TSubDomainKey&&) = default;
TSubDomainKey(ui64 shardId, ui64 pathId);
explicit TSubDomainKey(const NKikimrSubDomains::TDomainKey &domainKey);
- TSubDomainKey& operator =(const TSubDomainKey&) = default;
- TSubDomainKey& operator =(TSubDomainKey&&) = default;
-
+ TSubDomainKey& operator =(const TSubDomainKey&) = default;
+ TSubDomainKey& operator =(TSubDomainKey&&) = default;
+
ui64 GetSchemeShard() const;
ui64 GetPathId() const;
diff --git a/ydb/core/base/tablet.h b/ydb/core/base/tablet.h
index a49b52a0558..602e39c6000 100644
--- a/ydb/core/base/tablet.h
+++ b/ydb/core/base/tablet.h
@@ -1,5 +1,5 @@
#pragma once
-#include "blobstorage.h"
+#include "blobstorage.h"
#include "defs.h"
#include "events.h"
#include "logoblob.h"
@@ -50,7 +50,7 @@ struct TEvTablet {
EvFAuxUpdate,
EvFollowerGcApplied, // from leader to user tablet when all known followers reported consumed gc barrier
EvFollowerSyncComplete, // from leader to user tablet when all old followers are touched and synced
- EvCutTabletHistory,
+ EvCutTabletHistory,
EvUpdateConfig,
EvCommit = EvBoot + 512,
@@ -73,8 +73,8 @@ struct TEvTablet {
EvLocalMKQLResponse,
EvLocalSchemeTx,
EvLocalSchemeTxResponse,
- EvGetCounters,
- EvGetCountersResponse,
+ EvGetCounters,
+ EvGetCountersResponse,
EvLocalReadColumns,
EvLocalReadColumnsResponse,
@@ -94,7 +94,7 @@ struct TEvTablet {
// utilitary
EvCheckBlobstorageStatusResult = EvBoot + 3072,
- EvResetTabletResult,
+ EvResetTabletResult,
EvEnd
};
@@ -186,16 +186,16 @@ struct TEvTablet {
TIntrusivePtr<TTabletStorageInfo> TabletStorageInfo;
TResourceProfilesPtr ResourceProfiles;
TSharedQuotaPtr TxCacheQuota;
-
- NMetrics::TTabletThroughputRawValue GroupReadBytes;
+
+ NMetrics::TTabletThroughputRawValue GroupReadBytes;
NMetrics::TTabletIopsRawValue GroupReadOps;
-
- TEvBoot(
- ui64 tabletId,
- ui32 generation,
- TDependencyGraph *dependencyGraph,
+
+ TEvBoot(
+ ui64 tabletId,
+ ui32 generation,
+ TDependencyGraph *dependencyGraph,
const TActorId& launcher,
- TIntrusivePtr<TTabletStorageInfo> info,
+ TIntrusivePtr<TTabletStorageInfo> info,
TResourceProfilesPtr profiles = nullptr,
TSharedQuotaPtr txCacheQuota = nullptr,
NMetrics::TTabletThroughputRawValue&& read = NMetrics::TTabletThroughputRawValue(),
@@ -203,11 +203,11 @@ struct TEvTablet {
: TabletID(tabletId)
, Generation(generation)
, DependencyGraph(dependencyGraph)
- , Launcher(launcher)
+ , Launcher(launcher)
, TabletStorageInfo(info)
, ResourceProfiles(profiles)
, TxCacheQuota(txCacheQuota)
- , GroupReadBytes(std::move(read))
+ , GroupReadBytes(std::move(read))
, GroupReadOps(std::move(readOps))
{}
};
@@ -304,7 +304,7 @@ struct TEvTablet {
struct TEvPromoteToLeader : public TEventLocal<TEvPromoteToLeader, EvPromoteToLeader> {
const ui32 SuggestedGeneration;
- TIntrusivePtr<TTabletStorageInfo> TabletStorageInfo;
+ TIntrusivePtr<TTabletStorageInfo> TabletStorageInfo;
TEvPromoteToLeader(ui32 suggestedGeneration, TIntrusivePtr<TTabletStorageInfo> info)
: SuggestedGeneration(suggestedGeneration)
@@ -320,7 +320,7 @@ struct TEvTablet {
const ui32 ConfirmedOnSend;
TVector<ui32> YellowMoveChannels;
TVector<ui32> YellowStopChannels;
- NMetrics::TTabletThroughputRawValue GroupWrittenBytes;
+ NMetrics::TTabletThroughputRawValue GroupWrittenBytes;
NMetrics::TTabletIopsRawValue GroupWrittenOps;
TEvCommitResult(
@@ -340,7 +340,7 @@ struct TEvTablet {
, ConfirmedOnSend(confirmedOnSend)
, YellowMoveChannels(std::move(yellowMoveChannels))
, YellowStopChannels(std::move(yellowStopChannels))
- , GroupWrittenBytes(std::move(written))
+ , GroupWrittenBytes(std::move(written))
, GroupWrittenOps(std::move(writtenOps))
{}
};
@@ -353,7 +353,7 @@ struct TEvTablet {
XX(ReasonReserved01, 3) \
XX(ReasonBootBSError, 4) \
XX(ReasonBootSuggestOutdated, 5) \
- XX(ReasonBootSSError, 6) \
+ XX(ReasonBootSSError, 6) \
XX(ReasonBootReservedValue, 32) \
XX(ReasonPill, 33) \
XX(ReasonError, 34) \
@@ -463,22 +463,22 @@ struct TEvTablet {
}
};
- struct TEvLocalMKQL : public TEventPB<TEvLocalMKQL, NKikimrTabletTxBase::TEvLocalMKQL, TEvTablet::EvLocalMKQL> {
+ struct TEvLocalMKQL : public TEventPB<TEvLocalMKQL, NKikimrTabletTxBase::TEvLocalMKQL, TEvTablet::EvLocalMKQL> {
TEvLocalMKQL()
{}
};
- struct TEvLocalMKQLResponse : public TEventPB<TEvLocalMKQLResponse, NKikimrTabletTxBase::TEvLocalMKQLResponse, TEvTablet::EvLocalMKQLResponse> {
+ struct TEvLocalMKQLResponse : public TEventPB<TEvLocalMKQLResponse, NKikimrTabletTxBase::TEvLocalMKQLResponse, TEvTablet::EvLocalMKQLResponse> {
TEvLocalMKQLResponse()
{}
};
- struct TEvLocalSchemeTx : public TEventPB<TEvLocalSchemeTx, NKikimrTabletTxBase::TEvLocalSchemeTx, TEvTablet::EvLocalSchemeTx> {
+ struct TEvLocalSchemeTx : public TEventPB<TEvLocalSchemeTx, NKikimrTabletTxBase::TEvLocalSchemeTx, TEvTablet::EvLocalSchemeTx> {
TEvLocalSchemeTx()
{}
};
- struct TEvLocalSchemeTxResponse : public TEventPB<TEvLocalSchemeTxResponse, NKikimrTabletTxBase::TEvLocalSchemeTxResponse, TEvTablet::EvLocalSchemeTxResponse> {
+ struct TEvLocalSchemeTxResponse : public TEventPB<TEvLocalSchemeTxResponse, NKikimrTabletTxBase::TEvLocalSchemeTxResponse, TEvTablet::EvLocalSchemeTxResponse> {
TEvLocalSchemeTxResponse()
{}
};
@@ -714,23 +714,23 @@ struct TEvTablet {
{}
};
-
- struct TEvResetTabletResult : public TEventLocal<TEvResetTabletResult, EvResetTabletResult> {
- const NKikimrProto::EReplyStatus Status;
- const ui64 TabletId;
-
- TEvResetTabletResult(NKikimrProto::EReplyStatus status, ui64 tabletId)
- : Status(status)
- , TabletId(tabletId)
- {}
- };
-
- struct TEvGetCounters : TEventPB<TEvGetCounters, NKikimrTabletBase::TEvGetCounters, EvGetCounters> {};
- struct TEvGetCountersResponse : TEventPB<TEvGetCountersResponse, NKikimrTabletBase::TEvGetCountersResponse, EvGetCountersResponse> {};
-
- struct TEvCutTabletHistory : TEventPB<TEvCutTabletHistory, NKikimrTabletBase::TEvCutTabletHistory, EvCutTabletHistory> {
- TEvCutTabletHistory() = default;
- };
+
+ struct TEvResetTabletResult : public TEventLocal<TEvResetTabletResult, EvResetTabletResult> {
+ const NKikimrProto::EReplyStatus Status;
+ const ui64 TabletId;
+
+ TEvResetTabletResult(NKikimrProto::EReplyStatus status, ui64 tabletId)
+ : Status(status)
+ , TabletId(tabletId)
+ {}
+ };
+
+ struct TEvGetCounters : TEventPB<TEvGetCounters, NKikimrTabletBase::TEvGetCounters, EvGetCounters> {};
+ struct TEvGetCountersResponse : TEventPB<TEvGetCountersResponse, NKikimrTabletBase::TEvGetCountersResponse, EvGetCountersResponse> {};
+
+ struct TEvCutTabletHistory : TEventPB<TEvCutTabletHistory, NKikimrTabletBase::TEvCutTabletHistory, EvCutTabletHistory> {
+ TEvCutTabletHistory() = default;
+ };
struct TEvUpdateConfig : TEventLocal<TEvUpdateConfig, EvUpdateConfig> {
TResourceProfilesPtr ResourceProfiles;
diff --git a/ydb/core/base/tablet_killer.cpp b/ydb/core/base/tablet_killer.cpp
index 021f537e220..d46e2c5c895 100644
--- a/ydb/core/base/tablet_killer.cpp
+++ b/ydb/core/base/tablet_killer.cpp
@@ -4,63 +4,63 @@
#include <library/cpp/actors/core/actor_bootstrapped.h>
#include <library/cpp/actors/core/hfunc.h>
-
-namespace NKikimr {
-
-class TTabletKillRequest : public TActorBootstrapped<TTabletKillRequest> {
+
+namespace NKikimr {
+
+class TTabletKillRequest : public TActorBootstrapped<TTabletKillRequest> {
private:
const ui64 TabletId;
- const ui32 NodeId;
+ const ui32 NodeId;
const ui32 MaxGeneration;
-
+
void Handle(TEvStateStorage::TEvInfo::TPtr &ev, const TActorContext &ctx) {
TEvStateStorage::TEvInfo *msg = ev->Get();
TActorId LeaderActor;
- if (NodeId == 0) {
+ if (NodeId == 0) {
LeaderActor = msg->CurrentLeader;
- } else {
+ } else {
if (msg->CurrentLeader && msg->CurrentLeader.NodeId() == NodeId) {
LeaderActor = msg->CurrentLeader;
- } else {
+ } else {
for (const auto& pr : msg->Followers) {
- if (pr.first.NodeId() == NodeId) {
+ if (pr.first.NodeId() == NodeId) {
LeaderActor = pr.first;
- break;
- }
- }
- }
- }
+ break;
+ }
+ }
+ }
+ }
if (LeaderActor && msg->CurrentGeneration <= MaxGeneration)
ctx.Send(LeaderActor, new TEvents::TEvPoisonPill());
- return Die(ctx);
- }
-public:
+ return Die(ctx);
+ }
+public:
static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
return NKikimrServices::TActivity::TABLET_KILLER;
- }
-
+ }
+
TTabletKillRequest(ui64 tabletId, ui32 nodeId, ui32 maxGeneration)
- : TabletId(tabletId)
- , NodeId(nodeId)
+ : TabletId(tabletId)
+ , NodeId(nodeId)
, MaxGeneration(maxGeneration)
- {}
-
- void Bootstrap(const TActorContext &ctx) {
+ {}
+
+ void Bootstrap(const TActorContext &ctx) {
const TActorId stateStorageProxyId = MakeStateStorageProxyID(StateStorageGroupFromTabletID(TabletId));
ctx.Send(stateStorageProxyId, new TEvStateStorage::TEvLookup(TabletId, 0));
- Become(&TTabletKillRequest::StateFunc);
- }
-
- STFUNC(StateFunc) {
- switch (ev->GetTypeRewrite()) {
+ Become(&TTabletKillRequest::StateFunc);
+ }
+
+ STFUNC(StateFunc) {
+ switch (ev->GetTypeRewrite()) {
HFunc(TEvStateStorage::TEvInfo, Handle);
- }
- }
-};
-
+ }
+ }
+};
+
IActor* CreateTabletKiller(ui64 tabletId, ui32 nodeId, ui32 maxGeneration) {
return new TTabletKillRequest(tabletId, nodeId, maxGeneration);
-}
-
+}
+
}
diff --git a/ydb/core/base/tablet_pipe.h b/ydb/core/base/tablet_pipe.h
index 4f08943517e..a0420b86724 100644
--- a/ydb/core/base/tablet_pipe.h
+++ b/ydb/core/base/tablet_pipe.h
@@ -308,40 +308,40 @@ namespace NKikimr {
virtual bool IsStopped() const = 0;
};
- struct TClientRetryPolicy {
- ui32 RetryLimitCount = std::numeric_limits<ui32>::max();
- TDuration MinRetryTime = TDuration::MilliSeconds(10);
- TDuration MaxRetryTime = TDuration::Minutes(10);
- ui32 BackoffMultiplier = 2;
- bool DoFirstRetryInstantly = true;
-
- operator bool() const {
- return RetryLimitCount != 0;
- }
-
- static TClientRetryPolicy WithoutRetries() {
- return {
- .RetryLimitCount = {},
- .MinRetryTime = {},
- .MaxRetryTime = {},
- .BackoffMultiplier = {},
- .DoFirstRetryInstantly = {},
- };
- }
-
- static TClientRetryPolicy WithRetries() {
- return {};
- }
+ struct TClientRetryPolicy {
+ ui32 RetryLimitCount = std::numeric_limits<ui32>::max();
+ TDuration MinRetryTime = TDuration::MilliSeconds(10);
+ TDuration MaxRetryTime = TDuration::Minutes(10);
+ ui32 BackoffMultiplier = 2;
+ bool DoFirstRetryInstantly = true;
+
+ operator bool() const {
+ return RetryLimitCount != 0;
+ }
+
+ static TClientRetryPolicy WithoutRetries() {
+ return {
+ .RetryLimitCount = {},
+ .MinRetryTime = {},
+ .MaxRetryTime = {},
+ .BackoffMultiplier = {},
+ .DoFirstRetryInstantly = {},
+ };
+ }
+
+ static TClientRetryPolicy WithRetries() {
+ return {};
+ }
};
- struct TClientRetryState {
- bool IsAllowedToRetry(TDuration& wait, const TClientRetryPolicy& policy);
+ struct TClientRetryState {
+ bool IsAllowedToRetry(TDuration& wait, const TClientRetryPolicy& policy);
TDuration MakeCheckDelay();
- protected:
- ui64 RetryNumber = 0;
- TDuration RetryDuration;
- };
-
+ protected:
+ ui64 RetryNumber = 0;
+ TDuration RetryDuration;
+ };
+
struct TClientConfig {
bool ConnectToUserTablet = false;
bool AllowFollower = false;
@@ -350,15 +350,15 @@ namespace NKikimr {
bool PreferLocal = false;
bool CheckAliveness = false;
bool ExpectShutdown = false;
- TClientRetryPolicy RetryPolicy;
-
- TClientConfig()
- : RetryPolicy(TClientRetryPolicy::WithoutRetries())
- {}
-
- TClientConfig(TClientRetryPolicy retryPolicy)
- : RetryPolicy(std::move(retryPolicy))
- {}
+ TClientRetryPolicy RetryPolicy;
+
+ TClientConfig()
+ : RetryPolicy(TClientRetryPolicy::WithoutRetries())
+ {}
+
+ TClientConfig(TClientRetryPolicy retryPolicy)
+ : RetryPolicy(std::move(retryPolicy))
+ {}
};
// Returns client actor.
diff --git a/ydb/core/base/tablet_status_checker.cpp b/ydb/core/base/tablet_status_checker.cpp
index 1177d918a7e..bfb51b8e852 100644
--- a/ydb/core/base/tablet_status_checker.cpp
+++ b/ydb/core/base/tablet_status_checker.cpp
@@ -53,7 +53,7 @@ public:
++RequestsLeft;
}
}
- Become(&TTabletStatusCheckRequest::StateFunc);
+ Become(&TTabletStatusCheckRequest::StateFunc);
}
STFUNC(StateFunc) {
diff --git a/ydb/core/base/tablet_types.h b/ydb/core/base/tablet_types.h
index 7cde744ccfa..f585819299c 100644
--- a/ydb/core/base/tablet_types.h
+++ b/ydb/core/base/tablet_types.h
@@ -1,7 +1,7 @@
#pragma once
#include "defs.h"
-#include "tabletid.h"
+#include "tabletid.h"
#include <ydb/core/protos/tablet.pb.h>
////////////////////////////////////////////
@@ -10,25 +10,25 @@ namespace NKikimr {
////////////////////////////////////////////
/// The TTabletTypes class
////////////////////////////////////////////
-struct TTabletTypes : NKikimrTabletBase::TTabletTypes {
+struct TTabletTypes : NKikimrTabletBase::TTabletTypes {
public:
- static constexpr EType USER_TYPE_START = UserTypeStart;
- static constexpr EType TYPE_INVALID = TypeInvalid;
- static constexpr EType FLAT_SCHEMESHARD = SchemeShard;
- static constexpr EType FLAT_DATASHARD = DataShard;
+ static constexpr EType USER_TYPE_START = UserTypeStart;
+ static constexpr EType TYPE_INVALID = TypeInvalid;
+ static constexpr EType FLAT_SCHEMESHARD = SchemeShard;
+ static constexpr EType FLAT_DATASHARD = DataShard;
static constexpr EType COLUMNSHARD = ColumnShard;
- static constexpr EType KEYVALUEFLAT = KeyValue;
- static constexpr EType PERSQUEUE = PersQueue;
- static constexpr EType PERSQUEUE_READ_BALANCER = PersQueueReadBalancer;
- static constexpr EType TX_DUMMY = Dummy;
- static constexpr EType FLAT_TX_COORDINATOR = Coordinator;
- static constexpr EType TX_MEDIATOR = Mediator;
- static constexpr EType FLAT_HIVE = Hive;
- static constexpr EType FLAT_BS_CONTROLLER = BSController;
- static constexpr EType TX_ALLOCATOR = TxAllocator;
- static constexpr EType NODE_BROKER = NodeBroker;
+ static constexpr EType KEYVALUEFLAT = KeyValue;
+ static constexpr EType PERSQUEUE = PersQueue;
+ static constexpr EType PERSQUEUE_READ_BALANCER = PersQueueReadBalancer;
+ static constexpr EType TX_DUMMY = Dummy;
+ static constexpr EType FLAT_TX_COORDINATOR = Coordinator;
+ static constexpr EType TX_MEDIATOR = Mediator;
+ static constexpr EType FLAT_HIVE = Hive;
+ static constexpr EType FLAT_BS_CONTROLLER = BSController;
+ static constexpr EType TX_ALLOCATOR = TxAllocator;
+ static constexpr EType NODE_BROKER = NodeBroker;
static constexpr EType CMS = Cms;
- static constexpr EType RTMR_PARTITION = RTMRPartition;
+ static constexpr EType RTMR_PARTITION = RTMRPartition;
static constexpr EType BLOCKSTORE_VOLUME = BlockStoreVolume;
static constexpr EType BLOCKSTORE_PARTITION = BlockStorePartition;
static constexpr EType BLOCKSTORE_PARTITION2 = BlockStorePartition2;
@@ -42,22 +42,22 @@ public:
static constexpr EType SEQUENCESHARD = SequenceShard;
static constexpr EType REPLICATION_CONTROLLER = ReplicationController;
- static const char* TypeToStr(EType t) {
- return EType_Name(t).c_str();
- }
+ static const char* TypeToStr(EType t) {
+ return EType_Name(t).c_str();
+ }
- static EType StrToType(const TString& t) {
- EType type;
- if (EType_Parse(t, &type)) {
- return type;
- } else {
- return TypeInvalid;
+ static EType StrToType(const TString& t) {
+ EType type;
+ if (EType_Parse(t, &type)) {
+ return type;
+ } else {
+ return TypeInvalid;
}
}
};
} // end of NKikimr
-
+
Y_DECLARE_OUT_SPEC(inline, NKikimrTabletBase::TTabletTypes::EType, os, type) {
- os << NKikimrTabletBase::TTabletTypes::EType_Name(type);
-}
+ os << NKikimrTabletBase::TTabletTypes::EType_Name(type);
+}
diff --git a/ydb/core/base/tabletid.h b/ydb/core/base/tabletid.h
index 62dd37bf0fb..cd0a7cb58f0 100644
--- a/ydb/core/base/tabletid.h
+++ b/ydb/core/base/tabletid.h
@@ -27,15 +27,15 @@ namespace NKikimr {
return candidate;
}
- static const ui64 TABLET_ID_BLACKHOLE_BEGIN = 0x800000;
- static const ui64 TABLET_ID_BLACKHOLE_END = 0x900000;
-
+ static const ui64 TABLET_ID_BLACKHOLE_BEGIN = 0x800000;
+ static const ui64 TABLET_ID_BLACKHOLE_END = 0x900000;
+
inline ui64 AvoidReservedUniqPartsBySystemTablets(ui64 candidate) {
// candidate = AvoidReservedUniqPart(candidate, 0x800000, 0x800100); // coordinators
// candidate = AvoidReservedUniqPart(candidate, 0x810000, 0x810100); // mediators
// candidate = AvoidReservedUniqPart(candidate, 0x820000, 0x821000); // allocators
// candidate = AvoidReservedUniqPart(candidate, 0x840000, 0x860000); // schemeshard
- return AvoidReservedUniqPart(candidate, TABLET_ID_BLACKHOLE_BEGIN, TABLET_ID_BLACKHOLE_END); // for sure
+ return AvoidReservedUniqPart(candidate, TABLET_ID_BLACKHOLE_BEGIN, TABLET_ID_BLACKHOLE_END); // for sure
}
inline bool IsReservedTabletId(ui64 tabletId) {
diff --git a/ydb/core/base/ticket_parser.h b/ydb/core/base/ticket_parser.h
index dec6f8423af..62004b3a89d 100644
--- a/ydb/core/base/ticket_parser.h
+++ b/ydb/core/base/ticket_parser.h
@@ -1,77 +1,77 @@
-#pragma once
+#pragma once
#include <library/cpp/containers/stack_vector/stack_vec.h>
#include <ydb/core/base/defs.h>
#include <ydb/core/base/events.h>
#include <ydb/core/protos/config.pb.h>
#include <ydb/library/aclib/aclib.h>
#include <ydb/library/login/login.h>
-#include <util/string/builder.h>
-
-namespace NKikimr {
- struct TEvTicketParser {
- enum EEv {
- // requests
- EvAuthorizeTicket = EventSpaceBegin(TKikimrEvents::ES_TICKET_PARSER),
- EvRefreshTicket,
- EvDiscardTicket,
- EvUpdateLoginSecurityState,
-
- // replies
- EvAuthorizeTicketResult = EvAuthorizeTicket + 512,
-
- EvEnd
- };
-
- static_assert(EvEnd < EventSpaceEnd(TKikimrEvents::ES_TICKET_PARSER), "expect EvEnd < EventSpaceEnd(TKikimrEvents::ES_TICKET_PARSER)");
-
- struct TEvAuthorizeTicket : TEventLocal<TEvAuthorizeTicket, EvAuthorizeTicket> {
+#include <util/string/builder.h>
+
+namespace NKikimr {
+ struct TEvTicketParser {
+ enum EEv {
+ // requests
+ EvAuthorizeTicket = EventSpaceBegin(TKikimrEvents::ES_TICKET_PARSER),
+ EvRefreshTicket,
+ EvDiscardTicket,
+ EvUpdateLoginSecurityState,
+
+ // replies
+ EvAuthorizeTicketResult = EvAuthorizeTicket + 512,
+
+ EvEnd
+ };
+
+ static_assert(EvEnd < EventSpaceEnd(TKikimrEvents::ES_TICKET_PARSER), "expect EvEnd < EventSpaceEnd(TKikimrEvents::ES_TICKET_PARSER)");
+
+ struct TEvAuthorizeTicket : TEventLocal<TEvAuthorizeTicket, EvAuthorizeTicket> {
struct TEntry {
TStackVec<TString> Permissions;
TStackVec<std::pair<TString, TString>> Attributes;
};
- const TString Database;
+ const TString Database;
const TString Ticket;
- const TString PeerName;
+ const TString PeerName;
- // if two identical permissions with different attributies are specified,
+ // if two identical permissions with different attributies are specified,
// only one of them will be processed. Which one is not guaranteed
const std::vector<TEntry> Entries;
-
- struct TInitializationFields {
- TString Database;
- TString Ticket;
- TString PeerName;
+
+ struct TInitializationFields {
+ TString Database;
+ TString Ticket;
+ TString PeerName;
std::vector<TEntry> Entries;
- };
-
- TEvAuthorizeTicket(TInitializationFields&& init)
- : Database(std::move(init.Database))
- , Ticket(std::move(init.Ticket))
- , PeerName(std::move(init.PeerName))
- , Entries(std::move(init.Entries))
- {
- }
-
- TEvAuthorizeTicket(const TString& ticket)
- : Ticket(ticket)
- {}
-
- TEvAuthorizeTicket(const TString& ticket, const TString& peerName)
- : Ticket(ticket)
- , PeerName(peerName)
- {}
-
- TEvAuthorizeTicket(const TString& ticket, const TVector<std::pair<TString, TString>>& attributes, const TVector<TString>& permissions)
- : Ticket(ticket)
+ };
+
+ TEvAuthorizeTicket(TInitializationFields&& init)
+ : Database(std::move(init.Database))
+ , Ticket(std::move(init.Ticket))
+ , PeerName(std::move(init.PeerName))
+ , Entries(std::move(init.Entries))
+ {
+ }
+
+ TEvAuthorizeTicket(const TString& ticket)
+ : Ticket(ticket)
+ {}
+
+ TEvAuthorizeTicket(const TString& ticket, const TString& peerName)
+ : Ticket(ticket)
+ , PeerName(peerName)
+ {}
+
+ TEvAuthorizeTicket(const TString& ticket, const TVector<std::pair<TString, TString>>& attributes, const TVector<TString>& permissions)
+ : Ticket(ticket)
, Entries({{permissions, attributes}})
- {}
-
- TEvAuthorizeTicket(const TString& ticket, const TString& peerName, const TVector<std::pair<TString, TString>>& attributes, const TVector<TString>& permissions)
- : Ticket(ticket)
- , PeerName(peerName)
+ {}
+
+ TEvAuthorizeTicket(const TString& ticket, const TString& peerName, const TVector<std::pair<TString, TString>>& attributes, const TVector<TString>& permissions)
+ : Ticket(ticket)
+ , PeerName(peerName)
, Entries({{permissions, attributes}})
- {}
+ {}
TEvAuthorizeTicket(const TString& ticket, const TVector<TEntry>& entries)
: Ticket(ticket)
@@ -83,85 +83,85 @@ namespace NKikimr {
, PeerName(peerName)
, Entries(entries)
{}
- };
-
- struct TError {
- TString Message;
- bool Retryable = true;
-
- bool empty() const {
- return Message.empty();
- }
-
- void clear() {
- Message.clear();
- Retryable = true;
- }
-
- operator bool() const {
- return !empty();
- }
-
- TString ToString() const {
+ };
+
+ struct TError {
+ TString Message;
+ bool Retryable = true;
+
+ bool empty() const {
+ return Message.empty();
+ }
+
+ void clear() {
+ Message.clear();
+ Retryable = true;
+ }
+
+ operator bool() const {
+ return !empty();
+ }
+
+ TString ToString() const {
return TStringBuilder()
<< "{message:\"" << Message << "\",retryable:" << Retryable << "}";
- }
- };
-
- struct TEvAuthorizeTicketResult : TEventLocal<TEvAuthorizeTicketResult, EvAuthorizeTicketResult> {
- TString Ticket;
- TError Error;
- TIntrusivePtr<NACLib::TUserToken> Token;
+ }
+ };
+
+ struct TEvAuthorizeTicketResult : TEventLocal<TEvAuthorizeTicketResult, EvAuthorizeTicketResult> {
+ TString Ticket;
+ TError Error;
+ TIntrusivePtr<NACLib::TUserToken> Token;
TString SerializedToken;
-
- TEvAuthorizeTicketResult(const TString& ticket, const TIntrusivePtr<NACLib::TUserToken>& token, const TString& serializedToken)
- : Ticket(ticket)
- , Token(token)
- , SerializedToken(serializedToken)
- {}
-
- TEvAuthorizeTicketResult(const TString& ticket, const TError& error)
- : Ticket(ticket)
- , Error(error)
- {}
- };
-
- struct TEvRefreshTicket : TEventLocal<TEvRefreshTicket, EvRefreshTicket> {
- const TString Ticket;
-
- TEvRefreshTicket(const TString& ticket)
- : Ticket(ticket)
- {}
- };
-
- struct TEvDiscardTicket : TEventLocal<TEvDiscardTicket, EvDiscardTicket> {
- const TString Ticket;
-
- TEvDiscardTicket(const TString& ticket)
- : Ticket(ticket)
- {}
- };
-
- struct TEvUpdateLoginSecurityState : TEventLocal<TEvUpdateLoginSecurityState, EvUpdateLoginSecurityState> {
- NLoginProto::TSecurityState SecurityState;
-
- TEvUpdateLoginSecurityState(NLoginProto::TSecurityState securityState)
- : SecurityState(std::move(securityState))
- {
- }
- };
- };
-
+
+ TEvAuthorizeTicketResult(const TString& ticket, const TIntrusivePtr<NACLib::TUserToken>& token, const TString& serializedToken)
+ : Ticket(ticket)
+ , Token(token)
+ , SerializedToken(serializedToken)
+ {}
+
+ TEvAuthorizeTicketResult(const TString& ticket, const TError& error)
+ : Ticket(ticket)
+ , Error(error)
+ {}
+ };
+
+ struct TEvRefreshTicket : TEventLocal<TEvRefreshTicket, EvRefreshTicket> {
+ const TString Ticket;
+
+ TEvRefreshTicket(const TString& ticket)
+ : Ticket(ticket)
+ {}
+ };
+
+ struct TEvDiscardTicket : TEventLocal<TEvDiscardTicket, EvDiscardTicket> {
+ const TString Ticket;
+
+ TEvDiscardTicket(const TString& ticket)
+ : Ticket(ticket)
+ {}
+ };
+
+ struct TEvUpdateLoginSecurityState : TEventLocal<TEvUpdateLoginSecurityState, EvUpdateLoginSecurityState> {
+ NLoginProto::TSecurityState SecurityState;
+
+ TEvUpdateLoginSecurityState(NLoginProto::TSecurityState securityState)
+ : SecurityState(std::move(securityState))
+ {
+ }
+ };
+ };
+
inline NActors::TActorId MakeTicketParserID() {
- const char name[12] = "ticketparse";
+ const char name[12] = "ticketparse";
return NActors::TActorId(0, TStringBuf(name, 12));
- }
-}
-
-template <>
-inline void Out<NKikimr::TEvTicketParser::TError>(IOutputStream& str, const NKikimr::TEvTicketParser::TError& error) {
- str << error.Message;
-}
+ }
+}
+
+template <>
+inline void Out<NKikimr::TEvTicketParser::TError>(IOutputStream& str, const NKikimr::TEvTicketParser::TError& error) {
+ str << error.Message;
+}
namespace NKikimr {
namespace NGRpcService {
diff --git a/ydb/core/blobstorage/base/html.cpp b/ydb/core/blobstorage/base/html.cpp
index 7d48e6e549c..6658530a949 100644
--- a/ydb/core/blobstorage/base/html.cpp
+++ b/ydb/core/blobstorage/base/html.cpp
@@ -7,12 +7,12 @@ namespace NKikimr {
////////////////////////////////////////////////////////////////////////////
// THtmlLightSignalRenderer
////////////////////////////////////////////////////////////////////////////
- const std::pair<TStringBuf, TStringBuf> THtmlLightSignalRenderer::Lights[NKikimrWhiteboard::EFlag_ARRAYSIZE] = {
+ const std::pair<TStringBuf, TStringBuf> THtmlLightSignalRenderer::Lights[NKikimrWhiteboard::EFlag_ARRAYSIZE] = {
{"label", "background-color:grey"},
- {"label label-success", {}},
- {"label label-warning", {}},
- {"label", "background-color:orange"},
- {"label label-danger", {}},
+ {"label label-success", {}},
+ {"label label-warning", {}},
+ {"label", "background-color:orange"},
+ {"label label-danger", {}},
};
void THtmlLightSignalRenderer::Output(IOutputStream &str) const {
diff --git a/ydb/core/blobstorage/base/html.h b/ydb/core/blobstorage/base/html.h
index 14411daec8a..c592112f307 100644
--- a/ydb/core/blobstorage/base/html.h
+++ b/ydb/core/blobstorage/base/html.h
@@ -24,7 +24,7 @@ namespace NKikimr {
private:
NKikimrWhiteboard::EFlag Light;
const TString Value;
- static const std::pair<TStringBuf, TStringBuf> Lights[NKikimrWhiteboard::EFlag_ARRAYSIZE]; // {class, style}
+ static const std::pair<TStringBuf, TStringBuf> Lights[NKikimrWhiteboard::EFlag_ARRAYSIZE]; // {class, style}
};
} // NKikimr
diff --git a/ydb/core/blobstorage/dsproxy/dsproxy_get_impl.cpp b/ydb/core/blobstorage/dsproxy/dsproxy_get_impl.cpp
index 7834098ab82..0583b454df6 100644
--- a/ydb/core/blobstorage/dsproxy/dsproxy_get_impl.cpp
+++ b/ydb/core/blobstorage/dsproxy/dsproxy_get_impl.cpp
@@ -18,7 +18,7 @@ namespace NKikimr {
void TGetImpl::PrepareReply(NKikimrProto::EReplyStatus status, TLogContext &logCtx,
TAutoPtr<TEvBlobStorage::TEvGetResult> &outGetResult) {
- outGetResult.Reset(new TEvBlobStorage::TEvGetResult(status, QuerySize, Info->GroupID));
+ outGetResult.Reset(new TEvBlobStorage::TEvGetResult(status, QuerySize, Info->GroupID));
ReplyBytes = 0;
outGetResult->BlockedGeneration = BlockedGeneration;
diff --git a/ydb/core/blobstorage/dsproxy/dsproxy_mon.cpp b/ydb/core/blobstorage/dsproxy/dsproxy_mon.cpp
index 155a6242b4a..73afac8121f 100644
--- a/ydb/core/blobstorage/dsproxy/dsproxy_mon.cpp
+++ b/ydb/core/blobstorage/dsproxy/dsproxy_mon.cpp
@@ -138,7 +138,7 @@ void TBlobStorageGroupProxyMon::BecomeFull() {
void TBlobStorageGroupProxyMon::SerializeToWhiteboard(NKikimrWhiteboard::TBSGroupStateInfo& pb, ui32 groupId) const {
NKikimrWhiteboard::EFlag flag = NKikimrWhiteboard::EFlag::Green;
- auto calculate = [&flag](const auto& tracker) {
+ auto calculate = [&flag](const auto& tracker) {
for (const auto& x : tracker.Percentiles) {
const float percentile = x.first;
const ui32 milliseconds = *x.second;
@@ -159,7 +159,7 @@ void TBlobStorageGroupProxyMon::SerializeToWhiteboard(NKikimrWhiteboard::TBSGrou
calculate(GetResponseTime);
}
pb.SetGroupID(groupId);
- pb.SetLatency(flag);
+ pb.SetLatency(flag);
}
bool TBlobStorageGroupProxyMon::GetGroupIdGen(ui32 *groupId, ui32 *groupGen) const {
diff --git a/ydb/core/blobstorage/nodewarden/blobstorage_node_warden_ut.cpp b/ydb/core/blobstorage/nodewarden/blobstorage_node_warden_ut.cpp
index 7a9704c7bfc..e3c74cce7b4 100644
--- a/ydb/core/blobstorage/nodewarden/blobstorage_node_warden_ut.cpp
+++ b/ydb/core/blobstorage/nodewarden/blobstorage_node_warden_ut.cpp
@@ -27,11 +27,11 @@
#include <library/cpp/testing/unittest/registar.h>
const bool STRAND_PDISK = true;
-#ifndef NDEBUG
-const bool ENABLE_DETAILED_HIVE_LOG = true;
-#else
+#ifndef NDEBUG
+const bool ENABLE_DETAILED_HIVE_LOG = true;
+#else
const bool ENABLE_DETAILED_HIVE_LOG = false;
-#endif
+#endif
namespace NKikimr {
@@ -96,12 +96,12 @@ void SetupLogging(TTestActorRuntime& runtime) {
runtime.SetLogPriority(NKikimrServices::TABLET_MAIN, otherPriority);
runtime.SetLogPriority(NKikimrServices::TABLET_EXECUTOR, otherPriority);
runtime.SetLogPriority(NKikimrServices::BS_PROXY, otherPriority);
- runtime.SetLogPriority(NKikimrServices::PIPE_CLIENT, otherPriority);
- runtime.SetLogPriority(NKikimrServices::TABLET_RESOLVER, otherPriority);
+ runtime.SetLogPriority(NKikimrServices::PIPE_CLIENT, otherPriority);
+ runtime.SetLogPriority(NKikimrServices::TABLET_RESOLVER, otherPriority);
- runtime.SetLogPriority(NKikimrServices::BS_SKELETON, otherPriority);
- runtime.SetLogPriority(NKikimrServices::BS_SYNCJOB, otherPriority);
- runtime.SetLogPriority(NKikimrServices::BS_SYNCER, otherPriority);
+ runtime.SetLogPriority(NKikimrServices::BS_SKELETON, otherPriority);
+ runtime.SetLogPriority(NKikimrServices::BS_SYNCJOB, otherPriority);
+ runtime.SetLogPriority(NKikimrServices::BS_SYNCER, otherPriority);
}
void SetupServices(TTestActorRuntime &runtime, TString extraPath, TIntrusivePtr<NPDisk::TSectorMap> extraSectorMap) {
@@ -136,7 +136,7 @@ void SetupServices(TTestActorRuntime &runtime, TString extraPath, TIntrusivePtr<
app.AddHive(domainId, MakeDefaultHiveID(stateStorageGroup));
}
- SetupChannelProfiles(app, domainId);
+ SetupChannelProfiles(app, domainId);
if (false) { // setup channel profiles
TIntrusivePtr<TChannelProfiles> channelProfiles = new TChannelProfiles;
@@ -229,7 +229,7 @@ void SetupServices(TTestActorRuntime &runtime, TString extraPath, TIntrusivePtr<
// Magic path from testlib, do not change it
- TString pDiskPath1 = TStringBuilder() << baseDir << "pdisk_1.dat";
+ TString pDiskPath1 = TStringBuilder() << baseDir << "pdisk_1.dat";
TIntrusivePtr<NPDisk::TSectorMap> sectorMap1(new NPDisk::TSectorMap());
sectorMap1->ForceSize(64ull << 30ull);
sectorMap1->ZeroInit(32);
@@ -257,10 +257,10 @@ void SetupServices(TTestActorRuntime &runtime, TString extraPath, TIntrusivePtr<
ui64 defaultStateStorageGroup = runtime.GetAppData(0).DomainsInfo->GetDefaultStateStorageGroup(DOMAIN_ID);
CreateTestBootstrapper(runtime, CreateTestTabletInfo(MakeBSControllerID(defaultStateStorageGroup),
- TTabletTypes::FLAT_BS_CONTROLLER, TBlobStorageGroupType::ErasureMirror3, groupId),
- &CreateFlatBsController);
+ TTabletTypes::FLAT_BS_CONTROLLER, TBlobStorageGroupType::ErasureMirror3, groupId),
+ &CreateFlatBsController);
- SetupBoxAndStoragePool(runtime, runtime.AllocateEdgeActor(), domainId);
+ SetupBoxAndStoragePool(runtime, runtime.AllocateEdgeActor(), domainId);
}
void Setup(TTestActorRuntime &runtime, TString extraPath, TIntrusivePtr<NPDisk::TSectorMap> extraSectorMap) {
@@ -320,19 +320,19 @@ Y_UNIT_TEST_SUITE(TBlobStorageWardenTest) {
void CreateStoragePool(TTestBasicRuntime& runtime, ui32 domainId, TString name, TString kind) {
auto stateStorage = runtime.GetAppData().DomainsInfo->GetDefaultStateStorageGroup(domainId);
- NKikimrBlobStorage::TDefineStoragePool storagePool = runtime.GetAppData().DomainsInfo->GetDomain(domainId).StoragePoolTypes.at(kind);
+ NKikimrBlobStorage::TDefineStoragePool storagePool = runtime.GetAppData().DomainsInfo->GetDomain(domainId).StoragePoolTypes.at(kind);
TActorId edge = runtime.AllocateEdgeActor();
auto request = std::make_unique<TEvBlobStorage::TEvControllerConfigRequest>();
Y_VERIFY(storagePool.GetKind() == kind);
- storagePool.ClearStoragePoolId();
+ storagePool.ClearStoragePoolId();
storagePool.SetName(name);
storagePool.SetNumGroups(1);
storagePool.SetEncryptionMode(1);
request->Record.MutableRequest()->AddCommand()->MutableDefineStoragePool()->CopyFrom(storagePool);
NTabletPipe::TClientConfig pipeConfig;
- pipeConfig.RetryPolicy = NTabletPipe::TClientRetryPolicy::WithRetries();
+ pipeConfig.RetryPolicy = NTabletPipe::TClientRetryPolicy::WithRetries();
runtime.SendToPipe(MakeBSControllerID(stateStorage), edge, request.release(), 0, pipeConfig);
auto reply = runtime.GrabEdgeEventRethrow<TEvBlobStorage::TEvControllerConfigResponse>(edge);
@@ -350,7 +350,7 @@ Y_UNIT_TEST_SUITE(TBlobStorageWardenTest) {
groupParams->MutableStoragePoolSpecifier()->SetName(poolName);
NTabletPipe::TClientConfig pipeConfig;
- pipeConfig.RetryPolicy = NTabletPipe::TClientRetryPolicy::WithRetries();
+ pipeConfig.RetryPolicy = NTabletPipe::TClientRetryPolicy::WithRetries();
runtime.SendToPipe(MakeBSControllerID(stateStorage), edge, selectGroups.release(), 0, pipeConfig);
auto reply = runtime.GrabEdgeEventRethrow<TEvBlobStorage::TEvControllerSelectGroupsResult>(edge);
@@ -379,7 +379,7 @@ Y_UNIT_TEST_SUITE(TBlobStorageWardenTest) {
readPool->AddName(name);
NTabletPipe::TClientConfig pipeConfig;
- pipeConfig.RetryPolicy = NTabletPipe::TClientRetryPolicy::WithRetries();
+ pipeConfig.RetryPolicy = NTabletPipe::TClientRetryPolicy::WithRetries();
runtime.SendToPipe(MakeBSControllerID(stateStorage), edge, selectGroups.release(), 0, pipeConfig);
auto reply = runtime.GrabEdgeEventRethrow<TEvBlobStorage::TEvControllerConfigResponse>(edge);
@@ -398,7 +398,7 @@ Y_UNIT_TEST_SUITE(TBlobStorageWardenTest) {
deletePool->SetItemConfigGeneration(storagePool.GetItemConfigGeneration());
NTabletPipe::TClientConfig pipeConfig;
- pipeConfig.RetryPolicy = NTabletPipe::TClientRetryPolicy::WithRetries();
+ pipeConfig.RetryPolicy = NTabletPipe::TClientRetryPolicy::WithRetries();
runtime.SendToPipe(MakeBSControllerID(stateStorage), edge, selectGroups.release(), 0, pipeConfig);
auto reply = runtime.GrabEdgeEventRethrow<TEvBlobStorage::TEvControllerConfigResponse>(edge);
@@ -455,8 +455,8 @@ Y_UNIT_TEST_SUITE(TBlobStorageWardenTest) {
auto sender0 = runtime.AllocateEdgeActor(0);
- CreateStoragePool(runtime, DOMAIN_ID, "test_storage", "pool-kind-1");
- ui32 groupId = GetGroupFromPool(runtime, DOMAIN_ID, "test_storage");
+ CreateStoragePool(runtime, DOMAIN_ID, "test_storage", "pool-kind-1");
+ ui32 groupId = GetGroupFromPool(runtime, DOMAIN_ID, "test_storage");
ui64 tabletId = 1234;
ui32 generation = 1;
@@ -464,7 +464,7 @@ Y_UNIT_TEST_SUITE(TBlobStorageWardenTest) {
BlockGroup(runtime, sender0, tabletId, groupId, generation, true, NKikimrProto::EReplyStatus::RACE);
BlockGroup(runtime, sender0, tabletId, groupId, generation-1, true, NKikimrProto::EReplyStatus::RACE);
- auto describePool = DescribeStoragePool(runtime, DOMAIN_ID, "test_storage");
+ auto describePool = DescribeStoragePool(runtime, DOMAIN_ID, "test_storage");
{
TBlockUpdates bloker(runtime);
RemoveStoragePool(runtime, DOMAIN_ID, describePool);
@@ -507,8 +507,8 @@ Y_UNIT_TEST_SUITE(TBlobStorageWardenTest) {
auto sender0 = runtime.AllocateEdgeActor(0);
auto sender1 = runtime.AllocateEdgeActor(1);
- CreateStoragePool(runtime, DOMAIN_ID, "test_storage", "pool-kind-1");
- ui32 groupId = GetGroupFromPool(runtime, DOMAIN_ID, "test_storage");
+ CreateStoragePool(runtime, DOMAIN_ID, "test_storage", "pool-kind-1");
+ ui32 groupId = GetGroupFromPool(runtime, DOMAIN_ID, "test_storage");
ui64 tabletId = 1234;
ui32 generation = 1;
diff --git a/ydb/core/blobstorage/nodewarden/node_warden.h b/ydb/core/blobstorage/nodewarden/node_warden.h
index eb1ec7daeda..4d915508690 100644
--- a/ydb/core/blobstorage/nodewarden/node_warden.h
+++ b/ydb/core/blobstorage/nodewarden/node_warden.h
@@ -38,7 +38,7 @@ namespace NKikimr {
TNodeWardenConfig(const TIntrusivePtr<IPDiskServiceFactory> &pDiskServiceFactory)
: PDiskServiceFactory(pDiskServiceFactory)
- , AllVDiskKinds(new TAllVDiskKinds)
+ , AllVDiskKinds(new TAllVDiskKinds)
, AllDriveModels(new NPDisk::TDriveModelDb)
{}
diff --git a/ydb/core/blobstorage/nodewarden/node_warden_impl.cpp b/ydb/core/blobstorage/nodewarden/node_warden_impl.cpp
index 581e78225f1..47093a108da 100644
--- a/ydb/core/blobstorage/nodewarden/node_warden_impl.cpp
+++ b/ydb/core/blobstorage/nodewarden/node_warden_impl.cpp
@@ -364,12 +364,12 @@ void TNodeWarden::SendDiskMetrics(bool reportMetrics) {
for (auto& vdisk : std::exchange(VDisksWithUnreportedMetrics, {})) {
Y_VERIFY(vdisk.VDiskMetrics);
record.AddVDisksMetrics()->CopyFrom(*vdisk.VDiskMetrics);
- }
+ }
for (auto& pdisk : std::exchange(PDisksWithUnreportedMetrics, {})) {
Y_VERIFY(pdisk.PDiskMetrics);
record.AddPDisksMetrics()->CopyFrom(*pdisk.PDiskMetrics);
}
- }
+ }
FillInVDiskStatus(record.MutableVDiskStatus(), false);
@@ -377,7 +377,7 @@ void TNodeWarden::SendDiskMetrics(bool reportMetrics) {
SendToController(std::move(ev));
}
}
-
+
void TNodeWarden::Handle(TEvStatusUpdate::TPtr ev) {
STLOG(PRI_DEBUG, BS_NODE, NW47, "Handle(TEvStatusUpdate)");
auto *msg = ev->Get();
diff --git a/ydb/core/blobstorage/pdisk/blobstorage_pdisk_actor.cpp b/ydb/core/blobstorage/pdisk/blobstorage_pdisk_actor.cpp
index 94b1b942796..d92b19c6cca 100644
--- a/ydb/core/blobstorage/pdisk/blobstorage_pdisk_actor.cpp
+++ b/ydb/core/blobstorage/pdisk/blobstorage_pdisk_actor.cpp
@@ -179,10 +179,10 @@ class TPDiskActor : public TActorBootstrapped<TPDiskActor> {
void Render(IOutputStream& os) const {
switch (LastFlag) {
- case NKikimrWhiteboard::Grey:
+ case NKikimrWhiteboard::Grey:
break;
- default:
- THtmlLightSignalRenderer(LastFlag, NKikimrWhiteboard::EFlag_Name(LastFlag)).Output(os);
+ default:
+ THtmlLightSignalRenderer(LastFlag, NKikimrWhiteboard::EFlag_Name(LastFlag)).Output(os);
break;
}
}
@@ -409,7 +409,7 @@ public:
if (!PDisk->CheckGuid(&info)) {
*PDisk->Mon.PDiskState = NKikimrBlobStorage::TPDiskState::InitialFormatReadError;
*PDisk->Mon.PDiskBriefState = TPDiskMon::TPDisk::Error;
- *PDisk->Mon.PDiskDetailedState = TPDiskMon::TPDisk::ErrorInitialFormatReadDueToGuid;
+ *PDisk->Mon.PDiskDetailedState = TPDiskMon::TPDisk::ErrorInitialFormatReadDueToGuid;
PDisk->ErrorStr = TStringBuilder() << "Can't start due to a guid error " << info;
TStringStream str;
str << "PDiskId# " << PDisk->PDiskId << PDisk->ErrorStr;
diff --git a/ydb/core/blobstorage/pdisk/blobstorage_pdisk_impl.cpp b/ydb/core/blobstorage/pdisk/blobstorage_pdisk_impl.cpp
index d33f4384e78..d00fc0f2203 100644
--- a/ydb/core/blobstorage/pdisk/blobstorage_pdisk_impl.cpp
+++ b/ydb/core/blobstorage/pdisk/blobstorage_pdisk_impl.cpp
@@ -1209,9 +1209,9 @@ void TPDisk::WhiteboardReport(TWhiteboardReport &whiteboardReport) {
vslotId->SetPDiskId(PDiskId);
vslotId->SetVSlotId(data.VDiskSlotId);
}
- NKikimrBlobStorage::TPDiskMetrics& pDiskMetrics = *reportResult->DiskMetrics->Record.AddPDisksMetrics();
- pDiskMetrics.SetPDiskId(PDiskId);
- pDiskMetrics.SetTotalSize(Format.DiskSize);
+ NKikimrBlobStorage::TPDiskMetrics& pDiskMetrics = *reportResult->DiskMetrics->Record.AddPDisksMetrics();
+ pDiskMetrics.SetPDiskId(PDiskId);
+ pDiskMetrics.SetTotalSize(Format.DiskSize);
pDiskMetrics.SetAvailableSize(availableSize);
pDiskMetrics.SetMaxReadThroughput(DriveModel.Speed(TDriveModel::OP_TYPE_READ));
pDiskMetrics.SetMaxWriteThroughput(DriveModel.Speed(TDriveModel::OP_TYPE_WRITE));
@@ -2339,7 +2339,7 @@ bool TPDisk::PreprocessRequest(TRequestBase *request) {
case ERequestType::RequestLogRead:
{
TLogRead &evLog = *static_cast<TLogRead*>(request);
- TOwnerData &ownerData = OwnerData[evLog.Owner];
+ TOwnerData &ownerData = OwnerData[evLog.Owner];
if (ownerData.HasReadTheWholeLog) {
err << "Can't read log for ownerId# " << evLog.Owner
<< " ownerRound# " << evLog.OwnerRound << ", owner has already read the log!";
@@ -2429,7 +2429,7 @@ bool TPDisk::PreprocessRequest(TRequestBase *request) {
{
TChunkWrite &ev = *static_cast<TChunkWrite*>(request);
- TOwnerData &ownerData = OwnerData[ev.Owner];
+ TOwnerData &ownerData = OwnerData[ev.Owner];
Mon.QueueRequests->Dec();
const ui32 size = ev.PartsPtr ? ev.PartsPtr->ByteSize() : 0;
*Mon.QueueBytes -= size;
diff --git a/ydb/core/blobstorage/pdisk/blobstorage_pdisk_internal_interface.cpp b/ydb/core/blobstorage/pdisk/blobstorage_pdisk_internal_interface.cpp
index 4cea7e79547..43b0c69ae9b 100644
--- a/ydb/core/blobstorage/pdisk/blobstorage_pdisk_internal_interface.cpp
+++ b/ydb/core/blobstorage/pdisk/blobstorage_pdisk_internal_interface.cpp
@@ -20,7 +20,7 @@ TString TEvWhiteboardReportResult::ToString(const TEvWhiteboardReportResult &rec
str << " VDiskState# " << std::get<1>(p);
}
if (record.DiskMetrics) {
- str << " DiskMetrics# " << record.DiskMetrics->Record;
+ str << " DiskMetrics# " << record.DiskMetrics->Record;
}
str << "}";
return str.Str();
diff --git a/ydb/core/blobstorage/pdisk/blobstorage_pdisk_mon.h b/ydb/core/blobstorage/pdisk/blobstorage_pdisk_mon.h
index 4e52e73aa63..38a0f73b7c8 100644
--- a/ydb/core/blobstorage/pdisk/blobstorage_pdisk_mon.h
+++ b/ydb/core/blobstorage/pdisk/blobstorage_pdisk_mon.h
@@ -344,7 +344,7 @@ struct TPDiskMon {
BootingFormatMagicChecking,
BootingDeviceFormattingAndTrimming,
ErrorInitialFormatRead,
- ErrorInitialFormatReadDueToGuid,
+ ErrorInitialFormatReadDueToGuid,
ErrorInitialFormatReadIncompleteFormat,
ErrorDiskCannotBeFormated,
ErrorPDiskCannotBeInitialised,
@@ -385,7 +385,7 @@ struct TPDiskMon {
case BootingFormatMagicChecking: return "BootingFormatMagicChecking";
case BootingDeviceFormattingAndTrimming: return "BootingDeviceFormattingAndTrimming";
case ErrorInitialFormatRead: return "ErrorInitialFormatRead";
- case ErrorInitialFormatReadDueToGuid: return "ErrorInitialFormatReadDueToGuid";
+ case ErrorInitialFormatReadDueToGuid: return "ErrorInitialFormatReadDueToGuid";
case ErrorInitialFormatReadIncompleteFormat: return "ErrorInitialFormatReadIncompleteFormat";
case ErrorDiskCannotBeFormated: return "ErrorDiskCannotBeFormated";
case ErrorPDiskCannotBeInitialised: return "ErrorPDiskCannotBeInitialised";
diff --git a/ydb/core/blobstorage/pdisk/blobstorage_pdisk_ut_http_request.h b/ydb/core/blobstorage/pdisk/blobstorage_pdisk_ut_http_request.h
index 3b3b0e2d2ec..7f4a18c762f 100644
--- a/ydb/core/blobstorage/pdisk/blobstorage_pdisk_ut_http_request.h
+++ b/ydb/core/blobstorage/pdisk/blobstorage_pdisk_ut_http_request.h
@@ -36,10 +36,10 @@ struct THttpRequest : NMonitoring::IHttpRequest {
const THttpHeaders& GetHeaders() const override {
return HttpHeaders;
}
-
- TString GetRemoteAddr() const override {
- return TString();
- }
+
+ TString GetRemoteAddr() const override {
+ return TString();
+ }
};
} // NKikimr
diff --git a/ydb/core/blobstorage/pdisk/blobstorage_pdisk_ut_run.cpp b/ydb/core/blobstorage/pdisk/blobstorage_pdisk_ut_run.cpp
index 7721edfc790..5935d13229e 100644
--- a/ydb/core/blobstorage/pdisk/blobstorage_pdisk_ut_run.cpp
+++ b/ydb/core/blobstorage/pdisk/blobstorage_pdisk_ut_run.cpp
@@ -138,10 +138,10 @@ void Run(TVector<IActor*> tests, TTestRunConfig runCfg) {
if (IsMonitoringEnabled) {
// Monitoring startup
- monitoring.Reset(new NActors::TMon({
- .Port = pm.GetPort(8081),
- .Title = "TestYard monitoring"
- }));
+ monitoring.Reset(new NActors::TMon({
+ .Port = pm.GetPort(8081),
+ .Title = "TestYard monitoring"
+ }));
appData.Mon = monitoring.Get();
monitoring->RegisterCountersPage("counters", "Counters", mainCounters);
diff --git a/ydb/core/blobstorage/ut_vdisk/lib/astest.h b/ydb/core/blobstorage/ut_vdisk/lib/astest.h
index 6e99549c1a5..2cf254eff2c 100644
--- a/ydb/core/blobstorage/ut_vdisk/lib/astest.h
+++ b/ydb/core/blobstorage/ut_vdisk/lib/astest.h
@@ -106,10 +106,10 @@ inline void TTestWithActorSystem::Run(NActors::IActor *testActor) {
if (!MonPort) {
MonPort = pm.GetPort(MonPort);
}
- Monitoring.reset(new NActors::TMon({
- .Port = MonPort,
- .Title = "at"
- }));
+ Monitoring.reset(new NActors::TMon({
+ .Port = MonPort,
+ .Title = "at"
+ }));
NMonitoring::TIndexMonPage *actorsMonPage = Monitoring->RegisterIndexPage("actors", "Actors");
Y_UNUSED(actorsMonPage);
Monitoring->RegisterCountersPage("counters", "Counters", Counters);
diff --git a/ydb/core/blobstorage/ut_vdisk/lib/prepare.cpp b/ydb/core/blobstorage/ut_vdisk/lib/prepare.cpp
index 8f38afdb625..b2c020c3d21 100644
--- a/ydb/core/blobstorage/ut_vdisk/lib/prepare.cpp
+++ b/ydb/core/blobstorage/ut_vdisk/lib/prepare.cpp
@@ -359,10 +359,10 @@ void TConfiguration::Prepare(IVDiskSetup *vdiskSetup, bool newPDisks, bool runRe
//////////////////////////////////////////////////////////////////////////////
///////////////////////// MONITORING SETTINGS /////////////////////////////////
- Monitoring.reset(new NActors::TMon({
- .Port = 8088,
- .Title = "at"
- }));
+ Monitoring.reset(new NActors::TMon({
+ .Port = 8088,
+ .Title = "at"
+ }));
NMonitoring::TIndexMonPage *actorsMonPage = Monitoring->RegisterIndexPage("actors", "Actors");
Monitoring->RegisterCountersPage("counters", "Counters", Counters);
Monitoring->Start();
diff --git a/ydb/core/blobstorage/vdisk/common/vdisk_config.cpp b/ydb/core/blobstorage/vdisk/common/vdisk_config.cpp
index 891f6b21157..312fb3961ff 100644
--- a/ydb/core/blobstorage/vdisk/common/vdisk_config.cpp
+++ b/ydb/core/blobstorage/vdisk/common/vdisk_config.cpp
@@ -176,7 +176,7 @@ namespace NKikimr {
bool result = google::protobuf::TextFormat::ParseFromString(prototext, &AllKindsConfig);
Y_VERIFY(result, "Failed to parse AllVDiskKinds config "
"(error in protobuf format):\n%s\n", prototext.data());
- ParseConfig();
+ ParseConfig();
}
TIntrusivePtr<TVDiskConfig> TAllVDiskKinds::MakeVDiskConfig(const TVDiskConfig::TBaseInfo &baseInfo) {
@@ -203,25 +203,25 @@ namespace NKikimr {
return cfg;
}
- void TAllVDiskKinds::Merge(const NKikimrBlobStorage::TAllVDiskKinds &allVDiskKinds) {
- AllKindsConfig.MergeFrom(allVDiskKinds);
+ void TAllVDiskKinds::Merge(const NKikimrBlobStorage::TAllVDiskKinds &allVDiskKinds) {
+ AllKindsConfig.MergeFrom(allVDiskKinds);
- ParseConfig();
- }
+ ParseConfig();
+ }
- void TAllVDiskKinds::ParseConfig() {
- bool result;
- KindsMap.clear();
- for (const auto &x : AllKindsConfig.GetVDiskKinds()) {
- EKind kind = x.GetKind();
+ void TAllVDiskKinds::ParseConfig() {
+ bool result;
+ KindsMap.clear();
+ for (const auto &x : AllKindsConfig.GetVDiskKinds()) {
+ EKind kind = x.GetKind();
Y_VERIFY(kind != NKikimrBlobStorage::TVDiskKind::Default,
"It is forbidden to redefine Default kind");
- const NKikimrBlobStorage::TVDiskKind *val = &x;
- result = KindsMap.emplace(kind, val).second;
+ const NKikimrBlobStorage::TVDiskKind *val = &x;
+ result = KindsMap.emplace(kind, val).second;
Y_VERIFY(result, "Duplicate elements in the AllVDiskKinds config: kind='%s",
NKikimrBlobStorage::TVDiskKind::EVDiskKind_Name(kind).data());
- }
- }
-
-
+ }
+ }
+
+
} // NKikimr
diff --git a/ydb/core/blobstorage/vdisk/common/vdisk_config.h b/ydb/core/blobstorage/vdisk/common/vdisk_config.h
index 81886e108ff..ff4bb4f0d61 100644
--- a/ydb/core/blobstorage/vdisk/common/vdisk_config.h
+++ b/ydb/core/blobstorage/vdisk/common/vdisk_config.h
@@ -219,7 +219,7 @@ namespace NKikimr {
public:
TAllVDiskKinds(const TString &prototext = TString());
TIntrusivePtr<TVDiskConfig> MakeVDiskConfig(const TVDiskConfig::TBaseInfo &baseInfo);
- void Merge(const NKikimrBlobStorage::TAllVDiskKinds &allVDiskKinds);
+ void Merge(const NKikimrBlobStorage::TAllVDiskKinds &allVDiskKinds);
private:
using EKind = NKikimrBlobStorage::TVDiskKind::EVDiskKind;
@@ -229,8 +229,8 @@ namespace NKikimr {
NKikimrBlobStorage::TAllVDiskKinds AllKindsConfig;
TVDiskConfig VDiskMegaBaseConfig;
TKindsMap KindsMap;
-
- void ParseConfig();
+
+ void ParseConfig();
};
} // NKikimr
diff --git a/ydb/core/blobstorage/vdisk/hulldb/base/blobstorage_hullsatisfactionrank.cpp b/ydb/core/blobstorage/vdisk/hulldb/base/blobstorage_hullsatisfactionrank.cpp
index 55cb0f426c4..74ed554356b 100644
--- a/ydb/core/blobstorage/vdisk/hulldb/base/blobstorage_hullsatisfactionrank.cpp
+++ b/ydb/core/blobstorage/vdisk/hulldb/base/blobstorage_hullsatisfactionrank.cpp
@@ -127,7 +127,7 @@ namespace NKikimr {
TDecimal yellow,
TDecimal red,
NKikimrWhiteboard::TVDiskSatisfactionRank::TRank &r) {
- //r.SetRankPercent((rank * 100u).ToUi64());
+ //r.SetRankPercent((rank * 100u).ToUi64());
if (rank < yellow) {
r.SetFlag(NKikimrWhiteboard::Green);
} else if (rank < red) {
@@ -143,7 +143,7 @@ namespace NKikimr {
void TDynamicPDiskWeightsManager::DefWhiteboard(NKikimrWhiteboard::TVDiskSatisfactionRank &v) {
auto set = [] (NKikimrWhiteboard::TVDiskSatisfactionRank::TRank &r) {
- //r.SetRankPercent(0);
+ //r.SetRankPercent(0);
r.SetFlag(NKikimrWhiteboard::Green);
};
diff --git a/ydb/core/blobstorage/vdisk/hulldb/base/blobstorage_hullsatisfactionrank.h b/ydb/core/blobstorage/vdisk/hulldb/base/blobstorage_hullsatisfactionrank.h
index 28f4c4c3b89..faefa8ac859 100644
--- a/ydb/core/blobstorage/vdisk/hulldb/base/blobstorage_hullsatisfactionrank.h
+++ b/ydb/core/blobstorage/vdisk/hulldb/base/blobstorage_hullsatisfactionrank.h
@@ -120,10 +120,10 @@ namespace NKikimr {
return TThis(Val * v.Val / Base);
}
- TThis operator + (const TThis &v) const {
- return TThis(Val + v.Val);
- }
-
+ TThis operator + (const TThis &v) const {
+ return TThis(Val + v.Val);
+ }
+
TThis operator * (ui64 i) const {
return TThis(Val * i);
}
diff --git a/ydb/core/blobstorage/vdisk/skeleton/blobstorage_skeleton.cpp b/ydb/core/blobstorage/vdisk/skeleton/blobstorage_skeleton.cpp
index 8d752a460cf..96b813d3172 100644
--- a/ydb/core/blobstorage/vdisk/skeleton/blobstorage_skeleton.cpp
+++ b/ydb/core/blobstorage/vdisk/skeleton/blobstorage_skeleton.cpp
@@ -59,7 +59,7 @@ namespace NKikimr {
////////////////////////////////////////////////////////////////////////
// WHITEBOARD SECTOR
// Update Whiteboard with the current status
- // Update NodeWarden with current VDisk rank
+ // Update NodeWarden with current VDisk rank
////////////////////////////////////////////////////////////////////////
void UpdateWhiteboard(const TActorContext &ctx) {
// satisfaction rank
@@ -78,16 +78,16 @@ namespace NKikimr {
record.SetWriteThroughput(bytesWritten * 1000000 / delta.MicroSeconds());
}
ctx.Send(*SkeletonFrontIDPtr, ev.release());
- // send VDisk's metric to NodeWarden
+ // send VDisk's metric to NodeWarden
if (OverloadHandler) {
- ctx.Send(NodeWardenServiceId,
+ ctx.Send(NodeWardenServiceId,
new TEvBlobStorage::TEvControllerUpdateDiskStatus(
SelfVDiskId,
OverloadHandler->GetIntegralRankPercent(),
SelfId().NodeId(),
Config->BaseInfo.PDiskId,
Config->BaseInfo.VDiskSlotId));
- }
+ }
// repeat later
ctx.Schedule(Config->WhiteboardUpdateInterval, new TEvTimeToUpdateWhiteboard());
}
@@ -2425,7 +2425,7 @@ namespace NKikimr {
, LocalRecovInfo()
, SkeletonFrontIDPtr(new TActorId(skeletonFrontID))
, LocalDbRecoveryID()
- , NodeWardenServiceId(MakeBlobStorageNodeWardenID(vctx->NodeId))
+ , NodeWardenServiceId(MakeBlobStorageNodeWardenID(vctx->NodeId))
, SelfVDiskId(GInfo->GetVDiskId(VCtx->ShortSelfVDisk))
, Arena(std::make_shared<TRopeArena>(&TRopeArenaBackend::Allocate))
, VDiskMonGroup(VCtx->VDiskCounters, "subsystem", "state")
diff --git a/ydb/core/client/client_ut.cpp b/ydb/core/client/client_ut.cpp
index 9c3361909f8..b94c722588b 100644
--- a/ydb/core/client/client_ut.cpp
+++ b/ydb/core/client/client_ut.cpp
@@ -16,7 +16,7 @@
#include <ydb/library/yql/ast/yql_ast.h>
#include <ydb/library/yql/ast/yql_expr.h>
-#include <util/folder/path.h>
+#include <util/folder/path.h>
#include <util/generic/xrange.h>
#include <util/string/subst.h>
#include <util/thread/pool.h>
@@ -489,13 +489,13 @@ Y_UNIT_TEST_SUITE(TClientTest) {
Y_UNIT_TEST(ReadWriteViaMiniKQL) {
TPortManager tp;
ui16 port = tp.GetPort(2134);
-
+
const auto settings = TServerSettings(port);
TServer server(settings);
TClient client(settings);
client.InitRootScheme();
-
+
{
TTestTables tables(client, TTestTables::OneShard_NoOpts);
ReadWriteViaMiniKQLBody(client, false, false);
@@ -521,7 +521,7 @@ Y_UNIT_TEST_SUITE(TClientTest) {
ReadWriteViaMiniKQLBody(client, false, false);
}
}
-
+
Y_UNIT_TEST(ReadWrite_MiniKQL_AfterAlter) {
TPortManager tp;
ui16 port = tp.GetPort(2134);
@@ -815,9 +815,9 @@ Y_UNIT_TEST_SUITE(TClientTest) {
)
)
)___";
-
+
UNIT_ASSERT(client.FlatQuery(writeQuery, writeRes));
-
+
NKikimrMiniKQL::TResult updateRes;
const TString updateQuery = R"___(
(
@@ -836,18 +836,18 @@ Y_UNIT_TEST_SUITE(TClientTest) {
))
)
)___";
-
+
UNIT_ASSERT(client.FlatQuery(updateQuery, updateRes));
-
+
{
TValue value = TValue::Create(updateRes.GetValue(), updateRes.GetType());
TValue cmp1Opt = value["cmp1"];
TValue cmp2Opt = value["cmp2"];
-
+
UNIT_ASSERT(cmp1Opt.HaveValue() && bool(cmp1Opt) == true);
UNIT_ASSERT(cmp2Opt.HaveValue() && bool(cmp2Opt) == false);
}
-
+
NKikimrMiniKQL::TResult readRes;
const TString readQuery = R"___(
(
@@ -864,34 +864,34 @@ Y_UNIT_TEST_SUITE(TClientTest) {
))
)
)___";
-
+
UNIT_ASSERT(client.FlatQuery(readQuery, readRes));
-
+
{
TValue value = TValue::Create(readRes.GetValue(), readRes.GetType());
TValue row1Opt = value["row1"];
TValue row2Opt = value["row2"];
-
+
UNIT_ASSERT(row1Opt.HaveValue() && ui64(row1Opt) == 10);
UNIT_ASSERT(row2Opt.HaveValue() && ui64(row2Opt) == 50);
}
- }
-
+ }
+
Y_UNIT_TEST(CASViaMiniKQL) {
TPortManager tp;
ui16 port = tp.GetPort(2134);
-
+
const auto settings = TServerSettings(port);
TServer server(settings);
TClient client(settings);
client.InitRootScheme();
-
+
{
TTestTables tables(client, TTestTables::OneShard_NoOpts);
CASViaMiniKQLBody(client);
}
-
+
{
TTestTables tables(client, TTestTables::OneShard_OutOfOrder);
CASViaMiniKQLBody(client);
@@ -2169,7 +2169,7 @@ Y_UNIT_TEST_SUITE(TClientTest) {
NTabletPipe::TClientConfig pipeClientConfig;
pipeClientConfig.AllowFollower = true;
pipeClientConfig.ForceFollower = true;
- pipeClientConfig.RetryPolicy = {.RetryLimitCount = 2};
+ pipeClientConfig.RetryPolicy = {.RetryLimitCount = 2};
runtime.Register(NTabletPipe::CreateClient(edge, tabletId, pipeClientConfig));
auto reply = runtime.GrabEdgeEvent<TEvTabletPipe::TEvClientConnected>(edge);
@@ -2275,7 +2275,7 @@ Y_UNIT_TEST_SUITE(TClientTest) {
NTabletPipe::TClientConfig pipeClientConfig;
pipeClientConfig.AllowFollower = true;
pipeClientConfig.ForceFollower = true;
- pipeClientConfig.RetryPolicy = {.RetryLimitCount = 2};
+ pipeClientConfig.RetryPolicy = {.RetryLimitCount = 2};
runtime.Register(NTabletPipe::CreateClient(edge, tabletId, pipeClientConfig));
auto reply = runtime.GrabEdgeEvent<TEvTabletPipe::TEvClientConnected>(edge);
@@ -2418,7 +2418,7 @@ Y_UNIT_TEST_SUITE(TClientTest) {
NTabletPipe::TClientConfig pipeClientConfig;
pipeClientConfig.AllowFollower = true;
pipeClientConfig.ForceFollower = true;
- pipeClientConfig.RetryPolicy = {.RetryLimitCount = 2};
+ pipeClientConfig.RetryPolicy = {.RetryLimitCount = 2};
runtime.Register(NTabletPipe::CreateClient(edge, tabletId, pipeClientConfig));
auto reply = runtime.GrabEdgeEvent<TEvTabletPipe::TEvClientConnected>(edge);
@@ -2465,7 +2465,7 @@ Y_UNIT_TEST_SUITE(TClientTest) {
NTabletPipe::TClientConfig pipeClientConfig;
pipeClientConfig.AllowFollower = true;
pipeClientConfig.ForceFollower = true;
- pipeClientConfig.RetryPolicy = {.RetryLimitCount = 2};
+ pipeClientConfig.RetryPolicy = {.RetryLimitCount = 2};
runtime.Register(NTabletPipe::CreateClient(edge, tabletId, pipeClientConfig));
auto reply = runtime.GrabEdgeEvent<TEvTabletPipe::TEvClientConnected>(edge);
diff --git a/ydb/core/client/flat_ut.cpp b/ydb/core/client/flat_ut.cpp
index c25ed32e492..362c052aa11 100644
--- a/ydb/core/client/flat_ut.cpp
+++ b/ydb/core/client/flat_ut.cpp
@@ -1080,7 +1080,7 @@ Y_UNIT_TEST_SUITE(TFlatTest) {
if (selfName != "/") {
selfName= name.substr(name.find_last_of('/')+1);
}
- TAutoPtr<NMsgBusProxy::TBusResponse> res = annoyingClient.Ls(name);
+ TAutoPtr<NMsgBusProxy::TBusResponse> res = annoyingClient.Ls(name);
UNIT_ASSERT_VALUES_EQUAL_C(res->Record.GetPathDescription().GetSelf().GetName(), selfName, "Self name doesn't match");
// Compare expected and actual children count
@@ -1104,7 +1104,7 @@ Y_UNIT_TEST_SUITE(TFlatTest) {
}
void TestLsUknownPath(TFlatMsgBusClient& annoyingClient, const TString& name) {
- TAutoPtr<NMsgBusProxy::TBusResponse> res = annoyingClient.Ls(name);
+ TAutoPtr<NMsgBusProxy::TBusResponse> res = annoyingClient.Ls(name);
UNIT_ASSERT_VALUES_EQUAL_C(res->Record.HasPathDescription(), false,
"Unxepected description for " + name);
UNIT_ASSERT_VALUES_EQUAL_C(res->Record.GetStatus(), NMsgBusProxy::MSTATUS_ERROR,
@@ -1222,7 +1222,7 @@ Y_UNIT_TEST_SUITE(TFlatTest) {
}
void TestLsPathIdSuccess(TFlatMsgBusClient& annoyingClient, ui64 schemeshardId, ui64 pathId, const TString& selfName, const TVector<TString>& children) {
- TAutoPtr<NMsgBusProxy::TBusResponse> res = annoyingClient.LsPathId(schemeshardId, pathId);
+ TAutoPtr<NMsgBusProxy::TBusResponse> res = annoyingClient.LsPathId(schemeshardId, pathId);
UNIT_ASSERT_VALUES_EQUAL_C(res->Record.GetPathDescription().GetSelf().GetName(), selfName, "Self name doesn't match");
// Compare expected and actual children count
@@ -1243,7 +1243,7 @@ Y_UNIT_TEST_SUITE(TFlatTest) {
}
void TestLsUknownPathId(TFlatMsgBusClient& annoyingClient, ui64 schemeshardId, ui64 pathId) {
- TAutoPtr<NMsgBusProxy::TBusResponse> res = annoyingClient.LsPathId(schemeshardId, pathId);
+ TAutoPtr<NMsgBusProxy::TBusResponse> res = annoyingClient.LsPathId(schemeshardId, pathId);
UNIT_ASSERT_VALUES_EQUAL_C(res->Record.HasPathDescription(), false,
"Unxepected description for pathId " + ToString(pathId));
UNIT_ASSERT_VALUES_EQUAL_C(res->Record.GetStatus(), NMsgBusProxy::MSTATUS_ERROR,
@@ -1257,7 +1257,7 @@ Y_UNIT_TEST_SUITE(TFlatTest) {
TFlatMsgBusClient annoyingClient(port);
- TAutoPtr<NMsgBusProxy::TBusResponse> res = annoyingClient.Ls("/");
+ TAutoPtr<NMsgBusProxy::TBusResponse> res = annoyingClient.Ls("/");
ui64 schemeshardId = res->Record.GetPathDescription().GetChildren(0).GetSchemeshardId();
annoyingClient.InitRoot();
@@ -1298,92 +1298,92 @@ Y_UNIT_TEST_SUITE(TFlatTest) {
UNIT_ASSERT_VALUES_EQUAL(TestInitRoot(annoyingClient, "dc-11"), NMsgBusProxy::MSTATUS_ERROR);
UNIT_ASSERT_VALUES_EQUAL(TestInitRoot(annoyingClient, "dc-2"), NMsgBusProxy::MSTATUS_ERROR);
}
-
+
Y_UNIT_TEST(CheckACL) {
- TPortManager pm;
- ui16 port = pm.GetPort(2134);
+ TPortManager pm;
+ ui16 port = pm.GetPort(2134);
TServer cleverServer = TServer(TServerSettings(port));
- if (!true) {
- cleverServer.GetRuntime()->SetLogPriority(NKikimrServices::FLAT_TX_SCHEMESHARD, NActors::NLog::PRI_DEBUG);
- cleverServer.GetRuntime()->SetLogPriority(NKikimrServices::TX_DATASHARD, NActors::NLog::PRI_DEBUG);
- cleverServer.GetRuntime()->SetLogPriority(NKikimrServices::TX_PROXY, NActors::NLog::PRI_DEBUG);
- cleverServer.GetRuntime()->SetLogPriority(NKikimrServices::HIVE, NActors::NLog::PRI_DEBUG);
- cleverServer.GetRuntime()->SetLogPriority(NKikimrServices::TABLET_MAIN, NActors::NLog::PRI_DEBUG);
- cleverServer.GetRuntime()->SetLogPriority(NKikimrServices::PIPE_CLIENT, NActors::NLog::PRI_DEBUG);
- }
-
- TFlatMsgBusClient annoyingClient(port);
+ if (!true) {
+ cleverServer.GetRuntime()->SetLogPriority(NKikimrServices::FLAT_TX_SCHEMESHARD, NActors::NLog::PRI_DEBUG);
+ cleverServer.GetRuntime()->SetLogPriority(NKikimrServices::TX_DATASHARD, NActors::NLog::PRI_DEBUG);
+ cleverServer.GetRuntime()->SetLogPriority(NKikimrServices::TX_PROXY, NActors::NLog::PRI_DEBUG);
+ cleverServer.GetRuntime()->SetLogPriority(NKikimrServices::HIVE, NActors::NLog::PRI_DEBUG);
+ cleverServer.GetRuntime()->SetLogPriority(NKikimrServices::TABLET_MAIN, NActors::NLog::PRI_DEBUG);
+ cleverServer.GetRuntime()->SetLogPriority(NKikimrServices::PIPE_CLIENT, NActors::NLog::PRI_DEBUG);
+ }
+
+ TFlatMsgBusClient annoyingClient(port);
annoyingClient.InitRoot();
annoyingClient.ModifyOwner("/", "dc-1", "berkanavt@" BUILTIN_ACL_DOMAIN);
annoyingClient.SetSecurityToken("berkanavt@" BUILTIN_ACL_DOMAIN); // there is should be something like "234ba4f44ef7c"
-
- NMsgBusProxy::EResponseStatus status;
-
- status = annoyingClient.MkDir("/dc-1", "Berkanavt");
- UNIT_ASSERT_VALUES_EQUAL(status, NMsgBusProxy::MSTATUS_OK);
- status = annoyingClient.MkDir("/dc-1/Berkanavt", "tables");
- UNIT_ASSERT_VALUES_EQUAL(status, NMsgBusProxy::MSTATUS_OK);
-
+
+ NMsgBusProxy::EResponseStatus status;
+
+ status = annoyingClient.MkDir("/dc-1", "Berkanavt");
+ UNIT_ASSERT_VALUES_EQUAL(status, NMsgBusProxy::MSTATUS_OK);
+ status = annoyingClient.MkDir("/dc-1/Berkanavt", "tables");
+ UNIT_ASSERT_VALUES_EQUAL(status, NMsgBusProxy::MSTATUS_OK);
+
status = annoyingClient.CreateTable("/dc-1/Berkanavt",
"Name: \"Unused\""
- "Columns { Name: \"key1\" Type: \"Uint32\"}"
+ "Columns { Name: \"key1\" Type: \"Uint32\"}"
"Columns { Name: \"key2\" Type: \"Utf8\"}"
- "Columns { Name: \"RowId\" Type: \"Uint64\"}"
+ "Columns { Name: \"RowId\" Type: \"Uint64\"}"
"Columns { Name: \"Value\" Type: \"Utf8\"}"
- "KeyColumnNames: [\"RowId\", \"key1\", \"key2\"]"
- );
+ "KeyColumnNames: [\"RowId\", \"key1\", \"key2\"]"
+ );
UNIT_ASSERT_VALUES_EQUAL(status, NMsgBusProxy::MSTATUS_OK);
-
+
status = annoyingClient.CreateTable("/dc-1/Berkanavt/tables",
- "Name: \"Students\""
- "Columns { Name: \"Id\" Type: \"Uint32\"}"
+ "Name: \"Students\""
+ "Columns { Name: \"Id\" Type: \"Uint32\"}"
"Columns { Name: \"Name\" Type: \"Utf8\"}"
"Columns { Name: \"LastName\" Type: \"Utf8\"}"
- "Columns { Name: \"Age\" Type: \"Uint32\"}"
- "KeyColumnNames: [\"Id\"]"
- "UniformPartitionsCount: 10"
- );
+ "Columns { Name: \"Age\" Type: \"Uint32\"}"
+ "KeyColumnNames: [\"Id\"]"
+ "UniformPartitionsCount: 10"
+ );
UNIT_ASSERT_VALUES_EQUAL(status, NMsgBusProxy::MSTATUS_OK);
-
- TAutoPtr<NMsgBusProxy::TBusResponse> response;
-
- response = annoyingClient.Ls("/");
- UNIT_ASSERT_VALUES_EQUAL(response->Record.GetStatus(), NMsgBusProxy::MSTATUS_OK);
- response = annoyingClient.Ls("/dc-100");
- UNIT_ASSERT_VALUES_EQUAL(response->Record.GetStatus(), NMsgBusProxy::MSTATUS_ERROR);
+
+ TAutoPtr<NMsgBusProxy::TBusResponse> response;
+
+ response = annoyingClient.Ls("/");
+ UNIT_ASSERT_VALUES_EQUAL(response->Record.GetStatus(), NMsgBusProxy::MSTATUS_OK);
+ response = annoyingClient.Ls("/dc-100");
+ UNIT_ASSERT_VALUES_EQUAL(response->Record.GetStatus(), NMsgBusProxy::MSTATUS_ERROR);
response = annoyingClient.Ls("/dc-1/Argonaut");
- UNIT_ASSERT_VALUES_EQUAL(response->Record.GetStatus(), NMsgBusProxy::MSTATUS_ERROR);
- response = annoyingClient.Ls("/dc-1/Berkanavt/tabls");
- UNIT_ASSERT_VALUES_EQUAL(response->Record.GetStatus(), NMsgBusProxy::MSTATUS_ERROR);
- response = annoyingClient.Ls("/dc-1/Berkanavt/tables");
- UNIT_ASSERT_VALUES_EQUAL(response->Record.GetStatus(), NMsgBusProxy::MSTATUS_OK);
+ UNIT_ASSERT_VALUES_EQUAL(response->Record.GetStatus(), NMsgBusProxy::MSTATUS_ERROR);
+ response = annoyingClient.Ls("/dc-1/Berkanavt/tabls");
+ UNIT_ASSERT_VALUES_EQUAL(response->Record.GetStatus(), NMsgBusProxy::MSTATUS_ERROR);
+ response = annoyingClient.Ls("/dc-1/Berkanavt/tables");
+ UNIT_ASSERT_VALUES_EQUAL(response->Record.GetStatus(), NMsgBusProxy::MSTATUS_OK);
response = annoyingClient.Ls("/dc-1/Berkanavt/tables/Students");
- UNIT_ASSERT_VALUES_EQUAL(response->Record.GetStatus(), NMsgBusProxy::MSTATUS_OK);
+ UNIT_ASSERT_VALUES_EQUAL(response->Record.GetStatus(), NMsgBusProxy::MSTATUS_OK);
- ui64 studentsTableId;
- {
- TAutoPtr<NMsgBusProxy::TBusResponse> response = annoyingClient.Ls("/dc-1/Berkanavt/tables/Students");
- studentsTableId = response.Get()->Record.GetPathDescription().GetSelf().GetPathId();
- }
+ ui64 studentsTableId;
+ {
+ TAutoPtr<NMsgBusProxy::TBusResponse> response = annoyingClient.Ls("/dc-1/Berkanavt/tables/Students");
+ studentsTableId = response.Get()->Record.GetPathDescription().GetSelf().GetPathId();
+ }
TTableId tabletId(ChangeStateStorage(Tests::SchemeRoot, TestDomain), studentsTableId);
-
+
annoyingClient.SetSecurityToken("argonaut@" BUILTIN_ACL_DOMAIN); // there is should be something like "234ba4f44ef7c"
annoyingClient.FlatQuery("((return (AsList (SetResult 'res1 (Int32 '2016)))))");
-
+
const char * updateProgram = R"((
(let update_ '('('Name (Utf8 'Robert)) '('Age (Uint32 '21))))
(return (AsList (UpdateRow '/dc-1/Berkanavt/tables/Students '('('Id (Uint32 '42))) update_)))
))";
-
- // Update
+
+ // Update
annoyingClient.FlatQuery(updateProgram,
- NMsgBusProxy::MSTATUS_ERROR,
+ NMsgBusProxy::MSTATUS_ERROR,
TEvTxUserProxy::TResultStatus::AccessDenied); // as argonaut@
-
- annoyingClient.SetSecurityToken("berkanavt@" BUILTIN_ACL_DOMAIN); // there is should be something like "234ba4f44ef7c"
+
+ annoyingClient.SetSecurityToken("berkanavt@" BUILTIN_ACL_DOMAIN); // there is should be something like "234ba4f44ef7c"
annoyingClient.FlatQuery(updateProgram); // as berkanavt@
-
- NACLib::TDiffACL acl;
+
+ NACLib::TDiffACL acl;
acl.AddAccess(NACLib::EAccessType::Allow, NACLib::GenericWrite, "argonaut@" BUILTIN_ACL_DOMAIN);
annoyingClient.SetSecurityToken("argonaut@" BUILTIN_ACL_DOMAIN);
@@ -1407,7 +1407,7 @@ Y_UNIT_TEST_SUITE(TFlatTest) {
acl.ClearAccess();
acl.AddAccess(NACLib::EAccessType::Allow, NACLib::GenericRead, "argonaut@" BUILTIN_ACL_DOMAIN);
-
+
annoyingClient.ModifyACL("/dc-1", "Berkanavt", acl.SerializeAsString()); // as argonaut@
annoyingClient.ResetSchemeCache(cleverServer, tabletId);
annoyingClient.SetSecurityToken("argonaut@" BUILTIN_ACL_DOMAIN);
@@ -1420,17 +1420,17 @@ Y_UNIT_TEST_SUITE(TFlatTest) {
annoyingClient.FlatQuery(updateProgram,
NMsgBusProxy::MSTATUS_ERROR,
TEvTxUserProxy::TResultStatus::AccessDenied); // as argonaut@
-
+
annoyingClient.SetSecurityToken("berkanavt@" BUILTIN_ACL_DOMAIN); // as berkanavt@
NACLib::TDiffACL newAcl;
newAcl.ClearAccess();
newAcl.AddAccess(NACLib::EAccessType::Allow, NACLib::GenericWrite, "argonaut@" BUILTIN_ACL_DOMAIN);
annoyingClient.ModifyACL("/dc-1", "Berkanavt", newAcl.SerializeAsString()); // as berkanavt@
- annoyingClient.ResetSchemeCache(cleverServer, tabletId);
+ annoyingClient.ResetSchemeCache(cleverServer, tabletId);
annoyingClient.SetSecurityToken("argonaut@" BUILTIN_ACL_DOMAIN);
annoyingClient.FlatQuery(updateProgram); // as argonaut@
#endif
- }
+ }
Y_UNIT_TEST(OutOfDiskSpace) {
return; // TODO https://st.yandex-team.ru/KIKIMR-2279
diff --git a/ydb/core/client/flat_ut_client.h b/ydb/core/client/flat_ut_client.h
index 73fce2aab03..07f5b30cc6b 100644
--- a/ydb/core/client/flat_ut_client.h
+++ b/ydb/core/client/flat_ut_client.h
@@ -30,45 +30,45 @@ public:
NKikimrMiniKQL::TResult FlatQuery(const TString& mkql) {
NKikimrMiniKQL::TResult res;
TClient::TFlatQueryOptions opts;
- bool success = TClient::FlatQuery(mkql, opts, res, NMsgBusProxy::MSTATUS_OK);
- UNIT_ASSERT(success);
+ bool success = TClient::FlatQuery(mkql, opts, res, NMsgBusProxy::MSTATUS_OK);
+ UNIT_ASSERT(success);
return res;
- }
-
+ }
+
NKikimrMiniKQL::TResult FlatQuery(const TString& mkql, ui32 expectedStatus, ui32 expectedProxyErrorCode = TEvTxUserProxy::TResultStatus::Unknown) {
- NKikimrMiniKQL::TResult res;
- TClient::TFlatQueryOptions opts;
- NKikimrClient::TResponse expectedResponse;
- expectedResponse.SetStatus(expectedStatus);
- if (expectedProxyErrorCode != TEvTxUserProxy::TResultStatus::Unknown) {
- expectedResponse.SetProxyErrorCode(expectedProxyErrorCode);
- }
+ NKikimrMiniKQL::TResult res;
+ TClient::TFlatQueryOptions opts;
+ NKikimrClient::TResponse expectedResponse;
+ expectedResponse.SetStatus(expectedStatus);
+ if (expectedProxyErrorCode != TEvTxUserProxy::TResultStatus::Unknown) {
+ expectedResponse.SetProxyErrorCode(expectedProxyErrorCode);
+ }
bool success = TClient::FlatQuery(mkql, opts, res, expectedResponse);
UNIT_ASSERT(success == (expectedStatus == NMsgBusProxy::MSTATUS_OK));
return res;
}
- TAutoPtr<NMsgBusProxy::TBusResponse> LsPathId(ui64 schemeshardId, ui64 pathId) {
+ TAutoPtr<NMsgBusProxy::TBusResponse> LsPathId(ui64 schemeshardId, ui64 pathId) {
TAutoPtr<NMsgBusProxy::TBusSchemeDescribe> request(new NMsgBusProxy::TBusSchemeDescribe());
request->Record.SetPathId(pathId);
request->Record.SetSchemeshardId(schemeshardId);
TAutoPtr<NBus::TBusMessage> reply;
NBus::EMessageStatus msgStatus = SendWhenReady(request, reply);
UNIT_ASSERT_VALUES_EQUAL(msgStatus, NBus::MESSAGE_OK);
- Cout << PrintResult<NMsgBusProxy::TBusResponse>(reply.Get()) << Endl;
- return dynamic_cast<NMsgBusProxy::TBusResponse*>(reply.Release());
+ Cout << PrintResult<NMsgBusProxy::TBusResponse>(reply.Get()) << Endl;
+ return dynamic_cast<NMsgBusProxy::TBusResponse*>(reply.Release());
}
-
+
void ResetSchemeCache(Tests::TServer &server, TTableId tableId) {
- TTestActorRuntime* runtime = server.GetRuntime();
+ TTestActorRuntime* runtime = server.GetRuntime();
TActorId txProxy = MakeTxProxyID();
TActorId sender = runtime->AllocateEdgeActor();
- TAutoPtr<TEvTxUserProxy::TEvInvalidateTable> ev(new TEvTxUserProxy::TEvInvalidateTable(tableId));
+ TAutoPtr<TEvTxUserProxy::TEvInvalidateTable> ev(new TEvTxUserProxy::TEvInvalidateTable(tableId));
runtime->Send(new IEventHandle(txProxy, sender, ev.Release()));
- TAutoPtr<IEventHandle> handle;
- auto readSchemeStringResult = runtime->GrabEdgeEventRethrow<TEvTxUserProxy::TEvInvalidateTableResult>(handle);
- Y_UNUSED(readSchemeStringResult);
- }
+ TAutoPtr<IEventHandle> handle;
+ auto readSchemeStringResult = runtime->GrabEdgeEventRethrow<TEvTxUserProxy::TEvInvalidateTableResult>(handle);
+ Y_UNUSED(readSchemeStringResult);
+ }
void KillTablet(Tests::TServer &server, ui64 tabletId) {
TTestActorRuntime* runtime = server.GetRuntime();
@@ -107,14 +107,14 @@ public:
TAutoPtr<NBus::TBusMessage> reply;
NBus::EMessageStatus status = SendAndWaitCompletion(request.Release(), reply);
UNIT_ASSERT_VALUES_EQUAL(status, NBus::MESSAGE_OK);
- UNIT_ASSERT_VALUES_EQUAL(reply->GetHeader()->Type, (int)NMsgBusProxy::MTYPE_CLIENT_RESPONSE);
+ UNIT_ASSERT_VALUES_EQUAL(reply->GetHeader()->Type, (int)NMsgBusProxy::MTYPE_CLIENT_RESPONSE);
response = static_cast<NMsgBusProxy::TBusResponse *>(reply.Get())->Record;
}
NMsgBusProxy::EResponseStatus SplitTablePartition(const TString& tablePath, const TString& splitDescription) {
NKikimrClient::TResponse response;
TrySplitTablePartition(tablePath, splitDescription, response);
- UNIT_ASSERT_VALUES_EQUAL(response.GetStatus(), (int)NMsgBusProxy::MSTATUS_OK);
+ UNIT_ASSERT_VALUES_EQUAL(response.GetStatus(), (int)NMsgBusProxy::MSTATUS_OK);
return (NMsgBusProxy::EResponseStatus)response.GetStatus();
}
};
diff --git a/ydb/core/client/minikql_compile/mkql_compile_service.cpp b/ydb/core/client/minikql_compile/mkql_compile_service.cpp
index a53d68df7bc..e01d61a22cc 100644
--- a/ydb/core/client/minikql_compile/mkql_compile_service.cpp
+++ b/ydb/core/client/minikql_compile/mkql_compile_service.cpp
@@ -178,9 +178,9 @@ TActorId MakeMiniKQLCompileServiceID() {
const TActorId& GetMiniKQLCompileServiceID() {
static TActorId miniKQLCompileServiceID = MakeMiniKQLCompileServiceID();
- return miniKQLCompileServiceID;
-}
-
+ return miniKQLCompileServiceID;
+}
+
IActor* CreateMiniKQLCompileService(size_t compileInflightLimit) {
THolder<NYql::IDbSchemeResolver> resolver;
return new TMiniKQLCompileService(compileInflightLimit, std::move(resolver));
diff --git a/ydb/core/client/minikql_result_lib/converter.cpp b/ydb/core/client/minikql_result_lib/converter.cpp
index 386a67fe602..bfb1ea6db32 100644
--- a/ydb/core/client/minikql_result_lib/converter.cpp
+++ b/ydb/core/client/minikql_result_lib/converter.cpp
@@ -4,11 +4,11 @@
namespace NKikimr {
-namespace NResultLib {
+namespace NResultLib {
TStruct ConvertResult(const NKikimrMiniKQL::TValue& value, const NKikimrMiniKQL::TType& type) {
return TStruct(value, type);
}
-} // namespace NResultLib
+} // namespace NResultLib
} // namespace NKikimr
diff --git a/ydb/core/client/minikql_result_lib/converter.h b/ydb/core/client/minikql_result_lib/converter.h
index 9b9a4267575..108b098cfe1 100644
--- a/ydb/core/client/minikql_result_lib/converter.h
+++ b/ydb/core/client/minikql_result_lib/converter.h
@@ -12,7 +12,7 @@ class TType;
namespace NKikimr {
-namespace NResultLib {
+namespace NResultLib {
TStruct ConvertResult(const NKikimrMiniKQL::TValue& value, const NKikimrMiniKQL::TType& type);
@@ -25,5 +25,5 @@ inline TStruct ConvertResult(const NKikimr::NClient::TQueryResult& apiResult) {
return ConvertResult(result.GetValue(), result.GetType());
}
-} // namespace NResultLib
+} // namespace NResultLib
} // namespace NKikimr
diff --git a/ydb/core/client/minikql_result_lib/converter_ut.cpp b/ydb/core/client/minikql_result_lib/converter_ut.cpp
index 4c35aaf9de8..0fb5eff6211 100644
--- a/ydb/core/client/minikql_result_lib/converter_ut.cpp
+++ b/ydb/core/client/minikql_result_lib/converter_ut.cpp
@@ -8,8 +8,8 @@
namespace NKikimr {
-using namespace NResultLib;
-
+using namespace NResultLib;
+
Y_UNIT_TEST_SUITE(TMiniKQLResultConverterTest) {
Y_UNIT_TEST(TTestWithSimpleProgram) {
diff --git a/ydb/core/client/minikql_result_lib/objects.h b/ydb/core/client/minikql_result_lib/objects.h
index c744b58852a..4b5ae0da451 100644
--- a/ydb/core/client/minikql_result_lib/objects.h
+++ b/ydb/core/client/minikql_result_lib/objects.h
@@ -10,7 +10,7 @@
namespace NKikimr {
-namespace NResultLib {
+namespace NResultLib {
using TProtoValue = NKikimrMiniKQL::TValue;
using TProtoType = NKikimrMiniKQL::TType;
@@ -314,5 +314,5 @@ THashMap<K, V> TDict::GetHashMap() const {
#undef ENSURE_KIND
-} // namespace NResultLib
+} // namespace NResultLib
} // namespace NKikimr
diff --git a/ydb/core/client/minikql_result_lib/objects_ut.cpp b/ydb/core/client/minikql_result_lib/objects_ut.cpp
index b4a9a9b1f1c..49b3d300dcb 100644
--- a/ydb/core/client/minikql_result_lib/objects_ut.cpp
+++ b/ydb/core/client/minikql_result_lib/objects_ut.cpp
@@ -8,7 +8,7 @@
namespace NKikimr {
using namespace NKikimrMiniKQL;
-using namespace NResultLib;
+using namespace NResultLib;
Y_UNIT_TEST_SUITE(TMiniKQLResultTest) {
diff --git a/ydb/core/client/server/grpc_server.cpp b/ydb/core/client/server/grpc_server.cpp
index 46c65f2355d..aa122da36a1 100644
--- a/ydb/core/client/server/grpc_server.cpp
+++ b/ydb/core/client/server/grpc_server.cpp
@@ -460,10 +460,10 @@ void TGRpcService::SetupIncomingRequests() {
ADD_ACTOR_REQUEST(BlobStorageLoadRequest, TBsTestLoadRequest, MTYPE_CLIENT_LOAD_REQUEST)
ADD_ACTOR_REQUEST(BlobStorageGetRequest, TBsGetRequest, MTYPE_CLIENT_GET_REQUEST)
ADD_ACTOR_REQUEST(ChooseProxy, TChooseProxyRequest, MTYPE_CLIENT_CHOOSE_PROXY)
- ADD_ACTOR_REQUEST(WhoAmI, TWhoAmI, MTYPE_CLIENT_WHOAMI)
- ADD_ACTOR_REQUEST(ResolveNode, TResolveNodeRequest, MTYPE_CLIENT_RESOLVE_NODE)
- ADD_ACTOR_REQUEST(FillNode, TFillNodeRequest, MTYPE_CLIENT_FILL_NODE)
- ADD_ACTOR_REQUEST(DrainNode, TDrainNodeRequest, MTYPE_CLIENT_DRAIN_NODE)
+ ADD_ACTOR_REQUEST(WhoAmI, TWhoAmI, MTYPE_CLIENT_WHOAMI)
+ ADD_ACTOR_REQUEST(ResolveNode, TResolveNodeRequest, MTYPE_CLIENT_RESOLVE_NODE)
+ ADD_ACTOR_REQUEST(FillNode, TFillNodeRequest, MTYPE_CLIENT_FILL_NODE)
+ ADD_ACTOR_REQUEST(DrainNode, TDrainNodeRequest, MTYPE_CLIENT_DRAIN_NODE)
ADD_ACTOR_REQUEST(InterconnectDebug, TInterconnectDebug, MTYPE_CLIENT_INTERCONNECT_DEBUG)
ADD_ACTOR_REQUEST(TestShardControl, TTestShardControlRequest, MTYPE_CLIENT_TEST_SHARD_CONTROL)
@@ -511,7 +511,7 @@ void TGRpcService::SetupIncomingRequests() {
ADD_PROXY_REQUEST_BASE(NAME, TYPE, TResponse, EVENT_TYPE, MTYPE)
// proxy requests
- ADD_PROXY_REQUEST(SchemeInitRoot, TSchemeInitRoot, TEvBusProxy::TEvInitRoot, MTYPE_CLIENT_SCHEME_INITROOT)
+ ADD_PROXY_REQUEST(SchemeInitRoot, TSchemeInitRoot, TEvBusProxy::TEvInitRoot, MTYPE_CLIENT_SCHEME_INITROOT)
ADD_PROXY_REQUEST(PersQueueRequest, TPersQueueRequest, TEvBusProxy::TEvPersQueue, MTYPE_CLIENT_PERSQUEUE)
ADD_PROXY_REQUEST(Request, TRequest, TEvBusProxy::TEvRequest, MTYPE_CLIENT_REQUEST)
diff --git a/ydb/core/client/server/http_ping.cpp b/ydb/core/client/server/http_ping.cpp
index 9ea0fc8fb99..64e04c88d43 100644
--- a/ydb/core/client/server/http_ping.cpp
+++ b/ydb/core/client/server/http_ping.cpp
@@ -1,22 +1,22 @@
-#include "http_ping.h"
-
-namespace NKikimr {
-namespace NHttp {
-
-TPing::TPing()
- : NMonitoring::IMonPage("ping")
-{}
-
+#include "http_ping.h"
+
+namespace NKikimr {
+namespace NHttp {
+
+TPing::TPing()
+ : NMonitoring::IMonPage("ping")
+{}
+
void TPing::Output(NMonitoring::IMonHttpRequest& request) {
IOutputStream& out(request.Output());
- out << NMonitoring::HTTPOKTEXT;
- out << "ok /ping";
-}
-
-
-TPing* CreatePing() {
- return new TPing();
-}
-
-}
-}
+ out << NMonitoring::HTTPOKTEXT;
+ out << "ok /ping";
+}
+
+
+TPing* CreatePing() {
+ return new TPing();
+}
+
+}
+}
diff --git a/ydb/core/client/server/http_ping.h b/ydb/core/client/server/http_ping.h
index b21f1d34903..e07aba1eea2 100644
--- a/ydb/core/client/server/http_ping.h
+++ b/ydb/core/client/server/http_ping.h
@@ -1,19 +1,19 @@
-#pragma once
+#pragma once
#include <ydb/public/lib/base/defs.h>
#include <library/cpp/monlib/service/monservice.h>
#include <library/cpp/monlib/service/pages/mon_page.h>
#include <ydb/core/mon/mon.h>
-
-namespace NKikimr {
-namespace NHttp {
-
-class TPing : public NMonitoring::IMonPage {
-public:
- TPing();
+
+namespace NKikimr {
+namespace NHttp {
+
+class TPing : public NMonitoring::IMonPage {
+public:
+ TPing();
virtual void Output(NMonitoring::IMonHttpRequest& request) override;
-};
-
-TPing* CreatePing();
-
-}
-}
+};
+
+TPing* CreatePing();
+
+}
+}
diff --git a/ydb/core/client/server/msgbus_bsadm.cpp b/ydb/core/client/server/msgbus_bsadm.cpp
index 5f9f94c7222..a3bed376f43 100644
--- a/ydb/core/client/server/msgbus_bsadm.cpp
+++ b/ydb/core/client/server/msgbus_bsadm.cpp
@@ -1,5 +1,5 @@
#include "msgbus_tabletreq.h"
-#include "msgbus_securereq.h"
+#include "msgbus_securereq.h"
#include <ydb/core/blobstorage/base/blobstorage_events.h>
namespace NKikimr {
@@ -9,21 +9,21 @@ namespace {
const ui64 DefaultTimeout = 90000;
}
-class TMessageBusBSAdmGroupReconfigureWipe : public TMessageBusSecureRequest<
- TMessageBusSimpleTabletRequest<
- TMessageBusBSAdmGroupReconfigureWipe,
- TEvBlobStorage::TEvControllerGroupReconfigureWipeResult,
+class TMessageBusBSAdmGroupReconfigureWipe : public TMessageBusSecureRequest<
+ TMessageBusSimpleTabletRequest<
+ TMessageBusBSAdmGroupReconfigureWipe,
+ TEvBlobStorage::TEvControllerGroupReconfigureWipeResult,
NKikimrServices::TActivity::FRONT_BSADM_RECONF_REPLACE>> {
TAutoPtr<TEvBlobStorage::TEvControllerGroupReconfigureWipe> Ev;
public:
TMessageBusBSAdmGroupReconfigureWipe(TBusMessageContext &msg, ui64 tabletId,
TAutoPtr<TEvBlobStorage::TEvControllerGroupReconfigureWipe> ev, bool withRetry, TDuration timeout)
- : TMessageBusSecureRequest(msg, tabletId, withRetry, timeout, false)
+ : TMessageBusSecureRequest(msg, tabletId, withRetry, timeout, false)
, Ev(ev)
- {
- SetSecurityToken(static_cast<TBusBSAdm*>(msg.GetMessage())->Record.GetSecurityToken());
- SetRequireAdminAccess(true);
- }
+ {
+ SetSecurityToken(static_cast<TBusBSAdm*>(msg.GetMessage())->Record.GetSecurityToken());
+ SetRequireAdminAccess(true);
+ }
void Handle(TEvBlobStorage::TEvControllerGroupReconfigureWipeResult::TPtr &ev, const TActorContext &ctx) {
const NKikimrBlobStorage::TEvControllerGroupReconfigureWipeResult &record = ev->Get()->Record;
@@ -51,7 +51,7 @@ public:
}
};
-IActor* CreateMessageBusBSAdm(TBusMessageContext &msg) {
+IActor* CreateMessageBusBSAdm(TBusMessageContext &msg) {
const NKikimrClient::TBSAdm &record = static_cast<TBusBSAdm *>(msg.GetMessage())->Record;
const ui32 targetDomain = record.GetDomain();
diff --git a/ydb/core/client/server/msgbus_http_server.cpp b/ydb/core/client/server/msgbus_http_server.cpp
index 56da374fec9..e535ebe3350 100644
--- a/ydb/core/client/server/msgbus_http_server.cpp
+++ b/ydb/core/client/server/msgbus_http_server.cpp
@@ -2,232 +2,232 @@
#include <library/cpp/protobuf/json/json2proto.h>
#include <library/cpp/actors/core/actorsystem.h>
#include <ydb/public/lib/base/msgbus.h>
-#include "msgbus_http_server.h"
-#include "http_ping.h"
+#include "msgbus_http_server.h"
+#include "http_ping.h"
#include <ydb/core/base/counters.h>
#include <ydb/core/mon/mon.h>
#include <ydb/core/base/ticket_parser.h>
-
-namespace NKikimr {
-namespace NMsgBusProxy {
-
-class TBusHttpIdentity : public NBus::TBusIdentity {
-public:
- TBusHttpIdentity() {
- BeginWork();
- }
-
- void FinishWork() {
- EndWork();
- }
-};
-
-class TBusHttpServerSession : public NBus::TBusServerSession {
-public:
+
+namespace NKikimr {
+namespace NMsgBusProxy {
+
+class TBusHttpIdentity : public NBus::TBusIdentity {
+public:
+ TBusHttpIdentity() {
+ BeginWork();
+ }
+
+ void FinishWork() {
+ EndWork();
+ }
+};
+
+class TBusHttpServerSession : public NBus::TBusServerSession {
+public:
TBusHttpServerSession(IMessageBusHttpServer* httpServer, NMonitoring::IMonHttpRequest& request,
- const TProtocol& protocol, const NBus::TBusServerSessionConfig& config)
- : HttpServer(httpServer)
- , Request(request)
- , Protocol(protocol)
- , Config(config)
- , ReplySent(false)
- {}
-
- // dummy virtual handlers - just to make class constructable.
+ const TProtocol& protocol, const NBus::TBusServerSessionConfig& config)
+ : HttpServer(httpServer)
+ , Request(request)
+ , Protocol(protocol)
+ , Config(config)
+ , ReplySent(false)
+ {}
+
+ // dummy virtual handlers - just to make class constructable.
virtual void GetInFlightBulk(::TArrayRef<const NBus::TNetAddr>, TArrayRef<size_t>) const override {}
virtual void GetConnectSyscallsNumBulkForTest(::TArrayRef<const NBus::TNetAddr>, TArrayRef<size_t>) const override {}
- virtual int GetInFlight() const noexcept override { return 1; }
+ virtual int GetInFlight() const noexcept override { return 1; }
virtual TString GetStatus(ui16) override { return TString(); }
- virtual NBus::TConnectionStatusMonRecord GetStatusProtobuf() override { return NBus::TConnectionStatusMonRecord(); }
- virtual NBus::NPrivate::TSessionDumpStatus GetStatusRecordInternal() override { return NBus::NPrivate::TSessionDumpStatus(); }
+ virtual NBus::TConnectionStatusMonRecord GetStatusProtobuf() override { return NBus::TConnectionStatusMonRecord(); }
+ virtual NBus::NPrivate::TSessionDumpStatus GetStatusRecordInternal() override { return NBus::NPrivate::TSessionDumpStatus(); }
virtual TString GetStatusSingleLine() override { return TString(); }
- virtual const NBus::TBusSessionConfig* GetConfig() const noexcept override { return &Config; }
- virtual const NBus::TBusProtocol* GetProto() const noexcept override { return &Protocol; }
- virtual NBus::TBusMessageQueue* GetQueue() const noexcept override { return nullptr; }
+ virtual const NBus::TBusSessionConfig* GetConfig() const noexcept override { return &Config; }
+ virtual const NBus::TBusProtocol* GetProto() const noexcept override { return &Protocol; }
+ virtual NBus::TBusMessageQueue* GetQueue() const noexcept override { return nullptr; }
virtual TString GetNameInternal() override { return TString(); }
- virtual void Shutdown() override {}
- virtual void PauseInput(bool) override {}
- virtual unsigned GetActualListenPort() override { return 0; }
-
- // the only methods used
- virtual NBus::EMessageStatus SendReply(const NBus::TBusIdentity&, NBus::TBusMessage *pRep) override {
- TAutoPtr<NBus::TBusBufferBase> response(static_cast<NBus::TBusBufferBase*>(pRep));
+ virtual void Shutdown() override {}
+ virtual void PauseInput(bool) override {}
+ virtual unsigned GetActualListenPort() override { return 0; }
+
+ // the only methods used
+ virtual NBus::EMessageStatus SendReply(const NBus::TBusIdentity&, NBus::TBusMessage *pRep) override {
+ TAutoPtr<NBus::TBusBufferBase> response(static_cast<NBus::TBusBufferBase*>(pRep));
IOutputStream& out(Request.Output());
- if (response->GetHeader()->Type == MTYPE_CLIENT_RESPONSE) {
+ if (response->GetHeader()->Type == MTYPE_CLIENT_RESPONSE) {
NKikimrClient::TResponse* pbResponse(static_cast<NKikimrClient::TResponse*>(response->GetRecord()));
- NMsgBusProxy::EResponseStatus status = static_cast<NMsgBusProxy::EResponseStatus>(pbResponse->GetStatus());
- switch (status) {
- case MSTATUS_OK:
- out << "HTTP/1.1 200 Ok\r\nContent-Type: application/json; charset=utf-8\r\nConnection: Close\r\n\r\n";
- HttpServer->Status200->Inc();
- break;
- case MSTATUS_TIMEOUT:
- out << "HTTP/1.1 504 Gateway Timeout\r\nContent-Type: application/json\r\nConnection: Close\r\n\r\n";;
- HttpServer->Status504->Inc();
- break;
- case MSTATUS_NOTREADY:
- case MSTATUS_REJECTED:
- out << "HTTP/1.1 503 Service Unavailable\r\nContent-Type: application/json\r\nRetry-After: 1\r\nConnection: Close\r\n\r\n";;
- HttpServer->Status503->Inc();
- break;
- case MSTATUS_INTERNALERROR:
- out << "HTTP/1.1 500 Internal Server Error\r\nContent-Type: application/json\r\nConnection: Close\r\n\r\n";;
- HttpServer->Status500->Inc();
- break;
- default:
- // TODO: more status codes
- out << "HTTP/1.1 400 Bad Request\r\nContent-Type: application/json\r\nConnection: Close\r\n\r\n";;
- HttpServer->Status400->Inc();
- break;
- }
- } else {
- out << NMonitoring::HTTPOKJSON;
- HttpServer->Status200->Inc();
- }
- if (response->GetRecord()->GetDescriptor()->name() == "TJSON") {
+ NMsgBusProxy::EResponseStatus status = static_cast<NMsgBusProxy::EResponseStatus>(pbResponse->GetStatus());
+ switch (status) {
+ case MSTATUS_OK:
+ out << "HTTP/1.1 200 Ok\r\nContent-Type: application/json; charset=utf-8\r\nConnection: Close\r\n\r\n";
+ HttpServer->Status200->Inc();
+ break;
+ case MSTATUS_TIMEOUT:
+ out << "HTTP/1.1 504 Gateway Timeout\r\nContent-Type: application/json\r\nConnection: Close\r\n\r\n";;
+ HttpServer->Status504->Inc();
+ break;
+ case MSTATUS_NOTREADY:
+ case MSTATUS_REJECTED:
+ out << "HTTP/1.1 503 Service Unavailable\r\nContent-Type: application/json\r\nRetry-After: 1\r\nConnection: Close\r\n\r\n";;
+ HttpServer->Status503->Inc();
+ break;
+ case MSTATUS_INTERNALERROR:
+ out << "HTTP/1.1 500 Internal Server Error\r\nContent-Type: application/json\r\nConnection: Close\r\n\r\n";;
+ HttpServer->Status500->Inc();
+ break;
+ default:
+ // TODO: more status codes
+ out << "HTTP/1.1 400 Bad Request\r\nContent-Type: application/json\r\nConnection: Close\r\n\r\n";;
+ HttpServer->Status400->Inc();
+ break;
+ }
+ } else {
+ out << NMonitoring::HTTPOKJSON;
+ HttpServer->Status200->Inc();
+ }
+ if (response->GetRecord()->GetDescriptor()->name() == "TJSON") {
NKikimrClient::TJSON* json(static_cast<NKikimrClient::TJSON*>(response->GetRecord()));
- const auto& jsonString(json->GetJSON());
- out << jsonString;
+ const auto& jsonString(json->GetJSON());
+ out << jsonString;
*HttpServer->OutboundSize += jsonString.size();
- } else {
- out << response->GetRecord()->AsJSON();
- // TODO
- //*HttpServer->OutboundSize += ?
- }
- ReplySent = true;
- return NBus::MESSAGE_OK;
- }
-
- virtual NBus::EMessageStatus ForgetRequest(const NBus::TBusIdentity& ident) override {
- TBusHttpIdentity& httpIdent(const_cast<TBusHttpIdentity&>(static_cast<const TBusHttpIdentity&>(ident)));
- if (!ReplySent) {
+ } else {
+ out << response->GetRecord()->AsJSON();
+ // TODO
+ //*HttpServer->OutboundSize += ?
+ }
+ ReplySent = true;
+ return NBus::MESSAGE_OK;
+ }
+
+ virtual NBus::EMessageStatus ForgetRequest(const NBus::TBusIdentity& ident) override {
+ TBusHttpIdentity& httpIdent(const_cast<TBusHttpIdentity&>(static_cast<const TBusHttpIdentity&>(ident)));
+ if (!ReplySent) {
IOutputStream& out(Request.Output());
- out << NMonitoring::HTTPNOCONTENT;
- }
- httpIdent.FinishWork();
- DoneEvent.Signal();
- return NBus::MESSAGE_OK;
- }
-
- void Wait() {
- DoneEvent.WaitI();
- }
-
-protected:
- IMessageBusHttpServer* HttpServer;
+ out << NMonitoring::HTTPNOCONTENT;
+ }
+ httpIdent.FinishWork();
+ DoneEvent.Signal();
+ return NBus::MESSAGE_OK;
+ }
+
+ void Wait() {
+ DoneEvent.WaitI();
+ }
+
+protected:
+ IMessageBusHttpServer* HttpServer;
NMonitoring::IMonHttpRequest& Request;
- const TProtocol& Protocol;
- const NBus::TBusServerSessionConfig& Config;
+ const TProtocol& Protocol;
+ const NBus::TBusServerSessionConfig& Config;
TSystemEvent DoneEvent;
- bool ReplySent;
-};
-
-class TMessageBusHttpServer : public IMessageBusHttpServer {
-public:
- TMessageBusHttpServer(TActorSystem* actorSystem, NBus::IBusServerHandler* handler, const TProtocol& protocol, const NBus::TBusServerSessionConfig& config);
- ~TMessageBusHttpServer();
+ bool ReplySent;
+};
+
+class TMessageBusHttpServer : public IMessageBusHttpServer {
+public:
+ TMessageBusHttpServer(TActorSystem* actorSystem, NBus::IBusServerHandler* handler, const TProtocol& protocol, const NBus::TBusServerSessionConfig& config);
+ ~TMessageBusHttpServer();
virtual void Output(NMonitoring::IMonHttpRequest& request) override;
- virtual void Shutdown() override;
-
-protected:
- TActorSystem* ActorSystem;
- NBus::IBusServerHandler* Handler;
- const TProtocol& Protocol;
- NActors::TMon* Monitor;
- const NBus::TBusServerSessionConfig& Config;
-};
-
-TMessageBusHttpServer::TMessageBusHttpServer(TActorSystem* actorSystem, NBus::IBusServerHandler* handler, const TProtocol& protocol, const NBus::TBusServerSessionConfig& config)
- : IMessageBusHttpServer(protocol.GetService(), actorSystem->AppData<TAppData>()->Counters)
- , ActorSystem(actorSystem)
- , Handler(handler)
- , Protocol(protocol)
- , Monitor(actorSystem->AppData<TAppData>()->Mon)
- , Config(config)
-{
+ virtual void Shutdown() override;
+
+protected:
+ TActorSystem* ActorSystem;
+ NBus::IBusServerHandler* Handler;
+ const TProtocol& Protocol;
+ NActors::TMon* Monitor;
+ const NBus::TBusServerSessionConfig& Config;
+};
+
+TMessageBusHttpServer::TMessageBusHttpServer(TActorSystem* actorSystem, NBus::IBusServerHandler* handler, const TProtocol& protocol, const NBus::TBusServerSessionConfig& config)
+ : IMessageBusHttpServer(protocol.GetService(), actorSystem->AppData<TAppData>()->Counters)
+ , ActorSystem(actorSystem)
+ , Handler(handler)
+ , Protocol(protocol)
+ , Monitor(actorSystem->AppData<TAppData>()->Mon)
+ , Config(config)
+{
HttpGroup = GetServiceCounters(Counters, "proxy")->GetSubgroup("subsystem", "http");
- RequestsActive = HttpGroup->GetCounter("Requests/Active", false);
- RequestsCount = HttpGroup->GetCounter("Requests/Count", true);
- InboundSize = HttpGroup->GetCounter("Requests/InboundSize", true);
- OutboundSize = HttpGroup->GetCounter("Requests/OutboundSize", true);
- Status200 = HttpGroup->GetCounter("200", true);
- Status400 = HttpGroup->GetCounter("400", true);
- Status500 = HttpGroup->GetCounter("500", true);
- Status503 = HttpGroup->GetCounter("503", true);
- Status504 = HttpGroup->GetCounter("504", true);
- RequestTotalTimeHistogram.Init(HttpGroup.Get(), "RequestTotalTime", "ms", 1, 20);
- RequestPrepareTimeHistogram.Init(HttpGroup.Get(), "RequestPrepareTime", "ms", 1, 20);
- Monitor->Register(this);
-}
-
-TMessageBusHttpServer::~TMessageBusHttpServer() {
- Shutdown();
-}
-
-void TMessageBusHttpServer::Shutdown() {
- Handler = nullptr;
-}
-
+ RequestsActive = HttpGroup->GetCounter("Requests/Active", false);
+ RequestsCount = HttpGroup->GetCounter("Requests/Count", true);
+ InboundSize = HttpGroup->GetCounter("Requests/InboundSize", true);
+ OutboundSize = HttpGroup->GetCounter("Requests/OutboundSize", true);
+ Status200 = HttpGroup->GetCounter("200", true);
+ Status400 = HttpGroup->GetCounter("400", true);
+ Status500 = HttpGroup->GetCounter("500", true);
+ Status503 = HttpGroup->GetCounter("503", true);
+ Status504 = HttpGroup->GetCounter("504", true);
+ RequestTotalTimeHistogram.Init(HttpGroup.Get(), "RequestTotalTime", "ms", 1, 20);
+ RequestPrepareTimeHistogram.Init(HttpGroup.Get(), "RequestPrepareTime", "ms", 1, 20);
+ Monitor->Register(this);
+}
+
+TMessageBusHttpServer::~TMessageBusHttpServer() {
+ Shutdown();
+}
+
+void TMessageBusHttpServer::Shutdown() {
+ Handler = nullptr;
+}
+
void TMessageBusHttpServer::Output(NMonitoring::IMonHttpRequest& request) {
- if (Handler != nullptr) {
- THPTimer startTime;
+ if (Handler != nullptr) {
+ THPTimer startTime;
TString pathInfo{request.GetPathInfo().substr(1)};
TAutoPtr<NBus::TBusBufferBase> message = Protocol.NewMessage(pathInfo);
- if (message != nullptr) {
- RequestsCount->Inc();
- RequestsActive->Inc();
+ if (message != nullptr) {
+ RequestsCount->Inc();
+ RequestsActive->Inc();
TStringBuf postContent(request.GetPostContent());
*InboundSize += postContent.size();
- const ::google::protobuf::Descriptor* msgDescriptor = message->GetRecord()->GetDescriptor();
- if (msgDescriptor->name() == "TJSON") {
+ const ::google::protobuf::Descriptor* msgDescriptor = message->GetRecord()->GetDescriptor();
+ if (msgDescriptor->name() == "TJSON") {
NKikimrClient::TJSON* json(static_cast<NKikimrClient::TJSON*>(message->GetRecord()));
json->SetJSON(TString(postContent));
- } else {
- static NJson::TJsonReaderConfig readerConfig;
- static NProtobufJson::TJson2ProtoConfig protoConfig;
-
- TMemoryInput in(postContent);
- NJson::TJsonValue jsonValue;
- NJson::ReadJsonTree(&in, &readerConfig, &jsonValue, true);
- NProtobufJson::Json2Proto(jsonValue, *message->GetRecord(), protoConfig);
- }
- const ::google::protobuf::FieldDescriptor* fldDescriptor = msgDescriptor->FindFieldByName("SecurityToken");
- if (fldDescriptor != nullptr) {
- TStringBuf authorization = request.GetHeader("Authorization");
- if (!authorization.empty()) {
- const ::google::protobuf::Reflection* reflection = message->GetRecord()->GetReflection();
- reflection->SetString(
- message->GetRecord(),
- fldDescriptor,
- TString(authorization));
- }
- }
-
- LOG_DEBUG_S(*ActorSystem, NKikimrServices::HTTP, "HttpRequest "
+ } else {
+ static NJson::TJsonReaderConfig readerConfig;
+ static NProtobufJson::TJson2ProtoConfig protoConfig;
+
+ TMemoryInput in(postContent);
+ NJson::TJsonValue jsonValue;
+ NJson::ReadJsonTree(&in, &readerConfig, &jsonValue, true);
+ NProtobufJson::Json2Proto(jsonValue, *message->GetRecord(), protoConfig);
+ }
+ const ::google::protobuf::FieldDescriptor* fldDescriptor = msgDescriptor->FindFieldByName("SecurityToken");
+ if (fldDescriptor != nullptr) {
+ TStringBuf authorization = request.GetHeader("Authorization");
+ if (!authorization.empty()) {
+ const ::google::protobuf::Reflection* reflection = message->GetRecord()->GetReflection();
+ reflection->SetString(
+ message->GetRecord(),
+ fldDescriptor,
+ TString(authorization));
+ }
+ }
+
+ LOG_DEBUG_S(*ActorSystem, NKikimrServices::HTTP, "HttpRequest "
<< request.GetMethod()
- << " "
+ << " "
<< request.GetUri()
- << " "
- << message->GetRecord()->AsJSON());
-
- TBusHttpServerSession session(this, request, Protocol, Config);
- TBusHttpIdentity identity;
- NBus::TOnMessageContext onMessageContext(message.Release(), identity, &session);
- RequestPrepareTimeHistogram.Add(startTime.Passed() * 1000/*ms*/);
- Handler->OnMessage(onMessageContext);
- session.Wait();
- RequestsActive->Dec();
- } else {
+ << " "
+ << message->GetRecord()->AsJSON());
+
+ TBusHttpServerSession session(this, request, Protocol, Config);
+ TBusHttpIdentity identity;
+ NBus::TOnMessageContext onMessageContext(message.Release(), identity, &session);
+ RequestPrepareTimeHistogram.Add(startTime.Passed() * 1000/*ms*/);
+ Handler->OnMessage(onMessageContext);
+ session.Wait();
+ RequestsActive->Dec();
+ } else {
IOutputStream& out(request.Output());
- out << NMonitoring::HTTPNOTFOUND;
- }
- RequestTotalTimeHistogram.Add(startTime.Passed() * 1000/*ms*/);
- }
-}
-
-IMessageBusHttpServer* CreateMessageBusHttpServer(TActorSystem* actorSystem, NBus::IBusServerHandler* handler, const TProtocol& protocol, const NBus::TBusServerSessionConfig& config) {
- return new TMessageBusHttpServer(actorSystem, handler, protocol, config);
-}
-
-}
-}
+ out << NMonitoring::HTTPNOTFOUND;
+ }
+ RequestTotalTimeHistogram.Add(startTime.Passed() * 1000/*ms*/);
+ }
+}
+
+IMessageBusHttpServer* CreateMessageBusHttpServer(TActorSystem* actorSystem, NBus::IBusServerHandler* handler, const TProtocol& protocol, const NBus::TBusServerSessionConfig& config) {
+ return new TMessageBusHttpServer(actorSystem, handler, protocol, config);
+}
+
+}
+}
diff --git a/ydb/core/client/server/msgbus_http_server.h b/ydb/core/client/server/msgbus_http_server.h
index 11cb85b2ca5..911978c422e 100644
--- a/ydb/core/client/server/msgbus_http_server.h
+++ b/ydb/core/client/server/msgbus_http_server.h
@@ -1,4 +1,4 @@
-#pragma once
+#pragma once
#include <ydb/public/lib/base/defs.h>
#include <library/cpp/monlib/service/monservice.h>
#include <library/cpp/monlib/service/pages/mon_page.h>
@@ -6,36 +6,36 @@
#include <library/cpp/actors/helpers/mon_histogram_helper.h>
#include <ydb/public/lib/base/msgbus.h>
#include <ydb/core/base/appdata.h>
-
-namespace NKikimr {
-namespace NMsgBusProxy {
-
-class IMessageBusHttpServer : public NMonitoring::IMonPage {
-public:
+
+namespace NKikimr {
+namespace NMsgBusProxy {
+
+class IMessageBusHttpServer : public NMonitoring::IMonPage {
+public:
IMessageBusHttpServer(const TString& path, TIntrusivePtr<NMonitoring::TDynamicCounters> counters)
- : NMonitoring::IMonPage(path)
- , Counters(counters)
- {}
-
- virtual void Shutdown() = 0;
-
- // counters
- TIntrusivePtr<NMonitoring::TDynamicCounters> Counters;
- TIntrusivePtr<NMonitoring::TDynamicCounters> HttpGroup;
- NMonitoring::TDynamicCounters::TCounterPtr RequestsActive;
- NMonitoring::TDynamicCounters::TCounterPtr RequestsCount;
- NMonitoring::TDynamicCounters::TCounterPtr InboundSize;
- NMonitoring::TDynamicCounters::TCounterPtr OutboundSize;
- NMonitoring::TDynamicCounters::TCounterPtr Status200;
- NMonitoring::TDynamicCounters::TCounterPtr Status400;
- NMonitoring::TDynamicCounters::TCounterPtr Status500;
- NMonitoring::TDynamicCounters::TCounterPtr Status503;
- NMonitoring::TDynamicCounters::TCounterPtr Status504;
- NMon::THistogramCounterHelper RequestTotalTimeHistogram;
- NMon::THistogramCounterHelper RequestPrepareTimeHistogram;
-};
-
-IMessageBusHttpServer* CreateMessageBusHttpServer(TActorSystem* actorSystem, NBus::IBusServerHandler* handler, const TProtocol& protocol, const NBus::TBusServerSessionConfig& config);
-
-}
-}
+ : NMonitoring::IMonPage(path)
+ , Counters(counters)
+ {}
+
+ virtual void Shutdown() = 0;
+
+ // counters
+ TIntrusivePtr<NMonitoring::TDynamicCounters> Counters;
+ TIntrusivePtr<NMonitoring::TDynamicCounters> HttpGroup;
+ NMonitoring::TDynamicCounters::TCounterPtr RequestsActive;
+ NMonitoring::TDynamicCounters::TCounterPtr RequestsCount;
+ NMonitoring::TDynamicCounters::TCounterPtr InboundSize;
+ NMonitoring::TDynamicCounters::TCounterPtr OutboundSize;
+ NMonitoring::TDynamicCounters::TCounterPtr Status200;
+ NMonitoring::TDynamicCounters::TCounterPtr Status400;
+ NMonitoring::TDynamicCounters::TCounterPtr Status500;
+ NMonitoring::TDynamicCounters::TCounterPtr Status503;
+ NMonitoring::TDynamicCounters::TCounterPtr Status504;
+ NMon::THistogramCounterHelper RequestTotalTimeHistogram;
+ NMon::THistogramCounterHelper RequestPrepareTimeHistogram;
+};
+
+IMessageBusHttpServer* CreateMessageBusHttpServer(TActorSystem* actorSystem, NBus::IBusServerHandler* handler, const TProtocol& protocol, const NBus::TBusServerSessionConfig& config);
+
+}
+}
diff --git a/ydb/core/client/server/msgbus_securereq.h b/ydb/core/client/server/msgbus_securereq.h
index cdbce9d3388..5e68ca0eeb2 100644
--- a/ydb/core/client/server/msgbus_securereq.h
+++ b/ydb/core/client/server/msgbus_securereq.h
@@ -1,111 +1,111 @@
-#pragma once
-#include "msgbus_server.h"
-#include "msgbus_server_request.h"
-#include "msgbus_tabletreq.h"
+#pragma once
+#include "msgbus_server.h"
+#include "msgbus_server_request.h"
+#include "msgbus_tabletreq.h"
#include <ydb/core/tx/tx_proxy/proxy.h>
#include <ydb/core/security/secure_request.h>
-
-namespace NKikimr {
-namespace NMsgBusProxy {
-
-template <typename TBase>
-class TMessageBusSecureRequest;
-
-template <typename TDerived>
-class TMessageBusSecureRequest<TMessageBusServerRequestBase<TDerived>> : public
- TSecureRequestActor<TMessageBusServerRequestBase<TMessageBusSecureRequest<TMessageBusServerRequestBase<TDerived>>>, TDerived> {
-public:
+
+namespace NKikimr {
+namespace NMsgBusProxy {
+
+template <typename TBase>
+class TMessageBusSecureRequest;
+
+template <typename TDerived>
+class TMessageBusSecureRequest<TMessageBusServerRequestBase<TDerived>> : public
+ TSecureRequestActor<TMessageBusServerRequestBase<TMessageBusSecureRequest<TMessageBusServerRequestBase<TDerived>>>, TDerived> {
+public:
void OnAccessDenied(const TEvTicketParser::TError& error, const TActorContext& ctx) {
- TMessageBusServerRequestBase<TMessageBusSecureRequest<TMessageBusServerRequestBase<TDerived>>>::HandleError(
- MSTATUS_ERROR,
- TEvTxUserProxy::TEvProposeTransactionStatus::EStatus::AccessDenied,
+ TMessageBusServerRequestBase<TMessageBusSecureRequest<TMessageBusServerRequestBase<TDerived>>>::HandleError(
+ MSTATUS_ERROR,
+ TEvTxUserProxy::TEvProposeTransactionStatus::EStatus::AccessDenied,
error.Message,
- ctx);
- }
-
- template <typename... Args>
- TMessageBusSecureRequest(Args&&... args)
- : TSecureRequestActor<TMessageBusServerRequestBase<TMessageBusSecureRequest<TMessageBusServerRequestBase<TDerived>>>, TDerived>(std::forward<Args>(args)...)
- {}
-};
-
+ ctx);
+ }
+
+ template <typename... Args>
+ TMessageBusSecureRequest(Args&&... args)
+ : TSecureRequestActor<TMessageBusServerRequestBase<TMessageBusSecureRequest<TMessageBusServerRequestBase<TDerived>>>, TDerived>(std::forward<Args>(args)...)
+ {}
+};
+
template <typename TDerived, typename TTabletReplyEvent, NKikimrServices::TActivity::EType Activity>
-class TMessageBusSecureRequest<TMessageBusSimpleTabletRequest<TDerived, TTabletReplyEvent, Activity>> :
- public TSecureRequestActor<
- TMessageBusSimpleTabletRequest<TDerived, TTabletReplyEvent, Activity>,
- TMessageBusSecureRequest<TMessageBusSimpleTabletRequest<TDerived, TTabletReplyEvent, Activity>>,
- TMessageBusSimpleTabletRequest<TDerived, TTabletReplyEvent, Activity>> {
-public:
- void HandleError(EResponseStatus status, TEvTxUserProxy::TResultStatus::EStatus proxyStatus, const TActorContext &ctx) {
- HandleError(status, proxyStatus, TEvTxUserProxy::TResultStatus::Str(proxyStatus), ctx);
- }
-
- void HandleError(EResponseStatus status, TEvTxUserProxy::TResultStatus::EStatus proxyStatus, const TString& message, const TActorContext &ctx) {
- TAutoPtr<TBusResponse> response(new TBusResponseStatus(status, message));
-
- if (proxyStatus != TEvTxUserProxy::TResultStatus::Unknown)
- response->Record.SetProxyErrorCode(proxyStatus);
-
- TMessageBusSimpleTabletRequest<TDerived, TTabletReplyEvent, Activity>::SendReplyAutoPtr(response);
-
- TMessageBusSimpleTabletRequest<TDerived, TTabletReplyEvent, Activity>::Die(ctx);
- }
-
+class TMessageBusSecureRequest<TMessageBusSimpleTabletRequest<TDerived, TTabletReplyEvent, Activity>> :
+ public TSecureRequestActor<
+ TMessageBusSimpleTabletRequest<TDerived, TTabletReplyEvent, Activity>,
+ TMessageBusSecureRequest<TMessageBusSimpleTabletRequest<TDerived, TTabletReplyEvent, Activity>>,
+ TMessageBusSimpleTabletRequest<TDerived, TTabletReplyEvent, Activity>> {
+public:
+ void HandleError(EResponseStatus status, TEvTxUserProxy::TResultStatus::EStatus proxyStatus, const TActorContext &ctx) {
+ HandleError(status, proxyStatus, TEvTxUserProxy::TResultStatus::Str(proxyStatus), ctx);
+ }
+
+ void HandleError(EResponseStatus status, TEvTxUserProxy::TResultStatus::EStatus proxyStatus, const TString& message, const TActorContext &ctx) {
+ TAutoPtr<TBusResponse> response(new TBusResponseStatus(status, message));
+
+ if (proxyStatus != TEvTxUserProxy::TResultStatus::Unknown)
+ response->Record.SetProxyErrorCode(proxyStatus);
+
+ TMessageBusSimpleTabletRequest<TDerived, TTabletReplyEvent, Activity>::SendReplyAutoPtr(response);
+
+ TMessageBusSimpleTabletRequest<TDerived, TTabletReplyEvent, Activity>::Die(ctx);
+ }
+
void OnAccessDenied(const TEvTicketParser::TError& error, const TActorContext& ctx) {
- HandleError(
- MSTATUS_ERROR,
- TEvTxUserProxy::TEvProposeTransactionStatus::EStatus::AccessDenied,
+ HandleError(
+ MSTATUS_ERROR,
+ TEvTxUserProxy::TEvProposeTransactionStatus::EStatus::AccessDenied,
error.Message,
- ctx);
- }
-
- template <typename... Args>
- TMessageBusSecureRequest(Args&&... args)
- : TSecureRequestActor<
- TMessageBusSimpleTabletRequest<TDerived, TTabletReplyEvent, Activity>,
- TMessageBusSecureRequest<TMessageBusSimpleTabletRequest<TDerived, TTabletReplyEvent, Activity>>,
- TMessageBusSimpleTabletRequest<TDerived, TTabletReplyEvent, Activity>>(std::forward<Args>(args)...)
- {}
-};
-
-template <typename TDerived, typename TTabletReplyEvent>
-class TMessageBusSecureRequest<TMessageBusTabletRequest<TDerived, TTabletReplyEvent>> :
- public TSecureRequestActor<
- TMessageBusTabletRequest<TDerived, TTabletReplyEvent>,
- TMessageBusSecureRequest<TMessageBusTabletRequest<TDerived, TTabletReplyEvent>>,
- TMessageBusTabletRequest<TDerived, TTabletReplyEvent>> {
-public:
- void HandleError(EResponseStatus status, TEvTxUserProxy::TResultStatus::EStatus proxyStatus, const TActorContext &ctx) {
- HandleError(status, proxyStatus, TEvTxUserProxy::TResultStatus::Str(proxyStatus), ctx);
- }
-
- void HandleError(EResponseStatus status, TEvTxUserProxy::TResultStatus::EStatus proxyStatus, const TString& message, const TActorContext &ctx) {
- TAutoPtr<TBusResponse> response(new TBusResponseStatus(status, message));
-
- if (proxyStatus != TEvTxUserProxy::TResultStatus::Unknown)
- response->Record.SetProxyErrorCode(proxyStatus);
-
- TMessageBusTabletRequest<TDerived, TTabletReplyEvent>::SendReplyAutoPtr(response);
-
- TMessageBusTabletRequest<TDerived, TTabletReplyEvent>::Die(ctx);
- }
-
+ ctx);
+ }
+
+ template <typename... Args>
+ TMessageBusSecureRequest(Args&&... args)
+ : TSecureRequestActor<
+ TMessageBusSimpleTabletRequest<TDerived, TTabletReplyEvent, Activity>,
+ TMessageBusSecureRequest<TMessageBusSimpleTabletRequest<TDerived, TTabletReplyEvent, Activity>>,
+ TMessageBusSimpleTabletRequest<TDerived, TTabletReplyEvent, Activity>>(std::forward<Args>(args)...)
+ {}
+};
+
+template <typename TDerived, typename TTabletReplyEvent>
+class TMessageBusSecureRequest<TMessageBusTabletRequest<TDerived, TTabletReplyEvent>> :
+ public TSecureRequestActor<
+ TMessageBusTabletRequest<TDerived, TTabletReplyEvent>,
+ TMessageBusSecureRequest<TMessageBusTabletRequest<TDerived, TTabletReplyEvent>>,
+ TMessageBusTabletRequest<TDerived, TTabletReplyEvent>> {
+public:
+ void HandleError(EResponseStatus status, TEvTxUserProxy::TResultStatus::EStatus proxyStatus, const TActorContext &ctx) {
+ HandleError(status, proxyStatus, TEvTxUserProxy::TResultStatus::Str(proxyStatus), ctx);
+ }
+
+ void HandleError(EResponseStatus status, TEvTxUserProxy::TResultStatus::EStatus proxyStatus, const TString& message, const TActorContext &ctx) {
+ TAutoPtr<TBusResponse> response(new TBusResponseStatus(status, message));
+
+ if (proxyStatus != TEvTxUserProxy::TResultStatus::Unknown)
+ response->Record.SetProxyErrorCode(proxyStatus);
+
+ TMessageBusTabletRequest<TDerived, TTabletReplyEvent>::SendReplyAutoPtr(response);
+
+ TMessageBusTabletRequest<TDerived, TTabletReplyEvent>::Die(ctx);
+ }
+
void OnAccessDenied(const TEvTicketParser::TError& error, const TActorContext& ctx) {
- HandleError(
- MSTATUS_ERROR,
- TEvTxUserProxy::TEvProposeTransactionStatus::EStatus::AccessDenied,
+ HandleError(
+ MSTATUS_ERROR,
+ TEvTxUserProxy::TEvProposeTransactionStatus::EStatus::AccessDenied,
error.Message,
- ctx);
- }
-
- template <typename... Args>
- TMessageBusSecureRequest(Args&&... args)
- : TSecureRequestActor<
- TMessageBusTabletRequest<TDerived, TTabletReplyEvent>,
- TMessageBusSecureRequest<TMessageBusTabletRequest<TDerived, TTabletReplyEvent>>,
- TMessageBusTabletRequest<TDerived, TTabletReplyEvent>>(std::forward<Args>(args)...)
- {}
-};
-
-}
-}
+ ctx);
+ }
+
+ template <typename... Args>
+ TMessageBusSecureRequest(Args&&... args)
+ : TSecureRequestActor<
+ TMessageBusTabletRequest<TDerived, TTabletReplyEvent>,
+ TMessageBusSecureRequest<TMessageBusTabletRequest<TDerived, TTabletReplyEvent>>,
+ TMessageBusTabletRequest<TDerived, TTabletReplyEvent>>(std::forward<Args>(args)...)
+ {}
+};
+
+}
+}
diff --git a/ydb/core/client/server/msgbus_server.cpp b/ydb/core/client/server/msgbus_server.cpp
index dc0ba5bfb4d..8a4d8a3bbd5 100644
--- a/ydb/core/client/server/msgbus_server.cpp
+++ b/ydb/core/client/server/msgbus_server.cpp
@@ -2,8 +2,8 @@
#include <ydb/core/base/appdata.h>
#include <ydb/core/node_whiteboard/node_whiteboard.h>
#include "msgbus_server.h"
-#include "msgbus_server_tracer.h"
-#include "msgbus_http_server.h"
+#include "msgbus_server_tracer.h"
+#include "msgbus_http_server.h"
#include "grpc_server.h"
namespace NKikimr {
@@ -123,15 +123,15 @@ public:
MTYPE(TBusCmsRequest)
MTYPE(TBusChooseProxy)
MTYPE(TBusSqsRequest)
- MTYPE(TBusWhoAmI)
+ MTYPE(TBusWhoAmI)
MTYPE(TBusStreamRequest)
MTYPE(TBusS3ListingRequest)
MTYPE(TBusS3ListingResponse)
MTYPE(TBusInterconnectDebug)
MTYPE(TBusConsoleRequest)
- MTYPE(TBusResolveNode)
- MTYPE(TBusFillNode)
- MTYPE(TBusDrainNode)
+ MTYPE(TBusResolveNode)
+ MTYPE(TBusFillNode)
+ MTYPE(TBusDrainNode)
MTYPE(TBusTestShardControlRequest)
#undef MTYPE
}
@@ -330,17 +330,17 @@ THolder<TMessageBusSessionIdentHolder::TImpl> TBusMessageContext::TImplGRpc::Cre
return MakeHolder<TMessageBusSessionIdentHolder::TImplGRpc>(this);
}
-TMessageBusSessionIdentHolder::TMessageBusSessionIdentHolder()
-{}
-
+TMessageBusSessionIdentHolder::TMessageBusSessionIdentHolder()
+{}
+
TMessageBusSessionIdentHolder::TMessageBusSessionIdentHolder(TBusMessageContext &msg)
{
- InitSession(msg);
+ InitSession(msg);
}
TMessageBusSessionIdentHolder::~TMessageBusSessionIdentHolder()
{}
-
+
void TMessageBusSessionIdentHolder::InitSession(TBusMessageContext &msg) {
Impl = msg.CreateSessionIdentHolder();
}
@@ -361,80 +361,80 @@ void TMessageBusSessionIdentHolder::SendReplyMove(NBus::TBusMessageAutoPtr resp)
}
-void TBusMessageWatcher::NotifyForget() {
- if (MessageWatcher) {
- MessageWatcher->OnMessageDied(GetMessageId());
- MessageWatcher = nullptr;
+void TBusMessageWatcher::NotifyForget() {
+ if (MessageWatcher) {
+ MessageWatcher->OnMessageDied(GetMessageId());
+ MessageWatcher = nullptr;
}
}
-void TBusMessageWatcher::NotifyReply(NBus::TBusMessage *response) {
- if (MessageWatcher) {
- MessageWatcher->OnMessageReplied(GetMessageId(), response);
- MessageWatcher = nullptr;
- }
-}
-
-
-
-class TMessageBusMonitorActor : public TActorBootstrapped<TMessageBusMonitorActor> {
- struct TEvPrivate {
- enum EEv {
- EvUpdateMsgBusStats = EventSpaceBegin(TEvents::ES_PRIVATE),
- EvEnd
- };
-
- static_assert(EvEnd < EventSpaceEnd(TEvents::ES_PRIVATE), "expected EvEnd < EventSpaceEnd");
-
- struct TEvUpdateMsgBusStats : TEventLocal<TEvUpdateMsgBusStats, EvUpdateMsgBusStats> {};
- };
-
- constexpr static TDuration::TValue Interval = TDuration::Seconds(10).GetValue();
-
-public:
- TMessageBusMonitorActor(NBus::TBusServerSessionPtr session, const NBus::TBusServerSessionConfig &sessionConfig)
- : Session(session)
- , SessionConfig(sessionConfig)
- {}
-
+void TBusMessageWatcher::NotifyReply(NBus::TBusMessage *response) {
+ if (MessageWatcher) {
+ MessageWatcher->OnMessageReplied(GetMessageId(), response);
+ MessageWatcher = nullptr;
+ }
+}
+
+
+
+class TMessageBusMonitorActor : public TActorBootstrapped<TMessageBusMonitorActor> {
+ struct TEvPrivate {
+ enum EEv {
+ EvUpdateMsgBusStats = EventSpaceBegin(TEvents::ES_PRIVATE),
+ EvEnd
+ };
+
+ static_assert(EvEnd < EventSpaceEnd(TEvents::ES_PRIVATE), "expected EvEnd < EventSpaceEnd");
+
+ struct TEvUpdateMsgBusStats : TEventLocal<TEvUpdateMsgBusStats, EvUpdateMsgBusStats> {};
+ };
+
+ constexpr static TDuration::TValue Interval = TDuration::Seconds(10).GetValue();
+
+public:
+ TMessageBusMonitorActor(NBus::TBusServerSessionPtr session, const NBus::TBusServerSessionConfig &sessionConfig)
+ : Session(session)
+ , SessionConfig(sessionConfig)
+ {}
+
static constexpr NKikimrServices::TActivity::EType ActorActivityType() { return NKikimrServices::TActivity::MSGBUS_COMMON; }
-
- void Bootstrap(const TActorContext &ctx) {
- WhiteboardServiceId = NNodeWhiteboard::MakeNodeWhiteboardServiceId(ctx.SelfID.NodeId());
- ctx.Send(WhiteboardServiceId, new NNodeWhiteboard::TEvWhiteboard::TEvSystemStateAddEndpoint("mbus", Sprintf(":%d", Session->GetProto()->GetPort())));
+
+ void Bootstrap(const TActorContext &ctx) {
+ WhiteboardServiceId = NNodeWhiteboard::MakeNodeWhiteboardServiceId(ctx.SelfID.NodeId());
+ ctx.Send(WhiteboardServiceId, new NNodeWhiteboard::TEvWhiteboard::TEvSystemStateAddEndpoint("mbus", Sprintf(":%d", Session->GetProto()->GetPort())));
Become(&TMessageBusMonitorActor::StateWork, ctx, TDuration::MicroSeconds(Interval), new TEvPrivate::TEvUpdateMsgBusStats());
- }
-
-protected:
- void Handle(TEvPrivate::TEvUpdateMsgBusStats::TPtr, const TActorContext &ctx) {
- NKikimrWhiteboard::TSystemStateInfo systemStateInfo;
+ }
+
+protected:
+ void Handle(TEvPrivate::TEvUpdateMsgBusStats::TPtr, const TActorContext &ctx) {
+ NKikimrWhiteboard::TSystemStateInfo systemStateInfo;
auto inFlightPercent = SessionConfig.MaxInFlight > 0 ? Session->GetInFlight() * 100 / SessionConfig.MaxInFlight : 0;
- if (inFlightPercent < 75) {
- systemStateInfo.SetMessageBusState(NKikimrWhiteboard::EFlag::Green);
- } else
- if (inFlightPercent < 85) {
- systemStateInfo.SetMessageBusState(NKikimrWhiteboard::EFlag::Yellow);
- } else
- if (inFlightPercent < 95) {
- systemStateInfo.SetMessageBusState(NKikimrWhiteboard::EFlag::Orange);
- } else {
- systemStateInfo.SetMessageBusState(NKikimrWhiteboard::EFlag::Red);
- }
- ctx.Send(WhiteboardServiceId, new NNodeWhiteboard::TEvWhiteboard::TEvSystemStateUpdate(systemStateInfo));
+ if (inFlightPercent < 75) {
+ systemStateInfo.SetMessageBusState(NKikimrWhiteboard::EFlag::Green);
+ } else
+ if (inFlightPercent < 85) {
+ systemStateInfo.SetMessageBusState(NKikimrWhiteboard::EFlag::Yellow);
+ } else
+ if (inFlightPercent < 95) {
+ systemStateInfo.SetMessageBusState(NKikimrWhiteboard::EFlag::Orange);
+ } else {
+ systemStateInfo.SetMessageBusState(NKikimrWhiteboard::EFlag::Red);
+ }
+ ctx.Send(WhiteboardServiceId, new NNodeWhiteboard::TEvWhiteboard::TEvSystemStateUpdate(systemStateInfo));
ctx.Schedule(TDuration::MicroSeconds(Interval), new TEvPrivate::TEvUpdateMsgBusStats());
- }
-
- STFUNC(StateWork) {
- switch (ev->GetTypeRewrite()) {
- HFunc(TEvPrivate::TEvUpdateMsgBusStats, Handle);
- }
- }
-
+ }
+
+ STFUNC(StateWork) {
+ switch (ev->GetTypeRewrite()) {
+ HFunc(TEvPrivate::TEvUpdateMsgBusStats, Handle);
+ }
+ }
+
TActorId WhiteboardServiceId;
- NBus::TBusServerSessionPtr Session;
- const NBus::TBusServerSessionConfig &SessionConfig;
-};
-
+ NBus::TBusServerSessionPtr Session;
+ const NBus::TBusServerSessionConfig &SessionConfig;
+};
+
TMessageBusServer::TMessageBusServer(
const NBus::TBusServerSessionConfig &sessionConfig,
NBus::TBusMessageQueue *busQueue,
@@ -455,7 +455,7 @@ void TMessageBusServer::InitSession(TActorSystem *actorSystem, const TActorId &p
ActorSystem = actorSystem;
Proxy = proxy;
Session = NBus::TBusServerSession::Create(&Protocol, this, SessionConfig, BusQueue);
- HttpServer.Reset(CreateMessageBusHttpServer(actorSystem, this, Protocol, SessionConfig));
+ HttpServer.Reset(CreateMessageBusHttpServer(actorSystem, this, Protocol, SessionConfig));
Monitor = ActorSystem->Register(new TMessageBusMonitorActor(Session, SessionConfig), TMailboxType::HTSwap,
actorSystem->AppData<TAppData>()->UserPoolId);
}
@@ -472,18 +472,18 @@ void TMessageBusServer::RegisterMonPage(NMonitoring::TBusNgMonPage *busMonPage)
}
void TMessageBusServer::OnMessage(NBus::TOnMessageContext &msg) {
- TBusMessageContext messageContext(msg);
- OnMessage(messageContext);
-}
-
-void TMessageBusServer::OnMessage(TBusMessageContext &msg) {
+ TBusMessageContext messageContext(msg);
+ OnMessage(messageContext);
+}
+
+void TMessageBusServer::OnMessage(TBusMessageContext &msg) {
const ui32 msgType = msg.GetMessage()->GetHeader()->Type;
switch (msgType) {
case MTYPE_CLIENT_REQUEST:
return ClientProxyRequest<TEvBusProxy::TEvRequest>(msg);
case MTYPE_CLIENT_SCHEME_INITROOT:
- return ClientProxyRequest<TEvBusProxy::TEvInitRoot>(msg);
+ return ClientProxyRequest<TEvBusProxy::TEvInitRoot>(msg);
case MTYPE_CLIENT_BSADM:
return ClientActorRequest(CreateMessageBusBSAdm, msg);
case MTYPE_CLIENT_SCHEME_NAVIGATE:
@@ -491,19 +491,19 @@ void TMessageBusServer::OnMessage(TBusMessageContext &msg) {
case MTYPE_CLIENT_TYPES_REQUEST:
return GetTypes(msg);
case MTYPE_CLIENT_HIVE_CREATE_TABLET:
- case MTYPE_CLIENT_OLD_HIVE_CREATE_TABLET:
+ case MTYPE_CLIENT_OLD_HIVE_CREATE_TABLET:
return ClientActorRequest(CreateMessageBusHiveCreateTablet, msg);
case MTYPE_CLIENT_LOCAL_ENUMERATE_TABLETS:
- case MTYPE_CLIENT_OLD_LOCAL_ENUMERATE_TABLETS:
+ case MTYPE_CLIENT_OLD_LOCAL_ENUMERATE_TABLETS:
return ClientActorRequest(CreateMessageBusLocalEnumerateTablets, msg);
case MTYPE_CLIENT_KEYVALUE:
- case MTYPE_CLIENT_OLD_KEYVALUE:
+ case MTYPE_CLIENT_OLD_KEYVALUE:
return ClientActorRequest(CreateMessageBusKeyValue, msg);
case MTYPE_CLIENT_PERSQUEUE:
return ClientProxyRequest<TEvBusProxy::TEvPersQueue>(msg);
case MTYPE_CLIENT_CHOOSE_PROXY:
return ClientActorRequest(CreateMessageBusChooseProxy, msg);
- case MTYPE_CLIENT_TABLET_STATE_REQUEST:
+ case MTYPE_CLIENT_TABLET_STATE_REQUEST:
return ClientActorRequest(CreateMessageBusTabletStateRequest, msg);
case MTYPE_CLIENT_TABLET_COUNTERS_REQUEST:
return ClientActorRequest(CreateMessageBusTabletCountersRequest, msg);
@@ -511,39 +511,39 @@ void TMessageBusServer::OnMessage(TBusMessageContext &msg) {
return ClientActorRequest(CreateMessageBusLocalMKQL, msg);
case MTYPE_CLIENT_LOCAL_SCHEME_TX:
return ClientActorRequest(CreateMessageBusLocalSchemeTx, msg);
- case MTYPE_CLIENT_TABLET_KILL_REQUEST:
+ case MTYPE_CLIENT_TABLET_KILL_REQUEST:
return ClientActorRequest(CreateMessageBusTabletKillRequest, msg);
- case MTYPE_CLIENT_FLAT_TX_REQUEST:
+ case MTYPE_CLIENT_FLAT_TX_REQUEST:
return ClientProxyRequest<TEvBusProxy::TEvFlatTxRequest>(msg);
- case MTYPE_CLIENT_FLAT_TX_STATUS_REQUEST:
+ case MTYPE_CLIENT_FLAT_TX_STATUS_REQUEST:
return ClientActorRequest(CreateMessageBusSchemeOperationStatus, msg);
- case MTYPE_CLIENT_FLAT_DESCRIBE_REQUEST:
- case MTYPE_CLIENT_OLD_FLAT_DESCRIBE_REQUEST:
+ case MTYPE_CLIENT_FLAT_DESCRIBE_REQUEST:
+ case MTYPE_CLIENT_OLD_FLAT_DESCRIBE_REQUEST:
return ClientProxyRequest<TEvBusProxy::TEvFlatDescribeRequest>(msg);
case MTYPE_CLIENT_LOAD_REQUEST:
return ClientActorRequest(CreateMessageBusBlobStorageLoadRequest, msg);
case MTYPE_CLIENT_GET_REQUEST:
return ClientActorRequest(CreateMessageBusBlobStorageGetRequest, msg);
- case MTYPE_CLIENT_DB_SCHEMA:
+ case MTYPE_CLIENT_DB_SCHEMA:
return ClientProxyRequest<TEvBusProxy::TEvDbSchema>(msg);
- case MTYPE_CLIENT_DB_OPERATION:
+ case MTYPE_CLIENT_DB_OPERATION:
return ClientProxyRequest<TEvBusProxy::TEvDbOperation>(msg);
- case MTYPE_CLIENT_DB_BATCH:
+ case MTYPE_CLIENT_DB_BATCH:
return ClientProxyRequest<TEvBusProxy::TEvDbBatch>(msg);
case MTYPE_CLIENT_BLOB_STORAGE_CONFIG_REQUEST:
return ClientActorRequest(CreateMessageBusBlobStorageConfig, msg);
- case MTYPE_CLIENT_DRAIN_NODE:
- return ClientActorRequest(CreateMessageBusDrainNode, msg);
- case MTYPE_CLIENT_FILL_NODE:
- return ClientActorRequest(CreateMessageBusFillNode, msg);
- case MTYPE_CLIENT_RESOLVE_NODE:
- return ClientActorRequest(CreateMessageBusResolveNode, msg);
+ case MTYPE_CLIENT_DRAIN_NODE:
+ return ClientActorRequest(CreateMessageBusDrainNode, msg);
+ case MTYPE_CLIENT_FILL_NODE:
+ return ClientActorRequest(CreateMessageBusFillNode, msg);
+ case MTYPE_CLIENT_RESOLVE_NODE:
+ return ClientActorRequest(CreateMessageBusResolveNode, msg);
case MTYPE_CLIENT_CMS_REQUEST:
return ClientActorRequest(CreateMessageBusCmsRequest, msg);
case MTYPE_CLIENT_SQS_REQUEST:
return ClientActorRequest(CreateMessageBusSqsRequest, msg);
- case MTYPE_CLIENT_WHOAMI:
- return ClientActorRequest(CreateMessageBusWhoAmI, msg);
+ case MTYPE_CLIENT_WHOAMI:
+ return ClientActorRequest(CreateMessageBusWhoAmI, msg);
case MTYPE_CLIENT_S3_LISTING_REQUEST:
return ClientActorRequest(CreateMessageBusS3ListingRequest, msg);
case MTYPE_CLIENT_INTERCONNECT_DEBUG:
@@ -574,17 +574,17 @@ void TMessageBusServer::ClientProxyRequest(TBusMessageContext &msg) {
if (Proxy)
ActorSystem->Send(Proxy, new TEv(msg));
else
- msg.SendReplyMove(new TBusResponseStatus(MSTATUS_ERROR, "MessageBus proxy is not available"));
-}
-
+ msg.SendReplyMove(new TBusResponseStatus(MSTATUS_ERROR, "MessageBus proxy is not available"));
+}
+
void TMessageBusServer::ClientActorRequest(ActorCreationFunc func, TBusMessageContext &msg) {
if (IActor *x = func(msg))
ActorSystem->Register(x, TMailboxType::HTSwap, ActorSystem->AppData<TAppData>()->UserPoolId);
else
msg.SendReplyMove(new TBusResponseStatus(MSTATUS_ERROR));
-}
-
-void TMessageBusServer::GetTypes(TBusMessageContext &msg) {
+}
+
+void TMessageBusServer::GetTypes(TBusMessageContext &msg) {
if (IActor *x = CreateMessageBusGetTypes(msg)) {
ActorSystem->Register(x, TMailboxType::HTSwap, ActorSystem->AppData<TAppData>()->UserPoolId);
} else {
@@ -594,7 +594,7 @@ void TMessageBusServer::GetTypes(TBusMessageContext &msg) {
}
}
-void TMessageBusServer::UnknownMessage(TBusMessageContext &msg) {
+void TMessageBusServer::UnknownMessage(TBusMessageContext &msg) {
msg.SendReplyMove(new TBusResponseStatus(MSTATUS_UNKNOWN, "undocumented error 9"));
}
@@ -602,10 +602,10 @@ IActor* TMessageBusServer::CreateProxy() {
return CreateMessageBusServerProxy(this, PQReadSessionsInfoWorkerFactory);
}
-IActor* TMessageBusServer::CreateMessageBusTraceService() {
- return nullptr;
-}
-
+IActor* TMessageBusServer::CreateMessageBusTraceService() {
+ return nullptr;
+}
+
IMessageBusServer* CreateMsgBusServer(
NBus::TBusMessageQueue *queue,
const NBus::TBusServerSessionConfig &config,
diff --git a/ydb/core/client/server/msgbus_server.h b/ydb/core/client/server/msgbus_server.h
index 747d22410d1..3d40fc90017 100644
--- a/ydb/core/client/server/msgbus_server.h
+++ b/ydb/core/client/server/msgbus_server.h
@@ -3,7 +3,7 @@
#include <library/cpp/actors/core/actor_bootstrapped.h>
#include <ydb/public/lib/base/defs.h>
#include <ydb/public/lib/base/msgbus.h>
-#include "msgbus_http_server.h"
+#include "msgbus_http_server.h"
#include "msgbus_server_pq_metacache.h"
namespace NMonitoring {
@@ -18,25 +18,25 @@ namespace NGRpcProxy {
namespace NMsgBusProxy {
-class IMessageWatcher {
-public:
- virtual ~IMessageWatcher() {}
- virtual void OnMessageDied(NBus::TBusKey id) = 0;
- virtual void OnMessageReplied(NBus::TBusKey id, NBus::TBusMessage *response) = 0;
-};
-
-class TBusMessageWatcher {
- IMessageWatcher *MessageWatcher;
-
-protected:
- TBusMessageWatcher(IMessageWatcher *messageWatcher = nullptr) : MessageWatcher(messageWatcher) {}
- virtual ~TBusMessageWatcher() {}
- void NotifyForget();
- void NotifyReply(NBus::TBusMessage *response);
- void Swap(TBusMessageWatcher &watcher) { std::swap(MessageWatcher, watcher.MessageWatcher); }
- virtual NBus::TBusKey GetMessageId() = 0;
-};
-
+class IMessageWatcher {
+public:
+ virtual ~IMessageWatcher() {}
+ virtual void OnMessageDied(NBus::TBusKey id) = 0;
+ virtual void OnMessageReplied(NBus::TBusKey id, NBus::TBusMessage *response) = 0;
+};
+
+class TBusMessageWatcher {
+ IMessageWatcher *MessageWatcher;
+
+protected:
+ TBusMessageWatcher(IMessageWatcher *messageWatcher = nullptr) : MessageWatcher(messageWatcher) {}
+ virtual ~TBusMessageWatcher() {}
+ void NotifyForget();
+ void NotifyReply(NBus::TBusMessage *response);
+ void Swap(TBusMessageWatcher &watcher) { std::swap(MessageWatcher, watcher.MessageWatcher); }
+ virtual NBus::TBusKey GetMessageId() = 0;
+};
+
class TBusMessageContext;
class TMessageBusSessionIdentHolder {
@@ -71,13 +71,13 @@ class TBusMessageContext {
class TImplMessageBus;
class TImplGRpc;
-public:
+public:
TBusMessageContext();
TBusMessageContext(const TBusMessageContext& other);
- TBusMessageContext(NBus::TOnMessageContext &messageContext, IMessageWatcher *messageWatcher = nullptr);
+ TBusMessageContext(NBus::TOnMessageContext &messageContext, IMessageWatcher *messageWatcher = nullptr);
TBusMessageContext(NGRpcProxy::IRequestContext *requestContext, int type);
- ~TBusMessageContext();
-
+ ~TBusMessageContext();
+
TBusMessageContext& operator =(TBusMessageContext other);
NBus::TBusMessage* GetMessage();
@@ -88,19 +88,19 @@ public:
private:
friend class TMessageBusSessionIdentHolder;
THolder<TMessageBusSessionIdentHolder::TImpl> CreateSessionIdentHolder();
-};
-
+};
+
struct TEvBusProxy {
enum EEv {
EvRequest = EventSpaceBegin(TKikimrEvents::ES_PROXY_BUS),
EvNavigate,
- EvFlatTxRequest,
- EvFlatDescribeRequest,
+ EvFlatTxRequest,
+ EvFlatDescribeRequest,
EvPersQueue,
- EvDbSchema,
- EvDbOperation,
- EvDbBatch,
- EvInitRoot,
+ EvDbSchema,
+ EvDbOperation,
+ EvDbBatch,
+ EvInitRoot,
EvChooseProxy,
EvStreamIsReadyNotUsed = EvRequest + 512,
@@ -111,36 +111,36 @@ struct TEvBusProxy {
template<EEv EvId>
struct TEvMsgBusRequest : public TEventLocal<TEvMsgBusRequest<EvId>, EvId> {
- TBusMessageContext MsgContext;
+ TBusMessageContext MsgContext;
- TEvMsgBusRequest(TBusMessageContext &msg) {
+ TEvMsgBusRequest(TBusMessageContext &msg) {
MsgContext.Swap(msg);
}
};
typedef TEvMsgBusRequest<EvRequest> TEvRequest;
typedef TEvMsgBusRequest<EvNavigate> TEvNavigate;
- typedef TEvMsgBusRequest<EvFlatTxRequest> TEvFlatTxRequest;
- typedef TEvMsgBusRequest<EvFlatDescribeRequest> TEvFlatDescribeRequest;
+ typedef TEvMsgBusRequest<EvFlatTxRequest> TEvFlatTxRequest;
+ typedef TEvMsgBusRequest<EvFlatDescribeRequest> TEvFlatDescribeRequest;
typedef TEvMsgBusRequest<EvPersQueue> TEvPersQueue;
typedef TEvMsgBusRequest<EvChooseProxy> TEvChooseProxy;
- typedef TEvMsgBusRequest<EvDbSchema> TEvDbSchema;
- typedef TEvMsgBusRequest<EvDbOperation> TEvDbOperation;
- typedef TEvMsgBusRequest<EvDbBatch> TEvDbBatch;
- typedef TEvMsgBusRequest<EvInitRoot> TEvInitRoot;
+ typedef TEvMsgBusRequest<EvDbSchema> TEvDbSchema;
+ typedef TEvMsgBusRequest<EvDbOperation> TEvDbOperation;
+ typedef TEvMsgBusRequest<EvDbBatch> TEvDbBatch;
+ typedef TEvMsgBusRequest<EvInitRoot> TEvInitRoot;
};
class TMessageBusServer : public IMessageBusServer, public NBus::IBusServerHandler {
const NBus::TBusServerSessionConfig &SessionConfig;
NBus::TBusMessageQueuePtr BusQueue;
- NBus::TBusServerSessionPtr Session;
+ NBus::TBusServerSessionPtr Session;
TActorId Proxy;
TActorId Monitor;
std::shared_ptr<IPersQueueGetReadSessionsInfoWorkerFactory> PQReadSessionsInfoWorkerFactory;
-protected:
+protected:
TProtocol Protocol;
TActorSystem *ActorSystem = nullptr;
- TIntrusivePtr<IMessageBusHttpServer> HttpServer;
+ TIntrusivePtr<IMessageBusHttpServer> HttpServer;
public:
TMessageBusServer(
const NBus::TBusServerSessionConfig &sessionConfig,
@@ -154,17 +154,17 @@ public:
void ShutdownSession();
void RegisterMonPage(NMonitoring::TBusNgMonPage *busMonPage);
-
-protected:
- void OnMessage(NBus::TOnMessageContext &msg) override;
- void OnMessage(TBusMessageContext &msg);
- IActor* CreateMessageBusTraceService() override;
+
+protected:
+ void OnMessage(NBus::TOnMessageContext &msg) override;
+ void OnMessage(TBusMessageContext &msg);
+ IActor* CreateMessageBusTraceService() override;
private:
IActor* CreateProxy() override;
void OnError(TAutoPtr<NBus::TBusMessage> message, NBus::EMessageStatus status) override;
- void GetTypes(TBusMessageContext &msg);
- void UnknownMessage(TBusMessageContext &msg);
+ void GetTypes(TBusMessageContext &msg);
+ void UnknownMessage(TBusMessageContext &msg);
template<typename TEv>
void ClientProxyRequest(TBusMessageContext &msg);
@@ -173,105 +173,105 @@ private:
void ClientActorRequest(ActorCreationFunc func, TBusMessageContext &msg);
};
-template <typename TProto>
-void CopyProtobufsByFieldName(TProto& protoTo, const TProto& protoFrom) {
- using namespace ::google::protobuf;
- static_assert(std::is_base_of<Message, TProto>::value, "protoTo/protoFrom should be a subclass of protobuf::Message");
- protoTo.CopyFrom(protoFrom);
-}
-
-template <typename TProtoTo, typename TProtoFrom>
-void CopyProtobufsByFieldName(TProtoTo& protoTo, const TProtoFrom& protoFrom) {
- using namespace ::google::protobuf;
- static_assert(std::is_base_of<Message, TProtoTo>::value, "protoTo should be a subclass of protobuf::Message");
- static_assert(std::is_base_of<Message, TProtoFrom>::value, "protoFrom should be a subclass of protobuf::Message");
- const Descriptor& descriptorTo = *protoTo.GetDescriptor();
- const Reflection& reflectionTo = *protoTo.GetReflection();
- const Reflection& reflectionFrom = *protoFrom.GetReflection();
+template <typename TProto>
+void CopyProtobufsByFieldName(TProto& protoTo, const TProto& protoFrom) {
+ using namespace ::google::protobuf;
+ static_assert(std::is_base_of<Message, TProto>::value, "protoTo/protoFrom should be a subclass of protobuf::Message");
+ protoTo.CopyFrom(protoFrom);
+}
+
+template <typename TProtoTo, typename TProtoFrom>
+void CopyProtobufsByFieldName(TProtoTo& protoTo, const TProtoFrom& protoFrom) {
+ using namespace ::google::protobuf;
+ static_assert(std::is_base_of<Message, TProtoTo>::value, "protoTo should be a subclass of protobuf::Message");
+ static_assert(std::is_base_of<Message, TProtoFrom>::value, "protoFrom should be a subclass of protobuf::Message");
+ const Descriptor& descriptorTo = *protoTo.GetDescriptor();
+ const Reflection& reflectionTo = *protoTo.GetReflection();
+ const Reflection& reflectionFrom = *protoFrom.GetReflection();
std::vector<const FieldDescriptor*> fields;
- protoTo.Clear();
- reflectionFrom.ListFields(protoFrom, &fields);
- for (const FieldDescriptor* fieldFrom : fields) {
- const auto& name = fieldFrom->name();
- const FieldDescriptor* fieldTo = descriptorTo.FindFieldByName(name);
- Y_VERIFY(fieldTo != nullptr, "name=%s", name.c_str());
- if (fieldTo != nullptr) {
- FieldDescriptor::CppType type = fieldFrom->cpp_type();
- if (fieldFrom->is_repeated()) {
- int size = reflectionFrom.FieldSize(protoFrom, fieldFrom);
-
- for (int i = 0; i < size; ++i) {
- switch (type) {
- case FieldDescriptor::CPPTYPE_INT32:
- reflectionTo.AddInt32(&protoTo, fieldTo, reflectionFrom.GetRepeatedInt32(protoFrom, fieldFrom, i));
- break;
- case FieldDescriptor::CPPTYPE_INT64:
- reflectionTo.AddInt64(&protoTo, fieldTo, reflectionFrom.GetRepeatedInt64(protoFrom, fieldFrom, i));
- break;
- case FieldDescriptor::CPPTYPE_UINT32:
- reflectionTo.AddUInt32(&protoTo, fieldTo, reflectionFrom.GetRepeatedUInt32(protoFrom, fieldFrom, i));
- break;
- case FieldDescriptor::CPPTYPE_UINT64:
- reflectionTo.AddUInt64(&protoTo, fieldTo, reflectionFrom.GetRepeatedUInt64(protoFrom, fieldFrom, i));
- break;
- case FieldDescriptor::CPPTYPE_DOUBLE:
- reflectionTo.AddDouble(&protoTo, fieldTo, reflectionFrom.GetRepeatedDouble(protoFrom, fieldFrom, i));
- break;
- case FieldDescriptor::CPPTYPE_FLOAT:
- reflectionTo.AddFloat(&protoTo, fieldTo, reflectionFrom.GetRepeatedFloat(protoFrom, fieldFrom, i));
- break;
- case FieldDescriptor::CPPTYPE_BOOL:
- reflectionTo.AddBool(&protoTo, fieldTo, reflectionFrom.GetRepeatedBool(protoFrom, fieldFrom, i));
- break;
- case FieldDescriptor::CPPTYPE_ENUM:
- reflectionTo.AddEnum(&protoTo, fieldTo, reflectionFrom.GetRepeatedEnum(protoFrom, fieldFrom, i));
- break;
- case FieldDescriptor::CPPTYPE_STRING:
- reflectionTo.AddString(&protoTo, fieldTo, reflectionFrom.GetRepeatedString(protoFrom, fieldFrom, i));
- break;
- case FieldDescriptor::CPPTYPE_MESSAGE:
- reflectionTo.AddMessage(&protoTo, fieldTo)->CopyFrom(reflectionFrom.GetRepeatedMessage(protoFrom, fieldFrom, i));
- break;
- }
- }
- } else {
- switch (type) {
- case FieldDescriptor::CPPTYPE_INT32:
- reflectionTo.SetInt32(&protoTo, fieldTo, reflectionFrom.GetInt32(protoFrom, fieldFrom));
- break;
- case FieldDescriptor::CPPTYPE_INT64:
- reflectionTo.SetInt64(&protoTo, fieldTo, reflectionFrom.GetInt64(protoFrom, fieldFrom));
- break;
- case FieldDescriptor::CPPTYPE_UINT32:
- reflectionTo.SetUInt32(&protoTo, fieldTo, reflectionFrom.GetUInt32(protoFrom, fieldFrom));
- break;
- case FieldDescriptor::CPPTYPE_UINT64:
- reflectionTo.SetUInt64(&protoTo, fieldTo, reflectionFrom.GetUInt64(protoFrom, fieldFrom));
- break;
- case FieldDescriptor::CPPTYPE_DOUBLE:
- reflectionTo.SetDouble(&protoTo, fieldTo, reflectionFrom.GetDouble(protoFrom, fieldFrom));
- break;
- case FieldDescriptor::CPPTYPE_FLOAT:
- reflectionTo.SetFloat(&protoTo, fieldTo, reflectionFrom.GetFloat(protoFrom, fieldFrom));
- break;
- case FieldDescriptor::CPPTYPE_BOOL:
- reflectionTo.SetBool(&protoTo, fieldTo, reflectionFrom.GetBool(protoFrom, fieldFrom));
- break;
- case FieldDescriptor::CPPTYPE_ENUM:
- reflectionTo.SetEnum(&protoTo, fieldTo, reflectionFrom.GetEnum(protoFrom, fieldFrom));
- break;
- case FieldDescriptor::CPPTYPE_STRING:
- reflectionTo.SetString(&protoTo, fieldTo, reflectionFrom.GetString(protoFrom, fieldFrom));
- break;
- case FieldDescriptor::CPPTYPE_MESSAGE:
- reflectionTo.MutableMessage(&protoTo, fieldTo)->CopyFrom(reflectionFrom.GetMessage(protoFrom, fieldFrom));
- break;
- }
- }
- }
- }
-}
-
+ protoTo.Clear();
+ reflectionFrom.ListFields(protoFrom, &fields);
+ for (const FieldDescriptor* fieldFrom : fields) {
+ const auto& name = fieldFrom->name();
+ const FieldDescriptor* fieldTo = descriptorTo.FindFieldByName(name);
+ Y_VERIFY(fieldTo != nullptr, "name=%s", name.c_str());
+ if (fieldTo != nullptr) {
+ FieldDescriptor::CppType type = fieldFrom->cpp_type();
+ if (fieldFrom->is_repeated()) {
+ int size = reflectionFrom.FieldSize(protoFrom, fieldFrom);
+
+ for (int i = 0; i < size; ++i) {
+ switch (type) {
+ case FieldDescriptor::CPPTYPE_INT32:
+ reflectionTo.AddInt32(&protoTo, fieldTo, reflectionFrom.GetRepeatedInt32(protoFrom, fieldFrom, i));
+ break;
+ case FieldDescriptor::CPPTYPE_INT64:
+ reflectionTo.AddInt64(&protoTo, fieldTo, reflectionFrom.GetRepeatedInt64(protoFrom, fieldFrom, i));
+ break;
+ case FieldDescriptor::CPPTYPE_UINT32:
+ reflectionTo.AddUInt32(&protoTo, fieldTo, reflectionFrom.GetRepeatedUInt32(protoFrom, fieldFrom, i));
+ break;
+ case FieldDescriptor::CPPTYPE_UINT64:
+ reflectionTo.AddUInt64(&protoTo, fieldTo, reflectionFrom.GetRepeatedUInt64(protoFrom, fieldFrom, i));
+ break;
+ case FieldDescriptor::CPPTYPE_DOUBLE:
+ reflectionTo.AddDouble(&protoTo, fieldTo, reflectionFrom.GetRepeatedDouble(protoFrom, fieldFrom, i));
+ break;
+ case FieldDescriptor::CPPTYPE_FLOAT:
+ reflectionTo.AddFloat(&protoTo, fieldTo, reflectionFrom.GetRepeatedFloat(protoFrom, fieldFrom, i));
+ break;
+ case FieldDescriptor::CPPTYPE_BOOL:
+ reflectionTo.AddBool(&protoTo, fieldTo, reflectionFrom.GetRepeatedBool(protoFrom, fieldFrom, i));
+ break;
+ case FieldDescriptor::CPPTYPE_ENUM:
+ reflectionTo.AddEnum(&protoTo, fieldTo, reflectionFrom.GetRepeatedEnum(protoFrom, fieldFrom, i));
+ break;
+ case FieldDescriptor::CPPTYPE_STRING:
+ reflectionTo.AddString(&protoTo, fieldTo, reflectionFrom.GetRepeatedString(protoFrom, fieldFrom, i));
+ break;
+ case FieldDescriptor::CPPTYPE_MESSAGE:
+ reflectionTo.AddMessage(&protoTo, fieldTo)->CopyFrom(reflectionFrom.GetRepeatedMessage(protoFrom, fieldFrom, i));
+ break;
+ }
+ }
+ } else {
+ switch (type) {
+ case FieldDescriptor::CPPTYPE_INT32:
+ reflectionTo.SetInt32(&protoTo, fieldTo, reflectionFrom.GetInt32(protoFrom, fieldFrom));
+ break;
+ case FieldDescriptor::CPPTYPE_INT64:
+ reflectionTo.SetInt64(&protoTo, fieldTo, reflectionFrom.GetInt64(protoFrom, fieldFrom));
+ break;
+ case FieldDescriptor::CPPTYPE_UINT32:
+ reflectionTo.SetUInt32(&protoTo, fieldTo, reflectionFrom.GetUInt32(protoFrom, fieldFrom));
+ break;
+ case FieldDescriptor::CPPTYPE_UINT64:
+ reflectionTo.SetUInt64(&protoTo, fieldTo, reflectionFrom.GetUInt64(protoFrom, fieldFrom));
+ break;
+ case FieldDescriptor::CPPTYPE_DOUBLE:
+ reflectionTo.SetDouble(&protoTo, fieldTo, reflectionFrom.GetDouble(protoFrom, fieldFrom));
+ break;
+ case FieldDescriptor::CPPTYPE_FLOAT:
+ reflectionTo.SetFloat(&protoTo, fieldTo, reflectionFrom.GetFloat(protoFrom, fieldFrom));
+ break;
+ case FieldDescriptor::CPPTYPE_BOOL:
+ reflectionTo.SetBool(&protoTo, fieldTo, reflectionFrom.GetBool(protoFrom, fieldFrom));
+ break;
+ case FieldDescriptor::CPPTYPE_ENUM:
+ reflectionTo.SetEnum(&protoTo, fieldTo, reflectionFrom.GetEnum(protoFrom, fieldFrom));
+ break;
+ case FieldDescriptor::CPPTYPE_STRING:
+ reflectionTo.SetString(&protoTo, fieldTo, reflectionFrom.GetString(protoFrom, fieldFrom));
+ break;
+ case FieldDescriptor::CPPTYPE_MESSAGE:
+ reflectionTo.MutableMessage(&protoTo, fieldTo)->CopyFrom(reflectionFrom.GetMessage(protoFrom, fieldFrom));
+ break;
+ }
+ }
+ }
+ }
+}
+
class IPersQueueGetReadSessionsInfoWorkerFactory;
IActor* CreateMessageBusServerProxy(
@@ -283,28 +283,28 @@ IActor* CreateMessageBusServerProxy(
IActor* CreateMessageBusTabletCountersRequest(TBusMessageContext &msg);
IActor* CreateMessageBusLocalMKQL(TBusMessageContext &msg);
IActor* CreateMessageBusLocalSchemeTx(TBusMessageContext &msg);
-IActor* CreateMessageBusSchemeInitRoot(TBusMessageContext &msg);
-IActor* CreateMessageBusBSAdm(TBusMessageContext &msg);
-IActor* CreateMessageBusGetTypes(TBusMessageContext &msg);
-IActor* CreateMessageBusHiveCreateTablet(TBusMessageContext &msg);
-IActor* CreateMessageBusLocalEnumerateTablets(TBusMessageContext &msg);
-IActor* CreateMessageBusKeyValue(TBusMessageContext &msg);
+IActor* CreateMessageBusSchemeInitRoot(TBusMessageContext &msg);
+IActor* CreateMessageBusBSAdm(TBusMessageContext &msg);
+IActor* CreateMessageBusGetTypes(TBusMessageContext &msg);
+IActor* CreateMessageBusHiveCreateTablet(TBusMessageContext &msg);
+IActor* CreateMessageBusLocalEnumerateTablets(TBusMessageContext &msg);
+IActor* CreateMessageBusKeyValue(TBusMessageContext &msg);
IActor* CreateMessageBusPersQueue(TBusMessageContext &msg);
IActor* CreateMessageBusChooseProxy(TBusMessageContext &msg);
-IActor* CreateMessageBusTabletStateRequest(TBusMessageContext &msg);
-IActor* CreateMessageBusTabletKillRequest(TBusMessageContext &msg);
+IActor* CreateMessageBusTabletStateRequest(TBusMessageContext &msg);
+IActor* CreateMessageBusTabletKillRequest(TBusMessageContext &msg);
IActor* CreateMessageBusSchemeOperationStatus(TBusMessageContext &msg);
IActor* CreateMessageBusBlobStorageLoadRequest(TBusMessageContext &msg);
IActor* CreateMessageBusBlobStorageGetRequest(TBusMessageContext &msg);
-IActor* CreateMessageBusHiveLookupTablet(TBusMessageContext &msg);
+IActor* CreateMessageBusHiveLookupTablet(TBusMessageContext &msg);
IActor* CreateMessageBusBlobStorageConfig(TBusMessageContext &msg);
-IActor* CreateMessageBusDrainNode(TBusMessageContext &msg);
-IActor* CreateMessageBusFillNode(TBusMessageContext &msg);
-IActor* CreateMessageBusResolveNode(TBusMessageContext &msg);
+IActor* CreateMessageBusDrainNode(TBusMessageContext &msg);
+IActor* CreateMessageBusFillNode(TBusMessageContext &msg);
+IActor* CreateMessageBusResolveNode(TBusMessageContext &msg);
IActor* CreateMessageBusRegisterNode(TBusMessageContext &msg);
IActor* CreateMessageBusCmsRequest(TBusMessageContext &msg);
IActor* CreateMessageBusSqsRequest(TBusMessageContext &msg);
-IActor* CreateMessageBusWhoAmI(TBusMessageContext &msg);
+IActor* CreateMessageBusWhoAmI(TBusMessageContext &msg);
IActor* CreateMessageBusS3ListingRequest(TBusMessageContext& msg);
IActor* CreateMessageBusInterconnectDebug(TBusMessageContext& msg);
IActor* CreateMessageBusConsoleRequest(TBusMessageContext &msg);
diff --git a/ydb/core/client/server/msgbus_server_cms.cpp b/ydb/core/client/server/msgbus_server_cms.cpp
index 38123007c5b..53ada2a3fad 100644
--- a/ydb/core/client/server/msgbus_server_cms.cpp
+++ b/ydb/core/client/server/msgbus_server_cms.cpp
@@ -1,5 +1,5 @@
-#include "msgbus_server_request.h"
-#include "msgbus_securereq.h"
+#include "msgbus_server_request.h"
+#include "msgbus_securereq.h"
#include <library/cpp/actors/core/actor_bootstrapped.h>
#include <library/cpp/actors/core/hfunc.h>
@@ -16,10 +16,10 @@ using namespace NCms;
namespace {
-class TCmsRequestActor : public TMessageBusSecureRequest<TMessageBusServerRequestBase<TCmsRequestActor>>
+class TCmsRequestActor : public TMessageBusSecureRequest<TMessageBusServerRequestBase<TCmsRequestActor>>
{
using TActorBase = TActorBootstrapped<TCmsRequestActor>;
- using TBase = TMessageBusSecureRequest<TMessageBusServerRequestBase<TCmsRequestActor>>;
+ using TBase = TMessageBusSecureRequest<TMessageBusServerRequestBase<TCmsRequestActor>>;
public:
static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
@@ -27,10 +27,10 @@ public:
}
TCmsRequestActor(NKikimrClient::TCmsRequest &request, NMsgBusProxy::TBusMessageContext &msg)
- : TBase(msg)
+ : TBase(msg)
, Request(request)
{
- TBase::SetSecurityToken(request.GetSecurityToken());
+ TBase::SetSecurityToken(request.GetSecurityToken());
}
void Bootstrap(const TActorContext &ctx)
@@ -55,14 +55,14 @@ public:
StateStorageGroup = dinfo->GetDefaultStateStorageGroup(domain->DomainUid);
}
- SendRequest(ctx);
- Become(&TCmsRequestActor::MainState);
+ SendRequest(ctx);
+ Become(&TCmsRequestActor::MainState);
}
void SendRequest(const TActorContext &ctx)
{
NTabletPipe::TClientConfig pipeConfig;
- pipeConfig.RetryPolicy = {.RetryLimitCount = 10};
+ pipeConfig.RetryPolicy = {.RetryLimitCount = 10};
auto pipe = NTabletPipe::CreateClient(ctx.SelfID, MakeCmsID(StateStorageGroup), pipeConfig);
CmsPipe = ctx.RegisterWithSameMailbox(pipe);
@@ -118,7 +118,7 @@ public:
TAutoPtr<TEvCms::TEvResetMarkerRequest> request
= new TEvCms::TEvResetMarkerRequest;
request->Record.CopyFrom(Request.GetResetMarkerRequest());
- request->Record.SetUserToken(TBase::GetSerializedToken());
+ request->Record.SetUserToken(TBase::GetSerializedToken());
NTabletPipe::SendData(ctx, CmsPipe, request.Release());
} else if (Request.HasSetConfigRequest()) {
TAutoPtr<TEvCms::TEvSetConfigRequest> request
@@ -129,7 +129,7 @@ public:
TAutoPtr<TEvCms::TEvSetMarkerRequest> request
= new TEvCms::TEvSetMarkerRequest;
request->Record.CopyFrom(Request.GetSetMarkerRequest());
- request->Record.SetUserToken(TBase::GetSerializedToken());
+ request->Record.SetUserToken(TBase::GetSerializedToken());
NTabletPipe::SendData(ctx, CmsPipe, request.Release());
} else {
ReplyWithErrorAndDie("Unknown CMS request", ctx);
@@ -238,7 +238,7 @@ public:
{
if (CmsPipe)
NTabletPipe::CloseClient(ctx, CmsPipe);
- TBase::Die(ctx);
+ TBase::Die(ctx);
}
void SendReplyAndDie(const TActorContext &ctx)
diff --git a/ydb/core/client/server/msgbus_server_console.cpp b/ydb/core/client/server/msgbus_server_console.cpp
index 1ee3e3f26d4..66bc0b02ebe 100644
--- a/ydb/core/client/server/msgbus_server_console.cpp
+++ b/ydb/core/client/server/msgbus_server_console.cpp
@@ -1,5 +1,5 @@
-#include "msgbus_server_request.h"
-#include "msgbus_securereq.h"
+#include "msgbus_server_request.h"
+#include "msgbus_securereq.h"
#include <library/cpp/actors/core/actor_bootstrapped.h>
#include <library/cpp/actors/core/hfunc.h>
@@ -16,10 +16,10 @@ using namespace NConsole;
namespace {
-class TConsoleRequestActor : public TMessageBusSecureRequest<TMessageBusServerRequestBase<TConsoleRequestActor>>
+class TConsoleRequestActor : public TMessageBusSecureRequest<TMessageBusServerRequestBase<TConsoleRequestActor>>
{
using TActorBase = TActorBootstrapped<TConsoleRequestActor>;
- using TBase = TMessageBusSecureRequest<TMessageBusServerRequestBase<TConsoleRequestActor>>;
+ using TBase = TMessageBusSecureRequest<TMessageBusServerRequestBase<TConsoleRequestActor>>;
public:
static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
@@ -27,11 +27,11 @@ public:
}
TConsoleRequestActor(NKikimrClient::TConsoleRequest &request, NMsgBusProxy::TBusMessageContext &msg)
- : TBase(msg)
+ : TBase(msg)
, Request(request)
{
- TBase::SetSecurityToken(request.GetSecurityToken());
- TBase::SetRequireAdminAccess(true);
+ TBase::SetSecurityToken(request.GetSecurityToken());
+ TBase::SetRequireAdminAccess(true);
}
void Bootstrap(const TActorContext &ctx)
@@ -57,14 +57,14 @@ public:
StateStorageGroup = dinfo->GetDefaultStateStorageGroup(domain->DomainUid);
}
- SendRequest(ctx);
- TBase::Become(&TConsoleRequestActor::MainState);
+ SendRequest(ctx);
+ TBase::Become(&TConsoleRequestActor::MainState);
}
void SendRequest(const TActorContext &ctx)
{
NTabletPipe::TClientConfig pipeConfig;
- pipeConfig.RetryPolicy = {.RetryLimitCount = 10};
+ pipeConfig.RetryPolicy = {.RetryLimitCount = 10};
auto pipe = NTabletPipe::CreateClient(ctx.SelfID, MakeConsoleID(StateStorageGroup), pipeConfig);
ConsolePipe = ctx.RegisterWithSameMailbox(pipe);
@@ -76,7 +76,7 @@ public:
if (Request.HasCreateTenantRequest()) {
auto request = MakeHolder<TEvConsole::TEvCreateTenantRequest>();
request->Record.CopyFrom(Request.GetCreateTenantRequest());
- request->Record.SetUserToken(TBase::GetSerializedToken());
+ request->Record.SetUserToken(TBase::GetSerializedToken());
NTabletPipe::SendData(ctx, ConsolePipe, request.Release());
} else if (Request.HasGetConfigRequest()) {
auto request = MakeHolder<TEvConsole::TEvGetConfigRequest>();
@@ -85,22 +85,22 @@ public:
} else if (Request.HasGetTenantStatusRequest()) {
auto request = MakeHolder<TEvConsole::TEvGetTenantStatusRequest>();
request->Record.CopyFrom(Request.GetGetTenantStatusRequest());
- request->Record.SetUserToken(TBase::GetSerializedToken());
+ request->Record.SetUserToken(TBase::GetSerializedToken());
NTabletPipe::SendData(ctx, ConsolePipe, request.Release());
} else if (Request.HasAlterTenantRequest()) {
auto request = MakeHolder<TEvConsole::TEvAlterTenantRequest>();
request->Record.CopyFrom(Request.GetAlterTenantRequest());
- request->Record.SetUserToken(TBase::GetSerializedToken());
+ request->Record.SetUserToken(TBase::GetSerializedToken());
NTabletPipe::SendData(ctx, ConsolePipe, request.Release());
} else if (Request.HasListTenantsRequest()) {
auto request = MakeHolder<TEvConsole::TEvListTenantsRequest>();
request->Record.CopyFrom(Request.GetListTenantsRequest());
- request->Record.SetUserToken(TBase::GetSerializedToken());
+ request->Record.SetUserToken(TBase::GetSerializedToken());
NTabletPipe::SendData(ctx, ConsolePipe, request.Release());
} else if (Request.HasRemoveTenantRequest()) {
auto request = MakeHolder<TEvConsole::TEvRemoveTenantRequest>();
request->Record.CopyFrom(Request.GetRemoveTenantRequest());
- request->Record.SetUserToken(TBase::GetSerializedToken());
+ request->Record.SetUserToken(TBase::GetSerializedToken());
NTabletPipe::SendData(ctx, ConsolePipe, request.Release());
} else if (Request.HasSetConfigRequest()) {
auto request = MakeHolder<TEvConsole::TEvSetConfigRequest>();
@@ -291,7 +291,7 @@ public:
void Die(const TActorContext &ctx)
{
NTabletPipe::CloseClient(ctx, ConsolePipe);
- TBase::Die(ctx);
+ TBase::Die(ctx);
}
void SendReplyAndDie(const TActorContext &ctx)
diff --git a/ydb/core/client/server/msgbus_server_db.cpp b/ydb/core/client/server/msgbus_server_db.cpp
index a9e3e66ae61..08f3d717864 100644
--- a/ydb/core/client/server/msgbus_server_db.cpp
+++ b/ydb/core/client/server/msgbus_server_db.cpp
@@ -20,334 +20,334 @@
#include <library/cpp/json/json_reader.h>
#include <library/cpp/json/json_value.h>
#include <library/cpp/protobuf/json/json2proto.h>
-
-
-namespace NKikimr {
-namespace NMsgBusProxy {
-
-namespace {
- constexpr TDuration Timeout = TDuration::Seconds(30);
-
- struct TEvPrivate {
- enum EEv {
- EvReply = EventSpaceBegin(TEvents::ES_PRIVATE),
- EvEnd
- };
-
- static_assert(EvEnd < EventSpaceEnd(TEvents::ES_PRIVATE), "expected EvEnd < EventSpaceEnd");
-
- struct TEvReply : public TEventLocal<TEvReply, EvReply> {
- EResponseStatus Status;
- TEvTxUserProxy::TResultStatus::EStatus ProxyStatus;
+
+
+namespace NKikimr {
+namespace NMsgBusProxy {
+
+namespace {
+ constexpr TDuration Timeout = TDuration::Seconds(30);
+
+ struct TEvPrivate {
+ enum EEv {
+ EvReply = EventSpaceBegin(TEvents::ES_PRIVATE),
+ EvEnd
+ };
+
+ static_assert(EvEnd < EventSpaceEnd(TEvents::ES_PRIVATE), "expected EvEnd < EventSpaceEnd");
+
+ struct TEvReply : public TEventLocal<TEvReply, EvReply> {
+ EResponseStatus Status;
+ TEvTxUserProxy::TResultStatus::EStatus ProxyStatus;
TString Message;
- NKikimrTxUserProxy::TEvProposeTransactionStatus Result;
-
- TEvReply(EResponseStatus status, TEvTxUserProxy::TResultStatus::EStatus proxyStatus, const TString& message)
- : Status(status)
- , ProxyStatus(proxyStatus)
- , Message(message)
- {}
-
- TEvReply(EResponseStatus status, const NKikimrTxUserProxy::TEvProposeTransactionStatus& result)
- : Status(status)
- , ProxyStatus(TEvTxUserProxy::TResultStatus::EStatus::Unknown)
- , Result(result)
- {}
- };
- };
-}
-
-template <typename RequestType>
-class TMessageBusInterface : public TMessageBusSessionIdentHolder {
-private:
- TAutoPtr<RequestType> Request;
- NKikimrClient::TJsonSettings JsonSettings;
-
-public:
- TMessageBusInterface(TBusMessageContext& msg)
+ NKikimrTxUserProxy::TEvProposeTransactionStatus Result;
+
+ TEvReply(EResponseStatus status, TEvTxUserProxy::TResultStatus::EStatus proxyStatus, const TString& message)
+ : Status(status)
+ , ProxyStatus(proxyStatus)
+ , Message(message)
+ {}
+
+ TEvReply(EResponseStatus status, const NKikimrTxUserProxy::TEvProposeTransactionStatus& result)
+ : Status(status)
+ , ProxyStatus(TEvTxUserProxy::TResultStatus::EStatus::Unknown)
+ , Result(result)
+ {}
+ };
+ };
+}
+
+template <typename RequestType>
+class TMessageBusInterface : public TMessageBusSessionIdentHolder {
+private:
+ TAutoPtr<RequestType> Request;
+ NKikimrClient::TJsonSettings JsonSettings;
+
+public:
+ TMessageBusInterface(TBusMessageContext& msg)
: TMessageBusSessionIdentHolder(msg)
, Request(static_cast<RequestType*>(msg.ReleaseMessage()))
{}
-
+
void ReplyWithErrorToInterface(EResponseStatus status, TEvTxUserProxy::TResultStatus::EStatus proxyStatus, const TString& message, const TActorContext&) {
- TAutoPtr<TBusResponse> response(new TBusResponseStatus(status, message));
- if (proxyStatus != TEvTxUserProxy::TResultStatus::Unknown)
- response->Record.SetProxyErrorCode(proxyStatus);
- SendReplyAutoPtr(response);
- }
-
- void ReplyWithResultToInterface(EResponseStatus status, const NKikimrTxUserProxy::TEvProposeTransactionStatus& result, const TActorContext&) {
- if (status == MSTATUS_OK && result.HasExecutionEngineEvaluatedResponse()) {
- const NKikimrMiniKQL::TResult& pbResult(result.GetExecutionEngineEvaluatedResponse());
- if (pbResult.HasType() && pbResult.HasValue()) {
- TAutoPtr<TBusDbResponse> response(new TBusDbResponse);
- NClient::TValue value(NClient::TValue::Create(pbResult.GetValue(), pbResult.GetType()));
- NClient::TValue resultValue(value["Result"]);
- if (resultValue.HaveValue()) {
- response->Record.SetJSON(resultValue.GetValueText<NClient::TFormatJSON>({JsonSettings.GetUI64AsString()}));
- SendReplyAutoPtr(response);
- } else {
- response->Record.SetJSON("{}");
- SendReplyAutoPtr(response);
- }
- }
- } else {
+ TAutoPtr<TBusResponse> response(new TBusResponseStatus(status, message));
+ if (proxyStatus != TEvTxUserProxy::TResultStatus::Unknown)
+ response->Record.SetProxyErrorCode(proxyStatus);
+ SendReplyAutoPtr(response);
+ }
+
+ void ReplyWithResultToInterface(EResponseStatus status, const NKikimrTxUserProxy::TEvProposeTransactionStatus& result, const TActorContext&) {
+ if (status == MSTATUS_OK && result.HasExecutionEngineEvaluatedResponse()) {
+ const NKikimrMiniKQL::TResult& pbResult(result.GetExecutionEngineEvaluatedResponse());
+ if (pbResult.HasType() && pbResult.HasValue()) {
+ TAutoPtr<TBusDbResponse> response(new TBusDbResponse);
+ NClient::TValue value(NClient::TValue::Create(pbResult.GetValue(), pbResult.GetType()));
+ NClient::TValue resultValue(value["Result"]);
+ if (resultValue.HaveValue()) {
+ response->Record.SetJSON(resultValue.GetValueText<NClient::TFormatJSON>({JsonSettings.GetUI64AsString()}));
+ SendReplyAutoPtr(response);
+ } else {
+ response->Record.SetJSON("{}");
+ SendReplyAutoPtr(response);
+ }
+ }
+ } else {
TAutoPtr<TBusResponse> response(ProposeTransactionStatusToResponse(status, result));
- if (result.HasExecutionEngineEvaluatedResponse()) {
- response->Record.MutableExecutionEngineEvaluatedResponse()->CopyFrom(result.GetExecutionEngineEvaluatedResponse());
- }
- SendReplyAutoPtr(response);
- }
- }
-
- void ReplyWithResultToInterface(EResponseStatus, const google::protobuf::RepeatedPtrField<NKikimrMiniKQL::TResult>& result, const TActorContext&) {
- TStringStream json;
- if (!result.empty()) {
- if (result.size() == 1) {
- const NKikimrMiniKQL::TResult& pbResult = *result.begin();
- if (pbResult.HasType() && pbResult.HasValue()) {
- NClient::TValue value(NClient::TValue::Create(pbResult.GetValue(), pbResult.GetType()));
- NClient::TValue resultValue(value["Data"]);
- if (resultValue.HaveValue()) {
- json << resultValue.GetValueText<NClient::TFormatJSON>({JsonSettings.GetUI64AsString()});
- } else {
- json << "[]";
- }
- }
- } else {
- json << '[';
- for (auto it = result.begin(); it != result.end(); ++it) {
- const NKikimrMiniKQL::TResult& pbResult = *it;
- if (it != result.begin()) {
- json << ',';
- }
- if (pbResult.HasType() && pbResult.HasValue()) {
- NClient::TValue value(NClient::TValue::Create(pbResult.GetValue(), pbResult.GetType()));
- NClient::TValue resultValue(value["Data"]);
- if (resultValue.HaveValue()) {
- json << resultValue.GetValueText<NClient::TFormatJSON>({JsonSettings.GetUI64AsString()});
- } else {
- json << "[]";
- }
- } else {
- json << "[]";
- }
- }
- json << ']';
- }
- TAutoPtr<TBusDbResponse> response(new TBusDbResponse);
- response->Record.SetJSON(json.Str());
- SendReplyAutoPtr(response);
- }
- }
-
- bool BootstrapJSON(NJson::TJsonValue* jsonValue, TString& securityToken) {
- static NJson::TJsonReaderConfig readerConfig;
- TMemoryInput in(Request->Record.GetJSON());
- bool result = NJson::ReadJsonTree(&in, &readerConfig, jsonValue, false);
- if (result) {
- NJson::TJsonValue* jsonSettings;
- if (jsonValue->GetValuePointer("JsonSettings", &jsonSettings)) {
- try {
- NProtobufJson::Json2Proto(*jsonSettings, JsonSettings);
- } catch(const yexception&) {
- }
- }
- }
- if (Request->Record.HasSecurityToken()) {
- securityToken = Request->Record.GetSecurityToken();
- }
- if (Request->Record.HasJsonSettings()) {
- JsonSettings.MergeFrom(Request->Record.GetJsonSettings());
- }
- Request.Destroy();
- return result;
- }
-};
-
-class TActorInterface {
-private:
+ if (result.HasExecutionEngineEvaluatedResponse()) {
+ response->Record.MutableExecutionEngineEvaluatedResponse()->CopyFrom(result.GetExecutionEngineEvaluatedResponse());
+ }
+ SendReplyAutoPtr(response);
+ }
+ }
+
+ void ReplyWithResultToInterface(EResponseStatus, const google::protobuf::RepeatedPtrField<NKikimrMiniKQL::TResult>& result, const TActorContext&) {
+ TStringStream json;
+ if (!result.empty()) {
+ if (result.size() == 1) {
+ const NKikimrMiniKQL::TResult& pbResult = *result.begin();
+ if (pbResult.HasType() && pbResult.HasValue()) {
+ NClient::TValue value(NClient::TValue::Create(pbResult.GetValue(), pbResult.GetType()));
+ NClient::TValue resultValue(value["Data"]);
+ if (resultValue.HaveValue()) {
+ json << resultValue.GetValueText<NClient::TFormatJSON>({JsonSettings.GetUI64AsString()});
+ } else {
+ json << "[]";
+ }
+ }
+ } else {
+ json << '[';
+ for (auto it = result.begin(); it != result.end(); ++it) {
+ const NKikimrMiniKQL::TResult& pbResult = *it;
+ if (it != result.begin()) {
+ json << ',';
+ }
+ if (pbResult.HasType() && pbResult.HasValue()) {
+ NClient::TValue value(NClient::TValue::Create(pbResult.GetValue(), pbResult.GetType()));
+ NClient::TValue resultValue(value["Data"]);
+ if (resultValue.HaveValue()) {
+ json << resultValue.GetValueText<NClient::TFormatJSON>({JsonSettings.GetUI64AsString()});
+ } else {
+ json << "[]";
+ }
+ } else {
+ json << "[]";
+ }
+ }
+ json << ']';
+ }
+ TAutoPtr<TBusDbResponse> response(new TBusDbResponse);
+ response->Record.SetJSON(json.Str());
+ SendReplyAutoPtr(response);
+ }
+ }
+
+ bool BootstrapJSON(NJson::TJsonValue* jsonValue, TString& securityToken) {
+ static NJson::TJsonReaderConfig readerConfig;
+ TMemoryInput in(Request->Record.GetJSON());
+ bool result = NJson::ReadJsonTree(&in, &readerConfig, jsonValue, false);
+ if (result) {
+ NJson::TJsonValue* jsonSettings;
+ if (jsonValue->GetValuePointer("JsonSettings", &jsonSettings)) {
+ try {
+ NProtobufJson::Json2Proto(*jsonSettings, JsonSettings);
+ } catch(const yexception&) {
+ }
+ }
+ }
+ if (Request->Record.HasSecurityToken()) {
+ securityToken = Request->Record.GetSecurityToken();
+ }
+ if (Request->Record.HasJsonSettings()) {
+ JsonSettings.MergeFrom(Request->Record.GetJsonSettings());
+ }
+ Request.Destroy();
+ return result;
+ }
+};
+
+class TActorInterface {
+private:
TActorId HostActor;
-public:
+public:
TActorInterface(const TActorId& hostActor)
- : HostActor(hostActor)
- {}
-
+ : HostActor(hostActor)
+ {}
+
void ReplyWithErrorToInterface(EResponseStatus status, TEvTxUserProxy::TResultStatus::EStatus proxyStatus, const TString& message, const TActorContext& ctx) {
- ctx.Send(HostActor, new TEvPrivate::TEvReply(status, proxyStatus, message));
- }
-
- void ReplyWithResultToInterface(EResponseStatus status, const NKikimrTxUserProxy::TEvProposeTransactionStatus& result, const TActorContext& ctx) {
- ctx.Send(HostActor, new TEvPrivate::TEvReply(status, result));
- }
-
- bool BootstrapJSON(NJson::TJsonValue*, TString&) { return true; }
-};
-
-template <typename InterfaceBase>
-class TServerDbOperation : public TActorBootstrapped<TServerDbOperation<InterfaceBase>>, public InterfaceBase {
-protected:
- using TThis = TServerDbOperation<InterfaceBase>;
- using TBase = TActorBootstrapped<TServerDbOperation<InterfaceBase>>;
- using TTabletId = ui64;
-
+ ctx.Send(HostActor, new TEvPrivate::TEvReply(status, proxyStatus, message));
+ }
+
+ void ReplyWithResultToInterface(EResponseStatus status, const NKikimrTxUserProxy::TEvProposeTransactionStatus& result, const TActorContext& ctx) {
+ ctx.Send(HostActor, new TEvPrivate::TEvReply(status, result));
+ }
+
+ bool BootstrapJSON(NJson::TJsonValue*, TString&) { return true; }
+};
+
+template <typename InterfaceBase>
+class TServerDbOperation : public TActorBootstrapped<TServerDbOperation<InterfaceBase>>, public InterfaceBase {
+protected:
+ using TThis = TServerDbOperation<InterfaceBase>;
+ using TBase = TActorBootstrapped<TServerDbOperation<InterfaceBase>>;
+ using TTabletId = ui64;
+
TActorId TxProxyId;
TActorId SchemeCache;
- TIntrusivePtr<TMessageBusDbOpsCounters> DbOperationsCounters;
-
- NMon::THistogramCounterHelper* OperationHistogram;
+ TIntrusivePtr<TMessageBusDbOpsCounters> DbOperationsCounters;
+
+ NMon::THistogramCounterHelper* OperationHistogram;
TAutoPtr<NSchemeCache::TSchemeCacheNavigate> CacheNavigate;
- NJson::TJsonValue JSON;
- THPTimer StartTime;
+ NJson::TJsonValue JSON;
+ THPTimer StartTime;
TString Table;
- TString SecurityToken; // raw input
- TString UserToken; // built and serialized
- ui32 Requests = 0;
- ui32 Responses = 0;
-
- void CompleteRequest(const TActorContext& ctx) {
- TDuration duration(TDuration::MicroSeconds(StartTime.Passed() * 1000000/*us*/));
- if (OperationHistogram != nullptr) {
- OperationHistogram->Add(duration.MilliSeconds());
- }
- DbOperationsCounters->RequestTotalTimeHistogram.Add(duration.MilliSeconds());
- Die(ctx);
- }
-
- void ReplyWithError(EResponseStatus status, TEvTxUserProxy::TResultStatus::EStatus proxyStatus, const TString& message, const TActorContext& ctx) {
- InterfaceBase::ReplyWithErrorToInterface(status, proxyStatus, message, ctx);
- CompleteRequest(ctx);
- }
-
+ TString SecurityToken; // raw input
+ TString UserToken; // built and serialized
+ ui32 Requests = 0;
+ ui32 Responses = 0;
+
+ void CompleteRequest(const TActorContext& ctx) {
+ TDuration duration(TDuration::MicroSeconds(StartTime.Passed() * 1000000/*us*/));
+ if (OperationHistogram != nullptr) {
+ OperationHistogram->Add(duration.MilliSeconds());
+ }
+ DbOperationsCounters->RequestTotalTimeHistogram.Add(duration.MilliSeconds());
+ Die(ctx);
+ }
+
+ void ReplyWithError(EResponseStatus status, TEvTxUserProxy::TResultStatus::EStatus proxyStatus, const TString& message, const TActorContext& ctx) {
+ InterfaceBase::ReplyWithErrorToInterface(status, proxyStatus, message, ctx);
+ CompleteRequest(ctx);
+ }
+
void ReplyWithError(EResponseStatus status, const TString& message, const TActorContext& ctx) {
- ReplyWithError(status, TEvTxUserProxy::TResultStatus::Unknown, message, ctx);
- }
-
- void ReplyWithError(EResponseStatus status, TEvTxUserProxy::TResultStatus::EStatus proxyStatus, const TActorContext& ctx) {
- ReplyWithError(status, proxyStatus, TEvTxUserProxy::TResultStatus::Str(proxyStatus), ctx);
- }
-
- void ReplyWithResult(EResponseStatus status, const NKikimrTxUserProxy::TEvProposeTransactionStatus& result, const TActorContext& ctx) {
- InterfaceBase::ReplyWithResultToInterface(status, result, ctx);
- CompleteRequest(ctx);
- }
-
- void Handle(TEvTxProxySchemeCache::TEvNavigateKeySetResult::TPtr& ev, const TActorContext& ctx) {
+ ReplyWithError(status, TEvTxUserProxy::TResultStatus::Unknown, message, ctx);
+ }
+
+ void ReplyWithError(EResponseStatus status, TEvTxUserProxy::TResultStatus::EStatus proxyStatus, const TActorContext& ctx) {
+ ReplyWithError(status, proxyStatus, TEvTxUserProxy::TResultStatus::Str(proxyStatus), ctx);
+ }
+
+ void ReplyWithResult(EResponseStatus status, const NKikimrTxUserProxy::TEvProposeTransactionStatus& result, const TActorContext& ctx) {
+ InterfaceBase::ReplyWithResultToInterface(status, result, ctx);
+ CompleteRequest(ctx);
+ }
+
+ void Handle(TEvTxProxySchemeCache::TEvNavigateKeySetResult::TPtr& ev, const TActorContext& ctx) {
const NSchemeCache::TSchemeCacheNavigate& request = *ev->Get()->Request;
- Y_VERIFY(request.ResultSet.size() == 1);
+ Y_VERIFY(request.ResultSet.size() == 1);
if (request.ResultSet.front().Status != NSchemeCache::TSchemeCacheNavigate::EStatus::Ok) {
return ReplyWithError(MSTATUS_ERROR, TEvTxUserProxy::TResultStatus::ResolveError, ToString(request.ResultSet.front().Status), ctx);
- }
- CacheNavigate = ev->Get()->Request;
- if (++Responses == Requests) {
- BuildAndRunProgram(ctx);
- }
- }
-
- void Handle(TEvTicketParser::TEvAuthorizeTicketResult::TPtr &ev, const TActorContext &ctx) {
- const TEvTicketParser::TEvAuthorizeTicketResult& result(*ev->Get());
- if (!result.Error.empty()) {
- //return TBase::HandleError(EResponseStatus::MSTATUS_ERROR, TEvTxUserProxy::TEvProposeTransactionStatus::EStatus::AccessDenied, result.Error, ctx);
- } else {
- UserToken = result.SerializedToken;
- }
- if (++Responses == Requests) {
- BuildAndRunProgram(ctx);
- }
- }
-
- void Handle(TEvTxUserProxy::TEvProposeTransactionStatus::TPtr& ev, const TActorContext& ctx) {
- TEvTxUserProxy::TEvProposeTransactionStatus* msg = ev->Get();
- const TEvTxUserProxy::TEvProposeTransactionStatus::EStatus status = static_cast<TEvTxUserProxy::TEvProposeTransactionStatus::EStatus>(msg->Record.GetStatus());
- switch (status) {
- case TEvTxUserProxy::TEvProposeTransactionStatus::EStatus::ProxyAccepted:
- case TEvTxUserProxy::TEvProposeTransactionStatus::EStatus::ProxyResolved:
- case TEvTxUserProxy::TEvProposeTransactionStatus::EStatus::ProxyPrepared:
- case TEvTxUserProxy::TEvProposeTransactionStatus::EStatus::CoordinatorPlanned:
- // transitional statuses
- return;
- case TEvTxUserProxy::TEvProposeTransactionStatus::EStatus::ExecComplete:
- case TEvTxUserProxy::TEvProposeTransactionStatus::EStatus::ExecAlready:
- // completion
- return ReplyWithResult(MSTATUS_OK, msg->Record, ctx);
- case TEvTxUserProxy::TEvProposeTransactionStatus::EStatus::ExecTimeout:
- return ReplyWithResult(MSTATUS_INPROGRESS, msg->Record, ctx);
- case TEvTxUserProxy::TEvProposeTransactionStatus::EStatus::ProxyNotReady:
- return ReplyWithError(MSTATUS_NOTREADY, status, ctx);
- case TEvTxUserProxy::TEvProposeTransactionStatus::EStatus::ExecAborted:
- return ReplyWithError(MSTATUS_ABORTED, status, ctx);
- case TEvTxUserProxy::TEvProposeTransactionStatus::EStatus::EmptyAffectedSet:
- case TEvTxUserProxy::TEvProposeTransactionStatus::EStatus::ResolveError:
- case TEvTxUserProxy::TEvProposeTransactionStatus::EStatus::ExecError:
+ }
+ CacheNavigate = ev->Get()->Request;
+ if (++Responses == Requests) {
+ BuildAndRunProgram(ctx);
+ }
+ }
+
+ void Handle(TEvTicketParser::TEvAuthorizeTicketResult::TPtr &ev, const TActorContext &ctx) {
+ const TEvTicketParser::TEvAuthorizeTicketResult& result(*ev->Get());
+ if (!result.Error.empty()) {
+ //return TBase::HandleError(EResponseStatus::MSTATUS_ERROR, TEvTxUserProxy::TEvProposeTransactionStatus::EStatus::AccessDenied, result.Error, ctx);
+ } else {
+ UserToken = result.SerializedToken;
+ }
+ if (++Responses == Requests) {
+ BuildAndRunProgram(ctx);
+ }
+ }
+
+ void Handle(TEvTxUserProxy::TEvProposeTransactionStatus::TPtr& ev, const TActorContext& ctx) {
+ TEvTxUserProxy::TEvProposeTransactionStatus* msg = ev->Get();
+ const TEvTxUserProxy::TEvProposeTransactionStatus::EStatus status = static_cast<TEvTxUserProxy::TEvProposeTransactionStatus::EStatus>(msg->Record.GetStatus());
+ switch (status) {
+ case TEvTxUserProxy::TEvProposeTransactionStatus::EStatus::ProxyAccepted:
+ case TEvTxUserProxy::TEvProposeTransactionStatus::EStatus::ProxyResolved:
+ case TEvTxUserProxy::TEvProposeTransactionStatus::EStatus::ProxyPrepared:
+ case TEvTxUserProxy::TEvProposeTransactionStatus::EStatus::CoordinatorPlanned:
+ // transitional statuses
+ return;
+ case TEvTxUserProxy::TEvProposeTransactionStatus::EStatus::ExecComplete:
+ case TEvTxUserProxy::TEvProposeTransactionStatus::EStatus::ExecAlready:
+ // completion
+ return ReplyWithResult(MSTATUS_OK, msg->Record, ctx);
+ case TEvTxUserProxy::TEvProposeTransactionStatus::EStatus::ExecTimeout:
+ return ReplyWithResult(MSTATUS_INPROGRESS, msg->Record, ctx);
+ case TEvTxUserProxy::TEvProposeTransactionStatus::EStatus::ProxyNotReady:
+ return ReplyWithError(MSTATUS_NOTREADY, status, ctx);
+ case TEvTxUserProxy::TEvProposeTransactionStatus::EStatus::ExecAborted:
+ return ReplyWithError(MSTATUS_ABORTED, status, ctx);
+ case TEvTxUserProxy::TEvProposeTransactionStatus::EStatus::EmptyAffectedSet:
+ case TEvTxUserProxy::TEvProposeTransactionStatus::EStatus::ResolveError:
+ case TEvTxUserProxy::TEvProposeTransactionStatus::EStatus::ExecError:
case TEvTxUserProxy::TEvProposeTransactionStatus::EStatus::DomainLocalityError:
case TEvTxUserProxy::TEvProposeTransactionStatus::EStatus::WrongRequest:
- return ReplyWithResult(MSTATUS_ERROR, msg->Record, ctx);
- case TEvTxUserProxy::TEvProposeTransactionStatus::EStatus::ProxyShardNotAvailable:
- case TEvTxUserProxy::TEvProposeTransactionStatus::EStatus::ProxyShardTryLater:
- case TEvTxUserProxy::TEvProposeTransactionStatus::EStatus::ProxyShardOverloaded:
- return ReplyWithResult(MSTATUS_REJECTED, msg->Record, ctx);
+ return ReplyWithResult(MSTATUS_ERROR, msg->Record, ctx);
+ case TEvTxUserProxy::TEvProposeTransactionStatus::EStatus::ProxyShardNotAvailable:
+ case TEvTxUserProxy::TEvProposeTransactionStatus::EStatus::ProxyShardTryLater:
+ case TEvTxUserProxy::TEvProposeTransactionStatus::EStatus::ProxyShardOverloaded:
+ return ReplyWithResult(MSTATUS_REJECTED, msg->Record, ctx);
case TEvTxUserProxy::TEvProposeTransactionStatus::EStatus::ProxyShardUnknown:
return ReplyWithResult(MSTATUS_TIMEOUT, msg->Record, ctx);
- default:
- return ReplyWithResult(MSTATUS_INTERNALERROR, msg->Record, ctx);
- }
- }
-
-public:
+ default:
+ return ReplyWithResult(MSTATUS_INTERNALERROR, msg->Record, ctx);
+ }
+ }
+
+public:
static constexpr NKikimrServices::TActivity::EType ActorActivityType() { return NKikimrServices::TActivity::MSGBUS_COMMON; }
-
+
TServerDbOperation(TBusMessageContext& msg, TActorId txProxyId, const TActorId& schemeCache, const TIntrusivePtr<TMessageBusDbOpsCounters>& dbOperationsCounters);
-
- TServerDbOperation(
+
+ TServerDbOperation(
const TActorId& hostActor,
- NJson::TJsonValue&& jsonValue,
- const TString& SecurityToken,
+ NJson::TJsonValue&& jsonValue,
+ const TString& SecurityToken,
TActorId txProxyId,
const TActorId& schemeCache,
- const TIntrusivePtr<TMessageBusDbOpsCounters>& dbOperationsCounters
- );
-
- void HandleTimeout(const TActorContext& ctx) {
- return ReplyWithError(MSTATUS_TIMEOUT, "Request timed out", ctx);
- }
-
- void StateWaitResolve(TAutoPtr<NActors::IEventHandle>& ev, const NActors::TActorContext& ctx) {
- switch (ev->GetTypeRewrite()) {
- HFunc(TEvTxProxySchemeCache::TEvNavigateKeySetResult, Handle);
- HFunc(TEvTicketParser::TEvAuthorizeTicketResult, Handle);
- CFunc(TEvents::TSystem::Wakeup, HandleTimeout);
- }
- }
-
- void StateWaitExecute(TAutoPtr<NActors::IEventHandle>& ev, const NActors::TActorContext& ctx) {
- switch (ev->GetTypeRewrite()) {
- HFunc(TEvTxUserProxy::TEvProposeTransactionStatus, Handle);
- CFunc(TEvents::TSystem::Wakeup, HandleTimeout);
- }
- }
-
+ const TIntrusivePtr<TMessageBusDbOpsCounters>& dbOperationsCounters
+ );
+
+ void HandleTimeout(const TActorContext& ctx) {
+ return ReplyWithError(MSTATUS_TIMEOUT, "Request timed out", ctx);
+ }
+
+ void StateWaitResolve(TAutoPtr<NActors::IEventHandle>& ev, const NActors::TActorContext& ctx) {
+ switch (ev->GetTypeRewrite()) {
+ HFunc(TEvTxProxySchemeCache::TEvNavigateKeySetResult, Handle);
+ HFunc(TEvTicketParser::TEvAuthorizeTicketResult, Handle);
+ CFunc(TEvents::TSystem::Wakeup, HandleTimeout);
+ }
+ }
+
+ void StateWaitExecute(TAutoPtr<NActors::IEventHandle>& ev, const NActors::TActorContext& ctx) {
+ switch (ev->GetTypeRewrite()) {
+ HFunc(TEvTxUserProxy::TEvProposeTransactionStatus, Handle);
+ CFunc(TEvents::TSystem::Wakeup, HandleTimeout);
+ }
+ }
+
void ResolveTable(const TString& table, const NActors::TActorContext& ctx) {
TAutoPtr<NSchemeCache::TSchemeCacheNavigate> request(new NSchemeCache::TSchemeCacheNavigate());
NSchemeCache::TSchemeCacheNavigate::TEntry entry;
entry.Path = SplitPath(table);
- if (entry.Path.empty()) {
- return ReplyWithError(MSTATUS_ERROR, TEvTxUserProxy::TEvProposeTransactionStatus::EStatus::WrongRequest, "Invalid table path specified", ctx);
- }
+ if (entry.Path.empty()) {
+ return ReplyWithError(MSTATUS_ERROR, TEvTxUserProxy::TEvProposeTransactionStatus::EStatus::WrongRequest, "Invalid table path specified", ctx);
+ }
entry.Operation = NSchemeCache::TSchemeCacheNavigate::OpTable;
- request->ResultSet.emplace_back(entry);
- ctx.Send(SchemeCache, new TEvTxProxySchemeCache::TEvNavigateKeySet(request));
- ++Requests;
- if (!SecurityToken.empty()) {
- ctx.Send(MakeTicketParserID(), new TEvTicketParser::TEvAuthorizeTicket(SecurityToken));
- ++Requests;
- }
+ request->ResultSet.emplace_back(entry);
+ ctx.Send(SchemeCache, new TEvTxProxySchemeCache::TEvNavigateKeySet(request));
+ ++Requests;
+ if (!SecurityToken.empty()) {
+ ctx.Send(MakeTicketParserID(), new TEvTicketParser::TEvAuthorizeTicket(SecurityToken));
+ ++Requests;
+ }
TBase::Become(&TThis::StateWaitResolve, ctx, Timeout, new TEvents::TEvWakeup());
- }
-
+ }
+
static NMiniKQL::TRuntimeNode NewDataLiteral(NMiniKQL::TKikimrProgramBuilder& pgmBuilder, const NJson::TJsonValue& jsonValue, NScheme::TTypeId typeId) {
- // TODO
+ // TODO
auto& builder = static_cast<NMiniKQL::TProgramBuilder&>(pgmBuilder);
- switch (typeId) {
+ switch (typeId) {
case NScheme::NTypeIds::Bool:
return builder.NewDataLiteral<bool>(jsonValue.GetBoolean());
case NScheme::NTypeIds::Float:
@@ -374,695 +374,695 @@ public:
return pgmBuilder.NewDataLiteral<NUdf::EDataSlot::JsonDocument>(jsonValue.GetString());
case NScheme::NTypeIds::DyNumber:
return pgmBuilder.NewDataLiteral<NUdf::EDataSlot::DyNumber>(jsonValue.GetString());
- default:
- // still better than VERIFY
- return pgmBuilder.NewEmptyOptionalDataLiteral(typeId);
- }
- }
-
+ default:
+ // still better than VERIFY
+ return pgmBuilder.NewEmptyOptionalDataLiteral(typeId);
+ }
+ }
+
void BuildProgram(const NJson::TJsonValue& json, NMiniKQL::TRuntimeNode& pgmReturn, NMiniKQL::TKikimrProgramBuilder& pgmBuilder, const NSchemeCache::TSchemeCacheNavigate::TEntry& tableInfo,
const TVector<const NTxProxy::TTableColumnInfo*>& keys, const THashMap<TString, const NTxProxy::TTableColumnInfo*>& columnByName, TVector<NMiniKQL::TRuntimeNode>& result) {
TVector<NMiniKQL::TRuntimeNode> keyColumns;
TVector<ui32> keyTypes;
- keyTypes.reserve(keys.size());
- for (const NTxProxy::TTableColumnInfo* key : keys) {
- Y_VERIFY(key != nullptr);
- keyTypes.push_back(key->PType);
- }
- NJson::TJsonValue jsonWhere;
- if (json.GetValue("Where", &jsonWhere)) {
- keyColumns.reserve(keys.size());
- for (const NTxProxy::TTableColumnInfo* key : keys) {
- NJson::TJsonValue jsonKey;
- if (jsonWhere.GetValue(key->Name, &jsonKey)) {
- keyColumns.emplace_back(NewDataLiteral(pgmBuilder, jsonKey, key->PType));
- } else {
- throw yexception() << "Key \"" << key->Name << "\" was not specified";
- }
- }
- }
-
- TReadTarget readTarget;
- NJson::TJsonValue jsonReadTarget;
- if (json.GetValue("ReadTarget", &jsonReadTarget)) {
- const auto& readTargetValue = jsonReadTarget.GetString();
- if (readTargetValue == "Online") {
- readTarget = TReadTarget::Online();
- } else
- if (readTargetValue == "Head") {
- readTarget = TReadTarget::Head();
- } else
+ keyTypes.reserve(keys.size());
+ for (const NTxProxy::TTableColumnInfo* key : keys) {
+ Y_VERIFY(key != nullptr);
+ keyTypes.push_back(key->PType);
+ }
+ NJson::TJsonValue jsonWhere;
+ if (json.GetValue("Where", &jsonWhere)) {
+ keyColumns.reserve(keys.size());
+ for (const NTxProxy::TTableColumnInfo* key : keys) {
+ NJson::TJsonValue jsonKey;
+ if (jsonWhere.GetValue(key->Name, &jsonKey)) {
+ keyColumns.emplace_back(NewDataLiteral(pgmBuilder, jsonKey, key->PType));
+ } else {
+ throw yexception() << "Key \"" << key->Name << "\" was not specified";
+ }
+ }
+ }
+
+ TReadTarget readTarget;
+ NJson::TJsonValue jsonReadTarget;
+ if (json.GetValue("ReadTarget", &jsonReadTarget)) {
+ const auto& readTargetValue = jsonReadTarget.GetString();
+ if (readTargetValue == "Online") {
+ readTarget = TReadTarget::Online();
+ } else
+ if (readTargetValue == "Head") {
+ readTarget = TReadTarget::Head();
+ } else
if (readTargetValue == "Follower") {
readTarget = TReadTarget::Follower();
- }
- }
-
- NJson::TJsonValue jsonSelect;
- if (json.GetValue("Select", &jsonSelect)) {
+ }
+ }
+
+ NJson::TJsonValue jsonSelect;
+ if (json.GetValue("Select", &jsonSelect)) {
TVector<NMiniKQL::TSelectColumn> columnsToRead;
- if (jsonSelect.IsArray()) {
- const NJson::TJsonValue::TArray& array = jsonSelect.GetArray();
- columnsToRead.reserve(array.size());
- for (const NJson::TJsonValue& value : array) {
- const TString& column = value.GetString();
- auto itCol = columnByName.find(column);
- if (itCol != columnByName.end()) {
- columnsToRead.emplace_back(itCol->second->Name, itCol->second->Id, itCol->second->PType);
- } else if (column == "*") {
- for (const auto& pr : columnByName) {
- columnsToRead.emplace_back(pr.second->Name, pr.second->Id, pr.second->PType);
- }
- } else {
- throw yexception() << "Column \"" << value.GetString() << "\" not found";
- }
- }
- } else if (jsonSelect.IsString() && jsonSelect.GetString() == "*") {
- for (const auto& pr : columnByName) {
- columnsToRead.emplace_back(pr.second->Name, pr.second->Id, pr.second->PType);
- }
- }
- if (keyColumns.size() == keyTypes.size()) {
- result.emplace_back(pgmBuilder.SelectRow(tableInfo.TableId, keyTypes, columnsToRead, keyColumns, readTarget));
- } else {
- NMiniKQL::TTableRangeOptions tableRangeOptions = pgmBuilder.GetDefaultTableRangeOptions();
+ if (jsonSelect.IsArray()) {
+ const NJson::TJsonValue::TArray& array = jsonSelect.GetArray();
+ columnsToRead.reserve(array.size());
+ for (const NJson::TJsonValue& value : array) {
+ const TString& column = value.GetString();
+ auto itCol = columnByName.find(column);
+ if (itCol != columnByName.end()) {
+ columnsToRead.emplace_back(itCol->second->Name, itCol->second->Id, itCol->second->PType);
+ } else if (column == "*") {
+ for (const auto& pr : columnByName) {
+ columnsToRead.emplace_back(pr.second->Name, pr.second->Id, pr.second->PType);
+ }
+ } else {
+ throw yexception() << "Column \"" << value.GetString() << "\" not found";
+ }
+ }
+ } else if (jsonSelect.IsString() && jsonSelect.GetString() == "*") {
+ for (const auto& pr : columnByName) {
+ columnsToRead.emplace_back(pr.second->Name, pr.second->Id, pr.second->PType);
+ }
+ }
+ if (keyColumns.size() == keyTypes.size()) {
+ result.emplace_back(pgmBuilder.SelectRow(tableInfo.TableId, keyTypes, columnsToRead, keyColumns, readTarget));
+ } else {
+ NMiniKQL::TTableRangeOptions tableRangeOptions = pgmBuilder.GetDefaultTableRangeOptions();
TVector<NMiniKQL::TRuntimeNode> keyFromColumns = keyColumns;
- for (size_t i = keyColumns.size(); i < keyTypes.size(); ++i) {
- keyFromColumns.emplace_back(pgmBuilder.NewEmptyOptionalDataLiteral(keyTypes[i]));
- }
- tableRangeOptions.ToColumns = keyColumns;
- tableRangeOptions.FromColumns = keyFromColumns;
- result.emplace_back(pgmBuilder.SelectRange(tableInfo.TableId, keyTypes, columnsToRead, tableRangeOptions, readTarget));
- }
- OperationHistogram = &DbOperationsCounters->RequestSelectTimeHistogram;
- }
-
- NJson::TJsonValue jsonUpdate;
- if (json.GetValue("Update", &jsonUpdate)) {
+ for (size_t i = keyColumns.size(); i < keyTypes.size(); ++i) {
+ keyFromColumns.emplace_back(pgmBuilder.NewEmptyOptionalDataLiteral(keyTypes[i]));
+ }
+ tableRangeOptions.ToColumns = keyColumns;
+ tableRangeOptions.FromColumns = keyFromColumns;
+ result.emplace_back(pgmBuilder.SelectRange(tableInfo.TableId, keyTypes, columnsToRead, tableRangeOptions, readTarget));
+ }
+ OperationHistogram = &DbOperationsCounters->RequestSelectTimeHistogram;
+ }
+
+ NJson::TJsonValue jsonUpdate;
+ if (json.GetValue("Update", &jsonUpdate)) {
const NJson::TJsonValue::TMapType& jsonMap = jsonUpdate.GetMap();
- for (auto itVal = jsonMap.begin(); itVal != jsonMap.end(); ++itVal) {
- auto itCol = columnByName.find(itVal->first);
- if (itCol != columnByName.end()) {
- auto update = pgmBuilder.GetUpdateRowBuilder();
- update.SetColumn(itCol->second->Id, itCol->second->PType, pgmBuilder.NewOptional(NewDataLiteral(pgmBuilder, itVal->second, itCol->second->PType)));
- pgmReturn = pgmBuilder.Append(pgmReturn, pgmBuilder.UpdateRow(tableInfo.TableId, keyTypes, keyColumns, update));
- } else {
- throw yexception() << "Column \"" << itVal->first << "\" not found";
- }
- }
- OperationHistogram = &DbOperationsCounters->RequestUpdateTimeHistogram;
- }
-
- NJson::TJsonValue jsonDelete;
- if (json.GetValue("Delete", &jsonDelete)) {
- pgmReturn = pgmBuilder.Append(pgmReturn, pgmBuilder.EraseRow(tableInfo.TableId, keyTypes, keyColumns));
- OperationHistogram = &DbOperationsCounters->RequestUpdateTimeHistogram;
- }
-
- NJson::TJsonValue jsonBatch;
- if (json.GetValue("Batch", &jsonBatch)) {
- const NJson::TJsonValue::TArray& array = jsonBatch.GetArray();
- for (const NJson::TJsonValue& value : array) {
- BuildProgram(value, pgmReturn, pgmBuilder, tableInfo, keys, columnByName, result);
- }
- OperationHistogram = &DbOperationsCounters->RequestBatchTimeHistogram;
- }
- }
-
- void BuildAndRunProgram(const NActors::TActorContext& ctx) {
- try {
- const NMiniKQL::IFunctionRegistry& functionRegistry = *AppData(ctx)->FunctionRegistry;
+ for (auto itVal = jsonMap.begin(); itVal != jsonMap.end(); ++itVal) {
+ auto itCol = columnByName.find(itVal->first);
+ if (itCol != columnByName.end()) {
+ auto update = pgmBuilder.GetUpdateRowBuilder();
+ update.SetColumn(itCol->second->Id, itCol->second->PType, pgmBuilder.NewOptional(NewDataLiteral(pgmBuilder, itVal->second, itCol->second->PType)));
+ pgmReturn = pgmBuilder.Append(pgmReturn, pgmBuilder.UpdateRow(tableInfo.TableId, keyTypes, keyColumns, update));
+ } else {
+ throw yexception() << "Column \"" << itVal->first << "\" not found";
+ }
+ }
+ OperationHistogram = &DbOperationsCounters->RequestUpdateTimeHistogram;
+ }
+
+ NJson::TJsonValue jsonDelete;
+ if (json.GetValue("Delete", &jsonDelete)) {
+ pgmReturn = pgmBuilder.Append(pgmReturn, pgmBuilder.EraseRow(tableInfo.TableId, keyTypes, keyColumns));
+ OperationHistogram = &DbOperationsCounters->RequestUpdateTimeHistogram;
+ }
+
+ NJson::TJsonValue jsonBatch;
+ if (json.GetValue("Batch", &jsonBatch)) {
+ const NJson::TJsonValue::TArray& array = jsonBatch.GetArray();
+ for (const NJson::TJsonValue& value : array) {
+ BuildProgram(value, pgmReturn, pgmBuilder, tableInfo, keys, columnByName, result);
+ }
+ OperationHistogram = &DbOperationsCounters->RequestBatchTimeHistogram;
+ }
+ }
+
+ void BuildAndRunProgram(const NActors::TActorContext& ctx) {
+ try {
+ const NMiniKQL::IFunctionRegistry& functionRegistry = *AppData(ctx)->FunctionRegistry;
TAlignedPagePoolCounters counters(AppData(ctx)->Counters, "build");
NMiniKQL::TScopedAlloc alloc(counters, functionRegistry.SupportsSizedAllocators());
NMiniKQL::TTypeEnvironment env(alloc);
NMiniKQL::TKikimrProgramBuilder pgmBuilder(env, functionRegistry);
- NMiniKQL::TRuntimeNode pgmReturn = pgmBuilder.NewEmptyListOfVoid();
+ NMiniKQL::TRuntimeNode pgmReturn = pgmBuilder.NewEmptyListOfVoid();
const NSchemeCache::TSchemeCacheNavigate::TEntry& tableInfo = CacheNavigate->ResultSet.front();
TVector<const NTxProxy::TTableColumnInfo*> keys;
THashMap<TString, const NTxProxy::TTableColumnInfo*> columnByName;
TVector<NMiniKQL::TRuntimeNode> result;
-
- // reordering key columns
- for (auto itCol = tableInfo.Columns.begin(); itCol != tableInfo.Columns.end(); ++itCol) {
- if (itCol->second.KeyOrder != -1/*key column*/) {
- if (keys.size() <= (std::size_t)itCol->second.KeyOrder)
- keys.resize(itCol->second.KeyOrder + 1);
- keys[itCol->second.KeyOrder] = &itCol->second;
- }
- columnByName[itCol->second.Name] = &itCol->second;
- }
-
- BuildProgram(JSON, pgmReturn, pgmBuilder, tableInfo, keys, columnByName, result);
- if (JSON.Has("Batch")) {
- pgmReturn = pgmBuilder.Append(pgmReturn, pgmBuilder.SetResult("Result", pgmBuilder.NewTuple(result)));
- } else {
- if (!result.empty()) {
- pgmReturn = pgmBuilder.Append(pgmReturn, pgmBuilder.SetResult("Result", result.front()));
- }
- }
-
- NMiniKQL::TRuntimeNode node = pgmBuilder.Build(pgmReturn);
+
+ // reordering key columns
+ for (auto itCol = tableInfo.Columns.begin(); itCol != tableInfo.Columns.end(); ++itCol) {
+ if (itCol->second.KeyOrder != -1/*key column*/) {
+ if (keys.size() <= (std::size_t)itCol->second.KeyOrder)
+ keys.resize(itCol->second.KeyOrder + 1);
+ keys[itCol->second.KeyOrder] = &itCol->second;
+ }
+ columnByName[itCol->second.Name] = &itCol->second;
+ }
+
+ BuildProgram(JSON, pgmReturn, pgmBuilder, tableInfo, keys, columnByName, result);
+ if (JSON.Has("Batch")) {
+ pgmReturn = pgmBuilder.Append(pgmReturn, pgmBuilder.SetResult("Result", pgmBuilder.NewTuple(result)));
+ } else {
+ if (!result.empty()) {
+ pgmReturn = pgmBuilder.Append(pgmReturn, pgmBuilder.SetResult("Result", result.front()));
+ }
+ }
+
+ NMiniKQL::TRuntimeNode node = pgmBuilder.Build(pgmReturn);
TString bin = NMiniKQL::SerializeRuntimeNode(node, env);
-
- DbOperationsCounters->RequestPrepareTimeHistogram.Add(StartTime.Passed() * 1000/*ms*/);
-
- TAutoPtr<TEvTxUserProxy::TEvProposeTransaction> Proposal(new TEvTxUserProxy::TEvProposeTransaction());
- NKikimrTxUserProxy::TEvProposeTransaction &record = Proposal->Record;
- //record.SetExecTimeoutPeriod(TDuration::Seconds(60));
- record.MutableTransaction()->MutableMiniKQLTransaction()->MutableProgram()->SetBin(bin);
- if (!UserToken.empty()) {
- record.SetUserToken(UserToken);
- }
+
+ DbOperationsCounters->RequestPrepareTimeHistogram.Add(StartTime.Passed() * 1000/*ms*/);
+
+ TAutoPtr<TEvTxUserProxy::TEvProposeTransaction> Proposal(new TEvTxUserProxy::TEvProposeTransaction());
+ NKikimrTxUserProxy::TEvProposeTransaction &record = Proposal->Record;
+ //record.SetExecTimeoutPeriod(TDuration::Seconds(60));
+ record.MutableTransaction()->MutableMiniKQLTransaction()->MutableProgram()->SetBin(bin);
+ if (!UserToken.empty()) {
+ record.SetUserToken(UserToken);
+ }
ctx.Send(TxProxyId, Proposal.Release());
- TBase::Become(&TThis::StateWaitExecute);
- }
- catch (yexception& e) {
- ReplyWithError(MSTATUS_ERROR, TEvTxUserProxy::TEvProposeTransactionStatus::EStatus::WrongRequest, e.what(), ctx);
- }
- }
-
- void Die(const TActorContext& ctx) override {
- TBase::Die(ctx);
- }
-
- void Bootstrap(const TActorContext& ctx) {
- if (!InterfaceBase::BootstrapJSON(&JSON, SecurityToken) || !JSON.IsDefined()) {
- return ReplyWithError(MSTATUS_ERROR, TEvTxUserProxy::TEvProposeTransactionStatus::EStatus::WrongRequest, "Failed to parse JSON", ctx);
- }
- NJson::TJsonValue jsonTable;
- if (JSON.GetValue("Table", &jsonTable) && jsonTable.IsString()) {
- Table = jsonTable.GetString();
- } else {
- return ReplyWithError(MSTATUS_ERROR, TEvTxUserProxy::TEvProposeTransactionStatus::EStatus::WrongRequest, "Table should be specified", ctx);
- }
+ TBase::Become(&TThis::StateWaitExecute);
+ }
+ catch (yexception& e) {
+ ReplyWithError(MSTATUS_ERROR, TEvTxUserProxy::TEvProposeTransactionStatus::EStatus::WrongRequest, e.what(), ctx);
+ }
+ }
+
+ void Die(const TActorContext& ctx) override {
+ TBase::Die(ctx);
+ }
+
+ void Bootstrap(const TActorContext& ctx) {
+ if (!InterfaceBase::BootstrapJSON(&JSON, SecurityToken) || !JSON.IsDefined()) {
+ return ReplyWithError(MSTATUS_ERROR, TEvTxUserProxy::TEvProposeTransactionStatus::EStatus::WrongRequest, "Failed to parse JSON", ctx);
+ }
+ NJson::TJsonValue jsonTable;
+ if (JSON.GetValue("Table", &jsonTable) && jsonTable.IsString()) {
+ Table = jsonTable.GetString();
+ } else {
+ return ReplyWithError(MSTATUS_ERROR, TEvTxUserProxy::TEvProposeTransactionStatus::EStatus::WrongRequest, "Table should be specified", ctx);
+ }
ResolveTable(Table, ctx);
- }
-};
-
-template <>
-TServerDbOperation<TMessageBusInterface<TBusDbOperation>>::TServerDbOperation(
+ }
+};
+
+template <>
+TServerDbOperation<TMessageBusInterface<TBusDbOperation>>::TServerDbOperation(
TBusMessageContext& msg, TActorId txProxyId, const TActorId& schemeCache, const TIntrusivePtr<TMessageBusDbOpsCounters>& dbOperationsCounters)
- : TMessageBusInterface<TBusDbOperation>(msg)
+ : TMessageBusInterface<TBusDbOperation>(msg)
, TxProxyId(txProxyId)
- , SchemeCache(schemeCache)
- , DbOperationsCounters(dbOperationsCounters)
- , OperationHistogram(nullptr)
-{}
-
-template <>
-TServerDbOperation<TActorInterface>::TServerDbOperation(
+ , SchemeCache(schemeCache)
+ , DbOperationsCounters(dbOperationsCounters)
+ , OperationHistogram(nullptr)
+{}
+
+template <>
+TServerDbOperation<TActorInterface>::TServerDbOperation(
const TActorId& hostActor,
- NJson::TJsonValue&& jsonValue,
- const TString& securityToken,
+ NJson::TJsonValue&& jsonValue,
+ const TString& securityToken,
TActorId txProxyId,
const TActorId& schemeCache,
- const TIntrusivePtr<TMessageBusDbOpsCounters>& dbOperationsCounters
- )
- : TActorInterface(hostActor)
+ const TIntrusivePtr<TMessageBusDbOpsCounters>& dbOperationsCounters
+ )
+ : TActorInterface(hostActor)
, TxProxyId(txProxyId)
- , SchemeCache(schemeCache)
- , DbOperationsCounters(dbOperationsCounters)
- , OperationHistogram(nullptr)
- , JSON(jsonValue)
- , SecurityToken(securityToken)
-{}
-
-template <typename InterfaceBase>
-class TServerDbSchema : public TActorBootstrapped<TServerDbSchema<InterfaceBase>>, public InterfaceBase {
-protected:
- using TThis = TServerDbSchema<InterfaceBase>;
- using TBase = TActorBootstrapped<TServerDbSchema<InterfaceBase>>;
- using TTabletId = ui64;
-
+ , SchemeCache(schemeCache)
+ , DbOperationsCounters(dbOperationsCounters)
+ , OperationHistogram(nullptr)
+ , JSON(jsonValue)
+ , SecurityToken(securityToken)
+{}
+
+template <typename InterfaceBase>
+class TServerDbSchema : public TActorBootstrapped<TServerDbSchema<InterfaceBase>>, public InterfaceBase {
+protected:
+ using TThis = TServerDbSchema<InterfaceBase>;
+ using TBase = TActorBootstrapped<TServerDbSchema<InterfaceBase>>;
+ using TTabletId = ui64;
+
TActorId TxProxyId;
- TIntrusivePtr<TMessageBusDbOpsCounters> DbOperationsCounters;
- NJson::TJsonValue JSON;
+ TIntrusivePtr<TMessageBusDbOpsCounters> DbOperationsCounters;
+ NJson::TJsonValue JSON;
THashMap<TTabletId, TActorId> Pipes;
TDeque<TAutoPtr<TEvTxUserProxy::TEvProposeTransaction>> Requests;
- THPTimer StartTime;
- TString SecurityToken;
- TString UserToken; // built and serialized
-
- void CompleteRequest(const TActorContext& ctx) {
- TDuration duration(TDuration::MicroSeconds(StartTime.Passed() * 1000000/*us*/));
- DbOperationsCounters->RequestSchemaTimeHistogram.Add(duration.MilliSeconds());
- DbOperationsCounters->RequestTotalTimeHistogram.Add(duration.MilliSeconds());
- Die(ctx);
- }
-
+ THPTimer StartTime;
+ TString SecurityToken;
+ TString UserToken; // built and serialized
+
+ void CompleteRequest(const TActorContext& ctx) {
+ TDuration duration(TDuration::MicroSeconds(StartTime.Passed() * 1000000/*us*/));
+ DbOperationsCounters->RequestSchemaTimeHistogram.Add(duration.MilliSeconds());
+ DbOperationsCounters->RequestTotalTimeHistogram.Add(duration.MilliSeconds());
+ Die(ctx);
+ }
+
void ReplyWithError(EResponseStatus status, TEvTxUserProxy::TResultStatus::EStatus proxyStatus, const TString& message, const TActorContext& ctx) {
- InterfaceBase::ReplyWithErrorToInterface(status, proxyStatus, message, ctx);
- CompleteRequest(ctx);
- }
-
+ InterfaceBase::ReplyWithErrorToInterface(status, proxyStatus, message, ctx);
+ CompleteRequest(ctx);
+ }
+
void ReplyWithError(EResponseStatus status, const TString& message, const TActorContext& ctx) {
- ReplyWithError(status, TEvTxUserProxy::TResultStatus::Unknown, message, ctx);
- }
-
- void ReplyWithError(EResponseStatus status, TEvTxUserProxy::TResultStatus::EStatus proxyStatus, const TActorContext& ctx) {
- ReplyWithError(status, proxyStatus, TEvTxUserProxy::TResultStatus::Str(proxyStatus), ctx);
- }
-
- void ReplyWithResult(EResponseStatus status, const NKikimrTxUserProxy::TEvProposeTransactionStatus& result, const TActorContext& ctx) {
- InterfaceBase::ReplyWithResultToInterface(status, result, ctx);
- CompleteRequest(ctx);
- }
-
- void ProcessRequests(const TActorContext& ctx) {
- if (Requests.empty()) {
- CompleteRequest(ctx);
- } else {
- SendNextRequest(ctx);
- }
- }
-
+ ReplyWithError(status, TEvTxUserProxy::TResultStatus::Unknown, message, ctx);
+ }
+
+ void ReplyWithError(EResponseStatus status, TEvTxUserProxy::TResultStatus::EStatus proxyStatus, const TActorContext& ctx) {
+ ReplyWithError(status, proxyStatus, TEvTxUserProxy::TResultStatus::Str(proxyStatus), ctx);
+ }
+
+ void ReplyWithResult(EResponseStatus status, const NKikimrTxUserProxy::TEvProposeTransactionStatus& result, const TActorContext& ctx) {
+ InterfaceBase::ReplyWithResultToInterface(status, result, ctx);
+ CompleteRequest(ctx);
+ }
+
+ void ProcessRequests(const TActorContext& ctx) {
+ if (Requests.empty()) {
+ CompleteRequest(ctx);
+ } else {
+ SendNextRequest(ctx);
+ }
+ }
+
void Handle(NSchemeShard::TEvSchemeShard::TEvNotifyTxCompletionRegistered::TPtr&, const TActorContext&) {
- }
-
+ }
+
void Handle(NSchemeShard::TEvSchemeShard::TEvNotifyTxCompletionResult::TPtr&, const TActorContext& ctx) {
- ProcessRequests(ctx);
- }
-
- void SendNextRequest(const TActorContext& ctx) {
+ ProcessRequests(ctx);
+ }
+
+ void SendNextRequest(const TActorContext& ctx) {
LOG_DEBUG_S(ctx, NKikimrServices::MSGBUS_PROXY,
"SendNextRequest proposal" <<
" to proxy#" << TxProxyId.ToString());
- TAutoPtr<TEvTxUserProxy::TEvProposeTransaction> proposal = Requests.front();
- Requests.pop_front();
+ TAutoPtr<TEvTxUserProxy::TEvProposeTransaction> proposal = Requests.front();
+ Requests.pop_front();
ctx.Send(TxProxyId, proposal.Release());
- }
-
- void Handle(TEvTxUserProxy::TEvProposeTransactionStatus::TPtr& ev, const TActorContext& ctx) {
- TEvTxUserProxy::TEvProposeTransactionStatus* msg = ev->Get();
- const TEvTxUserProxy::TEvProposeTransactionStatus::EStatus status = static_cast<TEvTxUserProxy::TEvProposeTransactionStatus::EStatus>(msg->Record.GetStatus());
- if (status == TEvTxUserProxy::TEvProposeTransactionStatus::EStatus::ExecInProgress) {
- TTabletId schemeShardId = msg->Record.GetSchemeShardTabletId();
+ }
+
+ void Handle(TEvTxUserProxy::TEvProposeTransactionStatus::TPtr& ev, const TActorContext& ctx) {
+ TEvTxUserProxy::TEvProposeTransactionStatus* msg = ev->Get();
+ const TEvTxUserProxy::TEvProposeTransactionStatus::EStatus status = static_cast<TEvTxUserProxy::TEvProposeTransactionStatus::EStatus>(msg->Record.GetStatus());
+ if (status == TEvTxUserProxy::TEvProposeTransactionStatus::EStatus::ExecInProgress) {
+ TTabletId schemeShardId = msg->Record.GetSchemeShardTabletId();
TActorId pipe;
- {
- auto itPipe = Pipes.find(schemeShardId);
- if (itPipe == Pipes.end()) {
- static NTabletPipe::TClientConfig clientConfig;
+ {
+ auto itPipe = Pipes.find(schemeShardId);
+ if (itPipe == Pipes.end()) {
+ static NTabletPipe::TClientConfig clientConfig;
pipe = ctx.RegisterWithSameMailbox(NTabletPipe::CreateClient(ctx.SelfID, schemeShardId, clientConfig));
- Pipes.emplace(schemeShardId, pipe);
- } else {
- pipe = itPipe->second;
- }
- }
+ Pipes.emplace(schemeShardId, pipe);
+ } else {
+ pipe = itPipe->second;
+ }
+ }
TAutoPtr<NSchemeShard::TEvSchemeShard::TEvNotifyTxCompletion> request(new NSchemeShard::TEvSchemeShard::TEvNotifyTxCompletion());
- request->Record.SetTxId(msg->Record.GetTxId());
+ request->Record.SetTxId(msg->Record.GetTxId());
LOG_DEBUG_S(ctx, NKikimrServices::MSGBUS_PROXY,
"HANDLE TEvProposeTransactionStatus" <<
" send to schemeShard tabletid#" << schemeShardId);
- NTabletPipe::SendData(ctx, pipe, request.Release());
- return;
- }
-
- if (status == TEvTxUserProxy::TEvProposeTransactionStatus::EStatus::ExecComplete
- || status == TEvTxUserProxy::TEvProposeTransactionStatus::EStatus::ExecAlready) {
- if (Requests.empty()) {
- ReplyWithResult(MSTATUS_OK, msg->Record, ctx);
- } else {
- SendNextRequest(ctx);
- }
- return;
- }
-
- switch (status) {
- case TEvTxUserProxy::TEvProposeTransactionStatus::EStatus::ProxyAccepted:
- case TEvTxUserProxy::TEvProposeTransactionStatus::EStatus::ProxyResolved:
- case TEvTxUserProxy::TEvProposeTransactionStatus::EStatus::ProxyPrepared:
- case TEvTxUserProxy::TEvProposeTransactionStatus::EStatus::CoordinatorPlanned:
- // transitional statuses
- return;
- case TEvTxUserProxy::TEvProposeTransactionStatus::EStatus::ExecTimeout:
- return ReplyWithResult(MSTATUS_INPROGRESS, msg->Record, ctx);
- case TEvTxUserProxy::TEvProposeTransactionStatus::EStatus::ProxyNotReady:
- return ReplyWithError(MSTATUS_NOTREADY, status, ctx);
- case TEvTxUserProxy::TEvProposeTransactionStatus::EStatus::ExecAborted:
- return ReplyWithError(MSTATUS_ABORTED, status, ctx);
- case TEvTxUserProxy::TEvProposeTransactionStatus::EStatus::EmptyAffectedSet:
- case TEvTxUserProxy::TEvProposeTransactionStatus::EStatus::ResolveError:
- case TEvTxUserProxy::TEvProposeTransactionStatus::EStatus::ExecError:
+ NTabletPipe::SendData(ctx, pipe, request.Release());
+ return;
+ }
+
+ if (status == TEvTxUserProxy::TEvProposeTransactionStatus::EStatus::ExecComplete
+ || status == TEvTxUserProxy::TEvProposeTransactionStatus::EStatus::ExecAlready) {
+ if (Requests.empty()) {
+ ReplyWithResult(MSTATUS_OK, msg->Record, ctx);
+ } else {
+ SendNextRequest(ctx);
+ }
+ return;
+ }
+
+ switch (status) {
+ case TEvTxUserProxy::TEvProposeTransactionStatus::EStatus::ProxyAccepted:
+ case TEvTxUserProxy::TEvProposeTransactionStatus::EStatus::ProxyResolved:
+ case TEvTxUserProxy::TEvProposeTransactionStatus::EStatus::ProxyPrepared:
+ case TEvTxUserProxy::TEvProposeTransactionStatus::EStatus::CoordinatorPlanned:
+ // transitional statuses
+ return;
+ case TEvTxUserProxy::TEvProposeTransactionStatus::EStatus::ExecTimeout:
+ return ReplyWithResult(MSTATUS_INPROGRESS, msg->Record, ctx);
+ case TEvTxUserProxy::TEvProposeTransactionStatus::EStatus::ProxyNotReady:
+ return ReplyWithError(MSTATUS_NOTREADY, status, ctx);
+ case TEvTxUserProxy::TEvProposeTransactionStatus::EStatus::ExecAborted:
+ return ReplyWithError(MSTATUS_ABORTED, status, ctx);
+ case TEvTxUserProxy::TEvProposeTransactionStatus::EStatus::EmptyAffectedSet:
+ case TEvTxUserProxy::TEvProposeTransactionStatus::EStatus::ResolveError:
+ case TEvTxUserProxy::TEvProposeTransactionStatus::EStatus::ExecError:
case TEvTxUserProxy::TEvProposeTransactionStatus::EStatus::WrongRequest:
- return ReplyWithResult(MSTATUS_ERROR, msg->Record, ctx);
- case TEvTxUserProxy::TEvProposeTransactionStatus::EStatus::ProxyShardNotAvailable:
- case TEvTxUserProxy::TEvProposeTransactionStatus::EStatus::ProxyShardTryLater:
- case TEvTxUserProxy::TEvProposeTransactionStatus::EStatus::ProxyShardOverloaded:
- return ReplyWithResult(MSTATUS_REJECTED, msg->Record, ctx);
+ return ReplyWithResult(MSTATUS_ERROR, msg->Record, ctx);
+ case TEvTxUserProxy::TEvProposeTransactionStatus::EStatus::ProxyShardNotAvailable:
+ case TEvTxUserProxy::TEvProposeTransactionStatus::EStatus::ProxyShardTryLater:
+ case TEvTxUserProxy::TEvProposeTransactionStatus::EStatus::ProxyShardOverloaded:
+ return ReplyWithResult(MSTATUS_REJECTED, msg->Record, ctx);
case TEvTxUserProxy::TEvProposeTransactionStatus::EStatus::ProxyShardUnknown:
return ReplyWithResult(MSTATUS_TIMEOUT, msg->Record, ctx);
- default:
- return ReplyWithResult(MSTATUS_INTERNALERROR, msg->Record, ctx);
- }
- }
-
- void Handle(TEvTicketParser::TEvAuthorizeTicketResult::TPtr &ev, const TActorContext &ctx) {
- const TEvTicketParser::TEvAuthorizeTicketResult& result(*ev->Get());
- if (!result.Error.empty()) {
- //return TBase::HandleError(EResponseStatus::MSTATUS_ERROR, TEvTxUserProxy::TEvProposeTransactionStatus::EStatus::AccessDenied, result.Error, ctx);
- } else {
- UserToken = result.SerializedToken;
- }
- BuildRequests(ctx);
- }
-
-public:
+ default:
+ return ReplyWithResult(MSTATUS_INTERNALERROR, msg->Record, ctx);
+ }
+ }
+
+ void Handle(TEvTicketParser::TEvAuthorizeTicketResult::TPtr &ev, const TActorContext &ctx) {
+ const TEvTicketParser::TEvAuthorizeTicketResult& result(*ev->Get());
+ if (!result.Error.empty()) {
+ //return TBase::HandleError(EResponseStatus::MSTATUS_ERROR, TEvTxUserProxy::TEvProposeTransactionStatus::EStatus::AccessDenied, result.Error, ctx);
+ } else {
+ UserToken = result.SerializedToken;
+ }
+ BuildRequests(ctx);
+ }
+
+public:
static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
return NKikimrServices::TActivity::MSGBUS_COMMON;
}
TServerDbSchema(TBusMessageContext &msg, TActorId txProxyId, const TIntrusivePtr<TMessageBusDbOpsCounters>& dbOperationsCounters);
-
- TServerDbSchema(
+
+ TServerDbSchema(
const TActorId& hostActor,
- NJson::TJsonValue&& jsonValue,
- const TString& securityToken,
+ NJson::TJsonValue&& jsonValue,
+ const TString& securityToken,
TActorId txProxyId,
- const TIntrusivePtr<TMessageBusDbOpsCounters>& dbOperationsCounters
- );
-
- void StateWork(TAutoPtr<NActors::IEventHandle>& ev, const NActors::TActorContext& ctx) {
- switch (ev->GetTypeRewrite()) {
- HFunc(TEvTxUserProxy::TEvProposeTransactionStatus, Handle);
- HFunc(TEvTicketParser::TEvAuthorizeTicketResult, Handle)
+ const TIntrusivePtr<TMessageBusDbOpsCounters>& dbOperationsCounters
+ );
+
+ void StateWork(TAutoPtr<NActors::IEventHandle>& ev, const NActors::TActorContext& ctx) {
+ switch (ev->GetTypeRewrite()) {
+ HFunc(TEvTxUserProxy::TEvProposeTransactionStatus, Handle);
+ HFunc(TEvTicketParser::TEvAuthorizeTicketResult, Handle)
HFunc(NSchemeShard::TEvSchemeShard::TEvNotifyTxCompletionRegistered, Handle);
HFunc(NSchemeShard::TEvSchemeShard::TEvNotifyTxCompletionResult, Handle);
- }
- }
-
- void Die(const TActorContext& ctx) override {
- for (auto it = Pipes.begin(); it != Pipes.end(); ++it) {
- NTabletPipe::CloseClient(ctx, it->second);
- }
- TBase::Die(ctx);
- }
-
- void Bootstrap(const TActorContext& ctx) {
- if (!InterfaceBase::BootstrapJSON(&JSON, SecurityToken) || !JSON.IsDefined()) {
- return ReplyWithError(MSTATUS_ERROR, TEvTxUserProxy::TEvProposeTransactionStatus::EStatus::WrongRequest, "Failed to parse JSON", ctx);
- }
- if (!SecurityToken.empty()) {
- ctx.Send(MakeTicketParserID(), new TEvTicketParser::TEvAuthorizeTicket(SecurityToken));
- } else {
- BuildRequests(ctx);
- }
- TBase::Become(&TThis::StateWork, ctx, Timeout, new TEvents::TEvWakeup());
- }
-
- void BuildRequests(const TActorContext& ctx) {
+ }
+ }
+
+ void Die(const TActorContext& ctx) override {
+ for (auto it = Pipes.begin(); it != Pipes.end(); ++it) {
+ NTabletPipe::CloseClient(ctx, it->second);
+ }
+ TBase::Die(ctx);
+ }
+
+ void Bootstrap(const TActorContext& ctx) {
+ if (!InterfaceBase::BootstrapJSON(&JSON, SecurityToken) || !JSON.IsDefined()) {
+ return ReplyWithError(MSTATUS_ERROR, TEvTxUserProxy::TEvProposeTransactionStatus::EStatus::WrongRequest, "Failed to parse JSON", ctx);
+ }
+ if (!SecurityToken.empty()) {
+ ctx.Send(MakeTicketParserID(), new TEvTicketParser::TEvAuthorizeTicket(SecurityToken));
+ } else {
+ BuildRequests(ctx);
+ }
+ TBase::Become(&TThis::StateWork, ctx, Timeout, new TEvents::TEvWakeup());
+ }
+
+ void BuildRequests(const TActorContext& ctx) {
TString path;
- NJson::TJsonValue jsonPath;
- if (JSON.GetValue("Path", &jsonPath)) {
- path = jsonPath.GetString();
- } else {
- return ReplyWithError(MSTATUS_ERROR, TEvTxUserProxy::TEvProposeTransactionStatus::EStatus::WrongRequest, "Path not found", ctx);
- }
-
- NJson::TJsonValue jsonDropTable;
- if (JSON.GetValue("DropTable", &jsonDropTable)) {
- if (jsonDropTable.IsArray()) {
- const NJson::TJsonValue::TArray& array = jsonDropTable.GetArray();
- for (const NJson::TJsonValue& value : array) {
- TAutoPtr<TEvTxUserProxy::TEvProposeTransaction> Proposal(new TEvTxUserProxy::TEvProposeTransaction());
+ NJson::TJsonValue jsonPath;
+ if (JSON.GetValue("Path", &jsonPath)) {
+ path = jsonPath.GetString();
+ } else {
+ return ReplyWithError(MSTATUS_ERROR, TEvTxUserProxy::TEvProposeTransactionStatus::EStatus::WrongRequest, "Path not found", ctx);
+ }
+
+ NJson::TJsonValue jsonDropTable;
+ if (JSON.GetValue("DropTable", &jsonDropTable)) {
+ if (jsonDropTable.IsArray()) {
+ const NJson::TJsonValue::TArray& array = jsonDropTable.GetArray();
+ for (const NJson::TJsonValue& value : array) {
+ TAutoPtr<TEvTxUserProxy::TEvProposeTransaction> Proposal(new TEvTxUserProxy::TEvProposeTransaction());
NKikimrSchemeOp::TModifyScheme& modifyScheme(*Proposal->Record.MutableTransaction()->MutableModifyScheme());
- modifyScheme.SetWorkingDir(path);
+ modifyScheme.SetWorkingDir(path);
modifyScheme.SetOperationType(NKikimrSchemeOp::EOperationType::ESchemeOpDropTable);
- modifyScheme.MutableDrop()->SetName(value.GetString());
- Requests.emplace_back(Proposal.Release());
- }
- } else {
- TAutoPtr<TEvTxUserProxy::TEvProposeTransaction> Proposal(new TEvTxUserProxy::TEvProposeTransaction());
+ modifyScheme.MutableDrop()->SetName(value.GetString());
+ Requests.emplace_back(Proposal.Release());
+ }
+ } else {
+ TAutoPtr<TEvTxUserProxy::TEvProposeTransaction> Proposal(new TEvTxUserProxy::TEvProposeTransaction());
NKikimrSchemeOp::TModifyScheme& modifyScheme(*Proposal->Record.MutableTransaction()->MutableModifyScheme());
- modifyScheme.SetWorkingDir(path);
+ modifyScheme.SetWorkingDir(path);
modifyScheme.SetOperationType(NKikimrSchemeOp::EOperationType::ESchemeOpDropTable);
- modifyScheme.MutableDrop()->SetName(jsonDropTable.GetString());
- Requests.emplace_back(Proposal.Release());
- }
- }
-
- NJson::TJsonValue jsonMkDir;
- if (JSON.GetValue("MkDir", &jsonMkDir)) {
- if (jsonMkDir.IsArray()) {
- const NJson::TJsonValue::TArray& array = jsonMkDir.GetArray();
- for (const NJson::TJsonValue& value : array) {
- TAutoPtr<TEvTxUserProxy::TEvProposeTransaction> Proposal(new TEvTxUserProxy::TEvProposeTransaction());
+ modifyScheme.MutableDrop()->SetName(jsonDropTable.GetString());
+ Requests.emplace_back(Proposal.Release());
+ }
+ }
+
+ NJson::TJsonValue jsonMkDir;
+ if (JSON.GetValue("MkDir", &jsonMkDir)) {
+ if (jsonMkDir.IsArray()) {
+ const NJson::TJsonValue::TArray& array = jsonMkDir.GetArray();
+ for (const NJson::TJsonValue& value : array) {
+ TAutoPtr<TEvTxUserProxy::TEvProposeTransaction> Proposal(new TEvTxUserProxy::TEvProposeTransaction());
NKikimrSchemeOp::TModifyScheme& modifyScheme(*Proposal->Record.MutableTransaction()->MutableModifyScheme());
- modifyScheme.SetWorkingDir(path);
+ modifyScheme.SetWorkingDir(path);
modifyScheme.SetOperationType(NKikimrSchemeOp::EOperationType::ESchemeOpMkDir);
- modifyScheme.MutableMkDir()->SetName(value.GetString());
- Requests.emplace_back(Proposal.Release());
- }
- } else {
- TAutoPtr<TEvTxUserProxy::TEvProposeTransaction> Proposal(new TEvTxUserProxy::TEvProposeTransaction());
+ modifyScheme.MutableMkDir()->SetName(value.GetString());
+ Requests.emplace_back(Proposal.Release());
+ }
+ } else {
+ TAutoPtr<TEvTxUserProxy::TEvProposeTransaction> Proposal(new TEvTxUserProxy::TEvProposeTransaction());
NKikimrSchemeOp::TModifyScheme& modifyScheme(*Proposal->Record.MutableTransaction()->MutableModifyScheme());
- modifyScheme.SetWorkingDir(path);
+ modifyScheme.SetWorkingDir(path);
modifyScheme.SetOperationType(NKikimrSchemeOp::EOperationType::ESchemeOpMkDir);
- modifyScheme.MutableMkDir()->SetName(jsonMkDir.GetString());
- Requests.emplace_back(Proposal.Release());
- }
- }
-
- NJson::TJsonValue jsonCreateTable;
- if (JSON.GetValue("CreateTable", &jsonCreateTable)) {
+ modifyScheme.MutableMkDir()->SetName(jsonMkDir.GetString());
+ Requests.emplace_back(Proposal.Release());
+ }
+ }
+
+ NJson::TJsonValue jsonCreateTable;
+ if (JSON.GetValue("CreateTable", &jsonCreateTable)) {
const NJson::TJsonValue::TMapType& jsonTables = jsonCreateTable.GetMap();
- for (auto itTable = jsonTables.begin(); itTable != jsonTables.end(); ++itTable) {
- TAutoPtr<TEvTxUserProxy::TEvProposeTransaction> Proposal(new TEvTxUserProxy::TEvProposeTransaction());
+ for (auto itTable = jsonTables.begin(); itTable != jsonTables.end(); ++itTable) {
+ TAutoPtr<TEvTxUserProxy::TEvProposeTransaction> Proposal(new TEvTxUserProxy::TEvProposeTransaction());
NKikimrSchemeOp::TModifyScheme& modifyScheme(*Proposal->Record.MutableTransaction()->MutableModifyScheme());
- modifyScheme.SetWorkingDir(path);
+ modifyScheme.SetWorkingDir(path);
modifyScheme.SetOperationType(NKikimrSchemeOp::EOperationType::ESchemeOpCreateTable);
NKikimrSchemeOp::TTableDescription& createTable(*modifyScheme.MutableCreateTable());
- createTable.SetName(itTable->first);
- // parsing CreateTable/<name>/Columns
- NJson::TJsonValue jsonColumn;
- if (itTable->second.GetValue("Columns", &jsonColumn)) {
+ createTable.SetName(itTable->first);
+ // parsing CreateTable/<name>/Columns
+ NJson::TJsonValue jsonColumn;
+ if (itTable->second.GetValue("Columns", &jsonColumn)) {
const NJson::TJsonValue::TMapType& jsonColumns = jsonColumn.GetMap();
- for (auto itColumn = jsonColumns.begin(); itColumn != jsonColumns.end(); ++itColumn) {
+ for (auto itColumn = jsonColumns.begin(); itColumn != jsonColumns.end(); ++itColumn) {
NKikimrSchemeOp::TColumnDescription& column(*createTable.AddColumns());
- column.SetName(itColumn->first);
- column.SetType(itColumn->second.GetString());
- }
- }
- // parsing CreateTable/<name>/Key
- NJson::TJsonValue jsonKey;
- if (itTable->second.GetValue("Key", &jsonKey)) {
- if (jsonKey.IsArray()) {
- const NJson::TJsonValue::TArray& array = jsonKey.GetArray();
- for (const NJson::TJsonValue& value : array) {
- createTable.AddKeyColumnNames(value.GetString());
- }
- } else {
- createTable.AddKeyColumnNames(jsonKey.GetString());
- }
- }
- // parsing CreateTable/<name>/Partitions
- NJson::TJsonValue jsonPartitions;
- if (itTable->second.GetValue("Partitions", &jsonPartitions)) {
- createTable.SetUniformPartitionsCount(jsonPartitions.GetUInteger());
- }
- // parsing CreateTable/<name>/PartitionConfig
- try {
- NJson::TJsonValue jsonPartitionConfig;
- if (itTable->second.GetValue("PartitionConfig", &jsonPartitionConfig)) {
- NProtobufJson::Json2Proto(jsonPartitionConfig, *createTable.MutablePartitionConfig());
- }
- Requests.emplace_back(Proposal.Release());
- } catch(const yexception&) {
- // Json2Proto throws exception on invalid json
- }
- }
- }
-
- DbOperationsCounters->RequestPrepareTimeHistogram.Add(StartTime.Passed() * 1000/*ms*/);
- if (Requests.empty()) {
- return ReplyWithError(MSTATUS_ERROR, TEvTxUserProxy::TEvProposeTransactionStatus::EStatus::WrongRequest, "No valid operations were found", ctx);
- }
+ column.SetName(itColumn->first);
+ column.SetType(itColumn->second.GetString());
+ }
+ }
+ // parsing CreateTable/<name>/Key
+ NJson::TJsonValue jsonKey;
+ if (itTable->second.GetValue("Key", &jsonKey)) {
+ if (jsonKey.IsArray()) {
+ const NJson::TJsonValue::TArray& array = jsonKey.GetArray();
+ for (const NJson::TJsonValue& value : array) {
+ createTable.AddKeyColumnNames(value.GetString());
+ }
+ } else {
+ createTable.AddKeyColumnNames(jsonKey.GetString());
+ }
+ }
+ // parsing CreateTable/<name>/Partitions
+ NJson::TJsonValue jsonPartitions;
+ if (itTable->second.GetValue("Partitions", &jsonPartitions)) {
+ createTable.SetUniformPartitionsCount(jsonPartitions.GetUInteger());
+ }
+ // parsing CreateTable/<name>/PartitionConfig
+ try {
+ NJson::TJsonValue jsonPartitionConfig;
+ if (itTable->second.GetValue("PartitionConfig", &jsonPartitionConfig)) {
+ NProtobufJson::Json2Proto(jsonPartitionConfig, *createTable.MutablePartitionConfig());
+ }
+ Requests.emplace_back(Proposal.Release());
+ } catch(const yexception&) {
+ // Json2Proto throws exception on invalid json
+ }
+ }
+ }
+
+ DbOperationsCounters->RequestPrepareTimeHistogram.Add(StartTime.Passed() * 1000/*ms*/);
+ if (Requests.empty()) {
+ return ReplyWithError(MSTATUS_ERROR, TEvTxUserProxy::TEvProposeTransactionStatus::EStatus::WrongRequest, "No valid operations were found", ctx);
+ }
ProcessRequests(ctx);
- }
-};
-
-template <>
-TServerDbSchema<TMessageBusInterface<TBusDbSchema>>::TServerDbSchema(
+ }
+};
+
+template <>
+TServerDbSchema<TMessageBusInterface<TBusDbSchema>>::TServerDbSchema(
TBusMessageContext &msg, TActorId txProxyId, const TIntrusivePtr<TMessageBusDbOpsCounters>& dbOperationsCounters)
- : TMessageBusInterface<TBusDbSchema>(msg)
+ : TMessageBusInterface<TBusDbSchema>(msg)
, TxProxyId(txProxyId)
- , DbOperationsCounters(dbOperationsCounters)
-{}
-
-template <>
-TServerDbSchema<TActorInterface>::TServerDbSchema(
+ , DbOperationsCounters(dbOperationsCounters)
+{}
+
+template <>
+TServerDbSchema<TActorInterface>::TServerDbSchema(
const TActorId& hostActor,
- NJson::TJsonValue&& jsonValue,
- const TString& securityToken,
+ NJson::TJsonValue&& jsonValue,
+ const TString& securityToken,
TActorId txProxyId,
- const TIntrusivePtr<TMessageBusDbOpsCounters>& dbOperationsCounters
- )
- : TActorInterface(hostActor)
+ const TIntrusivePtr<TMessageBusDbOpsCounters>& dbOperationsCounters
+ )
+ : TActorInterface(hostActor)
, TxProxyId(txProxyId)
- , DbOperationsCounters(dbOperationsCounters)
- , JSON(jsonValue)
- , SecurityToken(securityToken)
-{}
-
-template <typename InterfaceBase>
-class TServerDbBatch : public TActorBootstrapped<TServerDbBatch<InterfaceBase>>, public InterfaceBase {
-protected:
- using TThis = TServerDbBatch<InterfaceBase>;
- using TBase = TActorBootstrapped<TServerDbBatch<InterfaceBase>>;
- using TTabletId = ui64;
-
+ , DbOperationsCounters(dbOperationsCounters)
+ , JSON(jsonValue)
+ , SecurityToken(securityToken)
+{}
+
+template <typename InterfaceBase>
+class TServerDbBatch : public TActorBootstrapped<TServerDbBatch<InterfaceBase>>, public InterfaceBase {
+protected:
+ using TThis = TServerDbBatch<InterfaceBase>;
+ using TBase = TActorBootstrapped<TServerDbBatch<InterfaceBase>>;
+ using TTabletId = ui64;
+
TActorId TxProxyId;
TActorId SchemeCache;
- TIntrusivePtr<TMessageBusDbOpsCounters> DbOperationsCounters;
- NJson::TJsonValue JSON;
+ TIntrusivePtr<TMessageBusDbOpsCounters> DbOperationsCounters;
+ NJson::TJsonValue JSON;
TDeque<TAutoPtr<IActor>> Operations;
TDeque<TAutoPtr<TEvPrivate::TEvReply>> Replies;
- int MaxInFlight;
- int CurrentInFlight;
- TString SecurityToken;
-
- void CompleteRequest(const TActorContext& ctx) {
- TBase::Die(ctx);
- }
-
+ int MaxInFlight;
+ int CurrentInFlight;
+ TString SecurityToken;
+
+ void CompleteRequest(const TActorContext& ctx) {
+ TBase::Die(ctx);
+ }
+
void ReplyWithError(EResponseStatus status, TEvTxUserProxy::TResultStatus::EStatus proxyStatus, const TString& message, const TActorContext& ctx) {
- InterfaceBase::ReplyWithErrorToInterface(status, proxyStatus, message, ctx);
- CompleteRequest(ctx);
- }
-
+ InterfaceBase::ReplyWithErrorToInterface(status, proxyStatus, message, ctx);
+ CompleteRequest(ctx);
+ }
+
void ReplyWithError(EResponseStatus status, const TString& message, const TActorContext& ctx) {
- ReplyWithError(status, TEvTxUserProxy::TResultStatus::Unknown, message, ctx);
- }
-
- void ReplyWithError(EResponseStatus status, TEvTxUserProxy::TResultStatus::EStatus proxyStatus, const TActorContext& ctx) {
- ReplyWithError(status, proxyStatus, TEvTxUserProxy::TResultStatus::Str(proxyStatus), ctx);
- }
-
- void ReplyWithResult(EResponseStatus status, const NKikimrTxUserProxy::TEvProposeTransactionStatus& result, const TActorContext& ctx) {
- InterfaceBase::ReplyWithResultToInterface(status, result, ctx);
- CompleteRequest(ctx);
- }
-
- void ProcessOperations(const TActorContext& ctx) {
- if (!Operations.empty()) {
- RunNextOperation(ctx);
- }
- }
-
- void RunNextOperation(const TActorContext& ctx) {
- if (CurrentInFlight < MaxInFlight) {
- TAutoPtr<IActor> operation = Operations.front();
- Operations.pop_front();
- ctx.Register(operation.Release());
- ++CurrentInFlight;
- }
- }
-
- void Handle(TEvPrivate::TEvReply::TPtr& ev, const TActorContext& ctx) {
- Replies.emplace_back(ev->Release());
- --CurrentInFlight;
- ProcessOperations(ctx);
- if (CurrentInFlight == 0) {
- NKikimrTxUserProxy::TEvProposeTransactionStatus mergedResult;
- EResponseStatus status = MSTATUS_OK;
+ ReplyWithError(status, TEvTxUserProxy::TResultStatus::Unknown, message, ctx);
+ }
+
+ void ReplyWithError(EResponseStatus status, TEvTxUserProxy::TResultStatus::EStatus proxyStatus, const TActorContext& ctx) {
+ ReplyWithError(status, proxyStatus, TEvTxUserProxy::TResultStatus::Str(proxyStatus), ctx);
+ }
+
+ void ReplyWithResult(EResponseStatus status, const NKikimrTxUserProxy::TEvProposeTransactionStatus& result, const TActorContext& ctx) {
+ InterfaceBase::ReplyWithResultToInterface(status, result, ctx);
+ CompleteRequest(ctx);
+ }
+
+ void ProcessOperations(const TActorContext& ctx) {
+ if (!Operations.empty()) {
+ RunNextOperation(ctx);
+ }
+ }
+
+ void RunNextOperation(const TActorContext& ctx) {
+ if (CurrentInFlight < MaxInFlight) {
+ TAutoPtr<IActor> operation = Operations.front();
+ Operations.pop_front();
+ ctx.Register(operation.Release());
+ ++CurrentInFlight;
+ }
+ }
+
+ void Handle(TEvPrivate::TEvReply::TPtr& ev, const TActorContext& ctx) {
+ Replies.emplace_back(ev->Release());
+ --CurrentInFlight;
+ ProcessOperations(ctx);
+ if (CurrentInFlight == 0) {
+ NKikimrTxUserProxy::TEvProposeTransactionStatus mergedResult;
+ EResponseStatus status = MSTATUS_OK;
TString message;
- for (const TAutoPtr<TEvPrivate::TEvReply>& reply : Replies) {
- if (status == MSTATUS_OK && reply->Status != MSTATUS_OK) {
- status = reply->Status;
- message = reply->Message;
- }
- mergedResult.MergeFrom(reply->Result);
- }
- if (status != MSTATUS_OK) {
- ReplyWithError(status, TEvTxUserProxy::TResultStatus::Unknown, message, ctx);
- } else {
- ReplyWithResult(status, mergedResult, ctx);
- }
- }
- }
-
-public:
+ for (const TAutoPtr<TEvPrivate::TEvReply>& reply : Replies) {
+ if (status == MSTATUS_OK && reply->Status != MSTATUS_OK) {
+ status = reply->Status;
+ message = reply->Message;
+ }
+ mergedResult.MergeFrom(reply->Result);
+ }
+ if (status != MSTATUS_OK) {
+ ReplyWithError(status, TEvTxUserProxy::TResultStatus::Unknown, message, ctx);
+ } else {
+ ReplyWithResult(status, mergedResult, ctx);
+ }
+ }
+ }
+
+public:
static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
return NKikimrServices::TActivity::MSGBUS_COMMON;
}
TServerDbBatch(TBusMessageContext &msg, const TActorId txProxyId, const TActorId& schemeCache, const TIntrusivePtr<TMessageBusDbOpsCounters>& dbOperationsCounters);
-
- void HandleTimeout(const TActorContext& ctx) {
- return ReplyWithError(MSTATUS_TIMEOUT, "Request timed out", ctx);
- }
-
- void StateWork(TAutoPtr<NActors::IEventHandle>& ev, const NActors::TActorContext& ctx) {
- switch (ev->GetTypeRewrite()) {
- HFunc(TEvPrivate::TEvReply, Handle);
- }
- }
-
- void Bootstrap(const TActorContext& ctx) {
- if (!InterfaceBase::BootstrapJSON(&JSON, SecurityToken) || !JSON.IsDefined()) {
- return ReplyWithError(MSTATUS_ERROR, TEvTxUserProxy::TEvProposeTransactionStatus::EStatus::WrongRequest, "Failed to parse JSON", ctx);
- }
- NJson::TJsonValue jsonOperations;
- if (JSON.GetValue("Operations", &jsonOperations)) {
- NJson::TJsonValue::TArray& array = jsonOperations.GetArraySafe();
- for (NJson::TJsonValue& value : array) {
- if (value.IsMap()) {
- if (value.Has("Path")) {
- Operations.emplace_back(new TServerDbSchema<TActorInterface>(
- ctx.SelfID,
- std::move(value),
- SecurityToken,
- TxProxyId,
- DbOperationsCounters
- ));
- } else {
- Operations.emplace_back(new TServerDbOperation<TActorInterface>(
- ctx.SelfID,
- std::move(value),
- SecurityToken,
- TxProxyId,
- SchemeCache,
- DbOperationsCounters
- ));
- }
- }
- }
- }
- TBase::Become(&TThis::StateWork);
- ProcessOperations(ctx);
- }
-};
-
-template <>
-TServerDbBatch<TMessageBusInterface<TBusDbBatch>>::TServerDbBatch(
+
+ void HandleTimeout(const TActorContext& ctx) {
+ return ReplyWithError(MSTATUS_TIMEOUT, "Request timed out", ctx);
+ }
+
+ void StateWork(TAutoPtr<NActors::IEventHandle>& ev, const NActors::TActorContext& ctx) {
+ switch (ev->GetTypeRewrite()) {
+ HFunc(TEvPrivate::TEvReply, Handle);
+ }
+ }
+
+ void Bootstrap(const TActorContext& ctx) {
+ if (!InterfaceBase::BootstrapJSON(&JSON, SecurityToken) || !JSON.IsDefined()) {
+ return ReplyWithError(MSTATUS_ERROR, TEvTxUserProxy::TEvProposeTransactionStatus::EStatus::WrongRequest, "Failed to parse JSON", ctx);
+ }
+ NJson::TJsonValue jsonOperations;
+ if (JSON.GetValue("Operations", &jsonOperations)) {
+ NJson::TJsonValue::TArray& array = jsonOperations.GetArraySafe();
+ for (NJson::TJsonValue& value : array) {
+ if (value.IsMap()) {
+ if (value.Has("Path")) {
+ Operations.emplace_back(new TServerDbSchema<TActorInterface>(
+ ctx.SelfID,
+ std::move(value),
+ SecurityToken,
+ TxProxyId,
+ DbOperationsCounters
+ ));
+ } else {
+ Operations.emplace_back(new TServerDbOperation<TActorInterface>(
+ ctx.SelfID,
+ std::move(value),
+ SecurityToken,
+ TxProxyId,
+ SchemeCache,
+ DbOperationsCounters
+ ));
+ }
+ }
+ }
+ }
+ TBase::Become(&TThis::StateWork);
+ ProcessOperations(ctx);
+ }
+};
+
+template <>
+TServerDbBatch<TMessageBusInterface<TBusDbBatch>>::TServerDbBatch(
TBusMessageContext &msg, TActorId txProxyId, const TActorId& schemeCache, const TIntrusivePtr<TMessageBusDbOpsCounters>& dbOperationsCounters)
- : TMessageBusInterface<TBusDbBatch>(msg)
+ : TMessageBusInterface<TBusDbBatch>(msg)
, TxProxyId(txProxyId)
- , SchemeCache(schemeCache)
- , DbOperationsCounters(dbOperationsCounters)
- , MaxInFlight(1)
- , CurrentInFlight(0)
-{}
-
-void TMessageBusServerProxy::Handle(TEvBusProxy::TEvDbSchema::TPtr& ev, const TActorContext& ctx) {
- TEvBusProxy::TEvDbSchema* msg = ev->Get();
+ , SchemeCache(schemeCache)
+ , DbOperationsCounters(dbOperationsCounters)
+ , MaxInFlight(1)
+ , CurrentInFlight(0)
+{}
+
+void TMessageBusServerProxy::Handle(TEvBusProxy::TEvDbSchema::TPtr& ev, const TActorContext& ctx) {
+ TEvBusProxy::TEvDbSchema* msg = ev->Get();
LOG_DEBUG_S(ctx, NKikimrServices::MSGBUS_PROXY,
" actor# "<< ctx.SelfID.ToString() <<
" HANDLE TEvDbSchema");
auto* requestActor = new TServerDbSchema<TMessageBusInterface<TBusDbSchema>>(msg->MsgContext, TxProxy, DbOperationsCounters);
ctx.Register(requestActor);
-}
-
-void TMessageBusServerProxy::Handle(TEvBusProxy::TEvDbOperation::TPtr& ev, const TActorContext& ctx) {
- TEvBusProxy::TEvDbOperation* msg = ev->Get();
+}
+
+void TMessageBusServerProxy::Handle(TEvBusProxy::TEvDbOperation::TPtr& ev, const TActorContext& ctx) {
+ TEvBusProxy::TEvDbOperation* msg = ev->Get();
auto* requestActor = new TServerDbOperation<TMessageBusInterface<TBusDbOperation>>(msg->MsgContext, TxProxy, SchemeCache, DbOperationsCounters);
ctx.Register(requestActor);
-}
-
-void TMessageBusServerProxy::Handle(TEvBusProxy::TEvDbBatch::TPtr& ev, const TActorContext& ctx) {
- TEvBusProxy::TEvDbBatch* msg = ev->Get();
+}
+
+void TMessageBusServerProxy::Handle(TEvBusProxy::TEvDbBatch::TPtr& ev, const TActorContext& ctx) {
+ TEvBusProxy::TEvDbBatch* msg = ev->Get();
auto* requestActor = new TServerDbBatch<TMessageBusInterface<TBusDbBatch>>(msg->MsgContext, TxProxy, SchemeCache, DbOperationsCounters);
ctx.Register(requestActor);
-}
-
-}
-}
+}
+
+}
+}
diff --git a/ydb/core/client/server/msgbus_server_drain_node.cpp b/ydb/core/client/server/msgbus_server_drain_node.cpp
index 65290c84c4a..a91e7e1f810 100644
--- a/ydb/core/client/server/msgbus_server_drain_node.cpp
+++ b/ydb/core/client/server/msgbus_server_drain_node.cpp
@@ -1,57 +1,57 @@
#include <ydb/core/base/hive.h>
-#include "msgbus_tabletreq.h"
-#include "msgbus_securereq.h"
-
-namespace NKikimr {
-namespace NMsgBusProxy {
-
-class TMessageBusDrainNode : public TMessageBusSecureRequest<TMessageBusTabletRequest<TMessageBusDrainNode, TEvHive::TEvDrainNodeResult>> {
- THolder<TBusDrainNode> Request;
- ui32 NodeId;
-public:
- static ui64 GetHiveTabletId(const TActorContext& ctx) {
- TDomainsInfo* domainsInfo = AppData(ctx)->DomainsInfo.Get();
- auto hiveTabletId = domainsInfo->GetHive(domainsInfo->GetDefaultHiveUid(domainsInfo->Domains.begin()->first));
- return hiveTabletId;
- }
-
- TMessageBusDrainNode(TBusMessageContext& msg)
- : TMessageBusSecureRequest(msg, true, TDuration::Minutes(30), false)
- , Request(static_cast<TBusDrainNode*>(msg.ReleaseMessage()))
- , NodeId(Request->Record.GetNodeID())
- {
- SetSecurityToken(Request->Record.GetSecurityToken());
- SetRequireAdminAccess(true);
- }
-
- std::pair<ui64, TAutoPtr<IEventBase>> MakeReqPair(const TActorContext& ctx) {
- ui64 TabletId = GetHiveTabletId(ctx);
- return std::make_pair(TabletId, new TEvHive::TEvDrainNode(NodeId));
- }
-
- void Handle(TEvHive::TEvDrainNodeResult::TPtr& ev, const TActorContext& ctx) {
- NMsgBusProxy::EResponseStatus status;
- switch (ev->Get()->Record.GetStatus()) {
- case NKikimrProto::OK:
- status = MSTATUS_OK;
- break;
- case NKikimrProto::ERROR:
- status = MSTATUS_ERROR;
- break;
- case NKikimrProto::TIMEOUT:
- status = MSTATUS_TIMEOUT;
- break;
- default:
- status = MSTATUS_INTERNALERROR;
- break;
- }
- return SendReplyAndDie(new TBusResponseStatus(status), ctx);
- }
-};
-
-IActor* CreateMessageBusDrainNode(TBusMessageContext& msg) {
- return new TMessageBusDrainNode(msg);
-}
-
-}
-}
+#include "msgbus_tabletreq.h"
+#include "msgbus_securereq.h"
+
+namespace NKikimr {
+namespace NMsgBusProxy {
+
+class TMessageBusDrainNode : public TMessageBusSecureRequest<TMessageBusTabletRequest<TMessageBusDrainNode, TEvHive::TEvDrainNodeResult>> {
+ THolder<TBusDrainNode> Request;
+ ui32 NodeId;
+public:
+ static ui64 GetHiveTabletId(const TActorContext& ctx) {
+ TDomainsInfo* domainsInfo = AppData(ctx)->DomainsInfo.Get();
+ auto hiveTabletId = domainsInfo->GetHive(domainsInfo->GetDefaultHiveUid(domainsInfo->Domains.begin()->first));
+ return hiveTabletId;
+ }
+
+ TMessageBusDrainNode(TBusMessageContext& msg)
+ : TMessageBusSecureRequest(msg, true, TDuration::Minutes(30), false)
+ , Request(static_cast<TBusDrainNode*>(msg.ReleaseMessage()))
+ , NodeId(Request->Record.GetNodeID())
+ {
+ SetSecurityToken(Request->Record.GetSecurityToken());
+ SetRequireAdminAccess(true);
+ }
+
+ std::pair<ui64, TAutoPtr<IEventBase>> MakeReqPair(const TActorContext& ctx) {
+ ui64 TabletId = GetHiveTabletId(ctx);
+ return std::make_pair(TabletId, new TEvHive::TEvDrainNode(NodeId));
+ }
+
+ void Handle(TEvHive::TEvDrainNodeResult::TPtr& ev, const TActorContext& ctx) {
+ NMsgBusProxy::EResponseStatus status;
+ switch (ev->Get()->Record.GetStatus()) {
+ case NKikimrProto::OK:
+ status = MSTATUS_OK;
+ break;
+ case NKikimrProto::ERROR:
+ status = MSTATUS_ERROR;
+ break;
+ case NKikimrProto::TIMEOUT:
+ status = MSTATUS_TIMEOUT;
+ break;
+ default:
+ status = MSTATUS_INTERNALERROR;
+ break;
+ }
+ return SendReplyAndDie(new TBusResponseStatus(status), ctx);
+ }
+};
+
+IActor* CreateMessageBusDrainNode(TBusMessageContext& msg) {
+ return new TMessageBusDrainNode(msg);
+}
+
+}
+}
diff --git a/ydb/core/client/server/msgbus_server_fill_node.cpp b/ydb/core/client/server/msgbus_server_fill_node.cpp
index 6852411023f..ed4658e77f0 100644
--- a/ydb/core/client/server/msgbus_server_fill_node.cpp
+++ b/ydb/core/client/server/msgbus_server_fill_node.cpp
@@ -1,57 +1,57 @@
#include <ydb/core/base/hive.h>
-#include "msgbus_tabletreq.h"
-#include "msgbus_securereq.h"
-
-namespace NKikimr {
-namespace NMsgBusProxy {
-
-class TMessageBusFillNode : public TMessageBusSecureRequest<TMessageBusTabletRequest<TMessageBusFillNode, TEvHive::TEvFillNodeResult>> {
- THolder<TBusFillNode> Request;
- ui32 NodeId;
-public:
- static ui64 GetHiveTabletId(const TActorContext& ctx) {
- TDomainsInfo* domainsInfo = AppData(ctx)->DomainsInfo.Get();
- auto hiveTabletId = domainsInfo->GetHive(domainsInfo->GetDefaultHiveUid(domainsInfo->Domains.begin()->first));
- return hiveTabletId;
- }
-
- TMessageBusFillNode(TBusMessageContext& msg)
- : TMessageBusSecureRequest(msg, true, TDuration::Minutes(30), false)
- , Request(static_cast<TBusFillNode*>(msg.ReleaseMessage()))
- , NodeId(Request->Record.GetNodeID())
- {
- SetSecurityToken(Request->Record.GetSecurityToken());
- SetRequireAdminAccess(true);
- }
-
- std::pair<ui64, TAutoPtr<IEventBase>> MakeReqPair(const TActorContext& ctx) {
- ui64 TabletId = GetHiveTabletId(ctx);
- return std::make_pair(TabletId, new TEvHive::TEvFillNode(NodeId));
- }
-
- void Handle(TEvHive::TEvFillNodeResult::TPtr& ev, const TActorContext& ctx) {
- NMsgBusProxy::EResponseStatus status;
- switch (ev->Get()->Record.GetStatus()) {
- case NKikimrProto::OK:
- status = MSTATUS_OK;
- break;
- case NKikimrProto::ERROR:
- status = MSTATUS_ERROR;
- break;
- case NKikimrProto::TIMEOUT:
- status = MSTATUS_TIMEOUT;
- break;
- default:
- status = MSTATUS_INTERNALERROR;
- break;
- }
- return SendReplyAndDie(new TBusResponseStatus(status), ctx);
- }
-};
-
-IActor* CreateMessageBusFillNode(TBusMessageContext& msg) {
- return new TMessageBusFillNode(msg);
-}
-
-}
-}
+#include "msgbus_tabletreq.h"
+#include "msgbus_securereq.h"
+
+namespace NKikimr {
+namespace NMsgBusProxy {
+
+class TMessageBusFillNode : public TMessageBusSecureRequest<TMessageBusTabletRequest<TMessageBusFillNode, TEvHive::TEvFillNodeResult>> {
+ THolder<TBusFillNode> Request;
+ ui32 NodeId;
+public:
+ static ui64 GetHiveTabletId(const TActorContext& ctx) {
+ TDomainsInfo* domainsInfo = AppData(ctx)->DomainsInfo.Get();
+ auto hiveTabletId = domainsInfo->GetHive(domainsInfo->GetDefaultHiveUid(domainsInfo->Domains.begin()->first));
+ return hiveTabletId;
+ }
+
+ TMessageBusFillNode(TBusMessageContext& msg)
+ : TMessageBusSecureRequest(msg, true, TDuration::Minutes(30), false)
+ , Request(static_cast<TBusFillNode*>(msg.ReleaseMessage()))
+ , NodeId(Request->Record.GetNodeID())
+ {
+ SetSecurityToken(Request->Record.GetSecurityToken());
+ SetRequireAdminAccess(true);
+ }
+
+ std::pair<ui64, TAutoPtr<IEventBase>> MakeReqPair(const TActorContext& ctx) {
+ ui64 TabletId = GetHiveTabletId(ctx);
+ return std::make_pair(TabletId, new TEvHive::TEvFillNode(NodeId));
+ }
+
+ void Handle(TEvHive::TEvFillNodeResult::TPtr& ev, const TActorContext& ctx) {
+ NMsgBusProxy::EResponseStatus status;
+ switch (ev->Get()->Record.GetStatus()) {
+ case NKikimrProto::OK:
+ status = MSTATUS_OK;
+ break;
+ case NKikimrProto::ERROR:
+ status = MSTATUS_ERROR;
+ break;
+ case NKikimrProto::TIMEOUT:
+ status = MSTATUS_TIMEOUT;
+ break;
+ default:
+ status = MSTATUS_INTERNALERROR;
+ break;
+ }
+ return SendReplyAndDie(new TBusResponseStatus(status), ctx);
+ }
+};
+
+IActor* CreateMessageBusFillNode(TBusMessageContext& msg) {
+ return new TMessageBusFillNode(msg);
+}
+
+}
+}
diff --git a/ydb/core/client/server/msgbus_server_hive_create_tablet.cpp b/ydb/core/client/server/msgbus_server_hive_create_tablet.cpp
index 42a7d1726e1..0c41e53f090 100644
--- a/ydb/core/client/server/msgbus_server_hive_create_tablet.cpp
+++ b/ydb/core/client/server/msgbus_server_hive_create_tablet.cpp
@@ -12,17 +12,17 @@ namespace {
const ui32 DefaultTimeout = 90000;
}
-template <typename ResponseType>
+template <typename ResponseType>
class TMessageBusHiveCreateTablet
- : public TActorBootstrapped<TMessageBusHiveCreateTablet<ResponseType>>
+ : public TActorBootstrapped<TMessageBusHiveCreateTablet<ResponseType>>
, public TMessageBusSessionIdentHolder {
-using TBase = TActorBootstrapped<TMessageBusHiveCreateTablet<ResponseType>>;
+using TBase = TActorBootstrapped<TMessageBusHiveCreateTablet<ResponseType>>;
struct TRequest {
- TEvHive::EEv Event;
+ TEvHive::EEv Event;
ui64 OwnerId;
ui64 OwnerIdx;
- TTabletTypes::EType TabletType;
+ TTabletTypes::EType TabletType;
TVector<ui32> AllowedNodeIDs;
TVector<TSubDomainKey> AllowedDomains;
TChannelsBindings BindedChannels;
@@ -30,12 +30,12 @@ using TBase = TActorBootstrapped<TMessageBusHiveCreateTablet<ResponseType>>;
NKikimrProto::EReplyStatus Status;
ui64 TabletId;
- TRequest(ui64 ownerId, ui64 ownerIdx, TTabletTypes::EType tabletType,
+ TRequest(ui64 ownerId, ui64 ownerIdx, TTabletTypes::EType tabletType,
TVector<ui32> allowedNodeIDs,
TVector<TSubDomainKey> allowedDomains,
TChannelsBindings bindedChannels)
- : Event(TEvHive::EvCreateTablet)
- , OwnerId(ownerId)
+ : Event(TEvHive::EvCreateTablet)
+ , OwnerId(ownerId)
, OwnerIdx(ownerIdx)
, TabletType(tabletType)
, AllowedNodeIDs(std::move(allowedNodeIDs))
@@ -44,15 +44,15 @@ using TBase = TActorBootstrapped<TMessageBusHiveCreateTablet<ResponseType>>;
, Status(NKikimrProto::UNKNOWN)
, TabletId(0)
{}
-
- TRequest(ui64 ownerId, ui64 ownerIdx)
- : Event(TEvHive::EvLookupTablet)
- , OwnerId(ownerId)
- , OwnerIdx(ownerIdx)
- , TabletType()
- , Status(NKikimrProto::UNKNOWN)
- , TabletId(0)
- {}
+
+ TRequest(ui64 ownerId, ui64 ownerIdx)
+ : Event(TEvHive::EvLookupTablet)
+ , OwnerId(ownerId)
+ , OwnerIdx(ownerIdx)
+ , TabletType()
+ , Status(NKikimrProto::UNKNOWN)
+ , TabletId(0)
+ {}
};
TDuration Timeout;
@@ -69,7 +69,7 @@ public:
return NKikimrServices::TActivity::MSGBUS_COMMON;
}
- TMessageBusHiveCreateTablet(TBusMessageContext &msg)
+ TMessageBusHiveCreateTablet(TBusMessageContext &msg)
: TMessageBusSessionIdentHolder(msg)
, Status(NKikimrProto::UNKNOWN)
, ResponsesReceived(0)
@@ -82,9 +82,9 @@ public:
for (ui32 i = 0; i < cmdCount; ++i) {
const auto &cmd = record.GetCmdCreateTablet(i);
isOk = isOk && cmd.HasOwnerId() && cmd.HasOwnerIdx()
- && cmd.HasTabletType() && (cmd.BindedChannelsSize() > 0);
+ && cmd.HasTabletType() && (cmd.BindedChannelsSize() > 0);
if (isOk) {
- Requests.emplace_back(cmd.GetOwnerId(), cmd.GetOwnerIdx(), cmd.GetTabletType(),
+ Requests.emplace_back(cmd.GetOwnerId(), cmd.GetOwnerIdx(), cmd.GetTabletType(),
TVector<ui32>(cmd.GetAllowedNodeIDs().begin(), cmd.GetAllowedNodeIDs().end()),
TVector<TSubDomainKey>(cmd.GetAllowedDomains().begin(), cmd.GetAllowedDomains().end()),
TChannelsBindings(cmd.GetBindedChannels().begin(), cmd.GetBindedChannels().end()));
@@ -92,20 +92,20 @@ public:
ErrorReason = Sprintf("Missing arguments for CmdCreateTablet(%" PRIu32 ") call", i);
}
}
- cmdCount = record.CmdLookupTabletSize();
- for (ui32 i = 0; i < cmdCount; ++i) {
- const auto &cmd = record.GetCmdLookupTablet(i);
- isOk = isOk && cmd.HasOwnerId() && cmd.HasOwnerIdx();
- if (isOk) {
+ cmdCount = record.CmdLookupTabletSize();
+ for (ui32 i = 0; i < cmdCount; ++i) {
+ const auto &cmd = record.GetCmdLookupTablet(i);
+ isOk = isOk && cmd.HasOwnerId() && cmd.HasOwnerIdx();
+ if (isOk) {
Requests.emplace_back(cmd.GetOwnerId(), cmd.GetOwnerIdx());
- } else {
- ErrorReason = Sprintf("Missing arguments for CmdLookupTablet(%" PRIu32 ") call", i);
- }
- }
+ } else {
+ ErrorReason = Sprintf("Missing arguments for CmdLookupTablet(%" PRIu32 ") call", i);
+ }
+ }
if (isOk) {
isOk = isOk && record.HasDomainUid();
if (!isOk) {
- ErrorReason = Sprintf("Missing DomainUid for CmdCreateTablet/CmdLookupTablet call");
+ ErrorReason = Sprintf("Missing DomainUid for CmdCreateTablet/CmdLookupTablet call");
}
}
@@ -167,27 +167,27 @@ public:
if (ResponsesReceived == Requests.size()) {
switch (Status) {
case NKikimrProto::OK: {
- THolder<ResponseType> result(new ResponseType());
+ THolder<ResponseType> result(new ResponseType());
auto &rec = result->Record;
rec.SetStatus(MSTATUS_OK);
for (ui32 i = 0; i < Requests.size(); ++i) {
TRequest &request = Requests[i];
- switch (request.Event) {
- case TEvHive::EvCreateTablet: {
- auto* item = rec.AddCreateTabletResult();
- item->SetStatus(request.Status);
- item->SetTabletId(request.TabletId);
- break;
- }
- case TEvHive::EvLookupTablet: {
- auto* item = rec.AddLookupTabletResult();
- item->SetStatus(request.Status);
- item->SetTabletId(request.TabletId);
- break;
- }
- default:
- break;
- }
+ switch (request.Event) {
+ case TEvHive::EvCreateTablet: {
+ auto* item = rec.AddCreateTabletResult();
+ item->SetStatus(request.Status);
+ item->SetTabletId(request.TabletId);
+ break;
+ }
+ case TEvHive::EvLookupTablet: {
+ auto* item = rec.AddLookupTabletResult();
+ item->SetStatus(request.Status);
+ item->SetTabletId(request.TabletId);
+ break;
+ }
+ default:
+ break;
+ }
}
return SendReplyAndDie(result.Release(), ctx);
}
@@ -215,7 +215,7 @@ public:
Y_UNUSED(ev);
PipeClient = TActorId();
ErrorReason = Sprintf("Client pipe to Hive destroyed (connection lost), Marker# HC9");
- SendReplyMove(CreateErrorReply(MSTATUS_ERROR, ctx));
+ SendReplyMove(CreateErrorReply(MSTATUS_ERROR, ctx));
return Die(ctx);
}
@@ -234,7 +234,7 @@ public:
virtual NBus::TBusMessage* CreateErrorReply(EResponseStatus status, const TActorContext &ctx) {
Y_UNUSED(ctx);
- THolder<ResponseType> result(new ResponseType());
+ THolder<ResponseType> result(new ResponseType());
auto &rec = result->Record;
rec.SetStatus(status);
if (ErrorReason.size()) {
@@ -246,7 +246,7 @@ public:
}
void SendReplyAndDie(NBus::TBusMessage *reply, const TActorContext &ctx) {
- SendReplyMove(reply);
+ SendReplyMove(reply);
return Die(ctx);
}
@@ -258,7 +258,7 @@ public:
NTabletPipe::TClientConfig clientConfig;
if (WithRetry) {
- clientConfig.RetryPolicy = NTabletPipe::TClientRetryPolicy::WithRetries();
+ clientConfig.RetryPolicy = NTabletPipe::TClientRetryPolicy::WithRetries();
}
auto &domainsInfo = *AppData(ctx)->DomainsInfo;
@@ -278,8 +278,8 @@ public:
for (ui64 i = 0; i < Requests.size(); ++i) {
const TRequest &cmd = Requests[i];
- switch (cmd.Event) {
- case TEvHive::EvCreateTablet: {
+ switch (cmd.Event) {
+ case TEvHive::EvCreateTablet: {
THolder<TEvHive::TEvCreateTablet> x(new TEvHive::TEvCreateTablet(cmd.OwnerId,
cmd.OwnerIdx,
cmd.TabletType,
@@ -290,20 +290,20 @@ public:
*x->Record.AddAllowedDomains() = domainKey;
}
- NTabletPipe::SendData(ctx, PipeClient, x.Release(), i);
- break;
- }
- case TEvHive::EvLookupTablet: {
- THolder<TEvHive::TEvLookupTablet> x(new TEvHive::TEvLookupTablet(cmd.OwnerId, cmd.OwnerIdx));
- NTabletPipe::SendData(ctx, PipeClient, x.Release(), i);
- break;
- }
- default:
- break;
- }
+ NTabletPipe::SendData(ctx, PipeClient, x.Release(), i);
+ break;
+ }
+ case TEvHive::EvLookupTablet: {
+ THolder<TEvHive::TEvLookupTablet> x(new TEvHive::TEvLookupTablet(cmd.OwnerId, cmd.OwnerIdx));
+ NTabletPipe::SendData(ctx, PipeClient, x.Release(), i);
+ break;
+ }
+ default:
+ break;
+ }
}
- TBase::Become(&TMessageBusHiveCreateTablet<ResponseType>::StateWaiting, ctx, Timeout, new TEvents::TEvWakeup());
+ TBase::Become(&TMessageBusHiveCreateTablet<ResponseType>::StateWaiting, ctx, Timeout, new TEvents::TEvWakeup());
} else {
if (ErrorReason.size() == 0) {
ErrorReason = Sprintf("Unexpected Status, Marker# HC8");
@@ -322,12 +322,12 @@ public:
}
};
-IActor* CreateMessageBusHiveCreateTablet(TBusMessageContext &msg) {
- if (msg.GetMessage()->GetHeader()->Type == MTYPE_CLIENT_OLD_HIVE_CREATE_TABLET) {
- return new TMessageBusHiveCreateTablet<TBusHiveCreateTabletResult>(msg);
- } else {
- return new TMessageBusHiveCreateTablet<TBusResponse>(msg);
- }
+IActor* CreateMessageBusHiveCreateTablet(TBusMessageContext &msg) {
+ if (msg.GetMessage()->GetHeader()->Type == MTYPE_CLIENT_OLD_HIVE_CREATE_TABLET) {
+ return new TMessageBusHiveCreateTablet<TBusHiveCreateTabletResult>(msg);
+ } else {
+ return new TMessageBusHiveCreateTablet<TBusResponse>(msg);
+ }
}
}
diff --git a/ydb/core/client/server/msgbus_server_keyvalue.cpp b/ydb/core/client/server/msgbus_server_keyvalue.cpp
index 9e76f3b0196..ad644f4c269 100644
--- a/ydb/core/client/server/msgbus_server_keyvalue.cpp
+++ b/ydb/core/client/server/msgbus_server_keyvalue.cpp
@@ -9,7 +9,7 @@ namespace {
const ui64 MaxAllowedTimeoutMs = 1000 * 60 * 30; // 30 minutes is an instanely long request
}
-template <typename ResponseType>
+template <typename ResponseType>
class TMessageBusKeyValue
: public TMessageBusSimpleTabletRequest<TMessageBusKeyValue<ResponseType>, TEvKeyValue::TEvResponse, NKikimrServices::TActivity::FRONT_KV_REQUEST> {
using TBase = TMessageBusSimpleTabletRequest<TMessageBusKeyValue<ResponseType>, TEvKeyValue::TEvResponse, NKikimrServices::TActivity::FRONT_KV_REQUEST>;
@@ -17,7 +17,7 @@ public:
NKikimrClient::TKeyValueRequest RequestProto;
ui64 TabletId;
- TMessageBusKeyValue(TBusMessageContext &msg, ui64 tabletId, bool withRetry, TDuration timeout)
+ TMessageBusKeyValue(TBusMessageContext &msg, ui64 tabletId, bool withRetry, TDuration timeout)
: TBase(msg, tabletId, withRetry, timeout, false)
, RequestProto(static_cast<TBusKeyValue *>(msg.GetMessage())->Record)
, TabletId(tabletId)
@@ -25,9 +25,9 @@ public:
void Handle(TEvKeyValue::TEvResponse::TPtr &ev, const TActorContext &ctx) {
TEvKeyValue::TEvResponse *msg = ev->Get();
- TAutoPtr<ResponseType> response(new ResponseType());
- CopyProtobufsByFieldName(response->Record, msg->Record);
- TBase::SendReplyAndDie(response.Release(), ctx);
+ TAutoPtr<ResponseType> response(new ResponseType());
+ CopyProtobufsByFieldName(response->Record, msg->Record);
+ TBase::SendReplyAndDie(response.Release(), ctx);
}
TEvKeyValue::TEvRequest* MakeReq(const TActorContext &ctx) {
@@ -42,22 +42,22 @@ public:
LOG_WARN_S(ctx, NKikimrServices::MSGBUS_REQUEST, "TMessageBusKeyValue TabletId# " << TabletId
<< " status# " << status << " text# \"" << text << "\" Marker# MBKV2" << Endl);
- TAutoPtr<ResponseType> response(new ResponseType());
+ TAutoPtr<ResponseType> response(new ResponseType());
response->Record.SetStatus(status);
if (text) {
- response->Record.SetErrorReason(text);
+ response->Record.SetErrorReason(text);
} else {
TStringStream str;
str << "TMessageBusKeyValue unknown error, TabletId# " << TabletId;
str << " status# " << status;
str << " Marker# MBKV1" << Endl;
- response->Record.SetErrorReason(str.Str());
+ response->Record.SetErrorReason(str.Str());
}
return response.Release();
}
};
-IActor* CreateMessageBusKeyValue(NKikimr::NMsgBusProxy::TBusMessageContext &msg) {
+IActor* CreateMessageBusKeyValue(NKikimr::NMsgBusProxy::TBusMessageContext &msg) {
auto &record = static_cast<TBusKeyValue *>(msg.GetMessage())->Record;
const ui64 tabletId = record.GetTabletId();
@@ -87,11 +87,11 @@ IActor* CreateMessageBusKeyValue(NKikimr::NMsgBusProxy::TBusMessageContext &msg)
ui64 deadlineInstantMs = deadlineInstant.MilliSeconds();
record.SetDeadlineInstantMs(deadlineInstantMs);
}
- if (msg.GetMessage()->GetHeader()->Type == MTYPE_CLIENT_OLD_KEYVALUE) {
- return new TMessageBusKeyValue<TBusKeyValueResponse>(msg, tabletId, withRetry, timeout);
- } else {
- return new TMessageBusKeyValue<TBusResponse>(msg, tabletId, withRetry, timeout);
- }
+ if (msg.GetMessage()->GetHeader()->Type == MTYPE_CLIENT_OLD_KEYVALUE) {
+ return new TMessageBusKeyValue<TBusKeyValueResponse>(msg, tabletId, withRetry, timeout);
+ } else {
+ return new TMessageBusKeyValue<TBusResponse>(msg, tabletId, withRetry, timeout);
+ }
}
}
diff --git a/ydb/core/client/server/msgbus_server_local_enumerate_tablets.cpp b/ydb/core/client/server/msgbus_server_local_enumerate_tablets.cpp
index 69e16ffdff9..9f867dddc7c 100644
--- a/ydb/core/client/server/msgbus_server_local_enumerate_tablets.cpp
+++ b/ydb/core/client/server/msgbus_server_local_enumerate_tablets.cpp
@@ -8,21 +8,21 @@ namespace {
const ui32 DefaultTimeout = 90000;
}
-template <typename ResponseType>
+template <typename ResponseType>
class TMessageBusLocalEnumerateTablets: public TMessageBusLocalServiceRequest<TMessageBusLocalEnumerateTablets<ResponseType>, NKikimrServices::TActivity::FRONT_ENUMERATE_TABLETS> {
using TBase = TMessageBusLocalServiceRequest<TMessageBusLocalEnumerateTablets<ResponseType>, NKikimrServices::TActivity::FRONT_ENUMERATE_TABLETS>;
ui64 DomainUid;
ui32 NodeId;
- TTabletTypes::EType TabletType;
+ TTabletTypes::EType TabletType;
bool IsFiltered;
bool IsOk;
bool IsNodeIdPresent;
public:
- TMessageBusLocalEnumerateTablets(TBusMessageContext &msg, TDuration timeout)
- : TBase(msg, timeout)
+ TMessageBusLocalEnumerateTablets(TBusMessageContext &msg, TDuration timeout)
+ : TBase(msg, timeout)
, DomainUid(0)
, NodeId(0)
- , TabletType()
+ , TabletType()
, IsFiltered(false)
, IsOk(true)
, IsNodeIdPresent(false)
@@ -45,12 +45,12 @@ public:
void Handle(TEvLocal::TEvEnumerateTabletsResult::TPtr &ev, const TActorContext &ctx) {
const NKikimrLocal::TEvEnumerateTabletsResult &record = ev->Get()->Record;
Y_VERIFY(record.HasStatus());
- THolder<ResponseType> response(new ResponseType());
+ THolder<ResponseType> response(new ResponseType());
if (record.GetStatus() != NKikimrProto::OK) {
response->Record.SetStatus(MSTATUS_ERROR);
response->Record.SetErrorReason(Sprintf("Local response is not OK (Status# %s), Marker# LE1",
NKikimrProto::EReplyStatus_Name(record.GetStatus()).data()));
- TBase::SendReplyAndDie(response.Release(), ctx);
+ TBase::SendReplyAndDie(response.Release(), ctx);
} else {
response->Record.SetStatus(MSTATUS_OK);
for (ui32 i = 0; i < record.TabletInfoSize(); ++i) {
@@ -63,7 +63,7 @@ public:
dstInfo->SetTabletType(srcInfo.GetTabletType());
}
}
- TBase::SendReplyAndDie(response.Release(), ctx);
+ TBase::SendReplyAndDie(response.Release(), ctx);
}
}
@@ -93,7 +93,7 @@ public:
Y_UNUSED(ctx);
Y_UNUSED(status);
ui64 nodeId = IsNodeIdPresent ? NodeId : ctx.SelfID.NodeId();
- THolder<ResponseType> response(new ResponseType());
+ THolder<ResponseType> response(new ResponseType());
response->Record.SetStatus(MSTATUS_ERROR);
response->Record.SetErrorReason(Sprintf("Invalid DomainUid# %" PRIu64 ", NodeId# %" PRIu64
" or kikimr hive/domain/node configuration, Marker# LE3", (ui64)DomainUid, (ui64)nodeId));
@@ -103,17 +103,17 @@ public:
void HandleTimeout(const TActorContext &ctx) {
Y_UNUSED(ctx);
TAutoPtr<TBusResponse> response(new TBusResponseStatus(MSTATUS_TIMEOUT, ""));
- TBase::SendReplyAndDie(response.Release(), ctx);
+ TBase::SendReplyAndDie(response.Release(), ctx);
}
void HandleUndelivered(TEvents::TEvUndelivered::TPtr& ev, const TActorContext& ctx) {
Y_UNUSED(ev);
- THolder<ResponseType> response(new ResponseType());
+ THolder<ResponseType> response(new ResponseType());
ui64 nodeId = IsNodeIdPresent ? NodeId : ctx.SelfID.NodeId();
response->Record.SetStatus(MSTATUS_ERROR);
response->Record.SetErrorReason(Sprintf("Request was not delivered to Local, NodeId# %" PRIu64
", Marker# LE2", (ui64)nodeId));
- TBase::SendReplyAndDie(response.Release(), ctx);
+ TBase::SendReplyAndDie(response.Release(), ctx);
}
@@ -126,16 +126,16 @@ public:
}
};
-IActor* CreateMessageBusLocalEnumerateTablets(TBusMessageContext &msg) {
+IActor* CreateMessageBusLocalEnumerateTablets(TBusMessageContext &msg) {
//const auto &record = static_cast<TBusLocalEnumerateTablets*>(msg.GetMessage())->Record;
//const TDuration timeout = TDuration::MilliSeconds(record.HasTimeout() ? record.GetTimeout() : DefaultTimeout);
const TDuration timeout = TDuration::MilliSeconds(DefaultTimeout);
- if (msg.GetMessage()->GetHeader()->Type == MTYPE_CLIENT_OLD_LOCAL_ENUMERATE_TABLETS) {
- return new TMessageBusLocalEnumerateTablets<TBusLocalEnumerateTabletsResult>(msg, timeout);
- } else {
- return new TMessageBusLocalEnumerateTablets<TBusResponse>(msg, timeout);
- }
+ if (msg.GetMessage()->GetHeader()->Type == MTYPE_CLIENT_OLD_LOCAL_ENUMERATE_TABLETS) {
+ return new TMessageBusLocalEnumerateTablets<TBusLocalEnumerateTabletsResult>(msg, timeout);
+ } else {
+ return new TMessageBusLocalEnumerateTablets<TBusResponse>(msg, timeout);
+ }
}
}
diff --git a/ydb/core/client/server/msgbus_server_local_minikql.cpp b/ydb/core/client/server/msgbus_server_local_minikql.cpp
index 2bbaa7169c0..42fa4ed9a83 100644
--- a/ydb/core/client/server/msgbus_server_local_minikql.cpp
+++ b/ydb/core/client/server/msgbus_server_local_minikql.cpp
@@ -1,5 +1,5 @@
#include "msgbus_tabletreq.h"
-#include "msgbus_securereq.h"
+#include "msgbus_securereq.h"
namespace NKikimr {
namespace NMsgBusProxy {
@@ -14,10 +14,10 @@ public:
TMessageBusLocalMKQL(TBusMessageContext &msg, const NKikimrClient::TLocalMKQL &request, ui64 tabletId, bool withRetry, TDuration timeout, bool connectToFollower)
: TMessageBusSecureRequest(msg, tabletId, withRetry, timeout, connectToFollower)
, Request(request)
- {
- SetSecurityToken(static_cast<TBusTabletLocalMKQL*>(msg.GetMessage())->Record.GetSecurityToken());
- SetRequireAdminAccess(true);
- }
+ {
+ SetSecurityToken(static_cast<TBusTabletLocalMKQL*>(msg.GetMessage())->Record.GetSecurityToken());
+ SetRequireAdminAccess(true);
+ }
void Handle(TEvTablet::TEvLocalMKQLResponse::TPtr &ev, const TActorContext &ctx) {
const auto &record = ev->Get()->Record;
diff --git a/ydb/core/client/server/msgbus_server_local_scheme_tx.cpp b/ydb/core/client/server/msgbus_server_local_scheme_tx.cpp
index 9cd9031e11f..c1eed46ef99 100644
--- a/ydb/core/client/server/msgbus_server_local_scheme_tx.cpp
+++ b/ydb/core/client/server/msgbus_server_local_scheme_tx.cpp
@@ -1,5 +1,5 @@
#include "msgbus_tabletreq.h"
-#include "msgbus_securereq.h"
+#include "msgbus_securereq.h"
namespace NKikimr {
namespace NMsgBusProxy {
@@ -8,9 +8,9 @@ namespace {
const ui64 DefaultTimeout = 90000;
}
-class TMessageBusLocalSchemeTx : public TMessageBusSecureRequest<TMessageBusSimpleTabletRequest<TMessageBusLocalSchemeTx,
+class TMessageBusLocalSchemeTx : public TMessageBusSecureRequest<TMessageBusSimpleTabletRequest<TMessageBusLocalSchemeTx,
TEvTablet::TEvLocalSchemeTxResponse, NKikimrServices::TActivity::FRONT_LOCAL_TXRQ>> {
- using TBase = TMessageBusSecureRequest<TMessageBusSimpleTabletRequest<TMessageBusLocalSchemeTx,
+ using TBase = TMessageBusSecureRequest<TMessageBusSimpleTabletRequest<TMessageBusLocalSchemeTx,
TEvTablet::TEvLocalSchemeTxResponse, NKikimrServices::TActivity::FRONT_LOCAL_TXRQ>>;
NKikimrClient::TLocalSchemeTx Request;
public:
@@ -19,8 +19,8 @@ public:
, Request()
{
Request.Swap(&request);
- TBase::SetSecurityToken(Request.GetSecurityToken());
- TBase::SetRequireAdminAccess(true);
+ TBase::SetSecurityToken(Request.GetSecurityToken());
+ TBase::SetRequireAdminAccess(true);
}
void Handle(TEvTablet::TEvLocalSchemeTxResponse::TPtr &ev, const TActorContext &ctx) {
diff --git a/ydb/core/client/server/msgbus_server_node_registration.cpp b/ydb/core/client/server/msgbus_server_node_registration.cpp
index b20295bbd6a..a3dda6092d0 100644
--- a/ydb/core/client/server/msgbus_server_node_registration.cpp
+++ b/ydb/core/client/server/msgbus_server_node_registration.cpp
@@ -56,7 +56,7 @@ public:
}
NTabletPipe::TClientConfig pipeConfig;
- pipeConfig.RetryPolicy = {.RetryLimitCount = 10};
+ pipeConfig.RetryPolicy = {.RetryLimitCount = 10};
auto pipe = NTabletPipe::CreateClient(ctx.SelfID, MakeNodeBrokerID(group), pipeConfig);
NodeBrokerPipe = ctx.RegisterWithSameMailbox(pipe);
diff --git a/ydb/core/client/server/msgbus_server_pq_metarequest.cpp b/ydb/core/client/server/msgbus_server_pq_metarequest.cpp
index f2093f5a3d5..32f37251cc5 100644
--- a/ydb/core/client/server/msgbus_server_pq_metarequest.cpp
+++ b/ydb/core/client/server/msgbus_server_pq_metarequest.cpp
@@ -690,7 +690,7 @@ void TPersQueueGetReadSessionsInfoTopicWorker::Answer(const TActorContext& ctx,
res->SetErrorCode(NPersQueue::NErrorCode::INITIALIZING);
res->SetErrorReason("Tablet for partition is not running");
}
- }
+ }
}
}
SendReplyAndDie(std::move(response), ctx);
diff --git a/ydb/core/client/server/msgbus_server_proxy.cpp b/ydb/core/client/server/msgbus_server_proxy.cpp
index 83877e01f72..7f3146d21a7 100644
--- a/ydb/core/client/server/msgbus_server_proxy.cpp
+++ b/ydb/core/client/server/msgbus_server_proxy.cpp
@@ -1,7 +1,7 @@
#include "msgbus_server.h"
-#include "msgbus_server_request.h"
-#include "msgbus_server_proxy.h"
-#include "msgbus_securereq.h"
+#include "msgbus_server_request.h"
+#include "msgbus_server_proxy.h"
+#include "msgbus_securereq.h"
#include <library/cpp/actors/core/hfunc.h>
#include <ydb/core/base/appdata.h>
@@ -19,21 +19,21 @@
namespace NKikimr {
namespace NMsgBusProxy {
-template <typename ResponseType>
-class TMessageBusServerFlatDescribeRequest : public TMessageBusSecureRequest<TMessageBusServerRequestBase<TMessageBusServerFlatDescribeRequest<ResponseType>>> {
- using TBase = TMessageBusSecureRequest<TMessageBusServerRequestBase<TMessageBusServerFlatDescribeRequest<ResponseType>>>;
- THolder<TBusSchemeDescribe> Request;
+template <typename ResponseType>
+class TMessageBusServerFlatDescribeRequest : public TMessageBusSecureRequest<TMessageBusServerRequestBase<TMessageBusServerFlatDescribeRequest<ResponseType>>> {
+ using TBase = TMessageBusSecureRequest<TMessageBusServerRequestBase<TMessageBusServerFlatDescribeRequest<ResponseType>>>;
+ THolder<TBusSchemeDescribe> Request;
NYql::TIssueManager IssueManager;
-
+
void Handle(NSchemeShard::TEvSchemeShard::TEvDescribeSchemeResult::TPtr& ev, const TActorContext& ctx) {
- auto &mutableRecord = *ev->Get()->MutableRecord();
- TAutoPtr<ResponseType> response(new ResponseType());
+ auto &mutableRecord = *ev->Get()->MutableRecord();
+ TAutoPtr<ResponseType> response(new ResponseType());
response->Record.SetSchemeStatus(mutableRecord.GetStatus());
const auto status = mutableRecord.GetStatus();
if (status == NKikimrScheme::StatusSuccess) {
response->Record.SetStatus(MSTATUS_OK);
response->Record.SetPath(mutableRecord.GetPath());
- response->Record.MutablePathDescription()->Swap(mutableRecord.MutablePathDescription());
+ response->Record.MutablePathDescription()->Swap(mutableRecord.MutablePathDescription());
response->Record.SetStatusCode(NKikimrIssues::TStatusIds::SUCCESS);
} else {
response->Record.SetStatus(MSTATUS_ERROR);
@@ -54,52 +54,52 @@ class TMessageBusServerFlatDescribeRequest : public TMessageBusSecureRequest<TMe
if (IssueManager.GetIssues())
IssuesToMessage(IssueManager.GetIssues(), response->Record.MutableIssues());
- TBase::SendReplyAutoPtr(response);
- Request.Destroy();
+ TBase::SendReplyAutoPtr(response);
+ Request.Destroy();
this->Die(ctx);
- }
-
-public:
+ }
+
+public:
static constexpr NKikimrServices::TActivity::EType ActorActivityType() { return NKikimrServices::TActivity::FRONT_SCHEME_DESCRIBE; }
- TMessageBusServerFlatDescribeRequest(TEvBusProxy::TEvFlatDescribeRequest* msg)
- : TBase(msg->MsgContext)
- , Request(static_cast<TBusSchemeDescribe*>(msg->MsgContext.ReleaseMessage()))
- {
- TBase::SetSecurityToken(Request->Record.GetSecurityToken());
- }
-
- //STFUNC(StateWork)
- void StateWork(TAutoPtr<NActors::IEventHandle>& ev, const NActors::TActorContext& ctx) {
- switch (ev->GetTypeRewrite()) {
+ TMessageBusServerFlatDescribeRequest(TEvBusProxy::TEvFlatDescribeRequest* msg)
+ : TBase(msg->MsgContext)
+ , Request(static_cast<TBusSchemeDescribe*>(msg->MsgContext.ReleaseMessage()))
+ {
+ TBase::SetSecurityToken(Request->Record.GetSecurityToken());
+ }
+
+ //STFUNC(StateWork)
+ void StateWork(TAutoPtr<NActors::IEventHandle>& ev, const NActors::TActorContext& ctx) {
+ switch (ev->GetTypeRewrite()) {
HFunc(NSchemeShard::TEvSchemeShard::TEvDescribeSchemeResult, Handle);
- }
- }
-
- void Bootstrap(const TActorContext& ctx) {
- SendRequest(ctx);
- TBase::Become(&TMessageBusServerFlatDescribeRequest::StateWork);
- }
-
- void SendRequest(const TActorContext& ctx) {
- TAutoPtr<TEvTxUserProxy::TEvNavigate> req(new TEvTxUserProxy::TEvNavigate());
+ }
+ }
+
+ void Bootstrap(const TActorContext& ctx) {
+ SendRequest(ctx);
+ TBase::Become(&TMessageBusServerFlatDescribeRequest::StateWork);
+ }
+
+ void SendRequest(const TActorContext& ctx) {
+ TAutoPtr<TEvTxUserProxy::TEvNavigate> req(new TEvTxUserProxy::TEvNavigate());
NKikimrSchemeOp::TDescribePath* record = req->Record.MutableDescribePath();
-
- if (Request->Record.HasPath()) {
- record->SetPath(Request->Record.GetPath());
- } else {
- record->SetSchemeshardId(Request->Record.GetSchemeshardId());
- record->SetPathId(Request->Record.GetPathId());
- }
+
+ if (Request->Record.HasPath()) {
+ record->SetPath(Request->Record.GetPath());
+ } else {
+ record->SetSchemeshardId(Request->Record.GetSchemeshardId());
+ record->SetPathId(Request->Record.GetPathId());
+ }
if (Request->Record.HasOptions()) {
auto options = record->MutableOptions();
options->CopyFrom(Request->Record.GetOptions());
}
- req->Record.SetUserToken(TBase::GetSerializedToken());
- ctx.Send(MakeTxProxyID(), req.Release());
- }
-};
-
+ req->Record.SetUserToken(TBase::GetSerializedToken());
+ ctx.Send(MakeTxProxyID(), req.Release());
+ }
+};
+
IActor* CreateMessageBusServerProxy(
TMessageBusServer* server,
std::shared_ptr<IPersQueueGetReadSessionsInfoWorkerFactory> pqReadSessionsInfoWorkerFactory
@@ -149,35 +149,35 @@ TBusResponse* ProposeTransactionStatusToResponse(EResponseStatus status,
return response.Release();
}
-//void TMessageBusServerProxy::Handle(TEvBusProxy::TEvRequest::TPtr& ev, const TActorContext& ctx); // see msgbus_server_request.cpp
-
-//void TMessageBusServerProxy::Handle(TEvBusProxy::TEvPersQueue::TPtr& ev, const TActorContext& ctx); // see msgbus_server_scheme_request.cpp
-//void TMessageBusServerProxy::Handle(TEvBusProxy::TEvFlatTxRequest::TPtr& ev, const TActorContext& ctx); // see msgbus_server_scheme_request.cpp
-
-void TMessageBusServerProxy::Handle(TEvBusProxy::TEvFlatDescribeRequest::TPtr& ev, const TActorContext& ctx) {
- TEvBusProxy::TEvFlatDescribeRequest *msg = ev->Get();
- if (msg->MsgContext.GetMessage()->GetHeader()->Type == MTYPE_CLIENT_OLD_FLAT_DESCRIBE_REQUEST) {
- ctx.Register(new TMessageBusServerFlatDescribeRequest<TBusOldFlatDescribeResponse>(ev->Get()));
- } else {
- ctx.Register(new TMessageBusServerFlatDescribeRequest<TBusResponse>(ev->Get()));
- }
-}
-
-//void TMessageBusServerProxy::Handle(TEvBusProxy::TEvDbSchema::TPtr& ev, const TActorContext& ctx); // see msgbus_server_db.cpp
-//void TMessageBusServerProxy::Handle(TEvBusProxy::TEvDbOperation::TPtr& ev, const TActorContext& ctx); // see msgbus_server_db.cpp
-
-void TMessageBusServerProxy::Bootstrap(const TActorContext& ctx) {
- SelfID = ctx.SelfID;
-
+//void TMessageBusServerProxy::Handle(TEvBusProxy::TEvRequest::TPtr& ev, const TActorContext& ctx); // see msgbus_server_request.cpp
+
+//void TMessageBusServerProxy::Handle(TEvBusProxy::TEvPersQueue::TPtr& ev, const TActorContext& ctx); // see msgbus_server_scheme_request.cpp
+//void TMessageBusServerProxy::Handle(TEvBusProxy::TEvFlatTxRequest::TPtr& ev, const TActorContext& ctx); // see msgbus_server_scheme_request.cpp
+
+void TMessageBusServerProxy::Handle(TEvBusProxy::TEvFlatDescribeRequest::TPtr& ev, const TActorContext& ctx) {
+ TEvBusProxy::TEvFlatDescribeRequest *msg = ev->Get();
+ if (msg->MsgContext.GetMessage()->GetHeader()->Type == MTYPE_CLIENT_OLD_FLAT_DESCRIBE_REQUEST) {
+ ctx.Register(new TMessageBusServerFlatDescribeRequest<TBusOldFlatDescribeResponse>(ev->Get()));
+ } else {
+ ctx.Register(new TMessageBusServerFlatDescribeRequest<TBusResponse>(ev->Get()));
+ }
+}
+
+//void TMessageBusServerProxy::Handle(TEvBusProxy::TEvDbSchema::TPtr& ev, const TActorContext& ctx); // see msgbus_server_db.cpp
+//void TMessageBusServerProxy::Handle(TEvBusProxy::TEvDbOperation::TPtr& ev, const TActorContext& ctx); // see msgbus_server_db.cpp
+
+void TMessageBusServerProxy::Bootstrap(const TActorContext& ctx) {
+ SelfID = ctx.SelfID;
+
TxProxy = MakeTxProxyID();
SchemeCacheCounters = GetServiceCounters(AppData(ctx)->Counters, "pqproxy|cache");
- DbOperationsCounters = new TMessageBusDbOpsCounters(AppData(ctx)->Counters);
-
+ DbOperationsCounters = new TMessageBusDbOpsCounters(AppData(ctx)->Counters);
+
auto cacheConfig = MakeIntrusive<NSchemeCache::TSchemeCacheConfig>(AppData(ctx), SchemeCacheCounters);
SchemeCache = ctx.ExecutorThread.RegisterActor(CreateSchemeBoardSchemeCache(cacheConfig.Get()));
PqMetaCache = CreatePersQueueMetaCacheV2Id();
-
+
if (Server) {
Server->InitSession(ctx.ExecutorThread.ActorSystem, ctx.SelfID);
}
@@ -186,9 +186,9 @@ void TMessageBusServerProxy::Bootstrap(const TActorContext& ctx) {
if (auto *busMonPage = AppData(ctx)->BusMonPage)
Server->RegisterMonPage(busMonPage);
}
-
- Become(&TThis::StateFunc);
-}
-
-}
-}
+
+ Become(&TThis::StateFunc);
+}
+
+}
+}
diff --git a/ydb/core/client/server/msgbus_server_proxy.h b/ydb/core/client/server/msgbus_server_proxy.h
index 33565326823..cb9f9c19d38 100644
--- a/ydb/core/client/server/msgbus_server_proxy.h
+++ b/ydb/core/client/server/msgbus_server_proxy.h
@@ -1,62 +1,62 @@
-#pragma once
-
+#pragma once
+
#include <library/cpp/actors/core/hfunc.h>
#include <ydb/core/base/counters.h>
#include <ydb/library/aclib/aclib.h>
-#include "msgbus_server.h"
-
-namespace NKikimr {
-namespace NMsgBusProxy {
-
-struct TMessageBusDbOpsCounters : TAtomicRefCount<TMessageBusDbOpsCounters> {
- TIntrusivePtr<NMonitoring::TDynamicCounters> DbOperationsCounters;
- NMon::THistogramCounterHelper RequestTotalTimeHistogram;
- NMon::THistogramCounterHelper RequestPrepareTimeHistogram;
- NMon::THistogramCounterHelper RequestUpdateTimeHistogram;
- NMon::THistogramCounterHelper RequestSelectTimeHistogram;
- NMon::THistogramCounterHelper RequestSchemaTimeHistogram;
- NMon::THistogramCounterHelper RequestBatchTimeHistogram;
- NMon::THistogramCounterHelper RequestQueryTimeHistogram;
-
- TMessageBusDbOpsCounters(const NMonitoring::TDynamicCounterPtr& counters) {
+#include "msgbus_server.h"
+
+namespace NKikimr {
+namespace NMsgBusProxy {
+
+struct TMessageBusDbOpsCounters : TAtomicRefCount<TMessageBusDbOpsCounters> {
+ TIntrusivePtr<NMonitoring::TDynamicCounters> DbOperationsCounters;
+ NMon::THistogramCounterHelper RequestTotalTimeHistogram;
+ NMon::THistogramCounterHelper RequestPrepareTimeHistogram;
+ NMon::THistogramCounterHelper RequestUpdateTimeHistogram;
+ NMon::THistogramCounterHelper RequestSelectTimeHistogram;
+ NMon::THistogramCounterHelper RequestSchemaTimeHistogram;
+ NMon::THistogramCounterHelper RequestBatchTimeHistogram;
+ NMon::THistogramCounterHelper RequestQueryTimeHistogram;
+
+ TMessageBusDbOpsCounters(const NMonitoring::TDynamicCounterPtr& counters) {
DbOperationsCounters = GetServiceCounters(counters, "proxy")->GetSubgroup("subsystem", "db");
- RequestTotalTimeHistogram.Init(DbOperationsCounters.Get(), "RequestTotalTime", "ms", 1, 20);
- RequestPrepareTimeHistogram.Init(DbOperationsCounters.Get(), "RequestPrepareTime", "ms", 1, 20);
- RequestUpdateTimeHistogram.Init(DbOperationsCounters.Get(), "RequestUpdateTime", "ms", 1, 20);
- RequestSelectTimeHistogram.Init(DbOperationsCounters.Get(), "RequestSelectTime", "ms", 1, 20);
- RequestSchemaTimeHistogram.Init(DbOperationsCounters.Get(), "RequestSchemaTime", "ms", 1, 20);
- RequestBatchTimeHistogram.Init(DbOperationsCounters.Get(), "RequestBatchTime", "ms", 1, 20);
- RequestQueryTimeHistogram.Init(DbOperationsCounters.Get(), "RequestQueryTime", "ms", 1, 20);
- }
-};
-
-class TMessageBusServerProxy : public TActorBootstrapped<TMessageBusServerProxy> {
+ RequestTotalTimeHistogram.Init(DbOperationsCounters.Get(), "RequestTotalTime", "ms", 1, 20);
+ RequestPrepareTimeHistogram.Init(DbOperationsCounters.Get(), "RequestPrepareTime", "ms", 1, 20);
+ RequestUpdateTimeHistogram.Init(DbOperationsCounters.Get(), "RequestUpdateTime", "ms", 1, 20);
+ RequestSelectTimeHistogram.Init(DbOperationsCounters.Get(), "RequestSelectTime", "ms", 1, 20);
+ RequestSchemaTimeHistogram.Init(DbOperationsCounters.Get(), "RequestSchemaTime", "ms", 1, 20);
+ RequestBatchTimeHistogram.Init(DbOperationsCounters.Get(), "RequestBatchTime", "ms", 1, 20);
+ RequestQueryTimeHistogram.Init(DbOperationsCounters.Get(), "RequestQueryTime", "ms", 1, 20);
+ }
+};
+
+class TMessageBusServerProxy : public TActorBootstrapped<TMessageBusServerProxy> {
TMessageBusServer* const Server;
std::shared_ptr<IPersQueueGetReadSessionsInfoWorkerFactory> PQReadSessionsInfoWorkerFactory;
-
- TIntrusivePtr<NMonitoring::TDynamicCounters> SchemeCacheCounters;
-
- TIntrusivePtr<TMessageBusDbOpsCounters> DbOperationsCounters;
-
+
+ TIntrusivePtr<NMonitoring::TDynamicCounters> SchemeCacheCounters;
+
+ TIntrusivePtr<TMessageBusDbOpsCounters> DbOperationsCounters;
+
TActorId SchemeCache;
TActorId PqMetaCache;
-
-public:
+
+public:
TActorId SelfID;
TActorId TxProxy;
-
-private:
- void Handle(TEvBusProxy::TEvRequest::TPtr &ev, const TActorContext &ctx);
- void Handle(TEvBusProxy::TEvNavigate::TPtr &ev, const TActorContext &ctx);
- void Handle(TEvBusProxy::TEvPersQueue::TPtr &ev, const TActorContext &ctx);
- void Handle(TEvBusProxy::TEvFlatTxRequest::TPtr &ev, const TActorContext &ctx);
- void Handle(TEvBusProxy::TEvFlatDescribeRequest::TPtr &ev, const TActorContext &ctx);
- void Handle(TEvBusProxy::TEvDbSchema::TPtr &ev, const TActorContext &ctx);
- void Handle(TEvBusProxy::TEvDbOperation::TPtr &ev, const TActorContext &ctx);
- void Handle(TEvBusProxy::TEvDbBatch::TPtr &ev, const TActorContext &ctx);
- void Handle(TEvBusProxy::TEvInitRoot::TPtr &ev, const TActorContext &ctx);
-
-public:
+
+private:
+ void Handle(TEvBusProxy::TEvRequest::TPtr &ev, const TActorContext &ctx);
+ void Handle(TEvBusProxy::TEvNavigate::TPtr &ev, const TActorContext &ctx);
+ void Handle(TEvBusProxy::TEvPersQueue::TPtr &ev, const TActorContext &ctx);
+ void Handle(TEvBusProxy::TEvFlatTxRequest::TPtr &ev, const TActorContext &ctx);
+ void Handle(TEvBusProxy::TEvFlatDescribeRequest::TPtr &ev, const TActorContext &ctx);
+ void Handle(TEvBusProxy::TEvDbSchema::TPtr &ev, const TActorContext &ctx);
+ void Handle(TEvBusProxy::TEvDbOperation::TPtr &ev, const TActorContext &ctx);
+ void Handle(TEvBusProxy::TEvDbBatch::TPtr &ev, const TActorContext &ctx);
+ void Handle(TEvBusProxy::TEvInitRoot::TPtr &ev, const TActorContext &ctx);
+
+public:
static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
return NKikimrServices::TActivity::MSGBUS_PROXY_ACTOR;
}
@@ -65,40 +65,40 @@ public:
TMessageBusServer* server,
std::shared_ptr<IPersQueueGetReadSessionsInfoWorkerFactory> pqReadSessionsInfoWorkerFactory
)
- : Server(server)
+ : Server(server)
, PQReadSessionsInfoWorkerFactory(pqReadSessionsInfoWorkerFactory)
- {
- }
-
- ~TMessageBusServerProxy() {
+ {
+ }
+
+ ~TMessageBusServerProxy() {
if (Server) {
Server->ShutdownSession();
}
- }
-
- void Bootstrap(const TActorContext &ctx);
-
- //STFUNC(StateFunc)
- void StateFunc(TAutoPtr<NActors::IEventHandle> &ev, const NActors::TActorContext &ctx) {
- switch (ev->GetTypeRewrite()) {
- HFunc(TEvBusProxy::TEvRequest, Handle);
- HFunc(TEvBusProxy::TEvPersQueue, Handle);
- HFunc(TEvBusProxy::TEvFlatTxRequest, Handle);
- HFunc(TEvBusProxy::TEvFlatDescribeRequest, Handle);
- HFunc(TEvBusProxy::TEvDbOperation, Handle);
- HFunc(TEvBusProxy::TEvDbSchema, Handle);
- HFunc(TEvBusProxy::TEvDbBatch, Handle);
- HFunc(TEvBusProxy::TEvInitRoot, Handle);
- }
- }
-
+ }
+
+ void Bootstrap(const TActorContext &ctx);
+
+ //STFUNC(StateFunc)
+ void StateFunc(TAutoPtr<NActors::IEventHandle> &ev, const NActors::TActorContext &ctx) {
+ switch (ev->GetTypeRewrite()) {
+ HFunc(TEvBusProxy::TEvRequest, Handle);
+ HFunc(TEvBusProxy::TEvPersQueue, Handle);
+ HFunc(TEvBusProxy::TEvFlatTxRequest, Handle);
+ HFunc(TEvBusProxy::TEvFlatDescribeRequest, Handle);
+ HFunc(TEvBusProxy::TEvDbOperation, Handle);
+ HFunc(TEvBusProxy::TEvDbSchema, Handle);
+ HFunc(TEvBusProxy::TEvDbBatch, Handle);
+ HFunc(TEvBusProxy::TEvInitRoot, Handle);
+ }
+ }
+
TIntrusivePtr<NACLib::TUserToken> GetUserToken(const TString& tokenString) {
- // TODO: tokenString -> UID -> (cache) -> tokenObject
- // HACK tokenObject(tokenString) - just for testing purposes
+ // TODO: tokenString -> UID -> (cache) -> tokenObject
+ // HACK tokenObject(tokenString) - just for testing purposes
TIntrusivePtr<NACLib::TUserToken> tokenObject = new NACLib::TUserToken(tokenString, TVector<NACLib::TSID>());
- return tokenObject;
- }
-};
-
-}
-}
+ return tokenObject;
+ }
+};
+
+}
+}
diff --git a/ydb/core/client/server/msgbus_server_request.cpp b/ydb/core/client/server/msgbus_server_request.cpp
index ccc5908af73..9223bea9f1a 100644
--- a/ydb/core/client/server/msgbus_server_request.cpp
+++ b/ydb/core/client/server/msgbus_server_request.cpp
@@ -1,5 +1,5 @@
-#include "msgbus_server_request.h"
-#include "msgbus_securereq.h"
+#include "msgbus_server_request.h"
+#include "msgbus_securereq.h"
#include <ydb/core/actorlib_impl/async_destroyer.h>
#include <ydb/core/actorlib_impl/long_timer.h>
@@ -15,14 +15,14 @@
namespace NKikimr {
namespace NMsgBusProxy {
-class TMessageBusServerRequest : public TMessageBusSecureRequest<TMessageBusServerRequestBase<TMessageBusServerRequest>> {
- using TBase = TMessageBusSecureRequest<TMessageBusServerRequestBase<TMessageBusServerRequest>>;
- THolder<TBusRequest> Request;
+class TMessageBusServerRequest : public TMessageBusSecureRequest<TMessageBusServerRequestBase<TMessageBusServerRequest>> {
+ using TBase = TMessageBusSecureRequest<TMessageBusServerRequestBase<TMessageBusServerRequest>>;
+ THolder<TBusRequest> Request;
TVector<TString*> WriteResolvedKeysTo;
TAutoPtr<TEvTxUserProxy::TEvProposeTransaction> Proposal;
TAutoPtr<NKikimrTxUserProxy::TEvProposeTransactionStatus> ProposalStatus;
- size_t InFlyRequests;
+ size_t InFlyRequests;
THashMap<TString, ui64> CompileResolveCookies;
TString TextProgramForCompilation;
bool CompilationRetried;
@@ -37,7 +37,7 @@ class TMessageBusServerRequest : public TMessageBusSecureRequest<TMessageBusServ
void Handle(TEvTxUserProxy::TEvProposeTransactionStatus::TPtr &ev, const TActorContext &ctx);
void Handle(TEvDataShard::TEvGetReadTableStreamStateRequest::TPtr &ev, const TActorContext &ctx);
- bool AllRequestsCompleted(const TActorContext& ctx);
+ bool AllRequestsCompleted(const TActorContext& ctx);
bool AllRequestsCompletedMKQL(const TActorContext& ctx);
bool AllRequestsCompletedReadTable(const TActorContext& ctx);
@@ -46,18 +46,18 @@ public:
return NKikimrServices::TActivity::FRONT_MKQL_REQUEST;
}
- TMessageBusServerRequest(TEvBusProxy::TEvRequest* msg)
- : TBase(msg->MsgContext)
- , Request(static_cast<TBusRequest*>(msg->MsgContext.ReleaseMessage()))
- , InFlyRequests(0)
+ TMessageBusServerRequest(TEvBusProxy::TEvRequest* msg)
+ : TBase(msg->MsgContext)
+ , Request(static_cast<TBusRequest*>(msg->MsgContext.ReleaseMessage()))
+ , InFlyRequests(0)
, CompilationRetried(false)
- {
- TBase::SetSecurityToken(Request->Record.GetSecurityToken());
- TBase::SetRequireAdminAccess(true); // MiniKQL and ReadTable execution required administative access
- }
+ {
+ TBase::SetSecurityToken(Request->Record.GetSecurityToken());
+ TBase::SetRequireAdminAccess(true); // MiniKQL and ReadTable execution required administative access
+ }
- //STFUNC(StateWork)
- void StateWork(TAutoPtr<NActors::IEventHandle> &ev, const NActors::TActorContext &ctx) {
+ //STFUNC(StateWork)
+ void StateWork(TAutoPtr<NActors::IEventHandle> &ev, const NActors::TActorContext &ctx) {
switch (ev->GetTypeRewrite()) {
HFunc(TMiniKQLCompileServiceEvents::TEvCompileStatus, Handle);
HFunc(TEvTxUserProxy::TEvProposeTransactionStatus, Handle);
@@ -65,81 +65,81 @@ public:
}
}
- void Bootstrap(const TActorContext &ctx) {
- TBase::Become(&TMessageBusServerRequest::StateWork);
+ void Bootstrap(const TActorContext &ctx) {
+ TBase::Become(&TMessageBusServerRequest::StateWork);
- ProposalStatus.Reset(new NKikimrTxUserProxy::TEvProposeTransactionStatus());
- Proposal.Reset(new TEvTxUserProxy::TEvProposeTransaction());
- NKikimrTxUserProxy::TEvProposeTransaction &record = Proposal->Record;
+ ProposalStatus.Reset(new NKikimrTxUserProxy::TEvProposeTransactionStatus());
+ Proposal.Reset(new TEvTxUserProxy::TEvProposeTransaction());
+ NKikimrTxUserProxy::TEvProposeTransaction &record = Proposal->Record;
// Transaction protobuf structure might be very heavy (if it has a batch of parameters)
// so we don't want to copy it, just move its contents
- record.MutableTransaction()->Swap(Request->Record.MutableTransaction());
-
- if (Request->Record.HasProxyFlags())
- record.SetProxyFlags(Request->Record.GetProxyFlags());
-
- if (Request->Record.HasExecTimeoutPeriod())
- record.SetExecTimeoutPeriod(Request->Record.GetExecTimeoutPeriod());
- else {
+ record.MutableTransaction()->Swap(Request->Record.MutableTransaction());
+
+ if (Request->Record.HasProxyFlags())
+ record.SetProxyFlags(Request->Record.GetProxyFlags());
+
+ if (Request->Record.HasExecTimeoutPeriod())
+ record.SetExecTimeoutPeriod(Request->Record.GetExecTimeoutPeriod());
+ else {
ui64 msgBusTimeout = GetTotalTimeout() * 3 / 4;
- if (msgBusTimeout > 3600000) // when we see something weird - rewrite with somewhat meaningful
- msgBusTimeout = 1800000;
- record.SetExecTimeoutPeriod(msgBusTimeout);
- }
-
+ if (msgBusTimeout > 3600000) // when we see something weird - rewrite with somewhat meaningful
+ msgBusTimeout = 1800000;
+ record.SetExecTimeoutPeriod(msgBusTimeout);
+ }
+
record.SetStreamResponse(false);
- auto* transaction = record.MutableTransaction();
- if (transaction->HasMiniKQLTransaction()) {
- auto& mkqlTx = *transaction->MutableMiniKQLTransaction();
- if (!mkqlTx.GetFlatMKQL()) {
- return HandleError(MSTATUS_ERROR, TEvTxUserProxy::TResultStatus::EStatus::NotImplemented, ctx);
- }
+ auto* transaction = record.MutableTransaction();
+ if (transaction->HasMiniKQLTransaction()) {
+ auto& mkqlTx = *transaction->MutableMiniKQLTransaction();
+ if (!mkqlTx.GetFlatMKQL()) {
+ return HandleError(MSTATUS_ERROR, TEvTxUserProxy::TResultStatus::EStatus::NotImplemented, ctx);
+ }
- if (mkqlTx.HasProgram() && mkqlTx.GetProgram().HasText()) {
+ if (mkqlTx.HasProgram() && mkqlTx.GetProgram().HasText()) {
TextProgramForCompilation = mkqlTx.GetProgram().GetText();
const bool forceRefresh = (mkqlTx.GetMode() == NKikimrTxUserProxy::TMiniKQLTransaction::COMPILE);
auto* compEv = new TMiniKQLCompileServiceEvents::TEvCompile(TextProgramForCompilation);
compEv->ForceRefresh = forceRefresh;
- ctx.Send(GetMiniKQLCompileServiceID(), compEv);
- ++InFlyRequests;
- }
- if (mkqlTx.HasParams()) {
- if (mkqlTx.GetParams().HasText()) {
+ ctx.Send(GetMiniKQLCompileServiceID(), compEv);
+ ++InFlyRequests;
+ }
+ if (mkqlTx.HasParams()) {
+ if (mkqlTx.GetParams().HasText()) {
auto* compEv = new TMiniKQLCompileServiceEvents::TEvCompile(mkqlTx.GetParams().GetText());
- ctx.Send(GetMiniKQLCompileServiceID(), compEv); // todo: handle undelivery (with warns atleast)
- ++InFlyRequests;
- } else
- if (mkqlTx.GetParams().HasProto()) {
- try {
+ ctx.Send(GetMiniKQLCompileServiceID(), compEv); // todo: handle undelivery (with warns atleast)
+ ++InFlyRequests;
+ } else
+ if (mkqlTx.GetParams().HasProto()) {
+ try {
TAlignedPagePoolCounters counters(AppData(ctx)->Counters, "params");
NMiniKQL::TScopedAlloc alloc(counters, AppData(ctx)->FunctionRegistry->SupportsSizedAllocators());
NMiniKQL::TTypeEnvironment env(alloc);
- NMiniKQL::TRuntimeNode node = NMiniKQL::ImportValueFromProto(mkqlTx.GetParams().GetProto(), env);
+ NMiniKQL::TRuntimeNode node = NMiniKQL::ImportValueFromProto(mkqlTx.GetParams().GetProto(), env);
TString bin = NMiniKQL::SerializeRuntimeNode(node, env);
- mkqlTx.MutableParams()->ClearProto();
- mkqlTx.MutableParams()->SetBin(bin);
- }
- catch(const yexception& e) {
- NKikimrTxUserProxy::TEvProposeTransactionStatus status;
- *status.MutableMiniKQLErrors() = e.what();
- return ReplyWithResult(EResponseStatus::MSTATUS_ERROR, status, ctx);
- }
- }
- }
- if (InFlyRequests == 0) {
- AllRequestsCompleted(ctx);
- }
- return;
+ mkqlTx.MutableParams()->ClearProto();
+ mkqlTx.MutableParams()->SetBin(bin);
+ }
+ catch(const yexception& e) {
+ NKikimrTxUserProxy::TEvProposeTransactionStatus status;
+ *status.MutableMiniKQLErrors() = e.what();
+ return ReplyWithResult(EResponseStatus::MSTATUS_ERROR, status, ctx);
+ }
+ }
+ }
+ if (InFlyRequests == 0) {
+ AllRequestsCompleted(ctx);
+ }
+ return;
} else if (transaction->HasReadTableTransaction()) {
NKikimrTxUserProxy::TEvProposeTransactionStatus status;
return ReplyWithResult(EResponseStatus::MSTATUS_ERROR, status, ctx);
}
- ctx.Send(MakeTxProxyID(), Proposal.Release());
+ ctx.Send(MakeTxProxyID(), Proposal.Release());
}
-};
+};
bool TMessageBusServerRequest::RetryResolve(const TActorContext &ctx) {
if (CompilationRetried || !TextProgramForCompilation)
@@ -167,9 +167,9 @@ void TMessageBusServerRequest::ReplyWithResult(EResponseStatus status,
if (result.HasSerializedReadTableResponse()) {
response->Record.SetSerializedReadTableResponse(result.GetSerializedReadTableResponse());
}
- if (result.HasStatus()) {
- response->Record.SetProxyErrorCode(result.GetStatus());
- }
+ if (result.HasStatus()) {
+ response->Record.SetProxyErrorCode(result.GetStatus());
+ }
if (result.HasTxStats()) {
response->Record.MutableTxStats()->Swap(result.MutableTxStats());
@@ -209,7 +209,7 @@ void TMessageBusServerRequest::Handle(TMiniKQLCompileServiceEvents::TEvCompileSt
} else {
NYql::IssuesToMessage(result.Errors, compileResults->MutableProgramCompileErrors());
}
- --InFlyRequests;
+ --InFlyRequests;
CompileResolveCookies = std::move(ev->Get()->CompileResolveCookies);
}
@@ -223,15 +223,15 @@ void TMessageBusServerRequest::Handle(TMiniKQLCompileServiceEvents::TEvCompileSt
} else {
NYql::IssuesToMessage(result.Errors, compileResults->MutableParamsCompileErrors());
}
- --InFlyRequests;
+ --InFlyRequests;
}
- if (InFlyRequests == 0) {
- AllRequestsCompleted(ctx);
+ if (InFlyRequests == 0) {
+ AllRequestsCompleted(ctx);
}
}
-bool TMessageBusServerRequest::AllRequestsCompleted(const TActorContext& ctx) {
+bool TMessageBusServerRequest::AllRequestsCompleted(const TActorContext& ctx) {
auto &transaction = Proposal->Record.GetTransaction();
if (transaction.HasMiniKQLTransaction())
return AllRequestsCompletedMKQL(ctx);
@@ -256,14 +256,14 @@ bool TMessageBusServerRequest::AllRequestsCompletedMKQL(const TActorContext& ctx
return false;
}
- NKikimrTxUserProxy::TEvProposeTransaction &record = Proposal->Record;
- record.SetUserToken(TBase::GetSerializedToken());
-
+ NKikimrTxUserProxy::TEvProposeTransaction &record = Proposal->Record;
+ record.SetUserToken(TBase::GetSerializedToken());
+
switch (mkqlTx->GetMode()) {
case NKikimrTxUserProxy::TMiniKQLTransaction::COMPILE_AND_EXEC: {
TAutoPtr<TEvTxUserProxy::TEvProposeTransaction> ev = new TEvTxUserProxy::TEvProposeTransaction();
ev->Record.CopyFrom(Proposal->Record);
- ctx.Send(MakeTxProxyID(), ev.Release());
+ ctx.Send(MakeTxProxyID(), ev.Release());
return true;
}
case NKikimrTxUserProxy::TMiniKQLTransaction::COMPILE: {
@@ -298,7 +298,7 @@ void TMessageBusServerRequest::Handle(TEvTxUserProxy::TEvProposeTransactionStatu
return HandleError(MSTATUS_ABORTED, status, ctx);
case TEvTxUserProxy::TEvProposeTransactionStatus::EStatus::EmptyAffectedSet:
case TEvTxUserProxy::TEvProposeTransactionStatus::EStatus::ExecError:
- case TEvTxUserProxy::TEvProposeTransactionStatus::EStatus::AccessDenied:
+ case TEvTxUserProxy::TEvProposeTransactionStatus::EStatus::AccessDenied:
case TEvTxUserProxy::TEvProposeTransactionStatus::EStatus::DomainLocalityError:
case TEvTxUserProxy::TEvProposeTransactionStatus::EStatus::ExecResultUnavailable:
case TEvTxUserProxy::TEvProposeTransactionStatus::EStatus::ExecCancelled:
@@ -335,9 +335,9 @@ void TMessageBusServerRequest::Handle(TEvDataShard::TEvGetReadTableStreamStateRe
ctx.Send(ev->Sender, response);
}
-void TMessageBusServerProxy::Handle(TEvBusProxy::TEvRequest::TPtr& ev, const TActorContext& ctx) {
- ctx.Register(new TMessageBusServerRequest(ev->Get()));
+void TMessageBusServerProxy::Handle(TEvBusProxy::TEvRequest::TPtr& ev, const TActorContext& ctx) {
+ ctx.Register(new TMessageBusServerRequest(ev->Get()));
+}
+
}
-
}
-}
diff --git a/ydb/core/client/server/msgbus_server_request.h b/ydb/core/client/server/msgbus_server_request.h
index d7665fe1c60..b77d50983e6 100644
--- a/ydb/core/client/server/msgbus_server_request.h
+++ b/ydb/core/client/server/msgbus_server_request.h
@@ -1,36 +1,36 @@
-#pragma once
-
+#pragma once
+
#include <ydb/core/tx/tx_proxy/proxy.h>
-#include "msgbus_server.h"
-#include "msgbus_server_proxy.h"
-
-namespace NKikimr {
-namespace NMsgBusProxy {
-
-template <typename TDerived>
-class TMessageBusServerRequestBase : public TActorBootstrapped<TDerived>, public TMessageBusSessionIdentHolder {
-public:
+#include "msgbus_server.h"
+#include "msgbus_server_proxy.h"
+
+namespace NKikimr {
+namespace NMsgBusProxy {
+
+template <typename TDerived>
+class TMessageBusServerRequestBase : public TActorBootstrapped<TDerived>, public TMessageBusSessionIdentHolder {
+public:
static constexpr NKikimrServices::TActivity::EType ActorActivityType() { return NKikimrServices::TActivity::MSGBUS_PROXY_ACTOR; }
-
- TMessageBusServerRequestBase(TBusMessageContext &msg) {
- InitSession(msg);
- }
-
- void HandleError(EResponseStatus status, TEvTxUserProxy::TResultStatus::EStatus proxyStatus, const TActorContext &ctx) {
- HandleError(status, proxyStatus, TEvTxUserProxy::TResultStatus::Str(proxyStatus), ctx);
- }
-
+
+ TMessageBusServerRequestBase(TBusMessageContext &msg) {
+ InitSession(msg);
+ }
+
+ void HandleError(EResponseStatus status, TEvTxUserProxy::TResultStatus::EStatus proxyStatus, const TActorContext &ctx) {
+ HandleError(status, proxyStatus, TEvTxUserProxy::TResultStatus::Str(proxyStatus), ctx);
+ }
+
void HandleError(EResponseStatus status, TEvTxUserProxy::TResultStatus::EStatus proxyStatus, const TString& message, const TActorContext &ctx) {
- TAutoPtr<TBusResponse> response(new TBusResponseStatus(status, message));
-
- if (proxyStatus != TEvTxUserProxy::TResultStatus::Unknown)
- response->Record.SetProxyErrorCode(proxyStatus);
-
- SendReplyAutoPtr(response);
+ TAutoPtr<TBusResponse> response(new TBusResponseStatus(status, message));
+
+ if (proxyStatus != TEvTxUserProxy::TResultStatus::Unknown)
+ response->Record.SetProxyErrorCode(proxyStatus);
+
+ SendReplyAutoPtr(response);
this->Die(ctx);
- }
-};
-
-}
-}
+ }
+};
+
+}
+}
diff --git a/ydb/core/client/server/msgbus_server_resolve_node.cpp b/ydb/core/client/server/msgbus_server_resolve_node.cpp
index fa9c79f055a..762df383cb8 100644
--- a/ydb/core/client/server/msgbus_server_resolve_node.cpp
+++ b/ydb/core/client/server/msgbus_server_resolve_node.cpp
@@ -1,92 +1,92 @@
-#include "msgbus_servicereq.h"
+#include "msgbus_servicereq.h"
#include <library/cpp/actors/core/interconnect.h>
#include <library/cpp/actors/interconnect/interconnect.h>
-
-namespace NKikimr {
-namespace NMsgBusProxy {
-
+
+namespace NKikimr {
+namespace NMsgBusProxy {
+
class TMessageBusResolveNode : public TMessageBusLocalServiceRequest<TMessageBusResolveNode, NKikimrServices::TActivity::MSGBUS_COMMON> {
using TBase = TMessageBusLocalServiceRequest<TMessageBusResolveNode, NKikimrServices::TActivity::MSGBUS_COMMON>;
- NKikimrClient::TResolveNodeRequest ResolveRequest;
-
-public:
- TMessageBusResolveNode(TBusMessageContext& msg)
- : TBase(msg, TDuration::Seconds(600))
- , ResolveRequest(static_cast<TBusResolveNode*>(msg.GetMessage())->Record)
- {}
-
+ NKikimrClient::TResolveNodeRequest ResolveRequest;
+
+public:
+ TMessageBusResolveNode(TBusMessageContext& msg)
+ : TBase(msg, TDuration::Seconds(600))
+ , ResolveRequest(static_cast<TBusResolveNode*>(msg.GetMessage())->Record)
+ {}
+
static TActorId MakeServiceID(const TActorContext&) {
return GetNameserviceActorId();
- }
-
- TEvInterconnect::TEvListNodes* MakeReq(const TActorContext&) {
- return new TEvInterconnect::TEvListNodes();
- }
-
- void HandleTimeout(const TActorContext& ctx) {
- TBase::SendReplyAndDie(new TBusResponseStatus(MSTATUS_TIMEOUT), ctx);
- }
-
- static bool CheckName(const TString& request, const TString& name) {
- return name.StartsWith(request) && (name.size() == request.size() || (name.size() > request.size() && name[request.size()] == '.'));
- }
-
- void Handle(TEvInterconnect::TEvNodesInfo::TPtr& ev, const TActorContext& ctx) {
- const TEvInterconnect::TEvNodesInfo& nodesInfo = *ev->Get();
- THolder<TBusResponse> response(new TBusResponse());
+ }
+
+ TEvInterconnect::TEvListNodes* MakeReq(const TActorContext&) {
+ return new TEvInterconnect::TEvListNodes();
+ }
+
+ void HandleTimeout(const TActorContext& ctx) {
+ TBase::SendReplyAndDie(new TBusResponseStatus(MSTATUS_TIMEOUT), ctx);
+ }
+
+ static bool CheckName(const TString& request, const TString& name) {
+ return name.StartsWith(request) && (name.size() == request.size() || (name.size() > request.size() && name[request.size()] == '.'));
+ }
+
+ void Handle(TEvInterconnect::TEvNodesInfo::TPtr& ev, const TActorContext& ctx) {
+ const TEvInterconnect::TEvNodesInfo& nodesInfo = *ev->Get();
+ THolder<TBusResponse> response(new TBusResponse());
TVector<TVector<TEvInterconnect::TNodeInfo>::const_iterator> items;
- if (ResolveRequest.GetResolveLocalNode() || ResolveRequest.GetHost() == ".") {
- ui32 localNodeId = SelfId().NodeId();
- for (auto it = nodesInfo.Nodes.begin(); it != nodesInfo.Nodes.end(); ++it) {
- if (it->NodeId == localNodeId) {
- items.push_back(it);
- break;
- }
- }
- } else {
- for (auto it = nodesInfo.Nodes.begin(); it != nodesInfo.Nodes.end(); ++it) {
- if (ResolveRequest.HasHost()) {
- const TString& host(ResolveRequest.GetHost());
- if (CheckName(host, it->Host) || CheckName(host, it->ResolveHost)) {
- items.push_back(it);
- continue;
- }
- }
- if (ResolveRequest.HasNodeId()) {
- if (it->NodeId == ResolveRequest.GetNodeId()) {
- items.push_back(it);
- continue;
- }
- }
- }
- }
- if (items.size() != 1) {
- response->Record.SetStatus(MSTATUS_ERROR);
- if (items.empty()) {
- response->Record.SetErrorReason("Could not resolve the node");
- } else {
- response->Record.SetErrorReason("More than one node resolved");
- }
- } else {
- response->Record.SetStatus(MSTATUS_OK);
- response->Record.MutableResolveNodeResponse()->SetHost(items.front()->Host);
- response->Record.MutableResolveNodeResponse()->SetNodeId(items.front()->NodeId);
- }
-
- TBase::SendReplyAndDie(response.Release(), ctx);
- }
-
- STFUNC(StateFunc) {
- switch (ev->GetTypeRewrite()) {
- HFunc(TEvInterconnect::TEvNodesInfo, Handle);
- CFunc(TEvents::TSystem::Wakeup, HandleTimeout);
- }
- }
-};
-
-IActor* CreateMessageBusResolveNode(TBusMessageContext &msg) {
- return new TMessageBusResolveNode(msg);
-}
-
-}
-}
+ if (ResolveRequest.GetResolveLocalNode() || ResolveRequest.GetHost() == ".") {
+ ui32 localNodeId = SelfId().NodeId();
+ for (auto it = nodesInfo.Nodes.begin(); it != nodesInfo.Nodes.end(); ++it) {
+ if (it->NodeId == localNodeId) {
+ items.push_back(it);
+ break;
+ }
+ }
+ } else {
+ for (auto it = nodesInfo.Nodes.begin(); it != nodesInfo.Nodes.end(); ++it) {
+ if (ResolveRequest.HasHost()) {
+ const TString& host(ResolveRequest.GetHost());
+ if (CheckName(host, it->Host) || CheckName(host, it->ResolveHost)) {
+ items.push_back(it);
+ continue;
+ }
+ }
+ if (ResolveRequest.HasNodeId()) {
+ if (it->NodeId == ResolveRequest.GetNodeId()) {
+ items.push_back(it);
+ continue;
+ }
+ }
+ }
+ }
+ if (items.size() != 1) {
+ response->Record.SetStatus(MSTATUS_ERROR);
+ if (items.empty()) {
+ response->Record.SetErrorReason("Could not resolve the node");
+ } else {
+ response->Record.SetErrorReason("More than one node resolved");
+ }
+ } else {
+ response->Record.SetStatus(MSTATUS_OK);
+ response->Record.MutableResolveNodeResponse()->SetHost(items.front()->Host);
+ response->Record.MutableResolveNodeResponse()->SetNodeId(items.front()->NodeId);
+ }
+
+ TBase::SendReplyAndDie(response.Release(), ctx);
+ }
+
+ STFUNC(StateFunc) {
+ switch (ev->GetTypeRewrite()) {
+ HFunc(TEvInterconnect::TEvNodesInfo, Handle);
+ CFunc(TEvents::TSystem::Wakeup, HandleTimeout);
+ }
+ }
+};
+
+IActor* CreateMessageBusResolveNode(TBusMessageContext &msg) {
+ return new TMessageBusResolveNode(msg);
+}
+
+}
+}
diff --git a/ydb/core/client/server/msgbus_server_scheme_initroot.cpp b/ydb/core/client/server/msgbus_server_scheme_initroot.cpp
index ddae127dc54..a8538eea1cb 100644
--- a/ydb/core/client/server/msgbus_server_scheme_initroot.cpp
+++ b/ydb/core/client/server/msgbus_server_scheme_initroot.cpp
@@ -1,7 +1,7 @@
-#include "msgbus_server.h"
-#include "msgbus_server_proxy.h"
-#include "msgbus_server_request.h"
-#include "msgbus_securereq.h"
+#include "msgbus_server.h"
+#include "msgbus_server_proxy.h"
+#include "msgbus_server_request.h"
+#include "msgbus_securereq.h"
#include <ydb/core/tx/schemeshard/schemeshard.h>
#include <ydb/core/tx/tx_proxy/proxy.h>
#include <ydb/core/base/appdata.h>
@@ -13,17 +13,17 @@ namespace NMsgBusProxy {
using namespace NSchemeShard;
-class TMessageBusSchemeInitRoot : public TMessageBusSecureRequest<TMessageBusServerRequestBase<TMessageBusSchemeInitRoot>> {
- using TBase = TMessageBusSecureRequest<TMessageBusServerRequestBase<TMessageBusSchemeInitRoot>>;
- THolder<TBusSchemeInitRoot> Request;
- const bool WithRetry = true;
+class TMessageBusSchemeInitRoot : public TMessageBusSecureRequest<TMessageBusServerRequestBase<TMessageBusSchemeInitRoot>> {
+ using TBase = TMessageBusSecureRequest<TMessageBusServerRequestBase<TMessageBusSchemeInitRoot>>;
+ THolder<TBusSchemeInitRoot> Request;
+ const bool WithRetry = true;
TActorId PipeClient;
void ReplyWithResult(EResponseStatus status, TEvSchemeShard::TEvInitRootShardResult::EStatus ssStatus, const TActorContext &ctx) {
- TAutoPtr<TBusResponseStatus> response(new TBusResponseStatus(status));
- response->Record.SetSchemeStatus(ssStatus);
- SendReplyAutoPtr(response);
- Request.Destroy();
+ TAutoPtr<TBusResponseStatus> response(new TBusResponseStatus(status));
+ response->Record.SetSchemeStatus(ssStatus);
+ SendReplyAutoPtr(response);
+ Request.Destroy();
Die(ctx);
}
@@ -33,66 +33,66 @@ class TMessageBusSchemeInitRoot : public TMessageBusSecureRequest<TMessageBusSer
switch (status) {
case TEvSchemeShard::TEvInitRootShardResult::StatusSuccess:
case TEvSchemeShard::TEvInitRootShardResult::StatusAlreadyInitialized:
- return ReplyWithResult(MSTATUS_OK, status, ctx);
+ return ReplyWithResult(MSTATUS_OK, status, ctx);
default:
- return ReplyWithResult(MSTATUS_ERROR, status, ctx);
+ return ReplyWithResult(MSTATUS_ERROR, status, ctx);
}
}
- void Die(const TActorContext &ctx) override {
- if (PipeClient) {
- NTabletPipe::CloseClient(ctx, PipeClient);
+ void Die(const TActorContext &ctx) override {
+ if (PipeClient) {
+ NTabletPipe::CloseClient(ctx, PipeClient);
PipeClient = TActorId();
- }
- TBase::Die(ctx);
- }
-
-public:
- TMessageBusSchemeInitRoot(TEvBusProxy::TEvInitRoot *msg)
- : TBase(msg->MsgContext)
- , Request(static_cast<TBusSchemeInitRoot*>(msg->MsgContext.ReleaseMessage()))
- {
- TBase::SetSecurityToken(Request->Record.GetSecurityToken());
- TBase::SetRequireAdminAccess(true);
- }
-
- void Bootstrap(const TActorContext &ctx) {
- SendRequest(ctx);
- Become(&TMessageBusSchemeInitRoot::StateWork);
- }
-
- //STFUNC(StateWork)
- void StateWork(TAutoPtr<NActors::IEventHandle> &ev, const NActors::TActorContext &ctx) {
- switch (ev->GetTypeRewrite()) {
+ }
+ TBase::Die(ctx);
+ }
+
+public:
+ TMessageBusSchemeInitRoot(TEvBusProxy::TEvInitRoot *msg)
+ : TBase(msg->MsgContext)
+ , Request(static_cast<TBusSchemeInitRoot*>(msg->MsgContext.ReleaseMessage()))
+ {
+ TBase::SetSecurityToken(Request->Record.GetSecurityToken());
+ TBase::SetRequireAdminAccess(true);
+ }
+
+ void Bootstrap(const TActorContext &ctx) {
+ SendRequest(ctx);
+ Become(&TMessageBusSchemeInitRoot::StateWork);
+ }
+
+ //STFUNC(StateWork)
+ void StateWork(TAutoPtr<NActors::IEventHandle> &ev, const NActors::TActorContext &ctx) {
+ switch (ev->GetTypeRewrite()) {
HFunc(TEvSchemeShard::TEvInitRootShardResult, Handle);
- }
- }
-
- void SendRequest(const TActorContext &ctx) {
- TString tagName = Request->Record.GetTagName();
- const TDomainsInfo::TDomain *domain = AppData(ctx)->DomainsInfo->GetDomainByName(tagName);
- if (domain != nullptr) {
+ }
+ }
+
+ void SendRequest(const TActorContext &ctx) {
+ TString tagName = Request->Record.GetTagName();
+ const TDomainsInfo::TDomain *domain = AppData(ctx)->DomainsInfo->GetDomainByName(tagName);
+ if (domain != nullptr) {
THolder<TEvSchemeShard::TEvInitRootShard> x = MakeHolder<TEvSchemeShard::TEvInitRootShard>(ctx.SelfID, domain->DomainRootTag(), domain->Name);
- if (Request->Record.HasGlobalConfig()) {
- x->Record.MutableConfig()->MergeFrom(Request->Record.GetGlobalConfig());
- }
- x->Record.SetOwner(TBase::GetUserSID());
- x->Record.MutableStoragePools()->CopyFrom(Request->Record.GetStoragePools());
- NTabletPipe::TClientConfig clientConfig;
- if (WithRetry) {
- clientConfig.RetryPolicy = NTabletPipe::TClientRetryPolicy::WithRetries();
- }
+ if (Request->Record.HasGlobalConfig()) {
+ x->Record.MutableConfig()->MergeFrom(Request->Record.GetGlobalConfig());
+ }
+ x->Record.SetOwner(TBase::GetUserSID());
+ x->Record.MutableStoragePools()->CopyFrom(Request->Record.GetStoragePools());
+ NTabletPipe::TClientConfig clientConfig;
+ if (WithRetry) {
+ clientConfig.RetryPolicy = NTabletPipe::TClientRetryPolicy::WithRetries();
+ }
PipeClient = ctx.RegisterWithSameMailbox(NTabletPipe::CreateClient(ctx.SelfID, domain->SchemeRoot, clientConfig));
- NTabletPipe::SendData(ctx, PipeClient, x.Release());
- } else {
+ NTabletPipe::SendData(ctx, PipeClient, x.Release());
+ } else {
ReplyWithResult(MSTATUS_ERROR, TEvSchemeShard::TEvInitRootShardResult::StatusBadArgument, ctx);
- }
- }
+ }
+ }
};
-void TMessageBusServerProxy::Handle(TEvBusProxy::TEvInitRoot::TPtr& ev, const TActorContext& ctx) {
- TEvBusProxy::TEvInitRoot *msg = ev->Get();
- ctx.Register(new TMessageBusSchemeInitRoot(msg));
+void TMessageBusServerProxy::Handle(TEvBusProxy::TEvInitRoot::TPtr& ev, const TActorContext& ctx) {
+ TEvBusProxy::TEvInitRoot *msg = ev->Get();
+ ctx.Register(new TMessageBusSchemeInitRoot(msg));
}
}
diff --git a/ydb/core/client/server/msgbus_server_scheme_request.cpp b/ydb/core/client/server/msgbus_server_scheme_request.cpp
index ea20adf7256..7df5e262d07 100644
--- a/ydb/core/client/server/msgbus_server_scheme_request.cpp
+++ b/ydb/core/client/server/msgbus_server_scheme_request.cpp
@@ -1,37 +1,37 @@
#include <ydb/core/base/ticket_parser.h>
-#include "msgbus_server.h"
-#include "msgbus_server_request.h"
-#include "msgbus_server_proxy.h"
-#include "msgbus_server_persqueue.h"
-#include "msgbus_securereq.h"
-
-namespace NKikimr {
-namespace NMsgBusProxy {
-
-template <typename T>
-class TMessageBusServerSchemeRequest : public TMessageBusSecureRequest<TMessageBusServerRequestBase<TMessageBusServerSchemeRequest<T>>> {
- using TBase = TMessageBusSecureRequest<TMessageBusServerRequestBase<TMessageBusServerSchemeRequest<T>>>;
- THolder<T> Request;
-
- void Handle(TEvTxUserProxy::TEvProposeTransactionStatus::TPtr& ev, const TActorContext& ctx) {
- TEvTxUserProxy::TEvProposeTransactionStatus* msg = ev->Get();
- const TEvTxUserProxy::TEvProposeTransactionStatus::EStatus status = static_cast<TEvTxUserProxy::TEvProposeTransactionStatus::EStatus>(msg->Record.GetStatus());
- switch (status) {
- case TEvTxUserProxy::TEvProposeTransactionStatus::EStatus::ExecComplete:
- // completion
- return ReplyWithResult(MSTATUS_OK, msg->Record, ctx);
- case TEvTxUserProxy::TEvProposeTransactionStatus::EStatus::ExecError:
- // completion
- return ReplyWithResult(MSTATUS_ERROR, msg->Record, ctx);
- case TEvTxUserProxy::TEvProposeTransactionStatus::EStatus::ExecInProgress:
- return ReplyWithResult(MSTATUS_INPROGRESS, msg->Record, ctx);
- default:
- return ReplyWithResult(MSTATUS_ERROR, msg->Record, ctx);
- }
- }
-
- void ReplyWithResult(EResponseStatus status, const NKikimrTxUserProxy::TEvProposeTransactionStatus &result, const TActorContext &ctx);
-
+#include "msgbus_server.h"
+#include "msgbus_server_request.h"
+#include "msgbus_server_proxy.h"
+#include "msgbus_server_persqueue.h"
+#include "msgbus_securereq.h"
+
+namespace NKikimr {
+namespace NMsgBusProxy {
+
+template <typename T>
+class TMessageBusServerSchemeRequest : public TMessageBusSecureRequest<TMessageBusServerRequestBase<TMessageBusServerSchemeRequest<T>>> {
+ using TBase = TMessageBusSecureRequest<TMessageBusServerRequestBase<TMessageBusServerSchemeRequest<T>>>;
+ THolder<T> Request;
+
+ void Handle(TEvTxUserProxy::TEvProposeTransactionStatus::TPtr& ev, const TActorContext& ctx) {
+ TEvTxUserProxy::TEvProposeTransactionStatus* msg = ev->Get();
+ const TEvTxUserProxy::TEvProposeTransactionStatus::EStatus status = static_cast<TEvTxUserProxy::TEvProposeTransactionStatus::EStatus>(msg->Record.GetStatus());
+ switch (status) {
+ case TEvTxUserProxy::TEvProposeTransactionStatus::EStatus::ExecComplete:
+ // completion
+ return ReplyWithResult(MSTATUS_OK, msg->Record, ctx);
+ case TEvTxUserProxy::TEvProposeTransactionStatus::EStatus::ExecError:
+ // completion
+ return ReplyWithResult(MSTATUS_ERROR, msg->Record, ctx);
+ case TEvTxUserProxy::TEvProposeTransactionStatus::EStatus::ExecInProgress:
+ return ReplyWithResult(MSTATUS_INPROGRESS, msg->Record, ctx);
+ default:
+ return ReplyWithResult(MSTATUS_ERROR, msg->Record, ctx);
+ }
+ }
+
+ void ReplyWithResult(EResponseStatus status, const NKikimrTxUserProxy::TEvProposeTransactionStatus &result, const TActorContext &ctx);
+
void FillStatus(EResponseStatus status, const NKikimrTxUserProxy::TEvProposeTransactionStatus &result, TBusResponse* response)
{
response->Record.SetStatus(status);
@@ -64,63 +64,63 @@ class TMessageBusServerSchemeRequest : public TMessageBusSecureRequest<TMessageB
}
-public:
+public:
static constexpr NKikimrServices::TActivity::EType ActorActivityType() { return NKikimrServices::TActivity::FRONT_SCHEME_REQUEST; }
- template <TEvBusProxy::EEv EvId>
- TMessageBusServerSchemeRequest(TEvBusProxy::TEvMsgBusRequest<EvId>* msg)
- : TBase(msg->MsgContext)
- , Request(static_cast<T*>(msg->MsgContext.ReleaseMessage()))
- {
- TBase::SetSecurityToken(Request->Record.GetSecurityToken());
- TBase::SetRequireAdminAccess(true);
- }
-
- //STFUNC(StateWork)
- void StateWork(TAutoPtr<NActors::IEventHandle> &ev, const NActors::TActorContext &ctx) {
- switch (ev->GetTypeRewrite()) {
- HFunc(TEvTxUserProxy::TEvProposeTransactionStatus, Handle);
- }
- }
-
- void Bootstrap(const TActorContext &ctx) {
- SendProposeRequest(ctx);
- TBase::Become(&TMessageBusServerSchemeRequest::StateWork);
- }
-
- void SendProposeRequest(const TActorContext &ctx);
-};
-
-template <>
-void TMessageBusServerSchemeRequest<TBusPersQueue>::SendProposeRequest(const TActorContext &ctx) {
- TAutoPtr<TEvTxUserProxy::TEvProposeTransaction> req(new TEvTxUserProxy::TEvProposeTransaction());
- NKikimrTxUserProxy::TEvProposeTransaction &record = req->Record;
-
- if (Request->Record.HasMetaRequest() && Request->Record.GetMetaRequest().HasCmdCreateTopic()) {
- const auto& cmd = Request->Record.GetMetaRequest().GetCmdCreateTopic();
- auto *transaction = record.MutableTransaction()->MutableModifyScheme();
+ template <TEvBusProxy::EEv EvId>
+ TMessageBusServerSchemeRequest(TEvBusProxy::TEvMsgBusRequest<EvId>* msg)
+ : TBase(msg->MsgContext)
+ , Request(static_cast<T*>(msg->MsgContext.ReleaseMessage()))
+ {
+ TBase::SetSecurityToken(Request->Record.GetSecurityToken());
+ TBase::SetRequireAdminAccess(true);
+ }
+
+ //STFUNC(StateWork)
+ void StateWork(TAutoPtr<NActors::IEventHandle> &ev, const NActors::TActorContext &ctx) {
+ switch (ev->GetTypeRewrite()) {
+ HFunc(TEvTxUserProxy::TEvProposeTransactionStatus, Handle);
+ }
+ }
+
+ void Bootstrap(const TActorContext &ctx) {
+ SendProposeRequest(ctx);
+ TBase::Become(&TMessageBusServerSchemeRequest::StateWork);
+ }
+
+ void SendProposeRequest(const TActorContext &ctx);
+};
+
+template <>
+void TMessageBusServerSchemeRequest<TBusPersQueue>::SendProposeRequest(const TActorContext &ctx) {
+ TAutoPtr<TEvTxUserProxy::TEvProposeTransaction> req(new TEvTxUserProxy::TEvProposeTransaction());
+ NKikimrTxUserProxy::TEvProposeTransaction &record = req->Record;
+
+ if (Request->Record.HasMetaRequest() && Request->Record.GetMetaRequest().HasCmdCreateTopic()) {
+ const auto& cmd = Request->Record.GetMetaRequest().GetCmdCreateTopic();
+ auto *transaction = record.MutableTransaction()->MutableModifyScheme();
transaction->SetWorkingDir(TopicPrefix(ctx));
transaction->SetOperationType(NKikimrSchemeOp::ESchemeOpCreatePersQueueGroup);
- auto *pqgroup = transaction->MutableCreatePersQueueGroup();
- pqgroup->SetName(cmd.GetTopic());
+ auto *pqgroup = transaction->MutableCreatePersQueueGroup();
+ pqgroup->SetName(cmd.GetTopic());
pqgroup->SetTotalGroupCount(cmd.GetNumPartitions());
pqgroup->SetPartitionPerTablet(cmd.GetNumPartitionsPerTablet());
- pqgroup->MutablePQTabletConfig()->MergeFrom(cmd.GetConfig());
- }
-
- if (Request->Record.HasMetaRequest() && Request->Record.GetMetaRequest().HasCmdChangeTopic()) {
- const auto& cmd = Request->Record.GetMetaRequest().GetCmdChangeTopic();
- auto *transaction = record.MutableTransaction()->MutableModifyScheme();
+ pqgroup->MutablePQTabletConfig()->MergeFrom(cmd.GetConfig());
+ }
+
+ if (Request->Record.HasMetaRequest() && Request->Record.GetMetaRequest().HasCmdChangeTopic()) {
+ const auto& cmd = Request->Record.GetMetaRequest().GetCmdChangeTopic();
+ auto *transaction = record.MutableTransaction()->MutableModifyScheme();
transaction->SetWorkingDir(TopicPrefix(ctx));
transaction->SetOperationType(NKikimrSchemeOp::ESchemeOpAlterPersQueueGroup);
- auto *pqgroup = transaction->MutableAlterPersQueueGroup();
- pqgroup->SetName(cmd.GetTopic());
- if (cmd.HasNumPartitions())
+ auto *pqgroup = transaction->MutableAlterPersQueueGroup();
+ pqgroup->SetName(cmd.GetTopic());
+ if (cmd.HasNumPartitions())
pqgroup->SetTotalGroupCount(cmd.GetNumPartitions());
- if (cmd.HasConfig())
- pqgroup->MutablePQTabletConfig()->MergeFrom(cmd.GetConfig());
- }
-
+ if (cmd.HasConfig())
+ pqgroup->MutablePQTabletConfig()->MergeFrom(cmd.GetConfig());
+ }
+
if (Request->Record.HasMetaRequest() && Request->Record.GetMetaRequest().HasCmdDeleteTopic()) {
const auto& cmd = Request->Record.GetMetaRequest().GetCmdDeleteTopic();
auto *transaction = record.MutableTransaction()->MutableModifyScheme();
@@ -130,100 +130,100 @@ void TMessageBusServerSchemeRequest<TBusPersQueue>::SendProposeRequest(const TAc
pqgroup->SetName(cmd.GetTopic());
}
- req->Record.SetUserToken(TBase::GetSerializedToken());
-
- ctx.Send(MakeTxProxyID(), req.Release());
-}
-
-template <>
-void TMessageBusServerSchemeRequest<TBusPersQueue>::ReplyWithResult(EResponseStatus status, const NKikimrTxUserProxy::TEvProposeTransactionStatus &result, const TActorContext &ctx) {
- TAutoPtr<TBusResponse> response(new TBusResponse());
+ req->Record.SetUserToken(TBase::GetSerializedToken());
+
+ ctx.Send(MakeTxProxyID(), req.Release());
+}
+
+template <>
+void TMessageBusServerSchemeRequest<TBusPersQueue>::ReplyWithResult(EResponseStatus status, const NKikimrTxUserProxy::TEvProposeTransactionStatus &result, const TActorContext &ctx) {
+ TAutoPtr<TBusResponse> response(new TBusResponse());
FillStatus(status, result, response.Get());
if (result.GetSchemeShardStatus() == NKikimrScheme::StatusPathDoesNotExist) {
response->Record.SetErrorCode(NPersQueue::NErrorCode::UNKNOWN_TOPIC);
} else if (status == MSTATUS_OK || status == MSTATUS_INPROGRESS)
response->Record.SetErrorCode(NPersQueue::NErrorCode::OK);
- else
+ else
response->Record.SetErrorCode(NPersQueue::NErrorCode::ERROR);
- if (result.HasSchemeShardReason()) {
- response->Record.SetErrorReason(result.GetSchemeShardReason());
- }
- SendReplyAutoPtr(response);
- Request.Destroy();
+ if (result.HasSchemeShardReason()) {
+ response->Record.SetErrorReason(result.GetSchemeShardReason());
+ }
+ SendReplyAutoPtr(response);
+ Request.Destroy();
Die(ctx);
-}
-
-template <>
+}
+
+template <>
void TMessageBusServerSchemeRequest<TBusSchemeOperation>::SendProposeRequest(const TActorContext &ctx) {
- TAutoPtr<TEvTxUserProxy::TEvProposeTransaction> req(new TEvTxUserProxy::TEvProposeTransaction());
- NKikimrTxUserProxy::TEvProposeTransaction &record = req->Record;
-
+ TAutoPtr<TEvTxUserProxy::TEvProposeTransaction> req(new TEvTxUserProxy::TEvProposeTransaction());
+ NKikimrTxUserProxy::TEvProposeTransaction &record = req->Record;
+
if (!Request->Record.HasTransaction()) {
- return HandleError(MSTATUS_ERROR, TEvTxUserProxy::TResultStatus::Unknown, "Malformed request: no modify scheme transaction provided", ctx);
+ return HandleError(MSTATUS_ERROR, TEvTxUserProxy::TResultStatus::Unknown, "Malformed request: no modify scheme transaction provided", ctx);
}
-
+
if (!Request->Record.GetTransaction().HasModifyScheme()) {
- return HandleError(MSTATUS_ERROR, TEvTxUserProxy::TResultStatus::Unknown, "Malformed request: no modify scheme request body provided", ctx);
+ return HandleError(MSTATUS_ERROR, TEvTxUserProxy::TResultStatus::Unknown, "Malformed request: no modify scheme request body provided", ctx);
}
- bool needAdminCheck = false;
- switch (Request->Record.GetTransaction().GetModifyScheme().GetOperationType()) {
+ bool needAdminCheck = false;
+ switch (Request->Record.GetTransaction().GetModifyScheme().GetOperationType()) {
case NKikimrSchemeOp::ESchemeOpSplitMergeTablePartitions:
- needAdminCheck = true;
- break;
- default:
- break;
- }
-
- const auto& allowedSIDs(AppData(ctx)->AdministrationAllowedSIDs);
-
- if (needAdminCheck) {
- if (allowedSIDs.empty()) {
- needAdminCheck = false;
- }
- }
-
- if (needAdminCheck) {
- if (!TBase::IsUserAdmin()) {
- return TBase::HandleError(
- EResponseStatus::MSTATUS_ERROR,
- TEvTxUserProxy::TEvProposeTransactionStatus::EStatus::AccessDenied,
- "Access denied",
- ctx);
- }
- }
-
- record.MutableTransaction()->MutableModifyScheme()->MergeFrom(Request->Record.GetTransaction().GetModifyScheme());
- req->Record.SetUserToken(TBase::GetSerializedToken());
- ctx.Send(MakeTxProxyID(), req.Release());
-}
-
-template <>
+ needAdminCheck = true;
+ break;
+ default:
+ break;
+ }
+
+ const auto& allowedSIDs(AppData(ctx)->AdministrationAllowedSIDs);
+
+ if (needAdminCheck) {
+ if (allowedSIDs.empty()) {
+ needAdminCheck = false;
+ }
+ }
+
+ if (needAdminCheck) {
+ if (!TBase::IsUserAdmin()) {
+ return TBase::HandleError(
+ EResponseStatus::MSTATUS_ERROR,
+ TEvTxUserProxy::TEvProposeTransactionStatus::EStatus::AccessDenied,
+ "Access denied",
+ ctx);
+ }
+ }
+
+ record.MutableTransaction()->MutableModifyScheme()->MergeFrom(Request->Record.GetTransaction().GetModifyScheme());
+ req->Record.SetUserToken(TBase::GetSerializedToken());
+ ctx.Send(MakeTxProxyID(), req.Release());
+}
+
+template <>
void TMessageBusServerSchemeRequest<TBusSchemeOperation>::ReplyWithResult(EResponseStatus status, const NKikimrTxUserProxy::TEvProposeTransactionStatus &result, const TActorContext &ctx) {
- TAutoPtr<TBusResponse> response(new TBusResponse());
+ TAutoPtr<TBusResponse> response(new TBusResponse());
FillStatus(status, result, response.Get());
- SendReplyAutoPtr(response);
- Request.Destroy();
+ SendReplyAutoPtr(response);
+ Request.Destroy();
Die(ctx);
-}
-
-void TMessageBusServerProxy::Handle(TEvBusProxy::TEvPersQueue::TPtr& ev, const TActorContext& ctx) {
- TEvBusProxy::TEvPersQueue *msg = ev->Get();
- const auto& rec = static_cast<TBusPersQueue *>(msg->MsgContext.GetMessage())->Record;
+}
+
+void TMessageBusServerProxy::Handle(TEvBusProxy::TEvPersQueue::TPtr& ev, const TActorContext& ctx) {
+ TEvBusProxy::TEvPersQueue *msg = ev->Get();
+ const auto& rec = static_cast<TBusPersQueue *>(msg->MsgContext.GetMessage())->Record;
if (rec.HasMetaRequest() && (rec.GetMetaRequest().HasCmdCreateTopic()
|| rec.GetMetaRequest().HasCmdChangeTopic()
|| rec.GetMetaRequest().HasCmdDeleteTopic())) {
ctx.Register(new TMessageBusServerSchemeRequest<TBusPersQueue>(ev->Get()), TMailboxType::HTSwap, AppData()->UserPoolId);
- return;
- }
+ return;
+ }
ctx.Register(CreateMessageBusServerPersQueue(msg->MsgContext, PqMetaCache, PQReadSessionsInfoWorkerFactory));
-}
-
-void TMessageBusServerProxy::Handle(TEvBusProxy::TEvFlatTxRequest::TPtr& ev, const TActorContext& ctx) {
- ctx.Register(new TMessageBusServerSchemeRequest<TBusSchemeOperation>(ev->Get()));
-}
-
-}
-}
+}
+
+void TMessageBusServerProxy::Handle(TEvBusProxy::TEvFlatTxRequest::TPtr& ev, const TActorContext& ctx) {
+ ctx.Register(new TMessageBusServerSchemeRequest<TBusSchemeOperation>(ev->Get()));
+}
+
+}
+}
diff --git a/ydb/core/client/server/msgbus_server_tablet_kill.cpp b/ydb/core/client/server/msgbus_server_tablet_kill.cpp
index 33d7c2b5ead..62da8569e2c 100644
--- a/ydb/core/client/server/msgbus_server_tablet_kill.cpp
+++ b/ydb/core/client/server/msgbus_server_tablet_kill.cpp
@@ -1,31 +1,31 @@
-
-#include "msgbus_tabletreq.h"
-
-namespace NKikimr {
-namespace NMsgBusProxy {
-
+
+#include "msgbus_tabletreq.h"
+
+namespace NKikimr {
+namespace NMsgBusProxy {
+
class TMessageBusTabletKillRequest : public TMessageBusSimpleTabletRequest<TMessageBusTabletKillRequest, TEvTablet::TEvTabletDead, NKikimrServices::TActivity::FRONT_POISON_TABLET> {
-public:
- TMessageBusTabletKillRequest(TBusMessageContext &msg)
+public:
+ TMessageBusTabletKillRequest(TBusMessageContext &msg)
: TMessageBusSimpleTabletRequest(msg, static_cast<TBusTabletKillRequest*>(msg.GetMessage())->Record.GetTabletID(), false, TDuration::Seconds(60), false)
- {}
-
- TEvents::TEvPoisonPill* MakeReq(const TActorContext &ctx) {
+ {}
+
+ TEvents::TEvPoisonPill* MakeReq(const TActorContext &ctx) {
Y_UNUSED(ctx);
- return new TEvents::TEvPoisonPill();
- }
-
- void Handle(TEvTablet::TEvTabletDead::TPtr&, const TActorContext &) {
- }
-
+ return new TEvents::TEvPoisonPill();
+ }
+
+ void Handle(TEvTablet::TEvTabletDead::TPtr&, const TActorContext &) {
+ }
+
virtual NBus::TBusMessage* CreateErrorReply(EResponseStatus, const TActorContext&, const TString& text = TString()) override {
- return new TBusResponseStatus(MSTATUS_OK, text);
- }
-};
-
-IActor* CreateMessageBusTabletKillRequest(TBusMessageContext &msg) {
- return new TMessageBusTabletKillRequest(msg);
-}
-
-}
-}
+ return new TBusResponseStatus(MSTATUS_OK, text);
+ }
+};
+
+IActor* CreateMessageBusTabletKillRequest(TBusMessageContext &msg) {
+ return new TMessageBusTabletKillRequest(msg);
+}
+
+}
+}
diff --git a/ydb/core/client/server/msgbus_server_tablet_state.cpp b/ydb/core/client/server/msgbus_server_tablet_state.cpp
index 1c7073a102f..c8582fc5501 100644
--- a/ydb/core/client/server/msgbus_server_tablet_state.cpp
+++ b/ydb/core/client/server/msgbus_server_tablet_state.cpp
@@ -1,5 +1,5 @@
#include "msgbus_server.h"
-
+
#include <library/cpp/actors/core/actor_bootstrapped.h>
#include <library/cpp/actors/core/hfunc.h>
#include <library/cpp/actors/core/interconnect.h>
@@ -9,143 +9,143 @@
#include <ydb/core/base/tablet_types.h>
#include <ydb/public/lib/base/msgbus.h>
#include <ydb/core/tablet/tablet_sys.h>
-
-namespace NKikimr {
-namespace NMsgBusProxy {
-
-using namespace NNodeWhiteboard;
-
-class TMessageBusTabletStateRequest : public TActorBootstrapped<TMessageBusTabletStateRequest>, public TMessageBusSessionIdentHolder {
-protected:
- TAutoPtr<TEvInterconnect::TEvNodesInfo> NodesInfo;
+
+namespace NKikimr {
+namespace NMsgBusProxy {
+
+using namespace NNodeWhiteboard;
+
+class TMessageBusTabletStateRequest : public TActorBootstrapped<TMessageBusTabletStateRequest>, public TMessageBusSessionIdentHolder {
+protected:
+ TAutoPtr<TEvInterconnect::TEvNodesInfo> NodesInfo;
TMap<ui64, TAutoPtr<TEvWhiteboard::TEvTabletStateResponse>> PerNodeTabletInfo;
- size_t NodesRequested;
- size_t NodesReceived;
+ size_t NodesRequested;
+ size_t NodesReceived;
const NKikimrClient::TTabletStateRequest Record;
-
-public:
- void SendReplyAndDie(NBus::TBusMessage *reply, const TActorContext &ctx) {
- SendReplyMove(reply);
- Die(ctx);
- }
-
+
+public:
+ void SendReplyAndDie(NBus::TBusMessage *reply, const TActorContext &ctx) {
+ SendReplyMove(reply);
+ Die(ctx);
+ }
+
static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
return NKikimrServices::TActivity::TABLET_FORWARDING_ACTOR;
}
- TMessageBusTabletStateRequest(TBusMessageContext &msg)
- : TMessageBusSessionIdentHolder(msg)
- , NodesRequested(0)
- , NodesReceived(0)
- , Record(static_cast<TBusTabletStateRequest*>(msg.GetMessage())->Record)
+ TMessageBusTabletStateRequest(TBusMessageContext &msg)
+ : TMessageBusSessionIdentHolder(msg)
+ , NodesRequested(0)
+ , NodesReceived(0)
+ , Record(static_cast<TBusTabletStateRequest*>(msg.GetMessage())->Record)
{}
-
- void Bootstrap(const TActorContext &ctx) {
+
+ void Bootstrap(const TActorContext &ctx) {
const TActorId nameserviceId = GetNameserviceActorId();
- ctx.Schedule(TDuration::Seconds(60), new TEvents::TEvWakeup());
- ctx.Send(nameserviceId, new TEvInterconnect::TEvListNodes());
- Become(&TThis::StateRequestedBrowse);
- }
-
- STFUNC(StateRequestedBrowse) {
- switch (ev->GetTypeRewrite()) {
- HFunc(TEvInterconnect::TEvNodesInfo, Handle);
- CFunc(TEvents::TSystem::Wakeup, Timeout);
- }
- }
-
- STFUNC(StateRequestedTabletInfo) {
- switch (ev->GetTypeRewrite()) {
- HFunc(TEvWhiteboard::TEvTabletStateResponse, Handle);
- HFunc(TEvents::TEvUndelivered, Undelivered);
- CFunc(TEvents::TSystem::Wakeup, Timeout);
- }
- }
-
- void Handle(TEvInterconnect::TEvNodesInfo::TPtr &ev, const TActorContext &ctx) {
- NodesInfo = ev->Release();
- if (!NodesInfo->Nodes.empty()) {
- for (const auto& ni : NodesInfo->Nodes) {
+ ctx.Schedule(TDuration::Seconds(60), new TEvents::TEvWakeup());
+ ctx.Send(nameserviceId, new TEvInterconnect::TEvListNodes());
+ Become(&TThis::StateRequestedBrowse);
+ }
+
+ STFUNC(StateRequestedBrowse) {
+ switch (ev->GetTypeRewrite()) {
+ HFunc(TEvInterconnect::TEvNodesInfo, Handle);
+ CFunc(TEvents::TSystem::Wakeup, Timeout);
+ }
+ }
+
+ STFUNC(StateRequestedTabletInfo) {
+ switch (ev->GetTypeRewrite()) {
+ HFunc(TEvWhiteboard::TEvTabletStateResponse, Handle);
+ HFunc(TEvents::TEvUndelivered, Undelivered);
+ CFunc(TEvents::TSystem::Wakeup, Timeout);
+ }
+ }
+
+ void Handle(TEvInterconnect::TEvNodesInfo::TPtr &ev, const TActorContext &ctx) {
+ NodesInfo = ev->Release();
+ if (!NodesInfo->Nodes.empty()) {
+ for (const auto& ni : NodesInfo->Nodes) {
TActorId tabletStateActorId = NNodeWhiteboard::MakeNodeWhiteboardServiceId(ni.NodeId);
- ctx.Send(tabletStateActorId, new TEvWhiteboard::TEvTabletStateRequest(), IEventHandle::FlagTrackDelivery, ni.NodeId);
- ++NodesRequested;
- }
- Become(&TThis::StateRequestedTabletInfo);
- } else {
- NoData(ctx);
- }
- }
-
- void Undelivered(TEvents::TEvUndelivered::TPtr &ev, const TActorContext &ctx) {
- ui64 nodeId = ev.Get()->Cookie;
- PerNodeTabletInfo[nodeId].Reset();
- NodeTabletInfoReceived(ctx);
- }
-
- void Handle(TEvWhiteboard::TEvTabletStateResponse::TPtr &ev, const TActorContext &ctx) {
- ui64 nodeId = ev.Get()->Cookie;
- PerNodeTabletInfo[nodeId] = ev->Release();
- NodeTabletInfoReceived(ctx);
- }
-
- void NodeTabletInfoReceived(const TActorContext &ctx) {
- ++NodesReceived;
- if (NodesReceived == NodesRequested) {
- RenderResponse(ctx);
- }
- }
-
- void RenderResponse(const TActorContext &ctx) {
- TAutoPtr<TBusResponse> response = new TBusResponse();
- auto& record = response->Record;
- record.SetStatus(MSTATUS_OK);
+ ctx.Send(tabletStateActorId, new TEvWhiteboard::TEvTabletStateRequest(), IEventHandle::FlagTrackDelivery, ni.NodeId);
+ ++NodesRequested;
+ }
+ Become(&TThis::StateRequestedTabletInfo);
+ } else {
+ NoData(ctx);
+ }
+ }
+
+ void Undelivered(TEvents::TEvUndelivered::TPtr &ev, const TActorContext &ctx) {
+ ui64 nodeId = ev.Get()->Cookie;
+ PerNodeTabletInfo[nodeId].Reset();
+ NodeTabletInfoReceived(ctx);
+ }
+
+ void Handle(TEvWhiteboard::TEvTabletStateResponse::TPtr &ev, const TActorContext &ctx) {
+ ui64 nodeId = ev.Get()->Cookie;
+ PerNodeTabletInfo[nodeId] = ev->Release();
+ NodeTabletInfoReceived(ctx);
+ }
+
+ void NodeTabletInfoReceived(const TActorContext &ctx) {
+ ++NodesReceived;
+ if (NodesReceived == NodesRequested) {
+ RenderResponse(ctx);
+ }
+ }
+
+ void RenderResponse(const TActorContext &ctx) {
+ TAutoPtr<TBusResponse> response = new TBusResponse();
+ auto& record = response->Record;
+ record.SetStatus(MSTATUS_OK);
for (const auto& ni : NodesInfo->Nodes) {
const auto& pr_node = *PerNodeTabletInfo.find(ni.NodeId);
- if (pr_node.second.Get() != nullptr) {
- for (const NKikimrWhiteboard::TTabletStateInfo& st_info : pr_node.second.Get()->Record.GetTabletStateInfo()) {
- if (Record.HasAlive()) {
- if (Record.GetAlive() == false && st_info.GetState() != NKikimrWhiteboard::TTabletStateInfo::Dead)
- continue;
- if (Record.GetAlive() == true && st_info.GetState() == NKikimrWhiteboard::TTabletStateInfo::Dead)
- continue;
- }
- if (Record.HasTabletType()) {
- if (Record.GetTabletType() != st_info.GetType())
- continue;
- }
- if (Record.TabletIDsSize() > 0) {
- bool found = false;
- for (size_t i = 0; i < Record.TabletIDsSize(); ++i) {
- if (Record.GetTabletIDs(i) == st_info.GetTabletId()) {
- found = true;
- break;
- }
- }
- if (!found)
- continue;
- }
+ if (pr_node.second.Get() != nullptr) {
+ for (const NKikimrWhiteboard::TTabletStateInfo& st_info : pr_node.second.Get()->Record.GetTabletStateInfo()) {
+ if (Record.HasAlive()) {
+ if (Record.GetAlive() == false && st_info.GetState() != NKikimrWhiteboard::TTabletStateInfo::Dead)
+ continue;
+ if (Record.GetAlive() == true && st_info.GetState() == NKikimrWhiteboard::TTabletStateInfo::Dead)
+ continue;
+ }
+ if (Record.HasTabletType()) {
+ if (Record.GetTabletType() != st_info.GetType())
+ continue;
+ }
+ if (Record.TabletIDsSize() > 0) {
+ bool found = false;
+ for (size_t i = 0; i < Record.TabletIDsSize(); ++i) {
+ if (Record.GetTabletIDs(i) == st_info.GetTabletId()) {
+ found = true;
+ break;
+ }
+ }
+ if (!found)
+ continue;
+ }
auto state = record.AddTabletStateInfo();
state->CopyFrom(st_info);
state->SetHost(ni.Host);
- }
- }
- }
- SendReplyAndDie(response.Release(), ctx);
- }
-
- void NoData(const TActorContext &ctx) {
- SendReplyAndDie(new TBusResponseStatus(MSTATUS_ERROR, "No data"), ctx);
- }
-
- void Timeout(const TActorContext &ctx) {
- SendReplyAndDie(new TBusResponseStatus(MSTATUS_TIMEOUT, "Timeout"), ctx);
- }
-};
-
-IActor* CreateMessageBusTabletStateRequest(TBusMessageContext &msg) {
- return new TMessageBusTabletStateRequest(msg);
-}
-
-
-}
-}
+ }
+ }
+ }
+ SendReplyAndDie(response.Release(), ctx);
+ }
+
+ void NoData(const TActorContext &ctx) {
+ SendReplyAndDie(new TBusResponseStatus(MSTATUS_ERROR, "No data"), ctx);
+ }
+
+ void Timeout(const TActorContext &ctx) {
+ SendReplyAndDie(new TBusResponseStatus(MSTATUS_TIMEOUT, "Timeout"), ctx);
+ }
+};
+
+IActor* CreateMessageBusTabletStateRequest(TBusMessageContext &msg) {
+ return new TMessageBusTabletStateRequest(msg);
+}
+
+
+}
+}
diff --git a/ydb/core/client/server/msgbus_server_tracer.cpp b/ydb/core/client/server/msgbus_server_tracer.cpp
index e611dce2cfd..ff93f8d1cbe 100644
--- a/ydb/core/client/server/msgbus_server_tracer.cpp
+++ b/ydb/core/client/server/msgbus_server_tracer.cpp
@@ -1,11 +1,11 @@
-#include "msgbus_server_tracer.h"
-#include "msgbus_servicereq.h"
-#include <util/folder/path.h>
-
-namespace NKikimr {
-namespace NMessageBusTracer {
-
-
+#include "msgbus_server_tracer.h"
+#include "msgbus_servicereq.h"
+#include <util/folder/path.h>
+
+namespace NKikimr {
+namespace NMessageBusTracer {
+
+
TMessageBusTracingServer::TMessageBusTracingServer(
const NBus::TBusServerSessionConfig &sessionConfig,
NBus::TBusMessageQueue *busQueue,
@@ -14,231 +14,231 @@ TMessageBusTracingServer::TMessageBusTracingServer(
std::shared_ptr<NMsgBusProxy::IPersQueueGetReadSessionsInfoWorkerFactory> pqReadSessionsInfoWorkerFactory
)
: NKikimr::NMsgBusProxy::TMessageBusServer(sessionConfig, busQueue, bindPort, pqReadSessionsInfoWorkerFactory)
- , MessageBusTracerActorID(MakeMessageBusTraceServiceID())
- , TraceActive(false)
- , TracePath(tracePath)
-{
-}
-
-void TMessageBusTracingServer::OnMessage(NBus::TOnMessageContext &msg) {
- NMsgBusProxy::TBusMessageContext msgCtx(msg, TraceActive ? this : nullptr);
- if (msgCtx.GetMessage()->GetHeader()->Type == NMsgBusProxy::MTYPE_CLIENT_MESSAGE_BUS_TRACE) {
- const auto &record = static_cast<NMsgBusProxy::TBusMessageBusTraceRequest*>(msgCtx.GetMessage())->Record;
- if (record.HasCommand()) {
+ , MessageBusTracerActorID(MakeMessageBusTraceServiceID())
+ , TraceActive(false)
+ , TracePath(tracePath)
+{
+}
+
+void TMessageBusTracingServer::OnMessage(NBus::TOnMessageContext &msg) {
+ NMsgBusProxy::TBusMessageContext msgCtx(msg, TraceActive ? this : nullptr);
+ if (msgCtx.GetMessage()->GetHeader()->Type == NMsgBusProxy::MTYPE_CLIENT_MESSAGE_BUS_TRACE) {
+ const auto &record = static_cast<NMsgBusProxy::TBusMessageBusTraceRequest*>(msgCtx.GetMessage())->Record;
+ if (record.HasCommand()) {
const NKikimrClient::TMessageBusTraceRequest::ECommand command = record.GetCommand();
- switch (command) {
+ switch (command) {
case NKikimrClient::TMessageBusTraceRequest::START:
- if (record.HasPath()) {
- TFsPath basePath = TracePath;
- TFsPath path = record.GetPath();
- TFsPath tracePath = basePath / path.GetName();
-
- if (tracePath.IsSubpathOf(basePath)) {
- if (IActor *x = CreateMessageBusTracerStartTrace(msgCtx, basePath / path.GetName())) {
- TraceActive = true;
- ActorSystem->Register(x);
- return;
- }
- }
- }
- break;
+ if (record.HasPath()) {
+ TFsPath basePath = TracePath;
+ TFsPath path = record.GetPath();
+ TFsPath tracePath = basePath / path.GetName();
+
+ if (tracePath.IsSubpathOf(basePath)) {
+ if (IActor *x = CreateMessageBusTracerStartTrace(msgCtx, basePath / path.GetName())) {
+ TraceActive = true;
+ ActorSystem->Register(x);
+ return;
+ }
+ }
+ }
+ break;
case NKikimrClient::TMessageBusTraceRequest::STOP:
- if (IActor *x = CreateMessageBusTracerStopTrace(msgCtx)) {
- TraceActive = false;
- ActorSystem->Register(x);
- return;
- }
- break;
- }
- }
- msgCtx.SendReplyMove(new NMsgBusProxy::TBusResponseStatus(NMsgBusProxy::MSTATUS_ERROR, "undocumented error 2"));
- } else {
- if (TraceActive)
- SaveRequest(msgCtx.GetMessage());
- TMessageBusServer::OnMessage(msgCtx);
- }
-}
-
-void TMessageBusTracingServer::OnMessageDied(NBus::TBusKey id) {
- if (TraceActive)
- SaveRequest(nullptr, id);
-}
-
-void TMessageBusTracingServer::OnMessageReplied(NBus::TBusKey id, NBus::TBusMessage *response) {
- if (TraceActive)
- SaveRequest(response, id);
-}
-
-void TMessageBusTracingServer::SaveRequest(NBus::TBusMessage *msg, NBus::TBusKey replyId) {
- TBuffer content;
- if (msg->GetHeader()->Size > 0)
- content.Reserve(msg->GetHeader()->Size - sizeof(NBus::TBusHeader));
- Protocol.Serialize(msg, content);
- ActorSystem->Send(MessageBusTracerActorID, new TEvMessageBusTracer::TEvTraceEvent(msg, std::move(content), replyId));
-}
-
-IActor* TMessageBusTracingServer::CreateMessageBusTraceService() {
- return new TMessageBusTracerService();
-}
-
-TEvMessageBusTracer::TEvTraceEvent::TEvTraceEvent(NBus::TBusMessage *msg, TBuffer &&content, NBus::TBusKey replyId)
- : ReplyId(replyId)
- , Header(*msg->GetHeader())
- , Content(content)
-{
- if (Header.Size == 0)
- Header.Size = sizeof(Header) + Content.Size();
-}
-
-TMessageBusTracerService::TMessageBusTracerService()
- : TActor(&TMessageBusTracerService::StateFunc)
+ if (IActor *x = CreateMessageBusTracerStopTrace(msgCtx)) {
+ TraceActive = false;
+ ActorSystem->Register(x);
+ return;
+ }
+ break;
+ }
+ }
+ msgCtx.SendReplyMove(new NMsgBusProxy::TBusResponseStatus(NMsgBusProxy::MSTATUS_ERROR, "undocumented error 2"));
+ } else {
+ if (TraceActive)
+ SaveRequest(msgCtx.GetMessage());
+ TMessageBusServer::OnMessage(msgCtx);
+ }
+}
+
+void TMessageBusTracingServer::OnMessageDied(NBus::TBusKey id) {
+ if (TraceActive)
+ SaveRequest(nullptr, id);
+}
+
+void TMessageBusTracingServer::OnMessageReplied(NBus::TBusKey id, NBus::TBusMessage *response) {
+ if (TraceActive)
+ SaveRequest(response, id);
+}
+
+void TMessageBusTracingServer::SaveRequest(NBus::TBusMessage *msg, NBus::TBusKey replyId) {
+ TBuffer content;
+ if (msg->GetHeader()->Size > 0)
+ content.Reserve(msg->GetHeader()->Size - sizeof(NBus::TBusHeader));
+ Protocol.Serialize(msg, content);
+ ActorSystem->Send(MessageBusTracerActorID, new TEvMessageBusTracer::TEvTraceEvent(msg, std::move(content), replyId));
+}
+
+IActor* TMessageBusTracingServer::CreateMessageBusTraceService() {
+ return new TMessageBusTracerService();
+}
+
+TEvMessageBusTracer::TEvTraceEvent::TEvTraceEvent(NBus::TBusMessage *msg, TBuffer &&content, NBus::TBusKey replyId)
+ : ReplyId(replyId)
+ , Header(*msg->GetHeader())
+ , Content(content)
+{
+ if (Header.Size == 0)
+ Header.Size = sizeof(Header) + Content.Size();
+}
+
+TMessageBusTracerService::TMessageBusTracerService()
+ : TActor(&TMessageBusTracerService::StateFunc)
{}
-
-void TMessageBusTracerService::StateFunc(TAutoPtr<IEventHandle> &ev, const TActorContext &ctx) {
- switch (ev->GetTypeRewrite()) {
- HFunc(TEvMessageBusTracer::TEvTraceEvent, HandleTraceEvent);
- HFunc(TEvMessageBusTracer::TEvStartTrace, HandleStartTrace);
- HFunc(TEvMessageBusTracer::TEvStopTrace, HandleStopTrace);
- }
-}
-
-void TMessageBusTracerService::HandleStartTrace(TEvMessageBusTracer::TEvStartTrace::TPtr &ev, const TActorContext &ctx) {
- const TEvMessageBusTracer::TEvStartTrace *event = ev->Get();
- Path = event->Path;
+
+void TMessageBusTracerService::StateFunc(TAutoPtr<IEventHandle> &ev, const TActorContext &ctx) {
+ switch (ev->GetTypeRewrite()) {
+ HFunc(TEvMessageBusTracer::TEvTraceEvent, HandleTraceEvent);
+ HFunc(TEvMessageBusTracer::TEvStartTrace, HandleStartTrace);
+ HFunc(TEvMessageBusTracer::TEvStopTrace, HandleStopTrace);
+ }
+}
+
+void TMessageBusTracerService::HandleStartTrace(TEvMessageBusTracer::TEvStartTrace::TPtr &ev, const TActorContext &ctx) {
+ const TEvMessageBusTracer::TEvStartTrace *event = ev->Get();
+ Path = event->Path;
Stream = new TFileOutput(Path);
- LOG_NOTICE_S(ctx, NKikimrServices::MSGBUS_TRACER, "MessageBus tracing started, file '"
- << Path << "' "
- << ctx.SelfID.ToString());
- ctx.Send(ev->Sender, new TEvMessageBusTracer::TEvTraceStatus(!!Stream, Path));
-}
-
-void TMessageBusTracerService::HandleStopTrace(TEvMessageBusTracer::TEvStopTrace::TPtr &ev, const TActorContext &ctx) {
- const TEvMessageBusTracer::TEvStopTrace *event = ev->Get();
+ LOG_NOTICE_S(ctx, NKikimrServices::MSGBUS_TRACER, "MessageBus tracing started, file '"
+ << Path << "' "
+ << ctx.SelfID.ToString());
+ ctx.Send(ev->Sender, new TEvMessageBusTracer::TEvTraceStatus(!!Stream, Path));
+}
+
+void TMessageBusTracerService::HandleStopTrace(TEvMessageBusTracer::TEvStopTrace::TPtr &ev, const TActorContext &ctx) {
+ const TEvMessageBusTracer::TEvStopTrace *event = ev->Get();
Y_UNUSED(event);
- LOG_NOTICE_S(ctx, NKikimrServices::MSGBUS_TRACER, "MessageBus tracing stopped, file '" << Path << "' "
- << ctx.SelfID.ToString());
- Path.clear();
- Stream.Reset(nullptr);
- ctx.Send(ev->Sender, new TEvMessageBusTracer::TEvTraceStatus(!!Stream, Path));
-}
-
-void TMessageBusTracerService::HandleTraceEvent(TEvMessageBusTracer::TEvTraceEvent::TPtr &ev, const TActorContext &) {
- const TEvMessageBusTracer::TEvTraceEvent *event = ev->Get();
- if (Stream != nullptr) {
- Stream->Write(&event->ReplyId, sizeof(NBus::TBusKey));
- Stream->Write(&event->Header, sizeof(NBus::TBusHeader));
- const TBuffer& content(event->Content);
- Stream->Write(content.Data(), content.Size());
-//#ifndef NDEBUG
-// Stream->Flush();
-//#endif
- }
-}
-
+ LOG_NOTICE_S(ctx, NKikimrServices::MSGBUS_TRACER, "MessageBus tracing stopped, file '" << Path << "' "
+ << ctx.SelfID.ToString());
+ Path.clear();
+ Stream.Reset(nullptr);
+ ctx.Send(ev->Sender, new TEvMessageBusTracer::TEvTraceStatus(!!Stream, Path));
+}
+
+void TMessageBusTracerService::HandleTraceEvent(TEvMessageBusTracer::TEvTraceEvent::TPtr &ev, const TActorContext &) {
+ const TEvMessageBusTracer::TEvTraceEvent *event = ev->Get();
+ if (Stream != nullptr) {
+ Stream->Write(&event->ReplyId, sizeof(NBus::TBusKey));
+ Stream->Write(&event->Header, sizeof(NBus::TBusHeader));
+ const TBuffer& content(event->Content);
+ Stream->Write(content.Data(), content.Size());
+//#ifndef NDEBUG
+// Stream->Flush();
+//#endif
+ }
+}
+
TEvMessageBusTracer::TEvStartTrace::TEvStartTrace(const TString &path)
- : Path(path)
-{
-}
-
+ : Path(path)
+{
+}
+
TEvMessageBusTracer::TEvTraceStatus::TEvTraceStatus(bool traceActive, const TString &path)
- : TraceActive(traceActive)
- , Path(path)
-{
-}
-
-
-namespace {
+ : TraceActive(traceActive)
+ , Path(path)
+{
+}
+
+
+namespace {
const ui32 DefaultTimeout = 90000;
-}
-
+}
+
template <typename TDerived>
class TMessageBusTraceSimpleActor : public NMsgBusProxy::TMessageBusLocalServiceRequest<TDerived, NKikimrServices::TActivity::MSGBUS_TRACER_ACTOR> {
-public:
- TMessageBusTraceSimpleActor(NMsgBusProxy::TBusMessageContext &msg)
+public:
+ TMessageBusTraceSimpleActor(NMsgBusProxy::TBusMessageContext &msg)
: NMsgBusProxy::TMessageBusLocalServiceRequest<TDerived, NKikimrServices::TActivity::MSGBUS_TRACER_ACTOR>(msg, TDuration::MilliSeconds(DefaultTimeout))
- {}
-
- void Handle(TEvMessageBusTracer::TEvTraceStatus::TPtr &ev, const TActorContext &ctx) {
- TEvMessageBusTracer::TEvTraceStatus *event = ev->Get();
- TAutoPtr<NMsgBusProxy::TBusMessageBusTraceStatus> response(new NMsgBusProxy::TBusMessageBusTraceStatus());
- response->Record.SetTraceActive(event->TraceActive);
- response->Record.SetPath(event->Path);
- this->SendReplyAndDie(response.Release(), ctx);
- }
-
+ {}
+
+ void Handle(TEvMessageBusTracer::TEvTraceStatus::TPtr &ev, const TActorContext &ctx) {
+ TEvMessageBusTracer::TEvTraceStatus *event = ev->Get();
+ TAutoPtr<NMsgBusProxy::TBusMessageBusTraceStatus> response(new NMsgBusProxy::TBusMessageBusTraceStatus());
+ response->Record.SetTraceActive(event->TraceActive);
+ response->Record.SetPath(event->Path);
+ this->SendReplyAndDie(response.Release(), ctx);
+ }
+
TActorId MakeServiceID(const TActorContext &ctx) {
Y_UNUSED(ctx);
- return MakeMessageBusTraceServiceID();
- }
-
- NBus::TBusMessage* CreateErrorReply(NMsgBusProxy::EResponseStatus status, const TActorContext &ctx) {
+ return MakeMessageBusTraceServiceID();
+ }
+
+ NBus::TBusMessage* CreateErrorReply(NMsgBusProxy::EResponseStatus status, const TActorContext &ctx) {
Y_UNUSED(ctx);
TAutoPtr<NMsgBusProxy::TBusResponse> response(new NMsgBusProxy::TBusResponseStatus(status, "Service not found"));
- return response.Release();
- }
-
- void HandleTimeout(const TActorContext &ctx) {
+ return response.Release();
+ }
+
+ void HandleTimeout(const TActorContext &ctx) {
Y_UNUSED(ctx);
TAutoPtr<NMsgBusProxy::TBusResponse> response(new NMsgBusProxy::TBusResponseStatus(NMsgBusProxy::MSTATUS_TIMEOUT, ""));
- this->SendReplyAndDie(response.Release(), ctx);
- }
-
- void HandleUndelivered(TEvents::TEvUndelivered::TPtr& ev, const TActorContext& ctx) {
+ this->SendReplyAndDie(response.Release(), ctx);
+ }
+
+ void HandleUndelivered(TEvents::TEvUndelivered::TPtr& ev, const TActorContext& ctx) {
Y_UNUSED(ev);
TAutoPtr<NMsgBusProxy::TBusResponse> response(new NMsgBusProxy::TBusResponseStatus(NMsgBusProxy::MSTATUS_ERROR, "HandleUndelivered"));
- response->Record.SetErrorReason("Cannot deliver request to the service");
- this->SendReplyAndDie(response.Release(), ctx);
- }
-
- void StateFunc(TAutoPtr<NActors::IEventHandle> &ev, const NActors::TActorContext &ctx) {
- switch (ev->GetTypeRewrite()) {
- HFunc(TEvMessageBusTracer::TEvTraceStatus, Handle);
- HFunc(TEvents::TEvUndelivered, HandleUndelivered);
- CFunc(TEvents::TSystem::Wakeup, HandleTimeout);
- }
- }
-};
-
-class TMessageBusTracerStartTrace: public TMessageBusTraceSimpleActor<TMessageBusTracerStartTrace> {
+ response->Record.SetErrorReason("Cannot deliver request to the service");
+ this->SendReplyAndDie(response.Release(), ctx);
+ }
+
+ void StateFunc(TAutoPtr<NActors::IEventHandle> &ev, const NActors::TActorContext &ctx) {
+ switch (ev->GetTypeRewrite()) {
+ HFunc(TEvMessageBusTracer::TEvTraceStatus, Handle);
+ HFunc(TEvents::TEvUndelivered, HandleUndelivered);
+ CFunc(TEvents::TSystem::Wakeup, HandleTimeout);
+ }
+ }
+};
+
+class TMessageBusTracerStartTrace: public TMessageBusTraceSimpleActor<TMessageBusTracerStartTrace> {
TString Path;
-public:
+public:
TMessageBusTracerStartTrace(NMsgBusProxy::TBusMessageContext &msg, const TString& path)
- : TMessageBusTraceSimpleActor<TMessageBusTracerStartTrace>(msg)
- , Path(path)
- {
- }
-
- TEvMessageBusTracer::TEvStartTrace* MakeReq(const TActorContext &ctx) {
+ : TMessageBusTraceSimpleActor<TMessageBusTracerStartTrace>(msg)
+ , Path(path)
+ {
+ }
+
+ TEvMessageBusTracer::TEvStartTrace* MakeReq(const TActorContext &ctx) {
Y_UNUSED(ctx);
- return new TEvMessageBusTracer::TEvStartTrace(Path);
- }
-};
-
+ return new TEvMessageBusTracer::TEvStartTrace(Path);
+ }
+};
+
IActor* CreateMessageBusTracerStartTrace(NMsgBusProxy::TBusMessageContext &msg, const TString& path) {
- return new TMessageBusTracerStartTrace(msg, path);
-}
-
-class TMessageBusTracerStopTrace: public TMessageBusTraceSimpleActor<TMessageBusTracerStopTrace> {
-public:
- TMessageBusTracerStopTrace(NMsgBusProxy::TBusMessageContext &msg)
- : TMessageBusTraceSimpleActor<TMessageBusTracerStopTrace>(msg)
- {}
-
- TEvMessageBusTracer::TEvStopTrace* MakeReq(const TActorContext &ctx) {
+ return new TMessageBusTracerStartTrace(msg, path);
+}
+
+class TMessageBusTracerStopTrace: public TMessageBusTraceSimpleActor<TMessageBusTracerStopTrace> {
+public:
+ TMessageBusTracerStopTrace(NMsgBusProxy::TBusMessageContext &msg)
+ : TMessageBusTraceSimpleActor<TMessageBusTracerStopTrace>(msg)
+ {}
+
+ TEvMessageBusTracer::TEvStopTrace* MakeReq(const TActorContext &ctx) {
Y_UNUSED(ctx);
- return new TEvMessageBusTracer::TEvStopTrace();
- }
-};
-
-IActor* CreateMessageBusTracerStopTrace(NMsgBusProxy::TBusMessageContext &msg) {
- return new TMessageBusTracerStopTrace(msg);
-}
-
-
-}
-
-namespace NMsgBusProxy {
-
+ return new TEvMessageBusTracer::TEvStopTrace();
+ }
+};
+
+IActor* CreateMessageBusTracerStopTrace(NMsgBusProxy::TBusMessageContext &msg) {
+ return new TMessageBusTracerStopTrace(msg);
+}
+
+
+}
+
+namespace NMsgBusProxy {
+
IMessageBusServer* CreateMsgBusTracingServer(
NBus::TBusMessageQueue *queue,
const NBus::TBusServerSessionConfig &config,
@@ -253,7 +253,7 @@ IMessageBusServer* CreateMsgBusTracingServer(
bindPort,
pqReadSessionsInfoWorkerFactory
);
-}
-
-}
-}
+}
+
+}
+}
diff --git a/ydb/core/client/server/msgbus_server_tracer.h b/ydb/core/client/server/msgbus_server_tracer.h
index 953dbb3a6f3..57a3812f5d5 100644
--- a/ydb/core/client/server/msgbus_server_tracer.h
+++ b/ydb/core/client/server/msgbus_server_tracer.h
@@ -1,22 +1,22 @@
-#pragma once
-#include <util/stream/file.h>
+#pragma once
+#include <util/stream/file.h>
#include <util/thread/pool.h>
-#include <util/generic/buffer.h>
+#include <util/generic/buffer.h>
#include <library/cpp/messagebus/handler.h>
#include <library/cpp/messagebus/message.h>
#include <library/cpp/messagebus/defs.h>
#include <ydb/public/lib/base/msgbus.h>
#include <library/cpp/actors/core/hfunc.h>
-#include "msgbus_server.h"
-#include <util/system/atomic.h>
-
-namespace NKikimr {
-namespace NMessageBusTracer {
-
-
-class TMessageBusTracingServer : public NKikimr::NMsgBusProxy::TMessageBusServer, public NMsgBusProxy::IMessageWatcher {
-public:
- using TBusKey = NBus::TBusKey;
+#include "msgbus_server.h"
+#include <util/system/atomic.h>
+
+namespace NKikimr {
+namespace NMessageBusTracer {
+
+
+class TMessageBusTracingServer : public NKikimr::NMsgBusProxy::TMessageBusServer, public NMsgBusProxy::IMessageWatcher {
+public:
+ using TBusKey = NBus::TBusKey;
TMessageBusTracingServer(
const NBus::TBusServerSessionConfig &sessionConfig,
NBus::TBusMessageQueue *busQueue,
@@ -24,87 +24,87 @@ public:
ui32 bindPort,
std::shared_ptr<NMsgBusProxy::IPersQueueGetReadSessionsInfoWorkerFactory> pqReadSessionsInfoWorkerFactory
);
- IActor* CreateMessageBusTraceService() override;
-protected:
+ IActor* CreateMessageBusTraceService() override;
+protected:
TActorId MessageBusTracerActorID;
- bool TraceActive;
+ bool TraceActive;
TString TracePath;
- void OnMessage(NBus::TOnMessageContext &msg) override;
- void OnMessageDied(NBus::TBusKey id) override;
- void OnMessageReplied(NBus::TBusKey id, NBus::TBusMessage *response) override;
- void SaveRequest(NBus::TBusMessage *msg, NBus::TBusKey replyId = YBUS_KEYINVALID);
-};
-
-struct TEvMessageBusTracer {
- enum EEv {
- EvTraceEvent = EventSpaceBegin(TKikimrEvents::ES_MSGBUS_TRACER),
- EvStartTrace,
- EvStopTrace,
- EvTraceStatus,
- EvEnd
- };
-
- static_assert(EvEnd < EventSpaceEnd(TKikimrEvents::ES_MSGBUS_TRACER), "expect End < EventSpaceEnd(TKikimrEvents::ES_MSGBUS_TRACER)");
-
- class TEvTraceEvent : public TEventLocal<TEvTraceEvent, TEvMessageBusTracer::EvTraceEvent> {
- public:
- using TBusKey = NBus::TBusKey;
- TBusKey ReplyId;
- NBus::TBusHeader Header;
- TBuffer Content;
-
- TEvTraceEvent(NBus::TBusMessage *msg, TBuffer &&content, TBusKey replyId = YBUS_KEYINVALID);
- };
-
- class TEvStartTrace : public TEventLocal<TEvStartTrace, TEvMessageBusTracer::EvStartTrace> {
- public:
+ void OnMessage(NBus::TOnMessageContext &msg) override;
+ void OnMessageDied(NBus::TBusKey id) override;
+ void OnMessageReplied(NBus::TBusKey id, NBus::TBusMessage *response) override;
+ void SaveRequest(NBus::TBusMessage *msg, NBus::TBusKey replyId = YBUS_KEYINVALID);
+};
+
+struct TEvMessageBusTracer {
+ enum EEv {
+ EvTraceEvent = EventSpaceBegin(TKikimrEvents::ES_MSGBUS_TRACER),
+ EvStartTrace,
+ EvStopTrace,
+ EvTraceStatus,
+ EvEnd
+ };
+
+ static_assert(EvEnd < EventSpaceEnd(TKikimrEvents::ES_MSGBUS_TRACER), "expect End < EventSpaceEnd(TKikimrEvents::ES_MSGBUS_TRACER)");
+
+ class TEvTraceEvent : public TEventLocal<TEvTraceEvent, TEvMessageBusTracer::EvTraceEvent> {
+ public:
+ using TBusKey = NBus::TBusKey;
+ TBusKey ReplyId;
+ NBus::TBusHeader Header;
+ TBuffer Content;
+
+ TEvTraceEvent(NBus::TBusMessage *msg, TBuffer &&content, TBusKey replyId = YBUS_KEYINVALID);
+ };
+
+ class TEvStartTrace : public TEventLocal<TEvStartTrace, TEvMessageBusTracer::EvStartTrace> {
+ public:
TString Path;
-
+
TEvStartTrace(const TString &path);
- };
-
- class TEvStopTrace : public TEventLocal<TEvStopTrace, TEvMessageBusTracer::EvStopTrace> {
- public:
- TEvStopTrace() {}
- };
-
- class TEvTraceStatus : public TEventLocal<TEvTraceStatus, TEvMessageBusTracer::EvTraceStatus> {
- public:
- bool TraceActive;
+ };
+
+ class TEvStopTrace : public TEventLocal<TEvStopTrace, TEvMessageBusTracer::EvStopTrace> {
+ public:
+ TEvStopTrace() {}
+ };
+
+ class TEvTraceStatus : public TEventLocal<TEvTraceStatus, TEvMessageBusTracer::EvTraceStatus> {
+ public:
+ bool TraceActive;
TString Path;
-
+
TEvTraceStatus(bool traceActive, const TString &path);
- };
-
-};
-
-class TMessageBusTracerService : public TActor<TMessageBusTracerService> {
-public:
- using TProtocol = NKikimr::NMsgBusProxy::TProtocol;
-
+ };
+
+};
+
+class TMessageBusTracerService : public TActor<TMessageBusTracerService> {
+public:
+ using TProtocol = NKikimr::NMsgBusProxy::TProtocol;
+
static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
return NKikimrServices::TActivity::MSGBUS_TRACER_ACTOR;
}
- TMessageBusTracerService();
- void StateFunc(TAutoPtr<IEventHandle> &ev, const TActorContext &ctx);
-
-private:
- void HandleStartTrace(TEvMessageBusTracer::TEvStartTrace::TPtr &ev, const TActorContext &ctx);
- void HandleStopTrace(TEvMessageBusTracer::TEvStopTrace::TPtr &ev, const TActorContext &ctx);
- void HandleTraceEvent(TEvMessageBusTracer::TEvTraceEvent::TPtr &ev, const TActorContext &);
-
+ TMessageBusTracerService();
+ void StateFunc(TAutoPtr<IEventHandle> &ev, const TActorContext &ctx);
+
+private:
+ void HandleStartTrace(TEvMessageBusTracer::TEvStartTrace::TPtr &ev, const TActorContext &ctx);
+ void HandleStopTrace(TEvMessageBusTracer::TEvStopTrace::TPtr &ev, const TActorContext &ctx);
+ void HandleTraceEvent(TEvMessageBusTracer::TEvTraceEvent::TPtr &ev, const TActorContext &);
+
TAutoPtr<IOutputStream> Stream;
TString Path;
-};
-
+};
+
inline TActorId MakeMessageBusTraceServiceID(ui32 node = 0) {
- char x[12] = {'m','s','g','b','u','s','t','r','a','c','e','r'};
+ char x[12] = {'m','s','g','b','u','s','t','r','a','c','e','r'};
return TActorId(node, TStringBuf(x, 12));
-}
-
+}
+
IActor* CreateMessageBusTracerStartTrace(NMsgBusProxy::TBusMessageContext &msg, const TString &path);
-IActor* CreateMessageBusTracerStopTrace(NMsgBusProxy::TBusMessageContext &msg);
-
-}
-}
+IActor* CreateMessageBusTracerStopTrace(NMsgBusProxy::TBusMessageContext &msg);
+
+}
+}
diff --git a/ydb/core/client/server/msgbus_server_tx_request.cpp b/ydb/core/client/server/msgbus_server_tx_request.cpp
index 3888c18b8df..a0d73fa9d69 100644
--- a/ydb/core/client/server/msgbus_server_tx_request.cpp
+++ b/ydb/core/client/server/msgbus_server_tx_request.cpp
@@ -1,74 +1,74 @@
-#include "msgbus_tabletreq.h"
-
+#include "msgbus_tabletreq.h"
+
#include <ydb/core/tx/schemeshard/schemeshard.h>
-namespace NKikimr {
-namespace NMsgBusProxy {
-
+namespace NKikimr {
+namespace NMsgBusProxy {
+
class TMessageBusTxStatusRequestActor : public TMessageBusSimpleTabletRequest<TMessageBusTxStatusRequestActor, NSchemeShard::TEvSchemeShard::TEvNotifyTxCompletionResult, NKikimrServices::TActivity::FRONT_SCHEME_TXSTATUS> {
- const ui64 TxId;
+ const ui64 TxId;
const ui64 PathId;
bool InProgress;
-public:
+public:
TMessageBusTxStatusRequestActor(NMsgBusProxy::TBusMessageContext& msg, const TBusSchemeOperationStatus* casted)
: TMessageBusSimpleTabletRequest(msg, casted->Record.GetFlatTxId().GetSchemeShardTabletId(), false,
TDuration::MilliSeconds(casted->Record.GetPollOptions().GetTimeout()), false)
, TxId(casted->Record.GetFlatTxId().GetTxId())
, PathId(casted->Record.GetFlatTxId().GetPathId())
, InProgress(false)
- {}
-
+ {}
+
TMessageBusTxStatusRequestActor(NMsgBusProxy::TBusMessageContext& msg)
: TMessageBusTxStatusRequestActor(msg, static_cast<TBusSchemeOperationStatus*>(msg.GetMessage()))
{}
void Handle(NSchemeShard::TEvSchemeShard::TEvNotifyTxCompletionResult::TPtr&, const TActorContext& ctx) {
- TAutoPtr<NMsgBusProxy::TBusResponse> response(new NMsgBusProxy::TBusResponse());
- response->Record.SetStatus(NMsgBusProxy::MSTATUS_OK);
- response->Record.MutableFlatTxId()->SetTxId(TxId);
+ TAutoPtr<NMsgBusProxy::TBusResponse> response(new NMsgBusProxy::TBusResponse());
+ response->Record.SetStatus(NMsgBusProxy::MSTATUS_OK);
+ response->Record.MutableFlatTxId()->SetTxId(TxId);
response->Record.MutableFlatTxId()->SetPathId(PathId);
- response->Record.MutableFlatTxId()->SetSchemeShardTabletId(TabletID);
- SendReplyAndDie(response.Release(), ctx);
- }
-
+ response->Record.MutableFlatTxId()->SetSchemeShardTabletId(TabletID);
+ SendReplyAndDie(response.Release(), ctx);
+ }
+
void Handle(NSchemeShard::TEvSchemeShard::TEvNotifyTxCompletionRegistered::TPtr&, const TActorContext&) {
InProgress = true;
}
- void HandleTimeout(const TActorContext& ctx) {
- TAutoPtr<NMsgBusProxy::TBusResponse> response = new NMsgBusProxy::TBusResponse();
+ void HandleTimeout(const TActorContext& ctx) {
+ TAutoPtr<NMsgBusProxy::TBusResponse> response = new NMsgBusProxy::TBusResponse();
response->Record.SetStatus(InProgress ? NMsgBusProxy::MSTATUS_INPROGRESS : NMsgBusProxy::MSTATUS_TIMEOUT);
- response->Record.MutableFlatTxId()->SetTxId(TxId);
+ response->Record.MutableFlatTxId()->SetTxId(TxId);
response->Record.MutableFlatTxId()->SetPathId(PathId);
- response->Record.MutableFlatTxId()->SetSchemeShardTabletId(TabletID);
- SendReplyAndDie(response.Release(), ctx);
- }
-
- void HandleUndelivered(TEvents::TEvUndelivered::TPtr&, const TActorContext& ctx) {
- TAutoPtr<NMsgBusProxy::TBusResponse> response(new NMsgBusProxy::TBusResponseStatus(NMsgBusProxy::MSTATUS_ERROR, "HandleUndelivered"));
- response->Record.SetErrorReason("Cannot deliver request to the service");
- SendReplyAndDie(response.Release(), ctx);
- }
-
+ response->Record.MutableFlatTxId()->SetSchemeShardTabletId(TabletID);
+ SendReplyAndDie(response.Release(), ctx);
+ }
+
+ void HandleUndelivered(TEvents::TEvUndelivered::TPtr&, const TActorContext& ctx) {
+ TAutoPtr<NMsgBusProxy::TBusResponse> response(new NMsgBusProxy::TBusResponseStatus(NMsgBusProxy::MSTATUS_ERROR, "HandleUndelivered"));
+ response->Record.SetErrorReason("Cannot deliver request to the service");
+ SendReplyAndDie(response.Release(), ctx);
+ }
+
NSchemeShard::TEvSchemeShard::TEvNotifyTxCompletion* MakeReq(const TActorContext&) {
THolder<NSchemeShard::TEvSchemeShard::TEvNotifyTxCompletion> request(new NSchemeShard::TEvSchemeShard::TEvNotifyTxCompletion());
- request->Record.SetTxId(TxId);
- return request.Release();
- }
-
- void StateFunc(TAutoPtr<NActors::IEventHandle>& ev, const NActors::TActorContext& ctx) {
- switch (ev->GetTypeRewrite()) {
- HFunc(TEvents::TEvUndelivered, HandleUndelivered);
+ request->Record.SetTxId(TxId);
+ return request.Release();
+ }
+
+ void StateFunc(TAutoPtr<NActors::IEventHandle>& ev, const NActors::TActorContext& ctx) {
+ switch (ev->GetTypeRewrite()) {
+ HFunc(TEvents::TEvUndelivered, HandleUndelivered);
HFunc(NSchemeShard::TEvSchemeShard::TEvNotifyTxCompletionRegistered, Handle);
HFunc(NSchemeShard::TEvSchemeShard::TEvNotifyTxCompletionResult, Handle);
- CFunc(TEvents::TSystem::Wakeup, HandleTimeout);
- }
- }
-};
-
+ CFunc(TEvents::TSystem::Wakeup, HandleTimeout);
+ }
+ }
+};
+
IActor* CreateMessageBusSchemeOperationStatus(TBusMessageContext &msg) {
- return new TMessageBusTxStatusRequestActor(msg);
-}
-
-}
-}
+ return new TMessageBusTxStatusRequestActor(msg);
+}
+
+}
+}
diff --git a/ydb/core/client/server/msgbus_server_types.cpp b/ydb/core/client/server/msgbus_server_types.cpp
index 178e7758ae4..0495040e3cd 100644
--- a/ydb/core/client/server/msgbus_server_types.cpp
+++ b/ydb/core/client/server/msgbus_server_types.cpp
@@ -19,7 +19,7 @@ public:
return NKikimrServices::TActivity::MSGBUS_COMMON;
}
- TMessageBusGetTypes(TBusMessageContext &msg, TMaybe<ui64> etag)
+ TMessageBusGetTypes(TBusMessageContext &msg, TMaybe<ui64> etag)
: TMessageBusSessionIdentHolder(msg)
, Etag(etag)
{}
@@ -40,7 +40,7 @@ public:
SerializeMetadata(*functionRegistry, reply->Record.MutableFunctionMetadata());
}
- SendReplyMove(reply);
+ SendReplyMove(reply);
return Die(ctx);
}
@@ -48,7 +48,7 @@ private:
const TMaybe<ui64> Etag;
};
-IActor* CreateMessageBusGetTypes(TBusMessageContext &msg) {
+IActor* CreateMessageBusGetTypes(TBusMessageContext &msg) {
const auto &record = static_cast<TBusTypesRequest *>(msg.GetMessage())->Record;
const TMaybe<ui64> etag = record.HasETag() ? record.GetETag() : TMaybe<ui64>();
diff --git a/ydb/core/client/server/msgbus_server_whoami.cpp b/ydb/core/client/server/msgbus_server_whoami.cpp
index 980c11faa2e..d0011548187 100644
--- a/ydb/core/client/server/msgbus_server_whoami.cpp
+++ b/ydb/core/client/server/msgbus_server_whoami.cpp
@@ -1,58 +1,58 @@
#include <library/cpp/actors/core/actor_bootstrapped.h>
#include <ydb/core/protos/services.pb.h>
#include <ydb/core/base/ticket_parser.h>
-#include "msgbus_server.h"
-#include "msgbus_server_request.h"
-#include "msgbus_securereq.h"
-
-namespace NKikimr {
-namespace NMsgBusProxy {
-
-using namespace NActors;
-
-class TMessageBusWhoAmI : public TMessageBusSecureRequest<TMessageBusServerRequestBase<TMessageBusWhoAmI>> {
- using TBase = TMessageBusSecureRequest<TMessageBusServerRequestBase<TMessageBusWhoAmI>>;
- THolder<TBusWhoAmI> Request;
-
-public:
+#include "msgbus_server.h"
+#include "msgbus_server_request.h"
+#include "msgbus_securereq.h"
+
+namespace NKikimr {
+namespace NMsgBusProxy {
+
+using namespace NActors;
+
+class TMessageBusWhoAmI : public TMessageBusSecureRequest<TMessageBusServerRequestBase<TMessageBusWhoAmI>> {
+ using TBase = TMessageBusSecureRequest<TMessageBusServerRequestBase<TMessageBusWhoAmI>>;
+ THolder<TBusWhoAmI> Request;
+
+public:
static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
return NKikimrServices::TActivity::WHOAMI;
- }
-
- TMessageBusWhoAmI(NMsgBusProxy::TBusMessageContext& msg)
- : TMessageBusSecureRequest<TMessageBusServerRequestBase<TMessageBusWhoAmI>>(msg)
- , Request(static_cast<TBusWhoAmI*>(msg.ReleaseMessage()))
- {
- SetSecurityToken(Request->Record.GetSecurityToken());
- }
-
- void Bootstrap(const TActorContext& ctx) {
- THolder<NMsgBusProxy::TBusResponse> response(new NMsgBusProxy::TBusResponse());
- response->Record.SetStatus(NMsgBusProxy::MSTATUS_OK);
- const TEvTicketParser::TEvAuthorizeTicketResult* result = GetAuthorizeTicketResult();
- if (result != nullptr) {
- if (result->Error) {
- response->Record.SetErrorReason(result->Error.Message);
- response->Record.SetStatus(NMsgBusProxy::MSTATUS_ERROR);
- } else {
- if (result->Token != nullptr) {
- response->Record.SetUserName(result->Token->GetUserSID());
- if (Request->Record.GetReturnGroups()) {
- for (const auto& value : result->Token->GetGroupSIDs()) {
- response->Record.AddGroups(value);
- }
- }
- }
- }
- }
- SendReply(response.Release());
- Die(ctx);
- }
-};
-
-IActor* CreateMessageBusWhoAmI(NMsgBusProxy::TBusMessageContext& msg) {
- return new TMessageBusWhoAmI(msg);
-}
-
-}
-}
+ }
+
+ TMessageBusWhoAmI(NMsgBusProxy::TBusMessageContext& msg)
+ : TMessageBusSecureRequest<TMessageBusServerRequestBase<TMessageBusWhoAmI>>(msg)
+ , Request(static_cast<TBusWhoAmI*>(msg.ReleaseMessage()))
+ {
+ SetSecurityToken(Request->Record.GetSecurityToken());
+ }
+
+ void Bootstrap(const TActorContext& ctx) {
+ THolder<NMsgBusProxy::TBusResponse> response(new NMsgBusProxy::TBusResponse());
+ response->Record.SetStatus(NMsgBusProxy::MSTATUS_OK);
+ const TEvTicketParser::TEvAuthorizeTicketResult* result = GetAuthorizeTicketResult();
+ if (result != nullptr) {
+ if (result->Error) {
+ response->Record.SetErrorReason(result->Error.Message);
+ response->Record.SetStatus(NMsgBusProxy::MSTATUS_ERROR);
+ } else {
+ if (result->Token != nullptr) {
+ response->Record.SetUserName(result->Token->GetUserSID());
+ if (Request->Record.GetReturnGroups()) {
+ for (const auto& value : result->Token->GetGroupSIDs()) {
+ response->Record.AddGroups(value);
+ }
+ }
+ }
+ }
+ }
+ SendReply(response.Release());
+ Die(ctx);
+ }
+};
+
+IActor* CreateMessageBusWhoAmI(NMsgBusProxy::TBusMessageContext& msg) {
+ return new TMessageBusWhoAmI(msg);
+}
+
+}
+}
diff --git a/ydb/core/client/server/msgbus_servicereq.h b/ydb/core/client/server/msgbus_servicereq.h
index 0e9690cc9b0..704a231dd1d 100644
--- a/ydb/core/client/server/msgbus_servicereq.h
+++ b/ydb/core/client/server/msgbus_servicereq.h
@@ -17,11 +17,11 @@ protected:
const TDuration Timeout;
void SendReplyAndDie(NBus::TBusMessage *reply, const TActorContext &ctx) {
- SendReplyMove(reply);
+ SendReplyMove(reply);
return this->Die(ctx);
}
- TMessageBusLocalServiceRequest(TBusMessageContext &msg, const TDuration& timeout)
+ TMessageBusLocalServiceRequest(TBusMessageContext &msg, const TDuration& timeout)
: TMessageBusSessionIdentHolder(msg)
, ServiceID()
, Timeout(timeout)
@@ -39,9 +39,9 @@ public:
IEventBase* request = static_cast<TDerived *>(this)->MakeReq(ctx);
ctx.Send(ServiceID, request, IEventHandle::FlagTrackDelivery, 0);
- if (Timeout) {
+ if (Timeout) {
this->Become(&TDerived::StateFunc, ctx, Timeout, new TEvents::TEvWakeup());
- } else {
+ } else {
// no timeout
this->Become(&TDerived::StateFunc);
}
diff --git a/ydb/core/client/server/msgbus_tabletreq.h b/ydb/core/client/server/msgbus_tabletreq.h
index 5e6863c69ce..f173ae90976 100644
--- a/ydb/core/client/server/msgbus_tabletreq.h
+++ b/ydb/core/client/server/msgbus_tabletreq.h
@@ -67,7 +67,7 @@ protected:
}
void SendReplyAndDie(NBus::TBusMessage *reply, const TActorContext &ctx) {
- SendReplyMove(reply);
+ SendReplyMove(reply);
return Die(ctx);
}
@@ -87,7 +87,7 @@ public:
void Bootstrap(const TActorContext &ctx) {
NTabletPipe::TClientConfig clientConfig;
if (WithRetry) {
- clientConfig.RetryPolicy = NTabletPipe::TClientRetryPolicy::WithRetries();
+ clientConfig.RetryPolicy = NTabletPipe::TClientRetryPolicy::WithRetries();
}
if (ConnectToFollower) {
@@ -139,6 +139,6 @@ public:
}
};
-
+
}
}
diff --git a/ydb/core/client/server/ya.make b/ydb/core/client/server/ya.make
index e42eed0f079..8cbeec21b77 100644
--- a/ydb/core/client/server/ya.make
+++ b/ydb/core/client/server/ya.make
@@ -8,20 +8,20 @@ OWNER(
SRCS(
document_conversion.h
- http_ping.cpp
- http_ping.h
+ http_ping.cpp
+ http_ping.h
msgbus_blobstorage_config.cpp
msgbus_bsadm.cpp
- msgbus_http_server.h
- msgbus_http_server.cpp
+ msgbus_http_server.h
+ msgbus_http_server.cpp
msgbus_server.cpp
msgbus_server.h
msgbus_server_cms.cpp
msgbus_server_configdummy.cpp
msgbus_server_console.cpp
- msgbus_server_db.cpp
- msgbus_server_drain_node.cpp
- msgbus_server_fill_node.cpp
+ msgbus_server_db.cpp
+ msgbus_server_drain_node.cpp
+ msgbus_server_fill_node.cpp
msgbus_server_get.cpp
msgbus_server_hive_create_tablet.cpp
msgbus_server_keyvalue.cpp
@@ -32,7 +32,7 @@ SRCS(
msgbus_server_pq_metarequest.h
msgbus_server_pq_metarequest.cpp
msgbus_server_pq_read_session_info.cpp
- msgbus_server_resolve_node.cpp
+ msgbus_server_resolve_node.cpp
msgbus_server_ic_debug.cpp
msgbus_server_load.cpp
msgbus_server_local_enumerate_tablets.cpp
@@ -40,22 +40,22 @@ SRCS(
msgbus_server_local_scheme_tx.cpp
msgbus_server_node_registration.cpp
msgbus_server_proxy.cpp
- msgbus_server_proxy.h
- msgbus_server_request.cpp
- msgbus_server_request.h
+ msgbus_server_proxy.h
+ msgbus_server_request.cpp
+ msgbus_server_request.h
msgbus_server_s3_listing.cpp
msgbus_server_scheme_initroot.cpp
- msgbus_server_scheme_request.cpp
+ msgbus_server_scheme_request.cpp
msgbus_server_sqs.cpp
msgbus_server_tablet_counters.cpp
- msgbus_server_tablet_kill.cpp
- msgbus_server_tablet_state.cpp
+ msgbus_server_tablet_kill.cpp
+ msgbus_server_tablet_state.cpp
msgbus_server_test_shard_request.cpp
- msgbus_server_tracer.cpp
- msgbus_server_tracer.h
- msgbus_server_tx_request.cpp
+ msgbus_server_tracer.cpp
+ msgbus_server_tracer.h
+ msgbus_server_tx_request.cpp
msgbus_server_types.cpp
- msgbus_server_whoami.cpp
+ msgbus_server_whoami.cpp
msgbus_servicereq.h
msgbus_tabletreq.h
grpc_server.cpp
diff --git a/ydb/core/cms/cluster_info.h b/ydb/core/cms/cluster_info.h
index 5ea1ba38673..af5fe24af80 100644
--- a/ydb/core/cms/cluster_info.h
+++ b/ydb/core/cms/cluster_info.h
@@ -335,7 +335,7 @@ using TNodeInfoPtr = TIntrusivePtr<TNodeInfo>;
*/
struct TTabletInfo {
using EState = NKikimrWhiteboard::TTabletStateInfo::ETabletState;
- using EType = TTabletTypes::EType;
+ using EType = TTabletTypes::EType;
TTabletInfo() = default;
TTabletInfo(const TTabletInfo &other) = default;
@@ -345,7 +345,7 @@ struct TTabletInfo {
TTabletInfo &operator=(TTabletInfo &&other) = default;
ui64 TabletId = 0;
- EType Type = TTabletTypes::Unknown;
+ EType Type = TTabletTypes::Unknown;
EState State = NKikimrWhiteboard::TTabletStateInfo::Created;
bool Leader = false;
ui32 NodeId = 0;
diff --git a/ydb/core/cms/cluster_info_ut.cpp b/ydb/core/cms/cluster_info_ut.cpp
index 46108bcafab..8b9d3b3d653 100644
--- a/ydb/core/cms/cluster_info_ut.cpp
+++ b/ydb/core/cms/cluster_info_ut.cpp
@@ -17,7 +17,7 @@ using namespace NKikimrWhiteboard;
using namespace NKikimrBlobStorage;
using namespace NKikimrCms;
-TTabletStateInfo MakeTabletInfo(ui64 id, TTabletTypes::EType type,
+TTabletStateInfo MakeTabletInfo(ui64 id, TTabletTypes::EType type,
TTabletStateInfo::ETabletState state, bool leader)
{
TTabletStateInfo tablet;
@@ -345,12 +345,12 @@ Y_UNIT_TEST_SUITE(TClusterInfoTest) {
UNIT_ASSERT(cluster.HasVDisk({0, 1, 0, 2, 0}));
CheckVDisk(cluster.VDisk({0, 1, 0, 2, 0}), TVDiskID(0, 1, 0, 2, 0), 3, UP, 3, 1, 2);
- cluster.AddTablet(1, MakeTabletInfo(1, TTabletTypes::Hive, TTabletStateInfo::Active, true));
+ cluster.AddTablet(1, MakeTabletInfo(1, TTabletTypes::Hive, TTabletStateInfo::Active, true));
UNIT_ASSERT(cluster.HasTablet(1));
UNIT_ASSERT(!cluster.HasTablet(2));
UNIT_ASSERT_VALUES_EQUAL(cluster.Node(1).Tablets.size(), 1);
UNIT_ASSERT_VALUES_EQUAL(cluster.Tablet(1).TabletId, 1);
- UNIT_ASSERT_VALUES_EQUAL(cluster.Tablet(1).Type, TTabletTypes::Hive);
+ UNIT_ASSERT_VALUES_EQUAL(cluster.Tablet(1).Type, TTabletTypes::Hive);
UNIT_ASSERT_VALUES_EQUAL(cluster.Tablet(1).State, TTabletStateInfo::Active);
UNIT_ASSERT_VALUES_EQUAL(cluster.Tablet(1).Leader, true);
diff --git a/ydb/core/cms/cms.h b/ydb/core/cms/cms.h
index ed4b8d60c53..25cb8ef024b 100644
--- a/ydb/core/cms/cms.h
+++ b/ydb/core/cms/cms.h
@@ -77,77 +77,77 @@ struct TEvCms {
static_assert(EvEnd < EventSpaceEnd(TKikimrEvents::ES_CMS), "expect EvEnd < EventSpaceEnd(TKikimrEvents::ES_CMS)");
- template <typename TEv, typename TRecord, ui32 TEventType>
- using TEventPB = TEventShortDebugPB<TEv, TRecord, TEventType>;
-
+ template <typename TEv, typename TRecord, ui32 TEventType>
+ using TEventPB = TEventShortDebugPB<TEv, TRecord, TEventType>;
+
struct TEvClusterStateRequest : public TEventPB<TEvClusterStateRequest,
NKikimrCms::TClusterStateRequest,
- EvClusterStateRequest> {
+ EvClusterStateRequest> {
};
struct TEvClusterStateResponse : public TEventPB<TEvClusterStateResponse,
NKikimrCms::TClusterStateResponse,
- EvClusterStateResponse> {
+ EvClusterStateResponse> {
};
struct TEvPermissionRequest : public TEventPB<TEvPermissionRequest,
NKikimrCms::TPermissionRequest,
- EvPermissionRequest> {
+ EvPermissionRequest> {
};
struct TEvCheckRequest : public TEventPB<TEvCheckRequest,
NKikimrCms::TCheckRequest,
- EvCheckRequest> {
+ EvCheckRequest> {
};
struct TEvConditionalPermissionRequest : public TEventPB<TEvConditionalPermissionRequest,
NKikimrCms::TConditionalPermissionRequest,
- EvConditionalPermissionRequest> {
+ EvConditionalPermissionRequest> {
};
struct TEvPermissionResponse : public TEventPB<TEvPermissionResponse,
NKikimrCms::TPermissionResponse,
- EvPermissionResponse> {
+ EvPermissionResponse> {
};
struct TEvManageRequestRequest : public TEventPB<TEvManageRequestRequest,
NKikimrCms::TManageRequestRequest,
- EvManageRequestRequest> {
+ EvManageRequestRequest> {
};
struct TEvManageRequestResponse : public TEventPB<TEvManageRequestResponse,
NKikimrCms::TManageRequestResponse,
- EvManageRequestResponse> {
+ EvManageRequestResponse> {
};
struct TEvManagePermissionRequest : public TEventPB<TEvManagePermissionRequest,
NKikimrCms::TManagePermissionRequest,
- EvManagePermissionRequest> {
+ EvManagePermissionRequest> {
};
struct TEvManagePermissionResponse : public TEventPB<TEvManagePermissionResponse,
NKikimrCms::TManagePermissionResponse,
- EvManagePermissionResponse> {
+ EvManagePermissionResponse> {
};
struct TEvNotification : public TEventPB<TEvNotification,
NKikimrCms::TNotification,
- EvNotification> {
+ EvNotification> {
};
struct TEvNotificationResponse : public TEventPB<TEvNotificationResponse,
NKikimrCms::TNotificationResponse,
- EvNotificationResponse> {
+ EvNotificationResponse> {
};
struct TEvManageNotificationRequest : public TEventPB<TEvManageNotificationRequest,
NKikimrCms::TManageNotificationRequest,
- EvManageNotificationRequest> {
+ EvManageNotificationRequest> {
};
struct TEvManageNotificationResponse : public TEventPB<TEvManageNotificationResponse,
NKikimrCms::TManageNotificationResponse,
- EvManageNotificationResponse> {
+ EvManageNotificationResponse> {
};
struct TEvWalleCreateTaskRequest : public TEventPB<TEvWalleCreateTaskRequest,
@@ -238,22 +238,22 @@ struct TEvCms {
struct TEvGetConfigRequest : public TEventPB<TEvGetConfigRequest,
NKikimrCms::TGetConfigRequest,
- EvGetConfigRequest> {
+ EvGetConfigRequest> {
};
struct TEvGetConfigResponse : public TEventPB<TEvGetConfigResponse,
NKikimrCms::TGetConfigResponse,
- EvGetConfigResponse> {
+ EvGetConfigResponse> {
};
struct TEvSetConfigRequest : public TEventPB<TEvSetConfigRequest,
NKikimrCms::TSetConfigRequest,
- EvSetConfigRequest> {
+ EvSetConfigRequest> {
};
struct TEvSetConfigResponse : public TEventPB<TEvSetConfigResponse,
NKikimrCms::TSetConfigResponse,
- EvSetConfigResponse> {
+ EvSetConfigResponse> {
};
struct TEvSetMarkerRequest : public TEventPB<TEvSetMarkerRequest,
diff --git a/ydb/core/cms/console/console.cpp b/ydb/core/cms/console/console.cpp
index f1aefd55df8..fe477202af5 100644
--- a/ydb/core/cms/console/console.cpp
+++ b/ydb/core/cms/console/console.cpp
@@ -30,7 +30,7 @@ void TConsole::OnActivateExecutor(const TActorContext &ctx)
TenantsManager = new TTenantsManager(*this, domains->Domains.at(domainId),
Counters,
- AppData()->FeatureFlags);
+ AppData()->FeatureFlags);
ctx.RegisterWithSameMailbox(TenantsManager);
if (AppData(ctx)->NetClassifierConfig.GetUpdaterConfig().GetNetDataSourceUrl()) {
diff --git a/ydb/core/cms/console/console__create_tenant.cpp b/ydb/core/cms/console/console__create_tenant.cpp
index 728ac95c460..77d8166d547 100644
--- a/ydb/core/cms/console/console__create_tenant.cpp
+++ b/ydb/core/cms/console/console__create_tenant.cpp
@@ -124,8 +124,8 @@ public:
Tenant = new TTenant(path, TTenant::CREATING_POOLS, token);
- Tenant->IsExternalSubdomain = Self->FeatureFlags.GetEnableExternalSubdomains();
- Tenant->IsExternalHive = Self->FeatureFlags.GetEnableExternalHive();
+ Tenant->IsExternalSubdomain = Self->FeatureFlags.GetEnableExternalSubdomains();
+ Tenant->IsExternalHive = Self->FeatureFlags.GetEnableExternalHive();
Tenant->IsExternalSysViewProcessor = Self->FeatureFlags.GetEnablePersistentQueryStats();
if (rec.options().disable_external_subdomain()) {
@@ -142,11 +142,11 @@ public:
Tenant->PlanResolution = 0;
Tenant->TimeCastBucketsPerMediator = 0;
Tenant->IsExternalSubdomain = false;
- Tenant->IsExternalHive = false;
+ Tenant->IsExternalHive = false;
Tenant->IsExternalSysViewProcessor = false;
}
- Tenant->IsExternalHive &= Tenant->IsExternalSubdomain; // external hive without external sub domain is pointless
+ Tenant->IsExternalHive &= Tenant->IsExternalSubdomain; // external hive without external sub domain is pointless
Tenant->IsExternalSysViewProcessor &= Tenant->IsExternalSubdomain;
Tenant->StorageUnitsQuota = Self->Config.DefaultStorageUnitsQuota;
diff --git a/ydb/core/cms/console/console__scheme.h b/ydb/core/cms/console/console__scheme.h
index dd9dadda303..29eb6c3035a 100644
--- a/ydb/core/cms/console/console__scheme.h
+++ b/ydb/core/cms/console/console__scheme.h
@@ -37,7 +37,7 @@ struct Schema : NIceDb::Schema {
// } // DomainId
struct ErrorCode : Column<17, NScheme::NTypeIds::Uint32> {};
struct IsExternalSubDomain : Column<18, NScheme::NTypeIds::Bool> {};
- struct IsExternalHive : Column<19, NScheme::NTypeIds::Bool> {};
+ struct IsExternalHive : Column<19, NScheme::NTypeIds::Bool> {};
struct AreResourcesShared : Column<20, NScheme::NTypeIds::Bool> {};
// SharedDomainId {
struct SharedDomainSchemeShardId : Column<21, NScheme::NTypeIds::Uint64> {};
@@ -50,8 +50,8 @@ struct Schema : NIceDb::Schema {
struct DatabaseQuotas : Column<27, NScheme::NTypeIds::String> {};
using TKey = TableKey<Path>;
- using TColumns = TableColumns<Path, State, Coordinators, Mediators, PlanResolution,
- Issue, TxId, UserToken, SubdomainVersion, ConfirmedSubdomain, TimeCastBucketsPerMediator,
+ using TColumns = TableColumns<Path, State, Coordinators, Mediators, PlanResolution,
+ Issue, TxId, UserToken, SubdomainVersion, ConfirmedSubdomain, TimeCastBucketsPerMediator,
Attributes, Generation, SchemeShardId, PathId, ErrorCode, IsExternalSubDomain, IsExternalHive,
AreResourcesShared, SharedDomainSchemeShardId, SharedDomainPathId, IsExternalSysViewProcessor,
SchemaOperationQuotas, CreateIdempotencyKey, AlterIdempotencyKey, DatabaseQuotas>;
diff --git a/ydb/core/cms/console/console_tenants_manager.cpp b/ydb/core/cms/console/console_tenants_manager.cpp
index 6e01855ad1a..0db3f5dceda 100644
--- a/ydb/core/cms/console/console_tenants_manager.cpp
+++ b/ydb/core/cms/console/console_tenants_manager.cpp
@@ -452,9 +452,9 @@ public:
subdomain.SetName(Subdomain.second);
if (Tenant->IsExternalSubdomain) {
subdomain.SetExternalSchemeShard(true);
- if (Tenant->IsExternalHive) {
- subdomain.SetExternalHive(true);
- }
+ if (Tenant->IsExternalHive) {
+ subdomain.SetExternalHive(true);
+ }
if (Tenant->IsExternalSysViewProcessor) {
subdomain.SetExternalSysViewProcessor(true);
}
@@ -480,9 +480,9 @@ public:
}
if (Tenant->IsExternalSubdomain) {
subdomain.SetExternalSchemeShard(true);
- if (Tenant->IsExternalHive) {
- subdomain.SetExternalHive(true);
- }
+ if (Tenant->IsExternalHive) {
+ subdomain.SetExternalHive(true);
+ }
if (Tenant->IsExternalSysViewProcessor) {
subdomain.SetExternalSysViewProcessor(true);
}
@@ -1182,7 +1182,7 @@ TTenantsManager::TTenant::TTenant(const TString &path,
, ConfirmedSubdomain(0)
, Generation(0)
, IsExternalSubdomain(false)
- , IsExternalHive(false)
+ , IsExternalHive(false)
, IsExternalSysViewProcessor(false)
, AreResourcesShared(false)
{
@@ -2246,7 +2246,7 @@ void TTenantsManager::DbAddTenant(TTenant::TPtr tenant,
<< " attrs=" << tenant->Attributes.ShortDebugString()
<< " generation=" << tenant->Generation
<< " errorcode=" << tenant->ErrorCode
- << " isExternalSubDomain=" << tenant->IsExternalSubdomain
+ << " isExternalSubDomain=" << tenant->IsExternalSubdomain
<< " isExternalHive=" << tenant->IsExternalHive
<< " isExternalSysViewProcessor=" << tenant->IsExternalSysViewProcessor
<< " areResourcesShared=" << tenant->AreResourcesShared
@@ -2267,7 +2267,7 @@ void TTenantsManager::DbAddTenant(TTenant::TPtr tenant,
NIceDb::TUpdate<Schema::Tenants::Attributes>(tenant->Attributes),
NIceDb::TUpdate<Schema::Tenants::Generation>(tenant->Generation),
NIceDb::TUpdate<Schema::Tenants::ErrorCode>(tenant->ErrorCode),
- NIceDb::TUpdate<Schema::Tenants::IsExternalSubDomain>(tenant->IsExternalSubdomain),
+ NIceDb::TUpdate<Schema::Tenants::IsExternalSubDomain>(tenant->IsExternalSubdomain),
NIceDb::TUpdate<Schema::Tenants::IsExternalHive>(tenant->IsExternalHive),
NIceDb::TUpdate<Schema::Tenants::IsExternalSysViewProcessor>(tenant->IsExternalSysViewProcessor),
NIceDb::TUpdate<Schema::Tenants::AreResourcesShared>(tenant->AreResourcesShared),
@@ -2372,7 +2372,7 @@ bool TTenantsManager::DbLoadState(TTransactionContext &txc, const TActorContext
Ydb::StatusIds::StatusCode errorCode
= static_cast<Ydb::StatusIds::StatusCode>(tenantRowset.GetValueOrDefault<Schema::Tenants::ErrorCode>(0));
bool isExternalSubDomain = tenantRowset.GetValueOrDefault<Schema::Tenants::IsExternalSubDomain>(false);
- bool isExternalHive = tenantRowset.GetValueOrDefault<Schema::Tenants::IsExternalHive>(false);
+ bool isExternalHive = tenantRowset.GetValueOrDefault<Schema::Tenants::IsExternalHive>(false);
bool isExternalSysViewProcessor = tenantRowset.GetValueOrDefault<Schema::Tenants::IsExternalSysViewProcessor>(false);
const bool areResourcesShared = tenantRowset.GetValueOrDefault<Schema::Tenants::AreResourcesShared>(false);
@@ -2391,7 +2391,7 @@ bool TTenantsManager::DbLoadState(TTransactionContext &txc, const TActorContext
tenant->ErrorCode = errorCode;
tenant->Issue = issue;
tenant->IsExternalSubdomain = isExternalSubDomain;
- tenant->IsExternalHive = isExternalHive;
+ tenant->IsExternalHive = isExternalHive;
tenant->IsExternalSysViewProcessor = isExternalSysViewProcessor;
tenant->AreResourcesShared = areResourcesShared;
diff --git a/ydb/core/cms/console/console_tenants_manager.h b/ydb/core/cms/console/console_tenants_manager.h
index e15e50405b5..a21615dd622 100644
--- a/ydb/core/cms/console/console_tenants_manager.h
+++ b/ydb/core/cms/console/console_tenants_manager.h
@@ -517,7 +517,7 @@ public:
TDomainId DomainId;
TDomainId SharedDomainId;
bool IsExternalSubdomain;
- bool IsExternalHive;
+ bool IsExternalHive;
bool IsExternalSysViewProcessor;
bool AreResourcesShared;
THashSet<TTenant::TPtr> HostedTenants;
@@ -960,11 +960,11 @@ public:
TTenantsManager(TConsole &self,
TDomainsInfo::TDomain::TPtr domain,
TDynamicCounterPtr counters,
- NKikimrConfig::TFeatureFlags featureFlags)
+ NKikimrConfig::TFeatureFlags featureFlags)
: Self(self)
, Domain(domain)
, Counters(counters)
- , FeatureFlags(std::move(featureFlags))
+ , FeatureFlags(std::move(featureFlags))
{
}
@@ -993,7 +993,7 @@ private:
TQueue<THolder<ITransaction>> DelayedTxs;
TSlotStats SlotStats;
TCounters Counters;
- NKikimrConfig::TFeatureFlags FeatureFlags;
+ NKikimrConfig::TFeatureFlags FeatureFlags;
};
} // namespace NConsole
diff --git a/ydb/core/cms/console/console_ut_tenants.cpp b/ydb/core/cms/console/console_ut_tenants.cpp
index 972988680ae..57e4820af72 100644
--- a/ydb/core/cms/console/console_ut_tenants.cpp
+++ b/ydb/core/cms/console/console_ut_tenants.cpp
@@ -394,7 +394,7 @@ void CheckPoolScope(TTenantTestRuntime &runtime,
read.AddName(name);
NTabletPipe::TClientConfig pipeConfig;
- pipeConfig.RetryPolicy = NTabletPipe::TClientRetryPolicy::WithRetries();
+ pipeConfig.RetryPolicy = NTabletPipe::TClientRetryPolicy::WithRetries();
runtime.SendToPipe(MakeBSControllerID(0), runtime.Sender, request.Release(), 0, pipeConfig);
TAutoPtr<IEventHandle> handle;
diff --git a/ydb/core/cms/http.cpp b/ydb/core/cms/http.cpp
index 1f95ce9c330..648d864b6ed 100644
--- a/ydb/core/cms/http.cpp
+++ b/ydb/core/cms/http.cpp
@@ -149,7 +149,7 @@ private:
result << " Headers {";
for (const auto& header : request.GetHeaders()) {
- if (stricmp(header.Name().data(), "Authorization") == 0) {
+ if (stricmp(header.Name().data(), "Authorization") == 0) {
continue;
}
diff --git a/ydb/core/cms/json_proxy.h b/ydb/core/cms/json_proxy.h
index a3a8ff240f6..185d0ce01b6 100644
--- a/ydb/core/cms/json_proxy.h
+++ b/ydb/core/cms/json_proxy.h
@@ -71,7 +71,7 @@ public:
"TJsonProxyBase send request to " << GetTabletName() << " tablet " << tid);
NTabletPipe::TClientConfig pipeConfig;
- pipeConfig.RetryPolicy = {.RetryLimitCount = 10};
+ pipeConfig.RetryPolicy = {.RetryLimitCount = 10};
Pipe = ctx.RegisterWithSameMailbox(NTabletPipe::CreateClient(ctx.SelfID, tid, pipeConfig));
NTabletPipe::SendData(ctx, Pipe, request.Release());
diff --git a/ydb/core/cms/sentinel.cpp b/ydb/core/cms/sentinel.cpp
index 9e4fea0f69a..638b78fe09b 100644
--- a/ydb/core/cms/sentinel.cpp
+++ b/ydb/core/cms/sentinel.cpp
@@ -288,7 +288,7 @@ protected:
const ui64 bscId = MakeBSControllerID(domains->GetDefaultStateStorageGroup(domainUid));
NTabletPipe::TClientConfig config;
- config.RetryPolicy = NTabletPipe::TClientRetryPolicy::WithRetries();
+ config.RetryPolicy = NTabletPipe::TClientRetryPolicy::WithRetries();
CmsState->BSControllerPipe = this->Register(NTabletPipe::CreateClient(CmsState->CmsActorId, bscId, config));
}
diff --git a/ydb/core/cms/walle_api_handler.cpp b/ydb/core/cms/walle_api_handler.cpp
index 60931467917..7b62f3275a9 100644
--- a/ydb/core/cms/walle_api_handler.cpp
+++ b/ydb/core/cms/walle_api_handler.cpp
@@ -336,10 +336,10 @@ private:
ui32 domain = AppData(ctx)->DomainsInfo->Domains.begin()->first;
NTabletPipe::TClientConfig pipeConfig;
- pipeConfig.RetryPolicy = {
- .MinRetryTime = TDuration::MilliSeconds(10),
- .MaxRetryTime = TDuration::Seconds(10),
- };
+ pipeConfig.RetryPolicy = {
+ .MinRetryTime = TDuration::MilliSeconds(10),
+ .MaxRetryTime = TDuration::Seconds(10),
+ };
CmsPipe = ctx.RegisterWithSameMailbox(NTabletPipe::CreateClient(ctx.SelfID, MakeCmsID(domain), pipeConfig));
NTabletPipe::SendData(ctx, CmsPipe, ev);
}
diff --git a/ydb/core/control/immediate_control_board_actor_ut.cpp b/ydb/core/control/immediate_control_board_actor_ut.cpp
index 95f9ab7509c..2753077d936 100644
--- a/ydb/core/control/immediate_control_board_actor_ut.cpp
+++ b/ydb/core/control/immediate_control_board_actor_ut.cpp
@@ -251,7 +251,7 @@ public:
struct THttpRequest : NMonitoring::IHttpRequest {
HTTP_METHOD Method;
TCgiParameters CgiParameters;
- THttpHeaders HttpHeaders;
+ THttpHeaders HttpHeaders;
THttpRequest(HTTP_METHOD method)
: Method(method)
@@ -282,14 +282,14 @@ struct THttpRequest : NMonitoring::IHttpRequest {
HTTP_METHOD GetMethod() const override {
return Method;
}
-
- const THttpHeaders& GetHeaders() const override {
- return HttpHeaders;
- }
-
- TString GetRemoteAddr() const override {
- return TString();
- }
+
+ const THttpHeaders& GetHeaders() const override {
+ return HttpHeaders;
+ }
+
+ TString GetRemoteAddr() const override {
+ return TString();
+ }
};
class TTestHttpGetResponse : public TBaseTest {
diff --git a/ydb/core/control/ut/ya.make b/ydb/core/control/ut/ya.make
index 12953a95272..18a4c9dc3b9 100644
--- a/ydb/core/control/ut/ya.make
+++ b/ydb/core/control/ut/ya.make
@@ -15,7 +15,7 @@ PEERDIR(
library/cpp/actors/core
library/cpp/actors/interconnect
library/cpp/testing/unittest
- util
+ util
ydb/core/base
ydb/core/mind
ydb/core/mon
diff --git a/ydb/core/driver_lib/cli_base/cli_cmds_db.cpp b/ydb/core/driver_lib/cli_base/cli_cmds_db.cpp
index 9b569dd5df0..450d4135c6c 100644
--- a/ydb/core/driver_lib/cli_base/cli_cmds_db.cpp
+++ b/ydb/core/driver_lib/cli_base/cli_cmds_db.cpp
@@ -1,5 +1,5 @@
-#include "cli.h"
-#include "cli_cmds.h"
+#include "cli.h"
+#include "cli_cmds.h"
#include <ydb/core/tx/schemeshard/schemeshard_user_attr_limits.h>
@@ -18,33 +18,33 @@
#include <util/string/join.h>
#include <util/string/printf.h>
-namespace NKikimr {
-namespace NDriverClient {
-
+namespace NKikimr {
+namespace NDriverClient {
+
void WarnProfilePathSet() {
Cout << "FYI: profile path is set. You can use short pathnames. Try --help for more info." << Endl;
}
-class TClientCommandSchemaMkdir : public TClientCommand {
-public:
- TClientCommandSchemaMkdir()
- : TClientCommand("mkdir", {}, "Create directory")
- {}
-
+class TClientCommandSchemaMkdir : public TClientCommand {
+public:
+ TClientCommandSchemaMkdir()
+ : TClientCommand("mkdir", {}, "Create directory")
+ {}
+
TAutoPtr<NKikimrClient::TSchemeOperation> Request;
-
- virtual void Config(TConfig& config) override {
- TClientCommand::Config(config);
+
+ virtual void Config(TConfig& config) override {
+ TClientCommand::Config(config);
config.SetFreeArgsNum(1);
SetFreeArgTitle(0, "<NAME>", "Full pathname of a directory (e.g. /ru/home/user/mydb/test1/test2).\n"
" Or short pathname if profile path is set (e.g. test1/test2).");
- }
-
+ }
+
TString Base;
TString Name;
-
- virtual void Parse(TConfig& config) override {
- TClientCommand::Parse(config);
+
+ virtual void Parse(TConfig& config) override {
+ TClientCommand::Parse(config);
TString pathname = config.ParseResult->GetFreeArgs()[0];
size_t pos = pathname.rfind('/');
if (config.Path) {
@@ -59,17 +59,17 @@ public:
}
Base = pathname.substr(0, pos);
Name = pathname.substr(pos + 1);
- }
-
- virtual int Run(TConfig& config) override {
+ }
+
+ virtual int Run(TConfig& config) override {
auto handler = [this](NClient::TKikimr& kikimr) {
kikimr.GetSchemaRoot(Base).MakeDirectory(Name);
return 0;
};
return InvokeThroughKikimr(config, std::move(handler));
- }
-};
-
+ }
+};
+
class TClientCommandSchemaDrop : public TClientCommand {
public:
TClientCommandSchemaDrop()
@@ -116,46 +116,46 @@ public:
};
class TClientCommandSchemaExec : public TClientCommandConfig {
-public:
- TClientCommandSchemaExec()
+public:
+ TClientCommandSchemaExec()
: TClientCommandConfig("execute", { "exec" }, "Execute schema protobuf")
- {}
-
+ {}
+
bool ReturnTxId;
TList<TAutoPtr<NKikimrClient::TSchemeOperation>> Requests;
-
- virtual void Config(TConfig& config) override {
- TClientCommand::Config(config);
+
+ virtual void Config(TConfig& config) override {
+ TClientCommand::Config(config);
ReturnTxId = false;
config.Opts->AddLongOption('t', "txid", "Print TxId").NoArgument().SetFlag(&ReturnTxId);
config.SetFreeArgsNum(1);
SetFreeArgTitle(0, "<SCHEMA-PROTO>", "Schema protobuf or file with schema protobuf");
- }
-
- virtual void Parse(TConfig& config) override {
- TClientCommand::Parse(config);
+ }
+
+ virtual void Parse(TConfig& config) override {
+ TClientCommand::Parse(config);
NKikimrSchemeOp::TModifyScript protoScript;
- ParseProtobuf(&protoScript, config.ParseResult->GetFreeArgs()[0]);
- for (const auto& modifyScheme : protoScript.GetModifyScheme()) {
+ ParseProtobuf(&protoScript, config.ParseResult->GetFreeArgs()[0]);
+ for (const auto& modifyScheme : protoScript.GetModifyScheme()) {
TAutoPtr<NKikimrClient::TSchemeOperation> request = new NKikimrClient::TSchemeOperation();
- request->MutablePollOptions()->SetTimeout(NClient::TKikimr::POLLING_TIMEOUT);
- request->MutableTransaction()->MutableModifyScheme()->CopyFrom(modifyScheme);
- Requests.emplace_back(request);
- }
- }
-
- virtual int Run(TConfig& config) override {
- int result = 0;
- for (const auto& pbRequest : Requests) {
+ request->MutablePollOptions()->SetTimeout(NClient::TKikimr::POLLING_TIMEOUT);
+ request->MutableTransaction()->MutableModifyScheme()->CopyFrom(modifyScheme);
+ Requests.emplace_back(request);
+ }
+ }
+
+ virtual int Run(TConfig& config) override {
+ int result = 0;
+ for (const auto& pbRequest : Requests) {
TAutoPtr<NMsgBusProxy::TBusSchemeOperation> request(new NMsgBusProxy::TBusSchemeOperation());
- request->Record.MergeFrom(*pbRequest);
+ request->Record.MergeFrom(*pbRequest);
result = MessageBusCall<NMsgBusProxy::TBusSchemeOperation, NMsgBusProxy::TBusResponse>(config, request,
[this](const NMsgBusProxy::TBusResponse& response) -> int {
- if (response.Record.GetStatus() != NMsgBusProxy::MSTATUS_OK) {
- Cerr << ToCString(static_cast<NMsgBusProxy::EResponseStatus>(response.Record.GetStatus())) << " " << response.Record.GetErrorReason() << Endl;
- return 1;
- }
+ if (response.Record.GetStatus() != NMsgBusProxy::MSTATUS_OK) {
+ Cerr << ToCString(static_cast<NMsgBusProxy::EResponseStatus>(response.Record.GetStatus())) << " " << response.Record.GetErrorReason() << Endl;
+ return 1;
+ }
if (ReturnTxId) {
if (response.Record.HasFlatTxId() && response.Record.GetFlatTxId().HasTxId()) {
Cout << "TxId: " << response.Record.GetFlatTxId().GetTxId() << Endl;
@@ -163,59 +163,59 @@ public:
Cout << "TxId: not returned" << Endl;
}
}
- return 0;
- });
- if (result != 0) {
- break;
- }
- }
- return result;
- }
-};
-
-class TClientCommandSchemaDescribe : public TClientCommand {
-public:
- TClientCommandSchemaDescribe()
- : TClientCommand("describe", { "desc" }, "Describe schema object")
- {}
-
+ return 0;
+ });
+ if (result != 0) {
+ break;
+ }
+ }
+ return result;
+ }
+};
+
+class TClientCommandSchemaDescribe : public TClientCommand {
+public:
+ TClientCommandSchemaDescribe()
+ : TClientCommand("describe", { "desc" }, "Describe schema object")
+ {}
+
TAutoPtr<NKikimrClient::TSchemeDescribe> Request;
TString Path;
- bool Tree;
- bool Details;
- bool AccessRights;
- bool AccessRightsEffective;
+ bool Tree;
+ bool Details;
+ bool AccessRights;
+ bool AccessRightsEffective;
bool BackupInfo;
bool Protobuf;
bool PartitionStats;
bool Boundaries;
-
- virtual void Config(TConfig& config) override {
- TClientCommand::Config(config);
- Tree = false;
- Details = false;
- AccessRights = false;
- AccessRightsEffective = false;
+
+ virtual void Config(TConfig& config) override {
+ TClientCommand::Config(config);
+ Tree = false;
+ Details = false;
+ AccessRights = false;
+ AccessRightsEffective = false;
BackupInfo = false;
Protobuf = false;
PartitionStats = false;
Boundaries = false;
config.SetFreeArgsNum(1);
SetFreeArgTitle(0, "<PATH>", "Schema path or pathId (e.g. 72075186232623600/1225)");
- config.Opts->AddLongOption('t', "tree", "Show schema path tree").NoArgument().SetFlag(&Tree);
- config.Opts->AddLongOption('d', "details", "Show detailed information (like columns in a table)").NoArgument().SetFlag(&Details);
- config.Opts->AddLongOption('a', "acl", "Show owner and acl information").NoArgument().SetFlag(&AccessRights);
- config.Opts->AddLongOption('e', "effacl", "Show effective acl information").NoArgument().SetFlag(&AccessRightsEffective);
+ config.Opts->AddLongOption('t', "tree", "Show schema path tree").NoArgument().SetFlag(&Tree);
+ config.Opts->AddLongOption('d', "details", "Show detailed information (like columns in a table)").NoArgument().SetFlag(&Details);
+ config.Opts->AddLongOption('a', "acl", "Show owner and acl information").NoArgument().SetFlag(&AccessRights);
+ config.Opts->AddLongOption('e', "effacl", "Show effective acl information").NoArgument().SetFlag(&AccessRightsEffective);
config.Opts->AddLongOption('b', "backup", "Show backup information").NoArgument().SetFlag(&BackupInfo);
config.Opts->AddLongOption('P', "protobuf", "Debug print all info as is").NoArgument().SetFlag(&Protobuf);
config.Opts->AddLongOption('s', "stats", "Return partition stats").NoArgument().SetFlag(&PartitionStats);
config.Opts->AddLongOption("boundaries", "Return boundaries").NoArgument().SetFlag(&Boundaries);
- }
-
- virtual void Parse(TConfig& config) override {
- TClientCommand::Parse(config);
+ }
+
+ virtual void Parse(TConfig& config) override {
+ TClientCommand::Parse(config);
Request = new NKikimrClient::TSchemeDescribe();
- Path = config.ParseResult->GetFreeArgs()[0];
+ Path = config.ParseResult->GetFreeArgs()[0];
if (Path.StartsWith('/')) {
Request->SetPath(Path);
} else {
@@ -239,26 +239,26 @@ public:
options->SetShowPrivateTable(true);
Protobuf = Protobuf || PartitionStats || Boundaries;
- }
-
+ }
+
void PadString(TString& str, size_t size) {
- if (str.size() < size) {
+ if (str.size() < size) {
str += TString(size - str.size(), ' ');
- } else {
- str += ' ';
- }
- }
-
+ } else {
+ str += ' ';
+ }
+ }
+
void PrintEntry(const NKikimrSchemeOp::TPathDescription& path) {
const NKikimrSchemeOp::TDirEntry& entry(path.GetSelf());
TString type;
- switch(entry.GetPathType()) {
+ switch(entry.GetPathType()) {
case NKikimrSchemeOp::EPathTypeDir:
- type = "<dir>";
- break;
+ type = "<dir>";
+ break;
case NKikimrSchemeOp::EPathTypeTable:
- type = "<table>";
- break;
+ type = "<table>";
+ break;
case NKikimrSchemeOp::EPathTypeColumnStore:
type = "<column store>";
break;
@@ -272,57 +272,57 @@ public:
type = "<replication>";
break;
case NKikimrSchemeOp::EPathTypePersQueueGroup:
- type = "<pq group>";
- break;
- default:
- type = "<unknown>";
- break;
- }
-
+ type = "<pq group>";
+ break;
+ default:
+ type = "<unknown>";
+ break;
+ }
+
TString id(Sprintf("%lu/%lu", entry.GetSchemeshardId(), entry.GetPathId()));
TString name(entry.GetName());
- PadString(id, 24);
- PadString(type, 11);
- PadString(name, 26);
+ PadString(id, 24);
+ PadString(type, 11);
+ PadString(name, 26);
TString owner;
TString acl;
- if (AccessRights) {
- if (entry.HasOwner()) {
- owner = entry.GetOwner();
- PadString(owner, 20);
- }
- if (AccessRightsEffective) {
- if (entry.HasEffectiveACL()) {
- acl = NACLib::TACL(entry.GetEffectiveACL()).ToString();
- }
- } else {
- if (entry.HasACL()) {
- acl = NACLib::TACL(entry.GetACL()).ToString();
- }
- }
- }
- Cout << id << type << name << owner << acl << Endl;
- if (Details) {
- switch(entry.GetPathType()) {
+ if (AccessRights) {
+ if (entry.HasOwner()) {
+ owner = entry.GetOwner();
+ PadString(owner, 20);
+ }
+ if (AccessRightsEffective) {
+ if (entry.HasEffectiveACL()) {
+ acl = NACLib::TACL(entry.GetEffectiveACL()).ToString();
+ }
+ } else {
+ if (entry.HasACL()) {
+ acl = NACLib::TACL(entry.GetACL()).ToString();
+ }
+ }
+ }
+ Cout << id << type << name << owner << acl << Endl;
+ if (Details) {
+ switch(entry.GetPathType()) {
case NKikimrSchemeOp::EPathTypeTable: {
const NKikimrSchemeOp::TTableDescription& table(path.GetTable());
- size_t szWidth = id.size() + type.size() + entry.GetName().size();
- size_t szColumns[3] = {0, 0, 0};
+ size_t szWidth = id.size() + type.size() + entry.GetName().size();
+ size_t szColumns[3] = {0, 0, 0};
for (const NKikimrSchemeOp::TColumnDescription& column : table.GetColumns()) {
- szColumns[0] = std::max(szColumns[0], ToString(column.GetId()).size());
- szColumns[1] = std::max(szColumns[1], column.GetType().size());
- szColumns[2] = std::max(szColumns[2], column.GetName().size());
- szWidth = std::max(szWidth, szColumns[0] + szColumns[1] + szColumns[2] + 2 + 2);
- }
- for (size_t i = 0; i < szWidth; ++i) {
- if (i == szColumns[0] || i == (szColumns[0] + szColumns[1] + 1) || i == (szColumns[0] + szColumns[1] + szColumns[2] + 2)) {
- Cout << "┬";
- } else {
- Cout << "─";
- }
- }
- Cout << Endl;
- const auto& keyColumnIds(table.GetKeyColumnIds());
+ szColumns[0] = std::max(szColumns[0], ToString(column.GetId()).size());
+ szColumns[1] = std::max(szColumns[1], column.GetType().size());
+ szColumns[2] = std::max(szColumns[2], column.GetName().size());
+ szWidth = std::max(szWidth, szColumns[0] + szColumns[1] + szColumns[2] + 2 + 2);
+ }
+ for (size_t i = 0; i < szWidth; ++i) {
+ if (i == szColumns[0] || i == (szColumns[0] + szColumns[1] + 1) || i == (szColumns[0] + szColumns[1] + szColumns[2] + 2)) {
+ Cout << "┬";
+ } else {
+ Cout << "─";
+ }
+ }
+ Cout << Endl;
+ const auto& keyColumnIds(table.GetKeyColumnIds());
for (const NKikimrSchemeOp::TColumnDescription& column : table.GetColumns()) {
TString id(ToString(column.GetId()));
TString type(column.GetType());
@@ -330,15 +330,15 @@ public:
id = id + TString(szColumns[0] - id.size(), ' ');
type = type + TString(szColumns[1] - type.size(), ' ');
name = name + TString(szColumns[2] - name.size(), ' ');
- Cout << id << "│" << type << "│" << name << "│";
- auto itKey = std::find(keyColumnIds.begin(), keyColumnIds.end(), column.GetId());
- if (itKey != keyColumnIds.end()) {
- Cout << "K" << itKey - keyColumnIds.begin(); // 🔑
- }
- Cout << Endl;
- }
- break;
- }
+ Cout << id << "│" << type << "│" << name << "│";
+ auto itKey = std::find(keyColumnIds.begin(), keyColumnIds.end(), column.GetId());
+ if (itKey != keyColumnIds.end()) {
+ Cout << "K" << itKey - keyColumnIds.begin(); // 🔑
+ }
+ Cout << Endl;
+ }
+ break;
+ }
case NKikimrSchemeOp::EPathTypePersQueueGroup: {
const NKikimrSchemeOp::TPersQueueGroupDescription& pqGroup(path.GetPersQueueGroup());
for (ui32 pi = 0; pi < pqGroup.PartitionsSize(); ++pi) {
@@ -348,10 +348,10 @@ public:
}
break;
}
- default:
- break;
- }
- }
+ default:
+ break;
+ }
+ }
if (BackupInfo) {
if (path.HasBackupProgress()) {
NKikimrSchemeOp::TBackupProgress backup = path.GetBackupProgress();
@@ -387,93 +387,93 @@ public:
::google::protobuf::TextFormat::PrintToString(path, &debugProto);
Cout << debugProto << Endl;
}
- }
-
- virtual int Run(TConfig& config) override {
+ }
+
+ virtual int Run(TConfig& config) override {
TAutoPtr<NMsgBusProxy::TBusSchemeDescribe> request(new NMsgBusProxy::TBusSchemeDescribe());
- if (Request != nullptr)
- request->Record.MergeFrom(*Request);
-
+ if (Request != nullptr)
+ request->Record.MergeFrom(*Request);
+
TList<NKikimrSchemeOp::TPathDescription> entries;
-
- for(;;) {
+
+ for(;;) {
MessageBusCall<NMsgBusProxy::TBusSchemeDescribe, NMsgBusProxy::TBusResponse>(config, request,
[&entries](const NMsgBusProxy::TBusResponse& response) -> int {
- entries.push_front(response.Record.GetPathDescription());
- return 0;
- });
-
- if (Tree
- && entries.front().GetSelf().HasParentPathId()
- && entries.front().GetSelf().HasSchemeshardId()
- && entries.front().GetSelf().GetParentPathId() != entries.front().GetSelf().GetPathId()) {
+ entries.push_front(response.Record.GetPathDescription());
+ return 0;
+ });
+
+ if (Tree
+ && entries.front().GetSelf().HasParentPathId()
+ && entries.front().GetSelf().HasSchemeshardId()
+ && entries.front().GetSelf().GetParentPathId() != entries.front().GetSelf().GetPathId()) {
request = new NMsgBusProxy::TBusSchemeDescribe();
- request->Record.SetSchemeshardId(entries.front().GetSelf().GetSchemeshardId());
- request->Record.SetPathId(entries.front().GetSelf().GetParentPathId());
- continue;
- }
- break;
- }
- int cnt = 0;
- //Cout << Path << Endl;
+ request->Record.SetSchemeshardId(entries.front().GetSelf().GetSchemeshardId());
+ request->Record.SetPathId(entries.front().GetSelf().GetParentPathId());
+ continue;
+ }
+ break;
+ }
+ int cnt = 0;
+ //Cout << Path << Endl;
for (const NKikimrSchemeOp::TPathDescription& entry : entries) {
- if (cnt > 0) {
+ if (cnt > 0) {
Cout << TString((cnt - 1) * 3, ' ');
- Cout << "└─ ";
- }
- PrintEntry(entry);
- ++cnt;
- }
- return 0;
- }
-};
-
-class TClientCommandSchemaLs : public TClientCommand {
-public:
- TClientCommandSchemaLs()
+ Cout << "└─ ";
+ }
+ PrintEntry(entry);
+ ++cnt;
+ }
+ return 0;
+ }
+};
+
+class TClientCommandSchemaLs : public TClientCommand {
+public:
+ TClientCommandSchemaLs()
: TClientCommand("ls", {}, "List schema object or path content")
- {}
-
+ {}
+
TAutoPtr<NKikimrClient::TSchemeDescribe> Request;
-
- virtual void Config(TConfig& config) override {
- TClientCommand::Config(config);
+
+ virtual void Config(TConfig& config) override {
+ TClientCommand::Config(config);
config.SetFreeArgsNum(1);
SetFreeArgTitle(0, "<PATH>", "Schema path");
- }
-
- virtual void Parse(TConfig& config) override {
- TClientCommand::Parse(config);
+ }
+
+ virtual void Parse(TConfig& config) override {
+ TClientCommand::Parse(config);
Request = new NKikimrClient::TSchemeDescribe();
- Request->SetPath(config.ParseResult->GetFreeArgs()[0]);
- }
-
- virtual int Run(TConfig& config) override {
+ Request->SetPath(config.ParseResult->GetFreeArgs()[0]);
+ }
+
+ virtual int Run(TConfig& config) override {
TAutoPtr<NMsgBusProxy::TBusSchemeDescribe> request(new NMsgBusProxy::TBusSchemeDescribe());
- if (Request != nullptr)
- request->Record.MergeFrom(*Request);
-
+ if (Request != nullptr)
+ request->Record.MergeFrom(*Request);
+
return MessageBusCall<NMsgBusProxy::TBusSchemeDescribe, NMsgBusProxy::TBusResponse>(config, request,
- [this](const NMsgBusProxy::TBusResponse& response) -> int {
- return PrintResponse(response);
- });
- }
-
+ [this](const NMsgBusProxy::TBusResponse& response) -> int {
+ return PrintResponse(response);
+ });
+ }
+
static void PrintEntry(const NKikimrSchemeOp::TDirEntry& entry) {
TString type;
- switch(entry.GetPathType()) {
+ switch(entry.GetPathType()) {
case NKikimrSchemeOp::EPathTypeDir:
- type = "<dir>";
- break;
+ type = "<dir>";
+ break;
case NKikimrSchemeOp::EPathTypeSubDomain:
type = "<database>";
break;
case NKikimrSchemeOp::EPathTypeTable:
- type = "<table>";
- break;
+ type = "<table>";
+ break;
case NKikimrSchemeOp::EPathTypePersQueueGroup:
- type = "<pq group>";
- break;
+ type = "<pq group>";
+ break;
case NKikimrSchemeOp::EPathTypeColumnStore:
type = "<column store>";
break;
@@ -486,17 +486,17 @@ public:
case NKikimrSchemeOp::EPathTypeReplication:
type = "<replication>";
break;
- default:
- type = "<unknown>";
- break;
- }
-
- Cout << entry.GetSchemeshardId() << '/' << entry.GetPathId() << '\t' << type << '\t' << entry.GetName() << Endl;
- }
-
- int PrintResponse(const NMsgBusProxy::TBusResponse& response) const {
+ default:
+ type = "<unknown>";
+ break;
+ }
+
+ Cout << entry.GetSchemeshardId() << '/' << entry.GetPathId() << '\t' << type << '\t' << entry.GetName() << Endl;
+ }
+
+ int PrintResponse(const NMsgBusProxy::TBusResponse& response) const {
const NKikimrClient::TResponse& record(response.Record);
- const auto& description(record.GetPathDescription());
+ const auto& description(record.GetPathDescription());
if (description.GetSelf().GetPathType() == NKikimrSchemeOp::EPathTypeDir
|| description.GetSelf().GetPathType() == NKikimrSchemeOp::EPathTypeSubDomain
|| description.GetSelf().GetPathType() == NKikimrSchemeOp::EPathTypeColumnStore) {
@@ -505,80 +505,80 @@ public:
}
} else {
PrintEntry(description.GetSelf());
- }
- return 0;
- }
-};
-
-class TClientCommandSchemaInit : public TClientCommand {
-public:
- TClientCommandSchemaInit()
- : TClientCommand("init", {}, "Initialize schema root")
- {}
-
+ }
+ return 0;
+ }
+};
+
+class TClientCommandSchemaInit : public TClientCommand {
+public:
+ TClientCommandSchemaInit()
+ : TClientCommand("init", {}, "Initialize schema root")
+ {}
+
TAutoPtr<NKikimrClient::TSchemeInitRoot> Request;
TString Root;
- TString DefaultStoragePool;
-
- virtual void Config(TConfig& config) override {
- TClientCommand::Config(config);
- config.Opts->AddLongOption("pool", "default storage pool").RequiredArgument("NAME").StoreResult(&DefaultStoragePool);
+ TString DefaultStoragePool;
+
+ virtual void Config(TConfig& config) override {
+ TClientCommand::Config(config);
+ config.Opts->AddLongOption("pool", "default storage pool").RequiredArgument("NAME").StoreResult(&DefaultStoragePool);
config.SetFreeArgsNum(1);
SetFreeArgTitle(0, "<ROOT>", "Schema root name");
- }
-
- virtual void Parse(TConfig& config) override {
- TClientCommand::Parse(config);
+ }
+
+ virtual void Parse(TConfig& config) override {
+ TClientCommand::Parse(config);
Request = new NKikimrClient::TSchemeInitRoot();
- Root = config.ParseResult->GetFreeArgs()[0];
+ Root = config.ParseResult->GetFreeArgs()[0];
if (Root.StartsWith('/'))
- Root = Root.substr(1);
- Request->SetTagName(Root);
- if (DefaultStoragePool) {
- auto* storagePool = Request->AddStoragePools();
- storagePool->SetName(DefaultStoragePool);
- TStringBuf kind = TStringBuf(DefaultStoragePool).RAfter(':');
- if (kind) {
- storagePool->SetKind(TString(kind));
- }
- }
- }
-
- virtual int Run(TConfig& config) override {
- TAutoPtr<NMsgBusProxy::TBusSchemeInitRoot> request(new NMsgBusProxy::TBusSchemeInitRoot());
- if (Request != nullptr)
- request->Record.MergeFrom(*Request);
- return MessageBusCall(config, request);
- }
-};
-
-class TClientCommandSchemaChown : public TClientCommand {
-public:
- TClientCommandSchemaChown()
- : TClientCommand("chown", {}, "Change owner")
- {}
-
+ Root = Root.substr(1);
+ Request->SetTagName(Root);
+ if (DefaultStoragePool) {
+ auto* storagePool = Request->AddStoragePools();
+ storagePool->SetName(DefaultStoragePool);
+ TStringBuf kind = TStringBuf(DefaultStoragePool).RAfter(':');
+ if (kind) {
+ storagePool->SetKind(TString(kind));
+ }
+ }
+ }
+
+ virtual int Run(TConfig& config) override {
+ TAutoPtr<NMsgBusProxy::TBusSchemeInitRoot> request(new NMsgBusProxy::TBusSchemeInitRoot());
+ if (Request != nullptr)
+ request->Record.MergeFrom(*Request);
+ return MessageBusCall(config, request);
+ }
+};
+
+class TClientCommandSchemaChown : public TClientCommand {
+public:
+ TClientCommandSchemaChown()
+ : TClientCommand("chown", {}, "Change owner")
+ {}
+
TAutoPtr<NKikimrClient::TSchemeOperation> Request;
-
- bool Recursive = false;
- bool Verbose = false;
-
- virtual void Config(TConfig& config) override {
- TClientCommand::Config(config);
+
+ bool Recursive = false;
+ bool Verbose = false;
+
+ virtual void Config(TConfig& config) override {
+ TClientCommand::Config(config);
config.SetFreeArgsNum(2);
SetFreeArgTitle(0, "<USER>", "User");
SetFreeArgTitle(1, "<PATH>", "Full pathname of an object (e.g. /ru/home/user/mydb/test1/test2).\n"
" Or short pathname if profile path is set (e.g. test1/test2).");
- config.Opts->AddLongOption('R', "recursive", "Change owner on schema objects recursively").NoArgument().SetFlag(&Recursive);
- config.Opts->AddLongOption('v', "verbose", "Verbose output").NoArgument().SetFlag(&Verbose);
- }
-
+ config.Opts->AddLongOption('R', "recursive", "Change owner on schema objects recursively").NoArgument().SetFlag(&Recursive);
+ config.Opts->AddLongOption('v', "verbose", "Verbose output").NoArgument().SetFlag(&Verbose);
+ }
+
TString Owner;
- TString Path;
-
- virtual void Parse(TConfig& config) override {
- TClientCommand::Parse(config);
- Owner = config.ParseResult->GetFreeArgs()[0];
+ TString Path;
+
+ virtual void Parse(TConfig& config) override {
+ TClientCommand::Parse(config);
+ Owner = config.ParseResult->GetFreeArgs()[0];
TString pathname = config.ParseResult->GetFreeArgs()[1];
if (config.Path) {
// Profile path is set
@@ -590,90 +590,90 @@ public:
}
}
Path = pathname;
- }
-
- int Chown(TConfig& config, const TString& path) {
- size_t pos = path.rfind('/');
- TString base = path.substr(0, pos);
- TString name = path.substr(pos + 1);
+ }
+
+ int Chown(TConfig& config, const TString& path) {
+ size_t pos = path.rfind('/');
+ TString base = path.substr(0, pos);
+ TString name = path.substr(pos + 1);
TAutoPtr<NMsgBusProxy::TBusSchemeOperation> request(new NMsgBusProxy::TBusSchemeOperation());
NKikimrClient::TSchemeOperation& record(request->Record);
- auto& modifyScheme = *record.MutableTransaction()->MutableModifyScheme();
+ auto& modifyScheme = *record.MutableTransaction()->MutableModifyScheme();
modifyScheme.SetOperationType(NKikimrSchemeOp::EOperationType::ESchemeOpModifyACL);
- modifyScheme.SetWorkingDir(base);
- auto& modifyAcl = *modifyScheme.MutableModifyACL();
- modifyAcl.SetName(name);
- modifyAcl.SetNewOwner(Owner);
- if (Verbose) {
- Cout << path << Endl;
- }
+ modifyScheme.SetWorkingDir(base);
+ auto& modifyAcl = *modifyScheme.MutableModifyACL();
+ modifyAcl.SetName(name);
+ modifyAcl.SetNewOwner(Owner);
+ if (Verbose) {
+ Cout << path << Endl;
+ }
int result = MessageBusCall<NMsgBusProxy::TBusSchemeOperation, NMsgBusProxy::TBusResponse>(config, request,
- [path](const NMsgBusProxy::TBusResponse& response) -> int {
- if (response.Record.GetStatus() != NMsgBusProxy::MSTATUS_OK) {
- Cerr << path << ' ' << ToCString(static_cast<NMsgBusProxy::EResponseStatus>(response.Record.GetStatus())) << " " << response.Record.GetErrorReason() << Endl;
- return 1;
- }
- return 0;
- });
- return result;
- }
-
- TList<TString> Ls(TConfig& config, const TString& path) {
- TAutoPtr<NMsgBusProxy::TBusSchemeDescribe> request(new NMsgBusProxy::TBusSchemeDescribe());
- NKikimrClient::TSchemeDescribe& record(request->Record);
- record.SetPath(path);
- TList<TString> result;
- MessageBusCall<NMsgBusProxy::TBusSchemeDescribe, NMsgBusProxy::TBusResponse>(config, request,
- [&result, path](const NMsgBusProxy::TBusResponse& response) -> int {
- for (const auto& item : response.Record.GetPathDescription().GetChildren()) {
- result.emplace_back(path + '/' + item.GetName());
- }
- return 0;
- });
- return result;
- }
-
- virtual int Run(TConfig& config) override {
- TList<TString> paths;
- paths.emplace_back(Path);
- while (!paths.empty()) {
- TString path = paths.front();
- int result = Chown(config, path);
- if (result != 0) {
- return result;
- }
- paths.pop_front();
- if (Recursive) {
- TList<TString> children = Ls(config, path);
- paths.insert(paths.begin(), children.begin(), children.end());
- }
- }
- return 0;
- }
-};
-
-class TClientCommandSchemaAccessAdd : public TClientCommand {
-public:
- TClientCommandSchemaAccessAdd()
- : TClientCommand("add", {}, "Add access right")
- {}
-
+ [path](const NMsgBusProxy::TBusResponse& response) -> int {
+ if (response.Record.GetStatus() != NMsgBusProxy::MSTATUS_OK) {
+ Cerr << path << ' ' << ToCString(static_cast<NMsgBusProxy::EResponseStatus>(response.Record.GetStatus())) << " " << response.Record.GetErrorReason() << Endl;
+ return 1;
+ }
+ return 0;
+ });
+ return result;
+ }
+
+ TList<TString> Ls(TConfig& config, const TString& path) {
+ TAutoPtr<NMsgBusProxy::TBusSchemeDescribe> request(new NMsgBusProxy::TBusSchemeDescribe());
+ NKikimrClient::TSchemeDescribe& record(request->Record);
+ record.SetPath(path);
+ TList<TString> result;
+ MessageBusCall<NMsgBusProxy::TBusSchemeDescribe, NMsgBusProxy::TBusResponse>(config, request,
+ [&result, path](const NMsgBusProxy::TBusResponse& response) -> int {
+ for (const auto& item : response.Record.GetPathDescription().GetChildren()) {
+ result.emplace_back(path + '/' + item.GetName());
+ }
+ return 0;
+ });
+ return result;
+ }
+
+ virtual int Run(TConfig& config) override {
+ TList<TString> paths;
+ paths.emplace_back(Path);
+ while (!paths.empty()) {
+ TString path = paths.front();
+ int result = Chown(config, path);
+ if (result != 0) {
+ return result;
+ }
+ paths.pop_front();
+ if (Recursive) {
+ TList<TString> children = Ls(config, path);
+ paths.insert(paths.begin(), children.begin(), children.end());
+ }
+ }
+ return 0;
+ }
+};
+
+class TClientCommandSchemaAccessAdd : public TClientCommand {
+public:
+ TClientCommandSchemaAccessAdd()
+ : TClientCommand("add", {}, "Add access right")
+ {}
+
TAutoPtr<NKikimrClient::TSchemeOperation> Request;
-
- virtual void Config(TConfig& config) override {
- TClientCommand::Config(config);
+
+ virtual void Config(TConfig& config) override {
+ TClientCommand::Config(config);
config.SetFreeArgsNum(2);
SetFreeArgTitle(0, "<PATH>", "Full pathname of an object (e.g. /ru/home/user/mydb/test1/test2).\n"
" Or short pathname if profile path is set (e.g. test1/test2).");
SetFreeArgTitle(1, "<ACCESS>", "ACCESS");
- }
-
+ }
+
TString Access;
TString Base;
TString Name;
-
- virtual void Parse(TConfig& config) override {
- TClientCommand::Parse(config);
+
+ virtual void Parse(TConfig& config) override {
+ TClientCommand::Parse(config);
TString pathname = config.ParseResult->GetFreeArgs()[0];
size_t pos = pathname.rfind('/');
if (config.Path) {
@@ -690,61 +690,61 @@ public:
Base = pathname.substr(0, pos);
Name = pathname.substr(pos + 1);
}
- Access = config.ParseResult->GetFreeArgs()[1];
- }
-
- virtual int Run(TConfig& config) override {
+ Access = config.ParseResult->GetFreeArgs()[1];
+ }
+
+ virtual int Run(TConfig& config) override {
TAutoPtr<NMsgBusProxy::TBusSchemeOperation> request(new NMsgBusProxy::TBusSchemeOperation());
NKikimrClient::TSchemeOperation& record(request->Record);
- auto& modifyScheme = *record.MutableTransaction()->MutableModifyScheme();
+ auto& modifyScheme = *record.MutableTransaction()->MutableModifyScheme();
modifyScheme.SetOperationType(NKikimrSchemeOp::EOperationType::ESchemeOpModifyACL);
- modifyScheme.SetWorkingDir(Base);
- auto& modifyAcl = *modifyScheme.MutableModifyACL();
- modifyAcl.SetName(Name);
- NACLib::TDiffACL diffAcl;
- {
- NACLibProto::TACE ace;
- NACLib::TACL::FromString(ace, Access);
- if (!ace.HasAccessRight() || !ace.HasAccessType()) {
- throw yexception() << "Invalid access right specified";
- }
- diffAcl.AddAccess(ace);
- }
- modifyAcl.SetDiffACL(diffAcl.SerializeAsString());
+ modifyScheme.SetWorkingDir(Base);
+ auto& modifyAcl = *modifyScheme.MutableModifyACL();
+ modifyAcl.SetName(Name);
+ NACLib::TDiffACL diffAcl;
+ {
+ NACLibProto::TACE ace;
+ NACLib::TACL::FromString(ace, Access);
+ if (!ace.HasAccessRight() || !ace.HasAccessType()) {
+ throw yexception() << "Invalid access right specified";
+ }
+ diffAcl.AddAccess(ace);
+ }
+ modifyAcl.SetDiffACL(diffAcl.SerializeAsString());
int result = MessageBusCall<NMsgBusProxy::TBusSchemeOperation, NMsgBusProxy::TBusResponse>(config, request,
[](const NMsgBusProxy::TBusResponse& response) -> int {
- if (response.Record.GetStatus() != NMsgBusProxy::MSTATUS_OK) {
- Cerr << ToCString(static_cast<NMsgBusProxy::EResponseStatus>(response.Record.GetStatus())) << " " << response.Record.GetErrorReason() << Endl;
- return 1;
- }
- return 0;
- });
- return result;
- }
-};
-
-class TClientCommandSchemaAccessRemove : public TClientCommand {
-public:
- TClientCommandSchemaAccessRemove()
- : TClientCommand("remove", {}, "Remove access right")
- {}
-
+ if (response.Record.GetStatus() != NMsgBusProxy::MSTATUS_OK) {
+ Cerr << ToCString(static_cast<NMsgBusProxy::EResponseStatus>(response.Record.GetStatus())) << " " << response.Record.GetErrorReason() << Endl;
+ return 1;
+ }
+ return 0;
+ });
+ return result;
+ }
+};
+
+class TClientCommandSchemaAccessRemove : public TClientCommand {
+public:
+ TClientCommandSchemaAccessRemove()
+ : TClientCommand("remove", {}, "Remove access right")
+ {}
+
TAutoPtr<NKikimrClient::TSchemeOperation> Request;
-
- virtual void Config(TConfig& config) override {
- TClientCommand::Config(config);
+
+ virtual void Config(TConfig& config) override {
+ TClientCommand::Config(config);
config.SetFreeArgsNum(2);
SetFreeArgTitle(0, "<PATH>", "Full pathname of an object (e.g. /ru/home/user/mydb/test1/test2).\n"
" Or short pathname if profile path is set (e.g. test1/test2).");
SetFreeArgTitle(1, "<ACCESS>", "ACCESS");
- }
-
+ }
+
TString Access;
TString Base;
TString Name;
-
- virtual void Parse(TConfig& config) override {
- TClientCommand::Parse(config);
+
+ virtual void Parse(TConfig& config) override {
+ TClientCommand::Parse(config);
TString pathname = config.ParseResult->GetFreeArgs()[0];
size_t pos = pathname.rfind('/');
if (config.Path) {
@@ -761,48 +761,48 @@ public:
Base = pathname.substr(0, pos);
Name = pathname.substr(pos + 1);
}
- Access = config.ParseResult->GetFreeArgs()[1];
- }
-
- virtual int Run(TConfig& config) override {
+ Access = config.ParseResult->GetFreeArgs()[1];
+ }
+
+ virtual int Run(TConfig& config) override {
TAutoPtr<NMsgBusProxy::TBusSchemeOperation> request(new NMsgBusProxy::TBusSchemeOperation());
NKikimrClient::TSchemeOperation& record(request->Record);
- auto& modifyScheme = *record.MutableTransaction()->MutableModifyScheme();
+ auto& modifyScheme = *record.MutableTransaction()->MutableModifyScheme();
modifyScheme.SetOperationType(NKikimrSchemeOp::EOperationType::ESchemeOpModifyACL);
- modifyScheme.SetWorkingDir(Base);
- auto& modifyAcl = *modifyScheme.MutableModifyACL();
- modifyAcl.SetName(Name);
- NACLib::TDiffACL diffAcl;
- {
- NACLibProto::TACE ace;
- NACLib::TACL::FromString(ace, Access);
- diffAcl.RemoveAccess(ace);
- }
- modifyAcl.SetDiffACL(diffAcl.SerializeAsString());
+ modifyScheme.SetWorkingDir(Base);
+ auto& modifyAcl = *modifyScheme.MutableModifyACL();
+ modifyAcl.SetName(Name);
+ NACLib::TDiffACL diffAcl;
+ {
+ NACLibProto::TACE ace;
+ NACLib::TACL::FromString(ace, Access);
+ diffAcl.RemoveAccess(ace);
+ }
+ modifyAcl.SetDiffACL(diffAcl.SerializeAsString());
int result = MessageBusCall<NMsgBusProxy::TBusSchemeOperation, NMsgBusProxy::TBusResponse>(config, request,
[](const NMsgBusProxy::TBusResponse& response) -> int {
- if (response.Record.GetStatus() != NMsgBusProxy::MSTATUS_OK) {
- Cerr << ToCString(static_cast<NMsgBusProxy::EResponseStatus>(response.Record.GetStatus())) << " " << response.Record.GetErrorReason() << Endl;
- return 1;
- }
- return 0;
- });
- return result;
- }
-};
-
-class TClientCommandSchemaAccess : public TClientCommandTree {
-public:
- TClientCommandSchemaAccess()
- : TClientCommandTree("access", { "acl" }, "Access operations")
- {
+ if (response.Record.GetStatus() != NMsgBusProxy::MSTATUS_OK) {
+ Cerr << ToCString(static_cast<NMsgBusProxy::EResponseStatus>(response.Record.GetStatus())) << " " << response.Record.GetErrorReason() << Endl;
+ return 1;
+ }
+ return 0;
+ });
+ return result;
+ }
+};
+
+class TClientCommandSchemaAccess : public TClientCommandTree {
+public:
+ TClientCommandSchemaAccess()
+ : TClientCommandTree("access", { "acl" }, "Access operations")
+ {
AddCommand(std::make_unique<TClientCommandSchemaAccessAdd>());
AddCommand(std::make_unique<TClientCommandSchemaAccessRemove>());
//AddCommand(std::make_unique<TClientCommandSchemaAccessGrant>());
//AddCommand(std::make_unique<TClientCommandSchemaAccessRevoke>());
- }
-};
-
+ }
+};
+
class TClientCommandSchemaTableOptions : public TClientCommand {
public:
NGrpc::TGRpcClientConfig ClientConfig;
@@ -1269,7 +1269,7 @@ TClientCommandSchemaLite::TClientCommandSchemaLite()
AddCommand(std::make_unique<TClientCommandSchemaTable>());
AddCommand(std::make_unique<TClientCommandSchemaUserAttribute>());
}
-
+
class TClientCommandSchema : public TClientCommandSchemaLite {
public:
TClientCommandSchema()
@@ -1279,35 +1279,35 @@ public:
};
class TClientCommandDbExec : public TClientCommandConfig {
-public:
- TClientCommandDbExec()
+public:
+ TClientCommandDbExec()
: TClientCommandConfig("minikql", { "execute", "exec", "mkql" }, "Execute Mini-KQL query")
- {}
-
+ {}
+
TString MiniKQL;
TString Params;
bool Proto = false;
-
- virtual void Config(TConfig& config) override {
- TClientCommand::Config(config);
+
+ virtual void Config(TConfig& config) override {
+ TClientCommand::Config(config);
config.SetFreeArgsNum(1, 2);
SetFreeArgTitle(0, "<MINIKQL>", "Text MiniKQL");
SetFreeArgTitle(1, "<PARAMS>", "Text MiniKQL parameters");
config.Opts->AddLongOption('p', "proto", "MiniKQL parameters are in protobuf format").NoArgument().SetFlag(&Proto);
- }
-
- virtual void Parse(TConfig& config) override {
- TClientCommand::Parse(config);
- MiniKQL = GetMiniKQL(config.ParseResult->GetFreeArgs()[0]);
- if (config.ParseResult->GetFreeArgsPos() > 1) {
+ }
+
+ virtual void Parse(TConfig& config) override {
+ TClientCommand::Parse(config);
+ MiniKQL = GetMiniKQL(config.ParseResult->GetFreeArgs()[0]);
+ if (config.ParseResult->GetFreeArgsPos() > 1) {
auto paramsArg = config.ParseResult->GetFreeArgs()[1];
Params = Proto
? TUnbufferedFileInput(paramsArg).ReadAll()
: GetMiniKQL(paramsArg);
- }
- }
-
- virtual int Run(TConfig& config) override {
+ }
+ }
+
+ virtual int Run(TConfig& config) override {
auto handler = [this](NClient::TKikimr& kikimr) {
NClient::TTextQuery query(kikimr.Query(MiniKQL));
@@ -1326,9 +1326,9 @@ public:
});
};
return InvokeThroughKikimr(config, std::move(handler));
- }
-};
-
+ }
+};
+
class TClientCommandS3Listing: public TClientCommand {
public:
@@ -1448,13 +1448,13 @@ public:
TString Columns;
};
-TClientCommandDb::TClientCommandDb()
- : TClientCommandTree("db", {}, "KiKiMR DB operations")
-{
+TClientCommandDb::TClientCommandDb()
+ : TClientCommandTree("db", {}, "KiKiMR DB operations")
+{
AddCommand(std::make_unique<TClientCommandSchema>());
AddCommand(std::make_unique<TClientCommandDbExec>());
AddCommand(std::make_unique<TClientCommandS3Listing>());
-}
-
-}
-}
+}
+
+}
+}
diff --git a/ydb/core/driver_lib/cli_base/cli_cmds_whoami.cpp b/ydb/core/driver_lib/cli_base/cli_cmds_whoami.cpp
index 023a9aa71c7..eab2c8e58cf 100644
--- a/ydb/core/driver_lib/cli_base/cli_cmds_whoami.cpp
+++ b/ydb/core/driver_lib/cli_base/cli_cmds_whoami.cpp
@@ -1,40 +1,40 @@
-#include "cli.h"
-#include "cli_cmds.h"
-
-namespace NKikimr {
-namespace NDriverClient {
-
-TClientCommandWhoAmI::TClientCommandWhoAmI()
- : TClientCommand("whoami", {}, "Who am I?")
-{}
-
-void TClientCommandWhoAmI::Config(TConfig& config) {
- TClientCommand::Config(config);
- config.Opts->AddLongOption('g', "groups", "With groups").NoArgument().SetFlag(&WithGroups);
-}
-
-int TClientCommandWhoAmI::Run(TConfig& config) {
- TAutoPtr<NMsgBusProxy::TBusWhoAmI> request(new NMsgBusProxy::TBusWhoAmI());
- request->Record.SetReturnGroups(WithGroups);
- return MessageBusCall<NMsgBusProxy::TBusWhoAmI, NMsgBusProxy::TBusResponse>(config, request,
- [this](const NMsgBusProxy::TBusResponse& response) -> int {
- return PrintResponse(response);
- });
-}
-
-int TClientCommandWhoAmI::PrintResponse(const NMsgBusProxy::TBusResponse& response) const {
- const NKikimrClient::TResponse& record(response.Record);
- if (!record.GetUserName().empty()) {
- Cout << record.GetUserName() << Endl;
- if (record.GroupsSize() > 0) {
- Cout << TString(30, '-') << Endl;
- for (const TString& group : record.GetGroups()) {
- Cout << group << Endl;
- }
- }
- }
- return 0;
-}
-
-}
-}
+#include "cli.h"
+#include "cli_cmds.h"
+
+namespace NKikimr {
+namespace NDriverClient {
+
+TClientCommandWhoAmI::TClientCommandWhoAmI()
+ : TClientCommand("whoami", {}, "Who am I?")
+{}
+
+void TClientCommandWhoAmI::Config(TConfig& config) {
+ TClientCommand::Config(config);
+ config.Opts->AddLongOption('g', "groups", "With groups").NoArgument().SetFlag(&WithGroups);
+}
+
+int TClientCommandWhoAmI::Run(TConfig& config) {
+ TAutoPtr<NMsgBusProxy::TBusWhoAmI> request(new NMsgBusProxy::TBusWhoAmI());
+ request->Record.SetReturnGroups(WithGroups);
+ return MessageBusCall<NMsgBusProxy::TBusWhoAmI, NMsgBusProxy::TBusResponse>(config, request,
+ [this](const NMsgBusProxy::TBusResponse& response) -> int {
+ return PrintResponse(response);
+ });
+}
+
+int TClientCommandWhoAmI::PrintResponse(const NMsgBusProxy::TBusResponse& response) const {
+ const NKikimrClient::TResponse& record(response.Record);
+ if (!record.GetUserName().empty()) {
+ Cout << record.GetUserName() << Endl;
+ if (record.GroupsSize() > 0) {
+ Cout << TString(30, '-') << Endl;
+ for (const TString& group : record.GetGroups()) {
+ Cout << group << Endl;
+ }
+ }
+ }
+ return 0;
+}
+
+}
+}
diff --git a/ydb/core/driver_lib/cli_base/cli_kicli.cpp b/ydb/core/driver_lib/cli_base/cli_kicli.cpp
index ceab301ba3d..5ba51e77a64 100644
--- a/ydb/core/driver_lib/cli_base/cli_kicli.cpp
+++ b/ydb/core/driver_lib/cli_base/cli_kicli.cpp
@@ -59,11 +59,11 @@ void PrepareRequest(TClientCommand::TConfig& config, TAutoPtr<NMsgBusProxy::TBus
}
template <>
-int OnMessageBus(const TClientCommand::TConfig& config, const NMsgBusProxy::TBusResponse& response) {
+int OnMessageBus(const TClientCommand::TConfig& config, const NMsgBusProxy::TBusResponse& response) {
const NKikimrClient::TResponse& resp(response.Record);
if (resp.HasExecutionEngineEvaluatedResponse()) {
NClient::TValue value = NClient::TValue::Create(resp.GetExecutionEngineEvaluatedResponse().GetValue(), resp.GetExecutionEngineEvaluatedResponse().GetType());
- Cout << value.GetValueText<NClient::TFormatJSON>({config.JsonUi64AsText, config.JsonBinaryAsBase64});
+ Cout << value.GetValueText<NClient::TFormatJSON>({config.JsonUi64AsText, config.JsonBinaryAsBase64});
}
return 0;
}
diff --git a/ydb/core/driver_lib/cli_base/cli_kicli.h b/ydb/core/driver_lib/cli_base/cli_kicli.h
index 2120aceefb3..a93e2717fb7 100644
--- a/ydb/core/driver_lib/cli_base/cli_kicli.h
+++ b/ydb/core/driver_lib/cli_base/cli_kicli.h
@@ -62,7 +62,7 @@ void PrepareRequest(TClientCommand::TConfig& config, TAutoPtr<NMsgBusProxy::TBus
void PrepareRequest(TClientCommand::TConfig& config, TAutoPtr<NMsgBusProxy::TBusDrainNode>& request);
template <typename ResponseType>
-int OnMessageBus(const TClientCommand::TConfig& config, const ResponseType& response);
+int OnMessageBus(const TClientCommand::TConfig& config, const ResponseType& response);
template <typename RequestType, typename ResponseType>
int MessageBusCall(TClientCommand::TConfig& config, TAutoPtr<RequestType> request, std::function<int(const ResponseType&)> callback) {
@@ -82,8 +82,8 @@ int MessageBusCall(TClientCommand::TConfig& config, TAutoPtr<RequestType> reques
template <typename RequestType, typename ResponseType = NMsgBusProxy::TBusResponse>
int MessageBusCall(TClientCommand::TConfig& config, TAutoPtr<RequestType> request) {
- return MessageBusCall<RequestType, ResponseType>(config, request, [&config](const ResponseType& response) -> int {
- return OnMessageBus(config, response);
+ return MessageBusCall<RequestType, ResponseType>(config, request, [&config](const ResponseType& response) -> int {
+ return OnMessageBus(config, response);
});
}
diff --git a/ydb/core/driver_lib/cli_config_base/config_base.cpp b/ydb/core/driver_lib/cli_config_base/config_base.cpp
index 1c8cb581f57..3672ce3ec2f 100644
--- a/ydb/core/driver_lib/cli_config_base/config_base.cpp
+++ b/ydb/core/driver_lib/cli_config_base/config_base.cpp
@@ -9,38 +9,38 @@ TDuration ParseDuration(const TStringBuf& str) {
if (TDuration::TryParse(str, result))
return result;
ythrow yexception() << "wrong TDuration format";
-}
+}
-TCommandConfig::TServerEndpoint TCommandConfig::ParseServerAddress(const TString& address) {
- TServerEndpoint endpoint = {EServerType::GRpc, address};
- if (address.empty()) {
- endpoint.Address = "localhost";
- }
- TString hostname;
- ui32 port = 0;
- if (address.StartsWith("grpc://")) {
- endpoint.ServerType = EServerType::GRpc;
- endpoint.Address = endpoint.Address.substr(7);
- port = 2135;
+TCommandConfig::TServerEndpoint TCommandConfig::ParseServerAddress(const TString& address) {
+ TServerEndpoint endpoint = {EServerType::GRpc, address};
+ if (address.empty()) {
+ endpoint.Address = "localhost";
+ }
+ TString hostname;
+ ui32 port = 0;
+ if (address.StartsWith("grpc://")) {
+ endpoint.ServerType = EServerType::GRpc;
+ endpoint.Address = endpoint.Address.substr(7);
+ port = 2135;
endpoint.EnableSsl = false;
} else if (address.StartsWith("grpcs://")) {
endpoint.ServerType = EServerType::GRpc;
endpoint.Address = endpoint.Address.substr(8);
port = 2135;
endpoint.EnableSsl = true;
- } else if (address.StartsWith("mbus://")) {
- endpoint.ServerType = EServerType::MessageBus;
- endpoint.Address = endpoint.Address.substr(7);
- port = 2134;
- } else {
- endpoint.ServerType = EServerType::GRpc; // default;
- port = 2135;
- }
- NMsgBusProxy::TMsgBusClientConfig::CrackAddress(endpoint.Address, hostname, port);
- endpoint.Address = hostname + ':' + ToString(port);
- return endpoint;
-}
-
+ } else if (address.StartsWith("mbus://")) {
+ endpoint.ServerType = EServerType::MessageBus;
+ endpoint.Address = endpoint.Address.substr(7);
+ port = 2134;
+ } else {
+ endpoint.ServerType = EServerType::GRpc; // default;
+ port = 2135;
+ }
+ NMsgBusProxy::TMsgBusClientConfig::CrackAddress(endpoint.Address, hostname, port);
+ endpoint.Address = hostname + ':' + ToString(port);
+ return endpoint;
+}
+
const TString ArgFormatDescription() {
return R"___(
Common option formats:
diff --git a/ydb/core/driver_lib/cli_config_base/config_base.h b/ydb/core/driver_lib/cli_config_base/config_base.h
index 20b3ad071e2..6db66dc7d1b 100644
--- a/ydb/core/driver_lib/cli_config_base/config_base.h
+++ b/ydb/core/driver_lib/cli_config_base/config_base.h
@@ -36,18 +36,18 @@ const TString ArgFormatDescription();
struct TCommandConfig {
TMaybe<std::variant<NMsgBusProxy::TMsgBusClientConfig, NGRpcProxy::TGRpcClientConfig>> ClientConfig;
- enum class EServerType {
- MessageBus,
- GRpc,
- };
-
- struct TServerEndpoint {
- EServerType ServerType;
- TString Address;
+ enum class EServerType {
+ MessageBus,
+ GRpc,
+ };
+
+ struct TServerEndpoint {
+ EServerType ServerType;
+ TString Address;
TMaybe<bool> EnableSsl = Nothing();
- };
-
- static TServerEndpoint ParseServerAddress(const TString& address);
+ };
+
+ static TServerEndpoint ParseServerAddress(const TString& address);
};
extern TCommandConfig CommandConfig;
diff --git a/ydb/core/driver_lib/cli_utils/cli.h b/ydb/core/driver_lib/cli_utils/cli.h
index 3d171cd4d41..099664792ea 100644
--- a/ydb/core/driver_lib/cli_utils/cli.h
+++ b/ydb/core/driver_lib/cli_utils/cli.h
@@ -30,7 +30,7 @@ namespace NDriverClient {
int BSAdmCreateVSlots(TCommandConfig &cmdConf, int argc, char **argv);
int BSAdmCreateGroup(TCommandConfig &cmdConf, int argc, char **argv);
int CompileAndExecMiniKQL(TCommandConfig &cmdConf, int argc, char **argv);
- int MessageBusTrace(TCommandConfig &cmdConf, int argc, char** argv);
+ int MessageBusTrace(TCommandConfig &cmdConf, int argc, char** argv);
int KeyValueRequest(TCommandConfig &cmdConf, int argc, char **argv);
int PersQueueRequest(TCommandConfig &cmdConf, int argc, char **argv);
int PersQueueStress(TCommandConfig &cmdConf, int argc, char **argv);
diff --git a/ydb/core/driver_lib/cli_utils/cli_cmd_config.cpp b/ydb/core/driver_lib/cli_utils/cli_cmd_config.cpp
index 31e7570e2ed..fcc93059966 100644
--- a/ydb/core/driver_lib/cli_utils/cli_cmd_config.cpp
+++ b/ydb/core/driver_lib/cli_utils/cli_cmd_config.cpp
@@ -18,27 +18,27 @@ namespace NDriverClient {
}
void TCliCmdConfig::ConfigureMsgBusLastGetopt(const NLastGetopt::TOptsParseResult& res, int argc, char** argv) {
- if (Address.empty()) {
+ if (Address.empty()) {
TString kikimrServer = GetEnv("KIKIMR_SERVER");
- if (kikimrServer != nullptr) {
- Address = kikimrServer;
- }
- }
- TCommandConfig::TServerEndpoint endpoint = TCommandConfig::ParseServerAddress(Address);
- switch (endpoint.ServerType) {
- case TCommandConfig::EServerType::GRpc:
+ if (kikimrServer != nullptr) {
+ Address = kikimrServer;
+ }
+ }
+ TCommandConfig::TServerEndpoint endpoint = TCommandConfig::ParseServerAddress(Address);
+ switch (endpoint.ServerType) {
+ case TCommandConfig::EServerType::GRpc:
ClientConfig = NGrpc::TGRpcClientConfig(endpoint.Address);
if (endpoint.EnableSsl.Defined()) {
auto *p = std::get_if<NGrpc::TGRpcClientConfig>(&ClientConfig.GetRef());
p->EnableSsl = endpoint.EnableSsl.GetRef();
}
- break;
- case TCommandConfig::EServerType::MessageBus:
- if (!endpoint.Address.empty()) {
- NMsgBusProxy::TMsgBusClientConfig::CrackAddress(
- endpoint.Address,
- MsgBusClientConfig.Ip,
- MsgBusClientConfig.Port);
+ break;
+ case TCommandConfig::EServerType::MessageBus:
+ if (!endpoint.Address.empty()) {
+ NMsgBusProxy::TMsgBusClientConfig::CrackAddress(
+ endpoint.Address,
+ MsgBusClientConfig.Ip,
+ MsgBusClientConfig.Port);
}
SetMsgBusDefaults(MsgBusClientConfig.BusSessionConfig, MsgBusClientConfig.BusQueueConfig);
if ((res.GetFreeArgCount() > 0) && (res.GetFreeArgs().at(0) == "mbus")) {
@@ -53,7 +53,7 @@ namespace NDriverClient {
}
ClientConfig = MsgBusClientConfig;
- break;
+ break;
}
}
diff --git a/ydb/core/driver_lib/cli_utils/cli_cmds.h b/ydb/core/driver_lib/cli_utils/cli_cmds.h
index bf4ea8dce31..b25db5a7be7 100644
--- a/ydb/core/driver_lib/cli_utils/cli_cmds.h
+++ b/ydb/core/driver_lib/cli_utils/cli_cmds.h
@@ -1,36 +1,36 @@
-#pragma once
-
-#include "cli.h"
+#pragma once
+
+#include "cli.h"
#include <ydb/core/driver_lib/cli_base/cli_cmds.h>
-
-namespace NKikimr {
-namespace NDriverClient {
-
-class TClientCommandAdmin : public TClientCommandTree {
-public:
- TClientCommandAdmin();
-};
-
-class TClientCommandBlobStorage : public TClientCommandTree {
-public:
- TClientCommandBlobStorage();
-};
-
-class TClientCommandDebug : public TClientCommandTree {
-public:
- TClientCommandDebug();
-};
-
-class TClientCommandTablet : public TClientCommandTree {
-public:
- TClientCommandTablet();
-};
-
-class TClientCommandNode : public TClientCommandTree {
-public:
- TClientCommandNode();
-};
-
+
+namespace NKikimr {
+namespace NDriverClient {
+
+class TClientCommandAdmin : public TClientCommandTree {
+public:
+ TClientCommandAdmin();
+};
+
+class TClientCommandBlobStorage : public TClientCommandTree {
+public:
+ TClientCommandBlobStorage();
+};
+
+class TClientCommandDebug : public TClientCommandTree {
+public:
+ TClientCommandDebug();
+};
+
+class TClientCommandTablet : public TClientCommandTree {
+public:
+ TClientCommandTablet();
+};
+
+class TClientCommandNode : public TClientCommandTree {
+public:
+ TClientCommandNode();
+};
+
class TClientCommandTenant : public TClientCommandTree {
public:
TClientCommandTenant();
@@ -46,5 +46,5 @@ public:
TClientCommandCms();
};
-}
-}
+}
+}
diff --git a/ydb/core/driver_lib/cli_utils/cli_cmds_admin.cpp b/ydb/core/driver_lib/cli_utils/cli_cmds_admin.cpp
index 1b2997d6e44..49935a5e980 100644
--- a/ydb/core/driver_lib/cli_utils/cli_cmds_admin.cpp
+++ b/ydb/core/driver_lib/cli_utils/cli_cmds_admin.cpp
@@ -1,19 +1,19 @@
-#include "cli.h"
-#include "cli_cmds.h"
-
-namespace NKikimr {
-namespace NDriverClient {
-
-TClientCommandAdmin::TClientCommandAdmin()
- : TClientCommandTree("admin", {}, "KiKiMR management and administration")
-{
+#include "cli.h"
+#include "cli_cmds.h"
+
+namespace NKikimr {
+namespace NDriverClient {
+
+TClientCommandAdmin::TClientCommandAdmin()
+ : TClientCommandTree("admin", {}, "KiKiMR management and administration")
+{
AddCommand(std::make_unique<TClientCommandTablet>());
AddCommand(std::make_unique<TClientCommandNode>());
AddCommand(std::make_unique<TClientCommandDebug>());
AddCommand(std::make_unique<TClientCommandBlobStorage>());
AddCommand(std::make_unique<TClientCommandTenant>());
AddCommand(std::make_unique<TClientCommandConsole>());
-}
-
-}
-}
+}
+
+}
+}
diff --git a/ydb/core/driver_lib/cli_utils/cli_cmds_bs.cpp b/ydb/core/driver_lib/cli_utils/cli_cmds_bs.cpp
index 8380842e2ae..ef731708bf8 100644
--- a/ydb/core/driver_lib/cli_utils/cli_cmds_bs.cpp
+++ b/ydb/core/driver_lib/cli_utils/cli_cmds_bs.cpp
@@ -1,24 +1,24 @@
-#include "cli.h"
-#include "cli_cmds.h"
-
-namespace NKikimr {
-namespace NDriverClient {
-
+#include "cli.h"
+#include "cli_cmds.h"
+
+namespace NKikimr {
+namespace NDriverClient {
+
std::unique_ptr<TClientCommand> CreateClientCommandDisk();
std::unique_ptr<TClientCommand> CreateClientCommandGroup();
std::unique_ptr<TClientCommand> CreateClientCommandGenConfig();
std::unique_ptr<TClientCommand> CreateClientCommandGet();
std::unique_ptr<TClientCommand> CreateClientCommandBsConfig();
-
-TClientCommandBlobStorage::TClientCommandBlobStorage()
- : TClientCommandTree("blobstorage", { "bs" }, "Blob Storage management")
-{
- AddCommand(CreateClientCommandDisk());
- AddCommand(CreateClientCommandGroup());
+
+TClientCommandBlobStorage::TClientCommandBlobStorage()
+ : TClientCommandTree("blobstorage", { "bs" }, "Blob Storage management")
+{
+ AddCommand(CreateClientCommandDisk());
+ AddCommand(CreateClientCommandGroup());
AddCommand(CreateClientCommandGenConfig());
AddCommand(CreateClientCommandGet());
AddCommand(CreateClientCommandBsConfig());
-}
-
-}
-}
+}
+
+}
+}
diff --git a/ydb/core/driver_lib/cli_utils/cli_cmds_debug.cpp b/ydb/core/driver_lib/cli_utils/cli_cmds_debug.cpp
index a089842b229..9cd9e582fa8 100644
--- a/ydb/core/driver_lib/cli_utils/cli_cmds_debug.cpp
+++ b/ydb/core/driver_lib/cli_utils/cli_cmds_debug.cpp
@@ -1,10 +1,10 @@
-#include "cli.h"
-#include "cli_cmds.h"
+#include "cli.h"
+#include "cli_cmds.h"
#include <util/string/split.h>
-
-namespace NKikimr {
-namespace NDriverClient {
-
+
+namespace NKikimr {
+namespace NDriverClient {
+
class TInterconnectLoad : public TClientCommand {
TString Name;
ui32 Channel = 0;
@@ -289,11 +289,11 @@ public:
}
};
-TClientCommandDebug::TClientCommandDebug()
- : TClientCommandTree("debug")
+TClientCommandDebug::TClientCommandDebug()
+ : TClientCommandTree("debug")
{
AddCommand(std::make_unique<TInterconnect>());
}
-
-}
-}
+
+}
+}
diff --git a/ydb/core/driver_lib/cli_utils/cli_cmds_disk.cpp b/ydb/core/driver_lib/cli_utils/cli_cmds_disk.cpp
index 61b770082be..a9be370d37f 100644
--- a/ydb/core/driver_lib/cli_utils/cli_cmds_disk.cpp
+++ b/ydb/core/driver_lib/cli_utils/cli_cmds_disk.cpp
@@ -1,25 +1,25 @@
#include <ydb/core/blobstorage/pdisk/blobstorage_pdisk_tools.h>
-#include <util/random/entropy.h>
-#include "cli.h"
-#include "cli_cmds.h"
-
-namespace NKikimr {
-namespace NDriverClient {
-
-class TClientCommandDiskInfo : public TClientCommand {
-public:
- TClientCommandDiskInfo()
- : TClientCommand("info", {}, "Get info about disk")
- {}
-
- bool IsVerbose;
+#include <util/random/entropy.h>
+#include "cli.h"
+#include "cli_cmds.h"
+
+namespace NKikimr {
+namespace NDriverClient {
+
+class TClientCommandDiskInfo : public TClientCommand {
+public:
+ TClientCommandDiskInfo()
+ : TClientCommand("info", {}, "Get info about disk")
+ {}
+
+ bool IsVerbose;
bool LockDevice;
ui64 MainKey;
TString Path;
-
- virtual void Config(TConfig& config) override {
- TClientCommand::Config(config);
- IsVerbose = false;
+
+ virtual void Config(TConfig& config) override {
+ TClientCommand::Config(config);
+ IsVerbose = false;
LockDevice = false;
MainKey = 0;
config.SetFreeArgsNum(1);
@@ -28,112 +28,112 @@ public:
.Optional().StoreResult(&MainKey); // TODO: make required
config.Opts->AddLongOption("master-key", "obsolete: use main-key").RequiredArgument("NUM")
.Optional().StoreResult(&MainKey); // TODO: remove after migration
- config.Opts->AddLongOption('v', "verbose", "output detailed information for debugging").Optional().NoArgument()
- .SetFlag(&IsVerbose);
+ config.Opts->AddLongOption('v', "verbose", "output detailed information for debugging").Optional().NoArgument()
+ .SetFlag(&IsVerbose);
config.Opts->AddLongOption('l', "lock", "lock device before reading disk info").Optional().NoArgument()
.SetFlag(&LockDevice);
- }
-
- virtual void Parse(TConfig& config) override {
- TClientCommand::Parse(config);
- Path = config.ParseResult->GetFreeArgs()[0];
+ }
+
+ virtual void Parse(TConfig& config) override {
+ TClientCommand::Parse(config);
+ Path = config.ParseResult->GetFreeArgs()[0];
// TODO: remove after master->main key migration
bool hasMainOption = config.ParseResult->FindLongOptParseResult("main-key");
bool hasMasterOption = config.ParseResult->FindLongOptParseResult("master-key");
bool hasKOption = config.ParseResult->FindCharOptParseResult('k');
if (!hasMainOption && !hasMasterOption && !hasKOption)
ythrow yexception() << "missing main-key param";
- }
-
- virtual int Run(TConfig&) override {
- TPDiskInfo info;
+ }
+
+ virtual int Run(TConfig&) override {
+ TPDiskInfo info;
bool isOk = ReadPDiskFormatInfo(Path, MainKey, info, LockDevice);
- if (isOk) {
- Cout << "Version: " << info.Version << Endl;
- Cout << "DiskSize: " << info.DiskSize << Endl;
- Cout << "SectorSizeBytes: " << info.SectorSizeBytes << Endl;
- Cout << "UserAccessibleChunkSizeBytes: " << info.UserAccessibleChunkSizeBytes << Endl;
- Cout << "RawChunkSizeBytes: " << info.RawChunkSizeBytes << Endl;
- Cout << "Guid: " << info.DiskGuid << Endl;
+ if (isOk) {
+ Cout << "Version: " << info.Version << Endl;
+ Cout << "DiskSize: " << info.DiskSize << Endl;
+ Cout << "SectorSizeBytes: " << info.SectorSizeBytes << Endl;
+ Cout << "UserAccessibleChunkSizeBytes: " << info.UserAccessibleChunkSizeBytes << Endl;
+ Cout << "RawChunkSizeBytes: " << info.RawChunkSizeBytes << Endl;
+ Cout << "Guid: " << info.DiskGuid << Endl;
Cout << "Timestamp: " << info.Timestamp.ToString() << Endl;
Cout << "FormatFlags: " << info.FormatFlags << Endl;
- Cout << "TextMessage: " << info.TextMessage << Endl;
- if (IsVerbose) {
- Cout << Endl;
- Cout << "SysLogSectorCount: " << info.SysLogSectorCount << Endl;
- Cout << "SystemChunkCount: " << info.SystemChunkCount << Endl;
- Cout << Endl;
- Cout << "sysLogSectorInfo: " << Endl;
- ui32 sectors = info.SectorInfo.size();
- ui32 lines = (sectors + 5) / 6;
- ui32 nonceReversalCount = 0;
- for (ui32 line = 0; line < lines; ++line) {
- for (ui32 column = 0; column < 6; ++column) {
- ui32 idx = line + column * lines;
- if (idx < sectors) {
- bool isSeq = (info.SectorInfo[idx].Nonce >= info.SectorInfo[(sectors + idx - 1) % sectors].Nonce);
- if (!isSeq) {
- nonceReversalCount++;
- }
- Cout << Sprintf("[%03" PRIu32 "v%" PRIu64 " n%010" PRIu64 "%s%s]", idx,
- info.SectorInfo[idx].Version, info.SectorInfo[idx].Nonce,
- (isSeq ? " " : "N-"),
- (info.SectorInfo[idx].IsCrcOk ? " " : "C-"));
- }
- }
- Cout << Endl;
- }
- Cout << Endl;
- Cout << "nonceReversalCount: " << nonceReversalCount << Endl;
- }
- return 0;
- } else {
+ Cout << "TextMessage: " << info.TextMessage << Endl;
+ if (IsVerbose) {
+ Cout << Endl;
+ Cout << "SysLogSectorCount: " << info.SysLogSectorCount << Endl;
+ Cout << "SystemChunkCount: " << info.SystemChunkCount << Endl;
+ Cout << Endl;
+ Cout << "sysLogSectorInfo: " << Endl;
+ ui32 sectors = info.SectorInfo.size();
+ ui32 lines = (sectors + 5) / 6;
+ ui32 nonceReversalCount = 0;
+ for (ui32 line = 0; line < lines; ++line) {
+ for (ui32 column = 0; column < 6; ++column) {
+ ui32 idx = line + column * lines;
+ if (idx < sectors) {
+ bool isSeq = (info.SectorInfo[idx].Nonce >= info.SectorInfo[(sectors + idx - 1) % sectors].Nonce);
+ if (!isSeq) {
+ nonceReversalCount++;
+ }
+ Cout << Sprintf("[%03" PRIu32 "v%" PRIu64 " n%010" PRIu64 "%s%s]", idx,
+ info.SectorInfo[idx].Version, info.SectorInfo[idx].Nonce,
+ (isSeq ? " " : "N-"),
+ (info.SectorInfo[idx].IsCrcOk ? " " : "C-"));
+ }
+ }
+ Cout << Endl;
+ }
+ Cout << Endl;
+ Cout << "nonceReversalCount: " << nonceReversalCount << Endl;
+ }
+ return 0;
+ } else {
Cerr << "Could not read disk format info"
<< " Path = " << Path
<< " ErrorReason = " << info.ErrorReason
<< Endl;
- return 1;
- }
- }
-};
-
-class TClientCommandDiskFormat : public TClientCommand {
-public:
- TClientCommandDiskFormat()
- : TClientCommand("format", {}, "Format local disk")
- {}
-
+ return 1;
+ }
+ }
+};
+
+class TClientCommandDiskFormat : public TClientCommand {
+public:
+ TClientCommandDiskFormat()
+ : TClientCommand("format", {}, "Format local disk")
+ {}
+
TString Path;
- NSize::TSize DiskSize;
- NSize::TSize ChunkSize;
- NSize::TSize SectorSize;
- ui64 Guid;
+ NSize::TSize DiskSize;
+ NSize::TSize ChunkSize;
+ NSize::TSize SectorSize;
+ ui64 Guid;
ui64 MainKey;
TString TextMessage;
bool IsErasureEncode;
-
- virtual void Config(TConfig& config) override {
- TClientCommand::Config(config);
+
+ virtual void Config(TConfig& config) override {
+ TClientCommand::Config(config);
MainKey = 0;
- DiskSize = 0;
- ChunkSize = 128 << 20;
- SectorSize = 4 << 10;
- Guid = 0;
+ DiskSize = 0;
+ ChunkSize = 128 << 20;
+ SectorSize = 4 << 10;
+ Guid = 0;
IsErasureEncode = false;
config.SetFreeArgsNum(1);
SetFreeArgTitle(0, "<PATH>", "Disk path");
- config.Opts->AddLongOption('d', "disk-size", "disk size to set (supports K/M/G/T suffixes, 0 to autodetect, default = 0)\n"
- "kikimr needs disk of at least 16 GiB, disk must be large enough to contain at least 100 chunks")
- .OptionalArgument("BYTES").StoreResult(&DiskSize);
- config.Opts->AddLongOption('c', "chunk-size", "chunk size to set (supports K/M/G/T suffixes, default = 128M)\n"
- "kikimr needs chunks of at least 32 MiB, but was designed to work with 128 MiB chunks in mind.\n"
- "It is not recommended to format disks with more than 64000 chunks.")
- .OptionalArgument("BYTES").StoreResult(&ChunkSize);
- config.Opts->AddLongOption('s', "sector-size", "sector size to set (suppords K/M/G/T suffixes, default = 4k)\n"
- "you must specify here the actual sector size of the physical device!")
- .OptionalArgument("BYTES").StoreResult(&SectorSize);
- config.Opts->AddLongOption('g', "guid", "guid to set while formatting").RequiredArgument("NUM").Required()
- .StoreResult(&Guid);
+ config.Opts->AddLongOption('d', "disk-size", "disk size to set (supports K/M/G/T suffixes, 0 to autodetect, default = 0)\n"
+ "kikimr needs disk of at least 16 GiB, disk must be large enough to contain at least 100 chunks")
+ .OptionalArgument("BYTES").StoreResult(&DiskSize);
+ config.Opts->AddLongOption('c', "chunk-size", "chunk size to set (supports K/M/G/T suffixes, default = 128M)\n"
+ "kikimr needs chunks of at least 32 MiB, but was designed to work with 128 MiB chunks in mind.\n"
+ "It is not recommended to format disks with more than 64000 chunks.")
+ .OptionalArgument("BYTES").StoreResult(&ChunkSize);
+ config.Opts->AddLongOption('s', "sector-size", "sector size to set (suppords K/M/G/T suffixes, default = 4k)\n"
+ "you must specify here the actual sector size of the physical device!")
+ .OptionalArgument("BYTES").StoreResult(&SectorSize);
+ config.Opts->AddLongOption('g', "guid", "guid to set while formatting").RequiredArgument("NUM").Required()
+ .StoreResult(&Guid);
config.Opts->AddLongOption('k', "main-key", "encryption main-key to set while formatting.\n"
"Make sure you use the same master key when you format your pdisks and when you run kikimr.")
.RequiredArgument("NUM").Optional().StoreResult(&MainKey);
@@ -143,37 +143,37 @@ public:
.OptionalArgument("STR").Optional().StoreResult(&TextMessage);
config.Opts->AddLongOption('e', "erasure-encode", "erasure-encode data to recover from single-sector failures")
.Optional().NoArgument().SetFlag(&IsErasureEncode);
-
+
config.Opts->SetCmdLineDescr("\n\n"
- "Kikimr was designed to work with large block-devices, like 4 TiB HDDs and 1 TiB SSDs\n"
- "It will work with files, but don't expect good performance.\n"
- "If you still want to run kikimr with a tiny file, specify --disk-size 17179869184 --chunk-size 33554432");
- }
-
- NPDisk::TKey ChunkKey;
- NPDisk::TKey LogKey;
- NPDisk::TKey SysLogKey;
-
- virtual void Parse(TConfig& config) override {
- TClientCommand::Parse(config);
- Path = config.ParseResult->GetFreeArgs()[0];
- EntropyPool().Read(&ChunkKey, sizeof(NKikimr::NPDisk::TKey));
- EntropyPool().Read(&LogKey, sizeof(NKikimr::NPDisk::TKey));
- EntropyPool().Read(&SysLogKey, sizeof(NKikimr::NPDisk::TKey));
+ "Kikimr was designed to work with large block-devices, like 4 TiB HDDs and 1 TiB SSDs\n"
+ "It will work with files, but don't expect good performance.\n"
+ "If you still want to run kikimr with a tiny file, specify --disk-size 17179869184 --chunk-size 33554432");
+ }
+
+ NPDisk::TKey ChunkKey;
+ NPDisk::TKey LogKey;
+ NPDisk::TKey SysLogKey;
+
+ virtual void Parse(TConfig& config) override {
+ TClientCommand::Parse(config);
+ Path = config.ParseResult->GetFreeArgs()[0];
+ EntropyPool().Read(&ChunkKey, sizeof(NKikimr::NPDisk::TKey));
+ EntropyPool().Read(&LogKey, sizeof(NKikimr::NPDisk::TKey));
+ EntropyPool().Read(&SysLogKey, sizeof(NKikimr::NPDisk::TKey));
bool hasMainOption = config.ParseResult->FindLongOptParseResult("main-key");
bool hasMasterOption = config.ParseResult->FindLongOptParseResult("master-key");
bool hasKOption = config.ParseResult->FindCharOptParseResult('k');
if (!hasMainOption && !hasMasterOption && !hasKOption)
ythrow yexception() << "missing main-key param";
- }
-
- virtual int Run(TConfig&) override {
+ }
+
+ virtual int Run(TConfig&) override {
FormatPDisk(Path, DiskSize, SectorSize, ChunkSize, Guid, ChunkKey, LogKey, SysLogKey, MainKey, TextMessage,
IsErasureEncode);
- return 0;
- }
-};
-
+ return 0;
+ }
+};
+
class TClientCommandDiskObliterate : public TClientCommand {
public:
TClientCommandDiskObliterate()
@@ -204,20 +204,20 @@ public:
}
};
-class TClientCommandDisk : public TClientCommandTree {
-public:
- TClientCommandDisk()
- : TClientCommandTree("disk", {}, "Disk management")
- {
+class TClientCommandDisk : public TClientCommandTree {
+public:
+ TClientCommandDisk()
+ : TClientCommandTree("disk", {}, "Disk management")
+ {
AddCommand(std::make_unique<TClientCommandDiskInfo>());
AddCommand(std::make_unique<TClientCommandDiskFormat>());
AddCommand(std::make_unique<TClientCommandDiskObliterate>());
- }
-};
-
+ }
+};
+
std::unique_ptr<TClientCommand> CreateClientCommandDisk() {
return std::make_unique<TClientCommandDisk>();
-}
-
-}
-}
+}
+
+}
+}
diff --git a/ydb/core/driver_lib/cli_utils/cli_cmds_group.cpp b/ydb/core/driver_lib/cli_utils/cli_cmds_group.cpp
index c6c3781d72c..0b4804c1c17 100644
--- a/ydb/core/driver_lib/cli_utils/cli_cmds_group.cpp
+++ b/ydb/core/driver_lib/cli_utils/cli_cmds_group.cpp
@@ -1,11 +1,11 @@
#include <ydb/core/erasure/erasure.h>
-#include "cli.h"
-#include "cli_cmds.h"
+#include "cli.h"
+#include "cli_cmds.h"
#include "proto_common.h"
-
-namespace NKikimr {
-namespace NDriverClient {
-
+
+namespace NKikimr {
+namespace NDriverClient {
+
class TClientCommandGroupReconfigureWipe: public TClientCommand {
public:
TClientCommandGroupReconfigureWipe()
@@ -74,19 +74,19 @@ public:
}
};
-class TClientCommandGroup : public TClientCommandTree {
-public:
- TClientCommandGroup()
- : TClientCommandTree("group", {}, "Group management")
- {
+class TClientCommandGroup : public TClientCommandTree {
+public:
+ TClientCommandGroup()
+ : TClientCommandTree("group", {}, "Group management")
+ {
AddCommand(std::make_unique<TClientCommandGroupReconfigure>());
- }
-};
-
+ }
+};
+
std::unique_ptr<TClientCommand> CreateClientCommandGroup() {
return std::make_unique<TClientCommandGroup>();
-}
-
-
-}
-}
+}
+
+
+}
+}
diff --git a/ydb/core/driver_lib/cli_utils/cli_cmds_node.cpp b/ydb/core/driver_lib/cli_utils/cli_cmds_node.cpp
index 20b63014e13..11e89d19602 100644
--- a/ydb/core/driver_lib/cli_utils/cli_cmds_node.cpp
+++ b/ydb/core/driver_lib/cli_utils/cli_cmds_node.cpp
@@ -1,101 +1,101 @@
-#include <util/string/type.h>
-#include <util/system/hostname.h>
-#include "cli.h"
-#include "cli_cmds.h"
-
-namespace NKikimr {
-namespace NDriverClient {
-
-class TClientCommandDrain : public TClientCommand {
-public:
- TClientCommandDrain()
- : TClientCommand("drain", {}, "Drain node")
- {}
-
- virtual int Run(TConfig& config) override {
- TAutoPtr<NMsgBusProxy::TBusDrainNode> request(new NMsgBusProxy::TBusDrainNode());
- request->Record.SetNodeID(config.NodeId);
- return MessageBusCall(config, request);
- }
-};
-
-class TClientCommandFill : public TClientCommand {
-public:
- TClientCommandFill()
- : TClientCommand("fill", {}, "Fill node")
- {}
-
- virtual int Run(TConfig& config) override {
- TAutoPtr<NMsgBusProxy::TBusFillNode> request(new NMsgBusProxy::TBusFillNode());
- request->Record.SetNodeID(config.NodeId);
- return MessageBusCall(config, request);
- }
-};
-
-class TClientCommandNodeN : public TClientCommandTree {
-public:
- TClientCommandNodeN()
- : TClientCommandTree("*", {}, "<node id or hostname>")
- {
+#include <util/string/type.h>
+#include <util/system/hostname.h>
+#include "cli.h"
+#include "cli_cmds.h"
+
+namespace NKikimr {
+namespace NDriverClient {
+
+class TClientCommandDrain : public TClientCommand {
+public:
+ TClientCommandDrain()
+ : TClientCommand("drain", {}, "Drain node")
+ {}
+
+ virtual int Run(TConfig& config) override {
+ TAutoPtr<NMsgBusProxy::TBusDrainNode> request(new NMsgBusProxy::TBusDrainNode());
+ request->Record.SetNodeID(config.NodeId);
+ return MessageBusCall(config, request);
+ }
+};
+
+class TClientCommandFill : public TClientCommand {
+public:
+ TClientCommandFill()
+ : TClientCommand("fill", {}, "Fill node")
+ {}
+
+ virtual int Run(TConfig& config) override {
+ TAutoPtr<NMsgBusProxy::TBusFillNode> request(new NMsgBusProxy::TBusFillNode());
+ request->Record.SetNodeID(config.NodeId);
+ return MessageBusCall(config, request);
+ }
+};
+
+class TClientCommandNodeN : public TClientCommandTree {
+public:
+ TClientCommandNodeN()
+ : TClientCommandTree("*", {}, "<node id or hostname>")
+ {
AddCommand(std::make_unique<TClientCommandDrain>());
AddCommand(std::make_unique<TClientCommandFill>());
- }
-
- virtual void Config(TConfig& config) override {
- TClientCommandTree::Config(config);
+ }
+
+ virtual void Config(TConfig& config) override {
+ TClientCommandTree::Config(config);
config.SetFreeArgsMin(0);
- }
-
- NKikimrClient::TResponse BusResponse;
- bool Error = false;
-
- virtual void Parse(TConfig& config) override {
- TAutoPtr<NMsgBusProxy::TBusResolveNode> request(new NMsgBusProxy::TBusResolveNode());
- TString node(config.Tokens.back());
- if (IsNumber(node)) {
- request->Record.SetNodeId(FromString(node));
- } else {
- // vvv remove in future versions
- if (node == ".") {
- node = HostName();
- request->Record.SetResolveLocalNode(true);
- }
- // ^^^ remove in future versions
- request->Record.SetHost(node);
- }
- MessageBusCall<NMsgBusProxy::TBusResolveNode, NMsgBusProxy::TBusResponse>(config, request,
+ }
+
+ NKikimrClient::TResponse BusResponse;
+ bool Error = false;
+
+ virtual void Parse(TConfig& config) override {
+ TAutoPtr<NMsgBusProxy::TBusResolveNode> request(new NMsgBusProxy::TBusResolveNode());
+ TString node(config.Tokens.back());
+ if (IsNumber(node)) {
+ request->Record.SetNodeId(FromString(node));
+ } else {
+ // vvv remove in future versions
+ if (node == ".") {
+ node = HostName();
+ request->Record.SetResolveLocalNode(true);
+ }
+ // ^^^ remove in future versions
+ request->Record.SetHost(node);
+ }
+ MessageBusCall<NMsgBusProxy::TBusResolveNode, NMsgBusProxy::TBusResponse>(config, request,
[this](const NMsgBusProxy::TBusResponse& response) -> int {
- BusResponse = response.Record;
- return 0;
- });
- if (BusResponse.GetStatus() != NMsgBusProxy::MSTATUS_OK) {
- Error = true;
- return;
- }
- config.NodeId = BusResponse.GetResolveNodeResponse().GetNodeId();
- TClientCommand::Parse(config);
- if (!config.ParseResult->GetFreeArgs().empty()) {
- TClientCommandTree::Parse(config);
- }
- }
-
- virtual int Run(TConfig& config) override {
- if (!config.ParseResult->GetFreeArgs().empty()) {
- return TClientCommandTree::Run(config);
- } else {
- if (BusResponse.HasResolveNodeResponse()) {
- Cout << BusResponse.GetResolveNodeResponse().GetNodeId() << '\t' << BusResponse.GetResolveNodeResponse().GetHost() << Endl;
- }
- return 0;
- }
- }
-};
-
-TClientCommandNode::TClientCommandNode()
- : TClientCommandTree("node", {}, "Nodes infrastructure administration")
-{
+ BusResponse = response.Record;
+ return 0;
+ });
+ if (BusResponse.GetStatus() != NMsgBusProxy::MSTATUS_OK) {
+ Error = true;
+ return;
+ }
+ config.NodeId = BusResponse.GetResolveNodeResponse().GetNodeId();
+ TClientCommand::Parse(config);
+ if (!config.ParseResult->GetFreeArgs().empty()) {
+ TClientCommandTree::Parse(config);
+ }
+ }
+
+ virtual int Run(TConfig& config) override {
+ if (!config.ParseResult->GetFreeArgs().empty()) {
+ return TClientCommandTree::Run(config);
+ } else {
+ if (BusResponse.HasResolveNodeResponse()) {
+ Cout << BusResponse.GetResolveNodeResponse().GetNodeId() << '\t' << BusResponse.GetResolveNodeResponse().GetHost() << Endl;
+ }
+ return 0;
+ }
+ }
+};
+
+TClientCommandNode::TClientCommandNode()
+ : TClientCommandTree("node", {}, "Nodes infrastructure administration")
+{
AddCommand(std::make_unique<TClientCommandNodeN>());
-}
-
-}
-}
+}
+
+}
+}
diff --git a/ydb/core/driver_lib/cli_utils/cli_cmds_root.cpp b/ydb/core/driver_lib/cli_utils/cli_cmds_root.cpp
index a2358ce106f..ec049fab114 100644
--- a/ydb/core/driver_lib/cli_utils/cli_cmds_root.cpp
+++ b/ydb/core/driver_lib/cli_utils/cli_cmds_root.cpp
@@ -1,30 +1,30 @@
-#include "cli.h"
-#include "cli_cmds.h"
+#include "cli.h"
+#include "cli_cmds.h"
#include <ydb/core/driver_lib/run/factories.h>
-#include <util/folder/path.h>
-#include <util/folder/dirut.h>
-#include <util/string/strip.h>
+#include <util/folder/path.h>
+#include <util/folder/dirut.h>
+#include <util/string/strip.h>
#include <util/system/env.h>
-
-namespace NKikimr {
-namespace NDriverClient {
-
+
+namespace NKikimr {
+namespace NDriverClient {
+
using namespace NYdb::NConsoleClient;
extern void AddClientCommandServer(TClientCommandTree& parent, std::shared_ptr<TModuleFactories> factories);
-
+
class TClientCommandRoot : public TClientCommandRootKikimrBase {
-public:
+public:
TClientCommandRoot(std::shared_ptr<TModuleFactories> factories)
: TClientCommandRootKikimrBase("kikimr")
- {
+ {
AddCommand(std::make_unique<TClientCommandAdmin>());
AddCommand(std::make_unique<TClientCommandDb>());
AddCommand(std::make_unique<TClientCommandCms>());
AddCommand(std::make_unique<TClientCommandWhoAmI>());
AddCommand(std::make_unique<TClientCommandDiscovery>());
AddClientCommandServer(*this, std::move(factories));
- }
+ }
void Config(TConfig& config) override {
NLastGetopt::TOpts& opts = *config.Opts;
@@ -77,24 +77,24 @@ public:
private:
NMsgBusProxy::TMsgBusClientConfig MsgBusClientConfig;
-};
-
+};
+
int NewClient(int argc, char** argv, std::shared_ptr<TModuleFactories> factories) {
THolder<TClientCommandRoot> commandsRoot = MakeHolder<TClientCommandRoot>(std::move(factories));
TClientCommand::TConfig config(argc, argv);
- // TODO: process flags from environment KIKIMR_FLAGS before command line processing
- return commandsRoot->Process(config);
-}
-
+ // TODO: process flags from environment KIKIMR_FLAGS before command line processing
+ return commandsRoot->Process(config);
+}
+
TString NewClientCommandsDescription(std::shared_ptr<TModuleFactories> factories) {
THolder<TClientCommandRoot> commandsRoot = MakeHolder<TClientCommandRoot>(std::move(factories));
- TStringStream stream;
+ TStringStream stream;
NColorizer::TColors colors = NColorizer::AutoColors(Cout);
stream << " [options] <subcommand>" << Endl << Endl
<< colors.BoldColor() << "Subcommands" << colors.OldColor() << ":" << Endl;
commandsRoot->RenderCommandsDescription(stream, colors);
- return stream.Str();
-}
-
-}
-}
+ return stream.Str();
+}
+
+}
+}
diff --git a/ydb/core/driver_lib/cli_utils/cli_cmds_server.cpp b/ydb/core/driver_lib/cli_utils/cli_cmds_server.cpp
index 506074f6fea..6766dd31719 100644
--- a/ydb/core/driver_lib/cli_utils/cli_cmds_server.cpp
+++ b/ydb/core/driver_lib/cli_utils/cli_cmds_server.cpp
@@ -1,5 +1,5 @@
-#include "cli.h"
-#include "cli_cmds.h"
+#include "cli.h"
+#include "cli_cmds.h"
#include <ydb/core/base/location.h>
#include <ydb/core/base/path.h>
#include <ydb/core/driver_lib/run/run.h>
@@ -13,39 +13,39 @@
#include <util/system/hostname.h>
#include <google/protobuf/text_format.h>
-extern TAutoPtr<NKikimrConfig::TActorSystemConfig> DummyActorSystemConfig();
-extern TAutoPtr<NKikimrConfig::TAllocatorConfig> DummyAllocatorConfig();
-
-namespace NKikimr {
-namespace NDriverClient {
-
+extern TAutoPtr<NKikimrConfig::TActorSystemConfig> DummyActorSystemConfig();
+extern TAutoPtr<NKikimrConfig::TAllocatorConfig> DummyAllocatorConfig();
+
+namespace NKikimr {
+namespace NDriverClient {
+
class TClientCommandServerBase : public TClientCommand {
protected:
NKikimrConfig::TAppConfig BaseConfig;
- NKikimrConfig::TAppConfig AppConfig;
- TKikimrRunConfig RunConfig;
-
- ui32 LogLevel; // log settings
- ui32 LogSamplingLevel; // log settings
- ui32 LogSamplingRate; // log settings
+ NKikimrConfig::TAppConfig AppConfig;
+ TKikimrRunConfig RunConfig;
+
+ ui32 LogLevel; // log settings
+ ui32 LogSamplingLevel; // log settings
+ ui32 LogSamplingRate; // log settings
TString LogFormat;// log settings
TString SysLogServiceTag; //unique tags for sys logs
TString LogFileName; // log file name to initialize file log backend
TString ClusterName; // log settings
-
- ui32 NodeId;
+
+ ui32 NodeId;
TString NodeIdValue;
ui32 DefaultInterconnectPort = 19001;
- ui32 BusProxyPort;
- NBus::TBusQueueConfig ProxyBusQueueConfig;
- NBus::TBusServerSessionConfig ProxyBusSessionConfig;
+ ui32 BusProxyPort;
+ NBus::TBusQueueConfig ProxyBusQueueConfig;
+ NBus::TBusServerSessionConfig ProxyBusSessionConfig;
TVector<ui64> ProxyBindToProxy;
- ui32 MonitoringPort;
- TString MonitoringAddress;
- ui32 MonitoringThreads;
+ ui32 MonitoringPort;
+ TString MonitoringAddress;
+ ui32 MonitoringThreads;
TString RestartsCountFile;
TString TracePath;
- size_t CompileInflightLimit; // MiniKQLCompileService
+ size_t CompileInflightLimit; // MiniKQLCompileService
TString UDFsDir;
TVector<TString> UDFsPaths;
TString HostLabelOverride;
@@ -62,8 +62,8 @@ protected:
bool FixedNodeID;
bool IgnoreCmsConfigs;
bool HierarchicalCfg;
- TString NodeAddress;
- TString NodeHost;
+ TString NodeAddress;
+ TString NodeHost;
TString NodeResolveHost;
TString NodeDomain;
ui32 InterconnectPort;
@@ -84,26 +84,26 @@ protected:
TString PathToPKey;
TString PathToCA;
TVector<TString> YamlConfigFiles;
-
+
TClientCommandServerBase(const char *cmd, const char *description)
: TClientCommand(cmd, {}, description)
, RunConfig(AppConfig)
{}
- virtual void Config(TConfig& config) override {
- TClientCommand::Config(config);
-
- LogLevel = NActors::NLog::PRI_WARN;
- LogSamplingLevel = NActors::NLog::PRI_DEBUG;
- LogSamplingRate = 0;
-
- NodeId = 0;
+ virtual void Config(TConfig& config) override {
+ TClientCommand::Config(config);
+
+ LogLevel = NActors::NLog::PRI_WARN;
+ LogSamplingLevel = NActors::NLog::PRI_DEBUG;
+ LogSamplingRate = 0;
+
+ NodeId = 0;
NodeIdValue = "";
- BusProxyPort = NMsgBusProxy::TProtocol::DefaultPort;
- MonitoringPort = 0;
- MonitoringThreads = 10;
- RestartsCountFile = "";
- CompileInflightLimit = 100000;
+ BusProxyPort = NMsgBusProxy::TProtocol::DefaultPort;
+ MonitoringPort = 0;
+ MonitoringThreads = 10;
+ RestartsCountFile = "";
+ CompileInflightLimit = 100000;
TenantName = "";
TenantSlotType = "default";
TenantSlotId = "";
@@ -127,23 +127,23 @@ protected:
GRpcPublicAddressesV4.clear();
GRpcPublicAddressesV6.clear();
GRpcPublicTargetNameOverride = "";
-
- config.Opts->AddLongOption("cluster-name", "which cluster this node belongs to")
- .DefaultValue("unknown").OptionalArgument("STR").StoreResult(&ClusterName);
- config.Opts->AddLongOption("log-level", "default logging level").OptionalArgument("1-7")
- .DefaultValue(ToString(LogLevel)).StoreResult(&LogLevel);
- config.Opts->AddLongOption("log-sampling-level", "sample logs equal to or above this level").OptionalArgument("1-7")
- .DefaultValue(ToString(LogSamplingLevel)).StoreResult(&LogSamplingLevel);
- config.Opts->AddLongOption("log-sampling-rate",
- "log only each Nth message with priority matching sampling level; 0 turns log sampling off")
- .OptionalArgument(Sprintf("0,%" PRIu32, Max<ui32>()))
- .DefaultValue(ToString(LogSamplingRate)).StoreResult(&LogSamplingRate);
- config.Opts->AddLongOption("log-format", "log format to use; short skips the priority and timestamp")
- .DefaultValue("full").OptionalArgument("full|short|json").StoreResult(&LogFormat);
- config.Opts->AddLongOption("syslog", "send to syslog instead of stderr").NoArgument();
+
+ config.Opts->AddLongOption("cluster-name", "which cluster this node belongs to")
+ .DefaultValue("unknown").OptionalArgument("STR").StoreResult(&ClusterName);
+ config.Opts->AddLongOption("log-level", "default logging level").OptionalArgument("1-7")
+ .DefaultValue(ToString(LogLevel)).StoreResult(&LogLevel);
+ config.Opts->AddLongOption("log-sampling-level", "sample logs equal to or above this level").OptionalArgument("1-7")
+ .DefaultValue(ToString(LogSamplingLevel)).StoreResult(&LogSamplingLevel);
+ config.Opts->AddLongOption("log-sampling-rate",
+ "log only each Nth message with priority matching sampling level; 0 turns log sampling off")
+ .OptionalArgument(Sprintf("0,%" PRIu32, Max<ui32>()))
+ .DefaultValue(ToString(LogSamplingRate)).StoreResult(&LogSamplingRate);
+ config.Opts->AddLongOption("log-format", "log format to use; short skips the priority and timestamp")
+ .DefaultValue("full").OptionalArgument("full|short|json").StoreResult(&LogFormat);
+ config.Opts->AddLongOption("syslog", "send to syslog instead of stderr").NoArgument();
config.Opts->AddLongOption("syslog-service-tag", "unique tag for syslog").RequiredArgument("NAME").StoreResult(&SysLogServiceTag);
config.Opts->AddLongOption("log-file-name", "file name for log backend").RequiredArgument("NAME").StoreResult(&LogFileName);
- config.Opts->AddLongOption("tcp", "start tcp interconnect").NoArgument();
+ config.Opts->AddLongOption("tcp", "start tcp interconnect").NoArgument();
config.Opts->AddLongOption('n', "node", "Node ID or 'static' to auto-detect using naming file and ic-port, or 'dynamic' for dynamic nodes, or 'dynamic-fixed' for dynamic nodes with infinite node ID lease (for dynamic storage nodes)")
.RequiredArgument("[NUM|static|dynamic]").StoreResult(&NodeIdValue);
config.Opts->AddLongOption("node-broker", "node broker address host:port")
@@ -152,10 +152,10 @@ protected:
.RequiredArgument("PORT").StoreResult(&NodeBrokerPort);
config.Opts->AddLongOption("node-broker-use-tls", "use tls for node broker (hosts from naming file are used)")
.RequiredArgument("PORT").StoreResult(&NodeBrokerUseTls);
- config.Opts->AddLongOption("node-address", "address for dynamic node")
- .RequiredArgument("ADDR").StoreResult(&NodeAddress);
- config.Opts->AddLongOption("node-host", "hostname for dynamic node")
- .RequiredArgument("NAME").StoreResult(&NodeHost);
+ config.Opts->AddLongOption("node-address", "address for dynamic node")
+ .RequiredArgument("ADDR").StoreResult(&NodeAddress);
+ config.Opts->AddLongOption("node-host", "hostname for dynamic node")
+ .RequiredArgument("NAME").StoreResult(&NodeHost);
config.Opts->AddLongOption("node-resolve-host", "resolve hostname for dynamic node")
.RequiredArgument("NAME").StoreResult(&NodeResolveHost);
config.Opts->AddLongOption("node-domain", "domain for dynamic node to register in")
@@ -164,7 +164,7 @@ protected:
.RequiredArgument("NUM").StoreResult(&InterconnectPort);
config.Opts->AddLongOption("sqs-port", "sqs port")
.RequiredArgument("NUM").StoreResult(&SqsHttpPort);
- config.Opts->AddLongOption("proxy", "Bind to proxy(-ies)").RequiredArgument("ADDR").AppendTo(&ProxyBindToProxy);
+ config.Opts->AddLongOption("proxy", "Bind to proxy(-ies)").RequiredArgument("ADDR").AppendTo(&ProxyBindToProxy);
config.Opts->AddLongOption("host-label-override", "overrides host label for slot").RequiredArgument("NAME").StoreResult(&HostLabelOverride);
config.Opts->AddLongOption("tenant", "add binding for Local service to specified tenant, might be one of {'no', 'dynamic', '/<root>', '/<root>/<path_to_user>'}")
.RequiredArgument("NAME").StoreResult(&TenantName);
@@ -180,20 +180,20 @@ protected:
.RequiredArgument("NUM").StoreResult(&TenantMemory);
config.Opts->AddLongOption("tenant-network", "specify Network limit for tenant binding")
.RequiredArgument("NUM").StoreResult(&TenantNetwork);
- config.Opts->AddLongOption("mon-port", "Monitoring port").OptionalArgument("NUM").StoreResult(&MonitoringPort);
- config.Opts->AddLongOption("mon-address", "Monitoring address").OptionalArgument("ADDR").StoreResult(&MonitoringAddress);
- config.Opts->AddLongOption("mon-threads", "Monitoring http server threads").RequiredArgument("NUM").StoreResult(&MonitoringThreads);
+ config.Opts->AddLongOption("mon-port", "Monitoring port").OptionalArgument("NUM").StoreResult(&MonitoringPort);
+ config.Opts->AddLongOption("mon-address", "Monitoring address").OptionalArgument("ADDR").StoreResult(&MonitoringAddress);
+ config.Opts->AddLongOption("mon-threads", "Monitoring http server threads").RequiredArgument("NUM").StoreResult(&MonitoringThreads);
config.Opts->AddLongOption("suppress-version-check", "Suppress version compatibility checking via IC").NoArgument();
-
+
// config.Opts->AddLongOption('u', "url-base", "url base to request configs from").OptionalArgument("URL");
- config.Opts->AddLongOption("sys-file", "actor system config file (use dummy config by default)").OptionalArgument("PATH");
- config.Opts->AddLongOption("naming-file", "static nameservice config file").OptionalArgument("PATH");
+ config.Opts->AddLongOption("sys-file", "actor system config file (use dummy config by default)").OptionalArgument("PATH");
+ config.Opts->AddLongOption("naming-file", "static nameservice config file").OptionalArgument("PATH");
config.Opts->AddLongOption("domains-file", "domain config file").OptionalArgument("PATH");
- config.Opts->AddLongOption("bs-file", "blobstorage config file").OptionalArgument("PATH");
- config.Opts->AddLongOption("log-file", "log config file").OptionalArgument("PATH");
- config.Opts->AddLongOption("ic-file", "interconnect config file").OptionalArgument("PATH");
+ config.Opts->AddLongOption("bs-file", "blobstorage config file").OptionalArgument("PATH");
+ config.Opts->AddLongOption("log-file", "log config file").OptionalArgument("PATH");
+ config.Opts->AddLongOption("ic-file", "interconnect config file").OptionalArgument("PATH");
config.Opts->AddLongOption("channels-file", "tablet channel profile config file").OptionalArgument("PATH");
- config.Opts->AddLongOption("vdisk-file", "vdisk kind config file").OptionalArgument("PATH");
+ config.Opts->AddLongOption("vdisk-file", "vdisk kind config file").OptionalArgument("PATH");
config.Opts->AddLongOption("drivemodel-file", "drive model config file").OptionalArgument("PATH");
config.Opts->AddLongOption("grpc-file", "gRPC config file").OptionalArgument("PATH");
config.Opts->AddLongOption("tenant-pool-file", "Tenant Pool service config file").OptionalArgument("PATH");
@@ -212,22 +212,22 @@ protected:
config.Opts->AddLongOption("pqcd-file", "PersQueue cluster discovery config file").OptionalArgument("PATH");
config.Opts->AddLongOption("netclassifier-file", "NetClassifier config file").OptionalArgument("PATH");
config.Opts->AddLongOption("auth-file", "authorization configuration").OptionalArgument("PATH");
- config.Opts->AddLongOption("auth-token-file", "authorization token configuration").OptionalArgument("PATH");
+ config.Opts->AddLongOption("auth-token-file", "authorization token configuration").OptionalArgument("PATH");
config.Opts->AddLongOption("key-file", "tanant encryption key configuration").OptionalArgument("PATH");
config.Opts->AddLongOption("pdisk-key-file", "pdisk encryption key configuration").OptionalArgument("PATH");
config.Opts->AddLongOption("sqs-file", "SQS config file").OptionalArgument("PATH");
- config.Opts->AddLongOption("bootstrap-file", "Bootstrap config file").OptionalArgument("PATH");
+ config.Opts->AddLongOption("bootstrap-file", "Bootstrap config file").OptionalArgument("PATH");
config.Opts->AddLongOption("dyn-nodes-file", "Dynamic nodes config file").OptionalArgument("PATH");
config.Opts->AddLongOption("cms-file", "CMS config file").OptionalArgument("PATH");
- config.Opts->AddLongOption("alloc-file", "Allocator config file").OptionalArgument("PATH");
+ config.Opts->AddLongOption("alloc-file", "Allocator config file").OptionalArgument("PATH");
config.Opts->AddLongOption("yql-file", "Yql Analytics config file").OptionalArgument("PATH");
config.Opts->AddLongOption("yq-file", "Yandex Query config file").OptionalArgument("PATH");
config.Opts->AddLongOption("feature-flags-file", "File with feature flags to turn new features on/off").OptionalArgument("PATH");
config.Opts->AddLongOption("rb-file", "File with resource broker customizations").OptionalArgument("PATH");
config.Opts->AddLongOption("metering-file", "File with metering config").OptionalArgument("PATH");
- config.Opts->AddLongOption('r', "restarts-count-file", "State for restarts monitoring counter,\nuse empty string to disable\n")
- .OptionalArgument("PATH").DefaultValue(RestartsCountFile).StoreResult(&RestartsCountFile);
- config.Opts->AddLongOption("compile-inflight-limit", "Limit on parallel programs compilation").OptionalArgument("NUM").StoreResult(&CompileInflightLimit);
+ config.Opts->AddLongOption('r', "restarts-count-file", "State for restarts monitoring counter,\nuse empty string to disable\n")
+ .OptionalArgument("PATH").DefaultValue(RestartsCountFile).StoreResult(&RestartsCountFile);
+ config.Opts->AddLongOption("compile-inflight-limit", "Limit on parallel programs compilation").OptionalArgument("NUM").StoreResult(&CompileInflightLimit);
config.Opts->AddLongOption("udf", "Load shared library with UDF by given path").AppendTo(&UDFsPaths);
config.Opts->AddLongOption("udfs-dir", "Load all shared libraries with UDFs found in given directory").StoreResult(&UDFsDir);
config.Opts->AddLongOption("node-type", "Type of the node")
@@ -246,7 +246,7 @@ protected:
config.Opts->AddLongOption("yaml-config", "Yaml config").OptionalArgument("PATH").AppendTo(&YamlConfigFiles);
config.Opts->AddLongOption("cms-config-cache-file", "Path to CMS cache config file").OptionalArgument("PATH")
.StoreResult(&RunConfig.PathToConfigCacheFile);
- config.Opts->AddHelpOption('h');
+ config.Opts->AddHelpOption('h');
// add messagebus proxy options
config.Opts->AddLongOption("mbus", "Start MessageBus proxy").NoArgument();
@@ -261,8 +261,8 @@ protected:
config.SetFreeArgsMin(0);
config.Opts->SetFreeArgDefaultTitle("PATH", "path to protobuf file; files are merged in order in which they are enlisted");
- }
-
+ }
+
template<typename TProto>
TProto *MutableConfigPart(TConfig& config, const char *optname,
bool (NKikimrConfig::TAppConfig::*hasConfig)() const,
@@ -284,28 +284,28 @@ protected:
return res;
}
- template<typename TProto>
- TProto *MutableConfigPartMerge(TConfig& config, const char *optname,
- TProto* (NKikimrConfig::TAppConfig::*mutableConfig)()) {
- TProto *res = nullptr;
-
- if (config.ParseResult->Has(optname)) {
- TProto cfg;
- bool success = ParsePBFromFile(config.ParseResult->Get(optname), &cfg);
- Y_VERIFY(success);
- res = (AppConfig.*mutableConfig)();
- res->MergeFrom(cfg);
- }
-
- return res;
- }
-
- virtual void Parse(TConfig& config) override {
- TClientCommand::Parse(config);
-
+ template<typename TProto>
+ TProto *MutableConfigPartMerge(TConfig& config, const char *optname,
+ TProto* (NKikimrConfig::TAppConfig::*mutableConfig)()) {
+ TProto *res = nullptr;
+
+ if (config.ParseResult->Has(optname)) {
+ TProto cfg;
+ bool success = ParsePBFromFile(config.ParseResult->Get(optname), &cfg);
+ Y_VERIFY(success);
+ res = (AppConfig.*mutableConfig)();
+ res->MergeFrom(cfg);
+ }
+
+ return res;
+ }
+
+ virtual void Parse(TConfig& config) override {
+ TClientCommand::Parse(config);
+
#define OPTION(NAME, FIELD) MutableConfigPart(config, NAME, &NKikimrConfig::TAppConfig::Has##FIELD, \
&NKikimrConfig::TAppConfig::Get##FIELD, &NKikimrConfig::TAppConfig::Mutable##FIELD)
-#define OPTION_MERGE(NAME, FIELD) MutableConfigPartMerge(config, NAME, &NKikimrConfig::TAppConfig::Mutable##FIELD)
+#define OPTION_MERGE(NAME, FIELD) MutableConfigPartMerge(config, NAME, &NKikimrConfig::TAppConfig::Mutable##FIELD)
OPTION("auth-file", AuthConfig);
OPTION_MERGE("auth-token-file", AuthConfig);
@@ -380,7 +380,7 @@ protected:
OPTION("domains-file", DomainsConfig);
OPTION("bs-file", BlobStorageConfig);
-
+
if (auto logConfig = OPTION("log-file", LogConfig)) {
if (config.ParseResult->Has("syslog"))
logConfig->SetSysLog(true);
@@ -394,12 +394,12 @@ protected:
logConfig->SetFormat(LogFormat);
if (config.ParseResult->Has("cluster-name"))
logConfig->SetClusterName(ClusterName);
- }
+ }
// This flag is set per node and we prefer flag over CMS.
if (config.ParseResult->Has("syslog-service-tag")
&& !AppConfig.GetLogConfig().GetSysLogService())
AppConfig.MutableLogConfig()->SetSysLogService(SysLogServiceTag);
-
+
if (config.ParseResult->Has("log-file-name"))
AppConfig.MutableLogConfig()->SetBackendFileName(LogFileName);
@@ -407,14 +407,14 @@ protected:
if (config.ParseResult->Has("tcp")) {
interconnectConfig->SetStartTcp(true);
}
- }
-
+ }
+
OPTION("channels-file", ChannelProfileConfig);
-
+
if (auto bootstrapConfig = OPTION("bootstrap-file", BootstrapConfig)) {
bootstrapConfig->MutableCompileServiceConfig()->SetInflightLimit(CompileInflightLimit);
- }
-
+ }
+
OPTION("vdisk-file", VDiskConfig);
OPTION("drivemodel-file", DriveModelConfig);
OPTION("grpc-file", GRpcConfig);
@@ -425,7 +425,7 @@ protected:
OPTION("pqcd-file", PQClusterDiscoveryConfig);
OPTION("netclassifier-file", NetClassifierConfig);
OPTION("auth-file", AuthConfig);
- OPTION_MERGE("auth-token-file", AuthConfig);
+ OPTION_MERGE("auth-token-file", AuthConfig);
OPTION("key-file", KeyConfig);
OPTION("pdisk-key-file", PDiskKeyConfig);
OPTION("sqs-file", SqsConfig);
@@ -434,13 +434,13 @@ protected:
OPTION("metering-file", MeteringConfig);
OPTION("kqp-file", KQPConfig);
OPTION("incrhuge-file", IncrHugeConfig);
- OPTION("alloc-file", AllocatorConfig);
+ OPTION("alloc-file", AllocatorConfig);
OPTION("yq-file", YandexQueryConfig);
- if (!AppConfig.HasAllocatorConfig()) {
- AppConfig.MutableAllocatorConfig()->CopyFrom(*DummyAllocatorConfig());
- }
-
+ if (!AppConfig.HasAllocatorConfig()) {
+ AppConfig.MutableAllocatorConfig()->CopyFrom(*DummyAllocatorConfig());
+ }
+
// apply certificates, if any
if (config.ParseResult->Has("cert")) {
AppConfig.MutableInterconnectConfig()->SetPathToCertificateFile(PathToCert);
@@ -518,12 +518,12 @@ protected:
AppConfig.MutableMonitoringConfig()->SetMonitoringThreads(MonitoringThreads);
if (!AppConfig.HasRestartsCountConfig() && RestartsCountFile)
AppConfig.MutableRestartsCountConfig()->SetRestartsCountFile(RestartsCountFile);
-
+
// Ports and node type are always applied (event if config was loaded from CMS).
if (MonitoringPort)
AppConfig.MutableMonitoringConfig()->SetMonitoringPort(MonitoringPort);
- if (MonitoringAddress)
- AppConfig.MutableMonitoringConfig()->SetMonitoringAddress(MonitoringAddress);
+ if (MonitoringAddress)
+ AppConfig.MutableMonitoringConfig()->SetMonitoringAddress(MonitoringAddress);
if (SqsHttpPort)
RunConfig.AppConfig.MutableSqsConfig()->MutableHttpServerConfig()->SetPort(SqsHttpPort);
if (GRpcPort) {
@@ -627,7 +627,7 @@ protected:
auto queueConfig = messageBusConfig->MutableProxyBusQueueConfig();
queueConfig->SetName(ProxyBusQueueConfig.Name);
queueConfig->SetNumWorkers(ProxyBusQueueConfig.NumWorkers);
-
+
auto sessionConfig = messageBusConfig->MutableProxyBusSessionConfig();
// TODO use macro from messagebus header file
@@ -661,9 +661,9 @@ protected:
}
messageBusConfig->SetStartTracingBusProxy(!!TracePath);
messageBusConfig->SetTracePath(TracePath);
- }
- }
-
+ }
+ }
+
inline bool LoadConfigFromCMS() {
TVector<TString> addrs;
FillClusterEndpoints(addrs);
@@ -854,13 +854,13 @@ protected:
RegisterDynamicNode();
if (!HierarchicalCfg && !IgnoreCmsConfigs)
LoadConfigForDynamicNode();
- }
+ }
- THolder<NClient::TRegistrationResult> TryToRegisterDynamicNode(
- const TString &addr,
- const TString &domainName,
- const TString &nodeHost,
- const TString &nodeAddress,
+ THolder<NClient::TRegistrationResult> TryToRegisterDynamicNode(
+ const TString &addr,
+ const TString &domainName,
+ const TString &nodeHost,
+ const TString &nodeAddress,
const TString &nodeResolveHost,
const TMaybe<TString>& path) {
NClient::TKikimr kikimr(GetKikimr(addr));
@@ -883,10 +883,10 @@ protected:
return MakeHolder<NClient::TRegistrationResult>
(registrant.SyncRegisterNode(ToString(domainName),
- nodeHost,
+ nodeHost,
InterconnectPort,
- nodeAddress,
- nodeResolveHost,
+ nodeAddress,
+ nodeResolveHost,
std::move(loc),
FixedNodeID,
path));
@@ -1108,8 +1108,8 @@ private:
}
return NClient::TKikimr(grpcConfig);
}
-};
-
+};
+
class TClientCommandServerConfig : public TClientCommandServerBase {
public:
TClientCommandServerConfig()
@@ -1155,7 +1155,7 @@ private:
void AddClientCommandServer(TClientCommandTree& parent, std::shared_ptr<TModuleFactories> factories) {
parent.AddCommand(std::make_unique<TClientCommandServer>(factories));
parent.AddCommand(std::make_unique<TClientCommandServerConfig>());
-}
-
-}
-}
+}
+
+}
+}
diff --git a/ydb/core/driver_lib/cli_utils/cli_cmds_tablet.cpp b/ydb/core/driver_lib/cli_utils/cli_cmds_tablet.cpp
index f8c6d1b5c83..361e757ca1d 100644
--- a/ydb/core/driver_lib/cli_utils/cli_cmds_tablet.cpp
+++ b/ydb/core/driver_lib/cli_utils/cli_cmds_tablet.cpp
@@ -1,166 +1,166 @@
-#include "cli.h"
-#include "cli_cmds.h"
-
-namespace NKikimr {
-namespace NDriverClient {
-
+#include "cli.h"
+#include "cli_cmds.h"
+
+namespace NKikimr {
+namespace NDriverClient {
+
class TClientCommandKeyValueRequest : public TClientCommandConfig {
-public:
- TClientCommandKeyValueRequest()
+public:
+ TClientCommandKeyValueRequest()
: TClientCommandConfig("request", { "req" }, "Request to KV tablet")
- {}
-
+ {}
+
TString ProtoBuf;
TAutoPtr<NKikimrClient::TKeyValueRequest> Request;
TString OutputFile;
TString InputFile;
-
+
int OnResponse(const NKikimrClient::TResponse& response) {
- if (!OutputFile.empty()) {
- Y_VERIFY(response.ReadResultSize() == 1);
- Y_VERIFY(response.GetReadResult(0).HasStatus());
- Y_VERIFY(response.GetReadResult(0).GetStatus() == NKikimrProto::OK);
- Y_VERIFY(response.GetReadResult(0).HasValue());
- TFile file(OutputFile, CreateNew | WrOnly);
+ if (!OutputFile.empty()) {
+ Y_VERIFY(response.ReadResultSize() == 1);
+ Y_VERIFY(response.GetReadResult(0).HasStatus());
+ Y_VERIFY(response.GetReadResult(0).GetStatus() == NKikimrProto::OK);
+ Y_VERIFY(response.GetReadResult(0).HasValue());
+ TFile file(OutputFile, CreateNew | WrOnly);
TString data = response.GetReadResult(0).GetValue();
file.Write(data.data(), data.size());
- file.Close();
- } else if (!InputFile.empty()) {
- Y_VERIFY(response.WriteResultSize() == 1);
- Y_VERIFY(response.GetWriteResult(0).HasStatus());
- Y_VERIFY(response.GetWriteResult(0).GetStatus() == NKikimrProto::OK);
- } else {
- Cout << GetString(response) << Endl;
- }
- return 0;
- }
-
- virtual int Run(TConfig& config) override {
- TAutoPtr<NMsgBusProxy::TBusKeyValue> request(new NMsgBusProxy::TBusKeyValue());
- if (Request != nullptr)
- request->Record.MergeFrom(*Request);
- if (config.TabletId != 0)
- request->Record.SetTabletId(config.TabletId);
- return MessageBusCall<NMsgBusProxy::TBusKeyValue, NMsgBusProxy::TBusResponse>(config, request,
- [this](const NMsgBusProxy::TBusResponse& response) -> int { return OnResponse(response.Record); });
- }
-
- virtual void Config(TConfig& config) override {
- TClientCommand::Config(config);
+ file.Close();
+ } else if (!InputFile.empty()) {
+ Y_VERIFY(response.WriteResultSize() == 1);
+ Y_VERIFY(response.GetWriteResult(0).HasStatus());
+ Y_VERIFY(response.GetWriteResult(0).GetStatus() == NKikimrProto::OK);
+ } else {
+ Cout << GetString(response) << Endl;
+ }
+ return 0;
+ }
+
+ virtual int Run(TConfig& config) override {
+ TAutoPtr<NMsgBusProxy::TBusKeyValue> request(new NMsgBusProxy::TBusKeyValue());
+ if (Request != nullptr)
+ request->Record.MergeFrom(*Request);
+ if (config.TabletId != 0)
+ request->Record.SetTabletId(config.TabletId);
+ return MessageBusCall<NMsgBusProxy::TBusKeyValue, NMsgBusProxy::TBusResponse>(config, request,
+ [this](const NMsgBusProxy::TBusResponse& response) -> int { return OnResponse(response.Record); });
+ }
+
+ virtual void Config(TConfig& config) override {
+ TClientCommand::Config(config);
config.SetFreeArgsNum(1);
SetFreeArgTitle(0, "<REQUEST>", "Request protobuf or file with request protobuf");
- config.Opts->AddLongOption("of", "output file path, protobuf must contain single read command!").Optional()
- .RequiredArgument("PATH").StoreResult(&OutputFile);
- config.Opts->AddLongOption("if", "input file path, protobuf must contain single write command!").Optional()
- .RequiredArgument("PATH").StoreResult(&InputFile);
- if (!(OutputFile.empty() || InputFile.empty())) {
- ythrow TWithBackTrace<yexception>() << "Use either --of or --if!";
- }
- }
-
- virtual void Parse(TConfig& config) override {
- TClientCommand::Parse(config);
- ProtoBuf = config.ParseResult->GetFreeArgs().at(0);
+ config.Opts->AddLongOption("of", "output file path, protobuf must contain single read command!").Optional()
+ .RequiredArgument("PATH").StoreResult(&OutputFile);
+ config.Opts->AddLongOption("if", "input file path, protobuf must contain single write command!").Optional()
+ .RequiredArgument("PATH").StoreResult(&InputFile);
+ if (!(OutputFile.empty() || InputFile.empty())) {
+ ythrow TWithBackTrace<yexception>() << "Use either --of or --if!";
+ }
+ }
+
+ virtual void Parse(TConfig& config) override {
+ TClientCommand::Parse(config);
+ ProtoBuf = config.ParseResult->GetFreeArgs().at(0);
Request = GetProtobuf<NKikimrClient::TKeyValueRequest>(ProtoBuf);
- if (!InputFile.empty()) {
- Y_VERIFY(Request->CmdWriteSize() == 1);
- Y_VERIFY(Request->GetCmdWrite(0).HasKey());
- Y_VERIFY(!Request->GetCmdWrite(0).HasValue());
+ if (!InputFile.empty()) {
+ Y_VERIFY(Request->CmdWriteSize() == 1);
+ Y_VERIFY(Request->GetCmdWrite(0).HasKey());
+ Y_VERIFY(!Request->GetCmdWrite(0).HasValue());
TString data = TUnbufferedFileInput(InputFile).ReadAll();
- Request->MutableCmdWrite(0)->SetValue(data);
- }
- }
-};
-
-class TClientCommandKeyValue : public TClientCommandTree {
-public:
- TClientCommandKeyValue()
- : TClientCommandTree("keyvalue", { "kv" })
- {
+ Request->MutableCmdWrite(0)->SetValue(data);
+ }
+ }
+};
+
+class TClientCommandKeyValue : public TClientCommandTree {
+public:
+ TClientCommandKeyValue()
+ : TClientCommandTree("keyvalue", { "kv" })
+ {
AddCommand(std::make_unique<TClientCommandKeyValueRequest>());
- }
-};
-
+ }
+};
+
class TClientCommandTabletExec : public TClientCommandConfig {
-public:
- TClientCommandTabletExec()
+public:
+ TClientCommandTabletExec()
: TClientCommandConfig("execute", { "exec" })
- {
- }
-
- TAutoPtr<NMsgBusProxy::TBusTabletLocalMKQL> Request;
+ {
+ }
+
+ TAutoPtr<NMsgBusProxy::TBusTabletLocalMKQL> Request;
TString Program;
TString Params;
-
+
virtual void Config(TConfig& config) override {
- TClientCommand::Config(config);
+ TClientCommand::Config(config);
config.Opts->AddLongOption("follower", "connect to follower").NoArgument();
- config.Opts->AddLongOption("json-ui64-as-string", "json output ui64 as string").NoArgument();
- config.Opts->AddLongOption("json-binary-as-base64", "json output binary data in base64").NoArgument();
+ config.Opts->AddLongOption("json-ui64-as-string", "json output ui64 as string").NoArgument();
+ config.Opts->AddLongOption("json-binary-as-base64", "json output binary data in base64").NoArgument();
config.SetFreeArgsNum(1, 2);
SetFreeArgTitle(0, "<PROGRAM>", "Program to execute");
SetFreeArgTitle(1, "<PARAMS>", "Parameters of the program");
- }
-
+ }
+
virtual void Parse(TConfig& config) override {
- TClientCommand::Parse(config);
-
- Program = GetMiniKQL(config.ParseResult->GetFreeArgs().at(0));
- if (config.ParseResult->GetFreeArgCount() > 1)
- Params = GetMiniKQL(config.ParseResult->GetFreeArgs().at(1));
-
- Request = new NMsgBusProxy::TBusTabletLocalMKQL;
- Request->Record.SetTabletID(config.TabletId);
- auto* pgm = Request->Record.MutableProgram();
- if (IsMiniKQL(Program)) {
- pgm->MutableProgram()->SetText(Program);
- } else {
- pgm->MutableProgram()->SetBin(Program);
- }
-
- if (!Params.empty()) {
- if (IsMiniKQL(Params)) {
- pgm->MutableParams()->SetText(Params);
- } else {
- pgm->MutableParams()->SetBin(Params);
- }
- }
+ TClientCommand::Parse(config);
+
+ Program = GetMiniKQL(config.ParseResult->GetFreeArgs().at(0));
+ if (config.ParseResult->GetFreeArgCount() > 1)
+ Params = GetMiniKQL(config.ParseResult->GetFreeArgs().at(1));
+
+ Request = new NMsgBusProxy::TBusTabletLocalMKQL;
+ Request->Record.SetTabletID(config.TabletId);
+ auto* pgm = Request->Record.MutableProgram();
+ if (IsMiniKQL(Program)) {
+ pgm->MutableProgram()->SetText(Program);
+ } else {
+ pgm->MutableProgram()->SetBin(Program);
+ }
+
+ if (!Params.empty()) {
+ if (IsMiniKQL(Params)) {
+ pgm->MutableParams()->SetText(Params);
+ } else {
+ pgm->MutableParams()->SetBin(Params);
+ }
+ }
Request->Record.SetConnectToFollower(config.ParseResult->Has("follower"));
- config.JsonUi64AsText = config.ParseResult->Has("json-ui64-as-string");
- config.JsonBinaryAsBase64 = config.ParseResult->Has("json-binary-as-base64");
- }
-
- virtual int Run(TConfig& config) override {
+ config.JsonUi64AsText = config.ParseResult->Has("json-ui64-as-string");
+ config.JsonBinaryAsBase64 = config.ParseResult->Has("json-binary-as-base64");
+ }
+
+ virtual int Run(TConfig& config) override {
return MessageBusCall(config, Request);
- }
-};
-
-class TClientCommandTabletKill : public TClientCommand {
-public:
- TClientCommandTabletKill()
- : TClientCommand("kill")
- {
- }
-
- TAutoPtr<NMsgBusProxy::TBusTabletKillRequest> Request;
-
- virtual void Config(TConfig& config) override {
- TClientCommand::Config(config);
+ }
+};
+
+class TClientCommandTabletKill : public TClientCommand {
+public:
+ TClientCommandTabletKill()
+ : TClientCommand("kill")
+ {
+ }
+
+ TAutoPtr<NMsgBusProxy::TBusTabletKillRequest> Request;
+
+ virtual void Config(TConfig& config) override {
+ TClientCommand::Config(config);
config.SetFreeArgsNum(0);
- }
-
- virtual void Parse(TConfig& config) override {
- TClientCommand::Parse(config);
- Request = new NMsgBusProxy::TBusTabletKillRequest;
- Request->Record.SetTabletID(config.TabletId);
- }
-
- virtual int Run(TConfig& config) override {
- return MessageBusCall(config, Request);
- }
-};
-
+ }
+
+ virtual void Parse(TConfig& config) override {
+ TClientCommand::Parse(config);
+ Request = new NMsgBusProxy::TBusTabletKillRequest;
+ Request->Record.SetTabletID(config.TabletId);
+ }
+
+ virtual int Run(TConfig& config) override {
+ return MessageBusCall(config, Request);
+ }
+};
+
class TClientCommandTabletSchemeTx : public TClientCommand {
public:
TClientCommandTabletSchemeTx()
@@ -202,81 +202,81 @@ public:
};
class TClientCommandDrainNode : public TClientCommand {
-public:
+public:
TClientCommandDrainNode()
- : TClientCommand("drain", {}, "Drain node")
- {}
-
- virtual void Config(TConfig& config) override {
- TClientCommand::Config(config);
+ : TClientCommand("drain", {}, "Drain node")
+ {}
+
+ virtual void Config(TConfig& config) override {
+ TClientCommand::Config(config);
config.SetFreeArgsNum(1);
SetFreeArgTitle(0, "<NODE ID>", "Node ID to drain tablets from");
- }
-
- ui32 NodeId;
-
- virtual void Parse(TConfig& config) override {
- TClientCommand::Parse(config);
- NodeId = FromString(config.ParseResult->GetFreeArgs().at(0));
- }
-
- virtual int Run(TConfig& config) override {
- TAutoPtr<NMsgBusProxy::TBusDrainNode> request(new NMsgBusProxy::TBusDrainNode());
- request->Record.SetNodeID(NodeId);
- return MessageBusCall(config, request);
- }
-};
-
+ }
+
+ ui32 NodeId;
+
+ virtual void Parse(TConfig& config) override {
+ TClientCommand::Parse(config);
+ NodeId = FromString(config.ParseResult->GetFreeArgs().at(0));
+ }
+
+ virtual int Run(TConfig& config) override {
+ TAutoPtr<NMsgBusProxy::TBusDrainNode> request(new NMsgBusProxy::TBusDrainNode());
+ request->Record.SetNodeID(NodeId);
+ return MessageBusCall(config, request);
+ }
+};
+
class TClientCommandFillNode : public TClientCommand {
-public:
+public:
TClientCommandFillNode()
- : TClientCommand("fill", {}, "Fill node")
- {}
-
- virtual void Config(TConfig& config) override {
- TClientCommand::Config(config);
+ : TClientCommand("fill", {}, "Fill node")
+ {}
+
+ virtual void Config(TConfig& config) override {
+ TClientCommand::Config(config);
config.SetFreeArgsNum(1);
SetFreeArgTitle(0, "<NODE ID>", "Node ID to fill tablets to");
- }
-
- ui32 NodeId;
-
- virtual void Parse(TConfig& config) override {
- TClientCommand::Parse(config);
- NodeId = FromString(config.ParseResult->GetFreeArgs().at(0));
- }
-
- virtual int Run(TConfig& config) override {
- TAutoPtr<NMsgBusProxy::TBusFillNode> request(new NMsgBusProxy::TBusFillNode());
- request->Record.SetNodeID(NodeId);
- return MessageBusCall(config, request);
- }
-};
-
-class TClientCommandTabletN : public TClientCommandTree {
-public:
- TClientCommandTabletN()
- : TClientCommandTree("#", {}, "<tablet id>")
- {
+ }
+
+ ui32 NodeId;
+
+ virtual void Parse(TConfig& config) override {
+ TClientCommand::Parse(config);
+ NodeId = FromString(config.ParseResult->GetFreeArgs().at(0));
+ }
+
+ virtual int Run(TConfig& config) override {
+ TAutoPtr<NMsgBusProxy::TBusFillNode> request(new NMsgBusProxy::TBusFillNode());
+ request->Record.SetNodeID(NodeId);
+ return MessageBusCall(config, request);
+ }
+};
+
+class TClientCommandTabletN : public TClientCommandTree {
+public:
+ TClientCommandTabletN()
+ : TClientCommandTree("#", {}, "<tablet id>")
+ {
AddCommand(std::make_unique<TClientCommandKeyValue>());
AddCommand(std::make_unique<TClientCommandTabletExec>());
AddCommand(std::make_unique<TClientCommandTabletKill>());
AddCommand(std::make_unique<TClientCommandTabletSchemeTx>());
- }
-
- virtual void Parse(TConfig& config) override {
- config.TabletId = FromString<ui64>(config.Tokens.back());
- TClientCommandTree::Parse(config);
- }
-};
-
-TClientCommandTablet::TClientCommandTablet()
- : TClientCommandTree("tablet", {}, "Tablet infrastructure administration")
-{
+ }
+
+ virtual void Parse(TConfig& config) override {
+ config.TabletId = FromString<ui64>(config.Tokens.back());
+ TClientCommandTree::Parse(config);
+ }
+};
+
+TClientCommandTablet::TClientCommandTablet()
+ : TClientCommandTree("tablet", {}, "Tablet infrastructure administration")
+{
AddCommand(std::make_unique<TClientCommandTabletN>());
AddCommand(std::make_unique<TClientCommandDrainNode>());
AddCommand(std::make_unique<TClientCommandFillNode>());
-}
-
-}
-}
+}
+
+}
+}
diff --git a/ydb/core/driver_lib/cli_utils/cli_mb_trace.cpp b/ydb/core/driver_lib/cli_utils/cli_mb_trace.cpp
index d970b88b451..df1fa4a79f3 100644
--- a/ydb/core/driver_lib/cli_utils/cli_mb_trace.cpp
+++ b/ydb/core/driver_lib/cli_utils/cli_mb_trace.cpp
@@ -1,98 +1,98 @@
-#include "cli.h"
+#include "cli.h"
#include <ydb/public/lib/deprecated/client/msgbus_client.h>
#include <ydb/public/lib/deprecated/client/msgbus_player.h>
-
-namespace NKikimr {
-namespace NDriverClient {
-
-struct TCmdMessageBusTraceConfig : public TCliCmdConfig {
+
+namespace NKikimr {
+namespace NDriverClient {
+
+struct TCmdMessageBusTraceConfig : public TCliCmdConfig {
TString Command;
TString Path;
- ui32 MaxInFlight;
-
- TCmdMessageBusTraceConfig() : MaxInFlight(1) {}
- void Parse(int argc, char **argv);
-};
-
-int MessageBusTrace(TCommandConfig &cmdConf, int argc, char** argv) {
+ ui32 MaxInFlight;
+
+ TCmdMessageBusTraceConfig() : MaxInFlight(1) {}
+ void Parse(int argc, char **argv);
+};
+
+int MessageBusTrace(TCommandConfig &cmdConf, int argc, char** argv) {
Y_UNUSED(cmdConf);
-
-#ifdef _win32_
- WSADATA dummy;
- WSAStartup(MAKEWORD(2, 2), &dummy);
-#endif
-
- TCmdMessageBusTraceConfig messageBusTraceConfig;
- messageBusTraceConfig.Parse(argc, argv);
-
+
+#ifdef _win32_
+ WSADATA dummy;
+ WSAStartup(MAKEWORD(2, 2), &dummy);
+#endif
+
+ TCmdMessageBusTraceConfig messageBusTraceConfig;
+ messageBusTraceConfig.Parse(argc, argv);
+
NMsgBusProxy::TMsgBusClient client(std::get<NMsgBusProxy::TMsgBusClientConfig>(*messageBusTraceConfig.ClientConfig));
- client.Init();
-
- if (messageBusTraceConfig.Command == "play") {
- try {
- bool displayProgress = isatty(fileno(stdout)); // don't know better way to check on all platforms for redirected output
- NMessageBusTracer::TMsgBusPlayer player(client);
- player.PlayTrace(messageBusTraceConfig.Path, messageBusTraceConfig.MaxInFlight, displayProgress ? [](int p){ Cout << p << "%\r"; Cout.Flush(); } : std::function<void(int)>());
- if (displayProgress)
- Cout << Endl;
- }
- catch(const yexception& e) {
- Cerr << "Caught exception: " << e.what() << Endl;
- return 1;
- }
- return 0;
- } else {
- NMsgBusProxy::TBusMessageBusTraceRequest *request(new NMsgBusProxy::TBusMessageBusTraceRequest());
- if (messageBusTraceConfig.Command == "start") {
+ client.Init();
+
+ if (messageBusTraceConfig.Command == "play") {
+ try {
+ bool displayProgress = isatty(fileno(stdout)); // don't know better way to check on all platforms for redirected output
+ NMessageBusTracer::TMsgBusPlayer player(client);
+ player.PlayTrace(messageBusTraceConfig.Path, messageBusTraceConfig.MaxInFlight, displayProgress ? [](int p){ Cout << p << "%\r"; Cout.Flush(); } : std::function<void(int)>());
+ if (displayProgress)
+ Cout << Endl;
+ }
+ catch(const yexception& e) {
+ Cerr << "Caught exception: " << e.what() << Endl;
+ return 1;
+ }
+ return 0;
+ } else {
+ NMsgBusProxy::TBusMessageBusTraceRequest *request(new NMsgBusProxy::TBusMessageBusTraceRequest());
+ if (messageBusTraceConfig.Command == "start") {
request->Record.SetCommand(NKikimrClient::TMessageBusTraceRequest::START);
- } else if (messageBusTraceConfig.Command == "stop") {
+ } else if (messageBusTraceConfig.Command == "stop") {
request->Record.SetCommand(NKikimrClient::TMessageBusTraceRequest::STOP);
- }
- if (messageBusTraceConfig.Path)
- request->Record.SetPath(messageBusTraceConfig.Path);
-
- TAutoPtr<NBus::TBusMessage> reply;
- NBus::EMessageStatus status = client.SyncCall(request, reply);
-
- switch (status) {
- case NBus::MESSAGE_OK:
- {
+ }
+ if (messageBusTraceConfig.Path)
+ request->Record.SetPath(messageBusTraceConfig.Path);
+
+ TAutoPtr<NBus::TBusMessage> reply;
+ NBus::EMessageStatus status = client.SyncCall(request, reply);
+
+ switch (status) {
+ case NBus::MESSAGE_OK:
+ {
const NKikimrClient::TMessageBusTraceStatus &response = static_cast<NMsgBusProxy::TBusMessageBusTraceStatus *>(reply.Get())->Record;
-// Cout << "status: " << response.GetStatus() << Endl;
-// Cout << "status transcript: " << static_cast<NMsgBusProxy::EResponseStatus>(response.GetStatus()) << Endl;
- Cout << "trace active: " << response.GetTraceActive() << Endl;
- if (response.GetTraceActive()) {
- Cout << "trace file: " << response.GetPath() << Endl;
- }
-
- return 0;
- }
- default:
- {
- const char *description = NBus::MessageStatusDescription(status);
- Cerr << description << Endl;
- }
- return 1;
- }
- }
-}
-
-void TCmdMessageBusTraceConfig::Parse(int argc, char **argv) {
- using namespace NLastGetopt;
-
- TOpts opts = TOpts::Default();
- opts.AddLongOption('c', "cmd", "command").Required().RequiredArgument("[start|stop|play]").StoreResult(&Command); // {start|stop|play}
- opts.AddLongOption("path", "name of trace file").Optional().RequiredArgument("PATH").StoreResult(&Path); // path to trace file
- opts.AddLongOption("inflight", "max inflight messages").Optional().RequiredArgument("NUM").StoreResult(&MaxInFlight); // max inflight messages
- ConfigureBaseLastGetopt(opts);
- TOptsParseResult res(&opts, argc, argv);
- if (Command != "start" && Command != "stop" && Command != "play") {
- ythrow yexception() << "command should be one of [start|stop|play].";
- }
- if (MaxInFlight == 0)
- ythrow yexception() << "inflight should be greater than 0";
- ConfigureMsgBusLastGetopt(res, argc, argv);
-}
-
-}
-}
+// Cout << "status: " << response.GetStatus() << Endl;
+// Cout << "status transcript: " << static_cast<NMsgBusProxy::EResponseStatus>(response.GetStatus()) << Endl;
+ Cout << "trace active: " << response.GetTraceActive() << Endl;
+ if (response.GetTraceActive()) {
+ Cout << "trace file: " << response.GetPath() << Endl;
+ }
+
+ return 0;
+ }
+ default:
+ {
+ const char *description = NBus::MessageStatusDescription(status);
+ Cerr << description << Endl;
+ }
+ return 1;
+ }
+ }
+}
+
+void TCmdMessageBusTraceConfig::Parse(int argc, char **argv) {
+ using namespace NLastGetopt;
+
+ TOpts opts = TOpts::Default();
+ opts.AddLongOption('c', "cmd", "command").Required().RequiredArgument("[start|stop|play]").StoreResult(&Command); // {start|stop|play}
+ opts.AddLongOption("path", "name of trace file").Optional().RequiredArgument("PATH").StoreResult(&Path); // path to trace file
+ opts.AddLongOption("inflight", "max inflight messages").Optional().RequiredArgument("NUM").StoreResult(&MaxInFlight); // max inflight messages
+ ConfigureBaseLastGetopt(opts);
+ TOptsParseResult res(&opts, argc, argv);
+ if (Command != "start" && Command != "stop" && Command != "play") {
+ ythrow yexception() << "command should be one of [start|stop|play].";
+ }
+ if (MaxInFlight == 0)
+ ythrow yexception() << "inflight should be greater than 0";
+ ConfigureMsgBusLastGetopt(res, argc, argv);
+}
+
+}
+}
diff --git a/ydb/core/driver_lib/cli_utils/ya.make b/ydb/core/driver_lib/cli_utils/ya.make
index a31282ae14e..cb1f9670bea 100644
--- a/ydb/core/driver_lib/cli_utils/ya.make
+++ b/ydb/core/driver_lib/cli_utils/ya.make
@@ -8,21 +8,21 @@ SRCS(
cli_actorsystem_perftest.cpp
cli_cmd_config.h
cli_cmd_config.cpp
- cli_cmds.h
- cli_cmds_admin.cpp
- cli_cmds_bs.cpp
+ cli_cmds.h
+ cli_cmds_admin.cpp
+ cli_cmds_bs.cpp
cli_cmds_cms.cpp
cli_cmds_config.cpp
cli_cmds_console.cpp
- cli_cmds_debug.cpp
- cli_cmds_disk.cpp
+ cli_cmds_debug.cpp
+ cli_cmds_disk.cpp
cli_cmds_genconfig.cpp
cli_cmds_get.cpp
- cli_cmds_group.cpp
- cli_cmds_node.cpp
- cli_cmds_root.cpp
- cli_cmds_server.cpp
- cli_cmds_tablet.cpp
+ cli_cmds_group.cpp
+ cli_cmds_node.cpp
+ cli_cmds_root.cpp
+ cli_cmds_server.cpp
+ cli_cmds_tablet.cpp
cli_cmds_tenant.cpp
cli_fakeinitshard.cpp
cli_keyvalue.cpp
diff --git a/ydb/core/driver_lib/run/config.h b/ydb/core/driver_lib/run/config.h
index 32b032fa0bc..faf1797413e 100644
--- a/ydb/core/driver_lib/run/config.h
+++ b/ydb/core/driver_lib/run/config.h
@@ -43,14 +43,14 @@ union TBasicKikimrServicesMask {
bool EnableKqp:1;
bool EnableMemoryLog:1;
bool EnableGRpcService:1;
- bool EnableNodeIdentifier:1;
+ bool EnableNodeIdentifier:1;
bool EnableCms:1;
bool EnableNodeTable:1;
bool EnableGRpcProxyStatus:1;
bool EnablePQ:1;
bool EnableSqs:1;
bool EnableConfigsDispatcher:1;
- bool EnableSecurityServices:1;
+ bool EnableSecurityServices:1;
bool EnableTabletInfo:1;
bool EnableQuoterService:1;
bool EnablePersQueueClusterDiscovery:1;
@@ -61,7 +61,7 @@ union TBasicKikimrServicesMask {
bool EnableSchemeBoardMonitoring:1;
bool EnableConfigsCache:1;
bool EnableLongTxService:1;
- bool EnableHealthCheckService:1;
+ bool EnableHealthCheckService:1;
bool EnableYandexQuery:1;
bool EnableSequenceProxyService:1;
};
diff --git a/ydb/core/driver_lib/run/config_parser.cpp b/ydb/core/driver_lib/run/config_parser.cpp
index 8db1b4fe36d..bb686562912 100644
--- a/ydb/core/driver_lib/run/config_parser.cpp
+++ b/ydb/core/driver_lib/run/config_parser.cpp
@@ -29,8 +29,8 @@ TRunCommandConfigParser::TRunOpts::TRunOpts()
, StartBusProxy(false)
, BusProxyPort(NMsgBusProxy::TProtocol::DefaultPort)
, MonitoringPort(0)
- , MonitoringAddress()
- , MonitoringThreads(10)
+ , MonitoringAddress()
+ , MonitoringThreads(10)
, RestartsCountFile("")
, StartTracingBusProxy(true)
, CompileInflightLimit(100000)
@@ -54,7 +54,7 @@ void TRunCommandConfigParser::SetupLastGetOptForConfigFiles(NLastGetopt::TOpts&
opts.AddLongOption("log-file", "log config file").OptionalArgument("PATH");
opts.AddLongOption("ic-file", "interconnect config file").OptionalArgument("PATH");
opts.AddLongOption("channels-file", "tablet channel profile config file").OptionalArgument("PATH").Required();
- opts.AddLongOption("vdisk-file", "vdisk kind config file").OptionalArgument("PATH");
+ opts.AddLongOption("vdisk-file", "vdisk kind config file").OptionalArgument("PATH");
opts.AddLongOption("drivemodel-file", "drive model config file").OptionalArgument("PATH");
opts.AddLongOption("kqp-file", "Kikimr Query Processor config file").OptionalArgument("PATH");
opts.AddLongOption("incrhuge-file", "incremental huge blob keeper config file").OptionalArgument("PATH");
@@ -69,10 +69,10 @@ void TRunCommandConfigParser::SetupLastGetOptForConfigFiles(NLastGetopt::TOpts&
opts.AddLongOption("pqcd-file", "PQCD config file").OptionalArgument("PATH");
opts.AddLongOption("netclassifier-file", "NetClassifier config file").OptionalArgument("PATH");
opts.AddLongOption("auth-file", "authorization config file").OptionalArgument("PATH");
- opts.AddLongOption("auth-token-file", "authorization token config file").OptionalArgument("PATH");
+ opts.AddLongOption("auth-token-file", "authorization token config file").OptionalArgument("PATH");
opts.AddLongOption("key-file", "encryption key config file").OptionalArgument("PATH");
opts.AddLongOption("sqs-file", "SQS config file").OptionalArgument("PATH");
- opts.AddLongOption("alloc-file", "Allocator config file").OptionalArgument("PATH");
+ opts.AddLongOption("alloc-file", "Allocator config file").OptionalArgument("PATH");
opts.AddLongOption("yql-file", "Yql Analytics config file").OptionalArgument("PATH");
opts.AddLongOption("yq-file", "Yandex Query config file").OptionalArgument("PATH");
}
@@ -112,10 +112,10 @@ void TRunCommandConfigParser::ParseConfigFiles(const NLastGetopt::TOptsParseResu
if (res.Has("bootstrap-file")) {
Y_VERIFY(ParsePBFromFile(res.Get("bootstrap-file"), Config.AppConfig.MutableBootstrapConfig()));
}
-
- if (res.Has("vdisk-file")) {
+
+ if (res.Has("vdisk-file")) {
Y_VERIFY(ParsePBFromFile(res.Get("vdisk-file"), Config.AppConfig.MutableVDiskConfig()));
- }
+ }
if (res.Has("drivemodel-file")) {
Y_VERIFY(ParsePBFromFile(res.Get("drivemodel-file"), Config.AppConfig.MutableDriveModelConfig()));
@@ -184,24 +184,24 @@ void TRunCommandConfigParser::ParseConfigFiles(const NLastGetopt::TOptsParseResu
Y_VERIFY(ParsePBFromFile(res.Get("auth-file"), Config.AppConfig.MutableAuthConfig()));
}
- if (res.Has("auth-token-file")) {
- Y_VERIFY(ParsePBFromFile(res.Get("auth-token-file"), Config.AppConfig.MutableAuthConfig()));
- }
-
+ if (res.Has("auth-token-file")) {
+ Y_VERIFY(ParsePBFromFile(res.Get("auth-token-file"), Config.AppConfig.MutableAuthConfig()));
+ }
+
if (res.Has("key-file")) {
Y_VERIFY(ParsePBFromFile(res.Get("key-file"), Config.AppConfig.MutableKeyConfig()));
}
-
+
if (res.Has("pdisk-key-file")) {
Y_VERIFY(ParsePBFromFile(res.Get("pdisk-key-file"), Config.AppConfig.MutablePDiskKeyConfig()));
}
- if (res.Has("alloc-file")) {
- Y_VERIFY(ParsePBFromFile(res.Get("alloc-file"), Config.AppConfig.MutableAllocatorConfig()));
- } else {
- auto allocConfig = DummyAllocatorConfig();
- Config.AppConfig.MutableAllocatorConfig()->CopyFrom(*allocConfig);
- }
+ if (res.Has("alloc-file")) {
+ Y_VERIFY(ParsePBFromFile(res.Get("alloc-file"), Config.AppConfig.MutableAllocatorConfig()));
+ } else {
+ auto allocConfig = DummyAllocatorConfig();
+ Config.AppConfig.MutableAllocatorConfig()->CopyFrom(*allocConfig);
+ }
if (res.Has("yq-file")) {
Y_VERIFY(ParsePBFromFile(res.Get("yq-file"), Config.AppConfig.MutableYandexQueryConfig()));
@@ -244,8 +244,8 @@ void TRunCommandConfigParser::ParseRunOpts(int argc, char **argv) {
.RequiredArgument(Sprintf("NUM (0,%d]", NActors::TActorId::MaxNodeId)).Required().StoreResult(&RunOpts.NodeId);
opts.AddLongOption("proxy", "Bind to proxy(-ies)").RequiredArgument("ADDR").AppendTo(&RunOpts.ProxyBindToProxy);
opts.AddLongOption("mon-port", "Monitoring port").OptionalArgument("NUM").StoreResult(&RunOpts.MonitoringPort);
- opts.AddLongOption("mon-address", "Monitoring address").OptionalArgument("ADDR").StoreResult(&RunOpts.MonitoringAddress);
- opts.AddLongOption("mon-threads", "Monitoring http server threads").RequiredArgument("NUM").StoreResult(&RunOpts.MonitoringThreads);
+ opts.AddLongOption("mon-address", "Monitoring address").OptionalArgument("ADDR").StoreResult(&RunOpts.MonitoringAddress);
+ opts.AddLongOption("mon-threads", "Monitoring http server threads").RequiredArgument("NUM").StoreResult(&RunOpts.MonitoringThreads);
SetupLastGetOptForConfigFiles(opts);
opts.AddLongOption("bootstrap-file", "Bootstrap config file").OptionalArgument("PATH");
@@ -346,8 +346,8 @@ void TRunCommandConfigParser::ApplyParsedOptions() {
Config.AppConfig.MutableBootstrapConfig()->MutableCompileServiceConfig()->SetInflightLimit(RunOpts.CompileInflightLimit);
Config.AppConfig.MutableMonitoringConfig()->SetMonitoringPort(RunOpts.MonitoringPort);
- Config.AppConfig.MutableMonitoringConfig()->SetMonitoringAddress(RunOpts.MonitoringAddress);
- Config.AppConfig.MutableMonitoringConfig()->SetMonitoringThreads(RunOpts.MonitoringThreads);
+ Config.AppConfig.MutableMonitoringConfig()->SetMonitoringAddress(RunOpts.MonitoringAddress);
+ Config.AppConfig.MutableMonitoringConfig()->SetMonitoringThreads(RunOpts.MonitoringThreads);
Config.AppConfig.MutableRestartsCountConfig()->SetRestartsCountFile(RunOpts.RestartsCountFile);
}
diff --git a/ydb/core/driver_lib/run/config_parser.h b/ydb/core/driver_lib/run/config_parser.h
index 313bfed645e..5825ec6c49e 100644
--- a/ydb/core/driver_lib/run/config_parser.h
+++ b/ydb/core/driver_lib/run/config_parser.h
@@ -47,8 +47,8 @@ protected:
NBus::TBusServerSessionConfig ProxyBusSessionConfig;
TVector<ui64> ProxyBindToProxy;
ui32 MonitoringPort;
- TString MonitoringAddress;
- ui32 MonitoringThreads;
+ TString MonitoringAddress;
+ ui32 MonitoringThreads;
TString RestartsCountFile;
bool StartTracingBusProxy;
TString TracePath;
diff --git a/ydb/core/driver_lib/run/driver.h b/ydb/core/driver_lib/run/driver.h
index 2089d9143c3..7ad96718d11 100644
--- a/ydb/core/driver_lib/run/driver.h
+++ b/ydb/core/driver_lib/run/driver.h
@@ -15,16 +15,16 @@ namespace NKikimr {
#define MODE_MAP(XX) \
XX(EDM_RUN, "run", "run kikimr node") \
- XX(EDM_SERVER, "server", "run kikimr node") \
- XX(EDM_ADMIN, "admin", "admin running kikimr") \
- XX(EDM_DB, "db", "admin running kikimr") \
- XX(EDM_TABLET, "tablet", "admin running kikimr") \
- XX(EDM_DEBUG, "debug", "admin running kikimr") \
- XX(EDM_BS, "bs", "admin running kikimr") \
- XX(EDM_BLOBSTORAGE, "blobstorage", "admin running kikimr") \
+ XX(EDM_SERVER, "server", "run kikimr node") \
+ XX(EDM_ADMIN, "admin", "admin running kikimr") \
+ XX(EDM_DB, "db", "admin running kikimr") \
+ XX(EDM_TABLET, "tablet", "admin running kikimr") \
+ XX(EDM_DEBUG, "debug", "admin running kikimr") \
+ XX(EDM_BS, "bs", "admin running kikimr") \
+ XX(EDM_BLOBSTORAGE, "blobstorage", "admin running kikimr") \
XX(EDM_CMS, "cms", "admin running kikimr") \
XX(EDM_DISCOVERY, "discovery", "discover endpoints") \
- XX(EDM_WHOAMI, "whoami", "admin running kikimr") \
+ XX(EDM_WHOAMI, "whoami", "admin running kikimr") \
XX(EDM_FORMAT_INFO, "format-info", "read pdisk format info") \
XX(EDM_FORMAT_UTIL, "format-util", "query blob storage format configuration file") \
XX(EDM_NODE_BY_HOST, "node-by-host", "get node id by hostname") \
diff --git a/ydb/core/driver_lib/run/dummy.cpp b/ydb/core/driver_lib/run/dummy.cpp
index f0230122cb8..12624df93ab 100644
--- a/ydb/core/driver_lib/run/dummy.cpp
+++ b/ydb/core/driver_lib/run/dummy.cpp
@@ -53,11 +53,11 @@ TAutoPtr<NKikimrConfig::TChannelProfileConfig> DummyChannelProfileConfig() {
return ret;
}
-
-TAutoPtr<NKikimrConfig::TAllocatorConfig> DummyAllocatorConfig() {
- TAutoPtr<NKikimrConfig::TAllocatorConfig> ret(new NKikimrConfig::TAllocatorConfig());
-
- ret->MutableParam()->insert({"EnableDefrag", "false"});
-
- return ret;
-}
+
+TAutoPtr<NKikimrConfig::TAllocatorConfig> DummyAllocatorConfig() {
+ TAutoPtr<NKikimrConfig::TAllocatorConfig> ret(new NKikimrConfig::TAllocatorConfig());
+
+ ret->MutableParam()->insert({"EnableDefrag", "false"});
+
+ return ret;
+}
diff --git a/ydb/core/driver_lib/run/dummy.h b/ydb/core/driver_lib/run/dummy.h
index 4e3688d61e4..3b546cc1b92 100644
--- a/ydb/core/driver_lib/run/dummy.h
+++ b/ydb/core/driver_lib/run/dummy.h
@@ -4,4 +4,4 @@
TAutoPtr<NKikimrConfig::TActorSystemConfig> DummyActorSystemConfig();
TAutoPtr<NKikimrConfig::TChannelProfileConfig> DummyChannelProfileConfig();
-TAutoPtr<NKikimrConfig::TAllocatorConfig> DummyAllocatorConfig();
+TAutoPtr<NKikimrConfig::TAllocatorConfig> DummyAllocatorConfig();
diff --git a/ydb/core/driver_lib/run/factories.h b/ydb/core/driver_lib/run/factories.h
index cf8c85a21c8..41a45b44e08 100644
--- a/ydb/core/driver_lib/run/factories.h
+++ b/ydb/core/driver_lib/run/factories.h
@@ -54,9 +54,9 @@ struct TModuleFactories {
/// Factory for pdisk's aio engines
std::shared_ptr<NPDisk::IIoContextFactory> IoContextFactory;
- std::function<NActors::TMon* (NActors::TMon::TConfig)> MonitoringFactory;
+ std::function<NActors::TMon* (NActors::TMon::TConfig)> MonitoringFactory;
std::shared_ptr<NSQS::IAuthFactory> SqsAuthFactory;
-
+
~TModuleFactories();
};
diff --git a/ydb/core/driver_lib/run/kikimr_services_initializers.cpp b/ydb/core/driver_lib/run/kikimr_services_initializers.cpp
index c9a95ccd683..819c1478d19 100644
--- a/ydb/core/driver_lib/run/kikimr_services_initializers.cpp
+++ b/ydb/core/driver_lib/run/kikimr_services_initializers.cpp
@@ -56,7 +56,7 @@
#include <ydb/core/test_tablet/state_server_interface.h>
#include <ydb/core/health_check/health_check.h>
-
+
#include <ydb/core/kqp/kqp.h>
#include <ydb/core/kqp/rm/kqp_rm.h>
@@ -660,9 +660,9 @@ void TBasicServicesInitializer::InitializeServices(NActors::TActorSystemSetup* s
}
if (const auto& whiteboardId = NNodeWhiteboard::MakeNodeWhiteboardServiceId(NodeId)) {
- icCommon->InitWhiteboard = [whiteboardId](ui16 port, TActorSystem *actorSystem) {
- actorSystem->Send(whiteboardId, new NNodeWhiteboard::TEvWhiteboard::TEvSystemStateAddEndpoint("ic", Sprintf(":%d", port)));
- };
+ icCommon->InitWhiteboard = [whiteboardId](ui16 port, TActorSystem *actorSystem) {
+ actorSystem->Send(whiteboardId, new NNodeWhiteboard::TEvWhiteboard::TEvSystemStateAddEndpoint("ic", Sprintf(":%d", port)));
+ };
icCommon->UpdateWhiteboard = [whiteboardId](const TString& peer, bool connected, bool green, bool yellow,
bool orange, bool red, TActorSystem *actorSystem) {
actorSystem->Send(whiteboardId, new NNodeWhiteboard::TEvWhiteboard::TEvNodeStateUpdate(
@@ -797,9 +797,9 @@ void TBSNodeWardenInitializer::InitializeServices(NActors::TActorSystemSetup* se
appData->StaticBlobStorageConfig->MergeFrom(bsc.GetServiceSet());
nodeWardenConfig->FeatureFlags = Config.GetFeatureFlags();
nodeWardenConfig->ServiceSet.MergeFrom(bsc.GetServiceSet());
- if (Config.HasVDiskConfig()) {
- nodeWardenConfig->AllVDiskKinds->Merge(Config.GetVDiskConfig());
- }
+ if (Config.HasVDiskConfig()) {
+ nodeWardenConfig->AllVDiskKinds->Merge(Config.GetVDiskConfig());
+ }
if (Config.HasDriveModelConfig()) {
nodeWardenConfig->AllDriveModels->Merge(Config.GetDriveModelConfig());
}
@@ -900,9 +900,9 @@ void TLocalServiceInitializer::InitializeServices(
// setup local
TLocalConfig::TPtr localConfig(new TLocalConfig());
- localConfig->TabletClassInfo[appData->DefaultTabletTypes.SchemeShard] = TLocalConfig::TTabletClassInfo(
+ localConfig->TabletClassInfo[appData->DefaultTabletTypes.SchemeShard] = TLocalConfig::TTabletClassInfo(
new TTabletSetupInfo(&CreateFlatTxSchemeShard, TMailboxType::ReadAsFilled, appData->UserPoolId, TMailboxType::ReadAsFilled, appData->SystemPoolId));
- localConfig->TabletClassInfo[appData->DefaultTabletTypes.DataShard] = TLocalConfig::TTabletClassInfo(
+ localConfig->TabletClassInfo[appData->DefaultTabletTypes.DataShard] = TLocalConfig::TTabletClassInfo(
new TTabletSetupInfo(&CreateDataShard, TMailboxType::ReadAsFilled, appData->UserPoolId, TMailboxType::ReadAsFilled, appData->SystemPoolId));
localConfig->TabletClassInfo[appData->DefaultTabletTypes.KeyValue] = TLocalConfig::TTabletClassInfo(
new TTabletSetupInfo(&CreateKeyValueFlat, TMailboxType::ReadAsFilled, appData->UserPoolId, TMailboxType::ReadAsFilled, appData->SystemPoolId));
@@ -916,7 +916,7 @@ void TLocalServiceInitializer::InitializeServices(
new TTabletSetupInfo(&CreateTxMediator, TMailboxType::Revolving, importantPoolId, TMailboxType::ReadAsFilled, appData->SystemPoolId));
localConfig->TabletClassInfo[appData->DefaultTabletTypes.Kesus] = TLocalConfig::TTabletClassInfo(
new TTabletSetupInfo(&NKesus::CreateKesusTablet, TMailboxType::ReadAsFilled, appData->UserPoolId, TMailboxType::ReadAsFilled, appData->SystemPoolId));
- localConfig->TabletClassInfo[appData->DefaultTabletTypes.Hive] = TLocalConfig::TTabletClassInfo(
+ localConfig->TabletClassInfo[appData->DefaultTabletTypes.Hive] = TLocalConfig::TTabletClassInfo(
new TTabletSetupInfo(&CreateDefaultHive, TMailboxType::ReadAsFilled, importantPoolId, TMailboxType::ReadAsFilled, appData->SystemPoolId));
localConfig->TabletClassInfo[appData->DefaultTabletTypes.SysViewProcessor] = TLocalConfig::TTabletClassInfo(
new TTabletSetupInfo(&NSysView::CreateSysViewProcessor, TMailboxType::ReadAsFilled, appData->UserPoolId, TMailboxType::ReadAsFilled, appData->SystemPoolId));
@@ -1255,7 +1255,7 @@ static TIntrusivePtr<TTabletSetupInfo> CreateTablet(
}
}
- TTabletTypes::EType tabletType = TTabletTypes::StrToType(typeName);
+ TTabletTypes::EType tabletType = TTabletTypes::StrToType(typeName);
ui32 workPoolId = appData->UserPoolId;
if (appData->FeatureFlags.GetImportantTabletsUseSystemPool()) {
@@ -1422,9 +1422,9 @@ TMessageBusServicesInitializer::TMessageBusServicesInitializer(const TKikimrRunC
void TMessageBusServicesInitializer::InitializeServices(NActors::TActorSystemSetup* setup,
const NKikimr::TAppData* appData) {
- if (!IsServiceInitialized(setup, NMsgBusProxy::CreateMsgBusProxyId())
- && Config.HasMessageBusConfig() && Config.GetMessageBusConfig().GetStartBusProxy()) {
- if (IActor *proxy = BusServer.CreateProxy()) {
+ if (!IsServiceInitialized(setup, NMsgBusProxy::CreateMsgBusProxyId())
+ && Config.HasMessageBusConfig() && Config.GetMessageBusConfig().GetStartBusProxy()) {
+ if (IActor *proxy = BusServer.CreateProxy()) {
TDuration pqMetaRefresh = TDuration::MilliSeconds(appData->PQConfig.GetMetaCacheRefreshIntervalMilliSeconds());
if (appData->PQConfig.GetEnabled()) {
setup->LocalServices.emplace_back(
@@ -1435,34 +1435,34 @@ void TMessageBusServicesInitializer::InitializeServices(NActors::TActorSystemSet
)
);
}
- }
-
- if (IActor* traceService = BusServer.CreateMessageBusTraceService()) {
- TActorSetupCmd messageBusTraceServiceSetup(traceService, TMailboxType::HTSwap, appData->IOPoolId);
+ }
+
+ if (IActor* traceService = BusServer.CreateMessageBusTraceService()) {
+ TActorSetupCmd messageBusTraceServiceSetup(traceService, TMailboxType::HTSwap, appData->IOPoolId);
setup->LocalServices.push_back(std::pair<TActorId, TActorSetupCmd>(NMessageBusTracer::MakeMessageBusTraceServiceID(),
- messageBusTraceServiceSetup));
- }
- }
-}
-
-// TSecurityServicesInitializer
-
-TSecurityServicesInitializer::TSecurityServicesInitializer(const TKikimrRunConfig& runConfig, std::shared_ptr<TModuleFactories> factories)
- : IKikimrServicesInitializer(runConfig)
- , Factories(factories)
-{
-}
-
-void TSecurityServicesInitializer::InitializeServices(NActors::TActorSystemSetup* setup,
- const NKikimr::TAppData* appData) {
+ messageBusTraceServiceSetup));
+ }
+ }
+}
+
+// TSecurityServicesInitializer
+
+TSecurityServicesInitializer::TSecurityServicesInitializer(const TKikimrRunConfig& runConfig, std::shared_ptr<TModuleFactories> factories)
+ : IKikimrServicesInitializer(runConfig)
+ , Factories(factories)
+{
+}
+
+void TSecurityServicesInitializer::InitializeServices(NActors::TActorSystemSetup* setup,
+ const NKikimr::TAppData* appData) {
if (!IsServiceInitialized(setup, MakeTicketParserID())) {
- IActor* ticketParser = nullptr;
- if (Factories && Factories->CreateTicketParser) {
- ticketParser = Factories->CreateTicketParser(Config.GetAuthConfig());
- } else {
- ticketParser = CreateTicketParser(Config.GetAuthConfig());
- }
- if (ticketParser) {
+ IActor* ticketParser = nullptr;
+ if (Factories && Factories->CreateTicketParser) {
+ ticketParser = Factories->CreateTicketParser(Config.GetAuthConfig());
+ } else {
+ ticketParser = CreateTicketParser(Config.GetAuthConfig());
+ }
+ if (ticketParser) {
setup->LocalServices.push_back(std::pair<TActorId, TActorSetupCmd>(MakeTicketParserID(),
TActorSetupCmd(ticketParser, TMailboxType::HTSwap, appData->UserPoolId)));
}
@@ -1712,21 +1712,21 @@ void TWhiteBoardServiceInitializer::InitializeServices(NActors::TActorSystemSetu
appData->SystemPoolId)));
}
-// TNodeIdentifierInitializer
-
-TNodeIdentifierInitializer::TNodeIdentifierInitializer(const TKikimrRunConfig& runConfig)
- : IKikimrServicesInitializer(runConfig) {
-}
-
-void TNodeIdentifierInitializer::InitializeServices(NActors::TActorSystemSetup* setup,
- const NKikimr::TAppData* appData) {
- IActor* nodeIdentifier = CreateNodeIdentifier();
+// TNodeIdentifierInitializer
+
+TNodeIdentifierInitializer::TNodeIdentifierInitializer(const TKikimrRunConfig& runConfig)
+ : IKikimrServicesInitializer(runConfig) {
+}
+
+void TNodeIdentifierInitializer::InitializeServices(NActors::TActorSystemSetup* setup,
+ const NKikimr::TAppData* appData) {
+ IActor* nodeIdentifier = CreateNodeIdentifier();
setup->LocalServices.push_back(std::pair<TActorId, TActorSetupCmd>(MakeNodeIdentifierServiceId(),
- TActorSetupCmd(nodeIdentifier,
- TMailboxType::Simple,
- appData->IOPoolId)));
-}
-
+ TActorSetupCmd(nodeIdentifier,
+ TMailboxType::Simple,
+ appData->IOPoolId)));
+}
+
// TTabletMonitorInitializer
TTabletMonitorInitializer::TTabletMonitorInitializer(
@@ -1747,25 +1747,25 @@ void TTabletMonitorInitializer::InitializeServices(NActors::TActorSystemSetup* s
appData->UserPoolId)));
}
-// TViewerInitializer
-
+// TViewerInitializer
+
TViewerInitializer::TViewerInitializer(const TKikimrRunConfig& runConfig)
- : IKikimrServicesInitializer(runConfig)
- , KikimrRunConfig(runConfig)
-{}
-
-void TViewerInitializer::InitializeServices(NActors::TActorSystemSetup* setup,
- const NKikimr::TAppData* appData) {
+ : IKikimrServicesInitializer(runConfig)
+ , KikimrRunConfig(runConfig)
+{}
+
+void TViewerInitializer::InitializeServices(NActors::TActorSystemSetup* setup,
+ const NKikimr::TAppData* appData) {
using namespace NViewer;
IActor* viewer = CreateViewer(KikimrRunConfig);
SetupPQVirtualHandlers(dynamic_cast<IViewer*>(viewer));
SetupDBVirtualHandlers(dynamic_cast<IViewer*>(viewer));
setup->LocalServices.push_back(std::pair<TActorId, TActorSetupCmd>(MakeViewerID(NodeId),
- TActorSetupCmd(viewer,
+ TActorSetupCmd(viewer,
TMailboxType::HTSwap,
- appData->BatchPoolId)));
-}
-
+ appData->BatchPoolId)));
+}
+
// TLoadInitializer
TLoadInitializer::TLoadInitializer(const TKikimrRunConfig& runConfig)
@@ -2239,17 +2239,17 @@ void TYqlLogsInitializer::InitializeServices(TActorSystemSetup* setup, const TAp
));
}
-THealthCheckInitializer::THealthCheckInitializer(const TKikimrRunConfig& runConfig)
- : IKikimrServicesInitializer(runConfig)
-{
-}
-
-void THealthCheckInitializer::InitializeServices(TActorSystemSetup* setup, const TAppData* appData) {
- setup->LocalServices.push_back(std::pair<TActorId, TActorSetupCmd>(
- NHealthCheck::MakeHealthCheckID(),
- TActorSetupCmd(NHealthCheck::CreateHealthCheckService(), TMailboxType::HTSwap, appData->UserPoolId)));
-}
-
+THealthCheckInitializer::THealthCheckInitializer(const TKikimrRunConfig& runConfig)
+ : IKikimrServicesInitializer(runConfig)
+{
+}
+
+void THealthCheckInitializer::InitializeServices(TActorSystemSetup* setup, const TAppData* appData) {
+ setup->LocalServices.push_back(std::pair<TActorId, TActorSetupCmd>(
+ NHealthCheck::MakeHealthCheckID(),
+ TActorSetupCmd(NHealthCheck::CreateHealthCheckService(), TMailboxType::HTSwap, appData->UserPoolId)));
+}
+
TYandexQueryInitializer::TYandexQueryInitializer(const TKikimrRunConfig& runConfig, std::shared_ptr<TModuleFactories> factories, NYq::IYqSharedResources::TPtr yqSharedResources)
: IKikimrServicesInitializer(runConfig)
, Factories(std::move(factories))
diff --git a/ydb/core/driver_lib/run/kikimr_services_initializers.h b/ydb/core/driver_lib/run/kikimr_services_initializers.h
index 0488327e400..407ce1bb7ba 100644
--- a/ydb/core/driver_lib/run/kikimr_services_initializers.h
+++ b/ydb/core/driver_lib/run/kikimr_services_initializers.h
@@ -243,15 +243,15 @@ public:
void InitializeServices(NActors::TActorSystemSetup *setup, const NKikimr::TAppData *appData) override;
};
-// ticket_parser and so on...
-class TSecurityServicesInitializer : public IKikimrServicesInitializer {
-public:
- std::shared_ptr<TModuleFactories> Factories;
- TSecurityServicesInitializer(const TKikimrRunConfig& runConfig, std::shared_ptr<TModuleFactories> factories);
-
- void InitializeServices(NActors::TActorSystemSetup *setup, const NKikimr::TAppData *appData) override;
-};
-
+// ticket_parser and so on...
+class TSecurityServicesInitializer : public IKikimrServicesInitializer {
+public:
+ std::shared_ptr<TModuleFactories> Factories;
+ TSecurityServicesInitializer(const TKikimrRunConfig& runConfig, std::shared_ptr<TModuleFactories> factories);
+
+ void InitializeServices(NActors::TActorSystemSetup *setup, const NKikimr::TAppData *appData) override;
+};
+
// grpc_proxy
class TGRpcServicesInitializer : public IKikimrServicesInitializer {
private:
@@ -287,13 +287,13 @@ public:
void InitializeServices(NActors::TActorSystemSetup *setup, const NKikimr::TAppData *appData) override;
};
-class TNodeIdentifierInitializer : public IKikimrServicesInitializer {
-public:
- TNodeIdentifierInitializer(const TKikimrRunConfig& runConfig);
-
+class TNodeIdentifierInitializer : public IKikimrServicesInitializer {
+public:
+ TNodeIdentifierInitializer(const TKikimrRunConfig& runConfig);
+
void InitializeServices(NActors::TActorSystemSetup *setup, const NKikimr::TAppData *appData) override;
-};
-
+};
+
class TTabletMonitorInitializer : public IKikimrServicesInitializer {
TIntrusivePtr<NNodeTabletMonitor::ITabletStateClassifier> TabletStateClassifier;
TIntrusivePtr<NNodeTabletMonitor::ITabletListRenderer> TabletListRenderer;
@@ -306,15 +306,15 @@ public:
void InitializeServices(NActors::TActorSystemSetup *setup, const NKikimr::TAppData *appData) override;
};
-class TViewerInitializer : public IKikimrServicesInitializer {
- const TKikimrRunConfig& KikimrRunConfig;
-
-public:
+class TViewerInitializer : public IKikimrServicesInitializer {
+ const TKikimrRunConfig& KikimrRunConfig;
+
+public:
TViewerInitializer(const TKikimrRunConfig& runConfig);
-
+
void InitializeServices(NActors::TActorSystemSetup *setup, const NKikimr::TAppData *appData) override;
-};
-
+};
+
class TLoadInitializer : public IKikimrServicesInitializer {
public:
TLoadInitializer(const TKikimrRunConfig& runConfig);
@@ -479,13 +479,13 @@ public:
void InitializeServices(NActors::TActorSystemSetup* setup, const NKikimr::TAppData* appData) override;
};
-class THealthCheckInitializer : public IKikimrServicesInitializer {
-public:
- THealthCheckInitializer(const TKikimrRunConfig& runConfig);
-
- void InitializeServices(NActors::TActorSystemSetup* setup, const NKikimr::TAppData* appData) override;
-};
-
+class THealthCheckInitializer : public IKikimrServicesInitializer {
+public:
+ THealthCheckInitializer(const TKikimrRunConfig& runConfig);
+
+ void InitializeServices(NActors::TActorSystemSetup* setup, const NKikimr::TAppData* appData) override;
+};
+
class TYandexQueryInitializer : public IKikimrServicesInitializer {
public:
TYandexQueryInitializer(const TKikimrRunConfig& runConfig, std::shared_ptr<TModuleFactories> factories, NYq::IYqSharedResources::TPtr yqSharedResources);
diff --git a/ydb/core/driver_lib/run/main.cpp b/ydb/core/driver_lib/run/main.cpp
index d3b72c6df76..f0a9315685b 100644
--- a/ydb/core/driver_lib/run/main.cpp
+++ b/ydb/core/driver_lib/run/main.cpp
@@ -22,7 +22,7 @@
#endif
namespace NKikimr {
-
+
int MainRun(const TKikimrRunConfig& runConfig, std::shared_ptr<TModuleFactories> factories) {
#ifdef _win32_
WSADATA dummy;
@@ -30,7 +30,7 @@ int MainRun(const TKikimrRunConfig& runConfig, std::shared_ptr<TModuleFactories>
#endif
TKikimrRunner::SetSignalHandlers();
- Cout << "Starting Kikimr r" << GetArcadiaLastChange()
+ Cout << "Starting Kikimr r" << GetArcadiaLastChange()
<< " built by " << GetProgramBuildUser() << Endl;
TIntrusivePtr<TKikimrRunner> runner = TKikimrRunner::CreateKikimrRunner(runConfig, std::move(factories));
@@ -65,11 +65,11 @@ int MainRun(const TKikimrRunConfig& runConfig, std::shared_ptr<TModuleFactories>
TRunCommandConfigParser configParser(runConfig);
TOpts opts = TOpts::Default();
- opts.SetTitle("KiKiMR client/server binary");
+ opts.SetTitle("KiKiMR client/server binary");
configParser.SetupGlobalOpts(opts);
- NMsgBusProxy::TMsgBusClientConfig mbusConfig;
- mbusConfig.ConfigureLastGetopt(opts, "mb-");
+ NMsgBusProxy::TMsgBusClientConfig mbusConfig;
+ mbusConfig.ConfigureLastGetopt(opts, "mb-");
NDriverClient::HideOptions(opts);
opts.AddLongOption('s', "server", "Server address to connect (default $KIKIMR_SERVER)").RequiredArgument("ADDR[:NUM]");
opts.AddLongOption('k', "token", "Security token").RequiredArgument("TOKEN");
@@ -82,7 +82,7 @@ int MainRun(const TKikimrRunConfig& runConfig, std::shared_ptr<TModuleFactories>
opts.SetFreeArgsMin(1);
opts.SetFreeArgTitle(0, "<command>", TDriverModeParser::CommandsCsv());
opts.SetCmdLineDescr(NDriverClient::NewClientCommandsDescription(factories));
-
+
opts.AddHelpOption('h');
opts.ArgPermutation_ = NLastGetopt::REQUIRE_ORDER;
@@ -109,16 +109,16 @@ int MainRun(const TKikimrRunConfig& runConfig, std::shared_ptr<TModuleFactories>
configParser.ApplyParsedOptions();
return MainRun(runConfig, factories);
}
- case EDM_ADMIN:
- case EDM_DB:
- case EDM_TABLET:
- case EDM_DEBUG:
- case EDM_BS:
- case EDM_BLOBSTORAGE:
- case EDM_SERVER:
+ case EDM_ADMIN:
+ case EDM_DB:
+ case EDM_TABLET:
+ case EDM_DEBUG:
+ case EDM_BS:
+ case EDM_BLOBSTORAGE:
+ case EDM_SERVER:
case EDM_CMS:
case EDM_DISCOVERY:
- case EDM_WHOAMI:
+ case EDM_WHOAMI:
return NDriverClient::NewClient(argc + freeArgsPos, argv - freeArgsPos, factories);
case EDM_FORMAT_INFO:
return MainFormatInfo(cmdConf, argc, argv);
@@ -130,8 +130,8 @@ int MainRun(const TKikimrRunConfig& runConfig, std::shared_ptr<TModuleFactories>
return NDriverClient::SchemeInitRoot(cmdConf, argc, argv);
case EDM_COMPILE_AND_EXEC_MINIKQL:
return NDriverClient::CompileAndExecMiniKQL(cmdConf, argc, argv);
- case EDM_TRACE:
- return NDriverClient::MessageBusTrace(cmdConf, argc, argv);
+ case EDM_TRACE:
+ return NDriverClient::MessageBusTrace(cmdConf, argc, argv);
case EDM_KEYVALUE_REQUEST:
return NDriverClient::KeyValueRequest(cmdConf, argc, argv);
case EDM_PERSQUEUE_REQUEST:
diff --git a/ydb/core/driver_lib/run/run.cpp b/ydb/core/driver_lib/run/run.cpp
index 1b0bfe22312..a4f74aa4e0f 100644
--- a/ydb/core/driver_lib/run/run.cpp
+++ b/ydb/core/driver_lib/run/run.cpp
@@ -74,7 +74,7 @@
#include <ydb/core/client/server/msgbus_server_pq_metacache.h>
#include <ydb/core/client/server/msgbus_server_tracer.h>
#include <ydb/core/client/server/http_ping.h>
-
+
#include <library/cpp/grpc/server/actors/logger.h>
#include <ydb/services/yq/private_grpc.h>
@@ -122,7 +122,7 @@
#include <util/system/file.h>
#include <util/system/getpid.h>
#include <util/system/hostname.h>
-
+
#include <ydb/core/tracing/tablet_info.h>
namespace NKikimr {
@@ -187,21 +187,21 @@ public:
for (const NKikimrConfig::TDomainsConfig::TNamedCompactionPolicy &policy : Config.GetDomainsConfig().GetNamedCompactionPolicy()) {
appData->DomainsInfo->AddCompactionPolicy(policy.GetName(), new NLocalDb::TCompactionPolicy(policy.GetPolicy()));
}
-
- const auto& securityConfig(Config.GetDomainsConfig().GetSecurityConfig());
-
- appData->EnforceUserTokenRequirement = securityConfig.GetEnforceUserTokenRequirement();
- if (securityConfig.AdministrationAllowedSIDsSize() > 0) {
- TVector<TString> administrationAllowedSIDs(securityConfig.GetAdministrationAllowedSIDs().begin(), securityConfig.GetAdministrationAllowedSIDs().end());
- appData->AdministrationAllowedSIDs = std::move(administrationAllowedSIDs);
- }
- if (securityConfig.DefaultUserSIDsSize() > 0) {
- TVector<TString> defaultUserSIDs(securityConfig.GetDefaultUserSIDs().begin(), securityConfig.GetDefaultUserSIDs().end());
- appData->DefaultUserSIDs = std::move(defaultUserSIDs);
- }
- appData->AllAuthenticatedUsers = securityConfig.GetAllAuthenticatedUsers();
-
- appData->FeatureFlags = Config.GetFeatureFlags();
+
+ const auto& securityConfig(Config.GetDomainsConfig().GetSecurityConfig());
+
+ appData->EnforceUserTokenRequirement = securityConfig.GetEnforceUserTokenRequirement();
+ if (securityConfig.AdministrationAllowedSIDsSize() > 0) {
+ TVector<TString> administrationAllowedSIDs(securityConfig.GetAdministrationAllowedSIDs().begin(), securityConfig.GetAdministrationAllowedSIDs().end());
+ appData->AdministrationAllowedSIDs = std::move(administrationAllowedSIDs);
+ }
+ if (securityConfig.DefaultUserSIDsSize() > 0) {
+ TVector<TString> defaultUserSIDs(securityConfig.GetDefaultUserSIDs().begin(), securityConfig.GetDefaultUserSIDs().end());
+ appData->DefaultUserSIDs = std::move(defaultUserSIDs);
+ }
+ appData->AllAuthenticatedUsers = securityConfig.GetAllAuthenticatedUsers();
+
+ appData->FeatureFlags = Config.GetFeatureFlags();
appData->AllowHugeKeyValueDeletes = Config.GetFeatureFlags().GetAllowHugeKeyValueDeletes();
appData->EnableKqpSpilling = Config.GetTableServiceConfig().GetSpillingServiceConfig().GetLocalFileConfig().GetEnable();
@@ -248,7 +248,7 @@ public:
ythrow yexception() << "wrong erasure species \"" << name << "\"";
}
const ui64 pDiskCategory = channel.GetPDiskCategory();
- const NKikimrBlobStorage::TVDiskKind::EVDiskKind vDiskCategory = static_cast<NKikimrBlobStorage::TVDiskKind::EVDiskKind>(channel.GetVDiskCategory());
+ const NKikimrBlobStorage::TVDiskKind::EVDiskKind vDiskCategory = static_cast<NKikimrBlobStorage::TVDiskKind::EVDiskKind>(channel.GetVDiskCategory());
const TString kind = channel.GetStoragePoolKind();
outProfile.Channels.push_back(TChannelProfiles::TProfile::TChannel(erasure, pDiskCategory, vDiskCategory, kind));
@@ -338,59 +338,59 @@ TKikimrRunner::~TKikimrRunner() {
}
}
-
+
void TKikimrRunner::InitializeMonitoring(const TKikimrRunConfig& runConfig, bool includeHostName)
{
const auto& appConfig = runConfig.AppConfig;
- NActors::TMon::TConfig monConfig;
- monConfig.Port = appConfig.HasMonitoringConfig() ? appConfig.GetMonitoringConfig().GetMonitoringPort() : 0;
- if (monConfig.Port) {
- monConfig.Title = appConfig.HasMonitoringConfig() ? appConfig.GetMonitoringConfig().GetMonitoringCaption() : "YDB Monitoring";
- monConfig.Threads = appConfig.GetMonitoringConfig().GetMonitoringThreads();
- monConfig.Address = appConfig.GetMonitoringConfig().GetMonitoringAddress();
+ NActors::TMon::TConfig monConfig;
+ monConfig.Port = appConfig.HasMonitoringConfig() ? appConfig.GetMonitoringConfig().GetMonitoringPort() : 0;
+ if (monConfig.Port) {
+ monConfig.Title = appConfig.HasMonitoringConfig() ? appConfig.GetMonitoringConfig().GetMonitoringCaption() : "YDB Monitoring";
+ monConfig.Threads = appConfig.GetMonitoringConfig().GetMonitoringThreads();
+ monConfig.Address = appConfig.GetMonitoringConfig().GetMonitoringAddress();
monConfig.RedirectMainPageTo = appConfig.GetMonitoringConfig().GetRedirectMainPageTo();
if (includeHostName) {
if (appConfig.HasNameserviceConfig() && appConfig.GetNameserviceConfig().NodeSize() > 0) {
for (const auto& it : appConfig.GetNameserviceConfig().GetNode()) {
if (it.HasNodeId() && it.GetNodeId() == runConfig.NodeId) {
if (it.HasHost()) {
- monConfig.Host = it.GetHost();
+ monConfig.Host = it.GetHost();
}
break;
- }
- }
- }
- if (monConfig.Host) {
- monConfig.Title += " - " + monConfig.Host;
- }
- }
-
- const auto& securityConfig(runConfig.AppConfig.GetDomainsConfig().GetSecurityConfig());
- if (securityConfig.MonitoringAllowedSIDsSize() > 0) {
- monConfig.AllowedSIDs.assign(securityConfig.GetMonitoringAllowedSIDs().begin(), securityConfig.GetMonitoringAllowedSIDs().end());
- }
-
- if (ModuleFactories && ModuleFactories->MonitoringFactory) {
- Monitoring = ModuleFactories->MonitoringFactory(std::move(monConfig));
+ }
+ }
+ }
+ if (monConfig.Host) {
+ monConfig.Title += " - " + monConfig.Host;
+ }
+ }
+
+ const auto& securityConfig(runConfig.AppConfig.GetDomainsConfig().GetSecurityConfig());
+ if (securityConfig.MonitoringAllowedSIDsSize() > 0) {
+ monConfig.AllowedSIDs.assign(securityConfig.GetMonitoringAllowedSIDs().begin(), securityConfig.GetMonitoringAllowedSIDs().end());
+ }
+
+ if (ModuleFactories && ModuleFactories->MonitoringFactory) {
+ Monitoring = ModuleFactories->MonitoringFactory(std::move(monConfig));
} else {
- Monitoring = new NActors::TMon(std::move(monConfig));
- }
- if (Monitoring) {
- Monitoring->RegisterCountersPage("counters", "Counters", Counters);
- Monitoring->Register(NHttp::CreatePing());
- ActorsMonPage = Monitoring->RegisterIndexPage("actors", "Actors");
- }
+ Monitoring = new NActors::TMon(std::move(monConfig));
+ }
+ if (Monitoring) {
+ Monitoring->RegisterCountersPage("counters", "Counters", Counters);
+ Monitoring->Register(NHttp::CreatePing());
+ ActorsMonPage = Monitoring->RegisterIndexPage("actors", "Actors");
+ }
}
}
-
-void TKikimrRunner::InitializeMonitoringLogin(const TKikimrRunConfig&)
-{
- if (Monitoring) {
- Monitoring->Register(CreateLoginPage(ActorSystem.Get()));
- Monitoring->Register(CreateLogoutPage(ActorSystem.Get()));
- }
-}
-
+
+void TKikimrRunner::InitializeMonitoringLogin(const TKikimrRunConfig&)
+{
+ if (Monitoring) {
+ Monitoring->Register(CreateLoginPage(ActorSystem.Get()));
+ Monitoring->Register(CreateLogoutPage(ActorSystem.Get()));
+ }
+}
+
void TKikimrRunner::InitializeControlBoard(const TKikimrRunConfig& runConfig)
{
if (Monitoring) {
@@ -447,7 +447,7 @@ void TKikimrRunner::InitializeMessageBus(
factories ? factories->PQReadSessionsInfoWorkerFactory : nullptr,
msgbusConfig.GetBusProxyPort())
);
- }
+ }
else {
BusServer.Reset(NMsgBusProxy::CreateMsgBusServer(
Bus.Get(),
@@ -484,61 +484,61 @@ void TKikimrRunner::InitializeKqpController(const TKikimrRunConfig& runConfig) {
void TKikimrRunner::InitializeGRpc(const TKikimrRunConfig& runConfig) {
const auto& appConfig = runConfig.AppConfig;
- auto fillFn = [&](const NKikimrConfig::TGRpcConfig& grpcConfig, NGrpc::TGRpcServer& server, NGrpc::TServerOptions& opts) {
- const auto& services = grpcConfig.GetServices();
-
- std::unordered_map<TString, bool*> names;
-
+ auto fillFn = [&](const NKikimrConfig::TGRpcConfig& grpcConfig, NGrpc::TGRpcServer& server, NGrpc::TServerOptions& opts) {
+ const auto& services = grpcConfig.GetServices();
+
+ std::unordered_map<TString, bool*> names;
+
bool hasLegacy = opts.SslData.Empty() && services.empty();
- names["legacy"] = &hasLegacy;
+ names["legacy"] = &hasLegacy;
bool hasScripting = services.empty();
- names["scripting"] = &hasScripting;
+ names["scripting"] = &hasScripting;
bool hasCms = services.empty();
- names["cms"] = &hasCms;
+ names["cms"] = &hasCms;
bool hasKesus = services.empty();
- names["locking"] = names["kesus"] = &hasKesus;
- bool hasMonitoring = services.empty();
- names["monitoring"] = &hasMonitoring;
+ names["locking"] = names["kesus"] = &hasKesus;
+ bool hasMonitoring = services.empty();
+ names["monitoring"] = &hasMonitoring;
bool hasDiscovery = services.empty();
- names["discovery"] = &hasDiscovery;
+ names["discovery"] = &hasDiscovery;
bool hasTableService = services.empty();
- names["table_service"] = &hasTableService;
+ names["table_service"] = &hasTableService;
bool hasSchemeService = false;
bool hasOperationService = false;
- bool hasYql = false;
- names["yql"] = &hasYql;
+ bool hasYql = false;
+ names["yql"] = &hasYql;
bool hasYqlInternal = services.empty();
- names["yql_internal"] = &hasYqlInternal;
+ names["yql_internal"] = &hasYqlInternal;
bool hasPQ = services.empty();
- names["pq"] = &hasPQ;
+ names["pq"] = &hasPQ;
bool hasPQv1 = false;
- names["pqv1"] = &hasPQv1;
+ names["pqv1"] = &hasPQv1;
bool hasPQCD = false;
- names["pqcd"] = &hasPQCD;
+ names["pqcd"] = &hasPQCD;
bool hasS3Internal = false;
- names["s3_internal"] = &hasS3Internal;
+ names["s3_internal"] = &hasS3Internal;
bool hasExperimental = false;
- names["experimental"] = &hasExperimental;
+ names["experimental"] = &hasExperimental;
bool hasClickhouseInternal = services.empty();
- names["clickhouse_internal"] = &hasClickhouseInternal;
+ names["clickhouse_internal"] = &hasClickhouseInternal;
bool hasRateLimiter = false;
- names["rate_limiter"] = &hasRateLimiter;
+ names["rate_limiter"] = &hasRateLimiter;
bool hasLongTx = false;
- names["long_tx"] = &hasLongTx;
+ names["long_tx"] = &hasLongTx;
bool hasExport = services.empty();
- names["export"] = &hasExport;
+ names["export"] = &hasExport;
bool hasImport = services.empty();
- names["import"] = &hasImport;
+ names["import"] = &hasImport;
bool hasAnalytics = false;
- names["analytics"] = &hasAnalytics;
+ names["analytics"] = &hasAnalytics;
bool hasDataStreams = false;
- names["datastreams"] = &hasDataStreams;
+ names["datastreams"] = &hasDataStreams;
bool hasYandexQuery = false;
- names["yq"] = &hasYandexQuery;
+ names["yq"] = &hasYandexQuery;
bool hasLogStore = false;
- names["logstore"] = &hasLogStore;
- bool hasAuth = services.empty();
- names["auth"] = &hasAuth;
+ names["logstore"] = &hasLogStore;
+ bool hasAuth = services.empty();
+ names["auth"] = &hasAuth;
std::unordered_set<TString> enabled;
for (const auto& name : services) {
@@ -554,33 +554,33 @@ void TKikimrRunner::InitializeGRpc(const TKikimrRunConfig& runConfig) {
}
for (const auto& name : enabled) {
- auto itName = names.find(name);
- if (itName != names.end()) {
- *(itName->second) = true;
+ auto itName = names.find(name);
+ if (itName != names.end()) {
+ *(itName->second) = true;
} else if (!ModuleFactories || !ModuleFactories->GrpcServiceFactory.Has(name)) {
- Cerr << "Unknown grpc service \"" << name << "\" was not enabled!" << Endl;
- }
- }
-
+ Cerr << "Unknown grpc service \"" << name << "\" was not enabled!" << Endl;
+ }
+ }
+
for (const auto& name : disabled) {
- auto itName = names.find(name);
- if (itName != names.end()) {
- *(itName->second) = false;
+ auto itName = names.find(name);
+ if (itName != names.end()) {
+ *(itName->second) = false;
} else if (!ModuleFactories || !ModuleFactories->GrpcServiceFactory.Has(name)) {
- Cerr << "Unknown grpc service \"" << name << "\" was not disabled!" << Endl;
- }
- }
-
+ Cerr << "Unknown grpc service \"" << name << "\" was not disabled!" << Endl;
+ }
+ }
+
// dependencies
if (hasRateLimiter) {
hasKesus = true;
}
- if (hasYql) {
- hasTableService = true;
- hasYqlInternal = true;
- }
-
+ if (hasYql) {
+ hasTableService = true;
+ hasYqlInternal = true;
+ }
+
if (hasTableService || hasYqlInternal || hasPQ || hasKesus || hasPQv1 || hasExport || hasImport) {
hasSchemeService = true;
hasOperationService = true;
@@ -700,15 +700,15 @@ void TKikimrRunner::InitializeGRpc(const TKikimrRunConfig& runConfig) {
if (hasRateLimiter) {
server.AddService(new NQuoter::TRateLimiterGRpcService(ActorSystem.Get(), Counters, grpcRequestProxyId));
}
-
- if (hasMonitoring) {
- server.AddService(new NGRpcService::TGRpcMonitoringService(ActorSystem.Get(), Counters, grpcRequestProxyId));
- }
- if (hasAuth) {
- server.AddService(new NGRpcService::TGRpcAuthService(ActorSystem.Get(), Counters, grpcRequestProxyId));
- }
-
+ if (hasMonitoring) {
+ server.AddService(new NGRpcService::TGRpcMonitoringService(ActorSystem.Get(), Counters, grpcRequestProxyId));
+ }
+
+ if (hasAuth) {
+ server.AddService(new NGRpcService::TGRpcAuthService(ActorSystem.Get(), Counters, grpcRequestProxyId));
+ }
+
if (hasDataStreams) {
server.AddService(new NGRpcService::TGRpcDataStreamsService(ActorSystem.Get(), Counters, grpcRequestProxyId));
}
@@ -777,14 +777,14 @@ void TKikimrRunner::InitializeGRpc(const TKikimrRunConfig& runConfig) {
GRpcServers.push_back({ "grpcs", new NGrpc::TGRpcServer(sslOpts) });
- fillFn(grpcConfig, *GRpcServers.back().second, sslOpts);
+ fillFn(grpcConfig, *GRpcServers.back().second, sslOpts);
}
- if (grpcConfig.GetPort()) {
+ if (grpcConfig.GetPort()) {
GRpcServers.push_back({ "grpc", new NGrpc::TGRpcServer(opts) });
- fillFn(grpcConfig, *GRpcServers.back().second, opts);
- }
+ fillFn(grpcConfig, *GRpcServers.back().second, opts);
+ }
for (auto &ex : grpcConfig.GetExtEndpoints()) {
// todo: check uniq
@@ -796,7 +796,7 @@ void TKikimrRunner::InitializeGRpc(const TKikimrRunConfig& runConfig) {
xopts.SetHost(ex.GetHost());
GRpcServers.push_back({ "grpc", new NGrpc::TGRpcServer(xopts) });
- fillFn(ex, *GRpcServers.back().second, xopts);
+ fillFn(ex, *GRpcServers.back().second, xopts);
}
if (ex.HasSslPort() && ex.GetSslPort()) {
@@ -815,20 +815,20 @@ void TKikimrRunner::InitializeGRpc(const TKikimrRunConfig& runConfig) {
Y_VERIFY(xopts.SslData->Key, "Key not set");
GRpcServers.push_back({ "grpcs", new NGrpc::TGRpcServer(xopts) });
- fillFn(ex, *GRpcServers.back().second, xopts);
+ fillFn(ex, *GRpcServers.back().second, xopts);
}
}
}
}
-void TKikimrRunner::InitializeAllocator(const TKikimrRunConfig& runConfig) {
- const auto& cfg = runConfig.AppConfig;
- const auto& allocConfig = cfg.GetAllocatorConfig();
- for (const auto& a : allocConfig.GetParam()) {
- NMalloc::MallocInfo().SetParam(a.first.c_str(), a.second.c_str());
- }
-}
-
+void TKikimrRunner::InitializeAllocator(const TKikimrRunConfig& runConfig) {
+ const auto& cfg = runConfig.AppConfig;
+ const auto& allocConfig = cfg.GetAllocatorConfig();
+ for (const auto& a : allocConfig.GetParam()) {
+ NMalloc::MallocInfo().SetParam(a.first.c_str(), a.second.c_str());
+ }
+}
+
void TKikimrRunner::InitializeAppData(const TKikimrRunConfig& runConfig)
{
const auto& cfg = runConfig.AppConfig;
@@ -902,10 +902,10 @@ void TKikimrRunner::InitializeAppData(const TKikimrRunConfig& runConfig)
AppData->PDiskKeyConfig.CopyFrom(runConfig.AppConfig.GetPDiskKeyConfig());
}
- if (runConfig.AppConfig.HasHiveConfig()) {
- AppData->HiveConfig.CopyFrom(runConfig.AppConfig.GetHiveConfig());
- }
-
+ if (runConfig.AppConfig.HasHiveConfig()) {
+ AppData->HiveConfig.CopyFrom(runConfig.AppConfig.GetHiveConfig());
+ }
+
if (runConfig.AppConfig.HasDataShardConfig()) {
AppData->DataShardConfig = runConfig.AppConfig.GetDataShardConfig();
}
@@ -1133,7 +1133,7 @@ TIntrusivePtr<TServiceInitializersList> TKikimrRunner::CreateServiceInitializers
using namespace NKikimrServicesInitializers;
TIntrusivePtr<TServiceInitializersList> sil(new TServiceInitializersList);
-
+
if (serviceMask.EnableMemoryLog) {
sil->AddServiceInitializer(new TMemoryLogInitializer(runConfig));
}
@@ -1147,9 +1147,9 @@ TIntrusivePtr<TServiceInitializersList> TKikimrRunner::CreateServiceInitializers
if (serviceMask.EnableWhiteBoard) {
sil->AddServiceInitializer(new TWhiteBoardServiceInitializer(runConfig));
}
- if (serviceMask.EnableNodeIdentifier) {
- sil->AddServiceInitializer(new TNodeIdentifierInitializer(runConfig));
- }
+ if (serviceMask.EnableNodeIdentifier) {
+ sil->AddServiceInitializer(new TNodeIdentifierInitializer(runConfig));
+ }
if (serviceMask.EnableBSNodeWarden) {
sil->AddServiceInitializer(new TBSNodeWardenInitializer(runConfig));
}
@@ -1206,10 +1206,10 @@ TIntrusivePtr<TServiceInitializersList> TKikimrRunner::CreateServiceInitializers
sil->AddServiceInitializer(new TTxProxyInitializer(runConfig));
}
- if (serviceMask.EnableSecurityServices) {
- sil->AddServiceInitializer(new TSecurityServicesInitializer(runConfig, ModuleFactories));
- }
-
+ if (serviceMask.EnableSecurityServices) {
+ sil->AddServiceInitializer(new TSecurityServicesInitializer(runConfig, ModuleFactories));
+ }
+
if (BusServer && serviceMask.EnableMessageBusServices) {
sil->AddServiceInitializer(new TMessageBusServicesInitializer(runConfig, *BusServer));
}
@@ -1218,10 +1218,10 @@ TIntrusivePtr<TServiceInitializersList> TKikimrRunner::CreateServiceInitializers
sil->AddServiceInitializer(new TMiniKQLCompileServiceInitializer(runConfig));
}
- if (serviceMask.EnableHealthCheckService) {
- sil->AddServiceInitializer(new THealthCheckInitializer(runConfig));
- }
-
+ if (serviceMask.EnableHealthCheckService) {
+ sil->AddServiceInitializer(new THealthCheckInitializer(runConfig));
+ }
+
if (serviceMask.EnableGRpcService) {
sil->AddServiceInitializer(new TGRpcServicesInitializer(runConfig, ModuleFactories));
}
@@ -1441,15 +1441,15 @@ void TKikimrRunner::KikimrStop(bool graceful) {
YdbDriver->Stop(true);
}
- if (Monitoring) {
- Monitoring->Stop();
- }
-
- if (BusMonPage) {
- BusMonPage.Drop();
- }
-
- if (PollerThreads) {
+ if (Monitoring) {
+ Monitoring->Stop();
+ }
+
+ if (BusMonPage) {
+ BusMonPage.Drop();
+ }
+
+ if (PollerThreads) {
PollerThreads->Stop();
}
@@ -1464,7 +1464,7 @@ void TKikimrRunner::KikimrStop(bool graceful) {
}
}
- if (ActorSystem) {
+ if (ActorSystem) {
ActorSystem->Stop();
}
@@ -1472,7 +1472,7 @@ void TKikimrRunner::KikimrStop(bool graceful) {
server.second.Destroy();
}
- if (Bus) {
+ if (Bus) {
Bus->Stop();
Bus.Drop();
}
@@ -1569,7 +1569,7 @@ TIntrusivePtr<TKikimrRunner> TKikimrRunner::CreateKikimrRunner(
runner->InitializeLogSettings(runConfig);
TIntrusivePtr<TServiceInitializersList> sil(runner->CreateServiceInitializersList(runConfig, servicesMask));
runner->InitializeActorSystem(runConfig, sil, servicesMask);
- runner->InitializeMonitoringLogin(runConfig);
+ runner->InitializeMonitoringLogin(runConfig);
runner->InitializeKqpController(runConfig);
runner->InitializeGracefulShutdown(runConfig);
runner->InitializeGRpc(runConfig);
diff --git a/ydb/core/driver_lib/run/run.h b/ydb/core/driver_lib/run/run.h
index a38eb3baf5b..dfd93a24e71 100644
--- a/ydb/core/driver_lib/run/run.h
+++ b/ydb/core/driver_lib/run/run.h
@@ -69,8 +69,8 @@ protected:
virtual void InitializeRegistries(const TKikimrRunConfig& runConfig);
- void InitializeAllocator(const TKikimrRunConfig& runConfig);
-
+ void InitializeAllocator(const TKikimrRunConfig& runConfig);
+
void InitializeLogSettings(const TKikimrRunConfig& runConfig);
void ApplyLogSettings(const TKikimrRunConfig& runConfig);
@@ -79,8 +79,8 @@ protected:
void InitializeControlBoard(const TKikimrRunConfig& runConfig);
- void InitializeMonitoringLogin(const TKikimrRunConfig& runConfig);
-
+ void InitializeMonitoringLogin(const TKikimrRunConfig& runConfig);
+
void InitializeMessageBus(
const TKikimrRunConfig& runConfig,
std::shared_ptr<TModuleFactories> factories = nullptr
diff --git a/ydb/core/engine/mkql_engine_flat_host_ut.cpp b/ydb/core/engine/mkql_engine_flat_host_ut.cpp
index 7618aeb21bc..68679f168df 100644
--- a/ydb/core/engine/mkql_engine_flat_host_ut.cpp
+++ b/ydb/core/engine/mkql_engine_flat_host_ut.cpp
@@ -16,26 +16,26 @@ using namespace NTabletFlatExecutor;
Y_UNIT_TEST_SUITE(TMiniKQLEngineFlatHostTest) {
- struct Schema : NIceDb::Schema {
+ struct Schema : NIceDb::Schema {
struct TestTable : Table<1> {
struct ID : Column<1, NUdf::TDataType<ui64>::Id> {};
struct Value : Column<2, NUdf::TDataType<ui64>::Id> {};
struct Name : Column<3, NUdf::TDataType<NUdf::TUtf8>::Id> {};
struct BoolValue : Column<4, NUdf::TDataType<bool>::Id> {};
- using TKey = TableKey<ID>;
- using TColumns = TableColumns<ID, Value, Name, BoolValue>;
+ using TKey = TableKey<ID>;
+ using TColumns = TableColumns<ID, Value, Name, BoolValue>;
};
struct TestTable2 : Table<2> {
struct ID1 : Column<1, NUdf::TDataType<ui64>::Id> {};
struct ID2 : Column<2, NUdf::TDataType<ui64>::Id> {};
- using TKey = TableKey<ID1, ID2>;
- using TColumns = TableColumns<ID1, ID2>;
+ using TKey = TableKey<ID1, ID2>;
+ using TColumns = TableColumns<ID1, ID2>;
};
- using TTables = SchemaTables<TestTable, TestTable2>;
+ using TTables = SchemaTables<TestTable, TestTable2>;
};
@@ -48,12 +48,12 @@ Y_UNIT_TEST_SUITE(TMiniKQLEngineFlatHostTest) {
Y_UNIT_TEST(Basic) {
NTable::TDatabase DB;
- NIceDb::TNiceDb db(DB);
+ NIceDb::TNiceDb db(DB);
{ // Create tables
NTable::TDummyEnv env;
DB.Begin(1, env);
- db.Materialize<Schema>();
+ db.Materialize<Schema>();
DB.Commit(1, true);
}
@@ -84,12 +84,12 @@ Y_UNIT_TEST_SUITE(TMiniKQLEngineFlatHostTest) {
NTable::TDummyEnv env;
DB.Begin(4, env);
for (ui64 i = 0; i < 1000; ++i) {
- auto row = db.Table<Schema::TestTable>().Key(i).Select<Schema::TestTable::Value, Schema::TestTable::Name, Schema::TestTable::BoolValue>();
- UNIT_ASSERT(row.IsReady());
- UNIT_ASSERT(row.IsValid());
- ui64 value = row.GetValue<Schema::TestTable::Value>();
+ auto row = db.Table<Schema::TestTable>().Key(i).Select<Schema::TestTable::Value, Schema::TestTable::Name, Schema::TestTable::BoolValue>();
+ UNIT_ASSERT(row.IsReady());
+ UNIT_ASSERT(row.IsValid());
+ ui64 value = row.GetValue<Schema::TestTable::Value>();
TString name = row.GetValue<Schema::TestTable::Name>();
- bool boolValue = row.GetValue<Schema::TestTable::BoolValue>();
+ bool boolValue = row.GetValue<Schema::TestTable::BoolValue>();
UNIT_ASSERT(value == i);
UNIT_ASSERT(ToString(value) == name);
UNIT_ASSERT(boolValue == (i % 2 == 0));
diff --git a/ydb/core/engine/mkql_engine_flat_ut.cpp b/ydb/core/engine/mkql_engine_flat_ut.cpp
index 31542d4d83e..e2b12e2d7a5 100644
--- a/ydb/core/engine/mkql_engine_flat_ut.cpp
+++ b/ydb/core/engine/mkql_engine_flat_ut.cpp
@@ -24,28 +24,28 @@ namespace {
const ui64 Table1Id = 301;
const ui64 Table2Id = 302;
- struct Schema1 : NIceDb::Schema {
+ struct Schema1 : NIceDb::Schema {
struct Table1 : Table<Table1Id> {
struct ID : Column<1, NUdf::TDataType<ui32>::Id> {};
struct Value : Column<2, NUdf::TDataType<NUdf::TUtf8>::Id> {};
- using TKey = TableKey<ID>;
- using TColumns = TableColumns<ID, Value>;
+ using TKey = TableKey<ID>;
+ using TColumns = TableColumns<ID, Value>;
};
- using TTables = SchemaTables<Table1>;
+ using TTables = SchemaTables<Table1>;
};
- struct Schema2 : NIceDb::Schema {
+ struct Schema2 : NIceDb::Schema {
struct Table2 : Table<Table2Id> {
struct ID : Column<3, NUdf::TDataType<ui64>::Id> {};
struct Value : Column<4, NUdf::TDataType<ui32>::Id> {};
- using TKey = TableKey<ID>;
- using TColumns = TableColumns<ID, Value>;
+ using TKey = TableKey<ID>;
+ using TColumns = TableColumns<ID, Value>;
};
- using TTables = SchemaTables<Table2>;
+ using TTables = SchemaTables<Table2>;
};
struct TShardDbState {
@@ -62,7 +62,7 @@ namespace {
{ // Create tables
BeginTransaction(tabletId);
- NIceDb::TNiceDb(*db).Materialize<TSchema>();
+ NIceDb::TNiceDb(*db).Materialize<TSchema>();
CommitTransaction(tabletId);
}
}
@@ -341,7 +341,7 @@ Y_UNIT_TEST_SUITE(TMiniKQLEngineFlatTest) {
Y_UNIT_TEST(TestEmptyProgram) {
TDriver driver;
auto& pgmBuilder = driver.PgmBuilder;
- auto pgm = pgmBuilder.Build(pgmBuilder.NewEmptyListOfVoid());
+ auto pgm = pgmBuilder.Build(pgmBuilder.NewEmptyListOfVoid());
NKikimrMiniKQL::TResult res;
UNIT_ASSERT_EQUAL(driver.Run(pgm, res, &EmptyShardResolver), IEngineFlat::EStatus::Complete);
diff --git a/ydb/core/engine/mkql_proto.cpp b/ydb/core/engine/mkql_proto.cpp
index 6bb362a29e9..3dd053e3724 100644
--- a/ydb/core/engine/mkql_proto.cpp
+++ b/ydb/core/engine/mkql_proto.cpp
@@ -160,26 +160,26 @@ NUdf::TUnboxedValue ImportValueFromProto(TType* type, const Ydb::Value& value, c
}
-template <typename ValType>
-class TAlmostDoneTypeValue : public TRawTypeValue {
-public:
+template <typename ValType>
+class TAlmostDoneTypeValue : public TRawTypeValue {
+public:
TAlmostDoneTypeValue(NUdf::TDataTypeId schemeType, ValType value)
- : TRawTypeValue(&Value, sizeof(Value), schemeType)
- , Value(value)
- {}
-
-protected:
- ValType Value;
-};
-
-template <>
+ : TRawTypeValue(&Value, sizeof(Value), schemeType)
+ , Value(value)
+ {}
+
+protected:
+ ValType Value;
+};
+
+template <>
class TAlmostDoneTypeValue<TString> : public TRawTypeValue {
-public:
+public:
TAlmostDoneTypeValue(NUdf::TDataTypeId schemeType, const TString& value)
- : TRawTypeValue(value.data(), value.size(), schemeType)
- {}
-};
-
+ : TRawTypeValue(value.data(), value.size(), schemeType)
+ {}
+};
+
// NOTE: TCell's can reference memomry from tupleValue
bool CellsFromTuple(const NKikimrMiniKQL::TType* tupleType,
const NKikimrMiniKQL::TValue& tupleValue,
diff --git a/ydb/core/grpc_services/base/base.h b/ydb/core/grpc_services/base/base.h
index 963a2d0c9be..44b25c4a5f9 100644
--- a/ydb/core/grpc_services/base/base.h
+++ b/ydb/core/grpc_services/base/base.h
@@ -118,7 +118,7 @@ struct TRpcServices {
EvKikhouseRefreshSnapshot,
EvKikhouseDiscardSnapshot,
EvExportToS3,
- EvSelfCheck,
+ EvSelfCheck,
EvStreamExecuteScanQuery,
EvPQDropTopic,
EvPQCreateTopic,
@@ -195,9 +195,9 @@ struct TRpcServices {
EvDropLogStore,
EvCreateLogTable,
EvDescribeLogTable,
- EvDropLogTable,
+ EvDropLogTable,
EvAlterLogTable,
- EvLogin,
+ EvLogin,
EvAnalyticsInternalPingTask,
EvAnalyticsInternalGetTask,
EvAnalyticsInternalWriteTaskResult,
@@ -314,7 +314,7 @@ public:
struct TRequestAuxSettings {
TRateLimiterMode RlMode = TRateLimiterMode::Off;
- void (*CustomAttributeProcessor)(const TSchemeBoardEvents::TDescribeSchemeResult& schemeData, ICheckerIface*) = nullptr;
+ void (*CustomAttributeProcessor)(const TSchemeBoardEvents::TDescribeSchemeResult& schemeData, ICheckerIface*) = nullptr;
};
// grpc_request_proxy part
@@ -339,7 +339,7 @@ public:
virtual void SetRespHook(TRespHook&& hook) = 0;
virtual void SetRlPath(TMaybe<NRpcService::TRlPath>&& path) = 0;
virtual TRateLimiterMode GetRlMode() const = 0;
- virtual bool TryCustomAttributeProcess(const TSchemeBoardEvents::TDescribeSchemeResult& schemeData,
+ virtual bool TryCustomAttributeProcess(const TSchemeBoardEvents::TDescribeSchemeResult& schemeData,
ICheckerIface* iface) = 0;
// Pass request for next processing
@@ -442,10 +442,10 @@ public:
return InternalToken_;
}
- TString GetPeerName() const override {
- return {};
- }
-
+ TString GetPeerName() const override {
+ return {};
+ }
+
void SetRlPath(TMaybe<NRpcService::TRlPath>&&) override {}
TMaybe<NRpcService::TRlPath> GetRlPath() const override {
@@ -511,10 +511,10 @@ public:
void SetRespHook(TRespHook&&) override { /* do nothing */}
TRateLimiterMode GetRlMode() const override {
- return TRateLimiterMode::Off;
- }
-
- bool TryCustomAttributeProcess(const TSchemeBoardEvents::TDescribeSchemeResult&, ICheckerIface*) override {
+ return TRateLimiterMode::Off;
+ }
+
+ bool TryCustomAttributeProcess(const TSchemeBoardEvents::TDescribeSchemeResult&, ICheckerIface*) override {
return false;
}
@@ -554,7 +554,7 @@ public:
return TRateLimiterMode::Off;
}
- bool TryCustomAttributeProcess(const TSchemeBoardEvents::TDescribeSchemeResult&, ICheckerIface*) override {
+ bool TryCustomAttributeProcess(const TSchemeBoardEvents::TDescribeSchemeResult&, ICheckerIface*) override {
return false;
}
@@ -630,10 +630,10 @@ public:
return InternalToken_;
}
- TString GetPeerName() const override {
- return Ctx_->GetPeerName();
- }
-
+ TString GetPeerName() const override {
+ return Ctx_->GetPeerName();
+ }
+
bool Validate(TString&) override {
return true;
}
@@ -1050,7 +1050,7 @@ public:
return AuxSettings.RlMode;
}
- bool TryCustomAttributeProcess(const TSchemeBoardEvents::TDescribeSchemeResult& schemeData,
+ bool TryCustomAttributeProcess(const TSchemeBoardEvents::TDescribeSchemeResult& schemeData,
ICheckerIface* iface) override
{
if (!AuxSettings.CustomAttributeProcessor) {
@@ -1089,37 +1089,37 @@ public:
return RateLimitMode;
}
- bool TryCustomAttributeProcess(const TSchemeBoardEvents::TDescribeSchemeResult&, ICheckerIface*) override {
+ bool TryCustomAttributeProcess(const TSchemeBoardEvents::TDescribeSchemeResult&, ICheckerIface*) override {
return false;
}
};
-template<ui32 TRpcId, typename TReq, typename TResp, bool IsOperation = true, TRateLimiterMode RlMode = TRateLimiterMode::Off>
-class TGRpcRequestWrapperNoAuth :
- public TGRpcRequestWrapperImpl<TRpcId, TReq, TResp, IsOperation, TGRpcRequestWrapperNoAuth<TRpcId, TReq, TResp, IsOperation, RlMode>> {
-public:
- static IActor* CreateRpcActor(typename std::conditional<IsOperation, IRequestOpCtx, IRequestNoOpCtx>::type* msg);
- static constexpr bool IsOp = IsOperation;
- static constexpr TRateLimiterMode RateLimitMode = RlMode;
-
- TGRpcRequestWrapperNoAuth(NGrpc::IRequestContextBase* ctx)
- : TGRpcRequestWrapperImpl<TRpcId, TReq, TResp, IsOperation, TGRpcRequestWrapperNoAuth<TRpcId, TReq, TResp, IsOperation, RlMode>>(ctx)
- { }
-
+template<ui32 TRpcId, typename TReq, typename TResp, bool IsOperation = true, TRateLimiterMode RlMode = TRateLimiterMode::Off>
+class TGRpcRequestWrapperNoAuth :
+ public TGRpcRequestWrapperImpl<TRpcId, TReq, TResp, IsOperation, TGRpcRequestWrapperNoAuth<TRpcId, TReq, TResp, IsOperation, RlMode>> {
+public:
+ static IActor* CreateRpcActor(typename std::conditional<IsOperation, IRequestOpCtx, IRequestNoOpCtx>::type* msg);
+ static constexpr bool IsOp = IsOperation;
+ static constexpr TRateLimiterMode RateLimitMode = RlMode;
+
+ TGRpcRequestWrapperNoAuth(NGrpc::IRequestContextBase* ctx)
+ : TGRpcRequestWrapperImpl<TRpcId, TReq, TResp, IsOperation, TGRpcRequestWrapperNoAuth<TRpcId, TReq, TResp, IsOperation, RlMode>>(ctx)
+ { }
+
TRateLimiterMode GetRlMode() const override {
- return RateLimitMode;
- }
-
- bool TryCustomAttributeProcess(const TSchemeBoardEvents::TDescribeSchemeResult&, ICheckerIface*) override {
+ return RateLimitMode;
+ }
+
+ bool TryCustomAttributeProcess(const TSchemeBoardEvents::TDescribeSchemeResult&, ICheckerIface*) override {
return false;
}
- const NGrpc::TAuthState& GetAuthState() const override {
- static NGrpc::TAuthState noAuthState(false);
- return noAuthState;
- }
-};
-
+ const NGrpc::TAuthState& GetAuthState() const override {
+ static NGrpc::TAuthState noAuthState(false);
+ return noAuthState;
+ }
+};
+
template<ui32 TRpcId, typename TReq, typename TResp, bool IsOperation, TRateLimiterMode RlMode = TRateLimiterMode::Off>
class TGRpcRequestValidationWrapper :
public TGRpcRequestWrapperImpl<TRpcId, TReq, TResp, IsOperation, TGRpcRequestValidationWrapper<TRpcId, TReq, TResp, IsOperation, RlMode>> {
@@ -1136,7 +1136,7 @@ public:
return RateLimitMode;
}
- bool TryCustomAttributeProcess(const TSchemeBoardEvents::TDescribeSchemeResult&, ICheckerIface*) override {
+ bool TryCustomAttributeProcess(const TSchemeBoardEvents::TDescribeSchemeResult&, ICheckerIface*) override {
return false;
}
diff --git a/ydb/core/grpc_services/grpc_endpoint.h b/ydb/core/grpc_services/grpc_endpoint.h
index 40bd51ab848..b0f592abf8a 100644
--- a/ydb/core/grpc_services/grpc_endpoint.h
+++ b/ydb/core/grpc_services/grpc_endpoint.h
@@ -1,31 +1,31 @@
-#pragma once
-#include "defs.h"
-
-namespace NKikimr {
-namespace NGRpcService {
-
-using namespace NActors;
-
-struct TGrpcEndpointDescription : public TThrRefBase {
- TString Address;
- ui32 Port = 0;
- bool Ssl = false;
-
+#pragma once
+#include "defs.h"
+
+namespace NKikimr {
+namespace NGRpcService {
+
+using namespace NActors;
+
+struct TGrpcEndpointDescription : public TThrRefBase {
+ TString Address;
+ ui32 Port = 0;
+ bool Ssl = false;
+
TVector<TString> AddressesV4;
TVector<TString> AddressesV6;
TString TargetNameOverride;
- TVector<TString> ServedServices;
- TVector<TString> ServedDatabases;
-};
-
-IActor* CreateGrpcEndpointPublishActor(TGrpcEndpointDescription *description);
-IActor* CreateGrpcPublisherServiceActor(TVector<TIntrusivePtr<TGrpcEndpointDescription>>&& endpoints);
-
-inline TActorId CreateGrpcPublisherServiceActorId() {
- const auto actorId = TActorId(0, "GrpcPublishS");
- return actorId;
-}
-
-}
-}
+ TVector<TString> ServedServices;
+ TVector<TString> ServedDatabases;
+};
+
+IActor* CreateGrpcEndpointPublishActor(TGrpcEndpointDescription *description);
+IActor* CreateGrpcPublisherServiceActor(TVector<TIntrusivePtr<TGrpcEndpointDescription>>&& endpoints);
+
+inline TActorId CreateGrpcPublisherServiceActorId() {
+ const auto actorId = TActorId(0, "GrpcPublishS");
+ return actorId;
+}
+
+}
+}
diff --git a/ydb/core/grpc_services/grpc_endpoint_publish_actor.cpp b/ydb/core/grpc_services/grpc_endpoint_publish_actor.cpp
index a940c92c35f..ce65619641b 100644
--- a/ydb/core/grpc_services/grpc_endpoint_publish_actor.cpp
+++ b/ydb/core/grpc_services/grpc_endpoint_publish_actor.cpp
@@ -1,51 +1,51 @@
-#include "grpc_endpoint.h"
-
-#include <util/generic/map.h>
-#include <util/generic/set.h>
-
-#include <library/cpp/actors/core/hfunc.h>
-#include <library/cpp/actors/core/actor_bootstrapped.h>
-#include <library/cpp/actors/interconnect/interconnect.h>
-
+#include "grpc_endpoint.h"
+
+#include <util/generic/map.h>
+#include <util/generic/set.h>
+
+#include <library/cpp/actors/core/hfunc.h>
+#include <library/cpp/actors/core/actor_bootstrapped.h>
+#include <library/cpp/actors/interconnect/interconnect.h>
+
#include <ydb/core/base/appdata.h>
#include <ydb/core/base/location.h>
#include <ydb/core/base/statestorage.h>
#include <ydb/core/mind/tenant_pool.h>
-
-namespace NKikimr {
-namespace NGRpcService {
-
-using namespace NActors;
-
-class TGRpcEndpointPublishActor : public TActorBootstrapped<TGRpcEndpointPublishActor> {
- TIntrusivePtr<TGrpcEndpointDescription> Description;
-
- TString SelfDatacenter;
-
- bool resolvedState;
- TMap<TActorId, TSet<TString>> ServedDatabases;
- TMap<TString, TActorId> PublishedDatabases;
-
- TActorId CreatePublishActor(const TString &database, TString &payload, ui32 nodeId) {
- auto *domains = AppData()->DomainsInfo.Get();
- auto domainName = ExtractDomain(database);
- auto *domainInfo = domains->GetDomainByName(domainName);
- if (!domainInfo)
- return TActorId();
-
- auto statestorageGroupId = domainInfo->DefaultStateStorageGroup;
- auto assignedPath = MakeEndpointsBoardPath(database);
- TActorId &aid = PublishedDatabases[database];
- if (!aid) {
- if (!payload) {
- NKikimrStateStorage::TEndpointBoardEntry entry;
- entry.SetAddress(Description->Address);
- entry.SetPort(Description->Port);
- entry.SetLoad(0.0f);
- entry.SetSsl(Description->Ssl);
- entry.MutableServices()->Reserve(Description->ServedServices.size());
- entry.SetDataCenter(SelfDatacenter);
- entry.SetNodeId(nodeId);
+
+namespace NKikimr {
+namespace NGRpcService {
+
+using namespace NActors;
+
+class TGRpcEndpointPublishActor : public TActorBootstrapped<TGRpcEndpointPublishActor> {
+ TIntrusivePtr<TGrpcEndpointDescription> Description;
+
+ TString SelfDatacenter;
+
+ bool resolvedState;
+ TMap<TActorId, TSet<TString>> ServedDatabases;
+ TMap<TString, TActorId> PublishedDatabases;
+
+ TActorId CreatePublishActor(const TString &database, TString &payload, ui32 nodeId) {
+ auto *domains = AppData()->DomainsInfo.Get();
+ auto domainName = ExtractDomain(database);
+ auto *domainInfo = domains->GetDomainByName(domainName);
+ if (!domainInfo)
+ return TActorId();
+
+ auto statestorageGroupId = domainInfo->DefaultStateStorageGroup;
+ auto assignedPath = MakeEndpointsBoardPath(database);
+ TActorId &aid = PublishedDatabases[database];
+ if (!aid) {
+ if (!payload) {
+ NKikimrStateStorage::TEndpointBoardEntry entry;
+ entry.SetAddress(Description->Address);
+ entry.SetPort(Description->Port);
+ entry.SetLoad(0.0f);
+ entry.SetSsl(Description->Ssl);
+ entry.MutableServices()->Reserve(Description->ServedServices.size());
+ entry.SetDataCenter(SelfDatacenter);
+ entry.SetNodeId(nodeId);
for (const auto& addr : Description->AddressesV4) {
entry.AddAddressesV4(addr);
}
@@ -55,113 +55,113 @@ class TGRpcEndpointPublishActor : public TActorBootstrapped<TGRpcEndpointPublish
if (Description->TargetNameOverride) {
entry.SetTargetNameOverride(Description->TargetNameOverride);
}
- for (const auto &service : Description->ServedServices)
- entry.AddServices(service);
- Y_VERIFY(entry.SerializeToString(&payload));
- }
-
- aid = Register(CreateBoardPublishActor(assignedPath, payload, SelfId(), statestorageGroupId, 0, true));
- }
- return aid;
- }
-
- void Handle(TEvTenantPool::TEvTenantPoolStatus::TPtr &ev) {
- const auto &record = ev->Get()->Record;
-
- auto &served = ServedDatabases[ev->Sender];
- auto toRemove = std::move(served);
- served = TSet<TString>();
-
- TString payload;
-
- for (auto &x : record.GetSlots()) {
- if (const TString &assignedDatabase = x.GetAssignedTenant()) {
- if (toRemove.erase(assignedDatabase) == 0)
- CreatePublishActor(assignedDatabase, payload, SelfId().NodeId());
-
- served.insert(assignedDatabase);
- }
- }
-
- for (auto &x : toRemove) {
- auto it = PublishedDatabases.find(x);
- if (it != PublishedDatabases.end()) {
- LOG_NOTICE_S(*TlsActivationContext, NKikimrServices::GRPC_SERVER, "Stop publish endpoints for database: " << x);
- Send(it->second, new TEvents::TEvPoisonPill());
- PublishedDatabases.erase(it);
- } else {
- LOG_CRIT_S(*TlsActivationContext, NKikimrServices::GRPC_SERVER, "multiple eviction of " << x << " database. Ignoring");
- }
- }
- }
-
- void PassAway() override {
- if (resolvedState) {
- Send(MakeTenantPoolRootID(), new TEvents::TEvUnsubscribe());
- for(const auto& x: PublishedDatabases) {
- LOG_NOTICE_S(*TlsActivationContext, NKikimrServices::GRPC_SERVER, "Stop publish endpoints for database: " << x.first);
- Send(x.second, new TEvents::TEvPoisonPill());
- }
- }
-
- TActor::PassAway();
- }
-
- void Handle(TEvInterconnect::TEvNodeInfo::TPtr &ev) {
- auto *msg = ev->Get();
+ for (const auto &service : Description->ServedServices)
+ entry.AddServices(service);
+ Y_VERIFY(entry.SerializeToString(&payload));
+ }
+
+ aid = Register(CreateBoardPublishActor(assignedPath, payload, SelfId(), statestorageGroupId, 0, true));
+ }
+ return aid;
+ }
+
+ void Handle(TEvTenantPool::TEvTenantPoolStatus::TPtr &ev) {
+ const auto &record = ev->Get()->Record;
+
+ auto &served = ServedDatabases[ev->Sender];
+ auto toRemove = std::move(served);
+ served = TSet<TString>();
+
+ TString payload;
+
+ for (auto &x : record.GetSlots()) {
+ if (const TString &assignedDatabase = x.GetAssignedTenant()) {
+ if (toRemove.erase(assignedDatabase) == 0)
+ CreatePublishActor(assignedDatabase, payload, SelfId().NodeId());
+
+ served.insert(assignedDatabase);
+ }
+ }
+
+ for (auto &x : toRemove) {
+ auto it = PublishedDatabases.find(x);
+ if (it != PublishedDatabases.end()) {
+ LOG_NOTICE_S(*TlsActivationContext, NKikimrServices::GRPC_SERVER, "Stop publish endpoints for database: " << x);
+ Send(it->second, new TEvents::TEvPoisonPill());
+ PublishedDatabases.erase(it);
+ } else {
+ LOG_CRIT_S(*TlsActivationContext, NKikimrServices::GRPC_SERVER, "multiple eviction of " << x << " database. Ignoring");
+ }
+ }
+ }
+
+ void PassAway() override {
+ if (resolvedState) {
+ Send(MakeTenantPoolRootID(), new TEvents::TEvUnsubscribe());
+ for(const auto& x: PublishedDatabases) {
+ LOG_NOTICE_S(*TlsActivationContext, NKikimrServices::GRPC_SERVER, "Stop publish endpoints for database: " << x.first);
+ Send(x.second, new TEvents::TEvPoisonPill());
+ }
+ }
+
+ TActor::PassAway();
+ }
+
+ void Handle(TEvInterconnect::TEvNodeInfo::TPtr &ev) {
+ auto *msg = ev->Get();
if (msg->Node && msg->Node->Location.GetDataCenterId())
SelfDatacenter = msg->Node->Location.GetDataCenterId();
-
- if (Description->ServedDatabases) {
- TString payload;
- for (auto &x : Description->ServedDatabases) {
- ServedDatabases[TActorId()].insert(x);
- CreatePublishActor(x, payload, SelfId().NodeId());
- }
- }
-
- Send(MakeTenantPoolRootID(), new TEvents::TEvSubscribe());
- Become(&TThis::StateWork);
- resolvedState = true;
- }
-public:
- static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
- return NKikimrServices::TActivity::GRPC_ENDPOINT_PUBLISH;
- }
-
- TGRpcEndpointPublishActor(TGrpcEndpointDescription *desc)
- : Description(desc)
- , resolvedState(false)
- {}
-
- void Bootstrap() {
- Become(&TThis::StateResolveDC);
- if (!Description || !Description->Port)
- return; // leave in zombie state for now
-
- Send(GetNameserviceActorId(), new TEvInterconnect::TEvGetNode(SelfId().NodeId()));
- }
-
- STFUNC(StateResolveDC) {
- Y_UNUSED(ctx);
- switch (ev->GetTypeRewrite()) {
- hFunc(TEvInterconnect::TEvNodeInfo, Handle);
- cFunc(TEvents::TEvPoisonPill::EventType, PassAway);
- }
- }
-
- STFUNC(StateWork) {
- Y_UNUSED(ctx);
- switch (ev->GetTypeRewrite()) {
- hFunc(TEvTenantPool::TEvTenantPoolStatus, Handle);
- cFunc(TEvents::TEvPoisonPill::EventType, PassAway);
- }
- }
-};
-
-IActor* CreateGrpcEndpointPublishActor(TGrpcEndpointDescription *description) {
- return new TGRpcEndpointPublishActor(description);
-}
-
-}
+
+ if (Description->ServedDatabases) {
+ TString payload;
+ for (auto &x : Description->ServedDatabases) {
+ ServedDatabases[TActorId()].insert(x);
+ CreatePublishActor(x, payload, SelfId().NodeId());
+ }
+ }
+
+ Send(MakeTenantPoolRootID(), new TEvents::TEvSubscribe());
+ Become(&TThis::StateWork);
+ resolvedState = true;
+ }
+public:
+ static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
+ return NKikimrServices::TActivity::GRPC_ENDPOINT_PUBLISH;
+ }
+
+ TGRpcEndpointPublishActor(TGrpcEndpointDescription *desc)
+ : Description(desc)
+ , resolvedState(false)
+ {}
+
+ void Bootstrap() {
+ Become(&TThis::StateResolveDC);
+ if (!Description || !Description->Port)
+ return; // leave in zombie state for now
+
+ Send(GetNameserviceActorId(), new TEvInterconnect::TEvGetNode(SelfId().NodeId()));
+ }
+
+ STFUNC(StateResolveDC) {
+ Y_UNUSED(ctx);
+ switch (ev->GetTypeRewrite()) {
+ hFunc(TEvInterconnect::TEvNodeInfo, Handle);
+ cFunc(TEvents::TEvPoisonPill::EventType, PassAway);
+ }
+ }
+
+ STFUNC(StateWork) {
+ Y_UNUSED(ctx);
+ switch (ev->GetTypeRewrite()) {
+ hFunc(TEvTenantPool::TEvTenantPoolStatus, Handle);
+ cFunc(TEvents::TEvPoisonPill::EventType, PassAway);
+ }
+ }
+};
+
+IActor* CreateGrpcEndpointPublishActor(TGrpcEndpointDescription *description) {
+ return new TGRpcEndpointPublishActor(description);
+}
+
+}
}
diff --git a/ydb/core/grpc_services/grpc_proxy_counters.h b/ydb/core/grpc_services/grpc_proxy_counters.h
index c0632bb7039..9d936f2ccec 100644
--- a/ydb/core/grpc_services/grpc_proxy_counters.h
+++ b/ydb/core/grpc_services/grpc_proxy_counters.h
@@ -1,47 +1,47 @@
-#pragma once
-#include "defs.h"
-
-#include <library/cpp/monlib/dynamic_counters/counters.h>
-
+#pragma once
+#include "defs.h"
+
+#include <library/cpp/monlib/dynamic_counters/counters.h>
+
#include <ydb/core/base/counters.h>
-
-namespace NKikimr {
-namespace NGRpcService {
-
-class TGrpcProxyCounters : public TThrRefBase {
-public:
- using TPtr = TIntrusivePtr<TGrpcProxyCounters>;
- explicit TGrpcProxyCounters(const TIntrusivePtr<NMonitoring::TDynamicCounters>& counters) {
- auto group = GetServiceCounters(counters, "grpc");
-
- DatabaseAccessDenyCounter_ = group->GetCounter("databaseAccessDeny", true);
- DatabaseSchemeErrorCounter_ = group->GetCounter("databaseSchemeError", true);
- DatabaseUnavailableCounter_ = group->GetCounter("databaseUnavailable", true);
- DatabaseRateLimitedCounter_ = group->GetCounter("databaseRateLimited", true);
- }
-
- void IncDatabaseAccessDenyCounter() {
- DatabaseAccessDenyCounter_->Inc();
- }
-
- void IncDatabaseSchemeErrorCounter() {
- DatabaseSchemeErrorCounter_->Inc();
- }
-
- void IncDatabaseUnavailableCounter() {
- DatabaseUnavailableCounter_->Inc();
- }
-
- void IncDatabaseRateLimitedCounter() {
- DatabaseRateLimitedCounter_->Inc();
- }
-
-private:
- NMonitoring::TDynamicCounters::TCounterPtr DatabaseAccessDenyCounter_;
- NMonitoring::TDynamicCounters::TCounterPtr DatabaseSchemeErrorCounter_;
- NMonitoring::TDynamicCounters::TCounterPtr DatabaseUnavailableCounter_;
- NMonitoring::TDynamicCounters::TCounterPtr DatabaseRateLimitedCounter_;
-};
-
-}
-}
+
+namespace NKikimr {
+namespace NGRpcService {
+
+class TGrpcProxyCounters : public TThrRefBase {
+public:
+ using TPtr = TIntrusivePtr<TGrpcProxyCounters>;
+ explicit TGrpcProxyCounters(const TIntrusivePtr<NMonitoring::TDynamicCounters>& counters) {
+ auto group = GetServiceCounters(counters, "grpc");
+
+ DatabaseAccessDenyCounter_ = group->GetCounter("databaseAccessDeny", true);
+ DatabaseSchemeErrorCounter_ = group->GetCounter("databaseSchemeError", true);
+ DatabaseUnavailableCounter_ = group->GetCounter("databaseUnavailable", true);
+ DatabaseRateLimitedCounter_ = group->GetCounter("databaseRateLimited", true);
+ }
+
+ void IncDatabaseAccessDenyCounter() {
+ DatabaseAccessDenyCounter_->Inc();
+ }
+
+ void IncDatabaseSchemeErrorCounter() {
+ DatabaseSchemeErrorCounter_->Inc();
+ }
+
+ void IncDatabaseUnavailableCounter() {
+ DatabaseUnavailableCounter_->Inc();
+ }
+
+ void IncDatabaseRateLimitedCounter() {
+ DatabaseRateLimitedCounter_->Inc();
+ }
+
+private:
+ NMonitoring::TDynamicCounters::TCounterPtr DatabaseAccessDenyCounter_;
+ NMonitoring::TDynamicCounters::TCounterPtr DatabaseSchemeErrorCounter_;
+ NMonitoring::TDynamicCounters::TCounterPtr DatabaseUnavailableCounter_;
+ NMonitoring::TDynamicCounters::TCounterPtr DatabaseRateLimitedCounter_;
+};
+
+}
+}
diff --git a/ydb/core/grpc_services/grpc_publisher_service_actor.cpp b/ydb/core/grpc_services/grpc_publisher_service_actor.cpp
index 54c30eb3e1e..f73de3a89c3 100644
--- a/ydb/core/grpc_services/grpc_publisher_service_actor.cpp
+++ b/ydb/core/grpc_services/grpc_publisher_service_actor.cpp
@@ -1,55 +1,55 @@
-#include "grpc_endpoint.h"
-
-#include <library/cpp/actors/core/hfunc.h>
-#include <library/cpp/actors/core/actor_bootstrapped.h>
-
-namespace NKikimr {
-namespace NGRpcService {
-
-using namespace NActors;
-
-class TGrpcPublisherServiceActor : public TActorBootstrapped<TGrpcPublisherServiceActor> {
- TVector<TIntrusivePtr<TGrpcEndpointDescription>> Endpoints;
- TVector<TActorId> ActorIds;
-
-public:
- static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
- return NKikimrServices::TActivity::GRPC_ENDPOINT_PUBLISH;
- }
-
- TGrpcPublisherServiceActor(TVector<TIntrusivePtr<TGrpcEndpointDescription>>&& endpoints)
- : Endpoints(endpoints)
- {}
-
- void Bootstrap() {
- ActorIds.reserve(Endpoints.size());
- for(auto& endpoint: Endpoints) {
- auto actor = CreateGrpcEndpointPublishActor(endpoint.Get());
- ActorIds.push_back(Register(actor));
- }
-
- Become(&TThis::StateWork);
- }
-
- void PassAway() override {
- for(auto& actorId : ActorIds) {
- Send(actorId, new TEvents::TEvPoisonPill());
- }
-
- TActor::PassAway();
- }
-
- STFUNC(StateWork) {
- Y_UNUSED(ctx);
- switch(ev->GetTypeRewrite()) {
- cFunc(TEvents::TEvPoisonPill::EventType, PassAway);
- }
- }
-};
-
-IActor* CreateGrpcPublisherServiceActor(TVector<TIntrusivePtr<TGrpcEndpointDescription>>&& endpoints) {
- return new TGrpcPublisherServiceActor(std::move(endpoints));
-}
-
-}
-} \ No newline at end of file
+#include "grpc_endpoint.h"
+
+#include <library/cpp/actors/core/hfunc.h>
+#include <library/cpp/actors/core/actor_bootstrapped.h>
+
+namespace NKikimr {
+namespace NGRpcService {
+
+using namespace NActors;
+
+class TGrpcPublisherServiceActor : public TActorBootstrapped<TGrpcPublisherServiceActor> {
+ TVector<TIntrusivePtr<TGrpcEndpointDescription>> Endpoints;
+ TVector<TActorId> ActorIds;
+
+public:
+ static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
+ return NKikimrServices::TActivity::GRPC_ENDPOINT_PUBLISH;
+ }
+
+ TGrpcPublisherServiceActor(TVector<TIntrusivePtr<TGrpcEndpointDescription>>&& endpoints)
+ : Endpoints(endpoints)
+ {}
+
+ void Bootstrap() {
+ ActorIds.reserve(Endpoints.size());
+ for(auto& endpoint: Endpoints) {
+ auto actor = CreateGrpcEndpointPublishActor(endpoint.Get());
+ ActorIds.push_back(Register(actor));
+ }
+
+ Become(&TThis::StateWork);
+ }
+
+ void PassAway() override {
+ for(auto& actorId : ActorIds) {
+ Send(actorId, new TEvents::TEvPoisonPill());
+ }
+
+ TActor::PassAway();
+ }
+
+ STFUNC(StateWork) {
+ Y_UNUSED(ctx);
+ switch(ev->GetTypeRewrite()) {
+ cFunc(TEvents::TEvPoisonPill::EventType, PassAway);
+ }
+ }
+};
+
+IActor* CreateGrpcPublisherServiceActor(TVector<TIntrusivePtr<TGrpcEndpointDescription>>&& endpoints) {
+ return new TGrpcPublisherServiceActor(std::move(endpoints));
+}
+
+}
+} \ No newline at end of file
diff --git a/ydb/core/grpc_services/grpc_request_check_actor.h b/ydb/core/grpc_services/grpc_request_check_actor.h
index daa8190f3ef..04c72abe6de 100644
--- a/ydb/core/grpc_services/grpc_request_check_actor.h
+++ b/ydb/core/grpc_services/grpc_request_check_actor.h
@@ -1,133 +1,133 @@
-#pragma once
-#include "defs.h"
-#include "grpc_proxy_counters.h"
-#include "local_rate_limiter.h"
-#include "operation_helpers.h"
-#include "rpc_calls.h"
-
-#include <library/cpp/actors/core/actor_bootstrapped.h>
-
+#pragma once
+#include "defs.h"
+#include "grpc_proxy_counters.h"
+#include "local_rate_limiter.h"
+#include "operation_helpers.h"
+#include "rpc_calls.h"
+
+#include <library/cpp/actors/core/actor_bootstrapped.h>
+
#include <ydb/core/base/path.h>
#include <ydb/core/base/subdomain.h>
#include <ydb/core/base/kikimr_issue.h>
#include <ydb/core/security/secure_request.h>
#include <ydb/core/tx/scheme_cache/scheme_cache.h>
-
+
#include <util/string/split.h>
-namespace NKikimr {
-namespace NGRpcService {
-
-template <typename TEvent>
+namespace NKikimr {
+namespace NGRpcService {
+
+template <typename TEvent>
class TGrpcRequestCheckActor
: public TActorBootstrappedSecureRequest<TGrpcRequestCheckActor<TEvent>>
, public ICheckerIface
{
- using TSelf = TGrpcRequestCheckActor<TEvent>;
- using TBase = TActorBootstrappedSecureRequest<TGrpcRequestCheckActor>;
-public:
- void OnAccessDenied(const TEvTicketParser::TError& error, const TActorContext& ctx) {
- LOG_ERROR(ctx, NKikimrServices::GRPC_SERVER, error.ToString());
- if (error.Retryable) {
- GrpcRequestBaseCtx_->UpdateAuthState(NGrpc::TAuthState::AS_UNAVAILABLE);
- } else {
- GrpcRequestBaseCtx_->UpdateAuthState(NGrpc::TAuthState::AS_FAIL);
- }
- ReplyBackAndDie();
- }
-
- static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
- return NKikimrServices::TActivity::GRPC_REQ_AUTH;
- }
-
- static const TVector<TString>& GetPermissions();
-
- void InitializeAttributesFromSchema(const TSchemeBoardEvents::TDescribeSchemeResult& schemeData) {
- CheckedDatabaseName_ = CanonizePath(schemeData.GetPath());
- if (!GrpcRequestBaseCtx_->TryCustomAttributeProcess(schemeData, this)) {
- ProcessCommonAttributes(schemeData);
+ using TSelf = TGrpcRequestCheckActor<TEvent>;
+ using TBase = TActorBootstrappedSecureRequest<TGrpcRequestCheckActor>;
+public:
+ void OnAccessDenied(const TEvTicketParser::TError& error, const TActorContext& ctx) {
+ LOG_ERROR(ctx, NKikimrServices::GRPC_SERVER, error.ToString());
+ if (error.Retryable) {
+ GrpcRequestBaseCtx_->UpdateAuthState(NGrpc::TAuthState::AS_UNAVAILABLE);
+ } else {
+ GrpcRequestBaseCtx_->UpdateAuthState(NGrpc::TAuthState::AS_FAIL);
}
+ ReplyBackAndDie();
}
- void ProcessCommonAttributes(const TSchemeBoardEvents::TDescribeSchemeResult& schemeData) {
+ static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
+ return NKikimrServices::TActivity::GRPC_REQ_AUTH;
+ }
+
+ static const TVector<TString>& GetPermissions();
+
+ void InitializeAttributesFromSchema(const TSchemeBoardEvents::TDescribeSchemeResult& schemeData) {
+ CheckedDatabaseName_ = CanonizePath(schemeData.GetPath());
+ if (!GrpcRequestBaseCtx_->TryCustomAttributeProcess(schemeData, this)) {
+ ProcessCommonAttributes(schemeData);
+ }
+ }
+
+ void ProcessCommonAttributes(const TSchemeBoardEvents::TDescribeSchemeResult& schemeData) {
static std::vector<TString> allowedAttributes = {"folder_id", "service_account_id", "database_id"};
TVector<std::pair<TString, TString>> attributes;
- attributes.reserve(schemeData.GetPathDescription().UserAttributesSize());
- for (const auto& attr : schemeData.GetPathDescription().GetUserAttributes()) {
- if (std::find(allowedAttributes.begin(), allowedAttributes.end(), attr.GetKey()) != allowedAttributes.end()) {
- attributes.emplace_back(attr.GetKey(), attr.GetValue());
- }
- }
+ attributes.reserve(schemeData.GetPathDescription().UserAttributesSize());
+ for (const auto& attr : schemeData.GetPathDescription().GetUserAttributes()) {
+ if (std::find(allowedAttributes.begin(), allowedAttributes.end(), attr.GetKey()) != allowedAttributes.end()) {
+ attributes.emplace_back(attr.GetKey(), attr.GetValue());
+ }
+ }
if (!attributes.empty()) {
SetEntries({{GetPermissions(), attributes}});
}
- }
-
+ }
+
void SetEntries(const TVector<TEvTicketParser::TEvAuthorizeTicket::TEntry>& entries) {
TBase::SetEntries(entries);
}
- void InitializeAttributes(const TSchemeBoardEvents::TDescribeSchemeResult& schemeData);
-
- TGrpcRequestCheckActor(
- const TActorId& owner,
- const TSchemeBoardEvents::TDescribeSchemeResult& schemeData,
- TIntrusivePtr<TSecurityObject> securityObject,
- TAutoPtr<TEventHandle<TEvent>> request,
+ void InitializeAttributes(const TSchemeBoardEvents::TDescribeSchemeResult& schemeData);
+
+ TGrpcRequestCheckActor(
+ const TActorId& owner,
+ const TSchemeBoardEvents::TDescribeSchemeResult& schemeData,
+ TIntrusivePtr<TSecurityObject> securityObject,
+ TAutoPtr<TEventHandle<TEvent>> request,
TGrpcProxyCounters::TPtr counters,
bool skipCheckConnectRigths)
- : Owner_(owner)
- , Request_(std::move(request))
- , Counters_(counters)
- , SecurityObject_(std::move(securityObject))
+ : Owner_(owner)
+ , Request_(std::move(request))
+ , Counters_(counters)
+ , SecurityObject_(std::move(securityObject))
, SkipCheckConnectRigths_(skipCheckConnectRigths)
- {
- GrpcRequestBaseCtx_ = Request_->Get();
- TMaybe<TString> authToken = GrpcRequestBaseCtx_->GetYdbToken();
- if (authToken) {
- TString peerName = GrpcRequestBaseCtx_->GetPeerName();
- TBase::SetSecurityToken(authToken.GetRef());
- TBase::SetPeerName(peerName);
- InitializeAttributes(schemeData);
- TBase::SetDatabase(CheckedDatabaseName_);
- }
- }
-
- void Bootstrap(const TActorContext& ctx) {
- TBase::Become(&TSelf::DbAccessStateFunc);
-
+ {
+ GrpcRequestBaseCtx_ = Request_->Get();
+ TMaybe<TString> authToken = GrpcRequestBaseCtx_->GetYdbToken();
+ if (authToken) {
+ TString peerName = GrpcRequestBaseCtx_->GetPeerName();
+ TBase::SetSecurityToken(authToken.GetRef());
+ TBase::SetPeerName(peerName);
+ InitializeAttributes(schemeData);
+ TBase::SetDatabase(CheckedDatabaseName_);
+ }
+ }
+
+ void Bootstrap(const TActorContext& ctx) {
+ TBase::Become(&TSelf::DbAccessStateFunc);
+
{
auto [error, issue] = CheckConnectRight();
if (error) {
ReplyUnauthorizedAndDie(*issue);
return;
- }
- }
-
+ }
+ }
+
// Simple rps limitation
- static NRpcService::TRlConfig rpsRlConfig(
- "serverless_rt_coordination_node_path",
- "serverless_rt_base_resource_rps",
- {
- NRpcService::TRlConfig::TOnReqAction {
- 1
- }
- }
- );
-
+ static NRpcService::TRlConfig rpsRlConfig(
+ "serverless_rt_coordination_node_path",
+ "serverless_rt_base_resource_rps",
+ {
+ NRpcService::TRlConfig::TOnReqAction {
+ 1
+ }
+ }
+ );
+
// Limitation RU for unary calls in time of response
- static NRpcService::TRlConfig ruRlConfig(
- "serverless_rt_coordination_node_path",
- "serverless_rt_base_resource_ru",
- {
- NRpcService::TRlConfig::TOnReqAction {
- 1
- },
- NRpcService::TRlConfig::TOnRespAction {
- }
- }
- );
-
+ static NRpcService::TRlConfig ruRlConfig(
+ "serverless_rt_coordination_node_path",
+ "serverless_rt_base_resource_ru",
+ {
+ NRpcService::TRlConfig::TOnReqAction {
+ 1
+ },
+ NRpcService::TRlConfig::TOnRespAction {
+ }
+ }
+ );
+
// Limitation ru for calls with internall rl support (read table)
static NRpcService::TRlConfig ruRlProgressConfig(
"serverless_rt_coordination_node_path",
@@ -140,194 +140,194 @@ public:
);
- auto rlMode = Request_->Get()->GetRlMode();
- switch (rlMode) {
- case TRateLimiterMode::Rps:
- RlConfig = &rpsRlConfig;
- break;
- case TRateLimiterMode::Ru:
- RlConfig = &ruRlConfig;
- break;
+ auto rlMode = Request_->Get()->GetRlMode();
+ switch (rlMode) {
+ case TRateLimiterMode::Rps:
+ RlConfig = &rpsRlConfig;
+ break;
+ case TRateLimiterMode::Ru:
+ RlConfig = &ruRlConfig;
+ break;
case TRateLimiterMode::RuOnProgress:
RlConfig = &ruRlProgressConfig;
break;
- case TRateLimiterMode::Off:
- break;
+ case TRateLimiterMode::Off:
+ break;
}
-
- if (!RlConfig) {
- // No rate limit config for this request
- return SetTokenAndDie(CheckedDatabaseName_);
- } else {
- THashMap<TString, TString> attributes;
+
+ if (!RlConfig) {
+ // No rate limit config for this request
+ return SetTokenAndDie(CheckedDatabaseName_);
+ } else {
+ THashMap<TString, TString> attributes;
for (const auto& [attrName, attrValue] : Attributes_) {
attributes[attrName] = attrValue;
- }
- return ProcessRateLimit(attributes, ctx);
- }
- }
-
- void SetTokenAndDie(const TString& database = {}) {
- GrpcRequestBaseCtx_->UpdateAuthState(NGrpc::TAuthState::AS_OK);
- GrpcRequestBaseCtx_->SetInternalToken(TBase::GetSerializedToken());
- GrpcRequestBaseCtx_->UseDatabase(database);
- ReplyBackAndDie();
- }
-
+ }
+ return ProcessRateLimit(attributes, ctx);
+ }
+ }
+
+ void SetTokenAndDie(const TString& database = {}) {
+ GrpcRequestBaseCtx_->UpdateAuthState(NGrpc::TAuthState::AS_OK);
+ GrpcRequestBaseCtx_->SetInternalToken(TBase::GetSerializedToken());
+ GrpcRequestBaseCtx_->UseDatabase(database);
+ ReplyBackAndDie();
+ }
+
void SetRlPath(TMaybe<NRpcService::TRlPath>&& rlPath) {
GrpcRequestBaseCtx_->SetRlPath(std::move(rlPath));
}
- STATEFN(DbAccessStateFunc) {
- switch (ev->GetTypeRewrite()) {
- hFunc(TEvents::TEvPoisonPill, HandlePoison);
- }
- }
-
- void HandlePoison(TEvents::TEvPoisonPill::TPtr&) {
- TBase::PassAway();
- }
-
-private:
- static NYql::TIssues GetRlIssues(const Ydb::RateLimiter::AcquireResourceResponse& resp) {
- NYql::TIssues opIssues;
- NYql::IssuesFromMessage(resp.operation().issues(), opIssues);
- return opIssues;
- }
-
- void ProcessOnRequest(Ydb::RateLimiter::AcquireResourceRequest&& req, const TActorContext& ctx) {
+ STATEFN(DbAccessStateFunc) {
+ switch (ev->GetTypeRewrite()) {
+ hFunc(TEvents::TEvPoisonPill, HandlePoison);
+ }
+ }
+
+ void HandlePoison(TEvents::TEvPoisonPill::TPtr&) {
+ TBase::PassAway();
+ }
+
+private:
+ static NYql::TIssues GetRlIssues(const Ydb::RateLimiter::AcquireResourceResponse& resp) {
+ NYql::TIssues opIssues;
+ NYql::IssuesFromMessage(resp.operation().issues(), opIssues);
+ return opIssues;
+ }
+
+ void ProcessOnRequest(Ydb::RateLimiter::AcquireResourceRequest&& req, const TActorContext& ctx) {
auto time = TInstant::Now();
auto cb = [this, time](Ydb::RateLimiter::AcquireResourceResponse resp) {
TDuration delay = TInstant::Now() - time;
- switch (resp.operation().status()) {
- case Ydb::StatusIds::SUCCESS:
+ switch (resp.operation().status()) {
+ case Ydb::StatusIds::SUCCESS:
LOG_DEBUG_S(*TlsActivationContext, NKikimrServices::GRPC_SERVER, "Request delayed for " << delay << " by ratelimiter");
- SetTokenAndDie(CheckedDatabaseName_);
- break;
- case Ydb::StatusIds::TIMEOUT:
- Counters_->IncDatabaseRateLimitedCounter();
+ SetTokenAndDie(CheckedDatabaseName_);
+ break;
+ case Ydb::StatusIds::TIMEOUT:
+ Counters_->IncDatabaseRateLimitedCounter();
LOG_ERROR(*TlsActivationContext, NKikimrServices::GRPC_SERVER, "Throughput limit exceeded");
- ReplyOverloadedAndDie(MakeIssue(NKikimrIssues::TIssuesIds::YDB_RESOURCE_USAGE_LIMITED, "Throughput limit exceeded"));
- break;
- default:
- {
- auto issues = GetRlIssues(resp);
- const TString error = Sprintf("RateLimiter status: %d database: %s, issues: %s",
- resp.operation().status(),
- CheckedDatabaseName_.c_str(),
- issues.ToString().c_str());
- LOG_ERROR(*TlsActivationContext, NKikimrServices::GRPC_SERVER, "%s", error.c_str());
-
- ReplyUnavailableAndDie(issues); // same as cloud-go serverless proxy
- }
- break;
- }
- };
-
- req.mutable_operation_params()->mutable_operation_timeout()->set_nanos(200000000); // same as cloud-go serverless proxy
-
- NKikimr::NRpcService::RateLimiterAcquireUseSameMailbox(
- std::move(req),
- CheckedDatabaseName_,
- TBase::GetSerializedToken(),
- std::move(cb),
- ctx);
- }
-
- TRespHook CreateRlRespHook(Ydb::RateLimiter::AcquireResourceRequest&& req) {
- const auto& databasename = CheckedDatabaseName_;
- auto token = TBase::GetSerializedToken();
- return [req{std::move(req)}, databasename, token](TRespHookCtx::TPtr ctx) mutable {
-
- LOG_DEBUG(*TlsActivationContext, NKikimrServices::GRPC_SERVER,
- "Response hook called to report RU usage, database: %s, request: %s, consumed: %d",
- databasename.c_str(), ctx->GetRequestName().c_str(), ctx->GetConsumedRu());
-
- if (ctx->GetConsumedRu() >= 1) {
- // We already count '1' on start request
- req.set_used(ctx->GetConsumedRu() - 1);
-
- // No need to handle result of rate limiter response on the response hook
- // just report ru usage
- auto noop = [](Ydb::RateLimiter::AcquireResourceResponse) {};
- NKikimr::NRpcService::RateLimiterAcquireUseSameMailbox(
- std::move(req),
- databasename,
- token,
- std::move(noop),
- TActivationContext::AsActorContext());
- }
-
- ctx->Pass();
- };
- }
-
- void ProcessRateLimit(const THashMap<TString, TString>& attributes, const TActorContext& ctx) {
- // Match rate limit config and database attributes
+ ReplyOverloadedAndDie(MakeIssue(NKikimrIssues::TIssuesIds::YDB_RESOURCE_USAGE_LIMITED, "Throughput limit exceeded"));
+ break;
+ default:
+ {
+ auto issues = GetRlIssues(resp);
+ const TString error = Sprintf("RateLimiter status: %d database: %s, issues: %s",
+ resp.operation().status(),
+ CheckedDatabaseName_.c_str(),
+ issues.ToString().c_str());
+ LOG_ERROR(*TlsActivationContext, NKikimrServices::GRPC_SERVER, "%s", error.c_str());
+
+ ReplyUnavailableAndDie(issues); // same as cloud-go serverless proxy
+ }
+ break;
+ }
+ };
+
+ req.mutable_operation_params()->mutable_operation_timeout()->set_nanos(200000000); // same as cloud-go serverless proxy
+
+ NKikimr::NRpcService::RateLimiterAcquireUseSameMailbox(
+ std::move(req),
+ CheckedDatabaseName_,
+ TBase::GetSerializedToken(),
+ std::move(cb),
+ ctx);
+ }
+
+ TRespHook CreateRlRespHook(Ydb::RateLimiter::AcquireResourceRequest&& req) {
+ const auto& databasename = CheckedDatabaseName_;
+ auto token = TBase::GetSerializedToken();
+ return [req{std::move(req)}, databasename, token](TRespHookCtx::TPtr ctx) mutable {
+
+ LOG_DEBUG(*TlsActivationContext, NKikimrServices::GRPC_SERVER,
+ "Response hook called to report RU usage, database: %s, request: %s, consumed: %d",
+ databasename.c_str(), ctx->GetRequestName().c_str(), ctx->GetConsumedRu());
+
+ if (ctx->GetConsumedRu() >= 1) {
+ // We already count '1' on start request
+ req.set_used(ctx->GetConsumedRu() - 1);
+
+ // No need to handle result of rate limiter response on the response hook
+ // just report ru usage
+ auto noop = [](Ydb::RateLimiter::AcquireResourceResponse) {};
+ NKikimr::NRpcService::RateLimiterAcquireUseSameMailbox(
+ std::move(req),
+ databasename,
+ token,
+ std::move(noop),
+ TActivationContext::AsActorContext());
+ }
+
+ ctx->Pass();
+ };
+ }
+
+ void ProcessRateLimit(const THashMap<TString, TString>& attributes, const TActorContext& ctx) {
+ // Match rate limit config and database attributes
auto rlPath = NRpcService::Match(*RlConfig, attributes);
if (!rlPath) {
- return SetTokenAndDie(CheckedDatabaseName_);
- } else {
+ return SetTokenAndDie(CheckedDatabaseName_);
+ } else {
auto actions = NRpcService::MakeRequests(*RlConfig, rlPath.GetRef());
SetRlPath(std::move(rlPath));
- Ydb::RateLimiter::AcquireResourceRequest req;
- bool hasOnReqAction = false;
- for (auto& action : actions) {
- switch (action.first) {
- case NRpcService::Actions::OnReq:
- req = std::move(action.second);
- hasOnReqAction = true;
- break;
- case NRpcService::Actions::OnResp:
- GrpcRequestBaseCtx_->SetRespHook(CreateRlRespHook(std::move(action.second)));
- break;
- }
- }
-
- if (hasOnReqAction) {
- return ProcessOnRequest(std::move(req), ctx);
- } else {
- return SetTokenAndDie(CheckedDatabaseName_);
- }
- }
- }
-
-private:
- void ReplyUnauthorizedAndDie(const NYql::TIssue& issue) {
- GrpcRequestBaseCtx_->RaiseIssue(issue);
- GrpcRequestBaseCtx_->ReplyWithYdbStatus(Ydb::StatusIds::UNAUTHORIZED);
- TBase::PassAway();
- }
-
- void ReplyUnavailableAndDie(const NYql::TIssue& issue) {
- GrpcRequestBaseCtx_->RaiseIssue(issue);
- GrpcRequestBaseCtx_->ReplyWithYdbStatus(Ydb::StatusIds::UNAVAILABLE);
- TBase::PassAway();
- }
-
- void ReplyUnavailableAndDie(const NYql::TIssues& issue) {
- GrpcRequestBaseCtx_->RaiseIssues(issue);
- GrpcRequestBaseCtx_->ReplyWithYdbStatus(Ydb::StatusIds::UNAVAILABLE);
- TBase::PassAway();
- }
-
- void ReplyUnauthenticatedAndDie() {
- GrpcRequestBaseCtx_->ReplyUnauthenticated("Unknown database");
- TBase::PassAway();
- }
-
- void ReplyOverloadedAndDie(const NYql::TIssue& issue) {
- GrpcRequestBaseCtx_->RaiseIssue(issue);
- GrpcRequestBaseCtx_->ReplyWithYdbStatus(Ydb::StatusIds::OVERLOADED);
- TBase::PassAway();
- }
-
- void ReplyBackAndDie() {
- TlsActivationContext->Send(Request_->Forward(Owner_));
- TBase::PassAway();
- }
-
+ Ydb::RateLimiter::AcquireResourceRequest req;
+ bool hasOnReqAction = false;
+ for (auto& action : actions) {
+ switch (action.first) {
+ case NRpcService::Actions::OnReq:
+ req = std::move(action.second);
+ hasOnReqAction = true;
+ break;
+ case NRpcService::Actions::OnResp:
+ GrpcRequestBaseCtx_->SetRespHook(CreateRlRespHook(std::move(action.second)));
+ break;
+ }
+ }
+
+ if (hasOnReqAction) {
+ return ProcessOnRequest(std::move(req), ctx);
+ } else {
+ return SetTokenAndDie(CheckedDatabaseName_);
+ }
+ }
+ }
+
+private:
+ void ReplyUnauthorizedAndDie(const NYql::TIssue& issue) {
+ GrpcRequestBaseCtx_->RaiseIssue(issue);
+ GrpcRequestBaseCtx_->ReplyWithYdbStatus(Ydb::StatusIds::UNAUTHORIZED);
+ TBase::PassAway();
+ }
+
+ void ReplyUnavailableAndDie(const NYql::TIssue& issue) {
+ GrpcRequestBaseCtx_->RaiseIssue(issue);
+ GrpcRequestBaseCtx_->ReplyWithYdbStatus(Ydb::StatusIds::UNAVAILABLE);
+ TBase::PassAway();
+ }
+
+ void ReplyUnavailableAndDie(const NYql::TIssues& issue) {
+ GrpcRequestBaseCtx_->RaiseIssues(issue);
+ GrpcRequestBaseCtx_->ReplyWithYdbStatus(Ydb::StatusIds::UNAVAILABLE);
+ TBase::PassAway();
+ }
+
+ void ReplyUnauthenticatedAndDie() {
+ GrpcRequestBaseCtx_->ReplyUnauthenticated("Unknown database");
+ TBase::PassAway();
+ }
+
+ void ReplyOverloadedAndDie(const NYql::TIssue& issue) {
+ GrpcRequestBaseCtx_->RaiseIssue(issue);
+ GrpcRequestBaseCtx_->ReplyWithYdbStatus(Ydb::StatusIds::OVERLOADED);
+ TBase::PassAway();
+ }
+
+ void ReplyBackAndDie() {
+ TlsActivationContext->Send(Request_->Forward(Owner_));
+ TBase::PassAway();
+ }
+
std::pair<bool, std::optional<NYql::TIssue>> CheckConnectRight() {
if (SkipCheckConnectRigths_) {
LOG_DEBUG_S(*TlsActivationContext, NKikimrServices::GRPC_PROXY_NO_CONNECT_ACCESS,
@@ -389,63 +389,63 @@ private:
return {true, MakeIssue(NKikimrIssues::TIssuesIds::ACCESS_DENIED, error)};
}
- const TActorId Owner_;
- TAutoPtr<TEventHandle<TEvent>> Request_;
- TGrpcProxyCounters::TPtr Counters_;
- TIntrusivePtr<TSecurityObject> SecurityObject_;
- TString CheckedDatabaseName_;
- IRequestProxyCtx* GrpcRequestBaseCtx_;
- NRpcService::TRlConfig* RlConfig = nullptr;
+ const TActorId Owner_;
+ TAutoPtr<TEventHandle<TEvent>> Request_;
+ TGrpcProxyCounters::TPtr Counters_;
+ TIntrusivePtr<TSecurityObject> SecurityObject_;
+ TString CheckedDatabaseName_;
+ IRequestProxyCtx* GrpcRequestBaseCtx_;
+ NRpcService::TRlConfig* RlConfig = nullptr;
bool SkipCheckConnectRigths_ = false;
std::vector<std::pair<TString, TString>> Attributes_;
-};
-
-// default behavior - attributes in schema
-template <typename TEvent>
-void TGrpcRequestCheckActor<TEvent>::InitializeAttributes(const TSchemeBoardEvents::TDescribeSchemeResult& schemeData) {
+};
+
+// default behavior - attributes in schema
+template <typename TEvent>
+void TGrpcRequestCheckActor<TEvent>::InitializeAttributes(const TSchemeBoardEvents::TDescribeSchemeResult& schemeData) {
for (const auto& attr : schemeData.GetPathDescription().GetUserAttributes()) {
Attributes_.emplace_back(std::make_pair(attr.GetKey(), attr.GetValue()));
}
- InitializeAttributesFromSchema(schemeData);
-}
-
-// default permissions
-template <typename TEvent>
-const TVector<TString>& TGrpcRequestCheckActor<TEvent>::GetPermissions() {
- static const TVector<TString> permissions = {
- "ydb.databases.list",
- "ydb.databases.create",
- "ydb.databases.connect"
- };
- return permissions;
-}
-
+ InitializeAttributesFromSchema(schemeData);
+}
+
+// default permissions
+template <typename TEvent>
+const TVector<TString>& TGrpcRequestCheckActor<TEvent>::GetPermissions() {
+ static const TVector<TString> permissions = {
+ "ydb.databases.list",
+ "ydb.databases.create",
+ "ydb.databases.connect"
+ };
+ return permissions;
+}
+
// yds behavior
template <>
inline const TVector<TString>& TGrpcRequestCheckActor<TEvDataStreamsPutRecordRequest>::GetPermissions() {
- //full list of permissions for compatility. remove old permissions later.
+ //full list of permissions for compatility. remove old permissions later.
static const TVector<TString> permissions = {"yds.streams.write", "ydb.databases.list", "ydb.databases.create", "ydb.databases.connect"};
- return permissions;
+ return permissions;
}
// yds behavior
template <>
inline const TVector<TString>& TGrpcRequestCheckActor<TEvDataStreamsPutRecordsRequest>::GetPermissions() {
- //full list of permissions for compatility. remove old permissions later.
+ //full list of permissions for compatility. remove old permissions later.
static const TVector<TString> permissions = {"yds.streams.write", "ydb.databases.list", "ydb.databases.create", "ydb.databases.connect"};
- return permissions;
+ return permissions;
}
-template <typename TEvent>
-IActor* CreateGrpcRequestCheckActor(
- const TActorId& owner,
- const TSchemeBoardEvents::TDescribeSchemeResult& schemeData,
- TIntrusivePtr<TSecurityObject> securityObject,
- TAutoPtr<TEventHandle<TEvent>> request,
+template <typename TEvent>
+IActor* CreateGrpcRequestCheckActor(
+ const TActorId& owner,
+ const TSchemeBoardEvents::TDescribeSchemeResult& schemeData,
+ TIntrusivePtr<TSecurityObject> securityObject,
+ TAutoPtr<TEventHandle<TEvent>> request,
TGrpcProxyCounters::TPtr counters,
bool skipCheckConnectRigths) {
return new TGrpcRequestCheckActor<TEvent>(owner, schemeData, std::move(securityObject), std::move(request), counters, skipCheckConnectRigths);
-}
-
-}
+}
+
+}
}
diff --git a/ydb/core/grpc_services/grpc_request_proxy.cpp b/ydb/core/grpc_services/grpc_request_proxy.cpp
index 8ed8addc5d5..a1e7accb877 100644
--- a/ydb/core/grpc_services/grpc_request_proxy.cpp
+++ b/ydb/core/grpc_services/grpc_request_proxy.cpp
@@ -1,5 +1,5 @@
-#include "grpc_proxy_counters.h"
-#include "grpc_request_check_actor.h"
+#include "grpc_proxy_counters.h"
+#include "grpc_request_check_actor.h"
#include "grpc_request_proxy.h"
#include "local_rate_limiter.h"
#include "operation_helpers.h"
@@ -16,9 +16,9 @@ namespace NGRpcService {
using namespace NActors;
-static const ui32 MAX_DEFERRED_EVENTS_PER_DATABASE = 100;
+static const ui32 MAX_DEFERRED_EVENTS_PER_DATABASE = 100;
-TString DatabaseFromDomain(const TAppData* appdata = AppData()) {
+TString DatabaseFromDomain(const TAppData* appdata = AppData()) {
auto dinfo = appdata->DomainsInfo;
if (!dinfo)
ythrow yexception() << "Invalid DomainsInfo ptr";
@@ -33,85 +33,85 @@ TString DatabaseFromDomain(const TAppData* appdata = AppData()) {
struct TDatabaseInfo {
enum class TDatabaseType {
- Root,
+ Root,
Tenant,
Serverless
};
- NKikimrTenantPool::EState State;
- TDatabaseType DatabaseType;
- THolder<TSchemeBoardEvents::TEvNotifyUpdate> SchemeBoardResult;
- TIntrusivePtr<TSecurityObject> SecurityObject;
-
- bool IsDatabaseReady() const {
- if (SchemeBoardResult == nullptr) {
- return false;
- }
- if (DatabaseType == TDatabaseType::Tenant) {
- switch (State) {
- case NKikimrTenantPool::STATE_UNKNOWN:
- case NKikimrTenantPool::TENANT_OK:
- return true;
- break;
- case NKikimrTenantPool::TENANT_ASSIGNED:
- case NKikimrTenantPool::TENANT_UNKNOWN:
- return false;
- break;
- }
- }
- return true;
+ NKikimrTenantPool::EState State;
+ TDatabaseType DatabaseType;
+ THolder<TSchemeBoardEvents::TEvNotifyUpdate> SchemeBoardResult;
+ TIntrusivePtr<TSecurityObject> SecurityObject;
+
+ bool IsDatabaseReady() const {
+ if (SchemeBoardResult == nullptr) {
+ return false;
+ }
+ if (DatabaseType == TDatabaseType::Tenant) {
+ switch (State) {
+ case NKikimrTenantPool::STATE_UNKNOWN:
+ case NKikimrTenantPool::TENANT_OK:
+ return true;
+ break;
+ case NKikimrTenantPool::TENANT_ASSIGNED:
+ case NKikimrTenantPool::TENANT_UNKNOWN:
+ return false;
+ break;
+ }
+ }
+ return true;
}
-};
-
-
-struct TEventReqHolder {
- TEventReqHolder(TAutoPtr<IEventHandle> ev, IRequestProxyCtx* ctx)
- : Ev(std::move(ev))
- , Ctx(ctx)
- {}
- TAutoPtr<IEventHandle> Ev;
- IRequestProxyCtx* Ctx;
-};
-
-class TGRpcRequestProxyImpl
- : public TActorBootstrapped<TGRpcRequestProxyImpl>
- , public TGRpcRequestProxy
-{
- using TBase = TActorBootstrapped<TGRpcRequestProxyImpl>;
+};
+
+
+struct TEventReqHolder {
+ TEventReqHolder(TAutoPtr<IEventHandle> ev, IRequestProxyCtx* ctx)
+ : Ev(std::move(ev))
+ , Ctx(ctx)
+ {}
+ TAutoPtr<IEventHandle> Ev;
+ IRequestProxyCtx* Ctx;
+};
+
+class TGRpcRequestProxyImpl
+ : public TActorBootstrapped<TGRpcRequestProxyImpl>
+ , public TGRpcRequestProxy
+{
+ using TBase = TActorBootstrapped<TGRpcRequestProxyImpl>;
public:
- explicit TGRpcRequestProxyImpl(const NKikimrConfig::TAppConfig& appConfig)
- : AppConfig(appConfig)
- {}
-
- void Bootstrap(const TActorContext& ctx);
- void StateFunc(TAutoPtr<IEventHandle>& ev, const TActorContext& ctx);
-
+ explicit TGRpcRequestProxyImpl(const NKikimrConfig::TAppConfig& appConfig)
+ : AppConfig(appConfig)
+ {}
+
+ void Bootstrap(const TActorContext& ctx);
+ void StateFunc(TAutoPtr<IEventHandle>& ev, const TActorContext& ctx);
+
static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
- return NKikimrServices::TActivity::GRPC_PROXY;
+ return NKikimrServices::TActivity::GRPC_PROXY;
}
-private:
- void HandlePoolStatus(TEvTenantPool::TEvTenantPoolStatus::TPtr& ev, const TActorContext& ctx);
- void HandleRefreshToken(TRefreshTokenImpl::TPtr& ev, const TActorContext& ctx);
- void HandleConfig(NConsole::TEvConfigsDispatcher::TEvSetConfigSubscriptionResponse::TPtr& ev);
- void HandleConfig(NConsole::TEvConsole::TEvConfigNotificationRequest::TPtr& ev);
- void HandleProxyService(TEvTxUserProxy::TEvGetProxyServicesResponse::TPtr& ev);
- void HandleUndelivery(TEvents::TEvUndelivered::TPtr& ev);
- void HandleSchemeBoard(TSchemeBoardEvents::TEvNotifyUpdate::TPtr& ev, const TActorContext& ctx);
- void HandleSchemeBoard(TSchemeBoardEvents::TEvNotifyDelete::TPtr& ev);
- void ReplayEvents(const TString& databaseName, const TActorContext& ctx);
-
- static bool IsAuthStateOK(const IRequestProxyCtx& ctx);
-
- template <typename TEvent>
- void Handle(TAutoPtr<TEventHandle<TEvent>>& event, const TActorContext& ctx) {
- IRequestProxyCtx* requestBaseCtx = event->Get();
- TString validationError;
- if (!requestBaseCtx->Validate(validationError)) {
- const auto issue = MakeIssue(NKikimrIssues::TIssuesIds::YDB_API_VALIDATION_ERROR, validationError);
- requestBaseCtx->RaiseIssue(issue);
- requestBaseCtx->ReplyWithYdbStatus(Ydb::StatusIds::BAD_REQUEST);
+private:
+ void HandlePoolStatus(TEvTenantPool::TEvTenantPoolStatus::TPtr& ev, const TActorContext& ctx);
+ void HandleRefreshToken(TRefreshTokenImpl::TPtr& ev, const TActorContext& ctx);
+ void HandleConfig(NConsole::TEvConfigsDispatcher::TEvSetConfigSubscriptionResponse::TPtr& ev);
+ void HandleConfig(NConsole::TEvConsole::TEvConfigNotificationRequest::TPtr& ev);
+ void HandleProxyService(TEvTxUserProxy::TEvGetProxyServicesResponse::TPtr& ev);
+ void HandleUndelivery(TEvents::TEvUndelivered::TPtr& ev);
+ void HandleSchemeBoard(TSchemeBoardEvents::TEvNotifyUpdate::TPtr& ev, const TActorContext& ctx);
+ void HandleSchemeBoard(TSchemeBoardEvents::TEvNotifyDelete::TPtr& ev);
+ void ReplayEvents(const TString& databaseName, const TActorContext& ctx);
+
+ static bool IsAuthStateOK(const IRequestProxyCtx& ctx);
+
+ template <typename TEvent>
+ void Handle(TAutoPtr<TEventHandle<TEvent>>& event, const TActorContext& ctx) {
+ IRequestProxyCtx* requestBaseCtx = event->Get();
+ TString validationError;
+ if (!requestBaseCtx->Validate(validationError)) {
+ const auto issue = MakeIssue(NKikimrIssues::TIssuesIds::YDB_API_VALIDATION_ERROR, validationError);
+ requestBaseCtx->RaiseIssue(issue);
+ requestBaseCtx->ReplyWithYdbStatus(Ydb::StatusIds::BAD_REQUEST);
} else {
- TGRpcRequestProxy::Handle(event, ctx);
+ TGRpcRequestProxy::Handle(event, ctx);
}
}
@@ -127,172 +127,172 @@ private:
}
}
- void Handle(TRefreshTokenImpl::TPtr& event, const TActorContext& ctx) {
- const auto record = event->Get();
- ctx.Send(record->GetFromId(), new TGRpcRequestProxy::TEvRefreshTokenResponse {
- record->GetAuthState().State == NGrpc::TAuthState::EAuthState::AS_OK,
- record->GetInternalToken(),
- record->GetAuthState().State == NGrpc::TAuthState::EAuthState::AS_UNAVAILABLE,
- NYql::TIssues()});
+ void Handle(TRefreshTokenImpl::TPtr& event, const TActorContext& ctx) {
+ const auto record = event->Get();
+ ctx.Send(record->GetFromId(), new TGRpcRequestProxy::TEvRefreshTokenResponse {
+ record->GetAuthState().State == NGrpc::TAuthState::EAuthState::AS_OK,
+ record->GetInternalToken(),
+ record->GetAuthState().State == NGrpc::TAuthState::EAuthState::AS_UNAVAILABLE,
+ NYql::TIssues()});
}
- // returns true and defer event if no updates for given database
- // otherwice returns false and leave event untouched
- template <typename TEvent>
- bool DeferAndStartUpdate(const TString& database, TAutoPtr<TEventHandle<TEvent>>& ev, IRequestProxyCtx* reqCtx) {
- std::deque<TEventReqHolder>& queue = DeferredEvents[database];
- if (queue.size() >= MAX_DEFERRED_EVENTS_PER_DATABASE) {
- return false;
+ // returns true and defer event if no updates for given database
+ // otherwice returns false and leave event untouched
+ template <typename TEvent>
+ bool DeferAndStartUpdate(const TString& database, TAutoPtr<TEventHandle<TEvent>>& ev, IRequestProxyCtx* reqCtx) {
+ std::deque<TEventReqHolder>& queue = DeferredEvents[database];
+ if (queue.size() >= MAX_DEFERRED_EVENTS_PER_DATABASE) {
+ return false;
+ }
+
+ if (queue.empty()) {
+ DoStartUpdate(database);
}
- if (queue.empty()) {
- DoStartUpdate(database);
- }
-
- queue.push_back(TEventReqHolder(ev.Release(), reqCtx));
- return true;
+ queue.push_back(TEventReqHolder(ev.Release(), reqCtx));
+ return true;
}
- template <typename TEvent>
- void PreHandle(TAutoPtr<TEventHandle<TEvent>>& event, const TActorContext& ctx) {
- IRequestProxyCtx* requestBaseCtx = event->Get();
+ template <typename TEvent>
+ void PreHandle(TAutoPtr<TEventHandle<TEvent>>& event, const TActorContext& ctx) {
+ IRequestProxyCtx* requestBaseCtx = event->Get();
- LogRequest(event);
+ LogRequest(event);
- if (!SchemeCache) {
- const TString error = "Grpc proxy is not ready to accept request, no proxy service";
- LOG_ERROR_S(ctx, NKikimrServices::GRPC_SERVER, error);
- const auto issue = MakeIssue(NKikimrIssues::TIssuesIds::GENERIC_TXPROXY_ERROR, error);
- requestBaseCtx->RaiseIssue(issue);
- requestBaseCtx->ReplyWithYdbStatus(Ydb::StatusIds::UNAVAILABLE);
- return;
- }
+ if (!SchemeCache) {
+ const TString error = "Grpc proxy is not ready to accept request, no proxy service";
+ LOG_ERROR_S(ctx, NKikimrServices::GRPC_SERVER, error);
+ const auto issue = MakeIssue(NKikimrIssues::TIssuesIds::GENERIC_TXPROXY_ERROR, error);
+ requestBaseCtx->RaiseIssue(issue);
+ requestBaseCtx->ReplyWithYdbStatus(Ydb::StatusIds::UNAVAILABLE);
+ return;
+ }
+
+ if (IsAuthStateOK(*requestBaseCtx)) {
+ Handle(event, ctx);
+ return;
+ }
- if (IsAuthStateOK(*requestBaseCtx)) {
- Handle(event, ctx);
- return;
- }
+ auto state = requestBaseCtx->GetAuthState();
- auto state = requestBaseCtx->GetAuthState();
+ if (state.State == NGrpc::TAuthState::AS_FAIL) {
+ requestBaseCtx->ReplyUnauthenticated();
+ return;
+ }
- if (state.State == NGrpc::TAuthState::AS_FAIL) {
- requestBaseCtx->ReplyUnauthenticated();
+ if (state.State == NGrpc::TAuthState::AS_UNAVAILABLE) {
+ Counters->IncDatabaseUnavailableCounter();
+ const TString error = "Unable to resolve token";
+ const auto issue = MakeIssue(NKikimrIssues::TIssuesIds::YDB_AUTH_UNAVAILABLE, error);
+ requestBaseCtx->RaiseIssue(issue);
+ requestBaseCtx->ReplyUnavaliable();
return;
- }
-
- if (state.State == NGrpc::TAuthState::AS_UNAVAILABLE) {
- Counters->IncDatabaseUnavailableCounter();
- const TString error = "Unable to resolve token";
- const auto issue = MakeIssue(NKikimrIssues::TIssuesIds::YDB_AUTH_UNAVAILABLE, error);
- requestBaseCtx->RaiseIssue(issue);
- requestBaseCtx->ReplyUnavaliable();
- return;
- }
-
- TString databaseName;
- const TDatabaseInfo* database = nullptr;
- bool skipResourceCheck = false;
+ }
+
+ TString databaseName;
+ const TDatabaseInfo* database = nullptr;
+ bool skipResourceCheck = false;
// do not check connect rights for the deprecated requests without database
// remove this along with AllowYdbRequestsWithoutDatabase flag
bool skipCheckConnectRigths = false;
- if (state.State == NGrpc::TAuthState::AS_NOT_PERFORMED) {
- const auto& maybeDatabaseName = requestBaseCtx->GetDatabaseName();
- if (maybeDatabaseName && !maybeDatabaseName.GetRef().empty()) {
- databaseName = CanonizePath(maybeDatabaseName.GetRef());
- } else {
- if (!AllowYdbRequestsWithoutDatabase) {
- requestBaseCtx->ReplyUnauthenticated("Requests without specified database is not allowed");
+ if (state.State == NGrpc::TAuthState::AS_NOT_PERFORMED) {
+ const auto& maybeDatabaseName = requestBaseCtx->GetDatabaseName();
+ if (maybeDatabaseName && !maybeDatabaseName.GetRef().empty()) {
+ databaseName = CanonizePath(maybeDatabaseName.GetRef());
+ } else {
+ if (!AllowYdbRequestsWithoutDatabase) {
+ requestBaseCtx->ReplyUnauthenticated("Requests without specified database is not allowed");
return;
- } else {
- databaseName = RootDatabase;
- skipResourceCheck = true;
+ } else {
+ databaseName = RootDatabase;
+ skipResourceCheck = true;
skipCheckConnectRigths = true;
}
}
- auto it = Databases.find(databaseName);
- if (it != Databases.end() && it->second.IsDatabaseReady()) {
- database = &it->second;
- } else {
- // No given database found, start update if possible
- if (!DeferAndStartUpdate(databaseName, event, requestBaseCtx)) {
- Counters->IncDatabaseUnavailableCounter();
- const TString error = "Grpc proxy is not ready to accept request, database unknown";
- LOG_ERROR(ctx, NKikimrServices::GRPC_SERVER, "Limit for deferred events per database %s reached", databaseName.c_str());
- const auto issue = MakeIssue(NKikimrIssues::TIssuesIds::YDB_DB_NOT_READY, error);
- requestBaseCtx->RaiseIssue(issue);
- requestBaseCtx->ReplyUnavaliable();
+ auto it = Databases.find(databaseName);
+ if (it != Databases.end() && it->second.IsDatabaseReady()) {
+ database = &it->second;
+ } else {
+ // No given database found, start update if possible
+ if (!DeferAndStartUpdate(databaseName, event, requestBaseCtx)) {
+ Counters->IncDatabaseUnavailableCounter();
+ const TString error = "Grpc proxy is not ready to accept request, database unknown";
+ LOG_ERROR(ctx, NKikimrServices::GRPC_SERVER, "Limit for deferred events per database %s reached", databaseName.c_str());
+ const auto issue = MakeIssue(NKikimrIssues::TIssuesIds::YDB_DB_NOT_READY, error);
+ requestBaseCtx->RaiseIssue(issue);
+ requestBaseCtx->ReplyUnavaliable();
}
- return;
+ return;
}
}
- if (database) {
- if (database->SchemeBoardResult) {
- const auto& domain = database->SchemeBoardResult->DescribeSchemeResult.GetPathDescription().GetDomainDescription();
- if (domain.HasResourcesDomainKey() && !skipResourceCheck && DynamicNode) {
- TSubDomainKey subdomainKey(domain.GetResourcesDomainKey());
- if (!SubDomainKeys.contains(subdomainKey)) {
- TStringBuilder error;
- error << "Unexpected node to perform query on database: " << databaseName
- << ", resource domain: " << domain.GetResourcesDomainKey().ShortDebugString();
- LOG_ERROR(ctx, NKikimrServices::GRPC_SERVER, error);
- auto issue = MakeIssue(NKikimrIssues::TIssuesIds::ACCESS_DENIED, error);
- requestBaseCtx->RaiseIssue(issue);
- requestBaseCtx->ReplyWithYdbStatus(Ydb::StatusIds::UNAUTHORIZED);
- return;
- }
- }
- } else {
- Counters->IncDatabaseUnavailableCounter();
- auto issue = MakeIssue(NKikimrIssues::TIssuesIds::YDB_DB_NOT_READY, "database unavailable");
- requestBaseCtx->RaiseIssue(issue);
- requestBaseCtx->ReplyWithYdbStatus(Ydb::StatusIds::UNAVAILABLE);
- return;
- }
-
- Register(CreateGrpcRequestCheckActor<TEvent>(SelfId(),
- database->SchemeBoardResult->DescribeSchemeResult,
+ if (database) {
+ if (database->SchemeBoardResult) {
+ const auto& domain = database->SchemeBoardResult->DescribeSchemeResult.GetPathDescription().GetDomainDescription();
+ if (domain.HasResourcesDomainKey() && !skipResourceCheck && DynamicNode) {
+ TSubDomainKey subdomainKey(domain.GetResourcesDomainKey());
+ if (!SubDomainKeys.contains(subdomainKey)) {
+ TStringBuilder error;
+ error << "Unexpected node to perform query on database: " << databaseName
+ << ", resource domain: " << domain.GetResourcesDomainKey().ShortDebugString();
+ LOG_ERROR(ctx, NKikimrServices::GRPC_SERVER, error);
+ auto issue = MakeIssue(NKikimrIssues::TIssuesIds::ACCESS_DENIED, error);
+ requestBaseCtx->RaiseIssue(issue);
+ requestBaseCtx->ReplyWithYdbStatus(Ydb::StatusIds::UNAUTHORIZED);
+ return;
+ }
+ }
+ } else {
+ Counters->IncDatabaseUnavailableCounter();
+ auto issue = MakeIssue(NKikimrIssues::TIssuesIds::YDB_DB_NOT_READY, "database unavailable");
+ requestBaseCtx->RaiseIssue(issue);
+ requestBaseCtx->ReplyWithYdbStatus(Ydb::StatusIds::UNAVAILABLE);
+ return;
+ }
+
+ Register(CreateGrpcRequestCheckActor<TEvent>(SelfId(),
+ database->SchemeBoardResult->DescribeSchemeResult,
database->SecurityObject, event.Release(), Counters, skipCheckConnectRigths));
- return;
+ return;
}
- // in case we somehow skipped all auth checks
- const auto issue = MakeIssue(NKikimrIssues::TIssuesIds::GENERIC_TXPROXY_ERROR, "Can't authenticate request");
- requestBaseCtx->RaiseIssue(issue);
- requestBaseCtx->ReplyWithYdbStatus(Ydb::StatusIds::BAD_REQUEST);
+ // in case we somehow skipped all auth checks
+ const auto issue = MakeIssue(NKikimrIssues::TIssuesIds::GENERIC_TXPROXY_ERROR, "Can't authenticate request");
+ requestBaseCtx->RaiseIssue(issue);
+ requestBaseCtx->ReplyWithYdbStatus(Ydb::StatusIds::BAD_REQUEST);
}
- void ForgetDatabase(const TString& database);
- void SubscribeToDatabase(const TString& database);
- void DoStartUpdate(const TString& database);
- bool DeferAndStartUpdate(const TString& database, TAutoPtr<IEventHandle>& ev, IRequestProxyCtx*);
+ void ForgetDatabase(const TString& database);
+ void SubscribeToDatabase(const TString& database);
+ void DoStartUpdate(const TString& database);
+ bool DeferAndStartUpdate(const TString& database, TAutoPtr<IEventHandle>& ev, IRequestProxyCtx*);
- const NKikimrConfig::TAppConfig& GetAppConfig() const override {
- return AppConfig;
+ const NKikimrConfig::TAppConfig& GetAppConfig() const override {
+ return AppConfig;
}
- virtual void PassAway() override {
- for (auto& [database, queue] : DeferredEvents) {
- for (TEventReqHolder& req : queue) {
- req.Ctx->ReplyUnavaliable();
+ virtual void PassAway() override {
+ for (auto& [database, queue] : DeferredEvents) {
+ for (TEventReqHolder& req : queue) {
+ req.Ctx->ReplyUnavaliable();
}
}
- for (const auto& [database, actor] : Subscribers) {
- Send(actor, new TEvents::TEvPoisonPill());
+ for (const auto& [database, actor] : Subscribers) {
+ Send(actor, new TEvents::TEvPoisonPill());
}
- TBase::PassAway();
+ TBase::PassAway();
}
- std::unordered_map<TString, TDatabaseInfo> Databases;
- std::unordered_map<TString, std::deque<TEventReqHolder>> DeferredEvents; // Events deferred to handle after getting database info
- std::unordered_map<TString, TActorId> Subscribers;
+ std::unordered_map<TString, TDatabaseInfo> Databases;
+ std::unordered_map<TString, std::deque<TEventReqHolder>> DeferredEvents; // Events deferred to handle after getting database info
+ std::unordered_map<TString, TActorId> Subscribers;
THashSet<TSubDomainKey> SubDomainKeys;
bool AllowYdbRequestsWithoutDatabase = true;
NKikimrConfig::TAppConfig AppConfig;
TActorId SchemeCache;
bool DynamicNode = false;
- TString RootDatabase;
+ TString RootDatabase;
TIntrusivePtr<TGrpcProxyCounters> Counters;
};
@@ -318,63 +318,63 @@ void TGRpcRequestProxyImpl::Bootstrap(const TActorContext& ctx) {
Counters = MakeIntrusive<TGrpcProxyCounters>(AppData()->Counters);
- RootDatabase = DatabaseFromDomain();
- TDatabaseInfo& database = Databases[RootDatabase];
- database.DatabaseType = TDatabaseInfo::TDatabaseType::Root;
- database.State = NKikimrTenantPool::EState::TENANT_OK;
- DoStartUpdate(RootDatabase);
-
+ RootDatabase = DatabaseFromDomain();
+ TDatabaseInfo& database = Databases[RootDatabase];
+ database.DatabaseType = TDatabaseInfo::TDatabaseType::Root;
+ database.State = NKikimrTenantPool::EState::TENANT_OK;
+ DoStartUpdate(RootDatabase);
+
Become(&TThis::StateFunc);
}
-void TGRpcRequestProxyImpl::ReplayEvents(const TString& databaseName, const TActorContext& ctx) {
- auto itDeferredEvents = DeferredEvents.find(databaseName);
- if (itDeferredEvents != DeferredEvents.end()) {
- std::deque<TEventReqHolder>& queue = itDeferredEvents->second;
- std::deque<TEventReqHolder> deferredEvents;
- std::swap(deferredEvents, queue); // we can put back event to DeferredEvents queue in StateFunc KIKIMR-12851
- while (!deferredEvents.empty()) {
+void TGRpcRequestProxyImpl::ReplayEvents(const TString& databaseName, const TActorContext& ctx) {
+ auto itDeferredEvents = DeferredEvents.find(databaseName);
+ if (itDeferredEvents != DeferredEvents.end()) {
+ std::deque<TEventReqHolder>& queue = itDeferredEvents->second;
+ std::deque<TEventReqHolder> deferredEvents;
+ std::swap(deferredEvents, queue); // we can put back event to DeferredEvents queue in StateFunc KIKIMR-12851
+ while (!deferredEvents.empty()) {
StateFunc(deferredEvents.front().Ev, ctx);
- deferredEvents.pop_front();
- }
- if (queue.empty()) {
- DeferredEvents.erase(itDeferredEvents);
- }
- }
-}
-
+ deferredEvents.pop_front();
+ }
+ if (queue.empty()) {
+ DeferredEvents.erase(itDeferredEvents);
+ }
+ }
+}
+
void TGRpcRequestProxyImpl::HandlePoolStatus(TEvTenantPool::TEvTenantPoolStatus::TPtr& ev, const TActorContext& ctx) {
const auto &event = ev->Get()->Record;
- LOG_INFO_S(ctx, NKikimrServices::GRPC_SERVER, "Received tenant pool status, serving tenants: " << event.ShortDebugString());
+ LOG_INFO_S(ctx, NKikimrServices::GRPC_SERVER, "Received tenant pool status, serving tenants: " << event.ShortDebugString());
SubDomainKeys.clear();
- for (auto it = Databases.begin(); it != Databases.end();) {
- if (it->second.DatabaseType != TDatabaseInfo::TDatabaseType::Root) {
- it = Databases.erase(it);
- } else {
- ++it;
- }
- }
+ for (auto it = Databases.begin(); it != Databases.end();) {
+ if (it->second.DatabaseType != TDatabaseInfo::TDatabaseType::Root) {
+ it = Databases.erase(it);
+ } else {
+ ++it;
+ }
+ }
for (const auto& slot : event.GetSlots()) {
- if (slot.GetAssignedTenant().empty()) {
- continue;
+ if (slot.GetAssignedTenant().empty()) {
+ continue;
}
const auto& subDomainKey = TSubDomainKey(slot.GetDomainKey());
if (subDomainKey) {
SubDomainKeys.insert(subDomainKey);
}
- TString databaseName = CanonizePath(slot.GetAssignedTenant());
- auto itDatabase = Databases.try_emplace(databaseName);
- if (itDatabase.second) {
- TDatabaseInfo& database = itDatabase.first->second;
- database.State = slot.GetState();
- database.DatabaseType = TDatabaseInfo::TDatabaseType::Tenant;
- DoStartUpdate(databaseName);
- }
- TDatabaseInfo& database = itDatabase.first->second;
- if (database.IsDatabaseReady()) {
- ReplayEvents(databaseName, ctx);
- }
+ TString databaseName = CanonizePath(slot.GetAssignedTenant());
+ auto itDatabase = Databases.try_emplace(databaseName);
+ if (itDatabase.second) {
+ TDatabaseInfo& database = itDatabase.first->second;
+ database.State = slot.GetState();
+ database.DatabaseType = TDatabaseInfo::TDatabaseType::Tenant;
+ DoStartUpdate(databaseName);
+ }
+ TDatabaseInfo& database = itDatabase.first->second;
+ if (database.IsDatabaseReady()) {
+ ReplayEvents(databaseName, ctx);
+ }
}
}
@@ -424,97 +424,97 @@ void TGRpcRequestProxyImpl::HandleUndelivery(TEvents::TEvUndelivered::TPtr& ev)
}
}
-bool TGRpcRequestProxyImpl::IsAuthStateOK(const IRequestProxyCtx& ctx) {
- const auto& state = ctx.GetAuthState();
+bool TGRpcRequestProxyImpl::IsAuthStateOK(const IRequestProxyCtx& ctx) {
+ const auto& state = ctx.GetAuthState();
return state.State == NGrpc::TAuthState::AS_OK ||
state.State == NGrpc::TAuthState::AS_FAIL && state.NeedAuth == false ||
state.NeedAuth == false && !ctx.GetYdbToken();
}
-void TGRpcRequestProxyImpl::HandleSchemeBoard(TSchemeBoardEvents::TEvNotifyUpdate::TPtr& ev, const TActorContext& ctx) {
- TString databaseName = ev->Get()->Path;
- LOG_DEBUG_S(*TlsActivationContext, NKikimrServices::GRPC_SERVER, "SchemeBoardUpdate " << databaseName);
+void TGRpcRequestProxyImpl::HandleSchemeBoard(TSchemeBoardEvents::TEvNotifyUpdate::TPtr& ev, const TActorContext& ctx) {
+ TString databaseName = ev->Get()->Path;
+ LOG_DEBUG_S(*TlsActivationContext, NKikimrServices::GRPC_SERVER, "SchemeBoardUpdate " << databaseName);
- // non-serverless databases should be in the cache already
- auto itDatabase = Databases.try_emplace(CanonizePath(databaseName));
- TDatabaseInfo& database = itDatabase.first->second;
- if (itDatabase.second) {
- database.State = NKikimrTenantPool::EState::TENANT_OK;
- database.DatabaseType = TDatabaseInfo::TDatabaseType::Serverless;
+ // non-serverless databases should be in the cache already
+ auto itDatabase = Databases.try_emplace(CanonizePath(databaseName));
+ TDatabaseInfo& database = itDatabase.first->second;
+ if (itDatabase.second) {
+ database.State = NKikimrTenantPool::EState::TENANT_OK;
+ database.DatabaseType = TDatabaseInfo::TDatabaseType::Serverless;
}
- database.SchemeBoardResult = ev->Release();
- const NKikimrScheme::TEvDescribeSchemeResult& describeScheme(database.SchemeBoardResult->DescribeSchemeResult);
- database.SecurityObject = new TSecurityObject(describeScheme.GetPathDescription().GetSelf().GetOwner(),
- describeScheme.GetPathDescription().GetSelf().GetEffectiveACL(), false);
-
- if (describeScheme.GetPathDescription().HasDomainDescription()
- && describeScheme.GetPathDescription().GetDomainDescription().HasSecurityState()) {
- LOG_DEBUG_S(*TlsActivationContext, NKikimrServices::GRPC_SERVER, "Updating SecurityState for " << databaseName);
- Send(MakeTicketParserID(), new TEvTicketParser::TEvUpdateLoginSecurityState(
- describeScheme.GetPathDescription().GetDomainDescription().GetSecurityState()
- ));
- } else {
- if (!describeScheme.GetPathDescription().HasDomainDescription()) {
- LOG_DEBUG_S(*TlsActivationContext, NKikimrServices::GRPC_SERVER, "Can't update SecurityState for " << databaseName << " - no DomainDescription");
- } else if (!describeScheme.GetPathDescription().GetDomainDescription().HasSecurityState()) {
- LOG_DEBUG_S(*TlsActivationContext, NKikimrServices::GRPC_SERVER, "Can't update SecurityState for " << databaseName << " - no SecurityState");
+ database.SchemeBoardResult = ev->Release();
+ const NKikimrScheme::TEvDescribeSchemeResult& describeScheme(database.SchemeBoardResult->DescribeSchemeResult);
+ database.SecurityObject = new TSecurityObject(describeScheme.GetPathDescription().GetSelf().GetOwner(),
+ describeScheme.GetPathDescription().GetSelf().GetEffectiveACL(), false);
+
+ if (describeScheme.GetPathDescription().HasDomainDescription()
+ && describeScheme.GetPathDescription().GetDomainDescription().HasSecurityState()) {
+ LOG_DEBUG_S(*TlsActivationContext, NKikimrServices::GRPC_SERVER, "Updating SecurityState for " << databaseName);
+ Send(MakeTicketParserID(), new TEvTicketParser::TEvUpdateLoginSecurityState(
+ describeScheme.GetPathDescription().GetDomainDescription().GetSecurityState()
+ ));
+ } else {
+ if (!describeScheme.GetPathDescription().HasDomainDescription()) {
+ LOG_DEBUG_S(*TlsActivationContext, NKikimrServices::GRPC_SERVER, "Can't update SecurityState for " << databaseName << " - no DomainDescription");
+ } else if (!describeScheme.GetPathDescription().GetDomainDescription().HasSecurityState()) {
+ LOG_DEBUG_S(*TlsActivationContext, NKikimrServices::GRPC_SERVER, "Can't update SecurityState for " << databaseName << " - no SecurityState");
}
}
- if (database.IsDatabaseReady()) {
- ReplayEvents(databaseName, ctx);
+ if (database.IsDatabaseReady()) {
+ ReplayEvents(databaseName, ctx);
}
}
-void TGRpcRequestProxyImpl::HandleSchemeBoard(TSchemeBoardEvents::TEvNotifyDelete::TPtr& ev) {
- LOG_WARN_S(*TlsActivationContext, NKikimrServices::GRPC_SERVER,
- "SchemeBoardDelete " << ev->Get()->Path << " Strong=" << ev->Get()->Strong);
+void TGRpcRequestProxyImpl::HandleSchemeBoard(TSchemeBoardEvents::TEvNotifyDelete::TPtr& ev) {
+ LOG_WARN_S(*TlsActivationContext, NKikimrServices::GRPC_SERVER,
+ "SchemeBoardDelete " << ev->Get()->Path << " Strong=" << ev->Get()->Strong);
- if (ev->Get()->Strong) {
- ForgetDatabase(ev->Get()->Path);
- }
+ if (ev->Get()->Strong) {
+ ForgetDatabase(ev->Get()->Path);
+ }
}
-void TGRpcRequestProxyImpl::ForgetDatabase(const TString& database) {
- auto itSubscriber = Subscribers.find(database);
- if (itSubscriber != Subscribers.end()) {
- Send(itSubscriber->second, new TEvents::TEvPoisonPill());
- Subscribers.erase(itSubscriber);
+void TGRpcRequestProxyImpl::ForgetDatabase(const TString& database) {
+ auto itSubscriber = Subscribers.find(database);
+ if (itSubscriber != Subscribers.end()) {
+ Send(itSubscriber->second, new TEvents::TEvPoisonPill());
+ Subscribers.erase(itSubscriber);
}
- auto itDeferredEvents = DeferredEvents.find(database);
- if (itDeferredEvents != DeferredEvents.end()) {
- auto& queue(itDeferredEvents->second);
- while (!queue.empty()) {
- Counters->IncDatabaseUnavailableCounter();
- queue.front().Ctx->ReplyUnauthenticated("Unknown database");
- queue.pop_front();
- }
- DeferredEvents.erase(itDeferredEvents);
+ auto itDeferredEvents = DeferredEvents.find(database);
+ if (itDeferredEvents != DeferredEvents.end()) {
+ auto& queue(itDeferredEvents->second);
+ while (!queue.empty()) {
+ Counters->IncDatabaseUnavailableCounter();
+ queue.front().Ctx->ReplyUnauthenticated("Unknown database");
+ queue.pop_front();
+ }
+ DeferredEvents.erase(itDeferredEvents);
}
- Databases.erase(database);
-}
+ Databases.erase(database);
+}
-void TGRpcRequestProxyImpl::SubscribeToDatabase(const TString& database) {
- LOG_DEBUG_S(*TlsActivationContext, NKikimrServices::GRPC_SERVER, "Subscribe to " << database);
+void TGRpcRequestProxyImpl::SubscribeToDatabase(const TString& database) {
+ LOG_DEBUG_S(*TlsActivationContext, NKikimrServices::GRPC_SERVER, "Subscribe to " << database);
- Y_VERIFY(!AppData()->DomainsInfo->Domains.empty());
- auto& domain = AppData()->DomainsInfo->Domains.begin()->second;
- ui64 domainOwnerId = domain->SchemeRoot;
- ui32 schemeBoardGroup = domain->DefaultSchemeBoardGroup;
+ Y_VERIFY(!AppData()->DomainsInfo->Domains.empty());
+ auto& domain = AppData()->DomainsInfo->Domains.begin()->second;
+ ui64 domainOwnerId = domain->SchemeRoot;
+ ui32 schemeBoardGroup = domain->DefaultSchemeBoardGroup;
THolder<IActor> subscriber{CreateSchemeBoardSubscriber(SelfId(), database, schemeBoardGroup, domainOwnerId)};
- TActorId subscriberId = Register(subscriber.Release());
- auto itSubscriber = Subscribers.emplace(database, subscriberId);
- if (!itSubscriber.second) {
- Send(itSubscriber.first->second, new TEvents::TEvPoisonPill());
- itSubscriber.first->second = subscriberId;
- }
+ TActorId subscriberId = Register(subscriber.Release());
+ auto itSubscriber = Subscribers.emplace(database, subscriberId);
+ if (!itSubscriber.second) {
+ Send(itSubscriber.first->second, new TEvents::TEvPoisonPill());
+ itSubscriber.first->second = subscriberId;
+ }
+}
+
+void TGRpcRequestProxyImpl::DoStartUpdate(const TString& database) {
+ // we will receive update (or delete) upon sucessfull subscription
+ SubscribeToDatabase(database);
}
-void TGRpcRequestProxyImpl::DoStartUpdate(const TString& database) {
- // we will receive update (or delete) upon sucessfull subscription
- SubscribeToDatabase(database);
-}
-
template<typename TEvent>
void LogRequest(const TEvent& event) {
auto getDebugString = [&event]()->TString {
@@ -542,139 +542,139 @@ void LogRequest(const TEvent& event) {
}
void TGRpcRequestProxyImpl::StateFunc(TAutoPtr<IEventHandle>& ev, const TActorContext& ctx) {
- bool handled = true;
- // handle internal events
+ bool handled = true;
+ // handle internal events
switch (ev->GetTypeRewrite()) {
HFunc(TEvTenantPool::TEvTenantPoolStatus, HandlePoolStatus);
hFunc(TEvTxUserProxy::TEvGetProxyServicesResponse, HandleProxyService);
hFunc(NConsole::TEvConfigsDispatcher::TEvSetConfigSubscriptionResponse, HandleConfig);
hFunc(NConsole::TEvConsole::TEvConfigNotificationRequest, HandleConfig);
hFunc(TEvents::TEvUndelivered, HandleUndelivery);
- HFunc(TSchemeBoardEvents::TEvNotifyUpdate, HandleSchemeBoard);
- hFunc(TSchemeBoardEvents::TEvNotifyDelete, HandleSchemeBoard);
+ HFunc(TSchemeBoardEvents::TEvNotifyUpdate, HandleSchemeBoard);
+ hFunc(TSchemeBoardEvents::TEvNotifyDelete, HandleSchemeBoard);
default:
- handled = false;
- break;
+ handled = false;
+ break;
}
- if (handled) {
+ if (handled) {
return;
}
- // handle external events
- switch (ev->GetTypeRewrite()) {
- HFunc(TRefreshTokenImpl, PreHandle);
- HFunc(TEvLoginRequest, PreHandle);
- HFunc(TEvAlterTableRequest, PreHandle);
- HFunc(TEvCreateTableRequest, PreHandle);
- HFunc(TEvDropTableRequest, PreHandle);
- HFunc(TEvGetOperationRequest, PreHandle);
- HFunc(TEvCancelOperationRequest, PreHandle);
- HFunc(TEvForgetOperationRequest, PreHandle);
- HFunc(TEvListOperationsRequest, PreHandle);
- HFunc(TEvCreateSessionRequest, PreHandle);
- HFunc(TEvKeepAliveRequest, PreHandle);
- HFunc(TEvDeleteSessionRequest, PreHandle);
- HFunc(TEvCopyTableRequest, PreHandle);
- HFunc(TEvCopyTablesRequest, PreHandle);
+ // handle external events
+ switch (ev->GetTypeRewrite()) {
+ HFunc(TRefreshTokenImpl, PreHandle);
+ HFunc(TEvLoginRequest, PreHandle);
+ HFunc(TEvAlterTableRequest, PreHandle);
+ HFunc(TEvCreateTableRequest, PreHandle);
+ HFunc(TEvDropTableRequest, PreHandle);
+ HFunc(TEvGetOperationRequest, PreHandle);
+ HFunc(TEvCancelOperationRequest, PreHandle);
+ HFunc(TEvForgetOperationRequest, PreHandle);
+ HFunc(TEvListOperationsRequest, PreHandle);
+ HFunc(TEvCreateSessionRequest, PreHandle);
+ HFunc(TEvKeepAliveRequest, PreHandle);
+ HFunc(TEvDeleteSessionRequest, PreHandle);
+ HFunc(TEvCopyTableRequest, PreHandle);
+ HFunc(TEvCopyTablesRequest, PreHandle);
HFunc(TEvRenameTablesRequest, PreHandle);
- HFunc(TEvDescribeTableRequest, PreHandle);
- HFunc(TEvReadTableRequest, PreHandle);
- HFunc(TEvExplainDataQueryRequest, PreHandle);
- HFunc(TEvPrepareDataQueryRequest, PreHandle);
- HFunc(TEvExecuteDataQueryRequest, PreHandle);
- HFunc(TEvExecuteSchemeQueryRequest, PreHandle);
- HFunc(TEvCreateTenantRequest, PreHandle);
- HFunc(TEvAlterTenantRequest, PreHandle);
- HFunc(TEvGetTenantStatusRequest, PreHandle);
- HFunc(TEvListTenantsRequest, PreHandle);
- HFunc(TEvRemoveTenantRequest, PreHandle);
- HFunc(TEvBeginTransactionRequest, PreHandle);
- HFunc(TEvCommitTransactionRequest, PreHandle);
- HFunc(TEvRollbackTransactionRequest, PreHandle);
- HFunc(TEvListEndpointsRequest, PreHandle);
- HFunc(TEvDescribeTenantOptionsRequest, PreHandle);
- HFunc(TEvDescribeTableOptionsRequest, PreHandle);
- HFunc(TEvCreateCoordinationNode, PreHandle);
- HFunc(TEvAlterCoordinationNode, PreHandle);
- HFunc(TEvDropCoordinationNode, PreHandle);
- HFunc(TEvDescribeCoordinationNode, PreHandle);
- HFunc(TEvReadColumnsRequest, PreHandle);
- HFunc(TEvGetShardLocationsRequest, PreHandle);
- HFunc(TEvKikhouseDescribeTableRequest, PreHandle);
- HFunc(TEvS3ListingRequest, PreHandle);
- HFunc(TEvBiStreamPingRequest, PreHandle);
- HFunc(TEvExperimentalStreamQueryRequest, PreHandle);
- HFunc(TEvStreamPQWriteRequest, PreHandle);
- HFunc(TEvStreamPQReadRequest, PreHandle);
- HFunc(TEvPQReadInfoRequest, PreHandle);
- HFunc(TEvPQDropTopicRequest, PreHandle);
- HFunc(TEvPQCreateTopicRequest, PreHandle);
- HFunc(TEvPQAlterTopicRequest, PreHandle);
- HFunc(TEvPQAddReadRuleRequest, PreHandle);
- HFunc(TEvPQRemoveReadRuleRequest, PreHandle);
- HFunc(TEvPQDescribeTopicRequest, PreHandle);
- HFunc(TEvExportToYtRequest, PreHandle);
- HFunc(TEvExportToS3Request, PreHandle);
- HFunc(TEvImportFromS3Request, PreHandle);
- HFunc(TEvImportDataRequest, PreHandle);
- HFunc(TEvDiscoverPQClustersRequest, PreHandle);
- HFunc(TEvBulkUpsertRequest, PreHandle);
- HFunc(TEvWhoAmIRequest, PreHandle);
- HFunc(TEvCreateRateLimiterResource, PreHandle);
- HFunc(TEvAlterRateLimiterResource, PreHandle);
- HFunc(TEvDropRateLimiterResource, PreHandle);
- HFunc(TEvListRateLimiterResources, PreHandle);
- HFunc(TEvDescribeRateLimiterResource, PreHandle);
- HFunc(TEvAcquireRateLimiterResource, PreHandle);
- HFunc(TEvKikhouseCreateSnapshotRequest, PreHandle);
- HFunc(TEvKikhouseRefreshSnapshotRequest, PreHandle);
- HFunc(TEvKikhouseDiscardSnapshotRequest, PreHandle);
- HFunc(TEvSelfCheckRequest, PreHandle);
- HFunc(TEvStreamExecuteScanQueryRequest, PreHandle);
- HFunc(TEvCoordinationSessionRequest, PreHandle);
- HFunc(TEvLongTxBeginRequest, PreHandle);
- HFunc(TEvLongTxCommitRequest, PreHandle);
- HFunc(TEvLongTxRollbackRequest, PreHandle);
- HFunc(TEvLongTxWriteRequest, PreHandle);
- HFunc(TEvLongTxReadRequest, PreHandle);
- HFunc(TEvDataStreamsCreateStreamRequest, PreHandle);
- HFunc(TEvDataStreamsDeleteStreamRequest, PreHandle);
- HFunc(TEvDataStreamsDescribeStreamRequest, PreHandle);
- HFunc(TEvDataStreamsRegisterStreamConsumerRequest, PreHandle);
- HFunc(TEvDataStreamsDeregisterStreamConsumerRequest, PreHandle);
- HFunc(TEvDataStreamsDescribeStreamConsumerRequest, PreHandle);
- HFunc(TEvDataStreamsPutRecordRequest, PreHandle);
- HFunc(TEvDataStreamsListStreamsRequest, PreHandle);
- HFunc(TEvDataStreamsListShardsRequest, PreHandle);
- HFunc(TEvDataStreamsPutRecordsRequest, PreHandle);
- HFunc(TEvDataStreamsGetRecordsRequest, PreHandle);
- HFunc(TEvDataStreamsGetShardIteratorRequest, PreHandle);
- HFunc(TEvDataStreamsSubscribeToShardRequest, PreHandle);
- HFunc(TEvDataStreamsDescribeLimitsRequest, PreHandle);
- HFunc(TEvDataStreamsDescribeStreamSummaryRequest, PreHandle);
- HFunc(TEvDataStreamsDecreaseStreamRetentionPeriodRequest, PreHandle);
- HFunc(TEvDataStreamsIncreaseStreamRetentionPeriodRequest, PreHandle);
- HFunc(TEvDataStreamsUpdateShardCountRequest, PreHandle);
- HFunc(TEvDataStreamsUpdateStreamRequest, PreHandle);
- HFunc(TEvDataStreamsSetWriteQuotaRequest, PreHandle);
- HFunc(TEvDataStreamsListStreamConsumersRequest, PreHandle);
- HFunc(TEvDataStreamsAddTagsToStreamRequest, PreHandle);
- HFunc(TEvDataStreamsDisableEnhancedMonitoringRequest, PreHandle);
- HFunc(TEvDataStreamsEnableEnhancedMonitoringRequest, PreHandle);
- HFunc(TEvDataStreamsListTagsForStreamRequest, PreHandle);
- HFunc(TEvDataStreamsMergeShardsRequest, PreHandle);
- HFunc(TEvDataStreamsRemoveTagsFromStreamRequest, PreHandle);
- HFunc(TEvDataStreamsSplitShardRequest, PreHandle);
- HFunc(TEvDataStreamsStartStreamEncryptionRequest, PreHandle);
- HFunc(TEvDataStreamsStopStreamEncryptionRequest, PreHandle);
+ HFunc(TEvDescribeTableRequest, PreHandle);
+ HFunc(TEvReadTableRequest, PreHandle);
+ HFunc(TEvExplainDataQueryRequest, PreHandle);
+ HFunc(TEvPrepareDataQueryRequest, PreHandle);
+ HFunc(TEvExecuteDataQueryRequest, PreHandle);
+ HFunc(TEvExecuteSchemeQueryRequest, PreHandle);
+ HFunc(TEvCreateTenantRequest, PreHandle);
+ HFunc(TEvAlterTenantRequest, PreHandle);
+ HFunc(TEvGetTenantStatusRequest, PreHandle);
+ HFunc(TEvListTenantsRequest, PreHandle);
+ HFunc(TEvRemoveTenantRequest, PreHandle);
+ HFunc(TEvBeginTransactionRequest, PreHandle);
+ HFunc(TEvCommitTransactionRequest, PreHandle);
+ HFunc(TEvRollbackTransactionRequest, PreHandle);
+ HFunc(TEvListEndpointsRequest, PreHandle);
+ HFunc(TEvDescribeTenantOptionsRequest, PreHandle);
+ HFunc(TEvDescribeTableOptionsRequest, PreHandle);
+ HFunc(TEvCreateCoordinationNode, PreHandle);
+ HFunc(TEvAlterCoordinationNode, PreHandle);
+ HFunc(TEvDropCoordinationNode, PreHandle);
+ HFunc(TEvDescribeCoordinationNode, PreHandle);
+ HFunc(TEvReadColumnsRequest, PreHandle);
+ HFunc(TEvGetShardLocationsRequest, PreHandle);
+ HFunc(TEvKikhouseDescribeTableRequest, PreHandle);
+ HFunc(TEvS3ListingRequest, PreHandle);
+ HFunc(TEvBiStreamPingRequest, PreHandle);
+ HFunc(TEvExperimentalStreamQueryRequest, PreHandle);
+ HFunc(TEvStreamPQWriteRequest, PreHandle);
+ HFunc(TEvStreamPQReadRequest, PreHandle);
+ HFunc(TEvPQReadInfoRequest, PreHandle);
+ HFunc(TEvPQDropTopicRequest, PreHandle);
+ HFunc(TEvPQCreateTopicRequest, PreHandle);
+ HFunc(TEvPQAlterTopicRequest, PreHandle);
+ HFunc(TEvPQAddReadRuleRequest, PreHandle);
+ HFunc(TEvPQRemoveReadRuleRequest, PreHandle);
+ HFunc(TEvPQDescribeTopicRequest, PreHandle);
+ HFunc(TEvExportToYtRequest, PreHandle);
+ HFunc(TEvExportToS3Request, PreHandle);
+ HFunc(TEvImportFromS3Request, PreHandle);
+ HFunc(TEvImportDataRequest, PreHandle);
+ HFunc(TEvDiscoverPQClustersRequest, PreHandle);
+ HFunc(TEvBulkUpsertRequest, PreHandle);
+ HFunc(TEvWhoAmIRequest, PreHandle);
+ HFunc(TEvCreateRateLimiterResource, PreHandle);
+ HFunc(TEvAlterRateLimiterResource, PreHandle);
+ HFunc(TEvDropRateLimiterResource, PreHandle);
+ HFunc(TEvListRateLimiterResources, PreHandle);
+ HFunc(TEvDescribeRateLimiterResource, PreHandle);
+ HFunc(TEvAcquireRateLimiterResource, PreHandle);
+ HFunc(TEvKikhouseCreateSnapshotRequest, PreHandle);
+ HFunc(TEvKikhouseRefreshSnapshotRequest, PreHandle);
+ HFunc(TEvKikhouseDiscardSnapshotRequest, PreHandle);
+ HFunc(TEvSelfCheckRequest, PreHandle);
+ HFunc(TEvStreamExecuteScanQueryRequest, PreHandle);
+ HFunc(TEvCoordinationSessionRequest, PreHandle);
+ HFunc(TEvLongTxBeginRequest, PreHandle);
+ HFunc(TEvLongTxCommitRequest, PreHandle);
+ HFunc(TEvLongTxRollbackRequest, PreHandle);
+ HFunc(TEvLongTxWriteRequest, PreHandle);
+ HFunc(TEvLongTxReadRequest, PreHandle);
+ HFunc(TEvDataStreamsCreateStreamRequest, PreHandle);
+ HFunc(TEvDataStreamsDeleteStreamRequest, PreHandle);
+ HFunc(TEvDataStreamsDescribeStreamRequest, PreHandle);
+ HFunc(TEvDataStreamsRegisterStreamConsumerRequest, PreHandle);
+ HFunc(TEvDataStreamsDeregisterStreamConsumerRequest, PreHandle);
+ HFunc(TEvDataStreamsDescribeStreamConsumerRequest, PreHandle);
+ HFunc(TEvDataStreamsPutRecordRequest, PreHandle);
+ HFunc(TEvDataStreamsListStreamsRequest, PreHandle);
+ HFunc(TEvDataStreamsListShardsRequest, PreHandle);
+ HFunc(TEvDataStreamsPutRecordsRequest, PreHandle);
+ HFunc(TEvDataStreamsGetRecordsRequest, PreHandle);
+ HFunc(TEvDataStreamsGetShardIteratorRequest, PreHandle);
+ HFunc(TEvDataStreamsSubscribeToShardRequest, PreHandle);
+ HFunc(TEvDataStreamsDescribeLimitsRequest, PreHandle);
+ HFunc(TEvDataStreamsDescribeStreamSummaryRequest, PreHandle);
+ HFunc(TEvDataStreamsDecreaseStreamRetentionPeriodRequest, PreHandle);
+ HFunc(TEvDataStreamsIncreaseStreamRetentionPeriodRequest, PreHandle);
+ HFunc(TEvDataStreamsUpdateShardCountRequest, PreHandle);
+ HFunc(TEvDataStreamsUpdateStreamRequest, PreHandle);
+ HFunc(TEvDataStreamsSetWriteQuotaRequest, PreHandle);
+ HFunc(TEvDataStreamsListStreamConsumersRequest, PreHandle);
+ HFunc(TEvDataStreamsAddTagsToStreamRequest, PreHandle);
+ HFunc(TEvDataStreamsDisableEnhancedMonitoringRequest, PreHandle);
+ HFunc(TEvDataStreamsEnableEnhancedMonitoringRequest, PreHandle);
+ HFunc(TEvDataStreamsListTagsForStreamRequest, PreHandle);
+ HFunc(TEvDataStreamsMergeShardsRequest, PreHandle);
+ HFunc(TEvDataStreamsRemoveTagsFromStreamRequest, PreHandle);
+ HFunc(TEvDataStreamsSplitShardRequest, PreHandle);
+ HFunc(TEvDataStreamsStartStreamEncryptionRequest, PreHandle);
+ HFunc(TEvDataStreamsStopStreamEncryptionRequest, PreHandle);
HFunc(TEvProxyRuntimeEvent, PreHandle);
- default:
- Y_FAIL("Unknown request: %u\n", ev->GetTypeRewrite());
- break;
+ default:
+ Y_FAIL("Unknown request: %u\n", ev->GetTypeRewrite());
+ break;
}
}
diff --git a/ydb/core/grpc_services/grpc_request_proxy.h b/ydb/core/grpc_services/grpc_request_proxy.h
index 40ea7d8ce01..97315f6e9fb 100644
--- a/ydb/core/grpc_services/grpc_request_proxy.h
+++ b/ydb/core/grpc_services/grpc_request_proxy.h
@@ -1,7 +1,7 @@
#pragma once
-#include "grpc_endpoint.h"
-
+#include "grpc_endpoint.h"
+
#include "rpc_calls.h"
#include <library/cpp/actors/core/actor.h>
@@ -112,8 +112,8 @@ protected:
void Handle(TEvKikhouseCreateSnapshotRequest::TPtr& ev, const TActorContext& ctx);
void Handle(TEvKikhouseRefreshSnapshotRequest::TPtr& ev, const TActorContext& ctx);
void Handle(TEvKikhouseDiscardSnapshotRequest::TPtr& ev, const TActorContext& ctx);
- void Handle(TEvSelfCheckRequest::TPtr& ev, const TActorContext& ctx);
- void Handle(TEvLoginRequest::TPtr& ev, const TActorContext& ctx);
+ void Handle(TEvSelfCheckRequest::TPtr& ev, const TActorContext& ctx);
+ void Handle(TEvLoginRequest::TPtr& ev, const TActorContext& ctx);
void Handle(TEvStreamExecuteScanQueryRequest::TPtr& ev, const TActorContext& ctx);
void Handle(TEvCoordinationSessionRequest::TPtr& ev, const TActorContext& ctx);
void Handle(TEvLongTxBeginRequest::TPtr& ev, const TActorContext& ctx);
diff --git a/ydb/core/grpc_services/local_rate_limiter.cpp b/ydb/core/grpc_services/local_rate_limiter.cpp
index 6229b3d4dcf..3a2fcb78cb4 100644
--- a/ydb/core/grpc_services/local_rate_limiter.cpp
+++ b/ydb/core/grpc_services/local_rate_limiter.cpp
@@ -31,7 +31,7 @@ TActorId RateLimiterAcquireUseSameMailbox(
};
Ydb::RateLimiter::AcquireResourceRequest request;
- SetDuration(duration, *request.mutable_operation_params()->mutable_operation_timeout());
+ SetDuration(duration, *request.mutable_operation_params()->mutable_operation_timeout());
request.set_coordination_node_path(fullPath.CoordinationNode);
request.set_resource_path(fullPath.ResourcePath);
request.set_required(required);
@@ -81,7 +81,7 @@ TActorId RateLimiterAcquireUseSameMailbox(
const auto& rlPath = maybeRlPath.GetRef();
Ydb::RateLimiter::AcquireResourceRequest request;
- SetDuration(duration, *request.mutable_operation_params()->mutable_operation_timeout());
+ SetDuration(duration, *request.mutable_operation_params()->mutable_operation_timeout());
request.set_coordination_node_path(rlPath.CoordinationNode);
request.set_resource_path(rlPath.ResourcePath);
request.set_required(required);
diff --git a/ydb/core/grpc_services/operation_helpers.cpp b/ydb/core/grpc_services/operation_helpers.cpp
index 28df648cc64..66e95a319ab 100644
--- a/ydb/core/grpc_services/operation_helpers.cpp
+++ b/ydb/core/grpc_services/operation_helpers.cpp
@@ -39,14 +39,14 @@ IEventBase* CreateNavigateForPath(const TString& path) {
auto& entry = request->ResultSet.emplace_back();
entry.Operation = NSchemeCache::TSchemeCacheNavigate::OpPath;
entry.Path = ::NKikimr::SplitPath(path);
- entry.RedirectRequired = false;
+ entry.RedirectRequired = false;
return new TEvTxProxySchemeCache::TEvNavigateKeySet(request.Release());
}
TActorId CreatePipeClient(ui64 id, const TActorContext& ctx) {
NTabletPipe::TClientConfig clientConfig;
- clientConfig.RetryPolicy = {.RetryLimitCount = 3};
+ clientConfig.RetryPolicy = {.RetryLimitCount = 3};
return ctx.RegisterWithSameMailbox(NTabletPipe::CreateClient(ctx.SelfID, id, clientConfig));
}
@@ -147,12 +147,12 @@ public:
}
NTabletPipe::TClientConfig config;
- config.RetryPolicy = {
- .RetryLimitCount = 5,
- .MinRetryTime = TDuration::MilliSeconds(50),
- .MaxRetryTime = TDuration::Seconds(10),
- .DoFirstRetryInstantly = false
- };
+ config.RetryPolicy = {
+ .RetryLimitCount = 5,
+ .MinRetryTime = TDuration::MilliSeconds(50),
+ .MaxRetryTime = TDuration::Seconds(10),
+ .DoFirstRetryInstantly = false
+ };
SSPipeClient = ctx.RegisterWithSameMailbox(NTabletPipe::CreateClient(ctx.SelfID, SchemeshardId, config));
AttemptsCounter++;
diff --git a/ydb/core/grpc_services/rpc_calls.h b/ydb/core/grpc_services/rpc_calls.h
index a4dddae0514..43136c2f4ad 100644
--- a/ydb/core/grpc_services/rpc_calls.h
+++ b/ydb/core/grpc_services/rpc_calls.h
@@ -111,7 +111,7 @@ using TEvKikhouseCreateSnapshotRequest = TGRpcRequestWrapper<TRpcServices::EvKik
using TEvKikhouseRefreshSnapshotRequest = TGRpcRequestWrapper<TRpcServices::EvKikhouseRefreshSnapshot, Ydb::ClickhouseInternal::RefreshSnapshotRequest, Ydb::ClickhouseInternal::RefreshSnapshotResponse, true>;
using TEvKikhouseDiscardSnapshotRequest = TGRpcRequestWrapper<TRpcServices::EvKikhouseDiscardSnapshot, Ydb::ClickhouseInternal::DiscardSnapshotRequest, Ydb::ClickhouseInternal::DiscardSnapshotResponse, true>;
using TEvSelfCheckRequest = TGRpcRequestWrapper<TRpcServices::EvSelfCheck, Ydb::Monitoring::SelfCheckRequest, Ydb::Monitoring::SelfCheckResponse, true>;
-using TEvLoginRequest = TGRpcRequestWrapperNoAuth<TRpcServices::EvLogin, Ydb::Auth::LoginRequest, Ydb::Auth::LoginResponse>;
+using TEvLoginRequest = TGRpcRequestWrapperNoAuth<TRpcServices::EvLogin, Ydb::Auth::LoginRequest, Ydb::Auth::LoginResponse>;
using TEvStreamExecuteScanQueryRequest = TGRpcRequestWrapper<TRpcServices::EvStreamExecuteScanQuery, Ydb::Table::ExecuteScanQueryRequest, Ydb::Table::ExecuteScanQueryPartialResponse, false, TRateLimiterMode::RuOnProgress>;
using TEvCoordinationSessionRequest = TGRpcRequestBiStreamWrapper<TRpcServices::EvCoordinationSession, Ydb::Coordination::SessionRequest, Ydb::Coordination::SessionResponse>;
using TEvLongTxBeginRequest = TGRpcRequestWrapper<TRpcServices::EvLongTxBegin, Ydb::LongTx::BeginTransactionRequest, Ydb::LongTx::BeginTransactionResponse, true>;
diff --git a/ydb/core/grpc_services/rpc_cms.cpp b/ydb/core/grpc_services/rpc_cms.cpp
index a913c37b050..78450233069 100644
--- a/ydb/core/grpc_services/rpc_cms.cpp
+++ b/ydb/core/grpc_services/rpc_cms.cpp
@@ -36,7 +36,7 @@ public:
ui32 group = dinfo->GetDefaultStateStorageGroup(domain->DomainUid);
NTabletPipe::TClientConfig pipeConfig;
- pipeConfig.RetryPolicy = {.RetryLimitCount = 10};
+ pipeConfig.RetryPolicy = {.RetryLimitCount = 10};
auto pipe = NTabletPipe::CreateClient(ctx.SelfID, MakeConsoleID(group), pipeConfig);
CmsPipe = ctx.RegisterWithSameMailbox(pipe);
diff --git a/ydb/core/grpc_services/rpc_describe_path.cpp b/ydb/core/grpc_services/rpc_describe_path.cpp
index f321098b6b7..7960f50779b 100644
--- a/ydb/core/grpc_services/rpc_describe_path.cpp
+++ b/ydb/core/grpc_services/rpc_describe_path.cpp
@@ -55,7 +55,7 @@ private:
}
void Handle(NSchemeShard::TEvSchemeShard::TEvDescribeSchemeResult::TPtr& ev, const TActorContext& ctx) {
- const auto& record = ev->Get()->GetRecord();
+ const auto& record = ev->Get()->GetRecord();
const auto status = record.GetStatus();
if (record.HasReason()) {
diff --git a/ydb/core/grpc_services/rpc_describe_table.cpp b/ydb/core/grpc_services/rpc_describe_table.cpp
index 0b44023ccfc..261f10d4676 100644
--- a/ydb/core/grpc_services/rpc_describe_table.cpp
+++ b/ydb/core/grpc_services/rpc_describe_table.cpp
@@ -37,7 +37,7 @@ private:
}
void Handle(NSchemeShard::TEvSchemeShard::TEvDescribeSchemeResult::TPtr& ev, const TActorContext& ctx) {
- const auto& record = ev->Get()->GetRecord();
+ const auto& record = ev->Get()->GetRecord();
const auto status = record.GetStatus();
if (record.HasReason()) {
auto issue = NYql::TIssue(record.GetReason());
diff --git a/ydb/core/grpc_services/rpc_get_shard_locations.cpp b/ydb/core/grpc_services/rpc_get_shard_locations.cpp
index e7939458deb..f7088c8eb60 100644
--- a/ydb/core/grpc_services/rpc_get_shard_locations.cpp
+++ b/ydb/core/grpc_services/rpc_get_shard_locations.cpp
@@ -94,10 +94,10 @@ private:
NTabletPipe::TClientConfig clientConfig;
clientConfig.AllowFollower = false;
clientConfig.CheckAliveness = false;
- clientConfig.RetryPolicy = {
- .RetryLimitCount = 2,
- .MinRetryTime = TDuration::MilliSeconds(5),
- };
+ clientConfig.RetryPolicy = {
+ .RetryLimitCount = 2,
+ .MinRetryTime = TDuration::MilliSeconds(5),
+ };
ShardPipes[ti] = ctx.Register(NTabletPipe::CreateClient(ctx.SelfID, ti, clientConfig));
}
diff --git a/ydb/core/grpc_services/rpc_login.cpp b/ydb/core/grpc_services/rpc_login.cpp
index faad29720a3..9815aeac99b 100644
--- a/ydb/core/grpc_services/rpc_login.cpp
+++ b/ydb/core/grpc_services/rpc_login.cpp
@@ -1,126 +1,126 @@
-#include "grpc_request_proxy.h"
-
-#include "rpc_calls.h"
-#include "rpc_kqp_base.h"
-#include "rpc_request_base.h"
-
+#include "grpc_request_proxy.h"
+
+#include "rpc_calls.h"
+#include "rpc_kqp_base.h"
+#include "rpc_request_base.h"
+
#include <ydb/core/tx/schemeshard/schemeshard.h>
#include <ydb/core/tx/scheme_cache/scheme_cache.h>
-
-namespace NKikimr {
-namespace NGRpcService {
-
+
+namespace NKikimr {
+namespace NGRpcService {
+
using namespace NSchemeShard;
-
-class TLoginRPC : public TRpcRequestActor<TLoginRPC, TEvLoginRequest> {
-public:
- using TRpcRequestActor::TRpcRequestActor;
-
+
+class TLoginRPC : public TRpcRequestActor<TLoginRPC, TEvLoginRequest> {
+public:
+ using TRpcRequestActor::TRpcRequestActor;
+
THolder<TEvSchemeShard::TEvLoginResult> Result;
- Ydb::StatusIds_StatusCode Status = Ydb::StatusIds::SUCCESS;
- TDuration Timeout = TDuration::MilliSeconds(60000);
+ Ydb::StatusIds_StatusCode Status = Ydb::StatusIds::SUCCESS;
+ TDuration Timeout = TDuration::MilliSeconds(60000);
TActorId PipeClient;
-
- NTabletPipe::TClientConfig GetPipeClientConfig() {
- NTabletPipe::TClientConfig clientConfig;
- clientConfig.RetryPolicy = {.RetryLimitCount = 3};
- return clientConfig;
- }
-
- void Bootstrap() {
- TString domainName = "/" + AppData()->DomainsInfo->Domains.begin()->second->Name;
- TString path = AppData()->AuthConfig.GetDomainLoginOnly() ? domainName : DatabaseName;
- auto request = MakeHolder<NSchemeCache::TSchemeCacheNavigate>();
- request->DatabaseName = path;
- auto& entry = request->ResultSet.emplace_back();
- entry.Operation = NSchemeCache::TSchemeCacheNavigate::OpPath;
- entry.Path = ::NKikimr::SplitPath(path);
- entry.RedirectRequired = false;
- Send(MakeSchemeCacheID(), new TEvTxProxySchemeCache::TEvNavigateKeySet(request.Release()));
-
- Become(&TThis::StateWork, Timeout, new TEvents::TEvWakeup());
- }
-
- void HandleTimeout() {
- Status = Ydb::StatusIds::TIMEOUT;
- ReplyAndPassAway();
- }
-
- void HandleNavigate(TEvTxProxySchemeCache::TEvNavigateKeySetResult::TPtr& ev) {
- const NSchemeCache::TSchemeCacheNavigate* response = ev->Get()->Request.Get();
- if (response->ResultSet.size() == 1) {
- const NSchemeCache::TSchemeCacheNavigate::TEntry& entry = response->ResultSet.front();
- ui64 schemeShardTabletId = entry.DomainInfo->ExtractSchemeShard();
- IActor* pipe = NTabletPipe::CreateClient(SelfId(), schemeShardTabletId, GetPipeClientConfig());
+
+ NTabletPipe::TClientConfig GetPipeClientConfig() {
+ NTabletPipe::TClientConfig clientConfig;
+ clientConfig.RetryPolicy = {.RetryLimitCount = 3};
+ return clientConfig;
+ }
+
+ void Bootstrap() {
+ TString domainName = "/" + AppData()->DomainsInfo->Domains.begin()->second->Name;
+ TString path = AppData()->AuthConfig.GetDomainLoginOnly() ? domainName : DatabaseName;
+ auto request = MakeHolder<NSchemeCache::TSchemeCacheNavigate>();
+ request->DatabaseName = path;
+ auto& entry = request->ResultSet.emplace_back();
+ entry.Operation = NSchemeCache::TSchemeCacheNavigate::OpPath;
+ entry.Path = ::NKikimr::SplitPath(path);
+ entry.RedirectRequired = false;
+ Send(MakeSchemeCacheID(), new TEvTxProxySchemeCache::TEvNavigateKeySet(request.Release()));
+
+ Become(&TThis::StateWork, Timeout, new TEvents::TEvWakeup());
+ }
+
+ void HandleTimeout() {
+ Status = Ydb::StatusIds::TIMEOUT;
+ ReplyAndPassAway();
+ }
+
+ void HandleNavigate(TEvTxProxySchemeCache::TEvNavigateKeySetResult::TPtr& ev) {
+ const NSchemeCache::TSchemeCacheNavigate* response = ev->Get()->Request.Get();
+ if (response->ResultSet.size() == 1) {
+ const NSchemeCache::TSchemeCacheNavigate::TEntry& entry = response->ResultSet.front();
+ ui64 schemeShardTabletId = entry.DomainInfo->ExtractSchemeShard();
+ IActor* pipe = NTabletPipe::CreateClient(SelfId(), schemeShardTabletId, GetPipeClientConfig());
PipeClient = RegisterWithSameMailbox(pipe);
THolder<TEvSchemeShard::TEvLogin> request = MakeHolder<TEvSchemeShard::TEvLogin>();
- const Ydb::Auth::LoginRequest* protoRequest = Request->GetProtoRequest();
- request.Get()->Record.SetUser(protoRequest->user());
- request.Get()->Record.SetPassword(protoRequest->password());
+ const Ydb::Auth::LoginRequest* protoRequest = Request->GetProtoRequest();
+ request.Get()->Record.SetUser(protoRequest->user());
+ request.Get()->Record.SetPassword(protoRequest->password());
NTabletPipe::SendData(SelfId(), PipeClient, request.Release());
- return;
- }
- Status = Ydb::StatusIds::SCHEME_ERROR;
- ReplyAndPassAway();
- }
-
+ return;
+ }
+ Status = Ydb::StatusIds::SCHEME_ERROR;
+ ReplyAndPassAway();
+ }
+
void HandleResult(TEvSchemeShard::TEvLoginResult::TPtr& ev) {
- Status = Ydb::StatusIds::SUCCESS;
- Result = ev->Release();
- ReplyAndPassAway();
- }
-
- void HandleUndelivered(TEvents::TEvUndelivered::TPtr&) {
- Status = Ydb::StatusIds::UNAVAILABLE;
- ReplyAndPassAway();
- }
-
- void HandleConnect(TEvTabletPipe::TEvClientConnected::TPtr& ev) {
- if (ev->Get()->Status != NKikimrProto::OK) {
- Status = Ydb::StatusIds::UNAVAILABLE;
- ReplyAndPassAway();
- }
- }
-
- STATEFN(StateWork) {
- switch (ev->GetTypeRewrite()) {
- hFunc(TEvents::TEvUndelivered, HandleUndelivered);
- hFunc(TEvTabletPipe::TEvClientConnected, HandleConnect);
- hFunc(TEvTxProxySchemeCache::TEvNavigateKeySetResult, HandleNavigate);
+ Status = Ydb::StatusIds::SUCCESS;
+ Result = ev->Release();
+ ReplyAndPassAway();
+ }
+
+ void HandleUndelivered(TEvents::TEvUndelivered::TPtr&) {
+ Status = Ydb::StatusIds::UNAVAILABLE;
+ ReplyAndPassAway();
+ }
+
+ void HandleConnect(TEvTabletPipe::TEvClientConnected::TPtr& ev) {
+ if (ev->Get()->Status != NKikimrProto::OK) {
+ Status = Ydb::StatusIds::UNAVAILABLE;
+ ReplyAndPassAway();
+ }
+ }
+
+ STATEFN(StateWork) {
+ switch (ev->GetTypeRewrite()) {
+ hFunc(TEvents::TEvUndelivered, HandleUndelivered);
+ hFunc(TEvTabletPipe::TEvClientConnected, HandleConnect);
+ hFunc(TEvTxProxySchemeCache::TEvNavigateKeySetResult, HandleNavigate);
hFunc(TEvSchemeShard::TEvLoginResult, HandleResult);
- cFunc(TEvents::TSystem::Wakeup, HandleTimeout);
- }
- }
-
- void ReplyAndPassAway() {
+ cFunc(TEvents::TSystem::Wakeup, HandleTimeout);
+ }
+ }
+
+ void ReplyAndPassAway() {
if (PipeClient) {
NTabletPipe::CloseClient(SelfId(), PipeClient);
}
- TResponse response;
- Ydb::Operations::Operation& operation = *response.mutable_operation();
- if (Result) {
+ TResponse response;
+ Ydb::Operations::Operation& operation = *response.mutable_operation();
+ if (Result) {
const NKikimrScheme::TEvLoginResult& record = Result->Record;
- if (record.error()) {
- Ydb::Issue::IssueMessage* issue = operation.add_issues();
- issue->set_message(record.error());
- issue->set_issue_code(Ydb::StatusIds::UNAUTHORIZED);
- Status = Ydb::StatusIds::UNAUTHORIZED;
- }
- if (record.token()) {
- Ydb::Auth::LoginResult result;
- result.set_token(record.token());
- operation.mutable_result()->PackFrom(result);
- }
- }
- operation.set_ready(true);
- operation.set_status(Status);
- return Reply(response);
- }
-};
-
-void TGRpcRequestProxy::Handle(TEvLoginRequest::TPtr& ev, const TActorContext& ctx) {
- ctx.Register(new TLoginRPC(ev->Release().Release()));
-}
-
-} // namespace NGRpcService
-} // namespace NKikimr
+ if (record.error()) {
+ Ydb::Issue::IssueMessage* issue = operation.add_issues();
+ issue->set_message(record.error());
+ issue->set_issue_code(Ydb::StatusIds::UNAUTHORIZED);
+ Status = Ydb::StatusIds::UNAUTHORIZED;
+ }
+ if (record.token()) {
+ Ydb::Auth::LoginResult result;
+ result.set_token(record.token());
+ operation.mutable_result()->PackFrom(result);
+ }
+ }
+ operation.set_ready(true);
+ operation.set_status(Status);
+ return Reply(response);
+ }
+};
+
+void TGRpcRequestProxy::Handle(TEvLoginRequest::TPtr& ev, const TActorContext& ctx) {
+ ctx.Register(new TLoginRPC(ev->Release().Release()));
+}
+
+} // namespace NGRpcService
+} // namespace NKikimr
diff --git a/ydb/core/grpc_services/rpc_monitoring.cpp b/ydb/core/grpc_services/rpc_monitoring.cpp
index e3d2550a06b..5640cdb5e22 100644
--- a/ydb/core/grpc_services/rpc_monitoring.cpp
+++ b/ydb/core/grpc_services/rpc_monitoring.cpp
@@ -1,77 +1,77 @@
-#include "grpc_request_proxy.h"
-
-#include "rpc_calls.h"
-#include "rpc_kqp_base.h"
-#include "rpc_request_base.h"
-
+#include "grpc_request_proxy.h"
+
+#include "rpc_calls.h"
+#include "rpc_kqp_base.h"
+#include "rpc_request_base.h"
+
#include <ydb/library/yql/public/issue/yql_issue_message.h>
#include <ydb/library/yql/public/issue/yql_issue.h>
-
-#include <library/cpp/actors/core/interconnect.h>
-#include <library/cpp/actors/core/hfunc.h>
-#include <library/cpp/actors/interconnect/interconnect.h>
-#include <library/cpp/digest/old_crc/crc.h>
-
-#include <util/random/shuffle.h>
-
+
+#include <library/cpp/actors/core/interconnect.h>
+#include <library/cpp/actors/core/hfunc.h>
+#include <library/cpp/actors/interconnect/interconnect.h>
+#include <library/cpp/digest/old_crc/crc.h>
+
+#include <util/random/shuffle.h>
+
#include <ydb/core/health_check/health_check.h>
-
-namespace NKikimr {
-namespace NGRpcService {
-
-using namespace NActors;
-using namespace Ydb;
-
-class TSelfCheckRPC : public TRpcRequestActor<TSelfCheckRPC, TEvSelfCheckRequest> {
-public:
- using TRpcRequestActor::TRpcRequestActor;
-
- THolder<NHealthCheck::TEvSelfCheckResult> Result;
- Ydb::StatusIds_StatusCode Status = Ydb::StatusIds::SUCCESS;
-
- void Bootstrap() {
- THolder<NHealthCheck::TEvSelfCheckRequest> request = MakeHolder<NHealthCheck::TEvSelfCheckRequest>();
- request->Request = *(Request->GetProtoRequest());
- if (Request->GetDatabaseName()) {
- request->Database = Request->GetDatabaseName().GetRef();
- }
- Send(NHealthCheck::MakeHealthCheckID(), request.Release());
- Become(&TThis::StateWait);
- }
-
- STATEFN(StateWait) {
- switch (ev->GetTypeRewrite()) {
- hFunc(TEvents::TEvUndelivered, Handle);
- hFunc(NHealthCheck::TEvSelfCheckResult, Handle);
- }
- }
-
- void Handle(NHealthCheck::TEvSelfCheckResult::TPtr& ev) {
- Status = Ydb::StatusIds::SUCCESS;
- Result = ev->Release();
- ReplyAndPassAway();
- }
-
- void Handle(TEvents::TEvUndelivered::TPtr&) {
- Status = Ydb::StatusIds::UNAVAILABLE;
- ReplyAndPassAway();
- }
-
- void ReplyAndPassAway() {
- TResponse response;
- Ydb::Operations::Operation& operation = *response.mutable_operation();
- operation.set_ready(true);
- operation.set_status(Status);
- if (Result) {
- operation.mutable_result()->PackFrom(Result->Result);
- }
- return Reply(response);
- }
-};
-
-void TGRpcRequestProxy::Handle(TEvSelfCheckRequest::TPtr& ev, const TActorContext& ctx) {
- ctx.Register(new TSelfCheckRPC(ev->Release().Release()));
-}
-
-} // namespace NGRpcService
-} // namespace NKikimr
+
+namespace NKikimr {
+namespace NGRpcService {
+
+using namespace NActors;
+using namespace Ydb;
+
+class TSelfCheckRPC : public TRpcRequestActor<TSelfCheckRPC, TEvSelfCheckRequest> {
+public:
+ using TRpcRequestActor::TRpcRequestActor;
+
+ THolder<NHealthCheck::TEvSelfCheckResult> Result;
+ Ydb::StatusIds_StatusCode Status = Ydb::StatusIds::SUCCESS;
+
+ void Bootstrap() {
+ THolder<NHealthCheck::TEvSelfCheckRequest> request = MakeHolder<NHealthCheck::TEvSelfCheckRequest>();
+ request->Request = *(Request->GetProtoRequest());
+ if (Request->GetDatabaseName()) {
+ request->Database = Request->GetDatabaseName().GetRef();
+ }
+ Send(NHealthCheck::MakeHealthCheckID(), request.Release());
+ Become(&TThis::StateWait);
+ }
+
+ STATEFN(StateWait) {
+ switch (ev->GetTypeRewrite()) {
+ hFunc(TEvents::TEvUndelivered, Handle);
+ hFunc(NHealthCheck::TEvSelfCheckResult, Handle);
+ }
+ }
+
+ void Handle(NHealthCheck::TEvSelfCheckResult::TPtr& ev) {
+ Status = Ydb::StatusIds::SUCCESS;
+ Result = ev->Release();
+ ReplyAndPassAway();
+ }
+
+ void Handle(TEvents::TEvUndelivered::TPtr&) {
+ Status = Ydb::StatusIds::UNAVAILABLE;
+ ReplyAndPassAway();
+ }
+
+ void ReplyAndPassAway() {
+ TResponse response;
+ Ydb::Operations::Operation& operation = *response.mutable_operation();
+ operation.set_ready(true);
+ operation.set_status(Status);
+ if (Result) {
+ operation.mutable_result()->PackFrom(Result->Result);
+ }
+ return Reply(response);
+ }
+};
+
+void TGRpcRequestProxy::Handle(TEvSelfCheckRequest::TPtr& ev, const TActorContext& ctx) {
+ ctx.Register(new TSelfCheckRPC(ev->Release().Release()));
+}
+
+} // namespace NGRpcService
+} // namespace NKikimr
diff --git a/ydb/core/grpc_services/rpc_operation_request_base.h b/ydb/core/grpc_services/rpc_operation_request_base.h
index 45057e2dd5a..697d2109cd7 100644
--- a/ydb/core/grpc_services/rpc_operation_request_base.h
+++ b/ydb/core/grpc_services/rpc_operation_request_base.h
@@ -105,7 +105,7 @@ protected:
if (!PipeClient) {
NTabletPipe::TClientConfig config;
- config.RetryPolicy = {.RetryLimitCount = 3};
+ config.RetryPolicy = {.RetryLimitCount = 3};
PipeClient = this->RegisterWithSameMailbox(NTabletPipe::CreateClient(this->SelfId(), schemeShardId, config));
}
diff --git a/ydb/core/grpc_services/rpc_rate_limiter_api.cpp b/ydb/core/grpc_services/rpc_rate_limiter_api.cpp
index 1baa46bb782..5579be8bdb3 100644
--- a/ydb/core/grpc_services/rpc_rate_limiter_api.cpp
+++ b/ydb/core/grpc_services/rpc_rate_limiter_api.cpp
@@ -158,9 +158,9 @@ protected:
NTabletPipe::TClientConfig GetPipeConfig() {
NTabletPipe::TClientConfig cfg;
- cfg.RetryPolicy = {
- .RetryLimitCount = 3u
- };
+ cfg.RetryPolicy = {
+ .RetryLimitCount = 3u
+ };
return cfg;
}
diff --git a/ydb/core/grpc_services/rpc_whoami.cpp b/ydb/core/grpc_services/rpc_whoami.cpp
index 93e4504543b..b8b2dadfcf1 100644
--- a/ydb/core/grpc_services/rpc_whoami.cpp
+++ b/ydb/core/grpc_services/rpc_whoami.cpp
@@ -21,12 +21,12 @@ public:
void Bootstrap(const TActorContext& ctx) {
TMaybe<TString> authToken = Request->GetYdbToken();
if (authToken) {
- TMaybe<TString> database = Request->GetDatabaseName();
- ctx.Send(MakeTicketParserID(), new TEvTicketParser::TEvAuthorizeTicket({
- .Database = database ? database.GetRef() : TString(),
- .Ticket = authToken.GetRef(),
- .PeerName = Request->GetPeerName()
- }));
+ TMaybe<TString> database = Request->GetDatabaseName();
+ ctx.Send(MakeTicketParserID(), new TEvTicketParser::TEvAuthorizeTicket({
+ .Database = database ? database.GetRef() : TString(),
+ .Ticket = authToken.GetRef(),
+ .PeerName = Request->GetPeerName()
+ }));
Become(&TThis::StateWaitForTicket);
} else {
ReplyError("No token provided");
@@ -37,14 +37,14 @@ public:
STFUNC(StateWaitForTicket) {
Y_UNUSED(ctx);
switch (ev->GetTypeRewrite()) {
- hFunc(TEvTicketParser::TEvAuthorizeTicketResult, Handle);
+ hFunc(TEvTicketParser::TEvAuthorizeTicketResult, Handle);
hFunc(TEvents::TEvUndelivered, Handle);
}
}
private:
- void Handle(TEvTicketParser::TEvAuthorizeTicketResult::TPtr& ev) {
- const TEvTicketParser::TEvAuthorizeTicketResult& result(*ev->Get());
+ void Handle(TEvTicketParser::TEvAuthorizeTicketResult::TPtr& ev) {
+ const TEvTicketParser::TEvAuthorizeTicketResult& result(*ev->Get());
auto *response = TEvWhoAmIRequest::AllocateResult<Ydb::Discovery::WhoAmIResult>(Request);
if (!result.Error) {
if (result.Token != nullptr) {
diff --git a/ydb/core/grpc_services/ya.make b/ydb/core/grpc_services/ya.make
index f03bb0e115b..05b156bf043 100644
--- a/ydb/core/grpc_services/ya.make
+++ b/ydb/core/grpc_services/ya.make
@@ -6,10 +6,10 @@ OWNER(
)
SRCS(
- grpc_endpoint_publish_actor.cpp
+ grpc_endpoint_publish_actor.cpp
grpc_helper.cpp
grpc_mon.cpp
- grpc_publisher_service_actor.cpp
+ grpc_publisher_service_actor.cpp
grpc_request_proxy.cpp
local_rate_limiter.cpp
operation_helpers.cpp
@@ -50,13 +50,13 @@ SRCS(
rpc_kh_snapshots.cpp
rpc_kqp_base.cpp
rpc_list_operations.cpp
- rpc_login.cpp
+ rpc_login.cpp
rpc_load_rows.cpp
rpc_log_store.cpp
rpc_long_tx.cpp
rpc_make_directory.cpp
rpc_modify_permissions.cpp
- rpc_monitoring.cpp
+ rpc_monitoring.cpp
rpc_prepare_data_query.cpp
rpc_rate_limiter_api.cpp
rpc_read_columns.cpp
@@ -78,7 +78,7 @@ SRCS(
PEERDIR(
contrib/libs/xxhash
library/cpp/cgiparam
- library/cpp/digest/old_crc
+ library/cpp/digest/old_crc
ydb/core/actorlib_impl
ydb/core/base
ydb/core/control
diff --git a/ydb/core/health_check/health_check.cpp b/ydb/core/health_check/health_check.cpp
index f3126436625..7995c58aafc 100644
--- a/ydb/core/health_check/health_check.cpp
+++ b/ydb/core/health_check/health_check.cpp
@@ -1,15 +1,15 @@
-#include "health_check.h"
-
+#include "health_check.h"
+
#include <ydb/library/yql/public/issue/yql_issue_message.h>
#include <ydb/library/yql/public/issue/yql_issue.h>
-
-#include <library/cpp/actors/core/interconnect.h>
-#include <library/cpp/actors/core/hfunc.h>
-#include <library/cpp/actors/interconnect/interconnect.h>
-#include <library/cpp/digest/old_crc/crc.h>
-
-#include <util/random/shuffle.h>
-
+
+#include <library/cpp/actors/core/interconnect.h>
+#include <library/cpp/actors/core/hfunc.h>
+#include <library/cpp/actors/interconnect/interconnect.h>
+#include <library/cpp/digest/old_crc/crc.h>
+
+#include <util/random/shuffle.h>
+
#include <ydb/core/base/hive.h>
#include <ydb/core/base/path.h>
#include <ydb/core/base/tablet_pipe.h>
@@ -21,1471 +21,1471 @@
#include <ydb/core/tx/schemeshard/schemeshard.h>
#include <ydb/core/util/proto_duration.h>
#include <ydb/core/util/tuples.h>
-
-static decltype(auto) make_vslot_tuple(const NKikimrBlobStorage::TVSlotId& id) {
- return std::make_tuple(id.GetNodeId(), id.GetPDiskId(), id.GetVSlotId());
-}
-
-namespace std {
-
-template <>
-struct equal_to<NKikimrBlobStorage::TVSlotId> {
- bool operator ()(const NKikimrBlobStorage::TVSlotId& a, const NKikimrBlobStorage::TVSlotId& b) const {
- return make_vslot_tuple(a) == make_vslot_tuple(b);
- }
-};
-
-template <>
-struct hash<NKikimrBlobStorage::TVSlotId> {
- size_t operator ()(const NKikimrBlobStorage::TVSlotId& a) const {
- auto tp = make_vslot_tuple(a);
- return hash<decltype(tp)>()(tp);
- }
-};
-
-}
-
-#define BLOG_CRIT(stream) LOG_CRIT_S(*TlsActivationContext, NKikimrServices::HEALTH, stream)
-
-namespace NKikimr {
-namespace NHealthCheck {
-
-using namespace NActors;
-using namespace Ydb;
-
-struct TEvPrivate {
- enum EEv {
- EvRetryNodeWhiteboard = EventSpaceBegin(NActors::TEvents::ES_PRIVATE),
- EvEnd
- };
-
- static_assert(EvEnd < EventSpaceEnd(NActors::TEvents::ES_PRIVATE), "expect EvEnd < EventSpaceEnd(TEvents::ES_PRIVATE)");
-
- struct TEvRetryNodeWhiteboard : NActors::TEventLocal<TEvRetryNodeWhiteboard, EvRetryNodeWhiteboard> {
- TNodeId NodeId;
- int EventId;
-
- TEvRetryNodeWhiteboard(TNodeId nodeId, int eventId)
- : NodeId(nodeId)
- , EventId(eventId)
- {}
- };
-};
-
-class TSelfCheckRequest : public TActorBootstrapped<TSelfCheckRequest> {
-public:
- static constexpr NKikimrServices::TActivity::EType ActorActivityType() { return NKikimrServices::TActivity::MONITORING_REQUEST; }
-
- TActorId Sender;
- THolder<TEvSelfCheckRequest> Request;
- ui64 Cookie;
-
- TSelfCheckRequest(const TActorId& sender, THolder<TEvSelfCheckRequest> request, ui64 cookie)
- : Sender(sender)
- , Request(std::move(request))
- , Cookie(cookie)
- {}
-
- using TGroupId = ui32;
-
- struct TTenantInfo {
- TString Name;
- Ydb::Cms::GetDatabaseStatusResult::State State;
- };
-
- struct TNodeTabletState {
- struct TTabletStateSettings {
- TInstant AliveBarrier;
- ui32 MaxRestartsPerPeriod = 30; // per hour
- ui32 MaxTabletIdsStored = 10;
- bool ReportGoodTabletsIds = false;
- };
-
- enum class ETabletState {
- Good,
- Stopped,
- RestartsTooOften,
- Dead,
- };
-
- struct TNodeTabletStateCount {
- NKikimrTabletBase::TTabletTypes::EType Type;
- ETabletState State;
- int Count = 1;
- TStackVec<TString> Identifiers;
-
- TNodeTabletStateCount(const NKikimrHive::TTabletInfo& info, const TTabletStateSettings& settings) {
- Type = info.tablettype();
- if (info.volatilestate() == NKikimrHive::TABLET_VOLATILE_STATE_STOPPED) {
- State = ETabletState::Stopped;
- } else if (info.volatilestate() != NKikimrHive::TABLET_VOLATILE_STATE_RUNNING
- && TInstant::MilliSeconds(info.lastalivetimestamp()) < settings.AliveBarrier
- && info.tabletbootmode() == NKikimrHive::TABLET_BOOT_MODE_DEFAULT) {
- State = ETabletState::Dead;
- } else if (info.restartsperperiod() >= settings.MaxRestartsPerPeriod) {
- State = ETabletState::RestartsTooOften;
- } else {
- State = ETabletState::Good;
- }
- }
-
- bool operator ==(const TNodeTabletStateCount& o) const {
- return State == o.State && Type == o.Type;
- }
- };
-
- TStackVec<TNodeTabletStateCount> Count;
-
- void AddTablet(const NKikimrHive::TTabletInfo& info, const TTabletStateSettings& settings) {
- TNodeTabletStateCount tabletState(info, settings);
- auto itCount = Find(Count, tabletState);
- if (itCount != Count.end()) {
- itCount->Count++;
- } else {
- Count.emplace_back(tabletState);
- itCount = std::prev(Count.end());
- }
- if (itCount->State != ETabletState::Good || settings.ReportGoodTabletsIds) {
- if (itCount->Identifiers.size() < settings.MaxTabletIdsStored) {
- TStringBuilder id;
- id << info.tabletid();
+
+static decltype(auto) make_vslot_tuple(const NKikimrBlobStorage::TVSlotId& id) {
+ return std::make_tuple(id.GetNodeId(), id.GetPDiskId(), id.GetVSlotId());
+}
+
+namespace std {
+
+template <>
+struct equal_to<NKikimrBlobStorage::TVSlotId> {
+ bool operator ()(const NKikimrBlobStorage::TVSlotId& a, const NKikimrBlobStorage::TVSlotId& b) const {
+ return make_vslot_tuple(a) == make_vslot_tuple(b);
+ }
+};
+
+template <>
+struct hash<NKikimrBlobStorage::TVSlotId> {
+ size_t operator ()(const NKikimrBlobStorage::TVSlotId& a) const {
+ auto tp = make_vslot_tuple(a);
+ return hash<decltype(tp)>()(tp);
+ }
+};
+
+}
+
+#define BLOG_CRIT(stream) LOG_CRIT_S(*TlsActivationContext, NKikimrServices::HEALTH, stream)
+
+namespace NKikimr {
+namespace NHealthCheck {
+
+using namespace NActors;
+using namespace Ydb;
+
+struct TEvPrivate {
+ enum EEv {
+ EvRetryNodeWhiteboard = EventSpaceBegin(NActors::TEvents::ES_PRIVATE),
+ EvEnd
+ };
+
+ static_assert(EvEnd < EventSpaceEnd(NActors::TEvents::ES_PRIVATE), "expect EvEnd < EventSpaceEnd(TEvents::ES_PRIVATE)");
+
+ struct TEvRetryNodeWhiteboard : NActors::TEventLocal<TEvRetryNodeWhiteboard, EvRetryNodeWhiteboard> {
+ TNodeId NodeId;
+ int EventId;
+
+ TEvRetryNodeWhiteboard(TNodeId nodeId, int eventId)
+ : NodeId(nodeId)
+ , EventId(eventId)
+ {}
+ };
+};
+
+class TSelfCheckRequest : public TActorBootstrapped<TSelfCheckRequest> {
+public:
+ static constexpr NKikimrServices::TActivity::EType ActorActivityType() { return NKikimrServices::TActivity::MONITORING_REQUEST; }
+
+ TActorId Sender;
+ THolder<TEvSelfCheckRequest> Request;
+ ui64 Cookie;
+
+ TSelfCheckRequest(const TActorId& sender, THolder<TEvSelfCheckRequest> request, ui64 cookie)
+ : Sender(sender)
+ , Request(std::move(request))
+ , Cookie(cookie)
+ {}
+
+ using TGroupId = ui32;
+
+ struct TTenantInfo {
+ TString Name;
+ Ydb::Cms::GetDatabaseStatusResult::State State;
+ };
+
+ struct TNodeTabletState {
+ struct TTabletStateSettings {
+ TInstant AliveBarrier;
+ ui32 MaxRestartsPerPeriod = 30; // per hour
+ ui32 MaxTabletIdsStored = 10;
+ bool ReportGoodTabletsIds = false;
+ };
+
+ enum class ETabletState {
+ Good,
+ Stopped,
+ RestartsTooOften,
+ Dead,
+ };
+
+ struct TNodeTabletStateCount {
+ NKikimrTabletBase::TTabletTypes::EType Type;
+ ETabletState State;
+ int Count = 1;
+ TStackVec<TString> Identifiers;
+
+ TNodeTabletStateCount(const NKikimrHive::TTabletInfo& info, const TTabletStateSettings& settings) {
+ Type = info.tablettype();
+ if (info.volatilestate() == NKikimrHive::TABLET_VOLATILE_STATE_STOPPED) {
+ State = ETabletState::Stopped;
+ } else if (info.volatilestate() != NKikimrHive::TABLET_VOLATILE_STATE_RUNNING
+ && TInstant::MilliSeconds(info.lastalivetimestamp()) < settings.AliveBarrier
+ && info.tabletbootmode() == NKikimrHive::TABLET_BOOT_MODE_DEFAULT) {
+ State = ETabletState::Dead;
+ } else if (info.restartsperperiod() >= settings.MaxRestartsPerPeriod) {
+ State = ETabletState::RestartsTooOften;
+ } else {
+ State = ETabletState::Good;
+ }
+ }
+
+ bool operator ==(const TNodeTabletStateCount& o) const {
+ return State == o.State && Type == o.Type;
+ }
+ };
+
+ TStackVec<TNodeTabletStateCount> Count;
+
+ void AddTablet(const NKikimrHive::TTabletInfo& info, const TTabletStateSettings& settings) {
+ TNodeTabletStateCount tabletState(info, settings);
+ auto itCount = Find(Count, tabletState);
+ if (itCount != Count.end()) {
+ itCount->Count++;
+ } else {
+ Count.emplace_back(tabletState);
+ itCount = std::prev(Count.end());
+ }
+ if (itCount->State != ETabletState::Good || settings.ReportGoodTabletsIds) {
+ if (itCount->Identifiers.size() < settings.MaxTabletIdsStored) {
+ TStringBuilder id;
+ id << info.tabletid();
if (info.followerid()) {
id << '.' << info.followerid();
- }
- itCount->Identifiers.emplace_back(id);
- }
- }
- }
- };
-
- struct TStoragePoolState {
- TString Kind;
- THashSet<TGroupId> Groups;
- THashSet<TGroupId> AuthenticGroups;
- };
-
- struct TDatabaseState {
- TTabletId HiveId = {};
- TPathId ResourcePathId = {};
- TVector<TNodeId> ComputeNodeIds;
- TVector<TString> StoragePoolNames;
+ }
+ itCount->Identifiers.emplace_back(id);
+ }
+ }
+ }
+ };
+
+ struct TStoragePoolState {
+ TString Kind;
+ THashSet<TGroupId> Groups;
+ THashSet<TGroupId> AuthenticGroups;
+ };
+
+ struct TDatabaseState {
+ TTabletId HiveId = {};
+ TPathId ResourcePathId = {};
+ TVector<TNodeId> ComputeNodeIds;
+ TVector<TString> StoragePoolNames;
THashMap<std::pair<TTabletId, TFollowerId>, const NKikimrHive::TTabletInfo*> MergedTabletState;
- THashMap<TNodeId, TNodeTabletState> MergedNodeTabletState;
- };
-
- struct TSelfCheckResult {
- struct TIssueRecord {
- Ydb::Monitoring::IssueLog IssueLog;
- TString Tag;
- };
-
- Ydb::Monitoring::StatusFlag::Status OverallStatus = Ydb::Monitoring::StatusFlag::GREY;
- TList<TIssueRecord> IssueLog;
- Ydb::Monitoring::Location Location;
- int Level = 1;
- TString Type;
-
- static bool IsErrorStatus(Ydb::Monitoring::StatusFlag::Status status) {
- return status != Ydb::Monitoring::StatusFlag::GREEN;
- }
-
- static TString crc16(const TString& data) {
- return Sprintf("%04x", (ui32)::crc16(data.data(), data.size()));
- }
-
- static TString GetIssueId(const Ydb::Monitoring::IssueLog& issueLog) {
- TStringStream id;
- id << Ydb::Monitoring::StatusFlag_Status_Name(issueLog.status());
- id << '-' << crc16(issueLog.message());
- const Ydb::Monitoring::Location& location(issueLog.location());
- if (location.storage().node().id()) {
- id << '-' << location.storage().node().id();
- } else {
- if (location.storage().node().host()) {
- id << '-' << location.storage().node().host();
- }
- if (location.storage().node().port()) {
- id << '-' << location.storage().node().port();
- }
- }
- if (location.storage().pool().group().vdisk().id()) {
- id << '-' << location.storage().pool().group().vdisk().id();
- } else {
- if (location.storage().pool().group().id()) {
- id << '-' << location.storage().pool().group().id();
- } else {
- if (location.storage().pool().name()) {
- id << '-' << crc16(location.storage().pool().name());
- }
- }
- }
- if (location.storage().pool().group().vdisk().pdisk().id()) {
- id << '-' << location.storage().pool().group().vdisk().pdisk().id();
- }
- if (location.compute().node().id()) {
- id << '-' << location.compute().node().id();
- } else {
- if (location.compute().node().host()) {
- id << '-' << location.compute().node().host();
- }
- if (location.compute().node().port()) {
- id << '-' << location.compute().node().port();
- }
- }
- if (location.compute().pool().name()) {
- id << '-' << location.compute().pool().name();
- }
- if (location.compute().tablet().type()) {
- id << '-' << location.compute().tablet().type();
- }
- return id.Str();
- }
-
- void ReportStatus(Ydb::Monitoring::StatusFlag::Status status,
- const TString& message = {},
- const TString& setTag = {},
- std::initializer_list<TString> includeTags = {}) {
- OverallStatus = MaxStatus(OverallStatus, status);
- if (IsErrorStatus(status)) {
- TVector<TString> reason;
- if (includeTags.size() != 0) {
- for (const TIssueRecord& record : IssueLog) {
- for (const TString& tag : includeTags) {
- if (record.Tag == tag) {
- reason.push_back(record.IssueLog.id());
- break;
- }
- }
- }
- }
- TIssueRecord& issueRecord(*IssueLog.emplace(IssueLog.begin()));
- Ydb::Monitoring::IssueLog& issueLog(issueRecord.IssueLog);
- issueLog.set_status(status);
- issueLog.set_message(message);
- if (Location.ByteSizeLong() > 0) {
- issueLog.mutable_location()->CopyFrom(Location);
- }
- issueLog.set_id(GetIssueId(issueLog));
- if (Type) {
- issueLog.set_type(Type);
- }
- issueLog.set_level(Level);
- if (reason) {
- for (const TString& r : reason) {
- issueLog.add_reason(r);
- }
- }
- if (setTag) {
- issueRecord.Tag = setTag;
- }
- }
- }
-
- Ydb::Monitoring::StatusFlag::Status GetOverallStatus() const {
- return OverallStatus;
- }
-
- void SetOverallStatus(Ydb::Monitoring::StatusFlag::Status status) {
- OverallStatus = status;
- }
-
- void InheritFrom(TSelfCheckResult& lower) {
- if (lower.GetOverallStatus() >= OverallStatus) {
- OverallStatus = lower.GetOverallStatus();
- }
- IssueLog.splice(IssueLog.end(), std::move(lower.IssueLog));
- }
- };
-
- struct TSelfCheckContext : TSelfCheckResult {
- TSelfCheckResult* Upper;
-
- TSelfCheckContext(TSelfCheckResult* upper)
- : Upper(upper)
- {
- Location.CopyFrom(upper->Location);
- Level = upper->Level + 1;
- }
-
- TSelfCheckContext(TSelfCheckResult* upper, const TString& type)
- : TSelfCheckContext(upper)
- {
- Type = type;
- }
-
- TSelfCheckContext(const TSelfCheckContext&) = delete;
-
- ~TSelfCheckContext() {
- Upper->InheritFrom(*this);
- }
- };
-
- TString FilterDatabase;
- THashMap<TSubDomainKey, TString> FilterDomainKey;
- TVector<TActorId> PipeClients;
- int Requests = 0;
- TString DomainPath;
- TTabletId ConsoleId;
- TTabletId BsControllerId;
- TTabletId RootSchemeShardId;
- TTabletId RootHiveId;
- THashMap<TString, TTenantInfo> TenantByPath;
+ THashMap<TNodeId, TNodeTabletState> MergedNodeTabletState;
+ };
+
+ struct TSelfCheckResult {
+ struct TIssueRecord {
+ Ydb::Monitoring::IssueLog IssueLog;
+ TString Tag;
+ };
+
+ Ydb::Monitoring::StatusFlag::Status OverallStatus = Ydb::Monitoring::StatusFlag::GREY;
+ TList<TIssueRecord> IssueLog;
+ Ydb::Monitoring::Location Location;
+ int Level = 1;
+ TString Type;
+
+ static bool IsErrorStatus(Ydb::Monitoring::StatusFlag::Status status) {
+ return status != Ydb::Monitoring::StatusFlag::GREEN;
+ }
+
+ static TString crc16(const TString& data) {
+ return Sprintf("%04x", (ui32)::crc16(data.data(), data.size()));
+ }
+
+ static TString GetIssueId(const Ydb::Monitoring::IssueLog& issueLog) {
+ TStringStream id;
+ id << Ydb::Monitoring::StatusFlag_Status_Name(issueLog.status());
+ id << '-' << crc16(issueLog.message());
+ const Ydb::Monitoring::Location& location(issueLog.location());
+ if (location.storage().node().id()) {
+ id << '-' << location.storage().node().id();
+ } else {
+ if (location.storage().node().host()) {
+ id << '-' << location.storage().node().host();
+ }
+ if (location.storage().node().port()) {
+ id << '-' << location.storage().node().port();
+ }
+ }
+ if (location.storage().pool().group().vdisk().id()) {
+ id << '-' << location.storage().pool().group().vdisk().id();
+ } else {
+ if (location.storage().pool().group().id()) {
+ id << '-' << location.storage().pool().group().id();
+ } else {
+ if (location.storage().pool().name()) {
+ id << '-' << crc16(location.storage().pool().name());
+ }
+ }
+ }
+ if (location.storage().pool().group().vdisk().pdisk().id()) {
+ id << '-' << location.storage().pool().group().vdisk().pdisk().id();
+ }
+ if (location.compute().node().id()) {
+ id << '-' << location.compute().node().id();
+ } else {
+ if (location.compute().node().host()) {
+ id << '-' << location.compute().node().host();
+ }
+ if (location.compute().node().port()) {
+ id << '-' << location.compute().node().port();
+ }
+ }
+ if (location.compute().pool().name()) {
+ id << '-' << location.compute().pool().name();
+ }
+ if (location.compute().tablet().type()) {
+ id << '-' << location.compute().tablet().type();
+ }
+ return id.Str();
+ }
+
+ void ReportStatus(Ydb::Monitoring::StatusFlag::Status status,
+ const TString& message = {},
+ const TString& setTag = {},
+ std::initializer_list<TString> includeTags = {}) {
+ OverallStatus = MaxStatus(OverallStatus, status);
+ if (IsErrorStatus(status)) {
+ TVector<TString> reason;
+ if (includeTags.size() != 0) {
+ for (const TIssueRecord& record : IssueLog) {
+ for (const TString& tag : includeTags) {
+ if (record.Tag == tag) {
+ reason.push_back(record.IssueLog.id());
+ break;
+ }
+ }
+ }
+ }
+ TIssueRecord& issueRecord(*IssueLog.emplace(IssueLog.begin()));
+ Ydb::Monitoring::IssueLog& issueLog(issueRecord.IssueLog);
+ issueLog.set_status(status);
+ issueLog.set_message(message);
+ if (Location.ByteSizeLong() > 0) {
+ issueLog.mutable_location()->CopyFrom(Location);
+ }
+ issueLog.set_id(GetIssueId(issueLog));
+ if (Type) {
+ issueLog.set_type(Type);
+ }
+ issueLog.set_level(Level);
+ if (reason) {
+ for (const TString& r : reason) {
+ issueLog.add_reason(r);
+ }
+ }
+ if (setTag) {
+ issueRecord.Tag = setTag;
+ }
+ }
+ }
+
+ Ydb::Monitoring::StatusFlag::Status GetOverallStatus() const {
+ return OverallStatus;
+ }
+
+ void SetOverallStatus(Ydb::Monitoring::StatusFlag::Status status) {
+ OverallStatus = status;
+ }
+
+ void InheritFrom(TSelfCheckResult& lower) {
+ if (lower.GetOverallStatus() >= OverallStatus) {
+ OverallStatus = lower.GetOverallStatus();
+ }
+ IssueLog.splice(IssueLog.end(), std::move(lower.IssueLog));
+ }
+ };
+
+ struct TSelfCheckContext : TSelfCheckResult {
+ TSelfCheckResult* Upper;
+
+ TSelfCheckContext(TSelfCheckResult* upper)
+ : Upper(upper)
+ {
+ Location.CopyFrom(upper->Location);
+ Level = upper->Level + 1;
+ }
+
+ TSelfCheckContext(TSelfCheckResult* upper, const TString& type)
+ : TSelfCheckContext(upper)
+ {
+ Type = type;
+ }
+
+ TSelfCheckContext(const TSelfCheckContext&) = delete;
+
+ ~TSelfCheckContext() {
+ Upper->InheritFrom(*this);
+ }
+ };
+
+ TString FilterDatabase;
+ THashMap<TSubDomainKey, TString> FilterDomainKey;
+ TVector<TActorId> PipeClients;
+ int Requests = 0;
+ TString DomainPath;
+ TTabletId ConsoleId;
+ TTabletId BsControllerId;
+ TTabletId RootSchemeShardId;
+ TTabletId RootHiveId;
+ THashMap<TString, TTenantInfo> TenantByPath;
THashMap<TString, THolder<NSchemeShard::TEvSchemeShard::TEvDescribeSchemeResult>> DescribeByPath;
- THashMap<TString, Ydb::Cms::GetDatabaseStatusResult> DatabaseStatusByPath;
- THashMap<TString, THolder<NTenantSlotBroker::TEvTenantSlotBroker::TEvTenantState>> TenantStateByPath;
- THashMap<TString, THolder<NSchemeCache::TSchemeCacheNavigate>> NavigateResult;
- THashMap<TTabletId, THolder<TEvHive::TEvResponseHiveDomainStats>> HiveDomainStats;
- THashMap<TTabletId, THolder<TEvHive::TEvResponseHiveNodeStats>> HiveNodeStats;
- THashMap<TTabletId, THolder<TEvHive::TEvResponseHiveInfo>> HiveInfo;
- THolder<TEvInterconnect::TEvNodesInfo> NodesInfo;
- THashMap<TNodeId, const TEvInterconnect::TNodeInfo*> MergedNodeInfo;
- THolder<TEvBlobStorage::TEvControllerConfigResponse> BaseConfig;
-
- THashSet<TNodeId> NodeIds;
- THashSet<TNodeId> StorageNodeIds;
- THashSet<TNodeId> ComputeNodeIds;
- std::unordered_map<std::pair<TNodeId, int>, ui32> NodeRetries;
- ui32 MaxRetries = 3;
- TDuration RetryDelay = TDuration::MilliSeconds(250);
-
- THashMap<TString, TDatabaseState> DatabaseState;
- THashMap<TPathId, TString> SharedDatabases;
-
- THashMap<TNodeId, THolder<NNodeWhiteboard::TEvWhiteboard::TEvSystemStateResponse>> NodeSystemState;
- THashMap<TNodeId, const NKikimrWhiteboard::TSystemStateInfo*> MergedNodeSystemState;
-
- THashMap<TNodeId, THolder<NNodeWhiteboard::TEvWhiteboard::TEvVDiskStateResponse>> NodeVDiskState;
- TList<NKikimrWhiteboard::TVDiskStateInfo> VDisksAppended;
- std::unordered_map<TString, const NKikimrWhiteboard::TVDiskStateInfo*> MergedVDiskState;
- std::unordered_set<TString> ValidVDisks;
-
- THashMap<TNodeId, THolder<NNodeWhiteboard::TEvWhiteboard::TEvPDiskStateResponse>> NodePDiskState;
- TList<NKikimrWhiteboard::TPDiskStateInfo> PDisksAppended;
- std::unordered_map<TString, const NKikimrWhiteboard::TPDiskStateInfo*> MergedPDiskState;
- std::unordered_set<TString> ValidPDisks;
-
- THashMap<TNodeId, THolder<NNodeWhiteboard::TEvWhiteboard::TEvBSGroupStateResponse>> NodeBSGroupState;
- TList<NKikimrWhiteboard::TBSGroupStateInfo> BSGroupAppended;
- std::unordered_map<TGroupId, const NKikimrWhiteboard::TBSGroupStateInfo*> MergedBSGroupState;
- std::unordered_set<TGroupId> ValidGroups;
-
- THashMap<TString, TStoragePoolState> StoragePoolState;
- THashSet<TString> StoragePoolSeen;
-
- THashSet<TNodeId> UnavailableStorageNodes;
- THashSet<TNodeId> UnavailableComputeNodes;
-
- struct TTabletRequestsState {
- struct TTabletState {
- TTabletTypes::EType Type = TTabletTypes::Unknown;
- TString Database;
- bool IsUnresponsive = false;
- TDuration MaxResponseTime;
- TActorId TabletPipe = {};
- };
-
- struct TRequestState {
- TTabletId TabletId;
- TString Key;
- TMonotonic StartTime;
- };
-
- std::unordered_map<TTabletId, TTabletState> TabletStates;
- std::unordered_map<ui64, TRequestState> RequestsInFlight;
- ui64 RequestId = 0;
-
- ui64 MakeRequest(TTabletId tabletId, const TString& key) {
- ++RequestId;
- RequestsInFlight.emplace(RequestId, TRequestState{tabletId, key, TMonotonic::Now()});
- return RequestId;
- }
-
- TTabletId CompleteRequest(ui64 requestId) {
- TTabletId tabletId = {};
- TMonotonic finishTime = TMonotonic::Now();
- auto itRequest = RequestsInFlight.find(requestId);
- if (itRequest != RequestsInFlight.end()) {
- TDuration responseTime = finishTime - itRequest->second.StartTime;
- tabletId = itRequest->second.TabletId;
- TTabletState& tabletState = TabletStates[tabletId];
- if (responseTime > tabletState.MaxResponseTime) {
- tabletState.MaxResponseTime = responseTime;
- }
- RequestsInFlight.erase(itRequest);
- }
- return tabletId;
- }
- };
-
- TTabletRequestsState TabletRequests;
-
- TDuration Timeout = TDuration::MilliSeconds(10000);
-
- static constexpr TStringBuf STATIC_STORAGE_POOL_NAME = "static";
-
- void Bootstrap() {
- FilterDatabase = Request->Database;
- if (Request->Request.operation_params().has_operation_timeout()) {
- Timeout = GetDuration(Request->Request.operation_params().operation_timeout());
- }
- TIntrusivePtr<TDomainsInfo> domains = AppData()->DomainsInfo;
- TIntrusivePtr<TDomainsInfo::TDomain> domain = domains->Domains.begin()->second;
- DomainPath = "/" + domain->Name;
- RootSchemeShardId = domain->SchemeRoot;
- auto group = domains->GetDefaultStateStorageGroup(domain->DomainUid);
- ConsoleId = MakeConsoleID(group);
- RootHiveId = domains->GetHive(domain->DefaultHiveUid);
- BsControllerId = MakeBSControllerID(group);
-
- if (ConsoleId) {
- TabletRequests.TabletStates[ConsoleId].Database = DomainPath;
- TabletRequests.TabletStates[ConsoleId].Type = TTabletTypes::Console;
- if (FilterDatabase) {
- if (FilterDatabase != DomainPath) {
- RequestTenantStatus(FilterDatabase);
- } else {
- TTenantInfo& tenant = TenantByPath[DomainPath];
- tenant.Name = DomainPath;
- RequestSchemeCacheNavigate(DomainPath);
- }
- } else {
- TTenantInfo& tenant = TenantByPath[DomainPath];
- tenant.Name = DomainPath;
- RequestSchemeCacheNavigate(DomainPath);
- RequestListTenants();
- }
- }
-
- if (RootHiveId) {
- TabletRequests.TabletStates[RootHiveId].Database = DomainPath;
- TabletRequests.TabletStates[RootHiveId].Type = TTabletTypes::Hive;
- //RequestHiveDomainStats(RootHiveId);
- RequestHiveNodeStats(RootHiveId);
- RequestHiveInfo(RootHiveId);
- }
-
- if (RootSchemeShardId && (!FilterDatabase || FilterDatabase == DomainPath)) {
- TabletRequests.TabletStates[RootSchemeShardId].Database = DomainPath;
- TabletRequests.TabletStates[RootSchemeShardId].Type = TTabletTypes::SchemeShard;
- RequestDescribe(RootSchemeShardId, DomainPath);
- }
-
- if (BsControllerId) {
- TabletRequests.TabletStates[BsControllerId].Database = DomainPath;
- TabletRequests.TabletStates[BsControllerId].Type = TTabletTypes::BSController;
- RequestConfig();
- }
-
- const NKikimrBlobStorage::TNodeWardenServiceSet& staticConfig = *AppData()->StaticBlobStorageConfig.Get();
- for (const NKikimrBlobStorage::TNodeWardenServiceSet_TPDisk& pDisk : staticConfig.pdisks()) {
- auto pDiskId = GetPDiskId(pDisk);
- ValidPDisks.emplace(pDiskId);
- auto itPDisk = MergedPDiskState.find(pDiskId);
- if (itPDisk == MergedPDiskState.end()) {
- PDisksAppended.emplace_back();
- NKikimrWhiteboard::TPDiskStateInfo& pbPDisk = PDisksAppended.back();
- itPDisk = MergedPDiskState.emplace(pDiskId, &pbPDisk).first;
- pbPDisk.SetNodeId(pDisk.GetNodeID());
- pbPDisk.SetPDiskId(pDisk.GetPDiskID());
- pbPDisk.SetPath(pDisk.GetPath());
- pbPDisk.SetGuid(pDisk.GetPDiskGuid());
- pbPDisk.SetCategory(static_cast<ui64>(pDisk.GetPDiskCategory()));
- RequestStorageNode(pDisk.GetNodeID());
- }
- }
- for (const NKikimrBlobStorage::TNodeWardenServiceSet_TVDisk& vDisk : staticConfig.vdisks()) {
- auto vDiskId = GetVDiskId(vDisk);
- ValidVDisks.emplace(vDiskId);
- auto itVDisk = MergedVDiskState.find(vDiskId);
- if (itVDisk == MergedVDiskState.end()) {
- VDisksAppended.emplace_back();
- NKikimrWhiteboard::TVDiskStateInfo& pbVDisk = VDisksAppended.back();
- itVDisk = MergedVDiskState.emplace(vDiskId, &pbVDisk).first;
- pbVDisk.MutableVDiskId()->CopyFrom(vDisk.vdiskid());
- pbVDisk.SetNodeId(vDisk.GetVDiskLocation().GetNodeID());
- pbVDisk.SetPDiskId(vDisk.GetVDiskLocation().GetPDiskID());
- }
- }
- for (const NKikimrBlobStorage::TGroupInfo& group : staticConfig.groups()) {
- ValidGroups.emplace(group.GetGroupID());
- TString storagePoolName = group.GetStoragePoolName();
- if (!storagePoolName) {
- storagePoolName = STATIC_STORAGE_POOL_NAME;
- }
- StoragePoolState[storagePoolName].Groups.emplace(group.groupid());
- if (!FilterDatabase || FilterDatabase == DomainPath) {
- DatabaseState[DomainPath].StoragePoolNames.emplace_back(storagePoolName);
- }
- }
- Send(GetNameserviceActorId(), new TEvInterconnect::TEvListNodes());
- ++Requests;
-
- Become(&TThis::StateWait, Timeout, new TEvents::TEvWakeup());
- }
-
- STATEFN(StateWait) {
- switch (ev->GetTypeRewrite()) {
- hFunc(TEvents::TEvUndelivered, Handle);
- hFunc(TEvInterconnect::TEvNodesInfo, Handle);
- hFunc(NConsole::TEvConsole::TEvListTenantsResponse, Handle);
- hFunc(NConsole::TEvConsole::TEvGetTenantStatusResponse, Handle);
- hFunc(TEvHive::TEvResponseHiveDomainStats, Handle);
- hFunc(TEvHive::TEvResponseHiveNodeStats, Handle);
- hFunc(TEvHive::TEvResponseHiveInfo, Handle);
+ THashMap<TString, Ydb::Cms::GetDatabaseStatusResult> DatabaseStatusByPath;
+ THashMap<TString, THolder<NTenantSlotBroker::TEvTenantSlotBroker::TEvTenantState>> TenantStateByPath;
+ THashMap<TString, THolder<NSchemeCache::TSchemeCacheNavigate>> NavigateResult;
+ THashMap<TTabletId, THolder<TEvHive::TEvResponseHiveDomainStats>> HiveDomainStats;
+ THashMap<TTabletId, THolder<TEvHive::TEvResponseHiveNodeStats>> HiveNodeStats;
+ THashMap<TTabletId, THolder<TEvHive::TEvResponseHiveInfo>> HiveInfo;
+ THolder<TEvInterconnect::TEvNodesInfo> NodesInfo;
+ THashMap<TNodeId, const TEvInterconnect::TNodeInfo*> MergedNodeInfo;
+ THolder<TEvBlobStorage::TEvControllerConfigResponse> BaseConfig;
+
+ THashSet<TNodeId> NodeIds;
+ THashSet<TNodeId> StorageNodeIds;
+ THashSet<TNodeId> ComputeNodeIds;
+ std::unordered_map<std::pair<TNodeId, int>, ui32> NodeRetries;
+ ui32 MaxRetries = 3;
+ TDuration RetryDelay = TDuration::MilliSeconds(250);
+
+ THashMap<TString, TDatabaseState> DatabaseState;
+ THashMap<TPathId, TString> SharedDatabases;
+
+ THashMap<TNodeId, THolder<NNodeWhiteboard::TEvWhiteboard::TEvSystemStateResponse>> NodeSystemState;
+ THashMap<TNodeId, const NKikimrWhiteboard::TSystemStateInfo*> MergedNodeSystemState;
+
+ THashMap<TNodeId, THolder<NNodeWhiteboard::TEvWhiteboard::TEvVDiskStateResponse>> NodeVDiskState;
+ TList<NKikimrWhiteboard::TVDiskStateInfo> VDisksAppended;
+ std::unordered_map<TString, const NKikimrWhiteboard::TVDiskStateInfo*> MergedVDiskState;
+ std::unordered_set<TString> ValidVDisks;
+
+ THashMap<TNodeId, THolder<NNodeWhiteboard::TEvWhiteboard::TEvPDiskStateResponse>> NodePDiskState;
+ TList<NKikimrWhiteboard::TPDiskStateInfo> PDisksAppended;
+ std::unordered_map<TString, const NKikimrWhiteboard::TPDiskStateInfo*> MergedPDiskState;
+ std::unordered_set<TString> ValidPDisks;
+
+ THashMap<TNodeId, THolder<NNodeWhiteboard::TEvWhiteboard::TEvBSGroupStateResponse>> NodeBSGroupState;
+ TList<NKikimrWhiteboard::TBSGroupStateInfo> BSGroupAppended;
+ std::unordered_map<TGroupId, const NKikimrWhiteboard::TBSGroupStateInfo*> MergedBSGroupState;
+ std::unordered_set<TGroupId> ValidGroups;
+
+ THashMap<TString, TStoragePoolState> StoragePoolState;
+ THashSet<TString> StoragePoolSeen;
+
+ THashSet<TNodeId> UnavailableStorageNodes;
+ THashSet<TNodeId> UnavailableComputeNodes;
+
+ struct TTabletRequestsState {
+ struct TTabletState {
+ TTabletTypes::EType Type = TTabletTypes::Unknown;
+ TString Database;
+ bool IsUnresponsive = false;
+ TDuration MaxResponseTime;
+ TActorId TabletPipe = {};
+ };
+
+ struct TRequestState {
+ TTabletId TabletId;
+ TString Key;
+ TMonotonic StartTime;
+ };
+
+ std::unordered_map<TTabletId, TTabletState> TabletStates;
+ std::unordered_map<ui64, TRequestState> RequestsInFlight;
+ ui64 RequestId = 0;
+
+ ui64 MakeRequest(TTabletId tabletId, const TString& key) {
+ ++RequestId;
+ RequestsInFlight.emplace(RequestId, TRequestState{tabletId, key, TMonotonic::Now()});
+ return RequestId;
+ }
+
+ TTabletId CompleteRequest(ui64 requestId) {
+ TTabletId tabletId = {};
+ TMonotonic finishTime = TMonotonic::Now();
+ auto itRequest = RequestsInFlight.find(requestId);
+ if (itRequest != RequestsInFlight.end()) {
+ TDuration responseTime = finishTime - itRequest->second.StartTime;
+ tabletId = itRequest->second.TabletId;
+ TTabletState& tabletState = TabletStates[tabletId];
+ if (responseTime > tabletState.MaxResponseTime) {
+ tabletState.MaxResponseTime = responseTime;
+ }
+ RequestsInFlight.erase(itRequest);
+ }
+ return tabletId;
+ }
+ };
+
+ TTabletRequestsState TabletRequests;
+
+ TDuration Timeout = TDuration::MilliSeconds(10000);
+
+ static constexpr TStringBuf STATIC_STORAGE_POOL_NAME = "static";
+
+ void Bootstrap() {
+ FilterDatabase = Request->Database;
+ if (Request->Request.operation_params().has_operation_timeout()) {
+ Timeout = GetDuration(Request->Request.operation_params().operation_timeout());
+ }
+ TIntrusivePtr<TDomainsInfo> domains = AppData()->DomainsInfo;
+ TIntrusivePtr<TDomainsInfo::TDomain> domain = domains->Domains.begin()->second;
+ DomainPath = "/" + domain->Name;
+ RootSchemeShardId = domain->SchemeRoot;
+ auto group = domains->GetDefaultStateStorageGroup(domain->DomainUid);
+ ConsoleId = MakeConsoleID(group);
+ RootHiveId = domains->GetHive(domain->DefaultHiveUid);
+ BsControllerId = MakeBSControllerID(group);
+
+ if (ConsoleId) {
+ TabletRequests.TabletStates[ConsoleId].Database = DomainPath;
+ TabletRequests.TabletStates[ConsoleId].Type = TTabletTypes::Console;
+ if (FilterDatabase) {
+ if (FilterDatabase != DomainPath) {
+ RequestTenantStatus(FilterDatabase);
+ } else {
+ TTenantInfo& tenant = TenantByPath[DomainPath];
+ tenant.Name = DomainPath;
+ RequestSchemeCacheNavigate(DomainPath);
+ }
+ } else {
+ TTenantInfo& tenant = TenantByPath[DomainPath];
+ tenant.Name = DomainPath;
+ RequestSchemeCacheNavigate(DomainPath);
+ RequestListTenants();
+ }
+ }
+
+ if (RootHiveId) {
+ TabletRequests.TabletStates[RootHiveId].Database = DomainPath;
+ TabletRequests.TabletStates[RootHiveId].Type = TTabletTypes::Hive;
+ //RequestHiveDomainStats(RootHiveId);
+ RequestHiveNodeStats(RootHiveId);
+ RequestHiveInfo(RootHiveId);
+ }
+
+ if (RootSchemeShardId && (!FilterDatabase || FilterDatabase == DomainPath)) {
+ TabletRequests.TabletStates[RootSchemeShardId].Database = DomainPath;
+ TabletRequests.TabletStates[RootSchemeShardId].Type = TTabletTypes::SchemeShard;
+ RequestDescribe(RootSchemeShardId, DomainPath);
+ }
+
+ if (BsControllerId) {
+ TabletRequests.TabletStates[BsControllerId].Database = DomainPath;
+ TabletRequests.TabletStates[BsControllerId].Type = TTabletTypes::BSController;
+ RequestConfig();
+ }
+
+ const NKikimrBlobStorage::TNodeWardenServiceSet& staticConfig = *AppData()->StaticBlobStorageConfig.Get();
+ for (const NKikimrBlobStorage::TNodeWardenServiceSet_TPDisk& pDisk : staticConfig.pdisks()) {
+ auto pDiskId = GetPDiskId(pDisk);
+ ValidPDisks.emplace(pDiskId);
+ auto itPDisk = MergedPDiskState.find(pDiskId);
+ if (itPDisk == MergedPDiskState.end()) {
+ PDisksAppended.emplace_back();
+ NKikimrWhiteboard::TPDiskStateInfo& pbPDisk = PDisksAppended.back();
+ itPDisk = MergedPDiskState.emplace(pDiskId, &pbPDisk).first;
+ pbPDisk.SetNodeId(pDisk.GetNodeID());
+ pbPDisk.SetPDiskId(pDisk.GetPDiskID());
+ pbPDisk.SetPath(pDisk.GetPath());
+ pbPDisk.SetGuid(pDisk.GetPDiskGuid());
+ pbPDisk.SetCategory(static_cast<ui64>(pDisk.GetPDiskCategory()));
+ RequestStorageNode(pDisk.GetNodeID());
+ }
+ }
+ for (const NKikimrBlobStorage::TNodeWardenServiceSet_TVDisk& vDisk : staticConfig.vdisks()) {
+ auto vDiskId = GetVDiskId(vDisk);
+ ValidVDisks.emplace(vDiskId);
+ auto itVDisk = MergedVDiskState.find(vDiskId);
+ if (itVDisk == MergedVDiskState.end()) {
+ VDisksAppended.emplace_back();
+ NKikimrWhiteboard::TVDiskStateInfo& pbVDisk = VDisksAppended.back();
+ itVDisk = MergedVDiskState.emplace(vDiskId, &pbVDisk).first;
+ pbVDisk.MutableVDiskId()->CopyFrom(vDisk.vdiskid());
+ pbVDisk.SetNodeId(vDisk.GetVDiskLocation().GetNodeID());
+ pbVDisk.SetPDiskId(vDisk.GetVDiskLocation().GetPDiskID());
+ }
+ }
+ for (const NKikimrBlobStorage::TGroupInfo& group : staticConfig.groups()) {
+ ValidGroups.emplace(group.GetGroupID());
+ TString storagePoolName = group.GetStoragePoolName();
+ if (!storagePoolName) {
+ storagePoolName = STATIC_STORAGE_POOL_NAME;
+ }
+ StoragePoolState[storagePoolName].Groups.emplace(group.groupid());
+ if (!FilterDatabase || FilterDatabase == DomainPath) {
+ DatabaseState[DomainPath].StoragePoolNames.emplace_back(storagePoolName);
+ }
+ }
+ Send(GetNameserviceActorId(), new TEvInterconnect::TEvListNodes());
+ ++Requests;
+
+ Become(&TThis::StateWait, Timeout, new TEvents::TEvWakeup());
+ }
+
+ STATEFN(StateWait) {
+ switch (ev->GetTypeRewrite()) {
+ hFunc(TEvents::TEvUndelivered, Handle);
+ hFunc(TEvInterconnect::TEvNodesInfo, Handle);
+ hFunc(NConsole::TEvConsole::TEvListTenantsResponse, Handle);
+ hFunc(NConsole::TEvConsole::TEvGetTenantStatusResponse, Handle);
+ hFunc(TEvHive::TEvResponseHiveDomainStats, Handle);
+ hFunc(TEvHive::TEvResponseHiveNodeStats, Handle);
+ hFunc(TEvHive::TEvResponseHiveInfo, Handle);
hFunc(NSchemeShard::TEvSchemeShard::TEvDescribeSchemeResult, Handle);
- hFunc(TEvTxProxySchemeCache::TEvNavigateKeySetResult, Handle)
- hFunc(TEvBlobStorage::TEvControllerSelectGroupsResult, Handle);
- hFunc(TEvBlobStorage::TEvControllerConfigResponse, Handle);
- hFunc(NNodeWhiteboard::TEvWhiteboard::TEvSystemStateResponse, Handle);
- //hFunc(NNodeWhiteboard::TEvWhiteboard::TEvTabletStateResponse, Handle);
- hFunc(NNodeWhiteboard::TEvWhiteboard::TEvVDiskStateResponse, Handle);
- hFunc(NNodeWhiteboard::TEvWhiteboard::TEvPDiskStateResponse, Handle);
- hFunc(NNodeWhiteboard::TEvWhiteboard::TEvBSGroupStateResponse, Handle);
- hFunc(TEvInterconnect::TEvNodeDisconnected, Disconnected);
- hFunc(TEvTabletPipe::TEvClientDestroyed, Handle);
- hFunc(TEvTabletPipe::TEvClientConnected, Handle);
- hFunc(TEvPrivate::TEvRetryNodeWhiteboard, Handle);
- cFunc(TEvents::TSystem::Wakeup, HandleTimeout);
- }
- }
-
- void RequestDone(const char* name) {
- --Requests;
- if (Requests == 0) {
- ReplyAndPassAway();
- }
- if (Requests < 0) {
- BLOG_CRIT("Requests < 0 in RequestDone(" << name << ")");
- }
- }
-
- void RequestTabletPipe(TTabletId tabletId, const TString& key, IEventBase* payload) {
- auto requestId = TabletRequests.MakeRequest(tabletId, key);
- TTabletRequestsState::TTabletState& requestState(TabletRequests.TabletStates[tabletId]);
- if (!requestState.TabletPipe) {
- requestState.TabletPipe = RegisterWithSameMailbox(NTabletPipe::CreateClient(
- SelfId(),
- tabletId,
- NTabletPipe::TClientRetryPolicy::WithRetries()));
- PipeClients.emplace_back(requestState.TabletPipe);
- }
- NTabletPipe::SendData(SelfId(), requestState.TabletPipe, payload, requestId);
- ++Requests;
- }
-
- void RequestDescribe(TTabletId schemeShardId, const TString& path) {
+ hFunc(TEvTxProxySchemeCache::TEvNavigateKeySetResult, Handle)
+ hFunc(TEvBlobStorage::TEvControllerSelectGroupsResult, Handle);
+ hFunc(TEvBlobStorage::TEvControllerConfigResponse, Handle);
+ hFunc(NNodeWhiteboard::TEvWhiteboard::TEvSystemStateResponse, Handle);
+ //hFunc(NNodeWhiteboard::TEvWhiteboard::TEvTabletStateResponse, Handle);
+ hFunc(NNodeWhiteboard::TEvWhiteboard::TEvVDiskStateResponse, Handle);
+ hFunc(NNodeWhiteboard::TEvWhiteboard::TEvPDiskStateResponse, Handle);
+ hFunc(NNodeWhiteboard::TEvWhiteboard::TEvBSGroupStateResponse, Handle);
+ hFunc(TEvInterconnect::TEvNodeDisconnected, Disconnected);
+ hFunc(TEvTabletPipe::TEvClientDestroyed, Handle);
+ hFunc(TEvTabletPipe::TEvClientConnected, Handle);
+ hFunc(TEvPrivate::TEvRetryNodeWhiteboard, Handle);
+ cFunc(TEvents::TSystem::Wakeup, HandleTimeout);
+ }
+ }
+
+ void RequestDone(const char* name) {
+ --Requests;
+ if (Requests == 0) {
+ ReplyAndPassAway();
+ }
+ if (Requests < 0) {
+ BLOG_CRIT("Requests < 0 in RequestDone(" << name << ")");
+ }
+ }
+
+ void RequestTabletPipe(TTabletId tabletId, const TString& key, IEventBase* payload) {
+ auto requestId = TabletRequests.MakeRequest(tabletId, key);
+ TTabletRequestsState::TTabletState& requestState(TabletRequests.TabletStates[tabletId]);
+ if (!requestState.TabletPipe) {
+ requestState.TabletPipe = RegisterWithSameMailbox(NTabletPipe::CreateClient(
+ SelfId(),
+ tabletId,
+ NTabletPipe::TClientRetryPolicy::WithRetries()));
+ PipeClients.emplace_back(requestState.TabletPipe);
+ }
+ NTabletPipe::SendData(SelfId(), requestState.TabletPipe, payload, requestId);
+ ++Requests;
+ }
+
+ void RequestDescribe(TTabletId schemeShardId, const TString& path) {
THolder<NSchemeShard::TEvSchemeShard::TEvDescribeScheme> request = MakeHolder<NSchemeShard::TEvSchemeShard::TEvDescribeScheme>();
NKikimrSchemeOp::TDescribePath& record = request->Record;
- record.SetPath(path);
- record.MutableOptions()->SetReturnPartitioningInfo(false);
- record.MutableOptions()->SetReturnPartitionConfig(false);
- record.MutableOptions()->SetReturnChildren(false);
- RequestTabletPipe(schemeShardId, "TEvDescribeScheme:" + path, request.Release());
- }
-
- void RequestHiveInfo(TTabletId hiveId) {
- THolder<TEvHive::TEvRequestHiveInfo> request = MakeHolder<TEvHive::TEvRequestHiveInfo>();
+ record.SetPath(path);
+ record.MutableOptions()->SetReturnPartitioningInfo(false);
+ record.MutableOptions()->SetReturnPartitionConfig(false);
+ record.MutableOptions()->SetReturnChildren(false);
+ RequestTabletPipe(schemeShardId, "TEvDescribeScheme:" + path, request.Release());
+ }
+
+ void RequestHiveInfo(TTabletId hiveId) {
+ THolder<TEvHive::TEvRequestHiveInfo> request = MakeHolder<TEvHive::TEvRequestHiveInfo>();
request->Record.SetReturnFollowers(true);
- RequestTabletPipe(hiveId, "TEvRequestHiveInfo", request.Release());
- }
-
- void RequestHiveDomainStats(TTabletId hiveId) {
- THolder<TEvHive::TEvRequestHiveDomainStats> request = MakeHolder<TEvHive::TEvRequestHiveDomainStats>();
+ RequestTabletPipe(hiveId, "TEvRequestHiveInfo", request.Release());
+ }
+
+ void RequestHiveDomainStats(TTabletId hiveId) {
+ THolder<TEvHive::TEvRequestHiveDomainStats> request = MakeHolder<TEvHive::TEvRequestHiveDomainStats>();
request->Record.SetReturnFollowers(true);
- request->Record.SetReturnMetrics(true);
- RequestTabletPipe(hiveId, "TEvRequestHiveDomainStats", request.Release());
- }
-
- void RequestHiveNodeStats(TTabletId hiveId) {
- THolder<TEvHive::TEvRequestHiveNodeStats> request = MakeHolder<TEvHive::TEvRequestHiveNodeStats>();
- RequestTabletPipe(hiveId, "TEvRequestHiveNodeStats", request.Release());
- }
-
- void RequestTenantStatus(const TString& path) {
- THolder<NConsole::TEvConsole::TEvGetTenantStatusRequest> request = MakeHolder<NConsole::TEvConsole::TEvGetTenantStatusRequest>();
- request->Record.MutableRequest()->set_path(path);
- RequestTabletPipe(ConsoleId, "TEvGetTenantStatusRequest:" + path, request.Release());
- }
-
- void RequestListTenants() {
- THolder<NConsole::TEvConsole::TEvListTenantsRequest> request = MakeHolder<NConsole::TEvConsole::TEvListTenantsRequest>();
- RequestTabletPipe(ConsoleId, "TEvListTenantsRequest", request.Release());
- }
-
- void RequestSelectGroups(const TString& storagePoolName) {
- THolder<TEvBlobStorage::TEvControllerSelectGroups> request = MakeHolder<TEvBlobStorage::TEvControllerSelectGroups>();
- request->Record.SetReturnAllMatchingGroups(true);
- request->Record.AddGroupParameters()->MutableStoragePoolSpecifier()->SetName(storagePoolName);
- RequestTabletPipe(BsControllerId, "TEvControllerSelectGroups:" + storagePoolName, request.Release());
- }
-
- void RequestConfig() {
- THolder<TEvBlobStorage::TEvControllerConfigRequest> request = MakeHolder<TEvBlobStorage::TEvControllerConfigRequest>();
- request->Record.MutableRequest()->AddCommand()->MutableQueryBaseConfig();
- RequestTabletPipe(BsControllerId, "TEvControllerConfigRequest", request.Release());
- }
-
- void RequestSchemeCacheNavigate(const TString& path) {
- THolder<NSchemeCache::TSchemeCacheNavigate> request = MakeHolder<NSchemeCache::TSchemeCacheNavigate>();
- NSchemeCache::TSchemeCacheNavigate::TEntry entry;
- entry.Path = NKikimr::SplitPath(path);
- entry.Operation = NSchemeCache::TSchemeCacheNavigate::EOp::OpPath;
- request->ResultSet.emplace_back(entry);
- Send(MakeSchemeCacheID(), new TEvTxProxySchemeCache::TEvNavigateKeySet(request.Release()));
- ++Requests;
- }
-
- void RequestSchemeCacheNavigate(const TPathId& pathId) {
- THolder<NSchemeCache::TSchemeCacheNavigate> request = MakeHolder<NSchemeCache::TSchemeCacheNavigate>();
- NSchemeCache::TSchemeCacheNavigate::TEntry entry;
- entry.TableId.PathId = pathId;
- entry.RequestType = NSchemeCache::TSchemeCacheNavigate::TEntry::ERequestType::ByTableId;
- entry.RedirectRequired = false;
- entry.Operation = NSchemeCache::TSchemeCacheNavigate::EOp::OpPath;
- request->ResultSet.emplace_back(entry);
- Send(MakeSchemeCacheID(), new TEvTxProxySchemeCache::TEvNavigateKeySet(request.Release()));
- ++Requests;
- }
-
- template<typename TEvent>
- void RequestNodeWhiteboard(TNodeId nodeId) {
- TActorId whiteboardServiceId = NNodeWhiteboard::MakeNodeWhiteboardServiceId(nodeId);
- auto request = MakeHolder<TEvent>();
- Send(whiteboardServiceId, request.Release(), IEventHandle::FlagTrackDelivery, nodeId);
- }
-
- void RequestGenericNode(TNodeId nodeId) {
- if (NodeIds.emplace(nodeId).second) {
- Send(TlsActivationContext->ActorSystem()->InterconnectProxy(nodeId), new TEvents::TEvSubscribe());
- RequestNodeWhiteboard<NNodeWhiteboard::TEvWhiteboard::TEvSystemStateRequest>(nodeId);
- ++Requests;
- }
- }
-
- void RequestComputeNode(TNodeId nodeId) {
- if (ComputeNodeIds.emplace(nodeId).second) {
- RequestGenericNode(nodeId);
- }
- }
-
- void RequestStorageNode(TNodeId nodeId) {
- if (StorageNodeIds.emplace(nodeId).second) {
- RequestGenericNode(nodeId);
- RequestNodeWhiteboard<NNodeWhiteboard::TEvWhiteboard::TEvVDiskStateRequest>(nodeId);
- ++Requests;
- RequestNodeWhiteboard<NNodeWhiteboard::TEvWhiteboard::TEvPDiskStateRequest>(nodeId);
- ++Requests;
- RequestNodeWhiteboard<NNodeWhiteboard::TEvWhiteboard::TEvBSGroupStateRequest>(nodeId);
- ++Requests;
- }
- }
-
- void Handle(TEvPrivate::TEvRetryNodeWhiteboard::TPtr& ev) {
- switch (ev->Get()->EventId) {
- case NNodeWhiteboard::TEvWhiteboard::EvSystemStateRequest:
- RequestNodeWhiteboard<NNodeWhiteboard::TEvWhiteboard::TEvSystemStateRequest>(ev->Get()->NodeId);
- break;
- case NNodeWhiteboard::TEvWhiteboard::EvVDiskStateRequest:
- RequestNodeWhiteboard<NNodeWhiteboard::TEvWhiteboard::TEvVDiskStateRequest>(ev->Get()->NodeId);
- break;
- case NNodeWhiteboard::TEvWhiteboard::EvPDiskStateRequest:
- RequestNodeWhiteboard<NNodeWhiteboard::TEvWhiteboard::TEvPDiskStateRequest>(ev->Get()->NodeId);
- break;
- case NNodeWhiteboard::TEvWhiteboard::EvBSGroupStateRequest:
- RequestNodeWhiteboard<NNodeWhiteboard::TEvWhiteboard::TEvBSGroupStateRequest>(ev->Get()->NodeId);
- break;
- default:
- RequestDone("unsupported event scheduled");
- break;
- }
- }
-
- template<typename TEvent>
- bool RetryRequestNodeWhiteboard(TNodeId nodeId) {
- if (NodeRetries[{nodeId, TEvent::EventType}]++ < MaxRetries) {
- Schedule(RetryDelay, new TEvPrivate::TEvRetryNodeWhiteboard(nodeId, TEvent::EventType));
- return true;
- }
- return false;
- }
-
- void Handle(TEvents::TEvUndelivered::TPtr& ev) {
- ui32 nodeId = ev.Get()->Cookie;
- if (ev->Get()->SourceType == NNodeWhiteboard::TEvWhiteboard::EvSystemStateRequest) {
- if (NodeIds.count(nodeId) != 0 && NodeSystemState.count(nodeId) == 0) {
- if (!RetryRequestNodeWhiteboard<NNodeWhiteboard::TEvWhiteboard::TEvSystemStateRequest>(nodeId)) {
- NodeSystemState.emplace(nodeId, nullptr);
- RequestDone("undelivered of TEvSystemStateRequest");
- UnavailableComputeNodes.insert(nodeId);
- }
- }
- }
- if (ev->Get()->SourceType == NNodeWhiteboard::TEvWhiteboard::EvVDiskStateRequest) {
- if (StorageNodeIds.count(nodeId) != 0 && NodeVDiskState.count(nodeId) == 0) {
- if (!RetryRequestNodeWhiteboard<NNodeWhiteboard::TEvWhiteboard::TEvVDiskStateRequest>(nodeId)) {
- NodeVDiskState.emplace(nodeId, nullptr);
- RequestDone("undelivered of TEvVDiskStateRequest");
- UnavailableStorageNodes.insert(nodeId);
- }
- }
- }
- if (ev->Get()->SourceType == NNodeWhiteboard::TEvWhiteboard::EvPDiskStateRequest) {
- if (StorageNodeIds.count(nodeId) != 0 && NodePDiskState.count(nodeId) == 0) {
- if (!RetryRequestNodeWhiteboard<NNodeWhiteboard::TEvWhiteboard::TEvPDiskStateRequest>(nodeId)) {
- NodePDiskState.emplace(nodeId, nullptr);
- RequestDone("undelivered of TEvPDiskStateRequest");
- UnavailableStorageNodes.insert(nodeId);
- }
- }
- }
- if (ev->Get()->SourceType == NNodeWhiteboard::TEvWhiteboard::EvBSGroupStateRequest) {
- if (StorageNodeIds.count(nodeId) != 0 && NodeBSGroupState.count(nodeId) == 0) {
- if (!RetryRequestNodeWhiteboard<NNodeWhiteboard::TEvWhiteboard::TEvBSGroupStateRequest>(nodeId)) {
- NodeBSGroupState.emplace(nodeId, nullptr);
- RequestDone("undelivered of TEvBSGroupStateRequest");
- }
- }
- }
- }
-
- void Disconnected(TEvInterconnect::TEvNodeDisconnected::TPtr& ev) {
- ui32 nodeId = ev->Get()->NodeId;
- if (NodeIds.count(nodeId) != 0 && NodeSystemState.count(nodeId) == 0) {
- if (!RetryRequestNodeWhiteboard<NNodeWhiteboard::TEvWhiteboard::TEvSystemStateRequest>(nodeId)) {
- NodeSystemState.emplace(nodeId, nullptr);
- RequestDone("node disconnected with TEvSystemStateRequest");
- UnavailableComputeNodes.insert(nodeId);
- }
- }
- if (StorageNodeIds.count(nodeId) != 0 && NodeVDiskState.count(nodeId) == 0) {
- if (!RetryRequestNodeWhiteboard<NNodeWhiteboard::TEvWhiteboard::TEvVDiskStateRequest>(nodeId)) {
- NodeVDiskState.emplace(nodeId, nullptr);
- RequestDone("node disconnected with TEvVDiskStateRequest");
- UnavailableStorageNodes.insert(nodeId);
- }
- }
- if (StorageNodeIds.count(nodeId) != 0 && NodePDiskState.count(nodeId) == 0) {
- if (!RetryRequestNodeWhiteboard<NNodeWhiteboard::TEvWhiteboard::TEvPDiskStateRequest>(nodeId)) {
- NodePDiskState.emplace(nodeId, nullptr);
- RequestDone("node disconnected with TEvPDiskStateRequest");
- UnavailableStorageNodes.insert(nodeId);
- }
- }
- if (StorageNodeIds.count(nodeId) != 0 && NodeBSGroupState.count(nodeId) == 0) {
- if (!RetryRequestNodeWhiteboard<NNodeWhiteboard::TEvWhiteboard::TEvBSGroupStateRequest>(nodeId)) {
- NodeBSGroupState.emplace(nodeId, nullptr);
- RequestDone("node disconnected with TEvBSGroupStateRequest");
- }
- }
- }
-
- void Handle(TEvTabletPipe::TEvClientDestroyed::TPtr&) {
- }
-
- void Handle(TEvTabletPipe::TEvClientConnected::TPtr& ev) {
- if (ev->Get()->Status != NKikimrProto::OK) {
- TTabletId tabletId = ev->Get()->TabletId;
- for (const auto& [requestId, requestState] : TabletRequests.RequestsInFlight) {
- if (requestState.TabletId == tabletId) {
- RequestDone("unsuccessful TEvClientConnected");
- }
- }
- }
- }
-
- void HandleTimeout() {
- ReplyAndPassAway();
- }
-
- bool IsStaticNode(const TEvInterconnect::TNodeInfo& nodeInfo) const {
- TAppData* appData = AppData();
- if (appData->DynamicNameserviceConfig) {
- return nodeInfo.NodeId <= AppData()->DynamicNameserviceConfig->MaxStaticNodeId;
- } else {
- return true;
- }
- }
-
- void Handle(TEvInterconnect::TEvNodesInfo::TPtr& ev) {
- bool needComputeFromStaticNodes = (!FilterDatabase || FilterDatabase == DomainPath);
- NodesInfo = ev->Release();
- for (const auto& ni : NodesInfo->Nodes) {
- MergedNodeInfo[ni.NodeId] = &ni;
- if (IsStaticNode(ni) && needComputeFromStaticNodes) {
- DatabaseState[DomainPath].ComputeNodeIds.push_back(ni.NodeId);
- RequestComputeNode(ni.NodeId);
- }
- }
- RequestDone("TEvNodesInfo");
- }
-
- void Handle(TEvBlobStorage::TEvControllerConfigResponse::TPtr& ev) {
- TabletRequests.CompleteRequest(ev->Cookie);
- const NKikimrBlobStorage::TEvControllerConfigResponse& pbRecord(ev->Get()->Record);
- if (pbRecord.HasResponse() && pbRecord.GetResponse().StatusSize() > 0) {
- const NKikimrBlobStorage::TConfigResponse::TStatus& pbStatus(pbRecord.GetResponse().GetStatus(0));
- if (pbStatus.HasBaseConfig()) {
- const NKikimrBlobStorage::TBaseConfig& pbConfig(pbStatus.GetBaseConfig());
- for (const NKikimrBlobStorage::TBaseConfig::TPDisk& pDisk : pbConfig.GetPDisk()) {
- RequestStorageNode(pDisk.GetNodeId());
- }
- BaseConfig = ev->Release();
- }
- }
- RequestDone("TEvControllerConfigResponse");
- }
-
- void Handle(TEvBlobStorage::TEvControllerSelectGroupsResult::TPtr& ev) {
- TabletRequests.CompleteRequest(ev->Cookie);
- for (const auto& matchingGroups : ev->Get()->Record.matchinggroups()) {
- for (const auto& group : matchingGroups.groups()) {
- TString storagePoolName = group.storagepoolname();
- StoragePoolState[storagePoolName].Groups.emplace(group.groupid());
- StoragePoolState[storagePoolName].AuthenticGroups.emplace(group.groupid());
- }
- }
- RequestDone("TEvControllerSelectGroupsResult");
- }
-
+ request->Record.SetReturnMetrics(true);
+ RequestTabletPipe(hiveId, "TEvRequestHiveDomainStats", request.Release());
+ }
+
+ void RequestHiveNodeStats(TTabletId hiveId) {
+ THolder<TEvHive::TEvRequestHiveNodeStats> request = MakeHolder<TEvHive::TEvRequestHiveNodeStats>();
+ RequestTabletPipe(hiveId, "TEvRequestHiveNodeStats", request.Release());
+ }
+
+ void RequestTenantStatus(const TString& path) {
+ THolder<NConsole::TEvConsole::TEvGetTenantStatusRequest> request = MakeHolder<NConsole::TEvConsole::TEvGetTenantStatusRequest>();
+ request->Record.MutableRequest()->set_path(path);
+ RequestTabletPipe(ConsoleId, "TEvGetTenantStatusRequest:" + path, request.Release());
+ }
+
+ void RequestListTenants() {
+ THolder<NConsole::TEvConsole::TEvListTenantsRequest> request = MakeHolder<NConsole::TEvConsole::TEvListTenantsRequest>();
+ RequestTabletPipe(ConsoleId, "TEvListTenantsRequest", request.Release());
+ }
+
+ void RequestSelectGroups(const TString& storagePoolName) {
+ THolder<TEvBlobStorage::TEvControllerSelectGroups> request = MakeHolder<TEvBlobStorage::TEvControllerSelectGroups>();
+ request->Record.SetReturnAllMatchingGroups(true);
+ request->Record.AddGroupParameters()->MutableStoragePoolSpecifier()->SetName(storagePoolName);
+ RequestTabletPipe(BsControllerId, "TEvControllerSelectGroups:" + storagePoolName, request.Release());
+ }
+
+ void RequestConfig() {
+ THolder<TEvBlobStorage::TEvControllerConfigRequest> request = MakeHolder<TEvBlobStorage::TEvControllerConfigRequest>();
+ request->Record.MutableRequest()->AddCommand()->MutableQueryBaseConfig();
+ RequestTabletPipe(BsControllerId, "TEvControllerConfigRequest", request.Release());
+ }
+
+ void RequestSchemeCacheNavigate(const TString& path) {
+ THolder<NSchemeCache::TSchemeCacheNavigate> request = MakeHolder<NSchemeCache::TSchemeCacheNavigate>();
+ NSchemeCache::TSchemeCacheNavigate::TEntry entry;
+ entry.Path = NKikimr::SplitPath(path);
+ entry.Operation = NSchemeCache::TSchemeCacheNavigate::EOp::OpPath;
+ request->ResultSet.emplace_back(entry);
+ Send(MakeSchemeCacheID(), new TEvTxProxySchemeCache::TEvNavigateKeySet(request.Release()));
+ ++Requests;
+ }
+
+ void RequestSchemeCacheNavigate(const TPathId& pathId) {
+ THolder<NSchemeCache::TSchemeCacheNavigate> request = MakeHolder<NSchemeCache::TSchemeCacheNavigate>();
+ NSchemeCache::TSchemeCacheNavigate::TEntry entry;
+ entry.TableId.PathId = pathId;
+ entry.RequestType = NSchemeCache::TSchemeCacheNavigate::TEntry::ERequestType::ByTableId;
+ entry.RedirectRequired = false;
+ entry.Operation = NSchemeCache::TSchemeCacheNavigate::EOp::OpPath;
+ request->ResultSet.emplace_back(entry);
+ Send(MakeSchemeCacheID(), new TEvTxProxySchemeCache::TEvNavigateKeySet(request.Release()));
+ ++Requests;
+ }
+
+ template<typename TEvent>
+ void RequestNodeWhiteboard(TNodeId nodeId) {
+ TActorId whiteboardServiceId = NNodeWhiteboard::MakeNodeWhiteboardServiceId(nodeId);
+ auto request = MakeHolder<TEvent>();
+ Send(whiteboardServiceId, request.Release(), IEventHandle::FlagTrackDelivery, nodeId);
+ }
+
+ void RequestGenericNode(TNodeId nodeId) {
+ if (NodeIds.emplace(nodeId).second) {
+ Send(TlsActivationContext->ActorSystem()->InterconnectProxy(nodeId), new TEvents::TEvSubscribe());
+ RequestNodeWhiteboard<NNodeWhiteboard::TEvWhiteboard::TEvSystemStateRequest>(nodeId);
+ ++Requests;
+ }
+ }
+
+ void RequestComputeNode(TNodeId nodeId) {
+ if (ComputeNodeIds.emplace(nodeId).second) {
+ RequestGenericNode(nodeId);
+ }
+ }
+
+ void RequestStorageNode(TNodeId nodeId) {
+ if (StorageNodeIds.emplace(nodeId).second) {
+ RequestGenericNode(nodeId);
+ RequestNodeWhiteboard<NNodeWhiteboard::TEvWhiteboard::TEvVDiskStateRequest>(nodeId);
+ ++Requests;
+ RequestNodeWhiteboard<NNodeWhiteboard::TEvWhiteboard::TEvPDiskStateRequest>(nodeId);
+ ++Requests;
+ RequestNodeWhiteboard<NNodeWhiteboard::TEvWhiteboard::TEvBSGroupStateRequest>(nodeId);
+ ++Requests;
+ }
+ }
+
+ void Handle(TEvPrivate::TEvRetryNodeWhiteboard::TPtr& ev) {
+ switch (ev->Get()->EventId) {
+ case NNodeWhiteboard::TEvWhiteboard::EvSystemStateRequest:
+ RequestNodeWhiteboard<NNodeWhiteboard::TEvWhiteboard::TEvSystemStateRequest>(ev->Get()->NodeId);
+ break;
+ case NNodeWhiteboard::TEvWhiteboard::EvVDiskStateRequest:
+ RequestNodeWhiteboard<NNodeWhiteboard::TEvWhiteboard::TEvVDiskStateRequest>(ev->Get()->NodeId);
+ break;
+ case NNodeWhiteboard::TEvWhiteboard::EvPDiskStateRequest:
+ RequestNodeWhiteboard<NNodeWhiteboard::TEvWhiteboard::TEvPDiskStateRequest>(ev->Get()->NodeId);
+ break;
+ case NNodeWhiteboard::TEvWhiteboard::EvBSGroupStateRequest:
+ RequestNodeWhiteboard<NNodeWhiteboard::TEvWhiteboard::TEvBSGroupStateRequest>(ev->Get()->NodeId);
+ break;
+ default:
+ RequestDone("unsupported event scheduled");
+ break;
+ }
+ }
+
+ template<typename TEvent>
+ bool RetryRequestNodeWhiteboard(TNodeId nodeId) {
+ if (NodeRetries[{nodeId, TEvent::EventType}]++ < MaxRetries) {
+ Schedule(RetryDelay, new TEvPrivate::TEvRetryNodeWhiteboard(nodeId, TEvent::EventType));
+ return true;
+ }
+ return false;
+ }
+
+ void Handle(TEvents::TEvUndelivered::TPtr& ev) {
+ ui32 nodeId = ev.Get()->Cookie;
+ if (ev->Get()->SourceType == NNodeWhiteboard::TEvWhiteboard::EvSystemStateRequest) {
+ if (NodeIds.count(nodeId) != 0 && NodeSystemState.count(nodeId) == 0) {
+ if (!RetryRequestNodeWhiteboard<NNodeWhiteboard::TEvWhiteboard::TEvSystemStateRequest>(nodeId)) {
+ NodeSystemState.emplace(nodeId, nullptr);
+ RequestDone("undelivered of TEvSystemStateRequest");
+ UnavailableComputeNodes.insert(nodeId);
+ }
+ }
+ }
+ if (ev->Get()->SourceType == NNodeWhiteboard::TEvWhiteboard::EvVDiskStateRequest) {
+ if (StorageNodeIds.count(nodeId) != 0 && NodeVDiskState.count(nodeId) == 0) {
+ if (!RetryRequestNodeWhiteboard<NNodeWhiteboard::TEvWhiteboard::TEvVDiskStateRequest>(nodeId)) {
+ NodeVDiskState.emplace(nodeId, nullptr);
+ RequestDone("undelivered of TEvVDiskStateRequest");
+ UnavailableStorageNodes.insert(nodeId);
+ }
+ }
+ }
+ if (ev->Get()->SourceType == NNodeWhiteboard::TEvWhiteboard::EvPDiskStateRequest) {
+ if (StorageNodeIds.count(nodeId) != 0 && NodePDiskState.count(nodeId) == 0) {
+ if (!RetryRequestNodeWhiteboard<NNodeWhiteboard::TEvWhiteboard::TEvPDiskStateRequest>(nodeId)) {
+ NodePDiskState.emplace(nodeId, nullptr);
+ RequestDone("undelivered of TEvPDiskStateRequest");
+ UnavailableStorageNodes.insert(nodeId);
+ }
+ }
+ }
+ if (ev->Get()->SourceType == NNodeWhiteboard::TEvWhiteboard::EvBSGroupStateRequest) {
+ if (StorageNodeIds.count(nodeId) != 0 && NodeBSGroupState.count(nodeId) == 0) {
+ if (!RetryRequestNodeWhiteboard<NNodeWhiteboard::TEvWhiteboard::TEvBSGroupStateRequest>(nodeId)) {
+ NodeBSGroupState.emplace(nodeId, nullptr);
+ RequestDone("undelivered of TEvBSGroupStateRequest");
+ }
+ }
+ }
+ }
+
+ void Disconnected(TEvInterconnect::TEvNodeDisconnected::TPtr& ev) {
+ ui32 nodeId = ev->Get()->NodeId;
+ if (NodeIds.count(nodeId) != 0 && NodeSystemState.count(nodeId) == 0) {
+ if (!RetryRequestNodeWhiteboard<NNodeWhiteboard::TEvWhiteboard::TEvSystemStateRequest>(nodeId)) {
+ NodeSystemState.emplace(nodeId, nullptr);
+ RequestDone("node disconnected with TEvSystemStateRequest");
+ UnavailableComputeNodes.insert(nodeId);
+ }
+ }
+ if (StorageNodeIds.count(nodeId) != 0 && NodeVDiskState.count(nodeId) == 0) {
+ if (!RetryRequestNodeWhiteboard<NNodeWhiteboard::TEvWhiteboard::TEvVDiskStateRequest>(nodeId)) {
+ NodeVDiskState.emplace(nodeId, nullptr);
+ RequestDone("node disconnected with TEvVDiskStateRequest");
+ UnavailableStorageNodes.insert(nodeId);
+ }
+ }
+ if (StorageNodeIds.count(nodeId) != 0 && NodePDiskState.count(nodeId) == 0) {
+ if (!RetryRequestNodeWhiteboard<NNodeWhiteboard::TEvWhiteboard::TEvPDiskStateRequest>(nodeId)) {
+ NodePDiskState.emplace(nodeId, nullptr);
+ RequestDone("node disconnected with TEvPDiskStateRequest");
+ UnavailableStorageNodes.insert(nodeId);
+ }
+ }
+ if (StorageNodeIds.count(nodeId) != 0 && NodeBSGroupState.count(nodeId) == 0) {
+ if (!RetryRequestNodeWhiteboard<NNodeWhiteboard::TEvWhiteboard::TEvBSGroupStateRequest>(nodeId)) {
+ NodeBSGroupState.emplace(nodeId, nullptr);
+ RequestDone("node disconnected with TEvBSGroupStateRequest");
+ }
+ }
+ }
+
+ void Handle(TEvTabletPipe::TEvClientDestroyed::TPtr&) {
+ }
+
+ void Handle(TEvTabletPipe::TEvClientConnected::TPtr& ev) {
+ if (ev->Get()->Status != NKikimrProto::OK) {
+ TTabletId tabletId = ev->Get()->TabletId;
+ for (const auto& [requestId, requestState] : TabletRequests.RequestsInFlight) {
+ if (requestState.TabletId == tabletId) {
+ RequestDone("unsuccessful TEvClientConnected");
+ }
+ }
+ }
+ }
+
+ void HandleTimeout() {
+ ReplyAndPassAway();
+ }
+
+ bool IsStaticNode(const TEvInterconnect::TNodeInfo& nodeInfo) const {
+ TAppData* appData = AppData();
+ if (appData->DynamicNameserviceConfig) {
+ return nodeInfo.NodeId <= AppData()->DynamicNameserviceConfig->MaxStaticNodeId;
+ } else {
+ return true;
+ }
+ }
+
+ void Handle(TEvInterconnect::TEvNodesInfo::TPtr& ev) {
+ bool needComputeFromStaticNodes = (!FilterDatabase || FilterDatabase == DomainPath);
+ NodesInfo = ev->Release();
+ for (const auto& ni : NodesInfo->Nodes) {
+ MergedNodeInfo[ni.NodeId] = &ni;
+ if (IsStaticNode(ni) && needComputeFromStaticNodes) {
+ DatabaseState[DomainPath].ComputeNodeIds.push_back(ni.NodeId);
+ RequestComputeNode(ni.NodeId);
+ }
+ }
+ RequestDone("TEvNodesInfo");
+ }
+
+ void Handle(TEvBlobStorage::TEvControllerConfigResponse::TPtr& ev) {
+ TabletRequests.CompleteRequest(ev->Cookie);
+ const NKikimrBlobStorage::TEvControllerConfigResponse& pbRecord(ev->Get()->Record);
+ if (pbRecord.HasResponse() && pbRecord.GetResponse().StatusSize() > 0) {
+ const NKikimrBlobStorage::TConfigResponse::TStatus& pbStatus(pbRecord.GetResponse().GetStatus(0));
+ if (pbStatus.HasBaseConfig()) {
+ const NKikimrBlobStorage::TBaseConfig& pbConfig(pbStatus.GetBaseConfig());
+ for (const NKikimrBlobStorage::TBaseConfig::TPDisk& pDisk : pbConfig.GetPDisk()) {
+ RequestStorageNode(pDisk.GetNodeId());
+ }
+ BaseConfig = ev->Release();
+ }
+ }
+ RequestDone("TEvControllerConfigResponse");
+ }
+
+ void Handle(TEvBlobStorage::TEvControllerSelectGroupsResult::TPtr& ev) {
+ TabletRequests.CompleteRequest(ev->Cookie);
+ for (const auto& matchingGroups : ev->Get()->Record.matchinggroups()) {
+ for (const auto& group : matchingGroups.groups()) {
+ TString storagePoolName = group.storagepoolname();
+ StoragePoolState[storagePoolName].Groups.emplace(group.groupid());
+ StoragePoolState[storagePoolName].AuthenticGroups.emplace(group.groupid());
+ }
+ }
+ RequestDone("TEvControllerSelectGroupsResult");
+ }
+
void Handle(NSchemeShard::TEvSchemeShard::TEvDescribeSchemeResult::TPtr& ev) {
- TabletRequests.CompleteRequest(ev->Cookie);
+ TabletRequests.CompleteRequest(ev->Cookie);
if (ev->Get()->GetRecord().GetStatus() == NKikimrScheme::StatusSuccess) {
- TString path = ev->Get()->GetRecord().GetPath();
- TDatabaseState& state(DatabaseState[path]);
- for (const auto& storagePool : ev->Get()->GetRecord().GetPathDescription().GetDomainDescription().GetStoragePools()) {
- TString storagePoolName = storagePool.name();
- state.StoragePoolNames.emplace_back(storagePoolName);
- StoragePoolState[storagePoolName].Kind = storagePool.kind();
- RequestSelectGroups(storagePoolName);
- }
- if (path == DomainPath) {
- state.StoragePoolNames.emplace_back(STATIC_STORAGE_POOL_NAME);
- }
- DescribeByPath[path] = ev->Release();
- }
- RequestDone("TEvDescribeSchemeResult");
- }
-
- void Handle(TEvTxProxySchemeCache::TEvNavigateKeySetResult::TPtr& ev) {
- if (ev->Get()->Request->ResultSet.size() == 1 && ev->Get()->Request->ResultSet.begin()->Status == NSchemeCache::TSchemeCacheNavigate::EStatus::Ok) {
- auto domainInfo = ev->Get()->Request->ResultSet.begin()->DomainInfo;
- TString path = CanonizePath(ev->Get()->Request->ResultSet.begin()->Path);
-
- if (domainInfo->DomainKey != domainInfo->ResourcesDomainKey) {
- if (SharedDatabases.emplace(domainInfo->ResourcesDomainKey, path).second) {
- RequestSchemeCacheNavigate(domainInfo->ResourcesDomainKey);
- }
- DatabaseState[path].ResourcePathId = domainInfo->ResourcesDomainKey;
- }
- TTabletId hiveId = domainInfo->Params.GetHive();
- if (hiveId) {
- DatabaseState[path].HiveId = hiveId;
- TabletRequests.TabletStates[hiveId].Database = path;
- TabletRequests.TabletStates[hiveId].Type = TTabletTypes::Hive;
- //RequestHiveDomainStats(hiveId);
- RequestHiveNodeStats(hiveId);
- RequestHiveInfo(hiveId);
- }
- FilterDomainKey[TSubDomainKey(domainInfo->DomainKey.OwnerId, domainInfo->DomainKey.LocalPathId)] = path;
- NavigateResult[path] = std::move(ev->Get()->Request);
- TTabletId schemeShardId = domainInfo->Params.GetSchemeShard();
- if (!schemeShardId) {
- schemeShardId = RootSchemeShardId;
- } else {
- TabletRequests.TabletStates[schemeShardId].Database = path;
- TabletRequests.TabletStates[schemeShardId].Type = TTabletTypes::SchemeShard;
- }
- RequestDescribe(schemeShardId, path);
- }
- RequestDone("TEvNavigateKeySetResult");
- }
-
- void Handle(TEvHive::TEvResponseHiveDomainStats::TPtr& ev) {
- TTabletId hiveId = TabletRequests.CompleteRequest(ev->Cookie);
- for (const NKikimrHive::THiveDomainStats& hiveStat : ev->Get()->Record.GetDomainStats()) {
- for (TNodeId nodeId : hiveStat.GetNodeIds()) {
- RequestComputeNode(nodeId);
- }
- }
- HiveDomainStats[hiveId] = std::move(ev->Release());
- RequestDone("TEvResponseHiveDomainStats");
- }
-
- void Handle(TEvHive::TEvResponseHiveNodeStats::TPtr& ev) {
- TTabletId hiveId = TabletRequests.CompleteRequest(ev->Cookie);
- for (const NKikimrHive::THiveNodeStats& hiveStat : ev->Get()->Record.GetNodeStats()) {
- RequestComputeNode(hiveStat.GetNodeId());
- }
- HiveNodeStats[hiveId] = std::move(ev->Release());
- RequestDone("TEvResponseHiveNodeStats");
- }
-
- void Handle(TEvHive::TEvResponseHiveInfo::TPtr& ev) {
- TTabletId hiveId = TabletRequests.CompleteRequest(ev->Cookie);
- HiveInfo[hiveId] = std::move(ev->Release());
- RequestDone("TEvResponseHiveInfo");
- }
-
- void Handle(NConsole::TEvConsole::TEvGetTenantStatusResponse::TPtr& ev) {
- TabletRequests.CompleteRequest(ev->Cookie);
- auto& operation(ev->Get()->Record.GetResponse().operation());
- if (operation.ready() && operation.status() == Ydb::StatusIds::SUCCESS) {
- Ydb::Cms::GetDatabaseStatusResult getTenantStatusResult;
- operation.result().UnpackTo(&getTenantStatusResult);
- TString path = getTenantStatusResult.path();
- DatabaseStatusByPath[path] = std::move(getTenantStatusResult);
- DatabaseState[path];
- RequestSchemeCacheNavigate(path);
- }
- RequestDone("TEvGetTenantStatusResponse");
- }
-
- void Handle(NConsole::TEvConsole::TEvListTenantsResponse::TPtr& ev) {
- TabletRequests.CompleteRequest(ev->Cookie);
- Ydb::Cms::ListDatabasesResult listTenantsResult;
- ev->Get()->Record.GetResponse().operation().result().UnpackTo(&listTenantsResult);
- for (const TString& path : listTenantsResult.paths()) {
- RequestTenantStatus(path);
- DatabaseState[path];
- }
- RequestDone("TEvListTenantsResponse");
- }
-
- void Handle(NNodeWhiteboard::TEvWhiteboard::TEvSystemStateResponse::TPtr& ev) {
- TNodeId nodeId = ev.Get()->Cookie;
- if (NodeSystemState.count(nodeId) == 0) {
- auto& nodeSystemState(NodeSystemState[nodeId]);
- nodeSystemState = ev->Release();
- for (NKikimrWhiteboard::TSystemStateInfo& state : *nodeSystemState->Record.MutableSystemStateInfo()) {
- state.set_nodeid(nodeId);
- MergedNodeSystemState[nodeId] = &state;
- }
- RequestDone("TEvSystemStateResponse");
- }
- }
-
- void AggregateHiveInfo() {
- TNodeTabletState::TTabletStateSettings settings;
- settings.AliveBarrier = TInstant::Now() - TDuration::Minutes(5);
- for (const auto& [hiveId, hiveResponse] : HiveInfo) {
- if (hiveResponse) {
- for (const NKikimrHive::TTabletInfo& hiveTablet : hiveResponse->Record.GetTablets()) {
- TSubDomainKey tenantId = TSubDomainKey(hiveTablet.GetObjectDomain());
- auto itDomain = FilterDomainKey.find(tenantId);
- if (itDomain == FilterDomainKey.end()) {
- continue;
- }
- auto itDatabase = DatabaseState.find(itDomain->second);
- if (itDatabase == DatabaseState.end()) {
- continue;
- }
- TDatabaseState& database = itDatabase->second;
+ TString path = ev->Get()->GetRecord().GetPath();
+ TDatabaseState& state(DatabaseState[path]);
+ for (const auto& storagePool : ev->Get()->GetRecord().GetPathDescription().GetDomainDescription().GetStoragePools()) {
+ TString storagePoolName = storagePool.name();
+ state.StoragePoolNames.emplace_back(storagePoolName);
+ StoragePoolState[storagePoolName].Kind = storagePool.kind();
+ RequestSelectGroups(storagePoolName);
+ }
+ if (path == DomainPath) {
+ state.StoragePoolNames.emplace_back(STATIC_STORAGE_POOL_NAME);
+ }
+ DescribeByPath[path] = ev->Release();
+ }
+ RequestDone("TEvDescribeSchemeResult");
+ }
+
+ void Handle(TEvTxProxySchemeCache::TEvNavigateKeySetResult::TPtr& ev) {
+ if (ev->Get()->Request->ResultSet.size() == 1 && ev->Get()->Request->ResultSet.begin()->Status == NSchemeCache::TSchemeCacheNavigate::EStatus::Ok) {
+ auto domainInfo = ev->Get()->Request->ResultSet.begin()->DomainInfo;
+ TString path = CanonizePath(ev->Get()->Request->ResultSet.begin()->Path);
+
+ if (domainInfo->DomainKey != domainInfo->ResourcesDomainKey) {
+ if (SharedDatabases.emplace(domainInfo->ResourcesDomainKey, path).second) {
+ RequestSchemeCacheNavigate(domainInfo->ResourcesDomainKey);
+ }
+ DatabaseState[path].ResourcePathId = domainInfo->ResourcesDomainKey;
+ }
+ TTabletId hiveId = domainInfo->Params.GetHive();
+ if (hiveId) {
+ DatabaseState[path].HiveId = hiveId;
+ TabletRequests.TabletStates[hiveId].Database = path;
+ TabletRequests.TabletStates[hiveId].Type = TTabletTypes::Hive;
+ //RequestHiveDomainStats(hiveId);
+ RequestHiveNodeStats(hiveId);
+ RequestHiveInfo(hiveId);
+ }
+ FilterDomainKey[TSubDomainKey(domainInfo->DomainKey.OwnerId, domainInfo->DomainKey.LocalPathId)] = path;
+ NavigateResult[path] = std::move(ev->Get()->Request);
+ TTabletId schemeShardId = domainInfo->Params.GetSchemeShard();
+ if (!schemeShardId) {
+ schemeShardId = RootSchemeShardId;
+ } else {
+ TabletRequests.TabletStates[schemeShardId].Database = path;
+ TabletRequests.TabletStates[schemeShardId].Type = TTabletTypes::SchemeShard;
+ }
+ RequestDescribe(schemeShardId, path);
+ }
+ RequestDone("TEvNavigateKeySetResult");
+ }
+
+ void Handle(TEvHive::TEvResponseHiveDomainStats::TPtr& ev) {
+ TTabletId hiveId = TabletRequests.CompleteRequest(ev->Cookie);
+ for (const NKikimrHive::THiveDomainStats& hiveStat : ev->Get()->Record.GetDomainStats()) {
+ for (TNodeId nodeId : hiveStat.GetNodeIds()) {
+ RequestComputeNode(nodeId);
+ }
+ }
+ HiveDomainStats[hiveId] = std::move(ev->Release());
+ RequestDone("TEvResponseHiveDomainStats");
+ }
+
+ void Handle(TEvHive::TEvResponseHiveNodeStats::TPtr& ev) {
+ TTabletId hiveId = TabletRequests.CompleteRequest(ev->Cookie);
+ for (const NKikimrHive::THiveNodeStats& hiveStat : ev->Get()->Record.GetNodeStats()) {
+ RequestComputeNode(hiveStat.GetNodeId());
+ }
+ HiveNodeStats[hiveId] = std::move(ev->Release());
+ RequestDone("TEvResponseHiveNodeStats");
+ }
+
+ void Handle(TEvHive::TEvResponseHiveInfo::TPtr& ev) {
+ TTabletId hiveId = TabletRequests.CompleteRequest(ev->Cookie);
+ HiveInfo[hiveId] = std::move(ev->Release());
+ RequestDone("TEvResponseHiveInfo");
+ }
+
+ void Handle(NConsole::TEvConsole::TEvGetTenantStatusResponse::TPtr& ev) {
+ TabletRequests.CompleteRequest(ev->Cookie);
+ auto& operation(ev->Get()->Record.GetResponse().operation());
+ if (operation.ready() && operation.status() == Ydb::StatusIds::SUCCESS) {
+ Ydb::Cms::GetDatabaseStatusResult getTenantStatusResult;
+ operation.result().UnpackTo(&getTenantStatusResult);
+ TString path = getTenantStatusResult.path();
+ DatabaseStatusByPath[path] = std::move(getTenantStatusResult);
+ DatabaseState[path];
+ RequestSchemeCacheNavigate(path);
+ }
+ RequestDone("TEvGetTenantStatusResponse");
+ }
+
+ void Handle(NConsole::TEvConsole::TEvListTenantsResponse::TPtr& ev) {
+ TabletRequests.CompleteRequest(ev->Cookie);
+ Ydb::Cms::ListDatabasesResult listTenantsResult;
+ ev->Get()->Record.GetResponse().operation().result().UnpackTo(&listTenantsResult);
+ for (const TString& path : listTenantsResult.paths()) {
+ RequestTenantStatus(path);
+ DatabaseState[path];
+ }
+ RequestDone("TEvListTenantsResponse");
+ }
+
+ void Handle(NNodeWhiteboard::TEvWhiteboard::TEvSystemStateResponse::TPtr& ev) {
+ TNodeId nodeId = ev.Get()->Cookie;
+ if (NodeSystemState.count(nodeId) == 0) {
+ auto& nodeSystemState(NodeSystemState[nodeId]);
+ nodeSystemState = ev->Release();
+ for (NKikimrWhiteboard::TSystemStateInfo& state : *nodeSystemState->Record.MutableSystemStateInfo()) {
+ state.set_nodeid(nodeId);
+ MergedNodeSystemState[nodeId] = &state;
+ }
+ RequestDone("TEvSystemStateResponse");
+ }
+ }
+
+ void AggregateHiveInfo() {
+ TNodeTabletState::TTabletStateSettings settings;
+ settings.AliveBarrier = TInstant::Now() - TDuration::Minutes(5);
+ for (const auto& [hiveId, hiveResponse] : HiveInfo) {
+ if (hiveResponse) {
+ for (const NKikimrHive::TTabletInfo& hiveTablet : hiveResponse->Record.GetTablets()) {
+ TSubDomainKey tenantId = TSubDomainKey(hiveTablet.GetObjectDomain());
+ auto itDomain = FilterDomainKey.find(tenantId);
+ if (itDomain == FilterDomainKey.end()) {
+ continue;
+ }
+ auto itDatabase = DatabaseState.find(itDomain->second);
+ if (itDatabase == DatabaseState.end()) {
+ continue;
+ }
+ TDatabaseState& database = itDatabase->second;
auto tabletId = std::make_pair(hiveTablet.GetTabletID(), hiveTablet.GetFollowerID());
- database.MergedTabletState.emplace(tabletId, &hiveTablet);
- TNodeId nodeId = hiveTablet.GetNodeID();
- switch (hiveTablet.GetVolatileState()) {
- case NKikimrHive::ETabletVolatileState::TABLET_VOLATILE_STATE_STARTING:
- case NKikimrHive::ETabletVolatileState::TABLET_VOLATILE_STATE_RUNNING:
- break;
- default:
- nodeId = 0;
- break;
- }
- database.MergedNodeTabletState[nodeId].AddTablet(hiveTablet, settings);
- }
- }
- }
- }
-
- void AggregateHiveDomainStats() {
- for (const auto& [hiveId, hiveResponse] : HiveDomainStats) {
- if (hiveResponse) {
- for (const NKikimrHive::THiveDomainStats& hiveStat : hiveResponse->Record.GetDomainStats()) {
- TSubDomainKey domainKey({hiveStat.GetShardId(), hiveStat.GetPathId()});
- auto itFilterDomainKey = FilterDomainKey.find(domainKey);
- if (itFilterDomainKey != FilterDomainKey.end()) {
- TString path(itFilterDomainKey->second);
- TDatabaseState& state(DatabaseState[path]);
- for (TNodeId nodeId : hiveStat.GetNodeIds()) {
- state.ComputeNodeIds.emplace_back(nodeId);
- }
- }
- }
- }
- }
- }
-
- void AggregateHiveNodeStats() {
- for (const auto& [hiveId, hiveResponse] : HiveNodeStats) {
- if (hiveResponse) {
- for (const NKikimrHive::THiveNodeStats& hiveStat : hiveResponse->Record.GetNodeStats()) {
- if (hiveStat.HasNodeDomain()) {
- TSubDomainKey domainKey(hiveStat.GetNodeDomain());
- auto itFilterDomainKey = FilterDomainKey.find(domainKey);
- if (itFilterDomainKey != FilterDomainKey.end()) {
- TString path(itFilterDomainKey->second);
- TDatabaseState& state(DatabaseState[path]);
- state.ComputeNodeIds.emplace_back(hiveStat.GetNodeId());
- }
- }
- }
- }
- }
- }
-
- void AggregateBSControllerState() {
- if (BaseConfig) {
- const NKikimrBlobStorage::TEvControllerConfigResponse& pbRecord(BaseConfig->Record);
- const NKikimrBlobStorage::TConfigResponse::TStatus& pbStatus(pbRecord.GetResponse().GetStatus(0));
- if (pbStatus.HasBaseConfig()) {
- const NKikimrBlobStorage::TBaseConfig& pbConfig(pbStatus.GetBaseConfig());
- for (const NKikimrBlobStorage::TBaseConfig::TPDisk& pDisk : pbConfig.GetPDisk()) {
- auto pDiskId = GetPDiskId(pDisk);
- ValidPDisks.emplace(pDiskId);
- auto itPDisk = MergedPDiskState.find(pDiskId);
- if (itPDisk == MergedPDiskState.end()) {
- PDisksAppended.emplace_back();
- NKikimrWhiteboard::TPDiskStateInfo& pbPDisk = PDisksAppended.back();
- itPDisk = MergedPDiskState.emplace(pDiskId, &pbPDisk).first;
- pbPDisk.SetNodeId(pDisk.GetNodeId());
- pbPDisk.SetPDiskId(pDisk.GetPDiskId());
- pbPDisk.SetPath(pDisk.GetPath());
- pbPDisk.SetGuid(pDisk.GetGuid());
- pbPDisk.SetCategory(static_cast<ui64>(pDisk.GetType()));
- pbPDisk.SetTotalSize(pDisk.GetPDiskMetrics().GetTotalSize());
- pbPDisk.SetAvailableSize(pDisk.GetPDiskMetrics().GetAvailableSize());
- }
- }
- std::unordered_map<NKikimrBlobStorage::TVSlotId, const NKikimrBlobStorage::TBaseConfig::TVSlot*> slotsIndex;
- for (const NKikimrBlobStorage::TBaseConfig::TVSlot& vDisk : pbConfig.GetVSlot()) {
- slotsIndex[vDisk.GetVSlotId()] = &vDisk;
- auto vDiskId = GetVDiskId(vDisk);
- ValidVDisks.emplace(vDiskId);
- auto itVDisk = MergedVDiskState.find(vDiskId);
- if (itVDisk == MergedVDiskState.end()) {
- VDisksAppended.emplace_back();
- NKikimrWhiteboard::TVDiskStateInfo& pbVDisk = VDisksAppended.back();
- itVDisk = MergedVDiskState.emplace(vDiskId, &pbVDisk).first;
- auto* pVDiskId = pbVDisk.MutableVDiskId();
- pVDiskId->SetGroupID(vDisk.groupid());
- pVDiskId->SetGroupGeneration(vDisk.groupgeneration());
- pVDiskId->SetRing(vDisk.failrealmidx());
- pVDiskId->SetDomain(vDisk.faildomainidx());
- pVDiskId->SetVDisk(vDisk.vslotid().vslotid());
- pbVDisk.SetNodeId(vDisk.GetVSlotId().GetNodeId());
- pbVDisk.SetPDiskId(vDisk.GetVSlotId().GetPDiskId());
- pbVDisk.SetAllocatedSize(vDisk.GetVDiskMetrics().GetAllocatedSize());
- }
- }
- for (const NKikimrBlobStorage::TBaseConfig::TGroup& group : pbConfig.GetGroup()) {
- auto groupId = group.GetGroupId();
- ValidGroups.emplace(groupId);
- auto itGroup = MergedBSGroupState.find(groupId);
- if (itGroup == MergedBSGroupState.end()) {
- BSGroupAppended.emplace_back();
- NKikimrWhiteboard::TBSGroupStateInfo& pbGroup = BSGroupAppended.back();
- itGroup = MergedBSGroupState.emplace(groupId, &pbGroup).first;
- pbGroup.SetGroupID(group.GetGroupId());
- pbGroup.SetGroupGeneration(group.GetGroupGeneration());
- pbGroup.SetErasureSpecies(group.GetErasureSpecies());
- for (const auto& vSlotId : group.GetVSlotId()) {
- auto itSlot = slotsIndex.find(vSlotId);
- if (itSlot != slotsIndex.end()) {
- const auto& vSlot(*(itSlot->second));
- VDiskIDFromVDiskID(TVDiskID(vSlot.GetGroupId(),
- vSlot.GetGroupGeneration(),
- vSlot.GetFailRealmIdx(),
- vSlot.GetFailDomainIdx(),
- vSlot.GetVDiskIdx()), pbGroup.AddVDiskIds());
- }
- }
- }
- }
- }
- }
- for (auto itPDisk = MergedPDiskState.begin(); itPDisk != MergedPDiskState.end();) {
- if (ValidPDisks.count(itPDisk->first)) {
- ++itPDisk;
- } else {
- itPDisk = MergedPDiskState.erase(itPDisk);
- }
- }
- for (auto itVDisk = MergedVDiskState.begin(); itVDisk != MergedVDiskState.end();) {
- if (ValidVDisks.count(itVDisk->first)) {
- ++itVDisk;
- } else {
- itVDisk = MergedVDiskState.erase(itVDisk);
- }
- }
- for (auto itGroup = MergedBSGroupState.begin(); itGroup != MergedBSGroupState.end();) {
- if (ValidGroups.count(itGroup->first)) {
- ++itGroup;
- } else {
- itGroup = MergedBSGroupState.erase(itGroup);
- }
- }
- }
-
- void Handle(NNodeWhiteboard::TEvWhiteboard::TEvVDiskStateResponse::TPtr& ev) {
- TNodeId nodeId = ev.Get()->Cookie;
- if (NodeVDiskState.count(nodeId) == 0) {
- auto& nodeVDiskState(NodeVDiskState[nodeId]);
- nodeVDiskState = ev->Release();
- for (NKikimrWhiteboard::TVDiskStateInfo& state : *nodeVDiskState->Record.MutableVDiskStateInfo()) {
- state.set_nodeid(nodeId);
- auto id = GetVDiskId(state.vdiskid());
- MergedVDiskState[id] = &state;
- }
- RequestDone("TEvVDiskStateResponse");
- }
- }
-
- void Handle(NNodeWhiteboard::TEvWhiteboard::TEvPDiskStateResponse::TPtr& ev) {
- TNodeId nodeId = ev.Get()->Cookie;
- if (NodePDiskState.count(nodeId) == 0) {
- auto& nodePDiskState(NodePDiskState[nodeId]);
- nodePDiskState = ev->Release();
- for (NKikimrWhiteboard::TPDiskStateInfo& state : *nodePDiskState->Record.MutablePDiskStateInfo()) {
- state.set_nodeid(nodeId);
- auto id = GetPDiskId(state);
- MergedPDiskState[id] = &state;
- }
- RequestDone("TEvPDiskStateResponse");
- }
- }
-
- void Handle(NNodeWhiteboard::TEvWhiteboard::TEvBSGroupStateResponse::TPtr& ev) {
- ui64 nodeId = ev.Get()->Cookie;
- if (NodeBSGroupState.count(nodeId) == 0) {
- auto& nodeBSGroupState(NodeBSGroupState[nodeId]);
- nodeBSGroupState = ev->Release();
- for (NKikimrWhiteboard::TBSGroupStateInfo& state : *nodeBSGroupState->Record.MutableBSGroupStateInfo()) {
- state.set_nodeid(nodeId);
- TString storagePoolName = state.storagepoolname();
- TGroupID groupId(state.groupid());
- const NKikimrWhiteboard::TBSGroupStateInfo*& current(MergedBSGroupState[state.groupid()]);
- if (current == nullptr || current->GetGroupGeneration() < state.GetGroupGeneration()) {
- current = &state;
- }
- if (storagePoolName.empty() && groupId.ConfigurationType() != EGroupConfigurationType::GroupConfigurationTypeStatic) {
- continue;
- }
- StoragePoolState[storagePoolName].Groups.emplace(state.groupid());
- }
- RequestDone("TEvBSGroupStateResponse");
- }
- }
-
- static Ydb::Monitoring::StatusFlag::Status MaxStatus(Ydb::Monitoring::StatusFlag::Status a, Ydb::Monitoring::StatusFlag::Status b) {
- return static_cast<Ydb::Monitoring::StatusFlag::Status>(std::max<int>(a, b));
- }
-
- static Ydb::Monitoring::StatusFlag::Status MinStatus(Ydb::Monitoring::StatusFlag::Status a, Ydb::Monitoring::StatusFlag::Status b) {
- return static_cast<Ydb::Monitoring::StatusFlag::Status>(std::min<int>(a, b));
- }
-
- static Ydb::Monitoring::StatusFlag::Status StatusFromWhiteboardFlag(NKikimrWhiteboard::EFlag flag) {
- switch(flag) {
- case NKikimrWhiteboard::EFlag::Green:
- return Ydb::Monitoring::StatusFlag::GREEN;
- case NKikimrWhiteboard::EFlag::Yellow:
- return Ydb::Monitoring::StatusFlag::YELLOW;
- case NKikimrWhiteboard::EFlag::Orange:
- return Ydb::Monitoring::StatusFlag::ORANGE;
- case NKikimrWhiteboard::EFlag::Red:
- return Ydb::Monitoring::StatusFlag::RED;
- default:
- return Ydb::Monitoring::StatusFlag::GREY;
- }
- }
-
- static Ydb::Monitoring::StatusFlag::Status StatusFrom(const NKikimrWhiteboard::TSystemStateInfo& systemStateInfo) {
- return StatusFromWhiteboardFlag(systemStateInfo.GetSystemState());
- }
-
- static Ydb::Monitoring::StatusFlag::Status StatusFrom(const NKikimrWhiteboard::TTabletStateInfo& tabletStateInfo) {
- TInstant now(TInstant::Now());
- if (tabletStateInfo.state() == NKikimrWhiteboard::TTabletStateInfo::Active) {
- if (now - TInstant::MilliSeconds(tabletStateInfo.changetime()) > TDuration::Seconds(30)) {
- return Ydb::Monitoring::StatusFlag::GREEN;
- } else {
- return Ydb::Monitoring::StatusFlag::YELLOW;
- }
- } else {
+ database.MergedTabletState.emplace(tabletId, &hiveTablet);
+ TNodeId nodeId = hiveTablet.GetNodeID();
+ switch (hiveTablet.GetVolatileState()) {
+ case NKikimrHive::ETabletVolatileState::TABLET_VOLATILE_STATE_STARTING:
+ case NKikimrHive::ETabletVolatileState::TABLET_VOLATILE_STATE_RUNNING:
+ break;
+ default:
+ nodeId = 0;
+ break;
+ }
+ database.MergedNodeTabletState[nodeId].AddTablet(hiveTablet, settings);
+ }
+ }
+ }
+ }
+
+ void AggregateHiveDomainStats() {
+ for (const auto& [hiveId, hiveResponse] : HiveDomainStats) {
+ if (hiveResponse) {
+ for (const NKikimrHive::THiveDomainStats& hiveStat : hiveResponse->Record.GetDomainStats()) {
+ TSubDomainKey domainKey({hiveStat.GetShardId(), hiveStat.GetPathId()});
+ auto itFilterDomainKey = FilterDomainKey.find(domainKey);
+ if (itFilterDomainKey != FilterDomainKey.end()) {
+ TString path(itFilterDomainKey->second);
+ TDatabaseState& state(DatabaseState[path]);
+ for (TNodeId nodeId : hiveStat.GetNodeIds()) {
+ state.ComputeNodeIds.emplace_back(nodeId);
+ }
+ }
+ }
+ }
+ }
+ }
+
+ void AggregateHiveNodeStats() {
+ for (const auto& [hiveId, hiveResponse] : HiveNodeStats) {
+ if (hiveResponse) {
+ for (const NKikimrHive::THiveNodeStats& hiveStat : hiveResponse->Record.GetNodeStats()) {
+ if (hiveStat.HasNodeDomain()) {
+ TSubDomainKey domainKey(hiveStat.GetNodeDomain());
+ auto itFilterDomainKey = FilterDomainKey.find(domainKey);
+ if (itFilterDomainKey != FilterDomainKey.end()) {
+ TString path(itFilterDomainKey->second);
+ TDatabaseState& state(DatabaseState[path]);
+ state.ComputeNodeIds.emplace_back(hiveStat.GetNodeId());
+ }
+ }
+ }
+ }
+ }
+ }
+
+ void AggregateBSControllerState() {
+ if (BaseConfig) {
+ const NKikimrBlobStorage::TEvControllerConfigResponse& pbRecord(BaseConfig->Record);
+ const NKikimrBlobStorage::TConfigResponse::TStatus& pbStatus(pbRecord.GetResponse().GetStatus(0));
+ if (pbStatus.HasBaseConfig()) {
+ const NKikimrBlobStorage::TBaseConfig& pbConfig(pbStatus.GetBaseConfig());
+ for (const NKikimrBlobStorage::TBaseConfig::TPDisk& pDisk : pbConfig.GetPDisk()) {
+ auto pDiskId = GetPDiskId(pDisk);
+ ValidPDisks.emplace(pDiskId);
+ auto itPDisk = MergedPDiskState.find(pDiskId);
+ if (itPDisk == MergedPDiskState.end()) {
+ PDisksAppended.emplace_back();
+ NKikimrWhiteboard::TPDiskStateInfo& pbPDisk = PDisksAppended.back();
+ itPDisk = MergedPDiskState.emplace(pDiskId, &pbPDisk).first;
+ pbPDisk.SetNodeId(pDisk.GetNodeId());
+ pbPDisk.SetPDiskId(pDisk.GetPDiskId());
+ pbPDisk.SetPath(pDisk.GetPath());
+ pbPDisk.SetGuid(pDisk.GetGuid());
+ pbPDisk.SetCategory(static_cast<ui64>(pDisk.GetType()));
+ pbPDisk.SetTotalSize(pDisk.GetPDiskMetrics().GetTotalSize());
+ pbPDisk.SetAvailableSize(pDisk.GetPDiskMetrics().GetAvailableSize());
+ }
+ }
+ std::unordered_map<NKikimrBlobStorage::TVSlotId, const NKikimrBlobStorage::TBaseConfig::TVSlot*> slotsIndex;
+ for (const NKikimrBlobStorage::TBaseConfig::TVSlot& vDisk : pbConfig.GetVSlot()) {
+ slotsIndex[vDisk.GetVSlotId()] = &vDisk;
+ auto vDiskId = GetVDiskId(vDisk);
+ ValidVDisks.emplace(vDiskId);
+ auto itVDisk = MergedVDiskState.find(vDiskId);
+ if (itVDisk == MergedVDiskState.end()) {
+ VDisksAppended.emplace_back();
+ NKikimrWhiteboard::TVDiskStateInfo& pbVDisk = VDisksAppended.back();
+ itVDisk = MergedVDiskState.emplace(vDiskId, &pbVDisk).first;
+ auto* pVDiskId = pbVDisk.MutableVDiskId();
+ pVDiskId->SetGroupID(vDisk.groupid());
+ pVDiskId->SetGroupGeneration(vDisk.groupgeneration());
+ pVDiskId->SetRing(vDisk.failrealmidx());
+ pVDiskId->SetDomain(vDisk.faildomainidx());
+ pVDiskId->SetVDisk(vDisk.vslotid().vslotid());
+ pbVDisk.SetNodeId(vDisk.GetVSlotId().GetNodeId());
+ pbVDisk.SetPDiskId(vDisk.GetVSlotId().GetPDiskId());
+ pbVDisk.SetAllocatedSize(vDisk.GetVDiskMetrics().GetAllocatedSize());
+ }
+ }
+ for (const NKikimrBlobStorage::TBaseConfig::TGroup& group : pbConfig.GetGroup()) {
+ auto groupId = group.GetGroupId();
+ ValidGroups.emplace(groupId);
+ auto itGroup = MergedBSGroupState.find(groupId);
+ if (itGroup == MergedBSGroupState.end()) {
+ BSGroupAppended.emplace_back();
+ NKikimrWhiteboard::TBSGroupStateInfo& pbGroup = BSGroupAppended.back();
+ itGroup = MergedBSGroupState.emplace(groupId, &pbGroup).first;
+ pbGroup.SetGroupID(group.GetGroupId());
+ pbGroup.SetGroupGeneration(group.GetGroupGeneration());
+ pbGroup.SetErasureSpecies(group.GetErasureSpecies());
+ for (const auto& vSlotId : group.GetVSlotId()) {
+ auto itSlot = slotsIndex.find(vSlotId);
+ if (itSlot != slotsIndex.end()) {
+ const auto& vSlot(*(itSlot->second));
+ VDiskIDFromVDiskID(TVDiskID(vSlot.GetGroupId(),
+ vSlot.GetGroupGeneration(),
+ vSlot.GetFailRealmIdx(),
+ vSlot.GetFailDomainIdx(),
+ vSlot.GetVDiskIdx()), pbGroup.AddVDiskIds());
+ }
+ }
+ }
+ }
+ }
+ }
+ for (auto itPDisk = MergedPDiskState.begin(); itPDisk != MergedPDiskState.end();) {
+ if (ValidPDisks.count(itPDisk->first)) {
+ ++itPDisk;
+ } else {
+ itPDisk = MergedPDiskState.erase(itPDisk);
+ }
+ }
+ for (auto itVDisk = MergedVDiskState.begin(); itVDisk != MergedVDiskState.end();) {
+ if (ValidVDisks.count(itVDisk->first)) {
+ ++itVDisk;
+ } else {
+ itVDisk = MergedVDiskState.erase(itVDisk);
+ }
+ }
+ for (auto itGroup = MergedBSGroupState.begin(); itGroup != MergedBSGroupState.end();) {
+ if (ValidGroups.count(itGroup->first)) {
+ ++itGroup;
+ } else {
+ itGroup = MergedBSGroupState.erase(itGroup);
+ }
+ }
+ }
+
+ void Handle(NNodeWhiteboard::TEvWhiteboard::TEvVDiskStateResponse::TPtr& ev) {
+ TNodeId nodeId = ev.Get()->Cookie;
+ if (NodeVDiskState.count(nodeId) == 0) {
+ auto& nodeVDiskState(NodeVDiskState[nodeId]);
+ nodeVDiskState = ev->Release();
+ for (NKikimrWhiteboard::TVDiskStateInfo& state : *nodeVDiskState->Record.MutableVDiskStateInfo()) {
+ state.set_nodeid(nodeId);
+ auto id = GetVDiskId(state.vdiskid());
+ MergedVDiskState[id] = &state;
+ }
+ RequestDone("TEvVDiskStateResponse");
+ }
+ }
+
+ void Handle(NNodeWhiteboard::TEvWhiteboard::TEvPDiskStateResponse::TPtr& ev) {
+ TNodeId nodeId = ev.Get()->Cookie;
+ if (NodePDiskState.count(nodeId) == 0) {
+ auto& nodePDiskState(NodePDiskState[nodeId]);
+ nodePDiskState = ev->Release();
+ for (NKikimrWhiteboard::TPDiskStateInfo& state : *nodePDiskState->Record.MutablePDiskStateInfo()) {
+ state.set_nodeid(nodeId);
+ auto id = GetPDiskId(state);
+ MergedPDiskState[id] = &state;
+ }
+ RequestDone("TEvPDiskStateResponse");
+ }
+ }
+
+ void Handle(NNodeWhiteboard::TEvWhiteboard::TEvBSGroupStateResponse::TPtr& ev) {
+ ui64 nodeId = ev.Get()->Cookie;
+ if (NodeBSGroupState.count(nodeId) == 0) {
+ auto& nodeBSGroupState(NodeBSGroupState[nodeId]);
+ nodeBSGroupState = ev->Release();
+ for (NKikimrWhiteboard::TBSGroupStateInfo& state : *nodeBSGroupState->Record.MutableBSGroupStateInfo()) {
+ state.set_nodeid(nodeId);
+ TString storagePoolName = state.storagepoolname();
+ TGroupID groupId(state.groupid());
+ const NKikimrWhiteboard::TBSGroupStateInfo*& current(MergedBSGroupState[state.groupid()]);
+ if (current == nullptr || current->GetGroupGeneration() < state.GetGroupGeneration()) {
+ current = &state;
+ }
+ if (storagePoolName.empty() && groupId.ConfigurationType() != EGroupConfigurationType::GroupConfigurationTypeStatic) {
+ continue;
+ }
+ StoragePoolState[storagePoolName].Groups.emplace(state.groupid());
+ }
+ RequestDone("TEvBSGroupStateResponse");
+ }
+ }
+
+ static Ydb::Monitoring::StatusFlag::Status MaxStatus(Ydb::Monitoring::StatusFlag::Status a, Ydb::Monitoring::StatusFlag::Status b) {
+ return static_cast<Ydb::Monitoring::StatusFlag::Status>(std::max<int>(a, b));
+ }
+
+ static Ydb::Monitoring::StatusFlag::Status MinStatus(Ydb::Monitoring::StatusFlag::Status a, Ydb::Monitoring::StatusFlag::Status b) {
+ return static_cast<Ydb::Monitoring::StatusFlag::Status>(std::min<int>(a, b));
+ }
+
+ static Ydb::Monitoring::StatusFlag::Status StatusFromWhiteboardFlag(NKikimrWhiteboard::EFlag flag) {
+ switch(flag) {
+ case NKikimrWhiteboard::EFlag::Green:
+ return Ydb::Monitoring::StatusFlag::GREEN;
+ case NKikimrWhiteboard::EFlag::Yellow:
+ return Ydb::Monitoring::StatusFlag::YELLOW;
+ case NKikimrWhiteboard::EFlag::Orange:
+ return Ydb::Monitoring::StatusFlag::ORANGE;
+ case NKikimrWhiteboard::EFlag::Red:
+ return Ydb::Monitoring::StatusFlag::RED;
+ default:
+ return Ydb::Monitoring::StatusFlag::GREY;
+ }
+ }
+
+ static Ydb::Monitoring::StatusFlag::Status StatusFrom(const NKikimrWhiteboard::TSystemStateInfo& systemStateInfo) {
+ return StatusFromWhiteboardFlag(systemStateInfo.GetSystemState());
+ }
+
+ static Ydb::Monitoring::StatusFlag::Status StatusFrom(const NKikimrWhiteboard::TTabletStateInfo& tabletStateInfo) {
+ TInstant now(TInstant::Now());
+ if (tabletStateInfo.state() == NKikimrWhiteboard::TTabletStateInfo::Active) {
+ if (now - TInstant::MilliSeconds(tabletStateInfo.changetime()) > TDuration::Seconds(30)) {
+ return Ydb::Monitoring::StatusFlag::GREEN;
+ } else {
+ return Ydb::Monitoring::StatusFlag::YELLOW;
+ }
+ } else {
if (tabletStateInfo.leader()) {
- return Ydb::Monitoring::StatusFlag::RED;
- } else {
- return Ydb::Monitoring::StatusFlag::BLUE;
- }
- }
- }
-
- static Ydb::Monitoring::StatusFlag::Status StatusFrom(const NKikimrHive::TTabletInfo& tabletInfo) {
- switch (tabletInfo.volatilestate()) {
- case NKikimrHive::TABLET_VOLATILE_STATE_RUNNING:
- return Ydb::Monitoring::StatusFlag::GREEN;
- case NKikimrHive::TABLET_VOLATILE_STATE_STARTING:
- return Ydb::Monitoring::StatusFlag::YELLOW;
- default:
- return Ydb::Monitoring::StatusFlag::RED;
- }
- }
-
- static TString GetNodeLocation(const TEvInterconnect::TNodeInfo& nodeInfo) {
- return TStringBuilder() << nodeInfo.NodeId << '/' << nodeInfo.Host << ':' << nodeInfo.Port;
- }
-
- static void Check(TSelfCheckContext& context, const NKikimrWhiteboard::TSystemStateInfo::TPoolStats& poolStats) {
- if (poolStats.name() == "System" || poolStats.name() == "IC" || poolStats.name() == "IO") {
- if (poolStats.usage() >= 0.99) {
- context.ReportStatus(Ydb::Monitoring::StatusFlag::RED, "Pool usage over 99%", "overload-state");
- } else if (poolStats.usage() >= 0.95) {
- context.ReportStatus(Ydb::Monitoring::StatusFlag::ORANGE, "Pool usage over 95%", "overload-state");
- } else if (poolStats.usage() >= 0.90) {
- context.ReportStatus(Ydb::Monitoring::StatusFlag::YELLOW, "Pool usage over 90%", "overload-state");
- } else {
- context.ReportStatus(Ydb::Monitoring::StatusFlag::GREEN);
- }
- } else {
- if (poolStats.usage() >= 0.99) {
- context.ReportStatus(Ydb::Monitoring::StatusFlag::ORANGE, "Pool usage over 99%", "overload-state");
- } else if (poolStats.usage() >= 0.95) {
- context.ReportStatus(Ydb::Monitoring::StatusFlag::YELLOW, "Pool usage over 95%", "overload-state");
- } else {
- context.ReportStatus(Ydb::Monitoring::StatusFlag::GREEN);
- }
- }
- }
-
- Ydb::Monitoring::StatusFlag::Status FillSystemTablets(TSelfCheckContext context) {
- TString databaseId = context.Location.database().name();
- for (auto& [tabletId, tablet] : TabletRequests.TabletStates) {
- if (tablet.Database == databaseId) {
- context.Location.mutable_compute()->clear_tablet();
- auto& protoTablet = *context.Location.mutable_compute()->mutable_tablet();
- if (tablet.IsUnresponsive || tablet.MaxResponseTime >= TDuration::MilliSeconds(1000)) {
- if (tablet.Type != TTabletTypes::Unknown) {
- protoTablet.set_type(TTabletTypes::EType_Name(tablet.Type));
- }
- protoTablet.add_id(ToString(tabletId));
- if (tablet.IsUnresponsive) {
- context.ReportStatus(Ydb::Monitoring::StatusFlag::RED, TStringBuilder() << "System tablet is unresponsive", "system-tablet-state");
- } else if (tablet.MaxResponseTime >= TDuration::MilliSeconds(5000)) {
- context.ReportStatus(Ydb::Monitoring::StatusFlag::ORANGE, "System tablet response time is over 5000ms", "system-tablet-state");
- } else if (tablet.MaxResponseTime >= TDuration::MilliSeconds(1000)) {
- context.ReportStatus(Ydb::Monitoring::StatusFlag::YELLOW, "System tablet response time is over 1000ms", "system-tablet-state");
- }
- }
- }
- }
- return context.GetOverallStatus();
- }
-
- Ydb::Monitoring::StatusFlag::Status FillTablets(TDatabaseState& databaseState,
- TNodeId nodeId,
- google::protobuf::RepeatedPtrField<Ydb::Monitoring::ComputeTabletStatus>& parent,
- TSelfCheckContext& context) {
- Ydb::Monitoring::StatusFlag::Status tabletsStatus = Ydb::Monitoring::StatusFlag::GREEN;
- auto itNodeTabletState = databaseState.MergedNodeTabletState.find(nodeId);
- if (itNodeTabletState != databaseState.MergedNodeTabletState.end()) {
- TSelfCheckContext tabletsContext(&context);
- for (const auto& count : itNodeTabletState->second.Count) {
- if (count.Count > 0) {
- TSelfCheckContext tabletContext(&tabletsContext, "TABLET");
- auto& protoTablet = *tabletContext.Location.mutable_compute()->mutable_tablet();
- protoTablet.set_type(TTabletTypes::EType_Name(count.Type));
- protoTablet.set_count(count.Count);
- if (!count.Identifiers.empty()) {
- for (const TString& id : count.Identifiers) {
- protoTablet.add_id(id);
- }
- }
- Ydb::Monitoring::ComputeTabletStatus& computeTabletStatus = *parent.Add();
- computeTabletStatus.set_type(NKikimrTabletBase::TTabletTypes::EType_Name(count.Type));
- computeTabletStatus.set_count(count.Count);
- for (const TString& id : count.Identifiers) {
- computeTabletStatus.add_id(id);
- }
- switch (count.State) {
- case TNodeTabletState::ETabletState::Good:
- computeTabletStatus.set_state("GOOD");
- tabletContext.ReportStatus(Ydb::Monitoring::StatusFlag::GREEN);
- break;
- case TNodeTabletState::ETabletState::Stopped:
- computeTabletStatus.set_state("STOPPED");
- tabletContext.ReportStatus(Ydb::Monitoring::StatusFlag::GREEN);
- break;
- case TNodeTabletState::ETabletState::RestartsTooOften:
- computeTabletStatus.set_state("RESTARTS_TOO_OFTEN");
- tabletContext.ReportStatus(Ydb::Monitoring::StatusFlag::RED, "Tablets are restarting too often", "tablet-state");
- break;
- case TNodeTabletState::ETabletState::Dead:
- computeTabletStatus.set_state("DEAD");
- tabletContext.ReportStatus(Ydb::Monitoring::StatusFlag::RED, "Tablets are dead", "tablet-state");
- break;
- }
- computeTabletStatus.set_overall(tabletContext.GetOverallStatus());
- tabletsStatus = MaxStatus(tabletsStatus, tabletContext.GetOverallStatus());
- }
- }
- }
- return tabletsStatus;
- }
-
- void FillComputeNodeStatus(TNodeId nodeId, Ydb::Monitoring::ComputeNodeStatus& computeNodeStatus, TSelfCheckContext context) {
- const TEvInterconnect::TNodeInfo* nodeInfo = nullptr;
- auto itNodeInfo = MergedNodeInfo.find(nodeId);
- if (itNodeInfo != MergedNodeInfo.end()) {
- nodeInfo = itNodeInfo->second;
- }
- TString id(ToString(nodeId));
-
- context.Location.mutable_compute()->mutable_node()->set_id(nodeId);
- if (nodeInfo) {
- context.Location.mutable_compute()->mutable_node()->set_host(nodeInfo->Host);
- context.Location.mutable_compute()->mutable_node()->set_port(nodeInfo->Port);
- }
-
- auto itNodeSystemState = MergedNodeSystemState.find(nodeId);
- if (itNodeSystemState != MergedNodeSystemState.end()) {
- const NKikimrWhiteboard::TSystemStateInfo& nodeSystemState(*itNodeSystemState->second);
-
- for (const auto& poolStat : nodeSystemState.poolstats()) {
- TSelfCheckContext poolContext(&context, "COMPUTE_POOL");
- poolContext.Location.mutable_compute()->mutable_pool()->set_name(poolStat.name());
- Check(poolContext, poolStat);
- Ydb::Monitoring::ThreadPoolStatus& threadPoolStatus = *computeNodeStatus.add_pools();
- threadPoolStatus.set_name(poolStat.name());
- threadPoolStatus.set_usage(poolStat.usage());
- threadPoolStatus.set_overall(poolContext.GetOverallStatus());
- }
-
- if (nodeSystemState.loadaverage_size() > 0 && nodeSystemState.numberofcpus() > 0) {
- TSelfCheckContext laContext(&context, "LOAD_AVERAGE");
- Ydb::Monitoring::LoadAverageStatus& loadAverageStatus = *computeNodeStatus.mutable_load();
- loadAverageStatus.set_load(nodeSystemState.loadaverage(0));
- loadAverageStatus.set_cores(nodeSystemState.numberofcpus());
- if (loadAverageStatus.load() > loadAverageStatus.cores()) {
- laContext.ReportStatus(Ydb::Monitoring::StatusFlag::YELLOW, "LoadAverage above 100%", "overload-state");
- } else {
- laContext.ReportStatus(Ydb::Monitoring::StatusFlag::GREEN);
- }
- loadAverageStatus.set_overall(laContext.GetOverallStatus());
- }
- } else {
- // context.ReportStatus(Ydb::Monitoring::StatusFlag::RED,
- // TStringBuilder() << "Compute node is not available",
- // "node-state");
- }
- computeNodeStatus.set_id(id);
- computeNodeStatus.set_overall(context.GetOverallStatus());
- }
-
- void FillCompute(TDatabaseState& databaseState, Ydb::Monitoring::ComputeStatus& computeStatus, TSelfCheckContext context) {
- TVector<TNodeId>* computeNodeIds = &databaseState.ComputeNodeIds;
- if (databaseState.ResourcePathId) {
- auto itDatabase = FilterDomainKey.find(TSubDomainKey(databaseState.ResourcePathId.OwnerId, databaseState.ResourcePathId.LocalPathId));
- if (itDatabase != FilterDomainKey.end()) {
- const TString& sharedDatabaseName = itDatabase->second;
- TDatabaseState& sharedDatabase = DatabaseState[sharedDatabaseName];
- computeNodeIds = &sharedDatabase.ComputeNodeIds;
- }
- }
-
- std::sort(computeNodeIds->begin(), computeNodeIds->end());
- computeNodeIds->erase(std::unique(computeNodeIds->begin(), computeNodeIds->end()), computeNodeIds->end());
- if (computeNodeIds->empty()) {
- context.ReportStatus(Ydb::Monitoring::StatusFlag::RED, "There are no compute nodes");
- } else {
- Ydb::Monitoring::StatusFlag::Status systemStatus = FillSystemTablets({&context, "SYSTEM_TABLET"});
- if (systemStatus != Ydb::Monitoring::StatusFlag::GREEN && systemStatus != Ydb::Monitoring::StatusFlag::GREY) {
- context.ReportStatus(systemStatus, "Compute has issues with system tablets", "compute-state", {"system-tablet-state"});
- }
- Ydb::Monitoring::StatusFlag::Status nodesStatus = Ydb::Monitoring::StatusFlag::GREEN;
- for (TNodeId nodeId : *computeNodeIds) {
- auto& computeNode = *computeStatus.add_nodes();
- FillComputeNodeStatus(nodeId, computeNode, {&context, "COMPUTE_NODE"});
- nodesStatus = MaxStatus(nodesStatus, computeNode.overall());
- }
- if (nodesStatus != Ydb::Monitoring::StatusFlag::GREEN) {
- context.ReportStatus(nodesStatus, "Compute is overloaded", "compute-state", {"overload-state"});
- }
- Ydb::Monitoring::StatusFlag::Status tabletsStatus = Ydb::Monitoring::StatusFlag::GREEN;
- computeNodeIds->push_back(0); // for tablets without node
- for (TNodeId nodeId : *computeNodeIds) {
- tabletsStatus = MaxStatus(tabletsStatus, FillTablets(databaseState, nodeId, *computeStatus.mutable_tablets(), context));
- }
- if (tabletsStatus != Ydb::Monitoring::StatusFlag::GREEN) {
- context.ReportStatus(tabletsStatus, "Compute has issues with tablets", "compute-state", {"tablet-state"});
- }
- }
- computeStatus.set_overall(context.GetOverallStatus());
- }
-
- static TString GetVDiskId(const NKikimrBlobStorage::TVDiskID& protoVDiskId) {
- return TStringBuilder()
- << protoVDiskId.groupid() << '-'
- << protoVDiskId.groupgeneration() << '-'
- << protoVDiskId.ring() << '-'
- << protoVDiskId.domain() << '-'
- << protoVDiskId.vdisk();
- }
-
- static TString GetVDiskId(const NKikimrBlobStorage::TBaseConfig::TVSlot& protoVSlotId) {
- return TStringBuilder()
- << protoVSlotId.groupid() << '-'
- << protoVSlotId.groupgeneration() << '-'
- << protoVSlotId.failrealmidx() << '-'
- << protoVSlotId.faildomainidx() << '-'
- << protoVSlotId.vdiskidx();
- }
-
- static TString GetVDiskId(const NKikimrBlobStorage::TNodeWardenServiceSet_TVDisk& protoVDiskId) {
- return GetVDiskId(protoVDiskId.vdiskid());
- }
-
- static TString GetVDiskId(const NKikimrWhiteboard::TVDiskStateInfo vDiskInfo) {
- return GetVDiskId(vDiskInfo.vdiskid());
- }
-
- static TString GetPDiskId(const NKikimrWhiteboard::TVDiskStateInfo vDiskInfo) {
- return TStringBuilder() << vDiskInfo.nodeid() << "-" << vDiskInfo.pdiskid();
- }
-
- static TString GetPDiskId(const NKikimrWhiteboard::TPDiskStateInfo pDiskInfo) {
- return TStringBuilder() << pDiskInfo.nodeid() << "-" << pDiskInfo.pdiskid();
- }
-
- static TString GetPDiskId(const NKikimrBlobStorage::TBaseConfig::TPDisk& pDisk) {
- return TStringBuilder() << pDisk.nodeid() << "-" << pDisk.pdiskid();
- }
-
- static TString GetPDiskId(const NKikimrBlobStorage::TNodeWardenServiceSet_TPDisk& pDisk) {
- return TStringBuilder() << pDisk.nodeid() << "-" << pDisk.pdiskid();
- }
-
- void FillPDiskStatus(const TString& pDiskId, const NKikimrWhiteboard::TPDiskStateInfo& pDiskInfo, Ydb::Monitoring::StoragePDiskStatus& storagePDiskStatus, TSelfCheckContext context) {
- context.Location.clear_database(); // PDisks are shared between databases
- context.Location.mutable_storage()->mutable_pool()->clear_name(); // PDisks are shared between pools
- context.Location.mutable_storage()->mutable_pool()->mutable_group()->clear_id(); // PDisks are shared between groups
- context.Location.mutable_storage()->mutable_pool()->mutable_group()->mutable_vdisk()->clear_id(); // PDisks are shared between vdisks
- context.Location.mutable_storage()->mutable_pool()->mutable_group()->mutable_vdisk()->mutable_pdisk()->set_id(pDiskId);
- context.Location.mutable_storage()->mutable_pool()->mutable_group()->mutable_vdisk()->mutable_pdisk()->set_path(pDiskInfo.path());
- storagePDiskStatus.set_id(pDiskId);
-
- if (pDiskInfo.HasState()) {
- switch (pDiskInfo.GetState()) {
+ return Ydb::Monitoring::StatusFlag::RED;
+ } else {
+ return Ydb::Monitoring::StatusFlag::BLUE;
+ }
+ }
+ }
+
+ static Ydb::Monitoring::StatusFlag::Status StatusFrom(const NKikimrHive::TTabletInfo& tabletInfo) {
+ switch (tabletInfo.volatilestate()) {
+ case NKikimrHive::TABLET_VOLATILE_STATE_RUNNING:
+ return Ydb::Monitoring::StatusFlag::GREEN;
+ case NKikimrHive::TABLET_VOLATILE_STATE_STARTING:
+ return Ydb::Monitoring::StatusFlag::YELLOW;
+ default:
+ return Ydb::Monitoring::StatusFlag::RED;
+ }
+ }
+
+ static TString GetNodeLocation(const TEvInterconnect::TNodeInfo& nodeInfo) {
+ return TStringBuilder() << nodeInfo.NodeId << '/' << nodeInfo.Host << ':' << nodeInfo.Port;
+ }
+
+ static void Check(TSelfCheckContext& context, const NKikimrWhiteboard::TSystemStateInfo::TPoolStats& poolStats) {
+ if (poolStats.name() == "System" || poolStats.name() == "IC" || poolStats.name() == "IO") {
+ if (poolStats.usage() >= 0.99) {
+ context.ReportStatus(Ydb::Monitoring::StatusFlag::RED, "Pool usage over 99%", "overload-state");
+ } else if (poolStats.usage() >= 0.95) {
+ context.ReportStatus(Ydb::Monitoring::StatusFlag::ORANGE, "Pool usage over 95%", "overload-state");
+ } else if (poolStats.usage() >= 0.90) {
+ context.ReportStatus(Ydb::Monitoring::StatusFlag::YELLOW, "Pool usage over 90%", "overload-state");
+ } else {
+ context.ReportStatus(Ydb::Monitoring::StatusFlag::GREEN);
+ }
+ } else {
+ if (poolStats.usage() >= 0.99) {
+ context.ReportStatus(Ydb::Monitoring::StatusFlag::ORANGE, "Pool usage over 99%", "overload-state");
+ } else if (poolStats.usage() >= 0.95) {
+ context.ReportStatus(Ydb::Monitoring::StatusFlag::YELLOW, "Pool usage over 95%", "overload-state");
+ } else {
+ context.ReportStatus(Ydb::Monitoring::StatusFlag::GREEN);
+ }
+ }
+ }
+
+ Ydb::Monitoring::StatusFlag::Status FillSystemTablets(TSelfCheckContext context) {
+ TString databaseId = context.Location.database().name();
+ for (auto& [tabletId, tablet] : TabletRequests.TabletStates) {
+ if (tablet.Database == databaseId) {
+ context.Location.mutable_compute()->clear_tablet();
+ auto& protoTablet = *context.Location.mutable_compute()->mutable_tablet();
+ if (tablet.IsUnresponsive || tablet.MaxResponseTime >= TDuration::MilliSeconds(1000)) {
+ if (tablet.Type != TTabletTypes::Unknown) {
+ protoTablet.set_type(TTabletTypes::EType_Name(tablet.Type));
+ }
+ protoTablet.add_id(ToString(tabletId));
+ if (tablet.IsUnresponsive) {
+ context.ReportStatus(Ydb::Monitoring::StatusFlag::RED, TStringBuilder() << "System tablet is unresponsive", "system-tablet-state");
+ } else if (tablet.MaxResponseTime >= TDuration::MilliSeconds(5000)) {
+ context.ReportStatus(Ydb::Monitoring::StatusFlag::ORANGE, "System tablet response time is over 5000ms", "system-tablet-state");
+ } else if (tablet.MaxResponseTime >= TDuration::MilliSeconds(1000)) {
+ context.ReportStatus(Ydb::Monitoring::StatusFlag::YELLOW, "System tablet response time is over 1000ms", "system-tablet-state");
+ }
+ }
+ }
+ }
+ return context.GetOverallStatus();
+ }
+
+ Ydb::Monitoring::StatusFlag::Status FillTablets(TDatabaseState& databaseState,
+ TNodeId nodeId,
+ google::protobuf::RepeatedPtrField<Ydb::Monitoring::ComputeTabletStatus>& parent,
+ TSelfCheckContext& context) {
+ Ydb::Monitoring::StatusFlag::Status tabletsStatus = Ydb::Monitoring::StatusFlag::GREEN;
+ auto itNodeTabletState = databaseState.MergedNodeTabletState.find(nodeId);
+ if (itNodeTabletState != databaseState.MergedNodeTabletState.end()) {
+ TSelfCheckContext tabletsContext(&context);
+ for (const auto& count : itNodeTabletState->second.Count) {
+ if (count.Count > 0) {
+ TSelfCheckContext tabletContext(&tabletsContext, "TABLET");
+ auto& protoTablet = *tabletContext.Location.mutable_compute()->mutable_tablet();
+ protoTablet.set_type(TTabletTypes::EType_Name(count.Type));
+ protoTablet.set_count(count.Count);
+ if (!count.Identifiers.empty()) {
+ for (const TString& id : count.Identifiers) {
+ protoTablet.add_id(id);
+ }
+ }
+ Ydb::Monitoring::ComputeTabletStatus& computeTabletStatus = *parent.Add();
+ computeTabletStatus.set_type(NKikimrTabletBase::TTabletTypes::EType_Name(count.Type));
+ computeTabletStatus.set_count(count.Count);
+ for (const TString& id : count.Identifiers) {
+ computeTabletStatus.add_id(id);
+ }
+ switch (count.State) {
+ case TNodeTabletState::ETabletState::Good:
+ computeTabletStatus.set_state("GOOD");
+ tabletContext.ReportStatus(Ydb::Monitoring::StatusFlag::GREEN);
+ break;
+ case TNodeTabletState::ETabletState::Stopped:
+ computeTabletStatus.set_state("STOPPED");
+ tabletContext.ReportStatus(Ydb::Monitoring::StatusFlag::GREEN);
+ break;
+ case TNodeTabletState::ETabletState::RestartsTooOften:
+ computeTabletStatus.set_state("RESTARTS_TOO_OFTEN");
+ tabletContext.ReportStatus(Ydb::Monitoring::StatusFlag::RED, "Tablets are restarting too often", "tablet-state");
+ break;
+ case TNodeTabletState::ETabletState::Dead:
+ computeTabletStatus.set_state("DEAD");
+ tabletContext.ReportStatus(Ydb::Monitoring::StatusFlag::RED, "Tablets are dead", "tablet-state");
+ break;
+ }
+ computeTabletStatus.set_overall(tabletContext.GetOverallStatus());
+ tabletsStatus = MaxStatus(tabletsStatus, tabletContext.GetOverallStatus());
+ }
+ }
+ }
+ return tabletsStatus;
+ }
+
+ void FillComputeNodeStatus(TNodeId nodeId, Ydb::Monitoring::ComputeNodeStatus& computeNodeStatus, TSelfCheckContext context) {
+ const TEvInterconnect::TNodeInfo* nodeInfo = nullptr;
+ auto itNodeInfo = MergedNodeInfo.find(nodeId);
+ if (itNodeInfo != MergedNodeInfo.end()) {
+ nodeInfo = itNodeInfo->second;
+ }
+ TString id(ToString(nodeId));
+
+ context.Location.mutable_compute()->mutable_node()->set_id(nodeId);
+ if (nodeInfo) {
+ context.Location.mutable_compute()->mutable_node()->set_host(nodeInfo->Host);
+ context.Location.mutable_compute()->mutable_node()->set_port(nodeInfo->Port);
+ }
+
+ auto itNodeSystemState = MergedNodeSystemState.find(nodeId);
+ if (itNodeSystemState != MergedNodeSystemState.end()) {
+ const NKikimrWhiteboard::TSystemStateInfo& nodeSystemState(*itNodeSystemState->second);
+
+ for (const auto& poolStat : nodeSystemState.poolstats()) {
+ TSelfCheckContext poolContext(&context, "COMPUTE_POOL");
+ poolContext.Location.mutable_compute()->mutable_pool()->set_name(poolStat.name());
+ Check(poolContext, poolStat);
+ Ydb::Monitoring::ThreadPoolStatus& threadPoolStatus = *computeNodeStatus.add_pools();
+ threadPoolStatus.set_name(poolStat.name());
+ threadPoolStatus.set_usage(poolStat.usage());
+ threadPoolStatus.set_overall(poolContext.GetOverallStatus());
+ }
+
+ if (nodeSystemState.loadaverage_size() > 0 && nodeSystemState.numberofcpus() > 0) {
+ TSelfCheckContext laContext(&context, "LOAD_AVERAGE");
+ Ydb::Monitoring::LoadAverageStatus& loadAverageStatus = *computeNodeStatus.mutable_load();
+ loadAverageStatus.set_load(nodeSystemState.loadaverage(0));
+ loadAverageStatus.set_cores(nodeSystemState.numberofcpus());
+ if (loadAverageStatus.load() > loadAverageStatus.cores()) {
+ laContext.ReportStatus(Ydb::Monitoring::StatusFlag::YELLOW, "LoadAverage above 100%", "overload-state");
+ } else {
+ laContext.ReportStatus(Ydb::Monitoring::StatusFlag::GREEN);
+ }
+ loadAverageStatus.set_overall(laContext.GetOverallStatus());
+ }
+ } else {
+ // context.ReportStatus(Ydb::Monitoring::StatusFlag::RED,
+ // TStringBuilder() << "Compute node is not available",
+ // "node-state");
+ }
+ computeNodeStatus.set_id(id);
+ computeNodeStatus.set_overall(context.GetOverallStatus());
+ }
+
+ void FillCompute(TDatabaseState& databaseState, Ydb::Monitoring::ComputeStatus& computeStatus, TSelfCheckContext context) {
+ TVector<TNodeId>* computeNodeIds = &databaseState.ComputeNodeIds;
+ if (databaseState.ResourcePathId) {
+ auto itDatabase = FilterDomainKey.find(TSubDomainKey(databaseState.ResourcePathId.OwnerId, databaseState.ResourcePathId.LocalPathId));
+ if (itDatabase != FilterDomainKey.end()) {
+ const TString& sharedDatabaseName = itDatabase->second;
+ TDatabaseState& sharedDatabase = DatabaseState[sharedDatabaseName];
+ computeNodeIds = &sharedDatabase.ComputeNodeIds;
+ }
+ }
+
+ std::sort(computeNodeIds->begin(), computeNodeIds->end());
+ computeNodeIds->erase(std::unique(computeNodeIds->begin(), computeNodeIds->end()), computeNodeIds->end());
+ if (computeNodeIds->empty()) {
+ context.ReportStatus(Ydb::Monitoring::StatusFlag::RED, "There are no compute nodes");
+ } else {
+ Ydb::Monitoring::StatusFlag::Status systemStatus = FillSystemTablets({&context, "SYSTEM_TABLET"});
+ if (systemStatus != Ydb::Monitoring::StatusFlag::GREEN && systemStatus != Ydb::Monitoring::StatusFlag::GREY) {
+ context.ReportStatus(systemStatus, "Compute has issues with system tablets", "compute-state", {"system-tablet-state"});
+ }
+ Ydb::Monitoring::StatusFlag::Status nodesStatus = Ydb::Monitoring::StatusFlag::GREEN;
+ for (TNodeId nodeId : *computeNodeIds) {
+ auto& computeNode = *computeStatus.add_nodes();
+ FillComputeNodeStatus(nodeId, computeNode, {&context, "COMPUTE_NODE"});
+ nodesStatus = MaxStatus(nodesStatus, computeNode.overall());
+ }
+ if (nodesStatus != Ydb::Monitoring::StatusFlag::GREEN) {
+ context.ReportStatus(nodesStatus, "Compute is overloaded", "compute-state", {"overload-state"});
+ }
+ Ydb::Monitoring::StatusFlag::Status tabletsStatus = Ydb::Monitoring::StatusFlag::GREEN;
+ computeNodeIds->push_back(0); // for tablets without node
+ for (TNodeId nodeId : *computeNodeIds) {
+ tabletsStatus = MaxStatus(tabletsStatus, FillTablets(databaseState, nodeId, *computeStatus.mutable_tablets(), context));
+ }
+ if (tabletsStatus != Ydb::Monitoring::StatusFlag::GREEN) {
+ context.ReportStatus(tabletsStatus, "Compute has issues with tablets", "compute-state", {"tablet-state"});
+ }
+ }
+ computeStatus.set_overall(context.GetOverallStatus());
+ }
+
+ static TString GetVDiskId(const NKikimrBlobStorage::TVDiskID& protoVDiskId) {
+ return TStringBuilder()
+ << protoVDiskId.groupid() << '-'
+ << protoVDiskId.groupgeneration() << '-'
+ << protoVDiskId.ring() << '-'
+ << protoVDiskId.domain() << '-'
+ << protoVDiskId.vdisk();
+ }
+
+ static TString GetVDiskId(const NKikimrBlobStorage::TBaseConfig::TVSlot& protoVSlotId) {
+ return TStringBuilder()
+ << protoVSlotId.groupid() << '-'
+ << protoVSlotId.groupgeneration() << '-'
+ << protoVSlotId.failrealmidx() << '-'
+ << protoVSlotId.faildomainidx() << '-'
+ << protoVSlotId.vdiskidx();
+ }
+
+ static TString GetVDiskId(const NKikimrBlobStorage::TNodeWardenServiceSet_TVDisk& protoVDiskId) {
+ return GetVDiskId(protoVDiskId.vdiskid());
+ }
+
+ static TString GetVDiskId(const NKikimrWhiteboard::TVDiskStateInfo vDiskInfo) {
+ return GetVDiskId(vDiskInfo.vdiskid());
+ }
+
+ static TString GetPDiskId(const NKikimrWhiteboard::TVDiskStateInfo vDiskInfo) {
+ return TStringBuilder() << vDiskInfo.nodeid() << "-" << vDiskInfo.pdiskid();
+ }
+
+ static TString GetPDiskId(const NKikimrWhiteboard::TPDiskStateInfo pDiskInfo) {
+ return TStringBuilder() << pDiskInfo.nodeid() << "-" << pDiskInfo.pdiskid();
+ }
+
+ static TString GetPDiskId(const NKikimrBlobStorage::TBaseConfig::TPDisk& pDisk) {
+ return TStringBuilder() << pDisk.nodeid() << "-" << pDisk.pdiskid();
+ }
+
+ static TString GetPDiskId(const NKikimrBlobStorage::TNodeWardenServiceSet_TPDisk& pDisk) {
+ return TStringBuilder() << pDisk.nodeid() << "-" << pDisk.pdiskid();
+ }
+
+ void FillPDiskStatus(const TString& pDiskId, const NKikimrWhiteboard::TPDiskStateInfo& pDiskInfo, Ydb::Monitoring::StoragePDiskStatus& storagePDiskStatus, TSelfCheckContext context) {
+ context.Location.clear_database(); // PDisks are shared between databases
+ context.Location.mutable_storage()->mutable_pool()->clear_name(); // PDisks are shared between pools
+ context.Location.mutable_storage()->mutable_pool()->mutable_group()->clear_id(); // PDisks are shared between groups
+ context.Location.mutable_storage()->mutable_pool()->mutable_group()->mutable_vdisk()->clear_id(); // PDisks are shared between vdisks
+ context.Location.mutable_storage()->mutable_pool()->mutable_group()->mutable_vdisk()->mutable_pdisk()->set_id(pDiskId);
+ context.Location.mutable_storage()->mutable_pool()->mutable_group()->mutable_vdisk()->mutable_pdisk()->set_path(pDiskInfo.path());
+ storagePDiskStatus.set_id(pDiskId);
+
+ if (pDiskInfo.HasState()) {
+ switch (pDiskInfo.GetState()) {
case NKikimrBlobStorage::TPDiskState::Normal:
- context.ReportStatus(Ydb::Monitoring::StatusFlag::GREEN);
- break;
+ context.ReportStatus(Ydb::Monitoring::StatusFlag::GREEN);
+ break;
case NKikimrBlobStorage::TPDiskState::Initial:
case NKikimrBlobStorage::TPDiskState::InitialFormatRead:
case NKikimrBlobStorage::TPDiskState::InitialSysLogRead:
case NKikimrBlobStorage::TPDiskState::InitialCommonLogRead:
- context.ReportStatus(Ydb::Monitoring::StatusFlag::YELLOW,
+ context.ReportStatus(Ydb::Monitoring::StatusFlag::YELLOW,
TStringBuilder() << "PDisk state is " << NKikimrBlobStorage::TPDiskState::E_Name(pDiskInfo.GetState()),
- "pdisk-state");
- break;
+ "pdisk-state");
+ break;
case NKikimrBlobStorage::TPDiskState::InitialFormatReadError:
case NKikimrBlobStorage::TPDiskState::InitialSysLogReadError:
case NKikimrBlobStorage::TPDiskState::InitialSysLogParseError:
@@ -1499,440 +1499,440 @@ public:
case NKikimrBlobStorage::TPDiskState::Timeout:
case NKikimrBlobStorage::TPDiskState::NodeDisconnected:
case NKikimrBlobStorage::TPDiskState::Unknown:
- context.ReportStatus(Ydb::Monitoring::StatusFlag::RED,
+ context.ReportStatus(Ydb::Monitoring::StatusFlag::RED,
TStringBuilder() << "PDisk state is " << NKikimrBlobStorage::TPDiskState::E_Name(pDiskInfo.GetState()),
- "pdisk-state");
- break;
+ "pdisk-state");
+ break;
case NKikimrBlobStorage::TPDiskState::Reserved14:
case NKikimrBlobStorage::TPDiskState::Reserved15:
case NKikimrBlobStorage::TPDiskState::Reserved16:
- context.ReportStatus(Ydb::Monitoring::StatusFlag::RED, "Unknown PDisk state");
- break;
- }
-
- //if (pDiskInfo.HasAvailableSize() && pDiskInfo.GetTotalSize() != 0) {
- if (pDiskInfo.GetAvailableSize() != 0 && pDiskInfo.GetTotalSize() != 0) { // hotfix until KIKIMR-12659
- double avail = (double)pDiskInfo.GetAvailableSize() / pDiskInfo.GetTotalSize();
- if (avail < 0.06) {
- context.ReportStatus(Ydb::Monitoring::StatusFlag::RED, "Available size is less than 6%", "pdisk-space");
+ context.ReportStatus(Ydb::Monitoring::StatusFlag::RED, "Unknown PDisk state");
+ break;
+ }
+
+ //if (pDiskInfo.HasAvailableSize() && pDiskInfo.GetTotalSize() != 0) {
+ if (pDiskInfo.GetAvailableSize() != 0 && pDiskInfo.GetTotalSize() != 0) { // hotfix until KIKIMR-12659
+ double avail = (double)pDiskInfo.GetAvailableSize() / pDiskInfo.GetTotalSize();
+ if (avail < 0.06) {
+ context.ReportStatus(Ydb::Monitoring::StatusFlag::RED, "Available size is less than 6%", "pdisk-space");
} else if (avail < 0.09) {
context.ReportStatus(Ydb::Monitoring::StatusFlag::ORANGE, "Available size is less than 9%", "pdisk-space");
} else if (avail < 0.12) {
context.ReportStatus(Ydb::Monitoring::StatusFlag::YELLOW, "Available size is less than 12%", "pdisk-space");
- }
- }
- } else {
- if (UnavailableStorageNodes.count(pDiskInfo.nodeid()) != 0) {
- TSelfCheckContext nodeContext(&context, "STORAGE_NODE");
- nodeContext.Location.mutable_storage()->clear_pool();
- nodeContext.Location.mutable_storage()->mutable_node()->set_id(pDiskInfo.nodeid());
- const TEvInterconnect::TNodeInfo* nodeInfo = nullptr;
- auto itNodeInfo = MergedNodeInfo.find(pDiskInfo.nodeid());
- if (itNodeInfo != MergedNodeInfo.end()) {
- nodeInfo = itNodeInfo->second;
- }
- if (nodeInfo) {
- nodeContext.Location.mutable_storage()->mutable_node()->set_host(nodeInfo->Host);
- nodeContext.Location.mutable_storage()->mutable_node()->set_port(nodeInfo->Port);
- }
- nodeContext.ReportStatus(Ydb::Monitoring::StatusFlag::RED,
- TStringBuilder() << "Storage node is not available",
- "node-state");
- }
- context.ReportStatus(Ydb::Monitoring::StatusFlag::RED,
- TStringBuilder() << "PDisk is not available",
- "pdisk-state",
- {"node-state"});
- }
-
- storagePDiskStatus.set_overall(context.GetOverallStatus());
- }
-
- static Ydb::Monitoring::StatusFlag::Status GetFlagFromWhiteboardFlag(NKikimrWhiteboard::EFlag flag) {
- switch (flag) {
- case NKikimrWhiteboard::EFlag::Green:
- return Ydb::Monitoring::StatusFlag::GREEN;
- case NKikimrWhiteboard::EFlag::Yellow:
- return Ydb::Monitoring::StatusFlag::YELLOW;
- case NKikimrWhiteboard::EFlag::Orange:
- return Ydb::Monitoring::StatusFlag::ORANGE;
- case NKikimrWhiteboard::EFlag::Red:
- return Ydb::Monitoring::StatusFlag::RED;
- default:
- return Ydb::Monitoring::StatusFlag::UNSPECIFIED;
- }
- }
-
- void FillVDiskStatus(const TString& vDiskId, const NKikimrWhiteboard::TVDiskStateInfo& vDiskInfo, Ydb::Monitoring::StorageVDiskStatus& storageVDiskStatus, TSelfCheckContext context) {
- context.Location.mutable_storage()->mutable_pool()->mutable_group()->mutable_vdisk()->set_id(vDiskId);
- storageVDiskStatus.set_id(vDiskId);
- TString pDiskId = GetPDiskId(vDiskInfo);
- auto itPDisk = MergedPDiskState.find(pDiskId);
- if (itPDisk != MergedPDiskState.end()) {
- FillPDiskStatus(pDiskId, *itPDisk->second, *storageVDiskStatus.mutable_pdisk(), {&context, "PDISK"});
- }
-
- if (!vDiskInfo.HasVDiskState()) {
- context.ReportStatus(Ydb::Monitoring::StatusFlag::RED,
- TStringBuilder() << "VDisk is not available",
- "vdisk-state",
- {"pdisk-state"});
- storageVDiskStatus.set_overall(context.GetOverallStatus());
- return;
- }
-
- switch (vDiskInfo.GetVDiskState()) {
- case NKikimrWhiteboard::EVDiskState::OK:
- context.ReportStatus(Ydb::Monitoring::StatusFlag::GREEN);
- break;
- case NKikimrWhiteboard::EVDiskState::Initial:
- case NKikimrWhiteboard::EVDiskState::SyncGuidRecovery:
- context.ReportStatus(Ydb::Monitoring::StatusFlag::YELLOW,
- TStringBuilder() << "VDisk state is " << NKikimrWhiteboard::EVDiskState_Name(vDiskInfo.GetVDiskState()),
- "vdisk-state");
- break;
- case NKikimrWhiteboard::EVDiskState::LocalRecoveryError:
- case NKikimrWhiteboard::EVDiskState::SyncGuidRecoveryError:
- case NKikimrWhiteboard::EVDiskState::PDiskError:
- context.ReportStatus(Ydb::Monitoring::StatusFlag::RED,
- TStringBuilder() << "VDisk state is " << NKikimrWhiteboard::EVDiskState_Name(vDiskInfo.GetVDiskState()),
- "vdisk-state",
- {"pdisk-state"});
- break;
- }
-
- if (vDiskInfo.HasDiskSpace()) {
- switch(vDiskInfo.GetDiskSpace()) {
- case NKikimrWhiteboard::EFlag::Green:
- context.ReportStatus(Ydb::Monitoring::StatusFlag::GREEN);
- break;
- case NKikimrWhiteboard::EFlag::Red:
- break;
- context.ReportStatus(GetFlagFromWhiteboardFlag(vDiskInfo.GetDiskSpace()),
- TStringBuilder() << "DiskSpace is " << NKikimrWhiteboard::EFlag_Name(vDiskInfo.GetDiskSpace()),
- "vdisk-state",
- {"pdisk-space"});
- default:
- context.ReportStatus(GetFlagFromWhiteboardFlag(vDiskInfo.GetDiskSpace()),
- TStringBuilder() << "DiskSpace is " << NKikimrWhiteboard::EFlag_Name(vDiskInfo.GetDiskSpace()),
- "vdisk-space",
- {"pdisk-space"});
- break;
- }
- }
-
- if (context.GetOverallStatus() == Ydb::Monitoring::StatusFlag::GREEN && !vDiskInfo.GetReplicated()) {
- context.ReportStatus(Ydb::Monitoring::StatusFlag::BLUE, "Replication in progress", "vdisk-state");
- }
-
- storageVDiskStatus.set_overall(context.GetOverallStatus());
- }
-
- static const inline TString NONE = "none";
- static const inline TString BLOCK_4_2 = "block-4-2";
- static const inline TString MIRROR_3_DC = "mirror-3-dc";
-
- static void IncrementFor(TStackVec<std::pair<ui32, int>>& realms, ui32 realm) {
- auto itRealm = FindIf(realms, [realm](const std::pair<ui32, int>& p) -> bool {
- return p.first == realm;
- });
- if (itRealm == realms.end()) {
- itRealm = realms.insert(realms.end(), { realm, 1 });
- } else {
- itRealm->second++;
- }
- }
-
- void FillGroupStatus(TGroupId groupId, const NKikimrWhiteboard::TBSGroupStateInfo& groupInfo, Ydb::Monitoring::StorageGroupStatus& storageGroupStatus, TSelfCheckContext context) {
- context.Location.mutable_storage()->mutable_pool()->mutable_group()->set_id(ToString(groupId));
- storageGroupStatus.set_id(ToString(groupId));
- int disksColors[Ydb::Monitoring::StatusFlag::Status_ARRAYSIZE] = {};
- TStackVec<std::pair<ui32, int>> failedRealms;
- int failedDisks = 0;
- for (const auto& protoVDiskId : groupInfo.vdiskids()) {
- TString vDiskId = GetVDiskId(protoVDiskId);
- auto itVDisk = MergedVDiskState.find(vDiskId);
- const TEvInterconnect::TNodeInfo* nodeInfo = nullptr;
- if (itVDisk != MergedVDiskState.end()) {
- TNodeId nodeId = itVDisk->second->nodeid();
- auto itNodeInfo = MergedNodeInfo.find(nodeId);
- if (itNodeInfo != MergedNodeInfo.end()) {
- nodeInfo = itNodeInfo->second;
- }
- context.Location.mutable_storage()->mutable_node()->set_id(nodeId);
- } else {
- context.Location.mutable_storage()->mutable_node()->clear_id();
- }
- if (nodeInfo) {
- context.Location.mutable_storage()->mutable_node()->set_host(nodeInfo->Host);
- context.Location.mutable_storage()->mutable_node()->set_port(nodeInfo->Port);
- } else {
- context.Location.mutable_storage()->mutable_node()->clear_host();
- context.Location.mutable_storage()->mutable_node()->clear_port();
- }
- Ydb::Monitoring::StorageVDiskStatus& vDiskStatus = *storageGroupStatus.add_vdisks();
- FillVDiskStatus(vDiskId, itVDisk != MergedVDiskState.end() ? *itVDisk->second : NKikimrWhiteboard::TVDiskStateInfo(), vDiskStatus, {&context, "VDISK"});
- ++disksColors[vDiskStatus.overall()];
- switch (vDiskStatus.overall()) {
- case Ydb::Monitoring::StatusFlag::BLUE: // disk is good, but not available
- case Ydb::Monitoring::StatusFlag::RED: // disk is bad, probably not available
- case Ydb::Monitoring::StatusFlag::GREY: // the status is absent, the disk is not available
- IncrementFor(failedRealms, protoVDiskId.ring());
- ++failedDisks;
+ }
+ }
+ } else {
+ if (UnavailableStorageNodes.count(pDiskInfo.nodeid()) != 0) {
+ TSelfCheckContext nodeContext(&context, "STORAGE_NODE");
+ nodeContext.Location.mutable_storage()->clear_pool();
+ nodeContext.Location.mutable_storage()->mutable_node()->set_id(pDiskInfo.nodeid());
+ const TEvInterconnect::TNodeInfo* nodeInfo = nullptr;
+ auto itNodeInfo = MergedNodeInfo.find(pDiskInfo.nodeid());
+ if (itNodeInfo != MergedNodeInfo.end()) {
+ nodeInfo = itNodeInfo->second;
+ }
+ if (nodeInfo) {
+ nodeContext.Location.mutable_storage()->mutable_node()->set_host(nodeInfo->Host);
+ nodeContext.Location.mutable_storage()->mutable_node()->set_port(nodeInfo->Port);
+ }
+ nodeContext.ReportStatus(Ydb::Monitoring::StatusFlag::RED,
+ TStringBuilder() << "Storage node is not available",
+ "node-state");
+ }
+ context.ReportStatus(Ydb::Monitoring::StatusFlag::RED,
+ TStringBuilder() << "PDisk is not available",
+ "pdisk-state",
+ {"node-state"});
+ }
+
+ storagePDiskStatus.set_overall(context.GetOverallStatus());
+ }
+
+ static Ydb::Monitoring::StatusFlag::Status GetFlagFromWhiteboardFlag(NKikimrWhiteboard::EFlag flag) {
+ switch (flag) {
+ case NKikimrWhiteboard::EFlag::Green:
+ return Ydb::Monitoring::StatusFlag::GREEN;
+ case NKikimrWhiteboard::EFlag::Yellow:
+ return Ydb::Monitoring::StatusFlag::YELLOW;
+ case NKikimrWhiteboard::EFlag::Orange:
+ return Ydb::Monitoring::StatusFlag::ORANGE;
+ case NKikimrWhiteboard::EFlag::Red:
+ return Ydb::Monitoring::StatusFlag::RED;
+ default:
+ return Ydb::Monitoring::StatusFlag::UNSPECIFIED;
+ }
+ }
+
+ void FillVDiskStatus(const TString& vDiskId, const NKikimrWhiteboard::TVDiskStateInfo& vDiskInfo, Ydb::Monitoring::StorageVDiskStatus& storageVDiskStatus, TSelfCheckContext context) {
+ context.Location.mutable_storage()->mutable_pool()->mutable_group()->mutable_vdisk()->set_id(vDiskId);
+ storageVDiskStatus.set_id(vDiskId);
+ TString pDiskId = GetPDiskId(vDiskInfo);
+ auto itPDisk = MergedPDiskState.find(pDiskId);
+ if (itPDisk != MergedPDiskState.end()) {
+ FillPDiskStatus(pDiskId, *itPDisk->second, *storageVDiskStatus.mutable_pdisk(), {&context, "PDISK"});
+ }
+
+ if (!vDiskInfo.HasVDiskState()) {
+ context.ReportStatus(Ydb::Monitoring::StatusFlag::RED,
+ TStringBuilder() << "VDisk is not available",
+ "vdisk-state",
+ {"pdisk-state"});
+ storageVDiskStatus.set_overall(context.GetOverallStatus());
+ return;
+ }
+
+ switch (vDiskInfo.GetVDiskState()) {
+ case NKikimrWhiteboard::EVDiskState::OK:
+ context.ReportStatus(Ydb::Monitoring::StatusFlag::GREEN);
+ break;
+ case NKikimrWhiteboard::EVDiskState::Initial:
+ case NKikimrWhiteboard::EVDiskState::SyncGuidRecovery:
+ context.ReportStatus(Ydb::Monitoring::StatusFlag::YELLOW,
+ TStringBuilder() << "VDisk state is " << NKikimrWhiteboard::EVDiskState_Name(vDiskInfo.GetVDiskState()),
+ "vdisk-state");
+ break;
+ case NKikimrWhiteboard::EVDiskState::LocalRecoveryError:
+ case NKikimrWhiteboard::EVDiskState::SyncGuidRecoveryError:
+ case NKikimrWhiteboard::EVDiskState::PDiskError:
+ context.ReportStatus(Ydb::Monitoring::StatusFlag::RED,
+ TStringBuilder() << "VDisk state is " << NKikimrWhiteboard::EVDiskState_Name(vDiskInfo.GetVDiskState()),
+ "vdisk-state",
+ {"pdisk-state"});
+ break;
+ }
+
+ if (vDiskInfo.HasDiskSpace()) {
+ switch(vDiskInfo.GetDiskSpace()) {
+ case NKikimrWhiteboard::EFlag::Green:
+ context.ReportStatus(Ydb::Monitoring::StatusFlag::GREEN);
+ break;
+ case NKikimrWhiteboard::EFlag::Red:
+ break;
+ context.ReportStatus(GetFlagFromWhiteboardFlag(vDiskInfo.GetDiskSpace()),
+ TStringBuilder() << "DiskSpace is " << NKikimrWhiteboard::EFlag_Name(vDiskInfo.GetDiskSpace()),
+ "vdisk-state",
+ {"pdisk-space"});
+ default:
+ context.ReportStatus(GetFlagFromWhiteboardFlag(vDiskInfo.GetDiskSpace()),
+ TStringBuilder() << "DiskSpace is " << NKikimrWhiteboard::EFlag_Name(vDiskInfo.GetDiskSpace()),
+ "vdisk-space",
+ {"pdisk-space"});
+ break;
+ }
+ }
+
+ if (context.GetOverallStatus() == Ydb::Monitoring::StatusFlag::GREEN && !vDiskInfo.GetReplicated()) {
+ context.ReportStatus(Ydb::Monitoring::StatusFlag::BLUE, "Replication in progress", "vdisk-state");
+ }
+
+ storageVDiskStatus.set_overall(context.GetOverallStatus());
+ }
+
+ static const inline TString NONE = "none";
+ static const inline TString BLOCK_4_2 = "block-4-2";
+ static const inline TString MIRROR_3_DC = "mirror-3-dc";
+
+ static void IncrementFor(TStackVec<std::pair<ui32, int>>& realms, ui32 realm) {
+ auto itRealm = FindIf(realms, [realm](const std::pair<ui32, int>& p) -> bool {
+ return p.first == realm;
+ });
+ if (itRealm == realms.end()) {
+ itRealm = realms.insert(realms.end(), { realm, 1 });
+ } else {
+ itRealm->second++;
+ }
+ }
+
+ void FillGroupStatus(TGroupId groupId, const NKikimrWhiteboard::TBSGroupStateInfo& groupInfo, Ydb::Monitoring::StorageGroupStatus& storageGroupStatus, TSelfCheckContext context) {
+ context.Location.mutable_storage()->mutable_pool()->mutable_group()->set_id(ToString(groupId));
+ storageGroupStatus.set_id(ToString(groupId));
+ int disksColors[Ydb::Monitoring::StatusFlag::Status_ARRAYSIZE] = {};
+ TStackVec<std::pair<ui32, int>> failedRealms;
+ int failedDisks = 0;
+ for (const auto& protoVDiskId : groupInfo.vdiskids()) {
+ TString vDiskId = GetVDiskId(protoVDiskId);
+ auto itVDisk = MergedVDiskState.find(vDiskId);
+ const TEvInterconnect::TNodeInfo* nodeInfo = nullptr;
+ if (itVDisk != MergedVDiskState.end()) {
+ TNodeId nodeId = itVDisk->second->nodeid();
+ auto itNodeInfo = MergedNodeInfo.find(nodeId);
+ if (itNodeInfo != MergedNodeInfo.end()) {
+ nodeInfo = itNodeInfo->second;
+ }
+ context.Location.mutable_storage()->mutable_node()->set_id(nodeId);
+ } else {
+ context.Location.mutable_storage()->mutable_node()->clear_id();
+ }
+ if (nodeInfo) {
+ context.Location.mutable_storage()->mutable_node()->set_host(nodeInfo->Host);
+ context.Location.mutable_storage()->mutable_node()->set_port(nodeInfo->Port);
+ } else {
+ context.Location.mutable_storage()->mutable_node()->clear_host();
+ context.Location.mutable_storage()->mutable_node()->clear_port();
+ }
+ Ydb::Monitoring::StorageVDiskStatus& vDiskStatus = *storageGroupStatus.add_vdisks();
+ FillVDiskStatus(vDiskId, itVDisk != MergedVDiskState.end() ? *itVDisk->second : NKikimrWhiteboard::TVDiskStateInfo(), vDiskStatus, {&context, "VDISK"});
+ ++disksColors[vDiskStatus.overall()];
+ switch (vDiskStatus.overall()) {
+ case Ydb::Monitoring::StatusFlag::BLUE: // disk is good, but not available
+ case Ydb::Monitoring::StatusFlag::RED: // disk is bad, probably not available
+ case Ydb::Monitoring::StatusFlag::GREY: // the status is absent, the disk is not available
+ IncrementFor(failedRealms, protoVDiskId.ring());
+ ++failedDisks;
+ break;
+ default:
+ break;
+ }
+ }
+
+ context.Location.mutable_storage()->clear_node(); // group doesn't have node
+ context.OverallStatus = MinStatus(context.OverallStatus, Ydb::Monitoring::StatusFlag::YELLOW);
+
+ if (groupInfo.erasurespecies() == NONE) {
+ if (failedDisks > 0) {
+ context.ReportStatus(Ydb::Monitoring::StatusFlag::RED, "Group failed", "group-state", {"vdisk-state"});
+ }
+ } else if (groupInfo.erasurespecies() == BLOCK_4_2) {
+ if (failedDisks > 2) {
+ context.ReportStatus(Ydb::Monitoring::StatusFlag::RED, "Group failed", "group-state", {"vdisk-state"});
+ } else if (failedDisks > 1) {
+ context.ReportStatus(Ydb::Monitoring::StatusFlag::ORANGE, "Group has no redundancy", "group-state", {"vdisk-state"});
+ } else if (failedDisks > 0) {
+ if (disksColors[Ydb::Monitoring::StatusFlag::BLUE] == failedDisks) {
+ context.ReportStatus(Ydb::Monitoring::StatusFlag::BLUE, "Group degraded", "group-state", {"vdisk-state"});
+ } else {
+ context.ReportStatus(Ydb::Monitoring::StatusFlag::YELLOW, "Group degraded", "group-state", {"vdisk-state"});
+ }
+ }
+ } else if (groupInfo.erasurespecies() == MIRROR_3_DC) {
+ if (failedRealms.size() > 2 || (failedRealms.size() == 2 && failedRealms[0].second > 1 && failedRealms[1].second > 1)) {
+ context.ReportStatus(Ydb::Monitoring::StatusFlag::RED, "Group failed", "group-state", {"vdisk-state"});
+ } else if (failedRealms.size() == 2) {
+ context.ReportStatus(Ydb::Monitoring::StatusFlag::ORANGE, "Group has no redundancy", "group-state", {"vdisk-state"});
+ } else if (failedDisks > 0) {
+ if (disksColors[Ydb::Monitoring::StatusFlag::BLUE] == failedDisks) {
+ context.ReportStatus(Ydb::Monitoring::StatusFlag::BLUE, "Group degraded", "group-state", {"vdisk-state"});
+ } else {
+ context.ReportStatus(Ydb::Monitoring::StatusFlag::YELLOW, "Group degraded", "group-state", {"vdisk-state"});
+ }
+ }
+ }
+
+ storageGroupStatus.set_overall(context.GetOverallStatus());
+ }
+
+ void FillPoolStatus(const TString& poolName, const TStoragePoolState& pool, Ydb::Monitoring::StoragePoolStatus& storagePoolStatus, TSelfCheckContext context) {
+ context.Location.mutable_storage()->mutable_pool()->set_name(poolName);
+ storagePoolStatus.set_id(poolName);
+ for (auto groupId : pool.Groups) {
+ auto itGroup = MergedBSGroupState.find(groupId);
+ if (itGroup != MergedBSGroupState.end()) {
+ FillGroupStatus(groupId, *itGroup->second, *storagePoolStatus.add_groups(), {&context, "STORAGE_GROUP"});
+ }
+ }
+ switch (context.GetOverallStatus()) {
+ case Ydb::Monitoring::StatusFlag::BLUE:
+ case Ydb::Monitoring::StatusFlag::YELLOW:
+ context.ReportStatus(context.GetOverallStatus(), "Pool degraded", "pool-state", {"group-state"});
+ break;
+ case Ydb::Monitoring::StatusFlag::ORANGE:
+ context.ReportStatus(context.GetOverallStatus(), "Pool has no redundancy", "pool-state", {"group-state"});
+ break;
+ case Ydb::Monitoring::StatusFlag::RED:
+ context.ReportStatus(context.GetOverallStatus(), "Pool failed", "pool-state", {"group-state"});
+ break;
+ default:
break;
- default:
- break;
- }
- }
-
- context.Location.mutable_storage()->clear_node(); // group doesn't have node
- context.OverallStatus = MinStatus(context.OverallStatus, Ydb::Monitoring::StatusFlag::YELLOW);
-
- if (groupInfo.erasurespecies() == NONE) {
- if (failedDisks > 0) {
- context.ReportStatus(Ydb::Monitoring::StatusFlag::RED, "Group failed", "group-state", {"vdisk-state"});
- }
- } else if (groupInfo.erasurespecies() == BLOCK_4_2) {
- if (failedDisks > 2) {
- context.ReportStatus(Ydb::Monitoring::StatusFlag::RED, "Group failed", "group-state", {"vdisk-state"});
- } else if (failedDisks > 1) {
- context.ReportStatus(Ydb::Monitoring::StatusFlag::ORANGE, "Group has no redundancy", "group-state", {"vdisk-state"});
- } else if (failedDisks > 0) {
- if (disksColors[Ydb::Monitoring::StatusFlag::BLUE] == failedDisks) {
- context.ReportStatus(Ydb::Monitoring::StatusFlag::BLUE, "Group degraded", "group-state", {"vdisk-state"});
- } else {
- context.ReportStatus(Ydb::Monitoring::StatusFlag::YELLOW, "Group degraded", "group-state", {"vdisk-state"});
- }
- }
- } else if (groupInfo.erasurespecies() == MIRROR_3_DC) {
- if (failedRealms.size() > 2 || (failedRealms.size() == 2 && failedRealms[0].second > 1 && failedRealms[1].second > 1)) {
- context.ReportStatus(Ydb::Monitoring::StatusFlag::RED, "Group failed", "group-state", {"vdisk-state"});
- } else if (failedRealms.size() == 2) {
- context.ReportStatus(Ydb::Monitoring::StatusFlag::ORANGE, "Group has no redundancy", "group-state", {"vdisk-state"});
- } else if (failedDisks > 0) {
- if (disksColors[Ydb::Monitoring::StatusFlag::BLUE] == failedDisks) {
- context.ReportStatus(Ydb::Monitoring::StatusFlag::BLUE, "Group degraded", "group-state", {"vdisk-state"});
- } else {
- context.ReportStatus(Ydb::Monitoring::StatusFlag::YELLOW, "Group degraded", "group-state", {"vdisk-state"});
- }
- }
- }
-
- storageGroupStatus.set_overall(context.GetOverallStatus());
- }
-
- void FillPoolStatus(const TString& poolName, const TStoragePoolState& pool, Ydb::Monitoring::StoragePoolStatus& storagePoolStatus, TSelfCheckContext context) {
- context.Location.mutable_storage()->mutable_pool()->set_name(poolName);
- storagePoolStatus.set_id(poolName);
- for (auto groupId : pool.Groups) {
- auto itGroup = MergedBSGroupState.find(groupId);
- if (itGroup != MergedBSGroupState.end()) {
- FillGroupStatus(groupId, *itGroup->second, *storagePoolStatus.add_groups(), {&context, "STORAGE_GROUP"});
- }
- }
- switch (context.GetOverallStatus()) {
- case Ydb::Monitoring::StatusFlag::BLUE:
- case Ydb::Monitoring::StatusFlag::YELLOW:
- context.ReportStatus(context.GetOverallStatus(), "Pool degraded", "pool-state", {"group-state"});
- break;
- case Ydb::Monitoring::StatusFlag::ORANGE:
- context.ReportStatus(context.GetOverallStatus(), "Pool has no redundancy", "pool-state", {"group-state"});
- break;
- case Ydb::Monitoring::StatusFlag::RED:
- context.ReportStatus(context.GetOverallStatus(), "Pool failed", "pool-state", {"group-state"});
- break;
- default:
- break;
- }
- storagePoolStatus.set_overall(context.GetOverallStatus());
- }
-
- void FillStorage(TDatabaseState& databaseState, Ydb::Monitoring::StorageStatus& storageStatus, TSelfCheckContext context) {
- if (databaseState.StoragePoolNames.empty()) {
- // pointless in real life
- // context.ReportStatus(Ydb::Monitoring::StatusFlag::RED, "There are no storage pools");
- } else {
- for (const TString& poolName : databaseState.StoragePoolNames) {
- auto itStoragePoolState = StoragePoolState.find(poolName);
- if (itStoragePoolState != StoragePoolState.end()) {
- if (!itStoragePoolState->second.AuthenticGroups.empty()) {
- itStoragePoolState->second.Groups = itStoragePoolState->second.AuthenticGroups;
- }
- FillPoolStatus(poolName, itStoragePoolState->second, *storageStatus.add_pools(), {&context, "STORAGE_POOL"});
- StoragePoolSeen.emplace(poolName);
- }
- }
- switch (context.GetOverallStatus()) {
- case Ydb::Monitoring::StatusFlag::BLUE:
- case Ydb::Monitoring::StatusFlag::YELLOW:
- context.ReportStatus(context.GetOverallStatus(), "Storage degraded", "storage-state", {"pool-state"});
- break;
- case Ydb::Monitoring::StatusFlag::ORANGE:
- context.ReportStatus(context.GetOverallStatus(), "Storage has no redundancy", "storage-state", {"pool-state"});
- break;
- case Ydb::Monitoring::StatusFlag::RED:
- context.ReportStatus(context.GetOverallStatus(), "Storage failed", "storage-state", {"pool-state"});
- break;
- default:
- break;
- }
- }
- storageStatus.set_overall(context.GetOverallStatus());
- }
-
- void FillResult(Ydb::Monitoring::SelfCheckResult& result) {
- Ydb::Monitoring::StatusFlag::Status overall = Ydb::Monitoring::StatusFlag::GREY;
- std::unordered_set<std::pair<TString, TString>> issueIds;
- for (auto& [path, state] : DatabaseState) {
- Ydb::Monitoring::DatabaseStatus& databaseStatus(*result.add_database_status());
- TSelfCheckResult context;
- context.Type = "DATABASE";
- context.Location.mutable_database()->set_name(path);
- databaseStatus.set_name(path);
- FillCompute(state, *databaseStatus.mutable_compute(), {&context, "COMPUTE"});
- FillStorage(state, *databaseStatus.mutable_storage(), {&context, "STORAGE"});
- if (databaseStatus.compute().overall() != Ydb::Monitoring::StatusFlag::GREEN
- && databaseStatus.storage().overall() != Ydb::Monitoring::StatusFlag::GREEN) {
- context.ReportStatus(MaxStatus(databaseStatus.compute().overall(), databaseStatus.storage().overall()),
- "Database has multiple issues", "database-state", {"compute-state", "storage-state"});
- } else if (databaseStatus.compute().overall() != Ydb::Monitoring::StatusFlag::GREEN) {
- context.ReportStatus(databaseStatus.compute().overall(), "Database has compute issues", "database-state", {"compute-state"});
- } else if (databaseStatus.storage().overall() != Ydb::Monitoring::StatusFlag::GREEN) {
- context.ReportStatus(databaseStatus.storage().overall(), "Database has storage issues", "database-state", {"storage-state"});
- }
- databaseStatus.set_overall(context.GetOverallStatus());
- overall = MaxStatus(overall, context.GetOverallStatus());
- for (auto& issueRecord : context.IssueLog) {
- std::pair<TString, TString> key{issueRecord.IssueLog.location().database().name(), issueRecord.IssueLog.id()};
- if (issueIds.emplace(key).second) {
- result.mutable_issue_log()->Add()->CopyFrom(issueRecord.IssueLog);
- }
- }
- }
- if (DatabaseState.empty()) {
- Ydb::Monitoring::DatabaseStatus& databaseStatus(*result.add_database_status());
- TSelfCheckResult context;
- context.Location.mutable_database()->set_name(DomainPath);
- databaseStatus.set_name(DomainPath);
- {
- FillSystemTablets({&context, "SYSTEM_TABLET"});
- overall = MaxStatus(overall, context.GetOverallStatus());
- }
- }
- if (!FilterDatabase) {
- TDatabaseState unknownDatabase;
- for (auto& [name, pool] : StoragePoolState) {
- if (StoragePoolSeen.count(name) == 0) {
- unknownDatabase.StoragePoolNames.push_back(name);
- }
- }
- if (!unknownDatabase.StoragePoolNames.empty()) {
- Ydb::Monitoring::DatabaseStatus& databaseStatus(*result.add_database_status());
- TSelfCheckResult context;
- FillStorage(unknownDatabase, *databaseStatus.mutable_storage(), {&context, "STORAGE"});
- databaseStatus.set_overall(context.GetOverallStatus());
- overall = MaxStatus(overall, context.GetOverallStatus());
- for (auto& issueRecord : context.IssueLog) {
- std::pair<TString, TString> key{issueRecord.IssueLog.location().database().name(), issueRecord.IssueLog.id()};
- if (issueIds.emplace(key).second) {
- result.mutable_issue_log()->Add()->CopyFrom(issueRecord.IssueLog);
- }
- }
- }
- }
- switch (overall) {
- case Ydb::Monitoring::StatusFlag::GREEN:
- case Ydb::Monitoring::StatusFlag::YELLOW:
- result.set_self_check_result(Ydb::Monitoring::SelfCheck::GOOD);
- break;
- case Ydb::Monitoring::StatusFlag::BLUE:
- result.set_self_check_result(Ydb::Monitoring::SelfCheck::DEGRADED);
- break;
- case Ydb::Monitoring::StatusFlag::ORANGE:
- result.set_self_check_result(Ydb::Monitoring::SelfCheck::MAINTENANCE_REQUIRED);
- break;
- case Ydb::Monitoring::StatusFlag::RED:
- result.set_self_check_result(Ydb::Monitoring::SelfCheck::EMERGENCY);
- break;
- default:
- break;
- }
- }
-
- void ReplyAndPassAway() {
- THolder<TEvSelfCheckResult> response = MakeHolder<TEvSelfCheckResult>();
- Ydb::Monitoring::SelfCheckResult& result = response->Result;
-
- AggregateHiveInfo();
- AggregateHiveNodeStats();
- AggregateBSControllerState();
-
- for (auto& [requestId, request] : TabletRequests.RequestsInFlight) {
- auto tabletId = request.TabletId;
- TabletRequests.TabletStates[tabletId].IsUnresponsive = true;
- }
-
- FillResult(result);
-
- if (!Request->Request.return_verbose_status()) {
- result.clear_database_status();
- }
- if (Request->Request.minimum_status() != Ydb::Monitoring::StatusFlag::UNSPECIFIED) {
- for (auto itIssue = result.mutable_issue_log()->begin(); itIssue != result.mutable_issue_log()->end();) {
- if (itIssue->status() < Request->Request.minimum_status()) {
- itIssue = result.mutable_issue_log()->erase(itIssue);
- } else {
- ++itIssue;
- }
- }
- }
- if (Request->Request.maximum_level() != 0) {
- for (auto itIssue = result.mutable_issue_log()->begin(); itIssue != result.mutable_issue_log()->end();) {
- if (itIssue->level() > Request->Request.maximum_level()) {
- itIssue = result.mutable_issue_log()->erase(itIssue);
- } else {
- ++itIssue;
- }
- }
- }
-
- for (TActorId pipe : PipeClients) {
- NTabletPipe::CloseClient(SelfId(), pipe);
- }
-
- Send(Sender, response.Release(), 0, Cookie);
-
- for (TNodeId nodeId : NodeIds) {
- Send(TlsActivationContext->ActorSystem()->InterconnectProxy(nodeId), new TEvents::TEvUnsubscribe());
- }
- PassAway();
- }
-};
-
-class THealthCheckService : public TActor<THealthCheckService> {
-public:
- static constexpr NKikimrServices::TActivity::EType ActorActivityType() { return NKikimrServices::TActivity::MONITORING_SERVICE; }
-
- THealthCheckService()
- : TActor<THealthCheckService>(&THealthCheckService::StateWork)
- {
- }
-
- void Handle(TEvSelfCheckRequest::TPtr& ev) {
- RegisterWithSameMailbox(new TSelfCheckRequest(ev->Sender, ev.Get()->Release(), ev->Cookie));
- }
-
- void StateWork(TAutoPtr<NActors::IEventHandle>& ev, const TActorContext&) {
- switch (ev->GetTypeRewrite()) {
- hFunc(TEvSelfCheckRequest, Handle);
- cFunc(TEvents::TSystem::PoisonPill, PassAway);
- }
- }
-};
-
-IActor* CreateHealthCheckService() {
- return new THealthCheckService();
-}
-
-} // namespace NHealthCheck
-} // namespace NKikimr
+ }
+ storagePoolStatus.set_overall(context.GetOverallStatus());
+ }
+
+ void FillStorage(TDatabaseState& databaseState, Ydb::Monitoring::StorageStatus& storageStatus, TSelfCheckContext context) {
+ if (databaseState.StoragePoolNames.empty()) {
+ // pointless in real life
+ // context.ReportStatus(Ydb::Monitoring::StatusFlag::RED, "There are no storage pools");
+ } else {
+ for (const TString& poolName : databaseState.StoragePoolNames) {
+ auto itStoragePoolState = StoragePoolState.find(poolName);
+ if (itStoragePoolState != StoragePoolState.end()) {
+ if (!itStoragePoolState->second.AuthenticGroups.empty()) {
+ itStoragePoolState->second.Groups = itStoragePoolState->second.AuthenticGroups;
+ }
+ FillPoolStatus(poolName, itStoragePoolState->second, *storageStatus.add_pools(), {&context, "STORAGE_POOL"});
+ StoragePoolSeen.emplace(poolName);
+ }
+ }
+ switch (context.GetOverallStatus()) {
+ case Ydb::Monitoring::StatusFlag::BLUE:
+ case Ydb::Monitoring::StatusFlag::YELLOW:
+ context.ReportStatus(context.GetOverallStatus(), "Storage degraded", "storage-state", {"pool-state"});
+ break;
+ case Ydb::Monitoring::StatusFlag::ORANGE:
+ context.ReportStatus(context.GetOverallStatus(), "Storage has no redundancy", "storage-state", {"pool-state"});
+ break;
+ case Ydb::Monitoring::StatusFlag::RED:
+ context.ReportStatus(context.GetOverallStatus(), "Storage failed", "storage-state", {"pool-state"});
+ break;
+ default:
+ break;
+ }
+ }
+ storageStatus.set_overall(context.GetOverallStatus());
+ }
+
+ void FillResult(Ydb::Monitoring::SelfCheckResult& result) {
+ Ydb::Monitoring::StatusFlag::Status overall = Ydb::Monitoring::StatusFlag::GREY;
+ std::unordered_set<std::pair<TString, TString>> issueIds;
+ for (auto& [path, state] : DatabaseState) {
+ Ydb::Monitoring::DatabaseStatus& databaseStatus(*result.add_database_status());
+ TSelfCheckResult context;
+ context.Type = "DATABASE";
+ context.Location.mutable_database()->set_name(path);
+ databaseStatus.set_name(path);
+ FillCompute(state, *databaseStatus.mutable_compute(), {&context, "COMPUTE"});
+ FillStorage(state, *databaseStatus.mutable_storage(), {&context, "STORAGE"});
+ if (databaseStatus.compute().overall() != Ydb::Monitoring::StatusFlag::GREEN
+ && databaseStatus.storage().overall() != Ydb::Monitoring::StatusFlag::GREEN) {
+ context.ReportStatus(MaxStatus(databaseStatus.compute().overall(), databaseStatus.storage().overall()),
+ "Database has multiple issues", "database-state", {"compute-state", "storage-state"});
+ } else if (databaseStatus.compute().overall() != Ydb::Monitoring::StatusFlag::GREEN) {
+ context.ReportStatus(databaseStatus.compute().overall(), "Database has compute issues", "database-state", {"compute-state"});
+ } else if (databaseStatus.storage().overall() != Ydb::Monitoring::StatusFlag::GREEN) {
+ context.ReportStatus(databaseStatus.storage().overall(), "Database has storage issues", "database-state", {"storage-state"});
+ }
+ databaseStatus.set_overall(context.GetOverallStatus());
+ overall = MaxStatus(overall, context.GetOverallStatus());
+ for (auto& issueRecord : context.IssueLog) {
+ std::pair<TString, TString> key{issueRecord.IssueLog.location().database().name(), issueRecord.IssueLog.id()};
+ if (issueIds.emplace(key).second) {
+ result.mutable_issue_log()->Add()->CopyFrom(issueRecord.IssueLog);
+ }
+ }
+ }
+ if (DatabaseState.empty()) {
+ Ydb::Monitoring::DatabaseStatus& databaseStatus(*result.add_database_status());
+ TSelfCheckResult context;
+ context.Location.mutable_database()->set_name(DomainPath);
+ databaseStatus.set_name(DomainPath);
+ {
+ FillSystemTablets({&context, "SYSTEM_TABLET"});
+ overall = MaxStatus(overall, context.GetOverallStatus());
+ }
+ }
+ if (!FilterDatabase) {
+ TDatabaseState unknownDatabase;
+ for (auto& [name, pool] : StoragePoolState) {
+ if (StoragePoolSeen.count(name) == 0) {
+ unknownDatabase.StoragePoolNames.push_back(name);
+ }
+ }
+ if (!unknownDatabase.StoragePoolNames.empty()) {
+ Ydb::Monitoring::DatabaseStatus& databaseStatus(*result.add_database_status());
+ TSelfCheckResult context;
+ FillStorage(unknownDatabase, *databaseStatus.mutable_storage(), {&context, "STORAGE"});
+ databaseStatus.set_overall(context.GetOverallStatus());
+ overall = MaxStatus(overall, context.GetOverallStatus());
+ for (auto& issueRecord : context.IssueLog) {
+ std::pair<TString, TString> key{issueRecord.IssueLog.location().database().name(), issueRecord.IssueLog.id()};
+ if (issueIds.emplace(key).second) {
+ result.mutable_issue_log()->Add()->CopyFrom(issueRecord.IssueLog);
+ }
+ }
+ }
+ }
+ switch (overall) {
+ case Ydb::Monitoring::StatusFlag::GREEN:
+ case Ydb::Monitoring::StatusFlag::YELLOW:
+ result.set_self_check_result(Ydb::Monitoring::SelfCheck::GOOD);
+ break;
+ case Ydb::Monitoring::StatusFlag::BLUE:
+ result.set_self_check_result(Ydb::Monitoring::SelfCheck::DEGRADED);
+ break;
+ case Ydb::Monitoring::StatusFlag::ORANGE:
+ result.set_self_check_result(Ydb::Monitoring::SelfCheck::MAINTENANCE_REQUIRED);
+ break;
+ case Ydb::Monitoring::StatusFlag::RED:
+ result.set_self_check_result(Ydb::Monitoring::SelfCheck::EMERGENCY);
+ break;
+ default:
+ break;
+ }
+ }
+
+ void ReplyAndPassAway() {
+ THolder<TEvSelfCheckResult> response = MakeHolder<TEvSelfCheckResult>();
+ Ydb::Monitoring::SelfCheckResult& result = response->Result;
+
+ AggregateHiveInfo();
+ AggregateHiveNodeStats();
+ AggregateBSControllerState();
+
+ for (auto& [requestId, request] : TabletRequests.RequestsInFlight) {
+ auto tabletId = request.TabletId;
+ TabletRequests.TabletStates[tabletId].IsUnresponsive = true;
+ }
+
+ FillResult(result);
+
+ if (!Request->Request.return_verbose_status()) {
+ result.clear_database_status();
+ }
+ if (Request->Request.minimum_status() != Ydb::Monitoring::StatusFlag::UNSPECIFIED) {
+ for (auto itIssue = result.mutable_issue_log()->begin(); itIssue != result.mutable_issue_log()->end();) {
+ if (itIssue->status() < Request->Request.minimum_status()) {
+ itIssue = result.mutable_issue_log()->erase(itIssue);
+ } else {
+ ++itIssue;
+ }
+ }
+ }
+ if (Request->Request.maximum_level() != 0) {
+ for (auto itIssue = result.mutable_issue_log()->begin(); itIssue != result.mutable_issue_log()->end();) {
+ if (itIssue->level() > Request->Request.maximum_level()) {
+ itIssue = result.mutable_issue_log()->erase(itIssue);
+ } else {
+ ++itIssue;
+ }
+ }
+ }
+
+ for (TActorId pipe : PipeClients) {
+ NTabletPipe::CloseClient(SelfId(), pipe);
+ }
+
+ Send(Sender, response.Release(), 0, Cookie);
+
+ for (TNodeId nodeId : NodeIds) {
+ Send(TlsActivationContext->ActorSystem()->InterconnectProxy(nodeId), new TEvents::TEvUnsubscribe());
+ }
+ PassAway();
+ }
+};
+
+class THealthCheckService : public TActor<THealthCheckService> {
+public:
+ static constexpr NKikimrServices::TActivity::EType ActorActivityType() { return NKikimrServices::TActivity::MONITORING_SERVICE; }
+
+ THealthCheckService()
+ : TActor<THealthCheckService>(&THealthCheckService::StateWork)
+ {
+ }
+
+ void Handle(TEvSelfCheckRequest::TPtr& ev) {
+ RegisterWithSameMailbox(new TSelfCheckRequest(ev->Sender, ev.Get()->Release(), ev->Cookie));
+ }
+
+ void StateWork(TAutoPtr<NActors::IEventHandle>& ev, const TActorContext&) {
+ switch (ev->GetTypeRewrite()) {
+ hFunc(TEvSelfCheckRequest, Handle);
+ cFunc(TEvents::TSystem::PoisonPill, PassAway);
+ }
+ }
+};
+
+IActor* CreateHealthCheckService() {
+ return new THealthCheckService();
+}
+
+} // namespace NHealthCheck
+} // namespace NKikimr
diff --git a/ydb/core/health_check/health_check.h b/ydb/core/health_check/health_check.h
index fc1d225c4eb..5708a4e974a 100644
--- a/ydb/core/health_check/health_check.h
+++ b/ydb/core/health_check/health_check.h
@@ -1,34 +1,34 @@
-#pragma once
-
+#pragma once
+
#include <ydb/public/api/protos/ydb_monitoring.pb.h>
#include <ydb/core/base/events.h>
-
-namespace NKikimr {
-namespace NHealthCheck {
-
-enum EEv {
- // requests
- EvSelfCheckRequest = EventSpaceBegin(TKikimrEvents::ES_HEALTH_CHECK),
-
- // replies
- EvSelfCheckResult = EvSelfCheckRequest + 512,
-
- EvEnd
-};
-
-static_assert(EvEnd < EventSpaceEnd(TKikimrEvents::ES_HEALTH_CHECK), "expect EvEnd < EventSpaceEnd(TKikimrEvents::ES_HEALTH_CHECK)");
-
-struct TEvSelfCheckRequest : TEventLocal<TEvSelfCheckRequest, EvSelfCheckRequest> {
- Ydb::Monitoring::SelfCheckRequest Request;
- TString Database;
-};
-
-struct TEvSelfCheckResult : TEventLocal<TEvSelfCheckResult, EvSelfCheckResult> {
- Ydb::Monitoring::SelfCheckResult Result;
-};
-
-inline NActors::TActorId MakeHealthCheckID() { return NActors::TActorId(0, "healthcheck"); }
-IActor* CreateHealthCheckService();
-
-}
-}
+
+namespace NKikimr {
+namespace NHealthCheck {
+
+enum EEv {
+ // requests
+ EvSelfCheckRequest = EventSpaceBegin(TKikimrEvents::ES_HEALTH_CHECK),
+
+ // replies
+ EvSelfCheckResult = EvSelfCheckRequest + 512,
+
+ EvEnd
+};
+
+static_assert(EvEnd < EventSpaceEnd(TKikimrEvents::ES_HEALTH_CHECK), "expect EvEnd < EventSpaceEnd(TKikimrEvents::ES_HEALTH_CHECK)");
+
+struct TEvSelfCheckRequest : TEventLocal<TEvSelfCheckRequest, EvSelfCheckRequest> {
+ Ydb::Monitoring::SelfCheckRequest Request;
+ TString Database;
+};
+
+struct TEvSelfCheckResult : TEventLocal<TEvSelfCheckResult, EvSelfCheckResult> {
+ Ydb::Monitoring::SelfCheckResult Result;
+};
+
+inline NActors::TActorId MakeHealthCheckID() { return NActors::TActorId(0, "healthcheck"); }
+IActor* CreateHealthCheckService();
+
+}
+}
diff --git a/ydb/core/health_check/health_check_ut.cpp b/ydb/core/health_check/health_check_ut.cpp
index 1910e48ff2d..0972b3b707a 100644
--- a/ydb/core/health_check/health_check_ut.cpp
+++ b/ydb/core/health_check/health_check_ut.cpp
@@ -1,35 +1,35 @@
-#include <library/cpp/testing/unittest/registar.h>
-#include <library/cpp/testing/unittest/tests_data.h>
+#include <library/cpp/testing/unittest/registar.h>
+#include <library/cpp/testing/unittest/tests_data.h>
#include <ydb/core/testlib/test_client.h>
#include <ydb/public/lib/deprecated/kicli/kicli.h>
-
-#include "health_check.h"
-
-using namespace NKikimr;
-using namespace Tests;
-
-Y_UNIT_TEST_SUITE(THealthCheckTest) {
- Y_UNIT_TEST(Basic) {
- TPortManager tp;
- ui16 port = tp.GetPort(2134);
- ui16 grpcPort = tp.GetPort(2135);
-
- auto settings = TServerSettings(port);
- settings.SetDomainName("Root");
- TServer server(settings);
- server.EnableGRpc(grpcPort);
-
- TClient client(settings);
- NClient::TKikimr kikimr(client.GetClientConfig());
- client.InitRootScheme();
-
- TTestActorRuntime* runtime = server.GetRuntime();
- TActorId sender = runtime->AllocateEdgeActor();
- TAutoPtr<IEventHandle> handle;
-
- runtime->Send(new IEventHandle(NHealthCheck::MakeHealthCheckID(), sender, new NHealthCheck::TEvSelfCheckRequest(), 0));
- NHealthCheck::TEvSelfCheckResult* result = runtime->GrabEdgeEvent<NHealthCheck::TEvSelfCheckResult>(handle);
-
- UNIT_ASSERT(result != nullptr);
- }
-}
+
+#include "health_check.h"
+
+using namespace NKikimr;
+using namespace Tests;
+
+Y_UNIT_TEST_SUITE(THealthCheckTest) {
+ Y_UNIT_TEST(Basic) {
+ TPortManager tp;
+ ui16 port = tp.GetPort(2134);
+ ui16 grpcPort = tp.GetPort(2135);
+
+ auto settings = TServerSettings(port);
+ settings.SetDomainName("Root");
+ TServer server(settings);
+ server.EnableGRpc(grpcPort);
+
+ TClient client(settings);
+ NClient::TKikimr kikimr(client.GetClientConfig());
+ client.InitRootScheme();
+
+ TTestActorRuntime* runtime = server.GetRuntime();
+ TActorId sender = runtime->AllocateEdgeActor();
+ TAutoPtr<IEventHandle> handle;
+
+ runtime->Send(new IEventHandle(NHealthCheck::MakeHealthCheckID(), sender, new NHealthCheck::TEvSelfCheckRequest(), 0));
+ NHealthCheck::TEvSelfCheckResult* result = runtime->GrabEdgeEvent<NHealthCheck::TEvSelfCheckResult>(handle);
+
+ UNIT_ASSERT(result != nullptr);
+ }
+}
diff --git a/ydb/core/health_check/ut/ya.make b/ydb/core/health_check/ut/ya.make
index 44a26e9cf0b..7a9484df0ab 100644
--- a/ydb/core/health_check/ut/ya.make
+++ b/ydb/core/health_check/ut/ya.make
@@ -1,19 +1,19 @@
UNITTEST_FOR(ydb/core/health_check)
-OWNER(g:kikimr)
-
-FORK_SUBTESTS()
-
-SIZE(SMALL)
-
-PEERDIR(
+OWNER(g:kikimr)
+
+FORK_SUBTESTS()
+
+SIZE(SMALL)
+
+PEERDIR(
ydb/core/testlib
-)
-
-SRCS(
- health_check_ut.cpp
-)
-
-YQL_LAST_ABI_VERSION()
-
-END()
+)
+
+SRCS(
+ health_check_ut.cpp
+)
+
+YQL_LAST_ABI_VERSION()
+
+END()
diff --git a/ydb/core/health_check/ya.make b/ydb/core/health_check/ya.make
index 732b7460689..864459edb43 100644
--- a/ydb/core/health_check/ya.make
+++ b/ydb/core/health_check/ya.make
@@ -1,25 +1,25 @@
-LIBRARY()
-
-OWNER(
- xenoxeno
- g:kikimr
-)
-
-SRCS(
- health_check.cpp
- health_check.h
-)
-
-PEERDIR(
+LIBRARY()
+
+OWNER(
+ xenoxeno
+ g:kikimr
+)
+
+SRCS(
+ health_check.cpp
+ health_check.h
+)
+
+PEERDIR(
library/cpp/actors/core
ydb/core/base
ydb/core/blobstorage/base
ydb/library/aclib
ydb/public/api/protos
ydb/library/yql/public/issue/protos
-)
-
-END()
+)
+
+END()
RECURSE_FOR_TESTS(
ut
diff --git a/ydb/core/keyvalue/keyvalue_flat_impl.h b/ydb/core/keyvalue/keyvalue_flat_impl.h
index 1dd16073454..292f2feff93 100644
--- a/ydb/core/keyvalue/keyvalue_flat_impl.h
+++ b/ydb/core/keyvalue/keyvalue_flat_impl.h
@@ -75,7 +75,7 @@ protected:
ctx.Send(Self.Tablet(), new TEvents::TEvPoisonPill);
return true;
}
- Self.State.UpdateResourceMetrics(ctx);
+ Self.State.UpdateResourceMetrics(ctx);
}
Self.State.InitExecute(Self.TabletID(), KeyValueActorId, txc.Generation, db, ctx, Self.Info());
LOG_DEBUG_S(ctx, NKikimrServices::KEYVALUE, "KeyValue# " << txc.Tablet
@@ -263,7 +263,7 @@ protected:
void OnActivateExecutor(const TActorContext &ctx) override {
Executor()->RegisterExternalTabletCounters(State.TakeTabletCounters());
- State.SetupResourceMetrics(Executor()->GetResourceMetrics());
+ State.SetupResourceMetrics(Executor()->GetResourceMetrics());
ctx.Schedule(TDuration::MilliSeconds(PeriodicRefreshMs), new TEvKeyValue::TEvPeriodicRefresh);
Execute(new TTxInit(ctx.SelfID, *this), ctx);
}
@@ -487,11 +487,11 @@ public:
HFunc(TEvents::TEvPoisonPill, Handle);
default:
- if (!HandleDefaultEvents(ev, ctx)) {
+ if (!HandleDefaultEvents(ev, ctx)) {
LOG_DEBUG_S(ctx, NKikimrServices::KEYVALUE, "KeyValue# " << TabletID()
<< " StateWork unexpected event type# " << (ui32)ev->GetTypeRewrite()
<< " event# " << (ev->HasEvent() ? ev->GetBase()->ToString().data() : "serialized?"));
- }
+ }
break;
}
}
diff --git a/ydb/core/keyvalue/keyvalue_intermediate.h b/ydb/core/keyvalue/keyvalue_intermediate.h
index 591204def4b..c28c14b9c37 100644
--- a/ydb/core/keyvalue/keyvalue_intermediate.h
+++ b/ydb/core/keyvalue/keyvalue_intermediate.h
@@ -139,7 +139,7 @@ struct TIntermediate {
ui64 TotalSizeLimit;
ui64 TotalReadsScheduled;
ui64 TotalReadsLimit;
- ui64 SequentialReadLimit;
+ ui64 SequentialReadLimit;
bool IsTruncated;
ui64 CreatedAtGeneration;
diff --git a/ydb/core/keyvalue/keyvalue_request_stat.h b/ydb/core/keyvalue/keyvalue_request_stat.h
index b8af2cf9f4f..070ffcbecac 100644
--- a/ydb/core/keyvalue/keyvalue_request_stat.h
+++ b/ydb/core/keyvalue/keyvalue_request_stat.h
@@ -30,8 +30,8 @@ struct TRequestStat {
TInstant LocalBaseTxCreatedAt;
TInstant IntermediateCreatedAt;
TRequestType::EType RequestType;
- NMetrics::TTabletThroughputRawValue GroupReadBytes;
- NMetrics::TTabletThroughputRawValue GroupWrittenBytes;
+ NMetrics::TTabletThroughputRawValue GroupReadBytes;
+ NMetrics::TTabletThroughputRawValue GroupWrittenBytes;
NMetrics::TTabletIopsRawValue GroupReadIops;
NMetrics::TTabletIopsRawValue GroupWrittenIops;
diff --git a/ydb/core/keyvalue/keyvalue_state.cpp b/ydb/core/keyvalue/keyvalue_state.cpp
index 84b4c6011b2..6b31c463f83 100644
--- a/ydb/core/keyvalue/keyvalue_state.cpp
+++ b/ydb/core/keyvalue/keyvalue_state.cpp
@@ -126,14 +126,14 @@ TAutoPtr<TTabletCountersBase> TKeyValueState::TakeTabletCounters() {
return TabletCountersPtr;
}
-TTabletCountersBase& TKeyValueState::GetTabletCounters() {
- return *TabletCounters;
-}
-
-void TKeyValueState::SetupResourceMetrics(NMetrics::TResourceMetrics* resourceMetrics) {
- ResourceMetrics = resourceMetrics;
-}
-
+TTabletCountersBase& TKeyValueState::GetTabletCounters() {
+ return *TabletCounters;
+}
+
+void TKeyValueState::SetupResourceMetrics(NMetrics::TResourceMetrics* resourceMetrics) {
+ ResourceMetrics = resourceMetrics;
+}
+
void TKeyValueState::CountRequestComplete(NMsgBusProxy::EResponseStatus status,
const TRequestStat &stat, const TActorContext &ctx)
{
@@ -179,26 +179,26 @@ void TKeyValueState::CountRequestComplete(NMsgBusProxy::EResponseStatus status,
}
}
- TInstant now(ctx.Now());
- ResourceMetrics->Network.Increment(stat.ReadBytes + stat.RangeReadBytes + stat.WriteBytes, now);
+ TInstant now(ctx.Now());
+ ResourceMetrics->Network.Increment(stat.ReadBytes + stat.RangeReadBytes + stat.WriteBytes, now);
constexpr ui64 MaxStatChannels = 16;
- for (const auto& pr : stat.GroupReadBytes) {
- ResourceMetrics->ReadThroughput[pr.first].Increment(pr.second, now);
+ for (const auto& pr : stat.GroupReadBytes) {
+ ResourceMetrics->ReadThroughput[pr.first].Increment(pr.second, now);
NMetrics::TChannel channel = pr.first.first;
if (channel >= MaxStatChannels) {
channel = MaxStatChannels - 1;
}
TabletCounters->Cumulative()[COUNTER_READ_BYTES_CHANNEL_0 + channel].Increment(pr.second);
- }
- for (const auto& pr : stat.GroupWrittenBytes) {
- ResourceMetrics->WriteThroughput[pr.first].Increment(pr.second, now);
+ }
+ for (const auto& pr : stat.GroupWrittenBytes) {
+ ResourceMetrics->WriteThroughput[pr.first].Increment(pr.second, now);
NMetrics::TChannel channel = pr.first.first;
if (channel >= MaxStatChannels) {
channel = MaxStatChannels - 1;
}
TabletCounters->Cumulative()[COUNTER_WRITE_BYTES_CHANNEL_0 + channel].Increment(pr.second);
- }
+ }
for (const auto& pr : stat.GroupReadIops) {
ResourceMetrics->ReadIops[pr.first].Increment(pr.second, now);
}
@@ -297,13 +297,13 @@ void TKeyValueState::CountTrashRecord(ui32 sizeBytes) {
TabletCounters->Simple()[COUNTER_TRASH_BYTES].Add((ui64)sizeBytes);
TabletCounters->Simple()[COUNTER_RECORD_COUNT].Add((ui64)-1);
TabletCounters->Simple()[COUNTER_RECORD_BYTES].Add((ui64)-(i64)sizeBytes);
- ResourceMetrics->StorageUser.Set(TabletCounters->Simple()[COUNTER_RECORD_BYTES].Get());
+ ResourceMetrics->StorageUser.Set(TabletCounters->Simple()[COUNTER_RECORD_BYTES].Get());
}
void TKeyValueState::CountWriteRecord(ui8 channel, ui32 sizeBytes) {
TabletCounters->Simple()[COUNTER_RECORD_COUNT].Add(1);
TabletCounters->Simple()[COUNTER_RECORD_BYTES].Add(sizeBytes);
- ResourceMetrics->StorageUser.Set(TabletCounters->Simple()[COUNTER_RECORD_BYTES].Get());
+ ResourceMetrics->StorageUser.Set(TabletCounters->Simple()[COUNTER_RECORD_BYTES].Get());
Y_VERIFY(channel < ChannelDataUsage.size());
ChannelDataUsage[channel] += sizeBytes;
}
@@ -1233,7 +1233,7 @@ void TKeyValueState::CmdWrite(THolder<TIntermediate> &intermediate, ISimpleDb &d
auto *response = intermediate->Response.AddWriteResult();
ProcessCmd(request, response, nullptr, db, ctx, intermediate->Stat, unixTime);
}
- ResourceMetrics->TryUpdate(ctx);
+ ResourceMetrics->TryUpdate(ctx);
}
void TKeyValueState::CmdGetStatus(THolder<TIntermediate> &intermediate, ISimpleDb &db, const TActorContext &ctx) {
@@ -1685,8 +1685,8 @@ void TKeyValueState::OnRequestComplete(ui64 requestUid, ui64 generation, ui64 st
}
}
- CountRequestComplete(status, stat, ctx);
- ResourceMetrics->TryUpdate(ctx);
+ CountRequestComplete(status, stat, ctx);
+ ResourceMetrics->TryUpdate(ctx);
if (Queue.size() && IntermediatesInFlight < IntermediatesInFlightLimit) {
TRequestType::EType requestType = Queue.front()->Stat.RequestType;
@@ -2545,7 +2545,7 @@ void TKeyValueState::ReplyError(const TActorContext &ctx, TString errorDescripti
response->Record.SetErrorReason(errorDescription);
response->Record.SetStatus(status);
- ResourceMetrics->Network.Increment(response->Record.ByteSize());
+ ResourceMetrics->Network.Increment(response->Record.ByteSize());
intermediate->IsReplied = true;
ctx.Send(intermediate->RespondTo, response.Release());
@@ -2987,8 +2987,8 @@ void TKeyValueState::OnEvRequest(TEvKeyValue::TEvRequest::TPtr &ev, const TActor
THolder<TIntermediate> intermediate;
NKikimrClient::TKeyValueRequest &request = ev->Get()->Record;
- ResourceMetrics->Network.Increment(request.ByteSize());
- ResourceMetrics->TryUpdate(ctx);
+ ResourceMetrics->Network.Increment(request.ByteSize());
+ ResourceMetrics->TryUpdate(ctx);
bool hasWrites = request.CmdWriteSize() || request.CmdDeleteRangeSize() || request.CmdRenameSize()
|| request.CmdCopyRangeSize() || request.CmdConcatSize() || request.HasCmdSetExecutorFastLogPolicy();
@@ -3127,10 +3127,10 @@ bool TKeyValueState::PrepareIntermediate(TEvKeyValue::TEvRequest::TPtr &ev, THol
return true;
}
-void TKeyValueState::UpdateResourceMetrics(const TActorContext& ctx) {
- ResourceMetrics->TryUpdate(ctx);
-}
-
+void TKeyValueState::UpdateResourceMetrics(const TActorContext& ctx) {
+ ResourceMetrics->TryUpdate(ctx);
+}
+
bool TKeyValueState::ConvertRange(const NKikimrClient::TKeyValueRequest::TKeyRange& from, TKeyRange *to,
const TActorContext& ctx, THolder<TIntermediate>& intermediate, const char *cmd,
ui32 index) {
diff --git a/ydb/core/keyvalue/keyvalue_state.h b/ydb/core/keyvalue/keyvalue_state.h
index a387d95f111..f57a69d35d3 100644
--- a/ydb/core/keyvalue/keyvalue_state.h
+++ b/ydb/core/keyvalue/keyvalue_state.h
@@ -281,17 +281,17 @@ protected:
ui32 PerGenerationCounter; // for garbage collection
- NMetrics::TResourceMetrics* ResourceMetrics;
-
+ NMetrics::TResourceMetrics* ResourceMetrics;
+
public:
TKeyValueState();
void Clear();
void SetupTabletCounters(TAutoPtr<TTabletCountersBase> counters);
void ClearTabletCounters();
TAutoPtr<TTabletCountersBase> TakeTabletCounters();
- TTabletCountersBase& GetTabletCounters();
- void SetupResourceMetrics(NMetrics::TResourceMetrics* metrics);
- void CountRequestComplete(NMsgBusProxy::EResponseStatus status, const TRequestStat &stat, const TActorContext &ctx);
+ TTabletCountersBase& GetTabletCounters();
+ void SetupResourceMetrics(NMetrics::TResourceMetrics* metrics);
+ void CountRequestComplete(NMsgBusProxy::EResponseStatus status, const TRequestStat &stat, const TActorContext &ctx);
void CountRequestTakeOffOrEnqueue(TRequestType::EType requestType);
void CountRequestOtherError(TRequestType::EType requestType);
void CountRequestIncoming(TRequestType::EType requestType);
@@ -674,16 +674,16 @@ public:
callback(it);
}
}
- void UpdateResourceMetrics(const TActorContext& ctx);
-
+ void UpdateResourceMetrics(const TActorContext& ctx);
+
bool GetIsDamaged() const {
return IsDamaged;
- }
-
+ }
+
bool GetIsTabletYellowMove() const {
return IsTabletYellowMove;
}
-
+
bool GetIsTabletYellowStop() const {
return IsTabletYellowStop;
}
diff --git a/ydb/core/keyvalue/keyvalue_storage_request.cpp b/ydb/core/keyvalue/keyvalue_storage_request.cpp
index a6a070c6119..e9032d2ed3d 100644
--- a/ydb/core/keyvalue/keyvalue_storage_request.cpp
+++ b/ydb/core/keyvalue/keyvalue_storage_request.cpp
@@ -159,7 +159,7 @@ public:
wr->StatusFlags.Merge(ev->Get()->StatusFlags.Raw);
wr->Latency = duration;
++WriteRequestsReplied;
- IntermediateResults->Stat.GroupWrittenBytes[std::make_pair(ev->Get()->Id.Channel(), groupId)] += ev->Get()->Id.BlobSize();
+ IntermediateResults->Stat.GroupWrittenBytes[std::make_pair(ev->Get()->Id.Channel(), groupId)] += ev->Get()->Id.BlobSize();
IntermediateResults->Stat.GroupWrittenIops[std::make_pair(ev->Get()->Id.Channel(), groupId)] += 1; // FIXME: count distinct blobs?
UpdateRequest(ctx);
}
@@ -275,7 +275,7 @@ public:
}
Y_VERIFY(ev->Get()->ResponseSz == request.ReadQueue.size());
- auto groupId = ev->Get()->GroupId;
+ auto groupId = ev->Get()->GroupId;
decltype(request.ReadQueue)::iterator it = request.ReadQueue.begin();
for (ui32 i = 0, num = ev->Get()->ResponseSz; i < num; ++i, ++it) {
const auto& response = ev->Get()->Responses[i];
@@ -289,7 +289,7 @@ public:
Y_VERIFY(response.Buffer.size() == readItem.BlobSize);
Y_VERIFY(readItem.ValueOffset + readItem.BlobSize <= read.ValueSize);
memcpy(const_cast<char *>(read.Value.data()) + readItem.ValueOffset, response.Buffer.data(), response.Buffer.size());
- IntermediateResults->Stat.GroupReadBytes[std::make_pair(response.Id.Channel(), groupId)] += response.Buffer.size();
+ IntermediateResults->Stat.GroupReadBytes[std::make_pair(response.Id.Channel(), groupId)] += response.Buffer.size();
IntermediateResults->Stat.GroupReadIops[std::make_pair(response.Id.Channel(), groupId)] += 1; // FIXME: count distinct blobs?
} else {
TStringStream err;
diff --git a/ydb/core/kqp/counters/kqp_counters.cpp b/ydb/core/kqp/counters/kqp_counters.cpp
index 25b5c0d38c6..26a28a0249a 100644
--- a/ydb/core/kqp/counters/kqp_counters.cpp
+++ b/ydb/core/kqp/counters/kqp_counters.cpp
@@ -373,7 +373,7 @@ void TKqpCountersBase::ReportIssues(const Ydb::Issue::IssueMessage& issue) {
YdbResponsesLocksInvalidated->Inc();
}
- for (auto& childIssue : issue.issues()) {
+ for (auto& childIssue : issue.issues()) {
ReportIssues(childIssue);
}
}
diff --git a/ydb/core/kqp/kqp_ic_gateway.cpp b/ydb/core/kqp/kqp_ic_gateway.cpp
index d36e11fe268..47489a9bd54 100644
--- a/ydb/core/kqp/kqp_ic_gateway.cpp
+++ b/ydb/core/kqp/kqp_ic_gateway.cpp
@@ -1052,7 +1052,7 @@ public:
[path] (TPromise<TListPathResult> promise, TDescribeSchemeResponse&& response) {
try {
promise.SetValue(GetListPathResult(
- response.GetRecord().GetPathDescription(), path));
+ response.GetRecord().GetPathDescription(), path));
}
catch (yexception& e) {
promise.SetValue(ResultFromException<TListPathResult>(e));
diff --git a/ydb/core/kqp/provider/yql_kikimr_gateway_ut.cpp b/ydb/core/kqp/provider/yql_kikimr_gateway_ut.cpp
index bfd81622ff2..791a617c083 100644
--- a/ydb/core/kqp/provider/yql_kikimr_gateway_ut.cpp
+++ b/ydb/core/kqp/provider/yql_kikimr_gateway_ut.cpp
@@ -11,7 +11,7 @@ namespace NYql {
using namespace NKikimr;
using namespace NKikimr::NKqp;
using namespace NMiniKQL;
-using namespace NResultLib;
+using namespace NResultLib;
using namespace NYdb::NTable;
namespace {
diff --git a/ydb/core/mind/bscontroller/impl.h b/ydb/core/mind/bscontroller/impl.h
index 640182dfefd..ba311a254c3 100644
--- a/ydb/core/mind/bscontroller/impl.h
+++ b/ydb/core/mind/bscontroller/impl.h
@@ -53,7 +53,7 @@ public:
class TTxMonEvent_OperationLog;
class TTxMonEvent_HealthEvents;
class TTxMonEvent_SetDown;
- class TTxMonEvent_GetDown;
+ class TTxMonEvent_GetDown;
class TTxUpdateDiskMetrics;
class TTxUpdateGroupLatencies;
class TTxGroupReconfigureWipe;
diff --git a/ydb/core/mind/bscontroller/load_everything.cpp b/ydb/core/mind/bscontroller/load_everything.cpp
index 715c6084c18..8fa32c53f75 100644
--- a/ydb/core/mind/bscontroller/load_everything.cpp
+++ b/ydb/core/mind/bscontroller/load_everything.cpp
@@ -66,7 +66,7 @@ public:
auto state = db.Table<T>().Select();
if (!state.IsReady())
return false;
- if (state.IsValid()) {
+ if (state.IsValid()) {
Self->NextGroupID = state.GetValue<T::NextGroupID>();
Self->NextStoragePoolId = state.GetValue<T::NextStoragePoolId>();
Self->NextOperationLogIndex = state.GetValueOrDefault<T::NextOperationLogIndex>(1);
@@ -84,7 +84,7 @@ public:
Self->MaxScrubbedDisksAtOnce = state.GetValue<T::MaxScrubbedDisksAtOnce>();
Self->PDiskSpaceColorBorder = state.GetValue<T::PDiskSpaceColorBorder>();
Self->SysViewChangedSettings = true;
- }
+ }
}
// Node
diff --git a/ydb/core/mind/bscontroller/monitoring.cpp b/ydb/core/mind/bscontroller/monitoring.cpp
index ebf7f0071b9..245c782cea6 100644
--- a/ydb/core/mind/bscontroller/monitoring.cpp
+++ b/ydb/core/mind/bscontroller/monitoring.cpp
@@ -1075,7 +1075,7 @@ void TBlobStorageController::RenderGroupRow(IOutputStream& out, const TGroupInfo
availableSize += m.GetAvailableSize();
satisfactionRank = std::max(satisfactionRank, m.GetSatisfactionRank());
}
-
+
auto renderLatency = [&](const auto& perc) {
TABLED() {
if (perc) {
@@ -1116,8 +1116,8 @@ void TBlobStorageController::RenderGroupRow(IOutputStream& out, const TGroupInfo
const auto& status = group.Status;
TABLED() { out << NKikimrBlobStorage::TGroupStatus::E_Name(status.OperatingStatus); }
TABLED() { out << NKikimrBlobStorage::TGroupStatus::E_Name(status.ExpectedStatus); }
- }
- }
+ }
+ }
}
} // NBlobStorageController
diff --git a/ydb/core/mind/bscontroller/ut/ya.make b/ydb/core/mind/bscontroller/ut/ya.make
index 229c8d656cf..46321b23789 100644
--- a/ydb/core/mind/bscontroller/ut/ya.make
+++ b/ydb/core/mind/bscontroller/ut/ya.make
@@ -18,7 +18,7 @@ ELSE()
TIMEOUT(600)
SIZE(MEDIUM)
ENDIF()
-
+
PEERDIR(
library/cpp/actors/util
ydb/core/yql_testlib
diff --git a/ydb/core/mind/dynamic_nameserver.cpp b/ydb/core/mind/dynamic_nameserver.cpp
index 358265176b8..6f4f147982a 100644
--- a/ydb/core/mind/dynamic_nameserver.cpp
+++ b/ydb/core/mind/dynamic_nameserver.cpp
@@ -25,11 +25,11 @@ void TDynamicNodeResolverBase::Bootstrap(const TActorContext &ctx)
return;
}
- NTabletPipe::TClientRetryPolicy retryPolicy = {
- .RetryLimitCount = 12,
- .MinRetryTime = TDuration::MilliSeconds(50),
- .MaxRetryTime = TDuration::Seconds(2)
- };
+ NTabletPipe::TClientRetryPolicy retryPolicy = {
+ .RetryLimitCount = 12,
+ .MinRetryTime = TDuration::MilliSeconds(50),
+ .MaxRetryTime = TDuration::Seconds(2)
+ };
ui32 group = dinfo->GetDefaultStateStorageGroup(domain);
auto pipe = NTabletPipe::CreateClient(ctx.SelfID, MakeNodeBrokerID(group), NTabletPipe::TClientConfig(retryPolicy));
diff --git a/ydb/core/mind/hive/balancer.cpp b/ydb/core/mind/hive/balancer.cpp
index 020698faa5e..8521e30499e 100644
--- a/ydb/core/mind/hive/balancer.cpp
+++ b/ydb/core/mind/hive/balancer.cpp
@@ -1,333 +1,333 @@
-#include <random>
+#include <random>
#include <library/cpp/actors/core/actor_bootstrapped.h>
-#include "hive_impl.h"
-#include "hive_log.h"
-#include "node_info.h"
-#include "balancer.h"
-
-namespace NKikimr {
-namespace NHive {
-
-template<>
-void BalanceNodes<NKikimrConfig::THiveConfig::HIVE_NODE_BALANCE_STRATEGY_OLD_WEIGHTED_RANDOM>(std::vector<TNodeInfo*>& nodes) {
- auto& randGen = *TAppData::RandomProvider.Get();
- // weighted random shuffle
- std::vector<double> usages;
- usages.reserve(nodes.size());
- for (auto it = nodes.begin(); it != nodes.end(); ++it) {
- usages.emplace_back((*it)->GetNodeUsage());
- }
- auto itN = nodes.begin();
- auto itU = usages.begin();
- while (itN != nodes.end() && itU != usages.end()) {
- auto idx = std::discrete_distribution(itU, usages.end())(randGen);
- if (idx != 0) {
- std::iter_swap(itN, std::next(itN, idx));
- std::iter_swap(itU, std::next(itU, idx));
- }
- ++itN;
- ++itU;
- }
-}
-
-template<>
-void BalanceNodes<NKikimrConfig::THiveConfig::HIVE_NODE_BALANCE_STRATEGY_WEIGHTED_RANDOM>(std::vector<TNodeInfo*>& nodes) {
- auto& randGen = *TAppData::RandomProvider.Get();
- std::vector<std::pair<double, TNodeInfo*>> weights;
- weights.reserve(nodes.size());
- for (TNodeInfo* node : nodes) {
- double weight = node->GetNodeUsage();
- weights.emplace_back(weight * randGen(), node);
- }
- std::sort(weights.begin(), weights.end(), [](const auto& a, const auto& b) -> bool {
- return a.first > b.first;
- });
- for (size_t n = 0; n < weights.size(); ++n) {
- nodes[n] = weights[n].second;
- }
-}
-
-template<>
-void BalanceNodes<NKikimrConfig::THiveConfig::HIVE_NODE_BALANCE_STRATEGY_HEAVIEST>(std::vector<TNodeInfo*>& nodes) {
- std::sort(nodes.begin(), nodes.end(), [](const TNodeInfo* a, const TNodeInfo* b) -> bool {
- return a->GetNodeUsage() > b->GetNodeUsage();
- });
-}
-
-template<>
-void BalanceNodes<NKikimrConfig::THiveConfig::HIVE_NODE_BALANCE_STRATEGY_RANDOM>(std::vector<TNodeInfo*>& nodes) {
- auto& randGen = *TAppData::RandomProvider.Get();
- std::shuffle(nodes.begin(), nodes.end(), randGen);
-}
-
-template<>
-void BalanceTablets<NKikimrConfig::THiveConfig::HIVE_TABLET_BALANCE_STRATEGY_OLD_WEIGHTED_RANDOM>(std::vector<TTabletInfo*>& tablets) {
- auto& randGen = *TAppData::RandomProvider.Get();
- // weighted random shuffle
- std::vector<double> weights;
- weights.reserve(tablets.size());
- for (auto it = tablets.begin(); it != tablets.end(); ++it) {
- weights.emplace_back((*it)->Weight);
- }
- auto itT = tablets.begin();
- auto itW = weights.begin();
- while (itT != tablets.end() && itW != weights.end()) {
- auto idx = std::discrete_distribution(itW, weights.end())(randGen);
- if (idx != 0) {
- std::iter_swap(itT, std::next(itT, idx));
- std::iter_swap(itW, std::next(itW, idx));
- }
- ++itT;
- ++itW;
- }
-}
-
-template<>
-void BalanceTablets<NKikimrConfig::THiveConfig::HIVE_TABLET_BALANCE_STRATEGY_HEAVIEST>(std::vector<TTabletInfo*>& tablets) {
- std::sort(tablets.begin(), tablets.end(), [](const TTabletInfo* a, const TTabletInfo* b) -> bool {
- return a->Weight > b->Weight;
- });
-}
-
-template<>
-void BalanceTablets<NKikimrConfig::THiveConfig::HIVE_TABLET_BALANCE_STRATEGY_RANDOM>(std::vector<TTabletInfo*>& tablets) {
- auto& randGen = *TAppData::RandomProvider.Get();
- std::shuffle(tablets.begin(), tablets.end(), randGen);
-}
-
-template<>
-void BalanceTablets<NKikimrConfig::THiveConfig::HIVE_TABLET_BALANCE_STRATEGY_WEIGHTED_RANDOM>(std::vector<TTabletInfo*>& tablets) {
- auto& randGen = *TAppData::RandomProvider.Get();
- std::vector<std::pair<double, TTabletInfo*>> weights;
- weights.reserve(tablets.size());
- for (TTabletInfo* tablet : tablets) {
- double weight = tablet->Weight;
- weights.emplace_back(weight * randGen(), tablet);
- }
- std::sort(weights.begin(), weights.end(), [](const auto& a, const auto& b) -> bool {
- return a.first > b.first;
- });
- for (size_t n = 0; n < weights.size(); ++n) {
- tablets[n] = weights[n].second;
- }
-}
-
-class THiveBalancer : public NActors::TActorBootstrapped<THiveBalancer>, public ISubActor {
-protected:
- constexpr static TDuration TIMEOUT = TDuration::Minutes(10);
- THive* Hive;
- using TTabletId = TFullTabletId;
- ui64 KickInFlight;
- int Movements;
- int MaxMovements;
- bool RecheckOnFinish;
- std::vector<TNodeId> FilterNodeIds;
-
- TString GetLogPrefix() const {
- return Hive->GetLogPrefix();
- }
-
- void PassAway() override {
- Hive->BalancerProgress = -1;
- BLOG_I("Balancer finished with " << Movements << " movements made");
- Hive->RemoveSubActor(this);
- if (Movements == 0) {
- Hive->TabletCounters->Cumulative()[NHive::COUNTER_BALANCER_FAILED].Increment(1);
- // we failed to balance specific nodes
- for (TNodeId nodeId : FilterNodeIds) {
- TNodeInfo* node = Hive->FindNode(nodeId);
- if (node != nullptr && node->IsOverloaded()) {
- BLOG_D("Balancer suggests scale-up");
- Hive->TabletCounters->Cumulative()[NHive::COUNTER_SUGGESTED_SCALE_UP].Increment(1);
- break;
- }
- }
- }
- if (RecheckOnFinish && MaxMovements != 0 && Movements >= MaxMovements) {
- BLOG_D("Balancer initiated recheck");
- Hive->ProcessTabletBalancer();
- }
- return IActor::PassAway();
- }
-
- void Cleanup() override {
- PassAway();
- }
-
- bool CanKickNextTablet() const {
- return KickInFlight < Hive->GetBalancerInflight();
- }
-
- void UpdateProgress() {
- if (MaxMovements != 0) {
- Hive->BalancerProgress = Movements * 100 / MaxMovements;
- } else {
- if (Hive->TabletsTotal != 0) {
- Hive->BalancerProgress = Movements * 100 / Hive->TabletsTotal;
- } else {
- Hive->BalancerProgress = 0;
- }
- }
- }
-
- void KickNextTablet() {
- if (!CanKickNextTablet()) {
- return;
- }
- if (MaxMovements != 0 && Movements >= MaxMovements) {
- if (KickInFlight > 0) {
- return;
- } else {
- return PassAway();
- }
- }
-
- struct TBalancerNodeInfo {
- const TNodeInfo* Node;
- double Usage;
-
- TBalancerNodeInfo(const TNodeInfo* node, double usage)
- : Node(node)
- , Usage(usage)
- {}
- };
-
- TInstant now = TActivationContext::Now();
- std::vector<TNodeInfo*> nodes;
- if (!FilterNodeIds.empty()) {
- nodes.reserve(FilterNodeIds.size());
- for (TNodeId nodeId : FilterNodeIds) {
- TNodeInfo* node = Hive->FindNode(nodeId);
- if (node != nullptr && node->IsAlive()) {
- nodes.emplace_back(node);
- }
- }
- } else {
- nodes.reserve(Hive->Nodes.size());
- for (auto& [nodeId, nodeInfo] : Hive->Nodes) {
- if (nodeInfo.IsAlive()) {
- nodes.emplace_back(&nodeInfo);
- }
- }
- }
-
- switch (Hive->GetNodeBalanceStrategy()) {
- case NKikimrConfig::THiveConfig::HIVE_NODE_BALANCE_STRATEGY_OLD_WEIGHTED_RANDOM:
- BalanceNodes<NKikimrConfig::THiveConfig::HIVE_NODE_BALANCE_STRATEGY_OLD_WEIGHTED_RANDOM>(nodes);
- break;
- case NKikimrConfig::THiveConfig::HIVE_NODE_BALANCE_STRATEGY_WEIGHTED_RANDOM:
- BalanceNodes<NKikimrConfig::THiveConfig::HIVE_NODE_BALANCE_STRATEGY_WEIGHTED_RANDOM>(nodes);
- break;
- case NKikimrConfig::THiveConfig::HIVE_NODE_BALANCE_STRATEGY_HEAVIEST:
- BalanceNodes<NKikimrConfig::THiveConfig::HIVE_NODE_BALANCE_STRATEGY_HEAVIEST>(nodes);
- break;
- case NKikimrConfig::THiveConfig::HIVE_NODE_BALANCE_STRATEGY_RANDOM:
- BalanceNodes<NKikimrConfig::THiveConfig::HIVE_NODE_BALANCE_STRATEGY_RANDOM>(nodes);
- break;
- }
- for (const TNodeInfo* node : nodes) {
- BLOG_TRACE("Balancer selected node " << node->Id);
- auto itTablets = node->Tablets.find(TTabletInfo::EVolatileState::TABLET_VOLATILE_STATE_RUNNING);
- if (itTablets == node->Tablets.end()) {
- continue;
- }
- const std::unordered_set<TTabletInfo*>& nodeTablets = itTablets->second;
- std::vector<TTabletInfo*> tablets;
- tablets.reserve(nodeTablets.size());
- for (TTabletInfo* tablet : nodeTablets) {
- if (tablet->IsGoodForBalancer(now)) {
- tablets.emplace_back(tablet);
- }
- }
- if (!tablets.empty()) {
- switch (Hive->GetTabletBalanceStrategy()) {
- case NKikimrConfig::THiveConfig::HIVE_TABLET_BALANCE_STRATEGY_OLD_WEIGHTED_RANDOM:
- BalanceTablets<NKikimrConfig::THiveConfig::HIVE_TABLET_BALANCE_STRATEGY_OLD_WEIGHTED_RANDOM>(tablets);
- break;
- case NKikimrConfig::THiveConfig::HIVE_TABLET_BALANCE_STRATEGY_WEIGHTED_RANDOM:
- BalanceTablets<NKikimrConfig::THiveConfig::HIVE_TABLET_BALANCE_STRATEGY_WEIGHTED_RANDOM>(tablets);
- break;
- case NKikimrConfig::THiveConfig::HIVE_TABLET_BALANCE_STRATEGY_HEAVIEST:
- BalanceTablets<NKikimrConfig::THiveConfig::HIVE_TABLET_BALANCE_STRATEGY_HEAVIEST>(tablets);
- break;
- case NKikimrConfig::THiveConfig::HIVE_TABLET_BALANCE_STRATEGY_RANDOM:
- BalanceTablets<NKikimrConfig::THiveConfig::HIVE_TABLET_BALANCE_STRATEGY_RANDOM>(tablets);
- break;
- }
- for (TTabletInfo* tablet : tablets) {
- BLOG_TRACE("Balancer selected tablet " << tablet->ToString());
- THive::TBestNodeResult result = Hive->FindBestNode(*tablet);
- if (result.BestNode != nullptr && result.BestNode != tablet->Node) {
- if (Hive->IsTabletMoveExpedient(*tablet, *result.BestNode)) {
- tablet->MakeBalancerDecision(now);
- tablet->ActorsToNotifyOnRestart.emplace_back(SelfId()); // volatile settings, will not persist upon restart
- ++KickInFlight;
- ++Movements;
- BLOG_D("Balancer moving tablet " << tablet->ToString() << " " << tablet->GetResourceValues()
- << " from node " << tablet->Node->Id << " " << tablet->Node->ResourceValues
- << " to node " << result.BestNode->Id << " " << result.BestNode->ResourceValues);
- Hive->TabletCounters->Cumulative()[NHive::COUNTER_TABLETS_MOVED].Increment(1);
- Hive->Execute(Hive->CreateRestartTablet(tablet->GetFullTabletId(), result.BestNode->Id));
- UpdateProgress();
- if (!CanKickNextTablet()) {
- return;
- }
- }
- }
- }
- }
- }
- return PassAway();
- }
-
- void Handle(TEvPrivate::TEvRestartComplete::TPtr& ev) {
- BLOG_D("Balancer " << SelfId() << " received " << ev->Get()->Status << " for tablet " << ev->Get()->TabletId);
- --KickInFlight;
- KickNextTablet();
- }
-
- void Timeout() {
- PassAway();
- }
-
-public:
+#include "hive_impl.h"
+#include "hive_log.h"
+#include "node_info.h"
+#include "balancer.h"
+
+namespace NKikimr {
+namespace NHive {
+
+template<>
+void BalanceNodes<NKikimrConfig::THiveConfig::HIVE_NODE_BALANCE_STRATEGY_OLD_WEIGHTED_RANDOM>(std::vector<TNodeInfo*>& nodes) {
+ auto& randGen = *TAppData::RandomProvider.Get();
+ // weighted random shuffle
+ std::vector<double> usages;
+ usages.reserve(nodes.size());
+ for (auto it = nodes.begin(); it != nodes.end(); ++it) {
+ usages.emplace_back((*it)->GetNodeUsage());
+ }
+ auto itN = nodes.begin();
+ auto itU = usages.begin();
+ while (itN != nodes.end() && itU != usages.end()) {
+ auto idx = std::discrete_distribution(itU, usages.end())(randGen);
+ if (idx != 0) {
+ std::iter_swap(itN, std::next(itN, idx));
+ std::iter_swap(itU, std::next(itU, idx));
+ }
+ ++itN;
+ ++itU;
+ }
+}
+
+template<>
+void BalanceNodes<NKikimrConfig::THiveConfig::HIVE_NODE_BALANCE_STRATEGY_WEIGHTED_RANDOM>(std::vector<TNodeInfo*>& nodes) {
+ auto& randGen = *TAppData::RandomProvider.Get();
+ std::vector<std::pair<double, TNodeInfo*>> weights;
+ weights.reserve(nodes.size());
+ for (TNodeInfo* node : nodes) {
+ double weight = node->GetNodeUsage();
+ weights.emplace_back(weight * randGen(), node);
+ }
+ std::sort(weights.begin(), weights.end(), [](const auto& a, const auto& b) -> bool {
+ return a.first > b.first;
+ });
+ for (size_t n = 0; n < weights.size(); ++n) {
+ nodes[n] = weights[n].second;
+ }
+}
+
+template<>
+void BalanceNodes<NKikimrConfig::THiveConfig::HIVE_NODE_BALANCE_STRATEGY_HEAVIEST>(std::vector<TNodeInfo*>& nodes) {
+ std::sort(nodes.begin(), nodes.end(), [](const TNodeInfo* a, const TNodeInfo* b) -> bool {
+ return a->GetNodeUsage() > b->GetNodeUsage();
+ });
+}
+
+template<>
+void BalanceNodes<NKikimrConfig::THiveConfig::HIVE_NODE_BALANCE_STRATEGY_RANDOM>(std::vector<TNodeInfo*>& nodes) {
+ auto& randGen = *TAppData::RandomProvider.Get();
+ std::shuffle(nodes.begin(), nodes.end(), randGen);
+}
+
+template<>
+void BalanceTablets<NKikimrConfig::THiveConfig::HIVE_TABLET_BALANCE_STRATEGY_OLD_WEIGHTED_RANDOM>(std::vector<TTabletInfo*>& tablets) {
+ auto& randGen = *TAppData::RandomProvider.Get();
+ // weighted random shuffle
+ std::vector<double> weights;
+ weights.reserve(tablets.size());
+ for (auto it = tablets.begin(); it != tablets.end(); ++it) {
+ weights.emplace_back((*it)->Weight);
+ }
+ auto itT = tablets.begin();
+ auto itW = weights.begin();
+ while (itT != tablets.end() && itW != weights.end()) {
+ auto idx = std::discrete_distribution(itW, weights.end())(randGen);
+ if (idx != 0) {
+ std::iter_swap(itT, std::next(itT, idx));
+ std::iter_swap(itW, std::next(itW, idx));
+ }
+ ++itT;
+ ++itW;
+ }
+}
+
+template<>
+void BalanceTablets<NKikimrConfig::THiveConfig::HIVE_TABLET_BALANCE_STRATEGY_HEAVIEST>(std::vector<TTabletInfo*>& tablets) {
+ std::sort(tablets.begin(), tablets.end(), [](const TTabletInfo* a, const TTabletInfo* b) -> bool {
+ return a->Weight > b->Weight;
+ });
+}
+
+template<>
+void BalanceTablets<NKikimrConfig::THiveConfig::HIVE_TABLET_BALANCE_STRATEGY_RANDOM>(std::vector<TTabletInfo*>& tablets) {
+ auto& randGen = *TAppData::RandomProvider.Get();
+ std::shuffle(tablets.begin(), tablets.end(), randGen);
+}
+
+template<>
+void BalanceTablets<NKikimrConfig::THiveConfig::HIVE_TABLET_BALANCE_STRATEGY_WEIGHTED_RANDOM>(std::vector<TTabletInfo*>& tablets) {
+ auto& randGen = *TAppData::RandomProvider.Get();
+ std::vector<std::pair<double, TTabletInfo*>> weights;
+ weights.reserve(tablets.size());
+ for (TTabletInfo* tablet : tablets) {
+ double weight = tablet->Weight;
+ weights.emplace_back(weight * randGen(), tablet);
+ }
+ std::sort(weights.begin(), weights.end(), [](const auto& a, const auto& b) -> bool {
+ return a.first > b.first;
+ });
+ for (size_t n = 0; n < weights.size(); ++n) {
+ tablets[n] = weights[n].second;
+ }
+}
+
+class THiveBalancer : public NActors::TActorBootstrapped<THiveBalancer>, public ISubActor {
+protected:
+ constexpr static TDuration TIMEOUT = TDuration::Minutes(10);
+ THive* Hive;
+ using TTabletId = TFullTabletId;
+ ui64 KickInFlight;
+ int Movements;
+ int MaxMovements;
+ bool RecheckOnFinish;
+ std::vector<TNodeId> FilterNodeIds;
+
+ TString GetLogPrefix() const {
+ return Hive->GetLogPrefix();
+ }
+
+ void PassAway() override {
+ Hive->BalancerProgress = -1;
+ BLOG_I("Balancer finished with " << Movements << " movements made");
+ Hive->RemoveSubActor(this);
+ if (Movements == 0) {
+ Hive->TabletCounters->Cumulative()[NHive::COUNTER_BALANCER_FAILED].Increment(1);
+ // we failed to balance specific nodes
+ for (TNodeId nodeId : FilterNodeIds) {
+ TNodeInfo* node = Hive->FindNode(nodeId);
+ if (node != nullptr && node->IsOverloaded()) {
+ BLOG_D("Balancer suggests scale-up");
+ Hive->TabletCounters->Cumulative()[NHive::COUNTER_SUGGESTED_SCALE_UP].Increment(1);
+ break;
+ }
+ }
+ }
+ if (RecheckOnFinish && MaxMovements != 0 && Movements >= MaxMovements) {
+ BLOG_D("Balancer initiated recheck");
+ Hive->ProcessTabletBalancer();
+ }
+ return IActor::PassAway();
+ }
+
+ void Cleanup() override {
+ PassAway();
+ }
+
+ bool CanKickNextTablet() const {
+ return KickInFlight < Hive->GetBalancerInflight();
+ }
+
+ void UpdateProgress() {
+ if (MaxMovements != 0) {
+ Hive->BalancerProgress = Movements * 100 / MaxMovements;
+ } else {
+ if (Hive->TabletsTotal != 0) {
+ Hive->BalancerProgress = Movements * 100 / Hive->TabletsTotal;
+ } else {
+ Hive->BalancerProgress = 0;
+ }
+ }
+ }
+
+ void KickNextTablet() {
+ if (!CanKickNextTablet()) {
+ return;
+ }
+ if (MaxMovements != 0 && Movements >= MaxMovements) {
+ if (KickInFlight > 0) {
+ return;
+ } else {
+ return PassAway();
+ }
+ }
+
+ struct TBalancerNodeInfo {
+ const TNodeInfo* Node;
+ double Usage;
+
+ TBalancerNodeInfo(const TNodeInfo* node, double usage)
+ : Node(node)
+ , Usage(usage)
+ {}
+ };
+
+ TInstant now = TActivationContext::Now();
+ std::vector<TNodeInfo*> nodes;
+ if (!FilterNodeIds.empty()) {
+ nodes.reserve(FilterNodeIds.size());
+ for (TNodeId nodeId : FilterNodeIds) {
+ TNodeInfo* node = Hive->FindNode(nodeId);
+ if (node != nullptr && node->IsAlive()) {
+ nodes.emplace_back(node);
+ }
+ }
+ } else {
+ nodes.reserve(Hive->Nodes.size());
+ for (auto& [nodeId, nodeInfo] : Hive->Nodes) {
+ if (nodeInfo.IsAlive()) {
+ nodes.emplace_back(&nodeInfo);
+ }
+ }
+ }
+
+ switch (Hive->GetNodeBalanceStrategy()) {
+ case NKikimrConfig::THiveConfig::HIVE_NODE_BALANCE_STRATEGY_OLD_WEIGHTED_RANDOM:
+ BalanceNodes<NKikimrConfig::THiveConfig::HIVE_NODE_BALANCE_STRATEGY_OLD_WEIGHTED_RANDOM>(nodes);
+ break;
+ case NKikimrConfig::THiveConfig::HIVE_NODE_BALANCE_STRATEGY_WEIGHTED_RANDOM:
+ BalanceNodes<NKikimrConfig::THiveConfig::HIVE_NODE_BALANCE_STRATEGY_WEIGHTED_RANDOM>(nodes);
+ break;
+ case NKikimrConfig::THiveConfig::HIVE_NODE_BALANCE_STRATEGY_HEAVIEST:
+ BalanceNodes<NKikimrConfig::THiveConfig::HIVE_NODE_BALANCE_STRATEGY_HEAVIEST>(nodes);
+ break;
+ case NKikimrConfig::THiveConfig::HIVE_NODE_BALANCE_STRATEGY_RANDOM:
+ BalanceNodes<NKikimrConfig::THiveConfig::HIVE_NODE_BALANCE_STRATEGY_RANDOM>(nodes);
+ break;
+ }
+ for (const TNodeInfo* node : nodes) {
+ BLOG_TRACE("Balancer selected node " << node->Id);
+ auto itTablets = node->Tablets.find(TTabletInfo::EVolatileState::TABLET_VOLATILE_STATE_RUNNING);
+ if (itTablets == node->Tablets.end()) {
+ continue;
+ }
+ const std::unordered_set<TTabletInfo*>& nodeTablets = itTablets->second;
+ std::vector<TTabletInfo*> tablets;
+ tablets.reserve(nodeTablets.size());
+ for (TTabletInfo* tablet : nodeTablets) {
+ if (tablet->IsGoodForBalancer(now)) {
+ tablets.emplace_back(tablet);
+ }
+ }
+ if (!tablets.empty()) {
+ switch (Hive->GetTabletBalanceStrategy()) {
+ case NKikimrConfig::THiveConfig::HIVE_TABLET_BALANCE_STRATEGY_OLD_WEIGHTED_RANDOM:
+ BalanceTablets<NKikimrConfig::THiveConfig::HIVE_TABLET_BALANCE_STRATEGY_OLD_WEIGHTED_RANDOM>(tablets);
+ break;
+ case NKikimrConfig::THiveConfig::HIVE_TABLET_BALANCE_STRATEGY_WEIGHTED_RANDOM:
+ BalanceTablets<NKikimrConfig::THiveConfig::HIVE_TABLET_BALANCE_STRATEGY_WEIGHTED_RANDOM>(tablets);
+ break;
+ case NKikimrConfig::THiveConfig::HIVE_TABLET_BALANCE_STRATEGY_HEAVIEST:
+ BalanceTablets<NKikimrConfig::THiveConfig::HIVE_TABLET_BALANCE_STRATEGY_HEAVIEST>(tablets);
+ break;
+ case NKikimrConfig::THiveConfig::HIVE_TABLET_BALANCE_STRATEGY_RANDOM:
+ BalanceTablets<NKikimrConfig::THiveConfig::HIVE_TABLET_BALANCE_STRATEGY_RANDOM>(tablets);
+ break;
+ }
+ for (TTabletInfo* tablet : tablets) {
+ BLOG_TRACE("Balancer selected tablet " << tablet->ToString());
+ THive::TBestNodeResult result = Hive->FindBestNode(*tablet);
+ if (result.BestNode != nullptr && result.BestNode != tablet->Node) {
+ if (Hive->IsTabletMoveExpedient(*tablet, *result.BestNode)) {
+ tablet->MakeBalancerDecision(now);
+ tablet->ActorsToNotifyOnRestart.emplace_back(SelfId()); // volatile settings, will not persist upon restart
+ ++KickInFlight;
+ ++Movements;
+ BLOG_D("Balancer moving tablet " << tablet->ToString() << " " << tablet->GetResourceValues()
+ << " from node " << tablet->Node->Id << " " << tablet->Node->ResourceValues
+ << " to node " << result.BestNode->Id << " " << result.BestNode->ResourceValues);
+ Hive->TabletCounters->Cumulative()[NHive::COUNTER_TABLETS_MOVED].Increment(1);
+ Hive->Execute(Hive->CreateRestartTablet(tablet->GetFullTabletId(), result.BestNode->Id));
+ UpdateProgress();
+ if (!CanKickNextTablet()) {
+ return;
+ }
+ }
+ }
+ }
+ }
+ }
+ return PassAway();
+ }
+
+ void Handle(TEvPrivate::TEvRestartComplete::TPtr& ev) {
+ BLOG_D("Balancer " << SelfId() << " received " << ev->Get()->Status << " for tablet " << ev->Get()->TabletId);
+ --KickInFlight;
+ KickNextTablet();
+ }
+
+ void Timeout() {
+ PassAway();
+ }
+
+public:
static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
return NKikimrServices::TActivity::HIVE_BALANCER_ACTOR;
}
- THiveBalancer(THive* hive, int maxMovements = 0, bool recheckOnFinish = false, const std::vector<TNodeId>& filterNodeIds = {})
- : Hive(hive)
- , KickInFlight(0)
- , Movements(0)
- , MaxMovements(maxMovements)
- , RecheckOnFinish(recheckOnFinish)
- , FilterNodeIds(filterNodeIds)
+ THiveBalancer(THive* hive, int maxMovements = 0, bool recheckOnFinish = false, const std::vector<TNodeId>& filterNodeIds = {})
+ : Hive(hive)
+ , KickInFlight(0)
+ , Movements(0)
+ , MaxMovements(maxMovements)
+ , RecheckOnFinish(recheckOnFinish)
+ , FilterNodeIds(filterNodeIds)
{}
-
- void Bootstrap() {
- UpdateProgress();
- Hive->TabletCounters->Cumulative()[NHive::COUNTER_BALANCER_EXECUTED].Increment(1);
- Become(&THiveBalancer::StateWork, TIMEOUT, new TEvents::TEvWakeup());
- KickNextTablet();
- }
-
- STATEFN(StateWork) {
- switch (ev->GetTypeRewrite()) {
- cFunc(TEvents::TSystem::PoisonPill, PassAway);
- hFunc(TEvPrivate::TEvRestartComplete, Handle);
- cFunc(TEvents::TSystem::Wakeup, Timeout);
- }
- }
-};
-
-void THive::StartHiveBalancer(int maxMovements, bool recheckOnFinish, const std::vector<TNodeId>& filterNodeIds) {
- if (BalancerProgress == -1) {
- auto* balancer = new THiveBalancer(this, maxMovements, recheckOnFinish, filterNodeIds);
- SubActors.emplace_back(balancer);
- BalancerProgress = -2;
- RegisterWithSameMailbox(balancer);
- }
-}
-
-} // NHive
-} // NKikimr
+
+ void Bootstrap() {
+ UpdateProgress();
+ Hive->TabletCounters->Cumulative()[NHive::COUNTER_BALANCER_EXECUTED].Increment(1);
+ Become(&THiveBalancer::StateWork, TIMEOUT, new TEvents::TEvWakeup());
+ KickNextTablet();
+ }
+
+ STATEFN(StateWork) {
+ switch (ev->GetTypeRewrite()) {
+ cFunc(TEvents::TSystem::PoisonPill, PassAway);
+ hFunc(TEvPrivate::TEvRestartComplete, Handle);
+ cFunc(TEvents::TSystem::Wakeup, Timeout);
+ }
+ }
+};
+
+void THive::StartHiveBalancer(int maxMovements, bool recheckOnFinish, const std::vector<TNodeId>& filterNodeIds) {
+ if (BalancerProgress == -1) {
+ auto* balancer = new THiveBalancer(this, maxMovements, recheckOnFinish, filterNodeIds);
+ SubActors.emplace_back(balancer);
+ BalancerProgress = -2;
+ RegisterWithSameMailbox(balancer);
+ }
+}
+
+} // NHive
+} // NKikimr
diff --git a/ydb/core/mind/hive/balancer.h b/ydb/core/mind/hive/balancer.h
index 3bd400f51d2..cf3d538c829 100644
--- a/ydb/core/mind/hive/balancer.h
+++ b/ydb/core/mind/hive/balancer.h
@@ -1,15 +1,15 @@
-#pragma once
-
-#include "hive_impl.h"
-
-namespace NKikimr {
-namespace NHive {
-
-template<NKikimrConfig::THiveConfig::EHiveNodeBalanceStrategy EHiveNodeBalanceStrategy>
-void BalanceNodes(std::vector<TNodeInfo*>& nodes);
-
-template<NKikimrConfig::THiveConfig::EHiveTabletBalanceStrategy EHiveTabletBalanceStrategy>
-void BalanceTablets(std::vector<TTabletInfo*>& tablets);
-
-}
-}
+#pragma once
+
+#include "hive_impl.h"
+
+namespace NKikimr {
+namespace NHive {
+
+template<NKikimrConfig::THiveConfig::EHiveNodeBalanceStrategy EHiveNodeBalanceStrategy>
+void BalanceNodes(std::vector<TNodeInfo*>& nodes);
+
+template<NKikimrConfig::THiveConfig::EHiveTabletBalanceStrategy EHiveTabletBalanceStrategy>
+void BalanceTablets(std::vector<TTabletInfo*>& tablets);
+
+}
+}
diff --git a/ydb/core/mind/hive/boot_queue.cpp b/ydb/core/mind/hive/boot_queue.cpp
index 136d1b26aaf..197aa6b6c57 100644
--- a/ydb/core/mind/hive/boot_queue.cpp
+++ b/ydb/core/mind/hive/boot_queue.cpp
@@ -1,29 +1,29 @@
-#include "boot_queue.h"
+#include "boot_queue.h"
#include "leader_tablet_info.h"
-
-namespace NKikimr {
-namespace NHive {
-
-void TBootQueue::AddToBootQueue(TBootQueueRecord record) {
- BootQueue.push(record);
-}
-
-TBootQueue::TBootQueueRecord TBootQueue::PopFromBootQueue() {
- TBootQueueRecord record = BootQueue.top();
- BootQueue.pop();
- return record;
-}
-
-void TBootQueue::AddToWaitQueue(TBootQueueRecord record) {
- WaitQueue.emplace_back(record);
-}
-
-void TBootQueue::MoveFromWaitQueueToBootQueue() {
- for (TBootQueueRecord record : WaitQueue) {
- AddToBootQueue(record);
- }
- WaitQueue.clear();
-}
-
-}
-}
+
+namespace NKikimr {
+namespace NHive {
+
+void TBootQueue::AddToBootQueue(TBootQueueRecord record) {
+ BootQueue.push(record);
+}
+
+TBootQueue::TBootQueueRecord TBootQueue::PopFromBootQueue() {
+ TBootQueueRecord record = BootQueue.top();
+ BootQueue.pop();
+ return record;
+}
+
+void TBootQueue::AddToWaitQueue(TBootQueueRecord record) {
+ WaitQueue.emplace_back(record);
+}
+
+void TBootQueue::MoveFromWaitQueueToBootQueue() {
+ for (TBootQueueRecord record : WaitQueue) {
+ AddToBootQueue(record);
+ }
+ WaitQueue.clear();
+}
+
+}
+}
diff --git a/ydb/core/mind/hive/boot_queue.h b/ydb/core/mind/hive/boot_queue.h
index 8d49a657322..a8424770f65 100644
--- a/ydb/core/mind/hive/boot_queue.h
+++ b/ydb/core/mind/hive/boot_queue.h
@@ -1,58 +1,58 @@
-#pragma once
-
-#include "hive.h"
-#include "tablet_info.h"
-
-namespace NKikimr {
-namespace NHive {
-
-struct TBootQueue {
- struct TBootQueueRecord {
- TFullTabletId TabletId;
- double Priority;
-
- static double GetBootPriority(const TTabletInfo& tablet) {
- double priority = 0;
- switch (tablet.GetTabletType()) {
- case TTabletTypes::Hive:
- priority = 4;
- break;
- case TTabletTypes::SchemeShard:
- priority = 3;
- break;
- case TTabletTypes::Mediator:
- case TTabletTypes::Coordinator:
- priority = 2;
- break;
- default:
+#pragma once
+
+#include "hive.h"
+#include "tablet_info.h"
+
+namespace NKikimr {
+namespace NHive {
+
+struct TBootQueue {
+ struct TBootQueueRecord {
+ TFullTabletId TabletId;
+ double Priority;
+
+ static double GetBootPriority(const TTabletInfo& tablet) {
+ double priority = 0;
+ switch (tablet.GetTabletType()) {
+ case TTabletTypes::Hive:
+ priority = 4;
+ break;
+ case TTabletTypes::SchemeShard:
+ priority = 3;
+ break;
+ case TTabletTypes::Mediator:
+ case TTabletTypes::Coordinator:
+ priority = 2;
+ break;
+ default:
if (tablet.IsLeader()) {
- priority = 1;
- }
- break;
- }
- priority += tablet.Weight;
- return priority;
- }
-
- bool operator <(const TBootQueueRecord& o) const {
- return Priority < o.Priority;
- }
-
- TBootQueueRecord(const TTabletInfo& tablet)
- : TabletId(tablet.GetFullTabletId())
- , Priority(GetBootPriority(tablet))
- {
- }
- };
-
- std::priority_queue<TBootQueueRecord, std::vector<TBootQueueRecord>> BootQueue;
- std::deque<TBootQueueRecord> WaitQueue; // tablets from BootQueue waiting for new nodes
-
- void AddToBootQueue(TBootQueueRecord record);
- TBootQueueRecord PopFromBootQueue();
- void AddToWaitQueue(TBootQueueRecord record);
- void MoveFromWaitQueueToBootQueue();
-};
-
-}
-}
+ priority = 1;
+ }
+ break;
+ }
+ priority += tablet.Weight;
+ return priority;
+ }
+
+ bool operator <(const TBootQueueRecord& o) const {
+ return Priority < o.Priority;
+ }
+
+ TBootQueueRecord(const TTabletInfo& tablet)
+ : TabletId(tablet.GetFullTabletId())
+ , Priority(GetBootPriority(tablet))
+ {
+ }
+ };
+
+ std::priority_queue<TBootQueueRecord, std::vector<TBootQueueRecord>> BootQueue;
+ std::deque<TBootQueueRecord> WaitQueue; // tablets from BootQueue waiting for new nodes
+
+ void AddToBootQueue(TBootQueueRecord record);
+ TBootQueueRecord PopFromBootQueue();
+ void AddToWaitQueue(TBootQueueRecord record);
+ void MoveFromWaitQueueToBootQueue();
+};
+
+}
+}
diff --git a/ydb/core/mind/hive/domain_info.h b/ydb/core/mind/hive/domain_info.h
index aba8a2f6868..1a737dbafbf 100644
--- a/ydb/core/mind/hive/domain_info.h
+++ b/ydb/core/mind/hive/domain_info.h
@@ -1,14 +1,14 @@
-#pragma once
-
-#include "hive.h"
-
-namespace NKikimr {
-namespace NHive {
-
-struct TDomainInfo {
- TString Path;
- TTabletId HiveId = 0;
-};
-
-}
-}
+#pragma once
+
+#include "hive.h"
+
+namespace NKikimr {
+namespace NHive {
+
+struct TDomainInfo {
+ TString Path;
+ TTabletId HiveId = 0;
+};
+
+}
+}
diff --git a/ydb/core/mind/hive/drain.cpp b/ydb/core/mind/hive/drain.cpp
index 59cbd054763..2e263a7f0e1 100644
--- a/ydb/core/mind/hive/drain.cpp
+++ b/ydb/core/mind/hive/drain.cpp
@@ -1,214 +1,214 @@
#include <library/cpp/actors/core/actor_bootstrapped.h>
-#include "hive_impl.h"
-#include "hive_log.h"
-#include "node_info.h"
-
-namespace NKikimr {
-namespace NHive {
-
-class THiveDrain : public NActors::TActorBootstrapped<THiveDrain>, public ISubActor {
-protected:
- constexpr static ui64 TIMEOUT = 1800000; // 30 minutes
- THive* Hive;
- TVector<TFullTabletId> Tablets;
- TVector<TFullTabletId>::iterator NextKick;
- ui32 KickInFlight;
- ui32 Movements;
- TNodeId NodeId;
- bool DownBefore = false;
- TActorId DomainHivePipeClient;
- TTabletId DomainHiveId = 0;
- ui32 DomainMovements = 0;
- TDrainSettings Settings;
-
- TString GetLogPrefix() const {
- return Hive->GetLogPrefix();
- }
-
- void PassAway() override {
- if (DomainHivePipeClient) {
- NTabletPipe::CloseClient(SelfId(), DomainHivePipeClient);
- }
- Hive->RemoveSubActor(this);
- Hive->BalancerNodes.erase(NodeId);
- return IActor::PassAway();
- }
-
- void Cleanup() override {
- PassAway();
- }
-
- void ReplyAndDie(NKikimrProto::EReplyStatus status) {
- BLOG_I("Drain " << SelfId() << " finished with " << Movements << " movements made");
- TNodeInfo* nodeInfo = Hive->FindNode(NodeId);
- if (nodeInfo != nullptr) {
- if (!DownBefore) {
- nodeInfo->SetDown(false);
- }
- }
- Hive->Execute(Hive->CreateSwitchDrainOff(NodeId, std::move(Settings), status, Movements + DomainMovements));
- PassAway();
- }
-
- bool CanKickNextTablet() const {
- ui32 inFlight = Settings.DrainInFlight ? Settings.DrainInFlight : Hive->GetDrainInflight();
- return NextKick != Tablets.end() && KickInFlight < inFlight;
- }
-
- void KickNextTablet() {
- while (CanKickNextTablet()) {
- TFullTabletId tabletId = *NextKick;
- TTabletInfo* tablet = Hive->FindTablet(tabletId);
- if (tablet != nullptr && tablet->IsAlive() && tablet->NodeId == NodeId) {
- THive::TBestNodeResult result = Hive->FindBestNode(*tablet);
- if (result.BestNode != nullptr) {
- tablet->ActorsToNotifyOnRestart.emplace_back(SelfId()); // volatile settings, will not persist upon restart
- ++KickInFlight;
- ++Movements;
- BLOG_D("Drain " << SelfId() << " moving tablet "
- << tablet->ToString() << " " << tablet->GetResourceValues()
- << " from node " << tablet->Node->Id << " " << tablet->Node->ResourceValues
- << " to node " << result.BestNode->Id << " " << result.BestNode->ResourceValues);
- Hive->TabletCounters->Cumulative()[NHive::COUNTER_DRAIN_EXECUTED].Increment(1);
- Hive->TabletCounters->Cumulative()[NHive::COUNTER_TABLETS_MOVED].Increment(1);
- Hive->Execute(Hive->CreateRestartTablet(tabletId, result.BestNode->Id));
- } else {
- Hive->TabletCounters->Cumulative()[NHive::COUNTER_DRAIN_FAILED].Increment(1);
- BLOG_D("Drain " << SelfId() << " could not move tablet " << tablet->ToString() << " " << tablet->GetResourceValues()
- << " from node " << tablet->Node->Id << " " << tablet->Node->ResourceValues);
- }
- }
- ++NextKick;
- }
- if (KickInFlight == 0) {
- return ReplyAndDie(NKikimrProto::OK);
- }
- }
-
- void DomainDrainCompleted(ui32 movements = 0) {
- Movements += movements;
- if (DomainHivePipeClient) {
- NTabletPipe::CloseClient(SelfId(), DomainHivePipeClient);
- DomainHivePipeClient = {};
- }
- KickNextTablet();
- }
-
- void Handle(TEvPrivate::TEvRestartComplete::TPtr& ev) {
- BLOG_D("Drain " << SelfId() << " received " << ev->Get()->Status << " for tablet " << ev->Get()->TabletId);
- --KickInFlight;
- KickNextTablet();
- }
-
- void Handle(TEvHive::TEvDrainNodeResult::TPtr& ev) {
- BLOG_D("Drain " << SelfId() << " received status from domain hive " << ev->Get()->Record.ShortDebugString());
- BLOG_I("Drain " << SelfId() << " continued for node " << NodeId << " with " << Tablets.size() << " tablets");
- DomainDrainCompleted(ev->Get()->Record.GetMovements());
- }
-
- void Handle(TEvTabletPipe::TEvClientConnected::TPtr& ev) {
- if (ev->Get()->Status != NKikimrProto::OK && DomainHiveId != 0) {
- BLOG_W("Drain " << SelfId() << " pipe to hive " << DomainHiveId << " failed to connect");
- DomainDrainCompleted();
- }
- }
-
- void Handle(TEvTabletPipe::TEvClientDestroyed::TPtr& ev) {
- if (ev->Get()->ClientId == DomainHivePipeClient) {
- BLOG_W("Drain " << SelfId() << " pipe to hive " << DomainHiveId << " destroyed - retrying");
- if (DomainHivePipeClient) {
- NTabletPipe::CloseClient(SelfId(), DomainHivePipeClient);
- }
- RequestDrainFromDomainHive();
- }
- }
-
- void Timeout() {
- ReplyAndDie(NKikimrProto::TIMEOUT);
- }
-
- void RequestDrainFromDomainHive() {
- NTabletPipe::TClientConfig pipeConfig;
- pipeConfig.RetryPolicy = {.RetryLimitCount = 13};
- DomainHivePipeClient = Register(NTabletPipe::CreateClient(SelfId(), DomainHiveId, pipeConfig));
- THolder<TEvHive::TEvDrainNode> event = MakeHolder<TEvHive::TEvDrainNode>(NodeId);
- event->Record.SetKeepDown(Settings.KeepDown);
- event->Record.SetPersist(Settings.Persist);
- event->Record.SetDrainInFlight(Settings.DrainInFlight);
- NTabletPipe::SendData(SelfId(), DomainHivePipeClient, event.Release());
- BLOG_I("Drain " << SelfId() << " forwarded for node " << NodeId << " to hive " << DomainHiveId);
- }
-
-
-public:
+#include "hive_impl.h"
+#include "hive_log.h"
+#include "node_info.h"
+
+namespace NKikimr {
+namespace NHive {
+
+class THiveDrain : public NActors::TActorBootstrapped<THiveDrain>, public ISubActor {
+protected:
+ constexpr static ui64 TIMEOUT = 1800000; // 30 minutes
+ THive* Hive;
+ TVector<TFullTabletId> Tablets;
+ TVector<TFullTabletId>::iterator NextKick;
+ ui32 KickInFlight;
+ ui32 Movements;
+ TNodeId NodeId;
+ bool DownBefore = false;
+ TActorId DomainHivePipeClient;
+ TTabletId DomainHiveId = 0;
+ ui32 DomainMovements = 0;
+ TDrainSettings Settings;
+
+ TString GetLogPrefix() const {
+ return Hive->GetLogPrefix();
+ }
+
+ void PassAway() override {
+ if (DomainHivePipeClient) {
+ NTabletPipe::CloseClient(SelfId(), DomainHivePipeClient);
+ }
+ Hive->RemoveSubActor(this);
+ Hive->BalancerNodes.erase(NodeId);
+ return IActor::PassAway();
+ }
+
+ void Cleanup() override {
+ PassAway();
+ }
+
+ void ReplyAndDie(NKikimrProto::EReplyStatus status) {
+ BLOG_I("Drain " << SelfId() << " finished with " << Movements << " movements made");
+ TNodeInfo* nodeInfo = Hive->FindNode(NodeId);
+ if (nodeInfo != nullptr) {
+ if (!DownBefore) {
+ nodeInfo->SetDown(false);
+ }
+ }
+ Hive->Execute(Hive->CreateSwitchDrainOff(NodeId, std::move(Settings), status, Movements + DomainMovements));
+ PassAway();
+ }
+
+ bool CanKickNextTablet() const {
+ ui32 inFlight = Settings.DrainInFlight ? Settings.DrainInFlight : Hive->GetDrainInflight();
+ return NextKick != Tablets.end() && KickInFlight < inFlight;
+ }
+
+ void KickNextTablet() {
+ while (CanKickNextTablet()) {
+ TFullTabletId tabletId = *NextKick;
+ TTabletInfo* tablet = Hive->FindTablet(tabletId);
+ if (tablet != nullptr && tablet->IsAlive() && tablet->NodeId == NodeId) {
+ THive::TBestNodeResult result = Hive->FindBestNode(*tablet);
+ if (result.BestNode != nullptr) {
+ tablet->ActorsToNotifyOnRestart.emplace_back(SelfId()); // volatile settings, will not persist upon restart
+ ++KickInFlight;
+ ++Movements;
+ BLOG_D("Drain " << SelfId() << " moving tablet "
+ << tablet->ToString() << " " << tablet->GetResourceValues()
+ << " from node " << tablet->Node->Id << " " << tablet->Node->ResourceValues
+ << " to node " << result.BestNode->Id << " " << result.BestNode->ResourceValues);
+ Hive->TabletCounters->Cumulative()[NHive::COUNTER_DRAIN_EXECUTED].Increment(1);
+ Hive->TabletCounters->Cumulative()[NHive::COUNTER_TABLETS_MOVED].Increment(1);
+ Hive->Execute(Hive->CreateRestartTablet(tabletId, result.BestNode->Id));
+ } else {
+ Hive->TabletCounters->Cumulative()[NHive::COUNTER_DRAIN_FAILED].Increment(1);
+ BLOG_D("Drain " << SelfId() << " could not move tablet " << tablet->ToString() << " " << tablet->GetResourceValues()
+ << " from node " << tablet->Node->Id << " " << tablet->Node->ResourceValues);
+ }
+ }
+ ++NextKick;
+ }
+ if (KickInFlight == 0) {
+ return ReplyAndDie(NKikimrProto::OK);
+ }
+ }
+
+ void DomainDrainCompleted(ui32 movements = 0) {
+ Movements += movements;
+ if (DomainHivePipeClient) {
+ NTabletPipe::CloseClient(SelfId(), DomainHivePipeClient);
+ DomainHivePipeClient = {};
+ }
+ KickNextTablet();
+ }
+
+ void Handle(TEvPrivate::TEvRestartComplete::TPtr& ev) {
+ BLOG_D("Drain " << SelfId() << " received " << ev->Get()->Status << " for tablet " << ev->Get()->TabletId);
+ --KickInFlight;
+ KickNextTablet();
+ }
+
+ void Handle(TEvHive::TEvDrainNodeResult::TPtr& ev) {
+ BLOG_D("Drain " << SelfId() << " received status from domain hive " << ev->Get()->Record.ShortDebugString());
+ BLOG_I("Drain " << SelfId() << " continued for node " << NodeId << " with " << Tablets.size() << " tablets");
+ DomainDrainCompleted(ev->Get()->Record.GetMovements());
+ }
+
+ void Handle(TEvTabletPipe::TEvClientConnected::TPtr& ev) {
+ if (ev->Get()->Status != NKikimrProto::OK && DomainHiveId != 0) {
+ BLOG_W("Drain " << SelfId() << " pipe to hive " << DomainHiveId << " failed to connect");
+ DomainDrainCompleted();
+ }
+ }
+
+ void Handle(TEvTabletPipe::TEvClientDestroyed::TPtr& ev) {
+ if (ev->Get()->ClientId == DomainHivePipeClient) {
+ BLOG_W("Drain " << SelfId() << " pipe to hive " << DomainHiveId << " destroyed - retrying");
+ if (DomainHivePipeClient) {
+ NTabletPipe::CloseClient(SelfId(), DomainHivePipeClient);
+ }
+ RequestDrainFromDomainHive();
+ }
+ }
+
+ void Timeout() {
+ ReplyAndDie(NKikimrProto::TIMEOUT);
+ }
+
+ void RequestDrainFromDomainHive() {
+ NTabletPipe::TClientConfig pipeConfig;
+ pipeConfig.RetryPolicy = {.RetryLimitCount = 13};
+ DomainHivePipeClient = Register(NTabletPipe::CreateClient(SelfId(), DomainHiveId, pipeConfig));
+ THolder<TEvHive::TEvDrainNode> event = MakeHolder<TEvHive::TEvDrainNode>(NodeId);
+ event->Record.SetKeepDown(Settings.KeepDown);
+ event->Record.SetPersist(Settings.Persist);
+ event->Record.SetDrainInFlight(Settings.DrainInFlight);
+ NTabletPipe::SendData(SelfId(), DomainHivePipeClient, event.Release());
+ BLOG_I("Drain " << SelfId() << " forwarded for node " << NodeId << " to hive " << DomainHiveId);
+ }
+
+
+public:
static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
return NKikimrServices::TActivity::HIVE_BALANCER_ACTOR;
- }
-
- THiveDrain(THive* hive, TNodeId nodeId, TDrainSettings settings)
- : Hive(hive)
- , NextKick(Tablets.end())
- , KickInFlight(0)
- , Movements(0)
- , NodeId(nodeId)
- , Settings(std::move(settings))
- {}
-
- void Bootstrap() {
- TNodeInfo* nodeInfo = Hive->FindNode(NodeId);
- if (nodeInfo != nullptr) {
- {
- const auto& tablets = nodeInfo->Tablets[TTabletInfo::EVolatileState::TABLET_VOLATILE_STATE_RUNNING];
- Tablets.reserve(tablets.size());
- for (TTabletInfo* tabletInfo : tablets) {
- Tablets.push_back(tabletInfo->GetFullTabletId());
- }
- }
- NextKick = Tablets.begin();
- DownBefore = nodeInfo->Down;
- if (!DownBefore) {
- nodeInfo->SetDown(true);
- }
-
- if (nodeInfo->ServicedDomains.size() == 1) {
- TDomainInfo* domainInfo = Hive->FindDomain(nodeInfo->ServicedDomains.front());
- if (domainInfo != nullptr) {
- if (domainInfo->HiveId != 0 && domainInfo->HiveId != Hive->TabletID()) {
- DomainHiveId = domainInfo->HiveId;
- RequestDrainFromDomainHive();
- Become(&THiveDrain::StateWork, TDuration::MilliSeconds(TIMEOUT), new TEvents::TEvWakeup());
- return;
- }
- }
- }
-
- Become(&THiveDrain::StateWork, TDuration::MilliSeconds(TIMEOUT), new TEvents::TEvWakeup());
- BLOG_I("Drain " << SelfId() << " started for node " << NodeId << " with " << Tablets.size() << " tablets");
- KickNextTablet();
- } else {
- ReplyAndDie(NKikimrProto::ERROR);
- }
- }
-
- STATEFN(StateWork) {
- switch (ev->GetTypeRewrite()) {
- cFunc(TEvents::TSystem::PoisonPill, PassAway);
- hFunc(TEvPrivate::TEvRestartComplete, Handle);
- hFunc(TEvHive::TEvDrainNodeResult, Handle);
- hFunc(TEvTabletPipe::TEvClientConnected, Handle);
- hFunc(TEvTabletPipe::TEvClientDestroyed, Handle);
- cFunc(TEvents::TSystem::Wakeup, Timeout);
- }
- }
-};
-
-void THive::StartHiveDrain(TNodeId nodeId, TDrainSettings settings) {
- if (BalancerNodes.emplace(nodeId).second) {
- auto* balancer = new THiveDrain(this, nodeId, std::move(settings));
- SubActors.emplace_back(balancer);
- RegisterWithSameMailbox(balancer);
- }
-}
-
-} // NHive
-} // NKikimr
+ }
+
+ THiveDrain(THive* hive, TNodeId nodeId, TDrainSettings settings)
+ : Hive(hive)
+ , NextKick(Tablets.end())
+ , KickInFlight(0)
+ , Movements(0)
+ , NodeId(nodeId)
+ , Settings(std::move(settings))
+ {}
+
+ void Bootstrap() {
+ TNodeInfo* nodeInfo = Hive->FindNode(NodeId);
+ if (nodeInfo != nullptr) {
+ {
+ const auto& tablets = nodeInfo->Tablets[TTabletInfo::EVolatileState::TABLET_VOLATILE_STATE_RUNNING];
+ Tablets.reserve(tablets.size());
+ for (TTabletInfo* tabletInfo : tablets) {
+ Tablets.push_back(tabletInfo->GetFullTabletId());
+ }
+ }
+ NextKick = Tablets.begin();
+ DownBefore = nodeInfo->Down;
+ if (!DownBefore) {
+ nodeInfo->SetDown(true);
+ }
+
+ if (nodeInfo->ServicedDomains.size() == 1) {
+ TDomainInfo* domainInfo = Hive->FindDomain(nodeInfo->ServicedDomains.front());
+ if (domainInfo != nullptr) {
+ if (domainInfo->HiveId != 0 && domainInfo->HiveId != Hive->TabletID()) {
+ DomainHiveId = domainInfo->HiveId;
+ RequestDrainFromDomainHive();
+ Become(&THiveDrain::StateWork, TDuration::MilliSeconds(TIMEOUT), new TEvents::TEvWakeup());
+ return;
+ }
+ }
+ }
+
+ Become(&THiveDrain::StateWork, TDuration::MilliSeconds(TIMEOUT), new TEvents::TEvWakeup());
+ BLOG_I("Drain " << SelfId() << " started for node " << NodeId << " with " << Tablets.size() << " tablets");
+ KickNextTablet();
+ } else {
+ ReplyAndDie(NKikimrProto::ERROR);
+ }
+ }
+
+ STATEFN(StateWork) {
+ switch (ev->GetTypeRewrite()) {
+ cFunc(TEvents::TSystem::PoisonPill, PassAway);
+ hFunc(TEvPrivate::TEvRestartComplete, Handle);
+ hFunc(TEvHive::TEvDrainNodeResult, Handle);
+ hFunc(TEvTabletPipe::TEvClientConnected, Handle);
+ hFunc(TEvTabletPipe::TEvClientDestroyed, Handle);
+ cFunc(TEvents::TSystem::Wakeup, Timeout);
+ }
+ }
+};
+
+void THive::StartHiveDrain(TNodeId nodeId, TDrainSettings settings) {
+ if (BalancerNodes.emplace(nodeId).second) {
+ auto* balancer = new THiveDrain(this, nodeId, std::move(settings));
+ SubActors.emplace_back(balancer);
+ RegisterWithSameMailbox(balancer);
+ }
+}
+
+} // NHive
+} // NKikimr
diff --git a/ydb/core/mind/hive/fill.cpp b/ydb/core/mind/hive/fill.cpp
index 3d7b87de225..f90fa56f422 100644
--- a/ydb/core/mind/hive/fill.cpp
+++ b/ydb/core/mind/hive/fill.cpp
@@ -1,143 +1,143 @@
#include <library/cpp/actors/core/actor_bootstrapped.h>
-#include "hive_impl.h"
-#include "hive_log.h"
-#include "node_info.h"
-
-namespace NKikimr {
-namespace NHive {
-
-class THiveFill : public NActors::TActorBootstrapped<THiveFill>, public ISubActor {
-protected:
- constexpr static ui64 TIMEOUT = 1800000; // 30 minutes
- THive* Hive;
- TVector<TFullTabletId> Tablets;
- TVector<TFullTabletId>::iterator NextKick;
- ui32 KickInFlight;
- ui32 Movements;
- TNodeId NodeId;
+#include "hive_impl.h"
+#include "hive_log.h"
+#include "node_info.h"
+
+namespace NKikimr {
+namespace NHive {
+
+class THiveFill : public NActors::TActorBootstrapped<THiveFill>, public ISubActor {
+protected:
+ constexpr static ui64 TIMEOUT = 1800000; // 30 minutes
+ THive* Hive;
+ TVector<TFullTabletId> Tablets;
+ TVector<TFullTabletId>::iterator NextKick;
+ ui32 KickInFlight;
+ ui32 Movements;
+ TNodeId NodeId;
TActorId Initiator;
-
- TString GetLogPrefix() const {
- return Hive->GetLogPrefix();
- }
-
- void PassAway() override {
- BLOG_I("Fill " << SelfId() << " finished with " << Movements << " movements made");
- Hive->RemoveSubActor(this);
- Hive->BalancerNodes.erase(NodeId);
- return IActor::PassAway();
- }
-
- void Cleanup() override {
- PassAway();
- }
-
- void ReplyAndDie(NKikimrProto::EReplyStatus status, const TActorContext& ctx) {
- ctx.Send(Initiator, new TEvHive::TEvFillNodeResult(status));
- Die(ctx);
- }
-
- bool CanKickNextTablet() const {
- return NextKick != Tablets.end() && KickInFlight < Hive->GetDrainInflight();
- }
-
- void KickNextTablet(const TActorContext& ctx) {
- while (CanKickNextTablet()) {
- TFullTabletId tabletId = *NextKick;
- TTabletInfo* tablet = Hive->FindTablet(tabletId);
- if (tablet != nullptr && tablet->IsAlive() && tablet->NodeId != NodeId) {
- THive::TBestNodeResult result = Hive->FindBestNode(*tablet);
- if (result.BestNode != nullptr) {
- if (result.BestNode->Id == NodeId) {
- tablet->ActorsToNotifyOnRestart.emplace_back(SelfId()); // volatile settings, will not persist upon restart
- ++KickInFlight;
- ++Movements;
- BLOG_D("Fill " << SelfId() << " moving tablet " << tablet->ToString() << " " << tablet->GetResourceValues()
- << " from node " << tablet->Node->Id << " " << tablet->Node->ResourceValues
- << " to node " << result.BestNode->Id << " " << result.BestNode->ResourceValues);
- Hive->TabletCounters->Cumulative()[NHive::COUNTER_FILL_EXECUTED].Increment(1);
- Hive->TabletCounters->Cumulative()[NHive::COUNTER_TABLETS_MOVED].Increment(1);
- Hive->Execute(Hive->CreateRestartTablet(tablet->GetFullTabletId(), result.BestNode->Id), ctx);
- }
- }
- }
- ++NextKick;
- }
- if (KickInFlight == 0) {
- return ReplyAndDie(NKikimrProto::OK, ctx);
- }
- }
-
- void Handle(TEvPrivate::TEvRestartComplete::TPtr& ev, const TActorContext& ctx) {
- BLOG_D("Fill " << SelfId() << " received " << ev->Get()->Status << " for tablet " << ev->Get()->TabletId);
- --KickInFlight;
- KickNextTablet(ctx);
- }
-
- void Timeout(const TActorContext& ctx) {
- ReplyAndDie(NKikimrProto::TIMEOUT, ctx);
- }
-
-public:
+
+ TString GetLogPrefix() const {
+ return Hive->GetLogPrefix();
+ }
+
+ void PassAway() override {
+ BLOG_I("Fill " << SelfId() << " finished with " << Movements << " movements made");
+ Hive->RemoveSubActor(this);
+ Hive->BalancerNodes.erase(NodeId);
+ return IActor::PassAway();
+ }
+
+ void Cleanup() override {
+ PassAway();
+ }
+
+ void ReplyAndDie(NKikimrProto::EReplyStatus status, const TActorContext& ctx) {
+ ctx.Send(Initiator, new TEvHive::TEvFillNodeResult(status));
+ Die(ctx);
+ }
+
+ bool CanKickNextTablet() const {
+ return NextKick != Tablets.end() && KickInFlight < Hive->GetDrainInflight();
+ }
+
+ void KickNextTablet(const TActorContext& ctx) {
+ while (CanKickNextTablet()) {
+ TFullTabletId tabletId = *NextKick;
+ TTabletInfo* tablet = Hive->FindTablet(tabletId);
+ if (tablet != nullptr && tablet->IsAlive() && tablet->NodeId != NodeId) {
+ THive::TBestNodeResult result = Hive->FindBestNode(*tablet);
+ if (result.BestNode != nullptr) {
+ if (result.BestNode->Id == NodeId) {
+ tablet->ActorsToNotifyOnRestart.emplace_back(SelfId()); // volatile settings, will not persist upon restart
+ ++KickInFlight;
+ ++Movements;
+ BLOG_D("Fill " << SelfId() << " moving tablet " << tablet->ToString() << " " << tablet->GetResourceValues()
+ << " from node " << tablet->Node->Id << " " << tablet->Node->ResourceValues
+ << " to node " << result.BestNode->Id << " " << result.BestNode->ResourceValues);
+ Hive->TabletCounters->Cumulative()[NHive::COUNTER_FILL_EXECUTED].Increment(1);
+ Hive->TabletCounters->Cumulative()[NHive::COUNTER_TABLETS_MOVED].Increment(1);
+ Hive->Execute(Hive->CreateRestartTablet(tablet->GetFullTabletId(), result.BestNode->Id), ctx);
+ }
+ }
+ }
+ ++NextKick;
+ }
+ if (KickInFlight == 0) {
+ return ReplyAndDie(NKikimrProto::OK, ctx);
+ }
+ }
+
+ void Handle(TEvPrivate::TEvRestartComplete::TPtr& ev, const TActorContext& ctx) {
+ BLOG_D("Fill " << SelfId() << " received " << ev->Get()->Status << " for tablet " << ev->Get()->TabletId);
+ --KickInFlight;
+ KickNextTablet(ctx);
+ }
+
+ void Timeout(const TActorContext& ctx) {
+ ReplyAndDie(NKikimrProto::TIMEOUT, ctx);
+ }
+
+public:
static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
return NKikimrServices::TActivity::HIVE_BALANCER_ACTOR;
- }
-
+ }
+
THiveFill(THive* hive, TNodeId nodeId, const TActorId& initiator)
- : Hive(hive)
- , NextKick(Tablets.end())
- , KickInFlight(0)
- , Movements(0)
- , NodeId(nodeId)
- , Initiator(initiator)
- {}
-
- void Bootstrap(const TActorContext& ctx) {
- TNodeInfo* nodeInfo = Hive->FindNode(NodeId);
- if (nodeInfo != nullptr) {
- TVector<TTabletInfo*> tablets;
- tablets.reserve(Hive->Tablets.size());
- Tablets.reserve(Hive->Tablets.size());
- for (auto it = Hive->Tablets.begin(); it != Hive->Tablets.end(); ++it) {
- it->second.UpdateWeight();
- tablets.push_back(&it->second);
+ : Hive(hive)
+ , NextKick(Tablets.end())
+ , KickInFlight(0)
+ , Movements(0)
+ , NodeId(nodeId)
+ , Initiator(initiator)
+ {}
+
+ void Bootstrap(const TActorContext& ctx) {
+ TNodeInfo* nodeInfo = Hive->FindNode(NodeId);
+ if (nodeInfo != nullptr) {
+ TVector<TTabletInfo*> tablets;
+ tablets.reserve(Hive->Tablets.size());
+ Tablets.reserve(Hive->Tablets.size());
+ for (auto it = Hive->Tablets.begin(); it != Hive->Tablets.end(); ++it) {
+ it->second.UpdateWeight();
+ tablets.push_back(&it->second);
for (auto& follower : it->second.Followers) {
follower.UpdateWeight();
tablets.push_back(&follower);
- }
- }
- Sort(tablets, [](const TTabletInfo* a, const TTabletInfo* b) -> bool { return a->Weight > b->Weight; });
- for (TTabletInfo* tabletInfo : tablets) {
- Tablets.push_back(tabletInfo->GetFullTabletId());
- }
- NextKick = Tablets.begin();
- Become(&THiveFill::StateWork, ctx, TDuration::MilliSeconds(TIMEOUT), new TEvents::TEvWakeup());
- LOG_INFO_S(ctx, NKikimrServices::HIVE, "Fill " << SelfId() << " started for node " << NodeId);
- KickNextTablet(ctx);
- } else {
- ReplyAndDie(NKikimrProto::ERROR, ctx);
- }
- }
-
- STFUNC(StateWork) {
- switch (ev->GetTypeRewrite()) {
- CFunc(TEvents::TSystem::PoisonPill, Die);
- HFunc(TEvPrivate::TEvRestartComplete, Handle);
- CFunc(TEvents::TSystem::Wakeup, Timeout);
- }
- }
-};
-
+ }
+ }
+ Sort(tablets, [](const TTabletInfo* a, const TTabletInfo* b) -> bool { return a->Weight > b->Weight; });
+ for (TTabletInfo* tabletInfo : tablets) {
+ Tablets.push_back(tabletInfo->GetFullTabletId());
+ }
+ NextKick = Tablets.begin();
+ Become(&THiveFill::StateWork, ctx, TDuration::MilliSeconds(TIMEOUT), new TEvents::TEvWakeup());
+ LOG_INFO_S(ctx, NKikimrServices::HIVE, "Fill " << SelfId() << " started for node " << NodeId);
+ KickNextTablet(ctx);
+ } else {
+ ReplyAndDie(NKikimrProto::ERROR, ctx);
+ }
+ }
+
+ STFUNC(StateWork) {
+ switch (ev->GetTypeRewrite()) {
+ CFunc(TEvents::TSystem::PoisonPill, Die);
+ HFunc(TEvPrivate::TEvRestartComplete, Handle);
+ CFunc(TEvents::TSystem::Wakeup, Timeout);
+ }
+ }
+};
+
void THive::StartHiveFill(TNodeId nodeId, const TActorId& initiator) {
- if (BalancerNodes.emplace(nodeId).second) {
- auto* balancer = new THiveFill(this, nodeId, initiator);
- SubActors.emplace_back(balancer);
- RegisterWithSameMailbox(balancer);
- } else {
- Send(initiator, new TEvHive::TEvDrainNodeResult(NKikimrProto::ALREADY));
- }
-}
-
-} // NHive
-} // NKikimr
-
+ if (BalancerNodes.emplace(nodeId).second) {
+ auto* balancer = new THiveFill(this, nodeId, initiator);
+ SubActors.emplace_back(balancer);
+ RegisterWithSameMailbox(balancer);
+ } else {
+ Send(initiator, new TEvHive::TEvDrainNodeResult(NKikimrProto::ALREADY));
+ }
+}
+
+} // NHive
+} // NKikimr
+
diff --git a/ydb/core/mind/hive/follower_group.h b/ydb/core/mind/hive/follower_group.h
index a0bb1c810fa..33ab3189ffe 100644
--- a/ydb/core/mind/hive/follower_group.h
+++ b/ydb/core/mind/hive/follower_group.h
@@ -1,43 +1,43 @@
-#pragma once
-
-#include "hive.h"
+#pragma once
+
+#include "hive.h"
#include <ydb/core/protos/hive.pb.h>
#include <ydb/core/base/location.h>
-
-namespace NKikimr {
-namespace NHive {
-
+
+namespace NKikimr {
+namespace NHive {
+
struct TFollowerGroup {
TFollowerGroupId Id = 0;
bool AllowLeaderPromotion = false;
- bool AllowClientRead = false;
- bool RequireAllDataCenters = true;
- TVector<TNodeId> AllowedNodes;
- TVector<TDataCenterId> AllowedDataCenters;
+ bool AllowClientRead = false;
+ bool RequireAllDataCenters = true;
+ TVector<TNodeId> AllowedNodes;
+ TVector<TDataCenterId> AllowedDataCenters;
bool LocalNodeOnly = true; // run follower on the same node as leader
bool RequireDifferentNodes = false; // do not run followers on same nodes as another followers of the same leader
bool FollowerCountPerDataCenter = false; // PER_AZ KIKIMR-10443
-
+
TFollowerGroup() = default;
TFollowerGroup(const TFollowerGroup&) = delete;
TFollowerGroup(TFollowerGroup&&) = delete;
TFollowerGroup& operator =(const TFollowerGroup&) = delete;
TFollowerGroup& operator =(TFollowerGroup&&) = delete;
-
+
operator TFollowerGroupId() const {
- return Id;
- }
-
+ return Id;
+ }
+
TFollowerGroup& operator =(const NKikimrHive::TFollowerGroup& followerGroup) {
FollowerCount = followerGroup.GetFollowerCount();
AllowLeaderPromotion = followerGroup.GetAllowLeaderPromotion();
AllowClientRead = followerGroup.GetAllowClientRead();
RequireAllDataCenters = followerGroup.GetRequireAllDataCenters();
- {
+ {
const auto& allowedNodes(followerGroup.GetAllowedNodeIDs());
- std::copy(allowedNodes.begin(), allowedNodes.end(), std::back_inserter(AllowedNodes));
- }
- {
+ std::copy(allowedNodes.begin(), allowedNodes.end(), std::back_inserter(AllowedNodes));
+ }
+ {
if (const auto& x = followerGroup.GetAllowedDataCenters(); !x.empty()) {
AllowedDataCenters.insert(AllowedDataCenters.end(), x.begin(), x.end());
} else {
@@ -45,32 +45,32 @@ struct TFollowerGroup {
AllowedDataCenters.push_back(DataCenterToString(dataCenterId));
}
}
- }
+ }
LocalNodeOnly = followerGroup.GetLocalNodeOnly();
RequireDifferentNodes = followerGroup.GetRequireDifferentNodes();
FollowerCountPerDataCenter = followerGroup.GetFollowerCountPerDataCenter();
- return *this;
- }
-
+ return *this;
+ }
+
ui32 GetRawFollowerCount() const {
return FollowerCount;
- }
-
- ui32 GetComputedFollowerCount(ui32 dataCenters) const {
+ }
+
+ ui32 GetComputedFollowerCount(ui32 dataCenters) const {
if (FollowerCountPerDataCenter) {
- return FollowerCount * dataCenters;
- } else {
+ return FollowerCount * dataCenters;
+ } else {
return FollowerCount;
- }
- }
-
+ }
+ }
+
void SetFollowerCount(ui32 followerCount) {
FollowerCount = followerCount;
- }
-
-private:
+ }
+
+private:
ui32 FollowerCount = 0;
-};
-
-} // NHive
-} // NKikimr
+};
+
+} // NHive
+} // NKikimr
diff --git a/ydb/core/mind/hive/follower_tablet_info.cpp b/ydb/core/mind/hive/follower_tablet_info.cpp
index 605bd36e559..44ba11dc8a0 100644
--- a/ydb/core/mind/hive/follower_tablet_info.cpp
+++ b/ydb/core/mind/hive/follower_tablet_info.cpp
@@ -1,16 +1,16 @@
#include "follower_tablet_info.h"
#include "follower_group.h"
#include "leader_tablet_info.h"
-
-namespace NKikimr {
-namespace NHive {
-
+
+namespace NKikimr {
+namespace NHive {
+
TFollowerTabletInfo::TFollowerTabletInfo(TLeaderTabletInfo& leaderTablet, TFollowerId id, TFollowerGroup& followerGroup)
: TTabletInfo(ETabletRole::Follower, leaderTablet.Hive)
, LeaderTablet(leaderTablet)
- , Id(id)
+ , Id(id)
, FollowerGroup(followerGroup)
-{}
-
-}
-}
+{}
+
+}
+}
diff --git a/ydb/core/mind/hive/follower_tablet_info.h b/ydb/core/mind/hive/follower_tablet_info.h
index ed06ec52696..730f6ae4a61 100644
--- a/ydb/core/mind/hive/follower_tablet_info.h
+++ b/ydb/core/mind/hive/follower_tablet_info.h
@@ -1,22 +1,22 @@
-#pragma once
-
-#include "hive.h"
-#include "tablet_info.h"
+#pragma once
+
+#include "hive.h"
+#include "tablet_info.h"
#include "follower_group.h"
-
-namespace NKikimr {
-namespace NHive {
-
+
+namespace NKikimr {
+namespace NHive {
+
struct TFollowerGroup;
-
+
struct TFollowerTabletInfo : TTabletInfo {
-public:
+public:
TLeaderTabletInfo& LeaderTablet;
TFollowerId Id;
TFollowerGroup& FollowerGroup;
-
+
TFollowerTabletInfo(TLeaderTabletInfo& leaderTablet, TFollowerId id, TFollowerGroup& followerGroup);
-};
-
-} // NHive
-} // NKikimr
+};
+
+} // NHive
+} // NKikimr
diff --git a/ydb/core/mind/hive/hive.cpp b/ydb/core/mind/hive/hive.cpp
index f4b56c1513d..58c64db8323 100644
--- a/ydb/core/mind/hive/hive.cpp
+++ b/ydb/core/mind/hive/hive.cpp
@@ -1,70 +1,70 @@
-#include "hive.h"
-
-namespace NKikimr {
-namespace NHive {
-
-TString ETabletStateName(ETabletState value) {
- switch (value) {
- case ETabletState::Unknown: return "Unknown";
- case ETabletState::GroupAssignment: return "GroupAssignment";
- case ETabletState::StoppingInGroupAssignment: return "StoppingInGroupAssignment";
- case ETabletState::Stopping: return "Stopping";
- case ETabletState::Stopped: return "Stopped";
- case ETabletState::ReadyToWork: return "ReadyToWork";
- case ETabletState::BlockStorage: return "BlockStorage";
- case ETabletState::Deleting: return "Deleting";
- default: return Sprintf("%d", static_cast<int>(value));
- }
-}
-
+#include "hive.h"
+
+namespace NKikimr {
+namespace NHive {
+
+TString ETabletStateName(ETabletState value) {
+ switch (value) {
+ case ETabletState::Unknown: return "Unknown";
+ case ETabletState::GroupAssignment: return "GroupAssignment";
+ case ETabletState::StoppingInGroupAssignment: return "StoppingInGroupAssignment";
+ case ETabletState::Stopping: return "Stopping";
+ case ETabletState::Stopped: return "Stopped";
+ case ETabletState::ReadyToWork: return "ReadyToWork";
+ case ETabletState::BlockStorage: return "BlockStorage";
+ case ETabletState::Deleting: return "Deleting";
+ default: return Sprintf("%d", static_cast<int>(value));
+ }
+}
+
TString EFollowerStrategyName(EFollowerStrategy value) {
- switch (value) {
+ switch (value) {
case EFollowerStrategy::Unknown: return "Unknown";
case EFollowerStrategy::Backup: return "Backup";
case EFollowerStrategy::Read: return "Read";
- default: return Sprintf("%d", static_cast<int>(value));
- }
-}
-
-TResourceNormalizedValues NormalizeRawValues(const TResourceRawValues& values, const TResourceRawValues& maximum) {
- TResourceNormalizedValues normValues = {};
- if (std::get<NMetrics::EResource::Counter>(maximum) != 0) {
- std::get<NMetrics::EResource::Counter>(normValues) =
- static_cast<double>(std::get<NMetrics::EResource::Counter>(values)) / std::get<NMetrics::EResource::Counter>(maximum);
- }
- if (std::get<NMetrics::EResource::CPU>(maximum) != 0) {
- std::get<NMetrics::EResource::CPU>(normValues) =
- static_cast<double>(std::get<NMetrics::EResource::CPU>(values)) / std::get<NMetrics::EResource::CPU>(maximum);
- }
- if (std::get<NMetrics::EResource::Memory>(maximum) != 0) {
- std::get<NMetrics::EResource::Memory>(normValues) =
- static_cast<double>(std::get<NMetrics::EResource::Memory>(values)) / std::get<NMetrics::EResource::Memory>(maximum);
- }
- if (std::get<NMetrics::EResource::Network>(maximum) != 0) {
- std::get<NMetrics::EResource::Network>(normValues) =
- static_cast<double>(std::get<NMetrics::EResource::Network>(values)) / std::get<NMetrics::EResource::Network>(maximum);
- }
- return normValues;
-}
-
-NMetrics::EResource GetDominantResourceType(const TResourceRawValues& values, const TResourceRawValues& maximum) {
- TResourceNormalizedValues normValues = NormalizeRawValues(values, maximum);
- NMetrics::EResource dominant = NMetrics::EResource::Counter;
- auto value = std::get<NMetrics::EResource::Counter>(normValues);
- if (std::get<NMetrics::EResource::CPU>(normValues) > value) {
- dominant = NMetrics::EResource::CPU;
- value = std::get<NMetrics::EResource::CPU>(normValues);
- }
- if (std::get<NMetrics::EResource::Memory>(normValues) > value) {
- dominant = NMetrics::EResource::Memory;
- value = std::get<NMetrics::EResource::Memory>(normValues);
- }
- if (std::get<NMetrics::EResource::Network>(normValues) > value) {
- dominant = NMetrics::EResource::Network;
- value = std::get<NMetrics::EResource::Network>(normValues);
- }
- return dominant;
-}
-
-}
-}
+ default: return Sprintf("%d", static_cast<int>(value));
+ }
+}
+
+TResourceNormalizedValues NormalizeRawValues(const TResourceRawValues& values, const TResourceRawValues& maximum) {
+ TResourceNormalizedValues normValues = {};
+ if (std::get<NMetrics::EResource::Counter>(maximum) != 0) {
+ std::get<NMetrics::EResource::Counter>(normValues) =
+ static_cast<double>(std::get<NMetrics::EResource::Counter>(values)) / std::get<NMetrics::EResource::Counter>(maximum);
+ }
+ if (std::get<NMetrics::EResource::CPU>(maximum) != 0) {
+ std::get<NMetrics::EResource::CPU>(normValues) =
+ static_cast<double>(std::get<NMetrics::EResource::CPU>(values)) / std::get<NMetrics::EResource::CPU>(maximum);
+ }
+ if (std::get<NMetrics::EResource::Memory>(maximum) != 0) {
+ std::get<NMetrics::EResource::Memory>(normValues) =
+ static_cast<double>(std::get<NMetrics::EResource::Memory>(values)) / std::get<NMetrics::EResource::Memory>(maximum);
+ }
+ if (std::get<NMetrics::EResource::Network>(maximum) != 0) {
+ std::get<NMetrics::EResource::Network>(normValues) =
+ static_cast<double>(std::get<NMetrics::EResource::Network>(values)) / std::get<NMetrics::EResource::Network>(maximum);
+ }
+ return normValues;
+}
+
+NMetrics::EResource GetDominantResourceType(const TResourceRawValues& values, const TResourceRawValues& maximum) {
+ TResourceNormalizedValues normValues = NormalizeRawValues(values, maximum);
+ NMetrics::EResource dominant = NMetrics::EResource::Counter;
+ auto value = std::get<NMetrics::EResource::Counter>(normValues);
+ if (std::get<NMetrics::EResource::CPU>(normValues) > value) {
+ dominant = NMetrics::EResource::CPU;
+ value = std::get<NMetrics::EResource::CPU>(normValues);
+ }
+ if (std::get<NMetrics::EResource::Memory>(normValues) > value) {
+ dominant = NMetrics::EResource::Memory;
+ value = std::get<NMetrics::EResource::Memory>(normValues);
+ }
+ if (std::get<NMetrics::EResource::Network>(normValues) > value) {
+ dominant = NMetrics::EResource::Network;
+ value = std::get<NMetrics::EResource::Network>(normValues);
+ }
+ return dominant;
+}
+
+}
+}
diff --git a/ydb/core/mind/hive/hive.h b/ydb/core/mind/hive/hive.h
index c9204f0c667..cce565aecd6 100644
--- a/ydb/core/mind/hive/hive.h
+++ b/ydb/core/mind/hive/hive.h
@@ -1,9 +1,9 @@
#pragma once
-#include <bitset>
-
-#include <util/generic/queue.h>
-#include <util/random/random.h>
-
+#include <bitset>
+
+#include <util/generic/queue.h>
+#include <util/random/random.h>
+
#include <ydb/core/base/hive.h>
#include <ydb/core/base/statestorage.h>
#include <ydb/core/base/blobstorage.h>
@@ -24,121 +24,121 @@
#include <ydb/core/tablet/tablet_impl.h>
#include <ydb/core/tablet_flat/flat_executor_counters.h>
-
+
#include <library/cpp/actors/core/interconnect.h>
#include <library/cpp/actors/core/hfunc.h>
-
+
#include <ydb/core/tablet/tablet_metrics.h>
-
+
namespace NKikimr {
-namespace NHive {
-
-using NTabletFlatExecutor::TTabletExecutedFlat;
-using NTabletFlatExecutor::TTransactionContext;
-using NTabletFlatExecutor::TExecutorCounters;
-
-using TTabletId = ui64;
-using TTabletCategoryId = ui64;
-using TNodeId = ui32;
+namespace NHive {
+
+using NTabletFlatExecutor::TTabletExecutedFlat;
+using NTabletFlatExecutor::TTransactionContext;
+using NTabletFlatExecutor::TExecutorCounters;
+
+using TTabletId = ui64;
+using TTabletCategoryId = ui64;
+using TNodeId = ui32;
using TDataCenterId = TString;
using TFollowerId = ui32;
using TFollowerGroupId = ui32;
-using TStorageGroupId = ui32;
+using TStorageGroupId = ui32;
using TFullTabletId = std::pair<TTabletId, TFollowerId>;
-using TObjectId = ui64; // schema object id, used to organize tablets of the same schema object
-using TOwnerId = ui64;
-using TResourceRawValues = std::tuple<i64, i64, i64, i64>; // CPU, Memory, Network, Counter
-using TResourceNormalizedValues = std::tuple<double, double, double, double>;
-using TOwnerIdxType = NScheme::TPairUi64Ui64;
-
-static constexpr std::size_t MAX_TABLET_CHANNELS = 256;
-
-enum class ETabletState : ui64 {
- Unknown = 0,
- GroupAssignment = 50,
- StoppingInGroupAssignment = 98,
- Stopping = 99,
- Stopped = 100,
- ReadyToWork = 200,
- BlockStorage, // blob storage block request for previous group of 0 channel
- Deleting,
-};
-
-TString ETabletStateName(ETabletState value);
-
+using TObjectId = ui64; // schema object id, used to organize tablets of the same schema object
+using TOwnerId = ui64;
+using TResourceRawValues = std::tuple<i64, i64, i64, i64>; // CPU, Memory, Network, Counter
+using TResourceNormalizedValues = std::tuple<double, double, double, double>;
+using TOwnerIdxType = NScheme::TPairUi64Ui64;
+
+static constexpr std::size_t MAX_TABLET_CHANNELS = 256;
+
+enum class ETabletState : ui64 {
+ Unknown = 0,
+ GroupAssignment = 50,
+ StoppingInGroupAssignment = 98,
+ Stopping = 99,
+ Stopped = 100,
+ ReadyToWork = 200,
+ BlockStorage, // blob storage block request for previous group of 0 channel
+ Deleting,
+};
+
+TString ETabletStateName(ETabletState value);
+
enum class EFollowerStrategy : ui32 {
- Unknown,
- Backup,
- Read,
-};
-
+ Unknown,
+ Backup,
+ Read,
+};
+
TString EFollowerStrategyName(EFollowerStrategy value);
-
-struct ISubActor {
- virtual void Cleanup() = 0;
-};
-
-TResourceNormalizedValues NormalizeRawValues(const TResourceRawValues& values, const TResourceRawValues& maximum);
-NMetrics::EResource GetDominantResourceType(const TResourceRawValues& values, const TResourceRawValues& maximum);
-
-template <typename... ResourceTypes>
-inline std::tuple<ResourceTypes...> GetStDev(const TVector<std::tuple<ResourceTypes...>>& values) {
- std::tuple<ResourceTypes...> sum;
- if (values.empty())
- return sum;
- for (const auto& v : values) {
- sum = sum + v;
- }
- auto mean = sum / values.size();
- sum = std::tuple<ResourceTypes...>();
- for (const auto& v : values) {
- auto diff = v - mean;
- sum = sum + diff * diff;
- }
- auto div = sum / values.size();
- auto st_dev = sqrt(div);
- return tuple_cast<ResourceTypes...>::cast(st_dev);
-}
-
-class THive;
-
-struct THiveSharedSettings {
- NKikimrConfig::THiveConfig CurrentConfig;
-
- NKikimrConfig::THiveConfig::EHiveStorageBalanceStrategy GetStorageBalanceStrategy() const {
- return CurrentConfig.GetStorageBalanceStrategy();
- }
-
- NKikimrConfig::THiveConfig::EHiveStorageSelectStrategy GetStorageSelectStrategy() const {
- return CurrentConfig.GetStorageSelectStrategy();
- }
-
- NKikimrConfig::THiveConfig::EHiveTabletBalanceStrategy GetTabletBalanceStrategy() const {
- return CurrentConfig.GetTabletBalanceStrategy();
- }
-
- NKikimrConfig::THiveConfig::EHiveNodeBalanceStrategy GetNodeBalanceStrategy() const {
- return CurrentConfig.GetNodeBalanceStrategy();
- }
-
- NKikimrConfig::THiveConfig::EHiveNodeSelectStrategy GetNodeSelectStrategy() const {
- return CurrentConfig.GetNodeSelectStrategy();
- }
-
- double GetStorageOvercommit() const {
- return CurrentConfig.GetStorageOvercommit();
- }
-
- bool GetStorageSafeMode() const {
- return CurrentConfig.GetStorageSafeMode();
- }
-};
-
-struct TDrainSettings {
- bool Persist = true;
- bool KeepDown = false;
- ui32 DrainInFlight = 0;
-};
-
-} // NHive
-} // NKikimr
+
+struct ISubActor {
+ virtual void Cleanup() = 0;
+};
+
+TResourceNormalizedValues NormalizeRawValues(const TResourceRawValues& values, const TResourceRawValues& maximum);
+NMetrics::EResource GetDominantResourceType(const TResourceRawValues& values, const TResourceRawValues& maximum);
+
+template <typename... ResourceTypes>
+inline std::tuple<ResourceTypes...> GetStDev(const TVector<std::tuple<ResourceTypes...>>& values) {
+ std::tuple<ResourceTypes...> sum;
+ if (values.empty())
+ return sum;
+ for (const auto& v : values) {
+ sum = sum + v;
+ }
+ auto mean = sum / values.size();
+ sum = std::tuple<ResourceTypes...>();
+ for (const auto& v : values) {
+ auto diff = v - mean;
+ sum = sum + diff * diff;
+ }
+ auto div = sum / values.size();
+ auto st_dev = sqrt(div);
+ return tuple_cast<ResourceTypes...>::cast(st_dev);
+}
+
+class THive;
+
+struct THiveSharedSettings {
+ NKikimrConfig::THiveConfig CurrentConfig;
+
+ NKikimrConfig::THiveConfig::EHiveStorageBalanceStrategy GetStorageBalanceStrategy() const {
+ return CurrentConfig.GetStorageBalanceStrategy();
+ }
+
+ NKikimrConfig::THiveConfig::EHiveStorageSelectStrategy GetStorageSelectStrategy() const {
+ return CurrentConfig.GetStorageSelectStrategy();
+ }
+
+ NKikimrConfig::THiveConfig::EHiveTabletBalanceStrategy GetTabletBalanceStrategy() const {
+ return CurrentConfig.GetTabletBalanceStrategy();
+ }
+
+ NKikimrConfig::THiveConfig::EHiveNodeBalanceStrategy GetNodeBalanceStrategy() const {
+ return CurrentConfig.GetNodeBalanceStrategy();
+ }
+
+ NKikimrConfig::THiveConfig::EHiveNodeSelectStrategy GetNodeSelectStrategy() const {
+ return CurrentConfig.GetNodeSelectStrategy();
+ }
+
+ double GetStorageOvercommit() const {
+ return CurrentConfig.GetStorageOvercommit();
+ }
+
+ bool GetStorageSafeMode() const {
+ return CurrentConfig.GetStorageSafeMode();
+ }
+};
+
+struct TDrainSettings {
+ bool Persist = true;
+ bool KeepDown = false;
+ ui32 DrainInFlight = 0;
+};
+
+} // NHive
+} // NKikimr
diff --git a/ydb/core/mind/hive/hive_domains.cpp b/ydb/core/mind/hive/hive_domains.cpp
index 8980cfcaf0d..4ddb952aec7 100644
--- a/ydb/core/mind/hive/hive_domains.cpp
+++ b/ydb/core/mind/hive/hive_domains.cpp
@@ -1,83 +1,83 @@
-#include "hive_impl.h"
-#include "hive_log.h"
-
-namespace NKikimr {
-namespace NHive {
-
-void TDomainsView::RegisterNode(const TNodeInfo& node) {
- for (auto &domainKey: node.ServicedDomains) {
- BLOG_TRACE("Node(" << node.Id << ")"
- << " RegisterInDomain (" << domainKey << ") : " << TotalCount[domainKey] << " -> " << TotalCount[domainKey] + 1);
- ++TotalCount[domainKey];
- }
-}
-
-void TDomainsView::DeregisterNode(const TNodeInfo& node) {
- for (auto &domainKey: node.ServicedDomains) {
- BLOG_TRACE("Node(" << node.Id << ")"
- << " DeregisterInDomains (" << domainKey << ") : " << TotalCount[domainKey] << " -> " << TotalCount[domainKey] - 1);
- Y_VERIFY(TotalCount[domainKey], "try decrement empty counter for DomainKey %s", ToString(domainKey).c_str());
- --TotalCount[domainKey];
- }
-}
-
-bool THive::SeenDomain(TSubDomainKey domain) {
- auto emResult = Domains.emplace(domain, TDomainInfo());
- if (emResult.second || emResult.first->second.Path.empty()) {
- emResult.first->second.Path = TStringBuilder() << domain;
- ResolveDomain(domain);
- return false;
- }
- return true;
-}
-
-void THive::ResolveDomain(TSubDomainKey domain) {
+#include "hive_impl.h"
+#include "hive_log.h"
+
+namespace NKikimr {
+namespace NHive {
+
+void TDomainsView::RegisterNode(const TNodeInfo& node) {
+ for (auto &domainKey: node.ServicedDomains) {
+ BLOG_TRACE("Node(" << node.Id << ")"
+ << " RegisterInDomain (" << domainKey << ") : " << TotalCount[domainKey] << " -> " << TotalCount[domainKey] + 1);
+ ++TotalCount[domainKey];
+ }
+}
+
+void TDomainsView::DeregisterNode(const TNodeInfo& node) {
+ for (auto &domainKey: node.ServicedDomains) {
+ BLOG_TRACE("Node(" << node.Id << ")"
+ << " DeregisterInDomains (" << domainKey << ") : " << TotalCount[domainKey] << " -> " << TotalCount[domainKey] - 1);
+ Y_VERIFY(TotalCount[domainKey], "try decrement empty counter for DomainKey %s", ToString(domainKey).c_str());
+ --TotalCount[domainKey];
+ }
+}
+
+bool THive::SeenDomain(TSubDomainKey domain) {
+ auto emResult = Domains.emplace(domain, TDomainInfo());
+ if (emResult.second || emResult.first->second.Path.empty()) {
+ emResult.first->second.Path = TStringBuilder() << domain;
+ ResolveDomain(domain);
+ return false;
+ }
+ return true;
+}
+
+void THive::ResolveDomain(TSubDomainKey domain) {
THolder<NSchemeCache::TSchemeCacheNavigate> request = MakeHolder<NSchemeCache::TSchemeCacheNavigate>();
- request->ResultSet.emplace_back();
- auto& entry = request->ResultSet.back();
- entry.TableId = TTableId(domain.first, domain.second);
- entry.Operation = NSchemeCache::TSchemeCacheNavigate::EOp::OpPath;
- entry.RequestType = NSchemeCache::TSchemeCacheNavigate::TEntry::ERequestType::ByTableId;
- entry.RedirectRequired = false;
- BLOG_D("Resolving domain " << entry.TableId);
- Send(MakeSchemeCacheID(), new TEvTxProxySchemeCache::TEvNavigateKeySet(request.Release()));
-}
-
-void THive::Handle(TEvTxProxySchemeCache::TEvNavigateKeySetResult::TPtr& ev) {
- NSchemeCache::TSchemeCacheNavigate* request = ev->Get()->Request.Get();
- if (!request->ResultSet.empty()) {
- auto& entry = request->ResultSet.front();
- if (entry.Status == NSchemeCache::TSchemeCacheNavigate::EStatus::Ok) {
- TSubDomainKey key(entry.TableId.PathId.OwnerId, entry.TableId.PathId.LocalPathId);
- TString path = CanonizePath(entry.Path);
- Domains[key].Path = path;
- if (entry.DomainInfo) {
- Domains[key].HiveId = entry.DomainInfo->Params.GetHive();
- }
- BLOG_D("Received NavigateKeySetResult for domain " << entry.TableId << " with path " << path);
- Execute(CreateUpdateDomain(key));
- } else {
- BLOG_W("Received NavigateKeySetResult for domain " << entry.TableId << " with status " << entry.Status);
- }
- } else {
- BLOG_W("Received empty NavigateKeySetResult");
- }
-}
-
-TString THive::GetDomainName(TSubDomainKey domain) {
- auto itDomain = Domains.find(domain);
- if (itDomain != Domains.end()) {
- if (!itDomain->second.Path.empty()) {
- return itDomain->second.Path;
- }
- } else {
- SeenDomain(domain);
- }
- if (domain == TSubDomainKey()) {
- return "<empty-subdomain-key>";
- }
- return TStringBuilder() << domain;
-}
-
-} // NHive
-} // NKikimr
+ request->ResultSet.emplace_back();
+ auto& entry = request->ResultSet.back();
+ entry.TableId = TTableId(domain.first, domain.second);
+ entry.Operation = NSchemeCache::TSchemeCacheNavigate::EOp::OpPath;
+ entry.RequestType = NSchemeCache::TSchemeCacheNavigate::TEntry::ERequestType::ByTableId;
+ entry.RedirectRequired = false;
+ BLOG_D("Resolving domain " << entry.TableId);
+ Send(MakeSchemeCacheID(), new TEvTxProxySchemeCache::TEvNavigateKeySet(request.Release()));
+}
+
+void THive::Handle(TEvTxProxySchemeCache::TEvNavigateKeySetResult::TPtr& ev) {
+ NSchemeCache::TSchemeCacheNavigate* request = ev->Get()->Request.Get();
+ if (!request->ResultSet.empty()) {
+ auto& entry = request->ResultSet.front();
+ if (entry.Status == NSchemeCache::TSchemeCacheNavigate::EStatus::Ok) {
+ TSubDomainKey key(entry.TableId.PathId.OwnerId, entry.TableId.PathId.LocalPathId);
+ TString path = CanonizePath(entry.Path);
+ Domains[key].Path = path;
+ if (entry.DomainInfo) {
+ Domains[key].HiveId = entry.DomainInfo->Params.GetHive();
+ }
+ BLOG_D("Received NavigateKeySetResult for domain " << entry.TableId << " with path " << path);
+ Execute(CreateUpdateDomain(key));
+ } else {
+ BLOG_W("Received NavigateKeySetResult for domain " << entry.TableId << " with status " << entry.Status);
+ }
+ } else {
+ BLOG_W("Received empty NavigateKeySetResult");
+ }
+}
+
+TString THive::GetDomainName(TSubDomainKey domain) {
+ auto itDomain = Domains.find(domain);
+ if (itDomain != Domains.end()) {
+ if (!itDomain->second.Path.empty()) {
+ return itDomain->second.Path;
+ }
+ } else {
+ SeenDomain(domain);
+ }
+ if (domain == TSubDomainKey()) {
+ return "<empty-subdomain-key>";
+ }
+ return TStringBuilder() << domain;
+}
+
+} // NHive
+} // NKikimr
diff --git a/ydb/core/mind/hive/hive_domains.h b/ydb/core/mind/hive/hive_domains.h
index 10176c50498..b5b23b0b831 100644
--- a/ydb/core/mind/hive/hive_domains.h
+++ b/ydb/core/mind/hive/hive_domains.h
@@ -1,48 +1,48 @@
-#pragma once
-
-#include "hive.h"
-
-namespace NKikimr {
-namespace NHive {
-
-struct TTabletInfo;
-struct TNodeInfo;
-
-class TDomainsView {
-public:
- ui32 CountNodes(const TSubDomainKey& domain) const {
- auto it = TotalCount.find(domain);
- if (it == TotalCount.end()) {
- return 0;
- }
- return it->second;
- }
-
- bool IsEmpty(const TSubDomainKey& domain) const {
- return CountNodes(domain) == 0;
- }
-
- void RegisterNode(const TNodeInfo& node);
- void DeregisterNode(const TNodeInfo& node);
-
- TString AsString() const {
- TStringBuilder result;
- result << '[';
- for (auto it = TotalCount.begin(); it != TotalCount.end(); ++it) {
- const auto &x = *it;
- if (it != TotalCount.begin()) {
- result << ", ";
- }
- result << x.first << '=' << x.second;
- }
- result << ']';
- return result;
- }
-
-private:
- std::unordered_map<TSubDomainKey, ui32, THash<TSubDomainKey>> TotalCount;
-};
-
-
-} // NHive
-} // NKikimr
+#pragma once
+
+#include "hive.h"
+
+namespace NKikimr {
+namespace NHive {
+
+struct TTabletInfo;
+struct TNodeInfo;
+
+class TDomainsView {
+public:
+ ui32 CountNodes(const TSubDomainKey& domain) const {
+ auto it = TotalCount.find(domain);
+ if (it == TotalCount.end()) {
+ return 0;
+ }
+ return it->second;
+ }
+
+ bool IsEmpty(const TSubDomainKey& domain) const {
+ return CountNodes(domain) == 0;
+ }
+
+ void RegisterNode(const TNodeInfo& node);
+ void DeregisterNode(const TNodeInfo& node);
+
+ TString AsString() const {
+ TStringBuilder result;
+ result << '[';
+ for (auto it = TotalCount.begin(); it != TotalCount.end(); ++it) {
+ const auto &x = *it;
+ if (it != TotalCount.begin()) {
+ result << ", ";
+ }
+ result << x.first << '=' << x.second;
+ }
+ result << ']';
+ return result;
+ }
+
+private:
+ std::unordered_map<TSubDomainKey, ui32, THash<TSubDomainKey>> TotalCount;
+};
+
+
+} // NHive
+} // NKikimr
diff --git a/ydb/core/mind/hive/hive_events.h b/ydb/core/mind/hive/hive_events.h
index 140a0006c5b..9e26edc7a83 100644
--- a/ydb/core/mind/hive/hive_events.h
+++ b/ydb/core/mind/hive/hive_events.h
@@ -1,84 +1,84 @@
-#pragma once
-
+#pragma once
+
#include <library/cpp/actors/core/events.h>
#include <library/cpp/actors/core/event_local.h>
-#include "hive.h"
-#include "tablet_info.h"
-#include "node_info.h"
-
-namespace NKikimr {
-namespace NHive {
-
-using namespace NActors;
-
-struct TEvPrivate {
- enum EEv {
- EvKickTablet = EventSpaceBegin(TEvents::ES_PRIVATE),
- EvProcessBootQueue,
- EvProcessDisconnectNode,
- EvPostponeProcessBootQueue,
- EvBootTablets,
- EvCheckTabletNodeAlive,
- EvProcessTabletBalancer,
- EvUnlockTabletReconnectTimeout,
- EvProcessPendingOperations,
- EvRestartComplete,
- EvEnd
- };
-
- static_assert(EvEnd < EventSpaceEnd(TEvents::ES_PRIVATE), "expect EvEnd < EventSpaceEnd(TEvents::ES_PRIVATE)");
-
- struct TEvKickTablet : TEventLocal<TEvKickTablet, EvKickTablet> {
+#include "hive.h"
+#include "tablet_info.h"
+#include "node_info.h"
+
+namespace NKikimr {
+namespace NHive {
+
+using namespace NActors;
+
+struct TEvPrivate {
+ enum EEv {
+ EvKickTablet = EventSpaceBegin(TEvents::ES_PRIVATE),
+ EvProcessBootQueue,
+ EvProcessDisconnectNode,
+ EvPostponeProcessBootQueue,
+ EvBootTablets,
+ EvCheckTabletNodeAlive,
+ EvProcessTabletBalancer,
+ EvUnlockTabletReconnectTimeout,
+ EvProcessPendingOperations,
+ EvRestartComplete,
+ EvEnd
+ };
+
+ static_assert(EvEnd < EventSpaceEnd(TEvents::ES_PRIVATE), "expect EvEnd < EventSpaceEnd(TEvents::ES_PRIVATE)");
+
+ struct TEvKickTablet : TEventLocal<TEvKickTablet, EvKickTablet> {
std::pair<TTabletId, TFollowerId> TabletId;
-
- TEvKickTablet(const TTabletInfo& tablet)
- : TabletId(tablet.GetFullTabletId())
- {}
- };
-
- struct TEvProcessBootQueue : TEventLocal<TEvProcessBootQueue, EvProcessBootQueue> {};
-
- struct TEvPostponeProcessBootQueue : TEventLocal<TEvPostponeProcessBootQueue, EvPostponeProcessBootQueue> {};
-
- struct TEvProcessDisconnectNode : TEventLocal<TEvProcessDisconnectNode, EvProcessDisconnectNode> {
- ui32 NodeId;
- TActorId Local;
- TInstant StartTime;
+
+ TEvKickTablet(const TTabletInfo& tablet)
+ : TabletId(tablet.GetFullTabletId())
+ {}
+ };
+
+ struct TEvProcessBootQueue : TEventLocal<TEvProcessBootQueue, EvProcessBootQueue> {};
+
+ struct TEvPostponeProcessBootQueue : TEventLocal<TEvPostponeProcessBootQueue, EvPostponeProcessBootQueue> {};
+
+ struct TEvProcessDisconnectNode : TEventLocal<TEvProcessDisconnectNode, EvProcessDisconnectNode> {
+ ui32 NodeId;
+ TActorId Local;
+ TInstant StartTime;
TMap<ui64,TVector<std::pair<TTabletId, TFollowerId>>> Tablets;
- };
-
- struct TEvBootTablets : TEventLocal<TEvBootTablets, EvBootTablets> {};
-
- struct TEvCheckTabletNodeAlive : TEventLocal<TEvCheckTabletNodeAlive, EvCheckTabletNodeAlive> {
- ui64 TabletId;
- };
-
- struct TEvProcessTabletBalancer : TEventLocal<TEvProcessTabletBalancer, EvProcessTabletBalancer> {};
-
- struct TEvUnlockTabletReconnectTimeout : TEventLocal<TEvUnlockTabletReconnectTimeout, EvUnlockTabletReconnectTimeout> {
- ui64 TabletId;
- ui64 SeqNo;
-
- TEvUnlockTabletReconnectTimeout() = default;
-
- explicit TEvUnlockTabletReconnectTimeout(ui64 tabletId, ui64 seqNo)
- : TabletId(tabletId)
- , SeqNo(seqNo)
- {}
- };
-
- struct TEvRestartComplete : TEventLocal<TEvRestartComplete, EvRestartComplete> {
- TFullTabletId TabletId;
- TStringBuf Status;
-
- TEvRestartComplete(TFullTabletId tabletId, TStringBuf status)
- : TabletId(tabletId)
- , Status(status)
- {}
- };
-
- struct TEvProcessPendingOperations : TEventLocal<TEvProcessPendingOperations, EvProcessPendingOperations> {};
-};
-
-} // NHive
-} // NKikimr
+ };
+
+ struct TEvBootTablets : TEventLocal<TEvBootTablets, EvBootTablets> {};
+
+ struct TEvCheckTabletNodeAlive : TEventLocal<TEvCheckTabletNodeAlive, EvCheckTabletNodeAlive> {
+ ui64 TabletId;
+ };
+
+ struct TEvProcessTabletBalancer : TEventLocal<TEvProcessTabletBalancer, EvProcessTabletBalancer> {};
+
+ struct TEvUnlockTabletReconnectTimeout : TEventLocal<TEvUnlockTabletReconnectTimeout, EvUnlockTabletReconnectTimeout> {
+ ui64 TabletId;
+ ui64 SeqNo;
+
+ TEvUnlockTabletReconnectTimeout() = default;
+
+ explicit TEvUnlockTabletReconnectTimeout(ui64 tabletId, ui64 seqNo)
+ : TabletId(tabletId)
+ , SeqNo(seqNo)
+ {}
+ };
+
+ struct TEvRestartComplete : TEventLocal<TEvRestartComplete, EvRestartComplete> {
+ TFullTabletId TabletId;
+ TStringBuf Status;
+
+ TEvRestartComplete(TFullTabletId tabletId, TStringBuf status)
+ : TabletId(tabletId)
+ , Status(status)
+ {}
+ };
+
+ struct TEvProcessPendingOperations : TEventLocal<TEvProcessPendingOperations, EvProcessPendingOperations> {};
+};
+
+} // NHive
+} // NKikimr
diff --git a/ydb/core/mind/hive/hive_impl.cpp b/ydb/core/mind/hive/hive_impl.cpp
index 69e0aec8749..58ca2ac3e43 100644
--- a/ydb/core/mind/hive/hive_impl.cpp
+++ b/ydb/core/mind/hive/hive_impl.cpp
@@ -1,730 +1,730 @@
-#include "hive_impl.h"
-#include "hive_log.h"
+#include "hive_impl.h"
+#include "hive_log.h"
#include <ydb/core/cms/console/console.h>
#include <ydb/core/cms/console/configs_dispatcher.h>
#include <ydb/core/protos/counters_hive.pb.h>
#include <ydb/core/util/tuples.h>
#include <ydb/core/util/yverify_stream.h>
#include <library/cpp/actors/interconnect/interconnect.h>
-#include <util/generic/array_ref.h>
-
-template <>
-inline IOutputStream& operator <<(IOutputStream& out, const TArrayRef<const NKikimrHive::TDataCentersGroup*>& vec) {
- out << '[';
- for (auto it = vec.begin(); it != vec.end(); ++it) {
- if (it != vec.begin())
- out << ';';
- out << (*it)->ShortDebugString();
- }
- out << ']';
- return out;
-}
-
+#include <util/generic/array_ref.h>
+
+template <>
+inline IOutputStream& operator <<(IOutputStream& out, const TArrayRef<const NKikimrHive::TDataCentersGroup*>& vec) {
+ out << '[';
+ for (auto it = vec.begin(); it != vec.end(); ++it) {
+ if (it != vec.begin())
+ out << ';';
+ out << (*it)->ShortDebugString();
+ }
+ out << ']';
+ return out;
+}
+
namespace NKikimr {
-namespace NHive {
-
-void THive::Handle(TEvHive::TEvCreateTablet::TPtr& ev) {
- NKikimrHive::TEvCreateTablet& rec = ev->Get()->Record;
- if (rec.HasOwner() && rec.HasOwnerIdx() && rec.HasTabletType() && rec.BindedChannelsSize() != 0) {
- BLOG_D("Handle TEvHive::TEvCreateTablet(" << rec.GetTabletType() << '(' << rec.GetOwner() << ',' << rec.GetOwnerIdx() << "))");
- Execute(CreateCreateTablet(std::move(rec), ev->Sender, ev->Cookie));
- } else {
- BLOG_ERROR("Invalid arguments specified to TEvCreateTablet: " << rec.DebugString());
+namespace NHive {
+
+void THive::Handle(TEvHive::TEvCreateTablet::TPtr& ev) {
+ NKikimrHive::TEvCreateTablet& rec = ev->Get()->Record;
+ if (rec.HasOwner() && rec.HasOwnerIdx() && rec.HasTabletType() && rec.BindedChannelsSize() != 0) {
+ BLOG_D("Handle TEvHive::TEvCreateTablet(" << rec.GetTabletType() << '(' << rec.GetOwner() << ',' << rec.GetOwnerIdx() << "))");
+ Execute(CreateCreateTablet(std::move(rec), ev->Sender, ev->Cookie));
+ } else {
+ BLOG_ERROR("Invalid arguments specified to TEvCreateTablet: " << rec.DebugString());
THolder<TEvHive::TEvCreateTabletReply> reply = MakeHolder<TEvHive::TEvCreateTabletReply>();
- reply->Record.SetStatus(NKikimrProto::EReplyStatus::ERROR);
- reply->Record.SetErrorReason(NKikimrHive::EErrorReason::ERROR_REASON_INVALID_ARGUMENTS);
- if (rec.HasOwner()) {
- reply->Record.SetOwner(rec.GetOwner());
- }
- if (rec.HasOwnerIdx()) {
- reply->Record.SetOwnerIdx(rec.GetOwnerIdx());
- }
- Send(ev->Sender, reply.Release(), 0, ev->Cookie);
- }
-}
-
-void THive::Handle(TEvHive::TEvAdoptTablet::TPtr& ev) {
- BLOG_D("Handle TEvHive::TEvAdoptTablet");
- NKikimrHive::TEvAdoptTablet& rec = ev->Get()->Record;
+ reply->Record.SetStatus(NKikimrProto::EReplyStatus::ERROR);
+ reply->Record.SetErrorReason(NKikimrHive::EErrorReason::ERROR_REASON_INVALID_ARGUMENTS);
+ if (rec.HasOwner()) {
+ reply->Record.SetOwner(rec.GetOwner());
+ }
+ if (rec.HasOwnerIdx()) {
+ reply->Record.SetOwnerIdx(rec.GetOwnerIdx());
+ }
+ Send(ev->Sender, reply.Release(), 0, ev->Cookie);
+ }
+}
+
+void THive::Handle(TEvHive::TEvAdoptTablet::TPtr& ev) {
+ BLOG_D("Handle TEvHive::TEvAdoptTablet");
+ NKikimrHive::TEvAdoptTablet& rec = ev->Get()->Record;
Y_VERIFY(rec.HasOwner() && rec.HasOwnerIdx() && rec.HasTabletType());
- Execute(CreateAdoptTablet(rec, ev->Sender, ev->Cookie));
+ Execute(CreateAdoptTablet(rec, ev->Sender, ev->Cookie));
}
-void THive::Handle(TEvents::TEvPoisonPill::TPtr&) {
- BLOG_D("Handle TEvents::TEvPoisonPill");
- Send(Tablet(), new TEvents::TEvPoisonPill);
+void THive::Handle(TEvents::TEvPoisonPill::TPtr&) {
+ BLOG_D("Handle TEvents::TEvPoisonPill");
+ Send(Tablet(), new TEvents::TEvPoisonPill);
}
-void THive::Handle(TEvTabletPipe::TEvClientConnected::TPtr& ev) {
- TEvTabletPipe::TEvClientConnected *msg = ev->Get();
- if (msg->ClientId == BSControllerPipeClient && msg->Status != NKikimrProto::OK) {
- RestartBSControllerPipe();
- return;
- }
- if (msg->ClientId == RootHivePipeClient && msg->Status != NKikimrProto::OK) {
- RestartRootHivePipe();
- return;
- }
+void THive::Handle(TEvTabletPipe::TEvClientConnected::TPtr& ev) {
+ TEvTabletPipe::TEvClientConnected *msg = ev->Get();
+ if (msg->ClientId == BSControllerPipeClient && msg->Status != NKikimrProto::OK) {
+ RestartBSControllerPipe();
+ return;
+ }
+ if (msg->ClientId == RootHivePipeClient && msg->Status != NKikimrProto::OK) {
+ RestartRootHivePipe();
+ return;
+ }
if (!PipeClientCache->OnConnect(ev)) {
- BLOG_ERROR("Failed to connect to tablet " << ev->Get()->TabletId << " from tablet " << TabletID());
- RestartPipeTx(ev->Get()->TabletId);
+ BLOG_ERROR("Failed to connect to tablet " << ev->Get()->TabletId << " from tablet " << TabletID());
+ RestartPipeTx(ev->Get()->TabletId);
} else {
- BLOG_D("Connected to tablet " << ev->Get()->TabletId << " from tablet " << TabletID());
+ BLOG_D("Connected to tablet " << ev->Get()->TabletId << " from tablet " << TabletID());
}
}
-void THive::Handle(TEvTabletPipe::TEvClientDestroyed::TPtr& ev) {
- TEvTabletPipe::TEvClientDestroyed *msg = ev->Get();
- if (msg->ClientId == BSControllerPipeClient) {
- RestartBSControllerPipe();
- return;
- }
- if (msg->ClientId == RootHivePipeClient) {
- RestartRootHivePipe();
- return;
- }
- BLOG_D("Client pipe to tablet " << ev->Get()->TabletId << " from " << TabletID() << " is reset");
+void THive::Handle(TEvTabletPipe::TEvClientDestroyed::TPtr& ev) {
+ TEvTabletPipe::TEvClientDestroyed *msg = ev->Get();
+ if (msg->ClientId == BSControllerPipeClient) {
+ RestartBSControllerPipe();
+ return;
+ }
+ if (msg->ClientId == RootHivePipeClient) {
+ RestartRootHivePipe();
+ return;
+ }
+ BLOG_D("Client pipe to tablet " << ev->Get()->TabletId << " from " << TabletID() << " is reset");
PipeClientCache->OnDisconnect(ev);
- RestartPipeTx(ev->Get()->TabletId);
+ RestartPipeTx(ev->Get()->TabletId);
}
-void THive::RestartPipeTx(ui64 tabletId) {
+void THive::RestartPipeTx(ui64 tabletId) {
for (auto txid : PipeTracker.FindTx(tabletId)) {
- BLOG_D("Pipe reset to tablet " << tabletId << " caused restart of txid# " << txid << " at tablet " << TabletID());
+ BLOG_D("Pipe reset to tablet " << tabletId << " caused restart of txid# " << txid << " at tablet " << TabletID());
// TODO: restart all the dependent transactions
}
}
-void THive::Handle(TEvTabletPipe::TEvServerConnected::TPtr& ev) {
- if (ev->Get()->TabletId == TabletID()) {
- BLOG_TRACE("Handle TEvTabletPipe::TEvServerConnected(" << ev->Get()->ClientId << ") " << ev->Get()->ServerId);
- TNodeInfo& node = GetNode(ev->Get()->ClientId.NodeId());
- node.PipeServers.emplace_back(ev->Get()->ServerId);
- }
-}
-
-void THive::Handle(TEvTabletPipe::TEvServerDisconnected::TPtr& ev) {
- if (ev->Get()->TabletId == TabletID()) {
- BLOG_TRACE("Handle TEvTabletPipe::TEvServerDisconnected(" << ev->Get()->ClientId << ") " << ev->Get()->ServerId);
- TNodeInfo* node = FindNode(ev->Get()->ClientId.NodeId());
- if (node != nullptr) {
- Erase(node->PipeServers, ev->Get()->ServerId);
- if (node->PipeServers.empty() && node->IsUnknown() && node->CanBeDeleted()) {
- DeleteNode(node->Id);
- }
- }
- }
-}
-
-void THive::Handle(TEvLocal::TEvRegisterNode::TPtr& ev) {
- NKikimrLocal::TEvRegisterNode& record = ev->Get()->Record;
- if (record.GetHiveId() == TabletID()) {
+void THive::Handle(TEvTabletPipe::TEvServerConnected::TPtr& ev) {
+ if (ev->Get()->TabletId == TabletID()) {
+ BLOG_TRACE("Handle TEvTabletPipe::TEvServerConnected(" << ev->Get()->ClientId << ") " << ev->Get()->ServerId);
+ TNodeInfo& node = GetNode(ev->Get()->ClientId.NodeId());
+ node.PipeServers.emplace_back(ev->Get()->ServerId);
+ }
+}
+
+void THive::Handle(TEvTabletPipe::TEvServerDisconnected::TPtr& ev) {
+ if (ev->Get()->TabletId == TabletID()) {
+ BLOG_TRACE("Handle TEvTabletPipe::TEvServerDisconnected(" << ev->Get()->ClientId << ") " << ev->Get()->ServerId);
+ TNodeInfo* node = FindNode(ev->Get()->ClientId.NodeId());
+ if (node != nullptr) {
+ Erase(node->PipeServers, ev->Get()->ServerId);
+ if (node->PipeServers.empty() && node->IsUnknown() && node->CanBeDeleted()) {
+ DeleteNode(node->Id);
+ }
+ }
+ }
+}
+
+void THive::Handle(TEvLocal::TEvRegisterNode::TPtr& ev) {
+ NKikimrLocal::TEvRegisterNode& record = ev->Get()->Record;
+ if (record.GetHiveId() == TabletID()) {
const TActorId &local = ev->Sender;
- BLOG_D("Handle TEvLocal::TEvRegisterNode from " << ev->Sender << " " << record.ShortDebugString());
+ BLOG_D("Handle TEvLocal::TEvRegisterNode from " << ev->Sender << " " << record.ShortDebugString());
Send(GetNameserviceActorId(), new TEvInterconnect::TEvGetNode(ev->Sender.NodeId()));
- Execute(CreateRegisterNode(local, std::move(record)));
- } else {
- BLOG_W("Handle incorrect TEvLocal::TEvRegisterNode from " << ev->Sender << " " << record.ShortDebugString());
- }
+ Execute(CreateRegisterNode(local, std::move(record)));
+ } else {
+ BLOG_W("Handle incorrect TEvLocal::TEvRegisterNode from " << ev->Sender << " " << record.ShortDebugString());
+ }
}
-bool THive::OnRenderAppHtmlPage(NMon::TEvRemoteHttpInfo::TPtr ev, const TActorContext& ctx) {
+bool THive::OnRenderAppHtmlPage(NMon::TEvRemoteHttpInfo::TPtr ev, const TActorContext& ctx) {
if (!Executor() || !Executor()->GetStats().IsActive)
return false;
- if (!ev)
- return true;
-
- CreateEvMonitoring(ev, ctx);
- return true;
+ if (!ev)
+ return true;
+
+ CreateEvMonitoring(ev, ctx);
+ return true;
}
-void THive::Handle(TEvHive::TEvStopTablet::TPtr& ev) {
- BLOG_D("Handle StopTablet");
- NKikimrHive::TEvStopTablet& rec = ev->Get()->Record;
+void THive::Handle(TEvHive::TEvStopTablet::TPtr& ev) {
+ BLOG_D("Handle StopTablet");
+ NKikimrHive::TEvStopTablet& rec = ev->Get()->Record;
const TActorId actorToNotify = rec.HasActorToNotify() ? ActorIdFromProto(rec.GetActorToNotify()) : ev->Sender;
- if (rec.HasTabletID()) {
-
- } else {
- Y_ENSURE_LOG(rec.HasTabletID(), rec.ShortDebugString());
- Send(actorToNotify, new TEvHive::TEvStopTabletResult(NKikimrProto::ERROR, 0), 0, ev->Cookie);
- }
-}
+ if (rec.HasTabletID()) {
+
+ } else {
+ Y_ENSURE_LOG(rec.HasTabletID(), rec.ShortDebugString());
+ Send(actorToNotify, new TEvHive::TEvStopTabletResult(NKikimrProto::ERROR, 0), 0, ev->Cookie);
+ }
+}
-void THive::Handle(TEvHive::TEvDeleteTablet::TPtr& ev) {
- Execute(CreateDeleteTablet(ev));
+void THive::Handle(TEvHive::TEvDeleteTablet::TPtr& ev) {
+ Execute(CreateDeleteTablet(ev));
}
-void THive::Handle(TEvHive::TEvDeleteOwnerTablets::TPtr& ev) {
- Execute(CreateDeleteOwnerTablets(ev));
+void THive::Handle(TEvHive::TEvDeleteOwnerTablets::TPtr& ev) {
+ Execute(CreateDeleteOwnerTablets(ev));
}
void THive::DeleteTabletWithoutStorage(TLeaderTabletInfo* tablet) {
- Y_ENSURE_LOG(tablet->IsDeleting(), "tablet " << tablet->Id);
- Y_ENSURE_LOG(tablet->TabletStorageInfo->Channels.empty() || tablet->TabletStorageInfo->Channels[0].History.empty(), "tablet " << tablet->Id);
+ Y_ENSURE_LOG(tablet->IsDeleting(), "tablet " << tablet->Id);
+ Y_ENSURE_LOG(tablet->TabletStorageInfo->Channels.empty() || tablet->TabletStorageInfo->Channels[0].History.empty(), "tablet " << tablet->Id);
// Tablet has no storage, so there's nothing to block or delete
// Simulate a response from CreateTabletReqDelete as if all steps have been completed
Send(SelfId(), new TEvTabletBase::TEvDeleteTabletResult(NKikimrProto::OK, tablet->Id));
}
-void THive::RunProcessBootQueue() {
- TInstant now = TActivationContext::Now();
- BLOG_D("Handle ProcessBootQueue (size: " << BootQueue.BootQueue.size() << ")");
- THPTimer bootQueueProcessingTimer;
- if (ProcessWaitQueueScheduled) {
- BLOG_D("Handle ProcessWaitQueue (size: " << BootQueue.WaitQueue.size() << ")");
- BootQueue.MoveFromWaitQueueToBootQueue();
- ProcessWaitQueueScheduled = false;
- }
- ProcessBootQueueScheduled = false;
- ui64 processedItems = 0;
- TInstant postponedStart;
- TStackVec<TBootQueue::TBootQueueRecord> delayedTablets;
- while (!BootQueue.BootQueue.empty() && processedItems < GetMaxBootBatchSize()) {
- TBootQueue::TBootQueueRecord record = BootQueue.PopFromBootQueue();
- ++processedItems;
- TTabletInfo* tablet = FindTablet(record.TabletId);
- if (tablet == nullptr) {
- continue;
- }
- if (tablet->IsAlive()) {
- continue;
- }
- if (tablet->IsReadyToStart(now)) {
- TBestNodeResult bestNodeResult = FindBestNode(*tablet);
- if (bestNodeResult.BestNode != nullptr) {
- if (tablet->InitiateStart(bestNodeResult.BestNode)) {
- continue;
- }
- } else {
- for (const TActorId actorToNotify : tablet->ActorsToNotifyOnRestart) {
- Send(actorToNotify, new TEvPrivate::TEvRestartComplete(tablet->GetFullTabletId(), "boot delay"));
- }
- tablet->ActorsToNotifyOnRestart.clear();
- if (!bestNodeResult.TryToContinue) {
- delayedTablets.push_back(record);
- break;
- } else {
- BootQueue.AddToWaitQueue(record); // waiting for new node
- continue;
- }
+void THive::RunProcessBootQueue() {
+ TInstant now = TActivationContext::Now();
+ BLOG_D("Handle ProcessBootQueue (size: " << BootQueue.BootQueue.size() << ")");
+ THPTimer bootQueueProcessingTimer;
+ if (ProcessWaitQueueScheduled) {
+ BLOG_D("Handle ProcessWaitQueue (size: " << BootQueue.WaitQueue.size() << ")");
+ BootQueue.MoveFromWaitQueueToBootQueue();
+ ProcessWaitQueueScheduled = false;
+ }
+ ProcessBootQueueScheduled = false;
+ ui64 processedItems = 0;
+ TInstant postponedStart;
+ TStackVec<TBootQueue::TBootQueueRecord> delayedTablets;
+ while (!BootQueue.BootQueue.empty() && processedItems < GetMaxBootBatchSize()) {
+ TBootQueue::TBootQueueRecord record = BootQueue.PopFromBootQueue();
+ ++processedItems;
+ TTabletInfo* tablet = FindTablet(record.TabletId);
+ if (tablet == nullptr) {
+ continue;
+ }
+ if (tablet->IsAlive()) {
+ continue;
+ }
+ if (tablet->IsReadyToStart(now)) {
+ TBestNodeResult bestNodeResult = FindBestNode(*tablet);
+ if (bestNodeResult.BestNode != nullptr) {
+ if (tablet->InitiateStart(bestNodeResult.BestNode)) {
+ continue;
+ }
+ } else {
+ for (const TActorId actorToNotify : tablet->ActorsToNotifyOnRestart) {
+ Send(actorToNotify, new TEvPrivate::TEvRestartComplete(tablet->GetFullTabletId(), "boot delay"));
+ }
+ tablet->ActorsToNotifyOnRestart.clear();
+ if (!bestNodeResult.TryToContinue) {
+ delayedTablets.push_back(record);
+ break;
+ } else {
+ BootQueue.AddToWaitQueue(record); // waiting for new node
+ continue;
+ }
+ }
+ } else {
+ TInstant tabletPostponedStart = tablet->PostponedStart;
+ if (tabletPostponedStart > now) {
+ if (postponedStart) {
+ postponedStart = std::min(postponedStart, tabletPostponedStart);
+ } else {
+ postponedStart = tabletPostponedStart;
+ }
}
- } else {
- TInstant tabletPostponedStart = tablet->PostponedStart;
- if (tabletPostponedStart > now) {
- if (postponedStart) {
- postponedStart = std::min(postponedStart, tabletPostponedStart);
- } else {
- postponedStart = tabletPostponedStart;
- }
- }
- }
- if (tablet->IsBooting()) {
- delayedTablets.push_back(record);
- }
- }
- for (TBootQueue::TBootQueueRecord record : delayedTablets) {
- BootQueue.AddToBootQueue(record);
- }
- if (TabletCounters != nullptr) {
- TabletCounters->Simple()[NHive::COUNTER_BOOTQUEUE_SIZE].Set(BootQueue.BootQueue.size());
- TabletCounters->Simple()[NHive::COUNTER_WAITQUEUE_SIZE].Set(BootQueue.WaitQueue.size());
- TabletCounters->Cumulative()[NHive::COUNTER_BOOTQUEUE_PROCESSED].Increment(1);
- TabletCounters->Cumulative()[NHive::COUNTER_BOOTQUEUE_TIME].Increment(ui64(1000000. * bootQueueProcessingTimer.PassedReset()));
- }
- if (BootQueue.BootQueue.empty()) {
- BLOG_D("ProcessBootQueue - BootQueue empty (WaitQueue: " << BootQueue.WaitQueue.size() << ")");
- }
- if (processedItems > 0) {
- if (processedItems == delayedTablets.size() && postponedStart < now) {
- BLOG_D("ProcessBootQueue - BootQueue throttling (size: " << BootQueue.BootQueue.size() << ")");
- return;
- }
- if (processedItems == GetMaxBootBatchSize()) {
- BLOG_D("ProcessBootQueue - rescheduling");
- ProcessBootQueue();
- } else if (postponedStart > now) {
- BLOG_D("ProcessBootQueue - postponing");
- PostponeProcessBootQueue(postponedStart - now);
- }
- }
-}
-
-void THive::Handle(TEvPrivate::TEvProcessBootQueue::TPtr&) {
- BLOG_TRACE("ProcessBootQueue - executing");
- Execute(CreateProcessBootQueue());
-}
-
-void THive::Handle(TEvPrivate::TEvPostponeProcessBootQueue::TPtr&) {
- ProcessBootQueuePostponed = false;
- ProcessBootQueue();
-}
-
-void THive::ProcessBootQueue() {
- BLOG_D("ProcessBootQueue (" << BootQueue.BootQueue.size() << ")");
- if (!ProcessBootQueueScheduled) {
- BLOG_TRACE("ProcessBootQueue - sending");
- ProcessBootQueueScheduled = true;
+ }
+ if (tablet->IsBooting()) {
+ delayedTablets.push_back(record);
+ }
+ }
+ for (TBootQueue::TBootQueueRecord record : delayedTablets) {
+ BootQueue.AddToBootQueue(record);
+ }
+ if (TabletCounters != nullptr) {
+ TabletCounters->Simple()[NHive::COUNTER_BOOTQUEUE_SIZE].Set(BootQueue.BootQueue.size());
+ TabletCounters->Simple()[NHive::COUNTER_WAITQUEUE_SIZE].Set(BootQueue.WaitQueue.size());
+ TabletCounters->Cumulative()[NHive::COUNTER_BOOTQUEUE_PROCESSED].Increment(1);
+ TabletCounters->Cumulative()[NHive::COUNTER_BOOTQUEUE_TIME].Increment(ui64(1000000. * bootQueueProcessingTimer.PassedReset()));
+ }
+ if (BootQueue.BootQueue.empty()) {
+ BLOG_D("ProcessBootQueue - BootQueue empty (WaitQueue: " << BootQueue.WaitQueue.size() << ")");
+ }
+ if (processedItems > 0) {
+ if (processedItems == delayedTablets.size() && postponedStart < now) {
+ BLOG_D("ProcessBootQueue - BootQueue throttling (size: " << BootQueue.BootQueue.size() << ")");
+ return;
+ }
+ if (processedItems == GetMaxBootBatchSize()) {
+ BLOG_D("ProcessBootQueue - rescheduling");
+ ProcessBootQueue();
+ } else if (postponedStart > now) {
+ BLOG_D("ProcessBootQueue - postponing");
+ PostponeProcessBootQueue(postponedStart - now);
+ }
+ }
+}
+
+void THive::Handle(TEvPrivate::TEvProcessBootQueue::TPtr&) {
+ BLOG_TRACE("ProcessBootQueue - executing");
+ Execute(CreateProcessBootQueue());
+}
+
+void THive::Handle(TEvPrivate::TEvPostponeProcessBootQueue::TPtr&) {
+ ProcessBootQueuePostponed = false;
+ ProcessBootQueue();
+}
+
+void THive::ProcessBootQueue() {
+ BLOG_D("ProcessBootQueue (" << BootQueue.BootQueue.size() << ")");
+ if (!ProcessBootQueueScheduled) {
+ BLOG_TRACE("ProcessBootQueue - sending");
+ ProcessBootQueueScheduled = true;
Send(SelfId(), new TEvPrivate::TEvProcessBootQueue());
}
-}
+}
-void THive::PostponeProcessBootQueue(TDuration after) {
+void THive::PostponeProcessBootQueue(TDuration after) {
if (!ProcessBootQueuePostponed) {
- BLOG_D("PostponeProcessBootQueue (" << after << ")");
- ProcessBootQueuePostponed = true;
- Schedule(after, new TEvPrivate::TEvPostponeProcessBootQueue());
- }
-}
-
-void THive::ProcessWaitQueue() {
- BLOG_D("ProcessWaitQueue (" << BootQueue.WaitQueue.size() << ")");
- ProcessWaitQueueScheduled = true;
- ProcessBootQueue();
-}
-
-void THive::AddToBootQueue(TTabletInfo* tablet) {
- tablet->UpdateWeight();
- tablet->BootState = BootStateBooting;
- BootQueue.AddToBootQueue(*tablet);
- UpdateCounterBootQueueSize(BootQueue.BootQueue.size());
-}
-
-void THive::Handle(TEvPrivate::TEvProcessPendingOperations::TPtr&) {
- BLOG_D("Handle ProcessPendingOperations");
-}
-
-void THive::Handle(TEvHive::TEvBootTablet::TPtr& ev) {
- TTabletId tabletId = ev->Get()->Record.GetTabletID();
- TTabletInfo* tablet = FindTablet(tabletId);
+ BLOG_D("PostponeProcessBootQueue (" << after << ")");
+ ProcessBootQueuePostponed = true;
+ Schedule(after, new TEvPrivate::TEvPostponeProcessBootQueue());
+ }
+}
+
+void THive::ProcessWaitQueue() {
+ BLOG_D("ProcessWaitQueue (" << BootQueue.WaitQueue.size() << ")");
+ ProcessWaitQueueScheduled = true;
+ ProcessBootQueue();
+}
+
+void THive::AddToBootQueue(TTabletInfo* tablet) {
+ tablet->UpdateWeight();
+ tablet->BootState = BootStateBooting;
+ BootQueue.AddToBootQueue(*tablet);
+ UpdateCounterBootQueueSize(BootQueue.BootQueue.size());
+}
+
+void THive::Handle(TEvPrivate::TEvProcessPendingOperations::TPtr&) {
+ BLOG_D("Handle ProcessPendingOperations");
+}
+
+void THive::Handle(TEvHive::TEvBootTablet::TPtr& ev) {
+ TTabletId tabletId = ev->Get()->Record.GetTabletID();
+ TTabletInfo* tablet = FindTablet(tabletId);
Y_VERIFY(tablet != nullptr);
- if (tablet->IsReadyToBoot()) {
- tablet->InitiateBoot();
- }
-}
-
-TVector<TTabletId> THive::UpdateStoragePools(const google::protobuf::RepeatedPtrField<NKikimrBlobStorage::TEvControllerSelectGroupsResult::TGroupParameters>& groups) {
- TVector<TTabletId> tabletsToUpdate;
- std::unordered_map<TString, std::vector<const NKikimrBlobStorage::TEvControllerSelectGroupsResult::TGroupParameters*>> poolToGroup;
- for (const auto& gp : groups) {
- poolToGroup[gp.GetStoragePoolName()].emplace_back(&gp);
- }
- for (const auto& [poolName, groupParams] : poolToGroup) {
- std::unordered_set<TStorageGroupId> groups;
- TStoragePoolInfo& storagePool = GetStoragePool(poolName);
- std::transform(storagePool.Groups.begin(), storagePool.Groups.end(), std::inserter(groups, groups.end()), [](const auto& pr) { return pr.first; });
- for (const NKikimrBlobStorage::TEvControllerSelectGroupsResult::TGroupParameters* group : groupParams) {
- TStorageGroupId groupId = group->GetGroupID();
- groups.erase(groupId);
- storagePool.UpdateStorageGroup(groupId, *group);
- }
- for (TStorageGroupId groupId : groups) {
- storagePool.DeleteStorageGroup(groupId);
- }
- if (storagePool.RefreshRequestInFlight > 0) {
- --storagePool.RefreshRequestInFlight;
- } else {
- BLOG_W("THive::Handle TEvControllerSelectGroupsResult: Out of inflight counter response received");
- }
- storagePool.SetAsFresh();
- storagePool.ConfigurationGeneration = ConfigurationGeneration;
- TVector<TTabletId> tabletsWaiting = storagePool.PullWaitingTablets();
- tabletsToUpdate.reserve(tabletsToUpdate.size() + tabletsWaiting.size());
- for (TTabletId tabletId : tabletsWaiting) {
- tabletsToUpdate.emplace_back(tabletId);
- }
- }
- return tabletsToUpdate;
-}
-
-void THive::Handle(TEvBlobStorage::TEvControllerSelectGroupsResult::TPtr& ev) {
- NKikimrBlobStorage::TEvControllerSelectGroupsResult& rec = ev->Get()->Record;
- if (rec.GetStatus() == NKikimrProto::OK) {
- BLOG_D("THive::Handle TEvControllerSelectGroupsResult: success " << rec.ShortDebugString());
+ if (tablet->IsReadyToBoot()) {
+ tablet->InitiateBoot();
+ }
+}
+
+TVector<TTabletId> THive::UpdateStoragePools(const google::protobuf::RepeatedPtrField<NKikimrBlobStorage::TEvControllerSelectGroupsResult::TGroupParameters>& groups) {
+ TVector<TTabletId> tabletsToUpdate;
+ std::unordered_map<TString, std::vector<const NKikimrBlobStorage::TEvControllerSelectGroupsResult::TGroupParameters*>> poolToGroup;
+ for (const auto& gp : groups) {
+ poolToGroup[gp.GetStoragePoolName()].emplace_back(&gp);
+ }
+ for (const auto& [poolName, groupParams] : poolToGroup) {
+ std::unordered_set<TStorageGroupId> groups;
+ TStoragePoolInfo& storagePool = GetStoragePool(poolName);
+ std::transform(storagePool.Groups.begin(), storagePool.Groups.end(), std::inserter(groups, groups.end()), [](const auto& pr) { return pr.first; });
+ for (const NKikimrBlobStorage::TEvControllerSelectGroupsResult::TGroupParameters* group : groupParams) {
+ TStorageGroupId groupId = group->GetGroupID();
+ groups.erase(groupId);
+ storagePool.UpdateStorageGroup(groupId, *group);
+ }
+ for (TStorageGroupId groupId : groups) {
+ storagePool.DeleteStorageGroup(groupId);
+ }
+ if (storagePool.RefreshRequestInFlight > 0) {
+ --storagePool.RefreshRequestInFlight;
+ } else {
+ BLOG_W("THive::Handle TEvControllerSelectGroupsResult: Out of inflight counter response received");
+ }
+ storagePool.SetAsFresh();
+ storagePool.ConfigurationGeneration = ConfigurationGeneration;
+ TVector<TTabletId> tabletsWaiting = storagePool.PullWaitingTablets();
+ tabletsToUpdate.reserve(tabletsToUpdate.size() + tabletsWaiting.size());
+ for (TTabletId tabletId : tabletsWaiting) {
+ tabletsToUpdate.emplace_back(tabletId);
+ }
+ }
+ return tabletsToUpdate;
+}
+
+void THive::Handle(TEvBlobStorage::TEvControllerSelectGroupsResult::TPtr& ev) {
+ NKikimrBlobStorage::TEvControllerSelectGroupsResult& rec = ev->Get()->Record;
+ if (rec.GetStatus() == NKikimrProto::OK) {
+ BLOG_D("THive::Handle TEvControllerSelectGroupsResult: success " << rec.ShortDebugString());
if (rec.MatchingGroupsSize()) {
- TVector<TTabletId> tablets;
- for (const auto& matchingGroups : rec.GetMatchingGroups()) {
- if (matchingGroups.GroupsSize() == 0) {
- BLOG_ERROR("THive::Handle TEvControllerSelectGroupsResult: BSC didn't return matching groups set");
- continue;
- }
- TVector<TTabletId> tabletsWaiting = UpdateStoragePools(matchingGroups.GetGroups());
- tablets.reserve(tablets.size() + tabletsWaiting.size());
- for (TTabletId tablet : tabletsWaiting) {
- tablets.emplace_back(tablet);
- }
- }
- std::sort(tablets.begin(), tablets.end());
- tablets.erase(std::unique(tablets.begin(), tablets.end()), tablets.end());
- for (TTabletId tabletId : tablets) {
+ TVector<TTabletId> tablets;
+ for (const auto& matchingGroups : rec.GetMatchingGroups()) {
+ if (matchingGroups.GroupsSize() == 0) {
+ BLOG_ERROR("THive::Handle TEvControllerSelectGroupsResult: BSC didn't return matching groups set");
+ continue;
+ }
+ TVector<TTabletId> tabletsWaiting = UpdateStoragePools(matchingGroups.GetGroups());
+ tablets.reserve(tablets.size() + tabletsWaiting.size());
+ for (TTabletId tablet : tabletsWaiting) {
+ tablets.emplace_back(tablet);
+ }
+ }
+ std::sort(tablets.begin(), tablets.end());
+ tablets.erase(std::unique(tablets.begin(), tablets.end()), tablets.end());
+ for (TTabletId tabletId : tablets) {
TLeaderTabletInfo* tablet = FindTablet(tabletId);
- if (!tablet) {
- BLOG_ERROR("THive::Handle TEvControllerSelectGroupsResult: tablet# " << tabletId << " not found");
- } else {
- Execute(CreateUpdateTabletGroups(tabletId));
- }
- }
+ if (!tablet) {
+ BLOG_ERROR("THive::Handle TEvControllerSelectGroupsResult: tablet# " << tabletId << " not found");
+ } else {
+ Execute(CreateUpdateTabletGroups(tabletId));
+ }
+ }
} else {
- BLOG_ERROR("THive::Handle TEvControllerSelectGroupsResult: obsolete BSC response");
- }
- } else {
- BLOG_ERROR("THive::Handle TEvControllerSelectGroupsResult: " << rec.GetStatus());
- }
-}
-
-void THive::Handle(TEvLocal::TEvTabletStatus::TPtr& ev) {
- TNodeId nodeId = ev->Sender.NodeId();
- TNodeInfo* node = FindNode(nodeId);
- if (node != nullptr) {
- if (node->IsDisconnected()) {
- BLOG_W("Handle TEvLocal::TEvTabletStatus, NodeId " << nodeId << " disconnected, reconnecting");
- node->SendReconnect(ev->Sender);
- return;
- }
- }
- TEvLocal::TEvTabletStatus* msg = ev->Get();
- NKikimrLocal::TEvTabletStatus& record = msg->Record;
- BLOG_D("Handle TEvLocal::TEvTabletStatus, TabletId: " << record.GetTabletID());
+ BLOG_ERROR("THive::Handle TEvControllerSelectGroupsResult: obsolete BSC response");
+ }
+ } else {
+ BLOG_ERROR("THive::Handle TEvControllerSelectGroupsResult: " << rec.GetStatus());
+ }
+}
+
+void THive::Handle(TEvLocal::TEvTabletStatus::TPtr& ev) {
+ TNodeId nodeId = ev->Sender.NodeId();
+ TNodeInfo* node = FindNode(nodeId);
+ if (node != nullptr) {
+ if (node->IsDisconnected()) {
+ BLOG_W("Handle TEvLocal::TEvTabletStatus, NodeId " << nodeId << " disconnected, reconnecting");
+ node->SendReconnect(ev->Sender);
+ return;
+ }
+ }
+ TEvLocal::TEvTabletStatus* msg = ev->Get();
+ NKikimrLocal::TEvTabletStatus& record = msg->Record;
+ BLOG_D("Handle TEvLocal::TEvTabletStatus, TabletId: " << record.GetTabletID());
if (FindTablet(record.GetTabletID(), record.GetFollowerId()) != nullptr) {
- Execute(CreateUpdateTabletStatus(
- record.GetTabletID(),
- ev->Sender,
- record.GetGeneration(),
+ Execute(CreateUpdateTabletStatus(
+ record.GetTabletID(),
+ ev->Sender,
+ record.GetGeneration(),
record.GetFollowerId(),
- static_cast<TEvLocal::TEvTabletStatus::EStatus>(record.GetStatus()),
- static_cast<TEvTablet::TEvTabletDead::EReason>(record.GetReason())
- ));
- } else {
- BLOG_W("Handle TEvLocal::TEvTabletStatus from node " << nodeId << ", TabletId: " << record.GetTabletID() << " not found");
- }
-}
-
-void THive::Handle(TEvPrivate::TEvBootTablets::TPtr&) {
- BLOG_D("Handle BootTablets");
- RequestPoolsInformation();
- for (auto& [id, node] : Nodes) {
- if (node.LocationAcquired) {
- UpdateRegisteredDataCenters(node.Location.GetDataCenterId());
- }
- if (node.IsUnknown() && node.Local) {
- node.Ping();
- }
- }
- TVector<TTabletId> tabletsToReleaseFromParent;
- for (auto& tab : Tablets) {
+ static_cast<TEvLocal::TEvTabletStatus::EStatus>(record.GetStatus()),
+ static_cast<TEvTablet::TEvTabletDead::EReason>(record.GetReason())
+ ));
+ } else {
+ BLOG_W("Handle TEvLocal::TEvTabletStatus from node " << nodeId << ", TabletId: " << record.GetTabletID() << " not found");
+ }
+}
+
+void THive::Handle(TEvPrivate::TEvBootTablets::TPtr&) {
+ BLOG_D("Handle BootTablets");
+ RequestPoolsInformation();
+ for (auto& [id, node] : Nodes) {
+ if (node.LocationAcquired) {
+ UpdateRegisteredDataCenters(node.Location.GetDataCenterId());
+ }
+ if (node.IsUnknown() && node.Local) {
+ node.Ping();
+ }
+ }
+ TVector<TTabletId> tabletsToReleaseFromParent;
+ for (auto& tab : Tablets) {
TLeaderTabletInfo& tablet = tab.second;
- if (tablet.NeedToReleaseFromParent) {
- BLOG_D("Need to release from parent tablet " << tablet.ToString());
- tabletsToReleaseFromParent.push_back(tablet.Id);
- } else if (tablet.IsReadyToBoot()) {
- tablet.InitiateBoot();
- } else if (tablet.IsReadyToAssignGroups()) {
- tablet.InitiateAssignTabletGroups();
- } else if (tablet.IsReadyToBlockStorage()) {
- tablet.InitiateBlockStorage();
- } else if (tablet.IsDeleting()) {
- if (!tablet.InitiateBlockStorage(std::numeric_limits<ui32>::max())) {
- DeleteTabletWithoutStorage(&tablet);
+ if (tablet.NeedToReleaseFromParent) {
+ BLOG_D("Need to release from parent tablet " << tablet.ToString());
+ tabletsToReleaseFromParent.push_back(tablet.Id);
+ } else if (tablet.IsReadyToBoot()) {
+ tablet.InitiateBoot();
+ } else if (tablet.IsReadyToAssignGroups()) {
+ tablet.InitiateAssignTabletGroups();
+ } else if (tablet.IsReadyToBlockStorage()) {
+ tablet.InitiateBlockStorage();
+ } else if (tablet.IsDeleting()) {
+ if (!tablet.InitiateBlockStorage(std::numeric_limits<ui32>::max())) {
+ DeleteTabletWithoutStorage(&tablet);
}
- } else if (tablet.IsStopped() && tablet.State == ETabletState::Stopped) {
- ReportStoppedToWhiteboard(tablet);
- BLOG_D("Report tablet " << tablet.ToString() << " as stopped to Whiteboard");
- } else {
- BLOG_W("The tablet "
- << tablet.ToString()
- << " is not ready for anything State:"
- << ETabletStateName(tablet.State)
- << " VolatileState:"
- << TTabletInfo::EVolatileStateName(tablet.GetVolatileState()));
- }
- for (const auto& domain : tablet.EffectiveAllowedDomains) {
- SeenDomain(domain);
- }
- if (tablet.ObjectDomain) {
- SeenDomain(tablet.ObjectDomain);
- }
- }
- SignalTabletActive(DEPRECATED_CTX);
- ReadyForConnections = true;
- if (AreWeRootHive()) {
- BLOG_D("Root Hive is ready");
- } else {
- BLOG_D("SubDomain Hive is ready");
- }
- if (!tabletsToReleaseFromParent.empty()) {
- THolder<TEvHive::TEvReleaseTablets> request(new TEvHive::TEvReleaseTablets());
- request->Record.SetNewOwnerID(TabletID());
- for (TTabletId tabletId : tabletsToReleaseFromParent) {
- request->Record.AddTabletIDs(tabletId);
- }
- SendToRootHivePipe(request.Release());
- }
- ProcessPendingOperations();
-}
-
-void THive::Handle(TEvHive::TEvInitMigration::TPtr& ev) {
- BLOG_D("Handle InitMigration " << ev->Get()->Record);
- if (MigrationState == NKikimrHive::EMigrationState::MIGRATION_READY || MigrationState == NKikimrHive::EMigrationState::MIGRATION_COMPLETE) {
- if (ev->Get()->Record.GetMigrationFilter().GetFilterDomain().GetSchemeShard() == 0 && GetMySubDomainKey().GetSchemeShard() == 0) {
- BLOG_ERROR("Migration ignored - unknown domain");
- Send(ev->Sender, new TEvHive::TEvInitMigrationReply(NKikimrProto::ERROR));
- return;
- }
- MigrationFilter = ev->Get()->Record.GetMigrationFilter();
- if (!MigrationFilter.HasFilterDomain()) {
- MigrationFilter.MutableFilterDomain()->CopyFrom(GetMySubDomainKey());
- }
- MigrationState = NKikimrHive::EMigrationState::MIGRATION_ACTIVE;
- // MigrationProgress = 0;
- // ^ we want cumulative statistics
- if (MigrationFilter.GetMaxTabletsToSeize() == 0) {
- MigrationFilter.SetMaxTabletsToSeize(1);
- }
- MigrationFilter.SetNewOwnerID(TabletID());
- BLOG_D("Requesting migration " << MigrationFilter.ShortDebugString());
- SendToRootHivePipe(new TEvHive::TEvSeizeTablets(MigrationFilter));
- Send(ev->Sender, new TEvHive::TEvInitMigrationReply(NKikimrProto::OK));
- } else {
- BLOG_D("Migration already in progress " << MigrationProgress);
- Send(ev->Sender, new TEvHive::TEvInitMigrationReply(NKikimrProto::ALREADY));
- }
-}
-
-void THive::Handle(TEvHive::TEvQueryMigration::TPtr& ev) {
- BLOG_D("Handle QueryMigration");
- Send(ev->Sender, new TEvHive::TEvQueryMigrationReply(MigrationState, MigrationProgress));
-}
-
-void THive::OnDetach(const TActorContext&) {
- BLOG_D("THive::OnDetach");
- Cleanup();
- PassAway();
-}
-
-void THive::OnTabletDead(TEvTablet::TEvTabletDead::TPtr&, const TActorContext&) {
- BLOG_I("OnTabletDead: " << TabletID());
- Cleanup();
- return PassAway();
-}
-
-void THive::BuildLocalConfig() {
+ } else if (tablet.IsStopped() && tablet.State == ETabletState::Stopped) {
+ ReportStoppedToWhiteboard(tablet);
+ BLOG_D("Report tablet " << tablet.ToString() << " as stopped to Whiteboard");
+ } else {
+ BLOG_W("The tablet "
+ << tablet.ToString()
+ << " is not ready for anything State:"
+ << ETabletStateName(tablet.State)
+ << " VolatileState:"
+ << TTabletInfo::EVolatileStateName(tablet.GetVolatileState()));
+ }
+ for (const auto& domain : tablet.EffectiveAllowedDomains) {
+ SeenDomain(domain);
+ }
+ if (tablet.ObjectDomain) {
+ SeenDomain(tablet.ObjectDomain);
+ }
+ }
+ SignalTabletActive(DEPRECATED_CTX);
+ ReadyForConnections = true;
+ if (AreWeRootHive()) {
+ BLOG_D("Root Hive is ready");
+ } else {
+ BLOG_D("SubDomain Hive is ready");
+ }
+ if (!tabletsToReleaseFromParent.empty()) {
+ THolder<TEvHive::TEvReleaseTablets> request(new TEvHive::TEvReleaseTablets());
+ request->Record.SetNewOwnerID(TabletID());
+ for (TTabletId tabletId : tabletsToReleaseFromParent) {
+ request->Record.AddTabletIDs(tabletId);
+ }
+ SendToRootHivePipe(request.Release());
+ }
+ ProcessPendingOperations();
+}
+
+void THive::Handle(TEvHive::TEvInitMigration::TPtr& ev) {
+ BLOG_D("Handle InitMigration " << ev->Get()->Record);
+ if (MigrationState == NKikimrHive::EMigrationState::MIGRATION_READY || MigrationState == NKikimrHive::EMigrationState::MIGRATION_COMPLETE) {
+ if (ev->Get()->Record.GetMigrationFilter().GetFilterDomain().GetSchemeShard() == 0 && GetMySubDomainKey().GetSchemeShard() == 0) {
+ BLOG_ERROR("Migration ignored - unknown domain");
+ Send(ev->Sender, new TEvHive::TEvInitMigrationReply(NKikimrProto::ERROR));
+ return;
+ }
+ MigrationFilter = ev->Get()->Record.GetMigrationFilter();
+ if (!MigrationFilter.HasFilterDomain()) {
+ MigrationFilter.MutableFilterDomain()->CopyFrom(GetMySubDomainKey());
+ }
+ MigrationState = NKikimrHive::EMigrationState::MIGRATION_ACTIVE;
+ // MigrationProgress = 0;
+ // ^ we want cumulative statistics
+ if (MigrationFilter.GetMaxTabletsToSeize() == 0) {
+ MigrationFilter.SetMaxTabletsToSeize(1);
+ }
+ MigrationFilter.SetNewOwnerID(TabletID());
+ BLOG_D("Requesting migration " << MigrationFilter.ShortDebugString());
+ SendToRootHivePipe(new TEvHive::TEvSeizeTablets(MigrationFilter));
+ Send(ev->Sender, new TEvHive::TEvInitMigrationReply(NKikimrProto::OK));
+ } else {
+ BLOG_D("Migration already in progress " << MigrationProgress);
+ Send(ev->Sender, new TEvHive::TEvInitMigrationReply(NKikimrProto::ALREADY));
+ }
+}
+
+void THive::Handle(TEvHive::TEvQueryMigration::TPtr& ev) {
+ BLOG_D("Handle QueryMigration");
+ Send(ev->Sender, new TEvHive::TEvQueryMigrationReply(MigrationState, MigrationProgress));
+}
+
+void THive::OnDetach(const TActorContext&) {
+ BLOG_D("THive::OnDetach");
+ Cleanup();
+ PassAway();
+}
+
+void THive::OnTabletDead(TEvTablet::TEvTabletDead::TPtr&, const TActorContext&) {
+ BLOG_I("OnTabletDead: " << TabletID());
+ Cleanup();
+ return PassAway();
+}
+
+void THive::BuildLocalConfig() {
LocalConfig.Clear();
if (ResourceProfiles)
ResourceProfiles->StoreProfiles(*LocalConfig.MutableResourceProfiles());
}
-void THive::BuildCurrentConfig() {
- BLOG_D("THive::BuildCurrentConfig ClusterConfig = " << ClusterConfig.ShortDebugString());
- CurrentConfig = ClusterConfig;
- BLOG_D("THive::BuildCurrentConfig DatabaseConfig = " << DatabaseConfig.ShortDebugString());
- CurrentConfig.MergeFrom(DatabaseConfig);
- BLOG_D("THive::BuildCurrentConfig CurrentConfig = " << CurrentConfig.ShortDebugString());
- TabletLimit.clear();
- for (const auto& tabletLimit : CurrentConfig.GetDefaultTabletLimit()) {
- TabletLimit.emplace(tabletLimit.GetType(), tabletLimit);
- }
- DefaultDataCentersPreference.clear();
- for (const NKikimrConfig::THiveTabletPreference& tabletPreference : CurrentConfig.GetDefaultTabletPreference()) {
- DefaultDataCentersPreference[tabletPreference.GetType()] = tabletPreference.GetDataCentersPreference();
- }
-}
-
-void THive::Cleanup() {
- BLOG_D("THive::Cleanup");
-
- Send(NConsole::MakeConfigsDispatcherID(SelfId().NodeId()),
- new NConsole::TEvConfigsDispatcher::TEvSetConfigSubscriptionRequest());
-
- while (!SubActors.empty()) {
- SubActors.front()->Cleanup();
- }
-
- PipeClientCache->Detach(DEPRECATED_CTX);
-
- if (BSControllerPipeClient) {
- NTabletPipe::CloseClient(SelfId(), BSControllerPipeClient);
+void THive::BuildCurrentConfig() {
+ BLOG_D("THive::BuildCurrentConfig ClusterConfig = " << ClusterConfig.ShortDebugString());
+ CurrentConfig = ClusterConfig;
+ BLOG_D("THive::BuildCurrentConfig DatabaseConfig = " << DatabaseConfig.ShortDebugString());
+ CurrentConfig.MergeFrom(DatabaseConfig);
+ BLOG_D("THive::BuildCurrentConfig CurrentConfig = " << CurrentConfig.ShortDebugString());
+ TabletLimit.clear();
+ for (const auto& tabletLimit : CurrentConfig.GetDefaultTabletLimit()) {
+ TabletLimit.emplace(tabletLimit.GetType(), tabletLimit);
+ }
+ DefaultDataCentersPreference.clear();
+ for (const NKikimrConfig::THiveTabletPreference& tabletPreference : CurrentConfig.GetDefaultTabletPreference()) {
+ DefaultDataCentersPreference[tabletPreference.GetType()] = tabletPreference.GetDataCentersPreference();
+ }
+}
+
+void THive::Cleanup() {
+ BLOG_D("THive::Cleanup");
+
+ Send(NConsole::MakeConfigsDispatcherID(SelfId().NodeId()),
+ new NConsole::TEvConfigsDispatcher::TEvSetConfigSubscriptionRequest());
+
+ while (!SubActors.empty()) {
+ SubActors.front()->Cleanup();
+ }
+
+ PipeClientCache->Detach(DEPRECATED_CTX);
+
+ if (BSControllerPipeClient) {
+ NTabletPipe::CloseClient(SelfId(), BSControllerPipeClient);
BSControllerPipeClient = TActorId();
- }
+ }
- if (RootHivePipeClient) {
- NTabletPipe::CloseClient(SelfId(), RootHivePipeClient);
+ if (RootHivePipeClient) {
+ NTabletPipe::CloseClient(SelfId(), RootHivePipeClient);
RootHivePipeClient = TActorId();
- }
-
+ }
+
if (ResponsivenessPinger) {
- ResponsivenessPinger->Detach(TlsActivationContext->ActorContextFor(ResponsivenessActorID));
+ ResponsivenessPinger->Detach(TlsActivationContext->ActorContextFor(ResponsivenessActorID));
ResponsivenessPinger = nullptr;
}
-}
-
-void THive::Handle(TEvLocal::TEvStatus::TPtr& ev) {
- BLOG_D("Handle TEvLocal::TEvStatus for Node " << ev->Sender.NodeId() << ": " << ev->Get()->Record.ShortDebugString());
- Execute(CreateStatus(ev->Sender, ev->Get()->Record));
-}
-
-void THive::Handle(TEvLocal::TEvSyncTablets::TPtr& ev) {
- BLOG_D("THive::Handle::TEvSyncTablets");
- Execute(CreateSyncTablets(ev->Sender, ev->Get()->Record));
-}
-
-void THive::Handle(TEvPrivate::TEvProcessDisconnectNode::TPtr& ev) {
- TAutoPtr<TEvPrivate::TEvProcessDisconnectNode> event = ev->Release();
- TNodeInfo& node = GetNode(event->NodeId);
- if (node.IsDisconnecting()) {
- auto itCategory = event->Tablets.begin();
- if (itCategory != event->Tablets.end()) {
- BLOG_D("THive::Handle::TEvProcessDisconnectNode: Node " << event->NodeId << " Category " << itCategory->first);
+}
+
+void THive::Handle(TEvLocal::TEvStatus::TPtr& ev) {
+ BLOG_D("Handle TEvLocal::TEvStatus for Node " << ev->Sender.NodeId() << ": " << ev->Get()->Record.ShortDebugString());
+ Execute(CreateStatus(ev->Sender, ev->Get()->Record));
+}
+
+void THive::Handle(TEvLocal::TEvSyncTablets::TPtr& ev) {
+ BLOG_D("THive::Handle::TEvSyncTablets");
+ Execute(CreateSyncTablets(ev->Sender, ev->Get()->Record));
+}
+
+void THive::Handle(TEvPrivate::TEvProcessDisconnectNode::TPtr& ev) {
+ TAutoPtr<TEvPrivate::TEvProcessDisconnectNode> event = ev->Release();
+ TNodeInfo& node = GetNode(event->NodeId);
+ if (node.IsDisconnecting()) {
+ auto itCategory = event->Tablets.begin();
+ if (itCategory != event->Tablets.end()) {
+ BLOG_D("THive::Handle::TEvProcessDisconnectNode: Node " << event->NodeId << " Category " << itCategory->first);
for (std::pair<TTabletId, TFollowerId> tabletId : itCategory->second) {
- TTabletInfo* tablet = FindTablet(tabletId);
- if (tablet != nullptr) {
- if (tablet->IsAlive()) {
- Execute(CreateRestartTablet(tabletId));
- }
- }
- }
- event->Tablets.erase(itCategory);
- }
- ScheduleDisconnectNode(event);
- }
-}
-
-void THive::Handle(TEvHive::TEvTabletMetrics::TPtr& ev) {
- TNodeId nodeId = ev->Sender.NodeId();
- BLOG_TRACE("THive::Handle::TEvTabletMetrics, NodeId " << nodeId << " " << ev->Get()->Record.ShortDebugString());
- if (UpdateTabletMetricsInProgress < MAX_UPDATE_TABLET_METRICS_IN_PROGRESS) {
- UpdateTabletMetricsInProgress++;
- if (UpdateTabletMetricsInProgress > (MAX_UPDATE_TABLET_METRICS_IN_PROGRESS / 2)) {
- BLOG_W("THive::Handle::TEvTabletMetrics, NodeId " << nodeId << " transactions in progress is over 50% of MAX_UPDATE_TABLET_METRICS_IN_PROGRESS");
- }
- Execute(CreateUpdateTabletMetrics(ev));
- } else {
- BLOG_ERROR("THive::Handle::TEvTabletMetrics, NodeId " << nodeId << " was skipped due to reaching of MAX_UPDATE_TABLET_METRICS_IN_PROGRESS");
- Send(ev->Sender, new TEvLocal::TEvTabletMetricsAck);
- }
-}
-
-void THive::Handle(TEvInterconnect::TEvNodeConnected::TPtr &ev) {
- TNodeId nodeId = ev->Get()->NodeId;
- BLOG_W("Handle TEvInterconnect::TEvNodeConnected, NodeId " << nodeId);
+ TTabletInfo* tablet = FindTablet(tabletId);
+ if (tablet != nullptr) {
+ if (tablet->IsAlive()) {
+ Execute(CreateRestartTablet(tabletId));
+ }
+ }
+ }
+ event->Tablets.erase(itCategory);
+ }
+ ScheduleDisconnectNode(event);
+ }
+}
+
+void THive::Handle(TEvHive::TEvTabletMetrics::TPtr& ev) {
+ TNodeId nodeId = ev->Sender.NodeId();
+ BLOG_TRACE("THive::Handle::TEvTabletMetrics, NodeId " << nodeId << " " << ev->Get()->Record.ShortDebugString());
+ if (UpdateTabletMetricsInProgress < MAX_UPDATE_TABLET_METRICS_IN_PROGRESS) {
+ UpdateTabletMetricsInProgress++;
+ if (UpdateTabletMetricsInProgress > (MAX_UPDATE_TABLET_METRICS_IN_PROGRESS / 2)) {
+ BLOG_W("THive::Handle::TEvTabletMetrics, NodeId " << nodeId << " transactions in progress is over 50% of MAX_UPDATE_TABLET_METRICS_IN_PROGRESS");
+ }
+ Execute(CreateUpdateTabletMetrics(ev));
+ } else {
+ BLOG_ERROR("THive::Handle::TEvTabletMetrics, NodeId " << nodeId << " was skipped due to reaching of MAX_UPDATE_TABLET_METRICS_IN_PROGRESS");
+ Send(ev->Sender, new TEvLocal::TEvTabletMetricsAck);
+ }
+}
+
+void THive::Handle(TEvInterconnect::TEvNodeConnected::TPtr &ev) {
+ TNodeId nodeId = ev->Get()->NodeId;
+ BLOG_W("Handle TEvInterconnect::TEvNodeConnected, NodeId " << nodeId);
Send(GetNameserviceActorId(), new TEvInterconnect::TEvGetNode(nodeId));
-}
+}
-void THive::Handle(TEvInterconnect::TEvNodeDisconnected::TPtr &ev) {
- BLOG_W("Handle TEvInterconnect::TEvNodeDisconnected, NodeId " << ev->Get()->NodeId);
+void THive::Handle(TEvInterconnect::TEvNodeDisconnected::TPtr &ev) {
+ BLOG_W("Handle TEvInterconnect::TEvNodeDisconnected, NodeId " << ev->Get()->NodeId);
Execute(CreateDisconnectNode(THolder<TEvInterconnect::TEvNodeDisconnected>(ev->Release().Release())));
-}
-
-void THive::Handle(TEvInterconnect::TEvNodeInfo::TPtr &ev) {
- THolder<TEvInterconnect::TNodeInfo>& node = ev->Get()->Node;
- if (node) {
- TEvInterconnect::TNodeInfo& nodeInfo = *node;
- NodesInfo[node->NodeId] = nodeInfo;
- TNodeInfo* hiveNodeInfo = FindNode(nodeInfo.NodeId);
- if (hiveNodeInfo != nullptr) {
+}
+
+void THive::Handle(TEvInterconnect::TEvNodeInfo::TPtr &ev) {
+ THolder<TEvInterconnect::TNodeInfo>& node = ev->Get()->Node;
+ if (node) {
+ TEvInterconnect::TNodeInfo& nodeInfo = *node;
+ NodesInfo[node->NodeId] = nodeInfo;
+ TNodeInfo* hiveNodeInfo = FindNode(nodeInfo.NodeId);
+ if (hiveNodeInfo != nullptr) {
hiveNodeInfo->Location = nodeInfo.Location;
hiveNodeInfo->LocationAcquired = true;
- BLOG_D("TEvInterconnect::TEvNodeInfo NodeId " << nodeInfo.NodeId << " Location " << GetLocationString(hiveNodeInfo->Location));
- if (hiveNodeInfo->IsRegistered()) {
- UpdateRegisteredDataCenters(hiveNodeInfo->Location.GetDataCenterId());
- }
- }
- }
+ BLOG_D("TEvInterconnect::TEvNodeInfo NodeId " << nodeInfo.NodeId << " Location " << GetLocationString(hiveNodeInfo->Location));
+ if (hiveNodeInfo->IsRegistered()) {
+ UpdateRegisteredDataCenters(hiveNodeInfo->Location.GetDataCenterId());
+ }
+ }
+ }
}
-void THive::Handle(TEvInterconnect::TEvNodesInfo::TPtr &ev) {
+void THive::Handle(TEvInterconnect::TEvNodesInfo::TPtr &ev) {
THashSet<TDataCenterId> dataCenters;
for (const TEvInterconnect::TNodeInfo& node : ev->Get()->Nodes) {
- NodesInfo[node.NodeId] = node;
+ NodesInfo[node.NodeId] = node;
dataCenters.insert(node.Location.GetDataCenterId());
- }
- dataCenters.erase(0); // remove default data center id if exists
- if (!dataCenters.empty()) {
- if (DataCenters != dataCenters.size()) {
- DataCenters = dataCenters.size();
- BLOG_D("TEvInterconnect::TEvNodesInfo DataCenters=" << DataCenters << " RegisteredDataCenters=" << RegisteredDataCenters);
- }
- }
- Execute(CreateLoadEverything());
-}
-
-void THive::ScheduleDisconnectNode(THolder<TEvPrivate::TEvProcessDisconnectNode> event) {
- auto itCategory = event->Tablets.begin();
- if (itCategory != event->Tablets.end()) {
- TTabletCategoryInfo& category = GetTabletCategory(itCategory->first);
- TDuration spentTime = TActivationContext::Now() - event->StartTime;
- TDuration disconnectTimeout = TDuration::MilliSeconds(category.MaxDisconnectTimeout);
- if (disconnectTimeout > spentTime) {
- Schedule(disconnectTimeout - spentTime, event.Release());
- } else {
+ }
+ dataCenters.erase(0); // remove default data center id if exists
+ if (!dataCenters.empty()) {
+ if (DataCenters != dataCenters.size()) {
+ DataCenters = dataCenters.size();
+ BLOG_D("TEvInterconnect::TEvNodesInfo DataCenters=" << DataCenters << " RegisteredDataCenters=" << RegisteredDataCenters);
+ }
+ }
+ Execute(CreateLoadEverything());
+}
+
+void THive::ScheduleDisconnectNode(THolder<TEvPrivate::TEvProcessDisconnectNode> event) {
+ auto itCategory = event->Tablets.begin();
+ if (itCategory != event->Tablets.end()) {
+ TTabletCategoryInfo& category = GetTabletCategory(itCategory->first);
+ TDuration spentTime = TActivationContext::Now() - event->StartTime;
+ TDuration disconnectTimeout = TDuration::MilliSeconds(category.MaxDisconnectTimeout);
+ if (disconnectTimeout > spentTime) {
+ Schedule(disconnectTimeout - spentTime, event.Release());
+ } else {
Send(SelfId(), event.Release());
}
- } else {
- KillNode(event->NodeId, event->Local);
- }
+ } else {
+ KillNode(event->NodeId, event->Local);
+ }
}
-void THive::Handle(TEvPrivate::TEvKickTablet::TPtr &ev) {
- TFullTabletId tabletId(ev->Get()->TabletId);
- TTabletInfo* tablet = FindTablet(tabletId);
+void THive::Handle(TEvPrivate::TEvKickTablet::TPtr &ev) {
+ TFullTabletId tabletId(ev->Get()->TabletId);
+ TTabletInfo* tablet = FindTablet(tabletId);
if (tablet == nullptr) {
- BLOG_W("THive::Handle::TEvKickTablet" <<
- " TabletId=" << tabletId <<
- " tablet not found");
+ BLOG_W("THive::Handle::TEvKickTablet" <<
+ " TabletId=" << tabletId <<
+ " tablet not found");
return;
}
if (!tablet->IsAlive()) {
- BLOG_D("THive::Handle::TEvKickTablet" <<
- " TabletId=" << tabletId <<
+ BLOG_D("THive::Handle::TEvKickTablet" <<
+ " TabletId=" << tabletId <<
" tablet isn't alive");
return;
}
- BLOG_D("THive::Handle::TEvKickTablet TabletId=" << tabletId);
- TBestNodeResult result = FindBestNode(*tablet);
+ BLOG_D("THive::Handle::TEvKickTablet TabletId=" << tabletId);
+ TBestNodeResult result = FindBestNode(*tablet);
if (result.BestNode == nullptr) {
- Execute(CreateRestartTablet(tabletId));
+ Execute(CreateRestartTablet(tabletId));
} else if (result.BestNode != tablet->Node) {
- if (IsTabletMoveExpedient(*tablet, *result.BestNode)) {
- Execute(CreateRestartTablet(tabletId));
- }
- }
-}
-
-void THive::Handle(TEvHive::TEvInitiateBlockStorage::TPtr& ev) {
- TTabletId tabletId = ev->Get()->TabletId;
- BLOG_D("THive::Handle::TEvInitiateBlockStorage TabletId=" << tabletId);
+ if (IsTabletMoveExpedient(*tablet, *result.BestNode)) {
+ Execute(CreateRestartTablet(tabletId));
+ }
+ }
+}
+
+void THive::Handle(TEvHive::TEvInitiateBlockStorage::TPtr& ev) {
+ TTabletId tabletId = ev->Get()->TabletId;
+ BLOG_D("THive::Handle::TEvInitiateBlockStorage TabletId=" << tabletId);
TLeaderTabletInfo* tablet = FindTabletEvenInDeleting(tabletId);
- if (tablet != nullptr) {
- if (tablet->IsDeleting()) {
- if (!tablet->InitiateBlockStorage(std::numeric_limits<ui32>::max())) {
- DeleteTabletWithoutStorage(tablet);
+ if (tablet != nullptr) {
+ if (tablet->IsDeleting()) {
+ if (!tablet->InitiateBlockStorage(std::numeric_limits<ui32>::max())) {
+ DeleteTabletWithoutStorage(tablet);
}
- } else
- if (tablet->IsReadyToBlockStorage()) {
- tablet->InitiateBlockStorage();
- }
- }
-}
-
-void THive::Handle(TEvHive::TEvInitiateDeleteStorage::TPtr &ev) {
- TTabletId tabletId = ev->Get()->TabletId;
- BLOG_D("THive::Handle::TEvInitiateDeleteStorage TabletId=" << tabletId);
+ } else
+ if (tablet->IsReadyToBlockStorage()) {
+ tablet->InitiateBlockStorage();
+ }
+ }
+}
+
+void THive::Handle(TEvHive::TEvInitiateDeleteStorage::TPtr &ev) {
+ TTabletId tabletId = ev->Get()->TabletId;
+ BLOG_D("THive::Handle::TEvInitiateDeleteStorage TabletId=" << tabletId);
TLeaderTabletInfo* tablet = FindTabletEvenInDeleting(tabletId);
- if (tablet != nullptr) {
- tablet->InitiateDeleteStorage();
- }
-}
-
-void THive::Handle(TEvHive::TEvGetTabletStorageInfo::TPtr& ev) {
+ if (tablet != nullptr) {
+ tablet->InitiateDeleteStorage();
+ }
+}
+
+void THive::Handle(TEvHive::TEvGetTabletStorageInfo::TPtr& ev) {
TTabletId tabletId = ev->Get()->Record.GetTabletID();
- BLOG_D("THive::Handle::TEvGetTabletStorageInfo TabletId=" << tabletId);
+ BLOG_D("THive::Handle::TEvGetTabletStorageInfo TabletId=" << tabletId);
TLeaderTabletInfo* tablet = FindTabletEvenInDeleting(tabletId);
if (tablet == nullptr) {
// Tablet doesn't exist
- Send(
+ Send(
ev->Sender,
new TEvHive::TEvGetTabletStorageInfoResult(tabletId, NKikimrProto::ERROR, "Tablet doesn't exist"),
0, ev->Cookie);
@@ -735,9 +735,9 @@ void THive::Handle(TEvHive::TEvGetTabletStorageInfo::TPtr& ev) {
case ETabletState::Unknown:
case ETabletState::StoppingInGroupAssignment:
// Subscribing in these states doesn't make sense, as it will never complete
- BLOG_ERROR("Requesting TabletStorageInfo with tablet State="
+ BLOG_ERROR("Requesting TabletStorageInfo with tablet State="
<< ETabletStateName(tablet->State));
- Send(
+ Send(
ev->Sender,
new TEvHive::TEvGetTabletStorageInfoResult(tabletId, NKikimrProto::ERROR, "Tablet is in an unexpected state"),
0, ev->Cookie);
@@ -746,11 +746,11 @@ void THive::Handle(TEvHive::TEvGetTabletStorageInfo::TPtr& ev) {
case ETabletState::GroupAssignment:
// We need to subscribe until group assignment or deletion is finished
tablet->StorageInfoSubscribers.emplace_back(ev->Sender);
- Send(ev->Sender, new TEvHive::TEvGetTabletStorageInfoRegistered(tabletId), 0, ev->Cookie);
+ Send(ev->Sender, new TEvHive::TEvGetTabletStorageInfoRegistered(tabletId), 0, ev->Cookie);
break;
default:
// Return what we have right now
- Send(
+ Send(
ev->Sender,
new TEvHive::TEvGetTabletStorageInfoResult(tabletId, *tablet->TabletStorageInfo),
0, ev->Cookie);
@@ -758,350 +758,350 @@ void THive::Handle(TEvHive::TEvGetTabletStorageInfo::TPtr& ev) {
}
}
-void THive::Handle(TEvents::TEvUndelivered::TPtr &ev) {
- BLOG_W("THive::Handle::TEvUndelivered Sender=" << ev->Sender << ", Type=" << ev->Get()->SourceType );
- switch (ev->Get()->SourceType) {
- case TEvLocal::EvBootTablet: {
- // restart boot of the tablet (on different node)
- TTabletId tabletId = ev->Cookie;
- TLeaderTabletInfo* tablet = FindTablet(tabletId);
- if (tablet != nullptr && tablet->IsStarting()) {
- Execute(CreateRestartTablet(tablet->GetFullTabletId()));
- }
- break;
- }
- case TEvLocal::EvPing: {
- TNodeId nodeId = ev->Cookie;
- TNodeInfo* node = FindNode(nodeId);
- if (node != nullptr && ev->Sender == node->Local) {
- if (node->IsDisconnecting()) {
- // ping continiousily until we fully disconnected from the node
- node->Ping();
- } else {
- KillNode(node->Id, node->Local);
- }
- }
- break;
- }
- };
-}
-
-void THive::Handle(TEvHive::TEvReassignTablet::TPtr &ev) {
- BLOG_D("THive::TEvReassignTablet " << ev->Get()->Record.ShortUtf8DebugString());
+void THive::Handle(TEvents::TEvUndelivered::TPtr &ev) {
+ BLOG_W("THive::Handle::TEvUndelivered Sender=" << ev->Sender << ", Type=" << ev->Get()->SourceType );
+ switch (ev->Get()->SourceType) {
+ case TEvLocal::EvBootTablet: {
+ // restart boot of the tablet (on different node)
+ TTabletId tabletId = ev->Cookie;
+ TLeaderTabletInfo* tablet = FindTablet(tabletId);
+ if (tablet != nullptr && tablet->IsStarting()) {
+ Execute(CreateRestartTablet(tablet->GetFullTabletId()));
+ }
+ break;
+ }
+ case TEvLocal::EvPing: {
+ TNodeId nodeId = ev->Cookie;
+ TNodeInfo* node = FindNode(nodeId);
+ if (node != nullptr && ev->Sender == node->Local) {
+ if (node->IsDisconnecting()) {
+ // ping continiousily until we fully disconnected from the node
+ node->Ping();
+ } else {
+ KillNode(node->Id, node->Local);
+ }
+ }
+ break;
+ }
+ };
+}
+
+void THive::Handle(TEvHive::TEvReassignTablet::TPtr &ev) {
+ BLOG_D("THive::TEvReassignTablet " << ev->Get()->Record.ShortUtf8DebugString());
TLeaderTabletInfo* tablet = FindTablet(ev->Get()->Record.GetTabletID());
- if (tablet != nullptr) {
- tablet->ChannelProfileReassignReason = ev->Get()->Record.GetReassignReason();
- std::bitset<MAX_TABLET_CHANNELS> channelProfileNewGroup;
- const auto& record(ev->Get()->Record);
- auto channels = tablet->GetChannelCount();
- for (ui32 channel : record.GetChannels()) {
- if (channel >= channels) {
- break;
- }
- channelProfileNewGroup.set(channel);
- }
- auto forcedGroupsSize = record.ForcedGroupIDsSize();
- if (forcedGroupsSize > 0) {
- TVector<NKikimrBlobStorage::TEvControllerSelectGroupsResult::TGroupParameters> groups;
- tablet->ChannelProfileNewGroup = channelProfileNewGroup;
- groups.resize(forcedGroupsSize);
- for (ui32 i = 0; i < forcedGroupsSize; ++i) {
- ui32 channel = record.GetChannels(i);
- Y_VERIFY(channel < channels);
- THolder<NKikimrBlobStorage::TEvControllerSelectGroups::TGroupParameters> parameters = BuildGroupParametersForChannel(*tablet, channel);
- if (parameters->HasStoragePoolSpecifier()) {
- groups[i].SetStoragePoolName(parameters->GetStoragePoolSpecifier().GetName());
- }
- if (parameters->HasErasureSpecies()) {
- groups[i].SetErasureSpecies(parameters->GetErasureSpecies());
- }
- groups[i].SetGroupID(record.GetForcedGroupIDs(i));
- }
- Execute(CreateUpdateTabletGroups(tablet->Id, std::move(groups)));
- } else {
- Execute(CreateReassignGroups(tablet->Id, ev.Get()->Sender, channelProfileNewGroup));
- }
- }
-}
-
-void THive::OnActivateExecutor(const TActorContext&) {
- BLOG_D("THive::OnActivateExecutor");
- TDomainsInfo* domainsInfo = AppData()->DomainsInfo.Get();
- HiveUid = domainsInfo->GetDefaultHiveUid(domainsInfo->Domains.begin()->first);
+ if (tablet != nullptr) {
+ tablet->ChannelProfileReassignReason = ev->Get()->Record.GetReassignReason();
+ std::bitset<MAX_TABLET_CHANNELS> channelProfileNewGroup;
+ const auto& record(ev->Get()->Record);
+ auto channels = tablet->GetChannelCount();
+ for (ui32 channel : record.GetChannels()) {
+ if (channel >= channels) {
+ break;
+ }
+ channelProfileNewGroup.set(channel);
+ }
+ auto forcedGroupsSize = record.ForcedGroupIDsSize();
+ if (forcedGroupsSize > 0) {
+ TVector<NKikimrBlobStorage::TEvControllerSelectGroupsResult::TGroupParameters> groups;
+ tablet->ChannelProfileNewGroup = channelProfileNewGroup;
+ groups.resize(forcedGroupsSize);
+ for (ui32 i = 0; i < forcedGroupsSize; ++i) {
+ ui32 channel = record.GetChannels(i);
+ Y_VERIFY(channel < channels);
+ THolder<NKikimrBlobStorage::TEvControllerSelectGroups::TGroupParameters> parameters = BuildGroupParametersForChannel(*tablet, channel);
+ if (parameters->HasStoragePoolSpecifier()) {
+ groups[i].SetStoragePoolName(parameters->GetStoragePoolSpecifier().GetName());
+ }
+ if (parameters->HasErasureSpecies()) {
+ groups[i].SetErasureSpecies(parameters->GetErasureSpecies());
+ }
+ groups[i].SetGroupID(record.GetForcedGroupIDs(i));
+ }
+ Execute(CreateUpdateTabletGroups(tablet->Id, std::move(groups)));
+ } else {
+ Execute(CreateReassignGroups(tablet->Id, ev.Get()->Sender, channelProfileNewGroup));
+ }
+ }
+}
+
+void THive::OnActivateExecutor(const TActorContext&) {
+ BLOG_D("THive::OnActivateExecutor");
+ TDomainsInfo* domainsInfo = AppData()->DomainsInfo.Get();
+ HiveUid = domainsInfo->GetDefaultHiveUid(domainsInfo->Domains.begin()->first);
HiveDomain = domainsInfo->GetHiveDomainUid(HiveUid);
- const TDomainsInfo::TDomain& domain = domainsInfo->GetDomain(HiveDomain);
- RootHiveId = domainsInfo->GetHive(domain.DefaultHiveUid);
+ const TDomainsInfo::TDomain& domain = domainsInfo->GetDomain(HiveDomain);
+ RootHiveId = domainsInfo->GetHive(domain.DefaultHiveUid);
Y_VERIFY(HiveUid != Max<ui32>() && HiveDomain != TDomainsInfo::BadDomainId);
- HiveId = TabletID();
- HiveGeneration = Executor()->Generation();
- RootDomainKey = TSubDomainKey(domain.SchemeRoot, 1);
- RootDomainName = "/" + domain.Name;
+ HiveId = TabletID();
+ HiveGeneration = Executor()->Generation();
+ RootDomainKey = TSubDomainKey(domain.SchemeRoot, 1);
+ RootDomainName = "/" + domain.Name;
Executor()->RegisterExternalTabletCounters(TabletCountersPtr);
- ResourceProfiles = AppData()->ResourceProfiles ? AppData()->ResourceProfiles : new TResourceProfiles;
+ ResourceProfiles = AppData()->ResourceProfiles ? AppData()->ResourceProfiles : new TResourceProfiles;
BuildLocalConfig();
- ClusterConfig = AppData()->HiveConfig;
- Send(NConsole::MakeConfigsDispatcherID(SelfId().NodeId()),
- new NConsole::TEvConfigsDispatcher::TEvSetConfigSubscriptionRequest(NKikimrConsole::TConfigItem::HiveConfigItem));
- Execute(CreateInitScheme());
+ ClusterConfig = AppData()->HiveConfig;
+ Send(NConsole::MakeConfigsDispatcherID(SelfId().NodeId()),
+ new NConsole::TEvConfigsDispatcher::TEvSetConfigSubscriptionRequest(NKikimrConsole::TConfigItem::HiveConfigItem));
+ Execute(CreateInitScheme());
if (!ResponsivenessPinger) {
ResponsivenessPinger = new TTabletResponsivenessPinger(TabletCounters->Simple()[NHive::COUNTER_RESPONSE_TIME_USEC], TDuration::Seconds(1));
ResponsivenessActorID = RegisterWithSameMailbox(ResponsivenessPinger);
}
}
-void THive::DefaultSignalTabletActive(const TActorContext& ctx) {
+void THive::DefaultSignalTabletActive(const TActorContext& ctx) {
Y_UNUSED(ctx);
-}
+}
void THive::AssignTabletGroups(TLeaderTabletInfo& tablet) {
- ui32 channels = tablet.GetChannelCount();
- THashSet<TString> storagePoolsToRefresh;
+ ui32 channels = tablet.GetChannelCount();
+ THashSet<TString> storagePoolsToRefresh;
// was this method called for the first time for this tablet?
- bool firstInvocation = tablet.ChannelProfileNewGroup.none();
+ bool firstInvocation = tablet.ChannelProfileNewGroup.none();
for (ui32 channelId = 0; channelId < channels; ++channelId) {
if (firstInvocation || tablet.ChannelProfileNewGroup.test(channelId)) {
tablet.ChannelProfileNewGroup.set(channelId);
- TStoragePoolInfo& storagePool = tablet.GetStoragePool(channelId);
- if (!storagePool.IsFresh() || storagePool.ConfigurationGeneration != ConfigurationGeneration) {
- storagePoolsToRefresh.insert(storagePool.Name);
+ TStoragePoolInfo& storagePool = tablet.GetStoragePool(channelId);
+ if (!storagePool.IsFresh() || storagePool.ConfigurationGeneration != ConfigurationGeneration) {
+ storagePoolsToRefresh.insert(storagePool.Name);
}
}
}
- if (!storagePoolsToRefresh.empty()) {
- // we had to refresh storage pool state from BSC
- TVector<THolder<NKikimrBlobStorage::TEvControllerSelectGroups::TGroupParameters>> requests;
- for (TString storagePoolName : storagePoolsToRefresh) {
- TStoragePoolInfo& storagePool = GetStoragePool(storagePoolName);
- if (storagePool.AddTabletToWait(tablet.Id)) {
- THolder<NKikimrBlobStorage::TEvControllerSelectGroups::TGroupParameters> item = storagePool.BuildRefreshRequest();
- ++storagePool.RefreshRequestInFlight;
- requests.emplace_back(std::move(item));
- }
- }
- if (!requests.empty()) {
+ if (!storagePoolsToRefresh.empty()) {
+ // we had to refresh storage pool state from BSC
+ TVector<THolder<NKikimrBlobStorage::TEvControllerSelectGroups::TGroupParameters>> requests;
+ for (TString storagePoolName : storagePoolsToRefresh) {
+ TStoragePoolInfo& storagePool = GetStoragePool(storagePoolName);
+ if (storagePool.AddTabletToWait(tablet.Id)) {
+ THolder<NKikimrBlobStorage::TEvControllerSelectGroups::TGroupParameters> item = storagePool.BuildRefreshRequest();
+ ++storagePool.RefreshRequestInFlight;
+ requests.emplace_back(std::move(item));
+ }
+ }
+ if (!requests.empty()) {
THolder<TEvBlobStorage::TEvControllerSelectGroups> ev = MakeHolder<TEvBlobStorage::TEvControllerSelectGroups>();
- NKikimrBlobStorage::TEvControllerSelectGroups& record = ev->Record;
- record.SetReturnAllMatchingGroups(true);
- for (auto& request : requests) {
- record.MutableGroupParameters()->AddAllocated(std::move(request).Release());
- }
- BLOG_D("THive::AssignTabletGroups TEvControllerSelectGroups tablet " << tablet.Id << " " << ev->Record.ShortDebugString());
- SendToBSControllerPipe(ev.Release());
- } else {
- BLOG_D("THive::AssignTabletGroups TEvControllerSelectGroups tablet " << tablet.Id << " waiting for response");
- }
- } else {
- // we ready to update tablet groups immediately
- BLOG_D("THive::AssignTabletGroups CreateUpdateTabletGroups tablet " << tablet.Id);
- Execute(CreateUpdateTabletGroups(tablet.Id));
- }
-}
-
-void THive::SendToBSControllerPipe(IEventBase* payload) {
- if (!BSControllerPipeClient) {
- Y_VERIFY(AppData()->DomainsInfo);
- ui32 domainUid = HiveDomain;
- ui64 defaultStateStorageGroup = AppData()->DomainsInfo->GetDefaultStateStorageGroup(domainUid);
-
- NTabletPipe::TClientConfig pipeConfig;
- pipeConfig.RetryPolicy = NTabletPipe::TClientRetryPolicy::WithRetries();
- BSControllerPipeClient = Register(NTabletPipe::CreateClient(
+ NKikimrBlobStorage::TEvControllerSelectGroups& record = ev->Record;
+ record.SetReturnAllMatchingGroups(true);
+ for (auto& request : requests) {
+ record.MutableGroupParameters()->AddAllocated(std::move(request).Release());
+ }
+ BLOG_D("THive::AssignTabletGroups TEvControllerSelectGroups tablet " << tablet.Id << " " << ev->Record.ShortDebugString());
+ SendToBSControllerPipe(ev.Release());
+ } else {
+ BLOG_D("THive::AssignTabletGroups TEvControllerSelectGroups tablet " << tablet.Id << " waiting for response");
+ }
+ } else {
+ // we ready to update tablet groups immediately
+ BLOG_D("THive::AssignTabletGroups CreateUpdateTabletGroups tablet " << tablet.Id);
+ Execute(CreateUpdateTabletGroups(tablet.Id));
+ }
+}
+
+void THive::SendToBSControllerPipe(IEventBase* payload) {
+ if (!BSControllerPipeClient) {
+ Y_VERIFY(AppData()->DomainsInfo);
+ ui32 domainUid = HiveDomain;
+ ui64 defaultStateStorageGroup = AppData()->DomainsInfo->GetDefaultStateStorageGroup(domainUid);
+
+ NTabletPipe::TClientConfig pipeConfig;
+ pipeConfig.RetryPolicy = NTabletPipe::TClientRetryPolicy::WithRetries();
+ BSControllerPipeClient = Register(NTabletPipe::CreateClient(
SelfId(), MakeBSControllerID(defaultStateStorageGroup), pipeConfig));
- }
- NTabletPipe::SendData(SelfId(), BSControllerPipeClient, payload);
-}
-
-void THive::SendToRootHivePipe(IEventBase* payload) {
- if (!RootHivePipeClient) {
- NTabletPipe::TClientConfig pipeConfig;
- pipeConfig.RetryPolicy = NTabletPipe::TClientRetryPolicy::WithRetries();
+ }
+ NTabletPipe::SendData(SelfId(), BSControllerPipeClient, payload);
+}
+
+void THive::SendToRootHivePipe(IEventBase* payload) {
+ if (!RootHivePipeClient) {
+ NTabletPipe::TClientConfig pipeConfig;
+ pipeConfig.RetryPolicy = NTabletPipe::TClientRetryPolicy::WithRetries();
RootHivePipeClient = Register(NTabletPipe::CreateClient(SelfId(), RootHiveId, pipeConfig));
- }
- NTabletPipe::SendData(SelfId(), RootHivePipeClient, payload);
-}
-
-void THive::RestartBSControllerPipe() {
- BLOG_D("THive::RestartBSControllerPipe");
- if (BSControllerPipeClient) {
- NTabletPipe::CloseClient(SelfId(), BSControllerPipeClient);
+ }
+ NTabletPipe::SendData(SelfId(), RootHivePipeClient, payload);
+}
+
+void THive::RestartBSControllerPipe() {
+ BLOG_D("THive::RestartBSControllerPipe");
+ if (BSControllerPipeClient) {
+ NTabletPipe::CloseClient(SelfId(), BSControllerPipeClient);
BSControllerPipeClient = TActorId();
- }
- RequestPoolsInformation();
- for (auto it = Tablets.begin(); it != Tablets.end(); ++it) {
+ }
+ RequestPoolsInformation();
+ for (auto it = Tablets.begin(); it != Tablets.end(); ++it) {
TLeaderTabletInfo& tablet(it->second);
- if (tablet.IsReadyToAssignGroups()) {
- tablet.ResetTabletGroupsRequests();
- tablet.InitiateAssignTabletGroups();
- }
- }
-}
-
-void THive::RestartRootHivePipe() {
- BLOG_D("THive::RestartRootHivePipe");
- if (RootHivePipeClient) {
- NTabletPipe::CloseClient(SelfId(), RootHivePipeClient);
+ if (tablet.IsReadyToAssignGroups()) {
+ tablet.ResetTabletGroupsRequests();
+ tablet.InitiateAssignTabletGroups();
+ }
+ }
+}
+
+void THive::RestartRootHivePipe() {
+ BLOG_D("THive::RestartRootHivePipe");
+ if (RootHivePipeClient) {
+ NTabletPipe::CloseClient(SelfId(), RootHivePipeClient);
RootHivePipeClient = TActorId();
- }
- // trying to retry for free sequence request
- if (RequestingSequenceNow) {
- RequestFreeSequence();
- }
- // trying to restart migration
- if (MigrationState == NKikimrHive::EMigrationState::MIGRATION_ACTIVE) {
- SendToRootHivePipe(new TEvHive::TEvSeizeTablets(MigrationFilter));
- }
-}
-
-void THive::Handle(TEvTabletBase::TEvBlockBlobStorageResult::TPtr &ev) {
- Execute(CreateBlockStorageResult(ev));
-}
-
-void THive::Handle(TEvTabletBase::TEvDeleteTabletResult::TPtr &ev) {
- Execute(CreateDeleteTabletResult(ev));
-}
-
-template <>
-TNodeInfo* THive::SelectNode<NKikimrConfig::THiveConfig::HIVE_NODE_SELECT_STRATEGY_RANDOM>(const std::vector<THive::TSelectedNode>& selectedNodes) {
- if (selectedNodes.empty()) {
- return nullptr;
- }
- return selectedNodes[TAppData::RandomProvider->GenRand() % selectedNodes.size()].Node;
-}
-
-template <>
-TNodeInfo* THive::SelectNode<NKikimrConfig::THiveConfig::HIVE_NODE_SELECT_STRATEGY_WEIGHTED_RANDOM>(const std::vector<THive::TSelectedNode>& selectedNodes) {
- if (selectedNodes.empty()) {
- return nullptr;
- }
- double sumUsage = 0;
- double maxUsage = 0;
- for (const TSelectedNode& selectedNode : selectedNodes) {
- double usage = selectedNode.Usage;
- sumUsage += usage;
- maxUsage = std::max(maxUsage, usage);
- }
- double sumAvail = maxUsage * selectedNodes.size() - sumUsage;
- if (sumAvail > 0) {
- double pos = TAppData::RandomProvider->GenRandReal2() * sumAvail;
- for (const TSelectedNode& selectedNode : selectedNodes) {
- double avail = maxUsage - selectedNode.Usage;
- if (pos < avail) {
- return selectedNode.Node;
- } else {
- pos -= avail;
- }
- }
- }
- return SelectNode<NKikimrConfig::THiveConfig::HIVE_NODE_SELECT_STRATEGY_RANDOM>(selectedNodes);
-}
-
-template <>
-TNodeInfo* THive::SelectNode<NKikimrConfig::THiveConfig::HIVE_NODE_SELECT_STRATEGY_EXACT_MIN>(const std::vector<THive::TSelectedNode>& selectedNodes) {
- if (selectedNodes.empty()) {
- return nullptr;
- }
- auto itMin = std::min_element(selectedNodes.begin(), selectedNodes.end());
- return itMin->Node;
-}
-
-template <>
-TNodeInfo* THive::SelectNode<NKikimrConfig::THiveConfig::HIVE_NODE_SELECT_STRATEGY_RANDOM_MIN_7P>(const std::vector<THive::TSelectedNode>& selectedNodes) {
- if (selectedNodes.empty()) {
- return nullptr;
- }
- std::vector<TSelectedNode> nodes(selectedNodes);
- auto itNode = nodes.begin();
- auto itPartition = itNode;
- size_t percent7 = std::max<size_t>(nodes.size() * 7 / 100, 1);
- std::advance(itPartition, percent7);
- std::nth_element(nodes.begin(), itPartition, nodes.end());
- std::advance(itNode, TAppData::RandomProvider->GenRand64() % percent7);
- return itNode->Node;
-}
-
-THive::TBestNodeResult THive::FindBestNode(const TTabletInfo& tablet) {
- BLOG_D("[FBN] Finding best node for tablet " << tablet.ToString());
- BLOG_TRACE("[FBN] Tablet " << tablet.ToString() << " family " << tablet.FamilyString());
-
- if (tablet.PreferredNodeId != 0) {
- TNodeInfo* node = FindNode(tablet.PreferredNodeId);
- if (node != nullptr) {
- if (node->IsAlive() && node->IsAllowedToRunTablet(tablet) && node->IsAbleToScheduleTablet() && node->IsAbleToRunTablet(tablet)) {
- BLOG_TRACE("[FBN] Tablet " << tablet.ToString() << " choose node " << node->Id << " because of preferred node");
- return TBestNodeResult(*node);
- }
- if (node->Freeze) {
- BLOG_TRACE("[FBN] Tablet " << tablet.ToString() << " preferred to freezed node " << node->Id);
- tablet.BootState = TStringBuilder() << "Preferred to freezed node " << node->Id;
- return TBestNodeResult(true);
- }
- }
- }
-
- /*
- TNodeInfo* bestNodeInfo = nullptr;
- double bestUsage = 0;
- if (tablet.IsAlive() && tablet.Node->IsAllowedToRunTablet(tablet) && !tablet.Node->IsOverloaded()) {
- bestNodeInfo = &(Nodes.find(tablet.Node->Id)->second);
- bestUsage = tablet.Node->GetNodeUsageForTablet(tablet);
- BLOG_TRACE("[FBN] Tablet " << tablet.ToString() << " starting with usage " << Sprintf("%.9f", bestUsage) << " of node " << bestNodeInfo->Id);
- }
- */
-
- TTabletDebugState debugState;
- std::vector<NKikimrHive::TDataCentersGroup> dataCentersGroupsHolder;
- std::vector<const NKikimrHive::TDataCentersGroup*> dataCentersGroupsPointers;
- TArrayRef<const NKikimrHive::TDataCentersGroup*> dataCentersGroups; // std::span
-
+ }
+ // trying to retry for free sequence request
+ if (RequestingSequenceNow) {
+ RequestFreeSequence();
+ }
+ // trying to restart migration
+ if (MigrationState == NKikimrHive::EMigrationState::MIGRATION_ACTIVE) {
+ SendToRootHivePipe(new TEvHive::TEvSeizeTablets(MigrationFilter));
+ }
+}
+
+void THive::Handle(TEvTabletBase::TEvBlockBlobStorageResult::TPtr &ev) {
+ Execute(CreateBlockStorageResult(ev));
+}
+
+void THive::Handle(TEvTabletBase::TEvDeleteTabletResult::TPtr &ev) {
+ Execute(CreateDeleteTabletResult(ev));
+}
+
+template <>
+TNodeInfo* THive::SelectNode<NKikimrConfig::THiveConfig::HIVE_NODE_SELECT_STRATEGY_RANDOM>(const std::vector<THive::TSelectedNode>& selectedNodes) {
+ if (selectedNodes.empty()) {
+ return nullptr;
+ }
+ return selectedNodes[TAppData::RandomProvider->GenRand() % selectedNodes.size()].Node;
+}
+
+template <>
+TNodeInfo* THive::SelectNode<NKikimrConfig::THiveConfig::HIVE_NODE_SELECT_STRATEGY_WEIGHTED_RANDOM>(const std::vector<THive::TSelectedNode>& selectedNodes) {
+ if (selectedNodes.empty()) {
+ return nullptr;
+ }
+ double sumUsage = 0;
+ double maxUsage = 0;
+ for (const TSelectedNode& selectedNode : selectedNodes) {
+ double usage = selectedNode.Usage;
+ sumUsage += usage;
+ maxUsage = std::max(maxUsage, usage);
+ }
+ double sumAvail = maxUsage * selectedNodes.size() - sumUsage;
+ if (sumAvail > 0) {
+ double pos = TAppData::RandomProvider->GenRandReal2() * sumAvail;
+ for (const TSelectedNode& selectedNode : selectedNodes) {
+ double avail = maxUsage - selectedNode.Usage;
+ if (pos < avail) {
+ return selectedNode.Node;
+ } else {
+ pos -= avail;
+ }
+ }
+ }
+ return SelectNode<NKikimrConfig::THiveConfig::HIVE_NODE_SELECT_STRATEGY_RANDOM>(selectedNodes);
+}
+
+template <>
+TNodeInfo* THive::SelectNode<NKikimrConfig::THiveConfig::HIVE_NODE_SELECT_STRATEGY_EXACT_MIN>(const std::vector<THive::TSelectedNode>& selectedNodes) {
+ if (selectedNodes.empty()) {
+ return nullptr;
+ }
+ auto itMin = std::min_element(selectedNodes.begin(), selectedNodes.end());
+ return itMin->Node;
+}
+
+template <>
+TNodeInfo* THive::SelectNode<NKikimrConfig::THiveConfig::HIVE_NODE_SELECT_STRATEGY_RANDOM_MIN_7P>(const std::vector<THive::TSelectedNode>& selectedNodes) {
+ if (selectedNodes.empty()) {
+ return nullptr;
+ }
+ std::vector<TSelectedNode> nodes(selectedNodes);
+ auto itNode = nodes.begin();
+ auto itPartition = itNode;
+ size_t percent7 = std::max<size_t>(nodes.size() * 7 / 100, 1);
+ std::advance(itPartition, percent7);
+ std::nth_element(nodes.begin(), itPartition, nodes.end());
+ std::advance(itNode, TAppData::RandomProvider->GenRand64() % percent7);
+ return itNode->Node;
+}
+
+THive::TBestNodeResult THive::FindBestNode(const TTabletInfo& tablet) {
+ BLOG_D("[FBN] Finding best node for tablet " << tablet.ToString());
+ BLOG_TRACE("[FBN] Tablet " << tablet.ToString() << " family " << tablet.FamilyString());
+
+ if (tablet.PreferredNodeId != 0) {
+ TNodeInfo* node = FindNode(tablet.PreferredNodeId);
+ if (node != nullptr) {
+ if (node->IsAlive() && node->IsAllowedToRunTablet(tablet) && node->IsAbleToScheduleTablet() && node->IsAbleToRunTablet(tablet)) {
+ BLOG_TRACE("[FBN] Tablet " << tablet.ToString() << " choose node " << node->Id << " because of preferred node");
+ return TBestNodeResult(*node);
+ }
+ if (node->Freeze) {
+ BLOG_TRACE("[FBN] Tablet " << tablet.ToString() << " preferred to freezed node " << node->Id);
+ tablet.BootState = TStringBuilder() << "Preferred to freezed node " << node->Id;
+ return TBestNodeResult(true);
+ }
+ }
+ }
+
+ /*
+ TNodeInfo* bestNodeInfo = nullptr;
+ double bestUsage = 0;
+ if (tablet.IsAlive() && tablet.Node->IsAllowedToRunTablet(tablet) && !tablet.Node->IsOverloaded()) {
+ bestNodeInfo = &(Nodes.find(tablet.Node->Id)->second);
+ bestUsage = tablet.Node->GetNodeUsageForTablet(tablet);
+ BLOG_TRACE("[FBN] Tablet " << tablet.ToString() << " starting with usage " << Sprintf("%.9f", bestUsage) << " of node " << bestNodeInfo->Id);
+ }
+ */
+
+ TTabletDebugState debugState;
+ std::vector<NKikimrHive::TDataCentersGroup> dataCentersGroupsHolder;
+ std::vector<const NKikimrHive::TDataCentersGroup*> dataCentersGroupsPointers;
+ TArrayRef<const NKikimrHive::TDataCentersGroup*> dataCentersGroups; // std::span
+
if (tablet.IsLeader()) {
const TLeaderTabletInfo& leader(tablet.GetLeader());
- dataCentersGroups = TArrayRef<const NKikimrHive::TDataCentersGroup*>(
+ dataCentersGroups = TArrayRef<const NKikimrHive::TDataCentersGroup*>(
const_cast<const NKikimrHive::TDataCentersGroup**>(leader.DataCentersPreference.GetDataCentersGroups().data()),
leader.DataCentersPreference.GetDataCentersGroups().size());
- if (dataCentersGroups.empty()) {
+ if (dataCentersGroups.empty()) {
dataCentersGroups = GetDefaultDataCentersPreference(leader.Type);
- }
- if (dataCentersGroups.empty()) {
+ }
+ if (dataCentersGroups.empty()) {
if (leader.Category) {
- std::unordered_map<TDataCenterId, ui32> dcTablets;
+ std::unordered_map<TDataCenterId, ui32> dcTablets;
for (TLeaderTabletInfo* tab : leader.Category->Tablets) {
- if (tab->IsAlive()) {
- TDataCenterId dc = tab->Node->GetDataCenter();
- dcTablets[dc]++;
- }
- }
- if (!dcTablets.empty()) {
- dataCentersGroupsHolder.resize(dcTablets.size());
- dataCentersGroupsPointers.resize(dcTablets.size());
- std::vector<TDataCenterId> dcs;
- for (const auto& [dc, count] : dcTablets) {
- dcs.push_back(dc);
- }
- std::sort(dcs.begin(), dcs.end(), [&](TDataCenterId a, TDataCenterId b) -> bool {
- return dcTablets[a] > dcTablets[b];
- });
- for (size_t i = 0; i < dcs.size(); ++i) {
- dataCentersGroupsHolder[i].AddDataCenter(dcs[i]);
+ if (tab->IsAlive()) {
+ TDataCenterId dc = tab->Node->GetDataCenter();
+ dcTablets[dc]++;
+ }
+ }
+ if (!dcTablets.empty()) {
+ dataCentersGroupsHolder.resize(dcTablets.size());
+ dataCentersGroupsPointers.resize(dcTablets.size());
+ std::vector<TDataCenterId> dcs;
+ for (const auto& [dc, count] : dcTablets) {
+ dcs.push_back(dc);
+ }
+ std::sort(dcs.begin(), dcs.end(), [&](TDataCenterId a, TDataCenterId b) -> bool {
+ return dcTablets[a] > dcTablets[b];
+ });
+ for (size_t i = 0; i < dcs.size(); ++i) {
+ dataCentersGroupsHolder[i].AddDataCenter(dcs[i]);
dataCentersGroupsHolder[i].AddDataCenterNum(DataCenterFromString(dcs[i]));
dataCentersGroupsPointers[i] = dataCentersGroupsHolder.data() + i;
- }
- dataCentersGroups = TArrayRef<const NKikimrHive::TDataCentersGroup*>(dataCentersGroupsPointers.data(), dcTablets.size());
- }
- }
- }
- if (!dataCentersGroups.empty()) {
- BLOG_TRACE("[FBN] Tablet " << tablet.ToString() << " using DC preference: " << dataCentersGroups);
- }
- }
-
- std::vector<std::vector<TNodeInfo*>> candidateGroups;
- candidateGroups.resize(dataCentersGroups.size() + 1);
- std::unordered_map<TDataCenterId, std::vector<TNodeInfo*>*> indexDC2Group;
- for (size_t numGroup = 0; numGroup < dataCentersGroups.size(); ++numGroup) {
- const NKikimrHive::TDataCentersGroup* dcGroup = dataCentersGroups[numGroup];
+ }
+ dataCentersGroups = TArrayRef<const NKikimrHive::TDataCentersGroup*>(dataCentersGroupsPointers.data(), dcTablets.size());
+ }
+ }
+ }
+ if (!dataCentersGroups.empty()) {
+ BLOG_TRACE("[FBN] Tablet " << tablet.ToString() << " using DC preference: " << dataCentersGroups);
+ }
+ }
+
+ std::vector<std::vector<TNodeInfo*>> candidateGroups;
+ candidateGroups.resize(dataCentersGroups.size() + 1);
+ std::unordered_map<TDataCenterId, std::vector<TNodeInfo*>*> indexDC2Group;
+ for (size_t numGroup = 0; numGroup < dataCentersGroups.size(); ++numGroup) {
+ const NKikimrHive::TDataCentersGroup* dcGroup = dataCentersGroups[numGroup];
if (dcGroup->DataCenterSize()) {
for (TDataCenterId dc : dcGroup->GetDataCenter()) {
indexDC2Group[dc] = candidateGroups.data() + numGroup;
@@ -1110,486 +1110,486 @@ THive::TBestNodeResult THive::FindBestNode(const TTabletInfo& tablet) {
for (const ui64 dcId : dcGroup->GetDataCenterNum()) {
indexDC2Group[DataCenterToString(dcId)] = candidateGroups.data() + numGroup;
}
- }
- }
- for (auto it = Nodes.begin(); it != Nodes.end(); ++it) {
- TNodeInfo* nodeInfo = &it->second;
- if (nodeInfo->IsAlive()) {
- TDataCenterId dataCenterId = nodeInfo->GetDataCenter();
- auto itDataCenter = indexDC2Group.find(dataCenterId);
- if (itDataCenter != indexDC2Group.end()) {
- itDataCenter->second->push_back(nodeInfo);
- } else {
- candidateGroups.back().push_back(nodeInfo);
- }
- } else {
- BLOG_TRACE("[FBN] Tablet " << tablet.ToString() << " node " << nodeInfo->Id << " is not alive");
- debugState.NodesDead++;
- }
- }
-
- TVector<TSelectedNode> selectedNodes;
-
- for (auto itCandidateNodes = candidateGroups.begin(); itCandidateNodes != candidateGroups.end(); ++itCandidateNodes) {
- const std::vector<TNodeInfo*>& candidateNodes(*itCandidateNodes);
- if (candidateGroups.size() > 1) {
- BLOG_TRACE("[FBN] Tablet " << tablet.ToString()
- << " checking candidates group " << (itCandidateNodes - candidateGroups.begin() + 1)
- << " of " << candidateGroups.size());
- }
-
- selectedNodes.clear();
- selectedNodes.reserve(candidateNodes.size());
-
- for (auto it = candidateNodes.begin(); it != candidateNodes.end(); ++it) {
- TNodeInfo& nodeInfo = *(*it);
- if (nodeInfo.IsAllowedToRunTablet(tablet, &debugState)) {
- if (nodeInfo.IsAbleToScheduleTablet()) {
- if (nodeInfo.IsAbleToRunTablet(tablet, &debugState)) {
- double usage = nodeInfo.GetNodeUsageForTablet(tablet);
- selectedNodes.emplace_back(usage, &nodeInfo);
- BLOG_TRACE("[FBN] Tablet " << tablet.ToString() << " selected usage " << Sprintf("%.9f", usage) << " of node " << nodeInfo.Id);
- } else {
- BLOG_TRACE("[FBN] Tablet " << tablet.ToString() << " node " << nodeInfo.Id << " is not able to run the tablet");
- }
- } else {
- BLOG_TRACE("[FBN] Tablet " << tablet.ToString() << " node " << nodeInfo.Id << " is not able to schedule the tablet");
- tablet.BootState = BootStateTooManyStarting;
- return TBestNodeResult(false);
- }
- } else {
- BLOG_TRACE("[FBN] Node " << nodeInfo.Id << " is not allowed"
- << " to run the tablet " << tablet.ToString()
- << " node domains " << nodeInfo.ServicedDomains
+ }
+ }
+ for (auto it = Nodes.begin(); it != Nodes.end(); ++it) {
+ TNodeInfo* nodeInfo = &it->second;
+ if (nodeInfo->IsAlive()) {
+ TDataCenterId dataCenterId = nodeInfo->GetDataCenter();
+ auto itDataCenter = indexDC2Group.find(dataCenterId);
+ if (itDataCenter != indexDC2Group.end()) {
+ itDataCenter->second->push_back(nodeInfo);
+ } else {
+ candidateGroups.back().push_back(nodeInfo);
+ }
+ } else {
+ BLOG_TRACE("[FBN] Tablet " << tablet.ToString() << " node " << nodeInfo->Id << " is not alive");
+ debugState.NodesDead++;
+ }
+ }
+
+ TVector<TSelectedNode> selectedNodes;
+
+ for (auto itCandidateNodes = candidateGroups.begin(); itCandidateNodes != candidateGroups.end(); ++itCandidateNodes) {
+ const std::vector<TNodeInfo*>& candidateNodes(*itCandidateNodes);
+ if (candidateGroups.size() > 1) {
+ BLOG_TRACE("[FBN] Tablet " << tablet.ToString()
+ << " checking candidates group " << (itCandidateNodes - candidateGroups.begin() + 1)
+ << " of " << candidateGroups.size());
+ }
+
+ selectedNodes.clear();
+ selectedNodes.reserve(candidateNodes.size());
+
+ for (auto it = candidateNodes.begin(); it != candidateNodes.end(); ++it) {
+ TNodeInfo& nodeInfo = *(*it);
+ if (nodeInfo.IsAllowedToRunTablet(tablet, &debugState)) {
+ if (nodeInfo.IsAbleToScheduleTablet()) {
+ if (nodeInfo.IsAbleToRunTablet(tablet, &debugState)) {
+ double usage = nodeInfo.GetNodeUsageForTablet(tablet);
+ selectedNodes.emplace_back(usage, &nodeInfo);
+ BLOG_TRACE("[FBN] Tablet " << tablet.ToString() << " selected usage " << Sprintf("%.9f", usage) << " of node " << nodeInfo.Id);
+ } else {
+ BLOG_TRACE("[FBN] Tablet " << tablet.ToString() << " node " << nodeInfo.Id << " is not able to run the tablet");
+ }
+ } else {
+ BLOG_TRACE("[FBN] Tablet " << tablet.ToString() << " node " << nodeInfo.Id << " is not able to schedule the tablet");
+ tablet.BootState = BootStateTooManyStarting;
+ return TBestNodeResult(false);
+ }
+ } else {
+ BLOG_TRACE("[FBN] Node " << nodeInfo.Id << " is not allowed"
+ << " to run the tablet " << tablet.ToString()
+ << " node domains " << nodeInfo.ServicedDomains
<< " tablet object domain " << tablet.GetLeader().ObjectDomain
<< " tablet allowed domains " << tablet.GetLeader().EffectiveAllowedDomains);
- }
- }
- if (!selectedNodes.empty()) {
- break;
- }
- }
- TNodeInfo* selectedNode = nullptr;
- if (!selectedNodes.empty()) {
- switch (GetNodeSelectStrategy()) {
- case NKikimrConfig::THiveConfig::HIVE_NODE_SELECT_STRATEGY_WEIGHTED_RANDOM:
- selectedNode = SelectNode<NKikimrConfig::THiveConfig::HIVE_NODE_SELECT_STRATEGY_WEIGHTED_RANDOM>(selectedNodes);
- break;
- case NKikimrConfig::THiveConfig::HIVE_NODE_SELECT_STRATEGY_EXACT_MIN:
- selectedNode = SelectNode<NKikimrConfig::THiveConfig::HIVE_NODE_SELECT_STRATEGY_EXACT_MIN>(selectedNodes);
- break;
- case NKikimrConfig::THiveConfig::HIVE_NODE_SELECT_STRATEGY_RANDOM_MIN_7P:
- selectedNode = SelectNode<NKikimrConfig::THiveConfig::HIVE_NODE_SELECT_STRATEGY_RANDOM_MIN_7P>(selectedNodes);
- break;
- case NKikimrConfig::THiveConfig::HIVE_NODE_SELECT_STRATEGY_RANDOM:
- default:
- selectedNode = SelectNode<NKikimrConfig::THiveConfig::HIVE_NODE_SELECT_STRATEGY_RANDOM>(selectedNodes);
- break;
- }
- }
- if (selectedNode != nullptr) {
- BLOG_TRACE("[FBN] Tablet " << tablet.ToString() << " selected node " << selectedNode->Id);
- tablet.BootState = BootStateStarting;
- return TBestNodeResult(*selectedNode);
- } else {
- BLOG_TRACE("[FBN] Tablet " << tablet.ToString() << " no node was selected");
-
- ui32 nodesLeft = Nodes.size();
-
+ }
+ }
+ if (!selectedNodes.empty()) {
+ break;
+ }
+ }
+ TNodeInfo* selectedNode = nullptr;
+ if (!selectedNodes.empty()) {
+ switch (GetNodeSelectStrategy()) {
+ case NKikimrConfig::THiveConfig::HIVE_NODE_SELECT_STRATEGY_WEIGHTED_RANDOM:
+ selectedNode = SelectNode<NKikimrConfig::THiveConfig::HIVE_NODE_SELECT_STRATEGY_WEIGHTED_RANDOM>(selectedNodes);
+ break;
+ case NKikimrConfig::THiveConfig::HIVE_NODE_SELECT_STRATEGY_EXACT_MIN:
+ selectedNode = SelectNode<NKikimrConfig::THiveConfig::HIVE_NODE_SELECT_STRATEGY_EXACT_MIN>(selectedNodes);
+ break;
+ case NKikimrConfig::THiveConfig::HIVE_NODE_SELECT_STRATEGY_RANDOM_MIN_7P:
+ selectedNode = SelectNode<NKikimrConfig::THiveConfig::HIVE_NODE_SELECT_STRATEGY_RANDOM_MIN_7P>(selectedNodes);
+ break;
+ case NKikimrConfig::THiveConfig::HIVE_NODE_SELECT_STRATEGY_RANDOM:
+ default:
+ selectedNode = SelectNode<NKikimrConfig::THiveConfig::HIVE_NODE_SELECT_STRATEGY_RANDOM>(selectedNodes);
+ break;
+ }
+ }
+ if (selectedNode != nullptr) {
+ BLOG_TRACE("[FBN] Tablet " << tablet.ToString() << " selected node " << selectedNode->Id);
+ tablet.BootState = BootStateStarting;
+ return TBestNodeResult(*selectedNode);
+ } else {
+ BLOG_TRACE("[FBN] Tablet " << tablet.ToString() << " no node was selected");
+
+ ui32 nodesLeft = Nodes.size();
+
if (tablet.IsFollower() && debugState.LeaderNotRunning) {
tablet.BootState = BootStateLeaderNotRunning;
- return TBestNodeResult(true);
- }
- if (debugState.NodesDead == nodesLeft) {
- tablet.BootState = BootStateAllNodesAreDead;
- return TBestNodeResult(true);
- }
- nodesLeft -= debugState.NodesDead;
- if (debugState.NodesDown == nodesLeft) {
- tablet.BootState = BootStateAllNodesAreDeadOrDown;
- return TBestNodeResult(true);
- }
- nodesLeft -= debugState.NodesDown;
- if (debugState.NodesNotAllowed + debugState.NodesInDatacentersNotAllowed == nodesLeft) {
- tablet.BootState = BootStateNoNodesAllowedToRun;
- return TBestNodeResult(true);
- }
- nodesLeft -= debugState.NodesNotAllowed;
- nodesLeft -= debugState.NodesInDatacentersNotAllowed;
- if (debugState.NodesWithSomeoneFromOurFamily == nodesLeft) {
- tablet.BootState = BootStateWeFilledAllAvailableNodes;
- return TBestNodeResult(true);
- }
- nodesLeft -= debugState.NodesWithSomeoneFromOurFamily;
- if (debugState.NodesWithoutDomain == nodesLeft) {
+ return TBestNodeResult(true);
+ }
+ if (debugState.NodesDead == nodesLeft) {
+ tablet.BootState = BootStateAllNodesAreDead;
+ return TBestNodeResult(true);
+ }
+ nodesLeft -= debugState.NodesDead;
+ if (debugState.NodesDown == nodesLeft) {
+ tablet.BootState = BootStateAllNodesAreDeadOrDown;
+ return TBestNodeResult(true);
+ }
+ nodesLeft -= debugState.NodesDown;
+ if (debugState.NodesNotAllowed + debugState.NodesInDatacentersNotAllowed == nodesLeft) {
+ tablet.BootState = BootStateNoNodesAllowedToRun;
+ return TBestNodeResult(true);
+ }
+ nodesLeft -= debugState.NodesNotAllowed;
+ nodesLeft -= debugState.NodesInDatacentersNotAllowed;
+ if (debugState.NodesWithSomeoneFromOurFamily == nodesLeft) {
+ tablet.BootState = BootStateWeFilledAllAvailableNodes;
+ return TBestNodeResult(true);
+ }
+ nodesLeft -= debugState.NodesWithSomeoneFromOurFamily;
+ if (debugState.NodesWithoutDomain == nodesLeft) {
tablet.BootState = TStringBuilder() << "Can't find domain " << tablet.GetLeader().EffectiveAllowedDomains;
- return TBestNodeResult(true);
- }
- nodesLeft -= debugState.NodesWithoutDomain;
+ return TBestNodeResult(true);
+ }
+ nodesLeft -= debugState.NodesWithoutDomain;
if (tablet.IsFollower() && debugState.NodesFilledWithDatacenterFollowers == nodesLeft) {
- tablet.BootState = BootStateNotEnoughDatacenters;
- return TBestNodeResult(true);
- }
- if (debugState.NodesWithoutResources == nodesLeft) {
- tablet.BootState = BootStateNotEnoughResources;
- return TBestNodeResult(true);
- }
- if (debugState.NodesWithoutLocation == nodesLeft) {
- tablet.BootState = BootStateNodesLocationUnknown;
- return TBestNodeResult(true);
- }
-
- TStringBuilder state;
-
+ tablet.BootState = BootStateNotEnoughDatacenters;
+ return TBestNodeResult(true);
+ }
+ if (debugState.NodesWithoutResources == nodesLeft) {
+ tablet.BootState = BootStateNotEnoughResources;
+ return TBestNodeResult(true);
+ }
+ if (debugState.NodesWithoutLocation == nodesLeft) {
+ tablet.BootState = BootStateNodesLocationUnknown;
+ return TBestNodeResult(true);
+ }
+
+ TStringBuilder state;
+
if (debugState.LeaderNotRunning) {
state << "LeaderNotRunning;";
- }
- if (debugState.NodesDead) {
- state << "NodesDead:" << debugState.NodesDead << ";";
- }
- if (debugState.NodesDown) {
- state << "NodesDown:" << debugState.NodesDown << ";";
- }
- if (debugState.NodesNotAllowed) {
- state << "NodesNotAllowed:" << debugState.NodesNotAllowed << ";";
- }
- if (debugState.NodesInDatacentersNotAllowed) {
- state << "NodesInDatacentersNotAllowed:" << debugState.NodesInDatacentersNotAllowed << ";";
- }
+ }
+ if (debugState.NodesDead) {
+ state << "NodesDead:" << debugState.NodesDead << ";";
+ }
+ if (debugState.NodesDown) {
+ state << "NodesDown:" << debugState.NodesDown << ";";
+ }
+ if (debugState.NodesNotAllowed) {
+ state << "NodesNotAllowed:" << debugState.NodesNotAllowed << ";";
+ }
+ if (debugState.NodesInDatacentersNotAllowed) {
+ state << "NodesInDatacentersNotAllowed:" << debugState.NodesInDatacentersNotAllowed << ";";
+ }
if (debugState.NodesWithLeaderNotLocal) {
state << "NodesWithLeaderNotLocal:" << debugState.NodesWithLeaderNotLocal << ";";
- }
- if (debugState.NodesWithoutDomain) {
- state << "NodesWithoutDomain:" << debugState.NodesWithoutDomain << ";";
- }
+ }
+ if (debugState.NodesWithoutDomain) {
+ state << "NodesWithoutDomain:" << debugState.NodesWithoutDomain << ";";
+ }
if (debugState.NodesFilledWithDatacenterFollowers) {
state << "NodesFilledWithDatacenterFollowers:" << debugState.NodesFilledWithDatacenterFollowers << ";";
- }
- if (debugState.NodesWithoutResources) {
- state << "NodesWithoutResources:" << debugState.NodesWithoutResources << ";";
- }
- if (debugState.NodesWithSomeoneFromOurFamily) {
- state << "NodesWithSomeoneFromOurFamily:" << debugState.NodesWithSomeoneFromOurFamily << ";";
- }
- if (debugState.NodesWithoutLocation) {
- state << "NodesWithoutLocation:" << debugState.NodesWithoutLocation << ";";
- }
- tablet.BootState = state;
-
- return TBestNodeResult(true);
- }
-}
-
+ }
+ if (debugState.NodesWithoutResources) {
+ state << "NodesWithoutResources:" << debugState.NodesWithoutResources << ";";
+ }
+ if (debugState.NodesWithSomeoneFromOurFamily) {
+ state << "NodesWithSomeoneFromOurFamily:" << debugState.NodesWithSomeoneFromOurFamily << ";";
+ }
+ if (debugState.NodesWithoutLocation) {
+ state << "NodesWithoutLocation:" << debugState.NodesWithoutLocation << ";";
+ }
+ tablet.BootState = state;
+
+ return TBestNodeResult(true);
+ }
+}
+
const TNodeLocation& THive::GetNodeLocation(TNodeId nodeId) const {
auto it = NodesInfo.find(nodeId);
if (it != NodesInfo.end())
return it->second.Location;
static TNodeLocation defaultLocation;
- return defaultLocation;
-}
-
-TNodeInfo& THive::GetNode(TNodeId nodeId) {
- auto it = Nodes.find(nodeId);
- if (it == Nodes.end()) {
- it = Nodes.emplace(std::piecewise_construct, std::tuple<TNodeId>(nodeId), std::tuple<TNodeId, THive&>(nodeId, *this)).first;
- }
- return it->second;
-}
-
-TNodeInfo* THive::FindNode(TNodeId nodeId) {
- auto it = Nodes.find(nodeId);
- if (it == Nodes.end())
- return nullptr;
- return &it->second;
-}
-
+ return defaultLocation;
+}
+
+TNodeInfo& THive::GetNode(TNodeId nodeId) {
+ auto it = Nodes.find(nodeId);
+ if (it == Nodes.end()) {
+ it = Nodes.emplace(std::piecewise_construct, std::tuple<TNodeId>(nodeId), std::tuple<TNodeId, THive&>(nodeId, *this)).first;
+ }
+ return it->second;
+}
+
+TNodeInfo* THive::FindNode(TNodeId nodeId) {
+ auto it = Nodes.find(nodeId);
+ if (it == Nodes.end())
+ return nullptr;
+ return &it->second;
+}
+
TLeaderTabletInfo& THive::GetTablet(TTabletId tabletId) {
- auto it = Tablets.find(tabletId);
- if (it == Tablets.end()) {
- it = Tablets.emplace(std::piecewise_construct, std::tuple<TTabletId>(tabletId), std::tuple<TTabletId, THive&>(tabletId, *this)).first;
- UpdateCounterTabletsTotal(+1);
- }
- return it->second;
-}
-
+ auto it = Tablets.find(tabletId);
+ if (it == Tablets.end()) {
+ it = Tablets.emplace(std::piecewise_construct, std::tuple<TTabletId>(tabletId), std::tuple<TTabletId, THive&>(tabletId, *this)).first;
+ UpdateCounterTabletsTotal(+1);
+ }
+ return it->second;
+}
+
TLeaderTabletInfo* THive::FindTablet(TTabletId tabletId) {
- auto it = Tablets.find(tabletId);
- if (it == Tablets.end() || it->second.IsDeleting())
- return nullptr;
- return &it->second;
-}
-
+ auto it = Tablets.find(tabletId);
+ if (it == Tablets.end() || it->second.IsDeleting())
+ return nullptr;
+ return &it->second;
+}
+
TLeaderTabletInfo* THive::FindTabletEvenInDeleting(TTabletId tabletId) {
- auto it = Tablets.find(tabletId);
- if (it == Tablets.end())
- return nullptr;
- return &it->second;
-}
-
+ auto it = Tablets.find(tabletId);
+ if (it == Tablets.end())
+ return nullptr;
+ return &it->second;
+}
+
TTabletInfo& THive::GetTablet(TTabletId tabletId, TFollowerId followerId) {
TLeaderTabletInfo& leader = GetTablet(tabletId);
return leader.GetTablet(followerId);
-}
-
+}
+
TTabletInfo* THive::FindTablet(TTabletId tabletId, TFollowerId followerId) {
TLeaderTabletInfo* leader = FindTablet(tabletId);
if (leader == nullptr) {
- return nullptr;
- }
+ return nullptr;
+ }
return leader->FindTablet(followerId);
-}
-
+}
+
TTabletInfo* THive::FindTabletEvenInDeleting(TTabletId tabletId, TFollowerId followerId) {
TLeaderTabletInfo* leader = FindTabletEvenInDeleting(tabletId);
if (leader == nullptr) {
- return nullptr;
- }
+ return nullptr;
+ }
return leader->FindTablet(followerId);
-}
-
-TStoragePoolInfo& THive::GetStoragePool(const TString& name) {
- auto it = StoragePools.find(name);
- if (it == StoragePools.end()) {
- it = StoragePools.emplace(std::piecewise_construct, std::tuple<TString>(name), std::tuple<TString, THive*>(name, this)).first;
- }
- return it->second;
-}
-
-TStoragePoolInfo* THive::FindStoragePool(const TString& name) {
- auto it = StoragePools.find(name);
- if (it == StoragePools.end()) {
- return nullptr;
- }
- return &it->second;
-}
-
-TDomainInfo* THive::FindDomain(TSubDomainKey key) {
- auto it = Domains.find(key);
- if (it == Domains.end()) {
- return nullptr;
- }
- return &it->second;
-}
-
-void THive::DeleteTablet(TTabletId tabletId) {
- auto it = Tablets.find(tabletId);
- if (it != Tablets.end()) {
+}
+
+TStoragePoolInfo& THive::GetStoragePool(const TString& name) {
+ auto it = StoragePools.find(name);
+ if (it == StoragePools.end()) {
+ it = StoragePools.emplace(std::piecewise_construct, std::tuple<TString>(name), std::tuple<TString, THive*>(name, this)).first;
+ }
+ return it->second;
+}
+
+TStoragePoolInfo* THive::FindStoragePool(const TString& name) {
+ auto it = StoragePools.find(name);
+ if (it == StoragePools.end()) {
+ return nullptr;
+ }
+ return &it->second;
+}
+
+TDomainInfo* THive::FindDomain(TSubDomainKey key) {
+ auto it = Domains.find(key);
+ if (it == Domains.end()) {
+ return nullptr;
+ }
+ return &it->second;
+}
+
+void THive::DeleteTablet(TTabletId tabletId) {
+ auto it = Tablets.find(tabletId);
+ if (it != Tablets.end()) {
TLeaderTabletInfo& tablet(it->second);
- tablet.BecomeStopped();
+ tablet.BecomeStopped();
for (TFollowerTabletInfo& follower : tablet.Followers) {
follower.BecomeStopped();
- }
- ReportDeletedToWhiteboard(tablet);
- tablet.ReleaseAllocationUnits();
- OwnerToTablet.erase(tablet.Owner);
- if (tablet.Category) {
- tablet.Category->Tablets.erase(&tablet);
- }
- auto itObj = ObjectToTabletMetrics.find(tablet.ObjectId);
- if (itObj != ObjectToTabletMetrics.end()) {
- itObj->second.DecreaseCount();
- if (itObj->second.Counter == 0) {
- ObjectToTabletMetrics.erase(itObj);
- }
- }
- auto itType = TabletTypeToTabletMetrics.find(tablet.Type);
- if (itType != TabletTypeToTabletMetrics.end()) {
- itType->second.DecreaseCount();
- if (itType->second.Counter == 0) {
- TabletTypeToTabletMetrics.erase(itType);
+ }
+ ReportDeletedToWhiteboard(tablet);
+ tablet.ReleaseAllocationUnits();
+ OwnerToTablet.erase(tablet.Owner);
+ if (tablet.Category) {
+ tablet.Category->Tablets.erase(&tablet);
+ }
+ auto itObj = ObjectToTabletMetrics.find(tablet.ObjectId);
+ if (itObj != ObjectToTabletMetrics.end()) {
+ itObj->second.DecreaseCount();
+ if (itObj->second.Counter == 0) {
+ ObjectToTabletMetrics.erase(itObj);
+ }
+ }
+ auto itType = TabletTypeToTabletMetrics.find(tablet.Type);
+ if (itType != TabletTypeToTabletMetrics.end()) {
+ itType->second.DecreaseCount();
+ if (itType->second.Counter == 0) {
+ TabletTypeToTabletMetrics.erase(itType);
}
}
- for (auto nt = Nodes.begin(); nt != Nodes.end(); ++nt) {
- for (auto st = nt->second.Tablets.begin(); st != nt->second.Tablets.end(); ++st) {
- Y_ENSURE_LOG(st->second.count(&tablet) == 0, " Deleting tablet found on node " << nt->first << " in state " << TTabletInfo::EVolatileStateName(st->first));
- }
- Y_ENSURE_LOG(nt->second.LockedTablets.count(&tablet) == 0, " Deleting tablet found on node " << nt->first << " in locked set");
- }
+ for (auto nt = Nodes.begin(); nt != Nodes.end(); ++nt) {
+ for (auto st = nt->second.Tablets.begin(); st != nt->second.Tablets.end(); ++st) {
+ Y_ENSURE_LOG(st->second.count(&tablet) == 0, " Deleting tablet found on node " << nt->first << " in state " << TTabletInfo::EVolatileStateName(st->first));
+ }
+ Y_ENSURE_LOG(nt->second.LockedTablets.count(&tablet) == 0, " Deleting tablet found on node " << nt->first << " in locked set");
+ }
UpdateCounterTabletsTotal(-1 - (tablet.Followers.size()));
- Tablets.erase(it);
- }
-}
-
-void THive::DeleteNode(TNodeId nodeId) {
- Nodes.erase(nodeId);
-}
-
-TTabletCategoryInfo& THive::GetTabletCategory(TTabletCategoryId tabletCategoryId) {
- auto it = TabletCategories.find(tabletCategoryId);
- if (it == TabletCategories.end())
- it = TabletCategories.emplace(tabletCategoryId, tabletCategoryId).first; // emplace()
- return it->second;
-}
-
-void THive::KillNode(TNodeId nodeId, const TActorId& local) {
- TNodeInfo* node = FindNode(nodeId);
- if (node != nullptr) {
- TVector<TTabletInfo*> tabletsToKill;
- for (const auto& t : node->Tablets) {
- for (TTabletInfo* tablet : t.second) {
- tabletsToKill.push_back(tablet);
- }
- }
- for (TTabletInfo* tablet : tabletsToKill) {
- Execute(CreateRestartTablet(tablet->GetFullTabletId()));
- }
- }
- Execute(CreateKillNode(nodeId, local));
-}
-
-void THive::SetCounterTabletsTotal(ui64 tabletsTotal) {
- if (TabletCounters != nullptr) {
- auto& counter = TabletCounters->Simple()[NHive::COUNTER_TABLETS_TOTAL];
- TabletsTotal = tabletsTotal;
- counter.Set(TabletsTotal);
- TabletCounters->Simple()[NHive::COUNTER_STATE_DONE].Set(TabletsTotal == TabletsAlive ? 1 : 0);
- }
-}
-
-void THive::UpdateCounterTabletsTotal(i64 tabletsTotalDiff) {
- if (TabletCounters != nullptr) {
+ Tablets.erase(it);
+ }
+}
+
+void THive::DeleteNode(TNodeId nodeId) {
+ Nodes.erase(nodeId);
+}
+
+TTabletCategoryInfo& THive::GetTabletCategory(TTabletCategoryId tabletCategoryId) {
+ auto it = TabletCategories.find(tabletCategoryId);
+ if (it == TabletCategories.end())
+ it = TabletCategories.emplace(tabletCategoryId, tabletCategoryId).first; // emplace()
+ return it->second;
+}
+
+void THive::KillNode(TNodeId nodeId, const TActorId& local) {
+ TNodeInfo* node = FindNode(nodeId);
+ if (node != nullptr) {
+ TVector<TTabletInfo*> tabletsToKill;
+ for (const auto& t : node->Tablets) {
+ for (TTabletInfo* tablet : t.second) {
+ tabletsToKill.push_back(tablet);
+ }
+ }
+ for (TTabletInfo* tablet : tabletsToKill) {
+ Execute(CreateRestartTablet(tablet->GetFullTabletId()));
+ }
+ }
+ Execute(CreateKillNode(nodeId, local));
+}
+
+void THive::SetCounterTabletsTotal(ui64 tabletsTotal) {
+ if (TabletCounters != nullptr) {
auto& counter = TabletCounters->Simple()[NHive::COUNTER_TABLETS_TOTAL];
- TabletsTotal = counter.Get() + tabletsTotalDiff;
- counter.Set(TabletsTotal);
- TabletCounters->Simple()[NHive::COUNTER_STATE_DONE].Set(TabletsTotal == TabletsAlive ? 1 : 0);
- }
-}
-
-void THive::UpdateCounterTabletsAlive(i64 tabletsAliveDiff) {
- if (TabletCounters != nullptr) {
+ TabletsTotal = tabletsTotal;
+ counter.Set(TabletsTotal);
+ TabletCounters->Simple()[NHive::COUNTER_STATE_DONE].Set(TabletsTotal == TabletsAlive ? 1 : 0);
+ }
+}
+
+void THive::UpdateCounterTabletsTotal(i64 tabletsTotalDiff) {
+ if (TabletCounters != nullptr) {
+ auto& counter = TabletCounters->Simple()[NHive::COUNTER_TABLETS_TOTAL];
+ TabletsTotal = counter.Get() + tabletsTotalDiff;
+ counter.Set(TabletsTotal);
+ TabletCounters->Simple()[NHive::COUNTER_STATE_DONE].Set(TabletsTotal == TabletsAlive ? 1 : 0);
+ }
+}
+
+void THive::UpdateCounterTabletsAlive(i64 tabletsAliveDiff) {
+ if (TabletCounters != nullptr) {
auto& counter = TabletCounters->Simple()[NHive::COUNTER_TABLETS_ALIVE];
- TabletsAlive = counter.Get() + tabletsAliveDiff;
- counter.Set(TabletsAlive);
- TabletCounters->Simple()[NHive::COUNTER_STATE_DONE].Set(TabletsTotal == TabletsAlive ? 1 : 0);
- }
-}
-
-void THive::UpdateCounterBootQueueSize(ui64 bootQueueSize) {
- if (TabletCounters != nullptr) {
+ TabletsAlive = counter.Get() + tabletsAliveDiff;
+ counter.Set(TabletsAlive);
+ TabletCounters->Simple()[NHive::COUNTER_STATE_DONE].Set(TabletsTotal == TabletsAlive ? 1 : 0);
+ }
+}
+
+void THive::UpdateCounterBootQueueSize(ui64 bootQueueSize) {
+ if (TabletCounters != nullptr) {
auto& counter = TabletCounters->Simple()[NHive::COUNTER_BOOTQUEUE_SIZE];
- counter.Set(bootQueueSize);
- }
-}
-
-bool THive::DomainHasNodes(const TSubDomainKey &domainKey) const {
+ counter.Set(bootQueueSize);
+ }
+}
+
+bool THive::DomainHasNodes(const TSubDomainKey &domainKey) const {
return !DomainsView.IsEmpty(domainKey);
}
-TResourceNormalizedValues THive::GetStDevResourceValues() const {
+TResourceNormalizedValues THive::GetStDevResourceValues() const {
TVector<TResourceNormalizedValues> values;
- values.reserve(Nodes.size());
- for (const auto& ni : Nodes) {
- if (ni.second.IsAlive() && !ni.second.Down) {
- values.push_back(NormalizeRawValues(ni.second.GetResourceCurrentValues(), ni.second.GetResourceMaximumValues()));
- }
- }
- return GetStDev(values);
-}
-
-bool THive::IsTabletMoveExpedient(const TTabletInfo& tablet, const TNodeInfo& node) const {
- if (!tablet.IsAlive()) {
- BLOG_TRACE("[TME] Move of tablet " << tablet.ToString() << " from " << tablet.NodeId << " to " << node.Id
- << " is expedient because the tablet is not alive");
- return true;
- }
- if (tablet.Node->Freeze) {
- BLOG_TRACE("[TME] Move of tablet " << tablet.ToString() << " from " << tablet.NodeId << " to " << node.Id
- << " is not expedient because the source node is freezed");
- return false;
- }
- if (node.Freeze) {
- BLOG_TRACE("[TME] Move of tablet " << tablet.ToString() << " from " << tablet.NodeId << " to " << node.Id
- << " is not expedient because the target node is freezed");
- return false;
- }
- if (tablet.Node->Down) {
- BLOG_TRACE("[TME] Move of tablet " << tablet.ToString() << " from " << tablet.NodeId << " to " << node.Id
- << " is expedient because the node is down");
- return true;
- }
+ values.reserve(Nodes.size());
+ for (const auto& ni : Nodes) {
+ if (ni.second.IsAlive() && !ni.second.Down) {
+ values.push_back(NormalizeRawValues(ni.second.GetResourceCurrentValues(), ni.second.GetResourceMaximumValues()));
+ }
+ }
+ return GetStDev(values);
+}
+
+bool THive::IsTabletMoveExpedient(const TTabletInfo& tablet, const TNodeInfo& node) const {
+ if (!tablet.IsAlive()) {
+ BLOG_TRACE("[TME] Move of tablet " << tablet.ToString() << " from " << tablet.NodeId << " to " << node.Id
+ << " is expedient because the tablet is not alive");
+ return true;
+ }
+ if (tablet.Node->Freeze) {
+ BLOG_TRACE("[TME] Move of tablet " << tablet.ToString() << " from " << tablet.NodeId << " to " << node.Id
+ << " is not expedient because the source node is freezed");
+ return false;
+ }
+ if (node.Freeze) {
+ BLOG_TRACE("[TME] Move of tablet " << tablet.ToString() << " from " << tablet.NodeId << " to " << node.Id
+ << " is not expedient because the target node is freezed");
+ return false;
+ }
+ if (tablet.Node->Down) {
+ BLOG_TRACE("[TME] Move of tablet " << tablet.ToString() << " from " << tablet.NodeId << " to " << node.Id
+ << " is expedient because the node is down");
+ return true;
+ }
if (!tablet.Node->IsAllowedToRunTablet(tablet)) {
- BLOG_TRACE("[TME] Move of tablet " << tablet.ToString() << " from " << tablet.NodeId << " to " << node.Id
- << " is expedient because the current node is unappropriate target for the tablet");
+ BLOG_TRACE("[TME] Move of tablet " << tablet.ToString() << " from " << tablet.NodeId << " to " << node.Id
+ << " is expedient because the current node is unappropriate target for the tablet");
return true;
}
- if (tablet.Node->Id == node.Id) {
- BLOG_TRACE("[TME] Move of tablet " << tablet.ToString() << " from " << tablet.NodeId << " to " << node.Id
- << " is not expedient because node is the same");
- return false;
- }
- if (tablet.Node->IsOverloaded() && !node.IsOverloaded()) {
- BLOG_TRACE("[TME] Move of tablet " << tablet.ToString() << " from " << tablet.NodeId << " to " << node.Id
- << " is forcefully expedient because source node is overloaded");
- return true;
- }
-
+ if (tablet.Node->Id == node.Id) {
+ BLOG_TRACE("[TME] Move of tablet " << tablet.ToString() << " from " << tablet.NodeId << " to " << node.Id
+ << " is not expedient because node is the same");
+ return false;
+ }
+ if (tablet.Node->IsOverloaded() && !node.IsOverloaded()) {
+ BLOG_TRACE("[TME] Move of tablet " << tablet.ToString() << " from " << tablet.NodeId << " to " << node.Id
+ << " is forcefully expedient because source node is overloaded");
+ return true;
+ }
+
TVector<TResourceNormalizedValues> values;
- std::size_t oldNode = std::numeric_limits<std::size_t>::max();
- std::size_t newNode = std::numeric_limits<std::size_t>::max();
- values.reserve(Nodes.size());
- for (const auto& ni : Nodes) {
- if (ni.second.IsAlive() && !ni.second.Down) {
- if (ni.first == node.Id)
- newNode = values.size();
- if (ni.first == tablet.Node->Id)
- oldNode = values.size();
- values.push_back(NormalizeRawValues(ni.second.GetResourceCurrentValues(), ni.second.GetResourceMaximumValues()));
- }
- }
-
- if (oldNode == std::numeric_limits<std::size_t>::max()
- || newNode == std::numeric_limits<std::size_t>::max()) {
- return false;
- }
-
- auto tabletResources = tablet.GetResourceCurrentValues();
-// NMetrics::TResourceMetrics::TResourceNormalizedValues oldValues = values[oldNode];
-// NMetrics::TResourceMetrics::TResourceNormalizedValues newValues = values[newNode] + NMetrics::TResourceMetrics::Normalize(tabletResources, node.GetResourceMaximumValues());
-// return sum(newValues) < sum(oldValues);
-
- TResourceNormalizedValues beforeStDev = GetStDev(values);
- values[oldNode] -= NormalizeRawValues(tabletResources, tablet.Node->GetResourceMaximumValues());
- values[newNode] += NormalizeRawValues(tabletResources, node.GetResourceMaximumValues());
- TResourceNormalizedValues afterStDev = GetStDev(values);
- tablet.FilterRawValues(beforeStDev);
- tablet.FilterRawValues(afterStDev);
- double before = max(beforeStDev);
- double after = max(afterStDev);
- bool result = after < before;
- if (result) {
- BLOG_TRACE("[TME] Move of tablet " << tablet.ToString() << " from " << tablet.NodeId << " to " << node.Id
- << " is expedient, beforeStDev " << beforeStDev << " afterStDev " << afterStDev);
- } else {
- BLOG_TRACE("[TME] Move of tablet " << tablet.ToString() << " from " << tablet.NodeId << " to " << node.Id
- << " is not expedient, beforeStDev " << beforeStDev << " afterStDev " << afterStDev);
- }
- return result;
-}
-
+ std::size_t oldNode = std::numeric_limits<std::size_t>::max();
+ std::size_t newNode = std::numeric_limits<std::size_t>::max();
+ values.reserve(Nodes.size());
+ for (const auto& ni : Nodes) {
+ if (ni.second.IsAlive() && !ni.second.Down) {
+ if (ni.first == node.Id)
+ newNode = values.size();
+ if (ni.first == tablet.Node->Id)
+ oldNode = values.size();
+ values.push_back(NormalizeRawValues(ni.second.GetResourceCurrentValues(), ni.second.GetResourceMaximumValues()));
+ }
+ }
+
+ if (oldNode == std::numeric_limits<std::size_t>::max()
+ || newNode == std::numeric_limits<std::size_t>::max()) {
+ return false;
+ }
+
+ auto tabletResources = tablet.GetResourceCurrentValues();
+// NMetrics::TResourceMetrics::TResourceNormalizedValues oldValues = values[oldNode];
+// NMetrics::TResourceMetrics::TResourceNormalizedValues newValues = values[newNode] + NMetrics::TResourceMetrics::Normalize(tabletResources, node.GetResourceMaximumValues());
+// return sum(newValues) < sum(oldValues);
+
+ TResourceNormalizedValues beforeStDev = GetStDev(values);
+ values[oldNode] -= NormalizeRawValues(tabletResources, tablet.Node->GetResourceMaximumValues());
+ values[newNode] += NormalizeRawValues(tabletResources, node.GetResourceMaximumValues());
+ TResourceNormalizedValues afterStDev = GetStDev(values);
+ tablet.FilterRawValues(beforeStDev);
+ tablet.FilterRawValues(afterStDev);
+ double before = max(beforeStDev);
+ double after = max(afterStDev);
+ bool result = after < before;
+ if (result) {
+ BLOG_TRACE("[TME] Move of tablet " << tablet.ToString() << " from " << tablet.NodeId << " to " << node.Id
+ << " is expedient, beforeStDev " << beforeStDev << " afterStDev " << afterStDev);
+ } else {
+ BLOG_TRACE("[TME] Move of tablet " << tablet.ToString() << " from " << tablet.NodeId << " to " << node.Id
+ << " is not expedient, beforeStDev " << beforeStDev << " afterStDev " << afterStDev);
+ }
+ return result;
+}
+
void THive::FillTabletInfo(NKikimrHive::TEvResponseHiveInfo& response, ui64 tabletId, const TLeaderTabletInfo *info, const NKikimrHive::TEvRequestHiveInfo &req) {
if (info) {
- auto& tabletInfo = *response.AddTablets();
- tabletInfo.SetTabletID(tabletId);
+ auto& tabletInfo = *response.AddTablets();
+ tabletInfo.SetTabletID(tabletId);
tabletInfo.SetTabletType(info->Type);
tabletInfo.SetState(static_cast<ui32>(info->State));
- tabletInfo.SetTabletBootMode(info->BootMode);
- tabletInfo.SetVolatileState(info->GetVolatileState());
+ tabletInfo.SetTabletBootMode(info->BootMode);
+ tabletInfo.SetVolatileState(info->GetVolatileState());
tabletInfo.SetNodeID(info->NodeId);
tabletInfo.MutableTabletOwner()->SetOwner(info->Owner.first);
tabletInfo.MutableTabletOwner()->SetOwnerIdx(info->Owner.second);
- tabletInfo.SetGeneration(info->KnownGeneration);
- tabletInfo.MutableObjectDomain()->CopyFrom(info->ObjectDomain);
- if (!info->IsRunning()) {
- tabletInfo.SetLastAliveTimestamp(info->Statistics.GetLastAliveTimestamp());
- }
- tabletInfo.SetRestartsPerPeriod(info->Statistics.RestartTimestampSize());
- if (req.GetReturnMetrics()) {
- tabletInfo.MutableMetrics()->CopyFrom(info->GetResourceValues());
- }
+ tabletInfo.SetGeneration(info->KnownGeneration);
+ tabletInfo.MutableObjectDomain()->CopyFrom(info->ObjectDomain);
+ if (!info->IsRunning()) {
+ tabletInfo.SetLastAliveTimestamp(info->Statistics.GetLastAliveTimestamp());
+ }
+ tabletInfo.SetRestartsPerPeriod(info->Statistics.RestartTimestampSize());
+ if (req.GetReturnMetrics()) {
+ tabletInfo.MutableMetrics()->CopyFrom(info->GetResourceValues());
+ }
if (req.GetReturnFollowers()) {
for (const auto& follower : info->Followers) {
if (req.HasFollowerID() && req.GetFollowerID() != follower.Id)
- continue;
+ continue;
NKikimrHive::TTabletInfo& tabletInfo = *response.AddTablets();
tabletInfo.SetTabletID(tabletId);
tabletInfo.SetTabletType(info->Type);
@@ -1598,476 +1598,476 @@ void THive::FillTabletInfo(NKikimrHive::TEvResponseHiveInfo& response, ui64 tabl
tabletInfo.SetNodeID(follower.NodeId);
tabletInfo.MutableTabletOwner()->SetOwner(info->Owner.first);
tabletInfo.MutableTabletOwner()->SetOwnerIdx(info->Owner.second);
- tabletInfo.MutableObjectDomain()->CopyFrom(info->ObjectDomain);
- if (!follower.IsRunning()) {
- tabletInfo.SetLastAliveTimestamp(follower.Statistics.GetLastAliveTimestamp());
- }
+ tabletInfo.MutableObjectDomain()->CopyFrom(info->ObjectDomain);
+ if (!follower.IsRunning()) {
+ tabletInfo.SetLastAliveTimestamp(follower.Statistics.GetLastAliveTimestamp());
+ }
tabletInfo.SetRestartsPerPeriod(follower.Statistics.RestartTimestampSize());
- if (req.GetReturnMetrics()) {
+ if (req.GetReturnMetrics()) {
tabletInfo.MutableMetrics()->CopyFrom(follower.GetResourceValues());
- }
- }
- }
- }
+ }
+ }
+ }
+ }
}
-void THive::Handle(TEvHive::TEvRequestHiveInfo::TPtr& ev) {
+void THive::Handle(TEvHive::TEvRequestHiveInfo::TPtr& ev) {
const auto& record = ev->Get()->Record;
TAutoPtr<TEvHive::TEvResponseHiveInfo> response = new TEvHive::TEvResponseHiveInfo();
- TInstant now = TlsActivationContext->Now();
+ TInstant now = TlsActivationContext->Now();
if (record.HasTabletID()) {
- TTabletId tabletId = record.GetTabletID();
- NKikimrHive::TForwardRequest forwardRequest;
- if (CheckForForwardTabletRequest(tabletId, forwardRequest)) {
- response->Record.MutableForwardRequest()->CopyFrom(forwardRequest);
- }
+ TTabletId tabletId = record.GetTabletID();
+ NKikimrHive::TForwardRequest forwardRequest;
+ if (CheckForForwardTabletRequest(tabletId, forwardRequest)) {
+ response->Record.MutableForwardRequest()->CopyFrom(forwardRequest);
+ }
TLeaderTabletInfo* tablet = FindTablet(tabletId);
- if (tablet) {
- tablet->ActualizeTabletStatistics(now);
- FillTabletInfo(response->Record, record.GetTabletID(), tablet, record);
- } else {
- BLOG_W("Can't find the tablet from RequestHiveInfo(TabletID=" << tabletId << ")");
- }
+ if (tablet) {
+ tablet->ActualizeTabletStatistics(now);
+ FillTabletInfo(response->Record, record.GetTabletID(), tablet, record);
+ } else {
+ BLOG_W("Can't find the tablet from RequestHiveInfo(TabletID=" << tabletId << ")");
+ }
} else {
response->Record.MutableTablets()->Reserve(Tablets.size());
for (auto it = Tablets.begin(); it != Tablets.end(); ++it) {
- if (record.HasTabletType() && record.GetTabletType() != it->second.Type) {
+ if (record.HasTabletType() && record.GetTabletType() != it->second.Type) {
continue;
- }
- if (it->second.IsDeleting()) {
- continue;
- }
- it->second.ActualizeTabletStatistics(now);
+ }
+ if (it->second.IsDeleting()) {
+ continue;
+ }
+ it->second.ActualizeTabletStatistics(now);
FillTabletInfo(response->Record, it->first, &it->second, record);
}
}
- Send(ev->Sender, response.Release(), 0, ev->Cookie);
-}
-
-NKikimrTabletBase::TMetrics& operator +=(NKikimrTabletBase::TMetrics& metrics, const NKikimrTabletBase::TMetrics& toAdd) {
- if (toAdd.HasCPU()) {
- metrics.SetCPU(metrics.GetCPU() + toAdd.GetCPU());
- }
- if (toAdd.HasMemory()) {
- metrics.SetMemory(metrics.GetMemory() + toAdd.GetMemory());
- }
- if (toAdd.HasNetwork()) {
- metrics.SetNetwork(metrics.GetNetwork() + toAdd.GetNetwork());
- }
- if (toAdd.HasStorage()) {
- metrics.SetStorage(metrics.GetStorage() + toAdd.GetStorage());
- }
- if (toAdd.HasReadThroughput()) {
- metrics.SetReadThroughput(metrics.GetReadThroughput() + toAdd.GetReadThroughput());
- }
- if (toAdd.HasWriteThroughput()) {
- metrics.SetWriteThroughput(metrics.GetWriteThroughput() + toAdd.GetWriteThroughput());
- }
- return metrics;
-}
-
-void THive::Handle(TEvHive::TEvRequestHiveDomainStats::TPtr& ev) {
- struct TSubDomainStats {
- THashMap<TTabletInfo::EVolatileState, ui32> StateCounter;
- THashSet<TNodeId> NodeIds;
- ui32 AliveNodes = 0;
- NKikimrTabletBase::TMetrics Metrics;
- };
-
- THashMap<TSubDomainKey, TSubDomainStats> subDomainStats;
-
- for (auto it = Tablets.begin(); it != Tablets.end(); ++it) {
+ Send(ev->Sender, response.Release(), 0, ev->Cookie);
+}
+
+NKikimrTabletBase::TMetrics& operator +=(NKikimrTabletBase::TMetrics& metrics, const NKikimrTabletBase::TMetrics& toAdd) {
+ if (toAdd.HasCPU()) {
+ metrics.SetCPU(metrics.GetCPU() + toAdd.GetCPU());
+ }
+ if (toAdd.HasMemory()) {
+ metrics.SetMemory(metrics.GetMemory() + toAdd.GetMemory());
+ }
+ if (toAdd.HasNetwork()) {
+ metrics.SetNetwork(metrics.GetNetwork() + toAdd.GetNetwork());
+ }
+ if (toAdd.HasStorage()) {
+ metrics.SetStorage(metrics.GetStorage() + toAdd.GetStorage());
+ }
+ if (toAdd.HasReadThroughput()) {
+ metrics.SetReadThroughput(metrics.GetReadThroughput() + toAdd.GetReadThroughput());
+ }
+ if (toAdd.HasWriteThroughput()) {
+ metrics.SetWriteThroughput(metrics.GetWriteThroughput() + toAdd.GetWriteThroughput());
+ }
+ return metrics;
+}
+
+void THive::Handle(TEvHive::TEvRequestHiveDomainStats::TPtr& ev) {
+ struct TSubDomainStats {
+ THashMap<TTabletInfo::EVolatileState, ui32> StateCounter;
+ THashSet<TNodeId> NodeIds;
+ ui32 AliveNodes = 0;
+ NKikimrTabletBase::TMetrics Metrics;
+ };
+
+ THashMap<TSubDomainKey, TSubDomainStats> subDomainStats;
+
+ for (auto it = Tablets.begin(); it != Tablets.end(); ++it) {
const TLeaderTabletInfo& tablet = it->second;
- TSubDomainKey domain = tablet.ObjectDomain;
- TSubDomainStats& stats = subDomainStats[domain];
- stats.StateCounter[tablet.GetVolatileState()]++;
- if (ev->Get()->Record.GetReturnMetrics()) {
- stats.Metrics += tablet.GetResourceValues();
- }
- }
-
- for (auto it = Nodes.begin(); it != Nodes.end(); ++it) {
- const TNodeInfo& node = it->second;
- for (const TSubDomainKey& domain : node.ServicedDomains) {
- TSubDomainStats& stats = subDomainStats[domain];
- if (node.IsAlive()) {
- stats.AliveNodes++;
- stats.NodeIds.emplace(node.Id);
- }
- }
- }
-
+ TSubDomainKey domain = tablet.ObjectDomain;
+ TSubDomainStats& stats = subDomainStats[domain];
+ stats.StateCounter[tablet.GetVolatileState()]++;
+ if (ev->Get()->Record.GetReturnMetrics()) {
+ stats.Metrics += tablet.GetResourceValues();
+ }
+ }
+
+ for (auto it = Nodes.begin(); it != Nodes.end(); ++it) {
+ const TNodeInfo& node = it->second;
+ for (const TSubDomainKey& domain : node.ServicedDomains) {
+ TSubDomainStats& stats = subDomainStats[domain];
+ if (node.IsAlive()) {
+ stats.AliveNodes++;
+ stats.NodeIds.emplace(node.Id);
+ }
+ }
+ }
+
THolder<TEvHive::TEvResponseHiveDomainStats> response = MakeHolder<TEvHive::TEvResponseHiveDomainStats>();
- auto& record = response->Record;
-
- for (const auto& pr1 : subDomainStats) {
- auto& domainStats = *record.AddDomainStats();
- domainStats.SetShardId(pr1.first.first);
- domainStats.SetPathId(pr1.first.second);
- if (ev->Get()->Record.GetReturnMetrics()) {
- domainStats.MutableMetrics()->CopyFrom(pr1.second.Metrics);
- }
- for (const auto& pr2 : pr1.second.StateCounter) {
- auto& stateStats = *domainStats.AddStateStats();
- stateStats.SetVolatileState(pr2.first);
- stateStats.SetCount(pr2.second);
- }
- for (const TNodeId nodeId : pr1.second.NodeIds) {
- domainStats.AddNodeIds(nodeId);
- }
- domainStats.SetAliveNodes(pr1.second.AliveNodes);
- }
-
- Send(ev->Sender, response.Release(), 0, ev->Cookie);
-}
-
-void THive::Handle(TEvHive::TEvRequestHiveNodeStats::TPtr& ev) {
+ auto& record = response->Record;
+
+ for (const auto& pr1 : subDomainStats) {
+ auto& domainStats = *record.AddDomainStats();
+ domainStats.SetShardId(pr1.first.first);
+ domainStats.SetPathId(pr1.first.second);
+ if (ev->Get()->Record.GetReturnMetrics()) {
+ domainStats.MutableMetrics()->CopyFrom(pr1.second.Metrics);
+ }
+ for (const auto& pr2 : pr1.second.StateCounter) {
+ auto& stateStats = *domainStats.AddStateStats();
+ stateStats.SetVolatileState(pr2.first);
+ stateStats.SetCount(pr2.second);
+ }
+ for (const TNodeId nodeId : pr1.second.NodeIds) {
+ domainStats.AddNodeIds(nodeId);
+ }
+ domainStats.SetAliveNodes(pr1.second.AliveNodes);
+ }
+
+ Send(ev->Sender, response.Release(), 0, ev->Cookie);
+}
+
+void THive::Handle(TEvHive::TEvRequestHiveNodeStats::TPtr& ev) {
THolder<TEvHive::TEvResponseHiveNodeStats> response = MakeHolder<TEvHive::TEvResponseHiveNodeStats>();
- auto& record = response->Record;
- for (auto it = Nodes.begin(); it != Nodes.end(); ++it) {
- auto& nodeStats = *record.AddNodeStats();
- const TNodeInfo& node = it->second;
- nodeStats.SetNodeId(node.Id);
- if (!node.ServicedDomains.empty()) {
- nodeStats.MutableNodeDomain()->CopyFrom(node.ServicedDomains.front());
- }
- for (const auto& [state, set] : node.Tablets) {
- if (!set.empty()) {
- auto* stateStats = nodeStats.AddStateStats();
- stateStats->SetVolatileState(state);
- stateStats->SetCount(set.size());
- }
- }
- if (ev->Get()->Record.GetReturnMetrics()) {
- nodeStats.MutableMetrics()->CopyFrom(MetricsFromResourceRawValues(node.GetResourceCurrentValues()));
- }
- if (!node.IsAlive()) {
- nodeStats.SetLastAliveTimestamp(node.Statistics.GetLastAliveTimestamp());
- }
- nodeStats.SetRestartsPerPeriod(node.Statistics.RestartTimestampSize());
- }
- Send(ev->Sender, response.Release(), 0, ev->Cookie);
-}
-
-void THive::Handle(TEvHive::TEvRequestHiveStorageStats::TPtr& ev) {
+ auto& record = response->Record;
+ for (auto it = Nodes.begin(); it != Nodes.end(); ++it) {
+ auto& nodeStats = *record.AddNodeStats();
+ const TNodeInfo& node = it->second;
+ nodeStats.SetNodeId(node.Id);
+ if (!node.ServicedDomains.empty()) {
+ nodeStats.MutableNodeDomain()->CopyFrom(node.ServicedDomains.front());
+ }
+ for (const auto& [state, set] : node.Tablets) {
+ if (!set.empty()) {
+ auto* stateStats = nodeStats.AddStateStats();
+ stateStats->SetVolatileState(state);
+ stateStats->SetCount(set.size());
+ }
+ }
+ if (ev->Get()->Record.GetReturnMetrics()) {
+ nodeStats.MutableMetrics()->CopyFrom(MetricsFromResourceRawValues(node.GetResourceCurrentValues()));
+ }
+ if (!node.IsAlive()) {
+ nodeStats.SetLastAliveTimestamp(node.Statistics.GetLastAliveTimestamp());
+ }
+ nodeStats.SetRestartsPerPeriod(node.Statistics.RestartTimestampSize());
+ }
+ Send(ev->Sender, response.Release(), 0, ev->Cookie);
+}
+
+void THive::Handle(TEvHive::TEvRequestHiveStorageStats::TPtr& ev) {
THolder<TEvHive::TEvResponseHiveStorageStats> response = MakeHolder<TEvHive::TEvResponseHiveStorageStats>();
- auto& record = response->Record;
- for (const auto& [name, pool] : StoragePools) {
- auto& pbPool = *record.AddPools();
- pbPool.SetName(name);
- for (const auto& [id, group] : pool.Groups) {
- auto& pbGroup = *pbPool.AddGroups();
- pbGroup.SetGroupID(id);
- pbGroup.SetAcquiredUnits(group.Units.size());
- pbGroup.SetAcquiredIOPS(group.AcquiredIOPS);
- pbGroup.SetAcquiredThroughput(group.AcquiredThroughput);
- pbGroup.SetAcquiredSize(group.AcquiredSize);
- pbGroup.SetMaximumIOPS(group.MaximumIOPS);
- pbGroup.SetMaximumThroughput(group.MaximumThroughput);
- pbGroup.SetMaximumSize(group.MaximumSize);
- pbGroup.SetAllocatedSize(group.GroupParameters.GetAllocatedSize());
- pbGroup.SetAvailableSize(group.GroupParameters.GetAvailableSize());
- }
- }
- Send(ev->Sender, response.Release(), 0, ev->Cookie);
-}
-
-void THive::Handle(TEvHive::TEvLookupTablet::TPtr& ev) {
- const auto& request(ev->Get()->Record);
- TOwnerIdxType::TValueType ownerIdx(request.GetOwner(), request.GetOwnerIdx());
- auto itOwner = OwnerToTablet.find(ownerIdx);
- if (itOwner == OwnerToTablet.end()) {
- Send(ev->Sender, new TEvHive::TEvCreateTabletReply(NKikimrProto::NODATA, ownerIdx.first, ownerIdx.second), 0, ev->Cookie);
- } else {
- Send(ev->Sender, new TEvHive::TEvCreateTabletReply(NKikimrProto::OK, ownerIdx.first, ownerIdx.second, itOwner->second), 0, ev->Cookie);
- }
-}
-
-void THive::Handle(TEvHive::TEvLookupChannelInfo::TPtr& ev) {
- const auto& request(ev->Get()->Record);
+ auto& record = response->Record;
+ for (const auto& [name, pool] : StoragePools) {
+ auto& pbPool = *record.AddPools();
+ pbPool.SetName(name);
+ for (const auto& [id, group] : pool.Groups) {
+ auto& pbGroup = *pbPool.AddGroups();
+ pbGroup.SetGroupID(id);
+ pbGroup.SetAcquiredUnits(group.Units.size());
+ pbGroup.SetAcquiredIOPS(group.AcquiredIOPS);
+ pbGroup.SetAcquiredThroughput(group.AcquiredThroughput);
+ pbGroup.SetAcquiredSize(group.AcquiredSize);
+ pbGroup.SetMaximumIOPS(group.MaximumIOPS);
+ pbGroup.SetMaximumThroughput(group.MaximumThroughput);
+ pbGroup.SetMaximumSize(group.MaximumSize);
+ pbGroup.SetAllocatedSize(group.GroupParameters.GetAllocatedSize());
+ pbGroup.SetAvailableSize(group.GroupParameters.GetAvailableSize());
+ }
+ }
+ Send(ev->Sender, response.Release(), 0, ev->Cookie);
+}
+
+void THive::Handle(TEvHive::TEvLookupTablet::TPtr& ev) {
+ const auto& request(ev->Get()->Record);
+ TOwnerIdxType::TValueType ownerIdx(request.GetOwner(), request.GetOwnerIdx());
+ auto itOwner = OwnerToTablet.find(ownerIdx);
+ if (itOwner == OwnerToTablet.end()) {
+ Send(ev->Sender, new TEvHive::TEvCreateTabletReply(NKikimrProto::NODATA, ownerIdx.first, ownerIdx.second), 0, ev->Cookie);
+ } else {
+ Send(ev->Sender, new TEvHive::TEvCreateTabletReply(NKikimrProto::OK, ownerIdx.first, ownerIdx.second, itOwner->second), 0, ev->Cookie);
+ }
+}
+
+void THive::Handle(TEvHive::TEvLookupChannelInfo::TPtr& ev) {
+ const auto& request(ev->Get()->Record);
const TLeaderTabletInfo* tablet = FindTablet(request.GetTabletID());
- if (tablet == nullptr) {
- Send(ev->Sender, new TEvHive::TEvChannelInfo(NKikimrProto::ERROR, request.GetTabletID()));
- return;
- }
- TAutoPtr<TEvHive::TEvChannelInfo> response = new TEvHive::TEvChannelInfo(NKikimrProto::OK, tablet->Id);
- for (const TTabletChannelInfo& channelInfo : tablet->TabletStorageInfo->Channels) {
- if (request.ChannelsSize() > 0 ) {
- const auto& channels(request.GetChannels());
- if (std::find(channels.begin(), channels.end(), channelInfo.Channel) == channels.end())
- continue;
- }
- NKikimrHive::TChannelInfo* channel = response->Record.AddChannelInfo();
- channel->SetType(channelInfo.Type.GetErasure());
- for (const TTabletChannelInfo::THistoryEntry& historyInfo : channelInfo.History) {
- // TODO
- //if (request.HasForGeneration() && request.GetForGeneration() ? historyInfo.FromGeneration)
- // continue;
- NKikimrHive::TChannelInfo_THistorySlot* history = channel->AddHistory();
- history->SetGroupID(historyInfo.GroupID);
- history->SetFromGeneration(historyInfo.FromGeneration);
- history->SetTimestamp(historyInfo.Timestamp.MilliSeconds());
- }
- }
- Send(ev->Sender, response.Release());
-}
-
-void THive::Handle(TEvHive::TEvCutTabletHistory::TPtr& ev) {
- Execute(CreateCutTabletHistory(ev));
-}
-
-void THive::Handle(TEvHive::TEvDrainNode::TPtr& ev) {
- Execute(CreateSwitchDrainOn(ev->Get()->Record.GetNodeID(),
- {
+ if (tablet == nullptr) {
+ Send(ev->Sender, new TEvHive::TEvChannelInfo(NKikimrProto::ERROR, request.GetTabletID()));
+ return;
+ }
+ TAutoPtr<TEvHive::TEvChannelInfo> response = new TEvHive::TEvChannelInfo(NKikimrProto::OK, tablet->Id);
+ for (const TTabletChannelInfo& channelInfo : tablet->TabletStorageInfo->Channels) {
+ if (request.ChannelsSize() > 0 ) {
+ const auto& channels(request.GetChannels());
+ if (std::find(channels.begin(), channels.end(), channelInfo.Channel) == channels.end())
+ continue;
+ }
+ NKikimrHive::TChannelInfo* channel = response->Record.AddChannelInfo();
+ channel->SetType(channelInfo.Type.GetErasure());
+ for (const TTabletChannelInfo::THistoryEntry& historyInfo : channelInfo.History) {
+ // TODO
+ //if (request.HasForGeneration() && request.GetForGeneration() ? historyInfo.FromGeneration)
+ // continue;
+ NKikimrHive::TChannelInfo_THistorySlot* history = channel->AddHistory();
+ history->SetGroupID(historyInfo.GroupID);
+ history->SetFromGeneration(historyInfo.FromGeneration);
+ history->SetTimestamp(historyInfo.Timestamp.MilliSeconds());
+ }
+ }
+ Send(ev->Sender, response.Release());
+}
+
+void THive::Handle(TEvHive::TEvCutTabletHistory::TPtr& ev) {
+ Execute(CreateCutTabletHistory(ev));
+}
+
+void THive::Handle(TEvHive::TEvDrainNode::TPtr& ev) {
+ Execute(CreateSwitchDrainOn(ev->Get()->Record.GetNodeID(),
+ {
.Persist = ev->Get()->Record.GetPersist(),
- .KeepDown = ev->Get()->Record.GetKeepDown(),
- .DrainInFlight = ev->Get()->Record.GetDrainInFlight(),
- }, ev->Sender));
-}
-
-void THive::Handle(TEvHive::TEvFillNode::TPtr& ev) {
- StartHiveFill(ev->Get()->Record.GetNodeID(), ev->Sender);
-}
-
-void THive::Handle(TEvHive::TEvInitiateTabletExternalBoot::TPtr& ev) {
- TTabletId tabletId = ev->Get()->Record.GetTabletID();
+ .KeepDown = ev->Get()->Record.GetKeepDown(),
+ .DrainInFlight = ev->Get()->Record.GetDrainInFlight(),
+ }, ev->Sender));
+}
+
+void THive::Handle(TEvHive::TEvFillNode::TPtr& ev) {
+ StartHiveFill(ev->Get()->Record.GetNodeID(), ev->Sender);
+}
+
+void THive::Handle(TEvHive::TEvInitiateTabletExternalBoot::TPtr& ev) {
+ TTabletId tabletId = ev->Get()->Record.GetTabletID();
TLeaderTabletInfo* tablet = FindTablet(tabletId);
if (!tablet) {
- Send(ev->Sender, new TEvHive::TEvBootTabletReply(NKikimrProto::EReplyStatus::ERROR), 0, ev->Cookie);
- BLOG_ERROR("Tablet not found " << tabletId);
+ Send(ev->Sender, new TEvHive::TEvBootTabletReply(NKikimrProto::EReplyStatus::ERROR), 0, ev->Cookie);
+ BLOG_ERROR("Tablet not found " << tabletId);
return;
}
if (tablet->State == ETabletState::GroupAssignment ||
tablet->State == ETabletState::BlockStorage)
{
- Send(ev->Sender, new TEvHive::TEvBootTabletReply(NKikimrProto::EReplyStatus::TRYLATER), 0, ev->Cookie);
- BLOG_W("Tablet waiting for group assignment " << tabletId);
+ Send(ev->Sender, new TEvHive::TEvBootTabletReply(NKikimrProto::EReplyStatus::TRYLATER), 0, ev->Cookie);
+ BLOG_W("Tablet waiting for group assignment " << tabletId);
return;
}
if (!tablet->IsBootingSuppressed()) {
- Send(ev->Sender, new TEvHive::TEvBootTabletReply(NKikimrProto::EReplyStatus::ERROR), 0, ev->Cookie);
- BLOG_ERROR("Tablet " << tabletId << " is not expected to boot externally");
+ Send(ev->Sender, new TEvHive::TEvBootTabletReply(NKikimrProto::EReplyStatus::ERROR), 0, ev->Cookie);
+ BLOG_ERROR("Tablet " << tabletId << " is not expected to boot externally");
return;
}
- Execute(CreateStartTablet(TFullTabletId(tabletId, 0), ev->Sender, ev->Cookie, /* external */ true));
-}
-
-void THive::Handle(NConsole::TEvConsole::TEvConfigNotificationRequest::TPtr& ev) {
- const NKikimrConsole::TConfigNotificationRequest& record = ev->Get()->Record;
- ClusterConfig = record.GetConfig().GetHiveConfig();
- BLOG_D("Received TEvConsole::TEvConfigNotificationRequest with update of cluster config: " << ClusterConfig.ShortDebugString());
- BuildCurrentConfig();
- Send(ev->Sender, new NConsole::TEvConsole::TEvConfigNotificationResponse(record), 0, ev->Cookie);
-}
-
-void THive::Handle(NConsole::TEvConfigsDispatcher::TEvSetConfigSubscriptionResponse::TPtr&) {
- // dummy
-}
-
-TResourceRawValues THive::GetDefaultResourceInitialMaximumValues() {
- TResourceRawValues values = {};
- std::get<NMetrics::EResource::Counter>(values) = 100000000; // MaximumTablets?
- std::get<NMetrics::EResource::CPU>(values) = 1000000 * 10; // 1 sec (per second) * 10 threads
- std::get<NMetrics::EResource::Memory>(values) = (ui64)512 << 30; // 512 GB
- std::get<NMetrics::EResource::Network>(values) = 1 << 30; // 10gbit network ~ 1gb/sec
- return values;
-}
-
-void THive::ProcessTabletBalancer() {
- if (!ProcessTabletBalancerScheduled && BootQueue.BootQueue.empty()) {
- Schedule(GetMinPeriodBetweenBalance(), new TEvPrivate::TEvProcessTabletBalancer());
- ProcessTabletBalancerScheduled = true;
- }
-}
-
-THive::THiveStats THive::GetStats() const {
- struct TNodeStat {
- TNodeId NodeId;
- double Usage;
- };
-
- THiveStats stats = {};
- TVector<TNodeStat> values;
- values.reserve(Nodes.size());
- for (const auto& ni : Nodes) {
- if (ni.second.IsAlive() && !ni.second.Down) {
- values.push_back({ni.first, ni.second.GetNodeUsage()});
- }
- }
- if (values.empty()) {
- return stats;
- }
- auto it = std::minmax_element(values.begin(), values.end(), [](const TNodeStat& a, const TNodeStat& b) -> bool {
- return a.Usage < b.Usage;
- });
- stats.MaxUsage = it.second->Usage;
- stats.MaxUsageNodeId = it.second->NodeId;
- stats.MinUsage = it.first->Usage;
- stats.MinUsageNodeId = it.first->NodeId;
- if (stats.MaxUsage > 0) {
- double minUsageToBalance = GetMinNodeUsageToBalance();
- double minUsage = std::max(stats.MinUsage, minUsageToBalance);
- double maxUsage = std::max(stats.MaxUsage, minUsageToBalance);
- stats.Scatter = (maxUsage - minUsage) / maxUsage;
- }
- return stats;
-}
-
-double THive::GetScatter() const {
- THiveStats stats = GetStats();
- return stats.Scatter;
-}
-
-double THive::GetUsage() const {
- THiveStats stats = GetStats();
- return stats.MaxUsage;
-}
-
-void THive::Handle(TEvPrivate::TEvProcessTabletBalancer::TPtr&) {
- ProcessTabletBalancerScheduled = false;
- if (!SubActors.empty()) {
- BLOG_D("Balancer has been postponed because of sub activity");
- ProcessTabletBalancer();
- return;
- }
-
- THiveStats stats = GetStats();
- BLOG_D("ProcessTabletBalancer"
- << " MaxUsage=" << Sprintf("%.9f", stats.MaxUsage) << " on #" << stats.MaxUsageNodeId
- << " MinUsage=" << Sprintf("%.9f", stats.MinUsage) << " on #" << stats.MinUsageNodeId
- << " Scatter=" << Sprintf("%.9f", stats.Scatter));
-
- TabletCounters->Simple()[NHive::COUNTER_BALANCE_SCATTER].Set(stats.Scatter * 100);
- TabletCounters->Simple()[NHive::COUNTER_BALANCE_USAGE_MIN].Set(stats.MinUsage * 100);
- TabletCounters->Simple()[NHive::COUNTER_BALANCE_USAGE_MAX].Set(stats.MaxUsage * 100);
-
- if (stats.MaxUsage >= GetMaxNodeUsageToKick()) {
- std::vector<TNodeId> overloadedNodes;
- for (const auto& [nodeId, nodeInfo] : Nodes) {
- if (nodeInfo.IsAlive() && !nodeInfo.Down && nodeInfo.IsOverloaded()) {
- overloadedNodes.emplace_back(nodeId);
- }
- }
-
- if (!overloadedNodes.empty()) {
- BLOG_D("Nodes " << overloadedNodes << " with usage over limit " << GetMaxNodeUsageToKick() << " - starting balancer");
- StartHiveBalancer(CurrentConfig.GetMaxMovementsOnAutoBalancer(), CurrentConfig.GetContinueAutoBalancer(), overloadedNodes);
- return;
- }
- }
-
- if (stats.MaxUsage < GetMinNodeUsageToBalance()) {
- TabletCounters->Cumulative()[NHive::COUNTER_SUGGESTED_SCALE_DOWN].Increment(1);
- }
-
- if (stats.Scatter >= GetMinScatterToBalance()) {
- BLOG_TRACE("Scatter " << stats.Scatter << " over limit "
- << GetMinScatterToBalance() << " - starting balancer");
- StartHiveBalancer(CurrentConfig.GetMaxMovementsOnAutoBalancer(), CurrentConfig.GetContinueAutoBalancer());
- }
-}
-
-void THive::UpdateTotalResourceValues(
- const TNodeInfo* node,
- const TTabletInfo* tablet,
- const NKikimrTabletBase::TMetrics& before,
- const NKikimrTabletBase::TMetrics& after,
- TResourceRawValues deltaRaw,
- TResourceNormalizedValues deltaNormalized) {
- TotalRawResourceValues = TotalRawResourceValues + deltaRaw;
- TotalNormalizedResourceValues = TotalNormalizedResourceValues + deltaNormalized;
- TInstant now = TInstant::Now();
-
- if (LastResourceChangeReaction + GetResourceChangeReactionPeriod() < now) {
- // in case we had overloaded nodes
- if (!BootQueue.WaitQueue.empty()) {
- ProcessWaitQueue();
- } else if (!BootQueue.BootQueue.empty()) {
- ProcessBootQueue();
- }
- ProcessTabletBalancer();
- LastResourceChangeReaction = now;
- }
-
- Y_UNUSED(node);
-
- if (tablet != nullptr) {
- auto& objectMetrics = ObjectToTabletMetrics[tablet->GetObjectId()];
- auto beforeMetrics = objectMetrics.Metrics;
- objectMetrics.AggregateDiff(before, after, tablet);
- BLOG_TRACE("UpdateTotalResources: ObjectId " << tablet->GetObjectId() <<
- ": {" << beforeMetrics.ShortDebugString() <<
- "} -> {" << objectMetrics.Metrics.ShortDebugString() << "}");
- auto& typeMetrics = TabletTypeToTabletMetrics[tablet->GetTabletType()];
- beforeMetrics = typeMetrics.Metrics;
- typeMetrics.AggregateDiff(before, after, tablet);
- BLOG_TRACE("UpdateTotalResources: Type " << tablet->GetTabletType() <<
- ": {" << beforeMetrics.ShortDebugString() <<
- "} -> {" << typeMetrics.Metrics.ShortDebugString() << "}");
- }
- TabletCounters->Simple()[NHive::COUNTER_METRICS_COUNTER].Set(std::get<NMetrics::EResource::Counter>(TotalRawResourceValues));
- TabletCounters->Simple()[NHive::COUNTER_METRICS_CPU].Set(std::get<NMetrics::EResource::CPU>(TotalRawResourceValues));
- TabletCounters->Simple()[NHive::COUNTER_METRICS_MEMORY].Set(std::get<NMetrics::EResource::Memory>(TotalRawResourceValues));
- TabletCounters->Simple()[NHive::COUNTER_METRICS_NETWORK].Set(std::get<NMetrics::EResource::Network>(TotalRawResourceValues));
-}
-
-void THive::RemoveSubActor(ISubActor* subActor) {
- auto it = std::find(SubActors.begin(), SubActors.end(), subActor);
- if (it != SubActors.end()) {
- SubActors.erase(it);
- }
-}
-
-bool THive::IsValidMetrics(const NKikimrTabletBase::TMetrics& metrics) {
- return IsValidMetricsCPU(metrics) || IsValidMetricsMemory(metrics) || IsValidMetricsNetwork(metrics);
-}
-
-bool THive::IsValidMetricsCPU(const NKikimrTabletBase::TMetrics& metrics) {
- return metrics.GetCPU() > 1000/*1ms*/;
-}
-
-bool THive::IsValidMetricsMemory(const NKikimrTabletBase::TMetrics& metrics) {
- return metrics.GetMemory() > 1024/*1KB*/;
-}
-
-bool THive::IsValidMetricsNetwork(const NKikimrTabletBase::TMetrics& metrics) {
- return metrics.GetNetwork() > 1024/*1KBps*/;
-}
-
+ Execute(CreateStartTablet(TFullTabletId(tabletId, 0), ev->Sender, ev->Cookie, /* external */ true));
+}
+
+void THive::Handle(NConsole::TEvConsole::TEvConfigNotificationRequest::TPtr& ev) {
+ const NKikimrConsole::TConfigNotificationRequest& record = ev->Get()->Record;
+ ClusterConfig = record.GetConfig().GetHiveConfig();
+ BLOG_D("Received TEvConsole::TEvConfigNotificationRequest with update of cluster config: " << ClusterConfig.ShortDebugString());
+ BuildCurrentConfig();
+ Send(ev->Sender, new NConsole::TEvConsole::TEvConfigNotificationResponse(record), 0, ev->Cookie);
+}
+
+void THive::Handle(NConsole::TEvConfigsDispatcher::TEvSetConfigSubscriptionResponse::TPtr&) {
+ // dummy
+}
+
+TResourceRawValues THive::GetDefaultResourceInitialMaximumValues() {
+ TResourceRawValues values = {};
+ std::get<NMetrics::EResource::Counter>(values) = 100000000; // MaximumTablets?
+ std::get<NMetrics::EResource::CPU>(values) = 1000000 * 10; // 1 sec (per second) * 10 threads
+ std::get<NMetrics::EResource::Memory>(values) = (ui64)512 << 30; // 512 GB
+ std::get<NMetrics::EResource::Network>(values) = 1 << 30; // 10gbit network ~ 1gb/sec
+ return values;
+}
+
+void THive::ProcessTabletBalancer() {
+ if (!ProcessTabletBalancerScheduled && BootQueue.BootQueue.empty()) {
+ Schedule(GetMinPeriodBetweenBalance(), new TEvPrivate::TEvProcessTabletBalancer());
+ ProcessTabletBalancerScheduled = true;
+ }
+}
+
+THive::THiveStats THive::GetStats() const {
+ struct TNodeStat {
+ TNodeId NodeId;
+ double Usage;
+ };
+
+ THiveStats stats = {};
+ TVector<TNodeStat> values;
+ values.reserve(Nodes.size());
+ for (const auto& ni : Nodes) {
+ if (ni.second.IsAlive() && !ni.second.Down) {
+ values.push_back({ni.first, ni.second.GetNodeUsage()});
+ }
+ }
+ if (values.empty()) {
+ return stats;
+ }
+ auto it = std::minmax_element(values.begin(), values.end(), [](const TNodeStat& a, const TNodeStat& b) -> bool {
+ return a.Usage < b.Usage;
+ });
+ stats.MaxUsage = it.second->Usage;
+ stats.MaxUsageNodeId = it.second->NodeId;
+ stats.MinUsage = it.first->Usage;
+ stats.MinUsageNodeId = it.first->NodeId;
+ if (stats.MaxUsage > 0) {
+ double minUsageToBalance = GetMinNodeUsageToBalance();
+ double minUsage = std::max(stats.MinUsage, minUsageToBalance);
+ double maxUsage = std::max(stats.MaxUsage, minUsageToBalance);
+ stats.Scatter = (maxUsage - minUsage) / maxUsage;
+ }
+ return stats;
+}
+
+double THive::GetScatter() const {
+ THiveStats stats = GetStats();
+ return stats.Scatter;
+}
+
+double THive::GetUsage() const {
+ THiveStats stats = GetStats();
+ return stats.MaxUsage;
+}
+
+void THive::Handle(TEvPrivate::TEvProcessTabletBalancer::TPtr&) {
+ ProcessTabletBalancerScheduled = false;
+ if (!SubActors.empty()) {
+ BLOG_D("Balancer has been postponed because of sub activity");
+ ProcessTabletBalancer();
+ return;
+ }
+
+ THiveStats stats = GetStats();
+ BLOG_D("ProcessTabletBalancer"
+ << " MaxUsage=" << Sprintf("%.9f", stats.MaxUsage) << " on #" << stats.MaxUsageNodeId
+ << " MinUsage=" << Sprintf("%.9f", stats.MinUsage) << " on #" << stats.MinUsageNodeId
+ << " Scatter=" << Sprintf("%.9f", stats.Scatter));
+
+ TabletCounters->Simple()[NHive::COUNTER_BALANCE_SCATTER].Set(stats.Scatter * 100);
+ TabletCounters->Simple()[NHive::COUNTER_BALANCE_USAGE_MIN].Set(stats.MinUsage * 100);
+ TabletCounters->Simple()[NHive::COUNTER_BALANCE_USAGE_MAX].Set(stats.MaxUsage * 100);
+
+ if (stats.MaxUsage >= GetMaxNodeUsageToKick()) {
+ std::vector<TNodeId> overloadedNodes;
+ for (const auto& [nodeId, nodeInfo] : Nodes) {
+ if (nodeInfo.IsAlive() && !nodeInfo.Down && nodeInfo.IsOverloaded()) {
+ overloadedNodes.emplace_back(nodeId);
+ }
+ }
+
+ if (!overloadedNodes.empty()) {
+ BLOG_D("Nodes " << overloadedNodes << " with usage over limit " << GetMaxNodeUsageToKick() << " - starting balancer");
+ StartHiveBalancer(CurrentConfig.GetMaxMovementsOnAutoBalancer(), CurrentConfig.GetContinueAutoBalancer(), overloadedNodes);
+ return;
+ }
+ }
+
+ if (stats.MaxUsage < GetMinNodeUsageToBalance()) {
+ TabletCounters->Cumulative()[NHive::COUNTER_SUGGESTED_SCALE_DOWN].Increment(1);
+ }
+
+ if (stats.Scatter >= GetMinScatterToBalance()) {
+ BLOG_TRACE("Scatter " << stats.Scatter << " over limit "
+ << GetMinScatterToBalance() << " - starting balancer");
+ StartHiveBalancer(CurrentConfig.GetMaxMovementsOnAutoBalancer(), CurrentConfig.GetContinueAutoBalancer());
+ }
+}
+
+void THive::UpdateTotalResourceValues(
+ const TNodeInfo* node,
+ const TTabletInfo* tablet,
+ const NKikimrTabletBase::TMetrics& before,
+ const NKikimrTabletBase::TMetrics& after,
+ TResourceRawValues deltaRaw,
+ TResourceNormalizedValues deltaNormalized) {
+ TotalRawResourceValues = TotalRawResourceValues + deltaRaw;
+ TotalNormalizedResourceValues = TotalNormalizedResourceValues + deltaNormalized;
+ TInstant now = TInstant::Now();
+
+ if (LastResourceChangeReaction + GetResourceChangeReactionPeriod() < now) {
+ // in case we had overloaded nodes
+ if (!BootQueue.WaitQueue.empty()) {
+ ProcessWaitQueue();
+ } else if (!BootQueue.BootQueue.empty()) {
+ ProcessBootQueue();
+ }
+ ProcessTabletBalancer();
+ LastResourceChangeReaction = now;
+ }
+
+ Y_UNUSED(node);
+
+ if (tablet != nullptr) {
+ auto& objectMetrics = ObjectToTabletMetrics[tablet->GetObjectId()];
+ auto beforeMetrics = objectMetrics.Metrics;
+ objectMetrics.AggregateDiff(before, after, tablet);
+ BLOG_TRACE("UpdateTotalResources: ObjectId " << tablet->GetObjectId() <<
+ ": {" << beforeMetrics.ShortDebugString() <<
+ "} -> {" << objectMetrics.Metrics.ShortDebugString() << "}");
+ auto& typeMetrics = TabletTypeToTabletMetrics[tablet->GetTabletType()];
+ beforeMetrics = typeMetrics.Metrics;
+ typeMetrics.AggregateDiff(before, after, tablet);
+ BLOG_TRACE("UpdateTotalResources: Type " << tablet->GetTabletType() <<
+ ": {" << beforeMetrics.ShortDebugString() <<
+ "} -> {" << typeMetrics.Metrics.ShortDebugString() << "}");
+ }
+ TabletCounters->Simple()[NHive::COUNTER_METRICS_COUNTER].Set(std::get<NMetrics::EResource::Counter>(TotalRawResourceValues));
+ TabletCounters->Simple()[NHive::COUNTER_METRICS_CPU].Set(std::get<NMetrics::EResource::CPU>(TotalRawResourceValues));
+ TabletCounters->Simple()[NHive::COUNTER_METRICS_MEMORY].Set(std::get<NMetrics::EResource::Memory>(TotalRawResourceValues));
+ TabletCounters->Simple()[NHive::COUNTER_METRICS_NETWORK].Set(std::get<NMetrics::EResource::Network>(TotalRawResourceValues));
+}
+
+void THive::RemoveSubActor(ISubActor* subActor) {
+ auto it = std::find(SubActors.begin(), SubActors.end(), subActor);
+ if (it != SubActors.end()) {
+ SubActors.erase(it);
+ }
+}
+
+bool THive::IsValidMetrics(const NKikimrTabletBase::TMetrics& metrics) {
+ return IsValidMetricsCPU(metrics) || IsValidMetricsMemory(metrics) || IsValidMetricsNetwork(metrics);
+}
+
+bool THive::IsValidMetricsCPU(const NKikimrTabletBase::TMetrics& metrics) {
+ return metrics.GetCPU() > 1000/*1ms*/;
+}
+
+bool THive::IsValidMetricsMemory(const NKikimrTabletBase::TMetrics& metrics) {
+ return metrics.GetMemory() > 1024/*1KB*/;
+}
+
+bool THive::IsValidMetricsNetwork(const NKikimrTabletBase::TMetrics& metrics) {
+ return metrics.GetNetwork() > 1024/*1KBps*/;
+}
+
TString THive::DebugDomainsActiveNodes() const {
return DomainsView.AsString();
}
-void THive::AggregateMetricsMax(NKikimrTabletBase::TMetrics& aggregate, const NKikimrTabletBase::TMetrics& value) {
- aggregate.SetCPU(std::max(aggregate.GetCPU(), value.GetCPU()));
- aggregate.SetMemory(std::max(aggregate.GetMemory(), value.GetMemory()));
- aggregate.SetNetwork(std::max(aggregate.GetNetwork(), value.GetNetwork()));
- aggregate.SetCounter(std::max(aggregate.GetCounter(), value.GetCounter()));
- aggregate.SetStorage(std::max(aggregate.GetStorage(), value.GetStorage()));
- aggregate.SetReadThroughput(std::max(aggregate.GetReadThroughput(), value.GetReadThroughput()));
- aggregate.SetWriteThroughput(std::max(aggregate.GetWriteThroughput(), value.GetWriteThroughput()));
-}
-
-template <void (NKikimrTabletBase::TMetrics::* setter)(ui64), ui64 (NKikimrTabletBase::TMetrics::* getter)() const, void (NKikimrTabletBase::TMetrics::* clear)()>
-static void AggregateDiff(NKikimrTabletBase::TMetrics& aggregate, const NKikimrTabletBase::TMetrics& before, const NKikimrTabletBase::TMetrics& after, TTabletId tabletId, const TString& name) {
- i64 oldValue = (aggregate.*getter)();
- i64 delta = (after.*getter)() - (before.*getter)();
- i64 newValue = oldValue + delta;
- Y_ENSURE_LOG(newValue >= 0, "tablet " << tabletId << " name=" << name << " oldValue=" << oldValue << " delta=" << delta << " newValue=" << newValue);
- newValue = Max(newValue, (i64)0);
- if (newValue != 0) {
- (aggregate.*setter)(newValue);
- } else {
- (aggregate.*clear)();
- }
-}
-
-void THive::AggregateMetricsDiff(NKikimrTabletBase::TMetrics& aggregate, const NKikimrTabletBase::TMetrics& before, const NKikimrTabletBase::TMetrics& after, const TTabletInfo* tablet) {
+void THive::AggregateMetricsMax(NKikimrTabletBase::TMetrics& aggregate, const NKikimrTabletBase::TMetrics& value) {
+ aggregate.SetCPU(std::max(aggregate.GetCPU(), value.GetCPU()));
+ aggregate.SetMemory(std::max(aggregate.GetMemory(), value.GetMemory()));
+ aggregate.SetNetwork(std::max(aggregate.GetNetwork(), value.GetNetwork()));
+ aggregate.SetCounter(std::max(aggregate.GetCounter(), value.GetCounter()));
+ aggregate.SetStorage(std::max(aggregate.GetStorage(), value.GetStorage()));
+ aggregate.SetReadThroughput(std::max(aggregate.GetReadThroughput(), value.GetReadThroughput()));
+ aggregate.SetWriteThroughput(std::max(aggregate.GetWriteThroughput(), value.GetWriteThroughput()));
+}
+
+template <void (NKikimrTabletBase::TMetrics::* setter)(ui64), ui64 (NKikimrTabletBase::TMetrics::* getter)() const, void (NKikimrTabletBase::TMetrics::* clear)()>
+static void AggregateDiff(NKikimrTabletBase::TMetrics& aggregate, const NKikimrTabletBase::TMetrics& before, const NKikimrTabletBase::TMetrics& after, TTabletId tabletId, const TString& name) {
+ i64 oldValue = (aggregate.*getter)();
+ i64 delta = (after.*getter)() - (before.*getter)();
+ i64 newValue = oldValue + delta;
+ Y_ENSURE_LOG(newValue >= 0, "tablet " << tabletId << " name=" << name << " oldValue=" << oldValue << " delta=" << delta << " newValue=" << newValue);
+ newValue = Max(newValue, (i64)0);
+ if (newValue != 0) {
+ (aggregate.*setter)(newValue);
+ } else {
+ (aggregate.*clear)();
+ }
+}
+
+void THive::AggregateMetricsDiff(NKikimrTabletBase::TMetrics& aggregate, const NKikimrTabletBase::TMetrics& before, const NKikimrTabletBase::TMetrics& after, const TTabletInfo* tablet) {
AggregateDiff<&NKikimrTabletBase::TMetrics::SetCPU, &NKikimrTabletBase::TMetrics::GetCPU, &NKikimrTabletBase::TMetrics::ClearCPU>(aggregate, before, after, tablet->GetLeader().Id, "cpu");
AggregateDiff<&NKikimrTabletBase::TMetrics::SetMemory, &NKikimrTabletBase::TMetrics::GetMemory, &NKikimrTabletBase::TMetrics::ClearMemory>(aggregate, before, after, tablet->GetLeader().Id, "memory");
AggregateDiff<&NKikimrTabletBase::TMetrics::SetNetwork, &NKikimrTabletBase::TMetrics::GetNetwork, &NKikimrTabletBase::TMetrics::ClearNetwork>(aggregate, before, after, tablet->GetLeader().Id, "network");
@@ -2075,318 +2075,318 @@ void THive::AggregateMetricsDiff(NKikimrTabletBase::TMetrics& aggregate, const N
AggregateDiff<&NKikimrTabletBase::TMetrics::SetStorage, &NKikimrTabletBase::TMetrics::GetStorage, &NKikimrTabletBase::TMetrics::ClearStorage>(aggregate, before, after, tablet->GetLeader().Id, "storage");
AggregateDiff<&NKikimrTabletBase::TMetrics::SetReadThroughput, &NKikimrTabletBase::TMetrics::GetReadThroughput, &NKikimrTabletBase::TMetrics::ClearReadThroughput>(aggregate, before, after, tablet->GetLeader().Id, "read");
AggregateDiff<&NKikimrTabletBase::TMetrics::SetWriteThroughput, &NKikimrTabletBase::TMetrics::GetWriteThroughput, &NKikimrTabletBase::TMetrics::ClearWriteThroughput>(aggregate, before, after, tablet->GetLeader().Id, "write");
-}
-
-void THive::DivideMetrics(NKikimrTabletBase::TMetrics& metrics, ui64 divider) {
- metrics.SetCPU(metrics.GetCPU() / divider);
- metrics.SetMemory(metrics.GetMemory() / divider);
- metrics.SetNetwork(metrics.GetNetwork() / divider);
- metrics.SetCounter(metrics.GetCounter() / divider);
- metrics.SetStorage(metrics.GetStorage() / divider);
- metrics.SetReadThroughput(metrics.GetReadThroughput() / divider);
- metrics.SetWriteThroughput(metrics.GetWriteThroughput() / divider);
-}
-
-NKikimrTabletBase::TMetrics THive::GetDefaultResourceValuesForObject(TObjectId objectId) {
- NKikimrTabletBase::TMetrics metrics;
- auto itTablets = ObjectToTabletMetrics.find(objectId);
- if (itTablets != ObjectToTabletMetrics.end()) {
- metrics = itTablets->second.GetAverage();
- metrics.ClearCounter();
- }
- return metrics;
-}
-
+}
+
+void THive::DivideMetrics(NKikimrTabletBase::TMetrics& metrics, ui64 divider) {
+ metrics.SetCPU(metrics.GetCPU() / divider);
+ metrics.SetMemory(metrics.GetMemory() / divider);
+ metrics.SetNetwork(metrics.GetNetwork() / divider);
+ metrics.SetCounter(metrics.GetCounter() / divider);
+ metrics.SetStorage(metrics.GetStorage() / divider);
+ metrics.SetReadThroughput(metrics.GetReadThroughput() / divider);
+ metrics.SetWriteThroughput(metrics.GetWriteThroughput() / divider);
+}
+
+NKikimrTabletBase::TMetrics THive::GetDefaultResourceValuesForObject(TObjectId objectId) {
+ NKikimrTabletBase::TMetrics metrics;
+ auto itTablets = ObjectToTabletMetrics.find(objectId);
+ if (itTablets != ObjectToTabletMetrics.end()) {
+ metrics = itTablets->second.GetAverage();
+ metrics.ClearCounter();
+ }
+ return metrics;
+}
+
NKikimrTabletBase::TMetrics THive::GetDefaultResourceValuesForTabletType(TTabletTypes::EType type) {
NKikimrTabletBase::TMetrics metrics;
- auto it = TabletTypeToTabletMetrics.find(type);
- if (it != TabletTypeToTabletMetrics.end()) {
- metrics = it->second.GetAverage();
- metrics.ClearCounter();
+ auto it = TabletTypeToTabletMetrics.find(type);
+ if (it != TabletTypeToTabletMetrics.end()) {
+ metrics = it->second.GetAverage();
+ metrics.ClearCounter();
}
return metrics;
}
-NKikimrTabletBase::TMetrics THive::GetDefaultResourceValuesForProfile(TTabletTypes::EType type, const TString& resourceProfile) {
- NKikimrTabletBase::TMetrics resourceValues;
- // copy default resource usage from resource profile
- if (ResourceProfiles) {
- // TODO: provide Hive with resource profile used by the tablet instead of default one.
- auto profile = ResourceProfiles->GetProfile(type, resourceProfile);
- resourceValues.SetMemory(profile->GetDefaultTabletMemoryUsage());
- }
- return resourceValues;
-}
-
-const TVector<i64>& THive::GetDefaultAllowedMetricIds() {
- static const TVector<i64> defaultAllowedMetricIds = {
- NKikimrTabletBase::TMetrics::kCounterFieldNumber,
- NKikimrTabletBase::TMetrics::kCPUFieldNumber,
- NKikimrTabletBase::TMetrics::kMemoryFieldNumber,
- NKikimrTabletBase::TMetrics::kNetworkFieldNumber,
- NKikimrTabletBase::TMetrics::kStorageFieldNumber,
- NKikimrTabletBase::TMetrics::kGroupReadThroughputFieldNumber,
- NKikimrTabletBase::TMetrics::kGroupWriteThroughputFieldNumber
- };
- return defaultAllowedMetricIds;
-}
-
-const TVector<i64>& THive::GetTabletTypeAllowedMetricIds(TTabletTypes::EType type) const {
- const TVector<i64>& defaultAllowedMetricIds = GetDefaultAllowedMetricIds();
- auto it = TabletTypeAllowedMetrics.find(type);
- if (it != TabletTypeAllowedMetrics.end()) {
- return it->second;
- }
- return defaultAllowedMetricIds;
-}
-
+NKikimrTabletBase::TMetrics THive::GetDefaultResourceValuesForProfile(TTabletTypes::EType type, const TString& resourceProfile) {
+ NKikimrTabletBase::TMetrics resourceValues;
+ // copy default resource usage from resource profile
+ if (ResourceProfiles) {
+ // TODO: provide Hive with resource profile used by the tablet instead of default one.
+ auto profile = ResourceProfiles->GetProfile(type, resourceProfile);
+ resourceValues.SetMemory(profile->GetDefaultTabletMemoryUsage());
+ }
+ return resourceValues;
+}
+
+const TVector<i64>& THive::GetDefaultAllowedMetricIds() {
+ static const TVector<i64> defaultAllowedMetricIds = {
+ NKikimrTabletBase::TMetrics::kCounterFieldNumber,
+ NKikimrTabletBase::TMetrics::kCPUFieldNumber,
+ NKikimrTabletBase::TMetrics::kMemoryFieldNumber,
+ NKikimrTabletBase::TMetrics::kNetworkFieldNumber,
+ NKikimrTabletBase::TMetrics::kStorageFieldNumber,
+ NKikimrTabletBase::TMetrics::kGroupReadThroughputFieldNumber,
+ NKikimrTabletBase::TMetrics::kGroupWriteThroughputFieldNumber
+ };
+ return defaultAllowedMetricIds;
+}
+
+const TVector<i64>& THive::GetTabletTypeAllowedMetricIds(TTabletTypes::EType type) const {
+ const TVector<i64>& defaultAllowedMetricIds = GetDefaultAllowedMetricIds();
+ auto it = TabletTypeAllowedMetrics.find(type);
+ if (it != TabletTypeAllowedMetrics.end()) {
+ return it->second;
+ }
+ return defaultAllowedMetricIds;
+}
+
THolder<NKikimrBlobStorage::TEvControllerSelectGroups::TGroupParameters> THive::BuildGroupParametersForChannel(const TLeaderTabletInfo& tablet, ui32 channelId) {
THolder<NKikimrBlobStorage::TEvControllerSelectGroups::TGroupParameters> groupParameters = MakeHolder<NKikimrBlobStorage::TEvControllerSelectGroups::TGroupParameters>();
- Y_VERIFY(channelId < tablet.BoundChannels.size());
- const auto& binding = tablet.BoundChannels[channelId];
- groupParameters->MutableStoragePoolSpecifier()->SetName(binding.GetStoragePoolName());
- return groupParameters;
-}
-
+ Y_VERIFY(channelId < tablet.BoundChannels.size());
+ const auto& binding = tablet.BoundChannels[channelId];
+ groupParameters->MutableStoragePoolSpecifier()->SetName(binding.GetStoragePoolName());
+ return groupParameters;
+}
+
void THive::ExecuteStartTablet(TFullTabletId tabletId, const TActorId& local, ui64 cookie, bool external) {
- Execute(CreateStartTablet(tabletId, local, cookie, external));
-}
-
+ Execute(CreateStartTablet(tabletId, local, cookie, external));
+}
+
void THive::SendPing(const TActorId& local, TNodeId id) {
- Send(local,
- new TEvLocal::TEvPing(HiveId,
- HiveGeneration,
- false,
- GetLocalConfig()),
- IEventHandle::FlagTrackDelivery | IEventHandle::FlagSubscribeOnSession,
- id);
-}
-
+ Send(local,
+ new TEvLocal::TEvPing(HiveId,
+ HiveGeneration,
+ false,
+ GetLocalConfig()),
+ IEventHandle::FlagTrackDelivery | IEventHandle::FlagSubscribeOnSession,
+ id);
+}
+
void THive::SendReconnect(const TActorId& local) {
- Send(local, new TEvLocal::TEvReconnect(HiveId, HiveGeneration));
-}
-
-ui32 THive::GetDataCenters() {
- return DataCenters;
-}
-
-ui32 THive::GetRegisteredDataCenters() {
- return RegisteredDataCenters;
-}
-
-void THive::UpdateRegisteredDataCenters(TDataCenterId dataCenterId) {
- if (dataCenterId != 0) { // ignore default data center id if exists
- RegisteredDataCenterIds.insert(dataCenterId);
- if (RegisteredDataCenters != RegisteredDataCenterIds.size()) {
- RegisteredDataCenters = RegisteredDataCenterIds.size();
- BLOG_D("THive (UpdateRegisteredDC) DataCenters=" << DataCenters << " RegisteredDataCenters=" << RegisteredDataCenters);
- }
- }
-}
-
+ Send(local, new TEvLocal::TEvReconnect(HiveId, HiveGeneration));
+}
+
+ui32 THive::GetDataCenters() {
+ return DataCenters;
+}
+
+ui32 THive::GetRegisteredDataCenters() {
+ return RegisteredDataCenters;
+}
+
+void THive::UpdateRegisteredDataCenters(TDataCenterId dataCenterId) {
+ if (dataCenterId != 0) { // ignore default data center id if exists
+ RegisteredDataCenterIds.insert(dataCenterId);
+ if (RegisteredDataCenters != RegisteredDataCenterIds.size()) {
+ RegisteredDataCenters = RegisteredDataCenterIds.size();
+ BLOG_D("THive (UpdateRegisteredDC) DataCenters=" << DataCenters << " RegisteredDataCenters=" << RegisteredDataCenters);
+ }
+ }
+}
+
THive::THive(TTabletStorageInfo *info, const TActorId &tablet)
- : TActor(&TThis::StateInit)
- , TTabletExecutedFlat(info, tablet, new NMiniKQL::TMiniKQLFactory)
- , HiveUid(Max<ui32>())
- , HiveDomain(Max<ui32>())
+ : TActor(&TThis::StateInit)
+ , TTabletExecutedFlat(info, tablet, new NMiniKQL::TMiniKQLFactory)
+ , HiveUid(Max<ui32>())
+ , HiveDomain(Max<ui32>())
, RootHiveId()
- , HiveId(Max<ui64>())
- , HiveGeneration(0)
- , PipeClientCacheConfig(new NTabletPipe::TBoundedClientCacheConfig())
- , PipeClientCache(NTabletPipe::CreateBoundedClientCache(PipeClientCacheConfig))
- , PipeTracker(*PipeClientCache)
- , PipeRetryPolicy()
- , BalancerProgress(-1)
- , ResponsivenessPinger(nullptr)
-{
- TabletCountersPtr.Reset(new TProtobufTabletCounters<
- ESimpleCounters_descriptor,
- ECumulativeCounters_descriptor,
- EPercentileCounters_descriptor,
- ETxTypes_descriptor
- >());
- TabletCounters = TabletCountersPtr.Get();
-}
-
-void THive::Handle(TEvHive::TEvInvalidateStoragePools::TPtr&) {
- for (auto& pr : StoragePools) {
- pr.second.Invalidate();
- }
-}
-
-void THive::InitDefaultChannelBind(TChannelBind& bind) {
- if (!bind.HasIOPS()) {
- bind.SetIOPS(GetDefaultUnitIOPS());
- }
- if (!bind.HasSize()) {
- bind.SetSize(GetDefaultUnitSize());
- }
- if (!bind.HasThroughput()) {
- bind.SetThroughput(GetDefaultUnitThroughput());
- }
-}
-
-void THive::RequestPoolsInformation() {
- BLOG_D("THive::RequestPoolsInformation()");
- TVector<THolder<NKikimrBlobStorage::TEvControllerSelectGroups::TGroupParameters>> requests;
-
- for (const auto& [poolName, storagePool] : StoragePools) {
- THolder<NKikimrBlobStorage::TEvControllerSelectGroups::TGroupParameters> item = storagePool.BuildRefreshRequest();
- requests.emplace_back(std::move(item));
- }
-
- if (!requests.empty()) {
+ , HiveId(Max<ui64>())
+ , HiveGeneration(0)
+ , PipeClientCacheConfig(new NTabletPipe::TBoundedClientCacheConfig())
+ , PipeClientCache(NTabletPipe::CreateBoundedClientCache(PipeClientCacheConfig))
+ , PipeTracker(*PipeClientCache)
+ , PipeRetryPolicy()
+ , BalancerProgress(-1)
+ , ResponsivenessPinger(nullptr)
+{
+ TabletCountersPtr.Reset(new TProtobufTabletCounters<
+ ESimpleCounters_descriptor,
+ ECumulativeCounters_descriptor,
+ EPercentileCounters_descriptor,
+ ETxTypes_descriptor
+ >());
+ TabletCounters = TabletCountersPtr.Get();
+}
+
+void THive::Handle(TEvHive::TEvInvalidateStoragePools::TPtr&) {
+ for (auto& pr : StoragePools) {
+ pr.second.Invalidate();
+ }
+}
+
+void THive::InitDefaultChannelBind(TChannelBind& bind) {
+ if (!bind.HasIOPS()) {
+ bind.SetIOPS(GetDefaultUnitIOPS());
+ }
+ if (!bind.HasSize()) {
+ bind.SetSize(GetDefaultUnitSize());
+ }
+ if (!bind.HasThroughput()) {
+ bind.SetThroughput(GetDefaultUnitThroughput());
+ }
+}
+
+void THive::RequestPoolsInformation() {
+ BLOG_D("THive::RequestPoolsInformation()");
+ TVector<THolder<NKikimrBlobStorage::TEvControllerSelectGroups::TGroupParameters>> requests;
+
+ for (const auto& [poolName, storagePool] : StoragePools) {
+ THolder<NKikimrBlobStorage::TEvControllerSelectGroups::TGroupParameters> item = storagePool.BuildRefreshRequest();
+ requests.emplace_back(std::move(item));
+ }
+
+ if (!requests.empty()) {
THolder<TEvBlobStorage::TEvControllerSelectGroups> ev = MakeHolder<TEvBlobStorage::TEvControllerSelectGroups>();
- NKikimrBlobStorage::TEvControllerSelectGroups& record = ev->Record;
- record.SetReturnAllMatchingGroups(true);
- record.SetBlockUntilAllResourcesAreComplete(true);
- for (auto& request : requests) {
- record.MutableGroupParameters()->AddAllocated(std::move(request).Release());
- }
- SendToBSControllerPipe(ev.Release());
- }
-}
-
-STFUNC(THive::StateInit) {
- switch (ev->GetTypeRewrite()) {
- hFunc(TEvInterconnect::TEvNodesInfo, Handle);
- default:
- StateInitImpl(ev, ctx);
- }
-}
-
-STFUNC(THive::StateWork) {
- if (ResponsivenessPinger)
- ResponsivenessPinger->OnAnyEvent(ctx);
-
- switch (ev->GetTypeRewrite()) {
- hFunc(TEvHive::TEvCreateTablet, Handle);
- hFunc(TEvHive::TEvAdoptTablet, Handle);
- hFunc(TEvHive::TEvStopTablet, Handle);
- hFunc(TEvHive::TEvBootTablet, Handle);
- hFunc(TEvLocal::TEvStatus, Handle);
- hFunc(TEvLocal::TEvTabletStatus, Handle); // from bootqueue
- hFunc(TEvLocal::TEvRegisterNode, Handle); // from local
- hFunc(TEvBlobStorage::TEvControllerSelectGroupsResult, Handle);
- hFunc(TEvents::TEvPoisonPill, Handle);
- hFunc(TEvTabletPipe::TEvClientConnected, Handle);
- hFunc(TEvTabletPipe::TEvClientDestroyed, Handle);
- hFunc(TEvTabletPipe::TEvServerConnected, Handle);
- hFunc(TEvTabletPipe::TEvServerDisconnected, Handle);
- hFunc(TEvPrivate::TEvBootTablets, Handle);
- hFunc(TEvHive::TEvInitMigration, Handle);
- hFunc(TEvHive::TEvQueryMigration, Handle);
- hFunc(TEvInterconnect::TEvNodeConnected, Handle);
- hFunc(TEvInterconnect::TEvNodeDisconnected, Handle);
- hFunc(TEvInterconnect::TEvNodeInfo, Handle);
- hFunc(TEvInterconnect::TEvNodesInfo, Handle);
- hFunc(TEvents::TEvUndelivered, Handle);
- hFunc(TEvPrivate::TEvProcessBootQueue, Handle);
- hFunc(TEvPrivate::TEvPostponeProcessBootQueue, Handle);
- hFunc(TEvPrivate::TEvProcessPendingOperations, Handle);
- hFunc(TEvPrivate::TEvProcessDisconnectNode, Handle);
- hFunc(TEvLocal::TEvSyncTablets, Handle);
- hFunc(TEvPrivate::TEvKickTablet, Handle);
- hFunc(TEvHive::TEvTabletMetrics, Handle);
- hFunc(TEvTabletBase::TEvBlockBlobStorageResult, Handle);
- hFunc(TEvTabletBase::TEvDeleteTabletResult, Handle);
- hFunc(TEvHive::TEvReassignTablet, Handle);
- hFunc(TEvHive::TEvInitiateBlockStorage, Handle);
- hFunc(TEvHive::TEvDeleteTablet, Handle);
- hFunc(TEvHive::TEvDeleteOwnerTablets, Handle);
- hFunc(TEvHive::TEvRequestHiveInfo, Handle);
- hFunc(TEvHive::TEvLookupTablet, Handle);
- hFunc(TEvHive::TEvLookupChannelInfo, Handle);
- hFunc(TEvHive::TEvCutTabletHistory, Handle);
- hFunc(TEvHive::TEvDrainNode, Handle);
- hFunc(TEvHive::TEvFillNode, Handle);
- hFunc(TEvHive::TEvInitiateDeleteStorage, Handle);
- hFunc(TEvHive::TEvGetTabletStorageInfo, Handle);
- hFunc(TEvHive::TEvLockTabletExecution, Handle);
- hFunc(TEvHive::TEvUnlockTabletExecution, Handle);
- hFunc(TEvPrivate::TEvProcessTabletBalancer, Handle);
- hFunc(TEvPrivate::TEvUnlockTabletReconnectTimeout, Handle);
- hFunc(TEvHive::TEvInitiateTabletExternalBoot, Handle);
- hFunc(TEvHive::TEvRequestHiveDomainStats, Handle);
- hFunc(TEvHive::TEvRequestHiveNodeStats, Handle);
- hFunc(TEvHive::TEvRequestHiveStorageStats, Handle);
- hFunc(TEvHive::TEvInvalidateStoragePools, Handle);
- hFunc(TEvHive::TEvRequestTabletIdSequence, Handle);
- hFunc(TEvHive::TEvResponseTabletIdSequence, Handle);
- hFunc(TEvHive::TEvSeizeTablets, Handle);
- hFunc(TEvHive::TEvSeizeTabletsReply, Handle);
- hFunc(TEvHive::TEvReleaseTablets, Handle);
- hFunc(TEvHive::TEvReleaseTabletsReply, Handle);
- hFunc(TEvSubDomain::TEvConfigure, Handle);
- hFunc(TEvHive::TEvConfigureHive, Handle);
- hFunc(TEvTxProxySchemeCache::TEvNavigateKeySetResult, Handle);
- hFunc(NConsole::TEvConsole::TEvConfigNotificationRequest, Handle);
- hFunc(NConsole::TEvConfigsDispatcher::TEvSetConfigSubscriptionResponse, Handle);
+ NKikimrBlobStorage::TEvControllerSelectGroups& record = ev->Record;
+ record.SetReturnAllMatchingGroups(true);
+ record.SetBlockUntilAllResourcesAreComplete(true);
+ for (auto& request : requests) {
+ record.MutableGroupParameters()->AddAllocated(std::move(request).Release());
+ }
+ SendToBSControllerPipe(ev.Release());
+ }
+}
+
+STFUNC(THive::StateInit) {
+ switch (ev->GetTypeRewrite()) {
+ hFunc(TEvInterconnect::TEvNodesInfo, Handle);
+ default:
+ StateInitImpl(ev, ctx);
+ }
+}
+
+STFUNC(THive::StateWork) {
+ if (ResponsivenessPinger)
+ ResponsivenessPinger->OnAnyEvent(ctx);
+
+ switch (ev->GetTypeRewrite()) {
+ hFunc(TEvHive::TEvCreateTablet, Handle);
+ hFunc(TEvHive::TEvAdoptTablet, Handle);
+ hFunc(TEvHive::TEvStopTablet, Handle);
+ hFunc(TEvHive::TEvBootTablet, Handle);
+ hFunc(TEvLocal::TEvStatus, Handle);
+ hFunc(TEvLocal::TEvTabletStatus, Handle); // from bootqueue
+ hFunc(TEvLocal::TEvRegisterNode, Handle); // from local
+ hFunc(TEvBlobStorage::TEvControllerSelectGroupsResult, Handle);
+ hFunc(TEvents::TEvPoisonPill, Handle);
+ hFunc(TEvTabletPipe::TEvClientConnected, Handle);
+ hFunc(TEvTabletPipe::TEvClientDestroyed, Handle);
+ hFunc(TEvTabletPipe::TEvServerConnected, Handle);
+ hFunc(TEvTabletPipe::TEvServerDisconnected, Handle);
+ hFunc(TEvPrivate::TEvBootTablets, Handle);
+ hFunc(TEvHive::TEvInitMigration, Handle);
+ hFunc(TEvHive::TEvQueryMigration, Handle);
+ hFunc(TEvInterconnect::TEvNodeConnected, Handle);
+ hFunc(TEvInterconnect::TEvNodeDisconnected, Handle);
+ hFunc(TEvInterconnect::TEvNodeInfo, Handle);
+ hFunc(TEvInterconnect::TEvNodesInfo, Handle);
+ hFunc(TEvents::TEvUndelivered, Handle);
+ hFunc(TEvPrivate::TEvProcessBootQueue, Handle);
+ hFunc(TEvPrivate::TEvPostponeProcessBootQueue, Handle);
+ hFunc(TEvPrivate::TEvProcessPendingOperations, Handle);
+ hFunc(TEvPrivate::TEvProcessDisconnectNode, Handle);
+ hFunc(TEvLocal::TEvSyncTablets, Handle);
+ hFunc(TEvPrivate::TEvKickTablet, Handle);
+ hFunc(TEvHive::TEvTabletMetrics, Handle);
+ hFunc(TEvTabletBase::TEvBlockBlobStorageResult, Handle);
+ hFunc(TEvTabletBase::TEvDeleteTabletResult, Handle);
+ hFunc(TEvHive::TEvReassignTablet, Handle);
+ hFunc(TEvHive::TEvInitiateBlockStorage, Handle);
+ hFunc(TEvHive::TEvDeleteTablet, Handle);
+ hFunc(TEvHive::TEvDeleteOwnerTablets, Handle);
+ hFunc(TEvHive::TEvRequestHiveInfo, Handle);
+ hFunc(TEvHive::TEvLookupTablet, Handle);
+ hFunc(TEvHive::TEvLookupChannelInfo, Handle);
+ hFunc(TEvHive::TEvCutTabletHistory, Handle);
+ hFunc(TEvHive::TEvDrainNode, Handle);
+ hFunc(TEvHive::TEvFillNode, Handle);
+ hFunc(TEvHive::TEvInitiateDeleteStorage, Handle);
+ hFunc(TEvHive::TEvGetTabletStorageInfo, Handle);
+ hFunc(TEvHive::TEvLockTabletExecution, Handle);
+ hFunc(TEvHive::TEvUnlockTabletExecution, Handle);
+ hFunc(TEvPrivate::TEvProcessTabletBalancer, Handle);
+ hFunc(TEvPrivate::TEvUnlockTabletReconnectTimeout, Handle);
+ hFunc(TEvHive::TEvInitiateTabletExternalBoot, Handle);
+ hFunc(TEvHive::TEvRequestHiveDomainStats, Handle);
+ hFunc(TEvHive::TEvRequestHiveNodeStats, Handle);
+ hFunc(TEvHive::TEvRequestHiveStorageStats, Handle);
+ hFunc(TEvHive::TEvInvalidateStoragePools, Handle);
+ hFunc(TEvHive::TEvRequestTabletIdSequence, Handle);
+ hFunc(TEvHive::TEvResponseTabletIdSequence, Handle);
+ hFunc(TEvHive::TEvSeizeTablets, Handle);
+ hFunc(TEvHive::TEvSeizeTabletsReply, Handle);
+ hFunc(TEvHive::TEvReleaseTablets, Handle);
+ hFunc(TEvHive::TEvReleaseTabletsReply, Handle);
+ hFunc(TEvSubDomain::TEvConfigure, Handle);
+ hFunc(TEvHive::TEvConfigureHive, Handle);
+ hFunc(TEvTxProxySchemeCache::TEvNavigateKeySetResult, Handle);
+ hFunc(NConsole::TEvConsole::TEvConfigNotificationRequest, Handle);
+ hFunc(NConsole::TEvConfigsDispatcher::TEvSetConfigSubscriptionResponse, Handle);
hFunc(NSysView::TEvSysView::TEvGetTabletIdsRequest, Handle);
hFunc(NSysView::TEvSysView::TEvGetTabletsRequest, Handle);
- default:
- if (!HandleDefaultEvents(ev, ctx)) {
- BLOG_W("THive::StateWork unhandled event type: " << ev->GetTypeRewrite()
- << " event: " << (ev->HasEvent() ? ev->GetBase()->ToString().data() : "serialized?"));
- }
- break;
- }
-}
-
-void THive::KickTablet(const TTabletInfo& tablet) {
+ default:
+ if (!HandleDefaultEvents(ev, ctx)) {
+ BLOG_W("THive::StateWork unhandled event type: " << ev->GetTypeRewrite()
+ << " event: " << (ev->HasEvent() ? ev->GetBase()->ToString().data() : "serialized?"));
+ }
+ break;
+ }
+}
+
+void THive::KickTablet(const TTabletInfo& tablet) {
Send(SelfId(), new TEvPrivate::TEvKickTablet(tablet));
-}
-
+}
+
void THive::StopTablet(const TActorId& local, const TTabletInfo& tablet) {
- BLOG_D("Sending TEvStopTablet(" << tablet.ToString() << ") to node " << local.NodeId());
- Send(local, new TEvLocal::TEvStopTablet(tablet.GetFullTabletId()));
-}
-
+ BLOG_D("Sending TEvStopTablet(" << tablet.ToString() << ") to node " << local.NodeId());
+ Send(local, new TEvLocal::TEvStopTablet(tablet.GetFullTabletId()));
+}
+
void THive::StopTablet(const TActorId& local, TFullTabletId tabletId) {
- BLOG_D("Sending TEvStopTablet(" << tabletId << ") to node " << local.NodeId());
- Send(local, new TEvLocal::TEvStopTablet(tabletId));
-}
-
-void THive::Handle(TEvHive::TEvRequestTabletIdSequence::TPtr& ev) {
- Execute(CreateRequestTabletSequence(std::move(ev)));
-}
-
-void THive::Handle(TEvHive::TEvResponseTabletIdSequence::TPtr& ev) {
- Execute(CreateResponseTabletSequence(std::move(ev)));
-}
-
-void THive::RequestFreeSequence() {
- TIntrusivePtr<TDomainsInfo> domains = AppData()->DomainsInfo;
- TIntrusivePtr<TDomainsInfo::TDomain> domain = domains->Domains.begin()->second;
- TTabletId rootHiveId = domains->GetHive(domain->DefaultHiveUid);
- if (rootHiveId != TabletID()) {
- size_t sequenceIndex = Sequencer.NextFreeSequenceIndex();
- size_t sequenceSize = GetRequestSequenceSize();
-
- BLOG_D("Requesting free sequence #" << sequenceIndex << " of " << sequenceSize << " from root hive");
- SendToRootHivePipe(new TEvHive::TEvRequestTabletIdSequence(TabletID(), sequenceIndex, sequenceSize));
- RequestingSequenceNow = true;
- RequestingSequenceIndex = sequenceIndex;
- } else {
- BLOG_ERROR("We run out of tablet ids");
- }
-}
-
-void THive::ProcessPendingOperations() {
- Execute(CreateProcessPendingOperations());
-}
-
-void THive::Handle(TEvSubDomain::TEvConfigure::TPtr& ev) {
- BLOG_D("Handle TEvSubDomain::TEvConfigure(" << ev->Get()->Record.ShortDebugString() << ")");
- Send(ev->Sender, new TEvSubDomain::TEvConfigureStatus(NKikimrTx::TEvSubDomainConfigurationAck::SUCCESS, TabletID()));
-}
-
-void THive::Handle(TEvHive::TEvConfigureHive::TPtr& ev) {
- BLOG_D("Handle TEvHive::TEvConfigureHive(" << ev->Get()->Record.ShortDebugString() << ")");
- Execute(CreateConfigureSubdomain(std::move(ev)));
-}
-
-
+ BLOG_D("Sending TEvStopTablet(" << tabletId << ") to node " << local.NodeId());
+ Send(local, new TEvLocal::TEvStopTablet(tabletId));
+}
+
+void THive::Handle(TEvHive::TEvRequestTabletIdSequence::TPtr& ev) {
+ Execute(CreateRequestTabletSequence(std::move(ev)));
+}
+
+void THive::Handle(TEvHive::TEvResponseTabletIdSequence::TPtr& ev) {
+ Execute(CreateResponseTabletSequence(std::move(ev)));
+}
+
+void THive::RequestFreeSequence() {
+ TIntrusivePtr<TDomainsInfo> domains = AppData()->DomainsInfo;
+ TIntrusivePtr<TDomainsInfo::TDomain> domain = domains->Domains.begin()->second;
+ TTabletId rootHiveId = domains->GetHive(domain->DefaultHiveUid);
+ if (rootHiveId != TabletID()) {
+ size_t sequenceIndex = Sequencer.NextFreeSequenceIndex();
+ size_t sequenceSize = GetRequestSequenceSize();
+
+ BLOG_D("Requesting free sequence #" << sequenceIndex << " of " << sequenceSize << " from root hive");
+ SendToRootHivePipe(new TEvHive::TEvRequestTabletIdSequence(TabletID(), sequenceIndex, sequenceSize));
+ RequestingSequenceNow = true;
+ RequestingSequenceIndex = sequenceIndex;
+ } else {
+ BLOG_ERROR("We run out of tablet ids");
+ }
+}
+
+void THive::ProcessPendingOperations() {
+ Execute(CreateProcessPendingOperations());
+}
+
+void THive::Handle(TEvSubDomain::TEvConfigure::TPtr& ev) {
+ BLOG_D("Handle TEvSubDomain::TEvConfigure(" << ev->Get()->Record.ShortDebugString() << ")");
+ Send(ev->Sender, new TEvSubDomain::TEvConfigureStatus(NKikimrTx::TEvSubDomainConfigurationAck::SUCCESS, TabletID()));
+}
+
+void THive::Handle(TEvHive::TEvConfigureHive::TPtr& ev) {
+ BLOG_D("Handle TEvHive::TEvConfigureHive(" << ev->Get()->Record.ShortDebugString() << ")");
+ Execute(CreateConfigureSubdomain(std::move(ev)));
+}
+
+
void THive::Handle(NSysView::TEvSysView::TEvGetTabletIdsRequest::TPtr& ev) {
const auto& request = ev->Get()->Record;
auto fromId = request.GetFrom();
@@ -2470,162 +2470,162 @@ void THive::Handle(NSysView::TEvSysView::TEvGetTabletsRequest::TPtr& ev) {
Send(ev->Sender, response.Release());
}
-const TTabletMetricsAggregates& THive::GetDefaultResourceMetricsAggregates() const {
- return DefaultResourceMetricsAggregates;
-}
-
-bool THive::CheckForForwardTabletRequest(TTabletId tabletId, NKikimrHive::TForwardRequest& forwardRequest) {
+const TTabletMetricsAggregates& THive::GetDefaultResourceMetricsAggregates() const {
+ return DefaultResourceMetricsAggregates;
+}
+
+bool THive::CheckForForwardTabletRequest(TTabletId tabletId, NKikimrHive::TForwardRequest& forwardRequest) {
const TLeaderTabletInfo* tablet = FindTablet(tabletId);
- if (tablet == nullptr) {
- TOwnershipKeeper::TOwnerType owner = Keeper.GetOwner(UniqPartFromTabletID(tabletId));
- if (owner == TSequencer::NO_OWNER && AreWeSubDomainHive()) {
- owner = RootHiveId;
- }
- if (owner != TSequencer::NO_OWNER && owner != TabletID()) {
- BLOG_NOTICE("Forwarding TabletRequest(TabletID " << tabletId << ") to Hive " << owner);
- forwardRequest.SetHiveTabletId(owner);
- return true;
- }
- }
- return false;
-}
-
-TSubDomainKey THive::GetRootDomainKey() const {
- return RootDomainKey;
-}
-
-TSubDomainKey THive::GetMySubDomainKey() const {
- if (AreWeRootHive()) {
- return GetRootDomainKey();
- }
- if (PrimaryDomainKey) {
- return PrimaryDomainKey;
- }
- if (Domains.size() == 1) {
- // not very straight way to get our domain key
- return Domains.begin()->first;
- }
- if (!Tablets.empty()) {
- std::unordered_set<TSubDomainKey> objectDomains;
- for (const auto& [id, tablet] : Tablets) {
- objectDomains.insert(tablet.ObjectDomain);
- }
- if (objectDomains.size() == 1) {
- BLOG_W("GetMySubDomainKey() - guessed PrimaryDomainKey to " << *objectDomains.begin());
- return *objectDomains.begin();
- } else {
- BLOG_W("GetMySubDomainKey() - couldn't guess PrimaryDomainKey: " << objectDomains.size() << " object domains found");
- }
- }
- return {};
-}
-
-void THive::Handle(TEvHive::TEvSeizeTablets::TPtr& ev) {
- BLOG_D("Handle TEvHive::TEvSeizeTablets(" << ev->Get()->Record.ShortDebugString() << ")");
- Execute(CreateSeizeTablets(ev));
-}
-
-void THive::Handle(TEvHive::TEvSeizeTabletsReply::TPtr& ev) {
- BLOG_D("Handle TEvHive::TEvSeizeTabletsReply(" << ev->Get()->Record.ShortDebugString() << ")");
- Execute(CreateSeizeTabletsReply(ev));
-}
-
-void THive::Handle(TEvHive::TEvReleaseTablets::TPtr& ev) {
- BLOG_D("Handle TEvHive::TEvReleaseTablets(" << ev->Get()->Record.ShortDebugString() << ")");
- Execute(CreateReleaseTablets(ev));
-}
-
-void THive::Handle(TEvHive::TEvReleaseTabletsReply::TPtr& ev) {
- BLOG_D("Handle TEvHive::TEvReleaseTabletsReply(" << ev->Get()->Record.ShortDebugString() << ")");
- Execute(CreateReleaseTabletsReply(ev));
-}
-
-TVector<TNodeId> THive::GetNodesForWhiteboardBroadcast(size_t maxNodesToReturn) {
- TVector<TNodeId> nodes;
- TNodeId selfNodeId = SelfId().NodeId();
- nodes.emplace_back(selfNodeId);
- for (const auto& [nodeId, nodeInfo] : Nodes) {
- if (nodes.size() >= maxNodesToReturn) {
- break;
- }
- if (nodeId != selfNodeId && nodeInfo.IsAlive()) {
- nodes.emplace_back(nodeId);
- }
- }
- return nodes;
-}
-
+ if (tablet == nullptr) {
+ TOwnershipKeeper::TOwnerType owner = Keeper.GetOwner(UniqPartFromTabletID(tabletId));
+ if (owner == TSequencer::NO_OWNER && AreWeSubDomainHive()) {
+ owner = RootHiveId;
+ }
+ if (owner != TSequencer::NO_OWNER && owner != TabletID()) {
+ BLOG_NOTICE("Forwarding TabletRequest(TabletID " << tabletId << ") to Hive " << owner);
+ forwardRequest.SetHiveTabletId(owner);
+ return true;
+ }
+ }
+ return false;
+}
+
+TSubDomainKey THive::GetRootDomainKey() const {
+ return RootDomainKey;
+}
+
+TSubDomainKey THive::GetMySubDomainKey() const {
+ if (AreWeRootHive()) {
+ return GetRootDomainKey();
+ }
+ if (PrimaryDomainKey) {
+ return PrimaryDomainKey;
+ }
+ if (Domains.size() == 1) {
+ // not very straight way to get our domain key
+ return Domains.begin()->first;
+ }
+ if (!Tablets.empty()) {
+ std::unordered_set<TSubDomainKey> objectDomains;
+ for (const auto& [id, tablet] : Tablets) {
+ objectDomains.insert(tablet.ObjectDomain);
+ }
+ if (objectDomains.size() == 1) {
+ BLOG_W("GetMySubDomainKey() - guessed PrimaryDomainKey to " << *objectDomains.begin());
+ return *objectDomains.begin();
+ } else {
+ BLOG_W("GetMySubDomainKey() - couldn't guess PrimaryDomainKey: " << objectDomains.size() << " object domains found");
+ }
+ }
+ return {};
+}
+
+void THive::Handle(TEvHive::TEvSeizeTablets::TPtr& ev) {
+ BLOG_D("Handle TEvHive::TEvSeizeTablets(" << ev->Get()->Record.ShortDebugString() << ")");
+ Execute(CreateSeizeTablets(ev));
+}
+
+void THive::Handle(TEvHive::TEvSeizeTabletsReply::TPtr& ev) {
+ BLOG_D("Handle TEvHive::TEvSeizeTabletsReply(" << ev->Get()->Record.ShortDebugString() << ")");
+ Execute(CreateSeizeTabletsReply(ev));
+}
+
+void THive::Handle(TEvHive::TEvReleaseTablets::TPtr& ev) {
+ BLOG_D("Handle TEvHive::TEvReleaseTablets(" << ev->Get()->Record.ShortDebugString() << ")");
+ Execute(CreateReleaseTablets(ev));
+}
+
+void THive::Handle(TEvHive::TEvReleaseTabletsReply::TPtr& ev) {
+ BLOG_D("Handle TEvHive::TEvReleaseTabletsReply(" << ev->Get()->Record.ShortDebugString() << ")");
+ Execute(CreateReleaseTabletsReply(ev));
+}
+
+TVector<TNodeId> THive::GetNodesForWhiteboardBroadcast(size_t maxNodesToReturn) {
+ TVector<TNodeId> nodes;
+ TNodeId selfNodeId = SelfId().NodeId();
+ nodes.emplace_back(selfNodeId);
+ for (const auto& [nodeId, nodeInfo] : Nodes) {
+ if (nodes.size() >= maxNodesToReturn) {
+ break;
+ }
+ if (nodeId != selfNodeId && nodeInfo.IsAlive()) {
+ nodes.emplace_back(nodeId);
+ }
+ }
+ return nodes;
+}
+
void THive::ReportStoppedToWhiteboard(const TLeaderTabletInfo& tablet) {
- ReportTabletStateToWhiteboard(tablet, NKikimrWhiteboard::TTabletStateInfo::Stopped);
-}
-
+ ReportTabletStateToWhiteboard(tablet, NKikimrWhiteboard::TTabletStateInfo::Stopped);
+}
+
void THive::ReportDeletedToWhiteboard(const TLeaderTabletInfo& tablet) {
- ReportTabletStateToWhiteboard(tablet, NKikimrWhiteboard::TTabletStateInfo::Deleted);
-}
-
+ ReportTabletStateToWhiteboard(tablet, NKikimrWhiteboard::TTabletStateInfo::Deleted);
+}
+
void THive::ReportTabletStateToWhiteboard(const TLeaderTabletInfo& tablet, NKikimrWhiteboard::TTabletStateInfo::ETabletState state) {
- ui32 generation = state == NKikimrWhiteboard::TTabletStateInfo::Deleted ? std::numeric_limits<ui32>::max() : tablet.KnownGeneration;
- TPathId pathId = tablet.GetTenant();
- TSubDomainKey tenantId(pathId.OwnerId, pathId.LocalPathId);
- for (TNodeId nodeId : GetNodesForWhiteboardBroadcast()) {
- TActorId whiteboardId = NNodeWhiteboard::MakeNodeWhiteboardServiceId(nodeId);
- THolder<NNodeWhiteboard::TEvWhiteboard::TEvTabletStateUpdate> event = MakeHolder<NNodeWhiteboard::TEvWhiteboard::TEvTabletStateUpdate>();
- event->Record.SetTabletId(tablet.Id);
- event->Record.SetType(tablet.Type);
+ ui32 generation = state == NKikimrWhiteboard::TTabletStateInfo::Deleted ? std::numeric_limits<ui32>::max() : tablet.KnownGeneration;
+ TPathId pathId = tablet.GetTenant();
+ TSubDomainKey tenantId(pathId.OwnerId, pathId.LocalPathId);
+ for (TNodeId nodeId : GetNodesForWhiteboardBroadcast()) {
+ TActorId whiteboardId = NNodeWhiteboard::MakeNodeWhiteboardServiceId(nodeId);
+ THolder<NNodeWhiteboard::TEvWhiteboard::TEvTabletStateUpdate> event = MakeHolder<NNodeWhiteboard::TEvWhiteboard::TEvTabletStateUpdate>();
+ event->Record.SetTabletId(tablet.Id);
+ event->Record.SetType(tablet.Type);
event->Record.SetLeader(true);
- event->Record.SetGeneration(generation);
- event->Record.SetState(state);
- event->Record.SetHiveId(TabletID());
- event->Record.MutableTenantId()->CopyFrom(tenantId);
- Send(whiteboardId, event.Release());
+ event->Record.SetGeneration(generation);
+ event->Record.SetState(state);
+ event->Record.SetHiveId(TabletID());
+ event->Record.MutableTenantId()->CopyFrom(tenantId);
+ Send(whiteboardId, event.Release());
for (const TFollowerTabletInfo& follower : tablet.Followers) {
- THolder<NNodeWhiteboard::TEvWhiteboard::TEvTabletStateUpdate> event = MakeHolder<NNodeWhiteboard::TEvWhiteboard::TEvTabletStateUpdate>();
+ THolder<NNodeWhiteboard::TEvWhiteboard::TEvTabletStateUpdate> event = MakeHolder<NNodeWhiteboard::TEvWhiteboard::TEvTabletStateUpdate>();
event->Record.SetTabletId(follower.LeaderTablet.Id);
event->Record.SetFollowerId(follower.Id);
- event->Record.SetType(tablet.Type);
- event->Record.SetGeneration(generation);
- event->Record.SetState(state);
- event->Record.SetHiveId(TabletID());
- event->Record.MutableTenantId()->CopyFrom(tenantId);
- Send(whiteboardId, event.Release());
- }
- }
-}
-
-void THive::ActualizeRestartStatistics(google::protobuf::RepeatedField<google::protobuf::uint64>& array, ui64 barrier) {
- static constexpr decltype(array.size()) MAX_RESTARTS_PER_PERIOD = 128;
- auto begin = array.begin();
- auto end = array.end();
- auto it = begin;
- if (array.size() > MAX_RESTARTS_PER_PERIOD) {
- it = end - MAX_RESTARTS_PER_PERIOD;
- }
- while (it != end && *it < barrier) {
- ++it;
- }
- array.erase(begin, it);
-}
-
-bool THive::IsSystemTablet(TTabletTypes::EType type) {
- switch (type) {
- case TTabletTypes::Coordinator:
- case TTabletTypes::Mediator:
- case TTabletTypes::TxAllocator:
- //case TTabletTypes::SchemeShard:
- return true;
- default:
- return false;
- }
-}
-
-TString THive::GetLogPrefix() const {
- return TStringBuilder() << "HIVE#" << TabletID() << " ";
-}
-
-} // NHive
-
+ event->Record.SetType(tablet.Type);
+ event->Record.SetGeneration(generation);
+ event->Record.SetState(state);
+ event->Record.SetHiveId(TabletID());
+ event->Record.MutableTenantId()->CopyFrom(tenantId);
+ Send(whiteboardId, event.Release());
+ }
+ }
+}
+
+void THive::ActualizeRestartStatistics(google::protobuf::RepeatedField<google::protobuf::uint64>& array, ui64 barrier) {
+ static constexpr decltype(array.size()) MAX_RESTARTS_PER_PERIOD = 128;
+ auto begin = array.begin();
+ auto end = array.end();
+ auto it = begin;
+ if (array.size() > MAX_RESTARTS_PER_PERIOD) {
+ it = end - MAX_RESTARTS_PER_PERIOD;
+ }
+ while (it != end && *it < barrier) {
+ ++it;
+ }
+ array.erase(begin, it);
+}
+
+bool THive::IsSystemTablet(TTabletTypes::EType type) {
+ switch (type) {
+ case TTabletTypes::Coordinator:
+ case TTabletTypes::Mediator:
+ case TTabletTypes::TxAllocator:
+ //case TTabletTypes::SchemeShard:
+ return true;
+ default:
+ return false;
+ }
+}
+
+TString THive::GetLogPrefix() const {
+ return TStringBuilder() << "HIVE#" << TabletID() << " ";
+}
+
+} // NHive
+
IActor* CreateDefaultHive(const TActorId &tablet, TTabletStorageInfo *info) {
- return new NHive::THive(info, tablet);
+ return new NHive::THive(info, tablet);
}
-} // NKikimr
+} // NKikimr
diff --git a/ydb/core/mind/hive/hive_impl.h b/ydb/core/mind/hive/hive_impl.h
index a64ff287be1..70c4530fee0 100644
--- a/ydb/core/mind/hive/hive_impl.h
+++ b/ydb/core/mind/hive/hive_impl.h
@@ -1,5 +1,5 @@
#pragma once
-#include <bitset>
+#include <bitset>
#include <library/cpp/actors/core/interconnect.h>
#include <ydb/core/base/hive.h>
#include <ydb/core/base/statestorage.h>
@@ -27,480 +27,480 @@
#include <ydb/core/sys_view/common/events.h>
#include <ydb/core/cms/console/console.h>
#include <ydb/core/cms/console/configs_dispatcher.h>
-
+
#include <library/cpp/actors/core/interconnect.h>
#include <library/cpp/actors/core/hfunc.h>
-
-#include <util/generic/queue.h>
-#include <util/random/random.h>
-
+
+#include <util/generic/queue.h>
+#include <util/random/random.h>
+
#include <ydb/core/tablet/tablet_metrics.h>
-
-#include "hive.h"
-#include "hive_transactions.h"
-#include "hive_events.h"
-#include "hive_domains.h"
-#include "hive_schema.h"
-#include "domain_info.h"
-#include "tablet_info.h"
+
+#include "hive.h"
+#include "hive_transactions.h"
+#include "hive_events.h"
+#include "hive_domains.h"
+#include "hive_schema.h"
+#include "domain_info.h"
+#include "tablet_info.h"
#include "leader_tablet_info.h"
#include "follower_tablet_info.h"
#include "follower_group.h"
-#include "node_info.h"
-#include "storage_group_info.h"
-#include "storage_pool_info.h"
-#include "sequencer.h"
-#include "boot_queue.h"
-
+#include "node_info.h"
+#include "storage_group_info.h"
+#include "storage_pool_info.h"
+#include "sequencer.h"
+#include "boot_queue.h"
+
#define DEPRECATED_CTX (TlsActivationContext->ActorContextFor(SelfId()))
-#define DEPRECATED_NOW (TActivationContext::Now())
-
-template <typename T>
-inline IOutputStream& operator <<(IOutputStream& out, const TVector<T>& vec) {
- out << '[';
- for (auto it = vec.begin(); it != vec.end(); ++it) {
- if (it != vec.begin())
- out << ',';
- out << *it;
- }
- out << ']';
- return out;
-}
-
-template <typename T>
-inline IOutputStream& operator <<(IOutputStream& out, const std::vector<T>& vec) {
- out << '[';
- for (auto it = vec.begin(); it != vec.end(); ++it) {
- if (it != vec.begin())
- out << ',';
- out << *it;
- }
- out << ']';
- return out;
-}
-
-template <size_t I>
-inline IOutputStream& operator <<(IOutputStream& out, const std::bitset<I>& vec) {
- out << '[';
- size_t bits = 0;
- for (size_t i = 0; i < I; ++i) {
- if (vec.test(i)) {
- if (bits > 0) {
- out << ',';
- }
- out << i;
- ++bits;
- }
- }
- out << ']';
- return out;
-}
-
-inline IOutputStream& operator <<(IOutputStream& out, std::pair<ui64, ui64> pr) {
- return out << std::tuple<ui64, ui64>(pr);
-}
-
-inline IOutputStream& operator <<(IOutputStream& out, NKikimr::NHive::TSequencer::TSequence sq) {
- return out << sq.Next << "@[" << sq.Begin << ".." << sq.End << ')';
-}
-
-namespace std {
- template <>
- struct hash<NKikimr::TSubDomainKey> {
- std::size_t operator()(const NKikimr::TSubDomainKey& key) const {
- return key.Hash();
- }
- };
-}
-
+#define DEPRECATED_NOW (TActivationContext::Now())
+
+template <typename T>
+inline IOutputStream& operator <<(IOutputStream& out, const TVector<T>& vec) {
+ out << '[';
+ for (auto it = vec.begin(); it != vec.end(); ++it) {
+ if (it != vec.begin())
+ out << ',';
+ out << *it;
+ }
+ out << ']';
+ return out;
+}
+
+template <typename T>
+inline IOutputStream& operator <<(IOutputStream& out, const std::vector<T>& vec) {
+ out << '[';
+ for (auto it = vec.begin(); it != vec.end(); ++it) {
+ if (it != vec.begin())
+ out << ',';
+ out << *it;
+ }
+ out << ']';
+ return out;
+}
+
+template <size_t I>
+inline IOutputStream& operator <<(IOutputStream& out, const std::bitset<I>& vec) {
+ out << '[';
+ size_t bits = 0;
+ for (size_t i = 0; i < I; ++i) {
+ if (vec.test(i)) {
+ if (bits > 0) {
+ out << ',';
+ }
+ out << i;
+ ++bits;
+ }
+ }
+ out << ']';
+ return out;
+}
+
+inline IOutputStream& operator <<(IOutputStream& out, std::pair<ui64, ui64> pr) {
+ return out << std::tuple<ui64, ui64>(pr);
+}
+
+inline IOutputStream& operator <<(IOutputStream& out, NKikimr::NHive::TSequencer::TSequence sq) {
+ return out << sq.Next << "@[" << sq.Begin << ".." << sq.End << ')';
+}
+
+namespace std {
+ template <>
+ struct hash<NKikimr::TSubDomainKey> {
+ std::size_t operator()(const NKikimr::TSubDomainKey& key) const {
+ return key.Hash();
+ }
+ };
+}
+
namespace NKikimr {
-namespace NHive {
+namespace NHive {
-struct TCompleteNotifications {
- TVector<THolder<IEventHandle>> Notifications;
+struct TCompleteNotifications {
+ TVector<THolder<IEventHandle>> Notifications;
TActorId SelfID;
-
+
void Reset(const TActorId &selfId) {
- Notifications.clear();
- SelfID = selfId;
- }
-
+ Notifications.clear();
+ SelfID = selfId;
+ }
+
void Send(const TActorId &recipient, IEventBase *ev, ui32 flags = 0, ui64 cookie = 0) {
- Notifications.emplace_back(new IEventHandle(recipient, SelfID, ev, flags, cookie));
- }
-
- void Send(const TActorContext& ctx) {
- for (auto& notification : Notifications) {
- ctx.ExecutorThread.Send(notification.Release());
- }
- }
-
- size_t size() const {
- return Notifications.size();
- }
-};
-
-TResourceRawValues ResourceRawValuesFromMetrics(const NKikimrTabletBase::TMetrics& metrics);
-NKikimrTabletBase::TMetrics MetricsFromResourceRawValues(const TResourceRawValues& values);
-TResourceRawValues ResourceRawValuesFromMetrics(const NKikimrHive::TTabletMetrics& tabletMetrics);
-TString GetResourceValuesText(const NKikimrTabletBase::TMetrics& values);
-TString GetResourceValuesText(const TTabletInfo& tablet);
-TString GetResourceValuesText(const TResourceRawValues& values);
-TString GetResourceValuesText(const TResourceNormalizedValues& values);
-TString GetResourceValuesHtml(const TResourceRawValues& values);
-NJson::TJsonValue GetResourceValuesJson(const TResourceRawValues& values);
-NJson::TJsonValue GetResourceValuesJson(const TResourceRawValues& values, const TResourceRawValues& maximum);
-TString GetResourceValuesHtml(const NKikimrTabletBase::TMetrics& values);
-NJson::TJsonValue GetResourceValuesJson(const NKikimrTabletBase::TMetrics& values);
-ui64 GetReadThroughput(const NKikimrTabletBase::TMetrics& values);
-ui64 GetWriteThroughput(const NKikimrTabletBase::TMetrics& values);
-TString GetCounter(ui64 counter, const TString& zero = "0");
-TString GetBytes(ui64 bytes, const TString& zero = "0B");
-TString GetBytesPerSecond(ui64 bytes, const TString& zero = "0B/s");
-TString GetTimes(ui64 times, const TString& zero = "0.00%");
-TString GetConditionalGreyString(const TString& str, bool condition);
-TString GetConditionalBoldString(const TString& str, bool condition);
-TString GetConditionalRedString(const TString& str, bool condition);
-TString GetDataCenterName(ui64 dataCenterId);
-TString LongToShortTabletName(const TString& longTabletName);
-TString GetLocationString(const NActors::TNodeLocation& location);
-
-class THive : public TActor<THive>, public TTabletExecutedFlat, public THiveSharedSettings {
-public:
- using IActorOps::Register;
-
-protected:
- friend class THiveBalancer;
- friend class THiveDrain;
- friend class THiveFill;
- friend class TReassignTabletWaitActor;
- friend class TStopTabletWaitActor;
- friend class TResumeTabletWaitActor;
- friend class TInitMigrationWaitActor;
- friend class TQueryMigrationWaitActor;
- friend class TReleaseTabletsWaitActor;
- friend class TDrainNodeWaitActor;
-
- friend class TTxInitScheme;
- friend class TTxDeleteTablet;
+ Notifications.emplace_back(new IEventHandle(recipient, SelfID, ev, flags, cookie));
+ }
+
+ void Send(const TActorContext& ctx) {
+ for (auto& notification : Notifications) {
+ ctx.ExecutorThread.Send(notification.Release());
+ }
+ }
+
+ size_t size() const {
+ return Notifications.size();
+ }
+};
+
+TResourceRawValues ResourceRawValuesFromMetrics(const NKikimrTabletBase::TMetrics& metrics);
+NKikimrTabletBase::TMetrics MetricsFromResourceRawValues(const TResourceRawValues& values);
+TResourceRawValues ResourceRawValuesFromMetrics(const NKikimrHive::TTabletMetrics& tabletMetrics);
+TString GetResourceValuesText(const NKikimrTabletBase::TMetrics& values);
+TString GetResourceValuesText(const TTabletInfo& tablet);
+TString GetResourceValuesText(const TResourceRawValues& values);
+TString GetResourceValuesText(const TResourceNormalizedValues& values);
+TString GetResourceValuesHtml(const TResourceRawValues& values);
+NJson::TJsonValue GetResourceValuesJson(const TResourceRawValues& values);
+NJson::TJsonValue GetResourceValuesJson(const TResourceRawValues& values, const TResourceRawValues& maximum);
+TString GetResourceValuesHtml(const NKikimrTabletBase::TMetrics& values);
+NJson::TJsonValue GetResourceValuesJson(const NKikimrTabletBase::TMetrics& values);
+ui64 GetReadThroughput(const NKikimrTabletBase::TMetrics& values);
+ui64 GetWriteThroughput(const NKikimrTabletBase::TMetrics& values);
+TString GetCounter(ui64 counter, const TString& zero = "0");
+TString GetBytes(ui64 bytes, const TString& zero = "0B");
+TString GetBytesPerSecond(ui64 bytes, const TString& zero = "0B/s");
+TString GetTimes(ui64 times, const TString& zero = "0.00%");
+TString GetConditionalGreyString(const TString& str, bool condition);
+TString GetConditionalBoldString(const TString& str, bool condition);
+TString GetConditionalRedString(const TString& str, bool condition);
+TString GetDataCenterName(ui64 dataCenterId);
+TString LongToShortTabletName(const TString& longTabletName);
+TString GetLocationString(const NActors::TNodeLocation& location);
+
+class THive : public TActor<THive>, public TTabletExecutedFlat, public THiveSharedSettings {
+public:
+ using IActorOps::Register;
+
+protected:
+ friend class THiveBalancer;
+ friend class THiveDrain;
+ friend class THiveFill;
+ friend class TReassignTabletWaitActor;
+ friend class TStopTabletWaitActor;
+ friend class TResumeTabletWaitActor;
+ friend class TInitMigrationWaitActor;
+ friend class TQueryMigrationWaitActor;
+ friend class TReleaseTabletsWaitActor;
+ friend class TDrainNodeWaitActor;
+
+ friend class TTxInitScheme;
+ friend class TTxDeleteTablet;
friend class TTxDeleteOwnerTablets;
- friend class TTxReassignGroups;
- friend class TTxStartTablet;
- friend class TTxCreateTablet;
- friend class TTxCutTabletHistory;
- friend class TTxBlockStorageResult;
- friend class TTxAdoptTablet;
- friend class TTxDeleteTabletResult;
- friend class TTxMonEvent_MemStateTablets;
- friend class TTxMonEvent_MemStateNodes;
- friend class TTxMonEvent_MemStateDomains;
- friend class TTxMonEvent_Resources;
- friend class TTxMonEvent_Settings;
- friend class TTxMonEvent_Landing;
- friend class TTxMonEvent_LandingData;
- friend class TTxMonEvent_SetDown;
- friend class TTxMonEvent_SetFreeze;
- friend class TTxMonEvent_KickNode;
- friend class TTxMonEvent_DrainNode;
- friend class TTxMonEvent_Rebalance;
- friend class TTxMonEvent_Storage;
- friend class TTxMonEvent_FindTablet;
- friend class TTxMonEvent_StopTablet;
- friend class TTxMonEvent_ResumeTablet;
- friend class TTxMonEvent_InitMigration;
- friend class TTxMonEvent_QueryMigration;
- friend class TTxKillNode;
- friend class TTxLoadEverything;
- friend class TTxRestartTablet;
- friend class TTxLockTabletExecution;
- friend class TTxMonEvent_ReassignTablet;
- friend class TTxRegisterNode;
- friend class TTxSyncTablets;
- friend class TTxRequestTabletSequence;
- friend class TTxResponseTabletSequence;
- friend class TTxDisconnectNode;
- friend class TTxProcessPendingOperations;
- friend class TTxStopTablet;
- friend class TTxResumeTablet;
- friend class TTxUpdateTabletStatus;
- friend class TTxUpdateTabletMetrics;
- friend class TTxSeizeTablets;
- friend class TTxSeizeTabletsReply;
- friend class TTxReleaseTablets;
- friend class TTxReleaseTabletsReply;
- friend class TTxConfigureSubdomain;
- friend class TTxStatus;
- friend class TTxSwitchDrainOn;
- friend class TTxSwitchDrainOff;
-
- friend class TDeleteTabletActor;
-
- friend struct TStoragePoolInfo;
-
- void StartHiveBalancer(int maxMovements = 0, bool recheckOnFinish = false, const std::vector<TNodeId>& filterNodeIds = {});
- void StartHiveDrain(TNodeId nodeId, TDrainSettings settings);
+ friend class TTxReassignGroups;
+ friend class TTxStartTablet;
+ friend class TTxCreateTablet;
+ friend class TTxCutTabletHistory;
+ friend class TTxBlockStorageResult;
+ friend class TTxAdoptTablet;
+ friend class TTxDeleteTabletResult;
+ friend class TTxMonEvent_MemStateTablets;
+ friend class TTxMonEvent_MemStateNodes;
+ friend class TTxMonEvent_MemStateDomains;
+ friend class TTxMonEvent_Resources;
+ friend class TTxMonEvent_Settings;
+ friend class TTxMonEvent_Landing;
+ friend class TTxMonEvent_LandingData;
+ friend class TTxMonEvent_SetDown;
+ friend class TTxMonEvent_SetFreeze;
+ friend class TTxMonEvent_KickNode;
+ friend class TTxMonEvent_DrainNode;
+ friend class TTxMonEvent_Rebalance;
+ friend class TTxMonEvent_Storage;
+ friend class TTxMonEvent_FindTablet;
+ friend class TTxMonEvent_StopTablet;
+ friend class TTxMonEvent_ResumeTablet;
+ friend class TTxMonEvent_InitMigration;
+ friend class TTxMonEvent_QueryMigration;
+ friend class TTxKillNode;
+ friend class TTxLoadEverything;
+ friend class TTxRestartTablet;
+ friend class TTxLockTabletExecution;
+ friend class TTxMonEvent_ReassignTablet;
+ friend class TTxRegisterNode;
+ friend class TTxSyncTablets;
+ friend class TTxRequestTabletSequence;
+ friend class TTxResponseTabletSequence;
+ friend class TTxDisconnectNode;
+ friend class TTxProcessPendingOperations;
+ friend class TTxStopTablet;
+ friend class TTxResumeTablet;
+ friend class TTxUpdateTabletStatus;
+ friend class TTxUpdateTabletMetrics;
+ friend class TTxSeizeTablets;
+ friend class TTxSeizeTabletsReply;
+ friend class TTxReleaseTablets;
+ friend class TTxReleaseTabletsReply;
+ friend class TTxConfigureSubdomain;
+ friend class TTxStatus;
+ friend class TTxSwitchDrainOn;
+ friend class TTxSwitchDrainOff;
+
+ friend class TDeleteTabletActor;
+
+ friend struct TStoragePoolInfo;
+
+ void StartHiveBalancer(int maxMovements = 0, bool recheckOnFinish = false, const std::vector<TNodeId>& filterNodeIds = {});
+ void StartHiveDrain(TNodeId nodeId, TDrainSettings settings);
void StartHiveFill(TNodeId nodeId, const TActorId& initiator);
- void CreateEvMonitoring(NMon::TEvRemoteHttpInfo::TPtr& ev, const TActorContext& ctx);
- ITransaction* CreateDeleteTablet(TEvHive::TEvDeleteTablet::TPtr& ev);
+ void CreateEvMonitoring(NMon::TEvRemoteHttpInfo::TPtr& ev, const TActorContext& ctx);
+ ITransaction* CreateDeleteTablet(TEvHive::TEvDeleteTablet::TPtr& ev);
ITransaction* CreateDeleteOwnerTablets(TEvHive::TEvDeleteOwnerTablets::TPtr& ev);
- ITransaction* CreateDeleteTabletResult(TEvTabletBase::TEvDeleteTabletResult::TPtr& ev);
- ITransaction* CreateCutTabletHistory(TEvHive::TEvCutTabletHistory::TPtr& ev);
- ITransaction* CreateBlockStorageResult(TEvTabletBase::TEvBlockBlobStorageResult::TPtr& ev);
- ITransaction* CreateRestartTablet(TFullTabletId tabletId);
- ITransaction* CreateRestartTablet(TFullTabletId tabletId, TNodeId preferredNodeId);
- ITransaction* CreateInitScheme();
+ ITransaction* CreateDeleteTabletResult(TEvTabletBase::TEvDeleteTabletResult::TPtr& ev);
+ ITransaction* CreateCutTabletHistory(TEvHive::TEvCutTabletHistory::TPtr& ev);
+ ITransaction* CreateBlockStorageResult(TEvTabletBase::TEvBlockBlobStorageResult::TPtr& ev);
+ ITransaction* CreateRestartTablet(TFullTabletId tabletId);
+ ITransaction* CreateRestartTablet(TFullTabletId tabletId, TNodeId preferredNodeId);
+ ITransaction* CreateInitScheme();
ITransaction* CreateAdoptTablet(NKikimrHive::TEvAdoptTablet &rec, const TActorId &sender, const ui64 cookie);
ITransaction* CreateCreateTablet(NKikimrHive::TEvCreateTablet rec, const TActorId& sender, const ui64 cookie);
- ITransaction* CreateLoadEverything();
+ ITransaction* CreateLoadEverything();
ITransaction* CreateRegisterNode(const TActorId& local, NKikimrLocal::TEvRegisterNode rec);
ITransaction* CreateStatus(const TActorId& local, NKikimrLocal::TEvStatus rec);
- ITransaction* CreateUpdateTabletStatus(TTabletId tabletId,
- const TActorId &local,
- ui32 generation,
- TFollowerId followerId,
- TEvLocal::TEvTabletStatus::EStatus status,
- TEvTablet::TEvTabletDead::EReason reason);
+ ITransaction* CreateUpdateTabletStatus(TTabletId tabletId,
+ const TActorId &local,
+ ui32 generation,
+ TFollowerId followerId,
+ TEvLocal::TEvTabletStatus::EStatus status,
+ TEvTablet::TEvTabletDead::EReason reason);
ITransaction* CreateBootTablet(TTabletId tabletId);
- ITransaction* CreateKillNode(TNodeId nodeId, const TActorId& local);
- ITransaction* CreateUpdateTabletGroups(TTabletId tabletId, TVector<NKikimrBlobStorage::TEvControllerSelectGroupsResult::TGroupParameters> groups = {});
+ ITransaction* CreateKillNode(TNodeId nodeId, const TActorId& local);
+ ITransaction* CreateUpdateTabletGroups(TTabletId tabletId, TVector<NKikimrBlobStorage::TEvControllerSelectGroupsResult::TGroupParameters> groups = {});
ITransaction* CreateCheckTablets();
ITransaction* CreateSyncTablets(const TActorId &local, NKikimrLocal::TEvSyncTablets& rec);
ITransaction* CreateStopTablet(TTabletId tabletId, const TActorId& actorToNotify);
- ITransaction* CreateResumeTablet(TTabletId tabletId, const TActorId& actorToNotify);
+ ITransaction* CreateResumeTablet(TTabletId tabletId, const TActorId& actorToNotify);
ITransaction* CreateStartTablet(TFullTabletId tabletId, const TActorId& local, ui64 cookie, bool external = false);
ITransaction* CreateUpdateTabletMetrics(TEvHive::TEvTabletMetrics::TPtr& ev);
ITransaction* CreateReassignGroups(TTabletId tabletId, const TActorId& actorToNotify, const std::bitset<MAX_TABLET_CHANNELS>& channelProfileNewGroup);
ITransaction* CreateLockTabletExecution(const NKikimrHive::TEvLockTabletExecution& rec, const TActorId& sender, const ui64 cookie);
ITransaction* CreateUnlockTabletExecution(const NKikimrHive::TEvUnlockTabletExecution& rec, const TActorId& sender, const ui64 cookie);
ITransaction* CreateUnlockTabletExecution(ui64 tabletId, ui64 seqNo);
- ITransaction* CreateRequestTabletSequence(TEvHive::TEvRequestTabletIdSequence::TPtr event);
- ITransaction* CreateResponseTabletSequence(TEvHive::TEvResponseTabletIdSequence::TPtr event);
- ITransaction* CreateDisconnectNode(THolder<TEvInterconnect::TEvNodeDisconnected> event);
- ITransaction* CreateProcessPendingOperations();
- ITransaction* CreateProcessBootQueue();
- ITransaction* CreateUpdateDomain(TSubDomainKey subdomainKey);
- ITransaction* CreateSeizeTablets(TEvHive::TEvSeizeTablets::TPtr event);
- ITransaction* CreateSeizeTabletsReply(TEvHive::TEvSeizeTabletsReply::TPtr event);
- ITransaction* CreateReleaseTablets(TEvHive::TEvReleaseTablets::TPtr event);
- ITransaction* CreateReleaseTabletsReply(TEvHive::TEvReleaseTabletsReply::TPtr event);
- ITransaction* CreateConfigureSubdomain(TEvHive::TEvConfigureHive::TPtr event);
- ITransaction* CreateSwitchDrainOn(TNodeId nodeId, TDrainSettings settings, const TActorId& initiator);
- ITransaction* CreateSwitchDrainOff(TNodeId nodeId, TDrainSettings settings, NKikimrProto::EReplyStatus status, ui32 movements);
-
-public:
- TDomainsView DomainsView;
-
-protected:
+ ITransaction* CreateRequestTabletSequence(TEvHive::TEvRequestTabletIdSequence::TPtr event);
+ ITransaction* CreateResponseTabletSequence(TEvHive::TEvResponseTabletIdSequence::TPtr event);
+ ITransaction* CreateDisconnectNode(THolder<TEvInterconnect::TEvNodeDisconnected> event);
+ ITransaction* CreateProcessPendingOperations();
+ ITransaction* CreateProcessBootQueue();
+ ITransaction* CreateUpdateDomain(TSubDomainKey subdomainKey);
+ ITransaction* CreateSeizeTablets(TEvHive::TEvSeizeTablets::TPtr event);
+ ITransaction* CreateSeizeTabletsReply(TEvHive::TEvSeizeTabletsReply::TPtr event);
+ ITransaction* CreateReleaseTablets(TEvHive::TEvReleaseTablets::TPtr event);
+ ITransaction* CreateReleaseTabletsReply(TEvHive::TEvReleaseTabletsReply::TPtr event);
+ ITransaction* CreateConfigureSubdomain(TEvHive::TEvConfigureHive::TPtr event);
+ ITransaction* CreateSwitchDrainOn(TNodeId nodeId, TDrainSettings settings, const TActorId& initiator);
+ ITransaction* CreateSwitchDrainOff(TNodeId nodeId, TDrainSettings settings, NKikimrProto::EReplyStatus status, ui32 movements);
+
+public:
+ TDomainsView DomainsView;
+
+protected:
TActorId BSControllerPipeClient;
TActorId RootHivePipeClient;
ui64 HiveUid; // Hive Personal Identifier - identifies a unique individual hive
ui32 HiveDomain;
- TTabletId RootHiveId;
- TTabletId HiveId;
- ui64 HiveGeneration;
+ TTabletId RootHiveId;
+ TTabletId HiveId;
+ ui64 HiveGeneration;
TSubDomainKey RootDomainKey;
- TSubDomainKey PrimaryDomainKey;
- TString RootDomainName;
+ TSubDomainKey PrimaryDomainKey;
+ TString RootDomainName;
TIntrusivePtr<NTabletPipe::TBoundedClientCacheConfig> PipeClientCacheConfig;
- THolder<NTabletPipe::IClientCache> PipeClientCache;
+ THolder<NTabletPipe::IClientCache> PipeClientCache;
TPipeTracker PipeTracker;
- NTabletPipe::TClientRetryPolicy PipeRetryPolicy;
- std::unordered_map<TNodeId, TNodeInfo> Nodes;
+ NTabletPipe::TClientRetryPolicy PipeRetryPolicy;
+ std::unordered_map<TNodeId, TNodeInfo> Nodes;
std::unordered_map<TTabletId, TLeaderTabletInfo> Tablets;
- std::unordered_map<TOwnerIdxType::TValueType, TTabletId> OwnerToTablet;
- std::unordered_map<TTabletCategoryId, TTabletCategoryInfo> TabletCategories;
- std::unordered_map<TTabletTypes::EType, TVector<i64>> TabletTypeAllowedMetrics;
- std::unordered_map<TString, TStoragePoolInfo> StoragePools;
- std::unordered_map<TSubDomainKey, TDomainInfo> Domains;
- std::unordered_set<TOwnerId> BlockedOwners;
- ui32 ConfigurationGeneration = 0;
- ui64 TabletsTotal = 0;
- ui64 TabletsAlive = 0;
- ui32 DataCenters = 1;
- ui32 RegisteredDataCenters = 1;
-
- bool AreWeRootHive() const { return RootHiveId == HiveId; }
- bool AreWeSubDomainHive() const { return RootHiveId != HiveId; }
-
- struct TAggregateMetrics {
- NKikimrTabletBase::TMetrics Metrics;
- ui64 Counter = 0;
-
- void IncreaseCount() {
- ++Counter;
- }
-
- void DecreaseCount() {
- Y_VERIFY(Counter > 0);
- --Counter;
- }
-
- void AggregateDiff(const NKikimrTabletBase::TMetrics& before, const NKikimrTabletBase::TMetrics& after, const TTabletInfo* tablet) {
- AggregateMetricsDiff(Metrics, before, after, tablet);
- }
-
- NKikimrTabletBase::TMetrics GetAverage() const {
- NKikimrTabletBase::TMetrics metrics;
- if (Counter > 0) {
- metrics.CopyFrom(Metrics);
- DivideMetrics(metrics, Counter);
- }
- return metrics;
- }
- };
-
- std::unordered_map<TObjectId, TAggregateMetrics> ObjectToTabletMetrics;
- std::unordered_map<TTabletTypes::EType, TAggregateMetrics> TabletTypeToTabletMetrics;
-
- TBootQueue BootQueue;
- bool ProcessWaitQueueScheduled = false;
- bool ProcessBootQueueScheduled = false;
- bool ProcessBootQueuePostponed = false;
-
+ std::unordered_map<TOwnerIdxType::TValueType, TTabletId> OwnerToTablet;
+ std::unordered_map<TTabletCategoryId, TTabletCategoryInfo> TabletCategories;
+ std::unordered_map<TTabletTypes::EType, TVector<i64>> TabletTypeAllowedMetrics;
+ std::unordered_map<TString, TStoragePoolInfo> StoragePools;
+ std::unordered_map<TSubDomainKey, TDomainInfo> Domains;
+ std::unordered_set<TOwnerId> BlockedOwners;
+ ui32 ConfigurationGeneration = 0;
+ ui64 TabletsTotal = 0;
+ ui64 TabletsAlive = 0;
+ ui32 DataCenters = 1;
+ ui32 RegisteredDataCenters = 1;
+
+ bool AreWeRootHive() const { return RootHiveId == HiveId; }
+ bool AreWeSubDomainHive() const { return RootHiveId != HiveId; }
+
+ struct TAggregateMetrics {
+ NKikimrTabletBase::TMetrics Metrics;
+ ui64 Counter = 0;
+
+ void IncreaseCount() {
+ ++Counter;
+ }
+
+ void DecreaseCount() {
+ Y_VERIFY(Counter > 0);
+ --Counter;
+ }
+
+ void AggregateDiff(const NKikimrTabletBase::TMetrics& before, const NKikimrTabletBase::TMetrics& after, const TTabletInfo* tablet) {
+ AggregateMetricsDiff(Metrics, before, after, tablet);
+ }
+
+ NKikimrTabletBase::TMetrics GetAverage() const {
+ NKikimrTabletBase::TMetrics metrics;
+ if (Counter > 0) {
+ metrics.CopyFrom(Metrics);
+ DivideMetrics(metrics, Counter);
+ }
+ return metrics;
+ }
+ };
+
+ std::unordered_map<TObjectId, TAggregateMetrics> ObjectToTabletMetrics;
+ std::unordered_map<TTabletTypes::EType, TAggregateMetrics> TabletTypeToTabletMetrics;
+
+ TBootQueue BootQueue;
+ bool ProcessWaitQueueScheduled = false;
+ bool ProcessBootQueueScheduled = false;
+ bool ProcessBootQueuePostponed = false;
+
THashMap<ui32, TEvInterconnect::TNodeInfo> NodesInfo;
- TTabletCountersBase* TabletCounters;
+ TTabletCountersBase* TabletCounters;
TAutoPtr<TTabletCountersBase> TabletCountersPtr;
- i32 BalancerProgress; // all values below 0 mean that balancer is not active (-1 = dead, -2 = starting)
- std::unordered_set<TNodeId> BalancerNodes; // all nodes, affected by running balancers
-
- NKikimrHive::EMigrationState MigrationState = NKikimrHive::EMigrationState::MIGRATION_UNKNOWN;
- i32 MigrationProgress = 0;
- NKikimrHive::TEvSeizeTablets MigrationFilter;
-
+ i32 BalancerProgress; // all values below 0 mean that balancer is not active (-1 = dead, -2 = starting)
+ std::unordered_set<TNodeId> BalancerNodes; // all nodes, affected by running balancers
+
+ NKikimrHive::EMigrationState MigrationState = NKikimrHive::EMigrationState::MIGRATION_UNKNOWN;
+ i32 MigrationProgress = 0;
+ NKikimrHive::TEvSeizeTablets MigrationFilter;
+
TActorId ResponsivenessActorID;
TTabletResponsivenessPinger *ResponsivenessPinger;
- // remove after upgrade to sub hives
- ui64 NextTabletId = 0x10000;
- /////////////////////////////////////
- bool RequestingSequenceNow = false;
- size_t RequestingSequenceIndex = 0;
- bool ProcessTabletBalancerScheduled = false;
- bool ProcessPendingOperationsScheduled = false;
- TResourceRawValues TotalRawResourceValues = {};
- TResourceNormalizedValues TotalNormalizedResourceValues = {};
- TInstant LastResourceChangeReaction;
- //TDuration ResourceChangeReactionPeriod = TDuration::Seconds(10);
- TVector<ISubActor*> SubActors;
+ // remove after upgrade to sub hives
+ ui64 NextTabletId = 0x10000;
+ /////////////////////////////////////
+ bool RequestingSequenceNow = false;
+ size_t RequestingSequenceIndex = 0;
+ bool ProcessTabletBalancerScheduled = false;
+ bool ProcessPendingOperationsScheduled = false;
+ TResourceRawValues TotalRawResourceValues = {};
+ TResourceNormalizedValues TotalNormalizedResourceValues = {};
+ TInstant LastResourceChangeReaction;
+ //TDuration ResourceChangeReactionPeriod = TDuration::Seconds(10);
+ TVector<ISubActor*> SubActors;
TResourceProfilesPtr ResourceProfiles;
NKikimrLocal::TLocalConfig LocalConfig;
- bool ReadyForConnections = false; // is Hive ready for incoming connections?
+ bool ReadyForConnections = false; // is Hive ready for incoming connections?
ui64 NextTabletUnlockSeqNo = 1; // sequence number for unlock events
- bool SpreadNeighbours = true; // spread tablets of the same object across cluster
- TSequenceGenerator Sequencer;
- TOwnershipKeeper Keeper;
-
- struct TPendingCreateTablet {
- NKikimrHive::TEvCreateTablet CreateTablet;
+ bool SpreadNeighbours = true; // spread tablets of the same object across cluster
+ TSequenceGenerator Sequencer;
+ TOwnershipKeeper Keeper;
+
+ struct TPendingCreateTablet {
+ NKikimrHive::TEvCreateTablet CreateTablet;
TActorId Sender;
- ui64 Cookie;
- };
-
- std::unordered_map<std::pair<ui64, ui64>, TPendingCreateTablet> PendingCreateTablets;
-
- ui64 UpdateTabletMetricsInProgress = 0;
- static constexpr ui64 MAX_UPDATE_TABLET_METRICS_IN_PROGRESS = 10000; // 10K
-
- TString BootStateBooting = "Booting";
- TString BootStateStarting = "Starting";
- TString BootStateRunning = "Running";
- TString BootStateTooManyStarting = "Too many tablets starting";
+ ui64 Cookie;
+ };
+
+ std::unordered_map<std::pair<ui64, ui64>, TPendingCreateTablet> PendingCreateTablets;
+
+ ui64 UpdateTabletMetricsInProgress = 0;
+ static constexpr ui64 MAX_UPDATE_TABLET_METRICS_IN_PROGRESS = 10000; // 10K
+
+ TString BootStateBooting = "Booting";
+ TString BootStateStarting = "Starting";
+ TString BootStateRunning = "Running";
+ TString BootStateTooManyStarting = "Too many tablets starting";
TString BootStateLeaderNotRunning = "Leader not running";
- TString BootStateAllNodesAreDead = "All nodes are dead";
- TString BootStateAllNodesAreDeadOrDown = "All nodes are dead or down";
- TString BootStateNoNodesAllowedToRun = "No nodes allowed to run";
- TString BootStateNotEnoughDatacenters = "Not enough datacenters";
- TString BootStateNotEnoughResources = "Not enough resources";
- TString BootStateNodesLocationUnknown = "Nodes location unknown";
- TString BootStateWeFilledAllAvailableNodes = "All available nodes are already filled with someone from our family";
-
- NKikimrConfig::THiveConfig ClusterConfig;
- NKikimrConfig::THiveConfig DatabaseConfig;
- std::unordered_map<TTabletTypes::EType, NKikimrConfig::THiveTabletLimit> TabletLimit; // built from CurrentConfig
- std::unordered_map<TTabletTypes::EType, NKikimrHive::TDataCentersPreference> DefaultDataCentersPreference;
- std::unordered_set<TDataCenterId> RegisteredDataCenterIds;
-
- void OnActivateExecutor(const TActorContext& ctx) override;
- void DefaultSignalTabletActive(const TActorContext& ctx) override;
- void OnDetach(const TActorContext&) override;
- void OnTabletDead(TEvTablet::TEvTabletDead::TPtr &ev, const TActorContext&) override;
- bool OnRenderAppHtmlPage(NMon::TEvRemoteHttpInfo::TPtr ev, const TActorContext&) override;
-
+ TString BootStateAllNodesAreDead = "All nodes are dead";
+ TString BootStateAllNodesAreDeadOrDown = "All nodes are dead or down";
+ TString BootStateNoNodesAllowedToRun = "No nodes allowed to run";
+ TString BootStateNotEnoughDatacenters = "Not enough datacenters";
+ TString BootStateNotEnoughResources = "Not enough resources";
+ TString BootStateNodesLocationUnknown = "Nodes location unknown";
+ TString BootStateWeFilledAllAvailableNodes = "All available nodes are already filled with someone from our family";
+
+ NKikimrConfig::THiveConfig ClusterConfig;
+ NKikimrConfig::THiveConfig DatabaseConfig;
+ std::unordered_map<TTabletTypes::EType, NKikimrConfig::THiveTabletLimit> TabletLimit; // built from CurrentConfig
+ std::unordered_map<TTabletTypes::EType, NKikimrHive::TDataCentersPreference> DefaultDataCentersPreference;
+ std::unordered_set<TDataCenterId> RegisteredDataCenterIds;
+
+ void OnActivateExecutor(const TActorContext& ctx) override;
+ void DefaultSignalTabletActive(const TActorContext& ctx) override;
+ void OnDetach(const TActorContext&) override;
+ void OnTabletDead(TEvTablet::TEvTabletDead::TPtr &ev, const TActorContext&) override;
+ bool OnRenderAppHtmlPage(NMon::TEvRemoteHttpInfo::TPtr ev, const TActorContext&) override;
+
bool ReassignChannelsEnabled() const override {
return true;
}
void BuildLocalConfig();
- void BuildCurrentConfig();
- void Cleanup();
-
- void Handle(TEvHive::TEvCreateTablet::TPtr&);
- void Handle(TEvHive::TEvAdoptTablet::TPtr&);
- void Handle(TEvHive::TEvStopTablet::TPtr&);
- void Handle(TEvHive::TEvBootTablet::TPtr&);
- void Handle(TEvLocal::TEvStatus::TPtr&);
- void Handle(TEvLocal::TEvTabletStatus::TPtr&);
- void Handle(TEvLocal::TEvRegisterNode::TPtr&);
- void Handle(TEvBlobStorage::TEvControllerSelectGroupsResult::TPtr&);
- void Handle(TEvents::TEvPoisonPill::TPtr&);
- void Handle(TEvTabletPipe::TEvClientConnected::TPtr&);
- void Handle(TEvTabletPipe::TEvClientDestroyed::TPtr&);
- void Handle(TEvTabletPipe::TEvServerConnected::TPtr&);
- void Handle(TEvTabletPipe::TEvServerDisconnected::TPtr&);
- void Handle(TEvInterconnect::TEvNodeConnected::TPtr&);
- void Handle(TEvInterconnect::TEvNodeDisconnected::TPtr&);
- void Handle(TEvInterconnect::TEvNodeInfo::TPtr&);
- void Handle(TEvInterconnect::TEvNodesInfo::TPtr&);
- void Handle(TEvents::TEvUndelivered::TPtr&);
- void Handle(TEvHive::TEvTabletMetrics::TPtr&);
- void Handle(TEvHive::TEvReassignTablet::TPtr&);
- void Handle(TEvHive::TEvInitiateBlockStorage::TPtr&);
- void Handle(TEvLocal::TEvSyncTablets::TPtr&);
- void Handle(TEvTabletBase::TEvBlockBlobStorageResult::TPtr&);
- void Handle(TEvTabletBase::TEvDeleteTabletResult::TPtr&);
- void Handle(TEvHive::TEvDeleteTablet::TPtr&);
- void Handle(TEvHive::TEvDeleteOwnerTablets::TPtr&);
- void Handle(TEvHive::TEvRequestHiveInfo::TPtr&);
- void Handle(TEvHive::TEvLookupTablet::TPtr&);
- void Handle(TEvHive::TEvLookupChannelInfo::TPtr&);
- void Handle(TEvHive::TEvCutTabletHistory::TPtr&);
- void Handle(TEvHive::TEvDrainNode::TPtr&);
- void Handle(TEvHive::TEvFillNode::TPtr&);
- void Handle(TEvHive::TEvInitiateDeleteStorage::TPtr&);
- void Handle(TEvHive::TEvGetTabletStorageInfo::TPtr&);
- void Handle(TEvHive::TEvLockTabletExecution::TPtr&);
- void Handle(TEvHive::TEvUnlockTabletExecution::TPtr&);
- void Handle(TEvHive::TEvInitiateTabletExternalBoot::TPtr&);
- void Handle(TEvHive::TEvRequestHiveDomainStats::TPtr&);
- void Handle(TEvHive::TEvRequestHiveNodeStats::TPtr&);
- void Handle(TEvHive::TEvRequestHiveStorageStats::TPtr&);
- void Handle(TEvHive::TEvInvalidateStoragePools::TPtr&);
- void Handle(TEvHive::TEvRequestTabletIdSequence::TPtr&);
- void Handle(TEvHive::TEvResponseTabletIdSequence::TPtr&);
- void Handle(TEvHive::TEvSeizeTablets::TPtr&);
- void Handle(TEvHive::TEvSeizeTabletsReply::TPtr&);
- void Handle(TEvHive::TEvReleaseTablets::TPtr&);
- void Handle(TEvHive::TEvReleaseTabletsReply::TPtr&);
- void Handle(TEvSubDomain::TEvConfigure::TPtr&);
- void Handle(TEvHive::TEvConfigureHive::TPtr& ev);
- void Handle(TEvHive::TEvInitMigration::TPtr&);
- void Handle(TEvHive::TEvQueryMigration::TPtr&);
- void Handle(TEvPrivate::TEvKickTablet::TPtr&);
- void Handle(TEvPrivate::TEvBootTablets::TPtr&);
- void Handle(TEvPrivate::TEvCheckTabletNodeAlive::TPtr&);
- void Handle(TEvPrivate::TEvProcessBootQueue::TPtr&);
- void Handle(TEvPrivate::TEvPostponeProcessBootQueue::TPtr&);
- void Handle(TEvPrivate::TEvProcessDisconnectNode::TPtr&);
- void Handle(TEvPrivate::TEvProcessTabletBalancer::TPtr&);
- void Handle(TEvPrivate::TEvUnlockTabletReconnectTimeout::TPtr&);
- void Handle(TEvPrivate::TEvProcessPendingOperations::TPtr&);
- void Handle(TEvTxProxySchemeCache::TEvNavigateKeySetResult::TPtr& ev);
- void Handle(NConsole::TEvConsole::TEvConfigNotificationRequest::TPtr& ev);
- void Handle(NConsole::TEvConfigsDispatcher::TEvSetConfigSubscriptionResponse::TPtr& ev);
+ void BuildCurrentConfig();
+ void Cleanup();
+
+ void Handle(TEvHive::TEvCreateTablet::TPtr&);
+ void Handle(TEvHive::TEvAdoptTablet::TPtr&);
+ void Handle(TEvHive::TEvStopTablet::TPtr&);
+ void Handle(TEvHive::TEvBootTablet::TPtr&);
+ void Handle(TEvLocal::TEvStatus::TPtr&);
+ void Handle(TEvLocal::TEvTabletStatus::TPtr&);
+ void Handle(TEvLocal::TEvRegisterNode::TPtr&);
+ void Handle(TEvBlobStorage::TEvControllerSelectGroupsResult::TPtr&);
+ void Handle(TEvents::TEvPoisonPill::TPtr&);
+ void Handle(TEvTabletPipe::TEvClientConnected::TPtr&);
+ void Handle(TEvTabletPipe::TEvClientDestroyed::TPtr&);
+ void Handle(TEvTabletPipe::TEvServerConnected::TPtr&);
+ void Handle(TEvTabletPipe::TEvServerDisconnected::TPtr&);
+ void Handle(TEvInterconnect::TEvNodeConnected::TPtr&);
+ void Handle(TEvInterconnect::TEvNodeDisconnected::TPtr&);
+ void Handle(TEvInterconnect::TEvNodeInfo::TPtr&);
+ void Handle(TEvInterconnect::TEvNodesInfo::TPtr&);
+ void Handle(TEvents::TEvUndelivered::TPtr&);
+ void Handle(TEvHive::TEvTabletMetrics::TPtr&);
+ void Handle(TEvHive::TEvReassignTablet::TPtr&);
+ void Handle(TEvHive::TEvInitiateBlockStorage::TPtr&);
+ void Handle(TEvLocal::TEvSyncTablets::TPtr&);
+ void Handle(TEvTabletBase::TEvBlockBlobStorageResult::TPtr&);
+ void Handle(TEvTabletBase::TEvDeleteTabletResult::TPtr&);
+ void Handle(TEvHive::TEvDeleteTablet::TPtr&);
+ void Handle(TEvHive::TEvDeleteOwnerTablets::TPtr&);
+ void Handle(TEvHive::TEvRequestHiveInfo::TPtr&);
+ void Handle(TEvHive::TEvLookupTablet::TPtr&);
+ void Handle(TEvHive::TEvLookupChannelInfo::TPtr&);
+ void Handle(TEvHive::TEvCutTabletHistory::TPtr&);
+ void Handle(TEvHive::TEvDrainNode::TPtr&);
+ void Handle(TEvHive::TEvFillNode::TPtr&);
+ void Handle(TEvHive::TEvInitiateDeleteStorage::TPtr&);
+ void Handle(TEvHive::TEvGetTabletStorageInfo::TPtr&);
+ void Handle(TEvHive::TEvLockTabletExecution::TPtr&);
+ void Handle(TEvHive::TEvUnlockTabletExecution::TPtr&);
+ void Handle(TEvHive::TEvInitiateTabletExternalBoot::TPtr&);
+ void Handle(TEvHive::TEvRequestHiveDomainStats::TPtr&);
+ void Handle(TEvHive::TEvRequestHiveNodeStats::TPtr&);
+ void Handle(TEvHive::TEvRequestHiveStorageStats::TPtr&);
+ void Handle(TEvHive::TEvInvalidateStoragePools::TPtr&);
+ void Handle(TEvHive::TEvRequestTabletIdSequence::TPtr&);
+ void Handle(TEvHive::TEvResponseTabletIdSequence::TPtr&);
+ void Handle(TEvHive::TEvSeizeTablets::TPtr&);
+ void Handle(TEvHive::TEvSeizeTabletsReply::TPtr&);
+ void Handle(TEvHive::TEvReleaseTablets::TPtr&);
+ void Handle(TEvHive::TEvReleaseTabletsReply::TPtr&);
+ void Handle(TEvSubDomain::TEvConfigure::TPtr&);
+ void Handle(TEvHive::TEvConfigureHive::TPtr& ev);
+ void Handle(TEvHive::TEvInitMigration::TPtr&);
+ void Handle(TEvHive::TEvQueryMigration::TPtr&);
+ void Handle(TEvPrivate::TEvKickTablet::TPtr&);
+ void Handle(TEvPrivate::TEvBootTablets::TPtr&);
+ void Handle(TEvPrivate::TEvCheckTabletNodeAlive::TPtr&);
+ void Handle(TEvPrivate::TEvProcessBootQueue::TPtr&);
+ void Handle(TEvPrivate::TEvPostponeProcessBootQueue::TPtr&);
+ void Handle(TEvPrivate::TEvProcessDisconnectNode::TPtr&);
+ void Handle(TEvPrivate::TEvProcessTabletBalancer::TPtr&);
+ void Handle(TEvPrivate::TEvUnlockTabletReconnectTimeout::TPtr&);
+ void Handle(TEvPrivate::TEvProcessPendingOperations::TPtr&);
+ void Handle(TEvTxProxySchemeCache::TEvNavigateKeySetResult::TPtr& ev);
+ void Handle(NConsole::TEvConsole::TEvConfigNotificationRequest::TPtr& ev);
+ void Handle(NConsole::TEvConfigsDispatcher::TEvSetConfigSubscriptionResponse::TPtr& ev);
void Handle(NSysView::TEvSysView::TEvGetTabletIdsRequest::TPtr& ev);
void Handle(NSysView::TEvSysView::TEvGetTabletsRequest::TPtr& ev);
protected:
- void RestartPipeTx(ui64 tabletId);
+ void RestartPipeTx(ui64 tabletId);
public:
static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
@@ -509,53 +509,53 @@ public:
THive(TTabletStorageInfo *info, const TActorId &tablet);
-protected:
- STATEFN(StateInit);
- STATEFN(StateWork);
-
- void SendToBSControllerPipe(IEventBase* payload);
- void SendToRootHivePipe(IEventBase* payload);
- void RestartBSControllerPipe();
- void RestartRootHivePipe();
-
- struct TBestNodeResult {
- TNodeInfo* BestNode;
- bool TryToContinue;
-
- TBestNodeResult(TNodeInfo& bestNode)
- : BestNode(&bestNode)
- , TryToContinue(true)
- {}
-
- TBestNodeResult(bool tryToContinue)
- : BestNode(nullptr)
- , TryToContinue(tryToContinue)
- {}
- };
-
- TBestNodeResult FindBestNode(const TTabletInfo& tablet);
-
- struct TSelectedNode {
- double Usage;
- TNodeInfo* Node;
-
- TSelectedNode(double usage, TNodeInfo* node)
- : Usage(usage)
- , Node(node)
- {}
-
- bool operator <(const TSelectedNode& b) const {
- return Usage < b.Usage;
- }
- };
-
- template <NKikimrConfig::THiveConfig::EHiveNodeSelectStrategy Strategy>
- TNodeInfo* SelectNode(const std::vector<TSelectedNode>& selectedNodes);
-
-public:
+protected:
+ STATEFN(StateInit);
+ STATEFN(StateWork);
+
+ void SendToBSControllerPipe(IEventBase* payload);
+ void SendToRootHivePipe(IEventBase* payload);
+ void RestartBSControllerPipe();
+ void RestartRootHivePipe();
+
+ struct TBestNodeResult {
+ TNodeInfo* BestNode;
+ bool TryToContinue;
+
+ TBestNodeResult(TNodeInfo& bestNode)
+ : BestNode(&bestNode)
+ , TryToContinue(true)
+ {}
+
+ TBestNodeResult(bool tryToContinue)
+ : BestNode(nullptr)
+ , TryToContinue(tryToContinue)
+ {}
+ };
+
+ TBestNodeResult FindBestNode(const TTabletInfo& tablet);
+
+ struct TSelectedNode {
+ double Usage;
+ TNodeInfo* Node;
+
+ TSelectedNode(double usage, TNodeInfo* node)
+ : Usage(usage)
+ , Node(node)
+ {}
+
+ bool operator <(const TSelectedNode& b) const {
+ return Usage < b.Usage;
+ }
+ };
+
+ template <NKikimrConfig::THiveConfig::EHiveNodeSelectStrategy Strategy>
+ TNodeInfo* SelectNode(const std::vector<TSelectedNode>& selectedNodes);
+
+public:
void AssignTabletGroups(TLeaderTabletInfo& tablet);
- TNodeInfo& GetNode(TNodeId nodeId);
- TNodeInfo* FindNode(TNodeId nodeId);
+ TNodeInfo& GetNode(TNodeId nodeId);
+ TNodeInfo* FindNode(TNodeId nodeId);
TLeaderTabletInfo& GetTablet(TTabletId tabletId);
TLeaderTabletInfo* FindTablet(TTabletId tabletId);
TLeaderTabletInfo* FindTabletEvenInDeleting(TTabletId tabletId); // find tablets, even deleting ones
@@ -563,241 +563,241 @@ public:
TTabletInfo* FindTablet(TTabletId tabletId, TFollowerId followerId);
TTabletInfo* FindTablet(const TFullTabletId& tabletId) { return FindTablet(tabletId.first, tabletId.second); }
TTabletInfo* FindTabletEvenInDeleting(TTabletId tabletId, TFollowerId followerId);
- TStoragePoolInfo& GetStoragePool(const TString& name);
- TStoragePoolInfo* FindStoragePool(const TString& name);
- TDomainInfo* FindDomain(TSubDomainKey key);
+ TStoragePoolInfo& GetStoragePool(const TString& name);
+ TStoragePoolInfo* FindStoragePool(const TString& name);
+ TDomainInfo* FindDomain(TSubDomainKey key);
const TNodeLocation& GetNodeLocation(TNodeId nodeId) const;
- void DeleteTablet(TTabletId tabletId);
- void DeleteNode(TNodeId nodeId);
- TVector<TNodeId> GetNodesForWhiteboardBroadcast(size_t maxNodesToReturn = 3);
+ void DeleteTablet(TTabletId tabletId);
+ void DeleteNode(TNodeId nodeId);
+ TVector<TNodeId> GetNodesForWhiteboardBroadcast(size_t maxNodesToReturn = 3);
void ReportTabletStateToWhiteboard(const TLeaderTabletInfo& tablet, NKikimrWhiteboard::TTabletStateInfo::ETabletState state);
void ReportStoppedToWhiteboard(const TLeaderTabletInfo& tablet);
void ReportDeletedToWhiteboard(const TLeaderTabletInfo& tablet);
- TTabletCategoryInfo& GetTabletCategory(TTabletCategoryId tabletCategoryId);
- void KillNode(TNodeId nodeId, const TActorId& local);
- void AddToBootQueue(TTabletInfo* tablet);
- void SetCounterTabletsTotal(ui64 tabletsTotal);
- void UpdateCounterTabletsTotal(i64 tabletsTotalDiff);
- void UpdateCounterTabletsAlive(i64 tabletsAliveDiff);
- void UpdateCounterBootQueueSize(ui64 bootQueueSize);
+ TTabletCategoryInfo& GetTabletCategory(TTabletCategoryId tabletCategoryId);
+ void KillNode(TNodeId nodeId, const TActorId& local);
+ void AddToBootQueue(TTabletInfo* tablet);
+ void SetCounterTabletsTotal(ui64 tabletsTotal);
+ void UpdateCounterTabletsTotal(i64 tabletsTotalDiff);
+ void UpdateCounterTabletsAlive(i64 tabletsAliveDiff);
+ void UpdateCounterBootQueueSize(ui64 bootQueueSize);
bool DomainHasNodes(const TSubDomainKey &domainKey) const;
- void ProcessBootQueue();
- void ProcessWaitQueue();
- void PostponeProcessBootQueue(TDuration after);
- void ProcessPendingOperations();
- void ProcessTabletBalancer();
- const TVector<i64>& GetTabletTypeAllowedMetricIds(TTabletTypes::EType type) const;
- static const TVector<i64>& GetDefaultAllowedMetricIds();
- static bool IsValidMetrics(const NKikimrTabletBase::TMetrics& metrics);
- static bool IsValidMetricsCPU(const NKikimrTabletBase::TMetrics& metrics);
- static bool IsValidMetricsMemory(const NKikimrTabletBase::TMetrics& metrics);
- static bool IsValidMetricsNetwork(const NKikimrTabletBase::TMetrics& metrics);
- void UpdateTotalResourceValues(
- const TNodeInfo* node,
- const TTabletInfo* tablet,
- const NKikimrTabletBase::TMetrics& before,
- const NKikimrTabletBase::TMetrics& after,
- NKikimr::NHive::TResourceRawValues deltaRaw,
- NKikimr::NHive::TResourceNormalizedValues deltaNormalized);
+ void ProcessBootQueue();
+ void ProcessWaitQueue();
+ void PostponeProcessBootQueue(TDuration after);
+ void ProcessPendingOperations();
+ void ProcessTabletBalancer();
+ const TVector<i64>& GetTabletTypeAllowedMetricIds(TTabletTypes::EType type) const;
+ static const TVector<i64>& GetDefaultAllowedMetricIds();
+ static bool IsValidMetrics(const NKikimrTabletBase::TMetrics& metrics);
+ static bool IsValidMetricsCPU(const NKikimrTabletBase::TMetrics& metrics);
+ static bool IsValidMetricsMemory(const NKikimrTabletBase::TMetrics& metrics);
+ static bool IsValidMetricsNetwork(const NKikimrTabletBase::TMetrics& metrics);
+ void UpdateTotalResourceValues(
+ const TNodeInfo* node,
+ const TTabletInfo* tablet,
+ const NKikimrTabletBase::TMetrics& before,
+ const NKikimrTabletBase::TMetrics& after,
+ NKikimr::NHive::TResourceRawValues deltaRaw,
+ NKikimr::NHive::TResourceNormalizedValues deltaNormalized);
static void FillTabletInfo(NKikimrHive::TEvResponseHiveInfo& response, ui64 tabletId, const TLeaderTabletInfo* info, const NKikimrHive::TEvRequestHiveInfo& req);
void ExecuteStartTablet(TFullTabletId tabletId, const TActorId& local, ui64 cookie, bool external);
- ui32 GetDataCenters();
- ui32 GetRegisteredDataCenters();
- void UpdateRegisteredDataCenters(TDataCenterId dataCenterId);
+ ui32 GetDataCenters();
+ ui32 GetRegisteredDataCenters();
+ void UpdateRegisteredDataCenters(TDataCenterId dataCenterId);
void SendPing(const TActorId& local, TNodeId id);
void SendReconnect(const TActorId& local);
static THolder<NKikimrBlobStorage::TEvControllerSelectGroups::TGroupParameters> BuildGroupParametersForChannel(const TLeaderTabletInfo& tablet, ui32 channelId);
- void KickTablet(const TTabletInfo& tablet);
+ void KickTablet(const TTabletInfo& tablet);
void StopTablet(const TActorId& local, const TTabletInfo& tablet);
void StopTablet(const TActorId& local, TFullTabletId tabletId);
- void RunProcessBootQueue();
-
- TTabletMetricsAggregates DefaultResourceMetricsAggregates;
- ui64 MetricsWindowSize = TDuration::Minutes(1).MilliSeconds();
- const TTabletMetricsAggregates& GetDefaultResourceMetricsAggregates() const;
- bool CheckForForwardTabletRequest(TTabletId tabletId, NKikimrHive::TForwardRequest& forwardRequest);
- TSubDomainKey GetRootDomainKey() const;
- TString GetLogPrefix() const;
-
- double GetResourceOvercommitment() const {
- return CurrentConfig.GetResourceOvercommitment();
- }
-
- TDuration GetTabletKickCooldownPeriod() const {
- return TDuration::Seconds(CurrentConfig.GetTabletKickCooldownPeriod());
- }
-
- TDuration GetResourceChangeReactionPeriod() const {
- return TDuration::Seconds(CurrentConfig.GetResourceChangeReactionPeriod());
- }
-
- TDuration GetMinPeriodBetweenBalance() const {
- return TDuration::Seconds(CurrentConfig.GetMinPeriodBetweenBalance());
- }
-
- TDuration GetMinPeriodBetweenReassign() const {
- return TDuration::Seconds(CurrentConfig.GetMinPeriodBetweenReassign());
- }
-
- TDuration GetTabletRestartWatchPeriod() const {
- return TDuration::Seconds(CurrentConfig.GetTabletRestartWatchPeriod());
- }
-
- TDuration GetNodeRestartWatchPeriod() const {
- return TDuration::Seconds(CurrentConfig.GetNodeRestartWatchPeriod());
- }
-
- TDuration GetNodeDeletePeriod() const {
- return TDuration::Seconds(CurrentConfig.GetNodeDeletePeriod());
- }
-
- ui64 GetDrainInflight() const {
- return CurrentConfig.GetDrainInflight();
- }
-
- ui64 GetBalancerInflight() const {
- return CurrentConfig.GetBalancerInflight();
- }
-
- ui64 GetMaxBootBatchSize() const {
- return CurrentConfig.GetMaxBootBatchSize();
- }
-
- double GetMinScatterToBalance() const {
- return CurrentConfig.GetMinScatterToBalance();
- }
-
- double GetMaxNodeUsageToKick() const {
- return CurrentConfig.GetMaxNodeUsageToKick();
- }
-
- double GetMinNodeUsageToBalance() const {
- return CurrentConfig.GetMinNodeUsageToBalance();
- }
-
- ui64 GetMaxTabletsScheduled() const {
- return CurrentConfig.GetMaxTabletsScheduled();
- }
-
- bool GetSpreadNeighbours() const {
- return CurrentConfig.GetSpreadNeighbours();
- }
-
- ui64 GetDefaultUnitIOPS() const {
- return CurrentConfig.GetDefaultUnitIOPS();
- }
-
- ui64 GetDefaultUnitSize() const {
- return CurrentConfig.GetDefaultUnitSize();
- }
-
- ui64 GetDefaultUnitThroughput() const {
- return CurrentConfig.GetDefaultUnitThroughput();
- }
-
- ui64 GetRequestSequenceSize() const {
- return CurrentConfig.GetRequestSequenceSize();
- }
-
- ui64 GetMetricsWindowSize() const {
- return CurrentConfig.GetMetricsWindowSize();
- }
-
- ui64 GetMinRequestSequenceSize() const {
- return CurrentConfig.GetMinRequestSequenceSize();
- }
-
- ui64 GetMaxRequestSequenceSize() const {
- return CurrentConfig.GetMaxRequestSequenceSize();
- }
-
- bool GetEnableFastTabletMove() const {
- return CurrentConfig.GetEnableFastTabletMove();
- }
-
- TDuration GetTabletRestartsPeriod() const {
- return TDuration::MilliSeconds(CurrentConfig.GetTabletRestartsPeriod());
- }
-
- ui64 GetTabletRestarsMaxCount() const {
- return CurrentConfig.GetTabletRestarsMaxCount();
- }
-
- TDuration GetPostponeStartPeriod() const {
- return TDuration::MilliSeconds(CurrentConfig.GetPostponeStartPeriod());
- }
-
- const std::unordered_map<TTabletTypes::EType, NKikimrConfig::THiveTabletLimit>& GetTabletLimit() const {
- return TabletLimit;
- }
-
- TArrayRef<const NKikimrHive::TDataCentersGroup*> GetDefaultDataCentersPreference(TTabletTypes::EType type) {
- auto itDCsPreference = DefaultDataCentersPreference.find(type);
- if (itDCsPreference != DefaultDataCentersPreference.end()) {
- return TArrayRef<const NKikimrHive::TDataCentersGroup*>(
- const_cast<const NKikimrHive::TDataCentersGroup**>(itDCsPreference->second.GetDataCentersGroups().data()),
- itDCsPreference->second.GetDataCentersGroups().size());
- }
- return {};
- }
-
- TResourceRawValues GetResourceInitialMaximumValues() const {
- TResourceRawValues initialMaximum;
- std::get<NMetrics::EResource::CPU>(initialMaximum) = CurrentConfig.GetMaxResourceCPU();
- std::get<NMetrics::EResource::Memory>(initialMaximum) = CurrentConfig.GetMaxResourceMemory();
- std::get<NMetrics::EResource::Network>(initialMaximum) = CurrentConfig.GetMaxResourceNetwork();
- std::get<NMetrics::EResource::Counter>(initialMaximum) = CurrentConfig.GetMaxResourceCounter();
- return initialMaximum;
- }
-
- static void ActualizeRestartStatistics(google::protobuf::RepeatedField<google::protobuf::uint64>& restartTimestamps, ui64 barrier);
- static bool IsSystemTablet(TTabletTypes::EType type);
-
-protected:
- void ScheduleDisconnectNode(THolder<TEvPrivate::TEvProcessDisconnectNode> event);
+ void RunProcessBootQueue();
+
+ TTabletMetricsAggregates DefaultResourceMetricsAggregates;
+ ui64 MetricsWindowSize = TDuration::Minutes(1).MilliSeconds();
+ const TTabletMetricsAggregates& GetDefaultResourceMetricsAggregates() const;
+ bool CheckForForwardTabletRequest(TTabletId tabletId, NKikimrHive::TForwardRequest& forwardRequest);
+ TSubDomainKey GetRootDomainKey() const;
+ TString GetLogPrefix() const;
+
+ double GetResourceOvercommitment() const {
+ return CurrentConfig.GetResourceOvercommitment();
+ }
+
+ TDuration GetTabletKickCooldownPeriod() const {
+ return TDuration::Seconds(CurrentConfig.GetTabletKickCooldownPeriod());
+ }
+
+ TDuration GetResourceChangeReactionPeriod() const {
+ return TDuration::Seconds(CurrentConfig.GetResourceChangeReactionPeriod());
+ }
+
+ TDuration GetMinPeriodBetweenBalance() const {
+ return TDuration::Seconds(CurrentConfig.GetMinPeriodBetweenBalance());
+ }
+
+ TDuration GetMinPeriodBetweenReassign() const {
+ return TDuration::Seconds(CurrentConfig.GetMinPeriodBetweenReassign());
+ }
+
+ TDuration GetTabletRestartWatchPeriod() const {
+ return TDuration::Seconds(CurrentConfig.GetTabletRestartWatchPeriod());
+ }
+
+ TDuration GetNodeRestartWatchPeriod() const {
+ return TDuration::Seconds(CurrentConfig.GetNodeRestartWatchPeriod());
+ }
+
+ TDuration GetNodeDeletePeriod() const {
+ return TDuration::Seconds(CurrentConfig.GetNodeDeletePeriod());
+ }
+
+ ui64 GetDrainInflight() const {
+ return CurrentConfig.GetDrainInflight();
+ }
+
+ ui64 GetBalancerInflight() const {
+ return CurrentConfig.GetBalancerInflight();
+ }
+
+ ui64 GetMaxBootBatchSize() const {
+ return CurrentConfig.GetMaxBootBatchSize();
+ }
+
+ double GetMinScatterToBalance() const {
+ return CurrentConfig.GetMinScatterToBalance();
+ }
+
+ double GetMaxNodeUsageToKick() const {
+ return CurrentConfig.GetMaxNodeUsageToKick();
+ }
+
+ double GetMinNodeUsageToBalance() const {
+ return CurrentConfig.GetMinNodeUsageToBalance();
+ }
+
+ ui64 GetMaxTabletsScheduled() const {
+ return CurrentConfig.GetMaxTabletsScheduled();
+ }
+
+ bool GetSpreadNeighbours() const {
+ return CurrentConfig.GetSpreadNeighbours();
+ }
+
+ ui64 GetDefaultUnitIOPS() const {
+ return CurrentConfig.GetDefaultUnitIOPS();
+ }
+
+ ui64 GetDefaultUnitSize() const {
+ return CurrentConfig.GetDefaultUnitSize();
+ }
+
+ ui64 GetDefaultUnitThroughput() const {
+ return CurrentConfig.GetDefaultUnitThroughput();
+ }
+
+ ui64 GetRequestSequenceSize() const {
+ return CurrentConfig.GetRequestSequenceSize();
+ }
+
+ ui64 GetMetricsWindowSize() const {
+ return CurrentConfig.GetMetricsWindowSize();
+ }
+
+ ui64 GetMinRequestSequenceSize() const {
+ return CurrentConfig.GetMinRequestSequenceSize();
+ }
+
+ ui64 GetMaxRequestSequenceSize() const {
+ return CurrentConfig.GetMaxRequestSequenceSize();
+ }
+
+ bool GetEnableFastTabletMove() const {
+ return CurrentConfig.GetEnableFastTabletMove();
+ }
+
+ TDuration GetTabletRestartsPeriod() const {
+ return TDuration::MilliSeconds(CurrentConfig.GetTabletRestartsPeriod());
+ }
+
+ ui64 GetTabletRestarsMaxCount() const {
+ return CurrentConfig.GetTabletRestarsMaxCount();
+ }
+
+ TDuration GetPostponeStartPeriod() const {
+ return TDuration::MilliSeconds(CurrentConfig.GetPostponeStartPeriod());
+ }
+
+ const std::unordered_map<TTabletTypes::EType, NKikimrConfig::THiveTabletLimit>& GetTabletLimit() const {
+ return TabletLimit;
+ }
+
+ TArrayRef<const NKikimrHive::TDataCentersGroup*> GetDefaultDataCentersPreference(TTabletTypes::EType type) {
+ auto itDCsPreference = DefaultDataCentersPreference.find(type);
+ if (itDCsPreference != DefaultDataCentersPreference.end()) {
+ return TArrayRef<const NKikimrHive::TDataCentersGroup*>(
+ const_cast<const NKikimrHive::TDataCentersGroup**>(itDCsPreference->second.GetDataCentersGroups().data()),
+ itDCsPreference->second.GetDataCentersGroups().size());
+ }
+ return {};
+ }
+
+ TResourceRawValues GetResourceInitialMaximumValues() const {
+ TResourceRawValues initialMaximum;
+ std::get<NMetrics::EResource::CPU>(initialMaximum) = CurrentConfig.GetMaxResourceCPU();
+ std::get<NMetrics::EResource::Memory>(initialMaximum) = CurrentConfig.GetMaxResourceMemory();
+ std::get<NMetrics::EResource::Network>(initialMaximum) = CurrentConfig.GetMaxResourceNetwork();
+ std::get<NMetrics::EResource::Counter>(initialMaximum) = CurrentConfig.GetMaxResourceCounter();
+ return initialMaximum;
+ }
+
+ static void ActualizeRestartStatistics(google::protobuf::RepeatedField<google::protobuf::uint64>& restartTimestamps, ui64 barrier);
+ static bool IsSystemTablet(TTabletTypes::EType type);
+
+protected:
+ void ScheduleDisconnectNode(THolder<TEvPrivate::TEvProcessDisconnectNode> event);
void DeleteTabletWithoutStorage(TLeaderTabletInfo* tablet);
- void ScheduleUnlockTabletExecution(TNodeInfo& node);
+ void ScheduleUnlockTabletExecution(TNodeInfo& node);
TString DebugDomainsActiveNodes() const;
- TResourceNormalizedValues GetStDevResourceValues() const;
- bool IsTabletMoveExpedient(const TTabletInfo& tablet, const TNodeInfo& node) const;
- TResourceRawValues GetDefaultResourceInitialMaximumValues();
- double GetScatter() const;
- double GetUsage() const;
-
- struct THiveStats {
- double MinUsage;
- TNodeId MinUsageNodeId;
- double MaxUsage;
- TNodeId MaxUsageNodeId;
- double Scatter;
- };
-
- THiveStats GetStats() const;
- void RemoveSubActor(ISubActor* subActor);
+ TResourceNormalizedValues GetStDevResourceValues() const;
+ bool IsTabletMoveExpedient(const TTabletInfo& tablet, const TNodeInfo& node) const;
+ TResourceRawValues GetDefaultResourceInitialMaximumValues();
+ double GetScatter() const;
+ double GetUsage() const;
+
+ struct THiveStats {
+ double MinUsage;
+ TNodeId MinUsageNodeId;
+ double MaxUsage;
+ TNodeId MaxUsageNodeId;
+ double Scatter;
+ };
+
+ THiveStats GetStats() const;
+ void RemoveSubActor(ISubActor* subActor);
const NKikimrLocal::TLocalConfig &GetLocalConfig() const { return LocalConfig; }
- NKikimrTabletBase::TMetrics GetDefaultResourceValuesForObject(TObjectId objectId);
+ NKikimrTabletBase::TMetrics GetDefaultResourceValuesForObject(TObjectId objectId);
NKikimrTabletBase::TMetrics GetDefaultResourceValuesForTabletType(TTabletTypes::EType type);
- NKikimrTabletBase::TMetrics GetDefaultResourceValuesForProfile(TTabletTypes::EType type, const TString& resourceProfile);
- static void AggregateMetricsMax(NKikimrTabletBase::TMetrics& aggregate, const NKikimrTabletBase::TMetrics& value);
- static void AggregateMetricsDiff(NKikimrTabletBase::TMetrics& aggregate,
- const NKikimrTabletBase::TMetrics& before,
- const NKikimrTabletBase::TMetrics& after,
- const TTabletInfo* tablet);
- static void DivideMetrics(NKikimrTabletBase::TMetrics& metrics, ui64 divider);
- TVector<TTabletId> UpdateStoragePools(const google::protobuf::RepeatedPtrField<NKikimrBlobStorage::TEvControllerSelectGroupsResult::TGroupParameters>& groups);
- void InitDefaultChannelBind(TChannelBind& bind);
- void RequestPoolsInformation();
- void RequestFreeSequence();
-
- bool SeenDomain(TSubDomainKey domain);
- void ResolveDomain(TSubDomainKey domain);
- TString GetDomainName(TSubDomainKey domain);
- TSubDomainKey GetMySubDomainKey() const;
+ NKikimrTabletBase::TMetrics GetDefaultResourceValuesForProfile(TTabletTypes::EType type, const TString& resourceProfile);
+ static void AggregateMetricsMax(NKikimrTabletBase::TMetrics& aggregate, const NKikimrTabletBase::TMetrics& value);
+ static void AggregateMetricsDiff(NKikimrTabletBase::TMetrics& aggregate,
+ const NKikimrTabletBase::TMetrics& before,
+ const NKikimrTabletBase::TMetrics& after,
+ const TTabletInfo* tablet);
+ static void DivideMetrics(NKikimrTabletBase::TMetrics& metrics, ui64 divider);
+ TVector<TTabletId> UpdateStoragePools(const google::protobuf::RepeatedPtrField<NKikimrBlobStorage::TEvControllerSelectGroupsResult::TGroupParameters>& groups);
+ void InitDefaultChannelBind(TChannelBind& bind);
+ void RequestPoolsInformation();
+ void RequestFreeSequence();
+
+ bool SeenDomain(TSubDomainKey domain);
+ void ResolveDomain(TSubDomainKey domain);
+ TString GetDomainName(TSubDomainKey domain);
+ TSubDomainKey GetMySubDomainKey() const;
};
-} // NHive
-} // NKikimr
-
-inline IOutputStream& operator <<(IOutputStream& o, NKikimr::NHive::ETabletState s) {
- return o << "ETabletState(" << static_cast<ui64>(s) << ")";
-}
+} // NHive
+} // NKikimr
+
+inline IOutputStream& operator <<(IOutputStream& o, NKikimr::NHive::ETabletState s) {
+ return o << "ETabletState(" << static_cast<ui64>(s) << ")";
+}
diff --git a/ydb/core/mind/hive/hive_impl_ut.cpp b/ydb/core/mind/hive/hive_impl_ut.cpp
index 0936c1dcadb..077c3eab24c 100644
--- a/ydb/core/mind/hive/hive_impl_ut.cpp
+++ b/ydb/core/mind/hive/hive_impl_ut.cpp
@@ -1,164 +1,164 @@
#include <library/cpp/testing/unittest/registar.h>
#include <library/cpp/testing/unittest/tests_data.h>
-#include <util/stream/null.h>
-#include "hive_impl.h"
-#include "balancer.h"
-
-#ifdef NDEBUG
-#define Ctest Cnull
-#else
-#define Ctest Cerr
-#endif
-
-#ifdef address_sanitizer_enabled
-#define SANITIZER_TYPE address
-#endif
-#ifdef memory_sanitizer_enabled
-#define SANITIZER_TYPE memory
-#endif
-#ifdef thread_sanitizer_enabled
-#define SANITIZER_TYPE thread
-#endif
-
-using namespace NKikimr;
-using namespace NHive;
-
-Y_UNIT_TEST_SUITE(THiveImplTest) {
- Y_UNIT_TEST(BootQueueSpeed) {
- TBootQueue bootQueue;
- static constexpr ui64 NUM_TABLETS = 1000000;
-
- TIntrusivePtr<TTabletStorageInfo> hiveStorage = new TTabletStorageInfo;
- hiveStorage->TabletType = TTabletTypes::Hive;
+#include <util/stream/null.h>
+#include "hive_impl.h"
+#include "balancer.h"
+
+#ifdef NDEBUG
+#define Ctest Cnull
+#else
+#define Ctest Cerr
+#endif
+
+#ifdef address_sanitizer_enabled
+#define SANITIZER_TYPE address
+#endif
+#ifdef memory_sanitizer_enabled
+#define SANITIZER_TYPE memory
+#endif
+#ifdef thread_sanitizer_enabled
+#define SANITIZER_TYPE thread
+#endif
+
+using namespace NKikimr;
+using namespace NHive;
+
+Y_UNIT_TEST_SUITE(THiveImplTest) {
+ Y_UNIT_TEST(BootQueueSpeed) {
+ TBootQueue bootQueue;
+ static constexpr ui64 NUM_TABLETS = 1000000;
+
+ TIntrusivePtr<TTabletStorageInfo> hiveStorage = new TTabletStorageInfo;
+ hiveStorage->TabletType = TTabletTypes::Hive;
THive hive(hiveStorage.Get(), TActorId());
std::unordered_map<ui64, TLeaderTabletInfo> tablets;
- THPTimer timer;
-
- for (ui64 i = 0; i < NUM_TABLETS; ++i) {
+ THPTimer timer;
+
+ for (ui64 i = 0; i < NUM_TABLETS; ++i) {
TLeaderTabletInfo& tablet = tablets.emplace(std::piecewise_construct, std::tuple<TTabletId>(i), std::tuple<TTabletId, THive&>(i, hive)).first->second;
- tablet.Weight = RandomNumber<double>();
- bootQueue.AddToBootQueue(tablet);
- }
-
- double passed = timer.Passed();
- Ctest << "Create = " << passed << Endl;
-#ifndef SANITIZER_TYPE
- UNIT_ASSERT(passed < 5);
-#endif
-
- timer.Reset();
-
- double maxP = 100;
-
- while (!bootQueue.BootQueue.empty()) {
- auto record = bootQueue.PopFromBootQueue();
- UNIT_ASSERT(record.Priority <= maxP);
- maxP = record.Priority;
- auto itTablet = tablets.find(record.TabletId.first);
- if (itTablet != tablets.end()) {
- bootQueue.AddToWaitQueue(itTablet->second);
- }
- }
-
- passed = timer.Passed();
- Ctest << "Process = " << passed << Endl;
-#ifndef SANITIZER_TYPE
- UNIT_ASSERT(passed < 2);
-#endif
-
- timer.Reset();
-
- bootQueue.MoveFromWaitQueueToBootQueue();
-
- passed = timer.Passed();
- Ctest << "Move = " << passed << Endl;
-#ifndef SANITIZER_TYPE
- UNIT_ASSERT(passed < 0.5);
-#endif
- }
-
- Y_UNIT_TEST(BalancerSpeedAndDistribution) {
- static constexpr ui64 NUM_TABLETS = 100000;
- static constexpr ui64 NUM_BUCKETS = 16;
-
- auto CheckSpeedAndDistribution = [](
- std::unordered_map<ui64, TLeaderTabletInfo>& allTablets,
- std::function<void(std::vector<TTabletInfo*>&)> func) -> void {
-
- std::vector<TTabletInfo*> tablets;
- for (auto& [id, tab] : allTablets) {
- tablets.emplace_back(&tab);
- }
-
- THPTimer timer;
-
- func(tablets);
-
- double passed = timer.Passed();
-
- Ctest << "Time=" << passed << Endl;
-#ifndef SANITIZER_TYPE
- UNIT_ASSERT(passed < 0.2);
-#endif
- std::vector<double> buckets(NUM_BUCKETS, 0);
- size_t revs = 0;
- double prev = 0;
- for (size_t n = 0; n < tablets.size(); ++n) {
- buckets[n / (NUM_TABLETS / NUM_BUCKETS)] += tablets[n]->Weight;
- if (n != 0 && tablets[n]->Weight >= prev) {
- ++revs;
- }
- prev = tablets[n]->Weight;
- }
-
- Ctest << "Indirection=" << revs * 100 / NUM_TABLETS << "%" << Endl;
-
- Ctest << "Distribution=";
- for (double v : buckets) {
- Ctest << Sprintf("%.2f", v) << " ";
- }
- Ctest << Endl;
-
- /*char bars[] = " ▁▂▃▄▅▆▇█";
- double mx = *std::max_element(buckets.begin(), buckets.end());
- for (double v : buckets) {
- Ctest << bars[int(ceil(v / mx)) * 8];
- }
- Ctest << Endl;*/
-
- /*prev = NUM_TABLETS;
- for (double v : buckets) {
- UNIT_ASSERT(v < prev);
- prev = v;
- }*/
-
- std::sort(tablets.begin(), tablets.end());
- auto unique_end = std::unique(tablets.begin(), tablets.end());
- Ctest << "Duplicates=" << tablets.end() - unique_end << Endl;
-
- UNIT_ASSERT(tablets.end() - unique_end == 0);
- };
-
- TIntrusivePtr<TTabletStorageInfo> hiveStorage = new TTabletStorageInfo;
- hiveStorage->TabletType = TTabletTypes::Hive;
- THive hive(hiveStorage.Get(), TActorId());
- std::unordered_map<ui64, TLeaderTabletInfo> allTablets;
-
- for (ui64 i = 0; i < NUM_TABLETS; ++i) {
- TLeaderTabletInfo& tablet = allTablets.emplace(std::piecewise_construct, std::tuple<TTabletId>(i), std::tuple<TTabletId, THive&>(i, hive)).first->second;
- tablet.Weight = RandomNumber<double>();
- }
-
- Ctest << "HIVE_TABLET_BALANCE_STRATEGY_HEAVIEST" << Endl;
- CheckSpeedAndDistribution(allTablets, BalanceTablets<NKikimrConfig::THiveConfig::HIVE_TABLET_BALANCE_STRATEGY_HEAVIEST>);
-
- //Ctest << "HIVE_TABLET_BALANCE_STRATEGY_OLD_WEIGHTED_RANDOM" << Endl;
- //CheckSpeedAndDistribution(allTablets, BalanceTablets<NKikimrConfig::THiveConfig::HIVE_TABLET_BALANCE_STRATEGY_OLD_WEIGHTED_RANDOM>);
-
- Ctest << "HIVE_TABLET_BALANCE_STRATEGY_WEIGHTED_RANDOM" << Endl;
- CheckSpeedAndDistribution(allTablets, BalanceTablets<NKikimrConfig::THiveConfig::HIVE_TABLET_BALANCE_STRATEGY_WEIGHTED_RANDOM>);
-
- Ctest << "HIVE_TABLET_BALANCE_STRATEGY_RANDOM" << Endl;
- CheckSpeedAndDistribution(allTablets, BalanceTablets<NKikimrConfig::THiveConfig::HIVE_TABLET_BALANCE_STRATEGY_RANDOM>);
- }
-}
+ tablet.Weight = RandomNumber<double>();
+ bootQueue.AddToBootQueue(tablet);
+ }
+
+ double passed = timer.Passed();
+ Ctest << "Create = " << passed << Endl;
+#ifndef SANITIZER_TYPE
+ UNIT_ASSERT(passed < 5);
+#endif
+
+ timer.Reset();
+
+ double maxP = 100;
+
+ while (!bootQueue.BootQueue.empty()) {
+ auto record = bootQueue.PopFromBootQueue();
+ UNIT_ASSERT(record.Priority <= maxP);
+ maxP = record.Priority;
+ auto itTablet = tablets.find(record.TabletId.first);
+ if (itTablet != tablets.end()) {
+ bootQueue.AddToWaitQueue(itTablet->second);
+ }
+ }
+
+ passed = timer.Passed();
+ Ctest << "Process = " << passed << Endl;
+#ifndef SANITIZER_TYPE
+ UNIT_ASSERT(passed < 2);
+#endif
+
+ timer.Reset();
+
+ bootQueue.MoveFromWaitQueueToBootQueue();
+
+ passed = timer.Passed();
+ Ctest << "Move = " << passed << Endl;
+#ifndef SANITIZER_TYPE
+ UNIT_ASSERT(passed < 0.5);
+#endif
+ }
+
+ Y_UNIT_TEST(BalancerSpeedAndDistribution) {
+ static constexpr ui64 NUM_TABLETS = 100000;
+ static constexpr ui64 NUM_BUCKETS = 16;
+
+ auto CheckSpeedAndDistribution = [](
+ std::unordered_map<ui64, TLeaderTabletInfo>& allTablets,
+ std::function<void(std::vector<TTabletInfo*>&)> func) -> void {
+
+ std::vector<TTabletInfo*> tablets;
+ for (auto& [id, tab] : allTablets) {
+ tablets.emplace_back(&tab);
+ }
+
+ THPTimer timer;
+
+ func(tablets);
+
+ double passed = timer.Passed();
+
+ Ctest << "Time=" << passed << Endl;
+#ifndef SANITIZER_TYPE
+ UNIT_ASSERT(passed < 0.2);
+#endif
+ std::vector<double> buckets(NUM_BUCKETS, 0);
+ size_t revs = 0;
+ double prev = 0;
+ for (size_t n = 0; n < tablets.size(); ++n) {
+ buckets[n / (NUM_TABLETS / NUM_BUCKETS)] += tablets[n]->Weight;
+ if (n != 0 && tablets[n]->Weight >= prev) {
+ ++revs;
+ }
+ prev = tablets[n]->Weight;
+ }
+
+ Ctest << "Indirection=" << revs * 100 / NUM_TABLETS << "%" << Endl;
+
+ Ctest << "Distribution=";
+ for (double v : buckets) {
+ Ctest << Sprintf("%.2f", v) << " ";
+ }
+ Ctest << Endl;
+
+ /*char bars[] = " ▁▂▃▄▅▆▇█";
+ double mx = *std::max_element(buckets.begin(), buckets.end());
+ for (double v : buckets) {
+ Ctest << bars[int(ceil(v / mx)) * 8];
+ }
+ Ctest << Endl;*/
+
+ /*prev = NUM_TABLETS;
+ for (double v : buckets) {
+ UNIT_ASSERT(v < prev);
+ prev = v;
+ }*/
+
+ std::sort(tablets.begin(), tablets.end());
+ auto unique_end = std::unique(tablets.begin(), tablets.end());
+ Ctest << "Duplicates=" << tablets.end() - unique_end << Endl;
+
+ UNIT_ASSERT(tablets.end() - unique_end == 0);
+ };
+
+ TIntrusivePtr<TTabletStorageInfo> hiveStorage = new TTabletStorageInfo;
+ hiveStorage->TabletType = TTabletTypes::Hive;
+ THive hive(hiveStorage.Get(), TActorId());
+ std::unordered_map<ui64, TLeaderTabletInfo> allTablets;
+
+ for (ui64 i = 0; i < NUM_TABLETS; ++i) {
+ TLeaderTabletInfo& tablet = allTablets.emplace(std::piecewise_construct, std::tuple<TTabletId>(i), std::tuple<TTabletId, THive&>(i, hive)).first->second;
+ tablet.Weight = RandomNumber<double>();
+ }
+
+ Ctest << "HIVE_TABLET_BALANCE_STRATEGY_HEAVIEST" << Endl;
+ CheckSpeedAndDistribution(allTablets, BalanceTablets<NKikimrConfig::THiveConfig::HIVE_TABLET_BALANCE_STRATEGY_HEAVIEST>);
+
+ //Ctest << "HIVE_TABLET_BALANCE_STRATEGY_OLD_WEIGHTED_RANDOM" << Endl;
+ //CheckSpeedAndDistribution(allTablets, BalanceTablets<NKikimrConfig::THiveConfig::HIVE_TABLET_BALANCE_STRATEGY_OLD_WEIGHTED_RANDOM>);
+
+ Ctest << "HIVE_TABLET_BALANCE_STRATEGY_WEIGHTED_RANDOM" << Endl;
+ CheckSpeedAndDistribution(allTablets, BalanceTablets<NKikimrConfig::THiveConfig::HIVE_TABLET_BALANCE_STRATEGY_WEIGHTED_RANDOM>);
+
+ Ctest << "HIVE_TABLET_BALANCE_STRATEGY_RANDOM" << Endl;
+ CheckSpeedAndDistribution(allTablets, BalanceTablets<NKikimrConfig::THiveConfig::HIVE_TABLET_BALANCE_STRATEGY_RANDOM>);
+ }
+}
diff --git a/ydb/core/mind/hive/hive_log.cpp b/ydb/core/mind/hive/hive_log.cpp
index 2ae154873b9..c1c7f100449 100644
--- a/ydb/core/mind/hive/hive_log.cpp
+++ b/ydb/core/mind/hive/hive_log.cpp
@@ -1,13 +1,13 @@
-#include "hive_impl.h"
-#include "hive_log.h"
-
-namespace NKikimr {
-namespace NHive {
-
-TString GetLogPrefix() {
- return TString();
-}
-
-}
-}
-
+#include "hive_impl.h"
+#include "hive_log.h"
+
+namespace NKikimr {
+namespace NHive {
+
+TString GetLogPrefix() {
+ return TString();
+}
+
+}
+}
+
diff --git a/ydb/core/mind/hive/hive_log.h b/ydb/core/mind/hive/hive_log.h
index c5680906c88..c2c124db33c 100644
--- a/ydb/core/mind/hive/hive_log.h
+++ b/ydb/core/mind/hive/hive_log.h
@@ -1,39 +1,39 @@
-#pragma once
-
-#if defined BLOG_D || defined BLOG_I || defined BLOG_ERROR || defined BLOG_TRACE
-#error log macro definition clash
-#endif
-
-namespace NKikimr {
-namespace NHive {
-
-TString GetLogPrefix();
-
-template <typename T>
-class TTransactionBase : public NKikimr::NTabletFlatExecutor::TTransactionBase<T> {
-protected:
- using TSelf = T;
- using TBase = TTransactionBase<T>;
-
-public:
- TTransactionBase(T* self)
- : NKikimr::NTabletFlatExecutor::TTransactionBase<T>(self)
- {}
-
- TString GetLogPrefix() const {
- return NKikimr::NTabletFlatExecutor::TTransactionBase<T>::Self->GetLogPrefix();
- }
-};
-
-}
-}
-
-#define BLOG_D(stream) LOG_DEBUG_S(*TlsActivationContext, NKikimrServices::HIVE, GetLogPrefix() << stream)
-#define BLOG_I(stream) LOG_INFO_S(*TlsActivationContext, NKikimrServices::HIVE, GetLogPrefix() << stream)
-#define BLOG_W(stream) LOG_WARN_S(*TlsActivationContext, NKikimrServices::HIVE, GetLogPrefix() << stream)
-#define BLOG_NOTICE(stream) LOG_NOTICE_S(*TlsActivationContext, NKikimrServices::HIVE, GetLogPrefix() << stream)
-#define BLOG_ERROR(stream) LOG_ERROR_S(*TlsActivationContext, NKikimrServices::HIVE, GetLogPrefix() << stream)
-#define BLOG_CRIT(stream) LOG_CRIT_S(*TlsActivationContext, NKikimrServices::HIVE, GetLogPrefix() << stream)
-#define BLOG_TRACE(stream) LOG_TRACE_S(*TlsActivationContext, NKikimrServices::HIVE, GetLogPrefix() << stream)
-#define Y_ENSURE_LOG(cond, stream) if (!(cond)) { BLOG_ERROR("Failed condition \"" << #cond << "\" " << stream); }
-
+#pragma once
+
+#if defined BLOG_D || defined BLOG_I || defined BLOG_ERROR || defined BLOG_TRACE
+#error log macro definition clash
+#endif
+
+namespace NKikimr {
+namespace NHive {
+
+TString GetLogPrefix();
+
+template <typename T>
+class TTransactionBase : public NKikimr::NTabletFlatExecutor::TTransactionBase<T> {
+protected:
+ using TSelf = T;
+ using TBase = TTransactionBase<T>;
+
+public:
+ TTransactionBase(T* self)
+ : NKikimr::NTabletFlatExecutor::TTransactionBase<T>(self)
+ {}
+
+ TString GetLogPrefix() const {
+ return NKikimr::NTabletFlatExecutor::TTransactionBase<T>::Self->GetLogPrefix();
+ }
+};
+
+}
+}
+
+#define BLOG_D(stream) LOG_DEBUG_S(*TlsActivationContext, NKikimrServices::HIVE, GetLogPrefix() << stream)
+#define BLOG_I(stream) LOG_INFO_S(*TlsActivationContext, NKikimrServices::HIVE, GetLogPrefix() << stream)
+#define BLOG_W(stream) LOG_WARN_S(*TlsActivationContext, NKikimrServices::HIVE, GetLogPrefix() << stream)
+#define BLOG_NOTICE(stream) LOG_NOTICE_S(*TlsActivationContext, NKikimrServices::HIVE, GetLogPrefix() << stream)
+#define BLOG_ERROR(stream) LOG_ERROR_S(*TlsActivationContext, NKikimrServices::HIVE, GetLogPrefix() << stream)
+#define BLOG_CRIT(stream) LOG_CRIT_S(*TlsActivationContext, NKikimrServices::HIVE, GetLogPrefix() << stream)
+#define BLOG_TRACE(stream) LOG_TRACE_S(*TlsActivationContext, NKikimrServices::HIVE, GetLogPrefix() << stream)
+#define Y_ENSURE_LOG(cond, stream) if (!(cond)) { BLOG_ERROR("Failed condition \"" << #cond << "\" " << stream); }
+
diff --git a/ydb/core/mind/hive/hive_schema.h b/ydb/core/mind/hive/hive_schema.h
index 94ff3e9ee14..6289499cc31 100644
--- a/ydb/core/mind/hive/hive_schema.h
+++ b/ydb/core/mind/hive/hive_schema.h
@@ -1,310 +1,310 @@
-#pragma once
-
+#pragma once
+
#include <ydb/core/tablet_flat/flat_cxx_database.h>
#include <ydb/core/protos/metrics.pb.h>
-#include "hive.h"
-
-namespace NKikimr {
-namespace NHive {
-
-struct TSchemeIds {
- enum State {
- NextTabletId,
- DefaultState = NextTabletId,
- DatabaseVersion,
- MaxTabletsScheduled,
- MaxResourceCounter,
- MaxResourceCPU,
- MaxResourceMemory,
- MaxResourceNetwork,
- MinScatterToBalance,
- SpreadNeighbours,
- MaxBootBatchSize,
- DrainInflight,
- DefaultUnitIOPS,
- DefaultUnitThroughput,
- DefaultUnitSize,
- StorageOvercommit,
- StorageBalanceStrategy,
- StorageSafeMode,
- StorageSelectStrategy,
- RequestSequenceSize,
- MinRequestSequenceSize,
- MaxRequestSequenceSize,
- MetricsWindowSize,
- MaxNodeUsageToKick,
- ResourceChangeReactionPeriod,
- TabletKickCooldownPeriod,
- ResourceOvercommitment,
- };
-};
-
-struct Schema : NIceDb::Schema {
- struct State : Table<0> {
- struct KeyCol : Column<0, NScheme::NTypeIds::Uint64> { static TString GetColumnName(const TString&) { return "Key"; } using Type = TSchemeIds::State; };
- struct Value : Column<1, NScheme::NTypeIds::Uint64> {};
- struct Config : Column<2, NScheme::NTypeIds::String> { using Type = NKikimrConfig::THiveConfig; };
-
- using TKey = TableKey<KeyCol>;
- using TColumns = TableColumns<KeyCol, Value, Config>;
- };
-
- struct OldTablet : Table<1> {
- struct ID : Column<0, NScheme::NTypeIds::Uint64> {};
+#include "hive.h"
+
+namespace NKikimr {
+namespace NHive {
+
+struct TSchemeIds {
+ enum State {
+ NextTabletId,
+ DefaultState = NextTabletId,
+ DatabaseVersion,
+ MaxTabletsScheduled,
+ MaxResourceCounter,
+ MaxResourceCPU,
+ MaxResourceMemory,
+ MaxResourceNetwork,
+ MinScatterToBalance,
+ SpreadNeighbours,
+ MaxBootBatchSize,
+ DrainInflight,
+ DefaultUnitIOPS,
+ DefaultUnitThroughput,
+ DefaultUnitSize,
+ StorageOvercommit,
+ StorageBalanceStrategy,
+ StorageSafeMode,
+ StorageSelectStrategy,
+ RequestSequenceSize,
+ MinRequestSequenceSize,
+ MaxRequestSequenceSize,
+ MetricsWindowSize,
+ MaxNodeUsageToKick,
+ ResourceChangeReactionPeriod,
+ TabletKickCooldownPeriod,
+ ResourceOvercommitment,
+ };
+};
+
+struct Schema : NIceDb::Schema {
+ struct State : Table<0> {
+ struct KeyCol : Column<0, NScheme::NTypeIds::Uint64> { static TString GetColumnName(const TString&) { return "Key"; } using Type = TSchemeIds::State; };
+ struct Value : Column<1, NScheme::NTypeIds::Uint64> {};
+ struct Config : Column<2, NScheme::NTypeIds::String> { using Type = NKikimrConfig::THiveConfig; };
+
+ using TKey = TableKey<KeyCol>;
+ using TColumns = TableColumns<KeyCol, Value, Config>;
+ };
+
+ struct OldTablet : Table<1> {
+ struct ID : Column<0, NScheme::NTypeIds::Uint64> {};
struct FollowerCount : Column<14, NScheme::NTypeIds::Uint32> { static constexpr ui32 Default = 0; };
struct AllowFollowerPromotion : Column<15, NScheme::NTypeIds::Bool> { static constexpr bool Default = false; };
struct CrossDataCenterFollowers : Column<16, NScheme::NTypeIds::Bool> { static constexpr bool Default = false; };
struct CrossDataCenterFollowerCount : Column<18, NScheme::NTypeIds::Uint32> { static constexpr ui32 Default = 0; };
-
- using TKey = TableKey<ID>;
+
+ using TKey = TableKey<ID>;
using TColumns = TableColumns<ID, FollowerCount, AllowFollowerPromotion, CrossDataCenterFollowers, CrossDataCenterFollowerCount>;
- };
-
- struct Tablet : Table<1> {
- struct ID : Column<0, NScheme::NTypeIds::Uint64> {};
- struct Owner : Column<1, NScheme::NTypeIds::PairUi64Ui64> {};
- struct KnownGeneration : Column<2, NScheme::NTypeIds::Uint64> {};
- struct TabletType : Column<3, NScheme::NTypeIds::Uint64> { using Type = TTabletTypes::EType; };
+ };
+
+ struct Tablet : Table<1> {
+ struct ID : Column<0, NScheme::NTypeIds::Uint64> {};
+ struct Owner : Column<1, NScheme::NTypeIds::PairUi64Ui64> {};
+ struct KnownGeneration : Column<2, NScheme::NTypeIds::Uint64> {};
+ struct TabletType : Column<3, NScheme::NTypeIds::Uint64> { using Type = TTabletTypes::EType; };
struct LeaderNode : Column<4, NScheme::NTypeIds::Uint64> {};
- struct State : Column<5, NScheme::NTypeIds::Uint64> { using Type = ETabletState; };
- struct AllowedNodes : Column<7, NScheme::NTypeIds::String> { using Type = TVector<TNodeId>; };
- struct ActorToNotify : Column<11, NScheme::NTypeIds::ActorId> {}; // deprecated because of ActorsToNotify down here
- //struct Weight : Column<12, NScheme::NTypeIds::Uint64> {};
- struct Category : Column<13, NScheme::NTypeIds::Uint64> {};
+ struct State : Column<5, NScheme::NTypeIds::Uint64> { using Type = ETabletState; };
+ struct AllowedNodes : Column<7, NScheme::NTypeIds::String> { using Type = TVector<TNodeId>; };
+ struct ActorToNotify : Column<11, NScheme::NTypeIds::ActorId> {}; // deprecated because of ActorsToNotify down here
+ //struct Weight : Column<12, NScheme::NTypeIds::Uint64> {};
+ struct Category : Column<13, NScheme::NTypeIds::Uint64> {};
struct AllowedDataCenters : Column<17, NScheme::NTypeIds::String> { using Type = TVector<ui32>; };
- struct TabletStorageVersion : Column<18, NScheme::NTypeIds::Uint32> { static constexpr ui32 Default = 0; };
- struct ObjectID : Column<19, NScheme::NTypeIds::Uint64> { using Type = TObjectId; };
+ struct TabletStorageVersion : Column<18, NScheme::NTypeIds::Uint32> { static constexpr ui32 Default = 0; };
+ struct ObjectID : Column<19, NScheme::NTypeIds::Uint64> { using Type = TObjectId; };
struct ActorsToNotify : Column<111, NScheme::NTypeIds::String> { using Type = TVector<TActorId>; };
- struct AllowedDomains : Column<112, NScheme::NTypeIds::String> { using Type = TVector<TSubDomainKey>; }; //order sets priority
- struct BootMode : Column<113, NScheme::NTypeIds::Uint64> { using Type = NKikimrHive::ETabletBootMode; static constexpr NKikimrHive::ETabletBootMode Default = NKikimrHive::TABLET_BOOT_MODE_DEFAULT; };
+ struct AllowedDomains : Column<112, NScheme::NTypeIds::String> { using Type = TVector<TSubDomainKey>; }; //order sets priority
+ struct BootMode : Column<113, NScheme::NTypeIds::Uint64> { using Type = NKikimrHive::ETabletBootMode; static constexpr NKikimrHive::ETabletBootMode Default = NKikimrHive::TABLET_BOOT_MODE_DEFAULT; };
struct LockedToActor : Column<114, NScheme::NTypeIds::String> { using Type = TActorId; };
- struct LockedReconnectTimeout : Column<115, NScheme::NTypeIds::Uint64> { static constexpr ui64 Default = 0; };
- struct ObjectDomain : Column<116, NScheme::NTypeIds::String> { using Type = NKikimrSubDomains::TDomainKey; };
-
- struct SeizedByChild : Column<117, NScheme::NTypeIds::Bool> {};
- struct NeedToReleaseFromParent : Column<118, NScheme::NTypeIds::Bool> {};
-
- struct ReassignReason : Column<119, NScheme::NTypeIds::Uint64> {
- using Type = NKikimrHive::TEvReassignTablet::EHiveReassignReason;
- static constexpr NKikimrHive::TEvReassignTablet::EHiveReassignReason Default = NKikimrHive::TEvReassignTablet::HIVE_REASSIGN_REASON_NO;
- };
- struct Statistics : Column<120, NScheme::NTypeIds::String> { using Type = NKikimrHive::TTabletStatistics; };
- struct DataCentersPreference : Column<121, NScheme::NTypeIds::String> { using Type = NKikimrHive::TDataCentersPreference; };
+ struct LockedReconnectTimeout : Column<115, NScheme::NTypeIds::Uint64> { static constexpr ui64 Default = 0; };
+ struct ObjectDomain : Column<116, NScheme::NTypeIds::String> { using Type = NKikimrSubDomains::TDomainKey; };
+
+ struct SeizedByChild : Column<117, NScheme::NTypeIds::Bool> {};
+ struct NeedToReleaseFromParent : Column<118, NScheme::NTypeIds::Bool> {};
+
+ struct ReassignReason : Column<119, NScheme::NTypeIds::Uint64> {
+ using Type = NKikimrHive::TEvReassignTablet::EHiveReassignReason;
+ static constexpr NKikimrHive::TEvReassignTablet::EHiveReassignReason Default = NKikimrHive::TEvReassignTablet::HIVE_REASSIGN_REASON_NO;
+ };
+ struct Statistics : Column<120, NScheme::NTypeIds::String> { using Type = NKikimrHive::TTabletStatistics; };
+ struct DataCentersPreference : Column<121, NScheme::NTypeIds::String> { using Type = NKikimrHive::TDataCentersPreference; };
struct AllowedDataCenterIds : Column<122, NScheme::NTypeIds::String> { using Type = TVector<TString>; };
-
- using TKey = TableKey<ID>;
- using TColumns = TableColumns<
- ID,
- Owner,
- KnownGeneration,
- TabletType,
+
+ using TKey = TableKey<ID>;
+ using TColumns = TableColumns<
+ ID,
+ Owner,
+ KnownGeneration,
+ TabletType,
LeaderNode,
- State,
- AllowedNodes,
- ActorToNotify,
- Category,
- AllowedDataCenters,
- TabletStorageVersion,
- ObjectID,
- ActorsToNotify,
- AllowedDomains,
- BootMode,
- LockedToActor,
- LockedReconnectTimeout,
- ObjectDomain,
- SeizedByChild,
- NeedToReleaseFromParent,
- ReassignReason,
- Statistics,
+ State,
+ AllowedNodes,
+ ActorToNotify,
+ Category,
+ AllowedDataCenters,
+ TabletStorageVersion,
+ ObjectID,
+ ActorsToNotify,
+ AllowedDomains,
+ BootMode,
+ LockedToActor,
+ LockedReconnectTimeout,
+ ObjectDomain,
+ SeizedByChild,
+ NeedToReleaseFromParent,
+ ReassignReason,
+ Statistics,
DataCentersPreference,
AllowedDataCenterIds
- >;
- };
-
+ >;
+ };
+
struct TabletFollowerGroup : Table<9> {
- struct TabletID : Column<1, Schema::Tablet::ID::ColumnType> {};
- struct GroupID : Column<2, NScheme::NTypeIds::Uint32> {};
+ struct TabletID : Column<1, Schema::Tablet::ID::ColumnType> {};
+ struct GroupID : Column<2, NScheme::NTypeIds::Uint32> {};
struct FollowerCount : Column<3, NScheme::NTypeIds::Uint32> {};
struct AllowLeaderPromotion : Column<4, NScheme::NTypeIds::Bool> { static constexpr bool Default = false; };
- struct AllowClientRead : Column<5, NScheme::NTypeIds::Bool> { static constexpr bool Default = false; };
- struct AllowedNodes : Column<6, NScheme::NTypeIds::String> { using Type = TVector<TNodeId>; };
+ struct AllowClientRead : Column<5, NScheme::NTypeIds::Bool> { static constexpr bool Default = false; };
+ struct AllowedNodes : Column<6, NScheme::NTypeIds::String> { using Type = TVector<TNodeId>; };
struct AllowedDataCenters : Column<7, NScheme::NTypeIds::String> { using Type = TVector<ui32>; };
- struct RequireAllDataCenters : Column<8, NScheme::NTypeIds::Bool> {};
- struct LocalNodeOnly : Column<9, NScheme::NTypeIds::Bool> { static constexpr bool Default = false; };
+ struct RequireAllDataCenters : Column<8, NScheme::NTypeIds::Bool> {};
+ struct LocalNodeOnly : Column<9, NScheme::NTypeIds::Bool> { static constexpr bool Default = false; };
struct FollowerCountPerDataCenter : Column<10, NScheme::NTypeIds::Bool> { static constexpr bool Default = false; };
- struct RequireDifferentNodes : Column<11, NScheme::NTypeIds::Bool> {};
+ struct RequireDifferentNodes : Column<11, NScheme::NTypeIds::Bool> {};
struct AllowedDataCenterIds : Column<12, NScheme::NTypeIds::String> { using Type = TVector<TString>; };
-
- using TKey = TableKey<TabletID, GroupID>;
+
+ using TKey = TableKey<TabletID, GroupID>;
using TColumns = TableColumns<TabletID, GroupID, FollowerCount, AllowLeaderPromotion, AllowClientRead,
- AllowedNodes, AllowedDataCenters, RequireAllDataCenters, LocalNodeOnly,
+ AllowedNodes, AllowedDataCenters, RequireAllDataCenters, LocalNodeOnly,
FollowerCountPerDataCenter, RequireDifferentNodes, AllowedDataCenterIds>;
- };
-
+ };
+
struct TabletFollowerTablet : Table<10> {
- struct TabletID : Column<1, Schema::Tablet::ID::ColumnType> {};
+ struct TabletID : Column<1, Schema::Tablet::ID::ColumnType> {};
struct FollowerID : Column<2, NScheme::NTypeIds::Uint32> {};
struct GroupID : Column<3, Schema::TabletFollowerGroup::GroupID::ColumnType> {};
struct FollowerNode : Column<4, NScheme::NTypeIds::Uint32> {};
- struct Statistics : Column<5, NScheme::NTypeIds::String> { using Type = NKikimrHive::TTabletStatistics; };
-
+ struct Statistics : Column<5, NScheme::NTypeIds::String> { using Type = NKikimrHive::TTabletStatistics; };
+
using TKey = TableKey<TabletID, FollowerID>;
- using TColumns = TableColumns<TabletID, GroupID, FollowerID, FollowerNode, Statistics>;
- };
-
- struct TabletChannel : Table<2> {
- struct Tablet : Column<0, Schema::Tablet::ID::ColumnType> {};
- struct Channel : Column<1, NScheme::NTypeIds::Uint64> {};
- //struct ErasureSpecies : Column<2, NScheme::NTypeIds::Uint64> { using Type = TBlobStorageGroupType::EErasureSpecies; };
- //struct PDiskCategory : Column<3, NScheme::NTypeIds::Uint64> {};
- //struct VDiskCategory : Column<4, NScheme::NTypeIds::Uint64> { using Type = NKikimrBlobStorage::TVDiskKind::EVDiskKind; };
- struct NeedNewGroup : Column<5, NScheme::NTypeIds::Bool> { static constexpr bool Default = false; };
- struct StoragePool : Column<7, NScheme::NTypeIds::Utf8> {};
- struct Binding : Column<8, NScheme::NTypeIds::String> { using Type = NKikimrStoragePool::TChannelBind; };
-
- using TKey = TableKey<Tablet, Channel>;
- using TColumns = TableColumns<Tablet, Channel, NeedNewGroup, StoragePool, Binding>;
- };
-
- struct TabletChannelGen : Table<3> {
- struct Tablet : Column<0, TabletChannel::Tablet::ColumnType> {};
- struct Channel : Column<1, TabletChannel::Channel::ColumnType> {};
- struct Generation : Column<2, NScheme::NTypeIds::Uint64> {};
- struct Group : Column<3, NScheme::NTypeIds::Uint64> {};
- struct Version : Column<4, NScheme::NTypeIds::Uint64> {};
- struct Timestamp : Column<5, NScheme::NTypeIds::Uint64> {};
-
- using TKey = TableKey<Tablet, Channel, Generation>;
- using TColumns = TableColumns<Tablet, Channel, Generation, Group, Version, Timestamp>;
- };
-
- struct Node : Table<4> {
- struct ID : Column<0, NScheme::NTypeIds::Uint64> {};
- struct Local : Column<1, NScheme::NTypeIds::ActorId> {};
- struct Down : Column<2, NScheme::NTypeIds::Bool> { static constexpr bool Default = false; };
- struct Freeze : Column<3, NScheme::NTypeIds::Bool> { static constexpr bool Default = false; };
- struct ServicedDomains : Column<4, NScheme::NTypeIds::String> { using Type = TVector<TSubDomainKey>; };
- struct Statistics : Column<5, NScheme::NTypeIds::String> { using Type = NKikimrHive::TNodeStatistics; };
- struct Drain : Column<6, NScheme::NTypeIds::Bool> { static constexpr bool Default = false; };
- struct DrainInitiators : Column<8, NScheme::NTypeIds::String> { using Type = TVector<TActorId>; };
- struct Location : Column<9, NScheme::NTypeIds::String> { using Type = NActorsInterconnect::TNodeLocation; };
-
- using TKey = TableKey<ID>;
- using TColumns = TableColumns<ID, Local, Down, Freeze, ServicedDomains, Statistics, Drain, DrainInitiators, Location>;
- };
-
- struct TabletCategory : Table<6> {
- struct ID : Column<0, NScheme::NTypeIds::Uint64> {};
- struct MaxDisconnectTimeout : Column<1, NScheme::NTypeIds::Uint64> {};
- struct StickTogetherInDC : Column<2, NScheme::NTypeIds::Bool> {};
-
- using TKey = TableKey<ID>;
- using TColumns = TableColumns<ID, MaxDisconnectTimeout, StickTogetherInDC>;
- };
-
- struct OldTabletMetrics : Table<7> {
- struct TabletID : Column<1, Tablet::ID::ColumnType> {};
-
- struct CPU : Column<300 + (int)NMetrics::EResource::CPU, NScheme::NTypeIds::Uint64> {};
- struct Memory : Column<300 + (int)NMetrics::EResource::Memory, NScheme::NTypeIds::Uint64> {};
- struct Network : Column<300 + (int)NMetrics::EResource::Network, NScheme::NTypeIds::Uint64> {};
- struct Metrics : Column<500, NScheme::NTypeIds::String> { using Type = NKikimrTabletBase::TMetrics; };
-
- using TKey = TableKey<TabletID>;
- using TColumns = TableColumns<TabletID, CPU, Memory, Network, Metrics>;
- };
-
+ using TColumns = TableColumns<TabletID, GroupID, FollowerID, FollowerNode, Statistics>;
+ };
+
+ struct TabletChannel : Table<2> {
+ struct Tablet : Column<0, Schema::Tablet::ID::ColumnType> {};
+ struct Channel : Column<1, NScheme::NTypeIds::Uint64> {};
+ //struct ErasureSpecies : Column<2, NScheme::NTypeIds::Uint64> { using Type = TBlobStorageGroupType::EErasureSpecies; };
+ //struct PDiskCategory : Column<3, NScheme::NTypeIds::Uint64> {};
+ //struct VDiskCategory : Column<4, NScheme::NTypeIds::Uint64> { using Type = NKikimrBlobStorage::TVDiskKind::EVDiskKind; };
+ struct NeedNewGroup : Column<5, NScheme::NTypeIds::Bool> { static constexpr bool Default = false; };
+ struct StoragePool : Column<7, NScheme::NTypeIds::Utf8> {};
+ struct Binding : Column<8, NScheme::NTypeIds::String> { using Type = NKikimrStoragePool::TChannelBind; };
+
+ using TKey = TableKey<Tablet, Channel>;
+ using TColumns = TableColumns<Tablet, Channel, NeedNewGroup, StoragePool, Binding>;
+ };
+
+ struct TabletChannelGen : Table<3> {
+ struct Tablet : Column<0, TabletChannel::Tablet::ColumnType> {};
+ struct Channel : Column<1, TabletChannel::Channel::ColumnType> {};
+ struct Generation : Column<2, NScheme::NTypeIds::Uint64> {};
+ struct Group : Column<3, NScheme::NTypeIds::Uint64> {};
+ struct Version : Column<4, NScheme::NTypeIds::Uint64> {};
+ struct Timestamp : Column<5, NScheme::NTypeIds::Uint64> {};
+
+ using TKey = TableKey<Tablet, Channel, Generation>;
+ using TColumns = TableColumns<Tablet, Channel, Generation, Group, Version, Timestamp>;
+ };
+
+ struct Node : Table<4> {
+ struct ID : Column<0, NScheme::NTypeIds::Uint64> {};
+ struct Local : Column<1, NScheme::NTypeIds::ActorId> {};
+ struct Down : Column<2, NScheme::NTypeIds::Bool> { static constexpr bool Default = false; };
+ struct Freeze : Column<3, NScheme::NTypeIds::Bool> { static constexpr bool Default = false; };
+ struct ServicedDomains : Column<4, NScheme::NTypeIds::String> { using Type = TVector<TSubDomainKey>; };
+ struct Statistics : Column<5, NScheme::NTypeIds::String> { using Type = NKikimrHive::TNodeStatistics; };
+ struct Drain : Column<6, NScheme::NTypeIds::Bool> { static constexpr bool Default = false; };
+ struct DrainInitiators : Column<8, NScheme::NTypeIds::String> { using Type = TVector<TActorId>; };
+ struct Location : Column<9, NScheme::NTypeIds::String> { using Type = NActorsInterconnect::TNodeLocation; };
+
+ using TKey = TableKey<ID>;
+ using TColumns = TableColumns<ID, Local, Down, Freeze, ServicedDomains, Statistics, Drain, DrainInitiators, Location>;
+ };
+
+ struct TabletCategory : Table<6> {
+ struct ID : Column<0, NScheme::NTypeIds::Uint64> {};
+ struct MaxDisconnectTimeout : Column<1, NScheme::NTypeIds::Uint64> {};
+ struct StickTogetherInDC : Column<2, NScheme::NTypeIds::Bool> {};
+
+ using TKey = TableKey<ID>;
+ using TColumns = TableColumns<ID, MaxDisconnectTimeout, StickTogetherInDC>;
+ };
+
+ struct OldTabletMetrics : Table<7> {
+ struct TabletID : Column<1, Tablet::ID::ColumnType> {};
+
+ struct CPU : Column<300 + (int)NMetrics::EResource::CPU, NScheme::NTypeIds::Uint64> {};
+ struct Memory : Column<300 + (int)NMetrics::EResource::Memory, NScheme::NTypeIds::Uint64> {};
+ struct Network : Column<300 + (int)NMetrics::EResource::Network, NScheme::NTypeIds::Uint64> {};
+ struct Metrics : Column<500, NScheme::NTypeIds::String> { using Type = NKikimrTabletBase::TMetrics; };
+
+ using TKey = TableKey<TabletID>;
+ using TColumns = TableColumns<TabletID, CPU, Memory, Network, Metrics>;
+ };
+
struct Metrics : Table<16> {
struct TabletID : Column<1, Tablet::ID::ColumnType> {};
struct FollowerID : Column<2, TabletFollowerTablet::FollowerID::ColumnType> {};
struct ProtoMetrics : Column<3, NScheme::NTypeIds::String> { using Type = NKikimrTabletBase::TMetrics; };
- struct MaximumCPU : Column<100 + (int)NMetrics::EResource::CPU, NScheme::NTypeIds::String> { using Type = NKikimrMetricsProto::TMaximumValueUI64; };
- struct MaximumMemory : Column<100 + (int)NMetrics::EResource::Memory, NScheme::NTypeIds::String> { using Type = NKikimrMetricsProto::TMaximumValueUI64; };
- struct MaximumNetwork : Column<100 + (int)NMetrics::EResource::Network, NScheme::NTypeIds::String> { using Type = NKikimrMetricsProto::TMaximumValueUI64; };
-
+ struct MaximumCPU : Column<100 + (int)NMetrics::EResource::CPU, NScheme::NTypeIds::String> { using Type = NKikimrMetricsProto::TMaximumValueUI64; };
+ struct MaximumMemory : Column<100 + (int)NMetrics::EResource::Memory, NScheme::NTypeIds::String> { using Type = NKikimrMetricsProto::TMaximumValueUI64; };
+ struct MaximumNetwork : Column<100 + (int)NMetrics::EResource::Network, NScheme::NTypeIds::String> { using Type = NKikimrMetricsProto::TMaximumValueUI64; };
+
using TKey = TableKey<TabletID, FollowerID>;
using TColumns = TableColumns<TabletID, FollowerID, ProtoMetrics, MaximumCPU, MaximumMemory, MaximumNetwork>;
};
- struct TabletTypeMetrics : Table<13> {
- struct TabletType : Column<1, Tablet::TabletType::ColumnType> { using Type = TTabletTypes::EType; };
- struct AllowedMetricIDs : Column<2, NScheme::NTypeIds::String> { using Type = TVector<i64>; };
-
- using TKey = TableKey<TabletType>;
- using TColumns = TableColumns<TabletType, AllowedMetricIDs>;
- };
-
- struct Sequences : Table<14> {
- struct OwnerId : Column<1, NScheme::NTypeIds::Uint64> {};
- struct OwnerIdx : Column<2, NScheme::NTypeIds::Uint64> {};
- struct Begin : Column<3, NScheme::NTypeIds::Uint64> {};
- struct End : Column<4, NScheme::NTypeIds::Uint64> {};
- struct Next : Column<5, NScheme::NTypeIds::Uint64> {};
-
- using TKey = TableKey<OwnerId, OwnerIdx>;
- using TColumns = TableColumns<OwnerId, OwnerIdx, Begin, End, Next>;
- };
-
- /*struct PendingCreateTablet : Table<15> {
- struct OwnerId : Column<1, NScheme::NTypeIds::Uint64> {};
- struct OwnerIdx : Column<2, NScheme::NTypeIds::Uint64> {};
- struct RequestData : Column<3, NScheme::NTypeIds::String> { using Type = NKikimrHive::TEvCreateTablet; };
- struct Sender : Column<4, NScheme::NTypeIds::ActorId> {};
- struct Cookie : Column<5, NScheme::NTypeIds::Uint64> {};
-
- using TKey = TableKey<OwnerId, OwnerIdx>;
- using TColumns = TableColumns<OwnerId, OwnerIdx, RequestData, Sender, Cookie>;
- };*/
-
- struct SubDomain : Table<17> {
- struct SchemeshardId : Column<1, NScheme::NTypeIds::Uint64> {};
- struct PathId : Column<2, NScheme::NTypeIds::Uint64> {};
- struct Path : Column<3, NScheme::NTypeIds::Utf8> {};
- struct Primary : Column<4, NScheme::NTypeIds::Bool> {};
- struct HiveId : Column<5, NScheme::NTypeIds::Uint64> {};
-
- using TKey = TableKey<SchemeshardId, PathId>;
- using TColumns = TableColumns<SchemeshardId, PathId, Path, Primary, HiveId>;
- };
-
- struct BlockedOwner : Table<18> {
- struct OwnerId : Column<1, NScheme::NTypeIds::Uint64> {};
-
- using TKey = TableKey<OwnerId>;
- using TColumns = TableColumns<OwnerId>;
- };
-
- struct TabletOwners : Table<19> {
- struct Begin : Column<1, NScheme::NTypeIds::Uint64> {};
- struct End : Column<2, NScheme::NTypeIds::Uint64> {};
- struct OwnerId : Column<3, NScheme::NTypeIds::Uint64> {};
-
- using TKey = TableKey<Begin, End>;
- using TColumns = TableColumns<Begin, End, OwnerId>;
- };
-
- using TTables = SchemaTables<
- State,
- Tablet,
- TabletChannel,
- TabletChannelGen,
- Node,
- TabletCategory,
+ struct TabletTypeMetrics : Table<13> {
+ struct TabletType : Column<1, Tablet::TabletType::ColumnType> { using Type = TTabletTypes::EType; };
+ struct AllowedMetricIDs : Column<2, NScheme::NTypeIds::String> { using Type = TVector<i64>; };
+
+ using TKey = TableKey<TabletType>;
+ using TColumns = TableColumns<TabletType, AllowedMetricIDs>;
+ };
+
+ struct Sequences : Table<14> {
+ struct OwnerId : Column<1, NScheme::NTypeIds::Uint64> {};
+ struct OwnerIdx : Column<2, NScheme::NTypeIds::Uint64> {};
+ struct Begin : Column<3, NScheme::NTypeIds::Uint64> {};
+ struct End : Column<4, NScheme::NTypeIds::Uint64> {};
+ struct Next : Column<5, NScheme::NTypeIds::Uint64> {};
+
+ using TKey = TableKey<OwnerId, OwnerIdx>;
+ using TColumns = TableColumns<OwnerId, OwnerIdx, Begin, End, Next>;
+ };
+
+ /*struct PendingCreateTablet : Table<15> {
+ struct OwnerId : Column<1, NScheme::NTypeIds::Uint64> {};
+ struct OwnerIdx : Column<2, NScheme::NTypeIds::Uint64> {};
+ struct RequestData : Column<3, NScheme::NTypeIds::String> { using Type = NKikimrHive::TEvCreateTablet; };
+ struct Sender : Column<4, NScheme::NTypeIds::ActorId> {};
+ struct Cookie : Column<5, NScheme::NTypeIds::Uint64> {};
+
+ using TKey = TableKey<OwnerId, OwnerIdx>;
+ using TColumns = TableColumns<OwnerId, OwnerIdx, RequestData, Sender, Cookie>;
+ };*/
+
+ struct SubDomain : Table<17> {
+ struct SchemeshardId : Column<1, NScheme::NTypeIds::Uint64> {};
+ struct PathId : Column<2, NScheme::NTypeIds::Uint64> {};
+ struct Path : Column<3, NScheme::NTypeIds::Utf8> {};
+ struct Primary : Column<4, NScheme::NTypeIds::Bool> {};
+ struct HiveId : Column<5, NScheme::NTypeIds::Uint64> {};
+
+ using TKey = TableKey<SchemeshardId, PathId>;
+ using TColumns = TableColumns<SchemeshardId, PathId, Path, Primary, HiveId>;
+ };
+
+ struct BlockedOwner : Table<18> {
+ struct OwnerId : Column<1, NScheme::NTypeIds::Uint64> {};
+
+ using TKey = TableKey<OwnerId>;
+ using TColumns = TableColumns<OwnerId>;
+ };
+
+ struct TabletOwners : Table<19> {
+ struct Begin : Column<1, NScheme::NTypeIds::Uint64> {};
+ struct End : Column<2, NScheme::NTypeIds::Uint64> {};
+ struct OwnerId : Column<3, NScheme::NTypeIds::Uint64> {};
+
+ using TKey = TableKey<Begin, End>;
+ using TColumns = TableColumns<Begin, End, OwnerId>;
+ };
+
+ using TTables = SchemaTables<
+ State,
+ Tablet,
+ TabletChannel,
+ TabletChannelGen,
+ Node,
+ TabletCategory,
TabletFollowerGroup,
TabletFollowerTablet,
- TabletTypeMetrics,
+ TabletTypeMetrics,
Sequences,
- Metrics,
- SubDomain,
- BlockedOwner,
- TabletOwners
- >;
- using TSettings = SchemaSettings<
- ExecutorLogBatching<true>,
- ExecutorLogFlushPeriod<TDuration::MicroSeconds(512).GetValue()>
- >;
-};
-
-} // NHive
-} // NKikimr
+ Metrics,
+ SubDomain,
+ BlockedOwner,
+ TabletOwners
+ >;
+ using TSettings = SchemaSettings<
+ ExecutorLogBatching<true>,
+ ExecutorLogFlushPeriod<TDuration::MicroSeconds(512).GetValue()>
+ >;
+};
+
+} // NHive
+} // NKikimr
diff --git a/ydb/core/mind/hive/hive_statics.cpp b/ydb/core/mind/hive/hive_statics.cpp
index 7c90776fc3f..42036789565 100644
--- a/ydb/core/mind/hive/hive_statics.cpp
+++ b/ydb/core/mind/hive/hive_statics.cpp
@@ -1,344 +1,344 @@
-#include "hive_impl.h"
-
+#include "hive_impl.h"
+
#include <library/cpp/json/json_value.h>
-namespace NKikimr {
-namespace NHive {
-
-TResourceRawValues ResourceRawValuesFromMetrics(const NKikimrTabletBase::TMetrics& metrics) {
- TResourceRawValues values = {};
- if (metrics.HasCounter()) {
- std::get<NMetrics::EResource::Counter>(values) = metrics.GetCounter();
- }
- if (metrics.HasCPU()) {
- std::get<NMetrics::EResource::CPU>(values) = metrics.GetCPU();
- }
- if (metrics.HasMemory()) {
- std::get<NMetrics::EResource::Memory>(values) = metrics.GetMemory();
- }
- if (metrics.HasNetwork()) {
- std::get<NMetrics::EResource::Network>(values) = metrics.GetNetwork();
- }
- return values;
-}
-
-NKikimrTabletBase::TMetrics MetricsFromResourceRawValues(const TResourceRawValues& values) {
- NKikimrTabletBase::TMetrics metrics;
- if (std::get<NMetrics::EResource::Counter>(values) != 0) {
- metrics.SetCounter(std::get<NMetrics::EResource::Counter>(values));
- }
- if (std::get<NMetrics::EResource::CPU>(values) != 0) {
- metrics.SetCPU(std::get<NMetrics::EResource::CPU>(values));
- }
- if (std::get<NMetrics::EResource::Memory>(values) != 0) {
- metrics.SetMemory(std::get<NMetrics::EResource::Memory>(values));
- }
- if (std::get<NMetrics::EResource::Network>(values) != 0) {
- metrics.SetNetwork(std::get<NMetrics::EResource::Network>(values));
- }
- return metrics;
-}
-
-TResourceRawValues ResourceRawValuesFromMetrics(const NKikimrHive::TTabletMetrics& tabletMetrics) {
- TResourceRawValues values = {};
- if (tabletMetrics.HasResourceUsage()) {
- const NKikimrTabletBase::TMetrics& metrics(tabletMetrics.GetResourceUsage());
- values = ResourceRawValuesFromMetrics(metrics);
- }
- return values;
-}
-
-TString GetResourceValuesText(const NKikimrTabletBase::TMetrics& values) {
- TStringStream str;
- str << '(';
- str << GetCounter(values.GetCounter());
- str << ",&nbsp;";
- str << GetTimes(values.GetCPU());
- str << ",&nbsp;";
- str << GetBytes(values.GetMemory());
- str << ",&nbsp;";
- str << GetBytesPerSecond(values.GetNetwork());
- str << ')';
- return str.Str();
-}
-
-TString GetResourceValuesText(const TResourceRawValues& values) {
- TStringStream str;
- str << '(';
- str << GetCounter(std::get<NMetrics::EResource::Counter>(values));
- str << ',';
- str << GetTimes(std::get<NMetrics::EResource::CPU>(values));
- str << ',';
- str << GetBytes(std::get<NMetrics::EResource::Memory>(values));
- str << ',';
- str << GetBytesPerSecond(std::get<NMetrics::EResource::Network>(values));
- str << ')';
- return str.Str();
-}
-
-TString GetResourceValuesText(const TResourceNormalizedValues& values) {
- TStringStream str;
- str << '(';
- str << Sprintf("%.9f", std::get<NMetrics::EResource::Counter>(values));
- str << ',';
- str << Sprintf("%.9f", std::get<NMetrics::EResource::CPU>(values));
- str << ',';
- str << Sprintf("%.9f", std::get<NMetrics::EResource::Memory>(values));
- str << ',';
- str << Sprintf("%.9f", std::get<NMetrics::EResource::Network>(values));
- str << ')';
- return str.Str();
-}
-
-TString GetResourceValuesText(const TTabletInfo& tablet) {
- TStringStream str;
- const auto& values(tablet.GetResourceValues());
- auto current(tablet.GetResourceCurrentValues());
- auto maximum(tablet.GetResourceMaximumValues());
- tablet.FilterRawValues(current);
- tablet.FilterRawValues(maximum);
- NMetrics::EResource resource = GetDominantResourceType(current, maximum);
- TVector<i64> allowedMetricIds = tablet.GetTabletAllowedMetricIds();
- str << '(';
- str << GetConditionalBoldString(
- GetConditionalGreyString(
- GetCounter(values.GetCounter()),
- Find(allowedMetricIds, NKikimrTabletBase::TMetrics::kCounterFieldNumber) == allowedMetricIds.end()),
- resource == NMetrics::EResource::Counter);
- str << ",&nbsp;";
- str << GetConditionalBoldString(
- GetConditionalGreyString(
- GetTimes(values.GetCPU()),
- Find(allowedMetricIds, NKikimrTabletBase::TMetrics::kCPUFieldNumber) == allowedMetricIds.end()),
- resource == NMetrics::EResource::CPU);
- str << ",&nbsp;";
- str << GetConditionalBoldString(
- GetConditionalGreyString(
- GetBytes(values.GetMemory()),
- Find(allowedMetricIds, NKikimrTabletBase::TMetrics::kMemoryFieldNumber) == allowedMetricIds.end()),
- resource == NMetrics::EResource::Memory);
- str << ",&nbsp;";
- str << GetConditionalBoldString(
- GetConditionalGreyString(
- GetBytesPerSecond(values.GetNetwork()),
- Find(allowedMetricIds, NKikimrTabletBase::TMetrics::kNetworkFieldNumber) == allowedMetricIds.end()),
- resource == NMetrics::EResource::Network);
- str << ')';
- return str.Str();
-}
-
-TString GetResourceValuesHtml(const TResourceRawValues& values) {
- TStringStream str;
- str << "<td>";
- str << GetCounter(std::get<NMetrics::EResource::Counter>(values));
- str << "</td><td>";
- str << GetTimes(std::get<NMetrics::EResource::CPU>(values));
- str << "</td><td>";
- str << GetBytes(std::get<NMetrics::EResource::Memory>(values));
- str << "</td><td>";
- str << GetBytesPerSecond(std::get<NMetrics::EResource::Network>(values));
- str << "</td>";
- return str.Str();
-}
-
-NJson::TJsonValue GetResourceValuesJson(const TResourceRawValues& values) {
- NJson::TJsonValue value;
- value.AppendValue(GetCounter(std::get<NMetrics::EResource::Counter>(values)));
- value.AppendValue(GetTimes(std::get<NMetrics::EResource::CPU>(values)));
- value.AppendValue(GetBytes(std::get<NMetrics::EResource::Memory>(values)));
- value.AppendValue(GetBytesPerSecond(std::get<NMetrics::EResource::Network>(values)));
- return value;
-}
-
-NJson::TJsonValue GetResourceValuesJson(const TResourceRawValues& values, const TResourceRawValues& maximum) {
- NMetrics::EResource resource = GetDominantResourceType(values, maximum);
- NJson::TJsonValue value;
- value.AppendValue(GetConditionalRedString(
- GetConditionalBoldString(
- GetCounter(std::get<NMetrics::EResource::Counter>(values)), resource == NMetrics::EResource::Counter),
- std::get<NMetrics::EResource::Counter>(values) >= std::get<NMetrics::EResource::Counter>(maximum)));
- value.AppendValue(GetConditionalRedString(
- GetConditionalBoldString(
- GetTimes(std::get<NMetrics::EResource::CPU>(values)), resource == NMetrics::EResource::CPU),
- std::get<NMetrics::EResource::CPU>(values) >= std::get<NMetrics::EResource::CPU>(maximum)));
- value.AppendValue(GetConditionalRedString(
- GetConditionalBoldString(
- GetBytes(std::get<NMetrics::EResource::Memory>(values)), resource == NMetrics::EResource::Memory),
- std::get<NMetrics::EResource::Memory>(values) >= std::get<NMetrics::EResource::Memory>(maximum)));
- value.AppendValue(GetConditionalRedString(
- GetConditionalBoldString(
- GetBytesPerSecond(std::get<NMetrics::EResource::Network>(values)), resource == NMetrics::EResource::Network),
- std::get<NMetrics::EResource::Network>(values) >= std::get<NMetrics::EResource::Network>(maximum)));
- return value;
-}
-
-TString GetConditionalGreyString(const TString& str, bool condition) {
- if (condition) {
- return "<span style='color:lightgrey'>" + str + "</span>";
- } else {
- return str;
- }
-}
-
-TString GetConditionalBoldString(const TString& str, bool condition) {
- if (condition) {
- return "<b>" + str + "</b>";
- } else {
- return str;
- }
-}
-
-TString GetConditionalRedString(const TString& str, bool condition) {
- if (condition) {
- return "<span style='color:red'>" + str + "</span>";
- } else {
- return str;
- }
-}
-
-ui64 GetReadThroughput(const NKikimrTabletBase::TMetrics& values) {
- ui64 acc = 0;
- for (const auto& throughput : values.GetGroupReadThroughput()) {
- acc += throughput.GetThroughput();
- }
- return acc;
-}
-
-ui64 GetWriteThroughput(const NKikimrTabletBase::TMetrics& values) {
- ui64 acc = 0;
- for (const auto& throughput : values.GetGroupWriteThroughput()) {
- acc += throughput.GetThroughput();
- }
- return acc;
-}
-
-TString GetCounter(ui64 counter, const TString& zero) {
- if (counter == 0) {
- return zero;
- }
- return Sprintf("%lu", counter);
-}
-
-TString GetBytes(ui64 bytes, const TString& zero) {
- if (bytes == 0) {
- return zero;
- }
- double value = bytes;
- const char* format = "%.0fB";
- if (value > 1024) {
- value /= 1024;
- format = "%.2fKB";
- }
- if (value > 1024) {
- value /= 1024;
- format = "%.1fMB";
- }
- if (value > 1024) {
- value /= 1024;
- format = "%.0fGB";
- }
- return Sprintf(format, value);
-}
-
-TString GetBytesPerSecond(ui64 bytes, const TString& zero) {
- if (bytes == 0) {
- return zero;
- }
- return GetBytes(bytes) + "/s";
-}
-
-TString GetTimes(ui64 times, const TString& zero) {
- if (times == 0) {
- return zero;
- }
- return Sprintf("%.2f%%", (double)times * 100 / 1000000);
-}
-
-TString GetResourceValuesHtml(const NKikimrTabletBase::TMetrics& values) {
- TStringStream str;
- str << "<td>";
- str << GetCounter(values.GetCounter(), TString());
- str << "</td><td data-text='" << values.GetCPU() << "'>";
- str << GetTimes(values.GetCPU(), TString());
- str << "</td><td data-text='" << values.GetMemory() << "'>";
- str << GetBytes(values.GetMemory(), TString());
- str << "</td><td data-text='" << values.GetNetwork() << "'>";
- str << GetBytesPerSecond(values.GetNetwork(), TString());
- str << "</td><td data-text='" << values.GetStorage() << "'>";
- str << GetBytes(values.GetStorage(), TString());
- ui64 bytes = GetReadThroughput(values);
- str << "</td><td data-text='" << bytes << "'>";
- str << GetBytesPerSecond(bytes, TString());
- bytes = GetWriteThroughput(values);
- str << "</td><td data-text='" << bytes << "'>";
- str << GetBytesPerSecond(bytes, TString());
- str << "</td>";
- return str.Str();
-}
-
-NJson::TJsonValue GetResourceValuesJson(const NKikimrTabletBase::TMetrics& values) {
- NJson::TJsonValue value;
- value.AppendValue(GetCounter(values.GetCounter()));
- value.AppendValue(GetTimes(values.GetCPU()));
- value.AppendValue(GetBytes(values.GetMemory()));
- value.AppendValue(GetBytesPerSecond(values.GetNetwork()));
- value.AppendValue(GetBytes(values.GetStorage()));
- value.AppendValue(GetBytesPerSecond(GetReadThroughput(values)));
- value.AppendValue(GetBytesPerSecond(GetWriteThroughput(values)));
- return value;
-}
-
-TString GetDataCenterName(ui64 dataCenterId) {
- switch (dataCenterId) {
- case '\0sas':
- case '\0SAS':
- return "sas";
- case '\0man':
- case '\0MAN':
- case '\0nam':
- case '\0NAM':
- return "man";
- case '\0myt':
- case '\0MYT':
- case '\0tym':
- case '\0TYM':
- return "myt";
- case '\0vla':
- case '\0VLA':
- case '\0alv':
- case '\0ALV':
- return "vla";
- case '\0iva':
- case '\0IVA':
- case '\0avi':
- case '\0AVI':
- return "iva";
- case 0:
- return "?";
- default:
- return ToString(dataCenterId);
- }
-}
-
-TString LongToShortTabletName(const TString& longTabletName) {
- TString shortName;
-
- for (char c : longTabletName) {
- if (c >= 'A' && c <= 'Z') {
- shortName += c;
- }
- }
- if (shortName.empty()) {
- shortName = longTabletName;
- }
- return shortName;
-}
-
-TString GetLocationString(const NActors::TNodeLocation& location) {
- NActorsInterconnect::TNodeLocation proto;
- location.Serialize(&proto);
- return proto.ShortDebugString();
-}
-
-} // NHive
-} // NKikimr
+namespace NKikimr {
+namespace NHive {
+
+TResourceRawValues ResourceRawValuesFromMetrics(const NKikimrTabletBase::TMetrics& metrics) {
+ TResourceRawValues values = {};
+ if (metrics.HasCounter()) {
+ std::get<NMetrics::EResource::Counter>(values) = metrics.GetCounter();
+ }
+ if (metrics.HasCPU()) {
+ std::get<NMetrics::EResource::CPU>(values) = metrics.GetCPU();
+ }
+ if (metrics.HasMemory()) {
+ std::get<NMetrics::EResource::Memory>(values) = metrics.GetMemory();
+ }
+ if (metrics.HasNetwork()) {
+ std::get<NMetrics::EResource::Network>(values) = metrics.GetNetwork();
+ }
+ return values;
+}
+
+NKikimrTabletBase::TMetrics MetricsFromResourceRawValues(const TResourceRawValues& values) {
+ NKikimrTabletBase::TMetrics metrics;
+ if (std::get<NMetrics::EResource::Counter>(values) != 0) {
+ metrics.SetCounter(std::get<NMetrics::EResource::Counter>(values));
+ }
+ if (std::get<NMetrics::EResource::CPU>(values) != 0) {
+ metrics.SetCPU(std::get<NMetrics::EResource::CPU>(values));
+ }
+ if (std::get<NMetrics::EResource::Memory>(values) != 0) {
+ metrics.SetMemory(std::get<NMetrics::EResource::Memory>(values));
+ }
+ if (std::get<NMetrics::EResource::Network>(values) != 0) {
+ metrics.SetNetwork(std::get<NMetrics::EResource::Network>(values));
+ }
+ return metrics;
+}
+
+TResourceRawValues ResourceRawValuesFromMetrics(const NKikimrHive::TTabletMetrics& tabletMetrics) {
+ TResourceRawValues values = {};
+ if (tabletMetrics.HasResourceUsage()) {
+ const NKikimrTabletBase::TMetrics& metrics(tabletMetrics.GetResourceUsage());
+ values = ResourceRawValuesFromMetrics(metrics);
+ }
+ return values;
+}
+
+TString GetResourceValuesText(const NKikimrTabletBase::TMetrics& values) {
+ TStringStream str;
+ str << '(';
+ str << GetCounter(values.GetCounter());
+ str << ",&nbsp;";
+ str << GetTimes(values.GetCPU());
+ str << ",&nbsp;";
+ str << GetBytes(values.GetMemory());
+ str << ",&nbsp;";
+ str << GetBytesPerSecond(values.GetNetwork());
+ str << ')';
+ return str.Str();
+}
+
+TString GetResourceValuesText(const TResourceRawValues& values) {
+ TStringStream str;
+ str << '(';
+ str << GetCounter(std::get<NMetrics::EResource::Counter>(values));
+ str << ',';
+ str << GetTimes(std::get<NMetrics::EResource::CPU>(values));
+ str << ',';
+ str << GetBytes(std::get<NMetrics::EResource::Memory>(values));
+ str << ',';
+ str << GetBytesPerSecond(std::get<NMetrics::EResource::Network>(values));
+ str << ')';
+ return str.Str();
+}
+
+TString GetResourceValuesText(const TResourceNormalizedValues& values) {
+ TStringStream str;
+ str << '(';
+ str << Sprintf("%.9f", std::get<NMetrics::EResource::Counter>(values));
+ str << ',';
+ str << Sprintf("%.9f", std::get<NMetrics::EResource::CPU>(values));
+ str << ',';
+ str << Sprintf("%.9f", std::get<NMetrics::EResource::Memory>(values));
+ str << ',';
+ str << Sprintf("%.9f", std::get<NMetrics::EResource::Network>(values));
+ str << ')';
+ return str.Str();
+}
+
+TString GetResourceValuesText(const TTabletInfo& tablet) {
+ TStringStream str;
+ const auto& values(tablet.GetResourceValues());
+ auto current(tablet.GetResourceCurrentValues());
+ auto maximum(tablet.GetResourceMaximumValues());
+ tablet.FilterRawValues(current);
+ tablet.FilterRawValues(maximum);
+ NMetrics::EResource resource = GetDominantResourceType(current, maximum);
+ TVector<i64> allowedMetricIds = tablet.GetTabletAllowedMetricIds();
+ str << '(';
+ str << GetConditionalBoldString(
+ GetConditionalGreyString(
+ GetCounter(values.GetCounter()),
+ Find(allowedMetricIds, NKikimrTabletBase::TMetrics::kCounterFieldNumber) == allowedMetricIds.end()),
+ resource == NMetrics::EResource::Counter);
+ str << ",&nbsp;";
+ str << GetConditionalBoldString(
+ GetConditionalGreyString(
+ GetTimes(values.GetCPU()),
+ Find(allowedMetricIds, NKikimrTabletBase::TMetrics::kCPUFieldNumber) == allowedMetricIds.end()),
+ resource == NMetrics::EResource::CPU);
+ str << ",&nbsp;";
+ str << GetConditionalBoldString(
+ GetConditionalGreyString(
+ GetBytes(values.GetMemory()),
+ Find(allowedMetricIds, NKikimrTabletBase::TMetrics::kMemoryFieldNumber) == allowedMetricIds.end()),
+ resource == NMetrics::EResource::Memory);
+ str << ",&nbsp;";
+ str << GetConditionalBoldString(
+ GetConditionalGreyString(
+ GetBytesPerSecond(values.GetNetwork()),
+ Find(allowedMetricIds, NKikimrTabletBase::TMetrics::kNetworkFieldNumber) == allowedMetricIds.end()),
+ resource == NMetrics::EResource::Network);
+ str << ')';
+ return str.Str();
+}
+
+TString GetResourceValuesHtml(const TResourceRawValues& values) {
+ TStringStream str;
+ str << "<td>";
+ str << GetCounter(std::get<NMetrics::EResource::Counter>(values));
+ str << "</td><td>";
+ str << GetTimes(std::get<NMetrics::EResource::CPU>(values));
+ str << "</td><td>";
+ str << GetBytes(std::get<NMetrics::EResource::Memory>(values));
+ str << "</td><td>";
+ str << GetBytesPerSecond(std::get<NMetrics::EResource::Network>(values));
+ str << "</td>";
+ return str.Str();
+}
+
+NJson::TJsonValue GetResourceValuesJson(const TResourceRawValues& values) {
+ NJson::TJsonValue value;
+ value.AppendValue(GetCounter(std::get<NMetrics::EResource::Counter>(values)));
+ value.AppendValue(GetTimes(std::get<NMetrics::EResource::CPU>(values)));
+ value.AppendValue(GetBytes(std::get<NMetrics::EResource::Memory>(values)));
+ value.AppendValue(GetBytesPerSecond(std::get<NMetrics::EResource::Network>(values)));
+ return value;
+}
+
+NJson::TJsonValue GetResourceValuesJson(const TResourceRawValues& values, const TResourceRawValues& maximum) {
+ NMetrics::EResource resource = GetDominantResourceType(values, maximum);
+ NJson::TJsonValue value;
+ value.AppendValue(GetConditionalRedString(
+ GetConditionalBoldString(
+ GetCounter(std::get<NMetrics::EResource::Counter>(values)), resource == NMetrics::EResource::Counter),
+ std::get<NMetrics::EResource::Counter>(values) >= std::get<NMetrics::EResource::Counter>(maximum)));
+ value.AppendValue(GetConditionalRedString(
+ GetConditionalBoldString(
+ GetTimes(std::get<NMetrics::EResource::CPU>(values)), resource == NMetrics::EResource::CPU),
+ std::get<NMetrics::EResource::CPU>(values) >= std::get<NMetrics::EResource::CPU>(maximum)));
+ value.AppendValue(GetConditionalRedString(
+ GetConditionalBoldString(
+ GetBytes(std::get<NMetrics::EResource::Memory>(values)), resource == NMetrics::EResource::Memory),
+ std::get<NMetrics::EResource::Memory>(values) >= std::get<NMetrics::EResource::Memory>(maximum)));
+ value.AppendValue(GetConditionalRedString(
+ GetConditionalBoldString(
+ GetBytesPerSecond(std::get<NMetrics::EResource::Network>(values)), resource == NMetrics::EResource::Network),
+ std::get<NMetrics::EResource::Network>(values) >= std::get<NMetrics::EResource::Network>(maximum)));
+ return value;
+}
+
+TString GetConditionalGreyString(const TString& str, bool condition) {
+ if (condition) {
+ return "<span style='color:lightgrey'>" + str + "</span>";
+ } else {
+ return str;
+ }
+}
+
+TString GetConditionalBoldString(const TString& str, bool condition) {
+ if (condition) {
+ return "<b>" + str + "</b>";
+ } else {
+ return str;
+ }
+}
+
+TString GetConditionalRedString(const TString& str, bool condition) {
+ if (condition) {
+ return "<span style='color:red'>" + str + "</span>";
+ } else {
+ return str;
+ }
+}
+
+ui64 GetReadThroughput(const NKikimrTabletBase::TMetrics& values) {
+ ui64 acc = 0;
+ for (const auto& throughput : values.GetGroupReadThroughput()) {
+ acc += throughput.GetThroughput();
+ }
+ return acc;
+}
+
+ui64 GetWriteThroughput(const NKikimrTabletBase::TMetrics& values) {
+ ui64 acc = 0;
+ for (const auto& throughput : values.GetGroupWriteThroughput()) {
+ acc += throughput.GetThroughput();
+ }
+ return acc;
+}
+
+TString GetCounter(ui64 counter, const TString& zero) {
+ if (counter == 0) {
+ return zero;
+ }
+ return Sprintf("%lu", counter);
+}
+
+TString GetBytes(ui64 bytes, const TString& zero) {
+ if (bytes == 0) {
+ return zero;
+ }
+ double value = bytes;
+ const char* format = "%.0fB";
+ if (value > 1024) {
+ value /= 1024;
+ format = "%.2fKB";
+ }
+ if (value > 1024) {
+ value /= 1024;
+ format = "%.1fMB";
+ }
+ if (value > 1024) {
+ value /= 1024;
+ format = "%.0fGB";
+ }
+ return Sprintf(format, value);
+}
+
+TString GetBytesPerSecond(ui64 bytes, const TString& zero) {
+ if (bytes == 0) {
+ return zero;
+ }
+ return GetBytes(bytes) + "/s";
+}
+
+TString GetTimes(ui64 times, const TString& zero) {
+ if (times == 0) {
+ return zero;
+ }
+ return Sprintf("%.2f%%", (double)times * 100 / 1000000);
+}
+
+TString GetResourceValuesHtml(const NKikimrTabletBase::TMetrics& values) {
+ TStringStream str;
+ str << "<td>";
+ str << GetCounter(values.GetCounter(), TString());
+ str << "</td><td data-text='" << values.GetCPU() << "'>";
+ str << GetTimes(values.GetCPU(), TString());
+ str << "</td><td data-text='" << values.GetMemory() << "'>";
+ str << GetBytes(values.GetMemory(), TString());
+ str << "</td><td data-text='" << values.GetNetwork() << "'>";
+ str << GetBytesPerSecond(values.GetNetwork(), TString());
+ str << "</td><td data-text='" << values.GetStorage() << "'>";
+ str << GetBytes(values.GetStorage(), TString());
+ ui64 bytes = GetReadThroughput(values);
+ str << "</td><td data-text='" << bytes << "'>";
+ str << GetBytesPerSecond(bytes, TString());
+ bytes = GetWriteThroughput(values);
+ str << "</td><td data-text='" << bytes << "'>";
+ str << GetBytesPerSecond(bytes, TString());
+ str << "</td>";
+ return str.Str();
+}
+
+NJson::TJsonValue GetResourceValuesJson(const NKikimrTabletBase::TMetrics& values) {
+ NJson::TJsonValue value;
+ value.AppendValue(GetCounter(values.GetCounter()));
+ value.AppendValue(GetTimes(values.GetCPU()));
+ value.AppendValue(GetBytes(values.GetMemory()));
+ value.AppendValue(GetBytesPerSecond(values.GetNetwork()));
+ value.AppendValue(GetBytes(values.GetStorage()));
+ value.AppendValue(GetBytesPerSecond(GetReadThroughput(values)));
+ value.AppendValue(GetBytesPerSecond(GetWriteThroughput(values)));
+ return value;
+}
+
+TString GetDataCenterName(ui64 dataCenterId) {
+ switch (dataCenterId) {
+ case '\0sas':
+ case '\0SAS':
+ return "sas";
+ case '\0man':
+ case '\0MAN':
+ case '\0nam':
+ case '\0NAM':
+ return "man";
+ case '\0myt':
+ case '\0MYT':
+ case '\0tym':
+ case '\0TYM':
+ return "myt";
+ case '\0vla':
+ case '\0VLA':
+ case '\0alv':
+ case '\0ALV':
+ return "vla";
+ case '\0iva':
+ case '\0IVA':
+ case '\0avi':
+ case '\0AVI':
+ return "iva";
+ case 0:
+ return "?";
+ default:
+ return ToString(dataCenterId);
+ }
+}
+
+TString LongToShortTabletName(const TString& longTabletName) {
+ TString shortName;
+
+ for (char c : longTabletName) {
+ if (c >= 'A' && c <= 'Z') {
+ shortName += c;
+ }
+ }
+ if (shortName.empty()) {
+ shortName = longTabletName;
+ }
+ return shortName;
+}
+
+TString GetLocationString(const NActors::TNodeLocation& location) {
+ NActorsInterconnect::TNodeLocation proto;
+ location.Serialize(&proto);
+ return proto.ShortDebugString();
+}
+
+} // NHive
+} // NKikimr
diff --git a/ydb/core/mind/hive/hive_transactions.h b/ydb/core/mind/hive/hive_transactions.h
index 13c1ddef027..bc1dd793738 100644
--- a/ydb/core/mind/hive/hive_transactions.h
+++ b/ydb/core/mind/hive/hive_transactions.h
@@ -1,13 +1,13 @@
-#pragma once
-
+#pragma once
+
#include <ydb/core/tablet_flat/tablet_flat_executor.h>
#include <ydb/core/tablet_flat/flat_cxx_database.h>
-#include "hive_events.h"
-
-namespace NKikimr {
-namespace NHive {
-
-using NKikimr::NTabletFlatExecutor::ITransaction;
-
-}
-}
+#include "hive_events.h"
+
+namespace NKikimr {
+namespace NHive {
+
+using NKikimr::NTabletFlatExecutor::ITransaction;
+
+}
+}
diff --git a/ydb/core/mind/hive/hive_ut.cpp b/ydb/core/mind/hive/hive_ut.cpp
index c5e1d53bf1e..0383d49a123 100644
--- a/ydb/core/mind/hive/hive_ut.cpp
+++ b/ydb/core/mind/hive/hive_ut.cpp
@@ -1,4 +1,4 @@
-#include <math.h>
+#include <math.h>
#include <ydb/core/base/hive.h>
#include <ydb/core/base/appdata.h>
#include <ydb/core/blobstorage/crypto/default.h>
@@ -24,7 +24,7 @@
#include <library/cpp/malloc/api/malloc.h>
#include <library/cpp/actors/core/interconnect.h>
#include <util/random/entropy.h>
-#include <util/stream/null.h>
+#include <util/stream/null.h>
#include <util/string/printf.h>
#include <util/string/subst.h>
#include <util/system/sanitizers.h>
@@ -32,18 +32,18 @@
#include <google/protobuf/text_format.h>
#include <library/cpp/testing/unittest/registar.h>
-#ifdef NDEBUG
-#define Ctest Cnull
-#else
-#define Ctest Cerr
-#endif
-
+#ifdef NDEBUG
+#define Ctest Cnull
+#else
+#define Ctest Cerr
+#endif
+
const bool STRAND_PDISK = true;
-#ifndef NDEBUG
-static constexpr bool ENABLE_DETAILED_HIVE_LOG = true;
-#else
-static constexpr bool ENABLE_DETAILED_HIVE_LOG = false;
-#endif
+#ifndef NDEBUG
+static constexpr bool ENABLE_DETAILED_HIVE_LOG = true;
+#else
+static constexpr bool ENABLE_DETAILED_HIVE_LOG = false;
+#endif
const char *DOMAIN_NAME = "dc-1";
namespace NKikimr {
@@ -54,65 +54,65 @@ namespace {
NActors::NLog::EPriority priority = ENABLE_DETAILED_HIVE_LOG ? NLog::PRI_DEBUG : NLog::PRI_ERROR;
NActors::NLog::EPriority otherPriority = NLog::PRI_ERROR;
- if (ENABLE_DETAILED_HIVE_LOG) {
- runtime.SetLogPriority(NKikimrServices::HIVE, NLog::PRI_TRACE);
- runtime.SetLogPriority(NKikimrServices::BS_CONTROLLER, NLog::PRI_TRACE);
- } else {
- runtime.SetLogPriority(NKikimrServices::HIVE, priority);
- runtime.SetLogPriority(NKikimrServices::BS_CONTROLLER, priority);
- }
+ if (ENABLE_DETAILED_HIVE_LOG) {
+ runtime.SetLogPriority(NKikimrServices::HIVE, NLog::PRI_TRACE);
+ runtime.SetLogPriority(NKikimrServices::BS_CONTROLLER, NLog::PRI_TRACE);
+ } else {
+ runtime.SetLogPriority(NKikimrServices::HIVE, priority);
+ runtime.SetLogPriority(NKikimrServices::BS_CONTROLLER, priority);
+ }
runtime.SetLogPriority(NKikimrServices::LOCAL, priority);
- runtime.SetLogPriority(NKikimrServices::TABLET_MAIN, otherPriority);
- runtime.SetLogPriority(NKikimrServices::TABLET_EXECUTOR, otherPriority);
+ runtime.SetLogPriority(NKikimrServices::TABLET_MAIN, otherPriority);
+ runtime.SetLogPriority(NKikimrServices::TABLET_EXECUTOR, otherPriority);
runtime.SetLogPriority(NKikimrServices::BS_NODE, otherPriority);
- runtime.SetLogPriority(NKikimrServices::BS_CONTROLLER, otherPriority);
- runtime.SetLogPriority(NKikimrServices::BS_PROXY, otherPriority);
- runtime.SetLogPriority(NKikimrServices::BS_SYNCLOG, NLog::PRI_CRIT);
- runtime.SetLogPriority(NKikimrServices::BS_SYNCER, NLog::PRI_CRIT);
- runtime.SetLogPriority(NKikimrServices::BS_PROXY_GET, otherPriority);
- runtime.SetLogPriority(NKikimrServices::BS_PROXY_PUT, otherPriority);
- runtime.SetLogPriority(NKikimrServices::BS_PROXY_COLLECT, otherPriority);
- runtime.SetLogPriority(NKikimrServices::BS_PROXY_BLOCK, otherPriority);
- runtime.SetLogPriority(NKikimrServices::BS_PROXY_RANGE, otherPriority);
- runtime.SetLogPriority(NKikimrServices::BS_PROXY_DISCOVER, otherPriority);
- runtime.SetLogPriority(NKikimrServices::PIPE_CLIENT, otherPriority);
- runtime.SetLogPriority(NKikimrServices::PIPE_SERVER, otherPriority);
- runtime.SetLogPriority(NKikimrServices::TX_DUMMY, otherPriority);
- runtime.SetLogPriority(NKikimrServices::TABLET_RESOLVER, otherPriority);
- runtime.SetLogPriority(NKikimrServices::STATESTORAGE, otherPriority);
- runtime.SetLogPriority(NKikimrServices::BOOTSTRAPPER, otherPriority);
+ runtime.SetLogPriority(NKikimrServices::BS_CONTROLLER, otherPriority);
+ runtime.SetLogPriority(NKikimrServices::BS_PROXY, otherPriority);
+ runtime.SetLogPriority(NKikimrServices::BS_SYNCLOG, NLog::PRI_CRIT);
+ runtime.SetLogPriority(NKikimrServices::BS_SYNCER, NLog::PRI_CRIT);
+ runtime.SetLogPriority(NKikimrServices::BS_PROXY_GET, otherPriority);
+ runtime.SetLogPriority(NKikimrServices::BS_PROXY_PUT, otherPriority);
+ runtime.SetLogPriority(NKikimrServices::BS_PROXY_COLLECT, otherPriority);
+ runtime.SetLogPriority(NKikimrServices::BS_PROXY_BLOCK, otherPriority);
+ runtime.SetLogPriority(NKikimrServices::BS_PROXY_RANGE, otherPriority);
+ runtime.SetLogPriority(NKikimrServices::BS_PROXY_DISCOVER, otherPriority);
+ runtime.SetLogPriority(NKikimrServices::PIPE_CLIENT, otherPriority);
+ runtime.SetLogPriority(NKikimrServices::PIPE_SERVER, otherPriority);
+ runtime.SetLogPriority(NKikimrServices::TX_DUMMY, otherPriority);
+ runtime.SetLogPriority(NKikimrServices::TABLET_RESOLVER, otherPriority);
+ runtime.SetLogPriority(NKikimrServices::STATESTORAGE, otherPriority);
+ runtime.SetLogPriority(NKikimrServices::BOOTSTRAPPER, otherPriority);
}
THashMap<ui32, TIntrusivePtr<TNodeWardenConfig>> NodeWardenConfigs;
-
- void SetupDomainInfo(TTestActorRuntime &runtime, TAppPrepare &app) {
+
+ void SetupDomainInfo(TTestActorRuntime &runtime, TAppPrepare &app) {
app.ClearDomainsAndHive();
-
+
ui32 domainUid = TTestTxConfig::DomainUid;
- ui32 ssId = 0;
- ui32 planResolution = 50;
+ ui32 ssId = 0;
+ ui32 planResolution = 50;
ui64 schemeRoot = TTestTxConfig::SchemeShard;
- ui64 hive = MakeDefaultHiveID(ssId);
- auto domain = TDomainsInfo::TDomain::ConstructDomainWithExplicitTabletIds(
- DOMAIN_NAME, domainUid, schemeRoot,
- ssId, ssId, TVector<ui32>{ssId},
- domainUid, TVector<ui32>{domainUid},
- planResolution,
- TVector<ui64>{TDomainsInfo::MakeTxCoordinatorIDFixed(domainUid, 1)},
- TVector<ui64>{},
- TVector<ui64>{TDomainsInfo::MakeTxAllocatorIDFixed(domainUid, 1)},
- DefaultPoolKinds(2));
-
- TVector<ui64> ids = runtime.GetTxAllocatorTabletIds();
- ids.insert(ids.end(), domain->TxAllocators.begin(), domain->TxAllocators.end());
- runtime.SetTxAllocatorTabletIds(ids);
-
- app.AddDomain(domain.Release());
- app.AddHive(domainUid, hive);
+ ui64 hive = MakeDefaultHiveID(ssId);
+ auto domain = TDomainsInfo::TDomain::ConstructDomainWithExplicitTabletIds(
+ DOMAIN_NAME, domainUid, schemeRoot,
+ ssId, ssId, TVector<ui32>{ssId},
+ domainUid, TVector<ui32>{domainUid},
+ planResolution,
+ TVector<ui64>{TDomainsInfo::MakeTxCoordinatorIDFixed(domainUid, 1)},
+ TVector<ui64>{},
+ TVector<ui64>{TDomainsInfo::MakeTxAllocatorIDFixed(domainUid, 1)},
+ DefaultPoolKinds(2));
+
+ TVector<ui64> ids = runtime.GetTxAllocatorTabletIds();
+ ids.insert(ids.end(), domain->TxAllocators.begin(), domain->TxAllocators.end());
+ runtime.SetTxAllocatorTabletIds(ids);
+
+ app.AddDomain(domain.Release());
+ app.AddHive(domainUid, hive);
}
- static TString STORAGE_POOL = "def";
-
+ static TString STORAGE_POOL = "def";
+
void SetupChannels(TAppPrepare &app) {
TIntrusivePtr<TChannelProfiles> channelProfiles = new TChannelProfiles;
channelProfiles->Profiles.emplace_back();
@@ -124,41 +124,41 @@ namespace {
app.SetChannels(std::move(channelProfiles));
}
- static TChannelBind GetChannelBind(const TString& storagePool) {
- TChannelBind bind;
- bind.SetStoragePoolName(storagePool);
- return bind;
- }
-
- static TChannelsBindings BINDED_CHANNELS = {GetChannelBind(STORAGE_POOL + "1"), GetChannelBind(STORAGE_POOL + "2"), GetChannelBind(STORAGE_POOL + "3")};
-
+ static TChannelBind GetChannelBind(const TString& storagePool) {
+ TChannelBind bind;
+ bind.SetStoragePoolName(storagePool);
+ return bind;
+ }
+
+ static TChannelsBindings BINDED_CHANNELS = {GetChannelBind(STORAGE_POOL + "1"), GetChannelBind(STORAGE_POOL + "2"), GetChannelBind(STORAGE_POOL + "3")};
+
void SetupNodeWarden(TTestActorRuntime &runtime) {
for (ui32 nodeIndex = 0; nodeIndex < runtime.GetNodeCount(); ++nodeIndex) {
TString staticConfig(
"AvailabilityDomains: 0 "
- "PDisks { NodeID: $Node1 PDiskID: 1 PDiskGuid: 1 Path: \"/tmp/pdisk.dat\" }"
+ "PDisks { NodeID: $Node1 PDiskID: 1 PDiskGuid: 1 Path: \"/tmp/pdisk.dat\" }"
"VDisks { VDiskID { GroupID: 0 GroupGeneration: 1 Ring: 0 Domain: 0 VDisk: 0 }"
- " VDiskLocation { NodeID: $Node1 PDiskID: 1 PDiskGuid: 1 VDiskSlotID: 0 }"
+ " VDiskLocation { NodeID: $Node1 PDiskID: 1 PDiskGuid: 1 VDiskSlotID: 0 }"
"}"
"Groups { GroupID: 0 GroupGeneration: 1 ErasureSpecies: 0 "// None
" Rings {"
- " FailDomains { VDiskLocations { NodeID: $Node1 PDiskID: 1 VDiskSlotID: 0 PDiskGuid: 1 } }"
+ " FailDomains { VDiskLocations { NodeID: $Node1 PDiskID: 1 VDiskSlotID: 0 PDiskGuid: 1 } }"
" }"
"}");
SubstGlobal(staticConfig, "$Node1", Sprintf("%" PRIu32, runtime.GetNodeId(0)));
- TIntrusivePtr<TNodeWardenConfig> nodeWardenConfig = new TNodeWardenConfig(
- STRAND_PDISK && !runtime.IsRealThreads() ? static_cast<IPDiskServiceFactory*>(new TStrandedPDiskServiceFactory(runtime)) :
- static_cast<IPDiskServiceFactory*>(new TRealPDiskServiceFactory()));
- //nodeWardenConfig->Monitoring = monitoring;
+ TIntrusivePtr<TNodeWardenConfig> nodeWardenConfig = new TNodeWardenConfig(
+ STRAND_PDISK && !runtime.IsRealThreads() ? static_cast<IPDiskServiceFactory*>(new TStrandedPDiskServiceFactory(runtime)) :
+ static_cast<IPDiskServiceFactory*>(new TRealPDiskServiceFactory()));
+ //nodeWardenConfig->Monitoring = monitoring;
google::protobuf::TextFormat::ParseFromString(staticConfig, &nodeWardenConfig->ServiceSet);
- TIntrusivePtr<TNodeWardenConfig> existingNodeWardenConfig = NodeWardenConfigs[nodeIndex];
- if (existingNodeWardenConfig != nullptr) {
+ TIntrusivePtr<TNodeWardenConfig> existingNodeWardenConfig = NodeWardenConfigs[nodeIndex];
+ if (existingNodeWardenConfig != nullptr) {
std::swap(nodeWardenConfig->SectorMaps, existingNodeWardenConfig->SectorMaps);
- }
-
+ }
+
NodeWardenConfigs[nodeIndex] = nodeWardenConfig;
}
}
@@ -174,7 +174,7 @@ namespace {
ui64 pDiskSize = 32ull << 30ull;
ui64 pDiskChunkSize = 32u << 20u;
if (true /*in memory*/) {
- pDiskPath = "/tmp/pdisk.dat";
+ pDiskPath = "/tmp/pdisk.dat";
auto& existing = nodeWardenConfig->SectorMaps[pDiskPath];
if (existing && existing->DeviceSize == pDiskSize) {
sectorMap = existing;
@@ -184,7 +184,7 @@ namespace {
}
} else {
static TTempDir tempDir;
- pDiskPath = tempDir() + "/pdisk.dat";
+ pDiskPath = tempDir() + "/pdisk.dat";
}
nodeWardenConfig->ServiceSet.MutablePDisks(0)->SetPath(pDiskPath);
ui64 pDiskGuid = 1;
@@ -217,17 +217,17 @@ namespace {
&CreateFlatDummyTablet,
TMailboxType::Simple, 0,
TMailboxType::Simple, 0);
- localConfig->TabletClassInfo[TTabletTypes::Hive].SetupInfo = new TTabletSetupInfo(
- &CreateDefaultHive,
- TMailboxType::Simple, 0,
- TMailboxType::Simple, 0);
- localConfig->TabletClassInfo[TTabletTypes::Mediator].SetupInfo = new TTabletSetupInfo(
- &CreateTxMediator,
- TMailboxType::Simple, 0,
- TMailboxType::Simple, 0);
+ localConfig->TabletClassInfo[TTabletTypes::Hive].SetupInfo = new TTabletSetupInfo(
+ &CreateDefaultHive,
+ TMailboxType::Simple, 0,
+ TMailboxType::Simple, 0);
+ localConfig->TabletClassInfo[TTabletTypes::Mediator].SetupInfo = new TTabletSetupInfo(
+ &CreateTxMediator,
+ TMailboxType::Simple, 0,
+ TMailboxType::Simple, 0);
TTenantPoolConfig::TPtr tenantPoolConfig = new TTenantPoolConfig(localConfig);
tenantPoolConfig->AddStaticSlot(DOMAIN_NAME);
-
+
runtime.AddLocalService(MakeTenantPoolRootID(), TActorSetupCmd(
CreateTenantPool(tenantPoolConfig), TMailboxType::Revolving, 0), nodeIndex);
}
@@ -247,12 +247,12 @@ namespace {
void SetupServices(TTestActorRuntime &runtime, bool isLocalEnabled) {
TAppPrepare app;
- SetupDomainInfo(runtime, app);
+ SetupDomainInfo(runtime, app);
SetupChannels(app);
- app.SetMinRequestSequenceSize(10); // for smaller sequences and high interaction between root and domain hives
- app.SetRequestSequenceSize(10);
-
+ app.SetMinRequestSequenceSize(10); // for smaller sequences and high interaction between root and domain hives
+ app.SetRequestSequenceSize(10);
+
SetupNodeWarden(runtime);
SetupPDisk(runtime);
@@ -267,13 +267,13 @@ namespace {
runtime.Initialize(app.Unwrap());
- for (ui32 nodeIndex = 0; nodeIndex < runtime.GetNodeCount(); ++nodeIndex) {
- auto it = NodeWardenConfigs.find(nodeIndex);
- if (it != NodeWardenConfigs.end()) {
+ for (ui32 nodeIndex = 0; nodeIndex < runtime.GetNodeCount(); ++nodeIndex) {
+ auto it = NodeWardenConfigs.find(nodeIndex);
+ if (it != NodeWardenConfigs.end()) {
runtime.GetAppData(nodeIndex).StaticBlobStorageConfig = MakeHolder<NKikimrBlobStorage::TNodeWardenServiceSet>(it->second->ServiceSet);
- }
- }
-
+ }
+ }
+
EnableSchedule(runtime, isLocalEnabled);
const ui32 domainsNum = 1;
@@ -286,77 +286,77 @@ namespace {
}
CreateTestBootstrapper(runtime, CreateTestTabletInfo(MakeBSControllerID(0), TTabletTypes::FLAT_BS_CONTROLLER),
- &CreateFlatBsController);
+ &CreateFlatBsController);
}
- void SetupBoxAndStoragePool(TTestActorRuntime &runtime, ui32 numGroups = 1, const TString& storagePoolNamePrefix = STORAGE_POOL) {
+ void SetupBoxAndStoragePool(TTestActorRuntime &runtime, ui32 numGroups = 1, const TString& storagePoolNamePrefix = STORAGE_POOL) {
TActorId sender = runtime.AllocateEdgeActor();
- ui32 domainId = 0;
- ui32 nodeIndex = 0;
- TString pDiskPath;
- if (true /*in memory*/) {
- pDiskPath = "/tmp/pdisk.dat";
- } else {
- pDiskPath = runtime.GetTempDir() + "/pdisk.dat";
- }
-
- NTabletPipe::TClientConfig pipeConfig;
- pipeConfig.RetryPolicy = NTabletPipe::TClientRetryPolicy::WithRetries();
-
+ ui32 domainId = 0;
+ ui32 nodeIndex = 0;
+ TString pDiskPath;
+ if (true /*in memory*/) {
+ pDiskPath = "/tmp/pdisk.dat";
+ } else {
+ pDiskPath = runtime.GetTempDir() + "/pdisk.dat";
+ }
+
+ NTabletPipe::TClientConfig pipeConfig;
+ pipeConfig.RetryPolicy = NTabletPipe::TClientRetryPolicy::WithRetries();
+
runtime.Send(new IEventHandle(GetNameserviceActorId(), sender, new TEvInterconnect::TEvListNodes));
- TAutoPtr<IEventHandle> handleNodesInfo;
- auto nodesInfo = runtime.GrabEdgeEventRethrow<TEvInterconnect::TEvNodesInfo>(handleNodesInfo);
-
+ TAutoPtr<IEventHandle> handleNodesInfo;
+ auto nodesInfo = runtime.GrabEdgeEventRethrow<TEvInterconnect::TEvNodesInfo>(handleNodesInfo);
+
auto bsConfigureRequest = MakeHolder<TEvBlobStorage::TEvControllerConfigRequest>();
-
- NKikimrBlobStorage::TDefineBox boxConfig;
- boxConfig.SetBoxId(1);
-
- ui32 nodeId = runtime.GetNodeId(nodeIndex);
- Y_VERIFY(nodesInfo->Nodes[0].NodeId == nodeId);
- auto& nodeInfo = nodesInfo->Nodes[0];
-
- NKikimrBlobStorage::TDefineHostConfig hostConfig;
- hostConfig.SetHostConfigId(nodeId);
- hostConfig.AddDrive()->SetPath(pDiskPath);
- bsConfigureRequest->Record.MutableRequest()->AddCommand()->MutableDefineHostConfig()->CopyFrom(hostConfig);
-
- auto &host = *boxConfig.AddHost();
- host.MutableKey()->SetFqdn(nodeInfo.Host);
- host.MutableKey()->SetIcPort(nodeInfo.Port);
- host.SetHostConfigId(hostConfig.GetHostConfigId());
- bsConfigureRequest->Record.MutableRequest()->AddCommand()->MutableDefineBox()->CopyFrom(boxConfig);
-
- for (int i = 1; i <= 3; ++i) {
- NKikimrBlobStorage::TDefineStoragePool storagePool;
- storagePool.SetBoxId(1);
- storagePool.SetStoragePoolId(i);
- storagePool.SetName(storagePoolNamePrefix + ToString(i));
- storagePool.SetErasureSpecies("none");
- storagePool.SetVDiskKind("Default");
- storagePool.SetKind("DefaultStoragePool");
- storagePool.SetNumGroups(numGroups);
- storagePool.AddPDiskFilter()->AddProperty()->SetType(NKikimrBlobStorage::ROT);
- bsConfigureRequest->Record.MutableRequest()->AddCommand()->MutableDefineStoragePool()->CopyFrom(storagePool);
- }
-
- runtime.SendToPipe(MakeBSControllerID(domainId), sender, bsConfigureRequest.Release(), 0, pipeConfig);
-
- TAutoPtr<IEventHandle> handleConfigureResponse;
- auto configureResponse = runtime.GrabEdgeEventRethrow<TEvBlobStorage::TEvControllerConfigResponse>(handleConfigureResponse);
- if (!configureResponse->Record.GetResponse().GetSuccess()) {
- Ctest << "\n\n configResponse is #" << configureResponse->Record.DebugString() << "\n\n";
- }
- UNIT_ASSERT(configureResponse->Record.GetResponse().GetSuccess());
- }
-
- void Setup(TTestActorRuntime& runtime, bool isLocalEnabled = true, ui32 numGroups = 1) {
- using namespace NMalloc;
- TMallocInfo mallocInfo = MallocInfo();
- mallocInfo.SetParam("FillMemoryOnAllocation", "false");
+
+ NKikimrBlobStorage::TDefineBox boxConfig;
+ boxConfig.SetBoxId(1);
+
+ ui32 nodeId = runtime.GetNodeId(nodeIndex);
+ Y_VERIFY(nodesInfo->Nodes[0].NodeId == nodeId);
+ auto& nodeInfo = nodesInfo->Nodes[0];
+
+ NKikimrBlobStorage::TDefineHostConfig hostConfig;
+ hostConfig.SetHostConfigId(nodeId);
+ hostConfig.AddDrive()->SetPath(pDiskPath);
+ bsConfigureRequest->Record.MutableRequest()->AddCommand()->MutableDefineHostConfig()->CopyFrom(hostConfig);
+
+ auto &host = *boxConfig.AddHost();
+ host.MutableKey()->SetFqdn(nodeInfo.Host);
+ host.MutableKey()->SetIcPort(nodeInfo.Port);
+ host.SetHostConfigId(hostConfig.GetHostConfigId());
+ bsConfigureRequest->Record.MutableRequest()->AddCommand()->MutableDefineBox()->CopyFrom(boxConfig);
+
+ for (int i = 1; i <= 3; ++i) {
+ NKikimrBlobStorage::TDefineStoragePool storagePool;
+ storagePool.SetBoxId(1);
+ storagePool.SetStoragePoolId(i);
+ storagePool.SetName(storagePoolNamePrefix + ToString(i));
+ storagePool.SetErasureSpecies("none");
+ storagePool.SetVDiskKind("Default");
+ storagePool.SetKind("DefaultStoragePool");
+ storagePool.SetNumGroups(numGroups);
+ storagePool.AddPDiskFilter()->AddProperty()->SetType(NKikimrBlobStorage::ROT);
+ bsConfigureRequest->Record.MutableRequest()->AddCommand()->MutableDefineStoragePool()->CopyFrom(storagePool);
+ }
+
+ runtime.SendToPipe(MakeBSControllerID(domainId), sender, bsConfigureRequest.Release(), 0, pipeConfig);
+
+ TAutoPtr<IEventHandle> handleConfigureResponse;
+ auto configureResponse = runtime.GrabEdgeEventRethrow<TEvBlobStorage::TEvControllerConfigResponse>(handleConfigureResponse);
+ if (!configureResponse->Record.GetResponse().GetSuccess()) {
+ Ctest << "\n\n configResponse is #" << configureResponse->Record.DebugString() << "\n\n";
+ }
+ UNIT_ASSERT(configureResponse->Record.GetResponse().GetSuccess());
+ }
+
+ void Setup(TTestActorRuntime& runtime, bool isLocalEnabled = true, ui32 numGroups = 1) {
+ using namespace NMalloc;
+ TMallocInfo mallocInfo = MallocInfo();
+ mallocInfo.SetParam("FillMemoryOnAllocation", "false");
SetupLogging(runtime);
SetupServices(runtime, isLocalEnabled);
- SetupBoxAndStoragePool(runtime, numGroups);
+ SetupBoxAndStoragePool(runtime, numGroups);
}
class THiveInitialEventsFilter : TNonCopyable {
@@ -384,26 +384,26 @@ namespace {
}
};
- class THiveEveryEventFilter : TNonCopyable {
- public:
- THiveEveryEventFilter()
- {}
-
- TTestActorRuntime::TEventFilter Prepare() {
- return [&](TTestActorRuntimeBase& runtime, TAutoPtr<IEventHandle>& event) {
- return (*this)(runtime, event);
- };
- }
-
- bool operator()(TTestActorRuntimeBase& runtime, TAutoPtr<IEventHandle>& event) {
- Y_UNUSED(runtime);
- Y_UNUSED(event);
- return false;
- /*return (event->GetTypeRewrite() >= EventSpaceBegin(TKikimrEvents::ES_HIVE)
- && event->GetTypeRewrite() < EventSpaceEnd(TKikimrEvents::ES_HIVE));*/
- }
- };
-
+ class THiveEveryEventFilter : TNonCopyable {
+ public:
+ THiveEveryEventFilter()
+ {}
+
+ TTestActorRuntime::TEventFilter Prepare() {
+ return [&](TTestActorRuntimeBase& runtime, TAutoPtr<IEventHandle>& event) {
+ return (*this)(runtime, event);
+ };
+ }
+
+ bool operator()(TTestActorRuntimeBase& runtime, TAutoPtr<IEventHandle>& event) {
+ Y_UNUSED(runtime);
+ Y_UNUSED(event);
+ return false;
+ /*return (event->GetTypeRewrite() >= EventSpaceBegin(TKikimrEvents::ES_HIVE)
+ && event->GetTypeRewrite() < EventSpaceEnd(TKikimrEvents::ES_HIVE));*/
+ }
+ };
+
}
void FormatPDiskForTest(TString path, ui64 diskSize, ui32 chunkSize, ui64 guid,
@@ -455,24 +455,24 @@ void InitSchemeRoot(TTestBasicRuntime& runtime, const TActorId& sender) {
}
Y_UNIT_TEST_SUITE(THiveTest) {
- template <typename KeyType, typename ValueType>
+ template <typename KeyType, typename ValueType>
static double GetStDev(const THashMap<KeyType, ValueType>& values) {
- double sum = double();
- if (values.empty())
- return sum;
- for (const auto& v : values)
- sum += v.second;
- double mean = sum / values.size();
- sum = double();
- for (const auto& v : values) {
- auto diff = (double)v.second - mean;
- sum += diff * diff;
- }
- auto div = sum / values.size();
- auto st_dev = ::sqrt(div);
- return st_dev;
- }
-
+ double sum = double();
+ if (values.empty())
+ return sum;
+ for (const auto& v : values)
+ sum += v.second;
+ double mean = sum / values.size();
+ sum = double();
+ for (const auto& v : values) {
+ auto diff = (double)v.second - mean;
+ sum += diff * diff;
+ }
+ auto div = sum / values.size();
+ auto st_dev = ::sqrt(div);
+ return st_dev;
+ }
+
template <typename KeyType, typename ValueType>
static ValueType GetMinMaxDiff(const THashMap<KeyType, ValueType>& values) {
ValueType minVal = std::numeric_limits<ValueType>::max();
@@ -489,15 +489,15 @@ Y_UNIT_TEST_SUITE(THiveTest) {
return maxVal - minVal;
}
- void SendToLocal(TTestActorRuntime &runtime, ui32 nodeIndex, IEventBase* event) {
+ void SendToLocal(TTestActorRuntime &runtime, ui32 nodeIndex, IEventBase* event) {
TActorId local = MakeLocalID(runtime.GetNodeId(nodeIndex));
runtime.Send(new IEventHandle(local, TActorId(), event), nodeIndex);
}
- void SendKillLocal(TTestActorRuntime &runtime, ui32 nodeIndex) {
- SendToLocal(runtime, nodeIndex, new TEvents::TEvPoisonPill());
- }
-
+ void SendKillLocal(TTestActorRuntime &runtime, ui32 nodeIndex) {
+ SendToLocal(runtime, nodeIndex, new TEvents::TEvPoisonPill());
+ }
+
void WaitForEvServerDisconnected(TTestActorRuntime &runtime) {
TDispatchOptions disconnectOptions;
disconnectOptions.FinalEvents.push_back(
@@ -518,21 +518,21 @@ Y_UNIT_TEST_SUITE(THiveTest) {
UNIT_ASSERT_EQUAL_C(createTabletReply->Record.GetOwner(), testerTablet,
createTabletReply->Record.GetOwner() << " != " << testerTablet);
ui64 tabletId = createTabletReply->Record.GetTabletID();
- while (doWaitForResult) {
+ while (doWaitForResult) {
auto tabletCreationResult = runtime.GrabEdgeEventRethrow<TEvHive::TEvTabletCreationResult>(handle);
- if (tabletId == tabletCreationResult->Record.GetTabletID()) {
- UNIT_ASSERT(tabletCreationResult);
- UNIT_ASSERT_EQUAL_C(tabletCreationResult->Record.GetStatus(), NKikimrProto::OK,
- (ui32)tabletCreationResult->Record.GetStatus() << " != " << (ui32)NKikimrProto::OK);
- break;
- }
+ if (tabletId == tabletCreationResult->Record.GetTabletID()) {
+ UNIT_ASSERT(tabletCreationResult);
+ UNIT_ASSERT_EQUAL_C(tabletCreationResult->Record.GetStatus(), NKikimrProto::OK,
+ (ui32)tabletCreationResult->Record.GetStatus() << " != " << (ui32)NKikimrProto::OK);
+ break;
+ }
}
return tabletId;
}
bool SendDeleteTestTablet(TTestActorRuntime &runtime, ui64 hiveTablet,
- THolder<TEvHive::TEvDeleteTablet> ev, ui32 nodeIndex = 0,
- NKikimrProto::EReplyStatus expectedStatus = NKikimrProto::OK) {
+ THolder<TEvHive::TEvDeleteTablet> ev, ui32 nodeIndex = 0,
+ NKikimrProto::EReplyStatus expectedStatus = NKikimrProto::OK) {
bool seenEvDeleteTabletResult = false;
TTestActorRuntime::TEventObserver prevObserverFunc;
prevObserverFunc = runtime.SetObserverFunc([&](TTestActorRuntimeBase& runtime, TAutoPtr<IEventHandle>& event) {
@@ -542,16 +542,16 @@ Y_UNIT_TEST_SUITE(THiveTest) {
return prevObserverFunc(runtime, event);
});
TActorId senderB = runtime.AllocateEdgeActor(nodeIndex);
- runtime.SendToPipe(hiveTablet, senderB, ev.Release(), 0, GetPipeConfigWithRetries());
- TAutoPtr<IEventHandle> handle;
- auto deleteTabletReply = runtime.GrabEdgeEventRethrow<TEvHive::TEvDeleteTabletReply>(handle);
- UNIT_ASSERT(deleteTabletReply);
- UNIT_ASSERT_EQUAL_C(deleteTabletReply->Record.GetStatus(), expectedStatus,
- (ui32)deleteTabletReply->Record.GetStatus() << " != " << (ui32)expectedStatus);
+ runtime.SendToPipe(hiveTablet, senderB, ev.Release(), 0, GetPipeConfigWithRetries());
+ TAutoPtr<IEventHandle> handle;
+ auto deleteTabletReply = runtime.GrabEdgeEventRethrow<TEvHive::TEvDeleteTabletReply>(handle);
+ UNIT_ASSERT(deleteTabletReply);
+ UNIT_ASSERT_EQUAL_C(deleteTabletReply->Record.GetStatus(), expectedStatus,
+ (ui32)deleteTabletReply->Record.GetStatus() << " != " << (ui32)expectedStatus);
runtime.SetObserverFunc(prevObserverFunc);
return seenEvDeleteTabletResult;
- }
-
+ }
+
bool SendDeleteTestOwner(TTestActorRuntime &runtime, ui64 hiveTablet,
THolder<TEvHive::TEvDeleteOwnerTablets> ev, ui32 nodeIndex = 0,
NKikimrProto::EReplyStatus expectedStatus = NKikimrProto::OK) {
@@ -599,48 +599,48 @@ Y_UNIT_TEST_SUITE(THiveTest) {
(ui32)stopTabletResult->Record.GetStatus() << " != " << (ui32)NKikimrProto::OK);
}
- void SendReassignTablet(TTestActorRuntime &runtime,
- ui64 hiveTablet,
- ui64 tabletId,
+ void SendReassignTablet(TTestActorRuntime &runtime,
+ ui64 hiveTablet,
+ ui64 tabletId,
const TVector<ui32>& channels,
- ui32 nodeIndex) {
+ ui32 nodeIndex) {
TActorId senderB = runtime.AllocateEdgeActor(nodeIndex);
- runtime.SendToPipe(hiveTablet, senderB, new TEvHive::TEvReassignTablet(tabletId, channels), 0, GetPipeConfigWithRetries());
- }
-
- void SendReassignTabletSpace(TTestActorRuntime &runtime,
- ui64 hiveTablet,
- ui64 tabletId,
- const TVector<ui32>& channels,
- ui32 nodeIndex) {
- TActorId senderB = runtime.AllocateEdgeActor(nodeIndex);
- runtime.SendToPipe(hiveTablet, senderB, new TEvHive::TEvReassignTabletSpace(tabletId, channels), 0, GetPipeConfigWithRetries());
- }
-
+ runtime.SendToPipe(hiveTablet, senderB, new TEvHive::TEvReassignTablet(tabletId, channels), 0, GetPipeConfigWithRetries());
+ }
+
+ void SendReassignTabletSpace(TTestActorRuntime &runtime,
+ ui64 hiveTablet,
+ ui64 tabletId,
+ const TVector<ui32>& channels,
+ ui32 nodeIndex) {
+ TActorId senderB = runtime.AllocateEdgeActor(nodeIndex);
+ runtime.SendToPipe(hiveTablet, senderB, new TEvHive::TEvReassignTabletSpace(tabletId, channels), 0, GetPipeConfigWithRetries());
+ }
+
void MakeSureTabletIsDown(TTestActorRuntime &runtime, ui64 tabletId, ui32 nodeIndex) {
TActorId sender = runtime.AllocateEdgeActor(nodeIndex);
- runtime.ConnectToPipe(tabletId, sender, nodeIndex, NTabletPipe::TClientConfig());
+ runtime.ConnectToPipe(tabletId, sender, nodeIndex, NTabletPipe::TClientConfig());
bool isException = false;
- TEvTabletPipe::TEvClientConnected* clientConnectedResult;
+ TEvTabletPipe::TEvClientConnected* clientConnectedResult;
TAutoPtr<IEventHandle> handle;
try {
- do {
- clientConnectedResult = runtime.GrabEdgeEventRethrow<TEvTabletPipe::TEvClientConnected>(handle);
- } while(handle->Recipient != sender);
+ do {
+ clientConnectedResult = runtime.GrabEdgeEventRethrow<TEvTabletPipe::TEvClientConnected>(handle);
+ } while(handle->Recipient != sender);
} catch (...) {
isException = true;
}
- UNIT_ASSERT(isException || clientConnectedResult->Status != NKikimrProto::OK);
+ UNIT_ASSERT(isException || clientConnectedResult->Status != NKikimrProto::OK);
runtime.ResetScheduledCount();
}
- void CreateLocal(TTestActorRuntime &runtime, ui32 nodeIndex, TLocalConfig::TPtr localConfig = {}) {
- if (localConfig == nullptr) {
- localConfig = new TLocalConfig();
+ void CreateLocal(TTestActorRuntime &runtime, ui32 nodeIndex, TLocalConfig::TPtr localConfig = {}) {
+ if (localConfig == nullptr) {
+ localConfig = new TLocalConfig();
localConfig->TabletClassInfo[TTabletTypes::Dummy].SetupInfo = new TTabletSetupInfo(&CreateFlatDummyTablet,
- TMailboxType::Simple, 0,
- TMailboxType::Simple, 0);
- }
+ TMailboxType::Simple, 0,
+ TMailboxType::Simple, 0);
+ }
TTenantPoolConfig::TPtr tenantPoolConfig = new TTenantPoolConfig(localConfig);
tenantPoolConfig->AddStaticSlot(DOMAIN_NAME);
@@ -650,39 +650,39 @@ Y_UNIT_TEST_SUITE(THiveTest) {
runtime.RegisterService(MakeTenantPoolRootID(), actorId, nodeIndex);
}
- void CreateLocalForTenant(TTestActorRuntime &runtime, ui32 nodeIndex, const TString& tenant) {
- TLocalConfig::TPtr localConfig(new TLocalConfig());
- localConfig->TabletClassInfo[TTabletTypes::Dummy].SetupInfo = new TTabletSetupInfo(
+ void CreateLocalForTenant(TTestActorRuntime &runtime, ui32 nodeIndex, const TString& tenant) {
+ TLocalConfig::TPtr localConfig(new TLocalConfig());
+ localConfig->TabletClassInfo[TTabletTypes::Dummy].SetupInfo = new TTabletSetupInfo(
&CreateFlatDummyTablet,
- TMailboxType::Simple, 0,
- TMailboxType::Simple, 0);
- localConfig->TabletClassInfo[TTabletTypes::Hive].SetupInfo = new TTabletSetupInfo(
- &CreateDefaultHive,
- TMailboxType::Simple, 0,
- TMailboxType::Simple, 0);
- TTenantPoolConfig::TPtr tenantPoolConfig = new TTenantPoolConfig(localConfig);
- tenantPoolConfig->AddStaticSlot(tenant);
-
- TActorId actorId = runtime.Register(
- CreateTenantPool(tenantPoolConfig), nodeIndex, 0, TMailboxType::Revolving, 0);
- runtime.EnableScheduleForActor(actorId, true);
- runtime.RegisterService(MakeTenantPoolID(runtime.GetNodeId(nodeIndex)), actorId, nodeIndex);
- }
-
- void MakeSureTabletIsUp(TTestActorRuntime &runtime, ui64 tabletId, ui32 nodeIndex, NTabletPipe::TClientConfig* pipeConfig = nullptr, bool* roleConnected = nullptr) {
+ TMailboxType::Simple, 0,
+ TMailboxType::Simple, 0);
+ localConfig->TabletClassInfo[TTabletTypes::Hive].SetupInfo = new TTabletSetupInfo(
+ &CreateDefaultHive,
+ TMailboxType::Simple, 0,
+ TMailboxType::Simple, 0);
+ TTenantPoolConfig::TPtr tenantPoolConfig = new TTenantPoolConfig(localConfig);
+ tenantPoolConfig->AddStaticSlot(tenant);
+
+ TActorId actorId = runtime.Register(
+ CreateTenantPool(tenantPoolConfig), nodeIndex, 0, TMailboxType::Revolving, 0);
+ runtime.EnableScheduleForActor(actorId, true);
+ runtime.RegisterService(MakeTenantPoolID(runtime.GetNodeId(nodeIndex)), actorId, nodeIndex);
+ }
+
+ void MakeSureTabletIsUp(TTestActorRuntime &runtime, ui64 tabletId, ui32 nodeIndex, NTabletPipe::TClientConfig* pipeConfig = nullptr, bool* roleConnected = nullptr) {
TActorId sender = runtime.AllocateEdgeActor(nodeIndex);
- runtime.ConnectToPipe(tabletId, sender, nodeIndex, pipeConfig ? *pipeConfig : GetPipeConfigWithRetries());
- for(;;) {
- TAutoPtr<IEventHandle> handle;
- auto clientConnectedResult = runtime.GrabEdgeEventRethrow<TEvTabletPipe::TEvClientConnected>(handle);
- if (handle->Recipient == sender) {
- UNIT_ASSERT(clientConnectedResult->Status == NKikimrProto::OK);
- if (roleConnected != nullptr) {
+ runtime.ConnectToPipe(tabletId, sender, nodeIndex, pipeConfig ? *pipeConfig : GetPipeConfigWithRetries());
+ for(;;) {
+ TAutoPtr<IEventHandle> handle;
+ auto clientConnectedResult = runtime.GrabEdgeEventRethrow<TEvTabletPipe::TEvClientConnected>(handle);
+ if (handle->Recipient == sender) {
+ UNIT_ASSERT(clientConnectedResult->Status == NKikimrProto::OK);
+ if (roleConnected != nullptr) {
*roleConnected = clientConnectedResult->Leader;
- }
- break;
- }
- }
+ }
+ break;
+ }
+ }
}
void MakeSureTheTabletIsDeleted(TTestActorRuntime &runtime, ui64 hiveTablet, ui64 tabletId) {
@@ -695,950 +695,950 @@ Y_UNIT_TEST_SUITE(THiveTest) {
}
}
- void WaitForTabletIsUp(
- TTestActorRuntime &runtime,
- i64 tabletId,
- ui32 nodeIndex,
- NTabletPipe::TClientConfig* pipeConfig = nullptr,
- bool* roleConnected = nullptr,
- ui32 maxAttempts = 10) {
+ void WaitForTabletIsUp(
+ TTestActorRuntime &runtime,
+ i64 tabletId,
+ ui32 nodeIndex,
+ NTabletPipe::TClientConfig* pipeConfig = nullptr,
+ bool* roleConnected = nullptr,
+ ui32 maxAttempts = 10) {
TActorId sender = runtime.AllocateEdgeActor(nodeIndex);
- ui32 attempts = 0;
- runtime.ConnectToPipe(tabletId, sender, nodeIndex, pipeConfig ? *pipeConfig : GetPipeConfigWithRetries());
- for(;;) {
- TAutoPtr<IEventHandle> handle;
- auto result = runtime.GrabEdgeEventsRethrow<TEvTabletPipe::TEvClientConnected, TEvTabletPipe::TEvClientDestroyed>(handle);
- if (handle->Recipient == sender) {
- if (std::get<TEvTabletPipe::TEvClientDestroyed*>(result) != nullptr) {
- UNIT_ASSERT(++attempts < maxAttempts);
- runtime.ConnectToPipe(tabletId, sender, nodeIndex, pipeConfig ? *pipeConfig : GetPipeConfigWithRetries());
- continue;
- }
- TEvTabletPipe::TEvClientConnected* event = std::get<TEvTabletPipe::TEvClientConnected*>(result);
- UNIT_ASSERT(event != nullptr);
- UNIT_ASSERT(event->Type() == TEvTabletPipe::TEvClientConnected::EventType);
- UNIT_ASSERT(event->Status == NKikimrProto::OK);
- if (roleConnected != nullptr) {
+ ui32 attempts = 0;
+ runtime.ConnectToPipe(tabletId, sender, nodeIndex, pipeConfig ? *pipeConfig : GetPipeConfigWithRetries());
+ for(;;) {
+ TAutoPtr<IEventHandle> handle;
+ auto result = runtime.GrabEdgeEventsRethrow<TEvTabletPipe::TEvClientConnected, TEvTabletPipe::TEvClientDestroyed>(handle);
+ if (handle->Recipient == sender) {
+ if (std::get<TEvTabletPipe::TEvClientDestroyed*>(result) != nullptr) {
+ UNIT_ASSERT(++attempts < maxAttempts);
+ runtime.ConnectToPipe(tabletId, sender, nodeIndex, pipeConfig ? *pipeConfig : GetPipeConfigWithRetries());
+ continue;
+ }
+ TEvTabletPipe::TEvClientConnected* event = std::get<TEvTabletPipe::TEvClientConnected*>(result);
+ UNIT_ASSERT(event != nullptr);
+ UNIT_ASSERT(event->Type() == TEvTabletPipe::TEvClientConnected::EventType);
+ UNIT_ASSERT(event->Status == NKikimrProto::OK);
+ if (roleConnected != nullptr) {
*roleConnected = event->Leader;
- }
- break;
- }
- }
- }
-
- bool CheckTabletIsUp(
- TTestActorRuntime &runtime,
- i64 tabletId,
- ui32 nodeIndex,
- NTabletPipe::TClientConfig* pipeConfig = nullptr,
- bool* roleConnected = nullptr,
- ui32 maxAttempts = 10) {
+ }
+ break;
+ }
+ }
+ }
+
+ bool CheckTabletIsUp(
+ TTestActorRuntime &runtime,
+ i64 tabletId,
+ ui32 nodeIndex,
+ NTabletPipe::TClientConfig* pipeConfig = nullptr,
+ bool* roleConnected = nullptr,
+ ui32 maxAttempts = 10) {
TActorId sender = runtime.AllocateEdgeActor(nodeIndex);
- ui32 attempts = 0;
- runtime.ConnectToPipe(tabletId, sender, nodeIndex, pipeConfig ? *pipeConfig : GetPipeConfigWithRetries());
- for(;;) {
- TAutoPtr<IEventHandle> handle;
- auto result = runtime.GrabEdgeEventsRethrow<TEvTabletPipe::TEvClientConnected, TEvTabletPipe::TEvClientDestroyed>(handle);
- if (handle->Recipient == sender) {
- if (std::get<TEvTabletPipe::TEvClientDestroyed*>(result) != nullptr) {
- if (++attempts >= maxAttempts) {
- Ctest << "Couldn't establish pipe because of TEvClientDestroyed" << Endl;
- return false;
- }
- runtime.ConnectToPipe(tabletId, sender, nodeIndex, pipeConfig ? *pipeConfig : GetPipeConfigWithRetries());
- continue;
- }
- TEvTabletPipe::TEvClientConnected* event = std::get<TEvTabletPipe::TEvClientConnected*>(result);
- if ((event != nullptr)
- && (event->Type() == TEvTabletPipe::TEvClientConnected::EventType)
- && (event->Status == NKikimrProto::OK)) {
- if (roleConnected != nullptr) {
+ ui32 attempts = 0;
+ runtime.ConnectToPipe(tabletId, sender, nodeIndex, pipeConfig ? *pipeConfig : GetPipeConfigWithRetries());
+ for(;;) {
+ TAutoPtr<IEventHandle> handle;
+ auto result = runtime.GrabEdgeEventsRethrow<TEvTabletPipe::TEvClientConnected, TEvTabletPipe::TEvClientDestroyed>(handle);
+ if (handle->Recipient == sender) {
+ if (std::get<TEvTabletPipe::TEvClientDestroyed*>(result) != nullptr) {
+ if (++attempts >= maxAttempts) {
+ Ctest << "Couldn't establish pipe because of TEvClientDestroyed" << Endl;
+ return false;
+ }
+ runtime.ConnectToPipe(tabletId, sender, nodeIndex, pipeConfig ? *pipeConfig : GetPipeConfigWithRetries());
+ continue;
+ }
+ TEvTabletPipe::TEvClientConnected* event = std::get<TEvTabletPipe::TEvClientConnected*>(result);
+ if ((event != nullptr)
+ && (event->Type() == TEvTabletPipe::TEvClientConnected::EventType)
+ && (event->Status == NKikimrProto::OK)) {
+ if (roleConnected != nullptr) {
*roleConnected = event->Leader;
- }
- return true;
- } else {
- if ((event != nullptr)
- && (event->Type() == TEvTabletPipe::TEvClientConnected::EventType)
- && (event->Status == NKikimrProto::TRYLATER || event->Status == NKikimrProto::ERROR)) {
- if (++attempts >= maxAttempts) {
- Ctest << "Couldn't establish pipe because of status " << event->Status << Endl;
- return false;
- }
- runtime.ConnectToPipe(tabletId, sender, nodeIndex, pipeConfig ? *pipeConfig : GetPipeConfigWithRetries());
- continue;
- }
- return false;
- }
- }
- }
- }
-
- static bool TabletActiveEvent(IEventHandle& ev) {
- if (ev.GetTypeRewrite() == NNodeWhiteboard::TEvWhiteboard::EvTabletStateUpdate) {
- if (ev.Get<NNodeWhiteboard::TEvWhiteboard::TEvTabletStateUpdate>()->Record.GetState()
- == NKikimrWhiteboard::TTabletStateInfo::Active) {
- return true;
- }
- }
- /*if (ev.GetTypeRewrite() == TEvLocal::TEvTabletStatus::EventType) {
- if (ev.Get<TEvLocal::TEvTabletStatus>()->Record.GetStatus() == TEvLocal::TEvTabletStatus::StatusOk) {
- return true;
- }
- }*/
- return false;
- }
-
- void WaitForTabletsBecomeActive(TTestActorRuntime& runtime, ui32 count) {
- TDispatchOptions options;
- options.FinalEvents.emplace_back(&NTestSuiteTHiveTest::TabletActiveEvent, count);
- runtime.DispatchEvents(options);
- }
-
+ }
+ return true;
+ } else {
+ if ((event != nullptr)
+ && (event->Type() == TEvTabletPipe::TEvClientConnected::EventType)
+ && (event->Status == NKikimrProto::TRYLATER || event->Status == NKikimrProto::ERROR)) {
+ if (++attempts >= maxAttempts) {
+ Ctest << "Couldn't establish pipe because of status " << event->Status << Endl;
+ return false;
+ }
+ runtime.ConnectToPipe(tabletId, sender, nodeIndex, pipeConfig ? *pipeConfig : GetPipeConfigWithRetries());
+ continue;
+ }
+ return false;
+ }
+ }
+ }
+ }
+
+ static bool TabletActiveEvent(IEventHandle& ev) {
+ if (ev.GetTypeRewrite() == NNodeWhiteboard::TEvWhiteboard::EvTabletStateUpdate) {
+ if (ev.Get<NNodeWhiteboard::TEvWhiteboard::TEvTabletStateUpdate>()->Record.GetState()
+ == NKikimrWhiteboard::TTabletStateInfo::Active) {
+ return true;
+ }
+ }
+ /*if (ev.GetTypeRewrite() == TEvLocal::TEvTabletStatus::EventType) {
+ if (ev.Get<TEvLocal::TEvTabletStatus>()->Record.GetStatus() == TEvLocal::TEvTabletStatus::StatusOk) {
+ return true;
+ }
+ }*/
+ return false;
+ }
+
+ void WaitForTabletsBecomeActive(TTestActorRuntime& runtime, ui32 count) {
+ TDispatchOptions options;
+ options.FinalEvents.emplace_back(&NTestSuiteTHiveTest::TabletActiveEvent, count);
+ runtime.DispatchEvents(options);
+ }
+
Y_UNIT_TEST(TestCreateTablet) {
TTestBasicRuntime runtime(1, false);
Setup(runtime, true);
const ui64 hiveTablet = MakeDefaultHiveID(0);
const ui64 testerTablet = MakeDefaultHiveID(1);
CreateTestBootstrapper(runtime, CreateTestTabletInfo(hiveTablet, TTabletTypes::FLAT_HIVE), &CreateDefaultHive);
- MakeSureTabletIsUp(runtime, hiveTablet, 0);
- TTabletTypes::EType tabletType = TTabletTypes::Dummy;
+ MakeSureTabletIsUp(runtime, hiveTablet, 0);
+ TTabletTypes::EType tabletType = TTabletTypes::Dummy;
ui64 tabletId = SendCreateTestTablet(runtime, hiveTablet, testerTablet, MakeHolder<TEvHive::TEvCreateTablet>(testerTablet, 0, tabletType, BINDED_CHANNELS), 0, true);
MakeSureTabletIsUp(runtime, tabletId, 0);
}
- Y_UNIT_TEST(TestBlockCreateTablet) {
- TTestBasicRuntime runtime(1, false);
- Setup(runtime, true);
- const ui64 hiveTablet = MakeDefaultHiveID(0);
- const ui64 testerTablet = MakeDefaultHiveID(1);
+ Y_UNIT_TEST(TestBlockCreateTablet) {
+ TTestBasicRuntime runtime(1, false);
+ Setup(runtime, true);
+ const ui64 hiveTablet = MakeDefaultHiveID(0);
+ const ui64 testerTablet = MakeDefaultHiveID(1);
CreateTestBootstrapper(runtime, CreateTestTabletInfo(hiveTablet, TTabletTypes::FLAT_HIVE), &CreateDefaultHive);
- MakeSureTabletIsUp(runtime, hiveTablet, 0);
- TTabletTypes::EType tabletType = TTabletTypes::Dummy;
+ MakeSureTabletIsUp(runtime, hiveTablet, 0);
+ TTabletTypes::EType tabletType = TTabletTypes::Dummy;
ui64 tabletId = SendCreateTestTablet(runtime, hiveTablet, testerTablet, MakeHolder<TEvHive::TEvCreateTablet>(testerTablet, 0, tabletType, BINDED_CHANNELS), 0, true);
- MakeSureTabletIsUp(runtime, tabletId, 0);
+ MakeSureTabletIsUp(runtime, tabletId, 0);
THolder<TEvHive::TEvDeleteOwnerTablets> deleteOwner = MakeHolder<TEvHive::TEvDeleteOwnerTablets>(testerTablet, 1);
TActorId senderB = runtime.AllocateEdgeActor(0);
- runtime.SendToPipe(hiveTablet, senderB, deleteOwner.Release(), 0, GetPipeConfigWithRetries());
- TAutoPtr<IEventHandle> handle;
- auto deleteTabletsReply = runtime.GrabEdgeEventRethrow<TEvHive::TEvDeleteOwnerTabletsReply>(handle);
- UNIT_ASSERT(deleteTabletsReply);
- runtime.SendToPipe(hiveTablet, senderB, new TEvHive::TEvCreateTablet(testerTablet, 1, tabletType, BINDED_CHANNELS), 0, GetPipeConfigWithRetries());
- auto createTabletReply = runtime.GrabEdgeEventRethrow<TEvHive::TEvCreateTabletReply>(handle);
- UNIT_ASSERT(createTabletReply);
- UNIT_ASSERT_EQUAL_C(createTabletReply->Record.GetStatus(), NKikimrProto::BLOCKED,
- createTabletReply->Record.GetStatus() << " != " << NKikimrProto::BLOCKED);
- }
-
- Y_UNIT_TEST(TestCreate100Tablets) {
- TTestBasicRuntime runtime(1, false);
- Setup(runtime, true);
- const ui64 hiveTablet = MakeDefaultHiveID(0);
- const ui64 testerTablet = MakeDefaultHiveID(1);
+ runtime.SendToPipe(hiveTablet, senderB, deleteOwner.Release(), 0, GetPipeConfigWithRetries());
+ TAutoPtr<IEventHandle> handle;
+ auto deleteTabletsReply = runtime.GrabEdgeEventRethrow<TEvHive::TEvDeleteOwnerTabletsReply>(handle);
+ UNIT_ASSERT(deleteTabletsReply);
+ runtime.SendToPipe(hiveTablet, senderB, new TEvHive::TEvCreateTablet(testerTablet, 1, tabletType, BINDED_CHANNELS), 0, GetPipeConfigWithRetries());
+ auto createTabletReply = runtime.GrabEdgeEventRethrow<TEvHive::TEvCreateTabletReply>(handle);
+ UNIT_ASSERT(createTabletReply);
+ UNIT_ASSERT_EQUAL_C(createTabletReply->Record.GetStatus(), NKikimrProto::BLOCKED,
+ createTabletReply->Record.GetStatus() << " != " << NKikimrProto::BLOCKED);
+ }
+
+ Y_UNIT_TEST(TestCreate100Tablets) {
+ TTestBasicRuntime runtime(1, false);
+ Setup(runtime, true);
+ const ui64 hiveTablet = MakeDefaultHiveID(0);
+ const ui64 testerTablet = MakeDefaultHiveID(1);
CreateTestBootstrapper(runtime, CreateTestTabletInfo(hiveTablet, TTabletTypes::FLAT_HIVE), &CreateDefaultHive);
- MakeSureTabletIsUp(runtime, hiveTablet, 0);
- TTabletTypes::EType tabletType = TTabletTypes::Dummy;
- TVector<TTabletId> tablets;
+ MakeSureTabletIsUp(runtime, hiveTablet, 0);
+ TTabletTypes::EType tabletType = TTabletTypes::Dummy;
+ TVector<TTabletId> tablets;
TActorId senderB = runtime.AllocateEdgeActor(0);
- for (int i = 0; i < 100; ++i) {
- runtime.SendToPipe(hiveTablet, senderB, new TEvHive::TEvCreateTablet(testerTablet, i, tabletType, BINDED_CHANNELS), 0, GetPipeConfigWithRetries());
- }
- for (int i = 0; i < 100; ++i) {
- TAutoPtr<IEventHandle> handle;
- auto createTabletReply = runtime.GrabEdgeEventRethrow<TEvHive::TEvCreateTabletReply>(handle);
- ui64 tabletId = createTabletReply->Record.GetTabletID();
- tablets.emplace_back(tabletId);
- }
- for (TTabletId tabletId : tablets) {
- MakeSureTabletIsUp(runtime, tabletId, 0);
- }
+ for (int i = 0; i < 100; ++i) {
+ runtime.SendToPipe(hiveTablet, senderB, new TEvHive::TEvCreateTablet(testerTablet, i, tabletType, BINDED_CHANNELS), 0, GetPipeConfigWithRetries());
+ }
+ for (int i = 0; i < 100; ++i) {
+ TAutoPtr<IEventHandle> handle;
+ auto createTabletReply = runtime.GrabEdgeEventRethrow<TEvHive::TEvCreateTabletReply>(handle);
+ ui64 tabletId = createTabletReply->Record.GetTabletID();
+ tablets.emplace_back(tabletId);
+ }
+ for (TTabletId tabletId : tablets) {
+ MakeSureTabletIsUp(runtime, tabletId, 0);
+ }
}
- Y_UNIT_TEST(TestDrain) {
- const int NUM_NODES = 3;
- const int NUM_TABLETS = 100;
- TTestBasicRuntime runtime(NUM_NODES, false);
- Setup(runtime, true);
- const ui64 hiveTablet = MakeDefaultHiveID(0);
- const ui64 testerTablet = MakeDefaultHiveID(1);
+ Y_UNIT_TEST(TestDrain) {
+ const int NUM_NODES = 3;
+ const int NUM_TABLETS = 100;
+ TTestBasicRuntime runtime(NUM_NODES, false);
+ Setup(runtime, true);
+ const ui64 hiveTablet = MakeDefaultHiveID(0);
+ const ui64 testerTablet = MakeDefaultHiveID(1);
CreateTestBootstrapper(runtime, CreateTestTabletInfo(hiveTablet, TTabletTypes::FLAT_HIVE), &CreateDefaultHive);
- {
- TDispatchOptions options;
- options.FinalEvents.emplace_back(TEvLocal::EvStatus, NUM_NODES);
- runtime.DispatchEvents(options);
- }
- TTabletTypes::EType tabletType = TTabletTypes::Dummy;
- std::unordered_set<TTabletId> tablets;
- TActorId senderA = runtime.AllocateEdgeActor(0);
- for (int i = 0; i < NUM_TABLETS; ++i) {
- THolder<TEvHive::TEvCreateTablet> ev(new TEvHive::TEvCreateTablet(testerTablet, 100500 + i, tabletType, BINDED_CHANNELS));
- auto* followerGroup = ev->Record.AddFollowerGroups();
- followerGroup->SetFollowerCount(1);
- runtime.SendToPipe(hiveTablet, senderA, ev.Release(), 0, GetPipeConfigWithRetries());
- }
- for (int i = 0; i < NUM_TABLETS; ++i) {
- TAutoPtr<IEventHandle> handle;
- auto createTabletReply = runtime.GrabEdgeEventRethrow<TEvHive::TEvCreateTabletReply>(handle);
- ui64 tabletId = createTabletReply->Record.GetTabletID();
- tablets.emplace(tabletId);
- }
- NTabletPipe::TClientConfig pipeConfig;
- pipeConfig.RetryPolicy = NTabletPipe::TClientRetryPolicy::WithRetries();
- pipeConfig.ForceFollower = true;
- for (TTabletId tabletId : tablets) {
- MakeSureTabletIsUp(runtime, tabletId, 0, &pipeConfig);
- }
-
- ui32 nodeId = runtime.GetNodeId(0);
- int drainMovements = 0;
- {
- runtime.SendToPipe(hiveTablet, senderA, new TEvHive::TEvDrainNode(nodeId));
- TAutoPtr<IEventHandle> handle;
- auto drainResponse = runtime.GrabEdgeEventRethrow<TEvHive::TEvDrainNodeResult>(handle, TDuration::Seconds(30));
- UNIT_ASSERT_VALUES_EQUAL(drainResponse->Record.GetStatus(), NKikimrProto::EReplyStatus::OK);
- drainMovements = drainResponse->Record.GetMovements();
- UNIT_ASSERT(drainMovements > 0);
- }
-
- std::unordered_map<NKikimrWhiteboard::TTabletStateInfo::ETabletState, int> tabletStates;
- {
- TAutoPtr<IEventHandle> handle;
- TActorId whiteboard = NNodeWhiteboard::MakeNodeWhiteboardServiceId(nodeId);
- runtime.Send(new IEventHandle(whiteboard, senderA, new NNodeWhiteboard::TEvWhiteboard::TEvTabletStateRequest()));
- NNodeWhiteboard::TEvWhiteboard::TEvTabletStateResponse* wbResponse = runtime.GrabEdgeEventRethrow<NNodeWhiteboard::TEvWhiteboard::TEvTabletStateResponse>(handle);
- for (const NKikimrWhiteboard::TTabletStateInfo& tabletInfo : wbResponse->Record.GetTabletStateInfo()) {
- if (tablets.count(tabletInfo.GetTabletId()) == 0) {
- continue;
- }
- tabletStates[tabletInfo.GetState()]++;
- if (tabletInfo.GetState() != NKikimrWhiteboard::TTabletStateInfo::Dead) {
- Ctest << "Tablet " << tabletInfo.GetTabletId() << "." << tabletInfo.GetFollowerId()
- << " is not dead yet (" << NKikimrWhiteboard::TTabletStateInfo::ETabletState_Name(tabletInfo.GetState()) << ")" << Endl;
- }
- }
- }
- UNIT_ASSERT_VALUES_EQUAL(tabletStates.size(), 1);
- UNIT_ASSERT_VALUES_EQUAL(tabletStates[NKikimrWhiteboard::TTabletStateInfo::Dead], drainMovements);
- }
-
- Y_UNIT_TEST(TestCreateSubHiveCreateTablet) {
- TTestBasicRuntime runtime(1, false);
- Setup(runtime, true);
-
- const ui64 hiveTablet = MakeDefaultHiveID(0);
- const ui64 testerTablet = MakeDefaultHiveID(1);
+ {
+ TDispatchOptions options;
+ options.FinalEvents.emplace_back(TEvLocal::EvStatus, NUM_NODES);
+ runtime.DispatchEvents(options);
+ }
+ TTabletTypes::EType tabletType = TTabletTypes::Dummy;
+ std::unordered_set<TTabletId> tablets;
+ TActorId senderA = runtime.AllocateEdgeActor(0);
+ for (int i = 0; i < NUM_TABLETS; ++i) {
+ THolder<TEvHive::TEvCreateTablet> ev(new TEvHive::TEvCreateTablet(testerTablet, 100500 + i, tabletType, BINDED_CHANNELS));
+ auto* followerGroup = ev->Record.AddFollowerGroups();
+ followerGroup->SetFollowerCount(1);
+ runtime.SendToPipe(hiveTablet, senderA, ev.Release(), 0, GetPipeConfigWithRetries());
+ }
+ for (int i = 0; i < NUM_TABLETS; ++i) {
+ TAutoPtr<IEventHandle> handle;
+ auto createTabletReply = runtime.GrabEdgeEventRethrow<TEvHive::TEvCreateTabletReply>(handle);
+ ui64 tabletId = createTabletReply->Record.GetTabletID();
+ tablets.emplace(tabletId);
+ }
+ NTabletPipe::TClientConfig pipeConfig;
+ pipeConfig.RetryPolicy = NTabletPipe::TClientRetryPolicy::WithRetries();
+ pipeConfig.ForceFollower = true;
+ for (TTabletId tabletId : tablets) {
+ MakeSureTabletIsUp(runtime, tabletId, 0, &pipeConfig);
+ }
+
+ ui32 nodeId = runtime.GetNodeId(0);
+ int drainMovements = 0;
+ {
+ runtime.SendToPipe(hiveTablet, senderA, new TEvHive::TEvDrainNode(nodeId));
+ TAutoPtr<IEventHandle> handle;
+ auto drainResponse = runtime.GrabEdgeEventRethrow<TEvHive::TEvDrainNodeResult>(handle, TDuration::Seconds(30));
+ UNIT_ASSERT_VALUES_EQUAL(drainResponse->Record.GetStatus(), NKikimrProto::EReplyStatus::OK);
+ drainMovements = drainResponse->Record.GetMovements();
+ UNIT_ASSERT(drainMovements > 0);
+ }
+
+ std::unordered_map<NKikimrWhiteboard::TTabletStateInfo::ETabletState, int> tabletStates;
+ {
+ TAutoPtr<IEventHandle> handle;
+ TActorId whiteboard = NNodeWhiteboard::MakeNodeWhiteboardServiceId(nodeId);
+ runtime.Send(new IEventHandle(whiteboard, senderA, new NNodeWhiteboard::TEvWhiteboard::TEvTabletStateRequest()));
+ NNodeWhiteboard::TEvWhiteboard::TEvTabletStateResponse* wbResponse = runtime.GrabEdgeEventRethrow<NNodeWhiteboard::TEvWhiteboard::TEvTabletStateResponse>(handle);
+ for (const NKikimrWhiteboard::TTabletStateInfo& tabletInfo : wbResponse->Record.GetTabletStateInfo()) {
+ if (tablets.count(tabletInfo.GetTabletId()) == 0) {
+ continue;
+ }
+ tabletStates[tabletInfo.GetState()]++;
+ if (tabletInfo.GetState() != NKikimrWhiteboard::TTabletStateInfo::Dead) {
+ Ctest << "Tablet " << tabletInfo.GetTabletId() << "." << tabletInfo.GetFollowerId()
+ << " is not dead yet (" << NKikimrWhiteboard::TTabletStateInfo::ETabletState_Name(tabletInfo.GetState()) << ")" << Endl;
+ }
+ }
+ }
+ UNIT_ASSERT_VALUES_EQUAL(tabletStates.size(), 1);
+ UNIT_ASSERT_VALUES_EQUAL(tabletStates[NKikimrWhiteboard::TTabletStateInfo::Dead], drainMovements);
+ }
+
+ Y_UNIT_TEST(TestCreateSubHiveCreateTablet) {
+ TTestBasicRuntime runtime(1, false);
+ Setup(runtime, true);
+
+ const ui64 hiveTablet = MakeDefaultHiveID(0);
+ const ui64 testerTablet = MakeDefaultHiveID(1);
CreateTestBootstrapper(runtime, CreateTestTabletInfo(hiveTablet, TTabletTypes::Hive), &CreateDefaultHive);
CreateTestBootstrapper(runtime, CreateTestTabletInfo(TTestTxConfig::SchemeShard, TTabletTypes::SchemeShard), &CreateFlatTxSchemeShard);
- MakeSureTabletIsUp(runtime, hiveTablet, 0); // root hive good
+ MakeSureTabletIsUp(runtime, hiveTablet, 0); // root hive good
MakeSureTabletIsUp(runtime, TTestTxConfig::SchemeShard, 0); // root ss good
-
+
TActorId sender = runtime.AllocateEdgeActor(0);
InitSchemeRoot(runtime, sender);
-
- TSubDomainKey subdomainKey;
-
- // Create subdomain
- do {
+
+ TSubDomainKey subdomainKey;
+
+ // Create subdomain
+ do {
auto x = MakeHolder<NSchemeShard::TEvSchemeShard::TEvModifySchemeTransaction>();
auto* tran = x->Record.AddTransaction();
- tran->SetWorkingDir("/dc-1");
+ tran->SetWorkingDir("/dc-1");
tran->SetOperationType(NKikimrSchemeOp::ESchemeOpCreateSubDomain);
- auto* subd = tran->MutableSubDomain();
- subd->SetName("tenant1");
+ auto* subd = tran->MutableSubDomain();
+ subd->SetName("tenant1");
runtime.SendToPipe(TTestTxConfig::SchemeShard, sender, x.Release());
- TAutoPtr<IEventHandle> handle;
+ TAutoPtr<IEventHandle> handle;
auto reply = runtime.GrabEdgeEventRethrow<NSchemeShard::TEvSchemeShard::TEvModifySchemeTransactionResult>(handle, TDuration::MilliSeconds(100));
- if (reply) {
- subdomainKey = TSubDomainKey(reply->Record.GetSchemeshardId(), reply->Record.GetPathId());
+ if (reply) {
+ subdomainKey = TSubDomainKey(reply->Record.GetSchemeshardId(), reply->Record.GetPathId());
UNIT_ASSERT_VALUES_EQUAL(reply->Record.GetStatus(), (ui32)NKikimrScheme::EStatus::StatusAccepted);
- break;
- }
- } while (true);
-
+ break;
+ }
+ } while (true);
+
THolder<TEvHive::TEvCreateTablet> createHive = MakeHolder<TEvHive::TEvCreateTablet>(testerTablet, 0, TTabletTypes::Hive, BINDED_CHANNELS);
- createHive->Record.AddAllowedDomains();
- createHive->Record.MutableAllowedDomains(0)->SetSchemeShard(subdomainKey.first);
- createHive->Record.MutableAllowedDomains(0)->SetPathId(subdomainKey.second);
+ createHive->Record.AddAllowedDomains();
+ createHive->Record.MutableAllowedDomains(0)->SetSchemeShard(subdomainKey.first);
+ createHive->Record.MutableAllowedDomains(0)->SetPathId(subdomainKey.second);
ui64 subHiveTablet = SendCreateTestTablet(runtime, hiveTablet, testerTablet, std::move(createHive), 0, false);
-
- TTestActorRuntime::TEventObserver prevObserverFunc;
- prevObserverFunc = runtime.SetObserverFunc([&](TTestActorRuntimeBase& runtime, TAutoPtr<IEventHandle>& event) {
+
+ TTestActorRuntime::TEventObserver prevObserverFunc;
+ prevObserverFunc = runtime.SetObserverFunc([&](TTestActorRuntimeBase& runtime, TAutoPtr<IEventHandle>& event) {
if (event->GetTypeRewrite() == NSchemeShard::TEvSchemeShard::EvDescribeSchemeResult) {
event->Get<NSchemeShard::TEvSchemeShard::TEvDescribeSchemeResult>()->MutableRecord()->
- MutablePathDescription()->MutableDomainDescription()->MutableProcessingParams()->SetHive(subHiveTablet);
- }
- return prevObserverFunc(runtime, event);
- });
-
- SendToLocal(runtime, 0, new TEvLocal::TEvAddTenant("/dc-1/tenant1"));
-
- MakeSureTabletIsUp(runtime, subHiveTablet, 0); // sub hive good
-
+ MutablePathDescription()->MutableDomainDescription()->MutableProcessingParams()->SetHive(subHiveTablet);
+ }
+ return prevObserverFunc(runtime, event);
+ });
+
+ SendToLocal(runtime, 0, new TEvLocal::TEvAddTenant("/dc-1/tenant1"));
+
+ MakeSureTabletIsUp(runtime, subHiveTablet, 0); // sub hive good
+
THolder<TEvHive::TEvCreateTablet> createTablet = MakeHolder<TEvHive::TEvCreateTablet>(testerTablet, 1, TTabletTypes::Dummy, BINDED_CHANNELS);
- createTablet->Record.AddAllowedDomains();
- createTablet->Record.MutableAllowedDomains(0)->SetSchemeShard(subdomainKey.first);
- createTablet->Record.MutableAllowedDomains(0)->SetPathId(subdomainKey.second);
+ createTablet->Record.AddAllowedDomains();
+ createTablet->Record.MutableAllowedDomains(0)->SetSchemeShard(subdomainKey.first);
+ createTablet->Record.MutableAllowedDomains(0)->SetPathId(subdomainKey.second);
ui64 tabletId = SendCreateTestTablet(runtime, subHiveTablet, testerTablet, std::move(createTablet), 0, true);
- MakeSureTabletIsUp(runtime, tabletId, 0); // dummy from sub hive also good
- runtime.SetObserverFunc(prevObserverFunc);
- }
-
- Y_UNIT_TEST(TestCheckSubHiveForwarding) {
- TTestBasicRuntime runtime(1, false);
- Setup(runtime, true);
-
- const ui64 hiveTablet = MakeDefaultHiveID(0);
- const ui64 testerTablet = MakeDefaultHiveID(1);
+ MakeSureTabletIsUp(runtime, tabletId, 0); // dummy from sub hive also good
+ runtime.SetObserverFunc(prevObserverFunc);
+ }
+
+ Y_UNIT_TEST(TestCheckSubHiveForwarding) {
+ TTestBasicRuntime runtime(1, false);
+ Setup(runtime, true);
+
+ const ui64 hiveTablet = MakeDefaultHiveID(0);
+ const ui64 testerTablet = MakeDefaultHiveID(1);
CreateTestBootstrapper(runtime, CreateTestTabletInfo(hiveTablet, TTabletTypes::Hive), &CreateDefaultHive);
CreateTestBootstrapper(runtime, CreateTestTabletInfo(TTestTxConfig::SchemeShard, TTabletTypes::SchemeShard), &CreateFlatTxSchemeShard);
- MakeSureTabletIsUp(runtime, hiveTablet, 0); // root hive good
+ MakeSureTabletIsUp(runtime, hiveTablet, 0); // root hive good
MakeSureTabletIsUp(runtime, TTestTxConfig::SchemeShard, 0); // root ss good
-
-
+
+
TActorId sender = runtime.AllocateEdgeActor(0);
InitSchemeRoot(runtime, sender);
-
- TSubDomainKey subdomainKey;
- // Create subdomain
- do {
+
+ TSubDomainKey subdomainKey;
+ // Create subdomain
+ do {
auto x = MakeHolder<NSchemeShard::TEvSchemeShard::TEvModifySchemeTransaction>();
auto* tran = x->Record.AddTransaction();
- tran->SetWorkingDir("/dc-1");
+ tran->SetWorkingDir("/dc-1");
tran->SetOperationType(NKikimrSchemeOp::ESchemeOpCreateSubDomain);
- auto* subd = tran->MutableSubDomain();
- subd->SetName("tenant1");
+ auto* subd = tran->MutableSubDomain();
+ subd->SetName("tenant1");
runtime.SendToPipe(TTestTxConfig::SchemeShard, sender, x.Release());
- TAutoPtr<IEventHandle> handle;
+ TAutoPtr<IEventHandle> handle;
auto reply = runtime.GrabEdgeEventRethrow<NSchemeShard::TEvSchemeShard::TEvModifySchemeTransactionResult>(handle, TDuration::MilliSeconds(100));
- if (reply) {
- subdomainKey = TSubDomainKey(reply->Record.GetSchemeshardId(), reply->Record.GetPathId());
+ if (reply) {
+ subdomainKey = TSubDomainKey(reply->Record.GetSchemeshardId(), reply->Record.GetPathId());
UNIT_ASSERT_VALUES_EQUAL(reply->Record.GetStatus(), (ui32)NKikimrScheme::EStatus::StatusAccepted);
- break;
- }
- } while (true);
-
+ break;
+ }
+ } while (true);
+
THolder<TEvHive::TEvCreateTablet> createHive = MakeHolder<TEvHive::TEvCreateTablet>(testerTablet, 0, TTabletTypes::Hive, BINDED_CHANNELS);
- createHive->Record.AddAllowedDomains();
- createHive->Record.MutableAllowedDomains(0)->SetSchemeShard(subdomainKey.first);
- createHive->Record.MutableAllowedDomains(0)->SetPathId(subdomainKey.second);
+ createHive->Record.AddAllowedDomains();
+ createHive->Record.MutableAllowedDomains(0)->SetSchemeShard(subdomainKey.first);
+ createHive->Record.MutableAllowedDomains(0)->SetPathId(subdomainKey.second);
ui64 subHiveTablet = SendCreateTestTablet(runtime, hiveTablet, testerTablet, std::move(createHive), 0, false);
-
- TTestActorRuntime::TEventObserver prevObserverFunc;
- prevObserverFunc = runtime.SetObserverFunc([&](TTestActorRuntimeBase& runtime, TAutoPtr<IEventHandle>& event) {
+
+ TTestActorRuntime::TEventObserver prevObserverFunc;
+ prevObserverFunc = runtime.SetObserverFunc([&](TTestActorRuntimeBase& runtime, TAutoPtr<IEventHandle>& event) {
if (event->GetTypeRewrite() == NSchemeShard::TEvSchemeShard::EvDescribeSchemeResult) {
event->Get<NSchemeShard::TEvSchemeShard::TEvDescribeSchemeResult>()->MutableRecord()->
- MutablePathDescription()->MutableDomainDescription()->MutableProcessingParams()->SetHive(subHiveTablet);
- }
- return prevObserverFunc(runtime, event);
- });
-
- SendToLocal(runtime, 0, new TEvLocal::TEvAddTenant("/dc-1/tenant1"));
-
- MakeSureTabletIsUp(runtime, subHiveTablet, 0); // sub hive good
-
+ MutablePathDescription()->MutableDomainDescription()->MutableProcessingParams()->SetHive(subHiveTablet);
+ }
+ return prevObserverFunc(runtime, event);
+ });
+
+ SendToLocal(runtime, 0, new TEvLocal::TEvAddTenant("/dc-1/tenant1"));
+
+ MakeSureTabletIsUp(runtime, subHiveTablet, 0); // sub hive good
+
THolder<TEvHive::TEvCreateTablet> createTablet1 = MakeHolder<TEvHive::TEvCreateTablet>(testerTablet, 1, TTabletTypes::Dummy, BINDED_CHANNELS);
- createTablet1->Record.AddAllowedDomains();
- createTablet1->Record.MutableAllowedDomains(0)->SetSchemeShard(subdomainKey.first);
- createTablet1->Record.MutableAllowedDomains(0)->SetPathId(subdomainKey.second);
+ createTablet1->Record.AddAllowedDomains();
+ createTablet1->Record.MutableAllowedDomains(0)->SetSchemeShard(subdomainKey.first);
+ createTablet1->Record.MutableAllowedDomains(0)->SetPathId(subdomainKey.second);
ui64 tabletId1 = SendCreateTestTablet(runtime, hiveTablet, testerTablet, std::move(createTablet1), 0, true);
- MakeSureTabletIsUp(runtime, tabletId1, 0);
-
+ MakeSureTabletIsUp(runtime, tabletId1, 0);
+
THolder<TEvHive::TEvCreateTablet> createTablet2 = MakeHolder<TEvHive::TEvCreateTablet>(testerTablet, 2, TTabletTypes::Dummy, BINDED_CHANNELS);
- createTablet2->Record.AddAllowedDomains();
- createTablet2->Record.MutableAllowedDomains(0)->SetSchemeShard(subdomainKey.first);
- createTablet2->Record.MutableAllowedDomains(0)->SetPathId(subdomainKey.second);
+ createTablet2->Record.AddAllowedDomains();
+ createTablet2->Record.MutableAllowedDomains(0)->SetSchemeShard(subdomainKey.first);
+ createTablet2->Record.MutableAllowedDomains(0)->SetPathId(subdomainKey.second);
ui64 tabletId2 = SendCreateTestTablet(runtime, subHiveTablet, testerTablet, std::move(createTablet2), 0, true);
- MakeSureTabletIsUp(runtime, tabletId2, 0); // dummy from sub hive also good
-
- // retry create request to sub domain hive
+ MakeSureTabletIsUp(runtime, tabletId2, 0); // dummy from sub hive also good
+
+ // retry create request to sub domain hive
createTablet1 = MakeHolder<TEvHive::TEvCreateTablet>(testerTablet, 1, TTabletTypes::Dummy, BINDED_CHANNELS);
- createTablet1->Record.SetTabletID(tabletId1);
-
- runtime.SendToPipe(subHiveTablet, sender, createTablet1.Release(), 0, GetPipeConfigWithRetries());
- TAutoPtr<IEventHandle> handle;
- auto createTabletReply = runtime.GrabEdgeEventRethrow<TEvHive::TEvCreateTabletReply>(handle);
- UNIT_ASSERT(createTabletReply);
- UNIT_ASSERT(createTabletReply->Record.HasForwardRequest());
- UNIT_ASSERT_VALUES_EQUAL(createTabletReply->Record.GetForwardRequest().GetHiveTabletId(), hiveTablet);
-
- // trying to delete same tablet from sub domain hive
+ createTablet1->Record.SetTabletID(tabletId1);
+
+ runtime.SendToPipe(subHiveTablet, sender, createTablet1.Release(), 0, GetPipeConfigWithRetries());
+ TAutoPtr<IEventHandle> handle;
+ auto createTabletReply = runtime.GrabEdgeEventRethrow<TEvHive::TEvCreateTabletReply>(handle);
+ UNIT_ASSERT(createTabletReply);
+ UNIT_ASSERT(createTabletReply->Record.HasForwardRequest());
+ UNIT_ASSERT_VALUES_EQUAL(createTabletReply->Record.GetForwardRequest().GetHiveTabletId(), hiveTablet);
+
+ // trying to delete same tablet from sub domain hive
THolder<TEvHive::TEvDeleteTablet> deleteTablet1 = MakeHolder<TEvHive::TEvDeleteTablet>(testerTablet, 1, 0);
- deleteTablet1->Record.AddTabletID(tabletId1);
-
- runtime.SendToPipe(subHiveTablet, sender, deleteTablet1.Release(), 0, GetPipeConfigWithRetries());
- auto deleteTabletReply = runtime.GrabEdgeEventRethrow<TEvHive::TEvDeleteTabletReply>(handle);
- UNIT_ASSERT(deleteTabletReply);
- UNIT_ASSERT(deleteTabletReply->Record.HasForwardRequest());
- UNIT_ASSERT_VALUES_EQUAL(deleteTabletReply->Record.GetForwardRequest().GetHiveTabletId(), hiveTablet);
-
- // retry create request to root hive
+ deleteTablet1->Record.AddTabletID(tabletId1);
+
+ runtime.SendToPipe(subHiveTablet, sender, deleteTablet1.Release(), 0, GetPipeConfigWithRetries());
+ auto deleteTabletReply = runtime.GrabEdgeEventRethrow<TEvHive::TEvDeleteTabletReply>(handle);
+ UNIT_ASSERT(deleteTabletReply);
+ UNIT_ASSERT(deleteTabletReply->Record.HasForwardRequest());
+ UNIT_ASSERT_VALUES_EQUAL(deleteTabletReply->Record.GetForwardRequest().GetHiveTabletId(), hiveTablet);
+
+ // retry create request to root hive
createTablet2 = MakeHolder<TEvHive::TEvCreateTablet>(testerTablet, 2, TTabletTypes::Dummy, BINDED_CHANNELS);
- createTablet2->Record.SetTabletID(tabletId2);
-
- runtime.SendToPipe(hiveTablet, sender, createTablet2.Release(), 0, GetPipeConfigWithRetries());
- createTabletReply = runtime.GrabEdgeEventRethrow<TEvHive::TEvCreateTabletReply>(handle);
- UNIT_ASSERT(createTabletReply);
- UNIT_ASSERT(createTabletReply->Record.HasForwardRequest());
- UNIT_ASSERT_VALUES_EQUAL(createTabletReply->Record.GetForwardRequest().GetHiveTabletId(), subHiveTablet);
-
- // trying to delete same tablet from root hive
+ createTablet2->Record.SetTabletID(tabletId2);
+
+ runtime.SendToPipe(hiveTablet, sender, createTablet2.Release(), 0, GetPipeConfigWithRetries());
+ createTabletReply = runtime.GrabEdgeEventRethrow<TEvHive::TEvCreateTabletReply>(handle);
+ UNIT_ASSERT(createTabletReply);
+ UNIT_ASSERT(createTabletReply->Record.HasForwardRequest());
+ UNIT_ASSERT_VALUES_EQUAL(createTabletReply->Record.GetForwardRequest().GetHiveTabletId(), subHiveTablet);
+
+ // trying to delete same tablet from root hive
THolder<TEvHive::TEvDeleteTablet> deleteTablet2 = MakeHolder<TEvHive::TEvDeleteTablet>(testerTablet, 2, 0);
- deleteTablet2->Record.AddTabletID(tabletId2);
-
- runtime.SendToPipe(hiveTablet, sender, deleteTablet2.Release(), 0, GetPipeConfigWithRetries());
- deleteTabletReply = runtime.GrabEdgeEventRethrow<TEvHive::TEvDeleteTabletReply>(handle);
- UNIT_ASSERT(deleteTabletReply);
- UNIT_ASSERT(deleteTabletReply->Record.HasForwardRequest());
- UNIT_ASSERT_VALUES_EQUAL(deleteTabletReply->Record.GetForwardRequest().GetHiveTabletId(), subHiveTablet);
-
- runtime.SetObserverFunc(prevObserverFunc);
- }
-
- Y_UNIT_TEST(TestCheckSubHiveMigration) {
- TTestBasicRuntime runtime(2, false);
- Setup(runtime, true);
-
- const ui64 hiveTablet = MakeDefaultHiveID(0);
- const ui64 testerTablet = MakeDefaultHiveID(1);
+ deleteTablet2->Record.AddTabletID(tabletId2);
+
+ runtime.SendToPipe(hiveTablet, sender, deleteTablet2.Release(), 0, GetPipeConfigWithRetries());
+ deleteTabletReply = runtime.GrabEdgeEventRethrow<TEvHive::TEvDeleteTabletReply>(handle);
+ UNIT_ASSERT(deleteTabletReply);
+ UNIT_ASSERT(deleteTabletReply->Record.HasForwardRequest());
+ UNIT_ASSERT_VALUES_EQUAL(deleteTabletReply->Record.GetForwardRequest().GetHiveTabletId(), subHiveTablet);
+
+ runtime.SetObserverFunc(prevObserverFunc);
+ }
+
+ Y_UNIT_TEST(TestCheckSubHiveMigration) {
+ TTestBasicRuntime runtime(2, false);
+ Setup(runtime, true);
+
+ const ui64 hiveTablet = MakeDefaultHiveID(0);
+ const ui64 testerTablet = MakeDefaultHiveID(1);
CreateTestBootstrapper(runtime, CreateTestTabletInfo(hiveTablet, TTabletTypes::Hive), &CreateDefaultHive);
CreateTestBootstrapper(runtime, CreateTestTabletInfo(TTestTxConfig::SchemeShard, TTabletTypes::SchemeShard), &CreateFlatTxSchemeShard);
- MakeSureTabletIsUp(runtime, hiveTablet, 0); // root hive good
+ MakeSureTabletIsUp(runtime, hiveTablet, 0); // root hive good
MakeSureTabletIsUp(runtime, TTestTxConfig::SchemeShard, 0); // root ss good
-
-
- TActorId sender = runtime.AllocateEdgeActor(0);
+
+
+ TActorId sender = runtime.AllocateEdgeActor(0);
InitSchemeRoot(runtime, sender);
-
- TSubDomainKey subdomainKey;
-
- // Create subdomain
- do {
+
+ TSubDomainKey subdomainKey;
+
+ // Create subdomain
+ do {
auto x = MakeHolder<NSchemeShard::TEvSchemeShard::TEvModifySchemeTransaction>();
auto* tran = x->Record.AddTransaction();
- tran->SetWorkingDir("/dc-1");
+ tran->SetWorkingDir("/dc-1");
tran->SetOperationType(NKikimrSchemeOp::ESchemeOpCreateSubDomain);
- auto* subd = tran->MutableSubDomain();
- subd->SetName("tenant1");
+ auto* subd = tran->MutableSubDomain();
+ subd->SetName("tenant1");
runtime.SendToPipe(TTestTxConfig::SchemeShard, sender, x.Release());
- TAutoPtr<IEventHandle> handle;
+ TAutoPtr<IEventHandle> handle;
auto reply = runtime.GrabEdgeEventRethrow<NSchemeShard::TEvSchemeShard::TEvModifySchemeTransactionResult>(handle, TDuration::MilliSeconds(100));
- if (reply) {
- subdomainKey = TSubDomainKey(reply->Record.GetSchemeshardId(), reply->Record.GetPathId());
+ if (reply) {
+ subdomainKey = TSubDomainKey(reply->Record.GetSchemeshardId(), reply->Record.GetPathId());
UNIT_ASSERT_VALUES_EQUAL(reply->Record.GetStatus(), (ui32)NKikimrScheme::EStatus::StatusAccepted);
- break;
- }
- } while (true);
-
- THolder<TEvHive::TEvCreateTablet> createHive = MakeHolder<TEvHive::TEvCreateTablet>(testerTablet, 0, TTabletTypes::Hive, BINDED_CHANNELS);
- createHive->Record.AddAllowedDomains();
- createHive->Record.MutableAllowedDomains(0)->SetSchemeShard(subdomainKey.first);
- createHive->Record.MutableAllowedDomains(0)->SetPathId(subdomainKey.second);
+ break;
+ }
+ } while (true);
+
+ THolder<TEvHive::TEvCreateTablet> createHive = MakeHolder<TEvHive::TEvCreateTablet>(testerTablet, 0, TTabletTypes::Hive, BINDED_CHANNELS);
+ createHive->Record.AddAllowedDomains();
+ createHive->Record.MutableAllowedDomains(0)->SetSchemeShard(subdomainKey.first);
+ createHive->Record.MutableAllowedDomains(0)->SetPathId(subdomainKey.second);
ui64 subHiveTablet = SendCreateTestTablet(runtime, hiveTablet, testerTablet, std::move(createHive), 0, false);
-
- TTestActorRuntime::TEventObserver prevObserverFunc;
- prevObserverFunc = runtime.SetObserverFunc([&](TTestActorRuntimeBase& runtime, TAutoPtr<IEventHandle>& event) {
+
+ TTestActorRuntime::TEventObserver prevObserverFunc;
+ prevObserverFunc = runtime.SetObserverFunc([&](TTestActorRuntimeBase& runtime, TAutoPtr<IEventHandle>& event) {
if (event->GetTypeRewrite() == NSchemeShard::TEvSchemeShard::EvDescribeSchemeResult) {
event->Get<NSchemeShard::TEvSchemeShard::TEvDescribeSchemeResult>()->MutableRecord()->
- MutablePathDescription()->MutableDomainDescription()->MutableProcessingParams()->SetHive(subHiveTablet);
- }
- return prevObserverFunc(runtime, event);
- });
-
- SendKillLocal(runtime, 1);
- CreateLocalForTenant(runtime, 1, "/dc-1/tenant1");
-
- MakeSureTabletIsUp(runtime, subHiveTablet, 0); // sub hive good
-
- THolder<TEvHive::TEvConfigureHive> configureHive = MakeHolder<TEvHive::TEvConfigureHive>(subdomainKey);
-
- runtime.SendToPipe(subHiveTablet, sender, configureHive.Release(), 0, GetPipeConfigWithRetries());
- TAutoPtr<IEventHandle> handle;
-
- auto configureHiveReply = runtime.GrabEdgeEventRethrow<TEvSubDomain::TEvConfigureStatus>(handle);
-
- Y_UNUSED(configureHiveReply);
-
- THolder<TEvHive::TEvCreateTablet> createTablet1 = MakeHolder<TEvHive::TEvCreateTablet>(testerTablet, 1, TTabletTypes::Dummy, BINDED_CHANNELS);
- createTablet1->Record.AddAllowedDomains();
- createTablet1->Record.MutableAllowedDomains(0)->SetSchemeShard(subdomainKey.first);
- createTablet1->Record.MutableAllowedDomains(0)->SetPathId(subdomainKey.second);
+ MutablePathDescription()->MutableDomainDescription()->MutableProcessingParams()->SetHive(subHiveTablet);
+ }
+ return prevObserverFunc(runtime, event);
+ });
+
+ SendKillLocal(runtime, 1);
+ CreateLocalForTenant(runtime, 1, "/dc-1/tenant1");
+
+ MakeSureTabletIsUp(runtime, subHiveTablet, 0); // sub hive good
+
+ THolder<TEvHive::TEvConfigureHive> configureHive = MakeHolder<TEvHive::TEvConfigureHive>(subdomainKey);
+
+ runtime.SendToPipe(subHiveTablet, sender, configureHive.Release(), 0, GetPipeConfigWithRetries());
+ TAutoPtr<IEventHandle> handle;
+
+ auto configureHiveReply = runtime.GrabEdgeEventRethrow<TEvSubDomain::TEvConfigureStatus>(handle);
+
+ Y_UNUSED(configureHiveReply);
+
+ THolder<TEvHive::TEvCreateTablet> createTablet1 = MakeHolder<TEvHive::TEvCreateTablet>(testerTablet, 1, TTabletTypes::Dummy, BINDED_CHANNELS);
+ createTablet1->Record.AddAllowedDomains();
+ createTablet1->Record.MutableAllowedDomains(0)->SetSchemeShard(subdomainKey.first);
+ createTablet1->Record.MutableAllowedDomains(0)->SetPathId(subdomainKey.second);
ui64 tabletId1 = SendCreateTestTablet(runtime, hiveTablet, testerTablet, std::move(createTablet1), 0, true);
-
- MakeSureTabletIsUp(runtime, tabletId1, 0); // tablet up in root hive
-
- int iterations = 0;
-
- for (;; ++iterations) {
- UNIT_ASSERT(iterations < 100); // 10 seconds max
-
- runtime.SendToPipe(subHiveTablet, sender, new TEvHive::TEvQueryMigration(), 0, GetPipeConfigWithRetries());
- auto queryMigrationReply = runtime.GrabEdgeEventRethrow<TEvHive::TEvQueryMigrationReply>(handle);
-
- if (queryMigrationReply->Record.GetMigrationState() == NKikimrHive::EMigrationState::MIGRATION_COMPLETE) {
- break;
- }
-
- if (queryMigrationReply->Record.GetMigrationState() == NKikimrHive::EMigrationState::MIGRATION_READY) {
- THolder<TEvHive::TEvInitMigration> migration = MakeHolder<TEvHive::TEvInitMigration>();
- runtime.SendToPipe(subHiveTablet, sender, migration.Release(), 0, GetPipeConfigWithRetries());
- auto initMigrationReply = runtime.GrabEdgeEventRethrow<TEvHive::TEvInitMigrationReply>(handle);
- UNIT_ASSERT(initMigrationReply);
- UNIT_ASSERT(initMigrationReply->Record.GetStatus() == NKikimrProto::OK);
- }
-
- TDispatchOptions options;
- runtime.DispatchEvents(options, TDuration::MilliSeconds(100));
- }
-
- MakeSureTabletIsUp(runtime, tabletId1, 0); // tablet up in sub hive
-
- // retry create request to sub domain hive
+
+ MakeSureTabletIsUp(runtime, tabletId1, 0); // tablet up in root hive
+
+ int iterations = 0;
+
+ for (;; ++iterations) {
+ UNIT_ASSERT(iterations < 100); // 10 seconds max
+
+ runtime.SendToPipe(subHiveTablet, sender, new TEvHive::TEvQueryMigration(), 0, GetPipeConfigWithRetries());
+ auto queryMigrationReply = runtime.GrabEdgeEventRethrow<TEvHive::TEvQueryMigrationReply>(handle);
+
+ if (queryMigrationReply->Record.GetMigrationState() == NKikimrHive::EMigrationState::MIGRATION_COMPLETE) {
+ break;
+ }
+
+ if (queryMigrationReply->Record.GetMigrationState() == NKikimrHive::EMigrationState::MIGRATION_READY) {
+ THolder<TEvHive::TEvInitMigration> migration = MakeHolder<TEvHive::TEvInitMigration>();
+ runtime.SendToPipe(subHiveTablet, sender, migration.Release(), 0, GetPipeConfigWithRetries());
+ auto initMigrationReply = runtime.GrabEdgeEventRethrow<TEvHive::TEvInitMigrationReply>(handle);
+ UNIT_ASSERT(initMigrationReply);
+ UNIT_ASSERT(initMigrationReply->Record.GetStatus() == NKikimrProto::OK);
+ }
+
+ TDispatchOptions options;
+ runtime.DispatchEvents(options, TDuration::MilliSeconds(100));
+ }
+
+ MakeSureTabletIsUp(runtime, tabletId1, 0); // tablet up in sub hive
+
+ // retry create request to sub domain hive
createTablet1 = MakeHolder<TEvHive::TEvCreateTablet>(testerTablet, 1, TTabletTypes::Dummy, BINDED_CHANNELS);
- createTablet1->Record.SetTabletID(tabletId1);
-
- runtime.SendToPipe(hiveTablet, sender, createTablet1.Release(), 0, GetPipeConfigWithRetries());
- auto createTabletReply = runtime.GrabEdgeEventRethrow<TEvHive::TEvCreateTabletReply>(handle);
- UNIT_ASSERT(createTabletReply);
- UNIT_ASSERT(createTabletReply->Record.HasForwardRequest());
- UNIT_ASSERT_VALUES_EQUAL(createTabletReply->Record.GetForwardRequest().GetHiveTabletId(), subHiveTablet);
-
- runtime.SetObserverFunc(prevObserverFunc);
- }
-
- Y_UNIT_TEST(TestCheckSubHiveMigrationManyTablets) {
- TTestBasicRuntime runtime(2, false);
- Setup(runtime, true);
-
- const ui64 hiveTablet = MakeDefaultHiveID(0);
- const ui64 testerTablet = MakeDefaultHiveID(1);
+ createTablet1->Record.SetTabletID(tabletId1);
+
+ runtime.SendToPipe(hiveTablet, sender, createTablet1.Release(), 0, GetPipeConfigWithRetries());
+ auto createTabletReply = runtime.GrabEdgeEventRethrow<TEvHive::TEvCreateTabletReply>(handle);
+ UNIT_ASSERT(createTabletReply);
+ UNIT_ASSERT(createTabletReply->Record.HasForwardRequest());
+ UNIT_ASSERT_VALUES_EQUAL(createTabletReply->Record.GetForwardRequest().GetHiveTabletId(), subHiveTablet);
+
+ runtime.SetObserverFunc(prevObserverFunc);
+ }
+
+ Y_UNIT_TEST(TestCheckSubHiveMigrationManyTablets) {
+ TTestBasicRuntime runtime(2, false);
+ Setup(runtime, true);
+
+ const ui64 hiveTablet = MakeDefaultHiveID(0);
+ const ui64 testerTablet = MakeDefaultHiveID(1);
CreateTestBootstrapper(runtime, CreateTestTabletInfo(hiveTablet, TTabletTypes::Hive), &CreateDefaultHive);
CreateTestBootstrapper(runtime, CreateTestTabletInfo(TTestTxConfig::SchemeShard, TTabletTypes::SchemeShard), &CreateFlatTxSchemeShard);
- MakeSureTabletIsUp(runtime, hiveTablet, 0); // root hive good
+ MakeSureTabletIsUp(runtime, hiveTablet, 0); // root hive good
MakeSureTabletIsUp(runtime, TTestTxConfig::SchemeShard, 0); // root ss good
-
-
- TActorId sender = runtime.AllocateEdgeActor(0);
+
+
+ TActorId sender = runtime.AllocateEdgeActor(0);
InitSchemeRoot(runtime, sender);
-
- TSubDomainKey subdomainKey;
-
- // Create subdomain
- do {
+
+ TSubDomainKey subdomainKey;
+
+ // Create subdomain
+ do {
auto x = MakeHolder<NSchemeShard::TEvSchemeShard::TEvModifySchemeTransaction>();
auto* tran = x->Record.AddTransaction();
- tran->SetWorkingDir("/dc-1");
+ tran->SetWorkingDir("/dc-1");
tran->SetOperationType(NKikimrSchemeOp::ESchemeOpCreateSubDomain);
- auto* subd = tran->MutableSubDomain();
- subd->SetName("tenant1");
+ auto* subd = tran->MutableSubDomain();
+ subd->SetName("tenant1");
runtime.SendToPipe(TTestTxConfig::SchemeShard, sender, x.Release());
- TAutoPtr<IEventHandle> handle;
+ TAutoPtr<IEventHandle> handle;
auto reply = runtime.GrabEdgeEventRethrow<NSchemeShard::TEvSchemeShard::TEvModifySchemeTransactionResult>(handle, TDuration::MilliSeconds(100));
- if (reply) {
- subdomainKey = TSubDomainKey(reply->Record.GetSchemeshardId(), reply->Record.GetPathId());
+ if (reply) {
+ subdomainKey = TSubDomainKey(reply->Record.GetSchemeshardId(), reply->Record.GetPathId());
UNIT_ASSERT_VALUES_EQUAL(reply->Record.GetStatus(), (ui32)NKikimrScheme::EStatus::StatusAccepted);
- break;
- }
- } while (true);
-
- THolder<TEvHive::TEvCreateTablet> createHive = MakeHolder<TEvHive::TEvCreateTablet>(testerTablet, 0, TTabletTypes::Hive, BINDED_CHANNELS);
- createHive->Record.AddAllowedDomains();
- createHive->Record.MutableAllowedDomains(0)->SetSchemeShard(subdomainKey.first);
- createHive->Record.MutableAllowedDomains(0)->SetPathId(subdomainKey.second);
+ break;
+ }
+ } while (true);
+
+ THolder<TEvHive::TEvCreateTablet> createHive = MakeHolder<TEvHive::TEvCreateTablet>(testerTablet, 0, TTabletTypes::Hive, BINDED_CHANNELS);
+ createHive->Record.AddAllowedDomains();
+ createHive->Record.MutableAllowedDomains(0)->SetSchemeShard(subdomainKey.first);
+ createHive->Record.MutableAllowedDomains(0)->SetPathId(subdomainKey.second);
ui64 subHiveTablet = SendCreateTestTablet(runtime, hiveTablet, testerTablet, std::move(createHive), 0, false);
-
- TTestActorRuntime::TEventObserver prevObserverFunc;
- prevObserverFunc = runtime.SetObserverFunc([&](TTestActorRuntimeBase& runtime, TAutoPtr<IEventHandle>& event) {
+
+ TTestActorRuntime::TEventObserver prevObserverFunc;
+ prevObserverFunc = runtime.SetObserverFunc([&](TTestActorRuntimeBase& runtime, TAutoPtr<IEventHandle>& event) {
if (event->GetTypeRewrite() == NSchemeShard::TEvSchemeShard::EvDescribeSchemeResult) {
event->Get<NSchemeShard::TEvSchemeShard::TEvDescribeSchemeResult>()->MutableRecord()->
- MutablePathDescription()->MutableDomainDescription()->MutableProcessingParams()->SetHive(subHiveTablet);
- }
- return prevObserverFunc(runtime, event);
- });
-
- SendKillLocal(runtime, 1);
- CreateLocalForTenant(runtime, 1, "/dc-1/tenant1");
-
- MakeSureTabletIsUp(runtime, subHiveTablet, 0); // sub hive good
-
- THolder<TEvHive::TEvConfigureHive> configureHive = MakeHolder<TEvHive::TEvConfigureHive>(subdomainKey);
-
- runtime.SendToPipe(subHiveTablet, sender, configureHive.Release(), 0, GetPipeConfigWithRetries());
- TAutoPtr<IEventHandle> handle;
-
- auto configureHiveReply = runtime.GrabEdgeEventRethrow<TEvSubDomain::TEvConfigureStatus>(handle);
-
- Y_UNUSED(configureHiveReply);
-
- static constexpr int TABLETS = 100;
-
- std::vector<ui64> tabletIds;
-
- for (int i = 0; i < TABLETS; ++i) {
- THolder<TEvHive::TEvCreateTablet> createTablet1 = MakeHolder<TEvHive::TEvCreateTablet>(testerTablet, i + 1, TTabletTypes::Dummy, BINDED_CHANNELS);
- createTablet1->Record.AddAllowedDomains();
- createTablet1->Record.MutableAllowedDomains(0)->SetSchemeShard(subdomainKey.first);
- createTablet1->Record.MutableAllowedDomains(0)->SetPathId(subdomainKey.second);
+ MutablePathDescription()->MutableDomainDescription()->MutableProcessingParams()->SetHive(subHiveTablet);
+ }
+ return prevObserverFunc(runtime, event);
+ });
+
+ SendKillLocal(runtime, 1);
+ CreateLocalForTenant(runtime, 1, "/dc-1/tenant1");
+
+ MakeSureTabletIsUp(runtime, subHiveTablet, 0); // sub hive good
+
+ THolder<TEvHive::TEvConfigureHive> configureHive = MakeHolder<TEvHive::TEvConfigureHive>(subdomainKey);
+
+ runtime.SendToPipe(subHiveTablet, sender, configureHive.Release(), 0, GetPipeConfigWithRetries());
+ TAutoPtr<IEventHandle> handle;
+
+ auto configureHiveReply = runtime.GrabEdgeEventRethrow<TEvSubDomain::TEvConfigureStatus>(handle);
+
+ Y_UNUSED(configureHiveReply);
+
+ static constexpr int TABLETS = 100;
+
+ std::vector<ui64> tabletIds;
+
+ for (int i = 0; i < TABLETS; ++i) {
+ THolder<TEvHive::TEvCreateTablet> createTablet1 = MakeHolder<TEvHive::TEvCreateTablet>(testerTablet, i + 1, TTabletTypes::Dummy, BINDED_CHANNELS);
+ createTablet1->Record.AddAllowedDomains();
+ createTablet1->Record.MutableAllowedDomains(0)->SetSchemeShard(subdomainKey.first);
+ createTablet1->Record.MutableAllowedDomains(0)->SetPathId(subdomainKey.second);
ui64 tabletId1 = SendCreateTestTablet(runtime, hiveTablet, testerTablet, std::move(createTablet1), 0, true);
- MakeSureTabletIsUp(runtime, tabletId1, 0); // tablet up in root hive
- tabletIds.push_back(tabletId1);
- }
-
- int iterations = 0;
-
- for (;; ++iterations) {
- UNIT_ASSERT(iterations < 300); // 30 seconds max
-
- runtime.SendToPipe(subHiveTablet, sender, new TEvHive::TEvQueryMigration(), 0, GetPipeConfigWithRetries());
- auto queryMigrationReply = runtime.GrabEdgeEventRethrow<TEvHive::TEvQueryMigrationReply>(handle);
-
- if (queryMigrationReply->Record.GetMigrationState() == NKikimrHive::EMigrationState::MIGRATION_COMPLETE) {
- break;
- }
-
- if (queryMigrationReply->Record.GetMigrationState() == NKikimrHive::EMigrationState::MIGRATION_READY) {
- THolder<TEvHive::TEvInitMigration> migration = MakeHolder<TEvHive::TEvInitMigration>();
- runtime.SendToPipe(subHiveTablet, sender, migration.Release(), 0, GetPipeConfigWithRetries());
- auto initMigrationReply = runtime.GrabEdgeEventRethrow<TEvHive::TEvInitMigrationReply>(handle);
- UNIT_ASSERT(initMigrationReply);
- UNIT_ASSERT(initMigrationReply->Record.GetStatus() == NKikimrProto::OK);
- }
-
- TDispatchOptions options;
- runtime.DispatchEvents(options, TDuration::MilliSeconds(100));
- }
-
- for (int i = 0; i < (int)tabletIds.size(); ++i) {
- MakeSureTabletIsUp(runtime, tabletIds[i], 0); // tablet up in sub hive
-
- // retry create request to sub domain hive
+ MakeSureTabletIsUp(runtime, tabletId1, 0); // tablet up in root hive
+ tabletIds.push_back(tabletId1);
+ }
+
+ int iterations = 0;
+
+ for (;; ++iterations) {
+ UNIT_ASSERT(iterations < 300); // 30 seconds max
+
+ runtime.SendToPipe(subHiveTablet, sender, new TEvHive::TEvQueryMigration(), 0, GetPipeConfigWithRetries());
+ auto queryMigrationReply = runtime.GrabEdgeEventRethrow<TEvHive::TEvQueryMigrationReply>(handle);
+
+ if (queryMigrationReply->Record.GetMigrationState() == NKikimrHive::EMigrationState::MIGRATION_COMPLETE) {
+ break;
+ }
+
+ if (queryMigrationReply->Record.GetMigrationState() == NKikimrHive::EMigrationState::MIGRATION_READY) {
+ THolder<TEvHive::TEvInitMigration> migration = MakeHolder<TEvHive::TEvInitMigration>();
+ runtime.SendToPipe(subHiveTablet, sender, migration.Release(), 0, GetPipeConfigWithRetries());
+ auto initMigrationReply = runtime.GrabEdgeEventRethrow<TEvHive::TEvInitMigrationReply>(handle);
+ UNIT_ASSERT(initMigrationReply);
+ UNIT_ASSERT(initMigrationReply->Record.GetStatus() == NKikimrProto::OK);
+ }
+
+ TDispatchOptions options;
+ runtime.DispatchEvents(options, TDuration::MilliSeconds(100));
+ }
+
+ for (int i = 0; i < (int)tabletIds.size(); ++i) {
+ MakeSureTabletIsUp(runtime, tabletIds[i], 0); // tablet up in sub hive
+
+ // retry create request to sub domain hive
THolder<TEvHive::TEvCreateTablet> createTablet1 = MakeHolder<TEvHive::TEvCreateTablet>(testerTablet, i + 1, TTabletTypes::Dummy, BINDED_CHANNELS);
- createTablet1->Record.SetTabletID(tabletIds[i]);
-
- runtime.SendToPipe(hiveTablet, sender, createTablet1.Release(), 0, GetPipeConfigWithRetries());
- auto createTabletReply = runtime.GrabEdgeEventRethrow<TEvHive::TEvCreateTabletReply>(handle);
- UNIT_ASSERT(createTabletReply);
- UNIT_ASSERT(createTabletReply->Record.HasForwardRequest());
- UNIT_ASSERT_VALUES_EQUAL(createTabletReply->Record.GetForwardRequest().GetHiveTabletId(), subHiveTablet);
- }
-
- runtime.SetObserverFunc(prevObserverFunc);
- }
-
- Y_UNIT_TEST(TestCreateSubHiveCreateManyTablets) {
- TTestBasicRuntime runtime(1, false);
- Setup(runtime, true);
- static constexpr int TABLETS = 1000;
- const ui64 hiveTablet = MakeDefaultHiveID(0);
- const ui64 testerTablet = MakeDefaultHiveID(1);
+ createTablet1->Record.SetTabletID(tabletIds[i]);
+
+ runtime.SendToPipe(hiveTablet, sender, createTablet1.Release(), 0, GetPipeConfigWithRetries());
+ auto createTabletReply = runtime.GrabEdgeEventRethrow<TEvHive::TEvCreateTabletReply>(handle);
+ UNIT_ASSERT(createTabletReply);
+ UNIT_ASSERT(createTabletReply->Record.HasForwardRequest());
+ UNIT_ASSERT_VALUES_EQUAL(createTabletReply->Record.GetForwardRequest().GetHiveTabletId(), subHiveTablet);
+ }
+
+ runtime.SetObserverFunc(prevObserverFunc);
+ }
+
+ Y_UNIT_TEST(TestCreateSubHiveCreateManyTablets) {
+ TTestBasicRuntime runtime(1, false);
+ Setup(runtime, true);
+ static constexpr int TABLETS = 1000;
+ const ui64 hiveTablet = MakeDefaultHiveID(0);
+ const ui64 testerTablet = MakeDefaultHiveID(1);
CreateTestBootstrapper(runtime, CreateTestTabletInfo(hiveTablet, TTabletTypes::Hive), &CreateDefaultHive);
CreateTestBootstrapper(runtime, CreateTestTabletInfo(TTestTxConfig::SchemeShard, TTabletTypes::SchemeShard), &CreateFlatTxSchemeShard);
- MakeSureTabletIsUp(runtime, hiveTablet, 0); // root hive good
+ MakeSureTabletIsUp(runtime, hiveTablet, 0); // root hive good
MakeSureTabletIsUp(runtime, TTestTxConfig::SchemeShard, 0); // root ss good
-
- TActorId sender = runtime.AllocateEdgeActor(0);
+
+ TActorId sender = runtime.AllocateEdgeActor(0);
InitSchemeRoot(runtime, sender);
-
- TSubDomainKey subdomainKey;
-
- // Create subdomain
- do {
+
+ TSubDomainKey subdomainKey;
+
+ // Create subdomain
+ do {
auto x = MakeHolder<NSchemeShard::TEvSchemeShard::TEvModifySchemeTransaction>();
auto* tran = x->Record.AddTransaction();
- tran->SetWorkingDir("/dc-1");
+ tran->SetWorkingDir("/dc-1");
tran->SetOperationType(NKikimrSchemeOp::ESchemeOpCreateSubDomain);
- auto* subd = tran->MutableSubDomain();
- subd->SetName("tenant1");
+ auto* subd = tran->MutableSubDomain();
+ subd->SetName("tenant1");
runtime.SendToPipe(TTestTxConfig::SchemeShard, sender, x.Release());
- TAutoPtr<IEventHandle> handle;
+ TAutoPtr<IEventHandle> handle;
auto reply = runtime.GrabEdgeEventRethrow<NSchemeShard::TEvSchemeShard::TEvModifySchemeTransactionResult>(handle, TDuration::MilliSeconds(100));
- if (reply) {
- subdomainKey = TSubDomainKey(reply->Record.GetSchemeshardId(), reply->Record.GetPathId());
+ if (reply) {
+ subdomainKey = TSubDomainKey(reply->Record.GetSchemeshardId(), reply->Record.GetPathId());
UNIT_ASSERT_VALUES_EQUAL(reply->Record.GetStatus(), (ui32)NKikimrScheme::EStatus::StatusAccepted);
- break;
- }
- } while (true);
-
- THolder<TEvHive::TEvCreateTablet> createHive = MakeHolder<TEvHive::TEvCreateTablet>(testerTablet, 0, TTabletTypes::Hive, BINDED_CHANNELS);
- createHive->Record.AddAllowedDomains();
- createHive->Record.MutableAllowedDomains(0)->SetSchemeShard(subdomainKey.first);
- createHive->Record.MutableAllowedDomains(0)->SetPathId(subdomainKey.second);
+ break;
+ }
+ } while (true);
+
+ THolder<TEvHive::TEvCreateTablet> createHive = MakeHolder<TEvHive::TEvCreateTablet>(testerTablet, 0, TTabletTypes::Hive, BINDED_CHANNELS);
+ createHive->Record.AddAllowedDomains();
+ createHive->Record.MutableAllowedDomains(0)->SetSchemeShard(subdomainKey.first);
+ createHive->Record.MutableAllowedDomains(0)->SetPathId(subdomainKey.second);
ui64 subHiveTablet = SendCreateTestTablet(runtime, hiveTablet, testerTablet, std::move(createHive), 0, false);
-
- TTestActorRuntime::TEventObserver prevObserverFunc;
- prevObserverFunc = runtime.SetObserverFunc([&](TTestActorRuntimeBase& runtime, TAutoPtr<IEventHandle>& event) {
+
+ TTestActorRuntime::TEventObserver prevObserverFunc;
+ prevObserverFunc = runtime.SetObserverFunc([&](TTestActorRuntimeBase& runtime, TAutoPtr<IEventHandle>& event) {
if (event->GetTypeRewrite() == NSchemeShard::TEvSchemeShard::EvDescribeSchemeResult) {
event->Get<NSchemeShard::TEvSchemeShard::TEvDescribeSchemeResult>()->MutableRecord()->
- MutablePathDescription()->MutableDomainDescription()->MutableProcessingParams()->SetHive(subHiveTablet);
- }
- return prevObserverFunc(runtime, event);
- });
-
- SendToLocal(runtime, 0, new TEvLocal::TEvAddTenant("/dc-1/tenant1"));
-
- MakeSureTabletIsUp(runtime, subHiveTablet, 0); // sub hive good
-
- NKikimrHive::TEvCreateTablet templateCreateTablet;
- templateCreateTablet.SetOwner(testerTablet);
- templateCreateTablet.SetOwnerIdx(0);
- templateCreateTablet.SetTabletType(TTabletTypes::Dummy);
- for (auto& channel : BINDED_CHANNELS) {
- (*templateCreateTablet.AddBindedChannels()) = channel;
- }
- templateCreateTablet.AddAllowedDomains();
- templateCreateTablet.MutableAllowedDomains(0)->SetSchemeShard(subdomainKey.first);
- templateCreateTablet.MutableAllowedDomains(0)->SetPathId(subdomainKey.second);
- for (int ownerIdx = 1; ownerIdx <= TABLETS; ++ownerIdx) {
- THolder<TEvHive::TEvCreateTablet> createTablet = MakeHolder<TEvHive::TEvCreateTablet>();
- createTablet->Record = templateCreateTablet;
- createTablet->Record.SetOwnerIdx(ownerIdx);
- runtime.SendToPipe(subHiveTablet, sender, createTablet.Release(), 0, GetPipeConfigWithRetries());
- }
-
- for (int ownerIdx = 1; ownerIdx <= TABLETS; ++ownerIdx) {
- TAutoPtr<IEventHandle> handle;
- auto createTabletReply = runtime.GrabEdgeEventRethrow<TEvHive::TEvCreateTabletReply>(handle);
- ui64 tabletId = createTabletReply->Record.GetTabletID();
- MakeSureTabletIsUp(runtime, tabletId, 0); // dummy from sub hive also good
- }
-
- runtime.SetObserverFunc(prevObserverFunc);
- }
-
- Y_UNIT_TEST(TestCreateSubHiveCreateManyTabletsWithReboots) {
- static constexpr int TABLETS = 100;
- const ui64 hiveTablet = MakeDefaultHiveID(0);
- const ui64 testerTablet = MakeDefaultHiveID(1);
- THiveInitialEventsFilter initialEventsFilter;
-
- TVector<ui64> tabletIds;
- tabletIds.push_back(hiveTablet);
- tabletIds.push_back(testerTablet);
- RunTestWithReboots(tabletIds, [&]() {
- return initialEventsFilter.Prepare();
- }, [&](const TString &dispatchName, std::function<void(TTestActorRuntime&)> setup, bool &activeZone) {
- if (ENABLE_DETAILED_HIVE_LOG) {
- Ctest << "At dispatch " << dispatchName << Endl;
- }
- TTestBasicRuntime runtime(2, false);
- Setup(runtime, true);
- setup(runtime);
-
+ MutablePathDescription()->MutableDomainDescription()->MutableProcessingParams()->SetHive(subHiveTablet);
+ }
+ return prevObserverFunc(runtime, event);
+ });
+
+ SendToLocal(runtime, 0, new TEvLocal::TEvAddTenant("/dc-1/tenant1"));
+
+ MakeSureTabletIsUp(runtime, subHiveTablet, 0); // sub hive good
+
+ NKikimrHive::TEvCreateTablet templateCreateTablet;
+ templateCreateTablet.SetOwner(testerTablet);
+ templateCreateTablet.SetOwnerIdx(0);
+ templateCreateTablet.SetTabletType(TTabletTypes::Dummy);
+ for (auto& channel : BINDED_CHANNELS) {
+ (*templateCreateTablet.AddBindedChannels()) = channel;
+ }
+ templateCreateTablet.AddAllowedDomains();
+ templateCreateTablet.MutableAllowedDomains(0)->SetSchemeShard(subdomainKey.first);
+ templateCreateTablet.MutableAllowedDomains(0)->SetPathId(subdomainKey.second);
+ for (int ownerIdx = 1; ownerIdx <= TABLETS; ++ownerIdx) {
+ THolder<TEvHive::TEvCreateTablet> createTablet = MakeHolder<TEvHive::TEvCreateTablet>();
+ createTablet->Record = templateCreateTablet;
+ createTablet->Record.SetOwnerIdx(ownerIdx);
+ runtime.SendToPipe(subHiveTablet, sender, createTablet.Release(), 0, GetPipeConfigWithRetries());
+ }
+
+ for (int ownerIdx = 1; ownerIdx <= TABLETS; ++ownerIdx) {
+ TAutoPtr<IEventHandle> handle;
+ auto createTabletReply = runtime.GrabEdgeEventRethrow<TEvHive::TEvCreateTabletReply>(handle);
+ ui64 tabletId = createTabletReply->Record.GetTabletID();
+ MakeSureTabletIsUp(runtime, tabletId, 0); // dummy from sub hive also good
+ }
+
+ runtime.SetObserverFunc(prevObserverFunc);
+ }
+
+ Y_UNIT_TEST(TestCreateSubHiveCreateManyTabletsWithReboots) {
+ static constexpr int TABLETS = 100;
+ const ui64 hiveTablet = MakeDefaultHiveID(0);
+ const ui64 testerTablet = MakeDefaultHiveID(1);
+ THiveInitialEventsFilter initialEventsFilter;
+
+ TVector<ui64> tabletIds;
+ tabletIds.push_back(hiveTablet);
+ tabletIds.push_back(testerTablet);
+ RunTestWithReboots(tabletIds, [&]() {
+ return initialEventsFilter.Prepare();
+ }, [&](const TString &dispatchName, std::function<void(TTestActorRuntime&)> setup, bool &activeZone) {
+ if (ENABLE_DETAILED_HIVE_LOG) {
+ Ctest << "At dispatch " << dispatchName << Endl;
+ }
+ TTestBasicRuntime runtime(2, false);
+ Setup(runtime, true);
+ setup(runtime);
+
CreateTestBootstrapper(runtime, CreateTestTabletInfo(hiveTablet, TTabletTypes::Hive), &CreateDefaultHive);
CreateTestBootstrapper(runtime, CreateTestTabletInfo(TTestTxConfig::SchemeShard, TTabletTypes::SchemeShard), &CreateFlatTxSchemeShard);
- MakeSureTabletIsUp(runtime, hiveTablet, 0); // root hive good
+ MakeSureTabletIsUp(runtime, hiveTablet, 0); // root hive good
MakeSureTabletIsUp(runtime, TTestTxConfig::SchemeShard, 0); // root ss good
-
- TActorId sender = runtime.AllocateEdgeActor(0);
+
+ TActorId sender = runtime.AllocateEdgeActor(0);
InitSchemeRoot(runtime, sender);
-
- TSubDomainKey subdomainKey;
-
- // Create subdomain
- do {
+
+ TSubDomainKey subdomainKey;
+
+ // Create subdomain
+ do {
auto x = MakeHolder<NSchemeShard::TEvSchemeShard::TEvModifySchemeTransaction>();
auto* tran = x->Record.AddTransaction();
- tran->SetWorkingDir("/dc-1");
+ tran->SetWorkingDir("/dc-1");
tran->SetOperationType(NKikimrSchemeOp::ESchemeOpCreateSubDomain);
- auto* subd = tran->MutableSubDomain();
- subd->SetName("tenant1");
+ auto* subd = tran->MutableSubDomain();
+ subd->SetName("tenant1");
runtime.SendToPipe(TTestTxConfig::SchemeShard, sender, x.Release());
- TAutoPtr<IEventHandle> handle;
+ TAutoPtr<IEventHandle> handle;
auto reply = runtime.GrabEdgeEventRethrow<NSchemeShard::TEvSchemeShard::TEvModifySchemeTransactionResult>(handle, TDuration::MilliSeconds(100));
- if (reply) {
- subdomainKey = TSubDomainKey(reply->Record.GetSchemeshardId(), reply->Record.GetPathId());
+ if (reply) {
+ subdomainKey = TSubDomainKey(reply->Record.GetSchemeshardId(), reply->Record.GetPathId());
UNIT_ASSERT_VALUES_EQUAL(reply->Record.GetStatus(), (ui32)NKikimrScheme::EStatus::StatusAccepted);
- break;
- }
- } while (true);
-
- THolder<TEvHive::TEvCreateTablet> createHive = MakeHolder<TEvHive::TEvCreateTablet>(testerTablet, 0, TTabletTypes::Hive, BINDED_CHANNELS);
- createHive->Record.AddAllowedDomains();
- createHive->Record.MutableAllowedDomains(0)->SetSchemeShard(subdomainKey.first);
- createHive->Record.MutableAllowedDomains(0)->SetPathId(subdomainKey.second);
+ break;
+ }
+ } while (true);
+
+ THolder<TEvHive::TEvCreateTablet> createHive = MakeHolder<TEvHive::TEvCreateTablet>(testerTablet, 0, TTabletTypes::Hive, BINDED_CHANNELS);
+ createHive->Record.AddAllowedDomains();
+ createHive->Record.MutableAllowedDomains(0)->SetSchemeShard(subdomainKey.first);
+ createHive->Record.MutableAllowedDomains(0)->SetPathId(subdomainKey.second);
ui64 subHiveTablet = SendCreateTestTablet(runtime, hiveTablet, testerTablet, std::move(createHive), 0, false);
-
- TTestActorRuntime::TEventObserver prevObserverFunc;
- prevObserverFunc = runtime.SetObserverFunc([&](TTestActorRuntimeBase& runtime, TAutoPtr<IEventHandle>& event) {
+
+ TTestActorRuntime::TEventObserver prevObserverFunc;
+ prevObserverFunc = runtime.SetObserverFunc([&](TTestActorRuntimeBase& runtime, TAutoPtr<IEventHandle>& event) {
if (event->GetTypeRewrite() == NSchemeShard::TEvSchemeShard::EvDescribeSchemeResult) {
event->Get<NSchemeShard::TEvSchemeShard::TEvDescribeSchemeResult>()->MutableRecord()->
- MutablePathDescription()->MutableDomainDescription()->MutableProcessingParams()->SetHive(subHiveTablet);
- }
- return prevObserverFunc(runtime, event);
- });
-
- SendKillLocal(runtime, 1);
- CreateLocalForTenant(runtime, 1, "/dc-1/tenant1");
-
- MakeSureTabletIsUp(runtime, subHiveTablet, 0); // sub hive good
-
- activeZone = true;
-
- NKikimrHive::TEvCreateTablet templateCreateTablet;
- templateCreateTablet.SetOwner(testerTablet);
- templateCreateTablet.SetOwnerIdx(0);
- templateCreateTablet.SetTabletType(TTabletTypes::Dummy);
- for (auto& channel : BINDED_CHANNELS) {
- (*templateCreateTablet.AddBindedChannels()) = channel;
- }
- templateCreateTablet.AddAllowedDomains();
- templateCreateTablet.MutableAllowedDomains(0)->SetSchemeShard(subdomainKey.first);
- templateCreateTablet.MutableAllowedDomains(0)->SetPathId(subdomainKey.second);
- for (int ownerIdx = 1; ownerIdx <= TABLETS; ++ownerIdx) {
- THolder<TEvHive::TEvCreateTablet> createTablet = MakeHolder<TEvHive::TEvCreateTablet>();
- createTablet->Record = templateCreateTablet;
- createTablet->Record.SetOwnerIdx(ownerIdx);
- runtime.SendToPipe(subHiveTablet, sender, createTablet.Release(), 0, GetPipeConfigWithRetries());
- }
-
- for (int ownerIdx = 1; ownerIdx <= TABLETS; ++ownerIdx) {
- TAutoPtr<IEventHandle> handle;
- auto createTabletReply = runtime.GrabEdgeEventRethrow<TEvHive::TEvCreateTabletReply>(handle);
- ui64 tabletId = createTabletReply->Record.GetTabletID();
- MakeSureTabletIsUp(runtime, tabletId, 0); // dummy from sub hive also good
- }
-
- activeZone = false;
-
- runtime.SetObserverFunc(prevObserverFunc);
- });
- }
-
- Y_UNIT_TEST(TestCheckSubHiveMigrationWithReboots) {
- const ui64 hiveTablet = MakeDefaultHiveID(0);
- const ui64 bsControllerTablet = MakeBSControllerID(0);
- const ui64 testerTablet = MakeDefaultHiveID(1);
- THiveEveryEventFilter everyEventFilter;
-
- TVector<ui64> tabletIds;
- tabletIds.push_back(hiveTablet);
- tabletIds.push_back(bsControllerTablet);
- tabletIds.push_back(65536); // sub hive
- tabletIds.push_back(testerTablet);
- RunTestWithReboots(tabletIds, [&]() {
- return everyEventFilter.Prepare();
- }, [&](const TString &dispatchName, std::function<void(TTestActorRuntime&)> setup, bool &activeZone) {
- if (ENABLE_DETAILED_HIVE_LOG) {
- Ctest << "At dispatch " << dispatchName << Endl;
- }
- TTestBasicRuntime runtime(2, false);
- Setup(runtime, true);
- setup(runtime);
-
+ MutablePathDescription()->MutableDomainDescription()->MutableProcessingParams()->SetHive(subHiveTablet);
+ }
+ return prevObserverFunc(runtime, event);
+ });
+
+ SendKillLocal(runtime, 1);
+ CreateLocalForTenant(runtime, 1, "/dc-1/tenant1");
+
+ MakeSureTabletIsUp(runtime, subHiveTablet, 0); // sub hive good
+
+ activeZone = true;
+
+ NKikimrHive::TEvCreateTablet templateCreateTablet;
+ templateCreateTablet.SetOwner(testerTablet);
+ templateCreateTablet.SetOwnerIdx(0);
+ templateCreateTablet.SetTabletType(TTabletTypes::Dummy);
+ for (auto& channel : BINDED_CHANNELS) {
+ (*templateCreateTablet.AddBindedChannels()) = channel;
+ }
+ templateCreateTablet.AddAllowedDomains();
+ templateCreateTablet.MutableAllowedDomains(0)->SetSchemeShard(subdomainKey.first);
+ templateCreateTablet.MutableAllowedDomains(0)->SetPathId(subdomainKey.second);
+ for (int ownerIdx = 1; ownerIdx <= TABLETS; ++ownerIdx) {
+ THolder<TEvHive::TEvCreateTablet> createTablet = MakeHolder<TEvHive::TEvCreateTablet>();
+ createTablet->Record = templateCreateTablet;
+ createTablet->Record.SetOwnerIdx(ownerIdx);
+ runtime.SendToPipe(subHiveTablet, sender, createTablet.Release(), 0, GetPipeConfigWithRetries());
+ }
+
+ for (int ownerIdx = 1; ownerIdx <= TABLETS; ++ownerIdx) {
+ TAutoPtr<IEventHandle> handle;
+ auto createTabletReply = runtime.GrabEdgeEventRethrow<TEvHive::TEvCreateTabletReply>(handle);
+ ui64 tabletId = createTabletReply->Record.GetTabletID();
+ MakeSureTabletIsUp(runtime, tabletId, 0); // dummy from sub hive also good
+ }
+
+ activeZone = false;
+
+ runtime.SetObserverFunc(prevObserverFunc);
+ });
+ }
+
+ Y_UNIT_TEST(TestCheckSubHiveMigrationWithReboots) {
+ const ui64 hiveTablet = MakeDefaultHiveID(0);
+ const ui64 bsControllerTablet = MakeBSControllerID(0);
+ const ui64 testerTablet = MakeDefaultHiveID(1);
+ THiveEveryEventFilter everyEventFilter;
+
+ TVector<ui64> tabletIds;
+ tabletIds.push_back(hiveTablet);
+ tabletIds.push_back(bsControllerTablet);
+ tabletIds.push_back(65536); // sub hive
+ tabletIds.push_back(testerTablet);
+ RunTestWithReboots(tabletIds, [&]() {
+ return everyEventFilter.Prepare();
+ }, [&](const TString &dispatchName, std::function<void(TTestActorRuntime&)> setup, bool &activeZone) {
+ if (ENABLE_DETAILED_HIVE_LOG) {
+ Ctest << "At dispatch " << dispatchName << Endl;
+ }
+ TTestBasicRuntime runtime(2, false);
+ Setup(runtime, true);
+ setup(runtime);
+
CreateTestBootstrapper(runtime, CreateTestTabletInfo(hiveTablet, TTabletTypes::Hive), &CreateDefaultHive);
CreateTestBootstrapper(runtime, CreateTestTabletInfo(TTestTxConfig::SchemeShard, TTabletTypes::SchemeShard), &CreateFlatTxSchemeShard);
- MakeSureTabletIsUp(runtime, hiveTablet, 0); // root hive good
+ MakeSureTabletIsUp(runtime, hiveTablet, 0); // root hive good
MakeSureTabletIsUp(runtime, TTestTxConfig::SchemeShard, 0); // root ss good
-
- TActorId sender = runtime.AllocateEdgeActor(0);
+
+ TActorId sender = runtime.AllocateEdgeActor(0);
InitSchemeRoot(runtime, sender);
-
- TSubDomainKey subdomainKey;
-
- // Create subdomain
- do {
+
+ TSubDomainKey subdomainKey;
+
+ // Create subdomain
+ do {
auto x = MakeHolder<NSchemeShard::TEvSchemeShard::TEvModifySchemeTransaction>();
auto* tran = x->Record.AddTransaction();
- tran->SetWorkingDir("/dc-1");
+ tran->SetWorkingDir("/dc-1");
tran->SetOperationType(NKikimrSchemeOp::ESchemeOpCreateSubDomain);
- auto* subd = tran->MutableSubDomain();
- subd->SetName("tenant1");
+ auto* subd = tran->MutableSubDomain();
+ subd->SetName("tenant1");
runtime.SendToPipe(TTestTxConfig::SchemeShard, sender, x.Release());
- TAutoPtr<IEventHandle> handle;
+ TAutoPtr<IEventHandle> handle;
auto reply = runtime.GrabEdgeEventRethrow<NSchemeShard::TEvSchemeShard::TEvModifySchemeTransactionResult>(handle, TDuration::MilliSeconds(100));
- if (reply) {
- subdomainKey = TSubDomainKey(reply->Record.GetSchemeshardId(), reply->Record.GetPathId());
+ if (reply) {
+ subdomainKey = TSubDomainKey(reply->Record.GetSchemeshardId(), reply->Record.GetPathId());
UNIT_ASSERT_VALUES_EQUAL(reply->Record.GetStatus(), (ui32)NKikimrScheme::EStatus::StatusAccepted);
- break;
- }
- } while (true);
-
- THolder<TEvHive::TEvCreateTablet> createHive = MakeHolder<TEvHive::TEvCreateTablet>(testerTablet, 0, TTabletTypes::Hive, BINDED_CHANNELS);
- createHive->Record.AddAllowedDomains();
- createHive->Record.MutableAllowedDomains(0)->SetSchemeShard(subdomainKey.first);
- createHive->Record.MutableAllowedDomains(0)->SetPathId(subdomainKey.second);
+ break;
+ }
+ } while (true);
+
+ THolder<TEvHive::TEvCreateTablet> createHive = MakeHolder<TEvHive::TEvCreateTablet>(testerTablet, 0, TTabletTypes::Hive, BINDED_CHANNELS);
+ createHive->Record.AddAllowedDomains();
+ createHive->Record.MutableAllowedDomains(0)->SetSchemeShard(subdomainKey.first);
+ createHive->Record.MutableAllowedDomains(0)->SetPathId(subdomainKey.second);
ui64 subHiveTablet = SendCreateTestTablet(runtime, hiveTablet, testerTablet, std::move(createHive), 0, false);
-
- TTestActorRuntime::TEventObserver prevObserverFunc;
- prevObserverFunc = runtime.SetObserverFunc([&](TTestActorRuntimeBase& runtime, TAutoPtr<IEventHandle>& event) {
+
+ TTestActorRuntime::TEventObserver prevObserverFunc;
+ prevObserverFunc = runtime.SetObserverFunc([&](TTestActorRuntimeBase& runtime, TAutoPtr<IEventHandle>& event) {
if (event->GetTypeRewrite() == NSchemeShard::TEvSchemeShard::EvDescribeSchemeResult) {
event->Get<NSchemeShard::TEvSchemeShard::TEvDescribeSchemeResult>()->MutableRecord()->
- MutablePathDescription()->MutableDomainDescription()->MutableProcessingParams()->SetHive(subHiveTablet);
- }
- return prevObserverFunc(runtime, event);
- });
-
- SendKillLocal(runtime, 1);
- CreateLocalForTenant(runtime, 1, "/dc-1/tenant1");
-
- MakeSureTabletIsUp(runtime, subHiveTablet, 0); // sub hive good
-
- runtime.SetObserverFunc(prevObserverFunc);
-
- THolder<TEvHive::TEvConfigureHive> configureHive = MakeHolder<TEvHive::TEvConfigureHive>(subdomainKey);
-
- runtime.SendToPipe(subHiveTablet, sender, configureHive.Release(), 0, GetPipeConfigWithRetries());
- TAutoPtr<IEventHandle> handle;
-
- auto configureHiveReply = runtime.GrabEdgeEventRethrow<TEvSubDomain::TEvConfigureStatus>(handle);
-
- Y_UNUSED(configureHiveReply);
-
- THolder<TEvHive::TEvCreateTablet> createTablet1 = MakeHolder<TEvHive::TEvCreateTablet>(testerTablet, 1, TTabletTypes::Dummy, BINDED_CHANNELS);
- createTablet1->Record.AddAllowedDomains();
- createTablet1->Record.MutableAllowedDomains(0)->SetSchemeShard(subdomainKey.first);
- createTablet1->Record.MutableAllowedDomains(0)->SetPathId(subdomainKey.second);
+ MutablePathDescription()->MutableDomainDescription()->MutableProcessingParams()->SetHive(subHiveTablet);
+ }
+ return prevObserverFunc(runtime, event);
+ });
+
+ SendKillLocal(runtime, 1);
+ CreateLocalForTenant(runtime, 1, "/dc-1/tenant1");
+
+ MakeSureTabletIsUp(runtime, subHiveTablet, 0); // sub hive good
+
+ runtime.SetObserverFunc(prevObserverFunc);
+
+ THolder<TEvHive::TEvConfigureHive> configureHive = MakeHolder<TEvHive::TEvConfigureHive>(subdomainKey);
+
+ runtime.SendToPipe(subHiveTablet, sender, configureHive.Release(), 0, GetPipeConfigWithRetries());
+ TAutoPtr<IEventHandle> handle;
+
+ auto configureHiveReply = runtime.GrabEdgeEventRethrow<TEvSubDomain::TEvConfigureStatus>(handle);
+
+ Y_UNUSED(configureHiveReply);
+
+ THolder<TEvHive::TEvCreateTablet> createTablet1 = MakeHolder<TEvHive::TEvCreateTablet>(testerTablet, 1, TTabletTypes::Dummy, BINDED_CHANNELS);
+ createTablet1->Record.AddAllowedDomains();
+ createTablet1->Record.MutableAllowedDomains(0)->SetSchemeShard(subdomainKey.first);
+ createTablet1->Record.MutableAllowedDomains(0)->SetPathId(subdomainKey.second);
ui64 tabletId1 = SendCreateTestTablet(runtime, hiveTablet, testerTablet, std::move(createTablet1), 0, true);
-
- MakeSureTabletIsUp(runtime, tabletId1, 0); // tablet up in root hive
-
- activeZone = true;
-
- int iterations = 0;
-
- for (;; ++iterations) {
- UNIT_ASSERT(iterations < 100); // 10 seconds max
-
- runtime.SendToPipe(subHiveTablet, sender, new TEvHive::TEvQueryMigration(), 0, GetPipeConfigWithRetries());
- auto queryMigrationReply = runtime.GrabEdgeEventRethrow<TEvHive::TEvQueryMigrationReply>(handle, TDuration::MilliSeconds(100));
-
- if (queryMigrationReply) {
- if (queryMigrationReply->Record.GetMigrationState() == NKikimrHive::EMigrationState::MIGRATION_COMPLETE) {
- break;
- }
-
- if (queryMigrationReply->Record.GetMigrationState() == NKikimrHive::EMigrationState::MIGRATION_READY) {
- // restart migration when needed
- THolder<TEvHive::TEvInitMigration> migration = MakeHolder<TEvHive::TEvInitMigration>();
- runtime.SendToPipe(subHiveTablet, sender, migration.Release(), 0, GetPipeConfigWithRetries());
- auto initMigrationReply = runtime.GrabEdgeEventRethrow<TEvHive::TEvInitMigrationReply>(handle, TDuration::MilliSeconds(100));
- if (initMigrationReply) {
- UNIT_ASSERT(initMigrationReply->Record.GetStatus() == NKikimrProto::OK);
- }
- }
-
- TDispatchOptions options;
- runtime.DispatchEvents(options, TDuration::MilliSeconds(100));
- }
- }
-
- activeZone = false;
-
- MakeSureTabletIsUp(runtime, tabletId1, 0); // tablet up in sub hive
-
- // retry create request to sub domain hive
+
+ MakeSureTabletIsUp(runtime, tabletId1, 0); // tablet up in root hive
+
+ activeZone = true;
+
+ int iterations = 0;
+
+ for (;; ++iterations) {
+ UNIT_ASSERT(iterations < 100); // 10 seconds max
+
+ runtime.SendToPipe(subHiveTablet, sender, new TEvHive::TEvQueryMigration(), 0, GetPipeConfigWithRetries());
+ auto queryMigrationReply = runtime.GrabEdgeEventRethrow<TEvHive::TEvQueryMigrationReply>(handle, TDuration::MilliSeconds(100));
+
+ if (queryMigrationReply) {
+ if (queryMigrationReply->Record.GetMigrationState() == NKikimrHive::EMigrationState::MIGRATION_COMPLETE) {
+ break;
+ }
+
+ if (queryMigrationReply->Record.GetMigrationState() == NKikimrHive::EMigrationState::MIGRATION_READY) {
+ // restart migration when needed
+ THolder<TEvHive::TEvInitMigration> migration = MakeHolder<TEvHive::TEvInitMigration>();
+ runtime.SendToPipe(subHiveTablet, sender, migration.Release(), 0, GetPipeConfigWithRetries());
+ auto initMigrationReply = runtime.GrabEdgeEventRethrow<TEvHive::TEvInitMigrationReply>(handle, TDuration::MilliSeconds(100));
+ if (initMigrationReply) {
+ UNIT_ASSERT(initMigrationReply->Record.GetStatus() == NKikimrProto::OK);
+ }
+ }
+
+ TDispatchOptions options;
+ runtime.DispatchEvents(options, TDuration::MilliSeconds(100));
+ }
+ }
+
+ activeZone = false;
+
+ MakeSureTabletIsUp(runtime, tabletId1, 0); // tablet up in sub hive
+
+ // retry create request to sub domain hive
createTablet1 = MakeHolder<TEvHive::TEvCreateTablet>(testerTablet, 1, TTabletTypes::Dummy, BINDED_CHANNELS);
- createTablet1->Record.SetTabletID(tabletId1);
-
- runtime.SendToPipe(hiveTablet, sender, createTablet1.Release(), 0, GetPipeConfigWithRetries());
-
- auto createTabletReply = runtime.GrabEdgeEventRethrow<TEvHive::TEvCreateTabletReply>(handle);
- UNIT_ASSERT(createTabletReply);
- UNIT_ASSERT(createTabletReply->Record.GetStatus() == NKikimrProto::INVALID_OWNER);
- UNIT_ASSERT(createTabletReply->Record.HasForwardRequest());
- UNIT_ASSERT_VALUES_EQUAL(createTabletReply->Record.GetForwardRequest().GetHiveTabletId(), subHiveTablet);
-
- });
- }
-
+ createTablet1->Record.SetTabletID(tabletId1);
+
+ runtime.SendToPipe(hiveTablet, sender, createTablet1.Release(), 0, GetPipeConfigWithRetries());
+
+ auto createTabletReply = runtime.GrabEdgeEventRethrow<TEvHive::TEvCreateTabletReply>(handle);
+ UNIT_ASSERT(createTabletReply);
+ UNIT_ASSERT(createTabletReply->Record.GetStatus() == NKikimrProto::INVALID_OWNER);
+ UNIT_ASSERT(createTabletReply->Record.HasForwardRequest());
+ UNIT_ASSERT_VALUES_EQUAL(createTabletReply->Record.GetForwardRequest().GetHiveTabletId(), subHiveTablet);
+
+ });
+ }
+
Y_UNIT_TEST(TestCreateAndDeleteTabletWithStoragePoolsReboots) {
const ui64 hiveTablet = MakeDefaultHiveID(0);
const ui64 bsControllerTablet = MakeBSControllerID(0);
@@ -1654,15 +1654,15 @@ Y_UNIT_TEST_SUITE(THiveTest) {
return initialEventsFilter.Prepare();
}, [&](const TString &dispatchName, std::function<void(TTestActorRuntime&)> setup, bool &activeZone) {
if (ENABLE_DETAILED_HIVE_LOG) {
- Ctest << "At dispatch " << dispatchName << Endl;
+ Ctest << "At dispatch " << dispatchName << Endl;
}
TTestBasicRuntime runtime(1, false);
- Setup(runtime, true);
+ Setup(runtime, true);
setup(runtime);
CreateTestBootstrapper(runtime, CreateTestTabletInfo(hiveTablet, TTabletTypes::FLAT_HIVE), &CreateDefaultHive);
- TAutoPtr<TEvHive::TEvCreateTablet> ev(new TEvHive::TEvCreateTablet(testerTablet, 0, TTabletTypes::Dummy, BINDED_CHANNELS));
+ TAutoPtr<TEvHive::TEvCreateTablet> ev(new TEvHive::TEvCreateTablet(testerTablet, 0, TTabletTypes::Dummy, BINDED_CHANNELS));
const bool doWaitForResult = false;
ui64 tabletId = SendCreateTestTablet(runtime, hiveTablet, testerTablet, ev, 0, doWaitForResult);
@@ -1672,7 +1672,7 @@ Y_UNIT_TEST_SUITE(THiveTest) {
try {
MakeSureTabletIsUp(runtime, tabletId, 0);
} catch (TEmptyEventQueueException&) {
- Ctest << "Event queue is empty at dispatch " << dispatchName << "\n";
+ Ctest << "Event queue is empty at dispatch " << dispatchName << "\n";
if (!allowIncompleteResult)
throw;
}
@@ -1683,14 +1683,14 @@ Y_UNIT_TEST_SUITE(THiveTest) {
Y_UNIT_TEST(TestCreateAndDeleteTabletWithStoragePools) {
TTestBasicRuntime runtime(1, false);
- Setup(runtime);
+ Setup(runtime);
const ui64 hiveTablet = MakeDefaultHiveID(0);
const ui64 testerTablet = MakeDefaultHiveID(1);
CreateTestBootstrapper(runtime, CreateTestTabletInfo(hiveTablet, TTabletTypes::FLAT_HIVE), &CreateDefaultHive);
TTabletTypes::EType tabletType = TTabletTypes::Dummy;
- TAutoPtr<TEvHive::TEvCreateTablet> ev(new TEvHive::TEvCreateTablet(testerTablet, 0, tabletType, BINDED_CHANNELS));
+ TAutoPtr<TEvHive::TEvCreateTablet> ev(new TEvHive::TEvCreateTablet(testerTablet, 0, tabletType, BINDED_CHANNELS));
const bool doWaitForResult = true;
ui64 tabletId = SendCreateTestTablet(runtime, hiveTablet, testerTablet, ev, 0, doWaitForResult);
@@ -1712,7 +1712,7 @@ Y_UNIT_TEST_SUITE(THiveTest) {
Y_UNIT_TEST(TestCreateAndReassignTabletWithStoragePools) {
TTestBasicRuntime runtime(1, false);
- Setup(runtime);
+ Setup(runtime);
const ui64 hiveTablet = MakeDefaultHiveID(0);
const ui64 testerTablet = MakeDefaultHiveID(1);
@@ -1720,7 +1720,7 @@ Y_UNIT_TEST_SUITE(THiveTest) {
CreateLocal(runtime, 0);
TTabletTypes::EType tabletType = TTabletTypes::Dummy;
- TAutoPtr<TEvHive::TEvCreateTablet> ev(new TEvHive::TEvCreateTablet(testerTablet, 0, tabletType, BINDED_CHANNELS));
+ TAutoPtr<TEvHive::TEvCreateTablet> ev(new TEvHive::TEvCreateTablet(testerTablet, 0, tabletType, BINDED_CHANNELS));
const bool doWaitForResult = true;
ui64 tabletId = SendCreateTestTablet(runtime, hiveTablet, testerTablet, ev, 0, doWaitForResult);
@@ -1754,161 +1754,161 @@ Y_UNIT_TEST_SUITE(THiveTest) {
}
}
- Y_UNIT_TEST(TestCreateAndReassignTabletWhileStarting) {
- TTestBasicRuntime runtime(1, false);
- Setup(runtime, true, 2);
-
- const ui64 hiveTablet = MakeDefaultHiveID(0);
- const ui64 testerTablet = MakeDefaultHiveID(1);
+ Y_UNIT_TEST(TestCreateAndReassignTabletWhileStarting) {
+ TTestBasicRuntime runtime(1, false);
+ Setup(runtime, true, 2);
+
+ const ui64 hiveTablet = MakeDefaultHiveID(0);
+ const ui64 testerTablet = MakeDefaultHiveID(1);
CreateTestBootstrapper(runtime, CreateTestTabletInfo(hiveTablet, TTabletTypes::FLAT_HIVE), &CreateDefaultHive);
- CreateLocal(runtime, 0);
-
- TTabletTypes::EType tabletType = TTabletTypes::Dummy;
- TAutoPtr<TEvHive::TEvCreateTablet> ev(new TEvHive::TEvCreateTablet(testerTablet, 0, tabletType, BINDED_CHANNELS));
- const bool doWaitForResult = true;
- ui64 tabletId = SendCreateTestTablet(runtime, hiveTablet, testerTablet, ev, 0, doWaitForResult);
-
- MakeSureTabletIsUp(runtime, tabletId, 0);
-
- SendReassignTablet(runtime, hiveTablet, tabletId, {}, 0);
-
- {
- TDispatchOptions options;
- options.FinalEvents.push_back(TDispatchOptions::TFinalEventCondition(TEvLocal::EvTabletStatus));
- runtime.DispatchEvents(options);
- }
-
- {
- TDispatchOptions options;
- options.FinalEvents.push_back(TDispatchOptions::TFinalEventCondition(TEvLocal::EvTabletStatus));
- runtime.DispatchEvents(options);
- }
-
- MakeSureTabletIsUp(runtime, tabletId, 0);
-
- TVector<THolder<IEventHandle>> blockedCommits;
- auto blockCommits = [&](TTestActorRuntimeBase&, TAutoPtr<IEventHandle>& ev) -> auto {
- switch (ev->GetTypeRewrite()) {
- case TEvTablet::TEvCommit::EventType: {
- auto* msg = ev->Get<TEvTablet::TEvCommit>();
- if (msg->TabletID == hiveTablet) {
- Ctest << "blocked commit for tablet " << msg->TabletID << Endl;
+ CreateLocal(runtime, 0);
+
+ TTabletTypes::EType tabletType = TTabletTypes::Dummy;
+ TAutoPtr<TEvHive::TEvCreateTablet> ev(new TEvHive::TEvCreateTablet(testerTablet, 0, tabletType, BINDED_CHANNELS));
+ const bool doWaitForResult = true;
+ ui64 tabletId = SendCreateTestTablet(runtime, hiveTablet, testerTablet, ev, 0, doWaitForResult);
+
+ MakeSureTabletIsUp(runtime, tabletId, 0);
+
+ SendReassignTablet(runtime, hiveTablet, tabletId, {}, 0);
+
+ {
+ TDispatchOptions options;
+ options.FinalEvents.push_back(TDispatchOptions::TFinalEventCondition(TEvLocal::EvTabletStatus));
+ runtime.DispatchEvents(options);
+ }
+
+ {
+ TDispatchOptions options;
+ options.FinalEvents.push_back(TDispatchOptions::TFinalEventCondition(TEvLocal::EvTabletStatus));
+ runtime.DispatchEvents(options);
+ }
+
+ MakeSureTabletIsUp(runtime, tabletId, 0);
+
+ TVector<THolder<IEventHandle>> blockedCommits;
+ auto blockCommits = [&](TTestActorRuntimeBase&, TAutoPtr<IEventHandle>& ev) -> auto {
+ switch (ev->GetTypeRewrite()) {
+ case TEvTablet::TEvCommit::EventType: {
+ auto* msg = ev->Get<TEvTablet::TEvCommit>();
+ if (msg->TabletID == hiveTablet) {
+ Ctest << "blocked commit for tablet " << msg->TabletID << Endl;
blockedCommits.push_back(std::move(ev));
- return TTestActorRuntime::EEventAction::DROP;
- }
- }
- }
- return TTestActorRuntime::EEventAction::PROCESS;
- };
-
- Ctest << "killing tablet " << tabletId << Endl;
- runtime.Register(CreateTabletKiller(tabletId, runtime.GetNodeId(0)));
-
- {
- TDispatchOptions options;
- options.FinalEvents.push_back(TDispatchOptions::TFinalEventCondition(TEvLocal::EvDeadTabletAck));
- runtime.DispatchEvents(options);
- }
-
- SendReassignTabletSpace(runtime, hiveTablet, tabletId, {}, 0);
-
- Ctest << "blocking commits" << Endl;
- auto prevObserver = runtime.SetObserverFunc(blockCommits);
-
- auto waitFor = [&](const auto& condition, const TString& description) {
- while (!condition()) {
- Ctest << "waiting for " << description << Endl;
- TDispatchOptions options;
- options.CustomFinalCondition = [&]() {
- return condition();
- };
- runtime.DispatchEvents(options);
- }
- };
-
- waitFor([&]{ return blockedCommits.size() >= 2; }, "at least 2 blocked commits");
-
- Ctest << "restoring commits" << Endl;
- runtime.SetObserverFunc(prevObserver);
- for (auto& ev : blockedCommits) {
- runtime.Send(ev.Release(), 0, true);
- }
-
- {
- TDispatchOptions options;
- options.FinalEvents.push_back(TDispatchOptions::TFinalEventCondition(TEvLocal::EvBootTablet));
- runtime.DispatchEvents(options);
- }
- }
-
- Y_UNIT_TEST(TestCreateTabletsWithRaceForStoragePoolsKIKIMR_9659) {
- TTestBasicRuntime runtime(1, false);
- Setup(runtime);
-
- const ui64 hiveTablet = MakeDefaultHiveID(0);
- const ui64 testerTablet = MakeDefaultHiveID(1);
+ return TTestActorRuntime::EEventAction::DROP;
+ }
+ }
+ }
+ return TTestActorRuntime::EEventAction::PROCESS;
+ };
+
+ Ctest << "killing tablet " << tabletId << Endl;
+ runtime.Register(CreateTabletKiller(tabletId, runtime.GetNodeId(0)));
+
+ {
+ TDispatchOptions options;
+ options.FinalEvents.push_back(TDispatchOptions::TFinalEventCondition(TEvLocal::EvDeadTabletAck));
+ runtime.DispatchEvents(options);
+ }
+
+ SendReassignTabletSpace(runtime, hiveTablet, tabletId, {}, 0);
+
+ Ctest << "blocking commits" << Endl;
+ auto prevObserver = runtime.SetObserverFunc(blockCommits);
+
+ auto waitFor = [&](const auto& condition, const TString& description) {
+ while (!condition()) {
+ Ctest << "waiting for " << description << Endl;
+ TDispatchOptions options;
+ options.CustomFinalCondition = [&]() {
+ return condition();
+ };
+ runtime.DispatchEvents(options);
+ }
+ };
+
+ waitFor([&]{ return blockedCommits.size() >= 2; }, "at least 2 blocked commits");
+
+ Ctest << "restoring commits" << Endl;
+ runtime.SetObserverFunc(prevObserver);
+ for (auto& ev : blockedCommits) {
+ runtime.Send(ev.Release(), 0, true);
+ }
+
+ {
+ TDispatchOptions options;
+ options.FinalEvents.push_back(TDispatchOptions::TFinalEventCondition(TEvLocal::EvBootTablet));
+ runtime.DispatchEvents(options);
+ }
+ }
+
+ Y_UNIT_TEST(TestCreateTabletsWithRaceForStoragePoolsKIKIMR_9659) {
+ TTestBasicRuntime runtime(1, false);
+ Setup(runtime);
+
+ const ui64 hiveTablet = MakeDefaultHiveID(0);
+ const ui64 testerTablet = MakeDefaultHiveID(1);
CreateTestBootstrapper(runtime, CreateTestTabletInfo(hiveTablet, TTabletTypes::FLAT_HIVE), &CreateDefaultHive);
- CreateLocal(runtime, 0);
-
- TTabletTypes::EType tabletType = TTabletTypes::Dummy;
- TVector<ui64> tabletIds;
+ CreateLocal(runtime, 0);
+
+ TTabletTypes::EType tabletType = TTabletTypes::Dummy;
+ TVector<ui64> tabletIds;
TActorId senderB = runtime.AllocateEdgeActor(0);
- for (int i = 0; i < 2; ++i) {
- TChannelsBindings bindings;
- for (int n = 0; n <= i + 1; ++n) {
- bindings.push_back(GetChannelBind(STORAGE_POOL + ToString(n + 1)));
- }
- TAutoPtr<TEvHive::TEvCreateTablet> ev(new TEvHive::TEvCreateTablet(testerTablet, i, tabletType, bindings));
- runtime.SendToPipe(hiveTablet, senderB, ev.Release(), 0, GetPipeConfigWithRetries());
- }
-
- for (int i = 0; i < 2; ++i) {
- TAutoPtr<IEventHandle> handle;
- auto createTabletReply = runtime.GrabEdgeEventRethrow<TEvHive::TEvCreateTabletReply>(handle);
- ui64 tabletId = createTabletReply->Record.GetTabletID();
- tabletIds.push_back(tabletId);
- }
-
- for (ui64 tabletId : tabletIds) {
- MakeSureTabletIsUp(runtime, tabletId, 0);
- }
-
- runtime.Register(CreateTabletKiller(hiveTablet, runtime.GetNodeId(0)));
-
- MakeSureTabletIsUp(runtime, hiveTablet, 0);
-
- for (ui64 tabletId : tabletIds) {
- MakeSureTabletIsUp(runtime, tabletId, 0);
- }
- }
-
+ for (int i = 0; i < 2; ++i) {
+ TChannelsBindings bindings;
+ for (int n = 0; n <= i + 1; ++n) {
+ bindings.push_back(GetChannelBind(STORAGE_POOL + ToString(n + 1)));
+ }
+ TAutoPtr<TEvHive::TEvCreateTablet> ev(new TEvHive::TEvCreateTablet(testerTablet, i, tabletType, bindings));
+ runtime.SendToPipe(hiveTablet, senderB, ev.Release(), 0, GetPipeConfigWithRetries());
+ }
+
+ for (int i = 0; i < 2; ++i) {
+ TAutoPtr<IEventHandle> handle;
+ auto createTabletReply = runtime.GrabEdgeEventRethrow<TEvHive::TEvCreateTabletReply>(handle);
+ ui64 tabletId = createTabletReply->Record.GetTabletID();
+ tabletIds.push_back(tabletId);
+ }
+
+ for (ui64 tabletId : tabletIds) {
+ MakeSureTabletIsUp(runtime, tabletId, 0);
+ }
+
+ runtime.Register(CreateTabletKiller(hiveTablet, runtime.GetNodeId(0)));
+
+ MakeSureTabletIsUp(runtime, hiveTablet, 0);
+
+ for (ui64 tabletId : tabletIds) {
+ MakeSureTabletIsUp(runtime, tabletId, 0);
+ }
+ }
+
Y_UNIT_TEST(TestDeleteTablet) {
TTestBasicRuntime runtime(1, false);
- Setup(runtime, true);
+ Setup(runtime, true);
TActorId sender = runtime.AllocateEdgeActor();
- const ui64 hiveTablet = MakeDefaultHiveID(0);
- const ui64 testerTablet = MakeDefaultHiveID(1);
+ const ui64 hiveTablet = MakeDefaultHiveID(0);
+ const ui64 testerTablet = MakeDefaultHiveID(1);
CreateTestBootstrapper(runtime, CreateTestTabletInfo(hiveTablet, TTabletTypes::FLAT_HIVE), &CreateDefaultHive);
- TTabletTypes::EType tabletType = TTabletTypes::Dummy;
+ TTabletTypes::EType tabletType = TTabletTypes::Dummy;
const ui64 tabletId = SendCreateTestTablet(runtime, hiveTablet, testerTablet, MakeHolder<TEvHive::TEvCreateTablet>(testerTablet, 0, tabletType, BINDED_CHANNELS), 0, false);
- {
- TDispatchOptions options;
- options.FinalEvents.emplace_back(TEvLocal::EvBootTablet);
- runtime.DispatchEvents(options);
- }
+ {
+ TDispatchOptions options;
+ options.FinalEvents.emplace_back(TEvLocal::EvBootTablet);
+ runtime.DispatchEvents(options);
+ }
if (!SendDeleteTestTablet(runtime, hiveTablet, MakeHolder<TEvHive::TEvDeleteTablet>(testerTablet, 0, 0))) {
WaitEvDeleteTabletResult(runtime);
- }
+ }
- runtime.SendToPipe(hiveTablet, sender, new TEvHive::TEvRequestHiveInfo(true));
- TAutoPtr<IEventHandle> handle;
- TEvHive::TEvResponseHiveInfo* response = runtime.GrabEdgeEventRethrow<TEvHive::TEvResponseHiveInfo>(handle);
+ runtime.SendToPipe(hiveTablet, sender, new TEvHive::TEvRequestHiveInfo(true));
+ TAutoPtr<IEventHandle> handle;
+ TEvHive::TEvResponseHiveInfo* response = runtime.GrabEdgeEventRethrow<TEvHive::TEvResponseHiveInfo>(handle);
for (const NKikimrHive::TTabletInfo& tablet : response->Record.GetTablets()) {
UNIT_ASSERT_VALUES_UNEQUAL(tablet.GetTabletID(), tabletId);
- }
- }
-
+ }
+ }
+
Y_UNIT_TEST(TestDeleteOwnerTablets) {
TTestBasicRuntime runtime(1, false);
Setup(runtime, true);
@@ -1966,39 +1966,39 @@ Y_UNIT_TEST_SUITE(THiveTest) {
}
Y_UNIT_TEST(TestDeleteTabletWithFollowers) {
- TTestBasicRuntime runtime(3, false);
- Setup(runtime, true);
- const ui64 hiveTablet = MakeDefaultHiveID(0);
- const ui64 testerTablet = MakeDefaultHiveID(1);
+ TTestBasicRuntime runtime(3, false);
+ Setup(runtime, true);
+ const ui64 hiveTablet = MakeDefaultHiveID(0);
+ const ui64 testerTablet = MakeDefaultHiveID(1);
CreateTestBootstrapper(runtime, CreateTestTabletInfo(hiveTablet, TTabletTypes::FLAT_HIVE), &CreateDefaultHive);
- TTabletTypes::EType tabletType = TTabletTypes::Dummy;
- THolder<TEvHive::TEvCreateTablet> ev(new TEvHive::TEvCreateTablet(testerTablet, 100500, tabletType, BINDED_CHANNELS));
+ TTabletTypes::EType tabletType = TTabletTypes::Dummy;
+ THolder<TEvHive::TEvCreateTablet> ev(new TEvHive::TEvCreateTablet(testerTablet, 100500, tabletType, BINDED_CHANNELS));
auto* followerGroup = ev->Record.AddFollowerGroups();
followerGroup->SetFollowerCount(2);
followerGroup->SetRequireDifferentNodes(true);
ui64 tabletId = SendCreateTestTablet(runtime, hiveTablet, testerTablet, std::move(ev), 0, true);
-
- NTabletPipe::TClientConfig pipeConfig;
- pipeConfig.RetryPolicy = NTabletPipe::TClientRetryPolicy::WithRetries();
- pipeConfig.ForceLocal = true;
+
+ NTabletPipe::TClientConfig pipeConfig;
+ pipeConfig.RetryPolicy = NTabletPipe::TClientRetryPolicy::WithRetries();
+ pipeConfig.ForceLocal = true;
pipeConfig.AllowFollower = true;
-
- MakeSureTabletIsUp(runtime, tabletId, 0, &pipeConfig);
- MakeSureTabletIsUp(runtime, tabletId, 1, &pipeConfig);
- MakeSureTabletIsUp(runtime, tabletId, 2, &pipeConfig);
-
+
+ MakeSureTabletIsUp(runtime, tabletId, 0, &pipeConfig);
+ MakeSureTabletIsUp(runtime, tabletId, 1, &pipeConfig);
+ MakeSureTabletIsUp(runtime, tabletId, 2, &pipeConfig);
+
if (!SendDeleteTestTablet(runtime, hiveTablet, MakeHolder<TEvHive::TEvDeleteTablet>(testerTablet, 100500, 0))) {
- WaitEvDeleteTabletResult(runtime);
- }
-
- SendKillLocal(runtime, 0);
- WaitForEvServerDisconnected(runtime);
- SendKillLocal(runtime, 1);
- WaitForEvServerDisconnected(runtime);
- SendKillLocal(runtime, 2);
- WaitForEvServerDisconnected(runtime);
- }
-
+ WaitEvDeleteTabletResult(runtime);
+ }
+
+ SendKillLocal(runtime, 0);
+ WaitForEvServerDisconnected(runtime);
+ SendKillLocal(runtime, 1);
+ WaitForEvServerDisconnected(runtime);
+ SendKillLocal(runtime, 2);
+ WaitForEvServerDisconnected(runtime);
+ }
+
Y_UNIT_TEST(PipeAlivenessOfDeadTablet) {
TTestBasicRuntime runtime(1, false);
Setup(runtime, true);
@@ -2006,7 +2006,7 @@ Y_UNIT_TEST_SUITE(THiveTest) {
const ui64 hiveTablet = MakeDefaultHiveID(0);
const ui64 testerTablet = 1;
CreateTestBootstrapper(runtime, CreateTestTabletInfo(hiveTablet, TTabletTypes::FLAT_HIVE), &CreateDefaultHive);
- TTabletTypes::EType tabletType = TTabletTypes::Dummy;
+ TTabletTypes::EType tabletType = TTabletTypes::Dummy;
const ui64 tabletId = SendCreateTestTablet(runtime, hiveTablet, testerTablet, MakeHolder<TEvHive::TEvCreateTablet>(testerTablet, 0, tabletType, BINDED_CHANNELS), 0, true);
MakeSureTabletIsUp(runtime, tabletId, 0);
if (!SendDeleteTestTablet(runtime, hiveTablet, MakeHolder<TEvHive::TEvDeleteTablet>(testerTablet, 0, 0))) {
@@ -2016,7 +2016,7 @@ Y_UNIT_TEST_SUITE(THiveTest) {
NTabletPipe::TClientConfig clientConfig;
clientConfig.CheckAliveness = true;
- clientConfig.RetryPolicy = {.RetryLimitCount = 3};
+ clientConfig.RetryPolicy = {.RetryLimitCount = 3};
runtime.Register(NTabletPipe::CreateClient(sender, tabletId, clientConfig));
TAutoPtr<IEventHandle> handle;
auto connectResult = runtime.GrabEdgeEventRethrow<TEvTabletPipe::TEvClientConnected>(handle);
@@ -2032,8 +2032,8 @@ Y_UNIT_TEST_SUITE(THiveTest) {
const ui64 testerTablet = MakeDefaultHiveID(1);
CreateTestBootstrapper(runtime, CreateTestTabletInfo(hiveTablet, TTabletTypes::FLAT_HIVE), &CreateDefaultHive);
- TTabletTypes::EType tabletType = TTabletTypes::Dummy;
- runtime.SendToPipe(hiveTablet, sender, new TEvHive::TEvCreateTablet(testerTablet, 0, tabletType, BINDED_CHANNELS), 0, GetPipeConfigWithRetries());
+ TTabletTypes::EType tabletType = TTabletTypes::Dummy;
+ runtime.SendToPipe(hiveTablet, sender, new TEvHive::TEvCreateTablet(testerTablet, 0, tabletType, BINDED_CHANNELS), 0, GetPipeConfigWithRetries());
TDispatchOptions options;
options.FinalEvents.push_back(TDispatchOptions::TFinalEventCondition(
@@ -2074,9 +2074,9 @@ Y_UNIT_TEST_SUITE(THiveTest) {
const ui64 testerTablet = MakeDefaultHiveID(1);
CreateTestBootstrapper(runtime, CreateTestTabletInfo(hiveTablet, TTabletTypes::FLAT_HIVE), &CreateDefaultHive);
- TTabletTypes::EType tabletType = TTabletTypes::Dummy;
+ TTabletTypes::EType tabletType = TTabletTypes::Dummy;
{
- runtime.SendToPipe(hiveTablet, sender, new TEvHive::TEvCreateTablet(testerTablet, 0, tabletType, BINDED_CHANNELS),
+ runtime.SendToPipe(hiveTablet, sender, new TEvHive::TEvCreateTablet(testerTablet, 0, tabletType, BINDED_CHANNELS),
0, GetPipeConfigWithRetries());
TAutoPtr<IEventHandle> handle;
auto createTabletReply = runtime.GrabEdgeEventRethrow<TEvHive::TEvCreateTabletReply>(handle);
@@ -2090,7 +2090,7 @@ Y_UNIT_TEST_SUITE(THiveTest) {
MakeSureTabletIsUp(runtime, tabletId, 0);
}
{
- runtime.SendToPipe(hiveTablet, sender, new TEvHive::TEvCreateTablet(testerTablet, 0, tabletType, BINDED_CHANNELS),
+ runtime.SendToPipe(hiveTablet, sender, new TEvHive::TEvCreateTablet(testerTablet, 0, tabletType, BINDED_CHANNELS),
0, GetPipeConfigWithRetries());
TAutoPtr<IEventHandle> handle;
auto createTabletReply = runtime.GrabEdgeEventRethrow<TEvHive::TEvCreateTabletReply>(handle);
@@ -2113,12 +2113,12 @@ Y_UNIT_TEST_SUITE(THiveTest) {
const ui64 testerTablet = MakeDefaultHiveID(1);
CreateTestBootstrapper(runtime, CreateTestTabletInfo(hiveTablet, TTabletTypes::FLAT_HIVE), &CreateDefaultHive);
- TTabletTypes::EType tabletType = TTabletTypes::Dummy;
+ TTabletTypes::EType tabletType = TTabletTypes::Dummy;
ui32 nodeIndex = 0;
SendCreateTestTablet(runtime, hiveTablet, testerTablet,
MakeHolder<TEvHive::TEvCreateTablet>(testerTablet, 0, tabletType, BINDED_CHANNELS), nodeIndex, true);
{
- runtime.SendToPipe(hiveTablet, sender, new TEvHive::TEvCreateTablet(testerTablet, 0, TTabletTypes::TxAllocator, BINDED_CHANNELS),
+ runtime.SendToPipe(hiveTablet, sender, new TEvHive::TEvCreateTablet(testerTablet, 0, TTabletTypes::TxAllocator, BINDED_CHANNELS),
nodeIndex, GetPipeConfigWithRetries());
TAutoPtr<IEventHandle> handle;
auto event = runtime.GrabEdgeEventRethrow<TEvHive::TEvCreateTabletReply>(handle);
@@ -2145,7 +2145,7 @@ Y_UNIT_TEST_SUITE(THiveTest) {
return initialEventsFilter.Prepare();
}, [&](const TString &dispatchName, std::function<void(TTestActorRuntime&)> setup, bool &activeZone) {
if (ENABLE_DETAILED_HIVE_LOG) {
- Ctest << "At dispatch " << dispatchName << Endl;
+ Ctest << "At dispatch " << dispatchName << Endl;
}
TTestBasicRuntime runtime;
Setup(runtime, true);
@@ -2158,25 +2158,25 @@ Y_UNIT_TEST_SUITE(THiveTest) {
runtime.DispatchEvents(options);
ui64 tabletId = 0;
- TTabletTypes::EType tabletType = TTabletTypes::Dummy;
-
- runtime.SendToPipe(hiveTablet, sender, new TEvHive::TEvCreateTablet(testerTablet, 0, tabletType, BINDED_CHANNELS));
- TAutoPtr<IEventHandle> handle;
- auto createTabletReply = runtime.GrabEdgeEventRethrow<TEvHive::TEvCreateTabletReply>(handle);
- UNIT_ASSERT(createTabletReply);
- UNIT_ASSERT_EQUAL_C(createTabletReply->Record.GetStatus(), NKikimrProto::OK,
- (ui32)createTabletReply->Record.GetStatus() << " != " << (ui32)NKikimrProto::OK);
- UNIT_ASSERT_EQUAL_C(createTabletReply->Record.GetOwner(), testerTablet,
- createTabletReply->Record.GetOwner() << " != " << testerTablet);
- tabletId = createTabletReply->Record.GetTabletID();
-
+ TTabletTypes::EType tabletType = TTabletTypes::Dummy;
+
+ runtime.SendToPipe(hiveTablet, sender, new TEvHive::TEvCreateTablet(testerTablet, 0, tabletType, BINDED_CHANNELS));
+ TAutoPtr<IEventHandle> handle;
+ auto createTabletReply = runtime.GrabEdgeEventRethrow<TEvHive::TEvCreateTabletReply>(handle);
+ UNIT_ASSERT(createTabletReply);
+ UNIT_ASSERT_EQUAL_C(createTabletReply->Record.GetStatus(), NKikimrProto::OK,
+ (ui32)createTabletReply->Record.GetStatus() << " != " << (ui32)NKikimrProto::OK);
+ UNIT_ASSERT_EQUAL_C(createTabletReply->Record.GetOwner(), testerTablet,
+ createTabletReply->Record.GetOwner() << " != " << testerTablet);
+ tabletId = createTabletReply->Record.GetTabletID();
+
activeZone = true;
{
bool allowIncompleteResult = (dispatchName != INITIAL_TEST_DISPATCH_NAME);
try {
- MakeSureTabletIsUp(runtime, tabletId, 0);
+ MakeSureTabletIsUp(runtime, tabletId, 0);
} catch (TEmptyEventQueueException&) {
- Ctest << "Event queue is empty at dispatch " << dispatchName << "\n";
+ Ctest << "Event queue is empty at dispatch " << dispatchName << "\n";
if (!allowIncompleteResult)
throw;
}
@@ -2194,7 +2194,7 @@ Y_UNIT_TEST_SUITE(THiveTest) {
CreateTestBootstrapper(runtime, CreateTestTabletInfo(hiveTablet, TTabletTypes::FLAT_HIVE), &CreateDefaultHive);
ui32 nodeIndex = 0;
- TTabletTypes::EType tabletType = TTabletTypes::Dummy;
+ TTabletTypes::EType tabletType = TTabletTypes::Dummy;
ui64 tabletId = SendCreateTestTablet(runtime, hiveTablet, testerTablet,
MakeHolder<TEvHive::TEvCreateTablet>(testerTablet, 100500, tabletType, BINDED_CHANNELS), nodeIndex, true);
MakeSureTabletIsUp(runtime, tabletId, nodeIndex);
@@ -2206,39 +2206,39 @@ Y_UNIT_TEST_SUITE(THiveTest) {
Y_UNIT_TEST(TestNodeDisconnect) {
TTestBasicRuntime runtime(1, false);
- Setup(runtime, true);
- TVector<ui64> tabletIds;
+ Setup(runtime, true);
+ TVector<ui64> tabletIds;
TActorId sender = runtime.AllocateEdgeActor();
- //TAutoPtr<ITabletScheduledEventsGuard> guard = CreateTabletScheduledEventsGuard(tabletIds, runtime, sender);
- const ui64 hiveTablet = MakeDefaultHiveID(0);
- const ui64 testerTablet = MakeDefaultHiveID(1);
+ //TAutoPtr<ITabletScheduledEventsGuard> guard = CreateTabletScheduledEventsGuard(tabletIds, runtime, sender);
+ const ui64 hiveTablet = MakeDefaultHiveID(0);
+ const ui64 testerTablet = MakeDefaultHiveID(1);
CreateTestBootstrapper(runtime, CreateTestTabletInfo(hiveTablet, TTabletTypes::FLAT_HIVE), &CreateDefaultHive);
-
- TTabletTypes::EType tabletType = TTabletTypes::Dummy;
- THolder<TEvHive::TEvCreateTablet> ev(new TEvHive::TEvCreateTablet(testerTablet, 100500, tabletType, BINDED_CHANNELS));
+
+ TTabletTypes::EType tabletType = TTabletTypes::Dummy;
+ THolder<TEvHive::TEvCreateTablet> ev(new TEvHive::TEvCreateTablet(testerTablet, 100500, tabletType, BINDED_CHANNELS));
ev->Record.SetFollowerCount(1);
ui64 tabletId = SendCreateTestTablet(runtime, hiveTablet, testerTablet, std::move(ev), 0, true);
-
- NTabletPipe::TClientConfig pipeConfig;
- pipeConfig.RetryPolicy = NTabletPipe::TClientRetryPolicy::WithRetries();
- pipeConfig.ForceLocal = true;
+
+ NTabletPipe::TClientConfig pipeConfig;
+ pipeConfig.RetryPolicy = NTabletPipe::TClientRetryPolicy::WithRetries();
+ pipeConfig.ForceLocal = true;
pipeConfig.AllowFollower = true;
-
- WaitForTabletIsUp(runtime, tabletId, 0, &pipeConfig);
- runtime.SendToPipe(hiveTablet, sender, new TEvInterconnect::TEvNodeDisconnected(runtime.GetNodeId(0)));
+
+ WaitForTabletIsUp(runtime, tabletId, 0, &pipeConfig);
+ runtime.SendToPipe(hiveTablet, sender, new TEvInterconnect::TEvNodeDisconnected(runtime.GetNodeId(0)));
//TActorId local = MakeLocalID(runtime.GetNodeId(0));
//runtime.Send(new IEventHandle(local, sender, new TEvTabletPipe::TEvClientDestroyed(hiveTablet, TActorId(), TActorId())), 0);
- SendKillLocal(runtime, 0);
- runtime.Register(CreateTabletKiller(hiveTablet));
- {
- TDispatchOptions options;
- options.FinalEvents.push_back(TDispatchOptions::TFinalEventCondition(TEvLocal::EvPing));
- runtime.DispatchEvents(options);
- }
- CreateLocal(runtime, 0);
- WaitForTabletIsUp(runtime, tabletId, 0, &pipeConfig);
- }
-
+ SendKillLocal(runtime, 0);
+ runtime.Register(CreateTabletKiller(hiveTablet));
+ {
+ TDispatchOptions options;
+ options.FinalEvents.push_back(TDispatchOptions::TFinalEventCondition(TEvLocal::EvPing));
+ runtime.DispatchEvents(options);
+ }
+ CreateLocal(runtime, 0);
+ WaitForTabletIsUp(runtime, tabletId, 0, &pipeConfig);
+ }
+
Y_UNIT_TEST(TestLocalReplacement) {
TTestBasicRuntime runtime(2, false);
Setup(runtime, true);
@@ -2250,11 +2250,11 @@ Y_UNIT_TEST_SUITE(THiveTest) {
// Kill local on node 1
SendKillLocal(runtime, 1);
// Create the tablet
- TTabletTypes::EType tabletType = TTabletTypes::Dummy;
+ TTabletTypes::EType tabletType = TTabletTypes::Dummy;
ui64 tabletId = SendCreateTestTablet(runtime, hiveTablet, testerTablet,
MakeHolder<TEvHive::TEvCreateTablet>(testerTablet, 100500, tabletType, BINDED_CHANNELS), 0, true);
// Make sure the tablet is OK
- WaitForTabletIsUp(runtime, tabletId, 0);
+ WaitForTabletIsUp(runtime, tabletId, 0);
// Re-create the local on node 1
CreateLocal(runtime, 1);
// Kill both local and the tablet on node 0
@@ -2263,60 +2263,60 @@ Y_UNIT_TEST_SUITE(THiveTest) {
WaitForEvServerDisconnected(runtime);
// Tablet should have moved to node 1
// Make sure the tablet is OK
- WaitForTabletIsUp(runtime, tabletId, 1);
+ WaitForTabletIsUp(runtime, tabletId, 1);
}
- Y_UNIT_TEST(TestHiveRestart) {
- TTestBasicRuntime runtime(1, false);
- Setup(runtime, true);
- TVector<ui64> tabletIds;
- const ui64 hiveTablet = MakeDefaultHiveID(0);
- const ui64 testerTablet = MakeDefaultHiveID(1);
+ Y_UNIT_TEST(TestHiveRestart) {
+ TTestBasicRuntime runtime(1, false);
+ Setup(runtime, true);
+ TVector<ui64> tabletIds;
+ const ui64 hiveTablet = MakeDefaultHiveID(0);
+ const ui64 testerTablet = MakeDefaultHiveID(1);
CreateTestBootstrapper(runtime, CreateTestTabletInfo(hiveTablet, TTabletTypes::FLAT_HIVE), &CreateDefaultHive);
-
- // creating tablet
- ui32 nodeIndex = 0;
- TTabletTypes::EType tabletType = TTabletTypes::Dummy;
- ui64 tabletId = SendCreateTestTablet(runtime, hiveTablet, testerTablet,
+
+ // creating tablet
+ ui32 nodeIndex = 0;
+ TTabletTypes::EType tabletType = TTabletTypes::Dummy;
+ ui64 tabletId = SendCreateTestTablet(runtime, hiveTablet, testerTablet,
MakeHolder<TEvHive::TEvCreateTablet>(testerTablet, 100500, tabletType, BINDED_CHANNELS), nodeIndex, true);
- MakeSureTabletIsUp(runtime, tabletId, nodeIndex);
-
+ MakeSureTabletIsUp(runtime, tabletId, nodeIndex);
+
TActorId senderA = runtime.AllocateEdgeActor();
-
- // first check, aquiring generation
- runtime.SendToPipe(hiveTablet, senderA, new TEvHive::TEvRequestHiveInfo(tabletId));
- TAutoPtr<IEventHandle> handle1;
- TEvHive::TEvResponseHiveInfo* response1 = runtime.GrabEdgeEventRethrow<TEvHive::TEvResponseHiveInfo>(handle1);
- UNIT_ASSERT_VALUES_EQUAL(response1->Record.TabletsSize(), 1);
- const auto& tabletInfo1 = response1->Record.GetTablets(0);
- UNIT_ASSERT_VALUES_EQUAL(tabletInfo1.GetTabletID(), tabletId);
- UNIT_ASSERT_VALUES_EQUAL((int)tabletInfo1.GetVolatileState(), (int)NKikimrHive::ETabletVolatileState::TABLET_VOLATILE_STATE_RUNNING);
-
- // killing hive
- runtime.Register(CreateTabletKiller(hiveTablet));
-
- // waiting for node synchronization
- {
- TDispatchOptions options;
- options.FinalEvents.push_back(TDispatchOptions::TFinalEventCondition(TEvLocal::EvStatus));
- runtime.DispatchEvents(options);
- }
-
- // second check
- MakeSureTabletIsUp(runtime, tabletId, nodeIndex);
-
- runtime.SendToPipe(hiveTablet, senderA, new TEvHive::TEvRequestHiveInfo(tabletId));
- TAutoPtr<IEventHandle> handle2;
- TEvHive::TEvResponseHiveInfo* response2 = runtime.GrabEdgeEventRethrow<TEvHive::TEvResponseHiveInfo>(handle2);
- UNIT_ASSERT_VALUES_EQUAL(response2->Record.TabletsSize(), 1);
- const auto& tabletInfo2 = response2->Record.GetTablets(0);
- UNIT_ASSERT_VALUES_EQUAL(tabletInfo2.GetTabletID(), tabletId);
- UNIT_ASSERT_VALUES_EQUAL((int)tabletInfo2.GetVolatileState(), (int)NKikimrHive::ETabletVolatileState::TABLET_VOLATILE_STATE_RUNNING);
-
- // the most important check
- UNIT_ASSERT_VALUES_EQUAL(tabletInfo2.GetGeneration(), tabletInfo1.GetGeneration());
- }
-
+
+ // first check, aquiring generation
+ runtime.SendToPipe(hiveTablet, senderA, new TEvHive::TEvRequestHiveInfo(tabletId));
+ TAutoPtr<IEventHandle> handle1;
+ TEvHive::TEvResponseHiveInfo* response1 = runtime.GrabEdgeEventRethrow<TEvHive::TEvResponseHiveInfo>(handle1);
+ UNIT_ASSERT_VALUES_EQUAL(response1->Record.TabletsSize(), 1);
+ const auto& tabletInfo1 = response1->Record.GetTablets(0);
+ UNIT_ASSERT_VALUES_EQUAL(tabletInfo1.GetTabletID(), tabletId);
+ UNIT_ASSERT_VALUES_EQUAL((int)tabletInfo1.GetVolatileState(), (int)NKikimrHive::ETabletVolatileState::TABLET_VOLATILE_STATE_RUNNING);
+
+ // killing hive
+ runtime.Register(CreateTabletKiller(hiveTablet));
+
+ // waiting for node synchronization
+ {
+ TDispatchOptions options;
+ options.FinalEvents.push_back(TDispatchOptions::TFinalEventCondition(TEvLocal::EvStatus));
+ runtime.DispatchEvents(options);
+ }
+
+ // second check
+ MakeSureTabletIsUp(runtime, tabletId, nodeIndex);
+
+ runtime.SendToPipe(hiveTablet, senderA, new TEvHive::TEvRequestHiveInfo(tabletId));
+ TAutoPtr<IEventHandle> handle2;
+ TEvHive::TEvResponseHiveInfo* response2 = runtime.GrabEdgeEventRethrow<TEvHive::TEvResponseHiveInfo>(handle2);
+ UNIT_ASSERT_VALUES_EQUAL(response2->Record.TabletsSize(), 1);
+ const auto& tabletInfo2 = response2->Record.GetTablets(0);
+ UNIT_ASSERT_VALUES_EQUAL(tabletInfo2.GetTabletID(), tabletId);
+ UNIT_ASSERT_VALUES_EQUAL((int)tabletInfo2.GetVolatileState(), (int)NKikimrHive::ETabletVolatileState::TABLET_VOLATILE_STATE_RUNNING);
+
+ // the most important check
+ UNIT_ASSERT_VALUES_EQUAL(tabletInfo2.GetGeneration(), tabletInfo1.GetGeneration());
+ }
+
Y_UNIT_TEST(TestLimitedNodeList) {
TTestBasicRuntime runtime(3, false);
Setup(runtime, true);
@@ -2328,9 +2328,9 @@ Y_UNIT_TEST_SUITE(THiveTest) {
// Kill local on node 1
SendKillLocal(runtime, 1);
// Create the tablet
- TTabletTypes::EType tabletType = TTabletTypes::Dummy;
- THolder<TEvHive::TEvCreateTablet> ev(new TEvHive::TEvCreateTablet(testerTablet, 100500, tabletType, BINDED_CHANNELS));
- ev->Record.AddAllowedNodeIDs(runtime.GetNodeId(1));
+ TTabletTypes::EType tabletType = TTabletTypes::Dummy;
+ THolder<TEvHive::TEvCreateTablet> ev(new TEvHive::TEvCreateTablet(testerTablet, 100500, tabletType, BINDED_CHANNELS));
+ ev->Record.AddAllowedNodeIDs(runtime.GetNodeId(1));
ui64 tabletId = SendCreateTestTablet(runtime, hiveTablet, testerTablet, std::move(ev), 0, false);
// Make sure the tablet is down
MakeSureTabletIsDown(runtime, tabletId, 0);
@@ -2342,19 +2342,19 @@ Y_UNIT_TEST_SUITE(THiveTest) {
Y_UNIT_TEST(TestCreateTabletAndReassignGroups) {
TTestBasicRuntime runtime(1, false);
- Setup(runtime, true);
- const ui64 hiveTablet = MakeDefaultHiveID(0);
- const ui64 testerTablet = MakeDefaultHiveID(1);
+ Setup(runtime, true);
+ const ui64 hiveTablet = MakeDefaultHiveID(0);
+ const ui64 testerTablet = MakeDefaultHiveID(1);
CreateTestBootstrapper(runtime, CreateTestTabletInfo(hiveTablet, TTabletTypes::FLAT_HIVE), &CreateDefaultHive);
-
- TTabletTypes::EType tabletType = TTabletTypes::Dummy;
- ui64 tabletId = SendCreateTestTablet(runtime, hiveTablet, testerTablet,
+
+ TTabletTypes::EType tabletType = TTabletTypes::Dummy;
+ ui64 tabletId = SendCreateTestTablet(runtime, hiveTablet, testerTablet,
MakeHolder<TEvHive::TEvCreateTablet>(testerTablet, 0, tabletType, BINDED_CHANNELS), 0, true);
- MakeSureTabletIsUp(runtime, tabletId, 0);
- SendReassignTablet(runtime, hiveTablet, tabletId, {}, 0);
- MakeSureTabletIsUp(runtime, tabletId, 0);
- }
-
+ MakeSureTabletIsUp(runtime, tabletId, 0);
+ SendReassignTablet(runtime, hiveTablet, tabletId, {}, 0);
+ MakeSureTabletIsUp(runtime, tabletId, 0);
+ }
+
Y_UNIT_TEST(TestCreateTabletWithWrongSPoolsAndReassignGroupsFailButDeletionIsOk) {
TTestBasicRuntime runtime(1, false);
Setup(runtime, true);
@@ -2363,20 +2363,20 @@ Y_UNIT_TEST_SUITE(THiveTest) {
CreateTestBootstrapper(runtime, CreateTestTabletInfo(hiveTablet, TTabletTypes::FLAT_HIVE), &CreateDefaultHive);
TTabletTypes::EType tabletType = TTabletTypes::Dummy;
- TChannelsBindings channlesBinds = {GetDefaultChannelBind("NoExistStoragePool"),
- GetDefaultChannelBind("NoExistStoragePool")};
- auto ev = new TEvHive::TEvCreateTablet(testerTablet, 0, tabletType, channlesBinds);
+ TChannelsBindings channlesBinds = {GetDefaultChannelBind("NoExistStoragePool"),
+ GetDefaultChannelBind("NoExistStoragePool")};
+ auto ev = new TEvHive::TEvCreateTablet(testerTablet, 0, tabletType, channlesBinds);
ui64 tabletId = SendCreateTestTablet(runtime, hiveTablet, testerTablet, THolder(ev), 0, false);
MakeSureTabletIsDown(runtime, tabletId, 0);
SendReassignTablet(runtime, hiveTablet, tabletId, {}, 0);
- /*{
+ /*{
TDispatchOptions options;
options.FinalEvents.push_back(TDispatchOptions::TFinalEventCondition(TEvBlobStorage::EvControllerSelectGroupsResult));
runtime.DispatchEvents(options);
- }*/
+ }*/
if (!SendDeleteTestTablet(runtime, hiveTablet, MakeHolder<TEvHive::TEvDeleteTablet>(testerTablet, 0, 0))) {
WaitEvDeleteTabletResult(runtime);
@@ -2387,205 +2387,205 @@ Y_UNIT_TEST_SUITE(THiveTest) {
Y_UNIT_TEST(TestCreateTabletAndReassignGroups3) {
TTestBasicRuntime runtime(1, false);
- Setup(runtime, true, 3);
- const ui64 hiveTablet = MakeDefaultHiveID(0);
- const ui64 testerTablet = MakeDefaultHiveID(1);
+ Setup(runtime, true, 3);
+ const ui64 hiveTablet = MakeDefaultHiveID(0);
+ const ui64 testerTablet = MakeDefaultHiveID(1);
CreateTestBootstrapper(runtime, CreateTestTabletInfo(hiveTablet, TTabletTypes::FLAT_HIVE), &CreateDefaultHive);
-
- TTabletTypes::EType tabletType = TTabletTypes::Dummy;
- ui64 tabletId = SendCreateTestTablet(runtime, hiveTablet, testerTablet,
+
+ TTabletTypes::EType tabletType = TTabletTypes::Dummy;
+ ui64 tabletId = SendCreateTestTablet(runtime, hiveTablet, testerTablet,
MakeHolder<TEvHive::TEvCreateTablet>(testerTablet, 0, tabletType, BINDED_CHANNELS), 0, true);
- MakeSureTabletIsUp(runtime, tabletId, 0);
- SendReassignTablet(runtime, hiveTablet, tabletId, {}, 0);
- SendReassignTablet(runtime, hiveTablet, tabletId, {}, 0);
- SendReassignTablet(runtime, hiveTablet, tabletId, {}, 0);
- MakeSureTabletIsUp(runtime, tabletId, 0);
- {
- TDispatchOptions options;
- //options.FinalEvents.push_back(TDispatchOptions::TFinalEventCondition(TEvBlobStorage::EvControllerSelectGroups));
- runtime.DispatchEvents(options);
- }
- }
-
- Y_UNIT_TEST(TestCreateTabletAndMixedReassignGroups3) {
- TTestBasicRuntime runtime(1, false);
- Setup(runtime, true, 3);
- const ui64 hiveTablet = MakeDefaultHiveID(0);
- const ui64 testerTablet = MakeDefaultHiveID(1);
+ MakeSureTabletIsUp(runtime, tabletId, 0);
+ SendReassignTablet(runtime, hiveTablet, tabletId, {}, 0);
+ SendReassignTablet(runtime, hiveTablet, tabletId, {}, 0);
+ SendReassignTablet(runtime, hiveTablet, tabletId, {}, 0);
+ MakeSureTabletIsUp(runtime, tabletId, 0);
+ {
+ TDispatchOptions options;
+ //options.FinalEvents.push_back(TDispatchOptions::TFinalEventCondition(TEvBlobStorage::EvControllerSelectGroups));
+ runtime.DispatchEvents(options);
+ }
+ }
+
+ Y_UNIT_TEST(TestCreateTabletAndMixedReassignGroups3) {
+ TTestBasicRuntime runtime(1, false);
+ Setup(runtime, true, 3);
+ const ui64 hiveTablet = MakeDefaultHiveID(0);
+ const ui64 testerTablet = MakeDefaultHiveID(1);
CreateTestBootstrapper(runtime, CreateTestTabletInfo(hiveTablet, TTabletTypes::FLAT_HIVE), &CreateDefaultHive);
-
- TTabletTypes::EType tabletType = TTabletTypes::Dummy;
- ui64 tabletId = SendCreateTestTablet(runtime, hiveTablet, testerTablet,
- MakeHolder<TEvHive::TEvCreateTablet>(testerTablet, 0, tabletType, BINDED_CHANNELS), 0, true);
- MakeSureTabletIsUp(runtime, tabletId, 0);
- SendReassignTabletSpace(runtime, hiveTablet, tabletId, {}, 0);
- {
- TDispatchOptions options;
- options.FinalEvents.push_back(TDispatchOptions::TFinalEventCondition(TEvTablet::EvBoot));
- runtime.DispatchEvents(options);
- }
- MakeSureTabletIsUp(runtime, tabletId, 0);
-
- TChannelsBindings newBindings = BINDED_CHANNELS;
- newBindings.push_back(GetChannelBind(STORAGE_POOL + "3")); // add one more channel
-
- // re-create tablet to apply new channel bindings
- SendCreateTestTablet(runtime, hiveTablet, testerTablet,
- MakeHolder<TEvHive::TEvCreateTablet>(testerTablet, 0, tabletType, newBindings), 0, true);
-
- {
- TDispatchOptions options;
- options.FinalEvents.push_back(TDispatchOptions::TFinalEventCondition(TEvTablet::EvBoot));
- runtime.DispatchEvents(options);
- }
- MakeSureTabletIsUp(runtime, tabletId, 0);
- }
-
+
+ TTabletTypes::EType tabletType = TTabletTypes::Dummy;
+ ui64 tabletId = SendCreateTestTablet(runtime, hiveTablet, testerTablet,
+ MakeHolder<TEvHive::TEvCreateTablet>(testerTablet, 0, tabletType, BINDED_CHANNELS), 0, true);
+ MakeSureTabletIsUp(runtime, tabletId, 0);
+ SendReassignTabletSpace(runtime, hiveTablet, tabletId, {}, 0);
+ {
+ TDispatchOptions options;
+ options.FinalEvents.push_back(TDispatchOptions::TFinalEventCondition(TEvTablet::EvBoot));
+ runtime.DispatchEvents(options);
+ }
+ MakeSureTabletIsUp(runtime, tabletId, 0);
+
+ TChannelsBindings newBindings = BINDED_CHANNELS;
+ newBindings.push_back(GetChannelBind(STORAGE_POOL + "3")); // add one more channel
+
+ // re-create tablet to apply new channel bindings
+ SendCreateTestTablet(runtime, hiveTablet, testerTablet,
+ MakeHolder<TEvHive::TEvCreateTablet>(testerTablet, 0, tabletType, newBindings), 0, true);
+
+ {
+ TDispatchOptions options;
+ options.FinalEvents.push_back(TDispatchOptions::TFinalEventCondition(TEvTablet::EvBoot));
+ runtime.DispatchEvents(options);
+ }
+ MakeSureTabletIsUp(runtime, tabletId, 0);
+ }
+
Y_UNIT_TEST(TestReassignGroupsWithRecreateTablet) {
TTestBasicRuntime runtime(1, false);
- Setup(runtime, true, 3);
+ Setup(runtime, true, 3);
TActorId sender = runtime.AllocateEdgeActor();
- const ui64 hiveTablet = MakeDefaultHiveID(0);
- const ui64 testerTablet = MakeDefaultHiveID(1);
+ const ui64 hiveTablet = MakeDefaultHiveID(0);
+ const ui64 testerTablet = MakeDefaultHiveID(1);
CreateTestBootstrapper(runtime, CreateTestTabletInfo(hiveTablet, TTabletTypes::FLAT_HIVE), &CreateDefaultHive);
-
- TTabletTypes::EType tabletType = TTabletTypes::Dummy;
- ui64 tabletId = SendCreateTestTablet(runtime,
- hiveTablet,
- testerTablet,
+
+ TTabletTypes::EType tabletType = TTabletTypes::Dummy;
+ ui64 tabletId = SendCreateTestTablet(runtime,
+ hiveTablet,
+ testerTablet,
MakeHolder<TEvHive::TEvCreateTablet>(testerTablet, 0, tabletType, BINDED_CHANNELS),
- 0,
- true);
-
- MakeSureTabletIsUp(runtime, tabletId, 0);
-
- runtime.SendToPipe(hiveTablet, sender, new TEvHive::TEvLookupChannelInfo(tabletId));
- TAutoPtr<IEventHandle> handle1;
- TEvHive::TEvChannelInfo* channelInfo1 = runtime.GrabEdgeEventRethrow<TEvHive::TEvChannelInfo>(handle1);
+ 0,
+ true);
+
+ MakeSureTabletIsUp(runtime, tabletId, 0);
+
+ runtime.SendToPipe(hiveTablet, sender, new TEvHive::TEvLookupChannelInfo(tabletId));
+ TAutoPtr<IEventHandle> handle1;
+ TEvHive::TEvChannelInfo* channelInfo1 = runtime.GrabEdgeEventRethrow<TEvHive::TEvChannelInfo>(handle1);
TVector<ui32> channels = {1, 2};
-
- runtime.SendToPipe(hiveTablet, sender, new TEvHive::TEvInvalidateStoragePools(), 0, GetPipeConfigWithRetries());
-
- SendReassignTablet(runtime, hiveTablet, tabletId, channels, 0);
-
- {
- TDispatchOptions options;
- options.FinalEvents.push_back(TDispatchOptions::TFinalEventCondition(TEvBlobStorage::EvControllerSelectGroups));
- runtime.DispatchEvents(options);
- }
-
- tabletId = SendCreateTestTablet(runtime,
- hiveTablet,
- testerTablet,
+
+ runtime.SendToPipe(hiveTablet, sender, new TEvHive::TEvInvalidateStoragePools(), 0, GetPipeConfigWithRetries());
+
+ SendReassignTablet(runtime, hiveTablet, tabletId, channels, 0);
+
+ {
+ TDispatchOptions options;
+ options.FinalEvents.push_back(TDispatchOptions::TFinalEventCondition(TEvBlobStorage::EvControllerSelectGroups));
+ runtime.DispatchEvents(options);
+ }
+
+ tabletId = SendCreateTestTablet(runtime,
+ hiveTablet,
+ testerTablet,
MakeHolder<TEvHive::TEvCreateTablet>(testerTablet, 0, tabletType, BINDED_CHANNELS),
- 0,
- true,
- NKikimrProto::ALREADY);
-
- MakeSureTabletIsUp(runtime, tabletId, 0);
-
- runtime.SendToPipe(hiveTablet, sender, new TEvHive::TEvLookupChannelInfo(tabletId));
- TAutoPtr<IEventHandle> handle2;
- TEvHive::TEvChannelInfo* channelInfo2 = runtime.GrabEdgeEventRethrow<TEvHive::TEvChannelInfo>(handle2);
- UNIT_ASSERT_VALUES_EQUAL(channelInfo1->Record.ChannelInfoSize(), channelInfo2->Record.ChannelInfoSize());
- int size = channelInfo1->Record.ChannelInfoSize();
- for (int channel = 0; channel < size; ++channel) {
- if (std::find(channels.begin(), channels.end(), channel) != channels.end())
- continue;
- const auto& history1 = channelInfo1->Record.GetChannelInfo(channel).GetHistory();
- const auto& history2 = channelInfo2->Record.GetChannelInfo(channel).GetHistory();
- UNIT_ASSERT_VALUES_EQUAL_C(history1.size(), history2.size(), "For channel " << channel);
- }
- }
-
+ 0,
+ true,
+ NKikimrProto::ALREADY);
+
+ MakeSureTabletIsUp(runtime, tabletId, 0);
+
+ runtime.SendToPipe(hiveTablet, sender, new TEvHive::TEvLookupChannelInfo(tabletId));
+ TAutoPtr<IEventHandle> handle2;
+ TEvHive::TEvChannelInfo* channelInfo2 = runtime.GrabEdgeEventRethrow<TEvHive::TEvChannelInfo>(handle2);
+ UNIT_ASSERT_VALUES_EQUAL(channelInfo1->Record.ChannelInfoSize(), channelInfo2->Record.ChannelInfoSize());
+ int size = channelInfo1->Record.ChannelInfoSize();
+ for (int channel = 0; channel < size; ++channel) {
+ if (std::find(channels.begin(), channels.end(), channel) != channels.end())
+ continue;
+ const auto& history1 = channelInfo1->Record.GetChannelInfo(channel).GetHistory();
+ const auto& history2 = channelInfo2->Record.GetChannelInfo(channel).GetHistory();
+ UNIT_ASSERT_VALUES_EQUAL_C(history1.size(), history2.size(), "For channel " << channel);
+ }
+ }
+
Y_UNIT_TEST(TestCreateTabletAndReassignGroupsWithReboots) {
- const ui64 hiveTablet = MakeDefaultHiveID(0);
- const ui64 bsControllerTablet = MakeBSControllerID(0);
- const ui64 testerTablet = MakeDefaultHiveID(1);
-
- THiveInitialEventsFilter initialEventsFilter;
-
- RunTestWithReboots({hiveTablet, bsControllerTablet, testerTablet}, [&]() {
- return initialEventsFilter.Prepare();
+ const ui64 hiveTablet = MakeDefaultHiveID(0);
+ const ui64 bsControllerTablet = MakeBSControllerID(0);
+ const ui64 testerTablet = MakeDefaultHiveID(1);
+
+ THiveInitialEventsFilter initialEventsFilter;
+
+ RunTestWithReboots({hiveTablet, bsControllerTablet, testerTablet}, [&]() {
+ return initialEventsFilter.Prepare();
}, [&](const TString &dispatchName, std::function<void(TTestActorRuntime&)> setup, bool &activeZone) {
- if (ENABLE_DETAILED_HIVE_LOG) {
- Ctest << "At dispatch " << dispatchName << Endl;
- }
+ if (ENABLE_DETAILED_HIVE_LOG) {
+ Ctest << "At dispatch " << dispatchName << Endl;
+ }
TTestBasicRuntime runtime;
- Setup(runtime, true);
- setup(runtime);
+ Setup(runtime, true);
+ setup(runtime);
TActorId sender = runtime.AllocateEdgeActor();
-
+
CreateTestBootstrapper(runtime, CreateTestTabletInfo(hiveTablet, TTabletTypes::FLAT_HIVE), &CreateDefaultHive);
- TDispatchOptions options;
- options.FinalEvents.push_back(TDispatchOptions::TFinalEventCondition(TEvTablet::EvBoot));
- runtime.DispatchEvents(options);
-
- ui64 tabletId = 0;
- TTabletTypes::EType tabletType = TTabletTypes::Dummy;
-
- runtime.SendToPipe(hiveTablet, sender, new TEvHive::TEvCreateTablet(testerTablet, 0, tabletType, BINDED_CHANNELS));
- TAutoPtr<IEventHandle> handle;
- auto createTabletReply = runtime.GrabEdgeEventRethrow<TEvHive::TEvCreateTabletReply>(handle);
- UNIT_ASSERT(createTabletReply);
- UNIT_ASSERT_EQUAL_C(createTabletReply->Record.GetStatus(), NKikimrProto::OK,
- (ui32)createTabletReply->Record.GetStatus() << " != " << (ui32)NKikimrProto::OK);
- UNIT_ASSERT_EQUAL_C(createTabletReply->Record.GetOwner(), testerTablet,
- createTabletReply->Record.GetOwner() << " != " << testerTablet);
- tabletId = createTabletReply->Record.GetTabletID();
-
- runtime.SendToPipe(hiveTablet, sender, new TEvHive::TEvReassignTablet(tabletId), 0, GetPipeConfigWithRetries());
-
- activeZone = true;
- {
- bool allowIncompleteResult = (dispatchName != INITIAL_TEST_DISPATCH_NAME);
- try {
- TAutoPtr<IEventHandle> handle;
- auto tabletCreationResult = runtime.GrabEdgeEventRethrow<TEvHive::TEvTabletCreationResult>(handle);
- UNIT_ASSERT(tabletCreationResult);
- UNIT_ASSERT_EQUAL_C(tabletCreationResult->Record.GetStatus(), NKikimrProto::OK,
- (ui32)tabletCreationResult->Record.GetStatus() << " != " << (ui32)NKikimrProto::OK);
- UNIT_ASSERT_EQUAL_C(tabletCreationResult->Record.GetTabletID(), tabletId,
- tabletCreationResult->Record.GetTabletID() << " != " << tabletId);
- } catch (TEmptyEventQueueException&) {
- Ctest << "Event queue is empty at dispatch " << dispatchName << "\n";
- if (!allowIncompleteResult)
- throw;
- }
- }
- activeZone = false;
- });
- }
-
+ TDispatchOptions options;
+ options.FinalEvents.push_back(TDispatchOptions::TFinalEventCondition(TEvTablet::EvBoot));
+ runtime.DispatchEvents(options);
+
+ ui64 tabletId = 0;
+ TTabletTypes::EType tabletType = TTabletTypes::Dummy;
+
+ runtime.SendToPipe(hiveTablet, sender, new TEvHive::TEvCreateTablet(testerTablet, 0, tabletType, BINDED_CHANNELS));
+ TAutoPtr<IEventHandle> handle;
+ auto createTabletReply = runtime.GrabEdgeEventRethrow<TEvHive::TEvCreateTabletReply>(handle);
+ UNIT_ASSERT(createTabletReply);
+ UNIT_ASSERT_EQUAL_C(createTabletReply->Record.GetStatus(), NKikimrProto::OK,
+ (ui32)createTabletReply->Record.GetStatus() << " != " << (ui32)NKikimrProto::OK);
+ UNIT_ASSERT_EQUAL_C(createTabletReply->Record.GetOwner(), testerTablet,
+ createTabletReply->Record.GetOwner() << " != " << testerTablet);
+ tabletId = createTabletReply->Record.GetTabletID();
+
+ runtime.SendToPipe(hiveTablet, sender, new TEvHive::TEvReassignTablet(tabletId), 0, GetPipeConfigWithRetries());
+
+ activeZone = true;
+ {
+ bool allowIncompleteResult = (dispatchName != INITIAL_TEST_DISPATCH_NAME);
+ try {
+ TAutoPtr<IEventHandle> handle;
+ auto tabletCreationResult = runtime.GrabEdgeEventRethrow<TEvHive::TEvTabletCreationResult>(handle);
+ UNIT_ASSERT(tabletCreationResult);
+ UNIT_ASSERT_EQUAL_C(tabletCreationResult->Record.GetStatus(), NKikimrProto::OK,
+ (ui32)tabletCreationResult->Record.GetStatus() << " != " << (ui32)NKikimrProto::OK);
+ UNIT_ASSERT_EQUAL_C(tabletCreationResult->Record.GetTabletID(), tabletId,
+ tabletCreationResult->Record.GetTabletID() << " != " << tabletId);
+ } catch (TEmptyEventQueueException&) {
+ Ctest << "Event queue is empty at dispatch " << dispatchName << "\n";
+ if (!allowIncompleteResult)
+ throw;
+ }
+ }
+ activeZone = false;
+ });
+ }
+
// Y_UNIT_TEST(TestCreateTabletAndChangeProfiles) {
// TTestBasicRuntime runtime(1, false);
-// Setup(runtime, true);
+// Setup(runtime, true);
// TActorId sender = runtime.AllocateEdgeActor();
-// CreatePDiskAndGroup(runtime, sender);
-// const ui64 hiveTablet = MakeDefaultHiveID(0);
-// const ui64 testerTablet = MakeDefaultHiveID(1);
+// CreatePDiskAndGroup(runtime, sender);
+// const ui64 hiveTablet = MakeDefaultHiveID(0);
+// const ui64 testerTablet = MakeDefaultHiveID(1);
// CreateTestBootstrapper(runtime, CreateTestTabletInfo(hiveTablet, TTabletTypes::FLAT_HIVE), &CreateDefaultHive);
-
-// ui32 tabletType = 0;
-// ui64 tabletId = SendCreateTestTablet(runtime, hiveTablet, testerTablet,
-// new TEvHive::TEvCreateTablet(testerTablet, 0, tabletType, 0), 0, true);
-// MakeSureTabletIsUp(runtime, tabletId, 0);
-
-// { // setup channel profiles
-// TIntrusivePtr<TChannelProfiles> channelProfiles = new TChannelProfiles;
-// channelProfiles->Profiles.emplace_back();
+
+// ui32 tabletType = 0;
+// ui64 tabletId = SendCreateTestTablet(runtime, hiveTablet, testerTablet,
+// new TEvHive::TEvCreateTablet(testerTablet, 0, tabletType, 0), 0, true);
+// MakeSureTabletIsUp(runtime, tabletId, 0);
+
+// { // setup channel profiles
+// TIntrusivePtr<TChannelProfiles> channelProfiles = new TChannelProfiles;
+// channelProfiles->Profiles.emplace_back();
// TChannelProfiles::TProfile &profile = channelProfiles->Profiles.back();
-// for (ui32 channelIdx = 0; channelIdx < 4; ++channelIdx) {
-// profile.Channels.emplace_back(TBlobStorageGroupType::Erasure4Plus2Block, 0, NKikimrBlobStorage::TVDiskKind::Default);
-// }
-// runtime.GetAppData().ChannelProfiles = channelProfiles;
-// }
-
-// tabletId = SendCreateTestTablet(runtime, hiveTablet, testerTablet,
-// new TEvHive::TEvCreateTablet(testerTablet, 0, tabletType, 0), 0, true);
-// MakeSureTabletIsUp(runtime, tabletId, 0);
-// }
-
+// for (ui32 channelIdx = 0; channelIdx < 4; ++channelIdx) {
+// profile.Channels.emplace_back(TBlobStorageGroupType::Erasure4Plus2Block, 0, NKikimrBlobStorage::TVDiskKind::Default);
+// }
+// runtime.GetAppData().ChannelProfiles = channelProfiles;
+// }
+
+// tabletId = SendCreateTestTablet(runtime, hiveTablet, testerTablet,
+// new TEvHive::TEvCreateTablet(testerTablet, 0, tabletType, 0), 0, true);
+// MakeSureTabletIsUp(runtime, tabletId, 0);
+// }
+
// FIXME: Hive does not pass this test.
// Commented to remove noise from the unit-test logs
/*
@@ -2660,351 +2660,351 @@ Y_UNIT_TEST_SUITE(THiveTest) {
MakeSureTabletIsUp(runtime, tabletId, 1);
}
*/
-
+
Y_UNIT_TEST(TestFollowers) {
TTestBasicRuntime runtime(3, false);
- Setup(runtime, true);
+ Setup(runtime, true);
TVector<ui64> tabletIds;
- const ui64 hiveTablet = MakeDefaultHiveID(0);
- const ui64 testerTablet = MakeDefaultHiveID(1);
+ const ui64 hiveTablet = MakeDefaultHiveID(0);
+ const ui64 testerTablet = MakeDefaultHiveID(1);
CreateTestBootstrapper(runtime, CreateTestTabletInfo(hiveTablet, TTabletTypes::FLAT_HIVE), &CreateDefaultHive);
-
- TTabletTypes::EType tabletType = TTabletTypes::Dummy;
- THolder<TEvHive::TEvCreateTablet> ev(new TEvHive::TEvCreateTablet(testerTablet, 100500, tabletType, BINDED_CHANNELS));
+
+ TTabletTypes::EType tabletType = TTabletTypes::Dummy;
+ THolder<TEvHive::TEvCreateTablet> ev(new TEvHive::TEvCreateTablet(testerTablet, 100500, tabletType, BINDED_CHANNELS));
auto* followerGroup = ev->Record.AddFollowerGroups();
followerGroup->SetFollowerCount(2);
followerGroup->SetRequireDifferentNodes(true);
ui64 tabletId = SendCreateTestTablet(runtime, hiveTablet, testerTablet, std::move(ev), 0, true);
-
- NTabletPipe::TClientConfig pipeConfig;
- pipeConfig.RetryPolicy = NTabletPipe::TClientRetryPolicy::WithRetries();
- pipeConfig.ForceLocal = true;
+
+ NTabletPipe::TClientConfig pipeConfig;
+ pipeConfig.RetryPolicy = NTabletPipe::TClientRetryPolicy::WithRetries();
+ pipeConfig.ForceLocal = true;
pipeConfig.AllowFollower = true;
-
- MakeSureTabletIsUp(runtime, tabletId, 0, &pipeConfig);
- MakeSureTabletIsUp(runtime, tabletId, 1, &pipeConfig);
- MakeSureTabletIsUp(runtime, tabletId, 2, &pipeConfig);
- }
-
+
+ MakeSureTabletIsUp(runtime, tabletId, 0, &pipeConfig);
+ MakeSureTabletIsUp(runtime, tabletId, 1, &pipeConfig);
+ MakeSureTabletIsUp(runtime, tabletId, 2, &pipeConfig);
+ }
+
Y_UNIT_TEST(TestFollowersReconfiguration) {
TTestBasicRuntime runtime(3, false);
- Setup(runtime, true);
+ Setup(runtime, true);
TVector<ui64> tabletIds;
TActorId senderA = runtime.AllocateEdgeActor();
- //TAutoPtr<ITabletScheduledEventsGuard> guard = CreateTabletScheduledEventsGuard(tabletIds, runtime, senderA);
- const ui64 hiveTablet = MakeDefaultHiveID(0);
- const ui64 testerTablet = MakeDefaultHiveID(1);
+ //TAutoPtr<ITabletScheduledEventsGuard> guard = CreateTabletScheduledEventsGuard(tabletIds, runtime, senderA);
+ const ui64 hiveTablet = MakeDefaultHiveID(0);
+ const ui64 testerTablet = MakeDefaultHiveID(1);
CreateTestBootstrapper(runtime, CreateTestTabletInfo(hiveTablet, TTabletTypes::FLAT_HIVE), &CreateDefaultHive);
-
- TTabletTypes::EType tabletType = TTabletTypes::Dummy;
- THolder<TEvHive::TEvCreateTablet> ev(new TEvHive::TEvCreateTablet(testerTablet, 100500, tabletType, BINDED_CHANNELS));
+
+ TTabletTypes::EType tabletType = TTabletTypes::Dummy;
+ THolder<TEvHive::TEvCreateTablet> ev(new TEvHive::TEvCreateTablet(testerTablet, 100500, tabletType, BINDED_CHANNELS));
auto* followerGroup = ev->Record.AddFollowerGroups();
followerGroup->SetFollowerCount(2);
followerGroup->SetRequireDifferentNodes(true);
ui64 tabletId = SendCreateTestTablet(runtime, hiveTablet, testerTablet, std::move(ev), 0, true);
-
- NTabletPipe::TClientConfig pipeConfig;
- pipeConfig.RetryPolicy = NTabletPipe::TClientRetryPolicy::WithRetries();
- pipeConfig.ForceLocal = true;
+
+ NTabletPipe::TClientConfig pipeConfig;
+ pipeConfig.RetryPolicy = NTabletPipe::TClientRetryPolicy::WithRetries();
+ pipeConfig.ForceLocal = true;
pipeConfig.AllowFollower = true;
-
- WaitForTabletIsUp(runtime, tabletId, 0, &pipeConfig);
- WaitForTabletIsUp(runtime, tabletId, 1, &pipeConfig);
- WaitForTabletIsUp(runtime, tabletId, 2, &pipeConfig);
-
- ev.Reset(new TEvHive::TEvCreateTablet(testerTablet, 100500, tabletType, BINDED_CHANNELS));
+
+ WaitForTabletIsUp(runtime, tabletId, 0, &pipeConfig);
+ WaitForTabletIsUp(runtime, tabletId, 1, &pipeConfig);
+ WaitForTabletIsUp(runtime, tabletId, 2, &pipeConfig);
+
+ ev.Reset(new TEvHive::TEvCreateTablet(testerTablet, 100500, tabletType, BINDED_CHANNELS));
ev->Record.SetFollowerCount(1);
- runtime.SendToPipe(hiveTablet, senderA, ev.Release(), 0, GetPipeConfigWithRetries());
-
- {
- TDispatchOptions options;
- options.FinalEvents.emplace_back(TEvTablet::EvTabletDead);
- runtime.DispatchEvents(options);
- }
-
- ev.Reset(new TEvHive::TEvCreateTablet(testerTablet, 100500, tabletType, BINDED_CHANNELS));
+ runtime.SendToPipe(hiveTablet, senderA, ev.Release(), 0, GetPipeConfigWithRetries());
+
+ {
+ TDispatchOptions options;
+ options.FinalEvents.emplace_back(TEvTablet::EvTabletDead);
+ runtime.DispatchEvents(options);
+ }
+
+ ev.Reset(new TEvHive::TEvCreateTablet(testerTablet, 100500, tabletType, BINDED_CHANNELS));
ev->Record.SetFollowerCount(2);
- runtime.SendToPipe(hiveTablet, senderA, ev.Release(), 0, GetPipeConfigWithRetries());
-
- {
- TDispatchOptions options;
- options.FinalEvents.emplace_back(TEvTablet::EvTabletActive);
- runtime.DispatchEvents(options);
- }
- }
-
+ runtime.SendToPipe(hiveTablet, senderA, ev.Release(), 0, GetPipeConfigWithRetries());
+
+ {
+ TDispatchOptions options;
+ options.FinalEvents.emplace_back(TEvTablet::EvTabletActive);
+ runtime.DispatchEvents(options);
+ }
+ }
+
Y_UNIT_TEST(TestFollowerPromotion) {
- constexpr int NODES = 3;
+ constexpr int NODES = 3;
TTestBasicRuntime runtime(NODES, false);
- Setup(runtime, true);
+ Setup(runtime, true);
TVector<ui64> tabletIds;
- const ui64 hiveTablet = MakeDefaultHiveID(0);
- const ui64 testerTablet = MakeDefaultHiveID(1);
+ const ui64 hiveTablet = MakeDefaultHiveID(0);
+ const ui64 testerTablet = MakeDefaultHiveID(1);
CreateTestBootstrapper(runtime, CreateTestTabletInfo(hiveTablet, TTabletTypes::FLAT_HIVE), &CreateDefaultHive);
- {
- TDispatchOptions options;
- options.FinalEvents.emplace_back(TEvLocal::EvSyncTablets, runtime.GetNodeCount());
- runtime.DispatchEvents(options);
- }
- TTabletTypes::EType tabletType = TTabletTypes::Dummy;
- THolder<TEvHive::TEvCreateTablet> ev(new TEvHive::TEvCreateTablet(testerTablet, 100500, tabletType, BINDED_CHANNELS));
+ {
+ TDispatchOptions options;
+ options.FinalEvents.emplace_back(TEvLocal::EvSyncTablets, runtime.GetNodeCount());
+ runtime.DispatchEvents(options);
+ }
+ TTabletTypes::EType tabletType = TTabletTypes::Dummy;
+ THolder<TEvHive::TEvCreateTablet> ev(new TEvHive::TEvCreateTablet(testerTablet, 100500, tabletType, BINDED_CHANNELS));
auto* followerGroup = ev->Record.AddFollowerGroups();
followerGroup->SetFollowerCount(2);
followerGroup->SetAllowLeaderPromotion(true);
-
+
ui64 tabletId = SendCreateTestTablet(runtime, hiveTablet, testerTablet, std::move(ev), 0, true);
-
- NTabletPipe::TClientConfig pipeConfig;
- pipeConfig.RetryPolicy = NTabletPipe::TClientRetryPolicy::WithRetries();
- pipeConfig.ForceLocal = true;
+
+ NTabletPipe::TClientConfig pipeConfig;
+ pipeConfig.RetryPolicy = NTabletPipe::TClientRetryPolicy::WithRetries();
+ pipeConfig.ForceLocal = true;
pipeConfig.AllowFollower = true;
- std::array<bool, NODES> tabletRolesBefore = {};
- for (int i = 0; i < NODES; ++i) {
- MakeSureTabletIsUp(runtime, tabletId, i, &pipeConfig, &tabletRolesBefore[i]);
- }
+ std::array<bool, NODES> tabletRolesBefore = {};
+ for (int i = 0; i < NODES; ++i) {
+ MakeSureTabletIsUp(runtime, tabletId, i, &pipeConfig, &tabletRolesBefore[i]);
+ }
int leaders = std::accumulate(tabletRolesBefore.begin(), tabletRolesBefore.end(), 0, [](int a, bool b) -> int { return b ? a + 1 : a; });
UNIT_ASSERT_VALUES_EQUAL(leaders, 1);
int leaderNode = std::find(tabletRolesBefore.begin(), tabletRolesBefore.end(), true) - tabletRolesBefore.begin();
// killing leader
SendKillLocal(runtime, leaderNode);
- {
- TDispatchOptions options;
+ {
+ TDispatchOptions options;
options.FinalEvents.emplace_back(TEvLocal::EvTabletStatus);
- runtime.DispatchEvents(options);
- }
- std::array<bool, NODES> tabletRolesIntermediate = {};
- for (int i = 0; i < NODES; ++i) {
+ runtime.DispatchEvents(options);
+ }
+ std::array<bool, NODES> tabletRolesIntermediate = {};
+ for (int i = 0; i < NODES; ++i) {
if (i != leaderNode) {
- MakeSureTabletIsUp(runtime, tabletId, i, &pipeConfig, &tabletRolesIntermediate[i]);
- } else {
- tabletRolesIntermediate[i] = false;
- }
- }
+ MakeSureTabletIsUp(runtime, tabletId, i, &pipeConfig, &tabletRolesIntermediate[i]);
+ } else {
+ tabletRolesIntermediate[i] = false;
+ }
+ }
leaders = std::accumulate(tabletRolesIntermediate.begin(), tabletRolesIntermediate.end(), 0, [](int a, bool b) -> int { return b ? a + 1 : a; });
int followers = std::accumulate(tabletRolesIntermediate.begin(), tabletRolesIntermediate.end(), 0, [](int a, bool b) -> int { return b ? a : a + 1; });
UNIT_ASSERT_VALUES_EQUAL(leaders, 1);
UNIT_ASSERT_VALUES_EQUAL(followers, 2);
std::unordered_set<std::pair<TTabletId, TFollowerId>> activeTablets;
- TActorId senderA = runtime.AllocateEdgeActor();
- for (int i = 0; i < NODES; ++i) {
- TActorId whiteboard = NNodeWhiteboard::MakeNodeWhiteboardServiceId(runtime.GetNodeId(i));
- runtime.Send(new IEventHandle(whiteboard, senderA, new NNodeWhiteboard::TEvWhiteboard::TEvTabletStateRequest()));
- TAutoPtr<IEventHandle> handle;
- NNodeWhiteboard::TEvWhiteboard::TEvTabletStateResponse* response = runtime.GrabEdgeEventRethrow<NNodeWhiteboard::TEvWhiteboard::TEvTabletStateResponse>(handle);
- for (const NKikimrWhiteboard::TTabletStateInfo& tabletInfo : response->Record.GetTabletStateInfo()) {
+ TActorId senderA = runtime.AllocateEdgeActor();
+ for (int i = 0; i < NODES; ++i) {
+ TActorId whiteboard = NNodeWhiteboard::MakeNodeWhiteboardServiceId(runtime.GetNodeId(i));
+ runtime.Send(new IEventHandle(whiteboard, senderA, new NNodeWhiteboard::TEvWhiteboard::TEvTabletStateRequest()));
+ TAutoPtr<IEventHandle> handle;
+ NNodeWhiteboard::TEvWhiteboard::TEvTabletStateResponse* response = runtime.GrabEdgeEventRethrow<NNodeWhiteboard::TEvWhiteboard::TEvTabletStateResponse>(handle);
+ for (const NKikimrWhiteboard::TTabletStateInfo& tabletInfo : response->Record.GetTabletStateInfo()) {
if (tabletInfo.GetTabletId() == tabletId && (
tabletInfo.GetState() == NKikimrWhiteboard::TTabletStateInfo::Active ||
tabletInfo.GetState() == NKikimrWhiteboard::TTabletStateInfo::ResolveLeader))
{
activeTablets.insert({tabletInfo.GetTabletId(), tabletInfo.GetFollowerId()});
- }
- }
- }
- UNIT_ASSERT_VALUES_EQUAL(activeTablets.size(), 3);
- }
-
+ }
+ }
+ }
+ UNIT_ASSERT_VALUES_EQUAL(activeTablets.size(), 3);
+ }
+
Y_UNIT_TEST(TestManyFollowersOnOneNode) {
TTestBasicRuntime runtime(2, false);
- Setup(runtime, true);
- const int nodeBase = runtime.GetNodeId(0);
+ Setup(runtime, true);
+ const int nodeBase = runtime.GetNodeId(0);
TVector<ui64> tabletIds;
TActorId senderA = runtime.AllocateEdgeActor();
- const ui64 hiveTablet = MakeDefaultHiveID(0);
- const ui64 testerTablet = MakeDefaultHiveID(1);
+ const ui64 hiveTablet = MakeDefaultHiveID(0);
+ const ui64 testerTablet = MakeDefaultHiveID(1);
CreateTestBootstrapper(runtime, CreateTestTabletInfo(hiveTablet, TTabletTypes::FLAT_HIVE), &CreateDefaultHive);
- {
- TDispatchOptions options;
- options.FinalEvents.emplace_back(TEvLocal::EvSyncTablets, runtime.GetNodeCount());
- runtime.DispatchEvents(options);
- }
- TTabletTypes::EType tabletType = TTabletTypes::Dummy;
- THolder<TEvHive::TEvCreateTablet> ev(new TEvHive::TEvCreateTablet(testerTablet, 100500, tabletType, BINDED_CHANNELS));
+ {
+ TDispatchOptions options;
+ options.FinalEvents.emplace_back(TEvLocal::EvSyncTablets, runtime.GetNodeCount());
+ runtime.DispatchEvents(options);
+ }
+ TTabletTypes::EType tabletType = TTabletTypes::Dummy;
+ THolder<TEvHive::TEvCreateTablet> ev(new TEvHive::TEvCreateTablet(testerTablet, 100500, tabletType, BINDED_CHANNELS));
auto* followerGroup = ev->Record.AddFollowerGroups();
followerGroup->SetFollowerCount(3);
followerGroup->SetAllowLeaderPromotion(true);
SendCreateTestTablet(runtime, hiveTablet, testerTablet, std::move(ev), 0, false);
- {
- TDispatchOptions options;
+ {
+ TDispatchOptions options;
options.FinalEvents.emplace_back(TEvLocal::EvTabletStatus, 4);
- runtime.DispatchEvents(options);
- }
- // checking distribution, should be equal number of tablets on every node
- {
- std::array<int, 2> nodeTablets = {};
- {
- runtime.SendToPipe(hiveTablet, senderA, new TEvHive::TEvRequestHiveInfo(true));
- TAutoPtr<IEventHandle> handle;
- TEvHive::TEvResponseHiveInfo* response = runtime.GrabEdgeEventRethrow<TEvHive::TEvResponseHiveInfo>(handle);
- for (const NKikimrHive::TTabletInfo& tablet : response->Record.GetTablets()) {
+ runtime.DispatchEvents(options);
+ }
+ // checking distribution, should be equal number of tablets on every node
+ {
+ std::array<int, 2> nodeTablets = {};
+ {
+ runtime.SendToPipe(hiveTablet, senderA, new TEvHive::TEvRequestHiveInfo(true));
+ TAutoPtr<IEventHandle> handle;
+ TEvHive::TEvResponseHiveInfo* response = runtime.GrabEdgeEventRethrow<TEvHive::TEvResponseHiveInfo>(handle);
+ for (const NKikimrHive::TTabletInfo& tablet : response->Record.GetTablets()) {
UNIT_ASSERT_C(((int)tablet.GetNodeID() - nodeBase >= 0) && (tablet.GetNodeID() - nodeBase < 2),
"nodeId# " << tablet.GetNodeID() << " nodeBase# " << nodeBase);
- nodeTablets[tablet.GetNodeID() - nodeBase]++;
- }
- }
- UNIT_ASSERT_VALUES_EQUAL(nodeTablets[0], 2);
- UNIT_ASSERT_VALUES_EQUAL(nodeTablets[1], 2);
- }
- }
-
+ nodeTablets[tablet.GetNodeID() - nodeBase]++;
+ }
+ }
+ UNIT_ASSERT_VALUES_EQUAL(nodeTablets[0], 2);
+ UNIT_ASSERT_VALUES_EQUAL(nodeTablets[1], 2);
+ }
+ }
+
Y_UNIT_TEST(TestStartTabletTwiceInARow) {
TTestBasicRuntime runtime(1, false);
- Setup(runtime, true);
- const ui64 hiveTablet = MakeDefaultHiveID(0);
- const ui64 testerTablet = MakeDefaultHiveID(1);
+ Setup(runtime, true);
+ const ui64 hiveTablet = MakeDefaultHiveID(0);
+ const ui64 testerTablet = MakeDefaultHiveID(1);
CreateTestBootstrapper(runtime, CreateTestTabletInfo(hiveTablet, TTabletTypes::FLAT_HIVE), &CreateDefaultHive);
-
- TTabletTypes::EType tabletType = TTabletTypes::Dummy;
+
+ TTabletTypes::EType tabletType = TTabletTypes::Dummy;
ui64 tabletId = SendCreateTestTablet(runtime, hiveTablet, testerTablet, MakeHolder<TEvHive::TEvCreateTablet>(testerTablet, 0, tabletType, BINDED_CHANNELS), 0, false);
- SendKillLocal(runtime, 0);
- CreateLocal(runtime, 0);
- {
- TDispatchOptions options;
- options.FinalEvents.emplace_back(TEvLocal::EvBootTablet);
- runtime.DispatchEvents(options);
- }
- SendKillLocal(runtime, 0);
- CreateLocal(runtime, 0);
- {
- TDispatchOptions options;
- options.FinalEvents.emplace_back(TEvLocal::EvBootTablet);
- runtime.DispatchEvents(options);
- }
- Y_UNUSED(tabletId);
- }
-
+ SendKillLocal(runtime, 0);
+ CreateLocal(runtime, 0);
+ {
+ TDispatchOptions options;
+ options.FinalEvents.emplace_back(TEvLocal::EvBootTablet);
+ runtime.DispatchEvents(options);
+ }
+ SendKillLocal(runtime, 0);
+ CreateLocal(runtime, 0);
+ {
+ TDispatchOptions options;
+ options.FinalEvents.emplace_back(TEvLocal::EvBootTablet);
+ runtime.DispatchEvents(options);
+ }
+ Y_UNUSED(tabletId);
+ }
+
Y_UNIT_TEST(TestHiveBalancer) {
- static const int NUM_NODES = 3;
- static const int NUM_TABLETS = NUM_NODES * 3;
+ static const int NUM_NODES = 3;
+ static const int NUM_TABLETS = NUM_NODES * 3;
TTestBasicRuntime runtime(NUM_NODES, false);
- Setup(runtime, true);
+ Setup(runtime, true);
const int nodeBase = runtime.GetNodeId(0);
TActorId senderA = runtime.AllocateEdgeActor();
- const ui64 hiveTablet = MakeDefaultHiveID(0);
- const ui64 testerTablet = MakeDefaultHiveID(1);
+ const ui64 hiveTablet = MakeDefaultHiveID(0);
+ const ui64 testerTablet = MakeDefaultHiveID(1);
CreateTestBootstrapper(runtime, CreateTestTabletInfo(hiveTablet, TTabletTypes::FLAT_HIVE), &CreateDefaultHive);
- {
- TDispatchOptions options;
- options.FinalEvents.emplace_back(TEvLocal::EvStatus, NUM_NODES);
- runtime.DispatchEvents(options);
- }
- for (int nodeIdx = 0; nodeIdx < NUM_NODES; ++nodeIdx) {
+ {
+ TDispatchOptions options;
+ options.FinalEvents.emplace_back(TEvLocal::EvStatus, NUM_NODES);
+ runtime.DispatchEvents(options);
+ }
+ for (int nodeIdx = 0; nodeIdx < NUM_NODES; ++nodeIdx) {
TActorId senderLocal = runtime.AllocateEdgeActor(nodeIdx);
THolder<TEvHive::TEvTabletMetrics> ev = MakeHolder<TEvHive::TEvTabletMetrics>();
- ev->Record.MutableTotalResourceUsage()->SetCPU(999); // KIKIMR-9870
- runtime.SendToPipe(hiveTablet, senderLocal, ev.Release(), nodeIdx, GetPipeConfigWithRetries());
- TAutoPtr<IEventHandle> handle;
- TEvLocal::TEvTabletMetricsAck* response = runtime.GrabEdgeEvent<TEvLocal::TEvTabletMetricsAck>(handle);
- Y_UNUSED(response);
- }
-
- // creating NUM_TABLETS tablets
- TTabletTypes::EType tabletType = TTabletTypes::Dummy;
+ ev->Record.MutableTotalResourceUsage()->SetCPU(999); // KIKIMR-9870
+ runtime.SendToPipe(hiveTablet, senderLocal, ev.Release(), nodeIdx, GetPipeConfigWithRetries());
+ TAutoPtr<IEventHandle> handle;
+ TEvLocal::TEvTabletMetricsAck* response = runtime.GrabEdgeEvent<TEvLocal::TEvTabletMetricsAck>(handle);
+ Y_UNUSED(response);
+ }
+
+ // creating NUM_TABLETS tablets
+ TTabletTypes::EType tabletType = TTabletTypes::Dummy;
TVector<ui64> tablets;
- for (int i = 0; i < NUM_TABLETS; ++i) {
- THolder<TEvHive::TEvCreateTablet> ev(new TEvHive::TEvCreateTablet(testerTablet, 100500 + i, tabletType, BINDED_CHANNELS));
- ev->Record.SetObjectId(i);
+ for (int i = 0; i < NUM_TABLETS; ++i) {
+ THolder<TEvHive::TEvCreateTablet> ev(new TEvHive::TEvCreateTablet(testerTablet, 100500 + i, tabletType, BINDED_CHANNELS));
+ ev->Record.SetObjectId(i);
ui64 tabletId = SendCreateTestTablet(runtime, hiveTablet, testerTablet, std::move(ev), 0, true);
- tablets.emplace_back(tabletId);
+ tablets.emplace_back(tabletId);
MakeSureTabletIsUp(runtime, tabletId, 0);
- }
-
- // checking distribution, should be equal number of tablets on every node
- {
- std::array<int, NUM_NODES> nodeTablets = {};
- {
- runtime.SendToPipe(hiveTablet, senderA, new TEvHive::TEvRequestHiveInfo());
- TAutoPtr<IEventHandle> handle;
- TEvHive::TEvResponseHiveInfo* response = runtime.GrabEdgeEventRethrow<TEvHive::TEvResponseHiveInfo>(handle);
- for (const NKikimrHive::TTabletInfo& tablet : response->Record.GetTablets()) {
+ }
+
+ // checking distribution, should be equal number of tablets on every node
+ {
+ std::array<int, NUM_NODES> nodeTablets = {};
+ {
+ runtime.SendToPipe(hiveTablet, senderA, new TEvHive::TEvRequestHiveInfo());
+ TAutoPtr<IEventHandle> handle;
+ TEvHive::TEvResponseHiveInfo* response = runtime.GrabEdgeEventRethrow<TEvHive::TEvResponseHiveInfo>(handle);
+ for (const NKikimrHive::TTabletInfo& tablet : response->Record.GetTablets()) {
UNIT_ASSERT_C(((int)tablet.GetNodeID() - nodeBase >= 0) && (tablet.GetNodeID() - nodeBase < NUM_NODES),
"nodeId# " << tablet.GetNodeID() << " nodeBase# " << nodeBase);
- nodeTablets[tablet.GetNodeID() - nodeBase]++;
- Ctest << "tablet " << tablet.GetTabletID() << " on node " << tablet.GetNodeID() << Endl;
- }
- }
- auto mmElements = std::minmax_element(nodeTablets.begin(), nodeTablets.end());
+ nodeTablets[tablet.GetNodeID() - nodeBase]++;
+ Ctest << "tablet " << tablet.GetTabletID() << " on node " << tablet.GetNodeID() << Endl;
+ }
+ }
+ auto mmElements = std::minmax_element(nodeTablets.begin(), nodeTablets.end());
UNIT_ASSERT_VALUES_EQUAL(mmElements.first, nodeTablets.begin());
UNIT_ASSERT_VALUES_EQUAL(mmElements.second, nodeTablets.end() - 1);
- }
-
- THashMap<ui64, ui64> tabletMetrics;
-
- // reporting uneven metrics for tablets
- {
- int i = 1;
- for (ui64 tabletId : tablets) {
+ }
+
+ THashMap<ui64, ui64> tabletMetrics;
+
+ // reporting uneven metrics for tablets
+ {
+ int i = 1;
+ for (ui64 tabletId : tablets) {
THolder<TEvHive::TEvTabletMetrics> metrics = MakeHolder<TEvHive::TEvTabletMetrics>();
- NKikimrHive::TTabletMetrics* metric = metrics->Record.AddTabletMetrics();
- metric->SetTabletID(tabletId);
- metric->MutableResourceUsage()->SetNetwork(100000 * i);
- tabletMetrics[tabletId] = 100000 * i;
- i *= 2;
- runtime.SendToPipe(hiveTablet, senderA, metrics.Release());
- TAutoPtr<IEventHandle> handle;
- runtime.GrabEdgeEventRethrow<TEvLocal::TEvTabletMetricsAck>(handle);
- }
- }
-
- // killing all tablets
- for (ui64 tabletId : tablets) {
- runtime.Register(CreateTabletKiller(tabletId));
+ NKikimrHive::TTabletMetrics* metric = metrics->Record.AddTabletMetrics();
+ metric->SetTabletID(tabletId);
+ metric->MutableResourceUsage()->SetNetwork(100000 * i);
+ tabletMetrics[tabletId] = 100000 * i;
+ i *= 2;
+ runtime.SendToPipe(hiveTablet, senderA, metrics.Release());
+ TAutoPtr<IEventHandle> handle;
+ runtime.GrabEdgeEventRethrow<TEvLocal::TEvTabletMetricsAck>(handle);
+ }
+ }
+
+ // killing all tablets
+ for (ui64 tabletId : tablets) {
+ runtime.Register(CreateTabletKiller(tabletId));
// wait for tablet to stop and start back up again
TDispatchOptions options;
options.FinalEvents.emplace_back(TEvLocal::EvTabletStatus, 2);
runtime.DispatchEvents(options);
- }
-
- // checking distribution, should be almost all tablets on one node and two other tablets on two other nodes (7,1,1)
- {
- std::array<int, NUM_NODES> nodeTablets = {};
- {
- runtime.SendToPipe(hiveTablet, senderA, new TEvHive::TEvRequestHiveInfo());
- TAutoPtr<IEventHandle> handle;
- TEvHive::TEvResponseHiveInfo* response = runtime.GrabEdgeEventRethrow<TEvHive::TEvResponseHiveInfo>(handle);
- for (const NKikimrHive::TTabletInfo& tablet : response->Record.GetTablets()) {
+ }
+
+ // checking distribution, should be almost all tablets on one node and two other tablets on two other nodes (7,1,1)
+ {
+ std::array<int, NUM_NODES> nodeTablets = {};
+ {
+ runtime.SendToPipe(hiveTablet, senderA, new TEvHive::TEvRequestHiveInfo());
+ TAutoPtr<IEventHandle> handle;
+ TEvHive::TEvResponseHiveInfo* response = runtime.GrabEdgeEventRethrow<TEvHive::TEvResponseHiveInfo>(handle);
+ for (const NKikimrHive::TTabletInfo& tablet : response->Record.GetTablets()) {
UNIT_ASSERT_C(((int)tablet.GetNodeID() - nodeBase >= 0) && (tablet.GetNodeID() - nodeBase < NUM_NODES),
"nodeId# " << tablet.GetNodeID() << " nodeBase# " << nodeBase);
- ui32 nodeId = tablet.GetNodeID() - nodeBase;
- nodeTablets[nodeId]++;
- }
- }
- auto mmElements = std::minmax_element(nodeTablets.begin(), nodeTablets.end());
+ ui32 nodeId = tablet.GetNodeID() - nodeBase;
+ nodeTablets[nodeId]++;
+ }
+ }
+ auto mmElements = std::minmax_element(nodeTablets.begin(), nodeTablets.end());
UNIT_ASSERT_VALUES_EQUAL(1, *mmElements.first);
UNIT_ASSERT_VALUES_EQUAL(7, *mmElements.second);
- }
-
- // creating NUM_TABLETS more tablets (with empty metrics)
- for (int i = 0; i < NUM_TABLETS; ++i) {
- THolder<TEvHive::TEvCreateTablet> ev(new TEvHive::TEvCreateTablet(testerTablet, 200500 + i, tabletType, BINDED_CHANNELS));
- ev->Record.SetObjectId(NUM_TABLETS + i);
+ }
+
+ // creating NUM_TABLETS more tablets (with empty metrics)
+ for (int i = 0; i < NUM_TABLETS; ++i) {
+ THolder<TEvHive::TEvCreateTablet> ev(new TEvHive::TEvCreateTablet(testerTablet, 200500 + i, tabletType, BINDED_CHANNELS));
+ ev->Record.SetObjectId(NUM_TABLETS + i);
ui64 tabletId = SendCreateTestTablet(runtime, hiveTablet, testerTablet, std::move(ev), 0, true);
- tablets.emplace_back(tabletId);
- }
-
+ tablets.emplace_back(tabletId);
+ }
+
// checking distribution, new tablets should go to less loaded nodes (7,6,5)
- {
- std::array<int, NUM_NODES> nodeTablets = {};
- {
- TEvHive::TEvRequestHiveInfo* request = new TEvHive::TEvRequestHiveInfo();
- request->Record.SetReturnMetrics(true);
- runtime.SendToPipe(hiveTablet, senderA, request);
- TAutoPtr<IEventHandle> handle;
- TEvHive::TEvResponseHiveInfo* response = runtime.GrabEdgeEventRethrow<TEvHive::TEvResponseHiveInfo>(handle);
- for (const NKikimrHive::TTabletInfo& tablet : response->Record.GetTablets()) {
+ {
+ std::array<int, NUM_NODES> nodeTablets = {};
+ {
+ TEvHive::TEvRequestHiveInfo* request = new TEvHive::TEvRequestHiveInfo();
+ request->Record.SetReturnMetrics(true);
+ runtime.SendToPipe(hiveTablet, senderA, request);
+ TAutoPtr<IEventHandle> handle;
+ TEvHive::TEvResponseHiveInfo* response = runtime.GrabEdgeEventRethrow<TEvHive::TEvResponseHiveInfo>(handle);
+ for (const NKikimrHive::TTabletInfo& tablet : response->Record.GetTablets()) {
UNIT_ASSERT_C(((int)tablet.GetNodeID() - nodeBase >= 0) && (tablet.GetNodeID() - nodeBase < NUM_NODES),
"nodeId# " << tablet.GetNodeID() << " nodeBase# " << nodeBase);
- ui32 nodeId = tablet.GetNodeID() - nodeBase;
- nodeTablets[nodeId]++;
- }
- }
- auto mmElements = std::minmax_element(nodeTablets.begin(), nodeTablets.end());
- UNIT_ASSERT_VALUES_EQUAL(2, *mmElements.first);
- UNIT_ASSERT_VALUES_EQUAL(11, *mmElements.second);
- }
- }
-
+ ui32 nodeId = tablet.GetNodeID() - nodeBase;
+ nodeTablets[nodeId]++;
+ }
+ }
+ auto mmElements = std::minmax_element(nodeTablets.begin(), nodeTablets.end());
+ UNIT_ASSERT_VALUES_EQUAL(2, *mmElements.first);
+ UNIT_ASSERT_VALUES_EQUAL(11, *mmElements.second);
+ }
+ }
+
TNodeLocation GetLocation(ui32 nodeId) {
NActorsInterconnect::TNodeLocation location;
location.SetDataCenter(ToString(nodeId / 2 + 1));
@@ -3014,836 +3014,836 @@ Y_UNIT_TEST_SUITE(THiveTest) {
return TNodeLocation(location); // DC = [1,1,2,2,3,3]
}
- Y_UNIT_TEST(TestHiveBalancerWithPrefferedDC1) {
- static const int NUM_NODES = 6;
- static const int NUM_TABLETS = NUM_NODES * 3;
- TTestBasicRuntime runtime(NUM_NODES, false);
-
+ Y_UNIT_TEST(TestHiveBalancerWithPrefferedDC1) {
+ static const int NUM_NODES = 6;
+ static const int NUM_TABLETS = NUM_NODES * 3;
+ TTestBasicRuntime runtime(NUM_NODES, false);
+
runtime.LocationCallback = GetLocation;
-
- Setup(runtime, true);
- const int nodeBase = runtime.GetNodeId(0);
- TActorId senderA = runtime.AllocateEdgeActor();
- const ui64 hiveTablet = MakeDefaultHiveID(0);
- const ui64 testerTablet = MakeDefaultHiveID(1);
+
+ Setup(runtime, true);
+ const int nodeBase = runtime.GetNodeId(0);
+ TActorId senderA = runtime.AllocateEdgeActor();
+ const ui64 hiveTablet = MakeDefaultHiveID(0);
+ const ui64 testerTablet = MakeDefaultHiveID(1);
CreateTestBootstrapper(runtime, CreateTestTabletInfo(hiveTablet, TTabletTypes::FLAT_HIVE), &CreateDefaultHive);
- {
- TDispatchOptions options;
- options.FinalEvents.emplace_back(TEvLocal::EvStatus, NUM_NODES);
- runtime.DispatchEvents(options);
- }
-
- // creating NUM_TABLETS tablets
- TTabletTypes::EType tabletType = TTabletTypes::Dummy;
- TVector<ui64> tablets;
- for (int i = 0; i < NUM_TABLETS; ++i) {
- THolder<TEvHive::TEvCreateTablet> ev(new TEvHive::TEvCreateTablet(testerTablet, 100500 + i, tabletType, BINDED_CHANNELS));
+ {
+ TDispatchOptions options;
+ options.FinalEvents.emplace_back(TEvLocal::EvStatus, NUM_NODES);
+ runtime.DispatchEvents(options);
+ }
+
+ // creating NUM_TABLETS tablets
+ TTabletTypes::EType tabletType = TTabletTypes::Dummy;
+ TVector<ui64> tablets;
+ for (int i = 0; i < NUM_TABLETS; ++i) {
+ THolder<TEvHive::TEvCreateTablet> ev(new TEvHive::TEvCreateTablet(testerTablet, 100500 + i, tabletType, BINDED_CHANNELS));
ev->Record.SetFollowerCount(3);
ev->Record.MutableDataCentersPreference()->AddDataCentersGroups()->AddDataCenter(ToString(1));
ev->Record.MutableDataCentersPreference()->AddDataCentersGroups()->AddDataCenter(ToString(2));
ui64 tabletId = SendCreateTestTablet(runtime, hiveTablet, testerTablet, std::move(ev), 0, true);
- tablets.emplace_back(tabletId);
- MakeSureTabletIsUp(runtime, tabletId, 0);
- }
-
+ tablets.emplace_back(tabletId);
+ MakeSureTabletIsUp(runtime, tabletId, 0);
+ }
+
// checking distribution, all leaders should be on the first node
- {
+ {
std::array<int, NUM_NODES> nodeLeaders = {};
- std::array<int, NUM_NODES> nodeTablets = {};
- {
- THolder<TEvHive::TEvRequestHiveInfo> request = MakeHolder<TEvHive::TEvRequestHiveInfo>();
+ std::array<int, NUM_NODES> nodeTablets = {};
+ {
+ THolder<TEvHive::TEvRequestHiveInfo> request = MakeHolder<TEvHive::TEvRequestHiveInfo>();
request->Record.SetReturnFollowers(true);
- runtime.SendToPipe(hiveTablet, senderA, request.Release());
- TAutoPtr<IEventHandle> handle;
- TEvHive::TEvResponseHiveInfo* response = runtime.GrabEdgeEventRethrow<TEvHive::TEvResponseHiveInfo>(handle);
- for (const NKikimrHive::TTabletInfo& tablet : response->Record.GetTablets()) {
+ runtime.SendToPipe(hiveTablet, senderA, request.Release());
+ TAutoPtr<IEventHandle> handle;
+ TEvHive::TEvResponseHiveInfo* response = runtime.GrabEdgeEventRethrow<TEvHive::TEvResponseHiveInfo>(handle);
+ for (const NKikimrHive::TTabletInfo& tablet : response->Record.GetTablets()) {
if (tablet.GetFollowerID() == 0) {
nodeLeaders[tablet.GetNodeID() - nodeBase]++;
- }
- nodeTablets[tablet.GetNodeID() - nodeBase]++;
+ }
+ nodeTablets[tablet.GetNodeID() - nodeBase]++;
Ctest << "tablet " << tablet.GetTabletID() << "." << tablet.GetFollowerID() << " on node " << tablet.GetNodeID() << Endl;
- }
- }
+ }
+ }
UNIT_ASSERT_GT(nodeLeaders[0], 0);
UNIT_ASSERT_GT(nodeLeaders[1], 0);
UNIT_ASSERT_VALUES_EQUAL(nodeLeaders[2], 0);
UNIT_ASSERT_VALUES_EQUAL(nodeLeaders[3], 0);
UNIT_ASSERT_VALUES_EQUAL(nodeLeaders[4], 0);
UNIT_ASSERT_VALUES_EQUAL(nodeLeaders[5], 0);
- UNIT_ASSERT_GT(nodeTablets[0], 0);
- UNIT_ASSERT_GT(nodeTablets[1], 0);
- UNIT_ASSERT_GT(nodeTablets[2], 0);
- UNIT_ASSERT_GT(nodeTablets[3], 0);
- UNIT_ASSERT_GT(nodeTablets[4], 0);
- UNIT_ASSERT_GT(nodeTablets[5], 0);
- }
- }
-
- Y_UNIT_TEST(TestHiveBalancerWithPrefferedDC2) {
- static const int NUM_NODES = 6;
- static const int NUM_TABLETS = NUM_NODES * 3;
- TTestBasicRuntime runtime(NUM_NODES, false);
-
+ UNIT_ASSERT_GT(nodeTablets[0], 0);
+ UNIT_ASSERT_GT(nodeTablets[1], 0);
+ UNIT_ASSERT_GT(nodeTablets[2], 0);
+ UNIT_ASSERT_GT(nodeTablets[3], 0);
+ UNIT_ASSERT_GT(nodeTablets[4], 0);
+ UNIT_ASSERT_GT(nodeTablets[5], 0);
+ }
+ }
+
+ Y_UNIT_TEST(TestHiveBalancerWithPrefferedDC2) {
+ static const int NUM_NODES = 6;
+ static const int NUM_TABLETS = NUM_NODES * 3;
+ TTestBasicRuntime runtime(NUM_NODES, false);
+
runtime.LocationCallback = GetLocation;
-
- Setup(runtime, true);
- const int nodeBase = runtime.GetNodeId(0);
- TActorId senderA = runtime.AllocateEdgeActor();
- const ui64 hiveTablet = MakeDefaultHiveID(0);
- const ui64 testerTablet = MakeDefaultHiveID(1);
+
+ Setup(runtime, true);
+ const int nodeBase = runtime.GetNodeId(0);
+ TActorId senderA = runtime.AllocateEdgeActor();
+ const ui64 hiveTablet = MakeDefaultHiveID(0);
+ const ui64 testerTablet = MakeDefaultHiveID(1);
CreateTestBootstrapper(runtime, CreateTestTabletInfo(hiveTablet, TTabletTypes::FLAT_HIVE), &CreateDefaultHive);
- {
- TDispatchOptions options;
- options.FinalEvents.emplace_back(TEvLocal::EvStatus, NUM_NODES);
- runtime.DispatchEvents(options);
- }
-
- // creating NUM_TABLETS tablets
- TTabletTypes::EType tabletType = TTabletTypes::Dummy;
- TVector<ui64> tablets;
- for (int i = 0; i < NUM_TABLETS; ++i) {
- THolder<TEvHive::TEvCreateTablet> ev(new TEvHive::TEvCreateTablet(testerTablet, 100500 + i, tabletType, BINDED_CHANNELS));
+ {
+ TDispatchOptions options;
+ options.FinalEvents.emplace_back(TEvLocal::EvStatus, NUM_NODES);
+ runtime.DispatchEvents(options);
+ }
+
+ // creating NUM_TABLETS tablets
+ TTabletTypes::EType tabletType = TTabletTypes::Dummy;
+ TVector<ui64> tablets;
+ for (int i = 0; i < NUM_TABLETS; ++i) {
+ THolder<TEvHive::TEvCreateTablet> ev(new TEvHive::TEvCreateTablet(testerTablet, 100500 + i, tabletType, BINDED_CHANNELS));
ev->Record.SetFollowerCount(3);
- auto* group = ev->Record.MutableDataCentersPreference()->AddDataCentersGroups();
+ auto* group = ev->Record.MutableDataCentersPreference()->AddDataCentersGroups();
group->AddDataCenter(ToString(1));
group->AddDataCenter(ToString(2));
ui64 tabletId = SendCreateTestTablet(runtime, hiveTablet, testerTablet, std::move(ev), 0, true);
- tablets.emplace_back(tabletId);
- MakeSureTabletIsUp(runtime, tabletId, 0);
- }
-
+ tablets.emplace_back(tabletId);
+ MakeSureTabletIsUp(runtime, tabletId, 0);
+ }
+
// checking distribution, all leaders should be on the first node
- {
+ {
std::array<int, NUM_NODES> nodeLeaders = {};
- std::array<int, NUM_NODES> nodeTablets = {};
- {
- THolder<TEvHive::TEvRequestHiveInfo> request = MakeHolder<TEvHive::TEvRequestHiveInfo>();
+ std::array<int, NUM_NODES> nodeTablets = {};
+ {
+ THolder<TEvHive::TEvRequestHiveInfo> request = MakeHolder<TEvHive::TEvRequestHiveInfo>();
request->Record.SetReturnFollowers(true);
- runtime.SendToPipe(hiveTablet, senderA, request.Release());
- TAutoPtr<IEventHandle> handle;
- TEvHive::TEvResponseHiveInfo* response = runtime.GrabEdgeEventRethrow<TEvHive::TEvResponseHiveInfo>(handle);
- for (const NKikimrHive::TTabletInfo& tablet : response->Record.GetTablets()) {
+ runtime.SendToPipe(hiveTablet, senderA, request.Release());
+ TAutoPtr<IEventHandle> handle;
+ TEvHive::TEvResponseHiveInfo* response = runtime.GrabEdgeEventRethrow<TEvHive::TEvResponseHiveInfo>(handle);
+ for (const NKikimrHive::TTabletInfo& tablet : response->Record.GetTablets()) {
if (tablet.GetFollowerID() == 0) {
nodeLeaders[tablet.GetNodeID() - nodeBase]++;
- }
- nodeTablets[tablet.GetNodeID() - nodeBase]++;
+ }
+ nodeTablets[tablet.GetNodeID() - nodeBase]++;
Ctest << "tablet " << tablet.GetTabletID() << "." << tablet.GetFollowerID() << " on node " << tablet.GetNodeID() << Endl;
- }
- }
+ }
+ }
UNIT_ASSERT_GT(nodeLeaders[0], 0);
UNIT_ASSERT_GT(nodeLeaders[1], 0);
UNIT_ASSERT_GT(nodeLeaders[2], 0);
UNIT_ASSERT_GT(nodeLeaders[3], 0);
UNIT_ASSERT_VALUES_EQUAL(nodeLeaders[4], 0);
UNIT_ASSERT_VALUES_EQUAL(nodeLeaders[5], 0);
- UNIT_ASSERT_GT(nodeTablets[0], 0);
- UNIT_ASSERT_GT(nodeTablets[1], 0);
- UNIT_ASSERT_GT(nodeTablets[2], 0);
- UNIT_ASSERT_GT(nodeTablets[3], 0);
- UNIT_ASSERT_GT(nodeTablets[4], 0);
- UNIT_ASSERT_GT(nodeTablets[5], 0);
- }
- }
-
- Y_UNIT_TEST(TestHiveBalancerWithSystemTablets) {
- static const int NUM_NODES = 6;
- static const int NUM_TABLETS = 12;
- TTestBasicRuntime runtime(NUM_NODES, false);
-
+ UNIT_ASSERT_GT(nodeTablets[0], 0);
+ UNIT_ASSERT_GT(nodeTablets[1], 0);
+ UNIT_ASSERT_GT(nodeTablets[2], 0);
+ UNIT_ASSERT_GT(nodeTablets[3], 0);
+ UNIT_ASSERT_GT(nodeTablets[4], 0);
+ UNIT_ASSERT_GT(nodeTablets[5], 0);
+ }
+ }
+
+ Y_UNIT_TEST(TestHiveBalancerWithSystemTablets) {
+ static const int NUM_NODES = 6;
+ static const int NUM_TABLETS = 12;
+ TTestBasicRuntime runtime(NUM_NODES, false);
+
runtime.LocationCallback = GetLocation;
-
- Setup(runtime, true);
- const int nodeBase = runtime.GetNodeId(0);
- TActorId senderA = runtime.AllocateEdgeActor();
- const ui64 hiveTablet = MakeDefaultHiveID(0);
- const ui64 testerTablet = MakeDefaultHiveID(1);
+
+ Setup(runtime, true);
+ const int nodeBase = runtime.GetNodeId(0);
+ TActorId senderA = runtime.AllocateEdgeActor();
+ const ui64 hiveTablet = MakeDefaultHiveID(0);
+ const ui64 testerTablet = MakeDefaultHiveID(1);
CreateTestBootstrapper(runtime, CreateTestTabletInfo(hiveTablet, TTabletTypes::FLAT_HIVE), &CreateDefaultHive);
- {
- TDispatchOptions options;
- options.FinalEvents.emplace_back(TEvLocal::EvStatus, NUM_NODES);
- runtime.DispatchEvents(options);
- }
-
- // creating NUM_TABLETS tablets
- TTabletTypes::EType tabletType = TTabletTypes::Mediator;
- TVector<ui64> tablets;
- for (int i = 0; i < NUM_TABLETS; ++i) {
- THolder<TEvHive::TEvCreateTablet> ev(new TEvHive::TEvCreateTablet(testerTablet, 100500 + i, tabletType, BINDED_CHANNELS));
+ {
+ TDispatchOptions options;
+ options.FinalEvents.emplace_back(TEvLocal::EvStatus, NUM_NODES);
+ runtime.DispatchEvents(options);
+ }
+
+ // creating NUM_TABLETS tablets
+ TTabletTypes::EType tabletType = TTabletTypes::Mediator;
+ TVector<ui64> tablets;
+ for (int i = 0; i < NUM_TABLETS; ++i) {
+ THolder<TEvHive::TEvCreateTablet> ev(new TEvHive::TEvCreateTablet(testerTablet, 100500 + i, tabletType, BINDED_CHANNELS));
ui64 tabletId = SendCreateTestTablet(runtime, hiveTablet, testerTablet, std::move(ev), 0, true);
- tablets.emplace_back(tabletId);
- MakeSureTabletIsUp(runtime, tabletId, 0);
- }
-
+ tablets.emplace_back(tabletId);
+ MakeSureTabletIsUp(runtime, tabletId, 0);
+ }
+
// checking distribution, all leaders should be on the first node
- {
+ {
std::unordered_map<TString, ui64> dcTablets;
- {
- THolder<TEvHive::TEvRequestHiveInfo> request = MakeHolder<TEvHive::TEvRequestHiveInfo>();
- runtime.SendToPipe(hiveTablet, senderA, request.Release());
- TAutoPtr<IEventHandle> handle;
- TEvHive::TEvResponseHiveInfo* response = runtime.GrabEdgeEventRethrow<TEvHive::TEvResponseHiveInfo>(handle);
- for (const NKikimrHive::TTabletInfo& tablet : response->Record.GetTablets()) {
+ {
+ THolder<TEvHive::TEvRequestHiveInfo> request = MakeHolder<TEvHive::TEvRequestHiveInfo>();
+ runtime.SendToPipe(hiveTablet, senderA, request.Release());
+ TAutoPtr<IEventHandle> handle;
+ TEvHive::TEvResponseHiveInfo* response = runtime.GrabEdgeEventRethrow<TEvHive::TEvResponseHiveInfo>(handle);
+ for (const NKikimrHive::TTabletInfo& tablet : response->Record.GetTablets()) {
dcTablets[runtime.LocationCallback(tablet.GetNodeID() - nodeBase).GetDataCenterId()]++;
Ctest << "tablet " << tablet.GetTabletID() << "." << tablet.GetFollowerID() << " on node " << tablet.GetNodeID()
<< " on DC " << runtime.LocationCallback(tablet.GetNodeID() - nodeBase).GetDataCenterId() << Endl;
- }
- }
- UNIT_ASSERT_VALUES_EQUAL(dcTablets.size(), 1);
- UNIT_ASSERT_VALUES_EQUAL(dcTablets.begin()->second, NUM_TABLETS);
- }
- }
-
+ }
+ }
+ UNIT_ASSERT_VALUES_EQUAL(dcTablets.size(), 1);
+ UNIT_ASSERT_VALUES_EQUAL(dcTablets.begin()->second, NUM_TABLETS);
+ }
+ }
+
Y_UNIT_TEST(TestHiveBalancerWithFollowers) {
- static const int NUM_NODES = 8;
- static const int NUM_TABLETS = 24;
- TTestBasicRuntime runtime(NUM_NODES, false);
- Setup(runtime, true);
- const int nodeBase = runtime.GetNodeId(0);
+ static const int NUM_NODES = 8;
+ static const int NUM_TABLETS = 24;
+ TTestBasicRuntime runtime(NUM_NODES, false);
+ Setup(runtime, true);
+ const int nodeBase = runtime.GetNodeId(0);
TActorId senderA = runtime.AllocateEdgeActor();
- const ui64 hiveTablet = MakeDefaultHiveID(0);
- const ui64 testerTablet = MakeDefaultHiveID(1);
+ const ui64 hiveTablet = MakeDefaultHiveID(0);
+ const ui64 testerTablet = MakeDefaultHiveID(1);
CreateTestBootstrapper(runtime, CreateTestTabletInfo(hiveTablet, TTabletTypes::FLAT_HIVE), &CreateDefaultHive);
- MakeSureTabletIsUp(runtime, hiveTablet, 0);
-
- // create NUM_TABLETS tablets
- TTabletTypes::EType tabletType = TTabletTypes::Dummy;
- TVector<ui64> tablets;
- for (int i = 0; i < NUM_TABLETS; ++i) {
- THolder<TEvHive::TEvCreateTablet> ev(new TEvHive::TEvCreateTablet(testerTablet, 100500 + i, tabletType, BINDED_CHANNELS));
- ev->Record.SetObjectId(1);
+ MakeSureTabletIsUp(runtime, hiveTablet, 0);
+
+ // create NUM_TABLETS tablets
+ TTabletTypes::EType tabletType = TTabletTypes::Dummy;
+ TVector<ui64> tablets;
+ for (int i = 0; i < NUM_TABLETS; ++i) {
+ THolder<TEvHive::TEvCreateTablet> ev(new TEvHive::TEvCreateTablet(testerTablet, 100500 + i, tabletType, BINDED_CHANNELS));
+ ev->Record.SetObjectId(1);
ev->Record.SetFollowerCount(3);
ui64 tabletId = SendCreateTestTablet(runtime, hiveTablet, testerTablet, std::move(ev), 0, true);
- tablets.emplace_back(tabletId);
- MakeSureTabletIsUp(runtime, tabletId, 0);
- }
-
+ tablets.emplace_back(tabletId);
+ MakeSureTabletIsUp(runtime, tabletId, 0);
+ }
+
// check leader distribution, should be equal number of tablets on every node
- {
- std::array<int, NUM_NODES> nodeTablets = {};
- {
+ {
+ std::array<int, NUM_NODES> nodeTablets = {};
+ {
THolder<TEvHive::TEvRequestHiveInfo> request = MakeHolder<TEvHive::TEvRequestHiveInfo>();
- runtime.SendToPipe(hiveTablet, senderA, request.Release());
- TAutoPtr<IEventHandle> handle;
- TEvHive::TEvResponseHiveInfo* response = runtime.GrabEdgeEventRethrow<TEvHive::TEvResponseHiveInfo>(handle);
- for (const NKikimrHive::TTabletInfo& tablet : response->Record.GetTablets()) {
- Ctest << tablet.ShortDebugString() << Endl;
- UNIT_ASSERT_C(((int)tablet.GetNodeID() - nodeBase >= 0) && (tablet.GetNodeID() - nodeBase < NUM_NODES),
- "nodeId# " << tablet.GetNodeID() << " nodeBase# " << nodeBase);
- nodeTablets[tablet.GetNodeID() - nodeBase]++;
- }
- }
- auto mmElements = std::minmax_element(nodeTablets.begin(), nodeTablets.end());
- UNIT_ASSERT_VALUES_EQUAL(mmElements.first, nodeTablets.begin());
- UNIT_ASSERT_VALUES_EQUAL(mmElements.second, nodeTablets.end() - 1);
- }
-
- // check total distribution, should be equal number of tablets on every node
- {
- std::array<int, NUM_NODES> nodeTablets = {};
- {
+ runtime.SendToPipe(hiveTablet, senderA, request.Release());
+ TAutoPtr<IEventHandle> handle;
+ TEvHive::TEvResponseHiveInfo* response = runtime.GrabEdgeEventRethrow<TEvHive::TEvResponseHiveInfo>(handle);
+ for (const NKikimrHive::TTabletInfo& tablet : response->Record.GetTablets()) {
+ Ctest << tablet.ShortDebugString() << Endl;
+ UNIT_ASSERT_C(((int)tablet.GetNodeID() - nodeBase >= 0) && (tablet.GetNodeID() - nodeBase < NUM_NODES),
+ "nodeId# " << tablet.GetNodeID() << " nodeBase# " << nodeBase);
+ nodeTablets[tablet.GetNodeID() - nodeBase]++;
+ }
+ }
+ auto mmElements = std::minmax_element(nodeTablets.begin(), nodeTablets.end());
+ UNIT_ASSERT_VALUES_EQUAL(mmElements.first, nodeTablets.begin());
+ UNIT_ASSERT_VALUES_EQUAL(mmElements.second, nodeTablets.end() - 1);
+ }
+
+ // check total distribution, should be equal number of tablets on every node
+ {
+ std::array<int, NUM_NODES> nodeTablets = {};
+ {
THolder<TEvHive::TEvRequestHiveInfo> request = MakeHolder<TEvHive::TEvRequestHiveInfo>();
request->Record.SetReturnFollowers(true);
- runtime.SendToPipe(hiveTablet, senderA, request.Release());
- TAutoPtr<IEventHandle> handle;
- TEvHive::TEvResponseHiveInfo* response = runtime.GrabEdgeEventRethrow<TEvHive::TEvResponseHiveInfo>(handle);
- for (const NKikimrHive::TTabletInfo& tablet : response->Record.GetTablets()) {
- Ctest << tablet.ShortDebugString() << Endl;
- UNIT_ASSERT_C(((int)tablet.GetNodeID() - nodeBase >= 0) && (tablet.GetNodeID() - nodeBase < NUM_NODES),
- "nodeId# " << tablet.GetNodeID() << " nodeBase# " << nodeBase);
- nodeTablets[tablet.GetNodeID() - nodeBase]++;
- }
- }
- auto mmElements = std::minmax_element(nodeTablets.begin(), nodeTablets.end());
- UNIT_ASSERT_VALUES_EQUAL(mmElements.first, nodeTablets.begin());
- UNIT_ASSERT_VALUES_EQUAL(mmElements.second, nodeTablets.end() - 1);
- }
-
- THashMap<ui64, ui64> tabletMetrics;
-
+ runtime.SendToPipe(hiveTablet, senderA, request.Release());
+ TAutoPtr<IEventHandle> handle;
+ TEvHive::TEvResponseHiveInfo* response = runtime.GrabEdgeEventRethrow<TEvHive::TEvResponseHiveInfo>(handle);
+ for (const NKikimrHive::TTabletInfo& tablet : response->Record.GetTablets()) {
+ Ctest << tablet.ShortDebugString() << Endl;
+ UNIT_ASSERT_C(((int)tablet.GetNodeID() - nodeBase >= 0) && (tablet.GetNodeID() - nodeBase < NUM_NODES),
+ "nodeId# " << tablet.GetNodeID() << " nodeBase# " << nodeBase);
+ nodeTablets[tablet.GetNodeID() - nodeBase]++;
+ }
+ }
+ auto mmElements = std::minmax_element(nodeTablets.begin(), nodeTablets.end());
+ UNIT_ASSERT_VALUES_EQUAL(mmElements.first, nodeTablets.begin());
+ UNIT_ASSERT_VALUES_EQUAL(mmElements.second, nodeTablets.end() - 1);
+ }
+
+ THashMap<ui64, ui64> tabletMetrics;
+
// report metrics for leaders only
- {
- for (ui64 tabletId : tablets) {
+ {
+ for (ui64 tabletId : tablets) {
THolder<TEvHive::TEvTabletMetrics> metrics = MakeHolder<TEvHive::TEvTabletMetrics>();
- NKikimrHive::TTabletMetrics* metric = metrics->Record.AddTabletMetrics();
- metric->SetTabletID(tabletId);
- metric->MutableResourceUsage()->SetCPU(5000);
- runtime.SendToPipe(hiveTablet, senderA, metrics.Release());
- TAutoPtr<IEventHandle> handle;
- runtime.GrabEdgeEventRethrow<TEvLocal::TEvTabletMetricsAck>(handle);
- }
- }
-
- // kill all tablets
- for (ui64 tabletId : tablets) {
- runtime.Register(CreateTabletKiller(tabletId));
-
- // wait for tablet to stop and start back up again
- TDispatchOptions options;
- options.FinalEvents.emplace_back(TEvLocal::EvTabletStatus, 2);
- runtime.DispatchEvents(options);
- }
-
- // check distribution, should be equal number of tablets on every node
- {
- std::array<int, NUM_NODES> nodeTablets = {};
- {
- runtime.SendToPipe(hiveTablet, senderA, new TEvHive::TEvRequestHiveInfo());
- TAutoPtr<IEventHandle> handle;
- TEvHive::TEvResponseHiveInfo* response = runtime.GrabEdgeEventRethrow<TEvHive::TEvResponseHiveInfo>(handle);
- for (const NKikimrHive::TTabletInfo& tablet : response->Record.GetTablets()) {
- UNIT_ASSERT_C(((int)tablet.GetNodeID() - nodeBase >= 0) && (tablet.GetNodeID() - nodeBase < NUM_NODES),
- "nodeId# " << tablet.GetNodeID() << " nodeBase# " << nodeBase);
- nodeTablets[tablet.GetNodeID() - nodeBase]++;
- }
- }
- auto mmElements = std::minmax_element(nodeTablets.begin(), nodeTablets.end());
- UNIT_ASSERT_VALUES_EQUAL(mmElements.first, nodeTablets.begin());
- UNIT_ASSERT_VALUES_EQUAL(mmElements.second, nodeTablets.end() - 1);
- }
- }
-
- Y_UNIT_TEST(TestHiveBalancerWithLimit) {
- static const int NUM_NODES = 3;
- static const int NUM_TABLETS = NUM_NODES * 3;
- TTestBasicRuntime runtime(NUM_NODES, false);
- Setup(runtime, true);
- SendKillLocal(runtime, 0);
- SendKillLocal(runtime, 1);
- TLocalConfig::TPtr local0 = new TLocalConfig();
- {
+ NKikimrHive::TTabletMetrics* metric = metrics->Record.AddTabletMetrics();
+ metric->SetTabletID(tabletId);
+ metric->MutableResourceUsage()->SetCPU(5000);
+ runtime.SendToPipe(hiveTablet, senderA, metrics.Release());
+ TAutoPtr<IEventHandle> handle;
+ runtime.GrabEdgeEventRethrow<TEvLocal::TEvTabletMetricsAck>(handle);
+ }
+ }
+
+ // kill all tablets
+ for (ui64 tabletId : tablets) {
+ runtime.Register(CreateTabletKiller(tabletId));
+
+ // wait for tablet to stop and start back up again
+ TDispatchOptions options;
+ options.FinalEvents.emplace_back(TEvLocal::EvTabletStatus, 2);
+ runtime.DispatchEvents(options);
+ }
+
+ // check distribution, should be equal number of tablets on every node
+ {
+ std::array<int, NUM_NODES> nodeTablets = {};
+ {
+ runtime.SendToPipe(hiveTablet, senderA, new TEvHive::TEvRequestHiveInfo());
+ TAutoPtr<IEventHandle> handle;
+ TEvHive::TEvResponseHiveInfo* response = runtime.GrabEdgeEventRethrow<TEvHive::TEvResponseHiveInfo>(handle);
+ for (const NKikimrHive::TTabletInfo& tablet : response->Record.GetTablets()) {
+ UNIT_ASSERT_C(((int)tablet.GetNodeID() - nodeBase >= 0) && (tablet.GetNodeID() - nodeBase < NUM_NODES),
+ "nodeId# " << tablet.GetNodeID() << " nodeBase# " << nodeBase);
+ nodeTablets[tablet.GetNodeID() - nodeBase]++;
+ }
+ }
+ auto mmElements = std::minmax_element(nodeTablets.begin(), nodeTablets.end());
+ UNIT_ASSERT_VALUES_EQUAL(mmElements.first, nodeTablets.begin());
+ UNIT_ASSERT_VALUES_EQUAL(mmElements.second, nodeTablets.end() - 1);
+ }
+ }
+
+ Y_UNIT_TEST(TestHiveBalancerWithLimit) {
+ static const int NUM_NODES = 3;
+ static const int NUM_TABLETS = NUM_NODES * 3;
+ TTestBasicRuntime runtime(NUM_NODES, false);
+ Setup(runtime, true);
+ SendKillLocal(runtime, 0);
+ SendKillLocal(runtime, 1);
+ TLocalConfig::TPtr local0 = new TLocalConfig();
+ {
local0->TabletClassInfo[TTabletTypes::Dummy].SetupInfo = new TTabletSetupInfo(&CreateFlatDummyTablet,
- TMailboxType::Simple, 0,
- TMailboxType::Simple, 0);
- local0->TabletClassInfo[TTabletTypes::Dummy].MaxCount = 2;
- }
- CreateLocal(runtime, 0, local0); // max 2 dummies on 0
- TLocalConfig::TPtr local1 = new TLocalConfig();
- {
- // it can't be empty, otherwise it will fallback to default behavior
- local1->TabletClassInfo[TTabletTypes::Unknown].SetupInfo = nullptr;
- }
- CreateLocal(runtime, 1, local1); // no tablets on 1
- const int nodeBase = runtime.GetNodeId(0);
- TActorId senderA = runtime.AllocateEdgeActor();
- const ui64 hiveTablet = MakeDefaultHiveID(0);
- const ui64 testerTablet = MakeDefaultHiveID(1);
+ TMailboxType::Simple, 0,
+ TMailboxType::Simple, 0);
+ local0->TabletClassInfo[TTabletTypes::Dummy].MaxCount = 2;
+ }
+ CreateLocal(runtime, 0, local0); // max 2 dummies on 0
+ TLocalConfig::TPtr local1 = new TLocalConfig();
+ {
+ // it can't be empty, otherwise it will fallback to default behavior
+ local1->TabletClassInfo[TTabletTypes::Unknown].SetupInfo = nullptr;
+ }
+ CreateLocal(runtime, 1, local1); // no tablets on 1
+ const int nodeBase = runtime.GetNodeId(0);
+ TActorId senderA = runtime.AllocateEdgeActor();
+ const ui64 hiveTablet = MakeDefaultHiveID(0);
+ const ui64 testerTablet = MakeDefaultHiveID(1);
CreateTestBootstrapper(runtime, CreateTestTabletInfo(hiveTablet, TTabletTypes::FLAT_HIVE), &CreateDefaultHive);
- {
- TDispatchOptions options;
- options.FinalEvents.emplace_back(TEvLocal::EvStatus, NUM_NODES);
- runtime.DispatchEvents(options);
- }
- for (int nodeIdx = 0; nodeIdx < NUM_NODES; ++nodeIdx) {
- TActorId senderLocal = runtime.AllocateEdgeActor(nodeIdx);
- THolder<TEvHive::TEvTabletMetrics> ev = MakeHolder<TEvHive::TEvTabletMetrics>();
- ev->Record.MutableTotalResourceUsage()->SetCPU(999); // KIKIMR-9870
- runtime.SendToPipe(hiveTablet, senderLocal, ev.Release(), nodeIdx, GetPipeConfigWithRetries());
- TAutoPtr<IEventHandle> handle;
- TEvLocal::TEvTabletMetricsAck* response = runtime.GrabEdgeEvent<TEvLocal::TEvTabletMetricsAck>(handle);
- Y_UNUSED(response);
- }
-
- // creating NUM_TABLETS tablets
- TTabletTypes::EType tabletType = TTabletTypes::Dummy;
- TVector<ui64> tablets;
- for (int i = 0; i < NUM_TABLETS; ++i) {
- THolder<TEvHive::TEvCreateTablet> ev(new TEvHive::TEvCreateTablet(testerTablet, 100500 + i, tabletType, BINDED_CHANNELS));
- ev->Record.SetObjectId(i);
+ {
+ TDispatchOptions options;
+ options.FinalEvents.emplace_back(TEvLocal::EvStatus, NUM_NODES);
+ runtime.DispatchEvents(options);
+ }
+ for (int nodeIdx = 0; nodeIdx < NUM_NODES; ++nodeIdx) {
+ TActorId senderLocal = runtime.AllocateEdgeActor(nodeIdx);
+ THolder<TEvHive::TEvTabletMetrics> ev = MakeHolder<TEvHive::TEvTabletMetrics>();
+ ev->Record.MutableTotalResourceUsage()->SetCPU(999); // KIKIMR-9870
+ runtime.SendToPipe(hiveTablet, senderLocal, ev.Release(), nodeIdx, GetPipeConfigWithRetries());
+ TAutoPtr<IEventHandle> handle;
+ TEvLocal::TEvTabletMetricsAck* response = runtime.GrabEdgeEvent<TEvLocal::TEvTabletMetricsAck>(handle);
+ Y_UNUSED(response);
+ }
+
+ // creating NUM_TABLETS tablets
+ TTabletTypes::EType tabletType = TTabletTypes::Dummy;
+ TVector<ui64> tablets;
+ for (int i = 0; i < NUM_TABLETS; ++i) {
+ THolder<TEvHive::TEvCreateTablet> ev(new TEvHive::TEvCreateTablet(testerTablet, 100500 + i, tabletType, BINDED_CHANNELS));
+ ev->Record.SetObjectId(i);
ui64 tabletId = SendCreateTestTablet(runtime, hiveTablet, testerTablet, std::move(ev), 0, true);
- tablets.emplace_back(tabletId);
- MakeSureTabletIsUp(runtime, tabletId, 0);
- }
-
- // checking distribution, should be equal number of tablets on every node
- {
- std::array<int, NUM_NODES> nodeTablets = {};
- {
- runtime.SendToPipe(hiveTablet, senderA, new TEvHive::TEvRequestHiveInfo());
- TAutoPtr<IEventHandle> handle;
- TEvHive::TEvResponseHiveInfo* response = runtime.GrabEdgeEventRethrow<TEvHive::TEvResponseHiveInfo>(handle);
- for (const NKikimrHive::TTabletInfo& tablet : response->Record.GetTablets()) {
- UNIT_ASSERT_C(((int)tablet.GetNodeID() - nodeBase >= 0) && (tablet.GetNodeID() - nodeBase < NUM_NODES),
- "nodeId# " << tablet.GetNodeID() << " nodeBase# " << nodeBase);
- nodeTablets[tablet.GetNodeID() - nodeBase]++;
- }
- }
- UNIT_ASSERT_VALUES_EQUAL(nodeTablets[0], 2);
- UNIT_ASSERT_VALUES_EQUAL(nodeTablets[1], 0);
- UNIT_ASSERT_VALUES_EQUAL(nodeTablets[2], NUM_TABLETS - 2);
- }
- }
-
+ tablets.emplace_back(tabletId);
+ MakeSureTabletIsUp(runtime, tabletId, 0);
+ }
+
+ // checking distribution, should be equal number of tablets on every node
+ {
+ std::array<int, NUM_NODES> nodeTablets = {};
+ {
+ runtime.SendToPipe(hiveTablet, senderA, new TEvHive::TEvRequestHiveInfo());
+ TAutoPtr<IEventHandle> handle;
+ TEvHive::TEvResponseHiveInfo* response = runtime.GrabEdgeEventRethrow<TEvHive::TEvResponseHiveInfo>(handle);
+ for (const NKikimrHive::TTabletInfo& tablet : response->Record.GetTablets()) {
+ UNIT_ASSERT_C(((int)tablet.GetNodeID() - nodeBase >= 0) && (tablet.GetNodeID() - nodeBase < NUM_NODES),
+ "nodeId# " << tablet.GetNodeID() << " nodeBase# " << nodeBase);
+ nodeTablets[tablet.GetNodeID() - nodeBase]++;
+ }
+ }
+ UNIT_ASSERT_VALUES_EQUAL(nodeTablets[0], 2);
+ UNIT_ASSERT_VALUES_EQUAL(nodeTablets[1], 0);
+ UNIT_ASSERT_VALUES_EQUAL(nodeTablets[2], NUM_TABLETS - 2);
+ }
+ }
+
Y_UNIT_TEST(TestRestartTablets) {
TTestBasicRuntime runtime(3, false);
- Setup(runtime, true);
+ Setup(runtime, true);
TVector<ui64> tabletIds;
- const ui64 hiveTablet = MakeDefaultHiveID(0);
- const ui64 testerTablet = MakeDefaultHiveID(1);
+ const ui64 hiveTablet = MakeDefaultHiveID(0);
+ const ui64 testerTablet = MakeDefaultHiveID(1);
CreateTestBootstrapper(runtime, CreateTestTabletInfo(hiveTablet, TTabletTypes::FLAT_HIVE), &CreateDefaultHive);
- {
- TDispatchOptions options;
- options.FinalEvents.emplace_back(TEvLocal::EvSyncTablets, runtime.GetNodeCount());
- runtime.DispatchEvents(options);
- }
- TTabletTypes::EType tabletType = TTabletTypes::Dummy;
- THolder<TEvHive::TEvCreateTablet> ev(new TEvHive::TEvCreateTablet(testerTablet, 100500, tabletType, BINDED_CHANNELS));
+ {
+ TDispatchOptions options;
+ options.FinalEvents.emplace_back(TEvLocal::EvSyncTablets, runtime.GetNodeCount());
+ runtime.DispatchEvents(options);
+ }
+ TTabletTypes::EType tabletType = TTabletTypes::Dummy;
+ THolder<TEvHive::TEvCreateTablet> ev(new TEvHive::TEvCreateTablet(testerTablet, 100500, tabletType, BINDED_CHANNELS));
ev->Record.SetAllowFollowerPromotion(false);
ev->Record.SetFollowerCount(2);
ui64 tabletId = SendCreateTestTablet(runtime, hiveTablet, testerTablet, std::move(ev), 0, false);
-
- WaitForTabletsBecomeActive(runtime, 3);
-
- NTabletPipe::TClientConfig pipeConfig;
- pipeConfig.RetryPolicy = NTabletPipe::TClientRetryPolicy::WithRetries();
- pipeConfig.ForceLocal = true;
+
+ WaitForTabletsBecomeActive(runtime, 3);
+
+ NTabletPipe::TClientConfig pipeConfig;
+ pipeConfig.RetryPolicy = NTabletPipe::TClientRetryPolicy::WithRetries();
+ pipeConfig.ForceLocal = true;
pipeConfig.AllowFollower = true;
-
- WaitForTabletIsUp(runtime, tabletId, 0, &pipeConfig);
- WaitForTabletIsUp(runtime, tabletId, 1, &pipeConfig);
- WaitForTabletIsUp(runtime, tabletId, 2, &pipeConfig);
-
- runtime.Register(CreateTabletKiller(tabletId, runtime.GetNodeId(0)));
- {
- TDispatchOptions options;
- options.FinalEvents.emplace_back(TEvLocal::EvDeadTabletAck);
- runtime.DispatchEvents(options);
- }
-
- WaitForTabletIsUp(runtime, tabletId, 0, &pipeConfig);
- WaitForTabletIsUp(runtime, tabletId, 1, &pipeConfig);
- WaitForTabletIsUp(runtime, tabletId, 2, &pipeConfig);
-
- runtime.Register(CreateTabletKiller(tabletId, runtime.GetNodeId(1)));
- {
- TDispatchOptions options;
- options.FinalEvents.emplace_back(TEvLocal::EvDeadTabletAck);
- runtime.DispatchEvents(options);
- }
-
- WaitForTabletIsUp(runtime, tabletId, 0, &pipeConfig);
- WaitForTabletIsUp(runtime, tabletId, 1, &pipeConfig);
- WaitForTabletIsUp(runtime, tabletId, 2, &pipeConfig);
-
- runtime.Register(CreateTabletKiller(tabletId, runtime.GetNodeId(2)));
- {
- TDispatchOptions options;
- options.FinalEvents.emplace_back(TEvLocal::EvDeadTabletAck);
- runtime.DispatchEvents(options);
- }
-
- WaitForTabletIsUp(runtime, tabletId, 0, &pipeConfig);
- WaitForTabletIsUp(runtime, tabletId, 1, &pipeConfig);
- WaitForTabletIsUp(runtime, tabletId, 2, &pipeConfig);
- }
-
+
+ WaitForTabletIsUp(runtime, tabletId, 0, &pipeConfig);
+ WaitForTabletIsUp(runtime, tabletId, 1, &pipeConfig);
+ WaitForTabletIsUp(runtime, tabletId, 2, &pipeConfig);
+
+ runtime.Register(CreateTabletKiller(tabletId, runtime.GetNodeId(0)));
+ {
+ TDispatchOptions options;
+ options.FinalEvents.emplace_back(TEvLocal::EvDeadTabletAck);
+ runtime.DispatchEvents(options);
+ }
+
+ WaitForTabletIsUp(runtime, tabletId, 0, &pipeConfig);
+ WaitForTabletIsUp(runtime, tabletId, 1, &pipeConfig);
+ WaitForTabletIsUp(runtime, tabletId, 2, &pipeConfig);
+
+ runtime.Register(CreateTabletKiller(tabletId, runtime.GetNodeId(1)));
+ {
+ TDispatchOptions options;
+ options.FinalEvents.emplace_back(TEvLocal::EvDeadTabletAck);
+ runtime.DispatchEvents(options);
+ }
+
+ WaitForTabletIsUp(runtime, tabletId, 0, &pipeConfig);
+ WaitForTabletIsUp(runtime, tabletId, 1, &pipeConfig);
+ WaitForTabletIsUp(runtime, tabletId, 2, &pipeConfig);
+
+ runtime.Register(CreateTabletKiller(tabletId, runtime.GetNodeId(2)));
+ {
+ TDispatchOptions options;
+ options.FinalEvents.emplace_back(TEvLocal::EvDeadTabletAck);
+ runtime.DispatchEvents(options);
+ }
+
+ WaitForTabletIsUp(runtime, tabletId, 0, &pipeConfig);
+ WaitForTabletIsUp(runtime, tabletId, 1, &pipeConfig);
+ WaitForTabletIsUp(runtime, tabletId, 2, &pipeConfig);
+ }
+
Y_UNIT_TEST(TestFollowersCrossDC_Easy) {
TTestBasicRuntime runtime((ui32)9, (ui32)3);
- Setup(runtime, true);
+ Setup(runtime, true);
TVector<ui64> tabletIds;
- const ui64 hiveTablet = MakeDefaultHiveID(0);
- const ui64 testerTablet = MakeDefaultHiveID(1);
+ const ui64 hiveTablet = MakeDefaultHiveID(0);
+ const ui64 testerTablet = MakeDefaultHiveID(1);
CreateTestBootstrapper(runtime, CreateTestTabletInfo(hiveTablet, TTabletTypes::FLAT_HIVE), &CreateDefaultHive);
- {
- TDispatchOptions options;
- options.FinalEvents.emplace_back(TEvLocal::EvSyncTablets, runtime.GetNodeCount());
- runtime.DispatchEvents(options);
- }
- TTabletTypes::EType tabletType = TTabletTypes::Dummy;
- THolder<TEvHive::TEvCreateTablet> ev(new TEvHive::TEvCreateTablet(testerTablet, 100500, tabletType, BINDED_CHANNELS));
+ {
+ TDispatchOptions options;
+ options.FinalEvents.emplace_back(TEvLocal::EvSyncTablets, runtime.GetNodeCount());
+ runtime.DispatchEvents(options);
+ }
+ TTabletTypes::EType tabletType = TTabletTypes::Dummy;
+ THolder<TEvHive::TEvCreateTablet> ev(new TEvHive::TEvCreateTablet(testerTablet, 100500, tabletType, BINDED_CHANNELS));
ev->Record.SetCrossDataCenterFollowerCount(2);
ui64 tabletId = SendCreateTestTablet(runtime, hiveTablet, testerTablet, std::move(ev), 0, false);
-
- WaitForTabletsBecomeActive(runtime, 7);
-
- NTabletPipe::TClientConfig pipeConfig;
- pipeConfig.ForceLocal = true;
- ui32 tabsPerDC[3] = {};
+
+ WaitForTabletsBecomeActive(runtime, 7);
+
+ NTabletPipe::TClientConfig pipeConfig;
+ pipeConfig.ForceLocal = true;
+ ui32 tabsPerDC[3] = {};
ui32 leaders = 0;
ui32 followers = 0;
- for (ui32 node = 0; node < 9; ++node) {
+ for (ui32 node = 0; node < 9; ++node) {
bool leader;
if (CheckTabletIsUp(runtime, tabletId, node, &pipeConfig, &leader)) {
if (leader) {
leaders++;
- tabsPerDC[node % 3]++;
- }
- }
- }
+ tabsPerDC[node % 3]++;
+ }
+ }
+ }
pipeConfig.AllowFollower = true;
pipeConfig.ForceFollower = true;
- for (ui32 node = 0; node < 9; ++node) {
+ for (ui32 node = 0; node < 9; ++node) {
bool leader;
if (CheckTabletIsUp(runtime, tabletId, node, &pipeConfig, &leader)) {
if (!leader) {
followers++;
- tabsPerDC[node % 3]++;
- }
- }
- }
-
+ tabsPerDC[node % 3]++;
+ }
+ }
+ }
+
UNIT_ASSERT_VALUES_EQUAL(leaders, 1);
UNIT_ASSERT_VALUES_EQUAL(followers, 6);
- UNIT_ASSERT(tabsPerDC[0] >= 2);
- UNIT_ASSERT(tabsPerDC[1] >= 2);
- UNIT_ASSERT(tabsPerDC[2] >= 2);
- }
-
+ UNIT_ASSERT(tabsPerDC[0] >= 2);
+ UNIT_ASSERT(tabsPerDC[1] >= 2);
+ UNIT_ASSERT(tabsPerDC[2] >= 2);
+ }
+
Y_UNIT_TEST(TestFollowers_LocalNodeOnly) {
TTestBasicRuntime runtime((ui32)9, (ui32)3);
- Setup(runtime, true);
- TVector<ui64> tabletIds;
- const ui64 hiveTablet = MakeDefaultHiveID(0);
- const ui64 testerTablet = MakeDefaultHiveID(1);
+ Setup(runtime, true);
+ TVector<ui64> tabletIds;
+ const ui64 hiveTablet = MakeDefaultHiveID(0);
+ const ui64 testerTablet = MakeDefaultHiveID(1);
CreateTestBootstrapper(runtime, CreateTestTabletInfo(hiveTablet, TTabletTypes::Hive), &CreateDefaultHive);
- {
- TDispatchOptions options;
- options.FinalEvents.emplace_back(TEvLocal::EvSyncTablets, runtime.GetNodeCount());
- runtime.DispatchEvents(options);
- }
- TTabletTypes::EType tabletType = TTabletTypes::Dummy;
- THolder<TEvHive::TEvCreateTablet> ev(new TEvHive::TEvCreateTablet(testerTablet, 100500, tabletType, BINDED_CHANNELS));
+ {
+ TDispatchOptions options;
+ options.FinalEvents.emplace_back(TEvLocal::EvSyncTablets, runtime.GetNodeCount());
+ runtime.DispatchEvents(options);
+ }
+ TTabletTypes::EType tabletType = TTabletTypes::Dummy;
+ THolder<TEvHive::TEvCreateTablet> ev(new TEvHive::TEvCreateTablet(testerTablet, 100500, tabletType, BINDED_CHANNELS));
auto* followerGroup = ev->Record.AddFollowerGroups();
followerGroup->SetFollowerCount(1);
followerGroup->SetLocalNodeOnly(true);
followerGroup->SetAllowClientRead(true);
ui64 tabletId = SendCreateTestTablet(runtime, hiveTablet, testerTablet, std::move(ev), 0, false);
-
- WaitForTabletsBecomeActive(runtime, 2);
-
+
+ WaitForTabletsBecomeActive(runtime, 2);
+
ui32 leaderNode = 999;
- {
- NTabletPipe::TClientConfig pipeConfig;
- pipeConfig.ForceLocal = true;
-
+ {
+ NTabletPipe::TClientConfig pipeConfig;
+ pipeConfig.ForceLocal = true;
+
ui32 leaders = 0;
ui32 followers = 0;
- for (ui32 node = 0; node < 9; ++node) {
+ for (ui32 node = 0; node < 9; ++node) {
bool leader;
if (CheckTabletIsUp(runtime, tabletId, node, &pipeConfig, &leader)) {
if (leader) {
leaders++;
leaderNode = node;
- }
- }
- }
+ }
+ }
+ }
pipeConfig.AllowFollower = true;
pipeConfig.ForceFollower = true;
ui32 followerNode = 999;
- for (ui32 node = 0; node < 9; ++node) {
+ for (ui32 node = 0; node < 9; ++node) {
bool leader;
if (CheckTabletIsUp(runtime, tabletId, node, &pipeConfig, &leader)) {
if (!leader) {
followers++;
followerNode = node;
- }
- }
- }
-
+ }
+ }
+ }
+
UNIT_ASSERT_VALUES_EQUAL(leaders, 1);
UNIT_ASSERT_VALUES_EQUAL(followers, 1);
UNIT_ASSERT_VALUES_EQUAL(leaderNode, followerNode);
- }
-
+ }
+
runtime.Register(CreateTabletKiller(tabletId, runtime.GetNodeId(leaderNode)));
SendKillLocal(runtime, leaderNode);
- WaitForTabletsBecomeActive(runtime, 2);
-
+ WaitForTabletsBecomeActive(runtime, 2);
+
ui32 secondLeaderNode = 999;
-
- {
- NTabletPipe::TClientConfig pipeConfig;
- pipeConfig.ForceLocal = true;
-
+
+ {
+ NTabletPipe::TClientConfig pipeConfig;
+ pipeConfig.ForceLocal = true;
+
ui32 leaders = 0;
ui32 followers = 0;
- for (ui32 node = 0; node < 9; ++node) {
+ for (ui32 node = 0; node < 9; ++node) {
bool leader;
if (CheckTabletIsUp(runtime, tabletId, node, &pipeConfig, &leader)) {
if (leader) {
leaders++;
secondLeaderNode = node;
- }
- }
- }
+ }
+ }
+ }
pipeConfig.AllowFollower = true;
pipeConfig.ForceFollower = true;
ui32 followerNode = 999;
- for (ui32 node = 0; node < 9; ++node) {
+ for (ui32 node = 0; node < 9; ++node) {
bool leader;
if (CheckTabletIsUp(runtime, tabletId, node, &pipeConfig, &leader)) {
if (!leader) {
followers++;
followerNode = node;
- }
- }
- }
-
+ }
+ }
+ }
+
UNIT_ASSERT_VALUES_EQUAL(leaders, 1);
UNIT_ASSERT_VALUES_EQUAL(followers, 1);
UNIT_ASSERT(leaderNode != secondLeaderNode);
UNIT_ASSERT_VALUES_EQUAL(secondLeaderNode, followerNode);
- }
- }
-
+ }
+ }
+
Y_UNIT_TEST(TestFollowersCrossDC_Tight) {
- static constexpr ui32 NODES = 9;
- static constexpr ui32 DCS = 3;
+ static constexpr ui32 NODES = 9;
+ static constexpr ui32 DCS = 3;
static constexpr ui32 FOLLOWERS = NODES / DCS;
- TTestBasicRuntime runtime(NODES, DCS);
- Setup(runtime, true);
+ TTestBasicRuntime runtime(NODES, DCS);
+ Setup(runtime, true);
TVector<ui64> tabletIds;
- const ui64 hiveTablet = MakeDefaultHiveID(0);
- const ui64 testerTablet = MakeDefaultHiveID(1);
+ const ui64 hiveTablet = MakeDefaultHiveID(0);
+ const ui64 testerTablet = MakeDefaultHiveID(1);
CreateTestBootstrapper(runtime, CreateTestTabletInfo(hiveTablet, TTabletTypes::FLAT_HIVE), &CreateDefaultHive);
- {
- TDispatchOptions options;
- options.FinalEvents.emplace_back(TEvLocal::EvSyncTablets, runtime.GetNodeCount());
- runtime.DispatchEvents(options);
- }
- TTabletTypes::EType tabletType = TTabletTypes::Dummy;
- THolder<TEvHive::TEvCreateTablet> ev(new TEvHive::TEvCreateTablet(testerTablet, 100500, tabletType, BINDED_CHANNELS));
+ {
+ TDispatchOptions options;
+ options.FinalEvents.emplace_back(TEvLocal::EvSyncTablets, runtime.GetNodeCount());
+ runtime.DispatchEvents(options);
+ }
+ TTabletTypes::EType tabletType = TTabletTypes::Dummy;
+ THolder<TEvHive::TEvCreateTablet> ev(new TEvHive::TEvCreateTablet(testerTablet, 100500, tabletType, BINDED_CHANNELS));
ev->Record.SetCrossDataCenterFollowerCount(FOLLOWERS);
ui64 tabletId = SendCreateTestTablet(runtime, hiveTablet, testerTablet, std::move(ev), 0, false);
-
- WaitForTabletsBecomeActive(runtime, NODES + 1);
-
- NTabletPipe::TClientConfig pipeConfig;
- pipeConfig.ForceLocal = true;
+
+ WaitForTabletsBecomeActive(runtime, NODES + 1);
+
+ NTabletPipe::TClientConfig pipeConfig;
+ pipeConfig.ForceLocal = true;
ui32 followersPerDC[DCS] = {};
ui32 leaders = 0;
ui32 followers = 0;
- for (ui32 node = 0; node < NODES; ++node) {
+ for (ui32 node = 0; node < NODES; ++node) {
bool leader;
if (CheckTabletIsUp(runtime, tabletId, node, &pipeConfig, &leader)) {
if (leader) {
leaders++;
- }
- }
- }
+ }
+ }
+ }
pipeConfig.AllowFollower = true;
pipeConfig.ForceFollower = true;
- for (ui32 node = 0; node < NODES; ++node) {
+ for (ui32 node = 0; node < NODES; ++node) {
bool leader;
if (CheckTabletIsUp(runtime, tabletId, node, &pipeConfig, &leader)) {
if (!leader) {
followers++;
followersPerDC[node % DCS]++;
- }
- }
- }
+ }
+ }
+ }
UNIT_ASSERT_VALUES_EQUAL(leaders, 1);
UNIT_ASSERT_VALUES_EQUAL(followers, FOLLOWERS * DCS);
- for (ui32 dc = 0; dc < DCS; ++dc) {
+ for (ui32 dc = 0; dc < DCS; ++dc) {
UNIT_ASSERT(followersPerDC[dc] == FOLLOWERS);
- }
- }
-
+ }
+ }
+
Y_UNIT_TEST(TestFollowersCrossDC_MovingLeader) {
- static constexpr ui32 NODES = 9;
- static constexpr ui32 DCS = 3;
+ static constexpr ui32 NODES = 9;
+ static constexpr ui32 DCS = 3;
static constexpr ui32 FOLLOWERS = NODES / DCS;
- TTestBasicRuntime runtime(NODES, DCS);
- Setup(runtime, true);
+ TTestBasicRuntime runtime(NODES, DCS);
+ Setup(runtime, true);
TVector<ui64> tabletIds;
- const ui64 hiveTablet = MakeDefaultHiveID(0);
- const ui64 testerTablet = MakeDefaultHiveID(1);
+ const ui64 hiveTablet = MakeDefaultHiveID(0);
+ const ui64 testerTablet = MakeDefaultHiveID(1);
CreateTestBootstrapper(runtime, CreateTestTabletInfo(hiveTablet, TTabletTypes::FLAT_HIVE), &CreateDefaultHive);
- {
- TDispatchOptions options;
- options.FinalEvents.emplace_back(TEvLocal::EvSyncTablets, runtime.GetNodeCount());
- runtime.DispatchEvents(options);
- }
- TTabletTypes::EType tabletType = TTabletTypes::Dummy;
- THolder<TEvHive::TEvCreateTablet> ev(new TEvHive::TEvCreateTablet(testerTablet, 100500, tabletType, BINDED_CHANNELS));
+ {
+ TDispatchOptions options;
+ options.FinalEvents.emplace_back(TEvLocal::EvSyncTablets, runtime.GetNodeCount());
+ runtime.DispatchEvents(options);
+ }
+ TTabletTypes::EType tabletType = TTabletTypes::Dummy;
+ THolder<TEvHive::TEvCreateTablet> ev(new TEvHive::TEvCreateTablet(testerTablet, 100500, tabletType, BINDED_CHANNELS));
ev->Record.SetCrossDataCenterFollowerCount(FOLLOWERS);
ui64 tabletId = SendCreateTestTablet(runtime, hiveTablet, testerTablet, std::move(ev), 0, true);
-
- //WaitForTabletsBecomeActive(runtime, 3 * 3 + 1);
-
+
+ //WaitForTabletsBecomeActive(runtime, 3 * 3 + 1);
+
ui32 leadersNode = 0;
- {
- NTabletPipe::TClientConfig pipeConfig;
- pipeConfig.ForceLocal = true;
+ {
+ NTabletPipe::TClientConfig pipeConfig;
+ pipeConfig.ForceLocal = true;
ui32 followersPerDC[DCS] = {};
- ui32 total = 0;
+ ui32 total = 0;
ui32 leaders = 0;
ui32 followers = 0;
- for (ui32 node = 0; node < NODES; ++node) {
+ for (ui32 node = 0; node < NODES; ++node) {
bool leader;
if (CheckTabletIsUp(runtime, tabletId, node, &pipeConfig, &leader)) {
if (leader) {
leaders++;
leadersNode = node;
- total++;
- }
- }
- }
+ total++;
+ }
+ }
+ }
pipeConfig.AllowFollower = true;
pipeConfig.ForceFollower = true;
- for (ui32 node = 0; node < NODES; ++node) {
+ for (ui32 node = 0; node < NODES; ++node) {
bool leader;
if (CheckTabletIsUp(runtime, tabletId, node, &pipeConfig, &leader)) {
if (!leader) {
- total++;
+ total++;
followers++;
followersPerDC[node % DCS]++;
- }
- }
- }
+ }
+ }
+ }
UNIT_ASSERT_VALUES_EQUAL(total, 1 + FOLLOWERS * DCS);
UNIT_ASSERT_VALUES_EQUAL(followers, FOLLOWERS * DCS);
UNIT_ASSERT_VALUES_EQUAL(leaders, 1);
- for (ui32 dc = 0; dc < DCS; ++dc) {
+ for (ui32 dc = 0; dc < DCS; ++dc) {
UNIT_ASSERT(followersPerDC[dc] == FOLLOWERS);
- }
- }
-
+ }
+ }
+
runtime.Register(CreateTabletKiller(tabletId, runtime.GetNodeId(leadersNode)));
- WaitForTabletsBecomeActive(runtime, 1);
-
- {
- NTabletPipe::TClientConfig pipeConfig;
+ WaitForTabletsBecomeActive(runtime, 1);
+
+ {
+ NTabletPipe::TClientConfig pipeConfig;
// we need retry policy to handle possible follower reconnect
- pipeConfig.RetryPolicy = {.RetryLimitCount = 2, .MinRetryTime = TDuration::MilliSeconds(100)};
- pipeConfig.ForceLocal = true;
+ pipeConfig.RetryPolicy = {.RetryLimitCount = 2, .MinRetryTime = TDuration::MilliSeconds(100)};
+ pipeConfig.ForceLocal = true;
ui32 followersPerDC[DCS] = {};
- ui32 total = 0;
+ ui32 total = 0;
ui32 leaders = 0;
ui32 followers = 0;
- for (ui32 node = 0; node < NODES; ++node) {
+ for (ui32 node = 0; node < NODES; ++node) {
bool leader;
if (CheckTabletIsUp(runtime, tabletId, node, &pipeConfig, &leader)) {
if (leader) {
leaders++;
- total++;
- }
- }
- }
+ total++;
+ }
+ }
+ }
pipeConfig.AllowFollower = true;
pipeConfig.ForceFollower = true;
- for (ui32 node = 0; node < NODES; ++node) {
+ for (ui32 node = 0; node < NODES; ++node) {
bool leader;
if (CheckTabletIsUp(runtime, tabletId, node, &pipeConfig, &leader)) {
if (!leader) {
- total++;
+ total++;
followers++;
followersPerDC[node % DCS]++;
- }
- }
- }
+ }
+ }
+ }
UNIT_ASSERT_VALUES_EQUAL(total, 1 + FOLLOWERS * DCS);
UNIT_ASSERT_VALUES_EQUAL(followers, FOLLOWERS * DCS);
UNIT_ASSERT_VALUES_EQUAL(leaders, 1);
- for (ui32 dc = 0; dc < DCS; ++dc) {
+ for (ui32 dc = 0; dc < DCS; ++dc) {
UNIT_ASSERT(followersPerDC[dc] == FOLLOWERS);
- }
- }
- }
+ }
+ }
+ }
Y_UNIT_TEST(TestFollowersCrossDC_KillingHiveAndFollower) {
- static constexpr ui32 NODES = 3;
- static constexpr ui32 DCS = 3;
+ static constexpr ui32 NODES = 3;
+ static constexpr ui32 DCS = 3;
static constexpr ui32 FOLLOWERS = 1;
- TTestBasicRuntime runtime(NODES, DCS);
- Setup(runtime, true);
- TVector<ui64> tabletIds;
- const ui64 hiveTablet = MakeDefaultHiveID(0);
- const ui64 testerTablet = MakeDefaultHiveID(1);
+ TTestBasicRuntime runtime(NODES, DCS);
+ Setup(runtime, true);
+ TVector<ui64> tabletIds;
+ const ui64 hiveTablet = MakeDefaultHiveID(0);
+ const ui64 testerTablet = MakeDefaultHiveID(1);
CreateTestBootstrapper(runtime, CreateTestTabletInfo(hiveTablet, TTabletTypes::FLAT_HIVE), &CreateDefaultHive, 0);
- {
- TDispatchOptions options;
- options.FinalEvents.emplace_back(TEvLocal::EvSyncTablets, runtime.GetNodeCount());
- runtime.DispatchEvents(options);
- }
- TTabletTypes::EType tabletType = TTabletTypes::Dummy;
- THolder<TEvHive::TEvCreateTablet> ev(new TEvHive::TEvCreateTablet(testerTablet, 100500, tabletType, BINDED_CHANNELS));
- ev->Record.SetObjectId(1337);
+ {
+ TDispatchOptions options;
+ options.FinalEvents.emplace_back(TEvLocal::EvSyncTablets, runtime.GetNodeCount());
+ runtime.DispatchEvents(options);
+ }
+ TTabletTypes::EType tabletType = TTabletTypes::Dummy;
+ THolder<TEvHive::TEvCreateTablet> ev(new TEvHive::TEvCreateTablet(testerTablet, 100500, tabletType, BINDED_CHANNELS));
+ ev->Record.SetObjectId(1337);
ev->Record.SetCrossDataCenterFollowerCount(FOLLOWERS);
ui64 tabletId = SendCreateTestTablet(runtime, hiveTablet, testerTablet, std::move(ev), 0, false);
-
+
WaitForTabletsBecomeActive(runtime, FOLLOWERS * DCS + 1);
-
+
ui32 leaderNode = 0;
ui32 followersNode = 0;
- {
- NTabletPipe::TClientConfig pipeConfig;
- pipeConfig.ForceLocal = true;
- ui32 total = 0;
+ {
+ NTabletPipe::TClientConfig pipeConfig;
+ pipeConfig.ForceLocal = true;
+ ui32 total = 0;
ui32 leaders = 0;
ui32 followers = 0;
- for (ui32 node = 0; node < NODES; ++node) {
+ for (ui32 node = 0; node < NODES; ++node) {
bool leader;
if (CheckTabletIsUp(runtime, tabletId, node, &pipeConfig, &leader)) {
if (leader) {
leaders++;
- total++;
+ total++;
leaderNode = node;
- }
- }
- }
+ }
+ }
+ }
pipeConfig.AllowFollower = true;
pipeConfig.ForceFollower = true;
- for (ui32 node = 0; node < NODES; ++node) {
+ for (ui32 node = 0; node < NODES; ++node) {
bool leader;
if (CheckTabletIsUp(runtime, tabletId, node, &pipeConfig, &leader)) {
if (!leader) {
- total++;
+ total++;
followers++;
if (node != leaderNode) {
followersNode = node;
- }
- }
- }
- }
+ }
+ }
+ }
+ }
UNIT_ASSERT_VALUES_EQUAL(followers, FOLLOWERS * DCS);
UNIT_ASSERT_VALUES_EQUAL(leaders, 1);
UNIT_ASSERT_VALUES_EQUAL(total, 1 + FOLLOWERS * DCS);
- }
-
- runtime.Register(CreateTabletKiller(hiveTablet));
- {
- TDispatchOptions options;
- options.FinalEvents.emplace_back(TEvTablet::EvTabletDead);
- runtime.DispatchEvents(options);
- }
+ }
+
+ runtime.Register(CreateTabletKiller(hiveTablet));
+ {
+ TDispatchOptions options;
+ options.FinalEvents.emplace_back(TEvTablet::EvTabletDead);
+ runtime.DispatchEvents(options);
+ }
SendKillLocal(runtime, followersNode);
- WaitForEvServerDisconnected(runtime);
- WaitForTabletsBecomeActive(runtime, 1); // hive
+ WaitForEvServerDisconnected(runtime);
+ WaitForTabletsBecomeActive(runtime, 1); // hive
CreateLocal(runtime, followersNode);
WaitForTabletsBecomeActive(runtime, 1); // follower
-
- {
- NTabletPipe::TClientConfig pipeConfig;
- pipeConfig.ForceLocal = true;
- ui32 total = 0;
+
+ {
+ NTabletPipe::TClientConfig pipeConfig;
+ pipeConfig.ForceLocal = true;
+ ui32 total = 0;
ui32 leaders = 0;
ui32 followers = 0;
- for (ui32 node = 0; node < NODES; ++node) {
+ for (ui32 node = 0; node < NODES; ++node) {
bool leader;
if (CheckTabletIsUp(runtime, tabletId, node, &pipeConfig, &leader)) {
if (leader) {
leaders++;
- total++;
- }
- }
- }
+ total++;
+ }
+ }
+ }
pipeConfig.AllowFollower = true;
pipeConfig.ForceFollower = true;
- for (ui32 node = 0; node < NODES; ++node) {
+ for (ui32 node = 0; node < NODES; ++node) {
bool leader;
if (CheckTabletIsUp(runtime, tabletId, node, &pipeConfig, &leader)) {
if (!leader) {
- total++;
+ total++;
followers++;
- }
- }
- }
+ }
+ }
+ }
UNIT_ASSERT_VALUES_EQUAL(followers, FOLLOWERS * DCS);
UNIT_ASSERT_VALUES_EQUAL(leaders, 1);
UNIT_ASSERT_VALUES_EQUAL(total, 1 + FOLLOWERS * DCS);
- }
- }
-
+ }
+ }
+
Y_UNIT_TEST(TestCreateExternalTablet) {
TTestBasicRuntime runtime(1, false);
Setup(runtime, true);
@@ -3852,7 +3852,7 @@ Y_UNIT_TEST_SUITE(THiveTest) {
CreateTestBootstrapper(runtime, CreateTestTabletInfo(hiveTablet, TTabletTypes::FLAT_HIVE), &CreateDefaultHive);
TTabletTypes::EType tabletType = TTabletTypes::Dummy;
- THolder<TEvHive::TEvCreateTablet> ev(new TEvHive::TEvCreateTablet(testerTablet, 0, tabletType, BINDED_CHANNELS));
+ THolder<TEvHive::TEvCreateTablet> ev(new TEvHive::TEvCreateTablet(testerTablet, 0, tabletType, BINDED_CHANNELS));
ev->Record.SetTabletBootMode(NKikimrHive::TABLET_BOOT_MODE_EXTERNAL);
ui64 tabletId = SendCreateTestTablet(runtime, hiveTablet, testerTablet, std::move(ev), 0, true);
MakeSureTabletIsDown(runtime, tabletId, 0);
@@ -3866,10 +3866,10 @@ Y_UNIT_TEST_SUITE(THiveTest) {
CreateTestBootstrapper(runtime, CreateTestTabletInfo(hiveTablet, TTabletTypes::FLAT_HIVE), &CreateDefaultHive);
TTabletTypes::EType tabletType = TTabletTypes::Dummy;
- THolder<TEvHive::TEvCreateTablet> ev(new TEvHive::TEvCreateTablet(testerTablet, 0, tabletType, BINDED_CHANNELS));
+ THolder<TEvHive::TEvCreateTablet> ev(new TEvHive::TEvCreateTablet(testerTablet, 0, tabletType, BINDED_CHANNELS));
ui64 tabletId = SendCreateTestTablet(runtime, hiveTablet, testerTablet, std::move(ev), 0, true);
MakeSureTabletIsUp(runtime, tabletId, 0);
- THolder<TEvHive::TEvCreateTablet> ev2(new TEvHive::TEvCreateTablet(testerTablet, 0, tabletType, BINDED_CHANNELS));
+ THolder<TEvHive::TEvCreateTablet> ev2(new TEvHive::TEvCreateTablet(testerTablet, 0, tabletType, BINDED_CHANNELS));
ev2->Record.SetTabletBootMode(NKikimrHive::TABLET_BOOT_MODE_EXTERNAL);
ui64 tabletId2 = SendCreateTestTablet(runtime, hiveTablet, testerTablet, std::move(ev2), 0, false, NKikimrProto::ALREADY);
UNIT_ASSERT_VALUES_EQUAL(tabletId, tabletId2);
@@ -3889,7 +3889,7 @@ Y_UNIT_TEST_SUITE(THiveTest) {
CreateTestBootstrapper(runtime, CreateTestTabletInfo(hiveTablet, TTabletTypes::FLAT_HIVE), &CreateDefaultHive);
TTabletTypes::EType tabletType = TTabletTypes::Dummy;
- THolder<TEvHive::TEvCreateTablet> ev(new TEvHive::TEvCreateTablet(testerTablet, 0, tabletType, BINDED_CHANNELS));
+ THolder<TEvHive::TEvCreateTablet> ev(new TEvHive::TEvCreateTablet(testerTablet, 0, tabletType, BINDED_CHANNELS));
ui64 tabletId = SendCreateTestTablet(runtime, hiveTablet, testerTablet, std::move(ev), 0, false);
SendGetTabletStorageInfo(runtime, hiveTablet, tabletId, 0);
@@ -3917,7 +3917,7 @@ Y_UNIT_TEST_SUITE(THiveTest) {
});
TTabletTypes::EType tabletType = TTabletTypes::Dummy;
- THolder<TEvHive::TEvCreateTablet> ev(new TEvHive::TEvCreateTablet(testerTablet, 0, tabletType, BINDED_CHANNELS));
+ THolder<TEvHive::TEvCreateTablet> ev(new TEvHive::TEvCreateTablet(testerTablet, 0, tabletType, BINDED_CHANNELS));
ui64 tabletId = SendCreateTestTablet(runtime, hiveTablet, testerTablet, std::move(ev), 0, false);
SendGetTabletStorageInfo(runtime, hiveTablet, tabletId, 0);
@@ -3987,7 +3987,7 @@ Y_UNIT_TEST_SUITE(THiveTest) {
CreateTestBootstrapper(runtime, CreateTestTabletInfo(hiveTablet, TTabletTypes::FLAT_HIVE), &CreateDefaultHive);
TTabletTypes::EType tabletType = TTabletTypes::Dummy;
- THolder<TEvHive::TEvCreateTablet> ev(new TEvHive::TEvCreateTablet(testerTablet, 0, tabletType, BINDED_CHANNELS));
+ THolder<TEvHive::TEvCreateTablet> ev(new TEvHive::TEvCreateTablet(testerTablet, 0, tabletType, BINDED_CHANNELS));
ui64 tabletId = SendCreateTestTablet(runtime, hiveTablet, testerTablet, std::move(ev), 0, true);
MakeSureTabletIsUp(runtime, tabletId, 0);
@@ -4011,7 +4011,7 @@ Y_UNIT_TEST_SUITE(THiveTest) {
CreateTestBootstrapper(runtime, CreateTestTabletInfo(hiveTablet, TTabletTypes::FLAT_HIVE), &CreateDefaultHive);
TTabletTypes::EType tabletType = TTabletTypes::Dummy;
- THolder<TEvHive::TEvCreateTablet> ev(new TEvHive::TEvCreateTablet(testerTablet, 0, tabletType, BINDED_CHANNELS));
+ THolder<TEvHive::TEvCreateTablet> ev(new TEvHive::TEvCreateTablet(testerTablet, 0, tabletType, BINDED_CHANNELS));
ui64 tabletId = SendCreateTestTablet(runtime, hiveTablet, testerTablet, std::move(ev), 0, true);
MakeSureTabletIsUp(runtime, tabletId, 0);
@@ -4031,7 +4031,7 @@ Y_UNIT_TEST_SUITE(THiveTest) {
runtime.EnableScheduleForActor(hiveActor);
TTabletTypes::EType tabletType = TTabletTypes::Dummy;
- THolder<TEvHive::TEvCreateTablet> ev(new TEvHive::TEvCreateTablet(testerTablet, 0, tabletType, BINDED_CHANNELS));
+ THolder<TEvHive::TEvCreateTablet> ev(new TEvHive::TEvCreateTablet(testerTablet, 0, tabletType, BINDED_CHANNELS));
ui64 tabletId = SendCreateTestTablet(runtime, hiveTablet, testerTablet, std::move(ev), 0, true);
MakeSureTabletIsUp(runtime, tabletId, 0);
@@ -4060,7 +4060,7 @@ Y_UNIT_TEST_SUITE(THiveTest) {
runtime.EnableScheduleForActor(hiveActor);
TTabletTypes::EType tabletType = TTabletTypes::Dummy;
- THolder<TEvHive::TEvCreateTablet> ev(new TEvHive::TEvCreateTablet(testerTablet, 0, tabletType, BINDED_CHANNELS));
+ THolder<TEvHive::TEvCreateTablet> ev(new TEvHive::TEvCreateTablet(testerTablet, 0, tabletType, BINDED_CHANNELS));
ui64 tabletId = SendCreateTestTablet(runtime, hiveTablet, testerTablet, std::move(ev), 0, true);
MakeSureTabletIsUp(runtime, tabletId, 0);
@@ -4090,7 +4090,7 @@ Y_UNIT_TEST_SUITE(THiveTest) {
runtime.EnableScheduleForActor(hiveActor);
TTabletTypes::EType tabletType = TTabletTypes::Dummy;
- THolder<TEvHive::TEvCreateTablet> ev(new TEvHive::TEvCreateTablet(testerTablet, 0, tabletType, BINDED_CHANNELS));
+ THolder<TEvHive::TEvCreateTablet> ev(new TEvHive::TEvCreateTablet(testerTablet, 0, tabletType, BINDED_CHANNELS));
ui64 tabletId = SendCreateTestTablet(runtime, hiveTablet, testerTablet, std::move(ev), 0, true);
MakeSureTabletIsUp(runtime, tabletId, 0);
@@ -4125,7 +4125,7 @@ Y_UNIT_TEST_SUITE(THiveTest) {
runtime.EnableScheduleForActor(hiveActor);
TTabletTypes::EType tabletType = TTabletTypes::Dummy;
- THolder<TEvHive::TEvCreateTablet> ev(new TEvHive::TEvCreateTablet(testerTablet, 0, tabletType, BINDED_CHANNELS));
+ THolder<TEvHive::TEvCreateTablet> ev(new TEvHive::TEvCreateTablet(testerTablet, 0, tabletType, BINDED_CHANNELS));
ui64 tabletId = SendCreateTestTablet(runtime, hiveTablet, testerTablet, std::move(ev), 0, true);
MakeSureTabletIsUp(runtime, tabletId, 0);
@@ -4160,7 +4160,7 @@ Y_UNIT_TEST_SUITE(THiveTest) {
TActorId edge = runtime.AllocateEdgeActor();
NTabletPipe::TClientConfig clientConfig;
clientConfig.AllowFollower = true;
- clientConfig.RetryPolicy = NTabletPipe::TClientRetryPolicy::WithRetries();
+ clientConfig.RetryPolicy = NTabletPipe::TClientRetryPolicy::WithRetries();
TActorId pipeClient = runtime.Register(NTabletPipe::CreateClient(edge, tabletId, clientConfig));
TAutoPtr<IEventHandle> handle;
TInstant deadline = TInstant::Now() + timeout;
@@ -4193,7 +4193,7 @@ Y_UNIT_TEST_SUITE(THiveTest) {
runtime.EnableScheduleForActor(hiveActor);
TTabletTypes::EType tabletType = TTabletTypes::Dummy;
- THolder<TEvHive::TEvCreateTablet> ev(new TEvHive::TEvCreateTablet(testerTablet, 0, tabletType, BINDED_CHANNELS));
+ THolder<TEvHive::TEvCreateTablet> ev(new TEvHive::TEvCreateTablet(testerTablet, 0, tabletType, BINDED_CHANNELS));
ui64 tabletId = SendCreateTestTablet(runtime, hiveTablet, testerTablet, std::move(ev), 0, true);
MakeSureTabletIsUp(runtime, tabletId, 0);
@@ -4222,7 +4222,7 @@ Y_UNIT_TEST_SUITE(THiveTest) {
runtime.EnableScheduleForActor(hiveActor);
TTabletTypes::EType tabletType = TTabletTypes::Dummy;
- THolder<TEvHive::TEvCreateTablet> ev(new TEvHive::TEvCreateTablet(testerTablet, 0, tabletType, BINDED_CHANNELS));
+ THolder<TEvHive::TEvCreateTablet> ev(new TEvHive::TEvCreateTablet(testerTablet, 0, tabletType, BINDED_CHANNELS));
ui64 tabletId = SendCreateTestTablet(runtime, hiveTablet, testerTablet, std::move(ev), 0, true);
MakeSureTabletIsUp(runtime, tabletId, 0);
@@ -4248,7 +4248,7 @@ Y_UNIT_TEST_SUITE(THiveTest) {
runtime.EnableScheduleForActor(hiveActor);
TTabletTypes::EType tabletType = TTabletTypes::Dummy;
- THolder<TEvHive::TEvCreateTablet> ev(new TEvHive::TEvCreateTablet(testerTablet, 0, tabletType, BINDED_CHANNELS));
+ THolder<TEvHive::TEvCreateTablet> ev(new TEvHive::TEvCreateTablet(testerTablet, 0, tabletType, BINDED_CHANNELS));
ui64 tabletId = SendCreateTestTablet(runtime, hiveTablet, testerTablet, std::move(ev), 0, true);
MakeSureTabletIsUp(runtime, tabletId, 0);
@@ -4296,7 +4296,7 @@ Y_UNIT_TEST_SUITE(THiveTest) {
CreateTestBootstrapper(runtime, CreateTestTabletInfo(hiveTablet, TTabletTypes::FLAT_HIVE), &CreateDefaultHive);
TTabletTypes::EType tabletType = TTabletTypes::Dummy;
- THolder<TEvHive::TEvCreateTablet> ev(new TEvHive::TEvCreateTablet(testerTablet, 0, tabletType, BINDED_CHANNELS));
+ THolder<TEvHive::TEvCreateTablet> ev(new TEvHive::TEvCreateTablet(testerTablet, 0, tabletType, BINDED_CHANNELS));
ui64 tabletId = SendCreateTestTablet(runtime, hiveTablet, testerTablet, std::move(ev), 0, true);
MakeSureTabletIsUp(runtime, tabletId, 0);
@@ -4317,7 +4317,7 @@ Y_UNIT_TEST_SUITE(THiveTest) {
CreateTestBootstrapper(runtime, CreateTestTabletInfo(hiveTablet, TTabletTypes::FLAT_HIVE), &CreateDefaultHive);
TTabletTypes::EType tabletType = TTabletTypes::Dummy;
- THolder<TEvHive::TEvCreateTablet> ev(new TEvHive::TEvCreateTablet(testerTablet, 0, tabletType, BINDED_CHANNELS));
+ THolder<TEvHive::TEvCreateTablet> ev(new TEvHive::TEvCreateTablet(testerTablet, 0, tabletType, BINDED_CHANNELS));
ui64 tabletId = SendCreateTestTablet(runtime, hiveTablet, testerTablet, std::move(ev), 0, true);
MakeSureTabletIsUp(runtime, tabletId, 0);
@@ -4342,7 +4342,7 @@ Y_UNIT_TEST_SUITE(THiveTest) {
CreateTestBootstrapper(runtime, CreateTestTabletInfo(hiveTablet, TTabletTypes::FLAT_HIVE), &CreateDefaultHive);
TTabletTypes::EType tabletType = TTabletTypes::Dummy;
- THolder<TEvHive::TEvCreateTablet> ev(new TEvHive::TEvCreateTablet(testerTablet, 0, tabletType, BINDED_CHANNELS));
+ THolder<TEvHive::TEvCreateTablet> ev(new TEvHive::TEvCreateTablet(testerTablet, 0, tabletType, BINDED_CHANNELS));
ui64 tabletId = SendCreateTestTablet(runtime, hiveTablet, testerTablet, std::move(ev), 0, true);
MakeSureTabletIsUp(runtime, tabletId, 0);
@@ -4366,7 +4366,7 @@ Y_UNIT_TEST_SUITE(THiveTest) {
const ui64 testerTablet = MakeDefaultHiveID(1);
CreateTestBootstrapper(runtime, CreateTestTabletInfo(hiveTablet, TTabletTypes::FLAT_HIVE), &CreateDefaultHive);
- TAutoPtr<TEvHive::TEvCreateTablet> ev = new TEvHive::TEvCreateTablet(testerTablet, 0, TTabletTypes::Dummy, BINDED_CHANNELS);
+ TAutoPtr<TEvHive::TEvCreateTablet> ev = new TEvHive::TEvCreateTablet(testerTablet, 0, TTabletTypes::Dummy, BINDED_CHANNELS);
ev->Record.SetTabletBootMode(NKikimrHive::ETabletBootMode::TABLET_BOOT_MODE_EXTERNAL);
ui64 tabletId = SendCreateTestTablet(runtime, hiveTablet, testerTablet, std::move(ev), 0, true);
@@ -4376,7 +4376,7 @@ Y_UNIT_TEST_SUITE(THiveTest) {
TAutoPtr<IEventHandle> handle;
auto* result = runtime.GrabEdgeEvent<TEvLocal::TEvBootTablet>(handle);
UNIT_ASSERT(result);
- UNIT_ASSERT_VALUES_EQUAL(result->Record.GetSuggestedGeneration(), 1);
+ UNIT_ASSERT_VALUES_EQUAL(result->Record.GetSuggestedGeneration(), 1);
UNIT_ASSERT_EQUAL(result->Record.GetBootMode(), NKikimrLocal::EBootMode::BOOT_MODE_LEADER);
const auto& storageInfo = result->Record.GetInfo();
@@ -4392,7 +4392,7 @@ Y_UNIT_TEST_SUITE(THiveTest) {
const ui64 testerTablet = MakeDefaultHiveID(1);
CreateTestBootstrapper(runtime, CreateTestTabletInfo(hiveTablet, TTabletTypes::FLAT_HIVE), &CreateDefaultHive);
- THolder<TEvHive::TEvCreateTablet> ev(new TEvHive::TEvCreateTablet(testerTablet, 0, TTabletTypes::Dummy, BINDED_CHANNELS));
+ THolder<TEvHive::TEvCreateTablet> ev(new TEvHive::TEvCreateTablet(testerTablet, 0, TTabletTypes::Dummy, BINDED_CHANNELS));
ui64 tabletId = SendCreateTestTablet(runtime, hiveTablet, testerTablet, std::move(ev), 0, true);
MakeSureTabletIsUp(runtime, tabletId, 0);
diff --git a/ydb/core/mind/hive/leader_tablet_info.cpp b/ydb/core/mind/hive/leader_tablet_info.cpp
index dc798e15834..13e1d5b2ee2 100644
--- a/ydb/core/mind/hive/leader_tablet_info.cpp
+++ b/ydb/core/mind/hive/leader_tablet_info.cpp
@@ -1,281 +1,281 @@
-#include "hive_impl.h"
-
-namespace NKikimr {
-namespace NHive {
-
+#include "hive_impl.h"
+
+namespace NKikimr {
+namespace NHive {
+
TString TLeaderTabletInfo::DEFAULT_STORAGE_POOL_NAME = "default";
-
+
TPathId TLeaderTabletInfo::GetTenant() const {
// todo: must be explicit TenantPathId
- if (!ObjectDomain)
+ if (!ObjectDomain)
return TPathId();
- return TPathId(ObjectDomain.GetSchemeShard(), ObjectDomain.GetPathId());
+ return TPathId(ObjectDomain.GetSchemeShard(), ObjectDomain.GetPathId());
}
bool TLeaderTabletInfo::IsSomeoneAliveOnNode(TNodeId nodeId) const {
- if (CanBeAlive() && Node->Id == nodeId) {
- return true;
- }
+ if (CanBeAlive() && Node->Id == nodeId) {
+ return true;
+ }
for (const TTabletInfo& follower : Followers) {
if (follower.CanBeAlive() && follower.Node->Id == nodeId)
- return true;
- }
- return false;
-}
-
+ return true;
+ }
+ return false;
+}
+
ui32 TLeaderTabletInfo::GetFollowersAliveOnDataCenter(TDataCenterId dataCenterId) const {
ui32 followers = 0;
for (const TTabletInfo& follower : Followers) {
if (follower.CanBeAlive() && follower.Node->Location.GetDataCenterId() == dataCenterId) {
++followers;
- }
- }
+ }
+ }
return followers;
-}
-
+}
+
ui32 TLeaderTabletInfo::GetFollowersAliveOnDataCenterExcludingFollower(TDataCenterId dataCenterId, const TTabletInfo& excludingFollower) const {
ui32 followers = 0;
for (const TTabletInfo& follower : Followers) {
if (follower == excludingFollower)
- continue;
+ continue;
if (follower.CanBeAlive() && follower.Node->Location.GetDataCenterId() == dataCenterId) {
++followers;
- }
- }
+ }
+ }
return followers;
-}
-
+}
+
bool TLeaderTabletInfo::IsFollowerPromotableOnNode(TNodeId nodeId) const {
for (const TFollowerTabletInfo& follower : Followers) {
if (follower.IsRunning() && follower.NodeId == nodeId && follower.FollowerGroup.AllowLeaderPromotion)
- return true;
- }
- return false;
-}
-
+ return true;
+ }
+ return false;
+}
+
TFollowerId TLeaderTabletInfo::GetFollowerPromotableOnNode(TNodeId nodeId) const {
for (const TFollowerTabletInfo& follower : Followers) {
if (follower.IsRunning() && follower.NodeId == nodeId && follower.FollowerGroup.AllowLeaderPromotion)
return follower.Id;
- }
- return 0;
-}
-
+ }
+ return 0;
+}
+
void TLeaderTabletInfo::AssignDomains(const TSubDomainKey& objectDomain, const TVector<TSubDomainKey>& allowedDomains) {
- if (!allowedDomains.empty()) {
- EffectiveAllowedDomains = allowedDomains;
- if (!objectDomain) {
- ObjectDomain = allowedDomains.front();
- } else {
- ObjectDomain = objectDomain;
- }
- } else if (objectDomain) {
- EffectiveAllowedDomains = { objectDomain };
- ObjectDomain = objectDomain;
- } else {
- EffectiveAllowedDomains = { Hive.GetRootDomainKey() };
- ObjectDomain = { Hive.GetRootDomainKey() };
- }
-}
-
+ if (!allowedDomains.empty()) {
+ EffectiveAllowedDomains = allowedDomains;
+ if (!objectDomain) {
+ ObjectDomain = allowedDomains.front();
+ } else {
+ ObjectDomain = objectDomain;
+ }
+ } else if (objectDomain) {
+ EffectiveAllowedDomains = { objectDomain };
+ ObjectDomain = objectDomain;
+ } else {
+ EffectiveAllowedDomains = { Hive.GetRootDomainKey() };
+ ObjectDomain = { Hive.GetRootDomainKey() };
+ }
+}
+
bool TLeaderTabletInfo::InitiateAssignTabletGroups() {
- Hive.AssignTabletGroups(*this);
- return true;
-}
-
+ Hive.AssignTabletGroups(*this);
+ return true;
+}
+
bool TLeaderTabletInfo::InitiateBlockStorage() {
- // attempt to kill tablet before blocking the storage group
- Kill();
- // blocks PREVIOUS entry of tablet history
+ // attempt to kill tablet before blocking the storage group
+ Kill();
+ // blocks PREVIOUS entry of tablet history
IActor* x = CreateTabletReqBlockBlobStorage(Hive.SelfId(), TabletStorageInfo.Get(), KnownGeneration, true);
- Hive.Register(x);
- return true;
-}
-
+ Hive.Register(x);
+ return true;
+}
+
bool TLeaderTabletInfo::InitiateBlockStorage(ui32 generation) {
- // attempt to kill tablet before blocking the storage group
- Kill();
- // blocks LATEST entry of tablet history
- const TTabletChannelInfo* channel = TabletStorageInfo->ChannelInfo(0);
- if (IsDeleting() && channel == nullptr) {
- return false;
- }
- Y_VERIFY(channel != nullptr && !channel->History.empty());
+ // attempt to kill tablet before blocking the storage group
+ Kill();
+ // blocks LATEST entry of tablet history
+ const TTabletChannelInfo* channel = TabletStorageInfo->ChannelInfo(0);
+ if (IsDeleting() && channel == nullptr) {
+ return false;
+ }
+ Y_VERIFY(channel != nullptr && !channel->History.empty());
IActor* x = CreateTabletReqBlockBlobStorage(Hive.SelfId(), TabletStorageInfo.Get(), generation, false);
- Hive.Register(x);
- return true;
-}
-
+ Hive.Register(x);
+ return true;
+}
+
bool TLeaderTabletInfo::InitiateDeleteStorage() {
IActor* x = CreateTabletReqDelete(Hive.SelfId(), TabletStorageInfo);
- Hive.Register(x);
- return true;
-}
-
+ Hive.Register(x);
+ return true;
+}
+
TFollowerTabletInfo& TLeaderTabletInfo::AddFollower(TFollowerGroup& followerGroup, TFollowerId followerId) {
Followers.emplace_back(*this, followerId, followerGroup);
TFollowerTabletInfo& follower = Followers.back();
if (followerId == 0) {
follower.Id = GenerateFollowerId();
- } else {
+ } else {
follower.Id = followerId;
- }
- Hive.UpdateCounterTabletsTotal(+1);
+ }
+ Hive.UpdateCounterTabletsTotal(+1);
return follower;
-}
-
+}
+
TFollowerGroupId TLeaderTabletInfo::GenerateFollowerGroupId() const {
return GenerateId(FollowerGroups);
-}
-
+}
+
TFollowerGroup& TLeaderTabletInfo::AddFollowerGroup(TFollowerGroupId followerGroupId) {
FollowerGroups.emplace_back();
TFollowerGroup& followerGroup = FollowerGroups.back();
if (followerGroupId == 0) {
followerGroup.Id = GenerateFollowerGroupId();
- } else {
+ } else {
followerGroup.Id = followerGroupId;
- }
+ }
return followerGroup;
-}
-
+}
+
TActorId TLeaderTabletInfo::SetLockedToActor(const TActorId& actor, const TDuration& timeout) {
TActorId previousOwner = LockedToActor;
- if (LockedToActor != actor) {
- if (LockedToActor.NodeId() != actor.NodeId()) {
- if (LockedToActor) {
- TNodeId oldNodeId = LockedToActor.NodeId();
- Y_VERIFY(oldNodeId != 0, "Unexpected oldNodeId == 0");
- Hive.GetNode(oldNodeId).LockedTablets.erase(this);
- }
- if (actor) {
- TNodeId newNodeId = actor.NodeId();
- Y_VERIFY(newNodeId != 0, "Unexpected newNodeId == 0");
- Hive.GetNode(newNodeId).LockedTablets.insert(this);
- }
- }
- LockedToActor = actor;
- }
- LockedReconnectTimeout = timeout;
- PendingUnlockSeqNo = 0;
- return previousOwner;
-}
-
+ if (LockedToActor != actor) {
+ if (LockedToActor.NodeId() != actor.NodeId()) {
+ if (LockedToActor) {
+ TNodeId oldNodeId = LockedToActor.NodeId();
+ Y_VERIFY(oldNodeId != 0, "Unexpected oldNodeId == 0");
+ Hive.GetNode(oldNodeId).LockedTablets.erase(this);
+ }
+ if (actor) {
+ TNodeId newNodeId = actor.NodeId();
+ Y_VERIFY(newNodeId != 0, "Unexpected newNodeId == 0");
+ Hive.GetNode(newNodeId).LockedTablets.insert(this);
+ }
+ }
+ LockedToActor = actor;
+ }
+ LockedReconnectTimeout = timeout;
+ PendingUnlockSeqNo = 0;
+ return previousOwner;
+}
+
void TLeaderTabletInfo::AcquireAllocationUnits() {
- for (ui32 channel = 0; channel < TabletStorageInfo->Channels.size(); ++channel) {
- AcquireAllocationUnit(channel);
- }
-}
-
+ for (ui32 channel = 0; channel < TabletStorageInfo->Channels.size(); ++channel) {
+ AcquireAllocationUnit(channel);
+ }
+}
+
void TLeaderTabletInfo::ReleaseAllocationUnits() {
- for (ui32 channel = 0; channel < TabletStorageInfo->Channels.size(); ++channel) {
- ReleaseAllocationUnit(channel);
- }
-}
-
+ for (ui32 channel = 0; channel < TabletStorageInfo->Channels.size(); ++channel) {
+ ReleaseAllocationUnit(channel);
+ }
+}
+
bool TLeaderTabletInfo::AcquireAllocationUnit(ui32 channelId) {
- if (channelId < TabletStorageInfo->Channels.size()) {
- const TTabletChannelInfo& channel = TabletStorageInfo->Channels[channelId];
- if (!channel.History.empty()) {
- TStoragePoolInfo& storagePool = Hive.GetStoragePool(GetChannelStoragePoolName(channel));
- return storagePool.AcquireAllocationUnit(this, channel.Channel, channel.History.back().GroupID);
- }
- }
- return false;
-}
-
+ if (channelId < TabletStorageInfo->Channels.size()) {
+ const TTabletChannelInfo& channel = TabletStorageInfo->Channels[channelId];
+ if (!channel.History.empty()) {
+ TStoragePoolInfo& storagePool = Hive.GetStoragePool(GetChannelStoragePoolName(channel));
+ return storagePool.AcquireAllocationUnit(this, channel.Channel, channel.History.back().GroupID);
+ }
+ }
+ return false;
+}
+
bool TLeaderTabletInfo::ReleaseAllocationUnit(ui32 channelId) {
- if (channelId < TabletStorageInfo->Channels.size()) {
- const TTabletChannelInfo& channel = TabletStorageInfo->Channels[channelId];
- if (!channel.History.empty()) {
- TStoragePoolInfo& storagePool = Hive.GetStoragePool(GetChannelStoragePoolName(channel));
- return storagePool.ReleaseAllocationUnit(this, channel.Channel, channel.History.back().GroupID);
- }
- }
- return false;
-}
-
+ if (channelId < TabletStorageInfo->Channels.size()) {
+ const TTabletChannelInfo& channel = TabletStorageInfo->Channels[channelId];
+ if (!channel.History.empty()) {
+ TStoragePoolInfo& storagePool = Hive.GetStoragePool(GetChannelStoragePoolName(channel));
+ return storagePool.ReleaseAllocationUnit(this, channel.Channel, channel.History.back().GroupID);
+ }
+ }
+ return false;
+}
+
const NKikimrBlobStorage::TEvControllerSelectGroupsResult::TGroupParameters* TLeaderTabletInfo::FindFreeAllocationUnit(ui32 channelId) {
- TStoragePoolInfo* storagePool = Hive.FindStoragePool(GetChannelStoragePoolName(channelId));
- if (storagePool != nullptr) {
- THolder<NKikimrBlobStorage::TEvControllerSelectGroups::TGroupParameters> params = Hive.BuildGroupParametersForChannel(*this, channelId);
- const TStorageGroupInfo* currentGroup = nullptr;
-
- // searching for last change of this channel
- if (TabletStorageInfo && TabletStorageInfo->Channels.size() > channelId && !TabletStorageInfo->Channels[channelId].History.empty()) {
- TTabletChannelInfo::THistoryEntry& lastHistory = TabletStorageInfo->Channels[channelId].History.back();
- auto itGroup = storagePool->Groups.find(lastHistory.GroupID);
- if (itGroup != storagePool->Groups.end()) {
- currentGroup = &itGroup->second;
- }
- }
-
- switch (ChannelProfileReassignReason) {
- default:
- case NKikimrHive::TEvReassignTablet::HIVE_REASSIGN_REASON_NO: {
- return storagePool->FindFreeAllocationUnit([params = *params, currentGroup](const TStorageGroupInfo& newGroup) -> bool {
- if (newGroup.IsMatchesParameters(params)) {
- if (currentGroup) {
- return newGroup.Id != currentGroup->Id;
- }
- return true;
- }
- return false;
- });
- break;
- }
- case NKikimrHive::TEvReassignTablet::HIVE_REASSIGN_REASON_SPACE: {
- NKikimrConfig::THiveConfig::EHiveStorageBalanceStrategy balanceStrategy = Hive.CurrentConfig.GetStorageBalanceStrategy();
- Hive.CurrentConfig.SetStorageBalanceStrategy(NKikimrConfig::THiveConfig::HIVE_STORAGE_BALANCE_STRATEGY_SIZE);
- auto result = storagePool->FindFreeAllocationUnit([params = *params, currentGroup](const TStorageGroupInfo& newGroup) -> bool {
- if (newGroup.IsMatchesParameters(params)) {
- if (currentGroup) {
- return newGroup.Id != currentGroup->Id
- && newGroup.GroupParameters.GetAvailableSize() >= currentGroup->GroupParameters.GetAvailableSize();
- }
- return true;
- }
- return false;
- });
- Hive.CurrentConfig.SetStorageBalanceStrategy(balanceStrategy);
- return result;
- break;
- }
- }
- }
- return nullptr;
-}
-
+ TStoragePoolInfo* storagePool = Hive.FindStoragePool(GetChannelStoragePoolName(channelId));
+ if (storagePool != nullptr) {
+ THolder<NKikimrBlobStorage::TEvControllerSelectGroups::TGroupParameters> params = Hive.BuildGroupParametersForChannel(*this, channelId);
+ const TStorageGroupInfo* currentGroup = nullptr;
+
+ // searching for last change of this channel
+ if (TabletStorageInfo && TabletStorageInfo->Channels.size() > channelId && !TabletStorageInfo->Channels[channelId].History.empty()) {
+ TTabletChannelInfo::THistoryEntry& lastHistory = TabletStorageInfo->Channels[channelId].History.back();
+ auto itGroup = storagePool->Groups.find(lastHistory.GroupID);
+ if (itGroup != storagePool->Groups.end()) {
+ currentGroup = &itGroup->second;
+ }
+ }
+
+ switch (ChannelProfileReassignReason) {
+ default:
+ case NKikimrHive::TEvReassignTablet::HIVE_REASSIGN_REASON_NO: {
+ return storagePool->FindFreeAllocationUnit([params = *params, currentGroup](const TStorageGroupInfo& newGroup) -> bool {
+ if (newGroup.IsMatchesParameters(params)) {
+ if (currentGroup) {
+ return newGroup.Id != currentGroup->Id;
+ }
+ return true;
+ }
+ return false;
+ });
+ break;
+ }
+ case NKikimrHive::TEvReassignTablet::HIVE_REASSIGN_REASON_SPACE: {
+ NKikimrConfig::THiveConfig::EHiveStorageBalanceStrategy balanceStrategy = Hive.CurrentConfig.GetStorageBalanceStrategy();
+ Hive.CurrentConfig.SetStorageBalanceStrategy(NKikimrConfig::THiveConfig::HIVE_STORAGE_BALANCE_STRATEGY_SIZE);
+ auto result = storagePool->FindFreeAllocationUnit([params = *params, currentGroup](const TStorageGroupInfo& newGroup) -> bool {
+ if (newGroup.IsMatchesParameters(params)) {
+ if (currentGroup) {
+ return newGroup.Id != currentGroup->Id
+ && newGroup.GroupParameters.GetAvailableSize() >= currentGroup->GroupParameters.GetAvailableSize();
+ }
+ return true;
+ }
+ return false;
+ });
+ Hive.CurrentConfig.SetStorageBalanceStrategy(balanceStrategy);
+ return result;
+ break;
+ }
+ }
+ }
+ return nullptr;
+}
+
TString TLeaderTabletInfo::GetChannelStoragePoolName(const TTabletChannelInfo& channel) {
- return channel.StoragePool.empty() ? DEFAULT_STORAGE_POOL_NAME : channel.StoragePool;
-}
-
+ return channel.StoragePool.empty() ? DEFAULT_STORAGE_POOL_NAME : channel.StoragePool;
+}
+
TString TLeaderTabletInfo::GetChannelStoragePoolName(const TChannelProfiles::TProfile::TChannel& channel) {
- return channel.PoolKind.empty() ? DEFAULT_STORAGE_POOL_NAME : channel.PoolKind;
-}
-
+ return channel.PoolKind.empty() ? DEFAULT_STORAGE_POOL_NAME : channel.PoolKind;
+}
+
TString TLeaderTabletInfo::GetChannelStoragePoolName(ui32 channelId) {
- if (BoundChannels.size() > channelId) {
- return BoundChannels[channelId].GetStoragePoolName();
- }
- if (TabletStorageInfo && TabletStorageInfo->Channels.size() > channelId) {
- return GetChannelStoragePoolName(TabletStorageInfo->Channels[channelId]);
- }
- return DEFAULT_STORAGE_POOL_NAME;
-}
-
+ if (BoundChannels.size() > channelId) {
+ return BoundChannels[channelId].GetStoragePoolName();
+ }
+ if (TabletStorageInfo && TabletStorageInfo->Channels.size() > channelId) {
+ return GetChannelStoragePoolName(TabletStorageInfo->Channels[channelId]);
+ }
+ return DEFAULT_STORAGE_POOL_NAME;
+}
+
TStoragePoolInfo& TLeaderTabletInfo::GetStoragePool(ui32 channelId) {
- TStoragePoolInfo& storagePool = Hive.GetStoragePool(GetChannelStoragePoolName(channelId));
- return storagePool;
-}
-
+ TStoragePoolInfo& storagePool = Hive.GetStoragePool(GetChannelStoragePoolName(channelId));
+ return storagePool;
+}
+
void TLeaderTabletInfo::ActualizeTabletStatistics(TInstant now) {
- TTabletInfo::ActualizeTabletStatistics(now);
- for (TTabletInfo& follower : Followers) {
- follower.ActualizeTabletStatistics(now);
- }
-}
-
-}
-}
+ TTabletInfo::ActualizeTabletStatistics(now);
+ for (TTabletInfo& follower : Followers) {
+ follower.ActualizeTabletStatistics(now);
+ }
+}
+
+}
+}
diff --git a/ydb/core/mind/hive/leader_tablet_info.h b/ydb/core/mind/hive/leader_tablet_info.h
index dae95d51b1a..88425b3caed 100644
--- a/ydb/core/mind/hive/leader_tablet_info.h
+++ b/ydb/core/mind/hive/leader_tablet_info.h
@@ -1,319 +1,319 @@
-#pragma once
-
-#include "hive.h"
-#include "tablet_info.h"
+#pragma once
+
+#include "hive.h"
+#include "tablet_info.h"
#include "follower_tablet_info.h"
-
-namespace NKikimr {
-namespace NHive {
-
-struct TTabletCategoryInfo {
- TTabletCategoryId Id;
+
+namespace NKikimr {
+namespace NHive {
+
+struct TTabletCategoryInfo {
+ TTabletCategoryId Id;
std::unordered_set<TLeaderTabletInfo*> Tablets;
- ui64 MaxDisconnectTimeout = 0;
- bool StickTogetherInDC = false;
-
- TTabletCategoryInfo(TTabletCategoryId id)
- : Id(id)
- {}
-};
-
-struct TStoragePoolInfo;
-
+ ui64 MaxDisconnectTimeout = 0;
+ bool StickTogetherInDC = false;
+
+ TTabletCategoryInfo(TTabletCategoryId id)
+ : Id(id)
+ {}
+};
+
+struct TStoragePoolInfo;
+
struct TLeaderTabletInfo : TTabletInfo {
-protected:
- static TString DEFAULT_STORAGE_POOL_NAME;
-
-public:
- TTabletId Id;
- ETabletState State;
- TTabletTypes::EType Type;
- TObjectId ObjectId;
- TSubDomainKey ObjectDomain;
- TVector<TNodeId> AllowedNodes;
- TVector<TDataCenterId> AllowedDataCenters;
- NKikimrHive::TDataCentersPreference DataCentersPreference;
- TIntrusivePtr<TTabletStorageInfo> TabletStorageInfo;
- TChannelsBindings BoundChannels;
- std::bitset<MAX_TABLET_CHANNELS> ChannelProfileNewGroup;
- NKikimrHive::TEvReassignTablet::EHiveReassignReason ChannelProfileReassignReason;
- ui32 KnownGeneration;
- TTabletCategoryInfo* Category;
+protected:
+ static TString DEFAULT_STORAGE_POOL_NAME;
+
+public:
+ TTabletId Id;
+ ETabletState State;
+ TTabletTypes::EType Type;
+ TObjectId ObjectId;
+ TSubDomainKey ObjectDomain;
+ TVector<TNodeId> AllowedNodes;
+ TVector<TDataCenterId> AllowedDataCenters;
+ NKikimrHive::TDataCentersPreference DataCentersPreference;
+ TIntrusivePtr<TTabletStorageInfo> TabletStorageInfo;
+ TChannelsBindings BoundChannels;
+ std::bitset<MAX_TABLET_CHANNELS> ChannelProfileNewGroup;
+ NKikimrHive::TEvReassignTablet::EHiveReassignReason ChannelProfileReassignReason;
+ ui32 KnownGeneration;
+ TTabletCategoryInfo* Category;
TList<TFollowerGroup> FollowerGroups;
TList<TFollowerTabletInfo> Followers;
- TOwnerIdxType::TValueType Owner;
- TVector<TSubDomainKey> EffectiveAllowedDomains; // AllowedDomains | ObjectDomain
- NKikimrHive::ETabletBootMode BootMode;
+ TOwnerIdxType::TValueType Owner;
+ TVector<TSubDomainKey> EffectiveAllowedDomains; // AllowedDomains | ObjectDomain
+ NKikimrHive::ETabletBootMode BootMode;
TVector<TActorId> StorageInfoSubscribers;
TActorId LockedToActor;
- TDuration LockedReconnectTimeout;
- ui64 PendingUnlockSeqNo;
-
- bool SeizedByChild = false; // transient state for migration - need to delete it later
- bool NeedToReleaseFromParent = false; // transient state for migration - need to delete it later
-
+ TDuration LockedReconnectTimeout;
+ ui64 PendingUnlockSeqNo;
+
+ bool SeizedByChild = false; // transient state for migration - need to delete it later
+ bool NeedToReleaseFromParent = false; // transient state for migration - need to delete it later
+
TLeaderTabletInfo(TTabletId id, THive& hive)
: TTabletInfo(ETabletRole::Leader, hive)
- , Id(id)
- , State(ETabletState::Unknown)
- , Type(TTabletTypes::TYPE_INVALID)
- , ObjectId(0)
- , ChannelProfileReassignReason(NKikimrHive::TEvReassignTablet::HIVE_REASSIGN_REASON_NO)
- , KnownGeneration(0)
- , Category(nullptr)
- , BootMode(NKikimrHive::TABLET_BOOT_MODE_DEFAULT)
- , PendingUnlockSeqNo(0)
- {}
-
- bool IsReadyToAssignGroups() const {
- return !SeizedByChild && !NeedToReleaseFromParent && State == ETabletState::GroupAssignment && !BoundChannels.empty();
- }
-
- bool IsReadyToWork() const {
- return !NeedToReleaseFromParent && State == ETabletState::ReadyToWork && !IsBootingSuppressed();
- }
-
- bool IsReadyToBoot() const {
- return IsReadyToWork() && TTabletInfo::IsReadyToBoot();
- }
-
- bool IsReadyToStart(TInstant now) const {
- return IsReadyToWork() && TTabletInfo::IsReadyToStart(now);
- }
-
- bool IsReadyToBlockStorage() const {
- return State == ETabletState::BlockStorage;
- }
-
- bool IsStarting() const {
- return IsReadyToWork() && TTabletInfo::IsStarting();
- }
-
- bool IsStartingOnNode(TNodeId nodeId) const {
- return IsReadyToWork() && TTabletInfo::IsStartingOnNode(nodeId);
- }
-
- bool IsRunning() const {
- return IsReadyToWork() && TTabletInfo::IsRunning();
- }
-
- bool IsAlive() const {
- return IsReadyToWork() && TTabletInfo::IsAlive();
- }
-
+ , Id(id)
+ , State(ETabletState::Unknown)
+ , Type(TTabletTypes::TYPE_INVALID)
+ , ObjectId(0)
+ , ChannelProfileReassignReason(NKikimrHive::TEvReassignTablet::HIVE_REASSIGN_REASON_NO)
+ , KnownGeneration(0)
+ , Category(nullptr)
+ , BootMode(NKikimrHive::TABLET_BOOT_MODE_DEFAULT)
+ , PendingUnlockSeqNo(0)
+ {}
+
+ bool IsReadyToAssignGroups() const {
+ return !SeizedByChild && !NeedToReleaseFromParent && State == ETabletState::GroupAssignment && !BoundChannels.empty();
+ }
+
+ bool IsReadyToWork() const {
+ return !NeedToReleaseFromParent && State == ETabletState::ReadyToWork && !IsBootingSuppressed();
+ }
+
+ bool IsReadyToBoot() const {
+ return IsReadyToWork() && TTabletInfo::IsReadyToBoot();
+ }
+
+ bool IsReadyToStart(TInstant now) const {
+ return IsReadyToWork() && TTabletInfo::IsReadyToStart(now);
+ }
+
+ bool IsReadyToBlockStorage() const {
+ return State == ETabletState::BlockStorage;
+ }
+
+ bool IsStarting() const {
+ return IsReadyToWork() && TTabletInfo::IsStarting();
+ }
+
+ bool IsStartingOnNode(TNodeId nodeId) const {
+ return IsReadyToWork() && TTabletInfo::IsStartingOnNode(nodeId);
+ }
+
+ bool IsRunning() const {
+ return IsReadyToWork() && TTabletInfo::IsRunning();
+ }
+
+ bool IsAlive() const {
+ return IsReadyToWork() && TTabletInfo::IsAlive();
+ }
+
bool IsAliveOnLocal(const TActorId& local) const {
- return IsReadyToWork() && TTabletInfo::IsAliveOnLocal(local);
- }
-
- bool IsDeleting() const {
- return State == ETabletState::Deleting;
- }
-
- bool IsSomeoneAliveOnNode(TNodeId nodeId) const;
-
- bool IsLockedToActor() const {
- return !!LockedToActor;
- }
-
- bool IsExternalBoot() const {
- return BootMode == NKikimrHive::TABLET_BOOT_MODE_EXTERNAL;
- }
-
- bool IsBootingSuppressed() const {
- return IsExternalBoot() || IsLockedToActor();
- }
-
- bool IsReadyToReassignTablet() const {
- return !SeizedByChild && State == ETabletState::ReadyToWork;
- }
-
+ return IsReadyToWork() && TTabletInfo::IsAliveOnLocal(local);
+ }
+
+ bool IsDeleting() const {
+ return State == ETabletState::Deleting;
+ }
+
+ bool IsSomeoneAliveOnNode(TNodeId nodeId) const;
+
+ bool IsLockedToActor() const {
+ return !!LockedToActor;
+ }
+
+ bool IsExternalBoot() const {
+ return BootMode == NKikimrHive::TABLET_BOOT_MODE_EXTERNAL;
+ }
+
+ bool IsBootingSuppressed() const {
+ return IsExternalBoot() || IsLockedToActor();
+ }
+
+ bool IsReadyToReassignTablet() const {
+ return !SeizedByChild && State == ETabletState::ReadyToWork;
+ }
+
ui32 GetFollowersAliveOnDataCenter(TDataCenterId dataCenterId) const;
ui32 GetFollowersAliveOnDataCenterExcludingFollower(TDataCenterId dataCenterId, const TTabletInfo& excludingFollower) const;
-
+
TPathId GetTenant() const;
- bool IsAllAlive() const {
- if (!IsAlive())
- return false;
+ bool IsAllAlive() const {
+ if (!IsAlive())
+ return false;
for (const TTabletInfo& follower : Followers) {
if (!follower.IsAlive())
- return false;
- }
- return true;
- }
-
- bool IsSomeoneAlive() const {
- if (IsAlive())
- return true;
+ return false;
+ }
+ return true;
+ }
+
+ bool IsSomeoneAlive() const {
+ if (IsAlive())
+ return true;
for (const TTabletInfo& follower : Followers) {
if (follower.IsAlive())
- return true;
- }
- return false;
- }
-
+ return true;
+ }
+ return false;
+ }
+
bool IsSomeFollowerAlive() const {
for (const TTabletInfo& follower : Followers) {
if (follower.IsAlive())
- return true;
- }
- return false;
- }
-
+ return true;
+ }
+ return false;
+ }
+
bool HaveFollowers() const {
return !Followers.empty();
- }
-
+ }
+
bool IsFollowerPromotableOnNode(TNodeId nodeId) const;
TFollowerId GetFollowerPromotableOnNode(TNodeId nodeId) const;
-
- void AssignDomains(const TSubDomainKey& objectDomain, const TVector<TSubDomainKey>& allowedDomains);
-
- bool TryToBoot() {
- bool boot = false;
- if (IsReadyToBoot()) {
- boot |= InitiateBoot();
- }
+
+ void AssignDomains(const TSubDomainKey& objectDomain, const TVector<TSubDomainKey>& allowedDomains);
+
+ bool TryToBoot() {
+ bool boot = false;
+ if (IsReadyToBoot()) {
+ boot |= InitiateBoot();
+ }
if (HaveFollowers()) {
boot |= InitiateFollowersBoot();
- }
- return boot;
- }
-
- bool InitiateAssignTabletGroups();
-
+ }
+ return boot;
+ }
+
+ bool InitiateAssignTabletGroups();
+
bool InitiateFollowersBoot() {
- bool result = false;
- if (IsReadyToWork()) {
+ bool result = false;
+ if (IsReadyToWork()) {
for (TFollowerTabletInfo& follower : Followers) {
if (follower.IsReadyToBoot()) {
result |= follower.InitiateBoot();
- }
- }
- }
- return result;
- }
-
- void Kill() {
+ }
+ }
+ }
+ return result;
+ }
+
+ void Kill() {
for (TFollowerTabletInfo& follower : Followers) {
follower.Kill();
- }
- TTabletInfo::Kill();
- }
-
- bool InitiateBlockStorage();
- bool InitiateBlockStorage(ui32 generation);
- bool InitiateDeleteStorage();
-
- void IncreaseGeneration() {
- Y_VERIFY(KnownGeneration < Max<ui32>());
- ++KnownGeneration;
- }
-
+ }
+ TTabletInfo::Kill();
+ }
+
+ bool InitiateBlockStorage();
+ bool InitiateBlockStorage(ui32 generation);
+ bool InitiateDeleteStorage();
+
+ void IncreaseGeneration() {
+ Y_VERIFY(KnownGeneration < Max<ui32>());
+ ++KnownGeneration;
+ }
+
const TTabletInfo* FindTablet(TFollowerId followerId) const { // get leader or follower tablet depending on followerId
if (followerId == 0) {
return this; // leader
- }
+ }
auto it = std::find_if(Followers.begin(), Followers.end(), [followerId](const TFollowerTabletInfo& info) -> bool {
return info.Id == followerId;
- });
+ });
if (it != Followers.end()) {
- return &(*it);
- }
- return nullptr;
- }
-
+ return &(*it);
+ }
+ return nullptr;
+ }
+
const TTabletInfo& GetTablet(TFollowerId followerId) const { // get leader or follower tablet depending on followerId
const TTabletInfo* tablet = FindTablet(followerId);
- if (tablet != nullptr) {
- return *tablet;
- }
+ if (tablet != nullptr) {
+ return *tablet;
+ }
return *this; // leader by default
- }
-
+ }
+
TTabletInfo* FindTablet(TFollowerId followerId) { // get leader or follower tablet depending on followerId
return const_cast<TTabletInfo*>(static_cast<const TLeaderTabletInfo*>(this)->FindTablet(followerId));
- }
-
+ }
+
TTabletInfo& GetTablet(TFollowerId followerId) { // get leader or follower tablet depending on followerId
return const_cast<TTabletInfo&>(static_cast<const TLeaderTabletInfo&>(*this).GetTablet(followerId));
- }
-
+ }
+
TFollowerTabletInfo& SpawnFollower(TFollowerGroup& followerGroup) {
TFollowerTabletInfo& follower = AddFollower(followerGroup);
follower.BecomeStopped();
return follower;
- }
-
- template <template <typename, typename...> class Cont, typename Type, typename... Types>
- static decltype(Type::Id) GenerateId(const Cont<Type, Types...>& items) {
- decltype(Type::Id) id = 1;
- bool retry;
- do {
- retry = false;
- for (const auto& item : items) {
- if (item.Id == id) {
- ++id;
- retry = true;
- }
- }
- } while (retry);
- return id;
- }
-
+ }
+
+ template <template <typename, typename...> class Cont, typename Type, typename... Types>
+ static decltype(Type::Id) GenerateId(const Cont<Type, Types...>& items) {
+ decltype(Type::Id) id = 1;
+ bool retry;
+ do {
+ retry = false;
+ for (const auto& item : items) {
+ if (item.Id == id) {
+ ++id;
+ retry = true;
+ }
+ }
+ } while (retry);
+ return id;
+ }
+
TFollowerId GenerateFollowerId() const {
return GenerateId(Followers);
- }
-
+ }
+
TFollowerTabletInfo& AddFollower(TFollowerGroup& followerGroup, TFollowerId followerId = 0);
TFollowerGroupId GenerateFollowerGroupId() const;
TFollowerGroup& AddFollowerGroup(TFollowerGroupId followerGroupId = 0);
-
+
TFollowerGroup& GetFollowerGroup(TFollowerGroupId followerGroupId) {
auto it = std::find(FollowerGroups.begin(), FollowerGroups.end(), followerGroupId);
Y_VERIFY(it != FollowerGroups.end(), "%s", (TStringBuilder()
- << "TabletId=" << Id
+ << "TabletId=" << Id
<< " FollowerGroupId=" << followerGroupId
<< " FollowerGroupSize=" << FollowerGroups.size()
<< " FollowersSize=" << Followers.size()).data());
- return *it;
- }
-
- void NotifyStorageInfo(const TActorContext& ctx) {
+ return *it;
+ }
+
+ void NotifyStorageInfo(const TActorContext& ctx) {
TVector<TActorId> targets;
- targets.swap(StorageInfoSubscribers);
+ targets.swap(StorageInfoSubscribers);
for (TActorId target : targets) {
- ctx.Send(target, new TEvHive::TEvGetTabletStorageInfoResult(Id, *TabletStorageInfo));
- }
- }
-
+ ctx.Send(target, new TEvHive::TEvGetTabletStorageInfoResult(Id, *TabletStorageInfo));
+ }
+ }
+
TActorId SetLockedToActor(const TActorId& actor, const TDuration& timeout);
-
+
TActorId ClearLockedToActor() {
return SetLockedToActor(TActorId(), TDuration());
- }
-
- void ActualizeTabletStatistics(TInstant now);
-
- void ResetTabletGroupsRequests() {
- ChannelProfileNewGroup.reset();
- }
-
- ui32 GetChannelCount() const {
- return BoundChannels.size();
- }
-
- void AcquireAllocationUnits();
- void ReleaseAllocationUnits();
- bool AcquireAllocationUnit(ui32 channelId);
- bool ReleaseAllocationUnit(ui32 channelId);
- const NKikimrBlobStorage::TEvControllerSelectGroupsResult::TGroupParameters* FindFreeAllocationUnit(ui32 channelId);
- TString GetChannelStoragePoolName(const TTabletChannelInfo& channel);
- TString GetChannelStoragePoolName(const TChannelProfiles::TProfile::TChannel& channel);
- TString GetChannelStoragePoolName(ui32 channelId);
- TStoragePoolInfo& GetStoragePool(ui32 channelId);
-};
-
-} // NHive
-} // NKikimr
-
+ }
+
+ void ActualizeTabletStatistics(TInstant now);
+
+ void ResetTabletGroupsRequests() {
+ ChannelProfileNewGroup.reset();
+ }
+
+ ui32 GetChannelCount() const {
+ return BoundChannels.size();
+ }
+
+ void AcquireAllocationUnits();
+ void ReleaseAllocationUnits();
+ bool AcquireAllocationUnit(ui32 channelId);
+ bool ReleaseAllocationUnit(ui32 channelId);
+ const NKikimrBlobStorage::TEvControllerSelectGroupsResult::TGroupParameters* FindFreeAllocationUnit(ui32 channelId);
+ TString GetChannelStoragePoolName(const TTabletChannelInfo& channel);
+ TString GetChannelStoragePoolName(const TChannelProfiles::TProfile::TChannel& channel);
+ TString GetChannelStoragePoolName(ui32 channelId);
+ TStoragePoolInfo& GetStoragePool(ui32 channelId);
+};
+
+} // NHive
+} // NKikimr
+
diff --git a/ydb/core/mind/hive/metrics.h b/ydb/core/mind/hive/metrics.h
index 18433a33d18..bd1c05eae56 100644
--- a/ydb/core/mind/hive/metrics.h
+++ b/ydb/core/mind/hive/metrics.h
@@ -1,18 +1,18 @@
-#pragma once
-
+#pragma once
+
#include <ydb/core/util/metrics.h>
-#include "hive_schema.h"
-
-namespace NKikimr {
-namespace NHive {
-
-using TMetricsMaximum = NMetrics::TMaximumValueVariableWindowUI64;
-
-struct TTabletMetricsAggregates {
- TMetricsMaximum MaximumCPU;
- TMetricsMaximum MaximumMemory;
- TMetricsMaximum MaximumNetwork;
-};
-
-}
-}
+#include "hive_schema.h"
+
+namespace NKikimr {
+namespace NHive {
+
+using TMetricsMaximum = NMetrics::TMaximumValueVariableWindowUI64;
+
+struct TTabletMetricsAggregates {
+ TMetricsMaximum MaximumCPU;
+ TMetricsMaximum MaximumMemory;
+ TMetricsMaximum MaximumNetwork;
+};
+
+}
+}
diff --git a/ydb/core/mind/hive/monitoring.cpp b/ydb/core/mind/hive/monitoring.cpp
index 9dbfea8fa08..7e9a83b354e 100644
--- a/ydb/core/mind/hive/monitoring.cpp
+++ b/ydb/core/mind/hive/monitoring.cpp
@@ -1,24 +1,24 @@
#include <library/cpp/monlib/service/pages/templates.h>
#include <library/cpp/json/json_writer.h>
-#include <library/cpp/protobuf/json/proto2json.h>
-#include <util/string/vector.h>
+#include <library/cpp/protobuf/json/proto2json.h>
+#include <util/string/vector.h>
#include <ydb/core/tablet_flat/flat_executor_counters.h>
#include <ydb/core/protos/counters_keyvalue.pb.h>
-#include "hive_impl.h"
-#include "hive_transactions.h"
-#include "hive_schema.h"
-#include "hive_log.h"
-
+#include "hive_impl.h"
+#include "hive_transactions.h"
+#include "hive_schema.h"
+#include "hive_log.h"
+
namespace NKikimr {
-namespace NHive {
+namespace NHive {
-class TTxMonEvent_DbState : public TTransactionBase<THive> {
+class TTxMonEvent_DbState : public TTransactionBase<THive> {
public:
struct TTabletInfo {
ui32 KnownGeneration;
ui32 TabletType;
ui32 LeaderNode;
- ETabletState TabletState;
+ ETabletState TabletState;
};
struct TNodeInfo {
@@ -40,43 +40,43 @@ public:
, Source(source)
{}
- TTxType GetTxType() const override { return NHive::TXTYPE_MON_DB_STATE; }
-
- bool Execute(TTransactionContext &txc, const TActorContext& ctx) override {
+ TTxType GetTxType() const override { return NHive::TXTYPE_MON_DB_STATE; }
+
+ bool Execute(TTransactionContext &txc, const TActorContext& ctx) override {
TabletInfo.clear();
NodeInfo.clear();
- NIceDb::TNiceDb db(txc.DB);
-
- { // read tablets from DB
- auto rowset = db.Table<Schema::Tablet>().Range().Select();
- if (!rowset.IsReady())
- return false;
- while (rowset.IsValid()) {
- const ui64 tabletId = rowset.GetValue<Schema::Tablet::ID>();
- const ui32 knownGen = rowset.GetValue<Schema::Tablet::KnownGeneration>();
- const ui32 type = rowset.GetValue<Schema::Tablet::TabletType>();
+ NIceDb::TNiceDb db(txc.DB);
+
+ { // read tablets from DB
+ auto rowset = db.Table<Schema::Tablet>().Range().Select();
+ if (!rowset.IsReady())
+ return false;
+ while (rowset.IsValid()) {
+ const ui64 tabletId = rowset.GetValue<Schema::Tablet::ID>();
+ const ui32 knownGen = rowset.GetValue<Schema::Tablet::KnownGeneration>();
+ const ui32 type = rowset.GetValue<Schema::Tablet::TabletType>();
const ui32 leaderNode = rowset.GetValue<Schema::Tablet::LeaderNode>();
- const ETabletState tabletState = rowset.GetValue<Schema::Tablet::State>();
+ const ETabletState tabletState = rowset.GetValue<Schema::Tablet::State>();
TabletInfo[tabletId] = {knownGen, type, leaderNode, tabletState};
++NodeInfo[leaderNode].TabletsOn; // leaderNode could be zero, then - counter of tablets w/o leader node
- if (!rowset.Next())
- return false;
+ if (!rowset.Next())
+ return false;
}
}
// read nodes
{
- auto rowset = db.Table<Schema::Node>().Range().Select();
- if (!rowset.IsReady())
- return false;
- while (rowset.IsValid()) {
- const ui32 nodeId = rowset.GetValue<Schema::Node::ID>();
+ auto rowset = db.Table<Schema::Node>().Range().Select();
+ if (!rowset.IsReady())
+ return false;
+ while (rowset.IsValid()) {
+ const ui32 nodeId = rowset.GetValue<Schema::Node::ID>();
const TActorId local = rowset.GetValue<Schema::Node::Local>();
NodeInfo[nodeId].Local = local;
- if (!rowset.Next())
- return false;
+ if (!rowset.Next())
+ return false;
}
}
@@ -87,7 +87,7 @@ public:
return true;
}
- void Complete(const TActorContext& ctx) override {
+ void Complete(const TActorContext& ctx) override {
Y_UNUSED(ctx);
}
@@ -95,10 +95,10 @@ public:
HTML(out) {
UL_CLASS("nav nav-tabs") {
LI_CLASS("active") {
- out << "<a href=\"#known-tablets\" data-toggle=\"tab\">Tablets</a>";
+ out << "<a href=\"#known-tablets\" data-toggle=\"tab\">Tablets</a>";
}
LI() {
- out << "<a href=\"#per-node-stats\" data-toggle=\"tab\">Nodes</a>";
+ out << "<a href=\"#per-node-stats\" data-toggle=\"tab\">Nodes</a>";
}
}
DIV_CLASS("tab-content") {
@@ -115,15 +115,15 @@ public:
}
}
TABLEBODY() {
- ui64 index = 0;
+ ui64 index = 0;
for (const auto &tabletPair : TabletInfo) {
const ui64 tabletId = tabletPair.first;
const auto &x = tabletPair.second;
TABLER() {
- out << "<td data-text='" << index << "'>" << "<a href=\"../tablets?TabletID="
+ out << "<td data-text='" << index << "'>" << "<a href=\"../tablets?TabletID="
<< tabletId << "\">"
<< TTabletTypes::TypeToStr((TTabletTypes::EType)x.TabletType)
- << "</a></td>";
+ << "</a></td>";
TABLED() {out << tabletId;}
TABLED() {out << x.KnownGeneration;}
TABLED_CLASS(x.LeaderNode ? "" : "warning")
@@ -131,11 +131,11 @@ public:
TABLED() {out << ETabletStateName(x.TabletState);}
TABLED() {out << " <a href=\"../tablets?SsId="
<< tabletId << "\">"
- << "<span class=\"glyphicon glyphicon-tasks\""
- << " title=\"State Storage\"/>"
+ << "<span class=\"glyphicon glyphicon-tasks\""
+ << " title=\"State Storage\"/>"
<< "</a>";}
}
- ++index;
+ ++index;
}
}
}
@@ -149,941 +149,941 @@ public:
}
}
TABLEBODY() {
- for (const auto &nodePair : NodeInfo) {
- const ui32 nodeId = nodePair.first;
- const auto &x = nodePair.second;
- if (nodeId != 0 || x.Local) {
+ for (const auto &nodePair : NodeInfo) {
+ const ui32 nodeId = nodePair.first;
+ const auto &x = nodePair.second;
+ if (nodeId != 0 || x.Local) {
TABLER() {
- if (nodeId == 0) {
+ if (nodeId == 0) {
TABLED_CLASS("danger") {out << "w/o leader node"; }
- } else {
+ } else {
TABLED() {out << nodeId; }
- }
- if (x.Local) {
+ }
+ if (x.Local) {
TABLED() {out << x.TabletsOn;}
- } else {
+ } else {
TABLED_CLASS("danger") {out << "down";}
- }
+ }
}
- }
- }
+ }
+ }
}
}
}
}
}
- }
-};
-
-class TTxMonEvent_MemStateTablets : public TTransactionBase<THive> {
-public:
+ }
+};
+
+class TTxMonEvent_MemStateTablets : public TTransactionBase<THive> {
+public:
const TActorId Source;
- THolder<NMon::TEvRemoteHttpInfo> Event;
- bool BadOnly = false;
- bool WaitingOnly = false;
- ui64 MaxCount = 0;
- TString Sort;
-
+ THolder<NMon::TEvRemoteHttpInfo> Event;
+ bool BadOnly = false;
+ bool WaitingOnly = false;
+ ui64 MaxCount = 0;
+ TString Sort;
+
TTxMonEvent_MemStateTablets(const TActorId &source, NMon::TEvRemoteHttpInfo::TPtr& ev, TSelf *hive)
- : TBase(hive)
- , Source(source)
- , Event(ev->Release())
- {}
-
- TTxType GetTxType() const override { return NHive::TXTYPE_MON_MEM_STATE; }
-
- bool Execute(TTransactionContext &txc, const TActorContext& ctx) override {
- const auto& params(Event->Cgi());
- if (params.contains("bad")) {
- BadOnly = FromStringWithDefault(params.Get("bad"), BadOnly);
- }
- if (params.contains("wait")) {
- WaitingOnly = FromStringWithDefault(params.Get("wait"), WaitingOnly);
- }
- if (params.contains("max")) {
- MaxCount = FromStringWithDefault(params.Get("max"), MaxCount);
- }
- if (params.contains("sort")) {
- Sort = params.Get("sort");
- }
+ : TBase(hive)
+ , Source(source)
+ , Event(ev->Release())
+ {}
+
+ TTxType GetTxType() const override { return NHive::TXTYPE_MON_MEM_STATE; }
+
+ bool Execute(TTransactionContext &txc, const TActorContext& ctx) override {
+ const auto& params(Event->Cgi());
+ if (params.contains("bad")) {
+ BadOnly = FromStringWithDefault(params.Get("bad"), BadOnly);
+ }
+ if (params.contains("wait")) {
+ WaitingOnly = FromStringWithDefault(params.Get("wait"), WaitingOnly);
+ }
+ if (params.contains("max")) {
+ MaxCount = FromStringWithDefault(params.Get("max"), MaxCount);
+ }
+ if (params.contains("sort")) {
+ Sort = params.Get("sort");
+ }
Y_UNUSED(txc);
- TStringStream str;
- RenderHTMLPage(str);
- ctx.Send(Source, new NMon::TEvRemoteHttpInfoRes(str.Str()));
- return true;
- }
-
- void Complete(const TActorContext& ctx) override {
+ TStringStream str;
+ RenderHTMLPage(str);
+ ctx.Send(Source, new NMon::TEvRemoteHttpInfoRes(str.Str()));
+ return true;
+ }
+
+ void Complete(const TActorContext& ctx) override {
Y_UNUSED(ctx);
- }
-
- void RenderHTMLPage(IOutputStream &out) {
- TVector<std::pair<double, TTabletInfo*>> tabletIdIndex;
- std::function<double(const TTabletInfo&)> tabletIndexFunction;
- if (Sort == "weight") {
- tabletIndexFunction = [](const TTabletInfo& tablet) -> double { return -tablet.Weight; };
- } else {
- tabletIndexFunction = [](const TTabletInfo& tablet) -> double { return tablet.GetFullTabletId().first * 100 + tablet.GetFullTabletId().second; };
- }
- if (WaitingOnly) {
- tabletIdIndex.reserve(Self->BootQueue.WaitQueue.size());
- for (const TBootQueue::TBootQueueRecord& rec : Self->BootQueue.WaitQueue) {
- TTabletInfo* tablet = Self->FindTablet(rec.TabletId);
- if (tablet != nullptr) {
- tabletIdIndex.push_back({tabletIndexFunction(*tablet), tablet});
- }
- }
- } else {
- tabletIdIndex.reserve(Self->Tablets.size());
- for (auto& [tabletId, tablet] : Self->Tablets) {
- tabletIdIndex.push_back({tabletIndexFunction(tablet), &tablet});
- for (auto& follower : tablet.Followers) {
- tabletIdIndex.emplace_back(tabletIndexFunction(follower), &follower);
- }
- }
- }
- std::sort(tabletIdIndex.begin(), tabletIdIndex.end(), [](const auto& tab1, const auto& tab2) -> bool { return tab1.first < tab2.first; });
-
- out << "<script>$('.container').css('width', 'auto');</script>";
- out << "<table class='table table-sortable'>";
- out << "<thead>";
- out << "<tr><th>Tablet</th><th>ID</th><th>Generation</th><th>Node</th><th>State</th><th>VolatileState</th><th>LastAlive</th><th>Restarts</th><th>BootState</th><th>Weight</th><th>Resources</th>"
- << "<th>AllowedMetrics</th><th class='sorter-false'></th></tr>";
- out << "</thead>";
- out << "<tbody>";
- ui64 count = 0;
- for (const auto& tabletIdx : tabletIdIndex) {
- TTabletInfo& x = *tabletIdx.second;
- if (BadOnly) {
+ }
+
+ void RenderHTMLPage(IOutputStream &out) {
+ TVector<std::pair<double, TTabletInfo*>> tabletIdIndex;
+ std::function<double(const TTabletInfo&)> tabletIndexFunction;
+ if (Sort == "weight") {
+ tabletIndexFunction = [](const TTabletInfo& tablet) -> double { return -tablet.Weight; };
+ } else {
+ tabletIndexFunction = [](const TTabletInfo& tablet) -> double { return tablet.GetFullTabletId().first * 100 + tablet.GetFullTabletId().second; };
+ }
+ if (WaitingOnly) {
+ tabletIdIndex.reserve(Self->BootQueue.WaitQueue.size());
+ for (const TBootQueue::TBootQueueRecord& rec : Self->BootQueue.WaitQueue) {
+ TTabletInfo* tablet = Self->FindTablet(rec.TabletId);
+ if (tablet != nullptr) {
+ tabletIdIndex.push_back({tabletIndexFunction(*tablet), tablet});
+ }
+ }
+ } else {
+ tabletIdIndex.reserve(Self->Tablets.size());
+ for (auto& [tabletId, tablet] : Self->Tablets) {
+ tabletIdIndex.push_back({tabletIndexFunction(tablet), &tablet});
+ for (auto& follower : tablet.Followers) {
+ tabletIdIndex.emplace_back(tabletIndexFunction(follower), &follower);
+ }
+ }
+ }
+ std::sort(tabletIdIndex.begin(), tabletIdIndex.end(), [](const auto& tab1, const auto& tab2) -> bool { return tab1.first < tab2.first; });
+
+ out << "<script>$('.container').css('width', 'auto');</script>";
+ out << "<table class='table table-sortable'>";
+ out << "<thead>";
+ out << "<tr><th>Tablet</th><th>ID</th><th>Generation</th><th>Node</th><th>State</th><th>VolatileState</th><th>LastAlive</th><th>Restarts</th><th>BootState</th><th>Weight</th><th>Resources</th>"
+ << "<th>AllowedMetrics</th><th class='sorter-false'></th></tr>";
+ out << "</thead>";
+ out << "<tbody>";
+ ui64 count = 0;
+ for (const auto& tabletIdx : tabletIdIndex) {
+ TTabletInfo& x = *tabletIdx.second;
+ if (BadOnly) {
if (x.IsAlive() || x.GetLeader().IsExternalBoot()) {
- continue;
- }
- if (x.IsLeader() && x.AsLeader().Type == TTabletTypes::BlockStoreVolume && x.IsStopped()) {
- continue;
- }
- }
- ++count;
- if (MaxCount != 0 && count > MaxCount) {
- break;
- }
- TFullTabletId tabletId = x.GetFullTabletId();
- x.UpdateWeight();
- out << "<tr>";
+ continue;
+ }
+ if (x.IsLeader() && x.AsLeader().Type == TTabletTypes::BlockStoreVolume && x.IsStopped()) {
+ continue;
+ }
+ }
+ ++count;
+ if (MaxCount != 0 && count > MaxCount) {
+ break;
+ }
+ TFullTabletId tabletId = x.GetFullTabletId();
+ x.UpdateWeight();
+ out << "<tr>";
out << "<td data-text='" << TTabletTypes::TypeToStr(x.GetLeader().Type) << "'><a href=\"../tablets?TabletID="
- << tabletId.first << "\">"
+ << tabletId.first << "\">"
<< TTabletTypes::TypeToStr(x.GetLeader().Type)
- << "</a></td>";
- out << "<td data-text='" << count << "'>" << tabletId.first << '.' << tabletId.second << "</td>";
+ << "</a></td>";
+ out << "<td data-text='" << count << "'>" << tabletId.first << '.' << tabletId.second << "</td>";
out << "<td style='text-align:right'>" << x.GetLeader().KnownGeneration << "</td>";
- out << "<td";
- if (x.NodeId == 0) {
- out << " class='warning'";
- }
- out << " style='text-align:right'>" << x.NodeId << "</td>";
+ out << "<td";
+ if (x.NodeId == 0) {
+ out << " class='warning'";
+ }
+ out << " style='text-align:right'>" << x.NodeId << "</td>";
out << "<td>" << ETabletStateName(x.GetLeader().State) << "</td>";
- out << "<td>" << TTabletInfo::EVolatileStateName(x.GetVolatileState()) << "</td>";
+ out << "<td>" << TTabletInfo::EVolatileStateName(x.GetVolatileState()) << "</td>";
if (x.IsLeader()) {
TLeaderTabletInfo& m(x.GetLeader());
- out << "<td>" << TInstant::MilliSeconds(m.Statistics.GetLastAliveTimestamp()).ToStringUpToSeconds() << "</td>";
- out << "<td style='text-align:right'>" << m.Statistics.RestartTimestampSize() << "</td>";
- } else {
- out << "<td>-</td>";
- out << "<td>-</td>";
- }
- out << "<td>" << x.BootState << "</td>";
- out << "<td>" << Sprintf("%.9f", x.Weight) << "</td>";
- out << "<td>" << GetResourceValuesText(x) << "</td>";
- out << "<td>" << x.GetTabletAllowedMetricIds() << "</td>";
- out << "<td><a href='../tablets?SsId=" << tabletId << "'><span class='glyphicon glyphicon-tasks' title='State Storage'/></a></td>";
- out << "</tr>";
- }
- out << "</tbody></table>";
- }
-};
-
-class TTxMonEvent_MemStateNodes : public TTransactionBase<THive> {
-public:
+ out << "<td>" << TInstant::MilliSeconds(m.Statistics.GetLastAliveTimestamp()).ToStringUpToSeconds() << "</td>";
+ out << "<td style='text-align:right'>" << m.Statistics.RestartTimestampSize() << "</td>";
+ } else {
+ out << "<td>-</td>";
+ out << "<td>-</td>";
+ }
+ out << "<td>" << x.BootState << "</td>";
+ out << "<td>" << Sprintf("%.9f", x.Weight) << "</td>";
+ out << "<td>" << GetResourceValuesText(x) << "</td>";
+ out << "<td>" << x.GetTabletAllowedMetricIds() << "</td>";
+ out << "<td><a href='../tablets?SsId=" << tabletId << "'><span class='glyphicon glyphicon-tasks' title='State Storage'/></a></td>";
+ out << "</tr>";
+ }
+ out << "</tbody></table>";
+ }
+};
+
+class TTxMonEvent_MemStateNodes : public TTransactionBase<THive> {
+public:
const TActorId Source;
- THolder<NMon::TEvRemoteHttpInfo> Event;
- bool BadOnly = false;
- ui64 MaxCount = 0;
-
+ THolder<NMon::TEvRemoteHttpInfo> Event;
+ bool BadOnly = false;
+ ui64 MaxCount = 0;
+
TTxMonEvent_MemStateNodes(const TActorId &source, NMon::TEvRemoteHttpInfo::TPtr& ev, TSelf *hive)
- : TBase(hive)
- , Source(source)
- , Event(ev->Release())
- {}
-
- TTxType GetTxType() const override { return NHive::TXTYPE_MON_MEM_STATE; }
-
- bool Execute(TTransactionContext &txc, const TActorContext& ctx) override {
- Y_UNUSED(txc);
- TStringStream str;
- RenderHTMLPage(str);
- ctx.Send(Source, new NMon::TEvRemoteHttpInfoRes(str.Str()));
- return true;
- }
-
- void Complete(const TActorContext& ctx) override {
- Y_UNUSED(ctx);
- }
-
- void RenderHTMLPage(IOutputStream &out) {
- out << "<script>$('.container').css('width', 'auto');</script>";
- out << "<table class='table table-sortable'>";
- out << "<thead>";
- out << "<tr><th>NodeId</th><th>Local</th><th>Domains</th><th>TabletsScheduled</th><th>TabletsRunning</th>"
- "<th>Values</th><th>Total</th><th>Total</th><th>Maximum</th><th>VolatileState</th><th>Location</th><th>LastAlive</th><th>Restarts</th>"
- << "</tr>";
- out << "</thead>";
- out << "<tbody>";
- TVector<std::pair<TNodeId, const TNodeInfo*>> nodeIdIndex;
- for (auto& nodePair : Self->Nodes) {
- nodeIdIndex.emplace_back(nodePair.first, &nodePair.second);
- }
- Sort(nodeIdIndex);
- for (const auto& [nodeId, nodeInfoPtr] : nodeIdIndex) {
- const TNodeInfo& x = *nodeInfoPtr;
- out << "<tr>";
- out << "<td>" << nodeId << "</td>";
- out << "<td>" << x.Local << "</td>";
- out << "<td>" << x.ServicedDomains << "</td>";
- out << "<td>" << x.GetTabletsScheduled() << "</td>";
- out << "<td>" << x.GetTabletsTotal() - x.GetTabletsScheduled() << "</td>";
- out << "<td>" << GetResourceValuesText(x.ResourceValues) << "</td>";
- out << "<td>" << GetResourceValuesText(x.ResourceTotalValues) << "</td>";
- out << "<td>" << x.NodeTotalUsage << "</td>";
- out << "<td>" << GetResourceValuesText(x.ResourceMaximumValues) << "</td>";
- out << "<td>" << TNodeInfo::EVolatileStateName(x.GetVolatileState()) << "</td>";
- out << "<td>" << GetLocationString(x.Location) << "</td>";
- out << "<td>" << TInstant::MilliSeconds(x.Statistics.GetLastAliveTimestamp()).ToStringUpToSeconds() << "</td>";
- out << "<td>" << x.Statistics.RestartTimestampSize() << "</td>";
- out << "</tr>";
- }
- out << "</tbody>";
- out << "</table>";
+ : TBase(hive)
+ , Source(source)
+ , Event(ev->Release())
+ {}
+
+ TTxType GetTxType() const override { return NHive::TXTYPE_MON_MEM_STATE; }
+
+ bool Execute(TTransactionContext &txc, const TActorContext& ctx) override {
+ Y_UNUSED(txc);
+ TStringStream str;
+ RenderHTMLPage(str);
+ ctx.Send(Source, new NMon::TEvRemoteHttpInfoRes(str.Str()));
+ return true;
+ }
+
+ void Complete(const TActorContext& ctx) override {
+ Y_UNUSED(ctx);
+ }
+
+ void RenderHTMLPage(IOutputStream &out) {
+ out << "<script>$('.container').css('width', 'auto');</script>";
+ out << "<table class='table table-sortable'>";
+ out << "<thead>";
+ out << "<tr><th>NodeId</th><th>Local</th><th>Domains</th><th>TabletsScheduled</th><th>TabletsRunning</th>"
+ "<th>Values</th><th>Total</th><th>Total</th><th>Maximum</th><th>VolatileState</th><th>Location</th><th>LastAlive</th><th>Restarts</th>"
+ << "</tr>";
+ out << "</thead>";
+ out << "<tbody>";
+ TVector<std::pair<TNodeId, const TNodeInfo*>> nodeIdIndex;
+ for (auto& nodePair : Self->Nodes) {
+ nodeIdIndex.emplace_back(nodePair.first, &nodePair.second);
+ }
+ Sort(nodeIdIndex);
+ for (const auto& [nodeId, nodeInfoPtr] : nodeIdIndex) {
+ const TNodeInfo& x = *nodeInfoPtr;
+ out << "<tr>";
+ out << "<td>" << nodeId << "</td>";
+ out << "<td>" << x.Local << "</td>";
+ out << "<td>" << x.ServicedDomains << "</td>";
+ out << "<td>" << x.GetTabletsScheduled() << "</td>";
+ out << "<td>" << x.GetTabletsTotal() - x.GetTabletsScheduled() << "</td>";
+ out << "<td>" << GetResourceValuesText(x.ResourceValues) << "</td>";
+ out << "<td>" << GetResourceValuesText(x.ResourceTotalValues) << "</td>";
+ out << "<td>" << x.NodeTotalUsage << "</td>";
+ out << "<td>" << GetResourceValuesText(x.ResourceMaximumValues) << "</td>";
+ out << "<td>" << TNodeInfo::EVolatileStateName(x.GetVolatileState()) << "</td>";
+ out << "<td>" << GetLocationString(x.Location) << "</td>";
+ out << "<td>" << TInstant::MilliSeconds(x.Statistics.GetLastAliveTimestamp()).ToStringUpToSeconds() << "</td>";
+ out << "<td>" << x.Statistics.RestartTimestampSize() << "</td>";
+ out << "</tr>";
+ }
+ out << "</tbody>";
+ out << "</table>";
}
};
-class TTxMonEvent_MemStateDomains : public TTransactionBase<THive> {
-public:
- const TActorId Source;
- THolder<NMon::TEvRemoteHttpInfo> Event;
- bool BadOnly = false;
- ui64 MaxCount = 0;
-
- TTxMonEvent_MemStateDomains(const TActorId &source, NMon::TEvRemoteHttpInfo::TPtr& ev, TSelf *hive)
- : TBase(hive)
- , Source(source)
- , Event(ev->Release())
- {}
-
- TTxType GetTxType() const override { return NHive::TXTYPE_MON_MEM_STATE; }
-
- bool Execute(TTransactionContext &txc, const TActorContext& ctx) override {
- Y_UNUSED(txc);
- TStringStream str;
- RenderHTMLPage(str);
- ctx.Send(Source, new NMon::TEvRemoteHttpInfoRes(str.Str()));
- return true;
- }
-
- void Complete(const TActorContext& ctx) override {
- Y_UNUSED(ctx);
- }
-
- void RenderHTMLPage(IOutputStream &out) {
- // out << "<script>$('.container').css('width', 'auto');</script>";
- out << "<table class='table table-sortable'>";
- out << "<thead>";
- out << "<tr><th>TenantId</th><th>Name</th><th>Hive</th><th>Status</th></tr>";
- out << "</thead>";
- out << "<tbody>";
- for (const auto& [domainKey, domainInfo] : Self->Domains) {
- out << "<tr>";
- out << "<td>" << domainKey << "</td>";
- out << "<td>" << domainInfo.Path << "</td>";
- if (domainInfo.HiveId) {
- out << "<td><a href='app?TabletID=" << domainInfo.HiveId << "'>" << domainInfo.HiveId << "</a></td>";
- if (domainInfo.HiveId == Self->TabletID()) {
- out << "<td>itself</td>";
- } else {
+class TTxMonEvent_MemStateDomains : public TTransactionBase<THive> {
+public:
+ const TActorId Source;
+ THolder<NMon::TEvRemoteHttpInfo> Event;
+ bool BadOnly = false;
+ ui64 MaxCount = 0;
+
+ TTxMonEvent_MemStateDomains(const TActorId &source, NMon::TEvRemoteHttpInfo::TPtr& ev, TSelf *hive)
+ : TBase(hive)
+ , Source(source)
+ , Event(ev->Release())
+ {}
+
+ TTxType GetTxType() const override { return NHive::TXTYPE_MON_MEM_STATE; }
+
+ bool Execute(TTransactionContext &txc, const TActorContext& ctx) override {
+ Y_UNUSED(txc);
+ TStringStream str;
+ RenderHTMLPage(str);
+ ctx.Send(Source, new NMon::TEvRemoteHttpInfoRes(str.Str()));
+ return true;
+ }
+
+ void Complete(const TActorContext& ctx) override {
+ Y_UNUSED(ctx);
+ }
+
+ void RenderHTMLPage(IOutputStream &out) {
+ // out << "<script>$('.container').css('width', 'auto');</script>";
+ out << "<table class='table table-sortable'>";
+ out << "<thead>";
+ out << "<tr><th>TenantId</th><th>Name</th><th>Hive</th><th>Status</th></tr>";
+ out << "</thead>";
+ out << "<tbody>";
+ for (const auto& [domainKey, domainInfo] : Self->Domains) {
+ out << "<tr>";
+ out << "<td>" << domainKey << "</td>";
+ out << "<td>" << domainInfo.Path << "</td>";
+ if (domainInfo.HiveId) {
+ out << "<td><a href='app?TabletID=" << domainInfo.HiveId << "'>" << domainInfo.HiveId << "</a></td>";
+ if (domainInfo.HiveId == Self->TabletID()) {
+ out << "<td>itself</td>";
+ } else {
TLeaderTabletInfo* tablet = Self->FindTablet(domainInfo.HiveId);
- if (tablet) {
- out << "<td>" << tablet->StateString() << "</td>";
- } else {
- out << "<td>-</td>";
- }
- }
- } else {
- out << "<td>-</td>";
- out << "<td>-</td>";
- }
- out << "</tr>";
- }
- out << "</tbody>";
- out << "</table>";
- }
-};
-
-
+ if (tablet) {
+ out << "<td>" << tablet->StateString() << "</td>";
+ } else {
+ out << "<td>-</td>";
+ }
+ }
+ } else {
+ out << "<td>-</td>";
+ out << "<td>-</td>";
+ }
+ out << "</tr>";
+ }
+ out << "</tbody>";
+ out << "</table>";
+ }
+};
+
+
TString GetDurationString(TDuration duration) {
- int seconds = duration.Seconds();
- if (seconds < 60)
- return Sprintf("%ds", seconds);
- if (seconds < 3600)
- return Sprintf("%d:%02d", seconds / 60, seconds % 60);
- if (seconds < 86400)
- return Sprintf("%d:%02d:%02d", seconds / 3600, (seconds % 3600) / 60, seconds % 60);
- return Sprintf("%dd %02d:%02d:%02d", seconds / 86400, (seconds % 86400) / 3600, (seconds % 3600) / 60, seconds % 60);
-}
-
-class TTxMonEvent_Resources : public TTransactionBase<THive> {
-public:
+ int seconds = duration.Seconds();
+ if (seconds < 60)
+ return Sprintf("%ds", seconds);
+ if (seconds < 3600)
+ return Sprintf("%d:%02d", seconds / 60, seconds % 60);
+ if (seconds < 86400)
+ return Sprintf("%d:%02d:%02d", seconds / 3600, (seconds % 3600) / 60, seconds % 60);
+ return Sprintf("%dd %02d:%02d:%02d", seconds / 86400, (seconds % 86400) / 3600, (seconds % 3600) / 60, seconds % 60);
+}
+
+class TTxMonEvent_Resources : public TTransactionBase<THive> {
+public:
const TActorId Source;
- TAutoPtr<NMon::TEvRemoteHttpInfo> Event;
-
+ TAutoPtr<NMon::TEvRemoteHttpInfo> Event;
+
TTxMonEvent_Resources(const TActorId &source, NMon::TEvRemoteHttpInfo::TPtr& ev, TSelf *hive)
- : TBase(hive)
- , Source(source)
- , Event(ev->Release())
- {}
-
- TTxType GetTxType() const override { return NHive::TXTYPE_MON_RESOURCES; }
-
- bool Execute(TTransactionContext&, const TActorContext& ctx) override {
- TStringStream str;
- RenderHTMLPage(str, ctx);
- ctx.Send(Source, new NMon::TEvRemoteHttpInfoRes(str.Str()));
- return true;
- }
-
- void Complete(const TActorContext&) override {
- }
-
- void RenderHTMLPage(IOutputStream& out, const TActorContext&) {
+ : TBase(hive)
+ , Source(source)
+ , Event(ev->Release())
+ {}
+
+ TTxType GetTxType() const override { return NHive::TXTYPE_MON_RESOURCES; }
+
+ bool Execute(TTransactionContext&, const TActorContext& ctx) override {
+ TStringStream str;
+ RenderHTMLPage(str, ctx);
+ ctx.Send(Source, new NMon::TEvRemoteHttpInfoRes(str.Str()));
+ return true;
+ }
+
+ void Complete(const TActorContext&) override {
+ }
+
+ void RenderHTMLPage(IOutputStream& out, const TActorContext&) {
TVector<ui64> tabletIdIndex;
- tabletIdIndex.reserve(Self->Tablets.size());
- for (const auto &tabletPair : Self->Tablets) {
- TTabletId tabletId = tabletPair.first;
- tabletIdIndex.push_back(tabletId);
- }
- Sort(tabletIdIndex);
-
- out << "<head></head><body>";
-
- out << "<table class='table table-sortable'>";
- out << "<thead>";
- out << "<tr>";
- out << "<th>TabletID</th>";
- out << "<th>Counter</th>";
- out << "<th>CPU</th>";
- out << "<th>Memory</th>";
- out << "<th>Network</th>";
- out << "<th>Storage</th>";
- out << "<th>Read</th>";
- out << "<th>Write</th>";
- out << "</tr>";
- out << "</thead>";
-
- out << "<tbody>";
- for (const auto& pr : Self->Tablets) {
- TTabletId id = pr.first;
- const TTabletInfo& tablet = pr.second;
- ui64 index = EqualRange(tabletIdIndex.begin(), tabletIdIndex.end(), id).first - tabletIdIndex.begin();
-
- out << "<tr title='" << tablet.GetResourceValues().DebugString() << "'>";
- out << "<td data-text='" << index << "'><a href='../tablets?TabletID=" << id << "'>" << id << "</a></td>";
- out << GetResourceValuesHtml(tablet.GetResourceValues());
- out << "</tr>";
- }
- out <<"</tbody>";
- out << "</table>";
-
- out << "<script>";
-
- out << R"(
- var suffixes = ['K', 'M', 'G', 'T', 'P'];
-
- function condenseValue(value) {
- var val = value;
- var suffix = '';
- var n = 0;
- while (n < suffixes.length && Math.abs(val) > 1000) {
- val = val / 1000;
- suffix = suffixes[n];
- n++;
- }
- return val.toPrecision(4) + suffix;
- }
-
- function renderGraph(canvas) {
- var content = canvas.textContent;
- var values = content.split(',').map(function(item) { return parseInt(item, 10); });
- var max = Math.max.apply(Math, values);
- var min = Math.min.apply(Math, values);
- var valueHeight = max - min + 1;
-
- var ctx = canvas.getContext('2d');
- var graphHeight = canvas.height;
- var graphWidth = canvas.width;
- var marginX = 5;
- var marginY = 12;
-
- graphWidth = graphWidth - marginX * 2;
- graphHeight = graphHeight - marginY * 2;
- var x = marginX;
- var y = canvas.height - marginY - (values[0] - min) * graphHeight / valueHeight;
-
- ctx.beginPath();
- ctx.lineWidth = '2';
- ctx.strokeStyle = 'red';
- ctx.lineCap = 'round';
- ctx.lineJoin = 'round';
-
- ctx.moveTo(x, y);
- var len = values.length;
- for (var i = 1; i < len; i++) {
- x = marginX + i * graphWidth / (len - 1);
- y = canvas.height - marginY - (values[i] - min) * graphHeight / valueHeight;
- ctx.lineTo(x, y);
- }
- ctx.stroke();
- //ctx.beginPath();
- ctx.lineWidth = '1';
- ctx.strokeStyle = 'red';
- ctx.fillStyle = '#FFCCCC';
- //ctx.moveTo(x, y);
- ctx.lineTo(marginX + graphWidth, canvas.height - marginY);
- ctx.lineTo(marginX, canvas.height - marginY);
- ctx.lineTo(marginX, canvas.height - marginY - (values[0] - min) * graphHeight / valueHeight);
- ctx.stroke();
- ctx.fill();
- ctx.fillStyle = 'black';
- ctx.font = '10px Arial';
- var txt;
- txt = 'min ' + condenseValue(min);
- /*ctx.shadowOffsetX = 2;
- ctx.shadowOffsetY = 2;
- ctx.shadowColor = 'white';*/
- ctx.textBaseline = 'bottom';
- ctx.fillText(txt, 0, canvas.height);
- ctx.textBaseline = 'top';
- txt = 'max ' + condenseValue(max);
- ctx.fillText(txt, canvas.width - ctx.measureText(txt).width, 0);
- /*ctx.beginPath();
- ctx.strokeStyle = 'black';
- ctx.lineWidth = '1';
- ctx.strokeRect(0, 0, canvas.width, canvas.height);
- ctx.stroke();*/
- }
-
- $('.resource-graph').each(function() { renderGraph(this); });
-
- )";
-
- out << "</script>";
-
- out << "</body>";
- }
-};
-
-class TTxMonEvent_Settings : public TTransactionBase<THive> {
-public:
+ tabletIdIndex.reserve(Self->Tablets.size());
+ for (const auto &tabletPair : Self->Tablets) {
+ TTabletId tabletId = tabletPair.first;
+ tabletIdIndex.push_back(tabletId);
+ }
+ Sort(tabletIdIndex);
+
+ out << "<head></head><body>";
+
+ out << "<table class='table table-sortable'>";
+ out << "<thead>";
+ out << "<tr>";
+ out << "<th>TabletID</th>";
+ out << "<th>Counter</th>";
+ out << "<th>CPU</th>";
+ out << "<th>Memory</th>";
+ out << "<th>Network</th>";
+ out << "<th>Storage</th>";
+ out << "<th>Read</th>";
+ out << "<th>Write</th>";
+ out << "</tr>";
+ out << "</thead>";
+
+ out << "<tbody>";
+ for (const auto& pr : Self->Tablets) {
+ TTabletId id = pr.first;
+ const TTabletInfo& tablet = pr.second;
+ ui64 index = EqualRange(tabletIdIndex.begin(), tabletIdIndex.end(), id).first - tabletIdIndex.begin();
+
+ out << "<tr title='" << tablet.GetResourceValues().DebugString() << "'>";
+ out << "<td data-text='" << index << "'><a href='../tablets?TabletID=" << id << "'>" << id << "</a></td>";
+ out << GetResourceValuesHtml(tablet.GetResourceValues());
+ out << "</tr>";
+ }
+ out <<"</tbody>";
+ out << "</table>";
+
+ out << "<script>";
+
+ out << R"(
+ var suffixes = ['K', 'M', 'G', 'T', 'P'];
+
+ function condenseValue(value) {
+ var val = value;
+ var suffix = '';
+ var n = 0;
+ while (n < suffixes.length && Math.abs(val) > 1000) {
+ val = val / 1000;
+ suffix = suffixes[n];
+ n++;
+ }
+ return val.toPrecision(4) + suffix;
+ }
+
+ function renderGraph(canvas) {
+ var content = canvas.textContent;
+ var values = content.split(',').map(function(item) { return parseInt(item, 10); });
+ var max = Math.max.apply(Math, values);
+ var min = Math.min.apply(Math, values);
+ var valueHeight = max - min + 1;
+
+ var ctx = canvas.getContext('2d');
+ var graphHeight = canvas.height;
+ var graphWidth = canvas.width;
+ var marginX = 5;
+ var marginY = 12;
+
+ graphWidth = graphWidth - marginX * 2;
+ graphHeight = graphHeight - marginY * 2;
+ var x = marginX;
+ var y = canvas.height - marginY - (values[0] - min) * graphHeight / valueHeight;
+
+ ctx.beginPath();
+ ctx.lineWidth = '2';
+ ctx.strokeStyle = 'red';
+ ctx.lineCap = 'round';
+ ctx.lineJoin = 'round';
+
+ ctx.moveTo(x, y);
+ var len = values.length;
+ for (var i = 1; i < len; i++) {
+ x = marginX + i * graphWidth / (len - 1);
+ y = canvas.height - marginY - (values[i] - min) * graphHeight / valueHeight;
+ ctx.lineTo(x, y);
+ }
+ ctx.stroke();
+ //ctx.beginPath();
+ ctx.lineWidth = '1';
+ ctx.strokeStyle = 'red';
+ ctx.fillStyle = '#FFCCCC';
+ //ctx.moveTo(x, y);
+ ctx.lineTo(marginX + graphWidth, canvas.height - marginY);
+ ctx.lineTo(marginX, canvas.height - marginY);
+ ctx.lineTo(marginX, canvas.height - marginY - (values[0] - min) * graphHeight / valueHeight);
+ ctx.stroke();
+ ctx.fill();
+ ctx.fillStyle = 'black';
+ ctx.font = '10px Arial';
+ var txt;
+ txt = 'min ' + condenseValue(min);
+ /*ctx.shadowOffsetX = 2;
+ ctx.shadowOffsetY = 2;
+ ctx.shadowColor = 'white';*/
+ ctx.textBaseline = 'bottom';
+ ctx.fillText(txt, 0, canvas.height);
+ ctx.textBaseline = 'top';
+ txt = 'max ' + condenseValue(max);
+ ctx.fillText(txt, canvas.width - ctx.measureText(txt).width, 0);
+ /*ctx.beginPath();
+ ctx.strokeStyle = 'black';
+ ctx.lineWidth = '1';
+ ctx.strokeRect(0, 0, canvas.width, canvas.height);
+ ctx.stroke();*/
+ }
+
+ $('.resource-graph').each(function() { renderGraph(this); });
+
+ )";
+
+ out << "</script>";
+
+ out << "</body>";
+ }
+};
+
+class TTxMonEvent_Settings : public TTransactionBase<THive> {
+public:
const TActorId Source;
- TAutoPtr<NMon::TEvRemoteHttpInfo> Event;
- bool ChangeRequest = false;
-
+ TAutoPtr<NMon::TEvRemoteHttpInfo> Event;
+ bool ChangeRequest = false;
+
TTxMonEvent_Settings(const TActorId &source, NMon::TEvRemoteHttpInfo::TPtr& ev, TSelf *hive)
- : TBase(hive)
- , Source(source)
- , Event(ev->Release())
- {}
-
- TTxType GetTxType() const override { return NHive::TXTYPE_MON_SETTINGS; }
-
- void UpdateConfig(NIceDb::TNiceDb& db, const TString& param, TSchemeIds::State compatibilityParam = TSchemeIds::State::DefaultState) {
- const auto& params(Event->Cgi());
- if (params.contains(param)) {
- const TString& value = params.Get(param);
- const google::protobuf::Reflection* reflection = Self->DatabaseConfig.GetReflection();
- const google::protobuf::FieldDescriptor* field = Self->DatabaseConfig.GetDescriptor()->FindFieldByName(param);
- if (reflection != nullptr && field != nullptr) {
- if (value.empty()) {
- reflection->ClearField(&Self->DatabaseConfig, field);
- // compatibility
- if (compatibilityParam != TSchemeIds::State::DefaultState) {
- db.Table<Schema::State>().Key(compatibilityParam).Delete();
- }
- // compatibility
- } else {
- switch (field->cpp_type()) {
- case google::protobuf::FieldDescriptor::CPPTYPE_UINT64:
- {
- ui64 val = FromStringWithDefault<ui64>(value);
- reflection->SetUInt64(&Self->DatabaseConfig, field, val);
- // compatibility
- if (compatibilityParam != TSchemeIds::State::DefaultState) {
- db.Table<Schema::State>().Key(compatibilityParam).Update<Schema::State::Value>(val);
- }
- // compatibility
- }
- break;
- case google::protobuf::FieldDescriptor::CPPTYPE_ENUM:
- {
- ui64 val = FromStringWithDefault<ui64>(value);
- reflection->SetEnumValue(&Self->DatabaseConfig, field, val);
- // compatibility
- if (compatibilityParam != TSchemeIds::State::DefaultState) {
- db.Table<Schema::State>().Key(compatibilityParam).Update<Schema::State::Value>(val);
- }
- // compatibility
- }
- break;
- case google::protobuf::FieldDescriptor::CPPTYPE_BOOL:
- {
- bool val = FromStringWithDefault<bool>(value);
- reflection->SetBool(&Self->DatabaseConfig, field, val);
- // compatibility
- if (compatibilityParam != TSchemeIds::State::DefaultState) {
- db.Table<Schema::State>().Key(compatibilityParam).Update<Schema::State::Value>(val ? 1 : 0);
- }
- // compatibility
- }
- break;
- case google::protobuf::FieldDescriptor::CPPTYPE_DOUBLE:
- {
- double val = FromStringWithDefault<double>(value);
- reflection->SetDouble(&Self->DatabaseConfig, field, val);
- // compatibility
- if (compatibilityParam != TSchemeIds::State::DefaultState) {
- db.Table<Schema::State>().Key(compatibilityParam).Update<Schema::State::Value>(val * 100);
- }
- // compatibility
- }
- break;
- default:
- break;
- }
- }
- }
- ChangeRequest = true;
- }
- }
-
- static TTabletTypes::EType GetShortTabletType(const TString& shortType) {
- for (TTabletTypes::EType tabletType : {
- TTabletTypes::DataShard,
- TTabletTypes::Coordinator,
- TTabletTypes::Mediator,
- TTabletTypes::SchemeShard,
- TTabletTypes::Hive,
- TTabletTypes::KeyValue,
- TTabletTypes::PersQueue,
- TTabletTypes::PersQueueReadBalancer,
+ : TBase(hive)
+ , Source(source)
+ , Event(ev->Release())
+ {}
+
+ TTxType GetTxType() const override { return NHive::TXTYPE_MON_SETTINGS; }
+
+ void UpdateConfig(NIceDb::TNiceDb& db, const TString& param, TSchemeIds::State compatibilityParam = TSchemeIds::State::DefaultState) {
+ const auto& params(Event->Cgi());
+ if (params.contains(param)) {
+ const TString& value = params.Get(param);
+ const google::protobuf::Reflection* reflection = Self->DatabaseConfig.GetReflection();
+ const google::protobuf::FieldDescriptor* field = Self->DatabaseConfig.GetDescriptor()->FindFieldByName(param);
+ if (reflection != nullptr && field != nullptr) {
+ if (value.empty()) {
+ reflection->ClearField(&Self->DatabaseConfig, field);
+ // compatibility
+ if (compatibilityParam != TSchemeIds::State::DefaultState) {
+ db.Table<Schema::State>().Key(compatibilityParam).Delete();
+ }
+ // compatibility
+ } else {
+ switch (field->cpp_type()) {
+ case google::protobuf::FieldDescriptor::CPPTYPE_UINT64:
+ {
+ ui64 val = FromStringWithDefault<ui64>(value);
+ reflection->SetUInt64(&Self->DatabaseConfig, field, val);
+ // compatibility
+ if (compatibilityParam != TSchemeIds::State::DefaultState) {
+ db.Table<Schema::State>().Key(compatibilityParam).Update<Schema::State::Value>(val);
+ }
+ // compatibility
+ }
+ break;
+ case google::protobuf::FieldDescriptor::CPPTYPE_ENUM:
+ {
+ ui64 val = FromStringWithDefault<ui64>(value);
+ reflection->SetEnumValue(&Self->DatabaseConfig, field, val);
+ // compatibility
+ if (compatibilityParam != TSchemeIds::State::DefaultState) {
+ db.Table<Schema::State>().Key(compatibilityParam).Update<Schema::State::Value>(val);
+ }
+ // compatibility
+ }
+ break;
+ case google::protobuf::FieldDescriptor::CPPTYPE_BOOL:
+ {
+ bool val = FromStringWithDefault<bool>(value);
+ reflection->SetBool(&Self->DatabaseConfig, field, val);
+ // compatibility
+ if (compatibilityParam != TSchemeIds::State::DefaultState) {
+ db.Table<Schema::State>().Key(compatibilityParam).Update<Schema::State::Value>(val ? 1 : 0);
+ }
+ // compatibility
+ }
+ break;
+ case google::protobuf::FieldDescriptor::CPPTYPE_DOUBLE:
+ {
+ double val = FromStringWithDefault<double>(value);
+ reflection->SetDouble(&Self->DatabaseConfig, field, val);
+ // compatibility
+ if (compatibilityParam != TSchemeIds::State::DefaultState) {
+ db.Table<Schema::State>().Key(compatibilityParam).Update<Schema::State::Value>(val * 100);
+ }
+ // compatibility
+ }
+ break;
+ default:
+ break;
+ }
+ }
+ }
+ ChangeRequest = true;
+ }
+ }
+
+ static TTabletTypes::EType GetShortTabletType(const TString& shortType) {
+ for (TTabletTypes::EType tabletType : {
+ TTabletTypes::DataShard,
+ TTabletTypes::Coordinator,
+ TTabletTypes::Mediator,
+ TTabletTypes::SchemeShard,
+ TTabletTypes::Hive,
+ TTabletTypes::KeyValue,
+ TTabletTypes::PersQueue,
+ TTabletTypes::PersQueueReadBalancer,
TTabletTypes::NodeBroker,
TTabletTypes::TestShard}) {
- if (shortType == LongToShortTabletName(TTabletTypes::TypeToStr(tabletType))) {
- return tabletType;
- }
- }
- return TTabletTypes::TypeInvalid;
- }
-
- bool Execute(TTransactionContext& txc, const TActorContext&) override {
- const auto& params(Event->Cgi());
- NIceDb::TNiceDb db(txc.DB);
-
- UpdateConfig(db, "MaxTabletsScheduled", TSchemeIds::State::MaxTabletsScheduled);
- UpdateConfig(db, "MaxBootBatchSize", TSchemeIds::State::MaxBootBatchSize);
- UpdateConfig(db, "DrainInflight", TSchemeIds::State::DrainInflight);
- UpdateConfig(db, "MaxResourceCPU", TSchemeIds::State::MaxResourceCPU);
- UpdateConfig(db, "MaxResourceMemory", TSchemeIds::State::MaxResourceMemory);
- UpdateConfig(db, "MaxResourceNetwork", TSchemeIds::State::MaxResourceNetwork);
- UpdateConfig(db, "MaxResourceCounter", TSchemeIds::State::MaxResourceCounter);
- UpdateConfig(db, "MinScatterToBalance", TSchemeIds::State::MinScatterToBalance);
- UpdateConfig(db, "MaxNodeUsageToKick", TSchemeIds::State::MaxNodeUsageToKick);
- UpdateConfig(db, "ResourceChangeReactionPeriod", TSchemeIds::State::ResourceChangeReactionPeriod);
- UpdateConfig(db, "TabletKickCooldownPeriod", TSchemeIds::State::TabletKickCooldownPeriod);
- UpdateConfig(db, "SpreadNeighbours", TSchemeIds::State::SpreadNeighbours);
- UpdateConfig(db, "DefaultUnitIOPS", TSchemeIds::State::DefaultUnitIOPS);
- UpdateConfig(db, "DefaultUnitThroughput", TSchemeIds::State::DefaultUnitThroughput);
- UpdateConfig(db, "DefaultUnitSize", TSchemeIds::State::DefaultUnitSize);
- UpdateConfig(db, "StorageOvercommit", TSchemeIds::State::StorageOvercommit);
- UpdateConfig(db, "StorageBalanceStrategy", TSchemeIds::State::StorageBalanceStrategy);
- UpdateConfig(db, "StorageSelectStrategy", TSchemeIds::State::StorageSelectStrategy);
- UpdateConfig(db, "StorageSafeMode", TSchemeIds::State::StorageSafeMode);
- UpdateConfig(db, "RequestSequenceSize", TSchemeIds::State::RequestSequenceSize);
- UpdateConfig(db, "MinRequestSequenceSize", TSchemeIds::State::MinRequestSequenceSize);
- UpdateConfig(db, "MaxRequestSequenceSize", TSchemeIds::State::MaxRequestSequenceSize);
- UpdateConfig(db, "MetricsWindowSize", TSchemeIds::State::MetricsWindowSize);
- UpdateConfig(db, "ResourceOvercommitment", TSchemeIds::State::ResourceOvercommitment);
- UpdateConfig(db, "BalancerInflight");
- UpdateConfig(db, "MinPeriodBetweenBalance");
- UpdateConfig(db, "NodeBalanceStrategy");
- UpdateConfig(db, "TabletBalanceStrategy");
- UpdateConfig(db, "MaxMovementsOnAutoBalancer");
- UpdateConfig(db, "ContinueAutoBalancer");
- UpdateConfig(db, "MinNodeUsageToBalance");
- UpdateConfig(db, "MinPeriodBetweenReassign");
- UpdateConfig(db, "NodeSelectStrategy");
-
- if (ChangeRequest) {
- Self->BuildCurrentConfig();
- db.Table<Schema::State>().Key(TSchemeIds::State::DefaultState).Update<Schema::State::Config>(Self->DatabaseConfig);
- }
+ if (shortType == LongToShortTabletName(TTabletTypes::TypeToStr(tabletType))) {
+ return tabletType;
+ }
+ }
+ return TTabletTypes::TypeInvalid;
+ }
+
+ bool Execute(TTransactionContext& txc, const TActorContext&) override {
+ const auto& params(Event->Cgi());
+ NIceDb::TNiceDb db(txc.DB);
+
+ UpdateConfig(db, "MaxTabletsScheduled", TSchemeIds::State::MaxTabletsScheduled);
+ UpdateConfig(db, "MaxBootBatchSize", TSchemeIds::State::MaxBootBatchSize);
+ UpdateConfig(db, "DrainInflight", TSchemeIds::State::DrainInflight);
+ UpdateConfig(db, "MaxResourceCPU", TSchemeIds::State::MaxResourceCPU);
+ UpdateConfig(db, "MaxResourceMemory", TSchemeIds::State::MaxResourceMemory);
+ UpdateConfig(db, "MaxResourceNetwork", TSchemeIds::State::MaxResourceNetwork);
+ UpdateConfig(db, "MaxResourceCounter", TSchemeIds::State::MaxResourceCounter);
+ UpdateConfig(db, "MinScatterToBalance", TSchemeIds::State::MinScatterToBalance);
+ UpdateConfig(db, "MaxNodeUsageToKick", TSchemeIds::State::MaxNodeUsageToKick);
+ UpdateConfig(db, "ResourceChangeReactionPeriod", TSchemeIds::State::ResourceChangeReactionPeriod);
+ UpdateConfig(db, "TabletKickCooldownPeriod", TSchemeIds::State::TabletKickCooldownPeriod);
+ UpdateConfig(db, "SpreadNeighbours", TSchemeIds::State::SpreadNeighbours);
+ UpdateConfig(db, "DefaultUnitIOPS", TSchemeIds::State::DefaultUnitIOPS);
+ UpdateConfig(db, "DefaultUnitThroughput", TSchemeIds::State::DefaultUnitThroughput);
+ UpdateConfig(db, "DefaultUnitSize", TSchemeIds::State::DefaultUnitSize);
+ UpdateConfig(db, "StorageOvercommit", TSchemeIds::State::StorageOvercommit);
+ UpdateConfig(db, "StorageBalanceStrategy", TSchemeIds::State::StorageBalanceStrategy);
+ UpdateConfig(db, "StorageSelectStrategy", TSchemeIds::State::StorageSelectStrategy);
+ UpdateConfig(db, "StorageSafeMode", TSchemeIds::State::StorageSafeMode);
+ UpdateConfig(db, "RequestSequenceSize", TSchemeIds::State::RequestSequenceSize);
+ UpdateConfig(db, "MinRequestSequenceSize", TSchemeIds::State::MinRequestSequenceSize);
+ UpdateConfig(db, "MaxRequestSequenceSize", TSchemeIds::State::MaxRequestSequenceSize);
+ UpdateConfig(db, "MetricsWindowSize", TSchemeIds::State::MetricsWindowSize);
+ UpdateConfig(db, "ResourceOvercommitment", TSchemeIds::State::ResourceOvercommitment);
+ UpdateConfig(db, "BalancerInflight");
+ UpdateConfig(db, "MinPeriodBetweenBalance");
+ UpdateConfig(db, "NodeBalanceStrategy");
+ UpdateConfig(db, "TabletBalanceStrategy");
+ UpdateConfig(db, "MaxMovementsOnAutoBalancer");
+ UpdateConfig(db, "ContinueAutoBalancer");
+ UpdateConfig(db, "MinNodeUsageToBalance");
+ UpdateConfig(db, "MinPeriodBetweenReassign");
+ UpdateConfig(db, "NodeSelectStrategy");
+
+ if (ChangeRequest) {
+ Self->BuildCurrentConfig();
+ db.Table<Schema::State>().Key(TSchemeIds::State::DefaultState).Update<Schema::State::Config>(Self->DatabaseConfig);
+ }
if (params.contains("allowedMetrics")) {
TVector<TString> allowedMetrics = SplitString(params.Get("allowedMetrics"), ";");
- for (TStringBuf tabletAllowedMetrics : allowedMetrics) {
- TStringBuf tabletType = tabletAllowedMetrics.NextTok(':');
- TTabletTypes::EType type = GetShortTabletType(TString(tabletType));
- if (type != TTabletTypes::TypeInvalid) {
- static const TVector<i64> metricsPos = {
- NKikimrTabletBase::TMetrics::kCPUFieldNumber,
- NKikimrTabletBase::TMetrics::kMemoryFieldNumber,
- NKikimrTabletBase::TMetrics::kNetworkFieldNumber
- };
- if (tabletAllowedMetrics.size() == metricsPos.size()) {
- TVector<i64> metrics = Self->GetTabletTypeAllowedMetricIds(type);
- bool changed = false;
- for (ui32 pos = 0; pos < metricsPos.size(); ++pos) {
- auto id = metricsPos[pos];
- auto it = std::find(metrics.begin(), metrics.end(), id);
- if (tabletAllowedMetrics[pos] == '1' && it == metrics.end()) {
- metrics.emplace_back(id);
- changed = true;
- }
- if (tabletAllowedMetrics[pos] == '0' && it != metrics.end()) {
- metrics.erase(it);
- changed = true;
- }
- }
- if (changed) {
- db.Table<Schema::TabletTypeMetrics>().Key(type).Update<Schema::TabletTypeMetrics::AllowedMetricIDs>(metrics);
- Self->TabletTypeAllowedMetrics[type] = metrics;
- }
- }
- }
- }
- }
- return true;
- }
-
- void Complete(const TActorContext& ctx) override {
- if (ChangeRequest) {
- ctx.Send(Source, new NMon::TEvRemoteJsonInfoRes("{\"status\":\"ok\"}"));
- } else {
- TStringStream str;
- RenderHTMLPage(str, ctx);
- ctx.Send(Source, new NMon::TEvRemoteHttpInfoRes(str.Str()));
- }
- }
-
- void ShowConfig(IOutputStream& out, const TString& param) {
- const google::protobuf::Reflection* reflection = Self->DatabaseConfig.GetReflection();
- const google::protobuf::FieldDescriptor* field = Self->DatabaseConfig.GetDescriptor()->FindFieldByName(param);
- if (reflection != nullptr && field != nullptr) {
- NKikimrConfig::THiveConfig defaultConfig;
- bool localOverrided = reflection->HasField(Self->DatabaseConfig, field);
-
- out << "<div class='row'>";
- if (localOverrided) {
- out << "<div class='col-sm-3' style='padding-top:12px;text-align:right'><label for='" << param << "'>" << param << ":</label></div>";
- } else {
- out << "<div class='col-sm-3' style='padding-top:12px;text-align:right'><label for='" << param << "' style='font-weight:normal'>" << param << ":</label></div>";
- }
-
- switch (field->cpp_type()) {
- case google::protobuf::FieldDescriptor::CPPTYPE_DOUBLE:
- {
- out << "<div class='col-sm-2' style='padding-top:5px'><input id='" << param << "' class='form-control' type='number' step='0.01' style='max-width:170px' value='"
- << reflection->GetDouble(Self->CurrentConfig, field) << "' onkeydown='edit(this);' onchange='edit(this);'></div>";
- out << "<div class='col-sm-1'><button type='button' class='btn' style='margin-top:5px' onclick='applyVal(this, \"" << param << "\");' disabled='true'>Apply</button></div>";
- out << "<div class='col-sm-1'><button type='button' class='btn' style='margin-top:5px' onclick='resetVal(this, \"" << param << "\");' " << (localOverrided ? "" : "disabled='true'") << ">Reset</button></div>";
- if (reflection->HasField(Self->ClusterConfig, field)) {
- out << "<div id='CMS" << param << "' class='col-sm-2' style='padding-top:12px'>" << reflection->GetDouble(Self->ClusterConfig, field) << "</div>";
- } else {
- out << "<div id='CMS" << param << "' class='col-sm-2' style='padding-top:12px'>-</div>";
- }
- out << "<div id='Default" << param << "' class='col-sm-2' style='padding-top:12px'>" << reflection->GetDouble(defaultConfig, field) << "</div>";
- }
- break;
- case google::protobuf::FieldDescriptor::CPPTYPE_UINT64:
- {
- out << "<div class='col-sm-2' style='padding-top:5px'><input id='" << param << "' class='form-control' type='number' style='max-width:170px' value='"
- << reflection->GetUInt64(Self->CurrentConfig, field) << "' onkeydown='edit(this);' onchange='edit(this);'></div>";
- out << "<div class='col-sm-1'><button type='button' class='btn' style='margin-top:5px' onclick='applyVal(this, \"" << param << "\");' disabled='true'>Apply</button></div>";
- out << "<div class='col-sm-1'><button type='button' class='btn' style='margin-top:5px' onclick='resetVal(this, \"" << param << "\");' " << (localOverrided ? "" : "disabled='true'") << ">Reset</button></div>";
- if (reflection->HasField(Self->ClusterConfig, field)) {
- out << "<div id='CMS" << param << "' class='col-sm-2' style='padding-top:12px'>" << reflection->GetUInt64(Self->ClusterConfig, field) << "</div>";
- } else {
- out << "<div id='CMS" << param << "' class='col-sm-2' style='padding-top:12px'>-</div>";
- }
- out << "<div id='Default" << param << "' class='col-sm-2' style='padding-top:12px'>" << reflection->GetUInt64(defaultConfig, field) << "</div>";
- }
- break;
- case google::protobuf::FieldDescriptor::CPPTYPE_BOOL:
- {
- out << "<div class='col-sm-2' style='padding-top:5px'><input id='" << param << "' class='form-control' type='checkbox' style='width:20px;height:20px'"
- << (reflection->GetBool(Self->CurrentConfig, field) ? " checked" : "") << " onkeydown='edit(this);' onchange='edit(this);'></div>";
- out << "<div class='col-sm-1'><button type='button' class='btn' style='margin-top:5px' onclick=\"applyVal(this, '" << param << "', $('#" << param << "').is(':checked') ? 1 : 0);\" disabled='true'>Apply</button></div>";
- out << "<div class='col-sm-1'><button type='button' class='btn' style='margin-top:5px' onclick=\"resetVal(this, '" << param << "'," << (reflection->GetBool(Self->ClusterConfig, field) ? "true" : "false") << ");\" " << (localOverrided ? "" : "disabled='true'") << ">Reset</button></div>";
- if (reflection->HasField(Self->ClusterConfig, field)) {
- out << "<div id='CMS" << param << "' class='col-sm-2' style='padding-top:12px'>" << (reflection->GetBool(Self->ClusterConfig, field) ? "true" : "false") << "</div>";
- } else {
- out << "<div id='CMS" << param << "' class='col-sm-2' style='padding-top:12px'>-</div>";
- }
- out << "<div id='Default" << param << "' class='col-sm-2' style='padding-top:12px'>" << (reflection->GetBool(defaultConfig, field) ? "true" : "false") << "</div>";
- }
- break;
- case google::protobuf::FieldDescriptor::CPPTYPE_ENUM:
- {
- int enumvalue = reflection->GetEnumValue(Self->CurrentConfig, field);
- const google::protobuf::EnumDescriptor* enumfield = field->enum_type();
- out << "<div class='col-sm-2' style='padding-top:5px'><select id='" << param << "' style='max-width:170px;margin-top:7px' onchange='edit(this);'>";
- TString base = enumfield->FindValueByNumber(0)->name();
- for (int n = 1; n < enumfield->value_count(); ++n) {
- const google::protobuf::EnumValueDescriptor* enumdescr = enumfield->FindValueByNumber(n);
- TString name = enumdescr->name();
- if (base.size() > name.size()) {
- base.resize(name.size());
- }
- while (base.size() > 0 && base.back() != name[base.size() - 1]) {
- base.resize(base.size() - 1);
- }
- }
- for (int n = 0; n < enumfield->value_count(); ++n) {
- const google::protobuf::EnumValueDescriptor* enumdescr = enumfield->FindValueByNumber(n);
- out << "<option value=" << enumdescr->number() << (enumvalue == enumdescr->number() ? " selected" : "") << ">"
- << enumdescr->name().substr(base.size())
- << "</option>";
- }
- out << "</select></div>";
- int defaultenumvalue = reflection->GetEnumValue(Self->ClusterConfig, field);
- out << "<div class='col-sm-1'><button type='button' class='btn' style='margin-top:5px' onclick='applyVal(this, \"" << param << "\");' disabled='true'>Apply</button></div>";
- out << "<div class='col-sm-1'><button type='button' class='btn' style='margin-top:5px' onclick='resetVal(this, \"" << param << "\"," << enumfield->FindValueByNumber(defaultenumvalue)->number() << ");' " << (localOverrided ? "" : "disabled='true'") << ">Reset</button></div>";
- if (reflection->HasField(Self->ClusterConfig, field)) {
- out << "<div id='CMS" << param << "' class='col-sm-2' style='padding-top:12px'>" << enumfield->FindValueByNumber(defaultenumvalue)->name().substr(base.size()) << "</div>";
- } else {
- out << "<div id='CMS" << param << "' class='col-sm-2' style='padding-top:12px'>-</div>";
- }
- out << "<div id='Default" << param << "' class='col-sm-2' style='padding-top:12px'>" << enumfield->FindValueByNumber(reflection->GetEnumValue(defaultConfig, field))->name().substr(base.size()) << "</div>";
- }
- break;
- default:
- break;
- }
-
- out << "</div>";
- }
- }
-
+ for (TStringBuf tabletAllowedMetrics : allowedMetrics) {
+ TStringBuf tabletType = tabletAllowedMetrics.NextTok(':');
+ TTabletTypes::EType type = GetShortTabletType(TString(tabletType));
+ if (type != TTabletTypes::TypeInvalid) {
+ static const TVector<i64> metricsPos = {
+ NKikimrTabletBase::TMetrics::kCPUFieldNumber,
+ NKikimrTabletBase::TMetrics::kMemoryFieldNumber,
+ NKikimrTabletBase::TMetrics::kNetworkFieldNumber
+ };
+ if (tabletAllowedMetrics.size() == metricsPos.size()) {
+ TVector<i64> metrics = Self->GetTabletTypeAllowedMetricIds(type);
+ bool changed = false;
+ for (ui32 pos = 0; pos < metricsPos.size(); ++pos) {
+ auto id = metricsPos[pos];
+ auto it = std::find(metrics.begin(), metrics.end(), id);
+ if (tabletAllowedMetrics[pos] == '1' && it == metrics.end()) {
+ metrics.emplace_back(id);
+ changed = true;
+ }
+ if (tabletAllowedMetrics[pos] == '0' && it != metrics.end()) {
+ metrics.erase(it);
+ changed = true;
+ }
+ }
+ if (changed) {
+ db.Table<Schema::TabletTypeMetrics>().Key(type).Update<Schema::TabletTypeMetrics::AllowedMetricIDs>(metrics);
+ Self->TabletTypeAllowedMetrics[type] = metrics;
+ }
+ }
+ }
+ }
+ }
+ return true;
+ }
+
+ void Complete(const TActorContext& ctx) override {
+ if (ChangeRequest) {
+ ctx.Send(Source, new NMon::TEvRemoteJsonInfoRes("{\"status\":\"ok\"}"));
+ } else {
+ TStringStream str;
+ RenderHTMLPage(str, ctx);
+ ctx.Send(Source, new NMon::TEvRemoteHttpInfoRes(str.Str()));
+ }
+ }
+
+ void ShowConfig(IOutputStream& out, const TString& param) {
+ const google::protobuf::Reflection* reflection = Self->DatabaseConfig.GetReflection();
+ const google::protobuf::FieldDescriptor* field = Self->DatabaseConfig.GetDescriptor()->FindFieldByName(param);
+ if (reflection != nullptr && field != nullptr) {
+ NKikimrConfig::THiveConfig defaultConfig;
+ bool localOverrided = reflection->HasField(Self->DatabaseConfig, field);
+
+ out << "<div class='row'>";
+ if (localOverrided) {
+ out << "<div class='col-sm-3' style='padding-top:12px;text-align:right'><label for='" << param << "'>" << param << ":</label></div>";
+ } else {
+ out << "<div class='col-sm-3' style='padding-top:12px;text-align:right'><label for='" << param << "' style='font-weight:normal'>" << param << ":</label></div>";
+ }
+
+ switch (field->cpp_type()) {
+ case google::protobuf::FieldDescriptor::CPPTYPE_DOUBLE:
+ {
+ out << "<div class='col-sm-2' style='padding-top:5px'><input id='" << param << "' class='form-control' type='number' step='0.01' style='max-width:170px' value='"
+ << reflection->GetDouble(Self->CurrentConfig, field) << "' onkeydown='edit(this);' onchange='edit(this);'></div>";
+ out << "<div class='col-sm-1'><button type='button' class='btn' style='margin-top:5px' onclick='applyVal(this, \"" << param << "\");' disabled='true'>Apply</button></div>";
+ out << "<div class='col-sm-1'><button type='button' class='btn' style='margin-top:5px' onclick='resetVal(this, \"" << param << "\");' " << (localOverrided ? "" : "disabled='true'") << ">Reset</button></div>";
+ if (reflection->HasField(Self->ClusterConfig, field)) {
+ out << "<div id='CMS" << param << "' class='col-sm-2' style='padding-top:12px'>" << reflection->GetDouble(Self->ClusterConfig, field) << "</div>";
+ } else {
+ out << "<div id='CMS" << param << "' class='col-sm-2' style='padding-top:12px'>-</div>";
+ }
+ out << "<div id='Default" << param << "' class='col-sm-2' style='padding-top:12px'>" << reflection->GetDouble(defaultConfig, field) << "</div>";
+ }
+ break;
+ case google::protobuf::FieldDescriptor::CPPTYPE_UINT64:
+ {
+ out << "<div class='col-sm-2' style='padding-top:5px'><input id='" << param << "' class='form-control' type='number' style='max-width:170px' value='"
+ << reflection->GetUInt64(Self->CurrentConfig, field) << "' onkeydown='edit(this);' onchange='edit(this);'></div>";
+ out << "<div class='col-sm-1'><button type='button' class='btn' style='margin-top:5px' onclick='applyVal(this, \"" << param << "\");' disabled='true'>Apply</button></div>";
+ out << "<div class='col-sm-1'><button type='button' class='btn' style='margin-top:5px' onclick='resetVal(this, \"" << param << "\");' " << (localOverrided ? "" : "disabled='true'") << ">Reset</button></div>";
+ if (reflection->HasField(Self->ClusterConfig, field)) {
+ out << "<div id='CMS" << param << "' class='col-sm-2' style='padding-top:12px'>" << reflection->GetUInt64(Self->ClusterConfig, field) << "</div>";
+ } else {
+ out << "<div id='CMS" << param << "' class='col-sm-2' style='padding-top:12px'>-</div>";
+ }
+ out << "<div id='Default" << param << "' class='col-sm-2' style='padding-top:12px'>" << reflection->GetUInt64(defaultConfig, field) << "</div>";
+ }
+ break;
+ case google::protobuf::FieldDescriptor::CPPTYPE_BOOL:
+ {
+ out << "<div class='col-sm-2' style='padding-top:5px'><input id='" << param << "' class='form-control' type='checkbox' style='width:20px;height:20px'"
+ << (reflection->GetBool(Self->CurrentConfig, field) ? " checked" : "") << " onkeydown='edit(this);' onchange='edit(this);'></div>";
+ out << "<div class='col-sm-1'><button type='button' class='btn' style='margin-top:5px' onclick=\"applyVal(this, '" << param << "', $('#" << param << "').is(':checked') ? 1 : 0);\" disabled='true'>Apply</button></div>";
+ out << "<div class='col-sm-1'><button type='button' class='btn' style='margin-top:5px' onclick=\"resetVal(this, '" << param << "'," << (reflection->GetBool(Self->ClusterConfig, field) ? "true" : "false") << ");\" " << (localOverrided ? "" : "disabled='true'") << ">Reset</button></div>";
+ if (reflection->HasField(Self->ClusterConfig, field)) {
+ out << "<div id='CMS" << param << "' class='col-sm-2' style='padding-top:12px'>" << (reflection->GetBool(Self->ClusterConfig, field) ? "true" : "false") << "</div>";
+ } else {
+ out << "<div id='CMS" << param << "' class='col-sm-2' style='padding-top:12px'>-</div>";
+ }
+ out << "<div id='Default" << param << "' class='col-sm-2' style='padding-top:12px'>" << (reflection->GetBool(defaultConfig, field) ? "true" : "false") << "</div>";
+ }
+ break;
+ case google::protobuf::FieldDescriptor::CPPTYPE_ENUM:
+ {
+ int enumvalue = reflection->GetEnumValue(Self->CurrentConfig, field);
+ const google::protobuf::EnumDescriptor* enumfield = field->enum_type();
+ out << "<div class='col-sm-2' style='padding-top:5px'><select id='" << param << "' style='max-width:170px;margin-top:7px' onchange='edit(this);'>";
+ TString base = enumfield->FindValueByNumber(0)->name();
+ for (int n = 1; n < enumfield->value_count(); ++n) {
+ const google::protobuf::EnumValueDescriptor* enumdescr = enumfield->FindValueByNumber(n);
+ TString name = enumdescr->name();
+ if (base.size() > name.size()) {
+ base.resize(name.size());
+ }
+ while (base.size() > 0 && base.back() != name[base.size() - 1]) {
+ base.resize(base.size() - 1);
+ }
+ }
+ for (int n = 0; n < enumfield->value_count(); ++n) {
+ const google::protobuf::EnumValueDescriptor* enumdescr = enumfield->FindValueByNumber(n);
+ out << "<option value=" << enumdescr->number() << (enumvalue == enumdescr->number() ? " selected" : "") << ">"
+ << enumdescr->name().substr(base.size())
+ << "</option>";
+ }
+ out << "</select></div>";
+ int defaultenumvalue = reflection->GetEnumValue(Self->ClusterConfig, field);
+ out << "<div class='col-sm-1'><button type='button' class='btn' style='margin-top:5px' onclick='applyVal(this, \"" << param << "\");' disabled='true'>Apply</button></div>";
+ out << "<div class='col-sm-1'><button type='button' class='btn' style='margin-top:5px' onclick='resetVal(this, \"" << param << "\"," << enumfield->FindValueByNumber(defaultenumvalue)->number() << ");' " << (localOverrided ? "" : "disabled='true'") << ">Reset</button></div>";
+ if (reflection->HasField(Self->ClusterConfig, field)) {
+ out << "<div id='CMS" << param << "' class='col-sm-2' style='padding-top:12px'>" << enumfield->FindValueByNumber(defaultenumvalue)->name().substr(base.size()) << "</div>";
+ } else {
+ out << "<div id='CMS" << param << "' class='col-sm-2' style='padding-top:12px'>-</div>";
+ }
+ out << "<div id='Default" << param << "' class='col-sm-2' style='padding-top:12px'>" << enumfield->FindValueByNumber(reflection->GetEnumValue(defaultConfig, field))->name().substr(base.size()) << "</div>";
+ }
+ break;
+ default:
+ break;
+ }
+
+ out << "</div>";
+ }
+ }
+
void RenderHTMLPage(IOutputStream& out, const TActorContext&/* ctx*/) {
- out << "<head></head><body>";
- out << "<script>$('.container > h2').html('Settings');</script>";
- out << "<div class='form-group'>";
- out << "<div class='row' style='margin-bottom:10px;font-weight:bold'><div class='col-sm-3'></div><div class='col-sm-2'>Current</div><div class='col-sm-2'></div><div class='col-sm-2'>CMS</div><div class='col-sm-2'>Default</div></div>";
-
- ShowConfig(out, "MaxTabletsScheduled");
- ShowConfig(out, "MaxBootBatchSize");
- ShowConfig(out, "DrainInflight");
- ShowConfig(out, "MinScatterToBalance");
- ShowConfig(out, "MinNodeUsageToBalance");
- ShowConfig(out, "MaxNodeUsageToKick");
- ShowConfig(out, "ResourceChangeReactionPeriod");
- ShowConfig(out, "TabletKickCooldownPeriod");
- ShowConfig(out, "NodeSelectStrategy");
- ShowConfig(out, "SpreadNeighbours");
- ShowConfig(out, "MaxResourceCPU");
- ShowConfig(out, "MaxResourceMemory");
- ShowConfig(out, "MaxResourceNetwork");
- ShowConfig(out, "MaxResourceCounter");
- ShowConfig(out, "DefaultUnitIOPS");
- ShowConfig(out, "DefaultUnitThroughput");
- ShowConfig(out, "DefaultUnitSize");
- ShowConfig(out, "StorageBalanceStrategy");
- ShowConfig(out, "StorageSafeMode");
- ShowConfig(out, "StorageSelectStrategy");
- ShowConfig(out, "MinPeriodBetweenReassign");
- ShowConfig(out, "MetricsWindowSize");
- ShowConfig(out, "ResourceOvercommitment");
- ShowConfig(out, "NodeBalanceStrategy");
- ShowConfig(out, "TabletBalanceStrategy");
- ShowConfig(out, "BalancerInflight");
- ShowConfig(out, "MinPeriodBetweenBalance");
- ShowConfig(out, "MaxMovementsOnAutoBalancer");
- ShowConfig(out, "ContinueAutoBalancer");
-
- out << "<div class='row' style='margin-top:40px'>";
- out << "<div class='col-sm-2' style='padding-top:30px;text-align:right'><label for='allowedMetrics'>AllowedMetrics:</label></div>";
- out << "<div class='col-sm-3' style='padding-top:5px'><table>";
- out << "<tr><th style='padding:2px 10px'>Tablet</th><th style='padding:2px 10px'>Cnt</th><th style='padding:2px 10px'>CPU</th><th style='padding:2px 10px'>Mem</th><th style='padding:2px 10px'>Net</th></tr>";
- for (TTabletTypes::EType tabletType : {
- TTabletTypes::DataShard,
- TTabletTypes::Coordinator,
- TTabletTypes::Mediator,
- TTabletTypes::SchemeShard,
- TTabletTypes::Hive,
- TTabletTypes::KeyValue,
- TTabletTypes::PersQueue,
- TTabletTypes::PersQueueReadBalancer,
+ out << "<head></head><body>";
+ out << "<script>$('.container > h2').html('Settings');</script>";
+ out << "<div class='form-group'>";
+ out << "<div class='row' style='margin-bottom:10px;font-weight:bold'><div class='col-sm-3'></div><div class='col-sm-2'>Current</div><div class='col-sm-2'></div><div class='col-sm-2'>CMS</div><div class='col-sm-2'>Default</div></div>";
+
+ ShowConfig(out, "MaxTabletsScheduled");
+ ShowConfig(out, "MaxBootBatchSize");
+ ShowConfig(out, "DrainInflight");
+ ShowConfig(out, "MinScatterToBalance");
+ ShowConfig(out, "MinNodeUsageToBalance");
+ ShowConfig(out, "MaxNodeUsageToKick");
+ ShowConfig(out, "ResourceChangeReactionPeriod");
+ ShowConfig(out, "TabletKickCooldownPeriod");
+ ShowConfig(out, "NodeSelectStrategy");
+ ShowConfig(out, "SpreadNeighbours");
+ ShowConfig(out, "MaxResourceCPU");
+ ShowConfig(out, "MaxResourceMemory");
+ ShowConfig(out, "MaxResourceNetwork");
+ ShowConfig(out, "MaxResourceCounter");
+ ShowConfig(out, "DefaultUnitIOPS");
+ ShowConfig(out, "DefaultUnitThroughput");
+ ShowConfig(out, "DefaultUnitSize");
+ ShowConfig(out, "StorageBalanceStrategy");
+ ShowConfig(out, "StorageSafeMode");
+ ShowConfig(out, "StorageSelectStrategy");
+ ShowConfig(out, "MinPeriodBetweenReassign");
+ ShowConfig(out, "MetricsWindowSize");
+ ShowConfig(out, "ResourceOvercommitment");
+ ShowConfig(out, "NodeBalanceStrategy");
+ ShowConfig(out, "TabletBalanceStrategy");
+ ShowConfig(out, "BalancerInflight");
+ ShowConfig(out, "MinPeriodBetweenBalance");
+ ShowConfig(out, "MaxMovementsOnAutoBalancer");
+ ShowConfig(out, "ContinueAutoBalancer");
+
+ out << "<div class='row' style='margin-top:40px'>";
+ out << "<div class='col-sm-2' style='padding-top:30px;text-align:right'><label for='allowedMetrics'>AllowedMetrics:</label></div>";
+ out << "<div class='col-sm-3' style='padding-top:5px'><table>";
+ out << "<tr><th style='padding:2px 10px'>Tablet</th><th style='padding:2px 10px'>Cnt</th><th style='padding:2px 10px'>CPU</th><th style='padding:2px 10px'>Mem</th><th style='padding:2px 10px'>Net</th></tr>";
+ for (TTabletTypes::EType tabletType : {
+ TTabletTypes::DataShard,
+ TTabletTypes::Coordinator,
+ TTabletTypes::Mediator,
+ TTabletTypes::SchemeShard,
+ TTabletTypes::Hive,
+ TTabletTypes::KeyValue,
+ TTabletTypes::PersQueue,
+ TTabletTypes::PersQueueReadBalancer,
TTabletTypes::NodeBroker,
TTabletTypes::TestShard}) {
- const TVector<i64>& allowedMetrics = Self->GetTabletTypeAllowedMetricIds(tabletType);
- out << "<tr>"
- "<td>" << LongToShortTabletName(TTabletTypes::TypeToStr(tabletType)) << "</td>";
- out << "<td><input id='cpu' class='form-control' type='checkbox' checked='' disabled='' style='width:20px;height:20px;margin:2px auto'</input></td>";
- out << "<td><input id='cpu' class='form-control' type='checkbox'";
- if (Find(allowedMetrics, NKikimrTabletBase::TMetrics::kCPUFieldNumber) != allowedMetrics.end()) {
- out << " checked=''";
- }
- out << " style='width:20px;height:20px;margin:2px auto' onchange='edit(this);'</input></td>";
- out << "<td><input id='mem' class='form-control' type='checkbox'";
- if (Find(allowedMetrics, NKikimrTabletBase::TMetrics::kMemoryFieldNumber) != allowedMetrics.end()) {
- out << " checked=''";
- }
- out << " style='width:20px;height:20px;margin:2px auto' onchange='edit(this);'</input></td>";
- out << "<td><input id='net' class='form-control' type='checkbox'";
- if (Find(allowedMetrics, NKikimrTabletBase::TMetrics::kNetworkFieldNumber) != allowedMetrics.end()) {
- out << " checked=''";
- }
- out << " style='width:20px;height:20px;margin:2px auto' onchange='edit(this);'</input></td>";
- out << "</tr>";
- }
- out << "</table></div>";
- out << "<div class='col-sm-2' style='padding-top:22px'><button type='button' class='btn' style='margin-top:5px' onclick='applyTab(this);' disabled='true'>Apply</button></div>";
-
- out << "</div>";
-
-
- out << "</div>";
-
- out << R"___(
- <script>
- function edit(button) {
- $(button).parents('div').next().children('button').prop('disabled', false);
- }
-
- function applyVal(button, name, val) {
- var input = $('#' + name);
- $.ajax({
- url: document.URL + '&' + name + '=' + (val === undefined ? input.val() : val),
- success: function() {
- $(button).prop('disabled', true).removeClass('btn-danger');
- $(button).parent().next().children().prop('disabled', false);
- $(button).parent().parent().find('label').removeAttr('style');
- },
- error: function() { $(button).addClass('btn-danger'); }
- });
- }
-
- function resetVal(button, name, val) {
- var input = $('#' + name);
- $.ajax({
- url: document.URL + '&' + name + '=',
- success: function() {
- if (val == undefined) {
- var v = $('#CMS' + name).text();
- if (v == '-') {
- v = $('#Default' + name).text();
- }
- input.val(v);
- } else {
- if (val === false || val === true) {
- input.prop('checked', val);
- } else {
- input.val(val);
- }
- }
- $(button).prop('disabled', true).removeClass('btn-danger');
- $(button).parent().parent().find('label').attr('style', 'font-weight:normal');
- },
- error: function() { $(button).addClass('btn-danger'); }
- });
- }
-
- function applyTab(button, val) {
- var table = $(button).parent().prev().children('table').first().get(0);
- var val = '';
- for (var rowNum = 1; rowNum < table.rows.length; ++rowNum) {
- var row = table.rows[rowNum];
- var type = row.cells[0].innerText;
- var cnt = row.cells[1].firstChild.checked ? 1 : 0;
- var cpu = row.cells[2].firstChild.checked ? 1 : 0;
- var mem = row.cells[3].firstChild.checked ? 1 : 0;
- var net = row.cells[4].firstChild.checked ? 1 : 0;
- if (val.length != 0)
- val += ';';
- val += type + ':' + cpu + mem + net;
- }
- var name = 'allowedMetrics';
- $.ajax({
- url: document.URL + '&' + name + '=' + val,
- success: function() { $(button).prop('disabled', true).removeClass('btn-danger'); },
- error: function() { $(button).addClass('btn-danger'); }
- });
- }
- </script>
- )___";
-
- out << "</body>";
- }
-};
-
-class TTxMonEvent_Landing : public TTransactionBase<THive> {
-public:
+ const TVector<i64>& allowedMetrics = Self->GetTabletTypeAllowedMetricIds(tabletType);
+ out << "<tr>"
+ "<td>" << LongToShortTabletName(TTabletTypes::TypeToStr(tabletType)) << "</td>";
+ out << "<td><input id='cpu' class='form-control' type='checkbox' checked='' disabled='' style='width:20px;height:20px;margin:2px auto'</input></td>";
+ out << "<td><input id='cpu' class='form-control' type='checkbox'";
+ if (Find(allowedMetrics, NKikimrTabletBase::TMetrics::kCPUFieldNumber) != allowedMetrics.end()) {
+ out << " checked=''";
+ }
+ out << " style='width:20px;height:20px;margin:2px auto' onchange='edit(this);'</input></td>";
+ out << "<td><input id='mem' class='form-control' type='checkbox'";
+ if (Find(allowedMetrics, NKikimrTabletBase::TMetrics::kMemoryFieldNumber) != allowedMetrics.end()) {
+ out << " checked=''";
+ }
+ out << " style='width:20px;height:20px;margin:2px auto' onchange='edit(this);'</input></td>";
+ out << "<td><input id='net' class='form-control' type='checkbox'";
+ if (Find(allowedMetrics, NKikimrTabletBase::TMetrics::kNetworkFieldNumber) != allowedMetrics.end()) {
+ out << " checked=''";
+ }
+ out << " style='width:20px;height:20px;margin:2px auto' onchange='edit(this);'</input></td>";
+ out << "</tr>";
+ }
+ out << "</table></div>";
+ out << "<div class='col-sm-2' style='padding-top:22px'><button type='button' class='btn' style='margin-top:5px' onclick='applyTab(this);' disabled='true'>Apply</button></div>";
+
+ out << "</div>";
+
+
+ out << "</div>";
+
+ out << R"___(
+ <script>
+ function edit(button) {
+ $(button).parents('div').next().children('button').prop('disabled', false);
+ }
+
+ function applyVal(button, name, val) {
+ var input = $('#' + name);
+ $.ajax({
+ url: document.URL + '&' + name + '=' + (val === undefined ? input.val() : val),
+ success: function() {
+ $(button).prop('disabled', true).removeClass('btn-danger');
+ $(button).parent().next().children().prop('disabled', false);
+ $(button).parent().parent().find('label').removeAttr('style');
+ },
+ error: function() { $(button).addClass('btn-danger'); }
+ });
+ }
+
+ function resetVal(button, name, val) {
+ var input = $('#' + name);
+ $.ajax({
+ url: document.URL + '&' + name + '=',
+ success: function() {
+ if (val == undefined) {
+ var v = $('#CMS' + name).text();
+ if (v == '-') {
+ v = $('#Default' + name).text();
+ }
+ input.val(v);
+ } else {
+ if (val === false || val === true) {
+ input.prop('checked', val);
+ } else {
+ input.val(val);
+ }
+ }
+ $(button).prop('disabled', true).removeClass('btn-danger');
+ $(button).parent().parent().find('label').attr('style', 'font-weight:normal');
+ },
+ error: function() { $(button).addClass('btn-danger'); }
+ });
+ }
+
+ function applyTab(button, val) {
+ var table = $(button).parent().prev().children('table').first().get(0);
+ var val = '';
+ for (var rowNum = 1; rowNum < table.rows.length; ++rowNum) {
+ var row = table.rows[rowNum];
+ var type = row.cells[0].innerText;
+ var cnt = row.cells[1].firstChild.checked ? 1 : 0;
+ var cpu = row.cells[2].firstChild.checked ? 1 : 0;
+ var mem = row.cells[3].firstChild.checked ? 1 : 0;
+ var net = row.cells[4].firstChild.checked ? 1 : 0;
+ if (val.length != 0)
+ val += ';';
+ val += type + ':' + cpu + mem + net;
+ }
+ var name = 'allowedMetrics';
+ $.ajax({
+ url: document.URL + '&' + name + '=' + val,
+ success: function() { $(button).prop('disabled', true).removeClass('btn-danger'); },
+ error: function() { $(button).addClass('btn-danger'); }
+ });
+ }
+ </script>
+ )___";
+
+ out << "</body>";
+ }
+};
+
+class TTxMonEvent_Landing : public TTransactionBase<THive> {
+public:
const TActorId Source;
- TAutoPtr<NMon::TEvRemoteHttpInfo> Event;
- TCgiParameters Cgi;
-
+ TAutoPtr<NMon::TEvRemoteHttpInfo> Event;
+ TCgiParameters Cgi;
+
TTxMonEvent_Landing(const TActorId &source, NMon::TEvRemoteHttpInfo::TPtr& ev, TSelf *hive)
- : TBase(hive)
- , Source(source)
- , Event(ev->Release())
- , Cgi(Event->Cgi())
- {}
-
- TTxType GetTxType() const override { return NHive::TXTYPE_MON_LANDING; }
-
- bool Execute(TTransactionContext &txc, const TActorContext& ctx) override {
+ : TBase(hive)
+ , Source(source)
+ , Event(ev->Release())
+ , Cgi(Event->Cgi())
+ {}
+
+ TTxType GetTxType() const override { return NHive::TXTYPE_MON_LANDING; }
+
+ bool Execute(TTransactionContext &txc, const TActorContext& ctx) override {
Y_UNUSED(txc);
- TStringStream str;
- RenderHTMLPage(str);
- ctx.Send(Source, new NMon::TEvRemoteHttpInfoRes(str.Str()));
- return true;
- }
-
- void Complete(const TActorContext& ctx) override {
+ TStringStream str;
+ RenderHTMLPage(str);
+ ctx.Send(Source, new NMon::TEvRemoteHttpInfoRes(str.Str()));
+ return true;
+ }
+
+ void Complete(const TActorContext& ctx) override {
Y_UNUSED(ctx);
- }
-
+ }
+
static TString GetTabletType(TTabletTypes::EType type) {
- switch(type) {
- case TTabletTypes::SchemeShard:
- return "SS";
- case TTabletTypes::Hive:
- return "H";
- case TTabletTypes::DataShard:
- return "DS";
- case TTabletTypes::KeyValue:
- return "KV";
- case TTabletTypes::PersQueue:
- return "PQ";
- case TTabletTypes::PersQueueReadBalancer:
+ switch(type) {
+ case TTabletTypes::SchemeShard:
+ return "SS";
+ case TTabletTypes::Hive:
+ return "H";
+ case TTabletTypes::DataShard:
+ return "DS";
+ case TTabletTypes::KeyValue:
+ return "KV";
+ case TTabletTypes::PersQueue:
+ return "PQ";
+ case TTabletTypes::PersQueueReadBalancer:
return "PQRB";
- case TTabletTypes::Dummy:
- return "DY";
- case TTabletTypes::Coordinator:
- return "C";
- case TTabletTypes::Mediator:
- return "M";
- case TTabletTypes::BlockStoreVolume:
- return "BV";
- case TTabletTypes::BlockStorePartition:
- case TTabletTypes::BlockStorePartition2:
- return "BP";
- case TTabletTypes::Kesus:
- return "K";
+ case TTabletTypes::Dummy:
+ return "DY";
+ case TTabletTypes::Coordinator:
+ return "C";
+ case TTabletTypes::Mediator:
+ return "M";
+ case TTabletTypes::BlockStoreVolume:
+ return "BV";
+ case TTabletTypes::BlockStorePartition:
+ case TTabletTypes::BlockStorePartition2:
+ return "BP";
+ case TTabletTypes::Kesus:
+ return "K";
case TTabletTypes::SysViewProcessor:
return "SV";
case TTabletTypes::FileStore:
@@ -1094,1779 +1094,1779 @@ public:
return "S";
case TTabletTypes::ReplicationController:
return "RC";
- default:
- return Sprintf("%d", (int)type);
- }
- }
-
+ default:
+ return Sprintf("%d", (int)type);
+ }
+ }
+
void RenderHTMLPage(IOutputStream &out) {
- ui64 nodes = 0;
- ui64 tablets = 0;
+ ui64 nodes = 0;
+ ui64 tablets = 0;
ui64 runningTablets = 0;
ui64 aliveNodes = 0;
THashMap<ui32, TMap<TString, ui32>> tabletsByNodeByType;
THashMap<TTabletTypes::EType, ui32> tabletTypesToChannels;
-
- for (const auto& pr : Self->Tablets) {
- if (pr.second.IsRunning()) {
+
+ for (const auto& pr : Self->Tablets) {
+ if (pr.second.IsRunning()) {
++runningTablets;
- ++tabletsByNodeByType[pr.second.NodeId][GetTabletType(pr.second.Type)];
- }
+ ++tabletsByNodeByType[pr.second.NodeId][GetTabletType(pr.second.Type)];
+ }
for (const auto& sl : pr.second.Followers) {
- if (sl.IsRunning()){
- ++runningTablets;
- ++tabletsByNodeByType[sl.NodeId][GetTabletType(pr.second.Type) + "s"];
- }
- ++tablets;
- }
- {
- auto it = tabletTypesToChannels.find(pr.second.Type);
- if (it == tabletTypesToChannels.end()) {
- ui32 channels = pr.second.GetChannelCount();
+ if (sl.IsRunning()){
+ ++runningTablets;
+ ++tabletsByNodeByType[sl.NodeId][GetTabletType(pr.second.Type) + "s"];
+ }
+ ++tablets;
+ }
+ {
+ auto it = tabletTypesToChannels.find(pr.second.Type);
+ if (it == tabletTypesToChannels.end()) {
+ ui32 channels = pr.second.GetChannelCount();
tabletTypesToChannels.emplace(pr.second.Type, channels);
- }
- }
- ++tablets;
- }
- for (const auto& pr : Self->Nodes) {
- if (pr.second.IsAlive()) {
+ }
+ }
+ ++tablets;
+ }
+ for (const auto& pr : Self->Nodes) {
+ if (pr.second.IsAlive()) {
++aliveNodes;
- }
- if (!pr.second.IsUnknown()) {
- ++nodes;
- }
- }
-
- out << "<head>";
- out << "<style>";
- out << "table.simple-table1 td { padding: 1px 3px; }";
- out << "table.simple-table1 td:nth-child(1) { text-align: right; }";
- out << "table.simple-table2 th { text-align: right; }";
- out << "table.simple-table2 tr:nth-child(1) > th:nth-child(2) { text-align: left; }";
- out << "table.simple-table2 tr:nth-child(1) > th:nth-child(3) { text-align: left; }";
- out << "table.simple-table2 tr:nth-child(1) > th:nth-child(4) { text-align: left; }";
- out << "table.simple-table2 td { text-align: right; }";
- out << "table.simple-table2 td:nth-child(2) { text-align: left; }";
- out << "table.simple-table2 td:nth-child(3) { text-align: left; }";
- out << "table.simple-table2 td:nth-child(4) { text-align: left; }";
- out << ".table-hover tbody tr:hover > td { background-color: #9dddf2; }";
- out << ".blinking { animation:blinkingText 0.8s infinite; }";
- out << "@keyframes blinkingText { 0% { color: #000; } 49% { color: #000; } 60% { color: transparent; } 99% { color:transparent; } 100% { color: #000; } }";
- out << "</style>";
- out << "</head>";
- out << "<body>";
- out << "<table class='simple-table1'>";
-
- TSubDomainKey domainId = Self->GetMySubDomainKey();
- if (domainId) {
- out << "<tr><td>" << "Tenant:" << "</td>";
- TDomainInfo* domainInfo = Self->FindDomain(domainId);
- if (domainInfo && domainInfo->Path) {
- out << "<td>" << domainInfo->Path << "</td>";
- } else {
- out << "<td>" << domainId << "</td>";
- }
- out << "<td><span id='alert-placeholder' class='glyphicon' style='height:14px'></span></td>";
- out << "</tr>";
- }
-
- /*out << "<tr><td>" << "Nodes:" << "</td><td id='aliveNodes'>" << (nodes == 0 ? 0 : aliveNodes * 100 / nodes) << "% "
- << aliveNodes << "/" << nodes << "</td></tr>";*/
- out << "<tr><td>" << "Tablets:" << "</td><td id='runningTablets'>" << (tablets == 0 ? 0 : runningTablets * 100 / tablets) << "% "
- << runningTablets << "/" << tablets << "</td></tr>";
- out << "<tr><td title='Rebalance all tablets' style='cursor:pointer' onclick='rebalanceTablets(this)'>Balancer: </td><td id='balancerProgress'>"
- << (Self->BalancerProgress >= 0 ? Sprintf("%d%%", Self->BalancerProgress) : TString()) << "</td></tr>";
- out << "<tr><td>" << "Boot Queue:" << "</td><td id='bootQueue'>" << Self->BootQueue.BootQueue.size() << "</td></tr>";
- out << "<tr><td>" << "Wait Queue:" << "</td><td id='waitQueue'>" << Self->BootQueue.WaitQueue.size() << "</td></tr>";
- out << "<tr><td>" << "Resource Total: " << "</td><td id='resourceTotal'>" << GetResourceValuesText(Self->TotalRawResourceValues) << "</td></tr>";
- out << "<tr><td>" << "Resource StDev: " << "</td><td id='resourceVariance'>"
- << convert(Self->GetStDevResourceValues(), [](double d) -> TString { return Sprintf("%.9f", d); }) << "</td></tr>";
- out << "</table>";
-
- out << "<table id='node_table' class='table simple-table2 table-hover table-condensed'>";
- out << "<thead><tr>"
- "<th rowspan='2' style='min-width:70px'>Node</th>"
- "<th rowspan='2' style='min-width:280px'>Name</th>"
- "<th rowspan='2' style='min-width:50px'>DC</th>"
- "<th rowspan='2' style='min-width:280px'>Domain</th>"
- "<th rowspan='2' style='min-width:120px'>Uptime</th>"
- "<th rowspan='2'>Unknown</th>"
- "<th rowspan='2'>Starting</th>"
- "<th rowspan='2'>Running</th>"
- "<th rowspan='2' style='min-width:160px'>Types</th>"
- "<th rowspan='2' style='min-width:110px'>Usage</th>"
- "<th colspan='4' style='text-align:center'>Resources</td>"
- "<th rowspan='2' style='text-align:center'>Active</th>"
- "<th rowspan='2' style='text-align:center'>Freeze</th>"
- "<th rowspan='2' style='text-align:center'>Kick</th>"
- "<th rowspan='2' style='text-align:center'>Drain</th></tr>"
- "<tr>"
- "<th style='min-width:70px'>cnt</th>"
- "<th style='min-width:100px'>cpu</th>"
- "<th style='min-width:100px'>mem</th>"
- "<th style='min-width:100px'>net</th></tr>"
- "</thead>";
- out << "<tbody>";
- out << "<tr><td colspan=18 style='text-align:center'><button type='button' class='btn btn-info' onclick='updateData();' style='margin-top:30px;margin-bottom:30px'>View Nodes</button></td></tr>";
- out << "</tbody>";
- out << "</table>";
-
- out << "<div class='row' style='margin-top:100px'>";
- out << "<div class='col-sm-1 col-md-1' style='text-align:center'>";
- out << "<button type='button' class='btn btn-info' onclick='location.href=\"app?TabletID=" << Self->HiveId << "&page=MemStateTablets&bad=1&max=1000\";' style='width:138px'>Bad Tablets</button>";
- out << "</div>";
- out << "<div class='col-sm-1 col-md-1' style='text-align:center'>";
- out << "<button type='button' class='btn btn-info' onclick='location.href=\"app?TabletID=" << Self->HiveId << "&page=MemStateTablets&sort=weight&max=1000\";' style='width:138px'>Heavy Tablets</button>";
- out << "</div>";
- out << "<div class='col-sm-1 col-md-1' style='text-align:center'>";
- out << "<button type='button' class='btn btn-info' onclick='location.href=\"app?TabletID=" << Self->HiveId << "&page=MemStateTablets&wait=1&max=1000\";' style='width:138px'>Waiting Tablets</button>";
- out << "</div>";
- out << "<div class='col-sm-1 col-md-1' style='text-align:center'>";
- out << "<button type='button' class='btn btn-info' onclick='location.href=\"app?TabletID=" << Self->HiveId << "&page=Resources\";' style='width:138px'>Resources</button>";
- out << "</div>";
- out << "<div class='col-sm-1 col-md-1' style='text-align:center'>";
- out << "<button type='button' class='btn btn-info' onclick='location.href=\"app?TabletID=" << Self->HiveId << "&page=MemStateDomains\";' style='width:138px'>Tenants</button>";
- out << "</div>";
- out << "</div>";
-
- out << "<div class='row' style='margin-top:10px'>";
- out << "<div class='col-sm-1 col-md-1' style='text-align:center'>";
- out << "<button type='button' class='btn btn-info' onclick='location.href=\"app?TabletID=" << Self->HiveId << "&page=MemStateNodes\";' style='width:138px'>Nodes</button>";
- out << "</div>";
- out << "<div class='col-sm-1 col-md-1' style='text-align:center'>";
- out << "<button type='button' class='btn btn-info' onclick='location.href=\"app?TabletID=" << Self->HiveId << "&page=Storage\";' style='width:138px'>Storage</button>";
- out << "</div>";
- out << "<div class='col-sm-1 col-md-1' style='text-align:center'>";
- out << "<button type='button' class='btn btn-info' onclick='location.href=\"app?TabletID=" << Self->HiveId << "&page=Groups\";' style='width:138px'>Groups</button>";
- out << "</div>";
- out << "<div class='col-sm-1 col-md-1' style='text-align:center'>";
- out << "<button type='button' class='btn btn-info' onclick='location.href=\"app?TabletID=" << Self->HiveId << "&page=Settings\";' style='width:138px'>Settings</button>";
- out << "</div>";
- out << "<div class='col-sm-1 col-md-1' style='text-align:center'>";
- out << "<button type='button' class='btn btn-info' data-toggle='modal' data-target='#reassign-groups' style='width:138px'>Reassign Groups</button>";
- out << "</div>";
- out << "</div>";
-
- out << "<div class='row' style='margin-top:50px'>";
-
- out << "<div class='form-group'><label for='tablets_group' style='padding-right:10px'>Groups of Tablet:</label>";
- out << "<input type='text' id='tablets_group'><input type='submit' value='open' onclick=\"window.open(document.URL + '&page=Groups&tablet_id=' + this.previousSibling.value);\">";
- out << "</div>";
-
- out << "<div class='form-group'><label for='groups_tablet' style='padding-right:10px'>Tablets of Group:</label>";
- out << "<input type='text' id='groups_tablet'><input type='submit' value='open' onclick=\"window.open(document.URL + '&page=Groups&group_id=' + this.previousSibling.value);\">";
- out << "</div>";
-
- out << "</div>";
-
- out << R"___(
- <div class='modal fade' id='reassign-groups' role='dialog'>
- <div class='modal-dialog' style='width:60%'>
- <div class='modal-content'>
- <div class='modal-header'>
- <button type='button' class='close' data-dismiss='modal' onclick='cancel();'>&times;</button>
- <h4 class='modal-title'>Reassign Tablets Groups</h4>
- </div>
- <div class='modal-body'>
- <div class='row'>
- <div class='col-md-5'>
- <label for='tablet_storage_pool_group'>Storage pool</label>
- <div in='tablet_storage_pool_group' class='input-group' style='width:100%'>
- <input id='tablet_storage_pool' type='text' min='0' max='255' class='form-control'>
- </div>
- <label for='tablet_storage_group_group' style='margin-top:20px'>Storage group</label>
- <div in='tablet_storage_group_group' class='input-group'>
- <input id='tablet_storage_group' type='number' class='form-control'>
- <span class='input-group-addon'>group id</span>
- </div>
- </div>
- <div class='col-md-4'>
- <label for='tablet_type'>Type</label>
- <select id='tablet_type' class='form-control'>
- <option selected value>Any</option>
- </select>
- <label for='tablet_from_channel_group' style='margin-top:20px'>Channels</label>
- <div in='tablet_from_channel_group' class='input-group'>
- <input id='tablet_from_channel' type='number' value='0' min='0' max='255' class='form-control'>
- <span class='input-group-addon'>from</span>
- <input id='tablet_to_channel' type='number' value='255' min='0' max='255' class='form-control'>
- <span class='input-group-addon'>to</span>
- </div>
- </div>
- <div class='col-md-3'>
- <label for='tablet_percent_group'>Percent</label>
- <div in='tablet_percent_group' class='input-group'>
- <input id='tablet_percent' type='number' value='100' min='1' max='100' class='form-control'>
- <span class='input-group-addon'>%</span>
- </div>
- <label for='tablet_reassign_inflight_group' style='margin-top:20px'>Inflight</label>
- <div id='tablet_reassign_inflight_group' class='input-group'>
- <input id='tablet_reassign_inflight' type='number' value='1' min='1' max='10' class='form-control'>
- <span class='input-group-addon'>1-10</span>
- </div>
- </div>
- </div>
- <div class='row'>
- <div class='col-md-12'>
- <hr>
- </div>
- </div>
- <div class='row'>
- <div class='col-md-2' style='visibility:hidden'>
- <label for='tablets_found_group'>Found</label>
- <div id='tablets_found_group'>
- <span id='tablets_found'>0</span>
- </div>
- </div>
- <div class='col-md-2' style='visibility:hidden'>
- <label for='tablets_processed_group'>Processed</label>
- <div id='tablets_processed_group'>
- <span id='tablets_processed'></span>
- </div>
- </div>
- <div class='col-md-2' style='visibility:hidden'>
- <label for='current_inflight_group'>Inflight</label>
- <div id='current_inflight_group'>
- <span id='current_inflight'></span>
- </div>
- </div>
- <div class='col-md-2' style='visibility:hidden'>
- <label for='time_left_group'>Time left</label>
- <div id='time_left_group'>
- <span id='time_left'></span>
- </div>
- </div>
- <div class='col-md-2'>
- </div>
- <div class='col-md-2'>
-
- </div>
- </div>
- <div class='row' style='margin-top:20px'>
- <div class='col-md-12' style='visibility:hidden'>
- <label for='progress_bar_group'>Progress</label>
- <div id='progress_bar_group' class='progress' style='height:30px'>
- <div id='progress_bar' class='progress-bar' role='progressbar' style='width:0%;font-size:20px;padding-top:5px' aria-valuenow='0' aria-valuemin='0' aria-valuemax='100'></div>
- </div>
- </div>
- </div>
- </div>
- <div class='modal-footer'>
- <span id='status_text' style='float:left'></span>
- <button id='button_query' type='submit' class='btn btn-default' onclick='queryTablets();'>Query</button>
- <button id='button_reassign' type='submit' class='btn btn-default disabled' onclick='reassignGroups();'>Reassign</button>
- <button type='button' class='btn btn-default' data-dismiss='modal' onclick='cancel();'>Cancel</button>
- </div>
- </div>
- </div>
- </div>
- )___";
-
- out << "<script>";
- out << "var hiveId = '" << Self->HiveId << "';";
- out << "var tablets = [";
- for (auto itTablet = tabletTypesToChannels.begin(); itTablet != tabletTypesToChannels.end(); ++itTablet) {
- if (itTablet != tabletTypesToChannels.begin()) {
- out << ',';
- }
- out << "{type:" << (ui32)(itTablet->first) << ",name:'" << TTabletTypes::TypeToStr(itTablet->first) << "',channels:" << itTablet->second << "}";
- }
- out << "];";
- out << R"___(
- $('.container')
- .toggleClass('container container-fluid')
- .css('padding-left', '1%')
- .css('padding-right', '1%');
-
- function initReassignGroups() {
- var domTabletType = document.getElementById('tablet_type');
- for (var tab = 0; tab < tablets.length; tab++) {
- var opt = document.createElement('option');
- opt.text = tablets[tab].name;
- opt.value = tablets[tab].type;
- domTabletType.add(opt);
- }
- }
-
- )___";
-
- out << R"___(
- initReassignGroups();
-
- var tablets_found;
-
- function queryTablets() {
- var storage_pool = $('#tablet_storage_pool').val();
- var storage_group = $('#tablet_storage_group').val();
- var tablet_type = $('#tablet_type').val();
- var channel_from = $('#tablet_from_channel').val();
- var channel_to = $('#tablet_to_channel').val();
- var percent = $('#tablet_percent').val();
- var url = 'app?TabletID=' + hiveId + '&page=FindTablet';
- if (storage_pool) {
- url = url + '&storagePool=' + storage_pool;
- }
- if (storage_group) {
- url = url + '&group=' + storage_group;
- }
- if (tablet_type) {
- url = url + '&type=' + tablet_type;
- }
- if (channel_from) {
- url = url + '&channelFrom=' + channel_from;
- }
- if (channel_to) {
- url = url + '&channelTo=' + channel_to;
- }
- if (percent) {
- url = url + '&percent=' + percent;
- }
- $.ajax({
- url: url,
- success: function(result) {
- tablets_found = result;
- $('#tablets_found_group').parent().css({visibility: 'visible'});
- $('#tablets_found').text(tablets_found.length);
- $('#button_reassign').removeClass('disabled');
- },
- error: function(jqXHR, status) {
- $('#status_text').text(status);
- }
- });
- }
-
- var tables_processed;
- var current_inflight;
-
- function continueReassign() {
- var max_inflight = $('#tablet_reassign_inflight').val();
- while (tablets_processed < tablets_found.length && current_inflight < max_inflight) {
- var tablet = tablets_found[tablets_processed];
- tablets_processed++;
- current_inflight++;
- $('#current_inflight').text(current_inflight);
- $.ajax({
- url: 'app?TabletID=' + hiveId
- + '&page=ReassignTablet&tablet=' + tablet.tabletId
- + '&channels=' + tablet.channels
- + '&wait=1',
- success: function() {
-
- },
- error: function(jqXHR, status) {
- $('#status_text').text(status);
- },
- complete: function() {
- $('#tablets_processed').text(tablets_processed);
- var value = Number(tablets_processed * 100 / tablets_found.length).toFixed();
- $('#progress_bar').css('width', value + '%').attr('aria-valuenow', value).text(value + '%');
- current_inflight--;
- continueReassign();
- },
- });
- }
- if (tablets_processed >= tablets_found.length) {
- $('#button_query').removeClass('disabled');
- $('#button_reassign').removeClass('disabled');
- }
- }
-
- function cancel() {
- tablets_processed = tablets_found.length;
- $('#tablets_processed_group').parent().css({visibility: 'hidden'});
- $('#current_inflight_group').parent().css({visibility: 'hidden'});
- $('#time_left_group').parent().css({visibility: 'hidden'});
- $('#progress_bar_group').parent().css({visibility: 'hidden'});
- }
-
- function reassignGroups() {
- $('#tablets_processed_group').parent().css({visibility: 'visible'});
- $('#current_inflight_group').parent().css({visibility: 'visible'});
- //$('#time_left_group').parent().css({visibility: 'visible'});
- $('#progress_bar_group').parent().css({visibility: 'visible'});
- $('#button_query').addClass('disabled');
- $('#button_reassign').addClass('disabled');
- tablets_processed = 0;
- current_inflight = 0;
- continueReassign();
- }
-
- function setDown(element, nodeId, down) {
- if (down && $(element).hasClass('glyphicon-ok')) {
- $(element).removeClass('glyphicon-ok');
- element.inProgress = true;
- $.ajax({url:'app?TabletID=' + hiveId + '&node=' + nodeId + '&page=SetDown&down=1', success: function(){ $(element).addClass('glyphicon-remove'); element.inProgress = false; }});
- } else if (!down && $(element).hasClass('glyphicon-remove')) {
- $(element).removeClass('glyphicon-remove');
- element.inProgress = true;
- $.ajax({url:'app?TabletID=' + hiveId + '&node=' + nodeId + '&page=SetDown&down=0', success: function(){ $(element).addClass('glyphicon-ok'); element.inProgress = false; }});
- }
- }
-
- function toggleDown(element, nodeId) {
- setDown(element, nodeId, $(element).hasClass('glyphicon-ok'));
- }
-
- function toggleFreeze(element, nodeId) {
- if ($(element).hasClass('glyphicon-play')) {
- $(element).removeClass('glyphicon-play');
- element.inProgress = true;
- $.ajax({url:'app?TabletID=' + hiveId + '&node=' + nodeId + '&page=SetFreeze&freeze=1', success: function(){ $(element).addClass('glyphicon-pause'); element.inProgress = false; }});
- } else if ($(element).hasClass('glyphicon-pause')) {
- $(element).removeClass('glyphicon-pause');
- element.inProgress = true;
- $.ajax({url:'app?TabletID=' + hiveId + '&node=' + nodeId + '&page=SetFreeze&freeze=0', success: function(){ $(element).addClass('glyphicon-play'); element.inProgress = false; }});
- }
- }
-
- function kickNode(element, nodeId) {
- $(element).removeClass('glyphicon-transfer');
- $.ajax({url:'app?TabletID=' + hiveId + '&node=' + nodeId + '&page=KickNode', success: function(){ $(element).addClass('glyphicon-transfer'); }});
- }
-
- function drainNode(element, nodeId) {
- $(element).removeClass('glyphicon-transfer');
- $.ajax({url:'app?TabletID=' + hiveId + '&node=' + nodeId + '&page=DrainNode', success: function(){ $(element).addClass('blinking'); }});
- }
-
- function rebalanceTablets(element) {
- $('#balancerProgress').html('o.O');
- $.ajax({url:'app?TabletID=' + hiveId + '&page=Rebalance'});
- }
-
- function toggleAlert() {
- $('#alert-placeholder').toggleClass('glyphicon-refresh');
- }
-
- function clearAlert() {
- $('#alert-placeholder').removeClass('glyphicon-refresh');
- }
- )___";
-
- out << R"___(
-
- var Nodes = {};
- var Empty = true;
-
- function onFreshData(result) {
- var nlen;
- try {
- if ("TotalTablets" in result) {
- $('#runningTablets').html((result.TotalTablets == 0 ? 0 : Math.floor(result.RunningTablets * 100 / result.TotalTablets)) + '% ' + result.RunningTablets + '/' + result.TotalTablets);
- //$('#aliveNodes').html(result.TotalNodes == 0 ? 0 : Math.floor(result.AliveNodes * 100 / result.TotalNodes) + '% ' + result.AliveNodes + '/' + result.TotalNodes);
- $('#resourceVariance').html(result.ResourceVariance);
- $('#resourceTotal').html(result.ResourceTotal);
- $('#bootQueue').html(result.BootQueueSize);
- $('#waitQueue').html(result.WaitQueueSize);
- if (result.BalancerProgress >= 0) {
- $('#balancerProgress').html(result.BalancerProgress + '%');
- } else {
- $('#balancerProgress').html('');
- }
- var old_nodes = {};
- if (Empty) {
- // initialization
- $('#node_table > tbody > tr').remove();
- Empty = false;
- } else {
- for (var id in Nodes) {
- old_nodes[id] = true;
- }
- }
- var was_append = false;
- nlen = result.Nodes.length;
- for (i = 0; i < nlen; i++) {
- var node = result.Nodes[i];
- var old_node = Nodes[node.Id];
- var nodeElement = $('#node' + node.Id).get(0);
- var nodeElement;
- if (old_node) {
- nodeElement = old_node.NodeElement;
- } else {
- nodeElement = $('<tr id="node' + node.Id + '"><td>' + node.Id + '</td>'
- + '<td></td>'
- + '<td></td>'
- + '<td></td>'
- + '<td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td>'
- + '<td style="text-align:center"><span title="Toggle node availability" onclick="toggleDown(this,' + node.Id + ')" style="cursor:pointer" class="active-mark glyphicon glyphicon-ok"></span></td>'
- + '<td style="text-align:center"><span title="Toggle node freeze" onclick="toggleFreeze(this,' + node.Id + ')" style="cursor:pointer" class="glyphicon glyphicon-play"></span></td>'
- + '<td style="text-align:center"><span title="Kick tablets on this node" onclick="kickNode(this,' + node.Id + ')" style="cursor:pointer" class="glyphicon glyphicon-transfer"></span></td>'
- + '<td style="text-align:center"><span title="Drain this node" onclick="drainNode(this,' + node.Id + ')" style="cursor:pointer" class="glyphicon glyphicon-log-out"></span></td>'
- + '</tr>').appendTo('#node_table > tbody').get(0);
- nodeElement.cells[1].innerHTML = '<a href="' + node.Host + ':8765">' + node.Name + '</a>';
- nodeElement.cells[2].innerHTML = node.DataCenter;
- was_append = true;
- }
- delete old_nodes[node.Id];
- if (!old_node || old_node.Alive != node.Alive) {
- if (node.Alive) {
- nodeElement.style.color = 'initial';
- } else {
- nodeElement.style.color = '#E0E0E0';
- }
- }
- var element = $(nodeElement.cells[14].children[0]);
- if (!element.hasOwnProperty("inProgress") || !element.inProgress) {
- if (!old_node || old_node.Down != node.Down) {
- if (node.Down) {
- element.removeClass('glyphicon-ok');
- element.addClass('glyphicon-remove');
- } else {
- element.removeClass('glyphicon-remove');
- element.addClass('glyphicon-ok');
- }
- }
- }
- element = $(nodeElement.cells[15].children[0]);
- if (!element.hasOwnProperty("inProgress") || !element.inProgress) {
- if (!old_node || old_node.Freeze != node.Freeze) {
- if (node.Freeze) {
- element.removeClass('glyphicon-play');
- element.addClass('glyphicon-pause');
- } else {
- element.removeClass('glyphicon-pause');
- element.addClass('glyphicon-play');
- }
- }
- }
- element = $(nodeElement.cells[17].children[0]);
- if (!element.hasOwnProperty("inProgress") || !element.inProgress) {
- if (!old_node || old_node.Drain != node.Drain) {
- if (node.Drain) {
- element.addClass('blinking');
- } else {
- element.removeClass('blinking');
- }
- }
- }
- if (!old_node || old_node.Name != node.Name) {
- nodeElement.cells[1].innerHTML = '<a href="' + node.Host + ':8765">' + node.Name + '</a>';
- }
- if (!old_node || old_node.DataCenter != node.DataCenter) {
- nodeElement.cells[2].innerHTML = node.DataCenter;
- }
- if (!old_node || old_node.Domain != node.Domain) {
- nodeElement.cells[3].innerHTML = node.Domain;
- }
- if (!old_node || old_node.Uptime != node.Uptime) {
- nodeElement.cells[4].innerHTML = node.Uptime;
- }
- if (!old_node || old_node.Unknown != node.Unknown) {
- nodeElement.cells[5].innerHTML = node.Unknown;
- }
- if (!old_node || old_node.Starting != node.Starting) {
- nodeElement.cells[6].innerHTML = node.Starting;
- }
- if (!old_node || old_node.Running != node.Running) {
- nodeElement.cells[7].innerHTML = node.Running;
- }
- if (!old_node || old_node.Types != node.Types) {
- nodeElement.cells[8].innerHTML = node.Types;
- }
- if (!old_node || old_node.Usage != node.Usage) {
- nodeElement.cells[9].innerHTML = node.Usage;
- }
- if (!old_node || old_node.ResourceValues[0] != node.ResourceValues[0]) {
- nodeElement.cells[10].innerHTML = node.ResourceValues[0];
- }
- if (!old_node || old_node.ResourceValues[1] != node.ResourceValues[1]) {
- nodeElement.cells[11].innerHTML = node.ResourceValues[1];
- }
- if (!old_node || old_node.ResourceValues[2] != node.ResourceValues[2]) {
- nodeElement.cells[12].innerHTML = node.ResourceValues[2];
- }
- if (!old_node || old_node.ResourceValues[3] != node.ResourceValues[3]) {
- nodeElement.cells[13].innerHTML = node.ResourceValues[3];
- }
- node.NodeElement = nodeElement;
- Nodes[node.Id] = node;
- }
- for (var id in old_nodes) {
- $('#node' + id).remove();
- delete Nodes[id];
- }
- if (was_append) {
- $('#node_table > tbody > tr').sort(function(a,b) {
- if (a.cells[3].innerHTML > b.cells[3].innerHTML)
- return 1;
- if (a.cells[3].innerHTML < b.cells[3].innerHTML)
- return -1;
- return parseInt(a.cells[0].innerHTML, 10) - parseInt(b.cells[0].innerHTML, 10);
- }).appendTo('#node_table > tbody');
- }
- }
- clearAlert();
- }
- catch(err) {
- toggleAlert();
- }
- setTimeout(function(){updateData();}, 500 + nlen);
- }
-
- function updateData() {
- $.ajax({url:'app?TabletID=' + hiveId + '&page=LandingData',
- success: function(result){ onFreshData(result); },
- error: function(){ toggleAlert(); setTimeout(updateData, 1000); }
- });
- }
-
- )___";
- out << "</script>";
- out << "</body>";
- }
-};
-
-class TTxMonEvent_LandingData : public TTransactionBase<THive> {
-public:
+ }
+ if (!pr.second.IsUnknown()) {
+ ++nodes;
+ }
+ }
+
+ out << "<head>";
+ out << "<style>";
+ out << "table.simple-table1 td { padding: 1px 3px; }";
+ out << "table.simple-table1 td:nth-child(1) { text-align: right; }";
+ out << "table.simple-table2 th { text-align: right; }";
+ out << "table.simple-table2 tr:nth-child(1) > th:nth-child(2) { text-align: left; }";
+ out << "table.simple-table2 tr:nth-child(1) > th:nth-child(3) { text-align: left; }";
+ out << "table.simple-table2 tr:nth-child(1) > th:nth-child(4) { text-align: left; }";
+ out << "table.simple-table2 td { text-align: right; }";
+ out << "table.simple-table2 td:nth-child(2) { text-align: left; }";
+ out << "table.simple-table2 td:nth-child(3) { text-align: left; }";
+ out << "table.simple-table2 td:nth-child(4) { text-align: left; }";
+ out << ".table-hover tbody tr:hover > td { background-color: #9dddf2; }";
+ out << ".blinking { animation:blinkingText 0.8s infinite; }";
+ out << "@keyframes blinkingText { 0% { color: #000; } 49% { color: #000; } 60% { color: transparent; } 99% { color:transparent; } 100% { color: #000; } }";
+ out << "</style>";
+ out << "</head>";
+ out << "<body>";
+ out << "<table class='simple-table1'>";
+
+ TSubDomainKey domainId = Self->GetMySubDomainKey();
+ if (domainId) {
+ out << "<tr><td>" << "Tenant:" << "</td>";
+ TDomainInfo* domainInfo = Self->FindDomain(domainId);
+ if (domainInfo && domainInfo->Path) {
+ out << "<td>" << domainInfo->Path << "</td>";
+ } else {
+ out << "<td>" << domainId << "</td>";
+ }
+ out << "<td><span id='alert-placeholder' class='glyphicon' style='height:14px'></span></td>";
+ out << "</tr>";
+ }
+
+ /*out << "<tr><td>" << "Nodes:" << "</td><td id='aliveNodes'>" << (nodes == 0 ? 0 : aliveNodes * 100 / nodes) << "% "
+ << aliveNodes << "/" << nodes << "</td></tr>";*/
+ out << "<tr><td>" << "Tablets:" << "</td><td id='runningTablets'>" << (tablets == 0 ? 0 : runningTablets * 100 / tablets) << "% "
+ << runningTablets << "/" << tablets << "</td></tr>";
+ out << "<tr><td title='Rebalance all tablets' style='cursor:pointer' onclick='rebalanceTablets(this)'>Balancer: </td><td id='balancerProgress'>"
+ << (Self->BalancerProgress >= 0 ? Sprintf("%d%%", Self->BalancerProgress) : TString()) << "</td></tr>";
+ out << "<tr><td>" << "Boot Queue:" << "</td><td id='bootQueue'>" << Self->BootQueue.BootQueue.size() << "</td></tr>";
+ out << "<tr><td>" << "Wait Queue:" << "</td><td id='waitQueue'>" << Self->BootQueue.WaitQueue.size() << "</td></tr>";
+ out << "<tr><td>" << "Resource Total: " << "</td><td id='resourceTotal'>" << GetResourceValuesText(Self->TotalRawResourceValues) << "</td></tr>";
+ out << "<tr><td>" << "Resource StDev: " << "</td><td id='resourceVariance'>"
+ << convert(Self->GetStDevResourceValues(), [](double d) -> TString { return Sprintf("%.9f", d); }) << "</td></tr>";
+ out << "</table>";
+
+ out << "<table id='node_table' class='table simple-table2 table-hover table-condensed'>";
+ out << "<thead><tr>"
+ "<th rowspan='2' style='min-width:70px'>Node</th>"
+ "<th rowspan='2' style='min-width:280px'>Name</th>"
+ "<th rowspan='2' style='min-width:50px'>DC</th>"
+ "<th rowspan='2' style='min-width:280px'>Domain</th>"
+ "<th rowspan='2' style='min-width:120px'>Uptime</th>"
+ "<th rowspan='2'>Unknown</th>"
+ "<th rowspan='2'>Starting</th>"
+ "<th rowspan='2'>Running</th>"
+ "<th rowspan='2' style='min-width:160px'>Types</th>"
+ "<th rowspan='2' style='min-width:110px'>Usage</th>"
+ "<th colspan='4' style='text-align:center'>Resources</td>"
+ "<th rowspan='2' style='text-align:center'>Active</th>"
+ "<th rowspan='2' style='text-align:center'>Freeze</th>"
+ "<th rowspan='2' style='text-align:center'>Kick</th>"
+ "<th rowspan='2' style='text-align:center'>Drain</th></tr>"
+ "<tr>"
+ "<th style='min-width:70px'>cnt</th>"
+ "<th style='min-width:100px'>cpu</th>"
+ "<th style='min-width:100px'>mem</th>"
+ "<th style='min-width:100px'>net</th></tr>"
+ "</thead>";
+ out << "<tbody>";
+ out << "<tr><td colspan=18 style='text-align:center'><button type='button' class='btn btn-info' onclick='updateData();' style='margin-top:30px;margin-bottom:30px'>View Nodes</button></td></tr>";
+ out << "</tbody>";
+ out << "</table>";
+
+ out << "<div class='row' style='margin-top:100px'>";
+ out << "<div class='col-sm-1 col-md-1' style='text-align:center'>";
+ out << "<button type='button' class='btn btn-info' onclick='location.href=\"app?TabletID=" << Self->HiveId << "&page=MemStateTablets&bad=1&max=1000\";' style='width:138px'>Bad Tablets</button>";
+ out << "</div>";
+ out << "<div class='col-sm-1 col-md-1' style='text-align:center'>";
+ out << "<button type='button' class='btn btn-info' onclick='location.href=\"app?TabletID=" << Self->HiveId << "&page=MemStateTablets&sort=weight&max=1000\";' style='width:138px'>Heavy Tablets</button>";
+ out << "</div>";
+ out << "<div class='col-sm-1 col-md-1' style='text-align:center'>";
+ out << "<button type='button' class='btn btn-info' onclick='location.href=\"app?TabletID=" << Self->HiveId << "&page=MemStateTablets&wait=1&max=1000\";' style='width:138px'>Waiting Tablets</button>";
+ out << "</div>";
+ out << "<div class='col-sm-1 col-md-1' style='text-align:center'>";
+ out << "<button type='button' class='btn btn-info' onclick='location.href=\"app?TabletID=" << Self->HiveId << "&page=Resources\";' style='width:138px'>Resources</button>";
+ out << "</div>";
+ out << "<div class='col-sm-1 col-md-1' style='text-align:center'>";
+ out << "<button type='button' class='btn btn-info' onclick='location.href=\"app?TabletID=" << Self->HiveId << "&page=MemStateDomains\";' style='width:138px'>Tenants</button>";
+ out << "</div>";
+ out << "</div>";
+
+ out << "<div class='row' style='margin-top:10px'>";
+ out << "<div class='col-sm-1 col-md-1' style='text-align:center'>";
+ out << "<button type='button' class='btn btn-info' onclick='location.href=\"app?TabletID=" << Self->HiveId << "&page=MemStateNodes\";' style='width:138px'>Nodes</button>";
+ out << "</div>";
+ out << "<div class='col-sm-1 col-md-1' style='text-align:center'>";
+ out << "<button type='button' class='btn btn-info' onclick='location.href=\"app?TabletID=" << Self->HiveId << "&page=Storage\";' style='width:138px'>Storage</button>";
+ out << "</div>";
+ out << "<div class='col-sm-1 col-md-1' style='text-align:center'>";
+ out << "<button type='button' class='btn btn-info' onclick='location.href=\"app?TabletID=" << Self->HiveId << "&page=Groups\";' style='width:138px'>Groups</button>";
+ out << "</div>";
+ out << "<div class='col-sm-1 col-md-1' style='text-align:center'>";
+ out << "<button type='button' class='btn btn-info' onclick='location.href=\"app?TabletID=" << Self->HiveId << "&page=Settings\";' style='width:138px'>Settings</button>";
+ out << "</div>";
+ out << "<div class='col-sm-1 col-md-1' style='text-align:center'>";
+ out << "<button type='button' class='btn btn-info' data-toggle='modal' data-target='#reassign-groups' style='width:138px'>Reassign Groups</button>";
+ out << "</div>";
+ out << "</div>";
+
+ out << "<div class='row' style='margin-top:50px'>";
+
+ out << "<div class='form-group'><label for='tablets_group' style='padding-right:10px'>Groups of Tablet:</label>";
+ out << "<input type='text' id='tablets_group'><input type='submit' value='open' onclick=\"window.open(document.URL + '&page=Groups&tablet_id=' + this.previousSibling.value);\">";
+ out << "</div>";
+
+ out << "<div class='form-group'><label for='groups_tablet' style='padding-right:10px'>Tablets of Group:</label>";
+ out << "<input type='text' id='groups_tablet'><input type='submit' value='open' onclick=\"window.open(document.URL + '&page=Groups&group_id=' + this.previousSibling.value);\">";
+ out << "</div>";
+
+ out << "</div>";
+
+ out << R"___(
+ <div class='modal fade' id='reassign-groups' role='dialog'>
+ <div class='modal-dialog' style='width:60%'>
+ <div class='modal-content'>
+ <div class='modal-header'>
+ <button type='button' class='close' data-dismiss='modal' onclick='cancel();'>&times;</button>
+ <h4 class='modal-title'>Reassign Tablets Groups</h4>
+ </div>
+ <div class='modal-body'>
+ <div class='row'>
+ <div class='col-md-5'>
+ <label for='tablet_storage_pool_group'>Storage pool</label>
+ <div in='tablet_storage_pool_group' class='input-group' style='width:100%'>
+ <input id='tablet_storage_pool' type='text' min='0' max='255' class='form-control'>
+ </div>
+ <label for='tablet_storage_group_group' style='margin-top:20px'>Storage group</label>
+ <div in='tablet_storage_group_group' class='input-group'>
+ <input id='tablet_storage_group' type='number' class='form-control'>
+ <span class='input-group-addon'>group id</span>
+ </div>
+ </div>
+ <div class='col-md-4'>
+ <label for='tablet_type'>Type</label>
+ <select id='tablet_type' class='form-control'>
+ <option selected value>Any</option>
+ </select>
+ <label for='tablet_from_channel_group' style='margin-top:20px'>Channels</label>
+ <div in='tablet_from_channel_group' class='input-group'>
+ <input id='tablet_from_channel' type='number' value='0' min='0' max='255' class='form-control'>
+ <span class='input-group-addon'>from</span>
+ <input id='tablet_to_channel' type='number' value='255' min='0' max='255' class='form-control'>
+ <span class='input-group-addon'>to</span>
+ </div>
+ </div>
+ <div class='col-md-3'>
+ <label for='tablet_percent_group'>Percent</label>
+ <div in='tablet_percent_group' class='input-group'>
+ <input id='tablet_percent' type='number' value='100' min='1' max='100' class='form-control'>
+ <span class='input-group-addon'>%</span>
+ </div>
+ <label for='tablet_reassign_inflight_group' style='margin-top:20px'>Inflight</label>
+ <div id='tablet_reassign_inflight_group' class='input-group'>
+ <input id='tablet_reassign_inflight' type='number' value='1' min='1' max='10' class='form-control'>
+ <span class='input-group-addon'>1-10</span>
+ </div>
+ </div>
+ </div>
+ <div class='row'>
+ <div class='col-md-12'>
+ <hr>
+ </div>
+ </div>
+ <div class='row'>
+ <div class='col-md-2' style='visibility:hidden'>
+ <label for='tablets_found_group'>Found</label>
+ <div id='tablets_found_group'>
+ <span id='tablets_found'>0</span>
+ </div>
+ </div>
+ <div class='col-md-2' style='visibility:hidden'>
+ <label for='tablets_processed_group'>Processed</label>
+ <div id='tablets_processed_group'>
+ <span id='tablets_processed'></span>
+ </div>
+ </div>
+ <div class='col-md-2' style='visibility:hidden'>
+ <label for='current_inflight_group'>Inflight</label>
+ <div id='current_inflight_group'>
+ <span id='current_inflight'></span>
+ </div>
+ </div>
+ <div class='col-md-2' style='visibility:hidden'>
+ <label for='time_left_group'>Time left</label>
+ <div id='time_left_group'>
+ <span id='time_left'></span>
+ </div>
+ </div>
+ <div class='col-md-2'>
+ </div>
+ <div class='col-md-2'>
+
+ </div>
+ </div>
+ <div class='row' style='margin-top:20px'>
+ <div class='col-md-12' style='visibility:hidden'>
+ <label for='progress_bar_group'>Progress</label>
+ <div id='progress_bar_group' class='progress' style='height:30px'>
+ <div id='progress_bar' class='progress-bar' role='progressbar' style='width:0%;font-size:20px;padding-top:5px' aria-valuenow='0' aria-valuemin='0' aria-valuemax='100'></div>
+ </div>
+ </div>
+ </div>
+ </div>
+ <div class='modal-footer'>
+ <span id='status_text' style='float:left'></span>
+ <button id='button_query' type='submit' class='btn btn-default' onclick='queryTablets();'>Query</button>
+ <button id='button_reassign' type='submit' class='btn btn-default disabled' onclick='reassignGroups();'>Reassign</button>
+ <button type='button' class='btn btn-default' data-dismiss='modal' onclick='cancel();'>Cancel</button>
+ </div>
+ </div>
+ </div>
+ </div>
+ )___";
+
+ out << "<script>";
+ out << "var hiveId = '" << Self->HiveId << "';";
+ out << "var tablets = [";
+ for (auto itTablet = tabletTypesToChannels.begin(); itTablet != tabletTypesToChannels.end(); ++itTablet) {
+ if (itTablet != tabletTypesToChannels.begin()) {
+ out << ',';
+ }
+ out << "{type:" << (ui32)(itTablet->first) << ",name:'" << TTabletTypes::TypeToStr(itTablet->first) << "',channels:" << itTablet->second << "}";
+ }
+ out << "];";
+ out << R"___(
+ $('.container')
+ .toggleClass('container container-fluid')
+ .css('padding-left', '1%')
+ .css('padding-right', '1%');
+
+ function initReassignGroups() {
+ var domTabletType = document.getElementById('tablet_type');
+ for (var tab = 0; tab < tablets.length; tab++) {
+ var opt = document.createElement('option');
+ opt.text = tablets[tab].name;
+ opt.value = tablets[tab].type;
+ domTabletType.add(opt);
+ }
+ }
+
+ )___";
+
+ out << R"___(
+ initReassignGroups();
+
+ var tablets_found;
+
+ function queryTablets() {
+ var storage_pool = $('#tablet_storage_pool').val();
+ var storage_group = $('#tablet_storage_group').val();
+ var tablet_type = $('#tablet_type').val();
+ var channel_from = $('#tablet_from_channel').val();
+ var channel_to = $('#tablet_to_channel').val();
+ var percent = $('#tablet_percent').val();
+ var url = 'app?TabletID=' + hiveId + '&page=FindTablet';
+ if (storage_pool) {
+ url = url + '&storagePool=' + storage_pool;
+ }
+ if (storage_group) {
+ url = url + '&group=' + storage_group;
+ }
+ if (tablet_type) {
+ url = url + '&type=' + tablet_type;
+ }
+ if (channel_from) {
+ url = url + '&channelFrom=' + channel_from;
+ }
+ if (channel_to) {
+ url = url + '&channelTo=' + channel_to;
+ }
+ if (percent) {
+ url = url + '&percent=' + percent;
+ }
+ $.ajax({
+ url: url,
+ success: function(result) {
+ tablets_found = result;
+ $('#tablets_found_group').parent().css({visibility: 'visible'});
+ $('#tablets_found').text(tablets_found.length);
+ $('#button_reassign').removeClass('disabled');
+ },
+ error: function(jqXHR, status) {
+ $('#status_text').text(status);
+ }
+ });
+ }
+
+ var tables_processed;
+ var current_inflight;
+
+ function continueReassign() {
+ var max_inflight = $('#tablet_reassign_inflight').val();
+ while (tablets_processed < tablets_found.length && current_inflight < max_inflight) {
+ var tablet = tablets_found[tablets_processed];
+ tablets_processed++;
+ current_inflight++;
+ $('#current_inflight').text(current_inflight);
+ $.ajax({
+ url: 'app?TabletID=' + hiveId
+ + '&page=ReassignTablet&tablet=' + tablet.tabletId
+ + '&channels=' + tablet.channels
+ + '&wait=1',
+ success: function() {
+
+ },
+ error: function(jqXHR, status) {
+ $('#status_text').text(status);
+ },
+ complete: function() {
+ $('#tablets_processed').text(tablets_processed);
+ var value = Number(tablets_processed * 100 / tablets_found.length).toFixed();
+ $('#progress_bar').css('width', value + '%').attr('aria-valuenow', value).text(value + '%');
+ current_inflight--;
+ continueReassign();
+ },
+ });
+ }
+ if (tablets_processed >= tablets_found.length) {
+ $('#button_query').removeClass('disabled');
+ $('#button_reassign').removeClass('disabled');
+ }
+ }
+
+ function cancel() {
+ tablets_processed = tablets_found.length;
+ $('#tablets_processed_group').parent().css({visibility: 'hidden'});
+ $('#current_inflight_group').parent().css({visibility: 'hidden'});
+ $('#time_left_group').parent().css({visibility: 'hidden'});
+ $('#progress_bar_group').parent().css({visibility: 'hidden'});
+ }
+
+ function reassignGroups() {
+ $('#tablets_processed_group').parent().css({visibility: 'visible'});
+ $('#current_inflight_group').parent().css({visibility: 'visible'});
+ //$('#time_left_group').parent().css({visibility: 'visible'});
+ $('#progress_bar_group').parent().css({visibility: 'visible'});
+ $('#button_query').addClass('disabled');
+ $('#button_reassign').addClass('disabled');
+ tablets_processed = 0;
+ current_inflight = 0;
+ continueReassign();
+ }
+
+ function setDown(element, nodeId, down) {
+ if (down && $(element).hasClass('glyphicon-ok')) {
+ $(element).removeClass('glyphicon-ok');
+ element.inProgress = true;
+ $.ajax({url:'app?TabletID=' + hiveId + '&node=' + nodeId + '&page=SetDown&down=1', success: function(){ $(element).addClass('glyphicon-remove'); element.inProgress = false; }});
+ } else if (!down && $(element).hasClass('glyphicon-remove')) {
+ $(element).removeClass('glyphicon-remove');
+ element.inProgress = true;
+ $.ajax({url:'app?TabletID=' + hiveId + '&node=' + nodeId + '&page=SetDown&down=0', success: function(){ $(element).addClass('glyphicon-ok'); element.inProgress = false; }});
+ }
+ }
+
+ function toggleDown(element, nodeId) {
+ setDown(element, nodeId, $(element).hasClass('glyphicon-ok'));
+ }
+
+ function toggleFreeze(element, nodeId) {
+ if ($(element).hasClass('glyphicon-play')) {
+ $(element).removeClass('glyphicon-play');
+ element.inProgress = true;
+ $.ajax({url:'app?TabletID=' + hiveId + '&node=' + nodeId + '&page=SetFreeze&freeze=1', success: function(){ $(element).addClass('glyphicon-pause'); element.inProgress = false; }});
+ } else if ($(element).hasClass('glyphicon-pause')) {
+ $(element).removeClass('glyphicon-pause');
+ element.inProgress = true;
+ $.ajax({url:'app?TabletID=' + hiveId + '&node=' + nodeId + '&page=SetFreeze&freeze=0', success: function(){ $(element).addClass('glyphicon-play'); element.inProgress = false; }});
+ }
+ }
+
+ function kickNode(element, nodeId) {
+ $(element).removeClass('glyphicon-transfer');
+ $.ajax({url:'app?TabletID=' + hiveId + '&node=' + nodeId + '&page=KickNode', success: function(){ $(element).addClass('glyphicon-transfer'); }});
+ }
+
+ function drainNode(element, nodeId) {
+ $(element).removeClass('glyphicon-transfer');
+ $.ajax({url:'app?TabletID=' + hiveId + '&node=' + nodeId + '&page=DrainNode', success: function(){ $(element).addClass('blinking'); }});
+ }
+
+ function rebalanceTablets(element) {
+ $('#balancerProgress').html('o.O');
+ $.ajax({url:'app?TabletID=' + hiveId + '&page=Rebalance'});
+ }
+
+ function toggleAlert() {
+ $('#alert-placeholder').toggleClass('glyphicon-refresh');
+ }
+
+ function clearAlert() {
+ $('#alert-placeholder').removeClass('glyphicon-refresh');
+ }
+ )___";
+
+ out << R"___(
+
+ var Nodes = {};
+ var Empty = true;
+
+ function onFreshData(result) {
+ var nlen;
+ try {
+ if ("TotalTablets" in result) {
+ $('#runningTablets').html((result.TotalTablets == 0 ? 0 : Math.floor(result.RunningTablets * 100 / result.TotalTablets)) + '% ' + result.RunningTablets + '/' + result.TotalTablets);
+ //$('#aliveNodes').html(result.TotalNodes == 0 ? 0 : Math.floor(result.AliveNodes * 100 / result.TotalNodes) + '% ' + result.AliveNodes + '/' + result.TotalNodes);
+ $('#resourceVariance').html(result.ResourceVariance);
+ $('#resourceTotal').html(result.ResourceTotal);
+ $('#bootQueue').html(result.BootQueueSize);
+ $('#waitQueue').html(result.WaitQueueSize);
+ if (result.BalancerProgress >= 0) {
+ $('#balancerProgress').html(result.BalancerProgress + '%');
+ } else {
+ $('#balancerProgress').html('');
+ }
+ var old_nodes = {};
+ if (Empty) {
+ // initialization
+ $('#node_table > tbody > tr').remove();
+ Empty = false;
+ } else {
+ for (var id in Nodes) {
+ old_nodes[id] = true;
+ }
+ }
+ var was_append = false;
+ nlen = result.Nodes.length;
+ for (i = 0; i < nlen; i++) {
+ var node = result.Nodes[i];
+ var old_node = Nodes[node.Id];
+ var nodeElement = $('#node' + node.Id).get(0);
+ var nodeElement;
+ if (old_node) {
+ nodeElement = old_node.NodeElement;
+ } else {
+ nodeElement = $('<tr id="node' + node.Id + '"><td>' + node.Id + '</td>'
+ + '<td></td>'
+ + '<td></td>'
+ + '<td></td>'
+ + '<td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td>'
+ + '<td style="text-align:center"><span title="Toggle node availability" onclick="toggleDown(this,' + node.Id + ')" style="cursor:pointer" class="active-mark glyphicon glyphicon-ok"></span></td>'
+ + '<td style="text-align:center"><span title="Toggle node freeze" onclick="toggleFreeze(this,' + node.Id + ')" style="cursor:pointer" class="glyphicon glyphicon-play"></span></td>'
+ + '<td style="text-align:center"><span title="Kick tablets on this node" onclick="kickNode(this,' + node.Id + ')" style="cursor:pointer" class="glyphicon glyphicon-transfer"></span></td>'
+ + '<td style="text-align:center"><span title="Drain this node" onclick="drainNode(this,' + node.Id + ')" style="cursor:pointer" class="glyphicon glyphicon-log-out"></span></td>'
+ + '</tr>').appendTo('#node_table > tbody').get(0);
+ nodeElement.cells[1].innerHTML = '<a href="' + node.Host + ':8765">' + node.Name + '</a>';
+ nodeElement.cells[2].innerHTML = node.DataCenter;
+ was_append = true;
+ }
+ delete old_nodes[node.Id];
+ if (!old_node || old_node.Alive != node.Alive) {
+ if (node.Alive) {
+ nodeElement.style.color = 'initial';
+ } else {
+ nodeElement.style.color = '#E0E0E0';
+ }
+ }
+ var element = $(nodeElement.cells[14].children[0]);
+ if (!element.hasOwnProperty("inProgress") || !element.inProgress) {
+ if (!old_node || old_node.Down != node.Down) {
+ if (node.Down) {
+ element.removeClass('glyphicon-ok');
+ element.addClass('glyphicon-remove');
+ } else {
+ element.removeClass('glyphicon-remove');
+ element.addClass('glyphicon-ok');
+ }
+ }
+ }
+ element = $(nodeElement.cells[15].children[0]);
+ if (!element.hasOwnProperty("inProgress") || !element.inProgress) {
+ if (!old_node || old_node.Freeze != node.Freeze) {
+ if (node.Freeze) {
+ element.removeClass('glyphicon-play');
+ element.addClass('glyphicon-pause');
+ } else {
+ element.removeClass('glyphicon-pause');
+ element.addClass('glyphicon-play');
+ }
+ }
+ }
+ element = $(nodeElement.cells[17].children[0]);
+ if (!element.hasOwnProperty("inProgress") || !element.inProgress) {
+ if (!old_node || old_node.Drain != node.Drain) {
+ if (node.Drain) {
+ element.addClass('blinking');
+ } else {
+ element.removeClass('blinking');
+ }
+ }
+ }
+ if (!old_node || old_node.Name != node.Name) {
+ nodeElement.cells[1].innerHTML = '<a href="' + node.Host + ':8765">' + node.Name + '</a>';
+ }
+ if (!old_node || old_node.DataCenter != node.DataCenter) {
+ nodeElement.cells[2].innerHTML = node.DataCenter;
+ }
+ if (!old_node || old_node.Domain != node.Domain) {
+ nodeElement.cells[3].innerHTML = node.Domain;
+ }
+ if (!old_node || old_node.Uptime != node.Uptime) {
+ nodeElement.cells[4].innerHTML = node.Uptime;
+ }
+ if (!old_node || old_node.Unknown != node.Unknown) {
+ nodeElement.cells[5].innerHTML = node.Unknown;
+ }
+ if (!old_node || old_node.Starting != node.Starting) {
+ nodeElement.cells[6].innerHTML = node.Starting;
+ }
+ if (!old_node || old_node.Running != node.Running) {
+ nodeElement.cells[7].innerHTML = node.Running;
+ }
+ if (!old_node || old_node.Types != node.Types) {
+ nodeElement.cells[8].innerHTML = node.Types;
+ }
+ if (!old_node || old_node.Usage != node.Usage) {
+ nodeElement.cells[9].innerHTML = node.Usage;
+ }
+ if (!old_node || old_node.ResourceValues[0] != node.ResourceValues[0]) {
+ nodeElement.cells[10].innerHTML = node.ResourceValues[0];
+ }
+ if (!old_node || old_node.ResourceValues[1] != node.ResourceValues[1]) {
+ nodeElement.cells[11].innerHTML = node.ResourceValues[1];
+ }
+ if (!old_node || old_node.ResourceValues[2] != node.ResourceValues[2]) {
+ nodeElement.cells[12].innerHTML = node.ResourceValues[2];
+ }
+ if (!old_node || old_node.ResourceValues[3] != node.ResourceValues[3]) {
+ nodeElement.cells[13].innerHTML = node.ResourceValues[3];
+ }
+ node.NodeElement = nodeElement;
+ Nodes[node.Id] = node;
+ }
+ for (var id in old_nodes) {
+ $('#node' + id).remove();
+ delete Nodes[id];
+ }
+ if (was_append) {
+ $('#node_table > tbody > tr').sort(function(a,b) {
+ if (a.cells[3].innerHTML > b.cells[3].innerHTML)
+ return 1;
+ if (a.cells[3].innerHTML < b.cells[3].innerHTML)
+ return -1;
+ return parseInt(a.cells[0].innerHTML, 10) - parseInt(b.cells[0].innerHTML, 10);
+ }).appendTo('#node_table > tbody');
+ }
+ }
+ clearAlert();
+ }
+ catch(err) {
+ toggleAlert();
+ }
+ setTimeout(function(){updateData();}, 500 + nlen);
+ }
+
+ function updateData() {
+ $.ajax({url:'app?TabletID=' + hiveId + '&page=LandingData',
+ success: function(result){ onFreshData(result); },
+ error: function(){ toggleAlert(); setTimeout(updateData, 1000); }
+ });
+ }
+
+ )___";
+ out << "</script>";
+ out << "</body>";
+ }
+};
+
+class TTxMonEvent_LandingData : public TTransactionBase<THive> {
+public:
const TActorId Source;
- TAutoPtr<NMon::TEvRemoteHttpInfo> Event;
- TCgiParameters Cgi;
-
+ TAutoPtr<NMon::TEvRemoteHttpInfo> Event;
+ TCgiParameters Cgi;
+
TTxMonEvent_LandingData(const TActorId &source, NMon::TEvRemoteHttpInfo::TPtr& ev, TSelf *hive)
- : TBase(hive)
- , Source(source)
- , Event(ev->Release())
- , Cgi(Event->Cgi())
- {}
-
- TTxType GetTxType() const override { return NHive::TXTYPE_MON_LANDING_DATA; }
-
- bool Execute(TTransactionContext &txc, const TActorContext& ctx) override {
+ : TBase(hive)
+ , Source(source)
+ , Event(ev->Release())
+ , Cgi(Event->Cgi())
+ {}
+
+ TTxType GetTxType() const override { return NHive::TXTYPE_MON_LANDING_DATA; }
+
+ bool Execute(TTransactionContext &txc, const TActorContext& ctx) override {
Y_UNUSED(txc);
- TStringStream str;
- RenderJSONPage(str);
- ctx.Send(Source, new NMon::TEvRemoteJsonInfoRes(str.Str()));
- return true;
- }
-
- void Complete(const TActorContext& ctx) override {
+ TStringStream str;
+ RenderJSONPage(str);
+ ctx.Send(Source, new NMon::TEvRemoteJsonInfoRes(str.Str()));
+ return true;
+ }
+
+ void Complete(const TActorContext& ctx) override {
Y_UNUSED(ctx);
- }
-
+ }
+
void RenderJSONPage(IOutputStream &out) {
- ui64 nodes = 0;
- ui64 tablets = 0;
- ui64 runningTablets = 0;
- ui64 aliveNodes = 0;
+ ui64 nodes = 0;
+ ui64 tablets = 0;
+ ui64 runningTablets = 0;
+ ui64 aliveNodes = 0;
THashMap<ui32, TMap<TString, ui32>> tabletsByNodeByType;
-
- for (const auto& pr : Self->Tablets) {
- if (pr.second.IsRunning()) {
- ++runningTablets;
- ++tabletsByNodeByType[pr.second.NodeId][TTxMonEvent_Landing::GetTabletType(pr.second.Type)];
- }
+
+ for (const auto& pr : Self->Tablets) {
+ if (pr.second.IsRunning()) {
+ ++runningTablets;
+ ++tabletsByNodeByType[pr.second.NodeId][TTxMonEvent_Landing::GetTabletType(pr.second.Type)];
+ }
for (const auto& sl : pr.second.Followers) {
- if (sl.IsRunning()) {
- ++runningTablets;
- ++tabletsByNodeByType[sl.NodeId][TTxMonEvent_Landing::GetTabletType(pr.second.Type) + "s"];
- }
- ++tablets;
- }
- ++tablets;
- }
- for (const auto& pr : Self->Nodes) {
- if (pr.second.IsAlive()) {
- ++aliveNodes;
- }
- if (!pr.second.IsUnknown()) {
- ++nodes;
- }
- }
-
- NJson::TJsonValue jsonData;
-
- jsonData["TotalTablets"] = tablets;
- jsonData["RunningTablets"] = runningTablets;
- jsonData["TotalNodes"] = nodes;
- jsonData["AliveNodes"] = aliveNodes;
- jsonData["ResourceTotal"] = GetResourceValuesText(Self->TotalRawResourceValues);
- jsonData["ResourceVariance"] = GetResourceValuesText(Self->GetStDevResourceValues());//, [](double d) -> TString { return Sprintf("%.9f", d); });
- jsonData["BootQueueSize"] = Self->BootQueue.BootQueue.size();
- jsonData["WaitQueueSize"] = Self->BootQueue.WaitQueue.size();
- jsonData["BalancerProgress"] = Self->BalancerProgress;
-
- TVector<TNodeInfo*> nodeInfos;
- nodeInfos.reserve(Self->Nodes.size());
- for (auto& pr : Self->Nodes) {
- if (!pr.second.IsUnknown()) {
- nodeInfos.push_back(&pr.second);
- }
- }
- std::sort(nodeInfos.begin(), nodeInfos.end(), [](TNodeInfo* a, TNodeInfo* b) -> bool {
- return std::make_tuple(a->ServicedDomains, a->Id) < std::make_tuple(b->ServicedDomains, b->Id);
- });
-
- TInstant aliveLine = TInstant::Now() - TDuration::Minutes(10);
-
- NJson::TJsonValue& jsonNodes = jsonData["Nodes"];
- for (TNodeInfo* nodeInfo : nodeInfos) {
- TNodeInfo& node = *nodeInfo;
- TNodeId id = node.Id;
-
- if (!node.IsAlive() && TInstant::MilliSeconds(node.Statistics.GetLastAliveTimestamp()) < aliveLine) {
- continue;
- }
-
- NJson::TJsonValue& jsonNode = jsonNodes.AppendValue(NJson::TJsonValue());
- TString name = "";
- TString host;
- auto it = Self->NodesInfo.find(node.Id);
- if (it != Self->NodesInfo.end()) {
- auto &ni = it->second;
- if (ni.Host.empty()) {
- name = ni.Address + ":" + ToString(ni.Port);
- host = ni.Address;
- } else {
- name = ni.Host.substr(0, ni.Host.find('.')) + ":" + ToString(ni.Port);
- host = ni.Host;
- }
- }
-
- jsonNode["Id"] = id;
- jsonNode["Host"] = host;
- jsonNode["Name"] = name;
+ if (sl.IsRunning()) {
+ ++runningTablets;
+ ++tabletsByNodeByType[sl.NodeId][TTxMonEvent_Landing::GetTabletType(pr.second.Type) + "s"];
+ }
+ ++tablets;
+ }
+ ++tablets;
+ }
+ for (const auto& pr : Self->Nodes) {
+ if (pr.second.IsAlive()) {
+ ++aliveNodes;
+ }
+ if (!pr.second.IsUnknown()) {
+ ++nodes;
+ }
+ }
+
+ NJson::TJsonValue jsonData;
+
+ jsonData["TotalTablets"] = tablets;
+ jsonData["RunningTablets"] = runningTablets;
+ jsonData["TotalNodes"] = nodes;
+ jsonData["AliveNodes"] = aliveNodes;
+ jsonData["ResourceTotal"] = GetResourceValuesText(Self->TotalRawResourceValues);
+ jsonData["ResourceVariance"] = GetResourceValuesText(Self->GetStDevResourceValues());//, [](double d) -> TString { return Sprintf("%.9f", d); });
+ jsonData["BootQueueSize"] = Self->BootQueue.BootQueue.size();
+ jsonData["WaitQueueSize"] = Self->BootQueue.WaitQueue.size();
+ jsonData["BalancerProgress"] = Self->BalancerProgress;
+
+ TVector<TNodeInfo*> nodeInfos;
+ nodeInfos.reserve(Self->Nodes.size());
+ for (auto& pr : Self->Nodes) {
+ if (!pr.second.IsUnknown()) {
+ nodeInfos.push_back(&pr.second);
+ }
+ }
+ std::sort(nodeInfos.begin(), nodeInfos.end(), [](TNodeInfo* a, TNodeInfo* b) -> bool {
+ return std::make_tuple(a->ServicedDomains, a->Id) < std::make_tuple(b->ServicedDomains, b->Id);
+ });
+
+ TInstant aliveLine = TInstant::Now() - TDuration::Minutes(10);
+
+ NJson::TJsonValue& jsonNodes = jsonData["Nodes"];
+ for (TNodeInfo* nodeInfo : nodeInfos) {
+ TNodeInfo& node = *nodeInfo;
+ TNodeId id = node.Id;
+
+ if (!node.IsAlive() && TInstant::MilliSeconds(node.Statistics.GetLastAliveTimestamp()) < aliveLine) {
+ continue;
+ }
+
+ NJson::TJsonValue& jsonNode = jsonNodes.AppendValue(NJson::TJsonValue());
+ TString name = "";
+ TString host;
+ auto it = Self->NodesInfo.find(node.Id);
+ if (it != Self->NodesInfo.end()) {
+ auto &ni = it->second;
+ if (ni.Host.empty()) {
+ name = ni.Address + ":" + ToString(ni.Port);
+ host = ni.Address;
+ } else {
+ name = ni.Host.substr(0, ni.Host.find('.')) + ":" + ToString(ni.Port);
+ host = ni.Host;
+ }
+ }
+
+ jsonNode["Id"] = id;
+ jsonNode["Host"] = host;
+ jsonNode["Name"] = name;
if (node.LocationAcquired) {
jsonNode["DataCenter"] = node.Location.GetDataCenterId();
- }
- jsonNode["Domain"] = node.ServicedDomains.empty() ? "" : Self->GetDomainName(node.GetServicedDomain());
- jsonNode["Alive"] = node.IsAlive();
- jsonNode["Down"] = node.Down;
- jsonNode["Freeze"] = node.Freeze;
- jsonNode["Drain"] = node.IsAlive() ? node.Drain : false;
- jsonNode["Uptime"] = node.IsAlive() ? GetDurationString(node.GetUptime()) : "";
- jsonNode["Unknown"] = node.Tablets[TTabletInfo::EVolatileState::TABLET_VOLATILE_STATE_UNKNOWN].size();
- jsonNode["Starting"] = node.Tablets[TTabletInfo::EVolatileState::TABLET_VOLATILE_STATE_STARTING].size();
- jsonNode["Running"] = node.Tablets[TTabletInfo::EVolatileState::TABLET_VOLATILE_STATE_RUNNING].size();
- {
+ }
+ jsonNode["Domain"] = node.ServicedDomains.empty() ? "" : Self->GetDomainName(node.GetServicedDomain());
+ jsonNode["Alive"] = node.IsAlive();
+ jsonNode["Down"] = node.Down;
+ jsonNode["Freeze"] = node.Freeze;
+ jsonNode["Drain"] = node.IsAlive() ? node.Drain : false;
+ jsonNode["Uptime"] = node.IsAlive() ? GetDurationString(node.GetUptime()) : "";
+ jsonNode["Unknown"] = node.Tablets[TTabletInfo::EVolatileState::TABLET_VOLATILE_STATE_UNKNOWN].size();
+ jsonNode["Starting"] = node.Tablets[TTabletInfo::EVolatileState::TABLET_VOLATILE_STATE_STARTING].size();
+ jsonNode["Running"] = node.Tablets[TTabletInfo::EVolatileState::TABLET_VOLATILE_STATE_RUNNING].size();
+ {
TString types;
- auto nodeTabletTypes = tabletsByNodeByType.find(node.Id);
- if (nodeTabletTypes != tabletsByNodeByType.end()) {
- for (auto it = nodeTabletTypes->second.begin(); it != nodeTabletTypes->second.end(); ++it) {
- if (!types.empty()) {
- types += ' ';
- }
- types += Sprintf("%s:%d", it->first.c_str(), it->second);
- }
- }
- jsonNode["Types"] = types;
- }
- double nodeUsage = node.GetNodeUsage();
- jsonNode["Usage"] = GetConditionalRedString(Sprintf("%.9f", nodeUsage), nodeUsage >= 1);
- jsonNode["ResourceValues"] = GetResourceValuesJson(node.ResourceValues, node.ResourceMaximumValues);
- jsonNode["StDevResourceValues"] = GetResourceValuesText(node.GetStDevResourceValues());
- }
- NJson::WriteJson(&out, &jsonData);
- }
-};
-
-class TTxMonEvent_SetDown : public TTransactionBase<THive> {
-public:
+ auto nodeTabletTypes = tabletsByNodeByType.find(node.Id);
+ if (nodeTabletTypes != tabletsByNodeByType.end()) {
+ for (auto it = nodeTabletTypes->second.begin(); it != nodeTabletTypes->second.end(); ++it) {
+ if (!types.empty()) {
+ types += ' ';
+ }
+ types += Sprintf("%s:%d", it->first.c_str(), it->second);
+ }
+ }
+ jsonNode["Types"] = types;
+ }
+ double nodeUsage = node.GetNodeUsage();
+ jsonNode["Usage"] = GetConditionalRedString(Sprintf("%.9f", nodeUsage), nodeUsage >= 1);
+ jsonNode["ResourceValues"] = GetResourceValuesJson(node.ResourceValues, node.ResourceMaximumValues);
+ jsonNode["StDevResourceValues"] = GetResourceValuesText(node.GetStDevResourceValues());
+ }
+ NJson::WriteJson(&out, &jsonData);
+ }
+};
+
+class TTxMonEvent_SetDown : public TTransactionBase<THive> {
+public:
const TActorId Source;
- const TNodeId NodeId;
- const bool Down;
+ const TNodeId NodeId;
+ const bool Down;
TString Response;
-
+
TTxMonEvent_SetDown(const TActorId& source, TNodeId nodeId, bool down, TSelf* hive)
- : TBase(hive)
- , Source(source)
- , NodeId(nodeId)
- , Down(down)
- {}
-
- TTxType GetTxType() const override { return NHive::TXTYPE_MON_SET_DOWN; }
-
- bool Execute(TTransactionContext& txc, const TActorContext&) override {
- NIceDb::TNiceDb db(txc.DB);
- TNodeInfo* node = Self->FindNode(NodeId);
- if (node != nullptr) {
- node->SetDown(Down);
- db.Table<Schema::Node>().Key(NodeId).Update(NIceDb::TUpdate<Schema::Node::Down>(Down));
- Response = "{\"NodeId\":" + ToString(NodeId) + ',' + "\"Down\":" + (Down ? "true" : "false") + "}";
- } else {
- Response = "{\"Error\":\"Node " + ToString(NodeId) + " not found\"}";
- }
- return true;
- }
-
- void Complete(const TActorContext& ctx) override {
- BLOG_D("THive::TTxMonEvent_SetDown(" << NodeId << ")::Complete Response=" << Response);
- ctx.Send(Source, new NMon::TEvRemoteJsonInfoRes(Response));
- }
-};
-
-class TTxMonEvent_SetFreeze : public TTransactionBase<THive> {
-public:
+ : TBase(hive)
+ , Source(source)
+ , NodeId(nodeId)
+ , Down(down)
+ {}
+
+ TTxType GetTxType() const override { return NHive::TXTYPE_MON_SET_DOWN; }
+
+ bool Execute(TTransactionContext& txc, const TActorContext&) override {
+ NIceDb::TNiceDb db(txc.DB);
+ TNodeInfo* node = Self->FindNode(NodeId);
+ if (node != nullptr) {
+ node->SetDown(Down);
+ db.Table<Schema::Node>().Key(NodeId).Update(NIceDb::TUpdate<Schema::Node::Down>(Down));
+ Response = "{\"NodeId\":" + ToString(NodeId) + ',' + "\"Down\":" + (Down ? "true" : "false") + "}";
+ } else {
+ Response = "{\"Error\":\"Node " + ToString(NodeId) + " not found\"}";
+ }
+ return true;
+ }
+
+ void Complete(const TActorContext& ctx) override {
+ BLOG_D("THive::TTxMonEvent_SetDown(" << NodeId << ")::Complete Response=" << Response);
+ ctx.Send(Source, new NMon::TEvRemoteJsonInfoRes(Response));
+ }
+};
+
+class TTxMonEvent_SetFreeze : public TTransactionBase<THive> {
+public:
const TActorId Source;
- const TNodeId NodeId;
- const bool Freeze;
+ const TNodeId NodeId;
+ const bool Freeze;
TString Response;
-
+
TTxMonEvent_SetFreeze(const TActorId& source, TNodeId nodeId, bool freeze, TSelf* hive)
- : TBase(hive)
- , Source(source)
- , NodeId(nodeId)
- , Freeze(freeze)
- {}
-
- TTxType GetTxType() const override { return NHive::TXTYPE_MON_SET_FREEZE; }
-
- bool Execute(TTransactionContext& txc, const TActorContext&) override {
- NIceDb::TNiceDb db(txc.DB);
- TNodeInfo* node = Self->FindNode(NodeId);
- if (node != nullptr) {
- node->SetFreeze(Freeze);
- db.Table<Schema::Node>().Key(NodeId).Update(NIceDb::TUpdate<Schema::Node::Freeze>(Freeze));
- Response = "{\"NodeId\":" + ToString(NodeId) + ',' + "\"Freeze\":" + (Freeze ? "true" : "false") + "}";
- } else {
- Response = "{\"Error\":\"Node " + ToString(NodeId) + " not found\"}";
- }
- return true;
- }
-
- void Complete(const TActorContext& ctx) override {
- BLOG_D("THive::TTxMonEvent_SetFreeze(" << NodeId << ")::Complete Response=" << Response);
- ctx.Send(Source, new NMon::TEvRemoteJsonInfoRes(Response));
- }
-};
-
-class TTxMonEvent_KickNode : public TTransactionBase<THive> {
-public:
+ : TBase(hive)
+ , Source(source)
+ , NodeId(nodeId)
+ , Freeze(freeze)
+ {}
+
+ TTxType GetTxType() const override { return NHive::TXTYPE_MON_SET_FREEZE; }
+
+ bool Execute(TTransactionContext& txc, const TActorContext&) override {
+ NIceDb::TNiceDb db(txc.DB);
+ TNodeInfo* node = Self->FindNode(NodeId);
+ if (node != nullptr) {
+ node->SetFreeze(Freeze);
+ db.Table<Schema::Node>().Key(NodeId).Update(NIceDb::TUpdate<Schema::Node::Freeze>(Freeze));
+ Response = "{\"NodeId\":" + ToString(NodeId) + ',' + "\"Freeze\":" + (Freeze ? "true" : "false") + "}";
+ } else {
+ Response = "{\"Error\":\"Node " + ToString(NodeId) + " not found\"}";
+ }
+ return true;
+ }
+
+ void Complete(const TActorContext& ctx) override {
+ BLOG_D("THive::TTxMonEvent_SetFreeze(" << NodeId << ")::Complete Response=" << Response);
+ ctx.Send(Source, new NMon::TEvRemoteJsonInfoRes(Response));
+ }
+};
+
+class TTxMonEvent_KickNode : public TTransactionBase<THive> {
+public:
const TActorId Source;
- const TNodeId NodeId;
+ const TNodeId NodeId;
TString Response;
-
+
TTxMonEvent_KickNode(const TActorId& source, TNodeId nodeId, TSelf* hive)
- : TBase(hive)
- , Source(source)
- , NodeId(nodeId)
- {}
-
- TTxType GetTxType() const override { return NHive::TXTYPE_MON_KICK_NODE; }
-
- bool Execute(TTransactionContext&, const TActorContext&) override {
- TNodeInfo* node = Self->FindNode(NodeId);
- if (node != nullptr) {
- int kicked = 0;
- for (TTabletInfo* tablet : node->Tablets[TTabletInfo::EVolatileState::TABLET_VOLATILE_STATE_RUNNING]) {
- tablet->Kick();
- ++kicked;
- }
- Response = "{\"TabletsKicked\":" + ToString(kicked) + "}";
- } else {
- Response = "{\"Error\":\"Node " + ToString(NodeId) + " not found\"}";
- }
- return true;
- }
-
- void Complete(const TActorContext& ctx) override {
- BLOG_D("THive::TTxMonEvent_KickNode(" << NodeId << ")::Complete Response=" << Response);
- ctx.Send(Source, new NMon::TEvRemoteJsonInfoRes(Response));
- }
-};
-
-class TDrainNodeWaitActor : public TActor<TDrainNodeWaitActor>, public ISubActor {
-public:
- TActorId Source;
- THive* Hive;
-
- static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
- return NKikimrServices::TActivity::HIVE_MON_REQUEST;
- }
-
- TDrainNodeWaitActor(const TActorId& source, THive* hive)
- : TActor(&TDrainNodeWaitActor::StateWork)
- , Source(source)
- , Hive(hive)
- {}
-
- void PassAway() override {
- Hive->RemoveSubActor(this);
- return IActor::PassAway();
- }
-
- void Cleanup() override {
- PassAway();
- }
-
- void Handle(TEvHive::TEvDrainNodeResult::TPtr& result) {
- Send(Source, new NMon::TEvRemoteJsonInfoRes(
- TStringBuilder() << "{\"status\":\"" << NKikimrProto::EReplyStatus_Name(result->Get()->Record.GetStatus()) << "\","
- << "\"movements\":" << result->Get()->Record.GetMovements() << "}"));
- PassAway();
- }
-
- STATEFN(StateWork) {
- switch (ev->GetTypeRewrite()) {
- cFunc(TEvents::TSystem::PoisonPill, PassAway);
- hFunc(TEvHive::TEvDrainNodeResult, Handle);
- }
- }
-};
-
-class TTxMonEvent_DrainNode : public TTransactionBase<THive> {
-public:
- TAutoPtr<NMon::TEvRemoteHttpInfo> Event;
- TActorId Source;
- TNodeId NodeId = 0;
- bool Wait = true;
- TActorId WaitActorId;
-
- TTxMonEvent_DrainNode(const TActorId& source, NMon::TEvRemoteHttpInfo::TPtr& ev, TSelf* hive)
- : TBase(hive)
- , Event(ev->Release())
- , Source(source)
- {
- NodeId = FromStringWithDefault<TNodeId>(Event->Cgi().Get("node"), NodeId);
- Wait = FromStringWithDefault(Event->Cgi().Get("wait"), Wait);
- }
-
- TTxType GetTxType() const override { return NHive::TXTYPE_MON_DRAIN_NODE; }
-
- bool Execute(TTransactionContext&, const TActorContext& ctx) override {
- TActorId waitActorId;
- TDrainNodeWaitActor* waitActor = nullptr;
- if (Wait) {
- waitActor = new TDrainNodeWaitActor(Source, Self);
- WaitActorId = ctx.RegisterWithSameMailbox(waitActor);
- Self->SubActors.emplace_back(waitActor);
- }
- return true;
- }
-
- void Complete(const TActorContext& ctx) override {
- if (Wait) {
+ : TBase(hive)
+ , Source(source)
+ , NodeId(nodeId)
+ {}
+
+ TTxType GetTxType() const override { return NHive::TXTYPE_MON_KICK_NODE; }
+
+ bool Execute(TTransactionContext&, const TActorContext&) override {
+ TNodeInfo* node = Self->FindNode(NodeId);
+ if (node != nullptr) {
+ int kicked = 0;
+ for (TTabletInfo* tablet : node->Tablets[TTabletInfo::EVolatileState::TABLET_VOLATILE_STATE_RUNNING]) {
+ tablet->Kick();
+ ++kicked;
+ }
+ Response = "{\"TabletsKicked\":" + ToString(kicked) + "}";
+ } else {
+ Response = "{\"Error\":\"Node " + ToString(NodeId) + " not found\"}";
+ }
+ return true;
+ }
+
+ void Complete(const TActorContext& ctx) override {
+ BLOG_D("THive::TTxMonEvent_KickNode(" << NodeId << ")::Complete Response=" << Response);
+ ctx.Send(Source, new NMon::TEvRemoteJsonInfoRes(Response));
+ }
+};
+
+class TDrainNodeWaitActor : public TActor<TDrainNodeWaitActor>, public ISubActor {
+public:
+ TActorId Source;
+ THive* Hive;
+
+ static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
+ return NKikimrServices::TActivity::HIVE_MON_REQUEST;
+ }
+
+ TDrainNodeWaitActor(const TActorId& source, THive* hive)
+ : TActor(&TDrainNodeWaitActor::StateWork)
+ , Source(source)
+ , Hive(hive)
+ {}
+
+ void PassAway() override {
+ Hive->RemoveSubActor(this);
+ return IActor::PassAway();
+ }
+
+ void Cleanup() override {
+ PassAway();
+ }
+
+ void Handle(TEvHive::TEvDrainNodeResult::TPtr& result) {
+ Send(Source, new NMon::TEvRemoteJsonInfoRes(
+ TStringBuilder() << "{\"status\":\"" << NKikimrProto::EReplyStatus_Name(result->Get()->Record.GetStatus()) << "\","
+ << "\"movements\":" << result->Get()->Record.GetMovements() << "}"));
+ PassAway();
+ }
+
+ STATEFN(StateWork) {
+ switch (ev->GetTypeRewrite()) {
+ cFunc(TEvents::TSystem::PoisonPill, PassAway);
+ hFunc(TEvHive::TEvDrainNodeResult, Handle);
+ }
+ }
+};
+
+class TTxMonEvent_DrainNode : public TTransactionBase<THive> {
+public:
+ TAutoPtr<NMon::TEvRemoteHttpInfo> Event;
+ TActorId Source;
+ TNodeId NodeId = 0;
+ bool Wait = true;
+ TActorId WaitActorId;
+
+ TTxMonEvent_DrainNode(const TActorId& source, NMon::TEvRemoteHttpInfo::TPtr& ev, TSelf* hive)
+ : TBase(hive)
+ , Event(ev->Release())
+ , Source(source)
+ {
+ NodeId = FromStringWithDefault<TNodeId>(Event->Cgi().Get("node"), NodeId);
+ Wait = FromStringWithDefault(Event->Cgi().Get("wait"), Wait);
+ }
+
+ TTxType GetTxType() const override { return NHive::TXTYPE_MON_DRAIN_NODE; }
+
+ bool Execute(TTransactionContext&, const TActorContext& ctx) override {
+ TActorId waitActorId;
+ TDrainNodeWaitActor* waitActor = nullptr;
+ if (Wait) {
+ waitActor = new TDrainNodeWaitActor(Source, Self);
+ WaitActorId = ctx.RegisterWithSameMailbox(waitActor);
+ Self->SubActors.emplace_back(waitActor);
+ }
+ return true;
+ }
+
+ void Complete(const TActorContext& ctx) override {
+ if (Wait) {
Self->Execute(Self->CreateSwitchDrainOn(NodeId, {.Persist = true, .KeepDown = true}, WaitActorId));
- } else {
+ } else {
Self->Execute(Self->CreateSwitchDrainOn(NodeId, {.Persist = true, .KeepDown = true}, {}));
- ctx.Send(Source, new NMon::TEvRemoteJsonInfoRes("{\"status\":\"SCHEDULED\"}"));
- }
- }
-};
-
-class TTxMonEvent_Rebalance : public TTransactionBase<THive> {
-public:
+ ctx.Send(Source, new NMon::TEvRemoteJsonInfoRes("{\"status\":\"SCHEDULED\"}"));
+ }
+ }
+};
+
+class TTxMonEvent_Rebalance : public TTransactionBase<THive> {
+public:
const TActorId Source;
- int MaxMovements = 1000;
-
- TTxMonEvent_Rebalance(const TActorId& source, NMon::TEvRemoteHttpInfo::TPtr& ev, TSelf* hive)
- : TBase(hive)
- , Source(source)
- {
- MaxMovements = FromStringWithDefault(ev->Get()->Cgi().Get("movements"), MaxMovements);
- }
-
- TTxType GetTxType() const override { return NHive::TXTYPE_MON_REBALANCE; }
-
- bool Execute(TTransactionContext&, const TActorContext&) override {
- Self->StartHiveBalancer(MaxMovements);
- return true;
- }
-
- void Complete(const TActorContext& ctx) override {
- ctx.Send(Source, new NMon::TEvRemoteJsonInfoRes("{}"));
- }
-};
-
-class TReassignTabletWaitActor : public TActor<TReassignTabletWaitActor>, public ISubActor {
-public:
+ int MaxMovements = 1000;
+
+ TTxMonEvent_Rebalance(const TActorId& source, NMon::TEvRemoteHttpInfo::TPtr& ev, TSelf* hive)
+ : TBase(hive)
+ , Source(source)
+ {
+ MaxMovements = FromStringWithDefault(ev->Get()->Cgi().Get("movements"), MaxMovements);
+ }
+
+ TTxType GetTxType() const override { return NHive::TXTYPE_MON_REBALANCE; }
+
+ bool Execute(TTransactionContext&, const TActorContext&) override {
+ Self->StartHiveBalancer(MaxMovements);
+ return true;
+ }
+
+ void Complete(const TActorContext& ctx) override {
+ ctx.Send(Source, new NMon::TEvRemoteJsonInfoRes("{}"));
+ }
+};
+
+class TReassignTabletWaitActor : public TActor<TReassignTabletWaitActor>, public ISubActor {
+public:
TActorId Source;
- ui32 TabletsTotal = std::numeric_limits<ui32>::max();
- ui32 TabletsDone = 0;
- THive* Hive;
-
- static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
- return NKikimrServices::TActivity::HIVE_MON_REQUEST;
- }
-
+ ui32 TabletsTotal = std::numeric_limits<ui32>::max();
+ ui32 TabletsDone = 0;
+ THive* Hive;
+
+ static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
+ return NKikimrServices::TActivity::HIVE_MON_REQUEST;
+ }
+
TReassignTabletWaitActor(const TActorId& source, THive* hive)
- : TActor(&TReassignTabletWaitActor::StateWork)
- , Source(source)
- , Hive(hive)
- {}
-
- void PassAway() override {
- Hive->RemoveSubActor(this);
- return IActor::PassAway();
- }
-
- void Cleanup() override {
- PassAway();
- }
-
- void Handle(TEvPrivate::TEvRestartComplete::TPtr&) {
- ++TabletsDone;
- if (TabletsDone >= TabletsTotal) {
- Send(Source, new NMon::TEvRemoteJsonInfoRes(TStringBuilder() << "{\"total\":" << TabletsDone << "}"));
- PassAway();
- }
- }
-
- STATEFN(StateWork) {
- switch (ev->GetTypeRewrite()) {
- cFunc(TEvents::TSystem::PoisonPill, PassAway);
- hFunc(TEvPrivate::TEvRestartComplete, Handle);
- }
- }
-};
-
-class TTxMonEvent_ReassignTablet : public TTransactionBase<THive> {
-public:
- TAutoPtr<NMon::TEvRemoteHttpInfo> Event;
+ : TActor(&TReassignTabletWaitActor::StateWork)
+ , Source(source)
+ , Hive(hive)
+ {}
+
+ void PassAway() override {
+ Hive->RemoveSubActor(this);
+ return IActor::PassAway();
+ }
+
+ void Cleanup() override {
+ PassAway();
+ }
+
+ void Handle(TEvPrivate::TEvRestartComplete::TPtr&) {
+ ++TabletsDone;
+ if (TabletsDone >= TabletsTotal) {
+ Send(Source, new NMon::TEvRemoteJsonInfoRes(TStringBuilder() << "{\"total\":" << TabletsDone << "}"));
+ PassAway();
+ }
+ }
+
+ STATEFN(StateWork) {
+ switch (ev->GetTypeRewrite()) {
+ cFunc(TEvents::TSystem::PoisonPill, PassAway);
+ hFunc(TEvPrivate::TEvRestartComplete, Handle);
+ }
+ }
+};
+
+class TTxMonEvent_ReassignTablet : public TTransactionBase<THive> {
+public:
+ TAutoPtr<NMon::TEvRemoteHttpInfo> Event;
const TActorId Source;
- TTabletId TabletId = 0;
- TTabletTypes::EType TabletType = TTabletTypes::TYPE_INVALID;
+ TTabletId TabletId = 0;
+ TTabletTypes::EType TabletType = TTabletTypes::TYPE_INVALID;
TVector<ui32> TabletChannels;
- ui32 GroupId = 0;
- TVector<ui32> ForcedGroupIds;
- int TabletPercent = 100;
- TString Error;
- bool Wait = true;
-
+ ui32 GroupId = 0;
+ TVector<ui32> ForcedGroupIds;
+ int TabletPercent = 100;
+ TString Error;
+ bool Wait = true;
+
TTxMonEvent_ReassignTablet(const TActorId& source, NMon::TEvRemoteHttpInfo::TPtr& ev, TSelf* hive)
- : TBase(hive)
- , Event(ev->Release())
- , Source(source)
- {
- TabletId = FromStringWithDefault<TTabletId>(Event->Cgi().Get("tablet"), TabletId);
- TabletType = (TTabletTypes::EType)FromStringWithDefault<int>(Event->Cgi().Get("type"), TabletType);
+ : TBase(hive)
+ , Event(ev->Release())
+ , Source(source)
+ {
+ TabletId = FromStringWithDefault<TTabletId>(Event->Cgi().Get("tablet"), TabletId);
+ TabletType = (TTabletTypes::EType)FromStringWithDefault<int>(Event->Cgi().Get("type"), TabletType);
TabletChannels = Scan<ui32>(SplitString(Event->Cgi().Get("channel"), ","));
- TabletPercent = FromStringWithDefault<int>(Event->Cgi().Get("percent"), TabletPercent);
- GroupId = FromStringWithDefault(Event->Cgi().Get("group"), GroupId);
- ForcedGroupIds = Scan<ui32>(SplitString(Event->Cgi().Get("forcedGroup"), ","));
- TabletPercent = std::min(std::abs(TabletPercent), 100);
- Wait = FromStringWithDefault(Event->Cgi().Get("wait"), Wait);
- }
-
- TTxType GetTxType() const override { return NHive::TXTYPE_MON_REASSIGN_TABLET; }
-
+ TabletPercent = FromStringWithDefault<int>(Event->Cgi().Get("percent"), TabletPercent);
+ GroupId = FromStringWithDefault(Event->Cgi().Get("group"), GroupId);
+ ForcedGroupIds = Scan<ui32>(SplitString(Event->Cgi().Get("forcedGroup"), ","));
+ TabletPercent = std::min(std::abs(TabletPercent), 100);
+ Wait = FromStringWithDefault(Event->Cgi().Get("wait"), Wait);
+ }
+
+ TTxType GetTxType() const override { return NHive::TXTYPE_MON_REASSIGN_TABLET; }
+
TInstant GetMaxTimestamp(const TLeaderTabletInfo* tablet) const {
- TInstant max;
- for (const auto& channel : tablet->TabletStorageInfo->Channels) {
- if (TabletChannels.empty()
- || std::find(
- TabletChannels.begin(),
- TabletChannels.end(),
- channel.Channel) != TabletChannels.end()) {
- const auto* latest = channel.LatestEntry();
- if (latest != nullptr && latest->Timestamp > max) {
- max = latest->Timestamp;
- }
- }
- }
- return max;
- }
-
- bool Execute(TTransactionContext&, const TActorContext& ctx) override {
- if (!ForcedGroupIds.empty() && ForcedGroupIds.size() != TabletChannels.size()) {
- Error = "forcedGroup size should be equal to channel size";
- return true;
- }
+ TInstant max;
+ for (const auto& channel : tablet->TabletStorageInfo->Channels) {
+ if (TabletChannels.empty()
+ || std::find(
+ TabletChannels.begin(),
+ TabletChannels.end(),
+ channel.Channel) != TabletChannels.end()) {
+ const auto* latest = channel.LatestEntry();
+ if (latest != nullptr && latest->Timestamp > max) {
+ max = latest->Timestamp;
+ }
+ }
+ }
+ return max;
+ }
+
+ bool Execute(TTransactionContext&, const TActorContext& ctx) override {
+ if (!ForcedGroupIds.empty() && ForcedGroupIds.size() != TabletChannels.size()) {
+ Error = "forcedGroup size should be equal to channel size";
+ return true;
+ }
TVector<TLeaderTabletInfo*> tablets;
- if (TabletId != 0) {
+ if (TabletId != 0) {
TLeaderTabletInfo* tablet = Self->FindTablet(TabletId);
- if (tablet != nullptr) {
- tablets.push_back(tablet);
- }
- } else
- if (TabletType != TTabletTypes::TYPE_INVALID) {
- for (auto& pr : Self->Tablets) {
- if (pr.second.Type == TabletType) {
- tablets.push_back(&pr.second);
- }
- }
- } else {
- for (auto& pr : Self->Tablets) {
- tablets.push_back(&pr.second);
- }
- }
- if (TabletPercent != 100) {
+ if (tablet != nullptr) {
+ tablets.push_back(tablet);
+ }
+ } else
+ if (TabletType != TTabletTypes::TYPE_INVALID) {
+ for (auto& pr : Self->Tablets) {
+ if (pr.second.Type == TabletType) {
+ tablets.push_back(&pr.second);
+ }
+ }
+ } else {
+ for (auto& pr : Self->Tablets) {
+ tablets.push_back(&pr.second);
+ }
+ }
+ if (TabletPercent != 100) {
std::sort(tablets.begin(), tablets.end(), [this](TLeaderTabletInfo* a, TLeaderTabletInfo* b) -> bool {
- return GetMaxTimestamp(a) < GetMaxTimestamp(b);
- });
- tablets.resize(tablets.size() * TabletPercent / 100);
- }
- TVector<THolder<TEvHive::TEvReassignTablet>> operations;
+ return GetMaxTimestamp(a) < GetMaxTimestamp(b);
+ });
+ tablets.resize(tablets.size() * TabletPercent / 100);
+ }
+ TVector<THolder<TEvHive::TEvReassignTablet>> operations;
TActorId waitActorId;
- TReassignTabletWaitActor* waitActor = nullptr;
- if (Wait) {
- waitActor = new TReassignTabletWaitActor(Source, Self);
+ TReassignTabletWaitActor* waitActor = nullptr;
+ if (Wait) {
+ waitActor = new TReassignTabletWaitActor(Source, Self);
waitActorId = ctx.RegisterWithSameMailbox(waitActor);
- Self->SubActors.emplace_back(waitActor);
- }
+ Self->SubActors.emplace_back(waitActor);
+ }
for (TLeaderTabletInfo* tablet : tablets) {
TVector<ui32> channels;
- TVector<ui32> forcedGroupIds;
- bool skip = false;
- if (GroupId != 0) {
- skip = true;
- for (const auto& channel : tablet->TabletStorageInfo->Channels) {
- if (TabletChannels.empty() || Find(TabletChannels, channel.Channel) != TabletChannels.end()) {
- const auto* latest = channel.LatestEntry();
- if (latest != nullptr && latest->GroupID == GroupId) {
- skip = false;
- channels.push_back(channel.Channel);
- if (!ForcedGroupIds.empty()) {
- auto itTabletChannel = Find(TabletChannels, channel.Channel);
- forcedGroupIds.push_back(ForcedGroupIds[std::distance(TabletChannels.begin(), itTabletChannel)]);
- }
- }
- }
- }
- } else {
- channels = TabletChannels;
- forcedGroupIds = ForcedGroupIds;
- }
- if (skip) {
- continue;
- }
- if (Wait) {
- tablet->ActorsToNotifyOnRestart.emplace_back(waitActorId); // volatile settings, will not persist upon restart
- }
- operations.emplace_back(new TEvHive::TEvReassignTablet(tablet->Id, channels, forcedGroupIds));
- }
- if (Wait) {
- waitActor->TabletsTotal = operations.size();
- }
- for (auto& op : operations) {
+ TVector<ui32> forcedGroupIds;
+ bool skip = false;
+ if (GroupId != 0) {
+ skip = true;
+ for (const auto& channel : tablet->TabletStorageInfo->Channels) {
+ if (TabletChannels.empty() || Find(TabletChannels, channel.Channel) != TabletChannels.end()) {
+ const auto* latest = channel.LatestEntry();
+ if (latest != nullptr && latest->GroupID == GroupId) {
+ skip = false;
+ channels.push_back(channel.Channel);
+ if (!ForcedGroupIds.empty()) {
+ auto itTabletChannel = Find(TabletChannels, channel.Channel);
+ forcedGroupIds.push_back(ForcedGroupIds[std::distance(TabletChannels.begin(), itTabletChannel)]);
+ }
+ }
+ }
+ }
+ } else {
+ channels = TabletChannels;
+ forcedGroupIds = ForcedGroupIds;
+ }
+ if (skip) {
+ continue;
+ }
+ if (Wait) {
+ tablet->ActorsToNotifyOnRestart.emplace_back(waitActorId); // volatile settings, will not persist upon restart
+ }
+ operations.emplace_back(new TEvHive::TEvReassignTablet(tablet->Id, channels, forcedGroupIds));
+ }
+ if (Wait) {
+ waitActor->TabletsTotal = operations.size();
+ }
+ for (auto& op : operations) {
ctx.Send(Self->SelfId(), op.Release());
- }
- return true;
- }
-
- void Complete(const TActorContext& ctx) override {
- if (Error) {
- ctx.Send(Source, new NMon::TEvRemoteJsonInfoRes(TStringBuilder() << "{\"error\":\"" << Error << "\"}"));
- } else {
- if (!Wait) {
- ctx.Send(Source, new NMon::TEvRemoteJsonInfoRes("{}"));
- }
- }
- }
-};
-
-class TInitMigrationWaitActor : public TActor<TInitMigrationWaitActor>, public ISubActor {
-public:
- TActorId Source;
- THive* Hive;
-
- static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
- return NKikimrServices::TActivity::HIVE_MON_REQUEST;
- }
-
- TInitMigrationWaitActor(const TActorId& source, THive* hive)
- : TActor(&TInitMigrationWaitActor::StateWork)
- , Source(source)
- , Hive(hive)
- {}
-
- void PassAway() override {
- Hive->RemoveSubActor(this);
- return IActor::PassAway();
- }
-
- void Cleanup() override {
- PassAway();
- }
-
- void Handle(TEvHive::TEvInitMigrationReply::TPtr& reply) {
- TStringBuilder output;
- NProtobufJson::TProto2JsonConfig config;
- config.SetEnumMode(NProtobufJson::TProto2JsonConfig::EnumName);
- NProtobufJson::Proto2Json(reply->Get()->Record, output, config);
- Send(Source, new NMon::TEvRemoteJsonInfoRes(output));
- PassAway();
- }
-
- STATEFN(StateWork) {
- switch (ev->GetTypeRewrite()) {
- cFunc(TEvents::TSystem::PoisonPill, PassAway);
- hFunc(TEvHive::TEvInitMigrationReply, Handle);
- }
- }
-};
-
-class TTxMonEvent_InitMigration : public TTransactionBase<THive> {
-public:
- TAutoPtr<NMon::TEvRemoteHttpInfo> Event;
- const TActorId Source;
- bool Wait = true;
-
- TTxMonEvent_InitMigration(const TActorId& source, NMon::TEvRemoteHttpInfo::TPtr& ev, TSelf* hive)
- : TBase(hive)
- , Event(ev->Release())
- , Source(source)
- {
- Wait = FromStringWithDefault(Event->Cgi().Get("wait"), Wait);
- }
-
- TTxType GetTxType() const override { return NHive::TXTYPE_MON_INIT_MIGRATION; }
-
- bool Execute(TTransactionContext&, const TActorContext& ctx) override {
- TActorId waitActorId;
- TInitMigrationWaitActor* waitActor = nullptr;
- if (Wait) {
- waitActor = new TInitMigrationWaitActor(Source, Self);
+ }
+ return true;
+ }
+
+ void Complete(const TActorContext& ctx) override {
+ if (Error) {
+ ctx.Send(Source, new NMon::TEvRemoteJsonInfoRes(TStringBuilder() << "{\"error\":\"" << Error << "\"}"));
+ } else {
+ if (!Wait) {
+ ctx.Send(Source, new NMon::TEvRemoteJsonInfoRes("{}"));
+ }
+ }
+ }
+};
+
+class TInitMigrationWaitActor : public TActor<TInitMigrationWaitActor>, public ISubActor {
+public:
+ TActorId Source;
+ THive* Hive;
+
+ static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
+ return NKikimrServices::TActivity::HIVE_MON_REQUEST;
+ }
+
+ TInitMigrationWaitActor(const TActorId& source, THive* hive)
+ : TActor(&TInitMigrationWaitActor::StateWork)
+ , Source(source)
+ , Hive(hive)
+ {}
+
+ void PassAway() override {
+ Hive->RemoveSubActor(this);
+ return IActor::PassAway();
+ }
+
+ void Cleanup() override {
+ PassAway();
+ }
+
+ void Handle(TEvHive::TEvInitMigrationReply::TPtr& reply) {
+ TStringBuilder output;
+ NProtobufJson::TProto2JsonConfig config;
+ config.SetEnumMode(NProtobufJson::TProto2JsonConfig::EnumName);
+ NProtobufJson::Proto2Json(reply->Get()->Record, output, config);
+ Send(Source, new NMon::TEvRemoteJsonInfoRes(output));
+ PassAway();
+ }
+
+ STATEFN(StateWork) {
+ switch (ev->GetTypeRewrite()) {
+ cFunc(TEvents::TSystem::PoisonPill, PassAway);
+ hFunc(TEvHive::TEvInitMigrationReply, Handle);
+ }
+ }
+};
+
+class TTxMonEvent_InitMigration : public TTransactionBase<THive> {
+public:
+ TAutoPtr<NMon::TEvRemoteHttpInfo> Event;
+ const TActorId Source;
+ bool Wait = true;
+
+ TTxMonEvent_InitMigration(const TActorId& source, NMon::TEvRemoteHttpInfo::TPtr& ev, TSelf* hive)
+ : TBase(hive)
+ , Event(ev->Release())
+ , Source(source)
+ {
+ Wait = FromStringWithDefault(Event->Cgi().Get("wait"), Wait);
+ }
+
+ TTxType GetTxType() const override { return NHive::TXTYPE_MON_INIT_MIGRATION; }
+
+ bool Execute(TTransactionContext&, const TActorContext& ctx) override {
+ TActorId waitActorId;
+ TInitMigrationWaitActor* waitActor = nullptr;
+ if (Wait) {
+ waitActor = new TInitMigrationWaitActor(Source, Self);
waitActorId = ctx.RegisterWithSameMailbox(waitActor);
- Self->SubActors.emplace_back(waitActor);
- }
- // TODO: pass arguments as post data json
+ Self->SubActors.emplace_back(waitActor);
+ }
+ // TODO: pass arguments as post data json
ctx.Send(new IEventHandle(Self->SelfId(), waitActorId, new TEvHive::TEvInitMigration()));
- return true;
- }
-
- void Complete(const TActorContext& ctx) override {
- if (!Wait) {
- ctx.Send(Source, new NMon::TEvRemoteJsonInfoRes("{}"));
- }
- }
-};
-
-class TQueryMigrationWaitActor : public TActor<TQueryMigrationWaitActor>, public ISubActor {
-public:
- TActorId Source;
- THive* Hive;
-
- static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
- return NKikimrServices::TActivity::HIVE_MON_REQUEST;
- }
-
- TQueryMigrationWaitActor(const TActorId& source, THive* hive)
- : TActor(&TQueryMigrationWaitActor::StateWork)
- , Source(source)
- , Hive(hive)
- {}
-
- void PassAway() override {
- Hive->RemoveSubActor(this);
- return IActor::PassAway();
- }
-
- void Cleanup() override {
- PassAway();
- }
-
- void Handle(TEvHive::TEvQueryMigrationReply::TPtr& reply) {
- TStringBuilder output;
- NProtobufJson::TProto2JsonConfig config;
- config.SetEnumMode(NProtobufJson::TProto2JsonConfig::EnumName);
- NProtobufJson::Proto2Json(reply->Get()->Record, output, config);
- Send(Source, new NMon::TEvRemoteJsonInfoRes(output));
- PassAway();
- }
-
- STATEFN(StateWork) {
- switch (ev->GetTypeRewrite()) {
- cFunc(TEvents::TSystem::PoisonPill, PassAway);
- hFunc(TEvHive::TEvQueryMigrationReply, Handle);
- }
- }
-};
-
-class TTxMonEvent_QueryMigration : public TTransactionBase<THive> {
-public:
- TAutoPtr<NMon::TEvRemoteHttpInfo> Event;
- const TActorId Source;
-
- TTxMonEvent_QueryMigration(const TActorId& source, NMon::TEvRemoteHttpInfo::TPtr& ev, TSelf* hive)
- : TBase(hive)
- , Event(ev->Release())
- , Source(source)
- {
- }
-
- TTxType GetTxType() const override { return NHive::TXTYPE_MON_QUERY_MIGRATION; }
-
- bool Execute(TTransactionContext&, const TActorContext& ctx) override {
- TActorId waitActorId;
- TQueryMigrationWaitActor* waitActor = nullptr;
- waitActor = new TQueryMigrationWaitActor(Source, Self);
+ return true;
+ }
+
+ void Complete(const TActorContext& ctx) override {
+ if (!Wait) {
+ ctx.Send(Source, new NMon::TEvRemoteJsonInfoRes("{}"));
+ }
+ }
+};
+
+class TQueryMigrationWaitActor : public TActor<TQueryMigrationWaitActor>, public ISubActor {
+public:
+ TActorId Source;
+ THive* Hive;
+
+ static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
+ return NKikimrServices::TActivity::HIVE_MON_REQUEST;
+ }
+
+ TQueryMigrationWaitActor(const TActorId& source, THive* hive)
+ : TActor(&TQueryMigrationWaitActor::StateWork)
+ , Source(source)
+ , Hive(hive)
+ {}
+
+ void PassAway() override {
+ Hive->RemoveSubActor(this);
+ return IActor::PassAway();
+ }
+
+ void Cleanup() override {
+ PassAway();
+ }
+
+ void Handle(TEvHive::TEvQueryMigrationReply::TPtr& reply) {
+ TStringBuilder output;
+ NProtobufJson::TProto2JsonConfig config;
+ config.SetEnumMode(NProtobufJson::TProto2JsonConfig::EnumName);
+ NProtobufJson::Proto2Json(reply->Get()->Record, output, config);
+ Send(Source, new NMon::TEvRemoteJsonInfoRes(output));
+ PassAway();
+ }
+
+ STATEFN(StateWork) {
+ switch (ev->GetTypeRewrite()) {
+ cFunc(TEvents::TSystem::PoisonPill, PassAway);
+ hFunc(TEvHive::TEvQueryMigrationReply, Handle);
+ }
+ }
+};
+
+class TTxMonEvent_QueryMigration : public TTransactionBase<THive> {
+public:
+ TAutoPtr<NMon::TEvRemoteHttpInfo> Event;
+ const TActorId Source;
+
+ TTxMonEvent_QueryMigration(const TActorId& source, NMon::TEvRemoteHttpInfo::TPtr& ev, TSelf* hive)
+ : TBase(hive)
+ , Event(ev->Release())
+ , Source(source)
+ {
+ }
+
+ TTxType GetTxType() const override { return NHive::TXTYPE_MON_QUERY_MIGRATION; }
+
+ bool Execute(TTransactionContext&, const TActorContext& ctx) override {
+ TActorId waitActorId;
+ TQueryMigrationWaitActor* waitActor = nullptr;
+ waitActor = new TQueryMigrationWaitActor(Source, Self);
waitActorId = ctx.RegisterWithSameMailbox(waitActor);
- Self->SubActors.emplace_back(waitActor);
+ Self->SubActors.emplace_back(waitActor);
ctx.Send(new IEventHandle(Self->SelfId(), waitActorId, new TEvHive::TEvQueryMigration()));
- return true;
- }
-
- void Complete(const TActorContext&) override {
- }
-};
-
-class TStopTabletWaitActor : public TActor<TStopTabletWaitActor>, public ISubActor {
-public:
- TActorId Source;
- THive* Hive;
-
- static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
- return NKikimrServices::TActivity::HIVE_MON_REQUEST;
- }
-
- TStopTabletWaitActor(const TActorId& source, THive* hive)
- : TActor(&TStopTabletWaitActor::StateWork)
- , Source(source)
- , Hive(hive)
- {}
-
- void PassAway() override {
- Hive->RemoveSubActor(this);
- return IActor::PassAway();
- }
-
- void Cleanup() override {
- PassAway();
- }
-
- void Handle(TEvHive::TEvStopTabletResult::TPtr& result) {
- Send(Source, new NMon::TEvRemoteJsonInfoRes(TStringBuilder() << result->Get()->Record.AsJSON()));
- PassAway();
- }
-
- STATEFN(StateWork) {
- switch (ev->GetTypeRewrite()) {
- cFunc(TEvents::TSystem::PoisonPill, PassAway);
- hFunc(TEvHive::TEvStopTabletResult, Handle);
- }
- }
-};
-
-
-class TTxMonEvent_StopTablet : public TTransactionBase<THive> {
-public:
- TAutoPtr<NMon::TEvRemoteHttpInfo> Event;
- const TActorId Source;
- TTabletId TabletId = 0;
- bool Wait = true;
-
- TTxMonEvent_StopTablet(const TActorId& source, NMon::TEvRemoteHttpInfo::TPtr& ev, TSelf* hive)
- : TBase(hive)
- , Event(ev->Release())
- , Source(source)
- {
- TabletId = FromStringWithDefault<TTabletId>(Event->Cgi().Get("tablet"), TabletId);
- Wait = FromStringWithDefault(Event->Cgi().Get("wait"), Wait);
- }
-
- TTxType GetTxType() const override { return NHive::TXTYPE_MON_STOP_TABLET; }
-
- bool Execute(TTransactionContext&, const TActorContext& ctx) override {
+ return true;
+ }
+
+ void Complete(const TActorContext&) override {
+ }
+};
+
+class TStopTabletWaitActor : public TActor<TStopTabletWaitActor>, public ISubActor {
+public:
+ TActorId Source;
+ THive* Hive;
+
+ static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
+ return NKikimrServices::TActivity::HIVE_MON_REQUEST;
+ }
+
+ TStopTabletWaitActor(const TActorId& source, THive* hive)
+ : TActor(&TStopTabletWaitActor::StateWork)
+ , Source(source)
+ , Hive(hive)
+ {}
+
+ void PassAway() override {
+ Hive->RemoveSubActor(this);
+ return IActor::PassAway();
+ }
+
+ void Cleanup() override {
+ PassAway();
+ }
+
+ void Handle(TEvHive::TEvStopTabletResult::TPtr& result) {
+ Send(Source, new NMon::TEvRemoteJsonInfoRes(TStringBuilder() << result->Get()->Record.AsJSON()));
+ PassAway();
+ }
+
+ STATEFN(StateWork) {
+ switch (ev->GetTypeRewrite()) {
+ cFunc(TEvents::TSystem::PoisonPill, PassAway);
+ hFunc(TEvHive::TEvStopTabletResult, Handle);
+ }
+ }
+};
+
+
+class TTxMonEvent_StopTablet : public TTransactionBase<THive> {
+public:
+ TAutoPtr<NMon::TEvRemoteHttpInfo> Event;
+ const TActorId Source;
+ TTabletId TabletId = 0;
+ bool Wait = true;
+
+ TTxMonEvent_StopTablet(const TActorId& source, NMon::TEvRemoteHttpInfo::TPtr& ev, TSelf* hive)
+ : TBase(hive)
+ , Event(ev->Release())
+ , Source(source)
+ {
+ TabletId = FromStringWithDefault<TTabletId>(Event->Cgi().Get("tablet"), TabletId);
+ Wait = FromStringWithDefault(Event->Cgi().Get("wait"), Wait);
+ }
+
+ TTxType GetTxType() const override { return NHive::TXTYPE_MON_STOP_TABLET; }
+
+ bool Execute(TTransactionContext&, const TActorContext& ctx) override {
TLeaderTabletInfo* tablet = Self->FindTablet(TabletId);
- if (tablet != nullptr) {
- TActorId waitActorId;
- TStopTabletWaitActor* waitActor = nullptr;
- if (Wait) {
- waitActor = new TStopTabletWaitActor(Source, Self);
+ if (tablet != nullptr) {
+ TActorId waitActorId;
+ TStopTabletWaitActor* waitActor = nullptr;
+ if (Wait) {
+ waitActor = new TStopTabletWaitActor(Source, Self);
waitActorId = ctx.RegisterWithSameMailbox(waitActor);
- Self->SubActors.emplace_back(waitActor);
- }
- Self->Execute(Self->CreateStopTablet(TabletId, waitActorId));
- if (!Wait) {
- ctx.Send(Source, new NMon::TEvRemoteJsonInfoRes("{}"));
- }
- } else {
- ctx.Send(Source, new NMon::TEvRemoteJsonInfoRes(TStringBuilder() << "{\"error\":\"Tablet not found\"}"));
- }
- return true;
- }
-
- void Complete(const TActorContext&) override {}
-};
-
-class TResumeTabletWaitActor : public TActor<TResumeTabletWaitActor>, public ISubActor {
-public:
- TActorId Source;
- THive* Hive;
-
- static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
- return NKikimrServices::TActivity::HIVE_MON_REQUEST;
- }
-
- TResumeTabletWaitActor(const TActorId& source, THive* hive)
- : TActor(&TResumeTabletWaitActor::StateWork)
- , Source(source)
- , Hive(hive)
- {}
-
- void PassAway() override {
- Hive->RemoveSubActor(this);
- return IActor::PassAway();
- }
-
- void Cleanup() override {
- PassAway();
- }
-
- void Handle(TEvHive::TEvResumeTabletResult::TPtr& result) {
- Send(Source, new NMon::TEvRemoteJsonInfoRes(TStringBuilder() << result->Get()->Record.AsJSON()));
- PassAway();
- }
-
- STATEFN(StateWork) {
- switch (ev->GetTypeRewrite()) {
- cFunc(TEvents::TSystem::PoisonPill, PassAway);
- hFunc(TEvHive::TEvResumeTabletResult, Handle);
- }
- }
-};
-
-
-class TTxMonEvent_ResumeTablet : public TTransactionBase<THive> {
-public:
- TAutoPtr<NMon::TEvRemoteHttpInfo> Event;
- const TActorId Source;
- TTabletId TabletId = 0;
- bool Wait = true;
-
- TTxMonEvent_ResumeTablet(const TActorId& source, NMon::TEvRemoteHttpInfo::TPtr& ev, TSelf* hive)
- : TBase(hive)
- , Event(ev->Release())
- , Source(source)
- {
- TabletId = FromStringWithDefault<TTabletId>(Event->Cgi().Get("tablet"), TabletId);
- Wait = FromStringWithDefault(Event->Cgi().Get("wait"), Wait);
- }
-
- TTxType GetTxType() const override { return NHive::TXTYPE_MON_STOP_TABLET; }
-
- bool Execute(TTransactionContext&, const TActorContext& ctx) override {
+ Self->SubActors.emplace_back(waitActor);
+ }
+ Self->Execute(Self->CreateStopTablet(TabletId, waitActorId));
+ if (!Wait) {
+ ctx.Send(Source, new NMon::TEvRemoteJsonInfoRes("{}"));
+ }
+ } else {
+ ctx.Send(Source, new NMon::TEvRemoteJsonInfoRes(TStringBuilder() << "{\"error\":\"Tablet not found\"}"));
+ }
+ return true;
+ }
+
+ void Complete(const TActorContext&) override {}
+};
+
+class TResumeTabletWaitActor : public TActor<TResumeTabletWaitActor>, public ISubActor {
+public:
+ TActorId Source;
+ THive* Hive;
+
+ static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
+ return NKikimrServices::TActivity::HIVE_MON_REQUEST;
+ }
+
+ TResumeTabletWaitActor(const TActorId& source, THive* hive)
+ : TActor(&TResumeTabletWaitActor::StateWork)
+ , Source(source)
+ , Hive(hive)
+ {}
+
+ void PassAway() override {
+ Hive->RemoveSubActor(this);
+ return IActor::PassAway();
+ }
+
+ void Cleanup() override {
+ PassAway();
+ }
+
+ void Handle(TEvHive::TEvResumeTabletResult::TPtr& result) {
+ Send(Source, new NMon::TEvRemoteJsonInfoRes(TStringBuilder() << result->Get()->Record.AsJSON()));
+ PassAway();
+ }
+
+ STATEFN(StateWork) {
+ switch (ev->GetTypeRewrite()) {
+ cFunc(TEvents::TSystem::PoisonPill, PassAway);
+ hFunc(TEvHive::TEvResumeTabletResult, Handle);
+ }
+ }
+};
+
+
+class TTxMonEvent_ResumeTablet : public TTransactionBase<THive> {
+public:
+ TAutoPtr<NMon::TEvRemoteHttpInfo> Event;
+ const TActorId Source;
+ TTabletId TabletId = 0;
+ bool Wait = true;
+
+ TTxMonEvent_ResumeTablet(const TActorId& source, NMon::TEvRemoteHttpInfo::TPtr& ev, TSelf* hive)
+ : TBase(hive)
+ , Event(ev->Release())
+ , Source(source)
+ {
+ TabletId = FromStringWithDefault<TTabletId>(Event->Cgi().Get("tablet"), TabletId);
+ Wait = FromStringWithDefault(Event->Cgi().Get("wait"), Wait);
+ }
+
+ TTxType GetTxType() const override { return NHive::TXTYPE_MON_STOP_TABLET; }
+
+ bool Execute(TTransactionContext&, const TActorContext& ctx) override {
TLeaderTabletInfo* tablet = Self->FindTablet(TabletId);
- if (tablet != nullptr) {
- TActorId waitActorId;
- TResumeTabletWaitActor* waitActor = nullptr;
- if (Wait) {
- waitActor = new TResumeTabletWaitActor(Source, Self);
+ if (tablet != nullptr) {
+ TActorId waitActorId;
+ TResumeTabletWaitActor* waitActor = nullptr;
+ if (Wait) {
+ waitActor = new TResumeTabletWaitActor(Source, Self);
waitActorId = ctx.RegisterWithSameMailbox(waitActor);
- Self->SubActors.emplace_back(waitActor);
- }
- Self->Execute(Self->CreateResumeTablet(TabletId, waitActorId));
- if (!Wait) {
- ctx.Send(Source, new NMon::TEvRemoteJsonInfoRes("{}"));
- }
- } else {
- ctx.Send(Source, new NMon::TEvRemoteJsonInfoRes(TStringBuilder() << "{\"error\":\"Tablet not found\"}"));
- }
- return true;
- }
-
- void Complete(const TActorContext&) override {}
-};
-
-class TTxMonEvent_FindTablet : public TTransactionBase<THive> {
-public:
- THolder<NMon::TEvRemoteHttpInfo> Event;
+ Self->SubActors.emplace_back(waitActor);
+ }
+ Self->Execute(Self->CreateResumeTablet(TabletId, waitActorId));
+ if (!Wait) {
+ ctx.Send(Source, new NMon::TEvRemoteJsonInfoRes("{}"));
+ }
+ } else {
+ ctx.Send(Source, new NMon::TEvRemoteJsonInfoRes(TStringBuilder() << "{\"error\":\"Tablet not found\"}"));
+ }
+ return true;
+ }
+
+ void Complete(const TActorContext&) override {}
+};
+
+class TTxMonEvent_FindTablet : public TTransactionBase<THive> {
+public:
+ THolder<NMon::TEvRemoteHttpInfo> Event;
const TActorId Source;
- TTabletId TabletId = 0;
- TTabletTypes::EType TabletType = TTabletTypes::TYPE_INVALID;
- ui32 ChannelFrom = 0;
- ui32 ChannelTo = 255;
- ui32 GroupId = 0;
- TString StoragePool;
- TVector<ui32> ForcedGroupIds;
- int TabletPercent = 100;
- NJson::TJsonValue Result;
-
+ TTabletId TabletId = 0;
+ TTabletTypes::EType TabletType = TTabletTypes::TYPE_INVALID;
+ ui32 ChannelFrom = 0;
+ ui32 ChannelTo = 255;
+ ui32 GroupId = 0;
+ TString StoragePool;
+ TVector<ui32> ForcedGroupIds;
+ int TabletPercent = 100;
+ NJson::TJsonValue Result;
+
TTxMonEvent_FindTablet(const TActorId& source, NMon::TEvRemoteHttpInfo::TPtr& ev, TSelf* hive)
- : TBase(hive)
- , Event(ev->Release())
- , Source(source)
- {
- TabletId = FromStringWithDefault<TTabletId>(Event->Cgi().Get("tablet"), TabletId);
- TabletType = (TTabletTypes::EType)FromStringWithDefault<int>(Event->Cgi().Get("type"), TabletType);
- ChannelFrom = FromStringWithDefault<ui32>(Event->Cgi().Get("channelFrom"), ChannelFrom);
- ChannelTo = FromStringWithDefault<ui32>(Event->Cgi().Get("channelTo"), ChannelTo);
- GroupId = FromStringWithDefault(Event->Cgi().Get("group"), GroupId);
- StoragePool = Event->Cgi().Get("storagePool");
- TabletPercent = FromStringWithDefault<int>(Event->Cgi().Get("percent"), TabletPercent);
- TabletPercent = std::min(std::abs(TabletPercent), 100);
- }
-
- TTxType GetTxType() const override { return NHive::TXTYPE_MON_FIND_TABLET; }
-
+ : TBase(hive)
+ , Event(ev->Release())
+ , Source(source)
+ {
+ TabletId = FromStringWithDefault<TTabletId>(Event->Cgi().Get("tablet"), TabletId);
+ TabletType = (TTabletTypes::EType)FromStringWithDefault<int>(Event->Cgi().Get("type"), TabletType);
+ ChannelFrom = FromStringWithDefault<ui32>(Event->Cgi().Get("channelFrom"), ChannelFrom);
+ ChannelTo = FromStringWithDefault<ui32>(Event->Cgi().Get("channelTo"), ChannelTo);
+ GroupId = FromStringWithDefault(Event->Cgi().Get("group"), GroupId);
+ StoragePool = Event->Cgi().Get("storagePool");
+ TabletPercent = FromStringWithDefault<int>(Event->Cgi().Get("percent"), TabletPercent);
+ TabletPercent = std::min(std::abs(TabletPercent), 100);
+ }
+
+ TTxType GetTxType() const override { return NHive::TXTYPE_MON_FIND_TABLET; }
+
TInstant GetMaxTimestamp(const TLeaderTabletInfo* tablet) const {
- TInstant max;
- for (const auto& channel : tablet->TabletStorageInfo->Channels) {
- if (channel.Channel >= ChannelFrom && channel.Channel <= ChannelTo) {
- const auto* latest = channel.LatestEntry();
- if (latest != nullptr && latest->Timestamp > max) {
- max = latest->Timestamp;
- }
- }
- }
- return max;
- }
-
- bool Execute(TTransactionContext&, const TActorContext&) override {
+ TInstant max;
+ for (const auto& channel : tablet->TabletStorageInfo->Channels) {
+ if (channel.Channel >= ChannelFrom && channel.Channel <= ChannelTo) {
+ const auto* latest = channel.LatestEntry();
+ if (latest != nullptr && latest->Timestamp > max) {
+ max = latest->Timestamp;
+ }
+ }
+ }
+ return max;
+ }
+
+ bool Execute(TTransactionContext&, const TActorContext&) override {
TDeque<TLeaderTabletInfo*> tablets;
- if (TabletId != 0) {
+ if (TabletId != 0) {
TLeaderTabletInfo* tablet = Self->FindTablet(TabletId);
- if (tablet != nullptr) {
- tablets.push_back(tablet);
- }
- } else if (TabletType != TTabletTypes::TYPE_INVALID) {
- for (auto& pr : Self->Tablets) {
- if (pr.second.Type == TabletType) {
- tablets.push_back(&pr.second);
- }
- }
- } else {
- for (auto& pr : Self->Tablets) {
- tablets.push_back(&pr.second);
- }
- }
+ if (tablet != nullptr) {
+ tablets.push_back(tablet);
+ }
+ } else if (TabletType != TTabletTypes::TYPE_INVALID) {
+ for (auto& pr : Self->Tablets) {
+ if (pr.second.Type == TabletType) {
+ tablets.push_back(&pr.second);
+ }
+ }
+ } else {
+ for (auto& pr : Self->Tablets) {
+ tablets.push_back(&pr.second);
+ }
+ }
Sort(tablets, [this](TLeaderTabletInfo* a, TLeaderTabletInfo* b) -> bool {
- return GetMaxTimestamp(a) < GetMaxTimestamp(b);
- });
- Result.SetType(NJson::EJsonValueType::JSON_ARRAY);
+ return GetMaxTimestamp(a) < GetMaxTimestamp(b);
+ });
+ Result.SetType(NJson::EJsonValueType::JSON_ARRAY);
for (TLeaderTabletInfo* tablet : tablets) {
- TVector<ui32> channels;
- for (const auto& channel : tablet->TabletStorageInfo->Channels) {
- if (channel.Channel < ChannelFrom) {
- continue;
- }
- if (channel.Channel > ChannelTo) {
- continue;
- }
- if (StoragePool && channel.StoragePool != StoragePool) {
- continue;
- }
- if (GroupId) {
- const auto* latest = channel.LatestEntry();
- if (latest != nullptr && latest->GroupID != GroupId) {
- continue;
- }
- }
- channels.push_back(channel.Channel);
- }
- if (channels) {
- NJson::TJsonValue jsonTablet(NJson::EJsonValueType::JSON_MAP);
- jsonTablet["tabletId"] = ToString(tablet->Id);
- NJson::TJsonValue& jsonChannels(jsonTablet["channels"]);
- for (ui32 channel : channels) {
- jsonChannels.AppendValue(channel);
- }
- Result.AppendValue(jsonTablet);
- }
- }
- if (TabletPercent != 100) {
- Result.GetArraySafe().resize(Result.GetArraySafe().size() * TabletPercent / 100);
- }
- return true;
- }
-
- void Complete(const TActorContext& ctx) override {
- ctx.Send(Source, new NMon::TEvRemoteJsonInfoRes(NJson::WriteJson(Result, false)));
- }
-};
-
-class TTxMonEvent_TabletInfo : public TTransactionBase<THive> {
-public:
- THolder<NMon::TEvRemoteHttpInfo> Event;
- const TActorId Source;
- TTabletId TabletId = 0;
- NJson::TJsonValue Result;
-
- TTxMonEvent_TabletInfo(const TActorId& source, NMon::TEvRemoteHttpInfo::TPtr& ev, TSelf* hive)
- : TBase(hive)
- , Event(ev->Release())
- , Source(source)
- {
- TabletId = FromStringWithDefault<TTabletId>(Event->Cgi().Get("tablet"), TabletId);
- }
-
- TTxType GetTxType() const override { return NHive::TXTYPE_MON_TABLET_INFO; }
-
- static NJson::TJsonValue MakeFrom(const TActorId& actorId) {
- return actorId.ToString();
- }
-
- static NJson::TJsonValue MakeFrom(const TSubDomainKey& subDomainKey) {
- return TStringBuilder() << subDomainKey;
- }
-
- static NJson::TJsonValue MakeFrom(const NProtoBuf::Message& proto) {
- NJson::TJsonValue result;
- NProtobufJson::TProto2JsonConfig config;
- config.SetEnumMode(NProtobufJson::TProto2JsonConfig::EnumName);
- try {
- NProtobufJson::Proto2Json(proto, result, config);
- }
- catch (const std::exception& e) {
- result["error"] = e.what();
- }
- return result;
- }
-
- static NJson::TJsonValue MakeFrom(ui64 item) {
- return item;
- }
-
+ TVector<ui32> channels;
+ for (const auto& channel : tablet->TabletStorageInfo->Channels) {
+ if (channel.Channel < ChannelFrom) {
+ continue;
+ }
+ if (channel.Channel > ChannelTo) {
+ continue;
+ }
+ if (StoragePool && channel.StoragePool != StoragePool) {
+ continue;
+ }
+ if (GroupId) {
+ const auto* latest = channel.LatestEntry();
+ if (latest != nullptr && latest->GroupID != GroupId) {
+ continue;
+ }
+ }
+ channels.push_back(channel.Channel);
+ }
+ if (channels) {
+ NJson::TJsonValue jsonTablet(NJson::EJsonValueType::JSON_MAP);
+ jsonTablet["tabletId"] = ToString(tablet->Id);
+ NJson::TJsonValue& jsonChannels(jsonTablet["channels"]);
+ for (ui32 channel : channels) {
+ jsonChannels.AppendValue(channel);
+ }
+ Result.AppendValue(jsonTablet);
+ }
+ }
+ if (TabletPercent != 100) {
+ Result.GetArraySafe().resize(Result.GetArraySafe().size() * TabletPercent / 100);
+ }
+ return true;
+ }
+
+ void Complete(const TActorContext& ctx) override {
+ ctx.Send(Source, new NMon::TEvRemoteJsonInfoRes(NJson::WriteJson(Result, false)));
+ }
+};
+
+class TTxMonEvent_TabletInfo : public TTransactionBase<THive> {
+public:
+ THolder<NMon::TEvRemoteHttpInfo> Event;
+ const TActorId Source;
+ TTabletId TabletId = 0;
+ NJson::TJsonValue Result;
+
+ TTxMonEvent_TabletInfo(const TActorId& source, NMon::TEvRemoteHttpInfo::TPtr& ev, TSelf* hive)
+ : TBase(hive)
+ , Event(ev->Release())
+ , Source(source)
+ {
+ TabletId = FromStringWithDefault<TTabletId>(Event->Cgi().Get("tablet"), TabletId);
+ }
+
+ TTxType GetTxType() const override { return NHive::TXTYPE_MON_TABLET_INFO; }
+
+ static NJson::TJsonValue MakeFrom(const TActorId& actorId) {
+ return actorId.ToString();
+ }
+
+ static NJson::TJsonValue MakeFrom(const TSubDomainKey& subDomainKey) {
+ return TStringBuilder() << subDomainKey;
+ }
+
+ static NJson::TJsonValue MakeFrom(const NProtoBuf::Message& proto) {
+ NJson::TJsonValue result;
+ NProtobufJson::TProto2JsonConfig config;
+ config.SetEnumMode(NProtobufJson::TProto2JsonConfig::EnumName);
+ try {
+ NProtobufJson::Proto2Json(proto, result, config);
+ }
+ catch (const std::exception& e) {
+ result["error"] = e.what();
+ }
+ return result;
+ }
+
+ static NJson::TJsonValue MakeFrom(ui64 item) {
+ return item;
+ }
+
static NJson::TJsonValue MakeFrom(TString item) {
return item;
}
- template<typename Type>
- static NJson::TJsonValue MakeFrom(const TVector<Type>& array) {
- NJson::TJsonValue result;
- result.SetType(NJson::JSON_ARRAY);
- for (const auto& item : array) {
- result.AppendValue(MakeFrom(item));
- }
- return result;
- }
-
- template<typename Type>
- static NJson::TJsonValue MakeFrom(const TList<Type>& list) {
- NJson::TJsonValue result;
- result.SetType(NJson::JSON_ARRAY);
- for (const auto& item : list) {
- result.AppendValue(MakeFrom(item));
- }
- return result;
- }
-
- static NJson::TJsonValue MakeFrom(const TIntrusivePtr<TTabletStorageInfo>& info) {
- NJson::TJsonValue result;
- if (info == nullptr) {
- result.SetType(NJson::JSON_NULL);
- return result;
- }
- result["Version"] = info->Version;
- NJson::TJsonValue& channels = result["Channels"];
- channels.SetType(NJson::JSON_ARRAY);
- for (const TTabletChannelInfo& ch : info->Channels) {
- NJson::TJsonValue& channel = channels.AppendValue({});
- channel["Channel"] = ch.Channel;
- NJson::TJsonValue& history = channel["History"];
- history.SetType(NJson::JSON_ARRAY);
- for (const TTabletChannelInfo::THistoryEntry& hs : ch.History) {
- NJson::TJsonValue& item = history.AppendValue({});
- item["FromGeneration"] = hs.FromGeneration;
- item["GroupID"] = hs.GroupID;
- item["Timestamp"] = hs.Timestamp.ToString();
- }
- }
- return result;
- }
-
- static NJson::TJsonValue MakeFrom(const NMetrics::TMaximumValueVariableWindowUI64& maximum) {
- NJson::TJsonValue result;
- result["MaximumValue"] = maximum.GetValue();
- result["Data"] = MakeFrom((const NProtoBuf::Message&)maximum);
- return result;
- }
-
- static NJson::TJsonValue MakeFrom(const NKikimrTabletBase::TMetrics& metrics) {
- return MakeFrom((const NProtoBuf::Message&)metrics);
- }
-
- static NJson::TJsonValue MakeFrom(const TTabletMetricsAggregates& aggregates) {
- NJson::TJsonValue result;
- result["MaximumCPU"] = MakeFrom(aggregates.MaximumCPU);
- result["MaximumMemory"] = MakeFrom(aggregates.MaximumMemory);
- result["MaximumNetwork"] = MakeFrom(aggregates.MaximumNetwork);
- return result;
- }
-
- static NJson::TJsonValue MakeFrom(const TTabletCategoryInfo& category) {
- NJson::TJsonValue result;
- result["Id"] = category.Id;
- result["MaxDisconnectTimeout"] = category.MaxDisconnectTimeout;
- result["StickTogetherInDC"] = category.StickTogetherInDC;
- return result;
- }
-
- static NJson::TJsonValue MakeFrom(const TTabletInfo& tablet) {
- NJson::TJsonValue result;
- result["VolatileState"] = TTabletInfo::EVolatileStateName(tablet.VolatileState);
- result["VolatileStateChangeTime"] = tablet.VolatileStateChangeTime.ToString();
- result["TabletRole"] = TTabletInfo::ETabletRoleName(tablet.TabletRole);
- result["LastBalancerDecisionTime"] = tablet.LastBalancerDecisionTime.ToString();
- result["NodeId"] = tablet.NodeId;
- result["LastNodeId"] = tablet.LastNodeId;
- result["PreferredNodeId"] = tablet.PreferredNodeId;
- if (tablet.Node != nullptr) {
- result["Node"] = tablet.Node->Id;
- } else {
- result["Node"] = nullptr ;
- }
- result["PostponedStart"] = tablet.PostponedStart.ToString();
- result["Weight"] = tablet.Weight;
- result["BootState"] = tablet.BootState;
- result["ResourceValues"] = MakeFrom(tablet.ResourceValues);
- result["ResourceMetricsAggregates"] = MakeFrom(tablet.ResourceMetricsAggregates);
- result["ActorsToNotify"] = MakeFrom(tablet.ActorsToNotify);
- result["ActorsToNotifyOnRestart"] = MakeFrom(tablet.ActorsToNotifyOnRestart);
- return result;
- }
-
- static NJson::TJsonValue MakeFrom(const TFollowerGroup& group) {
- NJson::TJsonValue result;
- result["Id"] = TStringBuilder() << group.Id;
+ template<typename Type>
+ static NJson::TJsonValue MakeFrom(const TVector<Type>& array) {
+ NJson::TJsonValue result;
+ result.SetType(NJson::JSON_ARRAY);
+ for (const auto& item : array) {
+ result.AppendValue(MakeFrom(item));
+ }
+ return result;
+ }
+
+ template<typename Type>
+ static NJson::TJsonValue MakeFrom(const TList<Type>& list) {
+ NJson::TJsonValue result;
+ result.SetType(NJson::JSON_ARRAY);
+ for (const auto& item : list) {
+ result.AppendValue(MakeFrom(item));
+ }
+ return result;
+ }
+
+ static NJson::TJsonValue MakeFrom(const TIntrusivePtr<TTabletStorageInfo>& info) {
+ NJson::TJsonValue result;
+ if (info == nullptr) {
+ result.SetType(NJson::JSON_NULL);
+ return result;
+ }
+ result["Version"] = info->Version;
+ NJson::TJsonValue& channels = result["Channels"];
+ channels.SetType(NJson::JSON_ARRAY);
+ for (const TTabletChannelInfo& ch : info->Channels) {
+ NJson::TJsonValue& channel = channels.AppendValue({});
+ channel["Channel"] = ch.Channel;
+ NJson::TJsonValue& history = channel["History"];
+ history.SetType(NJson::JSON_ARRAY);
+ for (const TTabletChannelInfo::THistoryEntry& hs : ch.History) {
+ NJson::TJsonValue& item = history.AppendValue({});
+ item["FromGeneration"] = hs.FromGeneration;
+ item["GroupID"] = hs.GroupID;
+ item["Timestamp"] = hs.Timestamp.ToString();
+ }
+ }
+ return result;
+ }
+
+ static NJson::TJsonValue MakeFrom(const NMetrics::TMaximumValueVariableWindowUI64& maximum) {
+ NJson::TJsonValue result;
+ result["MaximumValue"] = maximum.GetValue();
+ result["Data"] = MakeFrom((const NProtoBuf::Message&)maximum);
+ return result;
+ }
+
+ static NJson::TJsonValue MakeFrom(const NKikimrTabletBase::TMetrics& metrics) {
+ return MakeFrom((const NProtoBuf::Message&)metrics);
+ }
+
+ static NJson::TJsonValue MakeFrom(const TTabletMetricsAggregates& aggregates) {
+ NJson::TJsonValue result;
+ result["MaximumCPU"] = MakeFrom(aggregates.MaximumCPU);
+ result["MaximumMemory"] = MakeFrom(aggregates.MaximumMemory);
+ result["MaximumNetwork"] = MakeFrom(aggregates.MaximumNetwork);
+ return result;
+ }
+
+ static NJson::TJsonValue MakeFrom(const TTabletCategoryInfo& category) {
+ NJson::TJsonValue result;
+ result["Id"] = category.Id;
+ result["MaxDisconnectTimeout"] = category.MaxDisconnectTimeout;
+ result["StickTogetherInDC"] = category.StickTogetherInDC;
+ return result;
+ }
+
+ static NJson::TJsonValue MakeFrom(const TTabletInfo& tablet) {
+ NJson::TJsonValue result;
+ result["VolatileState"] = TTabletInfo::EVolatileStateName(tablet.VolatileState);
+ result["VolatileStateChangeTime"] = tablet.VolatileStateChangeTime.ToString();
+ result["TabletRole"] = TTabletInfo::ETabletRoleName(tablet.TabletRole);
+ result["LastBalancerDecisionTime"] = tablet.LastBalancerDecisionTime.ToString();
+ result["NodeId"] = tablet.NodeId;
+ result["LastNodeId"] = tablet.LastNodeId;
+ result["PreferredNodeId"] = tablet.PreferredNodeId;
+ if (tablet.Node != nullptr) {
+ result["Node"] = tablet.Node->Id;
+ } else {
+ result["Node"] = nullptr ;
+ }
+ result["PostponedStart"] = tablet.PostponedStart.ToString();
+ result["Weight"] = tablet.Weight;
+ result["BootState"] = tablet.BootState;
+ result["ResourceValues"] = MakeFrom(tablet.ResourceValues);
+ result["ResourceMetricsAggregates"] = MakeFrom(tablet.ResourceMetricsAggregates);
+ result["ActorsToNotify"] = MakeFrom(tablet.ActorsToNotify);
+ result["ActorsToNotifyOnRestart"] = MakeFrom(tablet.ActorsToNotifyOnRestart);
+ return result;
+ }
+
+ static NJson::TJsonValue MakeFrom(const TFollowerGroup& group) {
+ NJson::TJsonValue result;
+ result["Id"] = TStringBuilder() << group.Id;
result["AllowLeaderPromotion"] = group.AllowLeaderPromotion;
- result["AllowClientRead"] = group.AllowClientRead;
- result["RequireAllDataCenters"] = group.RequireAllDataCenters;
- result["AllowedNodes"] = MakeFrom(group.AllowedNodes);
- result["AllowedDataCenters"] = MakeFrom(group.AllowedDataCenters);
- result["LocalNodeOnly"] = group.LocalNodeOnly;
- result["RequireDifferentNodes"] = group.RequireDifferentNodes;
- result["FollowerCountPerDataCenter"] = group.FollowerCountPerDataCenter;
- return result;
- }
-
- static NJson::TJsonValue MakeFrom(const TLeaderTabletInfo& tablet) {
- NJson::TJsonValue result;
- result = MakeFrom(static_cast<const TTabletInfo&>(tablet)); // base properties
- result["Id"] = TStringBuilder() << tablet.Id;
- result["State"] = ETabletStateName(tablet.State);
- result["Type"] = TTabletTypes::EType_Name(tablet.Type);
- result["ObjectId"] = tablet.ObjectId;
- result["ObjectDomain"] = TStringBuilder() << tablet.ObjectDomain;
- result["AllowedNodes"] = MakeFrom(tablet.AllowedNodes);
- result["AllowedDataCenters"] = MakeFrom(tablet.AllowedDataCenters);
- result["DataCenterPreference"] = MakeFrom(tablet.DataCentersPreference);
- result["TabletStorageInfo"] = MakeFrom(tablet.TabletStorageInfo);
- result["BoundChannels"] = MakeFrom(tablet.BoundChannels);
- result["ChannelProfileNewGroup"] = TString(tablet.ChannelProfileNewGroup.to_string());
- result["ChannelProfileReassignReason"] = NKikimrHive::TEvReassignTablet::EHiveReassignReason_Name(tablet.ChannelProfileReassignReason);
- result["KnownGeneration"] = tablet.KnownGeneration;
- result["BootMode"] = NKikimrHive::ETabletBootMode_Name(tablet.BootMode);
- result["Owner"] = TStringBuilder() << tablet.Owner;
- result["EffectiveAllowedDomain"] = MakeFrom(tablet.EffectiveAllowedDomains);
- result["StorageInfoSubscribers"] = MakeFrom(tablet.StorageInfoSubscribers);
- result["LockedToActor"] = MakeFrom(tablet.LockedToActor);
- result["LockedReconnectTimeout"] = tablet.LockedReconnectTimeout.ToString();
- result["PendingUnlockSeqNo"] = tablet.PendingUnlockSeqNo;
- result["FollowerGroups"] = MakeFrom(tablet.FollowerGroups);
- result["Followers"] = MakeFrom(tablet.Followers);
- result["Statistics"] = MakeFrom(tablet.Statistics);
- if (tablet.Category) {
- result["Category"] = MakeFrom(*tablet.Category);
- } else {
- result["Category"] = nullptr;
- }
- return result;
- }
-
- static NJson::TJsonValue MakeFrom(const TFollowerTabletInfo& tablet) {
- NJson::TJsonValue result;
- result = MakeFrom(static_cast<const TTabletInfo&>(tablet)); // base properties
- result["Id"] = TStringBuilder() << tablet.GetFullTabletId();
- result["FollowerGroupId"] = tablet.FollowerGroup.Id;
- return result;
- }
-
- bool Execute(TTransactionContext&, const TActorContext&) override {
- TLeaderTabletInfo* tablet = Self->FindTablet(TabletId);
- if (tablet != nullptr) {
- Result = MakeFrom(*tablet);
- } else {
- Result["error"] = "Not found";
- }
- return true;
- }
-
- void Complete(const TActorContext& ctx) override {
- ctx.Send(Source, new NMon::TEvRemoteJsonInfoRes(NJson::WriteJson(Result, false)));
- }
-};
-
+ result["AllowClientRead"] = group.AllowClientRead;
+ result["RequireAllDataCenters"] = group.RequireAllDataCenters;
+ result["AllowedNodes"] = MakeFrom(group.AllowedNodes);
+ result["AllowedDataCenters"] = MakeFrom(group.AllowedDataCenters);
+ result["LocalNodeOnly"] = group.LocalNodeOnly;
+ result["RequireDifferentNodes"] = group.RequireDifferentNodes;
+ result["FollowerCountPerDataCenter"] = group.FollowerCountPerDataCenter;
+ return result;
+ }
+
+ static NJson::TJsonValue MakeFrom(const TLeaderTabletInfo& tablet) {
+ NJson::TJsonValue result;
+ result = MakeFrom(static_cast<const TTabletInfo&>(tablet)); // base properties
+ result["Id"] = TStringBuilder() << tablet.Id;
+ result["State"] = ETabletStateName(tablet.State);
+ result["Type"] = TTabletTypes::EType_Name(tablet.Type);
+ result["ObjectId"] = tablet.ObjectId;
+ result["ObjectDomain"] = TStringBuilder() << tablet.ObjectDomain;
+ result["AllowedNodes"] = MakeFrom(tablet.AllowedNodes);
+ result["AllowedDataCenters"] = MakeFrom(tablet.AllowedDataCenters);
+ result["DataCenterPreference"] = MakeFrom(tablet.DataCentersPreference);
+ result["TabletStorageInfo"] = MakeFrom(tablet.TabletStorageInfo);
+ result["BoundChannels"] = MakeFrom(tablet.BoundChannels);
+ result["ChannelProfileNewGroup"] = TString(tablet.ChannelProfileNewGroup.to_string());
+ result["ChannelProfileReassignReason"] = NKikimrHive::TEvReassignTablet::EHiveReassignReason_Name(tablet.ChannelProfileReassignReason);
+ result["KnownGeneration"] = tablet.KnownGeneration;
+ result["BootMode"] = NKikimrHive::ETabletBootMode_Name(tablet.BootMode);
+ result["Owner"] = TStringBuilder() << tablet.Owner;
+ result["EffectiveAllowedDomain"] = MakeFrom(tablet.EffectiveAllowedDomains);
+ result["StorageInfoSubscribers"] = MakeFrom(tablet.StorageInfoSubscribers);
+ result["LockedToActor"] = MakeFrom(tablet.LockedToActor);
+ result["LockedReconnectTimeout"] = tablet.LockedReconnectTimeout.ToString();
+ result["PendingUnlockSeqNo"] = tablet.PendingUnlockSeqNo;
+ result["FollowerGroups"] = MakeFrom(tablet.FollowerGroups);
+ result["Followers"] = MakeFrom(tablet.Followers);
+ result["Statistics"] = MakeFrom(tablet.Statistics);
+ if (tablet.Category) {
+ result["Category"] = MakeFrom(*tablet.Category);
+ } else {
+ result["Category"] = nullptr;
+ }
+ return result;
+ }
+
+ static NJson::TJsonValue MakeFrom(const TFollowerTabletInfo& tablet) {
+ NJson::TJsonValue result;
+ result = MakeFrom(static_cast<const TTabletInfo&>(tablet)); // base properties
+ result["Id"] = TStringBuilder() << tablet.GetFullTabletId();
+ result["FollowerGroupId"] = tablet.FollowerGroup.Id;
+ return result;
+ }
+
+ bool Execute(TTransactionContext&, const TActorContext&) override {
+ TLeaderTabletInfo* tablet = Self->FindTablet(TabletId);
+ if (tablet != nullptr) {
+ Result = MakeFrom(*tablet);
+ } else {
+ Result["error"] = "Not found";
+ }
+ return true;
+ }
+
+ void Complete(const TActorContext& ctx) override {
+ ctx.Send(Source, new NMon::TEvRemoteJsonInfoRes(NJson::WriteJson(Result, false)));
+ }
+};
+
class TTxMonEvent_ResetTablet : public TTransactionBase<THive> {
class TResetter : public TActorBootstrapped<TResetter> {
TIntrusivePtr<TTabletStorageInfo> Info;
@@ -2913,8 +2913,8 @@ public:
TabletId = FromStringWithDefault<TTabletId>(ev->Get()->Cgi().Get("tablet"), TabletId);
}
- TTxType GetTxType() const override { return NHive::TXTYPE_MON_RESET_TABLET; }
-
+ TTxType GetTxType() const override { return NHive::TXTYPE_MON_RESET_TABLET; }
+
bool Execute(TTransactionContext&, const TActorContext& /*ctx*/) override {
if (TabletId) {
if (TLeaderTabletInfo* tablet = Self->FindTablet(TabletId)) {
@@ -2940,112 +2940,112 @@ public:
}
};
-class TUpdateResourcesActor : public TActorBootstrapped<TUpdateResourcesActor> {
-public:
+class TUpdateResourcesActor : public TActorBootstrapped<TUpdateResourcesActor> {
+public:
TActorId Source;
TActorId Hive;
- NKikimrHive::TTabletMetrics Metrics;
-
+ NKikimrHive::TTabletMetrics Metrics;
+
static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
return NKikimrServices::TActivity::HIVE_MON_REQUEST;
}
TUpdateResourcesActor(const TActorId& source, const TActorId& hive, const NKikimrHive::TTabletMetrics& metrics)
- : Source(source)
- , Hive(hive)
- , Metrics(metrics)
- {}
-
- void HandleTimeout(const TActorContext& ctx) {
- ctx.Send(Source, new NMon::TEvRemoteJsonInfoRes("{\"Error\": \"Timeout\"}"));
- Die(ctx);
- }
-
- void Handle(TEvLocal::TEvTabletMetricsAck::TPtr, const TActorContext& ctx) {
- ctx.Send(Source, new NMon::TEvRemoteJsonInfoRes("{}"));
- Die(ctx);
- }
-
- STFUNC(StateWork) {
- switch (ev->GetTypeRewrite()) {
- HFunc(TEvLocal::TEvTabletMetricsAck, Handle);
- CFunc(TEvents::TSystem::Wakeup, HandleTimeout);
- }
- }
-
- void Bootstrap(const TActorContext& ctx) {
- TAutoPtr<TEvHive::TEvTabletMetrics> event(new TEvHive::TEvTabletMetrics());
- auto& record = event->Record;
- auto& metrics = *record.AddTabletMetrics();
- metrics = Metrics;
- ctx.Send(Hive, event.Release());
- Become(&TUpdateResourcesActor::StateWork, ctx, TDuration::MilliSeconds(30), new TEvents::TEvWakeup());
- }
-};
-
-class TCreateTabletActor : public TActorBootstrapped<TCreateTabletActor> {
-public:
+ : Source(source)
+ , Hive(hive)
+ , Metrics(metrics)
+ {}
+
+ void HandleTimeout(const TActorContext& ctx) {
+ ctx.Send(Source, new NMon::TEvRemoteJsonInfoRes("{\"Error\": \"Timeout\"}"));
+ Die(ctx);
+ }
+
+ void Handle(TEvLocal::TEvTabletMetricsAck::TPtr, const TActorContext& ctx) {
+ ctx.Send(Source, new NMon::TEvRemoteJsonInfoRes("{}"));
+ Die(ctx);
+ }
+
+ STFUNC(StateWork) {
+ switch (ev->GetTypeRewrite()) {
+ HFunc(TEvLocal::TEvTabletMetricsAck, Handle);
+ CFunc(TEvents::TSystem::Wakeup, HandleTimeout);
+ }
+ }
+
+ void Bootstrap(const TActorContext& ctx) {
+ TAutoPtr<TEvHive::TEvTabletMetrics> event(new TEvHive::TEvTabletMetrics());
+ auto& record = event->Record;
+ auto& metrics = *record.AddTabletMetrics();
+ metrics = Metrics;
+ ctx.Send(Hive, event.Release());
+ Become(&TUpdateResourcesActor::StateWork, ctx, TDuration::MilliSeconds(30), new TEvents::TEvWakeup());
+ }
+};
+
+class TCreateTabletActor : public TActorBootstrapped<TCreateTabletActor> {
+public:
TActorId Source;
- TAutoPtr<TEvHive::TEvCreateTablet> Event;
- THive* Hive;
-
+ TAutoPtr<TEvHive::TEvCreateTablet> Event;
+ THive* Hive;
+
static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
return NKikimrServices::TActivity::HIVE_MON_REQUEST;
}
TCreateTabletActor(const TActorId& source, ui64 owner, ui64 ownerIdx, TTabletTypes::EType type, ui32 channelsProfile, ui32 followers, THive* hive)
- : Source(source)
- , Event(new TEvHive::TEvCreateTablet())
- , Hive(hive)
- {
- Event->Record.SetOwner(owner);
- Event->Record.SetOwnerIdx(ownerIdx);
- Event->Record.SetTabletType(type);
- Event->Record.SetChannelsProfile(channelsProfile);
+ : Source(source)
+ , Event(new TEvHive::TEvCreateTablet())
+ , Hive(hive)
+ {
+ Event->Record.SetOwner(owner);
+ Event->Record.SetOwnerIdx(ownerIdx);
+ Event->Record.SetTabletType(type);
+ Event->Record.SetChannelsProfile(channelsProfile);
Event->Record.SetFollowerCount(followers);
- }
-
- void HandleTimeout(const TActorContext& ctx) {
- ctx.Send(Source, new NMon::TEvRemoteJsonInfoRes("{\"Error\": \"Timeout\"}"));
- Die(ctx);
- }
-
- void Handle(TEvHive::TEvCreateTabletReply::TPtr& ptr, const TActorContext& ctx) {
- TStringStream stream;
- stream << ptr->Get()->Record.AsJSON();
- ctx.Send(Source, new NMon::TEvRemoteJsonInfoRes(stream.Str()));
- Die(ctx);
- }
-
- void Handle(TEvHive::TEvTabletCreationResult::TPtr& ptr, const TActorContext& ctx) {
- TStringStream stream;
- stream << ptr->Get()->Record.AsJSON();
- ctx.Send(Source, new NMon::TEvRemoteJsonInfoRes(stream.Str()));
- Die(ctx);
- }
-
- STFUNC(StateWork) {
- switch (ev->GetTypeRewrite()) {
- HFunc(TEvHive::TEvCreateTabletReply, Handle);
- HFunc(TEvHive::TEvTabletCreationResult, Handle);
- CFunc(TEvents::TSystem::Wakeup, HandleTimeout);
- }
- }
-
- void Bootstrap(const TActorContext& ctx) {
+ }
+
+ void HandleTimeout(const TActorContext& ctx) {
+ ctx.Send(Source, new NMon::TEvRemoteJsonInfoRes("{\"Error\": \"Timeout\"}"));
+ Die(ctx);
+ }
+
+ void Handle(TEvHive::TEvCreateTabletReply::TPtr& ptr, const TActorContext& ctx) {
+ TStringStream stream;
+ stream << ptr->Get()->Record.AsJSON();
+ ctx.Send(Source, new NMon::TEvRemoteJsonInfoRes(stream.Str()));
+ Die(ctx);
+ }
+
+ void Handle(TEvHive::TEvTabletCreationResult::TPtr& ptr, const TActorContext& ctx) {
+ TStringStream stream;
+ stream << ptr->Get()->Record.AsJSON();
+ ctx.Send(Source, new NMon::TEvRemoteJsonInfoRes(stream.Str()));
+ Die(ctx);
+ }
+
+ STFUNC(StateWork) {
+ switch (ev->GetTypeRewrite()) {
+ HFunc(TEvHive::TEvCreateTabletReply, Handle);
+ HFunc(TEvHive::TEvTabletCreationResult, Handle);
+ CFunc(TEvents::TSystem::Wakeup, HandleTimeout);
+ }
+ }
+
+ void Bootstrap(const TActorContext& ctx) {
ctx.Send(Hive->SelfId(), Event.Release());
- Become(&TThis::StateWork, ctx, TDuration::Seconds(30), new TEvents::TEvWakeup());
- }
-};
-
-class TDeleteTabletActor : public TActorBootstrapped<TDeleteTabletActor> {
+ Become(&TThis::StateWork, ctx, TDuration::Seconds(30), new TEvents::TEvWakeup());
+ }
+};
+
+class TDeleteTabletActor : public TActorBootstrapped<TDeleteTabletActor> {
private:
ui64 FAKE_TXID = -1;
public:
TActorId Source;
TAutoPtr<TEvHive::TEvDeleteTablet> Event;
- THive* Hive;
+ THive* Hive;
TDeleteTabletActor(const TActorId& source, ui64 owner, ui64 ownerIdx, THive* hive)
: Source(source)
@@ -3108,294 +3108,294 @@ public:
}
};
-class TTxMonEvent_Groups : public TTransactionBase<THive> {
-public:
+class TTxMonEvent_Groups : public TTransactionBase<THive> {
+public:
const TActorId Source;
- TAutoPtr<NMon::TEvRemoteHttpInfo> Event;
-
+ TAutoPtr<NMon::TEvRemoteHttpInfo> Event;
+
TTxMonEvent_Groups(const TActorId &source, NMon::TEvRemoteHttpInfo::TPtr& ev, TSelf *hive)
- : TBase(hive)
- , Source(source)
- , Event(ev->Release())
- {}
-
- TTxType GetTxType() const override { return NHive::TXTYPE_MON_GROUPS; }
-
- bool Execute(TTransactionContext& txc, const TActorContext& ctx) override {
- TStringStream out;
- const auto& params(Event->Cgi());
- TTabletId filterTabletId = FromStringWithDefault<TTabletId>(params.Get("tablet_id"), (ui64)-1);
- ui64 filterGroupId = FromStringWithDefault<ui64>(params.Get("group_id"), (ui64)-1);
-
- out << "<head>";
- out << "<script>$('.container').toggleClass('container container-fluid').css('padding-left', '5%') .css('padding-right', '5%');</script>";
- out << "</head><body>";
-
- out << "<table class='table'>";
- out << "<thead>";
- out << "<tr><th>TabletID</th><th>Channel</th><th>GroupID</th><th>Generation</th><th>Version</th><th>Timestamp</th><th>Current AU</th></tr>";
- out << "</thead>";
-
- out << "<tbody>";
-
- NIceDb::TNiceDb db(txc.DB);
- auto tabletChannelGenRowset = db.Table<Schema::TabletChannelGen>().Range().Select();
- if (!tabletChannelGenRowset.IsReady())
- return false;
- while (!tabletChannelGenRowset.EndOfSet()) {
- TTabletId id = tabletChannelGenRowset.GetValue<Schema::TabletChannelGen::Tablet>();
- auto group = tabletChannelGenRowset.GetValue<Schema::TabletChannelGen::Group>();
- bool filterOk = (filterTabletId == id) || (filterGroupId == group) || (filterTabletId == (ui64)-1 && filterGroupId == (ui64)-1);
- if (filterOk) {
- ui32 channel = tabletChannelGenRowset.GetValue<Schema::TabletChannelGen::Channel>();
- out << "<tr>";
- out << "<td><a href='../tablets?TabletID=" << id << "'>" << id << "</a></td>";
- out << "<td>" << channel << "</td>";
- out << "<td>" << group << "</td>";
- out << "<td>" << tabletChannelGenRowset.GetValue<Schema::TabletChannelGen::Generation>() << "</td>";
- if (tabletChannelGenRowset.HaveValue<Schema::TabletChannelGen::Version>()) {
- out << "<td>" << tabletChannelGenRowset.GetValue<Schema::TabletChannelGen::Version>() << "</td>";
- } else {
- out << "<td></td>";
- }
- if (tabletChannelGenRowset.HaveValue<Schema::TabletChannelGen::Timestamp>()) {
- out << "<td>" << TInstant::MilliSeconds(tabletChannelGenRowset.GetValue<Schema::TabletChannelGen::Timestamp>()).ToString() << "</td>";
- } else {
- out << "<td></td>";
- }
- TString unitSize;
- TTabletInfo* tablet = Self->FindTablet(id);
- if (tablet) {
+ : TBase(hive)
+ , Source(source)
+ , Event(ev->Release())
+ {}
+
+ TTxType GetTxType() const override { return NHive::TXTYPE_MON_GROUPS; }
+
+ bool Execute(TTransactionContext& txc, const TActorContext& ctx) override {
+ TStringStream out;
+ const auto& params(Event->Cgi());
+ TTabletId filterTabletId = FromStringWithDefault<TTabletId>(params.Get("tablet_id"), (ui64)-1);
+ ui64 filterGroupId = FromStringWithDefault<ui64>(params.Get("group_id"), (ui64)-1);
+
+ out << "<head>";
+ out << "<script>$('.container').toggleClass('container container-fluid').css('padding-left', '5%') .css('padding-right', '5%');</script>";
+ out << "</head><body>";
+
+ out << "<table class='table'>";
+ out << "<thead>";
+ out << "<tr><th>TabletID</th><th>Channel</th><th>GroupID</th><th>Generation</th><th>Version</th><th>Timestamp</th><th>Current AU</th></tr>";
+ out << "</thead>";
+
+ out << "<tbody>";
+
+ NIceDb::TNiceDb db(txc.DB);
+ auto tabletChannelGenRowset = db.Table<Schema::TabletChannelGen>().Range().Select();
+ if (!tabletChannelGenRowset.IsReady())
+ return false;
+ while (!tabletChannelGenRowset.EndOfSet()) {
+ TTabletId id = tabletChannelGenRowset.GetValue<Schema::TabletChannelGen::Tablet>();
+ auto group = tabletChannelGenRowset.GetValue<Schema::TabletChannelGen::Group>();
+ bool filterOk = (filterTabletId == id) || (filterGroupId == group) || (filterTabletId == (ui64)-1 && filterGroupId == (ui64)-1);
+ if (filterOk) {
+ ui32 channel = tabletChannelGenRowset.GetValue<Schema::TabletChannelGen::Channel>();
+ out << "<tr>";
+ out << "<td><a href='../tablets?TabletID=" << id << "'>" << id << "</a></td>";
+ out << "<td>" << channel << "</td>";
+ out << "<td>" << group << "</td>";
+ out << "<td>" << tabletChannelGenRowset.GetValue<Schema::TabletChannelGen::Generation>() << "</td>";
+ if (tabletChannelGenRowset.HaveValue<Schema::TabletChannelGen::Version>()) {
+ out << "<td>" << tabletChannelGenRowset.GetValue<Schema::TabletChannelGen::Version>() << "</td>";
+ } else {
+ out << "<td></td>";
+ }
+ if (tabletChannelGenRowset.HaveValue<Schema::TabletChannelGen::Timestamp>()) {
+ out << "<td>" << TInstant::MilliSeconds(tabletChannelGenRowset.GetValue<Schema::TabletChannelGen::Timestamp>()).ToString() << "</td>";
+ } else {
+ out << "<td></td>";
+ }
+ TString unitSize;
+ TTabletInfo* tablet = Self->FindTablet(id);
+ if (tablet) {
TLeaderTabletInfo& leader = tablet->GetLeader();
if (channel < leader.GetChannelCount()) {
unitSize = leader.BoundChannels[channel].ShortDebugString();
- }
- }
- out << "<td>" << unitSize << "</td>";
-
- out << "</tr>";
- }
-
- if (!tabletChannelGenRowset.Next())
- return false;
- }
- out <<"</tbody>";
- out << "</table>";
-
- out << "</body>";
- ctx.Send(Source, new NMon::TEvRemoteHttpInfoRes(out.Str()));
- return true;
- }
-
- void Complete(const TActorContext&) override {}
-};
-
-class TTxMonEvent_NotReady : public TTransactionBase<THive> {
-public:
+ }
+ }
+ out << "<td>" << unitSize << "</td>";
+
+ out << "</tr>";
+ }
+
+ if (!tabletChannelGenRowset.Next())
+ return false;
+ }
+ out <<"</tbody>";
+ out << "</table>";
+
+ out << "</body>";
+ ctx.Send(Source, new NMon::TEvRemoteHttpInfoRes(out.Str()));
+ return true;
+ }
+
+ void Complete(const TActorContext&) override {}
+};
+
+class TTxMonEvent_NotReady : public TTransactionBase<THive> {
+public:
const TActorId Source;
-
+
TTxMonEvent_NotReady(const TActorId& source, TSelf* hive)
- : TBase(hive)
- , Source(source)
- {}
-
- TTxType GetTxType() const override { return NHive::TXTYPE_MON_NOT_READY; }
-
- bool Execute(TTransactionContext&, const TActorContext& ctx) override {
- ctx.Send(Source, new NMon::TEvRemoteHttpInfoRes("<head></head><body><h1>Hive is not ready yet</h1></body>"));
- return true;
- }
-
- void Complete(const TActorContext&) override {}
-};
-
-class TTxMonEvent_Storage : public TTransactionBase<THive> {
-public:
+ : TBase(hive)
+ , Source(source)
+ {}
+
+ TTxType GetTxType() const override { return NHive::TXTYPE_MON_NOT_READY; }
+
+ bool Execute(TTransactionContext&, const TActorContext& ctx) override {
+ ctx.Send(Source, new NMon::TEvRemoteHttpInfoRes("<head></head><body><h1>Hive is not ready yet</h1></body>"));
+ return true;
+ }
+
+ void Complete(const TActorContext&) override {}
+};
+
+class TTxMonEvent_Storage : public TTransactionBase<THive> {
+public:
const TActorId Source;
- THolder<NMon::TEvRemoteHttpInfo> Event;
- bool Kinds = true;
-
+ THolder<NMon::TEvRemoteHttpInfo> Event;
+ bool Kinds = true;
+
TTxMonEvent_Storage(const TActorId &source, NMon::TEvRemoteHttpInfo::TPtr& ev, TSelf *hive)
- : TBase(hive)
- , Source(source)
- , Event(ev->Release())
- {
- Kinds = FromStringWithDefault(Event->Cgi().Get("kinds"), Kinds);
- }
-
- TTxType GetTxType() const override { return NHive::TXTYPE_MON_STORAGE; }
-
- bool Execute(TTransactionContext &txc, const TActorContext& ctx) override {
- Y_UNUSED(txc);
- TStringStream str;
- RenderHTMLPage(str);
- ctx.Send(Source, new NMon::TEvRemoteHttpInfoRes(str.Str()));
- return true;
- }
-
- void Complete(const TActorContext& ctx) override {
- Y_UNUSED(ctx);
- }
-
- struct TUnitKind {
- double IOPS;
- ui64 Throughput;
- ui64 Size;
-
- bool operator ==(const TUnitKind& o) const {
- return IOPS == o.IOPS && Throughput == o.Throughput && Size == o.Size;
- }
-
- TString ToString() const {
- return TStringBuilder() << "{IOPS:" << Sprintf("%.2f",IOPS) << ",Throughput:" << GetBytesPerSecond(Throughput) << ",Size:" << GetBytes(Size) << "}";
- }
- };
-
- struct TUnitKindHash {
- size_t operator ()(const TUnitKind& a) const {
- return hash_combiner::hash_val(a.IOPS, a.Throughput, a.Size);
- }
- };
-
- using TKindMap = THashMap<TUnitKind, ui32, TUnitKindHash>;
-
- void GetUnitKinds(const TStorageGroupInfo& group, TKindMap& kinds) {
- for (const auto& [tablet, channel] : group.Units) {
- const auto& boundChannels(tablet->BoundChannels[channel]);
- kinds[TUnitKind{boundChannels.GetIOPS(), boundChannels.GetThroughput(), boundChannels.GetSize()}]++;
- }
- }
-
- void RenderHTMLPage(IOutputStream &out) {
- out << "<script>$('.container').css('width', 'auto');</script>";
-
- out << "<table class='table table-sortable'>";
- out << "<thead>";
- if (Kinds) {
- out << "<tr><th>Storage Pool</th><th>Group ID</th><th>Binding Kind</th><th>AUs</th><th>Acq. IOPS</th><th>Max. IOPS</th><th>Acq. Size</th><th>Max. Size</th>"
- "<th>Acq. Thr.</th><th>Max. Thr.</th><th>Overcommit</th><th>Group Usage</th></tr>";
- } else {
- out << "<tr><th>Storage Pool</th><th>Group ID</th><th>AUs</th><th>Acq. IOPS</th><th>Max. IOPS</th><th>Acq. Size</th><th>Max. Size</th>"
- "<th>Acq. Thr.</th><th>Max. Thr.</th><th>Allocated Size</th><th>Available Size</th><th>Overcommit</th><th>Group Usage</th></tr>";
- }
- out << "</thead>";
- out << "<tbody>";
- for (const auto& prStoragePool : Self->StoragePools) {
- for (const auto& prStorageGroup : prStoragePool.second.Groups) {
- if (Kinds) {
- TKindMap kindMap;
- GetUnitKinds(prStorageGroup.second, kindMap);
- for (const auto& [kind, units] : kindMap) {
- out << "<tr>";
- out << "<td>" << prStoragePool.second.Name << "</td>";
- out << "<td style='text-align:right'>" << prStorageGroup.second.Id << "</td>";
- out << "<td style='text-align:right'>" << kind.ToString() << "</td>";
- out << "<td style='text-align:right'>" << units << "</td>";
- out << "<td style='text-align:right'>" << Sprintf("%.2f", kind.IOPS * units) << "</td>";
- out << "<td style='text-align:right'>" << Sprintf("%.2f", prStorageGroup.second.MaximumIOPS) << "</td>";
- out << "<td style='text-align:right'>" << kind.Size * units << "</td>";
- out << "<td style='text-align:right'>" << prStorageGroup.second.MaximumSize << "</td>";
- out << "<td style='text-align:right'>" << kind.Throughput * units << "</td>";
- out << "<td style='text-align:right'>" << prStorageGroup.second.MaximumThroughput << "</td>";
- out << "<td style='text-align:right'>" << Sprintf("%.2f", prStorageGroup.second.StoragePool.GetOvercommit()) << "</td>";
- out << "<td style='text-align:right'>" << Sprintf("%.2f", prStorageGroup.second.GetUsage()) << "</td>";
- out << "</tr>";
- }
- } else {
- const TStorageGroupInfo& group = prStorageGroup.second;
- out << "<tr>";
- out << "<td>" << prStoragePool.second.Name << "</td>";
- out << "<td style='text-align:right'>" << group.Id << "</td>";
- out << "<td style='text-align:right'>" << group.Units.size() << "</td>";
- out << "<td style='text-align:right'>" << Sprintf("%.2f", group.AcquiredIOPS) << "</td>";
- out << "<td style='text-align:right'>" << Sprintf("%.2f", group.MaximumIOPS) << "</td>";
- out << "<td style='text-align:right'>" << group.AcquiredSize << "</td>";
- out << "<td style='text-align:right'>" << group.MaximumSize << "</td>";
- out << "<td style='text-align:right'>" << group.AcquiredThroughput << "</td>";
- out << "<td style='text-align:right'>" << group.MaximumThroughput << "</td>";
- out << "<td style='text-align:right'>" << group.GroupParameters.GetAllocatedSize() << "</td>";
- out << "<td style='text-align:right'>" << group.GroupParameters.GetAvailableSize() << "</td>";
- out << "<td style='text-align:right'>" << Sprintf("%.2f", group.StoragePool.GetOvercommit()) << "</td>";
- out << "<td style='text-align:right'>" << Sprintf("%.2f", group.GetUsage()) << "</td>";
- out << "</tr>";
- }
- }
- }
- out << "</tbody>";
- out << "</table>";
- out << "</div></div>";
- }
-};
-
-void THive::CreateEvMonitoring(NMon::TEvRemoteHttpInfo::TPtr& ev, const TActorContext& ctx) {
- if (!ReadyForConnections) {
- return Execute(new TTxMonEvent_NotReady(ev->Sender, this), ctx);
- }
- NMon::TEvRemoteHttpInfo* httpInfo = ev->Get();
- TCgiParameters cgi(httpInfo->Cgi());
+ : TBase(hive)
+ , Source(source)
+ , Event(ev->Release())
+ {
+ Kinds = FromStringWithDefault(Event->Cgi().Get("kinds"), Kinds);
+ }
+
+ TTxType GetTxType() const override { return NHive::TXTYPE_MON_STORAGE; }
+
+ bool Execute(TTransactionContext &txc, const TActorContext& ctx) override {
+ Y_UNUSED(txc);
+ TStringStream str;
+ RenderHTMLPage(str);
+ ctx.Send(Source, new NMon::TEvRemoteHttpInfoRes(str.Str()));
+ return true;
+ }
+
+ void Complete(const TActorContext& ctx) override {
+ Y_UNUSED(ctx);
+ }
+
+ struct TUnitKind {
+ double IOPS;
+ ui64 Throughput;
+ ui64 Size;
+
+ bool operator ==(const TUnitKind& o) const {
+ return IOPS == o.IOPS && Throughput == o.Throughput && Size == o.Size;
+ }
+
+ TString ToString() const {
+ return TStringBuilder() << "{IOPS:" << Sprintf("%.2f",IOPS) << ",Throughput:" << GetBytesPerSecond(Throughput) << ",Size:" << GetBytes(Size) << "}";
+ }
+ };
+
+ struct TUnitKindHash {
+ size_t operator ()(const TUnitKind& a) const {
+ return hash_combiner::hash_val(a.IOPS, a.Throughput, a.Size);
+ }
+ };
+
+ using TKindMap = THashMap<TUnitKind, ui32, TUnitKindHash>;
+
+ void GetUnitKinds(const TStorageGroupInfo& group, TKindMap& kinds) {
+ for (const auto& [tablet, channel] : group.Units) {
+ const auto& boundChannels(tablet->BoundChannels[channel]);
+ kinds[TUnitKind{boundChannels.GetIOPS(), boundChannels.GetThroughput(), boundChannels.GetSize()}]++;
+ }
+ }
+
+ void RenderHTMLPage(IOutputStream &out) {
+ out << "<script>$('.container').css('width', 'auto');</script>";
+
+ out << "<table class='table table-sortable'>";
+ out << "<thead>";
+ if (Kinds) {
+ out << "<tr><th>Storage Pool</th><th>Group ID</th><th>Binding Kind</th><th>AUs</th><th>Acq. IOPS</th><th>Max. IOPS</th><th>Acq. Size</th><th>Max. Size</th>"
+ "<th>Acq. Thr.</th><th>Max. Thr.</th><th>Overcommit</th><th>Group Usage</th></tr>";
+ } else {
+ out << "<tr><th>Storage Pool</th><th>Group ID</th><th>AUs</th><th>Acq. IOPS</th><th>Max. IOPS</th><th>Acq. Size</th><th>Max. Size</th>"
+ "<th>Acq. Thr.</th><th>Max. Thr.</th><th>Allocated Size</th><th>Available Size</th><th>Overcommit</th><th>Group Usage</th></tr>";
+ }
+ out << "</thead>";
+ out << "<tbody>";
+ for (const auto& prStoragePool : Self->StoragePools) {
+ for (const auto& prStorageGroup : prStoragePool.second.Groups) {
+ if (Kinds) {
+ TKindMap kindMap;
+ GetUnitKinds(prStorageGroup.second, kindMap);
+ for (const auto& [kind, units] : kindMap) {
+ out << "<tr>";
+ out << "<td>" << prStoragePool.second.Name << "</td>";
+ out << "<td style='text-align:right'>" << prStorageGroup.second.Id << "</td>";
+ out << "<td style='text-align:right'>" << kind.ToString() << "</td>";
+ out << "<td style='text-align:right'>" << units << "</td>";
+ out << "<td style='text-align:right'>" << Sprintf("%.2f", kind.IOPS * units) << "</td>";
+ out << "<td style='text-align:right'>" << Sprintf("%.2f", prStorageGroup.second.MaximumIOPS) << "</td>";
+ out << "<td style='text-align:right'>" << kind.Size * units << "</td>";
+ out << "<td style='text-align:right'>" << prStorageGroup.second.MaximumSize << "</td>";
+ out << "<td style='text-align:right'>" << kind.Throughput * units << "</td>";
+ out << "<td style='text-align:right'>" << prStorageGroup.second.MaximumThroughput << "</td>";
+ out << "<td style='text-align:right'>" << Sprintf("%.2f", prStorageGroup.second.StoragePool.GetOvercommit()) << "</td>";
+ out << "<td style='text-align:right'>" << Sprintf("%.2f", prStorageGroup.second.GetUsage()) << "</td>";
+ out << "</tr>";
+ }
+ } else {
+ const TStorageGroupInfo& group = prStorageGroup.second;
+ out << "<tr>";
+ out << "<td>" << prStoragePool.second.Name << "</td>";
+ out << "<td style='text-align:right'>" << group.Id << "</td>";
+ out << "<td style='text-align:right'>" << group.Units.size() << "</td>";
+ out << "<td style='text-align:right'>" << Sprintf("%.2f", group.AcquiredIOPS) << "</td>";
+ out << "<td style='text-align:right'>" << Sprintf("%.2f", group.MaximumIOPS) << "</td>";
+ out << "<td style='text-align:right'>" << group.AcquiredSize << "</td>";
+ out << "<td style='text-align:right'>" << group.MaximumSize << "</td>";
+ out << "<td style='text-align:right'>" << group.AcquiredThroughput << "</td>";
+ out << "<td style='text-align:right'>" << group.MaximumThroughput << "</td>";
+ out << "<td style='text-align:right'>" << group.GroupParameters.GetAllocatedSize() << "</td>";
+ out << "<td style='text-align:right'>" << group.GroupParameters.GetAvailableSize() << "</td>";
+ out << "<td style='text-align:right'>" << Sprintf("%.2f", group.StoragePool.GetOvercommit()) << "</td>";
+ out << "<td style='text-align:right'>" << Sprintf("%.2f", group.GetUsage()) << "</td>";
+ out << "</tr>";
+ }
+ }
+ }
+ out << "</tbody>";
+ out << "</table>";
+ out << "</div></div>";
+ }
+};
+
+void THive::CreateEvMonitoring(NMon::TEvRemoteHttpInfo::TPtr& ev, const TActorContext& ctx) {
+ if (!ReadyForConnections) {
+ return Execute(new TTxMonEvent_NotReady(ev->Sender, this), ctx);
+ }
+ NMon::TEvRemoteHttpInfo* httpInfo = ev->Get();
+ TCgiParameters cgi(httpInfo->Cgi());
TString page = cgi.Has("page") ? cgi.Get("page") : "";
- if (page == "MemStateTablets")
- return Execute(new TTxMonEvent_MemStateTablets(ev->Sender, ev, this), ctx);
- if (page == "MemStateNodes")
- return Execute(new TTxMonEvent_MemStateNodes(ev->Sender, ev, this), ctx);
- if (page == "MemStateDomains")
- return Execute(new TTxMonEvent_MemStateDomains(ev->Sender, ev, this), ctx);
- if (page == "DbState")
- return Execute(new TTxMonEvent_DbState(ev->Sender, this), ctx);
- if (page == "SetDown") {
- TNodeId nodeId = FromStringWithDefault<TNodeId>(cgi.Get("node"), 0);
- return Execute(new TTxMonEvent_SetDown(ev->Sender, nodeId, FromStringWithDefault<i32>(cgi.Get("down"), 0) != 0, this), ctx);
- }
- if (page == "SetFreeze") {
- TNodeId nodeId = FromStringWithDefault<TNodeId>(cgi.Get("node"), 0);
- return Execute(new TTxMonEvent_SetFreeze(ev->Sender, nodeId, FromStringWithDefault<i32>(cgi.Get("freeze"), 0) != 0, this), ctx);
- }
- if (page == "KickNode") {
- TNodeId nodeId = FromStringWithDefault<TNodeId>(cgi.Get("node"), 0);
- return Execute(new TTxMonEvent_KickNode(ev->Sender, nodeId, this), ctx);
- }
- if (page == "DrainNode") {
- return Execute(new TTxMonEvent_DrainNode(ev->Sender, ev, this), ctx);
- }
- if (page == "Rebalance") {
- return Execute(new TTxMonEvent_Rebalance(ev->Sender, ev, this), ctx);
- }
- if (page == "LandingData") {
- return Execute(new TTxMonEvent_LandingData(ev->Sender, ev, this), ctx);
- }
- if (page == "ReassignTablet") {
- return Execute(new TTxMonEvent_ReassignTablet(ev->Sender, ev, this), ctx);
- }
- if (page == "InitMigration") {
- return Execute(new TTxMonEvent_InitMigration(ev->Sender, ev, this), ctx);
- }
- if (page == "QueryMigration") {
- return Execute(new TTxMonEvent_QueryMigration(ev->Sender, ev, this), ctx);
- }
- if (page == "StopTablet") {
- return Execute(new TTxMonEvent_StopTablet(ev->Sender, ev, this), ctx);
- }
- if (page == "ResumeTablet") {
- return Execute(new TTxMonEvent_ResumeTablet(ev->Sender, ev, this), ctx);
- }
- if (page == "FindTablet") {
- return Execute(new TTxMonEvent_FindTablet(ev->Sender, ev, this), ctx);
- }
- if (page == "TabletInfo") {
- return Execute(new TTxMonEvent_TabletInfo(ev->Sender, ev, this), ctx);
- }
+ if (page == "MemStateTablets")
+ return Execute(new TTxMonEvent_MemStateTablets(ev->Sender, ev, this), ctx);
+ if (page == "MemStateNodes")
+ return Execute(new TTxMonEvent_MemStateNodes(ev->Sender, ev, this), ctx);
+ if (page == "MemStateDomains")
+ return Execute(new TTxMonEvent_MemStateDomains(ev->Sender, ev, this), ctx);
+ if (page == "DbState")
+ return Execute(new TTxMonEvent_DbState(ev->Sender, this), ctx);
+ if (page == "SetDown") {
+ TNodeId nodeId = FromStringWithDefault<TNodeId>(cgi.Get("node"), 0);
+ return Execute(new TTxMonEvent_SetDown(ev->Sender, nodeId, FromStringWithDefault<i32>(cgi.Get("down"), 0) != 0, this), ctx);
+ }
+ if (page == "SetFreeze") {
+ TNodeId nodeId = FromStringWithDefault<TNodeId>(cgi.Get("node"), 0);
+ return Execute(new TTxMonEvent_SetFreeze(ev->Sender, nodeId, FromStringWithDefault<i32>(cgi.Get("freeze"), 0) != 0, this), ctx);
+ }
+ if (page == "KickNode") {
+ TNodeId nodeId = FromStringWithDefault<TNodeId>(cgi.Get("node"), 0);
+ return Execute(new TTxMonEvent_KickNode(ev->Sender, nodeId, this), ctx);
+ }
+ if (page == "DrainNode") {
+ return Execute(new TTxMonEvent_DrainNode(ev->Sender, ev, this), ctx);
+ }
+ if (page == "Rebalance") {
+ return Execute(new TTxMonEvent_Rebalance(ev->Sender, ev, this), ctx);
+ }
+ if (page == "LandingData") {
+ return Execute(new TTxMonEvent_LandingData(ev->Sender, ev, this), ctx);
+ }
+ if (page == "ReassignTablet") {
+ return Execute(new TTxMonEvent_ReassignTablet(ev->Sender, ev, this), ctx);
+ }
+ if (page == "InitMigration") {
+ return Execute(new TTxMonEvent_InitMigration(ev->Sender, ev, this), ctx);
+ }
+ if (page == "QueryMigration") {
+ return Execute(new TTxMonEvent_QueryMigration(ev->Sender, ev, this), ctx);
+ }
+ if (page == "StopTablet") {
+ return Execute(new TTxMonEvent_StopTablet(ev->Sender, ev, this), ctx);
+ }
+ if (page == "ResumeTablet") {
+ return Execute(new TTxMonEvent_ResumeTablet(ev->Sender, ev, this), ctx);
+ }
+ if (page == "FindTablet") {
+ return Execute(new TTxMonEvent_FindTablet(ev->Sender, ev, this), ctx);
+ }
+ if (page == "TabletInfo") {
+ return Execute(new TTxMonEvent_TabletInfo(ev->Sender, ev, this), ctx);
+ }
if (page == "ResetTablet") {
return Execute(new TTxMonEvent_ResetTablet(ev->Sender, ev, this), ctx);
}
- if (page == "CreateTablet") {
- ui64 owner = FromStringWithDefault<ui64>(cgi.Get("owner"), 0);
- ui64 ownerIdx = FromStringWithDefault<ui64>(cgi.Get("owner_idx"), 0);
- TTabletTypes::EType type = (TTabletTypes::EType)FromStringWithDefault<ui32>(cgi.Get("type"), 0);
- ui32 channelsProfile = FromStringWithDefault<ui32>(cgi.Get("profile"), 0);
+ if (page == "CreateTablet") {
+ ui64 owner = FromStringWithDefault<ui64>(cgi.Get("owner"), 0);
+ ui64 ownerIdx = FromStringWithDefault<ui64>(cgi.Get("owner_idx"), 0);
+ TTabletTypes::EType type = (TTabletTypes::EType)FromStringWithDefault<ui32>(cgi.Get("type"), 0);
+ ui32 channelsProfile = FromStringWithDefault<ui32>(cgi.Get("profile"), 0);
ui32 followers = FromStringWithDefault<ui32>(cgi.Get("followers"), 0);
ctx.RegisterWithSameMailbox(new TCreateTabletActor(ev->Sender, owner, ownerIdx, type, channelsProfile, followers, this));
- return;
- }
+ return;
+ }
if (page == "DeleteTablet") {
if (cgi.Has("owner") && cgi.Has("owner_idx")) {
ui64 owner = FromStringWithDefault<ui64>(cgi.Get("owner"), 0);
@@ -3409,42 +3409,42 @@ void THive::CreateEvMonitoring(NMon::TEvRemoteHttpInfo::TPtr& ev, const TActorCo
}
return;
}
- if (page == "Resources") {
- return Execute(new TTxMonEvent_Resources(ev->Sender, ev, this), ctx);
- }
- if (page == "Settings") {
- return Execute(new TTxMonEvent_Settings(ev->Sender, ev, this), ctx);
- }
- if (page == "Groups") {
- return Execute(new TTxMonEvent_Groups(ev->Sender, ev, this), ctx);
- }
- if (page == "UpdateResources") {
- TTabletId tabletId = FromStringWithDefault<TTabletId>(cgi.Get("tablet"), 0);
- TTabletInfo* tablet = FindTablet(tabletId);
- if (tablet != nullptr) {
- NKikimrHive::TTabletMetrics metrics;
- metrics.SetTabletID(tabletId);
- if (cgi.Get("cpu")) {
- metrics.MutableResourceUsage()->SetCPU(FromStringWithDefault<ui64>(cgi.Get("cpu"), 0));
- }
- if (cgi.Get("kv")) {
- metrics.MutableResourceUsage()->SetMemory(FromStringWithDefault<ui64>(cgi.Get("kv"), 0));
- }
- if (cgi.Get("memory")) {
- metrics.MutableResourceUsage()->SetMemory(FromStringWithDefault<ui64>(cgi.Get("memory"), 0));
- }
- if (cgi.Get("network")) {
- metrics.MutableResourceUsage()->SetNetwork(FromStringWithDefault<ui64>(cgi.Get("network"), 0));
- }
+ if (page == "Resources") {
+ return Execute(new TTxMonEvent_Resources(ev->Sender, ev, this), ctx);
+ }
+ if (page == "Settings") {
+ return Execute(new TTxMonEvent_Settings(ev->Sender, ev, this), ctx);
+ }
+ if (page == "Groups") {
+ return Execute(new TTxMonEvent_Groups(ev->Sender, ev, this), ctx);
+ }
+ if (page == "UpdateResources") {
+ TTabletId tabletId = FromStringWithDefault<TTabletId>(cgi.Get("tablet"), 0);
+ TTabletInfo* tablet = FindTablet(tabletId);
+ if (tablet != nullptr) {
+ NKikimrHive::TTabletMetrics metrics;
+ metrics.SetTabletID(tabletId);
+ if (cgi.Get("cpu")) {
+ metrics.MutableResourceUsage()->SetCPU(FromStringWithDefault<ui64>(cgi.Get("cpu"), 0));
+ }
+ if (cgi.Get("kv")) {
+ metrics.MutableResourceUsage()->SetMemory(FromStringWithDefault<ui64>(cgi.Get("kv"), 0));
+ }
+ if (cgi.Get("memory")) {
+ metrics.MutableResourceUsage()->SetMemory(FromStringWithDefault<ui64>(cgi.Get("memory"), 0));
+ }
+ if (cgi.Get("network")) {
+ metrics.MutableResourceUsage()->SetNetwork(FromStringWithDefault<ui64>(cgi.Get("network"), 0));
+ }
ctx.RegisterWithSameMailbox(new TUpdateResourcesActor(ev->Sender, SelfId(), metrics));
return;
- }
- }
- if (page == "Storage") {
- return Execute(new TTxMonEvent_Storage(ev->Sender, ev, this), ctx);
- }
- return Execute(new TTxMonEvent_Landing(ev->Sender, ev, this), ctx);
+ }
+ }
+ if (page == "Storage") {
+ return Execute(new TTxMonEvent_Storage(ev->Sender, ev, this), ctx);
+ }
+ return Execute(new TTxMonEvent_Landing(ev->Sender, ev, this), ctx);
}
-} // NHive
-} // NKikimr
+} // NHive
+} // NKikimr
diff --git a/ydb/core/mind/hive/node_info.cpp b/ydb/core/mind/hive/node_info.cpp
index d1269830fe0..8b6913c9819 100644
--- a/ydb/core/mind/hive/node_info.cpp
+++ b/ydb/core/mind/hive/node_info.cpp
@@ -1,441 +1,441 @@
-#include "hive_impl.h"
-#include "hive_log.h"
-
-namespace NKikimr {
-namespace NHive {
-
-TNodeInfo::TNodeInfo(TNodeId nodeId, THive& hive)
- : VolatileState(EVolatileState::Unknown)
- , Hive(hive)
- , Id(nodeId)
- , Down(false)
- , Freeze(false)
- , Drain(false)
- , ResourceValues()
- , ResourceTotalValues()
- , ResourceMaximumValues(GetResourceInitialMaximumValues())
- , StartTime(TInstant::MicroSeconds(0))
+#include "hive_impl.h"
+#include "hive_log.h"
+
+namespace NKikimr {
+namespace NHive {
+
+TNodeInfo::TNodeInfo(TNodeId nodeId, THive& hive)
+ : VolatileState(EVolatileState::Unknown)
+ , Hive(hive)
+ , Id(nodeId)
+ , Down(false)
+ , Freeze(false)
+ , Drain(false)
+ , ResourceValues()
+ , ResourceTotalValues()
+ , ResourceMaximumValues(GetResourceInitialMaximumValues())
+ , StartTime(TInstant::MicroSeconds(0))
, Location()
, LocationAcquired(false)
-{}
-
-void TNodeInfo::ChangeVolatileState(EVolatileState state) {
- BLOG_W("Node(" << Id << ", " << ResourceValues << ") VolatileState: " << EVolatileStateName(VolatileState) << " -> " << EVolatileStateName(state));
-
- if (state == EVolatileState::Connected) {
- switch (VolatileState) {
- case EVolatileState::Unknown:
- case EVolatileState::Disconnected:
- case EVolatileState::Connecting:
- RegisterInDomains();
+{}
+
+void TNodeInfo::ChangeVolatileState(EVolatileState state) {
+ BLOG_W("Node(" << Id << ", " << ResourceValues << ") VolatileState: " << EVolatileStateName(VolatileState) << " -> " << EVolatileStateName(state));
+
+ if (state == EVolatileState::Connected) {
+ switch (VolatileState) {
+ case EVolatileState::Unknown:
+ case EVolatileState::Disconnected:
+ case EVolatileState::Connecting:
+ RegisterInDomains();
+ break;
+
+ default:
break;
+ };
+ }
- default:
- break;
- };
- }
-
- if (state == EVolatileState::Disconnected) {
- switch (VolatileState) {
- case EVolatileState::Connected:
- case EVolatileState::Disconnecting:
- DeregisterInDomains();
+ if (state == EVolatileState::Disconnected) {
+ switch (VolatileState) {
+ case EVolatileState::Connected:
+ case EVolatileState::Disconnecting:
+ DeregisterInDomains();
break;
- default:
- break;
- };
- }
-
- VolatileState = state;
-}
-
-bool TNodeInfo::OnTabletChangeVolatileState(TTabletInfo* tablet, TTabletInfo::EVolatileState newState) {
- TTabletInfo::EVolatileState oldState = tablet->GetVolatileState();
- if (IsResourceDrainingState(oldState)) {
- if (Tablets[oldState].erase(tablet) != 0) {
- UpdateResourceValues(tablet, tablet->GetResourceValues(), NKikimrTabletBase::TMetrics());
- } else {
- if (oldState != newState) {
- BLOG_W("Node(" << Id << ") could not delete tablet " << tablet->ToString() << " from state " << TTabletInfo::EVolatileStateName(oldState));
- }
- }
- }
- if (IsAliveState(oldState)) {
- TabletsRunningByType[tablet->GetTabletType()].erase(tablet);
- TabletsOfObject[tablet->GetObjectId()].erase(tablet);
- Hive.UpdateCounterTabletsAlive(-1);
- }
- if (IsResourceDrainingState(newState)) {
- if (Tablets[newState].insert(tablet).second) {
- UpdateResourceValues(tablet, NKikimrTabletBase::TMetrics(), tablet->GetResourceValues());
- } else {
- BLOG_W("Node(" << Id << ") could not insert tablet " << tablet->ToString() << " to state " << TTabletInfo::EVolatileStateName(newState));
- }
- }
- if (IsAliveState(newState)) {
- TabletsRunningByType[tablet->GetTabletType()].emplace(tablet);
- TabletsOfObject[tablet->GetObjectId()].emplace(tablet);
- Hive.UpdateCounterTabletsAlive(+1);
- }
- return true;
-}
-
-void TNodeInfo::UpdateResourceValues(const TTabletInfo* tablet, const NKikimrTabletBase::TMetrics& before, const NKikimrTabletBase::TMetrics& after) {
- TResourceRawValues delta = ResourceRawValuesFromMetrics(after) - ResourceRawValuesFromMetrics(before);
- auto oldResourceValues = ResourceValues;
- auto oldNormalizedValues = NormalizeRawValues(ResourceValues, ResourceMaximumValues);
- ResourceValues += delta;
- auto normalizedValues = NormalizeRawValues(ResourceValues, ResourceMaximumValues);
- BLOG_TRACE("Node(" << Id << ", " << oldResourceValues << "->" << ResourceValues << ")");
- Hive.UpdateTotalResourceValues(this, tablet, before, after, ResourceValues - oldResourceValues, normalizedValues - oldNormalizedValues);
-}
-
-bool TNodeInfo::IsAllowedToRunTablet(TTabletDebugState* debugState) const {
- if (Down) {
- if (debugState) {
- debugState->NodesDown++;
- }
- return false;
- }
-
+ default:
+ break;
+ };
+ }
+
+ VolatileState = state;
+}
+
+bool TNodeInfo::OnTabletChangeVolatileState(TTabletInfo* tablet, TTabletInfo::EVolatileState newState) {
+ TTabletInfo::EVolatileState oldState = tablet->GetVolatileState();
+ if (IsResourceDrainingState(oldState)) {
+ if (Tablets[oldState].erase(tablet) != 0) {
+ UpdateResourceValues(tablet, tablet->GetResourceValues(), NKikimrTabletBase::TMetrics());
+ } else {
+ if (oldState != newState) {
+ BLOG_W("Node(" << Id << ") could not delete tablet " << tablet->ToString() << " from state " << TTabletInfo::EVolatileStateName(oldState));
+ }
+ }
+ }
+ if (IsAliveState(oldState)) {
+ TabletsRunningByType[tablet->GetTabletType()].erase(tablet);
+ TabletsOfObject[tablet->GetObjectId()].erase(tablet);
+ Hive.UpdateCounterTabletsAlive(-1);
+ }
+ if (IsResourceDrainingState(newState)) {
+ if (Tablets[newState].insert(tablet).second) {
+ UpdateResourceValues(tablet, NKikimrTabletBase::TMetrics(), tablet->GetResourceValues());
+ } else {
+ BLOG_W("Node(" << Id << ") could not insert tablet " << tablet->ToString() << " to state " << TTabletInfo::EVolatileStateName(newState));
+ }
+ }
+ if (IsAliveState(newState)) {
+ TabletsRunningByType[tablet->GetTabletType()].emplace(tablet);
+ TabletsOfObject[tablet->GetObjectId()].emplace(tablet);
+ Hive.UpdateCounterTabletsAlive(+1);
+ }
+ return true;
+}
+
+void TNodeInfo::UpdateResourceValues(const TTabletInfo* tablet, const NKikimrTabletBase::TMetrics& before, const NKikimrTabletBase::TMetrics& after) {
+ TResourceRawValues delta = ResourceRawValuesFromMetrics(after) - ResourceRawValuesFromMetrics(before);
+ auto oldResourceValues = ResourceValues;
+ auto oldNormalizedValues = NormalizeRawValues(ResourceValues, ResourceMaximumValues);
+ ResourceValues += delta;
+ auto normalizedValues = NormalizeRawValues(ResourceValues, ResourceMaximumValues);
+ BLOG_TRACE("Node(" << Id << ", " << oldResourceValues << "->" << ResourceValues << ")");
+ Hive.UpdateTotalResourceValues(this, tablet, before, after, ResourceValues - oldResourceValues, normalizedValues - oldNormalizedValues);
+}
+
+bool TNodeInfo::IsAllowedToRunTablet(TTabletDebugState* debugState) const {
+ if (Down) {
+ if (debugState) {
+ debugState->NodesDown++;
+ }
+ return false;
+ }
+
if (!LocationAcquired) {
- if (debugState) {
- debugState->NodesWithoutLocation++;
- }
- return false;
- }
- return true;
-}
-
-bool TNodeInfo::IsAllowedToRunTablet(const TTabletInfo& tablet, TTabletDebugState* debugState) const {
- if (!IsAllowedToRunTablet(debugState)) {
- return false;
- }
-
+ if (debugState) {
+ debugState->NodesWithoutLocation++;
+ }
+ return false;
+ }
+ return true;
+}
+
+bool TNodeInfo::IsAllowedToRunTablet(const TTabletInfo& tablet, TTabletDebugState* debugState) const {
+ if (!IsAllowedToRunTablet(debugState)) {
+ return false;
+ }
+
const TVector<TSubDomainKey>& allowedDomains = tablet.GetLeader().EffectiveAllowedDomains;
- bool result = false;
-
- for (const auto& candidate : allowedDomains) {
- if (Hive.DomainHasNodes(candidate)) {
- result = std::find(ServicedDomains.begin(),
- ServicedDomains.end(),
- candidate) != ServicedDomains.end();
- if (result) {
- break;
- }
- }
- }
- if (!result) {
- if (debugState) {
- debugState->NodesWithoutDomain++;
- }
- return false;
- }
-
- const TVector<TNodeId>& allowedNodes = tablet.GetAllowedNodes();
-
- if (!allowedNodes.empty()
- && std::find(allowedNodes.begin(), allowedNodes.end(), Id) == allowedNodes.end()) {
- if (debugState) {
- debugState->NodesNotAllowed++;
- }
- return false;
- }
-
+ bool result = false;
+
+ for (const auto& candidate : allowedDomains) {
+ if (Hive.DomainHasNodes(candidate)) {
+ result = std::find(ServicedDomains.begin(),
+ ServicedDomains.end(),
+ candidate) != ServicedDomains.end();
+ if (result) {
+ break;
+ }
+ }
+ }
+ if (!result) {
+ if (debugState) {
+ debugState->NodesWithoutDomain++;
+ }
+ return false;
+ }
+
+ const TVector<TNodeId>& allowedNodes = tablet.GetAllowedNodes();
+
+ if (!allowedNodes.empty()
+ && std::find(allowedNodes.begin(), allowedNodes.end(), Id) == allowedNodes.end()) {
+ if (debugState) {
+ debugState->NodesNotAllowed++;
+ }
+ return false;
+ }
+
if (tablet.IsFollower() && tablet.AsFollower().FollowerGroup.LocalNodeOnly) {
const TLeaderTabletInfo& leader = tablet.GetLeader();
if (!leader.IsRunning()) {
- if (debugState) {
+ if (debugState) {
debugState->LeaderNotRunning = true;
- }
- return false;
- }
+ }
+ return false;
+ }
if (leader.NodeId != Id) {
- if (debugState) {
+ if (debugState) {
debugState->NodesWithLeaderNotLocal++;
- }
- return false;
- }
- }
-
- const TVector<TDataCenterId>& allowedDataCenters = tablet.GetAllowedDataCenters();
-
- if (!allowedDataCenters.empty()
- && std::find(
- allowedDataCenters.begin(),
- allowedDataCenters.end(),
- GetDataCenter()) == allowedDataCenters.end()) {
- if (debugState) {
- debugState->NodesInDatacentersNotAllowed++;
- }
- return false;
- }
-
- return true;
-}
-
-bool TNodeInfo::IsAbleToRunTablet(const TTabletInfo& tablet, TTabletDebugState* debugState) const {
- if (tablet.IsAliveOnLocal(Local)) {
- return !IsOverloaded();
- }
+ }
+ return false;
+ }
+ }
+
+ const TVector<TDataCenterId>& allowedDataCenters = tablet.GetAllowedDataCenters();
+
+ if (!allowedDataCenters.empty()
+ && std::find(
+ allowedDataCenters.begin(),
+ allowedDataCenters.end(),
+ GetDataCenter()) == allowedDataCenters.end()) {
+ if (debugState) {
+ debugState->NodesInDatacentersNotAllowed++;
+ }
+ return false;
+ }
+
+ return true;
+}
+
+bool TNodeInfo::IsAbleToRunTablet(const TTabletInfo& tablet, TTabletDebugState* debugState) const {
+ if (tablet.IsAliveOnLocal(Local)) {
+ return !IsOverloaded();
+ }
if (tablet.IsLeader()) {
const TLeaderTabletInfo& leader = tablet.AsLeader();
if (leader.IsFollowerPromotableOnNode(Id)) {
- return true;
- }
- }
+ return true;
+ }
+ }
// const TLeaderTabletInfo& leader = tablet.GetLeader();
// if (!leader.Followers.empty()) {
// if (leader.IsSomeoneAliveOnNode(Id)) {
-// return false;
-// }
-// }
+// return false;
+// }
+// }
if (tablet.IsFollower()) {
const TFollowerTabletInfo& follower = tablet.AsFollower();
const TFollowerGroup& followerGroup = follower.FollowerGroup;
const TLeaderTabletInfo& leader = follower.LeaderTablet;
if (followerGroup.RequireAllDataCenters) {
- auto dataCenters = Hive.GetRegisteredDataCenters();
- ui32 maxFollowersPerDataCenter = (followerGroup.GetComputedFollowerCount(Hive.GetDataCenters()) + dataCenters - 1) / dataCenters; // ceil
+ auto dataCenters = Hive.GetRegisteredDataCenters();
+ ui32 maxFollowersPerDataCenter = (followerGroup.GetComputedFollowerCount(Hive.GetDataCenters()) + dataCenters - 1) / dataCenters; // ceil
ui32 existingFollowers;
- if (tablet.IsAlive()) {
+ if (tablet.IsAlive()) {
existingFollowers = leader.GetFollowersAliveOnDataCenterExcludingFollower(Location.GetDataCenterId(), tablet);
- } else {
+ } else {
existingFollowers = leader.GetFollowersAliveOnDataCenter(Location.GetDataCenterId());
- }
+ }
if (maxFollowersPerDataCenter <= existingFollowers) {
- if (debugState) {
+ if (debugState) {
debugState->NodesFilledWithDatacenterFollowers++;
- }
- return false;
- }
- }
+ }
+ return false;
+ }
+ }
if (followerGroup.RequireDifferentNodes) {
if (leader.IsSomeoneAliveOnNode(Id)) {
- if (debugState) {
- debugState->NodesWithSomeoneFromOurFamily++;
- }
- return false;
- }
- }
- }
-
- {
- ui64 maxCount = 0;
- TTabletTypes::EType tabletType = tablet.GetTabletType();
- if (!TabletAvailability.empty()) {
- auto itTabletAvailability = TabletAvailability.find(tabletType);
- if (itTabletAvailability == TabletAvailability.end()) {
- if (debugState) {
- debugState->NodesWithoutResources++;
- }
- return false;
- } else {
- maxCount = itTabletAvailability->second.GetMaxCount();
- }
- }
- if (maxCount == 0) {
- const std::unordered_map<TTabletTypes::EType, NKikimrConfig::THiveTabletLimit>& tabletLimit = Hive.GetTabletLimit();
- auto itTabletLimit = tabletLimit.find(tabletType);
- if (itTabletLimit != tabletLimit.end()) {
- maxCount = itTabletLimit->second.GetMaxCount();
- }
- }
- if (maxCount != 0) {
- ui64 currentCount = GetTabletsRunningByType(tabletType);
- if (currentCount >= maxCount) {
- if (debugState) {
- debugState->NodesWithoutResources++;
- }
- return false;
- }
- }
- }
-
- if (tablet.IsAlive() && IsOverloaded()) {
- // we don't move already running tablet to another overloaded node
- if (debugState) {
- debugState->NodesWithoutResources++;
- }
- return false;
- }
-
- auto maximumResources = GetResourceMaximumValues() * Hive.GetResourceOvercommitment();
- auto allocatedResources = GetResourceCurrentValues() + tablet.GetResourceCurrentValues();
-
- bool result = min(maximumResources - allocatedResources) > 0;
- if (!result) {
- if (debugState) {
- debugState->NodesWithoutResources++;
- }
- }
- return result;
-}
-
-ui64 TNodeInfo::GetMaxTabletsScheduled() const {
- return Hive.GetMaxTabletsScheduled();
-}
-
-bool TNodeInfo::IsOverloaded() const {
- return GetNodeUsage() >= Hive.GetMaxNodeUsageToKick();
-}
-
-bool TNodeInfo::BecomeConnected() {
- if (VolatileState == EVolatileState::Connected) {
- return true;
- }
- if (VolatileState == EVolatileState::Connecting) {
- Y_VERIFY((bool)Local);
- ChangeVolatileState(EVolatileState::Connected);
- StartTime = DEPRECATED_NOW;
- return true;
- } else {
- return false;
- }
-}
-
-void TNodeInfo::RegisterInDomains() {
- Hive.DomainsView.RegisterNode(*this);
-}
-
-void TNodeInfo::DeregisterInDomains() {
- Hive.DomainsView.DeregisterNode(*this);
- LastSeenServicedDomains = std::move(ServicedDomains); // clear ServicedDomains
-}
-
-void TNodeInfo::Ping() {
- Y_VERIFY((bool)Local);
- BLOG_D("Node(" << Id << ") Ping(" << Local << ")");
- Hive.SendPing(Local, Id);
-}
-
+ if (debugState) {
+ debugState->NodesWithSomeoneFromOurFamily++;
+ }
+ return false;
+ }
+ }
+ }
+
+ {
+ ui64 maxCount = 0;
+ TTabletTypes::EType tabletType = tablet.GetTabletType();
+ if (!TabletAvailability.empty()) {
+ auto itTabletAvailability = TabletAvailability.find(tabletType);
+ if (itTabletAvailability == TabletAvailability.end()) {
+ if (debugState) {
+ debugState->NodesWithoutResources++;
+ }
+ return false;
+ } else {
+ maxCount = itTabletAvailability->second.GetMaxCount();
+ }
+ }
+ if (maxCount == 0) {
+ const std::unordered_map<TTabletTypes::EType, NKikimrConfig::THiveTabletLimit>& tabletLimit = Hive.GetTabletLimit();
+ auto itTabletLimit = tabletLimit.find(tabletType);
+ if (itTabletLimit != tabletLimit.end()) {
+ maxCount = itTabletLimit->second.GetMaxCount();
+ }
+ }
+ if (maxCount != 0) {
+ ui64 currentCount = GetTabletsRunningByType(tabletType);
+ if (currentCount >= maxCount) {
+ if (debugState) {
+ debugState->NodesWithoutResources++;
+ }
+ return false;
+ }
+ }
+ }
+
+ if (tablet.IsAlive() && IsOverloaded()) {
+ // we don't move already running tablet to another overloaded node
+ if (debugState) {
+ debugState->NodesWithoutResources++;
+ }
+ return false;
+ }
+
+ auto maximumResources = GetResourceMaximumValues() * Hive.GetResourceOvercommitment();
+ auto allocatedResources = GetResourceCurrentValues() + tablet.GetResourceCurrentValues();
+
+ bool result = min(maximumResources - allocatedResources) > 0;
+ if (!result) {
+ if (debugState) {
+ debugState->NodesWithoutResources++;
+ }
+ }
+ return result;
+}
+
+ui64 TNodeInfo::GetMaxTabletsScheduled() const {
+ return Hive.GetMaxTabletsScheduled();
+}
+
+bool TNodeInfo::IsOverloaded() const {
+ return GetNodeUsage() >= Hive.GetMaxNodeUsageToKick();
+}
+
+bool TNodeInfo::BecomeConnected() {
+ if (VolatileState == EVolatileState::Connected) {
+ return true;
+ }
+ if (VolatileState == EVolatileState::Connecting) {
+ Y_VERIFY((bool)Local);
+ ChangeVolatileState(EVolatileState::Connected);
+ StartTime = DEPRECATED_NOW;
+ return true;
+ } else {
+ return false;
+ }
+}
+
+void TNodeInfo::RegisterInDomains() {
+ Hive.DomainsView.RegisterNode(*this);
+}
+
+void TNodeInfo::DeregisterInDomains() {
+ Hive.DomainsView.DeregisterNode(*this);
+ LastSeenServicedDomains = std::move(ServicedDomains); // clear ServicedDomains
+}
+
+void TNodeInfo::Ping() {
+ Y_VERIFY((bool)Local);
+ BLOG_D("Node(" << Id << ") Ping(" << Local << ")");
+ Hive.SendPing(Local, Id);
+}
+
void TNodeInfo::SendReconnect(const TActorId& local) {
- BLOG_D("Node(" << Id << ") Reconnect(" << local << ")");
- Hive.SendReconnect(local);
-}
-
-void TNodeInfo::SetDown(bool down) {
- Down = down;
- if (!Down) {
- Hive.ProcessWaitQueue();
- }
-}
-
-void TNodeInfo::SetFreeze(bool freeze) {
- Freeze = freeze;
- if (!Freeze) {
- Hive.ProcessWaitQueue();
- }
-}
-
-void TNodeInfo::UpdateResourceMaximum(const NKikimrTabletBase::TMetrics& metrics) {
- auto oldNormalizedValues = NormalizeRawValues(ResourceValues, ResourceMaximumValues);
- if (metrics.HasCPU()) {
- std::get<NMetrics::EResource::CPU>(ResourceMaximumValues) = metrics.GetCPU();
- }
- if (metrics.HasMemory()) {
- std::get<NMetrics::EResource::Memory>(ResourceMaximumValues) = metrics.GetMemory();
- }
- if (metrics.HasNetwork()) {
- std::get<NMetrics::EResource::Network>(ResourceMaximumValues) = metrics.GetNetwork();
- }
- auto normalizedValues = NormalizeRawValues(ResourceValues, ResourceMaximumValues);
- Hive.UpdateTotalResourceValues(nullptr, nullptr, NKikimrTabletBase::TMetrics(), NKikimrTabletBase::TMetrics(), {}, normalizedValues - oldNormalizedValues);
-}
-
-double TNodeInfo::GetNodeUsageForTablet(const TTabletInfo& tablet) const {
- // what it would like when tablet will run on this node?
- TResourceRawValues nodeValues = GetResourceCurrentValues();
- TResourceRawValues tabletValues = tablet.GetResourceCurrentValues();
- tablet.FilterRawValues(nodeValues);
- tablet.FilterRawValues(tabletValues);
- auto current = tablet.IsAliveOnLocal(Local) ? nodeValues : nodeValues + tabletValues;
- auto maximum = GetResourceMaximumValues();
- // basically, this is: return max(a / b);
- double usage = TTabletInfo::GetUsage(current, maximum);
- if (Hive.GetSpreadNeighbours() && usage < 1) {
- auto neighbours = GetTabletNeighboursCount(tablet);
- if (neighbours > 0) {
- auto remain = 1 - usage;
- auto cost = remain / (neighbours + 1);
- usage += cost * neighbours; // n / (n + 1)
- }
- }
- return usage;
-}
-
-double TNodeInfo::GetNodeUsage() const {
- double usage = TTabletInfo::GetUsage(GetResourceCurrentValues(), GetResourceMaximumValues());
- if (AveragedNodeTotalUsage.IsValueStable()) {
- usage = std::max(usage, AveragedNodeTotalUsage.GetValue());
- }
- return usage;
-}
-
-ui64 TNodeInfo::GetTabletsRunningByType(TTabletTypes::EType tabletType) const {
- auto itRunningByType = TabletsRunningByType.find(tabletType);
- if (itRunningByType != TabletsRunningByType.end()) {
- return itRunningByType->second.size();
- }
- return 0;
-}
-
-TResourceRawValues TNodeInfo::GetResourceInitialMaximumValues() {
- return Hive.GetResourceInitialMaximumValues();
-}
-
-TResourceRawValues TNodeInfo::GetStDevResourceValues() {
- TVector<TResourceRawValues> values;
- const std::unordered_set<TTabletInfo*>& runningTablets = Tablets[TTabletInfo::EVolatileState::TABLET_VOLATILE_STATE_RUNNING];
- values.reserve(runningTablets.size());
- for (const TTabletInfo* tablet : runningTablets) {
- values.push_back(tablet->GetResourceCurrentValues());
- }
- return GetStDev(values);
-}
-
-bool TNodeInfo::CanBeDeleted() const {
- TInstant lastAlive(TInstant::MilliSeconds(Statistics.GetLastAliveTimestamp()));
- if (lastAlive) {
- return (IsDisconnected() || IsUnknown())
- && !Local
- && GetTabletsTotal() == 0
- && LockedTablets.empty()
- && !Freeze
- && (lastAlive + Hive.GetNodeDeletePeriod() < TInstant::Now());
- } else {
- return (IsDisconnected() || IsUnknown()) && !Local && GetTabletsTotal() == 0 && LockedTablets.empty() && !Freeze;
- }
-}
-
-void TNodeInfo::UpdateResourceTotalUsage(const NKikimrHive::TEvTabletMetrics& metrics) {
- if (metrics.HasTotalResourceUsage()) {
- AveragedResourceTotalValues.Push(ResourceRawValuesFromMetrics(metrics.GetTotalResourceUsage()));
- ResourceTotalValues = AveragedResourceTotalValues.GetValue();
- }
- if (metrics.HasTotalNodeUsage()) {
- AveragedNodeTotalUsage.Push(metrics.GetTotalNodeUsage());
- NodeTotalUsage = AveragedNodeTotalUsage.GetValue();
- }
-}
-
-TResourceRawValues TNodeInfo::GetResourceCurrentValues() const {
- if (AveragedResourceTotalValues.IsValueStable()) {
- return piecewise_max(ResourceValues, ResourceTotalValues);
- } else {
- return ResourceValues;
- }
-}
-
-void TNodeInfo::ActualizeNodeStatistics(TInstant now) {
- TInstant barierTime = now - Hive.GetNodeRestartWatchPeriod();
- Hive.ActualizeRestartStatistics(*Statistics.MutableRestartTimestamp(), barierTime.MilliSeconds());
-}
-
-TString TNodeInfo::GetLogPrefix() const {
- return Hive.GetLogPrefix();
-}
-
-} // NHive
-} // NKikimr
+ BLOG_D("Node(" << Id << ") Reconnect(" << local << ")");
+ Hive.SendReconnect(local);
+}
+
+void TNodeInfo::SetDown(bool down) {
+ Down = down;
+ if (!Down) {
+ Hive.ProcessWaitQueue();
+ }
+}
+
+void TNodeInfo::SetFreeze(bool freeze) {
+ Freeze = freeze;
+ if (!Freeze) {
+ Hive.ProcessWaitQueue();
+ }
+}
+
+void TNodeInfo::UpdateResourceMaximum(const NKikimrTabletBase::TMetrics& metrics) {
+ auto oldNormalizedValues = NormalizeRawValues(ResourceValues, ResourceMaximumValues);
+ if (metrics.HasCPU()) {
+ std::get<NMetrics::EResource::CPU>(ResourceMaximumValues) = metrics.GetCPU();
+ }
+ if (metrics.HasMemory()) {
+ std::get<NMetrics::EResource::Memory>(ResourceMaximumValues) = metrics.GetMemory();
+ }
+ if (metrics.HasNetwork()) {
+ std::get<NMetrics::EResource::Network>(ResourceMaximumValues) = metrics.GetNetwork();
+ }
+ auto normalizedValues = NormalizeRawValues(ResourceValues, ResourceMaximumValues);
+ Hive.UpdateTotalResourceValues(nullptr, nullptr, NKikimrTabletBase::TMetrics(), NKikimrTabletBase::TMetrics(), {}, normalizedValues - oldNormalizedValues);
+}
+
+double TNodeInfo::GetNodeUsageForTablet(const TTabletInfo& tablet) const {
+ // what it would like when tablet will run on this node?
+ TResourceRawValues nodeValues = GetResourceCurrentValues();
+ TResourceRawValues tabletValues = tablet.GetResourceCurrentValues();
+ tablet.FilterRawValues(nodeValues);
+ tablet.FilterRawValues(tabletValues);
+ auto current = tablet.IsAliveOnLocal(Local) ? nodeValues : nodeValues + tabletValues;
+ auto maximum = GetResourceMaximumValues();
+ // basically, this is: return max(a / b);
+ double usage = TTabletInfo::GetUsage(current, maximum);
+ if (Hive.GetSpreadNeighbours() && usage < 1) {
+ auto neighbours = GetTabletNeighboursCount(tablet);
+ if (neighbours > 0) {
+ auto remain = 1 - usage;
+ auto cost = remain / (neighbours + 1);
+ usage += cost * neighbours; // n / (n + 1)
+ }
+ }
+ return usage;
+}
+
+double TNodeInfo::GetNodeUsage() const {
+ double usage = TTabletInfo::GetUsage(GetResourceCurrentValues(), GetResourceMaximumValues());
+ if (AveragedNodeTotalUsage.IsValueStable()) {
+ usage = std::max(usage, AveragedNodeTotalUsage.GetValue());
+ }
+ return usage;
+}
+
+ui64 TNodeInfo::GetTabletsRunningByType(TTabletTypes::EType tabletType) const {
+ auto itRunningByType = TabletsRunningByType.find(tabletType);
+ if (itRunningByType != TabletsRunningByType.end()) {
+ return itRunningByType->second.size();
+ }
+ return 0;
+}
+
+TResourceRawValues TNodeInfo::GetResourceInitialMaximumValues() {
+ return Hive.GetResourceInitialMaximumValues();
+}
+
+TResourceRawValues TNodeInfo::GetStDevResourceValues() {
+ TVector<TResourceRawValues> values;
+ const std::unordered_set<TTabletInfo*>& runningTablets = Tablets[TTabletInfo::EVolatileState::TABLET_VOLATILE_STATE_RUNNING];
+ values.reserve(runningTablets.size());
+ for (const TTabletInfo* tablet : runningTablets) {
+ values.push_back(tablet->GetResourceCurrentValues());
+ }
+ return GetStDev(values);
+}
+
+bool TNodeInfo::CanBeDeleted() const {
+ TInstant lastAlive(TInstant::MilliSeconds(Statistics.GetLastAliveTimestamp()));
+ if (lastAlive) {
+ return (IsDisconnected() || IsUnknown())
+ && !Local
+ && GetTabletsTotal() == 0
+ && LockedTablets.empty()
+ && !Freeze
+ && (lastAlive + Hive.GetNodeDeletePeriod() < TInstant::Now());
+ } else {
+ return (IsDisconnected() || IsUnknown()) && !Local && GetTabletsTotal() == 0 && LockedTablets.empty() && !Freeze;
+ }
+}
+
+void TNodeInfo::UpdateResourceTotalUsage(const NKikimrHive::TEvTabletMetrics& metrics) {
+ if (metrics.HasTotalResourceUsage()) {
+ AveragedResourceTotalValues.Push(ResourceRawValuesFromMetrics(metrics.GetTotalResourceUsage()));
+ ResourceTotalValues = AveragedResourceTotalValues.GetValue();
+ }
+ if (metrics.HasTotalNodeUsage()) {
+ AveragedNodeTotalUsage.Push(metrics.GetTotalNodeUsage());
+ NodeTotalUsage = AveragedNodeTotalUsage.GetValue();
+ }
+}
+
+TResourceRawValues TNodeInfo::GetResourceCurrentValues() const {
+ if (AveragedResourceTotalValues.IsValueStable()) {
+ return piecewise_max(ResourceValues, ResourceTotalValues);
+ } else {
+ return ResourceValues;
+ }
+}
+
+void TNodeInfo::ActualizeNodeStatistics(TInstant now) {
+ TInstant barierTime = now - Hive.GetNodeRestartWatchPeriod();
+ Hive.ActualizeRestartStatistics(*Statistics.MutableRestartTimestamp(), barierTime.MilliSeconds());
+}
+
+TString TNodeInfo::GetLogPrefix() const {
+ return Hive.GetLogPrefix();
+}
+
+} // NHive
+} // NKikimr
diff --git a/ydb/core/mind/hive/node_info.h b/ydb/core/mind/hive/node_info.h
index ed6c5abc605..fa7400fd25b 100644
--- a/ydb/core/mind/hive/node_info.h
+++ b/ydb/core/mind/hive/node_info.h
@@ -1,255 +1,255 @@
-#pragma once
-
-#include "hive.h"
-#include "tablet_info.h"
-
-namespace NKikimr {
-namespace NHive {
-
-struct TTabletInfo;
-
-struct TNodeInfo {
- enum class EVolatileState {
- Unknown,
- Disconnected,
- Connecting,
- Connected,
- Disconnecting,
- };
-
- static TString EVolatileStateName(EVolatileState value) {
- switch(value) {
- case EVolatileState::Unknown: return "Unknown";
- case EVolatileState::Disconnected: return "Disconnected";
- case EVolatileState::Connecting: return "Connecting";
- case EVolatileState::Connected: return "Connected";
- case EVolatileState::Disconnecting: return "Disconnecting";
- default: return Sprintf("%d", static_cast<int>(value));
- }
- }
-
-protected:
- EVolatileState VolatileState;
-
-public:
- THive& Hive;
- TNodeId Id;
+#pragma once
+
+#include "hive.h"
+#include "tablet_info.h"
+
+namespace NKikimr {
+namespace NHive {
+
+struct TTabletInfo;
+
+struct TNodeInfo {
+ enum class EVolatileState {
+ Unknown,
+ Disconnected,
+ Connecting,
+ Connected,
+ Disconnecting,
+ };
+
+ static TString EVolatileStateName(EVolatileState value) {
+ switch(value) {
+ case EVolatileState::Unknown: return "Unknown";
+ case EVolatileState::Disconnected: return "Disconnected";
+ case EVolatileState::Connecting: return "Connecting";
+ case EVolatileState::Connected: return "Connected";
+ case EVolatileState::Disconnecting: return "Disconnecting";
+ default: return Sprintf("%d", static_cast<int>(value));
+ }
+ }
+
+protected:
+ EVolatileState VolatileState;
+
+public:
+ THive& Hive;
+ TNodeId Id;
TActorId Local;
- bool Down;
- bool Freeze;
- bool Drain;
- TVector<TActorId> DrainInitiators;
- TDrainSettings DrainSettings;
- std::unordered_map<TTabletInfo::EVolatileState, std::unordered_set<TTabletInfo*>> Tablets;
- std::unordered_map<TTabletTypes::EType, std::unordered_set<TTabletInfo*>> TabletsRunningByType;
- std::unordered_map<TObjectId, std::unordered_set<TTabletInfo*>> TabletsOfObject;
- TResourceRawValues ResourceValues; // accumulated resources from tablet metrics
- TResourceRawValues ResourceTotalValues; // actual used resources from the node (should be greater or equal one above)
- NMetrics::TAverageValue<TResourceRawValues, 20> AveragedResourceTotalValues;
- double NodeTotalUsage = 0;
- NMetrics::TFastRiseAverageValue<double, 20> AveragedNodeTotalUsage;
- TResourceRawValues ResourceMaximumValues;
- TInstant StartTime;
+ bool Down;
+ bool Freeze;
+ bool Drain;
+ TVector<TActorId> DrainInitiators;
+ TDrainSettings DrainSettings;
+ std::unordered_map<TTabletInfo::EVolatileState, std::unordered_set<TTabletInfo*>> Tablets;
+ std::unordered_map<TTabletTypes::EType, std::unordered_set<TTabletInfo*>> TabletsRunningByType;
+ std::unordered_map<TObjectId, std::unordered_set<TTabletInfo*>> TabletsOfObject;
+ TResourceRawValues ResourceValues; // accumulated resources from tablet metrics
+ TResourceRawValues ResourceTotalValues; // actual used resources from the node (should be greater or equal one above)
+ NMetrics::TAverageValue<TResourceRawValues, 20> AveragedResourceTotalValues;
+ double NodeTotalUsage = 0;
+ NMetrics::TFastRiseAverageValue<double, 20> AveragedNodeTotalUsage;
+ TResourceRawValues ResourceMaximumValues;
+ TInstant StartTime;
TNodeLocation Location;
bool LocationAcquired;
- std::unordered_map<TTabletTypes::EType, NKikimrLocal::TTabletAvailability> TabletAvailability;
- TVector<TSubDomainKey> ServicedDomains;
- TVector<TSubDomainKey> LastSeenServicedDomains;
- TVector<TActorId> PipeServers;
+ std::unordered_map<TTabletTypes::EType, NKikimrLocal::TTabletAvailability> TabletAvailability;
+ TVector<TSubDomainKey> ServicedDomains;
+ TVector<TSubDomainKey> LastSeenServicedDomains;
+ TVector<TActorId> PipeServers;
THashSet<TLeaderTabletInfo*> LockedTablets;
- mutable TInstant LastResourceChangeReaction;
- NKikimrHive::TNodeStatistics Statistics;
-
- TNodeInfo(TNodeId nodeId, THive& hive);
- TNodeInfo(const TNodeInfo&) = delete;
- TNodeInfo(TNodeInfo&&) = delete;
- TNodeInfo& operator =(const TNodeInfo&) = delete;
- TNodeInfo& operator =(TNodeInfo&&) = delete;
-
- TString GetLogPrefix() const;
-
- EVolatileState GetVolatileState() const {
- return VolatileState;
- }
-
- void ChangeVolatileState(EVolatileState state);
-
- static bool IsResourceDrainingState(TTabletInfo::EVolatileState state) {
- switch (state) {
- case TTabletInfo::EVolatileState::TABLET_VOLATILE_STATE_STARTING:
- case TTabletInfo::EVolatileState::TABLET_VOLATILE_STATE_RUNNING:
- case TTabletInfo::EVolatileState::TABLET_VOLATILE_STATE_UNKNOWN:
- return true;
- default:
- return false;
- }
- }
-
- static bool IsAliveState(TTabletInfo::EVolatileState state) {
- switch (state) {
- case TTabletInfo::EVolatileState::TABLET_VOLATILE_STATE_STARTING:
- case TTabletInfo::EVolatileState::TABLET_VOLATILE_STATE_RUNNING:
- return true;
- default:
- return false;
- }
- }
-
- bool OnTabletChangeVolatileState(TTabletInfo* tablet, TTabletInfo::EVolatileState newState);
- void UpdateResourceValues(const TTabletInfo* tablet, const NKikimrTabletBase::TMetrics& before, const NKikimrTabletBase::TMetrics& after);
-
- ui32 GetTabletsScheduled() const {
- auto it = Tablets.find(TTabletInfo::EVolatileState::TABLET_VOLATILE_STATE_STARTING);
- if (it != Tablets.end())
- return it->second.size();
- return 0;
- }
-
- ui32 GetTabletsTotal() const {
- ui32 totalSize = 0;
- for (const auto& t : Tablets) {
- totalSize += t.second.size();
- }
- return totalSize;
- }
-
- ui32 GetTabletNeighboursCount(const TTabletInfo& tablet) const {
- auto it = TabletsOfObject.find(tablet.GetObjectId());
- if (it != TabletsOfObject.end()) {
- return it->second.size();
- } else {
- return 0;
- }
- }
-
- bool IsUnknown() const {
- return VolatileState == EVolatileState::Unknown;
- }
-
- bool IsAlive() const {
- return VolatileState == EVolatileState::Connected && (bool)Local;
- }
-
- bool IsRegistered() const {
- return VolatileState == EVolatileState::Connecting || VolatileState == EVolatileState::Connected;
- }
-
- bool IsAllowedToRunTablet(TTabletDebugState* debugState = nullptr) const;
- bool IsAllowedToRunTablet(const TTabletInfo& tablet, TTabletDebugState* debugState = nullptr) const;
- bool IsAbleToRunTablet(const TTabletInfo& tablet, TTabletDebugState* debugState = nullptr) const;
- ui64 GetMaxTabletsScheduled() const;
-
- bool IsAbleToScheduleTablet() const {
- return GetTabletsScheduled() < GetMaxTabletsScheduled();
- }
-
- bool IsDisconnecting() const {
- return VolatileState == EVolatileState::Disconnecting;
- }
-
- bool IsDisconnected() const {
- return VolatileState == EVolatileState::Disconnected;
- }
-
- bool IsOverloaded() const;
-
- TString DumpTablets() const {
- TStringStream stream;
- for (const auto& t : Tablets) {
- stream << TTabletInfo::EVolatileStateName(t.first) << ":\n";
- for (const auto& j : t.second) {
- stream << j->ToString() << " " << TTabletInfo::EVolatileStateName(j->GetVolatileState()) << '\n';
- }
- }
- return stream.Str();
- }
-
- bool BecomeConnecting() {
- if (VolatileState != EVolatileState::Connecting) {
- ChangeVolatileState(EVolatileState::Connecting);
- return true;
- } else {
- return false;
- }
- }
-
- bool BecomeConnected();
-
- bool BecomeDisconnected() {
- if (VolatileState != EVolatileState::Disconnected) {
- TVector<TTabletInfo*> TabletsToRestart;
- for (const auto& t : Tablets) {
- for (const auto& j : t.second) {
- TabletsToRestart.push_back(j);
- }
- }
- for (const auto& t : TabletsToRestart) {
- t->BecomeStopped();
- }
- Y_VERIFY(GetTabletsTotal() == 0, "%s", DumpTablets().data());
+ mutable TInstant LastResourceChangeReaction;
+ NKikimrHive::TNodeStatistics Statistics;
+
+ TNodeInfo(TNodeId nodeId, THive& hive);
+ TNodeInfo(const TNodeInfo&) = delete;
+ TNodeInfo(TNodeInfo&&) = delete;
+ TNodeInfo& operator =(const TNodeInfo&) = delete;
+ TNodeInfo& operator =(TNodeInfo&&) = delete;
+
+ TString GetLogPrefix() const;
+
+ EVolatileState GetVolatileState() const {
+ return VolatileState;
+ }
+
+ void ChangeVolatileState(EVolatileState state);
+
+ static bool IsResourceDrainingState(TTabletInfo::EVolatileState state) {
+ switch (state) {
+ case TTabletInfo::EVolatileState::TABLET_VOLATILE_STATE_STARTING:
+ case TTabletInfo::EVolatileState::TABLET_VOLATILE_STATE_RUNNING:
+ case TTabletInfo::EVolatileState::TABLET_VOLATILE_STATE_UNKNOWN:
+ return true;
+ default:
+ return false;
+ }
+ }
+
+ static bool IsAliveState(TTabletInfo::EVolatileState state) {
+ switch (state) {
+ case TTabletInfo::EVolatileState::TABLET_VOLATILE_STATE_STARTING:
+ case TTabletInfo::EVolatileState::TABLET_VOLATILE_STATE_RUNNING:
+ return true;
+ default:
+ return false;
+ }
+ }
+
+ bool OnTabletChangeVolatileState(TTabletInfo* tablet, TTabletInfo::EVolatileState newState);
+ void UpdateResourceValues(const TTabletInfo* tablet, const NKikimrTabletBase::TMetrics& before, const NKikimrTabletBase::TMetrics& after);
+
+ ui32 GetTabletsScheduled() const {
+ auto it = Tablets.find(TTabletInfo::EVolatileState::TABLET_VOLATILE_STATE_STARTING);
+ if (it != Tablets.end())
+ return it->second.size();
+ return 0;
+ }
+
+ ui32 GetTabletsTotal() const {
+ ui32 totalSize = 0;
+ for (const auto& t : Tablets) {
+ totalSize += t.second.size();
+ }
+ return totalSize;
+ }
+
+ ui32 GetTabletNeighboursCount(const TTabletInfo& tablet) const {
+ auto it = TabletsOfObject.find(tablet.GetObjectId());
+ if (it != TabletsOfObject.end()) {
+ return it->second.size();
+ } else {
+ return 0;
+ }
+ }
+
+ bool IsUnknown() const {
+ return VolatileState == EVolatileState::Unknown;
+ }
+
+ bool IsAlive() const {
+ return VolatileState == EVolatileState::Connected && (bool)Local;
+ }
+
+ bool IsRegistered() const {
+ return VolatileState == EVolatileState::Connecting || VolatileState == EVolatileState::Connected;
+ }
+
+ bool IsAllowedToRunTablet(TTabletDebugState* debugState = nullptr) const;
+ bool IsAllowedToRunTablet(const TTabletInfo& tablet, TTabletDebugState* debugState = nullptr) const;
+ bool IsAbleToRunTablet(const TTabletInfo& tablet, TTabletDebugState* debugState = nullptr) const;
+ ui64 GetMaxTabletsScheduled() const;
+
+ bool IsAbleToScheduleTablet() const {
+ return GetTabletsScheduled() < GetMaxTabletsScheduled();
+ }
+
+ bool IsDisconnecting() const {
+ return VolatileState == EVolatileState::Disconnecting;
+ }
+
+ bool IsDisconnected() const {
+ return VolatileState == EVolatileState::Disconnected;
+ }
+
+ bool IsOverloaded() const;
+
+ TString DumpTablets() const {
+ TStringStream stream;
+ for (const auto& t : Tablets) {
+ stream << TTabletInfo::EVolatileStateName(t.first) << ":\n";
+ for (const auto& j : t.second) {
+ stream << j->ToString() << " " << TTabletInfo::EVolatileStateName(j->GetVolatileState()) << '\n';
+ }
+ }
+ return stream.Str();
+ }
+
+ bool BecomeConnecting() {
+ if (VolatileState != EVolatileState::Connecting) {
+ ChangeVolatileState(EVolatileState::Connecting);
+ return true;
+ } else {
+ return false;
+ }
+ }
+
+ bool BecomeConnected();
+
+ bool BecomeDisconnected() {
+ if (VolatileState != EVolatileState::Disconnected) {
+ TVector<TTabletInfo*> TabletsToRestart;
+ for (const auto& t : Tablets) {
+ for (const auto& j : t.second) {
+ TabletsToRestart.push_back(j);
+ }
+ }
+ for (const auto& t : TabletsToRestart) {
+ t->BecomeStopped();
+ }
+ Y_VERIFY(GetTabletsTotal() == 0, "%s", DumpTablets().data());
Local = TActorId();
- ChangeVolatileState(EVolatileState::Disconnected);
- for (TTabletInfo* tablet : TabletsToRestart) {
- if (tablet->IsReadyToBoot()) {
- tablet->InitiateBoot();
- }
- }
- return true;
- }
- return false;
- }
-
- bool BecomeDisconnecting() {
- if (VolatileState == EVolatileState::Connected) {
- ChangeVolatileState(EVolatileState::Disconnecting);
- return true;
- } else {
- return false;
- }
- }
-
- bool CanBeDeleted() const;
- void RegisterInDomains();
- void DeregisterInDomains();
- void Ping();
+ ChangeVolatileState(EVolatileState::Disconnected);
+ for (TTabletInfo* tablet : TabletsToRestart) {
+ if (tablet->IsReadyToBoot()) {
+ tablet->InitiateBoot();
+ }
+ }
+ return true;
+ }
+ return false;
+ }
+
+ bool BecomeDisconnecting() {
+ if (VolatileState == EVolatileState::Connected) {
+ ChangeVolatileState(EVolatileState::Disconnecting);
+ return true;
+ } else {
+ return false;
+ }
+ }
+
+ bool CanBeDeleted() const;
+ void RegisterInDomains();
+ void DeregisterInDomains();
+ void Ping();
void SendReconnect(const TActorId& local);
- void SetDown(bool down);
- void SetFreeze(bool freeze);
- void UpdateResourceMaximum(const NKikimrTabletBase::TMetrics& metrics);
-
- TResourceRawValues GetResourceCurrentValues() const;
-
- const TResourceRawValues& GetResourceMaximumValues() const {
- return ResourceMaximumValues;
- }
-
- double GetNodeUsageForTablet(const TTabletInfo& tablet) const;
- double GetNodeUsage() const;
-
- ui64 GetTabletsRunningByType(TTabletTypes::EType tabletType) const;
-
- TResourceRawValues GetResourceInitialMaximumValues();
- TResourceRawValues GetStDevResourceValues();
-
- TDuration GetUptime() const {
- return TInstant::Now() - StartTime;
- }
-
- TString DebugServicedDomains() const {
- return TStringBuilder() << ServicedDomains;
- }
-
- TSubDomainKey GetServicedDomain() const {
- return ServicedDomains.empty() ? TSubDomainKey() : ServicedDomains.front();
- }
-
- void UpdateResourceTotalUsage(const NKikimrHive::TEvTabletMetrics& metrics);
- void ActualizeNodeStatistics(TInstant now);
-
- TDataCenterId GetDataCenter() const {
+ void SetDown(bool down);
+ void SetFreeze(bool freeze);
+ void UpdateResourceMaximum(const NKikimrTabletBase::TMetrics& metrics);
+
+ TResourceRawValues GetResourceCurrentValues() const;
+
+ const TResourceRawValues& GetResourceMaximumValues() const {
+ return ResourceMaximumValues;
+ }
+
+ double GetNodeUsageForTablet(const TTabletInfo& tablet) const;
+ double GetNodeUsage() const;
+
+ ui64 GetTabletsRunningByType(TTabletTypes::EType tabletType) const;
+
+ TResourceRawValues GetResourceInitialMaximumValues();
+ TResourceRawValues GetStDevResourceValues();
+
+ TDuration GetUptime() const {
+ return TInstant::Now() - StartTime;
+ }
+
+ TString DebugServicedDomains() const {
+ return TStringBuilder() << ServicedDomains;
+ }
+
+ TSubDomainKey GetServicedDomain() const {
+ return ServicedDomains.empty() ? TSubDomainKey() : ServicedDomains.front();
+ }
+
+ void UpdateResourceTotalUsage(const NKikimrHive::TEvTabletMetrics& metrics);
+ void ActualizeNodeStatistics(TInstant now);
+
+ TDataCenterId GetDataCenter() const {
return Location.GetDataCenterId();
- }
-};
-
-} // NHive
-} // NKikimr
+ }
+};
+
+} // NHive
+} // NKikimr
diff --git a/ydb/core/mind/hive/sequencer.cpp b/ydb/core/mind/hive/sequencer.cpp
index 7fce649e9aa..7682a4d514f 100644
--- a/ydb/core/mind/hive/sequencer.cpp
+++ b/ydb/core/mind/hive/sequencer.cpp
@@ -1,180 +1,180 @@
-
-#include "sequencer.h"
-
-namespace NKikimr {
-namespace NHive {
-
-TSequencer::TSequence TSequencer::NO_SEQUENCE;
-
-bool TSequenceGenerator::AddFreeSequence(TOwnerType owner, TSequencer::TSequence sequence) {
- Y_VERIFY(sequence.Begin != NO_ELEMENT);
- auto [it, inserted] = SequenceByOwner.emplace(owner, sequence);
- if (inserted) {
- if (!sequence.Empty()) {
- FreeSequences.emplace_back(owner);
- }
- ++FreeSequencesIndex;
- }
- return inserted;
-}
-
-void TSequenceGenerator::AddAllocatedSequence(TOwnerType owner, TSequence sequence) {
- Y_VERIFY(owner.first != NO_OWNER);
- Y_VERIFY(sequence.Begin != NO_ELEMENT);
- {
- auto [it, inserted] = AllocatedSequences.emplace(sequence, owner);
- Y_VERIFY(inserted);
- }
- {
- auto [it, inserted] = SequenceByOwner.emplace(owner, sequence);
- Y_VERIFY(inserted);
- }
-}
-
-bool TSequenceGenerator::AddSequence(TOwnerType owner, TSequence sequence) {
- if (owner.first == NO_OWNER) {
- return AddFreeSequence(owner, sequence);
- } else {
- AddAllocatedSequence(owner, sequence);
- return true;
- }
-}
-
-TSequencer::TElementType TSequenceGenerator::AllocateElement(std::vector<TOwnerType>& modified) {
- return AllocateSequence({NO_OWNER, NO_ELEMENT}, 1, modified).GetNext();
-}
-
-TSequencer::TSequence TSequenceGenerator::AllocateSequence(TSequencer::TOwnerType owner, size_t size, std::vector<TOwnerType>& modified) {
- if (size > 1) {
- Y_VERIFY(owner.first != NO_OWNER);
- auto it = SequenceByOwner.find(owner);
- if (it != SequenceByOwner.end()) {
- return it->second;
- }
- }
- if (FreeSequences.empty()) {
- return NO_SEQUENCE;
- }
- TOwnerType freeOwner = FreeSequences.front();
- auto itSequence = SequenceByOwner.find(freeOwner);
- if (itSequence == SequenceByOwner.end()) {
- return NO_SEQUENCE;
- }
- TSequence result = itSequence->second.BiteOff(size);
- if (itSequence->second.Empty()) {
- FreeSequences.pop_front();
- }
- if (size > 1) {
- AddAllocatedSequence(owner, result);
- modified.emplace_back(owner);
- }
- modified.emplace_back(freeOwner);
- return result;
-}
-
-TSequencer::TSequence TSequenceGenerator::GetSequence(TSequencer::TOwnerType owner) {
- auto it = SequenceByOwner.find(owner);
- if (it != SequenceByOwner.end()) {
- return it->second;
- } else {
- return NO_SEQUENCE;
- }
-}
-
-TSequencer::TOwnerType TSequenceGenerator::GetOwner(TSequencer::TElementType element) {
- auto it = AllocatedSequences.lower_bound(element);
- if (it != AllocatedSequences.end()) {
- // check for "equal"
- if (it->first.Contains(element)) {
- return it->second;
- }
- }
- if (it != AllocatedSequences.begin()) {
- --it;
- if (it->first.Contains(element)) {
- return it->second;
- }
- }
-
- return {NO_OWNER, 0};
-}
-
-size_t TSequenceGenerator::FreeSize() const {
- size_t size = 0;
- for (const auto& owner : FreeSequences) {
- auto itSeq = SequenceByOwner.find(owner);
- if (itSeq != SequenceByOwner.end()) {
- size += itSeq->second.Size();
- }
- }
- return size;
-}
-
-size_t TSequenceGenerator::AllocatedSequencesSize() const {
- size_t size = 0;
- for (const auto& [seq, owner] : AllocatedSequences) {
- size += seq.Size();
- }
- return size;
-}
-
-size_t TSequenceGenerator::AllocatedSequencesCount() const {
- return AllocatedSequences.size();
-}
-
-size_t TSequenceGenerator::NextFreeSequenceIndex() const {
- return FreeSequencesIndex;
-}
-
-TSequencer::TElementType TSequenceGenerator::GetNextElement() const {
- if (FreeSequences.empty()) {
- return NO_ELEMENT;
- }
- TOwnerType freeOwner = FreeSequences.front();
- auto itSequence = SequenceByOwner.find(freeOwner);
- if (itSequence == SequenceByOwner.end()) {
- return NO_ELEMENT;
- }
- return itSequence->second.GetNext();
-}
-
-void TSequenceGenerator::Clear() {
- SequenceByOwner.clear();
- AllocatedSequences.clear();
- FreeSequences.clear();
- FreeSequencesIndex = 0;
-}
-
-void TOwnershipKeeper::AddOwnedSequence(TOwnerType owner, TSequence sequence) {
- Y_VERIFY(owner != NO_OWNER);
- Y_VERIFY(sequence.Begin != NO_ELEMENT);
- {
- auto [it, inserted] = OwnedSequences.emplace(sequence, owner);
- Y_VERIFY(inserted || it->second == owner);
- }
-}
-
-TOwnershipKeeper::TOwnerType TOwnershipKeeper::GetOwner(TSequencer::TElementType element) {
- auto it = OwnedSequences.lower_bound(element);
- if (it != OwnedSequences.end()) {
- // check for "equal"
- if (it->first.Contains(element)) {
- return it->second;
- }
- }
- if (it != OwnedSequences.begin()) {
- --it;
- if (it->first.Contains(element)) {
- return it->second;
- }
- }
-
- return NO_OWNER;
-}
-
-void TOwnershipKeeper::Clear() {
- OwnedSequences.clear();
-}
-
-}
-}
+
+#include "sequencer.h"
+
+namespace NKikimr {
+namespace NHive {
+
+TSequencer::TSequence TSequencer::NO_SEQUENCE;
+
+bool TSequenceGenerator::AddFreeSequence(TOwnerType owner, TSequencer::TSequence sequence) {
+ Y_VERIFY(sequence.Begin != NO_ELEMENT);
+ auto [it, inserted] = SequenceByOwner.emplace(owner, sequence);
+ if (inserted) {
+ if (!sequence.Empty()) {
+ FreeSequences.emplace_back(owner);
+ }
+ ++FreeSequencesIndex;
+ }
+ return inserted;
+}
+
+void TSequenceGenerator::AddAllocatedSequence(TOwnerType owner, TSequence sequence) {
+ Y_VERIFY(owner.first != NO_OWNER);
+ Y_VERIFY(sequence.Begin != NO_ELEMENT);
+ {
+ auto [it, inserted] = AllocatedSequences.emplace(sequence, owner);
+ Y_VERIFY(inserted);
+ }
+ {
+ auto [it, inserted] = SequenceByOwner.emplace(owner, sequence);
+ Y_VERIFY(inserted);
+ }
+}
+
+bool TSequenceGenerator::AddSequence(TOwnerType owner, TSequence sequence) {
+ if (owner.first == NO_OWNER) {
+ return AddFreeSequence(owner, sequence);
+ } else {
+ AddAllocatedSequence(owner, sequence);
+ return true;
+ }
+}
+
+TSequencer::TElementType TSequenceGenerator::AllocateElement(std::vector<TOwnerType>& modified) {
+ return AllocateSequence({NO_OWNER, NO_ELEMENT}, 1, modified).GetNext();
+}
+
+TSequencer::TSequence TSequenceGenerator::AllocateSequence(TSequencer::TOwnerType owner, size_t size, std::vector<TOwnerType>& modified) {
+ if (size > 1) {
+ Y_VERIFY(owner.first != NO_OWNER);
+ auto it = SequenceByOwner.find(owner);
+ if (it != SequenceByOwner.end()) {
+ return it->second;
+ }
+ }
+ if (FreeSequences.empty()) {
+ return NO_SEQUENCE;
+ }
+ TOwnerType freeOwner = FreeSequences.front();
+ auto itSequence = SequenceByOwner.find(freeOwner);
+ if (itSequence == SequenceByOwner.end()) {
+ return NO_SEQUENCE;
+ }
+ TSequence result = itSequence->second.BiteOff(size);
+ if (itSequence->second.Empty()) {
+ FreeSequences.pop_front();
+ }
+ if (size > 1) {
+ AddAllocatedSequence(owner, result);
+ modified.emplace_back(owner);
+ }
+ modified.emplace_back(freeOwner);
+ return result;
+}
+
+TSequencer::TSequence TSequenceGenerator::GetSequence(TSequencer::TOwnerType owner) {
+ auto it = SequenceByOwner.find(owner);
+ if (it != SequenceByOwner.end()) {
+ return it->second;
+ } else {
+ return NO_SEQUENCE;
+ }
+}
+
+TSequencer::TOwnerType TSequenceGenerator::GetOwner(TSequencer::TElementType element) {
+ auto it = AllocatedSequences.lower_bound(element);
+ if (it != AllocatedSequences.end()) {
+ // check for "equal"
+ if (it->first.Contains(element)) {
+ return it->second;
+ }
+ }
+ if (it != AllocatedSequences.begin()) {
+ --it;
+ if (it->first.Contains(element)) {
+ return it->second;
+ }
+ }
+
+ return {NO_OWNER, 0};
+}
+
+size_t TSequenceGenerator::FreeSize() const {
+ size_t size = 0;
+ for (const auto& owner : FreeSequences) {
+ auto itSeq = SequenceByOwner.find(owner);
+ if (itSeq != SequenceByOwner.end()) {
+ size += itSeq->second.Size();
+ }
+ }
+ return size;
+}
+
+size_t TSequenceGenerator::AllocatedSequencesSize() const {
+ size_t size = 0;
+ for (const auto& [seq, owner] : AllocatedSequences) {
+ size += seq.Size();
+ }
+ return size;
+}
+
+size_t TSequenceGenerator::AllocatedSequencesCount() const {
+ return AllocatedSequences.size();
+}
+
+size_t TSequenceGenerator::NextFreeSequenceIndex() const {
+ return FreeSequencesIndex;
+}
+
+TSequencer::TElementType TSequenceGenerator::GetNextElement() const {
+ if (FreeSequences.empty()) {
+ return NO_ELEMENT;
+ }
+ TOwnerType freeOwner = FreeSequences.front();
+ auto itSequence = SequenceByOwner.find(freeOwner);
+ if (itSequence == SequenceByOwner.end()) {
+ return NO_ELEMENT;
+ }
+ return itSequence->second.GetNext();
+}
+
+void TSequenceGenerator::Clear() {
+ SequenceByOwner.clear();
+ AllocatedSequences.clear();
+ FreeSequences.clear();
+ FreeSequencesIndex = 0;
+}
+
+void TOwnershipKeeper::AddOwnedSequence(TOwnerType owner, TSequence sequence) {
+ Y_VERIFY(owner != NO_OWNER);
+ Y_VERIFY(sequence.Begin != NO_ELEMENT);
+ {
+ auto [it, inserted] = OwnedSequences.emplace(sequence, owner);
+ Y_VERIFY(inserted || it->second == owner);
+ }
+}
+
+TOwnershipKeeper::TOwnerType TOwnershipKeeper::GetOwner(TSequencer::TElementType element) {
+ auto it = OwnedSequences.lower_bound(element);
+ if (it != OwnedSequences.end()) {
+ // check for "equal"
+ if (it->first.Contains(element)) {
+ return it->second;
+ }
+ }
+ if (it != OwnedSequences.begin()) {
+ --it;
+ if (it->first.Contains(element)) {
+ return it->second;
+ }
+ }
+
+ return NO_OWNER;
+}
+
+void TOwnershipKeeper::Clear() {
+ OwnedSequences.clear();
+}
+
+}
+}
diff --git a/ydb/core/mind/hive/sequencer.h b/ydb/core/mind/hive/sequencer.h
index 6cc4fe3d997..3780c84dd6a 100644
--- a/ydb/core/mind/hive/sequencer.h
+++ b/ydb/core/mind/hive/sequencer.h
@@ -1,133 +1,133 @@
-#pragma once
-
+#pragma once
+
#include <ydb/core/mind/defs.h>
#include <ydb/core/util/tuples.h>
-#include <map>
-#include <list>
-#include <utility>
-
-namespace NKikimr {
-namespace NHive {
-
-class TSequencer {
-public:
- using TElementType = ui64;
- using TOwnerType = std::pair<ui64, ui64>;
-
- struct TSequence {
- TElementType Begin = 0;
- TElementType Next = 0;
- TElementType End = 0;
-
- constexpr TSequence(TElementType begin, TElementType next, TElementType end)
- : Begin(begin)
- , Next(next)
- , End(end)
- {
- }
-
- constexpr TSequence(TElementType begin, TElementType end)
- : Begin(begin)
- , Next(begin)
- , End(end)
- {
- }
-
- constexpr TSequence(TElementType point)
- : Begin(point)
- , Next(point + 1)
- , End(point + 1)
- {
- }
-
- constexpr TSequence()
- : Begin(0)
- , Next(0)
- , End(0)
- {
- }
-
- bool operator <(TSequence sequence) const {
- return Begin < sequence.Begin;
- }
-
- bool operator ==(TSequence sequence) const {
- return Begin == sequence.Begin && End == sequence.End;
- }
-
- bool operator !=(TSequence sequence) const {
- return !(operator ==(sequence));
- }
-
- TSequence BiteOff(size_t size) {
- size = Min(size, Size());
- TSequence result(Next, Next, Next + size);
- Next += size;
- return result;
- }
-
- size_t Size() const {
- return End - Next;
- }
-
- bool Empty() const {
- return Next == End;
- }
-
- bool Contains(TElementType element) const {
- return element >= Begin && element < End;
- }
-
- void Clear() {
- Begin = End = Next = 0;
- }
-
- TElementType GetNext() const {
- return Next;
- }
- };
-
- static constexpr TElementType NO_ELEMENT = {};
- static constexpr TElementType NO_OWNER = {};
- static TSequence NO_SEQUENCE;
-};
-
-// to generate sequences/elements from another
-class TSequenceGenerator : public TSequencer {
-public:
- bool AddFreeSequence(TOwnerType owner, TSequence sequence); // free elements, which we could use to allocate from
- void AddAllocatedSequence(TOwnerType owner, TSequence sequence); // allocated elements by other owners
- bool AddSequence(TOwnerType owner, TSequence sequence);
- TElementType AllocateElement(std::vector<TOwnerType>& modified);
- TSequence AllocateSequence(TOwnerType owner, size_t size, std::vector<TOwnerType>& modified); // size = max possible size, but not exact size
- TSequence GetSequence(TOwnerType owner);
- TOwnerType GetOwner(TElementType element); // for unit tests only
- size_t FreeSize() const; // for unit tests only
- size_t AllocatedSequencesSize() const;
- size_t AllocatedSequencesCount() const;
- size_t NextFreeSequenceIndex() const;
- TElementType GetNextElement() const;
- void Clear();
-
-protected:
- std::unordered_map<TOwnerType, TSequence> SequenceByOwner;
- std::map<TSequence, TOwnerType> AllocatedSequences;
- std::list<TOwnerType> FreeSequences;
- size_t FreeSequencesIndex = 0;
-};
-
-// to keep ownership of sequences
-class TOwnershipKeeper : public TSequencer {
-public:
- using TOwnerType = TElementType;
-
- void AddOwnedSequence(TOwnerType owner, TSequence sequence); // all sequence range we owns, free and used, including allocated by the others
- TOwnerType GetOwner(TElementType element);
- void Clear();
-
-protected:
- std::map<TSequence, TOwnerType> OwnedSequences;
-};
-
-}
-}
+#include <map>
+#include <list>
+#include <utility>
+
+namespace NKikimr {
+namespace NHive {
+
+class TSequencer {
+public:
+ using TElementType = ui64;
+ using TOwnerType = std::pair<ui64, ui64>;
+
+ struct TSequence {
+ TElementType Begin = 0;
+ TElementType Next = 0;
+ TElementType End = 0;
+
+ constexpr TSequence(TElementType begin, TElementType next, TElementType end)
+ : Begin(begin)
+ , Next(next)
+ , End(end)
+ {
+ }
+
+ constexpr TSequence(TElementType begin, TElementType end)
+ : Begin(begin)
+ , Next(begin)
+ , End(end)
+ {
+ }
+
+ constexpr TSequence(TElementType point)
+ : Begin(point)
+ , Next(point + 1)
+ , End(point + 1)
+ {
+ }
+
+ constexpr TSequence()
+ : Begin(0)
+ , Next(0)
+ , End(0)
+ {
+ }
+
+ bool operator <(TSequence sequence) const {
+ return Begin < sequence.Begin;
+ }
+
+ bool operator ==(TSequence sequence) const {
+ return Begin == sequence.Begin && End == sequence.End;
+ }
+
+ bool operator !=(TSequence sequence) const {
+ return !(operator ==(sequence));
+ }
+
+ TSequence BiteOff(size_t size) {
+ size = Min(size, Size());
+ TSequence result(Next, Next, Next + size);
+ Next += size;
+ return result;
+ }
+
+ size_t Size() const {
+ return End - Next;
+ }
+
+ bool Empty() const {
+ return Next == End;
+ }
+
+ bool Contains(TElementType element) const {
+ return element >= Begin && element < End;
+ }
+
+ void Clear() {
+ Begin = End = Next = 0;
+ }
+
+ TElementType GetNext() const {
+ return Next;
+ }
+ };
+
+ static constexpr TElementType NO_ELEMENT = {};
+ static constexpr TElementType NO_OWNER = {};
+ static TSequence NO_SEQUENCE;
+};
+
+// to generate sequences/elements from another
+class TSequenceGenerator : public TSequencer {
+public:
+ bool AddFreeSequence(TOwnerType owner, TSequence sequence); // free elements, which we could use to allocate from
+ void AddAllocatedSequence(TOwnerType owner, TSequence sequence); // allocated elements by other owners
+ bool AddSequence(TOwnerType owner, TSequence sequence);
+ TElementType AllocateElement(std::vector<TOwnerType>& modified);
+ TSequence AllocateSequence(TOwnerType owner, size_t size, std::vector<TOwnerType>& modified); // size = max possible size, but not exact size
+ TSequence GetSequence(TOwnerType owner);
+ TOwnerType GetOwner(TElementType element); // for unit tests only
+ size_t FreeSize() const; // for unit tests only
+ size_t AllocatedSequencesSize() const;
+ size_t AllocatedSequencesCount() const;
+ size_t NextFreeSequenceIndex() const;
+ TElementType GetNextElement() const;
+ void Clear();
+
+protected:
+ std::unordered_map<TOwnerType, TSequence> SequenceByOwner;
+ std::map<TSequence, TOwnerType> AllocatedSequences;
+ std::list<TOwnerType> FreeSequences;
+ size_t FreeSequencesIndex = 0;
+};
+
+// to keep ownership of sequences
+class TOwnershipKeeper : public TSequencer {
+public:
+ using TOwnerType = TElementType;
+
+ void AddOwnedSequence(TOwnerType owner, TSequence sequence); // all sequence range we owns, free and used, including allocated by the others
+ TOwnerType GetOwner(TElementType element);
+ void Clear();
+
+protected:
+ std::map<TSequence, TOwnerType> OwnedSequences;
+};
+
+}
+}
diff --git a/ydb/core/mind/hive/sequencer_ut.cpp b/ydb/core/mind/hive/sequencer_ut.cpp
index 9b9aa5c881e..513159c76f4 100644
--- a/ydb/core/mind/hive/sequencer_ut.cpp
+++ b/ydb/core/mind/hive/sequencer_ut.cpp
@@ -1,67 +1,67 @@
#include <library/cpp/testing/unittest/registar.h>
#include <library/cpp/testing/unittest/tests_data.h>
-#include "sequencer.h"
-
-using namespace NKikimr;
-using namespace NHive;
-
-Y_UNIT_TEST_SUITE(Sequencer) {
- Y_UNIT_TEST(Basic1) {
- TSequenceGenerator sequencer;
- std::vector<TSequencer::TOwnerType> modified;
-
- UNIT_ASSERT_VALUES_EQUAL(sequencer.FreeSize(), 0);
- sequencer.AddFreeSequence({TSequencer::NO_OWNER, 1}, {1000, 2400});
- UNIT_ASSERT_VALUES_EQUAL(sequencer.FreeSize(), 1400);
- sequencer.AddFreeSequence({TSequencer::NO_OWNER, 2}, {2450, 2500});
- UNIT_ASSERT_VALUES_EQUAL(sequencer.FreeSize(), 1450);
- sequencer.AddFreeSequence({TSequencer::NO_OWNER, 3}, {2400, 2450});
- UNIT_ASSERT_VALUES_EQUAL(sequencer.FreeSize(), 1500);
- auto owner1 = sequencer.GetOwner(1003);
- UNIT_ASSERT_EQUAL(owner1.first, TSequencer::NO_OWNER);
- auto result1 = sequencer.AllocateSequence({1, 1}, 10, modified); // 1500 - 10 = 1490
- UNIT_ASSERT_VALUES_EQUAL(result1.Begin, 1000);
- UNIT_ASSERT_VALUES_EQUAL(result1.Next, 1000);
- UNIT_ASSERT_VALUES_EQUAL(result1.End, 1010);
- UNIT_ASSERT_VALUES_EQUAL(result1.Size(), 10);
- UNIT_ASSERT_VALUES_EQUAL(sequencer.FreeSize(), 1490);
- UNIT_ASSERT_VALUES_EQUAL(sequencer.AllocatedSequencesSize(), 10);
- UNIT_ASSERT_VALUES_EQUAL(sequencer.AllocatedSequencesCount(), 1);
- auto owner2 = sequencer.GetOwner(1003);
- UNIT_ASSERT_EQUAL(owner2, TSequencer::TOwnerType(1, 1));
- auto result2 = sequencer.AllocateSequence({2, 2}, 1390, modified);
- UNIT_ASSERT_VALUES_EQUAL(result2.Begin, 1010);
- UNIT_ASSERT_VALUES_EQUAL(result2.Next, 1010);
- UNIT_ASSERT_VALUES_EQUAL(result2.End, 2400);
- UNIT_ASSERT_VALUES_EQUAL(result2.Size(), 1390);
- UNIT_ASSERT_VALUES_EQUAL(sequencer.FreeSize(), 100);
- UNIT_ASSERT_VALUES_EQUAL(sequencer.AllocatedSequencesSize(), 1400);
- UNIT_ASSERT_VALUES_EQUAL(sequencer.AllocatedSequencesCount(), 2);
- auto owner3 = sequencer.GetOwner(1013);
- UNIT_ASSERT_EQUAL(owner3, TSequencer::TOwnerType(2, 2));
- for (int i = 0; i < 50; ++i) {
- auto element = sequencer.AllocateElement(modified);
- UNIT_ASSERT(element != TSequencer::NO_ELEMENT);
- }
- UNIT_ASSERT_VALUES_EQUAL(sequencer.FreeSize(), 50);
- UNIT_ASSERT_VALUES_EQUAL(sequencer.AllocatedSequencesSize(), 1400);
- UNIT_ASSERT_VALUES_EQUAL(sequencer.AllocatedSequencesCount(), 2);
- for (int i = 0; i < 50; ++i) {
- auto element = sequencer.AllocateElement(modified);
- UNIT_ASSERT(element != TSequencer::NO_ELEMENT);
- }
- UNIT_ASSERT_VALUES_EQUAL(sequencer.FreeSize(), 0);
- UNIT_ASSERT_VALUES_EQUAL(sequencer.AllocatedSequencesSize(), 1400);
- UNIT_ASSERT_VALUES_EQUAL(sequencer.AllocatedSequencesCount(), 2);
- auto result3 = sequencer.AllocateSequence({4, 4}, 10, modified);
- UNIT_ASSERT_EQUAL(result3, TSequencer::NO_SEQUENCE);
- sequencer.AddFreeSequence({TSequencer::NO_OWNER, 4}, {2500, 2600});
- UNIT_ASSERT_VALUES_EQUAL(sequencer.FreeSize(), 100);
- auto result4 = sequencer.AllocateSequence({4, 4}, 10, modified);
- UNIT_ASSERT_VALUES_EQUAL(result4.Begin, 2500);
- UNIT_ASSERT_VALUES_EQUAL(result4.Size(), 10);
- UNIT_ASSERT_VALUES_EQUAL(sequencer.FreeSize(), 90);
- UNIT_ASSERT_VALUES_EQUAL(sequencer.AllocatedSequencesSize(), 1410);
- UNIT_ASSERT_VALUES_EQUAL(sequencer.AllocatedSequencesCount(), 3);
- }
-}
+#include "sequencer.h"
+
+using namespace NKikimr;
+using namespace NHive;
+
+Y_UNIT_TEST_SUITE(Sequencer) {
+ Y_UNIT_TEST(Basic1) {
+ TSequenceGenerator sequencer;
+ std::vector<TSequencer::TOwnerType> modified;
+
+ UNIT_ASSERT_VALUES_EQUAL(sequencer.FreeSize(), 0);
+ sequencer.AddFreeSequence({TSequencer::NO_OWNER, 1}, {1000, 2400});
+ UNIT_ASSERT_VALUES_EQUAL(sequencer.FreeSize(), 1400);
+ sequencer.AddFreeSequence({TSequencer::NO_OWNER, 2}, {2450, 2500});
+ UNIT_ASSERT_VALUES_EQUAL(sequencer.FreeSize(), 1450);
+ sequencer.AddFreeSequence({TSequencer::NO_OWNER, 3}, {2400, 2450});
+ UNIT_ASSERT_VALUES_EQUAL(sequencer.FreeSize(), 1500);
+ auto owner1 = sequencer.GetOwner(1003);
+ UNIT_ASSERT_EQUAL(owner1.first, TSequencer::NO_OWNER);
+ auto result1 = sequencer.AllocateSequence({1, 1}, 10, modified); // 1500 - 10 = 1490
+ UNIT_ASSERT_VALUES_EQUAL(result1.Begin, 1000);
+ UNIT_ASSERT_VALUES_EQUAL(result1.Next, 1000);
+ UNIT_ASSERT_VALUES_EQUAL(result1.End, 1010);
+ UNIT_ASSERT_VALUES_EQUAL(result1.Size(), 10);
+ UNIT_ASSERT_VALUES_EQUAL(sequencer.FreeSize(), 1490);
+ UNIT_ASSERT_VALUES_EQUAL(sequencer.AllocatedSequencesSize(), 10);
+ UNIT_ASSERT_VALUES_EQUAL(sequencer.AllocatedSequencesCount(), 1);
+ auto owner2 = sequencer.GetOwner(1003);
+ UNIT_ASSERT_EQUAL(owner2, TSequencer::TOwnerType(1, 1));
+ auto result2 = sequencer.AllocateSequence({2, 2}, 1390, modified);
+ UNIT_ASSERT_VALUES_EQUAL(result2.Begin, 1010);
+ UNIT_ASSERT_VALUES_EQUAL(result2.Next, 1010);
+ UNIT_ASSERT_VALUES_EQUAL(result2.End, 2400);
+ UNIT_ASSERT_VALUES_EQUAL(result2.Size(), 1390);
+ UNIT_ASSERT_VALUES_EQUAL(sequencer.FreeSize(), 100);
+ UNIT_ASSERT_VALUES_EQUAL(sequencer.AllocatedSequencesSize(), 1400);
+ UNIT_ASSERT_VALUES_EQUAL(sequencer.AllocatedSequencesCount(), 2);
+ auto owner3 = sequencer.GetOwner(1013);
+ UNIT_ASSERT_EQUAL(owner3, TSequencer::TOwnerType(2, 2));
+ for (int i = 0; i < 50; ++i) {
+ auto element = sequencer.AllocateElement(modified);
+ UNIT_ASSERT(element != TSequencer::NO_ELEMENT);
+ }
+ UNIT_ASSERT_VALUES_EQUAL(sequencer.FreeSize(), 50);
+ UNIT_ASSERT_VALUES_EQUAL(sequencer.AllocatedSequencesSize(), 1400);
+ UNIT_ASSERT_VALUES_EQUAL(sequencer.AllocatedSequencesCount(), 2);
+ for (int i = 0; i < 50; ++i) {
+ auto element = sequencer.AllocateElement(modified);
+ UNIT_ASSERT(element != TSequencer::NO_ELEMENT);
+ }
+ UNIT_ASSERT_VALUES_EQUAL(sequencer.FreeSize(), 0);
+ UNIT_ASSERT_VALUES_EQUAL(sequencer.AllocatedSequencesSize(), 1400);
+ UNIT_ASSERT_VALUES_EQUAL(sequencer.AllocatedSequencesCount(), 2);
+ auto result3 = sequencer.AllocateSequence({4, 4}, 10, modified);
+ UNIT_ASSERT_EQUAL(result3, TSequencer::NO_SEQUENCE);
+ sequencer.AddFreeSequence({TSequencer::NO_OWNER, 4}, {2500, 2600});
+ UNIT_ASSERT_VALUES_EQUAL(sequencer.FreeSize(), 100);
+ auto result4 = sequencer.AllocateSequence({4, 4}, 10, modified);
+ UNIT_ASSERT_VALUES_EQUAL(result4.Begin, 2500);
+ UNIT_ASSERT_VALUES_EQUAL(result4.Size(), 10);
+ UNIT_ASSERT_VALUES_EQUAL(sequencer.FreeSize(), 90);
+ UNIT_ASSERT_VALUES_EQUAL(sequencer.AllocatedSequencesSize(), 1410);
+ UNIT_ASSERT_VALUES_EQUAL(sequencer.AllocatedSequencesCount(), 3);
+ }
+}
diff --git a/ydb/core/mind/hive/storage_group_info.cpp b/ydb/core/mind/hive/storage_group_info.cpp
index b8b0fa73ff6..fbcb7fc7ba4 100644
--- a/ydb/core/mind/hive/storage_group_info.cpp
+++ b/ydb/core/mind/hive/storage_group_info.cpp
@@ -1,113 +1,113 @@
-#include "storage_group_info.h"
-#include "storage_pool_info.h"
-
-namespace NKikimr {
-namespace NHive {
-
-TStorageGroupInfo::TStorageGroupInfo(const TStoragePoolInfo& storagePool, TStorageGroupId id)
- : StoragePool(storagePool)
- , Id(id)
-{}
-
+#include "storage_group_info.h"
+#include "storage_pool_info.h"
+
+namespace NKikimr {
+namespace NHive {
+
+TStorageGroupInfo::TStorageGroupInfo(const TStoragePoolInfo& storagePool, TStorageGroupId id)
+ : StoragePool(storagePool)
+ , Id(id)
+{}
+
bool TStorageGroupInfo::AcquireAllocationUnit(const TLeaderTabletInfo* tablet, ui32 channel) {
- Y_VERIFY(tablet->BoundChannels.size() > channel);
+ Y_VERIFY(tablet->BoundChannels.size() > channel);
bool acquired = Units.insert({tablet, channel}).second;
if (acquired) {
- AcquiredIOPS += tablet->BoundChannels[channel].GetIOPS();
- AcquiredThroughput += tablet->BoundChannels[channel].GetThroughput();
- AcquiredSize += tablet->BoundChannels[channel].GetSize();
- }
+ AcquiredIOPS += tablet->BoundChannels[channel].GetIOPS();
+ AcquiredThroughput += tablet->BoundChannels[channel].GetThroughput();
+ AcquiredSize += tablet->BoundChannels[channel].GetSize();
+ }
return acquired;
-}
-
+}
+
bool TStorageGroupInfo::ReleaseAllocationUnit(const TLeaderTabletInfo* tablet, ui32 channel) {
- Y_VERIFY(tablet->BoundChannels.size() > channel);
- bool released = Units.erase({tablet, channel}) != 0;
- if (released) {
- AcquiredIOPS -= tablet->BoundChannels[channel].GetIOPS();
- AcquiredThroughput -= tablet->BoundChannels[channel].GetThroughput();
- AcquiredSize -= tablet->BoundChannels[channel].GetSize();
- }
- return released;
-}
-
-void TStorageGroupInfo::UpdateStorageGroup(const TEvControllerSelectGroupsResult::TGroupParameters& groupParameters) {
- if (groupParameters.GetAssuredResources().HasIOPS()) {
- MaximumIOPS = groupParameters.GetAssuredResources().GetIOPS();
- }
- if (groupParameters.GetAssuredResources().HasReadThroughput() || groupParameters.GetAssuredResources().HasWriteThroughput()) {
- MaximumThroughput = groupParameters.GetAssuredResources().GetReadThroughput() + groupParameters.GetAssuredResources().GetWriteThroughput();
- }
- if (groupParameters.GetAssuredResources().HasSpace()) {
- MaximumSize = groupParameters.GetAssuredResources().GetSpace();
- }
- GroupParameters.CopyFrom(groupParameters);
-}
-
-bool TStorageGroupInfo::IsMatchesParameters(const TEvControllerSelectGroups::TGroupParameters& groupParameters) const {
- if (groupParameters.GetStoragePoolSpecifier().GetName() != GroupParameters.GetStoragePoolName()) {
- return false;
- }
- if (StoragePool.GetSafeMode()) {
- return true;
- }
- if (IsBalanceByIOPS() && groupParameters.HasRequiredIOPS() && groupParameters.GetRequiredIOPS() + AcquiredIOPS > GetMaximumIOPS()) {
- return false;
- }
- if (IsBalanceByThroughput() && groupParameters.HasRequiredThroughput() && groupParameters.GetRequiredThroughput() + AcquiredThroughput > GetMaximumThroughput()) {
- return false;
- }
- if (IsBalanceBySize() && groupParameters.HasRequiredDataSize() && groupParameters.GetRequiredDataSize() + AcquiredSize > GetMaximumSize()) {
- return false;
- }
- return true;
-}
-
-double TStorageGroupInfo::GetUsage() const {
- double usage = 0;
- int countUsage = 0;
- if (IsBalanceByIOPS() && MaximumIOPS > 0) {
- usage = std::max<double>(usage, static_cast<double>(AcquiredIOPS) / GetMaximumIOPS());
- ++countUsage;
- }
- if (IsBalanceByThroughput() && MaximumThroughput > 0) {
- usage = std::max<double>(usage, static_cast<double>(AcquiredThroughput) / GetMaximumThroughput());
- ++countUsage;
- }
- if (IsBalanceBySize() && MaximumSize > 0) {
- usage = std::max<double>(usage, static_cast<double>(AcquiredSize) / GetMaximumSize());
- ++countUsage;
- }
- if (countUsage > 0) {
- return usage;
- } else {
- return 1.0;
- }
-}
-
-double TStorageGroupInfo::GetMaximumIOPS() const {
- return MaximumIOPS * StoragePool.GetOvercommitIOPS();
-}
-
-ui64 TStorageGroupInfo::GetMaximumThroughput() const {
- return MaximumThroughput * StoragePool.GetOvercommitThroughput();
-}
-
-ui64 TStorageGroupInfo::GetMaximumSize() const {
- return MaximumSize * StoragePool.GetOvercommitSize();
-}
-
-bool TStorageGroupInfo::IsBalanceByIOPS() const {
- return StoragePool.IsBalanceByIOPS();
-}
-
-bool TStorageGroupInfo::IsBalanceByThroughput() const {
- return StoragePool.IsBalanceByThroughput();
-}
-
-bool TStorageGroupInfo::IsBalanceBySize() const {
- return StoragePool.IsBalanceBySize();
-}
-
-}
-}
+ Y_VERIFY(tablet->BoundChannels.size() > channel);
+ bool released = Units.erase({tablet, channel}) != 0;
+ if (released) {
+ AcquiredIOPS -= tablet->BoundChannels[channel].GetIOPS();
+ AcquiredThroughput -= tablet->BoundChannels[channel].GetThroughput();
+ AcquiredSize -= tablet->BoundChannels[channel].GetSize();
+ }
+ return released;
+}
+
+void TStorageGroupInfo::UpdateStorageGroup(const TEvControllerSelectGroupsResult::TGroupParameters& groupParameters) {
+ if (groupParameters.GetAssuredResources().HasIOPS()) {
+ MaximumIOPS = groupParameters.GetAssuredResources().GetIOPS();
+ }
+ if (groupParameters.GetAssuredResources().HasReadThroughput() || groupParameters.GetAssuredResources().HasWriteThroughput()) {
+ MaximumThroughput = groupParameters.GetAssuredResources().GetReadThroughput() + groupParameters.GetAssuredResources().GetWriteThroughput();
+ }
+ if (groupParameters.GetAssuredResources().HasSpace()) {
+ MaximumSize = groupParameters.GetAssuredResources().GetSpace();
+ }
+ GroupParameters.CopyFrom(groupParameters);
+}
+
+bool TStorageGroupInfo::IsMatchesParameters(const TEvControllerSelectGroups::TGroupParameters& groupParameters) const {
+ if (groupParameters.GetStoragePoolSpecifier().GetName() != GroupParameters.GetStoragePoolName()) {
+ return false;
+ }
+ if (StoragePool.GetSafeMode()) {
+ return true;
+ }
+ if (IsBalanceByIOPS() && groupParameters.HasRequiredIOPS() && groupParameters.GetRequiredIOPS() + AcquiredIOPS > GetMaximumIOPS()) {
+ return false;
+ }
+ if (IsBalanceByThroughput() && groupParameters.HasRequiredThroughput() && groupParameters.GetRequiredThroughput() + AcquiredThroughput > GetMaximumThroughput()) {
+ return false;
+ }
+ if (IsBalanceBySize() && groupParameters.HasRequiredDataSize() && groupParameters.GetRequiredDataSize() + AcquiredSize > GetMaximumSize()) {
+ return false;
+ }
+ return true;
+}
+
+double TStorageGroupInfo::GetUsage() const {
+ double usage = 0;
+ int countUsage = 0;
+ if (IsBalanceByIOPS() && MaximumIOPS > 0) {
+ usage = std::max<double>(usage, static_cast<double>(AcquiredIOPS) / GetMaximumIOPS());
+ ++countUsage;
+ }
+ if (IsBalanceByThroughput() && MaximumThroughput > 0) {
+ usage = std::max<double>(usage, static_cast<double>(AcquiredThroughput) / GetMaximumThroughput());
+ ++countUsage;
+ }
+ if (IsBalanceBySize() && MaximumSize > 0) {
+ usage = std::max<double>(usage, static_cast<double>(AcquiredSize) / GetMaximumSize());
+ ++countUsage;
+ }
+ if (countUsage > 0) {
+ return usage;
+ } else {
+ return 1.0;
+ }
+}
+
+double TStorageGroupInfo::GetMaximumIOPS() const {
+ return MaximumIOPS * StoragePool.GetOvercommitIOPS();
+}
+
+ui64 TStorageGroupInfo::GetMaximumThroughput() const {
+ return MaximumThroughput * StoragePool.GetOvercommitThroughput();
+}
+
+ui64 TStorageGroupInfo::GetMaximumSize() const {
+ return MaximumSize * StoragePool.GetOvercommitSize();
+}
+
+bool TStorageGroupInfo::IsBalanceByIOPS() const {
+ return StoragePool.IsBalanceByIOPS();
+}
+
+bool TStorageGroupInfo::IsBalanceByThroughput() const {
+ return StoragePool.IsBalanceByThroughput();
+}
+
+bool TStorageGroupInfo::IsBalanceBySize() const {
+ return StoragePool.IsBalanceBySize();
+}
+
+}
+}
diff --git a/ydb/core/mind/hive/storage_group_info.h b/ydb/core/mind/hive/storage_group_info.h
index aa49ba13e9b..cbd7d976e2f 100644
--- a/ydb/core/mind/hive/storage_group_info.h
+++ b/ydb/core/mind/hive/storage_group_info.h
@@ -1,44 +1,44 @@
-#pragma once
-
-#include "hive.h"
+#pragma once
+
+#include "hive.h"
#include "leader_tablet_info.h"
-
-namespace NKikimr {
-namespace NHive {
-
-using namespace NKikimrBlobStorage;
-
-struct TStoragePoolInfo;
-
-struct TStorageGroupInfo {
- const TStoragePoolInfo& StoragePool;
- TStorageGroupId Id;
+
+namespace NKikimr {
+namespace NHive {
+
+using namespace NKikimrBlobStorage;
+
+struct TStoragePoolInfo;
+
+struct TStorageGroupInfo {
+ const TStoragePoolInfo& StoragePool;
+ TStorageGroupId Id;
std::unordered_set<std::pair<const TLeaderTabletInfo*, ui32>> Units; // Tablet + Channel
- double AcquiredIOPS = 0;
- ui64 AcquiredThroughput = 0;
- ui64 AcquiredSize = 0;
- double MaximumIOPS = 0;
- ui64 MaximumThroughput = 0;
- ui64 MaximumSize = 0;
- NKikimrBlobStorage::TEvControllerSelectGroupsResult::TGroupParameters GroupParameters;
-
- TStorageGroupInfo(const TStoragePoolInfo& storagePool, TStorageGroupId id);
- TStorageGroupInfo(const TStorageGroupInfo&) = delete;
- TStorageGroupInfo(TStorageGroupInfo&&) = delete;
- TStorageGroupInfo& operator =(const TStorageGroupInfo&) = delete;
- TStorageGroupInfo& operator =(TStorageGroupInfo&&) = delete;
+ double AcquiredIOPS = 0;
+ ui64 AcquiredThroughput = 0;
+ ui64 AcquiredSize = 0;
+ double MaximumIOPS = 0;
+ ui64 MaximumThroughput = 0;
+ ui64 MaximumSize = 0;
+ NKikimrBlobStorage::TEvControllerSelectGroupsResult::TGroupParameters GroupParameters;
+
+ TStorageGroupInfo(const TStoragePoolInfo& storagePool, TStorageGroupId id);
+ TStorageGroupInfo(const TStorageGroupInfo&) = delete;
+ TStorageGroupInfo(TStorageGroupInfo&&) = delete;
+ TStorageGroupInfo& operator =(const TStorageGroupInfo&) = delete;
+ TStorageGroupInfo& operator =(TStorageGroupInfo&&) = delete;
bool AcquireAllocationUnit(const TLeaderTabletInfo* tablet, ui32 channel);
bool ReleaseAllocationUnit(const TLeaderTabletInfo* tablet, ui32 channel);
- void UpdateStorageGroup(const TEvControllerSelectGroupsResult::TGroupParameters& groupParameters);
- bool IsMatchesParameters(const TEvControllerSelectGroups::TGroupParameters& groupParameters) const;
- double GetUsage() const;
- double GetMaximumIOPS() const;
- ui64 GetMaximumThroughput() const;
- ui64 GetMaximumSize() const;
- bool IsBalanceByIOPS() const;
- bool IsBalanceByThroughput() const;
- bool IsBalanceBySize() const;
-};
-
-}
-}
+ void UpdateStorageGroup(const TEvControllerSelectGroupsResult::TGroupParameters& groupParameters);
+ bool IsMatchesParameters(const TEvControllerSelectGroups::TGroupParameters& groupParameters) const;
+ double GetUsage() const;
+ double GetMaximumIOPS() const;
+ ui64 GetMaximumThroughput() const;
+ ui64 GetMaximumSize() const;
+ bool IsBalanceByIOPS() const;
+ bool IsBalanceByThroughput() const;
+ bool IsBalanceBySize() const;
+};
+
+}
+}
diff --git a/ydb/core/mind/hive/storage_pool_info.cpp b/ydb/core/mind/hive/storage_pool_info.cpp
index 737e2940bc0..fafd6644dee 100644
--- a/ydb/core/mind/hive/storage_pool_info.cpp
+++ b/ydb/core/mind/hive/storage_pool_info.cpp
@@ -1,176 +1,176 @@
-#include "storage_pool_info.h"
-#include "hive_impl.h"
-
-namespace NKikimr {
-namespace NHive {
-
-using namespace NKikimrBlobStorage;
-
-TStoragePoolInfo::TStoragePoolInfo(const TString& name, THiveSharedSettings* hive)
- : Settings(hive)
- , Name(name)
-{
-}
-
-TStorageGroupInfo& TStoragePoolInfo::GetStorageGroup(TStorageGroupId groupId) {
- auto it = Groups.find(groupId);
- if (it == Groups.end()) {
- it = Groups.emplace(std::piecewise_construct, std::tuple<TStorageGroupId>(groupId), std::tuple<const TStoragePoolInfo&, TStorageGroupId>(*this, groupId)).first;
- }
- return it->second;
-}
-
+#include "storage_pool_info.h"
+#include "hive_impl.h"
+
+namespace NKikimr {
+namespace NHive {
+
+using namespace NKikimrBlobStorage;
+
+TStoragePoolInfo::TStoragePoolInfo(const TString& name, THiveSharedSettings* hive)
+ : Settings(hive)
+ , Name(name)
+{
+}
+
+TStorageGroupInfo& TStoragePoolInfo::GetStorageGroup(TStorageGroupId groupId) {
+ auto it = Groups.find(groupId);
+ if (it == Groups.end()) {
+ it = Groups.emplace(std::piecewise_construct, std::tuple<TStorageGroupId>(groupId), std::tuple<const TStoragePoolInfo&, TStorageGroupId>(*this, groupId)).first;
+ }
+ return it->second;
+}
+
bool TStoragePoolInfo::AcquireAllocationUnit(const TLeaderTabletInfo* tablet, ui32 channel, TStorageGroupId groupId) {
- return GetStorageGroup(groupId).AcquireAllocationUnit(tablet, channel);
-}
-
+ return GetStorageGroup(groupId).AcquireAllocationUnit(tablet, channel);
+}
+
bool TStoragePoolInfo::ReleaseAllocationUnit(const TLeaderTabletInfo* tablet, ui32 channel, TStorageGroupId groupId) {
- return GetStorageGroup(groupId).ReleaseAllocationUnit(tablet, channel);
-}
-
-void TStoragePoolInfo::UpdateStorageGroup(TStorageGroupId groupId, const TEvControllerSelectGroupsResult::TGroupParameters& groupParameters) {
- GetStorageGroup(groupId).UpdateStorageGroup(groupParameters);
-}
-
-void TStoragePoolInfo::DeleteStorageGroup(TStorageGroupId groupId) {
- Groups.erase(groupId);
-}
-
-template <>
-const TEvControllerSelectGroupsResult::TGroupParameters* TStoragePoolInfo::SelectGroup<NKikimrConfig::THiveConfig::HIVE_STORAGE_SELECT_STRATEGY_ROUND_ROBIN>(const TVector<const TStorageGroupInfo*>& groupCandidates) {
- Y_VERIFY(!groupCandidates.empty());
- return &(groupCandidates[RoundRobinPos++ % groupCandidates.size()]->GroupParameters);
-}
-
-template <>
-const TEvControllerSelectGroupsResult::TGroupParameters* TStoragePoolInfo::SelectGroup<NKikimrConfig::THiveConfig::HIVE_STORAGE_SELECT_STRATEGY_RANDOM>(const TVector<const TStorageGroupInfo*>& groupCandidates) {
- Y_VERIFY(!groupCandidates.empty());
- return &(groupCandidates[TAppData::RandomProvider->GenRand() % groupCandidates.size()]->GroupParameters);
-}
-
-template <>
-const TEvControllerSelectGroupsResult::TGroupParameters* TStoragePoolInfo::SelectGroup<NKikimrConfig::THiveConfig::HIVE_STORAGE_SELECT_STRATEGY_WEIGHTED_RANDOM>(const TVector<const TStorageGroupInfo*>& groupCandidates) {
- Y_VERIFY(!groupCandidates.empty());
- double sumUsage = 0;
- double maxUsage = 0;
- for (const TStorageGroupInfo* groupInfo : groupCandidates) {
- double usage = groupInfo->GetUsage();
- sumUsage += usage;
- maxUsage = std::max(maxUsage, usage);
- }
- //maxUsage = std::max(1.0, maxUsage);
- double sumAvail = maxUsage * groupCandidates.size() - sumUsage;
- if (sumAvail > 0) {
- double pos = TAppData::RandomProvider->GenRandReal2() * sumAvail;
- for (const TStorageGroupInfo* groupInfo : groupCandidates) {
- double avail = maxUsage - groupInfo->GetUsage();
- if (pos < avail) {
- return &groupInfo->GroupParameters;
- } else {
- pos -= avail;
- }
- }
- }
- return SelectGroup<NKikimrConfig::THiveConfig::HIVE_STORAGE_SELECT_STRATEGY_RANDOM>(groupCandidates);
-}
-
-template <>
-const TEvControllerSelectGroupsResult::TGroupParameters* TStoragePoolInfo::SelectGroup<NKikimrConfig::THiveConfig::HIVE_STORAGE_SELECT_STRATEGY_EXACT_MIN>(const TVector<const TStorageGroupInfo*>& groupCandidates) {
- Y_VERIFY(!groupCandidates.empty());
- auto itMin = std::min_element(
- groupCandidates.begin(),
- groupCandidates.end(),
- [](const TStorageGroupInfo* a, const TStorageGroupInfo* b) {
- return a->GetUsage() < b->GetUsage();
- });
- return &((*itMin)->GroupParameters);
-}
-
-template <>
-const TEvControllerSelectGroupsResult::TGroupParameters* TStoragePoolInfo::SelectGroup<NKikimrConfig::THiveConfig::HIVE_STORAGE_SELECT_STRATEGY_RANDOM_MIN_7P>(const TVector<const TStorageGroupInfo*>& groupCandidates) {
- Y_VERIFY(!groupCandidates.empty());
- TVector<const TStorageGroupInfo*> groups(groupCandidates);
- auto itGroup = groups.begin();
- auto itPartition = itGroup;
- size_t percent7 = std::max<size_t>(groups.size() * 7 / 100, 1);
- std::advance(itPartition, percent7);
- std::nth_element(groups.begin(), itPartition, groups.end(), [](const TStorageGroupInfo* a, const TStorageGroupInfo* b) {
- return a->GetUsage() < b->GetUsage();
- });
- std::advance(itGroup, TAppData::RandomProvider->GenRand64() % percent7);
- return &((*itGroup)->GroupParameters);
-}
-
-const TEvControllerSelectGroupsResult::TGroupParameters* TStoragePoolInfo::FindFreeAllocationUnit(std::function<bool(const TStorageGroupInfo&)> filter) {
- if (Groups.empty()) {
- return nullptr;
- }
- TVector<const TStorageGroupInfo*> groupCandidates;
- groupCandidates.reserve(Groups.size());
- for (const auto& [groupId, groupInfo] : Groups) {
- if (filter(groupInfo)) {
- groupCandidates.emplace_back(&groupInfo);
- }
- }
- if (groupCandidates.empty()) {
- return nullptr;
- }
- switch (GetSelectStrategy()) {
- case NKikimrConfig::THiveConfig::HIVE_STORAGE_SELECT_STRATEGY_WEIGHTED_RANDOM:
- return SelectGroup<NKikimrConfig::THiveConfig::HIVE_STORAGE_SELECT_STRATEGY_WEIGHTED_RANDOM>(groupCandidates);
- case NKikimrConfig::THiveConfig::HIVE_STORAGE_SELECT_STRATEGY_EXACT_MIN:
- return SelectGroup<NKikimrConfig::THiveConfig::HIVE_STORAGE_SELECT_STRATEGY_EXACT_MIN>(groupCandidates);
- case NKikimrConfig::THiveConfig::HIVE_STORAGE_SELECT_STRATEGY_RANDOM_MIN_7P:
- return SelectGroup<NKikimrConfig::THiveConfig::HIVE_STORAGE_SELECT_STRATEGY_RANDOM_MIN_7P>(groupCandidates);
- case NKikimrConfig::THiveConfig::HIVE_STORAGE_SELECT_STRATEGY_ROUND_ROBIN:
- return SelectGroup<NKikimrConfig::THiveConfig::HIVE_STORAGE_SELECT_STRATEGY_ROUND_ROBIN>(groupCandidates);
- case NKikimrConfig::THiveConfig::HIVE_STORAGE_SELECT_STRATEGY_RANDOM:
- return SelectGroup<NKikimrConfig::THiveConfig::HIVE_STORAGE_SELECT_STRATEGY_RANDOM>(groupCandidates);
- }
-}
-
-bool TStoragePoolInfo::IsBalanceByIOPS() const {
- auto balanceStrategy = GetBalanceStrategy();
- return balanceStrategy == NKikimrConfig::THiveConfig::HIVE_STORAGE_BALANCE_STRATEGY_AUTO || balanceStrategy == NKikimrConfig::THiveConfig::HIVE_STORAGE_BALANCE_STRATEGY_IOPS;
-}
-
-bool TStoragePoolInfo::IsBalanceByThroughput() const {
- auto balanceStrategy = GetBalanceStrategy();
- return balanceStrategy == NKikimrConfig::THiveConfig::HIVE_STORAGE_BALANCE_STRATEGY_AUTO || balanceStrategy == NKikimrConfig::THiveConfig::HIVE_STORAGE_BALANCE_STRATEGY_THROUGHPUT;
-}
-
-bool TStoragePoolInfo::IsBalanceBySize() const {
- auto balanceStrategy = GetBalanceStrategy();
- return balanceStrategy == NKikimrConfig::THiveConfig::HIVE_STORAGE_BALANCE_STRATEGY_AUTO || balanceStrategy == NKikimrConfig::THiveConfig::HIVE_STORAGE_BALANCE_STRATEGY_SIZE;
-}
-
-bool TStoragePoolInfo::IsFresh() const {
- return TInstant::Now() < LastUpdate + FreshPeriod;
-}
-
-void TStoragePoolInfo::SetAsFresh() {
- LastUpdate = TInstant::Now();
-}
-
-void TStoragePoolInfo::Invalidate() {
- LastUpdate = TInstant();
-}
-
-THolder<TEvControllerSelectGroups::TGroupParameters> TStoragePoolInfo::BuildRefreshRequest() const {
+ return GetStorageGroup(groupId).ReleaseAllocationUnit(tablet, channel);
+}
+
+void TStoragePoolInfo::UpdateStorageGroup(TStorageGroupId groupId, const TEvControllerSelectGroupsResult::TGroupParameters& groupParameters) {
+ GetStorageGroup(groupId).UpdateStorageGroup(groupParameters);
+}
+
+void TStoragePoolInfo::DeleteStorageGroup(TStorageGroupId groupId) {
+ Groups.erase(groupId);
+}
+
+template <>
+const TEvControllerSelectGroupsResult::TGroupParameters* TStoragePoolInfo::SelectGroup<NKikimrConfig::THiveConfig::HIVE_STORAGE_SELECT_STRATEGY_ROUND_ROBIN>(const TVector<const TStorageGroupInfo*>& groupCandidates) {
+ Y_VERIFY(!groupCandidates.empty());
+ return &(groupCandidates[RoundRobinPos++ % groupCandidates.size()]->GroupParameters);
+}
+
+template <>
+const TEvControllerSelectGroupsResult::TGroupParameters* TStoragePoolInfo::SelectGroup<NKikimrConfig::THiveConfig::HIVE_STORAGE_SELECT_STRATEGY_RANDOM>(const TVector<const TStorageGroupInfo*>& groupCandidates) {
+ Y_VERIFY(!groupCandidates.empty());
+ return &(groupCandidates[TAppData::RandomProvider->GenRand() % groupCandidates.size()]->GroupParameters);
+}
+
+template <>
+const TEvControllerSelectGroupsResult::TGroupParameters* TStoragePoolInfo::SelectGroup<NKikimrConfig::THiveConfig::HIVE_STORAGE_SELECT_STRATEGY_WEIGHTED_RANDOM>(const TVector<const TStorageGroupInfo*>& groupCandidates) {
+ Y_VERIFY(!groupCandidates.empty());
+ double sumUsage = 0;
+ double maxUsage = 0;
+ for (const TStorageGroupInfo* groupInfo : groupCandidates) {
+ double usage = groupInfo->GetUsage();
+ sumUsage += usage;
+ maxUsage = std::max(maxUsage, usage);
+ }
+ //maxUsage = std::max(1.0, maxUsage);
+ double sumAvail = maxUsage * groupCandidates.size() - sumUsage;
+ if (sumAvail > 0) {
+ double pos = TAppData::RandomProvider->GenRandReal2() * sumAvail;
+ for (const TStorageGroupInfo* groupInfo : groupCandidates) {
+ double avail = maxUsage - groupInfo->GetUsage();
+ if (pos < avail) {
+ return &groupInfo->GroupParameters;
+ } else {
+ pos -= avail;
+ }
+ }
+ }
+ return SelectGroup<NKikimrConfig::THiveConfig::HIVE_STORAGE_SELECT_STRATEGY_RANDOM>(groupCandidates);
+}
+
+template <>
+const TEvControllerSelectGroupsResult::TGroupParameters* TStoragePoolInfo::SelectGroup<NKikimrConfig::THiveConfig::HIVE_STORAGE_SELECT_STRATEGY_EXACT_MIN>(const TVector<const TStorageGroupInfo*>& groupCandidates) {
+ Y_VERIFY(!groupCandidates.empty());
+ auto itMin = std::min_element(
+ groupCandidates.begin(),
+ groupCandidates.end(),
+ [](const TStorageGroupInfo* a, const TStorageGroupInfo* b) {
+ return a->GetUsage() < b->GetUsage();
+ });
+ return &((*itMin)->GroupParameters);
+}
+
+template <>
+const TEvControllerSelectGroupsResult::TGroupParameters* TStoragePoolInfo::SelectGroup<NKikimrConfig::THiveConfig::HIVE_STORAGE_SELECT_STRATEGY_RANDOM_MIN_7P>(const TVector<const TStorageGroupInfo*>& groupCandidates) {
+ Y_VERIFY(!groupCandidates.empty());
+ TVector<const TStorageGroupInfo*> groups(groupCandidates);
+ auto itGroup = groups.begin();
+ auto itPartition = itGroup;
+ size_t percent7 = std::max<size_t>(groups.size() * 7 / 100, 1);
+ std::advance(itPartition, percent7);
+ std::nth_element(groups.begin(), itPartition, groups.end(), [](const TStorageGroupInfo* a, const TStorageGroupInfo* b) {
+ return a->GetUsage() < b->GetUsage();
+ });
+ std::advance(itGroup, TAppData::RandomProvider->GenRand64() % percent7);
+ return &((*itGroup)->GroupParameters);
+}
+
+const TEvControllerSelectGroupsResult::TGroupParameters* TStoragePoolInfo::FindFreeAllocationUnit(std::function<bool(const TStorageGroupInfo&)> filter) {
+ if (Groups.empty()) {
+ return nullptr;
+ }
+ TVector<const TStorageGroupInfo*> groupCandidates;
+ groupCandidates.reserve(Groups.size());
+ for (const auto& [groupId, groupInfo] : Groups) {
+ if (filter(groupInfo)) {
+ groupCandidates.emplace_back(&groupInfo);
+ }
+ }
+ if (groupCandidates.empty()) {
+ return nullptr;
+ }
+ switch (GetSelectStrategy()) {
+ case NKikimrConfig::THiveConfig::HIVE_STORAGE_SELECT_STRATEGY_WEIGHTED_RANDOM:
+ return SelectGroup<NKikimrConfig::THiveConfig::HIVE_STORAGE_SELECT_STRATEGY_WEIGHTED_RANDOM>(groupCandidates);
+ case NKikimrConfig::THiveConfig::HIVE_STORAGE_SELECT_STRATEGY_EXACT_MIN:
+ return SelectGroup<NKikimrConfig::THiveConfig::HIVE_STORAGE_SELECT_STRATEGY_EXACT_MIN>(groupCandidates);
+ case NKikimrConfig::THiveConfig::HIVE_STORAGE_SELECT_STRATEGY_RANDOM_MIN_7P:
+ return SelectGroup<NKikimrConfig::THiveConfig::HIVE_STORAGE_SELECT_STRATEGY_RANDOM_MIN_7P>(groupCandidates);
+ case NKikimrConfig::THiveConfig::HIVE_STORAGE_SELECT_STRATEGY_ROUND_ROBIN:
+ return SelectGroup<NKikimrConfig::THiveConfig::HIVE_STORAGE_SELECT_STRATEGY_ROUND_ROBIN>(groupCandidates);
+ case NKikimrConfig::THiveConfig::HIVE_STORAGE_SELECT_STRATEGY_RANDOM:
+ return SelectGroup<NKikimrConfig::THiveConfig::HIVE_STORAGE_SELECT_STRATEGY_RANDOM>(groupCandidates);
+ }
+}
+
+bool TStoragePoolInfo::IsBalanceByIOPS() const {
+ auto balanceStrategy = GetBalanceStrategy();
+ return balanceStrategy == NKikimrConfig::THiveConfig::HIVE_STORAGE_BALANCE_STRATEGY_AUTO || balanceStrategy == NKikimrConfig::THiveConfig::HIVE_STORAGE_BALANCE_STRATEGY_IOPS;
+}
+
+bool TStoragePoolInfo::IsBalanceByThroughput() const {
+ auto balanceStrategy = GetBalanceStrategy();
+ return balanceStrategy == NKikimrConfig::THiveConfig::HIVE_STORAGE_BALANCE_STRATEGY_AUTO || balanceStrategy == NKikimrConfig::THiveConfig::HIVE_STORAGE_BALANCE_STRATEGY_THROUGHPUT;
+}
+
+bool TStoragePoolInfo::IsBalanceBySize() const {
+ auto balanceStrategy = GetBalanceStrategy();
+ return balanceStrategy == NKikimrConfig::THiveConfig::HIVE_STORAGE_BALANCE_STRATEGY_AUTO || balanceStrategy == NKikimrConfig::THiveConfig::HIVE_STORAGE_BALANCE_STRATEGY_SIZE;
+}
+
+bool TStoragePoolInfo::IsFresh() const {
+ return TInstant::Now() < LastUpdate + FreshPeriod;
+}
+
+void TStoragePoolInfo::SetAsFresh() {
+ LastUpdate = TInstant::Now();
+}
+
+void TStoragePoolInfo::Invalidate() {
+ LastUpdate = TInstant();
+}
+
+THolder<TEvControllerSelectGroups::TGroupParameters> TStoragePoolInfo::BuildRefreshRequest() const {
THolder<TEvControllerSelectGroups::TGroupParameters> params = MakeHolder<TEvControllerSelectGroups::TGroupParameters>();
- params->MutableStoragePoolSpecifier()->SetName(Name);
- return params;
-}
-
-bool TStoragePoolInfo::AddTabletToWait(TTabletId tabletId) {
- bool result = TabletsWaiting.empty();
- TabletsWaiting.emplace_back(tabletId);
- return result;
-}
-
-TVector<TTabletId> TStoragePoolInfo::PullWaitingTablets() {
- return std::move(TabletsWaiting);
-}
-
-} // NHive
-} // NKikimr
+ params->MutableStoragePoolSpecifier()->SetName(Name);
+ return params;
+}
+
+bool TStoragePoolInfo::AddTabletToWait(TTabletId tabletId) {
+ bool result = TabletsWaiting.empty();
+ TabletsWaiting.emplace_back(tabletId);
+ return result;
+}
+
+TVector<TTabletId> TStoragePoolInfo::PullWaitingTablets() {
+ return std::move(TabletsWaiting);
+}
+
+} // NHive
+} // NKikimr
diff --git a/ydb/core/mind/hive/storage_pool_info.h b/ydb/core/mind/hive/storage_pool_info.h
index ab37fe1b3e6..b606fc40b7e 100644
--- a/ydb/core/mind/hive/storage_pool_info.h
+++ b/ydb/core/mind/hive/storage_pool_info.h
@@ -1,80 +1,80 @@
-#pragma once
-
-#include "hive.h"
-#include "storage_group_info.h"
-
-namespace NKikimr {
-namespace NHive {
-
-using namespace NKikimrBlobStorage;
-
-class THive;
-
-struct TStoragePoolInfo {
- static constexpr TDuration FreshPeriod = TDuration::Minutes(1);
- THiveSharedSettings* Settings;
-
- NKikimrConfig::THiveConfig::EHiveStorageBalanceStrategy GetBalanceStrategy() const {
- return Settings->GetStorageBalanceStrategy();
- }
-
- NKikimrConfig::THiveConfig::EHiveStorageSelectStrategy GetSelectStrategy() const {
- return Settings->GetStorageSelectStrategy();
- }
-
- bool GetSafeMode() const {
- return Settings->GetStorageSafeMode();
- }
-
- double GetOvercommit() const {
- return Settings->GetStorageOvercommit();
- }
-
- double GetOvercommitIOPS() const {
- return GetOvercommit();
- }
-
- double GetOvercommitThroughput() const {
- return GetOvercommit();
- }
-
- double GetOvercommitSize() const {
- return GetOvercommit();
- }
-
- TString Name;
- THashMap<TStorageGroupId, TStorageGroupInfo> Groups;
- TInstant LastUpdate;
- TVector<TTabletId> TabletsWaiting;
- ui32 ConfigurationGeneration = 0; // used to discard cache across configuration changes
- ui32 RefreshRequestInFlight = 0;
-
- TStoragePoolInfo(const TString& name, THiveSharedSettings* hive);
- TStoragePoolInfo(const TStoragePoolInfo&) = delete;
- TStoragePoolInfo(TStoragePoolInfo&&) = delete;
- TStoragePoolInfo& operator =(const TStoragePoolInfo&) = delete;
- TStoragePoolInfo& operator =(TStoragePoolInfo&&) = delete;
+#pragma once
+
+#include "hive.h"
+#include "storage_group_info.h"
+
+namespace NKikimr {
+namespace NHive {
+
+using namespace NKikimrBlobStorage;
+
+class THive;
+
+struct TStoragePoolInfo {
+ static constexpr TDuration FreshPeriod = TDuration::Minutes(1);
+ THiveSharedSettings* Settings;
+
+ NKikimrConfig::THiveConfig::EHiveStorageBalanceStrategy GetBalanceStrategy() const {
+ return Settings->GetStorageBalanceStrategy();
+ }
+
+ NKikimrConfig::THiveConfig::EHiveStorageSelectStrategy GetSelectStrategy() const {
+ return Settings->GetStorageSelectStrategy();
+ }
+
+ bool GetSafeMode() const {
+ return Settings->GetStorageSafeMode();
+ }
+
+ double GetOvercommit() const {
+ return Settings->GetStorageOvercommit();
+ }
+
+ double GetOvercommitIOPS() const {
+ return GetOvercommit();
+ }
+
+ double GetOvercommitThroughput() const {
+ return GetOvercommit();
+ }
+
+ double GetOvercommitSize() const {
+ return GetOvercommit();
+ }
+
+ TString Name;
+ THashMap<TStorageGroupId, TStorageGroupInfo> Groups;
+ TInstant LastUpdate;
+ TVector<TTabletId> TabletsWaiting;
+ ui32 ConfigurationGeneration = 0; // used to discard cache across configuration changes
+ ui32 RefreshRequestInFlight = 0;
+
+ TStoragePoolInfo(const TString& name, THiveSharedSettings* hive);
+ TStoragePoolInfo(const TStoragePoolInfo&) = delete;
+ TStoragePoolInfo(TStoragePoolInfo&&) = delete;
+ TStoragePoolInfo& operator =(const TStoragePoolInfo&) = delete;
+ TStoragePoolInfo& operator =(TStoragePoolInfo&&) = delete;
bool AcquireAllocationUnit(const TLeaderTabletInfo* tablet, ui32 channel, TStorageGroupId groupId);
bool ReleaseAllocationUnit(const TLeaderTabletInfo* tablet, ui32 channel, TStorageGroupId groupId);
- TStorageGroupInfo& GetStorageGroup(TStorageGroupId groupId);
- void UpdateStorageGroup(TStorageGroupId groupId, const TEvControllerSelectGroupsResult::TGroupParameters& groupParameters);
- void DeleteStorageGroup(TStorageGroupId groupId);
- const TEvControllerSelectGroupsResult::TGroupParameters* FindFreeAllocationUnit(std::function<bool(const TStorageGroupInfo&)> filter);
- bool IsBalanceByIOPS() const;
- bool IsBalanceByThroughput() const;
- bool IsBalanceBySize() const;
- bool IsFresh() const;
- void SetAsFresh();
- void Invalidate();
- THolder<TEvControllerSelectGroups::TGroupParameters> BuildRefreshRequest() const;
- bool AddTabletToWait(TTabletId tabletId);
- TVector<TTabletId> PullWaitingTablets();
- template <NKikimrConfig::THiveConfig::EHiveStorageSelectStrategy Strategy>
- const TEvControllerSelectGroupsResult::TGroupParameters* SelectGroup(const TVector<const TStorageGroupInfo*>& groupCandidates);
-
-private:
- size_t RoundRobinPos = 0;
-};
-
-}
-}
+ TStorageGroupInfo& GetStorageGroup(TStorageGroupId groupId);
+ void UpdateStorageGroup(TStorageGroupId groupId, const TEvControllerSelectGroupsResult::TGroupParameters& groupParameters);
+ void DeleteStorageGroup(TStorageGroupId groupId);
+ const TEvControllerSelectGroupsResult::TGroupParameters* FindFreeAllocationUnit(std::function<bool(const TStorageGroupInfo&)> filter);
+ bool IsBalanceByIOPS() const;
+ bool IsBalanceByThroughput() const;
+ bool IsBalanceBySize() const;
+ bool IsFresh() const;
+ void SetAsFresh();
+ void Invalidate();
+ THolder<TEvControllerSelectGroups::TGroupParameters> BuildRefreshRequest() const;
+ bool AddTabletToWait(TTabletId tabletId);
+ TVector<TTabletId> PullWaitingTablets();
+ template <NKikimrConfig::THiveConfig::EHiveStorageSelectStrategy Strategy>
+ const TEvControllerSelectGroupsResult::TGroupParameters* SelectGroup(const TVector<const TStorageGroupInfo*>& groupCandidates);
+
+private:
+ size_t RoundRobinPos = 0;
+};
+
+}
+}
diff --git a/ydb/core/mind/hive/storage_pool_info_ut.cpp b/ydb/core/mind/hive/storage_pool_info_ut.cpp
index adf339e3dc3..d0e21abc3f2 100644
--- a/ydb/core/mind/hive/storage_pool_info_ut.cpp
+++ b/ydb/core/mind/hive/storage_pool_info_ut.cpp
@@ -1,228 +1,228 @@
#include <library/cpp/testing/unittest/registar.h>
#include <library/cpp/testing/unittest/tests_data.h>
#include <ydb/core/protos/blobstorage.pb.h>
-#include "storage_pool_info.h"
-
-using namespace NKikimr;
-using namespace NHive;
-using namespace NKikimrBlobStorage;
-
-Y_UNIT_TEST_SUITE(StoragePool) {
- double GetAvg(const TMap<ui32, ui32>& values) {
- double sum = 0;
- for (auto [id, value] : values) {
- Y_UNUSED(id);
- sum += value;
- }
- return sum / values.size();
- }
-
- double GetMin(const TMap<ui32, ui32>& values) {
- double min = values.empty() ? NAN : values.begin()->second;
- for (auto [id, value] : values) {
- Y_UNUSED(id);
- min = std::min<double>(min, value);
- }
- return min;
- }
-
- double GetMax(const TMap<ui32, ui32>& values) {
- double max = values.empty() ? NAN : values.begin()->second;
- for (auto [id, value] : values) {
- Y_UNUSED(id);
- max = std::max<double>(max, value);
- }
- return max;
- }
-
- double GetStdDev(const TMap<ui32, ui32>& values) {
- double sum = 0;
- for (auto [id, value] : values) {
- Y_UNUSED(id);
- sum += value;
- }
- auto mean = sum / values.size();
- sum = 0;
- for (auto [id, value] : values) {
- Y_UNUSED(id);
- auto diff = value - mean;
- sum = sum + diff * diff;
- }
- return sqrt(sum / values.size());
- }
-
- void TestStrategy(NKikimrConfig::THiveConfig::EHiveStorageSelectStrategy strategy) {
- THiveSharedSettings settings;
- settings.CurrentConfig.SetStorageSelectStrategy(strategy);
- TStoragePoolInfo pool("pool1", &settings);
- TEvControllerSelectGroupsResult::TGroupParameters group1;
- group1.MutableAssuredResources()->SetIOPS(1000);
- group1.MutableAssuredResources()->SetReadThroughput(1000);
- group1.MutableAssuredResources()->SetSpace(1000000);
- for (int i = 1; i <= 80; ++i) {
- group1.SetGroupID(i);
- pool.UpdateStorageGroup(i, group1);
- }
-
- static constexpr int TABLETS1 = 100000;
- static constexpr int TABLETS2 = 60000;
- static constexpr int CHANNELS = 3;
-
- TMap<ui32, ui32> groupUnits;
- TMap<ui32, ui32> groupChannels[CHANNELS];
-
- TEvControllerSelectGroups::TGroupParameters unit1;
- unit1.SetRequiredIOPS(1);
- unit1.SetRequiredThroughput(10);
- unit1.SetRequiredDataSize(100);
-
- auto checkUnit1 = [&unit1](const TStorageGroupInfo& group) -> bool {
- return group.IsMatchesParameters(unit1);
- };
-
- for (int i = 0; i < TABLETS1 * CHANNELS; ++i) {
- int channel = i % CHANNELS;
- const TEvControllerSelectGroupsResult::TGroupParameters* found = pool.FindFreeAllocationUnit(checkUnit1);
- UNIT_ASSERT(found);
- ui32 groupId = found->GetGroupID();
- groupUnits[groupId]++;
- groupChannels[channel][groupId]++;
- pool.GetStorageGroup(groupId).AcquiredIOPS += unit1.GetRequiredIOPS();
- pool.GetStorageGroup(groupId).AcquiredThroughput += unit1.GetRequiredThroughput();
- pool.GetStorageGroup(groupId).AcquiredSize += unit1.GetRequiredDataSize();
- }
-
- if (strategy != NKikimrConfig::THiveConfig::HIVE_STORAGE_SELECT_STRATEGY_ROUND_ROBIN) {
- // simulate storage expansion - it doesn't work well with RoundRobin strategy
-
- for (int i = 81; i <= 100; ++i) {
- group1.SetGroupID(i);
- pool.UpdateStorageGroup(i, group1);
- }
-
- for (int i = 0; i < TABLETS2 * CHANNELS; ++i) {
- int channel = i % CHANNELS;
- const TEvControllerSelectGroupsResult::TGroupParameters* found = pool.FindFreeAllocationUnit(checkUnit1);
- UNIT_ASSERT(found);
- ui32 groupId = found->GetGroupID();
- groupUnits[groupId]++;
- groupChannels[channel][groupId]++;
- pool.GetStorageGroup(groupId).AcquiredIOPS += unit1.GetRequiredIOPS();
- pool.GetStorageGroup(groupId).AcquiredThroughput += unit1.GetRequiredThroughput();
- pool.GetStorageGroup(groupId).AcquiredSize += unit1.GetRequiredDataSize();
- }
- }
-
-#ifndef _NDEBUG
- auto avg = GetAvg(groupUnits);
- Cerr << "avg = " << avg << Endl;
-
- auto min = GetMin(groupUnits);
- Cerr << "min = " << min << Endl;
-
- auto max = GetMax(groupUnits);
- Cerr << "max = " << max << Endl;
-
- auto stdDev = GetStdDev(groupUnits);
- Cerr << "std-dev = " << stdDev << Endl;
-
- for (int i = 0; i < CHANNELS; ++i) {
- auto avg = GetAvg(groupChannels[i]);
- Cerr << "ch." << i << " avg = " << avg << Endl;
-
- auto min = GetMin(groupChannels[i]);
- Cerr << "ch." << i << " min = " << min << Endl;
-
- auto max = GetMax(groupChannels[i]);
- Cerr << "ch." << i << " max = " << max << Endl;
-
- auto stdDev = GetStdDev(groupChannels[i]);
- Cerr << "ch." << i << " std-dev = " << stdDev << Endl;
- }
-#endif
-
- UNIT_ASSERT_VALUES_EQUAL(round(GetAvg(groupUnits)), 4800);
- UNIT_ASSERT(GetStdDev(groupUnits) < 1);
- }
-
- void TestStrategyWithOverflow(NKikimrConfig::THiveConfig::EHiveStorageSelectStrategy strategy) {
- THiveSharedSettings settings;
- settings.CurrentConfig.SetStorageSelectStrategy(strategy);
- TStoragePoolInfo pool("pool1", &settings);
- TEvControllerSelectGroupsResult::TGroupParameters group1;
- group1.MutableAssuredResources()->SetIOPS(1000);
- group1.MutableAssuredResources()->SetReadThroughput(1000);
- group1.MutableAssuredResources()->SetSpace(1000000);
- group1.SetGroupID(1);
- pool.UpdateStorageGroup(1, group1);
- group1.SetGroupID(2);
- pool.UpdateStorageGroup(2, group1);
- group1.SetGroupID(3);
- pool.UpdateStorageGroup(3, group1);
- group1.SetGroupID(4);
- pool.UpdateStorageGroup(4, group1);
-
- TMap<ui32, ui32> groupUnits;
-
- TEvControllerSelectGroups::TGroupParameters unit1;
- unit1.SetRequiredIOPS(1);
- unit1.SetRequiredThroughput(10);
- unit1.SetRequiredDataSize(1000);
- auto checkUnit1 = [&unit1](const TStorageGroupInfo& group) -> bool {
- return group.IsMatchesParameters(unit1);
- };
- for (int i = 0; i < 5000; ++i) { // overflow
- const TEvControllerSelectGroupsResult::TGroupParameters* found = pool.FindFreeAllocationUnit(checkUnit1);
- UNIT_ASSERT(found);
- ui32 groupId = found->GetGroupID();
- groupUnits[groupId]++;
- pool.GetStorageGroup(groupId).AcquiredIOPS += unit1.GetRequiredIOPS();
- pool.GetStorageGroup(groupId).AcquiredThroughput += unit1.GetRequiredThroughput();
- pool.GetStorageGroup(groupId).AcquiredSize += unit1.GetRequiredDataSize();
- }
-
-#ifndef _NDEBUG
- auto avg = GetAvg(groupUnits);
- Cerr << "avg = " << avg << Endl;
-
-
- auto stdDev = GetStdDev(groupUnits);
- Cerr << "std-dev = " << stdDev << Endl;
-#endif
-
- UNIT_ASSERT_VALUES_EQUAL(round(GetAvg(groupUnits)), 1250);
- UNIT_ASSERT(GetStdDev(groupUnits) < 0.32);
- }
-
- Y_UNIT_TEST(TestDistributionRandomProbability) {
- TestStrategy(NKikimrConfig::THiveConfig::HIVE_STORAGE_SELECT_STRATEGY_WEIGHTED_RANDOM);
- }
-
- Y_UNIT_TEST(TestDistributionRandomProbabilityWithOverflow) {
- TestStrategyWithOverflow(NKikimrConfig::THiveConfig::HIVE_STORAGE_SELECT_STRATEGY_WEIGHTED_RANDOM);
- }
-
- Y_UNIT_TEST(TestDistributionExactMin) {
- TestStrategy(NKikimrConfig::THiveConfig::HIVE_STORAGE_SELECT_STRATEGY_EXACT_MIN);
- }
-
- Y_UNIT_TEST(TestDistributionExactMinWithOverflow) {
- TestStrategyWithOverflow(NKikimrConfig::THiveConfig::HIVE_STORAGE_SELECT_STRATEGY_EXACT_MIN);
- }
-
- Y_UNIT_TEST(TestDistributionRandomMin7p) {
- TestStrategy(NKikimrConfig::THiveConfig::HIVE_STORAGE_SELECT_STRATEGY_RANDOM_MIN_7P);
- }
-
- Y_UNIT_TEST(TestDistributionRandomMin7pWithOverflow) {
- TestStrategyWithOverflow(NKikimrConfig::THiveConfig::HIVE_STORAGE_SELECT_STRATEGY_RANDOM_MIN_7P);
- }
-
- /*Y_UNIT_TEST(TestDistributionRoundRobin) {
- TestStrategy(EStorageSelectStrategy::RoundRobin);
- }*/
-
- /*Y_UNIT_TEST(TestDistributionRoundRobinWithOverflow) {
- TestStrategyWithOverflow(EStorageSelectStrategy::RoundRobin);
- }*/
-}
+#include "storage_pool_info.h"
+
+using namespace NKikimr;
+using namespace NHive;
+using namespace NKikimrBlobStorage;
+
+Y_UNIT_TEST_SUITE(StoragePool) {
+ double GetAvg(const TMap<ui32, ui32>& values) {
+ double sum = 0;
+ for (auto [id, value] : values) {
+ Y_UNUSED(id);
+ sum += value;
+ }
+ return sum / values.size();
+ }
+
+ double GetMin(const TMap<ui32, ui32>& values) {
+ double min = values.empty() ? NAN : values.begin()->second;
+ for (auto [id, value] : values) {
+ Y_UNUSED(id);
+ min = std::min<double>(min, value);
+ }
+ return min;
+ }
+
+ double GetMax(const TMap<ui32, ui32>& values) {
+ double max = values.empty() ? NAN : values.begin()->second;
+ for (auto [id, value] : values) {
+ Y_UNUSED(id);
+ max = std::max<double>(max, value);
+ }
+ return max;
+ }
+
+ double GetStdDev(const TMap<ui32, ui32>& values) {
+ double sum = 0;
+ for (auto [id, value] : values) {
+ Y_UNUSED(id);
+ sum += value;
+ }
+ auto mean = sum / values.size();
+ sum = 0;
+ for (auto [id, value] : values) {
+ Y_UNUSED(id);
+ auto diff = value - mean;
+ sum = sum + diff * diff;
+ }
+ return sqrt(sum / values.size());
+ }
+
+ void TestStrategy(NKikimrConfig::THiveConfig::EHiveStorageSelectStrategy strategy) {
+ THiveSharedSettings settings;
+ settings.CurrentConfig.SetStorageSelectStrategy(strategy);
+ TStoragePoolInfo pool("pool1", &settings);
+ TEvControllerSelectGroupsResult::TGroupParameters group1;
+ group1.MutableAssuredResources()->SetIOPS(1000);
+ group1.MutableAssuredResources()->SetReadThroughput(1000);
+ group1.MutableAssuredResources()->SetSpace(1000000);
+ for (int i = 1; i <= 80; ++i) {
+ group1.SetGroupID(i);
+ pool.UpdateStorageGroup(i, group1);
+ }
+
+ static constexpr int TABLETS1 = 100000;
+ static constexpr int TABLETS2 = 60000;
+ static constexpr int CHANNELS = 3;
+
+ TMap<ui32, ui32> groupUnits;
+ TMap<ui32, ui32> groupChannels[CHANNELS];
+
+ TEvControllerSelectGroups::TGroupParameters unit1;
+ unit1.SetRequiredIOPS(1);
+ unit1.SetRequiredThroughput(10);
+ unit1.SetRequiredDataSize(100);
+
+ auto checkUnit1 = [&unit1](const TStorageGroupInfo& group) -> bool {
+ return group.IsMatchesParameters(unit1);
+ };
+
+ for (int i = 0; i < TABLETS1 * CHANNELS; ++i) {
+ int channel = i % CHANNELS;
+ const TEvControllerSelectGroupsResult::TGroupParameters* found = pool.FindFreeAllocationUnit(checkUnit1);
+ UNIT_ASSERT(found);
+ ui32 groupId = found->GetGroupID();
+ groupUnits[groupId]++;
+ groupChannels[channel][groupId]++;
+ pool.GetStorageGroup(groupId).AcquiredIOPS += unit1.GetRequiredIOPS();
+ pool.GetStorageGroup(groupId).AcquiredThroughput += unit1.GetRequiredThroughput();
+ pool.GetStorageGroup(groupId).AcquiredSize += unit1.GetRequiredDataSize();
+ }
+
+ if (strategy != NKikimrConfig::THiveConfig::HIVE_STORAGE_SELECT_STRATEGY_ROUND_ROBIN) {
+ // simulate storage expansion - it doesn't work well with RoundRobin strategy
+
+ for (int i = 81; i <= 100; ++i) {
+ group1.SetGroupID(i);
+ pool.UpdateStorageGroup(i, group1);
+ }
+
+ for (int i = 0; i < TABLETS2 * CHANNELS; ++i) {
+ int channel = i % CHANNELS;
+ const TEvControllerSelectGroupsResult::TGroupParameters* found = pool.FindFreeAllocationUnit(checkUnit1);
+ UNIT_ASSERT(found);
+ ui32 groupId = found->GetGroupID();
+ groupUnits[groupId]++;
+ groupChannels[channel][groupId]++;
+ pool.GetStorageGroup(groupId).AcquiredIOPS += unit1.GetRequiredIOPS();
+ pool.GetStorageGroup(groupId).AcquiredThroughput += unit1.GetRequiredThroughput();
+ pool.GetStorageGroup(groupId).AcquiredSize += unit1.GetRequiredDataSize();
+ }
+ }
+
+#ifndef _NDEBUG
+ auto avg = GetAvg(groupUnits);
+ Cerr << "avg = " << avg << Endl;
+
+ auto min = GetMin(groupUnits);
+ Cerr << "min = " << min << Endl;
+
+ auto max = GetMax(groupUnits);
+ Cerr << "max = " << max << Endl;
+
+ auto stdDev = GetStdDev(groupUnits);
+ Cerr << "std-dev = " << stdDev << Endl;
+
+ for (int i = 0; i < CHANNELS; ++i) {
+ auto avg = GetAvg(groupChannels[i]);
+ Cerr << "ch." << i << " avg = " << avg << Endl;
+
+ auto min = GetMin(groupChannels[i]);
+ Cerr << "ch." << i << " min = " << min << Endl;
+
+ auto max = GetMax(groupChannels[i]);
+ Cerr << "ch." << i << " max = " << max << Endl;
+
+ auto stdDev = GetStdDev(groupChannels[i]);
+ Cerr << "ch." << i << " std-dev = " << stdDev << Endl;
+ }
+#endif
+
+ UNIT_ASSERT_VALUES_EQUAL(round(GetAvg(groupUnits)), 4800);
+ UNIT_ASSERT(GetStdDev(groupUnits) < 1);
+ }
+
+ void TestStrategyWithOverflow(NKikimrConfig::THiveConfig::EHiveStorageSelectStrategy strategy) {
+ THiveSharedSettings settings;
+ settings.CurrentConfig.SetStorageSelectStrategy(strategy);
+ TStoragePoolInfo pool("pool1", &settings);
+ TEvControllerSelectGroupsResult::TGroupParameters group1;
+ group1.MutableAssuredResources()->SetIOPS(1000);
+ group1.MutableAssuredResources()->SetReadThroughput(1000);
+ group1.MutableAssuredResources()->SetSpace(1000000);
+ group1.SetGroupID(1);
+ pool.UpdateStorageGroup(1, group1);
+ group1.SetGroupID(2);
+ pool.UpdateStorageGroup(2, group1);
+ group1.SetGroupID(3);
+ pool.UpdateStorageGroup(3, group1);
+ group1.SetGroupID(4);
+ pool.UpdateStorageGroup(4, group1);
+
+ TMap<ui32, ui32> groupUnits;
+
+ TEvControllerSelectGroups::TGroupParameters unit1;
+ unit1.SetRequiredIOPS(1);
+ unit1.SetRequiredThroughput(10);
+ unit1.SetRequiredDataSize(1000);
+ auto checkUnit1 = [&unit1](const TStorageGroupInfo& group) -> bool {
+ return group.IsMatchesParameters(unit1);
+ };
+ for (int i = 0; i < 5000; ++i) { // overflow
+ const TEvControllerSelectGroupsResult::TGroupParameters* found = pool.FindFreeAllocationUnit(checkUnit1);
+ UNIT_ASSERT(found);
+ ui32 groupId = found->GetGroupID();
+ groupUnits[groupId]++;
+ pool.GetStorageGroup(groupId).AcquiredIOPS += unit1.GetRequiredIOPS();
+ pool.GetStorageGroup(groupId).AcquiredThroughput += unit1.GetRequiredThroughput();
+ pool.GetStorageGroup(groupId).AcquiredSize += unit1.GetRequiredDataSize();
+ }
+
+#ifndef _NDEBUG
+ auto avg = GetAvg(groupUnits);
+ Cerr << "avg = " << avg << Endl;
+
+
+ auto stdDev = GetStdDev(groupUnits);
+ Cerr << "std-dev = " << stdDev << Endl;
+#endif
+
+ UNIT_ASSERT_VALUES_EQUAL(round(GetAvg(groupUnits)), 1250);
+ UNIT_ASSERT(GetStdDev(groupUnits) < 0.32);
+ }
+
+ Y_UNIT_TEST(TestDistributionRandomProbability) {
+ TestStrategy(NKikimrConfig::THiveConfig::HIVE_STORAGE_SELECT_STRATEGY_WEIGHTED_RANDOM);
+ }
+
+ Y_UNIT_TEST(TestDistributionRandomProbabilityWithOverflow) {
+ TestStrategyWithOverflow(NKikimrConfig::THiveConfig::HIVE_STORAGE_SELECT_STRATEGY_WEIGHTED_RANDOM);
+ }
+
+ Y_UNIT_TEST(TestDistributionExactMin) {
+ TestStrategy(NKikimrConfig::THiveConfig::HIVE_STORAGE_SELECT_STRATEGY_EXACT_MIN);
+ }
+
+ Y_UNIT_TEST(TestDistributionExactMinWithOverflow) {
+ TestStrategyWithOverflow(NKikimrConfig::THiveConfig::HIVE_STORAGE_SELECT_STRATEGY_EXACT_MIN);
+ }
+
+ Y_UNIT_TEST(TestDistributionRandomMin7p) {
+ TestStrategy(NKikimrConfig::THiveConfig::HIVE_STORAGE_SELECT_STRATEGY_RANDOM_MIN_7P);
+ }
+
+ Y_UNIT_TEST(TestDistributionRandomMin7pWithOverflow) {
+ TestStrategyWithOverflow(NKikimrConfig::THiveConfig::HIVE_STORAGE_SELECT_STRATEGY_RANDOM_MIN_7P);
+ }
+
+ /*Y_UNIT_TEST(TestDistributionRoundRobin) {
+ TestStrategy(EStorageSelectStrategy::RoundRobin);
+ }*/
+
+ /*Y_UNIT_TEST(TestDistributionRoundRobinWithOverflow) {
+ TestStrategyWithOverflow(EStorageSelectStrategy::RoundRobin);
+ }*/
+}
diff --git a/ydb/core/mind/hive/tablet_info.cpp b/ydb/core/mind/hive/tablet_info.cpp
index d17fe2421b9..9fddd10801e 100644
--- a/ydb/core/mind/hive/tablet_info.cpp
+++ b/ydb/core/mind/hive/tablet_info.cpp
@@ -1,486 +1,486 @@
-#include "hive_impl.h"
-#include "hive_log.h"
-#include "tablet_info.h"
-#include "node_info.h"
+#include "hive_impl.h"
+#include "hive_log.h"
+#include "tablet_info.h"
+#include "node_info.h"
#include "leader_tablet_info.h"
#include "follower_tablet_info.h"
-
-namespace NKikimr {
-namespace NHive {
-
-TTabletInfo::TTabletInfo(ETabletRole role, THive& hive)
- : VolatileState(EVolatileState::TABLET_VOLATILE_STATE_UNKNOWN)
- , TabletRole(role)
- , VolatileStateChangeTime()
- , LastBalancerDecisionTime()
- , Hive(hive)
- , PreferredNodeId(0)
- , NodeId(0)
- , Node(nullptr)
- , LastNodeId(0)
- , ResourceValues()
- , ResourceMetricsAggregates(Hive.GetDefaultResourceMetricsAggregates())
- , Weight(0)
-{}
-
+
+namespace NKikimr {
+namespace NHive {
+
+TTabletInfo::TTabletInfo(ETabletRole role, THive& hive)
+ : VolatileState(EVolatileState::TABLET_VOLATILE_STATE_UNKNOWN)
+ , TabletRole(role)
+ , VolatileStateChangeTime()
+ , LastBalancerDecisionTime()
+ , Hive(hive)
+ , PreferredNodeId(0)
+ , NodeId(0)
+ , Node(nullptr)
+ , LastNodeId(0)
+ , ResourceValues()
+ , ResourceMetricsAggregates(Hive.GetDefaultResourceMetricsAggregates())
+ , Weight(0)
+{}
+
const TLeaderTabletInfo& TTabletInfo::GetLeader() const {
if (IsLeader()) {
return AsLeader();
- } else {
+ } else {
return AsFollower().LeaderTablet;
- }
-}
-
+ }
+}
+
TLeaderTabletInfo& TTabletInfo::GetLeader() {
if (IsLeader()) {
return AsLeader();
- } else {
+ } else {
return AsFollower().LeaderTablet;
- }
-}
-
+ }
+}
+
TLeaderTabletInfo& TTabletInfo::AsLeader() {
Y_VERIFY(TabletRole == ETabletRole::Leader);
return static_cast<TLeaderTabletInfo&>(*this);
-}
-
+}
+
const TLeaderTabletInfo& TTabletInfo::AsLeader() const {
Y_VERIFY(TabletRole == ETabletRole::Leader);
return static_cast<const TLeaderTabletInfo&>(*this);
-}
-
+}
+
TFollowerTabletInfo& TTabletInfo::AsFollower() {
Y_VERIFY(TabletRole == ETabletRole::Follower);
return static_cast<TFollowerTabletInfo&>(*this);
-}
-
+}
+
const TFollowerTabletInfo& TTabletInfo::AsFollower() const {
Y_VERIFY(TabletRole == ETabletRole::Follower);
return static_cast<const TFollowerTabletInfo&>(*this);
-}
-
+}
+
std::pair<TTabletId, TFollowerId> TTabletInfo::GetFullTabletId() const {
if (IsLeader()) {
return { GetLeader().Id, 0 };
- } else {
+ } else {
return { GetLeader().Id, AsFollower().Id };
- }
-}
-
-TObjectId TTabletInfo::GetObjectId() const {
+ }
+}
+
+TObjectId TTabletInfo::GetObjectId() const {
return GetLeader().ObjectId;
-}
-
-TTabletTypes::EType TTabletInfo::GetTabletType() const {
+}
+
+TTabletTypes::EType TTabletInfo::GetTabletType() const {
return GetLeader().Type;
-}
-
-TString TTabletInfo::ToString() const {
+}
+
+TString TTabletInfo::ToString() const {
const TLeaderTabletInfo& leader = GetLeader();
- TStringBuilder str;
+ TStringBuilder str;
str << TTabletTypes::TypeToStr(leader.Type) << '.' << leader.Id << '.' << ETabletRoleName(TabletRole);
if (IsFollower()) {
const TFollowerTabletInfo& follower(AsFollower());
str << '.' << follower.Id;
- } else {
+ } else {
str << '.' << leader.KnownGeneration;
- }
- return str;
-}
-
-TString TTabletInfo::StateString() const {
- TStringBuilder state;
- state << EVolatileStateName(VolatileState);
- if (Node != nullptr) {
- state << " on node " << Node->Id;
- }
- return state;
-}
-
-TString TTabletInfo::FamilyString() const {
- TStringBuilder family;
+ }
+ return str;
+}
+
+TString TTabletInfo::StateString() const {
+ TStringBuilder state;
+ state << EVolatileStateName(VolatileState);
+ if (Node != nullptr) {
+ state << " on node " << Node->Id;
+ }
+ return state;
+}
+
+TString TTabletInfo::FamilyString() const {
+ TStringBuilder family;
const TLeaderTabletInfo& leader = GetLeader();
- family << '{';
+ family << '{';
family << leader.ToString() << ' ' << leader.StateString();
for (const TFollowerTabletInfo& follower : leader.Followers) {
family << ", " << follower.ToString() << ' ' << follower.StateString();
- }
- family << '}';
- return family;
-}
-
-void TTabletInfo::ChangeVolatileState(EVolatileState state) {
- if (VolatileState == state) {
- if (Node != nullptr) {
- BLOG_D("Tablet(" << ToString() << ") VolatileState: " << EVolatileStateName(VolatileState) << " (Node " << Node->Id << ")");
- } else {
- BLOG_D("Tablet(" << ToString() << ") VolatileState: " << EVolatileStateName(VolatileState));
- }
- } else {
- if (Node != nullptr) {
- BLOG_D("Tablet(" << ToString() << ") VolatileState: " << EVolatileStateName(VolatileState) << " -> " << EVolatileStateName(state) << " (Node " << Node->Id << ")");
- } else {
- BLOG_D("Tablet(" << ToString() << ") VolatileState: " << EVolatileStateName(VolatileState) << " -> " << EVolatileStateName(state));
- }
- }
- if (Node != nullptr) {
- Node->OnTabletChangeVolatileState(this, state);
- }
- VolatileState = state;
- VolatileStateChangeTime = TActivationContext::Now();
-}
-
-bool TTabletInfo::IsReadyToStart(TInstant now) const {
+ }
+ family << '}';
+ return family;
+}
+
+void TTabletInfo::ChangeVolatileState(EVolatileState state) {
+ if (VolatileState == state) {
+ if (Node != nullptr) {
+ BLOG_D("Tablet(" << ToString() << ") VolatileState: " << EVolatileStateName(VolatileState) << " (Node " << Node->Id << ")");
+ } else {
+ BLOG_D("Tablet(" << ToString() << ") VolatileState: " << EVolatileStateName(VolatileState));
+ }
+ } else {
+ if (Node != nullptr) {
+ BLOG_D("Tablet(" << ToString() << ") VolatileState: " << EVolatileStateName(VolatileState) << " -> " << EVolatileStateName(state) << " (Node " << Node->Id << ")");
+ } else {
+ BLOG_D("Tablet(" << ToString() << ") VolatileState: " << EVolatileStateName(VolatileState) << " -> " << EVolatileStateName(state));
+ }
+ }
+ if (Node != nullptr) {
+ Node->OnTabletChangeVolatileState(this, state);
+ }
+ VolatileState = state;
+ VolatileStateChangeTime = TActivationContext::Now();
+}
+
+bool TTabletInfo::IsReadyToStart(TInstant now) const {
if (IsFollower()) {
if (!GetLeader().IsRunning()) {
- return false;
- }
- }
- return NodeId == 0 && VolatileState == EVolatileState::TABLET_VOLATILE_STATE_BOOTING && now >= PostponedStart;
-}
-
-bool TTabletInfo::IsStarting() const {
- return NodeId == 0 && VolatileState == EVolatileState::TABLET_VOLATILE_STATE_STARTING;
-}
-
-bool TTabletInfo::IsStartingOnNode(TNodeId nodeId) const {
- return IsStarting() && Node != nullptr && Node->Id == nodeId;
-}
-
-bool TTabletInfo::IsRunning() const {
- return Node != nullptr && VolatileState == EVolatileState::TABLET_VOLATILE_STATE_RUNNING;
-}
-
-bool TTabletInfo::IsBooting() const {
- return VolatileState == EVolatileState::TABLET_VOLATILE_STATE_BOOTING;
-}
-
-bool TTabletInfo::IsAlive() const {
- return Node != nullptr &&
- (VolatileState == EVolatileState::TABLET_VOLATILE_STATE_STARTING
- || VolatileState == EVolatileState::TABLET_VOLATILE_STATE_RUNNING);
-}
-
-bool TTabletInfo::CanBeAlive() const {
- return Node != nullptr &&
- (VolatileState == EVolatileState::TABLET_VOLATILE_STATE_STARTING
- || VolatileState == EVolatileState::TABLET_VOLATILE_STATE_RUNNING
- || VolatileState == EVolatileState::TABLET_VOLATILE_STATE_UNKNOWN); // KIKIMR-12558
-}
-
+ return false;
+ }
+ }
+ return NodeId == 0 && VolatileState == EVolatileState::TABLET_VOLATILE_STATE_BOOTING && now >= PostponedStart;
+}
+
+bool TTabletInfo::IsStarting() const {
+ return NodeId == 0 && VolatileState == EVolatileState::TABLET_VOLATILE_STATE_STARTING;
+}
+
+bool TTabletInfo::IsStartingOnNode(TNodeId nodeId) const {
+ return IsStarting() && Node != nullptr && Node->Id == nodeId;
+}
+
+bool TTabletInfo::IsRunning() const {
+ return Node != nullptr && VolatileState == EVolatileState::TABLET_VOLATILE_STATE_RUNNING;
+}
+
+bool TTabletInfo::IsBooting() const {
+ return VolatileState == EVolatileState::TABLET_VOLATILE_STATE_BOOTING;
+}
+
+bool TTabletInfo::IsAlive() const {
+ return Node != nullptr &&
+ (VolatileState == EVolatileState::TABLET_VOLATILE_STATE_STARTING
+ || VolatileState == EVolatileState::TABLET_VOLATILE_STATE_RUNNING);
+}
+
+bool TTabletInfo::CanBeAlive() const {
+ return Node != nullptr &&
+ (VolatileState == EVolatileState::TABLET_VOLATILE_STATE_STARTING
+ || VolatileState == EVolatileState::TABLET_VOLATILE_STATE_RUNNING
+ || VolatileState == EVolatileState::TABLET_VOLATILE_STATE_UNKNOWN); // KIKIMR-12558
+}
+
bool TTabletInfo::IsAliveOnLocal(const TActorId& local) const {
- return Node != nullptr
- && Node->Local == local
- && (VolatileState == EVolatileState::TABLET_VOLATILE_STATE_STARTING
- || VolatileState == EVolatileState::TABLET_VOLATILE_STATE_RUNNING
- || VolatileState == EVolatileState::TABLET_VOLATILE_STATE_UNKNOWN); // KIKIMR-3712
-}
-
-bool TTabletInfo::IsStopped() const {
- return VolatileState == EVolatileState::TABLET_VOLATILE_STATE_STOPPED;
-}
-
-bool TTabletInfo::IsGoodForBalancer(TInstant now) const {
- return now - LastBalancerDecisionTime > Hive.GetTabletKickCooldownPeriod();
-}
-
-bool TTabletInfo::InitiateBoot() {
- if (IsStopped()) {
- ChangeVolatileState(EVolatileState::TABLET_VOLATILE_STATE_BOOTING);
- Hive.AddToBootQueue(this);
- Hive.ProcessBootQueue();
- return true;
- } else {
- return false;
- }
-}
-
-bool TTabletInfo::InitiateStop() {
+ return Node != nullptr
+ && Node->Local == local
+ && (VolatileState == EVolatileState::TABLET_VOLATILE_STATE_STARTING
+ || VolatileState == EVolatileState::TABLET_VOLATILE_STATE_RUNNING
+ || VolatileState == EVolatileState::TABLET_VOLATILE_STATE_UNKNOWN); // KIKIMR-3712
+}
+
+bool TTabletInfo::IsStopped() const {
+ return VolatileState == EVolatileState::TABLET_VOLATILE_STATE_STOPPED;
+}
+
+bool TTabletInfo::IsGoodForBalancer(TInstant now) const {
+ return now - LastBalancerDecisionTime > Hive.GetTabletKickCooldownPeriod();
+}
+
+bool TTabletInfo::InitiateBoot() {
+ if (IsStopped()) {
+ ChangeVolatileState(EVolatileState::TABLET_VOLATILE_STATE_BOOTING);
+ Hive.AddToBootQueue(this);
+ Hive.ProcessBootQueue();
+ return true;
+ } else {
+ return false;
+ }
+}
+
+bool TTabletInfo::InitiateStop() {
TActorId local;
- TNodeInfo* node = Node;
- if (node == nullptr && NodeId != 0) {
- node = Hive.FindNode(NodeId);
- }
- if (node != nullptr) {
- local = node->Local;
- }
- if (BecomeStopped()) {
- if (Hive.GetEnableFastTabletMove() && node != nullptr && !node->Freeze && PreferredNodeId != 0) {
- // we only do it when we have PreferredNodeId, which means that we are moving from one node to another
- LastNodeId = node->Id;
- } else {
- SendStopTablet(local, GetFullTabletId());
- LastNodeId = 0;
- }
+ TNodeInfo* node = Node;
+ if (node == nullptr && NodeId != 0) {
+ node = Hive.FindNode(NodeId);
+ }
+ if (node != nullptr) {
+ local = node->Local;
+ }
+ if (BecomeStopped()) {
+ if (Hive.GetEnableFastTabletMove() && node != nullptr && !node->Freeze && PreferredNodeId != 0) {
+ // we only do it when we have PreferredNodeId, which means that we are moving from one node to another
+ LastNodeId = node->Id;
+ } else {
+ SendStopTablet(local, GetFullTabletId());
+ LastNodeId = 0;
+ }
if (IsLeader()) {
for (TFollowerTabletInfo& follower : AsLeader().Followers) {
if (follower.FollowerGroup.LocalNodeOnly) {
follower.InitiateStop();
- }
- }
- }
- return true;
- } else {
- return false;
- }
-}
-
-bool TTabletInfo::BecomeStarting(TNodeId nodeId) {
- if (VolatileState != EVolatileState::TABLET_VOLATILE_STATE_STARTING) {
- Node = Hive.FindNode(nodeId);
- Y_VERIFY(Node != nullptr);
- ChangeVolatileState(EVolatileState::TABLET_VOLATILE_STATE_STARTING);
- return true;
- }
- return false;
-}
-
-bool TTabletInfo::BecomeRunning(TNodeId nodeId) {
- if (VolatileState != EVolatileState::TABLET_VOLATILE_STATE_RUNNING || NodeId != nodeId || (Node != nullptr && Node->Id != nodeId)) {
- NodeId = nodeId;
- PreferredNodeId = 0;
- Y_VERIFY(NodeId != 0);
- if (Node == nullptr) {
- Node = Hive.FindNode(NodeId);
- Y_VERIFY(Node != nullptr);
- } else if (Node->Id != NodeId) {
- ChangeVolatileState(EVolatileState::TABLET_VOLATILE_STATE_STOPPED);
- Node = Hive.FindNode(NodeId);
- Y_VERIFY(Node != nullptr);
- }
- ChangeVolatileState(EVolatileState::TABLET_VOLATILE_STATE_RUNNING);
- return true;
- }
- return false;
-}
-
-bool TTabletInfo::BecomeStopped() {
- if (VolatileState != EVolatileState::TABLET_VOLATILE_STATE_STOPPED) {
- if (Node == nullptr && NodeId != 0) {
- Node = Hive.FindNode(NodeId);
- Y_VERIFY(Node != nullptr);
- }
- ChangeVolatileState(EVolatileState::TABLET_VOLATILE_STATE_STOPPED);
- BootState.clear();
- if (Node != nullptr && Node->Freeze) {
- PreferredNodeId = Node->Id;
- }
- NodeId = 0;
- Node = nullptr;
- return true;
- } else {
- return false;
- }
-}
-
-void TTabletInfo::BecomeUnknown(TNodeInfo* node) {
- Y_VERIFY(VolatileState == EVolatileState::TABLET_VOLATILE_STATE_UNKNOWN);
- Y_VERIFY(Node == nullptr || node == Node);
- Node = node;
- if (Node->Freeze) {
- PreferredNodeId = Node->Id;
- }
- ChangeVolatileState(EVolatileState::TABLET_VOLATILE_STATE_UNKNOWN);
-}
-
-bool TTabletInfo::Kick() {
- if (IsAlive()) {
- Hive.KickTablet(*this);
- return true;
- } else {
- return false;
- }
-}
-
-void TTabletInfo::Kill() {
+ }
+ }
+ }
+ return true;
+ } else {
+ return false;
+ }
+}
+
+bool TTabletInfo::BecomeStarting(TNodeId nodeId) {
+ if (VolatileState != EVolatileState::TABLET_VOLATILE_STATE_STARTING) {
+ Node = Hive.FindNode(nodeId);
+ Y_VERIFY(Node != nullptr);
+ ChangeVolatileState(EVolatileState::TABLET_VOLATILE_STATE_STARTING);
+ return true;
+ }
+ return false;
+}
+
+bool TTabletInfo::BecomeRunning(TNodeId nodeId) {
+ if (VolatileState != EVolatileState::TABLET_VOLATILE_STATE_RUNNING || NodeId != nodeId || (Node != nullptr && Node->Id != nodeId)) {
+ NodeId = nodeId;
+ PreferredNodeId = 0;
+ Y_VERIFY(NodeId != 0);
+ if (Node == nullptr) {
+ Node = Hive.FindNode(NodeId);
+ Y_VERIFY(Node != nullptr);
+ } else if (Node->Id != NodeId) {
+ ChangeVolatileState(EVolatileState::TABLET_VOLATILE_STATE_STOPPED);
+ Node = Hive.FindNode(NodeId);
+ Y_VERIFY(Node != nullptr);
+ }
+ ChangeVolatileState(EVolatileState::TABLET_VOLATILE_STATE_RUNNING);
+ return true;
+ }
+ return false;
+}
+
+bool TTabletInfo::BecomeStopped() {
+ if (VolatileState != EVolatileState::TABLET_VOLATILE_STATE_STOPPED) {
+ if (Node == nullptr && NodeId != 0) {
+ Node = Hive.FindNode(NodeId);
+ Y_VERIFY(Node != nullptr);
+ }
+ ChangeVolatileState(EVolatileState::TABLET_VOLATILE_STATE_STOPPED);
+ BootState.clear();
+ if (Node != nullptr && Node->Freeze) {
+ PreferredNodeId = Node->Id;
+ }
+ NodeId = 0;
+ Node = nullptr;
+ return true;
+ } else {
+ return false;
+ }
+}
+
+void TTabletInfo::BecomeUnknown(TNodeInfo* node) {
+ Y_VERIFY(VolatileState == EVolatileState::TABLET_VOLATILE_STATE_UNKNOWN);
+ Y_VERIFY(Node == nullptr || node == Node);
+ Node = node;
+ if (Node->Freeze) {
+ PreferredNodeId = Node->Id;
+ }
+ ChangeVolatileState(EVolatileState::TABLET_VOLATILE_STATE_UNKNOWN);
+}
+
+bool TTabletInfo::Kick() {
+ if (IsAlive()) {
+ Hive.KickTablet(*this);
+ return true;
+ } else {
+ return false;
+ }
+}
+
+void TTabletInfo::Kill() {
TActorId local;
- TNodeInfo* node = Node;
- if (node == nullptr && NodeId != 0) {
- node = Hive.FindNode(NodeId);
- }
- if (node != nullptr) {
- local = node->Local;
- }
- if (local) {
- Hive.StopTablet(local, *this);
- }
-}
-
-const TVector<i64>& TTabletInfo::GetTabletAllowedMetricIds() const {
+ TNodeInfo* node = Node;
+ if (node == nullptr && NodeId != 0) {
+ node = Hive.FindNode(NodeId);
+ }
+ if (node != nullptr) {
+ local = node->Local;
+ }
+ if (local) {
+ Hive.StopTablet(local, *this);
+ }
+}
+
+const TVector<i64>& TTabletInfo::GetTabletAllowedMetricIds() const {
return Hive.GetTabletTypeAllowedMetricIds(GetLeader().Type);
-}
-
-void TTabletInfo::UpdateResourceUsage(const NKikimrTabletBase::TMetrics& metrics) {
- TInstant now = TInstant::Now();
- const TVector<i64>& allowedMetricIds(GetTabletAllowedMetricIds());
- auto before = ResourceValues;
- auto maximum = GetResourceMaximumValues();
- if (Find(allowedMetricIds, NKikimrTabletBase::TMetrics::kCPUFieldNumber) != allowedMetricIds.end()) {
- if (metrics.HasCPU() || ResourceValues.HasCPU()) {
- if (metrics.GetCPU() > static_cast<ui64>(std::get<NMetrics::EResource::CPU>(maximum))) {
- BLOG_W("Ignoring too high CPU metric (" << metrics.GetCPU() << ") for tablet " << ToString());
- } else {
- ResourceMetricsAggregates.MaximumCPU.SetValue(metrics.GetCPU(), now);
- ResourceValues.SetCPU(ResourceMetricsAggregates.MaximumCPU.GetValue());
- }
- }
- }
- if (Find(allowedMetricIds, NKikimrTabletBase::TMetrics::kMemoryFieldNumber) != allowedMetricIds.end()) {
- if (metrics.HasMemory() || ResourceValues.HasMemory()) {
- if (metrics.GetMemory() > static_cast<ui64>(std::get<NMetrics::EResource::Memory>(maximum))) {
- BLOG_W("Ignoring too high Memory metric (" << metrics.GetMemory() << ") for tablet " << ToString());
- } else {
- ResourceMetricsAggregates.MaximumMemory.SetValue(metrics.GetMemory(), now);
- ResourceValues.SetMemory(ResourceMetricsAggregates.MaximumMemory.GetValue());
- }
- }
- }
- if (Find(allowedMetricIds, NKikimrTabletBase::TMetrics::kNetworkFieldNumber) != allowedMetricIds.end()) {
- if (metrics.HasNetwork() || ResourceValues.HasNetwork()) {
- if (metrics.GetNetwork() > static_cast<ui64>(std::get<NMetrics::EResource::Network>(maximum))) {
- BLOG_W("Ignoring too high Network metric (" << metrics.GetNetwork() << ") for tablet " << ToString());
- } else {
- ResourceMetricsAggregates.MaximumNetwork.SetValue(metrics.GetNetwork(), now);
- ResourceValues.SetNetwork(ResourceMetricsAggregates.MaximumNetwork.GetValue());
- }
- }
- }
- if (metrics.HasStorage()) {
- ResourceValues.SetStorage(metrics.GetStorage());
- }
- if (metrics.HasReadThroughput()) {
- ResourceValues.SetReadThroughput(metrics.GetReadThroughput());
- }
- if (metrics.HasWriteThroughput()) {
- ResourceValues.SetWriteThroughput(metrics.GetWriteThroughput());
- }
- if (metrics.GroupReadThroughputSize() > 0) {
- ResourceValues.ClearGroupReadThroughput();
- for (const auto& v : metrics.GetGroupReadThroughput()) {
- ResourceValues.AddGroupReadThroughput()->CopyFrom(v);
- }
- }
- if (metrics.GroupWriteThroughputSize() > 0) {
- ResourceValues.ClearGroupWriteThroughput();
- for (const auto& v : metrics.GetGroupWriteThroughput()) {
- ResourceValues.AddGroupWriteThroughput()->CopyFrom(v);
- }
- }
- ResourceValues.SetCounter(GetCounterValue(ResourceValues, GetTabletAllowedMetricIds()));
- const auto& after = ResourceValues;
- if (Node != nullptr) {
- Node->UpdateResourceValues(this, before, after);
- }
-}
-
-TResourceRawValues TTabletInfo::GetResourceCurrentValues() const {
- return ResourceRawValuesFromMetrics(ResourceValues);
-}
-
-TResourceRawValues TTabletInfo::GetResourceMaximumValues() const {
- if (Node != nullptr) {
- return Node->GetResourceMaximumValues();
- } else {
- return Hive.GetResourceInitialMaximumValues();
- }
-}
-
-i64 TTabletInfo::GetCounterValue(const NKikimrTabletBase::TMetrics& metrics, const TVector<i64>& allowedMetricIds) {
- if (Find(allowedMetricIds, NKikimrTabletBase::TMetrics::kCPUFieldNumber) != allowedMetricIds.end() && THive::IsValidMetricsCPU(metrics)) {
- return 0;
- }
- if (Find(allowedMetricIds, NKikimrTabletBase::TMetrics::kMemoryFieldNumber) != allowedMetricIds.end() && THive::IsValidMetricsMemory(metrics)) {
- return 0;
- }
- if (Find(allowedMetricIds, NKikimrTabletBase::TMetrics::kNetworkFieldNumber) != allowedMetricIds.end() && THive::IsValidMetricsNetwork(metrics)) {
- return 0;
- }
- return 1;
-}
-
-void TTabletInfo::FilterRawValues(TResourceRawValues& values) const {
- const NKikimrTabletBase::TMetrics& metrics(ResourceValues);
- const TVector<i64>& allowedMetricIds = GetTabletAllowedMetricIds();
- if (metrics.GetCounter() == 0) {
- std::get<NMetrics::EResource::Counter>(values) = 0;
- }
- if (Find(allowedMetricIds, NKikimrTabletBase::TMetrics::kCPUFieldNumber) == allowedMetricIds.end() || !THive::IsValidMetricsCPU(metrics)) {
- std::get<NMetrics::EResource::CPU>(values) = 0;
- }
- if (Find(allowedMetricIds, NKikimrTabletBase::TMetrics::kMemoryFieldNumber) == allowedMetricIds.end() || !THive::IsValidMetricsMemory(metrics)) {
- std::get<NMetrics::EResource::Memory>(values) = 0;
- }
- if (Find(allowedMetricIds, NKikimrTabletBase::TMetrics::kNetworkFieldNumber) == allowedMetricIds.end() || !THive::IsValidMetricsNetwork(metrics)) {
- std::get<NMetrics::EResource::Network>(values) = 0;
- }
-}
-
-void TTabletInfo::FilterRawValues(TResourceNormalizedValues& values) const {
- const NKikimrTabletBase::TMetrics& metrics(ResourceValues);
- const TVector<i64>& allowedMetricIds = GetTabletAllowedMetricIds();
- if (metrics.GetCounter() == 0) {
- std::get<NMetrics::EResource::Counter>(values) = 0;
- }
- if (Find(allowedMetricIds, NKikimrTabletBase::TMetrics::kCPUFieldNumber) == allowedMetricIds.end() || !THive::IsValidMetricsCPU(metrics)) {
- std::get<NMetrics::EResource::CPU>(values) = 0;
- }
- if (Find(allowedMetricIds, NKikimrTabletBase::TMetrics::kMemoryFieldNumber) == allowedMetricIds.end() || !THive::IsValidMetricsMemory(metrics)) {
- std::get<NMetrics::EResource::Memory>(values) = 0;
- }
- if (Find(allowedMetricIds, NKikimrTabletBase::TMetrics::kNetworkFieldNumber) == allowedMetricIds.end() || !THive::IsValidMetricsNetwork(metrics)) {
- std::get<NMetrics::EResource::Network>(values) = 0;
- }
-}
-
-const TVector<TNodeId>& TTabletInfo::GetAllowedNodes() const {
+}
+
+void TTabletInfo::UpdateResourceUsage(const NKikimrTabletBase::TMetrics& metrics) {
+ TInstant now = TInstant::Now();
+ const TVector<i64>& allowedMetricIds(GetTabletAllowedMetricIds());
+ auto before = ResourceValues;
+ auto maximum = GetResourceMaximumValues();
+ if (Find(allowedMetricIds, NKikimrTabletBase::TMetrics::kCPUFieldNumber) != allowedMetricIds.end()) {
+ if (metrics.HasCPU() || ResourceValues.HasCPU()) {
+ if (metrics.GetCPU() > static_cast<ui64>(std::get<NMetrics::EResource::CPU>(maximum))) {
+ BLOG_W("Ignoring too high CPU metric (" << metrics.GetCPU() << ") for tablet " << ToString());
+ } else {
+ ResourceMetricsAggregates.MaximumCPU.SetValue(metrics.GetCPU(), now);
+ ResourceValues.SetCPU(ResourceMetricsAggregates.MaximumCPU.GetValue());
+ }
+ }
+ }
+ if (Find(allowedMetricIds, NKikimrTabletBase::TMetrics::kMemoryFieldNumber) != allowedMetricIds.end()) {
+ if (metrics.HasMemory() || ResourceValues.HasMemory()) {
+ if (metrics.GetMemory() > static_cast<ui64>(std::get<NMetrics::EResource::Memory>(maximum))) {
+ BLOG_W("Ignoring too high Memory metric (" << metrics.GetMemory() << ") for tablet " << ToString());
+ } else {
+ ResourceMetricsAggregates.MaximumMemory.SetValue(metrics.GetMemory(), now);
+ ResourceValues.SetMemory(ResourceMetricsAggregates.MaximumMemory.GetValue());
+ }
+ }
+ }
+ if (Find(allowedMetricIds, NKikimrTabletBase::TMetrics::kNetworkFieldNumber) != allowedMetricIds.end()) {
+ if (metrics.HasNetwork() || ResourceValues.HasNetwork()) {
+ if (metrics.GetNetwork() > static_cast<ui64>(std::get<NMetrics::EResource::Network>(maximum))) {
+ BLOG_W("Ignoring too high Network metric (" << metrics.GetNetwork() << ") for tablet " << ToString());
+ } else {
+ ResourceMetricsAggregates.MaximumNetwork.SetValue(metrics.GetNetwork(), now);
+ ResourceValues.SetNetwork(ResourceMetricsAggregates.MaximumNetwork.GetValue());
+ }
+ }
+ }
+ if (metrics.HasStorage()) {
+ ResourceValues.SetStorage(metrics.GetStorage());
+ }
+ if (metrics.HasReadThroughput()) {
+ ResourceValues.SetReadThroughput(metrics.GetReadThroughput());
+ }
+ if (metrics.HasWriteThroughput()) {
+ ResourceValues.SetWriteThroughput(metrics.GetWriteThroughput());
+ }
+ if (metrics.GroupReadThroughputSize() > 0) {
+ ResourceValues.ClearGroupReadThroughput();
+ for (const auto& v : metrics.GetGroupReadThroughput()) {
+ ResourceValues.AddGroupReadThroughput()->CopyFrom(v);
+ }
+ }
+ if (metrics.GroupWriteThroughputSize() > 0) {
+ ResourceValues.ClearGroupWriteThroughput();
+ for (const auto& v : metrics.GetGroupWriteThroughput()) {
+ ResourceValues.AddGroupWriteThroughput()->CopyFrom(v);
+ }
+ }
+ ResourceValues.SetCounter(GetCounterValue(ResourceValues, GetTabletAllowedMetricIds()));
+ const auto& after = ResourceValues;
+ if (Node != nullptr) {
+ Node->UpdateResourceValues(this, before, after);
+ }
+}
+
+TResourceRawValues TTabletInfo::GetResourceCurrentValues() const {
+ return ResourceRawValuesFromMetrics(ResourceValues);
+}
+
+TResourceRawValues TTabletInfo::GetResourceMaximumValues() const {
+ if (Node != nullptr) {
+ return Node->GetResourceMaximumValues();
+ } else {
+ return Hive.GetResourceInitialMaximumValues();
+ }
+}
+
+i64 TTabletInfo::GetCounterValue(const NKikimrTabletBase::TMetrics& metrics, const TVector<i64>& allowedMetricIds) {
+ if (Find(allowedMetricIds, NKikimrTabletBase::TMetrics::kCPUFieldNumber) != allowedMetricIds.end() && THive::IsValidMetricsCPU(metrics)) {
+ return 0;
+ }
+ if (Find(allowedMetricIds, NKikimrTabletBase::TMetrics::kMemoryFieldNumber) != allowedMetricIds.end() && THive::IsValidMetricsMemory(metrics)) {
+ return 0;
+ }
+ if (Find(allowedMetricIds, NKikimrTabletBase::TMetrics::kNetworkFieldNumber) != allowedMetricIds.end() && THive::IsValidMetricsNetwork(metrics)) {
+ return 0;
+ }
+ return 1;
+}
+
+void TTabletInfo::FilterRawValues(TResourceRawValues& values) const {
+ const NKikimrTabletBase::TMetrics& metrics(ResourceValues);
+ const TVector<i64>& allowedMetricIds = GetTabletAllowedMetricIds();
+ if (metrics.GetCounter() == 0) {
+ std::get<NMetrics::EResource::Counter>(values) = 0;
+ }
+ if (Find(allowedMetricIds, NKikimrTabletBase::TMetrics::kCPUFieldNumber) == allowedMetricIds.end() || !THive::IsValidMetricsCPU(metrics)) {
+ std::get<NMetrics::EResource::CPU>(values) = 0;
+ }
+ if (Find(allowedMetricIds, NKikimrTabletBase::TMetrics::kMemoryFieldNumber) == allowedMetricIds.end() || !THive::IsValidMetricsMemory(metrics)) {
+ std::get<NMetrics::EResource::Memory>(values) = 0;
+ }
+ if (Find(allowedMetricIds, NKikimrTabletBase::TMetrics::kNetworkFieldNumber) == allowedMetricIds.end() || !THive::IsValidMetricsNetwork(metrics)) {
+ std::get<NMetrics::EResource::Network>(values) = 0;
+ }
+}
+
+void TTabletInfo::FilterRawValues(TResourceNormalizedValues& values) const {
+ const NKikimrTabletBase::TMetrics& metrics(ResourceValues);
+ const TVector<i64>& allowedMetricIds = GetTabletAllowedMetricIds();
+ if (metrics.GetCounter() == 0) {
+ std::get<NMetrics::EResource::Counter>(values) = 0;
+ }
+ if (Find(allowedMetricIds, NKikimrTabletBase::TMetrics::kCPUFieldNumber) == allowedMetricIds.end() || !THive::IsValidMetricsCPU(metrics)) {
+ std::get<NMetrics::EResource::CPU>(values) = 0;
+ }
+ if (Find(allowedMetricIds, NKikimrTabletBase::TMetrics::kMemoryFieldNumber) == allowedMetricIds.end() || !THive::IsValidMetricsMemory(metrics)) {
+ std::get<NMetrics::EResource::Memory>(values) = 0;
+ }
+ if (Find(allowedMetricIds, NKikimrTabletBase::TMetrics::kNetworkFieldNumber) == allowedMetricIds.end() || !THive::IsValidMetricsNetwork(metrics)) {
+ std::get<NMetrics::EResource::Network>(values) = 0;
+ }
+}
+
+const TVector<TNodeId>& TTabletInfo::GetAllowedNodes() const {
if (IsLeader()) {
return AsLeader().AllowedNodes;
- } else {
+ } else {
return AsFollower().FollowerGroup.AllowedNodes;
- }
-}
-
-const TVector<TDataCenterId>& TTabletInfo::GetAllowedDataCenters() const {
+ }
+}
+
+const TVector<TDataCenterId>& TTabletInfo::GetAllowedDataCenters() const {
if (IsLeader()) {
return AsLeader().AllowedDataCenters;
- } else {
+ } else {
return AsFollower().FollowerGroup.AllowedDataCenters;
- }
-}
-
-bool TTabletInfo::InitiateStart(TNodeInfo* node) {
- if (BecomeStarting(node->Id)) {
- PostponedStart = {};
- TFullTabletId tabletId = GetFullTabletId();
- Hive.ExecuteStartTablet(tabletId, node->Local, tabletId.first, false);
- return true;
- }
- return false;
-}
-
+ }
+}
+
+bool TTabletInfo::InitiateStart(TNodeInfo* node) {
+ if (BecomeStarting(node->Id)) {
+ PostponedStart = {};
+ TFullTabletId tabletId = GetFullTabletId();
+ Hive.ExecuteStartTablet(tabletId, node->Local, tabletId.first, false);
+ return true;
+ }
+ return false;
+}
+
void TTabletInfo::SendStopTablet(const TActorId& local, TFullTabletId tabletId) {
- if (local) {
- Hive.StopTablet(local, tabletId);
- }
-}
-
-TString TTabletInfo::GetLogPrefix() const {
- return Hive.GetLogPrefix();
-}
-
-void TTabletInfo::ActualizeTabletStatistics(TInstant now) {
- TInstant barierTime = now - Hive.GetTabletRestartWatchPeriod();
- Hive.ActualizeRestartStatistics(*Statistics.MutableRestartTimestamp(), barierTime.MilliSeconds());
-}
-
-ui64 TTabletInfo::GetRestartsPerPeriod(TInstant barrier) {
- const auto& array(Statistics.GetRestartTimestamp());
- ui64 restarts = 0;
- for (auto itRestart = array.rbegin(); (itRestart != array.rend()) && (TInstant::MilliSeconds(*itRestart) >= barrier); ++itRestart) {
- ++restarts;
- }
- return restarts;
-}
-
-} // NHive
-} // NKikimr
+ if (local) {
+ Hive.StopTablet(local, tabletId);
+ }
+}
+
+TString TTabletInfo::GetLogPrefix() const {
+ return Hive.GetLogPrefix();
+}
+
+void TTabletInfo::ActualizeTabletStatistics(TInstant now) {
+ TInstant barierTime = now - Hive.GetTabletRestartWatchPeriod();
+ Hive.ActualizeRestartStatistics(*Statistics.MutableRestartTimestamp(), barierTime.MilliSeconds());
+}
+
+ui64 TTabletInfo::GetRestartsPerPeriod(TInstant barrier) {
+ const auto& array(Statistics.GetRestartTimestamp());
+ ui64 restarts = 0;
+ for (auto itRestart = array.rbegin(); (itRestart != array.rend()) && (TInstant::MilliSeconds(*itRestart) >= barrier); ++itRestart) {
+ ++restarts;
+ }
+ return restarts;
+}
+
+} // NHive
+} // NKikimr
diff --git a/ydb/core/mind/hive/tablet_info.h b/ydb/core/mind/hive/tablet_info.h
index 48e407c41b8..dc360a30e48 100644
--- a/ydb/core/mind/hive/tablet_info.h
+++ b/ydb/core/mind/hive/tablet_info.h
@@ -1,186 +1,186 @@
-#pragma once
-
-#include "hive.h"
-#include "metrics.h"
-
-namespace NKikimr {
-namespace NHive {
-
-struct TNodeInfo;
+#pragma once
+
+#include "hive.h"
+#include "metrics.h"
+
+namespace NKikimr {
+namespace NHive {
+
+struct TNodeInfo;
struct TLeaderTabletInfo;
struct TFollowerTabletInfo;
-
-struct TCounters {
- TVector<ui64> Simple;
- TVector<i64> SimpleDelta;
- TVector<ui64> Cumulative;
- TVector<ui64> CumulativeDelta;
-
- void UpdateCounters(const NKikimrTabletCountersAggregator::TTabletCounters& counters) {
- {
- size_t size = counters.SimpleCountersSize();
- Simple.resize(size);
- SimpleDelta.resize(size);
- for (size_t i = 0; i < size; ++i) {
- ui64 newValue = counters.GetSimpleCounters(i);
- i64 deltaValue = newValue - Simple[i];
- Simple[i] = newValue;
- SimpleDelta[i] = deltaValue;
- }
- }
- {
- size_t size = counters.CumulativeCountersSize();
- Cumulative.resize(Max(size, Cumulative.size()), 0);
- CumulativeDelta.resize(Max(size, CumulativeDelta.size()), 0);
- for (size_t i = 0; i < size; ++i) {
- ui64 newValue = counters.GetCumulativeCounters(i);
- ui64 deltaValue = Cumulative[i] <= newValue ? newValue - Cumulative[i] : newValue;
- Cumulative[i] = newValue;
- CumulativeDelta[i] = deltaValue;
- }
- }
- }
-
- void UpdateCounters(const TCounters& counters) {
- {
- size_t size = counters.Simple.size();
- Simple.resize(size);
- SimpleDelta.resize(size);
- for (size_t i = 0; i < size; ++i) {
- i64 deltaValue = counters.SimpleDelta[i];
- Simple[i] += deltaValue;
- SimpleDelta[i] = deltaValue;
- }
- }
- {
- size_t size = counters.CumulativeDelta.size();
- Cumulative.resize(Max(size, Cumulative.size()), 0);
- CumulativeDelta.resize(Max(size, CumulativeDelta.size()), 0);
- for (size_t i = 0; i < size; ++i) {
- ui64 deltaValue = counters.CumulativeDelta[i];
- Cumulative[i] += deltaValue;
- CumulativeDelta[i] = deltaValue;
- }
- }
- }
-};
-
-struct TTabletCountersInfo {
- TCounters ExecutorCounters;
- TCounters AppCounters;
-
- void UpdateCounters(const NKikimrTabletCountersAggregator::TTabletCountersInfo& countersInfo) {
- if (countersInfo.HasExecutorCounters())
- ExecutorCounters.UpdateCounters(countersInfo.GetExecutorCounters());
- if (countersInfo.HasAppCounters())
- AppCounters.UpdateCounters(countersInfo.GetAppCounters());
- }
-};
-
-struct TTabletDebugState {
- ui32 NodesDead = 0;
- ui32 NodesDown = 0;
- ui32 NodesNotAllowed = 0;
- ui32 NodesInDatacentersNotAllowed = 0;
+
+struct TCounters {
+ TVector<ui64> Simple;
+ TVector<i64> SimpleDelta;
+ TVector<ui64> Cumulative;
+ TVector<ui64> CumulativeDelta;
+
+ void UpdateCounters(const NKikimrTabletCountersAggregator::TTabletCounters& counters) {
+ {
+ size_t size = counters.SimpleCountersSize();
+ Simple.resize(size);
+ SimpleDelta.resize(size);
+ for (size_t i = 0; i < size; ++i) {
+ ui64 newValue = counters.GetSimpleCounters(i);
+ i64 deltaValue = newValue - Simple[i];
+ Simple[i] = newValue;
+ SimpleDelta[i] = deltaValue;
+ }
+ }
+ {
+ size_t size = counters.CumulativeCountersSize();
+ Cumulative.resize(Max(size, Cumulative.size()), 0);
+ CumulativeDelta.resize(Max(size, CumulativeDelta.size()), 0);
+ for (size_t i = 0; i < size; ++i) {
+ ui64 newValue = counters.GetCumulativeCounters(i);
+ ui64 deltaValue = Cumulative[i] <= newValue ? newValue - Cumulative[i] : newValue;
+ Cumulative[i] = newValue;
+ CumulativeDelta[i] = deltaValue;
+ }
+ }
+ }
+
+ void UpdateCounters(const TCounters& counters) {
+ {
+ size_t size = counters.Simple.size();
+ Simple.resize(size);
+ SimpleDelta.resize(size);
+ for (size_t i = 0; i < size; ++i) {
+ i64 deltaValue = counters.SimpleDelta[i];
+ Simple[i] += deltaValue;
+ SimpleDelta[i] = deltaValue;
+ }
+ }
+ {
+ size_t size = counters.CumulativeDelta.size();
+ Cumulative.resize(Max(size, Cumulative.size()), 0);
+ CumulativeDelta.resize(Max(size, CumulativeDelta.size()), 0);
+ for (size_t i = 0; i < size; ++i) {
+ ui64 deltaValue = counters.CumulativeDelta[i];
+ Cumulative[i] += deltaValue;
+ CumulativeDelta[i] = deltaValue;
+ }
+ }
+ }
+};
+
+struct TTabletCountersInfo {
+ TCounters ExecutorCounters;
+ TCounters AppCounters;
+
+ void UpdateCounters(const NKikimrTabletCountersAggregator::TTabletCountersInfo& countersInfo) {
+ if (countersInfo.HasExecutorCounters())
+ ExecutorCounters.UpdateCounters(countersInfo.GetExecutorCounters());
+ if (countersInfo.HasAppCounters())
+ AppCounters.UpdateCounters(countersInfo.GetAppCounters());
+ }
+};
+
+struct TTabletDebugState {
+ ui32 NodesDead = 0;
+ ui32 NodesDown = 0;
+ ui32 NodesNotAllowed = 0;
+ ui32 NodesInDatacentersNotAllowed = 0;
bool LeaderNotRunning = false;
ui32 NodesWithLeaderNotLocal = 0;
- ui32 NodesWithoutDomain = 0;
+ ui32 NodesWithoutDomain = 0;
ui32 NodesFilledWithDatacenterFollowers = 0;
- ui32 NodesWithoutResources = 0;
- ui32 NodesWithSomeoneFromOurFamily = 0;
- ui32 NodesWithoutLocation = 0;
-};
-
-struct TTabletInfo {
- friend class TTxMonEvent_TabletInfo;
-public:
- using EVolatileState = NKikimrHive::ETabletVolatileState;
-
- enum class ETabletRole {
+ ui32 NodesWithoutResources = 0;
+ ui32 NodesWithSomeoneFromOurFamily = 0;
+ ui32 NodesWithoutLocation = 0;
+};
+
+struct TTabletInfo {
+ friend class TTxMonEvent_TabletInfo;
+public:
+ using EVolatileState = NKikimrHive::ETabletVolatileState;
+
+ enum class ETabletRole {
Leader,
Follower
- };
-
-protected:
- EVolatileState VolatileState;
- ETabletRole TabletRole;
- TInstant VolatileStateChangeTime;
- TInstant LastBalancerDecisionTime;
-
-public:
- static TString EVolatileStateName(EVolatileState value) {
- switch(value) {
- case EVolatileState::TABLET_VOLATILE_STATE_UNKNOWN: return "Unknown";
- case EVolatileState::TABLET_VOLATILE_STATE_STOPPED: return "Stopped";
- case EVolatileState::TABLET_VOLATILE_STATE_BOOTING: return "Booting";
- case EVolatileState::TABLET_VOLATILE_STATE_STARTING: return "Starting";
- case EVolatileState::TABLET_VOLATILE_STATE_RUNNING: return "Running";
- case EVolatileState::_TABLET_VOLATILE_STATE_BLOCKED: return "Blocked";
- default: return Sprintf("%d", static_cast<int>(value));
- }
- }
-
- static TString ETabletRoleName(ETabletRole value) {
- switch(value) {
+ };
+
+protected:
+ EVolatileState VolatileState;
+ ETabletRole TabletRole;
+ TInstant VolatileStateChangeTime;
+ TInstant LastBalancerDecisionTime;
+
+public:
+ static TString EVolatileStateName(EVolatileState value) {
+ switch(value) {
+ case EVolatileState::TABLET_VOLATILE_STATE_UNKNOWN: return "Unknown";
+ case EVolatileState::TABLET_VOLATILE_STATE_STOPPED: return "Stopped";
+ case EVolatileState::TABLET_VOLATILE_STATE_BOOTING: return "Booting";
+ case EVolatileState::TABLET_VOLATILE_STATE_STARTING: return "Starting";
+ case EVolatileState::TABLET_VOLATILE_STATE_RUNNING: return "Running";
+ case EVolatileState::_TABLET_VOLATILE_STATE_BLOCKED: return "Blocked";
+ default: return Sprintf("%d", static_cast<int>(value));
+ }
+ }
+
+ static TString ETabletRoleName(ETabletRole value) {
+ switch(value) {
case ETabletRole::Leader: return "Leader";
case ETabletRole::Follower: return "Follower";
- default: return Sprintf("%d", static_cast<int>(value));
- }
- }
-
- TInstant GetVolatileStateChangeTime() const {
- return VolatileStateChangeTime;
- }
-
- bool IsGoodForBalancer(TInstant now) const;
-
- void MakeBalancerDecision(TInstant now) {
- LastBalancerDecisionTime = now;
- }
-
- THive& Hive;
- TNodeId PreferredNodeId;
- TNodeId NodeId;
- TNodeInfo* Node;
- TNodeId LastNodeId;
- TTabletCountersInfo Counters;
- NKikimrHive::TTabletStatistics Statistics;
-
- TString GetLogPrefix() const;
-
-protected:
- NKikimrTabletBase::TMetrics ResourceValues; // current values of various metrics
- TTabletMetricsAggregates ResourceMetricsAggregates;
-
-public:
- TVector<TActorId> ActorsToNotify; // ...OnCreation persistent
- TVector<TActorId> ActorsToNotifyOnRestart; // volatile
- double Weight;
- mutable TString BootState;
- TInstant PostponedStart;
-
- TTabletInfo(ETabletRole role, THive& hive);
- TTabletInfo(const TTabletInfo&) = delete;
- TTabletInfo(TTabletInfo&&) = delete;
- TTabletInfo& operator =(const TTabletInfo&) = delete;
- TTabletInfo& operator =(TTabletInfo&&) = delete;
-
- bool operator ==(const TTabletInfo& tablet) const {
- return this == &tablet;
- }
-
- EVolatileState GetVolatileState() const {
- return VolatileState;
- }
-
+ default: return Sprintf("%d", static_cast<int>(value));
+ }
+ }
+
+ TInstant GetVolatileStateChangeTime() const {
+ return VolatileStateChangeTime;
+ }
+
+ bool IsGoodForBalancer(TInstant now) const;
+
+ void MakeBalancerDecision(TInstant now) {
+ LastBalancerDecisionTime = now;
+ }
+
+ THive& Hive;
+ TNodeId PreferredNodeId;
+ TNodeId NodeId;
+ TNodeInfo* Node;
+ TNodeId LastNodeId;
+ TTabletCountersInfo Counters;
+ NKikimrHive::TTabletStatistics Statistics;
+
+ TString GetLogPrefix() const;
+
+protected:
+ NKikimrTabletBase::TMetrics ResourceValues; // current values of various metrics
+ TTabletMetricsAggregates ResourceMetricsAggregates;
+
+public:
+ TVector<TActorId> ActorsToNotify; // ...OnCreation persistent
+ TVector<TActorId> ActorsToNotifyOnRestart; // volatile
+ double Weight;
+ mutable TString BootState;
+ TInstant PostponedStart;
+
+ TTabletInfo(ETabletRole role, THive& hive);
+ TTabletInfo(const TTabletInfo&) = delete;
+ TTabletInfo(TTabletInfo&&) = delete;
+ TTabletInfo& operator =(const TTabletInfo&) = delete;
+ TTabletInfo& operator =(TTabletInfo&&) = delete;
+
+ bool operator ==(const TTabletInfo& tablet) const {
+ return this == &tablet;
+ }
+
+ EVolatileState GetVolatileState() const {
+ return VolatileState;
+ }
+
bool IsLeader() const {
return TabletRole == ETabletRole::Leader;
- }
-
+ }
+
bool IsFollower() const {
return TabletRole == ETabletRole::Follower;
- }
-
+ }
+
const TLeaderTabletInfo& GetLeader() const;
TLeaderTabletInfo& GetLeader();
TLeaderTabletInfo& AsLeader();
@@ -188,95 +188,95 @@ public:
TFollowerTabletInfo& AsFollower();
const TFollowerTabletInfo& AsFollower() const;
std::pair<TTabletId, TFollowerId> GetFullTabletId() const;
- TObjectId GetObjectId() const;
- TTabletTypes::EType GetTabletType() const;
- TString ToString() const;
- TString StateString() const;
- TString FamilyString() const;
- void ChangeVolatileState(EVolatileState state);
-
- bool IsReadyToBoot() const {
- return NodeId == 0 && VolatileState == EVolatileState::TABLET_VOLATILE_STATE_STOPPED;
- }
-
- bool IsReadyToStart(TInstant now) const;
- bool IsStarting() const;
- bool IsStartingOnNode(TNodeId nodeId) const;
- bool IsRunning() const;
- bool IsBooting() const;
- bool IsAlive() const;
- bool CanBeAlive() const; // IsAlive() + <Unknown>
-
+ TObjectId GetObjectId() const;
+ TTabletTypes::EType GetTabletType() const;
+ TString ToString() const;
+ TString StateString() const;
+ TString FamilyString() const;
+ void ChangeVolatileState(EVolatileState state);
+
+ bool IsReadyToBoot() const {
+ return NodeId == 0 && VolatileState == EVolatileState::TABLET_VOLATILE_STATE_STOPPED;
+ }
+
+ bool IsReadyToStart(TInstant now) const;
+ bool IsStarting() const;
+ bool IsStartingOnNode(TNodeId nodeId) const;
+ bool IsRunning() const;
+ bool IsBooting() const;
+ bool IsAlive() const;
+ bool CanBeAlive() const; // IsAlive() + <Unknown>
+
bool IsAliveOnLocal(const TActorId& local) const;
- bool IsStopped() const;
- bool InitiateBoot();
- bool BecomeStarting(TNodeId nodeId);
- bool BecomeRunning(TNodeId nodeId);
- bool BecomeStopped();
-
+ bool IsStopped() const;
+ bool InitiateBoot();
+ bool BecomeStarting(TNodeId nodeId);
+ bool BecomeRunning(TNodeId nodeId);
+ bool BecomeStopped();
+
void SendStopTablet(const TActorId& local, TFullTabletId tabletId);
-
- bool InitiateStop();
-
- void BecomeUnknown(TNodeInfo* node);
- bool Kick();
- void Kill();
- const TVector<i64>& GetTabletAllowedMetricIds() const;
-
- void UpdateResourceUsage(const NKikimrTabletBase::TMetrics& metrics);
- TResourceRawValues GetResourceCurrentValues() const;
- TResourceRawValues GetResourceMaximumValues() const;
- static i64 GetCounterValue(const NKikimrTabletBase::TMetrics& metrics, const TVector<i64>& allowedMetricIds);
- void FilterRawValues(TResourceRawValues& values) const;
- void FilterRawValues(TResourceNormalizedValues& values) const;
-
- template <typename ResourcesType>
- static double GetUsage(const ResourcesType& current, const ResourcesType& maximum) {
- return max(NormalizeRawValues(current, maximum));
- }
-
+
+ bool InitiateStop();
+
+ void BecomeUnknown(TNodeInfo* node);
+ bool Kick();
+ void Kill();
+ const TVector<i64>& GetTabletAllowedMetricIds() const;
+
+ void UpdateResourceUsage(const NKikimrTabletBase::TMetrics& metrics);
+ TResourceRawValues GetResourceCurrentValues() const;
+ TResourceRawValues GetResourceMaximumValues() const;
+ static i64 GetCounterValue(const NKikimrTabletBase::TMetrics& metrics, const TVector<i64>& allowedMetricIds);
+ void FilterRawValues(TResourceRawValues& values) const;
+ void FilterRawValues(TResourceNormalizedValues& values) const;
+
+ template <typename ResourcesType>
+ static double GetUsage(const ResourcesType& current, const ResourcesType& maximum) {
+ return max(NormalizeRawValues(current, maximum));
+ }
+
void UpdateWeight() {
- TResourceRawValues current = GetResourceCurrentValues();
- TResourceRawValues maximum = GetResourceMaximumValues();
- FilterRawValues(current);
- FilterRawValues(maximum);
-
+ TResourceRawValues current = GetResourceCurrentValues();
+ TResourceRawValues maximum = GetResourceMaximumValues();
+ FilterRawValues(current);
+ FilterRawValues(maximum);
+
Weight = GetUsage(current, maximum);
- }
-
- void PostponeStart(TInstant nextStart) {
- PostponedStart = nextStart;
- }
-
- const TVector<TNodeId>& GetAllowedNodes() const;
- const TVector<TDataCenterId>& GetAllowedDataCenters() const;
- bool InitiateStart(TNodeInfo* node);
-
- const NKikimrTabletBase::TMetrics& GetResourceValues() const {
- return ResourceValues;
- }
-
- void InitTabletMetrics() {
- ResourceValues.SetCounter(1);
- }
-
- const TTabletMetricsAggregates& GetResourceMetricsAggregates() const {
- return ResourceMetricsAggregates;
- }
-
- TTabletMetricsAggregates& MutableResourceMetricsAggregates() {
- return ResourceMetricsAggregates;
- }
-
- /*NKikimrTabletBase::TMetrics& GetMutableResourceValues() {
- return ResourceValues;
- }*/
-
- void ActualizeTabletStatistics(TInstant now);
- ui64 GetRestartsPerPeriod(TInstant barrier);
-};
-
-
-} // NHive
-} // NKikimr
-
+ }
+
+ void PostponeStart(TInstant nextStart) {
+ PostponedStart = nextStart;
+ }
+
+ const TVector<TNodeId>& GetAllowedNodes() const;
+ const TVector<TDataCenterId>& GetAllowedDataCenters() const;
+ bool InitiateStart(TNodeInfo* node);
+
+ const NKikimrTabletBase::TMetrics& GetResourceValues() const {
+ return ResourceValues;
+ }
+
+ void InitTabletMetrics() {
+ ResourceValues.SetCounter(1);
+ }
+
+ const TTabletMetricsAggregates& GetResourceMetricsAggregates() const {
+ return ResourceMetricsAggregates;
+ }
+
+ TTabletMetricsAggregates& MutableResourceMetricsAggregates() {
+ return ResourceMetricsAggregates;
+ }
+
+ /*NKikimrTabletBase::TMetrics& GetMutableResourceValues() {
+ return ResourceValues;
+ }*/
+
+ void ActualizeTabletStatistics(TInstant now);
+ ui64 GetRestartsPerPeriod(TInstant barrier);
+};
+
+
+} // NHive
+} // NKikimr
+
diff --git a/ydb/core/mind/hive/tx__adopt_tablet.cpp b/ydb/core/mind/hive/tx__adopt_tablet.cpp
index 072dc5232ec..45203af0d1f 100644
--- a/ydb/core/mind/hive/tx__adopt_tablet.cpp
+++ b/ydb/core/mind/hive/tx__adopt_tablet.cpp
@@ -1,10 +1,10 @@
-#include "hive_impl.h"
-#include "hive_log.h"
+#include "hive_impl.h"
+#include "hive_log.h"
namespace NKikimr {
-namespace NHive {
+namespace NHive {
-class TTxAdoptTablet : public TTransactionBase<THive> {
+class TTxAdoptTablet : public TTransactionBase<THive> {
const ui64 TabletId;
const ui64 PrevOwner;
const ui64 PrevOwnerIdx;
@@ -37,7 +37,7 @@ public:
TTxType GetTxType() const override { return NHive::TXTYPE_ADOPT_TABLET; }
bool Execute(TTransactionContext &txc, const TActorContext&) override {
- BLOG_D("THive::TTxAdoptTablet::Execute");
+ BLOG_D("THive::TTxAdoptTablet::Execute");
NIceDb::TNiceDb db(txc.DB);
const TOwnerIdxType::TValueType prevOwner(PrevOwner, PrevOwnerIdx);
@@ -55,17 +55,17 @@ public:
}
TLeaderTabletInfo* tablet = Self->FindTablet(tabletId);
- if (tablet != nullptr && tablet->Type != TabletType) {
+ if (tablet != nullptr && tablet->Type != TabletType) {
Explain = "there is the tablet with different type assotiated with the (owner; ownerIdx)";
Status = NKikimrProto::EReplyStatus::RACE;
return true;
}
- if (tablet != nullptr) {
- Explain = "it seems like the tablet aleready adopted";
- Status = NKikimrProto::EReplyStatus::ALREADY;
- return true;
- }
+ if (tablet != nullptr) {
+ Explain = "it seems like the tablet aleready adopted";
+ Status = NKikimrProto::EReplyStatus::ALREADY;
+ return true;
+ }
}
}
@@ -84,7 +84,7 @@ public:
}
TLeaderTabletInfo* tablet = Self->FindTablet(tabletId);
- if (tablet != nullptr && tablet->Type != TabletType) { // tablet is the same
+ if (tablet != nullptr && tablet->Type != TabletType) { // tablet is the same
Explain = "there is the tablet with different type assotiated with the (preOwner; prevOwnerIdx)";
Status = NKikimrProto::EReplyStatus::ERROR;
return true;
@@ -101,9 +101,9 @@ public:
}
void Complete(const TActorContext& ctx) override {
- BLOG_D("THive::TTxAdoptTablet::Complete TabletId: " << TabletId <<
- " Status: " << NKikimrProto::EReplyStatus_Name(Status) <<
- " Explain: " << Explain);
+ BLOG_D("THive::TTxAdoptTablet::Complete TabletId: " << TabletId <<
+ " Status: " << NKikimrProto::EReplyStatus_Name(Status) <<
+ " Explain: " << Explain);
ctx.Send(Sender, new TEvHive::TEvAdoptTabletReply(Status, TabletId, Owner, OwnerIdx, Explain, Self->TabletID()), 0, Cookie);;
}
@@ -114,5 +114,5 @@ ITransaction* THive::CreateAdoptTablet(NKikimrHive::TEvAdoptTablet &rec, const T
return new TTxAdoptTablet(rec, sender, cookie, this);
}
-} // NHive
-} // NKikimr
+} // NHive
+} // NKikimr
diff --git a/ydb/core/mind/hive/tx__block_storage_result.cpp b/ydb/core/mind/hive/tx__block_storage_result.cpp
index 853cb8cc7f8..28315ec93bd 100644
--- a/ydb/core/mind/hive/tx__block_storage_result.cpp
+++ b/ydb/core/mind/hive/tx__block_storage_result.cpp
@@ -1,74 +1,74 @@
-#include "hive_impl.h"
-#include "hive_log.h"
-
-namespace NKikimr {
-namespace NHive {
-
-class TTxBlockStorageResult : public TTransactionBase<THive> {
- TEvTabletBase::TEvBlockBlobStorageResult::TPtr Result;
- TTabletId TabletId;
-public:
- TTxBlockStorageResult(TEvTabletBase::TEvBlockBlobStorageResult::TPtr& ev, THive* hive)
- : TBase(hive)
- , Result(ev)
- , TabletId(Result->Get()->TabletId)
- {}
-
- TTxType GetTxType() const override { return NHive::TXTYPE_BLOCK_STORAGE_RESULT; }
-
+#include "hive_impl.h"
+#include "hive_log.h"
+
+namespace NKikimr {
+namespace NHive {
+
+class TTxBlockStorageResult : public TTransactionBase<THive> {
+ TEvTabletBase::TEvBlockBlobStorageResult::TPtr Result;
+ TTabletId TabletId;
+public:
+ TTxBlockStorageResult(TEvTabletBase::TEvBlockBlobStorageResult::TPtr& ev, THive* hive)
+ : TBase(hive)
+ , Result(ev)
+ , TabletId(Result->Get()->TabletId)
+ {}
+
+ TTxType GetTxType() const override { return NHive::TXTYPE_BLOCK_STORAGE_RESULT; }
+
bool Execute(TTransactionContext& txc, const TActorContext&) override {
- TEvTabletBase::TEvBlockBlobStorageResult* msg = Result->Get();
- BLOG_D("THive::TTxBlockStorageResult::Execute(" << TabletId << " " << NKikimrProto::EReplyStatus_Name(msg->Status) << ")");
+ TEvTabletBase::TEvBlockBlobStorageResult* msg = Result->Get();
+ BLOG_D("THive::TTxBlockStorageResult::Execute(" << TabletId << " " << NKikimrProto::EReplyStatus_Name(msg->Status) << ")");
TLeaderTabletInfo* tablet = Self->FindTabletEvenInDeleting(TabletId);
- if (tablet != nullptr) {
- NIceDb::TNiceDb db(txc.DB);
- if (msg->Status == NKikimrProto::OK) {
- if (tablet->State == ETabletState::BlockStorage) {
- db.Table<Schema::Tablet>().Key(tablet->Id).Update(NIceDb::TUpdate<Schema::Tablet::State>(ETabletState::ReadyToWork));
- } else if (tablet->State == ETabletState::Deleting) {
+ if (tablet != nullptr) {
+ NIceDb::TNiceDb db(txc.DB);
+ if (msg->Status == NKikimrProto::OK) {
+ if (tablet->State == ETabletState::BlockStorage) {
+ db.Table<Schema::Tablet>().Key(tablet->Id).Update(NIceDb::TUpdate<Schema::Tablet::State>(ETabletState::ReadyToWork));
+ } else if (tablet->State == ETabletState::Deleting) {
for (TFollowerTabletInfo& follower : tablet->Followers) {
follower.InitiateStop();
- }
- }
- }
- }
- return true;
- }
-
+ }
+ }
+ }
+ }
+ return true;
+ }
+
void Complete(const TActorContext& ctx) override {
- TEvTabletBase::TEvBlockBlobStorageResult* msg = Result->Get();
- BLOG_D("THive::TTxBlockStorageResult::Complete(" << TabletId << " " << NKikimrProto::EReplyStatus_Name(msg->Status) << ")");
+ TEvTabletBase::TEvBlockBlobStorageResult* msg = Result->Get();
+ BLOG_D("THive::TTxBlockStorageResult::Complete(" << TabletId << " " << NKikimrProto::EReplyStatus_Name(msg->Status) << ")");
TLeaderTabletInfo* tablet = Self->FindTabletEvenInDeleting(TabletId);
- if (tablet != nullptr) {
+ if (tablet != nullptr) {
if (msg->Status == NKikimrProto::OK
|| msg->Status == NKikimrProto::RACE
|| msg->Status == NKikimrProto::BLOCKED
|| msg->Status == NKikimrProto::NO_GROUP) {
- if (tablet->IsDeleting()) {
- if (msg->Status != NKikimrProto::EReplyStatus::OK) {
- BLOG_W("THive::TTxBlockStorageResult Complete status was " << NKikimrProto::EReplyStatus_Name(msg->Status) << " for TabletId " << tablet->Id);
- }
+ if (tablet->IsDeleting()) {
+ if (msg->Status != NKikimrProto::EReplyStatus::OK) {
+ BLOG_W("THive::TTxBlockStorageResult Complete status was " << NKikimrProto::EReplyStatus_Name(msg->Status) << " for TabletId " << tablet->Id);
+ }
ctx.Send(Self->SelfId(), new TEvHive::TEvInitiateDeleteStorage(tablet->Id));
- } else {
- tablet->State = ETabletState::ReadyToWork;
+ } else {
+ tablet->State = ETabletState::ReadyToWork;
if (tablet->IsBootingSuppressed()) {
// Use best effort to kill currently running tablet
ctx.Register(CreateTabletKiller(TabletId, /* nodeId */ 0, tablet->KnownGeneration));
} else {
- Self->Execute(Self->CreateRestartTablet(tablet->GetFullTabletId()));
+ Self->Execute(Self->CreateRestartTablet(tablet->GetFullTabletId()));
}
- }
- } else {
- BLOG_W("THive::TTxBlockStorageResult retrying for " << TabletId << " because of " << NKikimrProto::EReplyStatus_Name(msg->Status));
- ctx.Schedule(TDuration::MilliSeconds(1000), new TEvHive::TEvInitiateBlockStorage(tablet->Id));
- }
- }
- }
-};
-
+ }
+ } else {
+ BLOG_W("THive::TTxBlockStorageResult retrying for " << TabletId << " because of " << NKikimrProto::EReplyStatus_Name(msg->Status));
+ ctx.Schedule(TDuration::MilliSeconds(1000), new TEvHive::TEvInitiateBlockStorage(tablet->Id));
+ }
+ }
+ }
+};
+
ITransaction* THive::CreateBlockStorageResult(TEvTabletBase::TEvBlockBlobStorageResult::TPtr& ev) {
- return new TTxBlockStorageResult(ev, this);
-}
-
-} // NHive
-} // NKikimr
+ return new TTxBlockStorageResult(ev, this);
+}
+
+} // NHive
+} // NKikimr
diff --git a/ydb/core/mind/hive/tx__configure_subdomain.cpp b/ydb/core/mind/hive/tx__configure_subdomain.cpp
index f721ede03ce..7ad28aa4e0e 100644
--- a/ydb/core/mind/hive/tx__configure_subdomain.cpp
+++ b/ydb/core/mind/hive/tx__configure_subdomain.cpp
@@ -1,44 +1,44 @@
-#include "hive_impl.h"
-#include "hive_log.h"
-
-namespace NKikimr {
-namespace NHive {
-
-class TTxConfigureSubdomain : public TTransactionBase<THive> {
-private:
- TEvHive::TEvConfigureHive::TPtr Event;
-
-public:
- TTxConfigureSubdomain(TEvHive::TEvConfigureHive::TPtr event, THive* hive)
- : TBase(hive)
- , Event(std::move(event))
- {}
-
- TTxType GetTxType() const override { return NHive::TXTYPE_CONFIGURE_SUBDOMAIN; }
-
- bool Execute(TTransactionContext& txc, const TActorContext&) override {
- BLOG_D("THive::TTxConfigureSubdomain::Execute");
-
- const auto& domain(Event->Get()->Record.GetDomain());
- Self->PrimaryDomainKey = TSubDomainKey(domain);
-
- BLOG_D("Switching primary domain to " << domain);
-
- NIceDb::TNiceDb db(txc.DB);
- db.Table<Schema::SubDomain>().Key(domain.GetSchemeShard(), domain.GetPathId()).Update<Schema::SubDomain::Primary>(true);
-
- return true;
- }
-
- void Complete(const TActorContext& ctx) override {
- BLOG_D("THive::TTxConfigureSubdomain::Complete");
- ctx.Send(Event->Sender, new TEvSubDomain::TEvConfigureStatus(NKikimrTx::TEvSubDomainConfigurationAck::SUCCESS, Self->TabletID()));
- }
-};
-
-ITransaction* THive::CreateConfigureSubdomain(TEvHive::TEvConfigureHive::TPtr event) {
- return new TTxConfigureSubdomain(std::move(event), this);
-}
-
-} // NHive
-} // NKikimr
+#include "hive_impl.h"
+#include "hive_log.h"
+
+namespace NKikimr {
+namespace NHive {
+
+class TTxConfigureSubdomain : public TTransactionBase<THive> {
+private:
+ TEvHive::TEvConfigureHive::TPtr Event;
+
+public:
+ TTxConfigureSubdomain(TEvHive::TEvConfigureHive::TPtr event, THive* hive)
+ : TBase(hive)
+ , Event(std::move(event))
+ {}
+
+ TTxType GetTxType() const override { return NHive::TXTYPE_CONFIGURE_SUBDOMAIN; }
+
+ bool Execute(TTransactionContext& txc, const TActorContext&) override {
+ BLOG_D("THive::TTxConfigureSubdomain::Execute");
+
+ const auto& domain(Event->Get()->Record.GetDomain());
+ Self->PrimaryDomainKey = TSubDomainKey(domain);
+
+ BLOG_D("Switching primary domain to " << domain);
+
+ NIceDb::TNiceDb db(txc.DB);
+ db.Table<Schema::SubDomain>().Key(domain.GetSchemeShard(), domain.GetPathId()).Update<Schema::SubDomain::Primary>(true);
+
+ return true;
+ }
+
+ void Complete(const TActorContext& ctx) override {
+ BLOG_D("THive::TTxConfigureSubdomain::Complete");
+ ctx.Send(Event->Sender, new TEvSubDomain::TEvConfigureStatus(NKikimrTx::TEvSubDomainConfigurationAck::SUCCESS, Self->TabletID()));
+ }
+};
+
+ITransaction* THive::CreateConfigureSubdomain(TEvHive::TEvConfigureHive::TPtr event) {
+ return new TTxConfigureSubdomain(std::move(event), this);
+}
+
+} // NHive
+} // NKikimr
diff --git a/ydb/core/mind/hive/tx__create_tablet.cpp b/ydb/core/mind/hive/tx__create_tablet.cpp
index f1c01060d11..f3b27bfd9ac 100644
--- a/ydb/core/mind/hive/tx__create_tablet.cpp
+++ b/ydb/core/mind/hive/tx__create_tablet.cpp
@@ -1,62 +1,62 @@
-#include "hive_impl.h"
-#include "hive_log.h"
-
-namespace NKikimr {
-namespace NHive {
-
-class TTxCreateTablet : public TTransactionBase<THive> {
- NKikimrHive::TEvCreateTablet RequestData;
- const ui64 OwnerId;
- const ui64 OwnerIdx;
- const TTabletTypes::EType TabletType;
- const ui32 AssignStateStorage;
-
+#include "hive_impl.h"
+#include "hive_log.h"
+
+namespace NKikimr {
+namespace NHive {
+
+class TTxCreateTablet : public TTransactionBase<THive> {
+ NKikimrHive::TEvCreateTablet RequestData;
+ const ui64 OwnerId;
+ const ui64 OwnerIdx;
+ const TTabletTypes::EType TabletType;
+ const ui32 AssignStateStorage;
+
const TActorId Sender;
- const ui64 Cookie;
-
- NKikimrProto::EReplyStatus Status;
+ const ui64 Cookie;
+
+ NKikimrProto::EReplyStatus Status;
NKikimrHive::EErrorReason ErrorReason;
- ui64 TabletId;
- TObjectId ObjectId;
- TSubDomainKey ObjectDomain;
-
- TChannelsBindings BoundChannels;
- TVector<TNodeId> AllowedNodeIds;
- TVector<TDataCenterId> AllowedDataCenterIds;
- NKikimrHive::TDataCentersPreference DataCentersPreference;
- TVector<TSubDomainKey> AllowedDomains;
- ETabletState State;
- NKikimrHive::TTabletCategory TabletCategory;
+ ui64 TabletId;
+ TObjectId ObjectId;
+ TSubDomainKey ObjectDomain;
+
+ TChannelsBindings BoundChannels;
+ TVector<TNodeId> AllowedNodeIds;
+ TVector<TDataCenterId> AllowedDataCenterIds;
+ NKikimrHive::TDataCentersPreference DataCentersPreference;
+ TVector<TSubDomainKey> AllowedDomains;
+ ETabletState State;
+ NKikimrHive::TTabletCategory TabletCategory;
TVector<NKikimrHive::TFollowerGroup> FollowerGroups;
NKikimrHive::ETabletBootMode BootMode;
- NKikimrHive::TForwardRequest ForwardRequest;
-
-public:
+ NKikimrHive::TForwardRequest ForwardRequest;
+
+public:
TTxCreateTablet(NKikimrHive::TEvCreateTablet record, const TActorId& sender, const ui64 cookie, THive* hive)
- : TBase(hive)
- , RequestData(std::move(record))
- , OwnerId(RequestData.GetOwner())
- , OwnerIdx(RequestData.GetOwnerIdx())
- , TabletType((TTabletTypes::EType)RequestData.GetTabletType())
- , AssignStateStorage(RequestData.HasAssignStateStorage() ? RequestData.GetAssignStateStorage() :
- StateStorageGroupFromTabletID(hive->TabletID()))
- , Sender(sender)
- , Cookie(cookie)
- , Status(NKikimrProto::UNKNOWN)
- , TabletId(0)
- , ObjectId(0)
- , ObjectDomain(RequestData.GetObjectDomain())
- , BoundChannels(RequestData.GetBindedChannels().begin(), RequestData.GetBindedChannels().end())
- , AllowedDomains(RequestData.GetAllowedDomains().begin(), RequestData.GetAllowedDomains().end())
- , State(ETabletState::Unknown)
- , BootMode(RequestData.GetTabletBootMode())
- {
- const ui32 allowedNodeIdsSize = RequestData.AllowedNodeIDsSize();
- AllowedNodeIds.reserve(allowedNodeIdsSize);
- for (ui32 idx = 0; idx < allowedNodeIdsSize; ++idx) {
- AllowedNodeIds.push_back(RequestData.GetAllowedNodeIDs(idx));
- }
- Sort(AllowedNodeIds);
+ : TBase(hive)
+ , RequestData(std::move(record))
+ , OwnerId(RequestData.GetOwner())
+ , OwnerIdx(RequestData.GetOwnerIdx())
+ , TabletType((TTabletTypes::EType)RequestData.GetTabletType())
+ , AssignStateStorage(RequestData.HasAssignStateStorage() ? RequestData.GetAssignStateStorage() :
+ StateStorageGroupFromTabletID(hive->TabletID()))
+ , Sender(sender)
+ , Cookie(cookie)
+ , Status(NKikimrProto::UNKNOWN)
+ , TabletId(0)
+ , ObjectId(0)
+ , ObjectDomain(RequestData.GetObjectDomain())
+ , BoundChannels(RequestData.GetBindedChannels().begin(), RequestData.GetBindedChannels().end())
+ , AllowedDomains(RequestData.GetAllowedDomains().begin(), RequestData.GetAllowedDomains().end())
+ , State(ETabletState::Unknown)
+ , BootMode(RequestData.GetTabletBootMode())
+ {
+ const ui32 allowedNodeIdsSize = RequestData.AllowedNodeIDsSize();
+ AllowedNodeIds.reserve(allowedNodeIdsSize);
+ for (ui32 idx = 0; idx < allowedNodeIdsSize; ++idx) {
+ AllowedNodeIds.push_back(RequestData.GetAllowedNodeIDs(idx));
+ }
+ Sort(AllowedNodeIds);
if (const auto& x = RequestData.GetAllowedDataCenters(); !x.empty()) {
AllowedDataCenterIds.insert(AllowedDataCenterIds.end(), x.begin(), x.end());
@@ -64,13 +64,13 @@ public:
for (const auto& dataCenterId : RequestData.GetAllowedDataCenterNumIDs()) {
AllowedDataCenterIds.push_back(DataCenterToString(dataCenterId));
}
- }
- Sort(AllowedDataCenterIds);
+ }
+ Sort(AllowedDataCenterIds);
- DataCentersPreference = RequestData.GetDataCentersPreference();
- if (RequestData.HasTabletCategory()) {
- TabletCategory.CopyFrom(RequestData.GetTabletCategory());
- }
+ DataCentersPreference = RequestData.GetDataCentersPreference();
+ if (RequestData.HasTabletCategory()) {
+ TabletCategory.CopyFrom(RequestData.GetTabletCategory());
+ }
auto& followerGroups = RequestData.GetFollowerGroups();
std::copy(followerGroups.begin(), followerGroups.end(), std::back_inserter(FollowerGroups));
if (FollowerGroups.empty() &&
@@ -82,23 +82,23 @@ public:
NKikimrHive::TFollowerGroup& compatibilityGroup(FollowerGroups.back());
if (RequestData.HasAllowFollowerPromotion()) {
compatibilityGroup.SetAllowLeaderPromotion(RequestData.GetAllowFollowerPromotion());
- }
+ }
if (RequestData.HasCrossDataCenterFollowers()) {
- compatibilityGroup.SetFollowerCount(Self->GetDataCenters());
- compatibilityGroup.SetRequireAllDataCenters(true);
- }
+ compatibilityGroup.SetFollowerCount(Self->GetDataCenters());
+ compatibilityGroup.SetRequireAllDataCenters(true);
+ }
if (RequestData.HasCrossDataCenterFollowerCount()) {
- compatibilityGroup.SetFollowerCount(RequestData.GetCrossDataCenterFollowerCount() * Self->GetDataCenters());
- compatibilityGroup.SetRequireAllDataCenters(true);
- }
+ compatibilityGroup.SetFollowerCount(RequestData.GetCrossDataCenterFollowerCount() * Self->GetDataCenters());
+ compatibilityGroup.SetRequireAllDataCenters(true);
+ }
if (RequestData.HasFollowerCount()) {
compatibilityGroup.SetFollowerCount(RequestData.GetFollowerCount());
- }
- compatibilityGroup.SetAllowClientRead(true);
- }
- ObjectId = RequestData.GetObjectId();
- }
-
+ }
+ compatibilityGroup.SetAllowClientRead(true);
+ }
+ ObjectId = RequestData.GetObjectId();
+ }
+
void UpdateChannelsBinding(TLeaderTabletInfo& tablet, NIceDb::TNiceDb& db) {
Y_VERIFY(tablet.BoundChannels.size() <= BoundChannels.size(), "only expansion channels number is allowed in Binded Channels");
@@ -107,157 +107,157 @@ public:
// compare channel list with erasure and category information
for (ui32 channelId = 0; channelId < tablet.BoundChannels.size(); ++channelId) {
auto& channelA = tablet.BoundChannels[channelId];
- auto channelB = BoundChannels[channelId]; // copy, not reference
- Self->InitDefaultChannelBind(channelB);
- if (channelA.SerializeAsString() != channelB.SerializeAsString()) {
- db.Table<Schema::TabletChannel>().Key(TabletId, channelId).Update<Schema::TabletChannel::StoragePool>(BoundChannels[channelId].GetStoragePoolName());
- db.Table<Schema::TabletChannel>().Key(TabletId, channelId).Update<Schema::TabletChannel::Binding>(BoundChannels[channelId]);
- db.Table<Schema::TabletChannel>().Key(TabletId, channelId).Update<Schema::TabletChannel::NeedNewGroup>(true);
+ auto channelB = BoundChannels[channelId]; // copy, not reference
+ Self->InitDefaultChannelBind(channelB);
+ if (channelA.SerializeAsString() != channelB.SerializeAsString()) {
+ db.Table<Schema::TabletChannel>().Key(TabletId, channelId).Update<Schema::TabletChannel::StoragePool>(BoundChannels[channelId].GetStoragePoolName());
+ db.Table<Schema::TabletChannel>().Key(TabletId, channelId).Update<Schema::TabletChannel::Binding>(BoundChannels[channelId]);
+ db.Table<Schema::TabletChannel>().Key(TabletId, channelId).Update<Schema::TabletChannel::NeedNewGroup>(true);
newChannels.set(channelId);
}
}
- // new channels found in the tablet profile
+ // new channels found in the tablet profile
for (ui32 channelId = tablet.BoundChannels.size(); channelId < BoundChannels.size(); ++channelId) {
- auto channel = BoundChannels[channelId]; // copy, not reference
- Self->InitDefaultChannelBind(channel);
- db.Table<Schema::TabletChannel>().Key(TabletId, channelId).Update<Schema::TabletChannel::StoragePool>(BoundChannels[channelId].GetStoragePoolName());
- db.Table<Schema::TabletChannel>().Key(TabletId, channelId).Update<Schema::TabletChannel::Binding>(BoundChannels[channelId]);
- db.Table<Schema::TabletChannel>().Key(TabletId, channelId).Update<Schema::TabletChannel::NeedNewGroup>(true);
+ auto channel = BoundChannels[channelId]; // copy, not reference
+ Self->InitDefaultChannelBind(channel);
+ db.Table<Schema::TabletChannel>().Key(TabletId, channelId).Update<Schema::TabletChannel::StoragePool>(BoundChannels[channelId].GetStoragePoolName());
+ db.Table<Schema::TabletChannel>().Key(TabletId, channelId).Update<Schema::TabletChannel::Binding>(BoundChannels[channelId]);
+ db.Table<Schema::TabletChannel>().Key(TabletId, channelId).Update<Schema::TabletChannel::NeedNewGroup>(true);
newChannels.set(channelId);
}
if (newChannels.any()) {
tablet.ChannelProfileNewGroup |= newChannels;
tablet.State = State = ETabletState::GroupAssignment;
- tablet.ChannelProfileReassignReason = NKikimrHive::TEvReassignTablet::HIVE_REASSIGN_REASON_NO;
+ tablet.ChannelProfileReassignReason = NKikimrHive::TEvReassignTablet::HIVE_REASSIGN_REASON_NO;
tablet.BoundChannels = BoundChannels;
- for (auto& bind : tablet.BoundChannels) {
- Self->InitDefaultChannelBind(bind);
- }
- db.Table<Schema::Tablet>().Key(TabletId)
- .Update<Schema::Tablet::State, Schema::Tablet::ReassignReason, Schema::Tablet::ActorsToNotify>(
- State, NKikimrHive::TEvReassignTablet::HIVE_REASSIGN_REASON_NO, {Sender}
- );
+ for (auto& bind : tablet.BoundChannels) {
+ Self->InitDefaultChannelBind(bind);
+ }
+ db.Table<Schema::Tablet>().Key(TabletId)
+ .Update<Schema::Tablet::State, Schema::Tablet::ReassignReason, Schema::Tablet::ActorsToNotify>(
+ State, NKikimrHive::TEvReassignTablet::HIVE_REASSIGN_REASON_NO, {Sender}
+ );
Status = NKikimrProto::OK; // otherwise it would be ALREADY
}
}
bool ValidateChannelsBinding(TLeaderTabletInfo& tablet) {
- if (BoundChannels.size() < tablet.BoundChannels.size()) {
- ErrorReason = NKikimrHive::ERROR_REASON_CHANNELS_CANNOT_SHRINK;
- return false;
+ if (BoundChannels.size() < tablet.BoundChannels.size()) {
+ ErrorReason = NKikimrHive::ERROR_REASON_CHANNELS_CANNOT_SHRINK;
+ return false;
}
return true;
}
- TTxType GetTxType() const override { return NHive::TXTYPE_CREATE_TABLET; }
-
+ TTxType GetTxType() const override { return NHive::TXTYPE_CREATE_TABLET; }
+
bool Execute(TTransactionContext &txc, const TActorContext&) override {
- BLOG_D("THive::TTxCreateTablet::Execute");
- State = ETabletState::Unknown;
+ BLOG_D("THive::TTxCreateTablet::Execute");
+ State = ETabletState::Unknown;
ErrorReason = NKikimrHive::ERROR_REASON_UNKNOWN;
- for (const auto& domain : AllowedDomains) {
- if (!Self->SeenDomain(domain)) {
- ++Self->ConfigurationGeneration;
- }
- }
- if (ObjectDomain) {
- if (!Self->SeenDomain(ObjectDomain)) {
- ++Self->ConfigurationGeneration;
- }
- }
- if (Self->BlockedOwners.count(OwnerId) != 0) {
- Status = NKikimrProto::BLOCKED;
- BLOG_W("THive::TTxCreateTablet::Execute Owner " << OwnerId << " is blocked");
- return true;
- }
- NIceDb::TNiceDb db(txc.DB);
- // check if tablet is already created
- const TOwnerIdxType::TValueType ownerIdx(OwnerId, OwnerIdx);
- {
- auto itOwner = Self->OwnerToTablet.find(ownerIdx);
- if (itOwner != Self->OwnerToTablet.end()) { // tablet is already created
- const ui64 tabletId = itOwner->second;
+ for (const auto& domain : AllowedDomains) {
+ if (!Self->SeenDomain(domain)) {
+ ++Self->ConfigurationGeneration;
+ }
+ }
+ if (ObjectDomain) {
+ if (!Self->SeenDomain(ObjectDomain)) {
+ ++Self->ConfigurationGeneration;
+ }
+ }
+ if (Self->BlockedOwners.count(OwnerId) != 0) {
+ Status = NKikimrProto::BLOCKED;
+ BLOG_W("THive::TTxCreateTablet::Execute Owner " << OwnerId << " is blocked");
+ return true;
+ }
+ NIceDb::TNiceDb db(txc.DB);
+ // check if tablet is already created
+ const TOwnerIdxType::TValueType ownerIdx(OwnerId, OwnerIdx);
+ {
+ auto itOwner = Self->OwnerToTablet.find(ownerIdx);
+ if (itOwner != Self->OwnerToTablet.end()) { // tablet is already created
+ const ui64 tabletId = itOwner->second;
TLeaderTabletInfo* tablet = Self->FindTablet(tabletId);
- if (tablet != nullptr) {
- // make sure tablet type matches the requested one
- TTabletTypes::EType existingTabletType = tablet->Type;
- TabletId = tabletId;
- if (existingTabletType != TabletType || tablet->SeizedByChild) {
- if (tablet->SeizedByChild) {
- BLOG_D("THive::TTxCreateTablet::Execute Existing tablet " << tablet->ToString() << " seized by child - operation postponed");
- Status = NKikimrProto::UNKNOWN; // retry later
- } else {
- Status = NKikimrProto::ERROR;
- }
- } else {
- Status = NKikimrProto::ALREADY;
- }
- if (Status == NKikimrProto::ALREADY) {
- if (BootMode == NKikimrHive::TABLET_BOOT_MODE_EXTERNAL) {
- // Make sure any running tablets are stopped
+ if (tablet != nullptr) {
+ // make sure tablet type matches the requested one
+ TTabletTypes::EType existingTabletType = tablet->Type;
+ TabletId = tabletId;
+ if (existingTabletType != TabletType || tablet->SeizedByChild) {
+ if (tablet->SeizedByChild) {
+ BLOG_D("THive::TTxCreateTablet::Execute Existing tablet " << tablet->ToString() << " seized by child - operation postponed");
+ Status = NKikimrProto::UNKNOWN; // retry later
+ } else {
+ Status = NKikimrProto::ERROR;
+ }
+ } else {
+ Status = NKikimrProto::ALREADY;
+ }
+ if (Status == NKikimrProto::ALREADY) {
+ if (BootMode == NKikimrHive::TABLET_BOOT_MODE_EXTERNAL) {
+ // Make sure any running tablets are stopped
for (TFollowerTabletInfo& follower : tablet->Followers) {
follower.InitiateStop();
- }
- tablet->InitiateStop();
+ }
+ tablet->InitiateStop();
}
-
- State = tablet->State;
- if (State == ETabletState::StoppingInGroupAssignment) {
- BLOG_D("THive::TTxCreateTablet::Execute TabletId: " << TabletId <<
- " Status: " << (ui32)Status << " Stopping in group assignment");
- tablet->ActorsToNotify.push_back(Sender);
- tablet->BootMode = BootMode;
- db.Table<Schema::Tablet>().Key(TabletId).Update<Schema::Tablet::ActorsToNotify>(tablet->ActorsToNotify);
- db.Table<Schema::Tablet>().Key(TabletId).Update<Schema::Tablet::BootMode>(tablet->BootMode);
- if (tablet->State != ETabletState::GroupAssignment) {
- tablet->State = State = ETabletState::GroupAssignment;
- db.Table<Schema::Tablet>().Key(TabletId).Update<Schema::Tablet::State>(State);
- }
- return true;
- } else if (State == ETabletState::Stopping || State == ETabletState::Stopped) {
- BLOG_D("THive::TTxCreateTablet::Execute TabletId: " << TabletId <<
- " Status: " << (ui32)Status << " Stopping or Stopped");
- tablet->ActorsToNotify.push_back(Sender);
- tablet->BootMode = BootMode;
- db.Table<Schema::Tablet>().Key(TabletId).Update<Schema::Tablet::ActorsToNotify>(tablet->ActorsToNotify);
- db.Table<Schema::Tablet>().Key(TabletId).Update<Schema::Tablet::BootMode>(tablet->BootMode);
- if (tablet->State != ETabletState::ReadyToWork) {
- tablet->State = State = ETabletState::ReadyToWork;
- db.Table<Schema::Tablet>().Key(TabletId).Update<Schema::Tablet::State>(State);
- }
- return true;
- }
- } else {
- BLOG_D("THive::TTxCreateTablet::Execute TabletId: " << TabletId << " Status: " << Status);
- return true;
- }
-
- if (!ValidateChannelsBinding(*tablet)) {
- Status = NKikimrProto::ERROR;
- return true;
- }
-
- db.Table<Schema::Tablet>().Key(TabletId).Update<Schema::Tablet::State>(State);
- tablet->ActorsToNotify.push_back(Sender);
- db.Table<Schema::Tablet>().Key(TabletId).Update<Schema::Tablet::ActorsToNotify>(tablet->ActorsToNotify);
- tablet->AllowedNodes = AllowedNodeIds;
- db.Table<Schema::Tablet>().Key(TabletId).Update<Schema::Tablet::AllowedNodes>(tablet->AllowedNodes);
- tablet->AssignDomains(ObjectDomain, AllowedDomains);
- db.Table<Schema::Tablet>().Key(TabletId).Update<Schema::Tablet::ObjectDomain>(ObjectDomain);
- db.Table<Schema::Tablet>().Key(TabletId).Update<Schema::Tablet::AllowedDomains>(AllowedDomains);
- tablet->ObjectId = ObjectId;
- db.Table<Schema::Tablet>().Key(TabletId).Update<Schema::Tablet::ObjectID>(ObjectId);
- tablet->BootMode = BootMode;
- db.Table<Schema::Tablet>().Key(TabletId).Update<Schema::Tablet::BootMode>(BootMode);
-
- UpdateChannelsBinding(*tablet, db);
-
+
+ State = tablet->State;
+ if (State == ETabletState::StoppingInGroupAssignment) {
+ BLOG_D("THive::TTxCreateTablet::Execute TabletId: " << TabletId <<
+ " Status: " << (ui32)Status << " Stopping in group assignment");
+ tablet->ActorsToNotify.push_back(Sender);
+ tablet->BootMode = BootMode;
+ db.Table<Schema::Tablet>().Key(TabletId).Update<Schema::Tablet::ActorsToNotify>(tablet->ActorsToNotify);
+ db.Table<Schema::Tablet>().Key(TabletId).Update<Schema::Tablet::BootMode>(tablet->BootMode);
+ if (tablet->State != ETabletState::GroupAssignment) {
+ tablet->State = State = ETabletState::GroupAssignment;
+ db.Table<Schema::Tablet>().Key(TabletId).Update<Schema::Tablet::State>(State);
+ }
+ return true;
+ } else if (State == ETabletState::Stopping || State == ETabletState::Stopped) {
+ BLOG_D("THive::TTxCreateTablet::Execute TabletId: " << TabletId <<
+ " Status: " << (ui32)Status << " Stopping or Stopped");
+ tablet->ActorsToNotify.push_back(Sender);
+ tablet->BootMode = BootMode;
+ db.Table<Schema::Tablet>().Key(TabletId).Update<Schema::Tablet::ActorsToNotify>(tablet->ActorsToNotify);
+ db.Table<Schema::Tablet>().Key(TabletId).Update<Schema::Tablet::BootMode>(tablet->BootMode);
+ if (tablet->State != ETabletState::ReadyToWork) {
+ tablet->State = State = ETabletState::ReadyToWork;
+ db.Table<Schema::Tablet>().Key(TabletId).Update<Schema::Tablet::State>(State);
+ }
+ return true;
+ }
+ } else {
+ BLOG_D("THive::TTxCreateTablet::Execute TabletId: " << TabletId << " Status: " << Status);
+ return true;
+ }
+
+ if (!ValidateChannelsBinding(*tablet)) {
+ Status = NKikimrProto::ERROR;
+ return true;
+ }
+
+ db.Table<Schema::Tablet>().Key(TabletId).Update<Schema::Tablet::State>(State);
+ tablet->ActorsToNotify.push_back(Sender);
+ db.Table<Schema::Tablet>().Key(TabletId).Update<Schema::Tablet::ActorsToNotify>(tablet->ActorsToNotify);
+ tablet->AllowedNodes = AllowedNodeIds;
+ db.Table<Schema::Tablet>().Key(TabletId).Update<Schema::Tablet::AllowedNodes>(tablet->AllowedNodes);
+ tablet->AssignDomains(ObjectDomain, AllowedDomains);
+ db.Table<Schema::Tablet>().Key(TabletId).Update<Schema::Tablet::ObjectDomain>(ObjectDomain);
+ db.Table<Schema::Tablet>().Key(TabletId).Update<Schema::Tablet::AllowedDomains>(AllowedDomains);
+ tablet->ObjectId = ObjectId;
+ db.Table<Schema::Tablet>().Key(TabletId).Update<Schema::Tablet::ObjectID>(ObjectId);
+ tablet->BootMode = BootMode;
+ db.Table<Schema::Tablet>().Key(TabletId).Update<Schema::Tablet::BootMode>(BootMode);
+
+ UpdateChannelsBinding(*tablet, db);
+
auto itFollowerGroup = tablet->FollowerGroups.begin();
for (const auto& srcFollowerGroup : FollowerGroups) {
TFollowerGroup& followerGroup = itFollowerGroup != tablet->FollowerGroups.end() ? *itFollowerGroup : tablet->AddFollowerGroup();
- ui32 oldFollowerCount = followerGroup.GetComputedFollowerCount(Self->GetDataCenters());
+ ui32 oldFollowerCount = followerGroup.GetComputedFollowerCount(Self->GetDataCenters());
followerGroup = srcFollowerGroup;
TVector<ui32> allowedDataCenters;
@@ -274,155 +274,155 @@ public:
NIceDb::TUpdate<Schema::TabletFollowerGroup::RequireAllDataCenters>(followerGroup.RequireAllDataCenters),
NIceDb::TUpdate<Schema::TabletFollowerGroup::FollowerCountPerDataCenter>(followerGroup.FollowerCountPerDataCenter),
NIceDb::TUpdate<Schema::TabletFollowerGroup::RequireDifferentNodes>(followerGroup.RequireDifferentNodes));
-
- for (ui32 i = oldFollowerCount; i < followerGroup.GetComputedFollowerCount(Self->GetDataCenters()); ++i) {
+
+ for (ui32 i = oldFollowerCount; i < followerGroup.GetComputedFollowerCount(Self->GetDataCenters()); ++i) {
TFollowerTabletInfo& follower = tablet->AddFollower(followerGroup);
db.Table<Schema::TabletFollowerTablet>().Key(TabletId, follower.Id).Update(
NIceDb::TUpdate<Schema::TabletFollowerTablet::GroupID>(follower.FollowerGroup.Id),
NIceDb::TUpdate<Schema::TabletFollowerTablet::FollowerNode>(0));
follower.InitTabletMetrics();
follower.BecomeStopped();
- }
-
- for (ui32 i = followerGroup.GetComputedFollowerCount(Self->GetDataCenters()); i < oldFollowerCount; ++i) {
+ }
+
+ for (ui32 i = followerGroup.GetComputedFollowerCount(Self->GetDataCenters()); i < oldFollowerCount; ++i) {
TFollowerTabletInfo& follower = tablet->Followers.back();
db.Table<Schema::TabletFollowerTablet>().Key(TabletId, follower.Id).Delete();
follower.InitiateStop();
tablet->Followers.pop_back();
- }
+ }
++itFollowerGroup;
- }
-
- return true;
- }
- } else if (RequestData.HasTabletID()) {
- TTabletId tabletId = RequestData.GetTabletID();
- if (Self->CheckForForwardTabletRequest(tabletId, ForwardRequest)) {
- TabletId = tabletId;
- Status = NKikimrProto::INVALID_OWNER; // actually this status from blob storage, but I think it fits this situation perfectly
- return true; // abort transaction
- }
- }
- }
-
- switch((TTabletTypes::EType)TabletType) {
- case TTabletTypes::BSController:
- Status = NKikimrProto::ERROR;
- return true;
- default:
- break;
- };
-
- std::vector<TSequencer::TOwnerType> modified;
- auto tabletIdIndex = Self->Sequencer.AllocateElement(modified);
- if (tabletIdIndex == TSequencer::NO_ELEMENT) {
- Status = NKikimrProto::UNKNOWN;
- return true;
- } else {
- TabletId = MakeTabletID(AssignStateStorage, Self->HiveUid, tabletIdIndex);
- BLOG_D("Hive " << Self->TabletID() << " allocated TabletId " << TabletId << " from TabletIdIndex " << tabletIdIndex);
- Y_VERIFY(Self->Tablets.count(TabletId) == 0);
- for (auto owner : modified) {
- auto sequence = Self->Sequencer.GetSequence(owner);
- db.Table<Schema::Sequences>().Key(owner).Update(
- NIceDb::TUpdate<Schema::Sequences::Begin>(sequence.Begin),
- NIceDb::TUpdate<Schema::Sequences::Next>(sequence.Next),
- NIceDb::TUpdate<Schema::Sequences::End>(sequence.End));
- }
- ///// remove after upgrade to sub-hives
- Self->NextTabletId = tabletIdIndex + 1;
- db.Table<Schema::State>().Key(TSchemeIds::State::NextTabletId).Update<Schema::State::Value>(Self->NextTabletId);
- ///// remove after upgrade to sub-hives
- }
-
- TInstant now = TlsActivationContext->Now();
-
- // insert entry for new tablet
- State = ETabletState::GroupAssignment;
-
+ }
+
+ return true;
+ }
+ } else if (RequestData.HasTabletID()) {
+ TTabletId tabletId = RequestData.GetTabletID();
+ if (Self->CheckForForwardTabletRequest(tabletId, ForwardRequest)) {
+ TabletId = tabletId;
+ Status = NKikimrProto::INVALID_OWNER; // actually this status from blob storage, but I think it fits this situation perfectly
+ return true; // abort transaction
+ }
+ }
+ }
+
+ switch((TTabletTypes::EType)TabletType) {
+ case TTabletTypes::BSController:
+ Status = NKikimrProto::ERROR;
+ return true;
+ default:
+ break;
+ };
+
+ std::vector<TSequencer::TOwnerType> modified;
+ auto tabletIdIndex = Self->Sequencer.AllocateElement(modified);
+ if (tabletIdIndex == TSequencer::NO_ELEMENT) {
+ Status = NKikimrProto::UNKNOWN;
+ return true;
+ } else {
+ TabletId = MakeTabletID(AssignStateStorage, Self->HiveUid, tabletIdIndex);
+ BLOG_D("Hive " << Self->TabletID() << " allocated TabletId " << TabletId << " from TabletIdIndex " << tabletIdIndex);
+ Y_VERIFY(Self->Tablets.count(TabletId) == 0);
+ for (auto owner : modified) {
+ auto sequence = Self->Sequencer.GetSequence(owner);
+ db.Table<Schema::Sequences>().Key(owner).Update(
+ NIceDb::TUpdate<Schema::Sequences::Begin>(sequence.Begin),
+ NIceDb::TUpdate<Schema::Sequences::Next>(sequence.Next),
+ NIceDb::TUpdate<Schema::Sequences::End>(sequence.End));
+ }
+ ///// remove after upgrade to sub-hives
+ Self->NextTabletId = tabletIdIndex + 1;
+ db.Table<Schema::State>().Key(TSchemeIds::State::NextTabletId).Update<Schema::State::Value>(Self->NextTabletId);
+ ///// remove after upgrade to sub-hives
+ }
+
+ TInstant now = TlsActivationContext->Now();
+
+ // insert entry for new tablet
+ State = ETabletState::GroupAssignment;
+
TLeaderTabletInfo& tablet = Self->GetTablet(TabletId);
- tablet.NodeId = 0;
- tablet.Type = (TTabletTypes::EType)TabletType;
- tablet.KnownGeneration = 0; // because we will increase it on start
- tablet.State = State;
- tablet.ActorsToNotify.push_back(Sender);
- tablet.AllowedNodes = AllowedNodeIds;
- tablet.Owner = ownerIdx;
- tablet.AllowedDataCenters = AllowedDataCenterIds;
- tablet.DataCentersPreference = DataCentersPreference;
+ tablet.NodeId = 0;
+ tablet.Type = (TTabletTypes::EType)TabletType;
+ tablet.KnownGeneration = 0; // because we will increase it on start
+ tablet.State = State;
+ tablet.ActorsToNotify.push_back(Sender);
+ tablet.AllowedNodes = AllowedNodeIds;
+ tablet.Owner = ownerIdx;
+ tablet.AllowedDataCenters = AllowedDataCenterIds;
+ tablet.DataCentersPreference = DataCentersPreference;
tablet.BootMode = BootMode;
- tablet.ObjectId = ObjectId;
- tablet.AssignDomains(ObjectDomain, AllowedDomains);
- tablet.Statistics.SetLastAliveTimestamp(now.MilliSeconds());
-
+ tablet.ObjectId = ObjectId;
+ tablet.AssignDomains(ObjectDomain, AllowedDomains);
+ tablet.Statistics.SetLastAliveTimestamp(now.MilliSeconds());
+
TVector<ui32> allowedDataCenters;
for (const TDataCenterId& dc : tablet.AllowedDataCenters) {
allowedDataCenters.push_back(DataCenterFromString(dc));
}
- db.Table<Schema::Tablet>().Key(TabletId).Update(NIceDb::TUpdate<Schema::Tablet::Owner>(tablet.Owner),
+ db.Table<Schema::Tablet>().Key(TabletId).Update(NIceDb::TUpdate<Schema::Tablet::Owner>(tablet.Owner),
NIceDb::TUpdate<Schema::Tablet::LeaderNode>(tablet.NodeId),
- NIceDb::TUpdate<Schema::Tablet::TabletType>(tablet.Type),
- NIceDb::TUpdate<Schema::Tablet::KnownGeneration>(tablet.KnownGeneration),
- NIceDb::TUpdate<Schema::Tablet::State>(tablet.State),
+ NIceDb::TUpdate<Schema::Tablet::TabletType>(tablet.Type),
+ NIceDb::TUpdate<Schema::Tablet::KnownGeneration>(tablet.KnownGeneration),
+ NIceDb::TUpdate<Schema::Tablet::State>(tablet.State),
NIceDb::TUpdate<Schema::Tablet::ActorsToNotify>(TVector<TActorId>(1, Sender)),
- NIceDb::TUpdate<Schema::Tablet::AllowedNodes>(tablet.AllowedNodes),
+ NIceDb::TUpdate<Schema::Tablet::AllowedNodes>(tablet.AllowedNodes),
NIceDb::TUpdate<Schema::Tablet::AllowedDataCenters>(allowedDataCenters),
NIceDb::TUpdate<Schema::Tablet::AllowedDataCenterIds>(tablet.AllowedDataCenters),
- NIceDb::TUpdate<Schema::Tablet::DataCentersPreference>(tablet.DataCentersPreference),
- NIceDb::TUpdate<Schema::Tablet::AllowedDomains>(AllowedDomains),
- NIceDb::TUpdate<Schema::Tablet::BootMode>(tablet.BootMode),
- NIceDb::TUpdate<Schema::Tablet::ObjectID>(tablet.ObjectId),
- NIceDb::TUpdate<Schema::Tablet::ObjectDomain>(ObjectDomain),
- NIceDb::TUpdate<Schema::Tablet::Statistics>(tablet.Statistics));
-
- Self->PendingCreateTablets.erase({OwnerId, OwnerIdx});
-
- if (TabletCategory.HasTabletCategoryID()) {
- TTabletCategoryInfo* tabletCategory = nullptr;
-
- db.Table<Schema::TabletCategory>().Key(TabletCategory.GetTabletCategoryID()).Update();
- tabletCategory = &Self->GetTabletCategory(TabletCategory.GetTabletCategoryID());
- if (TabletCategory.HasMaxDisconnectTimeout()) {
- db.Table<Schema::TabletCategory>().Key(TabletCategory.GetTabletCategoryID()).Update<Schema::TabletCategory::MaxDisconnectTimeout>(TabletCategory.GetMaxDisconnectTimeout());
- tabletCategory->MaxDisconnectTimeout = TabletCategory.GetMaxDisconnectTimeout();
- }
- if (TabletCategory.HasStickTogetherInDC()) {
- db.Table<Schema::TabletCategory>().Key(TabletCategory.GetTabletCategoryID()).Update<Schema::TabletCategory::StickTogetherInDC>(TabletCategory.GetStickTogetherInDC());
- tabletCategory->StickTogetherInDC = TabletCategory.GetStickTogetherInDC();
- }
- db.Table<Schema::Tablet>().Key(TabletId).Update<Schema::Tablet::Category>(TabletCategory.GetTabletCategoryID());
- tablet.Category = tabletCategory;
- } else if (Self->CurrentConfig.GetSystemTabletCategoryId() != 0 && Self->IsSystemTablet(tablet.Type)){
- tablet.Category = &Self->GetTabletCategory(Self->CurrentConfig.GetSystemTabletCategoryId());
- }
-
- if (tablet.Category != nullptr) {
- tablet.Category->Tablets.insert(&tablet);
- }
-
- NKikimrTabletBase::TMetrics resourceValues;
-
- resourceValues.CopyFrom(Self->GetDefaultResourceValuesForTabletType(tablet.Type));
- BLOG_D("THive::TTxCreateTablet::Execute; Default resources after merge for type " << tablet.Type << ": {" << resourceValues.ShortDebugString() << "}");
- if (tablet.ObjectId != 0) {
- resourceValues.MergeFrom(Self->GetDefaultResourceValuesForObject(tablet.ObjectId));
- BLOG_D("THive::TTxCreateTablet::Execute; Default resources after merge for object " << tablet.ObjectId << ": {" << resourceValues.ShortDebugString() << "}");
- }
- // TODO: provide Hive with resource profile used by the tablet instead of default one.
- resourceValues.MergeFrom(Self->GetDefaultResourceValuesForProfile(tablet.Type, "default"));
- BLOG_D("THive::TTxCreateTablet::Execute; Default resources after merge for profile 'default': {" << resourceValues.ShortDebugString() << "}");
- if (resourceValues.ByteSize() == 0) {
- resourceValues.SetStorage(1ULL << 30); // 1 GB
- resourceValues.SetReadThroughput(10ULL << 20); // 10 MB/s
- resourceValues.SetWriteThroughput(10ULL << 20); // 10 MB/s
- }
- tablet.UpdateResourceUsage(resourceValues);
+ NIceDb::TUpdate<Schema::Tablet::DataCentersPreference>(tablet.DataCentersPreference),
+ NIceDb::TUpdate<Schema::Tablet::AllowedDomains>(AllowedDomains),
+ NIceDb::TUpdate<Schema::Tablet::BootMode>(tablet.BootMode),
+ NIceDb::TUpdate<Schema::Tablet::ObjectID>(tablet.ObjectId),
+ NIceDb::TUpdate<Schema::Tablet::ObjectDomain>(ObjectDomain),
+ NIceDb::TUpdate<Schema::Tablet::Statistics>(tablet.Statistics));
+
+ Self->PendingCreateTablets.erase({OwnerId, OwnerIdx});
+
+ if (TabletCategory.HasTabletCategoryID()) {
+ TTabletCategoryInfo* tabletCategory = nullptr;
+
+ db.Table<Schema::TabletCategory>().Key(TabletCategory.GetTabletCategoryID()).Update();
+ tabletCategory = &Self->GetTabletCategory(TabletCategory.GetTabletCategoryID());
+ if (TabletCategory.HasMaxDisconnectTimeout()) {
+ db.Table<Schema::TabletCategory>().Key(TabletCategory.GetTabletCategoryID()).Update<Schema::TabletCategory::MaxDisconnectTimeout>(TabletCategory.GetMaxDisconnectTimeout());
+ tabletCategory->MaxDisconnectTimeout = TabletCategory.GetMaxDisconnectTimeout();
+ }
+ if (TabletCategory.HasStickTogetherInDC()) {
+ db.Table<Schema::TabletCategory>().Key(TabletCategory.GetTabletCategoryID()).Update<Schema::TabletCategory::StickTogetherInDC>(TabletCategory.GetStickTogetherInDC());
+ tabletCategory->StickTogetherInDC = TabletCategory.GetStickTogetherInDC();
+ }
+ db.Table<Schema::Tablet>().Key(TabletId).Update<Schema::Tablet::Category>(TabletCategory.GetTabletCategoryID());
+ tablet.Category = tabletCategory;
+ } else if (Self->CurrentConfig.GetSystemTabletCategoryId() != 0 && Self->IsSystemTablet(tablet.Type)){
+ tablet.Category = &Self->GetTabletCategory(Self->CurrentConfig.GetSystemTabletCategoryId());
+ }
+
+ if (tablet.Category != nullptr) {
+ tablet.Category->Tablets.insert(&tablet);
+ }
+
+ NKikimrTabletBase::TMetrics resourceValues;
+
+ resourceValues.CopyFrom(Self->GetDefaultResourceValuesForTabletType(tablet.Type));
+ BLOG_D("THive::TTxCreateTablet::Execute; Default resources after merge for type " << tablet.Type << ": {" << resourceValues.ShortDebugString() << "}");
+ if (tablet.ObjectId != 0) {
+ resourceValues.MergeFrom(Self->GetDefaultResourceValuesForObject(tablet.ObjectId));
+ BLOG_D("THive::TTxCreateTablet::Execute; Default resources after merge for object " << tablet.ObjectId << ": {" << resourceValues.ShortDebugString() << "}");
+ }
+ // TODO: provide Hive with resource profile used by the tablet instead of default one.
+ resourceValues.MergeFrom(Self->GetDefaultResourceValuesForProfile(tablet.Type, "default"));
+ BLOG_D("THive::TTxCreateTablet::Execute; Default resources after merge for profile 'default': {" << resourceValues.ShortDebugString() << "}");
+ if (resourceValues.ByteSize() == 0) {
+ resourceValues.SetStorage(1ULL << 30); // 1 GB
+ resourceValues.SetReadThroughput(10ULL << 20); // 10 MB/s
+ resourceValues.SetWriteThroughput(10ULL << 20); // 10 MB/s
+ }
+ tablet.UpdateResourceUsage(resourceValues);
tablet.BoundChannels.clear();
- tablet.TabletStorageInfo.Reset(new TTabletStorageInfo(tablet.Id, tablet.Type));
+ tablet.TabletStorageInfo.Reset(new TTabletStorageInfo(tablet.Id, tablet.Type));
tablet.TabletStorageInfo->TenantPathId = tablet.GetTenant();
UpdateChannelsBinding(tablet, db);
-
+
for (const auto& srcFollowerGroup : FollowerGroups) {
TFollowerGroup& followerGroup = tablet.AddFollowerGroup();
followerGroup = srcFollowerGroup;
@@ -440,78 +440,78 @@ public:
NIceDb::TUpdate<Schema::TabletFollowerGroup::AllowedDataCenterIds>(followerGroup.AllowedDataCenters),
NIceDb::TUpdate<Schema::TabletFollowerGroup::RequireAllDataCenters>(followerGroup.RequireAllDataCenters),
NIceDb::TUpdate<Schema::TabletFollowerGroup::FollowerCountPerDataCenter>(followerGroup.FollowerCountPerDataCenter));
-
- for (ui32 i = 0; i < followerGroup.GetComputedFollowerCount(Self->GetDataCenters()); ++i) {
+
+ for (ui32 i = 0; i < followerGroup.GetComputedFollowerCount(Self->GetDataCenters()); ++i) {
TFollowerTabletInfo& follower = tablet.AddFollower(followerGroup);
- follower.Statistics.SetLastAliveTimestamp(now.MilliSeconds());
+ follower.Statistics.SetLastAliveTimestamp(now.MilliSeconds());
db.Table<Schema::TabletFollowerTablet>().Key(TabletId, follower.Id).Update(
NIceDb::TUpdate<Schema::TabletFollowerTablet::GroupID>(follower.FollowerGroup.Id),
- NIceDb::TUpdate<Schema::TabletFollowerTablet::FollowerNode>(0),
- NIceDb::TUpdate<Schema::TabletFollowerTablet::Statistics>(follower.Statistics));
+ NIceDb::TUpdate<Schema::TabletFollowerTablet::FollowerNode>(0),
+ NIceDb::TUpdate<Schema::TabletFollowerTablet::Statistics>(follower.Statistics));
follower.InitTabletMetrics();
follower.BecomeStopped();
- }
- }
-
- Self->OwnerToTablet.emplace(ownerIdx, TabletId);
- Self->ObjectToTabletMetrics[tablet.ObjectId].IncreaseCount();
- Self->TabletTypeToTabletMetrics[tablet.Type].IncreaseCount();
- Status = NKikimrProto::OK;
- return true;
- }
-
+ }
+ }
+
+ Self->OwnerToTablet.emplace(ownerIdx, TabletId);
+ Self->ObjectToTabletMetrics[tablet.ObjectId].IncreaseCount();
+ Self->TabletTypeToTabletMetrics[tablet.Type].IncreaseCount();
+ Status = NKikimrProto::OK;
+ return true;
+ }
+
void Complete(const TActorContext& ctx) override {
- if (Status != NKikimrProto::UNKNOWN) {
- BLOG_D("THive::TTxCreateTablet::Complete TabletId: " << TabletId <<
- " Status: " << NKikimrProto::EReplyStatus_Name(Status) << " State: " << ETabletStateName(State));
- Y_VERIFY(!!Sender);
+ if (Status != NKikimrProto::UNKNOWN) {
+ BLOG_D("THive::TTxCreateTablet::Complete TabletId: " << TabletId <<
+ " Status: " << NKikimrProto::EReplyStatus_Name(Status) << " State: " << ETabletStateName(State));
+ Y_VERIFY(!!Sender);
THolder<TEvHive::TEvCreateTabletReply> reply = MakeHolder<TEvHive::TEvCreateTabletReply>(Status, OwnerId, OwnerIdx, TabletId, Self->TabletID(), ErrorReason);
- if (ForwardRequest.HasHiveTabletId()) {
- reply->Record.MutableForwardRequest()->CopyFrom(ForwardRequest);
- }
- ctx.Send(Sender, reply.Release(), 0, Cookie);
+ if (ForwardRequest.HasHiveTabletId()) {
+ reply->Record.MutableForwardRequest()->CopyFrom(ForwardRequest);
+ }
+ ctx.Send(Sender, reply.Release(), 0, Cookie);
TLeaderTabletInfo* tablet = Self->FindTablet(TabletId);
- if (tablet != nullptr) {
- if (Status == NKikimrProto::OK && tablet->Type == TTabletTypes::Hive) {
- auto itSubDomain = Self->Domains.find(tablet->ObjectDomain);
- if (itSubDomain != Self->Domains.end()) {
- if (itSubDomain->second.HiveId == 0) {
- itSubDomain->second.HiveId = tablet->Id;
- }
- Self->Execute(Self->CreateUpdateDomain(tablet->ObjectDomain));
- }
- }
- if (Status == NKikimrProto::OK && tablet->IsReadyToAssignGroups()) {
- tablet->InitiateAssignTabletGroups();
- } else if (Status == NKikimrProto::OK && tablet->IsBootingSuppressed()) {
- // Tablet will never boot, so notify about creation right now
+ if (tablet != nullptr) {
+ if (Status == NKikimrProto::OK && tablet->Type == TTabletTypes::Hive) {
+ auto itSubDomain = Self->Domains.find(tablet->ObjectDomain);
+ if (itSubDomain != Self->Domains.end()) {
+ if (itSubDomain->second.HiveId == 0) {
+ itSubDomain->second.HiveId = tablet->Id;
+ }
+ Self->Execute(Self->CreateUpdateDomain(tablet->ObjectDomain));
+ }
+ }
+ if (Status == NKikimrProto::OK && tablet->IsReadyToAssignGroups()) {
+ tablet->InitiateAssignTabletGroups();
+ } else if (Status == NKikimrProto::OK && tablet->IsBootingSuppressed()) {
+ // Tablet will never boot, so notify about creation right now
for (const TActorId& actor : tablet->ActorsToNotify) {
- ctx.Send(actor, new TEvHive::TEvTabletCreationResult(NKikimrProto::OK, TabletId));
- }
- tablet->ActorsToNotify.clear();
- } else {
- tablet->TryToBoot();
- }
+ ctx.Send(actor, new TEvHive::TEvTabletCreationResult(NKikimrProto::OK, TabletId));
+ }
+ tablet->ActorsToNotify.clear();
+ } else {
+ tablet->TryToBoot();
+ }
+ }
+ Self->ProcessBootQueue();
+ } else {
+ BLOG_D("THive::TTxCreateTablet::Complete CreateTablet Postponed");
+ THive::TPendingCreateTablet& pendingCreateTablet(Self->PendingCreateTablets[{OwnerId, OwnerIdx}]);
+ pendingCreateTablet.CreateTablet = RequestData; // TODO: consider std::move
+ pendingCreateTablet.Sender = Sender;
+ pendingCreateTablet.Cookie = Cookie;
+ if (Self->AreWeSubDomainHive()) {
+ if (!Self->RequestingSequenceNow) {
+ Self->RequestFreeSequence();
+ }
}
- Self->ProcessBootQueue();
- } else {
- BLOG_D("THive::TTxCreateTablet::Complete CreateTablet Postponed");
- THive::TPendingCreateTablet& pendingCreateTablet(Self->PendingCreateTablets[{OwnerId, OwnerIdx}]);
- pendingCreateTablet.CreateTablet = RequestData; // TODO: consider std::move
- pendingCreateTablet.Sender = Sender;
- pendingCreateTablet.Cookie = Cookie;
- if (Self->AreWeSubDomainHive()) {
- if (!Self->RequestingSequenceNow) {
- Self->RequestFreeSequence();
- }
- }
- }
- }
-};
-
+ }
+ }
+};
+
ITransaction* THive::CreateCreateTablet(NKikimrHive::TEvCreateTablet rec, const TActorId& sender, const ui64 cookie) {
- return new TTxCreateTablet(std::move(rec), sender, cookie, this);
-}
-
-} // NHive
-} // NKikimr
+ return new TTxCreateTablet(std::move(rec), sender, cookie, this);
+}
+
+} // NHive
+} // NKikimr
diff --git a/ydb/core/mind/hive/tx__cut_tablet_history.cpp b/ydb/core/mind/hive/tx__cut_tablet_history.cpp
index da56ab680ee..9bf4c94b98c 100644
--- a/ydb/core/mind/hive/tx__cut_tablet_history.cpp
+++ b/ydb/core/mind/hive/tx__cut_tablet_history.cpp
@@ -1,49 +1,49 @@
-#include "hive_impl.h"
-#include "hive_log.h"
-
-namespace NKikimr {
-namespace NHive {
-
-class TTxCutTabletHistory : public TTransactionBase<THive> {
- TEvHive::TEvCutTabletHistory::TPtr Event;
-public:
- TTxCutTabletHistory(TEvHive::TEvCutTabletHistory::TPtr& ev, THive* hive)
- : TBase(hive)
- , Event(ev)
- {}
-
- TTxType GetTxType() const override { return NHive::TXTYPE_CUT_TABLET_HISTORY; }
-
+#include "hive_impl.h"
+#include "hive_log.h"
+
+namespace NKikimr {
+namespace NHive {
+
+class TTxCutTabletHistory : public TTransactionBase<THive> {
+ TEvHive::TEvCutTabletHistory::TPtr Event;
+public:
+ TTxCutTabletHistory(TEvHive::TEvCutTabletHistory::TPtr& ev, THive* hive)
+ : TBase(hive)
+ , Event(ev)
+ {}
+
+ TTxType GetTxType() const override { return NHive::TXTYPE_CUT_TABLET_HISTORY; }
+
bool Execute(TTransactionContext& txc, const TActorContext&) override {
- TEvHive::TEvCutTabletHistory* msg = Event->Get();
- auto tabletId = msg->Record.GetTabletID();
- BLOG_D("THive::TTxCutTabletHistory::Execute(" << tabletId << ")");
+ TEvHive::TEvCutTabletHistory* msg = Event->Get();
+ auto tabletId = msg->Record.GetTabletID();
+ BLOG_D("THive::TTxCutTabletHistory::Execute(" << tabletId << ")");
TLeaderTabletInfo* tablet = Self->FindTabletEvenInDeleting(tabletId);
- if (tablet != nullptr && tablet->IsReadyToReassignTablet()) {
- auto channel = msg->Record.GetChannel();
- Y_VERIFY(channel < tablet->TabletStorageInfo->Channels.size());
- TTabletChannelInfo& channelInfo = tablet->TabletStorageInfo->Channels[channel];
- auto fromGeneration = msg->Record.GetFromGeneration();
- auto groupId = msg->Record.GetGroupID();
- auto it = std::find(
- channelInfo.History.begin(),
- channelInfo.History.end(),
- TTabletChannelInfo::THistoryEntry(fromGeneration, groupId));
- if (it != channelInfo.History.end()) {
- channelInfo.History.erase(it);
- NIceDb::TNiceDb db(txc.DB);
- db.Table<Schema::TabletChannelGen>().Key(tabletId, channel, fromGeneration).Delete();
- }
- }
- return true;
- }
-
+ if (tablet != nullptr && tablet->IsReadyToReassignTablet()) {
+ auto channel = msg->Record.GetChannel();
+ Y_VERIFY(channel < tablet->TabletStorageInfo->Channels.size());
+ TTabletChannelInfo& channelInfo = tablet->TabletStorageInfo->Channels[channel];
+ auto fromGeneration = msg->Record.GetFromGeneration();
+ auto groupId = msg->Record.GetGroupID();
+ auto it = std::find(
+ channelInfo.History.begin(),
+ channelInfo.History.end(),
+ TTabletChannelInfo::THistoryEntry(fromGeneration, groupId));
+ if (it != channelInfo.History.end()) {
+ channelInfo.History.erase(it);
+ NIceDb::TNiceDb db(txc.DB);
+ db.Table<Schema::TabletChannelGen>().Key(tabletId, channel, fromGeneration).Delete();
+ }
+ }
+ return true;
+ }
+
void Complete(const TActorContext&) override {}
-};
-
+};
+
ITransaction* THive::CreateCutTabletHistory(TEvHive::TEvCutTabletHistory::TPtr& ev) {
- return new TTxCutTabletHistory(ev, this);
-}
-
-} // NHive
-} // NKikimr
+ return new TTxCutTabletHistory(ev, this);
+}
+
+} // NHive
+} // NKikimr
diff --git a/ydb/core/mind/hive/tx__delete_tablet.cpp b/ydb/core/mind/hive/tx__delete_tablet.cpp
index 55127cad339..6d481e695fd 100644
--- a/ydb/core/mind/hive/tx__delete_tablet.cpp
+++ b/ydb/core/mind/hive/tx__delete_tablet.cpp
@@ -1,124 +1,124 @@
-#include "hive_impl.h"
-#include "hive_log.h"
-
-namespace NKikimr {
-namespace NHive {
-
-class TTxDeleteTablet : public TTransactionBase<THive> {
- TEvHive::TEvDeleteTablet::TPtr Event;
+#include "hive_impl.h"
+#include "hive_log.h"
+
+namespace NKikimr {
+namespace NHive {
+
+class TTxDeleteTablet : public TTransactionBase<THive> {
+ TEvHive::TEvDeleteTablet::TPtr Event;
ui64 OwnerId = 0;
TVector<ui64> LocalIdxs;
- NKikimrProto::EReplyStatus Status = NKikimrProto::ERROR;
- TVector<TTabletId> TabletIds;
- TCompleteNotifications Notifications;
- NKikimrHive::TForwardRequest ForwardRequest;
-
-public:
- TTxDeleteTablet(TEvHive::TEvDeleteTablet::TPtr& ev, THive* hive)
- : TBase(hive)
- , Event(ev)
- {}
-
- TTxType GetTxType() const override { return NHive::TXTYPE_DELETE_TABLET; }
-
- TTabletId DoDeleteTablet(ui64 owner, ui64 idx, NIceDb::TNiceDb& db) {
- TTabletId deletedTablet = 0;
+ NKikimrProto::EReplyStatus Status = NKikimrProto::ERROR;
+ TVector<TTabletId> TabletIds;
+ TCompleteNotifications Notifications;
+ NKikimrHive::TForwardRequest ForwardRequest;
+
+public:
+ TTxDeleteTablet(TEvHive::TEvDeleteTablet::TPtr& ev, THive* hive)
+ : TBase(hive)
+ , Event(ev)
+ {}
+
+ TTxType GetTxType() const override { return NHive::TXTYPE_DELETE_TABLET; }
+
+ TTabletId DoDeleteTablet(ui64 owner, ui64 idx, NIceDb::TNiceDb& db) {
+ TTabletId deletedTablet = 0;
TOwnerIdxType::TValueType ownerIdx(owner, idx);
- auto it = Self->OwnerToTablet.find(ownerIdx);
- if (it != Self->OwnerToTablet.end()) {
- deletedTablet = it->second;
- BLOG_D("THive::TTxDeleteTablet::Execute Tablet " << it->second);
+ auto it = Self->OwnerToTablet.find(ownerIdx);
+ if (it != Self->OwnerToTablet.end()) {
+ deletedTablet = it->second;
+ BLOG_D("THive::TTxDeleteTablet::Execute Tablet " << it->second);
TLeaderTabletInfo* tablet = Self->FindTabletEvenInDeleting(it->second);
Y_VERIFY(tablet != nullptr, "%s", (TStringBuilder() << "Tablet " << it->second << " OwnerIdx " << ownerIdx).data());
- if (tablet->SeizedByChild) {
- BLOG_W("THive::TTxDeleteTablet tablet " << it->second << " seized by child");
- return 0;
- }
- if (tablet->State != ETabletState::Deleting) {
- tablet->State = ETabletState::Deleting;
- tablet->InitiateStop();
+ if (tablet->SeizedByChild) {
+ BLOG_W("THive::TTxDeleteTablet tablet " << it->second << " seized by child");
+ return 0;
+ }
+ if (tablet->State != ETabletState::Deleting) {
+ tablet->State = ETabletState::Deleting;
+ tablet->InitiateStop();
db.Table<Schema::Tablet>().Key(tablet->Id).Update<Schema::Tablet::State, Schema::Tablet::LeaderNode>(ETabletState::Deleting, 0);
for (TTabletInfo& follower : tablet->Followers) {
follower.InitiateStop();
db.Table<Schema::TabletFollowerTablet>().Key(follower.GetFullTabletId()).Update<Schema::TabletFollowerTablet::FollowerNode>(0);
- }
- if (!tablet->InitiateBlockStorage(std::numeric_limits<ui32>::max())) {
- Self->DeleteTabletWithoutStorage(tablet);
- }
- } else {
- BLOG_D("THive::TTxDeleteTablet::Execute Tablet " << it->second << " already in ETabletState::Deleting");
+ }
+ if (!tablet->InitiateBlockStorage(std::numeric_limits<ui32>::max())) {
+ Self->DeleteTabletWithoutStorage(tablet);
+ }
+ } else {
+ BLOG_D("THive::TTxDeleteTablet::Execute Tablet " << it->second << " already in ETabletState::Deleting");
}
} else {
- BLOG_W("THive::TTxDeleteTablet tablet " << ownerIdx << " wasn't found");
- Self->PendingCreateTablets.erase({owner, idx});
+ BLOG_W("THive::TTxDeleteTablet tablet " << ownerIdx << " wasn't found");
+ Self->PendingCreateTablets.erase({owner, idx});
}
- return deletedTablet;
+ return deletedTablet;
}
bool Execute(TTransactionContext& txc, const TActorContext&) override {
- const NKikimrHive::TEvDeleteTablet& rec = Event->Get()->Record;
- NIceDb::TNiceDb db(txc.DB);
+ const NKikimrHive::TEvDeleteTablet& rec = Event->Get()->Record;
+ NIceDb::TNiceDb db(txc.DB);
OwnerId = rec.GetShardOwnerId();
- for (ui64 idx : rec.GetShardLocalIdx()) {
- LocalIdxs.push_back(idx);
- }
- for (TTabletId tabletId : rec.GetTabletID()) {
- TTabletId prevForwardHiveTabletId = ForwardRequest.GetHiveTabletId();
- if (Self->CheckForForwardTabletRequest(tabletId, ForwardRequest)) {
- if (prevForwardHiveTabletId != 0 && prevForwardHiveTabletId != ForwardRequest.GetHiveTabletId()) {
- BLOG_ERROR("Forward of DeleteTablet is not possible - different owners of tablets");
- Status = NKikimrProto::ERROR; // actually this status from blob storage, but I think it fits this situation perfectly
- return true; // abort transaction
- }
- }
- }
- if (ForwardRequest.GetHiveTabletId() != 0) {
- Status = NKikimrProto::INVALID_OWNER; // actually this status from blob storage, but I think it fits this situation perfectly
- return true; // abort transaction
- }
+ for (ui64 idx : rec.GetShardLocalIdx()) {
+ LocalIdxs.push_back(idx);
+ }
+ for (TTabletId tabletId : rec.GetTabletID()) {
+ TTabletId prevForwardHiveTabletId = ForwardRequest.GetHiveTabletId();
+ if (Self->CheckForForwardTabletRequest(tabletId, ForwardRequest)) {
+ if (prevForwardHiveTabletId != 0 && prevForwardHiveTabletId != ForwardRequest.GetHiveTabletId()) {
+ BLOG_ERROR("Forward of DeleteTablet is not possible - different owners of tablets");
+ Status = NKikimrProto::ERROR; // actually this status from blob storage, but I think it fits this situation perfectly
+ return true; // abort transaction
+ }
+ }
+ }
+ if (ForwardRequest.GetHiveTabletId() != 0) {
+ Status = NKikimrProto::INVALID_OWNER; // actually this status from blob storage, but I think it fits this situation perfectly
+ return true; // abort transaction
+ }
for (ui64 idx : rec.GetShardLocalIdx()) {
Status = NKikimrProto::OK;
- if (TTabletId deletedTablet = DoDeleteTablet(OwnerId, idx, db)) {
- TabletIds.push_back(deletedTablet);
- }
- }
- for (ui64 tabletId : TabletIds) {
+ if (TTabletId deletedTablet = DoDeleteTablet(OwnerId, idx, db)) {
+ TabletIds.push_back(deletedTablet);
+ }
+ }
+ for (ui64 tabletId : TabletIds) {
TLeaderTabletInfo* tablet = Self->FindTablet(tabletId);
- if (tablet != nullptr) {
- for (const TActorId& actor : tablet->ActorsToNotifyOnRestart) {
- Notifications.Send(actor, new TEvPrivate::TEvRestartComplete(tablet->GetFullTabletId(), "delete"));
- }
- tablet->ActorsToNotifyOnRestart.clear();
+ if (tablet != nullptr) {
+ for (const TActorId& actor : tablet->ActorsToNotifyOnRestart) {
+ Notifications.Send(actor, new TEvPrivate::TEvRestartComplete(tablet->GetFullTabletId(), "delete"));
+ }
+ tablet->ActorsToNotifyOnRestart.clear();
for (TTabletInfo& follower : tablet->Followers) {
- for (const TActorId& actor : follower.ActorsToNotifyOnRestart) {
- Notifications.Send(actor, new TEvPrivate::TEvRestartComplete(follower.GetFullTabletId(), "delete"));
- }
- follower.ActorsToNotifyOnRestart.clear();
- }
- }
- }
- return true;
- }
-
+ for (const TActorId& actor : follower.ActorsToNotifyOnRestart) {
+ Notifications.Send(actor, new TEvPrivate::TEvRestartComplete(follower.GetFullTabletId(), "delete"));
+ }
+ follower.ActorsToNotifyOnRestart.clear();
+ }
+ }
+ }
+ return true;
+ }
+
void Complete(const TActorContext& ctx) override {
- BLOG_D("THive::TTxDeleteTablet::Complete(" << TabletIds << ")");
+ BLOG_D("THive::TTxDeleteTablet::Complete(" << TabletIds << ")");
THolder<TEvHive::TEvDeleteTabletReply> response = MakeHolder<TEvHive::TEvDeleteTabletReply>(Status, Self->TabletID(), Event->Get()->Record.GetTxId_Deprecated(), OwnerId, LocalIdxs);
- if (ForwardRequest.HasHiveTabletId()) {
- response->Record.MutableForwardRequest()->CopyFrom(ForwardRequest);
- }
- ctx.Send(Event->Sender, response.Release(), 0, Event->Cookie);
- Notifications.Send(ctx);
- }
-};
-
+ if (ForwardRequest.HasHiveTabletId()) {
+ response->Record.MutableForwardRequest()->CopyFrom(ForwardRequest);
+ }
+ ctx.Send(Event->Sender, response.Release(), 0, Event->Cookie);
+ Notifications.Send(ctx);
+ }
+};
+
ITransaction* THive::CreateDeleteTablet(TEvHive::TEvDeleteTablet::TPtr& ev) {
- return new TTxDeleteTablet(ev, this);
-}
-
-
-// TODO: split
+ return new TTxDeleteTablet(ev, this);
+}
+
+
+// TODO: split
class TTxDeleteOwnerTablets : public TTransactionBase<THive> {
TEvHive::TEvDeleteOwnerTablets::TPtr Event;
NKikimrProto::EReplyStatus Status = NKikimrProto::OK;
@@ -129,55 +129,55 @@ public:
, Event(ev)
{}
- TTabletId DoDeleteTablet(ui64 owner, ui64 idx, NIceDb::TNiceDb& db) {
- TTabletId deletedTablet = 0;
-
- TOwnerIdxType::TValueType ownerIdx(owner, idx);
- auto it = Self->OwnerToTablet.find(ownerIdx);
- if (it != Self->OwnerToTablet.end()) {
- deletedTablet = it->second;
- BLOG_D("THive::TTxDeleteTablet::Execute Tablet " << it->second);
+ TTabletId DoDeleteTablet(ui64 owner, ui64 idx, NIceDb::TNiceDb& db) {
+ TTabletId deletedTablet = 0;
+
+ TOwnerIdxType::TValueType ownerIdx(owner, idx);
+ auto it = Self->OwnerToTablet.find(ownerIdx);
+ if (it != Self->OwnerToTablet.end()) {
+ deletedTablet = it->second;
+ BLOG_D("THive::TTxDeleteTablet::Execute Tablet " << it->second);
TLeaderTabletInfo* tablet = Self->FindTabletEvenInDeleting(it->second);
- Y_VERIFY(tablet != nullptr, "%s", (TStringBuilder() << "Tablet " << it->second << " OwnerIdx " << ownerIdx).data());
- if (tablet->SeizedByChild) {
- BLOG_W("THive::TTxDeleteTablet tablet " << it->second << " seized by child");
- return 0;
- }
- if (tablet->State != ETabletState::Deleting) {
- tablet->State = ETabletState::Deleting;
- tablet->InitiateStop();
+ Y_VERIFY(tablet != nullptr, "%s", (TStringBuilder() << "Tablet " << it->second << " OwnerIdx " << ownerIdx).data());
+ if (tablet->SeizedByChild) {
+ BLOG_W("THive::TTxDeleteTablet tablet " << it->second << " seized by child");
+ return 0;
+ }
+ if (tablet->State != ETabletState::Deleting) {
+ tablet->State = ETabletState::Deleting;
+ tablet->InitiateStop();
db.Table<Schema::Tablet>().Key(tablet->Id).Update<Schema::Tablet::State, Schema::Tablet::LeaderNode>(ETabletState::Deleting, 0);
for (TTabletInfo& follower : tablet->Followers) {
follower.InitiateStop();
db.Table<Schema::TabletFollowerTablet>().Key(follower.GetFullTabletId()).Update<Schema::TabletFollowerTablet::FollowerNode>(0);
- }
- if (!tablet->InitiateBlockStorage(std::numeric_limits<ui32>::max())) {
- Self->DeleteTabletWithoutStorage(tablet);
- }
- } else {
- BLOG_D("THive::TTxDeleteTablet::Execute Tablet " << it->second << " already in ETabletState::Deleting");
- }
- } else {
- BLOG_W("THive::TTxDeleteTablet tablet " << ownerIdx << " wasn't found");
- Self->PendingCreateTablets.erase({owner, idx});
- }
-
- return deletedTablet;
- }
-
+ }
+ if (!tablet->InitiateBlockStorage(std::numeric_limits<ui32>::max())) {
+ Self->DeleteTabletWithoutStorage(tablet);
+ }
+ } else {
+ BLOG_D("THive::TTxDeleteTablet::Execute Tablet " << it->second << " already in ETabletState::Deleting");
+ }
+ } else {
+ BLOG_W("THive::TTxDeleteTablet tablet " << ownerIdx << " wasn't found");
+ Self->PendingCreateTablets.erase({owner, idx});
+ }
+
+ return deletedTablet;
+ }
+
bool Execute(TTransactionContext& txc, const TActorContext&) override {
const NKikimrHive::TEvDeleteOwnerTablets& rec = Event->Get()->Record;
- BLOG_D("THive::TEvDeleteOwnerTablets::Execute Owner: " << rec.GetOwner());
- for (auto item : Self->OwnerToTablet) {
+ BLOG_D("THive::TEvDeleteOwnerTablets::Execute Owner: " << rec.GetOwner());
+ for (auto item : Self->OwnerToTablet) {
if (item.first.first != rec.GetOwner()) {
continue;
}
const TLeaderTabletInfo* tablet = Self->FindTabletEvenInDeleting(item.second);
- if (tablet) {
- if (!tablet->IsDeleting()) {
- ToDelete.push_back(item.first.second);
- }
- }
+ if (tablet) {
+ if (!tablet->IsDeleting()) {
+ ToDelete.push_back(item.first.second);
+ }
+ }
}
if (ToDelete.empty()) {
@@ -186,17 +186,17 @@ public:
}
NIceDb::TNiceDb db(txc.DB);
- for (auto idx : ToDelete) {
- DoDeleteTablet(rec.GetOwner(), idx, db);
+ for (auto idx : ToDelete) {
+ DoDeleteTablet(rec.GetOwner(), idx, db);
}
- db.Table<Schema::BlockedOwner>().Key(rec.GetOwner()).Update();
+ db.Table<Schema::BlockedOwner>().Key(rec.GetOwner()).Update();
return true;
}
void Complete(const TActorContext& ctx) override {
- BLOG_D("THive::TEvDeleteOwnerTablets::Complete(" << Event->Get()->Record.GetOwner() << "), " << ToDelete.size() << " tablet has been deleted");
- Self->BlockedOwners.emplace(Event->Get()->Record.GetOwner());
+ BLOG_D("THive::TEvDeleteOwnerTablets::Complete(" << Event->Get()->Record.GetOwner() << "), " << ToDelete.size() << " tablet has been deleted");
+ Self->BlockedOwners.emplace(Event->Get()->Record.GetOwner());
ctx.Send(Event->Sender, new TEvHive::TEvDeleteOwnerTabletsReply(Status, Self->TabletID(), Event->Get()->Record.GetOwner(), Event->Get()->Record.GetTxId()));
}
};
@@ -206,5 +206,5 @@ ITransaction* THive::CreateDeleteOwnerTablets(TEvHive::TEvDeleteOwnerTablets::TP
}
-} // NHive
-} // NKikimr
+} // NHive
+} // NKikimr
diff --git a/ydb/core/mind/hive/tx__delete_tablet_result.cpp b/ydb/core/mind/hive/tx__delete_tablet_result.cpp
index 19259762de5..bbe89acae48 100644
--- a/ydb/core/mind/hive/tx__delete_tablet_result.cpp
+++ b/ydb/core/mind/hive/tx__delete_tablet_result.cpp
@@ -1,70 +1,70 @@
-#include "hive_impl.h"
-#include "hive_log.h"
-
-namespace NKikimr {
-namespace NHive {
-
-class TTxDeleteTabletResult : public TTransactionBase<THive> {
- TEvTabletBase::TEvDeleteTabletResult::TPtr Result;
- TTabletId TabletId;
+#include "hive_impl.h"
+#include "hive_log.h"
+
+namespace NKikimr {
+namespace NHive {
+
+class TTxDeleteTabletResult : public TTransactionBase<THive> {
+ TEvTabletBase::TEvDeleteTabletResult::TPtr Result;
+ TTabletId TabletId;
TLeaderTabletInfo* Tablet = nullptr;
TVector<TActorId> StorageInfoSubscribers;
TActorId UnlockedFromActor;
-public:
- TTxDeleteTabletResult(TEvTabletBase::TEvDeleteTabletResult::TPtr& ev, THive* hive)
- : TBase(hive)
- , Result(ev)
- , TabletId(Result->Get()->TabletId)
- {}
-
- TTxType GetTxType() const override { return NHive::TXTYPE_DELETE_TABLET_RESULT; }
-
+public:
+ TTxDeleteTabletResult(TEvTabletBase::TEvDeleteTabletResult::TPtr& ev, THive* hive)
+ : TBase(hive)
+ , Result(ev)
+ , TabletId(Result->Get()->TabletId)
+ {}
+
+ TTxType GetTxType() const override { return NHive::TXTYPE_DELETE_TABLET_RESULT; }
+
bool Execute(TTransactionContext& txc, const TActorContext&) override {
- TEvTabletBase::TEvDeleteTabletResult* msg = Result->Get();
- BLOG_D("THive::TTxDeleteTabletResult::Execute(" << TabletId << " " << NKikimrProto::EReplyStatus_Name(msg->Status) << ")");
- Tablet = Self->FindTabletEvenInDeleting(TabletId);
- if (Tablet != nullptr) {
- if (msg->Status == NKikimrProto::OK) {
- NIceDb::TNiceDb db(txc.DB);
+ TEvTabletBase::TEvDeleteTabletResult* msg = Result->Get();
+ BLOG_D("THive::TTxDeleteTabletResult::Execute(" << TabletId << " " << NKikimrProto::EReplyStatus_Name(msg->Status) << ")");
+ Tablet = Self->FindTabletEvenInDeleting(TabletId);
+ if (Tablet != nullptr) {
+ if (msg->Status == NKikimrProto::OK) {
+ NIceDb::TNiceDb db(txc.DB);
db.Table<Schema::Metrics>().Key(Tablet->Id, 0).Delete();
- for (const TTabletChannelInfo& channelInfo : Tablet->TabletStorageInfo->Channels) {
- for (const TTabletChannelInfo::THistoryEntry& historyInfo : channelInfo.History) {
- db.Table<Schema::TabletChannelGen>().Key(Tablet->Id, channelInfo.Channel, historyInfo.FromGeneration).Delete();
- }
- db.Table<Schema::TabletChannel>().Key(Tablet->Id, channelInfo.Channel).Delete();
- }
+ for (const TTabletChannelInfo& channelInfo : Tablet->TabletStorageInfo->Channels) {
+ for (const TTabletChannelInfo::THistoryEntry& historyInfo : channelInfo.History) {
+ db.Table<Schema::TabletChannelGen>().Key(Tablet->Id, channelInfo.Channel, historyInfo.FromGeneration).Delete();
+ }
+ db.Table<Schema::TabletChannel>().Key(Tablet->Id, channelInfo.Channel).Delete();
+ }
for (TFollowerTabletInfo& follower : Tablet->Followers) {
auto fullTabletId = follower.GetFullTabletId();
db.Table<Schema::TabletFollowerTablet>().Key(fullTabletId).Delete();
db.Table<Schema::Metrics>().Key(fullTabletId).Delete();
- }
+ }
for (TFollowerGroup& group : Tablet->FollowerGroups) {
db.Table<Schema::TabletFollowerGroup>().Key(Tablet->Id, group.Id).Delete();
- }
- db.Table<Schema::Tablet>().Key(Tablet->Id).Delete();
- StorageInfoSubscribers.swap(Tablet->StorageInfoSubscribers);
- UnlockedFromActor = Tablet->ClearLockedToActor();
- Self->PendingCreateTablets.erase({Tablet->Owner.first, Tablet->Owner.second});
- Self->DeleteTablet(Tablet->Id);
- }
- }
- return true;
- }
-
+ }
+ db.Table<Schema::Tablet>().Key(Tablet->Id).Delete();
+ StorageInfoSubscribers.swap(Tablet->StorageInfoSubscribers);
+ UnlockedFromActor = Tablet->ClearLockedToActor();
+ Self->PendingCreateTablets.erase({Tablet->Owner.first, Tablet->Owner.second});
+ Self->DeleteTablet(Tablet->Id);
+ }
+ }
+ return true;
+ }
+
void Complete(const TActorContext& ctx) override {
- TEvTabletBase::TEvDeleteTabletResult* msg = Result->Get();
- BLOG_D("THive::TTxDeleteTabletResult(" << TabletId << " " << NKikimrProto::EReplyStatus_Name(msg->Status) << ")::Complete");
- Tablet = Self->FindTabletEvenInDeleting(TabletId);
- if (Tablet) {
- if (msg->Status == NKikimrProto::OK) {
- //ctx.Send(Tablet.ActorToNotify, new TEvHive::TEvDeleteTabletReply(NKikimrProto::OK, Self->TabletID(), rec.GetTxId()));
- } else {
- BLOG_W("THive::TTxDeleteTabletResult retrying for " << TabletId << " because of " << NKikimrProto::EReplyStatus_Name(msg->Status));
- Y_ENSURE_LOG(Tablet->IsDeleting(), " tablet " << Tablet->Id);
- ctx.Schedule(TDuration::MilliSeconds(1000), new TEvHive::TEvInitiateDeleteStorage(Tablet->Id));
- }
- }
+ TEvTabletBase::TEvDeleteTabletResult* msg = Result->Get();
+ BLOG_D("THive::TTxDeleteTabletResult(" << TabletId << " " << NKikimrProto::EReplyStatus_Name(msg->Status) << ")::Complete");
+ Tablet = Self->FindTabletEvenInDeleting(TabletId);
+ if (Tablet) {
+ if (msg->Status == NKikimrProto::OK) {
+ //ctx.Send(Tablet.ActorToNotify, new TEvHive::TEvDeleteTabletReply(NKikimrProto::OK, Self->TabletID(), rec.GetTxId()));
+ } else {
+ BLOG_W("THive::TTxDeleteTabletResult retrying for " << TabletId << " because of " << NKikimrProto::EReplyStatus_Name(msg->Status));
+ Y_ENSURE_LOG(Tablet->IsDeleting(), " tablet " << Tablet->Id);
+ ctx.Schedule(TDuration::MilliSeconds(1000), new TEvHive::TEvInitiateDeleteStorage(Tablet->Id));
+ }
+ }
for (const TActorId& subscriber : StorageInfoSubscribers) {
ctx.Send(
subscriber,
@@ -74,12 +74,12 @@ public:
// Notify lock owner that lock has been lost
ctx.Send(UnlockedFromActor, new TEvHive::TEvLockTabletExecutionLost(TabletId));
}
- }
-};
-
+ }
+};
+
ITransaction* THive::CreateDeleteTabletResult(TEvTabletBase::TEvDeleteTabletResult::TPtr& ev) {
- return new TTxDeleteTabletResult(ev, this);
-}
-
-} // NHive
-} // NKikimr
+ return new TTxDeleteTabletResult(ev, this);
+}
+
+} // NHive
+} // NKikimr
diff --git a/ydb/core/mind/hive/tx__disconnect_node.cpp b/ydb/core/mind/hive/tx__disconnect_node.cpp
index 6925153a30b..0969a6e3b92 100644
--- a/ydb/core/mind/hive/tx__disconnect_node.cpp
+++ b/ydb/core/mind/hive/tx__disconnect_node.cpp
@@ -1,55 +1,55 @@
-#include "hive_impl.h"
-#include "hive_log.h"
-
-namespace NKikimr {
-namespace NHive {
-
-class TTxDisconnectNode : public TTransactionBase<THive> {
-protected:
- THolder<TEvInterconnect::TEvNodeDisconnected> Event;
-
-public:
- TTxDisconnectNode(THolder<TEvInterconnect::TEvNodeDisconnected> event, THive* hive)
- : TBase(hive)
- , Event(std::move(event))
- {}
-
- TTxType GetTxType() const override { return NHive::TXTYPE_DISCONNECT_NODE; }
-
+#include "hive_impl.h"
+#include "hive_log.h"
+
+namespace NKikimr {
+namespace NHive {
+
+class TTxDisconnectNode : public TTransactionBase<THive> {
+protected:
+ THolder<TEvInterconnect::TEvNodeDisconnected> Event;
+
+public:
+ TTxDisconnectNode(THolder<TEvInterconnect::TEvNodeDisconnected> event, THive* hive)
+ : TBase(hive)
+ , Event(std::move(event))
+ {}
+
+ TTxType GetTxType() const override { return NHive::TXTYPE_DISCONNECT_NODE; }
+
bool Execute(TTransactionContext&, const TActorContext&) override {
- BLOG_D("THive::TTxDisconnectNode()::Execute");
- TNodeInfo* node = Self->FindNode(Event->NodeId);
- if (node != nullptr) {
- Self->ScheduleUnlockTabletExecution(*node);
- if (node->BecomeDisconnecting()) {
+ BLOG_D("THive::TTxDisconnectNode()::Execute");
+ TNodeInfo* node = Self->FindNode(Event->NodeId);
+ if (node != nullptr) {
+ Self->ScheduleUnlockTabletExecution(*node);
+ if (node->BecomeDisconnecting()) {
THolder<TEvPrivate::TEvProcessDisconnectNode> event = MakeHolder<TEvPrivate::TEvProcessDisconnectNode>();
- event->NodeId = node->Id;
- event->Local = node->Local;
- event->StartTime = TActivationContext::Now();
- for (const auto& t : node->Tablets) {
- for (TTabletInfo* tablet : t.second) {
+ event->NodeId = node->Id;
+ event->Local = node->Local;
+ event->StartTime = TActivationContext::Now();
+ for (const auto& t : node->Tablets) {
+ for (TTabletInfo* tablet : t.second) {
TLeaderTabletInfo& leader = tablet->GetLeader();
TTabletCategoryId tabletCategoryId = leader.Category ? leader.Category->Id : 0;
- event->Tablets[tabletCategoryId].emplace_back(tablet->GetFullTabletId());
- }
- }
- Self->ScheduleDisconnectNode(std::move(event));
- } else if (node->IsUnknown()) {
- BLOG_W("THive::TTxDisconnectNode() - killing node " << node->Id);
- Self->KillNode(node->Id, node->Local);
- }
- }
- return true;
- }
-
+ event->Tablets[tabletCategoryId].emplace_back(tablet->GetFullTabletId());
+ }
+ }
+ Self->ScheduleDisconnectNode(std::move(event));
+ } else if (node->IsUnknown()) {
+ BLOG_W("THive::TTxDisconnectNode() - killing node " << node->Id);
+ Self->KillNode(node->Id, node->Local);
+ }
+ }
+ return true;
+ }
+
void Complete(const TActorContext&) override {
- BLOG_D("THive::TTxDisconnectNode()::Complete");
- }
-};
-
-ITransaction* THive::CreateDisconnectNode(THolder<TEvInterconnect::TEvNodeDisconnected> event) {
- return new TTxDisconnectNode(std::move(event), this);
-}
-
-} // NHive
-} // NKikimr
+ BLOG_D("THive::TTxDisconnectNode()::Complete");
+ }
+};
+
+ITransaction* THive::CreateDisconnectNode(THolder<TEvInterconnect::TEvNodeDisconnected> event) {
+ return new TTxDisconnectNode(std::move(event), this);
+}
+
+} // NHive
+} // NKikimr
diff --git a/ydb/core/mind/hive/tx__init_scheme.cpp b/ydb/core/mind/hive/tx__init_scheme.cpp
index 5f9d9b8fe12..b65451f94a7 100644
--- a/ydb/core/mind/hive/tx__init_scheme.cpp
+++ b/ydb/core/mind/hive/tx__init_scheme.cpp
@@ -1,108 +1,108 @@
-#include "hive_impl.h"
-#include "hive_log.h"
+#include "hive_impl.h"
+#include "hive_log.h"
#include <library/cpp/actors/interconnect/interconnect.h>
-
-namespace NKikimr {
-namespace NHive {
-
-class TTxInitScheme : public TTransactionBase<THive> {
-public:
- TTxInitScheme(THive *hive)
- : TBase(hive)
- {}
-
- TTxType GetTxType() const override { return NHive::TXTYPE_INIT_SCHEME; }
-
+
+namespace NKikimr {
+namespace NHive {
+
+class TTxInitScheme : public TTransactionBase<THive> {
+public:
+ TTxInitScheme(THive *hive)
+ : TBase(hive)
+ {}
+
+ TTxType GetTxType() const override { return NHive::TXTYPE_INIT_SCHEME; }
+
bool Execute(TTransactionContext &txc, const TActorContext&) override {
- BLOG_D("THive::TTxInitScheme::Execute");
- NIceDb::TNiceDb(txc.DB).Materialize<Schema>();
- if (!txc.DB.GetScheme().IsEmpty()) {
- auto row = NIceDb::TNiceDb(txc.DB).Table<Schema::State>().Key(TSchemeIds::State::DatabaseVersion).Select<Schema::State::Value>();
- if (!row.IsReady())
- return false;
- auto version = row.GetValue<Schema::State::Value>();
- switch (version) {
- case 3:
- case 4:
- case 5:
- case 6:
- case 7:
- case 8:
- case 9:
- case 10: {
- break;
- }
- case 11: {
- NIceDb::TNiceDb db(txc.DB);
- auto tabletRowset = db.Table<Schema::OldTablet>().Range().Select<
- Schema::OldTablet::ID,
+ BLOG_D("THive::TTxInitScheme::Execute");
+ NIceDb::TNiceDb(txc.DB).Materialize<Schema>();
+ if (!txc.DB.GetScheme().IsEmpty()) {
+ auto row = NIceDb::TNiceDb(txc.DB).Table<Schema::State>().Key(TSchemeIds::State::DatabaseVersion).Select<Schema::State::Value>();
+ if (!row.IsReady())
+ return false;
+ auto version = row.GetValue<Schema::State::Value>();
+ switch (version) {
+ case 3:
+ case 4:
+ case 5:
+ case 6:
+ case 7:
+ case 8:
+ case 9:
+ case 10: {
+ break;
+ }
+ case 11: {
+ NIceDb::TNiceDb db(txc.DB);
+ auto tabletRowset = db.Table<Schema::OldTablet>().Range().Select<
+ Schema::OldTablet::ID,
Schema::OldTablet::CrossDataCenterFollowers,
Schema::OldTablet::FollowerCount,
Schema::OldTablet::AllowFollowerPromotion>();
- if (!tabletRowset.IsReady())
- return false;
- while (!tabletRowset.EndOfSet()) {
- TTabletId tabletId = tabletRowset.GetValue<Schema::OldTablet::ID>();
+ if (!tabletRowset.IsReady())
+ return false;
+ while (!tabletRowset.EndOfSet()) {
+ TTabletId tabletId = tabletRowset.GetValue<Schema::OldTablet::ID>();
ui32 followerCount = tabletRowset.GetValueOrDefault<Schema::OldTablet::FollowerCount>(0);
bool crossDataCenterFollowers = tabletRowset.GetValueOrDefault<Schema::OldTablet::CrossDataCenterFollowers>(false);
if (followerCount == 0 && crossDataCenterFollowers) {
- followerCount = Self->GetDataCenters();
- }
+ followerCount = Self->GetDataCenters();
+ }
bool allowFollowerPromotion = tabletRowset.GetValueOrDefault<Schema::OldTablet::AllowFollowerPromotion>();
if (followerCount > 0) {
db.Table<Schema::TabletFollowerGroup>().Key(tabletId, 1).Update(
NIceDb::TUpdate<Schema::TabletFollowerGroup::FollowerCount>(followerCount),
NIceDb::TUpdate<Schema::TabletFollowerGroup::AllowLeaderPromotion>(allowFollowerPromotion),
NIceDb::TUpdate<Schema::TabletFollowerGroup::AllowClientRead>(true));
- }
- if (!tabletRowset.Next())
- return false;
- }
- break;
- }
- case 12:
- case 13: {
- NIceDb::TNiceDb db(txc.DB);
- auto tabletRowset = db.Table<Schema::OldTablet>().Range().Select<
- Schema::OldTablet::ID,
+ }
+ if (!tabletRowset.Next())
+ return false;
+ }
+ break;
+ }
+ case 12:
+ case 13: {
+ NIceDb::TNiceDb db(txc.DB);
+ auto tabletRowset = db.Table<Schema::OldTablet>().Range().Select<
+ Schema::OldTablet::ID,
Schema::OldTablet::CrossDataCenterFollowerCount,
Schema::OldTablet::FollowerCount,
Schema::OldTablet::AllowFollowerPromotion>();
- if (!tabletRowset.IsReady())
- return false;
- while (!tabletRowset.EndOfSet()) {
- TTabletId tabletId = tabletRowset.GetValue<Schema::OldTablet::ID>();
+ if (!tabletRowset.IsReady())
+ return false;
+ while (!tabletRowset.EndOfSet()) {
+ TTabletId tabletId = tabletRowset.GetValue<Schema::OldTablet::ID>();
ui32 crossDataCenterFollowerCount = tabletRowset.GetValueOrDefault<Schema::OldTablet::CrossDataCenterFollowerCount>(0);
- ui32 followerCount = tabletRowset.GetValueOrDefault<Schema::OldTablet::FollowerCount>(Self->GetDataCenters() * crossDataCenterFollowerCount);
+ ui32 followerCount = tabletRowset.GetValueOrDefault<Schema::OldTablet::FollowerCount>(Self->GetDataCenters() * crossDataCenterFollowerCount);
bool allowFollowerPromotion = tabletRowset.GetValueOrDefault<Schema::OldTablet::AllowFollowerPromotion>();
if (followerCount > 0) {
db.Table<Schema::TabletFollowerGroup>().Key(tabletId, 1).Update(
NIceDb::TUpdate<Schema::TabletFollowerGroup::FollowerCount>(followerCount),
NIceDb::TUpdate<Schema::TabletFollowerGroup::AllowLeaderPromotion>(allowFollowerPromotion),
NIceDb::TUpdate<Schema::TabletFollowerGroup::AllowClientRead>(true));
- }
- if (!tabletRowset.Next())
- return false;
- }
- break;
- }
- }
- }
+ }
+ if (!tabletRowset.Next())
+ return false;
+ }
+ break;
+ }
+ }
+ }
NIceDb::TNiceDb(txc.DB).Table<Schema::State>().Key(TSchemeIds::State::DatabaseVersion).Update(NIceDb::TUpdate<Schema::State::Value>(19));
- return true;
- }
-
+ return true;
+ }
+
void Complete(const TActorContext& ctx) override {
- BLOG_D("THive::TTxInitScheme::Complete");
+ BLOG_D("THive::TTxInitScheme::Complete");
const TActorId nameserviceId = GetNameserviceActorId();
- ctx.Send(nameserviceId, new TEvInterconnect::TEvListNodes());
- }
-};
-
+ ctx.Send(nameserviceId, new TEvInterconnect::TEvListNodes());
+ }
+};
+
ITransaction* THive::CreateInitScheme() {
- return new TTxInitScheme(this);
-}
-
-} // NHive
-} // NKikimr
-
+ return new TTxInitScheme(this);
+}
+
+} // NHive
+} // NKikimr
+
diff --git a/ydb/core/mind/hive/tx__kill_node.cpp b/ydb/core/mind/hive/tx__kill_node.cpp
index 01e28e7f6ce..268327a0ddd 100644
--- a/ydb/core/mind/hive/tx__kill_node.cpp
+++ b/ydb/core/mind/hive/tx__kill_node.cpp
@@ -1,76 +1,76 @@
-#include "hive_impl.h"
-#include "hive_log.h"
-
-namespace NKikimr {
-namespace NHive {
-
-class TTxKillNode : public TTransactionBase<THive> {
-protected:
- TNodeId NodeId;
+#include "hive_impl.h"
+#include "hive_log.h"
+
+namespace NKikimr {
+namespace NHive {
+
+class TTxKillNode : public TTransactionBase<THive> {
+protected:
+ TNodeId NodeId;
TActorId Local;
-public:
- TTxKillNode(TNodeId nodeId, const TActorId& local, THive *hive)
- : TBase(hive)
- , NodeId(nodeId)
- , Local(local)
- {}
-
- TTxType GetTxType() const override { return NHive::TXTYPE_KILL_NODE; }
-
- bool Execute(TTransactionContext &txc, const TActorContext&) override {
- BLOG_D("THive::TTxKillNode(" << NodeId << ")::Execute");
- TInstant now = TInstant::Now();
- TNodeInfo* node = Self->FindNode(NodeId);
- if (node != nullptr) {
- Local = node->Local;
- NIceDb::TNiceDb db(txc.DB);
- for (const auto& t : node->Tablets) {
- for (TTabletInfo* tablet : t.second) {
- if (tablet->NodeId != 0) {
+public:
+ TTxKillNode(TNodeId nodeId, const TActorId& local, THive *hive)
+ : TBase(hive)
+ , NodeId(nodeId)
+ , Local(local)
+ {}
+
+ TTxType GetTxType() const override { return NHive::TXTYPE_KILL_NODE; }
+
+ bool Execute(TTransactionContext &txc, const TActorContext&) override {
+ BLOG_D("THive::TTxKillNode(" << NodeId << ")::Execute");
+ TInstant now = TInstant::Now();
+ TNodeInfo* node = Self->FindNode(NodeId);
+ if (node != nullptr) {
+ Local = node->Local;
+ NIceDb::TNiceDb db(txc.DB);
+ for (const auto& t : node->Tablets) {
+ for (TTabletInfo* tablet : t.second) {
+ if (tablet->NodeId != 0) {
TTabletId tabletId = tablet->GetLeader().Id;
if (tablet->IsLeader()) {
db.Table<Schema::Tablet>().Key(tabletId).Update<Schema::Tablet::LeaderNode>(0);
- } else {
+ } else {
db.Table<Schema::TabletFollowerTablet>().Key(tablet->GetFullTabletId()).Update<Schema::TabletFollowerTablet::FollowerNode>(0);
- }
- }
- }
- }
- if (node->IsAlive()) {
- node->Statistics.SetLastAliveTimestamp(now.MilliSeconds());
- db.Table<Schema::Node>().Key(NodeId).Update<Schema::Node::Statistics>(node->Statistics);
- }
- node->BecomeDisconnected();
- for (const TActorId& pipeServer : node->PipeServers) {
- BLOG_TRACE("THive::TTxKillNode - killing pipe server " << pipeServer);
- Self->Send(pipeServer, new TEvents::TEvPoisonPill());
- }
- node->PipeServers.clear();
- if (node->CanBeDeleted()) {
- db.Table<Schema::Node>().Key(NodeId).Delete();
- Self->DeleteNode(NodeId);
- } else {
+ }
+ }
+ }
+ }
+ if (node->IsAlive()) {
+ node->Statistics.SetLastAliveTimestamp(now.MilliSeconds());
+ db.Table<Schema::Node>().Key(NodeId).Update<Schema::Node::Statistics>(node->Statistics);
+ }
+ node->BecomeDisconnected();
+ for (const TActorId& pipeServer : node->PipeServers) {
+ BLOG_TRACE("THive::TTxKillNode - killing pipe server " << pipeServer);
+ Self->Send(pipeServer, new TEvents::TEvPoisonPill());
+ }
+ node->PipeServers.clear();
+ if (node->CanBeDeleted()) {
+ db.Table<Schema::Node>().Key(NodeId).Delete();
+ Self->DeleteNode(NodeId);
+ } else {
db.Table<Schema::Node>().Key(NodeId).Update<Schema::Node::Local>(TActorId());
- }
- }
- return true;
- }
-
- void Complete(const TActorContext&) override {
- BLOG_D("THive::TTxKillNode(" << NodeId << ")::Complete");
- if (Local) {
- TNodeInfo* node = Self->FindNode(Local.NodeId());
- if (node == nullptr || node->IsDisconnected()) {
- BLOG_D("THive::TTxKillNode(" << NodeId << ")::Complete - send Reconnect to " << Local);
- Self->SendReconnect(Local); // defibrillation
- }
- }
- }
-};
-
-ITransaction* THive::CreateKillNode(TNodeId nodeId, const TActorId& local) {
- return new TTxKillNode(nodeId, local, this);
-}
-
-} // NHive
-} // NKikimr
+ }
+ }
+ return true;
+ }
+
+ void Complete(const TActorContext&) override {
+ BLOG_D("THive::TTxKillNode(" << NodeId << ")::Complete");
+ if (Local) {
+ TNodeInfo* node = Self->FindNode(Local.NodeId());
+ if (node == nullptr || node->IsDisconnected()) {
+ BLOG_D("THive::TTxKillNode(" << NodeId << ")::Complete - send Reconnect to " << Local);
+ Self->SendReconnect(Local); // defibrillation
+ }
+ }
+ }
+};
+
+ITransaction* THive::CreateKillNode(TNodeId nodeId, const TActorId& local) {
+ return new TTxKillNode(nodeId, local, this);
+}
+
+} // NHive
+} // NKikimr
diff --git a/ydb/core/mind/hive/tx__load_everything.cpp b/ydb/core/mind/hive/tx__load_everything.cpp
index 00318e6f3fe..e4c1cf1f51e 100644
--- a/ydb/core/mind/hive/tx__load_everything.cpp
+++ b/ydb/core/mind/hive/tx__load_everything.cpp
@@ -1,351 +1,351 @@
-#include "hive_impl.h"
-#include "hive_log.h"
-
-namespace NKikimr {
-namespace NHive {
-
-class TTxLoadEverything : public TTransactionBase<THive> {
-public:
- TTxLoadEverything(THive *hive)
- : TBase(hive)
- {}
-
- TTxType GetTxType() const override { return NHive::TXTYPE_LOAD_EVERYTHING; }
-
+#include "hive_impl.h"
+#include "hive_log.h"
+
+namespace NKikimr {
+namespace NHive {
+
+class TTxLoadEverything : public TTransactionBase<THive> {
+public:
+ TTxLoadEverything(THive *hive)
+ : TBase(hive)
+ {}
+
+ TTxType GetTxType() const override { return NHive::TXTYPE_LOAD_EVERYTHING; }
+
bool Execute(TTransactionContext &txc, const TActorContext&) override {
- BLOG_D("THive::TTxLoadEverything::Execute");
-
- TAppData* appData = AppData();
- TDomainsInfo* domainsInfo = appData->DomainsInfo.Get();
- const TDomainsInfo::TDomain& domain = domainsInfo->GetDomain(Self->HiveDomain);
-
- TTabletId rootHiveId = domainsInfo->GetHive(domain.DefaultHiveUid);
- bool isRootHive = (rootHiveId == Self->TabletID());
-
- NIceDb::TNiceDb db(txc.DB);
-
- Self->Nodes.clear();
- Self->TabletCategories.clear();
- Self->Tablets.clear();
- Self->OwnerToTablet.clear();
- Self->ObjectToTabletMetrics.clear();
- Self->TabletTypeToTabletMetrics.clear();
- Self->TabletTypeAllowedMetrics.clear();
- Self->StoragePools.clear();
- Self->Sequencer.Clear();
- Self->Keeper.Clear();
- Self->Domains.clear();
- Self->BlockedOwners.clear();
-
- Self->Domains[Self->RootDomainKey].Path = Self->RootDomainName;
- Self->Domains[Self->RootDomainKey].HiveId = rootHiveId;
-
- {
- // precharge
- auto tabletRowset = db.Table<Schema::Tablet>().Range().Select();
- auto tabletChannelRowset = db.Table<Schema::TabletChannel>().Range().Select();
- auto tabletChannelGenRowset = db.Table<Schema::TabletChannelGen>().Range().Select();
+ BLOG_D("THive::TTxLoadEverything::Execute");
+
+ TAppData* appData = AppData();
+ TDomainsInfo* domainsInfo = appData->DomainsInfo.Get();
+ const TDomainsInfo::TDomain& domain = domainsInfo->GetDomain(Self->HiveDomain);
+
+ TTabletId rootHiveId = domainsInfo->GetHive(domain.DefaultHiveUid);
+ bool isRootHive = (rootHiveId == Self->TabletID());
+
+ NIceDb::TNiceDb db(txc.DB);
+
+ Self->Nodes.clear();
+ Self->TabletCategories.clear();
+ Self->Tablets.clear();
+ Self->OwnerToTablet.clear();
+ Self->ObjectToTabletMetrics.clear();
+ Self->TabletTypeToTabletMetrics.clear();
+ Self->TabletTypeAllowedMetrics.clear();
+ Self->StoragePools.clear();
+ Self->Sequencer.Clear();
+ Self->Keeper.Clear();
+ Self->Domains.clear();
+ Self->BlockedOwners.clear();
+
+ Self->Domains[Self->RootDomainKey].Path = Self->RootDomainName;
+ Self->Domains[Self->RootDomainKey].HiveId = rootHiveId;
+
+ {
+ // precharge
+ auto tabletRowset = db.Table<Schema::Tablet>().Range().Select();
+ auto tabletChannelRowset = db.Table<Schema::TabletChannel>().Range().Select();
+ auto tabletChannelGenRowset = db.Table<Schema::TabletChannelGen>().Range().Select();
auto metrics = db.Table<Schema::Metrics>().Range().Select();
auto tabletFollowerGroupRowset = db.Table<Schema::TabletFollowerGroup>().Range().Select();
auto tabletFollowerRowset = db.Table<Schema::TabletFollowerTablet>().Range().Select();
- auto tabletTypeAllowedMetrics = db.Table<Schema::TabletTypeMetrics>().Range().Select();
- auto stateRowset = db.Table<Schema::State>().Select();
- auto sequencesRowset = db.Table<Schema::Sequences>().Select();
- auto domainsRowset = db.Table<Schema::SubDomain>().Select();
- auto blockedOwnersRowset = db.Table<Schema::BlockedOwner>().Select();
- auto tabletOwnersRowset = db.Table<Schema::TabletOwners>().Select();
- if (!tabletRowset.IsReady()
- || !tabletChannelRowset.IsReady()
- || !tabletChannelGenRowset.IsReady()
+ auto tabletTypeAllowedMetrics = db.Table<Schema::TabletTypeMetrics>().Range().Select();
+ auto stateRowset = db.Table<Schema::State>().Select();
+ auto sequencesRowset = db.Table<Schema::Sequences>().Select();
+ auto domainsRowset = db.Table<Schema::SubDomain>().Select();
+ auto blockedOwnersRowset = db.Table<Schema::BlockedOwner>().Select();
+ auto tabletOwnersRowset = db.Table<Schema::TabletOwners>().Select();
+ if (!tabletRowset.IsReady()
+ || !tabletChannelRowset.IsReady()
+ || !tabletChannelGenRowset.IsReady()
|| !metrics.IsReady()
|| !tabletFollowerGroupRowset.IsReady()
|| !tabletFollowerRowset.IsReady()
- || !tabletTypeAllowedMetrics.IsReady()
- || !stateRowset.IsReady()
- || !sequencesRowset.IsReady()
- || !domainsRowset.IsReady()
- || !blockedOwnersRowset.IsReady()
- || !tabletOwnersRowset.IsReady())
- return false;
- }
-
- {
- auto configRowset = db.Table<Schema::State>().Key(TSchemeIds::State::DefaultState).Select();
- if (!configRowset.IsReady()) {
- return false;
- }
- if (!configRowset.EndOfSet()) {
- Self->DatabaseConfig = configRowset.GetValueOrDefault<Schema::State::Config>();
- }
- }
-
- {
- auto stateRowset = db.Table<Schema::State>().Select();
- if (!stateRowset.IsReady()) {
- return false;
- }
- while (!stateRowset.EndOfSet()) {
- if (stateRowset.HaveValue<Schema::State::Value>()) {
- switch (stateRowset.GetKey()) {
- case TSchemeIds::State::DatabaseVersion:
- break;
- case TSchemeIds::State::NextTabletId:
- Self->NextTabletId = stateRowset.GetValueOrDefault<Schema::State::Value>(Self->NextTabletId);
- break;
- case TSchemeIds::State::MaxResourceCounter:
- Self->DatabaseConfig.SetMaxResourceCounter(stateRowset.GetValue<Schema::State::Value>());
- break;
- case TSchemeIds::State::MaxResourceCPU:
- Self->DatabaseConfig.SetMaxResourceCPU(stateRowset.GetValue<Schema::State::Value>());
- break;
- case TSchemeIds::State::MaxResourceMemory:
- Self->DatabaseConfig.SetMaxResourceMemory(stateRowset.GetValue<Schema::State::Value>());
- break;
- case TSchemeIds::State::MaxResourceNetwork:
- Self->DatabaseConfig.SetMaxResourceNetwork(stateRowset.GetValue<Schema::State::Value>());
- break;
- case TSchemeIds::State::MaxTabletsScheduled:
- Self->DatabaseConfig.SetMaxTabletsScheduled(stateRowset.GetValue<Schema::State::Value>());
- break;
- case TSchemeIds::State::MaxBootBatchSize:
- Self->DatabaseConfig.SetMaxBootBatchSize(stateRowset.GetValue<Schema::State::Value>());
- break;
- case TSchemeIds::State::DrainInflight:
- Self->DatabaseConfig.SetDrainInflight(stateRowset.GetValue<Schema::State::Value>());
- break;
- case TSchemeIds::State::MinScatterToBalance:
- Self->DatabaseConfig.SetMinScatterToBalance(double(stateRowset.GetValue<Schema::State::Value>()) / 100);
- break;
- case TSchemeIds::State::SpreadNeighbours:
- Self->DatabaseConfig.SetSpreadNeighbours(stateRowset.GetValue<Schema::State::Value>() != 0);
- break;
- case TSchemeIds::State::DefaultUnitIOPS:
- Self->DatabaseConfig.SetDefaultUnitIOPS(stateRowset.GetValue<Schema::State::Value>());
- break;
- case TSchemeIds::State::DefaultUnitThroughput:
- Self->DatabaseConfig.SetDefaultUnitThroughput(stateRowset.GetValue<Schema::State::Value>());
- break;
- case TSchemeIds::State::DefaultUnitSize:
- Self->DatabaseConfig.SetDefaultUnitSize(stateRowset.GetValue<Schema::State::Value>());
- break;
- case TSchemeIds::State::StorageOvercommit:
- Self->DatabaseConfig.SetStorageOvercommit(double(stateRowset.GetValue<Schema::State::Value>()) / 100);
- break;
- case TSchemeIds::State::StorageBalanceStrategy:
- Self->DatabaseConfig.SetStorageBalanceStrategy((NKikimrConfig::THiveConfig::EHiveStorageBalanceStrategy)stateRowset.GetValue<Schema::State::Value>());
- break;
- case TSchemeIds::State::StorageSelectStrategy:
- Self->DatabaseConfig.SetStorageSelectStrategy((NKikimrConfig::THiveConfig::EHiveStorageSelectStrategy)stateRowset.GetValue<Schema::State::Value>());
- break;
- case TSchemeIds::State::StorageSafeMode:
- Self->DatabaseConfig.SetStorageSafeMode(stateRowset.GetValue<Schema::State::Value>() != 0);
- break;
- case TSchemeIds::State::RequestSequenceSize:
- Self->DatabaseConfig.SetRequestSequenceSize(stateRowset.GetValue<Schema::State::Value>());
- break;
- case TSchemeIds::State::MinRequestSequenceSize:
- Self->DatabaseConfig.SetMinRequestSequenceSize(stateRowset.GetValue<Schema::State::Value>());
- break;
- case TSchemeIds::State::MaxRequestSequenceSize:
- Self->DatabaseConfig.SetMaxRequestSequenceSize(stateRowset.GetValue<Schema::State::Value>());
- break;
- case TSchemeIds::State::MetricsWindowSize:
- Self->DatabaseConfig.SetMetricsWindowSize(stateRowset.GetValue<Schema::State::Value>());
- break;
- case TSchemeIds::State::MaxNodeUsageToKick:
- Self->DatabaseConfig.SetMaxNodeUsageToKick((double)stateRowset.GetValue<Schema::State::Value>() / 100);
- break;
- case TSchemeIds::State::ResourceChangeReactionPeriod:
- Self->DatabaseConfig.SetResourceChangeReactionPeriod(stateRowset.GetValue<Schema::State::Value>());
- break;
- case TSchemeIds::State::TabletKickCooldownPeriod:
- Self->DatabaseConfig.SetTabletKickCooldownPeriod(stateRowset.GetValue<Schema::State::Value>());
- break;
- case TSchemeIds::State::ResourceOvercommitment:
- Self->DatabaseConfig.SetResourceOvercommitment((double)stateRowset.GetValue<Schema::State::Value>() / 100);
- break;
- }
- }
- stateRowset.Next();
- }
- }
-
- Self->BuildCurrentConfig();
-
- Self->DefaultResourceMetricsAggregates.MaximumCPU.SetWindowSize(TDuration::MilliSeconds(Self->GetMetricsWindowSize()));
- Self->DefaultResourceMetricsAggregates.MaximumMemory.SetWindowSize(TDuration::MilliSeconds(Self->GetMetricsWindowSize()));
- Self->DefaultResourceMetricsAggregates.MaximumNetwork.SetWindowSize(TDuration::MilliSeconds(Self->GetMetricsWindowSize()));
-
- auto owners = db.Table<Schema::TabletOwners>().Select();
- if (!owners.IsReady()) {
- return false;
- }
- while (!owners.EndOfSet()) {
- auto begin = owners.GetValue<Schema::TabletOwners::Begin>();
- auto end = owners.GetValue<Schema::TabletOwners::End>();
- auto ownerId = owners.GetValue<Schema::TabletOwners::OwnerId>();
-
- Self->Keeper.AddOwnedSequence(ownerId, {begin, end});
- if (!owners.Next()) {
- return false;
- }
- }
-
- size_t numSequences = 0;
- auto sequences = db.Table<Schema::Sequences>().Select();
- if (!sequences.IsReady()) {
- return false;
- }
- while (!sequences.EndOfSet()) {
- auto begin = sequences.GetValue<Schema::Sequences::Begin>();
- auto end = sequences.GetValue<Schema::Sequences::End>();
- auto next = sequences.GetValue<Schema::Sequences::Next>();
- auto ownerId = sequences.GetValue<Schema::Sequences::OwnerId>();
- auto ownerIdx = sequences.GetValue<Schema::Sequences::OwnerIdx>();
- TSequencer::TSequence seq(begin, next, end);
-
- Self->Sequencer.AddSequence({ownerId, ownerIdx}, seq);
- ++numSequences;
-
- // remove after upgrade vvvv
- if (ownerId != TSequencer::NO_OWNER && Self->Keeper.GetOwner(seq.Begin) == TSequencer::NO_OWNER) {
- BLOG_W("THive::TTxLoadEverything fixing TabletOwners for " << seq << " to " << ownerId);
- Self->Keeper.AddOwnedSequence(ownerId, seq);
- db.Table<Schema::TabletOwners>().Key(seq.Begin, seq.End).Update<Schema::TabletOwners::OwnerId>(ownerId);
- }
-
- if (ownerId == TSequencer::NO_OWNER && !isRootHive && Self->Keeper.GetOwner(seq.Begin) == TSequencer::NO_OWNER) {
- BLOG_W("THive::TTxLoadEverything fixing TabletOwners for " << seq << " to " << Self->TabletID());
- Self->Keeper.AddOwnedSequence(Self->TabletID(), seq);
- db.Table<Schema::TabletOwners>().Key(seq.Begin, seq.End).Update<Schema::TabletOwners::OwnerId>(Self->TabletID());
- }
- // remove after upgrade ^^^^
-
- if (!sequences.Next()) {
- return false;
- }
- }
-
- auto tabletTypeAllowedMetrics = db.Table<Schema::TabletTypeMetrics>().Select();
- if (!tabletTypeAllowedMetrics.IsReady())
- return false;
- while (!tabletTypeAllowedMetrics.EndOfSet()) {
- auto type = tabletTypeAllowedMetrics.GetValue<Schema::TabletTypeMetrics::TabletType>();
- auto& allowedMetrics = Self->TabletTypeAllowedMetrics[type];
- allowedMetrics = tabletTypeAllowedMetrics.GetValue<Schema::TabletTypeMetrics::AllowedMetricIDs>();
- if (Find(allowedMetrics, NKikimrTabletBase::TMetrics::kCounterFieldNumber) == allowedMetrics.end()) {
- allowedMetrics.emplace_back(NKikimrTabletBase::TMetrics::kCounterFieldNumber);
- }
- if (!tabletTypeAllowedMetrics.Next())
- return false;
- }
-
- {
- auto domainRowset = db.Table<Schema::SubDomain>().Range().Select();
- if (!domainRowset.IsReady())
- return false;
- while (!domainRowset.EndOfSet()) {
- TSubDomainKey key(domainRowset.GetKey());
- TDomainInfo& domain = Self->Domains.emplace(key, TDomainInfo()).first->second;
- domain.Path = domainRowset.GetValueOrDefault<Schema::SubDomain::Path>();
- domain.HiveId = domainRowset.GetValueOrDefault<Schema::SubDomain::HiveId>();
- if (domain.HiveId == 0) {
- domain.Path.clear(); // we will refresh domain one more time to see if it has Hive now
- }
- if (domainRowset.GetValueOrDefault<Schema::SubDomain::Primary>()) {
- Self->PrimaryDomainKey = key;
- }
- if (!domainRowset.Next())
- return false;
- }
- }
-
- {
- auto blockedOwnerRowset = db.Table<Schema::BlockedOwner>().Range().Select();
- if (!blockedOwnerRowset.IsReady())
- return false;
- while (!blockedOwnerRowset.EndOfSet()) {
- Self->BlockedOwners.emplace(blockedOwnerRowset.GetKey());
- if (!blockedOwnerRowset.Next())
- return false;
- }
- }
-
- {
- auto nodeRowset = db.Table<Schema::Node>().Range().Select();
- if (!nodeRowset.IsReady())
- return false;
- while (!nodeRowset.EndOfSet()) {
- TNodeId nodeId = nodeRowset.GetValue<Schema::Node::ID>();
- TNodeInfo& node = Self->Nodes.emplace(std::piecewise_construct, std::tuple<TNodeId>(nodeId), std::tuple<TNodeId, THive&>(nodeId, *Self)).first->second;
- node.Local = nodeRowset.GetValue<Schema::Node::Local>();
- node.Down = nodeRowset.GetValue<Schema::Node::Down>();
- node.Freeze = nodeRowset.GetValue<Schema::Node::Freeze>();
- node.Drain = nodeRowset.GetValueOrDefault<Schema::Node::Drain>();
- node.DrainInitiators = nodeRowset.GetValueOrDefault<Schema::Node::DrainInitiators>();
- node.ServicedDomains = nodeRowset.GetValueOrDefault<Schema::Node::ServicedDomains>();
- node.Statistics = nodeRowset.GetValueOrDefault<Schema::Node::Statistics>();
- if (nodeRowset.HaveValue<Schema::Node::Location>()) {
- auto location = nodeRowset.GetValue<Schema::Node::Location>();
- if (location.HasDataCenter()) {
- node.Location = TNodeLocation(location);
- node.LocationAcquired = true;
- }
- }
- if (!node.ServicedDomains) {
- node.ServicedDomains = { Self->RootDomainKey };
- }
- node.LastSeenServicedDomains = node.ServicedDomains; // to keep Down and Freeze flags on restarts
- if (!(bool)node.Local) {
- // it's safe to call here, because there is no any tablets in the node yet
- node.BecomeDisconnected();
- }
- if (node.CanBeDeleted()) {
- db.Table<Schema::Node>().Key(nodeId).Delete();
- Self->Nodes.erase(nodeId);
- }
- if (!nodeRowset.Next())
- return false;
- }
- }
-
- {
- auto categoryRowset = db.Table<Schema::TabletCategory>().Range().Select();
- if (!categoryRowset.IsReady())
- return false;
- while (!categoryRowset.EndOfSet()) {
- TTabletCategoryId categoryId = categoryRowset.GetValue<Schema::TabletCategory::ID>();
- TTabletCategoryInfo& category = Self->TabletCategories.insert(std::make_pair(categoryId, TTabletCategoryInfo(categoryId))).first->second;
- category.MaxDisconnectTimeout = categoryRowset.GetValueOrDefault<Schema::TabletCategory::MaxDisconnectTimeout>();
- category.StickTogetherInDC = categoryRowset.GetValueOrDefault<Schema::TabletCategory::StickTogetherInDC>();
- if (!categoryRowset.Next())
- return false;
- }
- }
-
- if (Self->CurrentConfig.GetSystemTabletCategoryId() != 0 && Self->TabletCategories.empty()) {
- db.Table<Schema::TabletCategory>().Key(Self->CurrentConfig.GetSystemTabletCategoryId()).Update<Schema::TabletCategory::StickTogetherInDC>(true);
- }
-
- TTabletId maxTabletId = 0;
-
- {
- auto tabletRowset = db.Table<Schema::Tablet>().Range().Select();
- if (!tabletRowset.IsReady())
- return false;
- while (!tabletRowset.EndOfSet()) {
- TTabletId tabletId = tabletRowset.GetValue<Schema::Tablet::ID>();
- maxTabletId = std::max(maxTabletId, UniqPartFromTabletID(tabletId));
+ || !tabletTypeAllowedMetrics.IsReady()
+ || !stateRowset.IsReady()
+ || !sequencesRowset.IsReady()
+ || !domainsRowset.IsReady()
+ || !blockedOwnersRowset.IsReady()
+ || !tabletOwnersRowset.IsReady())
+ return false;
+ }
+
+ {
+ auto configRowset = db.Table<Schema::State>().Key(TSchemeIds::State::DefaultState).Select();
+ if (!configRowset.IsReady()) {
+ return false;
+ }
+ if (!configRowset.EndOfSet()) {
+ Self->DatabaseConfig = configRowset.GetValueOrDefault<Schema::State::Config>();
+ }
+ }
+
+ {
+ auto stateRowset = db.Table<Schema::State>().Select();
+ if (!stateRowset.IsReady()) {
+ return false;
+ }
+ while (!stateRowset.EndOfSet()) {
+ if (stateRowset.HaveValue<Schema::State::Value>()) {
+ switch (stateRowset.GetKey()) {
+ case TSchemeIds::State::DatabaseVersion:
+ break;
+ case TSchemeIds::State::NextTabletId:
+ Self->NextTabletId = stateRowset.GetValueOrDefault<Schema::State::Value>(Self->NextTabletId);
+ break;
+ case TSchemeIds::State::MaxResourceCounter:
+ Self->DatabaseConfig.SetMaxResourceCounter(stateRowset.GetValue<Schema::State::Value>());
+ break;
+ case TSchemeIds::State::MaxResourceCPU:
+ Self->DatabaseConfig.SetMaxResourceCPU(stateRowset.GetValue<Schema::State::Value>());
+ break;
+ case TSchemeIds::State::MaxResourceMemory:
+ Self->DatabaseConfig.SetMaxResourceMemory(stateRowset.GetValue<Schema::State::Value>());
+ break;
+ case TSchemeIds::State::MaxResourceNetwork:
+ Self->DatabaseConfig.SetMaxResourceNetwork(stateRowset.GetValue<Schema::State::Value>());
+ break;
+ case TSchemeIds::State::MaxTabletsScheduled:
+ Self->DatabaseConfig.SetMaxTabletsScheduled(stateRowset.GetValue<Schema::State::Value>());
+ break;
+ case TSchemeIds::State::MaxBootBatchSize:
+ Self->DatabaseConfig.SetMaxBootBatchSize(stateRowset.GetValue<Schema::State::Value>());
+ break;
+ case TSchemeIds::State::DrainInflight:
+ Self->DatabaseConfig.SetDrainInflight(stateRowset.GetValue<Schema::State::Value>());
+ break;
+ case TSchemeIds::State::MinScatterToBalance:
+ Self->DatabaseConfig.SetMinScatterToBalance(double(stateRowset.GetValue<Schema::State::Value>()) / 100);
+ break;
+ case TSchemeIds::State::SpreadNeighbours:
+ Self->DatabaseConfig.SetSpreadNeighbours(stateRowset.GetValue<Schema::State::Value>() != 0);
+ break;
+ case TSchemeIds::State::DefaultUnitIOPS:
+ Self->DatabaseConfig.SetDefaultUnitIOPS(stateRowset.GetValue<Schema::State::Value>());
+ break;
+ case TSchemeIds::State::DefaultUnitThroughput:
+ Self->DatabaseConfig.SetDefaultUnitThroughput(stateRowset.GetValue<Schema::State::Value>());
+ break;
+ case TSchemeIds::State::DefaultUnitSize:
+ Self->DatabaseConfig.SetDefaultUnitSize(stateRowset.GetValue<Schema::State::Value>());
+ break;
+ case TSchemeIds::State::StorageOvercommit:
+ Self->DatabaseConfig.SetStorageOvercommit(double(stateRowset.GetValue<Schema::State::Value>()) / 100);
+ break;
+ case TSchemeIds::State::StorageBalanceStrategy:
+ Self->DatabaseConfig.SetStorageBalanceStrategy((NKikimrConfig::THiveConfig::EHiveStorageBalanceStrategy)stateRowset.GetValue<Schema::State::Value>());
+ break;
+ case TSchemeIds::State::StorageSelectStrategy:
+ Self->DatabaseConfig.SetStorageSelectStrategy((NKikimrConfig::THiveConfig::EHiveStorageSelectStrategy)stateRowset.GetValue<Schema::State::Value>());
+ break;
+ case TSchemeIds::State::StorageSafeMode:
+ Self->DatabaseConfig.SetStorageSafeMode(stateRowset.GetValue<Schema::State::Value>() != 0);
+ break;
+ case TSchemeIds::State::RequestSequenceSize:
+ Self->DatabaseConfig.SetRequestSequenceSize(stateRowset.GetValue<Schema::State::Value>());
+ break;
+ case TSchemeIds::State::MinRequestSequenceSize:
+ Self->DatabaseConfig.SetMinRequestSequenceSize(stateRowset.GetValue<Schema::State::Value>());
+ break;
+ case TSchemeIds::State::MaxRequestSequenceSize:
+ Self->DatabaseConfig.SetMaxRequestSequenceSize(stateRowset.GetValue<Schema::State::Value>());
+ break;
+ case TSchemeIds::State::MetricsWindowSize:
+ Self->DatabaseConfig.SetMetricsWindowSize(stateRowset.GetValue<Schema::State::Value>());
+ break;
+ case TSchemeIds::State::MaxNodeUsageToKick:
+ Self->DatabaseConfig.SetMaxNodeUsageToKick((double)stateRowset.GetValue<Schema::State::Value>() / 100);
+ break;
+ case TSchemeIds::State::ResourceChangeReactionPeriod:
+ Self->DatabaseConfig.SetResourceChangeReactionPeriod(stateRowset.GetValue<Schema::State::Value>());
+ break;
+ case TSchemeIds::State::TabletKickCooldownPeriod:
+ Self->DatabaseConfig.SetTabletKickCooldownPeriod(stateRowset.GetValue<Schema::State::Value>());
+ break;
+ case TSchemeIds::State::ResourceOvercommitment:
+ Self->DatabaseConfig.SetResourceOvercommitment((double)stateRowset.GetValue<Schema::State::Value>() / 100);
+ break;
+ }
+ }
+ stateRowset.Next();
+ }
+ }
+
+ Self->BuildCurrentConfig();
+
+ Self->DefaultResourceMetricsAggregates.MaximumCPU.SetWindowSize(TDuration::MilliSeconds(Self->GetMetricsWindowSize()));
+ Self->DefaultResourceMetricsAggregates.MaximumMemory.SetWindowSize(TDuration::MilliSeconds(Self->GetMetricsWindowSize()));
+ Self->DefaultResourceMetricsAggregates.MaximumNetwork.SetWindowSize(TDuration::MilliSeconds(Self->GetMetricsWindowSize()));
+
+ auto owners = db.Table<Schema::TabletOwners>().Select();
+ if (!owners.IsReady()) {
+ return false;
+ }
+ while (!owners.EndOfSet()) {
+ auto begin = owners.GetValue<Schema::TabletOwners::Begin>();
+ auto end = owners.GetValue<Schema::TabletOwners::End>();
+ auto ownerId = owners.GetValue<Schema::TabletOwners::OwnerId>();
+
+ Self->Keeper.AddOwnedSequence(ownerId, {begin, end});
+ if (!owners.Next()) {
+ return false;
+ }
+ }
+
+ size_t numSequences = 0;
+ auto sequences = db.Table<Schema::Sequences>().Select();
+ if (!sequences.IsReady()) {
+ return false;
+ }
+ while (!sequences.EndOfSet()) {
+ auto begin = sequences.GetValue<Schema::Sequences::Begin>();
+ auto end = sequences.GetValue<Schema::Sequences::End>();
+ auto next = sequences.GetValue<Schema::Sequences::Next>();
+ auto ownerId = sequences.GetValue<Schema::Sequences::OwnerId>();
+ auto ownerIdx = sequences.GetValue<Schema::Sequences::OwnerIdx>();
+ TSequencer::TSequence seq(begin, next, end);
+
+ Self->Sequencer.AddSequence({ownerId, ownerIdx}, seq);
+ ++numSequences;
+
+ // remove after upgrade vvvv
+ if (ownerId != TSequencer::NO_OWNER && Self->Keeper.GetOwner(seq.Begin) == TSequencer::NO_OWNER) {
+ BLOG_W("THive::TTxLoadEverything fixing TabletOwners for " << seq << " to " << ownerId);
+ Self->Keeper.AddOwnedSequence(ownerId, seq);
+ db.Table<Schema::TabletOwners>().Key(seq.Begin, seq.End).Update<Schema::TabletOwners::OwnerId>(ownerId);
+ }
+
+ if (ownerId == TSequencer::NO_OWNER && !isRootHive && Self->Keeper.GetOwner(seq.Begin) == TSequencer::NO_OWNER) {
+ BLOG_W("THive::TTxLoadEverything fixing TabletOwners for " << seq << " to " << Self->TabletID());
+ Self->Keeper.AddOwnedSequence(Self->TabletID(), seq);
+ db.Table<Schema::TabletOwners>().Key(seq.Begin, seq.End).Update<Schema::TabletOwners::OwnerId>(Self->TabletID());
+ }
+ // remove after upgrade ^^^^
+
+ if (!sequences.Next()) {
+ return false;
+ }
+ }
+
+ auto tabletTypeAllowedMetrics = db.Table<Schema::TabletTypeMetrics>().Select();
+ if (!tabletTypeAllowedMetrics.IsReady())
+ return false;
+ while (!tabletTypeAllowedMetrics.EndOfSet()) {
+ auto type = tabletTypeAllowedMetrics.GetValue<Schema::TabletTypeMetrics::TabletType>();
+ auto& allowedMetrics = Self->TabletTypeAllowedMetrics[type];
+ allowedMetrics = tabletTypeAllowedMetrics.GetValue<Schema::TabletTypeMetrics::AllowedMetricIDs>();
+ if (Find(allowedMetrics, NKikimrTabletBase::TMetrics::kCounterFieldNumber) == allowedMetrics.end()) {
+ allowedMetrics.emplace_back(NKikimrTabletBase::TMetrics::kCounterFieldNumber);
+ }
+ if (!tabletTypeAllowedMetrics.Next())
+ return false;
+ }
+
+ {
+ auto domainRowset = db.Table<Schema::SubDomain>().Range().Select();
+ if (!domainRowset.IsReady())
+ return false;
+ while (!domainRowset.EndOfSet()) {
+ TSubDomainKey key(domainRowset.GetKey());
+ TDomainInfo& domain = Self->Domains.emplace(key, TDomainInfo()).first->second;
+ domain.Path = domainRowset.GetValueOrDefault<Schema::SubDomain::Path>();
+ domain.HiveId = domainRowset.GetValueOrDefault<Schema::SubDomain::HiveId>();
+ if (domain.HiveId == 0) {
+ domain.Path.clear(); // we will refresh domain one more time to see if it has Hive now
+ }
+ if (domainRowset.GetValueOrDefault<Schema::SubDomain::Primary>()) {
+ Self->PrimaryDomainKey = key;
+ }
+ if (!domainRowset.Next())
+ return false;
+ }
+ }
+
+ {
+ auto blockedOwnerRowset = db.Table<Schema::BlockedOwner>().Range().Select();
+ if (!blockedOwnerRowset.IsReady())
+ return false;
+ while (!blockedOwnerRowset.EndOfSet()) {
+ Self->BlockedOwners.emplace(blockedOwnerRowset.GetKey());
+ if (!blockedOwnerRowset.Next())
+ return false;
+ }
+ }
+
+ {
+ auto nodeRowset = db.Table<Schema::Node>().Range().Select();
+ if (!nodeRowset.IsReady())
+ return false;
+ while (!nodeRowset.EndOfSet()) {
+ TNodeId nodeId = nodeRowset.GetValue<Schema::Node::ID>();
+ TNodeInfo& node = Self->Nodes.emplace(std::piecewise_construct, std::tuple<TNodeId>(nodeId), std::tuple<TNodeId, THive&>(nodeId, *Self)).first->second;
+ node.Local = nodeRowset.GetValue<Schema::Node::Local>();
+ node.Down = nodeRowset.GetValue<Schema::Node::Down>();
+ node.Freeze = nodeRowset.GetValue<Schema::Node::Freeze>();
+ node.Drain = nodeRowset.GetValueOrDefault<Schema::Node::Drain>();
+ node.DrainInitiators = nodeRowset.GetValueOrDefault<Schema::Node::DrainInitiators>();
+ node.ServicedDomains = nodeRowset.GetValueOrDefault<Schema::Node::ServicedDomains>();
+ node.Statistics = nodeRowset.GetValueOrDefault<Schema::Node::Statistics>();
+ if (nodeRowset.HaveValue<Schema::Node::Location>()) {
+ auto location = nodeRowset.GetValue<Schema::Node::Location>();
+ if (location.HasDataCenter()) {
+ node.Location = TNodeLocation(location);
+ node.LocationAcquired = true;
+ }
+ }
+ if (!node.ServicedDomains) {
+ node.ServicedDomains = { Self->RootDomainKey };
+ }
+ node.LastSeenServicedDomains = node.ServicedDomains; // to keep Down and Freeze flags on restarts
+ if (!(bool)node.Local) {
+ // it's safe to call here, because there is no any tablets in the node yet
+ node.BecomeDisconnected();
+ }
+ if (node.CanBeDeleted()) {
+ db.Table<Schema::Node>().Key(nodeId).Delete();
+ Self->Nodes.erase(nodeId);
+ }
+ if (!nodeRowset.Next())
+ return false;
+ }
+ }
+
+ {
+ auto categoryRowset = db.Table<Schema::TabletCategory>().Range().Select();
+ if (!categoryRowset.IsReady())
+ return false;
+ while (!categoryRowset.EndOfSet()) {
+ TTabletCategoryId categoryId = categoryRowset.GetValue<Schema::TabletCategory::ID>();
+ TTabletCategoryInfo& category = Self->TabletCategories.insert(std::make_pair(categoryId, TTabletCategoryInfo(categoryId))).first->second;
+ category.MaxDisconnectTimeout = categoryRowset.GetValueOrDefault<Schema::TabletCategory::MaxDisconnectTimeout>();
+ category.StickTogetherInDC = categoryRowset.GetValueOrDefault<Schema::TabletCategory::StickTogetherInDC>();
+ if (!categoryRowset.Next())
+ return false;
+ }
+ }
+
+ if (Self->CurrentConfig.GetSystemTabletCategoryId() != 0 && Self->TabletCategories.empty()) {
+ db.Table<Schema::TabletCategory>().Key(Self->CurrentConfig.GetSystemTabletCategoryId()).Update<Schema::TabletCategory::StickTogetherInDC>(true);
+ }
+
+ TTabletId maxTabletId = 0;
+
+ {
+ auto tabletRowset = db.Table<Schema::Tablet>().Range().Select();
+ if (!tabletRowset.IsReady())
+ return false;
+ while (!tabletRowset.EndOfSet()) {
+ TTabletId tabletId = tabletRowset.GetValue<Schema::Tablet::ID>();
+ maxTabletId = std::max(maxTabletId, UniqPartFromTabletID(tabletId));
TLeaderTabletInfo& tablet = Self->Tablets.emplace(
- std::piecewise_construct,
- std::tuple<TTabletId>(tabletId),
- std::tuple<TTabletId, THive&>(tabletId, *Self)).first->second;
- tablet.State = tabletRowset.GetValue<Schema::Tablet::State>();
- tablet.Type = tabletRowset.GetValue<Schema::Tablet::TabletType>();
- tablet.ObjectId = tabletRowset.GetValueOrDefault<Schema::Tablet::ObjectID>();
- Self->ObjectToTabletMetrics[tablet.ObjectId].IncreaseCount();
- Self->TabletTypeToTabletMetrics[tablet.Type].IncreaseCount();
- tablet.AllowedNodes = tabletRowset.GetValue<Schema::Tablet::AllowedNodes>();
+ std::piecewise_construct,
+ std::tuple<TTabletId>(tabletId),
+ std::tuple<TTabletId, THive&>(tabletId, *Self)).first->second;
+ tablet.State = tabletRowset.GetValue<Schema::Tablet::State>();
+ tablet.Type = tabletRowset.GetValue<Schema::Tablet::TabletType>();
+ tablet.ObjectId = tabletRowset.GetValueOrDefault<Schema::Tablet::ObjectID>();
+ Self->ObjectToTabletMetrics[tablet.ObjectId].IncreaseCount();
+ Self->TabletTypeToTabletMetrics[tablet.Type].IncreaseCount();
+ tablet.AllowedNodes = tabletRowset.GetValue<Schema::Tablet::AllowedNodes>();
if (tabletRowset.HaveValue<Schema::Tablet::AllowedDataCenters>()) {
// this is priority format due to migration issues; when migration is complete, this code will
// be removed
@@ -355,68 +355,68 @@ public:
} else {
tablet.AllowedDataCenters = tabletRowset.GetValueOrDefault<Schema::Tablet::AllowedDataCenterIds>();
}
- tablet.DataCentersPreference = tabletRowset.GetValueOrDefault<Schema::Tablet::DataCentersPreference>();
- TVector<TSubDomainKey> allowedDomains = tabletRowset.GetValueOrDefault<Schema::Tablet::AllowedDomains>();
- TSubDomainKey objectDomain = TSubDomainKey(tabletRowset.GetValueOrDefault<Schema::Tablet::ObjectDomain>());
- tablet.AssignDomains(objectDomain, allowedDomains);
- //tablet.Weight = tabletRowset.GetValueOrDefault<Schema::Tablet::Weight>(1000);
+ tablet.DataCentersPreference = tabletRowset.GetValueOrDefault<Schema::Tablet::DataCentersPreference>();
+ TVector<TSubDomainKey> allowedDomains = tabletRowset.GetValueOrDefault<Schema::Tablet::AllowedDomains>();
+ TSubDomainKey objectDomain = TSubDomainKey(tabletRowset.GetValueOrDefault<Schema::Tablet::ObjectDomain>());
+ tablet.AssignDomains(objectDomain, allowedDomains);
+ //tablet.Weight = tabletRowset.GetValueOrDefault<Schema::Tablet::Weight>(1000);
tablet.NodeId = tabletRowset.GetValue<Schema::Tablet::LeaderNode>();
- tablet.KnownGeneration = tabletRowset.GetValue<Schema::Tablet::KnownGeneration>();
- tablet.ActorsToNotify = tabletRowset.GetValueOrDefault<Schema::Tablet::ActorsToNotify>();
- if (tabletRowset.HaveValue<Schema::Tablet::ActorToNotify>()) {
- tablet.ActorsToNotify.push_back(tabletRowset.GetValue<Schema::Tablet::ActorToNotify>());
- tablet.ActorsToNotify.erase(
- std::unique(tablet.ActorsToNotify.begin(), tablet.ActorsToNotify.end()),
- tablet.ActorsToNotify.end()
- );
- }
- TTabletCategoryId categoryId = 0;
- if (tabletRowset.HaveValue<Schema::Tablet::Category>()) {
- categoryId = tabletRowset.GetValue<Schema::Tablet::Category>();
- }
- if (categoryId == 0 && Self->IsSystemTablet(tablet.Type)) {
- categoryId = Self->CurrentConfig.GetSystemTabletCategoryId();
- }
- if (categoryId != 0) {
- tablet.Category = &Self->GetTabletCategory(categoryId);
- tablet.Category->Tablets.insert(&tablet);
- }
+ tablet.KnownGeneration = tabletRowset.GetValue<Schema::Tablet::KnownGeneration>();
+ tablet.ActorsToNotify = tabletRowset.GetValueOrDefault<Schema::Tablet::ActorsToNotify>();
+ if (tabletRowset.HaveValue<Schema::Tablet::ActorToNotify>()) {
+ tablet.ActorsToNotify.push_back(tabletRowset.GetValue<Schema::Tablet::ActorToNotify>());
+ tablet.ActorsToNotify.erase(
+ std::unique(tablet.ActorsToNotify.begin(), tablet.ActorsToNotify.end()),
+ tablet.ActorsToNotify.end()
+ );
+ }
+ TTabletCategoryId categoryId = 0;
+ if (tabletRowset.HaveValue<Schema::Tablet::Category>()) {
+ categoryId = tabletRowset.GetValue<Schema::Tablet::Category>();
+ }
+ if (categoryId == 0 && Self->IsSystemTablet(tablet.Type)) {
+ categoryId = Self->CurrentConfig.GetSystemTabletCategoryId();
+ }
+ if (categoryId != 0) {
+ tablet.Category = &Self->GetTabletCategory(categoryId);
+ tablet.Category->Tablets.insert(&tablet);
+ }
tablet.BootMode = tabletRowset.GetValue<Schema::Tablet::BootMode>();
tablet.LockedToActor = tabletRowset.GetValueOrDefault<Schema::Tablet::LockedToActor>();
tablet.LockedReconnectTimeout = TDuration::MilliSeconds(tabletRowset.GetValueOrDefault<Schema::Tablet::LockedReconnectTimeout>());
if (tablet.LockedToActor) {
TNodeId nodeId = tablet.LockedToActor.NodeId();
- auto it = Self->Nodes.find(nodeId);
- if (it == Self->Nodes.end()) {
+ auto it = Self->Nodes.find(nodeId);
+ if (it == Self->Nodes.end()) {
// Tablet was locked to a node that had no local service
- it = Self->Nodes.emplace(std::piecewise_construct, std::tuple<TNodeId>(nodeId), std::tuple<TNodeId, THive&>(nodeId, *Self)).first;
+ it = Self->Nodes.emplace(std::piecewise_construct, std::tuple<TNodeId>(nodeId), std::tuple<TNodeId, THive&>(nodeId, *Self)).first;
}
it->second.LockedTablets.insert(&tablet);
}
-
- tablet.SeizedByChild = tabletRowset.GetValueOrDefault<Schema::Tablet::SeizedByChild>();
- tablet.NeedToReleaseFromParent = tabletRowset.GetValueOrDefault<Schema::Tablet::NeedToReleaseFromParent>();
- tablet.ChannelProfileReassignReason = tabletRowset.GetValueOrDefault<Schema::Tablet::ReassignReason>();
- tablet.Statistics = tabletRowset.GetValueOrDefault<Schema::Tablet::Statistics>();
- tablet.InitTabletMetrics();
-
- if (tablet.NodeId == 0) {
- tablet.BecomeStopped();
- } else {
- auto it = Self->Nodes.find(tablet.NodeId);
- if (it != Self->Nodes.end() && it->second.IsUnknown()) {
- tablet.BecomeUnknown(&it->second);
- } else {
- tablet.NodeId = 0;
- tablet.BecomeStopped();
- }
- }
-
+
+ tablet.SeizedByChild = tabletRowset.GetValueOrDefault<Schema::Tablet::SeizedByChild>();
+ tablet.NeedToReleaseFromParent = tabletRowset.GetValueOrDefault<Schema::Tablet::NeedToReleaseFromParent>();
+ tablet.ChannelProfileReassignReason = tabletRowset.GetValueOrDefault<Schema::Tablet::ReassignReason>();
+ tablet.Statistics = tabletRowset.GetValueOrDefault<Schema::Tablet::Statistics>();
+ tablet.InitTabletMetrics();
+
+ if (tablet.NodeId == 0) {
+ tablet.BecomeStopped();
+ } else {
+ auto it = Self->Nodes.find(tablet.NodeId);
+ if (it != Self->Nodes.end() && it->second.IsUnknown()) {
+ tablet.BecomeUnknown(&it->second);
+ } else {
+ tablet.NodeId = 0;
+ tablet.BecomeStopped();
+ }
+ }
+
std::unordered_map<TFollowerGroup*, ui32> followersPerGroup;
-
+
auto tabletFollowerGroupRowset = db.Table<Schema::TabletFollowerGroup>().Range(tabletId).Select();
if (!tabletFollowerGroupRowset.IsReady())
- return false;
+ return false;
while (!tabletFollowerGroupRowset.EndOfSet()) {
TFollowerGroup& followerGroup = tablet.AddFollowerGroup();
followerGroup.Id = tabletFollowerGroupRowset.GetValue<Schema::TabletFollowerGroup::GroupID>();
@@ -441,35 +441,35 @@ public:
followerGroup.RequireDifferentNodes = tabletFollowerGroupRowset.GetValueOrDefault<Schema::TabletFollowerGroup::RequireDifferentNodes>();
followersPerGroup.emplace(&followerGroup, 0);
if (!tabletFollowerGroupRowset.Next())
- return false;
- }
-
+ return false;
+ }
+
auto tabletFollowerRowset = db.Table<Schema::TabletFollowerTablet>().Range(tabletId).Select();
if (!tabletFollowerRowset.IsReady())
- return false;
+ return false;
while (!tabletFollowerRowset.EndOfSet()) {
TFollowerGroupId followerGroupId = tabletFollowerRowset.GetValue<Schema::TabletFollowerTablet::GroupID>();
TFollowerId followerId = tabletFollowerRowset.GetValue<Schema::TabletFollowerTablet::FollowerID>();
TNodeId nodeId = tabletFollowerRowset.GetValue<Schema::TabletFollowerTablet::FollowerNode>();
TFollowerGroup& followerGroup = tablet.GetFollowerGroup(followerGroupId);
TFollowerTabletInfo& follower = tablet.AddFollower(followerGroup, followerId);
- follower.Statistics = tabletFollowerRowset.GetValueOrDefault<Schema::TabletFollowerTablet::Statistics>();
+ follower.Statistics = tabletFollowerRowset.GetValueOrDefault<Schema::TabletFollowerTablet::Statistics>();
follower.InitTabletMetrics();
- if (nodeId == 0) {
+ if (nodeId == 0) {
follower.BecomeStopped();
- } else {
- auto it = Self->Nodes.find(nodeId);
- if (it != Self->Nodes.end() && it->second.IsUnknown()) {
+ } else {
+ auto it = Self->Nodes.find(nodeId);
+ if (it != Self->Nodes.end() && it->second.IsUnknown()) {
follower.BecomeUnknown(&it->second);
- } else {
+ } else {
follower.BecomeStopped();
- }
- }
+ }
+ }
followersPerGroup[&followerGroup]++;
if (!tabletFollowerRowset.Next())
- return false;
- }
-
+ return false;
+ }
+
auto metricsRowset = db.Table<Schema::Metrics>().Range(tabletId).Select();
if (!metricsRowset.IsReady())
return false;
@@ -480,7 +480,7 @@ public:
leaderOrFollower->MutableResourceMetricsAggregates().MaximumCPU.InitiaizeFrom(metricsRowset.GetValueOrDefault<Schema::Metrics::MaximumCPU>());
leaderOrFollower->MutableResourceMetricsAggregates().MaximumMemory.InitiaizeFrom(metricsRowset.GetValueOrDefault<Schema::Metrics::MaximumMemory>());
leaderOrFollower->MutableResourceMetricsAggregates().MaximumNetwork.InitiaizeFrom(metricsRowset.GetValueOrDefault<Schema::Metrics::MaximumNetwork>());
- // do not reorder
+ // do not reorder
leaderOrFollower->UpdateResourceUsage(metricsRowset.GetValueOrDefault<Schema::Metrics::ProtoMetrics>());
}
if (!metricsRowset.Next())
@@ -489,163 +489,163 @@ public:
for (auto& pr : followersPerGroup) {
TFollowerGroup& followerGroup(*pr.first);
- while (followerGroup.GetComputedFollowerCount(Self->GetDataCenters()) > pr.second) {
+ while (followerGroup.GetComputedFollowerCount(Self->GetDataCenters()) > pr.second) {
TFollowerTabletInfo& follower = tablet.AddFollower(followerGroup);
follower.InitTabletMetrics();
follower.BecomeStopped();
db.Table<Schema::TabletFollowerTablet>().Key(tabletId, follower.Id).Update(NIceDb::TUpdate<Schema::TabletFollowerTablet::FollowerNode>(0),
NIceDb::TUpdate<Schema::TabletFollowerTablet::GroupID>(followerGroup.Id));
- ++pr.second;
- }
- }
-
- TOwnerIdxType::TValueType owner = tabletRowset.GetValue<Schema::Tablet::Owner>();
- Self->OwnerToTablet.emplace(owner, tabletId);
- tablet.Owner = owner;
-
- {
- tablet.TabletStorageInfo.Reset(new TTabletStorageInfo(tabletId, tablet.Type));
- tablet.TabletStorageInfo->Version = tabletRowset.GetValueOrDefault<Schema::Tablet::TabletStorageVersion>();
+ ++pr.second;
+ }
+ }
+
+ TOwnerIdxType::TValueType owner = tabletRowset.GetValue<Schema::Tablet::Owner>();
+ Self->OwnerToTablet.emplace(owner, tabletId);
+ tablet.Owner = owner;
+
+ {
+ tablet.TabletStorageInfo.Reset(new TTabletStorageInfo(tabletId, tablet.Type));
+ tablet.TabletStorageInfo->Version = tabletRowset.GetValueOrDefault<Schema::Tablet::TabletStorageVersion>();
tablet.TabletStorageInfo->TenantPathId = tablet.GetTenant();
- auto tabletChannelRowset = db.Table<Schema::TabletChannel>().Range(tabletId).Select();
- if (!tabletChannelRowset.IsReady())
- return false;
-
- while (!tabletChannelRowset.EndOfSet()) {
- ui32 channelId = tabletChannelRowset.GetValue<Schema::TabletChannel::Channel>();
- TString storagePool = tabletChannelRowset.GetValue<Schema::TabletChannel::StoragePool>();
- Y_VERIFY(tablet.BoundChannels.size() == channelId);
- tablet.BoundChannels.emplace_back();
- NKikimrStoragePool::TChannelBind& bind = tablet.BoundChannels.back();
- if (tabletChannelRowset.HaveValue<Schema::TabletChannel::Binding>()) {
- bind = tabletChannelRowset.GetValue<Schema::TabletChannel::Binding>();
+ auto tabletChannelRowset = db.Table<Schema::TabletChannel>().Range(tabletId).Select();
+ if (!tabletChannelRowset.IsReady())
+ return false;
+
+ while (!tabletChannelRowset.EndOfSet()) {
+ ui32 channelId = tabletChannelRowset.GetValue<Schema::TabletChannel::Channel>();
+ TString storagePool = tabletChannelRowset.GetValue<Schema::TabletChannel::StoragePool>();
+ Y_VERIFY(tablet.BoundChannels.size() == channelId);
+ tablet.BoundChannels.emplace_back();
+ NKikimrStoragePool::TChannelBind& bind = tablet.BoundChannels.back();
+ if (tabletChannelRowset.HaveValue<Schema::TabletChannel::Binding>()) {
+ bind = tabletChannelRowset.GetValue<Schema::TabletChannel::Binding>();
+ }
+ bind.SetStoragePoolName(storagePool);
+ Self->InitDefaultChannelBind(bind);
+ tablet.TabletStorageInfo->Channels.emplace_back(channelId, storagePool);
+
+ TTabletChannelInfo& channel = tablet.TabletStorageInfo->Channels[channelId];
+
+ if (tabletChannelRowset.GetValue<Schema::TabletChannel::NeedNewGroup>()) {
+ tablet.ChannelProfileNewGroup.set(channelId);
}
- bind.SetStoragePoolName(storagePool);
- Self->InitDefaultChannelBind(bind);
- tablet.TabletStorageInfo->Channels.emplace_back(channelId, storagePool);
-
- TTabletChannelInfo& channel = tablet.TabletStorageInfo->Channels[channelId];
-
- if (tabletChannelRowset.GetValue<Schema::TabletChannel::NeedNewGroup>()) {
- tablet.ChannelProfileNewGroup.set(channelId);
- }
-
- auto tabletChannelGenRowset = db.Table<Schema::TabletChannelGen>().Range(tabletId, channelId).Select();
- if (!tabletChannelGenRowset.IsReady())
- return false;
-
- while (!tabletChannelGenRowset.EndOfSet()) {
- ui32 generationId = tabletChannelGenRowset.GetValue<Schema::TabletChannelGen::Generation>();
- ui32 groupId = tabletChannelGenRowset.GetValue<Schema::TabletChannelGen::Group>();
- TInstant timestamp = TInstant::MilliSeconds(tabletChannelGenRowset.GetValueOrDefault<Schema::TabletChannelGen::Timestamp>());
- channel.History.emplace_back(generationId, groupId, timestamp);
- if (!tabletChannelGenRowset.Next())
- return false;
- }
- Y_VERIFY(tablet.IsReadyToAssignGroups() || !channel.History.empty(), "TabletID=%" PRIu64, tabletId);
-
- if (!tabletChannelRowset.Next())
- return false;
- }
- Y_VERIFY(tablet.IsReadyToAssignGroups() || tablet.TabletStorageInfo->Channels.size() >= 2, "TabletID=%" PRIu64, tabletId);
- }
-
- tablet.AcquireAllocationUnits();
-
- if (!tabletRowset.Next())
- return false;
- }
- }
-
- for (auto itNode = Self->Nodes.begin(); itNode != Self->Nodes.end();) {
- if (itNode->second.CanBeDeleted()) {
- db.Table<Schema::Node>().Key(itNode->first).Delete();
- itNode = Self->Nodes.erase(itNode);
- } else {
- ++itNode;
- }
- }
-
- TTabletId nextTabletId = Max(maxTabletId + 1, Self->NextTabletId);
-
- if (isRootHive) {
- if (numSequences == 0) {
- ui64 freeSequenceIdx = 0;
- BLOG_D("THive::TTxLoadEverything Self->NextTabletId = " << Self->NextTabletId << " NextTabletId = " << nextTabletId);
- if (nextTabletId < TABLET_ID_BLACKHOLE_BEGIN) {
- TSequencer::TOwnerType owner(TSequencer::NO_OWNER, freeSequenceIdx++);
- TSequencer::TSequence sequence({0x10000, std::max<TTabletId>(nextTabletId, 0x10000), TABLET_ID_BLACKHOLE_BEGIN});
- Self->Sequencer.AddFreeSequence(owner, sequence);
- db.Table<Schema::Sequences>().Key(owner)
- .Update<Schema::Sequences::Begin, Schema::Sequences::Next, Schema::Sequences::End>(
- sequence.Begin, sequence.Next, sequence.End);
- }
- {
- TSequencer::TOwnerType owner(TSequencer::NO_OWNER, freeSequenceIdx++);
- TSequencer::TSequence sequence({TABLET_ID_BLACKHOLE_END, std::max<TTabletId>(nextTabletId, TABLET_ID_BLACKHOLE_END), 0xFFFFFFFFFFF});
- Self->Sequencer.AddFreeSequence(owner, sequence);
- db.Table<Schema::Sequences>().Key(owner)
- .Update<Schema::Sequences::Begin, Schema::Sequences::Next, Schema::Sequences::End>(
- sequence.Begin, sequence.Next, sequence.End);
- }
- }
- }
-
- if (numSequences != 0) {
- std::vector<TSequencer::TOwnerType> modified;
- BLOG_D("THive::TTxLoadEverything NextElement = " << Self->Sequencer.GetNextElement() << " NextTabletId = " << nextTabletId);
- while (Self->Sequencer.GetNextElement() < nextTabletId) {
- TSequencer::TElementType element = Self->Sequencer.AllocateElement(modified);
- SortUnique(modified);
- if (element == TSequencer::NO_ELEMENT) {
- BLOG_ERROR("THive::TTxLoadEverything - unable to equalize NextTabletId " << nextTabletId << " - could not allocate free element");
- break;
- }
- }
- if (!modified.empty()) {
- for (auto owner : modified) {
- auto sequence = Self->Sequencer.GetSequence(owner);
- BLOG_CRIT("THive::TTxLoadEverything - equalizing sequence " << owner << " to " << sequence);
- db.Table<Schema::Sequences>()
- .Key(owner)
- .Update<Schema::Sequences::Begin, Schema::Sequences::Next, Schema::Sequences::End>(sequence.Begin, sequence.Next, sequence.End);
- }
- }
- }
-
- return true;
- }
-
+
+ auto tabletChannelGenRowset = db.Table<Schema::TabletChannelGen>().Range(tabletId, channelId).Select();
+ if (!tabletChannelGenRowset.IsReady())
+ return false;
+
+ while (!tabletChannelGenRowset.EndOfSet()) {
+ ui32 generationId = tabletChannelGenRowset.GetValue<Schema::TabletChannelGen::Generation>();
+ ui32 groupId = tabletChannelGenRowset.GetValue<Schema::TabletChannelGen::Group>();
+ TInstant timestamp = TInstant::MilliSeconds(tabletChannelGenRowset.GetValueOrDefault<Schema::TabletChannelGen::Timestamp>());
+ channel.History.emplace_back(generationId, groupId, timestamp);
+ if (!tabletChannelGenRowset.Next())
+ return false;
+ }
+ Y_VERIFY(tablet.IsReadyToAssignGroups() || !channel.History.empty(), "TabletID=%" PRIu64, tabletId);
+
+ if (!tabletChannelRowset.Next())
+ return false;
+ }
+ Y_VERIFY(tablet.IsReadyToAssignGroups() || tablet.TabletStorageInfo->Channels.size() >= 2, "TabletID=%" PRIu64, tabletId);
+ }
+
+ tablet.AcquireAllocationUnits();
+
+ if (!tabletRowset.Next())
+ return false;
+ }
+ }
+
+ for (auto itNode = Self->Nodes.begin(); itNode != Self->Nodes.end();) {
+ if (itNode->second.CanBeDeleted()) {
+ db.Table<Schema::Node>().Key(itNode->first).Delete();
+ itNode = Self->Nodes.erase(itNode);
+ } else {
+ ++itNode;
+ }
+ }
+
+ TTabletId nextTabletId = Max(maxTabletId + 1, Self->NextTabletId);
+
+ if (isRootHive) {
+ if (numSequences == 0) {
+ ui64 freeSequenceIdx = 0;
+ BLOG_D("THive::TTxLoadEverything Self->NextTabletId = " << Self->NextTabletId << " NextTabletId = " << nextTabletId);
+ if (nextTabletId < TABLET_ID_BLACKHOLE_BEGIN) {
+ TSequencer::TOwnerType owner(TSequencer::NO_OWNER, freeSequenceIdx++);
+ TSequencer::TSequence sequence({0x10000, std::max<TTabletId>(nextTabletId, 0x10000), TABLET_ID_BLACKHOLE_BEGIN});
+ Self->Sequencer.AddFreeSequence(owner, sequence);
+ db.Table<Schema::Sequences>().Key(owner)
+ .Update<Schema::Sequences::Begin, Schema::Sequences::Next, Schema::Sequences::End>(
+ sequence.Begin, sequence.Next, sequence.End);
+ }
+ {
+ TSequencer::TOwnerType owner(TSequencer::NO_OWNER, freeSequenceIdx++);
+ TSequencer::TSequence sequence({TABLET_ID_BLACKHOLE_END, std::max<TTabletId>(nextTabletId, TABLET_ID_BLACKHOLE_END), 0xFFFFFFFFFFF});
+ Self->Sequencer.AddFreeSequence(owner, sequence);
+ db.Table<Schema::Sequences>().Key(owner)
+ .Update<Schema::Sequences::Begin, Schema::Sequences::Next, Schema::Sequences::End>(
+ sequence.Begin, sequence.Next, sequence.End);
+ }
+ }
+ }
+
+ if (numSequences != 0) {
+ std::vector<TSequencer::TOwnerType> modified;
+ BLOG_D("THive::TTxLoadEverything NextElement = " << Self->Sequencer.GetNextElement() << " NextTabletId = " << nextTabletId);
+ while (Self->Sequencer.GetNextElement() < nextTabletId) {
+ TSequencer::TElementType element = Self->Sequencer.AllocateElement(modified);
+ SortUnique(modified);
+ if (element == TSequencer::NO_ELEMENT) {
+ BLOG_ERROR("THive::TTxLoadEverything - unable to equalize NextTabletId " << nextTabletId << " - could not allocate free element");
+ break;
+ }
+ }
+ if (!modified.empty()) {
+ for (auto owner : modified) {
+ auto sequence = Self->Sequencer.GetSequence(owner);
+ BLOG_CRIT("THive::TTxLoadEverything - equalizing sequence " << owner << " to " << sequence);
+ db.Table<Schema::Sequences>()
+ .Key(owner)
+ .Update<Schema::Sequences::Begin, Schema::Sequences::Next, Schema::Sequences::End>(sequence.Begin, sequence.Next, sequence.End);
+ }
+ }
+ }
+
+ return true;
+ }
+
void Complete(const TActorContext& ctx) override {
- BLOG_D("THive::TTxLoadEverything::Complete " << Self->DatabaseConfig.ShortDebugString());
- i64 tabletsTotal = 0;
- for (auto it = Self->Tablets.begin(); it != Self->Tablets.end(); ++it) {
- ++tabletsTotal;
+ BLOG_D("THive::TTxLoadEverything::Complete " << Self->DatabaseConfig.ShortDebugString());
+ i64 tabletsTotal = 0;
+ for (auto it = Self->Tablets.begin(); it != Self->Tablets.end(); ++it) {
+ ++tabletsTotal;
for (const TTabletInfo& follower : it->second.Followers) {
- ++tabletsTotal;
+ ++tabletsTotal;
if (follower.IsLeader()) {
follower.AsLeader();
- } else {
+ } else {
follower.AsFollower();
- }
- }
- }
-
- Self->Become(&TSelf::StateWork);
- Self->SetCounterTabletsTotal(tabletsTotal);
- Self->MigrationState = NKikimrHive::EMigrationState::MIGRATION_READY;
+ }
+ }
+ }
+
+ Self->Become(&TSelf::StateWork);
+ Self->SetCounterTabletsTotal(tabletsTotal);
+ Self->MigrationState = NKikimrHive::EMigrationState::MIGRATION_READY;
ctx.Send(Self->SelfId(), new TEvPrivate::TEvBootTablets());
for (auto it = Self->Nodes.begin(); it != Self->Nodes.end(); ++it) {
- Self->ScheduleUnlockTabletExecution(it->second);
+ Self->ScheduleUnlockTabletExecution(it->second);
}
- }
-};
-
+ }
+};
+
ITransaction* THive::CreateLoadEverything() {
- return new TTxLoadEverything(this);
-}
-
-} // NHive
-} // NKikimr
+ return new TTxLoadEverything(this);
+}
+
+} // NHive
+} // NKikimr
diff --git a/ydb/core/mind/hive/tx__lock_tablet.cpp b/ydb/core/mind/hive/tx__lock_tablet.cpp
index 1d0dee3f4fe..6365dd09886 100644
--- a/ydb/core/mind/hive/tx__lock_tablet.cpp
+++ b/ydb/core/mind/hive/tx__lock_tablet.cpp
@@ -1,10 +1,10 @@
-#include "hive_impl.h"
-#include "hive_log.h"
+#include "hive_impl.h"
+#include "hive_log.h"
namespace NKikimr {
-namespace NHive {
+namespace NHive {
-class TTxLockTabletExecution : public TTransactionBase<THive> {
+class TTxLockTabletExecution : public TTransactionBase<THive> {
private:
const ui64 TabletId;
const TActorId OwnerActor;
@@ -31,10 +31,10 @@ public:
Y_VERIFY(!!Sender);
}
- TTxType GetTxType() const override { return NHive::TXTYPE_LOCK_TABLET_EXECUTION; }
-
- bool Execute(TTransactionContext& txc, const TActorContext&) override {
- BLOG_D("THive::TTxLockTabletExecution::Execute");
+ TTxType GetTxType() const override { return NHive::TXTYPE_LOCK_TABLET_EXECUTION; }
+
+ bool Execute(TTransactionContext& txc, const TActorContext&) override {
+ BLOG_D("THive::TTxLockTabletExecution::Execute");
if (!OwnerActor) {
Status = NKikimrProto::ERROR;
@@ -79,7 +79,7 @@ public:
}
void Complete(const TActorContext& ctx) override {
- BLOG_D("THive::TTxLockTabletExecution::Complete TabletId: " << TabletId
+ BLOG_D("THive::TTxLockTabletExecution::Complete TabletId: " << TabletId
<< " Owner: " << OwnerActor << " Status: " << Status << " " << StatusMessage);
ui32 flags = 0;
@@ -96,7 +96,7 @@ public:
for (auto& follower : tablet->Followers) {
follower.InitiateStop();
}
- tablet->InitiateStop();
+ tablet->InitiateStop();
}
if (tablet->LockedToActor == OwnerActor && tablet->PendingUnlockSeqNo == 0) {
// Lock is still valid, watch for node disconnections
@@ -122,9 +122,9 @@ ITransaction* THive::CreateLockTabletExecution(const NKikimrHive::TEvLockTabletE
return new TTxLockTabletExecution(rec, sender, cookie, this);
}
-void THive::Handle(TEvHive::TEvLockTabletExecution::TPtr& ev) {
- Execute(CreateLockTabletExecution(ev->Get()->Record, ev->Sender, ev->Cookie));
+void THive::Handle(TEvHive::TEvLockTabletExecution::TPtr& ev) {
+ Execute(CreateLockTabletExecution(ev->Get()->Record, ev->Sender, ev->Cookie));
}
-} // NHive
-} // NKikimr
+} // NHive
+} // NKikimr
diff --git a/ydb/core/mind/hive/tx__process_boot_queue.cpp b/ydb/core/mind/hive/tx__process_boot_queue.cpp
index d697022ce6d..8ce6459862c 100644
--- a/ydb/core/mind/hive/tx__process_boot_queue.cpp
+++ b/ydb/core/mind/hive/tx__process_boot_queue.cpp
@@ -1,31 +1,31 @@
-#include "hive_impl.h"
-#include "hive_log.h"
-
-namespace NKikimr {
-namespace NHive {
-
-class TTxProcessBootQueue : public TTransactionBase<THive> {
-public:
- TTxProcessBootQueue(THive *hive)
- : TBase(hive)
- {}
-
- TTxType GetTxType() const override { return NHive::TXTYPE_PROCESS_BOOT_QUEUE; }
-
+#include "hive_impl.h"
+#include "hive_log.h"
+
+namespace NKikimr {
+namespace NHive {
+
+class TTxProcessBootQueue : public TTransactionBase<THive> {
+public:
+ TTxProcessBootQueue(THive *hive)
+ : TBase(hive)
+ {}
+
+ TTxType GetTxType() const override { return NHive::TXTYPE_PROCESS_BOOT_QUEUE; }
+
bool Execute(TTransactionContext&, const TActorContext&) override {
- BLOG_D("THive::TTxProcessBootQueue()::Execute");
- Self->RunProcessBootQueue();
- return true;
- }
-
+ BLOG_D("THive::TTxProcessBootQueue()::Execute");
+ Self->RunProcessBootQueue();
+ return true;
+ }
+
void Complete(const TActorContext&) override {
- BLOG_D("THive::TTxProcessBootQueue()::Complete");
- }
-};
-
-ITransaction* THive::CreateProcessBootQueue() {
- return new TTxProcessBootQueue(this);
-}
-
-} // NHive
-} // NKikimr
+ BLOG_D("THive::TTxProcessBootQueue()::Complete");
+ }
+};
+
+ITransaction* THive::CreateProcessBootQueue() {
+ return new TTxProcessBootQueue(this);
+}
+
+} // NHive
+} // NKikimr
diff --git a/ydb/core/mind/hive/tx__process_pending_operations.cpp b/ydb/core/mind/hive/tx__process_pending_operations.cpp
index b52eda31d95..afaf7203d47 100644
--- a/ydb/core/mind/hive/tx__process_pending_operations.cpp
+++ b/ydb/core/mind/hive/tx__process_pending_operations.cpp
@@ -1,42 +1,42 @@
-#include "hive_impl.h"
-#include "hive_log.h"
-
-namespace NKikimr {
-namespace NHive {
-
-class TTxProcessPendingOperations : public TTransactionBase<THive> {
-protected:
- std::deque<THolder<IEventHandle>> Events;
-
-public:
- TTxProcessPendingOperations(THive *hive)
- : TBase(hive)
- {}
-
- TTxType GetTxType() const override { return NHive::TXTYPE_PROCESS_PENDING_OPERATIONS; }
-
+#include "hive_impl.h"
+#include "hive_log.h"
+
+namespace NKikimr {
+namespace NHive {
+
+class TTxProcessPendingOperations : public TTransactionBase<THive> {
+protected:
+ std::deque<THolder<IEventHandle>> Events;
+
+public:
+ TTxProcessPendingOperations(THive *hive)
+ : TBase(hive)
+ {}
+
+ TTxType GetTxType() const override { return NHive::TXTYPE_PROCESS_PENDING_OPERATIONS; }
+
bool Execute(TTransactionContext&, const TActorContext&) override {
- BLOG_D("THive::TTxProcessPendingOperations()::Execute");
- for (auto& [owner, pendingCreateTablet] : Self->PendingCreateTablets) {
- THolder<TEvHive::TEvCreateTablet> evCreateTablet(new TEvHive::TEvCreateTablet());
- evCreateTablet->Record = pendingCreateTablet.CreateTablet;
+ BLOG_D("THive::TTxProcessPendingOperations()::Execute");
+ for (auto& [owner, pendingCreateTablet] : Self->PendingCreateTablets) {
+ THolder<TEvHive::TEvCreateTablet> evCreateTablet(new TEvHive::TEvCreateTablet());
+ evCreateTablet->Record = pendingCreateTablet.CreateTablet;
Events.emplace_back(new IEventHandle(Self->SelfId(), pendingCreateTablet.Sender, evCreateTablet.Release(), 0, pendingCreateTablet.Cookie));
- }
- return true;
- }
-
+ }
+ return true;
+ }
+
void Complete(const TActorContext&) override {
- BLOG_D("THive::TTxProcessPendingOperations()::Complete");
- for (THolder<IEventHandle>& event : Events) {
- BLOG_D("THive::TTxProcessPendingOperations(): retry event " << event->Type);
- TlsActivationContext->Send(event.Release());
- }
- }
-};
-
-ITransaction* THive::CreateProcessPendingOperations() {
- return new TTxProcessPendingOperations(this);
-}
-
-} // NHive
-} // NKikimr
+ BLOG_D("THive::TTxProcessPendingOperations()::Complete");
+ for (THolder<IEventHandle>& event : Events) {
+ BLOG_D("THive::TTxProcessPendingOperations(): retry event " << event->Type);
+ TlsActivationContext->Send(event.Release());
+ }
+ }
+};
+
+ITransaction* THive::CreateProcessPendingOperations() {
+ return new TTxProcessPendingOperations(this);
+}
+
+} // NHive
+} // NKikimr
diff --git a/ydb/core/mind/hive/tx__reassign_groups.cpp b/ydb/core/mind/hive/tx__reassign_groups.cpp
index 3f4a1621016..ec9f4bfdd23 100644
--- a/ydb/core/mind/hive/tx__reassign_groups.cpp
+++ b/ydb/core/mind/hive/tx__reassign_groups.cpp
@@ -1,78 +1,78 @@
-#include "hive_impl.h"
-#include "hive_log.h"
-
-namespace NKikimr {
-namespace NHive {
-
-class TTxReassignGroups : public TTransactionBase<THive> {
-protected:
- TTabletId TabletId;
+#include "hive_impl.h"
+#include "hive_log.h"
+
+namespace NKikimr {
+namespace NHive {
+
+class TTxReassignGroups : public TTransactionBase<THive> {
+protected:
+ TTabletId TabletId;
TActorId Sender;
- std::bitset<MAX_TABLET_CHANNELS> ChannelProfileNewGroup;
- bool InitiatedReassignTablet = false;
-
-public:
- TTxReassignGroups(TTabletId tabletId,
+ std::bitset<MAX_TABLET_CHANNELS> ChannelProfileNewGroup;
+ bool InitiatedReassignTablet = false;
+
+public:
+ TTxReassignGroups(TTabletId tabletId,
const TActorId& sender,
- const std::bitset<MAX_TABLET_CHANNELS>& channelProfileNewGroup,
- THive *hive)
- : TBase(hive)
- , TabletId(tabletId)
- , Sender(sender)
- , ChannelProfileNewGroup(channelProfileNewGroup)
- {}
-
- TTxType GetTxType() const override { return NHive::TXTYPE_REASSIGN_GROUPS; }
-
+ const std::bitset<MAX_TABLET_CHANNELS>& channelProfileNewGroup,
+ THive *hive)
+ : TBase(hive)
+ , TabletId(tabletId)
+ , Sender(sender)
+ , ChannelProfileNewGroup(channelProfileNewGroup)
+ {}
+
+ TTxType GetTxType() const override { return NHive::TXTYPE_REASSIGN_GROUPS; }
+
bool Execute(TTransactionContext &txc, const TActorContext&) override {
- //SetTxType(NHive::TXTYPE_KILL_TABLET);
+ //SetTxType(NHive::TXTYPE_KILL_TABLET);
TLeaderTabletInfo* tablet = Self->FindTablet(TabletId);
- if (tablet != nullptr) {
- BLOG_D("THive::TTxReassignGroups(" << tablet->Id << "," << ChannelProfileNewGroup << ")::Execute");
- if (tablet->IsReadyToReassignTablet()) {
- NIceDb::TNiceDb db(txc.DB);
- tablet->State = ETabletState::GroupAssignment;
- tablet->ChannelProfileNewGroup |= ChannelProfileNewGroup;
- tablet->ActorsToNotify.push_back(Sender);
- db.Table<Schema::Tablet>().Key(tablet->Id).Update(
- NIceDb::TUpdate<Schema::Tablet::State>(ETabletState::GroupAssignment),
- NIceDb::TUpdate<Schema::Tablet::ActorsToNotify>(tablet->ActorsToNotify),
- NIceDb::TUpdate<Schema::Tablet::ReassignReason>(tablet->ChannelProfileReassignReason));
-
- const ui32 channels = tablet->GetChannelCount();
+ if (tablet != nullptr) {
+ BLOG_D("THive::TTxReassignGroups(" << tablet->Id << "," << ChannelProfileNewGroup << ")::Execute");
+ if (tablet->IsReadyToReassignTablet()) {
+ NIceDb::TNiceDb db(txc.DB);
+ tablet->State = ETabletState::GroupAssignment;
+ tablet->ChannelProfileNewGroup |= ChannelProfileNewGroup;
+ tablet->ActorsToNotify.push_back(Sender);
+ db.Table<Schema::Tablet>().Key(tablet->Id).Update(
+ NIceDb::TUpdate<Schema::Tablet::State>(ETabletState::GroupAssignment),
+ NIceDb::TUpdate<Schema::Tablet::ActorsToNotify>(tablet->ActorsToNotify),
+ NIceDb::TUpdate<Schema::Tablet::ReassignReason>(tablet->ChannelProfileReassignReason));
+
+ const ui32 channels = tablet->GetChannelCount();
for (ui32 channelId = 0; channelId < channels; ++channelId) {
- if (ChannelProfileNewGroup.none() || ChannelProfileNewGroup.test(channelId)) {
- db.Table<Schema::TabletChannel>().Key(TabletId, channelId).Update(NIceDb::TUpdate<Schema::TabletChannel::NeedNewGroup>(true));
- }
- }
- InitiatedReassignTablet = true;
- } else {
- BLOG_W("THive::TTxReassignGroups(" << tablet->Id << ")::Execute - tablet is not ready for group reassignment");
- }
- }
- return true;
- }
-
+ if (ChannelProfileNewGroup.none() || ChannelProfileNewGroup.test(channelId)) {
+ db.Table<Schema::TabletChannel>().Key(TabletId, channelId).Update(NIceDb::TUpdate<Schema::TabletChannel::NeedNewGroup>(true));
+ }
+ }
+ InitiatedReassignTablet = true;
+ } else {
+ BLOG_W("THive::TTxReassignGroups(" << tablet->Id << ")::Execute - tablet is not ready for group reassignment");
+ }
+ }
+ return true;
+ }
+
void Complete(const TActorContext&) override {
- BLOG_D("THive::TTxReassignGroups(" << TabletId << ")::Complete");
- if (InitiatedReassignTablet) {
- TLeaderTabletInfo* tablet = Self->FindTablet(TabletId);
- if (tablet != nullptr) {
- if (tablet->IsReadyToAssignGroups()) {
- tablet->InitiateAssignTabletGroups();
- } else {
- BLOG_W("THive::TTxReassignGroups(" << tablet->Id << ")::Complete - tablet is not ready for group reassignment");
- }
- }
- }
- }
-};
-
-ITransaction* THive::CreateReassignGroups(TTabletId tabletId,
+ BLOG_D("THive::TTxReassignGroups(" << TabletId << ")::Complete");
+ if (InitiatedReassignTablet) {
+ TLeaderTabletInfo* tablet = Self->FindTablet(TabletId);
+ if (tablet != nullptr) {
+ if (tablet->IsReadyToAssignGroups()) {
+ tablet->InitiateAssignTabletGroups();
+ } else {
+ BLOG_W("THive::TTxReassignGroups(" << tablet->Id << ")::Complete - tablet is not ready for group reassignment");
+ }
+ }
+ }
+ }
+};
+
+ITransaction* THive::CreateReassignGroups(TTabletId tabletId,
const TActorId& actorToNotify,
- const std::bitset<MAX_TABLET_CHANNELS>& channelProfileNewGroup) {
- return new TTxReassignGroups(tabletId, actorToNotify, channelProfileNewGroup, this);
-}
-
-} // NHive
-} // NKikimr
+ const std::bitset<MAX_TABLET_CHANNELS>& channelProfileNewGroup) {
+ return new TTxReassignGroups(tabletId, actorToNotify, channelProfileNewGroup, this);
+}
+
+} // NHive
+} // NKikimr
diff --git a/ydb/core/mind/hive/tx__register_node.cpp b/ydb/core/mind/hive/tx__register_node.cpp
index 38805b21711..941c0dce658 100644
--- a/ydb/core/mind/hive/tx__register_node.cpp
+++ b/ydb/core/mind/hive/tx__register_node.cpp
@@ -1,82 +1,82 @@
-#include "hive_impl.h"
-#include "hive_log.h"
-
-namespace NKikimr {
-namespace NHive {
-
-class TTxRegisterNode : public TTransactionBase<THive> {
+#include "hive_impl.h"
+#include "hive_log.h"
+
+namespace NKikimr {
+namespace NHive {
+
+class TTxRegisterNode : public TTransactionBase<THive> {
TActorId Local;
- NKikimrLocal::TEvRegisterNode Record;
-
-public:
+ NKikimrLocal::TEvRegisterNode Record;
+
+public:
TTxRegisterNode(const TActorId& local, NKikimrLocal::TEvRegisterNode record, THive *hive)
- : TBase(hive)
- , Local(local)
- , Record(std::move(record))
- {}
-
- TTxType GetTxType() const override { return NHive::TXTYPE_REGISTER_NODE; }
-
- bool Execute(TTransactionContext &txc, const TActorContext&) override {
- BLOG_D("THive::TTxRegisterNode(" << Local.NodeId() << ")::Execute");
- NIceDb::TNiceDb db(txc.DB);
- TNodeId nodeId = Local.NodeId();
- TNodeInfo& node = Self->GetNode(nodeId);
- if (node.Local != Local) {
- TInstant now = TInstant::Now();
- node.Statistics.AddRestartTimestamp(now.MilliSeconds());
- node.ActualizeNodeStatistics(now);
- for (const auto& t : node.Tablets) {
- for (TTabletInfo* tablet : t.second) {
+ : TBase(hive)
+ , Local(local)
+ , Record(std::move(record))
+ {}
+
+ TTxType GetTxType() const override { return NHive::TXTYPE_REGISTER_NODE; }
+
+ bool Execute(TTransactionContext &txc, const TActorContext&) override {
+ BLOG_D("THive::TTxRegisterNode(" << Local.NodeId() << ")::Execute");
+ NIceDb::TNiceDb db(txc.DB);
+ TNodeId nodeId = Local.NodeId();
+ TNodeInfo& node = Self->GetNode(nodeId);
+ if (node.Local != Local) {
+ TInstant now = TInstant::Now();
+ node.Statistics.AddRestartTimestamp(now.MilliSeconds());
+ node.ActualizeNodeStatistics(now);
+ for (const auto& t : node.Tablets) {
+ for (TTabletInfo* tablet : t.second) {
if (tablet->IsLeader()) {
db.Table<Schema::Tablet>().Key(tablet->GetLeader().Id).Update<Schema::Tablet::LeaderNode>(0);
- } else {
+ } else {
db.Table<Schema::TabletFollowerTablet>().Key(tablet->GetFullTabletId()).Update<Schema::TabletFollowerTablet::FollowerNode>(0);
- }
- }
- }
- TVector<TSubDomainKey> servicedDomains(Record.GetServicedDomains().begin(), Record.GetServicedDomains().end());
- if (servicedDomains.empty()) {
- servicedDomains.emplace_back(Self->RootDomainKey);
- } else {
- Sort(servicedDomains);
- }
- db.Table<Schema::Node>().Key(nodeId).Update<Schema::Node::Local, Schema::Node::ServicedDomains, Schema::Node::Statistics>(Local, servicedDomains, node.Statistics);
- node.BecomeDisconnected();
- if (node.LastSeenServicedDomains != servicedDomains) {
- // new tenant - new rules
- node.Down = false;
- node.Freeze = false;
- db.Table<Schema::Node>().Key(nodeId).Update<Schema::Node::Down, Schema::Node::Freeze>(false, false);
- }
- node.Local = Local;
- node.ServicedDomains.swap(servicedDomains);
- node.LastSeenServicedDomains = node.ServicedDomains;
- }
- if (Record.HasSystemLocation() && Record.GetSystemLocation().HasDataCenter()) {
- node.Location = TNodeLocation(Record.GetSystemLocation());
- node.LocationAcquired = true;
- }
- node.TabletAvailability.clear();
- for (const NKikimrLocal::TTabletAvailability& tabletAvailability : Record.GetTabletAvailability()) {
- node.TabletAvailability.emplace(tabletAvailability.GetType(), tabletAvailability);
- }
- node.BecomeConnecting();
- return true;
- }
-
- void Complete(const TActorContext&) override {
- BLOG_D("THive::TTxRegisterNode(" << Local.NodeId() << ")::Complete");
- TNodeInfo* node = Self->FindNode(Local.NodeId());
- if (node != nullptr && node->Local) { // we send ping on every RegisterNode because we want to re-sync tablets upon every reconnection
- node->Ping();
- }
- }
-};
-
+ }
+ }
+ }
+ TVector<TSubDomainKey> servicedDomains(Record.GetServicedDomains().begin(), Record.GetServicedDomains().end());
+ if (servicedDomains.empty()) {
+ servicedDomains.emplace_back(Self->RootDomainKey);
+ } else {
+ Sort(servicedDomains);
+ }
+ db.Table<Schema::Node>().Key(nodeId).Update<Schema::Node::Local, Schema::Node::ServicedDomains, Schema::Node::Statistics>(Local, servicedDomains, node.Statistics);
+ node.BecomeDisconnected();
+ if (node.LastSeenServicedDomains != servicedDomains) {
+ // new tenant - new rules
+ node.Down = false;
+ node.Freeze = false;
+ db.Table<Schema::Node>().Key(nodeId).Update<Schema::Node::Down, Schema::Node::Freeze>(false, false);
+ }
+ node.Local = Local;
+ node.ServicedDomains.swap(servicedDomains);
+ node.LastSeenServicedDomains = node.ServicedDomains;
+ }
+ if (Record.HasSystemLocation() && Record.GetSystemLocation().HasDataCenter()) {
+ node.Location = TNodeLocation(Record.GetSystemLocation());
+ node.LocationAcquired = true;
+ }
+ node.TabletAvailability.clear();
+ for (const NKikimrLocal::TTabletAvailability& tabletAvailability : Record.GetTabletAvailability()) {
+ node.TabletAvailability.emplace(tabletAvailability.GetType(), tabletAvailability);
+ }
+ node.BecomeConnecting();
+ return true;
+ }
+
+ void Complete(const TActorContext&) override {
+ BLOG_D("THive::TTxRegisterNode(" << Local.NodeId() << ")::Complete");
+ TNodeInfo* node = Self->FindNode(Local.NodeId());
+ if (node != nullptr && node->Local) { // we send ping on every RegisterNode because we want to re-sync tablets upon every reconnection
+ node->Ping();
+ }
+ }
+};
+
ITransaction* THive::CreateRegisterNode(const TActorId& local, NKikimrLocal::TEvRegisterNode rec) {
- return new TTxRegisterNode(local, std::move(rec), this);
-}
-
-} // NHive
-} // NKikimr
+ return new TTxRegisterNode(local, std::move(rec), this);
+}
+
+} // NHive
+} // NKikimr
diff --git a/ydb/core/mind/hive/tx__release_tablets.cpp b/ydb/core/mind/hive/tx__release_tablets.cpp
index 776a304a764..cdfd82ce063 100644
--- a/ydb/core/mind/hive/tx__release_tablets.cpp
+++ b/ydb/core/mind/hive/tx__release_tablets.cpp
@@ -1,97 +1,97 @@
-#include "hive_impl.h"
-#include "hive_log.h"
-
-namespace NKikimr {
-namespace NHive {
-
-class TTxReleaseTablets : public TTransactionBase<THive> {
- THolder<TEvHive::TEvReleaseTablets::THandle> Request;
+#include "hive_impl.h"
+#include "hive_log.h"
+
+namespace NKikimr {
+namespace NHive {
+
+class TTxReleaseTablets : public TTransactionBase<THive> {
+ THolder<TEvHive::TEvReleaseTablets::THandle> Request;
THolder<TEvHive::TEvReleaseTabletsReply> Response = MakeHolder<TEvHive::TEvReleaseTabletsReply>();
- TVector<std::pair<TTabletId, TActorId>> UnlockedFromActor;
- bool NeedToProcessPendingOperations = false;
-
-public:
- TTxReleaseTablets(THolder<TEvHive::TEvReleaseTablets::THandle> event, THive *hive)
- : TBase(hive)
- , Request(std::move(event))
- {}
-
- TTxType GetTxType() const override { return NHive::TXTYPE_RELEASE_TABLETS; }
-
+ TVector<std::pair<TTabletId, TActorId>> UnlockedFromActor;
+ bool NeedToProcessPendingOperations = false;
+
+public:
+ TTxReleaseTablets(THolder<TEvHive::TEvReleaseTablets::THandle> event, THive *hive)
+ : TBase(hive)
+ , Request(std::move(event))
+ {}
+
+ TTxType GetTxType() const override { return NHive::TXTYPE_RELEASE_TABLETS; }
+
bool Execute(TTransactionContext& txc, const TActorContext&) override {
- const NKikimrHive::TEvReleaseTablets& request(Request->Get()->Record);
- NKikimrHive::TEvReleaseTabletsReply& response(Response->Record);
- BLOG_D("THive::TTxReleaseTablets::Execute " << request);
- NIceDb::TNiceDb db(txc.DB);
- for (TTabletId tabletId : request.GetTabletIDs()) {
+ const NKikimrHive::TEvReleaseTablets& request(Request->Get()->Record);
+ NKikimrHive::TEvReleaseTabletsReply& response(Response->Record);
+ BLOG_D("THive::TTxReleaseTablets::Execute " << request);
+ NIceDb::TNiceDb db(txc.DB);
+ for (TTabletId tabletId : request.GetTabletIDs()) {
TLeaderTabletInfo* tablet = Self->FindTablet(tabletId);
- if (tablet != nullptr) {
- Y_VERIFY(tablet->SeizedByChild);
-
- if (tablet->IsAlive() && tablet->Node != nullptr) {
- tablet->SendStopTablet(tablet->Node->Local, tablet->GetFullTabletId());
+ if (tablet != nullptr) {
+ Y_VERIFY(tablet->SeizedByChild);
+
+ if (tablet->IsAlive() && tablet->Node != nullptr) {
+ tablet->SendStopTablet(tablet->Node->Local, tablet->GetFullTabletId());
for (TFollowerTabletInfo& follower : tablet->Followers) {
if (follower.IsAlive() && follower.Node != nullptr) {
follower.SendStopTablet(follower.Node->Local, follower.GetFullTabletId());
- }
- }
- }
-
- db.Table<Schema::Metrics>().Key(tablet->Id, 0).Delete();
- for (const TTabletChannelInfo& channelInfo : tablet->TabletStorageInfo->Channels) {
- for (const TTabletChannelInfo::THistoryEntry& historyInfo : channelInfo.History) {
- db.Table<Schema::TabletChannelGen>().Key(tablet->Id, channelInfo.Channel, historyInfo.FromGeneration).Delete();
- }
- db.Table<Schema::TabletChannel>().Key(tablet->Id, channelInfo.Channel).Delete();
- }
+ }
+ }
+ }
+
+ db.Table<Schema::Metrics>().Key(tablet->Id, 0).Delete();
+ for (const TTabletChannelInfo& channelInfo : tablet->TabletStorageInfo->Channels) {
+ for (const TTabletChannelInfo::THistoryEntry& historyInfo : channelInfo.History) {
+ db.Table<Schema::TabletChannelGen>().Key(tablet->Id, channelInfo.Channel, historyInfo.FromGeneration).Delete();
+ }
+ db.Table<Schema::TabletChannel>().Key(tablet->Id, channelInfo.Channel).Delete();
+ }
for (TFollowerTabletInfo& follower : tablet->Followers) {
auto fullTabletId = follower.GetFullTabletId();
db.Table<Schema::TabletFollowerTablet>().Key(fullTabletId).Delete();
- db.Table<Schema::Metrics>().Key(fullTabletId).Delete();
- }
+ db.Table<Schema::Metrics>().Key(fullTabletId).Delete();
+ }
for (TFollowerGroup& group : tablet->FollowerGroups) {
db.Table<Schema::TabletFollowerGroup>().Key(tablet->Id, group.Id).Delete();
- }
- db.Table<Schema::Tablet>().Key(tablet->Id).Delete();
- TActorId unlockedFromActor = tablet->ClearLockedToActor();
- if (unlockedFromActor) {
- UnlockedFromActor.emplace_back(tabletId, unlockedFromActor);
- }
- if (Self->PendingCreateTablets.count({tablet->Owner.first, tablet->Owner.second}) > 0) {
- NeedToProcessPendingOperations = true;
- }
- Self->DeleteTablet(tablet->Id);
-
- ui64 uniqPart = UniqPartFromTabletID(tabletId);
- ui64 newOwnerId = request.GetNewOwnerID();
- TSequencer::TSequence pointSeq(uniqPart);
-
- db.Table<Schema::TabletOwners>().Key(pointSeq.Begin, pointSeq.End).Update<Schema::TabletOwners::OwnerId>(newOwnerId);
- Self->Keeper.AddOwnedSequence(newOwnerId, pointSeq);
- }
-
- response.AddTabletIDs(tabletId);
- }
- return true;
- }
-
+ }
+ db.Table<Schema::Tablet>().Key(tablet->Id).Delete();
+ TActorId unlockedFromActor = tablet->ClearLockedToActor();
+ if (unlockedFromActor) {
+ UnlockedFromActor.emplace_back(tabletId, unlockedFromActor);
+ }
+ if (Self->PendingCreateTablets.count({tablet->Owner.first, tablet->Owner.second}) > 0) {
+ NeedToProcessPendingOperations = true;
+ }
+ Self->DeleteTablet(tablet->Id);
+
+ ui64 uniqPart = UniqPartFromTabletID(tabletId);
+ ui64 newOwnerId = request.GetNewOwnerID();
+ TSequencer::TSequence pointSeq(uniqPart);
+
+ db.Table<Schema::TabletOwners>().Key(pointSeq.Begin, pointSeq.End).Update<Schema::TabletOwners::OwnerId>(newOwnerId);
+ Self->Keeper.AddOwnedSequence(newOwnerId, pointSeq);
+ }
+
+ response.AddTabletIDs(tabletId);
+ }
+ return true;
+ }
+
void Complete(const TActorContext& ctx) override {
- BLOG_D("THive::TTxReleaseTablets::Complete " << Request->Get()->Record);
- for (const auto& unlockedFromActor : UnlockedFromActor) {
- // Notify lock owner that lock has been lost
- ctx.Send(unlockedFromActor.second, new TEvHive::TEvLockTabletExecutionLost(unlockedFromActor.first));
- }
- ctx.Send(Request->Sender, Response.Release());
- if (NeedToProcessPendingOperations) {
- BLOG_D("THive::TTxReleaseTablets::Complete - retrying pending operations");
- Self->ProcessPendingOperations();
- }
- }
-};
-
-ITransaction* THive::CreateReleaseTablets(TEvHive::TEvReleaseTablets::TPtr event) {
+ BLOG_D("THive::TTxReleaseTablets::Complete " << Request->Get()->Record);
+ for (const auto& unlockedFromActor : UnlockedFromActor) {
+ // Notify lock owner that lock has been lost
+ ctx.Send(unlockedFromActor.second, new TEvHive::TEvLockTabletExecutionLost(unlockedFromActor.first));
+ }
+ ctx.Send(Request->Sender, Response.Release());
+ if (NeedToProcessPendingOperations) {
+ BLOG_D("THive::TTxReleaseTablets::Complete - retrying pending operations");
+ Self->ProcessPendingOperations();
+ }
+ }
+};
+
+ITransaction* THive::CreateReleaseTablets(TEvHive::TEvReleaseTablets::TPtr event) {
return new TTxReleaseTablets(THolder(std::move(event.Release())), this);
-}
-
-} // NHive
-} // NKikimr
+}
+
+} // NHive
+} // NKikimr
diff --git a/ydb/core/mind/hive/tx__release_tablets_reply.cpp b/ydb/core/mind/hive/tx__release_tablets_reply.cpp
index e8becaf87cc..8589258f32e 100644
--- a/ydb/core/mind/hive/tx__release_tablets_reply.cpp
+++ b/ydb/core/mind/hive/tx__release_tablets_reply.cpp
@@ -1,123 +1,123 @@
-#include "hive_impl.h"
-#include "hive_log.h"
-
-namespace NKikimr {
-namespace NHive {
-
-class TReleaseTabletsWaitActor : public TActorBootstrapped<TReleaseTabletsWaitActor>, public ISubActor {
-public:
- ui32 TabletsTotal = 0;
- ui32 TabletsDone = 0;
- THive* Hive;
-
- TReleaseTabletsWaitActor(THive* hive)
- : Hive(hive)
- {}
-
- void PassAway() override {
- Hive->RemoveSubActor(this);
- return IActor::PassAway();
- }
-
- void Cleanup() override {
- PassAway();
- }
-
- void Handle(TEvPrivate::TEvRestartComplete::TPtr&) {
- ++TabletsDone;
- if (TabletsDone >= TabletsTotal) {
- BLOG_D("THive::TTxReleaseTabletsReply::Complete - continue migration");
- Hive->SendToRootHivePipe(new TEvHive::TEvSeizeTablets(Hive->MigrationFilter));
- PassAway();
- }
- }
-
- void Bootstrap(const TActorContext&) {
- Become(&TThis::StateWork);
- if (TabletsTotal == 0) {
- BLOG_D("THive::TTxReleaseTabletsReply::Complete - continue migration");
- Hive->SendToRootHivePipe(new TEvHive::TEvSeizeTablets(Hive->MigrationFilter));
- PassAway();
- }
- }
-
- STATEFN(StateWork) {
- switch (ev->GetTypeRewrite()) {
- cFunc(TEvents::TSystem::PoisonPill, PassAway);
- hFunc(TEvPrivate::TEvRestartComplete, Handle);
- }
- }
-};
-
-
-class TTxReleaseTabletsReply : public TTransactionBase<THive> {
- THolder<TEvHive::TEvReleaseTabletsReply::THandle> Request;
-
-public:
- TTxReleaseTabletsReply(THolder<TEvHive::TEvReleaseTabletsReply::THandle> event, THive *hive)
- : TBase(hive)
- , Request(std::move(event))
- {}
-
- TTxType GetTxType() const override { return NHive::TXTYPE_RELEASE_TABLETS_REPLY; }
-
+#include "hive_impl.h"
+#include "hive_log.h"
+
+namespace NKikimr {
+namespace NHive {
+
+class TReleaseTabletsWaitActor : public TActorBootstrapped<TReleaseTabletsWaitActor>, public ISubActor {
+public:
+ ui32 TabletsTotal = 0;
+ ui32 TabletsDone = 0;
+ THive* Hive;
+
+ TReleaseTabletsWaitActor(THive* hive)
+ : Hive(hive)
+ {}
+
+ void PassAway() override {
+ Hive->RemoveSubActor(this);
+ return IActor::PassAway();
+ }
+
+ void Cleanup() override {
+ PassAway();
+ }
+
+ void Handle(TEvPrivate::TEvRestartComplete::TPtr&) {
+ ++TabletsDone;
+ if (TabletsDone >= TabletsTotal) {
+ BLOG_D("THive::TTxReleaseTabletsReply::Complete - continue migration");
+ Hive->SendToRootHivePipe(new TEvHive::TEvSeizeTablets(Hive->MigrationFilter));
+ PassAway();
+ }
+ }
+
+ void Bootstrap(const TActorContext&) {
+ Become(&TThis::StateWork);
+ if (TabletsTotal == 0) {
+ BLOG_D("THive::TTxReleaseTabletsReply::Complete - continue migration");
+ Hive->SendToRootHivePipe(new TEvHive::TEvSeizeTablets(Hive->MigrationFilter));
+ PassAway();
+ }
+ }
+
+ STATEFN(StateWork) {
+ switch (ev->GetTypeRewrite()) {
+ cFunc(TEvents::TSystem::PoisonPill, PassAway);
+ hFunc(TEvPrivate::TEvRestartComplete, Handle);
+ }
+ }
+};
+
+
+class TTxReleaseTabletsReply : public TTransactionBase<THive> {
+ THolder<TEvHive::TEvReleaseTabletsReply::THandle> Request;
+
+public:
+ TTxReleaseTabletsReply(THolder<TEvHive::TEvReleaseTabletsReply::THandle> event, THive *hive)
+ : TBase(hive)
+ , Request(std::move(event))
+ {}
+
+ TTxType GetTxType() const override { return NHive::TXTYPE_RELEASE_TABLETS_REPLY; }
+
bool Execute(TTransactionContext& txc, const TActorContext&) override {
- const NKikimrHive::TEvReleaseTabletsReply& request(Request->Get()->Record);
- BLOG_D("THive::TTxReleaseTabletsReply::Execute " << request);
- NIceDb::TNiceDb db(txc.DB);
- for (const TTabletId tabletId : request.GetTabletIDs()) {
- db.Table<Schema::Tablet>().Key(tabletId).Update<Schema::Tablet::NeedToReleaseFromParent>(false);
- }
- return true;
- }
-
+ const NKikimrHive::TEvReleaseTabletsReply& request(Request->Get()->Record);
+ BLOG_D("THive::TTxReleaseTabletsReply::Execute " << request);
+ NIceDb::TNiceDb db(txc.DB);
+ for (const TTabletId tabletId : request.GetTabletIDs()) {
+ db.Table<Schema::Tablet>().Key(tabletId).Update<Schema::Tablet::NeedToReleaseFromParent>(false);
+ }
+ return true;
+ }
+
void Complete(const TActorContext& ctx) override {
- const NKikimrHive::TEvReleaseTabletsReply& request(Request->Get()->Record);
- BLOG_D("THive::TTxReleaseTabletsReply::Complete");
-
- TActorId waitActorId;
- TReleaseTabletsWaitActor* waitActor = nullptr;
- if (Self->MigrationFilter.GetWaitForTabletsToRise()) {
- waitActor = new TReleaseTabletsWaitActor(Self);
+ const NKikimrHive::TEvReleaseTabletsReply& request(Request->Get()->Record);
+ BLOG_D("THive::TTxReleaseTabletsReply::Complete");
+
+ TActorId waitActorId;
+ TReleaseTabletsWaitActor* waitActor = nullptr;
+ if (Self->MigrationFilter.GetWaitForTabletsToRise()) {
+ waitActor = new TReleaseTabletsWaitActor(Self);
waitActorId = ctx.RegisterWithSameMailbox(waitActor);
- Self->SubActors.emplace_back(waitActor);
- }
-
- for (TTabletId tabletId : request.GetTabletIDs()) {
+ Self->SubActors.emplace_back(waitActor);
+ }
+
+ for (TTabletId tabletId : request.GetTabletIDs()) {
TLeaderTabletInfo* tablet = Self->FindTablet(tabletId);
- if (tablet != nullptr) {
- tablet->NeedToReleaseFromParent = false;
- if (tablet->IsReadyToAssignGroups()) {
- tablet->InitiateAssignTabletGroups();
- } else if (tablet->IsBootingSuppressed()) {
- // Tablet will never boot, so notify about creation right now
-// for (const TActorId& actor : tablet->ActorsToNotify) {
-// ctx.Send(actor, new TEvHive::TEvTabletCreationResult(NKikimrProto::OK, TabletId));
-// }
- tablet->ActorsToNotify.clear();
- } else {
- tablet->TryToBoot();
- if (waitActor) {
- waitActor->TabletsTotal++;
- tablet->ActorsToNotifyOnRestart.emplace_back(waitActorId);
- }
- }
- }
- }
- Self->MigrationProgress += request.TabletIDsSize();
- // continue migration
- if (waitActor) {
- BLOG_D("THive::TTxReleaseTabletsReply::Complete - waiting for tablets to rise");
- return; // waiting for tablets
- } else {
- Self->SendToRootHivePipe(new TEvHive::TEvSeizeTablets(Self->MigrationFilter));
- }
- }
-};
-
-ITransaction* THive::CreateReleaseTabletsReply(TEvHive::TEvReleaseTabletsReply::TPtr event) {
- return new TTxReleaseTabletsReply(THolder(event.Release()), this);
-}
-
-} // NHive
-} // NKikimr
+ if (tablet != nullptr) {
+ tablet->NeedToReleaseFromParent = false;
+ if (tablet->IsReadyToAssignGroups()) {
+ tablet->InitiateAssignTabletGroups();
+ } else if (tablet->IsBootingSuppressed()) {
+ // Tablet will never boot, so notify about creation right now
+// for (const TActorId& actor : tablet->ActorsToNotify) {
+// ctx.Send(actor, new TEvHive::TEvTabletCreationResult(NKikimrProto::OK, TabletId));
+// }
+ tablet->ActorsToNotify.clear();
+ } else {
+ tablet->TryToBoot();
+ if (waitActor) {
+ waitActor->TabletsTotal++;
+ tablet->ActorsToNotifyOnRestart.emplace_back(waitActorId);
+ }
+ }
+ }
+ }
+ Self->MigrationProgress += request.TabletIDsSize();
+ // continue migration
+ if (waitActor) {
+ BLOG_D("THive::TTxReleaseTabletsReply::Complete - waiting for tablets to rise");
+ return; // waiting for tablets
+ } else {
+ Self->SendToRootHivePipe(new TEvHive::TEvSeizeTablets(Self->MigrationFilter));
+ }
+ }
+};
+
+ITransaction* THive::CreateReleaseTabletsReply(TEvHive::TEvReleaseTabletsReply::TPtr event) {
+ return new TTxReleaseTabletsReply(THolder(event.Release()), this);
+}
+
+} // NHive
+} // NKikimr
diff --git a/ydb/core/mind/hive/tx__request_tablet_seq.cpp b/ydb/core/mind/hive/tx__request_tablet_seq.cpp
index f6c6e743b2e..aa43f85ea4e 100644
--- a/ydb/core/mind/hive/tx__request_tablet_seq.cpp
+++ b/ydb/core/mind/hive/tx__request_tablet_seq.cpp
@@ -1,76 +1,76 @@
-#include "hive_impl.h"
-#include "hive_log.h"
-
-namespace NKikimr {
-namespace NHive {
-
-class TTxRequestTabletSequence : public TTransactionBase<THive> {
-protected:
- TEvHive::TEvRequestTabletIdSequence::TPtr Event;
- TSequencer::TOwnerType Owner;
- TSequencer::TSequence Sequence;
- size_t Size;
-
-public:
- TTxRequestTabletSequence(TEvHive::TEvRequestTabletIdSequence::TPtr event, THive *hive)
- : TBase(hive)
- , Event(std::move(event))
- {}
-
- TTxType GetTxType() const override { return NHive::TXTYPE_REQUEST_TABLET_SEQUENCE; }
-
+#include "hive_impl.h"
+#include "hive_log.h"
+
+namespace NKikimr {
+namespace NHive {
+
+class TTxRequestTabletSequence : public TTransactionBase<THive> {
+protected:
+ TEvHive::TEvRequestTabletIdSequence::TPtr Event;
+ TSequencer::TOwnerType Owner;
+ TSequencer::TSequence Sequence;
+ size_t Size;
+
+public:
+ TTxRequestTabletSequence(TEvHive::TEvRequestTabletIdSequence::TPtr event, THive *hive)
+ : TBase(hive)
+ , Event(std::move(event))
+ {}
+
+ TTxType GetTxType() const override { return NHive::TXTYPE_REQUEST_TABLET_SEQUENCE; }
+
bool Execute(TTransactionContext& txc, const TActorContext&) override {
- BLOG_D("THive::TTxRequestTabletSequence()::Execute");
- const auto& pbRecord(Event->Get()->Record);
- Size = pbRecord.GetSize();
- if (Size == 0) {
- Size = Self->GetMinRequestSequenceSize();
- }
- if (Size > Self->GetMaxRequestSequenceSize()) {
- Size = Self->GetMaxRequestSequenceSize();
- }
- Owner = {pbRecord.GetOwner().GetOwner(), pbRecord.GetOwner().GetOwnerIdx()};
- std::vector<TSequencer::TOwnerType> modified;
- Sequence = Self->Sequencer.AllocateSequence(Owner, Size, modified);
- if (Sequence != TSequencer::NO_SEQUENCE) {
- NIceDb::TNiceDb db(txc.DB);
- for (auto owner : modified) {
- auto sequence = Self->Sequencer.GetSequence(owner);
- db.Table<Schema::Sequences>()
- .Key(owner)
- .Update<Schema::Sequences::Begin, Schema::Sequences::Next, Schema::Sequences::End>(sequence.Begin, sequence.Next, sequence.End);
-
- }
- TSequencer::TElementType nextElement = Self->Sequencer.GetNextElement();
- if (nextElement != TSequencer::NO_ELEMENT) {
- Self->NextTabletId = Max(Self->NextTabletId, nextElement);
- db.Table<Schema::State>().Key(TSchemeIds::State::NextTabletId).Update<Schema::State::Value>(Self->NextTabletId);
- }
- db.Table<Schema::TabletOwners>().Key(Sequence.Begin, Sequence.End).Update<Schema::TabletOwners::OwnerId>(Owner.first);
- Self->Keeper.AddOwnedSequence(Owner.first, Sequence);
- }
- return true;
- }
-
+ BLOG_D("THive::TTxRequestTabletSequence()::Execute");
+ const auto& pbRecord(Event->Get()->Record);
+ Size = pbRecord.GetSize();
+ if (Size == 0) {
+ Size = Self->GetMinRequestSequenceSize();
+ }
+ if (Size > Self->GetMaxRequestSequenceSize()) {
+ Size = Self->GetMaxRequestSequenceSize();
+ }
+ Owner = {pbRecord.GetOwner().GetOwner(), pbRecord.GetOwner().GetOwnerIdx()};
+ std::vector<TSequencer::TOwnerType> modified;
+ Sequence = Self->Sequencer.AllocateSequence(Owner, Size, modified);
+ if (Sequence != TSequencer::NO_SEQUENCE) {
+ NIceDb::TNiceDb db(txc.DB);
+ for (auto owner : modified) {
+ auto sequence = Self->Sequencer.GetSequence(owner);
+ db.Table<Schema::Sequences>()
+ .Key(owner)
+ .Update<Schema::Sequences::Begin, Schema::Sequences::Next, Schema::Sequences::End>(sequence.Begin, sequence.Next, sequence.End);
+
+ }
+ TSequencer::TElementType nextElement = Self->Sequencer.GetNextElement();
+ if (nextElement != TSequencer::NO_ELEMENT) {
+ Self->NextTabletId = Max(Self->NextTabletId, nextElement);
+ db.Table<Schema::State>().Key(TSchemeIds::State::NextTabletId).Update<Schema::State::Value>(Self->NextTabletId);
+ }
+ db.Table<Schema::TabletOwners>().Key(Sequence.Begin, Sequence.End).Update<Schema::TabletOwners::OwnerId>(Owner.first);
+ Self->Keeper.AddOwnedSequence(Owner.first, Sequence);
+ }
+ return true;
+ }
+
void Complete(const TActorContext&) override {
- BLOG_D("THive::TTxRequestTabletSequence()::Complete");
- if (Sequence == TSequencer::NO_SEQUENCE) {
- BLOG_CRIT("Could not allocate sequence of " << Size << " elements for " << Owner);
- } else {
- BLOG_D("Respond with sequence " << Sequence << " to " << Owner);
+ BLOG_D("THive::TTxRequestTabletSequence()::Complete");
+ if (Sequence == TSequencer::NO_SEQUENCE) {
+ BLOG_CRIT("Could not allocate sequence of " << Size << " elements for " << Owner);
+ } else {
+ BLOG_D("Respond with sequence " << Sequence << " to " << Owner);
THolder<TEvHive::TEvResponseTabletIdSequence> response = MakeHolder<TEvHive::TEvResponseTabletIdSequence>();
- const auto& pbRecord(Event->Get()->Record);
- response->Record.MutableOwner()->CopyFrom(pbRecord.GetOwner());
- response->Record.SetBeginId(Sequence.Begin);
- response->Record.SetEndId(Sequence.End);
- Self->Send(Event->Sender, std::move(response), 0, Event->Cookie);
- }
- }
-};
-
-ITransaction* THive::CreateRequestTabletSequence(TEvHive::TEvRequestTabletIdSequence::TPtr event) {
- return new TTxRequestTabletSequence(std::move(event), this);
-}
-
-} // NHive
-} // NKikimr
+ const auto& pbRecord(Event->Get()->Record);
+ response->Record.MutableOwner()->CopyFrom(pbRecord.GetOwner());
+ response->Record.SetBeginId(Sequence.Begin);
+ response->Record.SetEndId(Sequence.End);
+ Self->Send(Event->Sender, std::move(response), 0, Event->Cookie);
+ }
+ }
+};
+
+ITransaction* THive::CreateRequestTabletSequence(TEvHive::TEvRequestTabletIdSequence::TPtr event) {
+ return new TTxRequestTabletSequence(std::move(event), this);
+}
+
+} // NHive
+} // NKikimr
diff --git a/ydb/core/mind/hive/tx__response_tablet_seq.cpp b/ydb/core/mind/hive/tx__response_tablet_seq.cpp
index 922a0c9a1e2..4c0e2a41e3a 100644
--- a/ydb/core/mind/hive/tx__response_tablet_seq.cpp
+++ b/ydb/core/mind/hive/tx__response_tablet_seq.cpp
@@ -1,69 +1,69 @@
-#include "hive_impl.h"
-#include "hive_log.h"
-
-namespace NKikimr {
-namespace NHive {
-
-class TTxResponseTabletSequence : public TTransactionBase<THive> {
-protected:
- TEvHive::TEvResponseTabletIdSequence::TPtr Event;
- TSequencer::TOwnerType Owner;
- TSequencer::TSequence Sequence;
-
-public:
- TTxResponseTabletSequence(TEvHive::TEvResponseTabletIdSequence::TPtr event, THive *hive)
- : TBase(hive)
- , Event(std::move(event))
- {}
-
- TTxType GetTxType() const override { return NHive::TXTYPE_RESPONSE_TABLET_SEQUENCE; }
-
+#include "hive_impl.h"
+#include "hive_log.h"
+
+namespace NKikimr {
+namespace NHive {
+
+class TTxResponseTabletSequence : public TTransactionBase<THive> {
+protected:
+ TEvHive::TEvResponseTabletIdSequence::TPtr Event;
+ TSequencer::TOwnerType Owner;
+ TSequencer::TSequence Sequence;
+
+public:
+ TTxResponseTabletSequence(TEvHive::TEvResponseTabletIdSequence::TPtr event, THive *hive)
+ : TBase(hive)
+ , Event(std::move(event))
+ {}
+
+ TTxType GetTxType() const override { return NHive::TXTYPE_RESPONSE_TABLET_SEQUENCE; }
+
bool Execute(TTransactionContext& txc, const TActorContext&) override {
- BLOG_D("THive::TTxResponseTabletSequence()::Execute");
- const auto& pbRecord(Event->Get()->Record);
- if (!pbRecord.HasOwner()) {
- BLOG_ERROR("Invalid response received");
- return true;
- }
- if (pbRecord.GetBeginId() != pbRecord.GetEndId()) {
- Y_VERIFY(pbRecord.GetOwner().GetOwner() == Self->TabletID());
- Owner = {TSequencer::NO_OWNER, pbRecord.GetOwner().GetOwnerIdx()};
- Sequence = {pbRecord.GetBeginId(), pbRecord.GetEndId()};
- BLOG_D("Received sequence " << Sequence);
- if (Self->Sequencer.AddFreeSequence(Owner, Sequence)) {
- NIceDb::TNiceDb db(txc.DB);
- db.Table<Schema::Sequences>()
- .Key(Owner)
- .Update<Schema::Sequences::Begin, Schema::Sequences::Next, Schema::Sequences::End>(Sequence.Begin, Sequence.Next, Sequence.End);
- // we keep ownership of the sequence in case tablets will be deleted multiple times
- Self->Keeper.AddOwnedSequence(Self->TabletID(), Sequence);
- db.Table<Schema::TabletOwners>()
- .Key(Sequence.Begin, Sequence.End)
- .Update<Schema::TabletOwners::OwnerId>(Self->TabletID());
- } else {
- BLOG_D("This sequence " << Sequence << " already exists");
- Sequence.Clear();
- }
- } else {
- BLOG_D("Received empty sequence");
- }
- if (pbRecord.GetOwner().GetOwnerIdx() >= Self->RequestingSequenceIndex) {
- Self->RequestingSequenceNow = false;
- }
- return true;
- }
-
+ BLOG_D("THive::TTxResponseTabletSequence()::Execute");
+ const auto& pbRecord(Event->Get()->Record);
+ if (!pbRecord.HasOwner()) {
+ BLOG_ERROR("Invalid response received");
+ return true;
+ }
+ if (pbRecord.GetBeginId() != pbRecord.GetEndId()) {
+ Y_VERIFY(pbRecord.GetOwner().GetOwner() == Self->TabletID());
+ Owner = {TSequencer::NO_OWNER, pbRecord.GetOwner().GetOwnerIdx()};
+ Sequence = {pbRecord.GetBeginId(), pbRecord.GetEndId()};
+ BLOG_D("Received sequence " << Sequence);
+ if (Self->Sequencer.AddFreeSequence(Owner, Sequence)) {
+ NIceDb::TNiceDb db(txc.DB);
+ db.Table<Schema::Sequences>()
+ .Key(Owner)
+ .Update<Schema::Sequences::Begin, Schema::Sequences::Next, Schema::Sequences::End>(Sequence.Begin, Sequence.Next, Sequence.End);
+ // we keep ownership of the sequence in case tablets will be deleted multiple times
+ Self->Keeper.AddOwnedSequence(Self->TabletID(), Sequence);
+ db.Table<Schema::TabletOwners>()
+ .Key(Sequence.Begin, Sequence.End)
+ .Update<Schema::TabletOwners::OwnerId>(Self->TabletID());
+ } else {
+ BLOG_D("This sequence " << Sequence << " already exists");
+ Sequence.Clear();
+ }
+ } else {
+ BLOG_D("Received empty sequence");
+ }
+ if (pbRecord.GetOwner().GetOwnerIdx() >= Self->RequestingSequenceIndex) {
+ Self->RequestingSequenceNow = false;
+ }
+ return true;
+ }
+
void Complete(const TActorContext&) override {
- BLOG_D("THive::TTxResponseTabletSequence()::Complete");
- if (!Sequence.Empty()) {
- Self->ProcessPendingOperations();
- }
- }
-};
-
-ITransaction* THive::CreateResponseTabletSequence(TEvHive::TEvResponseTabletIdSequence::TPtr event) {
- return new TTxResponseTabletSequence(std::move(event), this);
-}
-
-} // NHive
-} // NKikimr
+ BLOG_D("THive::TTxResponseTabletSequence()::Complete");
+ if (!Sequence.Empty()) {
+ Self->ProcessPendingOperations();
+ }
+ }
+};
+
+ITransaction* THive::CreateResponseTabletSequence(TEvHive::TEvResponseTabletIdSequence::TPtr event) {
+ return new TTxResponseTabletSequence(std::move(event), this);
+}
+
+} // NHive
+} // NKikimr
diff --git a/ydb/core/mind/hive/tx__restart_tablet.cpp b/ydb/core/mind/hive/tx__restart_tablet.cpp
index ad7d7d2b5a6..3c070ed706c 100644
--- a/ydb/core/mind/hive/tx__restart_tablet.cpp
+++ b/ydb/core/mind/hive/tx__restart_tablet.cpp
@@ -1,65 +1,65 @@
-#include "hive_impl.h"
-#include "hive_log.h"
-
-namespace NKikimr {
-namespace NHive {
-
-class TTxRestartTablet : public TTransactionBase<THive> {
-protected:
- TFullTabletId TabletId;
- TNodeId PreferredNodeId;
-public:
- TTxRestartTablet(TFullTabletId tabletId, THive *hive)
- : TBase(hive)
- , TabletId(tabletId)
- , PreferredNodeId(0)
- {}
-
- TTxRestartTablet(TFullTabletId tabletId, TNodeId preferredNodeId, THive *hive)
- : TBase(hive)
- , TabletId(tabletId)
- , PreferredNodeId(preferredNodeId)
- {}
-
- TTxType GetTxType() const override { return NHive::TXTYPE_RESTART_TABLET; }
-
+#include "hive_impl.h"
+#include "hive_log.h"
+
+namespace NKikimr {
+namespace NHive {
+
+class TTxRestartTablet : public TTransactionBase<THive> {
+protected:
+ TFullTabletId TabletId;
+ TNodeId PreferredNodeId;
+public:
+ TTxRestartTablet(TFullTabletId tabletId, THive *hive)
+ : TBase(hive)
+ , TabletId(tabletId)
+ , PreferredNodeId(0)
+ {}
+
+ TTxRestartTablet(TFullTabletId tabletId, TNodeId preferredNodeId, THive *hive)
+ : TBase(hive)
+ , TabletId(tabletId)
+ , PreferredNodeId(preferredNodeId)
+ {}
+
+ TTxType GetTxType() const override { return NHive::TXTYPE_RESTART_TABLET; }
+
bool Execute(TTransactionContext &txc, const TActorContext&) override {
- TTabletInfo* tablet = Self->FindTablet(TabletId);
- if (tablet != nullptr) {
- if (PreferredNodeId != 0) {
- BLOG_D("THive::TTxRestartTablet(" << tablet->ToString() << ")::Execute");
- } else {
- BLOG_D("THive::TTxRestartTablet(" << tablet->ToString() << " to node " << PreferredNodeId << ")::Execute");
- }
- if (!tablet->IsStopped()) {
- NIceDb::TNiceDb db(txc.DB);
- if (tablet->Node != nullptr) {
+ TTabletInfo* tablet = Self->FindTablet(TabletId);
+ if (tablet != nullptr) {
+ if (PreferredNodeId != 0) {
+ BLOG_D("THive::TTxRestartTablet(" << tablet->ToString() << ")::Execute");
+ } else {
+ BLOG_D("THive::TTxRestartTablet(" << tablet->ToString() << " to node " << PreferredNodeId << ")::Execute");
+ }
+ if (!tablet->IsStopped()) {
+ NIceDb::TNiceDb db(txc.DB);
+ if (tablet->Node != nullptr) {
if (tablet->IsLeader()) {
db.Table<Schema::Tablet>().Key(tablet->GetLeader().Id).Update<Schema::Tablet::LeaderNode>(0);
- } else {
+ } else {
db.Table<Schema::TabletFollowerTablet>().Key(tablet->GetFullTabletId()).Update<Schema::TabletFollowerTablet::FollowerNode>(0);
- }
- }
- tablet->InitiateStop();
- }
- tablet->PreferredNodeId = PreferredNodeId;
- tablet->GetLeader().TryToBoot();
- }
- return true;
- }
-
+ }
+ }
+ tablet->InitiateStop();
+ }
+ tablet->PreferredNodeId = PreferredNodeId;
+ tablet->GetLeader().TryToBoot();
+ }
+ return true;
+ }
+
void Complete(const TActorContext&) override {
- BLOG_D("THive::TTxRestartTablet(" << TabletId << ")::Complete");
- }
-};
-
-ITransaction* THive::CreateRestartTablet(TFullTabletId tabletId) {
- return new TTxRestartTablet(tabletId, this);
-}
-
-ITransaction* THive::CreateRestartTablet(TFullTabletId tabletId, TNodeId preferredNodeId) {
- return new TTxRestartTablet(tabletId, preferredNodeId, this);
-}
-
-} // NHive
-} // NKikimr
+ BLOG_D("THive::TTxRestartTablet(" << TabletId << ")::Complete");
+ }
+};
+
+ITransaction* THive::CreateRestartTablet(TFullTabletId tabletId) {
+ return new TTxRestartTablet(tabletId, this);
+}
+
+ITransaction* THive::CreateRestartTablet(TFullTabletId tabletId, TNodeId preferredNodeId) {
+ return new TTxRestartTablet(tabletId, preferredNodeId, this);
+}
+
+} // NHive
+} // NKikimr
diff --git a/ydb/core/mind/hive/tx__resume_tablet.cpp b/ydb/core/mind/hive/tx__resume_tablet.cpp
index 244852430e6..a7252bff725 100644
--- a/ydb/core/mind/hive/tx__resume_tablet.cpp
+++ b/ydb/core/mind/hive/tx__resume_tablet.cpp
@@ -1,91 +1,91 @@
-#include "hive_impl.h"
-#include "hive_log.h"
-
-namespace NKikimr {
-namespace NHive {
-
-class TTxResumeTablet : public TTransactionBase<THive> {
- const TTabletId TabletId;
- const TActorId ActorToNotify;
- NKikimrProto::EReplyStatus Status;
-
-public:
- TTxResumeTablet(ui64 tabletId, const TActorId &actorToNotify, THive *hive)
- : TBase(hive)
- , TabletId(tabletId)
- , ActorToNotify(actorToNotify)
- , Status(NKikimrProto::UNKNOWN)
- {}
-
- TTxType GetTxType() const override { return NHive::TXTYPE_RESUME_TABLET; }
-
+#include "hive_impl.h"
+#include "hive_log.h"
+
+namespace NKikimr {
+namespace NHive {
+
+class TTxResumeTablet : public TTransactionBase<THive> {
+ const TTabletId TabletId;
+ const TActorId ActorToNotify;
+ NKikimrProto::EReplyStatus Status;
+
+public:
+ TTxResumeTablet(ui64 tabletId, const TActorId &actorToNotify, THive *hive)
+ : TBase(hive)
+ , TabletId(tabletId)
+ , ActorToNotify(actorToNotify)
+ , Status(NKikimrProto::UNKNOWN)
+ {}
+
+ TTxType GetTxType() const override { return NHive::TXTYPE_RESUME_TABLET; }
+
bool Execute(TTransactionContext &txc, const TActorContext&) override {
- BLOG_D("THive::TTxResumeTablet::Execute Tablet: " << TabletId);
+ BLOG_D("THive::TTxResumeTablet::Execute Tablet: " << TabletId);
TLeaderTabletInfo* tablet = Self->FindTablet(TabletId);
- if (tablet != nullptr) {
- ETabletState State = tablet->State;
- ETabletState NewState = State;
- NIceDb::TNiceDb db(txc.DB);
- switch (State) {
- case ETabletState::GroupAssignment:
- Status = NKikimrProto::ERROR;
- break;
- case ETabletState::ReadyToWork:
- Status = NKikimrProto::ALREADY;
- break;
- case ETabletState::Stopped:
- // Switch to ReadyToWork
- if (tablet->ChannelProfileNewGroup.any()) {
- NewState = ETabletState::GroupAssignment;
- } else {
- NewState = ETabletState::ReadyToWork;
- }
- Status = NKikimrProto::OK;
- break;
- case ETabletState::Deleting:
- Status = NKikimrProto::ERROR;
- break;
- case ETabletState::BlockStorage:
- Status = NKikimrProto::ERROR;
- break;
- case ETabletState::Stopping:
- case ETabletState::StoppingInGroupAssignment:
- case ETabletState::Unknown:
- Status = NKikimrProto::ERROR;
- break;
- }
- if (Status == NKikimrProto::OK && NewState != State) {
- db.Table<Schema::Tablet>().Key(TabletId).Update<Schema::Tablet::State>(NewState);
- tablet->State = NewState;
- }
- }
- return true;
- }
-
+ if (tablet != nullptr) {
+ ETabletState State = tablet->State;
+ ETabletState NewState = State;
+ NIceDb::TNiceDb db(txc.DB);
+ switch (State) {
+ case ETabletState::GroupAssignment:
+ Status = NKikimrProto::ERROR;
+ break;
+ case ETabletState::ReadyToWork:
+ Status = NKikimrProto::ALREADY;
+ break;
+ case ETabletState::Stopped:
+ // Switch to ReadyToWork
+ if (tablet->ChannelProfileNewGroup.any()) {
+ NewState = ETabletState::GroupAssignment;
+ } else {
+ NewState = ETabletState::ReadyToWork;
+ }
+ Status = NKikimrProto::OK;
+ break;
+ case ETabletState::Deleting:
+ Status = NKikimrProto::ERROR;
+ break;
+ case ETabletState::BlockStorage:
+ Status = NKikimrProto::ERROR;
+ break;
+ case ETabletState::Stopping:
+ case ETabletState::StoppingInGroupAssignment:
+ case ETabletState::Unknown:
+ Status = NKikimrProto::ERROR;
+ break;
+ }
+ if (Status == NKikimrProto::OK && NewState != State) {
+ db.Table<Schema::Tablet>().Key(TabletId).Update<Schema::Tablet::State>(NewState);
+ tablet->State = NewState;
+ }
+ }
+ return true;
+ }
+
void Complete(const TActorContext& ctx) override {
- BLOG_D("THive::TTxResumeTablet::Complete TabletId: " << TabletId);
- if (Status != NKikimrProto::UNKNOWN) {
- ctx.Send(ActorToNotify, new TEvHive::TEvResumeTabletResult(Status, TabletId), 0, 0);
- if (Status == NKikimrProto::OK) {
+ BLOG_D("THive::TTxResumeTablet::Complete TabletId: " << TabletId);
+ if (Status != NKikimrProto::UNKNOWN) {
+ ctx.Send(ActorToNotify, new TEvHive::TEvResumeTabletResult(Status, TabletId), 0, 0);
+ if (Status == NKikimrProto::OK) {
TLeaderTabletInfo* tablet = Self->FindTablet(TabletId);
- if (tablet != nullptr) {
- if (tablet->IsReadyToBoot()) {
- tablet->InitiateBoot();
- } else if (tablet->IsReadyToAssignGroups()) {
- tablet->InitiateAssignTabletGroups();
- }
- }
- }
- }
- Self->ProcessBootQueue();
- }
-};
-
-ITransaction* THive::CreateResumeTablet(TTabletId tabletId, const TActorId &actorToNotify) {
- return new TTxResumeTablet(tabletId, actorToNotify, this);
-}
-
-} // NHive
-} // NKikimr
-
-
+ if (tablet != nullptr) {
+ if (tablet->IsReadyToBoot()) {
+ tablet->InitiateBoot();
+ } else if (tablet->IsReadyToAssignGroups()) {
+ tablet->InitiateAssignTabletGroups();
+ }
+ }
+ }
+ }
+ Self->ProcessBootQueue();
+ }
+};
+
+ITransaction* THive::CreateResumeTablet(TTabletId tabletId, const TActorId &actorToNotify) {
+ return new TTxResumeTablet(tabletId, actorToNotify, this);
+}
+
+} // NHive
+} // NKikimr
+
+
diff --git a/ydb/core/mind/hive/tx__seize_tablets.cpp b/ydb/core/mind/hive/tx__seize_tablets.cpp
index a784720ff85..09a93c9656d 100644
--- a/ydb/core/mind/hive/tx__seize_tablets.cpp
+++ b/ydb/core/mind/hive/tx__seize_tablets.cpp
@@ -1,129 +1,129 @@
-#include "hive_impl.h"
-#include "hive_log.h"
-
-namespace NKikimr {
-namespace NHive {
-
-class TTxSeizeTablets : public TTransactionBase<THive> {
- THolder<TEvHive::TEvSeizeTablets::THandle> Request;
+#include "hive_impl.h"
+#include "hive_log.h"
+
+namespace NKikimr {
+namespace NHive {
+
+class TTxSeizeTablets : public TTransactionBase<THive> {
+ THolder<TEvHive::TEvSeizeTablets::THandle> Request;
THolder<TEvHive::TEvSeizeTabletsReply> Response = MakeHolder<TEvHive::TEvSeizeTabletsReply>();
-
-public:
- TTxSeizeTablets(THolder<TEvHive::TEvSeizeTablets::THandle> event, THive *hive)
- : TBase(hive)
- , Request(std::move(event))
- {}
-
- TTxType GetTxType() const override { return NHive::TXTYPE_SEIZE_TABLETS; }
-
+
+public:
+ TTxSeizeTablets(THolder<TEvHive::TEvSeizeTablets::THandle> event, THive *hive)
+ : TBase(hive)
+ , Request(std::move(event))
+ {}
+
+ TTxType GetTxType() const override { return NHive::TXTYPE_SEIZE_TABLETS; }
+
static bool IsMatch(const TLeaderTabletInfo& tablet, const NKikimrHive::TEvSeizeTablets& record) {
- return tablet.ObjectDomain == TSubDomainKey(record.GetFilterDomain())
- && record.GetNewOwnerID() != tablet.Id;
- }
-
+ return tablet.ObjectDomain == TSubDomainKey(record.GetFilterDomain())
+ && record.GetNewOwnerID() != tablet.Id;
+ }
+
static bool IsAbleToMigrate(const TLeaderTabletInfo& tablet) {
- // we can only migrate 'big' tablet ids, which have non-zero bits in 44+
- // that's because it stored in the same id space, where ownerIdx is stored
- // return !tablet.IsDeleting() && StateStorageGroupFromTabletID(tablet.Id) > 0 || HiveUidFromTabletID(tablet.Id) > 0;
- // ^^ temporary commented-out due to unit tests using 0 state storage group and 0 hive uid
-
- return tablet.IsReadyToWork()
- && tablet.ChannelProfileNewGroup.none()
- && tablet.Type != TTabletTypes::Hive // because we leave hive(s) in root hive
- && tablet.Type != TTabletTypes::BlockStoreVolume // because we don't have support for NBS yet
- && tablet.Type != TTabletTypes::BlockStorePartition // because we don't have support for NBS yet
- && tablet.Type != TTabletTypes::BlockStorePartition2; // because we don't have support for NBS yet
-
- }
-
+ // we can only migrate 'big' tablet ids, which have non-zero bits in 44+
+ // that's because it stored in the same id space, where ownerIdx is stored
+ // return !tablet.IsDeleting() && StateStorageGroupFromTabletID(tablet.Id) > 0 || HiveUidFromTabletID(tablet.Id) > 0;
+ // ^^ temporary commented-out due to unit tests using 0 state storage group and 0 hive uid
+
+ return tablet.IsReadyToWork()
+ && tablet.ChannelProfileNewGroup.none()
+ && tablet.Type != TTabletTypes::Hive // because we leave hive(s) in root hive
+ && tablet.Type != TTabletTypes::BlockStoreVolume // because we don't have support for NBS yet
+ && tablet.Type != TTabletTypes::BlockStorePartition // because we don't have support for NBS yet
+ && tablet.Type != TTabletTypes::BlockStorePartition2; // because we don't have support for NBS yet
+
+ }
+
bool Execute(TTransactionContext& txc, const TActorContext&) override {
- const NKikimrHive::TEvSeizeTablets& request(Request->Get()->Record);
- NKikimrHive::TEvSeizeTabletsReply& response(Response->Record);
- BLOG_D("THive::TTxSeizeTablets::Execute " << request);
- TTabletId newOwnerId = request.GetNewOwnerID();
- response.ClearTablets();
- NIceDb::TNiceDb db(txc.DB);
- ui32 seizedTablets = 0;
- for (auto& [tabletId, tablet] : Self->Tablets) {
- if (IsMatch(tablet, request) && IsAbleToMigrate(tablet)) {
- // to simplify migration we skip following fields:
- // Schema::Tablet::Category - because nobody is using it now
- // Schema::Tablet::ActorsToNotify - because it's volatile and we are going to restart the tablet
- // Schema::Tablet::AllowedNodes - because nobody is using it now
- // Schema::Tablet::AllowedDataCenters - because nobody is using it now
-
+ const NKikimrHive::TEvSeizeTablets& request(Request->Get()->Record);
+ NKikimrHive::TEvSeizeTabletsReply& response(Response->Record);
+ BLOG_D("THive::TTxSeizeTablets::Execute " << request);
+ TTabletId newOwnerId = request.GetNewOwnerID();
+ response.ClearTablets();
+ NIceDb::TNiceDb db(txc.DB);
+ ui32 seizedTablets = 0;
+ for (auto& [tabletId, tablet] : Self->Tablets) {
+ if (IsMatch(tablet, request) && IsAbleToMigrate(tablet)) {
+ // to simplify migration we skip following fields:
+ // Schema::Tablet::Category - because nobody is using it now
+ // Schema::Tablet::ActorsToNotify - because it's volatile and we are going to restart the tablet
+ // Schema::Tablet::AllowedNodes - because nobody is using it now
+ // Schema::Tablet::AllowedDataCenters - because nobody is using it now
+
// we also skip current metrics state for followers
-
- TTabletId id = tabletId;
- BLOG_D("THive::TTxSeizeTablets is migrating tablet " << id << " to " << newOwnerId);
-
- auto tabletRowset = db.Table<Schema::Tablet>().Key(id).Select();
- if (!tabletRowset.IsReady()) {
- return false;
- }
- if (tabletRowset.EndOfSet()) {
- BLOG_D("THive::TTxSeizeTablets couldn't find tablet " << id << " in database");
- continue;
- }
-
- NKikimrHive::TTabletInfo& tabletInfo = *response.AddTablets();
- tabletInfo.SetTabletID(tabletId);
- tabletInfo.MutableTabletOwner()->SetOwner(tablet.Owner.first);
- tabletInfo.MutableTabletOwner()->SetOwnerIdx(tablet.Owner.second);
- tabletInfo.SetTabletType(tablet.Type);
- tabletInfo.SetState(static_cast<ui32>(tablet.State));
- tabletInfo.SetVolatileState(tablet.GetVolatileState());
- tabletInfo.SetObjectId(tablet.ObjectId);
- tabletInfo.SetGeneration(tablet.KnownGeneration);
- ActorIdToProto(tablet.LockedToActor, tabletInfo.MutableLockedToActor());
- tabletInfo.SetLockedReconnectTimeout(tablet.LockedReconnectTimeout.MilliSeconds());
- tabletInfo.SetTabletStorageVersion(tablet.TabletStorageInfo->Version);
- tabletInfo.SetTabletBootMode(tablet.BootMode);
- tabletInfo.MutableResourceUsage()->CopyFrom(tablet.GetResourceValues());
-
- TSubDomainKey objectDomain = TSubDomainKey(tabletRowset.GetValueOrDefault<Schema::Tablet::ObjectDomain>());
- tabletInfo.MutableObjectDomain()->CopyFrom(objectDomain);
-
- TVector<TSubDomainKey> allowedDomains = tabletRowset.GetValueOrDefault<Schema::Tablet::AllowedDomains>();
- for (const auto& allowedDomain : allowedDomains) {
- if (allowedDomain != objectDomain) {
- tabletInfo.AddAllowedDomains()->CopyFrom(allowedDomain);
- }
- }
-
- auto tabletChannelRowset = db.Table<Schema::TabletChannel>().Range(tabletId).Select();
- if (!tabletChannelRowset.IsReady())
- return false;
-
- while (!tabletChannelRowset.EndOfSet()) {
- ui32 channelId = tabletChannelRowset.GetValueOrDefault<Schema::TabletChannel::Channel>();
- NKikimrHive::TTabletChannelInfo& tabletChannelInfo = *tabletInfo.AddTabletChannels();
- tabletChannelInfo.SetStoragePool(tabletChannelRowset.GetValue<Schema::TabletChannel::StoragePool>());
- tabletChannelInfo.MutableBinding()->CopyFrom(tabletChannelRowset.GetValueOrDefault<Schema::TabletChannel::Binding>());
- tabletChannelInfo.SetNeedNewGroup(tabletChannelRowset.GetValueOrDefault<Schema::TabletChannel::NeedNewGroup>());
-
- auto tabletChannelGenRowset = db.Table<Schema::TabletChannelGen>().Range(tabletId, channelId).Select();
- if (!tabletChannelGenRowset.IsReady())
- return false;
-
- while (!tabletChannelGenRowset.EndOfSet()) {
- NKikimrHive::TTabletChannelGenInfo& tabletChannelGenInfo = *tabletChannelInfo.AddHistory();
- tabletChannelGenInfo.SetGeneration(tabletChannelGenRowset.GetValue<Schema::TabletChannelGen::Generation>());
- tabletChannelGenInfo.SetGroup(tabletChannelGenRowset.GetValue<Schema::TabletChannelGen::Group>());
- tabletChannelGenInfo.SetTimestamp(tabletChannelGenRowset.GetValueOrDefault<Schema::TabletChannelGen::Timestamp>());
- tabletChannelGenInfo.SetVersion(tabletChannelGenRowset.GetValueOrDefault<Schema::TabletChannelGen::Version>());
- if (!tabletChannelGenRowset.Next())
- return false;
- }
-
- if (!tabletChannelRowset.Next())
- return false;
- }
-
+
+ TTabletId id = tabletId;
+ BLOG_D("THive::TTxSeizeTablets is migrating tablet " << id << " to " << newOwnerId);
+
+ auto tabletRowset = db.Table<Schema::Tablet>().Key(id).Select();
+ if (!tabletRowset.IsReady()) {
+ return false;
+ }
+ if (tabletRowset.EndOfSet()) {
+ BLOG_D("THive::TTxSeizeTablets couldn't find tablet " << id << " in database");
+ continue;
+ }
+
+ NKikimrHive::TTabletInfo& tabletInfo = *response.AddTablets();
+ tabletInfo.SetTabletID(tabletId);
+ tabletInfo.MutableTabletOwner()->SetOwner(tablet.Owner.first);
+ tabletInfo.MutableTabletOwner()->SetOwnerIdx(tablet.Owner.second);
+ tabletInfo.SetTabletType(tablet.Type);
+ tabletInfo.SetState(static_cast<ui32>(tablet.State));
+ tabletInfo.SetVolatileState(tablet.GetVolatileState());
+ tabletInfo.SetObjectId(tablet.ObjectId);
+ tabletInfo.SetGeneration(tablet.KnownGeneration);
+ ActorIdToProto(tablet.LockedToActor, tabletInfo.MutableLockedToActor());
+ tabletInfo.SetLockedReconnectTimeout(tablet.LockedReconnectTimeout.MilliSeconds());
+ tabletInfo.SetTabletStorageVersion(tablet.TabletStorageInfo->Version);
+ tabletInfo.SetTabletBootMode(tablet.BootMode);
+ tabletInfo.MutableResourceUsage()->CopyFrom(tablet.GetResourceValues());
+
+ TSubDomainKey objectDomain = TSubDomainKey(tabletRowset.GetValueOrDefault<Schema::Tablet::ObjectDomain>());
+ tabletInfo.MutableObjectDomain()->CopyFrom(objectDomain);
+
+ TVector<TSubDomainKey> allowedDomains = tabletRowset.GetValueOrDefault<Schema::Tablet::AllowedDomains>();
+ for (const auto& allowedDomain : allowedDomains) {
+ if (allowedDomain != objectDomain) {
+ tabletInfo.AddAllowedDomains()->CopyFrom(allowedDomain);
+ }
+ }
+
+ auto tabletChannelRowset = db.Table<Schema::TabletChannel>().Range(tabletId).Select();
+ if (!tabletChannelRowset.IsReady())
+ return false;
+
+ while (!tabletChannelRowset.EndOfSet()) {
+ ui32 channelId = tabletChannelRowset.GetValueOrDefault<Schema::TabletChannel::Channel>();
+ NKikimrHive::TTabletChannelInfo& tabletChannelInfo = *tabletInfo.AddTabletChannels();
+ tabletChannelInfo.SetStoragePool(tabletChannelRowset.GetValue<Schema::TabletChannel::StoragePool>());
+ tabletChannelInfo.MutableBinding()->CopyFrom(tabletChannelRowset.GetValueOrDefault<Schema::TabletChannel::Binding>());
+ tabletChannelInfo.SetNeedNewGroup(tabletChannelRowset.GetValueOrDefault<Schema::TabletChannel::NeedNewGroup>());
+
+ auto tabletChannelGenRowset = db.Table<Schema::TabletChannelGen>().Range(tabletId, channelId).Select();
+ if (!tabletChannelGenRowset.IsReady())
+ return false;
+
+ while (!tabletChannelGenRowset.EndOfSet()) {
+ NKikimrHive::TTabletChannelGenInfo& tabletChannelGenInfo = *tabletChannelInfo.AddHistory();
+ tabletChannelGenInfo.SetGeneration(tabletChannelGenRowset.GetValue<Schema::TabletChannelGen::Generation>());
+ tabletChannelGenInfo.SetGroup(tabletChannelGenRowset.GetValue<Schema::TabletChannelGen::Group>());
+ tabletChannelGenInfo.SetTimestamp(tabletChannelGenRowset.GetValueOrDefault<Schema::TabletChannelGen::Timestamp>());
+ tabletChannelGenInfo.SetVersion(tabletChannelGenRowset.GetValueOrDefault<Schema::TabletChannelGen::Version>());
+ if (!tabletChannelGenRowset.Next())
+ return false;
+ }
+
+ if (!tabletChannelRowset.Next())
+ return false;
+ }
+
auto tabletFollowerGroupRowset = db.Table<Schema::TabletFollowerGroup>().Range(tabletId).Select();
if (!tabletFollowerGroupRowset.IsReady())
- return false;
-
+ return false;
+
while (!tabletFollowerGroupRowset.EndOfSet()) {
NKikimrHive::TFollowerGroup& followerGroup = *tabletInfo.AddFollowerGroups();
followerGroup.SetFollowerCount(tabletFollowerGroupRowset.GetValueOrDefault<Schema::TabletFollowerGroup::FollowerCount>());
@@ -135,30 +135,30 @@ public:
followerGroup.SetRequireDifferentNodes(tabletFollowerGroupRowset.GetValueOrDefault<Schema::TabletFollowerGroup::RequireDifferentNodes>());
followerGroup.SetFollowerCountPerDataCenter(tabletFollowerGroupRowset.GetValueOrDefault<Schema::TabletFollowerGroup::FollowerCountPerDataCenter>());
if (!tabletFollowerGroupRowset.Next()) {
- return false;
- }
- }
-
- tablet.SeizedByChild = true;
- db.Table<Schema::Tablet>().Key(id).Update<Schema::Tablet::SeizedByChild>(true);
-
- if (++seizedTablets >= Request->Get()->Record.GetMaxTabletsToSeize()) {
- break;
- }
- }
- }
- return true;
- }
-
+ return false;
+ }
+ }
+
+ tablet.SeizedByChild = true;
+ db.Table<Schema::Tablet>().Key(id).Update<Schema::Tablet::SeizedByChild>(true);
+
+ if (++seizedTablets >= Request->Get()->Record.GetMaxTabletsToSeize()) {
+ break;
+ }
+ }
+ }
+ return true;
+ }
+
void Complete(const TActorContext& txc) override {
- BLOG_D("THive::TTxSeizeTablets::Complete " << Request->Get()->Record);
- txc.Send(Request->Sender, Response.Release());
- }
-};
-
-ITransaction* THive::CreateSeizeTablets(TEvHive::TEvSeizeTablets::TPtr event) {
+ BLOG_D("THive::TTxSeizeTablets::Complete " << Request->Get()->Record);
+ txc.Send(Request->Sender, Response.Release());
+ }
+};
+
+ITransaction* THive::CreateSeizeTablets(TEvHive::TEvSeizeTablets::TPtr event) {
return new TTxSeizeTablets(THolder(std::move(event.Release())), this);
-}
-
-} // NHive
-} // NKikimr
+}
+
+} // NHive
+} // NKikimr
diff --git a/ydb/core/mind/hive/tx__seize_tablets_reply.cpp b/ydb/core/mind/hive/tx__seize_tablets_reply.cpp
index bfc7fb665de..6e6db7131be 100644
--- a/ydb/core/mind/hive/tx__seize_tablets_reply.cpp
+++ b/ydb/core/mind/hive/tx__seize_tablets_reply.cpp
@@ -1,116 +1,116 @@
-#include "hive_impl.h"
-#include "hive_log.h"
-
-namespace NKikimr {
-namespace NHive {
-
-class TTxSeizeTabletsReply : public TTransactionBase<THive> {
- THolder<TEvHive::TEvSeizeTabletsReply::THandle> Request;
- TVector<TTabletId> TabletIds;
-
-public:
- TTxSeizeTabletsReply(THolder<TEvHive::TEvSeizeTabletsReply::THandle> event, THive *hive)
- : TBase(hive)
- , Request(std::move(event))
- {}
-
- TTxType GetTxType() const override { return NHive::TXTYPE_SEIZE_TABLETS_REPLY; }
-
+#include "hive_impl.h"
+#include "hive_log.h"
+
+namespace NKikimr {
+namespace NHive {
+
+class TTxSeizeTabletsReply : public TTransactionBase<THive> {
+ THolder<TEvHive::TEvSeizeTabletsReply::THandle> Request;
+ TVector<TTabletId> TabletIds;
+
+public:
+ TTxSeizeTabletsReply(THolder<TEvHive::TEvSeizeTabletsReply::THandle> event, THive *hive)
+ : TBase(hive)
+ , Request(std::move(event))
+ {}
+
+ TTxType GetTxType() const override { return NHive::TXTYPE_SEIZE_TABLETS_REPLY; }
+
bool Execute(TTransactionContext& txc, const TActorContext&) override {
- const NKikimrHive::TEvSeizeTabletsReply& request(Request->Get()->Record);
- BLOG_D("THive::TTxSeizeTabletsReply::Execute");
- NIceDb::TNiceDb db(txc.DB);
- for (const NKikimrHive::TTabletInfo& protoTabletInfo : request.GetTablets()) {
- TTabletId tabletId = protoTabletInfo.GetTabletID();
- std::pair<ui64, ui64> owner(protoTabletInfo.GetTabletOwner().GetOwner(), protoTabletInfo.GetTabletOwner().GetOwnerIdx());
+ const NKikimrHive::TEvSeizeTabletsReply& request(Request->Get()->Record);
+ BLOG_D("THive::TTxSeizeTabletsReply::Execute");
+ NIceDb::TNiceDb db(txc.DB);
+ for (const NKikimrHive::TTabletInfo& protoTabletInfo : request.GetTablets()) {
+ TTabletId tabletId = protoTabletInfo.GetTabletID();
+ std::pair<ui64, ui64> owner(protoTabletInfo.GetTabletOwner().GetOwner(), protoTabletInfo.GetTabletOwner().GetOwnerIdx());
TLeaderTabletInfo& tablet = Self->GetTablet(tabletId);
- tablet.Type = protoTabletInfo.GetTabletType();
- tablet.NodeId = 0;
- tablet.Node = nullptr;
- tablet.BecomeStopped();
- tablet.KnownGeneration = protoTabletInfo.GetGeneration();
- tablet.State = static_cast<ETabletState>(protoTabletInfo.GetState());
- tablet.Owner = owner;
- tablet.BootMode = protoTabletInfo.GetTabletBootMode();
- tablet.ObjectId = protoTabletInfo.GetObjectId();
-
- TVector<TSubDomainKey> allowedDomains;
- for (const auto& allowedDomain : protoTabletInfo.GetAllowedDomains()) {
- allowedDomains.emplace_back(allowedDomain);
- }
-
- TSubDomainKey objectDomain(protoTabletInfo.GetObjectDomain());
-
- tablet.AssignDomains(objectDomain, allowedDomains);
-
- tablet.UpdateResourceUsage(protoTabletInfo.GetResourceUsage());
- tablet.BoundChannels.clear();
- tablet.TabletStorageInfo.Reset(new TTabletStorageInfo(tablet.Id, tablet.Type));
- tablet.TabletStorageInfo->TenantPathId = tablet.GetTenant();
- tablet.TabletStorageInfo->Version = protoTabletInfo.GetTabletStorageVersion();
-
- tablet.LockedToActor = ActorIdFromProto(protoTabletInfo.GetLockedToActor());
- tablet.LockedReconnectTimeout = TDuration::MilliSeconds(protoTabletInfo.GetLockedReconnectTimeout());
-
- db.Table<Schema::Tablet>().Key(tabletId).Update(
- NIceDb::TUpdate<Schema::Tablet::Owner>(owner),
- NIceDb::TUpdate<Schema::Tablet::KnownGeneration>(protoTabletInfo.GetGeneration()),
- NIceDb::TUpdate<Schema::Tablet::TabletType>(protoTabletInfo.GetTabletType()),
- NIceDb::TUpdate<Schema::Tablet::State>(static_cast<ETabletState>(protoTabletInfo.GetState())),
+ tablet.Type = protoTabletInfo.GetTabletType();
+ tablet.NodeId = 0;
+ tablet.Node = nullptr;
+ tablet.BecomeStopped();
+ tablet.KnownGeneration = protoTabletInfo.GetGeneration();
+ tablet.State = static_cast<ETabletState>(protoTabletInfo.GetState());
+ tablet.Owner = owner;
+ tablet.BootMode = protoTabletInfo.GetTabletBootMode();
+ tablet.ObjectId = protoTabletInfo.GetObjectId();
+
+ TVector<TSubDomainKey> allowedDomains;
+ for (const auto& allowedDomain : protoTabletInfo.GetAllowedDomains()) {
+ allowedDomains.emplace_back(allowedDomain);
+ }
+
+ TSubDomainKey objectDomain(protoTabletInfo.GetObjectDomain());
+
+ tablet.AssignDomains(objectDomain, allowedDomains);
+
+ tablet.UpdateResourceUsage(protoTabletInfo.GetResourceUsage());
+ tablet.BoundChannels.clear();
+ tablet.TabletStorageInfo.Reset(new TTabletStorageInfo(tablet.Id, tablet.Type));
+ tablet.TabletStorageInfo->TenantPathId = tablet.GetTenant();
+ tablet.TabletStorageInfo->Version = protoTabletInfo.GetTabletStorageVersion();
+
+ tablet.LockedToActor = ActorIdFromProto(protoTabletInfo.GetLockedToActor());
+ tablet.LockedReconnectTimeout = TDuration::MilliSeconds(protoTabletInfo.GetLockedReconnectTimeout());
+
+ db.Table<Schema::Tablet>().Key(tabletId).Update(
+ NIceDb::TUpdate<Schema::Tablet::Owner>(owner),
+ NIceDb::TUpdate<Schema::Tablet::KnownGeneration>(protoTabletInfo.GetGeneration()),
+ NIceDb::TUpdate<Schema::Tablet::TabletType>(protoTabletInfo.GetTabletType()),
+ NIceDb::TUpdate<Schema::Tablet::State>(static_cast<ETabletState>(protoTabletInfo.GetState())),
NIceDb::TUpdate<Schema::Tablet::LeaderNode>(protoTabletInfo.GetNodeID()),
- //NIceDb::TUpdate<Schema::Tablet::Category>(),
- //NIceDb::TUpdate<Schema::Tablet::AllowedNodes>(),
- //NIceDb::TUpdate<Schema::Tablet::AllowedDataCenters>(),
- NIceDb::TUpdate<Schema::Tablet::TabletStorageVersion>(protoTabletInfo.GetTabletStorageVersion()),
- NIceDb::TUpdate<Schema::Tablet::ObjectID>(protoTabletInfo.GetObjectId()),
- //NIceDb::TUpdate<Schema::Tablet::ActorsToNotify>(),
- NIceDb::TUpdate<Schema::Tablet::AllowedDomains>(allowedDomains),
- NIceDb::TUpdate<Schema::Tablet::BootMode>(protoTabletInfo.GetTabletBootMode()),
- NIceDb::TUpdate<Schema::Tablet::LockedToActor>(ActorIdFromProto(protoTabletInfo.GetLockedToActor())),
- NIceDb::TUpdate<Schema::Tablet::LockedReconnectTimeout>(protoTabletInfo.GetLockedReconnectTimeout()),
- NIceDb::TUpdate<Schema::Tablet::ObjectDomain>(protoTabletInfo.GetObjectDomain()),
- NIceDb::TUpdate<Schema::Tablet::NeedToReleaseFromParent>(true));
-
- TVector<TTabletChannelInfo>& tabletChannels = tablet.TabletStorageInfo->Channels;
- ui16 channelId = 0;
- for (const auto& protoTabletChannel : protoTabletInfo.GetTabletChannels()) {
- db.Table<Schema::TabletChannel>().Key(tabletId, channelId).Update(
- NIceDb::TUpdate<Schema::TabletChannel::NeedNewGroup>(protoTabletChannel.GetNeedNewGroup()),
- NIceDb::TUpdate<Schema::TabletChannel::StoragePool>(protoTabletChannel.GetStoragePool()),
- NIceDb::TUpdate<Schema::TabletChannel::Binding>(protoTabletChannel.GetBinding()));
-
- tablet.BoundChannels.emplace_back();
- NKikimrStoragePool::TChannelBind& bind = tablet.BoundChannels.back();
- bind = protoTabletChannel.GetBinding();
- bind.SetStoragePoolName(protoTabletChannel.GetStoragePool());
- Self->InitDefaultChannelBind(bind);
-
- if (protoTabletChannel.GetNeedNewGroup()) {
- tablet.ChannelProfileNewGroup.set(channelId);
- }
-
- tabletChannels.emplace_back();
- tabletChannels.back().Channel = channelId;
-
- TTabletChannelInfo& channel = tablet.TabletStorageInfo->Channels[channelId];
-
- for (const auto& protoTabletChannelGen : protoTabletChannel.GetHistory()) {
- ui64 generation = protoTabletChannelGen.GetGeneration();
- ui32 groupId = protoTabletChannelGen.GetGroup();
- TInstant timestamp = TInstant::MilliSeconds(protoTabletChannelGen.GetTimestamp());
- db.Table<Schema::TabletChannelGen>().Key(tabletId, channelId, generation).Update(
- NIceDb::TUpdate<Schema::TabletChannelGen::Group>(groupId),
- NIceDb::TUpdate<Schema::TabletChannelGen::Version>(protoTabletChannelGen.GetVersion()),
- NIceDb::TUpdate<Schema::TabletChannelGen::Timestamp>(timestamp.MilliSeconds()));
-
- channel.History.emplace_back(generation, groupId, timestamp);
- }
-
- ++channelId;
- }
-
- tablet.AcquireAllocationUnits();
-
+ //NIceDb::TUpdate<Schema::Tablet::Category>(),
+ //NIceDb::TUpdate<Schema::Tablet::AllowedNodes>(),
+ //NIceDb::TUpdate<Schema::Tablet::AllowedDataCenters>(),
+ NIceDb::TUpdate<Schema::Tablet::TabletStorageVersion>(protoTabletInfo.GetTabletStorageVersion()),
+ NIceDb::TUpdate<Schema::Tablet::ObjectID>(protoTabletInfo.GetObjectId()),
+ //NIceDb::TUpdate<Schema::Tablet::ActorsToNotify>(),
+ NIceDb::TUpdate<Schema::Tablet::AllowedDomains>(allowedDomains),
+ NIceDb::TUpdate<Schema::Tablet::BootMode>(protoTabletInfo.GetTabletBootMode()),
+ NIceDb::TUpdate<Schema::Tablet::LockedToActor>(ActorIdFromProto(protoTabletInfo.GetLockedToActor())),
+ NIceDb::TUpdate<Schema::Tablet::LockedReconnectTimeout>(protoTabletInfo.GetLockedReconnectTimeout()),
+ NIceDb::TUpdate<Schema::Tablet::ObjectDomain>(protoTabletInfo.GetObjectDomain()),
+ NIceDb::TUpdate<Schema::Tablet::NeedToReleaseFromParent>(true));
+
+ TVector<TTabletChannelInfo>& tabletChannels = tablet.TabletStorageInfo->Channels;
+ ui16 channelId = 0;
+ for (const auto& protoTabletChannel : protoTabletInfo.GetTabletChannels()) {
+ db.Table<Schema::TabletChannel>().Key(tabletId, channelId).Update(
+ NIceDb::TUpdate<Schema::TabletChannel::NeedNewGroup>(protoTabletChannel.GetNeedNewGroup()),
+ NIceDb::TUpdate<Schema::TabletChannel::StoragePool>(protoTabletChannel.GetStoragePool()),
+ NIceDb::TUpdate<Schema::TabletChannel::Binding>(protoTabletChannel.GetBinding()));
+
+ tablet.BoundChannels.emplace_back();
+ NKikimrStoragePool::TChannelBind& bind = tablet.BoundChannels.back();
+ bind = protoTabletChannel.GetBinding();
+ bind.SetStoragePoolName(protoTabletChannel.GetStoragePool());
+ Self->InitDefaultChannelBind(bind);
+
+ if (protoTabletChannel.GetNeedNewGroup()) {
+ tablet.ChannelProfileNewGroup.set(channelId);
+ }
+
+ tabletChannels.emplace_back();
+ tabletChannels.back().Channel = channelId;
+
+ TTabletChannelInfo& channel = tablet.TabletStorageInfo->Channels[channelId];
+
+ for (const auto& protoTabletChannelGen : protoTabletChannel.GetHistory()) {
+ ui64 generation = protoTabletChannelGen.GetGeneration();
+ ui32 groupId = protoTabletChannelGen.GetGroup();
+ TInstant timestamp = TInstant::MilliSeconds(protoTabletChannelGen.GetTimestamp());
+ db.Table<Schema::TabletChannelGen>().Key(tabletId, channelId, generation).Update(
+ NIceDb::TUpdate<Schema::TabletChannelGen::Group>(groupId),
+ NIceDb::TUpdate<Schema::TabletChannelGen::Version>(protoTabletChannelGen.GetVersion()),
+ NIceDb::TUpdate<Schema::TabletChannelGen::Timestamp>(timestamp.MilliSeconds()));
+
+ channel.History.emplace_back(generation, groupId, timestamp);
+ }
+
+ ++channelId;
+ }
+
+ tablet.AcquireAllocationUnits();
+
for (const auto& protoFollowerGroup : protoTabletInfo.GetFollowerGroups()) {
TFollowerGroup& followerGroup = tablet.AddFollowerGroup();
followerGroup = protoFollowerGroup;
@@ -129,46 +129,46 @@ public:
NIceDb::TUpdate<Schema::TabletFollowerGroup::RequireAllDataCenters>(followerGroup.RequireAllDataCenters),
NIceDb::TUpdate<Schema::TabletFollowerGroup::RequireDifferentNodes>(followerGroup.RequireDifferentNodes),
NIceDb::TUpdate<Schema::TabletFollowerGroup::FollowerCountPerDataCenter>(followerGroup.FollowerCountPerDataCenter));
-
- for (ui32 i = 0; i < followerGroup.GetComputedFollowerCount(Self->GetDataCenters()); ++i) {
+
+ for (ui32 i = 0; i < followerGroup.GetComputedFollowerCount(Self->GetDataCenters()); ++i) {
TFollowerTabletInfo& follower = tablet.AddFollower(followerGroup);
db.Table<Schema::TabletFollowerTablet>().Key(tabletId, follower.Id).Update(
NIceDb::TUpdate<Schema::TabletFollowerTablet::GroupID>(follower.FollowerGroup.Id),
NIceDb::TUpdate<Schema::TabletFollowerTablet::FollowerNode>(0));
follower.InitTabletMetrics();
follower.BecomeStopped();
- }
- }
-
- if (Self->OwnerToTablet.emplace(owner, tabletId).second) {
- Self->ObjectToTabletMetrics[tablet.ObjectId].IncreaseCount();
- Self->TabletTypeToTabletMetrics[tablet.Type].IncreaseCount();
- }
-
- TabletIds.emplace_back(tabletId);
- }
- return true;
- }
-
+ }
+ }
+
+ if (Self->OwnerToTablet.emplace(owner, tabletId).second) {
+ Self->ObjectToTabletMetrics[tablet.ObjectId].IncreaseCount();
+ Self->TabletTypeToTabletMetrics[tablet.Type].IncreaseCount();
+ }
+
+ TabletIds.emplace_back(tabletId);
+ }
+ return true;
+ }
+
void Complete(const TActorContext& ctx) override {
- BLOG_D("THive::TTxSeizeTabletsReply::Complete");
- if (!TabletIds.empty()) {
- THolder<TEvHive::TEvReleaseTablets> request(new TEvHive::TEvReleaseTablets());
- request->Record.SetNewOwnerID(Self->TabletID());
- for (TTabletId tabletId : TabletIds) {
- request->Record.AddTabletIDs(tabletId);
- }
- ctx.Send(Request->Sender, request.Release());
- } else {
- BLOG_D("Migration complete (" << Self->MigrationProgress << " tablets migrated)");
- Self->MigrationState = NKikimrHive::EMigrationState::MIGRATION_COMPLETE;
- }
- }
-};
-
-ITransaction* THive::CreateSeizeTabletsReply(TEvHive::TEvSeizeTabletsReply::TPtr event) {
+ BLOG_D("THive::TTxSeizeTabletsReply::Complete");
+ if (!TabletIds.empty()) {
+ THolder<TEvHive::TEvReleaseTablets> request(new TEvHive::TEvReleaseTablets());
+ request->Record.SetNewOwnerID(Self->TabletID());
+ for (TTabletId tabletId : TabletIds) {
+ request->Record.AddTabletIDs(tabletId);
+ }
+ ctx.Send(Request->Sender, request.Release());
+ } else {
+ BLOG_D("Migration complete (" << Self->MigrationProgress << " tablets migrated)");
+ Self->MigrationState = NKikimrHive::EMigrationState::MIGRATION_COMPLETE;
+ }
+ }
+};
+
+ITransaction* THive::CreateSeizeTabletsReply(TEvHive::TEvSeizeTabletsReply::TPtr event) {
return new TTxSeizeTabletsReply(THolder(std::move(event.Release())), this);
-}
-
-} // NHive
-} // NKikimr
+}
+
+} // NHive
+} // NKikimr
diff --git a/ydb/core/mind/hive/tx__start_tablet.cpp b/ydb/core/mind/hive/tx__start_tablet.cpp
index b7b1422ff70..4cef3a0e069 100644
--- a/ydb/core/mind/hive/tx__start_tablet.cpp
+++ b/ydb/core/mind/hive/tx__start_tablet.cpp
@@ -1,114 +1,114 @@
-#include "hive_impl.h"
-#include "hive_log.h"
-
-namespace NKikimr {
-namespace NHive {
-
-class TTxStartTablet : public TTransactionBase<THive> {
- TFullTabletId TabletId;
+#include "hive_impl.h"
+#include "hive_log.h"
+
+namespace NKikimr {
+namespace NHive {
+
+class TTxStartTablet : public TTransactionBase<THive> {
+ TFullTabletId TabletId;
TActorId Local;
- ui64 Cookie;
+ ui64 Cookie;
bool External;
- ui32 KnownGeneration = -1;
+ ui32 KnownGeneration = -1;
-public:
+public:
TTxStartTablet(TFullTabletId tabletId, const TActorId& local, ui64 cookie, bool external, THive *hive)
- : TBase(hive)
- , TabletId(tabletId)
- , Local(local)
- , Cookie(cookie)
+ : TBase(hive)
+ , TabletId(tabletId)
+ , Local(local)
+ , Cookie(cookie)
, External(external)
- {}
-
- TTxType GetTxType() const override { return NHive::TXTYPE_START_TABLET; }
-
+ {}
+
+ TTxType GetTxType() const override { return NHive::TXTYPE_START_TABLET; }
+
bool Execute(TTransactionContext& txc, const TActorContext&) override {
- BLOG_D("THive::TTxStartTablet::Execute Tablet " << TabletId);
- TTabletInfo* tablet = Self->FindTablet(TabletId);
- if (tablet != nullptr) {
+ BLOG_D("THive::TTxStartTablet::Execute Tablet " << TabletId);
+ TTabletInfo* tablet = Self->FindTablet(TabletId);
+ if (tablet != nullptr) {
if (tablet->IsLeader()) {
TLeaderTabletInfo& leader = tablet->AsLeader();
if (leader.IsStarting() || leader.IsBootingSuppressed() && External) {
- NIceDb::TNiceDb db(txc.DB);
+ NIceDb::TNiceDb db(txc.DB);
leader.IncreaseGeneration();
KnownGeneration = leader.KnownGeneration;
db.Table<Schema::Tablet>().Key(leader.Id).Update<Schema::Tablet::KnownGeneration>(leader.KnownGeneration);
- } else {
- BLOG_W("THive::TTxStartTablet::Execute Tablet " << TabletId << " skipped generation increment");
- }
- }
- } else {
- BLOG_W("THive::TTxStartTablet::Execute Tablet " << TabletId << " wasn't found");
- }
- return true;
- }
-
+ } else {
+ BLOG_W("THive::TTxStartTablet::Execute Tablet " << TabletId << " skipped generation increment");
+ }
+ }
+ } else {
+ BLOG_W("THive::TTxStartTablet::Execute Tablet " << TabletId << " wasn't found");
+ }
+ return true;
+ }
+
void Complete(const TActorContext& ctx) override {
- TTabletInfo* tablet = Self->FindTablet(TabletId);
- if (tablet != nullptr) {
- if (tablet->LastNodeId != 0 && tablet->LastNodeId != Local.NodeId()) {
- TNodeInfo* lastNode = Self->FindNode(tablet->LastNodeId);
- if (lastNode != nullptr && lastNode->Local) {
- Self->StopTablet(lastNode->Local, tablet->GetFullTabletId());
- }
- tablet->LastNodeId = 0;
- }
+ TTabletInfo* tablet = Self->FindTablet(TabletId);
+ if (tablet != nullptr) {
+ if (tablet->LastNodeId != 0 && tablet->LastNodeId != Local.NodeId()) {
+ TNodeInfo* lastNode = Self->FindNode(tablet->LastNodeId);
+ if (lastNode != nullptr && lastNode->Local) {
+ Self->StopTablet(lastNode->Local, tablet->GetFullTabletId());
+ }
+ tablet->LastNodeId = 0;
+ }
if (tablet->IsLeader()) {
TLeaderTabletInfo& leader = tablet->AsLeader();
if (leader.IsStartingOnNode(Local.NodeId()) || leader.IsBootingSuppressed() && External) {
if (KnownGeneration == leader.KnownGeneration) {
BLOG_D("THive::TTxStartTablet::Complete, Sending TEvBootTablet(" << leader.ToString() << ")"
- << " to node " << Local.NodeId()
+ << " to node " << Local.NodeId()
<< " storage " << leader.TabletStorageInfo->ToString());
TFollowerId promotableFollowerId = leader.GetFollowerPromotableOnNode(Local.NodeId());
- ctx.Send(Local,
+ ctx.Send(Local,
new TEvLocal::TEvBootTablet(*leader.TabletStorageInfo, promotableFollowerId, KnownGeneration),
- IEventHandle::FlagTrackDelivery | IEventHandle::FlagSubscribeOnSession,
- Cookie);
- return;
- } else {
+ IEventHandle::FlagTrackDelivery | IEventHandle::FlagSubscribeOnSession,
+ Cookie);
+ return;
+ } else {
BLOG_W("THive::TTxStartTablet::Complete, ignoring outstanding TEvBootTablet(" << leader.ToString() << ") - wrong generation");
- }
- } else {
+ }
+ } else {
BLOG_W("THive::TTxStartTablet::Complete, ignoring outstanding TEvBootTablet(" << leader.ToString() << ") - wrong state or node");
- }
- } else {
+ }
+ } else {
TFollowerTabletInfo& follower = tablet->AsFollower();
if (follower.IsStartingOnNode(Local.NodeId())) {
BLOG_D("THive::TTxStartTablet::Complete, Sending TEvBootTablet(" << follower.ToString() << ")"
- << " to node " << Local.NodeId()
+ << " to node " << Local.NodeId()
<< " storage " << follower.LeaderTablet.TabletStorageInfo->ToString());
- ctx.Send(Local,
+ ctx.Send(Local,
new TEvLocal::TEvBootTablet(*follower.LeaderTablet.TabletStorageInfo, follower.Id),
- IEventHandle::FlagTrackDelivery | IEventHandle::FlagSubscribeOnSession,
- Cookie);
- return;
- } else {
+ IEventHandle::FlagTrackDelivery | IEventHandle::FlagSubscribeOnSession,
+ Cookie);
+ return;
+ } else {
BLOG_W("THive::TTxStartTablet::Complete, ignoring outstanding TEvBootTablet(" << follower.ToString() << ") - wrong state or node");
- }
- }
- // if anything wrong - attempt to restart the tablet
- if (tablet->InitiateStop()) {
- if (tablet->IsLeader()) {
- BLOG_NOTICE("THive::TTxStartTablet::Complete, jump-starting tablet " << tablet->ToString());
- tablet->AsLeader().TryToBoot();
- }
- }
- }
- if (External) {
+ }
+ }
+ // if anything wrong - attempt to restart the tablet
+ if (tablet->InitiateStop()) {
+ if (tablet->IsLeader()) {
+ BLOG_NOTICE("THive::TTxStartTablet::Complete, jump-starting tablet " << tablet->ToString());
+ tablet->AsLeader().TryToBoot();
+ }
+ }
+ }
+ if (External) {
// Always send some reply for external start requests
- BLOG_W("THive::TTxStartTablet::Complete, Aborting external boot of " << TabletId.first << "." << TabletId.second);
+ BLOG_W("THive::TTxStartTablet::Complete, Aborting external boot of " << TabletId.first << "." << TabletId.second);
ctx.Send(Local,
new TEvHive::TEvBootTabletReply(NKikimrProto::EReplyStatus::ERROR),
0,
Cookie);
}
- }
-};
-
+ }
+};
+
ITransaction* THive::CreateStartTablet(TFullTabletId tabletId, const TActorId& local, ui64 cookie, bool external) {
return new TTxStartTablet(tabletId, local, cookie, external, this);
-}
-
-} // NHive
-} // NKikimr
+}
+
+} // NHive
+} // NKikimr
diff --git a/ydb/core/mind/hive/tx__status.cpp b/ydb/core/mind/hive/tx__status.cpp
index 7b8bdd04971..e45fa5055a1 100644
--- a/ydb/core/mind/hive/tx__status.cpp
+++ b/ydb/core/mind/hive/tx__status.cpp
@@ -1,65 +1,65 @@
-#include "hive_impl.h"
-#include "hive_log.h"
-
-namespace NKikimr {
-namespace NHive {
-
-class TTxStatus : public TTransactionBase<THive> {
+#include "hive_impl.h"
+#include "hive_log.h"
+
+namespace NKikimr {
+namespace NHive {
+
+class TTxStatus : public TTransactionBase<THive> {
TActorId Local;
- NKikimrLocal::TEvStatus Record;
-
-public:
+ NKikimrLocal::TEvStatus Record;
+
+public:
TTxStatus(const TActorId& local, NKikimrLocal::TEvStatus record, THive* hive)
- : TBase(hive)
- , Local(local)
- , Record(std::move(record))
- {}
-
- TTxType GetTxType() const override { return NHive::TXTYPE_STATUS; }
-
- bool Execute(TTransactionContext& txc, const TActorContext&) override {
- TNodeId nodeId = Local.NodeId();
- BLOG_D("THive::TTxStatus(" << nodeId << ")::Execute");
- TEvLocal::TEvStatus::EStatus status = (TEvLocal::TEvStatus::EStatus)Record.GetStatus();
- TNodeInfo& node = Self->GetNode(nodeId);
- if (status == TEvLocal::TEvStatus::StatusOk && node.BecomeConnected()) {
- node.Local = Local;
- node.UpdateResourceMaximum(Record.GetResourceMaximum());
- if (Record.HasStartTime()) {
- node.StartTime = TInstant::MicroSeconds(Record.GetStartTime());
- }
- if (node.LocationAcquired) {
- NIceDb::TNiceDb db(txc.DB);
- NActorsInterconnect::TNodeLocation location;
- node.Location.Serialize(&location);
- db.Table<Schema::Node>().Key(nodeId).Update<Schema::Node::Location>(location);
- Self->UpdateRegisteredDataCenters(node.Location.GetDataCenterId());
- }
- Self->ProcessWaitQueue(); // new node connected
- } else {
- BLOG_W("THive::TTxStatus(status=" << static_cast<int>(status)
- << " node=" << TNodeInfo::EVolatileStateName(node.GetVolatileState()) << ") - killing node " << node.Id);
- Self->KillNode(node.Id, Local);
- }
- return true;
- }
-
+ : TBase(hive)
+ , Local(local)
+ , Record(std::move(record))
+ {}
+
+ TTxType GetTxType() const override { return NHive::TXTYPE_STATUS; }
+
+ bool Execute(TTransactionContext& txc, const TActorContext&) override {
+ TNodeId nodeId = Local.NodeId();
+ BLOG_D("THive::TTxStatus(" << nodeId << ")::Execute");
+ TEvLocal::TEvStatus::EStatus status = (TEvLocal::TEvStatus::EStatus)Record.GetStatus();
+ TNodeInfo& node = Self->GetNode(nodeId);
+ if (status == TEvLocal::TEvStatus::StatusOk && node.BecomeConnected()) {
+ node.Local = Local;
+ node.UpdateResourceMaximum(Record.GetResourceMaximum());
+ if (Record.HasStartTime()) {
+ node.StartTime = TInstant::MicroSeconds(Record.GetStartTime());
+ }
+ if (node.LocationAcquired) {
+ NIceDb::TNiceDb db(txc.DB);
+ NActorsInterconnect::TNodeLocation location;
+ node.Location.Serialize(&location);
+ db.Table<Schema::Node>().Key(nodeId).Update<Schema::Node::Location>(location);
+ Self->UpdateRegisteredDataCenters(node.Location.GetDataCenterId());
+ }
+ Self->ProcessWaitQueue(); // new node connected
+ } else {
+ BLOG_W("THive::TTxStatus(status=" << static_cast<int>(status)
+ << " node=" << TNodeInfo::EVolatileStateName(node.GetVolatileState()) << ") - killing node " << node.Id);
+ Self->KillNode(node.Id, Local);
+ }
+ return true;
+ }
+
void Complete(const TActorContext&) override {
- TNodeId nodeId = Local.NodeId();
- BLOG_D("THive::TTxStatus(" << nodeId << ")::Complete");
- TNodeInfo* node = Self->FindNode(nodeId);
- if (node != nullptr && node->IsAlive()) {
- if (node->Drain && Self->BalancerNodes.count(nodeId) == 0) {
- BLOG_D("THive::TTxStatus(" << nodeId << ")::Complete - continuing node drain");
- Self->StartHiveDrain(nodeId, {.Persist = true, .KeepDown = node->Down});
- }
- }
- }
-};
-
+ TNodeId nodeId = Local.NodeId();
+ BLOG_D("THive::TTxStatus(" << nodeId << ")::Complete");
+ TNodeInfo* node = Self->FindNode(nodeId);
+ if (node != nullptr && node->IsAlive()) {
+ if (node->Drain && Self->BalancerNodes.count(nodeId) == 0) {
+ BLOG_D("THive::TTxStatus(" << nodeId << ")::Complete - continuing node drain");
+ Self->StartHiveDrain(nodeId, {.Persist = true, .KeepDown = node->Down});
+ }
+ }
+ }
+};
+
ITransaction* THive::CreateStatus(const TActorId& local, NKikimrLocal::TEvStatus rec) {
- return new TTxStatus(local, std::move(rec), this);
-}
-
-} // NHive
-} // NKikimr
+ return new TTxStatus(local, std::move(rec), this);
+}
+
+} // NHive
+} // NKikimr
diff --git a/ydb/core/mind/hive/tx__stop_tablet.cpp b/ydb/core/mind/hive/tx__stop_tablet.cpp
index 9a508dd2194..c05103b258d 100644
--- a/ydb/core/mind/hive/tx__stop_tablet.cpp
+++ b/ydb/core/mind/hive/tx__stop_tablet.cpp
@@ -1,97 +1,97 @@
-#include "hive_impl.h"
-#include "hive_log.h"
-
-namespace NKikimr {
-namespace NHive {
-
-class TTxStopTablet : public TTransactionBase<THive> {
- const TTabletId TabletId;
+#include "hive_impl.h"
+#include "hive_log.h"
+
+namespace NKikimr {
+namespace NHive {
+
+class TTxStopTablet : public TTransactionBase<THive> {
+ const TTabletId TabletId;
const TActorId ActorToNotify;
- NKikimrProto::EReplyStatus Status;
-
-public:
+ NKikimrProto::EReplyStatus Status;
+
+public:
TTxStopTablet(ui64 tabletId, const TActorId &actorToNotify, THive *hive)
- : TBase(hive)
- , TabletId(tabletId)
- , ActorToNotify(actorToNotify)
- , Status(NKikimrProto::UNKNOWN)
- {}
-
- TTxType GetTxType() const override { return NHive::TXTYPE_STOP_TABLET; }
-
+ : TBase(hive)
+ , TabletId(tabletId)
+ , ActorToNotify(actorToNotify)
+ , Status(NKikimrProto::UNKNOWN)
+ {}
+
+ TTxType GetTxType() const override { return NHive::TXTYPE_STOP_TABLET; }
+
bool Execute(TTransactionContext &txc, const TActorContext&) override {
- BLOG_D("THive::TTxStopTablet::Execute Tablet: " << TabletId);
+ BLOG_D("THive::TTxStopTablet::Execute Tablet: " << TabletId);
TLeaderTabletInfo* tablet = Self->FindTablet(TabletId);
- if (tablet != nullptr) {
- ETabletState State = tablet->State;
- ETabletState NewState = State;
- NIceDb::TNiceDb db(txc.DB);
- switch (State) {
- case ETabletState::GroupAssignment:
- // switch to StoppingInGroupAssignment
- NewState = ETabletState::StoppingInGroupAssignment;
- Status = NKikimrProto::OK;
- // TODO: Notify of previous request failure
- // TODO: Set new notification receiver
- break;
- case ETabletState::Stopped:
- // notify with OK
- Status = NKikimrProto::ALREADY;
- break;
- case ETabletState::ReadyToWork:
- // Switch to Stopping
- NewState = ETabletState::Stopped;
+ if (tablet != nullptr) {
+ ETabletState State = tablet->State;
+ ETabletState NewState = State;
+ NIceDb::TNiceDb db(txc.DB);
+ switch (State) {
+ case ETabletState::GroupAssignment:
+ // switch to StoppingInGroupAssignment
+ NewState = ETabletState::StoppingInGroupAssignment;
+ Status = NKikimrProto::OK;
+ // TODO: Notify of previous request failure
+ // TODO: Set new notification receiver
+ break;
+ case ETabletState::Stopped:
+ // notify with OK
+ Status = NKikimrProto::ALREADY;
+ break;
+ case ETabletState::ReadyToWork:
+ // Switch to Stopping
+ NewState = ETabletState::Stopped;
for (TTabletInfo& follower : tablet->Followers) {
if (follower.IsAlive()) {
follower.InitiateStop();
db.Table<Schema::TabletFollowerTablet>().Key(follower.GetFullTabletId()).Update<Schema::TabletFollowerTablet::FollowerNode>(0);
- }
- }
- if (tablet->IsAlive()) {
- tablet->InitiateStop();
+ }
+ }
+ if (tablet->IsAlive()) {
+ tablet->InitiateStop();
db.Table<Schema::Tablet>().Key(tablet->Id).Update<Schema::Tablet::LeaderNode>(0);
- }
- Status = NKikimrProto::OK;
- break;
- case ETabletState::Deleting:
- Status = NKikimrProto::ERROR;
- break;
- case ETabletState::BlockStorage:
- Status = NKikimrProto::ERROR;
- break;
- case ETabletState::Stopping:
- case ETabletState::StoppingInGroupAssignment:
- case ETabletState::Unknown:
- Status = NKikimrProto::ERROR;
- break;
- }
- if (Status == NKikimrProto::OK && NewState != State) {
- db.Table<Schema::Tablet>().Key(TabletId).Update<Schema::Tablet::State>(NewState);
- tablet->State = NewState;
- }
- }
- return true;
- }
-
+ }
+ Status = NKikimrProto::OK;
+ break;
+ case ETabletState::Deleting:
+ Status = NKikimrProto::ERROR;
+ break;
+ case ETabletState::BlockStorage:
+ Status = NKikimrProto::ERROR;
+ break;
+ case ETabletState::Stopping:
+ case ETabletState::StoppingInGroupAssignment:
+ case ETabletState::Unknown:
+ Status = NKikimrProto::ERROR;
+ break;
+ }
+ if (Status == NKikimrProto::OK && NewState != State) {
+ db.Table<Schema::Tablet>().Key(TabletId).Update<Schema::Tablet::State>(NewState);
+ tablet->State = NewState;
+ }
+ }
+ return true;
+ }
+
void Complete(const TActorContext& ctx) override {
- BLOG_D("THive::TTxStopTablet::Complete TabletId: " << TabletId);
- if (Status != NKikimrProto::UNKNOWN) {
- ctx.Send(ActorToNotify, new TEvHive::TEvStopTabletResult(Status, TabletId), 0, 0);
+ BLOG_D("THive::TTxStopTablet::Complete TabletId: " << TabletId);
+ if (Status != NKikimrProto::UNKNOWN) {
+ ctx.Send(ActorToNotify, new TEvHive::TEvStopTabletResult(Status, TabletId), 0, 0);
TLeaderTabletInfo* tablet = Self->FindTablet(TabletId);
- if (tablet != nullptr) {
- Self->ReportStoppedToWhiteboard(*tablet);
- BLOG_D("Report tablet " << tablet->ToString() << " as stopped to Whiteboard");
- }
- }
- Self->ProcessBootQueue();
- }
-};
-
+ if (tablet != nullptr) {
+ Self->ReportStoppedToWhiteboard(*tablet);
+ BLOG_D("Report tablet " << tablet->ToString() << " as stopped to Whiteboard");
+ }
+ }
+ Self->ProcessBootQueue();
+ }
+};
+
ITransaction* THive::CreateStopTablet(TTabletId tabletId, const TActorId &actorToNotify) {
- return new TTxStopTablet(tabletId, actorToNotify, this);
-}
-
-} // NHive
-} // NKikimr
-
-
+ return new TTxStopTablet(tabletId, actorToNotify, this);
+}
+
+} // NHive
+} // NKikimr
+
+
diff --git a/ydb/core/mind/hive/tx__switch_drain.cpp b/ydb/core/mind/hive/tx__switch_drain.cpp
index 4646f6e7e9a..1a09d87993a 100644
--- a/ydb/core/mind/hive/tx__switch_drain.cpp
+++ b/ydb/core/mind/hive/tx__switch_drain.cpp
@@ -1,117 +1,117 @@
-#include "hive_impl.h"
-#include "hive_log.h"
-
-namespace NKikimr {
-namespace NHive {
-
-class TTxSwitchDrainOn : public TTransactionBase<THive> {
- TNodeId NodeId;
- TDrainSettings Settings;
- TActorId Initiator;
- NKikimrProto::EReplyStatus Status = NKikimrProto::UNKNOWN;
-public:
- TTxSwitchDrainOn(TNodeId nodeId, TDrainSettings settings, const TActorId& initiator, THive* hive)
- : TBase(hive)
- , NodeId(nodeId)
- , Settings(std::move(settings))
- , Initiator(initiator)
- {}
-
+#include "hive_impl.h"
+#include "hive_log.h"
+
+namespace NKikimr {
+namespace NHive {
+
+class TTxSwitchDrainOn : public TTransactionBase<THive> {
+ TNodeId NodeId;
+ TDrainSettings Settings;
+ TActorId Initiator;
+ NKikimrProto::EReplyStatus Status = NKikimrProto::UNKNOWN;
+public:
+ TTxSwitchDrainOn(TNodeId nodeId, TDrainSettings settings, const TActorId& initiator, THive* hive)
+ : TBase(hive)
+ , NodeId(nodeId)
+ , Settings(std::move(settings))
+ , Initiator(initiator)
+ {}
+
bool Execute(TTransactionContext& txc, const TActorContext&) override {
- BLOG_D("THive::TTxSwitchDrainOn::Execute Node: " << NodeId
- << " Persist: " << Settings.Persist << " KeepDown: " << Settings.KeepDown);
- NIceDb::TNiceDb db(txc.DB);
- TNodeInfo* node = Self->FindNode(NodeId);
- if (node != nullptr) {
- if (!(node->Drain) && Self->BalancerNodes.count(NodeId) != 0) {
- Status = NKikimrProto::ALREADY; // another balancer is active on the node
- } else {
- Status = NKikimrProto::OK;
- if (!node->Drain && node->Down) {
- Settings.KeepDown = true;
- }
- node->Drain = true;
- node->DrainInitiators.emplace_back(Initiator);
- if (Settings.Persist) {
- db.Table<Schema::Node>().Key(NodeId).Update<Schema::Node::Drain, Schema::Node::DrainInitiators>(node->Drain, node->DrainInitiators);
- }
- if (Settings.KeepDown) {
- node->SetDown(true);
- if (Settings.Persist) {
- db.Table<Schema::Node>().Key(NodeId).Update<Schema::Node::Down>(true);
- }
- }
- Self->StartHiveDrain(NodeId, std::move(Settings));
- }
- } else {
- Status = NKikimrProto::ERROR;
- }
- return true;
- }
-
+ BLOG_D("THive::TTxSwitchDrainOn::Execute Node: " << NodeId
+ << " Persist: " << Settings.Persist << " KeepDown: " << Settings.KeepDown);
+ NIceDb::TNiceDb db(txc.DB);
+ TNodeInfo* node = Self->FindNode(NodeId);
+ if (node != nullptr) {
+ if (!(node->Drain) && Self->BalancerNodes.count(NodeId) != 0) {
+ Status = NKikimrProto::ALREADY; // another balancer is active on the node
+ } else {
+ Status = NKikimrProto::OK;
+ if (!node->Drain && node->Down) {
+ Settings.KeepDown = true;
+ }
+ node->Drain = true;
+ node->DrainInitiators.emplace_back(Initiator);
+ if (Settings.Persist) {
+ db.Table<Schema::Node>().Key(NodeId).Update<Schema::Node::Drain, Schema::Node::DrainInitiators>(node->Drain, node->DrainInitiators);
+ }
+ if (Settings.KeepDown) {
+ node->SetDown(true);
+ if (Settings.Persist) {
+ db.Table<Schema::Node>().Key(NodeId).Update<Schema::Node::Down>(true);
+ }
+ }
+ Self->StartHiveDrain(NodeId, std::move(Settings));
+ }
+ } else {
+ Status = NKikimrProto::ERROR;
+ }
+ return true;
+ }
+
void Complete(const TActorContext&) override {
- BLOG_D("THive::TTxSwitchDrainOn::Complete NodeId: " << NodeId << " Status: " << Status);
- if (Status != NKikimrProto::OK) {
- if (Initiator) {
- Self->Send(Initiator, new TEvHive::TEvDrainNodeResult(Status));
- }
- }
- }
-};
-
-class TTxSwitchDrainOff : public TTransactionBase<THive> {
- TNodeId NodeId;
- TDrainSettings Settings;
- NKikimrProto::EReplyStatus Status;
- ui32 Movements;
- TVector<TActorId> Initiators;
-
-public:
- TTxSwitchDrainOff(TNodeId nodeId, TDrainSettings settings, NKikimrProto::EReplyStatus status, ui32 movements, THive* hive)
- : TBase(hive)
- , NodeId(nodeId)
- , Settings(std::move(settings))
- , Status(status)
- , Movements(movements)
- {}
-
+ BLOG_D("THive::TTxSwitchDrainOn::Complete NodeId: " << NodeId << " Status: " << Status);
+ if (Status != NKikimrProto::OK) {
+ if (Initiator) {
+ Self->Send(Initiator, new TEvHive::TEvDrainNodeResult(Status));
+ }
+ }
+ }
+};
+
+class TTxSwitchDrainOff : public TTransactionBase<THive> {
+ TNodeId NodeId;
+ TDrainSettings Settings;
+ NKikimrProto::EReplyStatus Status;
+ ui32 Movements;
+ TVector<TActorId> Initiators;
+
+public:
+ TTxSwitchDrainOff(TNodeId nodeId, TDrainSettings settings, NKikimrProto::EReplyStatus status, ui32 movements, THive* hive)
+ : TBase(hive)
+ , NodeId(nodeId)
+ , Settings(std::move(settings))
+ , Status(status)
+ , Movements(movements)
+ {}
+
bool Execute(TTransactionContext& txc, const TActorContext&) override {
- BLOG_D("THive::TTxSwitchDrainOff::Execute Node: " << NodeId);
- NIceDb::TNiceDb db(txc.DB);
- TNodeInfo* node = Self->FindNode(NodeId);
- if (node != nullptr) {
- Initiators = std::move(node->DrainInitiators);
- node->Drain = false;
- node->DrainInitiators.clear();
- db.Table<Schema::Node>().Key(NodeId).Update<Schema::Node::Drain, Schema::Node::DrainInitiators>(node->Drain, node->DrainInitiators);
- if (!Settings.KeepDown) {
- // node->SetDown(false); // it has already been dropped by Drain actor
- if (Settings.Persist) {
- db.Table<Schema::Node>().Key(NodeId).Update<Schema::Node::Down>(false);
- }
- }
- }
- return true;
- }
-
+ BLOG_D("THive::TTxSwitchDrainOff::Execute Node: " << NodeId);
+ NIceDb::TNiceDb db(txc.DB);
+ TNodeInfo* node = Self->FindNode(NodeId);
+ if (node != nullptr) {
+ Initiators = std::move(node->DrainInitiators);
+ node->Drain = false;
+ node->DrainInitiators.clear();
+ db.Table<Schema::Node>().Key(NodeId).Update<Schema::Node::Drain, Schema::Node::DrainInitiators>(node->Drain, node->DrainInitiators);
+ if (!Settings.KeepDown) {
+ // node->SetDown(false); // it has already been dropped by Drain actor
+ if (Settings.Persist) {
+ db.Table<Schema::Node>().Key(NodeId).Update<Schema::Node::Down>(false);
+ }
+ }
+ }
+ return true;
+ }
+
void Complete(const TActorContext&) override {
- BLOG_D("THive::TTxSwitchDrainOff::Complete NodeId: " << NodeId
- << " Status: " << NKikimrProto::EReplyStatus_Name(Status) << " Movements: " << Movements);
- for (const TActorId& initiator : Initiators) {
- Self->Send(initiator, new TEvHive::TEvDrainNodeResult(Status, Movements));
- }
- }
-};
-
-ITransaction* THive::CreateSwitchDrainOn(NHive::TNodeId nodeId, TDrainSettings settings, const TActorId& initiator) {
- return new TTxSwitchDrainOn(nodeId, std::move(settings), initiator, this);
-}
-
-ITransaction* THive::CreateSwitchDrainOff(NHive::TNodeId nodeId, TDrainSettings settings, NKikimrProto::EReplyStatus status, ui32 movements) {
- return new TTxSwitchDrainOff(nodeId, std::move(settings), status, movements, this);
-}
-
-} // NHive
-} // NKikimr
-
-
+ BLOG_D("THive::TTxSwitchDrainOff::Complete NodeId: " << NodeId
+ << " Status: " << NKikimrProto::EReplyStatus_Name(Status) << " Movements: " << Movements);
+ for (const TActorId& initiator : Initiators) {
+ Self->Send(initiator, new TEvHive::TEvDrainNodeResult(Status, Movements));
+ }
+ }
+};
+
+ITransaction* THive::CreateSwitchDrainOn(NHive::TNodeId nodeId, TDrainSettings settings, const TActorId& initiator) {
+ return new TTxSwitchDrainOn(nodeId, std::move(settings), initiator, this);
+}
+
+ITransaction* THive::CreateSwitchDrainOff(NHive::TNodeId nodeId, TDrainSettings settings, NKikimrProto::EReplyStatus status, ui32 movements) {
+ return new TTxSwitchDrainOff(nodeId, std::move(settings), status, movements, this);
+}
+
+} // NHive
+} // NKikimr
+
+
diff --git a/ydb/core/mind/hive/tx__sync_tablets.cpp b/ydb/core/mind/hive/tx__sync_tablets.cpp
index d1bac05e9af..29eb4cfba1c 100644
--- a/ydb/core/mind/hive/tx__sync_tablets.cpp
+++ b/ydb/core/mind/hive/tx__sync_tablets.cpp
@@ -1,134 +1,134 @@
-#include "hive_impl.h"
-#include "hive_log.h"
-
-namespace NKikimr {
-namespace NHive {
-
-class TTxSyncTablets : public TTransactionBase<THive> {
+#include "hive_impl.h"
+#include "hive_log.h"
+
+namespace NKikimr {
+namespace NHive {
+
+class TTxSyncTablets : public TTransactionBase<THive> {
TActorId Local;
- NKikimrLocal::TEvSyncTablets SyncTablets;
+ NKikimrLocal::TEvSyncTablets SyncTablets;
THashSet<std::pair<TTabletId, TFollowerId>> TabletsToStop;
THashSet<std::pair<TTabletId, TFollowerId>> TabletsToBoot;
-public:
+public:
TTxSyncTablets(const TActorId &local, NKikimrLocal::TEvSyncTablets& rec, THive* hive)
- : TBase(hive)
- , Local(local)
- {
- SyncTablets.Swap(&rec);
- }
-
- TTxType GetTxType() const override { return NHive::TXTYPE_SYNC_TABLETS; }
-
- bool IsSameTablet(const TTabletInfo* local, const NKikimrLocal::TEvSyncTablets_TTabletInfo& remote) const {
+ : TBase(hive)
+ , Local(local)
+ {
+ SyncTablets.Swap(&rec);
+ }
+
+ TTxType GetTxType() const override { return NHive::TXTYPE_SYNC_TABLETS; }
+
+ bool IsSameTablet(const TTabletInfo* local, const NKikimrLocal::TEvSyncTablets_TTabletInfo& remote) const {
if (local->IsFollower()) {
if (remote.GetBootMode() == NKikimrLocal::EBootMode::BOOT_MODE_FOLLOWER) {
if (local->AsFollower().Id == remote.GetFollowerId()
- && (local->IsStopped() || local->IsAliveOnLocal(Local))) {
- return true;
- }
- }
- } else {
+ && (local->IsStopped() || local->IsAliveOnLocal(Local))) {
+ return true;
+ }
+ }
+ } else {
if (remote.GetBootMode() == NKikimrLocal::EBootMode::BOOT_MODE_LEADER) {
if (remote.GetGeneration() >= local->GetLeader().KnownGeneration) {
- return true;
- }
- }
- }
- return false;
- }
-
+ return true;
+ }
+ }
+ }
+ return false;
+ }
+
bool Execute(TTransactionContext &txc, const TActorContext&) override {
- BLOG_D("THive::TTxSyncTablets(" << Local << ")::Execute");
- NIceDb::TNiceDb db(txc.DB);
- TNodeInfo& node = Self->GetNode(Local.NodeId());
- TabletsToStop.clear();
- TabletsToBoot.clear();
- for (const auto& t : node.Tablets) {
- for (TTabletInfo* tablet : t.second) {
- TabletsToStop.insert(tablet->GetFullTabletId());
- }
- }
- for (const NKikimrLocal::TEvSyncTablets_TTabletInfo& ti : SyncTablets.GetInbootTablets()) {
+ BLOG_D("THive::TTxSyncTablets(" << Local << ")::Execute");
+ NIceDb::TNiceDb db(txc.DB);
+ TNodeInfo& node = Self->GetNode(Local.NodeId());
+ TabletsToStop.clear();
+ TabletsToBoot.clear();
+ for (const auto& t : node.Tablets) {
+ for (TTabletInfo* tablet : t.second) {
+ TabletsToStop.insert(tablet->GetFullTabletId());
+ }
+ }
+ for (const NKikimrLocal::TEvSyncTablets_TTabletInfo& ti : SyncTablets.GetInbootTablets()) {
auto tabletId = std::pair<TTabletId, TFollowerId>(ti.GetTabletId(), ti.GetFollowerId());
- TTabletInfo* tablet = Self->FindTablet(tabletId);
- if (tablet) {
- if (IsSameTablet(tablet, ti)) {
+ TTabletInfo* tablet = Self->FindTablet(tabletId);
+ if (tablet) {
+ if (IsSameTablet(tablet, ti)) {
if (tablet->IsLeader()) {
tablet->GetLeader().KnownGeneration = ti.GetGeneration();
- }
- tablet->BecomeStarting(node.Id);
- BLOG_TRACE("THive::TTxSyncTablets(" << Local << ") confirmed starting tablet " << tabletId);
- TabletsToStop.erase(tabletId);
+ }
+ tablet->BecomeStarting(node.Id);
+ BLOG_TRACE("THive::TTxSyncTablets(" << Local << ") confirmed starting tablet " << tabletId);
+ TabletsToStop.erase(tabletId);
if (tablet->GetLeader().IsBootingSuppressed()) {
- tablet->InitiateStop();
+ tablet->InitiateStop();
}
- continue;
- }
- } else {
- Self->StopTablet(Local, tabletId);
- BLOG_TRACE("THive::TTxSyncTablets(" << Local << ") rejected unknown starting tablet " << tabletId);
- TabletsToStop.erase(tabletId);
- }
- }
- for (const NKikimrLocal::TEvSyncTablets_TTabletInfo& ti : SyncTablets.GetOnlineTablets()) {
+ continue;
+ }
+ } else {
+ Self->StopTablet(Local, tabletId);
+ BLOG_TRACE("THive::TTxSyncTablets(" << Local << ") rejected unknown starting tablet " << tabletId);
+ TabletsToStop.erase(tabletId);
+ }
+ }
+ for (const NKikimrLocal::TEvSyncTablets_TTabletInfo& ti : SyncTablets.GetOnlineTablets()) {
auto tabletId = std::pair<TTabletId, TFollowerId>(ti.GetTabletId(), ti.GetFollowerId());
- TTabletInfo* tablet = Self->FindTablet(tabletId);
- if (tablet) {
- if (IsSameTablet(tablet, ti)) {
+ TTabletInfo* tablet = Self->FindTablet(tabletId);
+ if (tablet) {
+ if (IsSameTablet(tablet, ti)) {
if (tablet->IsLeader()) {
tablet->GetLeader().KnownGeneration = ti.GetGeneration();
- }
- if (tablet->BecomeRunning(node.Id)) {
+ }
+ if (tablet->BecomeRunning(node.Id)) {
if (tablet->IsLeader()) {
db.Table<Schema::Tablet>().Key(tablet->GetLeader().Id).Update(NIceDb::TUpdate<Schema::Tablet::LeaderNode>(tablet->NodeId),
NIceDb::TUpdate<Schema::Tablet::KnownGeneration>(tablet->GetLeader().KnownGeneration));
- TabletsToBoot.insert(tabletId);
- } else {
+ TabletsToBoot.insert(tabletId);
+ } else {
db.Table<Schema::TabletFollowerTablet>().Key(tablet->GetFullTabletId()).Update(
NIceDb::TUpdate<Schema::TabletFollowerTablet::GroupID>(tablet->AsFollower().FollowerGroup.Id),
NIceDb::TUpdate<Schema::TabletFollowerTablet::FollowerNode>(tablet->NodeId));
- }
- }
- BLOG_TRACE("THive::TTxSyncTablets(" << Local << ") confirmed running tablet " << tabletId);
- TabletsToStop.erase(tabletId);
+ }
+ }
+ BLOG_TRACE("THive::TTxSyncTablets(" << Local << ") confirmed running tablet " << tabletId);
+ TabletsToStop.erase(tabletId);
if (tablet->GetLeader().IsBootingSuppressed()) {
- tablet->InitiateStop();
+ tablet->InitiateStop();
}
- continue;
+ continue;
} else if (ti.GetBootMode() == NKikimrLocal::EBootMode::BOOT_MODE_FOLLOWER) {
- Self->StopTablet(Local, tabletId); // the tablet is running somewhere else
- BLOG_TRACE("THive::TTxSyncTablets(" << Local << ") confirmed and stopped running tablet " << tabletId);
- TabletsToBoot.insert(tabletId);
- TabletsToStop.erase(tabletId);
- continue;
- }
- } else {
- Self->StopTablet(Local, tabletId);
- BLOG_TRACE("THive::TTxSyncTablets(" << Local << ") rejected unknown running tablet " << tabletId);
- TabletsToStop.erase(tabletId);
- }
- }
- return true;
- }
-
+ Self->StopTablet(Local, tabletId); // the tablet is running somewhere else
+ BLOG_TRACE("THive::TTxSyncTablets(" << Local << ") confirmed and stopped running tablet " << tabletId);
+ TabletsToBoot.insert(tabletId);
+ TabletsToStop.erase(tabletId);
+ continue;
+ }
+ } else {
+ Self->StopTablet(Local, tabletId);
+ BLOG_TRACE("THive::TTxSyncTablets(" << Local << ") rejected unknown running tablet " << tabletId);
+ TabletsToStop.erase(tabletId);
+ }
+ }
+ return true;
+ }
+
void Complete(const TActorContext& ctx) override {
- BLOG_D("THive::TTxSyncTablets(" << Local << ")::Complete");
+ BLOG_D("THive::TTxSyncTablets(" << Local << ")::Complete");
for (std::pair<TTabletId, TFollowerId> tabletId : TabletsToStop) {
- Self->Execute(Self->CreateRestartTablet(tabletId), ctx);
- }
+ Self->Execute(Self->CreateRestartTablet(tabletId), ctx);
+ }
for (std::pair<TTabletId, TFollowerId> tabletId : TabletsToBoot) {
- TTabletInfo* tablet = Self->FindTablet(tabletId.first, tabletId.second);
- if (tablet != nullptr) {
+ TTabletInfo* tablet = Self->FindTablet(tabletId.first, tabletId.second);
+ if (tablet != nullptr) {
tablet->GetLeader().TryToBoot(); // for followers
- }
- }
- Self->ProcessBootQueue();
- }
-};
-
+ }
+ }
+ Self->ProcessBootQueue();
+ }
+};
+
ITransaction* THive::CreateSyncTablets(const TActorId &local, NKikimrLocal::TEvSyncTablets& rec) {
- return new TTxSyncTablets(local, rec, this);
-}
-
-} // NHive
-} // NKikimr
+ return new TTxSyncTablets(local, rec, this);
+}
+
+} // NHive
+} // NKikimr
diff --git a/ydb/core/mind/hive/tx__unlock_tablet.cpp b/ydb/core/mind/hive/tx__unlock_tablet.cpp
index 86b2b1a1f21..66786b43b2a 100644
--- a/ydb/core/mind/hive/tx__unlock_tablet.cpp
+++ b/ydb/core/mind/hive/tx__unlock_tablet.cpp
@@ -1,10 +1,10 @@
-#include "hive_impl.h"
-#include "hive_log.h"
+#include "hive_impl.h"
+#include "hive_log.h"
namespace NKikimr {
-namespace NHive {
+namespace NHive {
-class TTxUnlockTabletExecution : public TTransactionBase<THive> {
+class TTxUnlockTabletExecution : public TTransactionBase<THive> {
const ui64 TabletId;
const TActorId OwnerActor;
const ui64 SeqNo;
@@ -28,8 +28,8 @@ public:
Y_VERIFY(!!Sender);
}
- TTxType GetTxType() const override { return NHive::TXTYPE_UNLOCK_TABLET_EXECUTION; }
-
+ TTxType GetTxType() const override { return NHive::TXTYPE_UNLOCK_TABLET_EXECUTION; }
+
TTxUnlockTabletExecution(ui64 tabletId, ui64 seqNo, THive* hive)
: TBase(hive)
, TabletId(tabletId)
@@ -37,8 +37,8 @@ public:
, Cookie(0)
{}
- bool Execute(TTransactionContext& txc, const TActorContext&) override {
- BLOG_D("THive::TTxUnlockTabletExecution::Execute");
+ bool Execute(TTransactionContext& txc, const TActorContext&) override {
+ BLOG_D("THive::TTxUnlockTabletExecution::Execute");
TLeaderTabletInfo* tablet = Self->FindTabletEvenInDeleting(TabletId);
if (tablet == nullptr) {
@@ -76,7 +76,7 @@ public:
}
void Complete(const TActorContext& ctx) override {
- BLOG_D("THive::TTxUnlockTabletExecution::Complete TabletId: " << TabletId
+ BLOG_D("THive::TTxUnlockTabletExecution::Complete TabletId: " << TabletId
<< " Status: " << Status << " " << StatusMessage);
if (Status == NKikimrProto::OK) {
@@ -89,7 +89,7 @@ public:
// Tablet still exists by the time transaction finished
if (!tablet->IsLockedToActor()) {
// Try to boot it if possible
- tablet->TryToBoot();
+ tablet->TryToBoot();
}
}
}
@@ -117,7 +117,7 @@ ITransaction* THive::CreateUnlockTabletExecution(ui64 tabletId, ui64 seqNo) {
return new TTxUnlockTabletExecution(tabletId, seqNo, this);
}
-void THive::ScheduleUnlockTabletExecution(TNodeInfo& node) {
+void THive::ScheduleUnlockTabletExecution(TNodeInfo& node) {
// Unlock tablets that have been locked by this node
for (TLeaderTabletInfo* tablet : node.LockedTablets) {
Y_VERIFY(FindTabletEvenInDeleting(tablet->Id) == tablet);
@@ -127,7 +127,7 @@ void THive::ScheduleUnlockTabletExecution(TNodeInfo& node) {
Y_VERIFY(tablet->PendingUnlockSeqNo != 0);
auto event = new TEvPrivate::TEvUnlockTabletReconnectTimeout(tablet->Id, tablet->PendingUnlockSeqNo);
if (tablet->LockedReconnectTimeout) {
- Schedule(tablet->LockedReconnectTimeout, event);
+ Schedule(tablet->LockedReconnectTimeout, event);
} else {
Send(SelfId(), event);
}
@@ -135,10 +135,10 @@ void THive::ScheduleUnlockTabletExecution(TNodeInfo& node) {
}
}
-void THive::Handle(TEvPrivate::TEvUnlockTabletReconnectTimeout::TPtr& ev) {
+void THive::Handle(TEvPrivate::TEvUnlockTabletReconnectTimeout::TPtr& ev) {
TTabletId tabletId = ev->Get()->TabletId;
ui64 seqNo = ev->Get()->SeqNo;
- BLOG_D("THive::Handle::TEvUnlockTabletReconnectTimeout TabletId=" << tabletId);
+ BLOG_D("THive::Handle::TEvUnlockTabletReconnectTimeout TabletId=" << tabletId);
TLeaderTabletInfo* tablet = FindTabletEvenInDeleting(tabletId);
if (tablet != nullptr && tablet->IsLockedToActor() && tablet->PendingUnlockSeqNo == seqNo) {
// We use sequence numbers to make sure unlock happens only if some
@@ -154,13 +154,13 @@ void THive::Handle(TEvPrivate::TEvUnlockTabletReconnectTimeout::TPtr& ev) {
// - reconnect timeout (execute, failure)
// tablet is not unlocked, because logically lock/reconnect
// transaction was scheduled before the timeout really happened.
- Execute(CreateUnlockTabletExecution(tabletId, seqNo));
+ Execute(CreateUnlockTabletExecution(tabletId, seqNo));
}
}
-void THive::Handle(TEvHive::TEvUnlockTabletExecution::TPtr& ev) {
- Execute(CreateUnlockTabletExecution(ev->Get()->Record, ev->Sender, ev->Cookie));
+void THive::Handle(TEvHive::TEvUnlockTabletExecution::TPtr& ev) {
+ Execute(CreateUnlockTabletExecution(ev->Get()->Record, ev->Sender, ev->Cookie));
}
-} // NHive
-} // NKikimr
+} // NHive
+} // NKikimr
diff --git a/ydb/core/mind/hive/tx__update_domain.cpp b/ydb/core/mind/hive/tx__update_domain.cpp
index b847c14da2b..65f48a0d0f2 100644
--- a/ydb/core/mind/hive/tx__update_domain.cpp
+++ b/ydb/core/mind/hive/tx__update_domain.cpp
@@ -1,40 +1,40 @@
-#include "hive_impl.h"
-#include "hive_log.h"
-
-namespace NKikimr {
-namespace NHive {
-
-class TTxUpdateDomain : public TTransactionBase<THive> {
- TSubDomainKey SubdomainKey;
-
-public:
- TTxUpdateDomain(TSubDomainKey subdomainKey, THive* hive)
- : TBase(hive)
- , SubdomainKey(subdomainKey)
- {}
-
- TTxType GetTxType() const override { return NHive::TXTYPE_UPDATE_DOMAIN; }
-
- bool Execute(TTransactionContext& txc, const TActorContext&) override {
- BLOG_D("THive::TTxUpdateDomain(" << SubdomainKey << ")::Execute");
- TDomainInfo* domain = Self->FindDomain(SubdomainKey);
- if (domain != nullptr) {
- NIceDb::TNiceDb db(txc.DB);
- db.Table<Schema::SubDomain>()
- .Key(SubdomainKey.first, SubdomainKey.second)
- .Update<Schema::SubDomain::Path, Schema::SubDomain::HiveId>(domain->Path, domain->HiveId);
- }
- return true;
- }
-
- void Complete(const TActorContext&) override {
- BLOG_D("THive::TTxUpdateDomain(" << SubdomainKey << ")::Complete");
- }
-};
-
-ITransaction* THive::CreateUpdateDomain(TSubDomainKey subdomainKey) {
- return new TTxUpdateDomain(subdomainKey, this);
-}
-
-}
-}
+#include "hive_impl.h"
+#include "hive_log.h"
+
+namespace NKikimr {
+namespace NHive {
+
+class TTxUpdateDomain : public TTransactionBase<THive> {
+ TSubDomainKey SubdomainKey;
+
+public:
+ TTxUpdateDomain(TSubDomainKey subdomainKey, THive* hive)
+ : TBase(hive)
+ , SubdomainKey(subdomainKey)
+ {}
+
+ TTxType GetTxType() const override { return NHive::TXTYPE_UPDATE_DOMAIN; }
+
+ bool Execute(TTransactionContext& txc, const TActorContext&) override {
+ BLOG_D("THive::TTxUpdateDomain(" << SubdomainKey << ")::Execute");
+ TDomainInfo* domain = Self->FindDomain(SubdomainKey);
+ if (domain != nullptr) {
+ NIceDb::TNiceDb db(txc.DB);
+ db.Table<Schema::SubDomain>()
+ .Key(SubdomainKey.first, SubdomainKey.second)
+ .Update<Schema::SubDomain::Path, Schema::SubDomain::HiveId>(domain->Path, domain->HiveId);
+ }
+ return true;
+ }
+
+ void Complete(const TActorContext&) override {
+ BLOG_D("THive::TTxUpdateDomain(" << SubdomainKey << ")::Complete");
+ }
+};
+
+ITransaction* THive::CreateUpdateDomain(TSubDomainKey subdomainKey) {
+ return new TTxUpdateDomain(subdomainKey, this);
+}
+
+}
+}
diff --git a/ydb/core/mind/hive/tx__update_tablet_groups.cpp b/ydb/core/mind/hive/tx__update_tablet_groups.cpp
index 2d9c5843d7c..2d9a11bc3b8 100644
--- a/ydb/core/mind/hive/tx__update_tablet_groups.cpp
+++ b/ydb/core/mind/hive/tx__update_tablet_groups.cpp
@@ -1,294 +1,294 @@
-#include "hive_impl.h"
-#include "hive_log.h"
-
-template <>
-inline IOutputStream& operator <<(IOutputStream& out, NKikimrHive::TEvReassignTablet::EHiveReassignReason reason) {
- return out << NKikimrHive::TEvReassignTablet::EHiveReassignReason_Name(reason);
-}
-
-namespace NKikimr {
-namespace NHive {
-
-class TTxUpdateTabletGroups : public TTransactionBase<THive> {
- TTabletId TabletId;
- TVector<NKikimrBlobStorage::TEvControllerSelectGroupsResult::TGroupParameters> Groups;
- ETabletState NewTabletState = ETabletState::GroupAssignment;
- bool NeedToBlockStorage = false;
- bool Changed = false;
- bool Ignored = false;
- TCompleteNotifications Notifications;
-
-public:
- TTxUpdateTabletGroups(TTabletId tabletId, TVector<NKikimrBlobStorage::TEvControllerSelectGroupsResult::TGroupParameters> groups, THive *hive)
- : TBase(hive)
- , TabletId(tabletId)
- , Groups(std::move(groups))
- {}
-
- TTxType GetTxType() const override { return NHive::TXTYPE_UPDATE_TABLET_GROUPS; }
-
+#include "hive_impl.h"
+#include "hive_log.h"
+
+template <>
+inline IOutputStream& operator <<(IOutputStream& out, NKikimrHive::TEvReassignTablet::EHiveReassignReason reason) {
+ return out << NKikimrHive::TEvReassignTablet::EHiveReassignReason_Name(reason);
+}
+
+namespace NKikimr {
+namespace NHive {
+
+class TTxUpdateTabletGroups : public TTransactionBase<THive> {
+ TTabletId TabletId;
+ TVector<NKikimrBlobStorage::TEvControllerSelectGroupsResult::TGroupParameters> Groups;
+ ETabletState NewTabletState = ETabletState::GroupAssignment;
+ bool NeedToBlockStorage = false;
+ bool Changed = false;
+ bool Ignored = false;
+ TCompleteNotifications Notifications;
+
+public:
+ TTxUpdateTabletGroups(TTabletId tabletId, TVector<NKikimrBlobStorage::TEvControllerSelectGroupsResult::TGroupParameters> groups, THive *hive)
+ : TBase(hive)
+ , TabletId(tabletId)
+ , Groups(std::move(groups))
+ {}
+
+ TTxType GetTxType() const override { return NHive::TXTYPE_UPDATE_TABLET_GROUPS; }
+
bool Execute(TTransactionContext &txc, const TActorContext& ctx) override {
- TStringBuilder tabletBootState;
-
+ TStringBuilder tabletBootState;
+
TLeaderTabletInfo* tablet = Self->FindTablet(TabletId);
- if (!tablet) {
- BLOG_W("THive::TTxUpdateTabletGroups:: tablet " << TabletId << " wasn't found");
- Ignored = true;
- return true;
+ if (!tablet) {
+ BLOG_W("THive::TTxUpdateTabletGroups:: tablet " << TabletId << " wasn't found");
+ Ignored = true;
+ return true;
}
- BLOG_D("THive::TTxUpdateTabletGroups::Execute{" << (ui64)this << "}("
- << tablet->Id << "," << tablet->ChannelProfileReassignReason << "," << Groups << ")");
+ BLOG_D("THive::TTxUpdateTabletGroups::Execute{" << (ui64)this << "}("
+ << tablet->Id << "," << tablet->ChannelProfileReassignReason << "," << Groups << ")");
- Y_VERIFY(tablet->TabletStorageInfo);
+ Y_VERIFY(tablet->TabletStorageInfo);
- if (tablet->ChannelProfileNewGroup.count() != Groups.size() && !Groups.empty()) {
- BLOG_W("THive::TTxUpdateTabletGroups::Execute{" << (ui64)this << "}: tablet "
- << tablet->Id
- << " ChannelProfileNewGroup has incorrect size");
- Ignored = true;
- return true;
+ if (tablet->ChannelProfileNewGroup.count() != Groups.size() && !Groups.empty()) {
+ BLOG_W("THive::TTxUpdateTabletGroups::Execute{" << (ui64)this << "}: tablet "
+ << tablet->Id
+ << " ChannelProfileNewGroup has incorrect size");
+ Ignored = true;
+ return true;
}
- if (!tablet->ChannelProfileNewGroup.any()) {
- BLOG_W("THive::TTxUpdateTabletGroups::Execute{" << (ui64)this << "}: tablet "
- << tablet->Id
- << " ChannelProfileNewGroup is empty");
- Ignored = true;
- return true;
- }
-
- TIntrusivePtr<TTabletStorageInfo>& tabletStorageInfo(tablet->TabletStorageInfo);
- ui32 channels = tablet->GetChannelCount();
-
- if (tablet->ChannelProfileReassignReason == NKikimrHive::TEvReassignTablet::HIVE_REASSIGN_REASON_SPACE) {
- TInstant lastChangeTimestamp;
-
- for (ui32 channelId = 0; channelId < channels; ++channelId) {
- if (tablet->ChannelProfileNewGroup.test(channelId)) {
- // searching for last change of this channel
- if (tabletStorageInfo && tabletStorageInfo->Channels.size() > channelId
- && tabletStorageInfo->Channels[channelId].History.size() > 1) {
- TTabletChannelInfo::THistoryEntry& lastHistory = tabletStorageInfo->Channels[channelId].History.back();
- lastChangeTimestamp = std::max(lastChangeTimestamp, lastHistory.Timestamp);
- }
- }
- }
-
- TDuration timeSinceLastReassign = ctx.Now() - lastChangeTimestamp;
- if (lastChangeTimestamp && Self->GetMinPeriodBetweenReassign() && timeSinceLastReassign < Self->GetMinPeriodBetweenReassign()) {
- BLOG_W("THive::TTxUpdateTabletGroups::Execute{" << (ui64)this << "}: tablet "
- << tablet->Id
- << " SpaceReassign was too soon - ignored");
- NewTabletState = ETabletState::ReadyToWork;
- return true;
- }
+ if (!tablet->ChannelProfileNewGroup.any()) {
+ BLOG_W("THive::TTxUpdateTabletGroups::Execute{" << (ui64)this << "}: tablet "
+ << tablet->Id
+ << " ChannelProfileNewGroup is empty");
+ Ignored = true;
+ return true;
}
- NIceDb::TNiceDb db(txc.DB);
-
- // updating tablet channels
- TVector<TTabletChannelInfo>& tabletChannels = tablet->TabletStorageInfo->Channels;
- ui32 orderNumber = 0;
- for (ui32 channelId = 0; channelId < channels; ++channelId) {
- if (!tablet->ChannelProfileNewGroup.test(channelId)) {
- // we are skipping this channel because we haven't asked for it
- continue;
- }
-
- const NKikimrBlobStorage::TEvControllerSelectGroupsResult::TGroupParameters* group;
-
- if (Groups.size() > orderNumber) {
- group = &Groups[orderNumber];
- } else {
- group = tablet->FindFreeAllocationUnit(channelId);
- if (group == nullptr) {
- BLOG_ERROR("THive::TTxUpdateTabletGroups::Execute{" << (ui64)this << "}: tablet "
- << tablet->Id
- << " could not find a group for channel " << channelId
- << " pool " << tablet->GetChannelStoragePoolName(channelId));
- if (tabletBootState.empty()) {
- tabletBootState << "Couldn't find a group for channel: ";
- tabletBootState << channelId;
- } else {
- tabletBootState << ", ";
- tabletBootState << channelId;
- }
- ++orderNumber;
- continue;
- } else {
- BLOG_D("THive::TTxUpdateTabletGroups::Execute{" << (ui64)this << "}: tablet "
- << tablet->Id
- << " channel "
- << channelId
- << " assigned to group "
- << group->GetGroupID());
- }
- }
-
- TTabletChannelInfo* channel;
-
+ TIntrusivePtr<TTabletStorageInfo>& tabletStorageInfo(tablet->TabletStorageInfo);
+ ui32 channels = tablet->GetChannelCount();
+
+ if (tablet->ChannelProfileReassignReason == NKikimrHive::TEvReassignTablet::HIVE_REASSIGN_REASON_SPACE) {
+ TInstant lastChangeTimestamp;
+
+ for (ui32 channelId = 0; channelId < channels; ++channelId) {
+ if (tablet->ChannelProfileNewGroup.test(channelId)) {
+ // searching for last change of this channel
+ if (tabletStorageInfo && tabletStorageInfo->Channels.size() > channelId
+ && tabletStorageInfo->Channels[channelId].History.size() > 1) {
+ TTabletChannelInfo::THistoryEntry& lastHistory = tabletStorageInfo->Channels[channelId].History.back();
+ lastChangeTimestamp = std::max(lastChangeTimestamp, lastHistory.Timestamp);
+ }
+ }
+ }
+
+ TDuration timeSinceLastReassign = ctx.Now() - lastChangeTimestamp;
+ if (lastChangeTimestamp && Self->GetMinPeriodBetweenReassign() && timeSinceLastReassign < Self->GetMinPeriodBetweenReassign()) {
+ BLOG_W("THive::TTxUpdateTabletGroups::Execute{" << (ui64)this << "}: tablet "
+ << tablet->Id
+ << " SpaceReassign was too soon - ignored");
+ NewTabletState = ETabletState::ReadyToWork;
+ return true;
+ }
+ }
+
+ NIceDb::TNiceDb db(txc.DB);
+
+ // updating tablet channels
+ TVector<TTabletChannelInfo>& tabletChannels = tablet->TabletStorageInfo->Channels;
+ ui32 orderNumber = 0;
+ for (ui32 channelId = 0; channelId < channels; ++channelId) {
+ if (!tablet->ChannelProfileNewGroup.test(channelId)) {
+ // we are skipping this channel because we haven't asked for it
+ continue;
+ }
+
+ const NKikimrBlobStorage::TEvControllerSelectGroupsResult::TGroupParameters* group;
+
+ if (Groups.size() > orderNumber) {
+ group = &Groups[orderNumber];
+ } else {
+ group = tablet->FindFreeAllocationUnit(channelId);
+ if (group == nullptr) {
+ BLOG_ERROR("THive::TTxUpdateTabletGroups::Execute{" << (ui64)this << "}: tablet "
+ << tablet->Id
+ << " could not find a group for channel " << channelId
+ << " pool " << tablet->GetChannelStoragePoolName(channelId));
+ if (tabletBootState.empty()) {
+ tabletBootState << "Couldn't find a group for channel: ";
+ tabletBootState << channelId;
+ } else {
+ tabletBootState << ", ";
+ tabletBootState << channelId;
+ }
+ ++orderNumber;
+ continue;
+ } else {
+ BLOG_D("THive::TTxUpdateTabletGroups::Execute{" << (ui64)this << "}: tablet "
+ << tablet->Id
+ << " channel "
+ << channelId
+ << " assigned to group "
+ << group->GetGroupID());
+ }
+ }
+
+ TTabletChannelInfo* channel;
+
if (channelId < tabletChannels.size()) {
- channel = &tabletChannels[channelId];
- Y_VERIFY(channel->Channel == channelId);
- if (!tablet->ReleaseAllocationUnit(channelId)) {
- BLOG_ERROR("Failed to release AU for tablet " << tablet->Id << " channel " << channelId);
- }
- } else {
- // increasing number of tablet channels
- tabletChannels.emplace_back();
- channel = &tabletChannels.back();
- channel->Channel = channelId;
- }
-
- if (group->HasStoragePoolName()) {
- channel->StoragePool = group->GetStoragePoolName();
- } else if (group->HasErasureSpecies()) {
- channel->Type = TBlobStorageGroupType(static_cast<TErasureType::EErasureSpecies>(group->GetErasureSpecies()));
- } else {
- Y_VERIFY(channelId < tablet->BoundChannels.size());
- auto& boundChannel = tablet->BoundChannels[channelId];
- channel->StoragePool = boundChannel.GetStoragePoolName();
- }
-
- db.Table<Schema::TabletChannel>().Key(tablet->Id, channelId).Update<Schema::TabletChannel::NeedNewGroup>(false);
-
- ui32 fromGeneration = channel->History.empty() ? 0 : (tablet->KnownGeneration + 1);
- TInstant timestamp = ctx.Now();
- db.Table<Schema::TabletChannelGen>().Key(tablet->Id, channelId, fromGeneration).Update(
- NIceDb::TUpdate<Schema::TabletChannelGen::Group>(group->GetGroupID()),
- NIceDb::TUpdate<Schema::TabletChannelGen::Version>(tabletStorageInfo->Version),
- NIceDb::TUpdate<Schema::TabletChannelGen::Timestamp>(timestamp.MilliSeconds()));
- if (!channel->History.empty() && fromGeneration == channel->History.back().FromGeneration) {
- channel->History.back().GroupID = group->GetGroupID(); // we overwrite history item when generation is the same as previous one (so the tablet didn't run yet)
- channel->History.back().Timestamp = timestamp;
- } else {
- channel->History.emplace_back(fromGeneration, group->GetGroupID(), timestamp);
- }
- if (channel->History.size() > 1) {
- // now we block storage for every change of a group's history
- NeedToBlockStorage = true;
- }
- Changed = true;
-
- if (!tablet->AcquireAllocationUnit(channelId)) {
- BLOG_ERROR("Failed to aquire AU for tablet " << tablet->Id << " channel " << channelId);
- }
- tablet->ChannelProfileNewGroup.reset(channelId);
-
- ++orderNumber;
- }
-
- bool hasEmptyChannel = false;
- for (ui32 channelId = 0; channelId < channels; ++channelId) {
- if (tabletStorageInfo->Channels.size() <= channelId || tabletStorageInfo->Channels[channelId].History.empty()) {
- hasEmptyChannel = true;
- break;
- }
- }
-
- if (Changed && (tablet->ChannelProfileNewGroup.none() || !hasEmptyChannel)) {
- ++tabletStorageInfo->Version;
- db.Table<Schema::Tablet>().Key(tablet->Id).Update<Schema::Tablet::TabletStorageVersion>(tabletStorageInfo->Version);
-
- if (tablet->ChannelProfileNewGroup.any()) {
- BLOG_W("THive::TTxUpdateTabletGroups::Execute{" << (ui64)this << "}: tablet "
- << tablet->Id
- << " was partially changed");
- }
-
- for (ui32 channelId = 0; channelId < channels; ++channelId) {
- if (tablet->ChannelProfileNewGroup.test(channelId)) {
- BLOG_W("THive::TTxUpdateTabletGroups::Execute{" << (ui64)this << "}: tablet " << tablet->Id
- << " skipped channel " << channelId);
- db.Table<Schema::TabletChannel>().Key(tablet->Id, channelId).Update<Schema::TabletChannel::NeedNewGroup>(false);
- tablet->ChannelProfileNewGroup.reset(channelId);
- }
- }
-
- if (NeedToBlockStorage) {
- NewTabletState = ETabletState::BlockStorage;
- } else {
- NewTabletState = ETabletState::ReadyToWork;
- }
-
- if (tablet->IsBootingSuppressed()) {
- // Tablet will never boot, so will notify about creation right after commit
+ channel = &tabletChannels[channelId];
+ Y_VERIFY(channel->Channel == channelId);
+ if (!tablet->ReleaseAllocationUnit(channelId)) {
+ BLOG_ERROR("Failed to release AU for tablet " << tablet->Id << " channel " << channelId);
+ }
+ } else {
+ // increasing number of tablet channels
+ tabletChannels.emplace_back();
+ channel = &tabletChannels.back();
+ channel->Channel = channelId;
+ }
+
+ if (group->HasStoragePoolName()) {
+ channel->StoragePool = group->GetStoragePoolName();
+ } else if (group->HasErasureSpecies()) {
+ channel->Type = TBlobStorageGroupType(static_cast<TErasureType::EErasureSpecies>(group->GetErasureSpecies()));
+ } else {
+ Y_VERIFY(channelId < tablet->BoundChannels.size());
+ auto& boundChannel = tablet->BoundChannels[channelId];
+ channel->StoragePool = boundChannel.GetStoragePoolName();
+ }
+
+ db.Table<Schema::TabletChannel>().Key(tablet->Id, channelId).Update<Schema::TabletChannel::NeedNewGroup>(false);
+
+ ui32 fromGeneration = channel->History.empty() ? 0 : (tablet->KnownGeneration + 1);
+ TInstant timestamp = ctx.Now();
+ db.Table<Schema::TabletChannelGen>().Key(tablet->Id, channelId, fromGeneration).Update(
+ NIceDb::TUpdate<Schema::TabletChannelGen::Group>(group->GetGroupID()),
+ NIceDb::TUpdate<Schema::TabletChannelGen::Version>(tabletStorageInfo->Version),
+ NIceDb::TUpdate<Schema::TabletChannelGen::Timestamp>(timestamp.MilliSeconds()));
+ if (!channel->History.empty() && fromGeneration == channel->History.back().FromGeneration) {
+ channel->History.back().GroupID = group->GetGroupID(); // we overwrite history item when generation is the same as previous one (so the tablet didn't run yet)
+ channel->History.back().Timestamp = timestamp;
+ } else {
+ channel->History.emplace_back(fromGeneration, group->GetGroupID(), timestamp);
+ }
+ if (channel->History.size() > 1) {
+ // now we block storage for every change of a group's history
+ NeedToBlockStorage = true;
+ }
+ Changed = true;
+
+ if (!tablet->AcquireAllocationUnit(channelId)) {
+ BLOG_ERROR("Failed to aquire AU for tablet " << tablet->Id << " channel " << channelId);
+ }
+ tablet->ChannelProfileNewGroup.reset(channelId);
+
+ ++orderNumber;
+ }
+
+ bool hasEmptyChannel = false;
+ for (ui32 channelId = 0; channelId < channels; ++channelId) {
+ if (tabletStorageInfo->Channels.size() <= channelId || tabletStorageInfo->Channels[channelId].History.empty()) {
+ hasEmptyChannel = true;
+ break;
+ }
+ }
+
+ if (Changed && (tablet->ChannelProfileNewGroup.none() || !hasEmptyChannel)) {
+ ++tabletStorageInfo->Version;
+ db.Table<Schema::Tablet>().Key(tablet->Id).Update<Schema::Tablet::TabletStorageVersion>(tabletStorageInfo->Version);
+
+ if (tablet->ChannelProfileNewGroup.any()) {
+ BLOG_W("THive::TTxUpdateTabletGroups::Execute{" << (ui64)this << "}: tablet "
+ << tablet->Id
+ << " was partially changed");
+ }
+
+ for (ui32 channelId = 0; channelId < channels; ++channelId) {
+ if (tablet->ChannelProfileNewGroup.test(channelId)) {
+ BLOG_W("THive::TTxUpdateTabletGroups::Execute{" << (ui64)this << "}: tablet " << tablet->Id
+ << " skipped channel " << channelId);
+ db.Table<Schema::TabletChannel>().Key(tablet->Id, channelId).Update<Schema::TabletChannel::NeedNewGroup>(false);
+ tablet->ChannelProfileNewGroup.reset(channelId);
+ }
+ }
+
+ if (NeedToBlockStorage) {
+ NewTabletState = ETabletState::BlockStorage;
+ } else {
+ NewTabletState = ETabletState::ReadyToWork;
+ }
+
+ if (tablet->IsBootingSuppressed()) {
+ // Tablet will never boot, so will notify about creation right after commit
for (const TActorId& actor : tablet->ActorsToNotify) {
- Notifications.Send(actor, new TEvHive::TEvTabletCreationResult(NKikimrProto::OK, TabletId));
- }
- tablet->ActorsToNotify.clear();
- db.Table<Schema::Tablet>().Key(TabletId).UpdateToNull<Schema::Tablet::ActorsToNotify>();
- }
+ Notifications.Send(actor, new TEvHive::TEvTabletCreationResult(NKikimrProto::OK, TabletId));
+ }
+ tablet->ActorsToNotify.clear();
+ db.Table<Schema::Tablet>().Key(TabletId).UpdateToNull<Schema::Tablet::ActorsToNotify>();
+ }
} else {
- BLOG_W("THive::TTxUpdateTabletGroups::Execute{" << (ui64)this << "}: tablet "
- << tablet->Id
- << " wasn't changed anything");
- if (hasEmptyChannel) {
- // we can't continue with partial/unsuccessfull reassign on 0 generation
- NewTabletState = ETabletState::GroupAssignment;
- } else {
- // we will continue to boot tablet even with unsuccessfull reassign
- for (ui32 channelId = 0; channelId < channels; ++channelId) {
- if (tablet->ChannelProfileNewGroup.test(channelId)) {
- BLOG_W("THive::TTxUpdateTabletGroups::Execute{" << (ui64)this << "}: tablet " << tablet->Id
- << " skipped channel " << channelId);
- db.Table<Schema::TabletChannel>().Key(tablet->Id, channelId).Update<Schema::TabletChannel::NeedNewGroup>(false);
- tablet->ChannelProfileNewGroup.reset(channelId);
- }
- }
- NewTabletState = ETabletState::ReadyToWork;
- }
+ BLOG_W("THive::TTxUpdateTabletGroups::Execute{" << (ui64)this << "}: tablet "
+ << tablet->Id
+ << " wasn't changed anything");
+ if (hasEmptyChannel) {
+ // we can't continue with partial/unsuccessfull reassign on 0 generation
+ NewTabletState = ETabletState::GroupAssignment;
+ } else {
+ // we will continue to boot tablet even with unsuccessfull reassign
+ for (ui32 channelId = 0; channelId < channels; ++channelId) {
+ if (tablet->ChannelProfileNewGroup.test(channelId)) {
+ BLOG_W("THive::TTxUpdateTabletGroups::Execute{" << (ui64)this << "}: tablet " << tablet->Id
+ << " skipped channel " << channelId);
+ db.Table<Schema::TabletChannel>().Key(tablet->Id, channelId).Update<Schema::TabletChannel::NeedNewGroup>(false);
+ tablet->ChannelProfileNewGroup.reset(channelId);
+ }
+ }
+ NewTabletState = ETabletState::ReadyToWork;
+ }
}
- db.Table<Schema::Tablet>().Key(tablet->Id).Update<Schema::Tablet::State>(NewTabletState);
-
- if (!tabletBootState.empty()) {
- tablet->BootState = tabletBootState;
- }
-
- return true;
- }
-
+ db.Table<Schema::Tablet>().Key(tablet->Id).Update<Schema::Tablet::State>(NewTabletState);
+
+ if (!tabletBootState.empty()) {
+ tablet->BootState = tabletBootState;
+ }
+
+ return true;
+ }
+
void Complete(const TActorContext& ctx) override {
- if (Ignored) {
- BLOG_NOTICE("THive::TTxUpdateTabletGroups{" << (ui64)this << "}(" << TabletId << ")::Complete"
- " - Ignored transaction");
- } else {
- BLOG_D("THive::TTxUpdateTabletGroups{" << (ui64)this << "}(" << TabletId << ")::Complete");
+ if (Ignored) {
+ BLOG_NOTICE("THive::TTxUpdateTabletGroups{" << (ui64)this << "}(" << TabletId << ")::Complete"
+ " - Ignored transaction");
+ } else {
+ BLOG_D("THive::TTxUpdateTabletGroups{" << (ui64)this << "}(" << TabletId << ")::Complete");
TLeaderTabletInfo* tablet = Self->FindTablet(TabletId);
- if (tablet != nullptr) {
- tablet->State = NewTabletState;
- if (Changed) {
- tablet->NotifyStorageInfo(ctx);
- Notifications.Send(ctx);
- if (tablet->IsReadyToBlockStorage()) {
- if (!tablet->InitiateBlockStorage()) {
- BLOG_W("THive::TTxUpdateTabletGroups{" << (ui64)this << "}(" << TabletId << ")::Complete"
- " - InitiateBlockStorage was not successfull");
- }
- } else if (tablet->IsReadyToWork()) {
- if (!tablet->InitiateStop()) {
- BLOG_W("THive::TTxUpdateTabletGroups{" << (ui64)this << "}(" << TabletId << ")::Complete"
- " - InitiateStop was not successfull");
- }
- } else if (tablet->IsBootingSuppressed()) {
- // Use best effort to kill currently running tablet
- ctx.Register(CreateTabletKiller(TabletId, /* nodeId */ 0, tablet->KnownGeneration));
- }
- }
- if (!tablet->TryToBoot()) {
- BLOG_NOTICE("THive::TTxUpdateTabletGroups{" << (ui64)this << "}(" << TabletId << ")::Complete"
- " - TryToBoot was not successfull");
- }
+ if (tablet != nullptr) {
+ tablet->State = NewTabletState;
+ if (Changed) {
+ tablet->NotifyStorageInfo(ctx);
+ Notifications.Send(ctx);
+ if (tablet->IsReadyToBlockStorage()) {
+ if (!tablet->InitiateBlockStorage()) {
+ BLOG_W("THive::TTxUpdateTabletGroups{" << (ui64)this << "}(" << TabletId << ")::Complete"
+ " - InitiateBlockStorage was not successfull");
+ }
+ } else if (tablet->IsReadyToWork()) {
+ if (!tablet->InitiateStop()) {
+ BLOG_W("THive::TTxUpdateTabletGroups{" << (ui64)this << "}(" << TabletId << ")::Complete"
+ " - InitiateStop was not successfull");
+ }
+ } else if (tablet->IsBootingSuppressed()) {
+ // Use best effort to kill currently running tablet
+ ctx.Register(CreateTabletKiller(TabletId, /* nodeId */ 0, tablet->KnownGeneration));
+ }
+ }
+ if (!tablet->TryToBoot()) {
+ BLOG_NOTICE("THive::TTxUpdateTabletGroups{" << (ui64)this << "}(" << TabletId << ")::Complete"
+ " - TryToBoot was not successfull");
+ }
}
- Self->ProcessBootQueue();
- }
- }
-};
-
-ITransaction* THive::CreateUpdateTabletGroups(TTabletId tabletId, TVector<NKikimrBlobStorage::TEvControllerSelectGroupsResult::TGroupParameters> groups) {
- return new TTxUpdateTabletGroups(tabletId, std::move(groups), this);
+ Self->ProcessBootQueue();
+ }
+ }
+};
+
+ITransaction* THive::CreateUpdateTabletGroups(TTabletId tabletId, TVector<NKikimrBlobStorage::TEvControllerSelectGroupsResult::TGroupParameters> groups) {
+ return new TTxUpdateTabletGroups(tabletId, std::move(groups), this);
}
-} // NHive
-} // NKikimr
+} // NHive
+} // NKikimr
diff --git a/ydb/core/mind/hive/tx__update_tablet_metrics.cpp b/ydb/core/mind/hive/tx__update_tablet_metrics.cpp
index cc894637b28..7e6150ec9a8 100644
--- a/ydb/core/mind/hive/tx__update_tablet_metrics.cpp
+++ b/ydb/core/mind/hive/tx__update_tablet_metrics.cpp
@@ -1,82 +1,82 @@
-#include "hive_impl.h"
-#include "hive_log.h"
-
-namespace NKikimr {
-namespace NHive {
-
-class TTxUpdateTabletMetrics : public TTransactionBase<THive> {
- TEvHive::TEvTabletMetrics::TPtr Event;
- TAutoPtr<TEvLocal::TEvTabletMetricsAck> Reply;
-public:
- TTxUpdateTabletMetrics(TEvHive::TEvTabletMetrics::TPtr& ev, THive* hive)
- : TBase(hive)
- , Event(ev)
- {}
-
- TTxType GetTxType() const override { return NHive::TXTYPE_UPDATE_TABLET_METRIC; }
-
+#include "hive_impl.h"
+#include "hive_log.h"
+
+namespace NKikimr {
+namespace NHive {
+
+class TTxUpdateTabletMetrics : public TTransactionBase<THive> {
+ TEvHive::TEvTabletMetrics::TPtr Event;
+ TAutoPtr<TEvLocal::TEvTabletMetricsAck> Reply;
+public:
+ TTxUpdateTabletMetrics(TEvHive::TEvTabletMetrics::TPtr& ev, THive* hive)
+ : TBase(hive)
+ , Event(ev)
+ {}
+
+ TTxType GetTxType() const override { return NHive::TXTYPE_UPDATE_TABLET_METRIC; }
+
bool Execute(TTransactionContext &txc, const TActorContext&) override {
- TInstant now = TInstant::Now();
- Reply = new TEvLocal::TEvTabletMetricsAck;
- auto& record = Event->Get()->Record;
- TNodeId nodeId = Event->Sender.NodeId();
- NIceDb::TNiceDb db(txc.DB);
- for (const auto& metrics : record.GetTabletMetrics()) {
- TTabletId tabletId = metrics.GetTabletID();
+ TInstant now = TInstant::Now();
+ Reply = new TEvLocal::TEvTabletMetricsAck;
+ auto& record = Event->Get()->Record;
+ TNodeId nodeId = Event->Sender.NodeId();
+ NIceDb::TNiceDb db(txc.DB);
+ for (const auto& metrics : record.GetTabletMetrics()) {
+ TTabletId tabletId = metrics.GetTabletID();
TFollowerId followerId = metrics.GetFollowerID();
- //BLOG_D("THive::TTxUpdateTabletMetrics::Execute Tablet: " << tabletId);
+ //BLOG_D("THive::TTxUpdateTabletMetrics::Execute Tablet: " << tabletId);
TTabletInfo* tablet = Self->FindTablet(tabletId, followerId);
- if (tablet != nullptr && metrics.HasResourceUsage()) {
- tablet->UpdateResourceUsage(metrics.GetResourceUsage());
- const NKikimrTabletBase::TMetrics& metrics(tablet->GetResourceValues());
-
+ if (tablet != nullptr && metrics.HasResourceUsage()) {
+ tablet->UpdateResourceUsage(metrics.GetResourceUsage());
+ const NKikimrTabletBase::TMetrics& metrics(tablet->GetResourceValues());
+
db.Table<Schema::Metrics>().Key(tabletId, followerId).Update<Schema::Metrics::ProtoMetrics>(metrics);
-
+
db.Table<Schema::Metrics>().Key(tabletId, followerId).Update<Schema::Metrics::MaximumCPU>(tablet->GetResourceMetricsAggregates().MaximumCPU);
db.Table<Schema::Metrics>().Key(tabletId, followerId).Update<Schema::Metrics::MaximumMemory>(tablet->GetResourceMetricsAggregates().MaximumMemory);
db.Table<Schema::Metrics>().Key(tabletId, followerId).Update<Schema::Metrics::MaximumNetwork>(tablet->GetResourceMetricsAggregates().MaximumNetwork);
-
- tablet->Statistics.SetLastAliveTimestamp(now.MilliSeconds());
- tablet->ActualizeTabletStatistics(now);
-
+
+ tablet->Statistics.SetLastAliveTimestamp(now.MilliSeconds());
+ tablet->ActualizeTabletStatistics(now);
+
if (tablet->IsLeader()) {
- db.Table<Schema::Tablet>()
- .Key(tabletId)
- .Update<Schema::Tablet::Statistics>(tablet->Statistics);
- } else {
- db.Table<Schema::TabletFollowerTablet>()
- .Key(tabletId, followerId)
- .Update<Schema::TabletFollowerTablet::Statistics>(tablet->Statistics);
- }
- }
- Reply->Record.AddTabletId(tabletId);
+ db.Table<Schema::Tablet>()
+ .Key(tabletId)
+ .Update<Schema::Tablet::Statistics>(tablet->Statistics);
+ } else {
+ db.Table<Schema::TabletFollowerTablet>()
+ .Key(tabletId, followerId)
+ .Update<Schema::TabletFollowerTablet::Statistics>(tablet->Statistics);
+ }
+ }
+ Reply->Record.AddTabletId(tabletId);
Reply->Record.AddFollowerId(followerId);
- }
- TNodeInfo* node = Self->FindNode(nodeId);
- if (node != nullptr) {
- node->UpdateResourceTotalUsage(record);
- node->Statistics.SetLastAliveTimestamp(now.MilliSeconds());
- node->ActualizeNodeStatistics(now);
- BLOG_TRACE("THive::TTxUpdateTabletMetrics UpdateResourceTotalUsage node "
- << nodeId
- << " value "
- << ResourceRawValuesFromMetrics(record.GetTotalResourceUsage())
- << " accumulated to "
- << node->ResourceTotalValues);
- db.Table<Schema::Node>().Key(nodeId).Update<Schema::Node::Statistics>(node->Statistics);
- }
- return true;
- }
-
+ }
+ TNodeInfo* node = Self->FindNode(nodeId);
+ if (node != nullptr) {
+ node->UpdateResourceTotalUsage(record);
+ node->Statistics.SetLastAliveTimestamp(now.MilliSeconds());
+ node->ActualizeNodeStatistics(now);
+ BLOG_TRACE("THive::TTxUpdateTabletMetrics UpdateResourceTotalUsage node "
+ << nodeId
+ << " value "
+ << ResourceRawValuesFromMetrics(record.GetTotalResourceUsage())
+ << " accumulated to "
+ << node->ResourceTotalValues);
+ db.Table<Schema::Node>().Key(nodeId).Update<Schema::Node::Statistics>(node->Statistics);
+ }
+ return true;
+ }
+
void Complete(const TActorContext& ctx) override {
- ctx.Send(Event->Sender, Reply.Release());
- Self->UpdateTabletMetricsInProgress--;
- }
-};
-
+ ctx.Send(Event->Sender, Reply.Release());
+ Self->UpdateTabletMetricsInProgress--;
+ }
+};
+
ITransaction* THive::CreateUpdateTabletMetrics(TEvHive::TEvTabletMetrics::TPtr& ev) {
- return new TTxUpdateTabletMetrics(ev, this);
-}
-
-} // NHive
-} // NKikimr
+ return new TTxUpdateTabletMetrics(ev, this);
+}
+
+} // NHive
+} // NKikimr
diff --git a/ydb/core/mind/hive/tx__update_tablet_status.cpp b/ydb/core/mind/hive/tx__update_tablet_status.cpp
index e79a69fe042..7e682e857d0 100644
--- a/ydb/core/mind/hive/tx__update_tablet_status.cpp
+++ b/ydb/core/mind/hive/tx__update_tablet_status.cpp
@@ -1,222 +1,222 @@
-#include "hive_impl.h"
-#include "hive_log.h"
-
-namespace NKikimr {
-namespace NHive {
-
-class TTxUpdateTabletStatus : public TTransactionBase<THive> {
- const TTabletId TabletId;
+#include "hive_impl.h"
+#include "hive_log.h"
+
+namespace NKikimr {
+namespace NHive {
+
+class TTxUpdateTabletStatus : public TTransactionBase<THive> {
+ const TTabletId TabletId;
const TActorId Local;
- const TEvLocal::TEvTabletStatus::EStatus Status;
- const TEvTablet::TEvTabletDead::EReason Reason;
- ui32 Generation;
+ const TEvLocal::TEvTabletStatus::EStatus Status;
+ const TEvTablet::TEvTabletDead::EReason Reason;
+ ui32 Generation;
TFollowerId FollowerId;
- TCompleteNotifications Notifications;
-
-public:
- TTxUpdateTabletStatus(
- TTabletId tabletId,
+ TCompleteNotifications Notifications;
+
+public:
+ TTxUpdateTabletStatus(
+ TTabletId tabletId,
const TActorId &local,
- ui32 generation,
+ ui32 generation,
TFollowerId followerId,
- TEvLocal::TEvTabletStatus::EStatus status,
- TEvTablet::TEvTabletDead::EReason reason,
- THive *hive)
- : TBase(hive)
- , TabletId(tabletId)
- , Local(local)
- , Status(status)
- , Reason(reason)
- , Generation(generation)
+ TEvLocal::TEvTabletStatus::EStatus status,
+ TEvTablet::TEvTabletDead::EReason reason,
+ THive *hive)
+ : TBase(hive)
+ , TabletId(tabletId)
+ , Local(local)
+ , Status(status)
+ , Reason(reason)
+ , Generation(generation)
, FollowerId(followerId)
- {}
-
- TTxType GetTxType() const override { return NHive::TXTYPE_UPDATE_TABLET_STATUS; }
-
- bool IsGoodStatusForPostpone() const {
- switch (Status) {
- case TEvLocal::TEvTabletStatus::StatusBootFailed:
- switch (Reason) {
- case TEvTablet::TEvTabletDead::EReason::ReasonBootSSError:
- case TEvTablet::TEvTabletDead::EReason::ReasonBootBSError:
- case TEvTablet::TEvTabletDead::EReason::ReasonBootSSTimeout:
- return true;
- default:
- break;
- }
+ {}
+
+ TTxType GetTxType() const override { return NHive::TXTYPE_UPDATE_TABLET_STATUS; }
+
+ bool IsGoodStatusForPostpone() const {
+ switch (Status) {
+ case TEvLocal::TEvTabletStatus::StatusBootFailed:
+ switch (Reason) {
+ case TEvTablet::TEvTabletDead::EReason::ReasonBootSSError:
+ case TEvTablet::TEvTabletDead::EReason::ReasonBootBSError:
+ case TEvTablet::TEvTabletDead::EReason::ReasonBootSSTimeout:
+ return true;
+ default:
+ break;
+ }
break;
- default:
- break;
- }
- return false;
- }
-
- TString GetStatus() {
- TStringBuilder str;
- str << (ui32)Status;
- if (Status != TEvLocal::TEvTabletStatus::StatusOk) {
- str << " reason " << Reason;
- }
- return str;
- }
-
+ default:
+ break;
+ }
+ return false;
+ }
+
+ TString GetStatus() {
+ TStringBuilder str;
+ str << (ui32)Status;
+ if (Status != TEvLocal::TEvTabletStatus::StatusOk) {
+ str << " reason " << Reason;
+ }
+ return str;
+ }
+
bool Execute(TTransactionContext &txc, const TActorContext&) override {
TTabletInfo* tablet = Self->FindTablet(TabletId, FollowerId);
- if (tablet != nullptr) {
- BLOG_D("THive::TTxUpdateTabletStatus::Execute for tablet "
- << tablet->ToString()
- << " status "
- << GetStatus()
- << " generation "
- << Generation
+ if (tablet != nullptr) {
+ BLOG_D("THive::TTxUpdateTabletStatus::Execute for tablet "
+ << tablet->ToString()
+ << " status "
+ << GetStatus()
+ << " generation "
+ << Generation
<< " follower "
<< FollowerId
- << " from local "
- << Local);
- NIceDb::TNiceDb db(txc.DB);
- TInstant now = TActivationContext::Now();
+ << " from local "
+ << Local);
+ NIceDb::TNiceDb db(txc.DB);
+ TInstant now = TActivationContext::Now();
Notifications.Reset(Self->SelfId());
- if (Status == TEvLocal::TEvTabletStatus::StatusOk) {
- tablet->Statistics.AddRestartTimestamp(now.MilliSeconds());
- tablet->ActualizeTabletStatistics(now);
- TNodeInfo* node = Self->FindNode(Local.NodeId());
- if (node == nullptr) {
- // event from IC about disconnection of the node could overtake events from the node itself because of Pipe Server
- // KIKIMR-9614
- return true;
- }
+ if (Status == TEvLocal::TEvTabletStatus::StatusOk) {
+ tablet->Statistics.AddRestartTimestamp(now.MilliSeconds());
+ tablet->ActualizeTabletStatistics(now);
+ TNodeInfo* node = Self->FindNode(Local.NodeId());
+ if (node == nullptr) {
+ // event from IC about disconnection of the node could overtake events from the node itself because of Pipe Server
+ // KIKIMR-9614
+ return true;
+ }
if (tablet->IsLeader() && Generation < tablet->GetLeader().KnownGeneration) {
- return true;
- }
- for (const TActorId& actor : tablet->ActorsToNotifyOnRestart) {
- Notifications.Send(actor, new TEvPrivate::TEvRestartComplete({TabletId, FollowerId}, "OK"));
- }
- tablet->ActorsToNotifyOnRestart.clear();
+ return true;
+ }
+ for (const TActorId& actor : tablet->ActorsToNotifyOnRestart) {
+ Notifications.Send(actor, new TEvPrivate::TEvRestartComplete({TabletId, FollowerId}, "OK"));
+ }
+ tablet->ActorsToNotifyOnRestart.clear();
if (tablet->GetLeader().IsDeleting()) {
tablet->SendStopTablet(Local, {TabletId, FollowerId});
- return true;
- }
- tablet->BecomeRunning(Local.NodeId());
+ return true;
+ }
+ tablet->BecomeRunning(Local.NodeId());
if (tablet->GetLeader().IsLockedToActor()) {
// Tablet is locked and shouldn't be running, but we just found out it's running on this node
// Ask it to stop using InitiateStop (which uses data saved by BecomeRunning call above)
- tablet->InitiateStop();
+ tablet->InitiateStop();
}
- tablet->BootState = Self->BootStateRunning;
- tablet->Statistics.SetLastAliveTimestamp(now.MilliSeconds());
+ tablet->BootState = Self->BootStateRunning;
+ tablet->Statistics.SetLastAliveTimestamp(now.MilliSeconds());
if (tablet->IsLeader()) {
TLeaderTabletInfo& leader(tablet->AsLeader());
leader.KnownGeneration = Generation;
db.Table<Schema::Tablet>().Key(TabletId).Update(NIceDb::TUpdate<Schema::Tablet::LeaderNode>(tablet->NodeId),
- NIceDb::TUpdate<Schema::Tablet::KnownGeneration>(Generation),
- NIceDb::TUpdate<Schema::Tablet::Statistics>(tablet->Statistics));
- } else {
+ NIceDb::TUpdate<Schema::Tablet::KnownGeneration>(Generation),
+ NIceDb::TUpdate<Schema::Tablet::Statistics>(tablet->Statistics));
+ } else {
db.Table<Schema::TabletFollowerTablet>().Key(TabletId, FollowerId).Update(
NIceDb::TUpdate<Schema::TabletFollowerTablet::GroupID>(tablet->AsFollower().FollowerGroup.Id),
- NIceDb::TUpdate<Schema::TabletFollowerTablet::FollowerNode>(Local.NodeId()),
- NIceDb::TUpdate<Schema::TabletFollowerTablet::Statistics>(tablet->Statistics));
- }
+ NIceDb::TUpdate<Schema::TabletFollowerTablet::FollowerNode>(Local.NodeId()),
+ NIceDb::TUpdate<Schema::TabletFollowerTablet::Statistics>(tablet->Statistics));
+ }
for (const TActorId& actor : tablet->ActorsToNotify) {
- Notifications.Send(actor, new TEvHive::TEvTabletCreationResult(NKikimrProto::OK, TabletId));
- }
- tablet->ActorsToNotify.clear();
- db.Table<Schema::Tablet>().Key(TabletId).UpdateToNull<Schema::Tablet::ActorsToNotify>();
- } else {
- if (Local) {
+ Notifications.Send(actor, new TEvHive::TEvTabletCreationResult(NKikimrProto::OK, TabletId));
+ }
+ tablet->ActorsToNotify.clear();
+ db.Table<Schema::Tablet>().Key(TabletId).UpdateToNull<Schema::Tablet::ActorsToNotify>();
+ } else {
+ if (Local) {
Notifications.Send(Local, new TEvLocal::TEvDeadTabletAck(std::make_pair(TabletId, FollowerId), Generation));
- }
- if (tablet->IsLeader()) {
- TLeaderTabletInfo& leader(tablet->AsLeader());
- if (Generation < leader.KnownGeneration) {
- return true;
- }
- if (leader.GetRestartsPerPeriod(now - Self->GetTabletRestartsPeriod()) >= Self->GetTabletRestarsMaxCount()) {
- if (IsGoodStatusForPostpone()) {
- leader.PostponeStart(now + Self->GetPostponeStartPeriod());
- BLOG_D("THive::TTxUpdateTabletStatus::Execute for tablet " << tablet->ToString()
- << " postponed start until " << leader.PostponedStart);
- }
- }
- }
- if (Local) {
- if (tablet->IsAliveOnLocal(Local)) {
+ }
+ if (tablet->IsLeader()) {
+ TLeaderTabletInfo& leader(tablet->AsLeader());
+ if (Generation < leader.KnownGeneration) {
+ return true;
+ }
+ if (leader.GetRestartsPerPeriod(now - Self->GetTabletRestartsPeriod()) >= Self->GetTabletRestarsMaxCount()) {
+ if (IsGoodStatusForPostpone()) {
+ leader.PostponeStart(now + Self->GetPostponeStartPeriod());
+ BLOG_D("THive::TTxUpdateTabletStatus::Execute for tablet " << tablet->ToString()
+ << " postponed start until " << leader.PostponedStart);
+ }
+ }
+ }
+ if (Local) {
+ if (tablet->IsAliveOnLocal(Local)) {
if (tablet->IsLeader()) {
TLeaderTabletInfo& leader(tablet->AsLeader());
db.Table<Schema::Tablet>().Key(TabletId).Update(NIceDb::TUpdate<Schema::Tablet::LeaderNode>(0),
NIceDb::TUpdate<Schema::Tablet::KnownGeneration>(leader.KnownGeneration),
- NIceDb::TUpdate<Schema::Tablet::Statistics>(tablet->Statistics));
- } else {
+ NIceDb::TUpdate<Schema::Tablet::Statistics>(tablet->Statistics));
+ } else {
db.Table<Schema::TabletFollowerTablet>().Key(TabletId, FollowerId).Update(
NIceDb::TUpdate<Schema::TabletFollowerTablet::GroupID>(tablet->AsFollower().FollowerGroup.Id),
- NIceDb::TUpdate<Schema::TabletFollowerTablet::FollowerNode>(0),
- NIceDb::TUpdate<Schema::TabletFollowerTablet::Statistics>(tablet->Statistics));
- }
- tablet->InitiateStop();
- }
- }
+ NIceDb::TUpdate<Schema::TabletFollowerTablet::FollowerNode>(0),
+ NIceDb::TUpdate<Schema::TabletFollowerTablet::Statistics>(tablet->Statistics));
+ }
+ tablet->InitiateStop();
+ }
+ }
switch (tablet->GetLeader().State) {
- case ETabletState::GroupAssignment:
- //Y_FAIL("Unexpected tablet boot failure during group assignment");
- // Just ignore it. This is fail from previous generation.
- return true;
- case ETabletState::StoppingInGroupAssignment:
- case ETabletState::Stopping:
+ case ETabletState::GroupAssignment:
+ //Y_FAIL("Unexpected tablet boot failure during group assignment");
+ // Just ignore it. This is fail from previous generation.
+ return true;
+ case ETabletState::StoppingInGroupAssignment:
+ case ETabletState::Stopping:
if (tablet->IsLeader()) {
for (const TActorId& actor : tablet->GetLeader().ActorsToNotify) {
- Notifications.Send(actor, new TEvHive::TEvStopTabletResult(NKikimrProto::OK, TabletId));
- }
+ Notifications.Send(actor, new TEvHive::TEvStopTabletResult(NKikimrProto::OK, TabletId));
+ }
tablet->GetLeader().ActorsToNotify.clear();
- }
+ }
[[fallthrough]]; // AUTOGENERATED_FALLTHROUGH_FIXME
- case ETabletState::Stopped:
+ case ETabletState::Stopped:
Self->ReportStoppedToWhiteboard(tablet->GetLeader());
- BLOG_D("Report tablet " << tablet->ToString() << " as stopped to Whiteboard");
- break;
- case ETabletState::BlockStorage:
- // do nothing - let the tablet die
- break;
- default:
- break;
- };
- }
- }
- return true;
- }
-
+ BLOG_D("Report tablet " << tablet->ToString() << " as stopped to Whiteboard");
+ break;
+ case ETabletState::BlockStorage:
+ // do nothing - let the tablet die
+ break;
+ default:
+ break;
+ };
+ }
+ }
+ return true;
+ }
+
void Complete(const TActorContext& ctx) override {
- BLOG_D("THive::TTxUpdateTabletStatus::Complete TabletId: " << TabletId << " Notifications: " << Notifications);
- Notifications.Send(ctx);
+ BLOG_D("THive::TTxUpdateTabletStatus::Complete TabletId: " << TabletId << " Notifications: " << Notifications);
+ Notifications.Send(ctx);
TLeaderTabletInfo* tablet = Self->FindTablet(TabletId);
- if (tablet != nullptr) {
- tablet->TryToBoot();
- }
- Self->ProcessBootQueue();
- }
-};
-
+ if (tablet != nullptr) {
+ tablet->TryToBoot();
+ }
+ Self->ProcessBootQueue();
+ }
+};
+
ITransaction* THive::CreateUpdateTabletStatus(
- TTabletId tabletId,
+ TTabletId tabletId,
const TActorId &local,
- ui32 generation,
+ ui32 generation,
TFollowerId followerId,
- TEvLocal::TEvTabletStatus::EStatus status,
- TEvTablet::TEvTabletDead::EReason reason) {
- return new TTxUpdateTabletStatus(tabletId, local, generation, followerId, status, reason, this);
-}
-
-} // NHive
-} // NKikimr
-
-template <>
-inline void Out<NKikimr::NHive::TCompleteNotifications>(IOutputStream& o, const NKikimr::NHive::TCompleteNotifications& n) {
- o << n.SelfID << " -> [";
- for (auto it = n.Notifications.begin(); it != n.Notifications.end(); ++it) {
- if (it != n.Notifications.begin()) {
- o << ',';
- }
- o << it->Get()->Recipient;
- }
- o << "]";
-}
+ TEvLocal::TEvTabletStatus::EStatus status,
+ TEvTablet::TEvTabletDead::EReason reason) {
+ return new TTxUpdateTabletStatus(tabletId, local, generation, followerId, status, reason, this);
+}
+
+} // NHive
+} // NKikimr
+
+template <>
+inline void Out<NKikimr::NHive::TCompleteNotifications>(IOutputStream& o, const NKikimr::NHive::TCompleteNotifications& n) {
+ o << n.SelfID << " -> [";
+ for (auto it = n.Notifications.begin(); it != n.Notifications.end(); ++it) {
+ if (it != n.Notifications.begin()) {
+ o << ',';
+ }
+ o << it->Get()->Recipient;
+ }
+ o << "]";
+}
diff --git a/ydb/core/mind/hive/ut/ya.make b/ydb/core/mind/hive/ut/ya.make
index 4d71e408537..e5f2423eafa 100644
--- a/ydb/core/mind/hive/ut/ya.make
+++ b/ydb/core/mind/hive/ut/ya.make
@@ -24,10 +24,10 @@ PEERDIR(
YQL_LAST_ABI_VERSION()
SRCS(
- sequencer_ut.cpp
- storage_pool_info_ut.cpp
- hive_ut.cpp
- hive_impl_ut.cpp
+ sequencer_ut.cpp
+ storage_pool_info_ut.cpp
+ hive_ut.cpp
+ hive_impl_ut.cpp
)
END()
diff --git a/ydb/core/mind/hive/ya.make b/ydb/core/mind/hive/ya.make
index c311f12bff5..171f26f1b5f 100644
--- a/ydb/core/mind/hive/ya.make
+++ b/ydb/core/mind/hive/ya.make
@@ -1,81 +1,81 @@
LIBRARY()
OWNER(
- xenoxeno
+ xenoxeno
g:kikimr
)
SRCS(
- balancer.cpp
- balancer.h
- boot_queue.cpp
- boot_queue.h
- domain_info.h
- drain.cpp
- fill.cpp
- hive.cpp
- hive.h
- hive_domains.cpp
- hive_domains.h
- hive_events.h
- hive_impl.cpp
- hive_impl.h
- hive_log.cpp
- hive_log.h
- hive_schema.h
- hive_statics.cpp
- hive_transactions.h
+ balancer.cpp
+ balancer.h
+ boot_queue.cpp
+ boot_queue.h
+ domain_info.h
+ drain.cpp
+ fill.cpp
+ hive.cpp
+ hive.h
+ hive_domains.cpp
+ hive_domains.h
+ hive_events.h
+ hive_impl.cpp
+ hive_impl.h
+ hive_log.cpp
+ hive_log.h
+ hive_schema.h
+ hive_statics.cpp
+ hive_transactions.h
leader_tablet_info.cpp
leader_tablet_info.h
- metrics.h
- monitoring.cpp
- node_info.cpp
- node_info.h
- sequencer.cpp
- sequencer.h
+ metrics.h
+ monitoring.cpp
+ node_info.cpp
+ node_info.h
+ sequencer.cpp
+ sequencer.h
follower_group.h
follower_tablet_info.cpp
follower_tablet_info.h
- storage_group_info.cpp
- storage_group_info.h
- storage_pool_info.cpp
- storage_pool_info.h
- tablet_info.cpp
- tablet_info.h
+ storage_group_info.cpp
+ storage_group_info.h
+ storage_pool_info.cpp
+ storage_pool_info.h
+ tablet_info.cpp
+ tablet_info.h
tx__adopt_tablet.cpp
- tx__block_storage_result.cpp
- tx__configure_subdomain.cpp
- tx__create_tablet.cpp
- tx__cut_tablet_history.cpp
- tx__delete_tablet.cpp
- tx__delete_tablet_result.cpp
- tx__disconnect_node.cpp
- tx__init_scheme.cpp
- tx__kill_node.cpp
- tx__load_everything.cpp
+ tx__block_storage_result.cpp
+ tx__configure_subdomain.cpp
+ tx__create_tablet.cpp
+ tx__cut_tablet_history.cpp
+ tx__delete_tablet.cpp
+ tx__delete_tablet_result.cpp
+ tx__disconnect_node.cpp
+ tx__init_scheme.cpp
+ tx__kill_node.cpp
+ tx__load_everything.cpp
tx__lock_tablet.cpp
- tx__process_boot_queue.cpp
- tx__process_pending_operations.cpp
- tx__reassign_groups.cpp
- tx__register_node.cpp
- tx__release_tablets.cpp
- tx__release_tablets_reply.cpp
- tx__request_tablet_seq.cpp
- tx__response_tablet_seq.cpp
- tx__restart_tablet.cpp
- tx__seize_tablets.cpp
- tx__seize_tablets_reply.cpp
- tx__resume_tablet.cpp
- tx__start_tablet.cpp
- tx__status.cpp
- tx__stop_tablet.cpp
- tx__switch_drain.cpp
- tx__sync_tablets.cpp
+ tx__process_boot_queue.cpp
+ tx__process_pending_operations.cpp
+ tx__reassign_groups.cpp
+ tx__register_node.cpp
+ tx__release_tablets.cpp
+ tx__release_tablets_reply.cpp
+ tx__request_tablet_seq.cpp
+ tx__response_tablet_seq.cpp
+ tx__restart_tablet.cpp
+ tx__seize_tablets.cpp
+ tx__seize_tablets_reply.cpp
+ tx__resume_tablet.cpp
+ tx__start_tablet.cpp
+ tx__status.cpp
+ tx__stop_tablet.cpp
+ tx__switch_drain.cpp
+ tx__sync_tablets.cpp
tx__unlock_tablet.cpp
- tx__update_domain.cpp
- tx__update_tablet_groups.cpp
- tx__update_tablet_metrics.cpp
- tx__update_tablet_status.cpp
+ tx__update_domain.cpp
+ tx__update_tablet_groups.cpp
+ tx__update_tablet_metrics.cpp
+ tx__update_tablet_status.cpp
)
PEERDIR(
diff --git a/ydb/core/mind/lease_holder.cpp b/ydb/core/mind/lease_holder.cpp
index 6027cfa7077..5d47d04c71f 100644
--- a/ydb/core/mind/lease_holder.cpp
+++ b/ydb/core/mind/lease_holder.cpp
@@ -144,7 +144,7 @@ private:
ui32 group = domain.DefaultStateStorageGroup;
NTabletPipe::TClientConfig config;
- config.RetryPolicy = NTabletPipe::TClientRetryPolicy::WithRetries();
+ config.RetryPolicy = NTabletPipe::TClientRetryPolicy::WithRetries();
auto pipe = NTabletPipe::CreateClient(ctx.SelfID, MakeNodeBrokerID(group), config);
NodeBrokerPipe = ctx.Register(pipe);
}
diff --git a/ydb/core/mind/local.cpp b/ydb/core/mind/local.cpp
index e12c920fb13..09fc15f76dd 100644
--- a/ydb/core/mind/local.cpp
+++ b/ydb/core/mind/local.cpp
@@ -14,23 +14,23 @@
#include <library/cpp/actors/core/hfunc.h>
#include <library/cpp/actors/core/log.h>
-#include <util/system/info.h>
-
-#include <unordered_map>
-#include <unordered_set>
+#include <util/system/info.h>
-template <>
+#include <unordered_map>
+#include <unordered_set>
+
+template <>
void Out<std::pair<ui64, ui32>>(IOutputStream& out, const std::pair<ui64, ui32>& p) {
- out << '(' << p.first << ',' << p.second << ')';
-}
-
+ out << '(' << p.first << ',' << p.second << ')';
+}
+
namespace NKikimr {
class TLocalNodeRegistrar : public TActorBootstrapped<TLocalNodeRegistrar> {
struct TEvPrivate {
enum EEv {
EvRegisterTimeout = EventSpaceBegin(TEvents::ES_PRIVATE),
- EvSendTabletMetrics,
- EvUpdateSystemUsage,
+ EvSendTabletMetrics,
+ EvUpdateSystemUsage,
EvLocalDrainTimeout,
EvEnd
};
@@ -38,42 +38,42 @@ class TLocalNodeRegistrar : public TActorBootstrapped<TLocalNodeRegistrar> {
static_assert(EvEnd < EventSpaceEnd(TEvents::ES_PRIVATE), "expect EvEnd < EventSpaceEnd(TEvents::ES_PRIVATE)");
typedef TEventSchedulerEv<EvRegisterTimeout> TEvRegisterTimeout;
- struct TEvSendTabletMetrics : TEventLocal<TEvSendTabletMetrics, EvSendTabletMetrics> {};
- struct TEvUpdateSystemUsage : TEventLocal<TEvUpdateSystemUsage, EvUpdateSystemUsage> {};
+ struct TEvSendTabletMetrics : TEventLocal<TEvSendTabletMetrics, EvSendTabletMetrics> {};
+ struct TEvUpdateSystemUsage : TEventLocal<TEvUpdateSystemUsage, EvUpdateSystemUsage> {};
struct TEvLocalDrainTimeout : TEventLocal<TEvLocalDrainTimeout, EvLocalDrainTimeout> {};
};
- struct TTablet {
+ struct TTablet {
TActorId Tablet;
ui32 Generation;
- TTabletTypes::EType TabletType;
- NKikimrLocal::EBootMode BootMode;
+ TTabletTypes::EType TabletType;
+ NKikimrLocal::EBootMode BootMode;
ui32 FollowerId;
- TTablet()
+ TTablet()
: Tablet()
, Generation(0)
- , TabletType()
+ , TabletType()
, BootMode(NKikimrLocal::EBootMode::BOOT_MODE_LEADER)
, FollowerId(0)
{}
};
- struct TTabletEntry : TTablet {
- TInstant From;
-
- TTabletEntry()
+ struct TTabletEntry : TTablet {
+ TInstant From;
+
+ TTabletEntry()
: From(TInstant::MicroSeconds(0))
- {}
- };
-
- struct TOnlineTabletEntry : TTabletEntry {
- NKikimrTabletBase::TMetrics ResourceValues;
-
- TOnlineTabletEntry() = default;
- TOnlineTabletEntry(TTabletEntry& tablet)
- : TTabletEntry(tablet)
- {}
+ {}
+ };
+
+ struct TOnlineTabletEntry : TTabletEntry {
+ NKikimrTabletBase::TMetrics ResourceValues;
+
+ TOnlineTabletEntry() = default;
+ TOnlineTabletEntry(TTabletEntry& tablet)
+ : TTabletEntry(tablet)
+ {}
};
const TActorId Owner;
@@ -91,28 +91,28 @@ class TLocalNodeRegistrar : public TActorBootstrapped<TLocalNodeRegistrar> {
TActorId KnownHiveLeader;
using TTabletId = std::pair<ui64, ui32>; // <TTabletId, TFollowerId>
- TInstant StartTime;
- std::unordered_map<TTabletId, TTabletEntry> InbootTablets;
- std::unordered_map<TTabletId, TOnlineTabletEntry> OnlineTablets;
- std::unordered_map<TTabletId, ui32> UpdatedTabletMetrics;
- bool SendTabletMetricsInProgress;
- TInstant SendTabletMetricsTime;
- TDuration LastSendTabletMetricsDuration = {};
- constexpr static TDuration TABLET_METRICS_BATCH_INTERVAL = TDuration::MilliSeconds(5000);
- constexpr static TDuration UPDATE_SYSTEM_USAGE_INTERVAL = TDuration::MilliSeconds(1000);
+ TInstant StartTime;
+ std::unordered_map<TTabletId, TTabletEntry> InbootTablets;
+ std::unordered_map<TTabletId, TOnlineTabletEntry> OnlineTablets;
+ std::unordered_map<TTabletId, ui32> UpdatedTabletMetrics;
+ bool SendTabletMetricsInProgress;
+ TInstant SendTabletMetricsTime;
+ TDuration LastSendTabletMetricsDuration = {};
+ constexpr static TDuration TABLET_METRICS_BATCH_INTERVAL = TDuration::MilliSeconds(5000);
+ constexpr static TDuration UPDATE_SYSTEM_USAGE_INTERVAL = TDuration::MilliSeconds(1000);
constexpr static TDuration DRAIN_NODE_TIMEOUT = TDuration::MilliSeconds(15000);
- ui64 UserPoolUsage = 0; // (usage uS x threads) / sec
- ui64 MemUsage = 0;
- ui64 MemLimit = 0;
- double NodeUsage = 0;
-
+ ui64 UserPoolUsage = 0; // (usage uS x threads) / sec
+ ui64 MemUsage = 0;
+ ui64 MemLimit = 0;
+ double NodeUsage = 0;
+
bool SentDrainNode = false;
bool DrainResultReceived = false;
i32 PrevEstimate = 0;
TIntrusivePtr<TDrainProgress> LastDrainRequest;
- NKikimrTabletBase::TMetrics ResourceLimit;
+ NKikimrTabletBase::TMetrics ResourceLimit;
TResourceProfilesPtr ResourceProfiles;
TSharedQuotaPtr TxCacheQuota;
NMonitoring::TDynamicCounterPtr Counters;
@@ -136,35 +136,35 @@ class TLocalNodeRegistrar : public TActorBootstrapped<TLocalNodeRegistrar> {
NMonitoring::TDynamicCounters::TCounterPtr CounterCancelUnknownReason;
void Die(const TActorContext &ctx) override {
- if (HivePipeClient) {
- if (Connected) {
- NTabletPipe::SendData(ctx, HivePipeClient, new TEvLocal::TEvStatus(TEvLocal::TEvStatus::StatusDead));
- }
+ if (HivePipeClient) {
+ if (Connected) {
+ NTabletPipe::SendData(ctx, HivePipeClient, new TEvLocal::TEvStatus(TEvLocal::TEvStatus::StatusDead));
+ }
NTabletPipe::CloseClient(ctx, HivePipeClient);
- }
+ }
HivePipeClient = TActorId();
- for (const auto &xpair : OnlineTablets) {
+ for (const auto &xpair : OnlineTablets) {
ctx.Send(xpair.second.Tablet, new TEvents::TEvPoisonPill());
- }
+ }
OnlineTablets.clear();
- for (const auto &xpair : InbootTablets) {
+ for (const auto &xpair : InbootTablets) {
ctx.Send(xpair.second.Tablet, new TEvents::TEvPoisonPill());
- }
+ }
InbootTablets.clear();
TActor::Die(ctx);
}
- void MarkDeadTablet(TTabletId tabletId,
- ui32 generation,
- TEvLocal::TEvTabletStatus::EStatus status,
- TEvTablet::TEvTabletDead::EReason reason,
- const TActorContext &ctx) {
- if (Connected) { // must be 'connected' check
- NTabletPipe::SendData(ctx, HivePipeClient, new TEvLocal::TEvTabletStatus(status, reason, tabletId, generation));
- }
+ void MarkDeadTablet(TTabletId tabletId,
+ ui32 generation,
+ TEvLocal::TEvTabletStatus::EStatus status,
+ TEvTablet::TEvTabletDead::EReason reason,
+ const TActorContext &ctx) {
+ if (Connected) { // must be 'connected' check
+ NTabletPipe::SendData(ctx, HivePipeClient, new TEvLocal::TEvTabletStatus(status, reason, tabletId, generation));
+ }
}
void TryToRegister(const TActorContext &ctx) {
@@ -172,35 +172,35 @@ class TLocalNodeRegistrar : public TActorBootstrapped<TLocalNodeRegistrar> {
Y_VERIFY_DEBUG(!HivePipeClient);
- // pipe client is in use for convenience, real info update come from EvPing
+ // pipe client is in use for convenience, real info update come from EvPing
NTabletPipe::TClientConfig pipeConfig;
- pipeConfig.RetryPolicy = {
- .MinRetryTime = TDuration::MilliSeconds(100),
- .MaxRetryTime = TDuration::Seconds(5),
- .BackoffMultiplier = 2,
- .DoFirstRetryInstantly = true
- };
+ pipeConfig.RetryPolicy = {
+ .MinRetryTime = TDuration::MilliSeconds(100),
+ .MaxRetryTime = TDuration::Seconds(5),
+ .BackoffMultiplier = 2,
+ .DoFirstRetryInstantly = true
+ };
HivePipeClient = ctx.RegisterWithSameMailbox(NTabletPipe::CreateClient(ctx.SelfID, HiveId, pipeConfig));
THolder<TEvLocal::TEvRegisterNode> request = MakeHolder<TEvLocal::TEvRegisterNode>(HiveId);
for (auto &domain: ServicedDomains) {
*request->Record.AddServicedDomains() = NKikimrSubDomains::TDomainKey(domain);
}
- for (const auto& [tabletType, tabletInfo] : Config->TabletClassInfo) {
- NKikimrLocal::TTabletAvailability* tabletAvailability = request->Record.AddTabletAvailability();
- tabletAvailability->SetType(tabletType);
- if (tabletInfo.MaxCount != 0) {
- tabletAvailability->SetMaxCount(tabletInfo.MaxCount);
- }
- }
+ for (const auto& [tabletType, tabletInfo] : Config->TabletClassInfo) {
+ NKikimrLocal::TTabletAvailability* tabletAvailability = request->Record.AddTabletAvailability();
+ tabletAvailability->SetType(tabletType);
+ if (tabletInfo.MaxCount != 0) {
+ tabletAvailability->SetMaxCount(tabletInfo.MaxCount);
+ }
+ }
NTabletPipe::SendData(ctx, HivePipeClient, request.Release());
- LOG_DEBUG_S(ctx, NKikimrServices::LOCAL, "TLocalNodeRegistrar::TryToRegister pipe to hive, pipe:" << HivePipeClient.ToString());
+ LOG_DEBUG_S(ctx, NKikimrServices::LOCAL, "TLocalNodeRegistrar::TryToRegister pipe to hive, pipe:" << HivePipeClient.ToString());
}
void HandlePipeDestroyed(const TActorContext &ctx) {
- LOG_DEBUG_S(ctx, NKikimrServices::LOCAL, "TLocalNodeRegistrar HandlePipeDestroyed - DISCONNECTED");
+ LOG_DEBUG_S(ctx, NKikimrServices::LOCAL, "TLocalNodeRegistrar HandlePipeDestroyed - DISCONNECTED");
HivePipeClient = TActorId();
Connected = false;
TryToRegister(ctx);
@@ -219,7 +219,7 @@ class TLocalNodeRegistrar : public TActorBootstrapped<TLocalNodeRegistrar> {
new TEvLocal::TEvEnumerateTabletsResult(NKikimrProto::OK));
bool isFilteringNeeded = false;
- TTabletTypes::EType tabletType = TTabletTypes::Unknown;
+ TTabletTypes::EType tabletType = TTabletTypes::Unknown;
if (record.HasTabletType()) {
isFilteringNeeded = true;
tabletType = record.GetTabletType();
@@ -229,7 +229,7 @@ class TLocalNodeRegistrar : public TActorBootstrapped<TLocalNodeRegistrar> {
for (const auto &tablet: OnlineTablets) {
if (!isFilteringNeeded || tablet.second.TabletType == tabletType) {
auto *info = result->Record.AddTabletInfo();
- info->SetTabletId(tablet.first.first);
+ info->SetTabletId(tablet.first.first);
info->SetFollowerId(tablet.first.second);
info->SetTabletType(tablet.second.TabletType);
info->SetBootMode(tablet.second.BootMode);
@@ -242,71 +242,71 @@ class TLocalNodeRegistrar : public TActorBootstrapped<TLocalNodeRegistrar> {
void Handle(TEvTabletPipe::TEvClientConnected::TPtr &ev, const TActorContext &ctx) {
TEvTabletPipe::TEvClientConnected *msg = ev->Get();
- LOG_DEBUG_S(ctx, NKikimrServices::LOCAL, "TEvTabletPipe::TEvClientConnected {"
- << "TabletId=" << msg->TabletId
- << " Status=" << msg->Status
- << " ClientId=" << msg->ClientId);
+ LOG_DEBUG_S(ctx, NKikimrServices::LOCAL, "TEvTabletPipe::TEvClientConnected {"
+ << "TabletId=" << msg->TabletId
+ << " Status=" << msg->Status
+ << " ClientId=" << msg->ClientId);
if (msg->ClientId != HivePipeClient)
return;
- if (msg->Status == NKikimrProto::OK) {
- SendTabletMetricsInProgress = false;
+ if (msg->Status == NKikimrProto::OK) {
+ SendTabletMetricsInProgress = false;
return;
- }
+ }
HandlePipeDestroyed(ctx);
}
void Handle(TEvTabletPipe::TEvClientDestroyed::TPtr &ev, const TActorContext &ctx) {
TEvTabletPipe::TEvClientDestroyed *msg = ev->Get();
- LOG_DEBUG_S(ctx, NKikimrServices::LOCAL, "TEvTabletPipe::TEvClientDestroyed {"
- << "TabletId=" << msg->TabletId
- << " ClientId=" << msg->ClientId);
+ LOG_DEBUG_S(ctx, NKikimrServices::LOCAL, "TEvTabletPipe::TEvClientDestroyed {"
+ << "TabletId=" << msg->TabletId
+ << " ClientId=" << msg->ClientId);
if (msg->ClientId != HivePipeClient)
return;
HandlePipeDestroyed(ctx);
}
void SendStatusOk(const TActorContext &ctx) {
- LOG_DEBUG_S(ctx, NKikimrServices::LOCAL, "TLocalNodeRegistrar SendStatusOk");
+ LOG_DEBUG_S(ctx, NKikimrServices::LOCAL, "TLocalNodeRegistrar SendStatusOk");
TAutoPtr<TEvLocal::TEvStatus> eventStatus = new TEvLocal::TEvStatus(TEvLocal::TEvStatus::StatusOk);
auto& record = eventStatus->Record;
record.SetStartTime(StartTime.GetValue());
record.MutableResourceMaximum()->CopyFrom(ResourceLimit);
- if (!record.GetResourceMaximum().HasCPU()) {
- TExecutorPoolStats poolStats;
- TVector<TExecutorThreadStats> statsCopy;
- ctx.ExecutorThread.ActorSystem->GetPoolStats(AppData()->UserPoolId, poolStats, statsCopy);
- if (!statsCopy.empty()) {
- record.MutableResourceMaximum()->SetCPU((statsCopy.size() - 1) * 1000000);
- }
- }
- if (!record.GetResourceMaximum().HasMemory()) {
- if (MemLimit != 0) {
- record.MutableResourceMaximum()->SetMemory(MemLimit);
- } else {
- record.MutableResourceMaximum()->SetMemory(NSystemInfo::TotalMemorySize());
- }
- }
- NTabletPipe::SendData(ctx, HivePipeClient, eventStatus.Release());
- }
-
- void Handle(TEvLocal::TEvReconnect::TPtr& ev, const TActorContext& ctx) {
- LOG_DEBUG(ctx, NKikimrServices::LOCAL, "TLocalNodeRegistrar::Handle TEvLocal::TEvReconnect");
+ if (!record.GetResourceMaximum().HasCPU()) {
+ TExecutorPoolStats poolStats;
+ TVector<TExecutorThreadStats> statsCopy;
+ ctx.ExecutorThread.ActorSystem->GetPoolStats(AppData()->UserPoolId, poolStats, statsCopy);
+ if (!statsCopy.empty()) {
+ record.MutableResourceMaximum()->SetCPU((statsCopy.size() - 1) * 1000000);
+ }
+ }
+ if (!record.GetResourceMaximum().HasMemory()) {
+ if (MemLimit != 0) {
+ record.MutableResourceMaximum()->SetMemory(MemLimit);
+ } else {
+ record.MutableResourceMaximum()->SetMemory(NSystemInfo::TotalMemorySize());
+ }
+ }
+ NTabletPipe::SendData(ctx, HivePipeClient, eventStatus.Release());
+ }
+
+ void Handle(TEvLocal::TEvReconnect::TPtr& ev, const TActorContext& ctx) {
+ LOG_DEBUG(ctx, NKikimrServices::LOCAL, "TLocalNodeRegistrar::Handle TEvLocal::TEvReconnect");
const TActorId& sender = ev->Sender;
- const NKikimrLocal::TEvReconnect& record = ev->Get()->Record;
- Y_VERIFY(HiveId == record.GetHiveId());
- const ui32 hiveGen = record.GetHiveGeneration();
- if (hiveGen < HiveGeneration) {
- LOG_DEBUG_S(ctx, NKikimrServices::LOCAL, "TLocalNodeRegistrar::Handle TEvLocal::TEvReconnect - outdated");
- ctx.Send(sender, new TEvLocal::TEvStatus(TEvLocal::TEvStatus::StatusOutdated));
- return;
- }
- if (HivePipeClient) {
- NTabletPipe::CloseClient(ctx, HivePipeClient); // called automatically HandlePipeDestroyed(ctx);
- } else {
- HandlePipeDestroyed(ctx);
- }
- }
-
+ const NKikimrLocal::TEvReconnect& record = ev->Get()->Record;
+ Y_VERIFY(HiveId == record.GetHiveId());
+ const ui32 hiveGen = record.GetHiveGeneration();
+ if (hiveGen < HiveGeneration) {
+ LOG_DEBUG_S(ctx, NKikimrServices::LOCAL, "TLocalNodeRegistrar::Handle TEvLocal::TEvReconnect - outdated");
+ ctx.Send(sender, new TEvLocal::TEvStatus(TEvLocal::TEvStatus::StatusOutdated));
+ return;
+ }
+ if (HivePipeClient) {
+ NTabletPipe::CloseClient(ctx, HivePipeClient); // called automatically HandlePipeDestroyed(ctx);
+ } else {
+ HandlePipeDestroyed(ctx);
+ }
+ }
+
void Handle(TEvLocal::TEvPing::TPtr &ev, const TActorContext &ctx) {
LOG_DEBUG(ctx, NKikimrServices::LOCAL, "TLocalNodeRegistrar::Handle TEvLocal::TEvPing");
const TActorId &sender = ev->Sender;
@@ -315,81 +315,81 @@ class TLocalNodeRegistrar : public TActorBootstrapped<TLocalNodeRegistrar> {
const ui32 hiveGen = record.GetHiveGeneration();
if (hiveGen < HiveGeneration) {
- LOG_DEBUG_S(ctx, NKikimrServices::LOCAL, "TLocalNodeRegistrar::Handle TEvLocal::TEvPing - outdated");
+ LOG_DEBUG_S(ctx, NKikimrServices::LOCAL, "TLocalNodeRegistrar::Handle TEvLocal::TEvPing - outdated");
ctx.Send(sender, new TEvLocal::TEvStatus(TEvLocal::TEvStatus::StatusOutdated));
return;
}
- if (!HivePipeClient) {
- TryToRegister(ctx);
- return;
- }
-
- if (!Connected) {
- if (sender != BootQueue) {
- for (const auto &x : InbootTablets)
- ctx.Send(x.second.Tablet, new TEvents::TEvPoisonPill());
- InbootTablets.clear();
- }
-
- if (record.GetPurge()) {
- for (const auto &x : OnlineTablets)
- ctx.Send(x.second.Tablet, new TEvents::TEvPoisonPill());
- OnlineTablets.clear();
- }
-
- ResourceProfiles = new TResourceProfiles;
- ResourceProfiles->LoadProfiles(record.GetConfig().GetResourceProfiles());
-
- // we send starting and running tablets
- TAutoPtr<TEvLocal::TEvSyncTablets> eventSyncTablets = new TEvLocal::TEvSyncTablets();
- for (const auto& pr : InbootTablets) {
- auto* tablet = eventSyncTablets->Record.AddInbootTablets();
- tablet->SetTabletId(pr.first.first);
+ if (!HivePipeClient) {
+ TryToRegister(ctx);
+ return;
+ }
+
+ if (!Connected) {
+ if (sender != BootQueue) {
+ for (const auto &x : InbootTablets)
+ ctx.Send(x.second.Tablet, new TEvents::TEvPoisonPill());
+ InbootTablets.clear();
+ }
+
+ if (record.GetPurge()) {
+ for (const auto &x : OnlineTablets)
+ ctx.Send(x.second.Tablet, new TEvents::TEvPoisonPill());
+ OnlineTablets.clear();
+ }
+
+ ResourceProfiles = new TResourceProfiles;
+ ResourceProfiles->LoadProfiles(record.GetConfig().GetResourceProfiles());
+
+ // we send starting and running tablets
+ TAutoPtr<TEvLocal::TEvSyncTablets> eventSyncTablets = new TEvLocal::TEvSyncTablets();
+ for (const auto& pr : InbootTablets) {
+ auto* tablet = eventSyncTablets->Record.AddInbootTablets();
+ tablet->SetTabletId(pr.first.first);
tablet->SetFollowerId(pr.first.second);
- tablet->SetGeneration(pr.second.Generation);
- tablet->SetBootMode(pr.second.BootMode);
-
- ctx.Send(pr.second.Tablet, new TEvTablet::TEvUpdateConfig(ResourceProfiles));
- }
- for (const auto& pr : OnlineTablets) {
- auto* tablet = eventSyncTablets->Record.AddOnlineTablets();
- tablet->SetTabletId(pr.first.first);
+ tablet->SetGeneration(pr.second.Generation);
+ tablet->SetBootMode(pr.second.BootMode);
+
+ ctx.Send(pr.second.Tablet, new TEvTablet::TEvUpdateConfig(ResourceProfiles));
+ }
+ for (const auto& pr : OnlineTablets) {
+ auto* tablet = eventSyncTablets->Record.AddOnlineTablets();
+ tablet->SetTabletId(pr.first.first);
tablet->SetFollowerId(pr.first.second);
- tablet->SetGeneration(pr.second.Generation);
- tablet->SetBootMode(pr.second.BootMode);
-
- ctx.Send(pr.second.Tablet, new TEvTablet::TEvUpdateConfig(ResourceProfiles));
- }
- NTabletPipe::SendData(ctx, HivePipeClient, eventSyncTablets.Release());
-
- Connected = true;
- LOG_DEBUG_S(ctx, NKikimrServices::LOCAL, "TLocalNodeRegistrar TEvPing - CONNECTED");
- }
-
- HiveGeneration = hiveGen;
- BootQueue = sender;
-
- // we send status of the 'local' to become online and available for new tablets
+ tablet->SetGeneration(pr.second.Generation);
+ tablet->SetBootMode(pr.second.BootMode);
+
+ ctx.Send(pr.second.Tablet, new TEvTablet::TEvUpdateConfig(ResourceProfiles));
+ }
+ NTabletPipe::SendData(ctx, HivePipeClient, eventSyncTablets.Release());
+
+ Connected = true;
+ LOG_DEBUG_S(ctx, NKikimrServices::LOCAL, "TLocalNodeRegistrar TEvPing - CONNECTED");
+ }
+
+ HiveGeneration = hiveGen;
+ BootQueue = sender;
+
+ // we send status of the 'local' to become online and available for new tablets
SendStatusOk(ctx);
-
- ScheduleSendTabletMetrics(ctx);
+
+ ScheduleSendTabletMetrics(ctx);
}
void Handle(TEvLocal::TEvBootTablet::TPtr &ev, const TActorContext &ctx) {
NKikimrLocal::TEvBootTablet &record = ev->Get()->Record;
TIntrusivePtr<TTabletStorageInfo> info(TabletStorageInfoFromProto(record.GetInfo()));
- info->HiveId = HiveId;
+ info->HiveId = HiveId;
TTabletId tabletId(info->TabletID, record.GetFollowerId());
- LOG_DEBUG_S(ctx, NKikimrServices::LOCAL, "TLocalNodeRegistrar::Handle TEvLocal::TEvBootTablet tabletId:"
- << tabletId
+ LOG_DEBUG_S(ctx, NKikimrServices::LOCAL, "TLocalNodeRegistrar::Handle TEvLocal::TEvBootTablet tabletId:"
+ << tabletId
<< (record.HasBootMode() && record.GetBootMode() == NKikimrLocal::EBootMode::BOOT_MODE_FOLLOWER ? ".Follower" : ".Leader")
- << " storage:"
- << info->ToString());
- Y_VERIFY(!info->Channels.empty() && !info->Channels[0].History.empty());
- auto tabletType = info->TabletType;
- Y_VERIFY(tabletType != TTabletTypes::TypeInvalid);
- ui32 suggestedGen = record.GetSuggestedGeneration();
+ << " storage:"
+ << info->ToString());
+ Y_VERIFY(!info->Channels.empty() && !info->Channels[0].History.empty());
+ auto tabletType = info->TabletType;
+ Y_VERIFY(tabletType != TTabletTypes::TypeInvalid);
+ ui32 suggestedGen = record.GetSuggestedGeneration();
if (ev->Sender != BootQueue) {
LOG_NOTICE(ctx, NKikimrServices::LOCAL,
@@ -400,14 +400,14 @@ class TLocalNodeRegistrar : public TActorBootstrapped<TLocalNodeRegistrar> {
return;
}
- LOG_DEBUG_S(ctx, NKikimrServices::LOCAL, "TLocalNodeRegistrar: Handle TEvLocal::TEvBootTablet tabletType:"
+ LOG_DEBUG_S(ctx, NKikimrServices::LOCAL, "TLocalNodeRegistrar: Handle TEvLocal::TEvBootTablet tabletType:"
<< tabletType << " tabletId:" << tabletId << " suggestedGen:" << suggestedGen);
TMap<TTabletTypes::EType, TLocalConfig::TTabletClassInfo>::const_iterator it = Config->TabletClassInfo.find(tabletType);
if (it == Config->TabletClassInfo.end()) {
LOG_ERROR_S(ctx, NKikimrServices::LOCAL,
- "TLocalNodeRegistrar: boot-tablet unknown tablet type: "
- << tabletType << " for tablet: " << tabletId);
+ "TLocalNodeRegistrar: boot-tablet unknown tablet type: "
+ << tabletType << " for tablet: " << tabletId);
ctx.Send(ev->Sender, new TEvLocal::TEvTabletStatus(
TEvLocal::TEvTabletStatus::StatusTypeUnknown, tabletId, suggestedGen));
return;
@@ -420,59 +420,59 @@ class TLocalNodeRegistrar : public TActorBootstrapped<TLocalNodeRegistrar> {
&& record.GetBootMode() == NKikimrLocal::EBootMode::BOOT_MODE_LEADER) {
// promote to leader
it->second.BootMode = NKikimrLocal::EBootMode::BOOT_MODE_LEADER;
- it->second.Generation = suggestedGen;
+ it->second.Generation = suggestedGen;
tabletId.second = 0; // FollowerId = 0
- TTabletEntry &entry = InbootTablets[tabletId];
- entry = it->second;
- entry.From = ctx.Now();
+ TTabletEntry &entry = InbootTablets[tabletId];
+ entry = it->second;
+ entry.From = ctx.Now();
entry.BootMode = NKikimrLocal::EBootMode::BOOT_MODE_LEADER;
- entry.Generation = suggestedGen;
+ entry.Generation = suggestedGen;
ctx.Send(entry.Tablet, new TEvTablet::TEvPromoteToLeader(suggestedGen, info));
MarkDeadTablet(it->first, 0, TEvLocal::TEvTabletStatus::StatusSupersededByLeader, TEvTablet::TEvTabletDead::ReasonError, ctx);
- OnlineTablets.erase(it);
- LOG_DEBUG_S(ctx, NKikimrServices::LOCAL,
+ OnlineTablets.erase(it);
+ LOG_DEBUG_S(ctx, NKikimrServices::LOCAL,
"TLocalNodeRegistrar::Handle TEvLocal::TEvBootTablet follower tablet " << tabletId << " promoted to leader");
- return;
- }
+ return;
+ }
ctx.Send(it->second.Tablet, new TEvTablet::TEvTabletStop(tabletId.first, TEvTablet::TEvTabletStop::ReasonStop));
OnlineTablets.erase(it);
}
}
- TTabletEntry &entry = InbootTablets[tabletId];
- if (entry.Tablet && entry.Generation != suggestedGen) {
- ctx.Send(entry.Tablet, new TEvents::TEvPoisonPill());
- }
+ TTabletEntry &entry = InbootTablets[tabletId];
+ if (entry.Tablet && entry.Generation != suggestedGen) {
+ ctx.Send(entry.Tablet, new TEvents::TEvPoisonPill());
+ }
TTabletSetupInfo *setupInfo = it->second.SetupInfo.Get();
- switch (record.GetBootMode()) {
+ switch (record.GetBootMode()) {
case NKikimrLocal::BOOT_MODE_LEADER:
entry.Tablet = setupInfo->Tablet(info.Get(), ctx.SelfID, ctx, suggestedGen, ResourceProfiles, TxCacheQuota);
CounterStartAttempts->Inc();
- break;
+ break;
case NKikimrLocal::BOOT_MODE_FOLLOWER:
entry.Tablet = setupInfo->Follower(info.Get(), ctx.SelfID, ctx, tabletId.second, ResourceProfiles, TxCacheQuota);
CounterFollowerAttempts->Inc();
- break;
- }
-
+ break;
+ }
+
entry.Generation = suggestedGen;
entry.From = ctx.Now();
entry.TabletType = tabletType;
- entry.BootMode = record.GetBootMode();
+ entry.BootMode = record.GetBootMode();
+
+ LOG_DEBUG_S(ctx, NKikimrServices::LOCAL, "TLocalNodeRegistrar::Handle TEvLocal::TEvBootTablet tabletId:" << tabletId << " tablet entry created");
- LOG_DEBUG_S(ctx, NKikimrServices::LOCAL, "TLocalNodeRegistrar::Handle TEvLocal::TEvBootTablet tabletId:" << tabletId << " tablet entry created");
-
if (record.GetBootMode() == NKikimrLocal::BOOT_MODE_FOLLOWER) {
- MarkRunningTablet(tabletId, suggestedGen, ctx);
- }
+ MarkRunningTablet(tabletId, suggestedGen, ctx);
+ }
}
void Handle(TEvLocal::TEvStopTablet::TPtr &ev, const TActorContext &ctx) {
const NKikimrLocal::TEvStopTablet &record = ev->Get()->Record;
Y_VERIFY(record.HasTabletId());
TTabletId tabletId(record.GetTabletId(), record.GetFollowerId());
- LOG_DEBUG_S(ctx, NKikimrServices::LOCAL, "TLocalNodeRegistrar: Handle TEvStopTablet TabletId:" << tabletId);
+ LOG_DEBUG_S(ctx, NKikimrServices::LOCAL, "TLocalNodeRegistrar: Handle TEvStopTablet TabletId:" << tabletId);
auto onlineTabletIt = OnlineTablets.find(tabletId);
if (onlineTabletIt != OnlineTablets.end()) {
@@ -488,43 +488,43 @@ class TLocalNodeRegistrar : public TActorBootstrapped<TLocalNodeRegistrar> {
}
void Handle(TEvLocal::TEvDeadTabletAck::TPtr &ev, const TActorContext &ctx) {
- const NKikimrLocal::TEvDeadTabletAck &record = ev->Get()->Record;
- Y_VERIFY(record.HasTabletId());
+ const NKikimrLocal::TEvDeadTabletAck &record = ev->Get()->Record;
+ Y_VERIFY(record.HasTabletId());
TTabletId tabletId(record.GetTabletId(), record.GetFollowerId());
- LOG_DEBUG_S(ctx, NKikimrServices::LOCAL, "TLocalNodeRegistrar: Handle TEvDeadTabletAck TabletId:" << tabletId);
+ LOG_DEBUG_S(ctx, NKikimrServices::LOCAL, "TLocalNodeRegistrar: Handle TEvDeadTabletAck TabletId:" << tabletId);
}
- void Handle(TEvLocal::TEvTabletMetrics::TPtr& ev, const TActorContext& ctx) {
- TEvLocal::TEvTabletMetrics* msg = ev->Get();
+ void Handle(TEvLocal::TEvTabletMetrics::TPtr& ev, const TActorContext& ctx) {
+ TEvLocal::TEvTabletMetrics* msg = ev->Get();
const TTabletId tabletId(msg->TabletId, msg->FollowerId);
- auto it = OnlineTablets.find(tabletId);
- if (it != OnlineTablets.end()) {
- const auto& metrics(msg->ResourceValues);
- auto before = it->second.ResourceValues.ByteSize();
- if (metrics.HasCPU()) {
- it->second.ResourceValues.SetCPU(metrics.GetCPU());
- }
- if (metrics.HasMemory()) {
- it->second.ResourceValues.SetMemory(metrics.GetMemory());
- }
- if (metrics.HasNetwork()) {
- it->second.ResourceValues.SetNetwork(metrics.GetNetwork());
- }
- if (metrics.HasStorage()) {
- it->second.ResourceValues.SetStorage(metrics.GetStorage());
- }
- if (metrics.GroupReadThroughputSize() > 0) {
- it->second.ResourceValues.ClearGroupReadThroughput();
- for (const auto& v : metrics.GetGroupReadThroughput()) {
- it->second.ResourceValues.AddGroupReadThroughput()->CopyFrom(v);
- }
- }
- if (metrics.GroupWriteThroughputSize() > 0) {
- it->second.ResourceValues.ClearGroupWriteThroughput();
- for (const auto& v : metrics.GetGroupWriteThroughput()) {
- it->second.ResourceValues.AddGroupWriteThroughput()->CopyFrom(v);
- }
- }
+ auto it = OnlineTablets.find(tabletId);
+ if (it != OnlineTablets.end()) {
+ const auto& metrics(msg->ResourceValues);
+ auto before = it->second.ResourceValues.ByteSize();
+ if (metrics.HasCPU()) {
+ it->second.ResourceValues.SetCPU(metrics.GetCPU());
+ }
+ if (metrics.HasMemory()) {
+ it->second.ResourceValues.SetMemory(metrics.GetMemory());
+ }
+ if (metrics.HasNetwork()) {
+ it->second.ResourceValues.SetNetwork(metrics.GetNetwork());
+ }
+ if (metrics.HasStorage()) {
+ it->second.ResourceValues.SetStorage(metrics.GetStorage());
+ }
+ if (metrics.GroupReadThroughputSize() > 0) {
+ it->second.ResourceValues.ClearGroupReadThroughput();
+ for (const auto& v : metrics.GetGroupReadThroughput()) {
+ it->second.ResourceValues.AddGroupReadThroughput()->CopyFrom(v);
+ }
+ }
+ if (metrics.GroupWriteThroughputSize() > 0) {
+ it->second.ResourceValues.ClearGroupWriteThroughput();
+ for (const auto& v : metrics.GetGroupWriteThroughput()) {
+ it->second.ResourceValues.AddGroupWriteThroughput()->CopyFrom(v);
+ }
+ }
if (metrics.GroupReadIopsSize() > 0) {
it->second.ResourceValues.ClearGroupReadIops();
for (const auto& v : metrics.GetGroupReadIops()) {
@@ -537,129 +537,129 @@ class TLocalNodeRegistrar : public TActorBootstrapped<TLocalNodeRegistrar> {
it->second.ResourceValues.AddGroupWriteIops()->CopyFrom(v);
}
}
- auto after = it->second.ResourceValues.ByteSize();
- if (after == 0 && before == 0) {
- return;
- }
- auto uit = UpdatedTabletMetrics.find(tabletId);
- if (uit == UpdatedTabletMetrics.end()) {
- UpdatedTabletMetrics.emplace(tabletId, 1);
- } else {
- uit->second = 2;
- }
- if (Connected) {
- ScheduleSendTabletMetrics(ctx);
- }
- }
- }
-
- void Handle(TEvPrivate::TEvSendTabletMetrics::TPtr&, const TActorContext& ctx) {
- if (Connected) {
- TAutoPtr<TEvHive::TEvTabletMetrics> event = new TEvHive::TEvTabletMetrics;
- NKikimrHive::TEvTabletMetrics& record = event->Record;
- for (const auto& prTabletId : UpdatedTabletMetrics) {
- AddTabletMetrics(prTabletId.first, record);
- }
- if (UserPoolUsage != 0) {
- record.MutableTotalResourceUsage()->SetCPU(UserPoolUsage);
- }
- if (MemUsage != 0) {
- record.MutableTotalResourceUsage()->SetMemory(MemUsage);
- }
- record.SetTotalNodeUsage(NodeUsage);
- NTabletPipe::SendData(ctx, HivePipeClient, event.Release());
- SendTabletMetricsTime = ctx.Now();
- } else {
- SendTabletMetricsInProgress = false;
- }
- }
-
- void ScheduleSendTabletMetrics(const TActorContext& ctx) {
- if (!SendTabletMetricsInProgress) {
- TDuration schedulePeriod = LastSendTabletMetricsDuration * 2 + TABLET_METRICS_BATCH_INTERVAL;
- schedulePeriod = Max(schedulePeriod, TABLET_METRICS_BATCH_INTERVAL);
- schedulePeriod = Min(schedulePeriod, TDuration::Seconds(60));
- ctx.Schedule(schedulePeriod, new TEvPrivate::TEvSendTabletMetrics());
- SendTabletMetricsInProgress = true;
- }
- }
-
- void AddTabletMetrics(TTabletId tabletId, NKikimrHive::TEvTabletMetrics& record) {
- auto it = OnlineTablets.find(tabletId);
- if (it != OnlineTablets.end()) {
- TOnlineTabletEntry& tablet = it->second;
- auto& metrics = *record.AddTabletMetrics();
- metrics.SetTabletID(tabletId.first);
+ auto after = it->second.ResourceValues.ByteSize();
+ if (after == 0 && before == 0) {
+ return;
+ }
+ auto uit = UpdatedTabletMetrics.find(tabletId);
+ if (uit == UpdatedTabletMetrics.end()) {
+ UpdatedTabletMetrics.emplace(tabletId, 1);
+ } else {
+ uit->second = 2;
+ }
+ if (Connected) {
+ ScheduleSendTabletMetrics(ctx);
+ }
+ }
+ }
+
+ void Handle(TEvPrivate::TEvSendTabletMetrics::TPtr&, const TActorContext& ctx) {
+ if (Connected) {
+ TAutoPtr<TEvHive::TEvTabletMetrics> event = new TEvHive::TEvTabletMetrics;
+ NKikimrHive::TEvTabletMetrics& record = event->Record;
+ for (const auto& prTabletId : UpdatedTabletMetrics) {
+ AddTabletMetrics(prTabletId.first, record);
+ }
+ if (UserPoolUsage != 0) {
+ record.MutableTotalResourceUsage()->SetCPU(UserPoolUsage);
+ }
+ if (MemUsage != 0) {
+ record.MutableTotalResourceUsage()->SetMemory(MemUsage);
+ }
+ record.SetTotalNodeUsage(NodeUsage);
+ NTabletPipe::SendData(ctx, HivePipeClient, event.Release());
+ SendTabletMetricsTime = ctx.Now();
+ } else {
+ SendTabletMetricsInProgress = false;
+ }
+ }
+
+ void ScheduleSendTabletMetrics(const TActorContext& ctx) {
+ if (!SendTabletMetricsInProgress) {
+ TDuration schedulePeriod = LastSendTabletMetricsDuration * 2 + TABLET_METRICS_BATCH_INTERVAL;
+ schedulePeriod = Max(schedulePeriod, TABLET_METRICS_BATCH_INTERVAL);
+ schedulePeriod = Min(schedulePeriod, TDuration::Seconds(60));
+ ctx.Schedule(schedulePeriod, new TEvPrivate::TEvSendTabletMetrics());
+ SendTabletMetricsInProgress = true;
+ }
+ }
+
+ void AddTabletMetrics(TTabletId tabletId, NKikimrHive::TEvTabletMetrics& record) {
+ auto it = OnlineTablets.find(tabletId);
+ if (it != OnlineTablets.end()) {
+ TOnlineTabletEntry& tablet = it->second;
+ auto& metrics = *record.AddTabletMetrics();
+ metrics.SetTabletID(tabletId.first);
metrics.SetFollowerID(tabletId.second);
- metrics.MutableResourceUsage()->MergeFrom(tablet.ResourceValues);
- }
- }
-
- void Handle(TEvLocal::TEvTabletMetricsAck::TPtr& ev, const TActorContext& ctx) {
- TEvLocal::TEvTabletMetricsAck* msg = ev->Get();
- auto size = msg->Record.TabletIdSize();
+ metrics.MutableResourceUsage()->MergeFrom(tablet.ResourceValues);
+ }
+ }
+
+ void Handle(TEvLocal::TEvTabletMetricsAck::TPtr& ev, const TActorContext& ctx) {
+ TEvLocal::TEvTabletMetricsAck* msg = ev->Get();
+ auto size = msg->Record.TabletIdSize();
Y_VERIFY(msg->Record.FollowerIdSize() == size);
- for (decltype(size) i = 0; i < size; ++i) {
+ for (decltype(size) i = 0; i < size; ++i) {
TTabletId tabletId(msg->Record.GetTabletId(i), msg->Record.GetFollowerId(i));
- auto uit = UpdatedTabletMetrics.find(tabletId);
- if (uit != UpdatedTabletMetrics.end() && --uit->second == 0) {
- UpdatedTabletMetrics.erase(uit);
- auto it = OnlineTablets.find(tabletId);
- if (it != OnlineTablets.end()) {
- TOnlineTabletEntry& tablet = it->second;
- tablet.ResourceValues.Clear();
- }
- }
- }
- LastSendTabletMetricsDuration = ctx.Now() - SendTabletMetricsTime;
- SendTabletMetricsInProgress = false;
- if (!UpdatedTabletMetrics.empty()) {
- ScheduleSendTabletMetrics(ctx);
- }
- }
-
- void Handle(TEvPrivate::TEvUpdateSystemUsage::TPtr&, const TActorContext&) {
- Send(NNodeWhiteboard::MakeNodeWhiteboardServiceId(SelfId().NodeId()), new NNodeWhiteboard::TEvWhiteboard::TEvSystemStateRequest());
- Schedule(UPDATE_SYSTEM_USAGE_INTERVAL, new TEvPrivate::TEvUpdateSystemUsage());
- }
-
- void Handle(NNodeWhiteboard::TEvWhiteboard::TEvSystemStateResponse::TPtr& ev, const TActorContext& ctx) {
- const NKikimrWhiteboard::TEvSystemStateResponse& record = ev->Get()->Record;
- if (!record.GetSystemStateInfo().empty()) {
- const NKikimrWhiteboard::TSystemStateInfo& info = record.GetSystemStateInfo(0);
- if (static_cast<ui32>(info.PoolStatsSize()) > AppData()->UserPoolId) {
- const auto& poolStats(info.GetPoolStats(AppData()->UserPoolId));
- UserPoolUsage = poolStats.usage() * poolStats.threads() * 1000000; // uS
- }
+ auto uit = UpdatedTabletMetrics.find(tabletId);
+ if (uit != UpdatedTabletMetrics.end() && --uit->second == 0) {
+ UpdatedTabletMetrics.erase(uit);
+ auto it = OnlineTablets.find(tabletId);
+ if (it != OnlineTablets.end()) {
+ TOnlineTabletEntry& tablet = it->second;
+ tablet.ResourceValues.Clear();
+ }
+ }
+ }
+ LastSendTabletMetricsDuration = ctx.Now() - SendTabletMetricsTime;
+ SendTabletMetricsInProgress = false;
+ if (!UpdatedTabletMetrics.empty()) {
+ ScheduleSendTabletMetrics(ctx);
+ }
+ }
+
+ void Handle(TEvPrivate::TEvUpdateSystemUsage::TPtr&, const TActorContext&) {
+ Send(NNodeWhiteboard::MakeNodeWhiteboardServiceId(SelfId().NodeId()), new NNodeWhiteboard::TEvWhiteboard::TEvSystemStateRequest());
+ Schedule(UPDATE_SYSTEM_USAGE_INTERVAL, new TEvPrivate::TEvUpdateSystemUsage());
+ }
+
+ void Handle(NNodeWhiteboard::TEvWhiteboard::TEvSystemStateResponse::TPtr& ev, const TActorContext& ctx) {
+ const NKikimrWhiteboard::TEvSystemStateResponse& record = ev->Get()->Record;
+ if (!record.GetSystemStateInfo().empty()) {
+ const NKikimrWhiteboard::TSystemStateInfo& info = record.GetSystemStateInfo(0);
+ if (static_cast<ui32>(info.PoolStatsSize()) > AppData()->UserPoolId) {
+ const auto& poolStats(info.GetPoolStats(AppData()->UserPoolId));
+ UserPoolUsage = poolStats.usage() * poolStats.threads() * 1000000; // uS
+ }
if (info.HasMemoryUsedInAlloc()) {
MemUsage = info.GetMemoryUsedInAlloc();
- }
- /*if (info.HasMemoryUsed()) {
- MemUsage = info.GetMemoryUsed();
- }*/
-
- double usage = 0;
-
- if (info.HasMemoryLimit()) {
- if (MemLimit != info.GetMemoryLimit()) {
- MemLimit = info.GetMemoryLimit();
- LOG_DEBUG_S(ctx, NKikimrServices::LOCAL, "TLocalNodeRegistrar MemoryLimit changed");
- if (Connected) {
- SendStatusOk(ctx);
- }
- }
- usage = static_cast<double>(MemUsage) / MemLimit;
- }
- for (const auto& poolInfo : info.poolstats()) {
- usage = std::max(usage, poolInfo.usage());
- }
-
- NodeUsage = usage;
-
- ScheduleSendTabletMetrics(ctx);
- }
- }
-
+ }
+ /*if (info.HasMemoryUsed()) {
+ MemUsage = info.GetMemoryUsed();
+ }*/
+
+ double usage = 0;
+
+ if (info.HasMemoryLimit()) {
+ if (MemLimit != info.GetMemoryLimit()) {
+ MemLimit = info.GetMemoryLimit();
+ LOG_DEBUG_S(ctx, NKikimrServices::LOCAL, "TLocalNodeRegistrar MemoryLimit changed");
+ if (Connected) {
+ SendStatusOk(ctx);
+ }
+ }
+ usage = static_cast<double>(MemUsage) / MemLimit;
+ }
+ for (const auto& poolInfo : info.poolstats()) {
+ usage = std::max(usage, poolInfo.usage());
+ }
+
+ NodeUsage = usage;
+
+ ScheduleSendTabletMetrics(ctx);
+ }
+ }
+
void Handle(TEvLocal::TEvAlterTenant::TPtr &ev, const TActorContext &ctx) {
auto &info = ev->Get()->TenantInfo;
ResourceLimit = info.ResourceLimit;
@@ -672,19 +672,19 @@ class TLocalNodeRegistrar : public TActorBootstrapped<TLocalNodeRegistrar> {
SendStatusOk(ctx);
}
- void MarkRunningTablet(TTabletId tabletId, ui32 generation, const TActorContext& ctx) {
- auto inbootIt = InbootTablets.find(tabletId);
- if (inbootIt == InbootTablets.end())
- return;
- LOG_DEBUG_S(ctx, NKikimrServices::LOCAL, "TLocalNodeRegistrar: tablet "
- << tabletId
- << " marked as running at generation "
- << generation);
- NTabletPipe::SendData(ctx, HivePipeClient, new TEvLocal::TEvTabletStatus(TEvLocal::TEvTabletStatus::StatusOk, tabletId, generation));
- OnlineTablets.emplace(tabletId, inbootIt->second);
- InbootTablets.erase(inbootIt);
- }
-
+ void MarkRunningTablet(TTabletId tabletId, ui32 generation, const TActorContext& ctx) {
+ auto inbootIt = InbootTablets.find(tabletId);
+ if (inbootIt == InbootTablets.end())
+ return;
+ LOG_DEBUG_S(ctx, NKikimrServices::LOCAL, "TLocalNodeRegistrar: tablet "
+ << tabletId
+ << " marked as running at generation "
+ << generation);
+ NTabletPipe::SendData(ctx, HivePipeClient, new TEvLocal::TEvTabletStatus(TEvLocal::TEvTabletStatus::StatusOk, tabletId, generation));
+ OnlineTablets.emplace(tabletId, inbootIt->second);
+ InbootTablets.erase(inbootIt);
+ }
+
void Handle(TEvTablet::TEvRestored::TPtr &ev, const TActorContext &ctx) {
TEvTablet::TEvRestored *msg = ev->Get();
@@ -693,41 +693,41 @@ class TLocalNodeRegistrar : public TActorBootstrapped<TLocalNodeRegistrar> {
CounterRestored->Inc(); // always update counter for every tablet, even non-actual one. it's about tracking not resource allocation
- const auto tabletId = msg->TabletID;
- LOG_DEBUG_S(ctx, NKikimrServices::LOCAL, "TLocalNodeRegistrar: Handle TEvTablet::TEvRestored tablet "
- << tabletId
- << " generation "
- << msg->Generation);
- auto inbootIt = std::find_if(InbootTablets.begin(), InbootTablets.end(), [&](const auto& pr) -> bool {
- return pr.second.Tablet == ev->Sender;
- });
+ const auto tabletId = msg->TabletID;
+ LOG_DEBUG_S(ctx, NKikimrServices::LOCAL, "TLocalNodeRegistrar: Handle TEvTablet::TEvRestored tablet "
+ << tabletId
+ << " generation "
+ << msg->Generation);
+ auto inbootIt = std::find_if(InbootTablets.begin(), InbootTablets.end(), [&](const auto& pr) -> bool {
+ return pr.second.Tablet == ev->Sender;
+ });
if (inbootIt == InbootTablets.end())
return;
TTabletEntry &entry = inbootIt->second;
- if (msg->Generation < entry.Generation) {
- LOG_WARN_S(ctx, NKikimrServices::LOCAL, "TLocalNodeRegistrar: Handle TEvTablet::TEvRestored tablet "
- << tabletId
- << " restored to generation "
- << msg->Generation
- << " but we waiting for generation "
- << entry.Generation
- << " - ignored");
- return;
- }
- MarkRunningTablet(inbootIt->first, msg->Generation, ctx);
- }
-
- void Handle(TEvTablet::TEvCutTabletHistory::TPtr &ev, const TActorContext &ctx) {
- if (Connected) // must be 'connected' check
- NTabletPipe::SendData(ctx, HivePipeClient, ev.Get()->Release().Release());
- }
-
+ if (msg->Generation < entry.Generation) {
+ LOG_WARN_S(ctx, NKikimrServices::LOCAL, "TLocalNodeRegistrar: Handle TEvTablet::TEvRestored tablet "
+ << tabletId
+ << " restored to generation "
+ << msg->Generation
+ << " but we waiting for generation "
+ << entry.Generation
+ << " - ignored");
+ return;
+ }
+ MarkRunningTablet(inbootIt->first, msg->Generation, ctx);
+ }
+
+ void Handle(TEvTablet::TEvCutTabletHistory::TPtr &ev, const TActorContext &ctx) {
+ if (Connected) // must be 'connected' check
+ NTabletPipe::SendData(ctx, HivePipeClient, ev.Get()->Release().Release());
+ }
+
void Handle(TEvTablet::TEvTabletDead::TPtr &ev, const TActorContext &ctx) {
TEvTablet::TEvTabletDead *msg = ev->Get();
- const auto tabletId = msg->TabletID;
+ const auto tabletId = msg->TabletID;
const ui32 generation = msg->Generation;
- LOG_DEBUG_S(ctx, NKikimrServices::LOCAL, "TLocalNodeRegistrar: Handle TEvTablet::TEvTabletDead tabletId:"
- << tabletId << " generation:" << generation << " reason:" << (ui32)msg->Reason);
+ LOG_DEBUG_S(ctx, NKikimrServices::LOCAL, "TLocalNodeRegistrar: Handle TEvTablet::TEvTabletDead tabletId:"
+ << tabletId << " generation:" << generation << " reason:" << (ui32)msg->Reason);
switch (msg->Reason) {
case TEvTablet::TEvTabletDead::ReasonBootLocked:
@@ -772,21 +772,21 @@ class TLocalNodeRegistrar : public TActorBootstrapped<TLocalNodeRegistrar> {
}
// known tablets should be in online-tablets or in inboot-tablets (with correct generation).
- auto onlineIt = std::find_if(OnlineTablets.begin(), OnlineTablets.end(), [&](const auto& pr) -> bool {
- return pr.second.Tablet == ev->Sender;
- });
- if (onlineIt != OnlineTablets.end()) { // from online list
- MarkDeadTablet(onlineIt->first, generation, TEvLocal::TEvTabletStatus::StatusFailed, msg->Reason, ctx);
+ auto onlineIt = std::find_if(OnlineTablets.begin(), OnlineTablets.end(), [&](const auto& pr) -> bool {
+ return pr.second.Tablet == ev->Sender;
+ });
+ if (onlineIt != OnlineTablets.end()) { // from online list
+ MarkDeadTablet(onlineIt->first, generation, TEvLocal::TEvTabletStatus::StatusFailed, msg->Reason, ctx);
OnlineTablets.erase(onlineIt);
UpdateEstimate();
return;
}
- auto inbootIt = std::find_if(InbootTablets.begin(), InbootTablets.end(), [&](const auto& pr) -> bool {
- return pr.second.Tablet == ev->Sender;
- });
+ auto inbootIt = std::find_if(InbootTablets.begin(), InbootTablets.end(), [&](const auto& pr) -> bool {
+ return pr.second.Tablet == ev->Sender;
+ });
if (inbootIt != InbootTablets.end() && inbootIt->second.Generation <= generation) {
- MarkDeadTablet(inbootIt->first, generation, TEvLocal::TEvTabletStatus::StatusBootFailed, msg->Reason, ctx);
+ MarkDeadTablet(inbootIt->first, generation, TEvLocal::TEvTabletStatus::StatusBootFailed, msg->Reason, ctx);
InbootTablets.erase(inbootIt);
return;
}
@@ -870,7 +870,7 @@ public:
, Connected(false)
, Config(config)
, HiveGeneration(0)
- , SendTabletMetricsInProgress(false)
+ , SendTabletMetricsInProgress(false)
, ResourceLimit(resourceLimit)
, Counters(counters)
{
@@ -900,34 +900,34 @@ public:
void Bootstrap(const TActorContext &ctx) {
LOG_DEBUG(ctx, NKikimrServices::LOCAL, "TLocalNodeRegistrar::Bootstrap");
- Send(SelfId(), new TEvPrivate::TEvUpdateSystemUsage());
- StartTime = ctx.Now();
+ Send(SelfId(), new TEvPrivate::TEvUpdateSystemUsage());
+ StartTime = ctx.Now();
TryToRegister(ctx);
- Become(&TThis::StateWork);
+ Become(&TThis::StateWork);
}
STFUNC(StateWork) {
switch (ev->GetTypeRewrite()) {
HFunc(TEvTablet::TEvRestored, Handle); // tablet restored, notify queue about update
HFunc(TEvTablet::TEvTabletDead, Handle); // tablet dead, notify queue about update
- HFunc(TEvTablet::TEvCutTabletHistory, Handle);
+ HFunc(TEvTablet::TEvCutTabletHistory, Handle);
HFunc(TEvLocal::TEvBootTablet, Handle); // command to boot tablet
HFunc(TEvLocal::TEvPing, Handle); // command to update link to per-local boot-queue
HFunc(TEvLocal::TEvStopTablet, Handle); // stop tablet
HFunc(TEvLocal::TEvDeadTabletAck, Handle);
HFunc(TEvLocal::TEvEnumerateTablets, Handle);
- HFunc(TEvLocal::TEvTabletMetrics, Handle);
- HFunc(TEvLocal::TEvTabletMetricsAck, Handle);
+ HFunc(TEvLocal::TEvTabletMetrics, Handle);
+ HFunc(TEvLocal::TEvTabletMetricsAck, Handle);
HFunc(TEvLocal::TEvAlterTenant, Handle);
- HFunc(TEvLocal::TEvReconnect, Handle);
+ HFunc(TEvLocal::TEvReconnect, Handle);
HFunc(TEvTabletPipe::TEvClientConnected, Handle);
HFunc(TEvTabletPipe::TEvClientDestroyed, Handle);
- HFunc(TEvPrivate::TEvSendTabletMetrics, Handle);
- HFunc(TEvPrivate::TEvUpdateSystemUsage, Handle);
+ HFunc(TEvPrivate::TEvSendTabletMetrics, Handle);
+ HFunc(TEvPrivate::TEvUpdateSystemUsage, Handle);
HFunc(TEvPrivate::TEvLocalDrainTimeout, HandleDrainTimeout);
HFunc(TEvLocal::TEvLocalDrainNode, HandleDrain);
HFunc(TEvHive::TEvDrainNodeResult, HandleDrainNodeResult);
- HFunc(NNodeWhiteboard::TEvWhiteboard::TEvSystemStateResponse, Handle);
+ HFunc(NNodeWhiteboard::TEvWhiteboard::TEvSystemStateResponse, Handle);
CFunc(TEvents::TSystem::PoisonPill, HandlePoison);
default:
LOG_DEBUG(ctx, NKikimrServices::LOCAL, "TLocalNodeRegistrar: Unhandled in StateWork type: %" PRIx32
@@ -956,7 +956,7 @@ class TDomainLocal : public TActorBootstrapped<TDomainLocal> {
TRegistrationInfo Info;
TVector<TActorId> Locals;
TActorId Subscriber;
- TVector<TTabletId> HiveIds;
+ TVector<TTabletId> HiveIds;
THashMap<TString, TString> Attributes;
TSubDomainKey DomainKey;
};
@@ -1078,7 +1078,7 @@ class TDomainLocal : public TActorBootstrapped<TDomainLocal> {
void RegisterAsSubDomain(const NKikimrScheme::TEvDescribeSchemeResult &rec,
const TResolveTask &task,
- const TVector<TTabletId> hiveIds,
+ const TVector<TTabletId> hiveIds,
const TActorContext &ctx)
{
const auto &domainDesc = rec.GetPathDescription().GetDomainDescription();
@@ -1090,12 +1090,12 @@ class TDomainLocal : public TActorBootstrapped<TDomainLocal> {
info.Attributes.emplace(std::make_pair(attr.GetKey(), attr.GetValue()));
RunningTenants.emplace(std::make_pair(task.Info.TenantName, info));
const TActorId whiteboardServiceId(NNodeWhiteboard::MakeNodeWhiteboardServiceId(SelfId().NodeId()));
- Send(whiteboardServiceId, new NNodeWhiteboard::TEvWhiteboard::TEvSystemStateAddRole("Tenant"));
- Send(whiteboardServiceId, new NNodeWhiteboard::TEvWhiteboard::TEvSystemStateSetTenant(task.Info.TenantName));
- for (TTabletId hId : hiveIds) {
+ Send(whiteboardServiceId, new NNodeWhiteboard::TEvWhiteboard::TEvSystemStateAddRole("Tenant"));
+ Send(whiteboardServiceId, new NNodeWhiteboard::TEvWhiteboard::TEvSystemStateSetTenant(task.Info.TenantName));
+ for (TTabletId hId : hiveIds) {
LOG_DEBUG_S(ctx, NKikimrServices::LOCAL,
LogPrefix << "Binding tenant " << task.Info.TenantName
- << " to hive " << hId
+ << " to hive " << hId
<< " (allocated resources: " << task.Info.ResourceLimit.ShortDebugString() << ")");
RegisterLocalNode(task.Info.TenantName, task.Info.ResourceLimit, hId, {domainKey}, ctx);
}
@@ -1105,21 +1105,21 @@ class TDomainLocal : public TActorBootstrapped<TDomainLocal> {
{
LOG_DEBUG_S(ctx, NKikimrServices::LOCAL, LogPrefix << "HandlePoison");
- for (auto &pr : RunningTenants) {
+ for (auto &pr : RunningTenants) {
for (auto aid : pr.second.Locals) {
LOG_DEBUG_S(ctx, NKikimrServices::LOCAL,
LogPrefix << "Send poison pill to local of " << pr.second.Info.TenantName);
ctx.Send(aid, new TEvents::TEvPoisonPill);
}
- if (pr.second.Subscriber) {
- LOG_DEBUG_S(ctx, NKikimrServices::LOCAL,
- LogPrefix << "Send poison pill to scheme subscriber of " << pr.second.Info.TenantName);
- ctx.Send(pr.second.Subscriber, new TEvents::TEvPoisonPill);
+ if (pr.second.Subscriber) {
+ LOG_DEBUG_S(ctx, NKikimrServices::LOCAL,
+ LogPrefix << "Send poison pill to scheme subscriber of " << pr.second.Info.TenantName);
+ ctx.Send(pr.second.Subscriber, new TEvents::TEvPoisonPill);
pr.second.Subscriber = TActorId();
- }
- ctx.Send(NNodeWhiteboard::MakeNodeWhiteboardServiceId(ctx.SelfID.NodeId()),
- new NNodeWhiteboard::TEvWhiteboard::TEvSystemStateRemoveTenant(pr.first));
- }
+ }
+ ctx.Send(NNodeWhiteboard::MakeNodeWhiteboardServiceId(ctx.SelfID.NodeId()),
+ new NNodeWhiteboard::TEvWhiteboard::TEvSystemStateRemoveTenant(pr.first));
+ }
ClosePipe(ctx);
Die(ctx);
@@ -1199,67 +1199,67 @@ class TDomainLocal : public TActorBootstrapped<TDomainLocal> {
Y_VERIFY(rec.GetPathDescription().HasDomainDescription());
Y_VERIFY(rec.GetPathDescription().GetDomainDescription().GetDomainKey().GetSchemeShard() == SchemeRoot);
- TVector<TTabletId> hiveIds(HiveIds);
- TString path = rec.GetPath();
-
- TTabletId hiveId = rec.GetPathDescription().GetDomainDescription().GetProcessingParams().GetHive();
- if (hiveId) {
- hiveIds.emplace_back(hiveId);
- }
- RegisterAsSubDomain(rec, task, hiveIds, ctx);
-
- auto itTenant = RunningTenants.find(path);
- if (itTenant != RunningTenants.end()) {
- TTenantInfo& tenant = itTenant->second;
-
- tenant.HiveIds = hiveIds;
-
- SendStatus(rec.GetPath(), task.Senders, ctx);
- ResolveTasks.erase(rec.GetPath());
-
- // subscribe for schema updates
- const auto& domains = *AppData()->DomainsInfo;
- const ui32 domainId = domains.GetDomainUidByTabletId(rec.GetPathDescription().GetSelf().GetSchemeshardId());
- const ui32 boardSSId = domains.GetDomain(domainId).DefaultSchemeBoardGroup;
-
+ TVector<TTabletId> hiveIds(HiveIds);
+ TString path = rec.GetPath();
+
+ TTabletId hiveId = rec.GetPathDescription().GetDomainDescription().GetProcessingParams().GetHive();
+ if (hiveId) {
+ hiveIds.emplace_back(hiveId);
+ }
+ RegisterAsSubDomain(rec, task, hiveIds, ctx);
+
+ auto itTenant = RunningTenants.find(path);
+ if (itTenant != RunningTenants.end()) {
+ TTenantInfo& tenant = itTenant->second;
+
+ tenant.HiveIds = hiveIds;
+
+ SendStatus(rec.GetPath(), task.Senders, ctx);
+ ResolveTasks.erase(rec.GetPath());
+
+ // subscribe for schema updates
+ const auto& domains = *AppData()->DomainsInfo;
+ const ui32 domainId = domains.GetDomainUidByTabletId(rec.GetPathDescription().GetSelf().GetSchemeshardId());
+ const ui32 boardSSId = domains.GetDomain(domainId).DefaultSchemeBoardGroup;
+
THolder<IActor> subscriber(CreateSchemeBoardSubscriber(SelfId(), path, boardSSId, ESchemeBoardSubscriberDeletionPolicy::Majority));
- tenant.Subscriber = Register(subscriber.Release());
- } else {
- LOG_WARN_S(ctx, NKikimrServices::LOCAL,
- LogPrefix << " Local tenant info not found, requested path " << task.Info.DomainName);
- }
- }
-
- void HandleSchemeBoard(TSchemeBoardEvents::TEvNotifyUpdate::TPtr &ev, const TActorContext &ctx)
- {
- TString path = ev->Get()->DescribeSchemeResult.GetPath();
- auto itTenant = RunningTenants.find(path);
- if (itTenant != RunningTenants.end()) {
- TTenantInfo& tenant = itTenant->second;
- TTabletId hiveId = ev->Get()->DescribeSchemeResult.GetPathDescription().GetDomainDescription().GetProcessingParams().GetHive();
- if (hiveId) {
- auto itHiveId = Find(tenant.HiveIds, hiveId);
- if (itHiveId == tenant.HiveIds.end()) {
- const auto &domainDesc = ev->Get()->DescribeSchemeResult.GetPathDescription().GetDomainDescription();
- TVector<TSubDomainKey> servicedDomains = {TSubDomainKey(domainDesc.GetDomainKey())};
-
- LOG_DEBUG_S(ctx, NKikimrServices::LOCAL,
- LogPrefix << "Binding tenant " << tenant.Info.TenantName
- << " to hive " << hiveId
- << " (allocated resources: " << tenant.Info.ResourceLimit.ShortDebugString() << ")");
- RegisterLocalNode(tenant.Info.TenantName, tenant.Info.ResourceLimit, hiveId, servicedDomains, ctx);
- tenant.HiveIds.emplace_back(hiveId);
- }
- }
- }
- }
-
- void HandleSchemeBoard(TSchemeBoardEvents::TEvNotifyDelete::TPtr &ev, const TActorContext &ctx)
- {
- Y_UNUSED(ev);
- Y_UNUSED(ctx);
- }
-
+ tenant.Subscriber = Register(subscriber.Release());
+ } else {
+ LOG_WARN_S(ctx, NKikimrServices::LOCAL,
+ LogPrefix << " Local tenant info not found, requested path " << task.Info.DomainName);
+ }
+ }
+
+ void HandleSchemeBoard(TSchemeBoardEvents::TEvNotifyUpdate::TPtr &ev, const TActorContext &ctx)
+ {
+ TString path = ev->Get()->DescribeSchemeResult.GetPath();
+ auto itTenant = RunningTenants.find(path);
+ if (itTenant != RunningTenants.end()) {
+ TTenantInfo& tenant = itTenant->second;
+ TTabletId hiveId = ev->Get()->DescribeSchemeResult.GetPathDescription().GetDomainDescription().GetProcessingParams().GetHive();
+ if (hiveId) {
+ auto itHiveId = Find(tenant.HiveIds, hiveId);
+ if (itHiveId == tenant.HiveIds.end()) {
+ const auto &domainDesc = ev->Get()->DescribeSchemeResult.GetPathDescription().GetDomainDescription();
+ TVector<TSubDomainKey> servicedDomains = {TSubDomainKey(domainDesc.GetDomainKey())};
+
+ LOG_DEBUG_S(ctx, NKikimrServices::LOCAL,
+ LogPrefix << "Binding tenant " << tenant.Info.TenantName
+ << " to hive " << hiveId
+ << " (allocated resources: " << tenant.Info.ResourceLimit.ShortDebugString() << ")");
+ RegisterLocalNode(tenant.Info.TenantName, tenant.Info.ResourceLimit, hiveId, servicedDomains, ctx);
+ tenant.HiveIds.emplace_back(hiveId);
+ }
+ }
+ }
+ }
+
+ void HandleSchemeBoard(TSchemeBoardEvents::TEvNotifyDelete::TPtr &ev, const TActorContext &ctx)
+ {
+ Y_UNUSED(ev);
+ Y_UNUSED(ctx);
+ }
+
void HandleTenant(TEvLocal::TEvAddTenant::TPtr &ev, const TActorContext &ctx)
{
auto &info = ev->Get()->TenantInfo;
@@ -1304,12 +1304,12 @@ class TDomainLocal : public TActorBootstrapped<TDomainLocal> {
if (it != RunningTenants.end()) {
for (auto aid : it->second.Locals)
ctx.Send(aid, new TEvents::TEvPoisonPill());
- if (it->second.Subscriber) {
- ctx.Send(it->second.Subscriber, new TEvents::TEvPoisonPill());
+ if (it->second.Subscriber) {
+ ctx.Send(it->second.Subscriber, new TEvents::TEvPoisonPill());
it->second.Subscriber = TActorId();
- }
- ctx.Send(NNodeWhiteboard::MakeNodeWhiteboardServiceId(ctx.SelfID.NodeId()),
- new NNodeWhiteboard::TEvWhiteboard::TEvSystemStateRemoveTenant(it->first));
+ }
+ ctx.Send(NNodeWhiteboard::MakeNodeWhiteboardServiceId(ctx.SelfID.NodeId()),
+ new NNodeWhiteboard::TEvWhiteboard::TEvSystemStateRemoveTenant(it->first));
RunningTenants.erase(it);
}
}
@@ -1357,7 +1357,7 @@ public:
for (auto hiveUid : domain.HiveUids)
HiveIds.push_back(domainsInfo.GetHive(hiveUid));
- PipeConfig.RetryPolicy = NTabletPipe::TClientRetryPolicy::WithRetries();
+ PipeConfig.RetryPolicy = NTabletPipe::TClientRetryPolicy::WithRetries();
LogPrefix = Sprintf("TDomainLocal(%s): ", Domain.data());
}
@@ -1382,9 +1382,9 @@ public:
HFunc(TEvLocal::TEvRemoveTenant, HandleTenant);
HFunc(TEvLocal::TEvAlterTenant, HandleTenant);
- HFunc(TSchemeBoardEvents::TEvNotifyUpdate, HandleSchemeBoard);
- HFunc(TSchemeBoardEvents::TEvNotifyDelete, HandleSchemeBoard);
-
+ HFunc(TSchemeBoardEvents::TEvNotifyUpdate, HandleSchemeBoard);
+ HFunc(TSchemeBoardEvents::TEvNotifyDelete, HandleSchemeBoard);
+
HFunc(TEvLocal::TEvLocalDrainNode, HandleDrain);
default:
Y_FAIL("Unexpected event for TDomainLocal");
diff --git a/ydb/core/mind/local.h b/ydb/core/mind/local.h
index 4673863ad81..05c9bdc48eb 100644
--- a/ydb/core/mind/local.h
+++ b/ydb/core/mind/local.h
@@ -76,14 +76,14 @@ struct TEvLocal {
EvStopTablet, // must be here
EvDeadTabletAck,
EvEnumerateTablets,
- EvSyncTablets,
- EvTabletMetrics,
- EvReconnect,
+ EvSyncTablets,
+ EvTabletMetrics,
+ EvReconnect,
EvStatus = EvRegisterNode + 512,
EvTabletStatus,
EvEnumerateTabletsResult,
- EvTabletMetricsAck,
+ EvTabletMetricsAck,
EvAddTenant = EvRegisterNode + 1024,
EvRemoveTenant,
@@ -98,7 +98,7 @@ struct TEvLocal {
static_assert(EvEnd < EventSpaceEnd(TKikimrEvents::ES_LOCAL),
"expect EvEnd < EventSpaceEnd(TKikimrEvents::ES_LOCAL)");
- struct TEvRegisterNode : public TEventPB<TEvRegisterNode, NKikimrLocal::TEvRegisterNode, EvRegisterNode> {
+ struct TEvRegisterNode : public TEventPB<TEvRegisterNode, NKikimrLocal::TEvRegisterNode, EvRegisterNode> {
TEvRegisterNode()
{}
@@ -107,7 +107,7 @@ struct TEvLocal {
}
};
- struct TEvPing : public TEventPB<TEvPing, NKikimrLocal::TEvPing, EvPing> {
+ struct TEvPing : public TEventPB<TEvPing, NKikimrLocal::TEvPing, EvPing> {
TEvPing()
{}
@@ -119,16 +119,16 @@ struct TEvLocal {
}
};
- struct TEvReconnect : TEventPB<TEvReconnect, NKikimrLocal::TEvReconnect, EvReconnect> {
- TEvReconnect() = default;
-
- TEvReconnect(ui64 hiveId, ui32 hiveGeneration) {
- Record.SetHiveId(hiveId);
- Record.SetHiveGeneration(hiveGeneration);
- }
- };
-
- struct TEvStatus : public TEventPB<TEvStatus, NKikimrLocal::TEvStatus, EvStatus> {
+ struct TEvReconnect : TEventPB<TEvReconnect, NKikimrLocal::TEvReconnect, EvReconnect> {
+ TEvReconnect() = default;
+
+ TEvReconnect(ui64 hiveId, ui32 hiveGeneration) {
+ Record.SetHiveId(hiveId);
+ Record.SetHiveGeneration(hiveGeneration);
+ }
+ };
+
+ struct TEvStatus : public TEventPB<TEvStatus, NKikimrLocal::TEvStatus, EvStatus> {
enum EStatus {
StatusOk,
StatusOutdated,
@@ -143,15 +143,15 @@ struct TEvLocal {
Record.SetStatus(status);
}
- TEvStatus(EStatus status, ui64 inbootTablets, ui64 onlineTablets, ui64 deadTablets) {
- Record.SetStatus(status);
- Record.SetInbootTablets(inbootTablets);
- Record.SetOnlineTablets(onlineTablets);
- Record.SetDeadTablets(deadTablets);
- }
+ TEvStatus(EStatus status, ui64 inbootTablets, ui64 onlineTablets, ui64 deadTablets) {
+ Record.SetStatus(status);
+ Record.SetInbootTablets(inbootTablets);
+ Record.SetOnlineTablets(onlineTablets);
+ Record.SetDeadTablets(deadTablets);
+ }
};
- struct TEvBootTablet : public TEventPB<TEvBootTablet, NKikimrLocal::TEvBootTablet, EvBootTablet> {
+ struct TEvBootTablet : public TEventPB<TEvBootTablet, NKikimrLocal::TEvBootTablet, EvBootTablet> {
TEvBootTablet()
{}
@@ -163,19 +163,19 @@ struct TEvLocal {
}
TEvBootTablet(const TTabletStorageInfo &info, ui32 followerId) {
- TabletStorageInfoToProto(info, Record.MutableInfo());
+ TabletStorageInfoToProto(info, Record.MutableInfo());
Record.SetBootMode(NKikimrLocal::BOOT_MODE_FOLLOWER);
Record.SetFollowerId(followerId);
- }
+ }
};
struct TEvStopTablet : public TEventPB<TEvStopTablet, NKikimrLocal::TEvStopTablet, EvStopTablet> {
TEvStopTablet()
{}
- TEvStopTablet(std::pair<ui64, ui32> tabletId)
+ TEvStopTablet(std::pair<ui64, ui32> tabletId)
{
- Record.SetTabletId(tabletId.first);
+ Record.SetTabletId(tabletId.first);
Record.SetFollowerId(tabletId.second);
}
};
@@ -184,15 +184,15 @@ struct TEvLocal {
TEvDeadTabletAck()
{}
- TEvDeadTabletAck(std::pair<ui64, ui32> tabletId, ui32 generation)
+ TEvDeadTabletAck(std::pair<ui64, ui32> tabletId, ui32 generation)
{
- Record.SetTabletId(tabletId.first);
+ Record.SetTabletId(tabletId.first);
Record.SetFollowerId(tabletId.second);
Record.SetGeneration(generation);
}
};
- struct TEvTabletStatus : public TEventPB<TEvTabletStatus, NKikimrLocal::TEvTabletStatus, EvTabletStatus> {
+ struct TEvTabletStatus : public TEventPB<TEvTabletStatus, NKikimrLocal::TEvTabletStatus, EvTabletStatus> {
enum EStatus {
StatusOk,
StatusBootFailed,
@@ -207,33 +207,33 @@ struct TEvLocal {
TEvTabletStatus()
{}
- TEvTabletStatus(EStatus status, TEvTablet::TEvTabletDead::EReason reason, std::pair<ui64, ui32> tabletId, ui32 generation) {
- Record.SetStatus(status);
- Record.SetReason(reason);
- Record.SetTabletID(tabletId.first);
- Record.SetFollowerId(tabletId.second);
- Record.SetGeneration(generation);
- }
-
- TEvTabletStatus(EStatus status, std::pair<ui64, ui32> tabletId, ui32 generation) {
+ TEvTabletStatus(EStatus status, TEvTablet::TEvTabletDead::EReason reason, std::pair<ui64, ui32> tabletId, ui32 generation) {
+ Record.SetStatus(status);
+ Record.SetReason(reason);
+ Record.SetTabletID(tabletId.first);
+ Record.SetFollowerId(tabletId.second);
+ Record.SetGeneration(generation);
+ }
+
+ TEvTabletStatus(EStatus status, std::pair<ui64, ui32> tabletId, ui32 generation) {
Record.SetStatus(status);
- Record.SetTabletID(tabletId.first);
+ Record.SetTabletID(tabletId.first);
Record.SetFollowerId(tabletId.second);
Record.SetGeneration(generation);
}
};
- struct TEvEnumerateTablets : public TEventPB<TEvEnumerateTablets, NKikimrLocal::TEvEnumerateTablets, EvEnumerateTablets> {
+ struct TEvEnumerateTablets : public TEventPB<TEvEnumerateTablets, NKikimrLocal::TEvEnumerateTablets, EvEnumerateTablets> {
TEvEnumerateTablets()
{}
- TEvEnumerateTablets(TTabletTypes::EType tabletType) {
- Record.SetTabletType(tabletType);
+ TEvEnumerateTablets(TTabletTypes::EType tabletType) {
+ Record.SetTabletType(tabletType);
}
};
- struct TEvEnumerateTabletsResult : public TEventPB<TEvEnumerateTabletsResult, NKikimrLocal::TEvEnumerateTabletsResult, EvEnumerateTabletsResult> {
+ struct TEvEnumerateTabletsResult : public TEventPB<TEvEnumerateTabletsResult, NKikimrLocal::TEvEnumerateTabletsResult, EvEnumerateTabletsResult> {
TEvEnumerateTabletsResult()
{}
@@ -241,26 +241,26 @@ struct TEvLocal {
Record.SetStatus(status);
}
};
-
- struct TEvSyncTablets : public TEventPB<TEvSyncTablets, NKikimrLocal::TEvSyncTablets, EvSyncTablets> {
- TEvSyncTablets()
- {}
- };
-
- struct TEvTabletMetrics : public TEventLocal<TEvTabletMetrics, EvTabletMetrics> {
- ui64 TabletId;
+
+ struct TEvSyncTablets : public TEventPB<TEvSyncTablets, NKikimrLocal::TEvSyncTablets, EvSyncTablets> {
+ TEvSyncTablets()
+ {}
+ };
+
+ struct TEvTabletMetrics : public TEventLocal<TEvTabletMetrics, EvTabletMetrics> {
+ ui64 TabletId;
ui32 FollowerId;
- NKikimrTabletBase::TMetrics ResourceValues;
-
+ NKikimrTabletBase::TMetrics ResourceValues;
+
TEvTabletMetrics(ui64 tabletId, ui32 followerId, const NKikimrTabletBase::TMetrics& resourceValues)
- : TabletId(tabletId)
+ : TabletId(tabletId)
, FollowerId(followerId)
- , ResourceValues(resourceValues)
- {}
- };
-
- struct TEvTabletMetricsAck : public TEventPB<TEvTabletMetricsAck, NKikimrLocal::TEvTabletMetricsAck, EvTabletMetricsAck> {
- };
+ , ResourceValues(resourceValues)
+ {}
+ };
+
+ struct TEvTabletMetricsAck : public TEventPB<TEvTabletMetricsAck, NKikimrLocal::TEvTabletMetricsAck, EvTabletMetricsAck> {
+ };
struct TEvAddTenant : public TEventLocal<TEvAddTenant, EvAddTenant> {
TRegistrationInfo TenantInfo;
@@ -311,7 +311,7 @@ struct TEvLocal {
TString TenantName;
EStatus Status;
- NKikimrTabletBase::TMetrics ResourceLimit;
+ NKikimrTabletBase::TMetrics ResourceLimit;
TString Error;
THashMap<TString, TString> Attributes;
TSubDomainKey DomainKey;
@@ -354,7 +354,7 @@ struct TLocalConfig : public TThrRefBase {
struct TTabletClassInfo {
TTabletSetupInfo::TPtr SetupInfo;
- ui64 MaxCount = 0; // maximum allowed number of running tablets, 0 means unlimited
+ ui64 MaxCount = 0; // maximum allowed number of running tablets, 0 means unlimited
TTabletClassInfo()
{}
diff --git a/ydb/core/mind/node_broker.h b/ydb/core/mind/node_broker.h
index f4a815439f2..c86edfe0e7a 100644
--- a/ydb/core/mind/node_broker.h
+++ b/ydb/core/mind/node_broker.h
@@ -105,27 +105,27 @@ struct TEvNodeBroker {
static_assert(EvEnd < EventSpaceEnd(TKikimrEvents::ES_NODE_BROKER),
"expect EvEnd < EventSpaceEnd(TKikimrEvents::ES_NODE_BROKER)");
- template <typename TEv, typename TRecord, ui32 TEventType>
- using TEventPB = TEventShortDebugPB<TEv, TRecord, TEventType>;
-
+ template <typename TEv, typename TRecord, ui32 TEventType>
+ using TEventPB = TEventShortDebugPB<TEv, TRecord, TEventType>;
+
struct TEvListNodes : public TEventPB<TEvListNodes,
NKikimrNodeBroker::TListNodes,
- EvListNodes> {
+ EvListNodes> {
};
struct TEvResolveNode : public TEventPB<TEvResolveNode,
NKikimrNodeBroker::TResolveNode,
- EvResolveNode> {
+ EvResolveNode> {
};
struct TEvRegistrationRequest : public TEventPB<TEvRegistrationRequest,
NKikimrNodeBroker::TRegistrationRequest,
- EvRegistrationRequest> {
+ EvRegistrationRequest> {
};
struct TEvExtendLeaseRequest : public TEventPB<TEvExtendLeaseRequest,
NKikimrNodeBroker::TExtendLeaseRequest,
- EvExtendLeaseRequest> {
+ EvExtendLeaseRequest> {
};
struct TEvNodesInfo : public TEventPreSerializedPB<TEvNodesInfo,
@@ -143,17 +143,17 @@ struct TEvNodeBroker {
struct TEvResolvedNode : public TEventPB<TEvResolvedNode,
NKikimrNodeBroker::TResolvedNode,
- EvResolvedNode> {
+ EvResolvedNode> {
};
struct TEvRegistrationResponse : public TEventPB<TEvRegistrationResponse,
NKikimrNodeBroker::TRegistrationResponse,
- EvRegistrationResponse> {
+ EvRegistrationResponse> {
};
struct TEvExtendLeaseResponse : public TEventPB<TEvExtendLeaseResponse,
NKikimrNodeBroker::TExtendLeaseResponse,
- EvExtendLeaseResponse> {
+ EvExtendLeaseResponse> {
};
struct TEvGetConfigRequest : public TEventPB<TEvGetConfigRequest,
diff --git a/ydb/core/mind/tenant_pool.cpp b/ydb/core/mind/tenant_pool.cpp
index e3730afadea..80236570b9e 100644
--- a/ydb/core/mind/tenant_pool.cpp
+++ b/ydb/core/mind/tenant_pool.cpp
@@ -163,10 +163,10 @@ public:
Y_VERIFY(!TenantSlotBroker.Pipe);
NTabletPipe::TClientConfig pipeConfig;
- pipeConfig.RetryPolicy = {
- .MinRetryTime = TDuration::MilliSeconds(10),
- .MaxRetryTime = TDuration::Seconds(1),
- };
+ pipeConfig.RetryPolicy = {
+ .MinRetryTime = TDuration::MilliSeconds(10),
+ .MaxRetryTime = TDuration::Seconds(1),
+ };
auto pipe = NTabletPipe::CreateClient(ctx.SelfID, TenantSlotBroker.TabletId, pipeConfig);
TenantSlotBroker.Pipe = ctx.ExecutorThread.RegisterActor(pipe);
diff --git a/ydb/core/mind/tenant_slot_broker.cpp b/ydb/core/mind/tenant_slot_broker.cpp
index 0649d12493a..65f7a86328b 100644
--- a/ydb/core/mind/tenant_slot_broker.cpp
+++ b/ydb/core/mind/tenant_slot_broker.cpp
@@ -1573,13 +1573,13 @@ void TTenantSlotBroker::FillTenantState(const TString &name,
allocation->Description.Serialize(pinned);
pinned.SetCount(allocation->PinnedCount);
}
-
- for (auto &slot : allocation->AssignedSlots) {
- const auto &slotId = slot->Id;
- auto &assigned = *state.AddAssignedSlots();
- assigned.SetNodeId(slotId.NodeId);
- assigned.SetSlotId(slotId.SlotId);
- }
+
+ for (auto &slot : allocation->AssignedSlots) {
+ const auto &slotId = slot->Id;
+ auto &assigned = *state.AddAssignedSlots();
+ assigned.SetNodeId(slotId.NodeId);
+ assigned.SetSlotId(slotId.SlotId);
+ }
}
}
}
diff --git a/ydb/core/mind/ut_fat/blobstorage_node_warden_ut_fat.cpp b/ydb/core/mind/ut_fat/blobstorage_node_warden_ut_fat.cpp
index 00f11cac621..011f03d93cd 100644
--- a/ydb/core/mind/ut_fat/blobstorage_node_warden_ut_fat.cpp
+++ b/ydb/core/mind/ut_fat/blobstorage_node_warden_ut_fat.cpp
@@ -25,11 +25,11 @@
#include <library/cpp/testing/unittest/registar.h>
const bool STRAND_PDISK = true;
-#ifndef NDEBUG
-const bool ENABLE_DETAILED_HIVE_LOG = true;
-#else
+#ifndef NDEBUG
+const bool ENABLE_DETAILED_HIVE_LOG = true;
+#else
const bool ENABLE_DETAILED_HIVE_LOG = false;
-#endif
+#endif
namespace NKikimr {
@@ -96,12 +96,12 @@ void SetupLogging(TTestActorRuntime& runtime) {
runtime.SetLogPriority(NKikimrServices::TABLET_MAIN, otherPriority);
runtime.SetLogPriority(NKikimrServices::TABLET_EXECUTOR, otherPriority);
runtime.SetLogPriority(NKikimrServices::BS_PROXY, otherPriority);
- runtime.SetLogPriority(NKikimrServices::PIPE_CLIENT, otherPriority);
- runtime.SetLogPriority(NKikimrServices::TABLET_RESOLVER, otherPriority);
+ runtime.SetLogPriority(NKikimrServices::PIPE_CLIENT, otherPriority);
+ runtime.SetLogPriority(NKikimrServices::TABLET_RESOLVER, otherPriority);
- runtime.SetLogPriority(NKikimrServices::BS_SKELETON, otherPriority);
- runtime.SetLogPriority(NKikimrServices::BS_SYNCJOB, otherPriority);
- runtime.SetLogPriority(NKikimrServices::BS_SYNCER, otherPriority);
+ runtime.SetLogPriority(NKikimrServices::BS_SKELETON, otherPriority);
+ runtime.SetLogPriority(NKikimrServices::BS_SYNCJOB, otherPriority);
+ runtime.SetLogPriority(NKikimrServices::BS_SYNCER, otherPriority);
}
void SetupServices(TTestActorRuntime &runtime) {
@@ -132,7 +132,7 @@ void SetupServices(TTestActorRuntime &runtime) {
TChannelProfiles::TProfile &profile = channelProfiles->Profiles.back();
for (ui32 channelIdx = 0; channelIdx < 3; ++channelIdx) {
profile.Channels.push_back(
- TChannelProfiles::TProfile::TChannel(TBlobStorageGroupType::ErasureMirror3, 0, NKikimrBlobStorage::TVDiskKind::Default));
+ TChannelProfiles::TProfile::TChannel(TBlobStorageGroupType::ErasureMirror3, 0, NKikimrBlobStorage::TVDiskKind::Default));
}
app.SetChannels(std::move(channelProfiles));
}
@@ -230,8 +230,8 @@ void SetupServices(TTestActorRuntime &runtime) {
ui64 defaultStateStorageGroup = runtime.GetAppData(0).DomainsInfo->GetDefaultStateStorageGroup(DOMAIN_ID);
CreateTestBootstrapper(runtime, CreateTestTabletInfo(MakeBSControllerID(defaultStateStorageGroup),
- TTabletTypes::FLAT_BS_CONTROLLER, TBlobStorageGroupType::ErasureMirror3, groupId),
- &CreateFlatBsController);
+ TTabletTypes::FLAT_BS_CONTROLLER, TBlobStorageGroupType::ErasureMirror3, groupId),
+ &CreateFlatBsController);
}
void Setup(TTestActorRuntime& runtime) {
diff --git a/ydb/core/mind/ya.make b/ydb/core/mind/ya.make
index ed87fc220a1..b9248c9d911 100644
--- a/ydb/core/mind/ya.make
+++ b/ydb/core/mind/ya.make
@@ -2,7 +2,7 @@ LIBRARY()
OWNER(
ddoarn
- xenoxeno
+ xenoxeno
g:kikimr
)
diff --git a/ydb/core/mon/mon.cpp b/ydb/core/mon/mon.cpp
index 33775f54255..d4722266f34 100644
--- a/ydb/core/mon/mon.cpp
+++ b/ydb/core/mon/mon.cpp
@@ -21,8 +21,8 @@ namespace NActors {
using namespace NMonitoring;
- using THttpResponsePtr = THolder<NMon::IEvHttpInfoRes>;
-
+ using THttpResponsePtr = THolder<NMon::IEvHttpInfoRes>;
+
////////////////////////////////////////////////////////////////////////////////
// MON REQUEST
////////////////////////////////////////////////////////////////////////////////
@@ -33,13 +33,13 @@ namespace NActors {
}
TMonRequest(const TActorId &targetActorId, IMonHttpRequest& request,
- NThreading::TPromise<THttpResponsePtr> result, const TVector<TString> &sids, TMon::TRequestAuthorizer authorizer)
+ NThreading::TPromise<THttpResponsePtr> result, const TVector<TString> &sids, TMon::TRequestAuthorizer authorizer)
: TActor(&TMonRequest::StateFunc)
, TargetActorId(targetActorId)
, Request(request)
, Result(result)
- , AllowedSIDs(sids)
- , Authorizer(authorizer)
+ , AllowedSIDs(sids)
+ , Authorizer(authorizer)
{
}
@@ -56,23 +56,23 @@ namespace NActors {
HFunc(TEvents::TEvWakeup, HandleWakeup);
HFunc(TEvents::TEvUndelivered, HandleUndelivered);
HFunc(NMon::IEvHttpInfoRes, HandleInfoRes);
- HFunc(NKikimr::TEvTicketParser::TEvAuthorizeTicketResult, Handle);
+ HFunc(NKikimr::TEvTicketParser::TEvAuthorizeTicketResult, Handle);
}
}
void HandleBootstrap(TEvents::TEvBootstrap::TPtr &, const TActorContext &ctx) {
- if (Request.GetMethod() == HTTP_METHOD_OPTIONS) {
- return ReplyOptionsResultAndDie(ctx);
- }
- ctx.Schedule(TDuration::Seconds(600), new TEvents::TEvWakeup());
- if (Authorizer) {
- NActors::IEventHandle* handle = Authorizer(SelfId(), Request);
- if (handle) {
- ctx.Send(handle);
- return;
- }
- }
- SendRequest(ctx);
+ if (Request.GetMethod() == HTTP_METHOD_OPTIONS) {
+ return ReplyOptionsResultAndDie(ctx);
+ }
+ ctx.Schedule(TDuration::Seconds(600), new TEvents::TEvWakeup());
+ if (Authorizer) {
+ NActors::IEventHandle* handle = Authorizer(SelfId(), Request);
+ if (handle) {
+ ctx.Send(handle);
+ return;
+ }
+ }
+ SendRequest(ctx);
}
void HandlePoisonPill(TEvents::TEvPoisonPill::TPtr &, const TActorContext &ctx) {
@@ -89,110 +89,110 @@ namespace NActors {
}
void HandleInfoRes(NMon::IEvHttpInfoRes::TPtr &ev, const NActors::TActorContext &ctx) {
- Result.SetValue(THolder<NMon::IEvHttpInfoRes>(ev->Release().Release()));
+ Result.SetValue(THolder<NMon::IEvHttpInfoRes>(ev->Release().Release()));
Die(ctx);
}
- void Handle(NKikimr::TEvTicketParser::TEvAuthorizeTicketResult::TPtr &ev, const TActorContext &ctx) {
- const NKikimr::TEvTicketParser::TEvAuthorizeTicketResult &result(*ev->Get());
- if (result.Error) {
- ReplyUnathorizedAndDie(ctx, result.Error.Message);
- return;
- }
- bool found = false;
- for (const TString& sid : AllowedSIDs) {
- if (result.Token->IsExist(sid)) {
- found = true;
- break;;
- }
- }
- if (found || AllowedSIDs.empty()) {
- User = result.Token->GetUserSID();
- SendRequest(ctx, result.SerializedToken);
- } else {
- ReplyForbiddenAndDie(ctx, TStringBuilder() << "SID is not allowed");
- }
- }
-
- TString GetUser() const {
- return User ? User : "anonymous";
- }
-
- static TString GetMethod(HTTP_METHOD method) {
- switch (method) {
- case HTTP_METHOD_UNDEFINED: return "UNDEFINED";
- case HTTP_METHOD_OPTIONS: return "OPTIONS";
- case HTTP_METHOD_GET: return "GET";
- case HTTP_METHOD_HEAD: return "HEAD";
- case HTTP_METHOD_POST: return "POST";
- case HTTP_METHOD_PUT: return "PUT";
- case HTTP_METHOD_DELETE: return "DELETE";
- case HTTP_METHOD_TRACE: return "TRACE";
- case HTTP_METHOD_CONNECT: return "CONNECT";
- case HTTP_METHOD_EXTENSION: return "EXTENSION";
- default: return "UNKNOWN";
- }
- }
-
- void SendRequest(const TActorContext &ctx, const TString& serializedToken = TString()) {
- if (Authorizer) {
- LOG_WARN_S(ctx, NKikimrServices::HTTP,
- Request.GetRemoteAddr()
- << " " << GetUser()
- << " " << GetMethod(Request.GetMethod())
- << " " << Request.GetUri());
- }
+ void Handle(NKikimr::TEvTicketParser::TEvAuthorizeTicketResult::TPtr &ev, const TActorContext &ctx) {
+ const NKikimr::TEvTicketParser::TEvAuthorizeTicketResult &result(*ev->Get());
+ if (result.Error) {
+ ReplyUnathorizedAndDie(ctx, result.Error.Message);
+ return;
+ }
+ bool found = false;
+ for (const TString& sid : AllowedSIDs) {
+ if (result.Token->IsExist(sid)) {
+ found = true;
+ break;;
+ }
+ }
+ if (found || AllowedSIDs.empty()) {
+ User = result.Token->GetUserSID();
+ SendRequest(ctx, result.SerializedToken);
+ } else {
+ ReplyForbiddenAndDie(ctx, TStringBuilder() << "SID is not allowed");
+ }
+ }
+
+ TString GetUser() const {
+ return User ? User : "anonymous";
+ }
+
+ static TString GetMethod(HTTP_METHOD method) {
+ switch (method) {
+ case HTTP_METHOD_UNDEFINED: return "UNDEFINED";
+ case HTTP_METHOD_OPTIONS: return "OPTIONS";
+ case HTTP_METHOD_GET: return "GET";
+ case HTTP_METHOD_HEAD: return "HEAD";
+ case HTTP_METHOD_POST: return "POST";
+ case HTTP_METHOD_PUT: return "PUT";
+ case HTTP_METHOD_DELETE: return "DELETE";
+ case HTTP_METHOD_TRACE: return "TRACE";
+ case HTTP_METHOD_CONNECT: return "CONNECT";
+ case HTTP_METHOD_EXTENSION: return "EXTENSION";
+ default: return "UNKNOWN";
+ }
+ }
+
+ void SendRequest(const TActorContext &ctx, const TString& serializedToken = TString()) {
+ if (Authorizer) {
+ LOG_WARN_S(ctx, NKikimrServices::HTTP,
+ Request.GetRemoteAddr()
+ << " " << GetUser()
+ << " " << GetMethod(Request.GetMethod())
+ << " " << Request.GetUri());
+ }
ctx.Send(TargetActorId, new NMon::TEvHttpInfo(Request, serializedToken), IEventHandle::FlagTrackDelivery);
- }
-
- void ReplyOptionsResultAndDie(const TActorContext &ctx) {
- TString url(Request.GetPathInfo());
- TString type = mimetypeByExt(url.data());
- if (type.empty()) {
- type = "application/json";
- }
+ }
+
+ void ReplyOptionsResultAndDie(const TActorContext &ctx) {
+ TString url(Request.GetPathInfo());
+ TString type = mimetypeByExt(url.data());
+ if (type.empty()) {
+ type = "application/json";
+ }
Result.SetValue(MakeHolder<NMon::TEvHttpInfoRes>(
- "HTTP/1.1 204 No Content\r\n"
- "Allow: OPTIONS, GET, POST\r\n"
- "Content-Type: " + type + "\r\n"
- "Connection: Keep-Alive\r\n\r\n", 0, NMon::IEvHttpInfoRes::EContentType::Custom));
- Die(ctx);
- }
-
- void ReplyUnathorizedAndDie(const TActorContext &ctx, const TString& error = TString()) {
- TStringStream response;
- TStringStream body;
- body << "<html><body><h1>401 Unauthorized</h1>";
- if (!error.empty()) {
- body << "<p>" << error << "</p>";
- }
- body << "</body></html>";
- response << "HTTP/1.1 401 Unauthorized\r\n";
- response << "Content-Type: text/html\r\n";
- response << "Content-Length: " << body.Size() << "\r\n";
- response << "\r\n";
- response << body.Str();
+ "HTTP/1.1 204 No Content\r\n"
+ "Allow: OPTIONS, GET, POST\r\n"
+ "Content-Type: " + type + "\r\n"
+ "Connection: Keep-Alive\r\n\r\n", 0, NMon::IEvHttpInfoRes::EContentType::Custom));
+ Die(ctx);
+ }
+
+ void ReplyUnathorizedAndDie(const TActorContext &ctx, const TString& error = TString()) {
+ TStringStream response;
+ TStringStream body;
+ body << "<html><body><h1>401 Unauthorized</h1>";
+ if (!error.empty()) {
+ body << "<p>" << error << "</p>";
+ }
+ body << "</body></html>";
+ response << "HTTP/1.1 401 Unauthorized\r\n";
+ response << "Content-Type: text/html\r\n";
+ response << "Content-Length: " << body.Size() << "\r\n";
+ response << "\r\n";
+ response << body.Str();
Result.SetValue(MakeHolder<NMon::TEvHttpInfoRes>(response.Str(), 0, NMon::IEvHttpInfoRes::EContentType::Custom));
- Die(ctx);
- }
-
- void ReplyForbiddenAndDie(const TActorContext &ctx, const TString& error = TString()) {
- TStringStream response;
- TStringStream body;
- body << "<html><body><h1>403 Forbidden</h1>";
- if (!error.empty()) {
- body << "<p>" << error << "</p>";
- }
- body << "</body></html>";
- response << "HTTP/1.1 403 Forbidden\r\n";
- response << "Content-Type: text/html\r\n";
- response << "Content-Length: " << body.Size() << "\r\n";
- response << "\r\n";
- response << body.Str();
+ Die(ctx);
+ }
+
+ void ReplyForbiddenAndDie(const TActorContext &ctx, const TString& error = TString()) {
+ TStringStream response;
+ TStringStream body;
+ body << "<html><body><h1>403 Forbidden</h1>";
+ if (!error.empty()) {
+ body << "<p>" << error << "</p>";
+ }
+ body << "</body></html>";
+ response << "HTTP/1.1 403 Forbidden\r\n";
+ response << "Content-Type: text/html\r\n";
+ response << "Content-Length: " << body.Size() << "\r\n";
+ response << "\r\n";
+ response << body.Str();
Result.SetValue(MakeHolder<NMon::TEvHttpInfoRes>(response.Str(), 0, NMon::IEvHttpInfoRes::EContentType::Custom));
- Die(ctx);
- }
-
+ Die(ctx);
+ }
+
void ReplyActorUnavailableAndDie(const TActorContext &ctx, const TString& error = TString()) {
TStringStream response;
TStringStream body;
@@ -218,10 +218,10 @@ namespace NActors {
protected:
TActorId TargetActorId;
IMonHttpRequest& Request;
- NThreading::TPromise<THttpResponsePtr> Result;
- const TVector<TString> &AllowedSIDs;
- TMon::TRequestAuthorizer Authorizer;
- TString User;
+ NThreading::TPromise<THttpResponsePtr> Result;
+ const TVector<TString> &AllowedSIDs;
+ TMon::TRequestAuthorizer Authorizer;
+ TString User;
};
@@ -239,53 +239,53 @@ namespace NActors {
{
}
- void Output(NMonitoring::IMonHttpRequest& request) override {
- IOutputStream& out = request.Output();
-
- out << HTTPOKHTML;
-
- out << "<!DOCTYPE html>\n";
- out << "<html>";
- out << "<head>";
- if (Title) {
- if (Host) {
- out << "<title>" << Title << " - " << Host << "</title>\n";
- } else {
- out << "<title>" << Title << "</title>\n";
- }
- }
-
- out << "<link rel='stylesheet' href='https://yastatic.net/bootstrap/3.3.1/css/bootstrap.min.css'>\n";
- out << "<script language='javascript' type='text/javascript' src='https://yastatic.net/jquery/2.1.3/jquery.min.js'></script>\n";
- out << "<script language='javascript' type='text/javascript' src='https://yastatic.net/bootstrap/3.3.1/js/bootstrap.min.js'></script>\n";
-
- if (OutputTableSorterJsCss) {
+ void Output(NMonitoring::IMonHttpRequest& request) override {
+ IOutputStream& out = request.Output();
+
+ out << HTTPOKHTML;
+
+ out << "<!DOCTYPE html>\n";
+ out << "<html>";
+ out << "<head>";
+ if (Title) {
+ if (Host) {
+ out << "<title>" << Title << " - " << Host << "</title>\n";
+ } else {
+ out << "<title>" << Title << "</title>\n";
+ }
+ }
+
+ out << "<link rel='stylesheet' href='https://yastatic.net/bootstrap/3.3.1/css/bootstrap.min.css'>\n";
+ out << "<script language='javascript' type='text/javascript' src='https://yastatic.net/jquery/2.1.3/jquery.min.js'></script>\n";
+ out << "<script language='javascript' type='text/javascript' src='https://yastatic.net/bootstrap/3.3.1/js/bootstrap.min.js'></script>\n";
+
+ if (OutputTableSorterJsCss) {
out << "<link rel='stylesheet' href='/jquery.tablesorter.css'>\n";
out << "<script language='javascript' type='text/javascript' src='/jquery.tablesorter.js'></script>\n";
- }
-
- out << "<style type=\"text/css\">\n";
- out << ".table-nonfluid { width: auto; }\n";
- out << ".narrow-line50 {line-height: 50%}\n";
- out << ".narrow-line60 {line-height: 60%}\n";
- out << ".narrow-line70 {line-height: 70%}\n";
- out << ".narrow-line80 {line-height: 80%}\n";
- out << ".narrow-line90 {line-height: 90%}\n";
- out << "</style>\n";
- out << "</head>";
- out << "<body>";
-
+ }
+
+ out << "<style type=\"text/css\">\n";
+ out << ".table-nonfluid { width: auto; }\n";
+ out << ".narrow-line50 {line-height: 50%}\n";
+ out << ".narrow-line60 {line-height: 60%}\n";
+ out << ".narrow-line70 {line-height: 70%}\n";
+ out << ".narrow-line80 {line-height: 80%}\n";
+ out << ".narrow-line90 {line-height: 90%}\n";
+ out << "</style>\n";
+ out << "</head>";
+ out << "<body>";
+
OutputNavBar(out);
-
- out << "<div class='container'>";
- if (Title) {
- out << "<h2>" << Title << "</h2>";
- }
- OutputContent(request);
- out << "</div>";
- out << "</body>";
- }
-
+
+ out << "<div class='container'>";
+ if (Title) {
+ out << "<h2>" << Title << "</h2>";
+ }
+ OutputContent(request);
+ out << "</div>";
+ out << "</body>";
+ }
+
void OutputContent(NMonitoring::IMonHttpRequest &request) override {
if (PreTag) {
request.Output() << "<pre>\n";
@@ -304,26 +304,26 @@ namespace NActors {
////////////////////////////////////////////////////////////////////////////////
- // INDEX PAGE
- // Redirects index page to fixed url
- ////////////////////////////////////////////////////////////////////////////////
- class TIndexRedirectMonPage: public IMonPage {
- public:
- TIndexRedirectMonPage(TIntrusivePtr<TIndexMonPage> indexMonPage, const TString& path = "internal")
- : IMonPage(path)
- , IndexMonPage(std::move(indexMonPage))
- {
- }
-
- void Output(IMonHttpRequest& request) override {
- IndexMonPage->OutputIndexPage(request);
- }
-
- TIntrusivePtr<TIndexMonPage> IndexMonPage;
- };
-
-
- ////////////////////////////////////////////////////////////////////////////////
+ // INDEX PAGE
+ // Redirects index page to fixed url
+ ////////////////////////////////////////////////////////////////////////////////
+ class TIndexRedirectMonPage: public IMonPage {
+ public:
+ TIndexRedirectMonPage(TIntrusivePtr<TIndexMonPage> indexMonPage, const TString& path = "internal")
+ : IMonPage(path)
+ , IndexMonPage(std::move(indexMonPage))
+ {
+ }
+
+ void Output(IMonHttpRequest& request) override {
+ IndexMonPage->OutputIndexPage(request);
+ }
+
+ TIntrusivePtr<TIndexMonPage> IndexMonPage;
+ };
+
+
+ ////////////////////////////////////////////////////////////////////////////////
// ACTOR MONITORING PAGE
// Encapsulates a request to an actor
////////////////////////////////////////////////////////////////////////////////
@@ -331,27 +331,27 @@ namespace NActors {
public:
TActorMonPage(const TString &path, const TString &title, const TString &host, bool preTag,
TActorSystem *actorSystem, const TActorId &actorId, const TVector<TString> &sids,
- TMon::TRequestAuthorizer authorizer)
+ TMon::TRequestAuthorizer authorizer)
: IMonPage(path, title)
, Host(host)
, PreTag(preTag)
, ActorSystem(actorSystem)
, TargetActorId(actorId)
- , AllowedSIDs(sids)
- , Authorizer(std::move(authorizer))
+ , AllowedSIDs(sids)
+ , Authorizer(std::move(authorizer))
{
}
void Output(IMonHttpRequest &request) override {
- auto promise = NThreading::NewPromise<THttpResponsePtr>();
- auto future = promise.GetFuture();
+ auto promise = NThreading::NewPromise<THttpResponsePtr>();
+ auto future = promise.GetFuture();
- ActorSystem->Register(new TMonRequest(TargetActorId, request, promise, AllowedSIDs, Authorizer));
+ ActorSystem->Register(new TMonRequest(TargetActorId, request, promise, AllowedSIDs, Authorizer));
- THttpResponsePtr result = future.ExtractValue(TDuration::Max());
+ THttpResponsePtr result = future.ExtractValue(TDuration::Max());
- if (result) {
- Output(request, *result);
+ if (result) {
+ Output(request, *result);
} else {
TStringStream out;
out << "Error: timeout. We were not able to receive response from '"
@@ -376,17 +376,17 @@ namespace NActors {
bool PreTag;
TActorSystem *ActorSystem;
TActorId TargetActorId;
- const TVector<TString> AllowedSIDs;
- TMon::TRequestAuthorizer Authorizer;
+ const TVector<TString> AllowedSIDs;
+ TMon::TRequestAuthorizer Authorizer;
};
////////////////////////////////////////////////////////////////////////////////
// TMON CLASS
////////////////////////////////////////////////////////////////////////////////
- TMon::TMon(TMon::TConfig config)
- : TBase(config.Port, config.Address, config.Threads, config.Title)
- , Config(std::move(config))
+ TMon::TMon(TMon::TConfig config)
+ : TBase(config.Port, config.Address, config.Threads, config.Title)
+ , Config(std::move(config))
{
}
@@ -395,7 +395,7 @@ namespace NActors {
}
void TMon::Start() {
- TBase::Register(new TIndexRedirectMonPage(IndexMonPage));
+ TBase::Register(new TIndexRedirectMonPage(IndexMonPage));
TBase::Register(new NMonitoring::TVersionMonPage);
TBase::Register(new NMonitoring::TTablesorterCssMonPage);
TBase::Register(new NMonitoring::TTablesorterJsMonPage);
@@ -406,48 +406,48 @@ namespace NActors {
TBase::Start();
}
- void TMon::Stop() {
- IndexMonPage->ClearPages(); // it's required to avoid loop-reference
- TBase::Stop();
- }
-
+ void TMon::Stop() {
+ IndexMonPage->ClearPages(); // it's required to avoid loop-reference
+ TBase::Stop();
+ }
+
void TMon::Register(NMonitoring::IMonPage *page) {
TBase::Register(page);
- TBase::SortPages();
+ TBase::SortPages();
}
TIndexMonPage *TMon::RegisterIndexPage(const TString &path, const TString &title) {
- auto page = TBase::RegisterIndexPage(path, title);
- TBase::SortPages();
- return page;
+ auto page = TBase::RegisterIndexPage(path, title);
+ TBase::SortPages();
+ return page;
}
IMonPage *TMon::RegisterActorPage(TIndexMonPage *index, const TString &relPath,
const TString &title, bool preTag, TActorSystem *actorSystem, const TActorId &actorId, bool useAuth) {
- return RegisterActorPage({
- .Title = title,
- .RelPath = relPath,
- .ActorSystem = actorSystem,
- .Index = index,
- .PreTag = preTag,
- .ActorId = actorId,
- .UseAuth = useAuth,
- });
- }
-
- IMonPage* TMon::RegisterActorPage(TMon::TRegisterActorPageFields fields) {
- IMonPage *page = new TActorMonPage(
- fields.RelPath,
- fields.Title,
- Config.Host,
- fields.PreTag,
- fields.ActorSystem,
- fields.ActorId,
- fields.AllowedSIDs ? fields.AllowedSIDs : Config.AllowedSIDs,
- fields.UseAuth ? Config.Authorizer : TRequestAuthorizer());
- if (fields.Index) {
- fields.Index->Register(page);
- fields.Index->SortPages();
+ return RegisterActorPage({
+ .Title = title,
+ .RelPath = relPath,
+ .ActorSystem = actorSystem,
+ .Index = index,
+ .PreTag = preTag,
+ .ActorId = actorId,
+ .UseAuth = useAuth,
+ });
+ }
+
+ IMonPage* TMon::RegisterActorPage(TMon::TRegisterActorPageFields fields) {
+ IMonPage *page = new TActorMonPage(
+ fields.RelPath,
+ fields.Title,
+ Config.Host,
+ fields.PreTag,
+ fields.ActorSystem,
+ fields.ActorId,
+ fields.AllowedSIDs ? fields.AllowedSIDs : Config.AllowedSIDs,
+ fields.UseAuth ? Config.Authorizer : TRequestAuthorizer());
+ if (fields.Index) {
+ fields.Index->Register(page);
+ fields.Index->SortPages();
} else {
Register(page);
}
@@ -470,7 +470,7 @@ namespace NActors {
return TBase::FindIndexPage(relPath);
}
- void TMon::OutputIndexPage(IOutputStream& out) {
+ void TMon::OutputIndexPage(IOutputStream& out) {
if (Config.RedirectMainPageTo) {
// XXX manual http response construction
out << "HTTP/1.1 302 Found\r\n"
@@ -479,56 +479,56 @@ namespace NActors {
} else {
NMonitoring::TMonService2::OutputIndexPage(out);
}
- }
-
- void TMon::SetAllowedSIDs(const TVector<TString>& sids) {
- Config.AllowedSIDs = sids;
- }
-
- ui16 TMon::GetListenPort() {
- return Options().Port;
- }
-
- NActors::IEventHandle* TMon::DefaultAuthorizer(const NActors::TActorId& owner, NMonitoring::IMonHttpRequest& request) {
- TStringBuf ydbSessionId = request.GetCookie("ydb_session_id");
- TStringBuf authorization = request.GetHeader("Authorization");
- if (!authorization.empty()) {
- return new NActors::IEventHandle(
- NKikimr::MakeTicketParserID(),
- owner,
- new NKikimr::TEvTicketParser::TEvAuthorizeTicket({
- .Ticket = TString(authorization)
- }),
- IEventHandle::FlagTrackDelivery
- );
- } else if (!ydbSessionId.empty()) {
- return new NActors::IEventHandle(
- NKikimr::MakeTicketParserID(),
- owner,
- new NKikimr::TEvTicketParser::TEvAuthorizeTicket({
- .Ticket = TString("Login ") + TString(ydbSessionId)
- }),
- IEventHandle::FlagTrackDelivery
- );
- } else if (NKikimr::AppData()->EnforceUserTokenRequirement && NKikimr::AppData()->DefaultUserSIDs.empty()) {
- return new NActors::IEventHandle(
- owner,
- owner,
- new NKikimr::TEvTicketParser::TEvAuthorizeTicketResult(TString(), {
- .Message = "No security credentials were provided",
- .Retryable = false
- })
- );
- } else if (!NKikimr::AppData()->DefaultUserSIDs.empty()) {
- TIntrusivePtr<NACLib::TUserToken> token = new NACLib::TUserToken(NKikimr::AppData()->DefaultUserSIDs);
- return new NActors::IEventHandle(
- owner,
- owner,
- new NKikimr::TEvTicketParser::TEvAuthorizeTicketResult(TString(), token, token->SerializeAsString())
- );
- } else {
- return nullptr;
- }
- }
-
+ }
+
+ void TMon::SetAllowedSIDs(const TVector<TString>& sids) {
+ Config.AllowedSIDs = sids;
+ }
+
+ ui16 TMon::GetListenPort() {
+ return Options().Port;
+ }
+
+ NActors::IEventHandle* TMon::DefaultAuthorizer(const NActors::TActorId& owner, NMonitoring::IMonHttpRequest& request) {
+ TStringBuf ydbSessionId = request.GetCookie("ydb_session_id");
+ TStringBuf authorization = request.GetHeader("Authorization");
+ if (!authorization.empty()) {
+ return new NActors::IEventHandle(
+ NKikimr::MakeTicketParserID(),
+ owner,
+ new NKikimr::TEvTicketParser::TEvAuthorizeTicket({
+ .Ticket = TString(authorization)
+ }),
+ IEventHandle::FlagTrackDelivery
+ );
+ } else if (!ydbSessionId.empty()) {
+ return new NActors::IEventHandle(
+ NKikimr::MakeTicketParserID(),
+ owner,
+ new NKikimr::TEvTicketParser::TEvAuthorizeTicket({
+ .Ticket = TString("Login ") + TString(ydbSessionId)
+ }),
+ IEventHandle::FlagTrackDelivery
+ );
+ } else if (NKikimr::AppData()->EnforceUserTokenRequirement && NKikimr::AppData()->DefaultUserSIDs.empty()) {
+ return new NActors::IEventHandle(
+ owner,
+ owner,
+ new NKikimr::TEvTicketParser::TEvAuthorizeTicketResult(TString(), {
+ .Message = "No security credentials were provided",
+ .Retryable = false
+ })
+ );
+ } else if (!NKikimr::AppData()->DefaultUserSIDs.empty()) {
+ TIntrusivePtr<NACLib::TUserToken> token = new NACLib::TUserToken(NKikimr::AppData()->DefaultUserSIDs);
+ return new NActors::IEventHandle(
+ owner,
+ owner,
+ new NKikimr::TEvTicketParser::TEvAuthorizeTicketResult(TString(), token, token->SerializeAsString())
+ );
+ } else {
+ return nullptr;
+ }
+ }
+
} // NActors
diff --git a/ydb/core/mon/mon.h b/ydb/core/mon/mon.h
index a22fb3c5db2..1cb5dbecd0c 100644
--- a/ydb/core/mon/mon.h
+++ b/ydb/core/mon/mon.h
@@ -14,53 +14,53 @@ namespace NActors {
class TMon : public NMonitoring::TMonService2 {
public:
- using TRequestAuthorizer = std::function<IEventHandle*(const NActors::TActorId& owner, NMonitoring::IMonHttpRequest& request)>;
-
- struct TConfig {
- ui16 Port = 0;
- TString Address;
- ui32 Threads = 10;
- TString Title;
- TString Host;
- TRequestAuthorizer Authorizer = DefaultAuthorizer;
- TVector<TString> AllowedSIDs;
+ using TRequestAuthorizer = std::function<IEventHandle*(const NActors::TActorId& owner, NMonitoring::IMonHttpRequest& request)>;
+
+ struct TConfig {
+ ui16 Port = 0;
+ TString Address;
+ ui32 Threads = 10;
+ TString Title;
+ TString Host;
+ TRequestAuthorizer Authorizer = DefaultAuthorizer;
+ TVector<TString> AllowedSIDs;
TString RedirectMainPageTo;
- };
-
- TMon(TConfig config);
+ };
+
+ TMon(TConfig config);
virtual ~TMon();
void Start();
- void Stop();
+ void Stop();
void Register(NMonitoring::IMonPage *page);
NMonitoring::TIndexMonPage *RegisterIndexPage(const TString &path, const TString &title);
-
- struct TRegisterActorPageFields {
- TString Title;
- TString RelPath;
- TActorSystem* ActorSystem;
- NMonitoring::TIndexMonPage* Index;
- bool PreTag = false;
- TActorId ActorId;
- bool UseAuth = true;
- TVector<TString> AllowedSIDs;
- };
-
- NMonitoring::IMonPage* RegisterActorPage(TRegisterActorPageFields fields);
+
+ struct TRegisterActorPageFields {
+ TString Title;
+ TString RelPath;
+ TActorSystem* ActorSystem;
+ NMonitoring::TIndexMonPage* Index;
+ bool PreTag = false;
+ TActorId ActorId;
+ bool UseAuth = true;
+ TVector<TString> AllowedSIDs;
+ };
+
+ NMonitoring::IMonPage* RegisterActorPage(TRegisterActorPageFields fields);
NMonitoring::IMonPage *RegisterActorPage(NMonitoring::TIndexMonPage *index, const TString &relPath,
const TString &title, bool preTag, TActorSystem *actorSystem, const TActorId &actorId, bool useAuth = true);
NMonitoring::IMonPage *RegisterCountersPage(const TString &path, const TString &title, TIntrusivePtr<NMonitoring::TDynamicCounters> counters);
NMonitoring::IMonPage *FindPage(const TString &relPath);
NMonitoring::TIndexMonPage *FindIndexPage(const TString &relPath);
- void OutputIndexPage(IOutputStream& out) override;
- void SetAllowedSIDs(const TVector<TString>& sids); // sets allowed users/groups for this web interface
- ui16 GetListenPort();
+ void OutputIndexPage(IOutputStream& out) override;
+ void SetAllowedSIDs(const TVector<TString>& sids); // sets allowed users/groups for this web interface
+ ui16 GetListenPort();
+
+ static NActors::IEventHandle* DefaultAuthorizer(const NActors::TActorId& owner, NMonitoring::IMonHttpRequest& request);
- static NActors::IEventHandle* DefaultAuthorizer(const NActors::TActorId& owner, NMonitoring::IMonHttpRequest& request);
-
protected:
typedef NMonitoring::TMonService2 TBase;
- TConfig Config;
+ TConfig Config;
};
} // NActors
diff --git a/ydb/core/node_whiteboard/node_whiteboard.h b/ydb/core/node_whiteboard/node_whiteboard.h
index c4626ff306a..cdf7601807c 100644
--- a/ydb/core/node_whiteboard/node_whiteboard.h
+++ b/ydb/core/node_whiteboard/node_whiteboard.h
@@ -1,5 +1,5 @@
-#pragma once
-#include "defs.h"
+#pragma once
+#include "defs.h"
#include <ydb/core/base/blobstorage.h>
#include <ydb/core/base/events.h>
#include <ydb/core/base/subdomain.h>
@@ -10,42 +10,42 @@
#include <library/cpp/actors/interconnect/events_local.h>
#include <library/cpp/actors/core/interconnect.h>
#include <ydb/core/base/tracing.h>
-
-namespace NKikimr {
-
-using TTabletId = ui64;
+
+namespace NKikimr {
+
+using TTabletId = ui64;
using TFollowerId = ui32;
-using TNodeId = ui32;
-
-namespace NNodeWhiteboard {
-
-struct TEvWhiteboard{
- enum EEv {
- EvTabletStateUpdate = EventSpaceBegin(TKikimrEvents::ES_NODE_WHITEBOARD),
- EvTabletStateRequest,
- EvTabletStateResponse,
+using TNodeId = ui32;
+
+namespace NNodeWhiteboard {
+
+struct TEvWhiteboard{
+ enum EEv {
+ EvTabletStateUpdate = EventSpaceBegin(TKikimrEvents::ES_NODE_WHITEBOARD),
+ EvTabletStateRequest,
+ EvTabletStateResponse,
EvNodeStateUpdate,
EvNodeStateDelete,
EvNodeStateRequest,
EvNodeStateResponse,
- EvPDiskStateUpdate,
- EvPDiskStateRequest,
- EvPDiskStateResponse,
- EvVDiskStateUpdate,
- EvVDiskStateRequest,
- EvVDiskStateResponse,
- EvSystemStateUpdate,
- EvSystemStateRequest,
- EvSystemStateResponse,
- EvBSGroupStateUpdate,
- EvBSGroupStateRequest,
- EvBSGroupStateResponse,
- EvVDiskStateDelete,
- EvSystemStateAddEndpoint,
- EvSystemStateAddRole,
- EvSystemStateSetTenant,
- EvSystemStateRemoveTenant,
- EvBSGroupStateDelete,
+ EvPDiskStateUpdate,
+ EvPDiskStateRequest,
+ EvPDiskStateResponse,
+ EvVDiskStateUpdate,
+ EvVDiskStateRequest,
+ EvVDiskStateResponse,
+ EvSystemStateUpdate,
+ EvSystemStateRequest,
+ EvSystemStateResponse,
+ EvBSGroupStateUpdate,
+ EvBSGroupStateRequest,
+ EvBSGroupStateResponse,
+ EvVDiskStateDelete,
+ EvSystemStateAddEndpoint,
+ EvSystemStateAddRole,
+ EvSystemStateSetTenant,
+ EvSystemStateRemoveTenant,
+ EvBSGroupStateDelete,
EvIntrospectionData,
EvTabletLookupRequest,
EvTabletLookupResponse,
@@ -57,93 +57,93 @@ struct TEvWhiteboard{
EvSignalBodyResponse,
EvPDiskStateDelete,
EvVDiskStateGenerationChange,
- EvEnd
- };
-
- static_assert(EvEnd < EventSpaceEnd(TKikimrEvents::ES_NODE_WHITEBOARD), "expect EvEnd < EventSpaceEnd(TKikimrEvents::ES_NODE_WHITEBOARD)");
-
- struct TEvTabletStateUpdate : TEventPB<TEvTabletStateUpdate, NKikimrWhiteboard::TTabletStateInfo, EvTabletStateUpdate> {
- TEvTabletStateUpdate() = default;
-
+ EvEnd
+ };
+
+ static_assert(EvEnd < EventSpaceEnd(TKikimrEvents::ES_NODE_WHITEBOARD), "expect EvEnd < EventSpaceEnd(TKikimrEvents::ES_NODE_WHITEBOARD)");
+
+ struct TEvTabletStateUpdate : TEventPB<TEvTabletStateUpdate, NKikimrWhiteboard::TTabletStateInfo, EvTabletStateUpdate> {
+ TEvTabletStateUpdate() = default;
+
TEvTabletStateUpdate(TTabletId tabletId, TFollowerId followerId, NKikimrWhiteboard::TTabletStateInfo::ETabletState state, const TIntrusivePtr<TTabletStorageInfo>& storageInfo, ui32 generation, bool leader) {
- Record.SetTabletId(tabletId);
+ Record.SetTabletId(tabletId);
Record.SetFollowerId(followerId);
- Record.SetType(storageInfo->TabletType);
- Record.SetState(state);
- Record.SetGeneration(generation);
+ Record.SetType(storageInfo->TabletType);
+ Record.SetState(state);
+ Record.SetGeneration(generation);
Record.SetLeader(leader);
- Record.MutableChannelGroupIDs()->Resize(storageInfo->Channels.size(), 0);
- for (const auto& channel : storageInfo->Channels) {
- const auto* latestEntry = channel.LatestEntry();
- ui32 groupId = latestEntry != nullptr ? latestEntry->GroupID : 0;
- Record.SetChannelGroupIDs(channel.Channel, groupId);
- }
- if (storageInfo->HiveId) {
- Record.SetHiveId(storageInfo->HiveId);
- }
- if (storageInfo->TenantPathId) {
- Record.MutableTenantId()->CopyFrom(TSubDomainKey(storageInfo->TenantPathId.OwnerId, storageInfo->TenantPathId.LocalPathId));
- }
- }
-
+ Record.MutableChannelGroupIDs()->Resize(storageInfo->Channels.size(), 0);
+ for (const auto& channel : storageInfo->Channels) {
+ const auto* latestEntry = channel.LatestEntry();
+ ui32 groupId = latestEntry != nullptr ? latestEntry->GroupID : 0;
+ Record.SetChannelGroupIDs(channel.Channel, groupId);
+ }
+ if (storageInfo->HiveId) {
+ Record.SetHiveId(storageInfo->HiveId);
+ }
+ if (storageInfo->TenantPathId) {
+ Record.MutableTenantId()->CopyFrom(TSubDomainKey(storageInfo->TenantPathId.OwnerId, storageInfo->TenantPathId.LocalPathId));
+ }
+ }
+
TEvTabletStateUpdate(TTabletId tabletId, TFollowerId followerId, NKikimrWhiteboard::TTabletStateInfo::ETabletState state, ui32 generation) {
- Record.SetTabletId(tabletId);
+ Record.SetTabletId(tabletId);
Record.SetFollowerId(followerId);
- Record.SetState(state);
- Record.SetGeneration(generation);
- }
+ Record.SetState(state);
+ Record.SetGeneration(generation);
+ }
TEvTabletStateUpdate(TTabletId tabletId, TFollowerId followerId, NKikimrWhiteboard::TTabletStateInfo::ETabletState state, ui32 generation, bool leader) {
- Record.SetTabletId(tabletId);
+ Record.SetTabletId(tabletId);
Record.SetFollowerId(followerId);
- Record.SetState(state);
- Record.SetGeneration(generation);
+ Record.SetState(state);
+ Record.SetGeneration(generation);
Record.SetLeader(leader);
- }
-
- TEvTabletStateUpdate(TTabletId tabletId, ui32 userState) {
+ }
+
+ TEvTabletStateUpdate(TTabletId tabletId, ui32 userState) {
Record.SetTabletId(tabletId);
Record.SetUserState(userState);
}
- };
-
- struct TEvTabletStateRequest : public TEventPB<TEvTabletStateRequest, NKikimrWhiteboard::TEvTabletStateRequest, EvTabletStateRequest> {};
-
- struct TEvTabletStateResponse : public TEventPB<TEvTabletStateResponse, NKikimrWhiteboard::TEvTabletStateResponse, EvTabletStateResponse> {};
-
- struct TEvPDiskStateUpdate : TEventPB<TEvPDiskStateUpdate, NKikimrWhiteboard::TPDiskStateInfo, EvPDiskStateUpdate> {
- TEvPDiskStateUpdate() = default;
-
+ };
+
+ struct TEvTabletStateRequest : public TEventPB<TEvTabletStateRequest, NKikimrWhiteboard::TEvTabletStateRequest, EvTabletStateRequest> {};
+
+ struct TEvTabletStateResponse : public TEventPB<TEvTabletStateResponse, NKikimrWhiteboard::TEvTabletStateResponse, EvTabletStateResponse> {};
+
+ struct TEvPDiskStateUpdate : TEventPB<TEvPDiskStateUpdate, NKikimrWhiteboard::TPDiskStateInfo, EvPDiskStateUpdate> {
+ TEvPDiskStateUpdate() = default;
+
TEvPDiskStateUpdate(ui32 pDiskId, const TString& path, ui64 guid, ui64 category) {
- Record.SetPDiskId(pDiskId);
- Record.SetPath(path);
- Record.SetGuid(guid);
- Record.SetCategory(category);
- }
-
- TEvPDiskStateUpdate(ui32 pDiskId, ui64 availableSize, ui64 totalSize, ui32 state) {
- Record.SetPDiskId(pDiskId);
- Record.SetAvailableSize(availableSize);
- Record.SetTotalSize(totalSize);
+ Record.SetPDiskId(pDiskId);
+ Record.SetPath(path);
+ Record.SetGuid(guid);
+ Record.SetCategory(category);
+ }
+
+ TEvPDiskStateUpdate(ui32 pDiskId, ui64 availableSize, ui64 totalSize, ui32 state) {
+ Record.SetPDiskId(pDiskId);
+ Record.SetAvailableSize(availableSize);
+ Record.SetTotalSize(totalSize);
Record.SetState(static_cast<NKikimrBlobStorage::TPDiskState::E>(state));
- }
+ }
TEvPDiskStateUpdate(ui32 pDiskId, NKikimrWhiteboard::EFlag realtime, NKikimrWhiteboard::EFlag device) {
Record.SetPDiskId(pDiskId);
Record.SetRealtime(realtime);
Record.SetDevice(device);
}
- };
-
- struct TEvPDiskStateRequest : public TEventPB<TEvPDiskStateRequest, NKikimrWhiteboard::TEvPDiskStateRequest, EvPDiskStateRequest> {};
-
- struct TEvPDiskStateResponse : public TEventPB<TEvPDiskStateResponse, NKikimrWhiteboard::TEvPDiskStateResponse, EvPDiskStateResponse> {};
-
- struct TEvVDiskStateUpdate : TEventPB<TEvVDiskStateUpdate, NKikimrWhiteboard::TVDiskStateInfo, EvVDiskStateUpdate> {
+ };
+
+ struct TEvPDiskStateRequest : public TEventPB<TEvPDiskStateRequest, NKikimrWhiteboard::TEvPDiskStateRequest, EvPDiskStateRequest> {};
+
+ struct TEvPDiskStateResponse : public TEventPB<TEvPDiskStateResponse, NKikimrWhiteboard::TEvPDiskStateResponse, EvPDiskStateResponse> {};
+
+ struct TEvVDiskStateUpdate : TEventPB<TEvVDiskStateUpdate, NKikimrWhiteboard::TVDiskStateInfo, EvVDiskStateUpdate> {
const bool Initial = false;
- TEvVDiskStateUpdate() = default;
-
+ TEvVDiskStateUpdate() = default;
+
// this message is generated by NodeWarden
explicit TEvVDiskStateUpdate(const TVDiskID& vDiskId, const TMaybe<TString>& storagePoolName, ui32 pDiskId,
ui32 vDiskSlotId, ui64 guid, NKikimrBlobStorage::TVDiskKind::EVDiskKind kind, bool donorMode,
@@ -154,15 +154,15 @@ struct TEvWhiteboard{
if (storagePoolName) {
Record.SetStoragePoolName(*storagePoolName);
}
- Record.SetPDiskId(pDiskId);
- Record.SetVDiskSlotId(vDiskSlotId);
- Record.SetGuid(guid);
- Record.SetKind(kind);
+ Record.SetPDiskId(pDiskId);
+ Record.SetVDiskSlotId(vDiskSlotId);
+ Record.SetGuid(guid);
+ Record.SetKind(kind);
if (donorMode) {
Record.SetDonorMode(true);
}
Record.SetInstanceGuid(instanceGuid);
- }
+ }
explicit TEvVDiskStateUpdate(NKikimrWhiteboard::TVDiskSatisfactionRank *satisfactionRank) {
Record.MutableSatisfactionRank()->Swap(satisfactionRank);
@@ -185,7 +185,7 @@ struct TEvWhiteboard{
Record.SetFrontQueues(frontQueuesLigth);
Record.SetHasUnreadableBlobs(hasUnreadableBlobs);
}
-
+
static constexpr struct TUpdateIncarnationGuid {} UpdateIncarnationGuid{};
explicit TEvVDiskStateUpdate(TUpdateIncarnationGuid, ui64 incarnationGuid) {
@@ -194,13 +194,13 @@ struct TEvWhiteboard{
explicit TEvVDiskStateUpdate(NKikimrWhiteboard::TVDiskStateInfo&& rec) {
Record = std::move(rec);
- }
- };
-
- struct TEvVDiskStateDelete : TEventPB<TEvVDiskStateDelete, NKikimrWhiteboard::TVDiskStateInfo, EvVDiskStateDelete> {
- TEvVDiskStateDelete() = default;
+ }
+ };
+
+ struct TEvVDiskStateDelete : TEventPB<TEvVDiskStateDelete, NKikimrWhiteboard::TVDiskStateInfo, EvVDiskStateDelete> {
+ TEvVDiskStateDelete() = default;
- explicit TEvVDiskStateDelete(const TVDiskID& vDiskId) {
+ explicit TEvVDiskStateDelete(const TVDiskID& vDiskId) {
VDiskIDFromVDiskID(vDiskId, Record.MutableVDiskId());
}
};
@@ -226,71 +226,71 @@ struct TEvWhiteboard{
};
- struct TEvVDiskStateRequest : public TEventPB<TEvVDiskStateRequest, NKikimrWhiteboard::TEvVDiskStateRequest, EvVDiskStateRequest> {};
-
- struct TEvVDiskStateResponse : public TEventPB<TEvVDiskStateResponse, NKikimrWhiteboard::TEvVDiskStateResponse, EvVDiskStateResponse> {};
-
- struct TEvBSGroupStateUpdate : TEventPB<TEvBSGroupStateUpdate, NKikimrWhiteboard::TBSGroupStateInfo, EvBSGroupStateUpdate> {
- TEvBSGroupStateUpdate() = default;
-
+ struct TEvVDiskStateRequest : public TEventPB<TEvVDiskStateRequest, NKikimrWhiteboard::TEvVDiskStateRequest, EvVDiskStateRequest> {};
+
+ struct TEvVDiskStateResponse : public TEventPB<TEvVDiskStateResponse, NKikimrWhiteboard::TEvVDiskStateResponse, EvVDiskStateResponse> {};
+
+ struct TEvBSGroupStateUpdate : TEventPB<TEvBSGroupStateUpdate, NKikimrWhiteboard::TBSGroupStateInfo, EvBSGroupStateUpdate> {
+ TEvBSGroupStateUpdate() = default;
+
TEvBSGroupStateUpdate(const TIntrusivePtr<TBlobStorageGroupInfo>& groupInfo, const TMaybe<TString>& storagePoolName) {
- Record.SetGroupID(groupInfo->GroupID);
- Record.SetGroupGeneration(groupInfo->GroupGeneration);
- Record.SetErasureSpecies(groupInfo->Type.ErasureSpeciesName(groupInfo->Type.GetErasure()));
+ Record.SetGroupID(groupInfo->GroupID);
+ Record.SetGroupGeneration(groupInfo->GroupGeneration);
+ Record.SetErasureSpecies(groupInfo->Type.ErasureSpeciesName(groupInfo->Type.GetErasure()));
for (auto it = groupInfo->VDisksBegin(), end = groupInfo->VDisksEnd(); it != end; ++it) {
auto vd = groupInfo->GetVDiskId(it->OrderNumber);
- NKikimrBlobStorage::TVDiskID* addedVDisk = Record.AddVDiskIds();
- VDiskIDFromVDiskID(vd, addedVDisk);
- }
+ NKikimrBlobStorage::TVDiskID* addedVDisk = Record.AddVDiskIds();
+ VDiskIDFromVDiskID(vd, addedVDisk);
+ }
if (storagePoolName) {
Record.SetStoragePoolName(*storagePoolName);
}
- }
- };
-
- struct TEvBSGroupStateDelete : TEventPB<TEvBSGroupStateDelete, NKikimrWhiteboard::TBSGroupStateInfo, EvBSGroupStateDelete> {
- TEvBSGroupStateDelete() = default;
-
- TEvBSGroupStateDelete(ui32 groupID) {
- Record.SetGroupID(groupID);
- }
- };
-
- struct TEvBSGroupStateRequest : public TEventPB<TEvBSGroupStateRequest, NKikimrWhiteboard::TEvBSGroupStateRequest, EvBSGroupStateRequest> {};
-
- struct TEvBSGroupStateResponse : public TEventPB<TEvBSGroupStateResponse, NKikimrWhiteboard::TEvBSGroupStateResponse, EvBSGroupStateResponse> {};
-
- struct TEvSystemStateUpdate : TEventPB<TEvSystemStateUpdate, NKikimrWhiteboard::TSystemStateInfo, EvSystemStateUpdate> {
- TEvSystemStateUpdate() = default;
-
- TEvSystemStateUpdate(
- TInstant startTime,
- ui32 numberOfCpus,
- const TString& version) {
- Record.SetStartTime(startTime.MilliSeconds());
- Record.SetNumberOfCpus(numberOfCpus);
- Record.SetVersion(version);
- }
-
- TEvSystemStateUpdate(
- TInstant startTime,
- ui32 numberOfCpus) {
- Record.SetStartTime(startTime.MilliSeconds());
- Record.SetNumberOfCpus(numberOfCpus);
- }
-
+ }
+ };
+
+ struct TEvBSGroupStateDelete : TEventPB<TEvBSGroupStateDelete, NKikimrWhiteboard::TBSGroupStateInfo, EvBSGroupStateDelete> {
+ TEvBSGroupStateDelete() = default;
+
+ TEvBSGroupStateDelete(ui32 groupID) {
+ Record.SetGroupID(groupID);
+ }
+ };
+
+ struct TEvBSGroupStateRequest : public TEventPB<TEvBSGroupStateRequest, NKikimrWhiteboard::TEvBSGroupStateRequest, EvBSGroupStateRequest> {};
+
+ struct TEvBSGroupStateResponse : public TEventPB<TEvBSGroupStateResponse, NKikimrWhiteboard::TEvBSGroupStateResponse, EvBSGroupStateResponse> {};
+
+ struct TEvSystemStateUpdate : TEventPB<TEvSystemStateUpdate, NKikimrWhiteboard::TSystemStateInfo, EvSystemStateUpdate> {
+ TEvSystemStateUpdate() = default;
+
+ TEvSystemStateUpdate(
+ TInstant startTime,
+ ui32 numberOfCpus,
+ const TString& version) {
+ Record.SetStartTime(startTime.MilliSeconds());
+ Record.SetNumberOfCpus(numberOfCpus);
+ Record.SetVersion(version);
+ }
+
+ TEvSystemStateUpdate(
+ TInstant startTime,
+ ui32 numberOfCpus) {
+ Record.SetStartTime(startTime.MilliSeconds());
+ Record.SetNumberOfCpus(numberOfCpus);
+ }
+
TEvSystemStateUpdate(const TVector<double>& loadAverage) {
- for (double d : loadAverage) {
- Record.AddLoadAverage(d);
- }
- }
-
- TEvSystemStateUpdate(const TVector<std::tuple<TString, double, ui32>>& poolStats) {
+ for (double d : loadAverage) {
+ Record.AddLoadAverage(d);
+ }
+ }
+
+ TEvSystemStateUpdate(const TVector<std::tuple<TString, double, ui32>>& poolStats) {
for (const auto& row : poolStats) {
auto& pb = *Record.AddPoolStats();
pb.SetName(std::get<0>(row));
pb.SetUsage(std::get<1>(row));
- pb.SetThreads(std::get<2>(row));
+ pb.SetThreads(std::get<2>(row));
}
}
@@ -302,50 +302,50 @@ struct TEvWhiteboard{
pb->SetRoom(x.Room);
pb->SetRack(x.Rack);
pb->SetBody(x.Body);
- }
-
- TEvSystemStateUpdate(const NKikimrWhiteboard::TSystemStateInfo& systemStateInfo) {
- Record.CopyFrom(systemStateInfo);
- }
- };
-
- struct TEvSystemStateAddEndpoint : TEventLocal<TEvSystemStateAddEndpoint, EvSystemStateAddEndpoint> {
- TString Name;
- TString Address;
-
- TEvSystemStateAddEndpoint(const TString& name, const TString& address)
- : Name(name)
- , Address(address)
- {}
- };
-
- struct TEvSystemStateAddRole : TEventLocal<TEvSystemStateAddRole, EvSystemStateAddRole> {
- TString Role;
-
- TEvSystemStateAddRole(const TString& role)
- : Role(role)
- {}
- };
-
- struct TEvSystemStateSetTenant : TEventLocal<TEvSystemStateSetTenant, EvSystemStateSetTenant> {
- TString Tenant;
-
- TEvSystemStateSetTenant(const TString& tenant)
- : Tenant(tenant)
- {}
- };
-
- struct TEvSystemStateRemoveTenant : TEventLocal<TEvSystemStateRemoveTenant, EvSystemStateRemoveTenant> {
- TString Tenant;
-
- TEvSystemStateRemoveTenant(const TString& tenant)
- : Tenant(tenant)
- {}
- };
-
- struct TEvSystemStateRequest : public TEventPB<TEvSystemStateRequest, NKikimrWhiteboard::TEvSystemStateRequest, EvSystemStateRequest> {};
-
- struct TEvSystemStateResponse : public TEventPB<TEvSystemStateResponse, NKikimrWhiteboard::TEvSystemStateResponse, EvSystemStateResponse> {};
+ }
+
+ TEvSystemStateUpdate(const NKikimrWhiteboard::TSystemStateInfo& systemStateInfo) {
+ Record.CopyFrom(systemStateInfo);
+ }
+ };
+
+ struct TEvSystemStateAddEndpoint : TEventLocal<TEvSystemStateAddEndpoint, EvSystemStateAddEndpoint> {
+ TString Name;
+ TString Address;
+
+ TEvSystemStateAddEndpoint(const TString& name, const TString& address)
+ : Name(name)
+ , Address(address)
+ {}
+ };
+
+ struct TEvSystemStateAddRole : TEventLocal<TEvSystemStateAddRole, EvSystemStateAddRole> {
+ TString Role;
+
+ TEvSystemStateAddRole(const TString& role)
+ : Role(role)
+ {}
+ };
+
+ struct TEvSystemStateSetTenant : TEventLocal<TEvSystemStateSetTenant, EvSystemStateSetTenant> {
+ TString Tenant;
+
+ TEvSystemStateSetTenant(const TString& tenant)
+ : Tenant(tenant)
+ {}
+ };
+
+ struct TEvSystemStateRemoveTenant : TEventLocal<TEvSystemStateRemoveTenant, EvSystemStateRemoveTenant> {
+ TString Tenant;
+
+ TEvSystemStateRemoveTenant(const TString& tenant)
+ : Tenant(tenant)
+ {}
+ };
+
+ struct TEvSystemStateRequest : public TEventPB<TEvSystemStateRequest, NKikimrWhiteboard::TEvSystemStateRequest, EvSystemStateRequest> {};
+
+ struct TEvSystemStateResponse : public TEventPB<TEvSystemStateResponse, NKikimrWhiteboard::TEvSystemStateResponse, EvSystemStateResponse> {};
struct TEvNodeStateUpdate : TEventPB<TEvNodeStateUpdate, NKikimrWhiteboard::TNodeStateInfo, EvNodeStateUpdate> {
TEvNodeStateUpdate() = default;
@@ -398,14 +398,14 @@ struct TEvWhiteboard{
struct TEvSignalBodyRequest : TEventPB<TEvSignalBodyRequest, NKikimrWhiteboard::TEvSignalBodyRequest, EvSignalBodyRequest> {};
struct TEvSignalBodyResponse : TEventPB<TEvSignalBodyResponse, NKikimrWhiteboard::TEvSignalBodyResponse, EvSignalBodyResponse> {};
-};
-
+};
+
inline TActorId MakeNodeWhiteboardServiceId(ui32 node) {
- char x[12] = {'n','o','d','e','w','h','i','t','e','b','o','a'};
+ char x[12] = {'n','o','d','e','w','h','i','t','e','b','o','a'};
return TActorId(node, TStringBuf(x, 12));
-}
-
-IActor* CreateNodeWhiteboardService();
-
-} // NTabletState
-} // NKikimr
+}
+
+IActor* CreateNodeWhiteboardService();
+
+} // NTabletState
+} // NKikimr
diff --git a/ydb/core/persqueue/events/global.h b/ydb/core/persqueue/events/global.h
index 3030a36513d..e1957e7a16f 100644
--- a/ydb/core/persqueue/events/global.h
+++ b/ydb/core/persqueue/events/global.h
@@ -24,8 +24,8 @@ struct TEvPersQueue {
EvStatusResponse,
EvHasDataInfo, //how much data is available to fetch from partition
EvHasDataInfoResponse,
- EvPartitionClientInfo,
- EvPartitionClientInfoResponse,
+ EvPartitionClientInfo,
+ EvPartitionClientInfoResponse,
EvUpdateBalancerConfig,
EvRegisterReadSession,
EvLockPartition,
@@ -154,14 +154,14 @@ struct TEvPersQueue {
TEvDropTabletReply()
{}
};
-
- struct TEvPartitionClientInfo : TEventPB<TEvPartitionClientInfo, NKikimrPQ::TPartitionClientInfo, EvPartitionClientInfo> {
- TEvPartitionClientInfo() = default;
- };
-
- struct TEvPartitionClientInfoResponse : TEventPB<TEvPartitionClientInfoResponse, NKikimrPQ::TClientInfoResponse, EvPartitionClientInfoResponse> {
- TEvPartitionClientInfoResponse() = default;
- };
+
+ struct TEvPartitionClientInfo : TEventPB<TEvPartitionClientInfo, NKikimrPQ::TPartitionClientInfo, EvPartitionClientInfo> {
+ TEvPartitionClientInfo() = default;
+ };
+
+ struct TEvPartitionClientInfoResponse : TEventPB<TEvPartitionClientInfoResponse, NKikimrPQ::TClientInfoResponse, EvPartitionClientInfoResponse> {
+ TEvPartitionClientInfoResponse() = default;
+ };
struct TEvWakeupClient : TEventLocal<TEvWakeupClient, EvWakeupClient> {
TEvWakeupClient(const TString& client, const ui32 group)
diff --git a/ydb/core/persqueue/events/internal.h b/ydb/core/persqueue/events/internal.h
index ce7740fab20..bc892988b47 100644
--- a/ydb/core/persqueue/events/internal.h
+++ b/ydb/core/persqueue/events/internal.h
@@ -86,7 +86,7 @@ struct TEvPQ {
EvPartitionCounters,
EvTabletCacheCounters,
EvPartitionLabeledCounters,
- EvGetPartitionClientInfo,
+ EvGetPartitionClientInfo,
EvUpdateAvailableSize,
EvPipeDisconnected,
EvReserveBytes,
@@ -503,13 +503,13 @@ struct TEvPQ {
TCacheCounters Counters;
};
- struct TEvGetPartitionClientInfo : TEventLocal<TEvGetPartitionClientInfo, EvGetPartitionClientInfo> {
+ struct TEvGetPartitionClientInfo : TEventLocal<TEvGetPartitionClientInfo, EvGetPartitionClientInfo> {
TEvGetPartitionClientInfo(const TActorId& sender)
- : Sender(sender)
- {}
-
+ : Sender(sender)
+ {}
+
TActorId Sender;
- };
+ };
struct TEvUpdateAvailableSize : TEventLocal<TEvUpdateAvailableSize, EvUpdateAvailableSize> {
TEvUpdateAvailableSize()
diff --git a/ydb/core/persqueue/partition.cpp b/ydb/core/persqueue/partition.cpp
index 55c71028826..cc8e2419cf2 100644
--- a/ydb/core/persqueue/partition.cpp
+++ b/ydb/core/persqueue/partition.cpp
@@ -2048,36 +2048,36 @@ void TPartition::HandleOnInit(TEvPQ::TEvPartitionStatus::TPtr& ev, const TActorC
}
-void TPartition::Handle(TEvPQ::TEvGetPartitionClientInfo::TPtr& ev, const TActorContext& ctx) {
+void TPartition::Handle(TEvPQ::TEvGetPartitionClientInfo::TPtr& ev, const TActorContext& ctx) {
THolder<TEvPersQueue::TEvPartitionClientInfoResponse> response = MakeHolder<TEvPersQueue::TEvPartitionClientInfoResponse>();
- NKikimrPQ::TClientInfoResponse& result(response->Record);
- result.SetPartition(Partition);
- result.SetStartOffset(StartOffset);
- result.SetEndOffset(EndOffset);
- result.SetResponseTimestamp(ctx.Now().MilliSeconds());
+ NKikimrPQ::TClientInfoResponse& result(response->Record);
+ result.SetPartition(Partition);
+ result.SetStartOffset(StartOffset);
+ result.SetEndOffset(EndOffset);
+ result.SetResponseTimestamp(ctx.Now().MilliSeconds());
for (auto& pr : UsersInfoStorage.GetAll()) {
TUserInfo& userInfo(pr.second);
- NKikimrPQ::TClientInfo& clientInfo = *result.AddClientInfo();
- clientInfo.SetClientId(pr.first);
- auto& write = *clientInfo.MutableWritePosition();
- write.SetOffset(userInfo.Offset);
+ NKikimrPQ::TClientInfo& clientInfo = *result.AddClientInfo();
+ clientInfo.SetClientId(pr.first);
+ auto& write = *clientInfo.MutableWritePosition();
+ write.SetOffset(userInfo.Offset);
userInfo.EndOffset = EndOffset;
write.SetWriteTimestamp((userInfo.GetWriteTimestamp() ? userInfo.GetWriteTimestamp() : GetWriteTimeEstimate(userInfo.Offset)).MilliSeconds());
write.SetCreateTimestamp(userInfo.GetCreateTimestamp().MilliSeconds());
- auto& read = *clientInfo.MutableReadPosition();
- read.SetOffset(userInfo.GetReadOffset());
+ auto& read = *clientInfo.MutableReadPosition();
+ read.SetOffset(userInfo.GetReadOffset());
read.SetWriteTimestamp((userInfo.GetReadWriteTimestamp() ? userInfo.GetReadWriteTimestamp() : GetWriteTimeEstimate(userInfo.GetReadOffset())).MilliSeconds());
read.SetCreateTimestamp(userInfo.GetReadCreateTimestamp().MilliSeconds());
write.SetSize(GetSizeLag(userInfo.Offset));
read.SetSize(GetSizeLag(userInfo.GetReadOffset()));
- }
- ctx.Send(ev->Get()->Sender, response.Release(), 0, ev->Cookie);
-}
+ }
+ ctx.Send(ev->Get()->Sender, response.Release(), 0, ev->Cookie);
+}
void TPartition::Handle(TEvPersQueue::TEvReportPartitionError::TPtr& ev, const TActorContext& ctx) {
LogAndCollectError(ev->Get()->Record, ctx);
}
-
+
void TPartition::LogAndCollectError(const NKikimrPQ::TStatusResponse::TErrorMessage& error, const TActorContext& ctx) {
if (Errors.size() == MAX_ERRORS_COUNT_TO_STORE) {
Errors.pop_front();
diff --git a/ydb/core/persqueue/partition.h b/ydb/core/persqueue/partition.h
index 7d60941621c..2eec26f2516 100644
--- a/ydb/core/persqueue/partition.h
+++ b/ydb/core/persqueue/partition.h
@@ -115,7 +115,7 @@ private:
void HandleOnInit(TEvPQ::TEvPartitionStatus::TPtr& ev, const TActorContext& ctx);
void Handle(TEvPQ::TEvPartitionOffsets::TPtr& ev, const TActorContext& ctx);
void Handle(TEvPQ::TEvPartitionStatus::TPtr& ev, const TActorContext& ctx);
- void Handle(TEvPQ::TEvGetPartitionClientInfo::TPtr& ev, const TActorContext& ctx);
+ void Handle(TEvPQ::TEvGetPartitionClientInfo::TPtr& ev, const TActorContext& ctx);
void Handle(TEvPersQueue::TEvReportPartitionError::TPtr& ev, const TActorContext& ctx);
void LogAndCollectError(const NKikimrPQ::TStatusResponse::TErrorMessage& error, const TActorContext& ctx);
@@ -269,7 +269,7 @@ private:
HFuncTraced(TEvPersQueue::TEvHasDataInfo, Handle);
HFuncTraced(TEvPQ::TEvMirrorerCounters, Handle);
HFuncTraced(NReadSpeedLimiterEvents::TEvCounters, Handle);
- HFuncTraced(TEvPQ::TEvGetPartitionClientInfo, Handle);
+ HFuncTraced(TEvPQ::TEvGetPartitionClientInfo, Handle);
default:
LOG_ERROR_S(ctx, NKikimrServices::PERSQUEUE, "Unexpected " << EventStr("StateInit", ev));
break;
@@ -307,7 +307,7 @@ private:
HFuncTraced(NReadSpeedLimiterEvents::TEvCounters, Handle);
HFuncTraced(TEvPQ::TEvProxyResponse, Handle);
HFuncTraced(TEvPQ::TEvError, Handle);
- HFuncTraced(TEvPQ::TEvGetPartitionClientInfo, Handle);
+ HFuncTraced(TEvPQ::TEvGetPartitionClientInfo, Handle);
HFuncTraced(TEvPQ::TEvUpdateAvailableSize, HandleOnIdle);
HFuncTraced(TEvPQ::TEvReserveBytes, Handle);
HFuncTraced(TEvPQ::TEvPipeDisconnected, Handle);
@@ -356,7 +356,7 @@ private:
HFuncTraced(TEvPQ::TEvProxyResponse, Handle);
HFuncTraced(TEvPQ::TEvError, Handle);
HFuncTraced(TEvPQ::TEvReserveBytes, Handle);
- HFuncTraced(TEvPQ::TEvGetPartitionClientInfo, Handle);
+ HFuncTraced(TEvPQ::TEvGetPartitionClientInfo, Handle);
HFuncTraced(TEvPQ::TEvPipeDisconnected, Handle);
HFuncTraced(TEvPQ::TEvUpdateAvailableSize, HandleOnWrite);
HFuncTraced(TEvPQ::TEvQuotaDeadlineCheck, Handle);
diff --git a/ydb/core/persqueue/pq_impl.cpp b/ydb/core/persqueue/pq_impl.cpp
index d3c65574b92..9937dbe561c 100644
--- a/ydb/core/persqueue/pq_impl.cpp
+++ b/ydb/core/persqueue/pq_impl.cpp
@@ -893,7 +893,7 @@ void TPersQueue::AggregateAndSendLabeledCountersFor(const TString& group, const
}
}
}
-
+
Y_VERIFY(aggr->HasCounters());
TActorId countersAggregator = MakeTabletCountersAggregatorID(ctx.SelfID.NodeId());
@@ -1245,20 +1245,20 @@ void TPersQueue::Handle(TEvPersQueue::TEvHasDataInfo::TPtr& ev, const TActorCont
}
-void TPersQueue::Handle(TEvPersQueue::TEvPartitionClientInfo::TPtr& ev, const TActorContext& ctx) {
- for (auto partition : ev->Get()->Record.GetPartitions()) {
- auto it = Partitions.find(partition);
- if (it != Partitions.end()) {
- ctx.Send(it->second.Actor, new TEvPQ::TEvGetPartitionClientInfo(ev->Sender), 0, ev->Cookie);
- } else {
+void TPersQueue::Handle(TEvPersQueue::TEvPartitionClientInfo::TPtr& ev, const TActorContext& ctx) {
+ for (auto partition : ev->Get()->Record.GetPartitions()) {
+ auto it = Partitions.find(partition);
+ if (it != Partitions.end()) {
+ ctx.Send(it->second.Actor, new TEvPQ::TEvGetPartitionClientInfo(ev->Sender), 0, ev->Cookie);
+ } else {
THolder<TEvPersQueue::TEvPartitionClientInfoResponse> clientInfo = MakeHolder<TEvPersQueue::TEvPartitionClientInfoResponse>();
- clientInfo->Record.SetPartition(partition);
- ctx.Send(ev->Sender, clientInfo.Release(), 0, ev->Cookie);
- }
- }
-}
-
-
+ clientInfo->Record.SetPartition(partition);
+ ctx.Send(ev->Sender, clientInfo.Release(), 0, ev->Cookie);
+ }
+ }
+}
+
+
void TPersQueue::Handle(TEvPersQueue::TEvStatus::TPtr& ev, const TActorContext& ctx)
{
if (!ConfigInited) {
@@ -2162,7 +2162,7 @@ bool TPersQueue::HandleHook(STFUNC_SIG)
HFuncTraced(TEvPersQueue::TEvOffsets, Handle);
HFuncTraced(TEvPersQueue::TEvHasDataInfo, Handle);
HFuncTraced(TEvPersQueue::TEvStatus, Handle);
- HFuncTraced(TEvPersQueue::TEvPartitionClientInfo, Handle);
+ HFuncTraced(TEvPersQueue::TEvPartitionClientInfo, Handle);
HFuncTraced(TEvKeyValue::TEvResponse, Handle);
HFuncTraced(TEvPQ::TEvInitComplete, Handle);
HFuncTraced(TEvPQ::TEvPartitionCounters, Handle);
diff --git a/ydb/core/persqueue/pq_impl.h b/ydb/core/persqueue/pq_impl.h
index 024826cc49b..bc3bfb10ba5 100644
--- a/ydb/core/persqueue/pq_impl.h
+++ b/ydb/core/persqueue/pq_impl.h
@@ -63,7 +63,7 @@ class TPersQueue : public NKeyValue::TKeyValueFlat {
void Handle(TEvPersQueue::TEvStatus::TPtr& ev, const TActorContext& ctx);
void Handle(TEvPersQueue::TEvDropTablet::TPtr& ev, const TActorContext& ctx);
void Handle(TEvPersQueue::TEvHasDataInfo::TPtr& ev, const TActorContext& ctx);
- void Handle(TEvPersQueue::TEvPartitionClientInfo::TPtr& ev, const TActorContext& ctx);
+ void Handle(TEvPersQueue::TEvPartitionClientInfo::TPtr& ev, const TActorContext& ctx);
bool OnRenderAppHtmlPage(NMon::TEvRemoteHttpInfo::TPtr ev, const TActorContext& ctx) override;
diff --git a/ydb/core/persqueue/pq_ut.cpp b/ydb/core/persqueue/pq_ut.cpp
index e70b9590eca..13a61229105 100644
--- a/ydb/core/persqueue/pq_ut.cpp
+++ b/ydb/core/persqueue/pq_ut.cpp
@@ -313,7 +313,7 @@ Y_UNIT_TEST(TestCheckACL) {
TFakeSchemeShardState::TPtr state{new TFakeSchemeShardState()};
ui64 ssId = 9876;
BootFakeSchemeShard(*tc.Runtime, ssId, state);
- IActor* ticketParser = NKikimr::CreateTicketParser(tc.Runtime->GetAppData().AuthConfig);
+ IActor* ticketParser = NKikimr::CreateTicketParser(tc.Runtime->GetAppData().AuthConfig);
TActorId ticketParserId = tc.Runtime->Register(ticketParser);
tc.Runtime->RegisterService(NKikimr::MakeTicketParserID(), ticketParserId);
diff --git a/ydb/core/persqueue/read_balancer.cpp b/ydb/core/persqueue/read_balancer.cpp
index 967849f4d63..4eb9c7206dd 100644
--- a/ydb/core/persqueue/read_balancer.cpp
+++ b/ydb/core/persqueue/read_balancer.cpp
@@ -675,7 +675,7 @@ void TPersQueueReadBalancer::Handle(NSchemeShard::TEvSchemeShard::TEvDescribeSch
if (!WaitingForACL) //ignore if already processed
return;
WaitingForACL = false;
- const auto& record = ev->Get()->GetRecord();
+ const auto& record = ev->Get()->GetRecord();
if (record.GetStatus() == NKikimrScheme::EStatus::StatusSuccess) {
ACL.Clear();
Y_PROTOBUF_SUPPRESS_NODISCARD ACL.MutableACL()->ParseFromString(record.GetPathDescription().GetSelf().GetEffectiveACL());
diff --git a/ydb/core/persqueue/user_info.h b/ydb/core/persqueue/user_info.h
index 658d64e4bb9..258e947c467 100644
--- a/ydb/core/persqueue/user_info.h
+++ b/ydb/core/persqueue/user_info.h
@@ -464,35 +464,35 @@ struct TUserInfo {
}
return false;
}
-
+
void SetImportant(bool important)
{
Important = important;
LabeledCounters.SetGroup(User + "/" + (important ? "1" : "0") + "/" + Topic);
}
- i64 GetReadOffset() const {
+ i64 GetReadOffset() const {
return ReadOffset == -1 ? Offset : (ReadOffset + 1); //+1 because we want to track first not readed offset
- }
-
+ }
+
TInstant GetReadTimestamp() const {
return ReadTimestamp;
}
TInstant GetWriteTimestamp() const {
return Offset == EndOffset ? TAppData::TimeProvider->Now() : WriteTimestamp;
- }
-
+ }
+
TInstant GetCreateTimestamp() const {
return Offset == EndOffset ? TAppData::TimeProvider->Now() : CreateTimestamp;
- }
-
+ }
+
TInstant GetReadWriteTimestamp() const {
TInstant ts = ReadOffset == -1 ? WriteTimestamp : ReadWriteTimestamp;
ts = GetReadOffset() >= EndOffset ? TAppData::TimeProvider->Now() : ts;
return ts;
- }
-
+ }
+
ui64 GetWriteLagMs() const {
return WriteLagMs.GetValue();
}
@@ -501,7 +501,7 @@ struct TUserInfo {
TInstant ts = ReadOffset == -1 ? CreateTimestamp : ReadCreateTimestamp;
ts = GetReadOffset() >= EndOffset ? TAppData::TimeProvider->Now() : ts;
return ts;
- }
+ }
};
diff --git a/ydb/core/protos/alloc.proto b/ydb/core/protos/alloc.proto
index 2e695df3bfd..9d73ab2183c 100644
--- a/ydb/core/protos/alloc.proto
+++ b/ydb/core/protos/alloc.proto
@@ -1,7 +1,7 @@
-syntax = "proto3";
-package NKikimrConfig;
-option java_package = "ru.yandex.kikimr.proto";
-
-message TAllocatorConfig {
- map<string, string> Param = 1;
-};
+syntax = "proto3";
+package NKikimrConfig;
+option java_package = "ru.yandex.kikimr.proto";
+
+message TAllocatorConfig {
+ map<string, string> Param = 1;
+};
diff --git a/ydb/core/protos/auth.proto b/ydb/core/protos/auth.proto
index cf1b19c0ee5..1f252b8f711 100644
--- a/ydb/core/protos/auth.proto
+++ b/ydb/core/protos/auth.proto
@@ -1,47 +1,47 @@
-package NKikimrProto;
+package NKikimrProto;
option java_package = "ru.yandex.kikimr.proto";
message TAuthConfig {
optional TUserRegistryConfig UserRegistryConfig = 1;
optional TTVMConfig TVMConfig = 2;
- optional string StaffApiUserToken = 3;
- optional string BlackBoxEndpoint = 4 [default = "blackbox.yandex-team.ru"];
- optional string AccessServiceEndpoint = 5 [default = "as.private-api.cloud.yandex.net:4286"];
- optional string UserAccountServiceEndpoint = 6 [default = "api-adapter.private-api.cloud.yandex.net:8443"];
- optional string ServiceAccountServiceEndpoint = 7 [default = "api-adapter.private-api.cloud.yandex.net:8443"];
- optional string StaffEndpoint = 10 [default = "staff-api.yandex-team.ru"];
- optional uint32 GrpcCacheSize = 16 [default = 1024];
- optional uint64 GrpcSuccessLifeTime = 17 [default = 60000]; // ms
- optional uint64 GrpcErrorLifeTime = 18 [default = 10000]; // ms
- optional bool UseBlackBox = 20 [default = true];
- optional bool UseAccessService = 21 [default = false];
- optional bool CacheAccessServiceAuthentication = 22 [default = true];
- optional bool CacheAccessServiceAuthorization = 23 [default = true];
- optional bool UseStaff = 25 [default = true];
- optional bool UseUserAccountService = 26 [default = false];
- optional bool UseServiceAccountService = 27 [default = false];
- optional bool UseLoginProvider = 29 [default = true];
- optional bool UseAccessServiceTLS = 31 [default = true];
- optional bool UseUserAccountServiceTLS = 32 [default = true];
- optional bool UseServiceAccountServiceTLS = 33 [default = true];
- optional bool CacheUserAccountService = 37 [default = true];
- optional bool CacheServiceAccountService = 38 [default = true];
- optional string TvmServiceDomain = 40 [default = "tvm"];
- optional string BlackBoxDomain = 41 [default = "blackbox"];
- optional string AccessServiceDomain = 42 [default = "as"];
- optional string UserAccountDomain = 43 [default = "passport"];
- optional string ServiceDomain = 44 [default = "service"];
- optional bool DomainLoginOnly = 45 [default = true];
- optional string RefreshPeriod = 50 [default = "1s"]; // how often do we check for ticket freshness/expiration
- optional string RefreshTime = 51 [default = "1h"]; // we will try to refresh valid ticket within RefreshTime/2 and RefreshTime randomly
- optional string LifeTime = 52 [default = "1h"]; // for how long ticket will remain in the cache after last access
- optional string ExpireTime = 53 [default = "24h"]; // after what time ticket will expired and removed from the cache
- optional string TVMExpireTime = 54 [default = "2m"]; // the same for TVM tickets
- optional string MinErrorRefreshTime = 55 [default = "1s"]; // min period for refresh of error ticket
- optional string MaxErrorRefreshTime = 56 [default = "1m"]; // max period for refresh of error ticket
- optional string PathToRootCA = 60 [default = "/etc/ssl/certs/YandexInternalRootCA.pem"]; // root CA certificate PEM/x509
- optional uint32 AccessServiceGrpcKeepAliveTimeMs = 70 [default = 10000]; // CLOUD-27573
- optional uint32 AccessServiceGrpcKeepAliveTimeoutMs = 71 [default = 1000]; // CLOUD-27573
+ optional string StaffApiUserToken = 3;
+ optional string BlackBoxEndpoint = 4 [default = "blackbox.yandex-team.ru"];
+ optional string AccessServiceEndpoint = 5 [default = "as.private-api.cloud.yandex.net:4286"];
+ optional string UserAccountServiceEndpoint = 6 [default = "api-adapter.private-api.cloud.yandex.net:8443"];
+ optional string ServiceAccountServiceEndpoint = 7 [default = "api-adapter.private-api.cloud.yandex.net:8443"];
+ optional string StaffEndpoint = 10 [default = "staff-api.yandex-team.ru"];
+ optional uint32 GrpcCacheSize = 16 [default = 1024];
+ optional uint64 GrpcSuccessLifeTime = 17 [default = 60000]; // ms
+ optional uint64 GrpcErrorLifeTime = 18 [default = 10000]; // ms
+ optional bool UseBlackBox = 20 [default = true];
+ optional bool UseAccessService = 21 [default = false];
+ optional bool CacheAccessServiceAuthentication = 22 [default = true];
+ optional bool CacheAccessServiceAuthorization = 23 [default = true];
+ optional bool UseStaff = 25 [default = true];
+ optional bool UseUserAccountService = 26 [default = false];
+ optional bool UseServiceAccountService = 27 [default = false];
+ optional bool UseLoginProvider = 29 [default = true];
+ optional bool UseAccessServiceTLS = 31 [default = true];
+ optional bool UseUserAccountServiceTLS = 32 [default = true];
+ optional bool UseServiceAccountServiceTLS = 33 [default = true];
+ optional bool CacheUserAccountService = 37 [default = true];
+ optional bool CacheServiceAccountService = 38 [default = true];
+ optional string TvmServiceDomain = 40 [default = "tvm"];
+ optional string BlackBoxDomain = 41 [default = "blackbox"];
+ optional string AccessServiceDomain = 42 [default = "as"];
+ optional string UserAccountDomain = 43 [default = "passport"];
+ optional string ServiceDomain = 44 [default = "service"];
+ optional bool DomainLoginOnly = 45 [default = true];
+ optional string RefreshPeriod = 50 [default = "1s"]; // how often do we check for ticket freshness/expiration
+ optional string RefreshTime = 51 [default = "1h"]; // we will try to refresh valid ticket within RefreshTime/2 and RefreshTime randomly
+ optional string LifeTime = 52 [default = "1h"]; // for how long ticket will remain in the cache after last access
+ optional string ExpireTime = 53 [default = "24h"]; // after what time ticket will expired and removed from the cache
+ optional string TVMExpireTime = 54 [default = "2m"]; // the same for TVM tickets
+ optional string MinErrorRefreshTime = 55 [default = "1s"]; // min period for refresh of error ticket
+ optional string MaxErrorRefreshTime = 56 [default = "1m"]; // max period for refresh of error ticket
+ optional string PathToRootCA = 60 [default = "/etc/ssl/certs/YandexInternalRootCA.pem"]; // root CA certificate PEM/x509
+ optional uint32 AccessServiceGrpcKeepAliveTimeMs = 70 [default = 10000]; // CLOUD-27573
+ optional uint32 AccessServiceGrpcKeepAliveTimeoutMs = 71 [default = 1000]; // CLOUD-27573
}
message TUserRegistryConfig {
diff --git a/ydb/core/protos/bind_channel_storage_pool.proto b/ydb/core/protos/bind_channel_storage_pool.proto
index 5b1fdd51da4..f9b1943aae6 100644
--- a/ydb/core/protos/bind_channel_storage_pool.proto
+++ b/ydb/core/protos/bind_channel_storage_pool.proto
@@ -7,9 +7,9 @@ message TStoragePool {
}
message TChannelBind {
- //optional uint32 Channel = 1; // it should be equal to array index, so it doesn't make any sense to have one
+ //optional uint32 Channel = 1; // it should be equal to array index, so it doesn't make any sense to have one
optional string StoragePoolName = 2;
- optional float IOPS = 10;
- optional uint64 Throughput = 11;
- optional uint64 Size = 12;
+ optional float IOPS = 10;
+ optional uint64 Throughput = 11;
+ optional uint64 Size = 12;
}
diff --git a/ydb/core/protos/blobstorage.proto b/ydb/core/protos/blobstorage.proto
index 3b47ae6478c..a08ccbf865c 100644
--- a/ydb/core/protos/blobstorage.proto
+++ b/ydb/core/protos/blobstorage.proto
@@ -960,7 +960,7 @@ message TNodeWardenServiceSet {
}
optional NKikimrBlobStorage.TVDiskID VDiskID = 1;
optional TVDiskLocation VDiskLocation = 2;
- optional TVDiskKind.EVDiskKind VDiskKind = 3;
+ optional TVDiskKind.EVDiskKind VDiskKind = 3;
optional bool DoDestroy = 4 [default = false];
optional bool DoWipe = 5 [default = false];
optional EEntityStatus EntityStatus = 6;
@@ -1078,19 +1078,19 @@ message TEvControllerProposeGroupKey {
optional uint64 GroupKeyNonce = 7 [default = 0];
}
-message TStorageOwnerGroupInfo {
- optional uint32 GroupID = 1;
- optional uint64 ReadThroughput = 2; // bytes per second
- optional uint64 WriteThroughput = 3; // bytes per second
- optional uint64 DataSize = 4;
-}
-
-message TStorageOwnerInfo {
- optional uint64 OwnerID = 1;
- repeated TStorageOwnerGroupInfo GroupInfo = 2;
- optional uint64 DataSize = 3;
-}
-
+message TStorageOwnerGroupInfo {
+ optional uint32 GroupID = 1;
+ optional uint64 ReadThroughput = 2; // bytes per second
+ optional uint64 WriteThroughput = 3; // bytes per second
+ optional uint64 DataSize = 4;
+}
+
+message TStorageOwnerInfo {
+ optional uint64 OwnerID = 1;
+ repeated TStorageOwnerGroupInfo GroupInfo = 2;
+ optional uint64 DataSize = 3;
+}
+
message TEvControllerSelectGroups {
message TStoragePoolSpecifier {
optional string Name = 1; // filter by name if set
@@ -1099,17 +1099,17 @@ message TEvControllerSelectGroups {
message TGroupParameters {
optional uint32 ErasureSpecies = 1;
optional uint64 DesiredPDiskCategory = 2;
- optional uint64 DesiredVDiskCategory = 3;
- optional float RequiredIOPS = 4;
- optional uint64 RequiredThroughput = 5;
- optional uint64 RequiredDataSize = 6;
+ optional uint64 DesiredVDiskCategory = 3;
+ optional float RequiredIOPS = 4;
+ optional uint64 RequiredThroughput = 5;
+ optional uint64 RequiredDataSize = 6;
optional TStoragePoolSpecifier StoragePoolSpecifier = 7;
-
+
}
reserved 1;
reserved 2;
repeated TGroupParameters GroupParameters = 3;
- optional TStorageOwnerInfo StorageOwnerInfo = 4;
+ optional TStorageOwnerInfo StorageOwnerInfo = 4;
optional uint64 ObjectId = 5; // scheme object id
optional bool ReturnAllMatchingGroups = 6; // when true, then all matching groups are returned
optional bool BlockUntilAllResourcesAreComplete = 7; // do not respond unless resources for all groups are filled up
@@ -1140,8 +1140,8 @@ message TEvControllerUpdateDiskStatus {
repeated NKikimrBlobStorage.TVDiskMetrics VDisksMetrics = 1;
repeated NKikimrBlobStorage.TPDiskMetrics PDisksMetrics = 2;
repeated TVDiskStatus VDiskStatus = 3;
-}
-
+}
+
message TEvGroupStatReport {
message TLatencyHistogram {
repeated uint32 Buckets = 1;
@@ -1217,30 +1217,30 @@ message TEvControllerScrubReportQuantumInProgress {
optional NKikimrBlobStorage.TVSlotId VSlotId = 1;
}
-message TEvRequestBSControllerInfo {
- optional uint32 GroupId = 1;
-}
-
-message TEvResponseBSControllerInfo {
- message TVDiskInfo {
+message TEvRequestBSControllerInfo {
+ optional uint32 GroupId = 1;
+}
+
+message TEvResponseBSControllerInfo {
+ message TVDiskInfo {
optional NKikimrBlobStorage.TVDiskID VDiskId = 1;
- optional uint32 PDiskId = 2;
- optional uint32 NodeId = 3;
- optional uint64 PDiskCategory = 4;
- optional uint64 VDiskCategory = 5; // Kind
- }
- message TBSGroupInfo {
- optional uint32 GroupId = 1;
- optional uint32 ErasureSpecies = 2;
- repeated TVDiskInfo VDiskInfo = 3;
+ optional uint32 PDiskId = 2;
+ optional uint32 NodeId = 3;
+ optional uint64 PDiskCategory = 4;
+ optional uint64 VDiskCategory = 5; // Kind
+ }
+ message TBSGroupInfo {
+ optional uint32 GroupId = 1;
+ optional uint32 ErasureSpecies = 2;
+ repeated TVDiskInfo VDiskInfo = 3;
//optional uint64 ReadThroughput = 4; // bytes per second
//optional uint64 WriteThroughput = 5; // bytes per second
- optional uint64 DataSize = 6;
+ optional uint64 DataSize = 6;
//optional uint64 Counter = 7; // usage counter
- }
- repeated TBSGroupInfo BSGroupInfo = 1;
-}
-
+ }
+ repeated TBSGroupInfo BSGroupInfo = 1;
+}
+
message TEvControllerNodeReport {
enum EVDiskPhase {
UNKNOWN = 0;
diff --git a/ydb/core/protos/blobstorage_vdisk_config.proto b/ydb/core/protos/blobstorage_vdisk_config.proto
index fb1f3bffbf4..5b800c1cf65 100644
--- a/ydb/core/protos/blobstorage_vdisk_config.proto
+++ b/ydb/core/protos/blobstorage_vdisk_config.proto
@@ -34,7 +34,7 @@ message TVDiskKind {
Test2 = 2;
Test3 = 3;
// optimized for tablet log
- Log = 10;
+ Log = 10;
LocalMode = 11;
Extra2 = 22;
Extra3 = 23;
diff --git a/ydb/core/protos/config.proto b/ydb/core/protos/config.proto
index e22a8611343..d64169d4fc0 100644
--- a/ydb/core/protos/config.proto
+++ b/ydb/core/protos/config.proto
@@ -119,11 +119,11 @@ message TStaticNameserviceConfig {
NS_EXTERNAL = 3; // may be paired with external discovery
}
- message TEndpoint {
- optional string Name = 1;
- optional string Address = 2;
- }
-
+ message TEndpoint {
+ optional string Name = 1;
+ optional string Address = 2;
+ }
+
message TNode { // todo: multiple networks
optional uint32 NodeId = 1;
@@ -134,8 +134,8 @@ message TStaticNameserviceConfig {
optional string InterconnectHost = 5;
optional NActorsInterconnect.TNodeLocation Location = 6;
-
- repeated TEndpoint Endpoint = 7;
+
+ repeated TEndpoint Endpoint = 7;
optional NActorsInterconnect.TNodeLocation WalleLocation = 8 [deprecated=true];
}
@@ -197,7 +197,7 @@ message TDomainsConfig {
optional uint32 SchemeBoardSSId = 15;
}
- message THiveConfig { // look for another THiveConfig later in this file
+ message THiveConfig { // look for another THiveConfig later in this file
optional uint32 HiveUid = 1;
optional fixed64 Hive = 2;
}
@@ -210,22 +210,22 @@ message TDomainsConfig {
optional NKikimrSchemeOp.TCompactionPolicy Policy = 2;
}
- message TSecurityConfig {
- optional bool EnforceUserTokenRequirement = 1 [default = false];
- repeated string MonitoringAllowedSIDs = 2;
- repeated string AdministrationAllowedSIDs = 3;
- repeated string DefaultUserSIDs = 4;
- optional string AllAuthenticatedUsers = 5;
- repeated string ViewerAllowedSIDs = 6;
- }
-
+ message TSecurityConfig {
+ optional bool EnforceUserTokenRequirement = 1 [default = false];
+ repeated string MonitoringAllowedSIDs = 2;
+ repeated string AdministrationAllowedSIDs = 3;
+ repeated string DefaultUserSIDs = 4;
+ optional string AllAuthenticatedUsers = 5;
+ repeated string ViewerAllowedSIDs = 6;
+ }
+
repeated TDomain Domain = 1;
repeated TStateStorage StateStorage = 2;
repeated TExecLevel ExecLevel = 3;
repeated THiveConfig HiveConfig = 4;
repeated TNamedCompactionPolicy NamedCompactionPolicy = 5;
- optional TSecurityConfig SecurityConfig = 6;
- optional bool ForbidImplicitStoragePools = 7 [default = true];
+ optional TSecurityConfig SecurityConfig = 6;
+ optional bool ForbidImplicitStoragePools = 7 [default = true];
}
message TBlobStorageConfig {
@@ -303,9 +303,9 @@ message TBootstrap {
TX_COORDINATOR = 10;
TX_MEDIATOR = 11;
TX_PROXY = 12;
- FLAT_TX_COORDINATOR = 13;
- FLAT_HIVE = 14;
- FLAT_BS_CONTROLLER = 15;
+ FLAT_TX_COORDINATOR = 13;
+ FLAT_HIVE = 14;
+ FLAT_BS_CONTROLLER = 15;
FLAT_TX_PROXY = 17;
TX_ALLOCATOR = 18;
@@ -421,7 +421,7 @@ message TChannelProfileConfig {
message TChannel {
optional string ErasureSpecies = 1;
optional uint64 PDiskCategory = 2;
- optional NKikimrBlobStorage.TVDiskKind.EVDiskKind VDiskCategory = 3 [default = Default];
+ optional NKikimrBlobStorage.TVDiskKind.EVDiskKind VDiskCategory = 3 [default = Default];
// this option uses new BS configuration interface to obtain matching groups, and it must not be provided
// with any of the above fields
@@ -471,17 +471,17 @@ message TMonitoringConfig {
};
optional uint32 MonitoringPort = 1 [default = 0];
- optional uint32 MonitoringThreads = 2 [default = 10];
- optional string MonitoringCaption = 3 [default = "YDB Monitoring"];
+ optional uint32 MonitoringThreads = 2 [default = 10];
+ optional string MonitoringCaption = 3 [default = "YDB Monitoring"];
optional uint32 TabletMonitoringRetries = 4 [default = 1];
optional bool ForceDatabaseLabels = 5 [default = false];
- optional string MonitoringAddress = 6;
+ optional string MonitoringAddress = 6;
optional TDatabaseLabels DatabaseLabels = 7;
optional TDatabaseAttributeLabels DatabaseAttributeLabels = 8;
optional string DataCenter = 9;
optional string HostLabelOverride = 10;
optional string ProcessLocation = 11;
- optional string AllowOrigin = 12;
+ optional string AllowOrigin = 12;
optional string RedirectMainPageTo = 13 [default = "monitoring/"];
}
@@ -585,8 +585,8 @@ message TGRpcConfig {
// empty service list is 'run most services "what means 'most' in unspecified"'
repeated string Services = 20;
optional bool ServeRootDomains = 21 [default = true];
- repeated string ServicesEnabled = 22;
- repeated string ServicesDisabled = 23;
+ repeated string ServicesEnabled = 22;
+ repeated string ServicesDisabled = 23;
// server socket options
optional bool KeepAliveEnable = 100 [default = true]; // SO_KEEPALIVE
@@ -629,7 +629,7 @@ message TFeatureFlags {
optional bool SendSchemaVersionToDatashard = 14 [default = true]; // deprecated: always true
optional bool EnableSchemeBoardCache = 15 [default = true]; // deprecated: always true
optional bool EnableSystemViews = 16 [default = true];
- optional bool EnableExternalHive = 17 [default = true];
+ optional bool EnableExternalHive = 17 [default = true];
optional bool UseSchemeBoardCacheForSchemeRequests = 18 [default = true]; // deprecated: always true
optional bool CompileMinikqlWithVersion = 19 [default = true]; // deprecated: always true
optional bool ReadTableWithSnapshot = 20 [default = true];
@@ -1192,98 +1192,98 @@ message TMeteringConfig {
repeated string SystemBackupSIDs = 2;
};
-message THiveTabletLimit {
- optional NKikimrTabletBase.TTabletTypes.EType Type = 1;
- optional uint64 MaxCount = 2;
-}
-
-message THiveTabletPreference {
- optional NKikimrTabletBase.TTabletTypes.EType Type = 1;
- optional NKikimrHive.TDataCentersPreference DataCentersPreference = 10;
-}
-
-message THiveConfig {
- enum EHiveStorageBalanceStrategy {
- HIVE_STORAGE_BALANCE_STRATEGY_AUTO = 0;
- HIVE_STORAGE_BALANCE_STRATEGY_IOPS = 1;
- HIVE_STORAGE_BALANCE_STRATEGY_THROUGHPUT = 2;
- HIVE_STORAGE_BALANCE_STRATEGY_SIZE = 3;
- }
-
- enum EHiveStorageSelectStrategy {
- HIVE_STORAGE_SELECT_STRATEGY_WEIGHTED_RANDOM = 0;
- HIVE_STORAGE_SELECT_STRATEGY_EXACT_MIN = 1;
- HIVE_STORAGE_SELECT_STRATEGY_RANDOM_MIN_7P = 2;
- HIVE_STORAGE_SELECT_STRATEGY_ROUND_ROBIN = 3;
- HIVE_STORAGE_SELECT_STRATEGY_RANDOM = 4;
- }
-
- enum EHiveNodeBalanceStrategy {
- HIVE_NODE_BALANCE_STRATEGY_OLD_WEIGHTED_RANDOM = 0;
- HIVE_NODE_BALANCE_STRATEGY_HEAVIEST = 1;
- HIVE_NODE_BALANCE_STRATEGY_RANDOM = 2;
- HIVE_NODE_BALANCE_STRATEGY_WEIGHTED_RANDOM = 3;
- }
-
- enum EHiveTabletBalanceStrategy {
- HIVE_TABLET_BALANCE_STRATEGY_OLD_WEIGHTED_RANDOM = 0;
- HIVE_TABLET_BALANCE_STRATEGY_HEAVIEST = 1;
- HIVE_TABLET_BALANCE_STRATEGY_RANDOM = 2;
- HIVE_TABLET_BALANCE_STRATEGY_WEIGHTED_RANDOM = 3;
- }
-
- enum EHiveNodeSelectStrategy {
- HIVE_NODE_SELECT_STRATEGY_WEIGHTED_RANDOM = 0;
- HIVE_NODE_SELECT_STRATEGY_EXACT_MIN = 1;
- HIVE_NODE_SELECT_STRATEGY_RANDOM_MIN_7P = 2;
- HIVE_NODE_SELECT_STRATEGY_RANDOM = 3;
- }
-
- optional uint64 MaxTabletsScheduled = 2 [default = 100];
- optional uint64 MaxResourceCounter = 3 [default = 100000000];
- optional uint64 MaxResourceCPU = 4 [default = 10000000];
- optional uint64 MaxResourceMemory = 5 [default = 512000000000];
- optional uint64 MaxResourceNetwork = 6 [default = 1000000000];
- optional double MinScatterToBalance = 7 [default = 1.01];
- optional bool SpreadNeighbours = 8 [default = true];
- optional uint64 MaxBootBatchSize = 9 [default = 1000];
- optional uint64 DrainInflight = 10 [default = 10];
- optional double DefaultUnitIOPS = 11 [default = 1]; // operations/sec
- optional uint64 DefaultUnitThroughput = 12 [default = 1000]; // bytes/sec
- optional uint64 DefaultUnitSize = 13 [default = 100000000]; // bytes
- optional double StorageOvercommit = 14 [default = 1.00];
- optional EHiveStorageBalanceStrategy StorageBalanceStrategy = 15 [default = HIVE_STORAGE_BALANCE_STRATEGY_SIZE];
- optional bool StorageSafeMode = 16 [default = true];
- optional EHiveStorageSelectStrategy StorageSelectStrategy = 17 [default = HIVE_STORAGE_SELECT_STRATEGY_WEIGHTED_RANDOM];
- optional uint64 RequestSequenceSize = 18 [default = 1000];
- optional uint64 MinRequestSequenceSize = 19 [default = 1000];
- optional uint64 MaxRequestSequenceSize = 20 [default = 1000000];
- optional uint64 MetricsWindowSize = 21 [default = 60000]; // milliseconds
- optional double MaxNodeUsageToKick = 22 [default = 1.01];
- optional uint64 ResourceChangeReactionPeriod = 23 [default = 10]; // seconds
- optional uint64 TabletKickCooldownPeriod = 24 [default = 1800]; // seconds
- optional double ResourceOvercommitment = 25 [default = 3.00];
- optional uint64 BalancerInflight = 26 [default = 1]; // tablets
- optional EHiveNodeBalanceStrategy NodeBalanceStrategy = 27 [default = HIVE_NODE_BALANCE_STRATEGY_HEAVIEST];
- optional EHiveTabletBalanceStrategy TabletBalanceStrategy = 28 [default = HIVE_TABLET_BALANCE_STRATEGY_WEIGHTED_RANDOM];
- optional double MinPeriodBetweenBalance = 29 [default = 1.0]; // seconds
- optional uint64 MaxMovementsOnAutoBalancer = 30 [default = 1]; // tablets
- optional bool ContinueAutoBalancer = 31 [default = true];
- optional double MinNodeUsageToBalance = 32 [default = 1.01];
- optional double MinPeriodBetweenReassign = 33 [default = 300.0]; // seconds
- optional double TabletRestartWatchPeriod = 34 [default = 3600.0]; // seconds
- optional double NodeRestartWatchPeriod = 35 [default = 3600.0]; // seconds
- optional uint64 NodeDeletePeriod = 36 [default = 14400]; // seconds
- repeated THiveTabletLimit DefaultTabletLimit = 37;
- repeated THiveTabletPreference DefaultTabletPreference = 38;
- optional uint64 SystemTabletCategoryId = 39 [default = 1];
- optional bool EnableFastTabletMove = 40 [default = true];
- optional uint64 TabletRestartsPeriod = 42 [default = 1000]; // milliseconds
- optional uint64 TabletRestarsMaxCount = 43 [default = 2]; // number
- optional uint64 PostponeStartPeriod = 44 [default = 1000]; // milliseconds
- optional EHiveNodeSelectStrategy NodeSelectStrategy = 45 [default = HIVE_NODE_SELECT_STRATEGY_RANDOM_MIN_7P];
-}
-
+message THiveTabletLimit {
+ optional NKikimrTabletBase.TTabletTypes.EType Type = 1;
+ optional uint64 MaxCount = 2;
+}
+
+message THiveTabletPreference {
+ optional NKikimrTabletBase.TTabletTypes.EType Type = 1;
+ optional NKikimrHive.TDataCentersPreference DataCentersPreference = 10;
+}
+
+message THiveConfig {
+ enum EHiveStorageBalanceStrategy {
+ HIVE_STORAGE_BALANCE_STRATEGY_AUTO = 0;
+ HIVE_STORAGE_BALANCE_STRATEGY_IOPS = 1;
+ HIVE_STORAGE_BALANCE_STRATEGY_THROUGHPUT = 2;
+ HIVE_STORAGE_BALANCE_STRATEGY_SIZE = 3;
+ }
+
+ enum EHiveStorageSelectStrategy {
+ HIVE_STORAGE_SELECT_STRATEGY_WEIGHTED_RANDOM = 0;
+ HIVE_STORAGE_SELECT_STRATEGY_EXACT_MIN = 1;
+ HIVE_STORAGE_SELECT_STRATEGY_RANDOM_MIN_7P = 2;
+ HIVE_STORAGE_SELECT_STRATEGY_ROUND_ROBIN = 3;
+ HIVE_STORAGE_SELECT_STRATEGY_RANDOM = 4;
+ }
+
+ enum EHiveNodeBalanceStrategy {
+ HIVE_NODE_BALANCE_STRATEGY_OLD_WEIGHTED_RANDOM = 0;
+ HIVE_NODE_BALANCE_STRATEGY_HEAVIEST = 1;
+ HIVE_NODE_BALANCE_STRATEGY_RANDOM = 2;
+ HIVE_NODE_BALANCE_STRATEGY_WEIGHTED_RANDOM = 3;
+ }
+
+ enum EHiveTabletBalanceStrategy {
+ HIVE_TABLET_BALANCE_STRATEGY_OLD_WEIGHTED_RANDOM = 0;
+ HIVE_TABLET_BALANCE_STRATEGY_HEAVIEST = 1;
+ HIVE_TABLET_BALANCE_STRATEGY_RANDOM = 2;
+ HIVE_TABLET_BALANCE_STRATEGY_WEIGHTED_RANDOM = 3;
+ }
+
+ enum EHiveNodeSelectStrategy {
+ HIVE_NODE_SELECT_STRATEGY_WEIGHTED_RANDOM = 0;
+ HIVE_NODE_SELECT_STRATEGY_EXACT_MIN = 1;
+ HIVE_NODE_SELECT_STRATEGY_RANDOM_MIN_7P = 2;
+ HIVE_NODE_SELECT_STRATEGY_RANDOM = 3;
+ }
+
+ optional uint64 MaxTabletsScheduled = 2 [default = 100];
+ optional uint64 MaxResourceCounter = 3 [default = 100000000];
+ optional uint64 MaxResourceCPU = 4 [default = 10000000];
+ optional uint64 MaxResourceMemory = 5 [default = 512000000000];
+ optional uint64 MaxResourceNetwork = 6 [default = 1000000000];
+ optional double MinScatterToBalance = 7 [default = 1.01];
+ optional bool SpreadNeighbours = 8 [default = true];
+ optional uint64 MaxBootBatchSize = 9 [default = 1000];
+ optional uint64 DrainInflight = 10 [default = 10];
+ optional double DefaultUnitIOPS = 11 [default = 1]; // operations/sec
+ optional uint64 DefaultUnitThroughput = 12 [default = 1000]; // bytes/sec
+ optional uint64 DefaultUnitSize = 13 [default = 100000000]; // bytes
+ optional double StorageOvercommit = 14 [default = 1.00];
+ optional EHiveStorageBalanceStrategy StorageBalanceStrategy = 15 [default = HIVE_STORAGE_BALANCE_STRATEGY_SIZE];
+ optional bool StorageSafeMode = 16 [default = true];
+ optional EHiveStorageSelectStrategy StorageSelectStrategy = 17 [default = HIVE_STORAGE_SELECT_STRATEGY_WEIGHTED_RANDOM];
+ optional uint64 RequestSequenceSize = 18 [default = 1000];
+ optional uint64 MinRequestSequenceSize = 19 [default = 1000];
+ optional uint64 MaxRequestSequenceSize = 20 [default = 1000000];
+ optional uint64 MetricsWindowSize = 21 [default = 60000]; // milliseconds
+ optional double MaxNodeUsageToKick = 22 [default = 1.01];
+ optional uint64 ResourceChangeReactionPeriod = 23 [default = 10]; // seconds
+ optional uint64 TabletKickCooldownPeriod = 24 [default = 1800]; // seconds
+ optional double ResourceOvercommitment = 25 [default = 3.00];
+ optional uint64 BalancerInflight = 26 [default = 1]; // tablets
+ optional EHiveNodeBalanceStrategy NodeBalanceStrategy = 27 [default = HIVE_NODE_BALANCE_STRATEGY_HEAVIEST];
+ optional EHiveTabletBalanceStrategy TabletBalanceStrategy = 28 [default = HIVE_TABLET_BALANCE_STRATEGY_WEIGHTED_RANDOM];
+ optional double MinPeriodBetweenBalance = 29 [default = 1.0]; // seconds
+ optional uint64 MaxMovementsOnAutoBalancer = 30 [default = 1]; // tablets
+ optional bool ContinueAutoBalancer = 31 [default = true];
+ optional double MinNodeUsageToBalance = 32 [default = 1.01];
+ optional double MinPeriodBetweenReassign = 33 [default = 300.0]; // seconds
+ optional double TabletRestartWatchPeriod = 34 [default = 3600.0]; // seconds
+ optional double NodeRestartWatchPeriod = 35 [default = 3600.0]; // seconds
+ optional uint64 NodeDeletePeriod = 36 [default = 14400]; // seconds
+ repeated THiveTabletLimit DefaultTabletLimit = 37;
+ repeated THiveTabletPreference DefaultTabletPreference = 38;
+ optional uint64 SystemTabletCategoryId = 39 [default = 1];
+ optional bool EnableFastTabletMove = 40 [default = true];
+ optional uint64 TabletRestartsPeriod = 42 [default = 1000]; // milliseconds
+ optional uint64 TabletRestarsMaxCount = 43 [default = 2]; // number
+ optional uint64 PostponeStartPeriod = 44 [default = 1000]; // milliseconds
+ optional EHiveNodeSelectStrategy NodeSelectStrategy = 45 [default = HIVE_NODE_SELECT_STRATEGY_RANDOM_MIN_7P];
+}
+
message TDataShardConfig {
optional string BackupTaskName = 1 [default = "backup"];
optional uint32 BackupTaskPriority = 2 [default = 10];
@@ -1313,7 +1313,7 @@ message TCompactionConfig {
// This message is used to upload custom service configs
// to CMS. Config name is used to identify owner and
// data format.
-// Custom config validators should b8e used to detect name
+// Custom config validators should b8e used to detect name
// conflicts and check config consistency.
message TNamedConfig {
optional string Name = 1;
@@ -1343,7 +1343,7 @@ message TAppConfig {
optional TRestartsCountConfig RestartsCountConfig = 11;
optional TMessageBusConfig MessageBusConfig = 12;
optional TTabletsConfig TabletsConfig = 13; // alternative bootstrapper configuration
- optional NKikimrBlobStorage.TAllVDiskKinds VDiskConfig = 14;
+ optional NKikimrBlobStorage.TAllVDiskKinds VDiskConfig = 14;
optional NKikimrBlobStorage.TDriveModelList DriveModelConfig = 31;
optional NKikimrBlobStorage.TIncrHugeConfig IncrHugeConfig = 18;
optional string UDFsDir = 15;
@@ -1359,7 +1359,7 @@ message TAppConfig {
optional TSqsConfig SqsConfig = 27;
optional NKikimrPQ.TPQConfig PQConfig = 28;
optional NKikimrTenantPool.TTenantPoolConfig TenantPoolConfig = 29;
- optional NKikimrProto.TAuthConfig AuthConfig = 30;
+ optional NKikimrProto.TAuthConfig AuthConfig = 30;
optional NKikimrTenantSlotBroker.TConfig TenantSlotBrokerConfig = 32;
optional TConfigsDispatcherConfig ConfigsDispatcherConfig = 33;
optional TTableProfilesConfig TableProfilesConfig = 34;
@@ -1369,13 +1369,13 @@ message TAppConfig {
optional TTableServiceConfig TableServiceConfig = 37;
optional NKikimrSharedCache.TSharedCacheConfig SharedCacheConfig = 38; // dynamic configuration via cms
optional TImmediateControlsConfig ImmediateControlsConfig = 39;
- optional TAllocatorConfig AllocatorConfig = 40;
+ optional TAllocatorConfig AllocatorConfig = 40;
optional NKikimrPQ.TPQClusterDiscoveryConfig PQClusterDiscoveryConfig = 41;
optional NKikimrNetClassifier.TNetClassifierConfig NetClassifierConfig = 42;
optional NKikimrNetClassifier.TNetClassifierDistributableConfig NetClassifierDistributableConfig = 43; // also dynamic via cms
optional NKikimrResourceBroker.TResourceBrokerConfig ResourceBrokerConfig = 44;
optional TMeteringConfig MeteringConfig = 45;
- optional THiveConfig HiveConfig = 46;
+ optional THiveConfig HiveConfig = 46;
optional TDataShardConfig DataShardConfig = 49;
optional NYq.NConfig.TConfig YandexQueryConfig = 50;
optional TCompactionConfig CompactionConfig = 52;
diff --git a/ydb/core/protos/console_config.proto b/ydb/core/protos/console_config.proto
index 54330556613..d5a32d05c66 100644
--- a/ydb/core/protos/console_config.proto
+++ b/ydb/core/protos/console_config.proto
@@ -107,7 +107,7 @@ message TConfigItem {
NetClassifierDistributableConfigItem = 43;
ResourceBrokerConfigItem = 44;
MeteringConfigItem = 45;
- HiveConfigItem = 46;
+ HiveConfigItem = 46;
DataShardConfigItem = 49;
YandexQueryConfigItem = 50;
PDiskKeyConfigItem = 51;
diff --git a/ydb/core/protos/counters_datashard.proto b/ydb/core/protos/counters_datashard.proto
index f9bfa4a72a0..956a1369378 100644
--- a/ydb/core/protos/counters_datashard.proto
+++ b/ydb/core/protos/counters_datashard.proto
@@ -168,29 +168,29 @@ enum EPercentileCounters {
COUNTER_LOCKS_LIFETIME = 8 [(CounterOpts) = {Name: "LocksLifetime"}];
COUNTER_PROPOSE_QUEUE_LATENCY = 9 [(CounterOpts) = {Name: "ProposeQueueLatency"}];
-
- COUNTER_HIST_RANGE_READ_BYTES = 10 [(CounterOpts) = {Name: "HIST(DataShard/EngineHostRangeReadBytes)",
- Ranges { Value: 0 Name: "0" }
- Ranges { Value: 1 Name: "1024" }
- Ranges { Value: 1024 Name: "2048" }
- Ranges { Value: 2048 Name: "4096" }
- Ranges { Value: 4096 Name: "8192" }
- Ranges { Value: 8192 Name: "16384" }
- Ranges { Value: 16384 Name: "32768" }
- Ranges { Value: 32768 Name: "65536" }
- Ranges { Value: 65536 Name: "131072" }
- Ranges { Value: 131072 Name: "262144" }
- Ranges { Value: 262144 Name: "524288" }
- Ranges { Value: 524288 Name: "1048576" }
- Ranges { Value: 1048576 Name: "2097152" }
- Ranges { Value: 2097152 Name: "4194304" }
- Ranges { Value: 4194304 Name: "8388608" }
- Ranges { Value: 8388608 Name: "16777216" }
- Ranges { Value: 16777216 Name: "33554432" }
- Ranges { Value: 33554432 Name: "67108864" }
- Ranges { Value: 67108864 Name: "134217728" }
- Ranges { Value: 134217728 Name: "inf" }
- }];
+
+ COUNTER_HIST_RANGE_READ_BYTES = 10 [(CounterOpts) = {Name: "HIST(DataShard/EngineHostRangeReadBytes)",
+ Ranges { Value: 0 Name: "0" }
+ Ranges { Value: 1 Name: "1024" }
+ Ranges { Value: 1024 Name: "2048" }
+ Ranges { Value: 2048 Name: "4096" }
+ Ranges { Value: 4096 Name: "8192" }
+ Ranges { Value: 8192 Name: "16384" }
+ Ranges { Value: 16384 Name: "32768" }
+ Ranges { Value: 32768 Name: "65536" }
+ Ranges { Value: 65536 Name: "131072" }
+ Ranges { Value: 131072 Name: "262144" }
+ Ranges { Value: 262144 Name: "524288" }
+ Ranges { Value: 524288 Name: "1048576" }
+ Ranges { Value: 1048576 Name: "2097152" }
+ Ranges { Value: 2097152 Name: "4194304" }
+ Ranges { Value: 4194304 Name: "8388608" }
+ Ranges { Value: 8388608 Name: "16777216" }
+ Ranges { Value: 16777216 Name: "33554432" }
+ Ranges { Value: 33554432 Name: "67108864" }
+ Ranges { Value: 67108864 Name: "134217728" }
+ Ranges { Value: 134217728 Name: "inf" }
+ }];
COUNTER_SELECT_ROWS_PER_REQUEST = 11 [(CounterOpts) = {Name: "SelectRowsPerRequest",
Ranges: { Value: 0 Name: "0"},
diff --git a/ydb/core/protos/counters_hive.proto b/ydb/core/protos/counters_hive.proto
index 350aea9f5ab..952f4e99e3c 100644
--- a/ydb/core/protos/counters_hive.proto
+++ b/ydb/core/protos/counters_hive.proto
@@ -11,30 +11,30 @@ enum ESimpleCounters {
COUNTER_TABLETS_ALIVE = 1 [(CounterOpts) = {Name: "TabletsAlive"}];
COUNTER_BOOTQUEUE_SIZE = 2 [(CounterOpts) = {Name: "BootQueueSize"}];
COUNTER_STATE_DONE = 3 [(CounterOpts) = {Name: "StateDone"}];
- COUNTER_RESPONSE_TIME_USEC = 4 [(CounterOpts) = {Name: "ResponseTimeMicrosec"}];
- COUNTER_METRICS_COUNTER = 5 [(CounterOpts) = {Name: "MetricsCounter"}];
- COUNTER_METRICS_CPU = 6 [(CounterOpts) = {Name: "MetricsCPU"}];
- COUNTER_METRICS_MEMORY = 7 [(CounterOpts) = {Name: "MetricsMemory"}];
- COUNTER_METRICS_NETWORK = 8 [(CounterOpts) = {Name: "MetricsNetwork"}];
- COUNTER_BALANCE_SCATTER = 9 [(CounterOpts) = {Name: "BalanceScatter"}];
- COUNTER_WAITQUEUE_SIZE = 10 [(CounterOpts) = {Name: "WaitQueueSize"}];
- COUNTER_BALANCE_USAGE_MIN = 11 [(CounterOpts) = {Name: "BalanceUsageMin"}];
- COUNTER_BALANCE_USAGE_MAX = 12 [(CounterOpts) = {Name: "BalanceUsageMax"}];
+ COUNTER_RESPONSE_TIME_USEC = 4 [(CounterOpts) = {Name: "ResponseTimeMicrosec"}];
+ COUNTER_METRICS_COUNTER = 5 [(CounterOpts) = {Name: "MetricsCounter"}];
+ COUNTER_METRICS_CPU = 6 [(CounterOpts) = {Name: "MetricsCPU"}];
+ COUNTER_METRICS_MEMORY = 7 [(CounterOpts) = {Name: "MetricsMemory"}];
+ COUNTER_METRICS_NETWORK = 8 [(CounterOpts) = {Name: "MetricsNetwork"}];
+ COUNTER_BALANCE_SCATTER = 9 [(CounterOpts) = {Name: "BalanceScatter"}];
+ COUNTER_WAITQUEUE_SIZE = 10 [(CounterOpts) = {Name: "WaitQueueSize"}];
+ COUNTER_BALANCE_USAGE_MIN = 11 [(CounterOpts) = {Name: "BalanceUsageMin"}];
+ COUNTER_BALANCE_USAGE_MAX = 12 [(CounterOpts) = {Name: "BalanceUsageMax"}];
}
enum ECumulativeCounters {
- COUNTER_BOOTQUEUE_PROCESSED = 0 [(CounterOpts) = {Name: "BootQueueProcessed"}];
- COUNTER_BOOTQUEUE_TIME = 1 [(CounterOpts) = {Name: "BootQueueTime"}];
- COUNTER_AUTOKICK_EXECUTED = 2 [(CounterOpts) = {Name: "AutokickExecuted"}]; // obsolete
- COUNTER_AUTOKICK_FAILED = 3 [(CounterOpts) = {Name: "AutokickFailed"}]; // obsolete
- COUNTER_BALANCER_EXECUTED = 4 [(CounterOpts) = {Name: "BalancerExecuted"}];
- COUNTER_BALANCER_FAILED = 5 [(CounterOpts) = {Name: "BalancerFailed"}];
- COUNTER_DRAIN_EXECUTED = 6 [(CounterOpts) = {Name: "DrainExecuted"}];
- COUNTER_DRAIN_FAILED = 7 [(CounterOpts) = {Name: "DrainFailed"}];
- COUNTER_FILL_EXECUTED = 8 [(CounterOpts) = {Name: "FillExecuted"}];
- COUNTER_TABLETS_MOVED = 9 [(CounterOpts) = {Name: "TabletsMoved"}];
- COUNTER_SUGGESTED_SCALE_UP = 10 [(CounterOpts) = {Name: "SuggestedScaleUp"}];
- COUNTER_SUGGESTED_SCALE_DOWN = 11 [(CounterOpts) = {Name: "SuggestedScaleDown"}];
+ COUNTER_BOOTQUEUE_PROCESSED = 0 [(CounterOpts) = {Name: "BootQueueProcessed"}];
+ COUNTER_BOOTQUEUE_TIME = 1 [(CounterOpts) = {Name: "BootQueueTime"}];
+ COUNTER_AUTOKICK_EXECUTED = 2 [(CounterOpts) = {Name: "AutokickExecuted"}]; // obsolete
+ COUNTER_AUTOKICK_FAILED = 3 [(CounterOpts) = {Name: "AutokickFailed"}]; // obsolete
+ COUNTER_BALANCER_EXECUTED = 4 [(CounterOpts) = {Name: "BalancerExecuted"}];
+ COUNTER_BALANCER_FAILED = 5 [(CounterOpts) = {Name: "BalancerFailed"}];
+ COUNTER_DRAIN_EXECUTED = 6 [(CounterOpts) = {Name: "DrainExecuted"}];
+ COUNTER_DRAIN_FAILED = 7 [(CounterOpts) = {Name: "DrainFailed"}];
+ COUNTER_FILL_EXECUTED = 8 [(CounterOpts) = {Name: "FillExecuted"}];
+ COUNTER_TABLETS_MOVED = 9 [(CounterOpts) = {Name: "TabletsMoved"}];
+ COUNTER_SUGGESTED_SCALE_UP = 10 [(CounterOpts) = {Name: "SuggestedScaleUp"}];
+ COUNTER_SUGGESTED_SCALE_DOWN = 11 [(CounterOpts) = {Name: "SuggestedScaleDown"}];
}
enum EPercentileCounters {
@@ -55,53 +55,53 @@ enum ETxTypes {
TXTYPE_REGISTER_NODE = 5 [(TxTypeOpts) = {Name: "TxRegisterNode"}];
TXTYPE_KILL_NODE = 6 [(TxTypeOpts) = {Name: "TxKillNode"}];
TXTYPE_ADOPT_TABLET = 7 [(TxTypeOpts) = {Name: "TxAdoptTablet"}];
- TXTYPE_UPDATE_TABLET_METRIC = 8 [(TxTypeOpts) = {Name: "TxUpdateTabletMetric"}];
- TXTYPE_UPDATE_TABLET_GROUPS = 9 [(TxTypeOpts) = {Name: "TxUpdateTabletGroups"}];
- TXTYPE_UNLOCK_TABLET_EXECUTION = 10 [(TxTypeOpts) = {Name: "TxUnlockTabletExecution"}];
- TXTYPE_REASSIGN_GROUPS = 11 [(TxTypeOpts) = {Name: "TxReassignGroups"}];
- TXTYPE_LOCK_TABLET_EXECUTION = 12 [(TxTypeOpts) = {Name: "TxLockTabletExecution"}];
- TXTYPE_LOAD_EVERYTHING = 13 [(TxTypeOpts) = {Name: "TxLoadEverything"}];
- TXTYPE_INIT_SCHEME = 14 [(TxTypeOpts) = {Name: "TxInitScheme"}];
- TXTYPE_DELETE_TABLET_RESULT = 15 [(TxTypeOpts) = {Name: "TxDeleteTabletResult"}];
- TXTYPE_DELETE_TABLET = 16 [(TxTypeOpts) = {Name: "TxDeleteTablet"}];
- TXTYPE_CUT_TABLET_HISTORY = 17 [(TxTypeOpts) = {Name: "TxCutTabletHistory"}];
- TXTYPE_BLOCK_STORAGE_RESULT = 18 [(TxTypeOpts) = {Name: "TxBlockStorageResult"}];
- TXTYPE_REQUEST_TABLET_SEQUENCE = 19 [(TxTypeOpts) = {Name: "TxRequestTabletSequence"}];
- TXTYPE_RESPONSE_TABLET_SEQUENCE = 20 [(TxTypeOpts) = {Name: "TxResponseTabletSequence"}];
- TXTYPE_PROCESS_PENDING_OPERATIONS = 21 [(TxTypeOpts) = {Name: "TxProcessPendingOperations"}];
- TXTYPE_MON_DB_STATE = 22 [(TxTypeOpts) = {Name: "TxMonDbState"}];
- TXTYPE_MON_MEM_STATE = 23 [(TxTypeOpts) = {Name: "TxMonMemState"}];
- TXTYPE_MON_RESOURCES = 24 [(TxTypeOpts) = {Name: "TxMonResources"}];
- TXTYPE_MON_SETTINGS = 25 [(TxTypeOpts) = {Name: "TxMonSettings"}];
- TXTYPE_MON_LANDING = 26 [(TxTypeOpts) = {Name: "TxMonLanding"}];
- TXTYPE_MON_LANDING_DATA = 27 [(TxTypeOpts) = {Name: "TxMonLandingData"}];
- TXTYPE_MON_SET_DOWN = 28 [(TxTypeOpts) = {Name: "TxMonSetDown"}];
- TXTYPE_MON_SET_FREEZE = 29 [(TxTypeOpts) = {Name: "TxMonSetFreeze"}];
- TXTYPE_MON_KICK_NODE = 30 [(TxTypeOpts) = {Name: "TxMonKickNode"}];
- TXTYPE_MON_REBALANCE = 31 [(TxTypeOpts) = {Name: "TxMonRebalance"}];
- TXTYPE_MON_REASSIGN_TABLET = 32 [(TxTypeOpts) = {Name: "TxMonReassignTablet"}];
- TXTYPE_MON_RESET_TABLET = 33 [(TxTypeOpts) = {Name: "TxMonResetTablet"}];
- TXTYPE_MON_GROUPS = 34 [(TxTypeOpts) = {Name: "TxMonGroups"}];
- TXTYPE_MON_NOT_READY = 35 [(TxTypeOpts) = {Name: "TxMonNotReady"}];
- TXTYPE_MON_STORAGE = 36 [(TxTypeOpts) = {Name: "TxMonStorage"}];
- TXTYPE_PROCESS_BOOT_QUEUE = 37 [(TxTypeOpts) = {Name: "TxProcessBootQueue"}];
- TXTYPE_STATUS = 38 [(TxTypeOpts) = {Name: "TxStatus"}];
- TXTYPE_DISCONNECT_NODE = 39 [(TxTypeOpts) = {Name: "TxDisconnectNode"}];
- TXTYPE_MON_FIND_TABLET = 40 [(TxTypeOpts) = {Name: "TxMonFindTablet"}];
- TXTYPE_UPDATE_DOMAIN = 41 [(TxTypeOpts) = {Name: "TxUpdateDomain"}];
- TXTYPE_MON_STOP_TABLET = 42 [(TxTypeOpts) = {Name: "TxMonStopTablet"}];
- TXTYPE_MON_RESUME_TABLET = 43 [(TxTypeOpts) = {Name: "TxMonResumeTablet"}];
- TXTYPE_CONFIGURE_SUBDOMAIN = 44 [(TxTypeOpts) = {Name: "TxConfigureSubdomain"}];
- TXTYPE_MON_INIT_MIGRATION = 45 [(TxTypeOpts) = {Name: "TxMonInitMigration"}];
- TXTYPE_MON_QUERY_MIGRATION = 46 [(TxTypeOpts) = {Name: "TxMonQueryMigration"}];
- TXTYPE_SEIZE_TABLETS = 47 [(TxTypeOpts) = {Name: "TxSeizeTablets"}];
- TXTYPE_SEIZE_TABLETS_REPLY = 48 [(TxTypeOpts) = {Name: "TxSeizeTabletsReply"}];
- TXTYPE_RELEASE_TABLETS = 49 [(TxTypeOpts) = {Name: "TxReleaseTablets"}];
- TXTYPE_RELEASE_TABLETS_REPLY = 50 [(TxTypeOpts) = {Name: "TxReleaseTabletsReply"}];
- TXTYPE_MON_DRAIN_NODE = 51 [(TxTypeOpts) = {Name: "TxMonDrainNode"}];
- TXTYPE_MON_TABLET_INFO = 52 [(TxTypeOpts) = {Name: "TxMonTabletInfo"}];
- TXTYPE_START_TABLET = 53 [(TxTypeOpts) = {Name: "TxStartTablet"}];
- TXTYPE_STOP_TABLET = 54 [(TxTypeOpts) = {Name: "TxStopTablet"}];
- TXTYPE_RESUME_TABLET = 55 [(TxTypeOpts) = {Name: "TxResumeTablet"}];
- TXTYPE_RESTART_TABLET = 56 [(TxTypeOpts) = {Name: "TxRestartTablet"}];
+ TXTYPE_UPDATE_TABLET_METRIC = 8 [(TxTypeOpts) = {Name: "TxUpdateTabletMetric"}];
+ TXTYPE_UPDATE_TABLET_GROUPS = 9 [(TxTypeOpts) = {Name: "TxUpdateTabletGroups"}];
+ TXTYPE_UNLOCK_TABLET_EXECUTION = 10 [(TxTypeOpts) = {Name: "TxUnlockTabletExecution"}];
+ TXTYPE_REASSIGN_GROUPS = 11 [(TxTypeOpts) = {Name: "TxReassignGroups"}];
+ TXTYPE_LOCK_TABLET_EXECUTION = 12 [(TxTypeOpts) = {Name: "TxLockTabletExecution"}];
+ TXTYPE_LOAD_EVERYTHING = 13 [(TxTypeOpts) = {Name: "TxLoadEverything"}];
+ TXTYPE_INIT_SCHEME = 14 [(TxTypeOpts) = {Name: "TxInitScheme"}];
+ TXTYPE_DELETE_TABLET_RESULT = 15 [(TxTypeOpts) = {Name: "TxDeleteTabletResult"}];
+ TXTYPE_DELETE_TABLET = 16 [(TxTypeOpts) = {Name: "TxDeleteTablet"}];
+ TXTYPE_CUT_TABLET_HISTORY = 17 [(TxTypeOpts) = {Name: "TxCutTabletHistory"}];
+ TXTYPE_BLOCK_STORAGE_RESULT = 18 [(TxTypeOpts) = {Name: "TxBlockStorageResult"}];
+ TXTYPE_REQUEST_TABLET_SEQUENCE = 19 [(TxTypeOpts) = {Name: "TxRequestTabletSequence"}];
+ TXTYPE_RESPONSE_TABLET_SEQUENCE = 20 [(TxTypeOpts) = {Name: "TxResponseTabletSequence"}];
+ TXTYPE_PROCESS_PENDING_OPERATIONS = 21 [(TxTypeOpts) = {Name: "TxProcessPendingOperations"}];
+ TXTYPE_MON_DB_STATE = 22 [(TxTypeOpts) = {Name: "TxMonDbState"}];
+ TXTYPE_MON_MEM_STATE = 23 [(TxTypeOpts) = {Name: "TxMonMemState"}];
+ TXTYPE_MON_RESOURCES = 24 [(TxTypeOpts) = {Name: "TxMonResources"}];
+ TXTYPE_MON_SETTINGS = 25 [(TxTypeOpts) = {Name: "TxMonSettings"}];
+ TXTYPE_MON_LANDING = 26 [(TxTypeOpts) = {Name: "TxMonLanding"}];
+ TXTYPE_MON_LANDING_DATA = 27 [(TxTypeOpts) = {Name: "TxMonLandingData"}];
+ TXTYPE_MON_SET_DOWN = 28 [(TxTypeOpts) = {Name: "TxMonSetDown"}];
+ TXTYPE_MON_SET_FREEZE = 29 [(TxTypeOpts) = {Name: "TxMonSetFreeze"}];
+ TXTYPE_MON_KICK_NODE = 30 [(TxTypeOpts) = {Name: "TxMonKickNode"}];
+ TXTYPE_MON_REBALANCE = 31 [(TxTypeOpts) = {Name: "TxMonRebalance"}];
+ TXTYPE_MON_REASSIGN_TABLET = 32 [(TxTypeOpts) = {Name: "TxMonReassignTablet"}];
+ TXTYPE_MON_RESET_TABLET = 33 [(TxTypeOpts) = {Name: "TxMonResetTablet"}];
+ TXTYPE_MON_GROUPS = 34 [(TxTypeOpts) = {Name: "TxMonGroups"}];
+ TXTYPE_MON_NOT_READY = 35 [(TxTypeOpts) = {Name: "TxMonNotReady"}];
+ TXTYPE_MON_STORAGE = 36 [(TxTypeOpts) = {Name: "TxMonStorage"}];
+ TXTYPE_PROCESS_BOOT_QUEUE = 37 [(TxTypeOpts) = {Name: "TxProcessBootQueue"}];
+ TXTYPE_STATUS = 38 [(TxTypeOpts) = {Name: "TxStatus"}];
+ TXTYPE_DISCONNECT_NODE = 39 [(TxTypeOpts) = {Name: "TxDisconnectNode"}];
+ TXTYPE_MON_FIND_TABLET = 40 [(TxTypeOpts) = {Name: "TxMonFindTablet"}];
+ TXTYPE_UPDATE_DOMAIN = 41 [(TxTypeOpts) = {Name: "TxUpdateDomain"}];
+ TXTYPE_MON_STOP_TABLET = 42 [(TxTypeOpts) = {Name: "TxMonStopTablet"}];
+ TXTYPE_MON_RESUME_TABLET = 43 [(TxTypeOpts) = {Name: "TxMonResumeTablet"}];
+ TXTYPE_CONFIGURE_SUBDOMAIN = 44 [(TxTypeOpts) = {Name: "TxConfigureSubdomain"}];
+ TXTYPE_MON_INIT_MIGRATION = 45 [(TxTypeOpts) = {Name: "TxMonInitMigration"}];
+ TXTYPE_MON_QUERY_MIGRATION = 46 [(TxTypeOpts) = {Name: "TxMonQueryMigration"}];
+ TXTYPE_SEIZE_TABLETS = 47 [(TxTypeOpts) = {Name: "TxSeizeTablets"}];
+ TXTYPE_SEIZE_TABLETS_REPLY = 48 [(TxTypeOpts) = {Name: "TxSeizeTabletsReply"}];
+ TXTYPE_RELEASE_TABLETS = 49 [(TxTypeOpts) = {Name: "TxReleaseTablets"}];
+ TXTYPE_RELEASE_TABLETS_REPLY = 50 [(TxTypeOpts) = {Name: "TxReleaseTabletsReply"}];
+ TXTYPE_MON_DRAIN_NODE = 51 [(TxTypeOpts) = {Name: "TxMonDrainNode"}];
+ TXTYPE_MON_TABLET_INFO = 52 [(TxTypeOpts) = {Name: "TxMonTabletInfo"}];
+ TXTYPE_START_TABLET = 53 [(TxTypeOpts) = {Name: "TxStartTablet"}];
+ TXTYPE_STOP_TABLET = 54 [(TxTypeOpts) = {Name: "TxStopTablet"}];
+ TXTYPE_RESUME_TABLET = 55 [(TxTypeOpts) = {Name: "TxResumeTablet"}];
+ TXTYPE_RESTART_TABLET = 56 [(TxTypeOpts) = {Name: "TxRestartTablet"}];
}
diff --git a/ydb/core/protos/counters_keyvalue.proto b/ydb/core/protos/counters_keyvalue.proto
index 92b13df5665..973df1d569b 100644
--- a/ydb/core/protos/counters_keyvalue.proto
+++ b/ydb/core/protos/counters_keyvalue.proto
@@ -167,807 +167,807 @@ enum EPercentileCounters {
COUNTER_LATENCY_FULL_WO = 9 [(CounterOpts) = {Name: "LatencyFullWo"}];
COUNTER_LATENCY_FULL_RW = 10 [(CounterOpts) = {Name: "LatencyFullRw"}];
COUNTER_LATENCY_FULL_RO_INLINE = 11 [(CounterOpts) = {Name: "LatencyFullRoInline"}];
-
- COUNTER_HIST_READ_BYTES_CHANNEL_0 = 12 [(CounterOpts) = {Name: "HIST(KV/ReadBytesChannel0)"
- Ranges { Value: 0 Name: "0" }
- Ranges { Value: 1 Name: "1024" }
- Ranges { Value: 1024 Name: "2048" }
- Ranges { Value: 2048 Name: "4096" }
- Ranges { Value: 4096 Name: "8192" }
- Ranges { Value: 8192 Name: "16384" }
- Ranges { Value: 16384 Name: "32768" }
- Ranges { Value: 32768 Name: "65536" }
- Ranges { Value: 65536 Name: "131072" }
- Ranges { Value: 131072 Name: "262144" }
- Ranges { Value: 262144 Name: "524288" }
- Ranges { Value: 524288 Name: "1048576" }
- Ranges { Value: 1048576 Name: "2097152" }
- Ranges { Value: 2097152 Name: "4194304" }
- Ranges { Value: 4194304 Name: "5242880" }
- Ranges { Value: 5242880 Name: "6291456" }
- Ranges { Value: 6291456 Name: "8388608" }
- Ranges { Value: 8388608 Name: "16777216" }
- Ranges { Value: 16777216 Name: "33554432" }
- Ranges { Value: 33554432 Name: "67108864" }
- Ranges { Value: 67108864 Name: "inf" }
- }
- ];
-
- COUNTER_HIST_READ_BYTES_CHANNEL_1 = 13 [(CounterOpts) = {Name: "HIST(KV/ReadBytesChannel1)"
- Ranges { Value: 0 Name: "0" }
- Ranges { Value: 1 Name: "1024" }
- Ranges { Value: 1024 Name: "2048" }
- Ranges { Value: 2048 Name: "4096" }
- Ranges { Value: 4096 Name: "8192" }
- Ranges { Value: 8192 Name: "16384" }
- Ranges { Value: 16384 Name: "32768" }
- Ranges { Value: 32768 Name: "65536" }
- Ranges { Value: 65536 Name: "131072" }
- Ranges { Value: 131072 Name: "262144" }
- Ranges { Value: 262144 Name: "524288" }
- Ranges { Value: 524288 Name: "1048576" }
- Ranges { Value: 1048576 Name: "2097152" }
- Ranges { Value: 2097152 Name: "4194304" }
- Ranges { Value: 4194304 Name: "5242880" }
- Ranges { Value: 5242880 Name: "6291456" }
- Ranges { Value: 6291456 Name: "8388608" }
- Ranges { Value: 8388608 Name: "16777216" }
- Ranges { Value: 16777216 Name: "33554432" }
- Ranges { Value: 33554432 Name: "67108864" }
- Ranges { Value: 67108864 Name: "inf" }
- }
- ];
-
- COUNTER_HIST_READ_BYTES_CHANNEL_2 = 14 [(CounterOpts) = {Name: "HIST(KV/ReadBytesChannel2)"
- Ranges { Value: 0 Name: "0" }
- Ranges { Value: 1 Name: "1024" }
- Ranges { Value: 1024 Name: "2048" }
- Ranges { Value: 2048 Name: "4096" }
- Ranges { Value: 4096 Name: "8192" }
- Ranges { Value: 8192 Name: "16384" }
- Ranges { Value: 16384 Name: "32768" }
- Ranges { Value: 32768 Name: "65536" }
- Ranges { Value: 65536 Name: "131072" }
- Ranges { Value: 131072 Name: "262144" }
- Ranges { Value: 262144 Name: "524288" }
- Ranges { Value: 524288 Name: "1048576" }
- Ranges { Value: 1048576 Name: "2097152" }
- Ranges { Value: 2097152 Name: "4194304" }
- Ranges { Value: 4194304 Name: "5242880" }
- Ranges { Value: 5242880 Name: "6291456" }
- Ranges { Value: 6291456 Name: "8388608" }
- Ranges { Value: 8388608 Name: "16777216" }
- Ranges { Value: 16777216 Name: "33554432" }
- Ranges { Value: 33554432 Name: "67108864" }
- Ranges { Value: 67108864 Name: "inf" }
- }
- ];
-
- COUNTER_HIST_READ_BYTES_CHANNEL_3 = 15 [(CounterOpts) = {Name: "HIST(KV/ReadBytesChannel3)"
- Ranges { Value: 0 Name: "0" }
- Ranges { Value: 1 Name: "1024" }
- Ranges { Value: 1024 Name: "2048" }
- Ranges { Value: 2048 Name: "4096" }
- Ranges { Value: 4096 Name: "8192" }
- Ranges { Value: 8192 Name: "16384" }
- Ranges { Value: 16384 Name: "32768" }
- Ranges { Value: 32768 Name: "65536" }
- Ranges { Value: 65536 Name: "131072" }
- Ranges { Value: 131072 Name: "262144" }
- Ranges { Value: 262144 Name: "524288" }
- Ranges { Value: 524288 Name: "1048576" }
- Ranges { Value: 1048576 Name: "2097152" }
- Ranges { Value: 2097152 Name: "4194304" }
- Ranges { Value: 4194304 Name: "5242880" }
- Ranges { Value: 5242880 Name: "6291456" }
- Ranges { Value: 6291456 Name: "8388608" }
- Ranges { Value: 8388608 Name: "16777216" }
- Ranges { Value: 16777216 Name: "33554432" }
- Ranges { Value: 33554432 Name: "67108864" }
- Ranges { Value: 67108864 Name: "inf" }
- }
- ];
-
- COUNTER_HIST_READ_BYTES_CHANNEL_4 = 16 [(CounterOpts) = {Name: "HIST(KV/ReadBytesChannel4)"
- Ranges { Value: 0 Name: "0" }
- Ranges { Value: 1 Name: "1024" }
- Ranges { Value: 1024 Name: "2048" }
- Ranges { Value: 2048 Name: "4096" }
- Ranges { Value: 4096 Name: "8192" }
- Ranges { Value: 8192 Name: "16384" }
- Ranges { Value: 16384 Name: "32768" }
- Ranges { Value: 32768 Name: "65536" }
- Ranges { Value: 65536 Name: "131072" }
- Ranges { Value: 131072 Name: "262144" }
- Ranges { Value: 262144 Name: "524288" }
- Ranges { Value: 524288 Name: "1048576" }
- Ranges { Value: 1048576 Name: "2097152" }
- Ranges { Value: 2097152 Name: "4194304" }
- Ranges { Value: 4194304 Name: "5242880" }
- Ranges { Value: 5242880 Name: "6291456" }
- Ranges { Value: 6291456 Name: "8388608" }
- Ranges { Value: 8388608 Name: "16777216" }
- Ranges { Value: 16777216 Name: "33554432" }
- Ranges { Value: 33554432 Name: "67108864" }
- Ranges { Value: 67108864 Name: "inf" }
- }
- ];
-
- COUNTER_HIST_READ_BYTES_CHANNEL_5 = 17 [(CounterOpts) = {Name: "HIST(KV/ReadBytesChannel5)"
- Ranges { Value: 0 Name: "0" }
- Ranges { Value: 1 Name: "1024" }
- Ranges { Value: 1024 Name: "2048" }
- Ranges { Value: 2048 Name: "4096" }
- Ranges { Value: 4096 Name: "8192" }
- Ranges { Value: 8192 Name: "16384" }
- Ranges { Value: 16384 Name: "32768" }
- Ranges { Value: 32768 Name: "65536" }
- Ranges { Value: 65536 Name: "131072" }
- Ranges { Value: 131072 Name: "262144" }
- Ranges { Value: 262144 Name: "524288" }
- Ranges { Value: 524288 Name: "1048576" }
- Ranges { Value: 1048576 Name: "2097152" }
- Ranges { Value: 2097152 Name: "4194304" }
- Ranges { Value: 4194304 Name: "5242880" }
- Ranges { Value: 5242880 Name: "6291456" }
- Ranges { Value: 6291456 Name: "8388608" }
- Ranges { Value: 8388608 Name: "16777216" }
- Ranges { Value: 16777216 Name: "33554432" }
- Ranges { Value: 33554432 Name: "67108864" }
- Ranges { Value: 67108864 Name: "inf" }
- }
- ];
-
- COUNTER_HIST_READ_BYTES_CHANNEL_6 = 18 [(CounterOpts) = {Name: "HIST(KV/ReadBytesChannel6)"
- Ranges { Value: 0 Name: "0" }
- Ranges { Value: 1 Name: "1024" }
- Ranges { Value: 1024 Name: "2048" }
- Ranges { Value: 2048 Name: "4096" }
- Ranges { Value: 4096 Name: "8192" }
- Ranges { Value: 8192 Name: "16384" }
- Ranges { Value: 16384 Name: "32768" }
- Ranges { Value: 32768 Name: "65536" }
- Ranges { Value: 65536 Name: "131072" }
- Ranges { Value: 131072 Name: "262144" }
- Ranges { Value: 262144 Name: "524288" }
- Ranges { Value: 524288 Name: "1048576" }
- Ranges { Value: 1048576 Name: "2097152" }
- Ranges { Value: 2097152 Name: "4194304" }
- Ranges { Value: 4194304 Name: "5242880" }
- Ranges { Value: 5242880 Name: "6291456" }
- Ranges { Value: 6291456 Name: "8388608" }
- Ranges { Value: 8388608 Name: "16777216" }
- Ranges { Value: 16777216 Name: "33554432" }
- Ranges { Value: 33554432 Name: "67108864" }
- Ranges { Value: 67108864 Name: "inf" }
- }
- ];
-
- COUNTER_HIST_READ_BYTES_CHANNEL_7 = 19 [(CounterOpts) = {Name: "HIST(KV/ReadBytesChannel7)"
- Ranges { Value: 0 Name: "0" }
- Ranges { Value: 1 Name: "1024" }
- Ranges { Value: 1024 Name: "2048" }
- Ranges { Value: 2048 Name: "4096" }
- Ranges { Value: 4096 Name: "8192" }
- Ranges { Value: 8192 Name: "16384" }
- Ranges { Value: 16384 Name: "32768" }
- Ranges { Value: 32768 Name: "65536" }
- Ranges { Value: 65536 Name: "131072" }
- Ranges { Value: 131072 Name: "262144" }
- Ranges { Value: 262144 Name: "524288" }
- Ranges { Value: 524288 Name: "1048576" }
- Ranges { Value: 1048576 Name: "2097152" }
- Ranges { Value: 2097152 Name: "4194304" }
- Ranges { Value: 4194304 Name: "5242880" }
- Ranges { Value: 5242880 Name: "6291456" }
- Ranges { Value: 6291456 Name: "8388608" }
- Ranges { Value: 8388608 Name: "16777216" }
- Ranges { Value: 16777216 Name: "33554432" }
- Ranges { Value: 33554432 Name: "67108864" }
- Ranges { Value: 67108864 Name: "inf" }
- }
- ];
-
- COUNTER_HIST_READ_BYTES_CHANNEL_8 = 20 [(CounterOpts) = {Name: "HIST(KV/ReadBytesChannel8)"
- Ranges { Value: 0 Name: "0" }
- Ranges { Value: 1 Name: "1024" }
- Ranges { Value: 1024 Name: "2048" }
- Ranges { Value: 2048 Name: "4096" }
- Ranges { Value: 4096 Name: "8192" }
- Ranges { Value: 8192 Name: "16384" }
- Ranges { Value: 16384 Name: "32768" }
- Ranges { Value: 32768 Name: "65536" }
- Ranges { Value: 65536 Name: "131072" }
- Ranges { Value: 131072 Name: "262144" }
- Ranges { Value: 262144 Name: "524288" }
- Ranges { Value: 524288 Name: "1048576" }
- Ranges { Value: 1048576 Name: "2097152" }
- Ranges { Value: 2097152 Name: "4194304" }
- Ranges { Value: 4194304 Name: "5242880" }
- Ranges { Value: 5242880 Name: "6291456" }
- Ranges { Value: 6291456 Name: "8388608" }
- Ranges { Value: 8388608 Name: "16777216" }
- Ranges { Value: 16777216 Name: "33554432" }
- Ranges { Value: 33554432 Name: "67108864" }
- Ranges { Value: 67108864 Name: "inf" }
- }
- ];
-
- COUNTER_HIST_READ_BYTES_CHANNEL_9 = 21 [(CounterOpts) = {Name: "HIST(KV/ReadBytesChannel9)"
- Ranges { Value: 0 Name: "0" }
- Ranges { Value: 1 Name: "1024" }
- Ranges { Value: 1024 Name: "2048" }
- Ranges { Value: 2048 Name: "4096" }
- Ranges { Value: 4096 Name: "8192" }
- Ranges { Value: 8192 Name: "16384" }
- Ranges { Value: 16384 Name: "32768" }
- Ranges { Value: 32768 Name: "65536" }
- Ranges { Value: 65536 Name: "131072" }
- Ranges { Value: 131072 Name: "262144" }
- Ranges { Value: 262144 Name: "524288" }
- Ranges { Value: 524288 Name: "1048576" }
- Ranges { Value: 1048576 Name: "2097152" }
- Ranges { Value: 2097152 Name: "4194304" }
- Ranges { Value: 4194304 Name: "5242880" }
- Ranges { Value: 5242880 Name: "6291456" }
- Ranges { Value: 6291456 Name: "8388608" }
- Ranges { Value: 8388608 Name: "16777216" }
- Ranges { Value: 16777216 Name: "33554432" }
- Ranges { Value: 33554432 Name: "67108864" }
- Ranges { Value: 67108864 Name: "inf" }
- }
- ];
-
- COUNTER_HIST_READ_BYTES_CHANNEL_10 = 22 [(CounterOpts) = {Name: "HIST(KV/ReadBytesChannel10)"
- Ranges { Value: 0 Name: "0" }
- Ranges { Value: 1 Name: "1024" }
- Ranges { Value: 1024 Name: "2048" }
- Ranges { Value: 2048 Name: "4096" }
- Ranges { Value: 4096 Name: "8192" }
- Ranges { Value: 8192 Name: "16384" }
- Ranges { Value: 16384 Name: "32768" }
- Ranges { Value: 32768 Name: "65536" }
- Ranges { Value: 65536 Name: "131072" }
- Ranges { Value: 131072 Name: "262144" }
- Ranges { Value: 262144 Name: "524288" }
- Ranges { Value: 524288 Name: "1048576" }
- Ranges { Value: 1048576 Name: "2097152" }
- Ranges { Value: 2097152 Name: "4194304" }
- Ranges { Value: 4194304 Name: "5242880" }
- Ranges { Value: 5242880 Name: "6291456" }
- Ranges { Value: 6291456 Name: "8388608" }
- Ranges { Value: 8388608 Name: "16777216" }
- Ranges { Value: 16777216 Name: "33554432" }
- Ranges { Value: 33554432 Name: "67108864" }
- Ranges { Value: 67108864 Name: "inf" }
- }
- ];
-
- COUNTER_HIST_READ_BYTES_CHANNEL_11 = 23 [(CounterOpts) = {Name: "HIST(KV/ReadBytesChannel11)"
- Ranges { Value: 0 Name: "0" }
- Ranges { Value: 1 Name: "1024" }
- Ranges { Value: 1024 Name: "2048" }
- Ranges { Value: 2048 Name: "4096" }
- Ranges { Value: 4096 Name: "8192" }
- Ranges { Value: 8192 Name: "16384" }
- Ranges { Value: 16384 Name: "32768" }
- Ranges { Value: 32768 Name: "65536" }
- Ranges { Value: 65536 Name: "131072" }
- Ranges { Value: 131072 Name: "262144" }
- Ranges { Value: 262144 Name: "524288" }
- Ranges { Value: 524288 Name: "1048576" }
- Ranges { Value: 1048576 Name: "2097152" }
- Ranges { Value: 2097152 Name: "4194304" }
- Ranges { Value: 4194304 Name: "5242880" }
- Ranges { Value: 5242880 Name: "6291456" }
- Ranges { Value: 6291456 Name: "8388608" }
- Ranges { Value: 8388608 Name: "16777216" }
- Ranges { Value: 16777216 Name: "33554432" }
- Ranges { Value: 33554432 Name: "67108864" }
- Ranges { Value: 67108864 Name: "inf" }
- }
- ];
-
- COUNTER_HIST_READ_BYTES_CHANNEL_12 = 24 [(CounterOpts) = {Name: "HIST(KV/ReadBytesChannel12)"
- Ranges { Value: 0 Name: "0" }
- Ranges { Value: 1 Name: "1024" }
- Ranges { Value: 1024 Name: "2048" }
- Ranges { Value: 2048 Name: "4096" }
- Ranges { Value: 4096 Name: "8192" }
- Ranges { Value: 8192 Name: "16384" }
- Ranges { Value: 16384 Name: "32768" }
- Ranges { Value: 32768 Name: "65536" }
- Ranges { Value: 65536 Name: "131072" }
- Ranges { Value: 131072 Name: "262144" }
- Ranges { Value: 262144 Name: "524288" }
- Ranges { Value: 524288 Name: "1048576" }
- Ranges { Value: 1048576 Name: "2097152" }
- Ranges { Value: 2097152 Name: "4194304" }
- Ranges { Value: 4194304 Name: "5242880" }
- Ranges { Value: 5242880 Name: "6291456" }
- Ranges { Value: 6291456 Name: "8388608" }
- Ranges { Value: 8388608 Name: "16777216" }
- Ranges { Value: 16777216 Name: "33554432" }
- Ranges { Value: 33554432 Name: "67108864" }
- Ranges { Value: 67108864 Name: "inf" }
- }
- ];
-
- COUNTER_HIST_READ_BYTES_CHANNEL_13 = 25 [(CounterOpts) = {Name: "HIST(KV/ReadBytesChannel13)"
- Ranges { Value: 0 Name: "0" }
- Ranges { Value: 1 Name: "1024" }
- Ranges { Value: 1024 Name: "2048" }
- Ranges { Value: 2048 Name: "4096" }
- Ranges { Value: 4096 Name: "8192" }
- Ranges { Value: 8192 Name: "16384" }
- Ranges { Value: 16384 Name: "32768" }
- Ranges { Value: 32768 Name: "65536" }
- Ranges { Value: 65536 Name: "131072" }
- Ranges { Value: 131072 Name: "262144" }
- Ranges { Value: 262144 Name: "524288" }
- Ranges { Value: 524288 Name: "1048576" }
- Ranges { Value: 1048576 Name: "2097152" }
- Ranges { Value: 2097152 Name: "4194304" }
- Ranges { Value: 4194304 Name: "5242880" }
- Ranges { Value: 5242880 Name: "6291456" }
- Ranges { Value: 6291456 Name: "8388608" }
- Ranges { Value: 8388608 Name: "16777216" }
- Ranges { Value: 16777216 Name: "33554432" }
- Ranges { Value: 33554432 Name: "67108864" }
- Ranges { Value: 67108864 Name: "inf" }
- }
- ];
-
- COUNTER_HIST_READ_BYTES_CHANNEL_14 = 26 [(CounterOpts) = {Name: "HIST(KV/ReadBytesChannel14)"
- Ranges { Value: 0 Name: "0" }
- Ranges { Value: 1 Name: "1024" }
- Ranges { Value: 1024 Name: "2048" }
- Ranges { Value: 2048 Name: "4096" }
- Ranges { Value: 4096 Name: "8192" }
- Ranges { Value: 8192 Name: "16384" }
- Ranges { Value: 16384 Name: "32768" }
- Ranges { Value: 32768 Name: "65536" }
- Ranges { Value: 65536 Name: "131072" }
- Ranges { Value: 131072 Name: "262144" }
- Ranges { Value: 262144 Name: "524288" }
- Ranges { Value: 524288 Name: "1048576" }
- Ranges { Value: 1048576 Name: "2097152" }
- Ranges { Value: 2097152 Name: "4194304" }
- Ranges { Value: 4194304 Name: "5242880" }
- Ranges { Value: 5242880 Name: "6291456" }
- Ranges { Value: 6291456 Name: "8388608" }
- Ranges { Value: 8388608 Name: "16777216" }
- Ranges { Value: 16777216 Name: "33554432" }
- Ranges { Value: 33554432 Name: "67108864" }
- Ranges { Value: 67108864 Name: "inf" }
- }
- ];
-
- COUNTER_HIST_READ_BYTES_CHANNEL_15 = 27 [(CounterOpts) = {Name: "HIST(KV/ReadBytesChannel15)"
- Ranges { Value: 0 Name: "0" }
- Ranges { Value: 1 Name: "1024" }
- Ranges { Value: 1024 Name: "2048" }
- Ranges { Value: 2048 Name: "4096" }
- Ranges { Value: 4096 Name: "8192" }
- Ranges { Value: 8192 Name: "16384" }
- Ranges { Value: 16384 Name: "32768" }
- Ranges { Value: 32768 Name: "65536" }
- Ranges { Value: 65536 Name: "131072" }
- Ranges { Value: 131072 Name: "262144" }
- Ranges { Value: 262144 Name: "524288" }
- Ranges { Value: 524288 Name: "1048576" }
- Ranges { Value: 1048576 Name: "2097152" }
- Ranges { Value: 2097152 Name: "4194304" }
- Ranges { Value: 4194304 Name: "5242880" }
- Ranges { Value: 5242880 Name: "6291456" }
- Ranges { Value: 6291456 Name: "8388608" }
- Ranges { Value: 8388608 Name: "16777216" }
- Ranges { Value: 16777216 Name: "33554432" }
- Ranges { Value: 33554432 Name: "67108864" }
- Ranges { Value: 67108864 Name: "inf" }
- }
- ];
-
- COUNTER_HIST_WRITE_BYTES_CHANNEL_0 = 28 [(CounterOpts) = {Name: "HIST(KV/WriteBytesChannel0)"
- Ranges { Value: 0 Name: "0" }
- Ranges { Value: 1 Name: "1024" }
- Ranges { Value: 1024 Name: "2048" }
- Ranges { Value: 2048 Name: "4096" }
- Ranges { Value: 4096 Name: "8192" }
- Ranges { Value: 8192 Name: "16384" }
- Ranges { Value: 16384 Name: "32768" }
- Ranges { Value: 32768 Name: "65536" }
- Ranges { Value: 65536 Name: "131072" }
- Ranges { Value: 131072 Name: "262144" }
- Ranges { Value: 262144 Name: "524288" }
- Ranges { Value: 524288 Name: "1048576" }
- Ranges { Value: 1048576 Name: "2097152" }
- Ranges { Value: 2097152 Name: "4194304" }
- Ranges { Value: 4194304 Name: "5242880" }
- Ranges { Value: 5242880 Name: "6291456" }
- Ranges { Value: 6291456 Name: "8388608" }
- Ranges { Value: 8388608 Name: "16777216" }
- Ranges { Value: 16777216 Name: "33554432" }
- Ranges { Value: 33554432 Name: "67108864" }
- Ranges { Value: 67108864 Name: "inf" }
- }
- ];
-
- COUNTER_HIST_WRITE_BYTES_CHANNEL_1 = 29 [(CounterOpts) = {Name: "HIST(KV/WriteBytesChannel1)"
- Ranges { Value: 0 Name: "0" }
- Ranges { Value: 1 Name: "1024" }
- Ranges { Value: 1024 Name: "2048" }
- Ranges { Value: 2048 Name: "4096" }
- Ranges { Value: 4096 Name: "8192" }
- Ranges { Value: 8192 Name: "16384" }
- Ranges { Value: 16384 Name: "32768" }
- Ranges { Value: 32768 Name: "65536" }
- Ranges { Value: 65536 Name: "131072" }
- Ranges { Value: 131072 Name: "262144" }
- Ranges { Value: 262144 Name: "524288" }
- Ranges { Value: 524288 Name: "1048576" }
- Ranges { Value: 1048576 Name: "2097152" }
- Ranges { Value: 2097152 Name: "4194304" }
- Ranges { Value: 4194304 Name: "5242880" }
- Ranges { Value: 5242880 Name: "6291456" }
- Ranges { Value: 6291456 Name: "8388608" }
- Ranges { Value: 8388608 Name: "16777216" }
- Ranges { Value: 16777216 Name: "33554432" }
- Ranges { Value: 33554432 Name: "67108864" }
- Ranges { Value: 67108864 Name: "inf" }
- }
- ];
-
- COUNTER_HIST_WRITE_BYTES_CHANNEL_2 = 30 [(CounterOpts) = {Name: "HIST(KV/WriteBytesChannel2)"
- Ranges { Value: 0 Name: "0" }
- Ranges { Value: 1 Name: "1024" }
- Ranges { Value: 1024 Name: "2048" }
- Ranges { Value: 2048 Name: "4096" }
- Ranges { Value: 4096 Name: "8192" }
- Ranges { Value: 8192 Name: "16384" }
- Ranges { Value: 16384 Name: "32768" }
- Ranges { Value: 32768 Name: "65536" }
- Ranges { Value: 65536 Name: "131072" }
- Ranges { Value: 131072 Name: "262144" }
- Ranges { Value: 262144 Name: "524288" }
- Ranges { Value: 524288 Name: "1048576" }
- Ranges { Value: 1048576 Name: "2097152" }
- Ranges { Value: 2097152 Name: "4194304" }
- Ranges { Value: 4194304 Name: "5242880" }
- Ranges { Value: 5242880 Name: "6291456" }
- Ranges { Value: 6291456 Name: "8388608" }
- Ranges { Value: 8388608 Name: "16777216" }
- Ranges { Value: 16777216 Name: "33554432" }
- Ranges { Value: 33554432 Name: "67108864" }
- Ranges { Value: 67108864 Name: "inf" }
- }
- ];
-
- COUNTER_HIST_WRITE_BYTES_CHANNEL_3 = 31 [(CounterOpts) = {Name: "HIST(KV/WriteBytesChannel3)"
- Ranges { Value: 0 Name: "0" }
- Ranges { Value: 1 Name: "1024" }
- Ranges { Value: 1024 Name: "2048" }
- Ranges { Value: 2048 Name: "4096" }
- Ranges { Value: 4096 Name: "8192" }
- Ranges { Value: 8192 Name: "16384" }
- Ranges { Value: 16384 Name: "32768" }
- Ranges { Value: 32768 Name: "65536" }
- Ranges { Value: 65536 Name: "131072" }
- Ranges { Value: 131072 Name: "262144" }
- Ranges { Value: 262144 Name: "524288" }
- Ranges { Value: 524288 Name: "1048576" }
- Ranges { Value: 1048576 Name: "2097152" }
- Ranges { Value: 2097152 Name: "4194304" }
- Ranges { Value: 4194304 Name: "5242880" }
- Ranges { Value: 5242880 Name: "6291456" }
- Ranges { Value: 6291456 Name: "8388608" }
- Ranges { Value: 8388608 Name: "16777216" }
- Ranges { Value: 16777216 Name: "33554432" }
- Ranges { Value: 33554432 Name: "67108864" }
- Ranges { Value: 67108864 Name: "inf" }
- }
- ];
-
- COUNTER_HIST_WRITE_BYTES_CHANNEL_4 = 32 [(CounterOpts) = {Name: "HIST(KV/WriteBytesChannel4)"
- Ranges { Value: 0 Name: "0" }
- Ranges { Value: 1 Name: "1024" }
- Ranges { Value: 1024 Name: "2048" }
- Ranges { Value: 2048 Name: "4096" }
- Ranges { Value: 4096 Name: "8192" }
- Ranges { Value: 8192 Name: "16384" }
- Ranges { Value: 16384 Name: "32768" }
- Ranges { Value: 32768 Name: "65536" }
- Ranges { Value: 65536 Name: "131072" }
- Ranges { Value: 131072 Name: "262144" }
- Ranges { Value: 262144 Name: "524288" }
- Ranges { Value: 524288 Name: "1048576" }
- Ranges { Value: 1048576 Name: "2097152" }
- Ranges { Value: 2097152 Name: "4194304" }
- Ranges { Value: 4194304 Name: "5242880" }
- Ranges { Value: 5242880 Name: "6291456" }
- Ranges { Value: 6291456 Name: "8388608" }
- Ranges { Value: 8388608 Name: "16777216" }
- Ranges { Value: 16777216 Name: "33554432" }
- Ranges { Value: 33554432 Name: "67108864" }
- Ranges { Value: 67108864 Name: "inf" }
- }
- ];
-
- COUNTER_HIST_WRITE_BYTES_CHANNEL_5 = 33 [(CounterOpts) = {Name: "HIST(KV/WriteBytesChannel5)"
- Ranges { Value: 0 Name: "0" }
- Ranges { Value: 1 Name: "1024" }
- Ranges { Value: 1024 Name: "2048" }
- Ranges { Value: 2048 Name: "4096" }
- Ranges { Value: 4096 Name: "8192" }
- Ranges { Value: 8192 Name: "16384" }
- Ranges { Value: 16384 Name: "32768" }
- Ranges { Value: 32768 Name: "65536" }
- Ranges { Value: 65536 Name: "131072" }
- Ranges { Value: 131072 Name: "262144" }
- Ranges { Value: 262144 Name: "524288" }
- Ranges { Value: 524288 Name: "1048576" }
- Ranges { Value: 1048576 Name: "2097152" }
- Ranges { Value: 2097152 Name: "4194304" }
- Ranges { Value: 4194304 Name: "5242880" }
- Ranges { Value: 5242880 Name: "6291456" }
- Ranges { Value: 6291456 Name: "8388608" }
- Ranges { Value: 8388608 Name: "16777216" }
- Ranges { Value: 16777216 Name: "33554432" }
- Ranges { Value: 33554432 Name: "67108864" }
- Ranges { Value: 67108864 Name: "inf" }
- }
- ];
-
- COUNTER_HIST_WRITE_BYTES_CHANNEL_6 = 34 [(CounterOpts) = {Name: "HIST(KV/WriteBytesChannel6)"
- Ranges { Value: 0 Name: "0" }
- Ranges { Value: 1 Name: "1024" }
- Ranges { Value: 1024 Name: "2048" }
- Ranges { Value: 2048 Name: "4096" }
- Ranges { Value: 4096 Name: "8192" }
- Ranges { Value: 8192 Name: "16384" }
- Ranges { Value: 16384 Name: "32768" }
- Ranges { Value: 32768 Name: "65536" }
- Ranges { Value: 65536 Name: "131072" }
- Ranges { Value: 131072 Name: "262144" }
- Ranges { Value: 262144 Name: "524288" }
- Ranges { Value: 524288 Name: "1048576" }
- Ranges { Value: 1048576 Name: "2097152" }
- Ranges { Value: 2097152 Name: "4194304" }
- Ranges { Value: 4194304 Name: "5242880" }
- Ranges { Value: 5242880 Name: "6291456" }
- Ranges { Value: 6291456 Name: "8388608" }
- Ranges { Value: 8388608 Name: "16777216" }
- Ranges { Value: 16777216 Name: "33554432" }
- Ranges { Value: 33554432 Name: "67108864" }
- Ranges { Value: 67108864 Name: "inf" }
- }
- ];
-
- COUNTER_HIST_WRITE_BYTES_CHANNEL_7 = 35 [(CounterOpts) = {Name: "HIST(KV/WriteBytesChannel7)"
- Ranges { Value: 0 Name: "0" }
- Ranges { Value: 1 Name: "1024" }
- Ranges { Value: 1024 Name: "2048" }
- Ranges { Value: 2048 Name: "4096" }
- Ranges { Value: 4096 Name: "8192" }
- Ranges { Value: 8192 Name: "16384" }
- Ranges { Value: 16384 Name: "32768" }
- Ranges { Value: 32768 Name: "65536" }
- Ranges { Value: 65536 Name: "131072" }
- Ranges { Value: 131072 Name: "262144" }
- Ranges { Value: 262144 Name: "524288" }
- Ranges { Value: 524288 Name: "1048576" }
- Ranges { Value: 1048576 Name: "2097152" }
- Ranges { Value: 2097152 Name: "4194304" }
- Ranges { Value: 4194304 Name: "5242880" }
- Ranges { Value: 5242880 Name: "6291456" }
- Ranges { Value: 6291456 Name: "8388608" }
- Ranges { Value: 8388608 Name: "16777216" }
- Ranges { Value: 16777216 Name: "33554432" }
- Ranges { Value: 33554432 Name: "67108864" }
- Ranges { Value: 67108864 Name: "inf" }
- }
- ];
-
- COUNTER_HIST_WRITE_BYTES_CHANNEL_8 = 36 [(CounterOpts) = {Name: "HIST(KV/WriteBytesChannel8)"
- Ranges { Value: 0 Name: "0" }
- Ranges { Value: 1 Name: "1024" }
- Ranges { Value: 1024 Name: "2048" }
- Ranges { Value: 2048 Name: "4096" }
- Ranges { Value: 4096 Name: "8192" }
- Ranges { Value: 8192 Name: "16384" }
- Ranges { Value: 16384 Name: "32768" }
- Ranges { Value: 32768 Name: "65536" }
- Ranges { Value: 65536 Name: "131072" }
- Ranges { Value: 131072 Name: "262144" }
- Ranges { Value: 262144 Name: "524288" }
- Ranges { Value: 524288 Name: "1048576" }
- Ranges { Value: 1048576 Name: "2097152" }
- Ranges { Value: 2097152 Name: "4194304" }
- Ranges { Value: 4194304 Name: "5242880" }
- Ranges { Value: 5242880 Name: "6291456" }
- Ranges { Value: 6291456 Name: "8388608" }
- Ranges { Value: 8388608 Name: "16777216" }
- Ranges { Value: 16777216 Name: "33554432" }
- Ranges { Value: 33554432 Name: "67108864" }
- Ranges { Value: 67108864 Name: "inf" }
- }
- ];
-
- COUNTER_HIST_WRITE_BYTES_CHANNEL_9 = 37 [(CounterOpts) = {Name: "HIST(KV/WriteBytesChannel9)"
- Ranges { Value: 0 Name: "0" }
- Ranges { Value: 1 Name: "1024" }
- Ranges { Value: 1024 Name: "2048" }
- Ranges { Value: 2048 Name: "4096" }
- Ranges { Value: 4096 Name: "8192" }
- Ranges { Value: 8192 Name: "16384" }
- Ranges { Value: 16384 Name: "32768" }
- Ranges { Value: 32768 Name: "65536" }
- Ranges { Value: 65536 Name: "131072" }
- Ranges { Value: 131072 Name: "262144" }
- Ranges { Value: 262144 Name: "524288" }
- Ranges { Value: 524288 Name: "1048576" }
- Ranges { Value: 1048576 Name: "2097152" }
- Ranges { Value: 2097152 Name: "4194304" }
- Ranges { Value: 4194304 Name: "5242880" }
- Ranges { Value: 5242880 Name: "6291456" }
- Ranges { Value: 6291456 Name: "8388608" }
- Ranges { Value: 8388608 Name: "16777216" }
- Ranges { Value: 16777216 Name: "33554432" }
- Ranges { Value: 33554432 Name: "67108864" }
- Ranges { Value: 67108864 Name: "inf" }
- }
- ];
-
- COUNTER_HIST_WRITE_BYTES_CHANNEL_10 = 38 [(CounterOpts) = {Name: "HIST(KV/WriteBytesChannel10)"
- Ranges { Value: 0 Name: "0" }
- Ranges { Value: 1 Name: "1024" }
- Ranges { Value: 1024 Name: "2048" }
- Ranges { Value: 2048 Name: "4096" }
- Ranges { Value: 4096 Name: "8192" }
- Ranges { Value: 8192 Name: "16384" }
- Ranges { Value: 16384 Name: "32768" }
- Ranges { Value: 32768 Name: "65536" }
- Ranges { Value: 65536 Name: "131072" }
- Ranges { Value: 131072 Name: "262144" }
- Ranges { Value: 262144 Name: "524288" }
- Ranges { Value: 524288 Name: "1048576" }
- Ranges { Value: 1048576 Name: "2097152" }
- Ranges { Value: 2097152 Name: "4194304" }
- Ranges { Value: 4194304 Name: "5242880" }
- Ranges { Value: 5242880 Name: "6291456" }
- Ranges { Value: 6291456 Name: "8388608" }
- Ranges { Value: 8388608 Name: "16777216" }
- Ranges { Value: 16777216 Name: "33554432" }
- Ranges { Value: 33554432 Name: "67108864" }
- Ranges { Value: 67108864 Name: "inf" }
- }
- ];
-
- COUNTER_HIST_WRITE_BYTES_CHANNEL_11 = 39 [(CounterOpts) = {Name: "HIST(KV/WriteBytesChannel11)"
- Ranges { Value: 0 Name: "0" }
- Ranges { Value: 1 Name: "1024" }
- Ranges { Value: 1024 Name: "2048" }
- Ranges { Value: 2048 Name: "4096" }
- Ranges { Value: 4096 Name: "8192" }
- Ranges { Value: 8192 Name: "16384" }
- Ranges { Value: 16384 Name: "32768" }
- Ranges { Value: 32768 Name: "65536" }
- Ranges { Value: 65536 Name: "131072" }
- Ranges { Value: 131072 Name: "262144" }
- Ranges { Value: 262144 Name: "524288" }
- Ranges { Value: 524288 Name: "1048576" }
- Ranges { Value: 1048576 Name: "2097152" }
- Ranges { Value: 2097152 Name: "4194304" }
- Ranges { Value: 4194304 Name: "5242880" }
- Ranges { Value: 5242880 Name: "6291456" }
- Ranges { Value: 6291456 Name: "8388608" }
- Ranges { Value: 8388608 Name: "16777216" }
- Ranges { Value: 16777216 Name: "33554432" }
- Ranges { Value: 33554432 Name: "67108864" }
- Ranges { Value: 67108864 Name: "inf" }
- }
- ];
-
- COUNTER_HIST_WRITE_BYTES_CHANNEL_12 = 40 [(CounterOpts) = {Name: "HIST(KV/WriteBytesChannel12)"
- Ranges { Value: 0 Name: "0" }
- Ranges { Value: 1 Name: "1024" }
- Ranges { Value: 1024 Name: "2048" }
- Ranges { Value: 2048 Name: "4096" }
- Ranges { Value: 4096 Name: "8192" }
- Ranges { Value: 8192 Name: "16384" }
- Ranges { Value: 16384 Name: "32768" }
- Ranges { Value: 32768 Name: "65536" }
- Ranges { Value: 65536 Name: "131072" }
- Ranges { Value: 131072 Name: "262144" }
- Ranges { Value: 262144 Name: "524288" }
- Ranges { Value: 524288 Name: "1048576" }
- Ranges { Value: 1048576 Name: "2097152" }
- Ranges { Value: 2097152 Name: "4194304" }
- Ranges { Value: 4194304 Name: "5242880" }
- Ranges { Value: 5242880 Name: "6291456" }
- Ranges { Value: 6291456 Name: "8388608" }
- Ranges { Value: 8388608 Name: "16777216" }
- Ranges { Value: 16777216 Name: "33554432" }
- Ranges { Value: 33554432 Name: "67108864" }
- Ranges { Value: 67108864 Name: "inf" }
- }
- ];
-
- COUNTER_HIST_WRITE_BYTES_CHANNEL_13 = 41 [(CounterOpts) = {Name: "HIST(KV/WriteBytesChannel13)"
- Ranges { Value: 0 Name: "0" }
- Ranges { Value: 1 Name: "1024" }
- Ranges { Value: 1024 Name: "2048" }
- Ranges { Value: 2048 Name: "4096" }
- Ranges { Value: 4096 Name: "8192" }
- Ranges { Value: 8192 Name: "16384" }
- Ranges { Value: 16384 Name: "32768" }
- Ranges { Value: 32768 Name: "65536" }
- Ranges { Value: 65536 Name: "131072" }
- Ranges { Value: 131072 Name: "262144" }
- Ranges { Value: 262144 Name: "524288" }
- Ranges { Value: 524288 Name: "1048576" }
- Ranges { Value: 1048576 Name: "2097152" }
- Ranges { Value: 2097152 Name: "4194304" }
- Ranges { Value: 4194304 Name: "5242880" }
- Ranges { Value: 5242880 Name: "6291456" }
- Ranges { Value: 6291456 Name: "8388608" }
- Ranges { Value: 8388608 Name: "16777216" }
- Ranges { Value: 16777216 Name: "33554432" }
- Ranges { Value: 33554432 Name: "67108864" }
- Ranges { Value: 67108864 Name: "inf" }
- }
- ];
-
- COUNTER_HIST_WRITE_BYTES_CHANNEL_14 = 42 [(CounterOpts) = {Name: "HIST(KV/WriteBytesChannel14)"
- Ranges { Value: 0 Name: "0" }
- Ranges { Value: 1 Name: "1024" }
- Ranges { Value: 1024 Name: "2048" }
- Ranges { Value: 2048 Name: "4096" }
- Ranges { Value: 4096 Name: "8192" }
- Ranges { Value: 8192 Name: "16384" }
- Ranges { Value: 16384 Name: "32768" }
- Ranges { Value: 32768 Name: "65536" }
- Ranges { Value: 65536 Name: "131072" }
- Ranges { Value: 131072 Name: "262144" }
- Ranges { Value: 262144 Name: "524288" }
- Ranges { Value: 524288 Name: "1048576" }
- Ranges { Value: 1048576 Name: "2097152" }
- Ranges { Value: 2097152 Name: "4194304" }
- Ranges { Value: 4194304 Name: "5242880" }
- Ranges { Value: 5242880 Name: "6291456" }
- Ranges { Value: 6291456 Name: "8388608" }
- Ranges { Value: 8388608 Name: "16777216" }
- Ranges { Value: 16777216 Name: "33554432" }
- Ranges { Value: 33554432 Name: "67108864" }
- Ranges { Value: 67108864 Name: "inf" }
- }
- ];
-
- COUNTER_HIST_WRITE_BYTES_CHANNEL_15 = 43 [(CounterOpts) = {Name: "HIST(KV/WriteBytesChannel15)"
- Ranges { Value: 0 Name: "0" }
- Ranges { Value: 1 Name: "1024" }
- Ranges { Value: 1024 Name: "2048" }
- Ranges { Value: 2048 Name: "4096" }
- Ranges { Value: 4096 Name: "8192" }
- Ranges { Value: 8192 Name: "16384" }
- Ranges { Value: 16384 Name: "32768" }
- Ranges { Value: 32768 Name: "65536" }
- Ranges { Value: 65536 Name: "131072" }
- Ranges { Value: 131072 Name: "262144" }
- Ranges { Value: 262144 Name: "524288" }
- Ranges { Value: 524288 Name: "1048576" }
- Ranges { Value: 1048576 Name: "2097152" }
- Ranges { Value: 2097152 Name: "4194304" }
- Ranges { Value: 4194304 Name: "5242880" }
- Ranges { Value: 5242880 Name: "6291456" }
- Ranges { Value: 6291456 Name: "8388608" }
- Ranges { Value: 8388608 Name: "16777216" }
- Ranges { Value: 16777216 Name: "33554432" }
- Ranges { Value: 33554432 Name: "67108864" }
- Ranges { Value: 67108864 Name: "inf" }
- }
- ];
-
+
+ COUNTER_HIST_READ_BYTES_CHANNEL_0 = 12 [(CounterOpts) = {Name: "HIST(KV/ReadBytesChannel0)"
+ Ranges { Value: 0 Name: "0" }
+ Ranges { Value: 1 Name: "1024" }
+ Ranges { Value: 1024 Name: "2048" }
+ Ranges { Value: 2048 Name: "4096" }
+ Ranges { Value: 4096 Name: "8192" }
+ Ranges { Value: 8192 Name: "16384" }
+ Ranges { Value: 16384 Name: "32768" }
+ Ranges { Value: 32768 Name: "65536" }
+ Ranges { Value: 65536 Name: "131072" }
+ Ranges { Value: 131072 Name: "262144" }
+ Ranges { Value: 262144 Name: "524288" }
+ Ranges { Value: 524288 Name: "1048576" }
+ Ranges { Value: 1048576 Name: "2097152" }
+ Ranges { Value: 2097152 Name: "4194304" }
+ Ranges { Value: 4194304 Name: "5242880" }
+ Ranges { Value: 5242880 Name: "6291456" }
+ Ranges { Value: 6291456 Name: "8388608" }
+ Ranges { Value: 8388608 Name: "16777216" }
+ Ranges { Value: 16777216 Name: "33554432" }
+ Ranges { Value: 33554432 Name: "67108864" }
+ Ranges { Value: 67108864 Name: "inf" }
+ }
+ ];
+
+ COUNTER_HIST_READ_BYTES_CHANNEL_1 = 13 [(CounterOpts) = {Name: "HIST(KV/ReadBytesChannel1)"
+ Ranges { Value: 0 Name: "0" }
+ Ranges { Value: 1 Name: "1024" }
+ Ranges { Value: 1024 Name: "2048" }
+ Ranges { Value: 2048 Name: "4096" }
+ Ranges { Value: 4096 Name: "8192" }
+ Ranges { Value: 8192 Name: "16384" }
+ Ranges { Value: 16384 Name: "32768" }
+ Ranges { Value: 32768 Name: "65536" }
+ Ranges { Value: 65536 Name: "131072" }
+ Ranges { Value: 131072 Name: "262144" }
+ Ranges { Value: 262144 Name: "524288" }
+ Ranges { Value: 524288 Name: "1048576" }
+ Ranges { Value: 1048576 Name: "2097152" }
+ Ranges { Value: 2097152 Name: "4194304" }
+ Ranges { Value: 4194304 Name: "5242880" }
+ Ranges { Value: 5242880 Name: "6291456" }
+ Ranges { Value: 6291456 Name: "8388608" }
+ Ranges { Value: 8388608 Name: "16777216" }
+ Ranges { Value: 16777216 Name: "33554432" }
+ Ranges { Value: 33554432 Name: "67108864" }
+ Ranges { Value: 67108864 Name: "inf" }
+ }
+ ];
+
+ COUNTER_HIST_READ_BYTES_CHANNEL_2 = 14 [(CounterOpts) = {Name: "HIST(KV/ReadBytesChannel2)"
+ Ranges { Value: 0 Name: "0" }
+ Ranges { Value: 1 Name: "1024" }
+ Ranges { Value: 1024 Name: "2048" }
+ Ranges { Value: 2048 Name: "4096" }
+ Ranges { Value: 4096 Name: "8192" }
+ Ranges { Value: 8192 Name: "16384" }
+ Ranges { Value: 16384 Name: "32768" }
+ Ranges { Value: 32768 Name: "65536" }
+ Ranges { Value: 65536 Name: "131072" }
+ Ranges { Value: 131072 Name: "262144" }
+ Ranges { Value: 262144 Name: "524288" }
+ Ranges { Value: 524288 Name: "1048576" }
+ Ranges { Value: 1048576 Name: "2097152" }
+ Ranges { Value: 2097152 Name: "4194304" }
+ Ranges { Value: 4194304 Name: "5242880" }
+ Ranges { Value: 5242880 Name: "6291456" }
+ Ranges { Value: 6291456 Name: "8388608" }
+ Ranges { Value: 8388608 Name: "16777216" }
+ Ranges { Value: 16777216 Name: "33554432" }
+ Ranges { Value: 33554432 Name: "67108864" }
+ Ranges { Value: 67108864 Name: "inf" }
+ }
+ ];
+
+ COUNTER_HIST_READ_BYTES_CHANNEL_3 = 15 [(CounterOpts) = {Name: "HIST(KV/ReadBytesChannel3)"
+ Ranges { Value: 0 Name: "0" }
+ Ranges { Value: 1 Name: "1024" }
+ Ranges { Value: 1024 Name: "2048" }
+ Ranges { Value: 2048 Name: "4096" }
+ Ranges { Value: 4096 Name: "8192" }
+ Ranges { Value: 8192 Name: "16384" }
+ Ranges { Value: 16384 Name: "32768" }
+ Ranges { Value: 32768 Name: "65536" }
+ Ranges { Value: 65536 Name: "131072" }
+ Ranges { Value: 131072 Name: "262144" }
+ Ranges { Value: 262144 Name: "524288" }
+ Ranges { Value: 524288 Name: "1048576" }
+ Ranges { Value: 1048576 Name: "2097152" }
+ Ranges { Value: 2097152 Name: "4194304" }
+ Ranges { Value: 4194304 Name: "5242880" }
+ Ranges { Value: 5242880 Name: "6291456" }
+ Ranges { Value: 6291456 Name: "8388608" }
+ Ranges { Value: 8388608 Name: "16777216" }
+ Ranges { Value: 16777216 Name: "33554432" }
+ Ranges { Value: 33554432 Name: "67108864" }
+ Ranges { Value: 67108864 Name: "inf" }
+ }
+ ];
+
+ COUNTER_HIST_READ_BYTES_CHANNEL_4 = 16 [(CounterOpts) = {Name: "HIST(KV/ReadBytesChannel4)"
+ Ranges { Value: 0 Name: "0" }
+ Ranges { Value: 1 Name: "1024" }
+ Ranges { Value: 1024 Name: "2048" }
+ Ranges { Value: 2048 Name: "4096" }
+ Ranges { Value: 4096 Name: "8192" }
+ Ranges { Value: 8192 Name: "16384" }
+ Ranges { Value: 16384 Name: "32768" }
+ Ranges { Value: 32768 Name: "65536" }
+ Ranges { Value: 65536 Name: "131072" }
+ Ranges { Value: 131072 Name: "262144" }
+ Ranges { Value: 262144 Name: "524288" }
+ Ranges { Value: 524288 Name: "1048576" }
+ Ranges { Value: 1048576 Name: "2097152" }
+ Ranges { Value: 2097152 Name: "4194304" }
+ Ranges { Value: 4194304 Name: "5242880" }
+ Ranges { Value: 5242880 Name: "6291456" }
+ Ranges { Value: 6291456 Name: "8388608" }
+ Ranges { Value: 8388608 Name: "16777216" }
+ Ranges { Value: 16777216 Name: "33554432" }
+ Ranges { Value: 33554432 Name: "67108864" }
+ Ranges { Value: 67108864 Name: "inf" }
+ }
+ ];
+
+ COUNTER_HIST_READ_BYTES_CHANNEL_5 = 17 [(CounterOpts) = {Name: "HIST(KV/ReadBytesChannel5)"
+ Ranges { Value: 0 Name: "0" }
+ Ranges { Value: 1 Name: "1024" }
+ Ranges { Value: 1024 Name: "2048" }
+ Ranges { Value: 2048 Name: "4096" }
+ Ranges { Value: 4096 Name: "8192" }
+ Ranges { Value: 8192 Name: "16384" }
+ Ranges { Value: 16384 Name: "32768" }
+ Ranges { Value: 32768 Name: "65536" }
+ Ranges { Value: 65536 Name: "131072" }
+ Ranges { Value: 131072 Name: "262144" }
+ Ranges { Value: 262144 Name: "524288" }
+ Ranges { Value: 524288 Name: "1048576" }
+ Ranges { Value: 1048576 Name: "2097152" }
+ Ranges { Value: 2097152 Name: "4194304" }
+ Ranges { Value: 4194304 Name: "5242880" }
+ Ranges { Value: 5242880 Name: "6291456" }
+ Ranges { Value: 6291456 Name: "8388608" }
+ Ranges { Value: 8388608 Name: "16777216" }
+ Ranges { Value: 16777216 Name: "33554432" }
+ Ranges { Value: 33554432 Name: "67108864" }
+ Ranges { Value: 67108864 Name: "inf" }
+ }
+ ];
+
+ COUNTER_HIST_READ_BYTES_CHANNEL_6 = 18 [(CounterOpts) = {Name: "HIST(KV/ReadBytesChannel6)"
+ Ranges { Value: 0 Name: "0" }
+ Ranges { Value: 1 Name: "1024" }
+ Ranges { Value: 1024 Name: "2048" }
+ Ranges { Value: 2048 Name: "4096" }
+ Ranges { Value: 4096 Name: "8192" }
+ Ranges { Value: 8192 Name: "16384" }
+ Ranges { Value: 16384 Name: "32768" }
+ Ranges { Value: 32768 Name: "65536" }
+ Ranges { Value: 65536 Name: "131072" }
+ Ranges { Value: 131072 Name: "262144" }
+ Ranges { Value: 262144 Name: "524288" }
+ Ranges { Value: 524288 Name: "1048576" }
+ Ranges { Value: 1048576 Name: "2097152" }
+ Ranges { Value: 2097152 Name: "4194304" }
+ Ranges { Value: 4194304 Name: "5242880" }
+ Ranges { Value: 5242880 Name: "6291456" }
+ Ranges { Value: 6291456 Name: "8388608" }
+ Ranges { Value: 8388608 Name: "16777216" }
+ Ranges { Value: 16777216 Name: "33554432" }
+ Ranges { Value: 33554432 Name: "67108864" }
+ Ranges { Value: 67108864 Name: "inf" }
+ }
+ ];
+
+ COUNTER_HIST_READ_BYTES_CHANNEL_7 = 19 [(CounterOpts) = {Name: "HIST(KV/ReadBytesChannel7)"
+ Ranges { Value: 0 Name: "0" }
+ Ranges { Value: 1 Name: "1024" }
+ Ranges { Value: 1024 Name: "2048" }
+ Ranges { Value: 2048 Name: "4096" }
+ Ranges { Value: 4096 Name: "8192" }
+ Ranges { Value: 8192 Name: "16384" }
+ Ranges { Value: 16384 Name: "32768" }
+ Ranges { Value: 32768 Name: "65536" }
+ Ranges { Value: 65536 Name: "131072" }
+ Ranges { Value: 131072 Name: "262144" }
+ Ranges { Value: 262144 Name: "524288" }
+ Ranges { Value: 524288 Name: "1048576" }
+ Ranges { Value: 1048576 Name: "2097152" }
+ Ranges { Value: 2097152 Name: "4194304" }
+ Ranges { Value: 4194304 Name: "5242880" }
+ Ranges { Value: 5242880 Name: "6291456" }
+ Ranges { Value: 6291456 Name: "8388608" }
+ Ranges { Value: 8388608 Name: "16777216" }
+ Ranges { Value: 16777216 Name: "33554432" }
+ Ranges { Value: 33554432 Name: "67108864" }
+ Ranges { Value: 67108864 Name: "inf" }
+ }
+ ];
+
+ COUNTER_HIST_READ_BYTES_CHANNEL_8 = 20 [(CounterOpts) = {Name: "HIST(KV/ReadBytesChannel8)"
+ Ranges { Value: 0 Name: "0" }
+ Ranges { Value: 1 Name: "1024" }
+ Ranges { Value: 1024 Name: "2048" }
+ Ranges { Value: 2048 Name: "4096" }
+ Ranges { Value: 4096 Name: "8192" }
+ Ranges { Value: 8192 Name: "16384" }
+ Ranges { Value: 16384 Name: "32768" }
+ Ranges { Value: 32768 Name: "65536" }
+ Ranges { Value: 65536 Name: "131072" }
+ Ranges { Value: 131072 Name: "262144" }
+ Ranges { Value: 262144 Name: "524288" }
+ Ranges { Value: 524288 Name: "1048576" }
+ Ranges { Value: 1048576 Name: "2097152" }
+ Ranges { Value: 2097152 Name: "4194304" }
+ Ranges { Value: 4194304 Name: "5242880" }
+ Ranges { Value: 5242880 Name: "6291456" }
+ Ranges { Value: 6291456 Name: "8388608" }
+ Ranges { Value: 8388608 Name: "16777216" }
+ Ranges { Value: 16777216 Name: "33554432" }
+ Ranges { Value: 33554432 Name: "67108864" }
+ Ranges { Value: 67108864 Name: "inf" }
+ }
+ ];
+
+ COUNTER_HIST_READ_BYTES_CHANNEL_9 = 21 [(CounterOpts) = {Name: "HIST(KV/ReadBytesChannel9)"
+ Ranges { Value: 0 Name: "0" }
+ Ranges { Value: 1 Name: "1024" }
+ Ranges { Value: 1024 Name: "2048" }
+ Ranges { Value: 2048 Name: "4096" }
+ Ranges { Value: 4096 Name: "8192" }
+ Ranges { Value: 8192 Name: "16384" }
+ Ranges { Value: 16384 Name: "32768" }
+ Ranges { Value: 32768 Name: "65536" }
+ Ranges { Value: 65536 Name: "131072" }
+ Ranges { Value: 131072 Name: "262144" }
+ Ranges { Value: 262144 Name: "524288" }
+ Ranges { Value: 524288 Name: "1048576" }
+ Ranges { Value: 1048576 Name: "2097152" }
+ Ranges { Value: 2097152 Name: "4194304" }
+ Ranges { Value: 4194304 Name: "5242880" }
+ Ranges { Value: 5242880 Name: "6291456" }
+ Ranges { Value: 6291456 Name: "8388608" }
+ Ranges { Value: 8388608 Name: "16777216" }
+ Ranges { Value: 16777216 Name: "33554432" }
+ Ranges { Value: 33554432 Name: "67108864" }
+ Ranges { Value: 67108864 Name: "inf" }
+ }
+ ];
+
+ COUNTER_HIST_READ_BYTES_CHANNEL_10 = 22 [(CounterOpts) = {Name: "HIST(KV/ReadBytesChannel10)"
+ Ranges { Value: 0 Name: "0" }
+ Ranges { Value: 1 Name: "1024" }
+ Ranges { Value: 1024 Name: "2048" }
+ Ranges { Value: 2048 Name: "4096" }
+ Ranges { Value: 4096 Name: "8192" }
+ Ranges { Value: 8192 Name: "16384" }
+ Ranges { Value: 16384 Name: "32768" }
+ Ranges { Value: 32768 Name: "65536" }
+ Ranges { Value: 65536 Name: "131072" }
+ Ranges { Value: 131072 Name: "262144" }
+ Ranges { Value: 262144 Name: "524288" }
+ Ranges { Value: 524288 Name: "1048576" }
+ Ranges { Value: 1048576 Name: "2097152" }
+ Ranges { Value: 2097152 Name: "4194304" }
+ Ranges { Value: 4194304 Name: "5242880" }
+ Ranges { Value: 5242880 Name: "6291456" }
+ Ranges { Value: 6291456 Name: "8388608" }
+ Ranges { Value: 8388608 Name: "16777216" }
+ Ranges { Value: 16777216 Name: "33554432" }
+ Ranges { Value: 33554432 Name: "67108864" }
+ Ranges { Value: 67108864 Name: "inf" }
+ }
+ ];
+
+ COUNTER_HIST_READ_BYTES_CHANNEL_11 = 23 [(CounterOpts) = {Name: "HIST(KV/ReadBytesChannel11)"
+ Ranges { Value: 0 Name: "0" }
+ Ranges { Value: 1 Name: "1024" }
+ Ranges { Value: 1024 Name: "2048" }
+ Ranges { Value: 2048 Name: "4096" }
+ Ranges { Value: 4096 Name: "8192" }
+ Ranges { Value: 8192 Name: "16384" }
+ Ranges { Value: 16384 Name: "32768" }
+ Ranges { Value: 32768 Name: "65536" }
+ Ranges { Value: 65536 Name: "131072" }
+ Ranges { Value: 131072 Name: "262144" }
+ Ranges { Value: 262144 Name: "524288" }
+ Ranges { Value: 524288 Name: "1048576" }
+ Ranges { Value: 1048576 Name: "2097152" }
+ Ranges { Value: 2097152 Name: "4194304" }
+ Ranges { Value: 4194304 Name: "5242880" }
+ Ranges { Value: 5242880 Name: "6291456" }
+ Ranges { Value: 6291456 Name: "8388608" }
+ Ranges { Value: 8388608 Name: "16777216" }
+ Ranges { Value: 16777216 Name: "33554432" }
+ Ranges { Value: 33554432 Name: "67108864" }
+ Ranges { Value: 67108864 Name: "inf" }
+ }
+ ];
+
+ COUNTER_HIST_READ_BYTES_CHANNEL_12 = 24 [(CounterOpts) = {Name: "HIST(KV/ReadBytesChannel12)"
+ Ranges { Value: 0 Name: "0" }
+ Ranges { Value: 1 Name: "1024" }
+ Ranges { Value: 1024 Name: "2048" }
+ Ranges { Value: 2048 Name: "4096" }
+ Ranges { Value: 4096 Name: "8192" }
+ Ranges { Value: 8192 Name: "16384" }
+ Ranges { Value: 16384 Name: "32768" }
+ Ranges { Value: 32768 Name: "65536" }
+ Ranges { Value: 65536 Name: "131072" }
+ Ranges { Value: 131072 Name: "262144" }
+ Ranges { Value: 262144 Name: "524288" }
+ Ranges { Value: 524288 Name: "1048576" }
+ Ranges { Value: 1048576 Name: "2097152" }
+ Ranges { Value: 2097152 Name: "4194304" }
+ Ranges { Value: 4194304 Name: "5242880" }
+ Ranges { Value: 5242880 Name: "6291456" }
+ Ranges { Value: 6291456 Name: "8388608" }
+ Ranges { Value: 8388608 Name: "16777216" }
+ Ranges { Value: 16777216 Name: "33554432" }
+ Ranges { Value: 33554432 Name: "67108864" }
+ Ranges { Value: 67108864 Name: "inf" }
+ }
+ ];
+
+ COUNTER_HIST_READ_BYTES_CHANNEL_13 = 25 [(CounterOpts) = {Name: "HIST(KV/ReadBytesChannel13)"
+ Ranges { Value: 0 Name: "0" }
+ Ranges { Value: 1 Name: "1024" }
+ Ranges { Value: 1024 Name: "2048" }
+ Ranges { Value: 2048 Name: "4096" }
+ Ranges { Value: 4096 Name: "8192" }
+ Ranges { Value: 8192 Name: "16384" }
+ Ranges { Value: 16384 Name: "32768" }
+ Ranges { Value: 32768 Name: "65536" }
+ Ranges { Value: 65536 Name: "131072" }
+ Ranges { Value: 131072 Name: "262144" }
+ Ranges { Value: 262144 Name: "524288" }
+ Ranges { Value: 524288 Name: "1048576" }
+ Ranges { Value: 1048576 Name: "2097152" }
+ Ranges { Value: 2097152 Name: "4194304" }
+ Ranges { Value: 4194304 Name: "5242880" }
+ Ranges { Value: 5242880 Name: "6291456" }
+ Ranges { Value: 6291456 Name: "8388608" }
+ Ranges { Value: 8388608 Name: "16777216" }
+ Ranges { Value: 16777216 Name: "33554432" }
+ Ranges { Value: 33554432 Name: "67108864" }
+ Ranges { Value: 67108864 Name: "inf" }
+ }
+ ];
+
+ COUNTER_HIST_READ_BYTES_CHANNEL_14 = 26 [(CounterOpts) = {Name: "HIST(KV/ReadBytesChannel14)"
+ Ranges { Value: 0 Name: "0" }
+ Ranges { Value: 1 Name: "1024" }
+ Ranges { Value: 1024 Name: "2048" }
+ Ranges { Value: 2048 Name: "4096" }
+ Ranges { Value: 4096 Name: "8192" }
+ Ranges { Value: 8192 Name: "16384" }
+ Ranges { Value: 16384 Name: "32768" }
+ Ranges { Value: 32768 Name: "65536" }
+ Ranges { Value: 65536 Name: "131072" }
+ Ranges { Value: 131072 Name: "262144" }
+ Ranges { Value: 262144 Name: "524288" }
+ Ranges { Value: 524288 Name: "1048576" }
+ Ranges { Value: 1048576 Name: "2097152" }
+ Ranges { Value: 2097152 Name: "4194304" }
+ Ranges { Value: 4194304 Name: "5242880" }
+ Ranges { Value: 5242880 Name: "6291456" }
+ Ranges { Value: 6291456 Name: "8388608" }
+ Ranges { Value: 8388608 Name: "16777216" }
+ Ranges { Value: 16777216 Name: "33554432" }
+ Ranges { Value: 33554432 Name: "67108864" }
+ Ranges { Value: 67108864 Name: "inf" }
+ }
+ ];
+
+ COUNTER_HIST_READ_BYTES_CHANNEL_15 = 27 [(CounterOpts) = {Name: "HIST(KV/ReadBytesChannel15)"
+ Ranges { Value: 0 Name: "0" }
+ Ranges { Value: 1 Name: "1024" }
+ Ranges { Value: 1024 Name: "2048" }
+ Ranges { Value: 2048 Name: "4096" }
+ Ranges { Value: 4096 Name: "8192" }
+ Ranges { Value: 8192 Name: "16384" }
+ Ranges { Value: 16384 Name: "32768" }
+ Ranges { Value: 32768 Name: "65536" }
+ Ranges { Value: 65536 Name: "131072" }
+ Ranges { Value: 131072 Name: "262144" }
+ Ranges { Value: 262144 Name: "524288" }
+ Ranges { Value: 524288 Name: "1048576" }
+ Ranges { Value: 1048576 Name: "2097152" }
+ Ranges { Value: 2097152 Name: "4194304" }
+ Ranges { Value: 4194304 Name: "5242880" }
+ Ranges { Value: 5242880 Name: "6291456" }
+ Ranges { Value: 6291456 Name: "8388608" }
+ Ranges { Value: 8388608 Name: "16777216" }
+ Ranges { Value: 16777216 Name: "33554432" }
+ Ranges { Value: 33554432 Name: "67108864" }
+ Ranges { Value: 67108864 Name: "inf" }
+ }
+ ];
+
+ COUNTER_HIST_WRITE_BYTES_CHANNEL_0 = 28 [(CounterOpts) = {Name: "HIST(KV/WriteBytesChannel0)"
+ Ranges { Value: 0 Name: "0" }
+ Ranges { Value: 1 Name: "1024" }
+ Ranges { Value: 1024 Name: "2048" }
+ Ranges { Value: 2048 Name: "4096" }
+ Ranges { Value: 4096 Name: "8192" }
+ Ranges { Value: 8192 Name: "16384" }
+ Ranges { Value: 16384 Name: "32768" }
+ Ranges { Value: 32768 Name: "65536" }
+ Ranges { Value: 65536 Name: "131072" }
+ Ranges { Value: 131072 Name: "262144" }
+ Ranges { Value: 262144 Name: "524288" }
+ Ranges { Value: 524288 Name: "1048576" }
+ Ranges { Value: 1048576 Name: "2097152" }
+ Ranges { Value: 2097152 Name: "4194304" }
+ Ranges { Value: 4194304 Name: "5242880" }
+ Ranges { Value: 5242880 Name: "6291456" }
+ Ranges { Value: 6291456 Name: "8388608" }
+ Ranges { Value: 8388608 Name: "16777216" }
+ Ranges { Value: 16777216 Name: "33554432" }
+ Ranges { Value: 33554432 Name: "67108864" }
+ Ranges { Value: 67108864 Name: "inf" }
+ }
+ ];
+
+ COUNTER_HIST_WRITE_BYTES_CHANNEL_1 = 29 [(CounterOpts) = {Name: "HIST(KV/WriteBytesChannel1)"
+ Ranges { Value: 0 Name: "0" }
+ Ranges { Value: 1 Name: "1024" }
+ Ranges { Value: 1024 Name: "2048" }
+ Ranges { Value: 2048 Name: "4096" }
+ Ranges { Value: 4096 Name: "8192" }
+ Ranges { Value: 8192 Name: "16384" }
+ Ranges { Value: 16384 Name: "32768" }
+ Ranges { Value: 32768 Name: "65536" }
+ Ranges { Value: 65536 Name: "131072" }
+ Ranges { Value: 131072 Name: "262144" }
+ Ranges { Value: 262144 Name: "524288" }
+ Ranges { Value: 524288 Name: "1048576" }
+ Ranges { Value: 1048576 Name: "2097152" }
+ Ranges { Value: 2097152 Name: "4194304" }
+ Ranges { Value: 4194304 Name: "5242880" }
+ Ranges { Value: 5242880 Name: "6291456" }
+ Ranges { Value: 6291456 Name: "8388608" }
+ Ranges { Value: 8388608 Name: "16777216" }
+ Ranges { Value: 16777216 Name: "33554432" }
+ Ranges { Value: 33554432 Name: "67108864" }
+ Ranges { Value: 67108864 Name: "inf" }
+ }
+ ];
+
+ COUNTER_HIST_WRITE_BYTES_CHANNEL_2 = 30 [(CounterOpts) = {Name: "HIST(KV/WriteBytesChannel2)"
+ Ranges { Value: 0 Name: "0" }
+ Ranges { Value: 1 Name: "1024" }
+ Ranges { Value: 1024 Name: "2048" }
+ Ranges { Value: 2048 Name: "4096" }
+ Ranges { Value: 4096 Name: "8192" }
+ Ranges { Value: 8192 Name: "16384" }
+ Ranges { Value: 16384 Name: "32768" }
+ Ranges { Value: 32768 Name: "65536" }
+ Ranges { Value: 65536 Name: "131072" }
+ Ranges { Value: 131072 Name: "262144" }
+ Ranges { Value: 262144 Name: "524288" }
+ Ranges { Value: 524288 Name: "1048576" }
+ Ranges { Value: 1048576 Name: "2097152" }
+ Ranges { Value: 2097152 Name: "4194304" }
+ Ranges { Value: 4194304 Name: "5242880" }
+ Ranges { Value: 5242880 Name: "6291456" }
+ Ranges { Value: 6291456 Name: "8388608" }
+ Ranges { Value: 8388608 Name: "16777216" }
+ Ranges { Value: 16777216 Name: "33554432" }
+ Ranges { Value: 33554432 Name: "67108864" }
+ Ranges { Value: 67108864 Name: "inf" }
+ }
+ ];
+
+ COUNTER_HIST_WRITE_BYTES_CHANNEL_3 = 31 [(CounterOpts) = {Name: "HIST(KV/WriteBytesChannel3)"
+ Ranges { Value: 0 Name: "0" }
+ Ranges { Value: 1 Name: "1024" }
+ Ranges { Value: 1024 Name: "2048" }
+ Ranges { Value: 2048 Name: "4096" }
+ Ranges { Value: 4096 Name: "8192" }
+ Ranges { Value: 8192 Name: "16384" }
+ Ranges { Value: 16384 Name: "32768" }
+ Ranges { Value: 32768 Name: "65536" }
+ Ranges { Value: 65536 Name: "131072" }
+ Ranges { Value: 131072 Name: "262144" }
+ Ranges { Value: 262144 Name: "524288" }
+ Ranges { Value: 524288 Name: "1048576" }
+ Ranges { Value: 1048576 Name: "2097152" }
+ Ranges { Value: 2097152 Name: "4194304" }
+ Ranges { Value: 4194304 Name: "5242880" }
+ Ranges { Value: 5242880 Name: "6291456" }
+ Ranges { Value: 6291456 Name: "8388608" }
+ Ranges { Value: 8388608 Name: "16777216" }
+ Ranges { Value: 16777216 Name: "33554432" }
+ Ranges { Value: 33554432 Name: "67108864" }
+ Ranges { Value: 67108864 Name: "inf" }
+ }
+ ];
+
+ COUNTER_HIST_WRITE_BYTES_CHANNEL_4 = 32 [(CounterOpts) = {Name: "HIST(KV/WriteBytesChannel4)"
+ Ranges { Value: 0 Name: "0" }
+ Ranges { Value: 1 Name: "1024" }
+ Ranges { Value: 1024 Name: "2048" }
+ Ranges { Value: 2048 Name: "4096" }
+ Ranges { Value: 4096 Name: "8192" }
+ Ranges { Value: 8192 Name: "16384" }
+ Ranges { Value: 16384 Name: "32768" }
+ Ranges { Value: 32768 Name: "65536" }
+ Ranges { Value: 65536 Name: "131072" }
+ Ranges { Value: 131072 Name: "262144" }
+ Ranges { Value: 262144 Name: "524288" }
+ Ranges { Value: 524288 Name: "1048576" }
+ Ranges { Value: 1048576 Name: "2097152" }
+ Ranges { Value: 2097152 Name: "4194304" }
+ Ranges { Value: 4194304 Name: "5242880" }
+ Ranges { Value: 5242880 Name: "6291456" }
+ Ranges { Value: 6291456 Name: "8388608" }
+ Ranges { Value: 8388608 Name: "16777216" }
+ Ranges { Value: 16777216 Name: "33554432" }
+ Ranges { Value: 33554432 Name: "67108864" }
+ Ranges { Value: 67108864 Name: "inf" }
+ }
+ ];
+
+ COUNTER_HIST_WRITE_BYTES_CHANNEL_5 = 33 [(CounterOpts) = {Name: "HIST(KV/WriteBytesChannel5)"
+ Ranges { Value: 0 Name: "0" }
+ Ranges { Value: 1 Name: "1024" }
+ Ranges { Value: 1024 Name: "2048" }
+ Ranges { Value: 2048 Name: "4096" }
+ Ranges { Value: 4096 Name: "8192" }
+ Ranges { Value: 8192 Name: "16384" }
+ Ranges { Value: 16384 Name: "32768" }
+ Ranges { Value: 32768 Name: "65536" }
+ Ranges { Value: 65536 Name: "131072" }
+ Ranges { Value: 131072 Name: "262144" }
+ Ranges { Value: 262144 Name: "524288" }
+ Ranges { Value: 524288 Name: "1048576" }
+ Ranges { Value: 1048576 Name: "2097152" }
+ Ranges { Value: 2097152 Name: "4194304" }
+ Ranges { Value: 4194304 Name: "5242880" }
+ Ranges { Value: 5242880 Name: "6291456" }
+ Ranges { Value: 6291456 Name: "8388608" }
+ Ranges { Value: 8388608 Name: "16777216" }
+ Ranges { Value: 16777216 Name: "33554432" }
+ Ranges { Value: 33554432 Name: "67108864" }
+ Ranges { Value: 67108864 Name: "inf" }
+ }
+ ];
+
+ COUNTER_HIST_WRITE_BYTES_CHANNEL_6 = 34 [(CounterOpts) = {Name: "HIST(KV/WriteBytesChannel6)"
+ Ranges { Value: 0 Name: "0" }
+ Ranges { Value: 1 Name: "1024" }
+ Ranges { Value: 1024 Name: "2048" }
+ Ranges { Value: 2048 Name: "4096" }
+ Ranges { Value: 4096 Name: "8192" }
+ Ranges { Value: 8192 Name: "16384" }
+ Ranges { Value: 16384 Name: "32768" }
+ Ranges { Value: 32768 Name: "65536" }
+ Ranges { Value: 65536 Name: "131072" }
+ Ranges { Value: 131072 Name: "262144" }
+ Ranges { Value: 262144 Name: "524288" }
+ Ranges { Value: 524288 Name: "1048576" }
+ Ranges { Value: 1048576 Name: "2097152" }
+ Ranges { Value: 2097152 Name: "4194304" }
+ Ranges { Value: 4194304 Name: "5242880" }
+ Ranges { Value: 5242880 Name: "6291456" }
+ Ranges { Value: 6291456 Name: "8388608" }
+ Ranges { Value: 8388608 Name: "16777216" }
+ Ranges { Value: 16777216 Name: "33554432" }
+ Ranges { Value: 33554432 Name: "67108864" }
+ Ranges { Value: 67108864 Name: "inf" }
+ }
+ ];
+
+ COUNTER_HIST_WRITE_BYTES_CHANNEL_7 = 35 [(CounterOpts) = {Name: "HIST(KV/WriteBytesChannel7)"
+ Ranges { Value: 0 Name: "0" }
+ Ranges { Value: 1 Name: "1024" }
+ Ranges { Value: 1024 Name: "2048" }
+ Ranges { Value: 2048 Name: "4096" }
+ Ranges { Value: 4096 Name: "8192" }
+ Ranges { Value: 8192 Name: "16384" }
+ Ranges { Value: 16384 Name: "32768" }
+ Ranges { Value: 32768 Name: "65536" }
+ Ranges { Value: 65536 Name: "131072" }
+ Ranges { Value: 131072 Name: "262144" }
+ Ranges { Value: 262144 Name: "524288" }
+ Ranges { Value: 524288 Name: "1048576" }
+ Ranges { Value: 1048576 Name: "2097152" }
+ Ranges { Value: 2097152 Name: "4194304" }
+ Ranges { Value: 4194304 Name: "5242880" }
+ Ranges { Value: 5242880 Name: "6291456" }
+ Ranges { Value: 6291456 Name: "8388608" }
+ Ranges { Value: 8388608 Name: "16777216" }
+ Ranges { Value: 16777216 Name: "33554432" }
+ Ranges { Value: 33554432 Name: "67108864" }
+ Ranges { Value: 67108864 Name: "inf" }
+ }
+ ];
+
+ COUNTER_HIST_WRITE_BYTES_CHANNEL_8 = 36 [(CounterOpts) = {Name: "HIST(KV/WriteBytesChannel8)"
+ Ranges { Value: 0 Name: "0" }
+ Ranges { Value: 1 Name: "1024" }
+ Ranges { Value: 1024 Name: "2048" }
+ Ranges { Value: 2048 Name: "4096" }
+ Ranges { Value: 4096 Name: "8192" }
+ Ranges { Value: 8192 Name: "16384" }
+ Ranges { Value: 16384 Name: "32768" }
+ Ranges { Value: 32768 Name: "65536" }
+ Ranges { Value: 65536 Name: "131072" }
+ Ranges { Value: 131072 Name: "262144" }
+ Ranges { Value: 262144 Name: "524288" }
+ Ranges { Value: 524288 Name: "1048576" }
+ Ranges { Value: 1048576 Name: "2097152" }
+ Ranges { Value: 2097152 Name: "4194304" }
+ Ranges { Value: 4194304 Name: "5242880" }
+ Ranges { Value: 5242880 Name: "6291456" }
+ Ranges { Value: 6291456 Name: "8388608" }
+ Ranges { Value: 8388608 Name: "16777216" }
+ Ranges { Value: 16777216 Name: "33554432" }
+ Ranges { Value: 33554432 Name: "67108864" }
+ Ranges { Value: 67108864 Name: "inf" }
+ }
+ ];
+
+ COUNTER_HIST_WRITE_BYTES_CHANNEL_9 = 37 [(CounterOpts) = {Name: "HIST(KV/WriteBytesChannel9)"
+ Ranges { Value: 0 Name: "0" }
+ Ranges { Value: 1 Name: "1024" }
+ Ranges { Value: 1024 Name: "2048" }
+ Ranges { Value: 2048 Name: "4096" }
+ Ranges { Value: 4096 Name: "8192" }
+ Ranges { Value: 8192 Name: "16384" }
+ Ranges { Value: 16384 Name: "32768" }
+ Ranges { Value: 32768 Name: "65536" }
+ Ranges { Value: 65536 Name: "131072" }
+ Ranges { Value: 131072 Name: "262144" }
+ Ranges { Value: 262144 Name: "524288" }
+ Ranges { Value: 524288 Name: "1048576" }
+ Ranges { Value: 1048576 Name: "2097152" }
+ Ranges { Value: 2097152 Name: "4194304" }
+ Ranges { Value: 4194304 Name: "5242880" }
+ Ranges { Value: 5242880 Name: "6291456" }
+ Ranges { Value: 6291456 Name: "8388608" }
+ Ranges { Value: 8388608 Name: "16777216" }
+ Ranges { Value: 16777216 Name: "33554432" }
+ Ranges { Value: 33554432 Name: "67108864" }
+ Ranges { Value: 67108864 Name: "inf" }
+ }
+ ];
+
+ COUNTER_HIST_WRITE_BYTES_CHANNEL_10 = 38 [(CounterOpts) = {Name: "HIST(KV/WriteBytesChannel10)"
+ Ranges { Value: 0 Name: "0" }
+ Ranges { Value: 1 Name: "1024" }
+ Ranges { Value: 1024 Name: "2048" }
+ Ranges { Value: 2048 Name: "4096" }
+ Ranges { Value: 4096 Name: "8192" }
+ Ranges { Value: 8192 Name: "16384" }
+ Ranges { Value: 16384 Name: "32768" }
+ Ranges { Value: 32768 Name: "65536" }
+ Ranges { Value: 65536 Name: "131072" }
+ Ranges { Value: 131072 Name: "262144" }
+ Ranges { Value: 262144 Name: "524288" }
+ Ranges { Value: 524288 Name: "1048576" }
+ Ranges { Value: 1048576 Name: "2097152" }
+ Ranges { Value: 2097152 Name: "4194304" }
+ Ranges { Value: 4194304 Name: "5242880" }
+ Ranges { Value: 5242880 Name: "6291456" }
+ Ranges { Value: 6291456 Name: "8388608" }
+ Ranges { Value: 8388608 Name: "16777216" }
+ Ranges { Value: 16777216 Name: "33554432" }
+ Ranges { Value: 33554432 Name: "67108864" }
+ Ranges { Value: 67108864 Name: "inf" }
+ }
+ ];
+
+ COUNTER_HIST_WRITE_BYTES_CHANNEL_11 = 39 [(CounterOpts) = {Name: "HIST(KV/WriteBytesChannel11)"
+ Ranges { Value: 0 Name: "0" }
+ Ranges { Value: 1 Name: "1024" }
+ Ranges { Value: 1024 Name: "2048" }
+ Ranges { Value: 2048 Name: "4096" }
+ Ranges { Value: 4096 Name: "8192" }
+ Ranges { Value: 8192 Name: "16384" }
+ Ranges { Value: 16384 Name: "32768" }
+ Ranges { Value: 32768 Name: "65536" }
+ Ranges { Value: 65536 Name: "131072" }
+ Ranges { Value: 131072 Name: "262144" }
+ Ranges { Value: 262144 Name: "524288" }
+ Ranges { Value: 524288 Name: "1048576" }
+ Ranges { Value: 1048576 Name: "2097152" }
+ Ranges { Value: 2097152 Name: "4194304" }
+ Ranges { Value: 4194304 Name: "5242880" }
+ Ranges { Value: 5242880 Name: "6291456" }
+ Ranges { Value: 6291456 Name: "8388608" }
+ Ranges { Value: 8388608 Name: "16777216" }
+ Ranges { Value: 16777216 Name: "33554432" }
+ Ranges { Value: 33554432 Name: "67108864" }
+ Ranges { Value: 67108864 Name: "inf" }
+ }
+ ];
+
+ COUNTER_HIST_WRITE_BYTES_CHANNEL_12 = 40 [(CounterOpts) = {Name: "HIST(KV/WriteBytesChannel12)"
+ Ranges { Value: 0 Name: "0" }
+ Ranges { Value: 1 Name: "1024" }
+ Ranges { Value: 1024 Name: "2048" }
+ Ranges { Value: 2048 Name: "4096" }
+ Ranges { Value: 4096 Name: "8192" }
+ Ranges { Value: 8192 Name: "16384" }
+ Ranges { Value: 16384 Name: "32768" }
+ Ranges { Value: 32768 Name: "65536" }
+ Ranges { Value: 65536 Name: "131072" }
+ Ranges { Value: 131072 Name: "262144" }
+ Ranges { Value: 262144 Name: "524288" }
+ Ranges { Value: 524288 Name: "1048576" }
+ Ranges { Value: 1048576 Name: "2097152" }
+ Ranges { Value: 2097152 Name: "4194304" }
+ Ranges { Value: 4194304 Name: "5242880" }
+ Ranges { Value: 5242880 Name: "6291456" }
+ Ranges { Value: 6291456 Name: "8388608" }
+ Ranges { Value: 8388608 Name: "16777216" }
+ Ranges { Value: 16777216 Name: "33554432" }
+ Ranges { Value: 33554432 Name: "67108864" }
+ Ranges { Value: 67108864 Name: "inf" }
+ }
+ ];
+
+ COUNTER_HIST_WRITE_BYTES_CHANNEL_13 = 41 [(CounterOpts) = {Name: "HIST(KV/WriteBytesChannel13)"
+ Ranges { Value: 0 Name: "0" }
+ Ranges { Value: 1 Name: "1024" }
+ Ranges { Value: 1024 Name: "2048" }
+ Ranges { Value: 2048 Name: "4096" }
+ Ranges { Value: 4096 Name: "8192" }
+ Ranges { Value: 8192 Name: "16384" }
+ Ranges { Value: 16384 Name: "32768" }
+ Ranges { Value: 32768 Name: "65536" }
+ Ranges { Value: 65536 Name: "131072" }
+ Ranges { Value: 131072 Name: "262144" }
+ Ranges { Value: 262144 Name: "524288" }
+ Ranges { Value: 524288 Name: "1048576" }
+ Ranges { Value: 1048576 Name: "2097152" }
+ Ranges { Value: 2097152 Name: "4194304" }
+ Ranges { Value: 4194304 Name: "5242880" }
+ Ranges { Value: 5242880 Name: "6291456" }
+ Ranges { Value: 6291456 Name: "8388608" }
+ Ranges { Value: 8388608 Name: "16777216" }
+ Ranges { Value: 16777216 Name: "33554432" }
+ Ranges { Value: 33554432 Name: "67108864" }
+ Ranges { Value: 67108864 Name: "inf" }
+ }
+ ];
+
+ COUNTER_HIST_WRITE_BYTES_CHANNEL_14 = 42 [(CounterOpts) = {Name: "HIST(KV/WriteBytesChannel14)"
+ Ranges { Value: 0 Name: "0" }
+ Ranges { Value: 1 Name: "1024" }
+ Ranges { Value: 1024 Name: "2048" }
+ Ranges { Value: 2048 Name: "4096" }
+ Ranges { Value: 4096 Name: "8192" }
+ Ranges { Value: 8192 Name: "16384" }
+ Ranges { Value: 16384 Name: "32768" }
+ Ranges { Value: 32768 Name: "65536" }
+ Ranges { Value: 65536 Name: "131072" }
+ Ranges { Value: 131072 Name: "262144" }
+ Ranges { Value: 262144 Name: "524288" }
+ Ranges { Value: 524288 Name: "1048576" }
+ Ranges { Value: 1048576 Name: "2097152" }
+ Ranges { Value: 2097152 Name: "4194304" }
+ Ranges { Value: 4194304 Name: "5242880" }
+ Ranges { Value: 5242880 Name: "6291456" }
+ Ranges { Value: 6291456 Name: "8388608" }
+ Ranges { Value: 8388608 Name: "16777216" }
+ Ranges { Value: 16777216 Name: "33554432" }
+ Ranges { Value: 33554432 Name: "67108864" }
+ Ranges { Value: 67108864 Name: "inf" }
+ }
+ ];
+
+ COUNTER_HIST_WRITE_BYTES_CHANNEL_15 = 43 [(CounterOpts) = {Name: "HIST(KV/WriteBytesChannel15)"
+ Ranges { Value: 0 Name: "0" }
+ Ranges { Value: 1 Name: "1024" }
+ Ranges { Value: 1024 Name: "2048" }
+ Ranges { Value: 2048 Name: "4096" }
+ Ranges { Value: 4096 Name: "8192" }
+ Ranges { Value: 8192 Name: "16384" }
+ Ranges { Value: 16384 Name: "32768" }
+ Ranges { Value: 32768 Name: "65536" }
+ Ranges { Value: 65536 Name: "131072" }
+ Ranges { Value: 131072 Name: "262144" }
+ Ranges { Value: 262144 Name: "524288" }
+ Ranges { Value: 524288 Name: "1048576" }
+ Ranges { Value: 1048576 Name: "2097152" }
+ Ranges { Value: 2097152 Name: "4194304" }
+ Ranges { Value: 4194304 Name: "5242880" }
+ Ranges { Value: 5242880 Name: "6291456" }
+ Ranges { Value: 6291456 Name: "8388608" }
+ Ranges { Value: 8388608 Name: "16777216" }
+ Ranges { Value: 16777216 Name: "33554432" }
+ Ranges { Value: 33554432 Name: "67108864" }
+ Ranges { Value: 67108864 Name: "inf" }
+ }
+ ];
+
}
enum ETxTypes {
diff --git a/ydb/core/protos/counters_schemeshard.proto b/ydb/core/protos/counters_schemeshard.proto
index ea268e595be..a839915c98f 100644
--- a/ydb/core/protos/counters_schemeshard.proto
+++ b/ydb/core/protos/counters_schemeshard.proto
@@ -75,7 +75,7 @@ enum ESimpleCounters {
COUNTER_IN_FLIGHT_OPS_TxFillIndex = 61 [(CounterOpts) = {Name: "InFlightOps/FillIndex"}];
COUNTER_IN_FLIGHT_OPS_TxUpgradeSubDomain = 62 [(CounterOpts) = {Name: "InFlightOps/UpgradeSubDomain"}];
COUNTER_IN_FLIGHT_OPS_TxUpgradeSubDomainDecision = 63 [(CounterOpts) = {Name: "InFlightOps/UpgradeSubDomainDecision"}];
- COUNTER_SUB_DOMAIN_HIVE_COUNT = 64 [(CounterOpts) = {Name: "SubDomainsHives"}];
+ COUNTER_SUB_DOMAIN_HIVE_COUNT = 64 [(CounterOpts) = {Name: "SubDomainsHives"}];
COUNTER_IN_FLIGHT_OPS_TxInitializeBuildIndex = 65 [(CounterOpts) = {Name: "InFlightOps/InitializeBuildIndex"}];
COUNTER_SNAPSHOTS_COUNT = 66 [(CounterOpts) = {Name: "Snapshots"}];
COUNTER_LOCKS_COUNT = 67 [(CounterOpts) = {Name: "Locks"}];
@@ -351,8 +351,8 @@ enum ETxTypes {
TXTYPE_CLEAN_BLOCKSTORE_VOLUMES = 61 [(TxTypeOpts) = {Name: "TxCleanBlockStoreVolumes"}];
TXTYPE_CLEAN_DROPPED_PATHS = 62 [(TxTypeOpts) = {Name: "TxCleanDroppedPaths"}];
TXTYPE_CLEAN_DROPPED_SUBDOMAINS = 63 [(TxTypeOpts) = {Name: "TxCleanDroppedSubDomains"}];
-
- TXTYPE_LOGIN = 64 [(TxTypeOpts) = {Name: "TxLogin"}];
+
+ TXTYPE_LOGIN = 64 [(TxTypeOpts) = {Name: "TxLogin"}];
TXTYPE_SEQUENCESHARD_CREATE_SEQUENCE_RESULT = 65 [(TxTypeOpts) = {Name: "TxSequenceShardCreateSequenceResult"}];
TXTYPE_SEQUENCESHARD_DROP_SEQUENCE_RESULT = 66 [(TxTypeOpts) = {Name: "TxSequenceShardDropSequenceResult"}];
diff --git a/ydb/core/protos/flat_scheme_op.proto b/ydb/core/protos/flat_scheme_op.proto
index 9cbc55c1366..33e598c1c25 100644
--- a/ydb/core/protos/flat_scheme_op.proto
+++ b/ydb/core/protos/flat_scheme_op.proto
@@ -651,50 +651,50 @@ message TAlterColumnTable {
optional string RESERVED_AlterTtlSettingsPresetName = 5;
}
-message TLoginCreateUser {
- optional string User = 1;
- optional string Password = 2;
-}
-
-message TLoginModifyUser {
- optional string User = 1;
- optional string Password = 2;
-}
-
-message TLoginRemoveUser {
- optional string User = 1;
-}
-
-message TLoginCreateGroup {
- optional string Group = 1;
-}
-
-message TLoginAddGroupMembership {
- optional string Group = 1;
- optional string Member = 2;
-}
-
-message TLoginRemoveGroupMembership {
- optional string Group = 1;
- optional string Member = 2;
-}
-
-message TLoginRemoveGroup {
- optional string Group = 1;
-}
-
-message TAlterLogin {
- oneof Alter {
- TLoginCreateUser CreateUser = 1;
- TLoginModifyUser ModifyUser = 2;
- TLoginRemoveUser RemoveUser = 3;
- TLoginCreateGroup CreateGroup = 4;
- TLoginAddGroupMembership AddGroupMembership = 5;
- TLoginRemoveGroupMembership RemoveGroupMembership = 6;
- TLoginRemoveGroup RemoveGroup = 7;
- }
-}
-
+message TLoginCreateUser {
+ optional string User = 1;
+ optional string Password = 2;
+}
+
+message TLoginModifyUser {
+ optional string User = 1;
+ optional string Password = 2;
+}
+
+message TLoginRemoveUser {
+ optional string User = 1;
+}
+
+message TLoginCreateGroup {
+ optional string Group = 1;
+}
+
+message TLoginAddGroupMembership {
+ optional string Group = 1;
+ optional string Member = 2;
+}
+
+message TLoginRemoveGroupMembership {
+ optional string Group = 1;
+ optional string Member = 2;
+}
+
+message TLoginRemoveGroup {
+ optional string Group = 1;
+}
+
+message TAlterLogin {
+ oneof Alter {
+ TLoginCreateUser CreateUser = 1;
+ TLoginModifyUser ModifyUser = 2;
+ TLoginRemoveUser RemoveUser = 3;
+ TLoginCreateGroup CreateGroup = 4;
+ TLoginAddGroupMembership AddGroupMembership = 5;
+ TLoginRemoveGroupMembership RemoveGroupMembership = 6;
+ TLoginRemoveGroup RemoveGroup = 7;
+ }
+}
+
enum ECdcStreamState {
ECdcStreamStateInvalid = 0;
ECdcStreamStateReady = 1;
@@ -1008,12 +1008,12 @@ message TBlockStoreAssignOp {
optional uint64 TokenVersion = 3;
}
-message TModifyACL {
- optional string Name = 1;
- optional bytes DiffACL = 2; // NACLibProto.TDiffACL
- optional string NewOwner = 3;
-}
-
+message TModifyACL {
+ optional string Name = 1;
+ optional bytes DiffACL = 2; // NACLibProto.TDiffACL
+ optional string NewOwner = 3;
+}
+
message TSplitMergeTablePartitions {
optional uint64 TxId = 1;
optional string TablePath = 2;
@@ -1074,7 +1074,7 @@ enum EOperationType {
ESchemeOpDropPersQueueGroup = 5;
ESchemeOpAlterTable = 6;
ESchemeOpAlterPersQueueGroup = 7;
- ESchemeOpModifyACL = 8;
+ ESchemeOpModifyACL = 8;
ESchemeOpRmDir = 9;
ESchemeOpSplitMergeTablePartitions = 10;
ESchemeOpBackup = 11;
@@ -1143,8 +1143,8 @@ enum EOperationType {
ESchemeOpCreateColumnTable = 58;
ESchemeOpAlterColumnTable = 59;
ESchemeOpDropColumnTable = 60;
-
- ESchemeOpAlterLogin = 61;
+
+ ESchemeOpAlterLogin = 61;
/// CDC
// Create
@@ -1230,7 +1230,7 @@ message TModifyScheme {
optional TPersQueueGroupDescription CreatePersQueueGroup = 5;
optional TPersQueueGroupDescription AlterPersQueueGroup = 6;
optional TDrop Drop = 7;
- optional TModifyACL ModifyACL = 8;
+ optional TModifyACL ModifyACL = 8;
optional TTableDescription AlterTable = 9;
optional TSplitMergeTablePartitions SplitMergeTablePartitions = 10;
optional TBackupTask Backup = 11;
@@ -1265,7 +1265,7 @@ message TModifyScheme {
optional TColumnTableDescription CreateColumnTable = 41;
optional TAlterColumnStore AlterColumnStore = 42;
optional TAlterColumnTable AlterColumnTable = 43;
- optional TAlterLogin AlterLogin = 44;
+ optional TAlterLogin AlterLogin = 44;
optional TCreateCdcStream CreateCdcStream = 45;
optional TAlterCdcStream AlterCdcStream = 46;
optional TDropCdcStream DropCdcStream = 47;
@@ -1275,11 +1275,11 @@ message TModifyScheme {
optional TReplicationDescription Replication = 52;
}
-// "Script", used by client to parse text files with multiple DDL commands
-message TModifyScript {
- repeated TModifyScheme ModifyScheme = 1;
-}
-
+// "Script", used by client to parse text files with multiple DDL commands
+message TModifyScript {
+ repeated TModifyScheme ModifyScheme = 1;
+}
+
message TDescribeOptions {
optional bool ReturnPartitioningInfo = 1 [default = true];
optional bool ReturnPartitionConfig = 2 [default = true];
@@ -1373,7 +1373,7 @@ message TPathVersion {
optional uint64 ColumnTableSchemaVersion = 20;
optional uint64 ColumnTableTtlSettingsVersion = 21;
optional uint64 CdcStreamVersion = 22;
- optional uint64 SecurityStateVersion = 23;
+ optional uint64 SecurityStateVersion = 23;
optional uint64 SequenceVersion = 24;
optional uint64 ReplicationVersion = 25;
}
@@ -1389,9 +1389,9 @@ message TDirEntry {
optional uint64 CreateStep = 7;
optional uint64 ParentPathId = 8; // parentPathOwnerId ?
optional EPathState PathState = 9;
- optional string Owner = 10;
- optional bytes ACL = 11;
- optional bytes EffectiveACL = 12;
+ optional string Owner = 10;
+ optional bytes ACL = 11;
+ optional bytes EffectiveACL = 12;
optional uint64 PathVersion = 13;
optional EPathSubType PathSubType = 14;
optional TPathVersion Version = 15;
@@ -1426,7 +1426,7 @@ message TBackupProgress {
message TLastBackupResult {
optional uint32 ErrorCount = 1;
optional uint64 CompleteTimeStamp = 2;
- optional uint64 StartTimeStamp = 3;
+ optional uint64 StartTimeStamp = 3;
repeated TShardError Errors = 4;
optional TYTSettings YTSettings = 5;
optional uint64 DataTotalSize = 6;
@@ -1443,7 +1443,7 @@ message TPathDescription {
optional TBackupProgress BackupProgress = 6;
repeated TLastBackupResult LastBackupResult = 7;
optional NKikimrTableStats.TTableStats TableStats = 8;
- optional NKikimrTabletBase.TMetrics TabletMetrics = 9;
+ optional NKikimrTabletBase.TMetrics TabletMetrics = 9;
optional NKikimrSubDomains.TDomainDescription DomainDescription = 10;
optional TRtmrVolumeDescription RtmrVolumeDescription = 11; // for rtmr volume
optional TBlockStoreVolumeDescription BlockStoreVolumeDescription = 12;
diff --git a/ydb/core/protos/flat_tx_scheme.proto b/ydb/core/protos/flat_tx_scheme.proto
index 6e527f6abc3..dc06523e5cc 100644
--- a/ydb/core/protos/flat_tx_scheme.proto
+++ b/ydb/core/protos/flat_tx_scheme.proto
@@ -31,31 +31,31 @@ enum EStatus {
StatusReadOnly = 9;
StatusTxIdNotExists = 10;
StatusTxIsNotCancellable = 11;
- StatusAccessDenied = 12;
- StatusNotAvailable = 13;
+ StatusAccessDenied = 12;
+ StatusNotAvailable = 13;
StatusPreconditionFailed = 14;
StatusRedirectDomain = 15;
StatusQuotaExceeded = 16;
StatusResourceExhausted = 17;
StatusReserved18 = 18;
StatusReserved19 = 19;
- // when adding a new status and keeping parse compatibility with the old version
- // rename existing reserved status to desired one, and add new reserved status to
- // the end of reserved statuses
+ // when adding a new status and keeping parse compatibility with the old version
+ // rename existing reserved status to desired one, and add new reserved status to
+ // the end of reserved statuses
}
message TEvModifySchemeTransaction {
repeated NKikimrSchemeOp.TModifyScheme Transaction = 1;
optional uint64 TxId = 2;
optional uint64 TabletId = 3;
- optional string Owner = 5;
+ optional string Owner = 5;
optional bool FailOnExist = 6; // depricated, TModifyScheme.FailOnExist is recomended
optional string UserToken = 7; // serialized NACLib::TUserToken
}
message TEvModifySchemeTransactionResult {
- optional EStatus Status = 1;
- optional string Reason = 2;
+ optional EStatus Status = 1;
+ optional string Reason = 2;
optional uint64 TxId = 3;
optional uint64 SchemeshardId = 4;
optional uint64 PathId = 5;
@@ -64,8 +64,8 @@ message TEvModifySchemeTransactionResult {
}
message TEvDescribeSchemeResult {
- optional EStatus Status = 1;
- optional string Reason = 2;
+ optional EStatus Status = 1;
+ optional string Reason = 2;
optional string Path = 3;
optional NKikimrSchemeOp.TPathDescription PathDescription = 4;
optional fixed64 PathOwner = 5;
@@ -99,19 +99,19 @@ message TEvUpdateConfig {
message TEvUpdateConfigResult {
optional uint64 Origin = 1;
optional NKikimrProto.EReplyStatus Status = 2;
- optional string Reason = 3;
-}
-
-message TEvLogin {
- optional string User = 1;
- optional string Password = 2;
-}
-
-message TEvLoginResult {
- optional string Error = 1;
- optional string Token = 2;
-}
-
+ optional string Reason = 3;
+}
+
+message TEvLogin {
+ optional string User = 1;
+ optional string Password = 2;
+}
+
+message TEvLoginResult {
+ optional string Error = 1;
+ optional string Token = 2;
+}
+
// Sending actor registers itself to be notified when tx completes
message TEvNotifyTxCompletion {
optional uint64 TxId = 1;
diff --git a/ydb/core/protos/grpc.proto b/ydb/core/protos/grpc.proto
index f2ce370a061..797cc2de829 100644
--- a/ydb/core/protos/grpc.proto
+++ b/ydb/core/protos/grpc.proto
@@ -25,8 +25,8 @@ service TGRpcServer {
rpc SchemeOperationStatus(TSchemeOperationStatus) returns (TResponse);
// describe
rpc SchemeDescribe(TSchemeDescribe) returns (TResponse);
- // whoami
- rpc WhoAmI(TWhoAmI) returns (TResponse);
+ // whoami
+ rpc WhoAmI(TWhoAmI) returns (TResponse);
/////////////////////////////////////////////////////////////////////////////////////////////////
// CHOOSE PROXY INTERFACE
@@ -46,8 +46,8 @@ service TGRpcServer {
rpc BSAdm(TBSAdm) returns (TResponse);
rpc ResolveNode(TResolveNodeRequest) returns (TResponse);
- rpc FillNode(TFillNodeRequest) returns (TResponse);
- rpc DrainNode(TDrainNodeRequest) returns (TResponse);
+ rpc FillNode(TFillNodeRequest) returns (TResponse);
+ rpc DrainNode(TDrainNodeRequest) returns (TResponse);
// Blob storage configuration manipulation/query interface
rpc BlobStorageConfig(TBlobStorageConfigRequest) returns (TResponse);
diff --git a/ydb/core/protos/hive.proto b/ydb/core/protos/hive.proto
index e857c2d8568..0059db81de8 100644
--- a/ydb/core/protos/hive.proto
+++ b/ydb/core/protos/hive.proto
@@ -22,35 +22,35 @@ enum EErrorReason {
// CreateTablet request provided a smaller number of channels than previous requests
ERROR_REASON_CHANNELS_CANNOT_SHRINK = 1;
-
- ERROR_REASON_INVALID_ARGUMENTS = 2;
-}
-
-enum ETabletVolatileState {
- TABLET_VOLATILE_STATE_UNKNOWN = 0;
- TABLET_VOLATILE_STATE_STOPPED = 1;
- TABLET_VOLATILE_STATE_BOOTING = 2;
- TABLET_VOLATILE_STATE_STARTING = 3;
- TABLET_VOLATILE_STATE_RUNNING = 4;
- _TABLET_VOLATILE_STATE_BLOCKED = 5; // deprecated
-}
-
-enum EMigrationState {
- MIGRATION_UNKNOWN = 0;
- MIGRATION_READY = 1;
- MIGRATION_ACTIVE = 2;
- MIGRATION_COMPLETE = 3;
-}
-
+
+ ERROR_REASON_INVALID_ARGUMENTS = 2;
+}
+
+enum ETabletVolatileState {
+ TABLET_VOLATILE_STATE_UNKNOWN = 0;
+ TABLET_VOLATILE_STATE_STOPPED = 1;
+ TABLET_VOLATILE_STATE_BOOTING = 2;
+ TABLET_VOLATILE_STATE_STARTING = 3;
+ TABLET_VOLATILE_STATE_RUNNING = 4;
+ _TABLET_VOLATILE_STATE_BLOCKED = 5; // deprecated
+}
+
+enum EMigrationState {
+ MIGRATION_UNKNOWN = 0;
+ MIGRATION_READY = 1;
+ MIGRATION_ACTIVE = 2;
+ MIGRATION_COMPLETE = 3;
+}
+
message TChannelInfo {
message THistorySlot {
optional uint32 FromGeneration = 1;
optional uint32 GroupID = 2;
- optional uint64 Timestamp = 3; // ms
+ optional uint64 Timestamp = 3; // ms
}
optional uint32 Id = 1;
- optional uint32 Type = 2; // erasure
+ optional uint32 Type = 2; // erasure
repeated THistorySlot History = 3;
}
@@ -63,55 +63,55 @@ message TEvBootTabletReply {
optional string StatusMsg = 2;
}
-message TTabletCategory {
- optional uint64 TabletCategoryID = 1; // it's required, actually
- optional uint64 MaxDisconnectTimeout = 2; // ms
- optional bool StickTogetherInDC = 3;
-}
-
-message TDataCentersGroup {
+message TTabletCategory {
+ optional uint64 TabletCategoryID = 1; // it's required, actually
+ optional uint64 MaxDisconnectTimeout = 2; // ms
+ optional bool StickTogetherInDC = 3;
+}
+
+message TDataCentersGroup {
repeated uint64 DataCenterNum = 1 [deprecated=true]; // array of DC IDs preffered to run the tablet; obsolete
repeated string DataCenter = 2;
-}
-
-message TDataCentersPreference {
- repeated TDataCentersGroup DataCentersGroups = 1;
-}
-
+}
+
+message TDataCentersPreference {
+ repeated TDataCentersGroup DataCentersGroups = 1;
+}
+
message TEvCreateTablet {
optional fixed64 Owner = 1;
optional uint64 OwnerIdx = 2;
- optional NKikimrTabletBase.TTabletTypes.EType TabletType = 3;
+ optional NKikimrTabletBase.TTabletTypes.EType TabletType = 3;
optional uint32 AssignStateStorage = 4;
repeated uint32 AllowedNodeIDs = 7;
repeated uint64 AllowedDataCenterNumIDs = 14 [deprecated=true]; // array of DC IDs allowed to run the tablet; obsolete; use AllowedDataCenters instead
- optional TTabletCategory TabletCategory = 16;
+ optional TTabletCategory TabletCategory = 16;
repeated TFollowerGroup FollowerGroups = 17;
- optional NKikimrSubDomains.TDomainKey ObjectDomain = 18;
+ optional NKikimrSubDomains.TDomainKey ObjectDomain = 18;
optional ETabletBootMode TabletBootMode = 19;
- optional uint64 ObjectId = 20;
+ optional uint64 ObjectId = 20;
repeated NKikimrStoragePool.TChannelBind BindedChannels = 21;
- optional fixed64 TabletID = 22;
- repeated NKikimrSubDomains.TDomainKey AllowedDomains = 23;
- optional TDataCentersPreference DataCentersPreference = 24;
+ optional fixed64 TabletID = 22;
+ repeated NKikimrSubDomains.TDomainKey AllowedDomains = 23;
+ optional TDataCentersPreference DataCentersPreference = 24;
repeated string AllowedDataCenters = 25;
-
- optional uint32 ChannelsProfile = 5 [deprecated = true]; // DEPRECATED
- optional uint32 Flags = 6 [deprecated = true]; // DEPRECATED
- optional uint32 BootTimeoutMilliSeconds = 8 [deprecated = true]; // DEPRECATED
- optional uint32 BootAttemptLimit = 9 [deprecated = true]; // DEPRECATED
- optional uint64 Weight = 10 [default = 1000, deprecated = true]; // DEPRECATED
+
+ optional uint32 ChannelsProfile = 5 [deprecated = true]; // DEPRECATED
+ optional uint32 Flags = 6 [deprecated = true]; // DEPRECATED
+ optional uint32 BootTimeoutMilliSeconds = 8 [deprecated = true]; // DEPRECATED
+ optional uint32 BootAttemptLimit = 9 [deprecated = true]; // DEPRECATED
+ optional uint64 Weight = 10 [default = 1000, deprecated = true]; // DEPRECATED
optional uint32 FollowerCount = 11 [default = 0]; // DEPRECATED
optional bool AllowFollowerPromotion = 12 [default = false]; // DEPRECATED
optional bool CrossDataCenterFollowers = 13 [default = false]; // enable to make followers automatically in every DC (one follower per one datacenter) - DEPRECATED
optional uint32 CrossDataCenterFollowerCount = 15; // follower count per one datacenter - DEPRECATED
}
-message TEvLookupTablet {
- optional fixed64 Owner = 1;
- optional uint64 OwnerIdx = 2;
-}
-
+message TEvLookupTablet {
+ optional fixed64 Owner = 1;
+ optional uint64 OwnerIdx = 2;
+}
+
message TEvCreateTabletReply {
optional NKikimrProto.EReplyStatus Status = 1;
optional fixed64 Owner = 2;
@@ -119,7 +119,7 @@ message TEvCreateTabletReply {
optional fixed64 TabletID = 4;
optional fixed64 Origin = 5;
optional EErrorReason ErrorReason = 6;
- optional TForwardRequest ForwardRequest = 7;
+ optional TForwardRequest ForwardRequest = 7;
}
message TEvTabletCreationResult {
@@ -132,16 +132,16 @@ message TEvStopTablet {
optional NActorsProto.TActorId ActorToNotify = 2;
}
-message TEvStopTabletResult {
+message TEvStopTabletResult {
+ optional NKikimrProto.EReplyStatus Status = 1;
+ optional fixed64 TabletID = 2;
+}
+
+message TEvResumeTabletResult {
optional NKikimrProto.EReplyStatus Status = 1;
optional fixed64 TabletID = 2;
}
-message TEvResumeTabletResult {
- optional NKikimrProto.EReplyStatus Status = 1;
- optional fixed64 TabletID = 2;
-}
-
message TChannelRequest {
optional uint32 Id = 1;
optional uint32 Type = 2;
@@ -187,16 +187,16 @@ message TEvDeleteTablet {
optional fixed64 ShardOwnerId = 1;
repeated uint64 ShardLocalIdx = 2;
optional uint64 TxId_Deprecated = 3;
- repeated fixed64 TabletID = 4;
+ repeated fixed64 TabletID = 4;
}
message TEvDeleteTabletReply {
optional NKikimrProto.EReplyStatus Status = 1;
- optional fixed64 Origin = 2;
+ optional fixed64 Origin = 2;
optional uint64 TxId_Deprecated = 3;
optional uint64 ShardOwnerId = 4;
repeated uint64 ShardLocalIdx = 5;
- optional TForwardRequest ForwardRequest = 6;
+ optional TForwardRequest ForwardRequest = 6;
}
message TEvDeleteOwnerTablets {
@@ -223,137 +223,137 @@ message TEvChannelInfo {
optional fixed64 TabletID = 2;
repeated TChannelInfo ChannelInfo = 3;
}
-
-message TTabletMetrics {
- optional fixed64 TabletID = 1;
- optional NKikimrTabletBase.TMetrics ResourceUsage = 4;
+
+message TTabletMetrics {
+ optional fixed64 TabletID = 1;
+ optional NKikimrTabletBase.TMetrics ResourceUsage = 4;
optional uint32 FollowerID = 3;
-}
-
-message TEvTabletMetrics {
- repeated TTabletMetrics TabletMetrics = 1;
- optional NKikimrTabletBase.TMetrics TotalResourceUsage = 2;
- optional double TotalNodeUsage = 3;
-}
-
-message TEvReassignTablet {
- enum EHiveReassignReason {
- HIVE_REASSIGN_REASON_NO = 0;
- HIVE_REASSIGN_REASON_SPACE = 1;
- }
-
- optional fixed64 TabletID = 1;
- repeated uint32 Channels = 2;
- repeated uint32 ForcedGroupIDs = 3;
- optional EHiveReassignReason ReassignReason = 4;
-}
-
-message TForwardRequest {
- optional fixed64 HiveTabletId = 1;
-}
-
-message TEvRequestHiveInfo {
- optional fixed64 TabletID = 1;
- optional NKikimrTabletBase.TTabletTypes.EType TabletType = 2;
+}
+
+message TEvTabletMetrics {
+ repeated TTabletMetrics TabletMetrics = 1;
+ optional NKikimrTabletBase.TMetrics TotalResourceUsage = 2;
+ optional double TotalNodeUsage = 3;
+}
+
+message TEvReassignTablet {
+ enum EHiveReassignReason {
+ HIVE_REASSIGN_REASON_NO = 0;
+ HIVE_REASSIGN_REASON_SPACE = 1;
+ }
+
+ optional fixed64 TabletID = 1;
+ repeated uint32 Channels = 2;
+ repeated uint32 ForcedGroupIDs = 3;
+ optional EHiveReassignReason ReassignReason = 4;
+}
+
+message TForwardRequest {
+ optional fixed64 HiveTabletId = 1;
+}
+
+message TEvRequestHiveInfo {
+ optional fixed64 TabletID = 1;
+ optional NKikimrTabletBase.TTabletTypes.EType TabletType = 2;
optional bool ReturnFollowers = 3;
optional uint32 FollowerID = 4;
- optional bool ReturnMetrics = 5;
-}
-
-message TEvResponseHiveInfo {
- repeated TTabletInfo Tablets = 1;
- optional TForwardRequest ForwardRequest = 2;
-}
-
-message TEvRequestHiveDomainStats {
+ optional bool ReturnMetrics = 5;
+}
+
+message TEvResponseHiveInfo {
+ repeated TTabletInfo Tablets = 1;
+ optional TForwardRequest ForwardRequest = 2;
+}
+
+message TEvRequestHiveDomainStats {
optional bool ReturnFollowers = 3;
- optional bool ReturnMetrics = 5;
-}
-
-message THiveDomainStatsStateCount {
- optional ETabletVolatileState VolatileState = 1;
- optional uint32 Count = 2;
-}
-
-message THiveDomainStats {
- optional fixed64 ShardId = 1;
- optional uint64 PathId = 2;
- repeated THiveDomainStatsStateCount StateStats = 3;
- optional NKikimrTabletBase.TMetrics Metrics = 4;
- repeated uint32 NodeIds = 5;
- optional uint32 AliveNodes = 6;
-}
-
-message TEvResponseHiveDomainStats {
- repeated THiveDomainStats DomainStats = 1;
-}
-
-message TEvRequestHiveNodeStats {
- optional bool ReturnMetrics = 5;
-}
-
-message THiveNodeStats {
- optional uint32 NodeId = 1;
- repeated THiveDomainStatsStateCount StateStats = 3;
- optional NKikimrTabletBase.TMetrics Metrics = 4;
- optional uint32 RestartsPerPeriod = 6;
- optional uint64 LastAliveTimestamp = 7;
- optional NKikimrSubDomains.TDomainKey NodeDomain = 8;
-}
-
-message TEvResponseHiveNodeStats {
- repeated THiveNodeStats NodeStats = 1;
-}
-
-message TEvRequestHiveStorageStats {
-}
-
-message THiveStorageGroupStats {
- optional uint32 GroupID = 1;
- optional uint64 AcquiredUnits = 2;
- optional float AcquiredIOPS = 3;
- optional uint64 AcquiredThroughput = 4;
- optional uint64 AcquiredSize = 5;
- optional float MaximumIOPS = 7;
- optional uint64 MaximumThroughput = 8;
- optional uint64 MaximumSize = 9;
- optional uint64 AllocatedSize = 10;
- optional uint64 AvailableSize = 11;
-}
-
-message THiveStoragePoolStats {
- optional string Name = 1;
- repeated THiveStorageGroupStats Groups = 2;
-}
-
-message TEvResponseHiveStorageStats {
- repeated THiveStoragePoolStats Pools = 1;
-}
-
-message TTabletOwner {
- optional fixed64 Owner = 1;
- optional uint64 OwnerIdx = 2;
-}
-
-message TEvDrainNode {
- optional uint32 NodeID = 1;
- optional bool Persist = 3 [default = true];
- optional bool KeepDown = 4 [default = false];
- optional uint32 DrainInFlight = 5;
-}
-
-message TEvDrainNodeResult {
- optional NKikimrProto.EReplyStatus Status = 1;
- optional uint32 Movements = 2;
-}
-
-message TEvFillNode {
- optional uint32 NodeID = 1;
-}
-
-message TEvFillNodeResult {
- optional NKikimrProto.EReplyStatus Status = 1;
-}
+ optional bool ReturnMetrics = 5;
+}
+
+message THiveDomainStatsStateCount {
+ optional ETabletVolatileState VolatileState = 1;
+ optional uint32 Count = 2;
+}
+
+message THiveDomainStats {
+ optional fixed64 ShardId = 1;
+ optional uint64 PathId = 2;
+ repeated THiveDomainStatsStateCount StateStats = 3;
+ optional NKikimrTabletBase.TMetrics Metrics = 4;
+ repeated uint32 NodeIds = 5;
+ optional uint32 AliveNodes = 6;
+}
+
+message TEvResponseHiveDomainStats {
+ repeated THiveDomainStats DomainStats = 1;
+}
+
+message TEvRequestHiveNodeStats {
+ optional bool ReturnMetrics = 5;
+}
+
+message THiveNodeStats {
+ optional uint32 NodeId = 1;
+ repeated THiveDomainStatsStateCount StateStats = 3;
+ optional NKikimrTabletBase.TMetrics Metrics = 4;
+ optional uint32 RestartsPerPeriod = 6;
+ optional uint64 LastAliveTimestamp = 7;
+ optional NKikimrSubDomains.TDomainKey NodeDomain = 8;
+}
+
+message TEvResponseHiveNodeStats {
+ repeated THiveNodeStats NodeStats = 1;
+}
+
+message TEvRequestHiveStorageStats {
+}
+
+message THiveStorageGroupStats {
+ optional uint32 GroupID = 1;
+ optional uint64 AcquiredUnits = 2;
+ optional float AcquiredIOPS = 3;
+ optional uint64 AcquiredThroughput = 4;
+ optional uint64 AcquiredSize = 5;
+ optional float MaximumIOPS = 7;
+ optional uint64 MaximumThroughput = 8;
+ optional uint64 MaximumSize = 9;
+ optional uint64 AllocatedSize = 10;
+ optional uint64 AvailableSize = 11;
+}
+
+message THiveStoragePoolStats {
+ optional string Name = 1;
+ repeated THiveStorageGroupStats Groups = 2;
+}
+
+message TEvResponseHiveStorageStats {
+ repeated THiveStoragePoolStats Pools = 1;
+}
+
+message TTabletOwner {
+ optional fixed64 Owner = 1;
+ optional uint64 OwnerIdx = 2;
+}
+
+message TEvDrainNode {
+ optional uint32 NodeID = 1;
+ optional bool Persist = 3 [default = true];
+ optional bool KeepDown = 4 [default = false];
+ optional uint32 DrainInFlight = 5;
+}
+
+message TEvDrainNodeResult {
+ optional NKikimrProto.EReplyStatus Status = 1;
+ optional uint32 Movements = 2;
+}
+
+message TEvFillNode {
+ optional uint32 NodeID = 1;
+}
+
+message TEvFillNodeResult {
+ optional NKikimrProto.EReplyStatus Status = 1;
+}
message TEvGetTabletStorageInfo {
optional fixed64 TabletID = 1;
@@ -397,107 +397,107 @@ message TEvUnlockTabletExecutionResult {
optional NKikimrProto.EReplyStatus Status = 2;
optional string StatusMessage = 3;
}
-
-message TEvInvalidateStoragePools {
-}
-
-message TEvRequestTabletIdSequence {
- optional TTabletOwner Owner = 1;
- optional uint64 Size = 2;
-}
-
-message TEvResponseTabletIdSequence {
- optional TTabletOwner Owner = 1;
- optional uint64 BeginId = 2;
- optional uint64 EndId = 3;
-}
-
-message TEvSeizeTablets {
- optional fixed64 NewOwnerID = 1;
- optional NKikimrSubDomains.TDomainKey FilterDomain = 2;
- optional uint32 MaxTabletsToSeize = 3 [default = 1];
- optional bool WaitForTabletsToRise = 4 [default = true];
-}
-
-message TTabletChannelGenInfo {
- optional uint64 Generation = 1;
- optional uint64 Group = 2;
- optional uint64 Version = 3;
- optional uint64 Timestamp = 4;
-}
-
-message TTabletChannelInfo {
- optional string StoragePool = 1;
- optional NKikimrStoragePool.TChannelBind Binding = 2;
- repeated TTabletChannelGenInfo History = 3;
- optional bool NeedNewGroup = 4;
-}
-
-message TTabletInfo {
- optional fixed64 TabletID = 1;
- optional NKikimrTabletBase.TTabletTypes.EType TabletType = 2;
- optional ETabletVolatileState VolatileState = 3;
- optional uint32 NodeID = 4;
- repeated uint64 ExecutorCounters = 5;
- repeated uint64 ApplicationCounters = 6;
- optional TTabletOwner TabletOwner = 7;
+
+message TEvInvalidateStoragePools {
+}
+
+message TEvRequestTabletIdSequence {
+ optional TTabletOwner Owner = 1;
+ optional uint64 Size = 2;
+}
+
+message TEvResponseTabletIdSequence {
+ optional TTabletOwner Owner = 1;
+ optional uint64 BeginId = 2;
+ optional uint64 EndId = 3;
+}
+
+message TEvSeizeTablets {
+ optional fixed64 NewOwnerID = 1;
+ optional NKikimrSubDomains.TDomainKey FilterDomain = 2;
+ optional uint32 MaxTabletsToSeize = 3 [default = 1];
+ optional bool WaitForTabletsToRise = 4 [default = true];
+}
+
+message TTabletChannelGenInfo {
+ optional uint64 Generation = 1;
+ optional uint64 Group = 2;
+ optional uint64 Version = 3;
+ optional uint64 Timestamp = 4;
+}
+
+message TTabletChannelInfo {
+ optional string StoragePool = 1;
+ optional NKikimrStoragePool.TChannelBind Binding = 2;
+ repeated TTabletChannelGenInfo History = 3;
+ optional bool NeedNewGroup = 4;
+}
+
+message TTabletInfo {
+ optional fixed64 TabletID = 1;
+ optional NKikimrTabletBase.TTabletTypes.EType TabletType = 2;
+ optional ETabletVolatileState VolatileState = 3;
+ optional uint32 NodeID = 4;
+ repeated uint64 ExecutorCounters = 5;
+ repeated uint64 ApplicationCounters = 6;
+ optional TTabletOwner TabletOwner = 7;
optional uint32 FollowerID = 8;
- optional uint32 State = 9; // THive::ETabletState
- optional NKikimrTabletBase.TMetrics Metrics = 10;
- optional uint32 Generation = 11;
- optional ETabletBootMode TabletBootMode = 12;
- optional NKikimrSubDomains.TDomainKey ObjectDomain = 13;
- optional uint64 ObjectId = 14;
- repeated NKikimrSubDomains.TDomainKey AllowedDomains = 15;
+ optional uint32 State = 9; // THive::ETabletState
+ optional NKikimrTabletBase.TMetrics Metrics = 10;
+ optional uint32 Generation = 11;
+ optional ETabletBootMode TabletBootMode = 12;
+ optional NKikimrSubDomains.TDomainKey ObjectDomain = 13;
+ optional uint64 ObjectId = 14;
+ repeated NKikimrSubDomains.TDomainKey AllowedDomains = 15;
repeated TFollowerGroup FollowerGroups = 16;
- repeated TTabletChannelInfo TabletChannels = 17;
- optional NActorsProto.TActorId LockedToActor = 18;
- optional uint64 LockedReconnectTimeout = 19;
- optional uint64 TabletStorageVersion = 20;
- optional NKikimrTabletBase.TMetrics ResourceUsage = 21;
- optional uint32 RestartsPerPeriod = 22;
- optional uint64 LastAliveTimestamp = 23;
-}
-
-message TEvSeizeTabletsReply {
- repeated TTabletInfo Tablets = 1;
-}
-
-message TEvReleaseTablets {
- optional fixed64 NewOwnerID = 1;
- repeated fixed64 TabletIDs = 2;
-}
-
-message TEvReleaseTabletsReply {
- repeated fixed64 TabletIDs = 1;
-}
-
-message TEvConfigureHive {
- optional NKikimrSubDomains.TDomainKey Domain = 1;
-}
-
-message TEvInitMigration {
- optional TEvSeizeTablets MigrationFilter = 1;
-}
-
-message TEvInitMigrationReply {
- optional NKikimrProto.EReplyStatus Status = 1;
-}
-
-message TEvQueryMigration {
-}
-
-message TEvQueryMigrationReply {
- optional EMigrationState MigrationState = 1;
- optional int32 MigrationProgress = 2;
-}
-
-message TTabletStatistics {
- repeated uint64 RestartTimestamp = 1;
- optional uint64 LastAliveTimestamp = 2;
-}
-
-message TNodeStatistics {
- repeated uint64 RestartTimestamp = 1;
- optional uint64 LastAliveTimestamp = 2;
-}
+ repeated TTabletChannelInfo TabletChannels = 17;
+ optional NActorsProto.TActorId LockedToActor = 18;
+ optional uint64 LockedReconnectTimeout = 19;
+ optional uint64 TabletStorageVersion = 20;
+ optional NKikimrTabletBase.TMetrics ResourceUsage = 21;
+ optional uint32 RestartsPerPeriod = 22;
+ optional uint64 LastAliveTimestamp = 23;
+}
+
+message TEvSeizeTabletsReply {
+ repeated TTabletInfo Tablets = 1;
+}
+
+message TEvReleaseTablets {
+ optional fixed64 NewOwnerID = 1;
+ repeated fixed64 TabletIDs = 2;
+}
+
+message TEvReleaseTabletsReply {
+ repeated fixed64 TabletIDs = 1;
+}
+
+message TEvConfigureHive {
+ optional NKikimrSubDomains.TDomainKey Domain = 1;
+}
+
+message TEvInitMigration {
+ optional TEvSeizeTablets MigrationFilter = 1;
+}
+
+message TEvInitMigrationReply {
+ optional NKikimrProto.EReplyStatus Status = 1;
+}
+
+message TEvQueryMigration {
+}
+
+message TEvQueryMigrationReply {
+ optional EMigrationState MigrationState = 1;
+ optional int32 MigrationProgress = 2;
+}
+
+message TTabletStatistics {
+ repeated uint64 RestartTimestamp = 1;
+ optional uint64 LastAliveTimestamp = 2;
+}
+
+message TNodeStatistics {
+ repeated uint64 RestartTimestamp = 1;
+ optional uint64 LastAliveTimestamp = 2;
+}
diff --git a/ydb/core/protos/local.proto b/ydb/core/protos/local.proto
index ff2500575df..a385a3cf3e1 100644
--- a/ydb/core/protos/local.proto
+++ b/ydb/core/protos/local.proto
@@ -8,16 +8,16 @@ import "ydb/core/protos/follower_group.proto";
package NKikimrLocal;
option java_package = "ru.yandex.kikimr.proto";
-message TTabletAvailability {
- optional NKikimrTabletBase.TTabletTypes.EType Type = 1;
- optional uint64 MaxCount = 2;
-}
-
+message TTabletAvailability {
+ optional NKikimrTabletBase.TTabletTypes.EType Type = 1;
+ optional uint64 MaxCount = 2;
+}
+
message TEvRegisterNode {
optional fixed64 HiveId = 1;
repeated NKikimrSubDomains.TDomainKey ServicedDomains = 2;
optional NActorsInterconnect.TNodeLocation SystemLocation = 3;
- repeated TTabletAvailability TabletAvailability = 4;
+ repeated TTabletAvailability TabletAvailability = 4;
}
message TEvRegisterNodeResult {
@@ -45,19 +45,19 @@ message TEvDeadTabletAck {
message TEvStatus {
optional uint32 Status = 1;
- optional uint64 InbootTablets = 2;
- optional uint64 OnlineTablets = 3;
- optional uint64 DeadTablets = 4;
- optional uint64 AvailableWeight = 5;
- optional NKikimrTabletBase.TMetrics ResourceMaximum = 8;
- optional uint64 StartTime = 7;
+ optional uint64 InbootTablets = 2;
+ optional uint64 OnlineTablets = 3;
+ optional uint64 DeadTablets = 4;
+ optional uint64 AvailableWeight = 5;
+ optional NKikimrTabletBase.TMetrics ResourceMaximum = 8;
+ optional uint64 StartTime = 7;
}
-enum EBootMode {
+enum EBootMode {
BOOT_MODE_LEADER = 0;
BOOT_MODE_FOLLOWER = 1;
-}
-
+}
+
message TEvBootTablet {
optional NKikimrTabletBase.TTabletStorageInfo Info = 1;
optional uint32 SuggestedGeneration = 2;
@@ -76,11 +76,11 @@ message TEvTabletStatus {
optional fixed64 TabletID = 2;
optional uint32 Generation = 3;
optional uint32 FollowerId = 4;
- optional uint32 Reason = 5 [default = 34]; // ReasonError
+ optional uint32 Reason = 5 [default = 34]; // ReasonError
}
message TEvEnumerateTablets {
- optional NKikimrTabletBase.TTabletTypes.EType TabletType = 1;
+ optional NKikimrTabletBase.TTabletTypes.EType TabletType = 1;
}
message TEvEnumerateTabletsResult {
@@ -88,32 +88,32 @@ message TEvEnumerateTabletsResult {
message TTabletInfo {
optional uint64 TabletId = 1;
- optional NKikimrTabletBase.TTabletTypes.EType TabletType = 2;
+ optional NKikimrTabletBase.TTabletTypes.EType TabletType = 2;
optional EBootMode BootMode = 3 [default = BOOT_MODE_LEADER];
optional uint32 FollowerId = 4;
}
repeated TTabletInfo TabletInfo = 2;
}
-
-message TEvSyncTablets {
- message TTabletInfo {
- optional uint64 TabletId = 1;
- optional uint32 Generation = 2;
- optional EBootMode BootMode = 3;
+
+message TEvSyncTablets {
+ message TTabletInfo {
+ optional uint64 TabletId = 1;
+ optional uint32 Generation = 2;
+ optional EBootMode BootMode = 3;
optional uint32 FollowerId = 4;
- }
-
- repeated TTabletInfo InbootTablets = 1;
- repeated TTabletInfo OnlineTablets = 2;
-}
-
-message TEvTabletMetricsAck {
- repeated fixed64 TabletId = 1;
+ }
+
+ repeated TTabletInfo InbootTablets = 1;
+ repeated TTabletInfo OnlineTablets = 2;
+}
+
+message TEvTabletMetricsAck {
+ repeated fixed64 TabletId = 1;
repeated uint32 FollowerId = 2;
-}
-
-message TEvReconnect {
- optional fixed64 HiveId = 1;
- optional uint32 HiveGeneration = 2;
-}
+}
+
+message TEvReconnect {
+ optional fixed64 HiveId = 1;
+ optional uint32 HiveGeneration = 2;
+}
diff --git a/ydb/core/protos/metrics.proto b/ydb/core/protos/metrics.proto
index b0518c20eb0..017014b8118 100644
--- a/ydb/core/protos/metrics.proto
+++ b/ydb/core/protos/metrics.proto
@@ -1,6 +1,6 @@
-package NKikimrMetricsProto;
-
-message TMaximumValueUI64 {
- optional uint64 LastBucketStartTime = 1;
- repeated uint64 Values = 2;
-}
+package NKikimrMetricsProto;
+
+message TMaximumValueUI64 {
+ optional uint64 LastBucketStartTime = 1;
+ repeated uint64 Values = 2;
+}
diff --git a/ydb/core/protos/msgbus.proto b/ydb/core/protos/msgbus.proto
index c9fd7d9bb6d..df7cda59800 100644
--- a/ydb/core/protos/msgbus.proto
+++ b/ydb/core/protos/msgbus.proto
@@ -55,20 +55,20 @@ message TRequest {
optional NKikimrTxUserProxy.TTransaction Transaction = 1;
optional uint64 ProxyFlags = 2;
optional uint64 ExecTimeoutPeriod = 4;
- optional string SecurityToken = 5;
+ optional string SecurityToken = 5;
}
-message TFlatTxId {
- optional fixed64 TxId = 1;
- optional fixed64 SchemeShardTabletId = 2;
+message TFlatTxId {
+ optional fixed64 TxId = 1;
+ optional fixed64 SchemeShardTabletId = 2;
optional uint64 PathId = 3;
-};
+};
+
+message TResolveNodeResponse {
+ optional string Host = 1;
+ optional uint32 NodeId = 2;
+};
-message TResolveNodeResponse {
- optional string Host = 1;
- optional uint32 NodeId = 2;
-};
-
// must start from TResponseBase
message TResponse {
optional uint32 Status = 1 [
@@ -86,7 +86,7 @@ message TResponse {
]}
]; // EResponseStatus from ydb/core/client/base/msgbus.h
- optional string ErrorReason = 400; // When present contains human-readable error description (aka ProtobufError)
+ optional string ErrorReason = 400; // When present contains human-readable error description (aka ProtobufError)
optional fixed64 TxId = 2;
optional fixed64 Step = 3;
@@ -176,57 +176,57 @@ message TResponse {
optional int32 SchemeStatus = 300; // for enum definition see flat_tx_scheme.proto - enum EStatus
optional uint32 SchemeTagId = 301;
optional bytes SchemePrefix = 302;
-
- // TTabletStateRequest
- repeated NKikimrWhiteboard.TTabletStateInfo TabletStateInfo = 500;
-
+
+ // TTabletStateRequest
+ repeated NKikimrWhiteboard.TTabletStateInfo TabletStateInfo = 500;
+
// TSchemeDescribe
optional NKikimrSchemeOp.TPathDescription PathDescription = 600;
optional string Path = 601;
-
+
// TSchemeOperation
- optional TFlatTxId FlatTxId = 700;
-
- // TPersQueueRequest
+ optional TFlatTxId FlatTxId = 700;
+
+ // TPersQueueRequest
optional NPersQueue.NErrorCode.EErrorCode ErrorCode = 800; // TODO: rename to something more PQ-specific
- optional TPersQueuePartitionResponse PartitionResponse = 801;
- optional TPersQueueMetaResponse MetaResponse = 802;
+ optional TPersQueuePartitionResponse PartitionResponse = 801;
+ optional TPersQueueMetaResponse MetaResponse = 802;
optional TPersQueueFetchResponse FetchResponse = 803;
-
- // TKeyValueRequest
- optional uint64 Cookie = 900;
- repeated TKeyValueResponse.TDeleteRangeResult DeleteRangeResult = 901;
- optional TKeyValueResponse.TIncrementGenerationResult IncrementGenerationResult = 902;
- repeated TKeyValueResponse.TReadResult ReadResult = 903;
- repeated TKeyValueResponse.TReadRangeResult ReadRangeResult = 904;
- repeated TKeyValueResponse.TWriteResult WriteResult = 905;
- repeated TKeyValueResponse.TRenameResult RenameResult = 906;
- repeated TKeyValueResponse.TCopyRangeResult CopyRangeResult = 907;
- repeated TKeyValueResponse.TConcatResult ConcatResult = 908;
+
+ // TKeyValueRequest
+ optional uint64 Cookie = 900;
+ repeated TKeyValueResponse.TDeleteRangeResult DeleteRangeResult = 901;
+ optional TKeyValueResponse.TIncrementGenerationResult IncrementGenerationResult = 902;
+ repeated TKeyValueResponse.TReadResult ReadResult = 903;
+ repeated TKeyValueResponse.TReadRangeResult ReadRangeResult = 904;
+ repeated TKeyValueResponse.TWriteResult WriteResult = 905;
+ repeated TKeyValueResponse.TRenameResult RenameResult = 906;
+ repeated TKeyValueResponse.TCopyRangeResult CopyRangeResult = 907;
+ repeated TKeyValueResponse.TConcatResult ConcatResult = 908;
repeated TKeyValueResponse.TGetStatusResult GetStatusResult = 909;
optional TKeyValueResponse.TTrimLeakedBlobsResult TrimLeakedBlobsResult = 910;
optional TKeyValueResponse.TSetExecutorFastLogPolicyResult SetExecutorFastLogPolicyResult = 911;
-
- // THiveCreateTablet
- message TCreateTabletResult {
- // Should be NKikimrProto::OK or NKikimrProto::ALREADY in case of success or repeated call
+
+ // THiveCreateTablet
+ message TCreateTabletResult {
+ // Should be NKikimrProto::OK or NKikimrProto::ALREADY in case of success or repeated call
optional uint32 Status = 1; // EReplyStatus from ydb/core/protos/base.proto
- optional uint64 TabletId = 2;
- }
- message TLookupTabletResult {
- // Should be NKikimrProto::OK or NKikimrProto::NODATA in case of non existing tablet
+ optional uint64 TabletId = 2;
+ }
+ message TLookupTabletResult {
+ // Should be NKikimrProto::OK or NKikimrProto::NODATA in case of non existing tablet
optional uint32 Status = 1; // EReplyStatus from ydb/core/protos/base.proto
- optional uint64 TabletId = 2;
- }
- repeated TCreateTabletResult CreateTabletResult = 1000;
- repeated TLookupTabletResult LookupTabletResult = 1002;
-
- // TLocalEnumerateTablets
- message TTabletInfo {
- optional uint64 TabletId = 1;
- optional NKikimrTabletBase.TTabletTypes.EType TabletType = 2;
- }
- repeated TTabletInfo TabletInfo = 1001;
+ optional uint64 TabletId = 2;
+ }
+ repeated TCreateTabletResult CreateTabletResult = 1000;
+ repeated TLookupTabletResult LookupTabletResult = 1002;
+
+ // TLocalEnumerateTablets
+ message TTabletInfo {
+ optional uint64 TabletId = 1;
+ optional NKikimrTabletBase.TTabletTypes.EType TabletType = 2;
+ }
+ repeated TTabletInfo TabletInfo = 1001;
// TTabletLocalSchemeTx
optional NTabletFlatScheme.TSchemeChanges LocalDbScheme = 1010;
@@ -236,16 +236,16 @@ message TResponse {
// TBlobStorageConfigRequest
optional NKikimrBlobStorage.TConfigResponse BlobStorageConfigResponse = 1030;
-
- optional TResolveNodeResponse ResolveNodeResponse = 1040;
+
+ optional TResolveNodeResponse ResolveNodeResponse = 1040;
// TChooseProxyRequest
optional string ProxyName = 1050;
optional uint64 ProxyCookie = 1051;
- // TWhoAmI
- optional string UserName = 1100;
- repeated string Groups = 1101;
+ // TWhoAmI
+ optional string UserName = 1100;
+ repeated string Groups = 1101;
}
message TFakeConfigDummy {
@@ -275,8 +275,8 @@ message TLocalMKQL {
optional NKikimrTxUserProxy.TMiniKQLTransaction Program = 2;
optional bool ConnectToFollower = 3;
- optional string SecurityToken = 5;
-
+ optional string SecurityToken = 5;
+
optional bool WithRetry = 10;
optional uint64 Timeout = 11;
}
@@ -286,7 +286,7 @@ message TLocalSchemeTx {
optional bool ConnectToFollower = 2;
optional NTabletFlatScheme.TSchemeChanges SchemeChanges = 3;
optional bool DryRun = 4;
- optional string SecurityToken = 5;
+ optional string SecurityToken = 5;
optional bool WithRetry = 10;
optional uint64 Timeout = 11;
@@ -304,8 +304,8 @@ message TSchemeInitRoot {
optional uint32 TagId = 2;
optional bytes TagName = 3;
optional NKikimrTxScheme.TConfig GlobalConfig = 4;
- optional string SecurityToken = 5;
- repeated NKikimrStoragePool.TStoragePool StoragePools = 6;
+ optional string SecurityToken = 5;
+ repeated NKikimrStoragePool.TStoragePool StoragePools = 6;
}
message TBSAdm {
@@ -322,7 +322,7 @@ message TBSAdm {
optional uint32 Domain = 1;
optional TGroupReconfigureWipe GroupReconfigureWipe = 6;
- optional string SecurityToken = 7;
+ optional string SecurityToken = 7;
}
message THiveCreateTablet {
@@ -331,18 +331,18 @@ message THiveCreateTablet {
optional uint64 OwnerIdx = 2; // mandatory, per-sender unique request id for duplicate request detection
optional NKikimrTabletBase.TTabletTypes.EType TabletType = 3; // mandatory, tablet type, see ydb/core/base/tablet_types.h
optional uint32 ChannelsProfile = 4; // mandatory, channels profile index (use 0 for default profile)
- repeated uint32 AllowedNodeIDs = 5;
+ repeated uint32 AllowedNodeIDs = 5;
repeated NKikimrSubDomains.TDomainKey AllowedDomains = 6;
repeated NKikimrStoragePool.TChannelBind BindedChannels = 7;
}
- message TCmdLookupTablet {
- optional uint64 OwnerId = 1; // mandatory, senders TabletId (use 0 for human/external system)
- optional uint64 OwnerIdx = 2; // mandatory, per-sender unique request id for duplicate request detection
- }
-
+ message TCmdLookupTablet {
+ optional uint64 OwnerId = 1; // mandatory, senders TabletId (use 0 for human/external system)
+ optional uint64 OwnerIdx = 2; // mandatory, per-sender unique request id for duplicate request detection
+ }
+
repeated TCmdCreateTablet CmdCreateTablet = 1;
- repeated TCmdLookupTablet CmdLookupTablet = 3;
+ repeated TCmdLookupTablet CmdLookupTablet = 3;
optional uint32 DomainUid = 2; // mandatory, Domain unique id, in most cases 1
}
@@ -356,21 +356,21 @@ message THiveCreateTabletResult {
optional uint64 TabletId = 2;
}
- message TLookupTabletResult {
- // Should be NKikimrProto::OK or NKikimrProto::NODATA in case of non existing tablet
+ message TLookupTabletResult {
+ // Should be NKikimrProto::OK or NKikimrProto::NODATA in case of non existing tablet
optional uint32 Status = 1; // EReplyStatus from ydb/core/protos/base.proto
- optional uint64 TabletId = 2;
- }
-
+ optional uint64 TabletId = 2;
+ }
+
repeated TCreateTabletResult CreateTabletResult = 2;
- repeated TLookupTabletResult LookupTabletResult = 4;
+ repeated TLookupTabletResult LookupTabletResult = 4;
optional string ErrorReason = 3; // When present contains human-readable error description
}
message TLocalEnumerateTablets {
optional uint64 DomainUid = 1; // mandatory
optional uint32 NodeId = 2; // optional, msgbus proxy will contact it's own node if not set
- optional NKikimrTabletBase.TTabletTypes.EType TabletType = 3; // optional, local will enumerate all tablets if not set
+ optional NKikimrTabletBase.TTabletTypes.EType TabletType = 3; // optional, local will enumerate all tablets if not set
}
message TLocalEnumerateTabletsResult {
@@ -379,7 +379,7 @@ message TLocalEnumerateTabletsResult {
message TTabletInfo {
optional uint64 TabletId = 1;
- optional NKikimrTabletBase.TTabletTypes.EType TabletType = 2;
+ optional NKikimrTabletBase.TTabletTypes.EType TabletType = 2;
}
repeated TTabletInfo TabletInfo = 2;
@@ -400,66 +400,66 @@ message TTypeMetadataResponse {
optional bytes FunctionMetadata = 4;
}
-message TMessageBusTraceRequest {
- enum ECommand {
- START = 0;
- STOP = 1;
- };
- optional ECommand Command = 1;
- optional bytes Path = 2;
-};
-
-message TMessageBusTraceStatus {
- optional bool TraceActive = 1;
- optional bytes Path = 2;
-};
-
-message TTabletKillRequest {
- optional uint64 TabletID = 1;
-};
-
-message TTabletStateRequest {
- optional NKikimrTabletBase.TTabletTypes.EType TabletType = 1;
- optional bool Alive = 2;
- repeated fixed64 TabletIDs = 3;
-};
-
-message TFlatTxPollOptions {
- optional uint32 Timeout = 1 [default = 1000]; // ms
-};
-
+message TMessageBusTraceRequest {
+ enum ECommand {
+ START = 0;
+ STOP = 1;
+ };
+ optional ECommand Command = 1;
+ optional bytes Path = 2;
+};
+
+message TMessageBusTraceStatus {
+ optional bool TraceActive = 1;
+ optional bytes Path = 2;
+};
+
+message TTabletKillRequest {
+ optional uint64 TabletID = 1;
+};
+
+message TTabletStateRequest {
+ optional NKikimrTabletBase.TTabletTypes.EType TabletType = 1;
+ optional bool Alive = 2;
+ repeated fixed64 TabletIDs = 3;
+};
+
+message TFlatTxPollOptions {
+ optional uint32 Timeout = 1 [default = 1000]; // ms
+};
+
message TSchemeOperation {
- optional NKikimrTxUserProxy.TTransaction Transaction = 1;
- optional TFlatTxPollOptions PollOptions = 10;
- optional string SecurityToken = 5;
-};
-
+ optional NKikimrTxUserProxy.TTransaction Transaction = 1;
+ optional TFlatTxPollOptions PollOptions = 10;
+ optional string SecurityToken = 5;
+};
+
message TSchemeDescribe {
- optional string Path = 1;
- optional uint64 PathId = 2;
- optional uint64 SchemeshardId = 3;
- optional string SecurityToken = 5;
+ optional string Path = 1;
+ optional uint64 PathId = 2;
+ optional uint64 SchemeshardId = 3;
+ optional string SecurityToken = 5;
optional NKikimrSchemeOp.TDescribeOptions Options = 6;
-};
-
-message TFlatDescribeResponse {
+};
+
+message TFlatDescribeResponse {
option deprecated = true;
- optional uint32 Status = 1;
+ optional uint32 Status = 1;
optional string Path = 9;
optional NKikimrSchemeOp.TPathDescription PathDescription = 2;
- optional string ErrorReason = 3; // When present contains human-readable error description
+ optional string ErrorReason = 3; // When present contains human-readable error description
optional int32 SchemeStatus = 4;
optional NKikimrIssues.TStatusIds.EStatusCode StatusCode = 7;
repeated Ydb.Issue.IssueMessage Issues = 8;
-};
-
+};
+
message TSchemeOperationStatus {
- optional TFlatTxId FlatTxId = 1;
- optional TFlatTxPollOptions PollOptions = 10;
-};
+ optional TFlatTxId FlatTxId = 1;
+ optional TFlatTxPollOptions PollOptions = 10;
+};
message TBsTestLoadRequest {
repeated uint32 NodeId = 1;
@@ -474,7 +474,7 @@ message TBsTestLoadResponse {
};
repeated TItem Items = 1;
};
-
+
message TBsGetRequest {
optional uint32 GroupId = 1;
oneof Query {
@@ -488,15 +488,15 @@ message TBsGetResponse {
optional string ErrorDescription = 3;
};
-message TJsonSettings {
- optional bool UI64AsString = 1 [default = false];
-};
-
-message TJSON {
- optional string JSON = 1;
- optional string SecurityToken = 2;
- optional TJsonSettings JsonSettings = 3;
-};
+message TJsonSettings {
+ optional bool UI64AsString = 1 [default = false];
+};
+
+message TJSON {
+ optional string JSON = 1;
+ optional string SecurityToken = 2;
+ optional TJsonSettings JsonSettings = 3;
+};
message TChooseProxyRequest {
optional uint32 DataCenterNum = 1;
@@ -504,32 +504,32 @@ message TChooseProxyRequest {
optional bool PreferLocalProxy = 2 [default = false];
}
-message TWhoAmI {
- optional bool ReturnGroups = 1;
- optional string SecurityToken = 5;
-}
-
+message TWhoAmI {
+ optional bool ReturnGroups = 1;
+ optional string SecurityToken = 5;
+}
+
message TBlobStorageConfigRequest {
optional uint32 Domain = 1;
optional NKikimrBlobStorage.TConfigRequest Request = 2;
optional string SecurityToken = 3;
}
-
-message TDrainNodeRequest {
- optional uint32 NodeID = 1;
- optional string SecurityToken = 5;
-};
-
-message TFillNodeRequest {
- optional uint32 NodeID = 1;
- optional string SecurityToken = 5;
-};
-
-message TResolveNodeRequest {
- optional string Host = 1;
- optional uint32 NodeId = 2;
- optional bool ResolveLocalNode = 3; // for compatibility of resolving local '.' node
-};
+
+message TDrainNodeRequest {
+ optional uint32 NodeID = 1;
+ optional string SecurityToken = 5;
+};
+
+message TFillNodeRequest {
+ optional uint32 NodeID = 1;
+ optional string SecurityToken = 5;
+};
+
+message TResolveNodeRequest {
+ optional string Host = 1;
+ optional uint32 NodeId = 2;
+ optional bool ResolveLocalNode = 3; // for compatibility of resolving local '.' node
+};
message TNodeRegistrationRequest {
optional string Host = 1;
diff --git a/ydb/core/protos/msgbus_pq.proto b/ydb/core/protos/msgbus_pq.proto
index cb24ed229be..849b292383a 100644
--- a/ydb/core/protos/msgbus_pq.proto
+++ b/ydb/core/protos/msgbus_pq.proto
@@ -220,7 +220,7 @@ message TPersQueueRequest {
optional TPersQueueFetchRequest FetchRequest = 3;
//only one from data, meta or fetch request must be set.
- optional string SecurityToken = 5;
+ optional string SecurityToken = 5;
optional string Ticket = 6; //if set, check for acl
optional string RequestId = 100; //for logging
@@ -300,7 +300,7 @@ message TPersQueueMetaResponse {
optional string Timestamp = 12;
optional uint64 ClientReadOffset = 13;
optional uint64 ReadTimeLag = 14;
- optional uint32 TabletNodeId = 15;
+ optional uint32 TabletNodeId = 15;
}
message TTopicResult {
diff --git a/ydb/core/protos/node_whiteboard.proto b/ydb/core/protos/node_whiteboard.proto
index 8c73ceb7326..b96713ca298 100644
--- a/ydb/core/protos/node_whiteboard.proto
+++ b/ydb/core/protos/node_whiteboard.proto
@@ -2,17 +2,17 @@ import "library/cpp/actors/protos/interconnect.proto";
import "ydb/core/protos/tablet.proto";
import "ydb/core/protos/subdomains.proto";
import "ydb/core/protos/blobstorage_disk.proto";
-import "google/protobuf/descriptor.proto";
+import "google/protobuf/descriptor.proto";
import "ydb/core/protos/tracing.proto";
-
-package NKikimrWhiteboard;
-option java_package = "ru.yandex.kikimr.proto";
-
-extend google.protobuf.FieldOptions {
+
+package NKikimrWhiteboard;
+option java_package = "ru.yandex.kikimr.proto";
+
+extend google.protobuf.FieldOptions {
optional uint64 InsignificantChangeAmount = 70553;
optional uint32 InsignificantChangePercent = 70554;
-}
-
+}
+
enum EFlag {
Grey = 0;
Green = 1;
@@ -26,107 +26,107 @@ message TCustomTabletAttribute {
optional string Value = 2;
}
-message TTabletStateInfo {
- enum ETabletState {
- Created = 0;
- ResolveStateStorage = 1;
- Candidate = 2;
- BlockBlobStorage = 3;
- RebuildGraph = 4;
- WriteZeroEntry = 5;
- Restored = 6;
- Discover = 7;
- Lock = 8;
- Dead = 9;
- Active = 10;
+message TTabletStateInfo {
+ enum ETabletState {
+ Created = 0;
+ ResolveStateStorage = 1;
+ Candidate = 2;
+ BlockBlobStorage = 3;
+ RebuildGraph = 4;
+ WriteZeroEntry = 5;
+ Restored = 6;
+ Discover = 7;
+ Lock = 8;
+ Dead = 9;
+ Active = 10;
ResolveLeader = 11;
- Deleted = 12;
- Stopped = 13;
- Reserved14 = 14;
- Reserved15 = 15;
- Reserved16 = 16;
- }
-
- optional uint64 TabletId = 1;
- optional uint64 CreateTime = 2;
- optional uint64 ChangeTime = 3;
- optional ETabletState State = 4;
+ Deleted = 12;
+ Stopped = 13;
+ Reserved14 = 14;
+ Reserved15 = 15;
+ Reserved16 = 16;
+ }
+
+ optional uint64 TabletId = 1;
+ optional uint64 CreateTime = 2;
+ optional uint64 ChangeTime = 3;
+ optional ETabletState State = 4;
optional uint32 UserState = 5; // implementation-dependent
optional uint32 Generation = 6;
- optional NKikimrTabletBase.TTabletTypes.EType Type = 7;
+ optional NKikimrTabletBase.TTabletTypes.EType Type = 7;
optional string Host = 8;
repeated uint32 ChannelGroupIDs = 9; // BS Group per channel
repeated TCustomTabletAttribute Attributes = 10;
- optional uint32 NodeId = 11; // filled during merge
+ optional uint32 NodeId = 11; // filled during merge
optional bool Leader = 12; // leader or follower
- optional uint32 Count = 13; // filled during group count
+ optional uint32 Count = 13; // filled during group count
optional uint32 FollowerId = 14;
- optional EFlag Overall = 15; // filled during merge
- optional NKikimrSubDomains.TDomainKey TenantId = 16;
- optional fixed64 HiveId = 17;
-}
-
-message TEvTabletStateRequest {
- optional uint64 ChangedSince = 1;
-}
-
-message TEvTabletStateResponse {
- repeated TTabletStateInfo TabletStateInfo = 1;
- optional uint64 ResponseTime = 2;
- optional uint32 ResponseDuration = 3; // filled during collect
-}
-
-message TNodeStateInfo {
- optional string PeerName = 1;
- optional bool Connected = 2;
- optional uint32 NodeId = 3; // filled during merge
- optional uint64 ChangeTime = 4;
- optional uint32 OutputQueueSize = 5 [(InsignificantChangeAmount) = 1048576]; // 1Mb
- optional EFlag ConnectStatus = 6;
- optional uint32 Count = 13; // filled during group count
-}
-
-message TEvNodeStateRequest {
- optional uint64 ChangedSince = 1;
-}
-
-message TEvNodeStateResponse {
- repeated TNodeStateInfo NodeStateInfo = 1;
- optional uint64 ResponseTime = 2;
- optional uint32 ResponseDuration = 3; // filled during collect
-}
-
-message TPDiskStateInfo {
- optional uint32 PDiskId = 1;
- optional uint64 CreateTime = 2;
- optional uint64 ChangeTime = 3;
- optional string Path = 4;
- optional uint64 Guid = 5;
- optional uint64 Category = 6;
- optional uint64 AvailableSize = 7 [(InsignificantChangeAmount) = 104857600]; // 100Mb
- optional uint64 TotalSize = 8;
+ optional EFlag Overall = 15; // filled during merge
+ optional NKikimrSubDomains.TDomainKey TenantId = 16;
+ optional fixed64 HiveId = 17;
+}
+
+message TEvTabletStateRequest {
+ optional uint64 ChangedSince = 1;
+}
+
+message TEvTabletStateResponse {
+ repeated TTabletStateInfo TabletStateInfo = 1;
+ optional uint64 ResponseTime = 2;
+ optional uint32 ResponseDuration = 3; // filled during collect
+}
+
+message TNodeStateInfo {
+ optional string PeerName = 1;
+ optional bool Connected = 2;
+ optional uint32 NodeId = 3; // filled during merge
+ optional uint64 ChangeTime = 4;
+ optional uint32 OutputQueueSize = 5 [(InsignificantChangeAmount) = 1048576]; // 1Mb
+ optional EFlag ConnectStatus = 6;
+ optional uint32 Count = 13; // filled during group count
+}
+
+message TEvNodeStateRequest {
+ optional uint64 ChangedSince = 1;
+}
+
+message TEvNodeStateResponse {
+ repeated TNodeStateInfo NodeStateInfo = 1;
+ optional uint64 ResponseTime = 2;
+ optional uint32 ResponseDuration = 3; // filled during collect
+}
+
+message TPDiskStateInfo {
+ optional uint32 PDiskId = 1;
+ optional uint64 CreateTime = 2;
+ optional uint64 ChangeTime = 3;
+ optional string Path = 4;
+ optional uint64 Guid = 5;
+ optional uint64 Category = 6;
+ optional uint64 AvailableSize = 7 [(InsignificantChangeAmount) = 104857600]; // 100Mb
+ optional uint64 TotalSize = 8;
optional NKikimrBlobStorage.TPDiskState.E State = 9;
- optional uint32 NodeId = 10; // filled during merge
- optional uint32 Count = 13; // filled during group count
+ optional uint32 NodeId = 10; // filled during merge
+ optional uint32 Count = 13; // filled during group count
optional EFlag Device = 14;
optional EFlag Realtime = 15;
- // State as flag - to be filled
- optional EFlag StateFlag = 16;
- // overall state - to be filled
- optional EFlag Overall = 17;
+ // State as flag - to be filled
+ optional EFlag StateFlag = 16;
+ // overall state - to be filled
+ optional EFlag Overall = 17;
optional string SerialNumber = 18;
-}
-
-message TEvPDiskStateRequest {
- optional uint64 ChangedSince = 1;
-}
-
-message TEvPDiskStateResponse {
- repeated TPDiskStateInfo PDiskStateInfo = 1;
- optional uint64 ResponseTime = 2;
- optional uint32 ResponseDuration = 3; // filled during collect
-}
-
+}
+
+message TEvPDiskStateRequest {
+ optional uint64 ChangedSince = 1;
+}
+
+message TEvPDiskStateResponse {
+ repeated TPDiskStateInfo PDiskStateInfo = 1;
+ optional uint64 ResponseTime = 2;
+ optional uint32 ResponseDuration = 3; // filled during collect
+}
+
enum EVDiskState {
Initial = 1;
LocalRecoveryError = 2;
@@ -143,7 +143,7 @@ message TVDiskSatisfactionRank {
// Rank in percents; 0-100% is good; >100% is bad.
// Formula for rank calculation is the following:
// Rank = actual_value / max_allowed_value * 100
- optional uint32 RankPercent = 1 [(InsignificantChangeAmount) = 3]; // 3%
+ optional uint32 RankPercent = 1 [(InsignificantChangeAmount) = 3]; // 3%
// Flag is the Rank transformed to something simple
// to understand: Green, Yellow or Red
@@ -154,20 +154,20 @@ message TVDiskSatisfactionRank {
optional TRank LevelRank = 2;
}
-message TVDiskStateInfo {
+message TVDiskStateInfo {
optional NKikimrBlobStorage.TVDiskID VDiskId = 1;
- optional uint64 CreateTime = 2;
- optional uint64 ChangeTime = 3;
- optional uint32 PDiskId = 4;
- optional uint32 VDiskSlotId = 5;
- optional uint64 Guid = 6;
- optional uint64 Kind = 7;
- optional uint32 NodeId = 9; // filled during merge
- optional uint32 Count = 17; // filled during group count
-
- // overall state - to be filled
- optional EFlag Overall = 10;
-
+ optional uint64 CreateTime = 2;
+ optional uint64 ChangeTime = 3;
+ optional uint32 PDiskId = 4;
+ optional uint32 VDiskSlotId = 5;
+ optional uint64 Guid = 6;
+ optional uint64 Kind = 7;
+ optional uint32 NodeId = 9; // filled during merge
+ optional uint32 Count = 17; // filled during group count
+
+ // overall state - to be filled
+ optional EFlag Overall = 10;
+
// Current state of VDisk
optional EVDiskState VDiskState = 11;
// Disk space flags
@@ -182,7 +182,7 @@ message TVDiskStateInfo {
optional bool UnreplicatedNonPhantoms = 21 [default = false];
// How many unsynced VDisks from current BlobStorage group we see
optional uint64 UnsyncedVDisks = 15 [default = 0];
- // How much this VDisk have allocated on corresponding PDisk
+ // How much this VDisk have allocated on corresponding PDisk
optional uint64 AllocatedSize = 16 [(InsignificantChangeAmount) = 536870912]; // 512MiB
// How much space is available for VDisk corresponding to PDisk's hard space limits
optional uint64 AvailableSize = 28 [(InsignificantChangeAmount) = 536870912]; // 512MiB
@@ -193,7 +193,7 @@ message TVDiskStateInfo {
optional fixed64 InstanceGuid = 27; // VDisk actor instance guid
// VDisk (Skeleton) Front Queue Status
- optional EFlag FrontQueues = 18;
+ optional EFlag FrontQueues = 18;
// VDisk storage pool label
optional string StoragePoolName = 19;
@@ -202,58 +202,58 @@ message TVDiskStateInfo {
optional uint64 ReadThroughput = 22;
// Write bytes per second to PDisk for TEvVPut blobs and replication bytes only
optional uint64 WriteThroughput = 23;
-}
-
-message TEvVDiskStateRequest {
- optional uint64 ChangedSince = 1;
-}
-
-message TEvVDiskStateResponse {
- repeated TVDiskStateInfo VDiskStateInfo = 1;
- optional uint64 ResponseTime = 2;
- optional uint32 ResponseDuration = 3; // filled during collect
-}
-
-message TBSGroupStateInfo {
- optional uint32 GroupID = 1;
- optional string ErasureSpecies = 2;
- repeated NKikimrBlobStorage.TVDiskID VDiskIds = 3;
- optional uint64 ChangeTime = 4;
- optional uint32 NodeId = 5; // filled during merge
- optional uint32 GroupGeneration = 6;
- optional EFlag Overall = 7;
- optional EFlag Latency = 8;
- optional uint32 Count = 13; // filled during group count
+}
+
+message TEvVDiskStateRequest {
+ optional uint64 ChangedSince = 1;
+}
+
+message TEvVDiskStateResponse {
+ repeated TVDiskStateInfo VDiskStateInfo = 1;
+ optional uint64 ResponseTime = 2;
+ optional uint32 ResponseDuration = 3; // filled during collect
+}
+
+message TBSGroupStateInfo {
+ optional uint32 GroupID = 1;
+ optional string ErasureSpecies = 2;
+ repeated NKikimrBlobStorage.TVDiskID VDiskIds = 3;
+ optional uint64 ChangeTime = 4;
+ optional uint32 NodeId = 5; // filled during merge
+ optional uint32 GroupGeneration = 6;
+ optional EFlag Overall = 7;
+ optional EFlag Latency = 8;
+ optional uint32 Count = 13; // filled during group count
optional string StoragePoolName = 14; // from BS_CONTROLLER
-}
-
-message TEvBSGroupStateRequest {
- optional uint64 ChangedSince = 1;
-}
-
-message TEvBSGroupStateResponse {
- repeated TBSGroupStateInfo BSGroupStateInfo = 1;
- optional uint64 ResponseTime = 2;
- optional uint32 ResponseDuration = 3; // filled during collect
-}
-
+}
+
+message TEvBSGroupStateRequest {
+ optional uint64 ChangedSince = 1;
+}
+
+message TEvBSGroupStateResponse {
+ repeated TBSGroupStateInfo BSGroupStateInfo = 1;
+ optional uint64 ResponseTime = 2;
+ optional uint32 ResponseDuration = 3; // filled during collect
+}
+
enum EConfigState {
Consistent = 0;
Outdated = 1;
}
-message TSystemStateInfo {
+message TSystemStateInfo {
message TPoolStats {
optional string Name = 1;
- optional double Usage = 2 [(InsignificantChangePercent) = 30];
- optional uint32 Threads = 3;
+ optional double Usage = 2 [(InsignificantChangePercent) = 30];
+ optional uint32 Threads = 3;
+ }
+
+ message TEndpoint {
+ optional string Name = 1;
+ optional string Address = 2;
}
- message TEndpoint {
- optional string Name = 1;
- optional string Address = 2;
- }
-
message TLegacyNodeLocation {
optional uint32 DataCenter = 1;
optional uint32 Room = 2;
@@ -261,46 +261,46 @@ message TSystemStateInfo {
optional uint32 Body = 4;
}
- optional uint64 StartTime = 1;
- optional uint64 ChangeTime = 2;
+ optional uint64 StartTime = 1;
+ optional uint64 ChangeTime = 2;
optional TLegacyNodeLocation SystemLocation = 3;
- repeated double LoadAverage = 4;
- optional uint32 NumberOfCpus = 5;
- optional EFlag SystemState = 6;
- optional EFlag MessageBusState = 7;
- optional EFlag GRpcState = 8;
- optional uint32 NodeId = 9; // filled during merge
- optional uint32 Count = 13; // filled during group count
- optional uint32 DataCenterId = 14;
- optional string DataCenterDescription = 15;
- optional string DataCenter = 16;
- optional uint32 RackId = 17;
- optional string Rack = 18;
- optional string Host = 19;
- optional string Version = 20;
+ repeated double LoadAverage = 4;
+ optional uint32 NumberOfCpus = 5;
+ optional EFlag SystemState = 6;
+ optional EFlag MessageBusState = 7;
+ optional EFlag GRpcState = 8;
+ optional uint32 NodeId = 9; // filled during merge
+ optional uint32 Count = 13; // filled during group count
+ optional uint32 DataCenterId = 14;
+ optional string DataCenterDescription = 15;
+ optional string DataCenter = 16;
+ optional uint32 RackId = 17;
+ optional string Rack = 18;
+ optional string Host = 19;
+ optional string Version = 20;
repeated TPoolStats PoolStats = 21;
- repeated TEndpoint Endpoints = 22;
- repeated string Roles = 23;
- repeated string Tenants = 24;
- optional string ClusterName = 25;
- optional uint64 MemoryUsed = 26;
- optional uint64 MemoryLimit = 27;
+ repeated TEndpoint Endpoints = 22;
+ repeated string Roles = 23;
+ repeated string Tenants = 24;
+ optional string ClusterName = 25;
+ optional uint64 MemoryUsed = 26;
+ optional uint64 MemoryLimit = 27;
optional EConfigState ConfigState = 28 [default = Consistent];
optional uint64 MemoryUsedInAlloc = 29;
optional double MaxDiskUsage = 30;
optional NActorsInterconnect.TNodeLocation Location = 31;
-}
-
-message TEvSystemStateRequest {
- optional uint64 ChangedSince = 1;
-}
-
-message TEvSystemStateResponse {
- repeated TSystemStateInfo SystemStateInfo = 1;
- optional uint64 ResponseTime = 2;
- optional uint32 ResponseDuration = 3; // filled during collect
-}
-
+}
+
+message TEvSystemStateRequest {
+ optional uint64 ChangedSince = 1;
+}
+
+message TEvSystemStateResponse {
+ repeated TSystemStateInfo SystemStateInfo = 1;
+ optional uint64 ResponseTime = 2;
+ optional uint32 ResponseDuration = 3; // filled during collect
+}
+
message TEvTabletLookupRequest {
}
diff --git a/ydb/core/protos/pqconfig.proto b/ydb/core/protos/pqconfig.proto
index 6fdfeb87af9..7c859274496 100644
--- a/ydb/core/protos/pqconfig.proto
+++ b/ydb/core/protos/pqconfig.proto
@@ -654,7 +654,7 @@ message TBatchHeader {
optional uint32 Format = 7; //for EPayloadFormat
optional bool HasKinesis = 8;
}
-
+
message TUserInfo {
optional uint64 Offset = 1;
optional uint32 Generation = 2;
@@ -664,17 +664,17 @@ message TUserInfo {
optional uint64 ReadRuleGeneration = 6;
}
-message TPartitionClientInfo {
- repeated int32 Partitions = 1;
-}
-
-message TClientInfoResponse {
- optional int32 Partition = 1;
- optional uint64 StartOffset = 2;
- optional uint64 EndOffset = 3;
- optional uint64 ResponseTimestamp = 4;
- repeated TClientInfo ClientInfo = 5;
-}
+message TPartitionClientInfo {
+ repeated int32 Partitions = 1;
+}
+
+message TClientInfoResponse {
+ optional int32 Partition = 1;
+ optional uint64 StartOffset = 2;
+ optional uint64 EndOffset = 3;
+ optional uint64 ResponseTimestamp = 4;
+ repeated TClientInfo ClientInfo = 5;
+}
message TPQClusterDiscoveryConfig {
optional bool Enabled = 1;
diff --git a/ydb/core/protos/scheme_log.proto b/ydb/core/protos/scheme_log.proto
index fd8b93ebfe5..fcf4ba52b94 100644
--- a/ydb/core/protos/scheme_log.proto
+++ b/ydb/core/protos/scheme_log.proto
@@ -1,16 +1,16 @@
import "ydb/core/protos/flat_scheme_op.proto";
-package NTabletFlatScheme;
-option java_package = "ru.yandex.kikimr.proto";
-
+package NTabletFlatScheme;
+option java_package = "ru.yandex.kikimr.proto";
+
message TAlterRecord {
- enum EDeltaType {
- AddTable = 1;
- DropTable = 2;
- AddColumn = 3;
- DropColumn = 4;
- AddColumnToKey = 5;
- AddColumnToFamily = 6;
+ enum EDeltaType {
+ AddTable = 1;
+ DropTable = 2;
+ AddColumn = 3;
+ DropColumn = 4;
+ AddColumnToKey = 5;
+ AddColumnToFamily = 6;
AddFamily = 7;
UpdateExecutorInfo = 8;
SetCompactionPolicy = 9;
@@ -18,12 +18,12 @@ message TAlterRecord {
SetFamily = 11;
SetRedo = 12;
SetTable = 13;
- };
+ };
- required EDeltaType DeltaType = 1;
- optional uint32 TableId = 2;
- optional string TableName = 3;
- optional uint32 ColumnId = 4;
+ required EDeltaType DeltaType = 1;
+ optional uint32 TableId = 2;
+ optional string TableName = 3;
+ optional uint32 ColumnId = 4;
optional uint32 FamilyId = 7;
optional uint32 RoomId = 8;
@@ -67,8 +67,8 @@ message TAlterRecord {
optional uint32 ExecutorLimitInFlyTx = 104;
optional string ExecutorResourceProfile = 105;
optional bool ExecutorLogFastCommitTactic = 106;
-};
-
-message TSchemeChanges {
+};
+
+message TSchemeChanges {
repeated TAlterRecord Delta = 1;
-};
+};
diff --git a/ydb/core/protos/services.proto b/ydb/core/protos/services.proto
index cc5560df266..c17c8a7dc37 100644
--- a/ydb/core/protos/services.proto
+++ b/ydb/core/protos/services.proto
@@ -147,7 +147,7 @@ enum EServiceKikimr {
LONG_TX_SERVICE = 405;
LOGGER = 410;
- MSGBUS_TRACER = 411;
+ MSGBUS_TRACER = 411;
MSGBUS_REQUEST = 412; // deprecated, use RPC_REQUEST
GRPC_SERVER = 413;
GRPC_PROXY = 415;
@@ -171,12 +171,12 @@ enum EServiceKikimr {
CHOOSE_PROXY = 444;
LB_CONFIG_MANAGER = 445;
- TOKEN_BUILDER = 450;
- TICKET_PARSER = 455;
- BLACKBOX_VALIDATOR = 460;
-
- GRPC_CLIENT = 461;
-
+ TOKEN_BUILDER = 450;
+ TICKET_PARSER = 455;
+ BLACKBOX_VALIDATOR = 460;
+
+ GRPC_CLIENT = 461;
+
// SQS section
SQS = 470;
@@ -196,8 +196,8 @@ enum EServiceKikimr {
CMS = 523;
- HTTP = 524;
-
+ HTTP = 524;
+
NODE_BROKER = 525;
TENANT_SLOT_BROKER = 526;
CMS_TENANTS = 527;
@@ -823,9 +823,9 @@ message TActivity {
YQL_GET_HISTORY_REQUEST_ACTOR = 518;
YQL_GET_RESULT_DATA_ACTOR = 519;
BLOB_CACHE_ACTOR = 520;
- MONITORING_SERVICE = 521;
- MONITORING_REQUEST = 522;
- ACTOR_SERVICE_CACHE = 523;
+ MONITORING_SERVICE = 521;
+ MONITORING_REQUEST = 522;
+ ACTOR_SERVICE_CACHE = 523;
CHANGE_SENDER_ACTOR = 524;
CHANGE_SENDER_ASYNC_INDEX_ACTOR_MAIN = 525;
CHANGE_SENDER_ASYNC_INDEX_ACTOR_PARTITION = 526;
diff --git a/ydb/core/protos/statestorage.proto b/ydb/core/protos/statestorage.proto
index 7a83fac76e0..4165af89ba0 100644
--- a/ydb/core/protos/statestorage.proto
+++ b/ydb/core/protos/statestorage.proto
@@ -31,13 +31,13 @@ message TEvInfo {
message TEvReplicaShutdown {
};
-message TEvDumpRequest {
-};
-
-message TEvDump {
- repeated TEvInfo Info = 1;
-};
-
+message TEvDumpRequest {
+};
+
+message TEvDump {
+ repeated TEvInfo Info = 1;
+};
+
message TEvUpdate {
optional fixed64 TabletID = 1;
optional uint64 Cookie = 2;
@@ -49,10 +49,10 @@ message TEvUpdate {
optional bool IsGuardian = 8;
};
-message TEvDelete {
- optional fixed64 TabletID = 1;
-};
-
+message TEvDelete {
+ optional fixed64 TabletID = 1;
+};
+
message TEvCleanup {
optional fixed64 TabletID = 1;
optional NActorsProto.TActorId ProposedLeader = 2;
@@ -85,7 +85,7 @@ message TEvReplicaLeaderDemoted {
message TEvReplicaBoardPublish {
optional string Path = 1;
- optional bytes Payload = 2;
+ optional bytes Payload = 2;
optional uint64 TtlMs = 3;
optional bool Register = 4;
optional NActorsProto.TActorId Owner = 5;
@@ -105,7 +105,7 @@ message TEvReplicaBoardCleanup {
message TBoardEntryInfo {
optional NActorsProto.TActorId Owner = 1;
- optional bytes Payload = 2;
+ optional bytes Payload = 2;
};
message TEvReplicaBoardInfo {
diff --git a/ydb/core/protos/subdomains.proto b/ydb/core/protos/subdomains.proto
index fbb3c742c63..5d665ff3813 100644
--- a/ydb/core/protos/subdomains.proto
+++ b/ydb/core/protos/subdomains.proto
@@ -16,8 +16,8 @@ message TSubDomainSettings {
optional string Name = 4;
optional uint32 TimeCastBucketsPerMediator = 5;
repeated NKikimrStoragePool.TStoragePool StoragePools = 6;
- optional bool ExternalSchemeShard = 7 [default = false];
- optional bool ExternalHive = 8 [default = false];
+ optional bool ExternalSchemeShard = 7 [default = false];
+ optional bool ExternalHive = 8 [default = false];
optional TDomainKey ResourcesDomainKey = 9;
optional bool ExternalSysViewProcessor = 10 [default = false];
optional TSchemeQuotas DeclaredSchemeQuotas = 11;
@@ -32,7 +32,7 @@ message TProcessingParams {
repeated fixed64 Mediators = 5;
optional fixed64 SchemeShard = 6;
- optional fixed64 Hive = 7;
+ optional fixed64 Hive = 7;
optional fixed64 SysViewProcessor = 8;
//put there SubSchemeShard and SubHive at the future
@@ -77,8 +77,8 @@ message TDomainDescription {
optional Ydb.Cms.DatabaseQuotas DatabaseQuotas = 15;
optional TDomainState DomainState = 16;
-
- optional NLoginProto.TSecurityState SecurityState = 20;
+
+ optional NLoginProto.TSecurityState SecurityState = 20;
}
message TSchemeQuotas {
diff --git a/ydb/core/protos/tablet.proto b/ydb/core/protos/tablet.proto
index dc6c58feb4f..f0bec238e78 100644
--- a/ydb/core/protos/tablet.proto
+++ b/ydb/core/protos/tablet.proto
@@ -4,35 +4,35 @@ import "ydb/core/protos/tablet_counters.proto";
package NKikimrTabletBase;
option java_package = "ru.yandex.kikimr.proto";
-// we have changed type without changing it's number because there is a binary compatibility with ui32 and enums
-message TTabletTypes {
- enum EType {
- Unknown = 0;
- OldSchemeShard = 1;
- OldDataShard = 2;
- OldHive = 3;
- OldCoordinator = 4;
- Mediator = 5;
- OldTxProxy = 6;
- OldBSController = 7;
- Dummy = 8;
- // number 9 was OldJobRunnerPoolManager - hierarchical JRPM tablet
- RTMRPartition = 10;
- OldKeyValue = 11;
- KeyValue = 12;
- Coordinator = 13;
- Hive = 14;
- BSController = 15;
- SchemeShard = 16;
- TxProxy = 17;
- DataShard = 18;
- // number 19 was JobRunnerPoolManager - flat JRPM tablet
- PersQueue = 20;
+// we have changed type without changing it's number because there is a binary compatibility with ui32 and enums
+message TTabletTypes {
+ enum EType {
+ Unknown = 0;
+ OldSchemeShard = 1;
+ OldDataShard = 2;
+ OldHive = 3;
+ OldCoordinator = 4;
+ Mediator = 5;
+ OldTxProxy = 6;
+ OldBSController = 7;
+ Dummy = 8;
+ // number 9 was OldJobRunnerPoolManager - hierarchical JRPM tablet
+ RTMRPartition = 10;
+ OldKeyValue = 11;
+ KeyValue = 12;
+ Coordinator = 13;
+ Hive = 14;
+ BSController = 15;
+ SchemeShard = 16;
+ TxProxy = 17;
+ DataShard = 18;
+ // number 19 was JobRunnerPoolManager - flat JRPM tablet
+ PersQueue = 20;
Cms = 21;
- NodeBroker = 22;
- TxAllocator = 23;
- PersQueueReadBalancer = 24;
- BlockStoreVolume = 25;
+ NodeBroker = 22;
+ TxAllocator = 23;
+ PersQueueReadBalancer = 24;
+ BlockStoreVolume = 25;
BlockStorePartition = 26;
TenantSlotBroker = 27;
Console = 28;
@@ -46,7 +46,7 @@ message TTabletTypes {
TestShard = 36;
SequenceShard = 37;
ReplicationController = 38;
-
+
// when adding a new tablet type and keeping parse compatibility with the old version
// rename existing reserved item to desired one, and add new reserved item to
// the end of reserved list
@@ -55,11 +55,11 @@ message TTabletTypes {
Reserved41 = 41;
Reserved42 = 42;
- UserTypeStart = 255;
- TypeInvalid = -1;
- }
-}
-
+ UserTypeStart = 255;
+ TypeInvalid = -1;
+ }
+}
+
message TTabletLogEntry {
// normal log entries
repeated uint32 DependsOn = 1;
@@ -97,8 +97,8 @@ message TTabletChannelInfo {
message TTabletStorageInfo {
optional fixed64 TabletID = 1;
repeated TTabletChannelInfo Channels = 2;
- optional TTabletTypes.EType TabletType = 3;
- optional uint32 Version = 4;
+ optional TTabletTypes.EType TabletType = 3;
+ optional uint32 Version = 4;
optional uint64 TenantIdOwner = 5;
optional uint64 TenantIdLocalId = 6;
}
@@ -182,48 +182,48 @@ message TEvFollowerRefresh {
optional uint32 Generation = 2;
optional bool OfflineProtocol = 3;
}
-
-message TEvGetCounters {
-}
-
-message TEvGetCountersResponse {
- optional NKikimrTabletBase.TTabletCounters TabletCounters = 1;
-}
-
-message TEvCutTabletHistory {
- optional fixed64 TabletID = 1;
- optional uint32 Channel = 2;
- optional uint32 GroupID = 3;
- optional uint32 FromGeneration = 4;
-}
-
-message TThroughputRecord {
- optional uint32 GroupID = 1;
- optional uint32 Channel = 2; // it uint8 actually
- optional uint64 Throughput = 3;
-}
-
+
+message TEvGetCounters {
+}
+
+message TEvGetCountersResponse {
+ optional NKikimrTabletBase.TTabletCounters TabletCounters = 1;
+}
+
+message TEvCutTabletHistory {
+ optional fixed64 TabletID = 1;
+ optional uint32 Channel = 2;
+ optional uint32 GroupID = 3;
+ optional uint32 FromGeneration = 4;
+}
+
+message TThroughputRecord {
+ optional uint32 GroupID = 1;
+ optional uint32 Channel = 2; // it uint8 actually
+ optional uint64 Throughput = 3;
+}
+
message TIopsRecord {
optional uint32 GroupID = 1;
optional uint32 Channel = 2; // actually uint8
optional uint64 Iops = 3;
}
-message TMetrics {
- optional uint64 CPU = 1;
- optional uint64 Memory = 2;
- optional uint64 Network = 3;
- optional uint64 Counter = 4;
- optional uint64 Storage = 5;
- repeated TThroughputRecord GroupReadThroughput = 6;
- repeated TThroughputRecord GroupWriteThroughput = 7;
- optional uint64 ReadThroughput = 8;
- optional uint64 WriteThroughput = 9;
+message TMetrics {
+ optional uint64 CPU = 1;
+ optional uint64 Memory = 2;
+ optional uint64 Network = 3;
+ optional uint64 Counter = 4;
+ optional uint64 Storage = 5;
+ repeated TThroughputRecord GroupReadThroughput = 6;
+ repeated TThroughputRecord GroupWriteThroughput = 7;
+ optional uint64 ReadThroughput = 8;
+ optional uint64 WriteThroughput = 9;
repeated TIopsRecord GroupReadIops = 10;
repeated TIopsRecord GroupWriteIops = 11;
optional uint64 ReadIops = 12;
optional uint64 WriteIops = 13;
-}
+}
message TEvTabletStop {
enum EReason {
diff --git a/ydb/core/protos/tablet_counters.proto b/ydb/core/protos/tablet_counters.proto
index 27872a9e74b..86f08adc235 100644
--- a/ydb/core/protos/tablet_counters.proto
+++ b/ydb/core/protos/tablet_counters.proto
@@ -1,29 +1,29 @@
-package NKikimrTabletBase;
-option java_package = "ru.yandex.kikimr.proto";
-
-message TTabletSimpleCounter {
- optional string Name = 1;
- optional uint64 Value = 2;
-}
-
-message TTabletCumulativeCounter {
- optional string Name = 1;
- optional uint64 Value = 2;
-}
-
-message TTabletPercentileCounter {
- optional string Name = 1;
- repeated string Ranges = 2;
- repeated uint64 Values = 3;
-}
-
-message TTabletCountersBase {
- repeated TTabletSimpleCounter SimpleCounters = 1;
- repeated TTabletCumulativeCounter CumulativeCounters = 2;
- repeated TTabletPercentileCounter PercentileCounters = 3;
-};
-
-message TTabletCounters {
- optional TTabletCountersBase ExecutorCounters = 1;
- optional TTabletCountersBase AppCounters = 2;
-};
+package NKikimrTabletBase;
+option java_package = "ru.yandex.kikimr.proto";
+
+message TTabletSimpleCounter {
+ optional string Name = 1;
+ optional uint64 Value = 2;
+}
+
+message TTabletCumulativeCounter {
+ optional string Name = 1;
+ optional uint64 Value = 2;
+}
+
+message TTabletPercentileCounter {
+ optional string Name = 1;
+ repeated string Ranges = 2;
+ repeated uint64 Values = 3;
+}
+
+message TTabletCountersBase {
+ repeated TTabletSimpleCounter SimpleCounters = 1;
+ repeated TTabletCumulativeCounter CumulativeCounters = 2;
+ repeated TTabletPercentileCounter PercentileCounters = 3;
+};
+
+message TTabletCounters {
+ optional TTabletCountersBase ExecutorCounters = 1;
+ optional TTabletCountersBase AppCounters = 2;
+};
diff --git a/ydb/core/protos/tablet_counters_aggregator.proto b/ydb/core/protos/tablet_counters_aggregator.proto
index 4fbdd440cae..b19d5a89da8 100644
--- a/ydb/core/protos/tablet_counters_aggregator.proto
+++ b/ydb/core/protos/tablet_counters_aggregator.proto
@@ -1,49 +1,49 @@
import "ydb/core/protos/counters.proto";
import "ydb/core/protos/tablet.proto";
-
-package NKikimrTabletCountersAggregator;
-option java_package = "ru.yandex.kikimr.proto";
-
+
+package NKikimrTabletCountersAggregator;
+option java_package = "ru.yandex.kikimr.proto";
+
option cc_enable_arenas = true;
-message TTabletCounters {
- repeated uint64 SimpleCounters = 1;
- repeated uint64 CumulativeCounters = 2;
-}
-
-message TTabletCountersInfo {
- optional uint64 TabletId = 1;
- optional TTabletCounters ExecutorCounters = 2;
- optional TTabletCounters AppCounters = 3;
-}
-
-message TEvTabletCountersRequest {
- repeated uint64 TabletIds = 1;
-}
-
-message TEvTabletCountersResponse {
- repeated TTabletCountersInfo CountersInfo = 1;
-}
+message TTabletCounters {
+ repeated uint64 SimpleCounters = 1;
+ repeated uint64 CumulativeCounters = 2;
+}
+
+message TTabletCountersInfo {
+ optional uint64 TabletId = 1;
+ optional TTabletCounters ExecutorCounters = 2;
+ optional TTabletCounters AppCounters = 3;
+}
+
+message TEvTabletCountersRequest {
+ repeated uint64 TabletIds = 1;
+}
+
+message TEvTabletCountersResponse {
+ repeated TTabletCountersInfo CountersInfo = 1;
+}
message TEvTabletLabeledCountersRequest {
- optional NKikimrTabletBase.TTabletTypes.EType TabletType = 1;
+ optional NKikimrTabletBase.TTabletTypes.EType TabletType = 1;
optional string Group = 2;
- optional uint64 LabeledCounterId = 3; // Version 1
- optional uint32 Version = 4 [default = 1];
+ optional uint64 LabeledCounterId = 3; // Version 1
+ optional uint32 Version = 4 [default = 1];
}
message TTabletLabeledCounter {
optional uint64 Value = 1;
optional uint64 Id = 2;
- optional string Name = 3; // Version 1
+ optional string Name = 3; // Version 1
optional NKikimr.TLabeledCounterOptions.EAggregateFunc AggregateFunc = 4;
optional NKikimr.TLabeledCounterOptions.ECounterType Type = 5;
- optional uint32 NameId = 6; // Version 2
+ optional uint32 NameId = 6; // Version 2
}
message TTabletLabeledCounters {
optional string Group = 1;
- optional string GroupNames = 2; // Version 1
+ optional string GroupNames = 2; // Version 1
repeated TTabletLabeledCounter LabeledCounter = 3;
optional string Delimiter = 4;
@@ -52,5 +52,5 @@ message TTabletLabeledCounters {
message TEvTabletLabeledCountersResponse {
repeated TTabletLabeledCounters LabeledCountersByGroup = 1;
repeated uint32 Nodes = 2;
- repeated string CounterNames = 3; // Version 2
+ repeated string CounterNames = 3; // Version 2
}
diff --git a/ydb/core/protos/tablet_tx.proto b/ydb/core/protos/tablet_tx.proto
index 1a4ca88420d..e8db9062114 100644
--- a/ydb/core/protos/tablet_tx.proto
+++ b/ydb/core/protos/tablet_tx.proto
@@ -1,37 +1,37 @@
import "ydb/core/protos/tx_proxy.proto";
import "ydb/core/protos/scheme_log.proto";
import "ydb/library/mkql_proto/protos/minikql.proto";
-
-package NKikimrTabletTxBase;
-option java_package = "ru.yandex.kikimr.proto";
-
-message TEvLocalMKQL {
- optional NKikimrTxUserProxy.TMiniKQLTransaction Program = 1;
-}
-
-message TEvLocalMKQLResponse {
- optional uint64 Origin = 1;
+
+package NKikimrTabletTxBase;
+option java_package = "ru.yandex.kikimr.proto";
+
+message TEvLocalMKQL {
+ optional NKikimrTxUserProxy.TMiniKQLTransaction Program = 1;
+}
+
+message TEvLocalMKQLResponse {
+ optional uint64 Origin = 1;
optional int32 Status = 2;
-
- optional uint32 EngineStatus = 10;
- optional uint32 EngineResponseStatus = 11;
- optional bytes MiniKQLErrors = 12;
- optional NKikimrMiniKQL.TResult ExecutionEngineEvaluatedResponse = 13;
- optional NKikimrTxUserProxy.TMiniKQLCompileResults CompileResults = 14;
-}
-
-message TEvLocalSchemeTx {
- optional NTabletFlatScheme.TSchemeChanges SchemeChanges = 1;
- optional bool DryRun = 2;
-}
-
-message TEvLocalSchemeTxResponse {
- optional uint64 Origin = 1;
+
+ optional uint32 EngineStatus = 10;
+ optional uint32 EngineResponseStatus = 11;
+ optional bytes MiniKQLErrors = 12;
+ optional NKikimrMiniKQL.TResult ExecutionEngineEvaluatedResponse = 13;
+ optional NKikimrTxUserProxy.TMiniKQLCompileResults CompileResults = 14;
+}
+
+message TEvLocalSchemeTx {
+ optional NTabletFlatScheme.TSchemeChanges SchemeChanges = 1;
+ optional bool DryRun = 2;
+}
+
+message TEvLocalSchemeTxResponse {
+ optional uint64 Origin = 1;
optional int32 Status = 2;
- optional string ErrorReason = 3;
-
- optional NTabletFlatScheme.TSchemeChanges FullScheme = 4;
-}
+ optional string ErrorReason = 3;
+
+ optional NTabletFlatScheme.TSchemeChanges FullScheme = 4;
+}
message TEvLocalReadColumns {
optional string TableName = 1;
diff --git a/ydb/core/protos/tenant_slot_broker.proto b/ydb/core/protos/tenant_slot_broker.proto
index a0cd003f87c..bccc7f7dc7b 100644
--- a/ydb/core/protos/tenant_slot_broker.proto
+++ b/ydb/core/protos/tenant_slot_broker.proto
@@ -45,7 +45,7 @@ message TTenantState {
repeated TSlotAllocation MisplacedSlots = 5;
repeated TSlotAllocation SplitSlots = 6;
repeated TSlotAllocation PinnedSlots = 7;
- repeated TSlotId AssignedSlots = 8;
+ repeated TSlotId AssignedSlots = 8;
}
message TAlterTenant {
diff --git a/ydb/core/protos/tx_datashard.proto b/ydb/core/protos/tx_datashard.proto
index 434c0ae3f17..89863b25400 100644
--- a/ydb/core/protos/tx_datashard.proto
+++ b/ydb/core/protos/tx_datashard.proto
@@ -728,7 +728,7 @@ message TEvGetTableStatsResult {
optional uint64 DatashardId = 1;
optional uint64 TableLocalId = 2;
optional NKikimrTableStats.TTableStats TableStats = 3;
- optional NKikimrTabletBase.TMetrics TabletMetrics = 4;
+ optional NKikimrTabletBase.TMetrics TabletMetrics = 4;
optional uint32 ShardState = 5;
repeated uint64 UserTablePartOwners = 6;
repeated uint64 SysTablesPartOwners = 7;
@@ -744,7 +744,7 @@ message TEvPeriodicTableStats {
optional uint64 Round = 4;
optional NKikimrTableStats.TTableStats TableStats = 5;
- optional NKikimrTabletBase.TMetrics TabletMetrics = 6;
+ optional NKikimrTabletBase.TMetrics TabletMetrics = 6;
optional uint32 ShardState = 7;
repeated uint64 UserTablePartOwners = 8;
diff --git a/ydb/core/protos/tx_proxy.proto b/ydb/core/protos/tx_proxy.proto
index 0205dc82fed..dedd2f9cbb5 100644
--- a/ydb/core/protos/tx_proxy.proto
+++ b/ydb/core/protos/tx_proxy.proto
@@ -130,7 +130,7 @@ message TMiniKQLTransaction {
// Server will use Text, if not set -- Bin.
optional string Text = 1; // Text params.
optional bytes Bin = 2; // Serialized params.
- optional NKikimrMiniKQL.TParams Proto = 3;
+ optional NKikimrMiniKQL.TParams Proto = 3;
};
enum EMode {
@@ -172,7 +172,7 @@ message TTransaction {
optional uint32 Flags = 6; // See ydb/core/tx/tx_datashard.h NKikimr::NTxDataShard::TTxFlags
optional string UserRequestId = 8;
-
+
optional NKikimrSchemeOp.TModifyScheme ModifyScheme = 10;
repeated NKikimrSchemeOp.TModifyScheme TransactionalModification = 11;
@@ -189,7 +189,7 @@ message TEvProposeTransaction {
optional TTransaction Transaction = 1;
optional uint64 ProxyFlags = 2;
optional uint64 ExecTimeoutPeriod = 3;
- optional string UserToken = 4; // already built and serialized user's token
+ optional string UserToken = 4; // already built and serialized user's token
optional bool StreamResponse = 5;
optional uint64 CancelAfterMs = 6;
optional string DatabaseName = 7;
@@ -234,7 +234,7 @@ message TEvProposeTransactionStatus {
optional uint32 SchemeShardStatus = 30;
optional uint32 SchemeShardReportedId = 31;
optional bytes SchemeShardReason = 32;
- optional fixed64 SchemeShardTabletId = 33;
+ optional fixed64 SchemeShardTabletId = 33;
optional uint64 PathId = 34;
optional uint64 PathCreateTxId = 35;
optional uint64 PathDropTxId = 36;
@@ -250,10 +250,10 @@ message TEvNavigate {
reserved 2; // optional uint32 ReadMaterializedFamily = 2;
reserved 3; // optional bytes TextPath = 3;
reserved 4; // optional uint64 SchemeShardHint = 4;
-
+
optional NKikimrSchemeOp.TDescribePath DescribePath = 5;
-
- optional string UserToken = 6; // already built and serialized user's token
+
+ optional string UserToken = 6; // already built and serialized user's token
optional string DatabaseName = 7;
}
@@ -266,14 +266,14 @@ message TEvNavigateStatus_Deprecated {
optional uint32 SchemeShardStatus = 30;
optional uint32 SchemeShardReportedId = 31;
-
+
optional NKikimrSchemeOp.TPathDescription PathDescription = 40;
}
-
-message TEvInvalidateTable {
- optional uint64 SchemeShardId = 1;
- optional uint64 TableId = 2;
-}
+
+message TEvInvalidateTable {
+ optional uint64 SchemeShardId = 1;
+ optional uint64 TableId = 2;
+}
message TEvExportRequest {
optional string DatabaseName = 1;
diff --git a/ydb/core/protos/tx_scheme.proto b/ydb/core/protos/tx_scheme.proto
index d46fca64409..037db6c4972 100644
--- a/ydb/core/protos/tx_scheme.proto
+++ b/ydb/core/protos/tx_scheme.proto
@@ -45,8 +45,8 @@ message TEvInitRootShard {
optional uint32 RootTag = 2;
optional bytes RootTagName = 3;
optional TConfig Config = 4;
- optional string Owner = 5;
- repeated NKikimrStoragePool.TStoragePool StoragePools = 6;
+ optional string Owner = 5;
+ repeated NKikimrStoragePool.TStoragePool StoragePools = 6;
}
message TEvInitRootShardResult {
diff --git a/ydb/core/protos/ya.make b/ydb/core/protos/ya.make
index 5d0bfc59acc..70bb65514cd 100644
--- a/ydb/core/protos/ya.make
+++ b/ydb/core/protos/ya.make
@@ -13,7 +13,7 @@ IF (OS_WINDOWS)
ENDIF()
SRCS(
- alloc.proto
+ alloc.proto
base.proto
bind_channel_storage_pool.proto
blobstorage.proto
@@ -72,7 +72,7 @@ SRCS(
kqp.proto
local.proto
long_tx_service.proto
- metrics.proto
+ metrics.proto
minikql_engine.proto
msgbus.proto
msgbus_health.proto
@@ -99,17 +99,17 @@ SRCS(
subdomains.proto
table_stats.proto
tablet.proto
- tablet_counters_aggregator.proto
- tablet_counters.proto
+ tablet_counters_aggregator.proto
+ tablet_counters.proto
tablet_database.proto
tablet_pipe.proto
- tablet_tx.proto
+ tablet_tx.proto
tenant_pool.proto
tenant_slot_broker.proto
test_shard.proto
tracing.proto
tablet_tracing_signals.proto
- node_whiteboard.proto
+ node_whiteboard.proto
tx.proto
tx_columnshard.proto
tx_datashard.proto
diff --git a/ydb/core/quoter/kesus_quoter_proxy.cpp b/ydb/core/quoter/kesus_quoter_proxy.cpp
index 023b8ee1792..4d2d20691e9 100644
--- a/ydb/core/quoter/kesus_quoter_proxy.cpp
+++ b/ydb/core/quoter/kesus_quoter_proxy.cpp
@@ -921,10 +921,10 @@ public:
NTabletPipe::TClientConfig GetPipeConnectionOptions(bool reconnection) {
NTabletPipe::TClientConfig cfg;
cfg.CheckAliveness = true;
- cfg.RetryPolicy = {
- .RetryLimitCount = 3u,
- .DoFirstRetryInstantly = !reconnection
- };
+ cfg.RetryPolicy = {
+ .RetryLimitCount = 3u,
+ .DoFirstRetryInstantly = !reconnection
+ };
return cfg;
}
diff --git a/ydb/core/scheme/scheme_tablecell.h b/ydb/core/scheme/scheme_tablecell.h
index 4b3ea96fb86..bccfdca97db 100644
--- a/ydb/core/scheme/scheme_tablecell.h
+++ b/ydb/core/scheme/scheme_tablecell.h
@@ -211,24 +211,24 @@ inline int CompareTypedCellVectors(const TCell* a, const TCell* b, const TTypeCl
template<class TTypeClass>
inline int CompareTypedCellVectors(const TCell* a, const TCell* b, const TTypeClass* type, const ui32 cnt_a, const ui32 cnt_b) {
Y_VERIFY_DEBUG(cnt_b <= cnt_a);
- ui32 i = 0;
- for (; i < cnt_b; ++i) {
- int cmpRes = CompareTypedCells(a[i], b[i], type[i]);
- if (cmpRes != 0)
- return cmpRes;
- }
- for (; i < cnt_a; ++i) {
- if (!a[i].IsNull())
- return 1;
- }
- return 0;
-}
+ ui32 i = 0;
+ for (; i < cnt_b; ++i) {
+ int cmpRes = CompareTypedCells(a[i], b[i], type[i]);
+ if (cmpRes != 0)
+ return cmpRes;
+ }
+ for (; i < cnt_a; ++i) {
+ if (!a[i].IsNull())
+ return 1;
+ }
+ return 0;
+}
// TODO: use NYql ops when TCell and TUnboxedValuePod had merged
inline ui64 GetValueHash(NScheme::TTypeId type, const TCell& cell) {
if (cell.IsNull())
return 0;
-
+
const NYql::NProto::TypeIds yqlType = static_cast<NYql::NProto::TypeIds>(type);
switch (yqlType) {
case NYql::NProto::TypeIds::Bool:
diff --git a/ydb/core/scheme/scheme_tabledefs.h b/ydb/core/scheme/scheme_tabledefs.h
index 5a4bd5fd669..190233fdeee 100644
--- a/ydb/core/scheme/scheme_tabledefs.h
+++ b/ydb/core/scheme/scheme_tabledefs.h
@@ -560,25 +560,25 @@ private:
EMode Mode;
std::pair<ui64, ui64> SnapshotTime;
};
-
-struct TSecurityObject : TAtomicRefCount<TSecurityObject>, NACLib::TSecurityObject {
+
+struct TSecurityObject : TAtomicRefCount<TSecurityObject>, NACLib::TSecurityObject {
using TPtr = TIntrusivePtr<TSecurityObject>;
static NACLib::TSecurityObject FromByteStream(const NACLibProto::TSecurityObject* parent, const TString& owner, const TString& acl, bool isContainer) {
- NACLib::TSecurityObject object(owner, isContainer);
- Y_VERIFY(object.MutableACL()->ParseFromString(acl));
- return parent != nullptr ? object.MergeWithParent(*parent) : object;
- }
-
+ NACLib::TSecurityObject object(owner, isContainer);
+ Y_VERIFY(object.MutableACL()->ParseFromString(acl));
+ return parent != nullptr ? object.MergeWithParent(*parent) : object;
+ }
+
TSecurityObject(const TString& owner, const TString& acl, bool isContainer)
- : NACLib::TSecurityObject(FromByteStream(nullptr, owner, acl, isContainer))
- {}
-
+ : NACLib::TSecurityObject(FromByteStream(nullptr, owner, acl, isContainer))
+ {}
+
TSecurityObject(const TSecurityObject* parent, const TString& owner, const TString& acl, bool isContainer)
- : NACLib::TSecurityObject(FromByteStream(parent, owner, acl, isContainer))
- {}
-};
-
+ : NACLib::TSecurityObject(FromByteStream(parent, owner, acl, isContainer))
+ {}
+};
+
// key description of one minikql operation
class TKeyDesc : TNonCopyable {
public:
@@ -676,7 +676,7 @@ public:
EStatus Status;
TVector<TColumnInfo> ColumnInfos;
TVector<TPartitionInfo> Partitions;
- TIntrusivePtr<TSecurityObject> SecurityObject;
+ TIntrusivePtr<TSecurityObject> SecurityObject;
bool IsSystemView() const { return Partitions.empty(); }
diff --git a/ydb/core/security/login_page.cpp b/ydb/core/security/login_page.cpp
index cfa33920e4b..efd99abca68 100644
--- a/ydb/core/security/login_page.cpp
+++ b/ydb/core/security/login_page.cpp
@@ -1,400 +1,400 @@
-#include "login_page.h"
-
-#include <library/cpp/json/json_value.h>
-#include <library/cpp/json/json_reader.h>
-#include <library/cpp/json/json_writer.h>
-
+#include "login_page.h"
+
+#include <library/cpp/json/json_value.h>
+#include <library/cpp/json/json_reader.h>
+#include <library/cpp/json/json_writer.h>
+
#include <ydb/core/base/tablet_pipe.h>
#include <ydb/core/tx/scheme_cache/scheme_cache.h>
#include <ydb/core/tx/schemeshard/schemeshard.h>
-
-#include <ydb/library/login/login.h>
-#include <ydb/library/security/util.h>
-
-namespace {
-
-using namespace NActors;
-using namespace NKikimr;
-using namespace NSchemeShard;
-using namespace NMonitoring;
-
-using THttpResponsePtr = THolder<NMon::IEvHttpInfoRes>;
-
-class TLoginRequest : public NActors::TActorBootstrapped<TLoginRequest> {
-public:
- static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
- return NKikimrServices::TActivity::ACTORLIB_COMMON;
- }
-
- TLoginRequest(IMonHttpRequest& request, NThreading::TPromise<THttpResponsePtr> result)
- : Request(request)
- , Result(result)
- {
- }
-
- ~TLoginRequest() {
- if (!Result.HasValue()) {
- Result.SetValue(nullptr);
- }
- }
-
- STATEFN(StateWork) {
- switch (ev->GetTypeRewrite()) {
- hFunc(TEvents::TEvPoisonPill, HandlePoisonPill);
- hFunc(TEvTabletPipe::TEvClientConnected, HandleConnect);
- hFunc(TEvTxProxySchemeCache::TEvNavigateKeySetResult, HandleNavigate);
- hFunc(TEvSchemeShard::TEvLoginResult, HandleResult);
- cFunc(TEvents::TSystem::Wakeup, HandleTimeout);
- }
- }
-
- static TString GetMethod(HTTP_METHOD method) {
- switch (method) {
- case HTTP_METHOD_UNDEFINED: return "UNDEFINED";
- case HTTP_METHOD_OPTIONS: return "OPTIONS";
- case HTTP_METHOD_GET: return "GET";
- case HTTP_METHOD_HEAD: return "HEAD";
- case HTTP_METHOD_POST: return "POST";
- case HTTP_METHOD_PUT: return "PUT";
- case HTTP_METHOD_DELETE: return "DELETE";
- case HTTP_METHOD_TRACE: return "TRACE";
- case HTTP_METHOD_CONNECT: return "CONNECT";
- case HTTP_METHOD_EXTENSION: return "EXTENSION";
- default: return "UNKNOWN";
- }
- }
-
- void Bootstrap() {
- LOG_WARN_S(*TlsActivationContext, NKikimrServices::HTTP,
- Request.GetRemoteAddr()
- << " " << GetMethod(Request.GetMethod())
- << " " << Request.GetUri());
-
- if (Request.GetMethod() == HTTP_METHOD_OPTIONS) {
- return ReplyOptionsAndPassAway();
- }
-
- if (Request.GetMethod() != HTTP_METHOD_POST) {
- return ReplyErrorAndPassAway("400 Bad Request", "Invalid method");
- }
-
- if (Request.GetHeader("Content-Type") != "application/json") {
- return ReplyErrorAndPassAway("400 Bad Request", "Invalid Content-Type");
- }
-
- NJson::TJsonValue postData;
-
- if (!NJson::ReadJsonTree(Request.GetPostContent(), &postData)) {
- return ReplyErrorAndPassAway("400 Bad Request", "Invalid JSON data");
- }
-
- if (postData.Has("database")) {
- Database = postData["database"].GetStringRobust();
- } else {
- TDomainsInfo* domainsInfo = AppData()->DomainsInfo.Get();
- const TDomainsInfo::TDomain& domain = *domainsInfo->Domains.begin()->second.Get();
- Database = "/" + domain.Name;
- }
-
- NJson::TJsonValue* jsonUser;
- if (postData.GetValuePointer("user", &jsonUser)) {
- User = jsonUser->GetStringRobust();
- } else {
- return ReplyErrorAndPassAway("400 Bad Request", "User must be specified");
- }
-
- NJson::TJsonValue* jsonPassword;
- if (postData.GetValuePointer("password", &jsonPassword)) {
- Password = jsonPassword->GetStringRobust();
- } else {
- return ReplyErrorAndPassAway("400 Bad Request", "Password must be specified");
- }
-
- auto request = MakeHolder<NSchemeCache::TSchemeCacheNavigate>();
- request->DatabaseName = Database;
- auto& entry = request->ResultSet.emplace_back();
- entry.Operation = NSchemeCache::TSchemeCacheNavigate::OpPath;
- entry.Path = ::NKikimr::SplitPath(Database);
- entry.RedirectRequired = false;
- Send(MakeSchemeCacheID(), new TEvTxProxySchemeCache::TEvNavigateKeySet(request.Release()));
-
- Become(&TThis::StateWork, Timeout, new TEvents::TEvWakeup());
- }
-
- static NTabletPipe::TClientConfig GetPipeClientConfig() {
- NTabletPipe::TClientConfig clientConfig;
- clientConfig.RetryPolicy = {.RetryLimitCount = 3};
- return clientConfig;
- }
-
- void HandleNavigate(TEvTxProxySchemeCache::TEvNavigateKeySetResult::TPtr& ev) {
- const NSchemeCache::TSchemeCacheNavigate* response = ev->Get()->Request.Get();
- if (response->ResultSet.size() == 1) {
- if (response->ResultSet.front().Status == NSchemeCache::TSchemeCacheNavigate::EStatus::Ok) {
- const NSchemeCache::TSchemeCacheNavigate::TEntry& entry = response->ResultSet.front();
- ui64 schemeShardTabletId = entry.DomainInfo->ExtractSchemeShard();
- IActor* pipe = NTabletPipe::CreateClient(SelfId(), schemeShardTabletId, GetPipeClientConfig());
- TActorId pipeClient = RegisterWithSameMailbox(pipe);
- THolder<TEvSchemeShard::TEvLogin> request = MakeHolder<TEvSchemeShard::TEvLogin>();
- request.Get()->Record.SetUser(User);
- request.Get()->Record.SetPassword(Password);
- NTabletPipe::SendData(SelfId(), pipeClient, request.Release());
- return;
- } else {
- ReplyErrorAndPassAway("503 Service Unavailable", TStringBuilder()
- << "Status " << static_cast<int>(response->ResultSet.front().Status));
- }
- } else {
- ReplyErrorAndPassAway("503 Service Unavailable", "Scheme error");
- }
- }
-
- void HandleResult(TEvSchemeShard::TEvLoginResult::TPtr& ev) {
- if (ev->Get()->Record.GetError()) {
- ReplyErrorAndPassAway("403 Forbidden", ev->Get()->Record.GetError());
- } else {
- ReplyCookieAndPassAway(ev->Get()->Record.GetToken());
- }
- }
-
- void HandleConnect(TEvTabletPipe::TEvClientConnected::TPtr& ev) {
- if (ev->Get()->Status != NKikimrProto::OK) {
- ReplyErrorAndPassAway("503 Service Unavailable", "SchemeShard is not available");
- }
- }
-
- void HandlePoisonPill(TEvents::TEvPoisonPill::TPtr&) {
- PassAway();
- }
-
- void HandleTimeout() {
- ReplyErrorAndPassAway("504 Gateway Timeout", "Timeout");
- }
-
- void ReplyOptionsAndPassAway() {
- Result.SetValue(MakeHolder<NMon::TEvHttpInfoRes>(
- "HTTP/1.1 204 No Content\r\n"
- "Allow: OPTIONS, POST\r\n"
- "Connection: Keep-Alive\r\n\r\n", 0, NMon::IEvHttpInfoRes::EContentType::Custom));
- PassAway();
- }
-
- void ReplyCookieAndPassAway(const TString& cookie) {
- TStringStream response;
- TDuration maxAge = (ToInstant(NLogin::TLoginProvider::GetTokenExpiresAt(cookie)) - TInstant::Now());
- response << "HTTP/1.1 200 OK\r\n";
- response << "Set-Cookie: ydb_session_id=" << cookie << "; Max-Age=" << maxAge.Seconds() << "\r\n";
- response << "\r\n";
- Result.SetValue(MakeHolder<NMon::TEvHttpInfoRes>(response.Str(), 0, NMon::IEvHttpInfoRes::EContentType::Custom));
- PassAway();
- }
-
- void ReplyErrorAndPassAway(const TString& status, const TString& error) {
- NJson::TJsonValue body;
- body["error"] = error;
- TStringStream response;
- TString responseBody = NJson::WriteJson(body, false);
- response << "HTTP/1.1 " << status << "\r\n";
- response << "Content-Type: application/json\r\n";
- response << "Content-Length: " << responseBody.Size() << "\r\n";
- response << "\r\n";
- response << responseBody;
- Result.SetValue(MakeHolder<NMon::TEvHttpInfoRes>(response.Str(), 0, NMon::IEvHttpInfoRes::EContentType::Custom));
- PassAway();
- }
-
-protected:
- IMonHttpRequest& Request;
- NThreading::TPromise<THttpResponsePtr> Result;
- TDuration Timeout = TDuration::Seconds(60);
- TString Database;
- TString User;
- TString Password;
-};
-
-class TLoginMonPage: public IMonPage {
-public:
- TLoginMonPage(TActorSystem* actorSystem, const TString& path)
- : IMonPage(path, {})
- , ActorSystem(actorSystem)
- {
- }
-
- void Output(IMonHttpRequest &request) override {
- auto promise = NThreading::NewPromise<THttpResponsePtr>();
- auto future = promise.GetFuture();
-
- ActorSystem->Register(new TLoginRequest(request, promise));
-
- THttpResponsePtr result = future.ExtractValue(TDuration::Max());
-
- if (result) {
- Output(request, *result);
- }
- }
-
-private:
- void Output(IMonHttpRequest& request, const NMon::IEvHttpInfoRes& result) const {
- result.Output(request.Output());
- }
-
-private:
- TActorSystem* ActorSystem;
-};
-
-class TLogoutRequest : public NActors::TActorBootstrapped<TLogoutRequest> {
-public:
- static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
- return NKikimrServices::TActivity::ACTORLIB_COMMON;
- }
-
- TLogoutRequest(IMonHttpRequest& request, NThreading::TPromise<THttpResponsePtr> result)
- : Request(request)
- , Result(result)
- {
- }
-
- ~TLogoutRequest() {
- if (!Result.HasValue()) {
- Result.SetValue(nullptr);
- }
- }
-
- STATEFN(StateWork) {
- switch (ev->GetTypeRewrite()) {
- hFunc(TEvents::TEvPoisonPill, HandlePoisonPill);
- cFunc(TEvents::TSystem::Wakeup, HandleTimeout);
- }
- }
-
- static TString GetMethod(HTTP_METHOD method) {
- switch (method) {
- case HTTP_METHOD_UNDEFINED: return "UNDEFINED";
- case HTTP_METHOD_OPTIONS: return "OPTIONS";
- case HTTP_METHOD_GET: return "GET";
- case HTTP_METHOD_HEAD: return "HEAD";
- case HTTP_METHOD_POST: return "POST";
- case HTTP_METHOD_PUT: return "PUT";
- case HTTP_METHOD_DELETE: return "DELETE";
- case HTTP_METHOD_TRACE: return "TRACE";
- case HTTP_METHOD_CONNECT: return "CONNECT";
- case HTTP_METHOD_EXTENSION: return "EXTENSION";
- default: return "UNKNOWN";
- }
- }
-
- void Bootstrap() {
- LOG_WARN_S(*TlsActivationContext, NKikimrServices::HTTP,
- Request.GetRemoteAddr()
- << " " << GetMethod(Request.GetMethod())
- << " " << Request.GetUri());
-
- if (Request.GetMethod() == HTTP_METHOD_OPTIONS) {
- return ReplyOptionsAndPassAway();
- }
-
- if (Request.GetMethod() != HTTP_METHOD_POST) {
- return ReplyErrorAndPassAway("400 Bad Request", "Invalid method");
- }
-
- if (Request.GetHeader("Content-Type") != "application/json") {
- return ReplyErrorAndPassAway("400 Bad Request", "Invalid Content-Type");
- }
-
- NJson::TJsonValue postData;
-
- if (!NJson::ReadJsonTree(Request.GetPostContent(), &postData)) {
- return ReplyErrorAndPassAway("400 Bad Request", "Invalid JSON data");
- }
-
- ReplyDeleteCookieAndPassAway();
- }
-
- void HandlePoisonPill(TEvents::TEvPoisonPill::TPtr&) {
- PassAway();
- }
-
- void HandleTimeout() {
- ReplyErrorAndPassAway("504 Gateway Timeout", "Timeout");
- }
-
- void ReplyOptionsAndPassAway() {
- Result.SetValue(MakeHolder<NMon::TEvHttpInfoRes>(
- "HTTP/1.1 204 No Content\r\n"
- "Allow: OPTIONS, POST\r\n"
- "Connection: Keep-Alive\r\n\r\n", 0, NMon::IEvHttpInfoRes::EContentType::Custom));
- PassAway();
- }
-
- void ReplyDeleteCookieAndPassAway() {
- TStringStream response;
- response << "HTTP/1.1 200 OK\r\n";
- response << "Set-Cookie: ydb_session_id=; Max-Age=0\r\n";
- response << "\r\n";
- Result.SetValue(MakeHolder<NMon::TEvHttpInfoRes>(response.Str(), 0, NMon::IEvHttpInfoRes::EContentType::Custom));
- PassAway();
- }
-
- void ReplyErrorAndPassAway(const TString& status, const TString& error) {
- NJson::TJsonValue body;
- body["error"] = error;
- TStringStream response;
- TString responseBody = NJson::WriteJson(body, false);
- response << "HTTP/1.1 " << status << "\r\n";
- response << "Content-Type: application/json\r\n";
- response << "Content-Length: " << responseBody.Size() << "\r\n";
- response << "\r\n";
- response << responseBody;
- Result.SetValue(MakeHolder<NMon::TEvHttpInfoRes>(response.Str(), 0, NMon::IEvHttpInfoRes::EContentType::Custom));
- PassAway();
- }
-
-protected:
- IMonHttpRequest& Request;
- NThreading::TPromise<THttpResponsePtr> Result;
- TDuration Timeout = TDuration::Seconds(60);
-};
-
-class TLogoutMonPage: public IMonPage {
-public:
- TLogoutMonPage(TActorSystem* actorSystem, const TString& path)
- : IMonPage(path, {})
- , ActorSystem(actorSystem)
- {
- }
-
- void Output(IMonHttpRequest &request) override {
- auto promise = NThreading::NewPromise<THttpResponsePtr>();
- auto future = promise.GetFuture();
-
- ActorSystem->Register(new TLogoutRequest(request, promise));
-
- THttpResponsePtr result = future.ExtractValue(TDuration::Max());
-
- if (result) {
- Output(request, *result);
- }
- }
-
-private:
- void Output(IMonHttpRequest& request, const NMon::IEvHttpInfoRes& result) const {
- result.Output(request.Output());
- }
-
-private:
- TActorSystem* ActorSystem;
-};
-
-}
-
-namespace NKikimr {
-
-IMonPage* CreateLoginPage(TActorSystem* actorSystem, const TString& path) {
- return new TLoginMonPage(actorSystem, path);
-}
-
-IMonPage* CreateLogoutPage(TActorSystem* actorSystem, const TString& path) {
- return new TLogoutMonPage(actorSystem, path);
-}
-
-}
+
+#include <ydb/library/login/login.h>
+#include <ydb/library/security/util.h>
+
+namespace {
+
+using namespace NActors;
+using namespace NKikimr;
+using namespace NSchemeShard;
+using namespace NMonitoring;
+
+using THttpResponsePtr = THolder<NMon::IEvHttpInfoRes>;
+
+class TLoginRequest : public NActors::TActorBootstrapped<TLoginRequest> {
+public:
+ static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
+ return NKikimrServices::TActivity::ACTORLIB_COMMON;
+ }
+
+ TLoginRequest(IMonHttpRequest& request, NThreading::TPromise<THttpResponsePtr> result)
+ : Request(request)
+ , Result(result)
+ {
+ }
+
+ ~TLoginRequest() {
+ if (!Result.HasValue()) {
+ Result.SetValue(nullptr);
+ }
+ }
+
+ STATEFN(StateWork) {
+ switch (ev->GetTypeRewrite()) {
+ hFunc(TEvents::TEvPoisonPill, HandlePoisonPill);
+ hFunc(TEvTabletPipe::TEvClientConnected, HandleConnect);
+ hFunc(TEvTxProxySchemeCache::TEvNavigateKeySetResult, HandleNavigate);
+ hFunc(TEvSchemeShard::TEvLoginResult, HandleResult);
+ cFunc(TEvents::TSystem::Wakeup, HandleTimeout);
+ }
+ }
+
+ static TString GetMethod(HTTP_METHOD method) {
+ switch (method) {
+ case HTTP_METHOD_UNDEFINED: return "UNDEFINED";
+ case HTTP_METHOD_OPTIONS: return "OPTIONS";
+ case HTTP_METHOD_GET: return "GET";
+ case HTTP_METHOD_HEAD: return "HEAD";
+ case HTTP_METHOD_POST: return "POST";
+ case HTTP_METHOD_PUT: return "PUT";
+ case HTTP_METHOD_DELETE: return "DELETE";
+ case HTTP_METHOD_TRACE: return "TRACE";
+ case HTTP_METHOD_CONNECT: return "CONNECT";
+ case HTTP_METHOD_EXTENSION: return "EXTENSION";
+ default: return "UNKNOWN";
+ }
+ }
+
+ void Bootstrap() {
+ LOG_WARN_S(*TlsActivationContext, NKikimrServices::HTTP,
+ Request.GetRemoteAddr()
+ << " " << GetMethod(Request.GetMethod())
+ << " " << Request.GetUri());
+
+ if (Request.GetMethod() == HTTP_METHOD_OPTIONS) {
+ return ReplyOptionsAndPassAway();
+ }
+
+ if (Request.GetMethod() != HTTP_METHOD_POST) {
+ return ReplyErrorAndPassAway("400 Bad Request", "Invalid method");
+ }
+
+ if (Request.GetHeader("Content-Type") != "application/json") {
+ return ReplyErrorAndPassAway("400 Bad Request", "Invalid Content-Type");
+ }
+
+ NJson::TJsonValue postData;
+
+ if (!NJson::ReadJsonTree(Request.GetPostContent(), &postData)) {
+ return ReplyErrorAndPassAway("400 Bad Request", "Invalid JSON data");
+ }
+
+ if (postData.Has("database")) {
+ Database = postData["database"].GetStringRobust();
+ } else {
+ TDomainsInfo* domainsInfo = AppData()->DomainsInfo.Get();
+ const TDomainsInfo::TDomain& domain = *domainsInfo->Domains.begin()->second.Get();
+ Database = "/" + domain.Name;
+ }
+
+ NJson::TJsonValue* jsonUser;
+ if (postData.GetValuePointer("user", &jsonUser)) {
+ User = jsonUser->GetStringRobust();
+ } else {
+ return ReplyErrorAndPassAway("400 Bad Request", "User must be specified");
+ }
+
+ NJson::TJsonValue* jsonPassword;
+ if (postData.GetValuePointer("password", &jsonPassword)) {
+ Password = jsonPassword->GetStringRobust();
+ } else {
+ return ReplyErrorAndPassAway("400 Bad Request", "Password must be specified");
+ }
+
+ auto request = MakeHolder<NSchemeCache::TSchemeCacheNavigate>();
+ request->DatabaseName = Database;
+ auto& entry = request->ResultSet.emplace_back();
+ entry.Operation = NSchemeCache::TSchemeCacheNavigate::OpPath;
+ entry.Path = ::NKikimr::SplitPath(Database);
+ entry.RedirectRequired = false;
+ Send(MakeSchemeCacheID(), new TEvTxProxySchemeCache::TEvNavigateKeySet(request.Release()));
+
+ Become(&TThis::StateWork, Timeout, new TEvents::TEvWakeup());
+ }
+
+ static NTabletPipe::TClientConfig GetPipeClientConfig() {
+ NTabletPipe::TClientConfig clientConfig;
+ clientConfig.RetryPolicy = {.RetryLimitCount = 3};
+ return clientConfig;
+ }
+
+ void HandleNavigate(TEvTxProxySchemeCache::TEvNavigateKeySetResult::TPtr& ev) {
+ const NSchemeCache::TSchemeCacheNavigate* response = ev->Get()->Request.Get();
+ if (response->ResultSet.size() == 1) {
+ if (response->ResultSet.front().Status == NSchemeCache::TSchemeCacheNavigate::EStatus::Ok) {
+ const NSchemeCache::TSchemeCacheNavigate::TEntry& entry = response->ResultSet.front();
+ ui64 schemeShardTabletId = entry.DomainInfo->ExtractSchemeShard();
+ IActor* pipe = NTabletPipe::CreateClient(SelfId(), schemeShardTabletId, GetPipeClientConfig());
+ TActorId pipeClient = RegisterWithSameMailbox(pipe);
+ THolder<TEvSchemeShard::TEvLogin> request = MakeHolder<TEvSchemeShard::TEvLogin>();
+ request.Get()->Record.SetUser(User);
+ request.Get()->Record.SetPassword(Password);
+ NTabletPipe::SendData(SelfId(), pipeClient, request.Release());
+ return;
+ } else {
+ ReplyErrorAndPassAway("503 Service Unavailable", TStringBuilder()
+ << "Status " << static_cast<int>(response->ResultSet.front().Status));
+ }
+ } else {
+ ReplyErrorAndPassAway("503 Service Unavailable", "Scheme error");
+ }
+ }
+
+ void HandleResult(TEvSchemeShard::TEvLoginResult::TPtr& ev) {
+ if (ev->Get()->Record.GetError()) {
+ ReplyErrorAndPassAway("403 Forbidden", ev->Get()->Record.GetError());
+ } else {
+ ReplyCookieAndPassAway(ev->Get()->Record.GetToken());
+ }
+ }
+
+ void HandleConnect(TEvTabletPipe::TEvClientConnected::TPtr& ev) {
+ if (ev->Get()->Status != NKikimrProto::OK) {
+ ReplyErrorAndPassAway("503 Service Unavailable", "SchemeShard is not available");
+ }
+ }
+
+ void HandlePoisonPill(TEvents::TEvPoisonPill::TPtr&) {
+ PassAway();
+ }
+
+ void HandleTimeout() {
+ ReplyErrorAndPassAway("504 Gateway Timeout", "Timeout");
+ }
+
+ void ReplyOptionsAndPassAway() {
+ Result.SetValue(MakeHolder<NMon::TEvHttpInfoRes>(
+ "HTTP/1.1 204 No Content\r\n"
+ "Allow: OPTIONS, POST\r\n"
+ "Connection: Keep-Alive\r\n\r\n", 0, NMon::IEvHttpInfoRes::EContentType::Custom));
+ PassAway();
+ }
+
+ void ReplyCookieAndPassAway(const TString& cookie) {
+ TStringStream response;
+ TDuration maxAge = (ToInstant(NLogin::TLoginProvider::GetTokenExpiresAt(cookie)) - TInstant::Now());
+ response << "HTTP/1.1 200 OK\r\n";
+ response << "Set-Cookie: ydb_session_id=" << cookie << "; Max-Age=" << maxAge.Seconds() << "\r\n";
+ response << "\r\n";
+ Result.SetValue(MakeHolder<NMon::TEvHttpInfoRes>(response.Str(), 0, NMon::IEvHttpInfoRes::EContentType::Custom));
+ PassAway();
+ }
+
+ void ReplyErrorAndPassAway(const TString& status, const TString& error) {
+ NJson::TJsonValue body;
+ body["error"] = error;
+ TStringStream response;
+ TString responseBody = NJson::WriteJson(body, false);
+ response << "HTTP/1.1 " << status << "\r\n";
+ response << "Content-Type: application/json\r\n";
+ response << "Content-Length: " << responseBody.Size() << "\r\n";
+ response << "\r\n";
+ response << responseBody;
+ Result.SetValue(MakeHolder<NMon::TEvHttpInfoRes>(response.Str(), 0, NMon::IEvHttpInfoRes::EContentType::Custom));
+ PassAway();
+ }
+
+protected:
+ IMonHttpRequest& Request;
+ NThreading::TPromise<THttpResponsePtr> Result;
+ TDuration Timeout = TDuration::Seconds(60);
+ TString Database;
+ TString User;
+ TString Password;
+};
+
+class TLoginMonPage: public IMonPage {
+public:
+ TLoginMonPage(TActorSystem* actorSystem, const TString& path)
+ : IMonPage(path, {})
+ , ActorSystem(actorSystem)
+ {
+ }
+
+ void Output(IMonHttpRequest &request) override {
+ auto promise = NThreading::NewPromise<THttpResponsePtr>();
+ auto future = promise.GetFuture();
+
+ ActorSystem->Register(new TLoginRequest(request, promise));
+
+ THttpResponsePtr result = future.ExtractValue(TDuration::Max());
+
+ if (result) {
+ Output(request, *result);
+ }
+ }
+
+private:
+ void Output(IMonHttpRequest& request, const NMon::IEvHttpInfoRes& result) const {
+ result.Output(request.Output());
+ }
+
+private:
+ TActorSystem* ActorSystem;
+};
+
+class TLogoutRequest : public NActors::TActorBootstrapped<TLogoutRequest> {
+public:
+ static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
+ return NKikimrServices::TActivity::ACTORLIB_COMMON;
+ }
+
+ TLogoutRequest(IMonHttpRequest& request, NThreading::TPromise<THttpResponsePtr> result)
+ : Request(request)
+ , Result(result)
+ {
+ }
+
+ ~TLogoutRequest() {
+ if (!Result.HasValue()) {
+ Result.SetValue(nullptr);
+ }
+ }
+
+ STATEFN(StateWork) {
+ switch (ev->GetTypeRewrite()) {
+ hFunc(TEvents::TEvPoisonPill, HandlePoisonPill);
+ cFunc(TEvents::TSystem::Wakeup, HandleTimeout);
+ }
+ }
+
+ static TString GetMethod(HTTP_METHOD method) {
+ switch (method) {
+ case HTTP_METHOD_UNDEFINED: return "UNDEFINED";
+ case HTTP_METHOD_OPTIONS: return "OPTIONS";
+ case HTTP_METHOD_GET: return "GET";
+ case HTTP_METHOD_HEAD: return "HEAD";
+ case HTTP_METHOD_POST: return "POST";
+ case HTTP_METHOD_PUT: return "PUT";
+ case HTTP_METHOD_DELETE: return "DELETE";
+ case HTTP_METHOD_TRACE: return "TRACE";
+ case HTTP_METHOD_CONNECT: return "CONNECT";
+ case HTTP_METHOD_EXTENSION: return "EXTENSION";
+ default: return "UNKNOWN";
+ }
+ }
+
+ void Bootstrap() {
+ LOG_WARN_S(*TlsActivationContext, NKikimrServices::HTTP,
+ Request.GetRemoteAddr()
+ << " " << GetMethod(Request.GetMethod())
+ << " " << Request.GetUri());
+
+ if (Request.GetMethod() == HTTP_METHOD_OPTIONS) {
+ return ReplyOptionsAndPassAway();
+ }
+
+ if (Request.GetMethod() != HTTP_METHOD_POST) {
+ return ReplyErrorAndPassAway("400 Bad Request", "Invalid method");
+ }
+
+ if (Request.GetHeader("Content-Type") != "application/json") {
+ return ReplyErrorAndPassAway("400 Bad Request", "Invalid Content-Type");
+ }
+
+ NJson::TJsonValue postData;
+
+ if (!NJson::ReadJsonTree(Request.GetPostContent(), &postData)) {
+ return ReplyErrorAndPassAway("400 Bad Request", "Invalid JSON data");
+ }
+
+ ReplyDeleteCookieAndPassAway();
+ }
+
+ void HandlePoisonPill(TEvents::TEvPoisonPill::TPtr&) {
+ PassAway();
+ }
+
+ void HandleTimeout() {
+ ReplyErrorAndPassAway("504 Gateway Timeout", "Timeout");
+ }
+
+ void ReplyOptionsAndPassAway() {
+ Result.SetValue(MakeHolder<NMon::TEvHttpInfoRes>(
+ "HTTP/1.1 204 No Content\r\n"
+ "Allow: OPTIONS, POST\r\n"
+ "Connection: Keep-Alive\r\n\r\n", 0, NMon::IEvHttpInfoRes::EContentType::Custom));
+ PassAway();
+ }
+
+ void ReplyDeleteCookieAndPassAway() {
+ TStringStream response;
+ response << "HTTP/1.1 200 OK\r\n";
+ response << "Set-Cookie: ydb_session_id=; Max-Age=0\r\n";
+ response << "\r\n";
+ Result.SetValue(MakeHolder<NMon::TEvHttpInfoRes>(response.Str(), 0, NMon::IEvHttpInfoRes::EContentType::Custom));
+ PassAway();
+ }
+
+ void ReplyErrorAndPassAway(const TString& status, const TString& error) {
+ NJson::TJsonValue body;
+ body["error"] = error;
+ TStringStream response;
+ TString responseBody = NJson::WriteJson(body, false);
+ response << "HTTP/1.1 " << status << "\r\n";
+ response << "Content-Type: application/json\r\n";
+ response << "Content-Length: " << responseBody.Size() << "\r\n";
+ response << "\r\n";
+ response << responseBody;
+ Result.SetValue(MakeHolder<NMon::TEvHttpInfoRes>(response.Str(), 0, NMon::IEvHttpInfoRes::EContentType::Custom));
+ PassAway();
+ }
+
+protected:
+ IMonHttpRequest& Request;
+ NThreading::TPromise<THttpResponsePtr> Result;
+ TDuration Timeout = TDuration::Seconds(60);
+};
+
+class TLogoutMonPage: public IMonPage {
+public:
+ TLogoutMonPage(TActorSystem* actorSystem, const TString& path)
+ : IMonPage(path, {})
+ , ActorSystem(actorSystem)
+ {
+ }
+
+ void Output(IMonHttpRequest &request) override {
+ auto promise = NThreading::NewPromise<THttpResponsePtr>();
+ auto future = promise.GetFuture();
+
+ ActorSystem->Register(new TLogoutRequest(request, promise));
+
+ THttpResponsePtr result = future.ExtractValue(TDuration::Max());
+
+ if (result) {
+ Output(request, *result);
+ }
+ }
+
+private:
+ void Output(IMonHttpRequest& request, const NMon::IEvHttpInfoRes& result) const {
+ result.Output(request.Output());
+ }
+
+private:
+ TActorSystem* ActorSystem;
+};
+
+}
+
+namespace NKikimr {
+
+IMonPage* CreateLoginPage(TActorSystem* actorSystem, const TString& path) {
+ return new TLoginMonPage(actorSystem, path);
+}
+
+IMonPage* CreateLogoutPage(TActorSystem* actorSystem, const TString& path) {
+ return new TLogoutMonPage(actorSystem, path);
+}
+
+}
diff --git a/ydb/core/security/login_page.h b/ydb/core/security/login_page.h
index e9c21ab7b91..fcf80e8c991 100644
--- a/ydb/core/security/login_page.h
+++ b/ydb/core/security/login_page.h
@@ -1,9 +1,9 @@
-#include <library/cpp/monlib/service/pages/mon_page.h>
-#include <library/cpp/actors/core/actorsystem.h>
-
-namespace NKikimr {
-
-NMonitoring::IMonPage* CreateLoginPage(NActors::TActorSystem* actorSystem, const TString& path = "login");
-NMonitoring::IMonPage* CreateLogoutPage(NActors::TActorSystem* actorSystem, const TString& path = "logout");
-
-}
+#include <library/cpp/monlib/service/pages/mon_page.h>
+#include <library/cpp/actors/core/actorsystem.h>
+
+namespace NKikimr {
+
+NMonitoring::IMonPage* CreateLoginPage(NActors::TActorSystem* actorSystem, const TString& path = "login");
+NMonitoring::IMonPage* CreateLogoutPage(NActors::TActorSystem* actorSystem, const TString& path = "logout");
+
+}
diff --git a/ydb/core/security/secure_request.h b/ydb/core/security/secure_request.h
index 16dc4530fe6..04e276a8971 100644
--- a/ydb/core/security/secure_request.h
+++ b/ydb/core/security/secure_request.h
@@ -1,181 +1,181 @@
-#pragma once
-#include "ticket_parser.h"
+#pragma once
+#include "ticket_parser.h"
#include <ydb/library/aclib/aclib.h>
#include <ydb/core/base/appdata.h>
-
-namespace NKikimr {
-
-template <typename TBase, typename TDerived, typename TBootstrap = TDerived>
-class TSecureRequestActor : public TBase {
-private:
- TString Database;
- TString SecurityToken;
- TString PeerName;
- THolder<TEvTicketParser::TEvAuthorizeTicketResult> AuthorizeTicketResult;
- bool RequireAdminAccess = false;
- bool UserAdmin = false;
+
+namespace NKikimr {
+
+template <typename TBase, typename TDerived, typename TBootstrap = TDerived>
+class TSecureRequestActor : public TBase {
+private:
+ TString Database;
+ TString SecurityToken;
+ TString PeerName;
+ THolder<TEvTicketParser::TEvAuthorizeTicketResult> AuthorizeTicketResult;
+ bool RequireAdminAccess = false;
+ bool UserAdmin = false;
TVector<TEvTicketParser::TEvAuthorizeTicket::TEntry> Entries;
-
- static bool GetEnforceUserTokenRequirement() {
- return AppData()->EnforceUserTokenRequirement;
- }
-
- static const TVector<TString>& GetAdministrationAllowedSIDs() {
- return AppData()->AdministrationAllowedSIDs;
- }
-
- static const TVector<TString>& GetDefaultUserSIDs() {
- return AppData()->DefaultUserSIDs;
- }
-
- bool IsTokenExists() const {
- return !SecurityToken.empty() || !GetDefaultUserSIDs().empty();
- }
-
- void Handle(TEvTicketParser::TEvAuthorizeTicketResult::TPtr& ev, const TActorContext& ctx) {
- const TEvTicketParser::TEvAuthorizeTicketResult& result(*ev->Get());
- if (!result.Error.empty()) {
- if (IsTokenRequired()) {
+
+ static bool GetEnforceUserTokenRequirement() {
+ return AppData()->EnforceUserTokenRequirement;
+ }
+
+ static const TVector<TString>& GetAdministrationAllowedSIDs() {
+ return AppData()->AdministrationAllowedSIDs;
+ }
+
+ static const TVector<TString>& GetDefaultUserSIDs() {
+ return AppData()->DefaultUserSIDs;
+ }
+
+ bool IsTokenExists() const {
+ return !SecurityToken.empty() || !GetDefaultUserSIDs().empty();
+ }
+
+ void Handle(TEvTicketParser::TEvAuthorizeTicketResult::TPtr& ev, const TActorContext& ctx) {
+ const TEvTicketParser::TEvAuthorizeTicketResult& result(*ev->Get());
+ if (!result.Error.empty()) {
+ if (IsTokenRequired()) {
return static_cast<TDerived*>(this)->OnAccessDenied(result.Error, ctx);
- }
- } else {
- if (RequireAdminAccess) {
- if (!GetAdministrationAllowedSIDs().empty()) {
- const auto& allowedSIDs(GetAdministrationAllowedSIDs());
- if (std::find_if(allowedSIDs.begin(), allowedSIDs.end(), [&result](const TString& sid) -> bool { return result.Token->IsExist(sid); }) == allowedSIDs.end()) {
+ }
+ } else {
+ if (RequireAdminAccess) {
+ if (!GetAdministrationAllowedSIDs().empty()) {
+ const auto& allowedSIDs(GetAdministrationAllowedSIDs());
+ if (std::find_if(allowedSIDs.begin(), allowedSIDs.end(), [&result](const TString& sid) -> bool { return result.Token->IsExist(sid); }) == allowedSIDs.end()) {
return static_cast<TDerived*>(this)->OnAccessDenied(TEvTicketParser::TError{"Administrative access denied", false}, ctx);
- }
- }
- UserAdmin = true;
- }
- }
- AuthorizeTicketResult = ev.Get()->Release();
- static_cast<TBootstrap*>(this)->Bootstrap(ctx);
- }
-
- void Handle(TEvents::TEvUndelivered::TPtr&, const TActorContext& ctx) {
- if (IsTokenRequired()) {
+ }
+ }
+ UserAdmin = true;
+ }
+ }
+ AuthorizeTicketResult = ev.Get()->Release();
+ static_cast<TBootstrap*>(this)->Bootstrap(ctx);
+ }
+
+ void Handle(TEvents::TEvUndelivered::TPtr&, const TActorContext& ctx) {
+ if (IsTokenRequired()) {
return static_cast<TDerived*>(this)->OnAccessDenied(TEvTicketParser::TError{"Access denied - error parsing token", false}, ctx);
- }
- static_cast<TBootstrap*>(this)->Bootstrap(ctx);
- }
-
-public:
+ }
+ static_cast<TBootstrap*>(this)->Bootstrap(ctx);
+ }
+
+public:
static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
return NKikimrServices::TActivity::GRPC_REQ_AUTH;
}
- template <typename... Args>
- TSecureRequestActor(Args&&... args)
- : TBase(std::forward<Args>(args)...)
- {}
-
- void SetDatabase(const TString& database) {
- Database = database;
- }
-
- void SetSecurityToken(const TString& securityToken) {
- SecurityToken = securityToken;
- }
-
- void SetPeerName(const TString& peerName) {
- PeerName = peerName;
- }
-
- void SetRequireAdminAccess(bool requireAdminAccess) {
- RequireAdminAccess = requireAdminAccess;
- }
-
+ template <typename... Args>
+ TSecureRequestActor(Args&&... args)
+ : TBase(std::forward<Args>(args)...)
+ {}
+
+ void SetDatabase(const TString& database) {
+ Database = database;
+ }
+
+ void SetSecurityToken(const TString& securityToken) {
+ SecurityToken = securityToken;
+ }
+
+ void SetPeerName(const TString& peerName) {
+ PeerName = peerName;
+ }
+
+ void SetRequireAdminAccess(bool requireAdminAccess) {
+ RequireAdminAccess = requireAdminAccess;
+ }
+
void SetEntries(const TVector<TEvTicketParser::TEvAuthorizeTicket::TEntry>& entries) {
Entries = entries;
}
const TVector<TEvTicketParser::TEvAuthorizeTicket::TEntry>& GetEntries() const {
return Entries;
- }
-
- const TEvTicketParser::TEvAuthorizeTicketResult* GetAuthorizeTicketResult() const {
- return AuthorizeTicketResult.Get();
- }
-
- TString GetSecurityToken() const {
- return SecurityToken;
- }
-
- TString GetSerializedToken() const {
- if (AuthorizeTicketResult) {
- if (AuthorizeTicketResult->SerializedToken) {
- return AuthorizeTicketResult->SerializedToken;
- }
- }
- return TString();
- }
-
- TString GetUserSID() const {
- if (AuthorizeTicketResult) {
- if (AuthorizeTicketResult->Token) {
- return AuthorizeTicketResult->Token->GetUserSID();
- }
- }
- const TVector<TString>& defaultUserSIDs = GetDefaultUserSIDs();
- if (!defaultUserSIDs.empty()) {
- return defaultUserSIDs.front();
- }
- return BUILTIN_ACL_ROOT;
- }
-
- bool IsUserAdmin() const {
- return UserAdmin;
- }
-
-public:
+ }
+
+ const TEvTicketParser::TEvAuthorizeTicketResult* GetAuthorizeTicketResult() const {
+ return AuthorizeTicketResult.Get();
+ }
+
+ TString GetSecurityToken() const {
+ return SecurityToken;
+ }
+
+ TString GetSerializedToken() const {
+ if (AuthorizeTicketResult) {
+ if (AuthorizeTicketResult->SerializedToken) {
+ return AuthorizeTicketResult->SerializedToken;
+ }
+ }
+ return TString();
+ }
+
+ TString GetUserSID() const {
+ if (AuthorizeTicketResult) {
+ if (AuthorizeTicketResult->Token) {
+ return AuthorizeTicketResult->Token->GetUserSID();
+ }
+ }
+ const TVector<TString>& defaultUserSIDs = GetDefaultUserSIDs();
+ if (!defaultUserSIDs.empty()) {
+ return defaultUserSIDs.front();
+ }
+ return BUILTIN_ACL_ROOT;
+ }
+
+ bool IsUserAdmin() const {
+ return UserAdmin;
+ }
+
+public:
bool IsTokenRequired() const {
return GetEnforceUserTokenRequirement() || (RequireAdminAccess && !GetAdministrationAllowedSIDs().empty());
}
- void Bootstrap(const TActorContext& ctx) {
- if (IsTokenRequired() && !IsTokenExists()) {
+ void Bootstrap(const TActorContext& ctx) {
+ if (IsTokenRequired() && !IsTokenExists()) {
return static_cast<TDerived*>(this)->OnAccessDenied(TEvTicketParser::TError{"Access denied without user token", false}, ctx);
- }
- if (SecurityToken.empty()) {
- if (!GetDefaultUserSIDs().empty()) {
- TIntrusivePtr<NACLib::TUserToken> userToken = new NACLib::TUserToken(GetDefaultUserSIDs());
- THolder<TEvTicketParser::TEvAuthorizeTicketResult> AuthorizeTicketResult = MakeHolder<TEvTicketParser::TEvAuthorizeTicketResult>(TString(), userToken, userToken->SerializeAsString());
- ctx.Send(ctx.SelfID, AuthorizeTicketResult.Release());
- } else {
- return static_cast<TBootstrap*>(this)->Bootstrap(ctx);
- }
- } else {
- ctx.Send(MakeTicketParserID(), new TEvTicketParser::TEvAuthorizeTicket({
- .Database = Database,
- .Ticket = SecurityToken,
- .PeerName = PeerName,
- .Entries = Entries
- }));
- }
- TBase::Become(&TSecureRequestActor::StateWaitForTicket);
- }
-
- STFUNC(StateWaitForTicket) {
- switch (ev->GetTypeRewrite()) {
- HFunc(TEvTicketParser::TEvAuthorizeTicketResult, Handle);
- HFunc(TEvents::TEvUndelivered, Handle);
- }
- }
-};
-
-template <typename TDerived>
-class TActorBootstrappedSecureRequest : public TSecureRequestActor<TActorBootstrapped<TActorBootstrappedSecureRequest<TDerived>>, TDerived> {
-public:
- template <typename... Args>
- TActorBootstrappedSecureRequest(Args&&... args)
- : TSecureRequestActor<TActorBootstrapped<TActorBootstrappedSecureRequest<TDerived>>, TDerived>(std::forward<Args>(args)...)
- {}
-
- void Bootstrap(const TActorContext& ctx) {
- TSecureRequestActor<TActorBootstrapped<TActorBootstrappedSecureRequest<TDerived>>, TDerived>::Bootstrap(ctx);
- }
-};
-
-}
-
+ }
+ if (SecurityToken.empty()) {
+ if (!GetDefaultUserSIDs().empty()) {
+ TIntrusivePtr<NACLib::TUserToken> userToken = new NACLib::TUserToken(GetDefaultUserSIDs());
+ THolder<TEvTicketParser::TEvAuthorizeTicketResult> AuthorizeTicketResult = MakeHolder<TEvTicketParser::TEvAuthorizeTicketResult>(TString(), userToken, userToken->SerializeAsString());
+ ctx.Send(ctx.SelfID, AuthorizeTicketResult.Release());
+ } else {
+ return static_cast<TBootstrap*>(this)->Bootstrap(ctx);
+ }
+ } else {
+ ctx.Send(MakeTicketParserID(), new TEvTicketParser::TEvAuthorizeTicket({
+ .Database = Database,
+ .Ticket = SecurityToken,
+ .PeerName = PeerName,
+ .Entries = Entries
+ }));
+ }
+ TBase::Become(&TSecureRequestActor::StateWaitForTicket);
+ }
+
+ STFUNC(StateWaitForTicket) {
+ switch (ev->GetTypeRewrite()) {
+ HFunc(TEvTicketParser::TEvAuthorizeTicketResult, Handle);
+ HFunc(TEvents::TEvUndelivered, Handle);
+ }
+ }
+};
+
+template <typename TDerived>
+class TActorBootstrappedSecureRequest : public TSecureRequestActor<TActorBootstrapped<TActorBootstrappedSecureRequest<TDerived>>, TDerived> {
+public:
+ template <typename... Args>
+ TActorBootstrappedSecureRequest(Args&&... args)
+ : TSecureRequestActor<TActorBootstrapped<TActorBootstrappedSecureRequest<TDerived>>, TDerived>(std::forward<Args>(args)...)
+ {}
+
+ void Bootstrap(const TActorContext& ctx) {
+ TSecureRequestActor<TActorBootstrapped<TActorBootstrappedSecureRequest<TDerived>>, TDerived>::Bootstrap(ctx);
+ }
+};
+
+}
+
diff --git a/ydb/core/security/ticket_parser.cpp b/ydb/core/security/ticket_parser.cpp
index fcf54f1a420..c7d024d03dc 100644
--- a/ydb/core/security/ticket_parser.cpp
+++ b/ydb/core/security/ticket_parser.cpp
@@ -4,616 +4,616 @@
#include <library/cpp/actors/core/hfunc.h>
#include <library/cpp/digest/md5/md5.h>
#include <library/cpp/openssl/init/init.h>
-#include <library/cpp/string_utils/base64/base64.h>
+#include <library/cpp/string_utils/base64/base64.h>
#include <ydb/core/base/appdata.h>
#include <ydb/core/base/counters.h>
#include <ydb/core/mon/mon.h>
#include <ydb/library/security/util.h>
-#include <util/generic/queue.h>
-#include <util/generic/deque.h>
-#include <util/stream/file.h>
-#include <util/string/vector.h>
-#include "ticket_parser.h"
-
-namespace NKikimr {
-
-class TTicketParser : public TActorBootstrapped<TTicketParser> {
- using TThis = TTicketParser;
- using TBase = TActorBootstrapped<TTicketParser>;
-
- NKikimrProto::TAuthConfig Config;
- TString DomainName;
-
- NMonitoring::TDynamicCounters::TCounterPtr CounterTicketsReceived;
- NMonitoring::TDynamicCounters::TCounterPtr CounterTicketsSuccess;
- NMonitoring::TDynamicCounters::TCounterPtr CounterTicketsErrors;
- NMonitoring::TDynamicCounters::TCounterPtr CounterTicketsErrorsRetryable;
- NMonitoring::TDynamicCounters::TCounterPtr CounterTicketsErrorsPermanent;
- NMonitoring::TDynamicCounters::TCounterPtr CounterTicketsBuiltin;
- NMonitoring::TDynamicCounters::TCounterPtr CounterTicketsLogin;
- NMonitoring::TDynamicCounters::TCounterPtr CounterTicketsCacheHit;
- NMonitoring::TDynamicCounters::TCounterPtr CounterTicketsCacheMiss;
- NMonitoring::THistogramPtr CounterTicketsBuildTime;
-
- TDuration RefreshPeriod = TDuration::Seconds(1); // how often do we check for ticket freshness/expiration
- TDuration LifeTime = TDuration::Hours(1); // for how long ticket will remain in the cache after last access
- TDuration ExpireTime = TDuration::Hours(24); // after what time ticket will expired and removed from cache
-
- enum class ETokenType {
- Unknown,
- Unsupported,
- Builtin,
- Login,
- };
-
- ETokenType ParseTokenType(TStringBuf tokenType) {
- if (tokenType == "Login") {
- if (UseLoginProvider) {
- return ETokenType::Login;
- } else {
- return ETokenType::Unsupported;
- }
- }
- return ETokenType::Unknown;
- }
-
- struct TTokenRecord {
- TTokenRecord(const TTokenRecord&) = delete;
- TTokenRecord& operator =(const TTokenRecord&) = delete;
-
- TString Ticket;
- TString Subject; // login
- TEvTicketParser::TError Error;
- TIntrusivePtr<NACLib::TUserToken> Token;
+#include <util/generic/queue.h>
+#include <util/generic/deque.h>
+#include <util/stream/file.h>
+#include <util/string/vector.h>
+#include "ticket_parser.h"
+
+namespace NKikimr {
+
+class TTicketParser : public TActorBootstrapped<TTicketParser> {
+ using TThis = TTicketParser;
+ using TBase = TActorBootstrapped<TTicketParser>;
+
+ NKikimrProto::TAuthConfig Config;
+ TString DomainName;
+
+ NMonitoring::TDynamicCounters::TCounterPtr CounterTicketsReceived;
+ NMonitoring::TDynamicCounters::TCounterPtr CounterTicketsSuccess;
+ NMonitoring::TDynamicCounters::TCounterPtr CounterTicketsErrors;
+ NMonitoring::TDynamicCounters::TCounterPtr CounterTicketsErrorsRetryable;
+ NMonitoring::TDynamicCounters::TCounterPtr CounterTicketsErrorsPermanent;
+ NMonitoring::TDynamicCounters::TCounterPtr CounterTicketsBuiltin;
+ NMonitoring::TDynamicCounters::TCounterPtr CounterTicketsLogin;
+ NMonitoring::TDynamicCounters::TCounterPtr CounterTicketsCacheHit;
+ NMonitoring::TDynamicCounters::TCounterPtr CounterTicketsCacheMiss;
+ NMonitoring::THistogramPtr CounterTicketsBuildTime;
+
+ TDuration RefreshPeriod = TDuration::Seconds(1); // how often do we check for ticket freshness/expiration
+ TDuration LifeTime = TDuration::Hours(1); // for how long ticket will remain in the cache after last access
+ TDuration ExpireTime = TDuration::Hours(24); // after what time ticket will expired and removed from cache
+
+ enum class ETokenType {
+ Unknown,
+ Unsupported,
+ Builtin,
+ Login,
+ };
+
+ ETokenType ParseTokenType(TStringBuf tokenType) {
+ if (tokenType == "Login") {
+ if (UseLoginProvider) {
+ return ETokenType::Login;
+ } else {
+ return ETokenType::Unsupported;
+ }
+ }
+ return ETokenType::Unknown;
+ }
+
+ struct TTokenRecord {
+ TTokenRecord(const TTokenRecord&) = delete;
+ TTokenRecord& operator =(const TTokenRecord&) = delete;
+
+ TString Ticket;
+ TString Subject; // login
+ TEvTicketParser::TError Error;
+ TIntrusivePtr<NACLib::TUserToken> Token;
TString SerializedToken;
- TDeque<THolder<TEventHandle<TEvTicketParser::TEvAuthorizeTicket>>> AuthorizeRequests;
- ui64 ResponsesLeft = 0;
- TInstant InitTime;
- TInstant ExpireTime;
- TInstant AccessTime;
- ETokenType TokenType = ETokenType::Unknown;
- TString PeerName;
- TString Database;
- TStackVec<TString> AdditionalSIDs;
-
- TString GetSubject() const {
- return Subject;
- }
-
- TTokenRecord(TStringBuf ticket)
- : Ticket(ticket)
- {}
-
- bool IsTokenReady() const {
- return Token != nullptr;
- }
-
- TString GetAuthType() const {
- switch (TokenType) {
- case ETokenType::Unknown:
- return "Unknown";
- case ETokenType::Unsupported:
- return "Unsupported";
- case ETokenType::Builtin:
- return "Builtin";
- case ETokenType::Login:
- return "Login";
- }
- }
- };
-
- struct TTokenRefreshRecord {
- TString Key;
- TInstant RefreshTime;
-
- bool operator <(const TTokenRefreshRecord& o) const {
- return RefreshTime > o.RefreshTime;
- }
- };
-
+ TDeque<THolder<TEventHandle<TEvTicketParser::TEvAuthorizeTicket>>> AuthorizeRequests;
+ ui64 ResponsesLeft = 0;
+ TInstant InitTime;
+ TInstant ExpireTime;
+ TInstant AccessTime;
+ ETokenType TokenType = ETokenType::Unknown;
+ TString PeerName;
+ TString Database;
+ TStackVec<TString> AdditionalSIDs;
+
+ TString GetSubject() const {
+ return Subject;
+ }
+
+ TTokenRecord(TStringBuf ticket)
+ : Ticket(ticket)
+ {}
+
+ bool IsTokenReady() const {
+ return Token != nullptr;
+ }
+
+ TString GetAuthType() const {
+ switch (TokenType) {
+ case ETokenType::Unknown:
+ return "Unknown";
+ case ETokenType::Unsupported:
+ return "Unsupported";
+ case ETokenType::Builtin:
+ return "Builtin";
+ case ETokenType::Login:
+ return "Login";
+ }
+ }
+ };
+
+ struct TTokenRefreshRecord {
+ TString Key;
+ TInstant RefreshTime;
+
+ bool operator <(const TTokenRefreshRecord& o) const {
+ return RefreshTime > o.RefreshTime;
+ }
+ };
+
THashMap<TString, TTokenRecord> UserTokens;
- TPriorityQueue<TTokenRefreshRecord> RefreshQueue;
- std::unordered_map<TString, NLogin::TLoginProvider> LoginProviders;
- bool UseLoginProvider = false;
-
- static TString GetKey(TEvTicketParser::TEvAuthorizeTicket* request) {
- TStringStream key;
- key << request->Ticket;
- key << ':';
- if (request->Database) {
- key << request->Database;
- key << ':';
- }
- for (const auto& entry : request->Entries) {
+ TPriorityQueue<TTokenRefreshRecord> RefreshQueue;
+ std::unordered_map<TString, NLogin::TLoginProvider> LoginProviders;
+ bool UseLoginProvider = false;
+
+ static TString GetKey(TEvTicketParser::TEvAuthorizeTicket* request) {
+ TStringStream key;
+ key << request->Ticket;
+ key << ':';
+ if (request->Database) {
+ key << request->Database;
+ key << ':';
+ }
+ for (const auto& entry : request->Entries) {
for (auto it = entry.Attributes.begin(); it != entry.Attributes.end(); ++it) {
if (it != entry.Attributes.begin()) {
key << '-';
}
key << it->second;
- }
+ }
key << ':';
for (auto it = entry.Permissions.begin(); it != entry.Permissions.end(); ++it) {
if (it != entry.Permissions.begin()) {
key << '-';
}
key << *it;
- }
- }
- return key.Str();
- }
-
- static TStringBuf GetTicketFromKey(TStringBuf key) {
- return key.Before(':');
- }
-
- TInstant GetExpireTime(TInstant now) {
- return now + ExpireTime;
- }
-
- TDuration GetLifeTime() {
- return LifeTime;
- }
-
- static void EnrichUserTokenWithBuiltins(const TTokenRecord& tokenRecord) {
- const TString& allAuthenticatedUsers = AppData()->AllAuthenticatedUsers;
- if (!allAuthenticatedUsers.empty()) {
- tokenRecord.Token->AddGroupSID(allAuthenticatedUsers);
- }
- for (const TString& sid : tokenRecord.AdditionalSIDs) {
- tokenRecord.Token->AddGroupSID(sid);
- }
- }
-
- void InitTokenRecord(const TString& key, TTokenRecord& record, const TActorContext& ctx) {
- TInstant now = ctx.Now();
- record.InitTime = now;
- record.AccessTime = now;
- record.ExpireTime = GetExpireTime(now);
-
- if (record.Error) {
- return;
- }
-
- if (record.TokenType == ETokenType::Unknown || record.TokenType == ETokenType::Builtin) {
- if(record.Ticket.EndsWith("@" BUILTIN_ACL_DOMAIN)) {
- record.TokenType = ETokenType::Builtin;
- SetToken(key, record, new NACLib::TUserToken({
- .OriginalUserToken = record.Ticket,
- .UserSID = record.Ticket,
- .AuthType = record.GetAuthType()
- }), ctx);
- CounterTicketsBuiltin->Inc();
+ }
+ }
+ return key.Str();
+ }
+
+ static TStringBuf GetTicketFromKey(TStringBuf key) {
+ return key.Before(':');
+ }
+
+ TInstant GetExpireTime(TInstant now) {
+ return now + ExpireTime;
+ }
+
+ TDuration GetLifeTime() {
+ return LifeTime;
+ }
+
+ static void EnrichUserTokenWithBuiltins(const TTokenRecord& tokenRecord) {
+ const TString& allAuthenticatedUsers = AppData()->AllAuthenticatedUsers;
+ if (!allAuthenticatedUsers.empty()) {
+ tokenRecord.Token->AddGroupSID(allAuthenticatedUsers);
+ }
+ for (const TString& sid : tokenRecord.AdditionalSIDs) {
+ tokenRecord.Token->AddGroupSID(sid);
+ }
+ }
+
+ void InitTokenRecord(const TString& key, TTokenRecord& record, const TActorContext& ctx) {
+ TInstant now = ctx.Now();
+ record.InitTime = now;
+ record.AccessTime = now;
+ record.ExpireTime = GetExpireTime(now);
+
+ if (record.Error) {
+ return;
+ }
+
+ if (record.TokenType == ETokenType::Unknown || record.TokenType == ETokenType::Builtin) {
+ if(record.Ticket.EndsWith("@" BUILTIN_ACL_DOMAIN)) {
+ record.TokenType = ETokenType::Builtin;
+ SetToken(key, record, new NACLib::TUserToken({
+ .OriginalUserToken = record.Ticket,
+ .UserSID = record.Ticket,
+ .AuthType = record.GetAuthType()
+ }), ctx);
+ CounterTicketsBuiltin->Inc();
return;
}
-
- if(record.Ticket.EndsWith("@" BUILTIN_ERROR_DOMAIN)) {
- record.TokenType = ETokenType::Builtin;
- SetError(key, record, {"Builtin error simulation"}, ctx);
- CounterTicketsBuiltin->Inc();
+
+ if(record.Ticket.EndsWith("@" BUILTIN_ERROR_DOMAIN)) {
+ record.TokenType = ETokenType::Builtin;
+ SetError(key, record, {"Builtin error simulation"}, ctx);
+ CounterTicketsBuiltin->Inc();
return;
}
}
- if (UseLoginProvider && (record.TokenType == ETokenType::Unknown || record.TokenType == ETokenType::Login)) {
- TString database = Config.GetDomainLoginOnly() ? DomainName : record.Database;
- auto itLoginProvider = LoginProviders.find(database);
- if (itLoginProvider != LoginProviders.end()) {
- NLogin::TLoginProvider& loginProvider(itLoginProvider->second);
- auto response = loginProvider.ValidateToken({.Token = record.Ticket});
- if (response.Error) {
- if (!response.TokenUnrecognized || record.TokenType != ETokenType::Unknown) {
- record.TokenType = ETokenType::Login;
- TEvTicketParser::TError error;
- error.Message = response.Error;
- error.Retryable = response.ErrorRetryable;
- SetError(key, record, error, ctx);
- CounterTicketsLogin->Inc();
- return;
- }
- } else {
- record.TokenType = ETokenType::Login;
- TVector<NACLib::TSID> groups;
- if (response.Groups.has_value()) {
- const std::vector<TString>& tokenGroups = response.Groups.value();
- groups.assign(tokenGroups.begin(), tokenGroups.end());
- } else {
- const std::vector<TString> providerGroups = loginProvider.GetGroupsMembership(response.User);
- groups.assign(providerGroups.begin(), providerGroups.end());
- }
- record.ExpireTime = ToInstant(response.ExpiresAt);
- SetToken(key, record, new NACLib::TUserToken({
- .OriginalUserToken = record.Ticket,
- .UserSID = response.User,
- .GroupSIDs = groups,
- .AuthType = record.GetAuthType()
- }), ctx);
- CounterTicketsLogin->Inc();
- return;
- }
- } else {
- if (record.TokenType == ETokenType::Login) {
- TEvTicketParser::TError error;
- error.Message = "Login state is not available yet";
- error.Retryable = false;
- SetError(key, record, error, ctx);
- CounterTicketsLogin->Inc();
- return;
- }
- }
- }
-
- if (record.TokenType == ETokenType::Unknown && record.ResponsesLeft == 0) {
- record.Error.Message = "Could not find correct token validator";
- record.Error.Retryable = false;
- }
- }
-
- void SetToken(const TString& key, TTokenRecord& record, TIntrusivePtr<NACLib::TUserToken> token, const TActorContext& ctx) {
- TInstant now = ctx.Now();
- record.Error.clear();
- record.Token = token;
- EnrichUserTokenWithBuiltins(record);
- if (!token->GetUserSID().empty()) {
- record.Subject = token->GetUserSID();
- }
- record.SerializedToken = token->SerializeAsString();
- if (!record.ExpireTime) {
- record.ExpireTime = GetExpireTime(now);
- }
- CounterTicketsSuccess->Inc();
- CounterTicketsBuildTime->Collect((now - record.InitTime).MilliSeconds());
- LOG_DEBUG_S(ctx, NKikimrServices::TICKET_PARSER, "Ticket " << MaskTicket(record.Ticket) << " ("
- << record.PeerName << ") has now valid token of " << record.Subject);
- RefreshQueue.push({key, record.ExpireTime});
- }
-
- void SetError(const TString& key, TTokenRecord& record, const TEvTicketParser::TError& error, const TActorContext& ctx) {
- record.Error = error;
- if (record.Error.Retryable) {
- record.ExpireTime = GetExpireTime(ctx.Now());
- CounterTicketsErrorsRetryable->Inc();
- LOG_DEBUG_S(ctx, NKikimrServices::TICKET_PARSER, "Ticket " << MaskTicket(record.Ticket) << " ("
- << record.PeerName << ") has now retryable error message '" << error.Message << "'");
- } else {
- record.Token = nullptr;
- record.SerializedToken.clear();
- CounterTicketsErrorsPermanent->Inc();
- LOG_DEBUG_S(ctx, NKikimrServices::TICKET_PARSER, "Ticket " << MaskTicket(record.Ticket) << " ("
- << record.PeerName << ") has now permanent error message '" << error.Message << "'");
- }
- CounterTicketsErrors->Inc();
- RefreshQueue.push({key, record.ExpireTime});
- }
-
- void Respond(TTokenRecord& record, const TActorContext& ctx) {
- if (record.IsTokenReady()) {
- for (const auto& request : record.AuthorizeRequests) {
- ctx.Send(request->Sender, new TEvTicketParser::TEvAuthorizeTicketResult(record.Ticket, record.Token, record.SerializedToken), 0, request->Cookie);
- }
- } else {
- for (const auto& request : record.AuthorizeRequests) {
- ctx.Send(request->Sender, new TEvTicketParser::TEvAuthorizeTicketResult(record.Ticket, record.Error), 0, request->Cookie);
- }
- }
- record.AuthorizeRequests.clear();
- }
-
- void CrackTicket(const TString& ticketBody, TStringBuf& ticket, TStringBuf& ticketType) {
- ticket = ticketBody;
- ticketType = ticket.NextTok(' ');
- if (ticket.empty()) {
- ticket = ticketBody;
- ticketType.Clear();
- }
- }
-
- void Handle(TEvTicketParser::TEvAuthorizeTicket::TPtr& ev, const TActorContext& ctx) {
- TStringBuf ticket;
- TStringBuf ticketType;
- CrackTicket(ev->Get()->Ticket, ticket, ticketType);
-
- TString key = GetKey(ev->Get());
+ if (UseLoginProvider && (record.TokenType == ETokenType::Unknown || record.TokenType == ETokenType::Login)) {
+ TString database = Config.GetDomainLoginOnly() ? DomainName : record.Database;
+ auto itLoginProvider = LoginProviders.find(database);
+ if (itLoginProvider != LoginProviders.end()) {
+ NLogin::TLoginProvider& loginProvider(itLoginProvider->second);
+ auto response = loginProvider.ValidateToken({.Token = record.Ticket});
+ if (response.Error) {
+ if (!response.TokenUnrecognized || record.TokenType != ETokenType::Unknown) {
+ record.TokenType = ETokenType::Login;
+ TEvTicketParser::TError error;
+ error.Message = response.Error;
+ error.Retryable = response.ErrorRetryable;
+ SetError(key, record, error, ctx);
+ CounterTicketsLogin->Inc();
+ return;
+ }
+ } else {
+ record.TokenType = ETokenType::Login;
+ TVector<NACLib::TSID> groups;
+ if (response.Groups.has_value()) {
+ const std::vector<TString>& tokenGroups = response.Groups.value();
+ groups.assign(tokenGroups.begin(), tokenGroups.end());
+ } else {
+ const std::vector<TString> providerGroups = loginProvider.GetGroupsMembership(response.User);
+ groups.assign(providerGroups.begin(), providerGroups.end());
+ }
+ record.ExpireTime = ToInstant(response.ExpiresAt);
+ SetToken(key, record, new NACLib::TUserToken({
+ .OriginalUserToken = record.Ticket,
+ .UserSID = response.User,
+ .GroupSIDs = groups,
+ .AuthType = record.GetAuthType()
+ }), ctx);
+ CounterTicketsLogin->Inc();
+ return;
+ }
+ } else {
+ if (record.TokenType == ETokenType::Login) {
+ TEvTicketParser::TError error;
+ error.Message = "Login state is not available yet";
+ error.Retryable = false;
+ SetError(key, record, error, ctx);
+ CounterTicketsLogin->Inc();
+ return;
+ }
+ }
+ }
+
+ if (record.TokenType == ETokenType::Unknown && record.ResponsesLeft == 0) {
+ record.Error.Message = "Could not find correct token validator";
+ record.Error.Retryable = false;
+ }
+ }
+
+ void SetToken(const TString& key, TTokenRecord& record, TIntrusivePtr<NACLib::TUserToken> token, const TActorContext& ctx) {
+ TInstant now = ctx.Now();
+ record.Error.clear();
+ record.Token = token;
+ EnrichUserTokenWithBuiltins(record);
+ if (!token->GetUserSID().empty()) {
+ record.Subject = token->GetUserSID();
+ }
+ record.SerializedToken = token->SerializeAsString();
+ if (!record.ExpireTime) {
+ record.ExpireTime = GetExpireTime(now);
+ }
+ CounterTicketsSuccess->Inc();
+ CounterTicketsBuildTime->Collect((now - record.InitTime).MilliSeconds());
+ LOG_DEBUG_S(ctx, NKikimrServices::TICKET_PARSER, "Ticket " << MaskTicket(record.Ticket) << " ("
+ << record.PeerName << ") has now valid token of " << record.Subject);
+ RefreshQueue.push({key, record.ExpireTime});
+ }
+
+ void SetError(const TString& key, TTokenRecord& record, const TEvTicketParser::TError& error, const TActorContext& ctx) {
+ record.Error = error;
+ if (record.Error.Retryable) {
+ record.ExpireTime = GetExpireTime(ctx.Now());
+ CounterTicketsErrorsRetryable->Inc();
+ LOG_DEBUG_S(ctx, NKikimrServices::TICKET_PARSER, "Ticket " << MaskTicket(record.Ticket) << " ("
+ << record.PeerName << ") has now retryable error message '" << error.Message << "'");
+ } else {
+ record.Token = nullptr;
+ record.SerializedToken.clear();
+ CounterTicketsErrorsPermanent->Inc();
+ LOG_DEBUG_S(ctx, NKikimrServices::TICKET_PARSER, "Ticket " << MaskTicket(record.Ticket) << " ("
+ << record.PeerName << ") has now permanent error message '" << error.Message << "'");
+ }
+ CounterTicketsErrors->Inc();
+ RefreshQueue.push({key, record.ExpireTime});
+ }
+
+ void Respond(TTokenRecord& record, const TActorContext& ctx) {
+ if (record.IsTokenReady()) {
+ for (const auto& request : record.AuthorizeRequests) {
+ ctx.Send(request->Sender, new TEvTicketParser::TEvAuthorizeTicketResult(record.Ticket, record.Token, record.SerializedToken), 0, request->Cookie);
+ }
+ } else {
+ for (const auto& request : record.AuthorizeRequests) {
+ ctx.Send(request->Sender, new TEvTicketParser::TEvAuthorizeTicketResult(record.Ticket, record.Error), 0, request->Cookie);
+ }
+ }
+ record.AuthorizeRequests.clear();
+ }
+
+ void CrackTicket(const TString& ticketBody, TStringBuf& ticket, TStringBuf& ticketType) {
+ ticket = ticketBody;
+ ticketType = ticket.NextTok(' ');
+ if (ticket.empty()) {
+ ticket = ticketBody;
+ ticketType.Clear();
+ }
+ }
+
+ void Handle(TEvTicketParser::TEvAuthorizeTicket::TPtr& ev, const TActorContext& ctx) {
+ TStringBuf ticket;
+ TStringBuf ticketType;
+ CrackTicket(ev->Get()->Ticket, ticket, ticketType);
+
+ TString key = GetKey(ev->Get());
TActorId sender = ev->Sender;
- ui64 cookie = ev->Cookie;
-
- CounterTicketsReceived->Inc();
- auto it = UserTokens.find(key);
- if (it != UserTokens.end()) {
- auto& record = it->second;
- // we know about token
- if (record.IsTokenReady()) {
- // token already have built
- record.AccessTime = ctx.Now();
- ctx.Send(sender, new TEvTicketParser::TEvAuthorizeTicketResult(ev->Get()->Ticket, record.Token, record.SerializedToken), 0, cookie);
- } else if (record.Error) {
- // token stores information about previous error
- record.AccessTime = ctx.Now();
- ctx.Send(sender, new TEvTicketParser::TEvAuthorizeTicketResult(ev->Get()->Ticket, record.Error), 0, cookie);
- } else {
- // token building in progress
- record.AuthorizeRequests.emplace_back(ev.Release());
- }
- CounterTicketsCacheHit->Inc();
- return;
- } else {
- it = UserTokens.emplace(key, ticket).first;
- CounterTicketsCacheMiss->Inc();
- }
-
- auto& record = it->second;
- record.PeerName = std::move(ev->Get()->PeerName);
- record.Database = std::move(ev->Get()->Database);
- if (ticketType) {
- record.TokenType = ParseTokenType(ticketType);
- switch (record.TokenType) {
- case ETokenType::Unsupported:
- record.Error.Message = "Token is not supported";
- record.Error.Retryable = false;
- break;
- case ETokenType::Unknown:
- record.Error.Message = "Unknown token";
- record.Error.Retryable = false;
- break;
- default:
- break;
- }
- }
- InitTokenRecord(key, record, ctx);
- if (record.Error) {
- LOG_ERROR_S(ctx, NKikimrServices::TICKET_PARSER, "Ticket " << MaskTicket(ticket) << ": " << record.Error);
- ctx.Send(sender, new TEvTicketParser::TEvAuthorizeTicketResult(ev->Get()->Ticket, record.Error), 0, cookie);
- return;
- }
- if (record.IsTokenReady()) {
- // offline check ready
- ctx.Send(sender, new TEvTicketParser::TEvAuthorizeTicketResult(ev->Get()->Ticket, record.Token, record.SerializedToken), 0, cookie);
- return;
- }
- record.AuthorizeRequests.emplace_back(ev.Release());
- }
-
- void Handle(TEvTicketParser::TEvRefreshTicket::TPtr& ev, const TActorContext&) {
- UserTokens.erase(ev->Get()->Ticket);
- }
-
- void Handle(TEvTicketParser::TEvDiscardTicket::TPtr& ev, const TActorContext&) {
- UserTokens.erase(ev->Get()->Ticket);
- }
-
- static TString GetLoginProviderKeys(const NLogin::TLoginProvider& loginProvider) {
- TStringBuilder keys;
- for (const auto& [key, pubKey, privKey, expiresAt] : loginProvider.Keys) {
- if (!keys.empty()) {
- keys << ",";
- }
- keys << key;
- }
- return keys;
- }
-
- void Handle(TEvTicketParser::TEvUpdateLoginSecurityState::TPtr& ev, const TActorContext& ctx) {
- auto& loginProvider = LoginProviders[ev->Get()->SecurityState.GetAudience()];
- loginProvider.UpdateSecurityState(ev->Get()->SecurityState);
- LOG_DEBUG_S(ctx, NKikimrServices::TICKET_PARSER,
- "Updated state for " << loginProvider.Audience << " keys " << GetLoginProviderKeys(loginProvider));
- }
-
- void HandleRefresh(const NActors::TActorContext& ctx) {
- while (!RefreshQueue.empty() && RefreshQueue.top().RefreshTime <= ctx.Now()) {
- TString key = RefreshQueue.top().Key;
- RefreshQueue.pop();
- auto itToken = UserTokens.find(key);
- if (itToken == UserTokens.end()) {
- continue;
- }
- auto& record(itToken->second);
- if ((record.ExpireTime > ctx.Now()) && (record.AccessTime + GetLifeTime() > ctx.Now())) {
- // we don't need to refresh anything
- } else {
- LOG_DEBUG_S(ctx, NKikimrServices::TICKET_PARSER, "Expired ticket " << MaskTicket(record.Ticket));
- if (!record.AuthorizeRequests.empty()) {
- record.Error = {"Timed out", true};
- Respond(record, ctx);
- }
- UserTokens.erase(itToken);
- }
- }
- ctx.Schedule(RefreshPeriod, new NActors::TEvents::TEvWakeup());
- }
-
- static TStringBuf HtmlBool(bool v) {
- return v ? "<span style='font-weight:bold'>&#x2611;</span>" : "<span style='font-weight:bold'>&#x2610;</span>";
- }
-
- void Handle(NMon::TEvHttpInfo::TPtr& ev, const TActorContext& ctx) {
+ ui64 cookie = ev->Cookie;
+
+ CounterTicketsReceived->Inc();
+ auto it = UserTokens.find(key);
+ if (it != UserTokens.end()) {
+ auto& record = it->second;
+ // we know about token
+ if (record.IsTokenReady()) {
+ // token already have built
+ record.AccessTime = ctx.Now();
+ ctx.Send(sender, new TEvTicketParser::TEvAuthorizeTicketResult(ev->Get()->Ticket, record.Token, record.SerializedToken), 0, cookie);
+ } else if (record.Error) {
+ // token stores information about previous error
+ record.AccessTime = ctx.Now();
+ ctx.Send(sender, new TEvTicketParser::TEvAuthorizeTicketResult(ev->Get()->Ticket, record.Error), 0, cookie);
+ } else {
+ // token building in progress
+ record.AuthorizeRequests.emplace_back(ev.Release());
+ }
+ CounterTicketsCacheHit->Inc();
+ return;
+ } else {
+ it = UserTokens.emplace(key, ticket).first;
+ CounterTicketsCacheMiss->Inc();
+ }
+
+ auto& record = it->second;
+ record.PeerName = std::move(ev->Get()->PeerName);
+ record.Database = std::move(ev->Get()->Database);
+ if (ticketType) {
+ record.TokenType = ParseTokenType(ticketType);
+ switch (record.TokenType) {
+ case ETokenType::Unsupported:
+ record.Error.Message = "Token is not supported";
+ record.Error.Retryable = false;
+ break;
+ case ETokenType::Unknown:
+ record.Error.Message = "Unknown token";
+ record.Error.Retryable = false;
+ break;
+ default:
+ break;
+ }
+ }
+ InitTokenRecord(key, record, ctx);
+ if (record.Error) {
+ LOG_ERROR_S(ctx, NKikimrServices::TICKET_PARSER, "Ticket " << MaskTicket(ticket) << ": " << record.Error);
+ ctx.Send(sender, new TEvTicketParser::TEvAuthorizeTicketResult(ev->Get()->Ticket, record.Error), 0, cookie);
+ return;
+ }
+ if (record.IsTokenReady()) {
+ // offline check ready
+ ctx.Send(sender, new TEvTicketParser::TEvAuthorizeTicketResult(ev->Get()->Ticket, record.Token, record.SerializedToken), 0, cookie);
+ return;
+ }
+ record.AuthorizeRequests.emplace_back(ev.Release());
+ }
+
+ void Handle(TEvTicketParser::TEvRefreshTicket::TPtr& ev, const TActorContext&) {
+ UserTokens.erase(ev->Get()->Ticket);
+ }
+
+ void Handle(TEvTicketParser::TEvDiscardTicket::TPtr& ev, const TActorContext&) {
+ UserTokens.erase(ev->Get()->Ticket);
+ }
+
+ static TString GetLoginProviderKeys(const NLogin::TLoginProvider& loginProvider) {
+ TStringBuilder keys;
+ for (const auto& [key, pubKey, privKey, expiresAt] : loginProvider.Keys) {
+ if (!keys.empty()) {
+ keys << ",";
+ }
+ keys << key;
+ }
+ return keys;
+ }
+
+ void Handle(TEvTicketParser::TEvUpdateLoginSecurityState::TPtr& ev, const TActorContext& ctx) {
+ auto& loginProvider = LoginProviders[ev->Get()->SecurityState.GetAudience()];
+ loginProvider.UpdateSecurityState(ev->Get()->SecurityState);
+ LOG_DEBUG_S(ctx, NKikimrServices::TICKET_PARSER,
+ "Updated state for " << loginProvider.Audience << " keys " << GetLoginProviderKeys(loginProvider));
+ }
+
+ void HandleRefresh(const NActors::TActorContext& ctx) {
+ while (!RefreshQueue.empty() && RefreshQueue.top().RefreshTime <= ctx.Now()) {
+ TString key = RefreshQueue.top().Key;
+ RefreshQueue.pop();
+ auto itToken = UserTokens.find(key);
+ if (itToken == UserTokens.end()) {
+ continue;
+ }
+ auto& record(itToken->second);
+ if ((record.ExpireTime > ctx.Now()) && (record.AccessTime + GetLifeTime() > ctx.Now())) {
+ // we don't need to refresh anything
+ } else {
+ LOG_DEBUG_S(ctx, NKikimrServices::TICKET_PARSER, "Expired ticket " << MaskTicket(record.Ticket));
+ if (!record.AuthorizeRequests.empty()) {
+ record.Error = {"Timed out", true};
+ Respond(record, ctx);
+ }
+ UserTokens.erase(itToken);
+ }
+ }
+ ctx.Schedule(RefreshPeriod, new NActors::TEvents::TEvWakeup());
+ }
+
+ static TStringBuf HtmlBool(bool v) {
+ return v ? "<span style='font-weight:bold'>&#x2611;</span>" : "<span style='font-weight:bold'>&#x2610;</span>";
+ }
+
+ void Handle(NMon::TEvHttpInfo::TPtr& ev, const TActorContext& ctx) {
const auto& params = ev->Get()->Request.GetParams();
- TStringBuilder html;
- if (params.Has("token")) {
- TString token = params.Get("token");
- html << "<head>";
- html << "<style>";
- html << "table.ticket-parser-proplist > tbody > tr > td { padding: 1px 3px; } ";
- html << "table.ticket-parser-proplist > tbody > tr > td:first-child { font-weight: bold; text-align: right; } ";
- html << "</style>";
- for (const std::pair<const TString, TTokenRecord>& pr : UserTokens) {
- if (MD5::Calc(pr.first) == token) {
- const TTokenRecord& record = pr.second;
- html << "<div>";
- html << "<table class='ticket-parser-proplist'>";
- html << "<tr><td>Ticket</td><td>" << MaskTicket(record.Ticket) << "</td></tr>";
- if (record.TokenType == ETokenType::Login) {
- TVector<TString> tokenData;
- Split(record.Ticket, ".", tokenData);
- if (tokenData.size() > 1) {
- TString header;
- TString payload;
- try {
- header = Base64DecodeUneven(tokenData[0]);
- }
- catch (const std::exception&) {
- header = tokenData[0];
- }
- try {
- payload = Base64DecodeUneven(tokenData[1]);
- }
- catch (const std::exception&) {
- payload = tokenData[1];
- }
- html << "<tr><td>Header</td><td>" << header << "</td></tr>";
- html << "<tr><td>Payload</td><td>" << payload << "</td></tr>";
- }
- }
- html << "<tr><td>Subject</td><td>" << record.Subject << "</td></tr>";
- html << "<tr><td>Additional SIDs</td><td>" << JoinStrings(record.AdditionalSIDs.begin(), record.AdditionalSIDs.end(), ", ") << "</td></tr>";
- html << "<tr><td>Error</td><td>" << record.Error << "</td></tr>";
- html << "<tr><td>Requests Infly</td><td>" << record.AuthorizeRequests.size() << "</td></tr>";
- html << "<tr><td>Responses Left</td><td>" << record.ResponsesLeft << "</td></tr>";
- html << "<tr><td>Expire Time</td><td>" << record.ExpireTime << "</td></tr>";
- html << "<tr><td>Access Time</td><td>" << record.AccessTime << "</td></tr>";
- html << "<tr><td>Peer Name</td><td>" << record.PeerName << "</td></tr>";
- if (record.Token != nullptr) {
- html << "<tr><td>User SID</td><td>" << record.Token->GetUserSID() << "</td></tr>";
- for (const TString& group : record.Token->GetGroupSIDs()) {
- html << "<tr><td>Group SID</td><td>" << group << "</td></tr>";
- }
- }
- html << "</table>";
- html << "</div>";
- break;
- }
- }
- html << "</head>";
- } else {
- html << "<head>";
- html << "<script>$('.container').css('width', 'auto');</script>";
- html << "<style>";
- html << "table.ticket-parser-proplist > tbody > tr > td { padding: 1px 3px; } ";
- html << "table.ticket-parser-proplist > tbody > tr > td:first-child { font-weight: bold; text-align: right; } ";
- html << "table.simple-table1 th { margin: 0px 3px; text-align: center; } ";
- html << "table.simple-table1 > tbody > tr > td:nth-child(6) { text-align: right; }";
- html << "table.simple-table1 > tbody > tr > td:nth-child(7) { text-align: right; }";
- html << "table.simple-table1 > tbody > tr > td:nth-child(8) { white-space: nowrap; }";
- html << "table.simple-table1 > tbody > tr > td:nth-child(9) { white-space: nowrap; }";
- html << "table.simple-table1 > tbody > tr > td:nth-child(10) { white-space: nowrap; }";
- html << "table.table-hover tbody tr:hover > td { background-color: #9dddf2; }";
- html << "</style>";
- html << "</head>";
- html << "<div style='margin-bottom: 10px; margin-left: 100px'>";
- html << "<table class='ticket-parser-proplist'>";
- html << "<tr><td>User Tokens</td><td>" << UserTokens.size() << "</td></tr>";
- html << "<tr><td>Refresh Queue</td><td>" << RefreshQueue.size() << "</td></tr>";
- if (!RefreshQueue.empty()) {
- html << "<tr><td>Refresh Queue Time</td><td>" << RefreshQueue.top().RefreshTime << "</td></tr>";
- }
- html << "<tr><td>Refresh Period</td><td>" << RefreshPeriod << "</td></tr>";
- html << "<tr><td>Life Time</td><td>" << LifeTime << "</td></tr>";
- html << "<tr><td>Expire Time</td><td>" << ExpireTime << "</td></tr>";
- if (UseLoginProvider) {
- for (const auto& [databaseName, loginProvider] : LoginProviders) {
- html << "<tr><td>LoginProvider Database</td><td>" << databaseName << " (" << loginProvider.Audience << ")</td></tr>";
- html << "<tr><td>LoginProvider Keys</td><td>" << GetLoginProviderKeys(loginProvider) << "</td></tr>";
- html << "<tr><td>LoginProvider Sids</td><td>" << loginProvider.Sids.size() << "</td></tr>";
- }
- }
- html << "<tr><td>Login</td><td>" << HtmlBool(UseLoginProvider) << "</td></tr>";
- html << "</table>";
- html << "</div>";
-
- html << "<div>";
- html << "<table class='table simple-table1 table-hover table-condensed'>";
- html << "<thead><tr>";
- html << "<th>Ticket</th>";
- html << "<th>UID</th>";
- html << "<th>Database</th>";
- html << "<th>Subject</th>";
- html << "<th>Error</th>";
- html << "<th>Token</th>";
- html << "<th>Requests</th>";
- html << "<th>Responses Left</th>";
- html << "<th>Refresh</th>";
- html << "<th>Expire</th>";
- html << "<th>Access</th>";
- html << "<th>Peer</th>";
- html << "</tr></thead><tbody>";
- for (const std::pair<const TString, TTokenRecord>& pr : UserTokens) {
- const TTokenRecord& record = pr.second;
- html << "<tr>";
- html << "<td>" << MaskTicket(record.Ticket) << "</td>";
- html << "<td>" << record.Database << "</td>";
- html << "<td>" << record.Subject << "</td>";
- html << "<td>" << record.Error << "</td>";
- html << "<td>" << "<a href='ticket_parser?token=" << MD5::Calc(pr.first) << "'>" << HtmlBool(record.Token != nullptr) << "</a>" << "</td>";
- html << "<td>" << record.AuthorizeRequests.size() << "</td>";
- html << "<td>" << record.ResponsesLeft << "</td>";
- html << "<td>" << record.ExpireTime << "</td>";
- html << "<td>" << record.AccessTime << "</td>";
- html << "<td>" << record.PeerName << "</td>";
- html << "</tr>";
- }
- html << "</tbody></table>";
- html << "</div>";
- }
- ctx.Send(ev->Sender, new NMon::TEvHttpInfoRes(html));
- }
-
-public:
+ TStringBuilder html;
+ if (params.Has("token")) {
+ TString token = params.Get("token");
+ html << "<head>";
+ html << "<style>";
+ html << "table.ticket-parser-proplist > tbody > tr > td { padding: 1px 3px; } ";
+ html << "table.ticket-parser-proplist > tbody > tr > td:first-child { font-weight: bold; text-align: right; } ";
+ html << "</style>";
+ for (const std::pair<const TString, TTokenRecord>& pr : UserTokens) {
+ if (MD5::Calc(pr.first) == token) {
+ const TTokenRecord& record = pr.second;
+ html << "<div>";
+ html << "<table class='ticket-parser-proplist'>";
+ html << "<tr><td>Ticket</td><td>" << MaskTicket(record.Ticket) << "</td></tr>";
+ if (record.TokenType == ETokenType::Login) {
+ TVector<TString> tokenData;
+ Split(record.Ticket, ".", tokenData);
+ if (tokenData.size() > 1) {
+ TString header;
+ TString payload;
+ try {
+ header = Base64DecodeUneven(tokenData[0]);
+ }
+ catch (const std::exception&) {
+ header = tokenData[0];
+ }
+ try {
+ payload = Base64DecodeUneven(tokenData[1]);
+ }
+ catch (const std::exception&) {
+ payload = tokenData[1];
+ }
+ html << "<tr><td>Header</td><td>" << header << "</td></tr>";
+ html << "<tr><td>Payload</td><td>" << payload << "</td></tr>";
+ }
+ }
+ html << "<tr><td>Subject</td><td>" << record.Subject << "</td></tr>";
+ html << "<tr><td>Additional SIDs</td><td>" << JoinStrings(record.AdditionalSIDs.begin(), record.AdditionalSIDs.end(), ", ") << "</td></tr>";
+ html << "<tr><td>Error</td><td>" << record.Error << "</td></tr>";
+ html << "<tr><td>Requests Infly</td><td>" << record.AuthorizeRequests.size() << "</td></tr>";
+ html << "<tr><td>Responses Left</td><td>" << record.ResponsesLeft << "</td></tr>";
+ html << "<tr><td>Expire Time</td><td>" << record.ExpireTime << "</td></tr>";
+ html << "<tr><td>Access Time</td><td>" << record.AccessTime << "</td></tr>";
+ html << "<tr><td>Peer Name</td><td>" << record.PeerName << "</td></tr>";
+ if (record.Token != nullptr) {
+ html << "<tr><td>User SID</td><td>" << record.Token->GetUserSID() << "</td></tr>";
+ for (const TString& group : record.Token->GetGroupSIDs()) {
+ html << "<tr><td>Group SID</td><td>" << group << "</td></tr>";
+ }
+ }
+ html << "</table>";
+ html << "</div>";
+ break;
+ }
+ }
+ html << "</head>";
+ } else {
+ html << "<head>";
+ html << "<script>$('.container').css('width', 'auto');</script>";
+ html << "<style>";
+ html << "table.ticket-parser-proplist > tbody > tr > td { padding: 1px 3px; } ";
+ html << "table.ticket-parser-proplist > tbody > tr > td:first-child { font-weight: bold; text-align: right; } ";
+ html << "table.simple-table1 th { margin: 0px 3px; text-align: center; } ";
+ html << "table.simple-table1 > tbody > tr > td:nth-child(6) { text-align: right; }";
+ html << "table.simple-table1 > tbody > tr > td:nth-child(7) { text-align: right; }";
+ html << "table.simple-table1 > tbody > tr > td:nth-child(8) { white-space: nowrap; }";
+ html << "table.simple-table1 > tbody > tr > td:nth-child(9) { white-space: nowrap; }";
+ html << "table.simple-table1 > tbody > tr > td:nth-child(10) { white-space: nowrap; }";
+ html << "table.table-hover tbody tr:hover > td { background-color: #9dddf2; }";
+ html << "</style>";
+ html << "</head>";
+ html << "<div style='margin-bottom: 10px; margin-left: 100px'>";
+ html << "<table class='ticket-parser-proplist'>";
+ html << "<tr><td>User Tokens</td><td>" << UserTokens.size() << "</td></tr>";
+ html << "<tr><td>Refresh Queue</td><td>" << RefreshQueue.size() << "</td></tr>";
+ if (!RefreshQueue.empty()) {
+ html << "<tr><td>Refresh Queue Time</td><td>" << RefreshQueue.top().RefreshTime << "</td></tr>";
+ }
+ html << "<tr><td>Refresh Period</td><td>" << RefreshPeriod << "</td></tr>";
+ html << "<tr><td>Life Time</td><td>" << LifeTime << "</td></tr>";
+ html << "<tr><td>Expire Time</td><td>" << ExpireTime << "</td></tr>";
+ if (UseLoginProvider) {
+ for (const auto& [databaseName, loginProvider] : LoginProviders) {
+ html << "<tr><td>LoginProvider Database</td><td>" << databaseName << " (" << loginProvider.Audience << ")</td></tr>";
+ html << "<tr><td>LoginProvider Keys</td><td>" << GetLoginProviderKeys(loginProvider) << "</td></tr>";
+ html << "<tr><td>LoginProvider Sids</td><td>" << loginProvider.Sids.size() << "</td></tr>";
+ }
+ }
+ html << "<tr><td>Login</td><td>" << HtmlBool(UseLoginProvider) << "</td></tr>";
+ html << "</table>";
+ html << "</div>";
+
+ html << "<div>";
+ html << "<table class='table simple-table1 table-hover table-condensed'>";
+ html << "<thead><tr>";
+ html << "<th>Ticket</th>";
+ html << "<th>UID</th>";
+ html << "<th>Database</th>";
+ html << "<th>Subject</th>";
+ html << "<th>Error</th>";
+ html << "<th>Token</th>";
+ html << "<th>Requests</th>";
+ html << "<th>Responses Left</th>";
+ html << "<th>Refresh</th>";
+ html << "<th>Expire</th>";
+ html << "<th>Access</th>";
+ html << "<th>Peer</th>";
+ html << "</tr></thead><tbody>";
+ for (const std::pair<const TString, TTokenRecord>& pr : UserTokens) {
+ const TTokenRecord& record = pr.second;
+ html << "<tr>";
+ html << "<td>" << MaskTicket(record.Ticket) << "</td>";
+ html << "<td>" << record.Database << "</td>";
+ html << "<td>" << record.Subject << "</td>";
+ html << "<td>" << record.Error << "</td>";
+ html << "<td>" << "<a href='ticket_parser?token=" << MD5::Calc(pr.first) << "'>" << HtmlBool(record.Token != nullptr) << "</a>" << "</td>";
+ html << "<td>" << record.AuthorizeRequests.size() << "</td>";
+ html << "<td>" << record.ResponsesLeft << "</td>";
+ html << "<td>" << record.ExpireTime << "</td>";
+ html << "<td>" << record.AccessTime << "</td>";
+ html << "<td>" << record.PeerName << "</td>";
+ html << "</tr>";
+ }
+ html << "</tbody></table>";
+ html << "</div>";
+ }
+ ctx.Send(ev->Sender, new NMon::TEvHttpInfoRes(html));
+ }
+
+public:
static constexpr NKikimrServices::TActivity::EType ActorActivityType() { return NKikimrServices::TActivity::TICKET_PARSER_ACTOR; }
-
- void StateWork(TAutoPtr<NActors::IEventHandle>& ev, const NActors::TActorContext& ctx) {
- switch (ev->GetTypeRewrite()) {
- HFunc(TEvTicketParser::TEvAuthorizeTicket, Handle);
- HFunc(TEvTicketParser::TEvRefreshTicket, Handle);
- HFunc(TEvTicketParser::TEvDiscardTicket, Handle);
- HFunc(TEvTicketParser::TEvUpdateLoginSecurityState, Handle);
- HFunc(NMon::TEvHttpInfo, Handle);
- CFunc(TEvents::TSystem::Wakeup, HandleRefresh);
- CFunc(TEvents::TSystem::PoisonPill, Die);
- }
- }
-
- void Bootstrap(const TActorContext& ctx) {
- TIntrusivePtr<NMonitoring::TDynamicCounters> rootCounters = AppData(ctx)->Counters;
- TIntrusivePtr<NMonitoring::TDynamicCounters> authCounters = GetServiceCounters(rootCounters, "auth");
- NMonitoring::TDynamicCounterPtr counters = authCounters->GetSubgroup("subsystem", "TicketParser");
- CounterTicketsReceived = counters->GetCounter("TicketsReceived", true);
- CounterTicketsSuccess = counters->GetCounter("TicketsSuccess", true);
- CounterTicketsErrors = counters->GetCounter("TicketsErrors", true);
- CounterTicketsErrorsRetryable = counters->GetCounter("TicketsErrorsRetryable", true);
- CounterTicketsErrorsPermanent = counters->GetCounter("TicketsErrorsPermanent", true);
- CounterTicketsBuiltin = counters->GetCounter("TicketsBuiltin", true);
- CounterTicketsLogin = counters->GetCounter("TicketsLogin", true);
- CounterTicketsCacheHit = counters->GetCounter("TicketsCacheHit", true);
- CounterTicketsCacheMiss = counters->GetCounter("TicketsCacheMiss", true);
- CounterTicketsBuildTime = counters->GetHistogram("TicketsBuildTimeMs",
- NMonitoring::ExplicitHistogram({0, 1, 5, 10, 50, 100, 500, 1000, 2000, 5000, 10000, 30000, 60000}));
-
- if (Config.GetUseLoginProvider()) {
- UseLoginProvider = true;
- }
- if (AppData() && AppData()->DomainsInfo && !AppData()->DomainsInfo->Domains.empty()) {
- DomainName = "/" + AppData()->DomainsInfo->Domains.begin()->second->Name;
- }
-
- RefreshPeriod = TDuration::Parse(Config.GetRefreshPeriod());
- LifeTime = TDuration::Parse(Config.GetLifeTime());
- ExpireTime = TDuration::Parse(Config.GetExpireTime());
-
- NActors::TMon* mon = AppData(ctx)->Mon;
- if (mon) {
- NMonitoring::TIndexMonPage* actorsMonPage = mon->RegisterIndexPage("actors", "Actors");
- mon->RegisterActorPage(actorsMonPage, "ticket_parser", "Ticket Parser", false, ctx.ExecutorThread.ActorSystem, ctx.SelfID);
- }
-
- ctx.Schedule(RefreshPeriod, new NActors::TEvents::TEvWakeup());
- TBase::Become(&TThis::StateWork);
- }
-
- TTicketParser(const NKikimrProto::TAuthConfig& authConfig)
- : Config(authConfig) {}
-};
-
-IActor* CreateTicketParser(const NKikimrProto::TAuthConfig& authConfig) {
- return new TTicketParser(authConfig);
-}
-
-}
+
+ void StateWork(TAutoPtr<NActors::IEventHandle>& ev, const NActors::TActorContext& ctx) {
+ switch (ev->GetTypeRewrite()) {
+ HFunc(TEvTicketParser::TEvAuthorizeTicket, Handle);
+ HFunc(TEvTicketParser::TEvRefreshTicket, Handle);
+ HFunc(TEvTicketParser::TEvDiscardTicket, Handle);
+ HFunc(TEvTicketParser::TEvUpdateLoginSecurityState, Handle);
+ HFunc(NMon::TEvHttpInfo, Handle);
+ CFunc(TEvents::TSystem::Wakeup, HandleRefresh);
+ CFunc(TEvents::TSystem::PoisonPill, Die);
+ }
+ }
+
+ void Bootstrap(const TActorContext& ctx) {
+ TIntrusivePtr<NMonitoring::TDynamicCounters> rootCounters = AppData(ctx)->Counters;
+ TIntrusivePtr<NMonitoring::TDynamicCounters> authCounters = GetServiceCounters(rootCounters, "auth");
+ NMonitoring::TDynamicCounterPtr counters = authCounters->GetSubgroup("subsystem", "TicketParser");
+ CounterTicketsReceived = counters->GetCounter("TicketsReceived", true);
+ CounterTicketsSuccess = counters->GetCounter("TicketsSuccess", true);
+ CounterTicketsErrors = counters->GetCounter("TicketsErrors", true);
+ CounterTicketsErrorsRetryable = counters->GetCounter("TicketsErrorsRetryable", true);
+ CounterTicketsErrorsPermanent = counters->GetCounter("TicketsErrorsPermanent", true);
+ CounterTicketsBuiltin = counters->GetCounter("TicketsBuiltin", true);
+ CounterTicketsLogin = counters->GetCounter("TicketsLogin", true);
+ CounterTicketsCacheHit = counters->GetCounter("TicketsCacheHit", true);
+ CounterTicketsCacheMiss = counters->GetCounter("TicketsCacheMiss", true);
+ CounterTicketsBuildTime = counters->GetHistogram("TicketsBuildTimeMs",
+ NMonitoring::ExplicitHistogram({0, 1, 5, 10, 50, 100, 500, 1000, 2000, 5000, 10000, 30000, 60000}));
+
+ if (Config.GetUseLoginProvider()) {
+ UseLoginProvider = true;
+ }
+ if (AppData() && AppData()->DomainsInfo && !AppData()->DomainsInfo->Domains.empty()) {
+ DomainName = "/" + AppData()->DomainsInfo->Domains.begin()->second->Name;
+ }
+
+ RefreshPeriod = TDuration::Parse(Config.GetRefreshPeriod());
+ LifeTime = TDuration::Parse(Config.GetLifeTime());
+ ExpireTime = TDuration::Parse(Config.GetExpireTime());
+
+ NActors::TMon* mon = AppData(ctx)->Mon;
+ if (mon) {
+ NMonitoring::TIndexMonPage* actorsMonPage = mon->RegisterIndexPage("actors", "Actors");
+ mon->RegisterActorPage(actorsMonPage, "ticket_parser", "Ticket Parser", false, ctx.ExecutorThread.ActorSystem, ctx.SelfID);
+ }
+
+ ctx.Schedule(RefreshPeriod, new NActors::TEvents::TEvWakeup());
+ TBase::Become(&TThis::StateWork);
+ }
+
+ TTicketParser(const NKikimrProto::TAuthConfig& authConfig)
+ : Config(authConfig) {}
+};
+
+IActor* CreateTicketParser(const NKikimrProto::TAuthConfig& authConfig) {
+ return new TTicketParser(authConfig);
+}
+
+}
diff --git a/ydb/core/security/ticket_parser.h b/ydb/core/security/ticket_parser.h
index a73a6c4a6ab..6623ecae2ad 100644
--- a/ydb/core/security/ticket_parser.h
+++ b/ydb/core/security/ticket_parser.h
@@ -1,10 +1,10 @@
-#pragma once
+#pragma once
#include <ydb/core/base/defs.h>
#include <ydb/core/base/events.h>
#include <ydb/core/protos/config.pb.h>
#include <ydb/core/base/ticket_parser.h>
-
-namespace NKikimr {
- IActor* CreateTicketParser(const NKikimrProto::TAuthConfig& authConfig);
-}
-
+
+namespace NKikimr {
+ IActor* CreateTicketParser(const NKikimrProto::TAuthConfig& authConfig);
+}
+
diff --git a/ydb/core/security/ticket_parser_ut.cpp b/ydb/core/security/ticket_parser_ut.cpp
index b9e580a6a00..2b624efefe3 100644
--- a/ydb/core/security/ticket_parser_ut.cpp
+++ b/ydb/core/security/ticket_parser_ut.cpp
@@ -11,127 +11,127 @@ namespace NKikimr {
Y_UNIT_TEST_SUITE(TTicketParserTest) {
- Y_UNIT_TEST(LoginGood) {
- using namespace Tests;
- TPortManager tp;
- ui16 kikimrPort = tp.GetPort(2134);
- ui16 grpcPort = tp.GetPort(2135);
- NKikimrProto::TAuthConfig authConfig;
- authConfig.SetUseBlackBox(false);
- authConfig.SetUseLoginProvider(true);
- auto settings = TServerSettings(kikimrPort, authConfig);
- settings.SetDomainName("Root");
- TServer server(settings);
- server.EnableGRpc(grpcPort);
- server.GetRuntime()->SetLogPriority(NKikimrServices::TICKET_PARSER, NLog::PRI_TRACE);
- server.GetRuntime()->SetLogPriority(NKikimrServices::GRPC_CLIENT, NLog::PRI_TRACE);
- TClient client(settings);
- NClient::TKikimr kikimr(client.GetClientConfig());
- client.InitRootScheme();
- TTestActorRuntime* runtime = server.GetRuntime();
-
- NLogin::TLoginProvider provider;
-
- provider.Audience = "/Root";
- provider.RotateKeys();
-
- TActorId sender = runtime->AllocateEdgeActor();
- runtime->Send(new IEventHandle(MakeTicketParserID(), sender, new TEvTicketParser::TEvUpdateLoginSecurityState(provider.GetSecurityState())), 0);
-
- provider.CreateUser({.User = "user1", .Password = "password1"});
- auto loginResponse = provider.LoginUser({.User = "user1", .Password = "password1"});
-
- runtime->Send(new IEventHandle(MakeTicketParserID(), sender, new TEvTicketParser::TEvAuthorizeTicket(loginResponse.Token)), 0);
-
- TAutoPtr<IEventHandle> handle;
-
- TEvTicketParser::TEvAuthorizeTicketResult* result = runtime->GrabEdgeEvent<TEvTicketParser::TEvAuthorizeTicketResult>(handle);
- UNIT_ASSERT(result->Error.empty());
- UNIT_ASSERT(result->Token != nullptr);
- UNIT_ASSERT_EQUAL(result->Token->GetUserSID(), "user1");
- }
-
- Y_UNIT_TEST(LoginGoodWithGroups) {
- using namespace Tests;
- TPortManager tp;
- ui16 kikimrPort = tp.GetPort(2134);
- ui16 grpcPort = tp.GetPort(2135);
- NKikimrProto::TAuthConfig authConfig;
- authConfig.SetUseBlackBox(false);
- authConfig.SetUseLoginProvider(true);
- auto settings = TServerSettings(kikimrPort, authConfig);
- settings.SetDomainName("Root");
- TServer server(settings);
- server.EnableGRpc(grpcPort);
- server.GetRuntime()->SetLogPriority(NKikimrServices::TICKET_PARSER, NLog::PRI_TRACE);
- server.GetRuntime()->SetLogPriority(NKikimrServices::GRPC_CLIENT, NLog::PRI_TRACE);
- TClient client(settings);
- NClient::TKikimr kikimr(client.GetClientConfig());
- client.InitRootScheme();
- TTestActorRuntime* runtime = server.GetRuntime();
-
- NLogin::TLoginProvider provider;
-
- provider.Audience = "/Root";
- provider.RotateKeys();
-
- TActorId sender = runtime->AllocateEdgeActor();
-
- provider.CreateGroup({.Group = "group1"});
- provider.CreateUser({.User = "user1", .Password = "password1"});
- provider.AddGroupMembership({.Group = "group1", .Member = "user1"});
-
- runtime->Send(new IEventHandle(MakeTicketParserID(), sender, new TEvTicketParser::TEvUpdateLoginSecurityState(provider.GetSecurityState())), 0);
-
- auto loginResponse = provider.LoginUser({.User = "user1", .Password = "password1"});
-
- UNIT_ASSERT_EQUAL(loginResponse.Error, "");
-
- runtime->Send(new IEventHandle(MakeTicketParserID(), sender, new TEvTicketParser::TEvAuthorizeTicket(loginResponse.Token)), 0);
-
- TAutoPtr<IEventHandle> handle;
-
- TEvTicketParser::TEvAuthorizeTicketResult* result = runtime->GrabEdgeEvent<TEvTicketParser::TEvAuthorizeTicketResult>(handle);
- UNIT_ASSERT(result->Error.empty());
- UNIT_ASSERT(result->Token != nullptr);
- UNIT_ASSERT_EQUAL(result->Token->GetUserSID(), "user1");
- UNIT_ASSERT(result->Token->IsExist("group1"));
- }
-
- Y_UNIT_TEST(LoginBad) {
- using namespace Tests;
- TPortManager tp;
- ui16 kikimrPort = tp.GetPort(2134);
- ui16 grpcPort = tp.GetPort(2135);
- NKikimrProto::TAuthConfig authConfig;
- authConfig.SetUseBlackBox(false);
- authConfig.SetUseLoginProvider(true);
- auto settings = TServerSettings(kikimrPort, authConfig);
- settings.SetDomainName("Root");
- TServer server(settings);
- server.EnableGRpc(grpcPort);
- server.GetRuntime()->SetLogPriority(NKikimrServices::TICKET_PARSER, NLog::PRI_TRACE);
- server.GetRuntime()->SetLogPriority(NKikimrServices::GRPC_CLIENT, NLog::PRI_TRACE);
- TClient client(settings);
- NClient::TKikimr kikimr(client.GetClientConfig());
- client.InitRootScheme();
- TTestActorRuntime* runtime = server.GetRuntime();
-
- NLogin::TLoginProvider provider;
-
- provider.Audience = "/Root";
- provider.RotateKeys();
-
- TActorId sender = runtime->AllocateEdgeActor();
- runtime->Send(new IEventHandle(MakeTicketParserID(), sender, new TEvTicketParser::TEvUpdateLoginSecurityState(provider.GetSecurityState())), 0);
-
- runtime->Send(new IEventHandle(MakeTicketParserID(), sender, new TEvTicketParser::TEvAuthorizeTicket("Login bad-token")), 0);
-
- TAutoPtr<IEventHandle> handle;
-
- TEvTicketParser::TEvAuthorizeTicketResult* result = runtime->GrabEdgeEvent<TEvTicketParser::TEvAuthorizeTicketResult>(handle);
- UNIT_ASSERT(!result->Error.empty());
- UNIT_ASSERT_EQUAL(result->Error.Message, "Token is not in correct format");
- }
+ Y_UNIT_TEST(LoginGood) {
+ using namespace Tests;
+ TPortManager tp;
+ ui16 kikimrPort = tp.GetPort(2134);
+ ui16 grpcPort = tp.GetPort(2135);
+ NKikimrProto::TAuthConfig authConfig;
+ authConfig.SetUseBlackBox(false);
+ authConfig.SetUseLoginProvider(true);
+ auto settings = TServerSettings(kikimrPort, authConfig);
+ settings.SetDomainName("Root");
+ TServer server(settings);
+ server.EnableGRpc(grpcPort);
+ server.GetRuntime()->SetLogPriority(NKikimrServices::TICKET_PARSER, NLog::PRI_TRACE);
+ server.GetRuntime()->SetLogPriority(NKikimrServices::GRPC_CLIENT, NLog::PRI_TRACE);
+ TClient client(settings);
+ NClient::TKikimr kikimr(client.GetClientConfig());
+ client.InitRootScheme();
+ TTestActorRuntime* runtime = server.GetRuntime();
+
+ NLogin::TLoginProvider provider;
+
+ provider.Audience = "/Root";
+ provider.RotateKeys();
+
+ TActorId sender = runtime->AllocateEdgeActor();
+ runtime->Send(new IEventHandle(MakeTicketParserID(), sender, new TEvTicketParser::TEvUpdateLoginSecurityState(provider.GetSecurityState())), 0);
+
+ provider.CreateUser({.User = "user1", .Password = "password1"});
+ auto loginResponse = provider.LoginUser({.User = "user1", .Password = "password1"});
+
+ runtime->Send(new IEventHandle(MakeTicketParserID(), sender, new TEvTicketParser::TEvAuthorizeTicket(loginResponse.Token)), 0);
+
+ TAutoPtr<IEventHandle> handle;
+
+ TEvTicketParser::TEvAuthorizeTicketResult* result = runtime->GrabEdgeEvent<TEvTicketParser::TEvAuthorizeTicketResult>(handle);
+ UNIT_ASSERT(result->Error.empty());
+ UNIT_ASSERT(result->Token != nullptr);
+ UNIT_ASSERT_EQUAL(result->Token->GetUserSID(), "user1");
+ }
+
+ Y_UNIT_TEST(LoginGoodWithGroups) {
+ using namespace Tests;
+ TPortManager tp;
+ ui16 kikimrPort = tp.GetPort(2134);
+ ui16 grpcPort = tp.GetPort(2135);
+ NKikimrProto::TAuthConfig authConfig;
+ authConfig.SetUseBlackBox(false);
+ authConfig.SetUseLoginProvider(true);
+ auto settings = TServerSettings(kikimrPort, authConfig);
+ settings.SetDomainName("Root");
+ TServer server(settings);
+ server.EnableGRpc(grpcPort);
+ server.GetRuntime()->SetLogPriority(NKikimrServices::TICKET_PARSER, NLog::PRI_TRACE);
+ server.GetRuntime()->SetLogPriority(NKikimrServices::GRPC_CLIENT, NLog::PRI_TRACE);
+ TClient client(settings);
+ NClient::TKikimr kikimr(client.GetClientConfig());
+ client.InitRootScheme();
+ TTestActorRuntime* runtime = server.GetRuntime();
+
+ NLogin::TLoginProvider provider;
+
+ provider.Audience = "/Root";
+ provider.RotateKeys();
+
+ TActorId sender = runtime->AllocateEdgeActor();
+
+ provider.CreateGroup({.Group = "group1"});
+ provider.CreateUser({.User = "user1", .Password = "password1"});
+ provider.AddGroupMembership({.Group = "group1", .Member = "user1"});
+
+ runtime->Send(new IEventHandle(MakeTicketParserID(), sender, new TEvTicketParser::TEvUpdateLoginSecurityState(provider.GetSecurityState())), 0);
+
+ auto loginResponse = provider.LoginUser({.User = "user1", .Password = "password1"});
+
+ UNIT_ASSERT_EQUAL(loginResponse.Error, "");
+
+ runtime->Send(new IEventHandle(MakeTicketParserID(), sender, new TEvTicketParser::TEvAuthorizeTicket(loginResponse.Token)), 0);
+
+ TAutoPtr<IEventHandle> handle;
+
+ TEvTicketParser::TEvAuthorizeTicketResult* result = runtime->GrabEdgeEvent<TEvTicketParser::TEvAuthorizeTicketResult>(handle);
+ UNIT_ASSERT(result->Error.empty());
+ UNIT_ASSERT(result->Token != nullptr);
+ UNIT_ASSERT_EQUAL(result->Token->GetUserSID(), "user1");
+ UNIT_ASSERT(result->Token->IsExist("group1"));
+ }
+
+ Y_UNIT_TEST(LoginBad) {
+ using namespace Tests;
+ TPortManager tp;
+ ui16 kikimrPort = tp.GetPort(2134);
+ ui16 grpcPort = tp.GetPort(2135);
+ NKikimrProto::TAuthConfig authConfig;
+ authConfig.SetUseBlackBox(false);
+ authConfig.SetUseLoginProvider(true);
+ auto settings = TServerSettings(kikimrPort, authConfig);
+ settings.SetDomainName("Root");
+ TServer server(settings);
+ server.EnableGRpc(grpcPort);
+ server.GetRuntime()->SetLogPriority(NKikimrServices::TICKET_PARSER, NLog::PRI_TRACE);
+ server.GetRuntime()->SetLogPriority(NKikimrServices::GRPC_CLIENT, NLog::PRI_TRACE);
+ TClient client(settings);
+ NClient::TKikimr kikimr(client.GetClientConfig());
+ client.InitRootScheme();
+ TTestActorRuntime* runtime = server.GetRuntime();
+
+ NLogin::TLoginProvider provider;
+
+ provider.Audience = "/Root";
+ provider.RotateKeys();
+
+ TActorId sender = runtime->AllocateEdgeActor();
+ runtime->Send(new IEventHandle(MakeTicketParserID(), sender, new TEvTicketParser::TEvUpdateLoginSecurityState(provider.GetSecurityState())), 0);
+
+ runtime->Send(new IEventHandle(MakeTicketParserID(), sender, new TEvTicketParser::TEvAuthorizeTicket("Login bad-token")), 0);
+
+ TAutoPtr<IEventHandle> handle;
+
+ TEvTicketParser::TEvAuthorizeTicketResult* result = runtime->GrabEdgeEvent<TEvTicketParser::TEvAuthorizeTicketResult>(handle);
+ UNIT_ASSERT(!result->Error.empty());
+ UNIT_ASSERT_EQUAL(result->Error.Message, "Token is not in correct format");
+ }
}
}
diff --git a/ydb/core/security/ya.make b/ydb/core/security/ya.make
index 3d7d040f327..514b0c34748 100644
--- a/ydb/core/security/ya.make
+++ b/ydb/core/security/ya.make
@@ -1,16 +1,16 @@
LIBRARY()
OWNER(
- xenoxeno
+ xenoxeno
g:kikimr
)
SRCS(
- login_page.cpp
- login_page.h
- secure_request.h
- ticket_parser.cpp
- ticket_parser.h
+ login_page.cpp
+ login_page.h
+ secure_request.h
+ ticket_parser.cpp
+ ticket_parser.h
)
PEERDIR(
diff --git a/ydb/core/sys_view/ut_kqp.cpp b/ydb/core/sys_view/ut_kqp.cpp
index 3e2bbeaecd3..5e90eb59927 100644
--- a/ydb/core/sys_view/ut_kqp.cpp
+++ b/ydb/core/sys_view/ut_kqp.cpp
@@ -1443,7 +1443,7 @@ Y_UNIT_TEST_SUITE(SystemView) {
TYsonFieldChecker check(ysonString, 11);
- check.String("Running"); // BootState
+ check.String("Running"); // BootState
check.DoubleGreaterOrEquals(0.0); // CPU
check.Uint64(1u); // Generation
check.Uint64GreaterOrEquals(0u); // Memory
diff --git a/ydb/core/tablet/node_tablet_monitor.cpp b/ydb/core/tablet/node_tablet_monitor.cpp
index 45bd2e5de0a..8bb34e7ea0b 100644
--- a/ydb/core/tablet/node_tablet_monitor.cpp
+++ b/ydb/core/tablet/node_tablet_monitor.cpp
@@ -1,5 +1,5 @@
-
-#include "node_tablet_monitor.h"
+
+#include "node_tablet_monitor.h"
#include <library/cpp/actors/core/actor_bootstrapped.h>
#include <library/cpp/actors/interconnect/interconnect.h>
#include <ydb/core/mon/mon.h>
@@ -7,56 +7,56 @@
#include <ydb/core/base/appdata.h>
#include <library/cpp/monlib/service/pages/templates.h>
#include <library/cpp/actors/core/interconnect.h>
-#include <util/generic/algorithm.h>
+#include <util/generic/algorithm.h>
#include <ydb/core/base/tablet_types.h>
#include <ydb/core/node_whiteboard/node_whiteboard.h>
#include <ydb/core/base/statestorage.h>
#include <ydb/core/base/tablet.h>
-
-namespace NKikimr {
-namespace NNodeTabletMonitor {
-
-using namespace NNodeWhiteboard;
-
-class TNodeList : public TActorBootstrapped<TNodeList> {
-public:
+
+namespace NKikimr {
+namespace NNodeTabletMonitor {
+
+using namespace NNodeWhiteboard;
+
+class TNodeList : public TActorBootstrapped<TNodeList> {
+public:
static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
return NKikimrServices::TActivity::TABLET_FORWARDING_ACTOR;
}
TNodeList(const TActorId &sender)
- : Sender(sender)
+ : Sender(sender)
{}
-
- void Bootstrap(const TActorContext& ctx) {
+
+ void Bootstrap(const TActorContext& ctx) {
const TActorId nameserviceId = GetNameserviceActorId();
- ctx.Send(nameserviceId, new TEvInterconnect::TEvListNodes());
- ctx.Schedule(TDuration::Seconds(60), new TEvents::TEvWakeup());
- Become(&TThis::StateRequestedBrowse);
- }
-
- STFUNC(StateRequestedBrowse) {
- switch (ev->GetTypeRewrite()) {
- HFunc(TEvInterconnect::TEvNodesInfo, Handle);
- CFunc(TEvents::TSystem::Wakeup, Timeout);
- }
- }
-
- void Handle(TEvInterconnect::TEvNodesInfo::TPtr &ev, const TActorContext &ctx) {
- NodesInfo = ev->Release();
- if (!NodesInfo->Nodes.empty()) {
- RenderResponse(ctx);
- } else {
- NoData(ctx);
- }
- }
-
- void RenderResponse(const TActorContext &ctx) {
- Sort(NodesInfo->Nodes.begin(), NodesInfo->Nodes.end());
- TStringStream str;
+ ctx.Send(nameserviceId, new TEvInterconnect::TEvListNodes());
+ ctx.Schedule(TDuration::Seconds(60), new TEvents::TEvWakeup());
+ Become(&TThis::StateRequestedBrowse);
+ }
+
+ STFUNC(StateRequestedBrowse) {
+ switch (ev->GetTypeRewrite()) {
+ HFunc(TEvInterconnect::TEvNodesInfo, Handle);
+ CFunc(TEvents::TSystem::Wakeup, Timeout);
+ }
+ }
+
+ void Handle(TEvInterconnect::TEvNodesInfo::TPtr &ev, const TActorContext &ctx) {
+ NodesInfo = ev->Release();
+ if (!NodesInfo->Nodes.empty()) {
+ RenderResponse(ctx);
+ } else {
+ NoData(ctx);
+ }
+ }
+
+ void RenderResponse(const TActorContext &ctx) {
+ Sort(NodesInfo->Nodes.begin(), NodesInfo->Nodes.end());
+ TStringStream str;
HTML(str) {
H3() {
- str << "Nodes";
+ str << "Nodes";
}
TABLE_SORTABLE_CLASS("table") {
TABLEHEAD() {
@@ -68,7 +68,7 @@ public:
}
}
TABLEBODY() {
- for (const auto& ni : NodesInfo->Nodes) {
+ for (const auto& ni : NodesInfo->Nodes) {
const TEvInterconnect::TNodeInfo &nodeInfo = ni;
TABLER() {
TABLED() {str << "<a href=\"nodetabmon?action=browse_tablets&node_id=" << nodeInfo.NodeId << "\">"
@@ -78,12 +78,12 @@ public:
TABLED() {str << nodeInfo.Address;}
TABLED() {str << nodeInfo.Port;}
}
- }
+ }
}
}
HTML_TAG() {str << "<a href=\"nodetabmon?action=browse_tablets\">All tablets of the cluster</a>";}
H3() {
- str << "State Storages";
+ str << "State Storages";
}
TABLE_SORTABLE_CLASS("table") {
TABLEHEAD() {
@@ -93,45 +93,45 @@ public:
}
}
TABLEBODY() {
-
- for (const auto& ni : AppData(ctx)->DomainsInfo->Domains) {
- const TDomainsInfo::TDomain &domain = *ni.second;
- for (const auto ssId : domain.StateStorageGroups) {
+
+ for (const auto& ni : AppData(ctx)->DomainsInfo->Domains) {
+ const TDomainsInfo::TDomain &domain = *ni.second;
+ for (const auto ssId : domain.StateStorageGroups) {
TABLER() {
TABLED() {str << "<a href=\"nodetabmon?action=browse_ss&ss_id=" << ssId << "\">"
<< ssId << "</a>";}
TABLED() {str << domain.Name;}
- }
+ }
}
- }
+ }
}
}
}
- ctx.Send(Sender, new NMon::TEvHttpInfoRes(str.Str()));
- Die(ctx);
- }
-
+ ctx.Send(Sender, new NMon::TEvHttpInfoRes(str.Str()));
+ Die(ctx);
+ }
+
void Notify(const TActorContext &ctx, const TString& html) {
- ctx.Send(Sender, new NMon::TEvHttpInfoRes(html));
- }
-
- void NoData(const TActorContext &ctx) {
- Notify(ctx, "No data to display");
- Die(ctx);
- }
-
- void Timeout(const TActorContext &ctx) {
- Notify(ctx, "Timeout");
- Die(ctx);
- }
-
-protected:
+ ctx.Send(Sender, new NMon::TEvHttpInfoRes(html));
+ }
+
+ void NoData(const TActorContext &ctx) {
+ Notify(ctx, "No data to display");
+ Die(ctx);
+ }
+
+ void Timeout(const TActorContext &ctx) {
+ Notify(ctx, "Timeout");
+ Die(ctx);
+ }
+
+protected:
TActorId Sender;
- TAutoPtr<TEvInterconnect::TEvNodesInfo> NodesInfo;
-};
-
-class TTabletList : public TActorBootstrapped<TTabletList> {
-public:
+ TAutoPtr<TEvInterconnect::TEvNodesInfo> NodesInfo;
+};
+
+class TTabletList : public TActorBootstrapped<TTabletList> {
+public:
static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
return NKikimrServices::TActivity::TABLET_FORWARDING_ACTOR;
}
@@ -139,95 +139,95 @@ public:
TTabletList(const TActorId &sender, ui32 filterNodeId,
const TIntrusivePtr<ITabletStateClassifier>& stateClassifier,
const TIntrusivePtr<ITabletListRenderer>& renderer)
- : Sender(sender)
- , NodesRequested(0)
- , NodesReceived(0)
- , FilterNodeId(filterNodeId)
+ : Sender(sender)
+ , NodesRequested(0)
+ , NodesReceived(0)
+ , FilterNodeId(filterNodeId)
, StateClassifier(stateClassifier)
, Renderer(renderer)
{}
-
- void Bootstrap(const TActorContext& ctx) {
+
+ void Bootstrap(const TActorContext& ctx) {
const TActorId nameserviceId = GetNameserviceActorId();
- ctx.Send(nameserviceId, new TEvInterconnect::TEvListNodes());
- ctx.Schedule(TDuration::Seconds(60), new TEvents::TEvWakeup());
- Become(&TThis::StateRequestedBrowse);
- }
-
- STFUNC(StateRequestedBrowse) {
- switch (ev->GetTypeRewrite()) {
- HFunc(TEvInterconnect::TEvNodesInfo, Handle);
- CFunc(TEvents::TSystem::Wakeup, Timeout);
- }
- }
-
- STFUNC(StateRequestedTabletInfo) {
- switch (ev->GetTypeRewrite()) {
- HFunc(TEvWhiteboard::TEvTabletStateResponse, Handle);
- HFunc(TEvents::TEvUndelivered, Undelivered);
- CFunc(TEvents::TSystem::Wakeup, Timeout);
- }
- }
-
- void Handle(TEvInterconnect::TEvNodesInfo::TPtr &ev, const TActorContext &ctx) {
- NodesInfo = ev->Release();
- if (!NodesInfo->Nodes.empty()) {
- if (FilterNodeId) {
+ ctx.Send(nameserviceId, new TEvInterconnect::TEvListNodes());
+ ctx.Schedule(TDuration::Seconds(60), new TEvents::TEvWakeup());
+ Become(&TThis::StateRequestedBrowse);
+ }
+
+ STFUNC(StateRequestedBrowse) {
+ switch (ev->GetTypeRewrite()) {
+ HFunc(TEvInterconnect::TEvNodesInfo, Handle);
+ CFunc(TEvents::TSystem::Wakeup, Timeout);
+ }
+ }
+
+ STFUNC(StateRequestedTabletInfo) {
+ switch (ev->GetTypeRewrite()) {
+ HFunc(TEvWhiteboard::TEvTabletStateResponse, Handle);
+ HFunc(TEvents::TEvUndelivered, Undelivered);
+ CFunc(TEvents::TSystem::Wakeup, Timeout);
+ }
+ }
+
+ void Handle(TEvInterconnect::TEvNodesInfo::TPtr &ev, const TActorContext &ctx) {
+ NodesInfo = ev->Release();
+ if (!NodesInfo->Nodes.empty()) {
+ if (FilterNodeId) {
TActorId tabletStateActorId = NNodeWhiteboard::MakeNodeWhiteboardServiceId(FilterNodeId);
- ctx.Send(tabletStateActorId, new TEvWhiteboard::TEvTabletStateRequest(), IEventHandle::FlagTrackDelivery, FilterNodeId);
- ++NodesRequested;
- } else {
- for (const auto& ni : NodesInfo->Nodes) {
+ ctx.Send(tabletStateActorId, new TEvWhiteboard::TEvTabletStateRequest(), IEventHandle::FlagTrackDelivery, FilterNodeId);
+ ++NodesRequested;
+ } else {
+ for (const auto& ni : NodesInfo->Nodes) {
TActorId tabletStateActorId = NNodeWhiteboard::MakeNodeWhiteboardServiceId(ni.NodeId);
- ctx.Send(tabletStateActorId, new TEvWhiteboard::TEvTabletStateRequest(), IEventHandle::FlagTrackDelivery, ni.NodeId);
- ++NodesRequested;
- }
- }
- Become(&TThis::StateRequestedTabletInfo);
- } else {
- NoData(ctx);
- }
- }
-
- void Undelivered(TEvents::TEvUndelivered::TPtr &ev, const TActorContext &ctx) {
- ui64 nodeId = ev.Get()->Cookie;
- PerNodeTabletInfo[nodeId]; // nullptr
- NodeTabletInfoReceived(ctx);
- }
-
- void Handle(TEvWhiteboard::TEvTabletStateResponse::TPtr &ev, const TActorContext &ctx) {
- ui64 nodeId = ev.Get()->Cookie;
- PerNodeTabletInfo[nodeId] = ev->Release();
- NodeTabletInfoReceived(ctx);
- }
-
- void NodeTabletInfoReceived(const TActorContext &ctx) {
- ++NodesReceived;
- if (NodesReceived >= NodesRequested) {
- RenderResponse(ctx);
- }
- }
-
+ ctx.Send(tabletStateActorId, new TEvWhiteboard::TEvTabletStateRequest(), IEventHandle::FlagTrackDelivery, ni.NodeId);
+ ++NodesRequested;
+ }
+ }
+ Become(&TThis::StateRequestedTabletInfo);
+ } else {
+ NoData(ctx);
+ }
+ }
+
+ void Undelivered(TEvents::TEvUndelivered::TPtr &ev, const TActorContext &ctx) {
+ ui64 nodeId = ev.Get()->Cookie;
+ PerNodeTabletInfo[nodeId]; // nullptr
+ NodeTabletInfoReceived(ctx);
+ }
+
+ void Handle(TEvWhiteboard::TEvTabletStateResponse::TPtr &ev, const TActorContext &ctx) {
+ ui64 nodeId = ev.Get()->Cookie;
+ PerNodeTabletInfo[nodeId] = ev->Release();
+ NodeTabletInfoReceived(ctx);
+ }
+
+ void NodeTabletInfoReceived(const TActorContext &ctx) {
+ ++NodesReceived;
+ if (NodesReceived >= NodesRequested) {
+ RenderResponse(ctx);
+ }
+ }
+
void BuildTabletList(std::function<bool(const NKikimrWhiteboard::TTabletStateInfo&)> filter,
TVector<TTabletListElement>& tabletsToRender) {
TVector<ui64> tabletIdIndex;
-
+
tabletsToRender.clear();
- for (const auto& ni : PerNodeTabletInfo) {
- if (FilterNodeId != 0 && FilterNodeId != ni.first)
- continue;
- auto eq_it = EqualRange(NodesInfo->Nodes.begin(), NodesInfo->Nodes.end(), ni.first);
- if (eq_it.first != NodesInfo->Nodes.end() && ni.second) {
- for (const auto& ti : ni.second->Record.GetTabletStateInfo()) {
- if (filter(ti)) {
- tabletIdIndex.push_back(ti.GetTabletId());
- }
- }
- }
- }
-
- Sort(tabletIdIndex);
-
+ for (const auto& ni : PerNodeTabletInfo) {
+ if (FilterNodeId != 0 && FilterNodeId != ni.first)
+ continue;
+ auto eq_it = EqualRange(NodesInfo->Nodes.begin(), NodesInfo->Nodes.end(), ni.first);
+ if (eq_it.first != NodesInfo->Nodes.end() && ni.second) {
+ for (const auto& ti : ni.second->Record.GetTabletStateInfo()) {
+ if (filter(ti)) {
+ tabletIdIndex.push_back(ti.GetTabletId());
+ }
+ }
+ }
+ }
+
+ Sort(tabletIdIndex);
+
for (const auto& ni : PerNodeTabletInfo) {
if (FilterNodeId != 0 && FilterNodeId != ni.first)
continue;
@@ -238,14 +238,14 @@ public:
if (filter(ti)) {
ui64 index = EqualRange(tabletIdIndex.begin(), tabletIdIndex.end(), ti.GetTabletId()).first - tabletIdIndex.begin();
tabletsToRender.push_back({ &nodeInfo, index, &ti });
- }
- }
- }
+ }
+ }
+ }
}
- }
-
- void RenderResponse(const TActorContext &ctx) {
- Sort(NodesInfo->Nodes.begin(), NodesInfo->Nodes.end());
+ }
+
+ void RenderResponse(const TActorContext &ctx) {
+ Sort(NodesInfo->Nodes.begin(), NodesInfo->Nodes.end());
TString filterNodeHost;
if (FilterNodeId != 0) {
auto eq_it = EqualRange(NodesInfo->Nodes.begin(), NodesInfo->Nodes.end(), FilterNodeId);
@@ -253,7 +253,7 @@ public:
filterNodeHost = eq_it.first->Host;
}
}
- TStringStream str;
+ TStringStream str;
HTML(str) {
Renderer->RenderPageHeader(str);
for(ui32 cls = 0; cls < StateClassifier->GetMaxTabletStateClass(); cls++) {
@@ -265,82 +265,82 @@ public:
}
Renderer->RenderPageFooter(str);
}
- ctx.Send(Sender, new NMon::TEvHttpInfoRes(str.Str()));
- Die(ctx);
- }
-
+ ctx.Send(Sender, new NMon::TEvHttpInfoRes(str.Str()));
+ Die(ctx);
+ }
+
void Notify(const TActorContext &ctx, const TString& html) {
- ctx.Send(Sender, new NMon::TEvHttpInfoRes(html));
- }
-
- void NoData(const TActorContext &ctx) {
- Notify(ctx, "No data to display");
- Die(ctx);
- }
-
- void Timeout(const TActorContext &ctx) {
- Notify(ctx, "Timeout");
- Die(ctx);
- }
-
-protected:
+ ctx.Send(Sender, new NMon::TEvHttpInfoRes(html));
+ }
+
+ void NoData(const TActorContext &ctx) {
+ Notify(ctx, "No data to display");
+ Die(ctx);
+ }
+
+ void Timeout(const TActorContext &ctx) {
+ Notify(ctx, "Timeout");
+ Die(ctx);
+ }
+
+protected:
TActorId Sender;
- TAutoPtr<TEvInterconnect::TEvNodesInfo> NodesInfo;
+ TAutoPtr<TEvInterconnect::TEvNodesInfo> NodesInfo;
TMap<ui64, TAutoPtr<TEvWhiteboard::TEvTabletStateResponse>> PerNodeTabletInfo;
- size_t NodesRequested;
- size_t NodesReceived;
- ui32 FilterNodeId;
+ size_t NodesRequested;
+ size_t NodesReceived;
+ ui32 FilterNodeId;
TIntrusivePtr<ITabletStateClassifier> StateClassifier;
TIntrusivePtr<ITabletListRenderer> Renderer;
-};
-
-class TStateStorageTabletList : public TActorBootstrapped<TStateStorageTabletList> {
-public:
+};
+
+class TStateStorageTabletList : public TActorBootstrapped<TStateStorageTabletList> {
+public:
static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
return NKikimrServices::TActivity::TABLET_FORWARDING_ACTOR;
}
TStateStorageTabletList(const TActorId &sender, ui32 stateStorageId)
- : Sender(sender)
- , StateStorageId(stateStorageId)
+ : Sender(sender)
+ , StateStorageId(stateStorageId)
{}
-
- void Bootstrap(const TActorContext& ctx) {
+
+ void Bootstrap(const TActorContext& ctx) {
const TActorId nameserviceId = GetNameserviceActorId();
- ctx.Send(nameserviceId, new TEvInterconnect::TEvListNodes());
- ctx.Schedule(TDuration::Seconds(60), new TEvents::TEvWakeup());
- Become(&TThis::StateRequestedBrowse);
- }
-
- STFUNC(StateRequestedBrowse) {
- switch (ev->GetTypeRewrite()) {
- HFunc(TEvInterconnect::TEvNodesInfo, Handle);
- HFunc(TEvStateStorage::TEvResponseReplicasDumps, Handle);
- CFunc(TEvents::TSystem::Wakeup, Timeout);
- }
- }
-
- void Handle(TEvInterconnect::TEvNodesInfo::TPtr &ev, const TActorContext &ctx) {
- NodesInfo = ev->Release();
+ ctx.Send(nameserviceId, new TEvInterconnect::TEvListNodes());
+ ctx.Schedule(TDuration::Seconds(60), new TEvents::TEvWakeup());
+ Become(&TThis::StateRequestedBrowse);
+ }
+
+ STFUNC(StateRequestedBrowse) {
+ switch (ev->GetTypeRewrite()) {
+ HFunc(TEvInterconnect::TEvNodesInfo, Handle);
+ HFunc(TEvStateStorage::TEvResponseReplicasDumps, Handle);
+ CFunc(TEvents::TSystem::Wakeup, Timeout);
+ }
+ }
+
+ void Handle(TEvInterconnect::TEvNodesInfo::TPtr &ev, const TActorContext &ctx) {
+ NodesInfo = ev->Release();
const TActorId proxyActorID = MakeStateStorageProxyID(StateStorageId);
- ctx.Send(proxyActorID, new TEvStateStorage::TEvRequestReplicasDumps());
- }
-
- void Handle(TEvStateStorage::TEvResponseReplicasDumps::TPtr &ev, const TActorContext &ctx) {
- Sort(NodesInfo->Nodes.begin(), NodesInfo->Nodes.end());
- TEvStateStorage::TEvResponseReplicasDumps &event = *ev->Get();
+ ctx.Send(proxyActorID, new TEvStateStorage::TEvRequestReplicasDumps());
+ }
+
+ void Handle(TEvStateStorage::TEvResponseReplicasDumps::TPtr &ev, const TActorContext &ctx) {
+ Sort(NodesInfo->Nodes.begin(), NodesInfo->Nodes.end());
+ TEvStateStorage::TEvResponseReplicasDumps &event = *ev->Get();
TMap<ui64, TVector<std::pair<ui32, const NKikimrStateStorage::TEvInfo*>>> indexByTabletId;
- for (const auto& rdi : event.ReplicasDumps) {
- const TEvStateStorage::TEvReplicaDump& replicaDump = *rdi.second;
- for (const NKikimrStateStorage::TEvInfo& ei : replicaDump.Record.GetInfo()) {
- indexByTabletId[ei.GetTabletID()].push_back(std::make_pair(rdi.first.NodeId(), &ei));
- }
- }
- TStringStream str;
+ for (const auto& rdi : event.ReplicasDumps) {
+ const TEvStateStorage::TEvReplicaDump& replicaDump = *rdi.second;
+ for (const NKikimrStateStorage::TEvInfo& ei : replicaDump.Record.GetInfo()) {
+ indexByTabletId[ei.GetTabletID()].push_back(std::make_pair(rdi.first.NodeId(), &ei));
+ }
+ }
+ TStringStream str;
HTML(str) {
H3() {
- str << "Tablets of StateStorage " << StateStorageId;
+ str << "Tablets of StateStorage " << StateStorageId;
}
TABLE_CLASS("table table-bordered") {
TABLEHEAD() {
@@ -351,70 +351,70 @@ public:
TABLEH() {str << "<span data-toggle='tooltip' title='Amount of time tablet has been locked in SS (seconds)'>Locked For</span>";}
TABLEH() {str << "<span data-toggle='tooltip' title='Node where tablet has been started'>Tablet Node ID / Hostname</span>";}
TABLEH() {str << "<span data-toggle='tooltip' title='Is user part (actor) of the tablet started?'>Active</span>";}
- str << "</tr>";
+ str << "</tr>";
}
}
TABLEBODY() {
- for (auto iit = indexByTabletId.begin(); iit != indexByTabletId.end(); ++iit) {
- for (auto iptr = iit->second.begin(); iptr != iit->second.end(); ++iptr) {
- const NKikimrStateStorage::TEvInfo &ei = *iptr->second;
- ui32 replicaNodeId = iptr->first;
+ for (auto iit = indexByTabletId.begin(); iit != indexByTabletId.end(); ++iit) {
+ for (auto iptr = iit->second.begin(); iptr != iit->second.end(); ++iptr) {
+ const NKikimrStateStorage::TEvInfo &ei = *iptr->second;
+ ui32 replicaNodeId = iptr->first;
TABLER() {
- if (iptr == iit->second.begin()) {
+ if (iptr == iit->second.begin()) {
HTML_TAG() {str << "<td rowspan='" << iit->second.size() << "'>"
<< "<a href='tablets?TabletID=" << ei.GetTabletID() << "'>" << ei.GetTabletID() << "</a></td>";}
- }
+ }
TABLED() {
- str << replicaNodeId;
- auto eq_it = EqualRange(NodesInfo->Nodes.begin(), NodesInfo->Nodes.end(), replicaNodeId);
- if (eq_it.first != NodesInfo->Nodes.end() && eq_it.first->Host) str << " / " << eq_it.first->Host;
+ str << replicaNodeId;
+ auto eq_it = EqualRange(NodesInfo->Nodes.begin(), NodesInfo->Nodes.end(), replicaNodeId);
+ if (eq_it.first != NodesInfo->Nodes.end() && eq_it.first->Host) str << " / " << eq_it.first->Host;
}
TABLED() {str << ei.GetCurrentGeneration();}
TABLED() {if (ei.HasLockedFor()) str << TDuration::MicroSeconds(ei.GetLockedFor()).Seconds();}
TABLED() {
ui32 nodeId = ActorIdFromProto(ei.GetCurrentLeader()).NodeId();
- str << nodeId;
- auto eq_it = EqualRange(NodesInfo->Nodes.begin(), NodesInfo->Nodes.end(), nodeId);
- if (eq_it.first != NodesInfo->Nodes.end() && eq_it.first->Host) str << " / " << eq_it.first->Host;
+ str << nodeId;
+ auto eq_it = EqualRange(NodesInfo->Nodes.begin(), NodesInfo->Nodes.end(), nodeId);
+ if (eq_it.first != NodesInfo->Nodes.end() && eq_it.first->Host) str << " / " << eq_it.first->Host;
}
TABLED() {if (ActorIdFromProto(ei.GetCurrentLeaderTablet())) str << "<span class='glyphicon glyphicon-ok' title='User Actor present'/>";}
}
- }
- }
+ }
+ }
}
}
HTML_TAG() {str << "<script>$(document).ready(function(){$('[data-toggle=\"tooltip\"]').tooltip();}</script>";}
}
- ctx.Send(Sender, new NMon::TEvHttpInfoRes(str.Str()));
- Die(ctx);
- }
-
+ ctx.Send(Sender, new NMon::TEvHttpInfoRes(str.Str()));
+ Die(ctx);
+ }
+
void Notify(const TActorContext &ctx, const TString& html) {
- ctx.Send(Sender, new NMon::TEvHttpInfoRes(html));
- }
-
- void NoData(const TActorContext &ctx) {
- Notify(ctx, "No data to display");
- Die(ctx);
- }
-
- void Timeout(const TActorContext &ctx) {
- Notify(ctx, "Timeout");
- Die(ctx);
- }
-
-protected:
+ ctx.Send(Sender, new NMon::TEvHttpInfoRes(html));
+ }
+
+ void NoData(const TActorContext &ctx) {
+ Notify(ctx, "No data to display");
+ Die(ctx);
+ }
+
+ void Timeout(const TActorContext &ctx) {
+ Notify(ctx, "Timeout");
+ Die(ctx);
+ }
+
+protected:
TActorId Sender;
- ui32 StateStorageId;
- TAutoPtr<TEvInterconnect::TEvNodesInfo> NodesInfo;
-};
-
-class TNodeTabletMonitor : public TActorBootstrapped<TNodeTabletMonitor> {
+ ui32 StateStorageId;
+ TAutoPtr<TEvInterconnect::TEvNodesInfo> NodesInfo;
+};
+
+class TNodeTabletMonitor : public TActorBootstrapped<TNodeTabletMonitor> {
private:
TIntrusivePtr<ITabletStateClassifier> StateClassifier;
TIntrusivePtr<ITabletListRenderer> TableRenderer;
-public:
+public:
static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
return NKikimrServices::TActivity::TABLET_MONITORING_PROXY;
@@ -425,63 +425,63 @@ public:
: StateClassifier(stateClassifier)
, TableRenderer(renderer)
{
- }
-
- void Bootstrap(const TActorContext &ctx) {
- Become(&TThis::StateWork);
- NActors::TMon* mon = AppData(ctx)->Mon;
-
- if (mon) {
- mon->RegisterActorPage(nullptr, "nodetabmon", "Node Tablet Monitor", false, ctx.ExecutorThread.ActorSystem, ctx.SelfID);
- }
- }
-
-private:
- STFUNC(StateWork) {
- switch (ev->GetTypeRewrite()) {
- HFunc(NMon::TEvHttpInfo, Handle);
- }
- }
-
- void Handle(NMon::TEvHttpInfo::TPtr &ev, const TActorContext &ctx) {
- NMon::TEvHttpInfo* msg = ev->Get();
+ }
+
+ void Bootstrap(const TActorContext &ctx) {
+ Become(&TThis::StateWork);
+ NActors::TMon* mon = AppData(ctx)->Mon;
+
+ if (mon) {
+ mon->RegisterActorPage(nullptr, "nodetabmon", "Node Tablet Monitor", false, ctx.ExecutorThread.ActorSystem, ctx.SelfID);
+ }
+ }
+
+private:
+ STFUNC(StateWork) {
+ switch (ev->GetTypeRewrite()) {
+ HFunc(NMon::TEvHttpInfo, Handle);
+ }
+ }
+
+ void Handle(NMon::TEvHttpInfo::TPtr &ev, const TActorContext &ctx) {
+ NMon::TEvHttpInfo* msg = ev->Get();
const TCgiParameters& cgi = msg->Request.GetParams();
- if (cgi.Has("action")) {
+ if (cgi.Has("action")) {
const TString &actionParam = cgi.Get("action");
- if (actionParam == "browse_nodes") {
- ctx.ExecutorThread.RegisterActor(new TNodeList(ev->Sender));
- return;
- } else if (actionParam == "kill_tablet") {
- if (cgi.Has("tablet_id")) {
- ui64 tabletId = FromStringWithDefault<ui64>(cgi.Get("tablet_id"));
+ if (actionParam == "browse_nodes") {
+ ctx.ExecutorThread.RegisterActor(new TNodeList(ev->Sender));
+ return;
+ } else if (actionParam == "kill_tablet") {
+ if (cgi.Has("tablet_id")) {
+ ui64 tabletId = FromStringWithDefault<ui64>(cgi.Get("tablet_id"));
ctx.Register(CreateTabletKiller(tabletId));
- if (cgi.Has("filter_node_id"))
- ctx.Send(ev->Sender, new NMon::TEvHttpInfoRes("<meta http-equiv=\"refresh\" content=\"0; nodetabmon?action=browse_tablets&node_id=" + cgi.Get("filter_node_id") + "\" />"));
- else
- ctx.Send(ev->Sender, new NMon::TEvHttpInfoRes("<meta http-equiv=\"refresh\" content=\"0; nodetabmon?action=browse_tablets\" />"));
- return;
- }
- } else if (actionParam == "browse_tablets") {
- ui32 filterNodeId = 0;
- if (cgi.Has("node_id"))
- filterNodeId = FromStringWithDefault<ui32>(cgi.Get("node_id"));
+ if (cgi.Has("filter_node_id"))
+ ctx.Send(ev->Sender, new NMon::TEvHttpInfoRes("<meta http-equiv=\"refresh\" content=\"0; nodetabmon?action=browse_tablets&node_id=" + cgi.Get("filter_node_id") + "\" />"));
+ else
+ ctx.Send(ev->Sender, new NMon::TEvHttpInfoRes("<meta http-equiv=\"refresh\" content=\"0; nodetabmon?action=browse_tablets\" />"));
+ return;
+ }
+ } else if (actionParam == "browse_tablets") {
+ ui32 filterNodeId = 0;
+ if (cgi.Has("node_id"))
+ filterNodeId = FromStringWithDefault<ui32>(cgi.Get("node_id"));
ctx.ExecutorThread.RegisterActor(new TTabletList(ev->Sender, filterNodeId, StateClassifier, TableRenderer));
- return;
- } else if (actionParam == "browse_ss" && cgi.Has("ss_id")) {
- ctx.ExecutorThread.RegisterActor(new TStateStorageTabletList(ev->Sender, FromStringWithDefault<ui32>(cgi.Get("ss_id"))));
- return;
- }
- }
- ctx.ExecutorThread.RegisterActor(new TNodeList(ev->Sender));
- }
-};
-
-
+ return;
+ } else if (actionParam == "browse_ss" && cgi.Has("ss_id")) {
+ ctx.ExecutorThread.RegisterActor(new TStateStorageTabletList(ev->Sender, FromStringWithDefault<ui32>(cgi.Get("ss_id"))));
+ return;
+ }
+ }
+ ctx.ExecutorThread.RegisterActor(new TNodeList(ev->Sender));
+ }
+};
+
+
IActor* CreateNodeTabletMonitor(const TIntrusivePtr<ITabletStateClassifier>& stateClassifier,
const TIntrusivePtr<ITabletListRenderer>& renderer)
{
return new TNodeTabletMonitor(stateClassifier, renderer);
-}
-
-} // NNodeTabletMonitor
-} // NKikimr
+}
+
+} // NNodeTabletMonitor
+} // NKikimr
diff --git a/ydb/core/tablet/node_tablet_monitor.h b/ydb/core/tablet/node_tablet_monitor.h
index 7d285c601cb..0fe88912003 100644
--- a/ydb/core/tablet/node_tablet_monitor.h
+++ b/ydb/core/tablet/node_tablet_monitor.h
@@ -1,6 +1,6 @@
-#pragma once
-
-#include "defs.h"
+#pragma once
+
+#include "defs.h"
#include <library/cpp/actors/core/defs.h>
#include <library/cpp/actors/core/actor.h>
#include <library/cpp/actors/core/event.h>
@@ -9,16 +9,16 @@
#include <ydb/core/protos/node_whiteboard.pb.h>
#include <util/generic/ptr.h>
#include <util/stream/str.h>
-
-namespace NKikimr {
-namespace NNodeTabletMonitor {
-
+
+namespace NKikimr {
+namespace NNodeTabletMonitor {
+
inline TActorId MakeNodeTabletMonitorID(ui32 node = 0) {
- char x[12] = {'n','o','d','e','t','a','b','l','e','t','m','o'};
+ char x[12] = {'n','o','d','e','t','a','b','l','e','t','m','o'};
return TActorId(node, TStringBuf(x, 12));
-}
-
-
+}
+
+
struct ITabletStateClassifier : public TAtomicRefCount<ITabletStateClassifier>{
virtual ui32 GetMaxTabletStateClass() const = 0;
virtual std::function<bool(const NKikimrWhiteboard::TTabletStateInfo&)> GetTabletStateClassFilter(ui32 cls) const = 0;
@@ -56,5 +56,5 @@ struct ITabletListRenderer : public TAtomicRefCount<ITabletListRenderer> {
IActor* CreateNodeTabletMonitor(const TIntrusivePtr<ITabletStateClassifier>& stateClassifier,
const TIntrusivePtr<ITabletListRenderer>& renderer);
-} // NNodeTabletMonitor
-} // NKikimr
+} // NNodeTabletMonitor
+} // NKikimr
diff --git a/ydb/core/tablet/node_whiteboard.cpp b/ydb/core/tablet/node_whiteboard.cpp
index 958a2bd1108..783758e99d1 100644
--- a/ydb/core/tablet/node_whiteboard.cpp
+++ b/ydb/core/tablet/node_whiteboard.cpp
@@ -1,413 +1,413 @@
-#include <cmath>
+#include <cmath>
#include <library/cpp/svnversion/svnversion.h>
-#include <util/system/info.h>
+#include <util/system/info.h>
#include <ydb/core/base/appdata.h>
#include <ydb/core/mon_alloc/stats.h>
#include <library/cpp/actors/core/actor.h>
#include <library/cpp/actors/core/actor_bootstrapped.h>
#include <library/cpp/actors/core/hfunc.h>
-#include <library/cpp/actors/core/process_stats.h>
+#include <library/cpp/actors/core/process_stats.h>
#include <ydb/core/node_whiteboard/node_whiteboard.h>
#include "tablet_counters.h"
#include <ydb/core/base/counters.h>
#include <ydb/core/util/tuples.h>
-
-using namespace NActors;
-
-namespace NKikimr {
-namespace NNodeWhiteboard {
-
-class TNodeWhiteboardService : public TActorBootstrapped<TNodeWhiteboardService> {
- struct TEvPrivate {
- enum EEv {
- EvUpdateRuntimeStats = EventSpaceBegin(TEvents::ES_PRIVATE),
- EvCleanupDeadTablets,
- EvEnd
- };
-
- static_assert(EvEnd < EventSpaceEnd(TEvents::ES_PRIVATE), "expected EvEnd < EventSpaceEnd");
-
- struct TEvUpdateRuntimeStats : TEventLocal<TEvUpdateRuntimeStats, EvUpdateRuntimeStats> {};
- struct TEvCleanupDeadTablets : TEventLocal<TEvCleanupDeadTablets, EvCleanupDeadTablets> {};
- };
-public:
+
+using namespace NActors;
+
+namespace NKikimr {
+namespace NNodeWhiteboard {
+
+class TNodeWhiteboardService : public TActorBootstrapped<TNodeWhiteboardService> {
+ struct TEvPrivate {
+ enum EEv {
+ EvUpdateRuntimeStats = EventSpaceBegin(TEvents::ES_PRIVATE),
+ EvCleanupDeadTablets,
+ EvEnd
+ };
+
+ static_assert(EvEnd < EventSpaceEnd(TEvents::ES_PRIVATE), "expected EvEnd < EventSpaceEnd");
+
+ struct TEvUpdateRuntimeStats : TEventLocal<TEvUpdateRuntimeStats, EvUpdateRuntimeStats> {};
+ struct TEvCleanupDeadTablets : TEventLocal<TEvCleanupDeadTablets, EvCleanupDeadTablets> {};
+ };
+public:
static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
return NKikimrServices::TActivity::NODE_WHITEBOARD_SERVICE;
}
- void Bootstrap(const TActorContext &ctx) {
+ void Bootstrap(const TActorContext &ctx) {
TIntrusivePtr<NMonitoring::TDynamicCounters> tabletsGroup = GetServiceCounters(AppData(ctx)->Counters, "tablets");
TIntrusivePtr<NMonitoring::TDynamicCounters> introspectionGroup = tabletsGroup->GetSubgroup("type", "introspection");
TabletIntrospectionData.Reset(NTracing::CreateTraceCollection(introspectionGroup));
- SystemStateInfo.SetNumberOfCpus(NSystemInfo::NumberOfCpus());
- TString branch = GetTag();
- if (branch.empty()) {
- branch = GetBranch();
- }
- auto pos = branch.rfind('/');
- if (pos != TString::npos) { // only the part after the last slash is used
- branch = branch.substr(pos + 1);
- }
- TString version = GetProgramCommitId();
- if (!version.empty()) {
- if (version.size() > 7) { // we limit the version size to 7 characters (the same way as in Arcanum)
- version = version.substr(0, 7);
- }
- version = branch + '.' + version;
- SystemStateInfo.SetVersion(version);
+ SystemStateInfo.SetNumberOfCpus(NSystemInfo::NumberOfCpus());
+ TString branch = GetTag();
+ if (branch.empty()) {
+ branch = GetBranch();
+ }
+ auto pos = branch.rfind('/');
+ if (pos != TString::npos) { // only the part after the last slash is used
+ branch = branch.substr(pos + 1);
+ }
+ TString version = GetProgramCommitId();
+ if (!version.empty()) {
+ if (version.size() > 7) { // we limit the version size to 7 characters (the same way as in Arcanum)
+ version = version.substr(0, 7);
+ }
+ version = branch + '.' + version;
+ SystemStateInfo.SetVersion(version);
auto versionCounter = GetServiceCounters(AppData(ctx)->Counters, "utils")->GetSubgroup("revision", version);
*versionCounter->GetCounter("version", false) = 1;
- }
- SystemStateInfo.SetStartTime(ctx.Now().MilliSeconds());
- ProcessStats.Fill(getpid());
- if (ProcessStats.CGroupMemLim != 0) {
- SystemStateInfo.SetMemoryLimit(ProcessStats.CGroupMemLim);
- }
- ctx.Send(ctx.SelfID, new TEvPrivate::TEvUpdateRuntimeStats());
- ctx.Schedule(TDuration::Seconds(60), new TEvPrivate::TEvCleanupDeadTablets());
- Become(&TNodeWhiteboardService::StateFunc);
- }
-
-protected:
+ }
+ SystemStateInfo.SetStartTime(ctx.Now().MilliSeconds());
+ ProcessStats.Fill(getpid());
+ if (ProcessStats.CGroupMemLim != 0) {
+ SystemStateInfo.SetMemoryLimit(ProcessStats.CGroupMemLim);
+ }
+ ctx.Send(ctx.SelfID, new TEvPrivate::TEvUpdateRuntimeStats());
+ ctx.Schedule(TDuration::Seconds(60), new TEvPrivate::TEvCleanupDeadTablets());
+ Become(&TNodeWhiteboardService::StateFunc);
+ }
+
+protected:
std::unordered_map<std::pair<TTabletId, TFollowerId>, NKikimrWhiteboard::TTabletStateInfo> TabletStateInfo;
- std::unordered_map<TString, NKikimrWhiteboard::TNodeStateInfo> NodeStateInfo;
- std::unordered_map<ui32, NKikimrWhiteboard::TPDiskStateInfo> PDiskStateInfo;
+ std::unordered_map<TString, NKikimrWhiteboard::TNodeStateInfo> NodeStateInfo;
+ std::unordered_map<ui32, NKikimrWhiteboard::TPDiskStateInfo> PDiskStateInfo;
std::unordered_map<TVDiskID, NKikimrWhiteboard::TVDiskStateInfo, THash<TVDiskID>> VDiskStateInfo;
- std::unordered_map<ui32, NKikimrWhiteboard::TBSGroupStateInfo> BSGroupStateInfo;
- NKikimrWhiteboard::TSystemStateInfo SystemStateInfo;
+ std::unordered_map<ui32, NKikimrWhiteboard::TBSGroupStateInfo> BSGroupStateInfo;
+ NKikimrWhiteboard::TSystemStateInfo SystemStateInfo;
THolder<NTracing::ITraceCollection> TabletIntrospectionData;
- TProcStat ProcessStats;
-
- template <typename PropertyType>
- static ui64 GetDifference(PropertyType a, PropertyType b) {
+ TProcStat ProcessStats;
+
+ template <typename PropertyType>
+ static ui64 GetDifference(PropertyType a, PropertyType b) {
return static_cast<ui64>(std::abs(static_cast<std::make_signed_t<PropertyType>>(b) -
static_cast<std::make_signed_t<PropertyType>>(a)));
- }
-
- static ui64 GetDifference(double a, double b) {
- return static_cast<ui64>(std::fabs(b - a));
- }
-
- static ui64 GetDifference(float a, float b) {
- return static_cast<ui64>(std::fabs(b - a));
- }
-
- static ui64 GetDifference(bool a, bool b) {
- return static_cast<ui64>(std::abs(static_cast<int>(b) - static_cast<int>(a)));
- }
-
- template <typename PropertyType>
- static int MergeProtoField(
- const ::google::protobuf::Reflection& reflectionTo,
- const ::google::protobuf::Reflection& reflectionFrom,
- ::google::protobuf::Message& protoTo,
- const ::google::protobuf::Message& protoFrom,
- const ::google::protobuf::FieldDescriptor* field,
- PropertyType (::google::protobuf::Reflection::* getter)(const ::google::protobuf::Message&, const ::google::protobuf::FieldDescriptor*) const,
+ }
+
+ static ui64 GetDifference(double a, double b) {
+ return static_cast<ui64>(std::fabs(b - a));
+ }
+
+ static ui64 GetDifference(float a, float b) {
+ return static_cast<ui64>(std::fabs(b - a));
+ }
+
+ static ui64 GetDifference(bool a, bool b) {
+ return static_cast<ui64>(std::abs(static_cast<int>(b) - static_cast<int>(a)));
+ }
+
+ template <typename PropertyType>
+ static int MergeProtoField(
+ const ::google::protobuf::Reflection& reflectionTo,
+ const ::google::protobuf::Reflection& reflectionFrom,
+ ::google::protobuf::Message& protoTo,
+ const ::google::protobuf::Message& protoFrom,
+ const ::google::protobuf::FieldDescriptor* field,
+ PropertyType (::google::protobuf::Reflection::* getter)(const ::google::protobuf::Message&, const ::google::protobuf::FieldDescriptor*) const,
void (::google::protobuf::Reflection::* setter)(::google::protobuf::Message*, const ::google::protobuf::FieldDescriptor*, PropertyType) const,
PropertyType defaultVal) {
- int modified = 0;
- bool has = reflectionTo.HasField(protoTo, field);
- PropertyType newVal = (reflectionFrom.*getter)(protoFrom, field);
- if (!has) {
+ int modified = 0;
+ bool has = reflectionTo.HasField(protoTo, field);
+ PropertyType newVal = (reflectionFrom.*getter)(protoFrom, field);
+ if (!has) {
if (field->has_default_value() && newVal == defaultVal) {
reflectionTo.ClearField(&protoTo, field);
} else {
(reflectionTo.*setter)(&protoTo, field, newVal);
}
- modified = 100;
- } else {
- PropertyType oldVal = (reflectionTo.*getter)(protoTo, field);
- if (oldVal != newVal) {
+ modified = 100;
+ } else {
+ PropertyType oldVal = (reflectionTo.*getter)(protoTo, field);
+ if (oldVal != newVal) {
if (field->has_default_value() && newVal == defaultVal) {
reflectionTo.ClearField(&protoTo, field);
} else {
(reflectionTo.*setter)(&protoTo, field, newVal);
}
- const auto& options(field->options());
- if (options.HasExtension(NKikimrWhiteboard::InsignificantChangeAmount)) {
- ui64 insignificantChangeAmount = options.GetExtension(NKikimrWhiteboard::InsignificantChangeAmount);
- if (GetDifference(oldVal, newVal) > insignificantChangeAmount) {
- modified = 100;
- }
- } else if (options.HasExtension(NKikimrWhiteboard::InsignificantChangePercent)) {
- ui32 insignificantChangePercent = options.GetExtension(NKikimrWhiteboard::InsignificantChangePercent);
- if (oldVal != PropertyType() && GetDifference(oldVal, newVal) * 100 / oldVal > insignificantChangePercent) {
- modified = 100;
- }
- } else {
- modified = 100;
- }
- }
- }
- return modified;
- }
-
- static int CheckedMerge(::google::protobuf::Message& protoTo, const ::google::protobuf::Message& protoFrom) {
- using namespace ::google::protobuf;
- int modified = 0;
- const Descriptor& descriptor = *protoTo.GetDescriptor();
- const Reflection& reflectionTo = *protoTo.GetReflection();
- const Reflection& reflectionFrom = *protoFrom.GetReflection();
- int fieldCount = descriptor.field_count();
- for (int index = 0; index < fieldCount; ++index) {
- const FieldDescriptor* field = descriptor.field(index);
- if (field->is_repeated()) {
- FieldDescriptor::CppType type = field->cpp_type();
- int size = reflectionFrom.FieldSize(protoFrom, field);
- if (size != 0 && reflectionTo.FieldSize(protoTo, field) != size) {
- reflectionTo.ClearField(&protoTo, field);
- for (int i = 0; i < size; ++i) {
- switch (type) {
- case FieldDescriptor::CPPTYPE_INT32:
- reflectionTo.AddInt32(&protoTo, field, reflectionFrom.GetRepeatedInt32(protoFrom, field, i));
- break;
- case FieldDescriptor::CPPTYPE_INT64:
- reflectionTo.AddInt64(&protoTo, field, reflectionFrom.GetRepeatedInt64(protoFrom, field, i));
- break;
- case FieldDescriptor::CPPTYPE_UINT32:
- reflectionTo.AddUInt32(&protoTo, field, reflectionFrom.GetRepeatedUInt32(protoFrom, field, i));
- break;
- case FieldDescriptor::CPPTYPE_UINT64:
- reflectionTo.AddUInt64(&protoTo, field, reflectionFrom.GetRepeatedUInt64(protoFrom, field, i));
- break;
- case FieldDescriptor::CPPTYPE_DOUBLE:
- reflectionTo.AddDouble(&protoTo, field, reflectionFrom.GetRepeatedDouble(protoFrom, field, i));
- break;
- case FieldDescriptor::CPPTYPE_FLOAT:
- reflectionTo.AddFloat(&protoTo, field, reflectionFrom.GetRepeatedFloat(protoFrom, field, i));
- break;
- case FieldDescriptor::CPPTYPE_BOOL:
- reflectionTo.AddBool(&protoTo, field, reflectionFrom.GetRepeatedBool(protoFrom, field, i));
- break;
- case FieldDescriptor::CPPTYPE_ENUM:
- reflectionTo.AddEnum(&protoTo, field, reflectionFrom.GetRepeatedEnum(protoFrom, field, i));
- break;
- case FieldDescriptor::CPPTYPE_STRING:
- reflectionTo.AddString(&protoTo, field, reflectionFrom.GetRepeatedString(protoFrom, field, i));
- break;
- case FieldDescriptor::CPPTYPE_MESSAGE:
- reflectionTo.AddMessage(&protoTo, field)->CopyFrom(reflectionFrom.GetRepeatedMessage(protoFrom, field, i));
- break;
- }
- }
- modified += 100;
- } else {
- for (int i = 0; i < size; ++i) {
- switch (type) {
- case FieldDescriptor::CPPTYPE_INT32: {
- auto val = reflectionFrom.GetRepeatedInt32(protoFrom, field, i);
- if (val != reflectionTo.GetRepeatedInt32(protoTo, field, i)) {
- reflectionTo.SetRepeatedInt32(&protoTo, field, i, val);
- modified += 100;
- }
- break;
- }
- case FieldDescriptor::CPPTYPE_INT64: {
- auto val = reflectionFrom.GetRepeatedInt64(protoFrom, field, i);
- if (val != reflectionTo.GetRepeatedInt64(protoTo, field, i)) {
- reflectionTo.SetRepeatedInt64(&protoTo, field, i, val);
- modified += 100;
- }
- break;
- }
- case FieldDescriptor::CPPTYPE_UINT32: {
- auto val = reflectionFrom.GetRepeatedUInt32(protoFrom, field, i);
- if (val != reflectionTo.GetRepeatedUInt32(protoTo, field, i)) {
- reflectionTo.SetRepeatedUInt32(&protoTo, field, i, val);
- modified += 100;
- }
- break;
- }
- case FieldDescriptor::CPPTYPE_UINT64: {
- auto val = reflectionFrom.GetRepeatedUInt64(protoFrom, field, i);
- if (val != reflectionTo.GetRepeatedUInt64(protoTo, field, i)) {
- reflectionTo.SetRepeatedUInt64(&protoTo, field, i, val);
- modified += 100;
- }
- break;
- }
- case FieldDescriptor::CPPTYPE_DOUBLE: {
- auto val = reflectionFrom.GetRepeatedDouble(protoFrom, field, i);
- if (val != reflectionTo.GetRepeatedDouble(protoTo, field, i)) {
- reflectionTo.SetRepeatedDouble(&protoTo, field, i, val);
- modified += 100;
- }
- break;
- }
- case FieldDescriptor::CPPTYPE_FLOAT: {
- auto val = reflectionFrom.GetRepeatedFloat(protoFrom, field, i);
- if (val != reflectionTo.GetRepeatedFloat(protoTo, field, i)) {
- reflectionTo.SetRepeatedFloat(&protoTo, field, i, val);
- modified += 100;
- }
- break;
- }
- case FieldDescriptor::CPPTYPE_BOOL: {
- auto val = reflectionFrom.GetRepeatedBool(protoFrom, field, i);
- if (val != reflectionTo.GetRepeatedBool(protoTo, field, i)) {
- reflectionTo.SetRepeatedBool(&protoTo, field, i, val);
- modified += 100;
- }
- break;
- }
- case FieldDescriptor::CPPTYPE_ENUM: {
- auto val = reflectionFrom.GetRepeatedEnum(protoFrom, field, i);
- if (val->number() != reflectionTo.GetRepeatedEnum(protoTo, field, i)->number()) {
- reflectionTo.SetRepeatedEnum(&protoTo, field, i, val);
- modified += 100;
- }
- break;
- }
- case FieldDescriptor::CPPTYPE_STRING: {
- auto val = reflectionFrom.GetRepeatedString(protoFrom, field, i);
- if (val != reflectionTo.GetRepeatedString(protoTo, field, i)) {
- reflectionTo.SetRepeatedString(&protoTo, field, i, val);
- modified += 100;
- }
- break;
- }
- case FieldDescriptor::CPPTYPE_MESSAGE:
- modified += CheckedMerge(*reflectionTo.MutableRepeatedMessage(&protoTo, field, i), reflectionFrom.GetRepeatedMessage(protoFrom, field, i));
- break;
- }
- }
- }
- } else {
- if (reflectionFrom.HasField(protoFrom, field)) {
- FieldDescriptor::CppType type = field->cpp_type();
- switch (type) {
- case FieldDescriptor::CPPTYPE_INT32: {
+ const auto& options(field->options());
+ if (options.HasExtension(NKikimrWhiteboard::InsignificantChangeAmount)) {
+ ui64 insignificantChangeAmount = options.GetExtension(NKikimrWhiteboard::InsignificantChangeAmount);
+ if (GetDifference(oldVal, newVal) > insignificantChangeAmount) {
+ modified = 100;
+ }
+ } else if (options.HasExtension(NKikimrWhiteboard::InsignificantChangePercent)) {
+ ui32 insignificantChangePercent = options.GetExtension(NKikimrWhiteboard::InsignificantChangePercent);
+ if (oldVal != PropertyType() && GetDifference(oldVal, newVal) * 100 / oldVal > insignificantChangePercent) {
+ modified = 100;
+ }
+ } else {
+ modified = 100;
+ }
+ }
+ }
+ return modified;
+ }
+
+ static int CheckedMerge(::google::protobuf::Message& protoTo, const ::google::protobuf::Message& protoFrom) {
+ using namespace ::google::protobuf;
+ int modified = 0;
+ const Descriptor& descriptor = *protoTo.GetDescriptor();
+ const Reflection& reflectionTo = *protoTo.GetReflection();
+ const Reflection& reflectionFrom = *protoFrom.GetReflection();
+ int fieldCount = descriptor.field_count();
+ for (int index = 0; index < fieldCount; ++index) {
+ const FieldDescriptor* field = descriptor.field(index);
+ if (field->is_repeated()) {
+ FieldDescriptor::CppType type = field->cpp_type();
+ int size = reflectionFrom.FieldSize(protoFrom, field);
+ if (size != 0 && reflectionTo.FieldSize(protoTo, field) != size) {
+ reflectionTo.ClearField(&protoTo, field);
+ for (int i = 0; i < size; ++i) {
+ switch (type) {
+ case FieldDescriptor::CPPTYPE_INT32:
+ reflectionTo.AddInt32(&protoTo, field, reflectionFrom.GetRepeatedInt32(protoFrom, field, i));
+ break;
+ case FieldDescriptor::CPPTYPE_INT64:
+ reflectionTo.AddInt64(&protoTo, field, reflectionFrom.GetRepeatedInt64(protoFrom, field, i));
+ break;
+ case FieldDescriptor::CPPTYPE_UINT32:
+ reflectionTo.AddUInt32(&protoTo, field, reflectionFrom.GetRepeatedUInt32(protoFrom, field, i));
+ break;
+ case FieldDescriptor::CPPTYPE_UINT64:
+ reflectionTo.AddUInt64(&protoTo, field, reflectionFrom.GetRepeatedUInt64(protoFrom, field, i));
+ break;
+ case FieldDescriptor::CPPTYPE_DOUBLE:
+ reflectionTo.AddDouble(&protoTo, field, reflectionFrom.GetRepeatedDouble(protoFrom, field, i));
+ break;
+ case FieldDescriptor::CPPTYPE_FLOAT:
+ reflectionTo.AddFloat(&protoTo, field, reflectionFrom.GetRepeatedFloat(protoFrom, field, i));
+ break;
+ case FieldDescriptor::CPPTYPE_BOOL:
+ reflectionTo.AddBool(&protoTo, field, reflectionFrom.GetRepeatedBool(protoFrom, field, i));
+ break;
+ case FieldDescriptor::CPPTYPE_ENUM:
+ reflectionTo.AddEnum(&protoTo, field, reflectionFrom.GetRepeatedEnum(protoFrom, field, i));
+ break;
+ case FieldDescriptor::CPPTYPE_STRING:
+ reflectionTo.AddString(&protoTo, field, reflectionFrom.GetRepeatedString(protoFrom, field, i));
+ break;
+ case FieldDescriptor::CPPTYPE_MESSAGE:
+ reflectionTo.AddMessage(&protoTo, field)->CopyFrom(reflectionFrom.GetRepeatedMessage(protoFrom, field, i));
+ break;
+ }
+ }
+ modified += 100;
+ } else {
+ for (int i = 0; i < size; ++i) {
+ switch (type) {
+ case FieldDescriptor::CPPTYPE_INT32: {
+ auto val = reflectionFrom.GetRepeatedInt32(protoFrom, field, i);
+ if (val != reflectionTo.GetRepeatedInt32(protoTo, field, i)) {
+ reflectionTo.SetRepeatedInt32(&protoTo, field, i, val);
+ modified += 100;
+ }
+ break;
+ }
+ case FieldDescriptor::CPPTYPE_INT64: {
+ auto val = reflectionFrom.GetRepeatedInt64(protoFrom, field, i);
+ if (val != reflectionTo.GetRepeatedInt64(protoTo, field, i)) {
+ reflectionTo.SetRepeatedInt64(&protoTo, field, i, val);
+ modified += 100;
+ }
+ break;
+ }
+ case FieldDescriptor::CPPTYPE_UINT32: {
+ auto val = reflectionFrom.GetRepeatedUInt32(protoFrom, field, i);
+ if (val != reflectionTo.GetRepeatedUInt32(protoTo, field, i)) {
+ reflectionTo.SetRepeatedUInt32(&protoTo, field, i, val);
+ modified += 100;
+ }
+ break;
+ }
+ case FieldDescriptor::CPPTYPE_UINT64: {
+ auto val = reflectionFrom.GetRepeatedUInt64(protoFrom, field, i);
+ if (val != reflectionTo.GetRepeatedUInt64(protoTo, field, i)) {
+ reflectionTo.SetRepeatedUInt64(&protoTo, field, i, val);
+ modified += 100;
+ }
+ break;
+ }
+ case FieldDescriptor::CPPTYPE_DOUBLE: {
+ auto val = reflectionFrom.GetRepeatedDouble(protoFrom, field, i);
+ if (val != reflectionTo.GetRepeatedDouble(protoTo, field, i)) {
+ reflectionTo.SetRepeatedDouble(&protoTo, field, i, val);
+ modified += 100;
+ }
+ break;
+ }
+ case FieldDescriptor::CPPTYPE_FLOAT: {
+ auto val = reflectionFrom.GetRepeatedFloat(protoFrom, field, i);
+ if (val != reflectionTo.GetRepeatedFloat(protoTo, field, i)) {
+ reflectionTo.SetRepeatedFloat(&protoTo, field, i, val);
+ modified += 100;
+ }
+ break;
+ }
+ case FieldDescriptor::CPPTYPE_BOOL: {
+ auto val = reflectionFrom.GetRepeatedBool(protoFrom, field, i);
+ if (val != reflectionTo.GetRepeatedBool(protoTo, field, i)) {
+ reflectionTo.SetRepeatedBool(&protoTo, field, i, val);
+ modified += 100;
+ }
+ break;
+ }
+ case FieldDescriptor::CPPTYPE_ENUM: {
+ auto val = reflectionFrom.GetRepeatedEnum(protoFrom, field, i);
+ if (val->number() != reflectionTo.GetRepeatedEnum(protoTo, field, i)->number()) {
+ reflectionTo.SetRepeatedEnum(&protoTo, field, i, val);
+ modified += 100;
+ }
+ break;
+ }
+ case FieldDescriptor::CPPTYPE_STRING: {
+ auto val = reflectionFrom.GetRepeatedString(protoFrom, field, i);
+ if (val != reflectionTo.GetRepeatedString(protoTo, field, i)) {
+ reflectionTo.SetRepeatedString(&protoTo, field, i, val);
+ modified += 100;
+ }
+ break;
+ }
+ case FieldDescriptor::CPPTYPE_MESSAGE:
+ modified += CheckedMerge(*reflectionTo.MutableRepeatedMessage(&protoTo, field, i), reflectionFrom.GetRepeatedMessage(protoFrom, field, i));
+ break;
+ }
+ }
+ }
+ } else {
+ if (reflectionFrom.HasField(protoFrom, field)) {
+ FieldDescriptor::CppType type = field->cpp_type();
+ switch (type) {
+ case FieldDescriptor::CPPTYPE_INT32: {
modified += MergeProtoField(reflectionTo, reflectionFrom, protoTo, protoFrom, field, &Reflection::GetInt32, &Reflection::SetInt32, field->default_value_int32());
- break;
- }
- case FieldDescriptor::CPPTYPE_INT64: {
+ break;
+ }
+ case FieldDescriptor::CPPTYPE_INT64: {
modified += MergeProtoField(reflectionTo, reflectionFrom, protoTo, protoFrom, field, &Reflection::GetInt64, &Reflection::SetInt64, field->default_value_int64());
- break;
- }
- case FieldDescriptor::CPPTYPE_UINT32: {
+ break;
+ }
+ case FieldDescriptor::CPPTYPE_UINT32: {
modified += MergeProtoField(reflectionTo, reflectionFrom, protoTo, protoFrom, field, &Reflection::GetUInt32, &Reflection::SetUInt32, field->default_value_uint32());
- break;
- }
- case FieldDescriptor::CPPTYPE_UINT64: {
+ break;
+ }
+ case FieldDescriptor::CPPTYPE_UINT64: {
modified += MergeProtoField(reflectionTo, reflectionFrom, protoTo, protoFrom, field, &Reflection::GetUInt64, &Reflection::SetUInt64, field->default_value_uint64());
- break;
- }
- case FieldDescriptor::CPPTYPE_DOUBLE: {
+ break;
+ }
+ case FieldDescriptor::CPPTYPE_DOUBLE: {
modified += MergeProtoField(reflectionTo, reflectionFrom, protoTo, protoFrom, field, &Reflection::GetDouble, &Reflection::SetDouble, field->default_value_double());
- break;
- }
- case FieldDescriptor::CPPTYPE_FLOAT: {
+ break;
+ }
+ case FieldDescriptor::CPPTYPE_FLOAT: {
modified += MergeProtoField(reflectionTo, reflectionFrom, protoTo, protoFrom, field, &Reflection::GetFloat, &Reflection::SetFloat, field->default_value_float());
- break;
- }
- case FieldDescriptor::CPPTYPE_BOOL: {
+ break;
+ }
+ case FieldDescriptor::CPPTYPE_BOOL: {
modified += MergeProtoField(reflectionTo, reflectionFrom, protoTo, protoFrom, field, &Reflection::GetBool, &Reflection::SetBool, field->default_value_bool());
- break;
- }
- case FieldDescriptor::CPPTYPE_ENUM: {
- bool has = reflectionTo.HasField(protoTo, field);
- auto val = reflectionFrom.GetEnum(protoFrom, field);
- if (!has || reflectionTo.GetEnum(protoTo, field)->number() != val->number()) {
+ break;
+ }
+ case FieldDescriptor::CPPTYPE_ENUM: {
+ bool has = reflectionTo.HasField(protoTo, field);
+ auto val = reflectionFrom.GetEnum(protoFrom, field);
+ if (!has || reflectionTo.GetEnum(protoTo, field)->number() != val->number()) {
if (field->has_default_value() && val->number() == field->default_value_enum()->number()) {
reflectionTo.ClearField(&protoTo, field);
} else {
reflectionTo.SetEnum(&protoTo, field, val);
}
- modified += 100;
- }
- break;
- }
- case FieldDescriptor::CPPTYPE_STRING: {
- bool has = reflectionTo.HasField(protoTo, field);
- auto val = reflectionFrom.GetString(protoFrom, field);
- if (!has || reflectionTo.GetString(protoTo, field) != val) {
+ modified += 100;
+ }
+ break;
+ }
+ case FieldDescriptor::CPPTYPE_STRING: {
+ bool has = reflectionTo.HasField(protoTo, field);
+ auto val = reflectionFrom.GetString(protoFrom, field);
+ if (!has || reflectionTo.GetString(protoTo, field) != val) {
if (field->has_default_value() && field->default_value_string() == val) {
reflectionTo.ClearField(&protoTo, field);
} else {
reflectionTo.SetString(&protoTo, field, val);
}
- modified += 100;
- }
- break;
- }
- case FieldDescriptor::CPPTYPE_MESSAGE:
- modified += CheckedMerge(*reflectionTo.MutableMessage(&protoTo, field), reflectionFrom.GetMessage(protoFrom, field));
- break;
- }
- }
- }
- }
- return modified;
- }
-
- void StateFunc(TAutoPtr<IEventHandle> &ev, const TActorContext &ctx) {
- switch (ev->GetTypeRewrite()) {
- HFunc(TEvWhiteboard::TEvTabletStateUpdate, Handle);
- HFunc(TEvWhiteboard::TEvTabletStateRequest, Handle);
+ modified += 100;
+ }
+ break;
+ }
+ case FieldDescriptor::CPPTYPE_MESSAGE:
+ modified += CheckedMerge(*reflectionTo.MutableMessage(&protoTo, field), reflectionFrom.GetMessage(protoFrom, field));
+ break;
+ }
+ }
+ }
+ }
+ return modified;
+ }
+
+ void StateFunc(TAutoPtr<IEventHandle> &ev, const TActorContext &ctx) {
+ switch (ev->GetTypeRewrite()) {
+ HFunc(TEvWhiteboard::TEvTabletStateUpdate, Handle);
+ HFunc(TEvWhiteboard::TEvTabletStateRequest, Handle);
HFunc(TEvWhiteboard::TEvNodeStateUpdate, Handle);
HFunc(TEvWhiteboard::TEvNodeStateDelete, Handle);
HFunc(TEvWhiteboard::TEvNodeStateRequest, Handle);
- HFunc(TEvWhiteboard::TEvPDiskStateUpdate, Handle);
- HFunc(TEvWhiteboard::TEvPDiskStateRequest, Handle);
+ HFunc(TEvWhiteboard::TEvPDiskStateUpdate, Handle);
+ HFunc(TEvWhiteboard::TEvPDiskStateRequest, Handle);
HFunc(TEvWhiteboard::TEvPDiskStateDelete, Handle);
- HFunc(TEvWhiteboard::TEvVDiskStateUpdate, Handle);
+ HFunc(TEvWhiteboard::TEvVDiskStateUpdate, Handle);
HFunc(TEvWhiteboard::TEvVDiskStateGenerationChange, Handle);
- HFunc(TEvWhiteboard::TEvVDiskStateDelete, Handle);
- HFunc(TEvWhiteboard::TEvVDiskStateRequest, Handle);
- HFunc(TEvWhiteboard::TEvBSGroupStateUpdate, Handle);
- HFunc(TEvWhiteboard::TEvBSGroupStateRequest, Handle);
- HFunc(TEvWhiteboard::TEvSystemStateUpdate, Handle);
- HFunc(TEvWhiteboard::TEvSystemStateAddEndpoint, Handle);
- HFunc(TEvWhiteboard::TEvSystemStateAddRole, Handle);
- HFunc(TEvWhiteboard::TEvSystemStateSetTenant, Handle);
- HFunc(TEvWhiteboard::TEvSystemStateRequest, Handle);
+ HFunc(TEvWhiteboard::TEvVDiskStateDelete, Handle);
+ HFunc(TEvWhiteboard::TEvVDiskStateRequest, Handle);
+ HFunc(TEvWhiteboard::TEvBSGroupStateUpdate, Handle);
+ HFunc(TEvWhiteboard::TEvBSGroupStateRequest, Handle);
+ HFunc(TEvWhiteboard::TEvSystemStateUpdate, Handle);
+ HFunc(TEvWhiteboard::TEvSystemStateAddEndpoint, Handle);
+ HFunc(TEvWhiteboard::TEvSystemStateAddRole, Handle);
+ HFunc(TEvWhiteboard::TEvSystemStateSetTenant, Handle);
+ HFunc(TEvWhiteboard::TEvSystemStateRequest, Handle);
hFunc(TEvWhiteboard::TEvIntrospectionData, Handle);
HFunc(TEvWhiteboard::TEvTabletLookupRequest, Handle);
HFunc(TEvWhiteboard::TEvTraceLookupRequest, Handle);
HFunc(TEvWhiteboard::TEvTraceRequest, Handle);
HFunc(TEvWhiteboard::TEvSignalBodyRequest, Handle);
- HFunc(TEvPrivate::TEvUpdateRuntimeStats, Handle);
- HFunc(TEvPrivate::TEvCleanupDeadTablets, Handle);
- }
- }
-
- void Handle(TEvWhiteboard::TEvTabletStateUpdate::TPtr &ev, const TActorContext &ctx) {
+ HFunc(TEvPrivate::TEvUpdateRuntimeStats, Handle);
+ HFunc(TEvPrivate::TEvCleanupDeadTablets, Handle);
+ }
+ }
+
+ void Handle(TEvWhiteboard::TEvTabletStateUpdate::TPtr &ev, const TActorContext &ctx) {
auto tabletId(std::make_pair(ev->Get()->Record.GetTabletId(), ev->Get()->Record.GetFollowerId()));
- auto& tabletStateInfo = TabletStateInfo[tabletId];
- if (ev->Get()->Record.HasGeneration() && tabletStateInfo.GetGeneration() > ev->Get()->Record.GetGeneration()) {
- return; // skip updates from previous generations
- }
- if (CheckedMerge(tabletStateInfo, ev->Get()->Record) >= 100) {
- tabletStateInfo.SetChangeTime(ctx.Now().MilliSeconds());
- }
- }
-
+ auto& tabletStateInfo = TabletStateInfo[tabletId];
+ if (ev->Get()->Record.HasGeneration() && tabletStateInfo.GetGeneration() > ev->Get()->Record.GetGeneration()) {
+ return; // skip updates from previous generations
+ }
+ if (CheckedMerge(tabletStateInfo, ev->Get()->Record) >= 100) {
+ tabletStateInfo.SetChangeTime(ctx.Now().MilliSeconds());
+ }
+ }
+
void Handle(TEvWhiteboard::TEvNodeStateUpdate::TPtr &ev, const TActorContext &ctx) {
- auto& nodeStateInfo = NodeStateInfo[ev->Get()->Record.GetPeerName()];
- if (CheckedMerge(nodeStateInfo, ev->Get()->Record) >= 100) {
- nodeStateInfo.SetChangeTime(ctx.Now().MilliSeconds());
- }
- }
-
+ auto& nodeStateInfo = NodeStateInfo[ev->Get()->Record.GetPeerName()];
+ if (CheckedMerge(nodeStateInfo, ev->Get()->Record) >= 100) {
+ nodeStateInfo.SetChangeTime(ctx.Now().MilliSeconds());
+ }
+ }
+
void Handle(TEvWhiteboard::TEvNodeStateDelete::TPtr &ev, const TActorContext &ctx) {
- auto& nodeStateInfo = NodeStateInfo[ev->Get()->Record.GetPeerName()];
- if (nodeStateInfo.HasConnected()) {
- nodeStateInfo.ClearConnected();
- nodeStateInfo.SetChangeTime(ctx.Now().MilliSeconds());
- }
- }
-
- void Handle(TEvWhiteboard::TEvPDiskStateUpdate::TPtr &ev, const TActorContext &ctx) {
- auto& pDiskStateInfo = PDiskStateInfo[ev->Get()->Record.GetPDiskId()];
- if (CheckedMerge(pDiskStateInfo, ev->Get()->Record) >= 100) {
- pDiskStateInfo.SetChangeTime(ctx.Now().MilliSeconds());
- UpdateSystemState(ctx);
- }
- }
-
- void Handle(TEvWhiteboard::TEvVDiskStateUpdate::TPtr &ev, const TActorContext &ctx) {
+ auto& nodeStateInfo = NodeStateInfo[ev->Get()->Record.GetPeerName()];
+ if (nodeStateInfo.HasConnected()) {
+ nodeStateInfo.ClearConnected();
+ nodeStateInfo.SetChangeTime(ctx.Now().MilliSeconds());
+ }
+ }
+
+ void Handle(TEvWhiteboard::TEvPDiskStateUpdate::TPtr &ev, const TActorContext &ctx) {
+ auto& pDiskStateInfo = PDiskStateInfo[ev->Get()->Record.GetPDiskId()];
+ if (CheckedMerge(pDiskStateInfo, ev->Get()->Record) >= 100) {
+ pDiskStateInfo.SetChangeTime(ctx.Now().MilliSeconds());
+ UpdateSystemState(ctx);
+ }
+ }
+
+ void Handle(TEvWhiteboard::TEvVDiskStateUpdate::TPtr &ev, const TActorContext &ctx) {
auto& record = ev->Get()->Record;
const auto& key = VDiskIDFromVDiskID(record.GetVDiskId());
if (ev->Get()->Initial) {
@@ -422,10 +422,10 @@ protected:
value.SetChangeTime(ctx.Now().MilliSeconds());
UpdateSystemState(ctx);
}
- }
- }
-
- void Handle(TEvWhiteboard::TEvVDiskStateDelete::TPtr &ev, const TActorContext &ctx) {
+ }
+ }
+
+ void Handle(TEvWhiteboard::TEvVDiskStateDelete::TPtr &ev, const TActorContext &ctx) {
if (VDiskStateInfo.erase(VDiskIDFromVDiskID(ev->Get()->Record.GetVDiskId()))) {
UpdateSystemState(ctx);
}
@@ -442,210 +442,210 @@ protected:
}
}
- void Handle(TEvWhiteboard::TEvBSGroupStateUpdate::TPtr &ev, const TActorContext &ctx) {
- auto& bSGroupStateInfo = BSGroupStateInfo[ev->Get()->Record.GetGroupID()];
- if (CheckedMerge(bSGroupStateInfo, ev->Get()->Record) >= 100) {
- bSGroupStateInfo.SetChangeTime(ctx.Now().MilliSeconds());
- }
- UpdateSystemState(ctx);
- }
-
- void Handle(TEvWhiteboard::TEvBSGroupStateDelete::TPtr &ev, const TActorContext &ctx) {
- ui32 groupId = ev->Get()->Record.GetGroupID();
- BSGroupStateInfo.erase(groupId);
- UpdateSystemState(ctx);
- }
-
- void Handle(TEvWhiteboard::TEvSystemStateUpdate::TPtr &ev, const TActorContext &ctx) {
- if (CheckedMerge(SystemStateInfo, ev->Get()->Record)) {
- SystemStateInfo.SetChangeTime(ctx.Now().MilliSeconds());
- UpdateSystemState(ctx);
- }
- }
-
- void Handle(TEvWhiteboard::TEvSystemStateAddEndpoint::TPtr &ev, const TActorContext &ctx) {
- auto& endpoint = *SystemStateInfo.AddEndpoints();
- endpoint.SetName(ev->Get()->Name);
- endpoint.SetAddress(ev->Get()->Address);
- SystemStateInfo.SetChangeTime(ctx.Now().MilliSeconds());
- UpdateSystemState(ctx);
- }
-
- void Handle(TEvWhiteboard::TEvSystemStateAddRole::TPtr &ev, const TActorContext &ctx) {
- const auto& roles = SystemStateInfo.GetRoles();
- if (Find(roles, ev->Get()->Role) == roles.end()) {
- SystemStateInfo.AddRoles(ev->Get()->Role);
- SystemStateInfo.SetChangeTime(ctx.Now().MilliSeconds());
- UpdateSystemState(ctx);
- }
- }
-
- void Handle(TEvWhiteboard::TEvSystemStateSetTenant::TPtr &ev, const TActorContext &ctx) {
- const auto& tenants = SystemStateInfo.GetTenants();
- if (Find(tenants, ev->Get()->Tenant) == tenants.end()) {
- SystemStateInfo.ClearTenants();
- SystemStateInfo.AddTenants(ev->Get()->Tenant);
- SystemStateInfo.SetChangeTime(ctx.Now().MilliSeconds());
- UpdateSystemState(ctx);
- }
- }
-
- void Handle(TEvWhiteboard::TEvSystemStateRemoveTenant::TPtr &ev, const TActorContext &ctx) {
- auto& tenants = *SystemStateInfo.MutableTenants();
- auto itTenant = Find(tenants, ev->Get()->Tenant);
- if (itTenant != tenants.end()) {
- tenants.erase(itTenant);
- SystemStateInfo.SetChangeTime(ctx.Now().MilliSeconds());
- UpdateSystemState(ctx);
- }
- }
-
- void UpdateSystemState(const TActorContext &ctx) {
- NKikimrWhiteboard::EFlag eFlag = NKikimrWhiteboard::EFlag::Green;
- NKikimrWhiteboard::EFlag pDiskFlag = NKikimrWhiteboard::EFlag::Green;
- ui32 yellowFlags = 0;
+ void Handle(TEvWhiteboard::TEvBSGroupStateUpdate::TPtr &ev, const TActorContext &ctx) {
+ auto& bSGroupStateInfo = BSGroupStateInfo[ev->Get()->Record.GetGroupID()];
+ if (CheckedMerge(bSGroupStateInfo, ev->Get()->Record) >= 100) {
+ bSGroupStateInfo.SetChangeTime(ctx.Now().MilliSeconds());
+ }
+ UpdateSystemState(ctx);
+ }
+
+ void Handle(TEvWhiteboard::TEvBSGroupStateDelete::TPtr &ev, const TActorContext &ctx) {
+ ui32 groupId = ev->Get()->Record.GetGroupID();
+ BSGroupStateInfo.erase(groupId);
+ UpdateSystemState(ctx);
+ }
+
+ void Handle(TEvWhiteboard::TEvSystemStateUpdate::TPtr &ev, const TActorContext &ctx) {
+ if (CheckedMerge(SystemStateInfo, ev->Get()->Record)) {
+ SystemStateInfo.SetChangeTime(ctx.Now().MilliSeconds());
+ UpdateSystemState(ctx);
+ }
+ }
+
+ void Handle(TEvWhiteboard::TEvSystemStateAddEndpoint::TPtr &ev, const TActorContext &ctx) {
+ auto& endpoint = *SystemStateInfo.AddEndpoints();
+ endpoint.SetName(ev->Get()->Name);
+ endpoint.SetAddress(ev->Get()->Address);
+ SystemStateInfo.SetChangeTime(ctx.Now().MilliSeconds());
+ UpdateSystemState(ctx);
+ }
+
+ void Handle(TEvWhiteboard::TEvSystemStateAddRole::TPtr &ev, const TActorContext &ctx) {
+ const auto& roles = SystemStateInfo.GetRoles();
+ if (Find(roles, ev->Get()->Role) == roles.end()) {
+ SystemStateInfo.AddRoles(ev->Get()->Role);
+ SystemStateInfo.SetChangeTime(ctx.Now().MilliSeconds());
+ UpdateSystemState(ctx);
+ }
+ }
+
+ void Handle(TEvWhiteboard::TEvSystemStateSetTenant::TPtr &ev, const TActorContext &ctx) {
+ const auto& tenants = SystemStateInfo.GetTenants();
+ if (Find(tenants, ev->Get()->Tenant) == tenants.end()) {
+ SystemStateInfo.ClearTenants();
+ SystemStateInfo.AddTenants(ev->Get()->Tenant);
+ SystemStateInfo.SetChangeTime(ctx.Now().MilliSeconds());
+ UpdateSystemState(ctx);
+ }
+ }
+
+ void Handle(TEvWhiteboard::TEvSystemStateRemoveTenant::TPtr &ev, const TActorContext &ctx) {
+ auto& tenants = *SystemStateInfo.MutableTenants();
+ auto itTenant = Find(tenants, ev->Get()->Tenant);
+ if (itTenant != tenants.end()) {
+ tenants.erase(itTenant);
+ SystemStateInfo.SetChangeTime(ctx.Now().MilliSeconds());
+ UpdateSystemState(ctx);
+ }
+ }
+
+ void UpdateSystemState(const TActorContext &ctx) {
+ NKikimrWhiteboard::EFlag eFlag = NKikimrWhiteboard::EFlag::Green;
+ NKikimrWhiteboard::EFlag pDiskFlag = NKikimrWhiteboard::EFlag::Green;
+ ui32 yellowFlags = 0;
double maxDiskUsage = 0;
- for (const auto& pr : PDiskStateInfo) {
- if (!pr.second.HasState()) {
- pDiskFlag = std::max(pDiskFlag, NKikimrWhiteboard::EFlag::Yellow);
- ++yellowFlags;
- } else {
- switch (pr.second.GetState()) {
+ for (const auto& pr : PDiskStateInfo) {
+ if (!pr.second.HasState()) {
+ pDiskFlag = std::max(pDiskFlag, NKikimrWhiteboard::EFlag::Yellow);
+ ++yellowFlags;
+ } else {
+ switch (pr.second.GetState()) {
case NKikimrBlobStorage::TPDiskState::InitialFormatReadError:
case NKikimrBlobStorage::TPDiskState::InitialSysLogReadError:
case NKikimrBlobStorage::TPDiskState::InitialSysLogParseError:
case NKikimrBlobStorage::TPDiskState::InitialCommonLogReadError:
case NKikimrBlobStorage::TPDiskState::InitialCommonLogParseError:
case NKikimrBlobStorage::TPDiskState::CommonLoggerInitError:
- pDiskFlag = std::max(pDiskFlag, NKikimrWhiteboard::EFlag::Red);
- break;
+ pDiskFlag = std::max(pDiskFlag, NKikimrWhiteboard::EFlag::Red);
+ break;
case NKikimrBlobStorage::TPDiskState::OpenFileError:
- pDiskFlag = std::max(pDiskFlag, NKikimrWhiteboard::EFlag::Yellow);
- ++yellowFlags;
- break;
- default:
- break;
- }
- }
- if (pr.second.HasAvailableSize() && pr.second.GetTotalSize() != 0) {
- double avail = (double)pr.second.GetAvailableSize() / pr.second.GetTotalSize();
- if (avail <= 0.06) {
- pDiskFlag = std::max(pDiskFlag, NKikimrWhiteboard::EFlag::Red);
- } else if (avail <= 0.08) {
- pDiskFlag = std::max(pDiskFlag, NKikimrWhiteboard::EFlag::Orange);
- } else if (avail <= 0.15) {
- pDiskFlag = std::max(pDiskFlag, NKikimrWhiteboard::EFlag::Yellow);
- ++yellowFlags;
- }
+ pDiskFlag = std::max(pDiskFlag, NKikimrWhiteboard::EFlag::Yellow);
+ ++yellowFlags;
+ break;
+ default:
+ break;
+ }
+ }
+ if (pr.second.HasAvailableSize() && pr.second.GetTotalSize() != 0) {
+ double avail = (double)pr.second.GetAvailableSize() / pr.second.GetTotalSize();
+ if (avail <= 0.06) {
+ pDiskFlag = std::max(pDiskFlag, NKikimrWhiteboard::EFlag::Red);
+ } else if (avail <= 0.08) {
+ pDiskFlag = std::max(pDiskFlag, NKikimrWhiteboard::EFlag::Orange);
+ } else if (avail <= 0.15) {
+ pDiskFlag = std::max(pDiskFlag, NKikimrWhiteboard::EFlag::Yellow);
+ ++yellowFlags;
+ }
maxDiskUsage = std::max(maxDiskUsage, 1.0 - avail);
- }
- }
+ }
+ }
SystemStateInfo.SetMaxDiskUsage(maxDiskUsage);
- if (pDiskFlag == NKikimrWhiteboard::EFlag::Yellow) {
- switch (yellowFlags) {
- case 1:
- break;
- case 2:
- pDiskFlag = NKikimrWhiteboard::EFlag::Orange;
- break;
- case 3:
- pDiskFlag = NKikimrWhiteboard::EFlag::Red;
- break;
- }
- }
- eFlag = std::max(eFlag, pDiskFlag);
- for (const auto& pr : VDiskStateInfo) {
- eFlag = std::max(eFlag, pr.second.GetDiskSpace());
- eFlag = std::max(eFlag, pr.second.GetSatisfactionRank().GetFreshRank().GetFlag());
- eFlag = std::max(eFlag, pr.second.GetSatisfactionRank().GetLevelRank().GetFlag());
- }
- if (SystemStateInfo.HasMessageBusState()) {
- eFlag = std::max(eFlag, SystemStateInfo.GetMessageBusState());
- }
- if (SystemStateInfo.HasGRpcState()) {
- eFlag = std::max(eFlag, SystemStateInfo.GetGRpcState());
- }
- for (const auto& stats : SystemStateInfo.GetPoolStats()) {
- double usage = stats.GetUsage();
- NKikimrWhiteboard::EFlag flag = NKikimrWhiteboard::EFlag::Grey;
- if (usage >= 0.99) {
- flag = NKikimrWhiteboard::EFlag::Red;
- } else if (usage >= 0.95) {
- flag = NKikimrWhiteboard::EFlag::Orange;
- } else if (usage >= 0.90) {
- flag = NKikimrWhiteboard::EFlag::Yellow;
- } else {
- flag = NKikimrWhiteboard::EFlag::Green;
- }
- eFlag = Max(eFlag, flag);
- }
- if (!SystemStateInfo.HasSystemState() || SystemStateInfo.GetSystemState() != eFlag) {
- SystemStateInfo.SetSystemState(eFlag);
- SystemStateInfo.SetChangeTime(ctx.Now().MilliSeconds());
- }
- }
-
- void Handle(TEvWhiteboard::TEvTabletStateRequest::TPtr &ev, const TActorContext &ctx) {
- const auto& request = ev->Get()->Record;
- ui64 changedSince = request.HasChangedSince() ? request.GetChangedSince() : 0;
- TAutoPtr<TEvWhiteboard::TEvTabletStateResponse> response = new TEvWhiteboard::TEvTabletStateResponse();
- auto& record = response->Record;
- for (const auto& pr : TabletStateInfo) {
- if (pr.second.GetChangeTime() >= changedSince) {
- NKikimrWhiteboard::TTabletStateInfo &tabletStateInfo = *record.AddTabletStateInfo();
- tabletStateInfo.CopyFrom(pr.second);
- }
- }
- response->Record.SetResponseTime(ctx.Now().MilliSeconds());
- ctx.Send(ev->Sender, response.Release(), 0, ev->Cookie);
- }
-
+ if (pDiskFlag == NKikimrWhiteboard::EFlag::Yellow) {
+ switch (yellowFlags) {
+ case 1:
+ break;
+ case 2:
+ pDiskFlag = NKikimrWhiteboard::EFlag::Orange;
+ break;
+ case 3:
+ pDiskFlag = NKikimrWhiteboard::EFlag::Red;
+ break;
+ }
+ }
+ eFlag = std::max(eFlag, pDiskFlag);
+ for (const auto& pr : VDiskStateInfo) {
+ eFlag = std::max(eFlag, pr.second.GetDiskSpace());
+ eFlag = std::max(eFlag, pr.second.GetSatisfactionRank().GetFreshRank().GetFlag());
+ eFlag = std::max(eFlag, pr.second.GetSatisfactionRank().GetLevelRank().GetFlag());
+ }
+ if (SystemStateInfo.HasMessageBusState()) {
+ eFlag = std::max(eFlag, SystemStateInfo.GetMessageBusState());
+ }
+ if (SystemStateInfo.HasGRpcState()) {
+ eFlag = std::max(eFlag, SystemStateInfo.GetGRpcState());
+ }
+ for (const auto& stats : SystemStateInfo.GetPoolStats()) {
+ double usage = stats.GetUsage();
+ NKikimrWhiteboard::EFlag flag = NKikimrWhiteboard::EFlag::Grey;
+ if (usage >= 0.99) {
+ flag = NKikimrWhiteboard::EFlag::Red;
+ } else if (usage >= 0.95) {
+ flag = NKikimrWhiteboard::EFlag::Orange;
+ } else if (usage >= 0.90) {
+ flag = NKikimrWhiteboard::EFlag::Yellow;
+ } else {
+ flag = NKikimrWhiteboard::EFlag::Green;
+ }
+ eFlag = Max(eFlag, flag);
+ }
+ if (!SystemStateInfo.HasSystemState() || SystemStateInfo.GetSystemState() != eFlag) {
+ SystemStateInfo.SetSystemState(eFlag);
+ SystemStateInfo.SetChangeTime(ctx.Now().MilliSeconds());
+ }
+ }
+
+ void Handle(TEvWhiteboard::TEvTabletStateRequest::TPtr &ev, const TActorContext &ctx) {
+ const auto& request = ev->Get()->Record;
+ ui64 changedSince = request.HasChangedSince() ? request.GetChangedSince() : 0;
+ TAutoPtr<TEvWhiteboard::TEvTabletStateResponse> response = new TEvWhiteboard::TEvTabletStateResponse();
+ auto& record = response->Record;
+ for (const auto& pr : TabletStateInfo) {
+ if (pr.second.GetChangeTime() >= changedSince) {
+ NKikimrWhiteboard::TTabletStateInfo &tabletStateInfo = *record.AddTabletStateInfo();
+ tabletStateInfo.CopyFrom(pr.second);
+ }
+ }
+ response->Record.SetResponseTime(ctx.Now().MilliSeconds());
+ ctx.Send(ev->Sender, response.Release(), 0, ev->Cookie);
+ }
+
void Handle(TEvWhiteboard::TEvNodeStateRequest::TPtr &ev, const TActorContext &ctx) {
- const auto& request = ev->Get()->Record;
- ui64 changedSince = request.HasChangedSince() ? request.GetChangedSince() : 0;
+ const auto& request = ev->Get()->Record;
+ ui64 changedSince = request.HasChangedSince() ? request.GetChangedSince() : 0;
TAutoPtr<TEvWhiteboard::TEvNodeStateResponse> response = new TEvWhiteboard::TEvNodeStateResponse();
- auto& record = response->Record;
- for (const auto& pr : NodeStateInfo) {
- if (pr.second.GetChangeTime() >= changedSince) {
- NKikimrWhiteboard::TNodeStateInfo &nodeStateInfo = *record.AddNodeStateInfo();
- nodeStateInfo.CopyFrom(pr.second);
- }
- }
- response->Record.SetResponseTime(ctx.Now().MilliSeconds());
- ctx.Send(ev->Sender, response.Release(), 0, ev->Cookie);
- }
-
+ auto& record = response->Record;
+ for (const auto& pr : NodeStateInfo) {
+ if (pr.second.GetChangeTime() >= changedSince) {
+ NKikimrWhiteboard::TNodeStateInfo &nodeStateInfo = *record.AddNodeStateInfo();
+ nodeStateInfo.CopyFrom(pr.second);
+ }
+ }
+ response->Record.SetResponseTime(ctx.Now().MilliSeconds());
+ ctx.Send(ev->Sender, response.Release(), 0, ev->Cookie);
+ }
+
// void Handle(TEvWhiteboard::TEvNodeStateRequest::TPtr &ev, const TActorContext &ctx) {
// TAutoPtr<TEvWhiteboard::TEvNodeStateResponse> response = new TEvWhiteboard::TEvNodeStateResponse();
-// auto& record = response->Record;
-// const TIntrusivePtr<NMonitoring::TDynamicCounters> &counters = AppData(ctx)->Counters;
+// auto& record = response->Record;
+// const TIntrusivePtr<NMonitoring::TDynamicCounters> &counters = AppData(ctx)->Counters;
// TIntrusivePtr<NMonitoring::TDynamicCounters> interconnectCounters = GetServiceCounters(counters, "interconnect");
// interconnectCounters->EnumerateSubgroups([&record, &interconnectCounters](const TString &name, const TString &value) -> void {
-// NKikimrWhiteboard::TNodeStateInfo &nodeStateInfo = *record.AddNodeStateInfo();
-// TIntrusivePtr<NMonitoring::TDynamicCounters> peerCounters = interconnectCounters->GetSubgroup(name, value);
-// NMonitoring::TDynamicCounters::TCounterPtr connectedCounter = peerCounters->GetCounter("Connected");
-// nodeStateInfo.SetPeerName(value);
-// nodeStateInfo.SetConnected(connectedCounter->Val());
-// });
-// response->Record.SetResponseTime(ctx.Now().MilliSeconds());
-// ctx.Send(ev->Sender, response.Release(), 0, ev->Cookie);
-// }
-
- void Handle(TEvWhiteboard::TEvPDiskStateRequest::TPtr &ev, const TActorContext &ctx) {
- const auto& request = ev->Get()->Record;
- ui64 changedSince = request.HasChangedSince() ? request.GetChangedSince() : 0;
- TAutoPtr<TEvWhiteboard::TEvPDiskStateResponse> response = new TEvWhiteboard::TEvPDiskStateResponse();
- auto& record = response->Record;
- for (const auto& pr : PDiskStateInfo) {
- if (pr.second.GetChangeTime() >= changedSince) {
- NKikimrWhiteboard::TPDiskStateInfo &pDiskStateInfo = *record.AddPDiskStateInfo();
- pDiskStateInfo.CopyFrom(pr.second);
- }
- }
- response->Record.SetResponseTime(ctx.Now().MilliSeconds());
- ctx.Send(ev->Sender, response.Release(), 0, ev->Cookie);
- }
-
+// NKikimrWhiteboard::TNodeStateInfo &nodeStateInfo = *record.AddNodeStateInfo();
+// TIntrusivePtr<NMonitoring::TDynamicCounters> peerCounters = interconnectCounters->GetSubgroup(name, value);
+// NMonitoring::TDynamicCounters::TCounterPtr connectedCounter = peerCounters->GetCounter("Connected");
+// nodeStateInfo.SetPeerName(value);
+// nodeStateInfo.SetConnected(connectedCounter->Val());
+// });
+// response->Record.SetResponseTime(ctx.Now().MilliSeconds());
+// ctx.Send(ev->Sender, response.Release(), 0, ev->Cookie);
+// }
+
+ void Handle(TEvWhiteboard::TEvPDiskStateRequest::TPtr &ev, const TActorContext &ctx) {
+ const auto& request = ev->Get()->Record;
+ ui64 changedSince = request.HasChangedSince() ? request.GetChangedSince() : 0;
+ TAutoPtr<TEvWhiteboard::TEvPDiskStateResponse> response = new TEvWhiteboard::TEvPDiskStateResponse();
+ auto& record = response->Record;
+ for (const auto& pr : PDiskStateInfo) {
+ if (pr.second.GetChangeTime() >= changedSince) {
+ NKikimrWhiteboard::TPDiskStateInfo &pDiskStateInfo = *record.AddPDiskStateInfo();
+ pDiskStateInfo.CopyFrom(pr.second);
+ }
+ }
+ response->Record.SetResponseTime(ctx.Now().MilliSeconds());
+ ctx.Send(ev->Sender, response.Release(), 0, ev->Cookie);
+ }
+
void Handle(TEvWhiteboard::TEvPDiskStateDelete::TPtr &ev, const TActorContext &ctx) {
auto pdiskId = ev->Get()->Record.GetPDiskId();
@@ -656,49 +656,49 @@ protected:
}
}
- void Handle(TEvWhiteboard::TEvVDiskStateRequest::TPtr &ev, const TActorContext &ctx) {
- const auto& request = ev->Get()->Record;
- ui64 changedSince = request.HasChangedSince() ? request.GetChangedSince() : 0;
- TAutoPtr<TEvWhiteboard::TEvVDiskStateResponse> response = new TEvWhiteboard::TEvVDiskStateResponse();
- auto& record = response->Record;
- for (const auto& pr : VDiskStateInfo) {
- if (pr.second.GetChangeTime() >= changedSince) {
- NKikimrWhiteboard::TVDiskStateInfo &vDiskStateInfo = *record.AddVDiskStateInfo();
- vDiskStateInfo.CopyFrom(pr.second);
- }
- }
- response->Record.SetResponseTime(ctx.Now().MilliSeconds());
- ctx.Send(ev->Sender, response.Release(), 0, ev->Cookie);
- }
-
- void Handle(TEvWhiteboard::TEvBSGroupStateRequest::TPtr &ev, const TActorContext &ctx) {
- const auto& request = ev->Get()->Record;
- ui64 changedSince = request.HasChangedSince() ? request.GetChangedSince() : 0;
- TAutoPtr<TEvWhiteboard::TEvBSGroupStateResponse> response = new TEvWhiteboard::TEvBSGroupStateResponse();
- auto& record = response->Record;
- for (const auto& pr : BSGroupStateInfo) {
- if (pr.second.GetChangeTime() >= changedSince) {
- NKikimrWhiteboard::TBSGroupStateInfo &bSGroupStateInfo = *record.AddBSGroupStateInfo();
- bSGroupStateInfo.CopyFrom(pr.second);
- }
- }
- response->Record.SetResponseTime(ctx.Now().MilliSeconds());
- ctx.Send(ev->Sender, response.Release(), 0, ev->Cookie);
- }
-
- void Handle(TEvWhiteboard::TEvSystemStateRequest::TPtr &ev, const TActorContext &ctx) {
- const auto& request = ev->Get()->Record;
- ui64 changedSince = request.HasChangedSince() ? request.GetChangedSince() : 0;
- TAutoPtr<TEvWhiteboard::TEvSystemStateResponse> response = new TEvWhiteboard::TEvSystemStateResponse();
- auto& record = response->Record;
- if (SystemStateInfo.GetChangeTime() >= changedSince) {
- NKikimrWhiteboard::TSystemStateInfo &systemStateInfo = *record.AddSystemStateInfo();
- systemStateInfo.CopyFrom(SystemStateInfo);
- }
- response->Record.SetResponseTime(ctx.Now().MilliSeconds());
- ctx.Send(ev->Sender, response.Release(), 0, ev->Cookie);
- }
-
+ void Handle(TEvWhiteboard::TEvVDiskStateRequest::TPtr &ev, const TActorContext &ctx) {
+ const auto& request = ev->Get()->Record;
+ ui64 changedSince = request.HasChangedSince() ? request.GetChangedSince() : 0;
+ TAutoPtr<TEvWhiteboard::TEvVDiskStateResponse> response = new TEvWhiteboard::TEvVDiskStateResponse();
+ auto& record = response->Record;
+ for (const auto& pr : VDiskStateInfo) {
+ if (pr.second.GetChangeTime() >= changedSince) {
+ NKikimrWhiteboard::TVDiskStateInfo &vDiskStateInfo = *record.AddVDiskStateInfo();
+ vDiskStateInfo.CopyFrom(pr.second);
+ }
+ }
+ response->Record.SetResponseTime(ctx.Now().MilliSeconds());
+ ctx.Send(ev->Sender, response.Release(), 0, ev->Cookie);
+ }
+
+ void Handle(TEvWhiteboard::TEvBSGroupStateRequest::TPtr &ev, const TActorContext &ctx) {
+ const auto& request = ev->Get()->Record;
+ ui64 changedSince = request.HasChangedSince() ? request.GetChangedSince() : 0;
+ TAutoPtr<TEvWhiteboard::TEvBSGroupStateResponse> response = new TEvWhiteboard::TEvBSGroupStateResponse();
+ auto& record = response->Record;
+ for (const auto& pr : BSGroupStateInfo) {
+ if (pr.second.GetChangeTime() >= changedSince) {
+ NKikimrWhiteboard::TBSGroupStateInfo &bSGroupStateInfo = *record.AddBSGroupStateInfo();
+ bSGroupStateInfo.CopyFrom(pr.second);
+ }
+ }
+ response->Record.SetResponseTime(ctx.Now().MilliSeconds());
+ ctx.Send(ev->Sender, response.Release(), 0, ev->Cookie);
+ }
+
+ void Handle(TEvWhiteboard::TEvSystemStateRequest::TPtr &ev, const TActorContext &ctx) {
+ const auto& request = ev->Get()->Record;
+ ui64 changedSince = request.HasChangedSince() ? request.GetChangedSince() : 0;
+ TAutoPtr<TEvWhiteboard::TEvSystemStateResponse> response = new TEvWhiteboard::TEvSystemStateResponse();
+ auto& record = response->Record;
+ if (SystemStateInfo.GetChangeTime() >= changedSince) {
+ NKikimrWhiteboard::TSystemStateInfo &systemStateInfo = *record.AddSystemStateInfo();
+ systemStateInfo.CopyFrom(SystemStateInfo);
+ }
+ response->Record.SetResponseTime(ctx.Now().MilliSeconds());
+ ctx.Send(ev->Sender, response.Release(), 0, ev->Cookie);
+ }
+
void Handle(TEvWhiteboard::TEvIntrospectionData::TPtr &ev) {
TEvWhiteboard::TEvIntrospectionData *msg = ev->Get();
TabletIntrospectionData->AddTrace(msg->TabletId, msg->Trace.Release());
@@ -781,62 +781,62 @@ protected:
static TVector<double> GetLoadAverage() {
TVector<double> loadAvg(3);
- loadAvg.resize(NSystemInfo::LoadAverage(loadAvg.data(), loadAvg.size()));
- return loadAvg;
- }
-
- void Handle(TEvPrivate::TEvUpdateRuntimeStats::TPtr &, const TActorContext &ctx) {
+ loadAvg.resize(NSystemInfo::LoadAverage(loadAvg.data(), loadAvg.size()));
+ return loadAvg;
+ }
+
+ void Handle(TEvPrivate::TEvUpdateRuntimeStats::TPtr &, const TActorContext &ctx) {
THolder<TEvWhiteboard::TEvSystemStateUpdate> systemStatsUpdate = MakeHolder<TEvWhiteboard::TEvSystemStateUpdate>();
- TVector<double> loadAverage = GetLoadAverage();
- for (double d : loadAverage) {
- systemStatsUpdate->Record.AddLoadAverage(d);
- }
- ProcessStats.Fill(getpid());
- if (ProcessStats.AnonRss != 0) {
- systemStatsUpdate->Record.SetMemoryUsed(ProcessStats.AnonRss);
- }
- if (ProcessStats.CGroupMemLim != 0) {
- systemStatsUpdate->Record.SetMemoryLimit(ProcessStats.CGroupMemLim);
- }
+ TVector<double> loadAverage = GetLoadAverage();
+ for (double d : loadAverage) {
+ systemStatsUpdate->Record.AddLoadAverage(d);
+ }
+ ProcessStats.Fill(getpid());
+ if (ProcessStats.AnonRss != 0) {
+ systemStatsUpdate->Record.SetMemoryUsed(ProcessStats.AnonRss);
+ }
+ if (ProcessStats.CGroupMemLim != 0) {
+ systemStatsUpdate->Record.SetMemoryLimit(ProcessStats.CGroupMemLim);
+ }
systemStatsUpdate->Record.SetMemoryUsedInAlloc(TAllocState::GetAllocatedMemoryEstimate());
- ctx.Send(ctx.SelfID, systemStatsUpdate.Release());
- ctx.Schedule(TDuration::Seconds(30), new TEvPrivate::TEvUpdateRuntimeStats());
- }
-
- void Handle(TEvPrivate::TEvCleanupDeadTablets::TPtr &, const TActorContext &ctx) {
- auto it = TabletStateInfo.begin();
- ui64 deadDeadline = (ctx.Now() - TDuration::Minutes(10)).MilliSeconds();
- ui64 deletedDeadline = (ctx.Now() - TDuration::Hours(1)).MilliSeconds();
- while (it != TabletStateInfo.end()) {
- const auto& tabletInfo = it->second;
- NKikimrWhiteboard::TTabletStateInfo::ETabletState state = tabletInfo.GetState();
- switch (state) {
- case NKikimrWhiteboard::TTabletStateInfo::Dead:
- if (tabletInfo.GetChangeTime() < deadDeadline) {
- it = TabletStateInfo.erase(it);
- } else {
- ++it;
- }
- break;
- case NKikimrWhiteboard::TTabletStateInfo::Deleted:
- if (tabletInfo.GetChangeTime() < deletedDeadline) {
- it = TabletStateInfo.erase(it);
- } else {
- ++it;
- }
- break;
- default:
- ++it;
- break;
- }
- }
- ctx.Schedule(TDuration::Seconds(60), new TEvPrivate::TEvCleanupDeadTablets());
- }
-};
-
-IActor* CreateNodeWhiteboardService() {
- return new TNodeWhiteboardService();
-}
-
-} // NNodeWhiteboard
-} // NKikimr
+ ctx.Send(ctx.SelfID, systemStatsUpdate.Release());
+ ctx.Schedule(TDuration::Seconds(30), new TEvPrivate::TEvUpdateRuntimeStats());
+ }
+
+ void Handle(TEvPrivate::TEvCleanupDeadTablets::TPtr &, const TActorContext &ctx) {
+ auto it = TabletStateInfo.begin();
+ ui64 deadDeadline = (ctx.Now() - TDuration::Minutes(10)).MilliSeconds();
+ ui64 deletedDeadline = (ctx.Now() - TDuration::Hours(1)).MilliSeconds();
+ while (it != TabletStateInfo.end()) {
+ const auto& tabletInfo = it->second;
+ NKikimrWhiteboard::TTabletStateInfo::ETabletState state = tabletInfo.GetState();
+ switch (state) {
+ case NKikimrWhiteboard::TTabletStateInfo::Dead:
+ if (tabletInfo.GetChangeTime() < deadDeadline) {
+ it = TabletStateInfo.erase(it);
+ } else {
+ ++it;
+ }
+ break;
+ case NKikimrWhiteboard::TTabletStateInfo::Deleted:
+ if (tabletInfo.GetChangeTime() < deletedDeadline) {
+ it = TabletStateInfo.erase(it);
+ } else {
+ ++it;
+ }
+ break;
+ default:
+ ++it;
+ break;
+ }
+ }
+ ctx.Schedule(TDuration::Seconds(60), new TEvPrivate::TEvCleanupDeadTablets());
+ }
+};
+
+IActor* CreateNodeWhiteboardService() {
+ return new TNodeWhiteboardService();
+}
+
+} // NNodeWhiteboard
+} // NKikimr
diff --git a/ydb/core/tablet/pipe_tracker.cpp b/ydb/core/tablet/pipe_tracker.cpp
index d4b64ba4177..cf6e41a97f9 100644
--- a/ydb/core/tablet/pipe_tracker.cpp
+++ b/ydb/core/tablet/pipe_tracker.cpp
@@ -1,14 +1,14 @@
-#include "pipe_tracker.h"
+#include "pipe_tracker.h"
namespace NKikimr {
-std::unordered_set<ui64> TPipeTrackerBase::EmptySet;
-std::unordered_set<std::pair<ui64, ui64>> TPipeTrackerBase::EmptyPairSet;
+std::unordered_set<ui64> TPipeTrackerBase::EmptySet;
+std::unordered_set<std::pair<ui64, ui64>> TPipeTrackerBase::EmptyPairSet;
void TPipeTrackerBase::AttachTablet(ui64 txid, ui64 tabletid, ui64 cookie) {
auto txIt = TxToTablet.find(txid);
if (txIt == TxToTablet.end()) {
- txIt = TxToTablet.emplace(txid, std::unordered_set<std::pair<ui64, ui64>>()).first;
+ txIt = TxToTablet.emplace(txid, std::unordered_set<std::pair<ui64, ui64>>()).first;
}
auto& tabletSet = txIt->second;
@@ -64,7 +64,7 @@ bool TPipeTrackerBase::IsTxAlive(ui64 txid) const {
return (txIt != TxToTablet.end());
}
-const std::unordered_set<ui64> &TPipeTrackerBase::FindTx(ui64 tabletid) const {
+const std::unordered_set<ui64> &TPipeTrackerBase::FindTx(ui64 tabletid) const {
auto it = TabletToTx.find(tabletid);
if (it == TabletToTx.end())
return EmptySet;
@@ -72,7 +72,7 @@ const std::unordered_set<ui64> &TPipeTrackerBase::FindTx(ui64 tabletid) const {
return it->second;
}
-const std::unordered_set<std::pair<ui64, ui64> > &TPipeTrackerBase::FindTablets(ui64 txid) const {
+const std::unordered_set<std::pair<ui64, ui64> > &TPipeTrackerBase::FindTablets(ui64 txid) const {
auto it = TxToTablet.find(txid);
if (it == TxToTablet.end())
return EmptyPairSet;
diff --git a/ydb/core/tablet/pipe_tracker.h b/ydb/core/tablet/pipe_tracker.h
index 12cacaff1bc..33b90ba82bb 100644
--- a/ydb/core/tablet/pipe_tracker.h
+++ b/ydb/core/tablet/pipe_tracker.h
@@ -3,8 +3,8 @@
#include <ydb/core/tablet/tablet_pipe_client_cache.h>
#include <ydb/core/util/tuples.h>
#include <functional>
-#include <unordered_map>
-#include <unordered_set>
+#include <unordered_map>
+#include <unordered_set>
namespace NKikimr {
@@ -15,15 +15,15 @@ public:
// returns false if tabletid is not used anymore
bool DetachTablet(ui64 txid, ui64 tabletid, ui64 cookie = 0);
bool IsTxAlive(ui64 txid) const;
- const std::unordered_set<ui64>& FindTx(ui64 tabletid) const;
- const std::unordered_set<std::pair<ui64, ui64>>& FindTablets(ui64 txid) const;
+ const std::unordered_set<ui64>& FindTx(ui64 tabletid) const;
+ const std::unordered_set<std::pair<ui64, ui64>>& FindTablets(ui64 txid) const;
private:
- std::unordered_map<ui64, std::unordered_set<ui64>> TabletToTx; // tabletid -> txid
- std::unordered_map<ui64, std::unordered_set<std::pair<ui64, ui64>>> TxToTablet; // txid -> cookie:tabletid
- std::unordered_map<ui64, std::unordered_multiset<ui64>> TxTablets; // txid -> tabletids
- static std::unordered_set<ui64> EmptySet;
- static std::unordered_set<std::pair<ui64, ui64>> EmptyPairSet;
+ std::unordered_map<ui64, std::unordered_set<ui64>> TabletToTx; // tabletid -> txid
+ std::unordered_map<ui64, std::unordered_set<std::pair<ui64, ui64>>> TxToTablet; // txid -> cookie:tabletid
+ std::unordered_map<ui64, std::unordered_multiset<ui64>> TxTablets; // txid -> tabletids
+ static std::unordered_set<ui64> EmptySet;
+ static std::unordered_set<std::pair<ui64, ui64>> EmptyPairSet;
};
class TPipeTracker : public TPipeTrackerBase {
diff --git a/ydb/core/tablet/pipe_tracker_ut.cpp b/ydb/core/tablet/pipe_tracker_ut.cpp
index 05f632e88c1..2a67c756d5b 100644
--- a/ydb/core/tablet/pipe_tracker_ut.cpp
+++ b/ydb/core/tablet/pipe_tracker_ut.cpp
@@ -1,4 +1,4 @@
-#include "pipe_tracker.h"
+#include "pipe_tracker.h"
#include <library/cpp/testing/unittest/registar.h>
namespace NKikimr {
@@ -78,26 +78,26 @@ Y_UNIT_TEST_SUITE(TPipeTrackerTest) {
UNIT_ASSERT(tracker.IsTxAlive(txid1));
UNIT_ASSERT(tracker.IsTxAlive(txid2));
UNIT_ASSERT(tracker.FindTx(tablet1).size() == 2);
- UNIT_ASSERT(tracker.FindTx(tablet1).count(txid1) == 1);
- UNIT_ASSERT(tracker.FindTx(tablet1).count(txid2) == 1);
+ UNIT_ASSERT(tracker.FindTx(tablet1).count(txid1) == 1);
+ UNIT_ASSERT(tracker.FindTx(tablet1).count(txid2) == 1);
UNIT_ASSERT(!tracker.DetachTablet(txid1, tablet1));
UNIT_ASSERT(!tracker.IsTxAlive(txid1));
UNIT_ASSERT(tracker.IsTxAlive(txid2));
UNIT_ASSERT(tracker.FindTx(tablet1).size() == 1);
- UNIT_ASSERT(tracker.FindTx(tablet1).count(txid2) == 1);
+ UNIT_ASSERT(tracker.FindTx(tablet1).count(txid2) == 1);
tracker.AttachTablet(txid3, tablet1);
UNIT_ASSERT(!tracker.IsTxAlive(txid1));
UNIT_ASSERT(tracker.IsTxAlive(txid2));
UNIT_ASSERT(tracker.IsTxAlive(txid3));
UNIT_ASSERT(tracker.FindTx(tablet1).size() == 2);
- UNIT_ASSERT(tracker.FindTx(tablet1).count(txid2) == 1);
- UNIT_ASSERT(tracker.FindTx(tablet1).count(txid3) == 1);
+ UNIT_ASSERT(tracker.FindTx(tablet1).count(txid2) == 1);
+ UNIT_ASSERT(tracker.FindTx(tablet1).count(txid3) == 1);
UNIT_ASSERT(!tracker.DetachTablet(txid3, tablet1));
UNIT_ASSERT(!tracker.IsTxAlive(txid1));
UNIT_ASSERT(tracker.IsTxAlive(txid2));
UNIT_ASSERT(!tracker.IsTxAlive(txid3));
UNIT_ASSERT(tracker.FindTx(tablet1).size() == 1);
- UNIT_ASSERT(tracker.FindTx(tablet1).count(txid2) == 1);
+ UNIT_ASSERT(tracker.FindTx(tablet1).count(txid2) == 1);
UNIT_ASSERT(tracker.DetachTablet(txid2, tablet1));
UNIT_ASSERT(!tracker.IsTxAlive(txid1));
UNIT_ASSERT(!tracker.IsTxAlive(txid2));
diff --git a/ydb/core/tablet/tablet_counters.cpp b/ydb/core/tablet/tablet_counters.cpp
index 680ef99712a..b2ef0d4ad7e 100644
--- a/ydb/core/tablet/tablet_counters.cpp
+++ b/ydb/core/tablet/tablet_counters.cpp
@@ -113,23 +113,23 @@ void TTabletCountersBase::OutputHtml(IOutputStream &os, const char* sectionName,
}
}
-void TTabletCountersBase::OutputProto(NKikimrTabletBase::TTabletCountersBase& op) const {
- if (HasCounters()) {
- for (ui32 idx = 0; idx < SimpleCounters.Size(); ++idx) {
+void TTabletCountersBase::OutputProto(NKikimrTabletBase::TTabletCountersBase& op) const {
+ if (HasCounters()) {
+ for (ui32 idx = 0; idx < SimpleCounters.Size(); ++idx) {
if (SimpleCounterName(idx)) {
auto& counter = *op.AddSimpleCounters();
counter.SetName(SimpleCounterName(idx));
counter.SetValue(SimpleCounters[idx].Get());
}
- }
- for (ui32 idx = 0; idx < CumulativeCounters.Size(); ++idx) {
+ }
+ for (ui32 idx = 0; idx < CumulativeCounters.Size(); ++idx) {
if (CumulativeCounterName(idx)) {
auto& counter = *op.AddCumulativeCounters();
counter.SetName(CumulativeCounterName(idx));
counter.SetValue(CumulativeCounters[idx].Get());
}
- }
- for (ui32 idx = 0; idx < PercentileCounters.Size(); ++idx) {
+ }
+ for (ui32 idx = 0; idx < PercentileCounters.Size(); ++idx) {
if (PercentileCounterName(idx)) {
auto& counter = *op.AddPercentileCounters();
counter.SetName(PercentileCounterName(idx));
@@ -138,11 +138,11 @@ void TTabletCountersBase::OutputProto(NKikimrTabletBase::TTabletCountersBase& op
counter.AddRanges(percentileCounter.GetRangeName(idxRange));
counter.AddValues(percentileCounter.GetRangeValue(idxRange));
}
- }
- }
- }
-}
-
+ }
+ }
+ }
+}
+
////////////////////////////////////////////
/// The TTabletLabeledCountersBase class
////////////////////////////////////////////
diff --git a/ydb/core/tablet/tablet_counters.h b/ydb/core/tablet/tablet_counters.h
index 4029a0bbe4e..a8cc27e9eda 100644
--- a/ydb/core/tablet/tablet_counters.h
+++ b/ydb/core/tablet/tablet_counters.h
@@ -90,10 +90,10 @@ private:
void SetTo(const TTabletSimpleCounter& rp) {
Value = rp.Value;
}
-
- void Populate(const TTabletSimpleCounter& rp) {
- SetTo(rp);
- }
+
+ void Populate(const TTabletSimpleCounter& rp) {
+ SetTo(rp);
+ }
};
////////////////////////////////////////////
@@ -129,10 +129,10 @@ private:
void SetTo(const TTabletCumulativeCounter& rp) {
Value = rp.Value;
}
-
- void Populate(const TTabletCumulativeCounter& rp) {
- Value += rp.Value;
- }
+
+ void Populate(const TTabletCumulativeCounter& rp) {
+ Value += rp.Value;
+ }
};
////////////////////////////////////////////
@@ -190,10 +190,10 @@ public:
return Ranges[index].RangeVal;
}
- TVector<TRangeDef> GetRanges() const {
- return TVector<TRangeDef>(Ranges, Ranges + RangeCount);
- }
-
+ TVector<TRangeDef> GetRanges() const {
+ return TVector<TRangeDef>(Ranges, Ranges + RangeCount);
+ }
+
bool GetIntegral() const {
return Integral;
}
@@ -251,13 +251,13 @@ public:
Values = TArrayHolder<ui64>(new ui64[RangeCount]());
}
-
- void Clear() {
- if (IsInitialized()) {
+
+ void Clear() {
+ if (IsInitialized()) {
std::fill(&Values[0], &Values[RangeCount], 0);
- }
- }
-
+ }
+ }
+
private:
//
ui32 FindSlot(ui64 what) const {
@@ -268,21 +268,21 @@ private:
return std::is_sorted(Ranges, Ranges + RangeCount);
}
- bool IsInitialized() const {
- return RangeCount != 0;
- }
-
- void Populate(const TTabletPercentileCounter& rp) {
- if (IsInitialized()) {
+ bool IsInitialized() const {
+ return RangeCount != 0;
+ }
+
+ void Populate(const TTabletPercentileCounter& rp) {
+ if (IsInitialized()) {
Y_VERIFY_DEBUG(RangeCount == rp.RangeCount);
- for (ui32 i = 0; i < RangeCount; ++i) {
- Values[i] += rp.Values[i];
- }
- } else {
- Initialize(rp);
- }
- }
-
+ for (ui32 i = 0; i < RangeCount; ++i) {
+ Values[i] += rp.Values[i];
+ }
+ } else {
+ Initialize(rp);
+ }
+ }
+
//
ui32 RangeCount = 0;
const TRangeDef* Ranges = nullptr;
@@ -377,16 +377,16 @@ private:
}
}
- void Populate(const TCountersArray<T>& rp) {
- if (CountersQnt != rp.CountersQnt) {
- Reset(rp);
- } else {
- for (ui32 i = 0, e = CountersQnt; i < e; ++i) {
- Counters[i].Populate(rp.Counters[i]);
- }
- }
- }
-
+ void Populate(const TCountersArray<T>& rp) {
+ if (CountersQnt != rp.CountersQnt) {
+ Reset(rp);
+ } else {
+ for (ui32 i = 0, e = CountersQnt; i < e; ++i) {
+ Counters[i].Populate(rp.Counters[i]);
+ }
+ }
+ }
+
//
ui32 CountersQnt;
TCountersHolder CountersHolder;
@@ -475,7 +475,7 @@ public:
//
void OutputHtml(IOutputStream &os) const;
- void OutputProto(NKikimrTabletBase::TTabletCountersBase& op) const;
+ void OutputProto(NKikimrTabletBase::TTabletCountersBase& op) const;
//
const char* SimpleCounterName(ui32 index) const {
@@ -490,23 +490,23 @@ public:
return PercentileCountersMetaInfo[index];
}
- void Populate(const TTabletCountersBase& rp) {
- if (!HasCounters()) {
- SimpleCounters.Reset(rp.SimpleCounters);
- SimpleCountersMetaInfo = rp.SimpleCountersMetaInfo;
-
- CumulativeCounters.Reset(rp.CumulativeCounters);
- CumulativeCountersMetaInfo = rp.CumulativeCountersMetaInfo;
-
- PercentileCounters.Reset(rp.PercentileCounters);
- PercentileCountersMetaInfo = rp.PercentileCountersMetaInfo;
- } else {
- SimpleCounters.Populate(rp.SimpleCounters);
- CumulativeCounters.Populate(rp.CumulativeCounters);
- PercentileCounters.Populate(rp.PercentileCounters);
- }
- }
-
+ void Populate(const TTabletCountersBase& rp) {
+ if (!HasCounters()) {
+ SimpleCounters.Reset(rp.SimpleCounters);
+ SimpleCountersMetaInfo = rp.SimpleCountersMetaInfo;
+
+ CumulativeCounters.Reset(rp.CumulativeCounters);
+ CumulativeCountersMetaInfo = rp.CumulativeCountersMetaInfo;
+
+ PercentileCounters.Reset(rp.PercentileCounters);
+ PercentileCountersMetaInfo = rp.PercentileCountersMetaInfo;
+ } else {
+ SimpleCounters.Populate(rp.SimpleCounters);
+ CumulativeCounters.Populate(rp.CumulativeCounters);
+ PercentileCounters.Populate(rp.PercentileCounters);
+ }
+ }
+
private:
//
TTabletCountersBase(const TTabletCountersBase&);
diff --git a/ydb/core/tablet/tablet_counters_aggregator.cpp b/ydb/core/tablet/tablet_counters_aggregator.cpp
index 4bcdb166220..1885b26e09c 100644
--- a/ydb/core/tablet/tablet_counters_aggregator.cpp
+++ b/ydb/core/tablet/tablet_counters_aggregator.cpp
@@ -38,20 +38,20 @@ TActorId MakeTabletCountersAggregatorID(ui32 node, bool follower) {
char x[12] ={'s','l','a','v','c','o','u','n','t','a','g','g'};
return TActorId(node, TStringBuf(x, 12));
}
-}
-
-TStringBuf GetHistogramAggregateSimpleName(TStringBuf name) {
- TStringBuf buffer(name);
- if (buffer.SkipPrefix("HIST(")) {
- return buffer.Before(')');
- }
- return TStringBuf();
-}
-
-bool IsHistogramAggregateSimpleName(TStringBuf name) {
- return !GetHistogramAggregateSimpleName(name).empty();
-}
-
+}
+
+TStringBuf GetHistogramAggregateSimpleName(TStringBuf name) {
+ TStringBuf buffer(name);
+ if (buffer.SkipPrefix("HIST(")) {
+ return buffer.Before(')');
+ }
+ return TStringBuf();
+}
+
+bool IsHistogramAggregateSimpleName(TStringBuf name) {
+ return !GetHistogramAggregateSimpleName(name).empty();
+}
+
////////////////////////////////////////////
namespace {
@@ -61,62 +61,62 @@ const ui32 WAKEUP_TIMEOUT_SECONDS = 4;
////////////////////////////////////////////
using TCountersVector = TVector<NMonitoring::TDynamicCounters::TCounterPtr>;
-struct THistogramCounter {
- TVector<TTabletPercentileCounter::TRangeDef> Ranges;
- TVector<NMonitoring::TDynamicCounters::TCounterPtr> Values;
+struct THistogramCounter {
+ TVector<TTabletPercentileCounter::TRangeDef> Ranges;
+ TVector<NMonitoring::TDynamicCounters::TCounterPtr> Values;
NMonitoring::THistogramPtr Histogram;
-
+
THistogramCounter(
const TVector<TTabletPercentileCounter::TRangeDef>& ranges,
TVector<NMonitoring::TDynamicCounters::TCounterPtr>&& values,
NMonitoring::THistogramPtr histogram)
- : Ranges(ranges)
- , Values(values)
+ : Ranges(ranges)
+ , Values(values)
, Histogram(histogram)
- {
- Y_VERIFY(!Ranges.empty() && Ranges.size() == Values.size());
- }
-
- void Clear() {
- for (const NMonitoring::TDynamicCounters::TCounterPtr& cnt : Values) {
- *cnt = 0;
- }
+ {
+ Y_VERIFY(!Ranges.empty() && Ranges.size() == Values.size());
+ }
+
+ void Clear() {
+ for (const NMonitoring::TDynamicCounters::TCounterPtr& cnt : Values) {
+ *cnt = 0;
+ }
Histogram->Reset();
- }
-
- void IncrementFor(ui64 value) {
+ }
+
+ void IncrementFor(ui64 value) {
const size_t i = Max<ssize_t>(0, std::upper_bound(Ranges.begin(), Ranges.end(), value) - Ranges.begin() - 1);
Values[i]->Inc();
Histogram->Collect(value);
- }
-};
-
-using THistogramVector = TVector<THolder<THistogramCounter>>;
-
-class TAggregatedSimpleCounters {
+ }
+};
+
+using THistogramVector = TVector<THolder<THistogramCounter>>;
+
+class TAggregatedSimpleCounters {
public:
//
TAggregatedSimpleCounters(NMonitoring::TDynamicCounterPtr counterGroup)
: CounterGroup(counterGroup)
{}
- void AddSimpleCounter(const char* name, THolder<THistogramCounter> percentileAggregate = THolder<THistogramCounter>()) {
+ void AddSimpleCounter(const char* name, THolder<THistogramCounter> percentileAggregate = THolder<THistogramCounter>()) {
auto fnAddCounter = [this](const char* name, TVector<NMonitoring::TDynamicCounters::TCounterPtr>& container) {
auto counter = CounterGroup->GetCounter(name, false);
container.push_back(counter);
};
CountersByTabletID.push_back(TCountersByTabletIDMap());
- ChangedCounters.push_back(true);
+ ChangedCounters.push_back(true);
TString maxName = Sprintf("MAX(%s)", name);
TString sumName = Sprintf("SUM(%s)", name);
fnAddCounter(maxName.data(), MaxSimpleCounters);
fnAddCounter(sumName.data(), SumSimpleCounters);
-
- HistSimpleCounters.emplace_back(std::move(percentileAggregate));
+
+ HistSimpleCounters.emplace_back(std::move(percentileAggregate));
}
ui64 GetSum(ui32 counterIndex) const {
@@ -180,7 +180,7 @@ private:
TCountersVector MaxSimpleCounters;
TCountersVector SumSimpleCounters;
- THistogramVector HistSimpleCounters;
+ THistogramVector HistSimpleCounters;
using TCountersByTabletIDMap = THashMap<ui64, ui64>;
TVector<TCountersByTabletIDMap> CountersByTabletID;
@@ -189,22 +189,22 @@ private:
private:
void Recalc(ui32 idx) {
auto &counters = CountersByTabletID[idx];
- THistogramCounter* histCounter = HistSimpleCounters[idx].Get();
+ THistogramCounter* histCounter = HistSimpleCounters[idx].Get();
ui64 maxVal = 0;
ui64 sumVal = 0;
- if (histCounter) {
- histCounter->Clear();
- }
-
+ if (histCounter) {
+ histCounter->Clear();
+ }
+
for (auto&& t : counters) {
- ui64 tValue = t.second;
+ ui64 tValue = t.second;
maxVal = Max(tValue, maxVal);
sumVal += tValue;
- if (histCounter) {
- histCounter->IncrementFor(tValue);
- }
+ if (histCounter) {
+ histCounter->IncrementFor(tValue);
+ }
}
*MaxSimpleCounters[idx].Get() = maxVal;
@@ -212,28 +212,28 @@ private:
}
};
-class TAggregatedCumulativeCounters {
-public:
- //
- TAggregatedCumulativeCounters(NMonitoring::TDynamicCounterPtr counterGroup)
- : CounterGroup(counterGroup)
- {}
-
- void AddCumulativeCounter(const char* name, THolder<THistogramCounter> percentileAggregate = THolder<THistogramCounter>()) {
- auto fnAddCounter = [this](const char* name, TVector<NMonitoring::TDynamicCounters::TCounterPtr>& container) {
- auto counter = CounterGroup->GetCounter(name, false);
- container.push_back(counter);
- };
-
- CountersByTabletID.push_back(TCountersByTabletIDMap());
- ChangedCounters.push_back(true);
- TString maxName = Sprintf("MAX(%s)", name);
-
- fnAddCounter(maxName.data(), MaxCumulativeCounters);
-
- HistCumulativeCounters.emplace_back(std::move(percentileAggregate));
- }
-
+class TAggregatedCumulativeCounters {
+public:
+ //
+ TAggregatedCumulativeCounters(NMonitoring::TDynamicCounterPtr counterGroup)
+ : CounterGroup(counterGroup)
+ {}
+
+ void AddCumulativeCounter(const char* name, THolder<THistogramCounter> percentileAggregate = THolder<THistogramCounter>()) {
+ auto fnAddCounter = [this](const char* name, TVector<NMonitoring::TDynamicCounters::TCounterPtr>& container) {
+ auto counter = CounterGroup->GetCounter(name, false);
+ container.push_back(counter);
+ };
+
+ CountersByTabletID.push_back(TCountersByTabletIDMap());
+ ChangedCounters.push_back(true);
+ TString maxName = Sprintf("MAX(%s)", name);
+
+ fnAddCounter(maxName.data(), MaxCumulativeCounters);
+
+ HistCumulativeCounters.emplace_back(std::move(percentileAggregate));
+ }
+
ui64 GetMax(ui32 counterIndex) const {
Y_VERIFY(counterIndex < MaxCumulativeCounters.size(),
"inconsistent max cumulative counters, %u >= %lu", counterIndex, MaxCumulativeCounters.size());
@@ -246,90 +246,90 @@ public:
*MaxCumulativeCounters[counterIndex] = value;
}
- void SetValue(ui64 tabletID, ui32 counterIndex, ui64 value, TTabletTypes::EType tabletType) {
- Y_VERIFY(counterIndex < CountersByTabletID.size(), "inconsistent counters for tablet type %s", TTabletTypes::TypeToStr(tabletType));
- auto it = CountersByTabletID[counterIndex].find(tabletID);
- if (it != CountersByTabletID[counterIndex].end()) {
- if (it->second != value) {
- ChangedCounters[counterIndex] = true;
- it->second = value;
- }
- } else {
- CountersByTabletID[counterIndex].insert(std::make_pair(tabletID, value));
- ChangedCounters[counterIndex] = true;
- }
- }
-
- void ForgetTablet(ui64 tabletId) {
- for (ui32 idx : xrange(CountersByTabletID.size())) {
- auto &counters = CountersByTabletID[idx];
- counters.erase(tabletId);
- ChangedCounters[idx] = true;
- }
- }
-
- void RecalcAll() {
- for (ui32 idx : xrange(CountersByTabletID.size())) {
- if (ChangedCounters[idx])
- Recalc(idx);
- ChangedCounters[idx] = false;
- }
- }
-
-private:
- //
- NMonitoring::TDynamicCounterPtr CounterGroup;
-
- TCountersVector MaxCumulativeCounters;
- THistogramVector HistCumulativeCounters;
- using TCountersByTabletIDMap = THashMap<ui64, ui64>;
-
- TVector<TCountersByTabletIDMap> CountersByTabletID;
- TVector<bool> ChangedCounters;
-
-private:
- void Recalc(ui32 idx) {
- auto &counters = CountersByTabletID[idx];
- THistogramCounter* histCounter = HistCumulativeCounters[idx].Get();
-
- ui64 maxVal = 0;
-
- if (histCounter) {
- histCounter->Clear();
- }
-
- for (auto&& t : counters) {
- ui64 tValue = t.second;
- maxVal = Max(tValue, maxVal);
- if (histCounter) {
- histCounter->IncrementFor(tValue);
- }
- }
-
- *MaxCumulativeCounters[idx].Get() = maxVal;
- }
-};
-
-struct TTabletLabeledCountersResponseContext {
- NKikimrTabletCountersAggregator::TEvTabletLabeledCountersResponse& Response;
- THashMap<TStringBuf, ui32> NamesToId;
-
- TTabletLabeledCountersResponseContext(NKikimrTabletCountersAggregator::TEvTabletLabeledCountersResponse& response)
- : Response(response)
- {}
-
- ui32 GetNameId(TStringBuf name) {
- auto it = NamesToId.find(name);
- if (it != NamesToId.end()) {
- return it->second;
- }
- Response.AddCounterNames(TString(name));
- ui32 id = Response.CounterNamesSize() - 1;
- NamesToId[name] = id;
- return id;
- }
-};
-
+ void SetValue(ui64 tabletID, ui32 counterIndex, ui64 value, TTabletTypes::EType tabletType) {
+ Y_VERIFY(counterIndex < CountersByTabletID.size(), "inconsistent counters for tablet type %s", TTabletTypes::TypeToStr(tabletType));
+ auto it = CountersByTabletID[counterIndex].find(tabletID);
+ if (it != CountersByTabletID[counterIndex].end()) {
+ if (it->second != value) {
+ ChangedCounters[counterIndex] = true;
+ it->second = value;
+ }
+ } else {
+ CountersByTabletID[counterIndex].insert(std::make_pair(tabletID, value));
+ ChangedCounters[counterIndex] = true;
+ }
+ }
+
+ void ForgetTablet(ui64 tabletId) {
+ for (ui32 idx : xrange(CountersByTabletID.size())) {
+ auto &counters = CountersByTabletID[idx];
+ counters.erase(tabletId);
+ ChangedCounters[idx] = true;
+ }
+ }
+
+ void RecalcAll() {
+ for (ui32 idx : xrange(CountersByTabletID.size())) {
+ if (ChangedCounters[idx])
+ Recalc(idx);
+ ChangedCounters[idx] = false;
+ }
+ }
+
+private:
+ //
+ NMonitoring::TDynamicCounterPtr CounterGroup;
+
+ TCountersVector MaxCumulativeCounters;
+ THistogramVector HistCumulativeCounters;
+ using TCountersByTabletIDMap = THashMap<ui64, ui64>;
+
+ TVector<TCountersByTabletIDMap> CountersByTabletID;
+ TVector<bool> ChangedCounters;
+
+private:
+ void Recalc(ui32 idx) {
+ auto &counters = CountersByTabletID[idx];
+ THistogramCounter* histCounter = HistCumulativeCounters[idx].Get();
+
+ ui64 maxVal = 0;
+
+ if (histCounter) {
+ histCounter->Clear();
+ }
+
+ for (auto&& t : counters) {
+ ui64 tValue = t.second;
+ maxVal = Max(tValue, maxVal);
+ if (histCounter) {
+ histCounter->IncrementFor(tValue);
+ }
+ }
+
+ *MaxCumulativeCounters[idx].Get() = maxVal;
+ }
+};
+
+struct TTabletLabeledCountersResponseContext {
+ NKikimrTabletCountersAggregator::TEvTabletLabeledCountersResponse& Response;
+ THashMap<TStringBuf, ui32> NamesToId;
+
+ TTabletLabeledCountersResponseContext(NKikimrTabletCountersAggregator::TEvTabletLabeledCountersResponse& response)
+ : Response(response)
+ {}
+
+ ui32 GetNameId(TStringBuf name) {
+ auto it = NamesToId.find(name);
+ if (it != NamesToId.end()) {
+ return it->second;
+ }
+ Response.AddCounterNames(TString(name));
+ ui32 id = Response.CounterNamesSize() - 1;
+ NamesToId[name] = id;
+ return id;
+ }
+};
+
class TAggregatedLabeledCounters {
public:
//
@@ -372,7 +372,7 @@ public:
return Ids[index];
}
- void FillGetRequestV1(NKikimrTabletCountersAggregator::TTabletLabeledCounters& labeledCounters, const TString& group, ui32 start, ui32 end) const {
+ void FillGetRequestV1(NKikimrTabletCountersAggregator::TTabletLabeledCounters& labeledCounters, const TString& group, ui32 start, ui32 end) const {
if (Changed) {
for (ui32 idx : xrange(CountersByTabletID.size())) {
Recalc(idx);
@@ -394,26 +394,26 @@ public:
}
}
- void FillGetRequestV2(TTabletLabeledCountersResponseContext& context, const TString& group) const {
- if (Changed) {
- for (ui32 idx : xrange(CountersByTabletID.size())) {
- Recalc(idx);
- }
- Changed = false;
- }
- auto& labeledCounters = *context.Response.AddLabeledCountersByGroup();
- labeledCounters.SetGroup(group);
+ void FillGetRequestV2(TTabletLabeledCountersResponseContext& context, const TString& group) const {
+ if (Changed) {
+ for (ui32 idx : xrange(CountersByTabletID.size())) {
+ Recalc(idx);
+ }
+ Changed = false;
+ }
+ auto& labeledCounters = *context.Response.AddLabeledCountersByGroup();
+ labeledCounters.SetGroup(group);
labeledCounters.SetDelimiter("/"); //TODO: change here to "|"
- for (ui32 i = 0; i < Size(); ++i) {
- auto& labeledCounter = *labeledCounters.AddLabeledCounter();
- labeledCounter.SetValue(GetValue(i));
- labeledCounter.SetNameId(context.GetNameId(Names[i]));
- labeledCounter.SetAggregateFunc(NKikimr::TLabeledCounterOptions::EAggregateFunc(AggrFunc[i]));
- labeledCounter.SetType(NKikimr::TLabeledCounterOptions::ECounterType(Types[i]));
- }
- }
-
-
+ for (ui32 i = 0; i < Size(); ++i) {
+ auto& labeledCounter = *labeledCounters.AddLabeledCounter();
+ labeledCounter.SetValue(GetValue(i));
+ labeledCounter.SetNameId(context.GetNameId(Names[i]));
+ labeledCounter.SetAggregateFunc(NKikimr::TLabeledCounterOptions::EAggregateFunc(AggrFunc[i]));
+ labeledCounter.SetType(NKikimr::TLabeledCounterOptions::ECounterType(Types[i]));
+ }
+ }
+
+
private:
//
NMonitoring::TDynamicCounterPtr CounterGroup;
@@ -499,24 +499,24 @@ public:
dbCounters->Apply(tabletID, executorCounters, appCounters, tabletType, limitedAppCounters);
}
}
-
- //
- auto& quietStats = QuietTabletCounters[tabletID];
- if (executorCounters) {
- if (quietStats.first == nullptr)
- quietStats.first = new TTabletCountersBase();
- quietStats.first->Populate(*executorCounters);
- }
+ //
+ auto& quietStats = QuietTabletCounters[tabletID];
+
+ if (executorCounters) {
+ if (quietStats.first == nullptr)
+ quietStats.first = new TTabletCountersBase();
+ quietStats.first->Populate(*executorCounters);
+ }
- if (appCounters) {
- if (quietStats.second == nullptr)
- quietStats.second = new TTabletCountersBase();
- quietStats.second->Populate(*appCounters);
- }
+ if (appCounters) {
+ if (quietStats.second == nullptr)
+ quietStats.second = new TTabletCountersBase();
+ quietStats.second->Populate(*appCounters);
+ }
}
- void ApplyLabeledCounters(ui64 tabletID, TTabletTypes::EType tabletType, const TTabletLabeledCountersBase* labeledCounters) {
+ void ApplyLabeledCounters(ui64 tabletID, TTabletTypes::EType tabletType, const TTabletLabeledCountersBase* labeledCounters) {
auto iterTabletType = LabeledCountersByTabletTypeAndGroup.find(std::make_pair(tabletType, labeledCounters->GetGroup()));
@@ -529,7 +529,7 @@ public:
if (iterTabletType == LabeledCountersByTabletTypeAndGroup.end()) {
- TString tabletTypeStr = TTabletTypes::TypeToStr(tabletType);
+ TString tabletTypeStr = TTabletTypes::TypeToStr(tabletType);
TString groupNames;
TVector<TString> rr;
StringSplitter(labeledCounters->GetGroup()).Split('/').SkipEmpty().Collect(&rr); // TODO: change here to "|"
@@ -538,11 +538,11 @@ public:
groupNames += '/';
groupNames += labeledCounters->GetGroupName(i);
}
- iterTabletType = LabeledCountersByTabletTypeAndGroup.emplace(
+ iterTabletType = LabeledCountersByTabletTypeAndGroup.emplace(
std::make_pair(tabletType, labeledCounters->GetGroup()),
new TAggregatedLabeledCounters(labeledCounters->GetCounters().Size(), labeledCounters->GetAggrFuncs(),
labeledCounters->GetNames(), labeledCounters->GetTypes(), groupNames)
- ).first;
+ ).first;
}
@@ -581,103 +581,103 @@ public:
Counters->RemoveSubgroup("tabletid", tabletIdStr.data());
}
- void Query(const NKikimrTabletCountersAggregator::TEvTabletCountersRequest& request, NKikimrTabletCountersAggregator::TEvTabletCountersResponse& response) {
+ void Query(const NKikimrTabletCountersAggregator::TEvTabletCountersRequest& request, NKikimrTabletCountersAggregator::TEvTabletCountersResponse& response) {
TVector<ui64> tabletIDs(request.GetTabletIds().begin(), request.GetTabletIds().end());
- if (tabletIDs.empty()) {
- for (const auto& pr : QuietTabletCounters) {
- auto& countersInfo = *response.AddCountersInfo();
- countersInfo.SetTabletId(pr.first);
- if (pr.second.first) { // executor counters
- auto& executorCounters = *countersInfo.MutableExecutorCounters();
- const auto& simple = pr.second.first->Simple();
- for (ui32 i = 0; i < simple.Size(); ++i) {
- executorCounters.AddSimpleCounters(simple[i].Get());
- }
- const auto& cumulative = pr.second.first->Cumulative();
- for (ui32 i = 0; i < cumulative.Size(); ++i) {
- executorCounters.AddCumulativeCounters(cumulative[i].Get());
- }
- }
- if (pr.second.second) { // app counters
- auto& appCounters = *countersInfo.MutableAppCounters();
- const auto& simple = pr.second.second->Simple();
- for (ui32 i = 0; i < simple.Size(); ++i) {
- appCounters.AddSimpleCounters(simple[i].Get());
- }
- const auto& cumulative = pr.second.second->Cumulative();
- for (ui32 i = 0; i < cumulative.Size(); ++i) {
- appCounters.AddCumulativeCounters(cumulative[i].Get());
- }
- }
- }
- } else {
- for (ui64 tabletID : tabletIDs) {
- auto it = QuietTabletCounters.find(tabletID);
- if (it != QuietTabletCounters.end()) {
- auto& countersInfo = *response.AddCountersInfo();
- countersInfo.SetTabletId(it->first);
- if (it->second.first) { // executor counters
- auto& executorCounters = *countersInfo.MutableExecutorCounters();
- const auto& simple = it->second.first->Simple();
- for (ui32 i = 0; i < simple.Size(); ++i) {
- executorCounters.AddSimpleCounters(simple[i].Get());
- }
- const auto& cumulative = it->second.first->Cumulative();
- for (ui32 i = 0; i < cumulative.Size(); ++i) {
- executorCounters.AddCumulativeCounters(cumulative[i].Get());
- }
- }
- if (it->second.second) { // app counters
- auto& appCounters = *countersInfo.MutableAppCounters();
- const auto& simple = it->second.second->Simple();
- for (ui32 i = 0; i < simple.Size(); ++i) {
- appCounters.AddSimpleCounters(simple[i].Get());
- }
- const auto& cumulative = it->second.second->Cumulative();
- for (ui32 i = 0; i < cumulative.Size(); ++i) {
- appCounters.AddCumulativeCounters(cumulative[i].Get());
- }
- }
- }
- }
- }
- }
-
+ if (tabletIDs.empty()) {
+ for (const auto& pr : QuietTabletCounters) {
+ auto& countersInfo = *response.AddCountersInfo();
+ countersInfo.SetTabletId(pr.first);
+ if (pr.second.first) { // executor counters
+ auto& executorCounters = *countersInfo.MutableExecutorCounters();
+ const auto& simple = pr.second.first->Simple();
+ for (ui32 i = 0; i < simple.Size(); ++i) {
+ executorCounters.AddSimpleCounters(simple[i].Get());
+ }
+ const auto& cumulative = pr.second.first->Cumulative();
+ for (ui32 i = 0; i < cumulative.Size(); ++i) {
+ executorCounters.AddCumulativeCounters(cumulative[i].Get());
+ }
+ }
+ if (pr.second.second) { // app counters
+ auto& appCounters = *countersInfo.MutableAppCounters();
+ const auto& simple = pr.second.second->Simple();
+ for (ui32 i = 0; i < simple.Size(); ++i) {
+ appCounters.AddSimpleCounters(simple[i].Get());
+ }
+ const auto& cumulative = pr.second.second->Cumulative();
+ for (ui32 i = 0; i < cumulative.Size(); ++i) {
+ appCounters.AddCumulativeCounters(cumulative[i].Get());
+ }
+ }
+ }
+ } else {
+ for (ui64 tabletID : tabletIDs) {
+ auto it = QuietTabletCounters.find(tabletID);
+ if (it != QuietTabletCounters.end()) {
+ auto& countersInfo = *response.AddCountersInfo();
+ countersInfo.SetTabletId(it->first);
+ if (it->second.first) { // executor counters
+ auto& executorCounters = *countersInfo.MutableExecutorCounters();
+ const auto& simple = it->second.first->Simple();
+ for (ui32 i = 0; i < simple.Size(); ++i) {
+ executorCounters.AddSimpleCounters(simple[i].Get());
+ }
+ const auto& cumulative = it->second.first->Cumulative();
+ for (ui32 i = 0; i < cumulative.Size(); ++i) {
+ executorCounters.AddCumulativeCounters(cumulative[i].Get());
+ }
+ }
+ if (it->second.second) { // app counters
+ auto& appCounters = *countersInfo.MutableAppCounters();
+ const auto& simple = it->second.second->Simple();
+ for (ui32 i = 0; i < simple.Size(); ++i) {
+ appCounters.AddSimpleCounters(simple[i].Get());
+ }
+ const auto& cumulative = it->second.second->Cumulative();
+ for (ui32 i = 0; i < cumulative.Size(); ++i) {
+ appCounters.AddCumulativeCounters(cumulative[i].Get());
+ }
+ }
+ }
+ }
+ }
+ }
+
void QueryLabeledCounters(const NKikimrTabletCountersAggregator::TEvTabletLabeledCountersRequest& request, NKikimrTabletCountersAggregator::TEvTabletLabeledCountersResponse& response, const TActorContext& ctx) {
LOG_INFO_S(ctx, NKikimrServices::TABLET_AGGREGATOR, "got request v" << request.GetVersion());
TString group = request.HasGroup() ? request.GetGroup() : "";
- TTabletTypes::EType tabletType = request.GetTabletType();
+ TTabletTypes::EType tabletType = request.GetTabletType();
ui32 cc = 0;
- if (request.GetVersion() == 1) {
- auto iter = LabeledCountersByTabletTypeAndGroup.lower_bound(std::make_pair(tabletType, group));
- for (; iter != LabeledCountersByTabletTypeAndGroup.end() && iter->first.first == tabletType &&
- (group.empty() || iter->first.second == group); ++iter) {
-
- ui32 s = 0, e = iter->second->Size();
- if (request.HasLabeledCounterId()) {
- s = request.GetLabeledCounterId();
- e = s + 1;
- }
- if (s >= iter->second->Size())
- continue;
- auto& labeledCountersByGroup = *response.AddLabeledCountersByGroup();
-
- iter->second->FillGetRequestV1(labeledCountersByGroup, iter->first.second, s, e);
- ++cc;
+ if (request.GetVersion() == 1) {
+ auto iter = LabeledCountersByTabletTypeAndGroup.lower_bound(std::make_pair(tabletType, group));
+ for (; iter != LabeledCountersByTabletTypeAndGroup.end() && iter->first.first == tabletType &&
+ (group.empty() || iter->first.second == group); ++iter) {
+
+ ui32 s = 0, e = iter->second->Size();
+ if (request.HasLabeledCounterId()) {
+ s = request.GetLabeledCounterId();
+ e = s + 1;
+ }
+ if (s >= iter->second->Size())
+ continue;
+ auto& labeledCountersByGroup = *response.AddLabeledCountersByGroup();
+
+ iter->second->FillGetRequestV1(labeledCountersByGroup, iter->first.second, s, e);
+ ++cc;
}
} else if (request.GetVersion() >= 2) {
- TTabletLabeledCountersResponseContext context(response);
- auto iter = LabeledCountersByTabletTypeAndGroup.lower_bound({tabletType, TString()});
- for (; iter != LabeledCountersByTabletTypeAndGroup.end()
- && iter->first.first == tabletType; ++iter) {
- if (group.empty() || IsMatchesWildcards(iter->first.second, group)) {
- iter->second->FillGetRequestV2(context, iter->first.second);
- }
- ++cc;
- }
+ TTabletLabeledCountersResponseContext context(response);
+ auto iter = LabeledCountersByTabletTypeAndGroup.lower_bound({tabletType, TString()});
+ for (; iter != LabeledCountersByTabletTypeAndGroup.end()
+ && iter->first.first == tabletType; ++iter) {
+ if (group.empty() || IsMatchesWildcards(iter->first.second, group)) {
+ iter->second->FillGetRequestV2(context, iter->first.second);
+ }
+ ++cc;
+ }
}
LOG_INFO_S(ctx, NKikimrServices::TABLET_AGGREGATOR, "request processed, " << cc << " groups processed");
}
@@ -719,37 +719,37 @@ private:
{
Y_VERIFY(executorCounters);
- if (executorCounters) {
- if (!TabletExecutorCounters.IsInitialized) {
- TabletExecutorCounters.Initialize(executorCounters);
- }
+ if (executorCounters) {
+ if (!TabletExecutorCounters.IsInitialized) {
+ TabletExecutorCounters.Initialize(executorCounters);
+ }
TabletExecutorCounters.Apply(tabletID, executorCounters, tabletType);
- }
+ }
- if (appCounters) {
- if (!TabletAppCounters.IsInitialized) {
+ if (appCounters) {
+ if (!TabletAppCounters.IsInitialized) {
TabletAppCounters.Initialize(limitedAppCounters ? limitedAppCounters : appCounters);
- }
+ }
TabletAppCounters.Apply(tabletID, appCounters, tabletType);
- }
+ }
}
void Forget(ui64 tabletId) {
- if (TabletExecutorCounters.IsInitialized) {
- TabletExecutorCounters.Forget(tabletId);
- }
- if (TabletAppCounters.IsInitialized) {
- TabletAppCounters.Forget(tabletId);
- }
+ if (TabletExecutorCounters.IsInitialized) {
+ TabletExecutorCounters.Forget(tabletId);
+ }
+ if (TabletAppCounters.IsInitialized) {
+ TabletAppCounters.Forget(tabletId);
+ }
}
void RecalcAll() {
- if (TabletExecutorCounters.IsInitialized) {
- TabletExecutorCounters.RecalcAll();
- }
- if (TabletAppCounters.IsInitialized) {
- TabletAppCounters.RecalcAll();
- }
+ if (TabletExecutorCounters.IsInitialized) {
+ TabletExecutorCounters.RecalcAll();
+ }
+ if (TabletAppCounters.IsInitialized) {
+ TabletAppCounters.RecalcAll();
+ }
}
// db counters
@@ -796,17 +796,17 @@ private:
private:
//
- class TSolomonCounters {
+ class TSolomonCounters {
public:
//
- bool IsInitialized;
-
- TSolomonCounters(NMonitoring::TDynamicCounterPtr counterGroup, bool doAggregateCounters)
+ bool IsInitialized;
+
+ TSolomonCounters(NMonitoring::TDynamicCounterPtr counterGroup, bool doAggregateCounters)
: IsInitialized(false)
- , DoAggregateSimpleCounters(doAggregateCounters)
+ , DoAggregateSimpleCounters(doAggregateCounters)
, AggregatedSimpleCounters(counterGroup)
- , DoAggregateCumulativeCounters(doAggregateCounters)
- , AggregatedCumulativeCounters(counterGroup)
+ , DoAggregateCumulativeCounters(doAggregateCounters)
+ , AggregatedCumulativeCounters(counterGroup)
, CounterGroup(counterGroup)
{}
@@ -814,8 +814,8 @@ private:
Y_VERIFY(!IsInitialized);
if (counters) {
- THashMap<TString, THolder<THistogramCounter>> histogramAggregates;
-
+ THashMap<TString, THolder<THistogramCounter>> histogramAggregates;
+
// percentile counters
FullSizePercentile = counters->Percentile().Size();
for (ui32 i = 0; i < FullSizePercentile; ++i) {
@@ -828,11 +828,11 @@ private:
PercentileCounters.push_back(TVector<NMonitoring::TDynamicCounters::TCounterPtr>());
auto counterRBeginIter = PercentileCounters.rbegin();
- auto& percentileCounter = counters->Percentile()[i];
+ auto& percentileCounter = counters->Percentile()[i];
const char* percentileCounterName = counters->PercentileCounterName(i);
- TStringBuf counterName(percentileCounterName);
- TStringBuf simpleCounterName = GetHistogramAggregateSimpleName(counterName);
- bool histogramAggregate = !simpleCounterName.empty();
+ TStringBuf counterName(percentileCounterName);
+ TStringBuf simpleCounterName = GetHistogramAggregateSimpleName(counterName);
+ bool histogramAggregate = !simpleCounterName.empty();
bool isDerivative = !histogramAggregate && !percentileCounter.GetIntegral();
@@ -853,52 +853,52 @@ private:
percentileCounterName, NMonitoring::ExplicitHistogram(bucketBounds), isDerivative);
Histograms.push_back(histogram);
- if (histogramAggregate) {
+ if (histogramAggregate) {
histogramAggregates.emplace(simpleCounterName, new THistogramCounter(
percentileCounter.GetRanges(), std::move(*counterRBeginIter), histogram));
- }
+ }
}
-
- // simple counters
+
+ // simple counters
FullSizeSimple = counters->Simple().Size();
for (ui32 i = 0; i < FullSizeSimple; ++i) {
- const char* name = counters->SimpleCounterName(i);
+ const char* name = counters->SimpleCounterName(i);
if (!name) {
DeprecatedSimple.insert(i);
continue;
}
- if (DoAggregateSimpleCounters) {
+ if (DoAggregateSimpleCounters) {
auto itHistogramAggregate = histogramAggregates.find(name);
if (itHistogramAggregate != histogramAggregates.end()) {
AggregatedSimpleCounters.AddSimpleCounter(name, std::move(itHistogramAggregate->second));
- } else {
- AggregatedSimpleCounters.AddSimpleCounter(name);
- }
- } else {
- auto counter = CounterGroup->GetCounter(name, false);
- SimpleCounters.push_back(counter);
- }
- }
-
- // cumulative counters
+ } else {
+ AggregatedSimpleCounters.AddSimpleCounter(name);
+ }
+ } else {
+ auto counter = CounterGroup->GetCounter(name, false);
+ SimpleCounters.push_back(counter);
+ }
+ }
+
+ // cumulative counters
FullSizeCumulative = counters->Cumulative().Size();
for (ui32 i = 0; i < FullSizeCumulative; ++i) {
- const char* name = counters->CumulativeCounterName(i);
+ const char* name = counters->CumulativeCounterName(i);
if (!name) {
DeprecatedCumulative.insert(i);
continue;
}
- if (DoAggregateCumulativeCounters) {
+ if (DoAggregateCumulativeCounters) {
auto itHistogramAggregate = histogramAggregates.find(name);
if (itHistogramAggregate != histogramAggregates.end()) {
AggregatedCumulativeCounters.AddCumulativeCounter(name, std::move(itHistogramAggregate->second));
- } else {
- AggregatedCumulativeCounters.AddCumulativeCounter(name);
- }
- }
- auto counter = CounterGroup->GetCounter(name, true);
- CumulativeCounters.push_back(counter);
- }
+ } else {
+ AggregatedCumulativeCounters.AddCumulativeCounter(name);
+ }
+ }
+ auto counter = CounterGroup->GetCounter(name, true);
+ CumulativeCounters.push_back(counter);
+ }
}
//
@@ -908,16 +908,16 @@ private:
void Apply(ui64 tabletID, const TTabletCountersBase* counters, TTabletTypes::EType tabletType) {
Y_VERIFY(counters);
- TInstant now = TInstant::Now();
- auto it = LastAggregateUpdateTime.find(tabletID);
- TDuration diff;
- if (it != LastAggregateUpdateTime.end()) {
- diff = now - it->second;
- it->second = now;
- } else {
- LastAggregateUpdateTime.emplace(tabletID, now);
- }
-
+ TInstant now = TInstant::Now();
+ auto it = LastAggregateUpdateTime.find(tabletID);
+ TDuration diff;
+ if (it != LastAggregateUpdateTime.end()) {
+ diff = now - it->second;
+ it->second = now;
+ } else {
+ LastAggregateUpdateTime.emplace(tabletID, now);
+ }
+
// simple counters
ui32 nextSimpleOffset = 0;
for (ui32 i = 0; i < FullSizeSimple; ++i) {
@@ -941,13 +941,13 @@ private:
continue;
}
const ui32 offset = nextCumulativeOffset++;
- const ui64 valueDiff = counters->Cumulative()[i].Get();
- if (DoAggregateCumulativeCounters) {
- if (diff) {
- const ui64 diffValue = valueDiff * 1000000 / diff.MicroSeconds(); // differentiate value to per second rate
+ const ui64 valueDiff = counters->Cumulative()[i].Get();
+ if (DoAggregateCumulativeCounters) {
+ if (diff) {
+ const ui64 diffValue = valueDiff * 1000000 / diff.MicroSeconds(); // differentiate value to per second rate
AggregatedCumulativeCounters.SetValue(tabletID, offset, diffValue, tabletType);
- }
- }
+ }
+ }
Y_VERIFY(offset < CumulativeCounters.size(), "inconsistent counters for tablet type %s", TTabletTypes::TypeToStr(tabletType));
*CumulativeCounters[offset] += valueDiff;
}
@@ -964,9 +964,9 @@ private:
auto &pcx = PercentileCounters[offset];
if (pcx.empty()) {
- continue;
- }
-
+ continue;
+ }
+
auto&& percentileCounter = counters->Percentile()[i];
auto rangeCount = percentileCounter.GetRangeCount();
Y_VERIFY(rangeCount <= pcx.size(),
@@ -1002,14 +1002,14 @@ private:
void Forget(ui64 tabletId) {
Y_VERIFY(IsInitialized);
- if (DoAggregateSimpleCounters || DoAggregateCumulativeCounters) {
- if (DoAggregateSimpleCounters) {
- AggregatedSimpleCounters.ForgetTablet(tabletId);
- }
- if (DoAggregateCumulativeCounters) {
- AggregatedCumulativeCounters.ForgetTablet(tabletId);
- LastAggregateUpdateTime.erase(tabletId);
- }
+ if (DoAggregateSimpleCounters || DoAggregateCumulativeCounters) {
+ if (DoAggregateSimpleCounters) {
+ AggregatedSimpleCounters.ForgetTablet(tabletId);
+ }
+ if (DoAggregateCumulativeCounters) {
+ AggregatedCumulativeCounters.ForgetTablet(tabletId);
+ LastAggregateUpdateTime.erase(tabletId);
+ }
} else {
for (auto &x : SimpleCounters)
x = 0;
@@ -1019,10 +1019,10 @@ private:
void RecalcAll() {
if (DoAggregateSimpleCounters) {
AggregatedSimpleCounters.RecalcAll();
- }
+ }
if (DoAggregateCumulativeCounters) {
- AggregatedCumulativeCounters.RecalcAll();
- }
+ AggregatedCumulativeCounters.RecalcAll();
+ }
}
template <bool IsSaving>
@@ -1134,13 +1134,13 @@ private:
//
bool DoAggregateSimpleCounters;
TCountersVector SimpleCounters;
- TAggregatedSimpleCounters AggregatedSimpleCounters;
+ TAggregatedSimpleCounters AggregatedSimpleCounters;
- bool DoAggregateCumulativeCounters;
+ bool DoAggregateCumulativeCounters;
TCountersVector CumulativeCounters;
- TAggregatedCumulativeCounters AggregatedCumulativeCounters;
- THashMap<ui64, TInstant> LastAggregateUpdateTime;
-
+ TAggregatedCumulativeCounters AggregatedCumulativeCounters;
+ THashMap<ui64, TInstant> LastAggregateUpdateTime;
+
TVector<TCountersVector> PercentileCounters; // old style
TVector<NMonitoring::THistogramPtr> Histograms; // new style
@@ -1153,8 +1153,8 @@ private:
NMonitoring::TDynamicCounterPtr TabletExecutorCountersSection;
NMonitoring::TDynamicCounterPtr TabletAppCountersSection;
- TSolomonCounters TabletExecutorCounters;
- TSolomonCounters TabletAppCounters;
+ TSolomonCounters TabletExecutorCounters;
+ TSolomonCounters TabletAppCounters;
};
typedef TMap<TTabletTypes::EType, TAutoPtr<TTabletCountersForTabletType> > TCountersByTabletType;
@@ -1576,7 +1576,7 @@ private:
//
void HandleWork(TEvTabletCounters::TEvTabletAddCounters::TPtr &ev, const TActorContext &ctx);
void HandleWork(TEvTabletCounters::TEvTabletCountersForgetTablet::TPtr &ev, const TActorContext &ctx);
- void HandleWork(TEvTabletCounters::TEvTabletCountersRequest::TPtr &ev, const TActorContext &ctx);
+ void HandleWork(TEvTabletCounters::TEvTabletCountersRequest::TPtr &ev, const TActorContext &ctx);
void HandleWork(TEvTabletCounters::TEvTabletAddLabeledCounters::TPtr &ev, const TActorContext &ctx);
void HandleWork(TEvTabletCounters::TEvTabletLabeledCountersRequest::TPtr &ev, const TActorContext &ctx);
void HandleWork(TEvTabletCounters::TEvTabletLabeledCountersResponse::TPtr &ev, const TActorContext &ctx);//from cluster aggregator
@@ -1620,7 +1620,7 @@ TTabletCountersAggregatorActor::Bootstrap(const TActorContext &ctx) {
auto mon = appData->Mon;
if (mon) {
if (!Follower)
- mon->RegisterActorPage(nullptr, "labeledcounters", "Labeled Counters", false, TlsActivationContext->ExecutorThread.ActorSystem, SelfId(), false);
+ mon->RegisterActorPage(nullptr, "labeledcounters", "Labeled Counters", false, TlsActivationContext->ExecutorThread.ActorSystem, SelfId(), false);
else
mon->RegisterActorPage(nullptr, "followercounters", "Follower Counters", false, TlsActivationContext->ExecutorThread.ActorSystem, SelfId(), false);
}
@@ -1656,15 +1656,15 @@ TTabletCountersAggregatorActor::HandleWork(TEvTabletCounters::TEvTabletCountersF
}
////////////////////////////////////////////
-void
-TTabletCountersAggregatorActor::HandleWork(TEvTabletCounters::TEvTabletCountersRequest::TPtr &ev, const TActorContext &ctx) {
- TEvTabletCounters::TEvTabletCountersRequest* msg = ev->Get();
- TAutoPtr<TEvTabletCounters::TEvTabletCountersResponse> resp = new TEvTabletCounters::TEvTabletCountersResponse();
- TabletMon->Query(msg->Record, resp->Record);
- ctx.Send(ev->Sender, resp.Release(), 0, ev->Cookie);
-}
-
-////////////////////////////////////////////
+void
+TTabletCountersAggregatorActor::HandleWork(TEvTabletCounters::TEvTabletCountersRequest::TPtr &ev, const TActorContext &ctx) {
+ TEvTabletCounters::TEvTabletCountersRequest* msg = ev->Get();
+ TAutoPtr<TEvTabletCounters::TEvTabletCountersResponse> resp = new TEvTabletCounters::TEvTabletCountersResponse();
+ TabletMon->Query(msg->Record, resp->Record);
+ ctx.Send(ev->Sender, resp.Release(), 0, ev->Cookie);
+}
+
+////////////////////////////////////////////
void
TTabletCountersAggregatorActor::HandleWork(TEvTabletCounters::TEvTabletLabeledCountersRequest::TPtr &ev, const TActorContext &ctx) {
TEvTabletCounters::TEvTabletLabeledCountersRequest* msg = ev->Get();
@@ -1799,8 +1799,8 @@ TTabletCountersAggregatorActor::HandleWork(NMon::TEvHttpInfo::TPtr &ev, const TA
ui32 workers = 0;
TryFromString(ev->Get()->Request.GetParams().Get("workers"), workers);
for (ui32 tabletType = 0; tabletType < TTabletTypes::USER_TYPE_START; ++tabletType) {
- if (!NKikimrTabletBase::TTabletTypes::EType_IsValid(tabletType))
- continue;
+ if (!NKikimrTabletBase::TTabletTypes::EType_IsValid(tabletType))
+ continue;
TString tabletTypeStr = TTabletTypes::TypeToStr((TTabletTypes::EType)tabletType);
if (tabletTypeStr == reqTabletType) {
TActorId handler = CreateClusterLabeledCountersAggregator(ctx.SelfID, (TTabletTypes::EType)tabletType, ctx, 1, "", workers);
@@ -1835,7 +1835,7 @@ STFUNC(TTabletCountersAggregatorActor::StateWork) {
switch (ev->GetTypeRewrite()) {
HFunc(TEvTabletCounters::TEvTabletAddCounters, HandleWork);
HFunc(TEvTabletCounters::TEvTabletCountersForgetTablet, HandleWork);
- HFunc(TEvTabletCounters::TEvTabletCountersRequest, HandleWork);
+ HFunc(TEvTabletCounters::TEvTabletCountersRequest, HandleWork);
HFunc(TEvTabletCounters::TEvTabletAddLabeledCounters, HandleWork);
HFunc(TEvTabletCounters::TEvTabletLabeledCountersRequest, HandleWork);
HFunc(TEvTabletCounters::TEvTabletLabeledCountersResponse, HandleWork); //from cluster aggregator, for http requests
@@ -1892,8 +1892,8 @@ void PreProcessResponse(TEvTabletCounters::TEvTabletLabeledCountersResponse* res
}
-class TClusterLabeledCountersAggregatorActorV1 : public TActorBootstrapped<TClusterLabeledCountersAggregatorActorV1> {
- using TBase = TActorBootstrapped<TClusterLabeledCountersAggregatorActorV1>;
+class TClusterLabeledCountersAggregatorActorV1 : public TActorBootstrapped<TClusterLabeledCountersAggregatorActorV1> {
+ using TBase = TActorBootstrapped<TClusterLabeledCountersAggregatorActorV1>;
TActorId Initiator;
TTabletTypes::EType TabletType;
ui32 NodesRequested;
@@ -1924,7 +1924,7 @@ public:
TActorId aggregatorServiceId = MakeTabletCountersAggregatorID(nodeId);
TAutoPtr<TEvTabletCounters::TEvTabletLabeledCountersRequest> request(new TEvTabletCounters::TEvTabletLabeledCountersRequest());
request->Record.SetTabletType(TabletType);
- request->Record.SetVersion(1);
+ request->Record.SetVersion(1);
ctx.Send(aggregatorServiceId, request.Release(), IEventHandle::FlagTrackDelivery | IEventHandle::FlagSubscribeOnSession, nodeId);
Nodes.emplace_back(nodeId);
LOG_INFO_S(ctx, NKikimrServices::TABLET_AGGREGATOR, "aggregator actor request to node " << nodeId << " " << ctx.SelfID);
@@ -1937,7 +1937,7 @@ public:
}
TBase::Die(ctx);
}
-
+
void Bootstrap(const TActorContext& ctx) {
if (NumWorkers > 0) {
const TActorId nameserviceId = GetNameserviceActorId();
@@ -2161,148 +2161,148 @@ public:
}
};
-class TClusterLabeledCountersAggregatorActorV2 : public TActorBootstrapped<TClusterLabeledCountersAggregatorActorV2> {
- using TBase = TActorBootstrapped<TClusterLabeledCountersAggregatorActorV2>;
+class TClusterLabeledCountersAggregatorActorV2 : public TActorBootstrapped<TClusterLabeledCountersAggregatorActorV2> {
+ using TBase = TActorBootstrapped<TClusterLabeledCountersAggregatorActorV2>;
TActorId Initiator;
- TTabletTypes::EType TabletType;
- ui32 NodesRequested;
- ui32 NodesReceived;
- TVector<ui32> Nodes;
- THolder<TEvTabletCounters::TEvTabletLabeledCountersResponse> Response;
- TTabletLabeledCountersResponseContext ResponseContext;
- THashMap<ui32, THolder<TEvTabletCounters::TEvTabletLabeledCountersResponse>> PerNodeResponse;
- THashMap<TString, NKikimrTabletCountersAggregator::TTabletLabeledCounters*> IndexTabletLabeledCounters;
- THashMap<std::pair<NKikimrTabletCountersAggregator::TTabletLabeledCounters*, ui32>, NKikimrTabletCountersAggregator::TTabletLabeledCounter*> IndexTabletLabeledCounter;
- TString Group;
+ TTabletTypes::EType TabletType;
+ ui32 NodesRequested;
+ ui32 NodesReceived;
+ TVector<ui32> Nodes;
+ THolder<TEvTabletCounters::TEvTabletLabeledCountersResponse> Response;
+ TTabletLabeledCountersResponseContext ResponseContext;
+ THashMap<ui32, THolder<TEvTabletCounters::TEvTabletLabeledCountersResponse>> PerNodeResponse;
+ THashMap<TString, NKikimrTabletCountersAggregator::TTabletLabeledCounters*> IndexTabletLabeledCounters;
+ THashMap<std::pair<NKikimrTabletCountersAggregator::TTabletLabeledCounters*, ui32>, NKikimrTabletCountersAggregator::TTabletLabeledCounter*> IndexTabletLabeledCounter;
+ TString Group;
ui32 NumWorkers;
ui32 WorkerId;
bool NewFormat;
-
-public:
+
+public:
static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
return NKikimrServices::TActivity::TABLET_COUNTERS_AGGREGATOR;
- }
-
- //
+ }
+
+ //
TClusterLabeledCountersAggregatorActorV2(const TActorId& parentActor, const TTabletTypes::EType tabletType, const TString& group, ui32 numWorkers = 0, ui32 workerId = 0, bool newFormat = false)
- : Initiator(parentActor)
- , TabletType(tabletType)
- , NodesRequested(0)
- , NodesReceived(0)
- , Response(new TEvTabletCounters::TEvTabletLabeledCountersResponse())
- , ResponseContext(Response->Record)
- , Group(group)
+ : Initiator(parentActor)
+ , TabletType(tabletType)
+ , NodesRequested(0)
+ , NodesReceived(0)
+ , Response(new TEvTabletCounters::TEvTabletLabeledCountersResponse())
+ , ResponseContext(Response->Record)
+ , Group(group)
, NumWorkers(numWorkers)
, WorkerId(workerId)
, NewFormat(newFormat)
- {}
-
- void SendRequest(ui32 nodeId, const TActorContext &ctx) {
+ {}
+
+ void SendRequest(ui32 nodeId, const TActorContext &ctx) {
TActorId aggregatorServiceId = MakeTabletCountersAggregatorID(nodeId);
- TAutoPtr<TEvTabletCounters::TEvTabletLabeledCountersRequest> request(new TEvTabletCounters::TEvTabletLabeledCountersRequest());
- request->Record.SetVersion(2);
- request->Record.SetTabletType(TabletType);
- if (!Group.empty()) {
- request->Record.SetGroup(Group);
-
- }
- ctx.Send(aggregatorServiceId, request.Release(), IEventHandle::FlagTrackDelivery | IEventHandle::FlagSubscribeOnSession, nodeId);
- Nodes.emplace_back(nodeId);
+ TAutoPtr<TEvTabletCounters::TEvTabletLabeledCountersRequest> request(new TEvTabletCounters::TEvTabletLabeledCountersRequest());
+ request->Record.SetVersion(2);
+ request->Record.SetTabletType(TabletType);
+ if (!Group.empty()) {
+ request->Record.SetGroup(Group);
+
+ }
+ ctx.Send(aggregatorServiceId, request.Release(), IEventHandle::FlagTrackDelivery | IEventHandle::FlagSubscribeOnSession, nodeId);
+ Nodes.emplace_back(nodeId);
LOG_INFO_S(ctx, NKikimrServices::TABLET_AGGREGATOR, "aggregator actor request to node " << nodeId << " " << ctx.SelfID);
- ++NodesRequested;
- }
-
- NKikimrTabletCountersAggregator::TTabletLabeledCounters* GetCounters(const TString& group) {
- auto it = IndexTabletLabeledCounters.find(group);
- if (it != IndexTabletLabeledCounters.end()) {
- return it->second;
- }
- NKikimrTabletCountersAggregator::TTabletLabeledCounters* counters = Response->Record.AddLabeledCountersByGroup();
- counters->SetGroup(group);
+ ++NodesRequested;
+ }
+
+ NKikimrTabletCountersAggregator::TTabletLabeledCounters* GetCounters(const TString& group) {
+ auto it = IndexTabletLabeledCounters.find(group);
+ if (it != IndexTabletLabeledCounters.end()) {
+ return it->second;
+ }
+ NKikimrTabletCountersAggregator::TTabletLabeledCounters* counters = Response->Record.AddLabeledCountersByGroup();
+ counters->SetGroup(group);
counters->SetDelimiter("/"); //TODO:change to "|"
- IndexTabletLabeledCounters.emplace(group, counters);
- return counters;
- }
-
- NKikimrTabletCountersAggregator::TTabletLabeledCounter* GetCounter(NKikimrTabletCountersAggregator::TTabletLabeledCounters* counters, ui32 nameId) {
- auto key = std::make_pair(counters, nameId);
- auto it = IndexTabletLabeledCounter.find(key);
- if (it != IndexTabletLabeledCounter.end()) {
- return it->second;
- }
- NKikimrTabletCountersAggregator::TTabletLabeledCounter* counter = counters->AddLabeledCounter();
- counter->SetNameId(nameId);
- IndexTabletLabeledCounter.emplace(key, counter);
- return counter;
- }
-
- void Merge(NKikimrTabletCountersAggregator::TTabletLabeledCounter& target, const NKikimrTabletCountersAggregator::TTabletLabeledCounter& source) {
- ui64 value(source.GetValue());
- TLabeledCounterOptions::ECounterType type(source.GetType());
- NKikimr::TLabeledCounterOptions::EAggregateFunc func(source.GetAggregateFunc());
- if (type == TLabeledCounterOptions::CT_TIMELAG) {
- type = TLabeledCounterOptions::CT_SIMPLE;
+ IndexTabletLabeledCounters.emplace(group, counters);
+ return counters;
+ }
+
+ NKikimrTabletCountersAggregator::TTabletLabeledCounter* GetCounter(NKikimrTabletCountersAggregator::TTabletLabeledCounters* counters, ui32 nameId) {
+ auto key = std::make_pair(counters, nameId);
+ auto it = IndexTabletLabeledCounter.find(key);
+ if (it != IndexTabletLabeledCounter.end()) {
+ return it->second;
+ }
+ NKikimrTabletCountersAggregator::TTabletLabeledCounter* counter = counters->AddLabeledCounter();
+ counter->SetNameId(nameId);
+ IndexTabletLabeledCounter.emplace(key, counter);
+ return counter;
+ }
+
+ void Merge(NKikimrTabletCountersAggregator::TTabletLabeledCounter& target, const NKikimrTabletCountersAggregator::TTabletLabeledCounter& source) {
+ ui64 value(source.GetValue());
+ TLabeledCounterOptions::ECounterType type(source.GetType());
+ NKikimr::TLabeledCounterOptions::EAggregateFunc func(source.GetAggregateFunc());
+ if (type == TLabeledCounterOptions::CT_TIMELAG) {
+ type = TLabeledCounterOptions::CT_SIMPLE;
auto now = TInstant::Now().MilliSeconds();
value = now > value ? now - value : 0;
- switch (func) {
- case NKikimr::TLabeledCounterOptions::EAF_MIN:
- func = NKikimr::TLabeledCounterOptions::EAF_MAX;
- break;
- case NKikimr::TLabeledCounterOptions::EAF_MAX:
- func = NKikimr::TLabeledCounterOptions::EAF_MIN;
- break;
- default:
- break;
- }
- }
- if (target.HasValue()) {
- switch (func) {
- case NKikimr::TLabeledCounterOptions::EAF_MIN:
- target.SetValue(std::min(target.GetValue(), value));
- break;
- case NKikimr::TLabeledCounterOptions::EAF_MAX:
- target.SetValue(std::max(target.GetValue(), value));
- break;
- case NKikimr::TLabeledCounterOptions::EAF_SUM:
- target.SetValue(target.GetValue() + value);
- break;
- }
- } else {
- target.SetValue(value);
- target.SetType(type);
- target.SetAggregateFunc(func);
- }
- }
-
- void Merge(const NKikimrTabletCountersAggregator::TEvTabletLabeledCountersResponse& source) {
- TVector<ui32> namesMapper;
- namesMapper.reserve(source.CounterNamesSize());
- for (const TString& name : source.GetCounterNames()) {
- namesMapper.push_back(ResponseContext.GetNameId(name));
- }
- for (const NKikimrTabletCountersAggregator::TTabletLabeledCounters& srcCounters : source.GetLabeledCountersByGroup()) {
- NKikimrTabletCountersAggregator::TTabletLabeledCounters* trgCounters = GetCounters(srcCounters.GetGroup());
- for (const NKikimrTabletCountersAggregator::TTabletLabeledCounter& srcCounter : srcCounters.GetLabeledCounter()) {
- ui32 nameId = 0;
- if (srcCounter.HasName()) {
- nameId = ResponseContext.GetNameId(srcCounter.GetName());
- } else {
- nameId = namesMapper[srcCounter.GetNameId()];
- }
- NKikimrTabletCountersAggregator::TTabletLabeledCounter* trgCounter = GetCounter(trgCounters, nameId);
- Merge(*trgCounter, srcCounter);
- }
- }
- }
-
- void Die(const TActorContext& ctx) override {
- for (const ui32 node : Nodes) {
+ switch (func) {
+ case NKikimr::TLabeledCounterOptions::EAF_MIN:
+ func = NKikimr::TLabeledCounterOptions::EAF_MAX;
+ break;
+ case NKikimr::TLabeledCounterOptions::EAF_MAX:
+ func = NKikimr::TLabeledCounterOptions::EAF_MIN;
+ break;
+ default:
+ break;
+ }
+ }
+ if (target.HasValue()) {
+ switch (func) {
+ case NKikimr::TLabeledCounterOptions::EAF_MIN:
+ target.SetValue(std::min(target.GetValue(), value));
+ break;
+ case NKikimr::TLabeledCounterOptions::EAF_MAX:
+ target.SetValue(std::max(target.GetValue(), value));
+ break;
+ case NKikimr::TLabeledCounterOptions::EAF_SUM:
+ target.SetValue(target.GetValue() + value);
+ break;
+ }
+ } else {
+ target.SetValue(value);
+ target.SetType(type);
+ target.SetAggregateFunc(func);
+ }
+ }
+
+ void Merge(const NKikimrTabletCountersAggregator::TEvTabletLabeledCountersResponse& source) {
+ TVector<ui32> namesMapper;
+ namesMapper.reserve(source.CounterNamesSize());
+ for (const TString& name : source.GetCounterNames()) {
+ namesMapper.push_back(ResponseContext.GetNameId(name));
+ }
+ for (const NKikimrTabletCountersAggregator::TTabletLabeledCounters& srcCounters : source.GetLabeledCountersByGroup()) {
+ NKikimrTabletCountersAggregator::TTabletLabeledCounters* trgCounters = GetCounters(srcCounters.GetGroup());
+ for (const NKikimrTabletCountersAggregator::TTabletLabeledCounter& srcCounter : srcCounters.GetLabeledCounter()) {
+ ui32 nameId = 0;
+ if (srcCounter.HasName()) {
+ nameId = ResponseContext.GetNameId(srcCounter.GetName());
+ } else {
+ nameId = namesMapper[srcCounter.GetNameId()];
+ }
+ NKikimrTabletCountersAggregator::TTabletLabeledCounter* trgCounter = GetCounter(trgCounters, nameId);
+ Merge(*trgCounter, srcCounter);
+ }
+ }
+ }
+
+ void Die(const TActorContext& ctx) override {
+ for (const ui32 node : Nodes) {
ctx.Send(TActivationContext::InterconnectProxy(node), new TEvents::TEvUnsubscribe());
- }
- TBase::Die(ctx);
- }
-
- void Bootstrap(const TActorContext& ctx) {
+ }
+ TBase::Die(ctx);
+ }
+
+ void Bootstrap(const TActorContext& ctx) {
if (NumWorkers > 0) {
const TActorId nameserviceId = GetNameserviceActorId();
ctx.Send(nameserviceId, new TEvInterconnect::TEvListNodes());
@@ -2317,83 +2317,83 @@ public:
NodesRequested = WorkerId;
TBase::Become(&TThis::StateRequested);
}
- }
-
- STFUNC(StateRequestedBrowse) {
- switch (ev->GetTypeRewrite()) {
- HFunc(TEvInterconnect::TEvNodesInfo, HandleBrowse);
- CFunc(TEvents::TSystem::Wakeup, HandleTimeout);
- }
- }
-
- STFUNC(StateRequested) {
- switch (ev->GetTypeRewrite()) {
- HFunc(TEvTabletCounters::TEvTabletLabeledCountersResponse, HandleResponse);
- HFunc(TEvents::TEvUndelivered, Undelivered);
- HFunc(TEvInterconnect::TEvNodeDisconnected, Disconnected);
- CFunc(TEvents::TSystem::Wakeup, HandleTimeout);
- }
- }
-
- void HandleBrowse(TEvInterconnect::TEvNodesInfo::TPtr &ev, const TActorContext &ctx) {
- const TEvInterconnect::TEvNodesInfo* nodesInfo = ev->Get();
- Y_VERIFY(!nodesInfo->Nodes.empty());
- Nodes.reserve(nodesInfo->Nodes.size());
+ }
+
+ STFUNC(StateRequestedBrowse) {
+ switch (ev->GetTypeRewrite()) {
+ HFunc(TEvInterconnect::TEvNodesInfo, HandleBrowse);
+ CFunc(TEvents::TSystem::Wakeup, HandleTimeout);
+ }
+ }
+
+ STFUNC(StateRequested) {
+ switch (ev->GetTypeRewrite()) {
+ HFunc(TEvTabletCounters::TEvTabletLabeledCountersResponse, HandleResponse);
+ HFunc(TEvents::TEvUndelivered, Undelivered);
+ HFunc(TEvInterconnect::TEvNodeDisconnected, Disconnected);
+ CFunc(TEvents::TSystem::Wakeup, HandleTimeout);
+ }
+ }
+
+ void HandleBrowse(TEvInterconnect::TEvNodesInfo::TPtr &ev, const TActorContext &ctx) {
+ const TEvInterconnect::TEvNodesInfo* nodesInfo = ev->Get();
+ Y_VERIFY(!nodesInfo->Nodes.empty());
+ Nodes.reserve(nodesInfo->Nodes.size());
ui32 i = 0;
- for (const auto& ni : nodesInfo->Nodes) {
+ for (const auto& ni : nodesInfo->Nodes) {
++i;
if (i % NumWorkers == WorkerId) {
SendRequest(ni.NodeId, ctx);
}
- }
- if (NodesRequested > 0) {
- TBase::Become(&TThis::StateRequested);
- } else {
- ReplyAndDie(ctx);
- }
- }
-
- void Undelivered(TEvents::TEvUndelivered::TPtr &ev, const TActorContext &ctx) {
- ui32 nodeId = ev.Get()->Cookie;
+ }
+ if (NodesRequested > 0) {
+ TBase::Become(&TThis::StateRequested);
+ } else {
+ ReplyAndDie(ctx);
+ }
+ }
+
+ void Undelivered(TEvents::TEvUndelivered::TPtr &ev, const TActorContext &ctx) {
+ ui32 nodeId = ev.Get()->Cookie;
LOG_INFO_S(ctx, NKikimrServices::TABLET_AGGREGATOR, "aggregator actor undelivered node " << nodeId << " " << ctx.SelfID);
- if (PerNodeResponse.emplace(nodeId, nullptr).second) {
- NodeResponseReceived(ctx);
- }
- }
-
- void Disconnected(TEvInterconnect::TEvNodeDisconnected::TPtr &ev, const TActorContext &ctx) {
- ui32 nodeId = ev->Get()->NodeId;
+ if (PerNodeResponse.emplace(nodeId, nullptr).second) {
+ NodeResponseReceived(ctx);
+ }
+ }
+
+ void Disconnected(TEvInterconnect::TEvNodeDisconnected::TPtr &ev, const TActorContext &ctx) {
+ ui32 nodeId = ev->Get()->NodeId;
LOG_INFO_S(ctx, NKikimrServices::TABLET_AGGREGATOR, "aggregator actor disconnected node " << nodeId << " " << ctx.SelfID);
- if (PerNodeResponse.emplace(nodeId, nullptr).second) {
- NodeResponseReceived(ctx);
- }
- }
-
- void HandleResponse(TEvTabletCounters::TEvTabletLabeledCountersResponse::TPtr &ev, const TActorContext &ctx) {
- ui64 nodeId = ev.Get()->Cookie;
+ if (PerNodeResponse.emplace(nodeId, nullptr).second) {
+ NodeResponseReceived(ctx);
+ }
+ }
+
+ void HandleResponse(TEvTabletCounters::TEvTabletLabeledCountersResponse::TPtr &ev, const TActorContext &ctx) {
+ ui64 nodeId = ev.Get()->Cookie;
LOG_INFO_S(ctx, NKikimrServices::TABLET_AGGREGATOR, "aggregator actor got response node " << nodeId << " " << ctx.SelfID);
PreProcessResponse(ev->Get());
- auto it = PerNodeResponse.emplace(nodeId, ev->Release().Release());
+ auto it = PerNodeResponse.emplace(nodeId, ev->Release().Release());
LOG_INFO_S(ctx, NKikimrServices::TABLET_AGGREGATOR, "aggregator actor merged response node " << nodeId << " " << ctx.SelfID);
- if (it.second) {
- Merge(it.first->second->Record);
- NodeResponseReceived(ctx);
- }
- }
-
- void NodeResponseReceived(const TActorContext &ctx) {
- ++NodesReceived;
- if (NodesReceived >= NodesRequested) {
- ReplyAndDie(ctx);
- }
- }
-
- void HandleTimeout(const TActorContext &ctx) {
- LOG_DEBUG_S(ctx, NKikimrServices::TABLET_AGGREGATOR, "aggregator actor got TIMEOUT");
- ReplyAndDie(ctx);
- }
-
- void ReplyAndDie(const TActorContext& ctx) {
+ if (it.second) {
+ Merge(it.first->second->Record);
+ NodeResponseReceived(ctx);
+ }
+ }
+
+ void NodeResponseReceived(const TActorContext &ctx) {
+ ++NodesReceived;
+ if (NodesReceived >= NodesRequested) {
+ ReplyAndDie(ctx);
+ }
+ }
+
+ void HandleTimeout(const TActorContext &ctx) {
+ LOG_DEBUG_S(ctx, NKikimrServices::TABLET_AGGREGATOR, "aggregator actor got TIMEOUT");
+ ReplyAndDie(ctx);
+ }
+
+ void ReplyAndDie(const TActorContext& ctx) {
LOG_INFO_S(ctx, NKikimrServices::TABLET_AGGREGATOR, "aggregator request processed " << ctx.SelfID << " Initiator " << Initiator);
ui64 cookie = NumWorkers ? WorkerId : 0;
if (NewFormat) {
@@ -2429,20 +2429,20 @@ public:
}
}
ctx.Send(Initiator, Response.Release(), 0, cookie);
- TBase::Die(ctx);
- }
-};
-
+ TBase::Die(ctx);
+ }
+};
+
IActor* CreateClusterLabeledCountersAggregatorActor(const TActorId& parentActor, TTabletTypes::EType tabletType, ui32 version, const TString& group, const ui32 totalWorkersCount) {
- switch (version) {
- case 1:
+ switch (version) {
+ case 1:
return new TClusterLabeledCountersAggregatorActorV1(parentActor, tabletType, totalWorkersCount == 0 ? 1 : 0, totalWorkersCount);
- case 2:
+ case 2:
return new TClusterLabeledCountersAggregatorActorV2(parentActor, tabletType, group, totalWorkersCount == 0 ? 1 : 0, totalWorkersCount);
case 3: //new format
return new TClusterLabeledCountersAggregatorActorV2(parentActor, tabletType, group, totalWorkersCount == 0 ? 1 : 0, totalWorkersCount, true);
- }
- return nullptr;
+ }
+ return nullptr;
}
diff --git a/ydb/core/tablet/tablet_counters_aggregator.h b/ydb/core/tablet/tablet_counters_aggregator.h
index 0744787fc38..db350d41cbf 100644
--- a/ydb/core/tablet/tablet_counters_aggregator.h
+++ b/ydb/core/tablet/tablet_counters_aggregator.h
@@ -28,8 +28,8 @@ struct TEvTabletCounters {
EvTabletAddCounters = EventSpaceBegin(TKikimrEvents::ES_TABLET_COUNTERS_AGGREGATOR),
EvDeprecated1,
EvTabletCountersForgetTablet,
- EvTabletCountersRequest,
- EvTabletCountersResponse,
+ EvTabletCountersRequest,
+ EvTabletCountersResponse,
EvTabletAddLabeledCounters,
EvTabletLabeledCountersRequest,
EvTabletLabeledCountersResponse,
@@ -45,7 +45,7 @@ struct TEvTabletCounters {
struct TEvTabletAddCounters : public TEventLocal<TEvTabletAddCounters, EvTabletAddCounters> {
//
const ui64 TabletID;
- const TTabletTypes::EType TabletType;
+ const TTabletTypes::EType TabletType;
const TPathId TenantPathId;
TAutoPtr<TTabletCountersBase> ExecutorCounters;
TAutoPtr<TTabletCountersBase> AppCounters;
@@ -65,10 +65,10 @@ struct TEvTabletCounters {
struct TEvTabletAddLabeledCounters : public TEventLocal<TEvTabletAddLabeledCounters, EvTabletAddLabeledCounters> {
//
const ui64 TabletID;
- const TTabletTypes::EType TabletType;
+ const TTabletTypes::EType TabletType;
TAutoPtr<TTabletLabeledCountersBase> LabeledCounters;
TIntrusivePtr<TInFlightCookie> InFlightCounter; // Used to detect when previous event has been consumed by the aggregator
- TEvTabletAddLabeledCounters(TIntrusivePtr<TInFlightCookie> inFlightCounter, ui64 tabletID, TTabletTypes::EType tabletType, TAutoPtr<TTabletLabeledCountersBase> labeledCounters)
+ TEvTabletAddLabeledCounters(TIntrusivePtr<TInFlightCookie> inFlightCounter, ui64 tabletID, TTabletTypes::EType tabletType, TAutoPtr<TTabletLabeledCountersBase> labeledCounters)
: TabletID(tabletID)
, TabletType(tabletType)
, LabeledCounters(labeledCounters)
@@ -80,7 +80,7 @@ struct TEvTabletCounters {
struct TEvTabletCountersForgetTablet : public TEventLocal<TEvTabletCountersForgetTablet, EvTabletCountersForgetTablet> {
//
const ui64 TabletID;
- const TTabletTypes::EType TabletType;
+ const TTabletTypes::EType TabletType;
const TPathId TenantPathId;
TEvTabletCountersForgetTablet(ui64 tabletID, TTabletTypes::EType tabletType, TPathId tenantPathId)
@@ -90,13 +90,13 @@ struct TEvTabletCounters {
{}
};
- //
- struct TEvTabletCountersRequest : public TEventPB<TEvTabletCountersRequest, NKikimrTabletCountersAggregator::TEvTabletCountersRequest, EvTabletCountersRequest> {
- };
-
- struct TEvTabletCountersResponse : public TEventPB<TEvTabletCountersResponse, NKikimrTabletCountersAggregator::TEvTabletCountersResponse, EvTabletCountersResponse> {
- };
-
+ //
+ struct TEvTabletCountersRequest : public TEventPB<TEvTabletCountersRequest, NKikimrTabletCountersAggregator::TEvTabletCountersRequest, EvTabletCountersRequest> {
+ };
+
+ struct TEvTabletCountersResponse : public TEventPB<TEvTabletCountersResponse, NKikimrTabletCountersAggregator::TEvTabletCountersResponse, EvTabletCountersResponse> {
+ };
+
//
struct TEvTabletLabeledCountersRequest : public TEventPB<TEvTabletLabeledCountersRequest, NKikimrTabletCountersAggregator::TEvTabletLabeledCountersRequest, EvTabletLabeledCountersRequest> {
};
@@ -117,8 +117,8 @@ struct TEvTabletCounters {
////////////////////////////////////////////
void TabletCountersForgetTablet(ui64 tabletId, TTabletTypes::EType tabletType, TPathId tenantPathId, bool follower, TActorIdentity identity);
-TStringBuf GetHistogramAggregateSimpleName(TStringBuf name);
-bool IsHistogramAggregateSimpleName(TStringBuf name);
+TStringBuf GetHistogramAggregateSimpleName(TStringBuf name);
+bool IsHistogramAggregateSimpleName(TStringBuf name);
////////////////////////////////////////////
TIntrusivePtr<NSysView::IDbCounters> CreateTabletDbCounters(
@@ -134,15 +134,15 @@ IActor* CreateTabletCountersAggregator(bool follower);
//will create actor that aggregate LabeledCounters from all nodes and reports them as TEvTabletLabeledCountersResponse to parentActor
TActorId CreateClusterLabeledCountersAggregator(
const TActorId& parentActor,
- TTabletTypes::EType tabletType,
- const TActorContext& ctx,
- ui32 version = 1,
+ TTabletTypes::EType tabletType,
+ const TActorContext& ctx,
+ ui32 version = 1,
const TString& group = TString(), const ui32 TotalWorkersCount = WORKERS_COUNT);
-IActor* CreateClusterLabeledCountersAggregatorActor(
+IActor* CreateClusterLabeledCountersAggregatorActor(
const TActorId& parentActor,
- TTabletTypes::EType tabletType,
- ui32 version = 1,
+ TTabletTypes::EType tabletType,
+ ui32 version = 1,
const TString& group = TString(), const ui32 TotalWorkersCount = WORKERS_COUNT);
} // end of the NKikimr namespace
diff --git a/ydb/core/tablet/tablet_counters_aggregator_ut.cpp b/ydb/core/tablet/tablet_counters_aggregator_ut.cpp
index 0ff9f9c56ac..707ffb977ee 100644
--- a/ydb/core/tablet/tablet_counters_aggregator_ut.cpp
+++ b/ydb/core/tablet/tablet_counters_aggregator_ut.cpp
@@ -2,14 +2,14 @@
#include <library/cpp/actors/core/interconnect.h>
#include <ydb/core/testlib/basics/runtime.h>
#include <ydb/core/testlib/basics/appdata.h>
-#include "tablet_counters_aggregator.h"
-
-namespace NKikimr {
-
-using namespace NActors;
-
+#include "tablet_counters_aggregator.h"
+
+namespace NKikimr {
+
+using namespace NActors;
+
void TestHeavy(const ui32 v, ui32 numWorkers) {
-
+
TInstant t(Now());
TVector<TActorId> cc;
@@ -91,20 +91,20 @@ Y_UNIT_TEST_SUITE(TTabletCountersAggregator) {
TActorId aggregatorId;
TTestBasicRuntime runtime(1);
-
+
runtime.Initialize(TAppPrepare().Unwrap());
TActorId edge = runtime.AllocateEdgeActor();
-
+
IActor* aggregator = CreateClusterLabeledCountersAggregatorActor(edge, TTabletTypes::PersQueue, 2, TString(), 3);
aggregatorId = runtime.Register(aggregator);
-
+
runtime.SetRegistrationObserverFunc([&cc, &aggregatorId](TTestActorRuntimeBase& runtime, const TActorId& parentId, const TActorId& actorId) {
TTestActorRuntime::DefaultRegistrationObserver(runtime, parentId, actorId);
if (parentId == aggregatorId) {
cc.push_back(actorId);
}
});
-
+
TDispatchOptions options;
options.FinalEvents.emplace_back(TEvents::TSystem::Bootstrap, 1);
runtime.DispatchEvents(options);
@@ -116,66 +116,66 @@ Y_UNIT_TEST_SUITE(TTabletCountersAggregator) {
runtime.Send(new NActors::IEventHandle(a, edge, nodesInfo.Release()), 0, true);
}
- {
+ {
THolder<TEvTabletCounters::TEvTabletLabeledCountersResponse> response = MakeHolder<TEvTabletCounters::TEvTabletLabeledCountersResponse>();
- auto& group1 = *response->Record.AddLabeledCountersByGroup();
+ auto& group1 = *response->Record.AddLabeledCountersByGroup();
group1.SetGroup("group1|group2");
group1.SetGroupNames("AAA|BBB");
group1.SetDelimiter("|");
- auto& counter1 = *group1.AddLabeledCounter();
- counter1.SetName("value1");
- counter1.SetValue(13);
- counter1.SetType(TLabeledCounterOptions::CT_SIMPLE);
- counter1.SetAggregateFunc(TLabeledCounterOptions::EAF_SUM);
+ auto& counter1 = *group1.AddLabeledCounter();
+ counter1.SetName("value1");
+ counter1.SetValue(13);
+ counter1.SetType(TLabeledCounterOptions::CT_SIMPLE);
+ counter1.SetAggregateFunc(TLabeledCounterOptions::EAF_SUM);
runtime.Send(new NActors::IEventHandle(cc[0], edge, response.Release(), 0, 1), 0, true);
- }
-
- {
+ }
+
+ {
THolder<TEvTabletCounters::TEvTabletLabeledCountersResponse> response = MakeHolder<TEvTabletCounters::TEvTabletLabeledCountersResponse>();
- response->Record.AddCounterNames("value1");
- auto& group1 = *response->Record.AddLabeledCountersByGroup();
+ response->Record.AddCounterNames("value1");
+ auto& group1 = *response->Record.AddLabeledCountersByGroup();
group1.SetGroup("group1|group2");
group1.SetGroupNames("AAA|BBB");
group1.SetDelimiter("|");
- auto& counter1 = *group1.AddLabeledCounter();
- counter1.SetNameId(0);
- counter1.SetValue(13);
- counter1.SetType(TLabeledCounterOptions::CT_SIMPLE);
- counter1.SetAggregateFunc(TLabeledCounterOptions::EAF_SUM);
+ auto& counter1 = *group1.AddLabeledCounter();
+ counter1.SetNameId(0);
+ counter1.SetValue(13);
+ counter1.SetType(TLabeledCounterOptions::CT_SIMPLE);
+ counter1.SetAggregateFunc(TLabeledCounterOptions::EAF_SUM);
runtime.Send(new NActors::IEventHandle(cc[1], edge, response.Release(), 0, 2), 0, true);
- }
-
- {
+ }
+
+ {
THolder<TEvTabletCounters::TEvTabletLabeledCountersResponse> response = MakeHolder<TEvTabletCounters::TEvTabletLabeledCountersResponse>();
- response->Record.AddCounterNames("value1");
- auto& group1 = *response->Record.AddLabeledCountersByGroup();
+ response->Record.AddCounterNames("value1");
+ auto& group1 = *response->Record.AddLabeledCountersByGroup();
group1.SetGroup("group1|group2");
group1.SetGroupNames("AAA|BBB");
group1.SetDelimiter("|");
- auto& counter1 = *group1.AddLabeledCounter();
- counter1.SetNameId(0);
- counter1.SetValue(13);
- counter1.SetType(TLabeledCounterOptions::CT_SIMPLE);
- counter1.SetAggregateFunc(TLabeledCounterOptions::EAF_SUM);
+ auto& counter1 = *group1.AddLabeledCounter();
+ counter1.SetNameId(0);
+ counter1.SetValue(13);
+ counter1.SetType(TLabeledCounterOptions::CT_SIMPLE);
+ counter1.SetAggregateFunc(TLabeledCounterOptions::EAF_SUM);
runtime.Send(new NActors::IEventHandle(cc[2], edge, response.Release(), 0, 3), 0, true);
- }
-
- runtime.DispatchEvents();
- THolder<TEvTabletCounters::TEvTabletLabeledCountersResponse> response = runtime.GrabEdgeEvent<TEvTabletCounters::TEvTabletLabeledCountersResponse>();
-#ifndef NDEBUG
- Cerr << response->Record.DebugString() << Endl;
-#endif
- UNIT_ASSERT(response != nullptr);
- UNIT_ASSERT_VALUES_EQUAL(response->Record.LabeledCountersByGroupSize(), 1);
- const auto& group1 = response->Record.GetLabeledCountersByGroup(0);
+ }
+
+ runtime.DispatchEvents();
+ THolder<TEvTabletCounters::TEvTabletLabeledCountersResponse> response = runtime.GrabEdgeEvent<TEvTabletCounters::TEvTabletLabeledCountersResponse>();
+#ifndef NDEBUG
+ Cerr << response->Record.DebugString() << Endl;
+#endif
+ UNIT_ASSERT(response != nullptr);
+ UNIT_ASSERT_VALUES_EQUAL(response->Record.LabeledCountersByGroupSize(), 1);
+ const auto& group1 = response->Record.GetLabeledCountersByGroup(0);
UNIT_ASSERT_VALUES_EQUAL(group1.GetGroup(), "group1/group2");
- UNIT_ASSERT_VALUES_EQUAL(group1.LabeledCounterSize(), 1);
- UNIT_ASSERT_VALUES_EQUAL(group1.LabeledCounterSize(), 1);
- const auto& counter1 = group1.GetLabeledCounter(0);
- UNIT_ASSERT_VALUES_EQUAL(counter1.GetNameId(), 0);
- UNIT_ASSERT_VALUES_EQUAL(counter1.GetValue(), 39);
- }
-
+ UNIT_ASSERT_VALUES_EQUAL(group1.LabeledCounterSize(), 1);
+ UNIT_ASSERT_VALUES_EQUAL(group1.LabeledCounterSize(), 1);
+ const auto& counter1 = group1.GetLabeledCounter(0);
+ UNIT_ASSERT_VALUES_EQUAL(counter1.GetNameId(), 0);
+ UNIT_ASSERT_VALUES_EQUAL(counter1.GetValue(), 39);
+ }
+
Y_UNIT_TEST(HeavyAggregation) {
TestHeavy(2, 10);
@@ -183,7 +183,7 @@ Y_UNIT_TEST_SUITE(TTabletCountersAggregator) {
TestHeavy(2, 1);
TestHeavy(2, 0);
}
-
+
Y_UNIT_TEST(Version3Aggregation) {
TVector<TActorId> cc;
TActorId aggregatorId;
@@ -260,6 +260,6 @@ Y_UNIT_TEST_SUITE(TTabletCountersAggregator) {
UNIT_ASSERT_VALUES_EQUAL(res[1], "cons/aaa|1|aba/caba/daba|man");
}
-}
-
-}
+}
+
+}
diff --git a/ydb/core/tablet/tablet_counters_protobuf.h b/ydb/core/tablet/tablet_counters_protobuf.h
index be40ad20212..11d3a334def 100644
--- a/ydb/core/tablet/tablet_counters_protobuf.h
+++ b/ydb/core/tablet/tablet_counters_protobuf.h
@@ -1,7 +1,7 @@
#pragma once
#include "tablet_counters.h"
-#include "tablet_counters_aggregator.h"
+#include "tablet_counters_aggregator.h"
#include <ydb/core/tablet_flat/defs.h>
#include <util/string/vector.h>
#include <util/string/split.h>
@@ -45,13 +45,13 @@ public:
TString cntName = co.GetName();
Y_VERIFY(!cntName.empty(), "counter '%s' number (%d) cannot have an empty counter name",
vdesc->full_name().c_str(), vdesc->number());
- TString nameString;
- if (IsHistogramAggregateSimpleName(cntName)) {
- nameString = co.GetName();
- } else {
- nameString = GetFilePrefix(appDesc->file()) + cntName;
- }
- NamesStrings.emplace_back(nameString);
+ TString nameString;
+ if (IsHistogramAggregateSimpleName(cntName)) {
+ nameString = co.GetName();
+ } else {
+ nameString = GetFilePrefix(appDesc->file()) + cntName;
+ }
+ NamesStrings.emplace_back(nameString);
Ranges.push_back(ParseRanges(co));
Integral.push_back(co.GetIntegral());
}
diff --git a/ydb/core/tablet/tablet_impl.h b/ydb/core/tablet/tablet_impl.h
index 14ca42ab0b6..b47b1f10971 100644
--- a/ydb/core/tablet/tablet_impl.h
+++ b/ydb/core/tablet/tablet_impl.h
@@ -25,7 +25,7 @@ struct TEvTabletBase {
EvRebuildGraphResult,
EvFindLatestLogEntryResult,
EvWriteLogResult,
- EvDeleteTabletResult,
+ EvDeleteTabletResult,
EvFollowerRetry = EvBlockBlobStorageResult + 512,
EvTrySyncFollower,
@@ -38,12 +38,12 @@ struct TEvTabletBase {
struct TEvBlockBlobStorageResult : public TEventLocal<TEvBlockBlobStorageResult, EvBlockBlobStorageResult> {
const NKikimrProto::EReplyStatus Status;
- const ui64 TabletId;
+ const ui64 TabletId;
const TString ErrorReason;
TEvBlockBlobStorageResult(NKikimrProto::EReplyStatus status, ui64 tabletId, const TString &reason = TString())
: Status(status)
- , TabletId(tabletId)
+ , TabletId(tabletId)
, ErrorReason(reason)
{}
};
@@ -53,7 +53,7 @@ struct TEvTabletBase {
const TString ErrorReason;
TIntrusivePtr<TEvTablet::TDependencyGraph> DependencyGraph;
- NMetrics::TTabletThroughputRawValue GroupReadBytes;
+ NMetrics::TTabletThroughputRawValue GroupReadBytes;
NMetrics::TTabletIopsRawValue GroupReadOps;
THolder<NTracing::ITrace> Trace;
@@ -75,7 +75,7 @@ struct TEvTabletBase {
)
: Status(NKikimrProto::OK)
, DependencyGraph(graph)
- , GroupReadBytes(std::move(read))
+ , GroupReadBytes(std::move(read))
, GroupReadOps(std::move(readOps))
, Trace(trace)
{}
@@ -109,7 +109,7 @@ struct TEvTabletBase {
const TLogoBlobID EntryId;
TVector<ui32> YellowMoveChannels;
TVector<ui32> YellowStopChannels;
- NMetrics::TTabletThroughputRawValue GroupWrittenBytes;
+ NMetrics::TTabletThroughputRawValue GroupWrittenBytes;
NMetrics::TTabletIopsRawValue GroupWrittenOps;
const TString ErrorReason;
@@ -129,7 +129,7 @@ struct TEvTabletBase {
, EntryId(entryId)
, YellowMoveChannels(std::move(yellowMoveChannels))
, YellowStopChannels(std::move(yellowStopChannels))
- , GroupWrittenBytes(std::move(written))
+ , GroupWrittenBytes(std::move(written))
, GroupWrittenOps(std::move(writtenOps))
, ErrorReason(reason)
{}
@@ -142,7 +142,7 @@ struct TEvTabletBase {
: Round(round)
{}
};
-
+
struct TEvTrySyncFollower : public TEventLocal<TEvTrySyncFollower, EvTrySyncFollower> {
const TActorId FollowerId;
TSchedulerCookieHolder CookieHolder;
@@ -155,15 +155,15 @@ struct TEvTabletBase {
struct TEvTryBuildFollowerGraph : public TEventLocal<TEvTryBuildFollowerGraph, EvTryBuildFollowerGraph> {};
- struct TEvDeleteTabletResult : public TEventLocal<TEvDeleteTabletResult, EvDeleteTabletResult> {
- const NKikimrProto::EReplyStatus Status;
- const ui64 TabletId;
-
- TEvDeleteTabletResult(NKikimrProto::EReplyStatus status, ui64 tabletId)
- : Status(status)
- , TabletId(tabletId)
- {}
- };
+ struct TEvDeleteTabletResult : public TEventLocal<TEvDeleteTabletResult, EvDeleteTabletResult> {
+ const NKikimrProto::EReplyStatus Status;
+ const ui64 TabletId;
+
+ TEvDeleteTabletResult(NKikimrProto::EReplyStatus status, ui64 tabletId)
+ : Status(status)
+ , TabletId(tabletId)
+ {}
+ };
};
}
diff --git a/ydb/core/tablet/tablet_list_renderer.cpp b/ydb/core/tablet/tablet_list_renderer.cpp
index 7f8b6e2a3db..ad36f12a291 100644
--- a/ydb/core/tablet/tablet_list_renderer.cpp
+++ b/ydb/core/tablet/tablet_list_renderer.cpp
@@ -14,7 +14,7 @@ namespace NNodeTabletMonitor {
bool TTabletStateClassifier::IsActiveTablet(const NKikimrWhiteboard::TTabletStateInfo& state)
{
- return state.GetState() != NKikimrWhiteboard::TTabletStateInfo::Dead;
+ return state.GetState() != NKikimrWhiteboard::TTabletStateInfo::Dead;
}
bool TTabletStateClassifier::IsDeadTablet(const NKikimrWhiteboard::TTabletStateInfo& state)
@@ -163,7 +163,7 @@ void TTabletListRenderer::RenderTableBody(TStringStream& str,
}
TString TTabletListRenderer::GetStateName(ETabletState state) {
- return NKikimrWhiteboard::TTabletStateInfo::ETabletState_Name(state);
+ return NKikimrWhiteboard::TTabletStateInfo::ETabletState_Name(state);
}
void TTabletListRenderer::RenderPageHeader(TStringStream& str)
diff --git a/ydb/core/tablet/tablet_list_renderer.h b/ydb/core/tablet/tablet_list_renderer.h
index 92c71aa210f..41de78016f5 100644
--- a/ydb/core/tablet/tablet_list_renderer.h
+++ b/ydb/core/tablet/tablet_list_renderer.h
@@ -27,7 +27,7 @@ public:
class TTabletListRenderer : public ITabletListRenderer {
protected:
- using ETabletState = NKikimrWhiteboard::TTabletStateInfo::ETabletState;
+ using ETabletState = NKikimrWhiteboard::TTabletStateInfo::ETabletState;
static TString GetStateName(ETabletState state);
virtual TString MakeTabletMonURL(const TTabletListElement& elem,
diff --git a/ydb/core/tablet/tablet_metrics.cpp b/ydb/core/tablet/tablet_metrics.cpp
index 06d795409cc..182c7c566e4 100644
--- a/ydb/core/tablet/tablet_metrics.cpp
+++ b/ydb/core/tablet/tablet_metrics.cpp
@@ -1,9 +1,9 @@
#include <ydb/core/mind/local.h>
-#include "tablet_metrics.h"
-
-namespace NKikimr {
-namespace NMetrics {
-
+#include "tablet_metrics.h"
+
+namespace NKikimr {
+namespace NMetrics {
+
void TDecayingAverageWithSum::Increment(std::make_signed_t<ui64> value, TInstant now)
{
RawValue += value;
@@ -16,46 +16,46 @@ ui64 TDecayingAverageWithSum::GetRawValue() const
}
void TResourceMetricsValues::Fill(NKikimrTabletBase::TMetrics& metrics) const {
- if (CPU.IsValueReady()) {
- metrics.SetCPU(CPU.GetValue());
- }
- if (Memory.IsValueReady()) {
- metrics.SetMemory(Memory.GetValue());
- }
- if (Network.IsValueReady()) {
- metrics.SetNetwork(Network.GetValue());
- }
- if (StorageSystem.IsValueReady() || StorageUser.IsValueReady()) {
- metrics.SetStorage(StorageSystem.GetValue() + StorageUser.GetValue());
- }
- {
- metrics.ClearGroupReadThroughput();
- for (auto it = ReadThroughput.begin(); it != ReadThroughput.end(); ++it) {
- auto groupId(it->first);
- const auto& value(it->second);
- if (value.IsValueReady()) {
- auto val = value.GetValue();
- auto& throughput= *metrics.AddGroupReadThroughput();
- throughput.SetChannel(groupId.first);
- throughput.SetGroupID(groupId.second);
- throughput.SetThroughput(val);
- }
- }
- }
- {
- metrics.ClearGroupWriteThroughput();
- for (auto it = WriteThroughput.begin(); it != WriteThroughput.end(); ++it) {
- auto groupId(it->first);
- const auto& value(it->second);
- if (value.IsValueReady()) {
- auto val = value.GetValue();
- auto& throughput= *metrics.AddGroupWriteThroughput();
- throughput.SetChannel(groupId.first);
- throughput.SetGroupID(groupId.second);
- throughput.SetThroughput(val);
- }
- }
- }
+ if (CPU.IsValueReady()) {
+ metrics.SetCPU(CPU.GetValue());
+ }
+ if (Memory.IsValueReady()) {
+ metrics.SetMemory(Memory.GetValue());
+ }
+ if (Network.IsValueReady()) {
+ metrics.SetNetwork(Network.GetValue());
+ }
+ if (StorageSystem.IsValueReady() || StorageUser.IsValueReady()) {
+ metrics.SetStorage(StorageSystem.GetValue() + StorageUser.GetValue());
+ }
+ {
+ metrics.ClearGroupReadThroughput();
+ for (auto it = ReadThroughput.begin(); it != ReadThroughput.end(); ++it) {
+ auto groupId(it->first);
+ const auto& value(it->second);
+ if (value.IsValueReady()) {
+ auto val = value.GetValue();
+ auto& throughput= *metrics.AddGroupReadThroughput();
+ throughput.SetChannel(groupId.first);
+ throughput.SetGroupID(groupId.second);
+ throughput.SetThroughput(val);
+ }
+ }
+ }
+ {
+ metrics.ClearGroupWriteThroughput();
+ for (auto it = WriteThroughput.begin(); it != WriteThroughput.end(); ++it) {
+ auto groupId(it->first);
+ const auto& value(it->second);
+ if (value.IsValueReady()) {
+ auto val = value.GetValue();
+ auto& throughput= *metrics.AddGroupWriteThroughput();
+ throughput.SetChannel(groupId.first);
+ throughput.SetGroupID(groupId.second);
+ throughput.SetThroughput(val);
+ }
+ }
+ }
{
metrics.ClearGroupReadIops();
for (const auto& kv : ReadIops) {
@@ -82,14 +82,14 @@ void TResourceMetricsValues::Fill(NKikimrTabletBase::TMetrics& metrics) const {
}
}
}
-}
-
+}
+
TResourceMetricsSendState::TResourceMetricsSendState(ui64 tabletId, ui32 followerId, const TActorId& launcher)
- : TabletId(tabletId)
+ : TabletId(tabletId)
, FollowerId(followerId)
- , Launcher(launcher)
-{}
-
+ , Launcher(launcher)
+{}
+
namespace {
template<class TGroupValues, class TGroupLevels, class TCallback>
bool ProcessChangedGroupMetrics(
@@ -135,77 +135,77 @@ namespace {
}
}
-bool TResourceMetricsSendState::FillChanged(TResourceMetricsValues& src, NKikimrTabletBase::TMetrics& metrics, TInstant now, bool force) {
- bool have = false;
-
- if (src.CPU.IsValueReady()) {
- auto cpu = !src.CPU.IsValueObsolete(now) ? src.CPU.GetValue() : 0;
- ui32 levelCPU = cpu / SignificantChangeCPU;
- if (levelCPU != LevelCPU || force) {
- metrics.SetCPU(cpu);
- LevelCPU = levelCPU;
- have = true;
- }
- } else if (force && src.CPU.IsValueObsolete(now)) {
- src.CPU.Set(0, now);
- metrics.SetCPU(0);
- have = true;
- }
-
- if (src.Memory.IsValueReady()) {
- auto memory = !src.Memory.IsValueObsolete(now) ? src.Memory.GetValue() : 0;
- ui32 levelMemory = memory / SignificantChangeMemory;
- if (levelMemory != LevelMemory || force) {
- metrics.SetMemory(memory);
- LevelMemory = levelMemory;
- have = true;
- }
- } else if (force && src.Memory.IsValueObsolete(now)) {
- src.Memory.Set(0);
- metrics.SetMemory(0);
- have = true;
- }
-
- if (src.Network.IsValueReady()) {
- auto network = !src.Network.IsValueObsolete(now) ? src.Network.GetValue() : 0;
- ui32 levelNetwork = network / SignificantChangeNetwork;
- if (levelNetwork != LevelNetwork || force) {
- metrics.SetNetwork(network);
- LevelNetwork = levelNetwork;
- have = true;
- }
- } else if (force && src.Network.IsValueObsolete(now)) {
- src.Network.Set(0, now);
- metrics.SetNetwork(0);
- have = true;
- }
-
- if (src.StorageSystem.IsValueReady() || src.StorageUser.IsValueReady()) {
- auto storageSystem = (src.StorageSystem.IsValueReady() && !src.StorageSystem.IsValueObsolete(now)) ? src.StorageSystem.GetValue() : 0;
- auto storageUser = (src.StorageUser.IsValueReady() && !src.StorageUser.IsValueObsolete(now)) ? src.StorageUser.GetValue() : 0;
- auto storage = storageSystem + storageUser;
- ui32 levelStorage = storage / SignificantChangeStorage;
- if (levelStorage != LevelStorage || force) {
- metrics.SetStorage(storage);
- LevelStorage = levelStorage;
- have = true;
- }
- } else if (force) {
- if (src.StorageSystem.IsValueObsolete(now)) {
- src.StorageSystem.Set(0);
- }
- if (src.StorageUser.IsValueObsolete(now)) {
- src.StorageUser.Set(0);
- }
- auto storageSystem = (src.StorageSystem.IsValueReady() && !src.StorageSystem.IsValueObsolete(now)) ? src.StorageSystem.GetValue() : 0;
- auto storageUser = (src.StorageUser.IsValueReady() && !src.StorageUser.IsValueObsolete(now)) ? src.StorageUser.GetValue() : 0;
- auto storage = storageSystem + storageUser;
- ui32 levelStorage = storage / SignificantChangeStorage;
- metrics.SetStorage(storage);
- LevelStorage = levelStorage;
- have = true;
- }
-
+bool TResourceMetricsSendState::FillChanged(TResourceMetricsValues& src, NKikimrTabletBase::TMetrics& metrics, TInstant now, bool force) {
+ bool have = false;
+
+ if (src.CPU.IsValueReady()) {
+ auto cpu = !src.CPU.IsValueObsolete(now) ? src.CPU.GetValue() : 0;
+ ui32 levelCPU = cpu / SignificantChangeCPU;
+ if (levelCPU != LevelCPU || force) {
+ metrics.SetCPU(cpu);
+ LevelCPU = levelCPU;
+ have = true;
+ }
+ } else if (force && src.CPU.IsValueObsolete(now)) {
+ src.CPU.Set(0, now);
+ metrics.SetCPU(0);
+ have = true;
+ }
+
+ if (src.Memory.IsValueReady()) {
+ auto memory = !src.Memory.IsValueObsolete(now) ? src.Memory.GetValue() : 0;
+ ui32 levelMemory = memory / SignificantChangeMemory;
+ if (levelMemory != LevelMemory || force) {
+ metrics.SetMemory(memory);
+ LevelMemory = levelMemory;
+ have = true;
+ }
+ } else if (force && src.Memory.IsValueObsolete(now)) {
+ src.Memory.Set(0);
+ metrics.SetMemory(0);
+ have = true;
+ }
+
+ if (src.Network.IsValueReady()) {
+ auto network = !src.Network.IsValueObsolete(now) ? src.Network.GetValue() : 0;
+ ui32 levelNetwork = network / SignificantChangeNetwork;
+ if (levelNetwork != LevelNetwork || force) {
+ metrics.SetNetwork(network);
+ LevelNetwork = levelNetwork;
+ have = true;
+ }
+ } else if (force && src.Network.IsValueObsolete(now)) {
+ src.Network.Set(0, now);
+ metrics.SetNetwork(0);
+ have = true;
+ }
+
+ if (src.StorageSystem.IsValueReady() || src.StorageUser.IsValueReady()) {
+ auto storageSystem = (src.StorageSystem.IsValueReady() && !src.StorageSystem.IsValueObsolete(now)) ? src.StorageSystem.GetValue() : 0;
+ auto storageUser = (src.StorageUser.IsValueReady() && !src.StorageUser.IsValueObsolete(now)) ? src.StorageUser.GetValue() : 0;
+ auto storage = storageSystem + storageUser;
+ ui32 levelStorage = storage / SignificantChangeStorage;
+ if (levelStorage != LevelStorage || force) {
+ metrics.SetStorage(storage);
+ LevelStorage = levelStorage;
+ have = true;
+ }
+ } else if (force) {
+ if (src.StorageSystem.IsValueObsolete(now)) {
+ src.StorageSystem.Set(0);
+ }
+ if (src.StorageUser.IsValueObsolete(now)) {
+ src.StorageUser.Set(0);
+ }
+ auto storageSystem = (src.StorageSystem.IsValueReady() && !src.StorageSystem.IsValueObsolete(now)) ? src.StorageSystem.GetValue() : 0;
+ auto storageUser = (src.StorageUser.IsValueReady() && !src.StorageUser.IsValueObsolete(now)) ? src.StorageUser.GetValue() : 0;
+ auto storage = storageSystem + storageUser;
+ ui32 levelStorage = storage / SignificantChangeStorage;
+ metrics.SetStorage(storage);
+ LevelStorage = levelStorage;
+ have = true;
+ }
+
have |= ProcessChangedGroupMetrics(
src.ReadThroughput,
LevelReadThroughput,
@@ -258,63 +258,63 @@ bool TResourceMetricsSendState::FillChanged(TResourceMetricsValues& src, NKikimr
iops.SetIops(value);
});
- return have;
-}
-
-bool TResourceMetricsSendState::TryUpdate(TResourceMetricsValues& src, const TActorContext& ctx) {
- TInstant now = ctx.Now();
- TDuration past = now - LastUpdate;
- if (past < TDuration::Seconds(1)) {
- return false; // too soon
- }
- NKikimrTabletBase::TMetrics values;
- bool updated = FillChanged(src, values, now, past > TDuration::Seconds(60));
- if (updated) {
+ return have;
+}
+
+bool TResourceMetricsSendState::TryUpdate(TResourceMetricsValues& src, const TActorContext& ctx) {
+ TInstant now = ctx.Now();
+ TDuration past = now - LastUpdate;
+ if (past < TDuration::Seconds(1)) {
+ return false; // too soon
+ }
+ NKikimrTabletBase::TMetrics values;
+ bool updated = FillChanged(src, values, now, past > TDuration::Seconds(60));
+ if (updated) {
ctx.Send(Launcher, new TEvLocal::TEvTabletMetrics(TabletId, FollowerId, values));
- LastUpdate = now;
- }
- return updated;
-}
-
-template <typename ValueType>
-static TString FormatValue(ValueType val);
-
-template <>
-TString FormatValue(ui64 val) {
- TString result = Sprintf("%lu", val);
- auto cnt = 0;
- for (auto i = result.size() - 1; i != 0; --i) {
- if (++cnt == 3) {
- cnt = 0;
- result.insert(i, " ");
- }
- }
- return result;
-}
-
-template <typename MetricType>
-static void RenderMetric(IOutputStream& str, TStringBuf name, const MetricType& metric) {
- str << "<tr><td>" << name << "</td><td>" << FormatValue(metric.GetValue()) << "</td><td>";
- if (!metric.IsValueReady()) {
- str << "(not ready)";
- }
- if (metric.IsValueObsolete()) {
- str << "(obsolete)";
- }
- str << "</td></tr>";
-}
-
-IOutputStream& operator <<(IOutputStream& str, const TRendererHtml<TResourceMetrics>& met) {
- str << "<h3>Executor Metrics</h3>";
- str << "<table class='metrics'>";
- RenderMetric(str, "CPU", met.Metrics.CPU);
- RenderMetric(str, "Memory", met.Metrics.Memory);
- RenderMetric(str, "Network", met.Metrics.Network);
- RenderMetric(str, "System Storage", met.Metrics.StorageSystem);
- RenderMetric(str, "User Storage", met.Metrics.StorageUser);
- str << "</table>";
- return str;
-}
-
-}
-}
+ LastUpdate = now;
+ }
+ return updated;
+}
+
+template <typename ValueType>
+static TString FormatValue(ValueType val);
+
+template <>
+TString FormatValue(ui64 val) {
+ TString result = Sprintf("%lu", val);
+ auto cnt = 0;
+ for (auto i = result.size() - 1; i != 0; --i) {
+ if (++cnt == 3) {
+ cnt = 0;
+ result.insert(i, " ");
+ }
+ }
+ return result;
+}
+
+template <typename MetricType>
+static void RenderMetric(IOutputStream& str, TStringBuf name, const MetricType& metric) {
+ str << "<tr><td>" << name << "</td><td>" << FormatValue(metric.GetValue()) << "</td><td>";
+ if (!metric.IsValueReady()) {
+ str << "(not ready)";
+ }
+ if (metric.IsValueObsolete()) {
+ str << "(obsolete)";
+ }
+ str << "</td></tr>";
+}
+
+IOutputStream& operator <<(IOutputStream& str, const TRendererHtml<TResourceMetrics>& met) {
+ str << "<h3>Executor Metrics</h3>";
+ str << "<table class='metrics'>";
+ RenderMetric(str, "CPU", met.Metrics.CPU);
+ RenderMetric(str, "Memory", met.Metrics.Memory);
+ RenderMetric(str, "Network", met.Metrics.Network);
+ RenderMetric(str, "System Storage", met.Metrics.StorageSystem);
+ RenderMetric(str, "User Storage", met.Metrics.StorageUser);
+ str << "</table>";
+ return str;
+}
+
+}
+}
diff --git a/ydb/core/tablet/tablet_metrics.h b/ydb/core/tablet/tablet_metrics.h
index 798c49d1aa7..b426284d33f 100644
--- a/ydb/core/tablet/tablet_metrics.h
+++ b/ydb/core/tablet/tablet_metrics.h
@@ -1,20 +1,20 @@
-#pragma once
-#include <unordered_map>
+#pragma once
+#include <unordered_map>
#include <ydb/core/base/defs.h>
#include <ydb/core/util/tuples.h>
#include <ydb/core/util/metrics.h>
#include <ydb/core/protos/tablet.pb.h>
-
-namespace NKikimr {
-namespace NMetrics {
-
-enum EResource { // DO NOT REORDER, DO NOT REMOVE ITEMS
- CPU, // the same as COUNTER_TT_EXECUTE_CPUTIME + COUNTER_TT_BOOKKEEPING_CPUTIME
- Memory, // the same as COUNTER_RECORD_BYTES for KV tablet
- Network, // Cumulative network bandwidth, used by a tablet
- Counter, // ALWAYS 1
-};
-
+
+namespace NKikimr {
+namespace NMetrics {
+
+enum EResource { // DO NOT REORDER, DO NOT REMOVE ITEMS
+ CPU, // the same as COUNTER_TT_EXECUTE_CPUTIME + COUNTER_TT_BOOKKEEPING_CPUTIME
+ Memory, // the same as COUNTER_RECORD_BYTES for KV tablet
+ Network, // Cumulative network bandwidth, used by a tablet
+ Counter, // ALWAYS 1
+};
+
class TDecayingAverageWithSum
: public TDecayingAverageValue<ui64, DurationPerMinute, DurationPerSecond>
{
@@ -26,91 +26,91 @@ private:
ui64 RawValue = 0;
};
-using TChannel = ui8;
-using TGroupId = ui32;
+using TChannel = ui8;
+using TGroupId = ui32;
using TGroupThroughputValue = TDecayingAverageWithSum;
-using TTabletThroughputValue = std::unordered_map<std::pair<TChannel, TGroupId>, TGroupThroughputValue>;
-using TTabletThroughputRawValue = std::unordered_map<std::pair<TChannel, TGroupId>, ui64>; // TStackYHash ?
+using TTabletThroughputValue = std::unordered_map<std::pair<TChannel, TGroupId>, TGroupThroughputValue>;
+using TTabletThroughputRawValue = std::unordered_map<std::pair<TChannel, TGroupId>, ui64>; // TStackYHash ?
using TGroupIopsValue = TDecayingAverageWithSum;
using TTabletIopsValue = std::unordered_map<std::pair<TChannel, TGroupId>, TGroupIopsValue>;
using TTabletIopsRawValue = std::unordered_map<std::pair<TChannel, TGroupId>, ui64>;
-
-constexpr TTimeBase<TInstant>::TValue DurationPer15Seconds = DurationPerSecond * 15;
-
-class TResourceMetricsValues {
-public:
- TDecayingAverageValue<ui64, DurationPer15Seconds, DurationPerSecond> CPU;
- TGaugeValue<ui64> Memory;
- TDecayingAverageValue<ui64, DurationPer15Seconds, DurationPerSecond> Network;
- TGaugeValue<ui64> StorageSystem;
- TGaugeValue<ui64> StorageUser;
- TTabletThroughputValue ReadThroughput;
- TTabletThroughputValue WriteThroughput;
+
+constexpr TTimeBase<TInstant>::TValue DurationPer15Seconds = DurationPerSecond * 15;
+
+class TResourceMetricsValues {
+public:
+ TDecayingAverageValue<ui64, DurationPer15Seconds, DurationPerSecond> CPU;
+ TGaugeValue<ui64> Memory;
+ TDecayingAverageValue<ui64, DurationPer15Seconds, DurationPerSecond> Network;
+ TGaugeValue<ui64> StorageSystem;
+ TGaugeValue<ui64> StorageUser;
+ TTabletThroughputValue ReadThroughput;
+ TTabletThroughputValue WriteThroughput;
TTabletIopsValue ReadIops;
TTabletIopsValue WriteIops;
-
+
void Fill(NKikimrTabletBase::TMetrics& metrics) const;
-};
-
-class TResourceMetricsSendState {
-public:
+};
+
+class TResourceMetricsSendState {
+public:
TResourceMetricsSendState(ui64 tabletId, ui32 followerId, const TActorId& launcher);
- bool FillChanged(TResourceMetricsValues& src, NKikimrTabletBase::TMetrics& metrics, TInstant now = TInstant::Now(), bool forceAll = false);
- bool TryUpdate(TResourceMetricsValues& src, const TActorContext& ctx);
-
-protected:
- static constexpr ui64 SignificantChangeCPU = 100000/* 100msec */;
- static constexpr ui64 SignificantChangeMemory = 1 << 20/* 1Mb */;
- static constexpr ui64 SignificantChangeNetwork = 1 << 20/* 1Mb */;
- static constexpr ui64 SignificantChangeThroughput = 1 << 20/* 1Mb */;
- static constexpr ui64 SignificantChangeStorage = 100 << 20/* 100Mb */;
+ bool FillChanged(TResourceMetricsValues& src, NKikimrTabletBase::TMetrics& metrics, TInstant now = TInstant::Now(), bool forceAll = false);
+ bool TryUpdate(TResourceMetricsValues& src, const TActorContext& ctx);
+
+protected:
+ static constexpr ui64 SignificantChangeCPU = 100000/* 100msec */;
+ static constexpr ui64 SignificantChangeMemory = 1 << 20/* 1Mb */;
+ static constexpr ui64 SignificantChangeNetwork = 1 << 20/* 1Mb */;
+ static constexpr ui64 SignificantChangeThroughput = 1 << 20/* 1Mb */;
+ static constexpr ui64 SignificantChangeStorage = 100 << 20/* 100Mb */;
static constexpr ui64 SignificantChangeIops = 10 /* 10 iops? */;
-
- const ui64 TabletId;
+
+ const ui64 TabletId;
const ui32 FollowerId;
const TActorId Launcher;
- ui32 LevelCPU = 0;
- ui32 LevelMemory = 0;
- ui32 LevelNetwork = 0;
- ui32 LevelStorage = 0;
+ ui32 LevelCPU = 0;
+ ui32 LevelMemory = 0;
+ ui32 LevelNetwork = 0;
+ ui32 LevelStorage = 0;
ui32 LevelIops = 0;
THashMap<std::pair<TChannel, TGroupId>, ui32> LevelReadThroughput;
THashMap<std::pair<TChannel, TGroupId>, ui32> LevelWriteThroughput;
THashMap<std::pair<TChannel, TGroupId>, ui32> LevelReadIops;
THashMap<std::pair<TChannel, TGroupId>, ui32> LevelWriteIops;
- TInstant LastUpdate;
-};
-
-class TResourceMetrics : public TResourceMetricsValues, public TResourceMetricsSendState {
-public:
+ TInstant LastUpdate;
+};
+
+class TResourceMetrics : public TResourceMetricsValues, public TResourceMetricsSendState {
+public:
TResourceMetrics(ui64 tabletId, ui32 followerId, const TActorId& launcher)
: TResourceMetricsSendState(tabletId, followerId, launcher) {}
-
- bool FillChanged(NKikimrTabletBase::TMetrics& metrics, TInstant now = TInstant::Now(), bool forceAll = false) {
- return TResourceMetricsSendState::FillChanged(*this, metrics, now, forceAll);
- }
-
- bool TryUpdate(const TActorContext& ctx) {
- return TResourceMetricsSendState::TryUpdate(*this, ctx);
- }
-};
-
-template <typename>
-struct TRendererHtml {};
-
-template <>
-struct TRendererHtml<TResourceMetrics> {
- const TResourceMetrics& Metrics;
- TRendererHtml(const TResourceMetrics& metrics)
- : Metrics(metrics)
- {}
- friend IOutputStream& operator <<(IOutputStream& str, const TRendererHtml<TResourceMetrics>& metrics);
-};
-
-template <typename Type>
-TRendererHtml<Type> AsHTML(const Type& object) {
- return TRendererHtml<Type>(object);
-}
-
-} // NMetrics
-} // NKikimr
+
+ bool FillChanged(NKikimrTabletBase::TMetrics& metrics, TInstant now = TInstant::Now(), bool forceAll = false) {
+ return TResourceMetricsSendState::FillChanged(*this, metrics, now, forceAll);
+ }
+
+ bool TryUpdate(const TActorContext& ctx) {
+ return TResourceMetricsSendState::TryUpdate(*this, ctx);
+ }
+};
+
+template <typename>
+struct TRendererHtml {};
+
+template <>
+struct TRendererHtml<TResourceMetrics> {
+ const TResourceMetrics& Metrics;
+ TRendererHtml(const TResourceMetrics& metrics)
+ : Metrics(metrics)
+ {}
+ friend IOutputStream& operator <<(IOutputStream& str, const TRendererHtml<TResourceMetrics>& metrics);
+};
+
+template <typename Type>
+TRendererHtml<Type> AsHTML(const Type& object) {
+ return TRendererHtml<Type>(object);
+}
+
+} // NMetrics
+} // NKikimr
diff --git a/ydb/core/tablet/tablet_metrics_ut.cpp b/ydb/core/tablet/tablet_metrics_ut.cpp
index 519191f2865..57cab15a5d6 100644
--- a/ydb/core/tablet/tablet_metrics_ut.cpp
+++ b/ydb/core/tablet/tablet_metrics_ut.cpp
@@ -1,373 +1,373 @@
#include <library/cpp/testing/unittest/registar.h>
#include <ydb/core/tablet_flat/flat_database.h>
-#include "tablet_metrics.h"
-
-namespace NKikimr {
-namespace NMetrics {
-
+#include "tablet_metrics.h"
+
+namespace NKikimr {
+namespace NMetrics {
+
Y_UNIT_TEST_SUITE(TFlatMetrics) {
Y_UNIT_TEST(TimeSeriesAvg4) {
- TTimeSeriesValue<ui64, TDuration::Minutes(1).GetValue(), 4> value;
- TInstant time = TInstant::Now();
-
- value.Increment(14, time);
- time += TDuration::Seconds(15);
- value.Increment(16, time);
- time += TDuration::Seconds(15);
- value.Increment(13, time);
- time += TDuration::Seconds(15);
- value.Increment(17, time);
- time += TDuration::Seconds(15);
-
- value.Increment(14, time);
- time += TDuration::Seconds(15);
- value.Increment(16, time);
- time += TDuration::Seconds(15);
- value.Increment(13, time);
- time += TDuration::Seconds(15);
- value.Increment(17, time);
- time += TDuration::Seconds(15);
-
- auto avg = value.GetValueAveragePerDuration(TDuration::Minutes(1));
- UNIT_ASSERT_C(avg >= 60 && avg <= 80, avg);
- }
-
+ TTimeSeriesValue<ui64, TDuration::Minutes(1).GetValue(), 4> value;
+ TInstant time = TInstant::Now();
+
+ value.Increment(14, time);
+ time += TDuration::Seconds(15);
+ value.Increment(16, time);
+ time += TDuration::Seconds(15);
+ value.Increment(13, time);
+ time += TDuration::Seconds(15);
+ value.Increment(17, time);
+ time += TDuration::Seconds(15);
+
+ value.Increment(14, time);
+ time += TDuration::Seconds(15);
+ value.Increment(16, time);
+ time += TDuration::Seconds(15);
+ value.Increment(13, time);
+ time += TDuration::Seconds(15);
+ value.Increment(17, time);
+ time += TDuration::Seconds(15);
+
+ auto avg = value.GetValueAveragePerDuration(TDuration::Minutes(1));
+ UNIT_ASSERT_C(avg >= 60 && avg <= 80, avg);
+ }
+
Y_UNIT_TEST(TimeSeriesAvg16) {
- TTimeSeriesValue<ui64, TDuration::Minutes(1).GetValue(), 16> value;
- TInstant time = TInstant::Now();
-
- value.Increment(14, time);
- time += TDuration::Seconds(15);
- value.Increment(16, time);
- time += TDuration::Seconds(15);
- value.Increment(13, time);
- time += TDuration::Seconds(15);
- value.Increment(17, time);
- time += TDuration::Seconds(15);
-
- value.Increment(14, time);
- time += TDuration::Seconds(15);
- value.Increment(16, time);
- time += TDuration::Seconds(15);
- value.Increment(13, time);
- time += TDuration::Seconds(15);
- value.Increment(17, time);
- time += TDuration::Seconds(15);
-
- auto avg = value.GetValueAveragePerDuration(TDuration::Minutes(1));
- UNIT_ASSERT_C(avg >= 60 && avg <= 65, avg);
- }
-
+ TTimeSeriesValue<ui64, TDuration::Minutes(1).GetValue(), 16> value;
+ TInstant time = TInstant::Now();
+
+ value.Increment(14, time);
+ time += TDuration::Seconds(15);
+ value.Increment(16, time);
+ time += TDuration::Seconds(15);
+ value.Increment(13, time);
+ time += TDuration::Seconds(15);
+ value.Increment(17, time);
+ time += TDuration::Seconds(15);
+
+ value.Increment(14, time);
+ time += TDuration::Seconds(15);
+ value.Increment(16, time);
+ time += TDuration::Seconds(15);
+ value.Increment(13, time);
+ time += TDuration::Seconds(15);
+ value.Increment(17, time);
+ time += TDuration::Seconds(15);
+
+ auto avg = value.GetValueAveragePerDuration(TDuration::Minutes(1));
+ UNIT_ASSERT_C(avg >= 60 && avg <= 65, avg);
+ }
+
Y_UNIT_TEST(TimeSeriesAvg16x60) {
- TTimeSeriesValue<ui64, TDuration::Minutes(1).GetValue(), 16> value;
- TInstant time = TInstant::Now();
-
- for (int i = 0; i < 60; ++i) {
- value.Increment(1, time);
- time += TDuration::Seconds(1);
- }
- auto avg = value.GetValueAveragePerDuration(TDuration::Minutes(1));
- UNIT_ASSERT_C(avg >= 55 && avg <= 65, avg);
- }
-
+ TTimeSeriesValue<ui64, TDuration::Minutes(1).GetValue(), 16> value;
+ TInstant time = TInstant::Now();
+
+ for (int i = 0; i < 60; ++i) {
+ value.Increment(1, time);
+ time += TDuration::Seconds(1);
+ }
+ auto avg = value.GetValueAveragePerDuration(TDuration::Minutes(1));
+ UNIT_ASSERT_C(avg >= 55 && avg <= 65, avg);
+ }
+
Y_UNIT_TEST(TimeSeriesAvg16Signed) {
- TTimeSeriesValue<i64, TDuration::Minutes(1).GetValue(), 16> value;
- TInstant time = TInstant::Now();
-
- value.Increment(+14, time);
- time += TDuration::Seconds(15);
- value.Increment(-16, time);
- time += TDuration::Seconds(15);
- value.Increment(+13, time);
- time += TDuration::Seconds(15);
- value.Increment(-17, time);
- time += TDuration::Seconds(15);
-
- value.Increment(-14, time);
- time += TDuration::Seconds(15);
- value.Increment(+16, time);
- time += TDuration::Seconds(15);
- value.Increment(-13, time);
- time += TDuration::Seconds(15);
- value.Increment(+17, time);
- time += TDuration::Seconds(15);
-
- auto avg = value.GetValueAveragePerDuration(TDuration::Minutes(1));
- UNIT_ASSERT_C(avg >= 0 && avg <= 15, avg);
- }
-
+ TTimeSeriesValue<i64, TDuration::Minutes(1).GetValue(), 16> value;
+ TInstant time = TInstant::Now();
+
+ value.Increment(+14, time);
+ time += TDuration::Seconds(15);
+ value.Increment(-16, time);
+ time += TDuration::Seconds(15);
+ value.Increment(+13, time);
+ time += TDuration::Seconds(15);
+ value.Increment(-17, time);
+ time += TDuration::Seconds(15);
+
+ value.Increment(-14, time);
+ time += TDuration::Seconds(15);
+ value.Increment(+16, time);
+ time += TDuration::Seconds(15);
+ value.Increment(-13, time);
+ time += TDuration::Seconds(15);
+ value.Increment(+17, time);
+ time += TDuration::Seconds(15);
+
+ auto avg = value.GetValueAveragePerDuration(TDuration::Minutes(1));
+ UNIT_ASSERT_C(avg >= 0 && avg <= 15, avg);
+ }
+
Y_UNIT_TEST(TimeSeriesKV) {
- TTimeSeriesValue<i64> value;
- TInstant time = TInstant::Now();
+ TTimeSeriesValue<i64> value;
+ TInstant time = TInstant::Now();
TVector<i64> values = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,7476717,0,529363,-1065564};
- time -= TDuration::Days(1);
- for (i64 val : values) {
- value.Increment(val, time);
- time += TDuration::Hours(1);
- }
- auto avg = value.GetValueAveragePerDuration(TDuration::Seconds(1));
- UNIT_ASSERT_C(avg >= 112 && avg <= 114, avg);
- }
-
+ time -= TDuration::Days(1);
+ for (i64 val : values) {
+ value.Increment(val, time);
+ time += TDuration::Hours(1);
+ }
+ auto avg = value.GetValueAveragePerDuration(TDuration::Seconds(1));
+ UNIT_ASSERT_C(avg >= 112 && avg <= 114, avg);
+ }
+
Y_UNIT_TEST(TimeSeriesKV2) {
- TTimeSeriesValue<i64> value;
- TInstant time = TInstant::Now();
+ TTimeSeriesValue<i64> value;
+ TInstant time = TInstant::Now();
TVector<i64> values = {0,0,0,0,1502,0,-64006,-100840,-151185,-4088398,-169038,-167227,-74841,-111563,-107191,-146359,-107399,-195925,-140440,-173191,-30211,-128287,-185191,-140449};
- time -= TDuration::Days(1);
- for (i64 val : values) {
- value.Increment(val, time);
- time += TDuration::Hours(1);
- }
- auto avg = value.GetValueAveragePerDuration(TDuration::Seconds(1));
- UNIT_ASSERT_C(avg < 0, avg);
- }
-
+ time -= TDuration::Days(1);
+ for (i64 val : values) {
+ value.Increment(val, time);
+ time += TDuration::Hours(1);
+ }
+ auto avg = value.GetValueAveragePerDuration(TDuration::Seconds(1));
+ UNIT_ASSERT_C(avg < 0, avg);
+ }
+
Y_UNIT_TEST(TimeSeriesAVG) {
- TTimeSeriesValue<i64, 1000000ull * 60 * 5, 20> value;
- TInstant time = TInstant::Now();
- time -= TDuration::Seconds(2);
- value.Increment(400, time);
- time += TDuration::Seconds(1);
- value.Increment(400, time);
- auto avg = value.GetValueAveragePerDuration(TDuration::Seconds(1));
- UNIT_ASSERT_C(avg == 400, avg);
- }
-
+ TTimeSeriesValue<i64, 1000000ull * 60 * 5, 20> value;
+ TInstant time = TInstant::Now();
+ time -= TDuration::Seconds(2);
+ value.Increment(400, time);
+ time += TDuration::Seconds(1);
+ value.Increment(400, time);
+ auto avg = value.GetValueAveragePerDuration(TDuration::Seconds(1));
+ UNIT_ASSERT_C(avg == 400, avg);
+ }
+
Y_UNIT_TEST(DecayingAverageAvg) {
- TDecayingAverageValue<ui64, NMetrics::DurationPerMinute> value;
- TInstant time = TInstant::Now();
-
- value.Increment(0, time); // first value will be skipped anyway
- UNIT_ASSERT(!value.IsValueReady());
- UNIT_ASSERT(!value.IsValueObsolete(time));
- time += TDuration::Seconds(15);
- value.Increment(14, time);
- UNIT_ASSERT(!value.IsValueReady());
- UNIT_ASSERT(!value.IsValueObsolete(time));
- time += TDuration::Seconds(15);
- value.Increment(16, time);
- UNIT_ASSERT(!value.IsValueReady());
- UNIT_ASSERT(!value.IsValueObsolete(time));
- time += TDuration::Seconds(15);
- value.Increment(13, time);
- UNIT_ASSERT(!value.IsValueReady());
- UNIT_ASSERT(!value.IsValueObsolete(time));
- time += TDuration::Seconds(15);
- value.Increment(17, time);
- UNIT_ASSERT(value.IsValueReady());
- UNIT_ASSERT(!value.IsValueObsolete(time));
- time += TDuration::Seconds(15);
-
- value.Increment(14, time);
- UNIT_ASSERT(value.IsValueReady());
- UNIT_ASSERT(!value.IsValueObsolete(time));
- time += TDuration::Seconds(15);
- value.Increment(16, time);
- UNIT_ASSERT(value.IsValueReady());
- UNIT_ASSERT(!value.IsValueObsolete(time));
- time += TDuration::Seconds(15);
- value.Increment(13, time);
- UNIT_ASSERT(value.IsValueReady());
- UNIT_ASSERT(!value.IsValueObsolete(time));
- time += TDuration::Seconds(15);
- value.Increment(17, time);
- UNIT_ASSERT(value.IsValueReady());
- UNIT_ASSERT(!value.IsValueObsolete(time));
- auto avg = value.GetValue();
- UNIT_ASSERT_C(avg == 60, avg);
+ TDecayingAverageValue<ui64, NMetrics::DurationPerMinute> value;
+ TInstant time = TInstant::Now();
+
+ value.Increment(0, time); // first value will be skipped anyway
+ UNIT_ASSERT(!value.IsValueReady());
+ UNIT_ASSERT(!value.IsValueObsolete(time));
+ time += TDuration::Seconds(15);
+ value.Increment(14, time);
+ UNIT_ASSERT(!value.IsValueReady());
+ UNIT_ASSERT(!value.IsValueObsolete(time));
+ time += TDuration::Seconds(15);
+ value.Increment(16, time);
+ UNIT_ASSERT(!value.IsValueReady());
+ UNIT_ASSERT(!value.IsValueObsolete(time));
+ time += TDuration::Seconds(15);
+ value.Increment(13, time);
+ UNIT_ASSERT(!value.IsValueReady());
+ UNIT_ASSERT(!value.IsValueObsolete(time));
+ time += TDuration::Seconds(15);
+ value.Increment(17, time);
+ UNIT_ASSERT(value.IsValueReady());
+ UNIT_ASSERT(!value.IsValueObsolete(time));
+ time += TDuration::Seconds(15);
+
+ value.Increment(14, time);
+ UNIT_ASSERT(value.IsValueReady());
+ UNIT_ASSERT(!value.IsValueObsolete(time));
+ time += TDuration::Seconds(15);
+ value.Increment(16, time);
+ UNIT_ASSERT(value.IsValueReady());
+ UNIT_ASSERT(!value.IsValueObsolete(time));
+ time += TDuration::Seconds(15);
+ value.Increment(13, time);
+ UNIT_ASSERT(value.IsValueReady());
+ UNIT_ASSERT(!value.IsValueObsolete(time));
+ time += TDuration::Seconds(15);
+ value.Increment(17, time);
+ UNIT_ASSERT(value.IsValueReady());
+ UNIT_ASSERT(!value.IsValueObsolete(time));
+ auto avg = value.GetValue();
+ UNIT_ASSERT_C(avg == 60, avg);
value.Set(avg, time);
- auto avg2 = value.GetValue();
- UNIT_ASSERT_C(avg2 == avg, avg2);
- time += TDuration::Minutes(1);
- UNIT_ASSERT(!value.IsValueObsolete(time));
- time += TDuration::Minutes(1);
- UNIT_ASSERT(!value.IsValueObsolete(time));
- time += TDuration::Minutes(1);
- UNIT_ASSERT(value.IsValueObsolete(time));
- }
-
- Y_UNIT_TEST(MaximumValue1) {
- TMaximumValueVariableWindowUI64 maximum;
- TInstant time = TInstant::Now();
-
- maximum.SetWindowSize(TDuration::MilliSeconds(60000));
- maximum.SetValue(90, time);
- time += TDuration::Seconds(2);
- maximum.SetValue(100, time);
- time += TDuration::Seconds(2);
- maximum.SetValue(80, time);
- time += TDuration::Seconds(2);
- maximum.SetValue(70, time);
- time += TDuration::Seconds(2);
- maximum.SetValue(60, time);
- time += TDuration::Seconds(2);
- maximum.SetValue(50, time);
-
- // +12 seconds
- UNIT_ASSERT_VALUES_EQUAL(maximum.GetValue(), 100);
-
- time += TDuration::Seconds(2);
- maximum.SetValue(60, time);
- time += TDuration::Seconds(2);
- maximum.SetValue(60, time);
- time += TDuration::Seconds(2);
- maximum.SetValue(60, time);
- time += TDuration::Seconds(2);
- maximum.SetValue(60, time);
- time += TDuration::Seconds(2);
- maximum.SetValue(60, time);
- time += TDuration::Seconds(2);
- maximum.SetValue(60, time);
-
- // +24 seconds
- time += TDuration::Seconds(2);
- maximum.SetValue(60, time);
- time += TDuration::Seconds(2);
- maximum.SetValue(60, time);
- time += TDuration::Seconds(2);
- maximum.SetValue(60, time);
- time += TDuration::Seconds(2);
- maximum.SetValue(60, time);
- time += TDuration::Seconds(2);
- maximum.SetValue(60, time);
- time += TDuration::Seconds(2);
- maximum.SetValue(60, time);
-
- // +36 seconds
- time += TDuration::Seconds(2);
- maximum.SetValue(80, time);
- time += TDuration::Seconds(2);
- maximum.SetValue(60, time);
- time += TDuration::Seconds(2);
- maximum.SetValue(60, time);
- time += TDuration::Seconds(2);
- maximum.SetValue(60, time);
- time += TDuration::Seconds(2);
- maximum.SetValue(60, time);
- time += TDuration::Seconds(2);
- maximum.SetValue(60, time);
-
- // +48 seconds
- UNIT_ASSERT_VALUES_EQUAL(maximum.GetValue(), 100);
-
- time += TDuration::Seconds(2);
- maximum.SetValue(60, time);
- time += TDuration::Seconds(2);
- maximum.SetValue(60, time);
- time += TDuration::Seconds(2);
- maximum.SetValue(60, time);
- time += TDuration::Seconds(2);
- maximum.SetValue(60, time);
- time += TDuration::Seconds(2);
- maximum.SetValue(60, time);
- time += TDuration::Seconds(2);
- maximum.SetValue(60, time);
-
- // +60 seconds
- time += TDuration::Seconds(2);
- maximum.SetValue(60, time);
-
- UNIT_ASSERT_VALUES_EQUAL(maximum.GetValue(), 80);
- }
-
- Y_UNIT_TEST(MaximumValue2) {
- TMaximumValueVariableWindowUI64 maximum;
- TInstant time = TInstant::Now();
-
- maximum.SetWindowSize(TDuration::MilliSeconds(60000));
- maximum.SetValue(100, time);
-
- UNIT_ASSERT_VALUES_EQUAL(maximum.GetValue(), 100);
-
- // +12 seconds
- time += TDuration::Seconds(12);
- maximum.SetValue(60, time);
-
- // +24 seconds
- time += TDuration::Seconds(12);
- maximum.SetValue(60, time);
-
- // +36 seconds
- time += TDuration::Seconds(12);
- maximum.SetValue(80, time);
-
- // +48 seconds
- UNIT_ASSERT_VALUES_EQUAL(maximum.GetValue(), 100);
-
- time += TDuration::Seconds(12);
- maximum.SetValue(60, time);
-
- // +60 seconds
- UNIT_ASSERT_VALUES_EQUAL(maximum.GetValue(), 100);
-
- // +72 seconds
- time += TDuration::Seconds(12);
- maximum.SetValue(60, time);
-
- UNIT_ASSERT_VALUES_EQUAL(maximum.GetValue(), 80);
- }
-
- void Dump(const TMaximumValueVariableWindowUI64& m) {
- Cerr << "[";
- for (auto it = m.GetValues().begin(); it != m.GetValues().end(); ++it) {
- if (it != m.GetValues().begin()) {
- Cerr << ",";
- }
- Cerr << *it;
- }
- Cerr << "]" << Endl;
- }
-
- Y_UNIT_TEST(MaximumValue3) {
- TMaximumValueVariableWindowUI64 maximum;
- TInstant time = TInstant::Now();
-
- maximum.SetWindowSize(TDuration::MilliSeconds(60000));
- maximum.SetValue(100, time);
-
- UNIT_ASSERT_VALUES_EQUAL(maximum.GetValue(), 100);
-
- // +30 seconds
- time += TDuration::Seconds(30);
- maximum.SetValue(80, time);
-
- UNIT_ASSERT_VALUES_EQUAL(maximum.GetValue(), 100);
-
- // +60 seconds
- time += TDuration::Seconds(30);
- maximum.SetValue(60, time);
-
- UNIT_ASSERT_VALUES_EQUAL(maximum.GetValue(), 80);
-
- // +90 seconds
- time += TDuration::Seconds(30);
- maximum.SetValue(40, time);
-
- UNIT_ASSERT_VALUES_EQUAL(maximum.GetValue(), 60);
-
- // +120 seconds
- time += TDuration::Seconds(30);
- maximum.SetValue(20, time);
-
- UNIT_ASSERT_VALUES_EQUAL(maximum.GetValue(), 40);
- }
-
- Y_UNIT_TEST(MaximumValue4) {
- TMaximumValueVariableWindowUI64 maximum;
- TInstant time = TInstant::Now();
-
- maximum.SetWindowSize(TDuration::MilliSeconds(60000));
- maximum.SetValue(100, time);
-
- UNIT_ASSERT_VALUES_EQUAL(maximum.GetValue(), 100);
-
- // +120 seconds
- time += TDuration::Seconds(120);
- maximum.SetValue(80, time);
-
- UNIT_ASSERT_VALUES_EQUAL(maximum.GetValue(), 80);
- }
-}
-
-}
-}
+ auto avg2 = value.GetValue();
+ UNIT_ASSERT_C(avg2 == avg, avg2);
+ time += TDuration::Minutes(1);
+ UNIT_ASSERT(!value.IsValueObsolete(time));
+ time += TDuration::Minutes(1);
+ UNIT_ASSERT(!value.IsValueObsolete(time));
+ time += TDuration::Minutes(1);
+ UNIT_ASSERT(value.IsValueObsolete(time));
+ }
+
+ Y_UNIT_TEST(MaximumValue1) {
+ TMaximumValueVariableWindowUI64 maximum;
+ TInstant time = TInstant::Now();
+
+ maximum.SetWindowSize(TDuration::MilliSeconds(60000));
+ maximum.SetValue(90, time);
+ time += TDuration::Seconds(2);
+ maximum.SetValue(100, time);
+ time += TDuration::Seconds(2);
+ maximum.SetValue(80, time);
+ time += TDuration::Seconds(2);
+ maximum.SetValue(70, time);
+ time += TDuration::Seconds(2);
+ maximum.SetValue(60, time);
+ time += TDuration::Seconds(2);
+ maximum.SetValue(50, time);
+
+ // +12 seconds
+ UNIT_ASSERT_VALUES_EQUAL(maximum.GetValue(), 100);
+
+ time += TDuration::Seconds(2);
+ maximum.SetValue(60, time);
+ time += TDuration::Seconds(2);
+ maximum.SetValue(60, time);
+ time += TDuration::Seconds(2);
+ maximum.SetValue(60, time);
+ time += TDuration::Seconds(2);
+ maximum.SetValue(60, time);
+ time += TDuration::Seconds(2);
+ maximum.SetValue(60, time);
+ time += TDuration::Seconds(2);
+ maximum.SetValue(60, time);
+
+ // +24 seconds
+ time += TDuration::Seconds(2);
+ maximum.SetValue(60, time);
+ time += TDuration::Seconds(2);
+ maximum.SetValue(60, time);
+ time += TDuration::Seconds(2);
+ maximum.SetValue(60, time);
+ time += TDuration::Seconds(2);
+ maximum.SetValue(60, time);
+ time += TDuration::Seconds(2);
+ maximum.SetValue(60, time);
+ time += TDuration::Seconds(2);
+ maximum.SetValue(60, time);
+
+ // +36 seconds
+ time += TDuration::Seconds(2);
+ maximum.SetValue(80, time);
+ time += TDuration::Seconds(2);
+ maximum.SetValue(60, time);
+ time += TDuration::Seconds(2);
+ maximum.SetValue(60, time);
+ time += TDuration::Seconds(2);
+ maximum.SetValue(60, time);
+ time += TDuration::Seconds(2);
+ maximum.SetValue(60, time);
+ time += TDuration::Seconds(2);
+ maximum.SetValue(60, time);
+
+ // +48 seconds
+ UNIT_ASSERT_VALUES_EQUAL(maximum.GetValue(), 100);
+
+ time += TDuration::Seconds(2);
+ maximum.SetValue(60, time);
+ time += TDuration::Seconds(2);
+ maximum.SetValue(60, time);
+ time += TDuration::Seconds(2);
+ maximum.SetValue(60, time);
+ time += TDuration::Seconds(2);
+ maximum.SetValue(60, time);
+ time += TDuration::Seconds(2);
+ maximum.SetValue(60, time);
+ time += TDuration::Seconds(2);
+ maximum.SetValue(60, time);
+
+ // +60 seconds
+ time += TDuration::Seconds(2);
+ maximum.SetValue(60, time);
+
+ UNIT_ASSERT_VALUES_EQUAL(maximum.GetValue(), 80);
+ }
+
+ Y_UNIT_TEST(MaximumValue2) {
+ TMaximumValueVariableWindowUI64 maximum;
+ TInstant time = TInstant::Now();
+
+ maximum.SetWindowSize(TDuration::MilliSeconds(60000));
+ maximum.SetValue(100, time);
+
+ UNIT_ASSERT_VALUES_EQUAL(maximum.GetValue(), 100);
+
+ // +12 seconds
+ time += TDuration::Seconds(12);
+ maximum.SetValue(60, time);
+
+ // +24 seconds
+ time += TDuration::Seconds(12);
+ maximum.SetValue(60, time);
+
+ // +36 seconds
+ time += TDuration::Seconds(12);
+ maximum.SetValue(80, time);
+
+ // +48 seconds
+ UNIT_ASSERT_VALUES_EQUAL(maximum.GetValue(), 100);
+
+ time += TDuration::Seconds(12);
+ maximum.SetValue(60, time);
+
+ // +60 seconds
+ UNIT_ASSERT_VALUES_EQUAL(maximum.GetValue(), 100);
+
+ // +72 seconds
+ time += TDuration::Seconds(12);
+ maximum.SetValue(60, time);
+
+ UNIT_ASSERT_VALUES_EQUAL(maximum.GetValue(), 80);
+ }
+
+ void Dump(const TMaximumValueVariableWindowUI64& m) {
+ Cerr << "[";
+ for (auto it = m.GetValues().begin(); it != m.GetValues().end(); ++it) {
+ if (it != m.GetValues().begin()) {
+ Cerr << ",";
+ }
+ Cerr << *it;
+ }
+ Cerr << "]" << Endl;
+ }
+
+ Y_UNIT_TEST(MaximumValue3) {
+ TMaximumValueVariableWindowUI64 maximum;
+ TInstant time = TInstant::Now();
+
+ maximum.SetWindowSize(TDuration::MilliSeconds(60000));
+ maximum.SetValue(100, time);
+
+ UNIT_ASSERT_VALUES_EQUAL(maximum.GetValue(), 100);
+
+ // +30 seconds
+ time += TDuration::Seconds(30);
+ maximum.SetValue(80, time);
+
+ UNIT_ASSERT_VALUES_EQUAL(maximum.GetValue(), 100);
+
+ // +60 seconds
+ time += TDuration::Seconds(30);
+ maximum.SetValue(60, time);
+
+ UNIT_ASSERT_VALUES_EQUAL(maximum.GetValue(), 80);
+
+ // +90 seconds
+ time += TDuration::Seconds(30);
+ maximum.SetValue(40, time);
+
+ UNIT_ASSERT_VALUES_EQUAL(maximum.GetValue(), 60);
+
+ // +120 seconds
+ time += TDuration::Seconds(30);
+ maximum.SetValue(20, time);
+
+ UNIT_ASSERT_VALUES_EQUAL(maximum.GetValue(), 40);
+ }
+
+ Y_UNIT_TEST(MaximumValue4) {
+ TMaximumValueVariableWindowUI64 maximum;
+ TInstant time = TInstant::Now();
+
+ maximum.SetWindowSize(TDuration::MilliSeconds(60000));
+ maximum.SetValue(100, time);
+
+ UNIT_ASSERT_VALUES_EQUAL(maximum.GetValue(), 100);
+
+ // +120 seconds
+ time += TDuration::Seconds(120);
+ maximum.SetValue(80, time);
+
+ UNIT_ASSERT_VALUES_EQUAL(maximum.GetValue(), 80);
+ }
+}
+
+}
+}
diff --git a/ydb/core/tablet/tablet_monitoring_proxy.cpp b/ydb/core/tablet/tablet_monitoring_proxy.cpp
index acd08467fd3..a61a43b7e5c 100644
--- a/ydb/core/tablet/tablet_monitoring_proxy.cpp
+++ b/ydb/core/tablet/tablet_monitoring_proxy.cpp
@@ -57,7 +57,7 @@ public:
HFunc(TEvTabletPipe::TEvClientDestroyed, Handle);
HFunc(NMon::TEvRemoteHttpInfoRes, Handle);
HFunc(NMon::TEvRemoteBinaryInfoRes, Handle);
- HFunc(NMon::TEvRemoteJsonInfoRes, Handle);
+ HFunc(NMon::TEvRemoteJsonInfoRes, Handle);
CFunc(TEvents::TSystem::Wakeup, Wakeup);
}
}
@@ -90,11 +90,11 @@ public:
Detach(ctx);
}
- void Handle(NMon::TEvRemoteJsonInfoRes::TPtr &ev, const TActorContext &ctx) {
- ctx.Send(Sender, new NMon::TEvHttpInfoRes(NMonitoring::HTTPOKJSON + ev->Get()->Json, 0, NMon::IEvHttpInfoRes::EContentType::Custom));
- Detach(ctx);
- }
-
+ void Handle(NMon::TEvRemoteJsonInfoRes::TPtr &ev, const TActorContext &ctx) {
+ ctx.Send(Sender, new NMon::TEvHttpInfoRes(NMonitoring::HTTPOKJSON + ev->Get()->Json, 0, NMon::IEvHttpInfoRes::EContentType::Custom));
+ Detach(ctx);
+ }
+
void Notify(const TActorContext &ctx, const TString& html) {
ctx.Send(Sender, new NMon::TEvHttpInfoRes(html));
}
@@ -170,13 +170,13 @@ TTabletMonitoringProxyActor::Bootstrap(const TActorContext &ctx) {
}
static ui64 TryParseTabletId(TStringBuf tabletIdParam) {
- if (tabletIdParam.StartsWith("0x")) {
- ui64 result = 0;
- TryIntFromString<16, ui64>(tabletIdParam.substr(2), result);
- return result;
- } else {
- return FromStringWithDefault<ui64>(tabletIdParam);
- }
+ if (tabletIdParam.StartsWith("0x")) {
+ ui64 result = 0;
+ TryIntFromString<16, ui64>(tabletIdParam.substr(2), result);
+ return result;
+ } else {
+ return FromStringWithDefault<ui64>(tabletIdParam);
+ }
}
////////////////////////////////////////////
@@ -194,18 +194,18 @@ TTabletMonitoringProxyActor::Handle(NMon::TEvHttpInfo::TPtr &ev, const TActorCon
if (cgi->Has("KillTabletID")) {
const ui64 tabletId = TryParseTabletId(cgi->Get("KillTabletID"));
- if (tabletId) {
- ctx.Register(CreateTabletKiller(tabletId));
- ctx.Send(ev->Sender, new NMon::TEvHttpInfoRes("<meta http-equiv=\"refresh\" content=\"0; tablets\" />"));
- return;
- }
- }
-
+ if (tabletId) {
+ ctx.Register(CreateTabletKiller(tabletId));
+ ctx.Send(ev->Sender, new NMon::TEvHttpInfoRes("<meta http-equiv=\"refresh\" content=\"0; tablets\" />"));
+ return;
+ }
+ }
+
bool hasFollowerParam = cgi->Has("FollowerID");
if (hasFollowerParam) {
const TString &tabletIdParam = cgi->Get("FollowerID");
- const ui64 tabletId = TryParseTabletId(tabletIdParam);
- if (tabletId) {
+ const ui64 tabletId = TryParseTabletId(tabletIdParam);
+ if (tabletId) {
TString url = TStringBuilder() << msg->Request.GetPathInfo() << "?" << cgi->Print();
ctx.ExecutorThread.RegisterActor(new TForwardingActor(Config, tabletId, true, ev->Sender, std::move(url)));
return;
@@ -215,8 +215,8 @@ TTabletMonitoringProxyActor::Handle(NMon::TEvHttpInfo::TPtr &ev, const TActorCon
bool hasIdParam = cgi->Has("TabletID");
if (hasIdParam) {
const TString &tabletIdParam = cgi->Get("TabletID");
- const ui64 tabletId = TryParseTabletId(tabletIdParam);
- if (tabletId) {
+ const ui64 tabletId = TryParseTabletId(tabletIdParam);
+ if (tabletId) {
TString url = TStringBuilder() << msg->Request.GetPathInfo() << "?" << cgi->Print();
ctx.ExecutorThread.RegisterActor(new TForwardingActor(Config, tabletId, false, ev->Sender, std::move(url), msg->Request.GetMethod()));
return;
@@ -225,8 +225,8 @@ TTabletMonitoringProxyActor::Handle(NMon::TEvHttpInfo::TPtr &ev, const TActorCon
if (cgi->Has("SsId")) {
const TString &ssIdParam = cgi->Get("SsId");
- const ui64 tabletId = TryParseTabletId(ssIdParam);
- if (tabletId) {
+ const ui64 tabletId = TryParseTabletId(ssIdParam);
+ if (tabletId) {
TString url = TStringBuilder() << msg->Request.GetPathInfo() << "?" << cgi->Print();
ctx.ExecutorThread.RegisterActor(CreateStateStorageMonitoringActor(tabletId, ev->Sender, std::move(url)));
return;
diff --git a/ydb/core/tablet/tablet_monitoring_proxy.h b/ydb/core/tablet/tablet_monitoring_proxy.h
index 8a606a0ee76..07fd7888db3 100644
--- a/ydb/core/tablet/tablet_monitoring_proxy.h
+++ b/ydb/core/tablet/tablet_monitoring_proxy.h
@@ -15,10 +15,10 @@ namespace NKikimr { namespace NTabletMonitoringProxy {
struct TTabletMonitoringProxyConfig {
bool PreferLocal = true;
- NTabletPipe::TClientRetryPolicy RetryPolicy;
+ NTabletPipe::TClientRetryPolicy RetryPolicy;
void SetRetryLimitCount(ui32 retryLimitCount) {
- RetryPolicy = {.RetryLimitCount = retryLimitCount};
+ RetryPolicy = {.RetryLimitCount = retryLimitCount};
}
};
diff --git a/ydb/core/tablet/tablet_pipe_client.cpp b/ydb/core/tablet/tablet_pipe_client.cpp
index e3bd46ae1b0..2fa35af9a0e 100644
--- a/ydb/core/tablet/tablet_pipe_client.cpp
+++ b/ydb/core/tablet/tablet_pipe_client.cpp
@@ -389,31 +389,31 @@ namespace NTabletPipe {
Lookup(ctx);
}
- void RequestHiveInfo(ui64 hiveTabletId) {
- static TClientConfig clientConfig({.RetryLimitCount = 3, .MinRetryTime = TDuration::MilliSeconds(300)});
- HiveClient = Register(CreateClient(SelfId(), hiveTabletId, clientConfig));
- NTabletPipe::SendData(SelfId(), HiveClient, new TEvHive::TEvRequestHiveInfo(TabletId, false));
- }
-
+ void RequestHiveInfo(ui64 hiveTabletId) {
+ static TClientConfig clientConfig({.RetryLimitCount = 3, .MinRetryTime = TDuration::MilliSeconds(300)});
+ HiveClient = Register(CreateClient(SelfId(), hiveTabletId, clientConfig));
+ NTabletPipe::SendData(SelfId(), HiveClient, new TEvHive::TEvRequestHiveInfo(TabletId, false));
+ }
+
// check aliveness section
void Handle(TEvHive::TEvResponseHiveInfo::TPtr &ev, const TActorContext &ctx) {
const auto &record = ev->Get()->Record;
- if (record.HasForwardRequest() && (++CurrentHiveForwards < MAX_HIVE_FORWARDS)) {
- BLOG_I("hive request forwarded to " << record.GetForwardRequest().GetHiveTabletId());
- CloseClient(ctx, HiveClient);
- RequestHiveInfo(record.GetForwardRequest().GetHiveTabletId());
- return;
- }
- bool definitelyDead = false;
- if (record.GetTablets().empty()) {
- definitelyDead = true; // the tablet wasn't found in Hive
- } else {
- const auto &info = record.GetTablets(0);
- Y_VERIFY(info.GetTabletID() == TabletId);
- if (!info.HasState() || info.GetState() == 202/*THive::ETabletState::Deleting*/) {
- definitelyDead = true;
- }
- }
+ if (record.HasForwardRequest() && (++CurrentHiveForwards < MAX_HIVE_FORWARDS)) {
+ BLOG_I("hive request forwarded to " << record.GetForwardRequest().GetHiveTabletId());
+ CloseClient(ctx, HiveClient);
+ RequestHiveInfo(record.GetForwardRequest().GetHiveTabletId());
+ return;
+ }
+ bool definitelyDead = false;
+ if (record.GetTablets().empty()) {
+ definitelyDead = true; // the tablet wasn't found in Hive
+ } else {
+ const auto &info = record.GetTablets(0);
+ Y_VERIFY(info.GetTabletID() == TabletId);
+ if (!info.HasState() || info.GetState() == 202/*THive::ETabletState::Deleting*/) {
+ definitelyDead = true;
+ }
+ }
ctx.Send(Owner, new TEvTabletPipe::TEvClientConnected(TabletId, NKikimrProto::ERROR, SelfId(), TActorId(), Leader, definitelyDead));
return Die(ctx);
@@ -509,7 +509,7 @@ namespace NTabletPipe {
LastKnownLeader = TActorId();
TDuration waitDuration;
- if (Config.RetryPolicy && RetryState.IsAllowedToRetry(waitDuration, Config.RetryPolicy)) {
+ if (Config.RetryPolicy && RetryState.IsAllowedToRetry(waitDuration, Config.RetryPolicy)) {
if (waitDuration == TDuration::Zero()) {
BLOG_D("immediate retry");
Lookup(ctx);
@@ -677,11 +677,11 @@ namespace NTabletPipe {
TActorId ServerId;
typedef TOneOneQueueInplace<IEventHandle*, 32> TPayloadQueue;
TAutoPtr<TPayloadQueue, TPayloadQueue::TPtrCleanDestructor> PayloadQueue;
- TClientRetryState RetryState;
+ TClientRetryState RetryState;
bool Leader;
TActorId HiveClient;
- ui32 CurrentHiveForwards = 0;
- static constexpr ui32 MAX_HIVE_FORWARDS = 10;
+ ui32 CurrentHiveForwards = 0;
+ static constexpr ui32 MAX_HIVE_FORWARDS = 10;
};
IActor* CreateClient(const TActorId& owner, ui64 tabletId, const TClientConfig& config) {
@@ -730,7 +730,7 @@ namespace NTabletPipe {
void CloseClient(const TActorContext& ctx, const TActorId& clientId) {
ctx.Send(clientId, new TEvents::TEvPoisonPill);
}
-
+
void CloseClient(TActorIdentity self, TActorId clientId) {
self.Send(clientId, new TEvents::TEvPoisonPill());
}
@@ -742,20 +742,20 @@ namespace NTabletPipe {
}
}
- bool TClientRetryState::IsAllowedToRetry(TDuration& wait, const TClientRetryPolicy& policy) {
- if (RetryNumber == 0) {
- wait = policy.DoFirstRetryInstantly ? TDuration::Zero() : policy.MinRetryTime;
- } else {
+ bool TClientRetryState::IsAllowedToRetry(TDuration& wait, const TClientRetryPolicy& policy) {
+ if (RetryNumber == 0) {
+ wait = policy.DoFirstRetryInstantly ? TDuration::Zero() : policy.MinRetryTime;
+ } else {
const ui64 baseRetryDuration = RetryDuration.GetValue() * policy.BackoffMultiplier;
const ui64 croppedRetryDuration = Min(policy.MaxRetryTime.GetValue(), baseRetryDuration);
const ui64 randomizedRetryDuration = croppedRetryDuration * AppData()->RandomProvider->Uniform(100, 115) / 100;
wait = TDuration::FromValue(randomizedRetryDuration);
- wait = Max(policy.MinRetryTime, wait);
- }
- ++RetryNumber;
- RetryDuration = wait;
- return !policy.RetryLimitCount || RetryNumber <= policy.RetryLimitCount;
- }
+ wait = Max(policy.MinRetryTime, wait);
+ }
+ ++RetryNumber;
+ RetryDuration = wait;
+ return !policy.RetryLimitCount || RetryNumber <= policy.RetryLimitCount;
+ }
TDuration TClientRetryState::MakeCheckDelay() {
const ui64 randomizedRetryDuration = RetryDuration.GetValue() * AppData()->RandomProvider->Uniform(100, 133) / 100;
diff --git a/ydb/core/tablet/tablet_pipe_server.cpp b/ydb/core/tablet/tablet_pipe_server.cpp
index aa44bfa4b49..b7c669e72cc 100644
--- a/ydb/core/tablet/tablet_pipe_server.cpp
+++ b/ydb/core/tablet/tablet_pipe_server.cpp
@@ -185,9 +185,9 @@ namespace NTabletPipe {
OwnerId = ev->Get()->OwnerId;
RecipientId = ev->Get()->RecipientId;
Leader = ev->Get()->Leader;
- Y_VERIFY(OwnerId);
- Y_VERIFY(RecipientId);
- if (InterconnectSession) {
+ Y_VERIFY(OwnerId);
+ Y_VERIFY(RecipientId);
+ if (InterconnectSession) {
NeedUnsubscribe = true;
ctx.Send(InterconnectSession, new TEvents::TEvSubscribe(), IEventHandle::FlagTrackDelivery);
Become(&TThis::StateWaitingSubscribe);
@@ -297,7 +297,7 @@ namespace NTabletPipe {
for (const auto& serverId : ServerIds) {
CloseServer(owner, serverId);
}
- Active = false;
+ Active = false;
ServerIds.clear();
ActivatePending.clear();
}
diff --git a/ydb/core/tablet/tablet_pipe_ut.cpp b/ydb/core/tablet/tablet_pipe_ut.cpp
index bc13f1b0701..2a528070fb6 100644
--- a/ydb/core/tablet/tablet_pipe_ut.cpp
+++ b/ydb/core/tablet/tablet_pipe_ut.cpp
@@ -97,7 +97,7 @@ namespace NKikimr {
Config.ConnectToUserTablet = ev->Get()->ConnectToUserTablet;
if (ev->Get()->WithRetryPolicy) {
- Config.RetryPolicy = NTabletPipe::TClientRetryPolicy::WithRetries();
+ Config.RetryPolicy = NTabletPipe::TClientRetryPolicy::WithRetries();
}
auto client = NTabletPipe::CreateClient(ctx.SelfID, ev->Get()->UseBadTabletId ?
diff --git a/ydb/core/tablet/tablet_req_blockbs.cpp b/ydb/core/tablet/tablet_req_blockbs.cpp
index ec1b345dc42..7e2e94ec95d 100644
--- a/ydb/core/tablet/tablet_req_blockbs.cpp
+++ b/ydb/core/tablet/tablet_req_blockbs.cpp
@@ -37,13 +37,13 @@ class TTabletReqBlockBlobStorageGroup : public TActorBootstrapped<TTabletReqBloc
case NKikimrProto::OK:
return ReplyAndDie(NKikimrProto::OK);
case NKikimrProto::BLOCKED:
- case NKikimrProto::RACE:
+ case NKikimrProto::RACE:
case NKikimrProto::NO_GROUP:
// The request will never succeed
return ReplyAndDie(msg->Status, msg->ErrorReason);
default:
++ErrorCount;
- if (ErrorCount >= MAX_ATTEMPTS) {
+ if (ErrorCount >= MAX_ATTEMPTS) {
return ReplyAndDie(NKikimrProto::ERROR, msg->ErrorReason);
}
return SendRequest();
diff --git a/ydb/core/tablet/tablet_req_delete.cpp b/ydb/core/tablet/tablet_req_delete.cpp
index f84a20718b3..754c79bb325 100644
--- a/ydb/core/tablet/tablet_req_delete.cpp
+++ b/ydb/core/tablet/tablet_req_delete.cpp
@@ -1,59 +1,59 @@
-#include "tablet_impl.h"
+#include "tablet_impl.h"
#include <library/cpp/actors/core/actor_bootstrapped.h>
#include <library/cpp/actors/core/hfunc.h>
#include <ydb/core/node_whiteboard/node_whiteboard.h>
-#include <util/generic/hash_set.h>
-
-namespace NKikimr {
-
-constexpr ui32 MAX_ATTEMPTS = 10;
-
-class TTabletReqDelete : public TActorBootstrapped<TTabletReqDelete> {
- struct TRequestInfo {
- ui32 GroupId;
- ui32 Channel;
-
- TRequestInfo(ui32 groupId, ui32 channel)
- : GroupId(groupId)
- , Channel(channel)
- {}
- };
-
+#include <util/generic/hash_set.h>
+
+namespace NKikimr {
+
+constexpr ui32 MAX_ATTEMPTS = 10;
+
+class TTabletReqDelete : public TActorBootstrapped<TTabletReqDelete> {
+ struct TRequestInfo {
+ ui32 GroupId;
+ ui32 Channel;
+
+ TRequestInfo(ui32 groupId, ui32 channel)
+ : GroupId(groupId)
+ , Channel(channel)
+ {}
+ };
+
const TActorId Owner;
- TIntrusivePtr<TTabletStorageInfo> TabletStorageInfo;
+ TIntrusivePtr<TTabletStorageInfo> TabletStorageInfo;
TVector<TRequestInfo> Requests;
- ui32 FinishedRequests;
- ui32 ErrorCount;
- ui32 Generation;
-
- void ReplyAndDie(NKikimrProto::EReplyStatus status, const TActorContext &ctx) {
- if (status == NKikimrProto::OK) {
+ ui32 FinishedRequests;
+ ui32 ErrorCount;
+ ui32 Generation;
+
+ void ReplyAndDie(NKikimrProto::EReplyStatus status, const TActorContext &ctx) {
+ if (status == NKikimrProto::OK) {
const TActorId tabletStateServiceId = NNodeWhiteboard::MakeNodeWhiteboardServiceId(ctx.SelfID.NodeId());
- ctx.Send(tabletStateServiceId, new NNodeWhiteboard::TEvWhiteboard::TEvTabletStateUpdate(
- TabletStorageInfo->TabletID,
- 0,
- NKikimrWhiteboard::TTabletStateInfo::Deleted,
- std::numeric_limits<ui32>::max()),
- true);
- // TODO(xenoxeno): broadcast message to more/all nodes ... maybe?
- }
- ctx.Send(Owner, new TEvTabletBase::TEvDeleteTabletResult(status, TabletStorageInfo->TabletID));
- Die(ctx);
- }
-
- void GenerateRequests() {
+ ctx.Send(tabletStateServiceId, new NNodeWhiteboard::TEvWhiteboard::TEvTabletStateUpdate(
+ TabletStorageInfo->TabletID,
+ 0,
+ NKikimrWhiteboard::TTabletStateInfo::Deleted,
+ std::numeric_limits<ui32>::max()),
+ true);
+ // TODO(xenoxeno): broadcast message to more/all nodes ... maybe?
+ }
+ ctx.Send(Owner, new TEvTabletBase::TEvDeleteTabletResult(status, TabletStorageInfo->TabletID));
+ Die(ctx);
+ }
+
+ void GenerateRequests() {
THashSet<std::pair<ui32, ui32>> groupChannels;
- for (const TTabletChannelInfo& channelInfo : TabletStorageInfo->Channels) {
- for (const TTabletChannelInfo::THistoryEntry& historyInfo : channelInfo.History) {
- if (groupChannels.emplace(historyInfo.GroupID, channelInfo.Channel).second) {
- Requests.emplace_back(historyInfo.GroupID, channelInfo.Channel);
- }
- }
- }
- }
-
- void SendRequest(int numRequest, const TActorContext& ctx) {
- const TRequestInfo& info(Requests[numRequest]);
+ for (const TTabletChannelInfo& channelInfo : TabletStorageInfo->Channels) {
+ for (const TTabletChannelInfo::THistoryEntry& historyInfo : channelInfo.History) {
+ if (groupChannels.emplace(historyInfo.GroupID, channelInfo.Channel).second) {
+ Requests.emplace_back(historyInfo.GroupID, channelInfo.Channel);
+ }
+ }
+ }
+ }
+
+ void SendRequest(int numRequest, const TActorContext& ctx) {
+ const TRequestInfo& info(Requests[numRequest]);
bool total = Generation == std::numeric_limits<ui32>::max();
const ui32 recordGeneration = total ? Generation : Generation + 1;
const ui32 perGenerationCounter = total ? Max<ui32>() : 0;
@@ -66,76 +66,76 @@ class TTabletReqDelete : public TActorBootstrapped<TTabletReqDelete> {
std::numeric_limits<ui32>::max(), // collectStep
TInstant::Max()); // deadline
event->IsMonitored = false;
- SendToBSProxy(ctx, info.GroupId, event.Release(), numRequest);
- }
-
+ SendToBSProxy(ctx, info.GroupId, event.Release(), numRequest);
+ }
+
void Handle(TEvents::TEvUndelivered::TPtr&, const TActorContext &ctx) {
return ReplyAndDie(NKikimrProto::ERROR, ctx);
}
- void Handle(TEvBlobStorage::TEvCollectGarbageResult::TPtr& ev, const TActorContext& ctx) {
- const TEvBlobStorage::TEvCollectGarbageResult* msg = ev->Get();
- switch (msg->Status) {
- case NKikimrProto::OK:
- case NKikimrProto::ALREADY:
+ void Handle(TEvBlobStorage::TEvCollectGarbageResult::TPtr& ev, const TActorContext& ctx) {
+ const TEvBlobStorage::TEvCollectGarbageResult* msg = ev->Get();
+ switch (msg->Status) {
+ case NKikimrProto::OK:
+ case NKikimrProto::ALREADY:
case NKikimrProto::NO_GROUP:
- ++FinishedRequests;
- if (FinishedRequests >= Requests.size()) {
- if (Generation == std::numeric_limits<ui32>::max()) {
- ui64 StateStorageId = StateStorageGroupFromTabletID(TabletStorageInfo->TabletID);
+ ++FinishedRequests;
+ if (FinishedRequests >= Requests.size()) {
+ if (Generation == std::numeric_limits<ui32>::max()) {
+ ui64 StateStorageId = StateStorageGroupFromTabletID(TabletStorageInfo->TabletID);
const TActorId proxyActorID = MakeStateStorageProxyID(StateStorageId);
- ctx.Send(proxyActorID, new TEvStateStorage::TEvDelete(TabletStorageInfo->TabletID));
- }
+ ctx.Send(proxyActorID, new TEvStateStorage::TEvDelete(TabletStorageInfo->TabletID));
+ }
ReplyAndDie(NKikimrProto::OK, ctx);
- }
- break;
- default:
- ++ErrorCount;
- if (ErrorCount >= Requests.size() * MAX_ATTEMPTS) {
- return ReplyAndDie(NKikimrProto::ERROR, ctx);
- }
- SendRequest(ev->Cookie, ctx);
- break;
- }
- }
-
- void Handle(TEvStateStorage::TEvDeleteResult::TPtr& ev, const TActorContext& ctx) {
- ReplyAndDie(ev->Get()->Status, ctx);
- }
-
- STFUNC(StateWait) {
- switch (ev->GetTypeRewrite()) {
- HFunc(TEvBlobStorage::TEvCollectGarbageResult, Handle);
- HFunc(TEvStateStorage::TEvDeleteResult, Handle);
+ }
+ break;
+ default:
+ ++ErrorCount;
+ if (ErrorCount >= Requests.size() * MAX_ATTEMPTS) {
+ return ReplyAndDie(NKikimrProto::ERROR, ctx);
+ }
+ SendRequest(ev->Cookie, ctx);
+ break;
+ }
+ }
+
+ void Handle(TEvStateStorage::TEvDeleteResult::TPtr& ev, const TActorContext& ctx) {
+ ReplyAndDie(ev->Get()->Status, ctx);
+ }
+
+ STFUNC(StateWait) {
+ switch (ev->GetTypeRewrite()) {
+ HFunc(TEvBlobStorage::TEvCollectGarbageResult, Handle);
+ HFunc(TEvStateStorage::TEvDeleteResult, Handle);
HFunc(TEvents::TEvUndelivered, Handle);
- }
- }
-
-public:
+ }
+ }
+
+public:
static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
return NKikimrServices::TActivity::TABLET_REQ_DELETE_TABLET;
- }
-
+ }
+
TTabletReqDelete(const TActorId &owner, const TIntrusivePtr<TTabletStorageInfo>& tabletStorageInfo, ui32 generation = std::numeric_limits<ui32>::max())
- : Owner(owner)
- , TabletStorageInfo(tabletStorageInfo)
- , FinishedRequests(0)
- , ErrorCount(0)
- , Generation(generation)
- {}
-
- void Bootstrap(const TActorContext& ctx) {
- GenerateRequests();
- for (std::size_t i = 0; i < Requests.size(); ++i) {
- SendRequest(i, ctx);
- }
- Become(&TTabletReqDelete::StateWait);
- }
-};
-
+ : Owner(owner)
+ , TabletStorageInfo(tabletStorageInfo)
+ , FinishedRequests(0)
+ , ErrorCount(0)
+ , Generation(generation)
+ {}
+
+ void Bootstrap(const TActorContext& ctx) {
+ GenerateRequests();
+ for (std::size_t i = 0; i < Requests.size(); ++i) {
+ SendRequest(i, ctx);
+ }
+ Become(&TTabletReqDelete::StateWait);
+ }
+};
+
IActor* CreateTabletReqDelete(const TActorId &owner, const TIntrusivePtr<TTabletStorageInfo>& tabletStorageInfo, ui32 generation) {
- return new TTabletReqDelete(owner, tabletStorageInfo, generation);
-}
-
-}
+ return new TTabletReqDelete(owner, tabletStorageInfo, generation);
+}
+
+}
diff --git a/ydb/core/tablet/tablet_req_rebuildhistory.cpp b/ydb/core/tablet/tablet_req_rebuildhistory.cpp
index 534ba6e1378..c0b4c0c2bc1 100644
--- a/ydb/core/tablet/tablet_req_rebuildhistory.cpp
+++ b/ydb/core/tablet/tablet_req_rebuildhistory.cpp
@@ -199,7 +199,7 @@ class TTabletReqRebuildHistoryGraph : public TActorBootstrapped<TTabletReqRebuil
TSet<TLogoBlobID> RangesToDiscover;
ui32 RequestsLeft;
- NMetrics::TTabletThroughputRawValue GroupReadBytes;
+ NMetrics::TTabletThroughputRawValue GroupReadBytes;
NMetrics::TTabletIopsRawValue GroupReadOps;
THolder<NTracing::ITrace> IntrospectionTrace;
@@ -453,9 +453,9 @@ class TTabletReqRebuildHistoryGraph : public TActorBootstrapped<TTabletReqRebuil
for (TVector<TEvBlobStorage::TEvRangeResult::TResponse>::iterator it = msg->Responses.begin(), end = msg->Responses.end(); it != end; ++it) {
const TLogoBlobID &id = it->Id;
- GroupReadBytes[std::make_pair(id.Channel(), msg->GroupId)] += it->Buffer.size();
+ GroupReadBytes[std::make_pair(id.Channel(), msg->GroupId)] += it->Buffer.size();
GroupReadOps[std::make_pair(id.Channel(), msg->GroupId)] += 1;
-
+
NKikimrTabletBase::TTabletLogEntry logEntry;
if (!logEntry.ParseFromString(it->Buffer)) {
BLOG_ERROR("TTabletReqRebuildHistoryGraph::ApplyDiscoveryRange it->Buffer ParseFromString error, id# " << id);
@@ -577,7 +577,7 @@ class TTabletReqRebuildHistoryGraph : public TActorBootstrapped<TTabletReqRebuil
switch (response.Status) {
case NKikimrProto::OK:
Y_VERIFY(1 == RefsToCheck.erase(response.Id));
- GroupReadBytes[std::make_pair(response.Id.Channel(), msg->GroupId)] += response.Buffer.size();
+ GroupReadBytes[std::make_pair(response.Id.Channel(), msg->GroupId)] += response.Buffer.size();
GroupReadOps[std::make_pair(response.Id.Channel(), msg->GroupId)] += 1;
break;
case NKikimrProto::NODATA:
diff --git a/ydb/core/tablet/tablet_req_reset.cpp b/ydb/core/tablet/tablet_req_reset.cpp
index d0f41bd3714..b73c68c120f 100644
--- a/ydb/core/tablet/tablet_req_reset.cpp
+++ b/ydb/core/tablet/tablet_req_reset.cpp
@@ -1,37 +1,37 @@
-#include "tablet_impl.h"
-#include "tablet_sys.h"
+#include "tablet_impl.h"
+#include "tablet_sys.h"
#include <ydb/core/base/logoblob.h>
#include <library/cpp/actors/core/actor_bootstrapped.h>
#include <library/cpp/actors/core/hfunc.h>
-
-namespace NKikimr {
-
-class TTabletReqReset : public TActorBootstrapped<TTabletReqReset> {
+
+namespace NKikimr {
+
+class TTabletReqReset : public TActorBootstrapped<TTabletReqReset> {
const TActorId Owner;
- const TIntrusivePtr<TTabletStorageInfo> TabletStorageInfo;
- ui32 Generation = 0;
+ const TIntrusivePtr<TTabletStorageInfo> TabletStorageInfo;
+ ui32 Generation = 0;
TActorId CurrentLeader;
-
- void ReplyAndDie(NKikimrProto::EReplyStatus status, const TActorContext& ctx) {
- ctx.Send(Owner, new TEvTablet::TEvResetTabletResult(status, TabletStorageInfo->TabletID));
- Die(ctx);
- }
-
- void Handle(TEvStateStorage::TEvInfo::TPtr& ev, const TActorContext&) {
+
+ void ReplyAndDie(NKikimrProto::EReplyStatus status, const TActorContext& ctx) {
+ ctx.Send(Owner, new TEvTablet::TEvResetTabletResult(status, TabletStorageInfo->TabletID));
+ Die(ctx);
+ }
+
+ void Handle(TEvStateStorage::TEvInfo::TPtr& ev, const TActorContext&) {
CurrentLeader = ev->Get()->CurrentLeader;
- Generation = std::max(Generation, ev->Get()->CurrentGeneration);
- }
-
+ Generation = std::max(Generation, ev->Get()->CurrentGeneration);
+ }
+
void FindLatestLogEntry(const TActorContext& ctx) {
ctx.Register(CreateTabletFindLastEntry(ctx.SelfID, false, TabletStorageInfo.Get(), 0));
Become(&TTabletReqReset::StateDiscover);
}
- void Handle(TEvTabletBase::TEvFindLatestLogEntryResult::TPtr& ev, const TActorContext& ctx) {
- if (ev->Get()->Status != NKikimrProto::OK) {
- return ReplyAndDie(ev->Get()->Status, ctx);
- }
- Generation = std::max(Generation, ev->Get()->Latest.Generation());
+ void Handle(TEvTabletBase::TEvFindLatestLogEntryResult::TPtr& ev, const TActorContext& ctx) {
+ if (ev->Get()->Status != NKikimrProto::OK) {
+ return ReplyAndDie(ev->Get()->Status, ctx);
+ }
+ Generation = std::max(Generation, ev->Get()->Latest.Generation());
AdjustGeneration();
BlockBlobStorage(ctx);
}
@@ -44,94 +44,94 @@ class TTabletReqReset : public TActorBootstrapped<TTabletReqReset> {
void BlockBlobStorage(const TActorContext& ctx) {
ctx.Register(CreateTabletReqBlockBlobStorage(ctx.SelfID, TabletStorageInfo.Get(), Generation, false));
- Become(&TTabletReqReset::StateBlockBlobStorage);
- }
-
- void Handle(TEvTabletBase::TEvBlockBlobStorageResult::TPtr& ev, const TActorContext& ctx) {
+ Become(&TTabletReqReset::StateBlockBlobStorage);
+ }
+
+ void Handle(TEvTabletBase::TEvBlockBlobStorageResult::TPtr& ev, const TActorContext& ctx) {
if (ev->Get()->Status == NKikimrProto::RACE) {
- ++Generation;
+ ++Generation;
ctx.Register(CreateTabletReqBlockBlobStorage(ctx.SelfID, TabletStorageInfo.Get(), Generation, false));
- return;
- }
- if (ev->Get()->Status != NKikimrProto::OK) {
- return ReplyAndDie(ev->Get()->Status, ctx);
- }
+ return;
+ }
+ if (ev->Get()->Status != NKikimrProto::OK) {
+ return ReplyAndDie(ev->Get()->Status, ctx);
+ }
TTablet::ExternalWriteZeroEntry(TabletStorageInfo.Get(), Generation + 1, SelfId());
- Become(&TTabletReqReset::StateWriteZeroEntry);
- }
-
- void Handle(TEvTabletBase::TEvWriteLogResult::TPtr& ev, const TActorContext& ctx) {
- if (ev->Get()->Status != NKikimrProto::OK) {
- return ReplyAndDie(ev->Get()->Status, ctx);
- }
- ctx.Register(CreateTabletReqDelete(ctx.SelfID, TabletStorageInfo, Generation));
- Become(&TTabletReqReset::StateDeleteTablet);
- }
-
- void Handle(TEvTabletBase::TEvDeleteTabletResult::TPtr& ev, const TActorContext& ctx) {
+ Become(&TTabletReqReset::StateWriteZeroEntry);
+ }
+
+ void Handle(TEvTabletBase::TEvWriteLogResult::TPtr& ev, const TActorContext& ctx) {
+ if (ev->Get()->Status != NKikimrProto::OK) {
+ return ReplyAndDie(ev->Get()->Status, ctx);
+ }
+ ctx.Register(CreateTabletReqDelete(ctx.SelfID, TabletStorageInfo, Generation));
+ Become(&TTabletReqReset::StateDeleteTablet);
+ }
+
+ void Handle(TEvTabletBase::TEvDeleteTabletResult::TPtr& ev, const TActorContext& ctx) {
if (CurrentLeader) {
ctx.Send(CurrentLeader, new TEvents::TEvPoisonPill());
- }
- ReplyAndDie(ev->Get()->Status, ctx);
- }
-
- // 1
- STFUNC(StateDiscover) {
- switch (ev->GetTypeRewrite()) {
- HFunc(TEvTabletBase::TEvFindLatestLogEntryResult, Handle); // latest log entry discovered
- HFunc(TEvStateStorage::TEvInfo, Handle); // reply from state storage
- }
- }
- // 2
- STFUNC(StateBlockBlobStorage) {
- switch (ev->GetTypeRewrite()) {
- HFunc(TEvTabletBase::TEvBlockBlobStorageResult, Handle); // blob storage blocked
- HFunc(TEvStateStorage::TEvInfo, Handle); // reply from state storage
- }
- }
- // 3
- STFUNC(StateWriteZeroEntry) {
- switch (ev->GetTypeRewrite()) {
- HFunc(TEvTabletBase::TEvWriteLogResult, Handle); // zero entry written
- HFunc(TEvStateStorage::TEvInfo, Handle); // reply from state storage
- }
- }
- // 4
- STFUNC(StateDeleteTablet) {
- switch (ev->GetTypeRewrite()) {
- HFunc(TEvTabletBase::TEvDeleteTabletResult, Handle); // tablet data deleted
- HFunc(TEvStateStorage::TEvInfo, Handle); // reply from state storage
- }
- }
-
-public:
+ }
+ ReplyAndDie(ev->Get()->Status, ctx);
+ }
+
+ // 1
+ STFUNC(StateDiscover) {
+ switch (ev->GetTypeRewrite()) {
+ HFunc(TEvTabletBase::TEvFindLatestLogEntryResult, Handle); // latest log entry discovered
+ HFunc(TEvStateStorage::TEvInfo, Handle); // reply from state storage
+ }
+ }
+ // 2
+ STFUNC(StateBlockBlobStorage) {
+ switch (ev->GetTypeRewrite()) {
+ HFunc(TEvTabletBase::TEvBlockBlobStorageResult, Handle); // blob storage blocked
+ HFunc(TEvStateStorage::TEvInfo, Handle); // reply from state storage
+ }
+ }
+ // 3
+ STFUNC(StateWriteZeroEntry) {
+ switch (ev->GetTypeRewrite()) {
+ HFunc(TEvTabletBase::TEvWriteLogResult, Handle); // zero entry written
+ HFunc(TEvStateStorage::TEvInfo, Handle); // reply from state storage
+ }
+ }
+ // 4
+ STFUNC(StateDeleteTablet) {
+ switch (ev->GetTypeRewrite()) {
+ HFunc(TEvTabletBase::TEvDeleteTabletResult, Handle); // tablet data deleted
+ HFunc(TEvStateStorage::TEvInfo, Handle); // reply from state storage
+ }
+ }
+
+public:
static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
return NKikimrServices::TActivity::TABLET_REQ_DELETE_TABLET;
- }
-
+ }
+
TTabletReqReset(const TActorId& owner, const TIntrusivePtr<TTabletStorageInfo>& tabletStorageInfo, ui32 knownGeneration)
- : Owner(owner)
- , TabletStorageInfo(tabletStorageInfo)
+ : Owner(owner)
+ , TabletStorageInfo(tabletStorageInfo)
, Generation(knownGeneration)
- {
- Y_VERIFY(!TabletStorageInfo->Channels.empty());
- Y_VERIFY(TabletStorageInfo->Channels[0].LatestEntry() != nullptr);
- }
-
- void Bootstrap(const TActorContext& ctx) {
+ {
+ Y_VERIFY(!TabletStorageInfo->Channels.empty());
+ Y_VERIFY(TabletStorageInfo->Channels[0].LatestEntry() != nullptr);
+ }
+
+ void Bootstrap(const TActorContext& ctx) {
TActorId stateStorageProxyId = MakeStateStorageProxyID(StateStorageGroupFromTabletID(TabletStorageInfo->TabletID));
- ctx.Send(stateStorageProxyId, new TEvStateStorage::TEvLookup(TabletStorageInfo->TabletID, 0));
+ ctx.Send(stateStorageProxyId, new TEvStateStorage::TEvLookup(TabletStorageInfo->TabletID, 0));
if (Generation == 0) {
FindLatestLogEntry(ctx);
} else {
AdjustGeneration();
BlockBlobStorage(ctx);
}
- }
-};
-
+ }
+};
+
IActor* CreateTabletReqReset(const TActorId& owner, const TIntrusivePtr<NKikimr::TTabletStorageInfo>& info, ui32 knownGeneration) {
return new TTabletReqReset(owner, info, knownGeneration);
-}
-
-}
+}
+
+}
diff --git a/ydb/core/tablet/tablet_req_writelog.cpp b/ydb/core/tablet/tablet_req_writelog.cpp
index 9f95d97de88..7c4d02c405c 100644
--- a/ydb/core/tablet/tablet_req_writelog.cpp
+++ b/ydb/core/tablet/tablet_req_writelog.cpp
@@ -16,7 +16,7 @@ class TTabletReqWriteLog : public TActorBootstrapped<TTabletReqWriteLog> {
const TEvBlobStorage::TEvPut::ETactic CommitTactic;
TIntrusivePtr<TTabletStorageInfo> Info;
- NMetrics::TTabletThroughputRawValue GroupWrittenBytes;
+ NMetrics::TTabletThroughputRawValue GroupWrittenBytes;
NMetrics::TTabletIopsRawValue GroupWrittenOps;
ui64 RequestCookies = 0;
@@ -44,9 +44,9 @@ class TTabletReqWriteLog : public TActorBootstrapped<TTabletReqWriteLog> {
case NKikimrProto::OK:
LOG_DEBUG_S(ctx, NKikimrServices::TABLET_MAIN, "Put Result: " << msg->Print(false));
- GroupWrittenBytes[std::make_pair(msg->Id.Channel(), msg->GroupId)] += msg->Id.BlobSize();
+ GroupWrittenBytes[std::make_pair(msg->Id.Channel(), msg->GroupId)] += msg->Id.BlobSize();
GroupWrittenOps[std::make_pair(msg->Id.Channel(), msg->GroupId)] += 1;
-
+
ResponseCookies ^= ev->Cookie;
if (--RepliesToWait == 0) {
diff --git a/ydb/core/tablet/tablet_resolver.cpp b/ydb/core/tablet/tablet_resolver.cpp
index 7562c239c7d..c0a39a2216b 100644
--- a/ydb/core/tablet/tablet_resolver.cpp
+++ b/ydb/core/tablet/tablet_resolver.cpp
@@ -696,7 +696,7 @@ class TTabletResolver : public TActorBootstrapped<TTabletResolver> {
case TEntry::StProblemPing:
if (ev->Sender == entry.KnownLeader) {
entry.Cookie.Detach();
- entry.State = TEntry::StNormal;
+ entry.State = TEntry::StNormal;
SendQueued(tabletId, entry, ctx);
MoveEntryToResolved(tabletId, *entryHolder);
}
diff --git a/ydb/core/tablet/tablet_sys.cpp b/ydb/core/tablet/tablet_sys.cpp
index 00c7eb2750e..44bfac7b2d6 100644
--- a/ydb/core/tablet/tablet_sys.cpp
+++ b/ydb/core/tablet/tablet_sys.cpp
@@ -57,9 +57,9 @@ void TTablet::ReportTabletStateChange(ETabletState state) {
const TActorId tabletStateServiceId = NNodeWhiteboard::MakeNodeWhiteboardServiceId(SelfId().NodeId());
if (state == TTabletStateInfo::Created || state == TTabletStateInfo::ResolveLeader) {
Send(tabletStateServiceId, new NNodeWhiteboard::TEvWhiteboard::TEvTabletStateUpdate(TabletID(), FollowerId, state, Info, StateStorageInfo.KnownGeneration, Leader));
- } else {
+ } else {
Send(tabletStateServiceId, new NNodeWhiteboard::TEvWhiteboard::TEvTabletStateUpdate(TabletID(), FollowerId, state, StateStorageInfo.KnownGeneration));
- }
+ }
}
void TTablet::PromoteToCandidate(ui32 gen) {
@@ -155,7 +155,7 @@ void TTablet::WriteZeroEntry(TEvTablet::TDependencyGraph *graph) {
Y_VERIFY(gen == lastGeneration);
lastInGeneration = step;
-
+
if (it->IsSnapshot) {
snapshot = std::pair<ui32, ui32>(gen, step);
snapIterator = it;
@@ -945,20 +945,20 @@ void TTablet::HandleRebuildGraphResult(TEvTabletBase::TEvRebuildGraphResult::TPt
if (IntrospectionTrace) {
IntrospectionTrace->Attach(MakeHolder<NTracing::TOnRebuildGraphResult>(msg->Trace.Get()));
}
- TIntrusivePtr<TEvTablet::TDependencyGraph> graph;
+ TIntrusivePtr<TEvTablet::TDependencyGraph> graph;
switch (msg->Status) {
case NKikimrProto::OK:
- graph = msg->DependencyGraph;
- break;
+ graph = msg->DependencyGraph;
+ break;
case NKikimrProto::NODATA:
- graph = new TEvTablet::TDependencyGraph(std::pair<ui32, ui32>(0, 0));
- break;
+ graph = new TEvTablet::TDependencyGraph(std::pair<ui32, ui32>(0, 0));
+ break;
default:
- break;
- }
- switch (msg->Status) {
- case NKikimrProto::OK:
- case NKikimrProto::NODATA:
+ break;
+ }
+ switch (msg->Status) {
+ case NKikimrProto::OK:
+ case NKikimrProto::NODATA:
WriteZeroEntry(graph.Get());
Send(UserTablet,
new TEvTablet::TEvBoot(TabletID(), StateStorageInfo.KnownGeneration,
@@ -966,8 +966,8 @@ void TTablet::HandleRebuildGraphResult(TEvTabletBase::TEvRebuildGraphResult::TPt
TxCacheQuota,
std::move(msg->GroupReadBytes),
std::move(msg->GroupReadOps)));
- return;
- default:
+ return;
+ default:
{
BLOG_ERROR("HandleRebuildGraphResult, msg->Status: " << NKikimrProto::EReplyStatus_Name(msg->Status));
return CancelTablet(TEvTablet::TEvTabletDead::ReasonBootBSError, msg->ErrorReason);
@@ -1754,7 +1754,7 @@ void TTablet::CancelTablet(TEvTablet::TEvTabletDead::EReason reason, const TStri
if (FollowerStStGuardian)
Send(FollowerStStGuardian, new TEvents::TEvPoisonPill());
-
+
if (RebuildGraphRequest)
Send(RebuildGraphRequest, new TEvents::TEvPoisonPill());
@@ -1836,7 +1836,7 @@ TTablet::TTablet(const TActorId &launcher, TTabletStorageInfo *info, TTabletSetu
, ResourceProfiles(profiles)
, TxCacheQuota(txCacheQuota)
{
- Y_VERIFY(!info->Channels.empty() && !info->Channels[0].History.empty());
+ Y_VERIFY(!info->Channels.empty() && !info->Channels[0].History.empty());
Y_VERIFY(TTabletTypes::TYPE_INVALID != info->TabletType);
}
@@ -1906,14 +1906,14 @@ void TTablet::Bootstrap() {
void TTablet::ExternalWriteZeroEntry(TTabletStorageInfo *info, ui32 gen, TActorIdentity owner) {
THolder<NKikimrTabletBase::TTabletLogEntry> entry = MakeHolder<NKikimrTabletBase::TTabletLogEntry>();
- entry->SetSnapshot(MakeGenStepPair(0, 0));
- entry->SetZeroConfirmed(MakeGenStepPair(0, 0));
- entry->SetZeroTailSz(0);
- TLogoBlobID logid(info->TabletID, gen, 0, 0, 0, 0);
+ entry->SetSnapshot(MakeGenStepPair(0, 0));
+ entry->SetZeroConfirmed(MakeGenStepPair(0, 0));
+ entry->SetZeroTailSz(0);
+ TLogoBlobID logid(info->TabletID, gen, 0, 0, 0, 0);
TVector<TEvTablet::TLogEntryReference> refs;
TActivationContext::Register(CreateTabletReqWriteLog(owner, logid, entry.Release(), refs, TEvBlobStorage::TEvPut::TacticDefault, info));
-}
-
+}
+
TActorId TTabletSetupInfo::Apply(TTabletStorageInfo *info, TActorIdentity owner) {
return TActivationContext::Register(Op(owner, info), owner, MailboxType, PoolId);
}
diff --git a/ydb/core/tablet/tablet_sys.h b/ydb/core/tablet/tablet_sys.h
index 2fa10b9c2f7..661d75a4e0a 100644
--- a/ydb/core/tablet/tablet_sys.h
+++ b/ydb/core/tablet/tablet_sys.h
@@ -11,9 +11,9 @@
namespace NKikimr {
-class TTablet : public TActor<TTablet> {
- using TTabletStateInfo = NKikimrWhiteboard::TTabletStateInfo;
- using ETabletState = TTabletStateInfo::ETabletState;
+class TTablet : public TActor<TTablet> {
+ using TTabletStateInfo = NKikimrWhiteboard::TTabletStateInfo;
+ using ETabletState = TTabletStateInfo::ETabletState;
struct TStateStorageInfo {
TActorId ProxyID;
@@ -87,7 +87,7 @@ class TTablet : public TActor<TTablet> {
THolder<TFollowerUpdate> FollowerUpdate;
TVector<TString> FollowerAuxUpdates;
- NMetrics::TTabletThroughputRawValue GroupWrittenBytes;
+ NMetrics::TTabletThroughputRawValue GroupWrittenBytes;
NMetrics::TTabletIopsRawValue GroupWrittenOps;
TVector<ui32> YellowMoveChannels;
@@ -597,16 +597,16 @@ public:
return NKikimrServices::TActivity::TABLET_ACTOR;
}
- TTablet(
+ TTablet(
const TActorId &launcher,
- TTabletStorageInfo *info,
- TTabletSetupInfo *setupInfo,
+ TTabletStorageInfo *info,
+ TTabletSetupInfo *setupInfo,
bool leader,
ui32 suggestedGeneration, // when leader == true
ui32 followerID, // when leader == false
TResourceProfilesPtr profiles = nullptr,
TSharedQuotaPtr txCacheQuota = nullptr
- );
+ );
TAutoPtr<IEventHandle> AfterRegister(const TActorId &self, const TActorId &parentId) override;
static void ExternalWriteZeroEntry(TTabletStorageInfo *info, ui32 gen, TActorIdentity owner);
diff --git a/ydb/core/tablet/ut/ya.make b/ydb/core/tablet/ut/ya.make
index 323f832fc24..52440600e13 100644
--- a/ydb/core/tablet/ut/ya.make
+++ b/ydb/core/tablet/ut/ya.make
@@ -23,7 +23,7 @@ PEERDIR(
YQL_LAST_ABI_VERSION()
SRCS(
- pipe_tracker_ut.cpp
+ pipe_tracker_ut.cpp
resource_broker_ut.cpp
tablet_counters_aggregator_ut.cpp
tablet_metrics_ut.cpp
diff --git a/ydb/core/tablet/ya.make b/ydb/core/tablet/ya.make
index 74401abbe52..25e611b4085 100644
--- a/ydb/core/tablet/ya.make
+++ b/ydb/core/tablet/ya.make
@@ -8,11 +8,11 @@ OWNER(
SRCS(
defs.h
- node_tablet_monitor.cpp
- node_tablet_monitor.h
- node_whiteboard.cpp
- pipe_tracker.cpp
- pipe_tracker.h
+ node_tablet_monitor.cpp
+ node_tablet_monitor.h
+ node_whiteboard.cpp
+ pipe_tracker.cpp
+ pipe_tracker.h
resource_broker.cpp
resource_broker.h
resource_broker_impl.h
@@ -29,8 +29,8 @@ SRCS(
tablet_tracing_signals.h
tablet_list_renderer.cpp
tablet_list_renderer.h
- tablet_metrics.h
- tablet_metrics.cpp
+ tablet_metrics.h
+ tablet_metrics.cpp
tablet_monitoring_proxy.cpp
tablet_monitoring_proxy.h
tablet_pipecache.cpp
@@ -39,10 +39,10 @@ SRCS(
tablet_pipe_client_cache.h
tablet_pipe_server.cpp
tablet_req_blockbs.cpp
- tablet_req_delete.cpp
+ tablet_req_delete.cpp
tablet_req_findlatest.cpp
tablet_req_rebuildhistory.cpp
- tablet_req_reset.cpp
+ tablet_req_reset.cpp
tablet_req_writelog.cpp
tablet_resolver.cpp
tablet_responsiveness_pinger.cpp
diff --git a/ydb/core/tablet_flat/flat_cxx_database.h b/ydb/core/tablet_flat/flat_cxx_database.h
index f494c771106..27a260bcb27 100644
--- a/ydb/core/tablet_flat/flat_cxx_database.h
+++ b/ydb/core/tablet_flat/flat_cxx_database.h
@@ -1,5 +1,5 @@
-#pragma once
-
+#pragma once
+
#include <ydb/core/tablet_flat/flat_database.h>
#include <ydb/core/util/tuples.h>
#include <ydb/core/util/templates.h>
@@ -8,146 +8,146 @@
#include <util/system/unaligned_mem.h>
#include <library/cpp/containers/stack_vector/stack_vec.h>
#include <utility>
-
+
#include <cxxabi.h>
-// https://wiki.yandex-team.ru/kikimr/techdoc/db/cxxapi/nicedb/
-
-namespace NKikimr {
-namespace NIceDb {
-
+// https://wiki.yandex-team.ru/kikimr/techdoc/db/cxxapi/nicedb/
+
+namespace NKikimr {
+namespace NIceDb {
+
using TToughDb = NTable::TDatabase;
using NTable::TUpdateOp;
using NTable::ELookup;
-
-class TTypeValue : public TRawTypeValue {
-public:
- TTypeValue() // null
- {}
-
- TTypeValue(const ui64& value, NScheme::TTypeId type = NScheme::NTypeIds::Uint64)
- : TRawTypeValue(&value, sizeof(value), type)
- {}
-
- TTypeValue(const i64& value, NScheme::TTypeId type = NScheme::NTypeIds::Int64)
- : TRawTypeValue(&value, sizeof(value), type)
- {}
-
- TTypeValue(const ui32& value, NScheme::TTypeId type = NScheme::NTypeIds::Uint32)
- : TRawTypeValue(&value, sizeof(value), type)
- {}
-
- TTypeValue(const i32& value, NScheme::TTypeId type = NScheme::NTypeIds::Int32)
- : TRawTypeValue(&value, sizeof(value), type)
- {}
-
+
+class TTypeValue : public TRawTypeValue {
+public:
+ TTypeValue() // null
+ {}
+
+ TTypeValue(const ui64& value, NScheme::TTypeId type = NScheme::NTypeIds::Uint64)
+ : TRawTypeValue(&value, sizeof(value), type)
+ {}
+
+ TTypeValue(const i64& value, NScheme::TTypeId type = NScheme::NTypeIds::Int64)
+ : TRawTypeValue(&value, sizeof(value), type)
+ {}
+
+ TTypeValue(const ui32& value, NScheme::TTypeId type = NScheme::NTypeIds::Uint32)
+ : TRawTypeValue(&value, sizeof(value), type)
+ {}
+
+ TTypeValue(const i32& value, NScheme::TTypeId type = NScheme::NTypeIds::Int32)
+ : TRawTypeValue(&value, sizeof(value), type)
+ {}
+
TTypeValue(const ui16& value, NScheme::TTypeId type = NScheme::NTypeIds::Date)
: TRawTypeValue(&value, sizeof(value), type)
{}
- TTypeValue(const ui8& value, NScheme::TTypeId type = NScheme::NTypeIds::Byte)
- : TRawTypeValue(&value, sizeof(value), type)
- {}
-
- TTypeValue(const bool& value, NScheme::TTypeId type = NScheme::NTypeIds::Bool)
- : TRawTypeValue(&value, sizeof(value), type)
- {}
-
+ TTypeValue(const ui8& value, NScheme::TTypeId type = NScheme::NTypeIds::Byte)
+ : TRawTypeValue(&value, sizeof(value), type)
+ {}
+
+ TTypeValue(const bool& value, NScheme::TTypeId type = NScheme::NTypeIds::Bool)
+ : TRawTypeValue(&value, sizeof(value), type)
+ {}
+
TTypeValue(const double& value, NScheme::TTypeId type = NScheme::NTypeIds::Double)
: TRawTypeValue(&value, sizeof(value), type)
{}
template <typename ElementType>
- TTypeValue(const TVector<ElementType> &value, NScheme::TTypeId type = NScheme::NTypeIds::String)
- : TRawTypeValue(value.empty() ? (const ElementType*)0xDEADBEEFDEADBEEF : value.data(), value.size() * sizeof(ElementType), type)
- {}
-
+ TTypeValue(const TVector<ElementType> &value, NScheme::TTypeId type = NScheme::NTypeIds::String)
+ : TRawTypeValue(value.empty() ? (const ElementType*)0xDEADBEEFDEADBEEF : value.data(), value.size() * sizeof(ElementType), type)
+ {}
+
TTypeValue(const TActorId& value, NScheme::TTypeId type = NScheme::NTypeIds::ActorId)
- : TRawTypeValue(&value, sizeof(value), type)
- {}
-
- TTypeValue(const std::pair<ui64, ui64>& value, NScheme::TTypeId type = NScheme::NTypeIds::PairUi64Ui64)
- : TRawTypeValue(&value, sizeof(value), type)
- {}
-
+ : TRawTypeValue(&value, sizeof(value), type)
+ {}
+
+ TTypeValue(const std::pair<ui64, ui64>& value, NScheme::TTypeId type = NScheme::NTypeIds::PairUi64Ui64)
+ : TRawTypeValue(&value, sizeof(value), type)
+ {}
+
TTypeValue(const std::pair<ui64, i64>& value, NScheme::TTypeId type = NScheme::NTypeIds::Decimal)
: TRawTypeValue(&value, sizeof(value), type)
{}
- TTypeValue(const TString& value, NScheme::TTypeId type = NScheme::NTypeIds::Utf8)
- : TRawTypeValue(value.data(), value.size(), type)
- {}
-
- TTypeValue(const TBuffer& value, NScheme::TTypeId type = NScheme::NTypeIds::String)
- : TRawTypeValue(value.Empty() ? (const char*)0xDEADBEEFDEADBEEF : value.Data(), value.Size(), type)
- {}
-
- TTypeValue(const TStringBuf& value, NScheme::TTypeId type = NScheme::NTypeIds::String)
+ TTypeValue(const TString& value, NScheme::TTypeId type = NScheme::NTypeIds::Utf8)
+ : TRawTypeValue(value.data(), value.size(), type)
+ {}
+
+ TTypeValue(const TBuffer& value, NScheme::TTypeId type = NScheme::NTypeIds::String)
+ : TRawTypeValue(value.Empty() ? (const char*)0xDEADBEEFDEADBEEF : value.Data(), value.Size(), type)
+ {}
+
+ TTypeValue(const TStringBuf& value, NScheme::TTypeId type = NScheme::NTypeIds::String)
: TRawTypeValue(value.empty() ? (const char*)0xDEADBEEFDEADBEEF : value.data(), value.size(), type)
- {}
-
- explicit TTypeValue(const TRawTypeValue& rawTypeValue)
- : TRawTypeValue(rawTypeValue)
- {}
-
- explicit TTypeValue(std::nullptr_t)
- : TRawTypeValue()
- {}
-
- operator TCell() const {
- return TCell(this);
- }
-
- bool HaveValue() const {
- return Data() != nullptr;
- }
-
- operator ui64() const {
+ {}
+
+ explicit TTypeValue(const TRawTypeValue& rawTypeValue)
+ : TRawTypeValue(rawTypeValue)
+ {}
+
+ explicit TTypeValue(std::nullptr_t)
+ : TRawTypeValue()
+ {}
+
+ operator TCell() const {
+ return TCell(this);
+ }
+
+ bool HaveValue() const {
+ return Data() != nullptr;
+ }
+
+ operator ui64() const {
Y_VERIFY((Type() == NScheme::NTypeIds::Uint64
|| Type() == NScheme::NTypeIds::Timestamp)
&& Size() == sizeof(ui64), "Data=%" PRIxPTR ", Type=%" PRIi64 ", Size=%" PRIi64, (ui64)Data(), (i64)Type(), (i64)Size());
return ReadUnaligned<ui64>(reinterpret_cast<const ui64*>(Data()));
- }
-
- operator i64() const {
+ }
+
+ operator i64() const {
Y_VERIFY((Type() == NScheme::NTypeIds::Int64
|| Type() == NScheme::NTypeIds::Interval)
&& Size() == sizeof(i64), "Data=%" PRIxPTR ", Type=%" PRIi64 ", Size=%" PRIi64, (ui64)Data(), (i64)Type(), (i64)Size());
return ReadUnaligned<i64>(reinterpret_cast<const i64*>(Data()));
- }
-
- operator ui32() const {
+ }
+
+ operator ui32() const {
Y_VERIFY((Type() == NScheme::NTypeIds::Uint32
|| Type() == NScheme::NTypeIds::Datetime)
&& Size() == sizeof(ui32), "Data=%" PRIxPTR ", Type=%" PRIi64 ", Size=%" PRIi64, (ui64)Data(), (i64)Type(), (i64)Size());
ui32 value = ReadUnaligned<ui32>(reinterpret_cast<const ui32*>(Data()));
- return value;
- }
-
- operator i32() const {
- Y_VERIFY(Type() == NScheme::NTypeIds::Int32 && Size() == sizeof(i32), "Data=%" PRIxPTR ", Type=%" PRIi64 ", Size=%" PRIi64, (ui64)Data(), (i64)Type(), (i64)Size());
+ return value;
+ }
+
+ operator i32() const {
+ Y_VERIFY(Type() == NScheme::NTypeIds::Int32 && Size() == sizeof(i32), "Data=%" PRIxPTR ", Type=%" PRIi64 ", Size=%" PRIi64, (ui64)Data(), (i64)Type(), (i64)Size());
i32 value = ReadUnaligned<i32>(reinterpret_cast<const i32*>(Data()));
- return value;
- }
-
+ return value;
+ }
+
operator ui16() const {
Y_VERIFY(Type() == NScheme::NTypeIds::Date && Size() == sizeof(ui16), "Data=%" PRIxPTR ", Type=%" PRIi64 ", Size=%" PRIi64, (ui64)Data(), (i64)Type(), (i64)Size());
ui16 value = ReadUnaligned<ui16>(reinterpret_cast<const ui16*>(Data()));
return value;
}
- operator ui8() const {
+ operator ui8() const {
Y_VERIFY(Type() == NScheme::NTypeIds::Byte && Size() == sizeof(ui8), "Data=%" PRIxPTR ", Type=%" PRIi64 ", Size=%" PRIi64, (ui64)Data(), (i64)Type(), (i64)Size());
- ui8 value = *reinterpret_cast<const ui8*>(Data());
- return value;
- }
-
- operator bool() const {
+ ui8 value = *reinterpret_cast<const ui8*>(Data());
+ return value;
+ }
+
+ operator bool() const {
Y_VERIFY(Type() == NScheme::NTypeIds::Bool && Size() == sizeof(bool), "Data=%" PRIxPTR ", Type=%" PRIi64 ", Size=%" PRIi64, (ui64)Data(), (i64)Type(), (i64)Size());
- bool value = *reinterpret_cast<const bool*>(Data());
- return value;
- }
-
+ bool value = *reinterpret_cast<const bool*>(Data());
+ return value;
+ }
+
operator double() const {
Y_VERIFY(Type() == NScheme::NTypeIds::Double && Size() == sizeof(double), "Data=%" PRIxPTR ", Type=%" PRIi64 ", Size=%" PRIi64, (ui64)Data(), (i64)Type(), (i64)Size());
double value = ReadUnaligned<double>(reinterpret_cast<const double*>(Data()));
@@ -160,28 +160,28 @@ public:
|| Type() == NScheme::NTypeIds::String2m
|| Type() == NScheme::NTypeIds::String4k) && Size() == sizeof(TActorId), "Data=%" PRIxPTR ", Type=%" PRIi64 ", Size=%" PRIi64, (ui64)Data(), (i64)Type(), (i64)Size());
return *reinterpret_cast<const TActorId*>(Data());
- }
-
+ }
+
operator TString() const {
Y_VERIFY(Type() == NScheme::NTypeIds::Utf8
|| Type() == NScheme::NTypeIds::String
|| Type() == NScheme::NTypeIds::String2m
|| Type() == NScheme::NTypeIds::String4k, "Data=%" PRIxPTR ", Type=%" PRIi64 ", Size=%" PRIi64, (ui64)Data(), (i64)Type(), (i64)Size());
return TString(reinterpret_cast<const char*>(Data()), Size());
- }
-
- operator TBuffer() const {
+ }
+
+ operator TBuffer() const {
Y_VERIFY(Type() == NScheme::NTypeIds::String
|| Type() == NScheme::NTypeIds::String2m
|| Type() == NScheme::NTypeIds::String4k, "Data=%" PRIxPTR ", Type=%" PRIi64 ", Size=%" PRIi64, (ui64)Data(), (i64)Type(), (i64)Size());
- return TBuffer(reinterpret_cast<const char*>(Data()), Size());
- }
-
- operator std::pair<ui64, ui64>() const {
+ return TBuffer(reinterpret_cast<const char*>(Data()), Size());
+ }
+
+ operator std::pair<ui64, ui64>() const {
Y_VERIFY(Type() == NScheme::NTypeIds::PairUi64Ui64 && Size() == sizeof(std::pair<ui64, ui64>), "Data=%" PRIxPTR ", Type=%" PRIi64 ", Size=%" PRIi64, (ui64)Data(), (i64)Type(), (i64)Size());
- return *reinterpret_cast<const std::pair<ui64, ui64>*>(Data());
- }
-
+ return *reinterpret_cast<const std::pair<ui64, ui64>*>(Data());
+ }
+
operator std::pair<ui64, i64>() const {
Y_VERIFY(Type() == NScheme::NTypeIds::Decimal && Size() == sizeof(std::pair<ui64, ui64>), "Data=%" PRIxPTR ", Type=%" PRIi64 ", Size=%" PRIi64, (ui64)Data(), (i64)Type(), (i64)Size());
return *reinterpret_cast<const std::pair<ui64, i64>*>(Data());
@@ -189,37 +189,37 @@ public:
template <typename ElementType>
operator TVector<ElementType>() const {
- static_assert(std::is_pod<ElementType>::value, "ElementType should be a POD type");
+ static_assert(std::is_pod<ElementType>::value, "ElementType should be a POD type");
Y_VERIFY(Type() == NScheme::NTypeIds::String || Type() == NScheme::NTypeIds::String4k || Type() == NScheme::NTypeIds::String2m);
Y_VERIFY(Size() % sizeof(ElementType) == 0);
- std::size_t count = Size() / sizeof(ElementType);
- const ElementType *begin = reinterpret_cast<const ElementType*>(Data());
- const ElementType *end = begin + count;
+ std::size_t count = Size() / sizeof(ElementType);
+ const ElementType *begin = reinterpret_cast<const ElementType*>(Data());
+ const ElementType *end = begin + count;
return TVector<ElementType>(begin, end);
- }
-
+ }
+
template <typename ElementType>
void ExtractArray(THashSet<ElementType> &container) const {
- static_assert(std::is_pod<ElementType>::value, "ElementType should be a POD type");
+ static_assert(std::is_pod<ElementType>::value, "ElementType should be a POD type");
Y_VERIFY(Type() == NScheme::NTypeIds::String || Type() == NScheme::NTypeIds::String4k || Type() == NScheme::NTypeIds::String2m);
Y_VERIFY(Size() % sizeof(ElementType) == 0);
- const ElementType *begin = reinterpret_cast<const ElementType*>(Data());
- const ElementType *end = begin + Size() / sizeof(ElementType);
- container.resize(Size() / sizeof(ElementType));
- for (auto it = begin; it !=end; ++it) {
- container.insert(*it);
- }
- }
-};
-
-template <NScheme::TTypeId T> struct NSchemeTypeMapper;
-
+ const ElementType *begin = reinterpret_cast<const ElementType*>(Data());
+ const ElementType *end = begin + Size() / sizeof(ElementType);
+ container.resize(Size() / sizeof(ElementType));
+ for (auto it = begin; it !=end; ++it) {
+ container.insert(*it);
+ }
+ }
+};
+
+template <NScheme::TTypeId T> struct NSchemeTypeMapper;
+
template <> struct NSchemeTypeMapper<NScheme::NTypeIds::Bool> { typedef bool Type; };
template <> struct NSchemeTypeMapper<NScheme::NTypeIds::Byte> { typedef ui8 Type; };
template <> struct NSchemeTypeMapper<NScheme::NTypeIds::Uint32> { typedef ui32 Type; };
-template <> struct NSchemeTypeMapper<NScheme::NTypeIds::Int32> { typedef i32 Type; };
+template <> struct NSchemeTypeMapper<NScheme::NTypeIds::Int32> { typedef i32 Type; };
template <> struct NSchemeTypeMapper<NScheme::NTypeIds::Uint64> { typedef ui64 Type; };
-template <> struct NSchemeTypeMapper<NScheme::NTypeIds::Int64> { typedef i64 Type; };
+template <> struct NSchemeTypeMapper<NScheme::NTypeIds::Int64> { typedef i64 Type; };
template <> struct NSchemeTypeMapper<NScheme::NTypeIds::String> { typedef TString Type; };
template <> struct NSchemeTypeMapper<NScheme::NTypeIds::String4k> : NSchemeTypeMapper<NScheme::NTypeIds::String> {};
template <> struct NSchemeTypeMapper<NScheme::NTypeIds::Utf8> { typedef TString Type; };
@@ -231,101 +231,101 @@ template <> struct NSchemeTypeMapper<NScheme::NTypeIds::Date> { typedef ui16 Typ
template <> struct NSchemeTypeMapper<NScheme::NTypeIds::Datetime> { typedef ui32 Type; };
template <> struct NSchemeTypeMapper<NScheme::NTypeIds::Timestamp> { typedef ui64 Type; };
template <> struct NSchemeTypeMapper<NScheme::NTypeIds::Interval> { typedef i64 Type; };
-
-/// only for compatibility with old code
+
+/// only for compatibility with old code
template <NScheme::TTypeId ValType>
class TConvertTypeValue : public TRawTypeValue {
-public:
- TConvertTypeValue(const TRawTypeValue& value)
+public:
+ TConvertTypeValue(const TRawTypeValue& value)
: TRawTypeValue(value.Data(), value.Size(), value.IsEmpty() ? 0 : ValType)
- {}
-
- template <typename ValueType> static typename NSchemeTypeMapper<ValType>::Type ConvertFrom(ValueType value) {
- return static_cast<typename NSchemeTypeMapper<ValType>::Type>(value);
- }
-};
-
-/// only for compatibility with old code
-template <>
-class TConvertTypeValue<NScheme::NTypeIds::String> : public TRawTypeValue {
-public:
- TConvertTypeValue(const TRawTypeValue& value)
- : TRawTypeValue(value.Data(), value.Size(), value.IsEmpty() ? 0 : NScheme::NTypeIds::String)
- {}
-
- static typename NSchemeTypeMapper<NScheme::NTypeIds::String>::Type ConvertFrom(const TString& value) {
- return static_cast<typename NSchemeTypeMapper<NScheme::NTypeIds::String>::Type>(value);
- }
-
+ {}
+
+ template <typename ValueType> static typename NSchemeTypeMapper<ValType>::Type ConvertFrom(ValueType value) {
+ return static_cast<typename NSchemeTypeMapper<ValType>::Type>(value);
+ }
+};
+
+/// only for compatibility with old code
+template <>
+class TConvertTypeValue<NScheme::NTypeIds::String> : public TRawTypeValue {
+public:
+ TConvertTypeValue(const TRawTypeValue& value)
+ : TRawTypeValue(value.Data(), value.Size(), value.IsEmpty() ? 0 : NScheme::NTypeIds::String)
+ {}
+
+ static typename NSchemeTypeMapper<NScheme::NTypeIds::String>::Type ConvertFrom(const TString& value) {
+ return static_cast<typename NSchemeTypeMapper<NScheme::NTypeIds::String>::Type>(value);
+ }
+
static typename NSchemeTypeMapper<NScheme::NTypeIds::String>::Type ConvertFrom(const TStringBuf& value) {
return static_cast<typename NSchemeTypeMapper<NScheme::NTypeIds::String>::Type>(TString(value));
}
- static typename NSchemeTypeMapper<NScheme::NTypeIds::String>::Type ConvertFrom(const ::google::protobuf::Message& value) {
- return static_cast<typename NSchemeTypeMapper<NScheme::NTypeIds::String>::Type>(value.SerializeAsString());
- }
-
- template <typename ElementType>
+ static typename NSchemeTypeMapper<NScheme::NTypeIds::String>::Type ConvertFrom(const ::google::protobuf::Message& value) {
+ return static_cast<typename NSchemeTypeMapper<NScheme::NTypeIds::String>::Type>(value.SerializeAsString());
+ }
+
+ template <typename ElementType>
static typename NSchemeTypeMapper<NScheme::NTypeIds::String>::Type ConvertFrom(const TVector<ElementType>& value) {
- return static_cast<typename NSchemeTypeMapper<NScheme::NTypeIds::String>::Type>(
- TString(
- reinterpret_cast<const char*>(value.data()), value.size() * sizeof(ElementType)
- )
- );
- }
-};
-
-////////////////////////////////////////////////////////////////////////////////////////
-
-/// use the following semantic to define custom rules for database types conversion:
-
-//template <typename ColumnType>
-//struct TConvertValue<ColumnType, TRawTypeValue, TStringBuf> {
-// TRawTypeValue Value;
-//
-// TConvertValue(TStringBuf value)
-// : Value(value.data(), value.size(), ColumnType::ColumnType)
-// {
-// static_assert(ColumnType::ColumnType == NScheme::NTypeIds::String
-// || ColumnType::ColumnType == NScheme::NTypeIds::Utf8,
-// "Unsupported ColumnType for TStringBuf");
-// }
-//
-// operator const TRawTypeValue&() const {
-// return Value;
-// }
-//};
-
-//template <typename ColumnType>
-//struct TConvertValue<ColumnType, TStringBuf, TRawTypeValue> {
-// TStringBuf Value;
-//
-// TConvertValue(const TRawTypeValue& value)
-// : Value(reinterpret_cast<const char*>(value.Data()), value.Size())
-// {
-// Y_VERIFY(value.Type() == NScheme::NTypeIds::String || value.Type() == NScheme::NTypeIds::Utf8);
-// }
-//
-// operator TStringBuf() const {
-// return Value;
-// }
-//};
-
-////////////////////////////////////////////////////////////////////////////////////////
-
-template <typename ColumnType, typename TargetType, typename SourceType>
-struct TConvertValue {
- TargetType Value;
-
- TConvertValue(const SourceType& value)
- : Value(value)
- {}
-
- operator const TargetType&() const {
- return Value;
- }
-};
-
+ return static_cast<typename NSchemeTypeMapper<NScheme::NTypeIds::String>::Type>(
+ TString(
+ reinterpret_cast<const char*>(value.data()), value.size() * sizeof(ElementType)
+ )
+ );
+ }
+};
+
+////////////////////////////////////////////////////////////////////////////////////////
+
+/// use the following semantic to define custom rules for database types conversion:
+
+//template <typename ColumnType>
+//struct TConvertValue<ColumnType, TRawTypeValue, TStringBuf> {
+// TRawTypeValue Value;
+//
+// TConvertValue(TStringBuf value)
+// : Value(value.data(), value.size(), ColumnType::ColumnType)
+// {
+// static_assert(ColumnType::ColumnType == NScheme::NTypeIds::String
+// || ColumnType::ColumnType == NScheme::NTypeIds::Utf8,
+// "Unsupported ColumnType for TStringBuf");
+// }
+//
+// operator const TRawTypeValue&() const {
+// return Value;
+// }
+//};
+
+//template <typename ColumnType>
+//struct TConvertValue<ColumnType, TStringBuf, TRawTypeValue> {
+// TStringBuf Value;
+//
+// TConvertValue(const TRawTypeValue& value)
+// : Value(reinterpret_cast<const char*>(value.Data()), value.Size())
+// {
+// Y_VERIFY(value.Type() == NScheme::NTypeIds::String || value.Type() == NScheme::NTypeIds::Utf8);
+// }
+//
+// operator TStringBuf() const {
+// return Value;
+// }
+//};
+
+////////////////////////////////////////////////////////////////////////////////////////
+
+template <typename ColumnType, typename TargetType, typename SourceType>
+struct TConvertValue {
+ TargetType Value;
+
+ TConvertValue(const SourceType& value)
+ : Value(value)
+ {}
+
+ operator const TargetType&() const {
+ return Value;
+ }
+};
+
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// TInstant conversion
@@ -366,646 +366,646 @@ struct TConvertValue<TColumnType, TDuration, TRawTypeValue> {
template <typename TColumnType, typename SourceType>
struct TConvertValue<TColumnType, TRawTypeValue, SourceType> {
- TTypeValue Value;
-
- TConvertValue(const SourceType& value)
+ TTypeValue Value;
+
+ TConvertValue(const SourceType& value)
: Value(value, TColumnType::ColumnType)
- {}
-
- operator const TRawTypeValue&() const {
- return Value;
- }
-};
-
+ {}
+
+ operator const TRawTypeValue&() const {
+ return Value;
+ }
+};
+
template <typename TColumnType, typename SourceType>
-struct TConvertValueFromProtoToRawTypeValue {
- TString Storage;
- TTypeValue Value;
-
- TConvertValueFromProtoToRawTypeValue(const SourceType& value)
- : Storage(value.SerializeAsString())
+struct TConvertValueFromProtoToRawTypeValue {
+ TString Storage;
+ TTypeValue Value;
+
+ TConvertValueFromProtoToRawTypeValue(const SourceType& value)
+ : Storage(value.SerializeAsString())
, Value(Storage, TColumnType::ColumnType)
- {
+ {
static_assert(TColumnType::ColumnType == NScheme::NTypeIds::String,
- "Unsupported ColumnType for proto");
- }
-
- operator const TRawTypeValue&() const {
- return Value;
- }
-};
-
+ "Unsupported ColumnType for proto");
+ }
+
+ operator const TRawTypeValue&() const {
+ return Value;
+ }
+};
+
template <typename TColumnType, typename SourceType>
-struct TConvertValueFromPodToRawTypeValue {
+struct TConvertValueFromPodToRawTypeValue {
typename NSchemeTypeMapper<TColumnType::ColumnType>::Type Storage;
- TTypeValue Value;
-
- TConvertValueFromPodToRawTypeValue(const SourceType& value)
+ TTypeValue Value;
+
+ TConvertValueFromPodToRawTypeValue(const SourceType& value)
: Storage(static_cast<typename NSchemeTypeMapper<TColumnType::ColumnType>::Type>(value))
, Value(Storage, TColumnType::ColumnType)
- {}
-
- operator const TRawTypeValue&() const {
- return Value;
- }
-};
-
+ {}
+
+ operator const TRawTypeValue&() const {
+ return Value;
+ }
+};
+
template <typename TColumnType>
struct TConvertValueFromPodToRawTypeValue<TColumnType, typename NSchemeTypeMapper<TColumnType::ColumnType>::Type> {
- TTypeValue Value;
-
+ TTypeValue Value;
+
TConvertValueFromPodToRawTypeValue(const typename NSchemeTypeMapper<TColumnType::ColumnType>::Type& value)
: Value(value, TColumnType::ColumnType)
- {}
-
- operator const TRawTypeValue&() const {
- return Value;
- }
-};
-
-template <typename ColumnType, typename TargetType>
-struct TConvertValueFromRawTypeValueToProto {
- TTypeValue Value;
-
- TConvertValueFromRawTypeValueToProto(const TRawTypeValue& value)
- : Value(value)
- {
- Y_VERIFY(value.Type() == NScheme::NTypeIds::String);
- }
-
- operator TargetType() const {
- TargetType msg;
- Y_VERIFY(msg.ParseFromArray(Value.Data(), Value.Size()));
- return msg;
- }
-};
-
-template <typename ColumnType, typename TargetType>
-struct TConvertValue<ColumnType, TargetType, TRawTypeValue> {
- TTypeValue Value;
-
- TConvertValue(const TRawTypeValue& value)
- : Value(value)
- {}
-
- operator TargetType() const {
- return static_cast<TargetType>(Value);
- }
-};
-
+ {}
+
+ operator const TRawTypeValue&() const {
+ return Value;
+ }
+};
+
+template <typename ColumnType, typename TargetType>
+struct TConvertValueFromRawTypeValueToProto {
+ TTypeValue Value;
+
+ TConvertValueFromRawTypeValueToProto(const TRawTypeValue& value)
+ : Value(value)
+ {
+ Y_VERIFY(value.Type() == NScheme::NTypeIds::String);
+ }
+
+ operator TargetType() const {
+ TargetType msg;
+ Y_VERIFY(msg.ParseFromArray(Value.Data(), Value.Size()));
+ return msg;
+ }
+};
+
+template <typename ColumnType, typename TargetType>
+struct TConvertValue<ColumnType, TargetType, TRawTypeValue> {
+ TTypeValue Value;
+
+ TConvertValue(const TRawTypeValue& value)
+ : Value(value)
+ {}
+
+ operator TargetType() const {
+ return static_cast<TargetType>(Value);
+ }
+};
+
template <typename TColumnType, typename TargetType>
-struct TConvertValueFromRawTypeValueToPod {
- TTypeValue Value;
-
- TConvertValueFromRawTypeValueToPod(const TRawTypeValue& value)
- : Value(value)
- {}
-
- operator TargetType() const {
+struct TConvertValueFromRawTypeValueToPod {
+ TTypeValue Value;
+
+ TConvertValueFromRawTypeValueToPod(const TRawTypeValue& value)
+ : Value(value)
+ {}
+
+ operator TargetType() const {
return static_cast<TargetType>(static_cast<typename NSchemeTypeMapper<TColumnType::ColumnType>::Type>(Value));
- }
-};
+ }
+};
+
+template <typename ColumnType, typename VectorType>
+struct TConvertValue<ColumnType, TVector<VectorType>, TRawTypeValue> {
+ TVector<VectorType> Value;
-template <typename ColumnType, typename VectorType>
-struct TConvertValue<ColumnType, TVector<VectorType>, TRawTypeValue> {
- TVector<VectorType> Value;
-
TConvertValue(const TRawTypeValue& value) {
- Y_VERIFY(value.Type() == NScheme::NTypeIds::String);
- Y_VERIFY(value.Size() % sizeof(VectorType) == 0);
+ Y_VERIFY(value.Type() == NScheme::NTypeIds::String);
+ Y_VERIFY(value.Size() % sizeof(VectorType) == 0);
const size_t count = value.Size() / sizeof(VectorType);
Value.reserve(count);
for (TUnalignedMemoryIterator<VectorType> it(value.Data(), value.Size()); !it.AtEnd(); it.Next()) {
Value.emplace_back(it.Cur());
}
Y_VERIFY(Value.size() == count);
- }
-
- operator const TVector<VectorType>&() const {
- return Value;
- }
-};
-
+ }
+
+ operator const TVector<VectorType>&() const {
+ return Value;
+ }
+};
+
template <typename TColumnType, typename VectorType>
struct TConvertValue<TColumnType, TRawTypeValue, TVector<VectorType>> {
- TTypeValue Value;
-
- TConvertValue(const TVector<VectorType>& value)
- : Value(value)
- {
+ TTypeValue Value;
+
+ TConvertValue(const TVector<VectorType>& value)
+ : Value(value)
+ {
static_assert(TColumnType::ColumnType == NScheme::NTypeIds::String,
- "Unsupported ColumnType for vector<>");
- }
-
- operator const TRawTypeValue&() const {
- return Value;
- }
-};
-
+ "Unsupported ColumnType for vector<>");
+ }
+
+ operator const TRawTypeValue&() const {
+ return Value;
+ }
+};
+
template <typename TColumnType>
struct TConvertValue<TColumnType, TRawTypeValue, TStringBuf> {
- TRawTypeValue Value;
-
- TConvertValue(TStringBuf value)
+ TRawTypeValue Value;
+
+ TConvertValue(TStringBuf value)
: Value(value.data(), value.size(), TColumnType::ColumnType)
- {
+ {
static_assert(TColumnType::ColumnType == NScheme::NTypeIds::String
|| TColumnType::ColumnType == NScheme::NTypeIds::Utf8,
- "Unsupported ColumnType for TStringBuf");
- }
-
- operator const TRawTypeValue&() const {
- return Value;
- }
-};
-
-template <typename ColumnType>
-struct TConvertValue<ColumnType, TStringBuf, TRawTypeValue> {
- TStringBuf Value;
-
- TConvertValue(const TRawTypeValue& value)
- : Value(reinterpret_cast<const char*>(value.Data()), value.Size())
- {
- Y_VERIFY(value.Type() == NScheme::NTypeIds::String || value.Type() == NScheme::NTypeIds::Utf8);
- }
-
- operator TStringBuf() const {
- return Value;
- }
-};
-
-template <typename ColumnType,
- typename TargetType,
- typename SourceType,
- typename std::enable_if<std::is_same<TRawTypeValue, TargetType>::value, bool>::type = true,
- typename std::enable_if<std::is_base_of<::google::protobuf::Message, SourceType>::value, bool>::type = true>
-auto ConvertValue(const SourceType& value) {
- return TConvertValueFromProtoToRawTypeValue<ColumnType, SourceType>(value);
-}
-
-template <typename ColumnType,
- typename TargetType,
- typename SourceType,
- typename std::enable_if<std::is_same<TRawTypeValue, SourceType>::value, bool>::type = true,
- typename std::enable_if<std::is_base_of<::google::protobuf::Message, TargetType>::value, bool>::type = true>
-auto ConvertValue(const SourceType& value) {
- return TConvertValueFromRawTypeValueToProto<ColumnType, TargetType>(value);
-}
-
-template <typename ColumnType,
- typename TargetType,
- typename SourceType,
- typename std::enable_if<std::is_same<TRawTypeValue, TargetType>::value, bool>::type = true,
- typename std::enable_if<std::is_pod<SourceType>::value, bool>::type = true>
-auto ConvertValue(const SourceType& value) {
- return TConvertValueFromPodToRawTypeValue<ColumnType, SourceType>(value);
-}
-
-template <typename ColumnType,
- typename TargetType,
- typename SourceType,
- typename std::enable_if<std::is_same<TRawTypeValue, SourceType>::value, bool>::type = true,
- typename std::enable_if<std::is_pod<TargetType>::value, bool>::type = true>
-auto ConvertValue(const SourceType& value) {
- return TConvertValueFromRawTypeValueToPod<ColumnType, TargetType>(value);
-}
-
-template <typename ColumnType,
- typename TargetType,
- typename SourceType,
+ "Unsupported ColumnType for TStringBuf");
+ }
+
+ operator const TRawTypeValue&() const {
+ return Value;
+ }
+};
+
+template <typename ColumnType>
+struct TConvertValue<ColumnType, TStringBuf, TRawTypeValue> {
+ TStringBuf Value;
+
+ TConvertValue(const TRawTypeValue& value)
+ : Value(reinterpret_cast<const char*>(value.Data()), value.Size())
+ {
+ Y_VERIFY(value.Type() == NScheme::NTypeIds::String || value.Type() == NScheme::NTypeIds::Utf8);
+ }
+
+ operator TStringBuf() const {
+ return Value;
+ }
+};
+
+template <typename ColumnType,
+ typename TargetType,
+ typename SourceType,
+ typename std::enable_if<std::is_same<TRawTypeValue, TargetType>::value, bool>::type = true,
+ typename std::enable_if<std::is_base_of<::google::protobuf::Message, SourceType>::value, bool>::type = true>
+auto ConvertValue(const SourceType& value) {
+ return TConvertValueFromProtoToRawTypeValue<ColumnType, SourceType>(value);
+}
+
+template <typename ColumnType,
+ typename TargetType,
+ typename SourceType,
+ typename std::enable_if<std::is_same<TRawTypeValue, SourceType>::value, bool>::type = true,
+ typename std::enable_if<std::is_base_of<::google::protobuf::Message, TargetType>::value, bool>::type = true>
+auto ConvertValue(const SourceType& value) {
+ return TConvertValueFromRawTypeValueToProto<ColumnType, TargetType>(value);
+}
+
+template <typename ColumnType,
+ typename TargetType,
+ typename SourceType,
+ typename std::enable_if<std::is_same<TRawTypeValue, TargetType>::value, bool>::type = true,
+ typename std::enable_if<std::is_pod<SourceType>::value, bool>::type = true>
+auto ConvertValue(const SourceType& value) {
+ return TConvertValueFromPodToRawTypeValue<ColumnType, SourceType>(value);
+}
+
+template <typename ColumnType,
+ typename TargetType,
+ typename SourceType,
+ typename std::enable_if<std::is_same<TRawTypeValue, SourceType>::value, bool>::type = true,
+ typename std::enable_if<std::is_pod<TargetType>::value, bool>::type = true>
+auto ConvertValue(const SourceType& value) {
+ return TConvertValueFromRawTypeValueToPod<ColumnType, TargetType>(value);
+}
+
+template <typename ColumnType,
+ typename TargetType,
+ typename SourceType,
std::enable_if_t<!std::is_pod<SourceType>::value, bool> = true,
std::enable_if_t<!std::is_pod<TargetType>::value, bool> = true,
- typename std::enable_if<!std::is_base_of<::google::protobuf::Message, SourceType>::value, bool>::type = true,
- typename std::enable_if<!std::is_base_of<::google::protobuf::Message, TargetType>::value, bool>::type = true>
-auto ConvertValue(const SourceType& value) {
- return TConvertValue<ColumnType, TargetType, SourceType>(value);
-}
-
-template <typename ColumnType, typename TargetType>
-struct TConvert {
- template <typename SourceType>
- static auto Convert(const SourceType& value) {
- return ConvertValue<ColumnType, TargetType, SourceType>(value);
- }
-};
-
-template <typename ColumnType, typename TargetType, typename SourceType>
-struct TConvertType {
- using Type = decltype(TConvert<ColumnType, TRawTypeValue>::Convert(*(const SourceType*)nullptr));
-};
-
-typedef ui32 TTableId;
-typedef ui32 TColumnId;
-
-template <typename Column>
-struct TUpdate {
- typename TConvertType<Column, TRawTypeValue, typename Column::Type>::Type Value;
-
- explicit TUpdate(const typename Column::Type& value)
- : Value(TConvert<Column, TRawTypeValue>::Convert(value))
- {}
-
- operator TUpdateOp() const {
+ typename std::enable_if<!std::is_base_of<::google::protobuf::Message, SourceType>::value, bool>::type = true,
+ typename std::enable_if<!std::is_base_of<::google::protobuf::Message, TargetType>::value, bool>::type = true>
+auto ConvertValue(const SourceType& value) {
+ return TConvertValue<ColumnType, TargetType, SourceType>(value);
+}
+
+template <typename ColumnType, typename TargetType>
+struct TConvert {
+ template <typename SourceType>
+ static auto Convert(const SourceType& value) {
+ return ConvertValue<ColumnType, TargetType, SourceType>(value);
+ }
+};
+
+template <typename ColumnType, typename TargetType, typename SourceType>
+struct TConvertType {
+ using Type = decltype(TConvert<ColumnType, TRawTypeValue>::Convert(*(const SourceType*)nullptr));
+};
+
+typedef ui32 TTableId;
+typedef ui32 TColumnId;
+
+template <typename Column>
+struct TUpdate {
+ typename TConvertType<Column, TRawTypeValue, typename Column::Type>::Type Value;
+
+ explicit TUpdate(const typename Column::Type& value)
+ : Value(TConvert<Column, TRawTypeValue>::Convert(value))
+ {}
+
+ operator TUpdateOp() const {
return TUpdateOp(Column::ColumnId, NTable::ECellOp::Set, Value);
- }
-};
-
-template <typename Column>
-struct TNull {
- operator TUpdateOp() const {
+ }
+};
+
+template <typename Column>
+struct TNull {
+ operator TUpdateOp() const {
return TUpdateOp(Column::ColumnId, NTable::ECellOp::Null, { });
- }
-};
-
+ }
+};
+
enum class EMaterializationMode {
All,
Existing,
NonExisting,
};
-struct Schema {
- template <typename T>
- struct Precharger {
+struct Schema {
+ template <typename T>
+ struct Precharger {
static bool Precharge(
TToughDb&, ui32,
NTable::TRawVals, NTable::TRawVals,
NTable::TTagsRef, NTable::EDirection);
- };
-
- struct NoAutoPrecharge {};
- struct AutoPrecharge {};
-
- template <TTableId _TableId> struct Table {
+ };
+
+ struct NoAutoPrecharge {};
+ struct AutoPrecharge {};
+
+ template <TTableId _TableId> struct Table {
constexpr static TTableId TableId = _TableId;
-
- using Precharge = AutoPrecharge;
-
+
+ using Precharge = AutoPrecharge;
+
template <TColumnId _ColumnId, NScheme::TTypeId _ColumnType, bool _IsNotNull = false>
struct Column {
constexpr static TColumnId ColumnId = _ColumnId;
constexpr static NScheme::TTypeId ColumnType = _ColumnType;
constexpr static bool IsNotNull = _IsNotNull;
- using Type = typename NSchemeTypeMapper<_ColumnType>::Type;
-
+ using Type = typename NSchemeTypeMapper<_ColumnType>::Type;
+
static TString GetColumnName(const TString& typeName) {
- return typeName.substr(typeName.rfind(':') + 1);
- }
- };
-
- template <typename...>
- struct TableColumns;
-
+ return typeName.substr(typeName.rfind(':') + 1);
+ }
+ };
+
+ template <typename...>
+ struct TableColumns;
+
template <typename T>
struct TableColumns<T> {
- using Type = typename T::Type;
- using TupleType = std::tuple<typename T::Type>;
- using RealTupleType = std::tuple<typename NSchemeTypeMapper<T::ColumnType>::Type>;
-
+ using Type = typename T::Type;
+ using TupleType = std::tuple<typename T::Type>;
+ using RealTupleType = std::tuple<typename NSchemeTypeMapper<T::ColumnType>::Type>;
+
static TString GetColumnName() {
- return GetColumnName(TypeName<T>());
- }
-
+ return GetColumnName(TypeName<T>());
+ }
+
static TString GetColumnName(const TString& typeName) {
- return T::GetColumnName(typeName);
- }
-
- static void Materialize(TToughDb& database) {
+ return T::GetColumnName(typeName);
+ }
+
+ static void Materialize(TToughDb& database) {
database.Alter().AddColumn(TableId, GetColumnName(), T::ColumnId, T::ColumnType, T::IsNotNull);
- }
-
- static constexpr bool HaveColumn(ui32 columnId) {
- return T::ColumnId == columnId;
- }
-
- template <typename OtherT>
- static constexpr bool HaveColumn() {
- return std::is_same<T, OtherT>::value != 0;
- }
- };
-
+ }
+
+ static constexpr bool HaveColumn(ui32 columnId) {
+ return T::ColumnId == columnId;
+ }
+
+ template <typename OtherT>
+ static constexpr bool HaveColumn() {
+ return std::is_same<T, OtherT>::value != 0;
+ }
+ };
+
template <typename T, typename... Ts>
struct TableColumns<T, Ts...> : TableColumns<Ts...> {
- using Type = std::tuple<typename T::Type, typename Ts::Type...>;
- using TupleType = std::tuple<typename T::Type, typename Ts::Type...>;
- using RealTupleType = std::tuple<typename NSchemeTypeMapper<T::ColumnType>::Type, typename NSchemeTypeMapper<Ts::ColumnType>::Type...>;
-
- static void Materialize(TToughDb& database) {
- TableColumns<T>::Materialize(database);
- TableColumns<Ts...>::Materialize(database);
- }
-
- static constexpr bool HaveColumn(ui32 columnId) {
- return TableColumns<T>::HaveColumn(columnId) || TableColumns<Ts...>::HaveColumn(columnId);
- }
- };
-
- template <typename... ColumnsTypes>
- struct Columns : TableColumns<ColumnsTypes...> {
- using ColumnsType = std::tuple<ColumnsTypes...>;
-
- static const std::array<TColumnId, sizeof...(ColumnsTypes)>& GetColumnIds() {
- static const std::array<TColumnId, sizeof...(ColumnsTypes)> ColumnIds = {{ColumnsTypes::ColumnId...}};
- return ColumnIds;
- }
-
- template <typename TColumn>
- static constexpr std::size_t GetIndex(TColumn) {
- return index_of<TColumn, ColumnsType>::value;
- }
-
- template <typename TColumn>
- static constexpr std::size_t GetIndex() {
- return index_of<TColumn, ColumnsType>::value;
- }
- };
-
- template <typename... ColumnsTypes>
- struct Columns<TableColumns<ColumnsTypes...>> : Columns<ColumnsTypes...> {};
-
+ using Type = std::tuple<typename T::Type, typename Ts::Type...>;
+ using TupleType = std::tuple<typename T::Type, typename Ts::Type...>;
+ using RealTupleType = std::tuple<typename NSchemeTypeMapper<T::ColumnType>::Type, typename NSchemeTypeMapper<Ts::ColumnType>::Type...>;
+
+ static void Materialize(TToughDb& database) {
+ TableColumns<T>::Materialize(database);
+ TableColumns<Ts...>::Materialize(database);
+ }
+
+ static constexpr bool HaveColumn(ui32 columnId) {
+ return TableColumns<T>::HaveColumn(columnId) || TableColumns<Ts...>::HaveColumn(columnId);
+ }
+ };
+
+ template <typename... ColumnsTypes>
+ struct Columns : TableColumns<ColumnsTypes...> {
+ using ColumnsType = std::tuple<ColumnsTypes...>;
+
+ static const std::array<TColumnId, sizeof...(ColumnsTypes)>& GetColumnIds() {
+ static const std::array<TColumnId, sizeof...(ColumnsTypes)> ColumnIds = {{ColumnsTypes::ColumnId...}};
+ return ColumnIds;
+ }
+
+ template <typename TColumn>
+ static constexpr std::size_t GetIndex(TColumn) {
+ return index_of<TColumn, ColumnsType>::value;
+ }
+
+ template <typename TColumn>
+ static constexpr std::size_t GetIndex() {
+ return index_of<TColumn, ColumnsType>::value;
+ }
+ };
+
+ template <typename... ColumnsTypes>
+ struct Columns<TableColumns<ColumnsTypes...>> : Columns<ColumnsTypes...> {};
+
template <typename IteratorType>
using ReverseIteratorType = typename IteratorType::TReverseType;
- template <typename, typename> class KeyOperations;
+ template <typename, typename> class KeyOperations;
template <typename, typename> class AnyKeyOperations;
template <typename, typename, typename> class KeyPrefixOperations;
template <typename, typename, typename> class GreaterOrEqualKeyOperations;
template <typename, typename, typename> class LessOrEqualKeyOperations;
template <typename, typename, typename, typename> class RangeKeyOperations;
-
+
template <typename IteratorType, typename TableType, typename... KeyColumns>
class TableSelector {
- protected:
- using KeyColumnsType = std::tuple<KeyColumns...>;
- using KeyValuesType = std::tuple<typename KeyColumns::Type...>;
+ protected:
+ using KeyColumnsType = std::tuple<KeyColumns...>;
+ using KeyValuesType = std::tuple<typename KeyColumns::Type...>;
using ReverseSelector = TableSelector<ReverseIteratorType<IteratorType>, TableType, KeyColumns...>;
- TToughDb* Database;
-
- public:
- TableSelector(TToughDb& database)
- : Database(&database)
- {}
-
- TableSelector(const TableSelector&) = default;
- TableSelector(TableSelector&&) = default;
-
- TableSelector& operator =(TableSelector&& selector) {
- Database = selector.Database;
- return *this;
- }
-
- TableSelector& operator =(const TableSelector& selector) {
- Database = selector.Database;
- return *this;
- }
-
- auto Key(typename KeyColumns::Type... keyValues) {
- return KeyOperations<TableType, KeyValuesType>(*Database, keyValues...);
- }
-
- auto Key(const KeyValuesType& keyValues) {
- return KeyOperations<TableType, KeyValuesType>(*Database, keyValues);
+ TToughDb* Database;
+
+ public:
+ TableSelector(TToughDb& database)
+ : Database(&database)
+ {}
+
+ TableSelector(const TableSelector&) = default;
+ TableSelector(TableSelector&&) = default;
+
+ TableSelector& operator =(TableSelector&& selector) {
+ Database = selector.Database;
+ return *this;
+ }
+
+ TableSelector& operator =(const TableSelector& selector) {
+ Database = selector.Database;
+ return *this;
+ }
+
+ auto Key(typename KeyColumns::Type... keyValues) {
+ return KeyOperations<TableType, KeyValuesType>(*Database, keyValues...);
+ }
+
+ auto Key(const KeyValuesType& keyValues) {
+ return KeyOperations<TableType, KeyValuesType>(*Database, keyValues);
}
template <typename... Keys>
- auto Range(Keys... keyValues) {
+ auto Range(Keys... keyValues) {
return KeyPrefixOperations<IteratorType, TableType, typename first_n_of<sizeof...(Keys), KeyValuesType>::type>(*Database, keyValues...);
- }
-
+ }
+
template <typename... Keys>
- auto Prefix(Keys... keyValues) {
+ auto Prefix(Keys... keyValues) {
return KeyPrefixOperations<IteratorType, TableType, typename first_n_of<sizeof...(Keys), KeyValuesType>::type>(*Database, keyValues...);
- }
-
- auto Range() {
+ }
+
+ auto Range() {
return AnyKeyOperations<IteratorType, TableType>(*Database);
- }
-
- auto All() {
+ }
+
+ auto All() {
return AnyKeyOperations<IteratorType, TableType>(*Database);
- }
-
- template <typename... Keys>
- auto GreaterOrEqual(Keys... keyValues) {
+ }
+
+ template <typename... Keys>
+ auto GreaterOrEqual(Keys... keyValues) {
return GreaterOrEqualKeyOperations<IteratorType, TableType, typename first_n_of<sizeof...(Keys), KeyValuesType>::type>(*Database, keyValues...);
- }
-
- template <typename... Keys>
- auto LessOrEqual(Keys... keyValues) {
+ }
+
+ template <typename... Keys>
+ auto LessOrEqual(Keys... keyValues) {
return LessOrEqualKeyOperations<IteratorType, TableType, typename first_n_of<sizeof...(Keys), KeyValuesType>::type>(*Database, keyValues...);
- }
-
- template <typename... ColumnTypes>
- auto Select() {
- return All().template Select<ColumnTypes...>();
- }
-
- auto Select() {
- return All().Select();
- }
-
- template <typename... ColumnTypes>
- auto Precharge() {
- return All().template Precharge<ColumnTypes...>();
- }
-
- auto Precharge() {
- return All().Precharge();
- }
+ }
+
+ template <typename... ColumnTypes>
+ auto Select() {
+ return All().template Select<ColumnTypes...>();
+ }
+
+ auto Select() {
+ return All().Select();
+ }
+
+ template <typename... ColumnTypes>
+ auto Precharge() {
+ return All().template Precharge<ColumnTypes...>();
+ }
+
+ auto Precharge() {
+ return All().Precharge();
+ }
auto Reverse() const {
return ReverseSelector(*Database);
}
- };
-
- template <typename... KeyColumnsTypes>
- struct TableKey : TableColumns<KeyColumnsTypes...> {
- private:
+ };
+
+ template <typename... KeyColumnsTypes>
+ struct TableKey : TableColumns<KeyColumnsTypes...> {
+ private:
template <typename... Ts>
struct TableKeyMaterializer;
-
+
template <typename T>
struct TableKeyMaterializer<T> {
- static void Materialize(TToughDb& database) {
+ static void Materialize(TToughDb& database) {
database.Alter().AddColumnToKey(TableId, T::ColumnId);
- }
- };
-
+ }
+ };
+
template <typename T, typename... Ts>
struct TableKeyMaterializer<T, Ts...> : TableKeyMaterializer<Ts...> {
- static void Materialize(TToughDb& database) {
- TableKeyMaterializer<T>::Materialize(database);
- TableKeyMaterializer<Ts...>::Materialize(database);
- }
- };
-
- public:
- static void Materialize(TToughDb& database) {
- TableKeyMaterializer<KeyColumnsTypes...>::Materialize(database);
- }
-
- template <typename TableType>
+ static void Materialize(TToughDb& database) {
+ TableKeyMaterializer<T>::Materialize(database);
+ TableKeyMaterializer<Ts...>::Materialize(database);
+ }
+ };
+
+ public:
+ static void Materialize(TToughDb& database) {
+ TableKeyMaterializer<KeyColumnsTypes...>::Materialize(database);
+ }
+
+ template <typename TableType>
using Selector = TableSelector<NTable::TTableIt, TableType, KeyColumnsTypes...>;
- using KeyColumnsType = std::tuple<KeyColumnsTypes...>;
- using KeyValuesType = typename TableColumns<KeyColumnsTypes...>::TupleType;
- using RealKeyValuesType = typename TableColumns<KeyColumnsTypes...>::RealTupleType;
- };
-
- template <typename, typename, std::size_t>
- class TTupleToRawTypeValueFixedSize;
-
- template <typename... ValuesTypes, typename... ColumnsTypes, std::size_t Size>
- class TTupleToRawTypeValueFixedSize<std::tuple<ValuesTypes...>, std::tuple<ColumnsTypes...>, Size> {
- public:
- using TValuesTuple = std::tuple<ValuesTypes...>;
- using TConvertTuple = std::tuple<typename TConvertType<ColumnsTypes, TRawTypeValue, ValuesTypes>::Type...>;
- using TArray = std::array<const TRawTypeValue, Size>;
-
- TTupleToRawTypeValueFixedSize(const TValuesTuple& values)
- : ConvertTuple(ValuesTuple2ConvertTuple(values))
- , Array(Tuple2Array(ConvertTuple))
- {}
-
- operator TArrayRef<const TRawTypeValue>() const {
- return Array;
- }
-
- protected:
- TConvertTuple ConvertTuple;
- TArray Array;
-
- template <std::size_t...I>
- static TArray Tuple2Array(const TConvertTuple& tuple, std::index_sequence<I...>) {
- return {{static_cast<const TRawTypeValue&>(std::get<I>(tuple))...}};
- }
-
- static TArray Tuple2Array(const TConvertTuple& tuple) {
- return Tuple2Array(tuple, std::make_index_sequence<sizeof...(ValuesTypes)>());
- }
-
- template <std::size_t...I>
- static TConvertTuple ValuesTuple2ConvertTuple(const TValuesTuple& tuple, std::index_sequence<I...>) {
- return TConvertTuple(std::get<I>(tuple)...);
- }
-
- static TConvertTuple ValuesTuple2ConvertTuple(const TValuesTuple& tuple) {
- return ValuesTuple2ConvertTuple(tuple, std::make_index_sequence<sizeof...(ValuesTypes)>());
- }
- };
-
- template <typename, typename>
- class TTupleToRawTypeValue;
-
- template <typename... ValuesTypes, typename... ColumnsTypes>
- class TTupleToRawTypeValue<std::tuple<ValuesTypes...>, std::tuple<ColumnsTypes...>> : public TTupleToRawTypeValueFixedSize<std::tuple<ValuesTypes...>, std::tuple<ColumnsTypes...>, sizeof...(ValuesTypes)> {
- public:
- TTupleToRawTypeValue(const std::tuple<ValuesTypes...>& values)
- : TTupleToRawTypeValueFixedSize<std::tuple<ValuesTypes...>, std::tuple<ColumnsTypes...>, sizeof...(ValuesTypes)>(values)
- {}
- };
-
- template <typename, typename>
- class TTupleToCell;
-
- template <typename... ValuesTypes, typename... ColumnsTypes>
- class TTupleToCell<std::tuple<ValuesTypes...>, std::tuple<ColumnsTypes...>> {
- public:
- using TValuesTuple = std::tuple<ValuesTypes...>;
- using TConvertTuple = std::tuple<typename TConvertType<ColumnsTypes, TRawTypeValue, ValuesTypes>::Type...>;
- using TArray = std::array<TCell, sizeof...(ValuesTypes)>;
-
- TTupleToCell(const TValuesTuple& values)
- : ConvertTuple(ValuesTuple2ConvertTuple(values))
- , Array(Tuple2Array(ConvertTuple))
- {}
-
- TTupleToCell& operator =(const TValuesTuple& values) {
- ConvertTuple = std::move(ValuesTuple2ConvertTuple(values));
- Array = std::move(Tuple2Array(ConvertTuple));
- return *this;
- }
-
- const TCell* data() const {
- return Array.data();
- }
-
- auto size() const {
- return Array.size();
- }
-
- protected:
- TConvertTuple ConvertTuple;
- TArray Array;
-
- template <std::size_t...I>
- static TArray Tuple2Array(const TConvertTuple& tuple, std::index_sequence<I...>) {
- return {{TCell(&static_cast<const TRawTypeValue&>(std::get<I>(tuple)))...}};
- }
-
- static TArray Tuple2Array(const TConvertTuple& tuple) {
- return Tuple2Array(tuple, std::make_index_sequence<sizeof...(ValuesTypes)>());
- }
-
- template <std::size_t...I>
- static TConvertTuple ValuesTuple2ConvertTuple(const TValuesTuple& tuple, std::index_sequence<I...>) {
- return TConvertTuple(std::get<I>(tuple)...);
- }
-
- static TConvertTuple ValuesTuple2ConvertTuple(const TValuesTuple& tuple) {
- return ValuesTuple2ConvertTuple(tuple, std::make_index_sequence<sizeof...(ValuesTypes)>());
- }
- };
-
- class Operations {
- public:
- Operations() = default;
- Operations(Operations&&) = default;
- Operations& operator =(Operations&&) = default;
-
+ using KeyColumnsType = std::tuple<KeyColumnsTypes...>;
+ using KeyValuesType = typename TableColumns<KeyColumnsTypes...>::TupleType;
+ using RealKeyValuesType = typename TableColumns<KeyColumnsTypes...>::RealTupleType;
+ };
+
+ template <typename, typename, std::size_t>
+ class TTupleToRawTypeValueFixedSize;
+
+ template <typename... ValuesTypes, typename... ColumnsTypes, std::size_t Size>
+ class TTupleToRawTypeValueFixedSize<std::tuple<ValuesTypes...>, std::tuple<ColumnsTypes...>, Size> {
+ public:
+ using TValuesTuple = std::tuple<ValuesTypes...>;
+ using TConvertTuple = std::tuple<typename TConvertType<ColumnsTypes, TRawTypeValue, ValuesTypes>::Type...>;
+ using TArray = std::array<const TRawTypeValue, Size>;
+
+ TTupleToRawTypeValueFixedSize(const TValuesTuple& values)
+ : ConvertTuple(ValuesTuple2ConvertTuple(values))
+ , Array(Tuple2Array(ConvertTuple))
+ {}
+
+ operator TArrayRef<const TRawTypeValue>() const {
+ return Array;
+ }
+
+ protected:
+ TConvertTuple ConvertTuple;
+ TArray Array;
+
+ template <std::size_t...I>
+ static TArray Tuple2Array(const TConvertTuple& tuple, std::index_sequence<I...>) {
+ return {{static_cast<const TRawTypeValue&>(std::get<I>(tuple))...}};
+ }
+
+ static TArray Tuple2Array(const TConvertTuple& tuple) {
+ return Tuple2Array(tuple, std::make_index_sequence<sizeof...(ValuesTypes)>());
+ }
+
+ template <std::size_t...I>
+ static TConvertTuple ValuesTuple2ConvertTuple(const TValuesTuple& tuple, std::index_sequence<I...>) {
+ return TConvertTuple(std::get<I>(tuple)...);
+ }
+
+ static TConvertTuple ValuesTuple2ConvertTuple(const TValuesTuple& tuple) {
+ return ValuesTuple2ConvertTuple(tuple, std::make_index_sequence<sizeof...(ValuesTypes)>());
+ }
+ };
+
+ template <typename, typename>
+ class TTupleToRawTypeValue;
+
+ template <typename... ValuesTypes, typename... ColumnsTypes>
+ class TTupleToRawTypeValue<std::tuple<ValuesTypes...>, std::tuple<ColumnsTypes...>> : public TTupleToRawTypeValueFixedSize<std::tuple<ValuesTypes...>, std::tuple<ColumnsTypes...>, sizeof...(ValuesTypes)> {
+ public:
+ TTupleToRawTypeValue(const std::tuple<ValuesTypes...>& values)
+ : TTupleToRawTypeValueFixedSize<std::tuple<ValuesTypes...>, std::tuple<ColumnsTypes...>, sizeof...(ValuesTypes)>(values)
+ {}
+ };
+
+ template <typename, typename>
+ class TTupleToCell;
+
+ template <typename... ValuesTypes, typename... ColumnsTypes>
+ class TTupleToCell<std::tuple<ValuesTypes...>, std::tuple<ColumnsTypes...>> {
+ public:
+ using TValuesTuple = std::tuple<ValuesTypes...>;
+ using TConvertTuple = std::tuple<typename TConvertType<ColumnsTypes, TRawTypeValue, ValuesTypes>::Type...>;
+ using TArray = std::array<TCell, sizeof...(ValuesTypes)>;
+
+ TTupleToCell(const TValuesTuple& values)
+ : ConvertTuple(ValuesTuple2ConvertTuple(values))
+ , Array(Tuple2Array(ConvertTuple))
+ {}
+
+ TTupleToCell& operator =(const TValuesTuple& values) {
+ ConvertTuple = std::move(ValuesTuple2ConvertTuple(values));
+ Array = std::move(Tuple2Array(ConvertTuple));
+ return *this;
+ }
+
+ const TCell* data() const {
+ return Array.data();
+ }
+
+ auto size() const {
+ return Array.size();
+ }
+
+ protected:
+ TConvertTuple ConvertTuple;
+ TArray Array;
+
+ template <std::size_t...I>
+ static TArray Tuple2Array(const TConvertTuple& tuple, std::index_sequence<I...>) {
+ return {{TCell(&static_cast<const TRawTypeValue&>(std::get<I>(tuple)))...}};
+ }
+
+ static TArray Tuple2Array(const TConvertTuple& tuple) {
+ return Tuple2Array(tuple, std::make_index_sequence<sizeof...(ValuesTypes)>());
+ }
+
+ template <std::size_t...I>
+ static TConvertTuple ValuesTuple2ConvertTuple(const TValuesTuple& tuple, std::index_sequence<I...>) {
+ return TConvertTuple(std::get<I>(tuple)...);
+ }
+
+ static TConvertTuple ValuesTuple2ConvertTuple(const TValuesTuple& tuple) {
+ return ValuesTuple2ConvertTuple(tuple, std::make_index_sequence<sizeof...(ValuesTypes)>());
+ }
+ };
+
+ class Operations {
+ public:
+ Operations() = default;
+ Operations(Operations&&) = default;
+ Operations& operator =(Operations&&) = default;
+
template <typename IteratorType, typename DeriveType>
- class KeyIterator {
- public:
+ class KeyIterator {
+ public:
KeyIterator(THolder<IteratorType>&& it)
- : Iterator(std::move(it))
- {}
-
- KeyIterator(KeyIterator&&) = default;
- KeyIterator& operator =(KeyIterator&&) = default;
-
- void Init() {
+ : Iterator(std::move(it))
+ {}
+
+ KeyIterator(KeyIterator&&) = default;
+ KeyIterator& operator =(KeyIterator&&) = default;
+
+ void Init() {
if (Iterator)
- Next(); /* should invoke for the first key */
- }
-
- bool IsReady() const {
+ Next(); /* should invoke for the first key */
+ }
+
+ bool IsReady() const {
return Iterator && Iterator->Last() != NTable::EReady::Page;
- }
-
- bool IsValid() const {
+ }
+
+ bool IsValid() const {
return Iterator->Last() == NTable::EReady::Data;
- }
-
- bool IsOk() const {
- return IsReady() && IsValid();
- }
-
- bool Next() {
+ }
+
+ bool IsOk() const {
+ return IsReady() && IsValid();
+ }
+
+ bool Next() {
while (Iterator->Next(NTable::ENext::Data) == NTable::EReady::Data && IsDeleted()) { }
return IsReady();
- }
-
- TDbTupleRef GetValues() const {
- return Iterator->GetValues();
- }
-
- TDbTupleRef GetKey() const {
- return Iterator->GetKey();
- }
-
+ }
+
+ TDbTupleRef GetValues() const {
+ return Iterator->GetValues();
+ }
+
+ TDbTupleRef GetKey() const {
+ return Iterator->GetKey();
+ }
+
typename NTable::TIteratorStats* Stats() const {
return Iterator ? &Iterator->Stats : nullptr;
}
- private:
+ private:
bool IsDeleted() const {
Y_VERIFY_DEBUG(
Iterator->Row().GetRowState() != NTable::ERowOp::Erase,
@@ -1019,63 +1019,63 @@ struct Schema {
private:
THolder<IteratorType> Iterator;
- };
-
+ };
+
template <typename IteratorType, typename TableType>
class AnyKeyIterator
: public KeyIterator<IteratorType, AnyKeyIterator<IteratorType, TableType>>
{
- public:
- using KeyColumnsType = typename TableType::TKey::KeyColumnsType;
+ public:
+ using KeyColumnsType = typename TableType::TKey::KeyColumnsType;
using Iterator = KeyIterator<IteratorType, AnyKeyIterator<IteratorType, TableType>>;
-
- AnyKeyIterator(TToughDb& database, NTable::TTagsRef columns)
- : Iterator(MakeIterator(database, columns))
- {
- Iterator::Init();
- }
-
- AnyKeyIterator(AnyKeyIterator&&) = default;
- AnyKeyIterator& operator =(AnyKeyIterator&&) = default;
-
+
+ AnyKeyIterator(TToughDb& database, NTable::TTagsRef columns)
+ : Iterator(MakeIterator(database, columns))
+ {
+ Iterator::Init();
+ }
+
+ AnyKeyIterator(AnyKeyIterator&&) = default;
+ AnyKeyIterator& operator =(AnyKeyIterator&&) = default;
+
static THolder<IteratorType> MakeIterator(
TToughDb& database, NTable::TTagsRef columns)
{
if (!Precharger<typename TableType::Precharge>::Precharge(database, TableId, {}, {}, columns, IteratorType::Direction)) {
- return nullptr;
- }
+ return nullptr;
+ }
return THolder<IteratorType>(database.IterateRangeGeneric<IteratorType>(TableId, NTable::TKeyRange{ }, columns).Release());
}
- static bool Precharge(TToughDb& database, NTable::TTagsRef columns) {
+ static bool Precharge(TToughDb& database, NTable::TTagsRef columns) {
return Precharger<AutoPrecharge>::Precharge(database, TableId, {}, {}, columns, IteratorType::Direction);
- }
- };
-
+ }
+ };
+
template <typename, typename, typename>
- class EqualPartialKeyIterator;
-
+ class EqualPartialKeyIterator;
+
template <typename IteratorType, typename TableType, typename... KeyValuesTypes>
class EqualPartialKeyIterator<IteratorType, TableType, std::tuple<KeyValuesTypes...>>
: public KeyIterator<IteratorType, EqualPartialKeyIterator<IteratorType, TableType, std::tuple<KeyValuesTypes...>>>
{
- public:
- using KeyValuesType = std::tuple<KeyValuesTypes...>;
- using KeyColumnsType = typename first_n_of<sizeof...(KeyValuesTypes), typename TableType::TKey::KeyColumnsType>::type;
+ public:
+ using KeyValuesType = std::tuple<KeyValuesTypes...>;
+ using KeyColumnsType = typename first_n_of<sizeof...(KeyValuesTypes), typename TableType::TKey::KeyColumnsType>::type;
using Iterator = KeyIterator<IteratorType, EqualPartialKeyIterator<IteratorType, TableType, KeyValuesType>>;
- static constexpr auto FullKeySize = std::tuple_size<typename TableType::TKey::KeyColumnsType>::value;
-
- EqualPartialKeyIterator(TToughDb& database, const KeyValuesType& key, NTable::TTagsRef columns)
- : Iterator(MakeIterator(database, key, columns))
- {
- Iterator::Init();
- }
-
- EqualPartialKeyIterator(const EqualPartialKeyIterator&) = delete;
-
+ static constexpr auto FullKeySize = std::tuple_size<typename TableType::TKey::KeyColumnsType>::value;
+
+ EqualPartialKeyIterator(TToughDb& database, const KeyValuesType& key, NTable::TTagsRef columns)
+ : Iterator(MakeIterator(database, key, columns))
+ {
+ Iterator::Init();
+ }
+
+ EqualPartialKeyIterator(const EqualPartialKeyIterator&) = delete;
+
EqualPartialKeyIterator(EqualPartialKeyIterator&& iterator) = default;
EqualPartialKeyIterator& operator =(EqualPartialKeyIterator&& iterator) = default;
-
+
static THolder<IteratorType> MakeIterator(
TToughDb& database,
const KeyValuesType& keyValues,
@@ -1084,46 +1084,46 @@ struct Schema {
TTupleToRawTypeValueFixedSize<KeyValuesType, KeyColumnsType, FullKeySize> minKey(keyValues);
TTupleToRawTypeValue<KeyValuesType, KeyColumnsType> maxKey(keyValues);
if (!Precharger<typename TableType::Precharge>::Precharge(database, TableId, minKey, maxKey, columns, IteratorType::Direction)) {
- return nullptr;
- }
+ return nullptr;
+ }
NTable::TKeyRange range;
range.MinKey = minKey;
range.MinInclusive = true;
range.MaxKey = maxKey;
range.MaxInclusive = true;
return THolder<IteratorType>(database.IterateRangeGeneric<IteratorType>(TableId, range, columns).Release());
- }
-
- static bool Precharge(TToughDb& database, const KeyValuesType& keyValues, NTable::TTagsRef columns) {
+ }
+
+ static bool Precharge(TToughDb& database, const KeyValuesType& keyValues, NTable::TTagsRef columns) {
TTupleToRawTypeValueFixedSize<KeyValuesType, KeyColumnsType, FullKeySize> minKey(keyValues);
TTupleToRawTypeValue<KeyValuesType, KeyColumnsType> maxKey(keyValues);
return Precharger<AutoPrecharge>::Precharge(database, TableId, minKey, maxKey, columns, IteratorType::Direction);
- }
- };
-
+ }
+ };
+
template <typename, typename, typename>
- class GreaterOrEqualKeyIterator;
-
+ class GreaterOrEqualKeyIterator;
+
template <typename IteratorType, typename TableType, typename... KeyValuesTypes>
class GreaterOrEqualKeyIterator<IteratorType, TableType, std::tuple<KeyValuesTypes...>>
: public KeyIterator<IteratorType, GreaterOrEqualKeyIterator<IteratorType, TableType, std::tuple<KeyValuesTypes...>>>
{
- public:
- using KeyValuesType = std::tuple<KeyValuesTypes...>;
- using KeyColumnsType = typename first_n_of<sizeof...(KeyValuesTypes), typename TableType::TKey::KeyColumnsType>::type;
+ public:
+ using KeyValuesType = std::tuple<KeyValuesTypes...>;
+ using KeyColumnsType = typename first_n_of<sizeof...(KeyValuesTypes), typename TableType::TKey::KeyColumnsType>::type;
using Iterator = KeyIterator<IteratorType, GreaterOrEqualKeyIterator<IteratorType, TableType, KeyValuesType>>;
- static constexpr auto FullKeySize = std::tuple_size<typename TableType::TKey::KeyColumnsType>::value;
-
- GreaterOrEqualKeyIterator(TToughDb& database, const KeyValuesType& key, NTable::TTagsRef columns)
- : Iterator(MakeIterator(database, key, columns))
- {
- Iterator::Init();
- }
-
- GreaterOrEqualKeyIterator(GreaterOrEqualKeyIterator&&) = default;
- GreaterOrEqualKeyIterator& operator =(GreaterOrEqualKeyIterator&&) = default;
-
+ static constexpr auto FullKeySize = std::tuple_size<typename TableType::TKey::KeyColumnsType>::value;
+
+ GreaterOrEqualKeyIterator(TToughDb& database, const KeyValuesType& key, NTable::TTagsRef columns)
+ : Iterator(MakeIterator(database, key, columns))
+ {
+ Iterator::Init();
+ }
+
+ GreaterOrEqualKeyIterator(GreaterOrEqualKeyIterator&&) = default;
+ GreaterOrEqualKeyIterator& operator =(GreaterOrEqualKeyIterator&&) = default;
+
static THolder<IteratorType> MakeIterator(
TToughDb& database,
const KeyValuesType& keyValues,
@@ -1131,45 +1131,45 @@ struct Schema {
{
TTupleToRawTypeValueFixedSize<KeyValuesType, KeyColumnsType, FullKeySize> minKey(keyValues);
if (!Precharger<typename TableType::Precharge>::Precharge(database, TableId, minKey, {}, columns, IteratorType::Direction)) {
- return nullptr;
- }
+ return nullptr;
+ }
NTable::TKeyRange range;
range.MinKey = minKey;
range.MinInclusive = true;
range.MaxKey = { };
range.MaxInclusive = true;
return THolder<IteratorType>(database.IterateRangeGeneric<IteratorType>(TableId, range, columns).Release());
- }
-
- static bool Precharge(TToughDb& database, const KeyValuesType& keyValues, NTable::TTagsRef columns) {
+ }
+
+ static bool Precharge(TToughDb& database, const KeyValuesType& keyValues, NTable::TTagsRef columns) {
TTupleToRawTypeValueFixedSize<KeyValuesType, KeyColumnsType, FullKeySize> minKey(keyValues);
return Precharger<AutoPrecharge>::Precharge(database, TableId, minKey, {}, columns, IteratorType::Direction);
- }
- };
-
+ }
+ };
+
template <typename, typename, typename>
- class LessOrEqualKeyIterator;
-
+ class LessOrEqualKeyIterator;
+
template <typename IteratorType, typename TableType, typename... KeyValuesTypes>
class LessOrEqualKeyIterator<IteratorType, TableType, std::tuple<KeyValuesTypes...>>
: public KeyIterator<IteratorType, LessOrEqualKeyIterator<IteratorType, TableType, std::tuple<KeyValuesTypes...>>>
{
- public:
- using KeyValuesType = std::tuple<KeyValuesTypes...>;
- using KeyColumnsType = typename first_n_of<sizeof...(KeyValuesTypes), typename TableType::TKey::KeyColumnsType>::type;
+ public:
+ using KeyValuesType = std::tuple<KeyValuesTypes...>;
+ using KeyColumnsType = typename first_n_of<sizeof...(KeyValuesTypes), typename TableType::TKey::KeyColumnsType>::type;
using Iterator = KeyIterator<IteratorType, LessOrEqualKeyIterator<IteratorType, TableType, KeyValuesType>>;
-
- LessOrEqualKeyIterator(TToughDb& database, const KeyValuesType& key, NTable::TTagsRef columns)
- : Iterator(MakeIterator(database, key, columns))
- {
- Iterator::Init();
- }
-
- LessOrEqualKeyIterator(const LessOrEqualKeyIterator&) = delete;
-
+
+ LessOrEqualKeyIterator(TToughDb& database, const KeyValuesType& key, NTable::TTagsRef columns)
+ : Iterator(MakeIterator(database, key, columns))
+ {
+ Iterator::Init();
+ }
+
+ LessOrEqualKeyIterator(const LessOrEqualKeyIterator&) = delete;
+
LessOrEqualKeyIterator(LessOrEqualKeyIterator&& iterator) = default;
LessOrEqualKeyIterator& operator =(LessOrEqualKeyIterator&& iterator) = default;
-
+
static THolder<IteratorType> MakeIterator(
TToughDb& database,
const KeyValuesType& keyValues,
@@ -1178,21 +1178,21 @@ struct Schema {
TTupleToRawTypeValue<KeyValuesType, KeyColumnsType> maxKey(keyValues);
if (!Precharger<typename TableType::Precharge>::Precharge(database, TableId, {}, maxKey, columns, IteratorType::Direction)) {
return nullptr;
- }
+ }
NTable::TKeyRange range;
range.MinKey = { };
range.MinInclusive = true;
range.MaxKey = maxKey;
range.MaxInclusive = true;
return THolder<IteratorType>(database.IterateRangeGeneric<IteratorType>(TableId, range, columns).Release());
- }
-
- static bool Precharge(TToughDb& database, const KeyValuesType& keyValues, NTable::TTagsRef columns) {
+ }
+
+ static bool Precharge(TToughDb& database, const KeyValuesType& keyValues, NTable::TTagsRef columns) {
TTupleToRawTypeValue<KeyValuesType, KeyColumnsType> maxKey(keyValues);
return Precharger<AutoPrecharge>::Precharge(database, TableId, {}, maxKey, columns, IteratorType::Direction);
- }
- };
-
+ }
+ };
+
template <typename, typename, typename, typename>
class RangeKeyIterator;
@@ -1200,31 +1200,31 @@ struct Schema {
class RangeKeyIterator<IteratorType, TableType, std::tuple<MinKeyValuesTypes...>, std::tuple<MaxKeyValuesTypes...>>
: public KeyIterator<IteratorType, RangeKeyIterator<IteratorType, TableType, std::tuple<MinKeyValuesTypes...>, std::tuple<MaxKeyValuesTypes...>>>
{
- public:
+ public:
using MinKeyValuesType = std::tuple<MinKeyValuesTypes...>;
using MinKeyColumnsType = typename first_n_of<sizeof...(MinKeyValuesTypes), typename TableType::TKey::KeyColumnsType>::type;
using MaxKeyValuesType = std::tuple<MaxKeyValuesTypes...>;
using MaxKeyColumnsType = typename first_n_of<sizeof...(MaxKeyValuesTypes), typename TableType::TKey::KeyColumnsType>::type;
using Iterator = KeyIterator<IteratorType, RangeKeyIterator<IteratorType, TableType, MinKeyValuesType, MaxKeyValuesType>>;
- static constexpr auto FullKeySize = std::tuple_size<typename TableType::TKey::KeyColumnsType>::value;
-
- RangeKeyIterator(TToughDb& database,
+ static constexpr auto FullKeySize = std::tuple_size<typename TableType::TKey::KeyColumnsType>::value;
+
+ RangeKeyIterator(TToughDb& database,
const MinKeyValuesType& minKey,
const MaxKeyValuesType& maxKey,
- NTable::TTagsRef columns)
+ NTable::TTagsRef columns)
: Iterator(MakeIterator(database, minKey, maxKey, columns))
- {
- Iterator::Init();
- }
-
- RangeKeyIterator(const RangeKeyIterator&) = delete;
-
+ {
+ Iterator::Init();
+ }
+
+ RangeKeyIterator(const RangeKeyIterator&) = delete;
+
RangeKeyIterator(RangeKeyIterator&& iterator) = default;
RangeKeyIterator& operator =(RangeKeyIterator&& iterator) = default;
-
+
static THolder<IteratorType> MakeIterator(
- TToughDb& database,
+ TToughDb& database,
const MinKeyValuesType& minKeyValues,
const MaxKeyValuesType& maxKeyValues,
NTable::TTagsRef columns)
@@ -1232,17 +1232,17 @@ struct Schema {
TTupleToRawTypeValueFixedSize<MinKeyValuesType, MinKeyColumnsType, FullKeySize> minKey(minKeyValues);
TTupleToRawTypeValue<MaxKeyValuesType, MaxKeyColumnsType> maxKey(maxKeyValues);
if (!Precharger<typename TableType::Precharge>::Precharge(database, TableId, minKey, maxKey, columns, IteratorType::Direction)) {
- return nullptr;
- }
+ return nullptr;
+ }
NTable::TKeyRange range;
range.MinKey = minKey;
range.MinInclusive = true;
range.MaxKey = maxKey;
range.MaxInclusive = true;
return THolder<IteratorType>(database.IterateRangeGeneric<IteratorType>(TableId, range, columns).Release());
- }
-
- static bool Precharge(TToughDb& database,
+ }
+
+ static bool Precharge(TToughDb& database,
const MinKeyValuesType& minKeyValues,
const MaxKeyValuesType& maxKeyValues,
NTable::TTagsRef columns)
@@ -1250,227 +1250,227 @@ struct Schema {
TTupleToRawTypeValueFixedSize<MinKeyValuesType, MinKeyColumnsType, FullKeySize> minKey(minKeyValues);
TTupleToRawTypeValue<MaxKeyValuesType, MaxKeyColumnsType> maxKey(maxKeyValues);
return Precharger<AutoPrecharge>::Precharge(database, TableId, minKey, maxKey, columns, IteratorType::Direction);
- }
- };
-
- template <typename TableType, typename KeyValuesType>
+ }
+ };
+
+ template <typename TableType, typename KeyValuesType>
class EqualKeyIterator
: public KeyIterator<NTable::TTableIt, EqualKeyIterator<TableType, KeyValuesType>>
{
public:
- using KeyColumnsType = typename TableType::TKey::KeyColumnsType;
+ using KeyColumnsType = typename TableType::TKey::KeyColumnsType;
using Iterator = KeyIterator<NTable::TTableIt, EqualKeyIterator<TableType, KeyValuesType>>;
-
- EqualKeyIterator(TToughDb& database, const KeyValuesType& key, NTable::TTagsRef columns)
- : Iterator(MakeIterator(database, key, columns))
- {
- Iterator::Init();
- }
-
- EqualKeyIterator(const EqualKeyIterator&) = delete;
-
+
+ EqualKeyIterator(TToughDb& database, const KeyValuesType& key, NTable::TTagsRef columns)
+ : Iterator(MakeIterator(database, key, columns))
+ {
+ Iterator::Init();
+ }
+
+ EqualKeyIterator(const EqualKeyIterator&) = delete;
+
EqualKeyIterator(EqualKeyIterator&& iterator) = default;
EqualKeyIterator& operator =(EqualKeyIterator&& iterator) = default;
-
- static THolder<NTable::TTableIt> MakeIterator(TToughDb& database, const KeyValuesType& keyValues, NTable::TTagsRef columns) {
- TTupleToRawTypeValue<KeyValuesType, KeyColumnsType> key(keyValues);
+
+ static THolder<NTable::TTableIt> MakeIterator(TToughDb& database, const KeyValuesType& keyValues, NTable::TTagsRef columns) {
+ TTupleToRawTypeValue<KeyValuesType, KeyColumnsType> key(keyValues);
return THolder<NTable::TTableIt>(database.IterateExact(TableId, key, columns).Release());
- }
-
- static bool Precharge(TToughDb& database, const KeyValuesType& keyValues, NTable::TTagsRef columns) {
- TTupleToRawTypeValue<KeyValuesType, KeyColumnsType> key(keyValues);
+ }
+
+ static bool Precharge(TToughDb& database, const KeyValuesType& keyValues, NTable::TTagsRef columns) {
+ TTupleToRawTypeValue<KeyValuesType, KeyColumnsType> key(keyValues);
return Precharger<AutoPrecharge>::Precharge(database, TableId, key, key, columns, NTable::TTableIt::Direction);
- }
- };
-
- template <typename> class ColumnsValueTuple;
- template <typename... KeyColumnsTypes>
- class ColumnsValueTuple<std::tuple<KeyColumnsTypes...>> {
- public:
- template <typename RowsetType>
- static auto Get(RowsetType& rowset) {
- return rowset.template GetValue<KeyColumnsTypes...>();
- }
- };
-
- template <typename TableType, typename KeyIterator, typename... ColumnTypes>
- class Rowset {
- public:
+ }
+ };
+
+ template <typename> class ColumnsValueTuple;
+ template <typename... KeyColumnsTypes>
+ class ColumnsValueTuple<std::tuple<KeyColumnsTypes...>> {
+ public:
+ template <typename RowsetType>
+ static auto Get(RowsetType& rowset) {
+ return rowset.template GetValue<KeyColumnsTypes...>();
+ }
+ };
+
+ template <typename TableType, typename KeyIterator, typename... ColumnTypes>
+ class Rowset {
+ public:
template <typename... Cs>
static Columns<Cs...> GetColumns(Columns<Cs...>) { return Columns<Cs...>(); }
template <typename... Cs>
static Columns<Cs...> GetColumns(Columns<TableColumns<Cs...>>) { return Columns<Cs...>(); }
using ColumnsType = decltype(GetColumns(Columns<ColumnTypes...>()));
- template <typename... Args>
- Rowset(TToughDb& database, Args&&... args)
- : Iterator(database, std::forward<Args>(args)...)
- {}
+ template <typename... Args>
+ Rowset(TToughDb& database, Args&&... args)
+ : Iterator(database, std::forward<Args>(args)...)
+ {}
bool IsReady() const {
- return Iterator.IsReady();
+ return Iterator.IsReady();
}
bool IsValid() const {
- return Iterator.IsValid();
+ return Iterator.IsValid();
+ }
+
+ bool IsOk() const {
+ return Iterator.IsReady() && Iterator.IsValid();
+ }
+
+ bool EndOfSet() const {
+ return !IsValid();
+ }
+
+ bool Next() {
+ return Iterator.Next();
}
- bool IsOk() const {
- return Iterator.IsReady() && Iterator.IsValid();
- }
-
- bool EndOfSet() const {
- return !IsValid();
- }
-
- bool Next() {
- return Iterator.Next();
- }
-
template <typename... ColumnType>
- auto GetValue() const {
- Y_VERIFY_DEBUG(IsReady(), "Rowset is not ready");
- Y_VERIFY_DEBUG(IsValid(), "Rowset is not valid");
+ auto GetValue() const {
+ Y_VERIFY_DEBUG(IsReady(), "Rowset is not ready");
+ Y_VERIFY_DEBUG(IsValid(), "Rowset is not valid");
typename Columns<ColumnType...>::Type value(GetColumnValue<ColumnType>()...);
return value;
}
template <typename ColumnType>
- auto GetValueOrDefault(typename ColumnType::Type defaultValue = GetDefaultValue<ColumnType>(SFINAE::special())) const {
- Y_VERIFY_DEBUG(IsReady(), "Rowset is not ready");
- Y_VERIFY_DEBUG(IsValid(), "Rowset is not valid");
+ auto GetValueOrDefault(typename ColumnType::Type defaultValue = GetDefaultValue<ColumnType>(SFINAE::special())) const {
+ Y_VERIFY_DEBUG(IsReady(), "Rowset is not ready");
+ Y_VERIFY_DEBUG(IsValid(), "Rowset is not valid");
typename ColumnType::Type value(HaveValue<ColumnType>() ? GetColumnValue<ColumnType>() : defaultValue);
return value;
}
- auto GetKey() const {
- return ColumnsValueTuple<typename TableType::TKey::KeyColumnsType>::Get(*this);
+ auto GetKey() const {
+ return ColumnsValueTuple<typename TableType::TKey::KeyColumnsType>::Get(*this);
}
template <typename ColumnType>
bool HaveValue() const {
- size_t index = GetIndex<ColumnType>();
- TDbTupleRef tuple = Iterator.GetValues();
- auto& cell = tuple.Columns[index];
+ size_t index = GetIndex<ColumnType>();
+ TDbTupleRef tuple = Iterator.GetValues();
+ auto& cell = tuple.Columns[index];
return !cell.IsNull();
}
- TString DbgPrint(const NScheme::TTypeRegistry& typeRegistry) {
- Y_VERIFY_DEBUG(IsReady(), "Rowset is not ready");
- Y_VERIFY_DEBUG(IsValid(), "Rowset is not valid");
- return DbgPrintTuple(Iterator.GetKey(), typeRegistry) + " -> " + DbgPrintTuple(Iterator.GetValues(), typeRegistry);
- }
-
- template <typename ColumnType, typename SFINAE::type_check<decltype(ColumnType::Default)>::type = 0>
- static decltype(ColumnType::Default) GetNullValue(SFINAE::special) {
- return ColumnType::Default;
- }
-
+ TString DbgPrint(const NScheme::TTypeRegistry& typeRegistry) {
+ Y_VERIFY_DEBUG(IsReady(), "Rowset is not ready");
+ Y_VERIFY_DEBUG(IsValid(), "Rowset is not valid");
+ return DbgPrintTuple(Iterator.GetKey(), typeRegistry) + " -> " + DbgPrintTuple(Iterator.GetValues(), typeRegistry);
+ }
+
+ template <typename ColumnType, typename SFINAE::type_check<decltype(ColumnType::Default)>::type = 0>
+ static decltype(ColumnType::Default) GetNullValue(SFINAE::special) {
+ return ColumnType::Default;
+ }
+
template <typename ColumnType>
- static typename ColumnType::Type GetNullValue(SFINAE::general) {
- return typename ColumnType::Type();
- }
-
- template <typename ColumnType, typename SFINAE::type_check<decltype(ColumnType::Default)>::type = 0>
- static decltype(ColumnType::Default) GetDefaultValue(SFINAE::special) {
- return ColumnType::Default;
- }
-
- template <typename ColumnType>
- static typename ColumnType::Type GetDefaultValue(SFINAE::general) {
- return typename ColumnType::Type();
- }
-
+ static typename ColumnType::Type GetNullValue(SFINAE::general) {
+ return typename ColumnType::Type();
+ }
+
+ template <typename ColumnType, typename SFINAE::type_check<decltype(ColumnType::Default)>::type = 0>
+ static decltype(ColumnType::Default) GetDefaultValue(SFINAE::special) {
+ return ColumnType::Default;
+ }
+
+ template <typename ColumnType>
+ static typename ColumnType::Type GetDefaultValue(SFINAE::general) {
+ return typename ColumnType::Type();
+ }
+
NTable::TIteratorStats* Stats() const {
return Iterator.Stats();
}
- protected:
- template <typename ColumnType>
- static constexpr size_t GetIndex() {
- return ColumnsType::template GetIndex<ColumnType>();
- }
-
- template <typename ColumnType>
+ protected:
+ template <typename ColumnType>
+ static constexpr size_t GetIndex() {
+ return ColumnsType::template GetIndex<ColumnType>();
+ }
+
+ template <typename ColumnType>
typename ColumnType::Type GetColumnValue() const {
- size_t index = GetIndex<ColumnType>();
- TDbTupleRef tuple = Iterator.GetValues();
- auto& cell = tuple.Columns[index];
- auto type = tuple.Types[index];
- if (cell.IsNull())
- return GetNullValue<ColumnType>(SFINAE::special());
- return TConvert<ColumnType, typename ColumnType::Type>::Convert(TRawTypeValue(cell.Data(), cell.Size(), type));
+ size_t index = GetIndex<ColumnType>();
+ TDbTupleRef tuple = Iterator.GetValues();
+ auto& cell = tuple.Columns[index];
+ auto type = tuple.Types[index];
+ if (cell.IsNull())
+ return GetNullValue<ColumnType>(SFINAE::special());
+ return TConvert<ColumnType, typename ColumnType::Type>::Convert(TRawTypeValue(cell.Data(), cell.Size(), type));
}
- KeyIterator Iterator;
+ KeyIterator Iterator;
};
- };
+ };
template <typename IteratorType, typename TableType>
- class AnyKeyOperations: public Operations {
- public:
- using KeyColumnsType = typename TableType::TKey::KeyColumnsType;
+ class AnyKeyOperations: public Operations {
+ public:
+ using KeyColumnsType = typename TableType::TKey::KeyColumnsType;
- template <typename KeyIterator, typename... Columns>
- using Rowset = typename Operations::template Rowset<KeyIterator, Columns...>;
+ template <typename KeyIterator, typename... Columns>
+ using Rowset = typename Operations::template Rowset<KeyIterator, Columns...>;
using Iterator = typename Operations::template AnyKeyIterator<IteratorType, TableType>;
-
+
using ReverseOperations = AnyKeyOperations<ReverseIteratorType<IteratorType>, TableType>;
- protected:
- TToughDb* Database;
-
- public:
- AnyKeyOperations(TToughDb& database)
- : Database(&database)
- {}
-
- AnyKeyOperations(AnyKeyOperations&&) = default;
- AnyKeyOperations& operator =(AnyKeyOperations&&) = default;
-
- template <typename... ColumnTypes>
- auto Select() {
- return Rowset<TableType, Iterator, ColumnTypes...>(*Database, Columns<ColumnTypes...>::GetColumnIds());
- }
-
- auto Select() {
- return Rowset<TableType, Iterator, typename TableType::TColumns>(*Database, Columns<typename TableType::TColumns>::GetColumnIds());
- }
-
- template <typename... ColumnTypes>
- bool Precharge() {
- return Iterator::Precharge(*Database, Columns<ColumnTypes...>::GetColumnIds());
- }
-
- bool Precharge() {
- return Iterator::Precharge(*Database, Columns<typename TableType::TColumns>::GetColumnIds());
- }
+ protected:
+ TToughDb* Database;
+
+ public:
+ AnyKeyOperations(TToughDb& database)
+ : Database(&database)
+ {}
+
+ AnyKeyOperations(AnyKeyOperations&&) = default;
+ AnyKeyOperations& operator =(AnyKeyOperations&&) = default;
+
+ template <typename... ColumnTypes>
+ auto Select() {
+ return Rowset<TableType, Iterator, ColumnTypes...>(*Database, Columns<ColumnTypes...>::GetColumnIds());
+ }
+
+ auto Select() {
+ return Rowset<TableType, Iterator, typename TableType::TColumns>(*Database, Columns<typename TableType::TColumns>::GetColumnIds());
+ }
+
+ template <typename... ColumnTypes>
+ bool Precharge() {
+ return Iterator::Precharge(*Database, Columns<ColumnTypes...>::GetColumnIds());
+ }
+
+ bool Precharge() {
+ return Iterator::Precharge(*Database, Columns<typename TableType::TColumns>::GetColumnIds());
+ }
auto Reverse() const {
return ReverseOperations(*Database);
}
- };
-
+ };
+
template <typename IteratorType, typename TableType, typename... KeyValuesTypes>
class KeyPrefixOperations<IteratorType, TableType, std::tuple<KeyValuesTypes...>>: public Operations {
- public:
- using KeyColumnsType = typename first_n_of<sizeof...(KeyValuesTypes), typename TableType::TKey::KeyColumnsType>::type;
- using KeyValuesType = typename first_n_of<sizeof...(KeyValuesTypes), typename TableType::TKey::RealKeyValuesType>::type;
-
- template <typename KeyIterator, typename... Columns>
- using Rowset = typename Operations::template Rowset<KeyIterator, Columns...>;
+ public:
+ using KeyColumnsType = typename first_n_of<sizeof...(KeyValuesTypes), typename TableType::TKey::KeyColumnsType>::type;
+ using KeyValuesType = typename first_n_of<sizeof...(KeyValuesTypes), typename TableType::TKey::RealKeyValuesType>::type;
+
+ template <typename KeyIterator, typename... Columns>
+ using Rowset = typename Operations::template Rowset<KeyIterator, Columns...>;
using Iterator = typename Operations::template EqualPartialKeyIterator<IteratorType, TableType, KeyValuesType>;
-
+
using ReverseOperations = KeyPrefixOperations<ReverseIteratorType<IteratorType>, TableType, std::tuple<KeyValuesTypes...>>;
- protected:
- TToughDb* Database;
- KeyValuesType KeyValues;
-
- public:
- KeyPrefixOperations(TToughDb& database, KeyValuesTypes... keyValues)
- : Database(&database)
- , KeyValues(keyValues...)
+ protected:
+ TToughDb* Database;
+ KeyValuesType KeyValues;
+
+ public:
+ KeyPrefixOperations(TToughDb& database, KeyValuesTypes... keyValues)
+ : Database(&database)
+ , KeyValues(keyValues...)
{}
explicit KeyPrefixOperations(const ReverseOperations& rhs)
@@ -1483,26 +1483,26 @@ struct Schema {
, KeyValues(std::move(rhs.KeyValues))
{ }
- KeyPrefixOperations(KeyPrefixOperations&&) = default;
- KeyPrefixOperations& operator =(KeyPrefixOperations&&) = default;
-
- template <typename... ColumnTypes>
- auto Select() {
- return Rowset<TableType, Iterator, ColumnTypes...>(*Database, KeyValues, Columns<ColumnTypes...>::GetColumnIds());
- }
-
- auto Select() {
- return Rowset<TableType, Iterator, typename TableType::TColumns>(*Database, KeyValues, Columns<typename TableType::TColumns>::GetColumnIds());
- }
-
- template <typename... ColumnTypes>
- bool Precharge() {
- return Iterator::Precharge(*Database, KeyValues, Columns<ColumnTypes...>::GetColumnIds());
- }
-
- bool Precharge() {
- return Iterator::Precharge(*Database, KeyValues, Columns<typename TableType::TColumns>::GetColumnIds());
- }
+ KeyPrefixOperations(KeyPrefixOperations&&) = default;
+ KeyPrefixOperations& operator =(KeyPrefixOperations&&) = default;
+
+ template <typename... ColumnTypes>
+ auto Select() {
+ return Rowset<TableType, Iterator, ColumnTypes...>(*Database, KeyValues, Columns<ColumnTypes...>::GetColumnIds());
+ }
+
+ auto Select() {
+ return Rowset<TableType, Iterator, typename TableType::TColumns>(*Database, KeyValues, Columns<typename TableType::TColumns>::GetColumnIds());
+ }
+
+ template <typename... ColumnTypes>
+ bool Precharge() {
+ return Iterator::Precharge(*Database, KeyValues, Columns<ColumnTypes...>::GetColumnIds());
+ }
+
+ bool Precharge() {
+ return Iterator::Precharge(*Database, KeyValues, Columns<typename TableType::TColumns>::GetColumnIds());
+ }
auto Reverse() const & {
return ReverseOperations(*this);
@@ -1511,30 +1511,30 @@ struct Schema {
auto Reverse() && {
return ReverseOperations(std::move(*this));
}
- };
-
+ };
+
template <typename IteratorType, typename TableType, typename... KeyValuesTypes>
class GreaterOrEqualKeyOperations<IteratorType, TableType, std::tuple<KeyValuesTypes...>>: public Operations {
public:
- using KeyColumnsType = typename TableType::TKey::KeyColumnsType;
- using KeyValuesType = typename first_n_of<sizeof...(KeyValuesTypes), typename TableType::TKey::RealKeyValuesType>::type;
-
- template <typename KeyIterator, typename... Columns>
- using Rowset = typename Operations::template Rowset<KeyIterator, Columns...>;
+ using KeyColumnsType = typename TableType::TKey::KeyColumnsType;
+ using KeyValuesType = typename first_n_of<sizeof...(KeyValuesTypes), typename TableType::TKey::RealKeyValuesType>::type;
+
+ template <typename KeyIterator, typename... Columns>
+ using Rowset = typename Operations::template Rowset<KeyIterator, Columns...>;
using Iterator = typename Operations::template GreaterOrEqualKeyIterator<IteratorType, TableType, KeyValuesType>;
-
+
using ReverseOperations = GreaterOrEqualKeyOperations<ReverseIteratorType<IteratorType>, TableType, std::tuple<KeyValuesTypes...>>;
- protected:
- TToughDb* Database;
- KeyValuesType KeyValues;
-
- public:
- GreaterOrEqualKeyOperations(TToughDb& database, KeyValuesTypes... keyValues)
- : Database(&database)
- , KeyValues(keyValues...)
- {}
-
+ protected:
+ TToughDb* Database;
+ KeyValuesType KeyValues;
+
+ public:
+ GreaterOrEqualKeyOperations(TToughDb& database, KeyValuesTypes... keyValues)
+ : Database(&database)
+ , KeyValues(keyValues...)
+ {}
+
explicit GreaterOrEqualKeyOperations(const ReverseOperations& rhs)
: Database(rhs.Database)
, KeyValues(rhs.KeyValues)
@@ -1545,33 +1545,33 @@ struct Schema {
, KeyValues(std::move(rhs.KeyValues))
{ }
- GreaterOrEqualKeyOperations(GreaterOrEqualKeyOperations&&) = default;
- GreaterOrEqualKeyOperations& operator =(GreaterOrEqualKeyOperations&&) = default;
-
- template <typename... Keys>
- auto LessOrEqual(Keys... keyValues) {
+ GreaterOrEqualKeyOperations(GreaterOrEqualKeyOperations&&) = default;
+ GreaterOrEqualKeyOperations& operator =(GreaterOrEqualKeyOperations&&) = default;
+
+ template <typename... Keys>
+ auto LessOrEqual(Keys... keyValues) {
using MinKeyValuesType = KeyValuesType;
using MaxKeyValuesType = typename first_n_of<sizeof...(Keys), typename TableType::TKey::KeyValuesType>::type;
return RangeKeyOperations<IteratorType, TableType, MinKeyValuesType, MaxKeyValuesType>(*Database, KeyValues, keyValues...);
- }
-
+ }
+
template <typename... ColumnTypes>
- auto Select() {
- return Rowset<TableType, Iterator, ColumnTypes...>(*Database, KeyValues, Columns<ColumnTypes...>::GetColumnIds());
- }
-
- auto Select() {
- return Rowset<TableType, Iterator, typename TableType::TColumns>(*Database, KeyValues, Columns<typename TableType::TColumns>::GetColumnIds());
- }
-
- template <typename... ColumnTypes>
- bool Precharge() {
- return Iterator::Precharge(*Database, KeyValues, Columns<ColumnTypes...>::GetColumnIds());
- }
-
- bool Precharge() {
- return Iterator::Precharge(*Database, KeyValues, Columns<typename TableType::TColumns>::GetColumnIds());
- }
+ auto Select() {
+ return Rowset<TableType, Iterator, ColumnTypes...>(*Database, KeyValues, Columns<ColumnTypes...>::GetColumnIds());
+ }
+
+ auto Select() {
+ return Rowset<TableType, Iterator, typename TableType::TColumns>(*Database, KeyValues, Columns<typename TableType::TColumns>::GetColumnIds());
+ }
+
+ template <typename... ColumnTypes>
+ bool Precharge() {
+ return Iterator::Precharge(*Database, KeyValues, Columns<ColumnTypes...>::GetColumnIds());
+ }
+
+ bool Precharge() {
+ return Iterator::Precharge(*Database, KeyValues, Columns<typename TableType::TColumns>::GetColumnIds());
+ }
auto Reverse() const & {
return ReverseOperations(*this);
@@ -1580,30 +1580,30 @@ struct Schema {
auto Reverse() && {
return ReverseOperations(std::move(*this));
}
- };
-
+ };
+
template <typename IteratorType, typename TableType, typename... KeyValuesTypes>
class LessOrEqualKeyOperations<IteratorType, TableType, std::tuple<KeyValuesTypes...>>: public Operations {
- public:
- using KeyColumnsType = typename TableType::TKey::KeyColumnsType;
- using KeyValuesType = typename first_n_of<sizeof...(KeyValuesTypes), typename TableType::TKey::RealKeyValuesType>::type;
-
- template <typename KeyIterator, typename... Columns>
- using Rowset = typename Operations::template Rowset<KeyIterator, Columns...>;
+ public:
+ using KeyColumnsType = typename TableType::TKey::KeyColumnsType;
+ using KeyValuesType = typename first_n_of<sizeof...(KeyValuesTypes), typename TableType::TKey::RealKeyValuesType>::type;
+
+ template <typename KeyIterator, typename... Columns>
+ using Rowset = typename Operations::template Rowset<KeyIterator, Columns...>;
using Iterator = typename Operations::template LessOrEqualKeyIterator<IteratorType, TableType, KeyValuesType>;
-
+
using ReverseOperations = LessOrEqualKeyOperations<ReverseIteratorType<IteratorType>, TableType, std::tuple<KeyValuesTypes...>>;
- protected:
- TToughDb* Database;
- KeyValuesType KeyValues;
-
- public:
- LessOrEqualKeyOperations(TToughDb& database, KeyValuesTypes... keyValues)
- : Database(&database)
- , KeyValues(keyValues...)
- {}
-
+ protected:
+ TToughDb* Database;
+ KeyValuesType KeyValues;
+
+ public:
+ LessOrEqualKeyOperations(TToughDb& database, KeyValuesTypes... keyValues)
+ : Database(&database)
+ , KeyValues(keyValues...)
+ {}
+
explicit LessOrEqualKeyOperations(const ReverseOperations& rhs)
: Database(rhs.Database)
, KeyValues(rhs.KeyValues)
@@ -1614,9 +1614,9 @@ struct Schema {
, KeyValues(std::move(rhs.KeyValues))
{ }
- LessOrEqualKeyOperations(LessOrEqualKeyOperations&&) = default;
- LessOrEqualKeyOperations& operator =(LessOrEqualKeyOperations&&) = default;
-
+ LessOrEqualKeyOperations(LessOrEqualKeyOperations&&) = default;
+ LessOrEqualKeyOperations& operator =(LessOrEqualKeyOperations&&) = default;
+
template <typename... Keys>
auto GreaterOrEqual(Keys... keyValues) {
using MinKeyValuesType = typename first_n_of<sizeof...(Keys), typename TableType::TKey::KeyValuesType>::type;
@@ -1624,23 +1624,23 @@ struct Schema {
return RangeKeyOperations<IteratorType, TableType, MinKeyValuesType, MaxKeyValuesType>(*Database, keyValues..., KeyValues);
}
- template <typename... ColumnTypes>
- auto Select() {
- return Rowset<TableType, Iterator, ColumnTypes...>(*Database, KeyValues, Columns<ColumnTypes...>::GetColumnIds());
- }
-
- auto Select() {
- return Rowset<TableType, Iterator, typename TableType::TColumns>(*Database, KeyValues, Columns<typename TableType::TColumns>::GetColumnIds());
- }
-
- template <typename... ColumnTypes>
- bool Precharge() {
- return Iterator::Precharge(*Database, KeyValues, Columns<ColumnTypes...>::GetColumnIds());
- }
-
- bool Precharge() {
- return Iterator::Precharge(*Database, KeyValues, Columns<typename TableType::TColumns>::GetColumnIds());
- }
+ template <typename... ColumnTypes>
+ auto Select() {
+ return Rowset<TableType, Iterator, ColumnTypes...>(*Database, KeyValues, Columns<ColumnTypes...>::GetColumnIds());
+ }
+
+ auto Select() {
+ return Rowset<TableType, Iterator, typename TableType::TColumns>(*Database, KeyValues, Columns<typename TableType::TColumns>::GetColumnIds());
+ }
+
+ template <typename... ColumnTypes>
+ bool Precharge() {
+ return Iterator::Precharge(*Database, KeyValues, Columns<ColumnTypes...>::GetColumnIds());
+ }
+
+ bool Precharge() {
+ return Iterator::Precharge(*Database, KeyValues, Columns<typename TableType::TColumns>::GetColumnIds());
+ }
auto Reverse() const & {
return ReverseOperations(*this);
@@ -1649,33 +1649,33 @@ struct Schema {
auto Reverse() && {
return ReverseOperations(std::move(*this));
}
- };
-
+ };
+
template <typename IteratorType, typename TableType, typename... MinKeyValuesTypes, typename... MaxKeyValuesTypes>
class RangeKeyOperations<IteratorType, TableType, std::tuple<MinKeyValuesTypes...>, std::tuple<MaxKeyValuesTypes...>>: public Operations {
- public:
- using KeyColumnsType = typename TableType::TKey::KeyColumnsType;
+ public:
+ using KeyColumnsType = typename TableType::TKey::KeyColumnsType;
using MinKeyValuesType = typename first_n_of<sizeof...(MinKeyValuesTypes), typename TableType::TKey::RealKeyValuesType>::type;
using MaxKeyValuesType = typename first_n_of<sizeof...(MaxKeyValuesTypes), typename TableType::TKey::RealKeyValuesType>::type;
-
- template <typename KeyIterator, typename... Columns>
- using Rowset = typename Operations::template Rowset<KeyIterator, Columns...>;
+
+ template <typename KeyIterator, typename... Columns>
+ using Rowset = typename Operations::template Rowset<KeyIterator, Columns...>;
using Iterator = typename Operations::template RangeKeyIterator<IteratorType, TableType, MinKeyValuesType, MaxKeyValuesType>;
-
+
using ReverseOperations = RangeKeyOperations<ReverseIteratorType<IteratorType>, TableType, std::tuple<MinKeyValuesTypes...>, std::tuple<MaxKeyValuesTypes...>>;
- protected:
- TToughDb* Database;
+ protected:
+ TToughDb* Database;
MinKeyValuesType MinKeyValues;
MaxKeyValuesType MaxKeyValues;
-
- public:
+
+ public:
RangeKeyOperations(TToughDb& database, const MinKeyValuesType& minKeyValues, MaxKeyValuesTypes... maxKeyValues)
- : Database(&database)
+ : Database(&database)
, MinKeyValues(minKeyValues)
, MaxKeyValues(maxKeyValues...)
- {}
-
+ {}
+
RangeKeyOperations(TToughDb& database, MinKeyValuesTypes... minKeyValues, const MaxKeyValuesType& maxKeyValues)
: Database(&database)
, MinKeyValues(minKeyValues...)
@@ -1694,26 +1694,26 @@ struct Schema {
, MaxKeyValues(std::move(rhs.MaxKeyValues))
{ }
- RangeKeyOperations(RangeKeyOperations&&) = default;
- RangeKeyOperations& operator =(RangeKeyOperations&&) = default;
-
- template <typename... ColumnTypes>
- auto Select() {
+ RangeKeyOperations(RangeKeyOperations&&) = default;
+ RangeKeyOperations& operator =(RangeKeyOperations&&) = default;
+
+ template <typename... ColumnTypes>
+ auto Select() {
return Rowset<TableType, Iterator, ColumnTypes...>(*Database, MinKeyValues, MaxKeyValues, Columns<ColumnTypes...>::GetColumnIds());
- }
-
- auto Select() {
+ }
+
+ auto Select() {
return Rowset<TableType, Iterator, typename TableType::TColumns>(*Database, MinKeyValues, MaxKeyValues, Columns<typename TableType::TColumns>::GetColumnIds());
- }
-
- template <typename... ColumnTypes>
- bool Precharge() {
+ }
+
+ template <typename... ColumnTypes>
+ bool Precharge() {
return Iterator::Precharge(*Database, MinKeyValues, MaxKeyValues, Columns<ColumnTypes...>::GetColumnIds());
- }
-
- bool Precharge() {
+ }
+
+ bool Precharge() {
return Iterator::Precharge(*Database, MinKeyValues, MaxKeyValues, Columns<typename TableType::TColumns>::GetColumnIds());
- }
+ }
auto Reverse() const & {
return ReverseOperations(*this);
@@ -1722,115 +1722,115 @@ struct Schema {
auto Reverse() && {
return ReverseOperations(std::move(*this));
}
- };
-
- template <typename TableType, typename... KeyValuesTypes>
- class KeyOperations<TableType, std::tuple<KeyValuesTypes...>>: public Operations {
- public:
- using KeyColumnsType = typename TableType::TKey::KeyColumnsType;
- using KeyValuesType = typename TableType::TKey::RealKeyValuesType;
-
- template <typename KeyIterator, typename... Columns>
- using Rowset = typename Operations::template Rowset<KeyIterator, Columns...>;
- using Iterator = typename Operations::template EqualKeyIterator<TableType, KeyValuesType>;
-
- protected:
- TToughDb* Database;
- KeyValuesType KeyValues;
-
- public:
- KeyOperations(TToughDb& database, KeyValuesTypes... keyValues)
- : Database(&database)
- , KeyValues(keyValues...)
- {}
-
- KeyOperations(TToughDb& database, const KeyValuesType& keyValues)
- : Database(&database)
- , KeyValues(keyValues)
- {}
-
- KeyOperations(KeyOperations&&) = default;
- KeyOperations& operator =(KeyOperations&&) = default;
-
- template <typename... ColumnTypes>
- auto Select() {
- // TODO
- //static_assert(have columns?, "fail");
- return Rowset<TableType, Iterator, ColumnTypes...>(*Database, KeyValues, Columns<ColumnTypes...>::GetColumnIds());
- }
-
- auto Select() {
- return Rowset<TableType, Iterator, typename TableType::TColumns>(*Database, KeyValues, Columns<typename TableType::TColumns>::GetColumnIds());
- }
-
- template <typename... ColumnTypes>
- bool Precharge() {
- return Iterator::Precharge(*Database, KeyValues, Columns<ColumnTypes...>::GetColumnIds());
- }
-
- bool Precharge() {
- return Iterator::Precharge(*Database, KeyValues, Columns<typename TableType::TColumns>::GetColumnIds());
- }
-
- template <typename... ColumnTypes>
- KeyOperations& Update(const typename ColumnTypes::Type&... value) {
- return Update(TUpdate<ColumnTypes>(value)...);
- }
-
- template <typename... ColumnTypes>
- KeyOperations& UpdateToNull() {
- return Update(TNull<ColumnTypes>()...);
- }
-
+ };
+
+ template <typename TableType, typename... KeyValuesTypes>
+ class KeyOperations<TableType, std::tuple<KeyValuesTypes...>>: public Operations {
+ public:
+ using KeyColumnsType = typename TableType::TKey::KeyColumnsType;
+ using KeyValuesType = typename TableType::TKey::RealKeyValuesType;
+
+ template <typename KeyIterator, typename... Columns>
+ using Rowset = typename Operations::template Rowset<KeyIterator, Columns...>;
+ using Iterator = typename Operations::template EqualKeyIterator<TableType, KeyValuesType>;
+
+ protected:
+ TToughDb* Database;
+ KeyValuesType KeyValues;
+
+ public:
+ KeyOperations(TToughDb& database, KeyValuesTypes... keyValues)
+ : Database(&database)
+ , KeyValues(keyValues...)
+ {}
+
+ KeyOperations(TToughDb& database, const KeyValuesType& keyValues)
+ : Database(&database)
+ , KeyValues(keyValues)
+ {}
+
+ KeyOperations(KeyOperations&&) = default;
+ KeyOperations& operator =(KeyOperations&&) = default;
+
+ template <typename... ColumnTypes>
+ auto Select() {
+ // TODO
+ //static_assert(have columns?, "fail");
+ return Rowset<TableType, Iterator, ColumnTypes...>(*Database, KeyValues, Columns<ColumnTypes...>::GetColumnIds());
+ }
+
+ auto Select() {
+ return Rowset<TableType, Iterator, typename TableType::TColumns>(*Database, KeyValues, Columns<typename TableType::TColumns>::GetColumnIds());
+ }
+
+ template <typename... ColumnTypes>
+ bool Precharge() {
+ return Iterator::Precharge(*Database, KeyValues, Columns<ColumnTypes...>::GetColumnIds());
+ }
+
+ bool Precharge() {
+ return Iterator::Precharge(*Database, KeyValues, Columns<typename TableType::TColumns>::GetColumnIds());
+ }
+
+ template <typename... ColumnTypes>
+ KeyOperations& Update(const typename ColumnTypes::Type&... value) {
+ return Update(TUpdate<ColumnTypes>(value)...);
+ }
+
+ template <typename... ColumnTypes>
+ KeyOperations& UpdateToNull() {
+ return Update(TNull<ColumnTypes>()...);
+ }
+
template <typename... UpdateTypes>
- KeyOperations& Update(const UpdateTypes&... updates) {
- std::array<TUpdateOp, sizeof...(UpdateTypes)> update_ops = {{updates...}};
+ KeyOperations& Update(const UpdateTypes&... updates) {
+ std::array<TUpdateOp, sizeof...(UpdateTypes)> update_ops = {{updates...}};
Database->Update(TableId, NTable::ERowOp::Upsert, TTupleToRawTypeValue<KeyValuesType, KeyColumnsType>(KeyValues), update_ops);
- return *this;
- }
-
- void Update() {
+ return *this;
+ }
+
+ void Update() {
Database->Update(TableId, NTable::ERowOp::Upsert, TTupleToRawTypeValue<KeyValuesType, KeyColumnsType>(KeyValues), { });
- }
-
- void Delete() {
+ }
+
+ void Delete() {
Database->Update(TableId, NTable::ERowOp::Erase, TTupleToRawTypeValue<KeyValuesType, KeyColumnsType>(KeyValues), { });
- }
- };
- };
-
- template <typename... Settings>
- struct SchemaSettings;
-
- template <typename Setting>
- struct SchemaSettings<Setting> {
- static void Materialize(TToughDb& database) {
- Setting::Materialize(database);
- }
- };
-
- template <typename Setting, typename... Settings>
- struct SchemaSettings<Setting, Settings...> : SchemaSettings<Settings...> {
- static void Materialize(TToughDb& database) {
- Setting::Materialize(database);
- SchemaSettings<Settings...>::Materialize(database);
- }
- };
-
- template <bool Allow = false>
- struct ExecutorLogBatching {
- static void Materialize(TToughDb& database) {
+ }
+ };
+ };
+
+ template <typename... Settings>
+ struct SchemaSettings;
+
+ template <typename Setting>
+ struct SchemaSettings<Setting> {
+ static void Materialize(TToughDb& database) {
+ Setting::Materialize(database);
+ }
+ };
+
+ template <typename Setting, typename... Settings>
+ struct SchemaSettings<Setting, Settings...> : SchemaSettings<Settings...> {
+ static void Materialize(TToughDb& database) {
+ Setting::Materialize(database);
+ SchemaSettings<Settings...>::Materialize(database);
+ }
+ };
+
+ template <bool Allow = false>
+ struct ExecutorLogBatching {
+ static void Materialize(TToughDb& database) {
database.Alter().SetExecutorAllowLogBatching(Allow);
- }
- };
-
- template <TDuration::TValue Period = 0>
- struct ExecutorLogFlushPeriod {
- static void Materialize(TToughDb& database) {
+ }
+ };
+
+ template <TDuration::TValue Period = 0>
+ struct ExecutorLogFlushPeriod {
+ static void Materialize(TToughDb& database) {
database.Alter().SetExecutorLogFlushPeriod(TDuration::MicroSeconds(Period));
- }
- };
-
+ }
+ };
+
template <ui32 LimitTxInFly = 0>
struct ExecutorLimitInFlyTx {
static void Materialize(TToughDb& database) {
@@ -1838,13 +1838,13 @@ struct Schema {
}
};
- template <ui64 CacheSize>
- struct ExecutorCacheSize {
- static void Materialize(TToughDb& database) {
+ template <ui64 CacheSize>
+ struct ExecutorCacheSize {
+ static void Materialize(TToughDb& database) {
database.Alter().SetExecutorCacheSize(CacheSize);
- }
- };
-
+ }
+ };
+
template <typename Type, typename... Types>
struct SchemaTables: SchemaTables<Types...> {
static bool Precharge(TToughDb& database) {
@@ -1854,24 +1854,24 @@ struct Schema {
static void Materialize(TToughDb& database, EMaterializationMode mode = EMaterializationMode::All) {
SchemaTables<Type>::Materialize(database, mode);
SchemaTables<Types...>::Materialize(database, mode);
- }
-
- static void Cleanup(TToughDb& database) {
- SchemaTables<Type>::Cleanup(database);
- SchemaTables<Types...>::Cleanup(database);
- }
-
- static bool HaveTable(ui32 tableId) {
- return SchemaTables<Type>::HaveTable(tableId) || SchemaTables<Types...>::HaveTable(tableId);
- }
- };
-
+ }
+
+ static void Cleanup(TToughDb& database) {
+ SchemaTables<Type>::Cleanup(database);
+ SchemaTables<Types...>::Cleanup(database);
+ }
+
+ static bool HaveTable(ui32 tableId) {
+ return SchemaTables<Type>::HaveTable(tableId) || SchemaTables<Types...>::HaveTable(tableId);
+ }
+ };
+
template <typename Type>
struct SchemaTables<Type> {
static TString GetTableName(const TString& typeName) {
- return typeName.substr(typeName.rfind(':') + 1);
- }
-
+ return typeName.substr(typeName.rfind(':') + 1);
+ }
+
static bool Precharge(TToughDb& database) {
return typename Type::TKey::template Selector<Type>(database).Precharge();
}
@@ -1893,72 +1893,72 @@ struct Schema {
}
database.Alter().AddTable(GetTableName(TypeName<Type>()), Type::TableId);
- Type::TColumns::Materialize(database);
- Type::TKey::Materialize(database);
- }
-
- static void Cleanup(TToughDb& database) {
+ Type::TColumns::Materialize(database);
+ Type::TKey::Materialize(database);
+ }
+
+ static void Cleanup(TToughDb& database) {
auto* table = database.GetScheme().GetTableInfo(Type::TableId);
if (table != nullptr) {
for (const auto& column : table->Columns) {
if (!Type::TColumns::HaveColumn(column.first)) {
database.Alter().DropColumn(Type::TableId, column.first);
- }
- }
- }
- }
-
- static bool HaveTable(ui32 tableId) {
- return Type::TableId == tableId;
- }
- };
-
- using TSettings = SchemaSettings<ExecutorLogBatching<false>>;
-};
-
-template <>
+ }
+ }
+ }
+ }
+
+ static bool HaveTable(ui32 tableId) {
+ return Type::TableId == tableId;
+ }
+ };
+
+ using TSettings = SchemaSettings<ExecutorLogBatching<false>>;
+};
+
+template <>
inline bool Schema::Precharger<Schema::AutoPrecharge>::Precharge(
TToughDb& database, ui32 table,
NTable::TRawVals minKey, NTable::TRawVals maxKey,
NTable::TTagsRef columns, NTable::EDirection direction)
{
return database.Precharge(table, minKey, maxKey, columns, 0, -1, -1, direction);
-}
-
-template <>
+}
+
+template <>
inline bool Schema::Precharger<Schema::NoAutoPrecharge>::Precharge(
TToughDb&, ui32,
NTable::TRawVals, NTable::TRawVals,
NTable::TTagsRef, NTable::EDirection)
{
- return true;
-}
-
-class TNiceDb {
-public:
- TNiceDb(TToughDb& database)
- : Database(database)
- {}
-
- template <typename TableType> typename TableType::TKey::template Selector<TableType> Table() { return Database; }
-
+ return true;
+}
+
+class TNiceDb {
+public:
+ TNiceDb(TToughDb& database)
+ : Database(database)
+ {}
+
+ template <typename TableType> typename TableType::TKey::template Selector<TableType> Table() { return Database; }
+
template <typename TableType>
bool HaveTable() {
return Database.GetScheme().GetTableInfo(TableType::TableId);
}
- template <typename SchemaType>
+ template <typename SchemaType>
bool Precharge() {
return SchemaType::TTables::Precharge(Database);
}
template <typename SchemaType>
- void Materialize() {
- SchemaType::TSettings::Materialize(Database);
+ void Materialize() {
+ SchemaType::TSettings::Materialize(Database);
SchemaType::TTables::Materialize(Database, EMaterializationMode::All);
- }
-
- template <typename SchemaType>
+ }
+
+ template <typename SchemaType>
void MaterializeExisting() {
SchemaType::TTables::Materialize(Database, EMaterializationMode::Existing);
}
@@ -1969,24 +1969,24 @@ public:
}
template <typename SchemaType>
- void Cleanup() {
- SchemaType::TTables::Cleanup(Database);
+ void Cleanup() {
+ SchemaType::TTables::Cleanup(Database);
for (const auto& table : Database.GetScheme().Tables) {
if (!SchemaType::TTables::HaveTable(table.first)) {
Database.Alter().DropTable(table.first);
- }
- }
- }
-
+ }
+ }
+ }
+
void NoMoreReadsForTx() {
return Database.NoMoreReadsForTx();
}
-protected:
- TToughDb& Database;
-};
-
+protected:
+ TToughDb& Database;
+};
+
namespace NHelpers {
// Fills NTable::TScheme::TTableSchema from static NIceDb::Schema
@@ -2061,5 +2061,5 @@ struct TStaticSchemaFiller {
} // namespace NHelpers
-}
-}
+}
+}
diff --git a/ydb/core/tablet_flat/flat_cxx_database_ut.cpp b/ydb/core/tablet_flat/flat_cxx_database_ut.cpp
index dbf0e304b3e..0423d82e624 100644
--- a/ydb/core/tablet_flat/flat_cxx_database_ut.cpp
+++ b/ydb/core/tablet_flat/flat_cxx_database_ut.cpp
@@ -1,235 +1,235 @@
-
+
#include <library/cpp/testing/unittest/registar.h>
#include <ydb/core/tablet_flat/test/libs/table/test_dummy.h>
#include <ydb/library/mkql_proto/protos/minikql.pb.h>
-#include "flat_cxx_database.h"
+#include "flat_cxx_database.h"
#include "flat_dbase_scheme.h"
#include "flat_dbase_apply.h"
-
-namespace NKikimr {
-
+
+namespace NKikimr {
+
namespace NTable {
-
+
Y_UNIT_TEST_SUITE(TFlatCxxDatabaseTest) {
using TDummyEnv = NTable::TDummyEnv;
-
- enum ESomeEnum : ui8 {
- SomeValue0,
- SomeValue1,
- SomeValue2,
- };
-
- struct Schema : NIceDb::Schema {
- struct TestTable : Table<1> {
+
+ enum ESomeEnum : ui8 {
+ SomeValue0,
+ SomeValue1,
+ SomeValue2,
+ };
+
+ struct Schema : NIceDb::Schema {
+ struct TestTable : Table<1> {
struct ID : Column<1, NScheme::NTypeIds::Uint64> {};
struct Value : Column<2, NScheme::NTypeIds::Uint64> {};
struct Name : Column<3, NScheme::NTypeIds::Utf8> {};
struct BoolValue : Column<4, NScheme::NTypeIds::Bool> {};
- struct EmptyValue : Column<5, NScheme::NTypeIds::Uint64> { static constexpr ui64 Default = 13; };
- struct ProtoValue : Column<6, NScheme::NTypeIds::String> { using Type = NKikimrMiniKQL::TValue; };
- struct EnumValue : Column<7, NScheme::NTypeIds::Uint64> { using Type = ESomeEnum; };
+ struct EmptyValue : Column<5, NScheme::NTypeIds::Uint64> { static constexpr ui64 Default = 13; };
+ struct ProtoValue : Column<6, NScheme::NTypeIds::String> { using Type = NKikimrMiniKQL::TValue; };
+ struct EnumValue : Column<7, NScheme::NTypeIds::Uint64> { using Type = ESomeEnum; };
struct InstantValue : Column<8, NScheme::NTypeIds::Uint64> { using Type = TInstant; };
-
- using TKey = TableKey<ID>;
+
+ using TKey = TableKey<ID>;
using TColumns = TableColumns<ID, Value, Name, BoolValue, EmptyValue, ProtoValue, EnumValue, InstantValue>;
- };
-
- struct TestTable2 : Table<2> {
+ };
+
+ struct TestTable2 : Table<2> {
struct ID1 : Column<1, NScheme::NTypeIds::Uint64> {};
struct ID2 : Column<2, NScheme::NTypeIds::Uint64> {};
- struct Value : Column<3, NScheme::NTypeIds::Uint64> {};
-
- using TKey = TableKey<ID1, ID2>;
- using TColumns = TableColumns<ID1, ID2, Value>;
-
- using Precharge = NoAutoPrecharge;
- };
-
- struct TestTable3 : Table<3> {
+ struct Value : Column<3, NScheme::NTypeIds::Uint64> {};
+
+ using TKey = TableKey<ID1, ID2>;
+ using TColumns = TableColumns<ID1, ID2, Value>;
+
+ using Precharge = NoAutoPrecharge;
+ };
+
+ struct TestTable3 : Table<3> {
struct ID1 : Column<1, NScheme::NTypeIds::Utf8> {};
- struct ID2 : Column<2, NScheme::NTypeIds::String> {};
+ struct ID2 : Column<2, NScheme::NTypeIds::String> {};
struct Value : Column<3, NScheme::NTypeIds::Uint64> {};
-
- using TKey = TableKey<ID1, ID2>;
- using TColumns = TableColumns<ID1, ID2, Value>;
- };
-
- struct TestTable4 : Table<4> {
- struct ID : Column<1, NScheme::NTypeIds::Uint64> {};
- struct Value : Column<2, NScheme::NTypeIds::String> { using Type = TStringBuf; };
- struct ProtoValue : Column<3, NScheme::NTypeIds::String> { using Type = NKikimrMiniKQL::TValue; };
-
- using TKey = TableKey<ID>;
- using TColumns = TableColumns<ID, Value, ProtoValue>;
- };
-
- using TTables = SchemaTables<TestTable, TestTable2, TestTable3, TestTable4>;
- };
-
+
+ using TKey = TableKey<ID1, ID2>;
+ using TColumns = TableColumns<ID1, ID2, Value>;
+ };
+
+ struct TestTable4 : Table<4> {
+ struct ID : Column<1, NScheme::NTypeIds::Uint64> {};
+ struct Value : Column<2, NScheme::NTypeIds::String> { using Type = TStringBuf; };
+ struct ProtoValue : Column<3, NScheme::NTypeIds::String> { using Type = NKikimrMiniKQL::TValue; };
+
+ using TKey = TableKey<ID>;
+ using TColumns = TableColumns<ID, Value, ProtoValue>;
+ };
+
+ using TTables = SchemaTables<TestTable, TestTable2, TestTable3, TestTable4>;
+ };
+
Y_UNIT_TEST(BasicSchemaTest) {
TDatabase DB;
- NIceDb::TNiceDb db(DB);
+ NIceDb::TNiceDb db(DB);
ui64 stamp = 0;
-
+
TInstant timestamp = TInstant::Now();
- {
+ {
TDummyEnv env;
DB.Begin(++stamp, env);
- db.Materialize<Schema>();
+ db.Materialize<Schema>();
DB.Commit(stamp, true);
- }
-
- {
+ }
+
+ {
TDummyEnv env;
DB.Begin(++stamp, env);
- for (ui64 i = 0; i < 1000; ++i) {
- NKikimrMiniKQL::TValue protoValue;
- protoValue.SetUint64(i);
- protoValue.SetText(ToString(i));
- protoValue.SetBool(i % 2 == 0);
-
- db.Table<Schema::TestTable>().Key(i).Update(NIceDb::TNull<Schema::TestTable::Value>());
-
- db.Table<Schema::TestTable>().Key(i).Update<Schema::TestTable::EnumValue>(ESomeEnum::SomeValue0);
-
- // old syntax:
- db.Table<Schema::TestTable>().Key(i).Update(NIceDb::TUpdate<Schema::TestTable::Value>(i),
- NIceDb::TUpdate<Schema::TestTable::Name>(ToString(i)),
- NIceDb::TUpdate<Schema::TestTable::BoolValue>(i % 2 == 0),
- NIceDb::TUpdate<Schema::TestTable::ProtoValue>(protoValue),
+ for (ui64 i = 0; i < 1000; ++i) {
+ NKikimrMiniKQL::TValue protoValue;
+ protoValue.SetUint64(i);
+ protoValue.SetText(ToString(i));
+ protoValue.SetBool(i % 2 == 0);
+
+ db.Table<Schema::TestTable>().Key(i).Update(NIceDb::TNull<Schema::TestTable::Value>());
+
+ db.Table<Schema::TestTable>().Key(i).Update<Schema::TestTable::EnumValue>(ESomeEnum::SomeValue0);
+
+ // old syntax:
+ db.Table<Schema::TestTable>().Key(i).Update(NIceDb::TUpdate<Schema::TestTable::Value>(i),
+ NIceDb::TUpdate<Schema::TestTable::Name>(ToString(i)),
+ NIceDb::TUpdate<Schema::TestTable::BoolValue>(i % 2 == 0),
+ NIceDb::TUpdate<Schema::TestTable::ProtoValue>(protoValue),
NIceDb::TUpdate<Schema::TestTable::EnumValue>(ESomeEnum::SomeValue1),
NIceDb::TUpdate<Schema::TestTable::InstantValue>(timestamp));
-
- // modern syntax:
- db.Table<Schema::TestTable>().Key(i).Update<
- Schema::TestTable::Value,
- Schema::TestTable::Name,
- Schema::TestTable::BoolValue,
- Schema::TestTable::ProtoValue,
+
+ // modern syntax:
+ db.Table<Schema::TestTable>().Key(i).Update<
+ Schema::TestTable::Value,
+ Schema::TestTable::Name,
+ Schema::TestTable::BoolValue,
+ Schema::TestTable::ProtoValue,
Schema::TestTable::EnumValue,
Schema::TestTable::InstantValue>(i, ToString(i), i % 2 == 0, protoValue, ESomeEnum::SomeValue1,
timestamp);
-
- // also modern syntax:
- db.Table<Schema::TestTable>().Key(i)
- .Update<Schema::TestTable::Value>(i)
- .Update<Schema::TestTable::Name>(ToString(i))
- .Update<Schema::TestTable::BoolValue>(i % 2 == 0)
- .Update<Schema::TestTable::ProtoValue>(protoValue)
+
+ // also modern syntax:
+ db.Table<Schema::TestTable>().Key(i)
+ .Update<Schema::TestTable::Value>(i)
+ .Update<Schema::TestTable::Name>(ToString(i))
+ .Update<Schema::TestTable::BoolValue>(i % 2 == 0)
+ .Update<Schema::TestTable::ProtoValue>(protoValue)
.Update<Schema::TestTable::EnumValue>(ESomeEnum::SomeValue1)
.Update<Schema::TestTable::InstantValue>(timestamp);
- }
+ }
DB.Commit(stamp, true);
- }
-
- {
+ }
+
+ {
TDummyEnv env;
DB.Begin(++stamp, env);
- for (ui64 i = 0; i < 100; ++i) {
- for (ui64 j = 0; j < 10; ++j) {
- db.Table<Schema::TestTable2>().Key(i, j).Update(NIceDb::TUpdate<Schema::TestTable2::Value>(i * 10 + j));
- }
- }
+ for (ui64 i = 0; i < 100; ++i) {
+ for (ui64 j = 0; j < 10; ++j) {
+ db.Table<Schema::TestTable2>().Key(i, j).Update(NIceDb::TUpdate<Schema::TestTable2::Value>(i * 10 + j));
+ }
+ }
DB.Commit(stamp, true);
- }
-
- // NoCopy
- {
+ }
+
+ // NoCopy
+ {
TDummyEnv env;
DB.Begin(++stamp, env);
- NKikimrMiniKQL::TValue protoValue;
- protoValue.SetText("test");
- db.Table<Schema::TestTable4>().Key(1).Update<Schema::TestTable4::Value, Schema::TestTable4::ProtoValue>("test", protoValue);
+ NKikimrMiniKQL::TValue protoValue;
+ protoValue.SetText("test");
+ db.Table<Schema::TestTable4>().Key(1).Update<Schema::TestTable4::Value, Schema::TestTable4::ProtoValue>("test", protoValue);
DB.Commit(stamp, true);
- }
- {
+ }
+ {
TDummyEnv env;
DB.Begin(++stamp, env);
- {
- auto row = db.Table<Schema::TestTable4>().Key(1).Select<Schema::TestTable4::Value>();
- }
- {
- auto row = db.Table<Schema::TestTable4>().Key(1).Select<Schema::TestTable4::ProtoValue>();
- }
- auto row = db.Table<Schema::TestTable4>().Key(1).Select<Schema::TestTable4::Value, Schema::TestTable4::ProtoValue>();
- UNIT_ASSERT(row.IsReady());
- UNIT_ASSERT(row.IsValid());
- UNIT_ASSERT(!row.EndOfSet());
- auto value = row.GetValue<Schema::TestTable4::Value>();
- UNIT_ASSERT(typeid(value) == typeid(TStringBuf));
- UNIT_ASSERT(value == "test");
- auto protoValue = row.GetValue<Schema::TestTable4::ProtoValue>();
- UNIT_ASSERT(typeid(protoValue) == typeid(NKikimrMiniKQL::TValue));
- UNIT_ASSERT(protoValue.GetText() == "test");
+ {
+ auto row = db.Table<Schema::TestTable4>().Key(1).Select<Schema::TestTable4::Value>();
+ }
+ {
+ auto row = db.Table<Schema::TestTable4>().Key(1).Select<Schema::TestTable4::ProtoValue>();
+ }
+ auto row = db.Table<Schema::TestTable4>().Key(1).Select<Schema::TestTable4::Value, Schema::TestTable4::ProtoValue>();
+ UNIT_ASSERT(row.IsReady());
+ UNIT_ASSERT(row.IsValid());
+ UNIT_ASSERT(!row.EndOfSet());
+ auto value = row.GetValue<Schema::TestTable4::Value>();
+ UNIT_ASSERT(typeid(value) == typeid(TStringBuf));
+ UNIT_ASSERT(value == "test");
+ auto protoValue = row.GetValue<Schema::TestTable4::ProtoValue>();
+ UNIT_ASSERT(typeid(protoValue) == typeid(NKikimrMiniKQL::TValue));
+ UNIT_ASSERT(protoValue.GetText() == "test");
DB.Commit(stamp, true);
- }
-
+ }
+
// SelectRow
- {
+ {
TDummyEnv env;
DB.Begin(++stamp, env);
for (ui64 i = 0; i < 1000; ++i) {
- auto row = db.Table<Schema::TestTable>().Key(i).Select<
- Schema::TestTable::Value,
- Schema::TestTable::Name,
- Schema::TestTable::BoolValue,
- Schema::TestTable::EmptyValue,
+ auto row = db.Table<Schema::TestTable>().Key(i).Select<
+ Schema::TestTable::Value,
+ Schema::TestTable::Name,
+ Schema::TestTable::BoolValue,
+ Schema::TestTable::EmptyValue,
Schema::TestTable::EnumValue,
Schema::TestTable::InstantValue>();
- // move semantics test
- decltype(row) new_row = std::move(row);
- row = std::move(new_row);
- ////////////////////////
- UNIT_ASSERT(row.IsReady());
- UNIT_ASSERT(row.IsValid());
- ui64 value = row.GetValue<Schema::TestTable::Value>();
+ // move semantics test
+ decltype(row) new_row = std::move(row);
+ row = std::move(new_row);
+ ////////////////////////
+ UNIT_ASSERT(row.IsReady());
+ UNIT_ASSERT(row.IsValid());
+ ui64 value = row.GetValue<Schema::TestTable::Value>();
TString name = row.GetValue<Schema::TestTable::Name>();
- bool boolValue = row.GetValue<Schema::TestTable::BoolValue>();
- ESomeEnum enumValue = row.GetValue<Schema::TestTable::EnumValue>();
+ bool boolValue = row.GetValue<Schema::TestTable::BoolValue>();
+ ESomeEnum enumValue = row.GetValue<Schema::TestTable::EnumValue>();
TInstant instantValue = row.GetValue<Schema::TestTable::InstantValue>();
UNIT_ASSERT_EQUAL(value, i);
UNIT_ASSERT_EQUAL(ToString(value), name);
UNIT_ASSERT_EQUAL(boolValue, (i % 2 == 0));
- UNIT_ASSERT_EQUAL(enumValue, ESomeEnum::SomeValue1);
+ UNIT_ASSERT_EQUAL(enumValue, ESomeEnum::SomeValue1);
UNIT_ASSERT_EQUAL(instantValue, timestamp);
- UNIT_ASSERT_EQUAL(row.GetValue<Schema::TestTable::EmptyValue>(), 13);
- UNIT_ASSERT_EQUAL(row.GetValueOrDefault<Schema::TestTable::EmptyValue>(), 13);
- UNIT_ASSERT_EQUAL(row.GetValueOrDefault<Schema::TestTable::EmptyValue>(i), i);
+ UNIT_ASSERT_EQUAL(row.GetValue<Schema::TestTable::EmptyValue>(), 13);
+ UNIT_ASSERT_EQUAL(row.GetValueOrDefault<Schema::TestTable::EmptyValue>(), 13);
+ UNIT_ASSERT_EQUAL(row.GetValueOrDefault<Schema::TestTable::EmptyValue>(i), i);
}
DB.Commit(stamp, true);
}
- // All
+ // All
{
TDummyEnv env;
DB.Begin(++stamp, env);
- UNIT_ASSERT(db.Table<Schema::TestTable>().Precharge());
- auto table = db.Table<Schema::TestTable>();
- // move semantics test
- decltype(table) new_table = std::move(table);
- table = std::move(new_table);
- ////////////////////////
- auto rowset = table.Select<Schema::TestTable::Value, Schema::TestTable::Name, Schema::TestTable::BoolValue>();
- UNIT_ASSERT(rowset.IsReady());
- // move semantics test
- decltype(rowset) new_rowset = std::move(rowset);
- rowset = std::move(new_rowset);
- ////////////////////////
- for (ui64 i = 0; i < 1000; ++i) {
- UNIT_ASSERT(!rowset.EndOfSet());
- ui64 value = rowset.GetValue<Schema::TestTable::Value>();
+ UNIT_ASSERT(db.Table<Schema::TestTable>().Precharge());
+ auto table = db.Table<Schema::TestTable>();
+ // move semantics test
+ decltype(table) new_table = std::move(table);
+ table = std::move(new_table);
+ ////////////////////////
+ auto rowset = table.Select<Schema::TestTable::Value, Schema::TestTable::Name, Schema::TestTable::BoolValue>();
+ UNIT_ASSERT(rowset.IsReady());
+ // move semantics test
+ decltype(rowset) new_rowset = std::move(rowset);
+ rowset = std::move(new_rowset);
+ ////////////////////////
+ for (ui64 i = 0; i < 1000; ++i) {
+ UNIT_ASSERT(!rowset.EndOfSet());
+ ui64 value = rowset.GetValue<Schema::TestTable::Value>();
TString name = rowset.GetValue<Schema::TestTable::Name>();
- bool boolValue = rowset.GetValue<Schema::TestTable::BoolValue>();
- UNIT_ASSERT_EQUAL(value, i);
- UNIT_ASSERT_EQUAL(ToString(value), name);
- UNIT_ASSERT_EQUAL(boolValue, (i % 2 == 0));
- UNIT_ASSERT(rowset.Next());
- }
- UNIT_ASSERT(rowset.EndOfSet());
+ bool boolValue = rowset.GetValue<Schema::TestTable::BoolValue>();
+ UNIT_ASSERT_EQUAL(value, i);
+ UNIT_ASSERT_EQUAL(ToString(value), name);
+ UNIT_ASSERT_EQUAL(boolValue, (i % 2 == 0));
+ UNIT_ASSERT(rowset.Next());
+ }
+ UNIT_ASSERT(rowset.EndOfSet());
DB.Commit(stamp, true);
- }
-
+ }
+
// All in reverse
{
TDummyEnv env;
@@ -261,26 +261,26 @@ Y_UNIT_TEST_SUITE(TFlatCxxDatabaseTest) {
DB.Commit(stamp, true);
}
- // Prefix
- {
+ // Prefix
+ {
TDummyEnv env;
DB.Begin(++stamp, env);
- UNIT_ASSERT(db.Table<Schema::TestTable2>().Prefix(50).Precharge<Schema::TestTable2::Value>());
- auto rowset = db.Table<Schema::TestTable2>().Prefix(50).Select<Schema::TestTable2::Value>();
- UNIT_ASSERT(rowset.IsReady());
- // move semantics test
- decltype(rowset) new_rowset = std::move(rowset);
- rowset = std::move(new_rowset);
- ////////////////////////
- for (ui64 i = 0; i < 10; ++i) {
- UNIT_ASSERT(!rowset.EndOfSet());
- UNIT_ASSERT_EQUAL(rowset.GetValue<Schema::TestTable2::Value>(), 50 * 10 + i);
- UNIT_ASSERT(rowset.Next());
- }
- UNIT_ASSERT(rowset.EndOfSet());
+ UNIT_ASSERT(db.Table<Schema::TestTable2>().Prefix(50).Precharge<Schema::TestTable2::Value>());
+ auto rowset = db.Table<Schema::TestTable2>().Prefix(50).Select<Schema::TestTable2::Value>();
+ UNIT_ASSERT(rowset.IsReady());
+ // move semantics test
+ decltype(rowset) new_rowset = std::move(rowset);
+ rowset = std::move(new_rowset);
+ ////////////////////////
+ for (ui64 i = 0; i < 10; ++i) {
+ UNIT_ASSERT(!rowset.EndOfSet());
+ UNIT_ASSERT_EQUAL(rowset.GetValue<Schema::TestTable2::Value>(), 50 * 10 + i);
+ UNIT_ASSERT(rowset.Next());
+ }
+ UNIT_ASSERT(rowset.EndOfSet());
DB.Commit(stamp, true);
- }
-
+ }
+
// Prefix in reverse
{
TDummyEnv env;
@@ -303,29 +303,29 @@ Y_UNIT_TEST_SUITE(TFlatCxxDatabaseTest) {
}
// GreaterOrEqual
- {
+ {
TDummyEnv env;
DB.Begin(++stamp, env);
- auto rowset = db.Table<Schema::TestTable>().GreaterOrEqual(500).Select();
- UNIT_ASSERT(rowset.IsReady());
- // move semantics test
- decltype(rowset) new_rowset = std::move(rowset);
- rowset = std::move(new_rowset);
- ////////////////////////
- for (ui64 i = 500; i < 1000; ++i) {
- UNIT_ASSERT(!rowset.EndOfSet());
- ui64 value = rowset.GetValue<Schema::TestTable::Value>();
+ auto rowset = db.Table<Schema::TestTable>().GreaterOrEqual(500).Select();
+ UNIT_ASSERT(rowset.IsReady());
+ // move semantics test
+ decltype(rowset) new_rowset = std::move(rowset);
+ rowset = std::move(new_rowset);
+ ////////////////////////
+ for (ui64 i = 500; i < 1000; ++i) {
+ UNIT_ASSERT(!rowset.EndOfSet());
+ ui64 value = rowset.GetValue<Schema::TestTable::Value>();
TString name = rowset.GetValue<Schema::TestTable::Name>();
- bool boolValue = rowset.GetValue<Schema::TestTable::BoolValue>();
- UNIT_ASSERT_EQUAL(value, i);
- UNIT_ASSERT_EQUAL(ToString(value), name);
- UNIT_ASSERT_EQUAL(boolValue, (i % 2 == 0));
- UNIT_ASSERT(rowset.Next());
- }
- UNIT_ASSERT(rowset.EndOfSet());
+ bool boolValue = rowset.GetValue<Schema::TestTable::BoolValue>();
+ UNIT_ASSERT_EQUAL(value, i);
+ UNIT_ASSERT_EQUAL(ToString(value), name);
+ UNIT_ASSERT_EQUAL(boolValue, (i % 2 == 0));
+ UNIT_ASSERT(rowset.Next());
+ }
+ UNIT_ASSERT(rowset.EndOfSet());
DB.Commit(stamp, true);
- }
-
+ }
+
// GreaterOrEqual in reverse
{
TDummyEnv env;
@@ -350,30 +350,30 @@ Y_UNIT_TEST_SUITE(TFlatCxxDatabaseTest) {
DB.Commit(stamp, true);
}
- // LessOrEqual
- {
+ // LessOrEqual
+ {
TDummyEnv env;
DB.Begin(++stamp, env);
- auto rowset = db.Table<Schema::TestTable>().LessOrEqual(500).Select();
- UNIT_ASSERT(rowset.IsReady());
- // move semantics test
- decltype(rowset) new_rowset = std::move(rowset);
- rowset = std::move(new_rowset);
- ////////////////////////
- for (ui64 i = 0; i <= 500; ++i) {
- UNIT_ASSERT(!rowset.EndOfSet());
- ui64 value = rowset.GetValue<Schema::TestTable::Value>();
- TString name = rowset.GetValue<Schema::TestTable::Name>();
- bool boolValue = rowset.GetValue<Schema::TestTable::BoolValue>();
- UNIT_ASSERT_EQUAL(value, i);
- UNIT_ASSERT_EQUAL(ToString(value), name);
- UNIT_ASSERT_EQUAL(boolValue, (i % 2 == 0));
- UNIT_ASSERT(rowset.Next());
- }
- UNIT_ASSERT(rowset.EndOfSet());
+ auto rowset = db.Table<Schema::TestTable>().LessOrEqual(500).Select();
+ UNIT_ASSERT(rowset.IsReady());
+ // move semantics test
+ decltype(rowset) new_rowset = std::move(rowset);
+ rowset = std::move(new_rowset);
+ ////////////////////////
+ for (ui64 i = 0; i <= 500; ++i) {
+ UNIT_ASSERT(!rowset.EndOfSet());
+ ui64 value = rowset.GetValue<Schema::TestTable::Value>();
+ TString name = rowset.GetValue<Schema::TestTable::Name>();
+ bool boolValue = rowset.GetValue<Schema::TestTable::BoolValue>();
+ UNIT_ASSERT_EQUAL(value, i);
+ UNIT_ASSERT_EQUAL(ToString(value), name);
+ UNIT_ASSERT_EQUAL(boolValue, (i % 2 == 0));
+ UNIT_ASSERT(rowset.Next());
+ }
+ UNIT_ASSERT(rowset.EndOfSet());
DB.Commit(stamp, true);
- }
-
+ }
+
// LessOrEqual in reverse
{
TDummyEnv env;
@@ -398,37 +398,37 @@ Y_UNIT_TEST_SUITE(TFlatCxxDatabaseTest) {
DB.Commit(stamp, true);
}
- // GreaterOrEqual + LessOrEqual
- {
+ // GreaterOrEqual + LessOrEqual
+ {
TDummyEnv env;
DB.Begin(++stamp, env);
- auto operation = db.Table<Schema::TestTable>().GreaterOrEqual(500).LessOrEqual(501);
- // move semantics test
- decltype(operation) new_operation = std::move(operation);
- operation = std::move(new_operation);
- ////////////////////////
- auto rowset = operation.Select();
- UNIT_ASSERT(rowset.IsReady());
- // move semantics test
- decltype(rowset) new_rowset = std::move(rowset);
- rowset = std::move(new_rowset);
- ////////////////////////
- for (ui64 i = 500; i <= 501; ++i) {
- UNIT_ASSERT(!rowset.EndOfSet());
- ui64 value = rowset.GetValue<Schema::TestTable::Value>();
- TString name = rowset.GetValue<Schema::TestTable::Name>();
- bool boolValue = rowset.GetValue<Schema::TestTable::BoolValue>();
- UNIT_ASSERT_EQUAL(value, i);
- UNIT_ASSERT_EQUAL(ToString(value), name);
- UNIT_ASSERT_EQUAL(boolValue, (i % 2 == 0));
- UNIT_ASSERT(rowset.Next());
- }
- UNIT_ASSERT(rowset.EndOfSet());
+ auto operation = db.Table<Schema::TestTable>().GreaterOrEqual(500).LessOrEqual(501);
+ // move semantics test
+ decltype(operation) new_operation = std::move(operation);
+ operation = std::move(new_operation);
+ ////////////////////////
+ auto rowset = operation.Select();
+ UNIT_ASSERT(rowset.IsReady());
+ // move semantics test
+ decltype(rowset) new_rowset = std::move(rowset);
+ rowset = std::move(new_rowset);
+ ////////////////////////
+ for (ui64 i = 500; i <= 501; ++i) {
+ UNIT_ASSERT(!rowset.EndOfSet());
+ ui64 value = rowset.GetValue<Schema::TestTable::Value>();
+ TString name = rowset.GetValue<Schema::TestTable::Name>();
+ bool boolValue = rowset.GetValue<Schema::TestTable::BoolValue>();
+ UNIT_ASSERT_EQUAL(value, i);
+ UNIT_ASSERT_EQUAL(ToString(value), name);
+ UNIT_ASSERT_EQUAL(boolValue, (i % 2 == 0));
+ UNIT_ASSERT(rowset.Next());
+ }
+ UNIT_ASSERT(rowset.EndOfSet());
DB.Commit(stamp, true);
- }
-
+ }
+
// GreaterOrEqual + LessOrEqual in reverse
- {
+ {
TDummyEnv env;
DB.Begin(++stamp, env);
auto operation = db.Table<Schema::TestTable>().Reverse().GreaterOrEqual(500).LessOrEqual(501);
@@ -517,94 +517,94 @@ Y_UNIT_TEST_SUITE(TFlatCxxDatabaseTest) {
{
TDummyEnv env;
DB.Begin(++stamp, env);
- for (ui64 i = 0; i < 1000; ++i) {
- db.Table<Schema::TestTable>().Key(i).Delete();
- }
+ for (ui64 i = 0; i < 1000; ++i) {
+ db.Table<Schema::TestTable>().Key(i).Delete();
+ }
DB.Commit(stamp, true);
- }
-
- {
+ }
+
+ {
TDummyEnv env;
DB.Begin(++stamp, env);
- auto rowset = db.Table<Schema::TestTable>().Select<Schema::TestTable::Value, Schema::TestTable::Name>();
- UNIT_ASSERT(rowset.IsReady());
- UNIT_ASSERT(rowset.EndOfSet());
+ auto rowset = db.Table<Schema::TestTable>().Select<Schema::TestTable::Value, Schema::TestTable::Name>();
+ UNIT_ASSERT(rowset.IsReady());
+ UNIT_ASSERT(rowset.EndOfSet());
DB.Commit(stamp, true);
- }
-
- {
+ }
+
+ {
TDummyEnv env;
DB.Begin(++stamp, env);
- for (ui64 i = 0; i < 1000; ++i) {
- db.Table<Schema::TestTable2>().Key(i / 100, i % 100).Update();
- }
+ for (ui64 i = 0; i < 1000; ++i) {
+ db.Table<Schema::TestTable2>().Key(i / 100, i % 100).Update();
+ }
DB.Commit(stamp, true);
- }
-
- {
+ }
+
+ {
TDummyEnv env;
DB.Begin(++stamp, env);
- auto rowset = db.Table<Schema::TestTable2>().GreaterOrEqual(5,0).Select();
- UNIT_ASSERT(rowset.IsReady());
- for (ui64 i = 500; i < 1000; ++i) {
- UNIT_ASSERT(!rowset.EndOfSet());
- UNIT_ASSERT_EQUAL(rowset.GetKey(), std::make_tuple(i / 100, i % 100));
- UNIT_ASSERT(rowset.Next());
- }
+ auto rowset = db.Table<Schema::TestTable2>().GreaterOrEqual(5,0).Select();
+ UNIT_ASSERT(rowset.IsReady());
+ for (ui64 i = 500; i < 1000; ++i) {
+ UNIT_ASSERT(!rowset.EndOfSet());
+ UNIT_ASSERT_EQUAL(rowset.GetKey(), std::make_tuple(i / 100, i % 100));
+ UNIT_ASSERT(rowset.Next());
+ }
DB.Commit(stamp, true);
- }
-
- {
+ }
+
+ {
TDummyEnv env;
DB.Begin(++stamp, env);
-
- for (ui64 i = 0; i < 1000; ++i) {
- db.Table<Schema::TestTable3>().Key(IntToString<16>(i / 4), IntToString<16>(i % 4)).Update(NIceDb::TUpdate<Schema::TestTable3::Value>(i));
- }
-
+
+ for (ui64 i = 0; i < 1000; ++i) {
+ db.Table<Schema::TestTable3>().Key(IntToString<16>(i / 4), IntToString<16>(i % 4)).Update(NIceDb::TUpdate<Schema::TestTable3::Value>(i));
+ }
+
DB.Commit(stamp, true);
- }
-
- {
+ }
+
+ {
TDummyEnv env;
DB.Begin(++stamp, env);
- for (ui64 i = 250; i > 0; --i) {
- auto rowset = db.Table<Schema::TestTable3>().Range(IntToString<16>(i - 1)).Select();
- UNIT_ASSERT(rowset.IsReady());
- for (ui64 j = 0; j < 4; ++j) {
- UNIT_ASSERT(rowset.IsValid());
+ for (ui64 i = 250; i > 0; --i) {
+ auto rowset = db.Table<Schema::TestTable3>().Range(IntToString<16>(i - 1)).Select();
+ UNIT_ASSERT(rowset.IsReady());
+ for (ui64 j = 0; j < 4; ++j) {
+ UNIT_ASSERT(rowset.IsValid());
TString should = IntToString<16>(j);
TString have = rowset.GetValue<Schema::TestTable3::ID2>();
- UNIT_ASSERT_EQUAL(should, have);
- UNIT_ASSERT_EQUAL((i - 1) * 4 + j, rowset.GetValue<Schema::TestTable3::Value>());
- UNIT_ASSERT(rowset.Next());
- }
- UNIT_ASSERT(rowset.EndOfSet());
- }
+ UNIT_ASSERT_EQUAL(should, have);
+ UNIT_ASSERT_EQUAL((i - 1) * 4 + j, rowset.GetValue<Schema::TestTable3::Value>());
+ UNIT_ASSERT(rowset.Next());
+ }
+ UNIT_ASSERT(rowset.EndOfSet());
+ }
DB.Commit(stamp, true);
- }
- }
-
+ }
+ }
+
Y_UNIT_TEST(RenameColumnSchemaTest) {
- TScheme scheme;
+ TScheme scheme;
TSchemeModifier applier(scheme);
TAlter delta;
-
- delta.AddTable("test", 1);
+
+ delta.AddTable("test", 1);
delta.AddColumn(1, "test", 1, 1, { });
applier.Apply(*delta.Flush());
-
- delta.AddTable("testtest", 1);
+
+ delta.AddTable("testtest", 1);
delta.AddColumn(1, "testtest", 1, 1, { });
applier.Apply(*delta.Flush());
-
- UNIT_ASSERT(scheme.Tables.find(1)->second.Name == "testtest");
- UNIT_ASSERT(scheme.TableNames.find("testtest")->second == 1);
- UNIT_ASSERT(scheme.TableNames.find("test") == scheme.TableNames.end());
- UNIT_ASSERT(scheme.Tables.find(1)->second.Columns.find(1)->second.Name == "testtest");
- UNIT_ASSERT(scheme.Tables.find(1)->second.ColumnNames.find("testtest")->second == 1);
- UNIT_ASSERT(scheme.Tables.find(1)->second.ColumnNames.find("test") == scheme.Tables.find(1)->second.ColumnNames.end());
- }
+
+ UNIT_ASSERT(scheme.Tables.find(1)->second.Name == "testtest");
+ UNIT_ASSERT(scheme.TableNames.find("testtest")->second == 1);
+ UNIT_ASSERT(scheme.TableNames.find("test") == scheme.TableNames.end());
+ UNIT_ASSERT(scheme.Tables.find(1)->second.Columns.find(1)->second.Name == "testtest");
+ UNIT_ASSERT(scheme.Tables.find(1)->second.ColumnNames.find("testtest")->second == 1);
+ UNIT_ASSERT(scheme.Tables.find(1)->second.ColumnNames.find("test") == scheme.Tables.find(1)->second.ColumnNames.end());
+ }
Y_UNIT_TEST(SchemaFillerTest) {
NTable::TScheme::TTableSchema schema;
@@ -629,7 +629,7 @@ Y_UNIT_TEST_SUITE(TFlatCxxDatabaseTest) {
UNIT_ASSERT_VALUES_EQUAL(schema.Columns.at(id).PType, col.second);
}
}
-}
-
-}
-}
+}
+
+}
+}
diff --git a/ydb/core/tablet_flat/flat_database.h b/ydb/core/tablet_flat/flat_database.h
index f9eea45851b..98baa8f4383 100644
--- a/ydb/core/tablet_flat/flat_database.h
+++ b/ydb/core/tablet_flat/flat_database.h
@@ -78,7 +78,7 @@ public:
// NOTE: the row refeneces data in some internal buffers that get invalidated on the next Select() or Commit() call
EReady Select(ui32 table, TRawVals key, TTagsRef tags, TRowState& row,
ui64 readFlags = 0, TRowVersion snapshot = TRowVersion::Max()) const noexcept;
-
+
EReady Select(ui32 table, TRawVals key, TTagsRef tags, TRowState& row, TSelectStats& stats,
ui64 readFlags = 0, TRowVersion snapshot = TRowVersion::Max()) const noexcept;
diff --git a/ydb/core/tablet_flat/flat_dbase_apply.cpp b/ydb/core/tablet_flat/flat_dbase_apply.cpp
index c509af09968..f87b315d332 100644
--- a/ydb/core/tablet_flat/flat_dbase_apply.cpp
+++ b/ydb/core/tablet_flat/flat_dbase_apply.cpp
@@ -193,13 +193,13 @@ bool TSchemeModifier::AddColumn(ui32 tid, const TString &name, ui32 id, ui32 typ
return true;
} else {
// do we have inserted a new column, OR we already have the same column with the same name?
- bool insertedNew = it.second && !haveName;
- bool replacedExisting = !it.second && it.first->second.Name == name && haveName && itName->second == it.first->first;
- Y_VERIFY_S((insertedNew || replacedExisting),
+ bool insertedNew = it.second && !haveName;
+ bool replacedExisting = !it.second && it.first->second.Name == name && haveName && itName->second == it.first->first;
+ Y_VERIFY_S((insertedNew || replacedExisting),
"NewName: " << name <<
- " OldName: " << (haveName ? itName->first : it.first->second.Name) <<
- " NewId: " << id <<
- " OldId: " << (haveName ? itName->second : it.first->first));
+ " OldName: " << (haveName ? itName->first : it.first->second.Name) <<
+ " NewId: " << id <<
+ " OldId: " << (haveName ? itName->second : it.first->first));
if (!haveName) {
table->ColumnNames.emplace(name, id);
return true;
diff --git a/ydb/core/tablet_flat/flat_dbase_scheme.cpp b/ydb/core/tablet_flat/flat_dbase_scheme.cpp
index c21dda16ba2..fa12005009b 100644
--- a/ydb/core/tablet_flat/flat_dbase_scheme.cpp
+++ b/ydb/core/tablet_flat/flat_dbase_scheme.cpp
@@ -1,12 +1,12 @@
#include "flat_dbase_scheme.h"
-
-namespace NKikimr {
+
+namespace NKikimr {
namespace NTable {
-
-TAutoPtr<TSchemeChanges> TScheme::GetSnapshot() const {
+
+TAutoPtr<TSchemeChanges> TScheme::GetSnapshot() const {
TAlter delta;
- for (const auto& itTable : Tables) {
+ for (const auto& itTable : Tables) {
const auto table = itTable.first;
delta.AddTable(itTable.second.Name, table);
@@ -46,7 +46,7 @@ TAutoPtr<TSchemeChanges> TScheme::GetSnapshot() const {
// N.B. must be last for compatibility with older versions :(
delta.SetByKeyFilter(table, itTable.second.ByKeyFilter);
delta.SetColdBorrow(table, itTable.second.ColdBorrow);
- }
+ }
delta.SetRedo(Redo.Annex);
delta.SetExecutorCacheSize(Executor.CacheSize);
@@ -56,9 +56,9 @@ TAutoPtr<TSchemeChanges> TScheme::GetSnapshot() const {
delta.SetExecutorFastLogPolicy(Executor.LogFastTactic);
return delta.Flush();
-}
-
-
+}
+
+
TAlter& TAlter::Merge(const TSchemeChanges &log)
{
Log.MutableDelta()->MergeFrom(log.GetDelta());
@@ -70,79 +70,79 @@ TAlter& TAlter::AddTable(const TString& name, ui32 id)
{
TAlterRecord& delta = *Log.AddDelta();
delta.SetDeltaType(TAlterRecord::AddTable);
- delta.SetTableName(name);
- delta.SetTableId(id);
+ delta.SetTableName(name);
+ delta.SetTableId(id);
return *this;
-}
-
+}
+
TAlter& TAlter::DropTable(ui32 id)
{
TAlterRecord& delta = *Log.AddDelta();
delta.SetDeltaType(TAlterRecord::DropTable);
- delta.SetTableId(id);
+ delta.SetTableId(id);
return *this;
-}
-
+}
+
TAlter& TAlter::AddColumn(ui32 table, const TString& name, ui32 id, ui32 type, bool notNull, TCell null)
{
TAlterRecord& delta = *Log.AddDelta();
delta.SetDeltaType(TAlterRecord::AddColumn);
- delta.SetColumnName(name);
- delta.SetTableId(table);
- delta.SetColumnId(id);
- delta.SetColumnType(type);
+ delta.SetColumnName(name);
+ delta.SetTableId(table);
+ delta.SetColumnId(id);
+ delta.SetColumnType(type);
delta.SetNotNull(notNull);
if (!null.IsNull())
delta.SetDefault(null.Data(), null.Size());
return *this;
-}
-
+}
+
TAlter& TAlter::DropColumn(ui32 table, ui32 id)
{
TAlterRecord& delta = *Log.AddDelta();
delta.SetDeltaType(TAlterRecord::DropColumn);
- delta.SetTableId(table);
- delta.SetColumnId(id);
+ delta.SetTableId(table);
+ delta.SetColumnId(id);
return *this;
-}
-
+}
+
TAlter& TAlter::AddColumnToFamily(ui32 table, ui32 column, ui32 family)
{
TAlterRecord& delta = *Log.AddDelta();
delta.SetDeltaType(TAlterRecord::AddColumnToFamily);
- delta.SetTableId(table);
- delta.SetColumnId(column);
+ delta.SetTableId(table);
+ delta.SetColumnId(column);
delta.SetFamilyId(family);
return *this;
-}
-
+}
+
TAlter& TAlter::AddFamily(ui32 table, ui32 family, ui32 room)
{
TAlterRecord& delta = *Log.AddDelta();
delta.SetDeltaType(TAlterRecord::AddFamily);
- delta.SetTableId(table);
+ delta.SetTableId(table);
delta.SetFamilyId(family);
delta.SetRoomId(room);
return *this;
-}
-
+}
+
TAlter& TAlter::AddColumnToKey(ui32 table, ui32 column)
{
TAlterRecord& delta = *Log.AddDelta();
delta.SetDeltaType(TAlterRecord::AddColumnToKey);
- delta.SetTableId(table);
- delta.SetColumnId(column);
+ delta.SetTableId(table);
+ delta.SetColumnId(column);
return *this;
-}
-
+}
+
TAlter& TAlter::SetFamily(ui32 table, ui32 family, ECache cache, ECodec codec)
{
TAlterRecord& delta = *Log.AddDelta();
@@ -292,10 +292,10 @@ TAlter& TAlter::SetEraseCache(ui32 tableId, bool enabled, ui32 minRows, ui32 max
TAutoPtr<TSchemeChanges> TAlter::Flush()
{
- TAutoPtr<TSchemeChanges> log(new TSchemeChanges);
+ TAutoPtr<TSchemeChanges> log(new TSchemeChanges);
log->MutableDelta()->Swap(Log.MutableDelta());
- return log;
-}
-
-}
-}
+ return log;
+}
+
+}
+}
diff --git a/ydb/core/tablet_flat/flat_dbase_scheme.h b/ydb/core/tablet_flat/flat_dbase_scheme.h
index 5f312ae34a3..1fd5ed2b480 100644
--- a/ydb/core/tablet_flat/flat_dbase_scheme.h
+++ b/ydb/core/tablet_flat/flat_dbase_scheme.h
@@ -8,23 +8,23 @@
#include <ydb/core/protos/scheme_log.pb.h>
#include <util/generic/map.h>
-#include <util/generic/hash_set.h>
-#include <util/generic/list.h>
+#include <util/generic/hash_set.h>
+#include <util/generic/list.h>
namespace NKikimr {
namespace NTable {
-using namespace NTabletFlatScheme;
-
+using namespace NTabletFlatScheme;
+
using NKikimrSchemeOp::ECompactionStrategy;
using TCompactionPolicy = NLocalDb::TCompactionPolicy;
-
+
class TScheme {
public:
- using TTypeId = ui32;
+ using TTypeId = ui32;
using ECache = NPage::ECache;
-
+
enum EDefault {
DefaultRoom = 0,
DefaultChannel = 1,
@@ -93,11 +93,11 @@ public:
Rooms[DefaultRoom];
}
- ui32 Id;
+ ui32 Id;
TString Name;
THashMap<ui32, TRoom> Rooms;
THashMap<ui32, TFamily> Families;
-
+
TIntrusiveConstPtr<TCompactionPolicy> CompactionPolicy;
bool ColdBorrow = false;
bool ByKeyFilter = false;
@@ -132,15 +132,15 @@ public:
ECompactionStrategy DefaultCompactionStrategy = NKikimrSchemeOp::CompactionStrategyGenerational;
};
- const TTableInfo* GetTableInfo(ui32 id) const { return const_cast<TScheme*>(this)->GetTableInfo(id); }
+ const TTableInfo* GetTableInfo(ui32 id) const { return const_cast<TScheme*>(this)->GetTableInfo(id); }
const TColumn* GetColumnInfo(ui32 table, ui32 id) const { return const_cast<TScheme*>(this)->GetColumnInfo(const_cast<TScheme*>(this)->GetTableInfo(table), id); }
-
- TAutoPtr<TSchemeChanges> GetSnapshot() const;
-
- inline TTableInfo* GetTableInfo(ui32 id) {
- return Tables.FindPtr(id);
- }
-
+
+ TAutoPtr<TSchemeChanges> GetSnapshot() const;
+
+ inline TTableInfo* GetTableInfo(ui32 id) {
+ return Tables.FindPtr(id);
+ }
+
inline TColumn* GetColumnInfo(TTableInfo* ptable, ui32 id) {
return ptable ? ptable->Columns.FindPtr(id) : nullptr;
}
@@ -149,10 +149,10 @@ public:
return ptable ? ptable->Columns.FindPtr(id) : nullptr;
}
- bool IsEmpty() const {
- return Tables.empty();
- }
-
+ bool IsEmpty() const {
+ return Tables.empty();
+ }
+
const TRoom* DefaultRoomFor(ui32 id) const noexcept
{
if (auto *table = GetTableInfo(id))
@@ -200,9 +200,9 @@ public:
TRedo Redo;
};
-// scheme delta
+// scheme delta
class TAlter {
-public:
+public:
using ECodec = NPage::ECodec;
using ECache = NPage::ECache;
@@ -235,8 +235,8 @@ public:
TAlter& SetEraseCache(ui32 tableId, bool enabled, ui32 minRows, ui32 maxBytes);
TAutoPtr<TSchemeChanges> Flush();
-protected:
+protected:
TSchemeChanges Log;
-};
-
+};
+
}}
diff --git a/ydb/core/tablet_flat/flat_executor.cpp b/ydb/core/tablet_flat/flat_executor.cpp
index 75b629c38b3..59afc462158 100644
--- a/ydb/core/tablet_flat/flat_executor.cpp
+++ b/ydb/core/tablet_flat/flat_executor.cpp
@@ -386,7 +386,7 @@ void TExecutor::Active(const TActorContext &ctx) {
CounterCacheMemTable = new NMonitoring::TCounterForPtr;
ResourceMetrics = MakeHolder<NMetrics::TResourceMetrics>(Owner->TabletID(), 0, Launcher);
-
+
PendingBlobQueue.Config.TabletID = Owner->TabletID();
PendingBlobQueue.Config.Generation = Generation();
PendingBlobQueue.Config.Follower = false;
@@ -630,7 +630,7 @@ void TExecutor::Boot(TEvTablet::TEvBoot::TPtr &ev, const TActorContext &ctx) {
TEvTablet::TEvBoot *msg = ev->Get();
Generation0 = msg->Generation;
Step0 = 0;
- Launcher = msg->Launcher;
+ Launcher = msg->Launcher;
Memory->SetProfiles(msg->ResourceProfiles);
const ui64 maxBootBytesInFly = 12 * 1024 * 1024;
@@ -643,7 +643,7 @@ void TExecutor::Boot(TEvTablet::TEvBoot::TPtr &ev, const TActorContext &ctx) {
for (auto& kv : msg->GroupReadBytes) {
totalBytes += kv.second;
}
-
+
ui64 totalOps = 0;
for (auto& kv : msg->GroupReadOps) {
totalOps += kv.second;
@@ -1918,7 +1918,7 @@ void TExecutor::CommitTransactionLog(TAutoPtr<TSeat> seat, TPageCollectionTxEnv
}
LogicRedo->CutLog(change->Deleted[num], edge, commit->GcDelta);
}
-
+
if (auto garbage = std::move(change->Garbage)) {
commit->WaitFollowerGcAck = true; // as we could collect some page collections
@@ -2274,16 +2274,16 @@ void TExecutor::CommitTransactionLog(TAutoPtr<TSeat> seat, TPageCollectionTxEnv
Counters->Cumulative()[TExecutorCounters::TX_FINISHED].Increment(1);
Counters->Percentile()[TExecutorCounters::TX_PERCENTILE_EXECUTE_CPUTIME].IncrementFor(execTimeuS);
Counters->Percentile()[TExecutorCounters::TX_PERCENTILE_BOOKKEEPING_CPUTIME].IncrementFor(bookkeepingTimeuS);
- Counters->Cumulative()[TExecutorCounters::CONSUMED_CPU].Increment(execTimeuS + bookkeepingTimeuS);
+ Counters->Cumulative()[TExecutorCounters::CONSUMED_CPU].Increment(execTimeuS + bookkeepingTimeuS);
if (AppTxCounters && txType != UnknownTxType) {
AppTxCounters->TxCumulative(txType, COUNTER_TT_EXECUTE_CPUTIME).Increment(execTimeuS);
AppTxCounters->TxCumulative(txType, COUNTER_TT_BOOKKEEPING_CPUTIME).Increment(bookkeepingTimeuS);
}
-
- if (ResourceMetrics) {
+
+ if (ResourceMetrics) {
ResourceMetrics->CPU.Increment(bookkeepingTimeuS + execTimeuS, Time->Now());
- ResourceMetrics->TryUpdate(ctx);
- }
+ ResourceMetrics->TryUpdate(ctx);
+ }
}
void TExecutor::MakeLogSnapshot() {
@@ -2308,7 +2308,7 @@ void TExecutor::MakeLogSnapshot() {
LogicAlter->SnapToLog(snap);
LogicRedo->SnapToLog(snap);
-
+
bool haveTxStatus = false;
for (const auto& kvTable : Scheme().Tables) {
@@ -2674,7 +2674,7 @@ void TExecutor::Handle(TEvTablet::TEvCommitResult::TPtr &ev, const TActorContext
for (auto& kv : msg->GroupWrittenBytes) {
totalBytes += kv.second;
}
-
+
ui64 totalOps = 0;
for (auto& kv : msg->GroupWrittenOps) {
totalOps += kv.second;
@@ -2812,7 +2812,7 @@ void TExecutor::Handle(NBlockIO::TEvStat::TPtr &ev, const TActorContext &ctx) {
Counters->Cumulative()[TExecutorCounters::COMP_BYTES_WRITTEN].Increment(msg->Bytes);
Counters->Cumulative()[TExecutorCounters::COMP_BLOBS_WRITTEN].Increment(msg->Ops);
break;
- }
+ }
} else {
switch (msg->Dir) {
case NBlockIO::EDir::Read:
@@ -3316,7 +3316,7 @@ void TExecutor::UpdateCounters(const TActorContext &ctx) {
executorCounters = Counters->MakeDiffForAggr(*CountersBaseline);
Counters->RememberCurrentStateAsBaseline(*CountersBaseline);
-
+
if (ResourceMetrics && !Stats->IsFollower) {
// N.B. DB_UNIQUE_OUTER_BYTES is already part of DB_UNIQUE_DATA_BYTES, due to how BackingSize works
// We also include DB_UNIQUE_KEEP_BYTES as unreferenced data that cannot be deleted
@@ -3324,14 +3324,14 @@ void TExecutor::UpdateCounters(const TActorContext &ctx) {
+ Counters->Simple()[TExecutorCounters::DB_UNIQUE_ELOBS_BYTES].Get()
+ Counters->Simple()[TExecutorCounters::DB_UNIQUE_KEEP_BYTES].Get();
- ResourceMetrics->StorageSystem.Set(storageSize);
+ ResourceMetrics->StorageSystem.Set(storageSize);
auto limit = Memory->Profile->GetStaticTabletTxMemoryLimit();
- auto memorySize = limit ? (UsedTabletMemory + limit) : (UsedTabletMemory + memory.Static);
- ResourceMetrics->Memory.Set(memorySize);
- Counters->Simple()[TExecutorCounters::CONSUMED_STORAGE].Set(storageSize);
- Counters->Simple()[TExecutorCounters::CONSUMED_MEMORY].Set(memorySize);
- }
+ auto memorySize = limit ? (UsedTabletMemory + limit) : (UsedTabletMemory + memory.Static);
+ ResourceMetrics->Memory.Set(memorySize);
+ Counters->Simple()[TExecutorCounters::CONSUMED_STORAGE].Set(storageSize);
+ Counters->Simple()[TExecutorCounters::CONSUMED_MEMORY].Set(memorySize);
+ }
}
if (AppCounters) {
@@ -3341,16 +3341,16 @@ void TExecutor::UpdateCounters(const TActorContext &ctx) {
// tablet id + tablet type
ui64 tabletId = Owner->TabletID();
- auto tabletType = Owner->TabletType();
+ auto tabletType = Owner->TabletType();
auto tenantPathId = Owner->Info()->TenantPathId;
TActorId countersAggregator = MakeTabletCountersAggregatorID(SelfId().NodeId(), Stats->IsFollower);
Send(countersAggregator, new TEvTabletCounters::TEvTabletAddCounters(
CounterEventsInFlight, tabletId, tabletType, tenantPathId, executorCounters, externalTabletCounters));
-
- if (ResourceMetrics) {
- ResourceMetrics->TryUpdate(ctx);
- }
+
+ if (ResourceMetrics) {
+ ResourceMetrics->TryUpdate(ctx);
+ }
}
Schedule(TDuration::Seconds(15), new TEvPrivate::TEvUpdateCounters());
}
@@ -3358,7 +3358,7 @@ void TExecutor::UpdateCounters(const TActorContext &ctx) {
float TExecutor::GetRejectProbability() const {
// Limit number of in-flight TXs
// TODO: make configurable
- if (Stats->TxInFly > 10000)
+ if (Stats->TxInFly > 10000)
return 1.0;
// Followers do not control compaction so let's always allow to read the data from follower
@@ -3633,11 +3633,11 @@ void TExecutor::RenderHtmlCounters(NMon::TEvRemoteHttpInfo::TPtr &ev) const {
if (Database) {
HTML(str) {
- str << "<style>";
- str << "table.metrics { margin-bottom: 20px; }";
- str << "table.metrics td { text-align: right; padding-right: 10px; }";
- str << "table.metrics td:nth-child(3) { text-align: left; }";
- str << "</style>";
+ str << "<style>";
+ str << "table.metrics { margin-bottom: 20px; }";
+ str << "table.metrics td { text-align: right; padding-right: 10px; }";
+ str << "table.metrics td:nth-child(3) { text-align: left; }";
+ str << "</style>";
if (Counters) {
H3() {str << "Executor counters";}
Counters->OutputHtml(str);
@@ -3647,10 +3647,10 @@ void TExecutor::RenderHtmlCounters(NMon::TEvRemoteHttpInfo::TPtr &ev) const {
H3() {str << "App counters";}
AppCounters->OutputHtml(str);
}
-
- if (ResourceMetrics) {
- str << NMetrics::AsHTML(*ResourceMetrics);
- }
+
+ if (ResourceMetrics) {
+ str << NMetrics::AsHTML(*ResourceMetrics);
+ }
}
} else {
HTML(str) {str << "loading...";} // todo: populate from bootlogic
@@ -3725,9 +3725,9 @@ void TExecutor::RenderHtmlPage(NMon::TEvRemoteHttpInfo::TPtr &ev) const {
H3() {str << "Scheme:";}
TVector<ui32> tables;
for (const auto &xtable : scheme->Tables)
- tables.push_back(xtable.first);
- Sort(tables);
- for (auto itable : tables) {
+ tables.push_back(xtable.first);
+ Sort(tables);
+ for (auto itable : tables) {
const auto &tinfo = scheme->Tables.find(itable)->second;
H4() {str << "<a href='db?TabletID=" << Owner->TabletID() << "&TableID=" << tinfo.Id << "'>Table: \"" << tinfo.Name << "\" id: " << tinfo.Id << "</a>";}
TABLE_SORTABLE_CLASS("table") {
@@ -3741,11 +3741,11 @@ void TExecutor::RenderHtmlPage(NMon::TEvRemoteHttpInfo::TPtr &ev) const {
}
TABLEBODY() {
TVector<ui32> columns;
- for (const auto &xcol : tinfo.Columns)
- columns.push_back(xcol.first);
- Sort(columns);
- for (auto icol : columns) {
- const auto &col = tinfo.Columns.find(icol)->second;
+ for (const auto &xcol : tinfo.Columns)
+ columns.push_back(xcol.first);
+ Sort(columns);
+ for (auto icol : columns) {
+ const auto &col = tinfo.Columns.find(icol)->second;
const bool isKey = (tinfo.KeyColumns.end() != std::find(tinfo.KeyColumns.begin(), tinfo.KeyColumns.end(), col.Id));
TABLER() {
TABLED() {str << col.Name;}
@@ -3823,12 +3823,12 @@ void TExecutor::RegisterExternalTabletCounters(TAutoPtr<TTabletCountersBase> app
}
void TExecutor::GetTabletCounters(TEvTablet::TEvGetCounters::TPtr &ev) {
- TAutoPtr<TEvTablet::TEvGetCountersResponse> response = new TEvTablet::TEvGetCountersResponse();
- Counters->OutputProto(*response->Record.MutableTabletCounters()->MutableExecutorCounters());
- AppCounters->OutputProto(*response->Record.MutableTabletCounters()->MutableAppCounters());
+ TAutoPtr<TEvTablet::TEvGetCountersResponse> response = new TEvTablet::TEvGetCountersResponse();
+ Counters->OutputProto(*response->Record.MutableTabletCounters()->MutableExecutorCounters());
+ AppCounters->OutputProto(*response->Record.MutableTabletCounters()->MutableAppCounters());
Send(ev->Sender, response.Release(), 0, ev->Cookie);
-}
-
+}
+
void TExecutor::UpdateConfig(TEvTablet::TEvUpdateConfig::TPtr &ev) {
Memory->SetProfiles(ev->Get()->ResourceProfiles);
ReadResourceProfile();
@@ -3846,9 +3846,9 @@ void TExecutor::SendUserAuxUpdateToFollowers(TString upd, const TActorContext &c
}
NMetrics::TResourceMetrics* TExecutor::GetResourceMetrics() const {
- return ResourceMetrics.Get();
-}
-
+ return ResourceMetrics.Get();
+}
+
void TExecutor::ReadResourceProfile() {
if (Database) {
auto type = static_cast<TMemory::ETablet>(Owner->TabletType());
@@ -3875,7 +3875,7 @@ TString TExecutor::CheckBorrowConsistency() {
TTransactionWaitPad::TTransactionWaitPad(THolder<TSeat> seat)
: Seat(std::move(seat))
{}
-
+
TTransactionWaitPad::~TTransactionWaitPad()
{}
diff --git a/ydb/core/tablet_flat/flat_executor.h b/ydb/core/tablet_flat/flat_executor.h
index 7379e41069c..df08b3a338a 100644
--- a/ydb/core/tablet_flat/flat_executor.h
+++ b/ydb/core/tablet_flat/flat_executor.h
@@ -321,7 +321,7 @@ class TExecutor
using ELnLev = NUtil::ELnLev;
friend class TExecutorCompactionLogic;
- class TTxExecutorDbMon;
+ class TTxExecutorDbMon;
static constexpr ui64 PostponeTransactionMemThreshold = 250*1024*1024;
@@ -409,7 +409,7 @@ class TExecutor
TTabletCountersWithTxTypes* AppTxCounters = nullptr;
TActorId Launcher;
-
+
THashMap<TPrivatePageCacheWaitPad*, THolder<TTransactionWaitPad>> TransactionWaitPads;
THashMap<TPrivatePageCacheWaitPad*, THolder<TCompactionReadWaitPad>> CompactionReadWaitPads;
@@ -597,7 +597,7 @@ public:
void RenderHtmlPage(NMon::TEvRemoteHttpInfo::TPtr &ev) const override;
void RenderHtmlCounters(NMon::TEvRemoteHttpInfo::TPtr &ev) const override;
- void RenderHtmlDb(NMon::TEvRemoteHttpInfo::TPtr &ev, const TActorContext &ctx) const override;
+ void RenderHtmlDb(NMon::TEvRemoteHttpInfo::TPtr &ev, const TActorContext &ctx) const override;
void GetTabletCounters(TEvTablet::TEvGetCounters::TPtr &ev) override;
void UpdateConfig(TEvTablet::TEvUpdateConfig::TPtr &ev) override;
diff --git a/ydb/core/tablet_flat/flat_executor_bootlogic.cpp b/ydb/core/tablet_flat/flat_executor_bootlogic.cpp
index 6512addd836..cf72960f9c4 100644
--- a/ydb/core/tablet_flat/flat_executor_bootlogic.cpp
+++ b/ydb/core/tablet_flat/flat_executor_bootlogic.cpp
@@ -166,8 +166,8 @@ void TExecutorBootLogic::LoadEntry(TIntrusivePtr<NBoot::TLoadBlobs> entry) {
EntriesToLoad[blobId] = entry;
LoadBlobQueue.Enqueue(blobId, group, this);
}
-}
-
+}
+
NBoot::TSpawned TExecutorBootLogic::LoadPages(NBoot::IStep *step, TAutoPtr<NPageCollection::TFetch> req) {
auto success = Loads.insert(std::make_pair(req->PageCollection.Get(), step)).second;
diff --git a/ydb/core/tablet_flat/flat_executor_counters.cpp b/ydb/core/tablet_flat/flat_executor_counters.cpp
index c06a5a81046..ddecce5206c 100644
--- a/ydb/core/tablet_flat/flat_executor_counters.cpp
+++ b/ydb/core/tablet_flat/flat_executor_counters.cpp
@@ -26,45 +26,45 @@ namespace NTabletFlatExecutor {
XX(200, "200-1000") \
XX(1000, ">1000")
-#define FLAT_EXECUTOR_DATA_SIZE(XX) \
- XX(0ULL, "0") \
- XX(1ULL, "10240") \
- XX(10*1024ULL, "102400") \
- XX(100*1024ULL, "1048576") \
- XX(1024*1024ULL, "10485760") \
- XX(10*1024*1024ULL, "104857600") \
- XX(100*1024*1024ULL, "1073741824") \
- XX(1024*1024*1024ULL, "10737418240") \
- XX(10*1024*1024*1024ULL, "107374182400") \
- XX(100*1024*1024*1024ULL, "1099511627776") \
- XX(1024*1024*1024*1024ULL, "inf")
-
-#define FLAT_EXECUTOR_DATA_RATE(XX) \
- XX(0ULL, "0") \
- XX(1ULL, "10240") \
- XX(10*1024ULL, "102400") \
- XX(100*1024ULL, "1048576") \
- XX(1024*1024ULL, "10485760") \
- XX(10*1024*1024ULL, "104857600") \
- XX(100*1024*1024ULL, "1073741824") \
- XX(1024*1024*1024ULL, "10737418240") \
- XX(10*1024*1024*1024ULL, "107374182400") \
- XX(100*1024*1024*1024ULL, "1099511627776") \
- XX(1024*1024*1024*1024ULL, "inf")
-
-#define FLAT_EXECUTOR_CONSUMED_CPU_RANGES(XX) \
- XX(0, "0%") \
- XX(100, "10%") \
- XX(100000, "20%") \
- XX(200000, "30%") \
- XX(300000, "40%") \
- XX(400000, "50%") \
- XX(500000, "60%") \
- XX(600000, "70%") \
- XX(700000, "80%") \
- XX(800000, "90%") \
- XX(900000, "100%")
-
+#define FLAT_EXECUTOR_DATA_SIZE(XX) \
+ XX(0ULL, "0") \
+ XX(1ULL, "10240") \
+ XX(10*1024ULL, "102400") \
+ XX(100*1024ULL, "1048576") \
+ XX(1024*1024ULL, "10485760") \
+ XX(10*1024*1024ULL, "104857600") \
+ XX(100*1024*1024ULL, "1073741824") \
+ XX(1024*1024*1024ULL, "10737418240") \
+ XX(10*1024*1024*1024ULL, "107374182400") \
+ XX(100*1024*1024*1024ULL, "1099511627776") \
+ XX(1024*1024*1024*1024ULL, "inf")
+
+#define FLAT_EXECUTOR_DATA_RATE(XX) \
+ XX(0ULL, "0") \
+ XX(1ULL, "10240") \
+ XX(10*1024ULL, "102400") \
+ XX(100*1024ULL, "1048576") \
+ XX(1024*1024ULL, "10485760") \
+ XX(10*1024*1024ULL, "104857600") \
+ XX(100*1024*1024ULL, "1073741824") \
+ XX(1024*1024*1024ULL, "10737418240") \
+ XX(10*1024*1024*1024ULL, "107374182400") \
+ XX(100*1024*1024*1024ULL, "1099511627776") \
+ XX(1024*1024*1024*1024ULL, "inf")
+
+#define FLAT_EXECUTOR_CONSUMED_CPU_RANGES(XX) \
+ XX(0, "0%") \
+ XX(100, "10%") \
+ XX(100000, "20%") \
+ XX(200000, "30%") \
+ XX(300000, "40%") \
+ XX(400000, "50%") \
+ XX(500000, "60%") \
+ XX(600000, "70%") \
+ XX(700000, "80%") \
+ XX(800000, "90%") \
+ XX(900000, "100%")
+
const char* TExecutorCounters::SimpleCounterNames[TExecutorCounters::SIMPLE_COUNTER_SIZE] =
{FLAT_EXECUTOR_SIMPLE_COUNTERS_MAP(COUNTER_TEXT_ARRAY)};
const char* TExecutorCounters::CumulativeCounterNames[TExecutorCounters::CUMULATIVE_COUNTER_SIZE] =
@@ -77,9 +77,9 @@ TExecutorCounters::TExecutorCounters()
{
static TTabletPercentileCounter::TRangeDef txLatencyConfig[] = { FLAT_EXECUTOR_LATENCY_RANGES(COUNTER_PERCENTILE_CONFIG_ARRAY) };
static TTabletPercentileCounter::TRangeDef txTouchedConfig[] = { FLAT_EXECUTOR_TOUCHED_BLOCKS(COUNTER_PERCENTILE_CONFIG_ARRAY) };
- static TTabletPercentileCounter::TRangeDef txDataSize[] = { FLAT_EXECUTOR_DATA_SIZE(COUNTER_PERCENTILE_CONFIG_ARRAY) };
- static TTabletPercentileCounter::TRangeDef txDataRate[] = { FLAT_EXECUTOR_DATA_RATE(COUNTER_PERCENTILE_CONFIG_ARRAY) };
- static TTabletPercentileCounter::TRangeDef txConsumedCpu[] = { FLAT_EXECUTOR_CONSUMED_CPU_RANGES(COUNTER_PERCENTILE_CONFIG_ARRAY) };
+ static TTabletPercentileCounter::TRangeDef txDataSize[] = { FLAT_EXECUTOR_DATA_SIZE(COUNTER_PERCENTILE_CONFIG_ARRAY) };
+ static TTabletPercentileCounter::TRangeDef txDataRate[] = { FLAT_EXECUTOR_DATA_RATE(COUNTER_PERCENTILE_CONFIG_ARRAY) };
+ static TTabletPercentileCounter::TRangeDef txConsumedCpu[] = { FLAT_EXECUTOR_CONSUMED_CPU_RANGES(COUNTER_PERCENTILE_CONFIG_ARRAY) };
Percentile()[TX_PERCENTILE_LATENCY_RO].Initialize(txLatencyConfig, false);
Percentile()[TX_PERCENTILE_LATENCY_RW].Initialize(txLatencyConfig, false);
diff --git a/ydb/core/tablet_flat/flat_executor_counters.h b/ydb/core/tablet_flat/flat_executor_counters.h
index 1e993b9b4cd..f100bc48a00 100644
--- a/ydb/core/tablet_flat/flat_executor_counters.h
+++ b/ydb/core/tablet_flat/flat_executor_counters.h
@@ -58,8 +58,8 @@ namespace NTabletFlatExecutor {
XX(USED_TABLET_MEMORY, "UsedTabletMemory") \
XX(USED_TABLET_TX_MEMORY, "UsedTabletTxMemory") \
XX(USED_DYNAMIC_TX_MEMORY, "UsedDynamicTxMemory") \
- XX(CONSUMED_STORAGE, "ConsumedStorage") \
- XX(CONSUMED_MEMORY, "ConsumedMemory") \
+ XX(CONSUMED_STORAGE, "ConsumedStorage") \
+ XX(CONSUMED_MEMORY, "ConsumedMemory") \
XX(COMPACTION_READ_IN_FLY, "CompactionReadInFly") \
#define FLAT_EXECUTOR_CUMULATIVE_COUNTERS_MAP(XX) \
@@ -105,7 +105,7 @@ namespace NTabletFlatExecutor {
XX(GC_FORGOTTEN, "GcBlobsForgotten") \
XX(GC_KEEPSET, "GcKeepFlagsSet") \
XX(GC_NOTKEEPSET, "GcNotKeepFlagsSet") \
- XX(CONSUMED_CPU, "ConsumedCPU") \
+ XX(CONSUMED_CPU, "ConsumedCPU") \
XX(COMPACTION_READ_POSTPONED, "CompactionReadPostponed") \
XX(COMPACTION_READ_CACHE_HITS, "CompactionReadCacheHits") \
XX(COMPACTION_READ_CACHE_MISSES, "CompactionReadCacheMisses") \
@@ -121,11 +121,11 @@ namespace NTabletFlatExecutor {
XX(TX_PERCENTILE_COMMITED_CPUTIME, "TxCommitedCPUTime") \
XX(TX_PERCENTILE_LOGSNAP_CPUTIME, "LogSnapCPUTime") \
XX(TX_PERCENTILE_PARTSWITCH_CPUTIME, "PartSwitchCPUTime") \
- XX(TX_PERCENTILE_TOUCHED_BLOCKS, "TouchedBlocks") \
- XX(TX_PERCENTILE_DB_DATA_BYTES, "HIST(DbDataBytes)") \
- XX(TX_PERCENTILE_TABLET_BYTES_WRITTEN, "HIST(TabletBytesWritten)") \
- XX(TX_PERCENTILE_TABLET_BYTES_READ, "HIST(TabletBytesRead)") \
- XX(TX_PERCENTILE_CONSUMED_CPU, "HIST(ConsumedCPU)") \
+ XX(TX_PERCENTILE_TOUCHED_BLOCKS, "TouchedBlocks") \
+ XX(TX_PERCENTILE_DB_DATA_BYTES, "HIST(DbDataBytes)") \
+ XX(TX_PERCENTILE_TABLET_BYTES_WRITTEN, "HIST(TabletBytesWritten)") \
+ XX(TX_PERCENTILE_TABLET_BYTES_READ, "HIST(TabletBytesRead)") \
+ XX(TX_PERCENTILE_CONSUMED_CPU, "HIST(ConsumedCPU)") \
XX(TX_PERCENTILE_FOLLOWERSYNC_LATENCY, "FollowerSyncLatency")
class TExecutorCounters : public TTabletCountersBase {
diff --git a/ydb/core/tablet_flat/flat_executor_db_mon.cpp b/ydb/core/tablet_flat/flat_executor_db_mon.cpp
index 66653eb86ef..d5353747beb 100644
--- a/ydb/core/tablet_flat/flat_executor_db_mon.cpp
+++ b/ydb/core/tablet_flat/flat_executor_db_mon.cpp
@@ -1,138 +1,138 @@
-#include "flat_executor.h"
+#include "flat_executor.h"
#include <ydb/library/binary_json/read.h>
#include <ydb/library/dynumber/dynumber.h>
-#include <util/stream/hex.h>
+#include <util/stream/hex.h>
#include <util/string/escape.h>
#include <library/cpp/html/pcdata/pcdata.h>
-
-namespace NKikimr {
-namespace NTabletFlatExecutor {
-
-class TExecutor::TTxExecutorDbMon : public TTransactionBase<TExecutor> {
-public:
- NMon::TEvRemoteHttpInfo::TPtr Event;
-
- TTxExecutorDbMon(NMon::TEvRemoteHttpInfo::TPtr& event, TSelf *executor)
- : TBase(executor)
- , Event(event)
- {}
-
- bool Execute(TTransactionContext &txc, const TActorContext &ctx) override {
- TStringStream str;
+
+namespace NKikimr {
+namespace NTabletFlatExecutor {
+
+class TExecutor::TTxExecutorDbMon : public TTransactionBase<TExecutor> {
+public:
+ NMon::TEvRemoteHttpInfo::TPtr Event;
+
+ TTxExecutorDbMon(NMon::TEvRemoteHttpInfo::TPtr& event, TSelf *executor)
+ : TBase(executor)
+ , Event(event)
+ {}
+
+ bool Execute(TTransactionContext &txc, const TActorContext &ctx) override {
+ TStringStream str;
{
const auto &scheme = txc.DB.GetScheme();
- TCgiParameters cgi(Event->Get()->Cgi());
- if (cgi.Has("TableID")) {
- ui32 tableId = FromStringWithDefault<ui32>(cgi.Get("TableID"));
+ TCgiParameters cgi(Event->Get()->Cgi());
+ if (cgi.Has("TableID")) {
+ ui32 tableId = FromStringWithDefault<ui32>(cgi.Get("TableID"));
const auto *tableInfo = scheme.GetTableInfo(tableId);
- if (tableInfo != nullptr) {
- str << "<script>$('.container').toggleClass('container container-fluid').css('padding-left','5%').css('padding-right','5%');</script>";
- str << "<h3>" << tableInfo->Id << ":" << tableInfo->Name << "</h3>";
- str << "<script>";
- str << R"___(
- function go() {
- var location = 'db?';
- var iargs = window.location.search.substring(1).split('&');
- var oargs = [];
- iargs.forEach(function(item){
- var params = item.split('=');
- if (params[0] == 'TabletID' || params[0] == 'TableID') {
- oargs.push(item);
- }
- });
- location += oargs.join('&');
- var keys = [];
- $('#go-form').find('input[type=text]').each(function(){if($(this).val().length>0)keys.push($(this).val());});
- location += "&Key=" + keys.join(',');
- if ($('#exact-checkbox').prop('checked')) {
- location += "&Lookup=Exact";
- }
- window.location.href = location;
- }
- )___";
- str << "</script>";
- str << "<form id='go-form' style='padding-bottom:10px'>";
- for (auto id : tableInfo->KeyColumns) {
- str << "<input type='text' id='key" << id << "' style='margin-right:3px'>";
- }
- str << R"___(
- <input type='button' value='Go' onclick='go();' style='margin-right:3px'>
- <input type='checkbox' id='exact-checkbox' checked='true'>
- <label for='exact-checkbox' style='padding-left:5px'>Exact</label>
- </form>
- )___";
+ if (tableInfo != nullptr) {
+ str << "<script>$('.container').toggleClass('container container-fluid').css('padding-left','5%').css('padding-right','5%');</script>";
+ str << "<h3>" << tableInfo->Id << ":" << tableInfo->Name << "</h3>";
+ str << "<script>";
+ str << R"___(
+ function go() {
+ var location = 'db?';
+ var iargs = window.location.search.substring(1).split('&');
+ var oargs = [];
+ iargs.forEach(function(item){
+ var params = item.split('=');
+ if (params[0] == 'TabletID' || params[0] == 'TableID') {
+ oargs.push(item);
+ }
+ });
+ location += oargs.join('&');
+ var keys = [];
+ $('#go-form').find('input[type=text]').each(function(){if($(this).val().length>0)keys.push($(this).val());});
+ location += "&Key=" + keys.join(',');
+ if ($('#exact-checkbox').prop('checked')) {
+ location += "&Lookup=Exact";
+ }
+ window.location.href = location;
+ }
+ )___";
+ str << "</script>";
+ str << "<form id='go-form' style='padding-bottom:10px'>";
+ for (auto id : tableInfo->KeyColumns) {
+ str << "<input type='text' id='key" << id << "' style='margin-right:3px'>";
+ }
+ str << R"___(
+ <input type='button' value='Go' onclick='go();' style='margin-right:3px'>
+ <input type='checkbox' id='exact-checkbox' checked='true'>
+ <label for='exact-checkbox' style='padding-left:5px'>Exact</label>
+ </form>
+ )___";
TVector<ui32> columns;
- for (const auto& pr : tableInfo->Columns) {
- columns.push_back(pr.first);
- }
- Sort(columns);
- TVector<TRawTypeValue> key;
- TList<TBuffer> vals;
- if (cgi.Has("Key")) {
- auto keys = SplitString(cgi.Get("Key"), ",");
- auto itColumn = tableInfo->KeyColumns.begin();
- for (const auto& val : keys) {
- if (itColumn == tableInfo->KeyColumns.end()) {
- break;
- }
- const auto& columnInfo = tableInfo->Columns.find(*itColumn)->second;
- auto type = columnInfo.PType;
- switch (type) {
- case NScheme::NTypeIds::Uint32:
- {
- ui32 v = FromStringWithDefault<ui32>(val);
- vals.emplace_back();
- TBuffer& buf = vals.back();
- buf.Assign(reinterpret_cast<const char*>(&v), sizeof(v));
- key.emplace_back(buf.Data(), buf.Size(), type);
- break;
- }
- case NScheme::NTypeIds::Uint64:
- {
- ui64 v = FromStringWithDefault<ui64>(val);
- vals.emplace_back();
- TBuffer& buf = vals.back();
- buf.Assign(reinterpret_cast<const char*>(&v), sizeof(v));
- key.emplace_back(buf.Data(), buf.Size(), type);
- break;
- }
- case NScheme::NTypeIds::String:
- case NScheme::NTypeIds::Utf8:
- {
- vals.emplace_back();
- TBuffer& buf = vals.back();
- buf.Assign(val.data(), val.size());
- key.emplace_back(buf.Data(), buf.Size(), type);
- break;
- }
- default:
- key.emplace_back();
- break;
- }
- ++itColumn;
- }
- while (itColumn != tableInfo->KeyColumns.end()) {
- key.emplace_back();
- ++itColumn;
- }
- }
- auto lookup = NTable::ELookup::GreaterOrEqualThan;
- if (cgi.Get("Lookup") == "Exact") {
- lookup = NTable::ELookup::ExactMatch;
- }
- auto result = txc.DB.Iterate(tableId, key, columns, lookup);
- str << "<table class='table table-sortable'>";
- str << "<thead>";
- str << "<tr>";
- for (ui32 column : columns) {
+ for (const auto& pr : tableInfo->Columns) {
+ columns.push_back(pr.first);
+ }
+ Sort(columns);
+ TVector<TRawTypeValue> key;
+ TList<TBuffer> vals;
+ if (cgi.Has("Key")) {
+ auto keys = SplitString(cgi.Get("Key"), ",");
+ auto itColumn = tableInfo->KeyColumns.begin();
+ for (const auto& val : keys) {
+ if (itColumn == tableInfo->KeyColumns.end()) {
+ break;
+ }
+ const auto& columnInfo = tableInfo->Columns.find(*itColumn)->second;
+ auto type = columnInfo.PType;
+ switch (type) {
+ case NScheme::NTypeIds::Uint32:
+ {
+ ui32 v = FromStringWithDefault<ui32>(val);
+ vals.emplace_back();
+ TBuffer& buf = vals.back();
+ buf.Assign(reinterpret_cast<const char*>(&v), sizeof(v));
+ key.emplace_back(buf.Data(), buf.Size(), type);
+ break;
+ }
+ case NScheme::NTypeIds::Uint64:
+ {
+ ui64 v = FromStringWithDefault<ui64>(val);
+ vals.emplace_back();
+ TBuffer& buf = vals.back();
+ buf.Assign(reinterpret_cast<const char*>(&v), sizeof(v));
+ key.emplace_back(buf.Data(), buf.Size(), type);
+ break;
+ }
+ case NScheme::NTypeIds::String:
+ case NScheme::NTypeIds::Utf8:
+ {
+ vals.emplace_back();
+ TBuffer& buf = vals.back();
+ buf.Assign(val.data(), val.size());
+ key.emplace_back(buf.Data(), buf.Size(), type);
+ break;
+ }
+ default:
+ key.emplace_back();
+ break;
+ }
+ ++itColumn;
+ }
+ while (itColumn != tableInfo->KeyColumns.end()) {
+ key.emplace_back();
+ ++itColumn;
+ }
+ }
+ auto lookup = NTable::ELookup::GreaterOrEqualThan;
+ if (cgi.Get("Lookup") == "Exact") {
+ lookup = NTable::ELookup::ExactMatch;
+ }
+ auto result = txc.DB.Iterate(tableId, key, columns, lookup);
+ str << "<table class='table table-sortable'>";
+ str << "<thead>";
+ str << "<tr>";
+ for (ui32 column : columns) {
const auto &columnInfo = tableInfo->Columns.find(column)->second;
- str << "<th>" << column << ":" << columnInfo.Name << "</th>";
- }
- str << "</tr>";
- str << "</thead>";
- str << "<tbody>";
+ str << "<th>" << column << ":" << columnInfo.Name << "</th>";
+ }
+ str << "</tr>";
+ str << "</thead>";
+ str << "<tbody>";
ssize_t rowOffset = FromStringWithDefault<ssize_t>(cgi.Get("RowsOffset"), 0);
rowOffset = Max<ssize_t>(rowOffset, 0);
ssize_t rowLimit = FromStringWithDefault<ssize_t>(cgi.Get("MaxRows"), 1000);
@@ -225,28 +225,28 @@ public:
str << "<i>unknown type " << tuple.Types[i] << "</i>";
break;
}
- }
+ }
str << "</td>";
- }
+ }
str << "</tr>";
- }
- }
- str << "</tbody>";
- str << "</table>";
+ }
+ }
+ str << "</tbody>";
+ str << "</table>";
if (result->Last() == NTable::EReady::Page)
return false;
- auto fnPrintLink = [this, &str, tableId, &cgi] (ssize_t offset, ssize_t limit, TString caption) {
+ auto fnPrintLink = [this, &str, tableId, &cgi] (ssize_t offset, ssize_t limit, TString caption) {
str << "<a href='db?TabletID=" << Self->TabletId()
- << "&TableID=" << tableId;
- if (cgi.Has("Key")) {
- str << "&Key=" << cgi.Get("Key");
- }
- if (cgi.Has("Lookup")) {
- str << "&Lookup=" << cgi.Get("Lookup");
- }
- str << "&RowsOffset=" << offset
+ << "&TableID=" << tableId;
+ if (cgi.Has("Key")) {
+ str << "&Key=" << cgi.Get("Key");
+ }
+ if (cgi.Has("Lookup")) {
+ str << "&Lookup=" << cgi.Get("Lookup");
+ }
+ str << "&RowsOffset=" << offset
<< "&MaxRows=" << limit
<< "'>" << caption << "</a>";
};
@@ -266,20 +266,20 @@ public:
}
fnPrintLink(0, 1000000000, "All");
- }
- }
- }
- ctx.Send(Event->Sender, new NMon::TEvRemoteHttpInfoRes(str.Str()));
- return true;
- }
-
- void Complete(const TActorContext&) override {}
-};
-
-void TExecutor::RenderHtmlDb(NMon::TEvRemoteHttpInfo::TPtr &ev, const TActorContext &ctx) const {
- const_cast<TExecutor*>(this)->Execute(new TTxExecutorDbMon(ev, const_cast<TExecutor*>(this)), ctx);
-}
-
-
-}
-}
+ }
+ }
+ }
+ ctx.Send(Event->Sender, new NMon::TEvRemoteHttpInfoRes(str.Str()));
+ return true;
+ }
+
+ void Complete(const TActorContext&) override {}
+};
+
+void TExecutor::RenderHtmlDb(NMon::TEvRemoteHttpInfo::TPtr &ev, const TActorContext &ctx) const {
+ const_cast<TExecutor*>(this)->Execute(new TTxExecutorDbMon(ev, const_cast<TExecutor*>(this)), ctx);
+}
+
+
+}
+}
diff --git a/ydb/core/tablet_flat/flat_executor_gclogic.cpp b/ydb/core/tablet_flat/flat_executor_gclogic.cpp
index c7bb48989ee..bded66353ec 100644
--- a/ydb/core/tablet_flat/flat_executor_gclogic.cpp
+++ b/ydb/core/tablet_flat/flat_executor_gclogic.cpp
@@ -1,26 +1,26 @@
-#include "flat_executor_gclogic.h"
+#include "flat_executor_gclogic.h"
#include "flat_bio_eggs.h"
#include <ydb/core/base/tablet.h>
-
-namespace NKikimr {
-namespace NTabletFlatExecutor {
-
+
+namespace NKikimr {
+namespace NTabletFlatExecutor {
+
TExecutorGCLogic::TExecutorGCLogic(TIntrusiveConstPtr<TTabletStorageInfo> info, TAutoPtr<NPageCollection::TSteppedCookieAllocator> cookies)
: TabletStorageInfo(std::move(info))
, Cookies(cookies)
, Generation(Cookies->Gen)
, Slicer(1, Cookies.Get(), NBlockIO::BlockSize)
- , SnapshotStep(0)
+ , SnapshotStep(0)
, PrevSnapshotStep(0)
, ConfirmedOnSendStep(0)
, AllowGarbageCollection(false)
-{
-}
-
+{
+}
+
void TExecutorGCLogic::WriteToLog(TLogCommit &commit) {
TGCTime time(Generation, commit.Step);
- TGCLogEntry& uncommittedDelta = UncommittedDeltaLog[time];
- uncommittedDelta.Time = time;
+ TGCLogEntry& uncommittedDelta = UncommittedDeltaLog[time];
+ uncommittedDelta.Time = time;
const ui32 gcEntriesInBatch = 250000; // ~7mb rawsize
@@ -59,18 +59,18 @@ void TExecutorGCLogic::WriteToLog(TLogCommit &commit) {
Slicer.One(commit.Refs, proto.SerializeAsString(), true);
}
}
-}
-
-TGCLogEntry TExecutorGCLogic::SnapshotLog(ui32 step) {
- TGCTime snapshotTime(Generation, step);
- TGCLogEntry snapshot(snapshotTime);
- for (const auto& chIt : ChannelInfo) {
- for (const auto& le : chIt.second.CommittedDelta) {
+}
+
+TGCLogEntry TExecutorGCLogic::SnapshotLog(ui32 step) {
+ TGCTime snapshotTime(Generation, step);
+ TGCLogEntry snapshot(snapshotTime);
+ for (const auto& chIt : ChannelInfo) {
+ for (const auto& le : chIt.second.CommittedDelta) {
Y_VERIFY(le.first <= snapshotTime);
TExecutorGCLogic::MergeVectors(snapshot.Delta.Created, le.second.Created);
TExecutorGCLogic::MergeVectors(snapshot.Delta.Deleted, le.second.Deleted);
- }
- }
+ }
+ }
for (const auto &it : UncommittedDeltaLog) {
TExecutorGCLogic::MergeVectors(snapshot.Delta.Created, it.second.Delta.Created);
@@ -78,22 +78,22 @@ TGCLogEntry TExecutorGCLogic::SnapshotLog(ui32 step) {
}
PrevSnapshotStep = SnapshotStep;
- SnapshotStep = step;
- return snapshot;
-}
-
+ SnapshotStep = step;
+ return snapshot;
+}
+
void TExecutorGCLogic::SnapToLog(NKikimrExecutorFlat::TLogSnapshot &snap, ui32 step) {
- TGCLogEntry gcLogEntry = SnapshotLog(step);
+ TGCLogEntry gcLogEntry = SnapshotLog(step);
auto *gcSnapDiscovered = snap.MutableGcSnapDiscovered();
auto *gcSnapLeft = snap.MutableGcSnapLeft();
-
+
gcSnapDiscovered->Reserve(gcLogEntry.Delta.Created.size());
for (const TLogoBlobID &x : gcLogEntry.Delta.Created)
- LogoBlobIDFromLogoBlobID(x, gcSnapDiscovered->Add());
-
+ LogoBlobIDFromLogoBlobID(x, gcSnapDiscovered->Add());
+
gcSnapLeft->Reserve(gcLogEntry.Delta.Deleted.size());
for (const TLogoBlobID &x : gcLogEntry.Delta.Deleted)
- LogoBlobIDFromLogoBlobID(x, gcSnapLeft->Add());
+ LogoBlobIDFromLogoBlobID(x, gcSnapLeft->Add());
for (const auto &chIt : ChannelInfo) {
if (chIt.second.CommitedGcBarrier) {
@@ -103,52 +103,52 @@ void TExecutorGCLogic::SnapToLog(NKikimrExecutorFlat::TLogSnapshot &snap, ui32 s
x->SetSetToStep(chIt.second.CommitedGcBarrier.Step);
}
}
-}
-
+}
+
void TExecutorGCLogic::OnCommitLog(ui32 step, ui32 confirmedOnSend, const TActorContext& ctx) {
- auto it = UncommittedDeltaLog.find(TGCTime(Generation, step));
- if (it != UncommittedDeltaLog.end()) {
- ApplyDelta(it->first, it->second.Delta);
- UncommittedDeltaLog.erase(it);
- }
+ auto it = UncommittedDeltaLog.find(TGCTime(Generation, step));
+ if (it != UncommittedDeltaLog.end()) {
+ ApplyDelta(it->first, it->second.Delta);
+ UncommittedDeltaLog.erase(it);
+ }
ConfirmedOnSendStep = Max(ConfirmedOnSendStep, confirmedOnSend);
if (step >= SnapshotStep)
- SendCollectGarbage(ctx);
-}
-
-void TExecutorGCLogic::OnCollectGarbageResult(TEvBlobStorage::TEvCollectGarbageResult::TPtr &ptr) {
- TEvBlobStorage::TEvCollectGarbageResult* ev = ptr->Get();
- TChannelInfo& channel = ChannelInfo[ev->Channel];
- if (ev->Status == NKikimrProto::EReplyStatus::OK) {
- channel.OnCollectGarbageSuccess();
- } else {
- channel.OnCollectGarbageFailure();
- }
-}
-
-void TExecutorGCLogic::ApplyLogEntry(TGCLogEntry& entry) {
- ApplyDelta(entry.Time, entry.Delta);
-}
-
+ SendCollectGarbage(ctx);
+}
+
+void TExecutorGCLogic::OnCollectGarbageResult(TEvBlobStorage::TEvCollectGarbageResult::TPtr &ptr) {
+ TEvBlobStorage::TEvCollectGarbageResult* ev = ptr->Get();
+ TChannelInfo& channel = ChannelInfo[ev->Channel];
+ if (ev->Status == NKikimrProto::EReplyStatus::OK) {
+ channel.OnCollectGarbageSuccess();
+ } else {
+ channel.OnCollectGarbageFailure();
+ }
+}
+
+void TExecutorGCLogic::ApplyLogEntry(TGCLogEntry& entry) {
+ ApplyDelta(entry.Time, entry.Delta);
+}
+
void TExecutorGCLogic::ApplyLogSnapshot(TGCLogEntry &snapshot, const TVector<std::pair<ui32, ui64>> &barriers) {
- ApplyLogEntry(snapshot);
+ ApplyLogEntry(snapshot);
for (auto &xpair : barriers) {
const ui32 channel = xpair.first;
const std::pair<ui32, ui32> barrier = ExpandGenStepPair(xpair.second);
ChannelInfo[channel].CommitedGcBarrier = {barrier.first, barrier.second};
}
-}
-
+}
+
void TExecutorGCLogic::HoldBarrier(ui32 step) {
Y_VERIFY(true == HoldBarriersSet.insert(TGCTime(Generation, step)).second);
-}
-
+}
+
void TExecutorGCLogic::ReleaseBarrier(ui32 step) {
Y_VERIFY(1 == HoldBarriersSet.erase(TGCTime(Generation, step)));
-}
-
+}
+
ui32 TExecutorGCLogic::GetActiveGcBarrier() {
if (HoldBarriersSet.empty())
return Max<ui32>();
@@ -160,21 +160,21 @@ void TExecutorGCLogic::FollowersSyncComplete(bool isBoot) {
AllowGarbageCollection = true;
}
-void TExecutorGCLogic::ApplyDelta(TGCTime time, TGCBlobDelta &delta) {
+void TExecutorGCLogic::ApplyDelta(TGCTime time, TGCBlobDelta &delta) {
for (const TLogoBlobID &blobId : delta.Created) {
auto &channel = ChannelInfo[blobId.Channel()];
TGCTime gcTime(blobId.Generation(), blobId.Step());
Y_VERIFY(channel.KnownGcBarrier < gcTime);
channel.CommittedDelta[gcTime].Created.push_back(blobId);
- }
+ }
for (const TLogoBlobID &blobId : delta.Deleted) {
auto &channel = ChannelInfo[blobId.Channel()];
channel.CommittedDelta[time].Deleted.push_back(blobId);
}
-}
-
-void TExecutorGCLogic::SendCollectGarbage(const TActorContext& ctx) {
+}
+
+void TExecutorGCLogic::SendCollectGarbage(const TActorContext& ctx) {
if (!AllowGarbageCollection)
return;
@@ -184,41 +184,41 @@ void TExecutorGCLogic::SendCollectGarbage(const TActorContext& ctx) {
const TGCTime minTime = std::min(uncommittedTime, std::min(uncommitedSnap, minBarrier));
- for (auto it = ChannelInfo.begin(); it != ChannelInfo.end(); ++it) {
+ for (auto it = ChannelInfo.begin(); it != ChannelInfo.end(); ++it) {
it->second.SendCollectGarbage(minTime, TabletStorageInfo.Get(), it->first, Generation, ctx);
- }
-}
-
-TExecutorGCLogic::TChannelInfo::TChannelInfo()
+ }
+}
+
+TExecutorGCLogic::TChannelInfo::TChannelInfo()
: GcCounter(1)
, GcWaitFor(0)
-{
-}
-
-void TExecutorGCLogic::TChannelInfo::ApplyDelta(TGCTime time, TGCBlobDelta& delta) {
- TGCBlobDelta& committedDelta = CommittedDelta[time];
+{
+}
+
+void TExecutorGCLogic::TChannelInfo::ApplyDelta(TGCTime time, TGCBlobDelta& delta) {
+ TGCBlobDelta& committedDelta = CommittedDelta[time];
DoSwap(committedDelta, delta);
Y_VERIFY_DEBUG(delta.Created.empty() && delta.Deleted.empty());
-}
-
+}
+
void TExecutorGCLogic::MergeVectors(TVector<TLogoBlobID>& destination, const TVector<TLogoBlobID>& source) {
- if (!source.empty()) {
- destination.insert(destination.end(), source.begin(), source.end());
- }
-}
-
+ if (!source.empty()) {
+ destination.insert(destination.end(), source.begin(), source.end());
+ }
+}
+
void TExecutorGCLogic::MergeVectors(THolder<TVector<TLogoBlobID>>& destination, const TVector<TLogoBlobID>& source) {
- if (!source.empty()) {
- if (!destination) {
+ if (!source.empty()) {
+ if (!destination) {
destination.Reset(new TVector<TLogoBlobID>(source));
- } else {
- MergeVectors(*destination.Get(), source);
- }
- }
-}
-
+ } else {
+ MergeVectors(*destination.Get(), source);
+ }
+ }
+}
+
void DeduplicateGCKeepVectors(TVector<TLogoBlobID> *keep, TVector<TLogoBlobID> *doNotKeep, ui32 barrierGen, ui32 barrierStep) {
- if (keep && doNotKeep && !keep->empty() && !doNotKeep->empty()) {
+ if (keep && doNotKeep && !keep->empty() && !doNotKeep->empty()) {
// vectors must be sorted!
TVector<TLogoBlobID>::const_iterator keepIt = keep->begin();
@@ -281,17 +281,17 @@ void DeduplicateGCKeepVectors(TVector<TLogoBlobID> *keep, TVector<TLogoBlobID> *
keep->erase(keepIns, keepEnd);
if (notKeepModified)
doNotKeep->erase(notIns, notEnd);
- }
-}
-
+ }
+}
+
TVector<TLogoBlobID>* TExecutorGCLogic::CreateVector(const TVector<TLogoBlobID>& source) {
- if (!source.empty()) {
+ if (!source.empty()) {
return new TVector<TLogoBlobID>(source);
- } else {
- return nullptr;
- }
-}
-
+ } else {
+ return nullptr;
+ }
+}
+
TExecutorGCLogic::TIntrospection TExecutorGCLogic::IntrospectStateSize() const {
TIntrospection ret;
@@ -354,9 +354,9 @@ void TExecutorGCLogic::TChannelInfo::SendCollectGarbageEntry(
++GcWaitFor;
}
-void TExecutorGCLogic::TChannelInfo::SendCollectGarbage(TGCTime uncommittedTime, const TTabletStorageInfo *tabletStorageInfo, ui32 channel, ui32 generation, const TActorContext& ctx) {
+void TExecutorGCLogic::TChannelInfo::SendCollectGarbage(TGCTime uncommittedTime, const TTabletStorageInfo *tabletStorageInfo, ui32 channel, ui32 generation, const TActorContext& ctx) {
if (GcWaitFor > 0)
- return;
+ return;
TVector<TLogoBlobID> keep;
TVector<TLogoBlobID> notKeep;
@@ -368,9 +368,9 @@ void TExecutorGCLogic::TChannelInfo::SendCollectGarbage(TGCTime uncommittedTime,
keep.insert(keep.end(), it->second.Created.begin(), it->second.Created.end());
notKeep.insert(notKeep.end(), it->second.Deleted.begin(), it->second.Deleted.end());
collectBarrier = it->first;
- } else
- break;
- }
+ } else
+ break;
+ }
// The first barrier of gen:0 (zero entry) is special
TGCTime zeroTime{ generation, 0 };
@@ -443,26 +443,26 @@ void TExecutorGCLogic::TChannelInfo::SendCollectGarbage(TGCTime uncommittedTime,
SendCollectGarbageEntry(ctx, std::move(xpair.second.first), std::move(xpair.second.second), tabletStorageInfo->TabletID, channel, xpair.first, generation);
}
}
- }
-}
-
-void TExecutorGCLogic::TChannelInfo::OnCollectGarbageSuccess() {
+ }
+}
+
+void TExecutorGCLogic::TChannelInfo::OnCollectGarbageSuccess() {
if (--GcWaitFor || !CollectSent)
return;
auto it = CommittedDelta.upper_bound(CollectSent);
if (it != CommittedDelta.begin()) {
- CommittedDelta.erase(CommittedDelta.begin(), it);
- }
+ CommittedDelta.erase(CommittedDelta.begin(), it);
+ }
- CollectSent.Clear();
+ CollectSent.Clear();
CommitedGcBarrier = KnownGcBarrier;
-}
-
-void TExecutorGCLogic::TChannelInfo::OnCollectGarbageFailure() {
- CollectSent.Clear();
+}
+
+void TExecutorGCLogic::TChannelInfo::OnCollectGarbageFailure() {
+ CollectSent.Clear();
--GcWaitFor;
-}
-
-}
-}
+}
+
+}
+}
diff --git a/ydb/core/tablet_flat/flat_executor_gclogic.h b/ydb/core/tablet_flat/flat_executor_gclogic.h
index fa499ba94de..9c1fa568a23 100644
--- a/ydb/core/tablet_flat/flat_executor_gclogic.h
+++ b/ydb/core/tablet_flat/flat_executor_gclogic.h
@@ -1,49 +1,49 @@
-#pragma once
+#pragma once
#include "defs.h"
#include "flat_sausage_slicer.h"
#include "flat_exec_commit.h"
-#include <util/generic/vector.h>
+#include <util/generic/vector.h>
#include <util/generic/set.h>
#include <ydb/core/base/blobstorage.h>
#include <ydb/core/tablet_flat/flat_executor.pb.h>
-
-namespace NKikimr {
-namespace NTabletFlatExecutor {
-
-struct TGCTime {
- ui32 Generation;
- ui32 Step;
-
- constexpr inline TGCTime() : TGCTime(0, 0) {}
- constexpr inline TGCTime(ui32 generation, ui32 step) : Generation(generation), Step(step) {}
- inline bool operator ==(const TGCTime& another) const { return Generation == another.Generation && Step == another.Step; }
- inline bool operator <(const TGCTime& another) const { return Generation < another.Generation || (Generation == another.Generation && Step < another.Step); }
- inline bool operator <=(const TGCTime& another) const { return Generation < another.Generation || (Generation == another.Generation && Step <= another.Step); }
- inline bool Valid() const { return Generation != 0 || Step != 0; }
- inline void Clear() { Generation = Step = 0; }
+
+namespace NKikimr {
+namespace NTabletFlatExecutor {
+
+struct TGCTime {
+ ui32 Generation;
+ ui32 Step;
+
+ constexpr inline TGCTime() : TGCTime(0, 0) {}
+ constexpr inline TGCTime(ui32 generation, ui32 step) : Generation(generation), Step(step) {}
+ inline bool operator ==(const TGCTime& another) const { return Generation == another.Generation && Step == another.Step; }
+ inline bool operator <(const TGCTime& another) const { return Generation < another.Generation || (Generation == another.Generation && Step < another.Step); }
+ inline bool operator <=(const TGCTime& another) const { return Generation < another.Generation || (Generation == another.Generation && Step <= another.Step); }
+ inline bool Valid() const { return Generation != 0 || Step != 0; }
+ inline void Clear() { Generation = Step = 0; }
static TGCTime Infinity() { return TGCTime(std::numeric_limits<ui32>::max(), std::numeric_limits<ui32>::max()); }
explicit operator bool() const noexcept { return Valid(); }
-};
-
-struct TGCLogEntry {
- TGCTime Time;
- TGCBlobDelta Delta;
-
- TGCLogEntry() {}
- TGCLogEntry(const TGCTime& time) : Time(time) {}
- TGCLogEntry(const TGCTime& time, const TGCBlobDelta& delta) : Time(time), Delta(delta) {}
-};
-
-class TExecutorGCLogic {
-public:
+};
+
+struct TGCLogEntry {
+ TGCTime Time;
+ TGCBlobDelta Delta;
+
+ TGCLogEntry() {}
+ TGCLogEntry(const TGCTime& time) : Time(time) {}
+ TGCLogEntry(const TGCTime& time, const TGCBlobDelta& delta) : Time(time), Delta(delta) {}
+};
+
+class TExecutorGCLogic {
+public:
TExecutorGCLogic(TIntrusiveConstPtr<TTabletStorageInfo>, TAutoPtr<NPageCollection::TSteppedCookieAllocator>);
void WriteToLog(TLogCommit &logEntry);
- TGCLogEntry SnapshotLog(ui32 step);
+ TGCLogEntry SnapshotLog(ui32 step);
void SnapToLog(NKikimrExecutorFlat::TLogSnapshot &logSnapshot, ui32 step);
void OnCommitLog(ui32 step, ui32 confirmedOnSend, const TActorContext &ctx); // notification about log commit - could send GC to blob storage
void OnCollectGarbageResult(TEvBlobStorage::TEvCollectGarbageResult::TPtr& ev); // notification on any garbage collection results
- void ApplyLogEntry(TGCLogEntry &entry); // apply one log entry, used during recovery and also from WriteToLog
+ void ApplyLogEntry(TGCLogEntry &entry); // apply one log entry, used during recovery and also from WriteToLog
void ApplyLogSnapshot(TGCLogEntry &snapshot, const TVector<std::pair<ui32, ui64>> &barriers);
void HoldBarrier(ui32 step); // holds GC on no more than this step for channels specified
void ReleaseBarrier(ui32 step);
@@ -73,45 +73,45 @@ public:
};
TIntrospection IntrospectStateSize() const;
-protected:
+protected:
const TIntrusiveConstPtr<TTabletStorageInfo> TabletStorageInfo;
const TAutoPtr<NPageCollection::TSteppedCookieAllocator> Cookies;
- const ui32 Generation;
+ const ui32 Generation;
NPageCollection::TSlicer Slicer;
-
- struct TChannelInfo {
+
+ struct TChannelInfo {
TMap<TGCTime, TGCBlobDelta> CommittedDelta; // we don't really need per-step map, what we really need is distinction b/w sent and not-yet-sent idsets
- TGCTime CollectSent;
+ TGCTime CollectSent;
TGCTime KnownGcBarrier;
TGCTime CommitedGcBarrier;
ui32 GcCounter;
ui32 GcWaitFor;
-
- inline TChannelInfo();
- void ApplyDelta(TGCTime time, TGCBlobDelta &delta);
- void SendCollectGarbage(TGCTime uncommittedTime, const TTabletStorageInfo *tabletStorageInfo, ui32 channel, ui32 generation, const TActorContext& executor);
+
+ inline TChannelInfo();
+ void ApplyDelta(TGCTime time, TGCBlobDelta &delta);
+ void SendCollectGarbage(TGCTime uncommittedTime, const TTabletStorageInfo *tabletStorageInfo, ui32 channel, ui32 generation, const TActorContext& executor);
void SendCollectGarbageEntry(const TActorContext &ctx, TVector<TLogoBlobID> &&keep, TVector<TLogoBlobID> &&notKeep, ui64 tabletid, ui32 channel, ui32 bsgroup, ui32 generation);
- void OnCollectGarbageSuccess();
- void OnCollectGarbageFailure();
- };
-
- ui32 SnapshotStep;
+ void OnCollectGarbageSuccess();
+ void OnCollectGarbageFailure();
+ };
+
+ ui32 SnapshotStep;
ui32 PrevSnapshotStep;
ui32 ConfirmedOnSendStep;
THashMap<ui32, TChannelInfo> ChannelInfo;
TMap<TGCTime, TGCLogEntry> UncommittedDeltaLog;
TSet<TGCTime> HoldBarriersSet;
-
+
bool AllowGarbageCollection;
- void ApplyDelta(TGCTime time, TGCBlobDelta &delta);
- void SendCollectGarbage(const TActorContext& executor);
+ void ApplyDelta(TGCTime time, TGCBlobDelta &delta);
+ void SendCollectGarbage(const TActorContext& executor);
static inline void MergeVectors(THolder<TVector<TLogoBlobID>>& destination, const TVector<TLogoBlobID>& source);
static inline void MergeVectors(TVector<TLogoBlobID>& destination, const TVector<TLogoBlobID>& source);
static inline TVector<TLogoBlobID>* CreateVector(const TVector<TLogoBlobID>& source);
-};
-
+};
+
void DeduplicateGCKeepVectors(TVector<TLogoBlobID> *keep, TVector<TLogoBlobID> *doNotKeep, ui32 barrierGen, ui32 barrierStep);
-}
-}
+}
+}
diff --git a/ydb/core/tablet_flat/flat_executor_gclogic_ut.cpp b/ydb/core/tablet_flat/flat_executor_gclogic_ut.cpp
index b68f68399b6..8c0c5ac6f01 100644
--- a/ydb/core/tablet_flat/flat_executor_gclogic_ut.cpp
+++ b/ydb/core/tablet_flat/flat_executor_gclogic_ut.cpp
@@ -1,9 +1,9 @@
-#include "flat_executor_gclogic.h"
+#include "flat_executor_gclogic.h"
#include <library/cpp/testing/unittest/registar.h>
-
-namespace NKikimr {
-namespace NTabletFlatExecutor {
-
+
+namespace NKikimr {
+namespace NTabletFlatExecutor {
+
Y_UNIT_TEST_SUITE(TFlatTableExecutorGC) {
bool TestDeduplication(TVector<TLogoBlobID> keep, TVector<TLogoBlobID> dontkeep, ui32 gen, ui32 step, TVector<TLogoBlobID> expectKeep, TVector<TLogoBlobID> expectnot) {
DeduplicateGCKeepVectors(&keep, &dontkeep, gen, step);
@@ -111,7 +111,7 @@ Y_UNIT_TEST_SUITE(TFlatTableExecutorGC) {
}
));
}
-}
-
-}
-}
+}
+
+}
+}
diff --git a/ydb/core/tablet_flat/flat_executor_txloglogic.cpp b/ydb/core/tablet_flat/flat_executor_txloglogic.cpp
index 0bf78de3e6c..df59ddc2455 100644
--- a/ydb/core/tablet_flat/flat_executor_txloglogic.cpp
+++ b/ydb/core/tablet_flat/flat_executor_txloglogic.cpp
@@ -81,13 +81,13 @@ void CompleteRoTransaction(TAutoPtr<TSeat> seat, const TActorContext &ownerCtx,
seat->Complete(ownerCtx);
LWTRACK(TransactionCompleteEnd, seat->Self->Orbit, seat->UniqID);
- const ui64 completeTimeus = ui64(1000000. * completeTimer.Passed());
-
+ const ui64 completeTimeus = ui64(1000000. * completeTimer.Passed());
+
counters->Cumulative()[TExecutorCounters::TX_RO_COMPLETED].Increment(1);
if (appTxCounters && txType != UnknownTxType)
appTxCounters->TxCumulative(txType, COUNTER_TT_RO_COMPLETED).Increment(1);
counters->Percentile()[TExecutorCounters::TX_PERCENTILE_COMMITED_CPUTIME].IncrementFor(completeTimeus);
- counters->Cumulative()[TExecutorCounters::CONSUMED_CPU].Increment(completeTimeus);
+ counters->Cumulative()[TExecutorCounters::CONSUMED_CPU].Increment(completeTimeus);
if (appTxCounters && txType != UnknownTxType)
appTxCounters->TxCumulative(txType, COUNTER_TT_COMMITED_CPUTIME).Increment(completeTimeus);
}
@@ -246,13 +246,13 @@ ui64 TLogicRedo::Confirm(ui32 step, const TActorContext &ctx, const TActorId &ow
entry.InFlyRWTransaction->Complete(ownerCtx);
LWTRACK(TransactionCompleteEnd, seat->Self->Orbit, seat->UniqID);
- const ui64 completeTimeus = ui64(1000000. * completeTimer.Passed());
-
+ const ui64 completeTimeus = ui64(1000000. * completeTimer.Passed());
+
Counters->Cumulative()[TExecutorCounters::TX_RW_COMPLETED].Increment(1);
if (AppTxCounters && txType != UnknownTxType)
AppTxCounters->TxCumulative(txType, COUNTER_TT_RW_COMPLETED).Increment(1);
Counters->Percentile()[TExecutorCounters::TX_PERCENTILE_COMMITED_CPUTIME].IncrementFor(completeTimeus);
- Counters->Cumulative()[TExecutorCounters::CONSUMED_CPU].Increment(completeTimeus);
+ Counters->Cumulative()[TExecutorCounters::CONSUMED_CPU].Increment(completeTimeus);
if (AppTxCounters && txType != UnknownTxType)
AppTxCounters->TxCumulative(txType, COUNTER_TT_COMMITED_CPUTIME).Increment(completeTimeus);
diff --git a/ydb/core/tablet_flat/flat_executor_ut.cpp b/ydb/core/tablet_flat/flat_executor_ut.cpp
index 8d2ed6fd523..c9cf5289711 100644
--- a/ydb/core/tablet_flat/flat_executor_ut.cpp
+++ b/ydb/core/tablet_flat/flat_executor_ut.cpp
@@ -1,8 +1,8 @@
#include "flat_executor_ut_common.h"
-
-namespace NKikimr {
-namespace NTabletFlatExecutor {
-
+
+namespace NKikimr {
+namespace NTabletFlatExecutor {
+
struct TRowsModel {
enum : ui32 {
TableId = 101,
@@ -241,7 +241,7 @@ struct TDummyResult: public IDestructable {
TDummyResult(ui64 count, ui64 expect)
: Count(count), Expect(expect)
{}
-
+
ui64 Count = 0;
ui64 Expect = 0;
};
@@ -591,7 +591,7 @@ Y_UNIT_TEST_SUITE(TFlatTableCompactionScan) {
env->GrabEdgeEventRethrow<TEvTestFlatTablet::TEvScanFinished>(handle);
env.SendSync(new TEvents::TEvPoison, false, true);
}
-}
+}
Y_UNIT_TEST_SUITE(TFlatTableExecutorTxLimit) {
diff --git a/ydb/core/tablet_flat/protos/ya.make b/ydb/core/tablet_flat/protos/ya.make
index 28378f340fe..fe35ffd0a84 100644
--- a/ydb/core/tablet_flat/protos/ya.make
+++ b/ydb/core/tablet_flat/protos/ya.make
@@ -1,19 +1,19 @@
-LIBRARY()
-
+LIBRARY()
+
OWNER(
serxa
xenoxeno
g:kikimr
)
-
-SRCS(
+
+SRCS(
flat_table_part.proto
flat_table_shard.proto
-)
-
-PEERDIR(
- contrib/libs/protobuf
+)
+
+PEERDIR(
+ contrib/libs/protobuf
ydb/core/protos
-)
-
-END()
+)
+
+END()
diff --git a/ydb/core/tablet_flat/tablet_flat_executed.cpp b/ydb/core/tablet_flat/tablet_flat_executed.cpp
index 7bb8c8ce5fd..4b3c15490c5 100644
--- a/ydb/core/tablet_flat/tablet_flat_executed.cpp
+++ b/ydb/core/tablet_flat/tablet_flat_executed.cpp
@@ -1,6 +1,6 @@
#include "tablet_flat_executed.h"
#include "flat_executor.h"
-#include "flat_executor_counters.h"
+#include "flat_executor_counters.h"
#include <ydb/core/base/appdata.h>
#include <library/cpp/monlib/service/pages/templates.h>
@@ -182,9 +182,9 @@ void TTabletExecutedFlat::RenderHtmlPage(NMon::TEvRemoteHttpInfo::TPtr &ev, cons
} else if (path == "/counters") {
Executor()->RenderHtmlCounters(ev);
return;
- } else if (path == "/db") {
- Executor()->RenderHtmlDb(ev, ExecutorCtx(ctx));
- return;
+ } else if (path == "/db") {
+ Executor()->RenderHtmlDb(ev, ExecutorCtx(ctx));
+ return;
} else {
const TDuration uptime = TAppData::TimeProvider->Now() - StartTime0;
TStringStream str;
@@ -238,8 +238,8 @@ void TTabletExecutedFlat::RenderHtmlPage(NMon::TEvRemoteHttpInfo::TPtr &ev, cons
void TTabletExecutedFlat::HandleGetCounters(TEvTablet::TEvGetCounters::TPtr &ev) {
Executor()->GetTabletCounters(ev);
-}
-
+}
+
bool TTabletExecutedFlat::HandleDefaultEvents(STFUNC_SIG) {
switch (ev->GetTypeRewrite()) {
HFunc(TEvTablet::TEvBoot, Handle);
diff --git a/ydb/core/tablet_flat/tablet_flat_executor.h b/ydb/core/tablet_flat/tablet_flat_executor.h
index d02e78597ed..075ebce354b 100644
--- a/ydb/core/tablet_flat/tablet_flat_executor.h
+++ b/ydb/core/tablet_flat/tablet_flat_executor.h
@@ -284,24 +284,24 @@ public:
NLWTrace::TOrbit Orbit;
};
-template<typename T>
+template<typename T>
class TTransactionBase : public ITransaction {
-protected:
- typedef T TSelf;
- typedef TTransactionBase<TSelf> TBase;
-
- TSelf * const Self;
-public:
- TTransactionBase(T *self)
- : Self(self)
- {}
+protected:
+ typedef T TSelf;
+ typedef TTransactionBase<TSelf> TBase;
+
+ TSelf * const Self;
+public:
+ TTransactionBase(T *self)
+ : Self(self)
+ {}
TTransactionBase(T *self, NLWTrace::TOrbit &&orbit)
: ITransaction(std::move(orbit))
, Self(self)
{ }
-};
-
+};
+
struct TExecutorStats {
bool IsActive = false;
bool IsFollower = false;
@@ -434,7 +434,7 @@ namespace NFlatExecutorSetup {
TTabletStorageInfo* Info() const { return TabletInfo.Get(); }
ui64 TabletID() const { return TabletInfo->TabletID; }
- TTabletTypes::EType TabletType() const { return TabletInfo->TabletType; }
+ TTabletTypes::EType TabletType() const { return TabletInfo->TabletType; }
const TActorId& Tablet() const { return TabletActorID; }
const TActorId& ExecutorID() const { return ExecutorActorID; }
const TActorId& LauncherID() const { return LauncherActorID; }
@@ -522,7 +522,7 @@ namespace NFlatExecutorSetup {
virtual void RenderHtmlPage(NMon::TEvRemoteHttpInfo::TPtr&) const = 0;
virtual void RenderHtmlCounters(NMon::TEvRemoteHttpInfo::TPtr&) const = 0;
- virtual void RenderHtmlDb(NMon::TEvRemoteHttpInfo::TPtr &ev, const TActorContext &ctx) const = 0;
+ virtual void RenderHtmlDb(NMon::TEvRemoteHttpInfo::TPtr &ev, const TActorContext &ctx) const = 0;
virtual void RegisterExternalTabletCounters(TAutoPtr<TTabletCountersBase> appCounters) = 0;
virtual void GetTabletCounters(TEvTablet::TEvGetCounters::TPtr&) = 0;
diff --git a/ydb/core/tablet_flat/ut/flat_test_db.cpp b/ydb/core/tablet_flat/ut/flat_test_db.cpp
index d71bcaaf068..b65757d4bbd 100644
--- a/ydb/core/tablet_flat/ut/flat_test_db.cpp
+++ b/ydb/core/tablet_flat/ut/flat_test_db.cpp
@@ -100,8 +100,8 @@ public:
ValueTypes.push_back(column->PType);
}
- for (auto tag : scheme.GetTableInfo(root)->KeyColumns) {
- KeyTypes.push_back(scheme.GetColumnInfo(root, tag)->PType);
+ for (auto tag : scheme.GetTableInfo(root)->KeyColumns) {
+ KeyTypes.push_back(scheme.GetColumnInfo(root, tag)->PType);
}
KeyCells.reserve(KeyTypes.size());
diff --git a/ydb/core/tablet_flat/ut/flat_test_db_helpers.h b/ydb/core/tablet_flat/ut/flat_test_db_helpers.h
index ec6ed030a61..ffc9a36daac 100644
--- a/ydb/core/tablet_flat/ut/flat_test_db_helpers.h
+++ b/ydb/core/tablet_flat/ut/flat_test_db_helpers.h
@@ -179,8 +179,8 @@ void AppendKeyColumn(ui32 root, const TScheme& scheme, TVector<TFakeTableCell>&
template <typename T, typename... Tt>
void AppendKeyColumn(ui32 root, const TScheme& scheme, TVector<TFakeTableCell>& tuple, T t, Tt... tt) {
ui32 pos = tuple.size();
- ui32 tag = scheme.GetTableInfo(root)->KeyColumns[pos];
- NScheme::TTypeId type = scheme.GetColumnInfo(root, tag)->PType;
+ ui32 tag = scheme.GetTableInfo(root)->KeyColumns[pos];
+ NScheme::TTypeId type = scheme.GetColumnInfo(root, tag)->PType;
tuple.push_back(FromVal(type, t));
AppendKeyColumn(root, scheme, tuple, tt...);
}
diff --git a/ydb/core/tablet_flat/ut/ut_db_scheme.cpp b/ydb/core/tablet_flat/ut/ut_db_scheme.cpp
index 7a511b1960c..ee12efa9032 100644
--- a/ydb/core/tablet_flat/ut/ut_db_scheme.cpp
+++ b/ydb/core/tablet_flat/ut/ut_db_scheme.cpp
@@ -1,7 +1,7 @@
#include <library/cpp/testing/unittest/registar.h>
#include <ydb/core/scheme/scheme_types_defs.h>
#include <ydb/core/tablet_flat/flat_dbase_apply.h>
-
+
namespace NKikimr {
namespace NTable {
@@ -134,35 +134,35 @@ Y_UNIT_TEST_SUITE(TScheme) {
const TModel model;
TScheme origin;
-
+
TSchemeModifier(origin).Apply(*model.Build().Flush());
-
+
model.Check(origin);
-
+
TScheme restored;
-
+
TSchemeModifier(restored).Apply(*origin.GetSnapshot());
-
+
model.Check(restored);
UNIT_ASSERT(!TCompare().Do(TModel::TableId, origin, {}));
UNIT_ASSERT(TCompare().Do(TModel::TableId, origin, origin));
UNIT_ASSERT(TCompare().Do(TModel::TableId, origin, restored));
- }
-
+ }
+
Y_UNIT_TEST(Delta)
{
const TModel model;
-
+
TAlter delta = model.Build();
-
+
TScheme restored;
-
+
TSchemeModifier(restored).Apply(*delta.Flush());
-
+
model.Check(restored);
- }
-
+ }
+
Y_UNIT_TEST(Policy)
{
auto delta = TModel().Build();
@@ -204,7 +204,7 @@ Y_UNIT_TEST_SUITE(TScheme) {
UNIT_ASSERT(false);
}
}
-}
-
-}
-}
+}
+
+}
+}
diff --git a/ydb/core/tablet_flat/ut/ya.make b/ydb/core/tablet_flat/ut/ya.make
index dad97cd4f6a..fd66d042026 100644
--- a/ydb/core/tablet_flat/ut/ya.make
+++ b/ydb/core/tablet_flat/ut/ya.make
@@ -16,10 +16,10 @@ OWNER(g:kikimr)
SRCS(
datetime_ut.cpp
decimal_ut.cpp
- flat_cxx_database_ut.cpp
+ flat_cxx_database_ut.cpp
ut_db_iface.cpp
ut_db_scheme.cpp
- flat_executor_ut.cpp
+ flat_executor_ut.cpp
flat_executor_database_ut.cpp
flat_executor_gclogic_ut.cpp
flat_range_cache_ut.cpp
diff --git a/ydb/core/tablet_flat/ya.make b/ydb/core/tablet_flat/ya.make
index 96f9a2a8d83..6b1226bf01c 100644
--- a/ydb/core/tablet_flat/ya.make
+++ b/ydb/core/tablet_flat/ya.make
@@ -12,7 +12,7 @@ SRCS(
flat_comp_create.cpp
flat_comp_gen.cpp
flat_comp_shard.cpp
- flat_cxx_database.h
+ flat_cxx_database.h
flat_database.cpp
flat_database.h
flat_dbase_scheme.cpp
@@ -31,9 +31,9 @@ SRCS(
flat_executor_compaction_logic.h
flat_executor_counters.cpp
flat_executor_counters.h
- flat_executor_db_mon.cpp
- flat_executor_gclogic.cpp
- flat_executor_gclogic.h
+ flat_executor_db_mon.cpp
+ flat_executor_gclogic.cpp
+ flat_executor_gclogic.h
flat_bio_actor.cpp
flat_executor_snapshot.cpp
flat_executor_txloglogic.cpp
diff --git a/ydb/core/testlib/actors/test_runtime.cpp b/ydb/core/testlib/actors/test_runtime.cpp
index 2fd13d42200..63f0436bff7 100644
--- a/ydb/core/testlib/actors/test_runtime.cpp
+++ b/ydb/core/testlib/actors/test_runtime.cpp
@@ -129,9 +129,9 @@ namespace NActors {
nodeAppData->NetClassifierConfig.CopyFrom(app0->NetClassifierConfig);
nodeAppData->StaticBlobStorageConfig->CopyFrom(*app0->StaticBlobStorageConfig);
nodeAppData->EnableKqpSpilling = app0->EnableKqpSpilling;
- nodeAppData->FeatureFlags = app0->FeatureFlags;
+ nodeAppData->FeatureFlags = app0->FeatureFlags;
nodeAppData->CompactionConfig = app0->CompactionConfig;
- nodeAppData->HiveConfig = app0->HiveConfig;
+ nodeAppData->HiveConfig = app0->HiveConfig;
nodeAppData->DataShardConfig = app0->DataShardConfig;
nodeAppData->MeteringConfig = app0->MeteringConfig;
nodeAppData->EnableMvccSnapshotWithLegacyDomainRoot = app0->EnableMvccSnapshotWithLegacyDomainRoot;
@@ -144,11 +144,11 @@ namespace NActors {
if (NeedMonitoring && !SingleSysEnv) {
ui16 port = GetPortManager().GetPort();
- node->Mon.Reset(new NActors::TMon({
- .Port = port,
- .Threads = 10,
- .Title = "KIKIMR monitoring"
- }));
+ node->Mon.Reset(new NActors::TMon({
+ .Port = port,
+ .Threads = 10,
+ .Title = "KIKIMR monitoring"
+ }));
nodeAppData->Mon = node->Mon.Get();
node->Mon->RegisterCountersPage("counters", "Counters", node->DynamicCounters);
auto actorsMonPage = node->Mon->RegisterIndexPage("actors", "Actors");
diff --git a/ydb/core/testlib/actors/test_runtime_ut.cpp b/ydb/core/testlib/actors/test_runtime_ut.cpp
index ba90a9abcc0..fce7f192934 100644
--- a/ydb/core/testlib/actors/test_runtime_ut.cpp
+++ b/ydb/core/testlib/actors/test_runtime_ut.cpp
@@ -126,15 +126,15 @@ Y_UNIT_TEST_SUITE(TActorTest) {
TActorId actorId = runtime.Register(new TMyActor);
runtime.Send(new IEventHandle(actorId, sender, new TEvents::TEvPing));
auto events = runtime.CaptureEvents();
- bool passed = false;
- for (const auto& event : events) {
- if (event->GetRecipientRewrite() == sender) {
- UNIT_ASSERT_EQUAL_C(event->Type, TEvents::THelloWorld::Pong, "reply ev. type check");
- passed = true;
- break;
- }
- }
- UNIT_ASSERT(passed);
+ bool passed = false;
+ for (const auto& event : events) {
+ if (event->GetRecipientRewrite() == sender) {
+ UNIT_ASSERT_EQUAL_C(event->Type, TEvents::THelloWorld::Pong, "reply ev. type check");
+ passed = true;
+ break;
+ }
+ }
+ UNIT_ASSERT(passed);
runtime.PushEventsFront(events);
}
@@ -214,15 +214,15 @@ Y_UNIT_TEST_SUITE(TActorTest) {
TActorId actorId = runtime.Register(actor);
runtime.Send(new IEventHandle(actorId, sender, new TEvents::TEvWakeup));
auto events = runtime.CaptureEvents();
- bool passed = false;
- for (const auto& event : events) {
- if (event->Recipient == actor->GetChildId()) {
- UNIT_ASSERT_EQUAL_C(event->Type, TEvents::THelloWorld::Ping, "reply ev. type check");
- passed = true;
- break;
- }
- }
- UNIT_ASSERT(passed);
+ bool passed = false;
+ for (const auto& event : events) {
+ if (event->Recipient == actor->GetChildId()) {
+ UNIT_ASSERT_EQUAL_C(event->Type, TEvents::THelloWorld::Ping, "reply ev. type check");
+ passed = true;
+ break;
+ }
+ }
+ UNIT_ASSERT(passed);
runtime.PushEventsFront(events);
}
diff --git a/ydb/core/testlib/basics/appdata.h b/ydb/core/testlib/basics/appdata.h
index 71511c9440b..409869161f5 100644
--- a/ydb/core/testlib/basics/appdata.h
+++ b/ydb/core/testlib/basics/appdata.h
@@ -76,7 +76,7 @@ namespace NKikimr {
bool EnableKqpSpilling = false;
NKikimrConfig::TCompactionConfig CompactionConfig;
TString NetDataSourceUrl;
- NKikimrConfig::THiveConfig HiveConfig;
+ NKikimrConfig::THiveConfig HiveConfig;
NKikimrConfig::TDataShardConfig DataShardConfig;
NKikimrConfig::TMeteringConfig MeteringConfig;
NKikimrPQ::TPQConfig PQConfig;
diff --git a/ydb/core/testlib/basics/helpers.cpp b/ydb/core/testlib/basics/helpers.cpp
index 7e7e6e09aba..259e4f9da94 100644
--- a/ydb/core/testlib/basics/helpers.cpp
+++ b/ydb/core/testlib/basics/helpers.cpp
@@ -34,7 +34,7 @@ namespace NKikimr {
NTabletPipe::TClientConfig GetPipeConfigWithRetries()
{
NTabletPipe::TClientConfig pipeConfig;
- pipeConfig.RetryPolicy = NTabletPipe::TClientRetryPolicy::WithRetries();
+ pipeConfig.RetryPolicy = NTabletPipe::TClientRetryPolicy::WithRetries();
return pipeConfig;
}
diff --git a/ydb/core/testlib/basics/storage.h b/ydb/core/testlib/basics/storage.h
index 01e896009f9..36cee178189 100644
--- a/ydb/core/testlib/basics/storage.h
+++ b/ydb/core/testlib/basics/storage.h
@@ -56,11 +56,11 @@ namespace NKikimr {
ui64 salt = ++keySalt;
TString baseDir = Runtime.GetTempDir();
- if (Conf.UseDisk) {
- MakeDirIfNotExist(baseDir.c_str());
- }
+ if (Conf.UseDisk) {
+ MakeDirIfNotExist(baseDir.c_str());
+ }
- PDiskPath = TStringBuilder() << baseDir << "pdisk_1.dat";
+ PDiskPath = TStringBuilder() << baseDir << "pdisk_1.dat";
if (!Mock) {
FormatPDisk(PDiskPath,
@@ -95,10 +95,10 @@ namespace NKikimr {
conf->PDiskConfigOverlay.SetGetDriveDataSwitch(NKikimrBlobStorage::TPDiskConfig::DoNotTouch);
conf->PDiskConfigOverlay.SetWriteCacheSwitch(NKikimrBlobStorage::TPDiskConfig::DoNotTouch);
- if (SectorMap) {
- conf->SectorMaps[PDiskPath] = SectorMap;
- }
-
+ if (SectorMap) {
+ conf->SectorMaps[PDiskPath] = SectorMap;
+ }
+
auto baseInfo = TVDiskConfig::TBaseInfo::SampleForTests();
TIntrusivePtr<TVDiskConfig> vDisk = conf->AllVDiskKinds->MakeVDiskConfig(baseInfo);
vDisk->AdvanceEntryPointTimeout = TDuration::Seconds(5);
@@ -123,7 +123,7 @@ namespace NKikimr {
for (const auto &it: domains.Domains) {
str << "AvailabilityDomains: " << it.second->DomainUid << Endl;
}
- str << "PDisks { NodeID: " << Runtime.GetNodeId(0) << " PDiskID: 1 PDiskGuid: " << PDiskGuid
+ str << "PDisks { NodeID: " << Runtime.GetNodeId(0) << " PDiskID: 1 PDiskGuid: " << PDiskGuid
<< " Path: \"" << escapedPdiskPath << "\"}" << Endl;
str << "" << Endl;
@@ -135,7 +135,7 @@ namespace NKikimr {
str << "VDisks {" << Endl;
str << " VDiskID { GroupID: 0 GroupGeneration: 1 Ring: " << ringIdx
<< " Domain: " << domainIdx << " VDisk: " << vDiskIdx << " }" << Endl;
- str << " VDiskLocation { NodeID: " << Runtime.GetNodeId(0) << " PDiskID: 1 PDiskGuid: " << PDiskGuid
+ str << " VDiskLocation { NodeID: " << Runtime.GetNodeId(0) << " PDiskID: 1 PDiskGuid: " << PDiskGuid
<< " VDiskSlotID: " << slotId << " }" << Endl;
str << "}" << Endl;
}
@@ -154,7 +154,7 @@ namespace NKikimr {
str << " FailDomains {" << Endl;
for (const ui32 vDiskIdx : xrange(DisksInDomain)) {
ui32 slotId = vDiskIdx + domainIdx * DisksInDomain + ringIdx * DomainsNum * DisksInDomain;
- str << " VDiskLocations { NodeID: " << Runtime.GetNodeId(0) << " PDiskID: 1 VDiskSlotID: " << slotId
+ str << " VDiskLocations { NodeID: " << Runtime.GetNodeId(0) << " PDiskID: 1 VDiskSlotID: " << slotId
<< " PDiskGuid: " << PDiskGuid << " }" << Endl;
}
str << " }" << Endl;
diff --git a/ydb/core/testlib/fake_coordinator.h b/ydb/core/testlib/fake_coordinator.h
index 9e295068e74..b3098d60a59 100644
--- a/ydb/core/testlib/fake_coordinator.h
+++ b/ydb/core/testlib/fake_coordinator.h
@@ -35,12 +35,12 @@ namespace NKikimr {
static NTabletPipe::TClientConfig GetPipeClientConfig() {
NTabletPipe::TClientConfig config;
config.CheckAliveness = true;
- config.RetryPolicy = {
- .RetryLimitCount = 3,
- .MinRetryTime = TDuration::MilliSeconds(10),
- .MaxRetryTime = TDuration::MilliSeconds(500),
- .BackoffMultiplier = 2
- };
+ config.RetryPolicy = {
+ .RetryLimitCount = 3,
+ .MinRetryTime = TDuration::MilliSeconds(10),
+ .MaxRetryTime = TDuration::MilliSeconds(500),
+ .BackoffMultiplier = 2
+ };
return config;
}
diff --git a/ydb/core/testlib/fake_scheme_shard.h b/ydb/core/testlib/fake_scheme_shard.h
index d4bc3ddaf71..8c388d49dd0 100644
--- a/ydb/core/testlib/fake_scheme_shard.h
+++ b/ydb/core/testlib/fake_scheme_shard.h
@@ -91,7 +91,7 @@ public:
TString out;
Y_PROTOBUF_SUPPRESS_NODISCARD State->ACL.GetACL().SerializeToString(&out);
response->Record.MutablePathDescription()->MutableSelf()->SetACL(out);
- response->Record.MutablePathDescription()->MutableSelf()->SetEffectiveACL(out);
+ response->Record.MutablePathDescription()->MutableSelf()->SetEffectiveACL(out);
//Fill response from State
ctx.Send(ev->Sender, response.Release());
}
diff --git a/ydb/core/testlib/service_mocks/access_service_mock.h b/ydb/core/testlib/service_mocks/access_service_mock.h
index eabb063b8ef..f18ac92f0a8 100644
--- a/ydb/core/testlib/service_mocks/access_service_mock.h
+++ b/ydb/core/testlib/service_mocks/access_service_mock.h
@@ -1,20 +1,20 @@
-#pragma once
-
-#include <yandex/cloud/priv/servicecontrol/v1/access_service.grpc.pb.h>
-
+#pragma once
+
+#include <yandex/cloud/priv/servicecontrol/v1/access_service.grpc.pb.h>
+
#include <library/cpp/testing/unittest/registar.h>
#include <iterator>
-class TAccessServiceMock : public yandex::cloud::priv::servicecontrol::v1::AccessService::Service {
-public:
+class TAccessServiceMock : public yandex::cloud::priv::servicecontrol::v1::AccessService::Service {
+public:
template <class TResonseProto>
struct TResponse {
TResonseProto Response;
grpc::Status Status = grpc::Status::OK;
bool RequireRequestId = false;
};
-
+
THashMap<TString, TResponse<yandex::cloud::priv::servicecontrol::v1::AuthenticateResponse>> AuthenticateData;
THashMap<TString, TResponse<yandex::cloud::priv::servicecontrol::v1::AuthorizeResponse>> AuthorizeData;
@@ -28,9 +28,9 @@ public:
}
}
- virtual grpc::Status Authenticate(
+ virtual grpc::Status Authenticate(
grpc::ServerContext* ctx,
- const yandex::cloud::priv::servicecontrol::v1::AuthenticateRequest* request,
+ const yandex::cloud::priv::servicecontrol::v1::AuthenticateRequest* request,
yandex::cloud::priv::servicecontrol::v1::AuthenticateResponse* response) override
{
TString key;
@@ -40,27 +40,27 @@ public:
key = request->iam_token();
}
auto it = AuthenticateData.find(key);
- if (it != AuthenticateData.end()) {
+ if (it != AuthenticateData.end()) {
response->CopyFrom(it->second.Response);
CheckRequestId(ctx, it->second, key);
return it->second.Status;
- } else {
- return grpc::Status(grpc::StatusCode::PERMISSION_DENIED, "Permission Denied");
- }
- }
-
- virtual grpc::Status Authorize(
+ } else {
+ return grpc::Status(grpc::StatusCode::PERMISSION_DENIED, "Permission Denied");
+ }
+ }
+
+ virtual grpc::Status Authorize(
grpc::ServerContext* ctx,
- const yandex::cloud::priv::servicecontrol::v1::AuthorizeRequest* request,
- yandex::cloud::priv::servicecontrol::v1::AuthorizeResponse* response) override {
+ const yandex::cloud::priv::servicecontrol::v1::AuthorizeRequest* request,
+ yandex::cloud::priv::servicecontrol::v1::AuthorizeResponse* response) override {
const TString& token = request->subject().user_account().id() + "-" + request->permission() + "-" + request->resource_path(0).id();
- auto it = AuthorizeData.find(token);
- if (it != AuthorizeData.end()) {
+ auto it = AuthorizeData.find(token);
+ if (it != AuthorizeData.end()) {
response->CopyFrom(it->second.Response);
CheckRequestId(ctx, it->second, token);
return it->second.Status;
- } else {
- return grpc::Status(grpc::StatusCode::PERMISSION_DENIED, "Permission Denied");
- }
- }
-};
+ } else {
+ return grpc::Status(grpc::StatusCode::PERMISSION_DENIED, "Permission Denied");
+ }
+ }
+};
diff --git a/ydb/core/testlib/service_mocks/folder_service_mock.h b/ydb/core/testlib/service_mocks/folder_service_mock.h
index 5d0c65ee405..5b1309ffc42 100644
--- a/ydb/core/testlib/service_mocks/folder_service_mock.h
+++ b/ydb/core/testlib/service_mocks/folder_service_mock.h
@@ -1,23 +1,23 @@
-#pragma once
-
-#include <yandex/cloud/priv/resourcemanager/v1/transitional/folder_service.grpc.pb.h>
-
-class TFolderServiceMock : public yandex::cloud::priv::resourcemanager::v1::transitional::FolderService::Service {
-public:
- THashMap<TString, yandex::cloud::priv::resourcemanager::v1::Folder> Folders;
-
- virtual grpc::Status List(
- grpc::ServerContext*,
- const yandex::cloud::priv::resourcemanager::v1::transitional::ListFoldersRequest* request,
- yandex::cloud::priv::resourcemanager::v1::transitional::ListFoldersResponse* response) override {
- TString key = request->id();
- auto it = Folders.find(key);
- if (it != Folders.end()) {
- response->add_result()->CopyFrom(it->second);
- return grpc::Status::OK;
- } else {
- return grpc::Status(grpc::StatusCode::NOT_FOUND, "Not Found");
- }
- }
-};
-
+#pragma once
+
+#include <yandex/cloud/priv/resourcemanager/v1/transitional/folder_service.grpc.pb.h>
+
+class TFolderServiceMock : public yandex::cloud::priv::resourcemanager::v1::transitional::FolderService::Service {
+public:
+ THashMap<TString, yandex::cloud::priv::resourcemanager::v1::Folder> Folders;
+
+ virtual grpc::Status List(
+ grpc::ServerContext*,
+ const yandex::cloud::priv::resourcemanager::v1::transitional::ListFoldersRequest* request,
+ yandex::cloud::priv::resourcemanager::v1::transitional::ListFoldersResponse* response) override {
+ TString key = request->id();
+ auto it = Folders.find(key);
+ if (it != Folders.end()) {
+ response->add_result()->CopyFrom(it->second);
+ return grpc::Status::OK;
+ } else {
+ return grpc::Status(grpc::StatusCode::NOT_FOUND, "Not Found");
+ }
+ }
+};
+
diff --git a/ydb/core/testlib/service_mocks/service_account_service_mock.h b/ydb/core/testlib/service_mocks/service_account_service_mock.h
index 48bf373aecb..583396fc0fe 100644
--- a/ydb/core/testlib/service_mocks/service_account_service_mock.h
+++ b/ydb/core/testlib/service_mocks/service_account_service_mock.h
@@ -1,13 +1,13 @@
-#pragma once
-
-#include <yandex/cloud/priv/iam/v1/service_account_service.grpc.pb.h>
-
-class TServiceAccountServiceMock : public yandex::cloud::priv::iam::v1::ServiceAccountService::Service {
-public:
- THashMap<TString, yandex::cloud::priv::iam::v1::ServiceAccount> ServiceAccountData;
+#pragma once
+
+#include <yandex/cloud/priv/iam/v1/service_account_service.grpc.pb.h>
+
+class TServiceAccountServiceMock : public yandex::cloud::priv::iam::v1::ServiceAccountService::Service {
+public:
+ THashMap<TString, yandex::cloud::priv::iam::v1::ServiceAccount> ServiceAccountData;
THashMap<TString, yandex::cloud::priv::iam::v1::IamToken> IamTokens;
TString Identity;
-
+
TMaybe<grpc::Status> CheckAuthorization(grpc::ServerContext* context) {
if (!Identity.empty()) {
auto[reqIdBegin, reqIdEnd] = context->client_metadata().equal_range("authorization");
@@ -24,7 +24,7 @@ public:
}
virtual grpc::Status Get(grpc::ServerContext* context,
- const yandex::cloud::priv::iam::v1::GetServiceAccountRequest* request,
+ const yandex::cloud::priv::iam::v1::GetServiceAccountRequest* request,
yandex::cloud::priv::iam::v1::ServiceAccount* response) override
{
auto status = CheckAuthorization(context);
@@ -33,14 +33,14 @@ public:
}
TString id = request->service_account_id();
- auto it = ServiceAccountData.find(id);
- if (it != ServiceAccountData.end()) {
- response->CopyFrom(it->second);
- return grpc::Status::OK;
- } else {
- return grpc::Status(grpc::StatusCode::NOT_FOUND, "Not Found");
- }
- }
+ auto it = ServiceAccountData.find(id);
+ if (it != ServiceAccountData.end()) {
+ response->CopyFrom(it->second);
+ return grpc::Status::OK;
+ } else {
+ return grpc::Status(grpc::StatusCode::NOT_FOUND, "Not Found");
+ }
+ }
virtual grpc::Status IssueToken(grpc::ServerContext* context,
const yandex::cloud::priv::iam::v1::IssueTokenRequest* request,
@@ -61,5 +61,5 @@ public:
}
}
-};
-
+};
+
diff --git a/ydb/core/testlib/service_mocks/user_account_service_mock.h b/ydb/core/testlib/service_mocks/user_account_service_mock.h
index 9bff16c502c..ddd7bb34cf6 100644
--- a/ydb/core/testlib/service_mocks/user_account_service_mock.h
+++ b/ydb/core/testlib/service_mocks/user_account_service_mock.h
@@ -1,22 +1,22 @@
-#pragma once
-
-#include <yandex/cloud/priv/iam/v1/user_account_service.grpc.pb.h>
-
-class TUserAccountServiceMock : public yandex::cloud::priv::iam::v1::UserAccountService::Service {
-public:
- THashMap<TString, yandex::cloud::priv::iam::v1::UserAccount> UserAccountData;
-
- virtual grpc::Status Get(grpc::ServerContext*,
- const yandex::cloud::priv::iam::v1::GetUserAccountRequest* request,
- yandex::cloud::priv::iam::v1::UserAccount* response) override {
- TString id = request->user_account_id();
- auto it = UserAccountData.find(id);
- if (it != UserAccountData.end()) {
- response->CopyFrom(it->second);
- return grpc::Status::OK;
- } else {
- return grpc::Status(grpc::StatusCode::NOT_FOUND, "Not Found");
- }
- }
-};
-
+#pragma once
+
+#include <yandex/cloud/priv/iam/v1/user_account_service.grpc.pb.h>
+
+class TUserAccountServiceMock : public yandex::cloud::priv::iam::v1::UserAccountService::Service {
+public:
+ THashMap<TString, yandex::cloud::priv::iam::v1::UserAccount> UserAccountData;
+
+ virtual grpc::Status Get(grpc::ServerContext*,
+ const yandex::cloud::priv::iam::v1::GetUserAccountRequest* request,
+ yandex::cloud::priv::iam::v1::UserAccount* response) override {
+ TString id = request->user_account_id();
+ auto it = UserAccountData.find(id);
+ if (it != UserAccountData.end()) {
+ response->CopyFrom(it->second);
+ return grpc::Status::OK;
+ } else {
+ return grpc::Status(grpc::StatusCode::NOT_FOUND, "Not Found");
+ }
+ }
+};
+
diff --git a/ydb/core/testlib/tablet_flat_dummy.cpp b/ydb/core/testlib/tablet_flat_dummy.cpp
index 4d08093cdf3..1a9dca04a52 100644
--- a/ydb/core/testlib/tablet_flat_dummy.cpp
+++ b/ydb/core/testlib/tablet_flat_dummy.cpp
@@ -12,7 +12,7 @@ namespace {
class TDummyFlatTablet : public TActor<TDummyFlatTablet>, public NTabletFlatExecutor::TTabletExecutedFlat {
- struct Schema : NIceDb::Schema {
+ struct Schema : NIceDb::Schema {
struct Snaps : Table<1> {
struct SourceTableId : Column<1, NScheme::NTypeIds::Uint32> {};
struct DestinationTablet : Column<2, NScheme::NTypeIds::Uint64> {};
@@ -52,7 +52,7 @@ class TDummyFlatTablet : public TActor<TDummyFlatTablet>, public NTabletFlatExec
bool Execute(TTransactionContext &txc, const TActorContext &ctx) override {
Y_UNUSED(ctx);
- NIceDb::TNiceDb(txc.DB).Materialize<Schema>();
+ NIceDb::TNiceDb(txc.DB).Materialize<Schema>();
return true;
}
diff --git a/ydb/core/testlib/tablet_helpers.cpp b/ydb/core/testlib/tablet_helpers.cpp
index 023b8eafe60..a853040b932 100644
--- a/ydb/core/testlib/tablet_helpers.cpp
+++ b/ydb/core/testlib/tablet_helpers.cpp
@@ -46,7 +46,7 @@
#include <ydb/core/testlib/basics/storage.h>
#include <ydb/core/testlib/basics/appdata.h>
-
+
const bool SUPPRESS_REBOOTS = false;
const bool ENABLE_REBOOT_DISPATCH_LOG = true;
const bool TRACE_DELAY_TIMING = true;
@@ -619,9 +619,9 @@ namespace NKikimr {
void SetupTabletServices(TTestActorRuntime &runtime, TAppPrepare *app, bool mockDisk, NFake::TStorage storage,
NFake::TCaches caches) {
TAutoPtr<TAppPrepare> dummy;
- if (app == nullptr) {
- dummy = app = new TAppPrepare;
- }
+ if (app == nullptr) {
+ dummy = app = new TAppPrepare;
+ }
TUltimateNodes nodes(runtime, app);
SetupBasicServices(runtime, *app, mockDisk, &nodes, storage, caches);
}
@@ -630,15 +630,15 @@ namespace NKikimr {
TDomainsInfo::TDomain::TStoragePoolKinds storagePoolKinds;
for (ui32 poolNum = 1; poolNum <= count; ++poolNum) {
- TString poolKind = "pool-kind-" + ToString(poolNum);
- NKikimrBlobStorage::TDefineStoragePool& hddPool = storagePoolKinds[poolKind];
+ TString poolKind = "pool-kind-" + ToString(poolNum);
+ NKikimrBlobStorage::TDefineStoragePool& hddPool = storagePoolKinds[poolKind];
hddPool.SetBoxId(1);
hddPool.SetErasureSpecies("none");
hddPool.SetVDiskKind("Default");
hddPool.AddPDiskFilter()->AddProperty()->SetType(NKikimrBlobStorage::ROT);
hddPool.SetKind(poolKind);
- hddPool.SetStoragePoolId(poolNum);
- hddPool.SetName("pool-" + ToString(poolNum));
+ hddPool.SetStoragePoolId(poolNum);
+ hddPool.SetName("pool-" + ToString(poolNum));
}
return storagePoolKinds;
@@ -656,7 +656,7 @@ namespace NKikimr {
return prev;
}
- void SetupChannelProfiles(TAppPrepare &app, ui32 domainId, ui32 nchannels) {
+ void SetupChannelProfiles(TAppPrepare &app, ui32 domainId, ui32 nchannels) {
Y_VERIFY(app.Domains && app.Domains->Domains.contains(domainId));
auto& poolKinds = app.Domains->GetDomain(domainId).StoragePoolTypes;
Y_VERIFY(!poolKinds.empty());
@@ -667,7 +667,7 @@ namespace NKikimr {
channelProfiles->Profiles.emplace_back();
auto& profile = channelProfiles->Profiles.back();
for (ui32 channelIdx = 0; channelIdx < nchannels; ++channelIdx) {
- profile.Channels.emplace_back(TBlobStorageGroupType::ErasureNone, 0, NKikimrBlobStorage::TVDiskKind::Default, poolKinds.begin()->first);
+ profile.Channels.emplace_back(TBlobStorageGroupType::ErasureNone, 0, NKikimrBlobStorage::TVDiskKind::Default, poolKinds.begin()->first);
}
}
@@ -705,7 +705,7 @@ namespace NKikimr {
void SetupBoxAndStoragePool(TTestActorRuntime &runtime, const TActorId& sender, ui32 domainId, ui32 nGroups) {
NTabletPipe::TClientConfig pipeConfig;
- pipeConfig.RetryPolicy = NTabletPipe::TClientRetryPolicy::WithRetries();
+ pipeConfig.RetryPolicy = NTabletPipe::TClientRetryPolicy::WithRetries();
//get NodesInfo, nodes hostname and port are interested
runtime.Send(new IEventHandle(GetNameserviceActorId(), sender, new TEvInterconnect::TEvListNodes));
@@ -733,13 +733,13 @@ namespace NKikimr {
host.SetHostConfigId(hostConfig.GetHostConfigId());
bsConfigureRequest->Record.MutableRequest()->AddCommand()->MutableDefineBox()->CopyFrom(boxConfig);
- for (const auto& [kind, pool] : runtime.GetAppData().DomainsInfo->Domains[domainId]->StoragePoolTypes) {
- NKikimrBlobStorage::TDefineStoragePool storagePool(pool);
- storagePool.SetNumGroups(nGroups);
- bsConfigureRequest->Record.MutableRequest()->AddCommand()->MutableDefineStoragePool()->CopyFrom(storagePool);
- }
+ for (const auto& [kind, pool] : runtime.GetAppData().DomainsInfo->Domains[domainId]->StoragePoolTypes) {
+ NKikimrBlobStorage::TDefineStoragePool storagePool(pool);
+ storagePool.SetNumGroups(nGroups);
+ bsConfigureRequest->Record.MutableRequest()->AddCommand()->MutableDefineStoragePool()->CopyFrom(storagePool);
+ }
- runtime.SendToPipe(MakeBSControllerID(domainId), sender, bsConfigureRequest.Release(), 0, GetPipeConfigWithRetries());
+ runtime.SendToPipe(MakeBSControllerID(domainId), sender, bsConfigureRequest.Release(), 0, GetPipeConfigWithRetries());
TAutoPtr<IEventHandle> handleConfigureResponse;
auto configureResponse = runtime.GrabEdgeEventRethrow<TEvBlobStorage::TEvControllerConfigResponse>(handleConfigureResponse);
@@ -1063,12 +1063,12 @@ namespace NKikimr {
};
NTabletPipe::TClientConfig GetPipeConfigWithRetriesAndFollowers() { // with blackjack and hookers... (c)
- NTabletPipe::TClientConfig pipeConfig;
- pipeConfig.RetryPolicy = NTabletPipe::TClientRetryPolicy::WithRetries();
+ NTabletPipe::TClientConfig pipeConfig;
+ pipeConfig.RetryPolicy = NTabletPipe::TClientRetryPolicy::WithRetries();
pipeConfig.AllowFollower = true;
- return pipeConfig;
- }
-
+ return pipeConfig;
+ }
+
void WaitScheduledEvents(TTestActorRuntime &runtime, TDuration delay, const TActorId &sender, ui32 nodeIndex) {
runtime.Schedule(new IEventHandle(sender, sender, new TEvents::TEvWakeup()), delay, nodeIndex);
TAutoPtr<IEventHandle> handle;
@@ -1147,10 +1147,10 @@ namespace NKikimr {
}
void Handle(TEvHive::TEvCreateTablet::TPtr& ev, const TActorContext& ctx) {
- Cout << "FAKEHIVE " << TabletID() << " TEvCreateTablet " << ev->Get()->Record.ShortDebugString() << Endl;
+ Cout << "FAKEHIVE " << TabletID() << " TEvCreateTablet " << ev->Get()->Record.ShortDebugString() << Endl;
NKikimrProto::EReplyStatus status = NKikimrProto::OK;
const std::pair<ui64, ui64> key(ev->Get()->Record.GetOwner(), ev->Get()->Record.GetOwnerIdx());
- const auto type = ev->Get()->Record.GetTabletType();
+ const auto type = ev->Get()->Record.GetTabletType();
const auto bootMode = ev->Get()->Record.GetTabletBootMode();
auto it = State->Tablets.find(key);
const auto& defaultTabletTypes = AppData(ctx)->DefaultTabletTypes;
@@ -1178,23 +1178,23 @@ namespace NKikimr {
bootstrapperActorId = Boot(ctx, type, &CreateFlatTxSchemeShard, DataGroupErasure);
} else if (type == defaultTabletTypes.Kesus) {
bootstrapperActorId = Boot(ctx, type, &NKesus::CreateKesusTablet, DataGroupErasure);
- } else if (type == defaultTabletTypes.Hive) {
- TFakeHiveState::TPtr state = State->AllocateSubHive();
+ } else if (type == defaultTabletTypes.Hive) {
+ TFakeHiveState::TPtr state = State->AllocateSubHive();
bootstrapperActorId = Boot(ctx, type, [=](const TActorId& tablet, TTabletStorageInfo* info) {
- return new TFakeHive(tablet, info, state, &TFakeHive::DefaultGetTabletCreationFunc);
- }, DataGroupErasure);
+ return new TFakeHive(tablet, info, state, &TFakeHive::DefaultGetTabletCreationFunc);
+ }, DataGroupErasure);
} else if (type == defaultTabletTypes.SysViewProcessor) {
bootstrapperActorId = Boot(ctx, type, &NSysView::CreateSysViewProcessor, DataGroupErasure);
} else if (type == defaultTabletTypes.SequenceShard) {
bootstrapperActorId = Boot(ctx, type, &NSequenceShard::CreateSequenceShard, DataGroupErasure);
} else if (type == defaultTabletTypes.ReplicationController) {
bootstrapperActorId = Boot(ctx, type, &NReplication::CreateController, DataGroupErasure);
- } else {
+ } else {
status = NKikimrProto::ERROR;
}
if (status == NKikimrProto::OK) {
- ui64 tabletId = State->AllocateTabletId();
+ ui64 tabletId = State->AllocateTabletId();
it = State->Tablets.insert(std::make_pair(key, TTabletInfo(type, tabletId, bootstrapperActorId))).first;
State->TabletIdToOwner[tabletId] = key;
}
@@ -1305,7 +1305,7 @@ namespace NKikimr {
void Handle(TEvHive::TEvDeleteTablet::TPtr &ev, const TActorContext &ctx) {
NKikimrHive::TEvDeleteTablet& rec = ev->Get()->Record;
- Cout << "FAKEHIVE " << TabletID() << " TEvDeleteTablet " << rec.ShortDebugString() << Endl;
+ Cout << "FAKEHIVE " << TabletID() << " TEvDeleteTablet " << rec.ShortDebugString() << Endl;
TVector<ui64> deletedIdx;
for (size_t i = 0; i < rec.ShardLocalIdxSize(); ++i) {
auto id = std::make_pair<ui64, ui64>(rec.GetShardOwnerId(), rec.GetShardLocalIdx(i));
@@ -1317,7 +1317,7 @@ namespace NKikimr {
void Handle(TEvHive::TEvDeleteOwnerTablets::TPtr &ev, const TActorContext &ctx) {
NKikimrHive::TEvDeleteOwnerTablets& rec = ev->Get()->Record;
- Cout << "FAKEHIVE " << TabletID() << " TEvDeleteOwnerTablets " << rec.ShortDebugString() << Endl;
+ Cout << "FAKEHIVE " << TabletID() << " TEvDeleteOwnerTablets " << rec.ShortDebugString() << Endl;
auto ownerId = rec.GetOwner();
TVector<ui64> toDelete;
@@ -1419,9 +1419,9 @@ namespace NKikimr {
tabletInfo.SetTabletID(tabletId);
if (info) {
tabletInfo.SetTabletType(info->Type);
- tabletInfo.SetState(200); // THive::ReadyToWork
+ tabletInfo.SetState(200); // THive::ReadyToWork
- // TODO: fill other fields when needed
+ // TODO: fill other fields when needed
}
}
diff --git a/ydb/core/testlib/tablet_helpers.h b/ydb/core/testlib/tablet_helpers.h
index 40c3ab0fbba..81a7c614aaa 100644
--- a/ydb/core/testlib/tablet_helpers.h
+++ b/ydb/core/testlib/tablet_helpers.h
@@ -30,17 +30,17 @@ namespace NKikimr {
const TString DEFAULT_STORAGE_POOL = "Storage Pool with id: 1";
- static TChannelBind GetDefaultChannelBind(const TString& storagePool = DEFAULT_STORAGE_POOL) {
- TChannelBind bind;
- bind.SetStoragePoolName(storagePool);
- return bind;
- }
-
- const TChannelsBindings DEFAULT_BINDED_CHANNELS = {GetDefaultChannelBind(), GetDefaultChannelBind(), GetDefaultChannelBind()};
+ static TChannelBind GetDefaultChannelBind(const TString& storagePool = DEFAULT_STORAGE_POOL) {
+ TChannelBind bind;
+ bind.SetStoragePoolName(storagePool);
+ return bind;
+ }
+
+ const TChannelsBindings DEFAULT_BINDED_CHANNELS = {GetDefaultChannelBind(), GetDefaultChannelBind(), GetDefaultChannelBind()};
void SetupBoxAndStoragePool(TTestActorRuntime &runtime, const TActorId& sender, ui32 domainId = 0, ui32 nGroups = 1);
- void SetupChannelProfiles(TAppPrepare &app, ui32 domainId = 0, ui32 nchannels = 3);
- TDomainsInfo::TDomain::TStoragePoolKinds DefaultPoolKinds(ui32 count = 1);
-
+ void SetupChannelProfiles(TAppPrepare &app, ui32 domainId = 0, ui32 nchannels = 3);
+ TDomainsInfo::TDomain::TStoragePoolKinds DefaultPoolKinds(ui32 count = 1);
+
i64 SetSplitMergePartCountLimit(TTestActorRuntime* runtime, i64 val);
bool SetAllowServerlessStorageBilling(TTestActorRuntime* runtime, bool isAllow);
@@ -110,7 +110,7 @@ namespace NKikimr {
};
struct TFakeHiveTabletInfo {
- const TTabletTypes::EType Type;
+ const TTabletTypes::EType Type;
const ui64 TabletId;
TActorId BootstrapperActorId;
@@ -131,35 +131,35 @@ namespace NKikimr {
struct TFakeHiveState : TThrRefBase {
TMap<std::pair<ui64, ui64>, TFakeHiveTabletInfo> Tablets;
TMap<ui64, std::pair<ui64, ui64>> TabletIdToOwner;
- TMap<ui64, ui64> TabletIdToHive;
+ TMap<ui64, ui64> TabletIdToHive;
ui64 NextTabletId;
- ui64 NextHiveNextTabletId;
+ ui64 NextHiveNextTabletId;
+
+ static constexpr ui64 TABLETS_PER_CHILD_HIVE = 1000000; // amount of tablet ids we reserve for child hive
- static constexpr ui64 TABLETS_PER_CHILD_HIVE = 1000000; // amount of tablet ids we reserve for child hive
-
typedef TIntrusivePtr<TFakeHiveState> TPtr;
TFakeHiveState()
: NextTabletId(TTestTxConfig::FakeHiveTablets)
- , NextHiveNextTabletId(NextTabletId + TABLETS_PER_CHILD_HIVE)
+ , NextHiveNextTabletId(NextTabletId + TABLETS_PER_CHILD_HIVE)
{}
-
- TPtr AllocateSubHive() {
- if (NextHiveNextTabletId == 0) {
- return nullptr;
- }
- TPtr state = new TFakeHiveState();
- state->NextTabletId = NextHiveNextTabletId;
- state->NextHiveNextTabletId = 0;
- ui64 hiveId = NextTabletId;
- TabletIdToHive[NextHiveNextTabletId] = hiveId;
- NextHiveNextTabletId += TABLETS_PER_CHILD_HIVE;
- return state;
- }
-
- ui64 AllocateTabletId() {
- return NextTabletId++;
- }
+
+ TPtr AllocateSubHive() {
+ if (NextHiveNextTabletId == 0) {
+ return nullptr;
+ }
+ TPtr state = new TFakeHiveState();
+ state->NextTabletId = NextHiveNextTabletId;
+ state->NextHiveNextTabletId = 0;
+ ui64 hiveId = NextTabletId;
+ TabletIdToHive[NextHiveNextTabletId] = hiveId;
+ NextHiveNextTabletId += TABLETS_PER_CHILD_HIVE;
+ return state;
+ }
+
+ ui64 AllocateTabletId() {
+ return NextTabletId++;
+ }
};
typedef std::function<std::function<IActor* (const TActorId &, TTabletStorageInfo*)>(ui32 type)> TGetTabletCreationFunc;
diff --git a/ydb/core/testlib/tenant_runtime.cpp b/ydb/core/testlib/tenant_runtime.cpp
index c63ef61d17c..974cc166d0d 100644
--- a/ydb/core/testlib/tenant_runtime.cpp
+++ b/ydb/core/testlib/tenant_runtime.cpp
@@ -364,7 +364,7 @@ class TFakeHive : public TActor<TFakeHive>, public TTabletExecutedFlat {
void Handle(TEvSchemeShard::TEvDescribeSchemeResult::TPtr &ev, const TActorContext &ctx)
{
- const auto &rec = ev->Get()->GetRecord();
+ const auto &rec = ev->Get()->GetRecord();
UNIT_ASSERT_VALUES_EQUAL(rec.GetStatus(), NKikimrScheme::StatusSuccess);
auto &path = rec.GetPath();
auto shardId = rec.GetPathDescription().GetSelf().GetSchemeshardId();
@@ -429,8 +429,8 @@ class TFakeHive : public TActor<TFakeHive>, public TTabletExecutedFlat {
bootstrapperActorId = Boot(ctx, type, &CreateTxMediator, DataGroupErasure);
} else if (type == defaultTabletTypes.SchemeShard) {
bootstrapperActorId = Boot(ctx, type, &CreateFlatTxSchemeShard, DataGroupErasure);
- } else if (type == defaultTabletTypes.Hive) {
- bootstrapperActorId = Boot(ctx, type, &CreateDefaultHive, DataGroupErasure);
+ } else if (type == defaultTabletTypes.Hive) {
+ bootstrapperActorId = Boot(ctx, type, &CreateDefaultHive, DataGroupErasure);
} else if (type == defaultTabletTypes.SysViewProcessor) {
bootstrapperActorId = Boot(ctx, type, &NSysView::CreateSysViewProcessor, DataGroupErasure);
} else if (type == defaultTabletTypes.SequenceShard) {
@@ -785,8 +785,8 @@ void TTenantTestRuntime::Setup(bool createTenantPools)
SetLogPriority(NKikimrServices::CMS_TENANTS, NLog::PRI_TRACE);
SetLogPriority(NKikimrServices::CONFIGS_DISPATCHER, NLog::PRI_TRACE);
SetLogPriority(NKikimrServices::CONFIGS_CACHE, NLog::PRI_TRACE);
- SetLogPriority(NKikimrServices::HIVE, NLog::PRI_DEBUG);
- SetLogPriority(NKikimrServices::BS_CONTROLLER, NLog::PRI_DEBUG);
+ SetLogPriority(NKikimrServices::HIVE, NLog::PRI_DEBUG);
+ SetLogPriority(NKikimrServices::BS_CONTROLLER, NLog::PRI_DEBUG);
SetLogPriority(NKikimrServices::FLAT_TX_SCHEMESHARD, NLog::PRI_DEBUG);
SetLogPriority(NKikimrServices::TX_PROXY, NLog::PRI_DEBUG);
SetLogPriority(NKikimrServices::TX_PROXY_SCHEME_CACHE, NLog::PRI_DEBUG);
@@ -804,7 +804,7 @@ void TTenantTestRuntime::Setup(bool createTenantPools)
TAppPrepare app;
- app.FeatureFlags = Extension.GetFeatureFlags();
+ app.FeatureFlags = Extension.GetFeatureFlags();
app.ClearDomainsAndHive();
ui32 planResolution = 500;
@@ -843,7 +843,7 @@ void TTenantTestRuntime::Setup(bool createTenantPools)
TActorSetupCmd(new TFakeNodeWhiteboardService, TMailboxType::Simple, 0), i);
}
- SetupChannelProfiles(app);
+ SetupChannelProfiles(app);
SetupBasicServices(*this, app);
if (ENABLE_DETAILED_LOG) {
@@ -901,11 +901,11 @@ void TTenantTestRuntime::Setup(bool createTenantPools)
auto op = transaction->MutableSubDomain();
op->SetName(domain.Name);
- for (const auto& [kind, pool] : GetAppData().DomainsInfo->GetDomain(0).StoragePoolTypes) {
+ for (const auto& [kind, pool] : GetAppData().DomainsInfo->GetDomain(0).StoragePoolTypes) {
auto* p = op->AddStoragePools();
p->SetKind(kind);
p->SetName(pool.GetName());
- }
+ }
SendToPipe(domain.SchemeShardId, Sender, evTx.Release(), 0, GetPipeConfigWithRetries());
@@ -977,7 +977,7 @@ void TTenantTestRuntime::Setup(bool createTenantPools)
NKikimrBlobStorage::TDefineHostConfig hostConfig;
hostConfig.SetHostConfigId(1);
- hostConfig.AddDrive()->SetPath(TStringBuilder() << GetTempDir() << "pdisk_1.dat");
+ hostConfig.AddDrive()->SetPath(TStringBuilder() << GetTempDir() << "pdisk_1.dat");
NKikimrBlobStorage::TDefineBox boxConfig;
boxConfig.SetBoxId(1);
for (const TEvInterconnect::TNodeInfo &node : reply1->Nodes) {
@@ -991,7 +991,7 @@ void TTenantTestRuntime::Setup(bool createTenantPools)
request->Record.MutableRequest()->AddCommand()->MutableDefineBox()->CopyFrom(boxConfig);
NTabletPipe::TClientConfig pipeConfig;
- pipeConfig.RetryPolicy = NTabletPipe::TClientRetryPolicy::WithRetries();
+ pipeConfig.RetryPolicy = NTabletPipe::TClientRetryPolicy::WithRetries();
SendToPipe(MakeBSControllerID(0), Sender, request.Release(), 0, pipeConfig);
auto reply2 = GrabEdgeEventRethrow<TEvBlobStorage::TEvControllerConfigResponse>(handle);
@@ -1124,7 +1124,7 @@ TTenantTestRuntime::TTenantTestRuntime(const TTenantTestConfig &config,
, Config(config)
, Extension(extension)
{
- Extension.MutableFeatureFlags()->SetEnableExternalHive(false);
+ Extension.MutableFeatureFlags()->SetEnableExternalHive(false);
Setup(createTenantPools);
}
diff --git a/ydb/core/testlib/test_client.cpp b/ydb/core/testlib/test_client.cpp
index 84bb3ac49c1..d4907c26f1e 100644
--- a/ydb/core/testlib/test_client.cpp
+++ b/ydb/core/testlib/test_client.cpp
@@ -103,13 +103,13 @@ namespace Tests {
- TServerSettings& TServerSettings::SetDomainName(const TString& value) {
- StoragePoolTypes.erase("test");
- DomainName = value;
- AddStoragePool("test", "/" + DomainName + ":test");
- return *this;
- }
-
+ TServerSettings& TServerSettings::SetDomainName(const TString& value) {
+ StoragePoolTypes.erase("test");
+ DomainName = value;
+ AddStoragePool("test", "/" + DomainName + ":test");
+ return *this;
+ }
+
const char* ServerRedirectEnvVar = "KIKIMR_SERVER";
const char* DomainRedirectEnvVar = "KIKIMR_TEST_DOMAIN";
const TDuration TIMEOUT = NSan::PlainOrUnderSanitizer(
@@ -164,10 +164,10 @@ namespace Tests {
app.SetChangesQueueItemsLimit(Settings->ChangesQueueItemsLimit);
app.SetChangesQueueBytesLimit(Settings->ChangesQueueBytesLimit);
app.CompactionConfig = Settings->CompactionConfig;
- app.FeatureFlags = Settings->FeatureFlags;
+ app.FeatureFlags = Settings->FeatureFlags;
Runtime = MakeHolder<TTestBasicRuntime>(StaticNodes() + DynamicNodes(), Settings->UseRealThreads);
-
+
if (!Settings->UseRealThreads)
Runtime->SetRegistrationObserverFunc([](TTestActorRuntimeBase& runtime, const TActorId&, const TActorId& actorId) {
runtime.EnableScheduleForActor(actorId);
@@ -199,7 +199,7 @@ namespace Tests {
NKikHouse::RegisterFormat(*Settings->Formats);
}
- NKikimr::SetupChannelProfiles(app, Settings->Domain);
+ NKikimr::SetupChannelProfiles(app, Settings->Domain);
Runtime->SetupMonitoring();
Runtime->SetLogBackend(Settings->LogBackend);
@@ -218,7 +218,7 @@ namespace Tests {
Runtime->GetAppData(nodeIdx).StreamingConfig.MergeFrom(Settings->AppConfig.GetGRpcConfig().GetStreamingConfig());
Runtime->GetAppData(nodeIdx).EnforceUserTokenRequirement = Settings->AppConfig.GetDomainsConfig().GetSecurityConfig().GetEnforceUserTokenRequirement();
SetupConfigurators(nodeIdx);
- SetupProxies(nodeIdx);
+ SetupProxies(nodeIdx);
}
}
@@ -241,9 +241,9 @@ namespace Tests {
port
));
}
- }
+ }
}
-
+
void TServer::EnableGRpc(const NGrpc::TServerOptions& options) {
GRpcServer.reset(new NGrpc::TGRpcServer(options));
auto grpcService = new NGRpcProxy::TGRpcService();
@@ -376,51 +376,51 @@ namespace Tests {
void TServer::SetupStorage() {
TActorId sender = Runtime->AllocateEdgeActor();
-
- NTabletPipe::TClientConfig pipeConfig;
- pipeConfig.RetryPolicy = NTabletPipe::TClientRetryPolicy::WithRetries();
-
- //get NodesInfo, nodes hostname and port are interested
+
+ NTabletPipe::TClientConfig pipeConfig;
+ pipeConfig.RetryPolicy = NTabletPipe::TClientRetryPolicy::WithRetries();
+
+ //get NodesInfo, nodes hostname and port are interested
Runtime->Send(new IEventHandle(GetNameserviceActorId(), sender, new TEvInterconnect::TEvListNodes));
- TAutoPtr<IEventHandle> handleNodesInfo;
- auto nodesInfo = Runtime->GrabEdgeEventRethrow<TEvInterconnect::TEvNodesInfo>(handleNodesInfo);
-
+ TAutoPtr<IEventHandle> handleNodesInfo;
+ auto nodesInfo = Runtime->GrabEdgeEventRethrow<TEvInterconnect::TEvNodesInfo>(handleNodesInfo);
+
auto bsConfigureRequest = MakeHolder<TEvBlobStorage::TEvControllerConfigRequest>();
-
- NKikimrBlobStorage::TDefineBox boxConfig;
- boxConfig.SetBoxId(Settings->BOX_ID);
-
- ui32 nodeId = Runtime->GetNodeId(0);
- Y_VERIFY(nodesInfo->Nodes[0].NodeId == nodeId);
- auto& nodeInfo = nodesInfo->Nodes[0];
-
- NKikimrBlobStorage::TDefineHostConfig hostConfig;
- hostConfig.SetHostConfigId(nodeId);
+
+ NKikimrBlobStorage::TDefineBox boxConfig;
+ boxConfig.SetBoxId(Settings->BOX_ID);
+
+ ui32 nodeId = Runtime->GetNodeId(0);
+ Y_VERIFY(nodesInfo->Nodes[0].NodeId == nodeId);
+ auto& nodeInfo = nodesInfo->Nodes[0];
+
+ NKikimrBlobStorage::TDefineHostConfig hostConfig;
+ hostConfig.SetHostConfigId(nodeId);
TString path = TStringBuilder() << Runtime->GetTempDir() << "pdisk_1.dat";
hostConfig.AddDrive()->SetPath(path);
Cerr << "test_client.cpp: SetPath # " << path << Endl;
- bsConfigureRequest->Record.MutableRequest()->AddCommand()->MutableDefineHostConfig()->CopyFrom(hostConfig);
-
- auto& host = *boxConfig.AddHost();
- host.MutableKey()->SetFqdn(nodeInfo.Host);
- host.MutableKey()->SetIcPort(nodeInfo.Port);
- host.SetHostConfigId(hostConfig.GetHostConfigId());
- bsConfigureRequest->Record.MutableRequest()->AddCommand()->MutableDefineBox()->CopyFrom(boxConfig);
-
- for (const auto& [poolKind, storagePool] : Settings->StoragePoolTypes) {
- if (storagePool.GetNumGroups() > 0) {
- bsConfigureRequest->Record.MutableRequest()->AddCommand()->MutableDefineStoragePool()->CopyFrom(storagePool);
- }
- }
-
- Runtime->SendToPipe(MakeBSControllerID(Settings->Domain), sender, bsConfigureRequest.Release(), 0, pipeConfig);
-
- TAutoPtr<IEventHandle> handleConfigureResponse;
- auto configureResponse = Runtime->GrabEdgeEventRethrow<TEvBlobStorage::TEvControllerConfigResponse>(handleConfigureResponse);
- if (!configureResponse->Record.GetResponse().GetSuccess()) {
- Cerr << "\n\n configResponse is #" << configureResponse->Record.DebugString() << "\n\n";
- }
- UNIT_ASSERT(configureResponse->Record.GetResponse().GetSuccess());
+ bsConfigureRequest->Record.MutableRequest()->AddCommand()->MutableDefineHostConfig()->CopyFrom(hostConfig);
+
+ auto& host = *boxConfig.AddHost();
+ host.MutableKey()->SetFqdn(nodeInfo.Host);
+ host.MutableKey()->SetIcPort(nodeInfo.Port);
+ host.SetHostConfigId(hostConfig.GetHostConfigId());
+ bsConfigureRequest->Record.MutableRequest()->AddCommand()->MutableDefineBox()->CopyFrom(boxConfig);
+
+ for (const auto& [poolKind, storagePool] : Settings->StoragePoolTypes) {
+ if (storagePool.GetNumGroups() > 0) {
+ bsConfigureRequest->Record.MutableRequest()->AddCommand()->MutableDefineStoragePool()->CopyFrom(storagePool);
+ }
+ }
+
+ Runtime->SendToPipe(MakeBSControllerID(Settings->Domain), sender, bsConfigureRequest.Release(), 0, pipeConfig);
+
+ TAutoPtr<IEventHandle> handleConfigureResponse;
+ auto configureResponse = Runtime->GrabEdgeEventRethrow<TEvBlobStorage::TEvControllerConfigResponse>(handleConfigureResponse);
+ if (!configureResponse->Record.GetResponse().GetSuccess()) {
+ Cerr << "\n\n configResponse is #" << configureResponse->Record.DebugString() << "\n\n";
+ }
+ UNIT_ASSERT(configureResponse->Record.GetResponse().GetSuccess());
}
void TServer::SetupDefaultProfiles() {
@@ -533,10 +533,10 @@ namespace Tests {
TLocalConfig::TTabletClassInfo(new TTabletSetupInfo(
&CreateFlatTxSchemeShard, TMailboxType::Revolving, appData.UserPoolId,
TMailboxType::Revolving, appData.SystemPoolId));
- localConfig.TabletClassInfo[appData.DefaultTabletTypes.Hive] =
- TLocalConfig::TTabletClassInfo(new TTabletSetupInfo(
- &CreateDefaultHive, TMailboxType::Revolving, appData.UserPoolId,
- TMailboxType::Revolving, appData.SystemPoolId));
+ localConfig.TabletClassInfo[appData.DefaultTabletTypes.Hive] =
+ TLocalConfig::TTabletClassInfo(new TTabletSetupInfo(
+ &CreateDefaultHive, TMailboxType::Revolving, appData.UserPoolId,
+ TMailboxType::Revolving, appData.SystemPoolId));
localConfig.TabletClassInfo[appData.DefaultTabletTypes.SysViewProcessor] =
TLocalConfig::TTabletClassInfo(new TTabletSetupInfo(
&NSysView::CreateSysViewProcessorForTests, TMailboxType::Revolving, appData.UserPoolId,
@@ -583,21 +583,21 @@ namespace Tests {
nodeIdx, appData.SystemPoolId, TMailboxType::Revolving, 0);
}
- void TServer::SetupProxies(ui32 nodeIdx) {
+ void TServer::SetupProxies(ui32 nodeIdx) {
Runtime->SetTxAllocatorTabletIds({ChangeStateStorage(TxAllocator, Settings->Domain)});
{
- IActor* ticketParser = Settings->CreateTicketParser(Settings->AuthConfig);
+ IActor* ticketParser = Settings->CreateTicketParser(Settings->AuthConfig);
TActorId ticketParserId = Runtime->Register(ticketParser, nodeIdx);
Runtime->RegisterService(MakeTicketParserID(), ticketParserId, nodeIdx);
}
{
- IActor* healthCheck = NHealthCheck::CreateHealthCheckService();
- TActorId healthCheckId = Runtime->Register(healthCheck, nodeIdx);
- Runtime->RegisterService(NHealthCheck::MakeHealthCheckID(), healthCheckId, nodeIdx);
- }
-
- {
+ IActor* healthCheck = NHealthCheck::CreateHealthCheckService();
+ TActorId healthCheckId = Runtime->Register(healthCheck, nodeIdx);
+ Runtime->RegisterService(NHealthCheck::MakeHealthCheckID(), healthCheckId, nodeIdx);
+ }
+
+ {
IActor* kqpRmService = NKqp::CreateKqpResourceManagerActor(Settings->AppConfig.GetTableServiceConfig().GetResourceManager(), nullptr);
TActorId kqpRmServiceId = Runtime->Register(kqpRmService, nodeIdx);
Runtime->RegisterService(NKqp::MakeKqpRmServiceID(Runtime->GetNodeId(nodeIdx)), kqpRmServiceId, nodeIdx);
@@ -606,7 +606,7 @@ namespace Tests {
{
IActor* kqpProxyService = NKqp::CreateKqpProxyService(Settings->AppConfig.GetLogConfig(),
Settings->AppConfig.GetTableServiceConfig(),
- TVector<NKikimrKqp::TKqpSetting>(Settings->KqpSettings),
+ TVector<NKikimrKqp::TKqpSetting>(Settings->KqpSettings),
nullptr);
TActorId kqpProxyServiceId = Runtime->Register(kqpProxyService, nodeIdx);
Runtime->RegisterService(NKqp::MakeKqpProxyID(Runtime->GetNodeId(nodeIdx)), kqpProxyServiceId, nodeIdx);
@@ -642,7 +642,7 @@ namespace Tests {
TActorId proxyId = Runtime->Register(proxy, nodeIdx, Runtime->GetAppData(nodeIdx).SystemPoolId, TMailboxType::Revolving, 0);
Runtime->RegisterService(NMsgBusProxy::CreateMsgBusProxyId(), proxyId, nodeIdx);
}
-
+
{
IActor* traceService = BusServer->CreateMessageBusTraceService();
if (traceService) {
@@ -650,7 +650,7 @@ namespace Tests {
Runtime->RegisterService(NMessageBusTracer::MakeMessageBusTraceServiceID(), traceServiceId, nodeIdx);
}
}
- }
+ }
{
auto driverConfig = NYdb::TDriverConfig().SetEndpoint(TStringBuilder() << "localhost:" << Settings->GrpcPort);
@@ -819,7 +819,7 @@ namespace Tests {
NYq::InitTest(Runtime.Get(), port, Settings->GrpcPort, yqSharedResources);
}
}
-
+
void TServer::SetupLogging() {
Runtime->SetLogPriority(NKikimrServices::FLAT_TX_SCHEMESHARD, NLog::PRI_WARN);
//Runtime->SetLogPriority(NKikimrServices::SCHEMESHARD_DESCRIBE, NLog::PRI_DEBUG);
@@ -906,7 +906,7 @@ namespace Tests {
if (SupportsRedirect && Tests::IsServerRedirected()) {
serverSetup = GetServerSetup();
} else {
- serverSetup = TServerSetup("localhost", settings.Port);
+ serverSetup = TServerSetup("localhost", settings.Port);
}
ClientConfig.Ip = serverSetup.IpAddress;
@@ -1016,7 +1016,7 @@ namespace Tests {
auto* p = op->AddStoragePools();
p->SetKind(kind);
p->SetName(pool.GetName());
- }
+ }
TAutoPtr<NBus::TBusMessage> reply;
SendAndWaitCompletion(request, reply);
@@ -1041,35 +1041,35 @@ namespace Tests {
void TClient::ExecuteTraceCommand(NKikimrClient::TMessageBusTraceRequest::ECommand command, const TString &path) {
TAutoPtr<NMsgBusProxy::TBusMessageBusTraceRequest> request(new NMsgBusProxy::TBusMessageBusTraceRequest());
- request->Record.SetCommand(command);
- if (path)
- request->Record.SetPath(path);
- TAutoPtr<NBus::TBusMessage> reply;
- UNIT_ASSERT_VALUES_EQUAL(SyncCall(request, reply), NBus::MESSAGE_OK);
- }
-
+ request->Record.SetCommand(command);
+ if (path)
+ request->Record.SetPath(path);
+ TAutoPtr<NBus::TBusMessage> reply;
+ UNIT_ASSERT_VALUES_EQUAL(SyncCall(request, reply), NBus::MESSAGE_OK);
+ }
+
TString TClient::StartTrace(const TString &path) {
TAutoPtr<NMsgBusProxy::TBusMessageBusTraceRequest> request(new NMsgBusProxy::TBusMessageBusTraceRequest());
request->Record.SetCommand(NKikimrClient::TMessageBusTraceRequest::START);
- if (path)
- request->Record.SetPath(path);
- TAutoPtr<NBus::TBusMessage> reply;
- UNIT_ASSERT_VALUES_EQUAL(SyncCall(request, reply), NBus::MESSAGE_OK);
- if (reply.Get()->GetHeader()->Type == NMsgBusProxy::MTYPE_CLIENT_MESSAGE_BUS_TRACE_STATUS) {
+ if (path)
+ request->Record.SetPath(path);
+ TAutoPtr<NBus::TBusMessage> reply;
+ UNIT_ASSERT_VALUES_EQUAL(SyncCall(request, reply), NBus::MESSAGE_OK);
+ if (reply.Get()->GetHeader()->Type == NMsgBusProxy::MTYPE_CLIENT_MESSAGE_BUS_TRACE_STATUS) {
const NKikimrClient::TMessageBusTraceStatus &response = static_cast<NMsgBusProxy::TBusMessageBusTraceStatus *>(reply.Get())->Record;
- return response.GetPath();
- } else {
- ythrow yexception() << "MessageBus trace not enabled on the server (see mbus/--trace-path option)";
- }
- }
-
- void TClient::StopTrace() {
+ return response.GetPath();
+ } else {
+ ythrow yexception() << "MessageBus trace not enabled on the server (see mbus/--trace-path option)";
+ }
+ }
+
+ void TClient::StopTrace() {
TAutoPtr<NMsgBusProxy::TBusMessageBusTraceRequest> request(new NMsgBusProxy::TBusMessageBusTraceRequest());
request->Record.SetCommand(NKikimrClient::TMessageBusTraceRequest::STOP);
- TAutoPtr<NBus::TBusMessage> reply;
- UNIT_ASSERT_VALUES_EQUAL(SyncCall(request, reply), NBus::MESSAGE_OK);
- }
-
+ TAutoPtr<NBus::TBusMessage> reply;
+ UNIT_ASSERT_VALUES_EQUAL(SyncCall(request, reply), NBus::MESSAGE_OK);
+ }
+
NBus::EMessageStatus TClient::WaitCompletion(ui64 txId, ui64 schemeshard, ui64 pathId,
TAutoPtr<NBus::TBusMessage>& reply,
TDuration timeout)
@@ -1084,19 +1084,19 @@ namespace Tests {
msg->Record.MutableFlatTxId()->SetSchemeShardTabletId(schemeshard);
msg->Record.MutableFlatTxId()->SetPathId(pathId);
msg->Record.MutablePollOptions()->SetTimeout(timeout.MilliSeconds());
-#ifndef NDEBUG
+#ifndef NDEBUG
Cerr << "waiting..." << Endl;
-#endif
+#endif
status = SyncCall(msg, reply);
if (status != NBus::MESSAGE_OK) {
const char *description = NBus::MessageStatusDescription(status);
Cerr << description << Endl;
return status;
}
- if (reply->GetHeader()->Type != NMsgBusProxy::MTYPE_CLIENT_RESPONSE) {
+ if (reply->GetHeader()->Type != NMsgBusProxy::MTYPE_CLIENT_RESPONSE) {
break;
}
- response = &static_cast<NMsgBusProxy::TBusResponse*>(reply.Get())->Record;
+ response = &static_cast<NMsgBusProxy::TBusResponse*>(reply.Get())->Record;
} while (response->GetStatus() == NMsgBusProxy::MSTATUS_INPROGRESS && deadline >= TInstant::Now());
return status;
@@ -1138,9 +1138,9 @@ namespace Tests {
SetApplyIf(*mkDirTx, applyIf);
TAutoPtr<NBus::TBusMessage> reply;
NBus::EMessageStatus msgStatus = SendAndWaitCompletion(request, reply);
-#ifndef NDEBUG
- Cout << PrintResult<NMsgBusProxy::TBusResponse>(reply.Get()) << Endl;
-#endif
+#ifndef NDEBUG
+ Cout << PrintResult<NMsgBusProxy::TBusResponse>(reply.Get()) << Endl;
+#endif
UNIT_ASSERT_VALUES_EQUAL(msgStatus, NBus::MESSAGE_OK);
const NKikimrClient::TResponse &response = dynamic_cast<NMsgBusProxy::TBusResponse *>(reply.Get())->Record;
return (NMsgBusProxy::EResponseStatus)response.GetStatus();
@@ -1599,9 +1599,9 @@ namespace Tests {
auto& descr = record.GetPathDescription().GetSelf();
TAutoPtr<NBus::TBusMessage> reply;
auto msgStatus = WaitCompletion(descr.GetCreateTxId(), descr.GetSchemeshardId(), descr.GetPathId(), reply, timeout);
-#ifndef NDEBUG
+#ifndef NDEBUG
Cout << PrintResult<NMsgBusProxy::TBusResponse>(reply.Get()) << Endl;
-#endif
+#endif
UNIT_ASSERT_VALUES_EQUAL(msgStatus, NBus::MESSAGE_OK);
const NKikimrClient::TResponse &response = dynamic_cast<NMsgBusProxy::TBusResponse *>(reply.Get())->Record;
return (NMsgBusProxy::EResponseStatus)response.GetStatus();
@@ -1614,10 +1614,10 @@ namespace Tests {
TAutoPtr<NBus::TBusMessage> reply;
NBus::EMessageStatus msgStatus = SendWhenReady(request, reply);
UNIT_ASSERT_VALUES_EQUAL(msgStatus, NBus::MESSAGE_OK);
-#ifndef NDEBUG
+#ifndef NDEBUG
Cerr << "TClient::Ls: " << PrintResult<NMsgBusProxy::TBusResponse>(reply.Get()) << Endl;
-#endif
- return dynamic_cast<NMsgBusProxy::TBusResponse*>(reply.Release());
+#endif
+ return dynamic_cast<NMsgBusProxy::TBusResponse*>(reply.Release());
}
TAutoPtr<NMsgBusProxy::TBusResponse> TClient::Ls(const TString& path) {
@@ -1639,24 +1639,24 @@ namespace Tests {
return TPathVersion{self.GetSchemeshardId(), self.GetPathId(), self.GetPathVersion()};
}
- TVector<ui64> TClient::ExtractTableShards(const TAutoPtr<NMsgBusProxy::TBusResponse>& describe) {
- UNIT_ASSERT(describe.Get());
- NKikimrClient::TResponse& record = describe->Record;
- UNIT_ASSERT_VALUES_EQUAL(record.GetStatus(), NMsgBusProxy::MSTATUS_OK);
+ TVector<ui64> TClient::ExtractTableShards(const TAutoPtr<NMsgBusProxy::TBusResponse>& describe) {
+ UNIT_ASSERT(describe.Get());
+ NKikimrClient::TResponse& record = describe->Record;
+ UNIT_ASSERT_VALUES_EQUAL(record.GetStatus(), NMsgBusProxy::MSTATUS_OK);
UNIT_ASSERT_VALUES_EQUAL(record.GetSchemeStatus(), NKikimrScheme::StatusSuccess);
-
- UNIT_ASSERT(record.HasPathDescription());
- auto& descr = record.GetPathDescription();
- UNIT_ASSERT(descr.TablePartitionsSize() > 0);
- auto& parts = descr.GetTablePartitions();
-
- TVector<ui64> shards;
- for (const auto& part : parts) {
- shards.emplace_back(part.GetDatashardId());
- }
- return shards;
- }
-
+
+ UNIT_ASSERT(record.HasPathDescription());
+ auto& descr = record.GetPathDescription();
+ UNIT_ASSERT(descr.TablePartitionsSize() > 0);
+ auto& parts = descr.GetTablePartitions();
+
+ TVector<ui64> shards;
+ for (const auto& part : parts) {
+ shards.emplace_back(part.GetDatashardId());
+ }
+ return shards;
+ }
+
void TClient::RefreshPathCache(TTestActorRuntime* runtime, const TString& path, ui32 nodeIdx) {
TActorId sender = runtime->AllocateEdgeActor(nodeIdx);
auto request = MakeHolder<NSchemeCache::TSchemeCacheNavigate>();
@@ -1687,17 +1687,17 @@ namespace Tests {
void TClient::ModifyACL(const TString& parent, const TString& name, const TString& acl) {
TAutoPtr<NMsgBusProxy::TBusSchemeOperation> request(new NMsgBusProxy::TBusSchemeOperation());
- auto *op = request->Record.MutableTransaction()->MutableModifyScheme();
+ auto *op = request->Record.MutableTransaction()->MutableModifyScheme();
op->SetOperationType(NKikimrSchemeOp::EOperationType::ESchemeOpModifyACL);
- op->SetWorkingDir(parent);
- op->MutableModifyACL()->SetName(name);
- op->MutableModifyACL()->SetDiffACL(acl);
- TAutoPtr<NBus::TBusMessage> reply;
- NBus::EMessageStatus status = SendAndWaitCompletion(request.Release(), reply);
- UNIT_ASSERT_VALUES_EQUAL(status, NBus::MESSAGE_OK);
- }
-
- TAutoPtr<NMsgBusProxy::TBusResponse> TClient::HiveCreateTablet(ui32 domainUid, ui64 owner, ui64 owner_index, TTabletTypes::EType tablet_type,
+ op->SetWorkingDir(parent);
+ op->MutableModifyACL()->SetName(name);
+ op->MutableModifyACL()->SetDiffACL(acl);
+ TAutoPtr<NBus::TBusMessage> reply;
+ NBus::EMessageStatus status = SendAndWaitCompletion(request.Release(), reply);
+ UNIT_ASSERT_VALUES_EQUAL(status, NBus::MESSAGE_OK);
+ }
+
+ TAutoPtr<NMsgBusProxy::TBusResponse> TClient::HiveCreateTablet(ui32 domainUid, ui64 owner, ui64 owner_index, TTabletTypes::EType tablet_type,
const TVector<ui32>& allowed_node_ids,
const TVector<TSubDomainKey>& allowed_domains,
const TChannelsBindings& bindings)
@@ -1715,16 +1715,16 @@ namespace Tests {
for (auto& domain_id: allowed_domains) {
*cmdCreate->AddAllowedDomains() = domain_id;
}
- if (!bindings.empty()) {
- for (auto& binding: bindings) {
- *cmdCreate->AddBindedChannels() = binding;
- }
- } else {
- UNIT_ASSERT(!StoragePoolTypes.empty());
- TString storagePool = StoragePoolTypes.begin()->second.GetName();
- cmdCreate->AddBindedChannels()->SetStoragePoolName(storagePool); // 0
- cmdCreate->AddBindedChannels()->SetStoragePoolName(storagePool); // 1
- cmdCreate->AddBindedChannels()->SetStoragePoolName(storagePool); // 2
+ if (!bindings.empty()) {
+ for (auto& binding: bindings) {
+ *cmdCreate->AddBindedChannels() = binding;
+ }
+ } else {
+ UNIT_ASSERT(!StoragePoolTypes.empty());
+ TString storagePool = StoragePoolTypes.begin()->second.GetName();
+ cmdCreate->AddBindedChannels()->SetStoragePoolName(storagePool); // 0
+ cmdCreate->AddBindedChannels()->SetStoragePoolName(storagePool); // 1
+ cmdCreate->AddBindedChannels()->SetStoragePoolName(storagePool); // 2
}
TAutoPtr<NBus::TBusMessage> reply;
NBus::EMessageStatus status = SyncCall(request, reply);
@@ -1764,15 +1764,15 @@ namespace Tests {
TAutoPtr<NMsgBusProxy::TBusBlobStorageConfigRequest> readRequest(new NMsgBusProxy::TBusBlobStorageConfigRequest());
readRequest->Record.SetDomain(Domain);
auto readParam = readRequest->Record.MutableRequest()->AddCommand()->MutableReadStoragePool();
- readParam->SetBoxId(TServerSettings::BOX_ID);
+ readParam->SetBoxId(TServerSettings::BOX_ID);
readParam->AddName(name);
TAutoPtr<NBus::TBusMessage> reply;
NBus::EMessageStatus msgStatus = SendWhenReady(readRequest, reply);
-#ifndef NDEBUG
- Cerr << PrintResult<NMsgBusProxy::TBusResponse>(reply.Get()) << Endl;
-#endif
+#ifndef NDEBUG
+ Cerr << PrintResult<NMsgBusProxy::TBusResponse>(reply.Get()) << Endl;
+#endif
UNIT_ASSERT_VALUES_EQUAL(msgStatus, NBus::MESSAGE_OK);
const NKikimrClient::TResponse &response = dynamic_cast<NMsgBusProxy::TBusResponse *>(reply.Get())->Record;
UNIT_ASSERT(response.HasBlobStorageConfigResponse() && response.GetBlobStorageConfigResponse().GetSuccess());
@@ -1783,7 +1783,7 @@ namespace Tests {
auto storagePool = status.GetStoragePool(0);
UNIT_ASSERT(name == storagePool.GetName());
- UNIT_ASSERT(TServerSettings::BOX_ID == storagePool.GetBoxId());
+ UNIT_ASSERT(TServerSettings::BOX_ID == storagePool.GetBoxId());
return storagePool;
}
@@ -1794,16 +1794,16 @@ namespace Tests {
TAutoPtr<NMsgBusProxy::TBusBlobStorageConfigRequest> deleteRequest(new NMsgBusProxy::TBusBlobStorageConfigRequest());
deleteRequest->Record.SetDomain(Domain);
auto deleteParam = deleteRequest->Record.MutableRequest()->AddCommand()->MutableDeleteStoragePool();
- deleteParam->SetBoxId(TServerSettings::BOX_ID);
+ deleteParam->SetBoxId(TServerSettings::BOX_ID);
deleteParam->SetStoragePoolId(storagePool.GetStoragePoolId());
deleteParam->SetItemConfigGeneration(storagePool.GetItemConfigGeneration());
TAutoPtr<NBus::TBusMessage> replyDelete;
NBus::EMessageStatus msgStatus = SendWhenReady(deleteRequest, replyDelete);
-#ifndef NDEBUG
+#ifndef NDEBUG
Cout << PrintResult<NMsgBusProxy::TBusResponse>(replyDelete.Get()) << Endl;
-#endif
+#endif
UNIT_ASSERT_VALUES_EQUAL(msgStatus, NBus::MESSAGE_OK);
const NKikimrClient::TResponse &responseDelete = dynamic_cast<NMsgBusProxy::TBusResponse *>(replyDelete.Get())->Record;
UNIT_ASSERT(responseDelete.HasBlobStorageConfigResponse() && responseDelete.GetBlobStorageConfigResponse().GetSuccess());
@@ -1880,7 +1880,7 @@ namespace Tests {
TStringStream err;
issues.PrintTo(err);
Cerr << "error: " << err.Str() << Endl;
-
+
return false;
}
@@ -1924,7 +1924,7 @@ namespace Tests {
return response.GetStatus();
}
- bool TClient::FlatQuery(const TString &query, TFlatQueryOptions& opts, NKikimrMiniKQL::TResult &result, const NKikimrClient::TResponse& expectedResponse) {
+ bool TClient::FlatQuery(const TString &query, TFlatQueryOptions& opts, NKikimrMiniKQL::TResult &result, const NKikimrClient::TResponse& expectedResponse) {
NKikimrClient::TResponse response;
FlatQueryRaw(query, opts, response);
@@ -1937,9 +1937,9 @@ namespace Tests {
if (response.HasProxyErrorCode()) {
if (response.GetProxyErrorCode() != TEvTxUserProxy::TResultStatus::ExecComplete)
Cerr << "proxy error code: " << static_cast<TEvTxUserProxy::TResultStatus::EStatus>(response.GetProxyErrorCode()) << Endl;
- if (expectedResponse.HasProxyErrorCode()) {
- UNIT_ASSERT_VALUES_EQUAL(response.GetProxyErrorCode(), expectedResponse.GetProxyErrorCode());
- }
+ if (expectedResponse.HasProxyErrorCode()) {
+ UNIT_ASSERT_VALUES_EQUAL(response.GetProxyErrorCode(), expectedResponse.GetProxyErrorCode());
+ }
}
if (response.HasProxyErrors()) {
Cerr << "proxy errors: " << response.GetProxyErrors() << Endl;
@@ -1970,10 +1970,10 @@ namespace Tests {
Cerr << "had follower reads" << Endl;
}
- if (expectedResponse.HasStatus()) {
- UNIT_ASSERT_VALUES_EQUAL(response.GetStatus(), expectedResponse.GetStatus());
- }
- if (expectedResponse.GetStatus() != NMsgBusProxy::MSTATUS_OK)
+ if (expectedResponse.HasStatus()) {
+ UNIT_ASSERT_VALUES_EQUAL(response.GetStatus(), expectedResponse.GetStatus());
+ }
+ if (expectedResponse.GetStatus() != NMsgBusProxy::MSTATUS_OK)
return false;
UNIT_ASSERT(response.HasTxId());
@@ -1987,12 +1987,12 @@ namespace Tests {
return response.GetExecutionEngineResponseStatus() == ui32(NMiniKQL::IEngineFlat::EStatus::Complete);
}
- bool TClient::FlatQuery(const TString &query, TFlatQueryOptions& opts, NKikimrMiniKQL::TResult &result, ui32 expectedStatus) {
- NKikimrClient::TResponse expectedResponse;
- expectedResponse.SetStatus(expectedStatus);
- return FlatQuery(query, opts, result, expectedResponse);
- }
-
+ bool TClient::FlatQuery(const TString &query, TFlatQueryOptions& opts, NKikimrMiniKQL::TResult &result, ui32 expectedStatus) {
+ NKikimrClient::TResponse expectedResponse;
+ expectedResponse.SetStatus(expectedStatus);
+ return FlatQuery(query, opts, result, expectedResponse);
+ }
+
bool TClient::FlatQueryParams(const TString& mkql, const TString& params, bool queryCompiled, NKikimrMiniKQL::TResult &result) {
TFlatQueryOptions opts;
opts.Params = params;
@@ -2012,9 +2012,9 @@ namespace Tests {
// Timeout for DEBUG purposes only
runtime->GrabEdgeEvent<NMon::TEvRemoteJsonInfoRes>(handle);
TString res = handle->Get<NMon::TEvRemoteJsonInfoRes>()->Json;
-#ifndef NDEBUG
+#ifndef NDEBUG
Cerr << res << Endl;
-#endif
+#endif
return res;
}
@@ -2043,7 +2043,7 @@ namespace Tests {
NTabletPipe::TClientConfig clientConfig;
clientConfig.AllowFollower = !leader;
clientConfig.ForceFollower = !leader;
- clientConfig.RetryPolicy = NTabletPipe::TClientRetryPolicy::WithRetries();
+ clientConfig.RetryPolicy = NTabletPipe::TClientRetryPolicy::WithRetries();
TActorId pipeClient = runtime->Register(NTabletPipe::CreateClient(edge, tabletId, clientConfig));
TAutoPtr<IEventHandle> handle;
const TInstant deadline = TInstant::Now() + timeout;
@@ -2071,12 +2071,12 @@ namespace Tests {
NTabletPipe::TClientConfig clientConfig;
clientConfig.AllowFollower = !leader;
clientConfig.ForceFollower = !leader;
- clientConfig.RetryPolicy = {
- .RetryLimitCount = 5,
- .MinRetryTime = TDuration::MilliSeconds(500),
- .MaxRetryTime = TDuration::Seconds(1),
- .BackoffMultiplier = 2,
- };
+ clientConfig.RetryPolicy = {
+ .RetryLimitCount = 5,
+ .MinRetryTime = TDuration::MilliSeconds(500),
+ .MaxRetryTime = TDuration::Seconds(1),
+ .BackoffMultiplier = 2,
+ };
TActorId pipeClient = runtime->Register(NTabletPipe::CreateClient(edge, tabletId, clientConfig));
TInstant deadline = TInstant::Now() + timeout;
@@ -2145,7 +2145,7 @@ namespace Tests {
for (const NKikimrHive::TTabletInfo& tablet : res.GetTablets()) {
if (tablet.GetTabletID() == tabletId) {
- return evenInDeleting || tablet.GetState() != (ui32)NHive::ETabletState::Deleting;
+ return evenInDeleting || tablet.GetState() != (ui32)NHive::ETabletState::Deleting;
}
}
@@ -2162,9 +2162,9 @@ namespace Tests {
TEvHive::TEvGetTabletStorageInfoResult* response = runtime->GrabEdgeEventRethrow<TEvHive::TEvGetTabletStorageInfoResult>(handle);
res.Swap(&response->Record);
-#ifndef NDEBUG
+#ifndef NDEBUG
Cerr << response->Record.DebugString() << "\n";
-#endif
+#endif
if (res.GetStatus() == NKikimrProto::OK) {
auto& info = res.GetInfo();
@@ -2347,13 +2347,13 @@ namespace Tests {
bool TTenants::IsActive(const TString &name, ui32 nodeIdx) const {
const TVector<ui32>& nodes = List(name);
-#ifndef NDEBUG
+#ifndef NDEBUG
Cerr << "IsActive: " << name << " -- " << nodeIdx << Endl;
for (auto& x: nodes) {
Cerr << " -- " << x;
}
Cerr << Endl;
-#endif
+#endif
return std::find(nodes.begin(), nodes.end(), nodeIdx) != nodes.end();
}
@@ -2440,37 +2440,37 @@ namespace Tests {
PushHeap(VacantNodes.begin(), VacantNodes.end());
}
- TServerSettings& TServerSettings::AddStoragePool(const TString& poolKind, const TString& poolName, ui32 numGroups, ui32 encryptionMode) {
- NKikimrBlobStorage::TDefineStoragePool& hddPool = StoragePoolTypes[poolKind];
- hddPool.SetBoxId(BOX_ID);
- hddPool.SetStoragePoolId(POOL_ID++);
- hddPool.SetErasureSpecies("none");
- hddPool.SetVDiskKind("Default");
- hddPool.AddPDiskFilter()->AddProperty()->SetType(NKikimrBlobStorage::ROT);
- hddPool.SetKind(poolKind);
- if (poolName) {
- hddPool.SetName(poolName);
- } else {
- hddPool.SetName(poolKind);
- }
- if (encryptionMode) {
- hddPool.SetEncryptionMode(encryptionMode);
- }
- hddPool.SetNumGroups(numGroups);
- return *this;
- }
-
- TServerSettings& TServerSettings::AddStoragePoolType(const TString& poolKind, ui32 encryptionMode) {
+ TServerSettings& TServerSettings::AddStoragePool(const TString& poolKind, const TString& poolName, ui32 numGroups, ui32 encryptionMode) {
+ NKikimrBlobStorage::TDefineStoragePool& hddPool = StoragePoolTypes[poolKind];
+ hddPool.SetBoxId(BOX_ID);
+ hddPool.SetStoragePoolId(POOL_ID++);
+ hddPool.SetErasureSpecies("none");
+ hddPool.SetVDiskKind("Default");
+ hddPool.AddPDiskFilter()->AddProperty()->SetType(NKikimrBlobStorage::ROT);
+ hddPool.SetKind(poolKind);
+ if (poolName) {
+ hddPool.SetName(poolName);
+ } else {
+ hddPool.SetName(poolKind);
+ }
+ if (encryptionMode) {
+ hddPool.SetEncryptionMode(encryptionMode);
+ }
+ hddPool.SetNumGroups(numGroups);
+ return *this;
+ }
+
+ TServerSettings& TServerSettings::AddStoragePoolType(const TString& poolKind, ui32 encryptionMode) {
NKikimrBlobStorage::TDefineStoragePool hddPool;
- hddPool.SetBoxId(BOX_ID);
- hddPool.SetStoragePoolId(POOL_ID++);
+ hddPool.SetBoxId(BOX_ID);
+ hddPool.SetStoragePoolId(POOL_ID++);
hddPool.SetErasureSpecies("none");
hddPool.SetVDiskKind("Default");
hddPool.AddPDiskFilter()->AddProperty()->SetType(NKikimrBlobStorage::ROT);
hddPool.SetKind(poolKind);
- if (encryptionMode) {
- hddPool.SetEncryptionMode(encryptionMode);
- }
+ if (encryptionMode) {
+ hddPool.SetEncryptionMode(encryptionMode);
+ }
StoragePoolTypes[poolKind] = hddPool;
return *this;
}
diff --git a/ydb/core/testlib/test_client.h b/ydb/core/testlib/test_client.h
index 518dd215b2b..2064752ab45 100644
--- a/ydb/core/testlib/test_client.h
+++ b/ydb/core/testlib/test_client.h
@@ -77,9 +77,9 @@ namespace Tests {
struct TServerSettings: public TThrRefBase, public TTestFeatureFlagsHolder<TServerSettings> {
- static constexpr ui64 BOX_ID = 999;
- ui64 POOL_ID = 1;
-
+ static constexpr ui64 BOX_ID = 999;
+ ui64 POOL_ID = 1;
+
using TPtr = TIntrusivePtr<TServerSettings>;
using TConstPtr = TIntrusiveConstPtr<TServerSettings>;
@@ -89,7 +89,7 @@ namespace Tests {
ui16 Port;
ui16 GrpcPort = 0;
- NKikimrProto::TAuthConfig AuthConfig;
+ NKikimrProto::TAuthConfig AuthConfig;
NKikimrPQ::TPQConfig PQConfig;
NKikimrPQ::TPQClusterDiscoveryConfig PQClusterDiscoveryConfig;
NKikimrNetClassifier::TNetClassifierConfig NetClassifierConfig;
@@ -125,14 +125,14 @@ namespace Tests {
bool EnableMetering = false;
TString MeteringFilePath;
- std::function<IActor*(const NKikimrProto::TAuthConfig&)> CreateTicketParser = NKikimr::CreateTicketParser;
+ std::function<IActor*(const NKikimrProto::TAuthConfig&)> CreateTicketParser = NKikimr::CreateTicketParser;
std::shared_ptr<TGrpcServiceFactory> GrpcServiceFactory;
-
+
TServerSettings& SetGrpcPort(ui16 value) { GrpcPort = value; return *this; }
TServerSettings& SetSupportsRedirect(bool value) { SupportsRedirect = value; return *this; }
TServerSettings& SetTracePath(const TString& value) { TracePath = value; return *this; }
TServerSettings& SetDomain(ui32 value) { Domain = value; return *this; }
- TServerSettings& SetDomainName(const TString& value);
+ TServerSettings& SetDomainName(const TString& value);
TServerSettings& SetNodeCount(ui32 value) { NodeCount = value; return *this; }
TServerSettings& SetDynamicNodeCount(ui32 value) { DynamicNodeCount = value; return *this; }
TServerSettings& SetCustomDiskParams(const NFake::TStorage& value) { CustomDiskParams = value; return *this; }
@@ -141,8 +141,8 @@ namespace Tests {
TServerSettings& SetEnableMockOnSingleNode(bool value) { EnableMockOnSingleNode = value; return *this; }
TServerSettings& SetLogBackend(TAutoPtr<TLogBackend> value) { LogBackend = value; return *this; }
TServerSettings& SetLoggerInitializer(TLoggerInitializer value) { LoggerInitializer = std::move(value); return *this; }
- TServerSettings& AddStoragePoolType(const TString& poolKind, ui32 encryptionMode = 0);
- TServerSettings& AddStoragePool(const TString& poolKind, const TString& poolName = {}, ui32 numGroups = 1, ui32 encryptionMode = 0);
+ TServerSettings& AddStoragePoolType(const TString& poolKind, ui32 encryptionMode = 0);
+ TServerSettings& AddStoragePool(const TString& poolKind, const TString& poolName = {}, ui32 numGroups = 1, ui32 encryptionMode = 0);
TServerSettings& SetKqpSettings(const TVector<NKikimrKqp::TKqpSetting>& settings) { KqpSettings = settings; return *this; }
TServerSettings& SetEnableConsole(bool value) { EnableConsole = value; return *this; }
TServerSettings& SetEnableConfigsDispatcher(bool value) { EnableConfigsDispatcher = value; return *this; }
@@ -179,13 +179,13 @@ namespace Tests {
return *this;
}
- explicit TServerSettings(ui16 port, const NKikimrProto::TAuthConfig authConfig = {}, const NKikimrPQ::TPQConfig pqConfig = {})
+ explicit TServerSettings(ui16 port, const NKikimrProto::TAuthConfig authConfig = {}, const NKikimrPQ::TPQConfig pqConfig = {})
: Port(port)
, AuthConfig(authConfig)
, PQConfig(pqConfig)
- {
- AddStoragePool("test", "/" + DomainName + ":test");
- }
+ {
+ AddStoragePool("test", "/" + DomainName + ":test");
+ }
TServerSettings(const TServerSettings& settings) = default;
};
@@ -201,7 +201,7 @@ namespace Tests {
void SetupDomainLocalService(ui32 nodeIdx);
void SetupLocalService(ui32 nodeIdx, const TString &domainName);
void SetupConfigurators(ui32 nodeIdx);
- void SetupProxies(ui32 nodeIdx);
+ void SetupProxies(ui32 nodeIdx);
void SetupLogging();
void Initialize();
@@ -286,38 +286,38 @@ namespace Tests {
const NMiniKQL::IFunctionRegistry& GetFunctionRegistry() const;
template <typename T>
- void PrepareRequest(TAutoPtr<T>&) {}
-
- void PrepareRequest(TAutoPtr<NMsgBusProxy::TBusRequest>& request) {
- if (!SecurityToken.empty())
- request->Record.SetSecurityToken(SecurityToken);
- }
-
- void PrepareRequest(TAutoPtr<NMsgBusProxy::TBusPersQueue>& request) {
- if (!SecurityToken.empty())
- request->Record.SetSecurityToken(SecurityToken);
- }
-
+ void PrepareRequest(TAutoPtr<T>&) {}
+
+ void PrepareRequest(TAutoPtr<NMsgBusProxy::TBusRequest>& request) {
+ if (!SecurityToken.empty())
+ request->Record.SetSecurityToken(SecurityToken);
+ }
+
+ void PrepareRequest(TAutoPtr<NMsgBusProxy::TBusPersQueue>& request) {
+ if (!SecurityToken.empty())
+ request->Record.SetSecurityToken(SecurityToken);
+ }
+
void PrepareRequest(TAutoPtr<NMsgBusProxy::TBusSchemeOperation>& request) {
- if (!SecurityToken.empty())
- request->Record.SetSecurityToken(SecurityToken);
- }
-
- void PrepareRequest(TAutoPtr<NMsgBusProxy::TBusSchemeInitRoot>& request) {
- if (!SecurityToken.empty())
- request->Record.SetSecurityToken(SecurityToken);
- }
-
- void PrepareRequest(TAutoPtr<NMsgBusProxy::TBusSchemeDescribe>& request) {
- if (!SecurityToken.empty())
- request->Record.SetSecurityToken(SecurityToken);
- }
-
- template <typename T>
+ if (!SecurityToken.empty())
+ request->Record.SetSecurityToken(SecurityToken);
+ }
+
+ void PrepareRequest(TAutoPtr<NMsgBusProxy::TBusSchemeInitRoot>& request) {
+ if (!SecurityToken.empty())
+ request->Record.SetSecurityToken(SecurityToken);
+ }
+
+ void PrepareRequest(TAutoPtr<NMsgBusProxy::TBusSchemeDescribe>& request) {
+ if (!SecurityToken.empty())
+ request->Record.SetSecurityToken(SecurityToken);
+ }
+
+ template <typename T>
NBus::EMessageStatus SyncCall(TAutoPtr<T> msgHolder, TAutoPtr<NBus::TBusMessage> &reply) {
NBus::EMessageStatus msgbusStatus = NBus::EMessageStatus::MESSAGE_TIMEOUT;
const ui64 finishTimeMs = TInstant::Now().MilliSeconds() + TIME_LIMIT_MS;
- PrepareRequest(msgHolder);
+ PrepareRequest(msgHolder);
while (TInstant::Now().MilliSeconds() < finishTimeMs) {
T* msgCopy(new T());
msgCopy->Record = msgHolder->Record;
@@ -340,7 +340,7 @@ namespace Tests {
void ExecuteTraceCommand(NKikimrClient::TMessageBusTraceRequest::ECommand command, const TString &path = TString());
TString StartTrace(const TString &path);
- void StopTrace();
+ void StopTrace();
// Flat DB operations
NMsgBusProxy::EResponseStatus WaitCreateTx(TTestActorRuntime* runtime, const TString& path, TDuration timeout);
@@ -385,11 +385,11 @@ namespace Tests {
TAutoPtr<NMsgBusProxy::TBusResponse> TryDropPersQueueGroup(const TString& parent, const TString& name);
TAutoPtr<NMsgBusProxy::TBusResponse> Ls(const TString& path);
static TPathVersion ExtractPathVersion(const TAutoPtr<NMsgBusProxy::TBusResponse>& describe);
- static TVector<ui64> ExtractTableShards(const TAutoPtr<NMsgBusProxy::TBusResponse>& resp);
+ static TVector<ui64> ExtractTableShards(const TAutoPtr<NMsgBusProxy::TBusResponse>& resp);
bool FlatQuery(const TString& mkql, NKikimrMiniKQL::TResult& result);
bool FlatQuery(const TString& mkql, TFlatQueryOptions& opts, NKikimrMiniKQL::TResult& result,
- const NKikimrClient::TResponse& expectedResponse);
- bool FlatQuery(const TString& mkql, TFlatQueryOptions& opts, NKikimrMiniKQL::TResult& result,
+ const NKikimrClient::TResponse& expectedResponse);
+ bool FlatQuery(const TString& mkql, TFlatQueryOptions& opts, NKikimrMiniKQL::TResult& result,
ui32 expectedStatus = NMsgBusProxy::MSTATUS_OK);
bool FlatQueryParams(const TString &query, const TString &params, bool queryCompiled, NKikimrMiniKQL::TResult &result);
@@ -410,7 +410,7 @@ namespace Tests {
void RemoveStoragePool(const TString& name);
- TAutoPtr<NMsgBusProxy::TBusResponse> HiveCreateTablet(ui32 domainUid, ui64 owner, ui64 owner_index, TTabletTypes::EType tablet_type,
+ TAutoPtr<NMsgBusProxy::TBusResponse> HiveCreateTablet(ui32 domainUid, ui64 owner, ui64 owner_index, TTabletTypes::EType tablet_type,
const TVector<ui32>& allowed_node_ids, const TVector<TSubDomainKey>& allowed_domains = {}, const TChannelsBindings& binding = {});
@@ -471,7 +471,7 @@ namespace Tests {
break;
if (notReadyResp->Record.GetStatus() != NMsgBusProxy::MSTATUS_NOTREADY)
- break;
+ break;
// Retry if the server wasn't ready yet
Sleep(TDuration::MilliSeconds(10));
diff --git a/ydb/core/tx/columnshard/columnshard_impl.cpp b/ydb/core/tx/columnshard/columnshard_impl.cpp
index eec51c1eddc..10dcea4d864 100644
--- a/ydb/core/tx/columnshard/columnshard_impl.cpp
+++ b/ydb/core/tx/columnshard/columnshard_impl.cpp
@@ -14,10 +14,10 @@ namespace
NTabletPipe::TClientConfig GetPipeClientConfig() {
NTabletPipe::TClientConfig config;
- config.RetryPolicy = {
- .MinRetryTime = TDuration::MilliSeconds(50),
- .MaxRetryTime = TDuration::Seconds(2),
- };
+ config.RetryPolicy = {
+ .MinRetryTime = TDuration::MilliSeconds(50),
+ .MaxRetryTime = TDuration::Seconds(2),
+ };
return config;
}
diff --git a/ydb/core/tx/coordinator/coordinator.h b/ydb/core/tx/coordinator/coordinator.h
index 2cdaed1291c..e7a76df3cee 100644
--- a/ydb/core/tx/coordinator/coordinator.h
+++ b/ydb/core/tx/coordinator/coordinator.h
@@ -6,10 +6,10 @@
#include <util/generic/set.h>
#include <util/generic/hash.h>
#include <util/generic/map.h>
-#include <util/generic/hash_set.h>
+#include <util/generic/hash_set.h>
namespace NKikimr {
-namespace NFlatTxCoordinator {
+namespace NFlatTxCoordinator {
struct TMediatorStep;
struct TMediatorConfirmations;
struct TCoordinatorStepConfirmations;
@@ -17,7 +17,7 @@ namespace NFlatTxCoordinator {
}
namespace NKikimr {
-
+
IActor* CreateFlatTxCoordinator(const TActorId &tablet, TTabletStorageInfo *info);
struct TEvTxCoordinator {
@@ -76,7 +76,7 @@ struct TEvTxCoordinator {
// must be explicit queue?
struct TEvMediatorQueueStep : public TEventLocal<TEvMediatorQueueStep, EvMediatorQueueStep> {
const ui64 GenCookie;
- TAutoPtr<NFlatTxCoordinator::TMediatorStep> Step;
+ TAutoPtr<NFlatTxCoordinator::TMediatorStep> Step;
TEvMediatorQueueStep(ui64 genCookie, TAutoPtr<NFlatTxCoordinator::TMediatorStep> step);
};
@@ -96,13 +96,13 @@ struct TEvTxCoordinator {
};
struct TEvMediatorQueueConfirmations : public TEventLocal<TEvMediatorQueueConfirmations, EvMediatorQueueConfirmations> {
- TAutoPtr<NFlatTxCoordinator::TMediatorConfirmations> Confirmations;
+ TAutoPtr<NFlatTxCoordinator::TMediatorConfirmations> Confirmations;
TEvMediatorQueueConfirmations(TAutoPtr<NFlatTxCoordinator::TMediatorConfirmations> &confirmations);
};
struct TEvCoordinatorConfirmPlan : public TEventLocal<TEvCoordinatorConfirmPlan, EvCoordinatorConfirmPlan> {
- TAutoPtr<NFlatTxCoordinator::TCoordinatorStepConfirmations> Confirmations;
+ TAutoPtr<NFlatTxCoordinator::TCoordinatorStepConfirmations> Confirmations;
TEvCoordinatorConfirmPlan(TAutoPtr<NFlatTxCoordinator::TCoordinatorStepConfirmations> &confirmations);
};
diff --git a/ydb/core/tx/coordinator/coordinator__check.cpp b/ydb/core/tx/coordinator/coordinator__check.cpp
index bcab2a5e69b..345ce8d1ddb 100644
--- a/ydb/core/tx/coordinator/coordinator__check.cpp
+++ b/ydb/core/tx/coordinator/coordinator__check.cpp
@@ -1,11 +1,11 @@
#include "coordinator__check.h"
-
-namespace NKikimr {
-namespace NFlatTxCoordinator {
-
+
+namespace NKikimr {
+namespace NFlatTxCoordinator {
+
ITransaction* TTxCoordinator::CreateTxConsistencyCheck() {
- return new TTxConsistencyCheck(this);
-}
-
-}
-}
+ return new TTxConsistencyCheck(this);
+}
+
+}
+}
diff --git a/ydb/core/tx/coordinator/coordinator__check.h b/ydb/core/tx/coordinator/coordinator__check.h
index 0f26075a309..8277b0200be 100644
--- a/ydb/core/tx/coordinator/coordinator__check.h
+++ b/ydb/core/tx/coordinator/coordinator__check.h
@@ -1,73 +1,73 @@
-#pragma once
-
+#pragma once
+
#include "coordinator_impl.h"
-#include <util/generic/hash_set.h>
-
-namespace NKikimr {
-namespace NFlatTxCoordinator {
-
-struct TTxCoordinator::TTxConsistencyCheck : public TTransactionBase<TTxCoordinator> {
- TTxConsistencyCheck(TSelf* self)
- : TTransactionBase<TTxCoordinator>(self)
- {}
-
- bool Execute(TTransactionContext &txc, const TActorContext&) override {
- NIceDb::TNiceDb db(txc.DB);
- TTransactions transactions;
- {
- auto rowset = db.Table<Schema::Transaction>().Range().Select();
- if (!rowset.IsReady())
- return false;
-
- while (!rowset.EndOfSet()) {
- TTxId txId = rowset.GetKey();
- TTransaction& transaction = transactions[txId];
- transaction.PlanOnStep = rowset.GetValue<Schema::Transaction::Plan>();
+#include <util/generic/hash_set.h>
+
+namespace NKikimr {
+namespace NFlatTxCoordinator {
+
+struct TTxCoordinator::TTxConsistencyCheck : public TTransactionBase<TTxCoordinator> {
+ TTxConsistencyCheck(TSelf* self)
+ : TTransactionBase<TTxCoordinator>(self)
+ {}
+
+ bool Execute(TTransactionContext &txc, const TActorContext&) override {
+ NIceDb::TNiceDb db(txc.DB);
+ TTransactions transactions;
+ {
+ auto rowset = db.Table<Schema::Transaction>().Range().Select();
+ if (!rowset.IsReady())
+ return false;
+
+ while (!rowset.EndOfSet()) {
+ TTxId txId = rowset.GetKey();
+ TTransaction& transaction = transactions[txId];
+ transaction.PlanOnStep = rowset.GetValue<Schema::Transaction::Plan>();
TVector<TTabletId> affectedSet = rowset.GetValue<Schema::Transaction::AffectedSet>();
transaction.AffectedSet.reserve(affectedSet.size());
- for (TTabletId id : affectedSet)
- transaction.AffectedSet.insert(id);
- if (!rowset.Next())
- return false; // data not ready
- }
- }
- {
- auto rowset = db.Table<Schema::AffectedSet>().Range().Select();
- if (!rowset.IsReady())
- return false;
- while (!rowset.EndOfSet()) {
+ for (TTabletId id : affectedSet)
+ transaction.AffectedSet.insert(id);
+ if (!rowset.Next())
+ return false; // data not ready
+ }
+ }
+ {
+ auto rowset = db.Table<Schema::AffectedSet>().Range().Select();
+ if (!rowset.IsReady())
+ return false;
+ while (!rowset.EndOfSet()) {
TTabletId medId = rowset.GetValue<Schema::AffectedSet::MediatorID>();
- TTxId txId = rowset.GetValue<Schema::AffectedSet::TransactionID>();
- auto itTransaction = transactions.find(txId);
+ TTxId txId = rowset.GetValue<Schema::AffectedSet::TransactionID>();
+ auto itTransaction = transactions.find(txId);
Y_ENSURE(itTransaction != transactions.end(), "Could not find mediator's transaction");
THashSet<TTabletId>& unconfirmedAffectedSet = itTransaction->second.UnconfirmedAffectedSet[medId];
- unconfirmedAffectedSet.insert(rowset.GetValue<Schema::AffectedSet::DataShardID>());
- if (!rowset.Next())
- return false;
- }
- }
- {
+ unconfirmedAffectedSet.insert(rowset.GetValue<Schema::AffectedSet::DataShardID>());
+ if (!rowset.Next())
+ return false;
+ }
+ }
+ {
Y_ENSURE(transactions.size() == Self->Transactions.size(), "Size of in memory and stored transactions mismatch");
- for (auto it = transactions.begin(); it != transactions.end(); ++it) {
- auto jt = Self->Transactions.find(it->first);
+ for (auto it = transactions.begin(); it != transactions.end(); ++it) {
+ auto jt = Self->Transactions.find(it->first);
Y_ENSURE(jt != Self->Transactions.end(), "Stored transaction hasn't been found in memory");
Y_ENSURE(it->second.PlanOnStep == jt->second.PlanOnStep, "Plan step mismatch");
Y_ENSURE(it->second.AffectedSet == jt->second.AffectedSet, "Affected set mismatch");
Y_ENSURE(it->second.UnconfirmedAffectedSet.size() == jt->second.UnconfirmedAffectedSet.size(), "Unconfirmed affected set size mismatch");
- for (auto kt = it->second.UnconfirmedAffectedSet.begin(); kt != it->second.UnconfirmedAffectedSet.end(); ++kt) {
- auto lt = jt->second.UnconfirmedAffectedSet.find(kt->first);
+ for (auto kt = it->second.UnconfirmedAffectedSet.begin(); kt != it->second.UnconfirmedAffectedSet.end(); ++kt) {
+ auto lt = jt->second.UnconfirmedAffectedSet.find(kt->first);
Y_ENSURE(lt != jt->second.UnconfirmedAffectedSet.end(), "Mediator hasn't' been found in memory");
Y_ENSURE(lt->second == kt->second, "Unconfirmed affected set doesn't match");
- }
- }
- }
- return true;
- }
-
- void Complete(const TActorContext&) override {
- }
-};
-
-}
-}
+ }
+ }
+ }
+ return true;
+ }
+
+ void Complete(const TActorContext&) override {
+ }
+};
+
+}
+}
diff --git a/ydb/core/tx/coordinator/coordinator__mediators_confirmations.cpp b/ydb/core/tx/coordinator/coordinator__mediators_confirmations.cpp
index 969eb34b887..28a644503d9 100644
--- a/ydb/core/tx/coordinator/coordinator__mediators_confirmations.cpp
+++ b/ydb/core/tx/coordinator/coordinator__mediators_confirmations.cpp
@@ -5,9 +5,9 @@
#include <util/generic/hash_set.h>
namespace NKikimr {
-namespace NFlatTxCoordinator {
+namespace NFlatTxCoordinator {
-struct TTxCoordinator::TTxMediatorConfirmations : public TTransactionBase<TTxCoordinator> {
+struct TTxCoordinator::TTxMediatorConfirmations : public TTransactionBase<TTxCoordinator> {
TAutoPtr<TMediatorConfirmations> Confirmations;
i64 CompleteTransactions;
@@ -19,59 +19,59 @@ struct TTxCoordinator::TTxMediatorConfirmations : public TTransactionBase<TTxCoo
TTxType GetTxType() const override { return TXTYPE_MEDIATOR_CONFIRMATIONS; }
- bool Execute(TTransactionContext &txc, const TActorContext &ctx) override {
+ bool Execute(TTransactionContext &txc, const TActorContext &ctx) override {
const TTabletId mediatorId = Confirmations->MediatorId;
Y_UNUSED(ctx);
CompleteTransactions = 0;
- NIceDb::TNiceDb db(txc.DB);
+ NIceDb::TNiceDb db(txc.DB);
ui64 internalTxGen = txc.Generation;
ui64 internalTxStep = txc.Step;
- for (const auto &txidsx : Confirmations->Acks) {
- const TTxId txid = txidsx.first;
- auto txit = Self->Transactions.find(txid);
- if (txit == Self->Transactions.end()) {
+ for (const auto &txidsx : Confirmations->Acks) {
+ const TTxId txid = txidsx.first;
+ auto txit = Self->Transactions.find(txid);
+ if (txit == Self->Transactions.end()) {
FLOG_DEBUG_S(ctx, NKikimrServices::TX_COORDINATOR,
"at tablet# " << Self->TabletID()
<< " gen:step " << internalTxGen << ":" << internalTxStep
<< " Mediator " << mediatorId << " confirmed finish of transaction " << txid << " but transaction wasn't found");
- for (const TTabletId affected : txidsx.second) {
- db.Table<Schema::AffectedSet>().Key(mediatorId, txid, affected).Delete();
- }
- continue;
- }
+ for (const TTabletId affected : txidsx.second) {
+ db.Table<Schema::AffectedSet>().Key(mediatorId, txid, affected).Delete();
+ }
+ continue;
+ }
THashSet<TTabletId>& mediatorAffectedSet = txit->second.UnconfirmedAffectedSet[mediatorId];
- for (const TTabletId affected : txidsx.second) {
+ for (const TTabletId affected : txidsx.second) {
THashSet<TTabletId>::size_type result = mediatorAffectedSet.erase(affected);
- db.Table<Schema::AffectedSet>().Key(mediatorId, txid, affected).Delete();
+ db.Table<Schema::AffectedSet>().Key(mediatorId, txid, affected).Delete();
FLOG_DEBUG_S(ctx, NKikimrServices::TX_COORDINATOR,
"at tablet# " << Self->TabletID()
<< " gen:step " << internalTxGen << ":" << internalTxStep
<< " Confirmed transaction " << txid << " for mediator " << mediatorId << " tablet " << affected << " result=" << result);
- }
+ }
- if (mediatorAffectedSet.empty()) {
+ if (mediatorAffectedSet.empty()) {
FLOG_DEBUG_S(ctx, NKikimrServices::TX_COORDINATOR,
"at tablet# " << Self->TabletID()
<< " gen:step " << internalTxGen << ":" << internalTxStep
<< " Mediator " << mediatorId << " confirmed finish of transaction " << txid);
- txit->second.UnconfirmedAffectedSet.erase(mediatorId);
- }
+ txit->second.UnconfirmedAffectedSet.erase(mediatorId);
+ }
- if (txit->second.UnconfirmedAffectedSet.empty()) { // transaction finished
+ if (txit->second.UnconfirmedAffectedSet.empty()) { // transaction finished
FLOG_DEBUG_S(ctx, NKikimrServices::TX_COORDINATOR,
"at tablet# " << Self->TabletID()
<< " gen:step " << internalTxGen << ":" << internalTxStep
<< " Transaction " << txid << " has been completed");
- db.Table<Schema::Transaction>().Key(txid).Delete();
- Self->Transactions.erase(txit);
- ++CompleteTransactions;
+ db.Table<Schema::Transaction>().Key(txid).Delete();
+ Self->Transactions.erase(txit);
+ ++CompleteTransactions;
}
- }
+ }
- return true;
+ return true;
}
void Complete(const TActorContext &ctx) override {
diff --git a/ydb/core/tx/coordinator/coordinator__monitoring.cpp b/ydb/core/tx/coordinator/coordinator__monitoring.cpp
index c29e5b4a972..550c8ef2815 100644
--- a/ydb/core/tx/coordinator/coordinator__monitoring.cpp
+++ b/ydb/core/tx/coordinator/coordinator__monitoring.cpp
@@ -1,41 +1,41 @@
#include "coordinator_impl.h"
#include "coordinator__check.h"
-
-namespace NKikimr {
-namespace NFlatTxCoordinator {
-
-struct TTxCoordinator::TTxMonitoring : public TTxCoordinator::TTxConsistencyCheck {
+
+namespace NKikimr {
+namespace NFlatTxCoordinator {
+
+struct TTxCoordinator::TTxMonitoring : public TTxCoordinator::TTxConsistencyCheck {
TActorId ActorToRespond;
TString CheckResult;
-
+
TTxMonitoring(TSelf* self, const TActorId& actorToRespond)
- : TTxCoordinator::TTxConsistencyCheck(self)
- , ActorToRespond(actorToRespond)
- {}
-
- bool Execute(TTransactionContext& txc, const TActorContext& ctx) override {
- try {
- bool ok = TTxCoordinator::TTxConsistencyCheck::Execute(txc, ctx);
- if (!ok)
- return false;
- CheckResult = "ConsistencyCheck OK";
- }
- catch(const yexception& e) {
- CheckResult = "ConsistencyCheck FAILED<br>";
- CheckResult += e.what();
- }
- return true;
- }
-
- void Complete(const TActorContext& ctx) override {
- TTxCoordinator::TTxConsistencyCheck::Complete(ctx);
- ctx.Send(ActorToRespond, new NMon::TEvRemoteHttpInfoRes(CheckResult));
- }
-};
-
+ : TTxCoordinator::TTxConsistencyCheck(self)
+ , ActorToRespond(actorToRespond)
+ {}
+
+ bool Execute(TTransactionContext& txc, const TActorContext& ctx) override {
+ try {
+ bool ok = TTxCoordinator::TTxConsistencyCheck::Execute(txc, ctx);
+ if (!ok)
+ return false;
+ CheckResult = "ConsistencyCheck OK";
+ }
+ catch(const yexception& e) {
+ CheckResult = "ConsistencyCheck FAILED<br>";
+ CheckResult += e.what();
+ }
+ return true;
+ }
+
+ void Complete(const TActorContext& ctx) override {
+ TTxCoordinator::TTxConsistencyCheck::Complete(ctx);
+ ctx.Send(ActorToRespond, new NMon::TEvRemoteHttpInfoRes(CheckResult));
+ }
+};
+
ITransaction* TTxCoordinator::CreateTxMonitoring(NMon::TEvRemoteHttpInfo::TPtr& ev) {
- return new TTxMonitoring(this, ev->Sender);
-}
-
-}
-}
+ return new TTxMonitoring(this, ev->Sender);
+}
+
+}
+}
diff --git a/ydb/core/tx/coordinator/coordinator__plan_step.cpp b/ydb/core/tx/coordinator/coordinator__plan_step.cpp
index 80d522248d0..c1fac2ffa58 100644
--- a/ydb/core/tx/coordinator/coordinator__plan_step.cpp
+++ b/ydb/core/tx/coordinator/coordinator__plan_step.cpp
@@ -3,7 +3,7 @@
#include <util/generic/hash_set.h>
namespace NKikimr {
-namespace NFlatTxCoordinator {
+namespace NFlatTxCoordinator {
struct TInFlyAccountant {
NMonitoring::TDynamicCounters::TCounterPtr Counter;
@@ -17,7 +17,7 @@ struct TInFlyAccountant {
}
};
-struct TTxCoordinator::TTxPlanStep : public TTransactionBase<TTxCoordinator> {
+struct TTxCoordinator::TTxPlanStep : public TTransactionBase<TTxCoordinator> {
const ui64 PlanOnStep;
const bool Rapid;
TVector<TQueueType::TSlot> Slots;
@@ -41,9 +41,9 @@ struct TTxCoordinator::TTxPlanStep : public TTransactionBase<TTxCoordinator> {
Slots.swap(slots);
}
- void Plan(TTransactionContext &txc, const TActorContext &ctx) {
+ void Plan(TTransactionContext &txc, const TActorContext &ctx) {
Y_UNUSED(txc);
- NIceDb::TNiceDb db(txc.DB);
+ NIceDb::TNiceDb db(txc.DB);
ExecStartMoment = ctx.Now();
const bool lowDiskSpace = Self->Executor()->GetStats().IsAnyChannelYellowStop;
@@ -51,67 +51,67 @@ struct TTxCoordinator::TTxPlanStep : public TTransactionBase<TTxCoordinator> {
TVector<TAutoPtr<TMediatorStep>> mediatorSteps;
THashMap<TTabletId, TVector<TTabletId>> byMediatorAffected;
- // first fill every mediator with something (every mediator must receive step)
+ // first fill every mediator with something (every mediator must receive step)
const ui32 mediatorsSize = Self->Config.Mediators->List().size();
- mediatorSteps.reserve(mediatorsSize);
+ mediatorSteps.reserve(mediatorsSize);
for (TTabletId mediatorId : Self->Config.Mediators->List()) {
- mediatorSteps.push_back(new TMediatorStep(mediatorId, PlanOnStep));
+ mediatorSteps.push_back(new TMediatorStep(mediatorId, PlanOnStep));
}
- // create mediator steps
- ProxyPlanConfirmations.Reset(new TCoordinatorStepConfirmations(PlanOnStep));
- for (const auto &slot : Slots) {
+ // create mediator steps
+ ProxyPlanConfirmations.Reset(new TCoordinatorStepConfirmations(PlanOnStep));
+ for (const auto &slot : Slots) {
TQueueType::TQ &queue = *slot.Queue;
TQueueType::TQ::TReadIterator iterator = queue.Iterator();
- while (TTransactionProposal *proposal = iterator.Next()) {
+ while (TTransactionProposal *proposal = iterator.Next()) {
for (auto &x : byMediatorAffected) {
x.second.clear();
}
- const TTxId txId = proposal->TxId;
+ const TTxId txId = proposal->TxId;
Y_VERIFY(txId);
- Self->MonCounters.StepConsideredTx->Inc();
+ Self->MonCounters.StepConsideredTx->Inc();
auto durationMs = (ExecStartMoment - proposal->AcceptMoment).MilliSeconds();
Self->MonCounters.LegacyTxFromReceiveToPlan.Add(durationMs);
Self->MonCounters.TxFromReceiveToPlan->Collect(durationMs);
- if (proposal->MaxStep < PlanOnStep) {
- Self->MonCounters.StepOutdatedTx->Inc();
- ProxyPlanConfirmations->Queue->Push(new TCoordinatorStepConfirmations::TEntry {
- txId,
- proposal->Proxy,
- TEvTxProxy::TEvProposeTransactionStatus::EStatus::StatusOutdated,
- 0 });
- ++DeclinedCounter;
- continue;
- }
-
- // check is transactions already processed?
- if (newTransactions.insert(txId).second == false) {
- Self->MonCounters.StepPlannedDeclinedTx->Inc();
- ProxyPlanConfirmations->Queue->Push(new TCoordinatorStepConfirmations::TEntry {
- txId,
- proposal->Proxy,
- TEvTxProxy::TEvProposeTransactionStatus::EStatus::StatusPlanned,
- PlanOnStep });
- ++DeclinedCounter;
- continue;
- }
-
- {
- auto it = Self->Transactions.find(txId);
- if (it != Self->Transactions.end()) {
- Self->MonCounters.StepPlannedDeclinedTx->Inc();
- ProxyPlanConfirmations->Queue->Push(new TCoordinatorStepConfirmations::TEntry {
- txId,
- proposal->Proxy,
- TEvTxProxy::TEvProposeTransactionStatus::EStatus::StatusPlanned,
- it->second.PlanOnStep });
- ++DeclinedCounter;
- continue;
- }
- }
+ if (proposal->MaxStep < PlanOnStep) {
+ Self->MonCounters.StepOutdatedTx->Inc();
+ ProxyPlanConfirmations->Queue->Push(new TCoordinatorStepConfirmations::TEntry {
+ txId,
+ proposal->Proxy,
+ TEvTxProxy::TEvProposeTransactionStatus::EStatus::StatusOutdated,
+ 0 });
+ ++DeclinedCounter;
+ continue;
+ }
+
+ // check is transactions already processed?
+ if (newTransactions.insert(txId).second == false) {
+ Self->MonCounters.StepPlannedDeclinedTx->Inc();
+ ProxyPlanConfirmations->Queue->Push(new TCoordinatorStepConfirmations::TEntry {
+ txId,
+ proposal->Proxy,
+ TEvTxProxy::TEvProposeTransactionStatus::EStatus::StatusPlanned,
+ PlanOnStep });
+ ++DeclinedCounter;
+ continue;
+ }
+
+ {
+ auto it = Self->Transactions.find(txId);
+ if (it != Self->Transactions.end()) {
+ Self->MonCounters.StepPlannedDeclinedTx->Inc();
+ ProxyPlanConfirmations->Queue->Push(new TCoordinatorStepConfirmations::TEntry {
+ txId,
+ proposal->Proxy,
+ TEvTxProxy::TEvProposeTransactionStatus::EStatus::StatusPlanned,
+ it->second.PlanOnStep });
+ ++DeclinedCounter;
+ continue;
+ }
+ }
if (lowDiskSpace && !proposal->IgnoreLowDiskSpace) {
Self->MonCounters.StepDeclinedNoSpaceTx->Inc();
@@ -125,91 +125,91 @@ struct TTxCoordinator::TTxPlanStep : public TTransactionBase<TTxCoordinator> {
continue;
}
- // write transaction in body
- // todo: subtree insertion, moderator/body store
- {
- TTransaction& transaction = Self->Transactions[txId];
+ // write transaction in body
+ // todo: subtree insertion, moderator/body store
+ {
+ TTransaction& transaction = Self->Transactions[txId];
- transaction.PlanOnStep = PlanOnStep;
+ transaction.PlanOnStep = PlanOnStep;
Y_VERIFY(!proposal->AffectedSet.empty());
- for (const auto &txprop : proposal->AffectedSet) {
- const TTabletId affectedTablet = txprop.TabletId;
+ for (const auto &txprop : proposal->AffectedSet) {
+ const TTabletId affectedTablet = txprop.TabletId;
const TTabletId mediatorId = Self->Config.Mediators->Select(affectedTablet);
-
- transaction.AffectedSet.insert(affectedTablet);
+
+ transaction.AffectedSet.insert(affectedTablet);
transaction.UnconfirmedAffectedSet[mediatorId].insert(affectedTablet);
byMediatorAffected[mediatorId].push_back(affectedTablet);
- }
+ }
TVector<TTabletId> affectedSet(transaction.AffectedSet.begin(), transaction.AffectedSet.end());
- db.Table<Schema::Transaction>().Key(txId).Update(
- NIceDb::TUpdate<Schema::Transaction::Plan>(PlanOnStep),
- NIceDb::TUpdate<Schema::Transaction::AffectedSet>(affectedSet));
- FLOG_DEBUG_S(ctx, NKikimrServices::TX_COORDINATOR, "Transaction " << txId << " has been planned");
- // todo: moderator, proxy
- }
+ db.Table<Schema::Transaction>().Key(txId).Update(
+ NIceDb::TUpdate<Schema::Transaction::Plan>(PlanOnStep),
+ NIceDb::TUpdate<Schema::Transaction::AffectedSet>(affectedSet));
+ FLOG_DEBUG_S(ctx, NKikimrServices::TX_COORDINATOR, "Transaction " << txId << " has been planned");
+ // todo: moderator, proxy
+ }
- for (ui32 idx = 0; idx < mediatorsSize; ++idx) {
+ for (ui32 idx = 0; idx < mediatorsSize; ++idx) {
TTabletId mediatorId = mediatorSteps[idx]->MediatorId;
TVector<TTabletId> &affected = byMediatorAffected[mediatorId];
- if (!affected.empty()) {
+ if (!affected.empty()) {
mediatorSteps[idx]->Transactions.push_back(TMediatorStep::TTx(txId, &affected.front(), affected.size(), 0));
- }
- }
-
- newTransactions.insert(txId);
- ++PlannedCounter;
-
- Self->MonCounters.StepPlannedTx->Inc();
- ProxyPlanConfirmations->Queue->Push(new TCoordinatorStepConfirmations::TEntry {
- txId,
- proposal->Proxy,
- TEvTxProxy::TEvProposeTransactionStatus::EStatus::StatusPlanned,
- PlanOnStep } );
- }
- }
-
- for (const TAutoPtr<TMediatorStep> &mp : mediatorSteps) {
- const ui64 mediatorId = mp->MediatorId;
-
- // write mediator entry
- for (const auto &tx : mp->Transactions) {
- for (TTabletId tablet : tx.PushToAffected) {
- db.Table<Schema::AffectedSet>().Key(mediatorId, tx.TxId, tablet).Update();
- FLOG_DEBUG_S(ctx, NKikimrServices::TX_COORDINATOR, "Planned transaction " << tx.TxId << " for mediator " << mediatorId << " tablet " << tablet);
- }
- }
-
- TMediator& mediator = Self->Mediator(mediatorId, ctx);
- if (mediator.PushUpdates) {
- StepsToConfirm[mediatorId] = std::pair<ui64, bool *>(mediator.GenCookie, &mp->Confirmed);
- mediator.Queue->Push(mp.Release());
+ }
+ }
+
+ newTransactions.insert(txId);
+ ++PlannedCounter;
+
+ Self->MonCounters.StepPlannedTx->Inc();
+ ProxyPlanConfirmations->Queue->Push(new TCoordinatorStepConfirmations::TEntry {
+ txId,
+ proposal->Proxy,
+ TEvTxProxy::TEvProposeTransactionStatus::EStatus::StatusPlanned,
+ PlanOnStep } );
+ }
+ }
+
+ for (const TAutoPtr<TMediatorStep> &mp : mediatorSteps) {
+ const ui64 mediatorId = mp->MediatorId;
+
+ // write mediator entry
+ for (const auto &tx : mp->Transactions) {
+ for (TTabletId tablet : tx.PushToAffected) {
+ db.Table<Schema::AffectedSet>().Key(mediatorId, tx.TxId, tablet).Update();
+ FLOG_DEBUG_S(ctx, NKikimrServices::TX_COORDINATOR, "Planned transaction " << tx.TxId << " for mediator " << mediatorId << " tablet " << tablet);
+ }
+ }
+
+ TMediator& mediator = Self->Mediator(mediatorId, ctx);
+ if (mediator.PushUpdates) {
+ StepsToConfirm[mediatorId] = std::pair<ui64, bool *>(mediator.GenCookie, &mp->Confirmed);
+ mediator.Queue->Push(mp.Release());
} else if (!StepsToConfirm.empty()) {
FLOG_DEBUG_S(ctx, NKikimrServices::TX_COORDINATOR, "PushUpdates false for mediator " << mediatorId << " step " << PlanOnStep);
- }
- }
- db.Table<Schema::State>().Key(Schema::State::KeyLastPlanned).Update(NIceDb::TUpdate<Schema::State::StateValue>(PlanOnStep));
+ }
+ }
+ db.Table<Schema::State>().Key(Schema::State::KeyLastPlanned).Update(NIceDb::TUpdate<Schema::State::StateValue>(PlanOnStep));
}
TTxType GetTxType() const override { return TXTYPE_STEP; }
- bool Execute(TTransactionContext &txc, const TActorContext &ctx) override {
- PlannedCounter = 0;
- DeclinedCounter = 0;
+ bool Execute(TTransactionContext &txc, const TActorContext &ctx) override {
+ PlannedCounter = 0;
+ DeclinedCounter = 0;
- Plan(txc, ctx);
+ Plan(txc, ctx);
- if (Rapid)
- Self->VolatileState.Queue.RapidFreeze = false;
+ if (Rapid)
+ Self->VolatileState.Queue.RapidFreeze = false;
- *Self->MonCounters.TxPlanned += PlannedCounter;
- *Self->MonCounters.TxInFly += PlannedCounter;
- Self->MonCounters.CurrentTxInFly += PlannedCounter;
- *Self->MonCounters.TxDeclined += DeclinedCounter;
+ *Self->MonCounters.TxPlanned += PlannedCounter;
+ *Self->MonCounters.TxInFly += PlannedCounter;
+ Self->MonCounters.CurrentTxInFly += PlannedCounter;
+ *Self->MonCounters.TxDeclined += DeclinedCounter;
- return true;
+ return true;
}
void Complete(const TActorContext &ctx) override {
@@ -227,9 +227,9 @@ struct TTxCoordinator::TTxPlanStep : public TTransactionBase<TTxCoordinator> {
}
ctx.Send(ctx.SelfID, new TEvTxCoordinator::TEvCoordinatorConfirmPlan(ProxyPlanConfirmations));
-
- // uncomment this to enable consistency self-check
- //Self->Execute(Self->CreateTxConsistencyCheck(), ctx);
+
+ // uncomment this to enable consistency self-check
+ //Self->Execute(Self->CreateTxConsistencyCheck(), ctx);
}
};
diff --git a/ydb/core/tx/coordinator/coordinator__restart_mediator.cpp b/ydb/core/tx/coordinator/coordinator__restart_mediator.cpp
index 35f0d85716d..673115d22b0 100644
--- a/ydb/core/tx/coordinator/coordinator__restart_mediator.cpp
+++ b/ydb/core/tx/coordinator/coordinator__restart_mediator.cpp
@@ -1,9 +1,9 @@
#include "coordinator_impl.h"
namespace NKikimr {
-namespace NFlatTxCoordinator {
+namespace NFlatTxCoordinator {
-struct TTxCoordinator::TTxRestartMediatorQueue : public TTransactionBase<TTxCoordinator> {
+struct TTxCoordinator::TTxRestartMediatorQueue : public TTransactionBase<TTxCoordinator> {
const TTabletId MediatorId;
const ui64 GenCookie;
@@ -25,28 +25,28 @@ struct TTxCoordinator::TTxRestartMediatorQueue : public TTransactionBase<TTxCoor
THashMap<TTxId,TVector<TTabletId>> pushToAffectedBuffer;
TVector<TAutoPtr<TMediatorStep>> mediatorSteps;
- if (!Self->RestoreMediatorInfo(MediatorId, mediatorSteps, txc, pushToAffectedBuffer))
- return false;
+ if (!Self->RestoreMediatorInfo(MediatorId, mediatorSteps, txc, pushToAffectedBuffer))
+ return false;
- for (const auto& it : pushToAffectedBuffer) {
- TTransaction& transaction = Self->Transactions[it.first];
+ for (const auto& it : pushToAffectedBuffer) {
+ TTransaction& transaction = Self->Transactions[it.first];
THashSet<TTabletId>& unconfirmedAffectedSet = transaction.UnconfirmedAffectedSet[MediatorId];
Y_VERIFY(unconfirmedAffectedSet.size() == it.second.size(),
"Incosistent affected set in mem in DB for txId %" PRIu64, it.first);
- for (const TTabletId affectedTabletId : it.second) {
+ for (const TTabletId affectedTabletId : it.second) {
Y_VERIFY(unconfirmedAffectedSet.contains(affectedTabletId),
"Incosistent affected set in mem in DB for txId %" PRIu64 " missing tabletId %" PRIu64,
it.first, affectedTabletId);
- }
- }
+ }
+ }
- for (const auto &mp : mediatorSteps) {
- StepsToConfirm.push_back(&mp->Confirmed);
- mediator.Queue->Push(mp.Release());
- }
+ for (const auto &mp : mediatorSteps) {
+ StepsToConfirm.push_back(&mp->Confirmed);
+ mediator.Queue->Push(mp.Release());
+ }
- mediator.PushUpdates = true;
- return true;
+ mediator.PushUpdates = true;
+ return true;
}
void Complete(const TActorContext &ctx) override {
@@ -66,45 +66,45 @@ ITransaction* TTxCoordinator::CreateTxRestartMediatorQueue(TTabletId mediatorId,
}
bool TTxCoordinator::RestoreMediatorInfo(TTabletId mediatorId, TVector<TAutoPtr<TMediatorStep>> &planned, TTransactionContext &txc, /*TKeyBuilder &kb, */THashMap<TTxId,TVector<TTabletId>> &pushToAffected) const {
- NIceDb::TNiceDb db(txc.DB);
+ NIceDb::TNiceDb db(txc.DB);
pushToAffected.clear();
planned.clear();
- auto rowset = db.Table<Schema::AffectedSet>().Range(mediatorId).Select();
- if (!rowset.IsReady())
- return false;
+ auto rowset = db.Table<Schema::AffectedSet>().Range(mediatorId).Select();
+ if (!rowset.IsReady())
+ return false;
// Later we will need this to be sorted by stepId
TMap<TStepId, TAutoPtr<TMediatorStep>> mediatorSteps;
- while (!rowset.EndOfSet()) {
- const TTxId txId = rowset.GetValue<Schema::AffectedSet::TransactionID>();
- auto itTransaction = Transactions.find(txId);
+ while (!rowset.EndOfSet()) {
+ const TTxId txId = rowset.GetValue<Schema::AffectedSet::TransactionID>();
+ auto itTransaction = Transactions.find(txId);
Y_VERIFY(itTransaction != Transactions.end());
- TStepId step = itTransaction->second.PlanOnStep;
- auto itStep = mediatorSteps.find(step);
- if (itStep == mediatorSteps.end()) {
- itStep = mediatorSteps.insert(std::make_pair(step, new TMediatorStep(mediatorId, step))).first;
- }
- TAutoPtr<TMediatorStep>& mediatorStep = itStep->second;
+ TStepId step = itTransaction->second.PlanOnStep;
+ auto itStep = mediatorSteps.find(step);
+ if (itStep == mediatorSteps.end()) {
+ itStep = mediatorSteps.insert(std::make_pair(step, new TMediatorStep(mediatorId, step))).first;
+ }
+ TAutoPtr<TMediatorStep>& mediatorStep = itStep->second;
if (mediatorStep->Transactions.empty() || mediatorStep->Transactions.back().TxId != txId)
mediatorStep->Transactions.push_back(TMediatorStep::TTx(txId));
- TMediatorStep::TTx &tx = mediatorStep->Transactions.back();
-
- TTabletId tablet = rowset.GetValue<Schema::AffectedSet::DataShardID>();
- pushToAffected[txId].push_back(tablet);
- tx.PushToAffected.push_back(tablet);
- tx.Moderator = 0;
- if (!rowset.Next())
- return false;
- }
+ TMediatorStep::TTx &tx = mediatorStep->Transactions.back();
+
+ TTabletId tablet = rowset.GetValue<Schema::AffectedSet::DataShardID>();
+ pushToAffected[txId].push_back(tablet);
+ tx.PushToAffected.push_back(tablet);
+ tx.Moderator = 0;
+ if (!rowset.Next())
+ return false;
+ }
for (auto& pr : mediatorSteps)
- planned.push_back(pr.second);
+ planned.push_back(pr.second);
- return true;
+ return true;
}
}
diff --git a/ydb/core/tx/coordinator/coordinator__restore_transaction.cpp b/ydb/core/tx/coordinator/coordinator__restore_transaction.cpp
index 32acad10d03..26a916bdff9 100644
--- a/ydb/core/tx/coordinator/coordinator__restore_transaction.cpp
+++ b/ydb/core/tx/coordinator/coordinator__restore_transaction.cpp
@@ -6,59 +6,59 @@
#include <util/stream/file.h>
namespace NKikimr {
-namespace NFlatTxCoordinator {
+namespace NFlatTxCoordinator {
struct TTxCoordinator::TTxRestoreTransactions : public TTransactionBase<TTxCoordinator> {
TTxRestoreTransactions(TSelf *coordinator)
: TBase(coordinator)
{}
- bool Restore(TTransactions &transactions, TTransactionContext &txc, const TActorContext &ctx) {
+ bool Restore(TTransactions &transactions, TTransactionContext &txc, const TActorContext &ctx) {
Y_UNUSED(ctx);
- NIceDb::TNiceDb db(txc.DB);
-
+ NIceDb::TNiceDb db(txc.DB);
+
{
- auto rowset = db.Table<Schema::Transaction>().Range().Select();
- if (!rowset.IsReady())
- return false;
-
- while (!rowset.EndOfSet()) {
- TTxId txId = rowset.GetValue<Schema::Transaction::ID>();
- TTransaction& transaction = transactions[txId];
- transaction.PlanOnStep = rowset.GetValue<Schema::Transaction::Plan>();
+ auto rowset = db.Table<Schema::Transaction>().Range().Select();
+ if (!rowset.IsReady())
+ return false;
+
+ while (!rowset.EndOfSet()) {
+ TTxId txId = rowset.GetValue<Schema::Transaction::ID>();
+ TTransaction& transaction = transactions[txId];
+ transaction.PlanOnStep = rowset.GetValue<Schema::Transaction::Plan>();
TVector<TTabletId> affectedSet = rowset.GetValue<Schema::Transaction::AffectedSet>();
transaction.AffectedSet.reserve(affectedSet.size());
- for (TTabletId id : affectedSet)
- transaction.AffectedSet.insert(id);
- if (!rowset.Next())
- return false; // data not ready
- }
- }
-
- {
- int errors = 0;
- auto rowset = db.Table<Schema::AffectedSet>().Range().Select();
- if (!rowset.IsReady())
- return false;
-
- while (!rowset.EndOfSet()) {
+ for (TTabletId id : affectedSet)
+ transaction.AffectedSet.insert(id);
+ if (!rowset.Next())
+ return false; // data not ready
+ }
+ }
+
+ {
+ int errors = 0;
+ auto rowset = db.Table<Schema::AffectedSet>().Range().Select();
+ if (!rowset.IsReady())
+ return false;
+
+ while (!rowset.EndOfSet()) {
const TTxId txId = rowset.GetValue<Schema::AffectedSet::TransactionID>();
const TTabletId medId = rowset.GetValue<Schema::AffectedSet::MediatorID>();
const ui64 affectedShardId = rowset.GetValue<Schema::AffectedSet::DataShardID>();
- auto itTransaction = transactions.find(txId);
- if (itTransaction != transactions.end()) {
+ auto itTransaction = transactions.find(txId);
+ if (itTransaction != transactions.end()) {
itTransaction->second.UnconfirmedAffectedSet[medId].insert(affectedShardId);
- } else {
+ } else {
LOG_ERROR_S(ctx, NKikimrServices::TX_COORDINATOR, "Transaction not found: MedId = " << medId << " TxId = " << txId << " DataShardId = " << affectedShardId);
- ++errors;
- }
+ ++errors;
+ }
- if (!rowset.Next())
- return false;
- }
+ if (!rowset.Next())
+ return false;
+ }
- if (errors > 0) {
+ if (errors > 0) {
// DB is corrupt. Make a dump and stop
const NScheme::TTypeRegistry& tr = *AppData(ctx)->TypeRegistry;
TString dbDumpFile = Sprintf("/tmp/coordinator_db_dump_%" PRIu64 ".%" PRIi32, Self->TabletID(), getpid());
@@ -66,26 +66,26 @@ struct TTxCoordinator::TTxRestoreTransactions : public TTransactionBase<TTxCoord
txc.DB.DebugDump(out, tr);
out.Finish();
Cerr << "Coordinator DB dumped to " << dbDumpFile;
- Sleep(TDuration::Seconds(10));
+ Sleep(TDuration::Seconds(10));
Y_FAIL("Transaction(s) not found!");
- }
- }
+ }
+ }
- return true;
+ return true;
}
TTxType GetTxType() const override { return TXTYPE_INIT; }
- bool Execute(TTransactionContext &txc, const TActorContext &ctx) override {
- TTransactions transactions;
- bool result = Restore(transactions, txc, ctx);
- if (!result)
- return false;
- i64 txCounter = transactions.size();
- Self->Transactions.swap(transactions);
- *Self->MonCounters.TxInFly += txCounter;
- Self->MonCounters.CurrentTxInFly = txCounter;
- return true;
+ bool Execute(TTransactionContext &txc, const TActorContext &ctx) override {
+ TTransactions transactions;
+ bool result = Restore(transactions, txc, ctx);
+ if (!result)
+ return false;
+ i64 txCounter = transactions.size();
+ Self->Transactions.swap(transactions);
+ *Self->MonCounters.TxInFly += txCounter;
+ Self->MonCounters.CurrentTxInFly = txCounter;
+ return true;
}
void Complete(const TActorContext &ctx) override {
diff --git a/ydb/core/tx/coordinator/coordinator__schema.cpp b/ydb/core/tx/coordinator/coordinator__schema.cpp
index 5833f4636f3..1fb202a2581 100644
--- a/ydb/core/tx/coordinator/coordinator__schema.cpp
+++ b/ydb/core/tx/coordinator/coordinator__schema.cpp
@@ -1,28 +1,28 @@
#include "coordinator_impl.h"
-
-namespace NKikimr {
-namespace NFlatTxCoordinator {
-
-struct TTxCoordinator::TTxSchema : public TTransactionBase<TTxCoordinator> {
- TTxSchema(TSelf *coordinator)
- : TBase(coordinator)
- {}
-
+
+namespace NKikimr {
+namespace NFlatTxCoordinator {
+
+struct TTxCoordinator::TTxSchema : public TTransactionBase<TTxCoordinator> {
+ TTxSchema(TSelf *coordinator)
+ : TBase(coordinator)
+ {}
+
TTxType GetTxType() const override { return TXTYPE_INIT; }
- bool Execute(TTransactionContext &txc, const TActorContext&) override {
- NIceDb::TNiceDb(txc.DB).Materialize<Schema>();
- return true;
- }
-
- void Complete(const TActorContext &ctx) override {
- Self->Execute(Self->CreateTxUpgrade(), ctx);
- }
-};
-
+ bool Execute(TTransactionContext &txc, const TActorContext&) override {
+ NIceDb::TNiceDb(txc.DB).Materialize<Schema>();
+ return true;
+ }
+
+ void Complete(const TActorContext &ctx) override {
+ Self->Execute(Self->CreateTxUpgrade(), ctx);
+ }
+};
+
ITransaction* TTxCoordinator::CreateTxSchema() {
- return new TTxSchema(this);
-}
-
-}
-}
+ return new TTxSchema(this);
+}
+
+}
+}
diff --git a/ydb/core/tx/coordinator/coordinator__schema_upgrade.cpp b/ydb/core/tx/coordinator/coordinator__schema_upgrade.cpp
index 216e127bfe9..931a7c993e5 100644
--- a/ydb/core/tx/coordinator/coordinator__schema_upgrade.cpp
+++ b/ydb/core/tx/coordinator/coordinator__schema_upgrade.cpp
@@ -1,39 +1,39 @@
#include "coordinator_impl.h"
#include <ydb/core/tablet/tablet_exception.h>
-
-namespace NKikimr {
-namespace NFlatTxCoordinator {
-
-struct TTxCoordinator::TTxUpgrade : public TTransactionBase<TTxCoordinator> {
+
+namespace NKikimr {
+namespace NFlatTxCoordinator {
+
+struct TTxCoordinator::TTxUpgrade : public TTransactionBase<TTxCoordinator> {
bool UpgradeFail;
- TTxUpgrade(TSelf *coordinator)
- : TBase(coordinator)
+ TTxUpgrade(TSelf *coordinator)
+ : TBase(coordinator)
, UpgradeFail(false)
- {}
-
+ {}
+
TTxType GetTxType() const override { return TXTYPE_INIT; }
bool Execute(TTransactionContext &txc, const TActorContext& ctx) override {
- NIceDb::TNiceDb db(txc.DB);
+ NIceDb::TNiceDb db(txc.DB);
- auto row = db.Table<Schema::State>().Key(Schema::State::DatabaseVersion).Select<Schema::State::StateValue>();
+ auto row = db.Table<Schema::State>().Key(Schema::State::DatabaseVersion).Select<Schema::State::StateValue>();
if (!row.IsReady()) {
- return false;
+ return false;
}
- if (!row.IsValid()) {
+ if (!row.IsValid()) {
db.Table<Schema::State>().Key(Schema::State::DatabaseVersion).Update(NIceDb::TUpdate<Schema::State::StateValue>(Schema::CurrentVersion));
return true;
}
-
+
Schema::State::StateValue::Type databaseVersion = row.GetValue<Schema::State::StateValue>();
if (Schema::CurrentVersion == databaseVersion) {
return true;
}
-
+
UpgradeFail = true;
FLOG_LOG_S(ctx, NActors::NLog::PRI_CRIT, NKikimrServices::TX_COORDINATOR,
"tablet# " << Self->Tablet() <<
@@ -41,23 +41,23 @@ struct TTxCoordinator::TTxUpgrade : public TTransactionBase<TTxCoordinator> {
" databaseVersion# " << databaseVersion <<
" CurrentDataBaseVersion# " << Schema::CurrentVersion <<
" reason# no realisation for upgrade scheme present");
- return true;
- }
-
- void Complete(const TActorContext &ctx) override {
+ return true;
+ }
+
+ void Complete(const TActorContext &ctx) override {
if (UpgradeFail) {
Self->Become(&TSelf::StateBroken);
ctx.Send(Self->Tablet(), new TEvents::TEvPoisonPill);
return;
}
- Self->Execute(Self->CreateTxInit(), ctx);
- }
-};
-
+ Self->Execute(Self->CreateTxInit(), ctx);
+ }
+};
+
ITransaction* TTxCoordinator::CreateTxUpgrade() {
- return new TTxUpgrade(this);
-}
-
-}
-}
+ return new TTxUpgrade(this);
+}
+
+}
+}
diff --git a/ydb/core/tx/coordinator/coordinator_impl.cpp b/ydb/core/tx/coordinator/coordinator_impl.cpp
index 429d3cba0f9..b4eeb184e29 100644
--- a/ydb/core/tx/coordinator/coordinator_impl.cpp
+++ b/ydb/core/tx/coordinator/coordinator_impl.cpp
@@ -9,7 +9,7 @@
#include <ydb/core/tx/tx.h>
namespace NKikimr {
-namespace NFlatTxCoordinator {
+namespace NFlatTxCoordinator {
static constexpr TDuration MaxEmptyPlanDelay = TDuration::Seconds(1);
@@ -57,10 +57,10 @@ TTxCoordinator::TTxCoordinator(TTabletStorageInfo *info, const TActorId &tablet)
#endif
{
#ifdef COORDINATOR_LOG_TO_FILE
- // HACK
- Cerr << "Coordinator LOG will be dumped to " << DebugName << Endl;
+ // HACK
+ Cerr << "Coordinator LOG will be dumped to " << DebugName << Endl;
#endif
-
+
Config.PlanAhead = 50;
Config.Resolution = 1250;
Config.RapidSlotFlushSize = 1000; // todo: something meaningful
@@ -130,7 +130,7 @@ void TTxCoordinator::PlanTx(TAutoPtr<TTransactionProposal> &proposal, const TAct
VolatileState.LastPlanned = planStep;
VolatileState.Queue.RapidFreeze = true;
- Execute(CreateTxPlanStep(planStep, slots, true), ctx);
+ Execute(CreateTxPlanStep(planStep, slots, true), ctx);
}
} else {
TQueueType::TSlot &planSlot = VolatileState.Queue.LowSlot(planStep);
@@ -233,7 +233,7 @@ void TTxCoordinator::Handle(TEvTxCoordinator::TEvMediatorQueueConfirmations::TPt
TEvTxCoordinator::TEvMediatorQueueConfirmations *msg = ev->Get();
LOG_DEBUG_S(ctx, NKikimrServices::TX_COORDINATOR, "tablet# " << TabletID()
<< " HANDLE EvMediatorQueueConfirmations MediatorId# " << msg->Confirmations->MediatorId);
- Execute(CreateTxMediatorConfirmations(msg->Confirmations), ctx);
+ Execute(CreateTxMediatorConfirmations(msg->Confirmations), ctx);
}
void TTxCoordinator::Handle(TEvTxCoordinator::TEvMediatorQueueStop::TPtr &ev, const TActorContext &ctx) {
@@ -255,7 +255,7 @@ void TTxCoordinator::Handle(TEvTxCoordinator::TEvMediatorQueueRestart::TPtr &ev,
mediator.PushUpdates = false;
mediator.GenCookie = msg->GenCookie;
mediator.Queue.Reset(new TMediator::TStepQueue());
- Execute(CreateTxRestartMediatorQueue(msg->MediatorId, msg->GenCookie), ctx);
+ Execute(CreateTxRestartMediatorQueue(msg->MediatorId, msg->GenCookie), ctx);
}
void TTxCoordinator::Handle(TEvTxCoordinator::TEvCoordinatorConfirmPlan::TPtr &ev, const TActorContext &ctx) {
@@ -300,15 +300,15 @@ void TTxCoordinator::Handle(TEvSubDomain::TEvConfigure::TPtr &ev, const TActorCo
DoConfiguration(*ev->Get(), ctx, ev->Sender);
}
-void TTxCoordinator::Handle(TEvents::TEvPoisonPill::TPtr&, const TActorContext& ctx) {
- Become(&TThis::StateBroken);
- ctx.Send(Tablet(), new TEvents::TEvPoisonPill);
-}
-
+void TTxCoordinator::Handle(TEvents::TEvPoisonPill::TPtr&, const TActorContext& ctx) {
+ Become(&TThis::StateBroken);
+ ctx.Send(Tablet(), new TEvents::TEvPoisonPill);
+}
+
void TTxCoordinator::OnActivateExecutor(const TActorContext &ctx) {
- TryInitMonCounters(ctx);
+ TryInitMonCounters(ctx);
Executor()->RegisterExternalTabletCounters(TabletCountersPtr);
- Execute(CreateTxSchema(), ctx);
+ Execute(CreateTxSchema(), ctx);
}
void TTxCoordinator::TryInitMonCounters(const TActorContext &ctx) {
@@ -364,15 +364,15 @@ void TTxCoordinator::SchedulePlanTick(const TActorContext &ctx) {
ctx.Schedule(TDuration::MilliSeconds(planResolution), new TEvPrivate::TEvPlanTick());
}
-bool TTxCoordinator::OnRenderAppHtmlPage(NMon::TEvRemoteHttpInfo::TPtr ev, const TActorContext &ctx) {
+bool TTxCoordinator::OnRenderAppHtmlPage(NMon::TEvRemoteHttpInfo::TPtr ev, const TActorContext &ctx) {
if (!Executor() || !Executor()->GetStats().IsActive)
- return false;
-
- if (!ev)
- return true;
-
- Execute(CreateTxMonitoring(ev), ctx);
- return true;
+ return false;
+
+ if (!ev)
+ return true;
+
+ Execute(CreateTxMonitoring(ev), ctx);
+ return true;
}
void TTxCoordinator::OnTabletStop(TEvTablet::TEvTabletStop::TPtr &ev, const TActorContext &ctx) {
@@ -401,8 +401,8 @@ void TTxCoordinator::OnTabletStop(TEvTablet::TEvTabletStop::TPtr &ev, const TAct
Stopping = true;
return TTabletExecutedFlat::OnTabletStop(ev, ctx);
-}
-
+}
+
void TTxCoordinator::OnStopGuardStarting(const TActorContext &ctx) {
auto processQueue = [&](auto &queue) {
while (TAutoPtr<TTransactionProposal> proposal = queue.Pop()) {
@@ -433,7 +433,7 @@ void TTxCoordinator::OnStopGuardComplete(const TActorContext &ctx) {
}
IActor* CreateFlatTxCoordinator(const TActorId &tablet, TTabletStorageInfo *info) {
- return new NFlatTxCoordinator::TTxCoordinator(info, tablet);
+ return new NFlatTxCoordinator::TTxCoordinator(info, tablet);
}
}
diff --git a/ydb/core/tx/coordinator/coordinator_impl.h b/ydb/core/tx/coordinator/coordinator_impl.h
index 151c61e33be..39018aff1e7 100644
--- a/ydb/core/tx/coordinator/coordinator_impl.h
+++ b/ydb/core/tx/coordinator/coordinator_impl.h
@@ -19,14 +19,14 @@
#include <library/cpp/actors/core/hfunc.h>
#include <util/generic/hash_set.h>
-#include <util/stream/file.h>
+#include <util/stream/file.h>
#include <util/stream/zlib.h>
-
+
#include <algorithm>
namespace NKikimr {
-namespace NFlatTxCoordinator {
-
+namespace NFlatTxCoordinator {
+
typedef ui64 TStepId;
typedef ui64 TTabletId;
typedef ui64 TTxId;
@@ -137,36 +137,36 @@ struct TMediatorConfirmations {
IActor* CreateTxCoordinatorMediatorQueue(const TActorId &owner, ui64 coordinator, ui64 mediator, ui64 coordinatorGeneration);
-using NTabletFlatExecutor::TTabletExecutedFlat;
+using NTabletFlatExecutor::TTabletExecutedFlat;
using NTabletFlatExecutor::ITransaction;
-using NTabletFlatExecutor::TTransactionBase;
-using NTabletFlatExecutor::TTransactionContext;
-
+using NTabletFlatExecutor::TTransactionBase;
+using NTabletFlatExecutor::TTransactionContext;
+
//#define COORDINATOR_LOG_TO_FILE
#ifdef COORDINATOR_LOG_TO_FILE
-#define FLOG_LOG_S_SAMPLED_BY(actorCtxOrSystem, priority, component, sampleBy, stream) \
-do { \
- ::NActors::NLog::TSettings *mSettings = (::NActors::NLog::TSettings*)((actorCtxOrSystem).LoggerSettings()); \
- ::NActors::NLog::EPriority mPriority = (::NActors::NLog::EPriority)(priority); \
- ::NActors::NLog::EComponent mComponent = (::NActors::NLog::EComponent)(component); \
- if (mSettings && mSettings->Satisfies(mPriority, mComponent, sampleBy)) { \
- TStringBuilder logStringBuilder; \
- logStringBuilder << stream; \
+#define FLOG_LOG_S_SAMPLED_BY(actorCtxOrSystem, priority, component, sampleBy, stream) \
+do { \
+ ::NActors::NLog::TSettings *mSettings = (::NActors::NLog::TSettings*)((actorCtxOrSystem).LoggerSettings()); \
+ ::NActors::NLog::EPriority mPriority = (::NActors::NLog::EPriority)(priority); \
+ ::NActors::NLog::EComponent mComponent = (::NActors::NLog::EComponent)(component); \
+ if (mSettings && mSettings->Satisfies(mPriority, mComponent, sampleBy)) { \
+ TStringBuilder logStringBuilder; \
+ logStringBuilder << stream; \
Self->DebugLog << (TString)logStringBuilder << Endl; \
- } \
-} while(0) \
-/**/
+ } \
+} while(0) \
+/**/
#else
#define FLOG_LOG_S_SAMPLED_BY(actorCtxOrSystem, priority, component, sampleBy, stream) \
LOG_LOG_S_SAMPLED_BY(actorCtxOrSystem, priority, component, sampleBy, stream)
#endif
-
-#define FLOG_LOG_S(actorCtxOrSystem, priority, component, stream) FLOG_LOG_S_SAMPLED_BY(actorCtxOrSystem, priority, component, 0ull, stream)
-#define FLOG_DEBUG_S(actorCtxOrSystem, component, stream) FLOG_LOG_S(actorCtxOrSystem, NActors::NLog::PRI_DEBUG, component, stream)
-
-
-class TTxCoordinator : public TActor<TTxCoordinator>, public TTabletExecutedFlat {
+
+#define FLOG_LOG_S(actorCtxOrSystem, priority, component, stream) FLOG_LOG_S_SAMPLED_BY(actorCtxOrSystem, priority, component, 0ull, stream)
+#define FLOG_DEBUG_S(actorCtxOrSystem, component, stream) FLOG_LOG_S(actorCtxOrSystem, NActors::NLog::PRI_DEBUG, component, stream)
+
+
+class TTxCoordinator : public TActor<TTxCoordinator>, public TTabletExecutedFlat {
struct TEvPrivate {
enum EEv {
@@ -213,7 +213,7 @@ class TTxCoordinator : public TActor<TTxCoordinator>, public TTabletExecutedFlat
TAutoPtr<TQ, TQ::TPtrCleanDestructor> Unsorted;
- TSlot& LowSlot(TStepId step) {
+ TSlot& LowSlot(TStepId step) {
TMap<TStepId, TSlot>::iterator it = Low.find(step);
if (it != Low.end())
return it->second;
@@ -230,13 +230,13 @@ class TTxCoordinator : public TActor<TTxCoordinator>, public TTabletExecutedFlat
struct TTxInit;
struct TTxRestoreTransactions;
struct TTxConfigure;
- struct TTxSchema;
- struct TTxUpgrade;
+ struct TTxSchema;
+ struct TTxUpgrade;
struct TTxPlanStep;
struct TTxRestartMediatorQueue;
struct TTxMediatorConfirmations;
- struct TTxConsistencyCheck;
- struct TTxMonitoring;
+ struct TTxConsistencyCheck;
+ struct TTxMonitoring;
struct TTxStopGuard;
struct TTxAcquireReadStep;
@@ -289,16 +289,16 @@ class TTxCoordinator : public TActor<TTxCoordinator>, public TTabletExecutedFlat
{}
};
- struct TTransaction {
- TStepId PlanOnStep;
+ struct TTransaction {
+ TStepId PlanOnStep;
THashSet<TTabletId> AffectedSet;
THashMap<TTabletId, THashSet<TTabletId>> UnconfirmedAffectedSet;
-
- TTransaction()
- : PlanOnStep(0)
- {}
- };
-
+
+ TTransaction()
+ : PlanOnStep(0)
+ {}
+ };
+
struct TAcquireReadStepRequest {
TActorId Sender;
ui64 Cookie;
@@ -327,41 +327,41 @@ class TTxCoordinator : public TActor<TTxCoordinator>, public TTabletExecutedFlat
};
public:
- struct Schema : NIceDb::Schema {
+ struct Schema : NIceDb::Schema {
static const ui32 CurrentVersion;
- struct Transaction : Table<0> {
+ struct Transaction : Table<0> {
struct ID : Column<0, NScheme::NTypeIds::Uint64> {}; // PK
struct Plan : Column<1, NScheme::NTypeIds::Uint64> {};
struct AffectedSet : Column<2, NScheme::NTypeIds::String> { using Type = TVector<TTabletId>; };
- using TKey = TableKey<ID>;
- using TColumns = TableColumns<ID, Plan, AffectedSet>;
+ using TKey = TableKey<ID>;
+ using TColumns = TableColumns<ID, Plan, AffectedSet>;
};
- struct AffectedSet : Table<4> {
+ struct AffectedSet : Table<4> {
struct MediatorID : Column<1, NScheme::NTypeIds::Uint64> {};
- struct TransactionID : Column<2, Transaction::ID::ColumnType> {};
+ struct TransactionID : Column<2, Transaction::ID::ColumnType> {};
struct DataShardID : Column<3, NScheme::NTypeIds::Uint64> {};
-
- using TKey = TableKey<MediatorID, TransactionID, DataShardID>;
- using TColumns = TableColumns<MediatorID, TransactionID, DataShardID>;
+
+ using TKey = TableKey<MediatorID, TransactionID, DataShardID>;
+ using TColumns = TableColumns<MediatorID, TransactionID, DataShardID>;
};
- struct State : Table<2> {
- enum EKeyType {
- KeyLastPlanned,
- DatabaseVersion,
+ struct State : Table<2> {
+ enum EKeyType {
+ KeyLastPlanned,
+ DatabaseVersion,
AcquireReadStepLast,
- };
-
+ };
+
struct StateKey : Column<0, NScheme::NTypeIds::Uint64> { using Type = EKeyType; }; // PK
struct StateValue : Column<1, NScheme::NTypeIds::Uint64> {};
-
- using TKey = TableKey<StateKey>;
- using TColumns = TableColumns<StateKey, StateValue>;
+
+ using TKey = TableKey<StateKey>;
+ using TColumns = TableColumns<StateKey, StateValue>;
};
-
+
struct DomainConfiguration : Table<5> {
struct Version : Column<1, NScheme::NTypeIds::Uint64> {};
struct Mediators : Column<2, NScheme::NTypeIds::String> { using Type = TVector<TTabletId>; };
@@ -374,7 +374,7 @@ public:
using TTables = SchemaTables<Transaction, AffectedSet, State, DomainConfiguration>;
};
-
+
private:
struct TCoordinatorMonCounters {
TIntrusivePtr<NMonitoring::TDynamicCounters> Coordinator;
@@ -414,17 +414,17 @@ private:
TMediatorsIndex Mediators;
typedef THashMap<TTxId, TTransaction> TTransactions;
- TTransactions Transactions;
-
+ TTransactions Transactions;
+
bool Stopping = false;
#ifdef COORDINATOR_LOG_TO_FILE
- // HACK
+ // HACK
TString DebugName;
TFixedBufferFileOutput DebugLogFile;
TZLibCompress DebugLog;
#endif
-
+
void Die(const TActorContext &ctx) override {
for (TMediatorsIndex::iterator it = Mediators.begin(), end = Mediators.end(); it != end; ++it) {
TMediator &x = it->second;
@@ -475,8 +475,8 @@ private:
void Handle(TEvTxCoordinator::TEvCoordinatorConfirmPlan::TPtr &ev, const TActorContext &ctx);
void Handle(TEvSubDomain::TEvConfigure::TPtr &ev, const TActorContext &ctx);
- void Handle(TEvents::TEvPoisonPill::TPtr& ev, const TActorContext& ctx);
-
+ void Handle(TEvents::TEvPoisonPill::TPtr& ev, const TActorContext& ctx);
+
void DoConfiguration(const TEvSubDomain::TEvConfigure &ev, const TActorContext &ctx, const TActorId &ackTo = TActorId());
void Sync(ui64 mediator, const TActorContext &ctx);
@@ -488,7 +488,7 @@ private:
bool RestoreMediatorInfo(TTabletId mediatorId, TVector<TAutoPtr<TMediatorStep>> &planned, TTransactionContext &txc, /*TKeyBuilder &kb, */THashMap<TTxId,TVector<TTabletId>> &pushToAffected) const;
void TryInitMonCounters(const TActorContext &ctx);
- bool OnRenderAppHtmlPage(NMon::TEvRemoteHttpInfo::TPtr ev, const TActorContext &ctx) override;
+ bool OnRenderAppHtmlPage(NMon::TEvRemoteHttpInfo::TPtr ev, const TActorContext &ctx) override;
void OnTabletStop(TEvTablet::TEvTabletStop::TPtr &ev, const TActorContext &ctx) override;
void OnStopGuardStarting(const TActorContext &ctx);
@@ -533,7 +533,7 @@ public:
HFunc(TEvents::TEvPoisonPill, Handle)
IgnoreFunc(TEvTabletPipe::TEvServerConnected)
IgnoreFunc(TEvTabletPipe::TEvServerDisconnected))
-
+
STFUNC_TABLET_IGN(StateBroken,)
};
diff --git a/ydb/core/tx/coordinator/mediator_queue.cpp b/ydb/core/tx/coordinator/mediator_queue.cpp
index dcc7969ed9c..9b3955fa1bf 100644
--- a/ydb/core/tx/coordinator/mediator_queue.cpp
+++ b/ydb/core/tx/coordinator/mediator_queue.cpp
@@ -7,7 +7,7 @@
#include <library/cpp/actors/core/hfunc.h>
namespace NKikimr {
-namespace NFlatTxCoordinator {
+namespace NFlatTxCoordinator {
class TTxCoordinatorMediatorQueue : public TActorBootstrapped<TTxCoordinatorMediatorQueue> {
const TActorId Owner;
@@ -73,7 +73,7 @@ class TTxCoordinatorMediatorQueue : public TActorBootstrapped<TTxCoordinatorMedi
<< " HANDLE EvMediatorQueueStep step# " << msg->Step->Step);
if (msg->GenCookie == GenCookie && PipeClient) {
- const NFlatTxCoordinator::TMediatorStep &step = *msg->Step;
+ const NFlatTxCoordinator::TMediatorStep &step = *msg->Step;
LOG_DEBUG(ctx, NKikimrServices::TX_COORDINATOR_PRIVATE, "[%" PRIu64 "] to [%" PRIu64 "], step [%" PRIu64 "]", Coordinator, Mediator, step.Step);
@@ -127,9 +127,9 @@ class TTxCoordinatorMediatorQueue : public TActorBootstrapped<TTxCoordinatorMedi
if (!Confirmations)
Confirmations.Reset(new TMediatorConfirmations(Mediator));
- const TTabletId tabletId = record.GetTabletId();
+ const TTabletId tabletId = record.GetTabletId();
for (const auto txid : record.GetTxId()) {
- Confirmations->Acks[txid].insert(tabletId);
+ Confirmations->Acks[txid].insert(tabletId);
}
}
@@ -173,8 +173,8 @@ public:
};
IActor* CreateTxCoordinatorMediatorQueue(const TActorId &owner, ui64 coordinator, ui64 mediator, ui64 coordinatorGeneration) {
- return new NFlatTxCoordinator::TTxCoordinatorMediatorQueue(owner, coordinator, mediator, coordinatorGeneration);
+ return new NFlatTxCoordinator::TTxCoordinatorMediatorQueue(owner, coordinator, mediator, coordinatorGeneration);
}
}
-}
+}
diff --git a/ydb/core/tx/datashard/datashard.cpp b/ydb/core/tx/datashard/datashard.cpp
index 54e305a686c..d86568b4a15 100644
--- a/ydb/core/tx/datashard/datashard.cpp
+++ b/ydb/core/tx/datashard/datashard.cpp
@@ -97,7 +97,7 @@ TDataShard::TDataShard(const TActorId &tablet, TTabletStorageInfo *info)
, PipeClientCacheConfig(new NTabletPipe::TBoundedClientCacheConfig())
, PipeClientCache(NTabletPipe::CreateBoundedClientCache(PipeClientCacheConfig, GetPipeClientConfig()))
, ResendReadSetPipeTracker(*PipeClientCache)
- , SchemeShardPipeRetryPolicy({})
+ , SchemeShardPipeRetryPolicy({})
, PathOwnerId(INVALID_TABLET_ID)
, CurrentSchemeShardId(INVALID_TABLET_ID)
, LastKnownMediator(INVALID_TABLET_ID)
@@ -156,12 +156,12 @@ TDataShard::TDataShard(const TActorId &tablet, TTabletStorageInfo *info)
NTabletPipe::TClientConfig TDataShard::GetPipeClientConfig() {
NTabletPipe::TClientConfig config;
config.CheckAliveness = true;
- config.RetryPolicy = {
- .RetryLimitCount = 30,
- .MinRetryTime = TDuration::MilliSeconds(10),
- .MaxRetryTime = TDuration::MilliSeconds(500),
- .BackoffMultiplier = 2,
- };
+ config.RetryPolicy = {
+ .RetryLimitCount = 30,
+ .MinRetryTime = TDuration::MilliSeconds(10),
+ .MaxRetryTime = TDuration::MilliSeconds(500),
+ .BackoffMultiplier = 2,
+ };
return config;
}
diff --git a/ydb/core/tx/datashard/datashard__cleanup_borrowed.cpp b/ydb/core/tx/datashard/datashard__cleanup_borrowed.cpp
index 48c7c00c706..c53faa1c603 100644
--- a/ydb/core/tx/datashard/datashard__cleanup_borrowed.cpp
+++ b/ydb/core/tx/datashard/datashard__cleanup_borrowed.cpp
@@ -28,11 +28,11 @@ public:
{ }
void Bootstrap(const TActorContext& ctx) {
- NTabletPipe::TClientConfig config({
- .RetryLimitCount = 5,
- .MinRetryTime = TDuration::MilliSeconds(10),
- .MaxRetryTime = TDuration::MilliSeconds(100)
- });
+ NTabletPipe::TClientConfig config({
+ .RetryLimitCount = 5,
+ .MinRetryTime = TDuration::MilliSeconds(10),
+ .MaxRetryTime = TDuration::MilliSeconds(100)
+ });
config.CheckAliveness = true;
for (const auto& kv : BorrowedParts) {
diff --git a/ydb/core/tx/datashard/datashard__init.cpp b/ydb/core/tx/datashard/datashard__init.cpp
index 29ed2acc4a1..dc12c49959b 100644
--- a/ydb/core/tx/datashard/datashard__init.cpp
+++ b/ydb/core/tx/datashard/datashard__init.cpp
@@ -210,7 +210,7 @@ bool TDataShard::TTxInit::ReadEverything(TTransactionContext &txc) {
{ // Reads user tables metadata
Self->TableInfos.clear(); // For idempotency
- auto rowset = db.Table<Schema::UserTables>().GreaterOrEqual(0).Select(); // TODO[serxa]: this should be Range() but it is not working right now
+ auto rowset = db.Table<Schema::UserTables>().GreaterOrEqual(0).Select(); // TODO[serxa]: this should be Range() but it is not working right now
if (!rowset.IsReady())
return false;
while (!rowset.EndOfSet()) {
@@ -512,7 +512,7 @@ public:
Schema::SchemaTables<Schema::SchemaOperations>::Materialize(txc.DB, NIceDb::EMaterializationMode::NonExisting);
Schema::SchemaTables<Schema::ScanProgress>::Materialize(txc.DB, NIceDb::EMaterializationMode::NonExisting);
} else {
- db.Materialize<Schema>();
+ db.Materialize<Schema>();
}
if (isCreate) {
diff --git a/ydb/core/tx/datashard/datashard_impl.h b/ydb/core/tx/datashard/datashard_impl.h
index d78c64fbfc5..11313474f80 100644
--- a/ydb/core/tx/datashard/datashard_impl.h
+++ b/ydb/core/tx/datashard/datashard_impl.h
@@ -438,14 +438,14 @@ class TDataShard
};
};
- struct Schema : NIceDb::Schema {
+ struct Schema : NIceDb::Schema {
struct Sys : Table<1> {
struct Id : Column<1, NScheme::NTypeIds::Uint64> {};
struct Bytes : Column<2, NScheme::NTypeIds::String> {};
struct Uint64 : Column<3, NScheme::NTypeIds::Uint64> {};
- using TKey = TableKey<Id>;
- using TColumns = TableColumns<Id, Bytes, Uint64>;
+ using TKey = TableKey<Id>;
+ using TColumns = TableColumns<Id, Bytes, Uint64>;
};
// Note that table UserTablesStats must be always updated with this one
@@ -457,7 +457,7 @@ class TDataShard
struct Schema : Column<5, NScheme::NTypeIds::String> { using Type = TString; };
struct ShadowTid : Column<6, NScheme::NTypeIds::Uint32> { static constexpr ui32 Default = 0; };
- using TKey = TableKey<Tid>;
+ using TKey = TableKey<Tid>;
using TColumns = TableColumns<Tid, LocalTid, Path, Name, Schema, ShadowTid>;
};
@@ -473,7 +473,7 @@ class TDataShard
struct Source : Column<9, NScheme::NTypeIds::ActorId> {};
struct Cookie : Column<10, NScheme::NTypeIds::Uint64> {};
- using TKey = TableKey<TxId>;
+ using TKey = TableKey<TxId>;
using TColumns = TableColumns<TxId, Kind, Flags, State, InRSRemain, MaxStep, ReceivedAt, Flags64, Source, Cookie>;
};
@@ -484,8 +484,8 @@ class TDataShard
struct Body : Column<4, NScheme::NTypeIds::String> { using Type = TString; };
struct Source : Column<5, NScheme::NTypeIds::ActorId> {};
- using TKey = TableKey<TxId, Origin>;
- using TColumns = TableColumns<TxId, Origin, InReadSetState, Body, Source>;
+ using TKey = TableKey<TxId, Origin>;
+ using TColumns = TableColumns<TxId, Origin, InReadSetState, Body, Source>;
};
struct InReadSets : Table<5> {
@@ -496,8 +496,8 @@ class TDataShard
struct Body : Column<5, NScheme::NTypeIds::String> { using Type = TString; };
struct BalanceTrackList : Column<6, NScheme::NTypeIds::String> { using Type = TString; };
- using TKey = TableKey<TxId, Origin, From, To>;
- using TColumns = TableColumns<TxId, Origin, From, To, Body, BalanceTrackList>;
+ using TKey = TableKey<TxId, Origin, From, To>;
+ using TColumns = TableColumns<TxId, Origin, From, To, Body, BalanceTrackList>;
};
struct OutReadSets : Table<6> {
@@ -510,24 +510,24 @@ class TDataShard
struct Body : Column<7, NScheme::NTypeIds::String> { using Type = TString; };
struct SplitTraj : Column<8, NScheme::NTypeIds::String> { using Type = TString; };
- using TKey = TableKey<Seqno>;
- using TColumns = TableColumns<Seqno, Step, TxId, Origin, From, To, Body, SplitTraj>;
+ using TKey = TableKey<Seqno>;
+ using TColumns = TableColumns<Seqno, Step, TxId, Origin, From, To, Body, SplitTraj>;
};
struct PlanQueue : Table<7> {
struct Step : Column<1, NScheme::NTypeIds::Uint64> {};
struct TxId : Column<2, NScheme::NTypeIds::Uint64> {};
- using TKey = TableKey<Step, TxId>;
- using TColumns = TableColumns<Step, TxId>;
+ using TKey = TableKey<Step, TxId>;
+ using TColumns = TableColumns<Step, TxId>;
};
struct DeadlineQueue : Table<8> {
struct MaxStep : Column<1, NScheme::NTypeIds::Uint64> {};
struct TxId : Column<2, NScheme::NTypeIds::Uint64> {};
- using TKey = TableKey<MaxStep, TxId>;
- using TColumns = TableColumns<MaxStep, TxId>;
+ using TKey = TableKey<MaxStep, TxId>;
+ using TColumns = TableColumns<MaxStep, TxId>;
};
struct SchemaOperations : Table<9> {
@@ -821,27 +821,27 @@ class TDataShard
static constexpr const char* ShadowTablePrefix = "__shadow__";
};
- inline static bool SysGetUi64(NIceDb::TNiceDb& db, ui64 row, ui64& value) {
+ inline static bool SysGetUi64(NIceDb::TNiceDb& db, ui64 row, ui64& value) {
auto rowset = db.Table<Schema::Sys>().Key(row).Select<Schema::Sys::Uint64>();
if (!rowset.IsReady())
return false;
if (rowset.IsValid())
- value = rowset.GetValue<Schema::Sys::Uint64>();
+ value = rowset.GetValue<Schema::Sys::Uint64>();
+ return true;
+ }
+
+ inline static bool SysGetUi64(NIceDb::TNiceDb& db, ui64 row, ui32& value) {
+ auto rowset = db.Table<Schema::Sys>().Key(row).Select<Schema::Sys::Uint64>();
+ if (!rowset.IsReady())
+ return false;
+ if (rowset.IsValid()) {
+ ui64 val = rowset.GetValue<Schema::Sys::Uint64>();
+ Y_VERIFY(val <= std::numeric_limits<ui32>::max());
+ value = static_cast<ui32>(val);
+ }
return true;
}
- inline static bool SysGetUi64(NIceDb::TNiceDb& db, ui64 row, ui32& value) {
- auto rowset = db.Table<Schema::Sys>().Key(row).Select<Schema::Sys::Uint64>();
- if (!rowset.IsReady())
- return false;
- if (rowset.IsValid()) {
- ui64 val = rowset.GetValue<Schema::Sys::Uint64>();
- Y_VERIFY(val <= std::numeric_limits<ui32>::max());
- value = static_cast<ui32>(val);
- }
- return true;
- }
-
inline static bool SysGetBool(NIceDb::TNiceDb& db, ui64 row, bool& value) {
auto rowset = db.Table<Schema::Sys>().Key(row).Select<Schema::Sys::Uint64>();
if (!rowset.IsReady())
@@ -1456,16 +1456,16 @@ private:
THashMap<ui64, TLoanReturnInfo> LoanReturns;
// part -> owner
THashMap<TLogoBlobID, ui64> LoanOwners;
- NTabletPipe::TClientRetryPolicy PipeRetryPolicy;
+ NTabletPipe::TClientRetryPolicy PipeRetryPolicy;
public:
explicit TLoanReturnTracker(ui64 myTabletId)
: MyTabletID(myTabletId)
- , PipeRetryPolicy{
- .RetryLimitCount = 20,
- .MinRetryTime = TDuration::MilliSeconds(10),
- .MaxRetryTime = TDuration::MilliSeconds(500),
- .BackoffMultiplier = 2}
+ , PipeRetryPolicy{
+ .RetryLimitCount = 20,
+ .MinRetryTime = TDuration::MilliSeconds(10),
+ .MaxRetryTime = TDuration::MilliSeconds(500),
+ .BackoffMultiplier = 2}
{}
TLoanReturnTracker(const TLoanReturnTracker&) = delete;
@@ -1646,12 +1646,12 @@ private:
public:
explicit TChangeSenderActivator(ui64 selfTabletId)
: Origin(selfTabletId)
- , PipeRetryPolicy{
- .RetryLimitCount = 20,
- .MinRetryTime = TDuration::MilliSeconds(10),
- .MaxRetryTime = TDuration::MilliSeconds(500),
- .BackoffMultiplier = 2
- }
+ , PipeRetryPolicy{
+ .RetryLimitCount = 20,
+ .MinRetryTime = TDuration::MilliSeconds(10),
+ .MaxRetryTime = TDuration::MilliSeconds(500),
+ .BackoffMultiplier = 2
+ }
{
}
@@ -1731,7 +1731,7 @@ private:
private:
const ui64 Origin;
- NTabletPipe::TClientRetryPolicy PipeRetryPolicy;
+ NTabletPipe::TClientRetryPolicy PipeRetryPolicy;
THashSet<ui64> Dst;
THashMap<ui64, TActorId> PipesToDstShards;
@@ -1889,7 +1889,7 @@ private:
TIntrusivePtr<NTabletPipe::TBoundedClientCacheConfig> PipeClientCacheConfig;
THolder<NTabletPipe::IClientCache> PipeClientCache;
TPipeTracker ResendReadSetPipeTracker;
- NTabletPipe::TClientRetryPolicy SchemeShardPipeRetryPolicy;
+ NTabletPipe::TClientRetryPolicy SchemeShardPipeRetryPolicy;
TActorId SchemeShardPipe; // For notifications about schema changes
TActorId StateReportPipe; // For notifications about shard state changes
ui64 PathOwnerId; // TabletID of the schmemeshard that allocated the TPathId(ownerId,localId)
@@ -2341,7 +2341,7 @@ protected:
return;
auto* resourceMetrics = Executor()->GetResourceMetrics();
-
+
for (const auto& t : TableInfos) {
ui64 tableId = t.first;
@@ -2380,9 +2380,9 @@ protected:
ev->Record.MutableTableStats()->SetRowReads(TabletCounters->Cumulative()[COUNTER_ENGINE_HOST_SELECT_ROW].Get());
ev->Record.MutableTableStats()->SetRangeReads(TabletCounters->Cumulative()[COUNTER_ENGINE_HOST_SELECT_RANGE].Get());
ev->Record.MutableTableStats()->SetRangeReadRows(TabletCounters->Cumulative()[COUNTER_ENGINE_HOST_SELECT_RANGE_ROWS].Get());
- if (resourceMetrics != nullptr) {
- resourceMetrics->Fill(*ev->Record.MutableTabletMetrics());
- }
+ if (resourceMetrics != nullptr) {
+ resourceMetrics->Fill(*ev->Record.MutableTabletMetrics());
+ }
ev->Record.MutableTableStats()->SetPartCount(ti.Stats.PartCount);
ev->Record.MutableTableStats()->SetSearchHeight(ti.Stats.SearchHeight);
diff --git a/ydb/core/tx/datashard/datashard_txs.h b/ydb/core/tx/datashard/datashard_txs.h
index 8ad4f7c3237..4a9ab008789 100644
--- a/ydb/core/tx/datashard/datashard_txs.h
+++ b/ydb/core/tx/datashard/datashard_txs.h
@@ -7,8 +7,8 @@
namespace NKikimr {
namespace NDataShard {
-using NTabletFlatExecutor::TTransactionContext;
-
+using NTabletFlatExecutor::TTransactionContext;
+
class TDataShard::TTxStopGuard : public NTabletFlatExecutor::TTransactionBase<TDataShard> {
public:
TTxStopGuard(TDataShard* ds)
diff --git a/ydb/core/tx/datashard/datashard_ut_common.cpp b/ydb/core/tx/datashard/datashard_ut_common.cpp
index 87de7b0cc43..d754f7ad0e2 100644
--- a/ydb/core/tx/datashard/datashard_ut_common.cpp
+++ b/ydb/core/tx/datashard/datashard_ut_common.cpp
@@ -1054,7 +1054,7 @@ void InitRoot(Tests::TServer::TPtr server,
auto tid = ChangeStateStorage(SchemeRoot, settings.Domain);
const TDomainsInfo::TDomain& domain = runtime.GetAppData().DomainsInfo->GetDomain(settings.Domain);
-
+
auto evTx = MakeHolder<TEvSchemeShard::TEvModifySchemeTransaction>(1, tid);
auto transaction = evTx->Record.AddTransaction();
transaction->SetOperationType(NKikimrSchemeOp::EOperationType::ESchemeOpAlterSubDomain);
@@ -1066,8 +1066,8 @@ void InitRoot(Tests::TServer::TPtr server,
auto* p = op->AddStoragePools();
p->SetKind(kind);
p->SetName(pool.GetName());
- }
-
+ }
+
runtime.SendToPipe(tid, sender, evTx.Release(), 0, GetPipeConfigWithRetries());
{
diff --git a/ydb/core/tx/datashard/datashard_ut_locks.cpp b/ydb/core/tx/datashard/datashard_ut_locks.cpp
index a58be1b021c..1d25c39f99d 100644
--- a/ydb/core/tx/datashard/datashard_ut_locks.cpp
+++ b/ydb/core/tx/datashard/datashard_ut_locks.cpp
@@ -600,7 +600,7 @@ void CheckLocksCacheUsage(bool waitForLocksStore) {
TAutoPtr<IEventHandle> handle;
NTabletPipe::TClientConfig pipeConfig;
- pipeConfig.RetryPolicy = NTabletPipe::TClientRetryPolicy::WithRetries();
+ pipeConfig.RetryPolicy = NTabletPipe::TClientRetryPolicy::WithRetries();
auto pipe = runtime.ConnectToPipe(ChangeStateStorage(SchemeRoot, serverSettings.Domain), sender, 0, pipeConfig);
// Create table with two shards.
diff --git a/ydb/core/tx/datashard/datashard_ut_minstep.cpp b/ydb/core/tx/datashard/datashard_ut_minstep.cpp
index 6bb0d896f9f..99d72b2e457 100644
--- a/ydb/core/tx/datashard/datashard_ut_minstep.cpp
+++ b/ydb/core/tx/datashard/datashard_ut_minstep.cpp
@@ -77,7 +77,7 @@ Y_UNIT_TEST_SUITE(TDataShardMinStepTest) {
auto sender = runtime.AllocateEdgeActor();
TAutoPtr<IEventHandle> handle;
- runtime.SetLogPriority(NKikimrServices::HIVE, NLog::PRI_DEBUG);
+ runtime.SetLogPriority(NKikimrServices::HIVE, NLog::PRI_DEBUG);
runtime.SetLogPriority(NKikimrServices::TX_DATASHARD, NLog::PRI_DEBUG);
runtime.SetLogPriority(NKikimrServices::FLAT_TX_SCHEMESHARD, NLog::PRI_NOTICE);
runtime.SetLogPriority(NKikimrServices::TX_COORDINATOR, NLog::PRI_TRACE);
diff --git a/ydb/core/tx/mediator/execute_queue.cpp b/ydb/core/tx/mediator/execute_queue.cpp
index 8358c1f4826..07740e9f826 100644
--- a/ydb/core/tx/mediator/execute_queue.cpp
+++ b/ydb/core/tx/mediator/execute_queue.cpp
@@ -23,7 +23,7 @@ namespace NTxMediator {
TTimeCastBuckets BucketSelector;
TVector<TBucket> Buckets;
- TBucket& SelectBucket(TTabletId tablet) {
+ TBucket& SelectBucket(TTabletId tablet) {
const ui32 bucketIdx = BucketSelector.Select(tablet);
Y_VERIFY_DEBUG(bucketIdx < Buckets.size());
return Buckets[bucketIdx];
@@ -66,7 +66,7 @@ namespace NTxMediator {
TEvTxMediator::TEvCommitStep *msg = ev->Get();
TMediateStep *step = msg->MediateStep.Get();
- const ui32 totalCoordinators = step->Steps.size();
+ const ui32 totalCoordinators = step->Steps.size();
LOG_DEBUG_S(ctx, NKikimrServices::TX_MEDIATOR_EXEC_QUEUE, "Actor# " << ctx.SelfID.ToString()
<< " MediatorId# " << MediatorId << " HANDLE TEvCommitStep " << step->ToString() << " marker# M1");
@@ -89,16 +89,16 @@ namespace NTxMediator {
const ui64 tttsize = coord.TabletsToTransaction.size();
while (readPos < tttsize) {
- const std::pair<TTabletId, std::size_t> &x = coord.TabletsToTransaction[readPos];
+ const std::pair<TTabletId, std::size_t> &x = coord.TabletsToTransaction[readPos];
if (x.first != activeTablet)
break;
- currentTx.emplace_back(coord.Transactions[x.second]);
+ currentTx.emplace_back(coord.Transactions[x.second]);
++readPos;
}
if (readPos < tttsize) {
- const std::pair<TTabletId, std::size_t> &x = coord.TabletsToTransaction[readPos];
+ const std::pair<TTabletId, std::size_t> &x = coord.TabletsToTransaction[readPos];
if (x.first < lookupTablet)
lookupTablet = x.first;
}
@@ -132,7 +132,7 @@ namespace NTxMediator {
Sort(step->TabletsToTransaction.begin(), step->TabletsToTransaction.end(), TCoordinatorStep::TabletToTransactionCmp());
TVector<TTx> currentTx;
- TTabletId activeTablet = 0;
+ TTabletId activeTablet = 0;
for (TVector<std::pair<TTabletId, std::size_t>>::const_iterator it = step->TabletsToTransaction.begin(), end = step->TabletsToTransaction.end(); it != end; ++it) {
if (activeTablet != it->first) {
@@ -142,7 +142,7 @@ namespace NTxMediator {
currentTx.clear();
}
- currentTx.emplace_back(step->Transactions[it->second]);
+ currentTx.emplace_back(step->Transactions[it->second]);
currentTx.back().AckTo = ackTo;
}
diff --git a/ydb/core/tx/mediator/mediator.cpp b/ydb/core/tx/mediator/mediator.cpp
index 0c0fc3fc902..0fbd44403c0 100644
--- a/ydb/core/tx/mediator/mediator.cpp
+++ b/ydb/core/tx/mediator/mediator.cpp
@@ -10,7 +10,7 @@ namespace NTxMediator {
: Step(record.GetStep())
, PrevStep(record.GetPrevStep())
{
- const std::size_t txsize = record.TransactionsSize();
+ const std::size_t txsize = record.TransactionsSize();
// todo: save body as-is, without any processing
// and defer parsing and per-tablet mapping for latter stage, when we could merge all selected steps
@@ -19,16 +19,16 @@ namespace NTxMediator {
Transactions.reserve(txsize);
TabletsToTransaction.reserve(record.GetTotalTxAffectedEntries());
- for (std::size_t i = 0; i != txsize; ++i) {
+ for (std::size_t i = 0; i != txsize; ++i) {
const NKikimrTx::TCoordinatorTransaction &c = record.GetTransactions(i);
- Transactions.emplace_back(
+ Transactions.emplace_back(
c.HasModerator() ? c.GetModerator() : 0,
c.GetTxId()
- );
+ );
for (ui32 tabi = 0, tabe = c.GetAffectedSet().size(); tabi != tabe; ++tabi)
- TabletsToTransaction.emplace_back(c.GetAffectedSet(tabi), i);
+ TabletsToTransaction.emplace_back(c.GetAffectedSet(tabi), i);
}
}
diff --git a/ydb/core/tx/mediator/mediator_impl.h b/ydb/core/tx/mediator/mediator_impl.h
index 663b8eb8530..c98bd4246b0 100644
--- a/ydb/core/tx/mediator/mediator_impl.h
+++ b/ydb/core/tx/mediator/mediator_impl.h
@@ -20,23 +20,23 @@
namespace NKikimr {
namespace NTxMediator {
- using TStepId = ui64;
- using TTxId = ui64;
- using TTabletId = ui64;
-
+ using TStepId = ui64;
+ using TTxId = ui64;
+ using TTabletId = ui64;
+
struct TTx {
// transaction body
ui64 Moderator;
- TTxId TxId;
+ TTxId TxId;
TActorId AckTo;
- TTx(ui64 moderator, TTxId txid)
+ TTx(ui64 moderator, TTxId txid)
: Moderator(moderator)
, TxId(txid)
, AckTo() // must be updated before commit
- {
- Y_VERIFY(TxId != 0);
- }
+ {
+ Y_VERIFY(TxId != 0);
+ }
struct TCmpOrderId {
bool operator()(const TTx &left, const TTx &right) const noexcept {
@@ -55,15 +55,15 @@ namespace NTxMediator {
};
struct TCoordinatorStep {
- const TStepId Step;
- const TStepId PrevStep;
+ const TStepId Step;
+ const TStepId PrevStep;
TVector<TTx> Transactions;
TVector<std::pair<TTabletId, std::size_t>> TabletsToTransaction; // tablet -> tx index in Transactions
struct TabletToTransactionCmp {
- bool operator()(const std::pair<TTabletId, std::size_t> &left, const std::pair<TTabletId, std::size_t> &right) const {
+ bool operator()(const std::pair<TTabletId, std::size_t> &left, const std::pair<TTabletId, std::size_t> &right) const {
return left.first < right.first;
}
};
@@ -85,7 +85,7 @@ namespace NTxMediator {
str << "TabletsToTransaction: {";
for (size_t i = 0; i < TabletsToTransaction.size(); ++i) {
str << "{tablet# " << TabletsToTransaction[i].first;
- str << " txid# " << Transactions[TabletsToTransaction[i].second].TxId;
+ str << " txid# " << Transactions[TabletsToTransaction[i].second].TxId;
str << "}";
}
str << "}";
@@ -96,12 +96,12 @@ namespace NTxMediator {
};
struct TMediateStep {
- TStepId From;
- TStepId To;
+ TStepId From;
+ TStepId To;
TVector<TAutoPtr<TCoordinatorStep>> Steps;
- TMediateStep(TStepId from, TStepId to)
+ TMediateStep(TStepId from, TStepId to)
: From(from)
, To(to)
{}
@@ -124,9 +124,9 @@ namespace NTxMediator {
}
struct TEvTxMediator {
- using TTabletId = NTxMediator::TTabletId;
- using TStepId = NTxMediator::TStepId;
-
+ using TTabletId = NTxMediator::TTabletId;
+ using TStepId = NTxMediator::TStepId;
+
enum EEv {
EvCommitStep = EventSpaceBegin(TKikimrEvents::ES_TX_MEDIATOR),
EvRequestLostAcks,
@@ -177,8 +177,8 @@ struct TEvTxMediator {
// just reschedule command, actual transport is over command queue
struct TEvCommitTabletStep : public TEventLocal<TEvCommitTabletStep, EvCommitTabletStep> {
- const TStepId Step;
- const TTabletId TabletId;
+ const TStepId Step;
+ const TTabletId TabletId;
TVector<NTxMediator::TTx> Transactions; // todo: inplace placing
TEvCommitTabletStep(TStepId step, TTabletId tabletId, TVector<NTxMediator::TTx> &transactions)
@@ -201,9 +201,9 @@ struct TEvTxMediator {
};
struct TEvStepPlanComplete : public TEventLocal<TEvStepPlanComplete, EvStepPlanComplete> {
- const TStepId Step;
+ const TStepId Step;
- TEvStepPlanComplete(TStepId step)
+ TEvStepPlanComplete(TStepId step)
: Step(step)
{}
@@ -216,8 +216,8 @@ struct TEvTxMediator {
};
struct TEvOoOTabletStep : public TEventLocal<TEvOoOTabletStep, EvOoOTabletStep> {
- const TStepId Step;
- const TTabletId TabletId;
+ const TStepId Step;
+ const TTabletId TabletId;
TVector<NTxMediator::TTx> Transactions;
TEvOoOTabletStep(TStepId step, TTabletId tabletId, TVector<NTxMediator::TTx> &transactions)
diff --git a/ydb/core/tx/mediator/tablet_queue.cpp b/ydb/core/tx/mediator/tablet_queue.cpp
index 6459f0f73c3..b28179517ca 100644
--- a/ydb/core/tx/mediator/tablet_queue.cpp
+++ b/ydb/core/tx/mediator/tablet_queue.cpp
@@ -20,10 +20,10 @@ namespace NTxMediator {
class TTxMediatorTabletQueue : public TActor<TTxMediatorTabletQueue> {
struct TStepEntry {
- const TStepId Step;
+ const TStepId Step;
ui64 RefCounter;
- TStepEntry(TStepId step)
+ TStepEntry(TStepId step)
: Step(step)
, RefCounter(0)
{}
@@ -72,8 +72,8 @@ class TTxMediatorTabletQueue : public TActor<TTxMediatorTabletQueue> {
TAutoPtr<NTabletPipe::IClientCache> Pipes;
- TStepId AcceptedStep;
- TStepId CommitedStep;
+ TStepId AcceptedStep;
+ TStepId CommitedStep;
TStepEntry *ActiveStep;
THashSet<TActorId> TimecastWatches;
@@ -135,8 +135,8 @@ class TTxMediatorTabletQueue : public TActor<TTxMediatorTabletQueue> {
void Handle(TEvTxMediator::TEvCommitTabletStep::TPtr &ev, const TActorContext &ctx) {
TEvTxMediator::TEvCommitTabletStep *msg = ev->Get();
- const TStepId step = msg->Step;
- const TTabletId tablet = msg->TabletId;
+ const TStepId step = msg->Step;
+ const TTabletId tablet = msg->TabletId;
LOG_DEBUG_S(ctx, NKikimrServices::TX_MEDIATOR_TABLETQUEUE, "Actor# " << ctx.SelfID.ToString()
<< " Mediator# " << Mediator << " HANDLE " << msg->ToString() << " marker# M4");
@@ -169,8 +169,8 @@ class TTxMediatorTabletQueue : public TActor<TTxMediatorTabletQueue> {
void Handle(TEvTxMediator::TEvOoOTabletStep::TPtr &ev, const TActorContext &ctx) {
TEvTxMediator::TEvOoOTabletStep *msg = ev->Get();
- const TStepId step = msg->Step;
- const TTabletId tablet = msg->TabletId;
+ const TStepId step = msg->Step;
+ const TTabletId tablet = msg->TabletId;
LOG_DEBUG_S(ctx, NKikimrServices::TX_MEDIATOR_TABLETQUEUE, "Actor# " << ctx.SelfID.ToString()
<< " Mediator# " << Mediator << " HANDLE " << msg->ToString());
@@ -185,7 +185,7 @@ class TTxMediatorTabletQueue : public TActor<TTxMediatorTabletQueue> {
void Handle(TEvTabletPipe::TEvClientConnected::TPtr &ev, const TActorContext &ctx) {
const TEvTabletPipe::TEvClientConnected *msg = ev->Get();
- const TTabletId tablet = msg->TabletId;
+ const TTabletId tablet = msg->TabletId;
LOG_DEBUG_S(ctx, NKikimrServices::TX_MEDIATOR_TABLETQUEUE, "Actor# " << ctx.SelfID.ToString()
<< " Mediator# " << Mediator << " HANDLE " << msg->ToString());
@@ -194,8 +194,8 @@ class TTxMediatorTabletQueue : public TActor<TTxMediatorTabletQueue> {
if (!Pipes->OnConnect(ev)) {
if (msg->Dead) {
- LOG_WARN_S(ctx, NKikimrServices::TX_MEDIATOR_TABLETQUEUE, "Actor# " << ctx.SelfID.ToString()
- << " Mediator# " << Mediator << " HANDLE TEvClientConnected(Dead=true)");
+ LOG_WARN_S(ctx, NKikimrServices::TX_MEDIATOR_TABLETQUEUE, "Actor# " << ctx.SelfID.ToString()
+ << " Mediator# " << Mediator << " HANDLE TEvClientConnected(Dead=true)");
while (TTabletEntry::TStep *sx = tabletEntry.Queue->Head()) {
tabletEntry.MergeOutOfOrder(sx);
AckOoO(tablet, sx->StepRef->Step, sx->Transactions, ctx);
@@ -221,7 +221,7 @@ class TTxMediatorTabletQueue : public TActor<TTxMediatorTabletQueue> {
void Handle(TEvTabletPipe::TEvClientDestroyed::TPtr &ev, const TActorContext &ctx) {
const TEvTabletPipe::TEvClientDestroyed *msg = ev->Get();
- const TTabletId tablet = msg->TabletId;
+ const TTabletId tablet = msg->TabletId;
LOG_DEBUG_S(ctx, NKikimrServices::TX_MEDIATOR_TABLETQUEUE, "Actor# " << ctx.SelfID.ToString()
<< " Mediator# " << Mediator << " HANDLE " << msg->ToString());
@@ -241,7 +241,7 @@ class TTxMediatorTabletQueue : public TActor<TTxMediatorTabletQueue> {
void Handle(TEvTxMediator::TEvStepPlanComplete::TPtr &ev, const TActorContext &ctx) {
const TEvTxMediator::TEvStepPlanComplete *msg = ev->Get();
- const TStepId step = msg->Step;
+ const TStepId step = msg->Step;
LOG_DEBUG_S(ctx, NKikimrServices::TX_MEDIATOR_TABLETQUEUE, "Actor# " << ctx.SelfID.ToString()
<< " Mediator# " << Mediator << " HANDLE " << msg->ToString());
@@ -256,8 +256,8 @@ class TTxMediatorTabletQueue : public TActor<TTxMediatorTabletQueue> {
void Handle(TEvTxProcessing::TEvPlanStepAccepted::TPtr &ev, const TActorContext &ctx) {
const NKikimrTx::TEvPlanStepAccepted &record = ev->Get()->Record;
- const TTabletId tablet = record.GetTabletId();
- const TStepId step = record.GetStep();
+ const TTabletId tablet = record.GetTabletId();
+ const TStepId step = record.GetStep();
LOG_DEBUG_S(ctx, NKikimrServices::TX_MEDIATOR_TABLETQUEUE, "Actor# " << ctx.SelfID.ToString()
<< " Mediator# " << Mediator << " HANDLE " << ev->Get()->ToString());
@@ -326,12 +326,12 @@ class TTxMediatorTabletQueue : public TActor<TTxMediatorTabletQueue> {
static NTabletPipe::TClientConfig GetPipeClientConfig() {
NTabletPipe::TClientConfig config;
config.CheckAliveness = true;
- config.RetryPolicy = {
- .RetryLimitCount = 30,
- .MinRetryTime = TDuration::MilliSeconds(10),
- .MaxRetryTime = TDuration::MilliSeconds(500),
- .BackoffMultiplier = 2,
- };
+ config.RetryPolicy = {
+ .RetryLimitCount = 30,
+ .MinRetryTime = TDuration::MilliSeconds(10),
+ .MaxRetryTime = TDuration::MilliSeconds(500),
+ .BackoffMultiplier = 2,
+ };
return config;
}
@@ -371,20 +371,20 @@ public:
};
TString yvector2str(const TVector<TTx>& v) {
- TStringStream stream;
- stream << '{';
- for (auto it = v.begin(); it != v.end(); ++it) {
- if (it != v.begin())
- stream << ',';
- stream << it->TxId;
- }
- stream << '}';
- return stream.Str();
-}
-//
-
+ TStringStream stream;
+ stream << '{';
+ for (auto it = v.begin(); it != v.end(); ++it) {
+ if (it != v.begin())
+ stream << ',';
+ stream << it->TxId;
+ }
+ stream << '}';
+ return stream.Str();
+}
+//
+
void TTxMediatorTabletQueue::TTabletEntry::MergeOutOfOrder(TStep *sx) {
- const TStepId step = sx->StepRef->Step;
+ const TStepId step = sx->StepRef->Step;
const auto ox = OutOfOrder.find(step);
if (ox != OutOfOrder.end()) {
const TVector<TTx> &o = ox->second;
@@ -394,7 +394,7 @@ void TTxMediatorTabletQueue::TTabletEntry::MergeOutOfOrder(TStep *sx) {
yvector2str(sx->Transactions).c_str()
);
Y_VERIFY_DEBUG(IsSorted(o.begin(), o.end(), TTx::TCmpOrderId()), "%s", yvector2str(o).c_str());
- //
+ //
// ok, now merge sorted arrays replacing ack-to
TVector<TTx>::iterator planIt = sx->Transactions.begin();
TVector<TTx>::iterator planEnd = sx->Transactions.end();
@@ -424,7 +424,7 @@ void TTxMediatorTabletQueue::TTabletEntry::MergeToOutOfOrder(TStepId step, TVect
old.swap(current);
Y_VERIFY_DEBUG(IsSorted(old.begin(), old.end(), TTx::TCmpOrderId()), "%s", yvector2str(old).c_str());
Y_VERIFY_DEBUG(IsSorted(update.begin(), update.end(), TTx::TCmpOrderId()), "%s", yvector2str(update).c_str());
- //
+ //
// now merge old with update
TVector<TTx>::const_iterator oldIt = old.begin();
TVector<TTx>::const_iterator oldEnd = old.end();
@@ -432,14 +432,14 @@ void TTxMediatorTabletQueue::TTabletEntry::MergeToOutOfOrder(TStepId step, TVect
TVector<TTx>::const_iterator updEnd = update.end();
while (oldIt != oldEnd && updIt != updEnd) {
- if (oldIt->TxId < updIt->TxId) {
+ if (oldIt->TxId < updIt->TxId) {
current.push_back(*oldIt);
++oldIt;
- } else if (updIt->TxId < oldIt->TxId) {
- current.push_back(*updIt);
+ } else if (updIt->TxId < oldIt->TxId) {
+ current.push_back(*updIt);
++updIt;
} else {
- current.push_back(*updIt);
+ current.push_back(*updIt);
++updIt;
++oldIt;
}
@@ -449,7 +449,7 @@ void TTxMediatorTabletQueue::TTabletEntry::MergeToOutOfOrder(TStepId step, TVect
current.insert(current.end(), oldIt, oldEnd);
current.insert(current.end(), updIt, updEnd);
Y_VERIFY_DEBUG(IsSorted(current.begin(), current.end(), TTx::TCmpOrderId()), "%s", yvector2str(current).c_str());
- //
+ //
}
}
diff --git a/ydb/core/tx/scheme_board/cache.cpp b/ydb/core/tx/scheme_board/cache.cpp
index b05b67ab5e0..8e778a4a1d8 100644
--- a/ydb/core/tx/scheme_board/cache.cpp
+++ b/ydb/core/tx/scheme_board/cache.cpp
@@ -699,7 +699,7 @@ class TSchemeCache: public TMonitorableActor<TSchemeCache> {
Self.Drop();
- DomainDescription.Drop();
+ DomainDescription.Drop();
RtmrVolumeInfo.Drop();
KesusInfo.Drop();
SolomonVolumeInfo.Drop();
@@ -1339,19 +1339,19 @@ class TSchemeCache: public TMonitorableActor<TSchemeCache> {
switch (entryDesc.GetPathType()) {
case NKikimrSchemeOp::EPathTypeSubDomain:
Kind = TNavigate::KindSubdomain;
- FillInfo(Kind, DomainDescription, std::move(*pathDesc.MutableDomainDescription()));
+ FillInfo(Kind, DomainDescription, std::move(*pathDesc.MutableDomainDescription()));
break;
case NKikimrSchemeOp::EPathTypeExtSubDomain:
Kind = TNavigate::KindExtSubdomain;
- FillInfo(Kind, DomainDescription, std::move(*pathDesc.MutableDomainDescription()));
+ FillInfo(Kind, DomainDescription, std::move(*pathDesc.MutableDomainDescription()));
break;
case NKikimrSchemeOp::EPathTypeDir:
case NKikimrSchemeOp::EPathTypeBlockStoreVolume:
case NKikimrSchemeOp::EPathTypeFileStore:
Kind = TNavigate::KindPath;
- if (entryDesc.GetPathId() == entryDesc.GetParentPathId()) {
- FillInfo(Kind, DomainDescription, std::move(*pathDesc.MutableDomainDescription()));
- }
+ if (entryDesc.GetPathId() == entryDesc.GetParentPathId()) {
+ FillInfo(Kind, DomainDescription, std::move(*pathDesc.MutableDomainDescription()));
+ }
break;
case NKikimrSchemeOp::EPathTypeTable:
Kind = TNavigate::KindTable;
@@ -1670,7 +1670,7 @@ class TSchemeCache: public TMonitorableActor<TSchemeCache> {
entry.NotNullColumns = NotNullColumns;
entry.Indexes = Indexes;
entry.CdcStreams = CdcStreams;
- entry.DomainDescription = DomainDescription;
+ entry.DomainDescription = DomainDescription;
entry.RTMRVolumeInfo = RtmrVolumeInfo;
entry.KesusInfo = KesusInfo;
entry.SolomonVolumeInfo = SolomonVolumeInfo;
@@ -1906,7 +1906,7 @@ class TSchemeCache: public TMonitorableActor<TSchemeCache> {
// domain & path specific
TIntrusivePtr<TNavigate::TListNodeEntry> ListNodeEntry;
- TIntrusivePtr<TNavigate::TDomainDescription> DomainDescription;
+ TIntrusivePtr<TNavigate::TDomainDescription> DomainDescription;
// table specific
THashMap<ui32, TSysTables::TTableColumnInfo> Columns;
diff --git a/ydb/core/tx/scheme_cache/scheme_cache.cpp b/ydb/core/tx/scheme_cache/scheme_cache.cpp
index 558aa897221..5cf9a0b0d5e 100644
--- a/ydb/core/tx/scheme_cache/scheme_cache.cpp
+++ b/ydb/core/tx/scheme_cache/scheme_cache.cpp
@@ -115,8 +115,8 @@ TString TSchemeCacheRequest::TEntry::ToString(const NScheme::TTypeRegistry& type
out << " }";
return out;
-}
-
+}
+
TString TSchemeCacheRequest::ToString(const NScheme::TTypeRegistry& typeRegistry) const {
return TStringBuilder() << "{"
<< " ErrorCount: " << ErrorCount
diff --git a/ydb/core/tx/scheme_cache/scheme_cache.h b/ydb/core/tx/scheme_cache/scheme_cache.h
index 7df6f754cb9..26a07897a11 100644
--- a/ydb/core/tx/scheme_cache/scheme_cache.h
+++ b/ydb/core/tx/scheme_cache/scheme_cache.h
@@ -149,11 +149,11 @@ struct TSchemeCacheNavigate {
NKikimrSchemeOp::TDirEntry Info;
};
- struct TDomainDescription : public TAtomicRefCount<TDomainDescription> {
- EKind Kind = KindUnknown;
- NKikimrSubDomains::TDomainDescription Description;
- };
-
+ struct TDomainDescription : public TAtomicRefCount<TDomainDescription> {
+ EKind Kind = KindUnknown;
+ NKikimrSubDomains::TDomainDescription Description;
+ };
+
struct TPQGroupInfo : public TAtomicRefCount<TPQGroupInfo> {
EKind Kind = KindUnknown;
NKikimrSchemeOp::TPersQueueGroupDescription Description;
@@ -235,7 +235,7 @@ struct TSchemeCacheNavigate {
TVector<NKikimrSchemeOp::TCdcStreamDescription> CdcStreams;
// other
- TIntrusiveConstPtr<TDomainDescription> DomainDescription;
+ TIntrusiveConstPtr<TDomainDescription> DomainDescription;
TIntrusiveConstPtr<TPQGroupInfo> PQGroupInfo;
TIntrusiveConstPtr<TRtmrVolumeInfo> RTMRVolumeInfo;
TIntrusiveConstPtr<TKesusInfo> KesusInfo;
@@ -405,7 +405,7 @@ struct TEvTxProxySchemeCache {
EvInvalidateDistEntry, // unused
EvResolveKeySetResult,
EvNavigateKeySet,
- EvNavigateKeySetResult,
+ EvNavigateKeySetResult,
EvInvalidateTable,
EvInvalidateTableResult,
EvWatchPathId,
@@ -442,7 +442,7 @@ public:
using TEvBasic::TEvBasic;
};
- struct TEvNavigateKeySetResult : public TEvBasic<TEvNavigateKeySetResult, EvNavigateKeySetResult, NSchemeCache::TSchemeCacheNavigate> {
+ struct TEvNavigateKeySetResult : public TEvBasic<TEvNavigateKeySetResult, EvNavigateKeySetResult, NSchemeCache::TSchemeCacheNavigate> {
using TEvBasic::TEvBasic;
};
diff --git a/ydb/core/tx/schemeshard/schemeshard.h b/ydb/core/tx/schemeshard/schemeshard.h
index 9994f5c533c..d33173508ce 100644
--- a/ydb/core/tx/schemeshard/schemeshard.h
+++ b/ydb/core/tx/schemeshard/schemeshard.h
@@ -12,8 +12,8 @@
#include <library/cpp/deprecated/enum_codegen/enum_codegen.h>
-#include "schemeshard_identificators.h"
-
+#include "schemeshard_identificators.h"
+
namespace NKikimr {
namespace NSchemeShard {
@@ -52,8 +52,8 @@ struct TEvSchemeShard {
EvRewriteOwnerResult,
EvPublishTenant,
EvPublishTenantResult, // 271125012
- EvLogin,
- EvLoginResult,
+ EvLogin,
+ EvLoginResult,
EvBackupDatashard = EvModifySchemeTransaction + 6 * 512,
@@ -120,13 +120,13 @@ struct TEvSchemeShard {
TEvModifySchemeTransactionResult()
{}
- TEvModifySchemeTransactionResult(TTxId txid, TTabletId schemeshardId) {
- Record.SetTxId(ui64(txid));
- Record.SetSchemeshardId(ui64(schemeshardId));
- }
-
+ TEvModifySchemeTransactionResult(TTxId txid, TTabletId schemeshardId) {
+ Record.SetTxId(ui64(txid));
+ Record.SetSchemeshardId(ui64(schemeshardId));
+ }
+
TEvModifySchemeTransactionResult(EStatus status, ui64 txid, ui64 schemeshardId, const TStringBuf& reason = TStringBuf())
- : TEvModifySchemeTransactionResult(TTxId(txid), TTabletId(schemeshardId))
+ : TEvModifySchemeTransactionResult(TTxId(txid), TTabletId(schemeshardId))
{
Record.SetStatus(status);
if (reason.size() > 0) {
@@ -147,13 +147,13 @@ struct TEvSchemeShard {
return Record.GetReason().empty() && (Record.GetStatus() == EStatus::StatusSuccess);
}
- void SetStatus(EStatus status, const TString& reason = {}) {
- Record.SetStatus(status);
- if (reason) {
- Record.SetReason(reason);
- }
- }
-
+ void SetStatus(EStatus status, const TString& reason = {}) {
+ Record.SetStatus(status);
+ if (reason) {
+ Record.SetReason(reason);
+ }
+ }
+
void SetError(EStatus status, const TString& errStr) {
Record.SetStatus(status);
Record.SetReason(errStr);
@@ -218,10 +218,10 @@ struct TEvSchemeShard {
{}
TEvDescribeScheme(const NKikimrSchemeOp::TDescribePath& describePath)
- {
- Record.CopyFrom(describePath);
- }
-
+ {
+ Record.CopyFrom(describePath);
+ }
+
TEvDescribeScheme(const TString& path)
{
Record.SetPath(path);
@@ -246,9 +246,9 @@ struct TEvSchemeShard {
}
};
- struct TEvDescribeSchemeResult : public TEventPreSerializedPB<TEvDescribeSchemeResult,
+ struct TEvDescribeSchemeResult : public TEventPreSerializedPB<TEvDescribeSchemeResult,
NKikimrScheme::TEvDescribeSchemeResult,
- EvDescribeSchemeResult> {
+ EvDescribeSchemeResult> {
TEvDescribeSchemeResult() = default;
TEvDescribeSchemeResult(const TString& path, ui64 pathOwner, TPathId pathId)
@@ -260,17 +260,17 @@ struct TEvSchemeShard {
}
};
- struct TEvDescribeSchemeResultBuilder : TEvDescribeSchemeResult {
- using TBase::Record;
-
- TEvDescribeSchemeResultBuilder() = default;
-
+ struct TEvDescribeSchemeResultBuilder : TEvDescribeSchemeResult {
+ using TBase::Record;
+
+ TEvDescribeSchemeResultBuilder() = default;
+
TEvDescribeSchemeResultBuilder(const TString& path, ui64 pathOwner, TPathId pathId)
: TEvDescribeSchemeResult(path, pathOwner, pathId)
- {
- }
- };
-
+ {
+ }
+ };
+
struct TEvNotifyTxCompletion : public TEventPB<TEvNotifyTxCompletion,
NKikimrScheme::TEvNotifyTxCompletion,
EvNotifyTxCompletion> {
@@ -528,24 +528,24 @@ struct TEvSchemeShard {
Record.SetSubDomainPathId(subDomainPathId);
}
};
-
+
struct TEvLogin : TEventPB<TEvLogin, NKikimrScheme::TEvLogin, EvLogin> {
- TEvLogin() = default;
- };
-
+ TEvLogin() = default;
+ };
+
struct TEvLoginResult : TEventPB<TEvLoginResult, NKikimrScheme::TEvLoginResult, EvLoginResult> {
- TEvLoginResult() = default;
- };
+ TEvLoginResult() = default;
+ };
};
}
-
+
IActor* CreateFlatTxSchemeShard(const TActorId &tablet, TTabletStorageInfo *info);
bool PartitionConfigHasExternalBlobsEnabled(const NKikimrSchemeOp::TPartitionConfig &partitionConfig);
}
-template<>
+template<>
inline void Out<NKikimrScheme::EStatus>(IOutputStream& o, NKikimrScheme::EStatus x) {
o << NKikimrScheme::EStatus_Name(x);
- return;
-}
+ return;
+}
diff --git a/ydb/core/tx/schemeshard/schemeshard__clean_pathes.cpp b/ydb/core/tx/schemeshard/schemeshard__clean_pathes.cpp
index e66a5da5f04..258699bba93 100644
--- a/ydb/core/tx/schemeshard/schemeshard__clean_pathes.cpp
+++ b/ydb/core/tx/schemeshard/schemeshard__clean_pathes.cpp
@@ -36,13 +36,13 @@ struct TSchemeShard::TTxCleanTables : public TTransactionBase<TSchemeShard> {
}
void Complete(const TActorContext &ctx) override {
- if (RemovedCount) {
- LOG_WARN_S(ctx, NKikimrServices::FLAT_TX_SCHEMESHARD,
- "TTxCleanPathes Complete"
- << ", done PersistRemoveTable for " << RemovedCount << " tables"
- << ", left " << TablesToClean.size()
- << ", at schemeshard: "<< Self->TabletID());
- }
+ if (RemovedCount) {
+ LOG_WARN_S(ctx, NKikimrServices::FLAT_TX_SCHEMESHARD,
+ "TTxCleanPathes Complete"
+ << ", done PersistRemoveTable for " << RemovedCount << " tables"
+ << ", left " << TablesToClean.size()
+ << ", at schemeshard: "<< Self->TabletID());
+ }
if (TablesToClean) {
Self->Execute(Self->CreateTxCleanTables(std::move(TablesToClean)), ctx);
diff --git a/ydb/core/tx/schemeshard/schemeshard__delete_tablet_reply.cpp b/ydb/core/tx/schemeshard/schemeshard__delete_tablet_reply.cpp
index 76c63b48ea7..855553cddc8 100644
--- a/ydb/core/tx/schemeshard/schemeshard__delete_tablet_reply.cpp
+++ b/ydb/core/tx/schemeshard/schemeshard__delete_tablet_reply.cpp
@@ -24,25 +24,25 @@ struct TSchemeShard::TTxDeleteTabletReply : public TSchemeShard::TRwTxBase {
ShardIdx = TShardIdx(Ev->Get()->Record.GetShardOwnerId(),
Ev->Get()->Record.GetShardLocalIdx(0));
}
- if (Ev->Get()->Record.HasForwardRequest()) {
- ForwardToHiveId = TTabletId(Ev->Get()->Record.GetForwardRequest().GetHiveTabletId());
- }
+ if (Ev->Get()->Record.HasForwardRequest()) {
+ ForwardToHiveId = TTabletId(Ev->Get()->Record.GetForwardRequest().GetHiveTabletId());
+ }
}
TTxType GetTxType() const override { return TXTYPE_FREE_TABLET_RESULT; }
void DoExecute(TTransactionContext &txc, const TActorContext &ctx) override {
if (Status != NKikimrProto::OK) {
- if (Status == NKikimrProto::INVALID_OWNER) {
- LOG_WARN_S(ctx, NKikimrServices::FLAT_TX_SCHEMESHARD,
- "Got DeleteTabletReply with Forward response from Hive " << HiveId << " to Hive " << ForwardToHiveId << " shardIdx " << ShardIdx);
- Y_VERIFY(ForwardToHiveId);
- Self->ShardDeleter.RedirectDeleteRequest(HiveId, ForwardToHiveId, ShardIdx, Self->ShardInfos, ctx);
- return;
- }
+ if (Status == NKikimrProto::INVALID_OWNER) {
+ LOG_WARN_S(ctx, NKikimrServices::FLAT_TX_SCHEMESHARD,
+ "Got DeleteTabletReply with Forward response from Hive " << HiveId << " to Hive " << ForwardToHiveId << " shardIdx " << ShardIdx);
+ Y_VERIFY(ForwardToHiveId);
+ Self->ShardDeleter.RedirectDeleteRequest(HiveId, ForwardToHiveId, ShardIdx, Self->ShardInfos, ctx);
+ return;
+ }
// WTF could happen that hive failed to delete the freaking tablet?
- LOG_ALERT_S(ctx, NKikimrServices::FLAT_TX_SCHEMESHARD,
- "Got DeleteTabletReply from Hive " << HiveId << " shardIdx " << ShardIdx << " status " << Status);
+ LOG_ALERT_S(ctx, NKikimrServices::FLAT_TX_SCHEMESHARD,
+ "Got DeleteTabletReply from Hive " << HiveId << " shardIdx " << ShardIdx << " status " << Status);
return;
}
@@ -62,9 +62,9 @@ struct TSchemeShard::TTxDeleteTabletReply : public TSchemeShard::TRwTxBase {
case ETabletType::SchemeShard:
Self->TabletCounters->Simple()[COUNTER_SUB_DOMAIN_SCHEME_SHARD_COUNT].Sub(1);
break;
- case ETabletType::Hive:
+ case ETabletType::Hive:
Self->TabletCounters->Simple()[COUNTER_SUB_DOMAIN_HIVE_COUNT].Sub(1);
- break;
+ break;
case ETabletType::BlockStoreVolume:
Self->TabletCounters->Simple()[COUNTER_BLOCKSTORE_VOLUME_SHARD_COUNT].Sub(1);
break;
@@ -174,9 +174,9 @@ struct TSchemeShard::TTxDeleteTabletReply : public TSchemeShard::TRwTxBase {
private:
TShardIdx ShardIdx;
TTabletId TabletId;
- NKikimrProto::EReplyStatus Status;
+ NKikimrProto::EReplyStatus Status;
TTabletId HiveId;
- TTabletId ForwardToHiveId = {};
+ TTabletId ForwardToHiveId = {};
};
NTabletFlatExecutor::ITransaction* TSchemeShard::CreateTxDeleteTabletReply(TEvHive::TEvDeleteTabletReply::TPtr& ev) {
diff --git a/ydb/core/tx/schemeshard/schemeshard__init.cpp b/ydb/core/tx/schemeshard/schemeshard__init.cpp
index 6382ad9825f..650506549e0 100644
--- a/ydb/core/tx/schemeshard/schemeshard__init.cpp
+++ b/ydb/core/tx/schemeshard/schemeshard__init.cpp
@@ -1485,7 +1485,7 @@ struct TSchemeShard::TTxInit : public TTransactionBase<TSchemeShard> {
TSubDomainInfo::TPtr rootDomainInfo = new TSubDomainInfo(version, Self->RootPathId());
rootDomainInfo->SetSchemeLimits(rootLimits);
- rootDomainInfo->SetSecurityStateVersion(row.GetValueOrDefault<Schema::SubDomains::SecurityStateVersion>());
+ rootDomainInfo->SetSecurityStateVersion(row.GetValueOrDefault<Schema::SubDomains::SecurityStateVersion>());
rootDomainInfo->InitializeAsGlobal(Self->CreateRootProcessingParams(ctx));
@@ -1555,7 +1555,7 @@ struct TSchemeShard::TTxInit : public TTransactionBase<TSchemeShard> {
}
domainInfo->SetDomainStateVersion(rowset.GetValueOrDefault<Schema::SubDomains::StateVersion>(0));
- domainInfo->SetSecurityStateVersion(rowset.GetValueOrDefault<Schema::SubDomains::SecurityStateVersion>());
+ domainInfo->SetSecurityStateVersion(rowset.GetValueOrDefault<Schema::SubDomains::SecurityStateVersion>());
domainInfo->SetDiskQuotaExceeded(rowset.GetValueOrDefault<Schema::SubDomains::DiskQuotaExceeded>(false));
if (domainInfo->GetDiskQuotaExceeded()) {
Self->ChangeDiskSpaceQuotaExceeded(+1);
@@ -2201,18 +2201,18 @@ struct TSchemeShard::TTxInit : public TTransactionBase<TSchemeShard> {
Y_VERIFY(Self->ShardInfos.contains(shardIdx));
TShardInfo& shardInfo = Self->ShardInfos[shardIdx];
- if (shardInfo.BindedChannels.size() <= channelId) {
- shardInfo.BindedChannels.resize(channelId + 1);
- }
- TChannelBind& channelBind = shardInfo.BindedChannels[channelId];
+ if (shardInfo.BindedChannels.size() <= channelId) {
+ shardInfo.BindedChannels.resize(channelId + 1);
+ }
+ TChannelBind& channelBind = shardInfo.BindedChannels[channelId];
if (bindingData) {
bool parseOk = ParseFromStringNoSizeLimit(channelBind, bindingData);
Y_VERIFY(parseOk);
- }
+ }
if (poolName) {
channelBind.SetStoragePoolName(poolName);
- }
+ }
}
}
@@ -3503,66 +3503,66 @@ struct TSchemeShard::TTxInit : public TTransactionBase<TSchemeShard> {
}
}
- // Read security state
- NLoginProto::TSecurityState securityState;
+ // Read security state
+ NLoginProto::TSecurityState securityState;
+ {
+ auto rowset = db.Table<Schema::LoginKeys>().Select();
+
+ if (!rowset.IsReady()) {
+ return false;
+ }
+
+ while (!rowset.EndOfSet()) {
+ auto& key = *securityState.AddPublicKeys();
+ key.SetKeyId(rowset.GetValue<Schema::LoginKeys::KeyId>());
+ key.SetKeyDataPEM(rowset.GetValue<Schema::LoginKeys::KeyDataPEM>());
+ key.SetExpiresAt(rowset.GetValueOrDefault<Schema::LoginKeys::ExpiresAt>());
+ if (!rowset.Next()) {
+ return false;
+ }
+ }
+ }
+ std::unordered_map<TString, int> sidIndex;
+ {
+ auto rowset = db.Table<Schema::LoginSids>().Select();
+
+ if (!rowset.IsReady()) {
+ return false;
+ }
+
+ while (!rowset.EndOfSet()) {
+ auto& sid = *securityState.AddSids();
+ sid.SetName(rowset.GetValue<Schema::LoginSids::SidName>());
+ sid.SetType(rowset.GetValue<Schema::LoginSids::SidType>());
+ sid.SetHash(rowset.GetValue<Schema::LoginSids::SidHash>());
+ sidIndex[sid.name()] = securityState.SidsSize() - 1;
+ if (!rowset.Next()) {
+ return false;
+ }
+ }
+ }
+ {
+ auto rowset = db.Table<Schema::LoginSidMembers>().Select();
+
+ if (!rowset.IsReady()) {
+ return false;
+ }
+
+ while (!rowset.EndOfSet()) {
+ TString sidName = rowset.GetValue<Schema::LoginSidMembers::SidName>();
+ auto itSidIndex = sidIndex.find(sidName);
+ if (itSidIndex != sidIndex.end()) {
+ NLoginProto::TSid& sid = (*securityState.MutableSids())[itSidIndex->second];
+ sid.AddMembers(rowset.GetValue<Schema::LoginSidMembers::SidMember>());
+ }
+ if (!rowset.Next()) {
+ return false;
+ }
+ }
+ }
+ Self->LoginProvider.UpdateSecurityState(std::move(securityState));
+
{
- auto rowset = db.Table<Schema::LoginKeys>().Select();
-
- if (!rowset.IsReady()) {
- return false;
- }
-
- while (!rowset.EndOfSet()) {
- auto& key = *securityState.AddPublicKeys();
- key.SetKeyId(rowset.GetValue<Schema::LoginKeys::KeyId>());
- key.SetKeyDataPEM(rowset.GetValue<Schema::LoginKeys::KeyDataPEM>());
- key.SetExpiresAt(rowset.GetValueOrDefault<Schema::LoginKeys::ExpiresAt>());
- if (!rowset.Next()) {
- return false;
- }
- }
- }
- std::unordered_map<TString, int> sidIndex;
- {
- auto rowset = db.Table<Schema::LoginSids>().Select();
-
- if (!rowset.IsReady()) {
- return false;
- }
-
- while (!rowset.EndOfSet()) {
- auto& sid = *securityState.AddSids();
- sid.SetName(rowset.GetValue<Schema::LoginSids::SidName>());
- sid.SetType(rowset.GetValue<Schema::LoginSids::SidType>());
- sid.SetHash(rowset.GetValue<Schema::LoginSids::SidHash>());
- sidIndex[sid.name()] = securityState.SidsSize() - 1;
- if (!rowset.Next()) {
- return false;
- }
- }
- }
- {
- auto rowset = db.Table<Schema::LoginSidMembers>().Select();
-
- if (!rowset.IsReady()) {
- return false;
- }
-
- while (!rowset.EndOfSet()) {
- TString sidName = rowset.GetValue<Schema::LoginSidMembers::SidName>();
- auto itSidIndex = sidIndex.find(sidName);
- if (itSidIndex != sidIndex.end()) {
- NLoginProto::TSid& sid = (*securityState.MutableSids())[itSidIndex->second];
- sid.AddMembers(rowset.GetValue<Schema::LoginSidMembers::SidMember>());
- }
- if (!rowset.Next()) {
- return false;
- }
- }
- }
- Self->LoginProvider.UpdateSecurityState(std::move(securityState));
-
- {
TShardBackupStatusRows backupStatuses;
if (!LoadBackupStatuses(db, backupStatuses)) {
return false;
@@ -3660,7 +3660,7 @@ struct TSchemeShard::TTxInit : public TTransactionBase<TSchemeShard> {
domainInfo->AddInternalShard(shardIdx);
switch (si.second.TabletType) {
- case ETabletType::DataShard:
+ case ETabletType::DataShard:
{
const auto table = Self->Tables.FindPtr(pathId);
if (tabletId != InvalidTabletId) {
@@ -3671,10 +3671,10 @@ struct TSchemeShard::TTxInit : public TTransactionBase<TSchemeShard> {
}
break;
}
- case ETabletType::PersQueue:
+ case ETabletType::PersQueue:
Self->TabletCounters->Simple()[COUNTER_PQ_SHARD_COUNT].Add(1);
break;
- case ETabletType::PersQueueReadBalancer:
+ case ETabletType::PersQueueReadBalancer:
Self->TabletCounters->Simple()[COUNTER_PQ_RB_SHARD_COUNT].Add(1);
break;
case ETabletType::BlockStoreVolume:
@@ -3692,10 +3692,10 @@ struct TSchemeShard::TTxInit : public TTransactionBase<TSchemeShard> {
case ETabletType::Kesus:
Self->TabletCounters->Simple()[COUNTER_KESUS_SHARD_COUNT].Add(1);
break;
- case ETabletType::Coordinator:
+ case ETabletType::Coordinator:
Self->TabletCounters->Simple()[COUNTER_SUB_DOMAIN_COORDINATOR_COUNT].Add(1);
break;
- case ETabletType::Mediator:
+ case ETabletType::Mediator:
Self->TabletCounters->Simple()[COUNTER_SUB_DOMAIN_MEDIATOR_COUNT].Add(1);
break;
case ETabletType::RTMRPartition:
@@ -3707,9 +3707,9 @@ struct TSchemeShard::TTxInit : public TTransactionBase<TSchemeShard> {
case ETabletType::SchemeShard:
Self->TabletCounters->Simple()[COUNTER_SUB_DOMAIN_SCHEME_SHARD_COUNT].Add(1);
break;
- case ETabletType::Hive:
- Self->TabletCounters->Simple()[COUNTER_SUB_DOMAIN_HIVE_COUNT].Add(1);
- break;
+ case ETabletType::Hive:
+ Self->TabletCounters->Simple()[COUNTER_SUB_DOMAIN_HIVE_COUNT].Add(1);
+ break;
case ETabletType::SysViewProcessor:
Self->TabletCounters->Simple()[COUNTER_SYS_VIEW_PROCESSOR_COUNT].Add(1);
break;
diff --git a/ydb/core/tx/schemeshard/schemeshard__init_root.cpp b/ydb/core/tx/schemeshard/schemeshard__init_root.cpp
index 211ef722104..74399680cda 100644
--- a/ydb/core/tx/schemeshard/schemeshard__init_root.cpp
+++ b/ydb/core/tx/schemeshard/schemeshard__init_root.cpp
@@ -17,7 +17,7 @@ struct TSchemeShard::TTxInitRoot : public TSchemeShard::TRwTxBase {
TTxType GetTxType() const override { return TXTYPE_INIT_ROOT; }
- void DoExecute(TTransactionContext &txc, const TActorContext &ctx) override {
+ void DoExecute(TTransactionContext &txc, const TActorContext &ctx) override {
NIceDb::TNiceDb db(txc.DB);
const TDomainsInfo::TDomain& selfDomain = Self->GetDomainDescription(ctx);
@@ -53,11 +53,11 @@ struct TSchemeShard::TTxInitRoot : public TSchemeShard::TRwTxBase {
Self->ShardInfos.clear();
Self->RootPathElemets = std::move(rootPathElemets);
-
+
TSubDomainInfo::TPtr newDomain = new TSubDomainInfo(0, Self->RootPathId());
newDomain->InitializeAsGlobal(Self->CreateRootProcessingParams(ctx));
Self->SubDomains[Self->RootPathId()] = newDomain;
-
+
Self->PersistUserAttributes(db, Self->RootPathId(), nullptr, newPath->UserAttrs);
Self->PersistPath(db, newPath->PathId);
Self->PersistUpdateNextPathId(db);
@@ -325,9 +325,9 @@ struct TSchemeShard::TTxInitTenantSchemeShard : public TSchemeShard::TRwTxBase {
RegisterShard(db, subdomain, processingParams.GetCoordinators(), TTabletTypes::Coordinator);
RegisterShard(db, subdomain, processingParams.GetMediators(), TTabletTypes::Mediator);
RegisterShard(db, subdomain, TVector<ui64>{processingParams.GetSchemeShard()}, TTabletTypes::SchemeShard);
- if (processingParams.HasHive()) {
- RegisterShard(db, subdomain, TVector<ui64>{processingParams.GetHive()}, TTabletTypes::Hive);
- }
+ if (processingParams.HasHive()) {
+ RegisterShard(db, subdomain, TVector<ui64>{processingParams.GetHive()}, TTabletTypes::Hive);
+ }
if (processingParams.HasSysViewProcessor()) {
RegisterShard(db, subdomain, TVector<ui64>{processingParams.GetSysViewProcessor()}, TTabletTypes::SysViewProcessor);
}
diff --git a/ydb/core/tx/schemeshard/schemeshard__init_schema.cpp b/ydb/core/tx/schemeshard/schemeshard__init_schema.cpp
index 1cf1ef8799d..b27131388a9 100644
--- a/ydb/core/tx/schemeshard/schemeshard__init_schema.cpp
+++ b/ydb/core/tx/schemeshard/schemeshard__init_schema.cpp
@@ -12,7 +12,7 @@ struct TSchemeShard::TTxInitSchema : public TTransactionBase<TSchemeShard> {
bool Execute(TTransactionContext &txc, const TActorContext &ctx) override {
LOG_DEBUG(ctx, NKikimrServices::FLAT_TX_SCHEMESHARD, "TxInitSchema.Execute");
- NIceDb::TNiceDb(txc.DB).Materialize<Schema>();
+ NIceDb::TNiceDb(txc.DB).Materialize<Schema>();
return true;
}
diff --git a/ydb/core/tx/schemeshard/schemeshard__login.cpp b/ydb/core/tx/schemeshard/schemeshard__login.cpp
index 83394c6a367..ad8058e3807 100644
--- a/ydb/core/tx/schemeshard/schemeshard__login.cpp
+++ b/ydb/core/tx/schemeshard/schemeshard__login.cpp
@@ -1,91 +1,91 @@
-#include "schemeshard_impl.h"
-#include <ydb/library/security/util.h>
-
-namespace NKikimr {
+#include "schemeshard_impl.h"
+#include <ydb/library/security/util.h>
+
+namespace NKikimr {
namespace NSchemeShard {
-
-using namespace NTabletFlatExecutor;
-
+
+using namespace NTabletFlatExecutor;
+
struct TSchemeShard::TTxLogin : TSchemeShard::TRwTxBase {
TEvSchemeShard::TEvLogin::TPtr Request;
- TPathId SubDomainPathId;
- bool NeedPublishOnComplete = false;
-
+ TPathId SubDomainPathId;
+ bool NeedPublishOnComplete = false;
+
TTxLogin(TSelf *self, TEvSchemeShard::TEvLogin::TPtr &ev)
- : TRwTxBase(self)
- , Request(std::move(ev))
- {}
-
- TTxType GetTxType() const override { return TXTYPE_LOGIN; }
-
- NLogin::TLoginProvider::TLoginUserRequest GetLoginRequest() const {
- return {
- .User = Request->Get()->Record.GetUser(),
- .Password = Request->Get()->Record.GetPassword()
- };
- }
-
- void DoExecute(TTransactionContext& txc, const TActorContext& ctx) override {
- LOG_DEBUG_S(ctx, NKikimrServices::FLAT_TX_SCHEMESHARD,
- "TTxLogin DoExecute"
- << " at schemeshard: " << Self->TabletID());
- if (Self->LoginProvider.IsItTimeToRotateKeys()) {
- LOG_DEBUG_S(ctx, NKikimrServices::FLAT_TX_SCHEMESHARD, "TTxLogin RotateKeys at schemeshard: " << Self->TabletID());
- std::vector<ui64> keysExpired;
- std::vector<ui64> keysAdded;
- Self->LoginProvider.RotateKeys(keysExpired, keysAdded);
- SubDomainPathId = Self->GetCurrentSubDomainPathId();
- TSubDomainInfo::TPtr domainPtr = Self->ResolveDomainInfo(SubDomainPathId);
-
- // TODO(xenoxeno): optimize security state changes
- domainPtr->UpdateSecurityState(Self->LoginProvider.GetSecurityState());
- domainPtr->IncSecurityStateVersion();
-
- NIceDb::TNiceDb db(txc.DB);
-
- Self->PersistSubDomainSecurityStateVersion(db, SubDomainPathId, *domainPtr);
-
- for (ui64 keyId : keysExpired) {
- db.Table<Schema::LoginKeys>().Key(keyId).Delete();
- }
- for (ui64 keyId : keysAdded) {
- const auto* key = Self->LoginProvider.FindKey(keyId);
- if (key) {
- db.Table<Schema::LoginKeys>().Key(keyId).Update<Schema::LoginKeys::KeyDataPEM, Schema::LoginKeys::ExpiresAt>(
- key->PublicKey, ToInstant(key->ExpiresAt).MilliSeconds());
- }
- }
-
- NeedPublishOnComplete = true;
- }
- }
-
- void DoComplete(const TActorContext &ctx) override {
- if (NeedPublishOnComplete) {
- Self->PublishToSchemeBoard(TTxId(), {SubDomainPathId}, ctx);
- }
-
- NLogin::TLoginProvider::TLoginUserResponse LoginResponse = Self->LoginProvider.LoginUser(GetLoginRequest());
+ : TRwTxBase(self)
+ , Request(std::move(ev))
+ {}
+
+ TTxType GetTxType() const override { return TXTYPE_LOGIN; }
+
+ NLogin::TLoginProvider::TLoginUserRequest GetLoginRequest() const {
+ return {
+ .User = Request->Get()->Record.GetUser(),
+ .Password = Request->Get()->Record.GetPassword()
+ };
+ }
+
+ void DoExecute(TTransactionContext& txc, const TActorContext& ctx) override {
+ LOG_DEBUG_S(ctx, NKikimrServices::FLAT_TX_SCHEMESHARD,
+ "TTxLogin DoExecute"
+ << " at schemeshard: " << Self->TabletID());
+ if (Self->LoginProvider.IsItTimeToRotateKeys()) {
+ LOG_DEBUG_S(ctx, NKikimrServices::FLAT_TX_SCHEMESHARD, "TTxLogin RotateKeys at schemeshard: " << Self->TabletID());
+ std::vector<ui64> keysExpired;
+ std::vector<ui64> keysAdded;
+ Self->LoginProvider.RotateKeys(keysExpired, keysAdded);
+ SubDomainPathId = Self->GetCurrentSubDomainPathId();
+ TSubDomainInfo::TPtr domainPtr = Self->ResolveDomainInfo(SubDomainPathId);
+
+ // TODO(xenoxeno): optimize security state changes
+ domainPtr->UpdateSecurityState(Self->LoginProvider.GetSecurityState());
+ domainPtr->IncSecurityStateVersion();
+
+ NIceDb::TNiceDb db(txc.DB);
+
+ Self->PersistSubDomainSecurityStateVersion(db, SubDomainPathId, *domainPtr);
+
+ for (ui64 keyId : keysExpired) {
+ db.Table<Schema::LoginKeys>().Key(keyId).Delete();
+ }
+ for (ui64 keyId : keysAdded) {
+ const auto* key = Self->LoginProvider.FindKey(keyId);
+ if (key) {
+ db.Table<Schema::LoginKeys>().Key(keyId).Update<Schema::LoginKeys::KeyDataPEM, Schema::LoginKeys::ExpiresAt>(
+ key->PublicKey, ToInstant(key->ExpiresAt).MilliSeconds());
+ }
+ }
+
+ NeedPublishOnComplete = true;
+ }
+ }
+
+ void DoComplete(const TActorContext &ctx) override {
+ if (NeedPublishOnComplete) {
+ Self->PublishToSchemeBoard(TTxId(), {SubDomainPathId}, ctx);
+ }
+
+ NLogin::TLoginProvider::TLoginUserResponse LoginResponse = Self->LoginProvider.LoginUser(GetLoginRequest());
THolder<TEvSchemeShard::TEvLoginResult> result = MakeHolder<TEvSchemeShard::TEvLoginResult>();
- if (LoginResponse.Error) {
- result->Record.SetError(LoginResponse.Error);
- }
- if (LoginResponse.Token) {
- result->Record.SetToken(LoginResponse.Token);
- }
-
- LOG_DEBUG_S(ctx, NKikimrServices::FLAT_TX_SCHEMESHARD,
- "TTxLogin DoComplete"
- << ", result: " << result->Record.ShortDebugString()
- << ", at schemeshard: " << Self->TabletID());
-
- ctx.Send(Request->Sender, std::move(result), 0, Request->Cookie);
- }
-
-};
-
+ if (LoginResponse.Error) {
+ result->Record.SetError(LoginResponse.Error);
+ }
+ if (LoginResponse.Token) {
+ result->Record.SetToken(LoginResponse.Token);
+ }
+
+ LOG_DEBUG_S(ctx, NKikimrServices::FLAT_TX_SCHEMESHARD,
+ "TTxLogin DoComplete"
+ << ", result: " << result->Record.ShortDebugString()
+ << ", at schemeshard: " << Self->TabletID());
+
+ ctx.Send(Request->Sender, std::move(result), 0, Request->Cookie);
+ }
+
+};
+
NTabletFlatExecutor::ITransaction* TSchemeShard::CreateTxLogin(TEvSchemeShard::TEvLogin::TPtr &ev) {
- return new TTxLogin(this, ev);
-}
-
-}}
+ return new TTxLogin(this, ev);
+}
+
+}}
diff --git a/ydb/core/tx/schemeshard/schemeshard__monitoring.cpp b/ydb/core/tx/schemeshard/schemeshard__monitoring.cpp
index ef19aa7f18e..76e73182496 100644
--- a/ydb/core/tx/schemeshard/schemeshard__monitoring.cpp
+++ b/ydb/core/tx/schemeshard/schemeshard__monitoring.cpp
@@ -918,13 +918,13 @@ private:
TABLEH() {str << "PoolName";}
}
}
- ui32 channelId = 0;
+ ui32 channelId = 0;
for (auto& bind: shard.BindedChannels) {
TABLER() {
- TABLED() { str << channelId; }
+ TABLED() { str << channelId; }
TABLED() { str << bind.GetStoragePoolName(); }
}
- ++channelId;
+ ++channelId;
}
}
}
diff --git a/ydb/core/tx/schemeshard/schemeshard__operation.cpp b/ydb/core/tx/schemeshard/schemeshard__operation.cpp
index a4c581c3ee4..daf1218bcf7 100644
--- a/ydb/core/tx/schemeshard/schemeshard__operation.cpp
+++ b/ydb/core/tx/schemeshard/schemeshard__operation.cpp
@@ -1024,10 +1024,10 @@ ISubOperationBase::TPtr TOperation::ConstructPart(NKikimrSchemeOp::EOperationTyp
case NKikimrSchemeOp::EOperationType::ESchemeOpDropFileStore:
return CreateDropFileStore(NextPartId(), tx);
- // Login
+ // Login
case NKikimrSchemeOp::EOperationType::ESchemeOpAlterLogin:
- return CreateAlterLogin(NextPartId(), tx);
-
+ return CreateAlterLogin(NextPartId(), tx);
+
// Sequence
case NKikimrSchemeOp::EOperationType::ESchemeOpCreateSequence:
return CreateNewSequence(NextPartId(), tx);
diff --git a/ydb/core/tx/schemeshard/schemeshard__operation_alter_extsubdomain.cpp b/ydb/core/tx/schemeshard/schemeshard__operation_alter_extsubdomain.cpp
index 326b0ba9359..463f3bb3cf9 100644
--- a/ydb/core/tx/schemeshard/schemeshard__operation_alter_extsubdomain.cpp
+++ b/ydb/core/tx/schemeshard/schemeshard__operation_alter_extsubdomain.cpp
@@ -260,7 +260,7 @@ public:
shardsToCreate += 1;
allowOverTheLimitShards += 1;
}
-
+
if (wasViewProcessors && setViewProcessors) {
if (bool(subDomainInfo->GetTenantSysViewProcessorID()) != settings.GetExternalSysViewProcessor()) {
result->SetError(
@@ -414,8 +414,8 @@ public:
DeclareShards(txState, OperationId.GetTxId(), subDomain->PathId, 1, TTabletTypes::Hive, channelBindings, context.SS);
} else if (!alterData->GetSharedHive()) {
alterData->SetSharedHive(context.SS->GetGlobalHive(context.Ctx));
- }
-
+ }
+
if (addViewProcessors) {
DeclareShards(txState, OperationId.GetTxId(), subDomain->PathId, 1, TTabletTypes::SysViewProcessor, channelBindings, context.SS);
}
diff --git a/ydb/core/tx/schemeshard/schemeshard__operation_alter_login.cpp b/ydb/core/tx/schemeshard/schemeshard__operation_alter_login.cpp
index a70dce1aa9a..0b420f75b41 100644
--- a/ydb/core/tx/schemeshard/schemeshard__operation_alter_login.cpp
+++ b/ydb/core/tx/schemeshard/schemeshard__operation_alter_login.cpp
@@ -1,178 +1,178 @@
-#include "schemeshard__operation_part.h"
-#include "schemeshard__operation_common.h"
-#include "schemeshard_impl.h"
-
-namespace {
-
-using namespace NKikimr;
+#include "schemeshard__operation_part.h"
+#include "schemeshard__operation_common.h"
+#include "schemeshard_impl.h"
+
+namespace {
+
+using namespace NKikimr;
using namespace NSchemeShard;
-
-class TAlterLogin: public ISubOperationBase {
- const TOperationId OperationId;
- const TTxTransaction Transaction;
-
-public:
- TAlterLogin(TOperationId id, const TTxTransaction& tx)
- : OperationId(id)
- , Transaction(tx)
- {
- }
-
- TAlterLogin(TOperationId id)
- : OperationId(id)
- {
- }
-
+
+class TAlterLogin: public ISubOperationBase {
+ const TOperationId OperationId;
+ const TTxTransaction Transaction;
+
+public:
+ TAlterLogin(TOperationId id, const TTxTransaction& tx)
+ : OperationId(id)
+ , Transaction(tx)
+ {
+ }
+
+ TAlterLogin(TOperationId id)
+ : OperationId(id)
+ {
+ }
+
THolder<TProposeResponse> Propose(const TString&, TOperationContext& context) override {
- NIceDb::TNiceDb db(context.Txc.DB);
- TTabletId ssId = context.SS->SelfTabletId();
- auto result = MakeHolder<TProposeResponse>(OperationId.GetTxId(), ssId);
- if (Transaction.GetWorkingDir() != context.SS->LoginProvider.Audience) {
- result->SetStatus(NKikimrScheme::StatusPreconditionFailed, "Wrong working dir");
- } else {
- const NKikimrSchemeOp::TAlterLogin& alterLogin = Transaction.GetAlterLogin();
- switch (alterLogin.GetAlterCase()) {
- case NKikimrSchemeOp::TAlterLogin::kCreateUser: {
- const auto& createUser = alterLogin.GetCreateUser();
- auto response = context.SS->LoginProvider.CreateUser({.User = createUser.GetUser(), .Password = createUser.GetPassword()});
- if (response.Error) {
- result->SetStatus(NKikimrScheme::StatusPreconditionFailed, response.Error);
- } else {
- auto& sid = context.SS->LoginProvider.Sids[createUser.GetUser()];
- db.Table<Schema::LoginSids>().Key(sid.Name).Update<Schema::LoginSids::SidType, Schema::LoginSids::SidHash>(sid.Type, sid.Hash);
- result->SetStatus(NKikimrScheme::StatusSuccess);
- }
- break;
- }
- case NKikimrSchemeOp::TAlterLogin::kModifyUser: {
- const auto& modifyUser = alterLogin.GetModifyUser();
- auto response = context.SS->LoginProvider.ModifyUser({.User = modifyUser.GetUser(), .Password = modifyUser.GetPassword()});
- if (response.Error) {
- result->SetStatus(NKikimrScheme::StatusPreconditionFailed, response.Error);
- } else {
- auto& sid = context.SS->LoginProvider.Sids[modifyUser.GetUser()];
- db.Table<Schema::LoginSids>().Key(sid.Name).Update<Schema::LoginSids::SidType, Schema::LoginSids::SidHash>(sid.Type, sid.Hash);
- result->SetStatus(NKikimrScheme::StatusSuccess);
- }
- break;
- }
- case NKikimrSchemeOp::TAlterLogin::kRemoveUser: {
- const auto& removeUser = alterLogin.GetRemoveUser();
- const TString& user = removeUser.GetUser();
- auto response = context.SS->LoginProvider.RemoveUser({.User = user});
- if (response.Error) {
- result->SetStatus(NKikimrScheme::StatusPreconditionFailed, response.Error);
- } else {
- db.Table<Schema::LoginSids>().Key(user).Delete();
- for (const TString& group : response.TouchedGroups) {
- db.Table<Schema::LoginSidMembers>().Key(group, user).Delete();
- }
- result->SetStatus(NKikimrScheme::StatusSuccess);
- }
- break;
- }
- case NKikimrSchemeOp::TAlterLogin::kCreateGroup: {
- const auto& createGroup = alterLogin.GetCreateGroup();
- const TString& group = createGroup.GetGroup();
- auto response = context.SS->LoginProvider.CreateGroup({.Group = group});
- if (response.Error) {
- result->SetStatus(NKikimrScheme::StatusPreconditionFailed, response.Error);
- } else {
- auto& sid = context.SS->LoginProvider.Sids[group];
- db.Table<Schema::LoginSids>().Key(sid.Name).Update<Schema::LoginSids::SidType>(sid.Type);
- result->SetStatus(NKikimrScheme::StatusSuccess);
- }
- break;
- }
- case NKikimrSchemeOp::TAlterLogin::kAddGroupMembership: {
- const auto& addGroupMembership = alterLogin.GetAddGroupMembership();
- auto response = context.SS->LoginProvider.AddGroupMembership({
- .Group = addGroupMembership.GetGroup(),
- .Member = addGroupMembership.GetMember()
- });
- if (response.Error) {
- result->SetStatus(NKikimrScheme::StatusPreconditionFailed, response.Error);
- } else {
- db.Table<Schema::LoginSidMembers>().Key(addGroupMembership.GetGroup(), addGroupMembership.GetMember()).Update();
- result->SetStatus(NKikimrScheme::StatusSuccess);
- }
- break;
- }
- case NKikimrSchemeOp::TAlterLogin::kRemoveGroupMembership: {
- const auto& removeGroupMembership = alterLogin.GetRemoveGroupMembership();
- auto response = context.SS->LoginProvider.RemoveGroupMembership({
- .Group = removeGroupMembership.GetGroup(),
- .Member = removeGroupMembership.GetMember()
- });
- if (response.Error) {
- result->SetStatus(NKikimrScheme::StatusPreconditionFailed, response.Error);
- } else {
- db.Table<Schema::LoginSidMembers>().Key(removeGroupMembership.GetGroup(), removeGroupMembership.GetMember()).Delete();
- result->SetStatus(NKikimrScheme::StatusSuccess);
- }
- break;
- }
- case NKikimrSchemeOp::TAlterLogin::kRemoveGroup: {
- const auto& removeGroup = alterLogin.GetRemoveGroup();
- const TString& group = removeGroup.GetGroup();
- auto response = context.SS->LoginProvider.RemoveGroup({.Group = group});
- if (response.Error) {
- result->SetStatus(NKikimrScheme::StatusPreconditionFailed, response.Error);
- } else {
- db.Table<Schema::LoginSids>().Key(group).Delete();
- for (const TString& parent : response.TouchedGroups) {
- db.Table<Schema::LoginSidMembers>().Key(parent, group).Delete();
- }
- result->SetStatus(NKikimrScheme::StatusSuccess);
- }
- break;
- }
- default: {
- result->SetStatus(NKikimrScheme::StatusInvalidParameter, "Unknown alter login operation");
- break;
- }
- }
- }
-
+ NIceDb::TNiceDb db(context.Txc.DB);
+ TTabletId ssId = context.SS->SelfTabletId();
+ auto result = MakeHolder<TProposeResponse>(OperationId.GetTxId(), ssId);
+ if (Transaction.GetWorkingDir() != context.SS->LoginProvider.Audience) {
+ result->SetStatus(NKikimrScheme::StatusPreconditionFailed, "Wrong working dir");
+ } else {
+ const NKikimrSchemeOp::TAlterLogin& alterLogin = Transaction.GetAlterLogin();
+ switch (alterLogin.GetAlterCase()) {
+ case NKikimrSchemeOp::TAlterLogin::kCreateUser: {
+ const auto& createUser = alterLogin.GetCreateUser();
+ auto response = context.SS->LoginProvider.CreateUser({.User = createUser.GetUser(), .Password = createUser.GetPassword()});
+ if (response.Error) {
+ result->SetStatus(NKikimrScheme::StatusPreconditionFailed, response.Error);
+ } else {
+ auto& sid = context.SS->LoginProvider.Sids[createUser.GetUser()];
+ db.Table<Schema::LoginSids>().Key(sid.Name).Update<Schema::LoginSids::SidType, Schema::LoginSids::SidHash>(sid.Type, sid.Hash);
+ result->SetStatus(NKikimrScheme::StatusSuccess);
+ }
+ break;
+ }
+ case NKikimrSchemeOp::TAlterLogin::kModifyUser: {
+ const auto& modifyUser = alterLogin.GetModifyUser();
+ auto response = context.SS->LoginProvider.ModifyUser({.User = modifyUser.GetUser(), .Password = modifyUser.GetPassword()});
+ if (response.Error) {
+ result->SetStatus(NKikimrScheme::StatusPreconditionFailed, response.Error);
+ } else {
+ auto& sid = context.SS->LoginProvider.Sids[modifyUser.GetUser()];
+ db.Table<Schema::LoginSids>().Key(sid.Name).Update<Schema::LoginSids::SidType, Schema::LoginSids::SidHash>(sid.Type, sid.Hash);
+ result->SetStatus(NKikimrScheme::StatusSuccess);
+ }
+ break;
+ }
+ case NKikimrSchemeOp::TAlterLogin::kRemoveUser: {
+ const auto& removeUser = alterLogin.GetRemoveUser();
+ const TString& user = removeUser.GetUser();
+ auto response = context.SS->LoginProvider.RemoveUser({.User = user});
+ if (response.Error) {
+ result->SetStatus(NKikimrScheme::StatusPreconditionFailed, response.Error);
+ } else {
+ db.Table<Schema::LoginSids>().Key(user).Delete();
+ for (const TString& group : response.TouchedGroups) {
+ db.Table<Schema::LoginSidMembers>().Key(group, user).Delete();
+ }
+ result->SetStatus(NKikimrScheme::StatusSuccess);
+ }
+ break;
+ }
+ case NKikimrSchemeOp::TAlterLogin::kCreateGroup: {
+ const auto& createGroup = alterLogin.GetCreateGroup();
+ const TString& group = createGroup.GetGroup();
+ auto response = context.SS->LoginProvider.CreateGroup({.Group = group});
+ if (response.Error) {
+ result->SetStatus(NKikimrScheme::StatusPreconditionFailed, response.Error);
+ } else {
+ auto& sid = context.SS->LoginProvider.Sids[group];
+ db.Table<Schema::LoginSids>().Key(sid.Name).Update<Schema::LoginSids::SidType>(sid.Type);
+ result->SetStatus(NKikimrScheme::StatusSuccess);
+ }
+ break;
+ }
+ case NKikimrSchemeOp::TAlterLogin::kAddGroupMembership: {
+ const auto& addGroupMembership = alterLogin.GetAddGroupMembership();
+ auto response = context.SS->LoginProvider.AddGroupMembership({
+ .Group = addGroupMembership.GetGroup(),
+ .Member = addGroupMembership.GetMember()
+ });
+ if (response.Error) {
+ result->SetStatus(NKikimrScheme::StatusPreconditionFailed, response.Error);
+ } else {
+ db.Table<Schema::LoginSidMembers>().Key(addGroupMembership.GetGroup(), addGroupMembership.GetMember()).Update();
+ result->SetStatus(NKikimrScheme::StatusSuccess);
+ }
+ break;
+ }
+ case NKikimrSchemeOp::TAlterLogin::kRemoveGroupMembership: {
+ const auto& removeGroupMembership = alterLogin.GetRemoveGroupMembership();
+ auto response = context.SS->LoginProvider.RemoveGroupMembership({
+ .Group = removeGroupMembership.GetGroup(),
+ .Member = removeGroupMembership.GetMember()
+ });
+ if (response.Error) {
+ result->SetStatus(NKikimrScheme::StatusPreconditionFailed, response.Error);
+ } else {
+ db.Table<Schema::LoginSidMembers>().Key(removeGroupMembership.GetGroup(), removeGroupMembership.GetMember()).Delete();
+ result->SetStatus(NKikimrScheme::StatusSuccess);
+ }
+ break;
+ }
+ case NKikimrSchemeOp::TAlterLogin::kRemoveGroup: {
+ const auto& removeGroup = alterLogin.GetRemoveGroup();
+ const TString& group = removeGroup.GetGroup();
+ auto response = context.SS->LoginProvider.RemoveGroup({.Group = group});
+ if (response.Error) {
+ result->SetStatus(NKikimrScheme::StatusPreconditionFailed, response.Error);
+ } else {
+ db.Table<Schema::LoginSids>().Key(group).Delete();
+ for (const TString& parent : response.TouchedGroups) {
+ db.Table<Schema::LoginSidMembers>().Key(parent, group).Delete();
+ }
+ result->SetStatus(NKikimrScheme::StatusSuccess);
+ }
+ break;
+ }
+ default: {
+ result->SetStatus(NKikimrScheme::StatusInvalidParameter, "Unknown alter login operation");
+ break;
+ }
+ }
+ }
+
if (result->Record.GetStatus() == NKikimrScheme::StatusSuccess) {
- TPathId subDomainPathId = context.SS->GetCurrentSubDomainPathId();
- TSubDomainInfo::TPtr domainPtr = context.SS->ResolveDomainInfo(subDomainPathId);
- domainPtr->UpdateSecurityState(context.SS->LoginProvider.GetSecurityState());
- domainPtr->IncSecurityStateVersion();
- context.SS->PersistSubDomainSecurityStateVersion(db, subDomainPathId, *domainPtr);
- context.OnComplete.PublishToSchemeBoard(OperationId, subDomainPathId);
- }
-
- context.OnComplete.DoneOperation(OperationId);
- return result;
- }
-
- void AbortPropose(TOperationContext&) override {
- Y_FAIL("no AbortPropose for TAlterLogin");
- }
-
- void ProgressState(TOperationContext&) override {
- Y_FAIL("no progress state for TAlterLogin");
- }
-
- void AbortUnsafe(TTxId, TOperationContext&) override {
- Y_FAIL("no AbortUnsafe for TAlterLogin");
- }
-};
-
-}
-
-namespace NKikimr {
+ TPathId subDomainPathId = context.SS->GetCurrentSubDomainPathId();
+ TSubDomainInfo::TPtr domainPtr = context.SS->ResolveDomainInfo(subDomainPathId);
+ domainPtr->UpdateSecurityState(context.SS->LoginProvider.GetSecurityState());
+ domainPtr->IncSecurityStateVersion();
+ context.SS->PersistSubDomainSecurityStateVersion(db, subDomainPathId, *domainPtr);
+ context.OnComplete.PublishToSchemeBoard(OperationId, subDomainPathId);
+ }
+
+ context.OnComplete.DoneOperation(OperationId);
+ return result;
+ }
+
+ void AbortPropose(TOperationContext&) override {
+ Y_FAIL("no AbortPropose for TAlterLogin");
+ }
+
+ void ProgressState(TOperationContext&) override {
+ Y_FAIL("no progress state for TAlterLogin");
+ }
+
+ void AbortUnsafe(TTxId, TOperationContext&) override {
+ Y_FAIL("no AbortUnsafe for TAlterLogin");
+ }
+};
+
+}
+
+namespace NKikimr {
namespace NSchemeShard {
-
-ISubOperationBase::TPtr CreateAlterLogin(TOperationId id, const TTxTransaction& tx) {
- return new TAlterLogin(id, tx);
-}
-
-ISubOperationBase::TPtr CreateAlterLogin(TOperationId id, TTxState::ETxState state) {
- Y_VERIFY(state == TTxState::Invalid || state == TTxState::Propose);
- return new TAlterLogin(id);
-}
-
-}
-}
+
+ISubOperationBase::TPtr CreateAlterLogin(TOperationId id, const TTxTransaction& tx) {
+ return new TAlterLogin(id, tx);
+}
+
+ISubOperationBase::TPtr CreateAlterLogin(TOperationId id, TTxState::ETxState state) {
+ Y_VERIFY(state == TTxState::Invalid || state == TTxState::Propose);
+ return new TAlterLogin(id);
+}
+
+}
+}
diff --git a/ydb/core/tx/schemeshard/schemeshard__operation_alter_pq.cpp b/ydb/core/tx/schemeshard/schemeshard__operation_alter_pq.cpp
index ba83ec48431..f7a47459b97 100644
--- a/ydb/core/tx/schemeshard/schemeshard__operation_alter_pq.cpp
+++ b/ydb/core/tx/schemeshard/schemeshard__operation_alter_pq.cpp
@@ -192,15 +192,15 @@ public:
}
TTxState& PrepareChanges(
- TOperationId operationId,
- const TPath& path,
+ TOperationId operationId,
+ const TPath& path,
TPersQueueGroupInfo::TPtr pqGroup,
ui64 shardsToCreate,
const TChannelsBindings& rbChannelsBinding,
const TChannelsBindings& pqChannelsBinding,
TOperationContext& context)
{
- TPathElement::TPtr item = path.Base();
+ TPathElement::TPtr item = path.Base();
NIceDb::TNiceDb db(context.Txc.DB);
item->LastTxId = operationId.GetTxId();
@@ -227,8 +227,8 @@ public:
ui64 checkShardsToCreate = 0;
for (auto shard : txState.Shards) {
if (shard.Operation == TTxState::CreateParts) {
- TShardInfo& shardInfo = context.SS->ShardInfos[shard.Idx];
- context.SS->PersistShardMapping(db, shard.Idx, shardInfo.TabletID, item->PathId, operationId.GetTxId(), shard.TabletType);
+ TShardInfo& shardInfo = context.SS->ShardInfos[shard.Idx];
+ context.SS->PersistShardMapping(db, shard.Idx, shardInfo.TabletID, item->PathId, operationId.GetTxId(), shard.TabletType);
switch (shard.TabletType) {
case ETabletType::PersQueueReadBalancer:
context.SS->PersistChannelsBinding(db, shard.Idx, rbChannelsBinding);
@@ -239,9 +239,9 @@ public:
context.SS->TabletCounters->Simple()[COUNTER_PQ_SHARD_COUNT].Add(1);
break;
}
- if (!shardInfo.TabletID) {
- ++checkShardsToCreate;
- }
+ if (!shardInfo.TabletID) {
+ ++checkShardsToCreate;
+ }
}
}
Y_VERIFY(shardsToCreate == checkShardsToCreate);
@@ -249,28 +249,28 @@ public:
return txState;
}
- static bool IsChannelsEqual(const TChannelsBindings& a, const TChannelsBindings& b) {
- // for some reason, the default equality operator doesn't work with this proto message
- return std::equal(a.begin(), a.end(), b.begin(), b.end(),
- [](const NKikimrStoragePool::TChannelBind& a, const NKikimrStoragePool::TChannelBind& b) -> bool {
- return a.storagepoolname() == b.storagepoolname()
- && a.iops() == b.iops()
- && a.throughput() == b.throughput()
- && a.size() == b.size();
- });
- }
-
- static bool IsShardRequiresRecreation(const TShardInfo& actual, const TShardInfo& requested) {
- if (actual.BindedChannels.size() < requested.BindedChannels.size()) {
- return true;
- }
- if (actual.BindedChannels.size() == requested.BindedChannels.size()
- && !IsChannelsEqual(actual.BindedChannels, requested.BindedChannels)) {
- return true;
- }
- return false;
- }
-
+ static bool IsChannelsEqual(const TChannelsBindings& a, const TChannelsBindings& b) {
+ // for some reason, the default equality operator doesn't work with this proto message
+ return std::equal(a.begin(), a.end(), b.begin(), b.end(),
+ [](const NKikimrStoragePool::TChannelBind& a, const NKikimrStoragePool::TChannelBind& b) -> bool {
+ return a.storagepoolname() == b.storagepoolname()
+ && a.iops() == b.iops()
+ && a.throughput() == b.throughput()
+ && a.size() == b.size();
+ });
+ }
+
+ static bool IsShardRequiresRecreation(const TShardInfo& actual, const TShardInfo& requested) {
+ if (actual.BindedChannels.size() < requested.BindedChannels.size()) {
+ return true;
+ }
+ if (actual.BindedChannels.size() == requested.BindedChannels.size()
+ && !IsChannelsEqual(actual.BindedChannels, requested.BindedChannels)) {
+ return true;
+ }
+ return false;
+ }
+
bool ApplySharding(
TTxId txId,
const TPathId& pathId,
@@ -280,7 +280,7 @@ public:
const TChannelsBindings& pqBindedChannels,
TOperationContext& context)
{
- TShardInfo defaultShardInfo = TShardInfo::PersQShardInfo(txId, pathId);
+ TShardInfo defaultShardInfo = TShardInfo::PersQShardInfo(txId, pathId);
defaultShardInfo.BindedChannels = pqBindedChannels;
LOG_DEBUG_S(context.Ctx, NKikimrServices::FLAT_TX_SCHEMESHARD,
@@ -312,15 +312,15 @@ public:
// reconfig old shards
for (auto& shard : pqGroup->Shards) {
auto shardIdx = shard.first;
- auto& shardInfo = context.SS->ShardInfos[shardIdx];
-
- if (IsShardRequiresRecreation(shardInfo, defaultShardInfo)) {
- txState.Shards.emplace_back(shardIdx, ETabletType::PersQueue, TTxState::CreateParts);
- shardInfo.CurrentTxId = defaultShardInfo.CurrentTxId;
- shardInfo.BindedChannels = defaultShardInfo.BindedChannels;
- } else {
- txState.Shards.emplace_back(shardIdx, ETabletType::PersQueue, TTxState::ConfigureParts);
- }
+ auto& shardInfo = context.SS->ShardInfos[shardIdx];
+
+ if (IsShardRequiresRecreation(shardInfo, defaultShardInfo)) {
+ txState.Shards.emplace_back(shardIdx, ETabletType::PersQueue, TTxState::CreateParts);
+ shardInfo.CurrentTxId = defaultShardInfo.CurrentTxId;
+ shardInfo.BindedChannels = defaultShardInfo.BindedChannels;
+ } else {
+ txState.Shards.emplace_back(shardIdx, ETabletType::PersQueue, TTxState::ConfigureParts);
+ }
}
// create new shards
@@ -570,13 +570,13 @@ public:
// explicit channel profiles are specified. Read balancer tablet is
// a tablet with local db which doesn't use extra channels in any way.
const ui32 tabletProfileId = 0;
- TChannelsBindings tabletChannelsBinding;
- if (!context.SS->ResolvePqChannels(tabletProfileId, path.DomainId(), tabletChannelsBinding)) {
+ TChannelsBindings tabletChannelsBinding;
+ if (!context.SS->ResolvePqChannels(tabletProfileId, path.DomainId(), tabletChannelsBinding)) {
result->SetError(NKikimrScheme::StatusInvalidParameter,
- "Unable to construct channel binding for PQ with the storage pool");
- return result;
- }
-
+ "Unable to construct channel binding for PQ with the storage pool");
+ return result;
+ }
+
// This channel bindings are for PersQueue shards. They either use
// explicit channel profiles, or reuse channel profile above.
const auto& partConfig = newTabletConfig.GetPartitionConfig();
diff --git a/ydb/core/tx/schemeshard/schemeshard__operation_alter_subdomain.cpp b/ydb/core/tx/schemeshard/schemeshard__operation_alter_subdomain.cpp
index 878660d24a8..dc1208bbb9c 100644
--- a/ydb/core/tx/schemeshard/schemeshard__operation_alter_subdomain.cpp
+++ b/ydb/core/tx/schemeshard/schemeshard__operation_alter_subdomain.cpp
@@ -271,7 +271,7 @@ public:
if (uniqEnd != requestedPools.end()) {
result->SetError(
NKikimrScheme::StatusInvalidParameter,
- "Malformed subdomain request: requested storage pools is not unique, for example, the pool '" + uniqEnd->GetName() +"' repeats several times");
+ "Malformed subdomain request: requested storage pools is not unique, for example, the pool '" + uniqEnd->GetName() +"' repeats several times");
return result;
}
diff --git a/ydb/core/tx/schemeshard/schemeshard__operation_common.h b/ydb/core/tx/schemeshard/schemeshard__operation_common.h
index 2bbeab93d29..5a3da32cade 100644
--- a/ydb/core/tx/schemeshard/schemeshard__operation_common.h
+++ b/ydb/core/tx/schemeshard/schemeshard__operation_common.h
@@ -297,9 +297,9 @@ public:
switch (type) {
case ETabletType::Coordinator:
- case ETabletType::Mediator: {
+ case ETabletType::Mediator: {
LOG_DEBUG_S(context.Ctx, NKikimrServices::FLAT_TX_SCHEMESHARD,
- "Send configure request to coordinator/mediator: " << tabletID <<
+ "Send configure request to coordinator/mediator: " << tabletID <<
" opId: " << OperationId <<
" schemeshard: " << ssId);
shard.Operation = TTxState::ConfigureParts;
@@ -307,16 +307,16 @@ public:
context.OnComplete.BindMsgToPipe(OperationId, tabletID, idx, event);
break;
}
- case ETabletType::Hive: {
- LOG_DEBUG_S(context.Ctx, NKikimrServices::FLAT_TX_SCHEMESHARD,
- "Send configure request to hive: " << tabletID <<
- " opId: " << OperationId <<
- " schemeshard: " << ssId);
- shard.Operation = TTxState::ConfigureParts;
- auto event = new TEvHive::TEvConfigureHive(TSubDomainKey(pathId.OwnerId, pathId.LocalPathId));
- context.OnComplete.BindMsgToPipe(OperationId, tabletID, idx, event);
- break;
- }
+ case ETabletType::Hive: {
+ LOG_DEBUG_S(context.Ctx, NKikimrServices::FLAT_TX_SCHEMESHARD,
+ "Send configure request to hive: " << tabletID <<
+ " opId: " << OperationId <<
+ " schemeshard: " << ssId);
+ shard.Operation = TTxState::ConfigureParts;
+ auto event = new TEvHive::TEvConfigureHive(TSubDomainKey(pathId.OwnerId, pathId.LocalPathId));
+ context.OnComplete.BindMsgToPipe(OperationId, tabletID, idx, event);
+ break;
+ }
case ETabletType::SysViewProcessor: {
LOG_DEBUG_S(context.Ctx, NKikimrServices::FLAT_TX_SCHEMESHARD,
"Send configure request to sysview processor: " << tabletID <<
@@ -609,24 +609,24 @@ public:
}
if (shardInfo.TabletID == InvalidTabletId) {
- switch (shardInfo.TabletType) {
- case ETabletType::DataShard:
+ switch (shardInfo.TabletType) {
+ case ETabletType::DataShard:
context.SS->TabletCounters->Simple()[COUNTER_TABLE_SHARD_ACTIVE_COUNT].Add(1);
- break;
- case ETabletType::Coordinator:
+ break;
+ case ETabletType::Coordinator:
context.SS->TabletCounters->Simple()[COUNTER_SUB_DOMAIN_COORDINATOR_COUNT].Add(1);
- break;
- case ETabletType::Mediator:
+ break;
+ case ETabletType::Mediator:
context.SS->TabletCounters->Simple()[COUNTER_SUB_DOMAIN_MEDIATOR_COUNT].Add(1);
- break;
- case ETabletType::Hive:
- context.SS->TabletCounters->Simple()[COUNTER_SUB_DOMAIN_HIVE_COUNT].Add(1);
- break;
+ break;
+ case ETabletType::Hive:
+ context.SS->TabletCounters->Simple()[COUNTER_SUB_DOMAIN_HIVE_COUNT].Add(1);
+ break;
case ETabletType::SysViewProcessor:
context.SS->TabletCounters->Simple()[COUNTER_SYS_VIEW_PROCESSOR_COUNT].Add(1);
break;
- default:
- break;
+ default:
+ break;
}
}
@@ -672,13 +672,13 @@ public:
TPathId domainId = context.SS->ResolveDomainId(targetPath);
TPathElement::TPtr domainEl = context.SS->PathsById.at(domainId);
- auto objectDomain = ev->Record.MutableObjectDomain();
+ auto objectDomain = ev->Record.MutableObjectDomain();
if (domainEl->IsRoot()) {
- objectDomain->SetSchemeShard(context.SS->ParentDomainId.OwnerId);
- objectDomain->SetPathId(context.SS->ParentDomainId.LocalPathId);
+ objectDomain->SetSchemeShard(context.SS->ParentDomainId.OwnerId);
+ objectDomain->SetPathId(context.SS->ParentDomainId.LocalPathId);
} else {
- objectDomain->SetSchemeShard(domainId.OwnerId);
- objectDomain->SetPathId(domainId.LocalPathId);
+ objectDomain->SetSchemeShard(domainId.OwnerId);
+ objectDomain->SetPathId(domainId.LocalPathId);
}
Y_VERIFY(context.SS->SubDomains.contains(domainId));
@@ -693,10 +693,10 @@ public:
Y_FAIL("Cannot retrieve resources domain id");
}
- auto allowedDomain = ev->Record.AddAllowedDomains();
+ auto allowedDomain = ev->Record.AddAllowedDomains();
allowedDomain->SetSchemeShard(resourcesDomainId.OwnerId);
allowedDomain->SetPathId(resourcesDomainId.LocalPathId);
-
+
if (tablePartitionConfig) {
if (tablePartitionConfig->FollowerGroupsSize()) {
ev->Record.MutableFollowerGroups()->CopyFrom(tablePartitionConfig->GetFollowerGroups());
@@ -722,10 +722,10 @@ public:
ev->Record.SetObjectId(targetPath->PathId.LocalPathId);
- if (shard.TabletID) {
- ev->Record.SetTabletID(ui64(shard.TabletID));
- }
-
+ if (shard.TabletID) {
+ ev->Record.SetTabletID(ui64(shard.TabletID));
+ }
+
return ev;
}
diff --git a/ydb/core/tx/schemeshard/schemeshard__operation_create_pq.cpp b/ydb/core/tx/schemeshard/schemeshard__operation_create_pq.cpp
index ab4e45c956d..992fd3175c2 100644
--- a/ydb/core/tx/schemeshard/schemeshard__operation_create_pq.cpp
+++ b/ydb/core/tx/schemeshard/schemeshard__operation_create_pq.cpp
@@ -172,15 +172,15 @@ TPersQueueGroupInfo::TPtr CreatePersQueueGroup(TOperationContext& context,
return pqGroupInfo;
}
-void ApplySharding(TTxId txId,
- TPathId pathId,
- TPersQueueGroupInfo::TPtr pqGroup,
- TTxState& txState,
+void ApplySharding(TTxId txId,
+ TPathId pathId,
+ TPersQueueGroupInfo::TPtr pqGroup,
+ TTxState& txState,
const TChannelsBindings& rbBindedChannels,
const TChannelsBindings& pqBindedChannels,
TSchemeShard* ss) {
pqGroup->AlterVersion = 0;
- TShardInfo shardInfo = TShardInfo::PersQShardInfo(txId, pathId);
+ TShardInfo shardInfo = TShardInfo::PersQShardInfo(txId, pathId);
shardInfo.BindedChannels = pqBindedChannels;
Y_VERIFY(pqGroup->TotalGroupCount == pqGroup->PartitionsToAdd.size());
const ui64 count = pqGroup->ExpectedShardCount();
@@ -422,13 +422,13 @@ public:
// explicit channel profiles are specified. Read balancer tablet is
// a tablet with local db which doesn't use extra channels in any way.
const ui32 tabletProfileId = 0;
- TChannelsBindings tabletChannelsBinding;
- if (!context.SS->ResolvePqChannels(tabletProfileId, dstPath.DomainId(), tabletChannelsBinding)) {
+ TChannelsBindings tabletChannelsBinding;
+ if (!context.SS->ResolvePqChannels(tabletProfileId, dstPath.DomainId(), tabletChannelsBinding)) {
result->SetError(NKikimrScheme::StatusInvalidParameter,
- "Unable to construct channel binding for PQ with the storage pool");
- return result;
- }
-
+ "Unable to construct channel binding for PQ with the storage pool");
+ return result;
+ }
+
// This channel bindings are for PersQueue shards. They either use
// explicit channel profiles, or reuse channel profile above.
const auto& partConfig = createDEscription.GetPQTabletConfig().GetPartitionConfig();
@@ -498,7 +498,7 @@ public:
for (auto shard : txState.Shards) {
Y_VERIFY(shard.Operation == TTxState::CreateParts);
context.SS->PersistShardMapping(db, shard.Idx, InvalidTabletId, pathId, OperationId.GetTxId(), shard.TabletType);
- context.SS->PersistChannelsBinding(db, shard.Idx, tabletChannelsBinding);
+ context.SS->PersistChannelsBinding(db, shard.Idx, tabletChannelsBinding);
}
Y_VERIFY(txState.Shards.size() == shardsToCreate);
context.SS->TabletCounters->Simple()[COUNTER_PQ_SHARD_COUNT].Add(shardsToCreate-1);
diff --git a/ydb/core/tx/schemeshard/schemeshard__operation_part.h b/ydb/core/tx/schemeshard/schemeshard__operation_part.h
index 1c8bad791d8..4a639e63429 100644
--- a/ydb/core/tx/schemeshard/schemeshard__operation_part.h
+++ b/ydb/core/tx/schemeshard/schemeshard__operation_part.h
@@ -378,9 +378,9 @@ ISubOperationBase::TPtr CreateAlterFileStore(TOperationId id, TTxState::ETxState
ISubOperationBase::TPtr CreateDropFileStore(TOperationId id, const TTxTransaction& tx);
ISubOperationBase::TPtr CreateDropFileStore(TOperationId id, TTxState::ETxState state);
-ISubOperationBase::TPtr CreateAlterLogin(TOperationId id, const TTxTransaction& tx);
-ISubOperationBase::TPtr CreateAlterLogin(TOperationId id, TTxState::ETxState state);
-
+ISubOperationBase::TPtr CreateAlterLogin(TOperationId id, const TTxTransaction& tx);
+ISubOperationBase::TPtr CreateAlterLogin(TOperationId id, TTxState::ETxState state);
+
TVector<ISubOperationBase::TPtr> CreateConsistentMoveTable(TOperationId id, const TTxTransaction& tx, TOperationContext& context);
ISubOperationBase::TPtr CreateMoveTable(TOperationId id, const TTxTransaction& tx);
diff --git a/ydb/core/tx/schemeshard/schemeshard__table_stats.cpp b/ydb/core/tx/schemeshard/schemeshard__table_stats.cpp
index befde6a90cb..b2e7db88b79 100644
--- a/ydb/core/tx/schemeshard/schemeshard__table_stats.cpp
+++ b/ydb/core/tx/schemeshard/schemeshard__table_stats.cpp
@@ -5,14 +5,14 @@
namespace NKikimr {
namespace NSchemeShard {
-template <typename T>
-static ui64 GetThroughput(const T& c) {
- ui64 acc = 0;
- for (const auto& v : c)
- acc += v.GetThroughput();
- return acc;
-}
-
+template <typename T>
+static ui64 GetThroughput(const T& c) {
+ ui64 acc = 0;
+ for (const auto& v : c)
+ acc += v.GetThroughput();
+ return acc;
+}
+
template <typename T>
static ui64 GetIops(const T& c) {
ui64 acc = 0;
@@ -126,7 +126,7 @@ bool TTxStorePartitionStats::Execute(TTransactionContext& txc, const TActorConte
}
const auto& tableStats = rec.GetTableStats();
- const auto& tabletMetrics = rec.GetTabletMetrics();
+ const auto& tabletMetrics = rec.GetTabletMetrics();
ui64 dataSize = tableStats.GetDataSize();
ui64 rowCount = tableStats.GetRowCount();
@@ -166,11 +166,11 @@ bool TTxStorePartitionStats::Execute(TTransactionContext& txc, const TActorConte
TInstant now = AppData(ctx)->TimeProvider->Now();
newStats.SetCurrentRawCpuUsage(tabletMetrics.GetCPU(), now);
- newStats.Memory = tabletMetrics.GetMemory();
- newStats.Network = tabletMetrics.GetNetwork();
- newStats.Storage = tabletMetrics.GetStorage();
- newStats.ReadThroughput = GetThroughput(tabletMetrics.GetGroupReadThroughput());
- newStats.WriteThroughput = GetThroughput(tabletMetrics.GetGroupWriteThroughput());
+ newStats.Memory = tabletMetrics.GetMemory();
+ newStats.Network = tabletMetrics.GetNetwork();
+ newStats.Storage = tabletMetrics.GetStorage();
+ newStats.ReadThroughput = GetThroughput(tabletMetrics.GetGroupReadThroughput());
+ newStats.WriteThroughput = GetThroughput(tabletMetrics.GetGroupWriteThroughput());
newStats.ReadIops = GetIops(tabletMetrics.GetGroupReadIops());
newStats.WriteIops = GetIops(tabletMetrics.GetGroupWriteIops());
newStats.PartCount = tableStats.GetPartCount();
diff --git a/ydb/core/tx/schemeshard/schemeshard_domain_links.cpp b/ydb/core/tx/schemeshard/schemeshard_domain_links.cpp
index bd591878ff4..b50aaa509a3 100644
--- a/ydb/core/tx/schemeshard/schemeshard_domain_links.cpp
+++ b/ydb/core/tx/schemeshard/schemeshard_domain_links.cpp
@@ -7,10 +7,10 @@ namespace NSchemeShard {
TParentDomainLink::TParentDomainLink(NKikimr::NSchemeShard::TSchemeShard *self)
: Self(self)
{
- PipeClientConfig.RetryPolicy = {
- .MinRetryTime = TDuration::MilliSeconds(10),
- .MaxRetryTime = TDuration::Minutes(5),
- };
+ PipeClientConfig.RetryPolicy = {
+ .MinRetryTime = TDuration::MilliSeconds(10),
+ .MaxRetryTime = TDuration::Minutes(5),
+ };
}
THolder<TEvSchemeShard::TEvSyncTenantSchemeShard> TParentDomainLink::MakeSyncMsg() const {
diff --git a/ydb/core/tx/schemeshard/schemeshard_impl.cpp b/ydb/core/tx/schemeshard/schemeshard_impl.cpp
index 475974f6072..0715543a229 100644
--- a/ydb/core/tx/schemeshard/schemeshard_impl.cpp
+++ b/ydb/core/tx/schemeshard/schemeshard_impl.cpp
@@ -62,9 +62,9 @@ void TSchemeShard::ActivateAfterInitialization(const TActorContext& ctx,
TDeque<TPathId>&& blockStoreVolumesToClean
)
{
- TPathId subDomainPathId = GetCurrentSubDomainPathId();
- TSubDomainInfo::TPtr domainPtr = ResolveDomainInfo(subDomainPathId);
- LoginProvider.Audience = TPath::Init(subDomainPathId, this).PathString();
+ TPathId subDomainPathId = GetCurrentSubDomainPathId();
+ TSubDomainInfo::TPtr domainPtr = ResolveDomainInfo(subDomainPathId);
+ LoginProvider.Audience = TPath::Init(subDomainPathId, this).PathString();
domainPtr->UpdateSecurityState(LoginProvider.GetSecurityState());
Execute(CreateTxInitPopulator(std::move(delayPublications)), ctx);
@@ -349,8 +349,8 @@ bool TSchemeShard::ApplyStorageConfig(
{
if (channelsBinding && !reverseBinding) {
// Build a hash map from storage pool name to an existing channel number
- for (ui32 channel = 1; channel < channelsBinding.size(); ++channel) {
- reverseBinding.emplace(channelsBinding[channel].GetStoragePoolName(), channel);
+ for (ui32 channel = 1; channel < channelsBinding.size(); ++channel) {
+ reverseBinding.emplace(channelsBinding[channel].GetStoragePoolName(), channel);
}
}
@@ -380,8 +380,8 @@ bool TSchemeShard::ApplyStorageConfig(
}
ui32 channel = channelsBinding.size();
- channelsBinding.emplace_back();
- channelsBinding.back().SetStoragePoolName(poolName);
+ channelsBinding.emplace_back();
+ channelsBinding.back().SetStoragePoolName(poolName);
reverseBinding[poolName] = channel;
return channel;
};
@@ -397,8 +397,8 @@ bool TSchemeShard::ApplyStorageConfig(
auto sysLogPool = resolve(storagePools, storageConfig.GetSysLog());
LOCAL_CHECK(sysLogPool != storagePools.end(), "unable determine pool for syslog storage");
- channelsBinding.emplace_back();
- channelsBinding.back().SetStoragePoolName(sysLogPool->GetName());
+ channelsBinding.emplace_back();
+ channelsBinding.back().SetStoragePoolName(sysLogPool->GetName());
}
if (channelsBinding.size() < 2) {
@@ -435,7 +435,7 @@ bool TSchemeShard::ApplyStorageConfig(
#undef LOCAL_CHECK
return true;
- return true;
+ return true;
}
void TSchemeShard::ClearDescribePathCaches(const TPathElement::TPtr node) {
@@ -579,9 +579,9 @@ bool TSchemeShard::GetBindingsRoomsChanges(
continue;
}
- auto shardPoolsMapping = GetPoolsMapping(shardInfo.BindedChannels);
-
- auto& change = changes[shardPoolsMapping];
+ auto shardPoolsMapping = GetPoolsMapping(shardInfo.BindedChannels);
+
+ auto& change = changes[shardPoolsMapping];
if (change.ChannelsBindings) {
// This change info is already initialized
continue;
@@ -595,7 +595,7 @@ bool TSchemeShard::GetBindingsRoomsChanges(
if (!GetBindingsRooms(domainId, partitionConfig, storageRooms, familyRooms, change.ChannelsBindings, errStr)) {
return false;
}
- change.ChannelsBindingsUpdated = (GetPoolsMapping(change.ChannelsBindings) != shardPoolsMapping);
+ change.ChannelsBindingsUpdated = (GetPoolsMapping(change.ChannelsBindings) != shardPoolsMapping);
for (const auto& room : storageRooms) {
change.PerShardConfig.AddStorageRooms()->CopyFrom(room);
@@ -772,10 +772,10 @@ bool TSchemeShard::ResolveSolomonChannels(ui32 profileId, const TPathId domainId
}
bool TSchemeShard::ResolvePqChannels(ui32 profileId, const TPathId domainId, TChannelsBindings &channelsBinding) const
-{
- return ResolveChannelCommon(profileId, domainId, channelsBinding, &ResolveChannelsDetailsAsIs);
-}
-
+{
+ return ResolveChannelCommon(profileId, domainId, channelsBinding, &ResolveChannelsDetailsAsIs);
+}
+
bool TSchemeShard::ResolveChannelsByPoolKinds(
const TVector<TStringBuf> &channelPoolKinds,
const TPathId domainId,
@@ -866,7 +866,7 @@ bool TSchemeShard::ResolveSubdomainsChannels(const TStoragePools &storagePools,
channelsBinding.clear();
return false;
}
- if (ChannelProfiles->Profiles.empty()) {
+ if (ChannelProfiles->Profiles.empty()) {
channelsBinding.clear();
return false;
}
@@ -943,8 +943,8 @@ bool TSchemeShard::TabletResolveChannelsDetails(ui32 profileId, const TChannelPr
// sys log channel is 0
// log channel is 1 always
if (0 == channelId || 1 == channelId) {
- result.emplace_back();
- result.back().SetStoragePoolName(poolIt->GetName());
+ result.emplace_back();
+ result.back().SetStoragePoolName(poolIt->GetName());
continue;
}
@@ -952,8 +952,8 @@ bool TSchemeShard::TabletResolveChannelsDetails(ui32 profileId, const TChannelPr
// but we already already provide for clients variable like ColumnStorage1Ext2
// so we do not want to break them and we should always make at least 3 channe until StorageConfig is mainstream
if (uniqPoolsNames.insert(poolIt->GetName()).second) {
- result.emplace_back();
- result.back().SetStoragePoolName(poolIt->GetName());
+ result.emplace_back();
+ result.back().SetStoragePoolName(poolIt->GetName());
}
}
@@ -1732,13 +1732,13 @@ void TSchemeShard::PersistSubDomainVersion(NIceDb::TNiceDb& db, const TPathId& p
}
void TSchemeShard::PersistSubDomainSecurityStateVersion(NIceDb::TNiceDb& db, const TPathId& pathId, const TSubDomainInfo& subDomain) {
- Y_VERIFY(IsLocalId(pathId));
-
- db.Table<Schema::SubDomains>()
- .Key(pathId.LocalPathId)
- .Update<Schema::SubDomains::SecurityStateVersion>(subDomain.GetSecurityStateVersion());
-}
-
+ Y_VERIFY(IsLocalId(pathId));
+
+ db.Table<Schema::SubDomains>()
+ .Key(pathId.LocalPathId)
+ .Update<Schema::SubDomains::SecurityStateVersion>(subDomain.GetSecurityStateVersion());
+}
+
void TSchemeShard::PersistSubDomain(NIceDb::TNiceDb& db, const TPathId& pathId, const TSubDomainInfo& subDomain) {
Y_VERIFY(IsLocalId(pathId));
@@ -1865,8 +1865,8 @@ void TSchemeShard::PersistACL(NIceDb::TNiceDb& db, const TPathElement::TPtr path
NIceDb::TUpdate<Schema::MigratedPaths::ACL>(path->ACL),
NIceDb::TUpdate<Schema::MigratedPaths::ACLVersion>(path->ACLVersion));
}
-}
-
+}
+
void TSchemeShard::PersistOwner(NIceDb::TNiceDb& db, const TPathElement::TPtr path) {
if (path->PathId.OwnerId == TabletID()) {
@@ -2019,11 +2019,11 @@ void TSchemeShard::PersistTable(NIceDb::TNiceDb& db, const TPathId tableId) {
}
void TSchemeShard::PersistChannelsBinding(NIceDb::TNiceDb& db, const TShardIdx shardId, const TChannelsBindings& bindedChannels) {
- for (ui32 channelId = 0; channelId < bindedChannels.size(); ++channelId) {
- const auto& bind = bindedChannels[channelId];
+ for (ui32 channelId = 0; channelId < bindedChannels.size(); ++channelId) {
+ const auto& bind = bindedChannels[channelId];
if (IsLocalId(shardId)) {
db.Table<Schema::ChannelsBinding>().Key(shardId.GetLocalId(), channelId).Update(
- NIceDb::TUpdate<Schema::ChannelsBinding::PoolName>(bind.GetStoragePoolName()),
+ NIceDb::TUpdate<Schema::ChannelsBinding::PoolName>(bind.GetStoragePoolName()),
NIceDb::TUpdate<Schema::ChannelsBinding::Binding>(bind.SerializeAsString()));
} else {
db.Table<Schema::MigratedChannelsBinding>().Key(shardId.GetOwnerId(), shardId.GetLocalId(), channelId).Update(
@@ -2590,7 +2590,7 @@ void TSchemeShard::PersistShardDeleted(NIceDb::TNiceDb& db, TShardIdx shardIdx,
db.Table<Schema::MigratedShardsToDelete>().Key(shardIdx.GetOwnerId(), shardIdx.GetLocalId()).Delete();
db.Table<Schema::MigratedShards>().Key(shardIdx.GetOwnerId(), shardIdx.GetLocalId()).Delete();
- for (ui32 channelId = 0; channelId < bindedChannels.size(); ++channelId) {
+ for (ui32 channelId = 0; channelId < bindedChannels.size(); ++channelId) {
db.Table<Schema::MigratedChannelsBinding>().Key(shardIdx.GetOwnerId(), shardIdx.GetLocalId(), channelId).Delete();
}
db.Table<Schema::MigratedTableShardPartitionConfigs>().Key(shardIdx.GetOwnerId(), shardIdx.GetLocalId()).Delete();
@@ -3417,18 +3417,18 @@ TTabletId TSchemeShard::ResolveHive(TShardIdx shardIdx, const TActorContext& ctx
}
void TSchemeShard::DoShardsDeletion(const THashSet<TShardIdx>& shardIdxs, const TActorContext& ctx) {
- TMap<TTabletId, THashSet<TShardIdx>> shardsPerHive;
- for (TShardIdx shardIdx : shardIdxs) {
+ TMap<TTabletId, THashSet<TShardIdx>> shardsPerHive;
+ for (TShardIdx shardIdx : shardIdxs) {
TTabletId hiveToRequest = ResolveHive(shardIdx, ctx);
shardsPerHive[hiveToRequest].emplace(shardIdx);
- }
+ }
for (const auto& item: shardsPerHive) {
const auto& hive = item.first;
const auto& shards = item.second;
- ShardDeleter.SendDeleteRequests(hive, shards, ShardInfos, ctx);
- }
+ ShardDeleter.SendDeleteRequests(hive, shards, ShardInfos, ctx);
+ }
}
NKikimrSchemeOp::TPathVersion TSchemeShard::GetPathVersion(const TPath& path) const {
@@ -3448,12 +3448,12 @@ NKikimrSchemeOp::TPathVersion TSchemeShard::GetPathVersion(const TPath& path) co
switch(pathEl->PathType) {
case NKikimrSchemeOp::EPathType::EPathTypeDir:
if (pathEl->IsRoot() && IsDomainSchemeShard) {
- TSubDomainInfo::TPtr subDomain = SubDomains.at(pathId);
+ TSubDomainInfo::TPtr subDomain = SubDomains.at(pathId);
Y_VERIFY(SubDomains.contains(pathId));
- result.SetSubDomainVersion(subDomain->GetVersion());
- result.SetSecurityStateVersion(subDomain->GetSecurityStateVersion());
+ result.SetSubDomainVersion(subDomain->GetVersion());
+ result.SetSecurityStateVersion(subDomain->GetSecurityStateVersion());
generalVersion += result.GetSubDomainVersion();
- generalVersion += result.GetSecurityStateVersion();
+ generalVersion += result.GetSecurityStateVersion();
}
break;
case NKikimrSchemeOp::EPathType::EPathTypeSubDomain:
@@ -3461,18 +3461,18 @@ NKikimrSchemeOp::TPathVersion TSchemeShard::GetPathVersion(const TPath& path) co
Y_VERIFY(!(pathEl->IsRoot() && IsDomainSchemeShard));
Y_VERIFY(SubDomains.contains(pathId));
- TSubDomainInfo::TPtr subDomain = SubDomains.at(pathId);
- result.SetSubDomainVersion(subDomain->GetVersion());
- result.SetSecurityStateVersion(subDomain->GetSecurityStateVersion());
+ TSubDomainInfo::TPtr subDomain = SubDomains.at(pathId);
+ result.SetSubDomainVersion(subDomain->GetVersion());
+ result.SetSecurityStateVersion(subDomain->GetSecurityStateVersion());
generalVersion += result.GetSubDomainVersion();
- generalVersion += result.GetSecurityStateVersion();
+ generalVersion += result.GetSecurityStateVersion();
- if (ui64 version = subDomain->GetDomainStateVersion()) {
+ if (ui64 version = subDomain->GetDomainStateVersion()) {
result.SetSubDomainStateVersion(version);
generalVersion += version;
}
break;
- }
+ }
case NKikimrSchemeOp::EPathType::EPathTypeTable:
Y_VERIFY_S(Tables.contains(pathId),
"no table with id: " << pathId << ", at schemeshard: " << SelfTabletId());
@@ -3675,10 +3675,10 @@ NKikimrSubDomains::TProcessingParams TSchemeShard::CreateRootProcessingParams(co
NTabletPipe::TClientConfig TSchemeShard::GetPipeClientConfig() {
NTabletPipe::TClientConfig config;
- config.RetryPolicy = {
- .MinRetryTime = TDuration::MilliSeconds(50),
- .MaxRetryTime = TDuration::Seconds(2),
- };
+ config.RetryPolicy = {
+ .MinRetryTime = TDuration::MilliSeconds(50),
+ .MaxRetryTime = TDuration::Seconds(2),
+ };
return config;
}
@@ -3995,7 +3995,7 @@ void TSchemeShard::StateWork(STFUNC_SIG) {
HFuncTraced(TEvPrivate::TEvSubscribeToShardDeletion, Handle);
HFuncTraced(TEvSchemeShard::TEvLogin, Handle);
-
+
default:
if (!HandleDefaultEvents(ev, ctx)) {
LOG_WARN_S(ctx, NKikimrServices::FLAT_TX_SCHEMESHARD,
@@ -4553,7 +4553,7 @@ void TSchemeShard::Handle(TEvTabletPipe::TEvClientConnected::TPtr &ev, const TAc
}
if (ShardDeleter.Has(tabletId, clientId)) {
- ShardDeleter.ResendDeleteRequests(TTabletId(ev->Get()->TabletId), ShardInfos, ctx);
+ ShardDeleter.ResendDeleteRequests(TTabletId(ev->Get()->TabletId), ShardInfos, ctx);
return;
}
@@ -4595,7 +4595,7 @@ void TSchemeShard::Handle(TEvTabletPipe::TEvClientDestroyed::TPtr &ev, const TAc
}
if (ShardDeleter.Has(tabletId, clientId)) {
- ShardDeleter.ResendDeleteRequests(tabletId, ShardInfos, ctx);
+ ShardDeleter.ResendDeleteRequests(tabletId, ShardInfos, ctx);
return;
}
@@ -5847,10 +5847,10 @@ bool TSchemeShard::ReadSysValue(NIceDb::TNiceDb &db, ui64 sysTag, ui64 &value, u
}
TSchemeShard::TDedicatedPipePool::TDedicatedPipePool() {
- PipeCfg.RetryPolicy = {
- .MinRetryTime = TDuration::MilliSeconds(100),
- .MaxRetryTime = TDuration::Seconds(30),
- };
+ PipeCfg.RetryPolicy = {
+ .MinRetryTime = TDuration::MilliSeconds(100),
+ .MaxRetryTime = TDuration::Seconds(30),
+ };
}
void TSchemeShard::TDedicatedPipePool::Create(TIndexBuildId ownerTxId, TTabletId dst, THolder<IEventBase> message, const TActorContext &ctx) {
@@ -6086,8 +6086,8 @@ void TSchemeShard::ChangeDiskSpaceSoftQuotaBytes(i64 delta) {
}
void TSchemeShard::Handle(TEvSchemeShard::TEvLogin::TPtr &ev, const TActorContext &ctx) {
- Execute(CreateTxLogin(ev), ctx);
-}
-
+ Execute(CreateTxLogin(ev), ctx);
+}
+
} // namespace NSchemeShard
} // namespace NKikimr
diff --git a/ydb/core/tx/schemeshard/schemeshard_impl.h b/ydb/core/tx/schemeshard/schemeshard_impl.h
index c0768b686f7..e1a1d08b9a6 100644
--- a/ydb/core/tx/schemeshard/schemeshard_impl.h
+++ b/ydb/core/tx/schemeshard/schemeshard_impl.h
@@ -49,7 +49,7 @@
#include <ydb/core/filestore/core/filestore.h>
#include <ydb/library/login/login.h>
-
+
#include <util/generic/ptr.h>
namespace NKikimr {
@@ -251,10 +251,10 @@ public:
return shardIdx.GetOwnerId() == TabletID();
}
- TPathId GetCurrentSubDomainPathId() const {
- return RootPathId();
- }
-
+ TPathId GetCurrentSubDomainPathId() const {
+ return RootPathId();
+ }
+
TPathId PeekNextPathId() const {
return MakeLocalId(NextLocalPathId);
}
@@ -332,7 +332,7 @@ public:
bool ResolveTabletChannels(ui32 profileId, const TPathId domainId, TChannelsBindings& channelsBinding) const;
bool ResolveRtmrChannels(const TPathId domainId, TChannelsBindings& channelsBinding) const;
bool ResolveSolomonChannels(ui32 profileId, const TPathId domainId, TChannelsBindings& channelsBinding) const;
- bool ResolvePqChannels(ui32 profileId, const TPathId domainId, TChannelsBindings& channelsBinding) const;
+ bool ResolvePqChannels(ui32 profileId, const TPathId domainId, TChannelsBindings& channelsBinding) const;
bool ResolveChannelsByPoolKinds(
const TVector<TStringBuf>& channelPoolKinds,
const TPathId domainId,
@@ -517,7 +517,7 @@ public:
void PersistSubDomainDatabaseQuotas(NIceDb::TNiceDb& db, const TPathId& pathId, const TSubDomainInfo& subDomain);
void PersistSubDomainState(NIceDb::TNiceDb& db, const TPathId& pathId, const TSubDomainInfo& subDomain);
void PersistSubDomainSchemeQuotas(NIceDb::TNiceDb& db, const TPathId& pathId, const TSubDomainInfo& subDomain);
- void PersistSubDomainSecurityStateVersion(NIceDb::TNiceDb& db, const TPathId& pathId, const TSubDomainInfo& subDomain);
+ void PersistSubDomainSecurityStateVersion(NIceDb::TNiceDb& db, const TPathId& pathId, const TSubDomainInfo& subDomain);
void PersistDeleteSubDomainAlter(NIceDb::TNiceDb& db, const TPathId& pathId, const TSubDomainInfo& subDomain);
void PersistKesusInfo(NIceDb::TNiceDb& db, TPathId pathId, const TKesusInfo::TPtr);
void PersistKesusVersion(NIceDb::TNiceDb& db, TPathId pathId, const TKesusInfo::TPtr);
@@ -697,10 +697,10 @@ public:
struct TTxServerlessStorageBilling;
NTabletFlatExecutor::ITransaction* CreateTxServerlessStorageBilling();
- struct TTxLogin;
+ struct TTxLogin;
NTabletFlatExecutor::ITransaction* CreateTxLogin(TEvSchemeShard::TEvLogin::TPtr &ev);
-
+
template<class T> struct TTxOperationReply;
#define DeclareCreateTxOperationReply(TEvType, TxType) \
NTabletFlatExecutor::ITransaction* CreateTxOperationReply(TOperationId id, TEvType::TPtr& ev);
@@ -827,7 +827,7 @@ public:
void Handle(NConsole::TEvConsole::TEvConfigNotificationRequest::TPtr &ev, const TActorContext &ctx);
void Handle(TEvSchemeShard::TEvLogin::TPtr& ev, const TActorContext& ctx);
-
+
void RestartPipeTx(TTabletId tabletId, const TActorContext& ctx);
TOperationId RouteIncomming(TTabletId tabletId, const TActorContext& ctx);
@@ -1060,7 +1060,7 @@ public:
void ChangeDiskSpaceHardQuotaBytes(i64 delta) override;
void ChangeDiskSpaceSoftQuotaBytes(i64 delta) override;
- NLogin::TLoginProvider LoginProvider;
+ NLogin::TLoginProvider LoginProvider;
private:
void OnDetach(const TActorContext &ctx) override;
diff --git a/ydb/core/tx/schemeshard/schemeshard_info_types.cpp b/ydb/core/tx/schemeshard/schemeshard_info_types.cpp
index 122b966c92a..fcb564b6065 100644
--- a/ydb/core/tx/schemeshard/schemeshard_info_types.cpp
+++ b/ydb/core/tx/schemeshard/schemeshard_info_types.cpp
@@ -1631,14 +1631,14 @@ bool TTableInfo::CheckSplitByLoad(const TSplitSettings& splitSettings, TShardIdx
return true;
}
-TChannelsMapping GetPoolsMapping(const TChannelsBindings& bindings) {
- TChannelsMapping mapping;
- for (const auto& bind : bindings) {
- mapping.emplace_back(bind.GetStoragePoolName());
- }
- return mapping;
-}
-
+TChannelsMapping GetPoolsMapping(const TChannelsBindings& bindings) {
+ TChannelsMapping mapping;
+ for (const auto& bind : bindings) {
+ mapping.emplace_back(bind.GetStoragePoolName());
+ }
+ return mapping;
+}
+
TString TExportInfo::ToString() const {
return TStringBuilder() << "{"
<< " Id: " << Id
diff --git a/ydb/core/tx/schemeshard/schemeshard_info_types.h b/ydb/core/tx/schemeshard/schemeshard_info_types.h
index b709b54e66d..2e5710c3d3e 100644
--- a/ydb/core/tx/schemeshard/schemeshard_info_types.h
+++ b/ydb/core/tx/schemeshard/schemeshard_info_types.h
@@ -19,7 +19,7 @@
#include <ydb/core/util/counted_leaky_bucket.h>
#include <ydb/library/login/protos/login.pb.h>
-
+
#include <ydb/public/api/protos/ydb_import.pb.h>
#include <ydb/public/lib/scheme_types/scheme_type_id.h>
@@ -73,14 +73,14 @@ struct TBindingsRoomsChange {
bool ChannelsBindingsUpdated = false;
};
-using TChannelsMapping = TVector<TString>; // channel idx -> storage pool name
-
+using TChannelsMapping = TVector<TString>; // channel idx -> storage pool name
+
/**
* Maps original channels bindings to possible updates
*/
-using TBindingsRoomsChanges = TMap<TChannelsMapping, TBindingsRoomsChange>;
+using TBindingsRoomsChanges = TMap<TChannelsMapping, TBindingsRoomsChange>;
-TChannelsMapping GetPoolsMapping(const TChannelsBindings& bindings);
+TChannelsMapping GetPoolsMapping(const TChannelsBindings& bindings);
struct TTableShardInfo {
TShardIdx ShardIdx = InvalidShardIdx;
@@ -1258,12 +1258,12 @@ struct TSubDomainInfo: TSimpleRefCount<TSubDomainInfo> {
}
TTabletId GetTenantHiveID() const {
- if (!ProcessingParams.HasHive()) {
- return InvalidTabletId;
- }
- return TTabletId(ProcessingParams.GetHive());
- }
-
+ if (!ProcessingParams.HasHive()) {
+ return InvalidTabletId;
+ }
+ return TTabletId(ProcessingParams.GetHive());
+ }
+
TTabletId GetTenantSysViewProcessorID() const {
if (!ProcessingParams.HasSysViewProcessor()) {
return InvalidTabletId;
@@ -1598,14 +1598,14 @@ struct TSubDomainInfo: TSimpleRefCount<TSubDomainInfo> {
if (schemeshards.size()) {
ProcessingParams.SetSchemeShard(ui64(schemeshards.front()));
}
-
- ProcessingParams.ClearHive();
- TVector<TTabletId> hives = FilterTablets(ETabletType::Hive, allShards);
- Y_VERIFY_S(hives.size() <= 1, "size was: " << hives.size());
- if (hives.size()) {
- ProcessingParams.SetHive(ui64(hives.front()));
+
+ ProcessingParams.ClearHive();
+ TVector<TTabletId> hives = FilterTablets(ETabletType::Hive, allShards);
+ Y_VERIFY_S(hives.size() <= 1, "size was: " << hives.size());
+ if (hives.size()) {
+ ProcessingParams.SetHive(ui64(hives.front()));
SetSharedHive(InvalidTabletId); // set off shared hive when our own hive has found
- }
+ }
ProcessingParams.ClearSysViewProcessor();
TVector<TTabletId> sysViewProcessors = FilterTablets(ETabletType::SysViewProcessor, allShards);
@@ -1752,30 +1752,30 @@ struct TSubDomainInfo: TSimpleRefCount<TSubDomainInfo> {
DiskQuotaExceeded = value;
}
- bool HasSecurityState() const {
- return SecurityState.PublicKeysSize() > 0;
- }
-
- const NLoginProto::TSecurityState& GetSecurityState() const {
- return SecurityState;
- }
-
- void UpdateSecurityState(NLoginProto::TSecurityState state) {
- SecurityState = std::move(state);
- }
-
- ui64 GetSecurityStateVersion() const {
- return SecurityStateVersion;
- }
-
- void SetSecurityStateVersion(ui64 securityStateVersion) {
- SecurityStateVersion = securityStateVersion;
- }
-
- void IncSecurityStateVersion() {
- ++SecurityStateVersion;
- }
-
+ bool HasSecurityState() const {
+ return SecurityState.PublicKeysSize() > 0;
+ }
+
+ const NLoginProto::TSecurityState& GetSecurityState() const {
+ return SecurityState;
+ }
+
+ void UpdateSecurityState(NLoginProto::TSecurityState state) {
+ SecurityState = std::move(state);
+ }
+
+ ui64 GetSecurityStateVersion() const {
+ return SecurityStateVersion;
+ }
+
+ void SetSecurityStateVersion(ui64 securityStateVersion) {
+ SecurityStateVersion = securityStateVersion;
+ }
+
+ void IncSecurityStateVersion() {
+ ++SecurityStateVersion;
+ }
+
private:
bool InitiatedAsGlobal = false;
NKikimrSubDomains::TProcessingParams ProcessingParams;
@@ -1805,9 +1805,9 @@ private:
TPathId ResourcesDomainId;
TTabletId SharedHive = InvalidTabletId;
- NLoginProto::TSecurityState SecurityState;
- ui64 SecurityStateVersion = 0;
-
+ NLoginProto::TSecurityState SecurityState;
+ ui64 SecurityStateVersion = 0;
+
TVector<TTabletId> FilterTablets(TTabletTypes::EType type, const THashMap<TShardIdx, TShardInfo>& allShards) const {
TVector<TTabletId> tablets;
for (auto shardId: PrivateShards) {
diff --git a/ydb/core/tx/schemeshard/schemeshard_path_describer.cpp b/ydb/core/tx/schemeshard/schemeshard_path_describer.cpp
index ba9c1a5f350..3789d3af1b8 100644
--- a/ydb/core/tx/schemeshard/schemeshard_path_describer.cpp
+++ b/ydb/core/tx/schemeshard/schemeshard_path_describer.cpp
@@ -596,7 +596,7 @@ void TPathDescriber::DescribeRevertedMigrations(TPathElement::TPtr pathEl) {
void TPathDescriber::DescribeDomainRoot(TPathElement::TPtr pathEl) {
Y_VERIFY(pathEl->IsDomainRoot());
auto it = Self->SubDomains.FindPtr(pathEl->PathId);
- Y_VERIFY(it, "SubDomain not found");
+ Y_VERIFY(it, "SubDomain not found");
auto subDomainInfo = *it;
NKikimrSubDomains::TDomainDescription * entry = Result->Record.MutablePathDescription()->MutableDomainDescription();
@@ -644,22 +644,22 @@ void TPathDescriber::DescribeDomainRoot(TPathElement::TPtr pathEl) {
}
}
-void TPathDescriber::DescribeDomainExtra(TPathElement::TPtr pathEl) {
- Y_VERIFY(pathEl->IsDomainRoot());
- auto it = Self->SubDomains.FindPtr(pathEl->PathId);
- Y_VERIFY(it, "SubDomain not found");
- auto subDomainInfo = *it;
-
- NKikimrSubDomains::TDomainDescription * entry = Result->Record.MutablePathDescription()->MutableDomainDescription();
-
- for (auto& pool: subDomainInfo->GetStoragePools()) {
- *entry->AddStoragePools() = pool;
- }
- if (subDomainInfo->HasSecurityState()) {
- entry->MutableSecurityState()->CopyFrom(subDomainInfo->GetSecurityState());
- }
-}
-
+void TPathDescriber::DescribeDomainExtra(TPathElement::TPtr pathEl) {
+ Y_VERIFY(pathEl->IsDomainRoot());
+ auto it = Self->SubDomains.FindPtr(pathEl->PathId);
+ Y_VERIFY(it, "SubDomain not found");
+ auto subDomainInfo = *it;
+
+ NKikimrSubDomains::TDomainDescription * entry = Result->Record.MutablePathDescription()->MutableDomainDescription();
+
+ for (auto& pool: subDomainInfo->GetStoragePools()) {
+ *entry->AddStoragePools() = pool;
+ }
+ if (subDomainInfo->HasSecurityState()) {
+ entry->MutableSecurityState()->CopyFrom(subDomainInfo->GetSecurityState());
+ }
+}
+
void TPathDescriber::DescribeBlockStoreVolume(TPathId pathId, TPathElement::TPtr pathEl) {
Y_VERIFY(pathEl->IsBlockStoreVolume());
auto it = Self->BlockStoreVolumes.FindPtr(pathId);
@@ -797,9 +797,9 @@ THolder<TEvSchemeShard::TEvDescribeSchemeResultBuilder> TPathDescriber::Describe
auto descr = Result->Record.MutablePathDescription()->MutableSelf();
FillPathDescr(descr, path);
BuildEffectiveACL(descr, path);
- auto base = path.Base();
- DescribeDomain(base);
- DescribeUserAttributes(base);
+ auto base = path.Base();
+ DescribeDomain(base);
+ DescribeUserAttributes(base);
DescribePathVersion(path);
if (base->IsCreateFinished()) {
@@ -858,7 +858,7 @@ THolder<TEvSchemeShard::TEvDescribeSchemeResultBuilder> TPathDescriber::Describe
break;
case NKikimrSchemeOp::EPathTypeInvalid:
Y_UNREACHABLE();
- }
+ }
} else {
// here we do not full any object specific information, like table description
// nevertheless, chindren list should be set even when dir or children is being created right now
diff --git a/ydb/core/tx/schemeshard/schemeshard_path_describer.h b/ydb/core/tx/schemeshard/schemeshard_path_describer.h
index 91d1de50686..7d10ed1da7a 100644
--- a/ydb/core/tx/schemeshard/schemeshard_path_describer.h
+++ b/ydb/core/tx/schemeshard/schemeshard_path_describer.h
@@ -34,7 +34,7 @@ class TPathDescriber {
void DescribePathVersion(const TPath& path);
void DescribeDomain(TPathElement::TPtr pathEl);
void DescribeDomainRoot(TPathElement::TPtr pathEl);
- void DescribeDomainExtra(TPathElement::TPtr pathEl);
+ void DescribeDomainExtra(TPathElement::TPtr pathEl);
void DescribeRevertedMigrations(TPathElement::TPtr pathEl);
void DescribeBlockStoreVolume(TPathId pathId, TPathElement::TPtr pathEl);
diff --git a/ydb/core/tx/schemeshard/schemeshard_schema.h b/ydb/core/tx/schemeshard/schemeshard_schema.h
index 7c8ae77a3c3..f293136fe85 100644
--- a/ydb/core/tx/schemeshard/schemeshard_schema.h
+++ b/ydb/core/tx/schemeshard/schemeshard_schema.h
@@ -718,7 +718,7 @@ struct Schema : NIceDb::Schema {
struct DatabaseQuotas : Column<23, NScheme::NTypeIds::String> {};
struct StateVersion : Column<24, NScheme::NTypeIds::Uint64> {};
struct DiskQuotaExceeded : Column<25, NScheme::NTypeIds::Bool> {};
- struct SecurityStateVersion : Column<26, NScheme::NTypeIds::Uint64> {};
+ struct SecurityStateVersion : Column<26, NScheme::NTypeIds::Uint64> {};
using TKey = TableKey<PathId>;
using TColumns = TableColumns<
@@ -746,8 +746,8 @@ struct Schema : NIceDb::Schema {
PQPartitionsLimit,
DatabaseQuotas,
StateVersion,
- DiskQuotaExceeded,
- SecurityStateVersion
+ DiskQuotaExceeded,
+ SecurityStateVersion
>;
};
@@ -1500,32 +1500,32 @@ struct Schema : NIceDb::Schema {
using TColumns = TableColumns<PathId, AlterVersion, Description, Sharding, AlterBody>;
};
- struct LoginKeys : Table<92> {
- struct KeyId : Column<1, NScheme::NTypeIds::Uint64> {};
- struct KeyDataPEM : Column<2, NScheme::NTypeIds::String> {};
- struct ExpiresAt : Column<3, NScheme::NTypeIds::Uint64> {};
-
- using TKey = TableKey<KeyId>;
- using TColumns = TableColumns<KeyId, KeyDataPEM, ExpiresAt>;
- };
-
- struct LoginSids : Table<93> {
- struct SidName : Column<1, NScheme::NTypeIds::String> {};
- struct SidType : Column<2, NScheme::NTypeIds::Uint64> { using Type = NLoginProto::ESidType::SidType; };
- struct SidHash : Column<3, NScheme::NTypeIds::String> {};
-
- using TKey = TableKey<SidName>;
- using TColumns = TableColumns<SidName, SidType, SidHash>;
- };
-
- struct LoginSidMembers : Table<94> {
- struct SidName : Column<1, NScheme::NTypeIds::String> {};
- struct SidMember : Column<2, NScheme::NTypeIds::String> {};
-
- using TKey = TableKey<SidName, SidMember>;
- using TColumns = TableColumns<SidName, SidMember>;
- };
-
+ struct LoginKeys : Table<92> {
+ struct KeyId : Column<1, NScheme::NTypeIds::Uint64> {};
+ struct KeyDataPEM : Column<2, NScheme::NTypeIds::String> {};
+ struct ExpiresAt : Column<3, NScheme::NTypeIds::Uint64> {};
+
+ using TKey = TableKey<KeyId>;
+ using TColumns = TableColumns<KeyId, KeyDataPEM, ExpiresAt>;
+ };
+
+ struct LoginSids : Table<93> {
+ struct SidName : Column<1, NScheme::NTypeIds::String> {};
+ struct SidType : Column<2, NScheme::NTypeIds::Uint64> { using Type = NLoginProto::ESidType::SidType; };
+ struct SidHash : Column<3, NScheme::NTypeIds::String> {};
+
+ using TKey = TableKey<SidName>;
+ using TColumns = TableColumns<SidName, SidType, SidHash>;
+ };
+
+ struct LoginSidMembers : Table<94> {
+ struct SidName : Column<1, NScheme::NTypeIds::String> {};
+ struct SidMember : Column<2, NScheme::NTypeIds::String> {};
+
+ using TKey = TableKey<SidName, SidMember>;
+ using TColumns = TableColumns<SidName, SidMember>;
+ };
+
struct CdcStream : Table<95> {
struct OwnerPathId : Column<1, NScheme::NTypeIds::Uint64> { using Type = TOwnerId; };
struct LocalPathId : Column<2, NScheme::NTypeIds::Uint64> { using Type = TLocalPathId; };
@@ -1677,9 +1677,9 @@ struct Schema : NIceDb::Schema {
OlapStores,
OlapStoresAlters,
OlapTables,
- OlapTablesAlters,
- LoginKeys,
- LoginSids,
+ OlapTablesAlters,
+ LoginKeys,
+ LoginSids,
LoginSidMembers,
CdcStream,
CdcStreamAlterData,
diff --git a/ydb/core/tx/schemeshard/schemeshard_utils.cpp b/ydb/core/tx/schemeshard/schemeshard_utils.cpp
index c6ae82c7eb9..4ee28e35435 100644
--- a/ydb/core/tx/schemeshard/schemeshard_utils.cpp
+++ b/ydb/core/tx/schemeshard/schemeshard_utils.cpp
@@ -13,10 +13,10 @@ void TShardDeleter::Shutdown(const NActors::TActorContext &ctx) {
PerHiveDeletions.clear();
}
-void TShardDeleter::SendDeleteRequests(TTabletId hiveTabletId,
- const THashSet<TShardIdx> &shardsToDelete,
+void TShardDeleter::SendDeleteRequests(TTabletId hiveTabletId,
+ const THashSet<TShardIdx> &shardsToDelete,
const THashMap<NKikimr::NSchemeShard::TShardIdx, NKikimr::NSchemeShard::TShardInfo>& shardsInfos,
- const NActors::TActorContext &ctx) {
+ const NActors::TActorContext &ctx) {
if (shardsToDelete.empty())
return;
@@ -34,13 +34,13 @@ void TShardDeleter::SendDeleteRequests(TTabletId hiveTabletId,
// TODO: change hive events to get rid of this hack
// svc@ in progress fixing it
TAutoPtr<TEvHive::TEvDeleteTablet> event = new TEvHive::TEvDeleteTablet(shardIdx.GetOwnerId(), ui64(shardIdx.GetLocalId()), ui64(shardIdx.GetLocalId()));
- auto itShard = shardsInfos.find(shardIdx);
- if (itShard != shardsInfos.end()) {
- TTabletId shardTabletId = itShard->second.TabletID;
- if (shardTabletId) {
- event->Record.AddTabletID(ui64(shardTabletId));
- }
- }
+ auto itShard = shardsInfos.find(shardIdx);
+ if (itShard != shardsInfos.end()) {
+ TTabletId shardTabletId = itShard->second.TabletID;
+ if (shardTabletId) {
+ event->Record.AddTabletID(ui64(shardTabletId));
+ }
+ }
Y_VERIFY(shardIdx);
@@ -51,74 +51,74 @@ void TShardDeleter::SendDeleteRequests(TTabletId hiveTabletId,
}
}
-void TShardDeleter::ResendDeleteRequests(TTabletId hiveTabletId, const THashMap<TShardIdx, TShardInfo>& shardsInfos, const NActors::TActorContext &ctx) {
- LOG_NOTICE_S(ctx, NKikimrServices::FLAT_TX_SCHEMESHARD,
- "Resending tablet deletion requests from " << MyTabletID << " to " << hiveTabletId);
+void TShardDeleter::ResendDeleteRequests(TTabletId hiveTabletId, const THashMap<TShardIdx, TShardInfo>& shardsInfos, const NActors::TActorContext &ctx) {
+ LOG_NOTICE_S(ctx, NKikimrServices::FLAT_TX_SCHEMESHARD,
+ "Resending tablet deletion requests from " << MyTabletID << " to " << hiveTabletId);
- auto itPerHive = PerHiveDeletions.find(hiveTabletId);
- if (itPerHive == PerHiveDeletions.end()) {
- LOG_WARN_S(ctx, NKikimrServices::FLAT_TX_SCHEMESHARD,
- "Hive " << hiveTabletId << " not found for delete requests");
+ auto itPerHive = PerHiveDeletions.find(hiveTabletId);
+ if (itPerHive == PerHiveDeletions.end()) {
+ LOG_WARN_S(ctx, NKikimrServices::FLAT_TX_SCHEMESHARD,
+ "Hive " << hiveTabletId << " not found for delete requests");
return;
- }
-
- THashSet<TShardIdx> toResend(std::move(itPerHive->second.ShardsToDelete));
- PerHiveDeletions.erase(itPerHive);
-
- SendDeleteRequests(hiveTabletId, toResend, shardsInfos, ctx);
-}
-
-void TShardDeleter::ResendDeleteRequest(TTabletId hiveTabletId,
- const THashMap<TShardIdx, TShardInfo>& shardsInfos,
- TShardIdx shardIdx,
- const NActors::TActorContext &ctx) {
- LOG_NOTICE_S(ctx, NKikimrServices::FLAT_TX_SCHEMESHARD,
- "Resending tablet deletion request from " << MyTabletID << " to " << hiveTabletId);
-
- auto itPerHive = PerHiveDeletions.find(hiveTabletId);
- if (itPerHive == PerHiveDeletions.end())
- return;
-
- auto itShardIdx = itPerHive->second.ShardsToDelete.find(shardIdx);
- if (itShardIdx != itPerHive->second.ShardsToDelete.end()) {
- THashSet<TShardIdx> toResend({shardIdx});
- itPerHive->second.ShardsToDelete.erase(itShardIdx);
- if (itPerHive->second.ShardsToDelete.empty()) {
- PerHiveDeletions.erase(itPerHive);
- }
- SendDeleteRequests(hiveTabletId, toResend, shardsInfos, ctx);
- } else {
- LOG_WARN_S(ctx, NKikimrServices::FLAT_TX_SCHEMESHARD,
- "Shard " << shardIdx << " not found for delete request for Hive " << hiveTabletId);
- }
+ }
+
+ THashSet<TShardIdx> toResend(std::move(itPerHive->second.ShardsToDelete));
+ PerHiveDeletions.erase(itPerHive);
+
+ SendDeleteRequests(hiveTabletId, toResend, shardsInfos, ctx);
+}
+
+void TShardDeleter::ResendDeleteRequest(TTabletId hiveTabletId,
+ const THashMap<TShardIdx, TShardInfo>& shardsInfos,
+ TShardIdx shardIdx,
+ const NActors::TActorContext &ctx) {
+ LOG_NOTICE_S(ctx, NKikimrServices::FLAT_TX_SCHEMESHARD,
+ "Resending tablet deletion request from " << MyTabletID << " to " << hiveTabletId);
+
+ auto itPerHive = PerHiveDeletions.find(hiveTabletId);
+ if (itPerHive == PerHiveDeletions.end())
+ return;
+
+ auto itShardIdx = itPerHive->second.ShardsToDelete.find(shardIdx);
+ if (itShardIdx != itPerHive->second.ShardsToDelete.end()) {
+ THashSet<TShardIdx> toResend({shardIdx});
+ itPerHive->second.ShardsToDelete.erase(itShardIdx);
+ if (itPerHive->second.ShardsToDelete.empty()) {
+ PerHiveDeletions.erase(itPerHive);
+ }
+ SendDeleteRequests(hiveTabletId, toResend, shardsInfos, ctx);
+ } else {
+ LOG_WARN_S(ctx, NKikimrServices::FLAT_TX_SCHEMESHARD,
+ "Shard " << shardIdx << " not found for delete request for Hive " << hiveTabletId);
+ }
+}
+
+void TShardDeleter::RedirectDeleteRequest(TTabletId hiveFromTabletId,
+ TTabletId hiveToTabletId,
+ TShardIdx shardIdx,
+ const THashMap<TShardIdx, TShardInfo>& shardsInfos,
+ const NActors::TActorContext &ctx) {
+ LOG_NOTICE_S(ctx, NKikimrServices::FLAT_TX_SCHEMESHARD,
+ "Redirecting tablet deletion requests from " << hiveFromTabletId << " to " << hiveToTabletId);
+ auto itFromHive = PerHiveDeletions.find(hiveFromTabletId);
+ if (itFromHive != PerHiveDeletions.end()) {
+ auto& toHive(PerHiveDeletions[hiveToTabletId]);
+ auto itShardIdx = itFromHive->second.ShardsToDelete.find(shardIdx);
+ if (itShardIdx != itFromHive->second.ShardsToDelete.end()) {
+ toHive.ShardsToDelete.emplace(*itShardIdx);
+ itFromHive->second.ShardsToDelete.erase(itShardIdx);
+ } else {
+ LOG_WARN_S(ctx, NKikimrServices::FLAT_TX_SCHEMESHARD,
+ "Shard " << shardIdx << " not found for delete request for Hive " << hiveFromTabletId);
+ }
+ if (itFromHive->second.ShardsToDelete.empty()) {
+ PerHiveDeletions.erase(itFromHive);
+ }
+ }
+
+ ResendDeleteRequest(hiveToTabletId, shardsInfos, shardIdx, ctx);
}
-void TShardDeleter::RedirectDeleteRequest(TTabletId hiveFromTabletId,
- TTabletId hiveToTabletId,
- TShardIdx shardIdx,
- const THashMap<TShardIdx, TShardInfo>& shardsInfos,
- const NActors::TActorContext &ctx) {
- LOG_NOTICE_S(ctx, NKikimrServices::FLAT_TX_SCHEMESHARD,
- "Redirecting tablet deletion requests from " << hiveFromTabletId << " to " << hiveToTabletId);
- auto itFromHive = PerHiveDeletions.find(hiveFromTabletId);
- if (itFromHive != PerHiveDeletions.end()) {
- auto& toHive(PerHiveDeletions[hiveToTabletId]);
- auto itShardIdx = itFromHive->second.ShardsToDelete.find(shardIdx);
- if (itShardIdx != itFromHive->second.ShardsToDelete.end()) {
- toHive.ShardsToDelete.emplace(*itShardIdx);
- itFromHive->second.ShardsToDelete.erase(itShardIdx);
- } else {
- LOG_WARN_S(ctx, NKikimrServices::FLAT_TX_SCHEMESHARD,
- "Shard " << shardIdx << " not found for delete request for Hive " << hiveFromTabletId);
- }
- if (itFromHive->second.ShardsToDelete.empty()) {
- PerHiveDeletions.erase(itFromHive);
- }
- }
-
- ResendDeleteRequest(hiveToTabletId, shardsInfos, shardIdx, ctx);
-}
-
void TShardDeleter::ShardDeleted(TShardIdx shardIdx, const NActors::TActorContext &ctx) {
if (!ShardHive.contains(shardIdx))
return;
diff --git a/ydb/core/tx/schemeshard/schemeshard_utils.h b/ydb/core/tx/schemeshard/schemeshard_utils.h
index 6ad9defaa00..de7d17f316f 100644
--- a/ydb/core/tx/schemeshard/schemeshard_utils.h
+++ b/ydb/core/tx/schemeshard/schemeshard_utils.h
@@ -65,26 +65,26 @@ class TShardDeleter {
THashMap<TTabletId, TPerHiveDeletions> PerHiveDeletions;
// Tablet -> Hive TabletID
THashMap<TShardIdx, TTabletId> ShardHive;
- NTabletPipe::TClientRetryPolicy HivePipeRetryPolicy;
+ NTabletPipe::TClientRetryPolicy HivePipeRetryPolicy;
public:
explicit TShardDeleter(ui64 myTabletId)
: MyTabletID(myTabletId)
- , HivePipeRetryPolicy({})
+ , HivePipeRetryPolicy({})
{}
TShardDeleter(const TShardDeleter&) = delete;
TShardDeleter& operator=(const TShardDeleter&) = delete;
void Shutdown(const TActorContext& ctx);
- void SendDeleteRequests(TTabletId hiveTabletId, const THashSet<TShardIdx>& shardsToDelete,
- const THashMap<TShardIdx, TShardInfo>& shardsInfos, const TActorContext& ctx);
- void ResendDeleteRequests(TTabletId hiveTabletId,
- const THashMap<TShardIdx, TShardInfo>& shardsInfos, const TActorContext& ctx);
- void ResendDeleteRequest(TTabletId hiveTabletId,
- const THashMap<TShardIdx, TShardInfo>& shardsInfos, TShardIdx shardIdx, const TActorContext& ctx);
- void RedirectDeleteRequest(TTabletId hiveFromTabletId, TTabletId hiveToTabletId, TShardIdx shardIdx,
- const THashMap<TShardIdx, TShardInfo>& shardsInfos, const TActorContext& ctx);
+ void SendDeleteRequests(TTabletId hiveTabletId, const THashSet<TShardIdx>& shardsToDelete,
+ const THashMap<TShardIdx, TShardInfo>& shardsInfos, const TActorContext& ctx);
+ void ResendDeleteRequests(TTabletId hiveTabletId,
+ const THashMap<TShardIdx, TShardInfo>& shardsInfos, const TActorContext& ctx);
+ void ResendDeleteRequest(TTabletId hiveTabletId,
+ const THashMap<TShardIdx, TShardInfo>& shardsInfos, TShardIdx shardIdx, const TActorContext& ctx);
+ void RedirectDeleteRequest(TTabletId hiveFromTabletId, TTabletId hiveToTabletId, TShardIdx shardIdx,
+ const THashMap<TShardIdx, TShardInfo>& shardsInfos, const TActorContext& ctx);
void ShardDeleted(TShardIdx shardIdx, const TActorContext& ctx);
bool Has(TTabletId hiveTabletId, TActorId pipeClientActorId) const;
bool Has(TShardIdx shardIdx) const;
diff --git a/ydb/core/tx/schemeshard/ut_base.cpp b/ydb/core/tx/schemeshard/ut_base.cpp
index 517b18c59a4..a76dcf9d5bb 100644
--- a/ydb/core/tx/schemeshard/ut_base.cpp
+++ b/ydb/core/tx/schemeshard/ut_base.cpp
@@ -3280,14 +3280,14 @@ Y_UNIT_TEST_SUITE(TSchemeShardTest) {
TestAlterSubDomain(runtime, ++txId, "/",
"StoragePools { "
- " Name: \"pool-1\" "
- " Kind: \"pool-kind-1\" "
- "} "
- "StoragePools { "
- " Name: \"pool-2\" "
- " Kind: \"pool-kind-2\" "
- "} "
- "StoragePools { "
+ " Name: \"pool-1\" "
+ " Kind: \"pool-kind-1\" "
+ "} "
+ "StoragePools { "
+ " Name: \"pool-2\" "
+ " Kind: \"pool-kind-2\" "
+ "} "
+ "StoragePools { "
" Name: \"name_USER_0_kind_hdd-1\" "
" Kind: \"hdd-1\" "
"} "
@@ -4329,14 +4329,14 @@ Y_UNIT_TEST_SUITE(TSchemeShardTest) {
TestAlterSubDomain(runtime, ++txId, "/", R"(
StoragePools {
- Name: "pool-1"
- Kind: "pool-kind-1"
- }
- StoragePools {
- Name: "pool-2"
- Kind: "pool-kind-2"
- }
- StoragePools {
+ Name: "pool-1"
+ Kind: "pool-kind-1"
+ }
+ StoragePools {
+ Name: "pool-2"
+ Kind: "pool-kind-2"
+ }
+ StoragePools {
Name: "name_USER_0_kind_hdd-1"
Kind: "hdd-1"
}
@@ -4853,14 +4853,14 @@ Y_UNIT_TEST_SUITE(TSchemeShardTest) {
TestAlterSubDomain(runtime, ++txId, "/", R"(
StoragePools {
- Name: "pool-1"
- Kind: "pool-kind-1"
- }
- StoragePools {
- Name: "pool-2"
- Kind: "pool-kind-2"
- }
- StoragePools {
+ Name: "pool-1"
+ Kind: "pool-kind-1"
+ }
+ StoragePools {
+ Name: "pool-2"
+ Kind: "pool-kind-2"
+ }
+ StoragePools {
Name: "name_USER_0_kind_hdd-1"
Kind: "hdd-1"
}
diff --git a/ydb/core/tx/schemeshard/ut_extsubdomain.cpp b/ydb/core/tx/schemeshard/ut_extsubdomain.cpp
index 5ac76e0c6fa..0fa6a27bce0 100644
--- a/ydb/core/tx/schemeshard/ut_extsubdomain.cpp
+++ b/ydb/core/tx/schemeshard/ut_extsubdomain.cpp
@@ -146,14 +146,14 @@ Y_UNIT_TEST_SUITE(TSchemeShardExtSubDomainTest) {
TestAlterExtSubDomain(runtime, ++txId, "/MyRoot",
"StoragePools { "
- " Name: \"pool-1\" "
- " Kind: \"pool-kind-1\" "
- "} "
- "StoragePools { "
- " Name: \"pool-2\" "
- " Kind: \"pool-kind-2\" "
- "} "
- "StoragePools { "
+ " Name: \"pool-1\" "
+ " Kind: \"pool-kind-1\" "
+ "} "
+ "StoragePools { "
+ " Name: \"pool-2\" "
+ " Kind: \"pool-kind-2\" "
+ "} "
+ "StoragePools { "
" Name: \"/dc-1/users/tenant-1:hdd\" "
" Kind: \"hdd\" "
"} "
diff --git a/ydb/core/tx/schemeshard/ut_helpers/helpers.cpp b/ydb/core/tx/schemeshard/ut_helpers/helpers.cpp
index e41e9f17c2c..6f999b268bb 100644
--- a/ydb/core/tx/schemeshard/ut_helpers/helpers.cpp
+++ b/ydb/core/tx/schemeshard/ut_helpers/helpers.cpp
@@ -1736,24 +1736,24 @@ namespace NSchemeShardUT_Private {
auto evTx = new TEvSchemeShard::TEvModifySchemeTransaction(txId, TTestTxConfig::SchemeShard);
auto transaction = evTx->Record.AddTransaction();
transaction->SetOperationType(NKikimrSchemeOp::EOperationType::ESchemeOpAlterLogin);
- auto createUser = transaction->MutableAlterLogin()->MutableCreateUser();
- createUser->SetUser(user);
- createUser->SetPassword(password);
- return evTx;
- }
-
+ auto createUser = transaction->MutableAlterLogin()->MutableCreateUser();
+ createUser->SetUser(user);
+ createUser->SetPassword(password);
+ return evTx;
+ }
+
NKikimrScheme::TEvLoginResult Login(TTestActorRuntime& runtime, const TString& user, const TString& password) {
- TActorId sender = runtime.AllocateEdgeActor();
+ TActorId sender = runtime.AllocateEdgeActor();
auto evLogin = new TEvSchemeShard::TEvLogin();
- evLogin->Record.SetUser(user);
- evLogin->Record.SetPassword(password);
+ evLogin->Record.SetUser(user);
+ evLogin->Record.SetPassword(password);
ForwardToTablet(runtime, TTestTxConfig::SchemeShard, sender, evLogin);
- TAutoPtr<IEventHandle> handle;
+ TAutoPtr<IEventHandle> handle;
auto event = runtime.GrabEdgeEvent<TEvSchemeShard::TEvLoginResult>(handle);
- UNIT_ASSERT(event);
- return event->Record;
- }
-
+ UNIT_ASSERT(event);
+ return event->Record;
+ }
+
// class TFakeDataReq {
TFakeDataReq::TFakeDataReq(NActors::TTestActorRuntime &runtime, ui64 txId, const TString &table, const TString &query)
: Runtime(runtime)
diff --git a/ydb/core/tx/schemeshard/ut_helpers/helpers.h b/ydb/core/tx/schemeshard/ut_helpers/helpers.h
index b991fca8165..6b12c25534a 100644
--- a/ydb/core/tx/schemeshard/ut_helpers/helpers.h
+++ b/ydb/core/tx/schemeshard/ut_helpers/helpers.h
@@ -398,10 +398,10 @@ namespace NSchemeShardUT_Private {
TTestActorRuntime& runtime, ui64 schemeShard, ui64 tabletId,
NKikimrScheme::TEvFindTabletSubDomainPathIdResult::EStatus expected = NKikimrScheme::TEvFindTabletSubDomainPathIdResult::SUCCESS);
- // Login
+ // Login
TEvTx* CreateAlterLoginCreateUser(ui64 txId, const TString& user, const TString& password);
NKikimrScheme::TEvLoginResult Login(TTestActorRuntime& runtime, const TString& user, const TString& password);
-
+
// Mimics data query to a single table with multiple partitions
class TFakeDataReq {
public:
diff --git a/ydb/core/tx/schemeshard/ut_login.cpp b/ydb/core/tx/schemeshard/ut_login.cpp
index f7905a5a433..1a46fafeb1d 100644
--- a/ydb/core/tx/schemeshard/ut_login.cpp
+++ b/ydb/core/tx/schemeshard/ut_login.cpp
@@ -1,31 +1,31 @@
#include <ydb/core/tx/schemeshard/ut_helpers/helpers.h>
#include <ydb/library/login/login.h>
-
-using namespace NKikimr;
+
+using namespace NKikimr;
using namespace NSchemeShard;
-using namespace NSchemeShardUT_Private;
-
-Y_UNIT_TEST_SUITE(TSchemeShardLoginTest) {
- Y_UNIT_TEST(BasicLogin) {
- TTestBasicRuntime runtime;
- TTestEnv env(runtime);
- ui64 txId = 100;
- TActorId sender = runtime.AllocateEdgeActor();
- std::unique_ptr<TEvSchemeShard::TEvModifySchemeTransaction> transaction(CreateAlterLoginCreateUser(++txId, "user1", "password1"));
- transaction->Record.MutableTransaction(0)->SetWorkingDir("/MyRoot");
- ForwardToTablet(runtime, TTestTxConfig::SchemeShard, sender, transaction.release());
- auto resultLogin = Login(runtime, "user1", "password1");
- UNIT_ASSERT_VALUES_EQUAL(resultLogin.error(), "");
+using namespace NSchemeShardUT_Private;
+
+Y_UNIT_TEST_SUITE(TSchemeShardLoginTest) {
+ Y_UNIT_TEST(BasicLogin) {
+ TTestBasicRuntime runtime;
+ TTestEnv env(runtime);
+ ui64 txId = 100;
+ TActorId sender = runtime.AllocateEdgeActor();
+ std::unique_ptr<TEvSchemeShard::TEvModifySchemeTransaction> transaction(CreateAlterLoginCreateUser(++txId, "user1", "password1"));
+ transaction->Record.MutableTransaction(0)->SetWorkingDir("/MyRoot");
+ ForwardToTablet(runtime, TTestTxConfig::SchemeShard, sender, transaction.release());
+ auto resultLogin = Login(runtime, "user1", "password1");
+ UNIT_ASSERT_VALUES_EQUAL(resultLogin.error(), "");
auto describe = DescribePath(runtime, TTestTxConfig::SchemeShard, "/MyRoot");
- UNIT_ASSERT(describe.HasPathDescription());
- UNIT_ASSERT(describe.GetPathDescription().HasDomainDescription());
- UNIT_ASSERT(describe.GetPathDescription().GetDomainDescription().HasSecurityState());
- UNIT_ASSERT(describe.GetPathDescription().GetDomainDescription().GetSecurityState().PublicKeysSize() > 0);
-
- // check token
- NLogin::TLoginProvider login;
- login.UpdateSecurityState(describe.GetPathDescription().GetDomainDescription().GetSecurityState());
- auto resultValidate = login.ValidateToken({.Token = resultLogin.token()});
- UNIT_ASSERT_VALUES_EQUAL(resultValidate.User, "user1");
- }
-}
+ UNIT_ASSERT(describe.HasPathDescription());
+ UNIT_ASSERT(describe.GetPathDescription().HasDomainDescription());
+ UNIT_ASSERT(describe.GetPathDescription().GetDomainDescription().HasSecurityState());
+ UNIT_ASSERT(describe.GetPathDescription().GetDomainDescription().GetSecurityState().PublicKeysSize() > 0);
+
+ // check token
+ NLogin::TLoginProvider login;
+ login.UpdateSecurityState(describe.GetPathDescription().GetDomainDescription().GetSecurityState());
+ auto resultValidate = login.ValidateToken({.Token = resultLogin.token()});
+ UNIT_ASSERT_VALUES_EQUAL(resultValidate.User, "user1");
+ }
+}
diff --git a/ydb/core/tx/schemeshard/ut_login/ya.make b/ydb/core/tx/schemeshard/ut_login/ya.make
index 801fd88602d..b05cff0643c 100644
--- a/ydb/core/tx/schemeshard/ut_login/ya.make
+++ b/ydb/core/tx/schemeshard/ut_login/ya.make
@@ -1,33 +1,33 @@
UNITTEST_FOR(ydb/core/tx/schemeshard)
-
-OWNER(g:kikimr)
-
-FORK_SUBTESTS()
-IF (SANITIZER_TYPE OR WITH_VALGRIND)
- TIMEOUT(3600)
- SIZE(LARGE)
- TAG(ya:fat)
-ELSE()
- TIMEOUT(600)
- SIZE(MEDIUM)
-ENDIF()
-
-PEERDIR(
+OWNER(g:kikimr)
+
+FORK_SUBTESTS()
+
+IF (SANITIZER_TYPE OR WITH_VALGRIND)
+ TIMEOUT(3600)
+ SIZE(LARGE)
+ TAG(ya:fat)
+ELSE()
+ TIMEOUT(600)
+ SIZE(MEDIUM)
+ENDIF()
+
+PEERDIR(
library/cpp/getopt
- library/cpp/regex/pcre
- library/cpp/svnversion
+ library/cpp/regex/pcre
+ library/cpp/svnversion
ydb/core/testlib
ydb/core/tx
ydb/core/tx/schemeshard/ut_helpers
ydb/library/login
ydb/library/yql/public/udf/service/exception_policy
-)
-
-YQL_LAST_ABI_VERSION()
-
-SRCS(
- ut_login.cpp
-)
-
-END()
+)
+
+YQL_LAST_ABI_VERSION()
+
+SRCS(
+ ut_login.cpp
+)
+
+END()
diff --git a/ydb/core/tx/schemeshard/ut_pq_reboots.cpp b/ydb/core/tx/schemeshard/ut_pq_reboots.cpp
index 76c7a88a055..86278552974 100644
--- a/ydb/core/tx/schemeshard/ut_pq_reboots.cpp
+++ b/ydb/core/tx/schemeshard/ut_pq_reboots.cpp
@@ -70,75 +70,75 @@ Y_UNIT_TEST_SUITE(TPqGroupTestReboots) {
});
}
- Y_UNIT_TEST(AlterWithProfileChange) {
- TTestBasicRuntime runtime;
- TTestEnv env(runtime);
- ui64 txId = 100;
- TPathVersion pqVer;
-
- TestDescribeResult(DescribePath(runtime, "/MyRoot"),
+ Y_UNIT_TEST(AlterWithProfileChange) {
+ TTestBasicRuntime runtime;
+ TTestEnv env(runtime);
+ ui64 txId = 100;
+ TPathVersion pqVer;
+
+ TestDescribeResult(DescribePath(runtime, "/MyRoot"),
{NLs::NoChildren});
-
- AsyncMkDir(runtime, ++txId, "/MyRoot", "DirA");
-
- env.TestWaitNotification(runtime, txId);
-
- TestCreatePQGroup(runtime, ++txId, "/MyRoot/DirA",
- "Name: \"PQGroup\""
- "TotalGroupCount: 10 "
- "PartitionPerTablet: 10 "
- "PQTabletConfig: {PartitionConfig { LifetimeSeconds : 10}}"
- );
-
- env.TestWaitNotification(runtime, txId);
-
- pqVer = TestDescribeResult(DescribePath(runtime, "/MyRoot/DirA/PQGroup", true),
- {NLs::Finished,
- NLs::CheckPartCount("PQGroup", 10, 10, 1, 10),
+
+ AsyncMkDir(runtime, ++txId, "/MyRoot", "DirA");
+
+ env.TestWaitNotification(runtime, txId);
+
+ TestCreatePQGroup(runtime, ++txId, "/MyRoot/DirA",
+ "Name: \"PQGroup\""
+ "TotalGroupCount: 10 "
+ "PartitionPerTablet: 10 "
+ "PQTabletConfig: {PartitionConfig { LifetimeSeconds : 10}}"
+ );
+
+ env.TestWaitNotification(runtime, txId);
+
+ pqVer = TestDescribeResult(DescribePath(runtime, "/MyRoot/DirA/PQGroup", true),
+ {NLs::Finished,
+ NLs::CheckPartCount("PQGroup", 10, 10, 1, 10),
NLs::PQPartitionsInsideDomain(10),
- NLs::PathVersionEqual(2)});
-
- auto numChannels = runtime.GetAppData().ChannelProfiles->Profiles[0].Channels.size();
- {
+ NLs::PathVersionEqual(2)});
+
+ auto numChannels = runtime.GetAppData().ChannelProfiles->Profiles[0].Channels.size();
+ {
auto itTablet = env.GetHiveState()->Tablets.find({TTestTxConfig::SchemeShard, 1});
- UNIT_ASSERT_UNEQUAL(itTablet, env.GetHiveState()->Tablets.end());
- UNIT_ASSERT_VALUES_EQUAL(itTablet->second.Type, TTabletTypes::PersQueue);
- UNIT_ASSERT_VALUES_EQUAL(itTablet->second.BoundChannels.size(), numChannels);
-
- }
-
- // increasing number of channels in 0 profile
- runtime.GetAppData().ChannelProfiles->Profiles[0].Channels.emplace_back(runtime.GetAppData().ChannelProfiles->Profiles[0].Channels.back());
- runtime.GetAppData().ChannelProfiles->Profiles[0].Channels.emplace_back(runtime.GetAppData().ChannelProfiles->Profiles[0].Channels.back());
- runtime.GetAppData().ChannelProfiles->Profiles[0].Channels.emplace_back(runtime.GetAppData().ChannelProfiles->Profiles[0].Channels.back());
- runtime.GetAppData().ChannelProfiles->Profiles[0].Channels.emplace_back(runtime.GetAppData().ChannelProfiles->Profiles[0].Channels.back());
- auto numChannelsNew = runtime.GetAppData().ChannelProfiles->Profiles[0].Channels.size();
-
- TestAlterPQGroup(runtime, ++txId, "/MyRoot/DirA",
- "Name: \"PQGroup\""
- "TotalGroupCount: 10 "
- "PartitionPerTablet: 10 "
- "PQTabletConfig: {PartitionConfig { LifetimeSeconds : 10}}",
+ UNIT_ASSERT_UNEQUAL(itTablet, env.GetHiveState()->Tablets.end());
+ UNIT_ASSERT_VALUES_EQUAL(itTablet->second.Type, TTabletTypes::PersQueue);
+ UNIT_ASSERT_VALUES_EQUAL(itTablet->second.BoundChannels.size(), numChannels);
+
+ }
+
+ // increasing number of channels in 0 profile
+ runtime.GetAppData().ChannelProfiles->Profiles[0].Channels.emplace_back(runtime.GetAppData().ChannelProfiles->Profiles[0].Channels.back());
+ runtime.GetAppData().ChannelProfiles->Profiles[0].Channels.emplace_back(runtime.GetAppData().ChannelProfiles->Profiles[0].Channels.back());
+ runtime.GetAppData().ChannelProfiles->Profiles[0].Channels.emplace_back(runtime.GetAppData().ChannelProfiles->Profiles[0].Channels.back());
+ runtime.GetAppData().ChannelProfiles->Profiles[0].Channels.emplace_back(runtime.GetAppData().ChannelProfiles->Profiles[0].Channels.back());
+ auto numChannelsNew = runtime.GetAppData().ChannelProfiles->Profiles[0].Channels.size();
+
+ TestAlterPQGroup(runtime, ++txId, "/MyRoot/DirA",
+ "Name: \"PQGroup\""
+ "TotalGroupCount: 10 "
+ "PartitionPerTablet: 10 "
+ "PQTabletConfig: {PartitionConfig { LifetimeSeconds : 10}}",
{NKikimrScheme::StatusAccepted}, {pqVer});
-
- env.TestWaitNotification(runtime, txId);
-
- pqVer = TestDescribeResult(DescribePath(runtime, "/MyRoot/DirA/PQGroup", true),
- {NLs::Finished,
- NLs::CheckPartCount("PQGroup", 10, 10, 1, 10),
+
+ env.TestWaitNotification(runtime, txId);
+
+ pqVer = TestDescribeResult(DescribePath(runtime, "/MyRoot/DirA/PQGroup", true),
+ {NLs::Finished,
+ NLs::CheckPartCount("PQGroup", 10, 10, 1, 10),
NLs::PQPartitionsInsideDomain(10),
- NLs::PathVersionEqual(3)});
-
- {
+ NLs::PathVersionEqual(3)});
+
+ {
auto itTablet = env.GetHiveState()->Tablets.find({TTestTxConfig::SchemeShard, 1});
- UNIT_ASSERT_UNEQUAL(itTablet, env.GetHiveState()->Tablets.end());
- UNIT_ASSERT_VALUES_EQUAL(itTablet->second.Type, TTabletTypes::PersQueue);
- UNIT_ASSERT_VALUES_UNEQUAL(itTablet->second.BoundChannels.size(), numChannels);
- UNIT_ASSERT_VALUES_EQUAL(itTablet->second.BoundChannels.size(), numChannelsNew);
- }
- }
-
- Y_UNIT_TEST(AlterWithReboots) {
+ UNIT_ASSERT_UNEQUAL(itTablet, env.GetHiveState()->Tablets.end());
+ UNIT_ASSERT_VALUES_EQUAL(itTablet->second.Type, TTabletTypes::PersQueue);
+ UNIT_ASSERT_VALUES_UNEQUAL(itTablet->second.BoundChannels.size(), numChannels);
+ UNIT_ASSERT_VALUES_EQUAL(itTablet->second.BoundChannels.size(), numChannelsNew);
+ }
+ }
+
+ Y_UNIT_TEST(AlterWithReboots) {
TTestWithReboots t;
t.Run([&](TTestActorRuntime& runtime, bool& activeZone) {
TPathVersion pqVer;
diff --git a/ydb/core/tx/schemeshard/ut_subdomain.cpp b/ydb/core/tx/schemeshard/ut_subdomain.cpp
index fa557c9ff85..d0d30bf7da8 100644
--- a/ydb/core/tx/schemeshard/ut_subdomain.cpp
+++ b/ydb/core/tx/schemeshard/ut_subdomain.cpp
@@ -402,11 +402,11 @@ Y_UNIT_TEST_SUITE(TSchemeShardSubDomainTest) {
NLs::PathsInsideDomain(3),
NLs::ShardsInsideDomain(4)});
TestDescribeResult(DescribePath(runtime, "/MyRoot/USER_0/table_0"),
- {NLs::InSubdomain});
+ {NLs::InSubdomain});
TestDescribeResult(DescribePath(runtime, "/MyRoot/USER_0/dir_0"),
- {NLs::InSubdomain});
+ {NLs::InSubdomain});
TestDescribeResult(DescribePath(runtime, "/MyRoot/USER_0/dir_0/table_1"),
- {NLs::InSubdomain});
+ {NLs::InSubdomain});
}
Y_UNIT_TEST(CreateSubDomainWithoutTablets) {
@@ -598,7 +598,7 @@ Y_UNIT_TEST_SUITE(TSchemeShardSubDomainTest) {
}
}
- Y_UNIT_TEST(SimultaneousCreateForceDrop) {
+ Y_UNIT_TEST(SimultaneousCreateForceDrop) {
TTestBasicRuntime runtime;
TTestEnv env(runtime);
ui64 txId = 100;
@@ -627,7 +627,7 @@ Y_UNIT_TEST_SUITE(TSchemeShardSubDomainTest) {
UNIT_ASSERT(!CheckLocalRowExists(runtime, TTestTxConfig::SchemeShard, "Paths", "Id", 2));
}
- Y_UNIT_TEST(ForceDropTwice) {
+ Y_UNIT_TEST(ForceDropTwice) {
TTestBasicRuntime runtime;
TTestEnv env(runtime);
ui64 txId = 100;
@@ -659,7 +659,7 @@ Y_UNIT_TEST_SUITE(TSchemeShardSubDomainTest) {
NLs::ShardsInsideDomain(0)});
}
- Y_UNIT_TEST(SimultaneousCreateForceDropTwice) {
+ Y_UNIT_TEST(SimultaneousCreateForceDropTwice) {
TTestBasicRuntime runtime;
TTestEnv env(runtime);
ui64 txId = 100;
@@ -1177,10 +1177,10 @@ Y_UNIT_TEST_SUITE(TSchemeShardSubDomainTest) {
UNIT_ASSERT(CheckLocalRowExists(runtime, TTestTxConfig::SchemeShard, "Paths", "Id", 3));
UNIT_ASSERT(CheckLocalRowExists(runtime, TTestTxConfig::SchemeShard, "BlockStoreVolumes", "PathId", 3));
- TestDescribeResult(DescribePath(runtime, "/MyRoot/USER_0"),
- {NLs::SubdomainWithNoEmptyStoragePools});
- TestDescribeResult(DescribePath(runtime, "/MyRoot/USER_0/BSVolume"),
- {NLs::PathsInsideDomain(1),
+ TestDescribeResult(DescribePath(runtime, "/MyRoot/USER_0"),
+ {NLs::SubdomainWithNoEmptyStoragePools});
+ TestDescribeResult(DescribePath(runtime, "/MyRoot/USER_0/BSVolume"),
+ {NLs::PathsInsideDomain(1),
NLs::ShardsInsideDomain(4)});
TestForceDropSubDomain(runtime, txId++, "/MyRoot", "USER_0");
@@ -1267,11 +1267,11 @@ Y_UNIT_TEST_SUITE(TSchemeShardSubDomainTest) {
);
UNIT_ASSERT_VALUES_EQUAL(tablet->BoundChannels[3].GetSize(), 222);
- TestDescribeResult(DescribePath(runtime, "/MyRoot/USER_0"),
- {NLs::SubdomainWithNoEmptyStoragePools});
-
+ TestDescribeResult(DescribePath(runtime, "/MyRoot/USER_0"),
+ {NLs::SubdomainWithNoEmptyStoragePools});
+
TestDescribeResult(DescribePath(runtime, "/MyRoot/USER_0/BSVolume"),
- {NLs::PathsInsideDomain(1), NLs::ShardsInsideDomain(4)});
+ {NLs::PathsInsideDomain(1), NLs::ShardsInsideDomain(4)});
vc.ClearBlockSize();
vc.ClearPartitions();
@@ -1561,14 +1561,14 @@ Y_UNIT_TEST_SUITE(TSchemeShardSubDomainTest) {
"Coordinators: 1 "
"Mediators: 2 "
"TimeCastBucketsPerMediator: 2 "
- "StoragePools { "
- " Name: \"pool-1\" "
- " Kind: \"pool-kind-1\" "
- "} "
- "StoragePools { "
- " Name: \"pool-2\" "
- " Kind: \"pool-kind-2\" "
- "} "
+ "StoragePools { "
+ " Name: \"pool-1\" "
+ " Kind: \"pool-kind-1\" "
+ "} "
+ "StoragePools { "
+ " Name: \"pool-2\" "
+ " Kind: \"pool-kind-2\" "
+ "} "
"StoragePools {"
" Name: \"pool-hdd-1\""
" Kind: \"hdd-1\""
@@ -1585,14 +1585,14 @@ Y_UNIT_TEST_SUITE(TSchemeShardSubDomainTest) {
"Coordinators: 1 "
"Mediators: 2 "
"TimeCastBucketsPerMediator: 2 "
- "StoragePools { "
- " Name: \"pool-1\" "
- " Kind: \"pool-kind-1\" "
- "} "
- "StoragePools { "
- " Name: \"pool-2\" "
- " Kind: \"pool-kind-2\" "
- "} "
+ "StoragePools { "
+ " Name: \"pool-1\" "
+ " Kind: \"pool-kind-1\" "
+ "} "
+ "StoragePools { "
+ " Name: \"pool-2\" "
+ " Kind: \"pool-kind-2\" "
+ "} "
"StoragePools {"
" Name: \"pool-hdd-2\""
" Kind: \"hdd-1\""
@@ -1605,14 +1605,14 @@ Y_UNIT_TEST_SUITE(TSchemeShardSubDomainTest) {
"Coordinators: 1 "
"Mediators: 2 "
"TimeCastBucketsPerMediator: 2 "
- "StoragePools { "
- " Name: \"pool-1\" "
- " Kind: \"pool-kind-1\" "
- "} "
- "StoragePools { "
- " Name: \"pool-2\" "
- " Kind: \"pool-kind-2\" "
- "} "
+ "StoragePools { "
+ " Name: \"pool-1\" "
+ " Kind: \"pool-kind-1\" "
+ "} "
+ "StoragePools { "
+ " Name: \"pool-2\" "
+ " Kind: \"pool-kind-2\" "
+ "} "
"StoragePools {"
" Name: \"pool-hdd-1\""
" Kind: \"hdd-1\""
@@ -1641,14 +1641,14 @@ Y_UNIT_TEST_SUITE(TSchemeShardSubDomainTest) {
"Coordinators: 1 "
"Mediators: 2 "
"TimeCastBucketsPerMediator: 2 "
- "StoragePools { "
- " Name: \"pool-1\" "
- " Kind: \"pool-kind-1\" "
- "} "
- "StoragePools { "
- " Name: \"pool-2\" "
- " Kind: \"pool-kind-2\" "
- "} "
+ "StoragePools { "
+ " Name: \"pool-1\" "
+ " Kind: \"pool-kind-1\" "
+ "} "
+ "StoragePools { "
+ " Name: \"pool-2\" "
+ " Kind: \"pool-kind-2\" "
+ "} "
"StoragePools {"
" Name: \"pool-hdd-1\""
" Kind: \"hdd-1\""
@@ -1834,14 +1834,14 @@ Y_UNIT_TEST_SUITE(TSchemeShardSubDomainTest) {
NLs::ShardsInsideDomain(0)});
TestAlterSubDomain(runtime, txId++, "/MyRoot",
- "StoragePools { "
- " Name: \"pool-1\" "
- " Kind: \"pool-kind-1\" "
- "} "
- "StoragePools { "
- " Name: \"pool-2\" "
- " Kind: \"pool-kind-2\" "
- "} "
+ "StoragePools { "
+ " Name: \"pool-1\" "
+ " Kind: \"pool-kind-1\" "
+ "} "
+ "StoragePools { "
+ " Name: \"pool-2\" "
+ " Kind: \"pool-kind-2\" "
+ "} "
"StoragePools {"
" Name: \"pool-hdd-1\""
" Kind: \"hdd-1\""
@@ -1862,14 +1862,14 @@ Y_UNIT_TEST_SUITE(TSchemeShardSubDomainTest) {
NLs::ShardsInsideDomain(0)});
TestAlterSubDomain(runtime, txId++, "/MyRoot",
- "StoragePools { "
- " Name: \"pool-1\" "
- " Kind: \"pool-kind-1\" "
- "} "
- "StoragePools { "
- " Name: \"pool-2\" "
- " Kind: \"pool-kind-2\" "
- "} "
+ "StoragePools { "
+ " Name: \"pool-1\" "
+ " Kind: \"pool-kind-1\" "
+ "} "
+ "StoragePools { "
+ " Name: \"pool-2\" "
+ " Kind: \"pool-kind-2\" "
+ "} "
"StoragePools {"
" Name: \"pool-hdd-1\""
" Kind: \"hdd-1\""
diff --git a/ydb/core/tx/schemeshard/ya.make b/ydb/core/tx/schemeshard/ya.make
index 6b4ff1ced1e..ceb87ce3883 100644
--- a/ydb/core/tx/schemeshard/ya.make
+++ b/ydb/core/tx/schemeshard/ya.make
@@ -14,7 +14,7 @@ RECURSE_FOR_TESTS(
ut_filestore_reboots
ut_index_build
ut_index_build_reboots
- ut_login
+ ut_login
ut_move
ut_move_reboots
ut_olap
@@ -41,7 +41,7 @@ RECURSE_FOR_TESTS(
ut_user_attributes
ut_user_attributes_reboots
)
-
+
LIBRARY()
OWNER(
@@ -72,7 +72,7 @@ SRCS(
schemeshard__init_schema.cpp
schemeshard__serverless_storage_billing.cpp
schemeshard__sync_update_tenants.cpp
- schemeshard__login.cpp
+ schemeshard__login.cpp
schemeshard__monitoring.cpp
schemeshard__notify.cpp
schemeshard__operation.cpp
@@ -86,7 +86,7 @@ SRCS(
schemeshard__operation_alter_fs.cpp
schemeshard__operation_alter_index.cpp
schemeshard__operation_alter_kesus.cpp
- schemeshard__operation_alter_login.cpp
+ schemeshard__operation_alter_login.cpp
schemeshard__operation_alter_olap_store.cpp
schemeshard__operation_alter_olap_table.cpp
schemeshard__operation_alter_pq.cpp
diff --git a/ydb/core/tx/tx_allocator/txallocator_impl.h b/ydb/core/tx/tx_allocator/txallocator_impl.h
index 814f574148a..5a539f9b7bc 100644
--- a/ydb/core/tx/tx_allocator/txallocator_impl.h
+++ b/ydb/core/tx/tx_allocator/txallocator_impl.h
@@ -56,8 +56,8 @@ public:
struct Schema : NIceDb::Schema {
// for compatible use old names config, dummyKey, reservedIds
struct config : Table<1> {
- enum EKeyType : bool {
- ReservedTo = true,
+ enum EKeyType : bool {
+ ReservedTo = true,
};
// for compatible use old names
diff --git a/ydb/core/tx/tx_allocator/txallocator_ut_helpers.cpp b/ydb/core/tx/tx_allocator/txallocator_ut_helpers.cpp
index 124042426b6..95566493b6f 100644
--- a/ydb/core/tx/tx_allocator/txallocator_ut_helpers.cpp
+++ b/ydb/core/tx/tx_allocator/txallocator_ut_helpers.cpp
@@ -72,19 +72,19 @@ void TTestEnv::SetupLogging(TTestActorRuntime &runtime) {
}
void TTestEnv::Setup(TTestActorRuntime &runtime) {
- static constexpr ui32 domainId = 0;
+ static constexpr ui32 domainId = 0;
SetupLogging(runtime);
TAppPrepare app;
- auto domain = TDomainsInfo::TDomain::ConstructDomainWithExplicitTabletIds("dc-1", domainId, 0,
+ auto domain = TDomainsInfo::TDomain::ConstructDomainWithExplicitTabletIds("dc-1", domainId, 0,
domainId, domainId, TVector<ui32>{domainId},
- domainId, TVector<ui32>{domainId},
- 100500,
- TVector<ui64>{},
- TVector<ui64>{},
- TVector<ui64>{},
- DefaultPoolKinds(2));
- app.AddDomain(domain.Release());
- //app.AddHive(0, 0);
+ domainId, TVector<ui32>{domainId},
+ 100500,
+ TVector<ui64>{},
+ TVector<ui64>{},
+ TVector<ui64>{},
+ DefaultPoolKinds(2));
+ app.AddDomain(domain.Release());
+ //app.AddHive(0, 0);
SetupChannelProfiles(app);
SetupTabletServices(runtime, &app, true);
}
diff --git a/ydb/core/tx/tx_allocator_client/actor_client.cpp b/ydb/core/tx/tx_allocator_client/actor_client.cpp
index c392779077d..20909a8401f 100644
--- a/ydb/core/tx/tx_allocator_client/actor_client.cpp
+++ b/ydb/core/tx/tx_allocator_client/actor_client.cpp
@@ -19,12 +19,12 @@ class TTxAllocatorClientActor: public TActorBootstrapped<TTxAllocatorClientActor
static NTabletPipe::TClientConfig InitPipeClientConfig() {
NTabletPipe::TClientConfig config;
- config.RetryPolicy = {
- .RetryLimitCount = 3,
- .MinRetryTime = TDuration::MilliSeconds(100),
- .MaxRetryTime = TDuration::Seconds(1),
- .BackoffMultiplier = 5
- };
+ config.RetryPolicy = {
+ .RetryLimitCount = 3,
+ .MinRetryTime = TDuration::MilliSeconds(100),
+ .MaxRetryTime = TDuration::Seconds(1),
+ .BackoffMultiplier = 5
+ };
return config;
}
diff --git a/ydb/core/tx/tx_proxy/datareq.cpp b/ydb/core/tx/tx_proxy/datareq.cpp
index 9e5c12db2eb..af48b42d60f 100644
--- a/ydb/core/tx/tx_proxy/datareq.cpp
+++ b/ydb/core/tx/tx_proxy/datareq.cpp
@@ -313,7 +313,7 @@ private:
TString DatashardErrors;
TVector<ui64> ComplainingDatashards;
TVector<TString> UnresolvedKeys;
- TAutoPtr<const NACLib::TUserToken> UserToken;
+ TAutoPtr<const NACLib::TUserToken> UserToken;
THashMap<ui64, TPerTablet> PerTablet;
NYql::TIssueManager IssueManager;
@@ -1249,10 +1249,10 @@ void TDataReq::Handle(TEvTxProxyReq::TEvMakeRequest::TPtr &ev, const TActorConte
"Actor# " << ctx.SelfID.ToString() << " Cookie# " << (ui64)ev->Cookie
<< " txid# " << TxId << " HANDLE TDataReq marker# P1");
- if (!record.GetUserToken().empty()) {
- UserToken = new NACLib::TUserToken(record.GetUserToken());
- }
-
+ if (!record.GetUserToken().empty()) {
+ UserToken = new NACLib::TUserToken(record.GetUserToken());
+ }
+
// For read table transaction we need to resolve table path.
if (txbody.HasReadTableTransaction()) {
ReadTableRequest = new TReadTableRequest(txbody.GetReadTableTransaction());
@@ -1594,7 +1594,7 @@ void TDataReq::Handle(TEvTxProxySchemeCache::TEvResolveKeySetResult::TPtr &ev, c
if (access != 0
&& UserToken != nullptr
&& entry.KeyDescription->Status == TKeyDesc::EStatus::Ok
- && entry.KeyDescription->SecurityObject != nullptr
+ && entry.KeyDescription->SecurityObject != nullptr
&& !entry.KeyDescription->SecurityObject->CheckAccess(access, *UserToken)) {
TStringStream explanation;
explanation << "Access denied for " << UserToken->GetUserSID()
diff --git a/ydb/core/tx/tx_proxy/describe.cpp b/ydb/core/tx/tx_proxy/describe.cpp
index a26839c2617..deb38ca2b7d 100644
--- a/ydb/core/tx/tx_proxy/describe.cpp
+++ b/ydb/core/tx/tx_proxy/describe.cpp
@@ -14,10 +14,10 @@
namespace NKikimr {
namespace NTxProxy {
-class TDescribeReq : public TActor<TDescribeReq> {
- const TTxProxyServices Services;
+class TDescribeReq : public TActor<TDescribeReq> {
+ const TTxProxyServices Services;
- THolder<TEvTxProxyReq::TEvNavigateScheme> SchemeRequest;
+ THolder<TEvTxProxyReq::TEvNavigateScheme> SchemeRequest;
TIntrusivePtr<TTxProxyMon> TxProxyMon;
TInstant WallClockStarted;
@@ -25,8 +25,8 @@ class TDescribeReq : public TActor<TDescribeReq> {
TActorId Source;
ui64 SourceCookie;
- TAutoPtr<const NACLib::TUserToken> UserToken;
-
+ TAutoPtr<const NACLib::TUserToken> UserToken;
+
TString TextPath;
void Die(const TActorContext &ctx) override {
@@ -40,16 +40,16 @@ class TDescribeReq : public TActor<TDescribeReq> {
void ReportError(NKikimrScheme::EStatus status, const TString& reason, const TActorContext &ctx) {
TAutoPtr<NSchemeShard::TEvSchemeShard::TEvDescribeSchemeResultBuilder> result =
new NSchemeShard::TEvSchemeShard::TEvDescribeSchemeResultBuilder();
-
- if (SchemeRequest != nullptr) {
- const auto &record = SchemeRequest->Ev->Get()->Record;
+
+ if (SchemeRequest != nullptr) {
+ const auto &record = SchemeRequest->Ev->Get()->Record;
if (record.GetDescribePath().HasPath()) {
result->Record.SetPath(record.GetDescribePath().GetPath());
- }
- }
+ }
+ }
- result->Record.SetStatus(status);
- result->Record.SetReason(reason);
+ result->Record.SetStatus(status);
+ result->Record.SetReason(reason);
ctx.Send(Source, result.Release(), 0, SourceCookie);
}
@@ -60,10 +60,10 @@ class TDescribeReq : public TActor<TDescribeReq> {
descr->SetSchemeshardId(schemeRootId);
descr->SetPathType(NKikimrSchemeOp::EPathType::EPathTypeDir);
descr->SetCreateFinished(true);
- // TODO(xenoxeno): ?
- //descr->SetCreateTxId(0);
- //descr->SetCreateStep(0);
- //descr->SetOwner(BUILTIN_ACL_ROOT);
+ // TODO(xenoxeno): ?
+ //descr->SetCreateTxId(0);
+ //descr->SetCreateStep(0);
+ //descr->SetOwner(BUILTIN_ACL_ROOT);
}
void FillSystemViewDescr(NKikimrSchemeOp::TDirEntry* descr, ui64 schemeShardId) {
@@ -178,7 +178,7 @@ class TDescribeReq : public TActor<TDescribeReq> {
void Handle(TEvTxProxyReq::TEvNavigateScheme::TPtr &ev, const TActorContext &ctx);
void Handle(TEvPipeCache::TEvDeliveryProblem::TPtr &ev, const TActorContext &ctx);
- void Handle(TEvTxProxySchemeCache::TEvNavigateKeySetResult::TPtr &ev, const TActorContext &ctx);
+ void Handle(TEvTxProxySchemeCache::TEvNavigateKeySetResult::TPtr &ev, const TActorContext &ctx);
void Handle(NSchemeShard::TEvSchemeShard::TEvDescribeSchemeResult::TPtr &ev, const TActorContext &ctx);
public:
@@ -186,9 +186,9 @@ public:
return NKikimrServices::TActivity::TX_PROXY_NAVIGATE;
}
- TDescribeReq(const TTxProxyServices &services, const TIntrusivePtr<TTxProxyMon>& txProxyMon)
+ TDescribeReq(const TTxProxyServices &services, const TIntrusivePtr<TTxProxyMon>& txProxyMon)
: TActor(&TThis::StateWaitInit)
- , Services(services)
+ , Services(services)
, TxProxyMon(txProxyMon)
{
++*TxProxyMon->NavigateReqInFly;
@@ -200,12 +200,12 @@ public:
}
}
- STFUNC(StateWaitResolve) {
- switch (ev->GetTypeRewrite()) {
- HFunc(TEvTxProxySchemeCache::TEvNavigateKeySetResult, Handle);
- }
- }
-
+ STFUNC(StateWaitResolve) {
+ switch (ev->GetTypeRewrite()) {
+ HFunc(TEvTxProxySchemeCache::TEvNavigateKeySetResult, Handle);
+ }
+ }
+
STFUNC(StateWaitExec) {
switch (ev->GetTypeRewrite()) {
HFunc(NSchemeShard::TEvSchemeShard::TEvDescribeSchemeResult, Handle);
@@ -214,7 +214,7 @@ public:
}
};
-void TDescribeReq::Handle(TEvTxProxyReq::TEvNavigateScheme::TPtr &ev, const TActorContext &ctx) {
+void TDescribeReq::Handle(TEvTxProxyReq::TEvNavigateScheme::TPtr &ev, const TActorContext &ctx) {
TEvTxProxyReq::TEvNavigateScheme *msg = ev->Get();
const auto &record = msg->Ev->Get()->Record;
LOG_DEBUG_S(ctx, NKikimrServices::TX_PROXY, "Actor# " << ctx.SelfID.ToString() << " HANDLE EvNavigateScheme " << record.GetDescribePath().GetPath());
@@ -242,32 +242,32 @@ void TDescribeReq::Handle(TEvTxProxyReq::TEvNavigateScheme::TPtr &ev, const TAct
ctx.Send(Source, result.Release(), 0, SourceCookie);
return Die(ctx);
}
- }
+ }
- if (!record.GetUserToken().empty()) {
- UserToken = new NACLib::TUserToken(record.GetUserToken());
- }
+ if (!record.GetUserToken().empty()) {
+ UserToken = new NACLib::TUserToken(record.GetUserToken());
+ }
- if (UserToken == nullptr && record.GetDescribePath().HasPathId()) {
+ if (UserToken == nullptr && record.GetDescribePath().HasPathId()) {
TAutoPtr<NSchemeShard::TEvSchemeShard::TEvDescribeScheme> req =
new NSchemeShard::TEvSchemeShard::TEvDescribeScheme(
- record.GetDescribePath().GetSchemeshardId(),
- record.GetDescribePath().GetPathId());
+ record.GetDescribePath().GetSchemeshardId(),
+ record.GetDescribePath().GetPathId());
- const ui64 shardToRequest = record.GetDescribePath().GetSchemeshardId();
+ const ui64 shardToRequest = record.GetDescribePath().GetSchemeshardId();
if (record.GetDescribePath().HasOptions()) {
auto options = req->Record.MutableOptions();
options->CopyFrom(record.GetDescribePath().GetOptions());
}
- LOG_DEBUG_S(ctx, NKikimrServices::TX_PROXY, "Actor# " << ctx.SelfID.ToString()
- << " SEND to# " << shardToRequest << " shardToRequest " << req->ToString());
+ LOG_DEBUG_S(ctx, NKikimrServices::TX_PROXY, "Actor# " << ctx.SelfID.ToString()
+ << " SEND to# " << shardToRequest << " shardToRequest " << req->ToString());
Send(Services.LeaderPipeCache, new TEvPipeCache::TEvForward(req.Release(), shardToRequest, true), 0, SourceCookie);
- Become(&TThis::StateWaitExec);
- return;
- }
+ Become(&TThis::StateWaitExec);
+ return;
+ }
TAutoPtr<NSchemeCache::TSchemeCacheNavigate> request(new NSchemeCache::TSchemeCacheNavigate());
request->DatabaseName = record.GetDatabaseName();
@@ -276,22 +276,22 @@ void TDescribeReq::Handle(TEvTxProxyReq::TEvNavigateScheme::TPtr &ev, const TAct
entry.SyncVersion = true;
entry.ShowPrivatePath = record.GetDescribePath().GetOptions().GetShowPrivateTable();
entry.Path = SplitPath(record.GetDescribePath().GetPath());
- if (entry.Path.empty()) {
+ if (entry.Path.empty()) {
ReportError(NKikimrScheme::StatusInvalidParameter, "Invalid path", ctx);
- TxProxyMon->ResolveKeySetWrongRequest->Inc();
- return Die(ctx);
- }
+ TxProxyMon->ResolveKeySetWrongRequest->Inc();
+ return Die(ctx);
+ }
- request->ResultSet.emplace_back(entry);
+ request->ResultSet.emplace_back(entry);
ctx.Send(Services.SchemeCache, new TEvTxProxySchemeCache::TEvNavigateKeySet(request), 0, SourceCookie);
- SchemeRequest = ev->Release();
- Become(&TThis::StateWaitResolve);
-}
+ SchemeRequest = ev->Release();
+ Become(&TThis::StateWaitResolve);
+}
-void TDescribeReq::Handle(TEvTxProxySchemeCache::TEvNavigateKeySetResult::TPtr &ev, const TActorContext &ctx) {
- TEvTxProxySchemeCache::TEvNavigateKeySetResult *msg = ev->Get();
+void TDescribeReq::Handle(TEvTxProxySchemeCache::TEvNavigateKeySetResult::TPtr &ev, const TActorContext &ctx) {
+ TEvTxProxySchemeCache::TEvNavigateKeySetResult *msg = ev->Get();
NSchemeCache::TSchemeCacheNavigate *navigate = msg->Request.Get();
TxProxyMon->CacheRequestLatency->Collect((ctx.Now() - WallClockStarted).MilliSeconds());
@@ -300,11 +300,11 @@ void TDescribeReq::Handle(TEvTxProxySchemeCache::TEvNavigateKeySetResult::TPtr &
const auto& entry = navigate->ResultSet.front();
LOG_LOG_S(ctx, (navigate->ErrorCount == 0 ? NActors::NLog::PRI_DEBUG : NActors::NLog::PRI_INFO),
- NKikimrServices::TX_PROXY,
- "Actor# " << ctx.SelfID.ToString()
- << " HANDLE EvNavigateKeySetResult TDescribeReq marker# P5 ErrorCount# " << navigate->ErrorCount);
+ NKikimrServices::TX_PROXY,
+ "Actor# " << ctx.SelfID.ToString()
+ << " HANDLE EvNavigateKeySetResult TDescribeReq marker# P5 ErrorCount# " << navigate->ErrorCount);
- if (navigate->ErrorCount > 0) {
+ if (navigate->ErrorCount > 0) {
switch (entry.Status) {
case NSchemeCache::TSchemeCacheNavigate::EStatus::PathErrorUnknown:
if (UserToken != nullptr && entry.SecurityObject != nullptr) {
@@ -335,15 +335,15 @@ void TDescribeReq::Handle(TEvTxProxySchemeCache::TEvNavigateKeySetResult::TPtr &
break;
}
- return Die(ctx);
- }
-
- if (UserToken != nullptr) {
- ui32 access = NACLib::EAccessRights::DescribeSchema;
- if (entry.SecurityObject != nullptr && !entry.SecurityObject->CheckAccess(access, *UserToken)) {
- LOG_ERROR_S(ctx, NKikimrServices::TX_PROXY,
- "Access denied for " << UserToken->GetUserSID()
- << " with access " << NACLib::AccessRightsToString(access)
+ return Die(ctx);
+ }
+
+ if (UserToken != nullptr) {
+ ui32 access = NACLib::EAccessRights::DescribeSchema;
+ if (entry.SecurityObject != nullptr && !entry.SecurityObject->CheckAccess(access, *UserToken)) {
+ LOG_ERROR_S(ctx, NKikimrServices::TX_PROXY,
+ "Access denied for " << UserToken->GetUserSID()
+ << " with access " << NACLib::AccessRightsToString(access)
<< " to path " << JoinPath(entry.Path));
ReportError(NKikimrScheme::StatusAccessDenied, "Access denied", ctx);
return Die(ctx);
@@ -368,14 +368,14 @@ void TDescribeReq::Handle(TEvTxProxySchemeCache::TEvNavigateKeySetResult::TPtr &
TAutoPtr<NSchemeShard::TEvSchemeShard::TEvDescribeScheme> req(
new NSchemeShard::TEvSchemeShard::TEvDescribeScheme(describePath));
- LOG_DEBUG_S(ctx, NKikimrServices::TX_PROXY, "Actor# " << ctx.SelfID.ToString()
- << " SEND to# " << shardToRequest << " shardToRequest " << req->ToString());
+ LOG_DEBUG_S(ctx, NKikimrServices::TX_PROXY, "Actor# " << ctx.SelfID.ToString()
+ << " SEND to# " << shardToRequest << " shardToRequest " << req->ToString());
Send(Services.LeaderPipeCache, new TEvPipeCache::TEvForward(req.Release(), shardToRequest, true), 0, SourceCookie);
Become(&TThis::StateWaitExec);
}
-
+
void TDescribeReq::Handle(NSchemeShard::TEvSchemeShard::TEvDescribeSchemeResult::TPtr &ev, const TActorContext &ctx) {
LOG_DEBUG_S(ctx, NKikimrServices::TX_PROXY,
"Actor# " << ctx.SelfID.ToString() <<
@@ -436,11 +436,11 @@ void TDescribeReq::Handle(NSchemeShard::TEvSchemeShard::TEvDescribeSchemeResult:
void TDescribeReq::Handle(TEvPipeCache::TEvDeliveryProblem::TPtr &ev, const TActorContext &ctx) {
Y_UNUSED(ev);
ReportError(NKikimrScheme::StatusNotAvailable, "Schemeshard not available", ctx);
- return Die(ctx);
+ return Die(ctx);
}
-IActor* CreateTxProxyDescribeFlatSchemeReq(const TTxProxyServices &services, const TIntrusivePtr<TTxProxyMon>& txProxyMon) {
- return new TDescribeReq(services, txProxyMon);
+IActor* CreateTxProxyDescribeFlatSchemeReq(const TTxProxyServices &services, const TIntrusivePtr<TTxProxyMon>& txProxyMon) {
+ return new TDescribeReq(services, txProxyMon);
}
}
diff --git a/ydb/core/tx/tx_proxy/encrypted_storage_ut.cpp b/ydb/core/tx/tx_proxy/encrypted_storage_ut.cpp
index 215fe6a110b..aee15400043 100644
--- a/ydb/core/tx/tx_proxy/encrypted_storage_ut.cpp
+++ b/ydb/core/tx/tx_proxy/encrypted_storage_ut.cpp
@@ -12,9 +12,9 @@ using namespace NKikimr;
using namespace NTxProxyUT;
using namespace NHelpers;
-class TTestEnvWithEncryptedPoolsSupport: public TBaseTestEnv {
+class TTestEnvWithEncryptedPoolsSupport: public TBaseTestEnv {
public:
- TTestEnvWithEncryptedPoolsSupport(ui32 staticNodes = 1, ui32 dynamicNodes = 2)
+ TTestEnvWithEncryptedPoolsSupport(ui32 staticNodes = 1, ui32 dynamicNodes = 2)
{
Settings = new Tests::TServerSettings(PortManager.GetPort(3534));
GetSettings().SetEnableMockOnSingleNode(false);
@@ -22,7 +22,7 @@ public:
GetSettings().SetNodeCount(staticNodes);
GetSettings().SetDynamicNodeCount(dynamicNodes);
ui32 encryptionMode = 1;
- GetSettings().AddStoragePool("encrypted", "", encryptionMode);
+ GetSettings().AddStoragePool("encrypted", "", encryptionMode);
for (ui32 nodeIdx = 0; nodeIdx < staticNodes + dynamicNodes; ++nodeIdx) {
TString key = TStringBuilder() << "node_key_" << nodeIdx;
@@ -55,7 +55,7 @@ Y_UNIT_TEST_SUITE(TStorageTenantTest) {
Y_UNIT_TEST(CreateTableOutsideDatabaseFailToStartTabletsButDropIsOk) {
return;
- TTestEnvWithEncryptedPoolsSupport env(1, 1);
+ TTestEnvWithEncryptedPoolsSupport env(1, 1);
UNIT_ASSERT_VALUES_EQUAL("/dc-1", env.GetRoot());
UNIT_ASSERT_VALUES_EQUAL(NMsgBusProxy::MSTATUS_OK,
diff --git a/ydb/core/tx/tx_proxy/proxy.h b/ydb/core/tx/tx_proxy/proxy.h
index d92177b7728..86d4f1ac79e 100644
--- a/ydb/core/tx/tx_proxy/proxy.h
+++ b/ydb/core/tx/tx_proxy/proxy.h
@@ -39,8 +39,8 @@ struct TEvTxUserProxy {
EvProposeTransactionStatus = EvProposeTransaction + 1 * 512,
EvNavigateStatus,
- EvInvalidateTable,
- EvInvalidateTableResult,
+ EvInvalidateTable,
+ EvInvalidateTableResult,
EvCancelBackupRequestDeprecated,
EvCancelBackupResultDeprecated,
@@ -161,14 +161,14 @@ struct TEvTxUserProxy {
TString ToString() const;
};
- struct TEvInvalidateTable : public TEventPB<TEvInvalidateTable, NKikimrTxUserProxy::TEvInvalidateTable, EvInvalidateTable> {
- TEvInvalidateTable() = default;
- TEvInvalidateTable(const TTableId& tableId) {
+ struct TEvInvalidateTable : public TEventPB<TEvInvalidateTable, NKikimrTxUserProxy::TEvInvalidateTable, EvInvalidateTable> {
+ TEvInvalidateTable() = default;
+ TEvInvalidateTable(const TTableId& tableId) {
Record.SetSchemeShardId(tableId.PathId.OwnerId);
Record.SetTableId(tableId.PathId.LocalPathId);
- }
- };
-
+ }
+ };
+
struct TEvInvalidateTableResult : public TEventSimple<TEvInvalidateTableResult, EvInvalidateTableResult> {};
struct TEvProposeKqpTransaction : public TEventLocal<TEvProposeKqpTransaction, EvProposeKqpTransaction> {
diff --git a/ydb/core/tx/tx_proxy/proxy_ext_tenant_ut.cpp b/ydb/core/tx/tx_proxy/proxy_ext_tenant_ut.cpp
index 153449732c1..ff7c9579d83 100644
--- a/ydb/core/tx/tx_proxy/proxy_ext_tenant_ut.cpp
+++ b/ydb/core/tx/tx_proxy/proxy_ext_tenant_ut.cpp
@@ -46,15 +46,15 @@ void DeclareAndDrop(TTestEnv& env) {
}
-void DeclareAndDefineWithoutNodes(TTestEnvWithPoolsSupport& env) {
+void DeclareAndDefineWithoutNodes(TTestEnvWithPoolsSupport& env) {
{
auto subdomain = GetSubDomainDeclareSetting("USER_0");
UNIT_ASSERT_VALUES_EQUAL(NMsgBusProxy::MSTATUS_OK, env.GetClient().CreateExtSubdomain("/dc-1", subdomain));
}
{
- auto storagePool = env.CreatePoolsForTenant("USER_0");
- auto subdomain = GetSubDomainDefaultSetting("USER_0", storagePool);
+ auto storagePool = env.CreatePoolsForTenant("USER_0");
+ auto subdomain = GetSubDomainDefaultSetting("USER_0", storagePool);
subdomain.SetExternalSchemeShard(true);
UNIT_ASSERT_VALUES_EQUAL(NMsgBusProxy::MSTATUS_INPROGRESS, env.GetClient().AlterExtSubdomain("/dc-1", subdomain, TDuration::MilliSeconds(500)));
}
@@ -72,7 +72,7 @@ void DeclareAndDefineWithoutNodes(TTestEnvWithPoolsSupport& env) {
}
}
-void DeclareAndDefineWithNodes(TTestEnvWithPoolsSupport& env) {
+void DeclareAndDefineWithNodes(TTestEnvWithPoolsSupport& env) {
{
auto subdomain = GetSubDomainDeclareSetting("USER_0");
UNIT_ASSERT_VALUES_EQUAL(NMsgBusProxy::MSTATUS_OK, env.GetClient().CreateExtSubdomain("/dc-1", subdomain));
@@ -81,10 +81,10 @@ void DeclareAndDefineWithNodes(TTestEnvWithPoolsSupport& env) {
env.GetTenants().Run("/dc-1/USER_0");
{
- auto storagePool = env.CreatePoolsForTenant("USER_0");
- auto subdomain = GetSubDomainDefaultSetting("USER_0", storagePool);
+ auto storagePool = env.CreatePoolsForTenant("USER_0");
+ auto subdomain = GetSubDomainDefaultSetting("USER_0", storagePool);
subdomain.SetExternalSchemeShard(true);
- subdomain.SetExternalHive(true);
+ subdomain.SetExternalHive(true);
UNIT_ASSERT_VALUES_EQUAL(NMsgBusProxy::MSTATUS_OK, env.GetClient().AlterExtSubdomain("/dc-1", subdomain, WaitTimeOut));
}
@@ -104,7 +104,7 @@ void DeclareAndDefineWithNodes(TTestEnvWithPoolsSupport& env) {
}
}
-void CreateTableInsideAndLs(TTestEnvWithPoolsSupport& env) {
+void CreateTableInsideAndLs(TTestEnvWithPoolsSupport& env) {
ui64 rootSchemeShard = Tests::ChangeStateStorage(Tests::SchemeRoot, 1);
{
@@ -115,10 +115,10 @@ void CreateTableInsideAndLs(TTestEnvWithPoolsSupport& env) {
env.GetTenants().Run("/dc-1/USER_0");
{
- auto storagePool = env.CreatePoolsForTenant("USER_0");
- auto subdomain = GetSubDomainDefaultSetting("USER_0", storagePool);
+ auto storagePool = env.CreatePoolsForTenant("USER_0");
+ auto subdomain = GetSubDomainDefaultSetting("USER_0", storagePool);
subdomain.SetExternalSchemeShard(true);
- subdomain.SetExternalHive(true);
+ subdomain.SetExternalHive(true);
UNIT_ASSERT_VALUES_EQUAL(NMsgBusProxy::MSTATUS_OK, env.GetClient().AlterExtSubdomain("/dc-1", subdomain));
auto ls = env.GetClient().Ls("/dc-1/USER_0");
@@ -215,15 +215,15 @@ void DeclareAndAlterPools(TTestEnvWithPoolsSupport& env) {
UNIT_ASSERT_VALUES_EQUAL(NMsgBusProxy::MSTATUS_OK, env.GetClient().ForceDeleteSubdomain("/dc-1", "USER_0"));
}
-void CreateTableInsideThenStopTenantAndForceDeleteSubDomain(TTestEnvWithPoolsSupport& env) {
+void CreateTableInsideThenStopTenantAndForceDeleteSubDomain(TTestEnvWithPoolsSupport& env) {
ui64 rootSchemeShard = Tests::ChangeStateStorage(Tests::SchemeRoot, 1);
- auto storagePool = env.CreatePoolsForTenant("USER_0");
+ auto storagePool = env.CreatePoolsForTenant("USER_0");
const ui32 triesNum = 3;
TVector<ui64> schemeshards(triesNum, 0);
for (ui32 x = 0; x < triesNum; ++x) {
{
auto subdomain_0 = GetSubDomainDeclareSetting("USER_0");
- subdomain_0.SetExternalHive(true);
+ subdomain_0.SetExternalHive(true);
UNIT_ASSERT_VALUES_EQUAL(NMsgBusProxy::MSTATUS_OK, env.GetClient().CreateExtSubdomain("/dc-1", subdomain_0));
auto ls = env.GetClient().Ls("/dc-1/USER_0");
@@ -237,8 +237,8 @@ void CreateTableInsideThenStopTenantAndForceDeleteSubDomain(TTestEnvWithPoolsSup
env.GetTenants().Run("/dc-1/USER_0");
{
- auto subdomain = GetSubDomainDefaultSetting("USER_0", storagePool);
- subdomain.SetExternalHive(true);
+ auto subdomain = GetSubDomainDefaultSetting("USER_0", storagePool);
+ subdomain.SetExternalHive(true);
subdomain.SetExternalSchemeShard(true);
UNIT_ASSERT_VALUES_EQUAL(NMsgBusProxy::MSTATUS_OK, env.GetClient().AlterExtSubdomain("/dc-1", subdomain));
@@ -301,183 +301,183 @@ void CreateTableInsideThenStopTenantAndForceDeleteSubDomain(TTestEnvWithPoolsSup
}
}
-void CreateTableInsideAndDeleteTable(TTestEnvWithPoolsSupport& env) {
- ui64 rootSchemeShard = Tests::ChangeStateStorage(Tests::SchemeRoot, 1);
- auto storagePool = env.CreatePoolsForTenant("USER_0");
- const ui32 triesNum = 3;
- TVector<ui64> schemeshards(triesNum, 0);
- for (ui32 x = 0; x < triesNum; ++x) {
- {
- auto subdomain_0 = GetSubDomainDeclareSetting("USER_0");
- subdomain_0.SetExternalHive(true);
- UNIT_ASSERT_VALUES_EQUAL(NMsgBusProxy::MSTATUS_OK, env.GetClient().CreateExtSubdomain("/dc-1", subdomain_0));
-
- auto ls = env.GetClient().Ls("/dc-1/USER_0");
- NTestLs::IsUnavailable(ls); //root TSS not ready yet
-
- ls = env.GetClient().Ls("/dc-1");
- NTestLs::ChildrenCount(ls, 1);
+void CreateTableInsideAndDeleteTable(TTestEnvWithPoolsSupport& env) {
+ ui64 rootSchemeShard = Tests::ChangeStateStorage(Tests::SchemeRoot, 1);
+ auto storagePool = env.CreatePoolsForTenant("USER_0");
+ const ui32 triesNum = 3;
+ TVector<ui64> schemeshards(triesNum, 0);
+ for (ui32 x = 0; x < triesNum; ++x) {
+ {
+ auto subdomain_0 = GetSubDomainDeclareSetting("USER_0");
+ subdomain_0.SetExternalHive(true);
+ UNIT_ASSERT_VALUES_EQUAL(NMsgBusProxy::MSTATUS_OK, env.GetClient().CreateExtSubdomain("/dc-1", subdomain_0));
+
+ auto ls = env.GetClient().Ls("/dc-1/USER_0");
+ NTestLs::IsUnavailable(ls); //root TSS not ready yet
+
+ ls = env.GetClient().Ls("/dc-1");
+ NTestLs::ChildrenCount(ls, 1);
NTestLs::HasChild(ls, "USER_0", NKikimrSchemeOp::EPathTypeExtSubDomain);
- }
-
- env.GetTenants().Run("/dc-1/USER_0");
-
- {
- auto subdomain = GetSubDomainDefaultSetting("USER_0", storagePool);
- subdomain.SetExternalHive(true);
- subdomain.SetExternalSchemeShard(true);
- UNIT_ASSERT_VALUES_EQUAL(NMsgBusProxy::MSTATUS_OK, env.GetClient().AlterExtSubdomain("/dc-1", subdomain));
-
- auto ls = env.GetClient().Ls("/dc-1/USER_0");
- NTestLs::IsExtSubdomain(ls); //root TSS ready
- auto ver = NTestLs::ExtractPathVersion(ls);
- UNIT_ASSERT_VALUES_UNEQUAL(ver.OwnerId, rootSchemeShard);
- schemeshards[x] = ver.OwnerId;
- if (x) {
- UNIT_ASSERT_VALUES_UNEQUAL(schemeshards[x], schemeshards[x-1]);
- }
- UNIT_ASSERT_VALUES_EQUAL(ver.PathId, 1);
- UNIT_ASSERT_VALUES_EQUAL(ver.Version, 4);
- }
-
- {
- auto tableDesc = GetTableSimpleDescription("SimpleTable");
- UNIT_ASSERT_VALUES_EQUAL(env.GetClient().CreateTable("/dc-1/USER_0", tableDesc),
- NMsgBusProxy::MSTATUS_OK);
-
- env.GetClient().RefreshPathCache(&env.GetRuntime(), "/dc-1/USER_0/SimpleTable");
- auto ls = env.GetClient().Ls("/dc-1/USER_0/SimpleTable");
+ }
+
+ env.GetTenants().Run("/dc-1/USER_0");
+
+ {
+ auto subdomain = GetSubDomainDefaultSetting("USER_0", storagePool);
+ subdomain.SetExternalHive(true);
+ subdomain.SetExternalSchemeShard(true);
+ UNIT_ASSERT_VALUES_EQUAL(NMsgBusProxy::MSTATUS_OK, env.GetClient().AlterExtSubdomain("/dc-1", subdomain));
+
+ auto ls = env.GetClient().Ls("/dc-1/USER_0");
+ NTestLs::IsExtSubdomain(ls); //root TSS ready
+ auto ver = NTestLs::ExtractPathVersion(ls);
+ UNIT_ASSERT_VALUES_UNEQUAL(ver.OwnerId, rootSchemeShard);
+ schemeshards[x] = ver.OwnerId;
+ if (x) {
+ UNIT_ASSERT_VALUES_UNEQUAL(schemeshards[x], schemeshards[x-1]);
+ }
+ UNIT_ASSERT_VALUES_EQUAL(ver.PathId, 1);
+ UNIT_ASSERT_VALUES_EQUAL(ver.Version, 4);
+ }
+
+ {
+ auto tableDesc = GetTableSimpleDescription("SimpleTable");
+ UNIT_ASSERT_VALUES_EQUAL(env.GetClient().CreateTable("/dc-1/USER_0", tableDesc),
+ NMsgBusProxy::MSTATUS_OK);
+
+ env.GetClient().RefreshPathCache(&env.GetRuntime(), "/dc-1/USER_0/SimpleTable");
+ auto ls = env.GetClient().Ls("/dc-1/USER_0/SimpleTable");
NTestLs::PathType(ls, NKikimrSchemeOp::EPathTypeTable);
- auto ver = NTestLs::ExtractPathVersion(ls);
- UNIT_ASSERT_VALUES_EQUAL(ver.OwnerId, schemeshards[x]);
- UNIT_ASSERT_VALUES_EQUAL(ver.PathId, 2);
- UNIT_ASSERT_VALUES_EQUAL(ver.Version, 3);
-
- UNIT_ASSERT_VALUES_EQUAL(env.GetClient().DeleteTable("/dc-1/USER_0", "SimpleTable"),
- NMsgBusProxy::MSTATUS_OK);
-
- auto shards = NTestLs::ExtractTablePartitions(ls);
- for (auto shard : shards) {
- bool success = env.GetClient().WaitForTabletDown(&env.GetRuntime(), shard.GetDatashardId(), true, TDuration::Seconds(60));
- UNIT_ASSERT(success);
- }
-
- }
- {
- env.GetClient().RefreshPathCache(&env.GetRuntime(), "/dc-1/USER_0/SimpleTable");
- auto ls = env.GetClient().Ls("/dc-1/USER_0/SimpleTable");
- NTestLs::IsDoesNotExist(ls);
- }
-
- env.GetTenants().Stop();
-
+ auto ver = NTestLs::ExtractPathVersion(ls);
+ UNIT_ASSERT_VALUES_EQUAL(ver.OwnerId, schemeshards[x]);
+ UNIT_ASSERT_VALUES_EQUAL(ver.PathId, 2);
+ UNIT_ASSERT_VALUES_EQUAL(ver.Version, 3);
+
+ UNIT_ASSERT_VALUES_EQUAL(env.GetClient().DeleteTable("/dc-1/USER_0", "SimpleTable"),
+ NMsgBusProxy::MSTATUS_OK);
+
+ auto shards = NTestLs::ExtractTablePartitions(ls);
+ for (auto shard : shards) {
+ bool success = env.GetClient().WaitForTabletDown(&env.GetRuntime(), shard.GetDatashardId(), true, TDuration::Seconds(60));
+ UNIT_ASSERT(success);
+ }
+
+ }
+ {
+ env.GetClient().RefreshPathCache(&env.GetRuntime(), "/dc-1/USER_0/SimpleTable");
+ auto ls = env.GetClient().Ls("/dc-1/USER_0/SimpleTable");
+ NTestLs::IsDoesNotExist(ls);
+ }
+
+ env.GetTenants().Stop();
+
UNIT_ASSERT_VALUES_EQUAL(NMsgBusProxy::MSTATUS_OK, env.GetClient().ForceDeleteSubdomain("/dc-1", "USER_0"));
-
- {
- auto ls = env.GetClient().Ls("/dc-1");
- NTestLs::NoChildren(ls);
- auto ver = NTestLs::ExtractPathVersion(ls);
- UNIT_ASSERT_VALUES_EQUAL(ver.OwnerId, rootSchemeShard);
- UNIT_ASSERT_VALUES_EQUAL(ver.PathId, 1);
+
+ {
+ auto ls = env.GetClient().Ls("/dc-1");
+ NTestLs::NoChildren(ls);
+ auto ver = NTestLs::ExtractPathVersion(ls);
+ UNIT_ASSERT_VALUES_EQUAL(ver.OwnerId, rootSchemeShard);
+ UNIT_ASSERT_VALUES_EQUAL(ver.PathId, 1);
UNIT_ASSERT_VALUES_EQUAL(ver.Version, 7 + x * 4);
-
- env.GetClient().RefreshPathCache(&env.GetRuntime(), "/dc-1/USER_0");
- ls = env.GetClient().Ls("/dc-1/USER_0");
- NTestLs::IsDoesNotExist(ls); //root TSS deleted
- }
- }
-}
-
-void CreateTableInsideAndAlterTable(TTestEnvWithPoolsSupport& env) {
- ui64 rootSchemeShard = Tests::ChangeStateStorage(Tests::SchemeRoot, 1);
- auto storagePool = env.CreatePoolsForTenant("USER_0");
- const ui32 triesNum = 3;
- TVector<ui64> schemeshards(triesNum, 0);
- for (ui32 x = 0; x < triesNum; ++x) {
- {
- auto subdomain_0 = GetSubDomainDeclareSetting("USER_0");
- subdomain_0.SetExternalHive(true);
- UNIT_ASSERT_VALUES_EQUAL(NMsgBusProxy::MSTATUS_OK, env.GetClient().CreateExtSubdomain("/dc-1", subdomain_0));
-
- auto ls = env.GetClient().Ls("/dc-1/USER_0");
- NTestLs::IsUnavailable(ls); //root TSS not ready yet
-
- ls = env.GetClient().Ls("/dc-1");
- NTestLs::ChildrenCount(ls, 1);
+
+ env.GetClient().RefreshPathCache(&env.GetRuntime(), "/dc-1/USER_0");
+ ls = env.GetClient().Ls("/dc-1/USER_0");
+ NTestLs::IsDoesNotExist(ls); //root TSS deleted
+ }
+ }
+}
+
+void CreateTableInsideAndAlterTable(TTestEnvWithPoolsSupport& env) {
+ ui64 rootSchemeShard = Tests::ChangeStateStorage(Tests::SchemeRoot, 1);
+ auto storagePool = env.CreatePoolsForTenant("USER_0");
+ const ui32 triesNum = 3;
+ TVector<ui64> schemeshards(triesNum, 0);
+ for (ui32 x = 0; x < triesNum; ++x) {
+ {
+ auto subdomain_0 = GetSubDomainDeclareSetting("USER_0");
+ subdomain_0.SetExternalHive(true);
+ UNIT_ASSERT_VALUES_EQUAL(NMsgBusProxy::MSTATUS_OK, env.GetClient().CreateExtSubdomain("/dc-1", subdomain_0));
+
+ auto ls = env.GetClient().Ls("/dc-1/USER_0");
+ NTestLs::IsUnavailable(ls); //root TSS not ready yet
+
+ ls = env.GetClient().Ls("/dc-1");
+ NTestLs::ChildrenCount(ls, 1);
NTestLs::HasChild(ls, "USER_0", NKikimrSchemeOp::EPathTypeExtSubDomain);
- }
-
- env.GetTenants().Run("/dc-1/USER_0");
-
- {
- auto subdomain = GetSubDomainDefaultSetting("USER_0", storagePool);
- subdomain.SetExternalHive(true);
- subdomain.SetExternalSchemeShard(true);
- UNIT_ASSERT_VALUES_EQUAL(NMsgBusProxy::MSTATUS_OK, env.GetClient().AlterExtSubdomain("/dc-1", subdomain));
-
- auto ls = env.GetClient().Ls("/dc-1/USER_0");
- NTestLs::IsExtSubdomain(ls); //root TSS ready
- auto ver = NTestLs::ExtractPathVersion(ls);
- UNIT_ASSERT_VALUES_UNEQUAL(ver.OwnerId, rootSchemeShard);
- schemeshards[x] = ver.OwnerId;
- if (x) {
- UNIT_ASSERT_VALUES_UNEQUAL(schemeshards[x], schemeshards[x-1]);
- }
- UNIT_ASSERT_VALUES_EQUAL(ver.PathId, 1);
- UNIT_ASSERT_VALUES_EQUAL(ver.Version, 4);
- }
-
- {
- auto tableDesc = GetTableSimpleDescription("SimpleTable");
- UNIT_ASSERT_VALUES_EQUAL(env.GetClient().CreateTable("/dc-1/USER_0", tableDesc),
- NMsgBusProxy::MSTATUS_OK);
-
- env.GetClient().RefreshPathCache(&env.GetRuntime(), "/dc-1/USER_0/SimpleTable");
- auto ls = env.GetClient().Ls("/dc-1/USER_0/SimpleTable");
+ }
+
+ env.GetTenants().Run("/dc-1/USER_0");
+
+ {
+ auto subdomain = GetSubDomainDefaultSetting("USER_0", storagePool);
+ subdomain.SetExternalHive(true);
+ subdomain.SetExternalSchemeShard(true);
+ UNIT_ASSERT_VALUES_EQUAL(NMsgBusProxy::MSTATUS_OK, env.GetClient().AlterExtSubdomain("/dc-1", subdomain));
+
+ auto ls = env.GetClient().Ls("/dc-1/USER_0");
+ NTestLs::IsExtSubdomain(ls); //root TSS ready
+ auto ver = NTestLs::ExtractPathVersion(ls);
+ UNIT_ASSERT_VALUES_UNEQUAL(ver.OwnerId, rootSchemeShard);
+ schemeshards[x] = ver.OwnerId;
+ if (x) {
+ UNIT_ASSERT_VALUES_UNEQUAL(schemeshards[x], schemeshards[x-1]);
+ }
+ UNIT_ASSERT_VALUES_EQUAL(ver.PathId, 1);
+ UNIT_ASSERT_VALUES_EQUAL(ver.Version, 4);
+ }
+
+ {
+ auto tableDesc = GetTableSimpleDescription("SimpleTable");
+ UNIT_ASSERT_VALUES_EQUAL(env.GetClient().CreateTable("/dc-1/USER_0", tableDesc),
+ NMsgBusProxy::MSTATUS_OK);
+
+ env.GetClient().RefreshPathCache(&env.GetRuntime(), "/dc-1/USER_0/SimpleTable");
+ auto ls = env.GetClient().Ls("/dc-1/USER_0/SimpleTable");
NTestLs::PathType(ls, NKikimrSchemeOp::EPathTypeTable);
- auto ver = NTestLs::ExtractPathVersion(ls);
- UNIT_ASSERT_VALUES_EQUAL(ver.OwnerId, schemeshards[x]);
- UNIT_ASSERT_VALUES_EQUAL(ver.PathId, 2);
- UNIT_ASSERT_VALUES_EQUAL(ver.Version, 3);
-
+ auto ver = NTestLs::ExtractPathVersion(ls);
+ UNIT_ASSERT_VALUES_EQUAL(ver.OwnerId, schemeshards[x]);
+ UNIT_ASSERT_VALUES_EQUAL(ver.PathId, 2);
+ UNIT_ASSERT_VALUES_EQUAL(ver.Version, 3);
+
NKikimrSchemeOp::TTableDescription description = NTestLs::ExtractTableDescription(ls);
-
- description.ClearColumns();
- description.ClearKeyColumnIds();
- description.ClearKeyColumnNames();
- description.ClearSplitBoundary();
- description.ClearTableIndexes();
+
+ description.ClearColumns();
+ description.ClearKeyColumnIds();
+ description.ClearKeyColumnNames();
+ description.ClearSplitBoundary();
+ description.ClearTableIndexes();
description.MutablePartitionConfig()->SetFollowerCount(1);
-
- UNIT_ASSERT_VALUES_EQUAL(env.GetClient().AlterTable("/dc-1/USER_0", description),
- NMsgBusProxy::MSTATUS_OK);
- }
- {
- env.GetClient().RefreshPathCache(&env.GetRuntime(), "/dc-1/USER_0/SimpleTable");
- auto ls = env.GetClient().Ls("/dc-1/USER_0/SimpleTable");
+
+ UNIT_ASSERT_VALUES_EQUAL(env.GetClient().AlterTable("/dc-1/USER_0", description),
+ NMsgBusProxy::MSTATUS_OK);
+ }
+ {
+ env.GetClient().RefreshPathCache(&env.GetRuntime(), "/dc-1/USER_0/SimpleTable");
+ auto ls = env.GetClient().Ls("/dc-1/USER_0/SimpleTable");
NKikimrSchemeOp::TTableDescription description = NTestLs::ExtractTableDescription(ls);
UNIT_ASSERT_VALUES_EQUAL(description.GetPartitionConfig().GetFollowerCount(), 1);
- }
-
- env.GetTenants().Stop();
-
+ }
+
+ env.GetTenants().Stop();
+
UNIT_ASSERT_VALUES_EQUAL(NMsgBusProxy::MSTATUS_OK, env.GetClient().ForceDeleteSubdomain("/dc-1", "USER_0"));
-
- {
- auto ls = env.GetClient().Ls("/dc-1");
- NTestLs::NoChildren(ls);
- auto ver = NTestLs::ExtractPathVersion(ls);
- UNIT_ASSERT_VALUES_EQUAL(ver.OwnerId, rootSchemeShard);
- UNIT_ASSERT_VALUES_EQUAL(ver.PathId, 1);
+
+ {
+ auto ls = env.GetClient().Ls("/dc-1");
+ NTestLs::NoChildren(ls);
+ auto ver = NTestLs::ExtractPathVersion(ls);
+ UNIT_ASSERT_VALUES_EQUAL(ver.OwnerId, rootSchemeShard);
+ UNIT_ASSERT_VALUES_EQUAL(ver.PathId, 1);
UNIT_ASSERT_VALUES_EQUAL(ver.Version, 7 + x * 4);
-
- env.GetClient().RefreshPathCache(&env.GetRuntime(), "/dc-1/USER_0");
- ls = env.GetClient().Ls("/dc-1/USER_0");
- NTestLs::IsDoesNotExist(ls); //root TSS deleted
- }
- }
-}
-
+
+ env.GetClient().RefreshPathCache(&env.GetRuntime(), "/dc-1/USER_0");
+ ls = env.GetClient().Ls("/dc-1/USER_0");
+ NTestLs::IsDoesNotExist(ls); //root TSS deleted
+ }
+ }
+}
+
void CreateTableInsideAndAlterDomainAndTable(TTestEnvWithPoolsSupport& env) {
ui64 rootSchemeShard = Tests::ChangeStateStorage(Tests::SchemeRoot, 1);
@@ -619,15 +619,15 @@ void CreateTableInsideAndAlterDomainAndTable(TTestEnvWithPoolsSupport& env) {
}
}
-void GenericCases(TTestEnvWithPoolsSupport& env) {
+void GenericCases(TTestEnvWithPoolsSupport& env) {
UNIT_ASSERT_VALUES_EQUAL("/dc-1", env.GetRoot());
UNIT_ASSERT_VALUES_EQUAL(NMsgBusProxy::MSTATUS_OK,
env.GetClient().CreateExtSubdomain("/dc-1", GetSubDomainDeclareSetting("USER_0")));
env.GetTenants().Run("/dc-1/USER_0");
- auto storagePools = env.CreatePoolsForTenant("USER_0");
- auto alter = GetSubDomainDefaultSetting("USER_0", storagePools);
+ auto storagePools = env.CreatePoolsForTenant("USER_0");
+ auto alter = GetSubDomainDefaultSetting("USER_0", storagePools);
alter.SetExternalSchemeShard(true);
UNIT_ASSERT_VALUES_EQUAL(NMsgBusProxy::MSTATUS_OK,
env.GetClient().AlterExtSubdomain("/dc-1", alter, WaitTimeOut));
@@ -710,9 +710,9 @@ Y_UNIT_TEST_SUITE(TExtSubDomainTest) {
DeclareAndDrop(env);
}
- Y_UNIT_TEST(DeclareAndDefineWithoutNodes) {
+ Y_UNIT_TEST(DeclareAndDefineWithoutNodes) {
TTestEnvWithPoolsSupport env(1, 0, 2);
- DeclareAndDefineWithoutNodes(env);
+ DeclareAndDefineWithoutNodes(env);
}
Y_UNIT_TEST(DeclareAndDefineWithNodes) {
diff --git a/ydb/core/tx/tx_proxy/proxy_impl.cpp b/ydb/core/tx/tx_proxy/proxy_impl.cpp
index f68c5b03d06..20dc8cce176 100644
--- a/ydb/core/tx/tx_proxy/proxy_impl.cpp
+++ b/ydb/core/tx/tx_proxy/proxy_impl.cpp
@@ -183,12 +183,12 @@ class TTxProxy : public TActorBootstrapped<TTxProxy> {
static NTabletPipe::TClientConfig InitPipeClientConfig() {
NTabletPipe::TClientConfig config;
- config.RetryPolicy = {
- .RetryLimitCount = 3,
- .MinRetryTime = TDuration::MilliSeconds(100),
- .MaxRetryTime = TDuration::Seconds(1),
- .BackoffMultiplier = 5,
- };
+ config.RetryPolicy = {
+ .RetryLimitCount = 3,
+ .MinRetryTime = TDuration::MilliSeconds(100),
+ .MaxRetryTime = TDuration::Seconds(1),
+ .BackoffMultiplier = 5,
+ };
return config;
}
@@ -407,20 +407,20 @@ class TTxProxy : public TActorBootstrapped<TTxProxy> {
ctx.Send(reqId, new TEvTxProxyReq::TEvNavigateScheme(ev));
}
- void Handle(TEvTxUserProxy::TEvInvalidateTable::TPtr &ev, const TActorContext &ctx) {
+ void Handle(TEvTxUserProxy::TEvInvalidateTable::TPtr &ev, const TActorContext &ctx) {
LOG_DEBUG_S(ctx, NKikimrServices::TX_PROXY,
"actor# " << SelfId() <<
" HANDLE EvInvalidateTable");
ctx.Send(Services.SchemeCache, new TEvTxProxySchemeCache::TEvInvalidateTable(TTableId(ev.Get()->Get()->Record.GetSchemeShardId(), ev.Get()->Get()->Record.GetTableId()), ev.Get()->Sender));
- }
-
- void Handle(TEvTxProxySchemeCache::TEvInvalidateTableResult::TPtr &ev, const TActorContext &ctx) {
+ }
+
+ void Handle(TEvTxProxySchemeCache::TEvInvalidateTableResult::TPtr &ev, const TActorContext &ctx) {
LOG_DEBUG_S(ctx, NKikimrServices::TX_PROXY,
"actor# " << SelfId() <<
" HANDLE EvInvalidateTableResult");
- ctx.Send(ev.Get()->Get()->Sender, new TEvTxUserProxy::TEvInvalidateTableResult);
- }
-
+ ctx.Send(ev.Get()->Get()->Sender, new TEvTxUserProxy::TEvInvalidateTableResult);
+ }
+
public:
TTxProxy(const TVector<ui64> &txAllocators)
: PipeClientCache(NTabletPipe::CreateUnboundedClientCache(GetPipeClientConfig()))
@@ -466,7 +466,7 @@ public:
HFunc(TEvTxUserProxy::TEvNavigate, Handle);
HFunc(TEvTxUserProxy::TEvProposeTransaction, Handle);
- HFunc(TEvTxUserProxy::TEvInvalidateTable, Handle);
+ HFunc(TEvTxUserProxy::TEvInvalidateTable, Handle);
HFunc(TEvTxProxySchemeCache::TEvInvalidateTableResult, Handle);
HFunc(TEvTxUserProxy::TEvProposeKqpTransaction, Handle);
diff --git a/ydb/core/tx/tx_proxy/proxy_ut.cpp b/ydb/core/tx/tx_proxy/proxy_ut.cpp
index c324ef369af..eba78928c5a 100644
--- a/ydb/core/tx/tx_proxy/proxy_ut.cpp
+++ b/ydb/core/tx/tx_proxy/proxy_ut.cpp
@@ -62,7 +62,7 @@ Y_UNIT_TEST_SUITE(TSubDomainTest) {
TTestEnv env;
{
- auto subdomain = GetSubDomainDeclareSetting("USER_0", env.GetPools());
+ auto subdomain = GetSubDomainDeclareSetting("USER_0", env.GetPools());
UNIT_ASSERT_VALUES_EQUAL(NMsgBusProxy::MSTATUS_OK, env.GetClient().CreateSubdomain("/dc-1", subdomain));
}
@@ -87,7 +87,7 @@ Y_UNIT_TEST_SUITE(TSubDomainTest) {
TTestEnv env;
{
- auto subdomain = GetSubDomainDeclareSetting("USER_0", env.GetPools());
+ auto subdomain = GetSubDomainDeclareSetting("USER_0", env.GetPools());
UNIT_ASSERT_VALUES_EQUAL(NMsgBusProxy::MSTATUS_OK, env.GetClient().CreateSubdomain("/dc-1", subdomain));
}
@@ -117,7 +117,7 @@ Y_UNIT_TEST_SUITE(TSubDomainTest) {
ui64 owner = THash<TString>()("CreateTablet");
ui64 index = 1;
TAutoPtr<NMsgBusProxy::TBusResponse> resp = env.GetClient().HiveCreateTablet(
- env.GetSettings().Domain, owner, index, TTabletTypes::TX_DUMMY, {}, {});
+ env.GetSettings().Domain, owner, index, TTabletTypes::TX_DUMMY, {}, {});
NKikimrClient::TResponse& record = resp->Record;
UNIT_ASSERT_VALUES_EQUAL(record.CreateTabletResultSize(), 1);
@@ -143,7 +143,7 @@ Y_UNIT_TEST_SUITE(TSubDomainTest) {
allowed_domains.push_back(TSubDomainKey(999, 999));
TAutoPtr<NMsgBusProxy::TBusResponse> resp = env.GetClient().HiveCreateTablet(
- env.GetSettings().Domain, owner, index, TTabletTypes::TX_DUMMY, {}, allowed_domains);
+ env.GetSettings().Domain, owner, index, TTabletTypes::TX_DUMMY, {}, allowed_domains);
NKikimrClient::TResponse& record = resp->Record;
UNIT_ASSERT_VALUES_EQUAL(record.CreateTabletResultSize(), 1);
@@ -199,7 +199,7 @@ Y_UNIT_TEST_SUITE(TSubDomainTest) {
Y_UNIT_TEST(StartAndStopTenanNode) {
TTestEnv env(1, 1);
- auto subdomain_0 = GetSubDomainDeclareSetting("USER_0", env.GetPools());
+ auto subdomain_0 = GetSubDomainDeclareSetting("USER_0", env.GetPools());
UNIT_ASSERT_VALUES_EQUAL(NMsgBusProxy::MSTATUS_OK, env.GetClient().CreateSubdomain("/dc-1", subdomain_0));
env.GetTenants().Run("/dc-1/USER_0");
@@ -209,7 +209,7 @@ Y_UNIT_TEST_SUITE(TSubDomainTest) {
Y_UNIT_TEST(CreateTableInsideAndForceDeleteSubDomain) {
TTestEnv env(1, 1);
- auto subdomain_0 = GetSubDomainDeclareSetting("USER_0", env.GetPools());
+ auto subdomain_0 = GetSubDomainDeclareSetting("USER_0", env.GetPools());
UNIT_ASSERT_VALUES_EQUAL(NMsgBusProxy::MSTATUS_OK, env.GetClient().CreateSubdomain("/dc-1", subdomain_0));
{
@@ -251,7 +251,7 @@ Y_UNIT_TEST_SUITE(TSubDomainTest) {
Y_UNIT_TEST(CreateTableInsidetThenStopTenantAndForceDeleteSubDomain) {
TTestEnv env(1, 1);
- auto subdomain_0 = GetSubDomainDeclareSetting("USER_0", env.GetPools());
+ auto subdomain_0 = GetSubDomainDeclareSetting("USER_0", env.GetPools());
UNIT_ASSERT_VALUES_EQUAL(NMsgBusProxy::MSTATUS_OK, env.GetClient().CreateSubdomain("/dc-1", subdomain_0));
{
@@ -305,7 +305,7 @@ Y_UNIT_TEST_SUITE(TSubDomainTest) {
UNIT_ASSERT_VALUES_EQUAL("/dc-1", env.GetRoot());
UNIT_ASSERT_VALUES_EQUAL(NMsgBusProxy::MSTATUS_OK,
- env.GetClient().CreateSubdomain("/dc-1", GetSubDomainDeclareSetting("USER_0", env.GetPools())));
+ env.GetClient().CreateSubdomain("/dc-1", GetSubDomainDeclareSetting("USER_0", env.GetPools())));
env.GetTenants().Run("/dc-1/USER_0");
@@ -329,7 +329,7 @@ Y_UNIT_TEST_SUITE(TSubDomainTest) {
Y_UNIT_TEST(StartTenanNodeAndStopAtDestructor) {
TTestEnv env(1, 1);
- auto subdomain_0 = GetSubDomainDeclareSetting("USER_0", env.GetPools());
+ auto subdomain_0 = GetSubDomainDeclareSetting("USER_0", env.GetPools());
UNIT_ASSERT_VALUES_EQUAL(NMsgBusProxy::MSTATUS_OK, env.GetClient().CreateSubdomain("/dc-1", subdomain_0));
env.GetTenants().Run("/dc-1/USER_0");
@@ -341,7 +341,7 @@ Y_UNIT_TEST_SUITE(TSubDomainTest) {
UNIT_ASSERT_VALUES_EQUAL("/dc-1", env.GetRoot());
UNIT_ASSERT_VALUES_EQUAL(NMsgBusProxy::MSTATUS_OK,
- env.GetClient().CreateSubdomain("/dc-1", GetSubDomainDeclareSetting("USER_0", env.GetPools())));
+ env.GetClient().CreateSubdomain("/dc-1", GetSubDomainDeclareSetting("USER_0", env.GetPools())));
{
auto ls = env.GetClient().Ls("/dc-1/USER_0");
@@ -384,13 +384,13 @@ Y_UNIT_TEST_SUITE(TSubDomainTest) {
UNIT_ASSERT_VALUES_EQUAL("/dc-1", env.GetRoot());
UNIT_ASSERT_VALUES_EQUAL(NMsgBusProxy::MSTATUS_OK,
- env.GetClient().CreateSubdomain("/dc-1", GetSubDomainDeclareSetting("USER_0", env.GetPools())));
+ env.GetClient().CreateSubdomain("/dc-1", GetSubDomainDeclareSetting("USER_0", env.GetPools())));
UNIT_ASSERT_VALUES_EQUAL(NMsgBusProxy::MSTATUS_INPROGRESS,
env.GetClient().AlterSubdomain("/dc-1", GetSubDomainDefaultSetting("USER_0"), TDuration::MilliSeconds(500)));
env.GetTenants().Run("/dc-1/USER_0");
UNIT_ASSERT_VALUES_EQUAL(NMsgBusProxy::MSTATUS_OK,
- env.GetClient().CreateSubdomain("/dc-1", GetSubDomainDeclareSetting("USER_1", env.GetPools())));
+ env.GetClient().CreateSubdomain("/dc-1", GetSubDomainDeclareSetting("USER_1", env.GetPools())));
UNIT_ASSERT_VALUES_EQUAL(NMsgBusProxy::MSTATUS_INPROGRESS,
env.GetClient().AlterSubdomain("/dc-1", GetSubDomainDefaultSetting("USER_1"), TDuration::MilliSeconds(500)));
env.GetTenants().Run("/dc-1/USER_1");
@@ -474,7 +474,7 @@ Y_UNIT_TEST_SUITE(TSubDomainTest) {
UNIT_ASSERT_VALUES_EQUAL("/dc-1", env.GetRoot());
UNIT_ASSERT_VALUES_EQUAL(NMsgBusProxy::MSTATUS_OK,
- env.GetClient().CreateSubdomain("/dc-1", GetSubDomainDeclareSetting("USER_0", env.GetPools())));
+ env.GetClient().CreateSubdomain("/dc-1", GetSubDomainDeclareSetting("USER_0", env.GetPools())));
UNIT_ASSERT_VALUES_EQUAL(NMsgBusProxy::MSTATUS_INPROGRESS,
env.GetClient().AlterSubdomain("/dc-1", GetSubDomainDefaultSetting("USER_0"), TDuration::MilliSeconds(500)));
@@ -553,7 +553,7 @@ Y_UNIT_TEST_SUITE(TSubDomainTest) {
UNIT_ASSERT_VALUES_EQUAL("/dc-1", env.GetRoot());
UNIT_ASSERT_VALUES_EQUAL(NMsgBusProxy::MSTATUS_OK,
- env.GetClient().CreateSubdomain("/dc-1", GetSubDomainDeclareSetting("USER_0", env.GetPools())));
+ env.GetClient().CreateSubdomain("/dc-1", GetSubDomainDeclareSetting("USER_0", env.GetPools())));
UNIT_ASSERT_VALUES_EQUAL(NMsgBusProxy::MSTATUS_INPROGRESS,
env.GetClient().AlterSubdomain("/dc-1", GetSubDomainDefaultSetting("USER_0"), TDuration::MilliSeconds(500)));
@@ -593,7 +593,7 @@ Y_UNIT_TEST_SUITE(TSubDomainTest) {
UNIT_ASSERT_VALUES_EQUAL("/dc-1", env.GetRoot());
UNIT_ASSERT_VALUES_EQUAL(NMsgBusProxy::MSTATUS_OK,
- env.GetClient().CreateSubdomain("/dc-1", GetSubDomainDeclareSetting("USER_0", env.GetPools())));
+ env.GetClient().CreateSubdomain("/dc-1", GetSubDomainDeclareSetting("USER_0", env.GetPools())));
UNIT_ASSERT_VALUES_EQUAL(NMsgBusProxy::MSTATUS_INPROGRESS,
env.GetClient().AlterSubdomain("/dc-1", GetSubDomainDefaultSetting("USER_0"), TDuration::MilliSeconds(500)));
@@ -634,7 +634,7 @@ Y_UNIT_TEST_SUITE(TSubDomainTest) {
}
{
- auto subdomain = GetSubDomainDeclareSetting("USER_0", env.GetPools());
+ auto subdomain = GetSubDomainDeclareSetting("USER_0", env.GetPools());
UNIT_ASSERT_VALUES_EQUAL(NMsgBusProxy::MSTATUS_OK, env.GetClient().CreateSubdomain("/dc-1", subdomain));
}
@@ -707,7 +707,7 @@ Y_UNIT_TEST_SUITE(TSubDomainTest) {
}
{
- auto subdomain = GetSubDomainDeclareSetting("USER_0", env.GetPools());
+ auto subdomain = GetSubDomainDeclareSetting("USER_0", env.GetPools());
UNIT_ASSERT_VALUES_EQUAL(NMsgBusProxy::MSTATUS_OK, env.GetClient().CreateSubdomain("/dc-1", subdomain));
}
@@ -762,7 +762,7 @@ Y_UNIT_TEST_SUITE(TSubDomainTest) {
UNIT_ASSERT_VALUES_EQUAL("/dc-1", env.GetRoot());
UNIT_ASSERT_VALUES_EQUAL(NMsgBusProxy::MSTATUS_OK,
- env.GetClient().CreateSubdomain("/dc-1", GetSubDomainDeclareSetting("USER_0", env.GetPools())));
+ env.GetClient().CreateSubdomain("/dc-1", GetSubDomainDeclareSetting("USER_0", env.GetPools())));
UNIT_ASSERT_VALUES_EQUAL(NMsgBusProxy::MSTATUS_OK,
env.GetClient().AlterUserAttributes("/dc-1", "USER_0", {{"AttrA1", "ValA1"}}));
@@ -779,7 +779,7 @@ Y_UNIT_TEST_SUITE(TSubDomainTest) {
UNIT_ASSERT_VALUES_EQUAL("/dc-1", env.GetRoot());
UNIT_ASSERT_VALUES_EQUAL(NMsgBusProxy::MSTATUS_OK,
- env.GetClient().CreateSubdomain("/dc-1", GetSubDomainDeclareSetting("USER_0", env.GetPools())));
+ env.GetClient().CreateSubdomain("/dc-1", GetSubDomainDeclareSetting("USER_0", env.GetPools())));
UNIT_ASSERT_VALUES_EQUAL(NMsgBusProxy::MSTATUS_OK,
env.GetClient().AlterUserAttributes("/dc-1", "USER_0", {{"AttrA1", "ValA1"}}));
@@ -839,7 +839,7 @@ Y_UNIT_TEST_SUITE(TSubDomainTest) {
UNIT_ASSERT_VALUES_EQUAL("/dc-1", env.GetRoot());
UNIT_ASSERT_VALUES_EQUAL(NMsgBusProxy::MSTATUS_OK,
- env.GetClient().CreateSubdomain("/dc-1", GetSubDomainDeclareSetting("USER_0", env.GetPools())));
+ env.GetClient().CreateSubdomain("/dc-1", GetSubDomainDeclareSetting("USER_0", env.GetPools())));
env.GetTenants().Run("/dc-1/USER_0", 1);
UNIT_ASSERT_VALUES_EQUAL(NMsgBusProxy::MSTATUS_OK,
env.GetClient().AlterSubdomain("/dc-1", GetSubDomainDefaultSetting("USER_0")));
@@ -847,7 +847,7 @@ Y_UNIT_TEST_SUITE(TSubDomainTest) {
env.GetClient().RefreshPathCache(&env.GetRuntime(), "/dc-1/USER_0");
UNIT_ASSERT_VALUES_EQUAL(NMsgBusProxy::MSTATUS_OK,
- env.GetClient().CreateSubdomain("/dc-1", GetSubDomainDeclareSetting("USER_1", env.GetPools())));
+ env.GetClient().CreateSubdomain("/dc-1", GetSubDomainDeclareSetting("USER_1", env.GetPools())));
env.GetTenants().Run("/dc-1/USER_1", 1);
UNIT_ASSERT_VALUES_EQUAL(NMsgBusProxy::MSTATUS_OK,
env.GetClient().AlterSubdomain("/dc-1", GetSubDomainDefaultSetting("USER_1")));
@@ -890,7 +890,7 @@ Y_UNIT_TEST_SUITE(TSubDomainTest) {
UNIT_ASSERT_VALUES_EQUAL("/dc-1", env.GetRoot());
UNIT_ASSERT_VALUES_EQUAL(NMsgBusProxy::MSTATUS_OK,
- env.GetClient().CreateSubdomain("/dc-1", GetSubDomainDeclareSetting("USER_0", env.GetPools())));
+ env.GetClient().CreateSubdomain("/dc-1", GetSubDomainDeclareSetting("USER_0", env.GetPools())));
env.GetTenants().Run("/dc-1/USER_0", 1);
UNIT_ASSERT_VALUES_EQUAL(NMsgBusProxy::MSTATUS_OK,
env.GetClient().AlterSubdomain("/dc-1", GetSubDomainDefaultSetting("USER_0")));
@@ -898,7 +898,7 @@ Y_UNIT_TEST_SUITE(TSubDomainTest) {
env.GetClient().RefreshPathCache(&env.GetRuntime(), "/dc-1/USER_0");
UNIT_ASSERT_VALUES_EQUAL(NMsgBusProxy::MSTATUS_OK,
- env.GetClient().CreateSubdomain("/dc-1", GetSubDomainDeclareSetting("USER_1", env.GetPools())));
+ env.GetClient().CreateSubdomain("/dc-1", GetSubDomainDeclareSetting("USER_1", env.GetPools())));
env.GetTenants().Run("/dc-1/USER_1", 1);
UNIT_ASSERT_VALUES_EQUAL(NMsgBusProxy::MSTATUS_OK,
env.GetClient().AlterSubdomain("/dc-1", GetSubDomainDefaultSetting("USER_1")));
diff --git a/ydb/core/tx/tx_proxy/proxy_ut_helpers.cpp b/ydb/core/tx/tx_proxy/proxy_ut_helpers.cpp
index cff29805d40..a9becc80d7d 100644
--- a/ydb/core/tx/tx_proxy/proxy_ut_helpers.cpp
+++ b/ydb/core/tx/tx_proxy/proxy_ut_helpers.cpp
@@ -215,17 +215,17 @@ TVector<NKikimrSchemeOp::TTablePartition> ExtractTablePartitions(const TAutoPtr<
}
NKikimrSchemeOp::TTableDescription ExtractTableDescription(const TAutoPtr<NMsgBusProxy::TBusResponse>& resp) {
- UNIT_ASSERT(resp.Get());
- auto& record = resp->Record;
- UNIT_ASSERT_VALUES_EQUAL(record.GetStatus(), NMsgBusProxy::MSTATUS_OK);
+ UNIT_ASSERT(resp.Get());
+ auto& record = resp->Record;
+ UNIT_ASSERT_VALUES_EQUAL(record.GetStatus(), NMsgBusProxy::MSTATUS_OK);
UNIT_ASSERT_VALUES_EQUAL(record.GetSchemeStatus(), NKikimrScheme::StatusSuccess);
- auto& descr = record.GetPathDescription();
- auto actualType = descr.GetSelf().GetPathType();
+ auto& descr = record.GetPathDescription();
+ auto actualType = descr.GetSelf().GetPathType();
UNIT_ASSERT_VALUES_EQUAL(actualType, NKikimrSchemeOp::EPathTypeTable);
- UNIT_ASSERT(descr.HasTable());
- return descr.GetTable();
-}
-
+ UNIT_ASSERT(descr.HasTable());
+ return descr.GetTable();
+}
+
TString CheckStatus(const TAutoPtr<NMsgBusProxy::TBusResponse>& resp, NKikimrScheme::EStatus schemeStatus) {
UNIT_ASSERT(resp.Get());
auto& record = resp->Record;
@@ -329,12 +329,12 @@ TString IsDoesNotExist(const TAutoPtr<NMsgBusProxy::TBusResponse> &resp) {
namespace NHelpers {
-TChannelBind GetChannelBind(const TString& storagePool) {
- TChannelBind bind;
- bind.SetStoragePoolName(storagePool);
- return bind;
-}
-
+TChannelBind GetChannelBind(const TString& storagePool) {
+ TChannelBind bind;
+ bind.SetStoragePoolName(storagePool);
+ return bind;
+}
+
ui64 CreateSubDomainAndTabletInside(TBaseTestEnv &env, const TString &name, ui64 shard_index, const TStoragePools &pools) {
const ui64 owner = THash<TString>()(name);
@@ -342,16 +342,16 @@ ui64 CreateSubDomainAndTabletInside(TBaseTestEnv &env, const TString &name, ui64
TChannelsBindings channelBindings;
if (pools) {
auto poolIt = pools.begin();
- channelBindings.emplace_back(GetChannelBind(poolIt->GetName()));
+ channelBindings.emplace_back(GetChannelBind(poolIt->GetName()));
if (pools.size() > 1) {
++poolIt;
}
- channelBindings.emplace_back(GetChannelBind(poolIt->GetName()));
+ channelBindings.emplace_back(GetChannelBind(poolIt->GetName()));
if (pools.size() > 2) {
++poolIt;
- channelBindings.emplace_back(GetChannelBind(poolIt->GetName()));
+ channelBindings.emplace_back(GetChannelBind(poolIt->GetName()));
}
}
@@ -365,7 +365,7 @@ ui64 CreateSubDomainAndTabletInside(TBaseTestEnv &env, const TString &name, ui64
TAutoPtr<NMsgBusProxy::TBusResponse> resp = env.GetClient().HiveCreateTablet(
env.GetSettings().Domain,
owner, shard_index,
- TTabletTypes::TX_DUMMY,
+ TTabletTypes::TX_DUMMY,
{},
{key},
channelBindings);
diff --git a/ydb/core/tx/tx_proxy/proxy_ut_helpers.h b/ydb/core/tx/tx_proxy/proxy_ut_helpers.h
index 8d5513e4ae5..846b0cf568c 100644
--- a/ydb/core/tx/tx_proxy/proxy_ut_helpers.h
+++ b/ydb/core/tx/tx_proxy/proxy_ut_helpers.h
@@ -66,7 +66,7 @@ protected:
if (GetSettings().SupportsRedirect && Tests::IsServerRedirected())
return;
- GetRuntime().SetLogPriority(NKikimrServices::FLAT_TX_SCHEMESHARD, NActors::NLog::PRI_DEBUG);
+ GetRuntime().SetLogPriority(NKikimrServices::FLAT_TX_SCHEMESHARD, NActors::NLog::PRI_DEBUG);
GetRuntime().SetLogPriority(NKikimrServices::HIVE, NActors::NLog::PRI_NOTICE);
GetRuntime().SetLogPriority(NKikimrServices::LOCAL, NActors::NLog::PRI_NOTICE);
@@ -110,14 +110,14 @@ public:
SetLogging();
InitRoot();
}
-
- TStoragePools GetPools() {
- TStoragePools pools;
- for (const auto& [kind, pool] : GetSettings().StoragePoolTypes) {
- pools.emplace_back(pool.GetName(), kind);
- }
- return pools;
- }
+
+ TStoragePools GetPools() {
+ TStoragePools pools;
+ for (const auto& [kind, pool] : GetSettings().StoragePoolTypes) {
+ pools.emplace_back(pool.GetName(), kind);
+ }
+ return pools;
+ }
};
void Print(const TAutoPtr<NMsgBusProxy::TBusResponse>& resp);
@@ -153,8 +153,8 @@ namespace NTestLs {
using TPathVersion = Tests::TClient::TPathVersion;
TPathVersion ExtractPathVersion(const TAutoPtr<NMsgBusProxy::TBusResponse>& resp);
-
- TVector<ui64> ExtractTableShards(const TAutoPtr<NMsgBusProxy::TBusResponse>& resp);
+
+ TVector<ui64> ExtractTableShards(const TAutoPtr<NMsgBusProxy::TBusResponse>& resp);
}
namespace NHelpers {
diff --git a/ydb/core/tx/tx_proxy/schemereq.cpp b/ydb/core/tx/tx_proxy/schemereq.cpp
index 246576c2472..923fe381ae6 100644
--- a/ydb/core/tx/tx_proxy/schemereq.cpp
+++ b/ydb/core/tx/tx_proxy/schemereq.cpp
@@ -25,9 +25,9 @@ struct TBaseSchemeReq: public TActorBootstrapped<TDerived> {
using TEvSchemeShardPropose = NSchemeShard::TEvSchemeShard::TEvModifySchemeTransaction;
- const TTxProxyServices Services;
+ const TTxProxyServices Services;
const ui64 TxId;
- THolder<TEvTxProxyReq::TEvSchemeRequest> SchemeRequest;
+ THolder<TEvTxProxyReq::TEvSchemeRequest> SchemeRequest;
TIntrusivePtr<TTxProxyMon> TxProxyMon;
TInstant WallClockStarted;
@@ -41,7 +41,7 @@ struct TBaseSchemeReq: public TActorBootstrapped<TDerived> {
TVector<TString> Path;
bool RequiredRedirect = true;
ui32 RequiredAccess = NACLib::EAccessRights::NoAccess;
-
+
std::optional<NKikimrSchemeOp::TModifyACL> RequiredGrandAccess;
TPathToResolve(NKikimrSchemeOp::EOperationType opType)
@@ -156,7 +156,7 @@ struct TBaseSchemeReq: public TActorBootstrapped<TDerived> {
case NKikimrSchemeOp::ESchemeOpSplitMergeTablePartitions:
Y_FAIL("no implementation for ESchemeOpSplitMergeTablePartitions");
-
+
case NKikimrSchemeOp::ESchemeOpBackup:
return *modifyScheme.MutableBackup()->MutableTableName();
@@ -221,7 +221,7 @@ struct TBaseSchemeReq: public TActorBootstrapped<TDerived> {
case NKikimrSchemeOp::ESchemeOpAlterTableIndex:
return *modifyScheme.MutableAlterTableIndex()->MutableName();
-
+
case NKikimrSchemeOp::ESchemeOpAlterSolomonVolume:
return *modifyScheme.MutableAlterSolomonVolume()->MutableName();
@@ -528,7 +528,7 @@ struct TBaseSchemeReq: public TActorBootstrapped<TDerived> {
toResolve.Path = SplitPath(baseDir);
toResolve.RequiredAccess = NACLib::EAccessRights::NoAccess; // why not?
ResolveForACL.push_back(toResolve);
- break;
+ break;
}
case NKikimrSchemeOp::ESchemeOpAlterTable:
case NKikimrSchemeOp::ESchemeOpDropIndex:
@@ -586,7 +586,7 @@ struct TBaseSchemeReq: public TActorBootstrapped<TDerived> {
toResolve.RequiredAccess = NACLib::EAccessRights::DropDatabase | NACLib::EAccessRights::RemoveSchema;
toResolve.RequiredRedirect = false;
ResolveForACL.push_back(toResolve);
- break;
+ break;
}
case NKikimrSchemeOp::ESchemeOpModifyACL: {
auto toResolve = TPathToResolve(pbModifyScheme.GetOperationType());
@@ -594,7 +594,7 @@ struct TBaseSchemeReq: public TActorBootstrapped<TDerived> {
toResolve.RequiredAccess = NACLib::EAccessRights::GrantAccessRights | accessToUserAttrs;
toResolve.RequiredGrandAccess = pbModifyScheme.GetModifyACL();
ResolveForACL.push_back(toResolve);
- break;
+ break;
}
case NKikimrSchemeOp::ESchemeOpCreateTable: {
auto toResolve = TPathToResolve(pbModifyScheme.GetOperationType());
@@ -676,7 +676,7 @@ struct TBaseSchemeReq: public TActorBootstrapped<TDerived> {
toResolve.Path = workingDir;
toResolve.RequiredAccess = NACLib::EAccessRights::CreateQueue | accessToUserAttrs;
ResolveForACL.push_back(toResolve);
- break;
+ break;
}
case NKikimrSchemeOp::ESchemeOpAlterLogin:
{
@@ -684,7 +684,7 @@ struct TBaseSchemeReq: public TActorBootstrapped<TDerived> {
toResolve.Path = workingDir;
toResolve.RequiredAccess = NACLib::EAccessRights::AlterSchema | accessToUserAttrs;
ResolveForACL.push_back(toResolve);
- break;
+ break;
}
case NKikimrSchemeOp::ESchemeOpCreateTableIndex:
case NKikimrSchemeOp::ESchemeOpDropTableIndex:
@@ -949,7 +949,7 @@ struct TBaseSchemeReq: public TActorBootstrapped<TDerived> {
ReportStatus(TEvTxUserProxy::TResultStatus::ProxyShardNotAvailable, ctx);
return Die(ctx);
}
- }
+ }
void Handle(TEvTabletPipe::TEvClientDestroyed::TPtr &ev, const TActorContext &ctx) {
LOG_DEBUG_S(ctx, NKikimrServices::TX_PROXY, "Actor# " << ctx.SelfID.ToString() << " txid# " << TxId
@@ -965,7 +965,7 @@ struct TBaseSchemeReq: public TActorBootstrapped<TDerived> {
const NKikimrScheme::TEvModifySchemeTransactionResult &record = ev->Get()->Record;
LOG_DEBUG_S(ctx, NKikimrServices::TX_PROXY, "Actor# " << ctx.SelfID.ToString() << " txid# " << TxId
<< " Status " << record.GetStatus() << " HANDLE "<< ev->Get()->ToString());
-
+
TxProxyMon->SchemeRequestLatency->Collect((ctx.Now() - WallClockStarted).MilliSeconds());
switch (record.GetStatus()) {
@@ -1124,7 +1124,7 @@ void TFlatSchemeReq::Bootstrap(const TActorContext &ctx) {
ctx.Send(Services.SchemeCache, new TEvTxProxySchemeCache::TEvNavigateKeySet(resolveRequest));
Become(&TThis::StateWaitResolveWorkingDir);
return;
- }
+ }
ProcessRequest(ctx);
}
@@ -1145,10 +1145,10 @@ void TFlatSchemeReq::ProcessRequest(const TActorContext &ctx) {
LOG_DEBUG_S(ctx, NKikimrServices::TX_PROXY, "Actor# " << ctx.SelfID.ToString() << " txid# " << TxId << " TEvNavigateKeySet requested from SchemeCache");
ctx.Send(Services.SchemeCache, new TEvTxProxySchemeCache::TEvNavigateKeySet(resolveRequest));
- Become(&TThis::StateWaitResolve);
+ Become(&TThis::StateWaitResolve);
return;
-}
-
+}
+
void TFlatSchemeReq::HandleWorkingDir(TEvTxProxySchemeCache::TEvNavigateKeySetResult::TPtr &ev, const TActorContext &ctx) {
LOG_DEBUG_S(ctx, NKikimrServices::TX_PROXY,
"Actor# " << ctx.SelfID.ToString()
@@ -1193,13 +1193,13 @@ void TFlatSchemeReq::HandleWorkingDir(TEvTxProxySchemeCache::TEvNavigateKeySetRe
///
struct TSchemeTransactionalReq : public TBaseSchemeReq<TSchemeTransactionalReq> {
using TBase = TBaseSchemeReq<TSchemeTransactionalReq>;
-
+
void Bootstrap(const TActorContext &ctx);
static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
return NKikimrServices::TActivity::TX_PROXY_SCHEMEREQ;
}
-
+
TSchemeTransactionalReq(const TTxProxyServices &services, ui64 txid, TAutoPtr<TEvTxProxyReq::TEvSchemeRequest> request, const TIntrusivePtr<TTxProxyMon> &txProxyMon)
: TBase(services, txid, request, txProxyMon)
{}
@@ -1212,8 +1212,8 @@ struct TSchemeTransactionalReq : public TBaseSchemeReq<TSchemeTransactionalReq>
switch (ev->GetTypeRewrite()) {
HFunc(TEvTxProxySchemeCache::TEvNavigateKeySetResult, Handle);
}
- }
-
+ }
+
STFUNC(StateWaitPrepare) {
switch (ev->GetTypeRewrite()) {
HFunc(NSchemeShard::TEvSchemeShard::TEvModifySchemeTransactionResult, Handle);
@@ -1241,9 +1241,9 @@ void TSchemeTransactionalReq::Bootstrap(const TActorContext &ctx) {
ReportStatus(TEvTxUserProxy::TEvProposeTransactionStatus::EStatus::NotImplemented, ctx);
TxProxyMon->ResolveKeySetWrongRequest->Inc();
return Die(ctx);
- }
- }
-
+ }
+ }
+
for(auto& scheme: GetModifications()) {
if (!ExtractResolveForACL(scheme)) {
ReportStatus(TEvTxUserProxy::TEvProposeTransactionStatus::EStatus::NotImplemented, ctx);
diff --git a/ydb/core/tx/tx_proxy/storage_tenant_ut.cpp b/ydb/core/tx/tx_proxy/storage_tenant_ut.cpp
index d376da55ab5..c3b8e9921a8 100644
--- a/ydb/core/tx/tx_proxy/storage_tenant_ut.cpp
+++ b/ydb/core/tx/tx_proxy/storage_tenant_ut.cpp
@@ -268,7 +268,7 @@ Y_UNIT_TEST_SUITE(TStorageTenantTest) {
{
UNIT_ASSERT_VALUES_EQUAL(NMsgBusProxy::MSTATUS_OK, env.GetClient().MkDir("/dc-1/USER_0", "dir"));
auto ls = env.GetClient().Ls("/dc-1/USER_0/dir");
- NTestLs::InSubdomain(ls);
+ NTestLs::InSubdomain(ls);
}
{
@@ -285,13 +285,13 @@ Y_UNIT_TEST_SUITE(TStorageTenantTest) {
{
UNIT_ASSERT_VALUES_EQUAL(NMsgBusProxy::MSTATUS_OK, env.GetClient().MkDir("/dc-1/USER_0/dir", "dir_0"));
auto ls = env.GetClient().Ls("/dc-1/USER_0/dir/dir_0");
- NTestLs::InSubdomain(ls);
+ NTestLs::InSubdomain(ls);
}
{
UNIT_ASSERT_VALUES_EQUAL(NMsgBusProxy::MSTATUS_OK, env.GetClient().MkDir("/dc-1/USER_0/dir", "dir_1"));
auto ls = env.GetClient().Ls("/dc-1/USER_0/dir/dir_1");
- NTestLs::InSubdomain(ls);
+ NTestLs::InSubdomain(ls);
}
{
diff --git a/ydb/core/util/metrics.h b/ydb/core/util/metrics.h
index c6dfa6c0bc7..cae931733fa 100644
--- a/ydb/core/util/metrics.h
+++ b/ydb/core/util/metrics.h
@@ -1,462 +1,462 @@
-#pragma once
-#include <array>
-#include <util/datetime/base.h>
+#pragma once
+#include <array>
+#include <util/datetime/base.h>
#include <util/stream/buffer.h>
-#include <cmath>
+#include <cmath>
#include <ydb/core/protos/metrics.pb.h>
-
-namespace std {
-
-template <>
-struct make_signed<double> {
- using type = double;
-};
-
-}
-
-namespace NKikimr {
-namespace NMetrics {
-
-// gauge resource type, supports absolute and delta population
-template <typename ValueType>
-class TGaugeValue {
-public:
- using TType = ValueType;
-
- TGaugeValue(ValueType value = ValueType())
- : Value(value)
- {}
-
+
+namespace std {
+
+template <>
+struct make_signed<double> {
+ using type = double;
+};
+
+}
+
+namespace NKikimr {
+namespace NMetrics {
+
+// gauge resource type, supports absolute and delta population
+template <typename ValueType>
+class TGaugeValue {
+public:
+ using TType = ValueType;
+
+ TGaugeValue(ValueType value = ValueType())
+ : Value(value)
+ {}
+
std::make_signed_t<ValueType> Set(ValueType value) {
std::make_signed_t<ValueType> diff =
static_cast<std::make_signed_t<ValueType>>(value) -
static_cast<std::make_signed_t<ValueType>>(Value);
- Value = value;
- return diff;
- }
-
+ Value = value;
+ return diff;
+ }
+
void Increment(std::make_signed_t<ValueType> value) { Value += value; }
- ValueType GetValue() const { return Value; }
- TGaugeValue operator +(const TGaugeValue& o) const { return TGaugeValue(Value + o.GetValue()); }
- TGaugeValue operator -(const TGaugeValue& o) const { return TGaugeValue(Value - o.GetValue()); }
- constexpr bool IsValueReady() const { return Value != ValueType(); }
- constexpr bool IsValueObsolete(TInstant now = TInstant::Now()) const { Y_UNUSED(now); return false; }
-
-protected:
- ValueType Value;
-};
-
-constexpr TTimeBase<TInstant>::TValue DurationPerSecond = 1000000ull;
-constexpr TTimeBase<TInstant>::TValue DurationPerMinute = DurationPerSecond * 60;
-constexpr TTimeBase<TInstant>::TValue DurationPerHour = DurationPerMinute * 60;
-constexpr TTimeBase<TInstant>::TValue DurationPerDay = DurationPerHour * 24;
-
-// simple RRD time series type
-template <typename ValueType, TTimeBase<TInstant>::TValue DurationToStore = DurationPerDay, int BucketCount = 24>
-class TTimeSeriesValue {
-public:
- using TType = ValueType;
- static constexpr int BUCKET_COUNT = BucketCount;
- static constexpr TTimeBase<TInstant>::TValue BUCKET_DURATION = DurationToStore / BucketCount;
-
- TTimeSeriesValue()
- : Buckets()
- , FirstUpdate()
- , LastUpdate()
- {}
-
- static int TimeToBucket(TInstant time) {
- return (time.GetValue() % DurationToStore) / BUCKET_DURATION;
- }
-
- static TTimeBase<TInstant>::TValue GetBucketSizeFrom(TInstant time) {
- return BUCKET_DURATION - (time.GetValue() % BUCKET_DURATION);
- }
-
- static TTimeBase<TInstant>::TValue GetBucketSizeTo(TInstant time) {
- return time.GetValue() % BUCKET_DURATION;
- }
-
- void Store(ValueType value, TInstant to) {
- int bucketTo = TimeToBucket(to);
- TInstant from;
- if (LastUpdate == TInstant()) {
- LastUpdate = FirstUpdate = to;
- return;
- } else {
+ ValueType GetValue() const { return Value; }
+ TGaugeValue operator +(const TGaugeValue& o) const { return TGaugeValue(Value + o.GetValue()); }
+ TGaugeValue operator -(const TGaugeValue& o) const { return TGaugeValue(Value - o.GetValue()); }
+ constexpr bool IsValueReady() const { return Value != ValueType(); }
+ constexpr bool IsValueObsolete(TInstant now = TInstant::Now()) const { Y_UNUSED(now); return false; }
+
+protected:
+ ValueType Value;
+};
+
+constexpr TTimeBase<TInstant>::TValue DurationPerSecond = 1000000ull;
+constexpr TTimeBase<TInstant>::TValue DurationPerMinute = DurationPerSecond * 60;
+constexpr TTimeBase<TInstant>::TValue DurationPerHour = DurationPerMinute * 60;
+constexpr TTimeBase<TInstant>::TValue DurationPerDay = DurationPerHour * 24;
+
+// simple RRD time series type
+template <typename ValueType, TTimeBase<TInstant>::TValue DurationToStore = DurationPerDay, int BucketCount = 24>
+class TTimeSeriesValue {
+public:
+ using TType = ValueType;
+ static constexpr int BUCKET_COUNT = BucketCount;
+ static constexpr TTimeBase<TInstant>::TValue BUCKET_DURATION = DurationToStore / BucketCount;
+
+ TTimeSeriesValue()
+ : Buckets()
+ , FirstUpdate()
+ , LastUpdate()
+ {}
+
+ static int TimeToBucket(TInstant time) {
+ return (time.GetValue() % DurationToStore) / BUCKET_DURATION;
+ }
+
+ static TTimeBase<TInstant>::TValue GetBucketSizeFrom(TInstant time) {
+ return BUCKET_DURATION - (time.GetValue() % BUCKET_DURATION);
+ }
+
+ static TTimeBase<TInstant>::TValue GetBucketSizeTo(TInstant time) {
+ return time.GetValue() % BUCKET_DURATION;
+ }
+
+ void Store(ValueType value, TInstant to) {
+ int bucketTo = TimeToBucket(to);
+ TInstant from;
+ if (LastUpdate == TInstant()) {
+ LastUpdate = FirstUpdate = to;
+ return;
+ } else {
from = TInstant::MicroSeconds(std::max(LastUpdate.GetValue(), to.GetValue() - (DurationToStore - BUCKET_DURATION)));
- }
- int bucketFrom = TimeToBucket(from);
- if (bucketFrom == bucketTo) {
- Buckets[bucketTo] += value;
- } else {
- if (++bucketFrom == BucketCount)
- bucketFrom = 0;
- while (bucketFrom != bucketTo) {
- Buckets[bucketFrom] = 0;
- if (++bucketFrom == BucketCount)
- bucketFrom = 0;
- }
- Buckets[bucketTo] = value;
- }
- LastUpdate = to;
- if (FirstUpdate == TInstant()) {
- FirstUpdate = to;
- } else {
+ }
+ int bucketFrom = TimeToBucket(from);
+ if (bucketFrom == bucketTo) {
+ Buckets[bucketTo] += value;
+ } else {
+ if (++bucketFrom == BucketCount)
+ bucketFrom = 0;
+ while (bucketFrom != bucketTo) {
+ Buckets[bucketFrom] = 0;
+ if (++bucketFrom == BucketCount)
+ bucketFrom = 0;
+ }
+ Buckets[bucketTo] = value;
+ }
+ LastUpdate = to;
+ if (FirstUpdate == TInstant()) {
+ FirstUpdate = to;
+ } else {
FirstUpdate = TInstant::MicroSeconds(std::max(FirstUpdate.GetValue(), to.GetValue() - GetBucketSizeTo(to) - (DurationToStore - BUCKET_DURATION)));
- }
- }
-
- TDuration GetStoredDuration() const {
+ }
+ }
+
+ TDuration GetStoredDuration() const {
return TDuration::MicroSeconds(LastUpdate.GetValue() - FirstUpdate.GetValue());
- }
-
- ValueType GetValueAveragePerDuration(TDuration duration) const {
- if (LastUpdate == TInstant() || LastUpdate == FirstUpdate)
- return ValueType();
- ValueType accumulator = ValueType();
- int bucketTo = TimeToBucket(LastUpdate);
- int bucketFrom = TimeToBucket(FirstUpdate);
- for (int bucket = bucketFrom;; ++bucket, bucket = bucket >= BucketCount ? 0 : bucket) {
- accumulator += Buckets[bucket];
- if (bucket == bucketTo)
- break;
- }
- ValueType multiplicator(duration.GetValue());
- ValueType divider(GetStoredDuration().GetValue());
- return accumulator * multiplicator / divider;
- }
-
+ }
+
+ ValueType GetValueAveragePerDuration(TDuration duration) const {
+ if (LastUpdate == TInstant() || LastUpdate == FirstUpdate)
+ return ValueType();
+ ValueType accumulator = ValueType();
+ int bucketTo = TimeToBucket(LastUpdate);
+ int bucketFrom = TimeToBucket(FirstUpdate);
+ for (int bucket = bucketFrom;; ++bucket, bucket = bucket >= BucketCount ? 0 : bucket) {
+ accumulator += Buckets[bucket];
+ if (bucket == bucketTo)
+ break;
+ }
+ ValueType multiplicator(duration.GetValue());
+ ValueType divider(GetStoredDuration().GetValue());
+ return accumulator * multiplicator / divider;
+ }
+
void Increment(std::make_signed_t<ValueType> value, TInstant to = TInstant::Now()) {
- Store(value, to);
- }
-
- ValueType GetValue() const {
- return GetValueAveragePerDuration(TDuration::Seconds(1));
- }
-
- TTimeSeriesValue operator -(const TTimeSeriesValue& o) const {
- TTimeSeriesValue temp(*this);
- temp -= o;
- return temp;
- }
-
- TTimeSeriesValue operator +(const TTimeSeriesValue& o) const {
- TTimeSeriesValue temp(*this);
- temp += o;
- return temp;
- }
-
- TTimeSeriesValue& operator -=(const TTimeSeriesValue& o) {
- for (std::size_t i = 0; i < BucketCount; ++i)
- Buckets[i] -= o.Buckets[i];
- return *this;
- }
-
- TTimeSeriesValue& operator +=(const TTimeSeriesValue& o) {
- for (std::size_t i = 0; i < BucketCount; ++i)
- Buckets[i] += o.Buckets[i];
- return *this;
- }
-
- bool IsValueReady() const {
- return (LastUpdate - FirstUpdate).GetValue() >= DurationToStore / BucketCount;
- }
-
-protected:
- std::array<ValueType, BucketCount> Buckets;
- TInstant FirstUpdate;
- TInstant LastUpdate;
-};
-
-template <typename ValueType>
-struct TAverageConverter {
- static ValueType GetAverage(TTimeBase<TInstant>::TValue duration,
- TTimeBase<TInstant>::TValue accumulatorTime,
- ValueType accumulatorValue) {
- // we ether lose precision or having overflow...
- //return AccumulatorValue * duration.MilliSeconds() / AccumulatorTime;
- //return AccumulatorValue / AccumulatorTime * duration.GetValue();
- return round(double(duration) / accumulatorTime * accumulatorValue);
- }
-};
-
-template <>
-struct TAverageConverter<double> {
- static double GetAverage(TTimeBase<TInstant>::TValue duration,
- TTimeBase<TInstant>::TValue accumulatorTime,
- double accumulatorValue) {
- return double(duration) / accumulatorTime * accumulatorValue;
- }
-};
-
-template <typename ValueType,
- TTimeBase<TInstant>::TValue DurationToStore = DurationPerMinute,
- TTimeBase<TInstant>::TValue DurationToCalculate = DurationToStore>
-class TDecayingAverageValue {
- static constexpr TTimeBase<TInstant>::TValue GetTimeValue(TDuration duration) {
- return duration.MicroSeconds();
- }
-
- static constexpr TDuration GetTimeValue(TTimeBase<TInstant>::TValue duration) {
- return TDuration::MicroSeconds(duration);
- }
-
-public:
- using TType = ValueType;
-
- TDecayingAverageValue()
- : AverageValue()
- , AccumulatorValue()
- , LastUpdate()
- {}
-
- void Set(ValueType value, TInstant now = TInstant::Now()) {
- AverageValue = value;
- AccumulatorValue = ValueType();
- LastUpdate = now;
- }
-
- ValueType GetValueAveragePerDuration(TTimeBase<TInstant>::TValue periodToCalculate, TTimeBase<TInstant>::TValue periodToMeasure) const {
- if (AccumulatorValue == ValueType()) {
- return ValueType();
- }
- return TAverageConverter<ValueType>::GetAverage(periodToCalculate, periodToMeasure, AccumulatorValue);
- }
-
- static ValueType GetSumOfAverages(ValueType oldAverage, ValueType newAverage) {
- return oldAverage == ValueType() ? newAverage : (oldAverage * 1 + newAverage * 3) / 4;
- }
-
- void Increment(std::make_signed_t<ValueType> value, TInstant now = TInstant::Now()) {
- if (LastUpdate == TInstant()) {
- LastUpdate = now;
- return;
- }
- AccumulatorValue += value;
- auto time(GetTimeValue(now - LastUpdate));
- if (time >= DurationToStore) {
- AverageValue = GetSumOfAverages(AverageValue, GetValueAveragePerDuration(DurationToCalculate, time));
- AccumulatorValue = ValueType();
- LastUpdate = now;
- }
- }
-
- ValueType GetValue() const {
- return AverageValue;
- }
-
- bool IsValueReady() const {
- return AverageValue != ValueType();
- }
-
- bool IsValueObsolete(TInstant now = TInstant::Now()) const {
- return (LastUpdate + GetTimeValue(DurationToStore) * 2) < now;
- }
-
-protected:
- ValueType AverageValue;
- ValueType AccumulatorValue;
- TInstant LastUpdate;
-};
-
-template <typename ValueType, size_t MaxCount = 20>
-class TAverageValue {
-public:
- using TType = ValueType;
-
- TAverageValue()
- : AccumulatorValue()
- , AccumulatorCount()
- {}
-
- void Push(ValueType value) {
- if (AccumulatorCount >= MaxCount) {
- AccumulatorValue = AccumulatorValue / 2;
- AccumulatorCount /= 2;
- }
- AccumulatorValue += value;
- AccumulatorCount++;
- }
-
- ValueType GetValue() const {
- if (AccumulatorCount == 0) {
- return ValueType();
- }
- return AccumulatorValue / AccumulatorCount;
- }
-
- bool IsValueReady() const {
- return AccumulatorCount > 0;
- }
-
- bool IsValueStable() const {
- return AccumulatorCount >= MaxCount / 2;
- }
-
-protected:
- ValueType AccumulatorValue;
- size_t AccumulatorCount;
-};
-
-template <typename ValueType, size_t MaxCount = 20>
-class TFastRiseAverageValue {
-public:
- using TType = ValueType;
-
- TFastRiseAverageValue()
- : AccumulatorValue()
- , AccumulatorCount()
- {}
-
- void Push(ValueType value) {
- if (IsValueReady()) {
- ValueType currentValue = GetValue();
- if (value > currentValue) {
- ValueType newValue = (currentValue + value) / 2;
- AccumulatorCount++;
- AccumulatorValue = newValue * AccumulatorCount;
- return;
- }
- }
- if (AccumulatorCount >= MaxCount) {
- AccumulatorValue = AccumulatorValue / 2;
- AccumulatorCount /= 2;
- }
- AccumulatorValue += value;
- AccumulatorCount++;
- }
-
- ValueType GetValue() const {
- if (AccumulatorCount == 0) {
- return ValueType();
- }
- return AccumulatorValue / AccumulatorCount;
- }
-
- bool IsValueReady() const {
- return AccumulatorCount > 0;
- }
-
- bool IsValueStable() const {
- return AccumulatorCount >= 2;
- }
-
-protected:
- ValueType AccumulatorValue;
- size_t AccumulatorCount;
-};
-
-template <TTimeBase<TInstant>::TValue DurationToStore = DurationPerDay, size_t BucketCount = 24>
-class TMaximumValueUI64 : public NKikimrMetricsProto::TMaximumValueUI64 {
-public:
- using TType = ui64;
- using TProto = NKikimrMetricsProto::TMaximumValueUI64;
- static constexpr TDuration BucketDuration = TDuration::MilliSeconds(DurationToStore / BucketCount);
-
- void SetValue(TType value, TInstant now = TInstant::Now()) {
- if (TProto::ValuesSize() == 0 || now - TInstant::MilliSeconds(TProto::GetLastBucketStartTime()) > BucketDuration) {
- // new bucket
- if (TProto::ValuesSize() == BucketCount) {
- std::rotate(TProto::MutableValues()->begin(), std::next(TProto::MutableValues()->begin()), TProto::MutableValues()->end());
- auto& lastBucketValue(*std::prev(TProto::MutableValues()->end()));
- lastBucketValue = value;
- MaximumValue = *std::max_element(TProto::GetValues().begin(), TProto::GetValues().end());
- } else {
- TProto::MutableValues()->Add(value);
- MaximumValue = std::max(MaximumValue, value);
- }
- TProto::SetLastBucketStartTime(now.MilliSeconds());
- } else {
- auto& lastBucketValue(*std::prev(TProto::MutableValues()->end()));
- lastBucketValue = std::max(lastBucketValue, value);
- MaximumValue = std::max(MaximumValue, value);
- }
- }
-
- TType GetValue() const {
- return MaximumValue;
- }
-
- void InitiaizeFrom(const TProto& proto) {
- TProto::CopyFrom(proto);
- if (TProto::ValuesSize() > 0) {
- MaximumValue = *std::max_element(TProto::GetValues().begin(), TProto::GetValues().end());
- }
- }
-
-protected:
- TType MaximumValue = {};
-};
-
-class TMaximumValueVariableWindowUI64 : public NKikimrMetricsProto::TMaximumValueUI64 {
-public:
- using TType = ui64;
- using TProto = NKikimrMetricsProto::TMaximumValueUI64;
-
- void SetValue(TType value, TInstant now = TInstant::Now()) {
- TDuration elapsedCurrentBucket = now - TInstant::MilliSeconds(TProto::GetLastBucketStartTime());
- if (TProto::ValuesSize() == 0 || elapsedCurrentBucket >= BucketDuration) {
- size_t bucketsPassed = 0;
- // new bucket
- if (TProto::ValuesSize() == 0) {
- TProto::SetLastBucketStartTime(now.MilliSeconds());
- bucketsPassed = 1;
- } else {
- bucketsPassed = elapsedCurrentBucket / BucketDuration;
- TProto::SetLastBucketStartTime(TProto::GetLastBucketStartTime() + bucketsPassed * BucketDuration.MilliSeconds());
- }
-
- if (bucketsPassed >= BucketCount) {
- TProto::MutableValues()->Clear();
- TProto::MutableValues()->Add(value);
- MaximumValue = value;
- } else if (TProto::ValuesSize() + bucketsPassed > BucketCount) {
- auto shift = TProto::ValuesSize() + bucketsPassed - BucketCount;
- for (size_t pass = TProto::ValuesSize(); pass < BucketCount; ++pass) {
- TProto::MutableValues()->Add(value);
- }
- auto newBegin = TProto::MutableValues()->begin();
- std::advance(newBegin, shift);
- std::rotate(TProto::MutableValues()->begin(), newBegin, TProto::MutableValues()->end());
- auto last = TProto::MutableValues()->end();
- std::advance(last, -shift);
- std::fill(last, TProto::MutableValues()->end(), value);
- MaximumValue = *std::max_element(TProto::GetValues().begin(), TProto::GetValues().end());
- } else {
- for (size_t pass = 0; pass < bucketsPassed; ++pass) {
- TProto::MutableValues()->Add(value);
- }
- MaximumValue = std::max(MaximumValue, value);
- }
- } else {
- auto& lastBucketValue(*std::prev(TProto::MutableValues()->end()));
- lastBucketValue = std::max(lastBucketValue, value);
- MaximumValue = std::max(MaximumValue, value);
- }
- }
-
- TType GetValue() const {
- return MaximumValue;
- }
-
- void InitiaizeFrom(const TProto& proto) {
- TProto::CopyFrom(proto);
- if (TProto::ValuesSize() > 0) {
- MaximumValue = *std::max_element(TProto::GetValues().begin(), TProto::GetValues().end());
- }
- }
-
- void SetWindowSize(TDuration durationToStore, size_t bucketCount = 24) {
- BucketCount = bucketCount;
- BucketDuration = TDuration::MilliSeconds(durationToStore.MilliSeconds() / BucketCount);
- }
-
-protected:
- TType MaximumValue = {};
- size_t BucketCount = 24;
- TDuration BucketDuration = TDuration::Hours(1);
-};
-
-} // NMetrics
-} // NKikimr
+ Store(value, to);
+ }
+
+ ValueType GetValue() const {
+ return GetValueAveragePerDuration(TDuration::Seconds(1));
+ }
+
+ TTimeSeriesValue operator -(const TTimeSeriesValue& o) const {
+ TTimeSeriesValue temp(*this);
+ temp -= o;
+ return temp;
+ }
+
+ TTimeSeriesValue operator +(const TTimeSeriesValue& o) const {
+ TTimeSeriesValue temp(*this);
+ temp += o;
+ return temp;
+ }
+
+ TTimeSeriesValue& operator -=(const TTimeSeriesValue& o) {
+ for (std::size_t i = 0; i < BucketCount; ++i)
+ Buckets[i] -= o.Buckets[i];
+ return *this;
+ }
+
+ TTimeSeriesValue& operator +=(const TTimeSeriesValue& o) {
+ for (std::size_t i = 0; i < BucketCount; ++i)
+ Buckets[i] += o.Buckets[i];
+ return *this;
+ }
+
+ bool IsValueReady() const {
+ return (LastUpdate - FirstUpdate).GetValue() >= DurationToStore / BucketCount;
+ }
+
+protected:
+ std::array<ValueType, BucketCount> Buckets;
+ TInstant FirstUpdate;
+ TInstant LastUpdate;
+};
+
+template <typename ValueType>
+struct TAverageConverter {
+ static ValueType GetAverage(TTimeBase<TInstant>::TValue duration,
+ TTimeBase<TInstant>::TValue accumulatorTime,
+ ValueType accumulatorValue) {
+ // we ether lose precision or having overflow...
+ //return AccumulatorValue * duration.MilliSeconds() / AccumulatorTime;
+ //return AccumulatorValue / AccumulatorTime * duration.GetValue();
+ return round(double(duration) / accumulatorTime * accumulatorValue);
+ }
+};
+
+template <>
+struct TAverageConverter<double> {
+ static double GetAverage(TTimeBase<TInstant>::TValue duration,
+ TTimeBase<TInstant>::TValue accumulatorTime,
+ double accumulatorValue) {
+ return double(duration) / accumulatorTime * accumulatorValue;
+ }
+};
+
+template <typename ValueType,
+ TTimeBase<TInstant>::TValue DurationToStore = DurationPerMinute,
+ TTimeBase<TInstant>::TValue DurationToCalculate = DurationToStore>
+class TDecayingAverageValue {
+ static constexpr TTimeBase<TInstant>::TValue GetTimeValue(TDuration duration) {
+ return duration.MicroSeconds();
+ }
+
+ static constexpr TDuration GetTimeValue(TTimeBase<TInstant>::TValue duration) {
+ return TDuration::MicroSeconds(duration);
+ }
+
+public:
+ using TType = ValueType;
+
+ TDecayingAverageValue()
+ : AverageValue()
+ , AccumulatorValue()
+ , LastUpdate()
+ {}
+
+ void Set(ValueType value, TInstant now = TInstant::Now()) {
+ AverageValue = value;
+ AccumulatorValue = ValueType();
+ LastUpdate = now;
+ }
+
+ ValueType GetValueAveragePerDuration(TTimeBase<TInstant>::TValue periodToCalculate, TTimeBase<TInstant>::TValue periodToMeasure) const {
+ if (AccumulatorValue == ValueType()) {
+ return ValueType();
+ }
+ return TAverageConverter<ValueType>::GetAverage(periodToCalculate, periodToMeasure, AccumulatorValue);
+ }
+
+ static ValueType GetSumOfAverages(ValueType oldAverage, ValueType newAverage) {
+ return oldAverage == ValueType() ? newAverage : (oldAverage * 1 + newAverage * 3) / 4;
+ }
+
+ void Increment(std::make_signed_t<ValueType> value, TInstant now = TInstant::Now()) {
+ if (LastUpdate == TInstant()) {
+ LastUpdate = now;
+ return;
+ }
+ AccumulatorValue += value;
+ auto time(GetTimeValue(now - LastUpdate));
+ if (time >= DurationToStore) {
+ AverageValue = GetSumOfAverages(AverageValue, GetValueAveragePerDuration(DurationToCalculate, time));
+ AccumulatorValue = ValueType();
+ LastUpdate = now;
+ }
+ }
+
+ ValueType GetValue() const {
+ return AverageValue;
+ }
+
+ bool IsValueReady() const {
+ return AverageValue != ValueType();
+ }
+
+ bool IsValueObsolete(TInstant now = TInstant::Now()) const {
+ return (LastUpdate + GetTimeValue(DurationToStore) * 2) < now;
+ }
+
+protected:
+ ValueType AverageValue;
+ ValueType AccumulatorValue;
+ TInstant LastUpdate;
+};
+
+template <typename ValueType, size_t MaxCount = 20>
+class TAverageValue {
+public:
+ using TType = ValueType;
+
+ TAverageValue()
+ : AccumulatorValue()
+ , AccumulatorCount()
+ {}
+
+ void Push(ValueType value) {
+ if (AccumulatorCount >= MaxCount) {
+ AccumulatorValue = AccumulatorValue / 2;
+ AccumulatorCount /= 2;
+ }
+ AccumulatorValue += value;
+ AccumulatorCount++;
+ }
+
+ ValueType GetValue() const {
+ if (AccumulatorCount == 0) {
+ return ValueType();
+ }
+ return AccumulatorValue / AccumulatorCount;
+ }
+
+ bool IsValueReady() const {
+ return AccumulatorCount > 0;
+ }
+
+ bool IsValueStable() const {
+ return AccumulatorCount >= MaxCount / 2;
+ }
+
+protected:
+ ValueType AccumulatorValue;
+ size_t AccumulatorCount;
+};
+
+template <typename ValueType, size_t MaxCount = 20>
+class TFastRiseAverageValue {
+public:
+ using TType = ValueType;
+
+ TFastRiseAverageValue()
+ : AccumulatorValue()
+ , AccumulatorCount()
+ {}
+
+ void Push(ValueType value) {
+ if (IsValueReady()) {
+ ValueType currentValue = GetValue();
+ if (value > currentValue) {
+ ValueType newValue = (currentValue + value) / 2;
+ AccumulatorCount++;
+ AccumulatorValue = newValue * AccumulatorCount;
+ return;
+ }
+ }
+ if (AccumulatorCount >= MaxCount) {
+ AccumulatorValue = AccumulatorValue / 2;
+ AccumulatorCount /= 2;
+ }
+ AccumulatorValue += value;
+ AccumulatorCount++;
+ }
+
+ ValueType GetValue() const {
+ if (AccumulatorCount == 0) {
+ return ValueType();
+ }
+ return AccumulatorValue / AccumulatorCount;
+ }
+
+ bool IsValueReady() const {
+ return AccumulatorCount > 0;
+ }
+
+ bool IsValueStable() const {
+ return AccumulatorCount >= 2;
+ }
+
+protected:
+ ValueType AccumulatorValue;
+ size_t AccumulatorCount;
+};
+
+template <TTimeBase<TInstant>::TValue DurationToStore = DurationPerDay, size_t BucketCount = 24>
+class TMaximumValueUI64 : public NKikimrMetricsProto::TMaximumValueUI64 {
+public:
+ using TType = ui64;
+ using TProto = NKikimrMetricsProto::TMaximumValueUI64;
+ static constexpr TDuration BucketDuration = TDuration::MilliSeconds(DurationToStore / BucketCount);
+
+ void SetValue(TType value, TInstant now = TInstant::Now()) {
+ if (TProto::ValuesSize() == 0 || now - TInstant::MilliSeconds(TProto::GetLastBucketStartTime()) > BucketDuration) {
+ // new bucket
+ if (TProto::ValuesSize() == BucketCount) {
+ std::rotate(TProto::MutableValues()->begin(), std::next(TProto::MutableValues()->begin()), TProto::MutableValues()->end());
+ auto& lastBucketValue(*std::prev(TProto::MutableValues()->end()));
+ lastBucketValue = value;
+ MaximumValue = *std::max_element(TProto::GetValues().begin(), TProto::GetValues().end());
+ } else {
+ TProto::MutableValues()->Add(value);
+ MaximumValue = std::max(MaximumValue, value);
+ }
+ TProto::SetLastBucketStartTime(now.MilliSeconds());
+ } else {
+ auto& lastBucketValue(*std::prev(TProto::MutableValues()->end()));
+ lastBucketValue = std::max(lastBucketValue, value);
+ MaximumValue = std::max(MaximumValue, value);
+ }
+ }
+
+ TType GetValue() const {
+ return MaximumValue;
+ }
+
+ void InitiaizeFrom(const TProto& proto) {
+ TProto::CopyFrom(proto);
+ if (TProto::ValuesSize() > 0) {
+ MaximumValue = *std::max_element(TProto::GetValues().begin(), TProto::GetValues().end());
+ }
+ }
+
+protected:
+ TType MaximumValue = {};
+};
+
+class TMaximumValueVariableWindowUI64 : public NKikimrMetricsProto::TMaximumValueUI64 {
+public:
+ using TType = ui64;
+ using TProto = NKikimrMetricsProto::TMaximumValueUI64;
+
+ void SetValue(TType value, TInstant now = TInstant::Now()) {
+ TDuration elapsedCurrentBucket = now - TInstant::MilliSeconds(TProto::GetLastBucketStartTime());
+ if (TProto::ValuesSize() == 0 || elapsedCurrentBucket >= BucketDuration) {
+ size_t bucketsPassed = 0;
+ // new bucket
+ if (TProto::ValuesSize() == 0) {
+ TProto::SetLastBucketStartTime(now.MilliSeconds());
+ bucketsPassed = 1;
+ } else {
+ bucketsPassed = elapsedCurrentBucket / BucketDuration;
+ TProto::SetLastBucketStartTime(TProto::GetLastBucketStartTime() + bucketsPassed * BucketDuration.MilliSeconds());
+ }
+
+ if (bucketsPassed >= BucketCount) {
+ TProto::MutableValues()->Clear();
+ TProto::MutableValues()->Add(value);
+ MaximumValue = value;
+ } else if (TProto::ValuesSize() + bucketsPassed > BucketCount) {
+ auto shift = TProto::ValuesSize() + bucketsPassed - BucketCount;
+ for (size_t pass = TProto::ValuesSize(); pass < BucketCount; ++pass) {
+ TProto::MutableValues()->Add(value);
+ }
+ auto newBegin = TProto::MutableValues()->begin();
+ std::advance(newBegin, shift);
+ std::rotate(TProto::MutableValues()->begin(), newBegin, TProto::MutableValues()->end());
+ auto last = TProto::MutableValues()->end();
+ std::advance(last, -shift);
+ std::fill(last, TProto::MutableValues()->end(), value);
+ MaximumValue = *std::max_element(TProto::GetValues().begin(), TProto::GetValues().end());
+ } else {
+ for (size_t pass = 0; pass < bucketsPassed; ++pass) {
+ TProto::MutableValues()->Add(value);
+ }
+ MaximumValue = std::max(MaximumValue, value);
+ }
+ } else {
+ auto& lastBucketValue(*std::prev(TProto::MutableValues()->end()));
+ lastBucketValue = std::max(lastBucketValue, value);
+ MaximumValue = std::max(MaximumValue, value);
+ }
+ }
+
+ TType GetValue() const {
+ return MaximumValue;
+ }
+
+ void InitiaizeFrom(const TProto& proto) {
+ TProto::CopyFrom(proto);
+ if (TProto::ValuesSize() > 0) {
+ MaximumValue = *std::max_element(TProto::GetValues().begin(), TProto::GetValues().end());
+ }
+ }
+
+ void SetWindowSize(TDuration durationToStore, size_t bucketCount = 24) {
+ BucketCount = bucketCount;
+ BucketDuration = TDuration::MilliSeconds(durationToStore.MilliSeconds() / BucketCount);
+ }
+
+protected:
+ TType MaximumValue = {};
+ size_t BucketCount = 24;
+ TDuration BucketDuration = TDuration::Hours(1);
+};
+
+} // NMetrics
+} // NKikimr
diff --git a/ydb/core/util/proto_duration.h b/ydb/core/util/proto_duration.h
index b01136b9e86..01644ead377 100644
--- a/ydb/core/util/proto_duration.h
+++ b/ydb/core/util/proto_duration.h
@@ -1,25 +1,25 @@
-#pragma once
-
-#include <util/datetime/base.h>
-#include <google/protobuf/duration.pb.h>
-
-namespace NKikimr {
-
-inline
-TDuration GetDuration(const google::protobuf::Duration& duration) {
- ui32 ns = std::max((i32)duration.nanos(), (i32)0);
- ui32 ms = ns / 1000000;
- ms += ns % 1000000 > 0 ? 1 : 0; // ceil to millisecond
-
- ui64 seconds = std::max((i64)duration.seconds(), (i64)0);
-
- return TDuration::Seconds(seconds) + TDuration::MilliSeconds(ms);
-}
-
-inline
-void SetDuration(const TDuration& duration, google::protobuf::Duration& protoValue) {
- protoValue.set_seconds(duration.Seconds());
- protoValue.set_nanos(duration.NanoSecondsOfSecond());
-}
-
-}
+#pragma once
+
+#include <util/datetime/base.h>
+#include <google/protobuf/duration.pb.h>
+
+namespace NKikimr {
+
+inline
+TDuration GetDuration(const google::protobuf::Duration& duration) {
+ ui32 ns = std::max((i32)duration.nanos(), (i32)0);
+ ui32 ms = ns / 1000000;
+ ms += ns % 1000000 > 0 ? 1 : 0; // ceil to millisecond
+
+ ui64 seconds = std::max((i64)duration.seconds(), (i64)0);
+
+ return TDuration::Seconds(seconds) + TDuration::MilliSeconds(ms);
+}
+
+inline
+void SetDuration(const TDuration& duration, google::protobuf::Duration& protoValue) {
+ protoValue.set_seconds(duration.Seconds());
+ protoValue.set_nanos(duration.NanoSecondsOfSecond());
+}
+
+}
diff --git a/ydb/core/util/simple_cache.h b/ydb/core/util/simple_cache.h
index 91b1f575072..4190e8bb762 100644
--- a/ydb/core/util/simple_cache.h
+++ b/ydb/core/util/simple_cache.h
@@ -1,74 +1,74 @@
-#pragma once
-
-#include <unordered_map>
-#include <list>
-
-namespace NKikimr {
-
-template <typename TKey, typename TValue>
-class TSimpleCache {
-public:
- size_t MaxSize = 1024;
-
- struct TItem;
-
- using TMap = std::unordered_map<TKey, TItem>;
- using TMapIterator = typename TMap::iterator;
- using TList = typename std::list<TMapIterator>;
- using TListIterator = typename TList::iterator;
-
- struct TItem {
- TValue Value;
- TListIterator ListIterator;
- };
-
- TValue* FindPtr(TKey key) {
- auto it = Map_.find(key);
- if (it != Map_.end()) {
- Touch(it);
- return &it->second.Value;
- } else {
- return nullptr;
- }
- }
-
- TValue& Update(TKey key, TValue value = {}) {
- auto it = Map_.find(key); // we don't use blind emplace to avoid coping value
- if (it == Map_.end()) {
- it = Map_.emplace(key, TItem{std::move(value), List_.end()}).first;
- List_.emplace_back(it);
- it->second.ListIterator = std::prev(List_.end());
- Shrink();
- } else {
- it->second.Value = std::move(value);
- Touch(it);
- }
- return it->second.Value;
- }
-
- void Erase(TKey key) {
- auto it = Map_.find(key);
- if (it != Map_.end()) {
- List_.remove(it); // log(N)
- Map_.erase(it);
- }
- }
-
-protected:
- void Touch(TMapIterator it) {
- List_.splice(List_.end(), List_, it->second.ListIterator);
- it->second.ListIterator = std::prev(List_.end());
- }
-
- void Shrink() {
- if (List_.size() > MaxSize) {
- Map_.erase(List_.front());
- List_.pop_front();
- }
- }
-
- TMap Map_;
- TList List_;
-};
-
-} // NKikimr
+#pragma once
+
+#include <unordered_map>
+#include <list>
+
+namespace NKikimr {
+
+template <typename TKey, typename TValue>
+class TSimpleCache {
+public:
+ size_t MaxSize = 1024;
+
+ struct TItem;
+
+ using TMap = std::unordered_map<TKey, TItem>;
+ using TMapIterator = typename TMap::iterator;
+ using TList = typename std::list<TMapIterator>;
+ using TListIterator = typename TList::iterator;
+
+ struct TItem {
+ TValue Value;
+ TListIterator ListIterator;
+ };
+
+ TValue* FindPtr(TKey key) {
+ auto it = Map_.find(key);
+ if (it != Map_.end()) {
+ Touch(it);
+ return &it->second.Value;
+ } else {
+ return nullptr;
+ }
+ }
+
+ TValue& Update(TKey key, TValue value = {}) {
+ auto it = Map_.find(key); // we don't use blind emplace to avoid coping value
+ if (it == Map_.end()) {
+ it = Map_.emplace(key, TItem{std::move(value), List_.end()}).first;
+ List_.emplace_back(it);
+ it->second.ListIterator = std::prev(List_.end());
+ Shrink();
+ } else {
+ it->second.Value = std::move(value);
+ Touch(it);
+ }
+ return it->second.Value;
+ }
+
+ void Erase(TKey key) {
+ auto it = Map_.find(key);
+ if (it != Map_.end()) {
+ List_.remove(it); // log(N)
+ Map_.erase(it);
+ }
+ }
+
+protected:
+ void Touch(TMapIterator it) {
+ List_.splice(List_.end(), List_, it->second.ListIterator);
+ it->second.ListIterator = std::prev(List_.end());
+ }
+
+ void Shrink() {
+ if (List_.size() > MaxSize) {
+ Map_.erase(List_.front());
+ List_.pop_front();
+ }
+ }
+
+ TMap Map_;
+ TList List_;
+};
+
+} // NKikimr
diff --git a/ydb/core/util/simple_cache_ut.cpp b/ydb/core/util/simple_cache_ut.cpp
index 34da1fd7366..340d5226634 100644
--- a/ydb/core/util/simple_cache_ut.cpp
+++ b/ydb/core/util/simple_cache_ut.cpp
@@ -1,27 +1,27 @@
#include <library/cpp/testing/unittest/registar.h>
-#include "simple_cache.h"
-
-namespace NKikimr {
-Y_UNIT_TEST_SUITE(TSimpleCacheTest) {
- Y_UNIT_TEST(TestSimpleCache) {
- TSimpleCache<TString, TString> cache;
-
- cache.MaxSize = 3;
- TString* ptr = cache.FindPtr("1");
- UNIT_ASSERT(ptr == nullptr);
- cache.Update("1", "one");
- ptr = cache.FindPtr("1");
- UNIT_ASSERT(ptr != nullptr);
- UNIT_ASSERT(*ptr == "one");
- cache.Update("2", "two");
- cache.Update("3", "three");
- ptr = cache.FindPtr("1");
- UNIT_ASSERT(ptr != nullptr);
- UNIT_ASSERT(*ptr == "one");
- cache.Update("4", "four"); // we evicting oldest one - "two"
- ptr = cache.FindPtr("2");
- UNIT_ASSERT(ptr == nullptr);
- }
-}
-
-} // NKikimr
+#include "simple_cache.h"
+
+namespace NKikimr {
+Y_UNIT_TEST_SUITE(TSimpleCacheTest) {
+ Y_UNIT_TEST(TestSimpleCache) {
+ TSimpleCache<TString, TString> cache;
+
+ cache.MaxSize = 3;
+ TString* ptr = cache.FindPtr("1");
+ UNIT_ASSERT(ptr == nullptr);
+ cache.Update("1", "one");
+ ptr = cache.FindPtr("1");
+ UNIT_ASSERT(ptr != nullptr);
+ UNIT_ASSERT(*ptr == "one");
+ cache.Update("2", "two");
+ cache.Update("3", "three");
+ ptr = cache.FindPtr("1");
+ UNIT_ASSERT(ptr != nullptr);
+ UNIT_ASSERT(*ptr == "one");
+ cache.Update("4", "four"); // we evicting oldest one - "two"
+ ptr = cache.FindPtr("2");
+ UNIT_ASSERT(ptr == nullptr);
+ }
+}
+
+} // NKikimr
diff --git a/ydb/core/util/templates.h b/ydb/core/util/templates.h
index 3e4466e61bb..68596db50dc 100644
--- a/ydb/core/util/templates.h
+++ b/ydb/core/util/templates.h
@@ -1,41 +1,41 @@
-#pragma once
-
-namespace NKikimr {
-
-// first_of
-
-template <typename T, typename... Types>
-struct first_of {
- using type = T;
-};
-
-// max_of
-
-template <std::size_t... I>
-struct max_of;
-template <std::size_t I>
-struct max_of<I> {
- static constexpr std::size_t value = I;
-};
-template <std::size_t A, std::size_t B>
-struct max_of<A, B> {
- static constexpr std::size_t value = A > B ? A : B;
-};
-template <std::size_t A, std::size_t B, std::size_t... I>
-struct max_of<A, B, I...> {
- static constexpr std::size_t value = max_of<max_of<A, B>::value, I...>::value;
-};
-
-namespace SFINAE {
-
-template <typename>
-struct type_check {
- using type = int;
-};
-
-struct general {};
-struct special : general {};
-
-}
-
-}
+#pragma once
+
+namespace NKikimr {
+
+// first_of
+
+template <typename T, typename... Types>
+struct first_of {
+ using type = T;
+};
+
+// max_of
+
+template <std::size_t... I>
+struct max_of;
+template <std::size_t I>
+struct max_of<I> {
+ static constexpr std::size_t value = I;
+};
+template <std::size_t A, std::size_t B>
+struct max_of<A, B> {
+ static constexpr std::size_t value = A > B ? A : B;
+};
+template <std::size_t A, std::size_t B, std::size_t... I>
+struct max_of<A, B, I...> {
+ static constexpr std::size_t value = max_of<max_of<A, B>::value, I...>::value;
+};
+
+namespace SFINAE {
+
+template <typename>
+struct type_check {
+ using type = int;
+};
+
+struct general {};
+struct special : general {};
+
+}
+
+}
diff --git a/ydb/core/util/testactorsys.cpp b/ydb/core/util/testactorsys.cpp
index 9584fe43462..73d27bc9d92 100644
--- a/ydb/core/util/testactorsys.cpp
+++ b/ydb/core/util/testactorsys.cpp
@@ -97,7 +97,7 @@ static TActorId MakeBoardReplicaID(ui32 node, ui64 stateStorageGroup, ui32 repli
NTabletPipe::TClientConfig TTestActorSystem::GetPipeConfigWithRetries() {
NTabletPipe::TClientConfig pipeConfig;
- pipeConfig.RetryPolicy = NTabletPipe::TClientRetryPolicy::WithRetries();
+ pipeConfig.RetryPolicy = NTabletPipe::TClientRetryPolicy::WithRetries();
return pipeConfig;
}
diff --git a/ydb/core/util/tuples.h b/ydb/core/util/tuples.h
index 0bd04c79fc5..0ca06891984 100644
--- a/ydb/core/util/tuples.h
+++ b/ydb/core/util/tuples.h
@@ -1,361 +1,361 @@
-#pragma once
-#include <util/digest/multi.h>
+#pragma once
+#include <util/digest/multi.h>
#include <util/str_stl.h>
-#include <util/stream/output.h>
-#include <math.h>
-#include <numeric>
+#include <util/stream/output.h>
+#include <math.h>
+#include <numeric>
#include <utility>
-
-struct hash_combiner {
- template <typename T>
- inline static void hash_combine(std::size_t& seed, const T& val) {
- seed ^= std::hash<T>()(val) + 0x9e3779b9 + (seed<<6) + (seed>>2);
- }
-
- template <typename T, typename... Ts>
- static void hash_combine(std::size_t& seed, const T& val, const Ts&... args)
- {
- hash_combine(seed, val);
- hash_combine(seed, args...);
- }
-
- static void hash_combine (std::size_t&) {}
-
- template <typename... Ts>
- static std::size_t hash_val(const Ts&... args)
- {
- std::size_t seed = 0;
- hash_combine(seed, args...);
- return seed;
- }
-};
-
-namespace std {
-
-// std::hash for tuples
-template <typename... Types>
-struct hash<std::tuple<Types...>> {
- template <typename TupleType, std::size_t... I>
+
+struct hash_combiner {
+ template <typename T>
+ inline static void hash_combine(std::size_t& seed, const T& val) {
+ seed ^= std::hash<T>()(val) + 0x9e3779b9 + (seed<<6) + (seed>>2);
+ }
+
+ template <typename T, typename... Ts>
+ static void hash_combine(std::size_t& seed, const T& val, const Ts&... args)
+ {
+ hash_combine(seed, val);
+ hash_combine(seed, args...);
+ }
+
+ static void hash_combine (std::size_t&) {}
+
+ template <typename... Ts>
+ static std::size_t hash_val(const Ts&... args)
+ {
+ std::size_t seed = 0;
+ hash_combine(seed, args...);
+ return seed;
+ }
+};
+
+namespace std {
+
+// std::hash for tuples
+template <typename... Types>
+struct hash<std::tuple<Types...>> {
+ template <typename TupleType, std::size_t... I>
inline static std::size_t MultiHasher(const TupleType& tuple, std::index_sequence<I...> ) {
- return hash_combiner::hash_val(std::get<I>(tuple)...);
- }
-
- inline size_t operator()(const std::tuple<Types...>& tuple) const {
+ return hash_combiner::hash_val(std::get<I>(tuple)...);
+ }
+
+ inline size_t operator()(const std::tuple<Types...>& tuple) const {
return MultiHasher(tuple, std::make_index_sequence<sizeof...(Types)>());
- }
-};
-
-// std::hash for pairs (subset of tuple)
-template <typename TFirst, typename TSecond>
-struct hash<pair<TFirst, TSecond>> {
- inline size_t operator()(pair<TFirst, TSecond> pair) const {
- return hash_combiner::hash_val(pair.first, pair.second);
- }
-};
-
-}
-
-// output for tuples
-template <typename TupleType, std::size_t N>
-struct OutTuple : OutTuple<TupleType, N - 1> {
+ }
+};
+
+// std::hash for pairs (subset of tuple)
+template <typename TFirst, typename TSecond>
+struct hash<pair<TFirst, TSecond>> {
+ inline size_t operator()(pair<TFirst, TSecond> pair) const {
+ return hash_combiner::hash_val(pair.first, pair.second);
+ }
+};
+
+}
+
+// output for tuples
+template <typename TupleType, std::size_t N>
+struct OutTuple : OutTuple<TupleType, N - 1> {
static void Out(IOutputStream& stream, const TupleType& t) {
- OutTuple<TupleType, N - 1>::Out(stream, t);
- stream << "," << std::get<N>(t);
- }
-};
-
-template <typename TupleType>
-struct OutTuple<TupleType, 0> {
+ OutTuple<TupleType, N - 1>::Out(stream, t);
+ stream << "," << std::get<N>(t);
+ }
+};
+
+template <typename TupleType>
+struct OutTuple<TupleType, 0> {
static void Out(IOutputStream& stream, const TupleType& t) {
- stream << std::get<0>(t);
- }
-};
-
-template <typename... Types>
+ stream << std::get<0>(t);
+ }
+};
+
+template <typename... Types>
IOutputStream& operator <<(IOutputStream& stream, const std::tuple<Types...>& t) {
- stream << "(";
- OutTuple<std::tuple<Types...>, sizeof...(Types) - 1>::Out(stream, t);
- stream << ")";
- return stream;
-}
-
-namespace NKikimr {
-
-// tuple arithmethic operators (+ - * /)
-
-template <std::size_t... I, typename... A, typename... B>
-decltype(std::make_tuple(std::get<I>(std::tuple<A...>()) + std::get<I>(std::tuple<B...>())...))
+ stream << "(";
+ OutTuple<std::tuple<Types...>, sizeof...(Types) - 1>::Out(stream, t);
+ stream << ")";
+ return stream;
+}
+
+namespace NKikimr {
+
+// tuple arithmethic operators (+ - * /)
+
+template <std::size_t... I, typename... A, typename... B>
+decltype(std::make_tuple(std::get<I>(std::tuple<A...>()) + std::get<I>(std::tuple<B...>())...))
add(std::index_sequence<I...>, const std::tuple<A...>& a, const std::tuple<B...>& b) {
- return std::make_tuple(std::get<I>(a) + std::get<I>(b)...);
-}
-
-template <typename... A, typename... B>
+ return std::make_tuple(std::get<I>(a) + std::get<I>(b)...);
+}
+
+template <typename... A, typename... B>
decltype(add(std::make_index_sequence<sizeof...(A)>(), std::tuple<A...>(), std::tuple<B...>()))
-operator +(const std::tuple<A...>& a, const std::tuple<B...>& b) {
- static_assert(sizeof...(A) == sizeof...(B), "Tuples should be the same size");
+operator +(const std::tuple<A...>& a, const std::tuple<B...>& b) {
+ static_assert(sizeof...(A) == sizeof...(B), "Tuples should be the same size");
return add(std::make_index_sequence<sizeof...(A)>(), a, b);
-}
-
-template <std::size_t... I, typename... A, typename... B>
-decltype(std::make_tuple(std::get<I>(std::tuple<A...>()) - std::get<I>(std::tuple<B...>())...))
+}
+
+template <std::size_t... I, typename... A, typename... B>
+decltype(std::make_tuple(std::get<I>(std::tuple<A...>()) - std::get<I>(std::tuple<B...>())...))
sub(std::index_sequence<I...>, const std::tuple<A...>& a, const std::tuple<B...>& b) {
- return std::make_tuple(std::get<I>(a) - std::get<I>(b)...);
-}
-
-template <typename... A, typename... B>
+ return std::make_tuple(std::get<I>(a) - std::get<I>(b)...);
+}
+
+template <typename... A, typename... B>
decltype(sub(std::make_index_sequence<sizeof...(A)>(), std::tuple<A...>(), std::tuple<B...>()))
-operator -(const std::tuple<A...>& a, const std::tuple<B...>& b) {
- static_assert(sizeof...(A) == sizeof...(B), "Tuples should be the same size");
+operator -(const std::tuple<A...>& a, const std::tuple<B...>& b) {
+ static_assert(sizeof...(A) == sizeof...(B), "Tuples should be the same size");
return sub(std::make_index_sequence<sizeof...(A)>(), a, b);
-}
-
-template <std::size_t... I, typename... A, typename... B>
-decltype(std::make_tuple(std::get<I>(std::tuple<A...>()) * std::get<I>(std::tuple<B...>())...))
+}
+
+template <std::size_t... I, typename... A, typename... B>
+decltype(std::make_tuple(std::get<I>(std::tuple<A...>()) * std::get<I>(std::tuple<B...>())...))
mul(std::index_sequence<I...>, const std::tuple<A...>& a, const std::tuple<B...>& b) {
- return std::make_tuple(std::get<I>(a) * std::get<I>(b)...);
-}
-
-template <typename... A, typename... B>
+ return std::make_tuple(std::get<I>(a) * std::get<I>(b)...);
+}
+
+template <typename... A, typename... B>
decltype(mul(std::make_index_sequence<sizeof...(A)>(), std::tuple<A...>(), std::tuple<B...>()))
-operator *(const std::tuple<A...>& a, const std::tuple<B...>& b) {
- static_assert(sizeof...(A) == sizeof...(B), "Tuples should be the same size");
+operator *(const std::tuple<A...>& a, const std::tuple<B...>& b) {
+ static_assert(sizeof...(A) == sizeof...(B), "Tuples should be the same size");
return mul(std::make_index_sequence<sizeof...(A)>(), a, b);
-}
-
-template <std::size_t... I, typename... A, typename... B>
-decltype(std::make_tuple(std::get<I>(std::tuple<A...>()) / std::get<I>(std::tuple<B...>())...))
+}
+
+template <std::size_t... I, typename... A, typename... B>
+decltype(std::make_tuple(std::get<I>(std::tuple<A...>()) / std::get<I>(std::tuple<B...>())...))
div(std::index_sequence<I...>, const std::tuple<A...>& a, const std::tuple<B...>& b) {
- return std::make_tuple(std::get<I>(a) / std::get<I>(b)...);
-}
-
-template <typename... A, typename... B>
+ return std::make_tuple(std::get<I>(a) / std::get<I>(b)...);
+}
+
+template <typename... A, typename... B>
decltype(div(std::make_index_sequence<sizeof...(A)>(), std::tuple<A...>(), std::tuple<B...>()))
-operator /(const std::tuple<A...>& a, const std::tuple<B...>& b) {
- static_assert(sizeof...(A) == sizeof...(B), "Tuples should be the same size");
+operator /(const std::tuple<A...>& a, const std::tuple<B...>& b) {
+ static_assert(sizeof...(A) == sizeof...(B), "Tuples should be the same size");
return div(std::make_index_sequence<sizeof...(A)>(), a, b);
-}
-
-/////
-
-template <std::size_t... I, typename... A, typename V>
-decltype(std::make_tuple(std::get<I>(std::tuple<A...>()) / V()...))
-mul(std::index_sequence<I...>, const std::tuple<A...>& a, V b) {
- return std::make_tuple(std::get<I>(a) * b...);
-}
-
-template <typename... A, typename V>
-decltype(mul(std::make_index_sequence<sizeof...(A)>(), std::tuple<A...>(), V()))
-operator *(const std::tuple<A...>& a, V b) {
- return mul(std::make_index_sequence<sizeof...(A)>(), a, b);
-}
-
-template <std::size_t... I, typename... A, typename V>
-decltype(std::make_tuple(std::get<I>(std::tuple<A...>()) / V()...))
+}
+
+/////
+
+template <std::size_t... I, typename... A, typename V>
+decltype(std::make_tuple(std::get<I>(std::tuple<A...>()) / V()...))
+mul(std::index_sequence<I...>, const std::tuple<A...>& a, V b) {
+ return std::make_tuple(std::get<I>(a) * b...);
+}
+
+template <typename... A, typename V>
+decltype(mul(std::make_index_sequence<sizeof...(A)>(), std::tuple<A...>(), V()))
+operator *(const std::tuple<A...>& a, V b) {
+ return mul(std::make_index_sequence<sizeof...(A)>(), a, b);
+}
+
+template <std::size_t... I, typename... A, typename V>
+decltype(std::make_tuple(std::get<I>(std::tuple<A...>()) / V()...))
div(std::index_sequence<I...>, const std::tuple<A...>& a, V b) {
- return std::make_tuple(std::get<I>(a) / b...);
-}
-
-template <typename... A, typename V>
+ return std::make_tuple(std::get<I>(a) / b...);
+}
+
+template <typename... A, typename V>
decltype(div(std::make_index_sequence<sizeof...(A)>(), std::tuple<A...>(), V()))
-operator /(const std::tuple<A...>& a, V b) {
+operator /(const std::tuple<A...>& a, V b) {
return div(std::make_index_sequence<sizeof...(A)>(), a, b);
-}
-
-/////
-
-template <typename... A, typename... B>
-std::tuple<A...> operator +=(std::tuple<A...>& a, const std::tuple<B...>& b) {
- return a = (a + b);
-}
-
-template <typename... A, typename... B>
-std::tuple<A...> operator -=(std::tuple<A...>& a, const std::tuple<B...>& b) {
- return a = (a - b);
-}
-
-template <typename... A, typename... B>
-std::tuple<A...> operator /=(std::tuple<A...>& a, const std::tuple<B...>& b) {
- return a = (a / b);
-}
-
-template <typename... A, typename... B>
-std::tuple<A...> operator *=(std::tuple<A...>& a, const std::tuple<B...>& b) {
- return a = (a * b);
-}
-
-/////
-
-template <typename... T, typename V>
-decltype(std::tuple<T...>() / V()) operator /=(std::tuple<T...>& a, V b) {
- return a = (a / b);
-}
-
-// max(tuple<>) - returns maximum of all tuple elements
-
-template <std::size_t... I, typename...T>
+}
+
+/////
+
+template <typename... A, typename... B>
+std::tuple<A...> operator +=(std::tuple<A...>& a, const std::tuple<B...>& b) {
+ return a = (a + b);
+}
+
+template <typename... A, typename... B>
+std::tuple<A...> operator -=(std::tuple<A...>& a, const std::tuple<B...>& b) {
+ return a = (a - b);
+}
+
+template <typename... A, typename... B>
+std::tuple<A...> operator /=(std::tuple<A...>& a, const std::tuple<B...>& b) {
+ return a = (a / b);
+}
+
+template <typename... A, typename... B>
+std::tuple<A...> operator *=(std::tuple<A...>& a, const std::tuple<B...>& b) {
+ return a = (a * b);
+}
+
+/////
+
+template <typename... T, typename V>
+decltype(std::tuple<T...>() / V()) operator /=(std::tuple<T...>& a, V b) {
+ return a = (a / b);
+}
+
+// max(tuple<>) - returns maximum of all tuple elements
+
+template <std::size_t... I, typename...T>
decltype(std::max({std::get<I>(std::tuple<T...>())...})) max(std::index_sequence<I...>, const std::tuple<T...>& a) {
- return std::max({std::get<I>(a)...});
-}
-
-template <typename... T>
+ return std::max({std::get<I>(a)...});
+}
+
+template <typename... T>
decltype(max(std::make_index_sequence<sizeof...(T)>(), std::tuple<T...>())) max(const std::tuple<T...>& a) {
return max(std::make_index_sequence<sizeof...(T)>(), a);
-}
-
-// min(tuple<>) - returns minimum of all tuple elements
-
-template <std::size_t... I, typename...T>
+}
+
+// min(tuple<>) - returns minimum of all tuple elements
+
+template <std::size_t... I, typename...T>
decltype(std::min({std::get<I>(std::tuple<T...>())...})) min(std::index_sequence<I...>, const std::tuple<T...>& a) {
- return std::min({std::get<I>(a)...});
-}
-
-template <typename... T>
+ return std::min({std::get<I>(a)...});
+}
+
+template <typename... T>
decltype(min(std::make_index_sequence<sizeof...(T)>(), std::tuple<T...>())) min(const std::tuple<T...>& a) {
return min(std::make_index_sequence<sizeof...(T)>(), a);
-}
-
-// sqrt(tuple<>) - returns sqrt of every tuple element
-
-template <std::size_t... I, typename...T>
+}
+
+// sqrt(tuple<>) - returns sqrt of every tuple element
+
+template <std::size_t... I, typename...T>
decltype(std::make_tuple(::sqrt(std::get<I>(std::tuple<T...>()))...)) sqrt(std::index_sequence<I...>, const std::tuple<T...>& a) {
- return std::make_tuple(::sqrt(std::get<I>(a))...);
-}
-
-template <typename... T>
+ return std::make_tuple(::sqrt(std::get<I>(a))...);
+}
+
+template <typename... T>
decltype(sqrt(std::make_index_sequence<sizeof...(T)>(), std::tuple<T...>())) sqrt(const std::tuple<T...>& a) {
return sqrt(std::make_index_sequence<sizeof...(T)>(), a);
-}
-
-// convert(tuple<>, f) - converts every tuple element using f
-
-template <std::size_t... I, typename...T, typename F>
+}
+
+// convert(tuple<>, f) - converts every tuple element using f
+
+template <std::size_t... I, typename...T, typename F>
decltype(std::make_tuple((*(F*)(nullptr))(std::get<I>(std::tuple<T...>()))...)) convert(std::index_sequence<I...>, const std::tuple<T...>& a, F f) {
- return std::make_tuple(f(std::get<I>(a))...);
-}
-
-template <typename... T, typename F>
+ return std::make_tuple(f(std::get<I>(a))...);
+}
+
+template <typename... T, typename F>
decltype(convert(std::make_index_sequence<sizeof...(T)>(), std::tuple<T...>(), *(F*)(nullptr))) convert(const std::tuple<T...>& a, F f) {
return convert(std::make_index_sequence<sizeof...(T)>(), a, f);
-}
-
-template <typename... T>
-struct tuple_cast {
- template <std::size_t... I, typename... F>
+}
+
+template <typename... T>
+struct tuple_cast {
+ template <std::size_t... I, typename... F>
static std::tuple<T...> cast(std::index_sequence<I...>, const std::tuple<F...>& a) {
- return std::tuple<T...>((T)std::get<I>(a)...);
- }
-
- template <typename... F>
- static std::tuple<T...> cast(const std::tuple<F...>& a) {
- static_assert(sizeof...(F) == sizeof...(T), "Tuples should be equal size");
+ return std::tuple<T...>((T)std::get<I>(a)...);
+ }
+
+ template <typename... F>
+ static std::tuple<T...> cast(const std::tuple<F...>& a) {
+ static_assert(sizeof...(F) == sizeof...(T), "Tuples should be equal size");
return cast(std::make_index_sequence<sizeof...(T)>(), a);
- }
-};
-
-// sum(tuple<>) - returns sum of all tuple elements
-
-template <typename T>
-T sum(const std::initializer_list<T>& v) {
- return std::accumulate(v.begin(), v.end(), T());
-}
-
-template <std::size_t... I, typename...T>
+ }
+};
+
+// sum(tuple<>) - returns sum of all tuple elements
+
+template <typename T>
+T sum(const std::initializer_list<T>& v) {
+ return std::accumulate(v.begin(), v.end(), T());
+}
+
+template <std::size_t... I, typename...T>
decltype(sum({std::get<I>(std::tuple<T...>())...})) sum(std::index_sequence<I...>, const std::tuple<T...>& a) {
- return sum({std::get<I>(a)...});
-}
-
-template <typename... T>
+ return sum({std::get<I>(a)...});
+}
+
+template <typename... T>
decltype(sum(std::make_index_sequence<sizeof...(T)>(), std::tuple<T...>())) sum(const std::tuple<T...>& a) {
return sum(std::make_index_sequence<sizeof...(T)>(), a);
-}
-
-// make_n_tuple<N,T>::type - returns type of std::tuple<T, T, T... N times>
-
-template <typename T1, typename T2>
-struct concat_tuples;
-template <typename... T1, typename... T2>
-struct concat_tuples<std::tuple<T1...>, std::tuple<T2...>> {
- using type = std::tuple<T1..., T2...>;
-};
-template <std::size_t N, typename T>
-struct make_n_tuple {
- using type = typename concat_tuples<std::tuple<T>, typename make_n_tuple<N - 1, T>::type>::type;
-};
-template <typename T>
-struct make_n_tuple<1, T> {
- using type = std::tuple<T>;
-};
-
-// make_array(tuple<>) - converts to std::array<>
-
-template <typename T, std::size_t... I>
+}
+
+// make_n_tuple<N,T>::type - returns type of std::tuple<T, T, T... N times>
+
+template <typename T1, typename T2>
+struct concat_tuples;
+template <typename... T1, typename... T2>
+struct concat_tuples<std::tuple<T1...>, std::tuple<T2...>> {
+ using type = std::tuple<T1..., T2...>;
+};
+template <std::size_t N, typename T>
+struct make_n_tuple {
+ using type = typename concat_tuples<std::tuple<T>, typename make_n_tuple<N - 1, T>::type>::type;
+};
+template <typename T>
+struct make_n_tuple<1, T> {
+ using type = std::tuple<T>;
+};
+
+// make_array(tuple<>) - converts to std::array<>
+
+template <typename T, std::size_t... I>
std::array<std::tuple_element_t<0, T>, std::tuple_size<T>::value> tuple_to_array(std::index_sequence<I...>, const T& a) {
- return {{std::get<I>(a)...}};
-}
-
-template <typename T>
+ return {{std::get<I>(a)...}};
+}
+
+template <typename T>
std::array<std::tuple_element_t<0, T>, std::tuple_size<T>::value> tuple_to_array(const T& a) {
return tuple_to_array(std::make_index_sequence<std::tuple_size<T>::value>(), a);
-}
-
-// make_tuple(array<>) - converts to std::tuple<>
-
-template <typename T, std::size_t S, std::size_t... I>
+}
+
+// make_tuple(array<>) - converts to std::tuple<>
+
+template <typename T, std::size_t S, std::size_t... I>
typename make_n_tuple<S, T>::type array_to_tuple(std::index_sequence<I...>, const std::array<T, S>& a) {
- return std::make_tuple(a[I]...);
-}
-
-template <typename T, std::size_t S>
-typename make_n_tuple<S, T>::type array_to_tuple(const std::array<T, S>& a) {
+ return std::make_tuple(a[I]...);
+}
+
+template <typename T, std::size_t S>
+typename make_n_tuple<S, T>::type array_to_tuple(const std::array<T, S>& a) {
return array_to_tuple(std::make_index_sequence<S>(), a);
-}
-
-// index_of
-
-template <typename T, typename Tuple>
-struct index_of;
-template <typename T, typename... Types>
-struct index_of<T, std::tuple<T, Types...>> {
- static constexpr std::size_t value = 0;
-};
-template <typename T, typename U, class... Types>
-struct index_of<T, std::tuple<U, Types...>> {
- static constexpr std::size_t value = 1 + index_of<T, std::tuple<Types...>>::value;
-};
-
-// first_n_of
-
-template <std::size_t, typename...>
-struct first_n_of_tuple;
-template <std::size_t N, typename Type, typename... Types>
-struct first_n_of_tuple<N, Type, Types...> {
- using type = typename concat_tuples<std::tuple<Type>, typename first_n_of_tuple<N - 1, Types...>::type>::type;
-};
-template <typename... Types>
-struct first_n_of_tuple<0, Types...> {
- using type = std::tuple<>;
-};
-template <typename Type, typename... Types>
-struct first_n_of_tuple<1, Type, Types...> {
- using type = std::tuple<Type>;
-};
-
-template <std::size_t, typename...>
-struct first_n_of;
-template <typename... Types>
-struct first_n_of<0, std::tuple<Types...>> {
- using type = std::tuple<>;
-};
-template <std::size_t N, typename... Types>
-struct first_n_of<N, std::tuple<Types...>> {
- using type = typename first_n_of_tuple<N, Types...>::type;
-};
-
-// piecewise_max(tuple<>, tuple<>)
-
-template <std::size_t... I, typename... Ts>
-inline std::tuple<Ts...> piecewise_max(std::index_sequence<I...>, const std::tuple<Ts...>& a, const std::tuple<Ts...>& b) { return std::tuple<Ts...>({std::max<Ts>(std::get<I>(a), std::get<I>(b))...}); }
-template <typename... Ts>
-inline std::tuple<Ts...> piecewise_max(const std::tuple<Ts...>& a, const std::tuple<Ts...>& b) { return piecewise_max(std::make_index_sequence<sizeof...(Ts)>(), a, b); }
-
-}
+}
+
+// index_of
+
+template <typename T, typename Tuple>
+struct index_of;
+template <typename T, typename... Types>
+struct index_of<T, std::tuple<T, Types...>> {
+ static constexpr std::size_t value = 0;
+};
+template <typename T, typename U, class... Types>
+struct index_of<T, std::tuple<U, Types...>> {
+ static constexpr std::size_t value = 1 + index_of<T, std::tuple<Types...>>::value;
+};
+
+// first_n_of
+
+template <std::size_t, typename...>
+struct first_n_of_tuple;
+template <std::size_t N, typename Type, typename... Types>
+struct first_n_of_tuple<N, Type, Types...> {
+ using type = typename concat_tuples<std::tuple<Type>, typename first_n_of_tuple<N - 1, Types...>::type>::type;
+};
+template <typename... Types>
+struct first_n_of_tuple<0, Types...> {
+ using type = std::tuple<>;
+};
+template <typename Type, typename... Types>
+struct first_n_of_tuple<1, Type, Types...> {
+ using type = std::tuple<Type>;
+};
+
+template <std::size_t, typename...>
+struct first_n_of;
+template <typename... Types>
+struct first_n_of<0, std::tuple<Types...>> {
+ using type = std::tuple<>;
+};
+template <std::size_t N, typename... Types>
+struct first_n_of<N, std::tuple<Types...>> {
+ using type = typename first_n_of_tuple<N, Types...>::type;
+};
+
+// piecewise_max(tuple<>, tuple<>)
+
+template <std::size_t... I, typename... Ts>
+inline std::tuple<Ts...> piecewise_max(std::index_sequence<I...>, const std::tuple<Ts...>& a, const std::tuple<Ts...>& b) { return std::tuple<Ts...>({std::max<Ts>(std::get<I>(a), std::get<I>(b))...}); }
+template <typename... Ts>
+inline std::tuple<Ts...> piecewise_max(const std::tuple<Ts...>& a, const std::tuple<Ts...>& b) { return piecewise_max(std::make_index_sequence<sizeof...(Ts)>(), a, b); }
+
+}
diff --git a/ydb/core/util/ut/ya.make b/ydb/core/util/ut/ya.make
index 47c2717d7b5..315713cad86 100644
--- a/ydb/core/util/ut/ya.make
+++ b/ydb/core/util/ut/ya.make
@@ -47,7 +47,7 @@ SRCS(
time_series_vec_ut.cpp
token_bucket_ut.cpp
ulid_ut.cpp
- wildcard_ut.cpp
+ wildcard_ut.cpp
)
END()
diff --git a/ydb/core/util/wildcard.h b/ydb/core/util/wildcard.h
index 727db701d3f..ddd31eac30b 100644
--- a/ydb/core/util/wildcard.h
+++ b/ydb/core/util/wildcard.h
@@ -1,50 +1,50 @@
-#pragma once
-
-#include <util/generic/strbuf.h>
-
-namespace NKikimr {
-
-inline bool IsMatchesWildcard(TStringBuf source, TStringBuf wildcard) {
- size_t srcPos = 0;
- size_t wldPos = 0;
- size_t srcSize = source.size();
- size_t wldSize = wildcard.size();
- while(wldPos < wldSize) {
- if (wildcard[wldPos] == '*') {
- ++wldPos;
- size_t partPos = wldPos;
- while (wldPos < wldSize && wildcard[wldPos] != '*' && wildcard[wldPos] != '?') {
- ++wldPos;
- }
- if (wldPos == partPos) {
- return true;
- }
- TStringBuf part(wildcard.substr(partPos, wldPos - partPos));
- size_t partFound = source.find(part, srcPos);
- if (partFound == TStringBuf::npos) {
- return false;
- }
- srcPos = partFound + part.size();
- continue;
- }
- if (srcPos < srcSize && (wildcard[wldPos] == '?' || source[srcPos] == wildcard[wldPos])) {
- ++srcPos;
- ++wldPos;
- continue;
- } else {
- return false;
- }
- }
- return true;
-}
-
-inline bool IsMatchesWildcards(TStringBuf source, TStringBuf wildcards) {
- while (!wildcards.empty()) {
- if (IsMatchesWildcard(source, wildcards.NextTok(','))) {
- return true;
- }
- }
- return false;
-}
-
-} // NKikimr
+#pragma once
+
+#include <util/generic/strbuf.h>
+
+namespace NKikimr {
+
+inline bool IsMatchesWildcard(TStringBuf source, TStringBuf wildcard) {
+ size_t srcPos = 0;
+ size_t wldPos = 0;
+ size_t srcSize = source.size();
+ size_t wldSize = wildcard.size();
+ while(wldPos < wldSize) {
+ if (wildcard[wldPos] == '*') {
+ ++wldPos;
+ size_t partPos = wldPos;
+ while (wldPos < wldSize && wildcard[wldPos] != '*' && wildcard[wldPos] != '?') {
+ ++wldPos;
+ }
+ if (wldPos == partPos) {
+ return true;
+ }
+ TStringBuf part(wildcard.substr(partPos, wldPos - partPos));
+ size_t partFound = source.find(part, srcPos);
+ if (partFound == TStringBuf::npos) {
+ return false;
+ }
+ srcPos = partFound + part.size();
+ continue;
+ }
+ if (srcPos < srcSize && (wildcard[wldPos] == '?' || source[srcPos] == wildcard[wldPos])) {
+ ++srcPos;
+ ++wldPos;
+ continue;
+ } else {
+ return false;
+ }
+ }
+ return true;
+}
+
+inline bool IsMatchesWildcards(TStringBuf source, TStringBuf wildcards) {
+ while (!wildcards.empty()) {
+ if (IsMatchesWildcard(source, wildcards.NextTok(','))) {
+ return true;
+ }
+ }
+ return false;
+}
+
+} // NKikimr
diff --git a/ydb/core/util/wildcard_ut.cpp b/ydb/core/util/wildcard_ut.cpp
index f70813c9957..ad818a54f11 100644
--- a/ydb/core/util/wildcard_ut.cpp
+++ b/ydb/core/util/wildcard_ut.cpp
@@ -1,31 +1,31 @@
-#include "wildcard.h"
+#include "wildcard.h"
#include <library/cpp/testing/unittest/registar.h>
-
-namespace NKikimr {
+
+namespace NKikimr {
Y_UNIT_TEST_SUITE(TWildcardTest) {
Y_UNIT_TEST(TestWildcard) {
- UNIT_ASSERT(NKikimr::IsMatchesWildcard("some/test/string", "*"));
- UNIT_ASSERT(NKikimr::IsMatchesWildcard("some/test/string", "*/*"));
- UNIT_ASSERT(NKikimr::IsMatchesWildcard("some/test/string", "some/test/string"));
- UNIT_ASSERT(NKikimr::IsMatchesWildcard("some/test/string", "some*string"));
- UNIT_ASSERT(NKikimr::IsMatchesWildcard("some/test/string", "some*str?ng"));
- UNIT_ASSERT(NKikimr::IsMatchesWildcard("some/test/string", "some*"));
- UNIT_ASSERT(NKikimr::IsMatchesWildcard("some/test/string", "*string"));
- UNIT_ASSERT(NKikimr::IsMatchesWildcard("some/test/string", "*/test/*"));
- UNIT_ASSERT(NKikimr::IsMatchesWildcard("", "*"));
- UNIT_ASSERT(NKikimr::IsMatchesWildcard("", ""));
- UNIT_ASSERT(!NKikimr::IsMatchesWildcard("some/test/string", "ssome*"));
- UNIT_ASSERT(!NKikimr::IsMatchesWildcard("some/test/string", "*strring"));
- UNIT_ASSERT(!NKikimr::IsMatchesWildcard("", "*/test/*"));
- }
-
+ UNIT_ASSERT(NKikimr::IsMatchesWildcard("some/test/string", "*"));
+ UNIT_ASSERT(NKikimr::IsMatchesWildcard("some/test/string", "*/*"));
+ UNIT_ASSERT(NKikimr::IsMatchesWildcard("some/test/string", "some/test/string"));
+ UNIT_ASSERT(NKikimr::IsMatchesWildcard("some/test/string", "some*string"));
+ UNIT_ASSERT(NKikimr::IsMatchesWildcard("some/test/string", "some*str?ng"));
+ UNIT_ASSERT(NKikimr::IsMatchesWildcard("some/test/string", "some*"));
+ UNIT_ASSERT(NKikimr::IsMatchesWildcard("some/test/string", "*string"));
+ UNIT_ASSERT(NKikimr::IsMatchesWildcard("some/test/string", "*/test/*"));
+ UNIT_ASSERT(NKikimr::IsMatchesWildcard("", "*"));
+ UNIT_ASSERT(NKikimr::IsMatchesWildcard("", ""));
+ UNIT_ASSERT(!NKikimr::IsMatchesWildcard("some/test/string", "ssome*"));
+ UNIT_ASSERT(!NKikimr::IsMatchesWildcard("some/test/string", "*strring"));
+ UNIT_ASSERT(!NKikimr::IsMatchesWildcard("", "*/test/*"));
+ }
+
Y_UNIT_TEST(TestWildcards) {
- UNIT_ASSERT(NKikimr::IsMatchesWildcards("some/test/string", "ssome*,*strring,*"));
- UNIT_ASSERT(NKikimr::IsMatchesWildcards("some/test/string", "ssome*,*,*strring"));
- UNIT_ASSERT(NKikimr::IsMatchesWildcards("some/test/string", "*,ssome*,*strring"));
- UNIT_ASSERT(NKikimr::IsMatchesWildcards("some/test/string", "ssome*,*/*,*strring"));
- UNIT_ASSERT(NKikimr::IsMatchesWildcards("some/test/string", "ssome*,*/test/*,*strring"));
- }
-}
-
-} // NKikimr
+ UNIT_ASSERT(NKikimr::IsMatchesWildcards("some/test/string", "ssome*,*strring,*"));
+ UNIT_ASSERT(NKikimr::IsMatchesWildcards("some/test/string", "ssome*,*,*strring"));
+ UNIT_ASSERT(NKikimr::IsMatchesWildcards("some/test/string", "*,ssome*,*strring"));
+ UNIT_ASSERT(NKikimr::IsMatchesWildcards("some/test/string", "ssome*,*/*,*strring"));
+ UNIT_ASSERT(NKikimr::IsMatchesWildcards("some/test/string", "ssome*,*/test/*,*strring"));
+ }
+}
+
+} // NKikimr
diff --git a/ydb/core/util/ya.make b/ydb/core/util/ya.make
index 980f4f13b82..4f325d8fcbd 100644
--- a/ydb/core/util/ya.make
+++ b/ydb/core/util/ya.make
@@ -38,14 +38,14 @@ SRCS(
operation_queue.h
page_map.cpp
pb.h
- proto_duration.h
+ proto_duration.h
queue_inplace.h
queue_oneone_inplace.h
- simple_cache.h
+ simple_cache.h
single_thread_ic_mock.cpp
single_thread_ic_mock.h
stlog.h
- templates.h
+ templates.h
testactorsys.cpp
testactorsys.h
text.cpp
@@ -53,11 +53,11 @@ SRCS(
time_series_vec.h
token_bucket.h
throughput_meter.h
- tuples.h
+ tuples.h
type_alias.h
ulid.cpp
ulid.h
- wildcard.h
+ wildcard.h
yverify_stream.h
)
diff --git a/ydb/core/viewer/browse.h b/ydb/core/viewer/browse.h
index 664d1c1d86c..c5716f46a76 100644
--- a/ydb/core/viewer/browse.h
+++ b/ydb/core/viewer/browse.h
@@ -1,4 +1,4 @@
-#pragma once
+#pragma once
#include <library/cpp/actors/core/actor_bootstrapped.h>
#include <library/cpp/actors/core/mon.h>
#include <ydb/core/base/domain.h>
@@ -10,72 +10,72 @@
#include <ydb/core/viewer/protos/viewer.pb.h>
#include <ydb/core/viewer/json/json.h>
#include "browse_events.h"
-#include "viewer.h"
-#include "wb_aggregate.h"
-
-namespace NKikimr {
-namespace NViewer {
-
-using namespace NActors;
-
-class TBrowse : public TActorBootstrapped<TBrowse> {
- static const bool WithRetry = false;
- using TBase = TActorBootstrapped<TBrowse>;
- const IViewer* Viewer;
+#include "viewer.h"
+#include "wb_aggregate.h"
+
+namespace NKikimr {
+namespace NViewer {
+
+using namespace NActors;
+
+class TBrowse : public TActorBootstrapped<TBrowse> {
+ static const bool WithRetry = false;
+ using TBase = TActorBootstrapped<TBrowse>;
+ const IViewer* Viewer;
TActorId Owner;
- ui32 Requests = 0;
- ui32 Responses = 0;
- bool Final = false;
- TString Path;
- NKikimrViewer::TBrowseInfo BrowseInfo;
- NKikimrViewer::TMetaInfo MetaInfo;
- TString CurrentPath; // TStringBuf?
- NKikimrViewer::EObjectType CurrentType;
+ ui32 Requests = 0;
+ ui32 Responses = 0;
+ bool Final = false;
+ TString Path;
+ NKikimrViewer::TBrowseInfo BrowseInfo;
+ NKikimrViewer::TMetaInfo MetaInfo;
+ TString CurrentPath; // TStringBuf?
+ NKikimrViewer::EObjectType CurrentType;
THolder<NSchemeShard::TEvSchemeShard::TEvDescribeSchemeResult> DescribeResult;
THashSet<TActorId> Handlers;
TActorId TxProxy = MakeTxProxyID();
-
-public:
- IViewer::TBrowseContext BrowseContext;
-
+
+public:
+ IViewer::TBrowseContext BrowseContext;
+
static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
return NKikimrServices::TActivity::VIEWER_HANDLER;
- }
-
+ }
+
TBrowse(const IViewer* viewer, const TActorId& owner, const TString& path, const TString& userToken)
- : Viewer(viewer)
- , Owner(owner)
- , Path(path)
- , BrowseContext(owner, userToken)
- {}
-
- static NTabletPipe::TClientConfig InitPipeClientConfig() {
- NTabletPipe::TClientConfig clientConfig;
- if (WithRetry) {
- clientConfig.RetryPolicy = NTabletPipe::TClientRetryPolicy::WithRetries();
- }
- return clientConfig;
- }
-
- static const NTabletPipe::TClientConfig& GetPipeClientConfig() {
- static NTabletPipe::TClientConfig clientConfig = InitPipeClientConfig();
- return clientConfig;
- }
-
+ : Viewer(viewer)
+ , Owner(owner)
+ , Path(path)
+ , BrowseContext(owner, userToken)
+ {}
+
+ static NTabletPipe::TClientConfig InitPipeClientConfig() {
+ NTabletPipe::TClientConfig clientConfig;
+ if (WithRetry) {
+ clientConfig.RetryPolicy = NTabletPipe::TClientRetryPolicy::WithRetries();
+ }
+ return clientConfig;
+ }
+
+ static const NTabletPipe::TClientConfig& GetPipeClientConfig() {
+ static NTabletPipe::TClientConfig clientConfig = InitPipeClientConfig();
+ return clientConfig;
+ }
+
static NKikimrViewer::EObjectType GetPathTypeFromSchemeShardType(NKikimrSchemeOp::EPathType type) {
- switch (type) {
+ switch (type) {
case NKikimrSchemeOp::EPathType::EPathTypeDir:
case NKikimrSchemeOp::EPathType::EPathTypeColumnStore: // TODO
- return NKikimrViewer::EObjectType::Directory;
+ return NKikimrViewer::EObjectType::Directory;
case NKikimrSchemeOp::EPathType::EPathTypeRtmrVolume:
return NKikimrViewer::EObjectType::RtmrVolume;
case NKikimrSchemeOp::EPathType::EPathTypeTable:
case NKikimrSchemeOp::EPathType::EPathTypeColumnTable: // TODO
- return NKikimrViewer::EObjectType::Table;
+ return NKikimrViewer::EObjectType::Table;
case NKikimrSchemeOp::EPathType::EPathTypePersQueueGroup:
- return NKikimrViewer::EObjectType::Topic;
+ return NKikimrViewer::EObjectType::Topic;
case NKikimrSchemeOp::EPathType::EPathTypeSubDomain:
- return NKikimrViewer::EObjectType::SubDomain;
+ return NKikimrViewer::EObjectType::SubDomain;
case NKikimrSchemeOp::EPathType::EPathTypeBlockStoreVolume:
return NKikimrViewer::EObjectType::BlockStoreVolume;
case NKikimrSchemeOp::EPathType::EPathTypeFileStore:
@@ -94,17 +94,17 @@ public:
case NKikimrSchemeOp::EPathType::EPathTypeTableIndex:
case NKikimrSchemeOp::EPathType::EPathTypeInvalid:
Y_UNREACHABLE();
- }
- return NKikimrViewer::EObjectType::Unknown;
- }
-
+ }
+ return NKikimrViewer::EObjectType::Unknown;
+ }
+
TString GetNextName() const {
TString nextName;
- if (CurrentPath.size() < Path.size()) {
- auto pos = CurrentPath.size();
- if (Path[pos] == '/') {
- ++pos;
- }
+ if (CurrentPath.size() < Path.size()) {
+ auto pos = CurrentPath.size();
+ if (Path[pos] == '/') {
+ ++pos;
+ }
if (CurrentType == NKikimrViewer::RtmrTables) {
nextName = Path.substr(pos);
} else {
@@ -114,96 +114,96 @@ public:
}
nextName = Path.substr(pos, end_pos - pos);
- }
- }
+ }
+ }
return nextName;
- }
-
- void FillCommonData(NKikimrViewer::TBrowseInfo& browseInfo, NKikimrViewer::TMetaInfo& metaInfo) {
- browseInfo.SetPath(BrowseContext.Path);
- browseInfo.SetName(BrowseContext.GetMyName());
- browseInfo.SetType(BrowseContext.GetMyType());
- NKikimrViewer::TMetaCommonInfo& pbCommon = *metaInfo.MutableCommon();
- pbCommon.SetPath(BrowseContext.Path);
- pbCommon.SetType(BrowseContext.GetMyType());
- if (DescribeResult != nullptr) {
- const auto& pbRecord(DescribeResult->GetRecord());
- if (pbRecord.HasPathDescription()) {
- const auto& pbPathDescription(pbRecord.GetPathDescription());
- if (pbPathDescription.HasSelf()) {
- const auto& pbSelf(pbPathDescription.GetSelf());
- pbCommon.SetOwner(pbSelf.GetOwner());
- }
- if (pbPathDescription.GetSelf().HasACL()) {
- NACLib::TACL acl(pbPathDescription.GetSelf().GetACL());
- auto& aces(acl.GetACE());
- for (auto it = aces.begin(); it != aces.end(); ++it) {
- const NACLibProto::TACE& ace = *it;
- auto& pbAce = *pbCommon.AddACL();
- if (static_cast<NACLib::EAccessType>(ace.GetAccessType()) == NACLib::EAccessType::Deny) {
- pbAce.SetAccessType("Deny");
- } else
- if (static_cast<NACLib::EAccessType>(ace.GetAccessType()) == NACLib::EAccessType::Allow) {
- pbAce.SetAccessType("Allow");
- }
- auto ar = ace.GetAccessRight();
- if ((ar & NACLib::EAccessRights::SelectRow) != 0) {
- pbAce.AddAccessRights("SelectRow");
- }
- if ((ar & NACLib::EAccessRights::UpdateRow) != 0) {
- pbAce.AddAccessRights("UpdateRow");
- }
- if ((ar & NACLib::EAccessRights::EraseRow) != 0) {
- pbAce.AddAccessRights("EraseRow");
- }
- if ((ar & NACLib::EAccessRights::ReadAttributes) != 0) {
- pbAce.AddAccessRights("ReadAttributes");
- }
- if ((ar & NACLib::EAccessRights::WriteAttributes) != 0) {
- pbAce.AddAccessRights("WriteAttributes");
- }
- if ((ar & NACLib::EAccessRights::CreateDirectory) != 0) {
- pbAce.AddAccessRights("CreateDirectory");
- }
- if ((ar & NACLib::EAccessRights::CreateTable) != 0) {
- pbAce.AddAccessRights("CreateTable");
- }
- if ((ar & NACLib::EAccessRights::CreateQueue) != 0) {
- pbAce.AddAccessRights("CreateQueue");
- }
- if ((ar & NACLib::EAccessRights::RemoveSchema) != 0) {
- pbAce.AddAccessRights("RemoveSchema");
- }
- if ((ar & NACLib::EAccessRights::DescribeSchema) != 0) {
- pbAce.AddAccessRights("DescribeSchema");
- }
- if ((ar & NACLib::EAccessRights::AlterSchema) != 0) {
- pbAce.AddAccessRights("AlterSchema");
- }
- pbAce.SetSubject(ace.GetSID());
- auto inht = ace.GetInheritanceType();
- if ((inht & NACLib::EInheritanceType::InheritObject) != 0) {
- pbAce.AddInheritanceType("InheritObject");
- }
- if ((inht & NACLib::EInheritanceType::InheritContainer) != 0) {
- pbAce.AddInheritanceType("InheritContainer");
- }
- if ((inht & NACLib::EInheritanceType::InheritOnly) != 0) {
- pbAce.AddInheritanceType("InheritOnly");
- }
- }
- }
- }
- }
- }
-
+ }
+
+ void FillCommonData(NKikimrViewer::TBrowseInfo& browseInfo, NKikimrViewer::TMetaInfo& metaInfo) {
+ browseInfo.SetPath(BrowseContext.Path);
+ browseInfo.SetName(BrowseContext.GetMyName());
+ browseInfo.SetType(BrowseContext.GetMyType());
+ NKikimrViewer::TMetaCommonInfo& pbCommon = *metaInfo.MutableCommon();
+ pbCommon.SetPath(BrowseContext.Path);
+ pbCommon.SetType(BrowseContext.GetMyType());
+ if (DescribeResult != nullptr) {
+ const auto& pbRecord(DescribeResult->GetRecord());
+ if (pbRecord.HasPathDescription()) {
+ const auto& pbPathDescription(pbRecord.GetPathDescription());
+ if (pbPathDescription.HasSelf()) {
+ const auto& pbSelf(pbPathDescription.GetSelf());
+ pbCommon.SetOwner(pbSelf.GetOwner());
+ }
+ if (pbPathDescription.GetSelf().HasACL()) {
+ NACLib::TACL acl(pbPathDescription.GetSelf().GetACL());
+ auto& aces(acl.GetACE());
+ for (auto it = aces.begin(); it != aces.end(); ++it) {
+ const NACLibProto::TACE& ace = *it;
+ auto& pbAce = *pbCommon.AddACL();
+ if (static_cast<NACLib::EAccessType>(ace.GetAccessType()) == NACLib::EAccessType::Deny) {
+ pbAce.SetAccessType("Deny");
+ } else
+ if (static_cast<NACLib::EAccessType>(ace.GetAccessType()) == NACLib::EAccessType::Allow) {
+ pbAce.SetAccessType("Allow");
+ }
+ auto ar = ace.GetAccessRight();
+ if ((ar & NACLib::EAccessRights::SelectRow) != 0) {
+ pbAce.AddAccessRights("SelectRow");
+ }
+ if ((ar & NACLib::EAccessRights::UpdateRow) != 0) {
+ pbAce.AddAccessRights("UpdateRow");
+ }
+ if ((ar & NACLib::EAccessRights::EraseRow) != 0) {
+ pbAce.AddAccessRights("EraseRow");
+ }
+ if ((ar & NACLib::EAccessRights::ReadAttributes) != 0) {
+ pbAce.AddAccessRights("ReadAttributes");
+ }
+ if ((ar & NACLib::EAccessRights::WriteAttributes) != 0) {
+ pbAce.AddAccessRights("WriteAttributes");
+ }
+ if ((ar & NACLib::EAccessRights::CreateDirectory) != 0) {
+ pbAce.AddAccessRights("CreateDirectory");
+ }
+ if ((ar & NACLib::EAccessRights::CreateTable) != 0) {
+ pbAce.AddAccessRights("CreateTable");
+ }
+ if ((ar & NACLib::EAccessRights::CreateQueue) != 0) {
+ pbAce.AddAccessRights("CreateQueue");
+ }
+ if ((ar & NACLib::EAccessRights::RemoveSchema) != 0) {
+ pbAce.AddAccessRights("RemoveSchema");
+ }
+ if ((ar & NACLib::EAccessRights::DescribeSchema) != 0) {
+ pbAce.AddAccessRights("DescribeSchema");
+ }
+ if ((ar & NACLib::EAccessRights::AlterSchema) != 0) {
+ pbAce.AddAccessRights("AlterSchema");
+ }
+ pbAce.SetSubject(ace.GetSID());
+ auto inht = ace.GetInheritanceType();
+ if ((inht & NACLib::EInheritanceType::InheritObject) != 0) {
+ pbAce.AddInheritanceType("InheritObject");
+ }
+ if ((inht & NACLib::EInheritanceType::InheritContainer) != 0) {
+ pbAce.AddInheritanceType("InheritContainer");
+ }
+ if ((inht & NACLib::EInheritanceType::InheritOnly) != 0) {
+ pbAce.AddInheritanceType("InheritOnly");
+ }
+ }
+ }
+ }
+ }
+ }
+
void StepOnPath(const TActorContext& ctx, const TString& currentName) {
- switch (CurrentType) {
- case NKikimrViewer::EObjectType::Unknown:
- case NKikimrViewer::EObjectType::Root:
- case NKikimrViewer::EObjectType::Directory:
- case NKikimrViewer::EObjectType::Table:
- {
+ switch (CurrentType) {
+ case NKikimrViewer::EObjectType::Unknown:
+ case NKikimrViewer::EObjectType::Root:
+ case NKikimrViewer::EObjectType::Directory:
+ case NKikimrViewer::EObjectType::Table:
+ {
const auto* domainsInfo = AppData(ctx)->DomainsInfo.Get();
if (!domainsInfo || !TxProxy) {
break;
@@ -218,170 +218,170 @@ public:
if (!hasTxAllocators) {
break;
}
- THolder<TEvTxUserProxy::TEvNavigate> request(new TEvTxUserProxy::TEvNavigate());
- if (!BrowseContext.UserToken.empty()) {
- request->Record.SetUserToken(BrowseContext.UserToken);
- }
+ THolder<TEvTxUserProxy::TEvNavigate> request(new TEvTxUserProxy::TEvNavigate());
+ if (!BrowseContext.UserToken.empty()) {
+ request->Record.SetUserToken(BrowseContext.UserToken);
+ }
NKikimrSchemeOp::TDescribePath* record = request->Record.MutableDescribePath();
- record->SetPath(CurrentPath);
+ record->SetPath(CurrentPath);
ctx.Send(TxProxy, request.Release(), IEventHandle::FlagTrackDelivery);
- ++Requests;
- ctx.Send(BrowseContext.Owner, new NViewerEvents::TEvBrowseRequestSent(TxProxy, TEvTxUserProxy::EvNavigate));
- }
- break;
- default:
- break;
- };
-
- BrowseContext.Path = CurrentPath;
- BrowseContext.Paths.emplace_back(IViewer::TBrowseContext::TPathEntry({CurrentType, currentName}));
-
- auto handlers = Viewer->GetVirtualHandlers(CurrentType, CurrentPath);
- for (const auto* handler : handlers) {
- if (handler->BrowseHandler) {
+ ++Requests;
+ ctx.Send(BrowseContext.Owner, new NViewerEvents::TEvBrowseRequestSent(TxProxy, TEvTxUserProxy::EvNavigate));
+ }
+ break;
+ default:
+ break;
+ };
+
+ BrowseContext.Path = CurrentPath;
+ BrowseContext.Paths.emplace_back(IViewer::TBrowseContext::TPathEntry({CurrentType, currentName}));
+
+ auto handlers = Viewer->GetVirtualHandlers(CurrentType, CurrentPath);
+ for (const auto* handler : handlers) {
+ if (handler->BrowseHandler) {
TActorId browseActor = ctx.RegisterWithSameMailbox(handler->BrowseHandler(ctx.SelfID, BrowseContext));
- Handlers.insert(browseActor);
- ++Requests;
- }
- }
-
- if (Requests == Responses) {
- return ReplyAndDie(ctx);
- }
- }
-
- void NextStep(const TActorContext& ctx) {
+ Handlers.insert(browseActor);
+ ++Requests;
+ }
+ }
+
+ if (Requests == Responses) {
+ return ReplyAndDie(ctx);
+ }
+ }
+
+ void NextStep(const TActorContext& ctx) {
TString currentName = GetNextName();
- if (currentName.empty()) {
- return ReplyAndDie(ctx);
- }
- for (const auto& pbChild : BrowseInfo.GetChildren()) {
- if (pbChild.GetName() == currentName) {
- if (!CurrentPath.EndsWith('/')) {
- CurrentPath += '/';
- }
- CurrentPath += currentName;
- CurrentType = pbChild.GetType();
- Final = pbChild.GetFinal();
- BrowseInfo.Clear();
- MetaInfo.Clear();
+ if (currentName.empty()) {
+ return ReplyAndDie(ctx);
+ }
+ for (const auto& pbChild : BrowseInfo.GetChildren()) {
+ if (pbChild.GetName() == currentName) {
+ if (!CurrentPath.EndsWith('/')) {
+ CurrentPath += '/';
+ }
+ CurrentPath += currentName;
+ CurrentType = pbChild.GetType();
+ Final = pbChild.GetFinal();
+ BrowseInfo.Clear();
+ MetaInfo.Clear();
DescribeResult.Reset();
return StepOnPath(ctx, currentName);
- }
- }
- return HandleBadRequest(ctx, "The path is not found");
- }
-
+ }
+ }
+ return HandleBadRequest(ctx, "The path is not found");
+ }
+
void Handle(NSchemeShard::TEvSchemeShard::TEvDescribeSchemeResult::TPtr &ev, const TActorContext &ctx) {
- DescribeResult.Reset(ev->Release());
- ++Responses;
- ctx.Send(BrowseContext.Owner, new NViewerEvents::TEvBrowseRequestCompleted(TxProxy, TEvTxUserProxy::EvNavigate));
- const auto& pbRecord(DescribeResult->GetRecord());
+ DescribeResult.Reset(ev->Release());
+ ++Responses;
+ ctx.Send(BrowseContext.Owner, new NViewerEvents::TEvBrowseRequestCompleted(TxProxy, TEvTxUserProxy::EvNavigate));
+ const auto& pbRecord(DescribeResult->GetRecord());
if (pbRecord.GetStatus() == NKikimrScheme::EStatus::StatusSuccess) {
- if (pbRecord.HasPathDescription()) {
- const auto& pbPathDescription(pbRecord.GetPathDescription());
- if (pbPathDescription.HasSelf()) {
- const auto& pbChildren(pbPathDescription.GetChildren());
- for (const auto& pbSrcChild : pbChildren) {
- auto& pbDstChild = *BrowseInfo.AddChildren();
- pbDstChild.SetType(GetPathTypeFromSchemeShardType(pbSrcChild.GetPathType()));
- pbDstChild.SetName(pbSrcChild.GetName());
- }
- }
- }
- } else {
- return HandleBadRequest(ctx, "Error getting schema information");
- }
- if (Responses == Requests) {
- NextStep(ctx);
- }
- }
-
+ if (pbRecord.HasPathDescription()) {
+ const auto& pbPathDescription(pbRecord.GetPathDescription());
+ if (pbPathDescription.HasSelf()) {
+ const auto& pbChildren(pbPathDescription.GetChildren());
+ for (const auto& pbSrcChild : pbChildren) {
+ auto& pbDstChild = *BrowseInfo.AddChildren();
+ pbDstChild.SetType(GetPathTypeFromSchemeShardType(pbSrcChild.GetPathType()));
+ pbDstChild.SetName(pbSrcChild.GetName());
+ }
+ }
+ }
+ } else {
+ return HandleBadRequest(ctx, "Error getting schema information");
+ }
+ if (Responses == Requests) {
+ NextStep(ctx);
+ }
+ }
+
void Handle(NViewerEvents::TEvBrowseResponse::TPtr &ev, const TActorContext &ctx) {
- BrowseInfo.MergeFrom(ev->Get()->BrowseInfo);
- MetaInfo.MergeFrom(ev->Get()->MetaInfo);
- ++Responses;
- Handlers.erase(ev->Sender);
- if (Final) {
- // TODO(xenoxeno): it could be a little bit more effective
- BrowseInfo.ClearChildren();
- }
- if (Responses == Requests) {
- NextStep(ctx);
- }
- }
-
- void Bootstrap(const TActorContext& ctx) {
- if (Path.empty()) {
- HandleBadRequest(ctx, "The path is empty");
- return;
- }
- if (!Path.StartsWith('/')) {
- HandleBadRequest(ctx, "The path should start from /");
- return;
- }
- CurrentPath = Path.substr(0, 1);
- CurrentType = NKikimrViewer::EObjectType::Root;
+ BrowseInfo.MergeFrom(ev->Get()->BrowseInfo);
+ MetaInfo.MergeFrom(ev->Get()->MetaInfo);
+ ++Responses;
+ Handlers.erase(ev->Sender);
+ if (Final) {
+ // TODO(xenoxeno): it could be a little bit more effective
+ BrowseInfo.ClearChildren();
+ }
+ if (Responses == Requests) {
+ NextStep(ctx);
+ }
+ }
+
+ void Bootstrap(const TActorContext& ctx) {
+ if (Path.empty()) {
+ HandleBadRequest(ctx, "The path is empty");
+ return;
+ }
+ if (!Path.StartsWith('/')) {
+ HandleBadRequest(ctx, "The path should start from /");
+ return;
+ }
+ CurrentPath = Path.substr(0, 1);
+ CurrentType = NKikimrViewer::EObjectType::Root;
StepOnPath(ctx, "/");
- Become(&TThis::StateWork);
- }
-
- void Die(const TActorContext& ctx) override {
+ Become(&TThis::StateWork);
+ }
+
+ void Die(const TActorContext& ctx) override {
for (const TActorId& actor : Handlers) {
- ctx.Send(actor, new TEvents::TEvPoisonPill());
- }
- TBase::Die(ctx);
- }
-
- STFUNC(StateWork) {
- switch (ev->GetTypeRewrite()) {
+ ctx.Send(actor, new TEvents::TEvPoisonPill());
+ }
+ TBase::Die(ctx);
+ }
+
+ STFUNC(StateWork) {
+ switch (ev->GetTypeRewrite()) {
HFunc(NSchemeShard::TEvSchemeShard::TEvDescribeSchemeResult, Handle);
HFunc(NViewerEvents::TEvBrowseResponse, Handle);
- CFunc(TEvents::TSystem::PoisonPill, HandlePoisonPill);
+ CFunc(TEvents::TSystem::PoisonPill, HandlePoisonPill);
HFunc(TEvents::TEvUndelivered, HandleUndelivered);
- }
- }
-
- void ReplyAndDie(const TActorContext &ctx) {
- FillCommonData(BrowseInfo, MetaInfo);
+ }
+ }
+
+ void ReplyAndDie(const TActorContext &ctx) {
+ FillCommonData(BrowseInfo, MetaInfo);
ctx.Send(Owner, new NViewerEvents::TEvBrowseResponse(std::move(BrowseInfo), std::move(MetaInfo)));
- Die(ctx);
- }
-
- void HandleBadRequest(const TActorContext& ctx, const TString& error) {
- ctx.Send(Owner, new NMon::TEvHttpInfoRes(TString("HTTP/1.1 400 Bad Request\r\n\r\n") + error, 0, NMon::IEvHttpInfoRes::EContentType::Custom));
- Die(ctx);
- }
-
- void HandlePoisonPill(const TActorContext& ctx) {
- Die(ctx);
- }
+ Die(ctx);
+ }
+
+ void HandleBadRequest(const TActorContext& ctx, const TString& error) {
+ ctx.Send(Owner, new NMon::TEvHttpInfoRes(TString("HTTP/1.1 400 Bad Request\r\n\r\n") + error, 0, NMon::IEvHttpInfoRes::EContentType::Custom));
+ Die(ctx);
+ }
+
+ void HandlePoisonPill(const TActorContext& ctx) {
+ Die(ctx);
+ }
void HandleUndelivered(TEvents::TEvUndelivered::TPtr &ev, const TActorContext &ctx) {
if (ev->Get()->SourceType == TEvTxUserProxy::EvNavigate) {
++Responses;
ctx.Send(BrowseContext.Owner, new NViewerEvents::TEvBrowseRequestCompleted(TxProxy, TEvTxUserProxy::EvNavigate));
TxProxy = TActorId(); // do not query this TxProxy any more
- if (Responses == Requests) {
+ if (Responses == Requests) {
NextStep(ctx);
}
}
}
-};
-
-class TBrowseTabletsCommon : public TActorBootstrapped<TBrowseTabletsCommon> {
-protected:
- static const bool WithRetry = false;
- using TBase = TActorBootstrapped<TBrowseTabletsCommon>;
+};
+
+class TBrowseTabletsCommon : public TActorBootstrapped<TBrowseTabletsCommon> {
+protected:
+ static const bool WithRetry = false;
+ using TBase = TActorBootstrapped<TBrowseTabletsCommon>;
TActorId Owner;
THashMap<TTabletId, TActorId> PipeClients;
TSet<TString> Consumers;
TVector<ui64> Tablets;
- ui32 Requests = 0;
- ui32 Responses = 0;
+ ui32 Requests = 0;
+ ui32 Responses = 0;
THolder<NSchemeShard::TEvSchemeShard::TEvDescribeSchemeResult> DescribeResult;
- TString Path;
- IViewer::TBrowseContext BrowseContext;
+ TString Path;
+ IViewer::TBrowseContext BrowseContext;
TMap<TTabletId, THolder<TEvTablet::TEvGetCountersResponse>> TabletCountersResults;
THashMap<ui32, THolder<NKikimrBlobStorage::TEvResponseBSControllerInfo::TBSGroupInfo>> GroupInfo;
THashSet<ui32> ErasureSpecies;
@@ -389,253 +389,253 @@ protected:
THashSet<ui64> VDiskCategories;
THashSet<TNodeId> Nodes;
THashSet<ui32> PDisks;
-
-public:
+
+public:
static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
return NKikimrServices::TActivity::VIEWER_HANDLER;
- }
-
+ }
+
TBrowseTabletsCommon(const TActorId& owner, const IViewer::TBrowseContext& browseContext)
: Owner(owner)
- , Path(browseContext.Path)
- , BrowseContext(browseContext)
- {}
-
- static NTabletPipe::TClientConfig InitPipeClientConfig() {
- NTabletPipe::TClientConfig clientConfig;
- if (WithRetry) {
- clientConfig.RetryPolicy = NTabletPipe::TClientRetryPolicy::WithRetries();
- }
- return clientConfig;
- }
-
- static const NTabletPipe::TClientConfig& GetPipeClientConfig() {
- static NTabletPipe::TClientConfig clientConfig = InitPipeClientConfig();
- return clientConfig;
- }
-
+ , Path(browseContext.Path)
+ , BrowseContext(browseContext)
+ {}
+
+ static NTabletPipe::TClientConfig InitPipeClientConfig() {
+ NTabletPipe::TClientConfig clientConfig;
+ if (WithRetry) {
+ clientConfig.RetryPolicy = NTabletPipe::TClientRetryPolicy::WithRetries();
+ }
+ return clientConfig;
+ }
+
+ static const NTabletPipe::TClientConfig& GetPipeClientConfig() {
+ static NTabletPipe::TClientConfig clientConfig = InitPipeClientConfig();
+ return clientConfig;
+ }
+
const TActorId& GetTabletPipe(TTabletId tabletId, const TActorContext& ctx) {
- auto it = PipeClients.find(tabletId);
- if (it != PipeClients.end()) {
- return it->second;
- }
+ auto it = PipeClients.find(tabletId);
+ if (it != PipeClients.end()) {
+ return it->second;
+ }
TActorId pipeClient = ctx.RegisterWithSameMailbox(NTabletPipe::CreateClient(ctx.SelfID, tabletId, GetPipeClientConfig()));
- return PipeClients.emplace(tabletId, pipeClient).first->second;
- }
-
- TTabletId GetBscTabletId(TTabletId tabletId, const TActorContext& ctx) {
- TDomainsInfo* domainsInfo = AppData(ctx)->DomainsInfo.Get();
- ui64 hiveUid = HiveUidFromTabletID(tabletId);
- ui32 hiveDomain = domainsInfo->GetHiveDomainUid(hiveUid);
- ui64 defaultStateStorageGroup = domainsInfo->GetDefaultStateStorageGroup(hiveDomain);
- TTabletId bscTabletId = MakeBSControllerID(defaultStateStorageGroup);
- return bscTabletId;
- }
-
- void Handle(TEvTablet::TEvGetCountersResponse::TPtr &ev, const TActorContext &ctx) {
- TabletCountersResults.emplace(ev->Cookie, ev->Release());
- ++Responses;
- ctx.Send(BrowseContext.Owner, new NViewerEvents::TEvBrowseRequestCompleted(ev->Sender, ev->Cookie, TEvTablet::EvGetCounters));
- if (Responses == Requests) {
- ReplyAndDie(ctx);
- }
- }
-
- void Handle(TEvHive::TEvChannelInfo::TPtr &ev, const TActorContext &ctx) {
- THolder<TEvHive::TEvChannelInfo> lookupResult = ev->Release();
- for (const auto& channelInfo : lookupResult->Record.GetChannelInfo()) {
- for (const auto& historyInfo : channelInfo.GetHistory()) {
- ui32 groupId = historyInfo.GetGroupID();
- if (GroupInfo.emplace(groupId, nullptr).second) {
- TTabletId bscTabletId = GetBscTabletId(lookupResult->Record.GetTabletID(), ctx);
+ return PipeClients.emplace(tabletId, pipeClient).first->second;
+ }
+
+ TTabletId GetBscTabletId(TTabletId tabletId, const TActorContext& ctx) {
+ TDomainsInfo* domainsInfo = AppData(ctx)->DomainsInfo.Get();
+ ui64 hiveUid = HiveUidFromTabletID(tabletId);
+ ui32 hiveDomain = domainsInfo->GetHiveDomainUid(hiveUid);
+ ui64 defaultStateStorageGroup = domainsInfo->GetDefaultStateStorageGroup(hiveDomain);
+ TTabletId bscTabletId = MakeBSControllerID(defaultStateStorageGroup);
+ return bscTabletId;
+ }
+
+ void Handle(TEvTablet::TEvGetCountersResponse::TPtr &ev, const TActorContext &ctx) {
+ TabletCountersResults.emplace(ev->Cookie, ev->Release());
+ ++Responses;
+ ctx.Send(BrowseContext.Owner, new NViewerEvents::TEvBrowseRequestCompleted(ev->Sender, ev->Cookie, TEvTablet::EvGetCounters));
+ if (Responses == Requests) {
+ ReplyAndDie(ctx);
+ }
+ }
+
+ void Handle(TEvHive::TEvChannelInfo::TPtr &ev, const TActorContext &ctx) {
+ THolder<TEvHive::TEvChannelInfo> lookupResult = ev->Release();
+ for (const auto& channelInfo : lookupResult->Record.GetChannelInfo()) {
+ for (const auto& historyInfo : channelInfo.GetHistory()) {
+ ui32 groupId = historyInfo.GetGroupID();
+ if (GroupInfo.emplace(groupId, nullptr).second) {
+ TTabletId bscTabletId = GetBscTabletId(lookupResult->Record.GetTabletID(), ctx);
TActorId pipeClient = GetTabletPipe(bscTabletId, ctx);
- NTabletPipe::SendData(ctx, pipeClient, new TEvBlobStorage::TEvRequestControllerInfo(groupId));
- ++Requests;
- ctx.Send(BrowseContext.Owner, new NViewerEvents::TEvBrowseRequestSent(pipeClient, TEvBlobStorage::EvRequestControllerInfo));
- }
- }
- }
- ++Responses;
- ctx.Send(BrowseContext.Owner, new NViewerEvents::TEvBrowseRequestCompleted(ev->Sender, TEvHive::EvLookupChannelInfo));
- if (Responses == Requests) {
- ReplyAndDie(ctx);
- }
- }
-
- void Handle(TEvBlobStorage::TEvResponseControllerInfo::TPtr &ev, const TActorContext &ctx) {
- THolder<TEvBlobStorage::TEvResponseControllerInfo> bsResult = ev->Release();
- auto& bsGroupInfo = *bsResult->Record.MutableBSGroupInfo();
-
- while (!bsGroupInfo.empty()) {
+ NTabletPipe::SendData(ctx, pipeClient, new TEvBlobStorage::TEvRequestControllerInfo(groupId));
+ ++Requests;
+ ctx.Send(BrowseContext.Owner, new NViewerEvents::TEvBrowseRequestSent(pipeClient, TEvBlobStorage::EvRequestControllerInfo));
+ }
+ }
+ }
+ ++Responses;
+ ctx.Send(BrowseContext.Owner, new NViewerEvents::TEvBrowseRequestCompleted(ev->Sender, TEvHive::EvLookupChannelInfo));
+ if (Responses == Requests) {
+ ReplyAndDie(ctx);
+ }
+ }
+
+ void Handle(TEvBlobStorage::TEvResponseControllerInfo::TPtr &ev, const TActorContext &ctx) {
+ THolder<TEvBlobStorage::TEvResponseControllerInfo> bsResult = ev->Release();
+ auto& bsGroupInfo = *bsResult->Record.MutableBSGroupInfo();
+
+ while (!bsGroupInfo.empty()) {
THolder<NKikimrBlobStorage::TEvResponseBSControllerInfo::TBSGroupInfo> groupInfo(bsGroupInfo.ReleaseLast());
- ErasureSpecies.insert(groupInfo->GetErasureSpecies());
- for (const auto& vDiskInfo : groupInfo->GetVDiskInfo()) {
- VDiskCategories.insert(vDiskInfo.GetVDiskCategory());
- PDiskCategories.insert(vDiskInfo.GetPDiskCategory());
- Nodes.insert(vDiskInfo.GetNodeId());
- PDisks.insert(vDiskInfo.GetPDiskId());
- }
- GroupInfo[groupInfo->GetGroupId()] = std::move(groupInfo);
- }
- ctx.Send(BrowseContext.Owner, new NViewerEvents::TEvBrowseRequestCompleted(ev->Sender, TEvBlobStorage::EvRequestControllerInfo));
- if (++Responses == Requests) {
- ReplyAndDie(ctx);
- }
- }
-
- static ui64 GetCounterValue(
- const ::google::protobuf::RepeatedPtrField<NKikimrTabletBase::TTabletSimpleCounter>& counters,
- const TString& name) {
- for (const NKikimrTabletBase::TTabletSimpleCounter& counter : counters) {
- if (counter.GetName() == name) {
- return counter.GetValue();
- }
- }
- return 0;
- }
-
- void Die(const TActorContext& ctx) override {
- for (const auto& pr : PipeClients) {
- NTabletPipe::CloseClient(ctx, pr.second);
- }
- TBase::Die(ctx);
- }
-
- void HandleBadRequest(const TActorContext& ctx, const TString& error) {
- ctx.Send(Owner, new NMon::TEvHttpInfoRes(TString("HTTP/1.1 400 Bad Request\r\n\r\n") + error, 0, NMon::IEvHttpInfoRes::EContentType::Custom));
- Die(ctx);
- }
-
- void HandleServerError(const TActorContext& ctx, const TString& error) {
- ctx.Send(Owner, new NMon::TEvHttpInfoRes(TString("HTTP/1.1 500 Internal Server Error\r\n\r\n") + error, 0, NMon::IEvHttpInfoRes::EContentType::Custom));
- Die(ctx);
- }
-
- void HandlePoisonPill(const TActorContext& ctx) {
- Die(ctx);
- }
-
- void FillCommonData(NKikimrViewer::TBrowseInfo& browseInfo, NKikimrViewer::TMetaInfo& metaInfo) {
- browseInfo.SetPath(BrowseContext.Path);
- browseInfo.SetName(BrowseContext.GetMyName());
- browseInfo.SetType(BrowseContext.GetMyType());
- NKikimrViewer::TMetaCommonInfo& pbCommon = *metaInfo.MutableCommon();
- pbCommon.SetPath(BrowseContext.Path);
- pbCommon.SetType(BrowseContext.GetMyType());
- if (DescribeResult != nullptr) {
- const auto& pbRecord(DescribeResult->GetRecord());
- if (pbRecord.HasPathDescription()) {
- const auto& pbPathDescription(pbRecord.GetPathDescription());
- if (pbPathDescription.HasSelf()) {
- const auto& pbSelf(pbPathDescription.GetSelf());
- pbCommon.SetOwner(pbSelf.GetOwner());
- }
- if (pbPathDescription.GetSelf().HasACL()) {
- NACLib::TACL acl(pbPathDescription.GetSelf().GetACL());
- auto& aces(acl.GetACE());
- for (auto it = aces.begin(); it != aces.end(); ++it) {
- const NACLibProto::TACE& ace = *it;
- auto& pbAce = *pbCommon.AddACL();
- if (static_cast<NACLib::EAccessType>(ace.GetAccessType()) == NACLib::EAccessType::Deny) {
- pbAce.SetAccessType("Deny");
- } else
- if (static_cast<NACLib::EAccessType>(ace.GetAccessType()) == NACLib::EAccessType::Allow) {
- pbAce.SetAccessType("Allow");
- }
- auto ar = ace.GetAccessRight();
- if ((ar & NACLib::EAccessRights::SelectRow) != 0) {
- pbAce.AddAccessRights("SelectRow");
- }
- if ((ar & NACLib::EAccessRights::UpdateRow) != 0) {
- pbAce.AddAccessRights("UpdateRow");
- }
- if ((ar & NACLib::EAccessRights::EraseRow) != 0) {
- pbAce.AddAccessRights("EraseRow");
- }
- if ((ar & NACLib::EAccessRights::ReadAttributes) != 0) {
- pbAce.AddAccessRights("ReadAttributes");
- }
- if ((ar & NACLib::EAccessRights::WriteAttributes) != 0) {
- pbAce.AddAccessRights("WriteAttributes");
- }
- if ((ar & NACLib::EAccessRights::CreateDirectory) != 0) {
- pbAce.AddAccessRights("CreateDirectory");
- }
- if ((ar & NACLib::EAccessRights::CreateTable) != 0) {
- pbAce.AddAccessRights("CreateTable");
- }
- if ((ar & NACLib::EAccessRights::CreateQueue) != 0) {
- pbAce.AddAccessRights("CreateQueue");
- }
- if (ar == NACLib::EAccessRights::GenericRead) {
- pbAce.SetAccessRule("Read");
- }
- if (ar == NACLib::EAccessRights::GenericWrite) {
- pbAce.SetAccessRule("Write");
- }
- if (ar == NACLib::EAccessRights::GenericFull) {
- pbAce.SetAccessRule("Full");
- }
- pbAce.SetSubject(ace.GetSID());
- auto inht = ace.GetInheritanceType();
- if ((inht & NACLib::EInheritanceType::InheritObject) != 0) {
- pbAce.AddInheritanceType("InheritObject");
- }
- if ((inht & NACLib::EInheritanceType::InheritContainer) != 0) {
- pbAce.AddInheritanceType("InheritContainer");
- }
- if ((inht & NACLib::EInheritanceType::InheritOnly) != 0) {
- pbAce.AddInheritanceType("InheritOnly");
- }
- }
- }
- }
- }
- pbCommon.SetTablets(Tablets.size());
-
- THolder<TEvTablet::TEvGetCountersResponse> response = AggregateWhiteboardResponses(TabletCountersResults);
-
- ui64 dataSize = 0;
+ ErasureSpecies.insert(groupInfo->GetErasureSpecies());
+ for (const auto& vDiskInfo : groupInfo->GetVDiskInfo()) {
+ VDiskCategories.insert(vDiskInfo.GetVDiskCategory());
+ PDiskCategories.insert(vDiskInfo.GetPDiskCategory());
+ Nodes.insert(vDiskInfo.GetNodeId());
+ PDisks.insert(vDiskInfo.GetPDiskId());
+ }
+ GroupInfo[groupInfo->GetGroupId()] = std::move(groupInfo);
+ }
+ ctx.Send(BrowseContext.Owner, new NViewerEvents::TEvBrowseRequestCompleted(ev->Sender, TEvBlobStorage::EvRequestControllerInfo));
+ if (++Responses == Requests) {
+ ReplyAndDie(ctx);
+ }
+ }
+
+ static ui64 GetCounterValue(
+ const ::google::protobuf::RepeatedPtrField<NKikimrTabletBase::TTabletSimpleCounter>& counters,
+ const TString& name) {
+ for (const NKikimrTabletBase::TTabletSimpleCounter& counter : counters) {
+ if (counter.GetName() == name) {
+ return counter.GetValue();
+ }
+ }
+ return 0;
+ }
+
+ void Die(const TActorContext& ctx) override {
+ for (const auto& pr : PipeClients) {
+ NTabletPipe::CloseClient(ctx, pr.second);
+ }
+ TBase::Die(ctx);
+ }
+
+ void HandleBadRequest(const TActorContext& ctx, const TString& error) {
+ ctx.Send(Owner, new NMon::TEvHttpInfoRes(TString("HTTP/1.1 400 Bad Request\r\n\r\n") + error, 0, NMon::IEvHttpInfoRes::EContentType::Custom));
+ Die(ctx);
+ }
+
+ void HandleServerError(const TActorContext& ctx, const TString& error) {
+ ctx.Send(Owner, new NMon::TEvHttpInfoRes(TString("HTTP/1.1 500 Internal Server Error\r\n\r\n") + error, 0, NMon::IEvHttpInfoRes::EContentType::Custom));
+ Die(ctx);
+ }
+
+ void HandlePoisonPill(const TActorContext& ctx) {
+ Die(ctx);
+ }
+
+ void FillCommonData(NKikimrViewer::TBrowseInfo& browseInfo, NKikimrViewer::TMetaInfo& metaInfo) {
+ browseInfo.SetPath(BrowseContext.Path);
+ browseInfo.SetName(BrowseContext.GetMyName());
+ browseInfo.SetType(BrowseContext.GetMyType());
+ NKikimrViewer::TMetaCommonInfo& pbCommon = *metaInfo.MutableCommon();
+ pbCommon.SetPath(BrowseContext.Path);
+ pbCommon.SetType(BrowseContext.GetMyType());
+ if (DescribeResult != nullptr) {
+ const auto& pbRecord(DescribeResult->GetRecord());
+ if (pbRecord.HasPathDescription()) {
+ const auto& pbPathDescription(pbRecord.GetPathDescription());
+ if (pbPathDescription.HasSelf()) {
+ const auto& pbSelf(pbPathDescription.GetSelf());
+ pbCommon.SetOwner(pbSelf.GetOwner());
+ }
+ if (pbPathDescription.GetSelf().HasACL()) {
+ NACLib::TACL acl(pbPathDescription.GetSelf().GetACL());
+ auto& aces(acl.GetACE());
+ for (auto it = aces.begin(); it != aces.end(); ++it) {
+ const NACLibProto::TACE& ace = *it;
+ auto& pbAce = *pbCommon.AddACL();
+ if (static_cast<NACLib::EAccessType>(ace.GetAccessType()) == NACLib::EAccessType::Deny) {
+ pbAce.SetAccessType("Deny");
+ } else
+ if (static_cast<NACLib::EAccessType>(ace.GetAccessType()) == NACLib::EAccessType::Allow) {
+ pbAce.SetAccessType("Allow");
+ }
+ auto ar = ace.GetAccessRight();
+ if ((ar & NACLib::EAccessRights::SelectRow) != 0) {
+ pbAce.AddAccessRights("SelectRow");
+ }
+ if ((ar & NACLib::EAccessRights::UpdateRow) != 0) {
+ pbAce.AddAccessRights("UpdateRow");
+ }
+ if ((ar & NACLib::EAccessRights::EraseRow) != 0) {
+ pbAce.AddAccessRights("EraseRow");
+ }
+ if ((ar & NACLib::EAccessRights::ReadAttributes) != 0) {
+ pbAce.AddAccessRights("ReadAttributes");
+ }
+ if ((ar & NACLib::EAccessRights::WriteAttributes) != 0) {
+ pbAce.AddAccessRights("WriteAttributes");
+ }
+ if ((ar & NACLib::EAccessRights::CreateDirectory) != 0) {
+ pbAce.AddAccessRights("CreateDirectory");
+ }
+ if ((ar & NACLib::EAccessRights::CreateTable) != 0) {
+ pbAce.AddAccessRights("CreateTable");
+ }
+ if ((ar & NACLib::EAccessRights::CreateQueue) != 0) {
+ pbAce.AddAccessRights("CreateQueue");
+ }
+ if (ar == NACLib::EAccessRights::GenericRead) {
+ pbAce.SetAccessRule("Read");
+ }
+ if (ar == NACLib::EAccessRights::GenericWrite) {
+ pbAce.SetAccessRule("Write");
+ }
+ if (ar == NACLib::EAccessRights::GenericFull) {
+ pbAce.SetAccessRule("Full");
+ }
+ pbAce.SetSubject(ace.GetSID());
+ auto inht = ace.GetInheritanceType();
+ if ((inht & NACLib::EInheritanceType::InheritObject) != 0) {
+ pbAce.AddInheritanceType("InheritObject");
+ }
+ if ((inht & NACLib::EInheritanceType::InheritContainer) != 0) {
+ pbAce.AddInheritanceType("InheritContainer");
+ }
+ if ((inht & NACLib::EInheritanceType::InheritOnly) != 0) {
+ pbAce.AddInheritanceType("InheritOnly");
+ }
+ }
+ }
+ }
+ }
+ pbCommon.SetTablets(Tablets.size());
+
+ THolder<TEvTablet::TEvGetCountersResponse> response = AggregateWhiteboardResponses(TabletCountersResults);
+
+ ui64 dataSize = 0;
dataSize += GetCounterValue(response->Record.GetTabletCounters().GetExecutorCounters().GetSimpleCounters(), "LogRedoMemory");
dataSize += GetCounterValue(response->Record.GetTabletCounters().GetExecutorCounters().GetSimpleCounters(), "DbIndexBytes");
dataSize += GetCounterValue(response->Record.GetTabletCounters().GetExecutorCounters().GetSimpleCounters(), "DbDataBytes");
- dataSize += GetCounterValue(response->Record.GetTabletCounters().GetAppCounters().GetSimpleCounters(), "KV/RecordBytes");
- dataSize += GetCounterValue(response->Record.GetTabletCounters().GetAppCounters().GetSimpleCounters(), "KV/TrashBytes");
- pbCommon.SetDataSize(dataSize);
-
- ui64 memSize = 0;
+ dataSize += GetCounterValue(response->Record.GetTabletCounters().GetAppCounters().GetSimpleCounters(), "KV/RecordBytes");
+ dataSize += GetCounterValue(response->Record.GetTabletCounters().GetAppCounters().GetSimpleCounters(), "KV/TrashBytes");
+ pbCommon.SetDataSize(dataSize);
+
+ ui64 memSize = 0;
memSize += GetCounterValue(response->Record.GetTabletCounters().GetExecutorCounters().GetSimpleCounters(), "DbWarmBytes"); // not cache
- memSize += GetCounterValue(response->Record.GetTabletCounters().GetExecutorCounters().GetSimpleCounters(), "CacheFreshSize"); // cache
- memSize += GetCounterValue(response->Record.GetTabletCounters().GetExecutorCounters().GetSimpleCounters(), "CacheStagingSize"); // cache
- memSize += GetCounterValue(response->Record.GetTabletCounters().GetExecutorCounters().GetSimpleCounters(), "CacheWarmSize"); // cache
- pbCommon.SetMemorySize(memSize);
-
- for (auto erasure : ErasureSpecies) {
- pbCommon.AddErasureSpecies(TErasureType::ErasureSpeciesName(erasure));
- }
-
- for (auto pDiskKind : PDiskCategories) {
+ memSize += GetCounterValue(response->Record.GetTabletCounters().GetExecutorCounters().GetSimpleCounters(), "CacheFreshSize"); // cache
+ memSize += GetCounterValue(response->Record.GetTabletCounters().GetExecutorCounters().GetSimpleCounters(), "CacheStagingSize"); // cache
+ memSize += GetCounterValue(response->Record.GetTabletCounters().GetExecutorCounters().GetSimpleCounters(), "CacheWarmSize"); // cache
+ pbCommon.SetMemorySize(memSize);
+
+ for (auto erasure : ErasureSpecies) {
+ pbCommon.AddErasureSpecies(TErasureType::ErasureSpeciesName(erasure));
+ }
+
+ for (auto pDiskKind : PDiskCategories) {
pbCommon.AddPDiskKind(TPDiskCategory(pDiskKind).TypeStrShort());
- }
-
- for (auto vDiskKind : VDiskCategories) {
- pbCommon.AddVDiskKind(NKikimrBlobStorage::TVDiskKind::EVDiskKind_Name(static_cast<NKikimrBlobStorage::TVDiskKind::EVDiskKind>(vDiskKind)));
- }
-
- for (auto nodeId : Nodes) {
- pbCommon.AddNodes(nodeId);
- }
-
- for (auto pDiskId : PDisks) {
- pbCommon.AddDisks(pDiskId);
- }
-
- metaInfo.MutableCounters()->CopyFrom(response->Record.GetTabletCounters());
- }
-
- virtual void Bootstrap(const TActorContext& ctx) = 0;
- virtual void ReplyAndDie(const TActorContext &ctx) = 0;
-};
-
-}
-}
+ }
+
+ for (auto vDiskKind : VDiskCategories) {
+ pbCommon.AddVDiskKind(NKikimrBlobStorage::TVDiskKind::EVDiskKind_Name(static_cast<NKikimrBlobStorage::TVDiskKind::EVDiskKind>(vDiskKind)));
+ }
+
+ for (auto nodeId : Nodes) {
+ pbCommon.AddNodes(nodeId);
+ }
+
+ for (auto pDiskId : PDisks) {
+ pbCommon.AddDisks(pDiskId);
+ }
+
+ metaInfo.MutableCounters()->CopyFrom(response->Record.GetTabletCounters());
+ }
+
+ virtual void Bootstrap(const TActorContext& ctx) = 0;
+ virtual void ReplyAndDie(const TActorContext &ctx) = 0;
+};
+
+}
+}
diff --git a/ydb/core/viewer/browse_db.h b/ydb/core/viewer/browse_db.h
index 537feef0df3..fe7b5d31408 100644
--- a/ydb/core/viewer/browse_db.h
+++ b/ydb/core/viewer/browse_db.h
@@ -1,4 +1,4 @@
-#pragma once
+#pragma once
#include <library/cpp/actors/core/actor_bootstrapped.h>
#include <library/cpp/actors/core/mon.h>
#include <ydb/core/base/tablet.h>
@@ -8,166 +8,166 @@
#include <ydb/core/tx/tx_proxy/proxy.h>
#include <ydb/core/viewer/protos/viewer.pb.h>
#include <ydb/core/viewer/json/json.h>
-#include "viewer.h"
-#include "browse.h"
-#include "wb_aggregate.h"
-
-namespace NKikimr {
-namespace NViewerDB {
-
-using namespace NViewer;
-using namespace NActors;
-
-class TBrowseTable : public TBrowseTabletsCommon {
-protected:
- static const bool WithRetry = false;
- using TThis = TBrowseTable;
- using TBase = TBrowseTabletsCommon;
+#include "viewer.h"
+#include "browse.h"
+#include "wb_aggregate.h"
+
+namespace NKikimr {
+namespace NViewerDB {
+
+using namespace NViewer;
+using namespace NActors;
+
+class TBrowseTable : public TBrowseTabletsCommon {
+protected:
+ static const bool WithRetry = false;
+ using TThis = TBrowseTable;
+ using TBase = TBrowseTabletsCommon;
TActorId TxProxy = MakeTxProxyID();
-
-public:
+
+public:
TBrowseTable(const TActorId& owner, const IViewer::TBrowseContext& browseContext)
: TBrowseTabletsCommon(owner, browseContext)
- {}
-
+ {}
+
void Handle(NSchemeShard::TEvSchemeShard::TEvDescribeSchemeResult::TPtr &ev, const TActorContext &ctx) {
- DescribeResult.Reset(ev->Release());
- ++Responses;
- ctx.Send(BrowseContext.Owner, new NViewerEvents::TEvBrowseRequestCompleted(TxProxy, TEvTxUserProxy::EvNavigate));
- const auto& pbRecord(DescribeResult->GetRecord());
+ DescribeResult.Reset(ev->Release());
+ ++Responses;
+ ctx.Send(BrowseContext.Owner, new NViewerEvents::TEvBrowseRequestCompleted(TxProxy, TEvTxUserProxy::EvNavigate));
+ const auto& pbRecord(DescribeResult->GetRecord());
if (pbRecord.GetStatus() == NKikimrScheme::EStatus::StatusSuccess) {
- if (pbRecord.HasPathDescription()) {
- const auto& pbPathDescription(pbRecord.GetPathDescription());
+ if (pbRecord.HasPathDescription()) {
+ const auto& pbPathDescription(pbRecord.GetPathDescription());
TVector<ui64> tablets;
- tablets.reserve(pbPathDescription.TablePartitionsSize());
- for (const auto& partition : pbPathDescription.GetTablePartitions()) {
- tablets.emplace_back(partition.GetDatashardId());
- }
- if (!tablets.empty()) {
- Sort(tablets);
- tablets.erase(std::unique(tablets.begin(), tablets.end()), tablets.end());
- SendTabletRequests(tablets, ctx);
- std::copy(tablets.begin(), tablets.end(), std::back_inserter(Tablets));
- }
- }
- } else {
- switch (DescribeResult->GetRecord().GetStatus()) {
+ tablets.reserve(pbPathDescription.TablePartitionsSize());
+ for (const auto& partition : pbPathDescription.GetTablePartitions()) {
+ tablets.emplace_back(partition.GetDatashardId());
+ }
+ if (!tablets.empty()) {
+ Sort(tablets);
+ tablets.erase(std::unique(tablets.begin(), tablets.end()), tablets.end());
+ SendTabletRequests(tablets, ctx);
+ std::copy(tablets.begin(), tablets.end(), std::back_inserter(Tablets));
+ }
+ }
+ } else {
+ switch (DescribeResult->GetRecord().GetStatus()) {
case NKikimrScheme::EStatus::StatusPathDoesNotExist:
- return HandleBadRequest(ctx, "The path is not found");
- default:
- return HandleBadRequest(ctx, "Error getting schema information");
- }
- }
- if (Responses == Requests) {
- ReplyAndDie(ctx);
- }
- }
-
+ return HandleBadRequest(ctx, "The path is not found");
+ default:
+ return HandleBadRequest(ctx, "Error getting schema information");
+ }
+ }
+ if (Responses == Requests) {
+ ReplyAndDie(ctx);
+ }
+ }
+
void SendTabletRequests(const TVector<TTabletId>& tablets, const TActorContext& ctx) {
- TDomainsInfo* domainsInfo = AppData(ctx)->DomainsInfo.Get();
- for (auto tabletId : tablets) {
+ TDomainsInfo* domainsInfo = AppData(ctx)->DomainsInfo.Get();
+ for (auto tabletId : tablets) {
TActorId pipeClient = GetTabletPipe(tabletId, ctx);
- NTabletPipe::SendData(ctx, pipeClient, new TEvTablet::TEvGetCounters(), tabletId);
- ++Requests;
- ctx.Send(BrowseContext.Owner, new NViewerEvents::TEvBrowseRequestSent(TxProxy, tabletId, TEvTablet::EvGetCounters));
- auto hiveUid = HiveUidFromTabletID(tabletId);
- auto hiveTabletId = domainsInfo->GetHive(hiveUid);
- pipeClient = GetTabletPipe(hiveTabletId, ctx);
- NTabletPipe::SendData(ctx, pipeClient, new TEvHive::TEvLookupChannelInfo(tabletId), tabletId);
- ++Requests;
- ctx.Send(BrowseContext.Owner, new NViewerEvents::TEvBrowseRequestSent(pipeClient, TEvHive::EvLookupChannelInfo));
- }
- }
-
- STFUNC(StateWork) {
- switch (ev->GetTypeRewrite()) {
+ NTabletPipe::SendData(ctx, pipeClient, new TEvTablet::TEvGetCounters(), tabletId);
+ ++Requests;
+ ctx.Send(BrowseContext.Owner, new NViewerEvents::TEvBrowseRequestSent(TxProxy, tabletId, TEvTablet::EvGetCounters));
+ auto hiveUid = HiveUidFromTabletID(tabletId);
+ auto hiveTabletId = domainsInfo->GetHive(hiveUid);
+ pipeClient = GetTabletPipe(hiveTabletId, ctx);
+ NTabletPipe::SendData(ctx, pipeClient, new TEvHive::TEvLookupChannelInfo(tabletId), tabletId);
+ ++Requests;
+ ctx.Send(BrowseContext.Owner, new NViewerEvents::TEvBrowseRequestSent(pipeClient, TEvHive::EvLookupChannelInfo));
+ }
+ }
+
+ STFUNC(StateWork) {
+ switch (ev->GetTypeRewrite()) {
HFunc(NSchemeShard::TEvSchemeShard::TEvDescribeSchemeResult, Handle);
- HFunc(TEvTablet::TEvGetCountersResponse, TBase::Handle);
- HFunc(TEvHive::TEvChannelInfo, TBase::Handle);
- HFunc(TEvBlobStorage::TEvResponseControllerInfo, TBase::Handle);
- CFunc(TEvents::TSystem::PoisonPill, HandlePoisonPill);
- }
- }
-
- void Handle(TEvBlobStorage::TEvResponseControllerInfo::TPtr &ev, const TActorContext &ctx) {
- THolder<TEvBlobStorage::TEvResponseControllerInfo> bsResult = ev->Release();
- auto& bsGroupInfo = *bsResult->Record.MutableBSGroupInfo();
-
- while (!bsGroupInfo.empty()) {
+ HFunc(TEvTablet::TEvGetCountersResponse, TBase::Handle);
+ HFunc(TEvHive::TEvChannelInfo, TBase::Handle);
+ HFunc(TEvBlobStorage::TEvResponseControllerInfo, TBase::Handle);
+ CFunc(TEvents::TSystem::PoisonPill, HandlePoisonPill);
+ }
+ }
+
+ void Handle(TEvBlobStorage::TEvResponseControllerInfo::TPtr &ev, const TActorContext &ctx) {
+ THolder<TEvBlobStorage::TEvResponseControllerInfo> bsResult = ev->Release();
+ auto& bsGroupInfo = *bsResult->Record.MutableBSGroupInfo();
+
+ while (!bsGroupInfo.empty()) {
THolder<NKikimrBlobStorage::TEvResponseBSControllerInfo::TBSGroupInfo> groupInfo(bsGroupInfo.ReleaseLast());
- ErasureSpecies.insert(groupInfo->GetErasureSpecies());
- for (const auto& vDiskInfo : groupInfo->GetVDiskInfo()) {
- VDiskCategories.insert(vDiskInfo.GetVDiskCategory());
- PDiskCategories.insert(vDiskInfo.GetPDiskCategory());
- Nodes.insert(vDiskInfo.GetNodeId());
- PDisks.insert(vDiskInfo.GetPDiskId());
- }
- GroupInfo[groupInfo->GetGroupId()] = std::move(groupInfo);
- }
- ctx.Send(BrowseContext.Owner, new NViewerEvents::TEvBrowseRequestCompleted(ev->Sender, TEvBlobStorage::EvRequestControllerInfo));
- if (++Responses == Requests) {
- ReplyAndDie(ctx);
- }
- }
-
- virtual void Bootstrap(const TActorContext& ctx) override {
- THolder<TEvTxUserProxy::TEvNavigate> request(new TEvTxUserProxy::TEvNavigate());
- if (!BrowseContext.UserToken.empty()) {
- request->Record.SetUserToken(BrowseContext.UserToken);
- }
+ ErasureSpecies.insert(groupInfo->GetErasureSpecies());
+ for (const auto& vDiskInfo : groupInfo->GetVDiskInfo()) {
+ VDiskCategories.insert(vDiskInfo.GetVDiskCategory());
+ PDiskCategories.insert(vDiskInfo.GetPDiskCategory());
+ Nodes.insert(vDiskInfo.GetNodeId());
+ PDisks.insert(vDiskInfo.GetPDiskId());
+ }
+ GroupInfo[groupInfo->GetGroupId()] = std::move(groupInfo);
+ }
+ ctx.Send(BrowseContext.Owner, new NViewerEvents::TEvBrowseRequestCompleted(ev->Sender, TEvBlobStorage::EvRequestControllerInfo));
+ if (++Responses == Requests) {
+ ReplyAndDie(ctx);
+ }
+ }
+
+ virtual void Bootstrap(const TActorContext& ctx) override {
+ THolder<TEvTxUserProxy::TEvNavigate> request(new TEvTxUserProxy::TEvNavigate());
+ if (!BrowseContext.UserToken.empty()) {
+ request->Record.SetUserToken(BrowseContext.UserToken);
+ }
NKikimrSchemeOp::TDescribePath* record = request->Record.MutableDescribePath();
- record->SetPath(Path);
- record->SetBackupInfo(true);
- request->Record.SetUserToken(BrowseContext.UserToken);
- ctx.Send(TxProxy, request.Release());
- ++Requests;
- Become(&TThis::StateWork);
- }
-
- virtual void ReplyAndDie(const TActorContext &ctx) override {
- NKikimrViewer::TBrowseInfo browseInfo;
- NKikimrViewer::TMetaInfo metaInfo;
- NKikimrViewer::TMetaCommonInfo& pbCommon = *metaInfo.MutableCommon();
- FillCommonData(browseInfo, metaInfo);
- if (DescribeResult != nullptr) {
- const auto& pbRecord(DescribeResult->GetRecord());
- if (pbRecord.HasPathDescription()) {
- const auto& pbPathDescription(pbRecord.GetPathDescription());
- if (pbPathDescription.HasSelf()) {
- const auto& pbSelf(pbPathDescription.GetSelf());
- pbCommon.SetOwner(pbSelf.GetOwner());
- if (pbSelf.GetCreateStep() != 0) {
- pbCommon.SetCreateTime(pbSelf.GetCreateStep());
- }
- }
- if (pbPathDescription.HasTable()) {
- const auto& pbTable(pbPathDescription.GetTable());
- if (pbTable.HasUniformPartitionsCount()) {
- pbCommon.SetPartitions(pbTable.GetUniformPartitionsCount());
- }
- if (pbTable.SplitBoundarySize() > 0) {
- pbCommon.SetPartitions(pbTable.SplitBoundarySize() + 1);
- }
- if (pbTable.ColumnsSize() > 0) {
- NKikimrViewer::TMetaTableInfo& pbMetaTable = *metaInfo.MutableTable();
- for (const auto& column : pbTable.GetColumns()) {
- auto& pbSchema = *pbMetaTable.AddSchema();
- pbSchema.SetName(column.GetName());
- pbSchema.SetType(column.GetType());
- for (ui32 keyId : pbTable.GetKeyColumnIds()) {
- if (keyId == column.GetId()) {
- pbSchema.SetKey(true);
- break;
- }
- }
- }
- }
- }
- if (pbPathDescription.HasTableStats()) {
- const auto& pbTableStats(pbPathDescription.GetTableStats());
- pbCommon.SetRowCount(pbTableStats.GetRowCount());
- pbCommon.SetAccessTime(pbTableStats.GetLastAccessTime());
- pbCommon.SetUpdateTime(pbTableStats.GetLastUpdateTime());
+ record->SetPath(Path);
+ record->SetBackupInfo(true);
+ request->Record.SetUserToken(BrowseContext.UserToken);
+ ctx.Send(TxProxy, request.Release());
+ ++Requests;
+ Become(&TThis::StateWork);
+ }
+
+ virtual void ReplyAndDie(const TActorContext &ctx) override {
+ NKikimrViewer::TBrowseInfo browseInfo;
+ NKikimrViewer::TMetaInfo metaInfo;
+ NKikimrViewer::TMetaCommonInfo& pbCommon = *metaInfo.MutableCommon();
+ FillCommonData(browseInfo, metaInfo);
+ if (DescribeResult != nullptr) {
+ const auto& pbRecord(DescribeResult->GetRecord());
+ if (pbRecord.HasPathDescription()) {
+ const auto& pbPathDescription(pbRecord.GetPathDescription());
+ if (pbPathDescription.HasSelf()) {
+ const auto& pbSelf(pbPathDescription.GetSelf());
+ pbCommon.SetOwner(pbSelf.GetOwner());
+ if (pbSelf.GetCreateStep() != 0) {
+ pbCommon.SetCreateTime(pbSelf.GetCreateStep());
+ }
+ }
+ if (pbPathDescription.HasTable()) {
+ const auto& pbTable(pbPathDescription.GetTable());
+ if (pbTable.HasUniformPartitionsCount()) {
+ pbCommon.SetPartitions(pbTable.GetUniformPartitionsCount());
+ }
+ if (pbTable.SplitBoundarySize() > 0) {
+ pbCommon.SetPartitions(pbTable.SplitBoundarySize() + 1);
+ }
+ if (pbTable.ColumnsSize() > 0) {
+ NKikimrViewer::TMetaTableInfo& pbMetaTable = *metaInfo.MutableTable();
+ for (const auto& column : pbTable.GetColumns()) {
+ auto& pbSchema = *pbMetaTable.AddSchema();
+ pbSchema.SetName(column.GetName());
+ pbSchema.SetType(column.GetType());
+ for (ui32 keyId : pbTable.GetKeyColumnIds()) {
+ if (keyId == column.GetId()) {
+ pbSchema.SetKey(true);
+ break;
+ }
+ }
+ }
+ }
+ }
+ if (pbPathDescription.HasTableStats()) {
+ const auto& pbTableStats(pbPathDescription.GetTableStats());
+ pbCommon.SetRowCount(pbTableStats.GetRowCount());
+ pbCommon.SetAccessTime(pbTableStats.GetLastAccessTime());
+ pbCommon.SetUpdateTime(pbTableStats.GetLastUpdateTime());
pbCommon.SetImmediateTxCompleted(pbTableStats.GetImmediateTxCompleted());
pbCommon.SetPlannedTxCompleted(pbTableStats.GetPlannedTxCompleted());
pbCommon.SetTxRejectedByOverload(pbTableStats.GetTxRejectedByOverload());
@@ -178,26 +178,26 @@ public:
pbCommon.SetRowReads(pbTableStats.GetRowReads());
pbCommon.SetRangeReads(pbTableStats.GetRangeReads());
pbCommon.SetRangeReadRows(pbTableStats.GetRangeReadRows());
- }
- if (pbPathDescription.HasTabletMetrics()) {
- const auto& pbTabletMetrics(pbPathDescription.GetTabletMetrics());
- auto& pbResources(*pbCommon.MutableResources());
- pbResources.SetCPU(pbTabletMetrics.GetCPU());
- pbResources.SetMemory(pbTabletMetrics.GetMemory());
- pbResources.SetNetwork(pbTabletMetrics.GetNetwork());
- pbResources.SetStorage(pbTabletMetrics.GetStorage());
- pbResources.SetReadThroughput(pbTabletMetrics.GetReadThroughput());
- pbResources.SetWriteThroughput(pbTabletMetrics.GetWriteThroughput());
- }
- pbCommon.MutableBackup()->MutableLastResults()->CopyFrom(pbPathDescription.GetLastBackupResult());
- pbCommon.MutableBackup()->MutableProgress()->CopyFrom(pbPathDescription.GetBackupProgress());
- }
- }
-
+ }
+ if (pbPathDescription.HasTabletMetrics()) {
+ const auto& pbTabletMetrics(pbPathDescription.GetTabletMetrics());
+ auto& pbResources(*pbCommon.MutableResources());
+ pbResources.SetCPU(pbTabletMetrics.GetCPU());
+ pbResources.SetMemory(pbTabletMetrics.GetMemory());
+ pbResources.SetNetwork(pbTabletMetrics.GetNetwork());
+ pbResources.SetStorage(pbTabletMetrics.GetStorage());
+ pbResources.SetReadThroughput(pbTabletMetrics.GetReadThroughput());
+ pbResources.SetWriteThroughput(pbTabletMetrics.GetWriteThroughput());
+ }
+ pbCommon.MutableBackup()->MutableLastResults()->CopyFrom(pbPathDescription.GetLastBackupResult());
+ pbCommon.MutableBackup()->MutableProgress()->CopyFrom(pbPathDescription.GetBackupProgress());
+ }
+ }
+
ctx.Send(Owner, new NViewerEvents::TEvBrowseResponse(std::move(browseInfo), std::move(metaInfo)));
- Die(ctx);
- }
-};
-
-}
-}
+ Die(ctx);
+ }
+};
+
+}
+}
diff --git a/ydb/core/viewer/browse_events.h b/ydb/core/viewer/browse_events.h
index 96856ed9823..96ced773938 100644
--- a/ydb/core/viewer/browse_events.h
+++ b/ydb/core/viewer/browse_events.h
@@ -12,15 +12,15 @@ namespace NViewer {
namespace NViewerEvents {
enum EEv {
EvBrowseResponse = EventSpaceBegin(TKikimrEvents::ES_VIEWER),
- EvBrowseRequestSent,
- EvBrowseRequestCompleted,
+ EvBrowseRequestSent,
+ EvBrowseRequestCompleted,
EvEnd
};
static_assert(EvEnd < EventSpaceEnd(TKikimrEvents::ES_VIEWER), "expected EvEnd < EventSpaceEnd");
- using TTabletId = ui64;
-
+ using TTabletId = ui64;
+
struct TEvBrowseResponse : TEventLocal<TEvBrowseResponse, EvBrowseResponse> {
TEvBrowseResponse(
NKikimrViewer::TBrowseInfo&& browseInfo,
@@ -38,42 +38,42 @@ namespace NViewerEvents {
NKikimrViewer::TMetaInfo MetaInfo;
TString Error;
};
-
- struct TEvBrowseRequestSent : TEventLocal<TEvBrowseRequestSent, EvBrowseRequestSent> {
+
+ struct TEvBrowseRequestSent : TEventLocal<TEvBrowseRequestSent, EvBrowseRequestSent> {
TActorId Actor;
- TTabletId Tablet;
- ui32 Event;
-
+ TTabletId Tablet;
+ ui32 Event;
+
TEvBrowseRequestSent(const TActorId& actor, TTabletId tablet, ui32 event)
- : Actor(actor)
- , Tablet(tablet)
- , Event(event)
- {}
-
+ : Actor(actor)
+ , Tablet(tablet)
+ , Event(event)
+ {}
+
TEvBrowseRequestSent(const TActorId& actor, ui32 event)
- : Actor(actor)
- , Tablet(0)
- , Event(event)
- {}
- };
-
- struct TEvBrowseRequestCompleted : TEventLocal<TEvBrowseRequestCompleted, EvBrowseRequestCompleted> {
+ : Actor(actor)
+ , Tablet(0)
+ , Event(event)
+ {}
+ };
+
+ struct TEvBrowseRequestCompleted : TEventLocal<TEvBrowseRequestCompleted, EvBrowseRequestCompleted> {
TActorId Actor;
- TTabletId Tablet;
- ui32 Event;
-
+ TTabletId Tablet;
+ ui32 Event;
+
TEvBrowseRequestCompleted(const TActorId& actor, TTabletId tablet, ui32 event)
- : Actor(actor)
- , Tablet(tablet)
- , Event(event)
- {}
-
+ : Actor(actor)
+ , Tablet(tablet)
+ , Event(event)
+ {}
+
TEvBrowseRequestCompleted(const TActorId& actor, ui32 event)
- : Actor(actor)
- , Tablet(0)
- , Event(event)
- {}
- };
+ : Actor(actor)
+ , Tablet(0)
+ , Event(event)
+ {}
+ };
} // namespace NViewerEvents
} // namespace NViewer
diff --git a/ydb/core/viewer/browse_pq.h b/ydb/core/viewer/browse_pq.h
index b3605c3a522..3e3b32a21e3 100644
--- a/ydb/core/viewer/browse_pq.h
+++ b/ydb/core/viewer/browse_pq.h
@@ -1,4 +1,4 @@
-#pragma once
+#pragma once
#include <library/cpp/actors/core/actor_bootstrapped.h>
#include <library/cpp/actors/core/mon.h>
#include <ydb/core/base/tablet.h>
@@ -9,415 +9,415 @@
#include <ydb/core/tx/tx_proxy/proxy.h>
#include <ydb/core/viewer/protos/viewer.pb.h>
#include <ydb/core/viewer/json/json.h>
-#include "viewer.h"
-#include "browse.h"
-#include "wb_aggregate.h"
-
-namespace NKikimr {
-namespace NViewerPQ {
-
-using namespace NViewer;
-using namespace NActors;
-
-class TBrowseRoot : public TActorBootstrapped<TBrowseRoot> {
- using TBase = TActorBootstrapped<TBrowseRoot>;
+#include "viewer.h"
+#include "browse.h"
+#include "wb_aggregate.h"
+
+namespace NKikimr {
+namespace NViewerPQ {
+
+using namespace NViewer;
+using namespace NActors;
+
+class TBrowseRoot : public TActorBootstrapped<TBrowseRoot> {
+ using TBase = TActorBootstrapped<TBrowseRoot>;
TActorId Owner;
-
-public:
+
+public:
static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
return NKikimrServices::TActivity::VIEWER_HANDLER;
- }
-
+ }
+
TBrowseRoot(const TActorId& owner, const IViewer::TBrowseContext&)
- : Owner(owner)
- {}
-
- void Bootstrap(const TActorContext& ctx) {
- NKikimrViewer::TBrowseInfo browseInfo;
- NKikimrViewer::TMetaInfo metaInfo;
- NKikimrViewer::TBrowseInfo& pbConsumers = *browseInfo.AddChildren();
- pbConsumers.SetType(NKikimrViewer::EObjectType::Consumers);
- pbConsumers.SetName("Consumers");
+ : Owner(owner)
+ {}
+
+ void Bootstrap(const TActorContext& ctx) {
+ NKikimrViewer::TBrowseInfo browseInfo;
+ NKikimrViewer::TMetaInfo metaInfo;
+ NKikimrViewer::TBrowseInfo& pbConsumers = *browseInfo.AddChildren();
+ pbConsumers.SetType(NKikimrViewer::EObjectType::Consumers);
+ pbConsumers.SetName("Consumers");
ctx.Send(Owner, new NViewerEvents::TEvBrowseResponse(std::move(browseInfo), std::move(metaInfo)));
- Die(ctx);
- }
-};
-
-class TBrowseCommon : public TBrowseTabletsCommon {
-protected:
- using TThis = TBrowseCommon;
- using TBase = TBrowseTabletsCommon;
- const TString PQ_ROOT_PATH;
+ Die(ctx);
+ }
+};
+
+class TBrowseCommon : public TBrowseTabletsCommon {
+protected:
+ using TThis = TBrowseCommon;
+ using TBase = TBrowseTabletsCommon;
+ const TString PQ_ROOT_PATH;
TSet<TString> Consumers;
- struct TTopicInfo : NKikimrViewer::TMetaTopicInfo {
+ struct TTopicInfo : NKikimrViewer::TMetaTopicInfo {
TMap<i32, THolder<TEvPersQueue::TEvPartitionClientInfoResponse>> PartitionResults;
TMap<i32, NKikimrViewer::TMetaTopicPartitionInfo> PartitionInfo;
- };
+ };
TMap<TString, TTopicInfo> Topics;
TMultiMap<TTabletId, i32> TabletPartitions;
TMap<TTabletId, TTopicInfo*> TabletTopic;
THashMap<TString, NKikimrViewer::TMetaTopicConsumerInfo> ConsumerInfo;
- TString FilterTopic;
- TString FilterConsumer;
+ TString FilterTopic;
+ TString FilterConsumer;
TActorId TxProxy = MakeTxProxyID();
-
-public:
+
+public:
TBrowseCommon(const TActorId& owner, const IViewer::TBrowseContext& browseContext)
: TBrowseTabletsCommon(owner, browseContext)
- , PQ_ROOT_PATH("/Root/PQ") // TODO(xenoxeno)
- {}
-
+ , PQ_ROOT_PATH("/Root/PQ") // TODO(xenoxeno)
+ {}
+
void Handle(NSchemeShard::TEvSchemeShard::TEvDescribeSchemeResult::TPtr &ev, const TActorContext &ctx) {
- DescribeResult.Reset(ev->Release());
- ++Responses;
- ctx.Send(BrowseContext.Owner, new NViewerEvents::TEvBrowseRequestCompleted(TxProxy, TEvTxUserProxy::EvNavigate));
- const auto& pbRecord(DescribeResult->GetRecord());
+ DescribeResult.Reset(ev->Release());
+ ++Responses;
+ ctx.Send(BrowseContext.Owner, new NViewerEvents::TEvBrowseRequestCompleted(TxProxy, TEvTxUserProxy::EvNavigate));
+ const auto& pbRecord(DescribeResult->GetRecord());
if (pbRecord.GetStatus() == NKikimrScheme::EStatus::StatusSuccess) {
- if (pbRecord.HasPathDescription()) {
- const auto& pbPathDescription(pbRecord.GetPathDescription());
+ if (pbRecord.HasPathDescription()) {
+ const auto& pbPathDescription(pbRecord.GetPathDescription());
TVector<ui64> tablets;
- if (pbPathDescription.HasPersQueueGroup()) {
- const auto& pbPersQueueGroup = pbPathDescription.GetPersQueueGroup();
- TTopicInfo* topicInfo = &Topics[GetTopicName(pbRecord.GetPath())];
- tablets.reserve(pbPersQueueGroup.PartitionsSize());
- for (const auto& partition : pbPersQueueGroup.GetPartitions()) {
- TTabletId tabletId = partition.GetTabletId();
- tablets.emplace_back(tabletId);
- TabletTopic.emplace(tabletId, topicInfo);
- TabletPartitions.emplace(tabletId, partition.GetPartitionId());
- }
- }
- if (!tablets.empty()) {
- Sort(tablets);
- tablets.erase(std::unique(tablets.begin(), tablets.end()), tablets.end());
- SendTabletRequests(tablets, ctx);
- std::copy(tablets.begin(), tablets.end(), std::back_inserter(Tablets));
- }
- }
- } else {
- switch (DescribeResult->GetRecord().GetStatus()) {
+ if (pbPathDescription.HasPersQueueGroup()) {
+ const auto& pbPersQueueGroup = pbPathDescription.GetPersQueueGroup();
+ TTopicInfo* topicInfo = &Topics[GetTopicName(pbRecord.GetPath())];
+ tablets.reserve(pbPersQueueGroup.PartitionsSize());
+ for (const auto& partition : pbPersQueueGroup.GetPartitions()) {
+ TTabletId tabletId = partition.GetTabletId();
+ tablets.emplace_back(tabletId);
+ TabletTopic.emplace(tabletId, topicInfo);
+ TabletPartitions.emplace(tabletId, partition.GetPartitionId());
+ }
+ }
+ if (!tablets.empty()) {
+ Sort(tablets);
+ tablets.erase(std::unique(tablets.begin(), tablets.end()), tablets.end());
+ SendTabletRequests(tablets, ctx);
+ std::copy(tablets.begin(), tablets.end(), std::back_inserter(Tablets));
+ }
+ }
+ } else {
+ switch (DescribeResult->GetRecord().GetStatus()) {
case NKikimrScheme::EStatus::StatusPathDoesNotExist:
- return HandleBadRequest(ctx, "The path is not found");
- default:
- return HandleBadRequest(ctx, "Error getting schema information");
- }
- }
- const auto& pbDescribeResult(DescribeResult->GetRecord());
- if (pbDescribeResult.HasPathDescription()) {
- const auto& pbPathDescription(pbDescribeResult.GetPathDescription());
- if (pbPathDescription.HasSelf()) {
- const auto& pbChildren(pbPathDescription.GetChildren());
- for (const auto& pbChild : pbChildren) {
+ return HandleBadRequest(ctx, "The path is not found");
+ default:
+ return HandleBadRequest(ctx, "Error getting schema information");
+ }
+ }
+ const auto& pbDescribeResult(DescribeResult->GetRecord());
+ if (pbDescribeResult.HasPathDescription()) {
+ const auto& pbPathDescription(pbDescribeResult.GetPathDescription());
+ if (pbPathDescription.HasSelf()) {
+ const auto& pbChildren(pbPathDescription.GetChildren());
+ for (const auto& pbChild : pbChildren) {
if (pbChild.GetPathType() == NKikimrSchemeOp::EPathType::EPathTypePersQueueGroup) {
- THolder<TEvTxUserProxy::TEvNavigate> request(new TEvTxUserProxy::TEvNavigate());
- if (!BrowseContext.UserToken.empty()) {
- request->Record.SetUserToken(BrowseContext.UserToken);
- }
+ THolder<TEvTxUserProxy::TEvNavigate> request(new TEvTxUserProxy::TEvNavigate());
+ if (!BrowseContext.UserToken.empty()) {
+ request->Record.SetUserToken(BrowseContext.UserToken);
+ }
NKikimrSchemeOp::TDescribePath* record = request->Record.MutableDescribePath();
- record->SetPath(pbDescribeResult.GetPath() + "/" + pbChild.GetName());
- ctx.Send(TxProxy, request.Release());
- ++Requests;
- ctx.Send(BrowseContext.Owner, new NViewerEvents::TEvBrowseRequestSent(TxProxy, TEvTxUserProxy::EvNavigate));
- }
- }
- }
- }
- if (Responses == Requests) {
- ReplyAndDie(ctx);
- }
- }
-
+ record->SetPath(pbDescribeResult.GetPath() + "/" + pbChild.GetName());
+ ctx.Send(TxProxy, request.Release());
+ ++Requests;
+ ctx.Send(BrowseContext.Owner, new NViewerEvents::TEvBrowseRequestSent(TxProxy, TEvTxUserProxy::EvNavigate));
+ }
+ }
+ }
+ }
+ if (Responses == Requests) {
+ ReplyAndDie(ctx);
+ }
+ }
+
void SendTabletRequests(const TVector<TTabletId>& tablets, const TActorContext& ctx) {
- TDomainsInfo* domainsInfo = AppData(ctx)->DomainsInfo.Get();
- for (auto tabletId : tablets) {
+ TDomainsInfo* domainsInfo = AppData(ctx)->DomainsInfo.Get();
+ for (auto tabletId : tablets) {
TActorId pipeClient = GetTabletPipe(tabletId, ctx);
- const auto& range = TabletPartitions.equal_range(tabletId);
- if (range.first != range.second) {
- TAutoPtr<TEvPersQueue::TEvPartitionClientInfo> request = new TEvPersQueue::TEvPartitionClientInfo();
- for (auto it = range.first; it != range.second; ++it) {
- request->Record.AddPartitions(it->second);
- ++Requests; // because we are waiting for individual partition responses
- }
- NTabletPipe::SendData(ctx, pipeClient, request.Release(), tabletId);
- ctx.Send(BrowseContext.Owner, new NViewerEvents::TEvBrowseRequestSent(pipeClient, tabletId, TEvPersQueue::EvPartitionClientInfo));
- }
- pipeClient = GetTabletPipe(tabletId, ctx);
- NTabletPipe::SendData(ctx, pipeClient, new TEvTablet::TEvGetCounters(), tabletId);
- ++Requests;
- ctx.Send(BrowseContext.Owner, new NViewerEvents::TEvBrowseRequestSent(pipeClient, tabletId, TEvTablet::EvGetCounters));
- auto hiveUid = HiveUidFromTabletID(tabletId);
- auto hiveTabletId = domainsInfo->GetHive(hiveUid);
- pipeClient = GetTabletPipe(hiveTabletId, ctx);
- NTabletPipe::SendData(ctx, pipeClient, new TEvHive::TEvLookupChannelInfo(tabletId), tabletId);
- ++Requests;
- ctx.Send(BrowseContext.Owner, new NViewerEvents::TEvBrowseRequestSent(pipeClient, hiveTabletId, TEvHive::EvLookupChannelInfo));
- }
- }
-
- STFUNC(StateWork) {
- switch (ev->GetTypeRewrite()) {
+ const auto& range = TabletPartitions.equal_range(tabletId);
+ if (range.first != range.second) {
+ TAutoPtr<TEvPersQueue::TEvPartitionClientInfo> request = new TEvPersQueue::TEvPartitionClientInfo();
+ for (auto it = range.first; it != range.second; ++it) {
+ request->Record.AddPartitions(it->second);
+ ++Requests; // because we are waiting for individual partition responses
+ }
+ NTabletPipe::SendData(ctx, pipeClient, request.Release(), tabletId);
+ ctx.Send(BrowseContext.Owner, new NViewerEvents::TEvBrowseRequestSent(pipeClient, tabletId, TEvPersQueue::EvPartitionClientInfo));
+ }
+ pipeClient = GetTabletPipe(tabletId, ctx);
+ NTabletPipe::SendData(ctx, pipeClient, new TEvTablet::TEvGetCounters(), tabletId);
+ ++Requests;
+ ctx.Send(BrowseContext.Owner, new NViewerEvents::TEvBrowseRequestSent(pipeClient, tabletId, TEvTablet::EvGetCounters));
+ auto hiveUid = HiveUidFromTabletID(tabletId);
+ auto hiveTabletId = domainsInfo->GetHive(hiveUid);
+ pipeClient = GetTabletPipe(hiveTabletId, ctx);
+ NTabletPipe::SendData(ctx, pipeClient, new TEvHive::TEvLookupChannelInfo(tabletId), tabletId);
+ ++Requests;
+ ctx.Send(BrowseContext.Owner, new NViewerEvents::TEvBrowseRequestSent(pipeClient, hiveTabletId, TEvHive::EvLookupChannelInfo));
+ }
+ }
+
+ STFUNC(StateWork) {
+ switch (ev->GetTypeRewrite()) {
HFunc(NSchemeShard::TEvSchemeShard::TEvDescribeSchemeResult, Handle);
- HFunc(TEvTablet::TEvGetCountersResponse, TBase::Handle);
- HFunc(TEvPersQueue::TEvPartitionClientInfoResponse, Handle);
- HFunc(TEvHive::TEvChannelInfo, TBase::Handle);
- HFunc(TEvBlobStorage::TEvResponseControllerInfo, TBase::Handle);
- CFunc(TEvents::TSystem::PoisonPill, HandlePoisonPill);
- }
- }
-
- TString GetTopicName(const TString& name) {
- if (name.StartsWith(PQ_ROOT_PATH)) {
- return name.substr(PQ_ROOT_PATH.size() + 1);
- }
- return name;
- }
-
- void Handle(TEvPersQueue::TEvPartitionClientInfoResponse::TPtr &ev, const TActorContext &ctx) {
- auto it = TabletTopic.find(ev->Cookie); // by tablet id
- if (it != TabletTopic.end()) {
- it->second->PartitionResults.emplace(ev->Get()->Record.GetPartition(), ev->Release());
- }
- if (++Responses == Requests) {
- ReplyAndDie(ctx);
- }
- }
-
- static void UpdateMaximum(NKikimrViewer::TMetaTopicLagInfo& destination, const NKikimrViewer::TMetaTopicLagInfo& source) {
- if (source.GetCreateTime() != 0
- && (destination.GetCreateTime() == 0 || destination.GetCreateTime() < source.GetCreateTime())) {
- destination.SetCreateTime(source.GetCreateTime());
- }
- if (source.GetWriteTime() != 0
- && (destination.GetWriteTime() != 0 || destination.GetWriteTime() < source.GetWriteTime())) {
- destination.SetWriteTime(source.GetWriteTime());
- }
- if (source.GetMessages() != 0
- && (destination.GetMessages() != 0 || destination.GetMessages() < source.GetMessages())) {
- destination.SetMessages(source.GetMessages());
- }
- if (source.GetSize() != 0
- && (destination.GetSize() == 0 || destination.GetSize() < source.GetSize())) {
- destination.SetSize(source.GetSize());
- }
- }
-
- void AggregatePartitionResults() {
- for (auto& it : Topics) {
- if (!FilterTopic.empty() && FilterTopic != it.first) {
- continue;
- }
- TTopicInfo& topic(it.second);
- for (const auto& pr : topic.PartitionResults) {
- const NKikimrPQ::TClientInfoResponse& pbPartitionInfo(pr.second->Record);
- auto partition = pbPartitionInfo.GetPartition();
- if (!pbPartitionInfo.HasStartOffset() || !pbPartitionInfo.HasEndOffset()) {
- // partition wasn't found ?
- continue;
- }
- for (const NKikimrPQ::TClientInfo& pbClientInfo : pbPartitionInfo.GetClientInfo()) {
- const TString& client = pbClientInfo.GetClientId();
- if (!FilterConsumer.empty() && FilterConsumer != client) {
- continue;
- }
- NKikimrViewer::TMetaTopicLagInfo committedLags;
- NKikimrViewer::TMetaTopicLagInfo readLags;
- const auto& writePos = pbClientInfo.GetWritePosition();
- ui64 writeLag = pbPartitionInfo.GetEndOffset() - writePos.GetOffset();
- committedLags.SetMessages(writeLag);
- if (writeLag != 0) {
- committedLags.SetSize(writePos.GetSize());
- if (writePos.HasCreateTimestamp()) {
- committedLags.SetCreateTime(pbPartitionInfo.GetResponseTimestamp() - writePos.GetCreateTimestamp());
- }
- committedLags.SetWriteTime(pbPartitionInfo.GetResponseTimestamp() - writePos.GetWriteTimestamp());
- }
- const auto& readPos = pbClientInfo.GetReadPosition();
- ui64 readLag = pbPartitionInfo.GetEndOffset() - readPos.GetOffset();
- readLags.SetMessages(readLag);
- if (readLag != 0) {
- readLags.SetSize(readPos.GetSize());
- if (readPos.HasCreateTimestamp()) {
- readLags.SetCreateTime(pbPartitionInfo.GetResponseTimestamp() - readPos.GetCreateTimestamp());
- }
- readLags.SetWriteTime(pbPartitionInfo.GetResponseTimestamp() - readPos.GetWriteTimestamp());
- }
- auto itConsumerInfo = ConsumerInfo.find(client);
- if (itConsumerInfo == ConsumerInfo.end()) {
- itConsumerInfo = ConsumerInfo.emplace(client, NKikimrViewer::TMetaTopicConsumerInfo()).first;
- itConsumerInfo->second.SetName(client);
- }
- NKikimrViewer::TMetaTopicPartitionInfo& pbPartition = topic.PartitionInfo[partition];
- pbPartition.SetPartition(partition);
- UpdateMaximum(*itConsumerInfo->second.MutableCommittedLags(), committedLags);
- UpdateMaximum(*itConsumerInfo->second.MutableLastReadLags(), readLags);
- UpdateMaximum(*pbPartition.MutableCommittedLags(), committedLags);
- UpdateMaximum(*pbPartition.MutableLastReadLags(), readLags);
- UpdateMaximum(*topic.MutableCommittedLags(), committedLags);
- UpdateMaximum(*topic.MutableLastReadLags(), readLags);
- }
- }
- }
- }
-
- void Bootstrap(const TActorContext& ctx) override {
- // TODO: select correct TX proxy
- THolder<TEvTxUserProxy::TEvNavigate> request(new TEvTxUserProxy::TEvNavigate());
- if (!BrowseContext.UserToken.empty()) {
- request->Record.SetUserToken(BrowseContext.UserToken);
- }
+ HFunc(TEvTablet::TEvGetCountersResponse, TBase::Handle);
+ HFunc(TEvPersQueue::TEvPartitionClientInfoResponse, Handle);
+ HFunc(TEvHive::TEvChannelInfo, TBase::Handle);
+ HFunc(TEvBlobStorage::TEvResponseControllerInfo, TBase::Handle);
+ CFunc(TEvents::TSystem::PoisonPill, HandlePoisonPill);
+ }
+ }
+
+ TString GetTopicName(const TString& name) {
+ if (name.StartsWith(PQ_ROOT_PATH)) {
+ return name.substr(PQ_ROOT_PATH.size() + 1);
+ }
+ return name;
+ }
+
+ void Handle(TEvPersQueue::TEvPartitionClientInfoResponse::TPtr &ev, const TActorContext &ctx) {
+ auto it = TabletTopic.find(ev->Cookie); // by tablet id
+ if (it != TabletTopic.end()) {
+ it->second->PartitionResults.emplace(ev->Get()->Record.GetPartition(), ev->Release());
+ }
+ if (++Responses == Requests) {
+ ReplyAndDie(ctx);
+ }
+ }
+
+ static void UpdateMaximum(NKikimrViewer::TMetaTopicLagInfo& destination, const NKikimrViewer::TMetaTopicLagInfo& source) {
+ if (source.GetCreateTime() != 0
+ && (destination.GetCreateTime() == 0 || destination.GetCreateTime() < source.GetCreateTime())) {
+ destination.SetCreateTime(source.GetCreateTime());
+ }
+ if (source.GetWriteTime() != 0
+ && (destination.GetWriteTime() != 0 || destination.GetWriteTime() < source.GetWriteTime())) {
+ destination.SetWriteTime(source.GetWriteTime());
+ }
+ if (source.GetMessages() != 0
+ && (destination.GetMessages() != 0 || destination.GetMessages() < source.GetMessages())) {
+ destination.SetMessages(source.GetMessages());
+ }
+ if (source.GetSize() != 0
+ && (destination.GetSize() == 0 || destination.GetSize() < source.GetSize())) {
+ destination.SetSize(source.GetSize());
+ }
+ }
+
+ void AggregatePartitionResults() {
+ for (auto& it : Topics) {
+ if (!FilterTopic.empty() && FilterTopic != it.first) {
+ continue;
+ }
+ TTopicInfo& topic(it.second);
+ for (const auto& pr : topic.PartitionResults) {
+ const NKikimrPQ::TClientInfoResponse& pbPartitionInfo(pr.second->Record);
+ auto partition = pbPartitionInfo.GetPartition();
+ if (!pbPartitionInfo.HasStartOffset() || !pbPartitionInfo.HasEndOffset()) {
+ // partition wasn't found ?
+ continue;
+ }
+ for (const NKikimrPQ::TClientInfo& pbClientInfo : pbPartitionInfo.GetClientInfo()) {
+ const TString& client = pbClientInfo.GetClientId();
+ if (!FilterConsumer.empty() && FilterConsumer != client) {
+ continue;
+ }
+ NKikimrViewer::TMetaTopicLagInfo committedLags;
+ NKikimrViewer::TMetaTopicLagInfo readLags;
+ const auto& writePos = pbClientInfo.GetWritePosition();
+ ui64 writeLag = pbPartitionInfo.GetEndOffset() - writePos.GetOffset();
+ committedLags.SetMessages(writeLag);
+ if (writeLag != 0) {
+ committedLags.SetSize(writePos.GetSize());
+ if (writePos.HasCreateTimestamp()) {
+ committedLags.SetCreateTime(pbPartitionInfo.GetResponseTimestamp() - writePos.GetCreateTimestamp());
+ }
+ committedLags.SetWriteTime(pbPartitionInfo.GetResponseTimestamp() - writePos.GetWriteTimestamp());
+ }
+ const auto& readPos = pbClientInfo.GetReadPosition();
+ ui64 readLag = pbPartitionInfo.GetEndOffset() - readPos.GetOffset();
+ readLags.SetMessages(readLag);
+ if (readLag != 0) {
+ readLags.SetSize(readPos.GetSize());
+ if (readPos.HasCreateTimestamp()) {
+ readLags.SetCreateTime(pbPartitionInfo.GetResponseTimestamp() - readPos.GetCreateTimestamp());
+ }
+ readLags.SetWriteTime(pbPartitionInfo.GetResponseTimestamp() - readPos.GetWriteTimestamp());
+ }
+ auto itConsumerInfo = ConsumerInfo.find(client);
+ if (itConsumerInfo == ConsumerInfo.end()) {
+ itConsumerInfo = ConsumerInfo.emplace(client, NKikimrViewer::TMetaTopicConsumerInfo()).first;
+ itConsumerInfo->second.SetName(client);
+ }
+ NKikimrViewer::TMetaTopicPartitionInfo& pbPartition = topic.PartitionInfo[partition];
+ pbPartition.SetPartition(partition);
+ UpdateMaximum(*itConsumerInfo->second.MutableCommittedLags(), committedLags);
+ UpdateMaximum(*itConsumerInfo->second.MutableLastReadLags(), readLags);
+ UpdateMaximum(*pbPartition.MutableCommittedLags(), committedLags);
+ UpdateMaximum(*pbPartition.MutableLastReadLags(), readLags);
+ UpdateMaximum(*topic.MutableCommittedLags(), committedLags);
+ UpdateMaximum(*topic.MutableLastReadLags(), readLags);
+ }
+ }
+ }
+ }
+
+ void Bootstrap(const TActorContext& ctx) override {
+ // TODO: select correct TX proxy
+ THolder<TEvTxUserProxy::TEvNavigate> request(new TEvTxUserProxy::TEvNavigate());
+ if (!BrowseContext.UserToken.empty()) {
+ request->Record.SetUserToken(BrowseContext.UserToken);
+ }
NKikimrSchemeOp::TDescribePath* record = request->Record.MutableDescribePath();
- TString path(PQ_ROOT_PATH);
- if (!FilterTopic.empty()) {
- path += '/';
- path += FilterTopic;
- }
- record->SetPath(path);
- ctx.Send(TxProxy, request.Release());
- ++Requests;
- ctx.Send(BrowseContext.Owner, new NViewerEvents::TEvBrowseRequestSent(TxProxy, TEvTxUserProxy::EvNavigate));
- Become(&TThis::StateWork);
- }
-
+ TString path(PQ_ROOT_PATH);
+ if (!FilterTopic.empty()) {
+ path += '/';
+ path += FilterTopic;
+ }
+ record->SetPath(path);
+ ctx.Send(TxProxy, request.Release());
+ ++Requests;
+ ctx.Send(BrowseContext.Owner, new NViewerEvents::TEvBrowseRequestSent(TxProxy, TEvTxUserProxy::EvNavigate));
+ Become(&TThis::StateWork);
+ }
+
void ReplyAndDie(const TActorContext &ctx) override = 0;
-};
-
-class TBrowseConsumers : public TBrowseCommon {
-public:
+};
+
+class TBrowseConsumers : public TBrowseCommon {
+public:
static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
return NKikimrServices::TActivity::VIEWER_HANDLER;
- }
-
+ }
+
TBrowseConsumers(const TActorId& owner, const IViewer::TBrowseContext& browseContext)
: TBrowseCommon(owner, browseContext)
- {}
-
- void ReplyAndDie(const TActorContext &ctx) {
- NKikimrViewer::TBrowseInfo browseInfo;
- NKikimrViewer::TMetaInfo metaInfo;
- FillCommonData(browseInfo, metaInfo);
- AggregatePartitionResults();
- for (const auto& pr : ConsumerInfo) {
- NKikimrViewer::TBrowseInfo& pbConsumer = *browseInfo.AddChildren();
- pbConsumer.SetType(NKikimrViewer::EObjectType::Consumer);
- pbConsumer.SetName(pr.first);
- }
+ {}
+
+ void ReplyAndDie(const TActorContext &ctx) {
+ NKikimrViewer::TBrowseInfo browseInfo;
+ NKikimrViewer::TMetaInfo metaInfo;
+ FillCommonData(browseInfo, metaInfo);
+ AggregatePartitionResults();
+ for (const auto& pr : ConsumerInfo) {
+ NKikimrViewer::TBrowseInfo& pbConsumer = *browseInfo.AddChildren();
+ pbConsumer.SetType(NKikimrViewer::EObjectType::Consumer);
+ pbConsumer.SetName(pr.first);
+ }
ctx.Send(Owner, new NViewerEvents::TEvBrowseResponse(std::move(browseInfo), std::move(metaInfo)));
- Die(ctx);
- }
-};
-
-class TBrowseConsumer : public TBrowseCommon {
-public:
+ Die(ctx);
+ }
+};
+
+class TBrowseConsumer : public TBrowseCommon {
+public:
TBrowseConsumer(const TActorId& owner, const IViewer::TBrowseContext& browseContext)
: TBrowseCommon(owner, browseContext)
- {
- FilterConsumer = BrowseContext.GetMyName();
- if (BrowseContext.GetParentType() == NKikimrViewer::EObjectType::Topic) {
- FilterTopic = BrowseContext.GetParentName();
- }
- }
-
- void ReplyAndDie(const TActorContext &ctx) {
- NKikimrViewer::TBrowseInfo browseInfo;
- NKikimrViewer::TMetaInfo metaInfo;
- FillCommonData(browseInfo, metaInfo);
- AggregatePartitionResults();
- for (const auto& pr : Topics) {
- NKikimrViewer::TBrowseInfo& pbTopic = *browseInfo.AddChildren();
- pbTopic.SetType(NKikimrViewer::EObjectType::Topic);
- pbTopic.SetName(pr.first);
- pbTopic.SetFinal(true);
- }
- if (ConsumerInfo.size() == 1) {
- const NKikimrViewer::TMetaTopicConsumerInfo& consumer = ConsumerInfo.begin()->second;
- NKikimrViewer::TMetaTopicConsumerInfo& pbMetaConsumer = *metaInfo.MutableConsumer();
- pbMetaConsumer.MutableCommittedLags()->MergeFrom(consumer.GetCommittedLags());
- pbMetaConsumer.MutableLastReadLags()->MergeFrom(consumer.GetLastReadLags());
- for (const auto& pr : Topics) {
- auto& pbTopic = *pbMetaConsumer.AddTopics();
- pbTopic.SetName(pr.first);
- pbTopic.MergeFrom(pr.second);
- }
- if (!FilterTopic.empty()) {
- if (!Topics.empty() && pbMetaConsumer.TopicsSize() > 0) {
- TTopicInfo& topic = Topics.begin()->second;
- auto& pbMetaTopic = *pbMetaConsumer.MutableTopics(0);
- for (const auto& pr : topic.PartitionInfo) {
- auto& pbPartition = *pbMetaTopic.AddPartitions();
- pbPartition.MergeFrom(pr.second);
- }
- }
- }
- }
+ {
+ FilterConsumer = BrowseContext.GetMyName();
+ if (BrowseContext.GetParentType() == NKikimrViewer::EObjectType::Topic) {
+ FilterTopic = BrowseContext.GetParentName();
+ }
+ }
+
+ void ReplyAndDie(const TActorContext &ctx) {
+ NKikimrViewer::TBrowseInfo browseInfo;
+ NKikimrViewer::TMetaInfo metaInfo;
+ FillCommonData(browseInfo, metaInfo);
+ AggregatePartitionResults();
+ for (const auto& pr : Topics) {
+ NKikimrViewer::TBrowseInfo& pbTopic = *browseInfo.AddChildren();
+ pbTopic.SetType(NKikimrViewer::EObjectType::Topic);
+ pbTopic.SetName(pr.first);
+ pbTopic.SetFinal(true);
+ }
+ if (ConsumerInfo.size() == 1) {
+ const NKikimrViewer::TMetaTopicConsumerInfo& consumer = ConsumerInfo.begin()->second;
+ NKikimrViewer::TMetaTopicConsumerInfo& pbMetaConsumer = *metaInfo.MutableConsumer();
+ pbMetaConsumer.MutableCommittedLags()->MergeFrom(consumer.GetCommittedLags());
+ pbMetaConsumer.MutableLastReadLags()->MergeFrom(consumer.GetLastReadLags());
+ for (const auto& pr : Topics) {
+ auto& pbTopic = *pbMetaConsumer.AddTopics();
+ pbTopic.SetName(pr.first);
+ pbTopic.MergeFrom(pr.second);
+ }
+ if (!FilterTopic.empty()) {
+ if (!Topics.empty() && pbMetaConsumer.TopicsSize() > 0) {
+ TTopicInfo& topic = Topics.begin()->second;
+ auto& pbMetaTopic = *pbMetaConsumer.MutableTopics(0);
+ for (const auto& pr : topic.PartitionInfo) {
+ auto& pbPartition = *pbMetaTopic.AddPartitions();
+ pbPartition.MergeFrom(pr.second);
+ }
+ }
+ }
+ }
ctx.Send(Owner, new NViewerEvents::TEvBrowseResponse(std::move(browseInfo), std::move(metaInfo)));
- Die(ctx);
- }
-};
-
-class TBrowseTopic : public TBrowseCommon {
-public:
+ Die(ctx);
+ }
+};
+
+class TBrowseTopic : public TBrowseCommon {
+public:
TBrowseTopic(const TActorId& owner, const IViewer::TBrowseContext& browseContext)
: TBrowseCommon(owner, browseContext)
- {
- FilterTopic = BrowseContext.GetMyName();
- if (BrowseContext.GetParentType() == NKikimrViewer::EObjectType::Consumer) {
- FilterConsumer = BrowseContext.GetParentName();
- }
- }
-
- void ReplyAndDie(const TActorContext &ctx) {
- NKikimrViewer::TBrowseInfo browseInfo;
- NKikimrViewer::TMetaInfo metaInfo;
- FillCommonData(browseInfo, metaInfo);
- AggregatePartitionResults();
- for (const auto& pr : ConsumerInfo) {
- NKikimrViewer::TBrowseInfo& pbConsumer = *browseInfo.AddChildren();
- pbConsumer.SetType(NKikimrViewer::EObjectType::Consumer);
- pbConsumer.SetName(pr.first);
- pbConsumer.SetFinal(true);
- }
- if (DescribeResult != nullptr) {
- const auto& pbRecord(DescribeResult->GetRecord());
- if (pbRecord.HasPathDescription()) {
- const auto& pbPathDescription(pbRecord.GetPathDescription());
- if (pbPathDescription.HasPersQueueGroup()) {
- const auto& pbPersQueueGroup(pbPathDescription.GetPersQueueGroup());
- NKikimrViewer::TMetaCommonInfo& pbCommon = *metaInfo.MutableCommon();
+ {
+ FilterTopic = BrowseContext.GetMyName();
+ if (BrowseContext.GetParentType() == NKikimrViewer::EObjectType::Consumer) {
+ FilterConsumer = BrowseContext.GetParentName();
+ }
+ }
+
+ void ReplyAndDie(const TActorContext &ctx) {
+ NKikimrViewer::TBrowseInfo browseInfo;
+ NKikimrViewer::TMetaInfo metaInfo;
+ FillCommonData(browseInfo, metaInfo);
+ AggregatePartitionResults();
+ for (const auto& pr : ConsumerInfo) {
+ NKikimrViewer::TBrowseInfo& pbConsumer = *browseInfo.AddChildren();
+ pbConsumer.SetType(NKikimrViewer::EObjectType::Consumer);
+ pbConsumer.SetName(pr.first);
+ pbConsumer.SetFinal(true);
+ }
+ if (DescribeResult != nullptr) {
+ const auto& pbRecord(DescribeResult->GetRecord());
+ if (pbRecord.HasPathDescription()) {
+ const auto& pbPathDescription(pbRecord.GetPathDescription());
+ if (pbPathDescription.HasPersQueueGroup()) {
+ const auto& pbPersQueueGroup(pbPathDescription.GetPersQueueGroup());
+ NKikimrViewer::TMetaCommonInfo& pbCommon = *metaInfo.MutableCommon();
if (pbPersQueueGroup.PartitionsSize()) {
pbCommon.SetPartitions(pbPersQueueGroup.PartitionsSize());
- }
- if (pbPersQueueGroup.HasPQTabletConfig()) {
- const auto& pbPQTabletConfig(pbPersQueueGroup.GetPQTabletConfig());
- if (pbPQTabletConfig.HasPartitionConfig()) {
- const auto& pbPartitionConfig(pbPQTabletConfig.GetPartitionConfig());
- NKikimrViewer::TMetaTopicInfo& pbMetaTopic = *metaInfo.MutableTopic();
- pbMetaTopic.MutablePartitionConfig()->SetMaxCountInPartition(pbPartitionConfig.GetMaxCountInPartition());
- pbMetaTopic.MutablePartitionConfig()->SetMaxSizeInPartition(pbPartitionConfig.GetMaxSizeInPartition());
- pbMetaTopic.MutablePartitionConfig()->SetLifetimeSeconds(pbPartitionConfig.GetLifetimeSeconds());
- }
- }
- }
- }
- }
- if (Topics.size() == 1) {
- TTopicInfo& topic = Topics.begin()->second;
- NKikimrViewer::TMetaTopicInfo& pbMetaTopic = *metaInfo.MutableTopic();
- pbMetaTopic.MutableCommittedLags()->MergeFrom(topic.GetCommittedLags());
- pbMetaTopic.MutableLastReadLags()->MergeFrom(topic.GetLastReadLags());
- for (const auto& pr : ConsumerInfo) {
- auto& pbClient = *pbMetaTopic.AddConsumers();
- pbClient.MergeFrom(pr.second);
- }
- for (const auto& pr : topic.PartitionInfo) {
- auto& pbPartition = *pbMetaTopic.AddPartitions();
- pbPartition.MergeFrom(pr.second);
- }
- }
-
+ }
+ if (pbPersQueueGroup.HasPQTabletConfig()) {
+ const auto& pbPQTabletConfig(pbPersQueueGroup.GetPQTabletConfig());
+ if (pbPQTabletConfig.HasPartitionConfig()) {
+ const auto& pbPartitionConfig(pbPQTabletConfig.GetPartitionConfig());
+ NKikimrViewer::TMetaTopicInfo& pbMetaTopic = *metaInfo.MutableTopic();
+ pbMetaTopic.MutablePartitionConfig()->SetMaxCountInPartition(pbPartitionConfig.GetMaxCountInPartition());
+ pbMetaTopic.MutablePartitionConfig()->SetMaxSizeInPartition(pbPartitionConfig.GetMaxSizeInPartition());
+ pbMetaTopic.MutablePartitionConfig()->SetLifetimeSeconds(pbPartitionConfig.GetLifetimeSeconds());
+ }
+ }
+ }
+ }
+ }
+ if (Topics.size() == 1) {
+ TTopicInfo& topic = Topics.begin()->second;
+ NKikimrViewer::TMetaTopicInfo& pbMetaTopic = *metaInfo.MutableTopic();
+ pbMetaTopic.MutableCommittedLags()->MergeFrom(topic.GetCommittedLags());
+ pbMetaTopic.MutableLastReadLags()->MergeFrom(topic.GetLastReadLags());
+ for (const auto& pr : ConsumerInfo) {
+ auto& pbClient = *pbMetaTopic.AddConsumers();
+ pbClient.MergeFrom(pr.second);
+ }
+ for (const auto& pr : topic.PartitionInfo) {
+ auto& pbPartition = *pbMetaTopic.AddPartitions();
+ pbPartition.MergeFrom(pr.second);
+ }
+ }
+
ctx.Send(Owner, new NViewerEvents::TEvBrowseResponse(std::move(browseInfo), std::move(metaInfo)));
- Die(ctx);
- }
-};
-
-}
-}
+ Die(ctx);
+ }
+};
+
+}
+}
diff --git a/ydb/core/viewer/content/api/css/print.css b/ydb/core/viewer/content/api/css/print.css
index da8be7b3349..f9cb0439f29 100644
--- a/ydb/core/viewer/content/api/css/print.css
+++ b/ydb/core/viewer/content/api/css/print.css
@@ -1,1367 +1,1367 @@
-/* Original style from softwaremaniacs.org (c) Ivan Sagalaev <Maniac@SoftwareManiacs.Org> */
-.swagger-section pre code {
- display: block;
- padding: 0.5em;
- background: #F0F0F0;
-}
-.swagger-section pre code,
-.swagger-section pre .subst,
-.swagger-section pre .tag .title,
-.swagger-section pre .lisp .title,
-.swagger-section pre .clojure .built_in,
-.swagger-section pre .nginx .title {
- color: black;
-}
-.swagger-section pre .string,
-.swagger-section pre .title,
-.swagger-section pre .constant,
-.swagger-section pre .parent,
-.swagger-section pre .tag .value,
-.swagger-section pre .rules .value,
-.swagger-section pre .rules .value .number,
-.swagger-section pre .preprocessor,
-.swagger-section pre .ruby .symbol,
-.swagger-section pre .ruby .symbol .string,
-.swagger-section pre .aggregate,
-.swagger-section pre .template_tag,
-.swagger-section pre .django .variable,
-.swagger-section pre .smalltalk .class,
-.swagger-section pre .addition,
-.swagger-section pre .flow,
-.swagger-section pre .stream,
-.swagger-section pre .bash .variable,
-.swagger-section pre .apache .tag,
-.swagger-section pre .apache .cbracket,
-.swagger-section pre .tex .command,
-.swagger-section pre .tex .special,
-.swagger-section pre .erlang_repl .function_or_atom,
-.swagger-section pre .markdown .header {
- color: #800;
-}
-.swagger-section pre .comment,
-.swagger-section pre .annotation,
-.swagger-section pre .template_comment,
-.swagger-section pre .diff .header,
-.swagger-section pre .chunk,
-.swagger-section pre .markdown .blockquote {
- color: #888;
-}
-.swagger-section pre .number,
-.swagger-section pre .date,
-.swagger-section pre .regexp,
-.swagger-section pre .literal,
-.swagger-section pre .smalltalk .symbol,
-.swagger-section pre .smalltalk .char,
-.swagger-section pre .go .constant,
-.swagger-section pre .change,
-.swagger-section pre .markdown .bullet,
-.swagger-section pre .markdown .link_url {
- color: #080;
-}
-.swagger-section pre .label,
-.swagger-section pre .javadoc,
-.swagger-section pre .ruby .string,
-.swagger-section pre .decorator,
-.swagger-section pre .filter .argument,
-.swagger-section pre .localvars,
-.swagger-section pre .array,
-.swagger-section pre .attr_selector,
-.swagger-section pre .important,
-.swagger-section pre .pseudo,
-.swagger-section pre .pi,
-.swagger-section pre .doctype,
-.swagger-section pre .deletion,
-.swagger-section pre .envvar,
-.swagger-section pre .shebang,
-.swagger-section pre .apache .sqbracket,
-.swagger-section pre .nginx .built_in,
-.swagger-section pre .tex .formula,
-.swagger-section pre .erlang_repl .reserved,
-.swagger-section pre .prompt,
-.swagger-section pre .markdown .link_label,
-.swagger-section pre .vhdl .attribute,
-.swagger-section pre .clojure .attribute,
-.swagger-section pre .coffeescript .property {
- color: #88F;
-}
-.swagger-section pre .keyword,
-.swagger-section pre .id,
-.swagger-section pre .phpdoc,
-.swagger-section pre .title,
-.swagger-section pre .built_in,
-.swagger-section pre .aggregate,
-.swagger-section pre .css .tag,
-.swagger-section pre .javadoctag,
-.swagger-section pre .phpdoc,
-.swagger-section pre .yardoctag,
-.swagger-section pre .smalltalk .class,
-.swagger-section pre .winutils,
-.swagger-section pre .bash .variable,
-.swagger-section pre .apache .tag,
-.swagger-section pre .go .typename,
-.swagger-section pre .tex .command,
-.swagger-section pre .markdown .strong,
-.swagger-section pre .request,
-.swagger-section pre .status {
- font-weight: bold;
-}
-.swagger-section pre .markdown .emphasis {
- font-style: italic;
-}
-.swagger-section pre .nginx .built_in {
- font-weight: normal;
-}
-.swagger-section pre .coffeescript .javascript,
-.swagger-section pre .javascript .xml,
-.swagger-section pre .tex .formula,
-.swagger-section pre .xml .javascript,
-.swagger-section pre .xml .vbscript,
-.swagger-section pre .xml .css,
-.swagger-section pre .xml .cdata {
- opacity: 0.5;
-}
-.swagger-section .hljs {
- display: block;
- overflow-x: auto;
- padding: 0.5em;
- background: #F0F0F0;
-}
-.swagger-section .hljs,
-.swagger-section .hljs-subst {
- color: #444;
-}
-.swagger-section .hljs-keyword,
-.swagger-section .hljs-attribute,
-.swagger-section .hljs-selector-tag,
-.swagger-section .hljs-meta-keyword,
-.swagger-section .hljs-doctag,
-.swagger-section .hljs-name {
- font-weight: bold;
-}
-.swagger-section .hljs-built_in,
-.swagger-section .hljs-literal,
-.swagger-section .hljs-bullet,
-.swagger-section .hljs-code,
-.swagger-section .hljs-addition {
- color: #1F811F;
-}
-.swagger-section .hljs-regexp,
-.swagger-section .hljs-symbol,
-.swagger-section .hljs-variable,
-.swagger-section .hljs-template-variable,
-.swagger-section .hljs-link,
-.swagger-section .hljs-selector-attr,
-.swagger-section .hljs-selector-pseudo {
- color: #BC6060;
-}
-.swagger-section .hljs-type,
-.swagger-section .hljs-string,
-.swagger-section .hljs-number,
-.swagger-section .hljs-selector-id,
-.swagger-section .hljs-selector-class,
-.swagger-section .hljs-quote,
-.swagger-section .hljs-template-tag,
-.swagger-section .hljs-deletion {
- color: #880000;
-}
-.swagger-section .hljs-title,
-.swagger-section .hljs-section {
- color: #880000;
- font-weight: bold;
-}
-.swagger-section .hljs-comment {
- color: #888888;
-}
-.swagger-section .hljs-meta {
- color: #2B6EA1;
-}
-.swagger-section .hljs-emphasis {
- font-style: italic;
-}
-.swagger-section .hljs-strong {
- font-weight: bold;
-}
-.swagger-section .swagger-ui-wrap {
- line-height: 1;
- font-family: "Droid Sans", sans-serif;
- min-width: 760px;
- max-width: 960px;
- margin-left: auto;
- margin-right: auto;
- /* JSONEditor specific styling */
-}
-.swagger-section .swagger-ui-wrap b,
-.swagger-section .swagger-ui-wrap strong {
- font-family: "Droid Sans", sans-serif;
- font-weight: bold;
-}
-.swagger-section .swagger-ui-wrap q,
-.swagger-section .swagger-ui-wrap blockquote {
- quotes: none;
-}
-.swagger-section .swagger-ui-wrap p {
- line-height: 1.4em;
- padding: 0 0 10px;
- color: #333333;
-}
-.swagger-section .swagger-ui-wrap q:before,
-.swagger-section .swagger-ui-wrap q:after,
-.swagger-section .swagger-ui-wrap blockquote:before,
-.swagger-section .swagger-ui-wrap blockquote:after {
- content: none;
-}
-.swagger-section .swagger-ui-wrap .heading_with_menu h1,
-.swagger-section .swagger-ui-wrap .heading_with_menu h2,
-.swagger-section .swagger-ui-wrap .heading_with_menu h3,
-.swagger-section .swagger-ui-wrap .heading_with_menu h4,
-.swagger-section .swagger-ui-wrap .heading_with_menu h5,
-.swagger-section .swagger-ui-wrap .heading_with_menu h6 {
- display: block;
- clear: none;
- float: left;
- -moz-box-sizing: border-box;
- -webkit-box-sizing: border-box;
- -ms-box-sizing: border-box;
- box-sizing: border-box;
- width: 60%;
-}
-.swagger-section .swagger-ui-wrap table {
- border-collapse: collapse;
- border-spacing: 0;
-}
-.swagger-section .swagger-ui-wrap table thead tr th {
- padding: 5px;
- font-size: 0.9em;
- color: #666666;
- border-bottom: 1px solid #999999;
-}
-.swagger-section .swagger-ui-wrap table tbody tr:last-child td {
- border-bottom: none;
-}
-.swagger-section .swagger-ui-wrap table tbody tr.offset {
- background-color: #f0f0f0;
-}
-.swagger-section .swagger-ui-wrap table tbody tr td {
- padding: 6px;
- font-size: 0.9em;
- border-bottom: 1px solid #cccccc;
- vertical-align: top;
- line-height: 1.3em;
-}
-.swagger-section .swagger-ui-wrap ol {
- margin: 0px 0 10px;
- padding: 0 0 0 18px;
- list-style-type: decimal;
-}
-.swagger-section .swagger-ui-wrap ol li {
- padding: 5px 0px;
- font-size: 0.9em;
- color: #333333;
-}
-.swagger-section .swagger-ui-wrap ol,
-.swagger-section .swagger-ui-wrap ul {
- list-style: none;
-}
-.swagger-section .swagger-ui-wrap h1 a,
-.swagger-section .swagger-ui-wrap h2 a,
-.swagger-section .swagger-ui-wrap h3 a,
-.swagger-section .swagger-ui-wrap h4 a,
-.swagger-section .swagger-ui-wrap h5 a,
-.swagger-section .swagger-ui-wrap h6 a {
- text-decoration: none;
-}
-.swagger-section .swagger-ui-wrap h1 a:hover,
-.swagger-section .swagger-ui-wrap h2 a:hover,
-.swagger-section .swagger-ui-wrap h3 a:hover,
-.swagger-section .swagger-ui-wrap h4 a:hover,
-.swagger-section .swagger-ui-wrap h5 a:hover,
-.swagger-section .swagger-ui-wrap h6 a:hover {
- text-decoration: underline;
-}
-.swagger-section .swagger-ui-wrap h1 span.divider,
-.swagger-section .swagger-ui-wrap h2 span.divider,
-.swagger-section .swagger-ui-wrap h3 span.divider,
-.swagger-section .swagger-ui-wrap h4 span.divider,
-.swagger-section .swagger-ui-wrap h5 span.divider,
-.swagger-section .swagger-ui-wrap h6 span.divider {
- color: #aaaaaa;
-}
-.swagger-section .swagger-ui-wrap a {
- color: #547f00;
-}
-.swagger-section .swagger-ui-wrap a img {
- border: none;
-}
-.swagger-section .swagger-ui-wrap article,
-.swagger-section .swagger-ui-wrap aside,
-.swagger-section .swagger-ui-wrap details,
-.swagger-section .swagger-ui-wrap figcaption,
-.swagger-section .swagger-ui-wrap figure,
-.swagger-section .swagger-ui-wrap footer,
-.swagger-section .swagger-ui-wrap header,
-.swagger-section .swagger-ui-wrap hgroup,
-.swagger-section .swagger-ui-wrap menu,
-.swagger-section .swagger-ui-wrap nav,
-.swagger-section .swagger-ui-wrap section,
-.swagger-section .swagger-ui-wrap summary {
- display: block;
-}
-.swagger-section .swagger-ui-wrap pre {
- font-family: "Anonymous Pro", "Menlo", "Consolas", "Bitstream Vera Sans Mono", "Courier New", monospace;
- background-color: #fcf6db;
- border: 1px solid #e5e0c6;
- padding: 10px;
-}
-.swagger-section .swagger-ui-wrap pre code {
- line-height: 1.6em;
- background: none;
-}
-.swagger-section .swagger-ui-wrap .content > .content-type > div > label {
- clear: both;
- display: block;
- color: #0F6AB4;
- font-size: 1.1em;
- margin: 0;
- padding: 15px 0 5px;
-}
-.swagger-section .swagger-ui-wrap .content pre {
- font-size: 12px;
- margin-top: 5px;
- padding: 5px;
-}
-.swagger-section .swagger-ui-wrap .icon-btn {
- cursor: pointer;
-}
-.swagger-section .swagger-ui-wrap .info_title {
- padding-bottom: 10px;
- font-weight: bold;
- font-size: 25px;
-}
-.swagger-section .swagger-ui-wrap .footer {
- margin-top: 20px;
-}
-.swagger-section .swagger-ui-wrap p.big,
-.swagger-section .swagger-ui-wrap div.big p {
- font-size: 1em;
- margin-bottom: 10px;
-}
-.swagger-section .swagger-ui-wrap form.fullwidth ol li.string input,
-.swagger-section .swagger-ui-wrap form.fullwidth ol li.url input,
-.swagger-section .swagger-ui-wrap form.fullwidth ol li.text textarea,
-.swagger-section .swagger-ui-wrap form.fullwidth ol li.numeric input {
- width: 500px !important;
-}
-.swagger-section .swagger-ui-wrap .info_license {
- padding-bottom: 5px;
-}
-.swagger-section .swagger-ui-wrap .info_tos {
- padding-bottom: 5px;
-}
-.swagger-section .swagger-ui-wrap .message-fail {
- color: #cc0000;
-}
-.swagger-section .swagger-ui-wrap .info_url {
- padding-bottom: 5px;
-}
-.swagger-section .swagger-ui-wrap .info_email {
- padding-bottom: 5px;
-}
-.swagger-section .swagger-ui-wrap .info_name {
- padding-bottom: 5px;
-}
-.swagger-section .swagger-ui-wrap .info_description {
- padding-bottom: 10px;
- font-size: 15px;
-}
-.swagger-section .swagger-ui-wrap .markdown ol li,
-.swagger-section .swagger-ui-wrap .markdown ul li {
- padding: 3px 0px;
- line-height: 1.4em;
- color: #333333;
-}
-.swagger-section .swagger-ui-wrap form.formtastic fieldset.inputs ol li.string input,
-.swagger-section .swagger-ui-wrap form.formtastic fieldset.inputs ol li.url input,
-.swagger-section .swagger-ui-wrap form.formtastic fieldset.inputs ol li.numeric input {
- display: block;
- padding: 4px;
- width: auto;
- clear: both;
-}
-.swagger-section .swagger-ui-wrap form.formtastic fieldset.inputs ol li.string input.title,
-.swagger-section .swagger-ui-wrap form.formtastic fieldset.inputs ol li.url input.title,
-.swagger-section .swagger-ui-wrap form.formtastic fieldset.inputs ol li.numeric input.title {
- font-size: 1.3em;
-}
-.swagger-section .swagger-ui-wrap table.fullwidth {
- width: 100%;
-}
-.swagger-section .swagger-ui-wrap .model-signature {
- font-family: "Droid Sans", sans-serif;
- font-size: 1em;
- line-height: 1.5em;
-}
-.swagger-section .swagger-ui-wrap .model-signature .signature-nav a {
- text-decoration: none;
- color: #AAA;
-}
-.swagger-section .swagger-ui-wrap .model-signature .signature-nav a:hover {
- text-decoration: underline;
- color: black;
-}
-.swagger-section .swagger-ui-wrap .model-signature .signature-nav .selected {
- color: black;
- text-decoration: none;
-}
-.swagger-section .swagger-ui-wrap .model-signature .propType {
- color: #5555aa;
-}
-.swagger-section .swagger-ui-wrap .model-signature pre:hover {
- background-color: #ffffdd;
-}
-.swagger-section .swagger-ui-wrap .model-signature pre {
- font-size: .85em;
- line-height: 1.2em;
- overflow: auto;
- max-height: 200px;
- cursor: pointer;
-}
-.swagger-section .swagger-ui-wrap .model-signature ul.signature-nav {
- display: block;
- min-width: 230px;
- margin: 0;
- padding: 0;
-}
-.swagger-section .swagger-ui-wrap .model-signature ul.signature-nav li:last-child {
- padding-right: 0;
- border-right: none;
-}
-.swagger-section .swagger-ui-wrap .model-signature ul.signature-nav li {
- float: left;
- margin: 0 5px 5px 0;
- padding: 2px 5px 2px 0;
- border-right: 1px solid #ddd;
-}
-.swagger-section .swagger-ui-wrap .model-signature .propOpt {
- color: #555;
-}
-.swagger-section .swagger-ui-wrap .model-signature .snippet small {
- font-size: 0.75em;
-}
-.swagger-section .swagger-ui-wrap .model-signature .propOptKey {
- font-style: italic;
-}
-.swagger-section .swagger-ui-wrap .model-signature .description .strong {
- font-weight: bold;
- color: #000;
- font-size: .9em;
-}
-.swagger-section .swagger-ui-wrap .model-signature .description div {
- font-size: 0.9em;
- line-height: 1.5em;
- margin-left: 1em;
-}
-.swagger-section .swagger-ui-wrap .model-signature .description .stronger {
- font-weight: bold;
- color: #000;
-}
-.swagger-section .swagger-ui-wrap .model-signature .description .propWrap .optionsWrapper {
- border-spacing: 0;
- position: absolute;
- background-color: #ffffff;
- border: 1px solid #bbbbbb;
- display: none;
- font-size: 11px;
- max-width: 400px;
- line-height: 30px;
- color: black;
- padding: 5px;
- margin-left: 10px;
-}
-.swagger-section .swagger-ui-wrap .model-signature .description .propWrap .optionsWrapper th {
- text-align: center;
- background-color: #eeeeee;
- border: 1px solid #bbbbbb;
- font-size: 11px;
- color: #666666;
- font-weight: bold;
- padding: 5px;
- line-height: 15px;
-}
-.swagger-section .swagger-ui-wrap .model-signature .description .propWrap .optionsWrapper .optionName {
- font-weight: bold;
-}
-.swagger-section .swagger-ui-wrap .model-signature .description .propDesc.markdown > p:first-child,
-.swagger-section .swagger-ui-wrap .model-signature .description .propDesc.markdown > p:last-child {
- display: inline;
-}
-.swagger-section .swagger-ui-wrap .model-signature .description .propDesc.markdown > p:not(:first-child):before {
- display: block;
- content: '';
-}
-.swagger-section .swagger-ui-wrap .model-signature .description span:last-of-type.propDesc.markdown > p:only-child {
- margin-right: -3px;
-}
-.swagger-section .swagger-ui-wrap .model-signature .propName {
- font-weight: bold;
-}
-.swagger-section .swagger-ui-wrap .model-signature .signature-container {
- clear: both;
-}
-.swagger-section .swagger-ui-wrap .body-textarea {
- width: 300px;
- height: 100px;
- border: 1px solid #aaa;
-}
-.swagger-section .swagger-ui-wrap .markdown p code,
-.swagger-section .swagger-ui-wrap .markdown li code {
- font-family: "Anonymous Pro", "Menlo", "Consolas", "Bitstream Vera Sans Mono", "Courier New", monospace;
- background-color: #f0f0f0;
- color: black;
- padding: 1px 3px;
-}
-.swagger-section .swagger-ui-wrap .required {
- font-weight: bold;
-}
-.swagger-section .swagger-ui-wrap .editor_holder {
- font-family: "Anonymous Pro", "Menlo", "Consolas", "Bitstream Vera Sans Mono", "Courier New", monospace;
- font-size: 0.9em;
-}
-.swagger-section .swagger-ui-wrap .editor_holder label {
- font-weight: normal!important;
- /* JSONEditor uses bold by default for all labels, we revert that back to normal to not give the impression that by default fields are required */
-}
-.swagger-section .swagger-ui-wrap .editor_holder label.required {
- font-weight: bold!important;
-}
-.swagger-section .swagger-ui-wrap input.parameter {
- width: 300px;
- border: 1px solid #aaa;
-}
-.swagger-section .swagger-ui-wrap h1 {
- color: black;
- font-size: 1.5em;
- line-height: 1.3em;
- padding: 10px 0 10px 0;
- font-family: "Droid Sans", sans-serif;
- font-weight: bold;
-}
-.swagger-section .swagger-ui-wrap .heading_with_menu {
- float: none;
- clear: both;
- overflow: hidden;
- display: block;
-}
-.swagger-section .swagger-ui-wrap .heading_with_menu ul {
- display: block;
- clear: none;
- float: right;
- -moz-box-sizing: border-box;
- -webkit-box-sizing: border-box;
- -ms-box-sizing: border-box;
- box-sizing: border-box;
- margin-top: 10px;
-}
-.swagger-section .swagger-ui-wrap h2 {
- color: black;
- font-size: 1.3em;
- padding: 10px 0 10px 0;
-}
-.swagger-section .swagger-ui-wrap h2 a {
- color: black;
-}
-.swagger-section .swagger-ui-wrap h2 span.sub {
- font-size: 0.7em;
- color: #999999;
- font-style: italic;
-}
-.swagger-section .swagger-ui-wrap h2 span.sub a {
- color: #777777;
-}
-.swagger-section .swagger-ui-wrap span.weak {
- color: #666666;
-}
-.swagger-section .swagger-ui-wrap .message-success {
- color: #89BF04;
-}
-.swagger-section .swagger-ui-wrap caption,
-.swagger-section .swagger-ui-wrap th,
-.swagger-section .swagger-ui-wrap td {
- text-align: left;
- font-weight: normal;
- vertical-align: middle;
-}
-.swagger-section .swagger-ui-wrap .code {
- font-family: "Anonymous Pro", "Menlo", "Consolas", "Bitstream Vera Sans Mono", "Courier New", monospace;
-}
-.swagger-section .swagger-ui-wrap form.formtastic fieldset.inputs ol li.text textarea {
- font-family: "Droid Sans", sans-serif;
- height: 250px;
- padding: 4px;
- display: block;
- clear: both;
-}
-.swagger-section .swagger-ui-wrap form.formtastic fieldset.inputs ol li.select select {
- display: block;
- clear: both;
-}
-.swagger-section .swagger-ui-wrap form.formtastic fieldset.inputs ol li.boolean {
- float: none;
- clear: both;
- overflow: hidden;
- display: block;
-}
-.swagger-section .swagger-ui-wrap form.formtastic fieldset.inputs ol li.boolean label {
- display: block;
- float: left;
- clear: none;
- margin: 0;
- padding: 0;
-}
-.swagger-section .swagger-ui-wrap form.formtastic fieldset.inputs ol li.boolean input {
- display: block;
- float: left;
- clear: none;
- margin: 0 5px 0 0;
-}
-.swagger-section .swagger-ui-wrap form.formtastic fieldset.inputs ol li.required label {
- color: black;
-}
-.swagger-section .swagger-ui-wrap form.formtastic fieldset.inputs ol li label {
- display: block;
- clear: both;
- width: auto;
- padding: 0 0 3px;
- color: #666666;
-}
-.swagger-section .swagger-ui-wrap form.formtastic fieldset.inputs ol li label abbr {
- padding-left: 3px;
- color: #888888;
-}
-.swagger-section .swagger-ui-wrap form.formtastic fieldset.inputs ol li p.inline-hints {
- margin-left: 0;
- font-style: italic;
- font-size: 0.9em;
- margin: 0;
-}
-.swagger-section .swagger-ui-wrap form.formtastic fieldset.buttons {
- margin: 0;
- padding: 0;
-}
-.swagger-section .swagger-ui-wrap span.blank,
-.swagger-section .swagger-ui-wrap span.empty {
- color: #888888;
- font-style: italic;
-}
-.swagger-section .swagger-ui-wrap .markdown h3 {
- color: #547f00;
-}
-.swagger-section .swagger-ui-wrap .markdown h4 {
- color: #666666;
-}
-.swagger-section .swagger-ui-wrap .markdown pre {
- font-family: "Anonymous Pro", "Menlo", "Consolas", "Bitstream Vera Sans Mono", "Courier New", monospace;
- background-color: #fcf6db;
- border: 1px solid #e5e0c6;
- padding: 10px;
- margin: 0 0 10px 0;
-}
-.swagger-section .swagger-ui-wrap .markdown pre code {
- line-height: 1.6em;
- overflow: auto;
-}
-.swagger-section .swagger-ui-wrap div.gist {
- margin: 20px 0 25px 0 !important;
-}
-.swagger-section .swagger-ui-wrap ul#resources {
- font-family: "Droid Sans", sans-serif;
- font-size: 0.9em;
-}
-.swagger-section .swagger-ui-wrap ul#resources li.resource {
- border-bottom: 1px solid #dddddd;
-}
-.swagger-section .swagger-ui-wrap ul#resources li.resource:hover div.heading h2 a,
-.swagger-section .swagger-ui-wrap ul#resources li.resource.active div.heading h2 a {
- color: black;
-}
-.swagger-section .swagger-ui-wrap ul#resources li.resource:hover div.heading ul.options li a,
-.swagger-section .swagger-ui-wrap ul#resources li.resource.active div.heading ul.options li a {
- color: #555555;
-}
-.swagger-section .swagger-ui-wrap ul#resources li.resource:last-child {
- border-bottom: none;
-}
-.swagger-section .swagger-ui-wrap ul#resources li.resource div.heading {
- border: 1px solid transparent;
- float: none;
- clear: both;
- overflow: hidden;
- display: block;
-}
-.swagger-section .swagger-ui-wrap ul#resources li.resource div.heading ul.options {
- overflow: hidden;
- padding: 0;
- display: block;
- clear: none;
- float: right;
- margin: 14px 10px 0 0;
-}
-.swagger-section .swagger-ui-wrap ul#resources li.resource div.heading ul.options li {
- float: left;
- clear: none;
- margin: 0;
- padding: 2px 10px;
- border-right: 1px solid #dddddd;
- color: #666666;
- font-size: 0.9em;
-}
-.swagger-section .swagger-ui-wrap ul#resources li.resource div.heading ul.options li a {
- color: #aaaaaa;
- text-decoration: none;
-}
-.swagger-section .swagger-ui-wrap ul#resources li.resource div.heading ul.options li a:hover {
- text-decoration: underline;
- color: black;
-}
-.swagger-section .swagger-ui-wrap ul#resources li.resource div.heading ul.options li a:hover,
-.swagger-section .swagger-ui-wrap ul#resources li.resource div.heading ul.options li a:active,
-.swagger-section .swagger-ui-wrap ul#resources li.resource div.heading ul.options li a.active {
- text-decoration: underline;
-}
-.swagger-section .swagger-ui-wrap ul#resources li.resource div.heading ul.options li:first-child,
-.swagger-section .swagger-ui-wrap ul#resources li.resource div.heading ul.options li.first {
- padding-left: 0;
-}
-.swagger-section .swagger-ui-wrap ul#resources li.resource div.heading ul.options li:last-child,
-.swagger-section .swagger-ui-wrap ul#resources li.resource div.heading ul.options li.last {
- padding-right: 0;
- border-right: none;
-}
-.swagger-section .swagger-ui-wrap ul#resources li.resource div.heading ul.options:first-child,
-.swagger-section .swagger-ui-wrap ul#resources li.resource div.heading ul.options.first {
- padding-left: 0;
-}
-.swagger-section .swagger-ui-wrap ul#resources li.resource div.heading h2 {
- color: #999999;
- padding-left: 0;
- display: block;
- clear: none;
- float: left;
- font-family: "Droid Sans", sans-serif;
- font-weight: bold;
-}
-.swagger-section .swagger-ui-wrap ul#resources li.resource div.heading h2 a {
- color: #999999;
-}
-.swagger-section .swagger-ui-wrap ul#resources li.resource div.heading h2 a:hover {
- color: black;
-}
-.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation {
- float: none;
- clear: both;
- overflow: hidden;
- display: block;
- margin: 0 0 10px;
- padding: 0;
-}
-.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation div.heading {
- float: none;
- clear: both;
- overflow: hidden;
- display: block;
- margin: 0;
- padding: 0;
-}
-.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation div.heading h3 {
- display: block;
- clear: none;
- float: left;
- width: auto;
- margin: 0;
- padding: 0;
- line-height: 1.1em;
- color: black;
-}
-.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation div.heading h3 span.path {
- padding-left: 10px;
-}
-.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation div.heading h3 span.path a {
- color: black;
- text-decoration: none;
-}
-.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation div.heading h3 span.path a.toggleOperation.deprecated {
- text-decoration: line-through;
-}
-.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation div.heading h3 span.path a:hover {
- text-decoration: underline;
-}
-.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation div.heading h3 span.http_method a {
- text-transform: uppercase;
- text-decoration: none;
- color: white;
- display: inline-block;
- width: 50px;
- font-size: 0.7em;
- text-align: center;
- padding: 7px 0 4px;
- -moz-border-radius: 2px;
- -webkit-border-radius: 2px;
- -o-border-radius: 2px;
- -ms-border-radius: 2px;
- -khtml-border-radius: 2px;
- border-radius: 2px;
-}
-.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation div.heading h3 span {
- margin: 0;
- padding: 0;
-}
-.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation div.heading ul.options {
- overflow: hidden;
- padding: 0;
- display: block;
- clear: none;
- float: right;
- margin: 6px 10px 0 0;
-}
-.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation div.heading ul.options li {
- float: left;
- clear: none;
- margin: 0;
- padding: 2px 10px;
- font-size: 0.9em;
-}
-.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation div.heading ul.options li a {
- text-decoration: none;
-}
-.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation div.heading ul.options li a .markdown p {
- color: inherit;
- padding: 0;
- line-height: inherit;
-}
-.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation div.heading ul.options li.access {
- color: black;
-}
-.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation div.content {
- border-top: none;
- padding: 10px;
- -moz-border-radius-bottomleft: 6px;
- -webkit-border-bottom-left-radius: 6px;
- -o-border-bottom-left-radius: 6px;
- -ms-border-bottom-left-radius: 6px;
- -khtml-border-bottom-left-radius: 6px;
- border-bottom-left-radius: 6px;
- -moz-border-radius-bottomright: 6px;
- -webkit-border-bottom-right-radius: 6px;
- -o-border-bottom-right-radius: 6px;
- -ms-border-bottom-right-radius: 6px;
- -khtml-border-bottom-right-radius: 6px;
- border-bottom-right-radius: 6px;
- margin: 0 0 20px;
-}
-.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation div.content h4 {
- font-size: 1.1em;
- margin: 0;
- padding: 15px 0 5px;
-}
-.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation div.content div.sandbox_header {
- float: none;
- clear: both;
- overflow: hidden;
- display: block;
-}
-.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation div.content div.sandbox_header a {
- padding: 4px 0 0 10px;
- display: inline-block;
- font-size: 0.9em;
-}
-.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation div.content div.sandbox_header input.submit {
- display: block;
- clear: none;
- float: left;
- padding: 6px 8px;
-}
-.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation div.content div.sandbox_header span.response_throbber {
- background-image: url('../images/throbber.gif');
- width: 128px;
- height: 16px;
- display: block;
- clear: none;
- float: right;
-}
-.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation div.content form input[type='text'].error {
- outline: 2px solid black;
- outline-color: #cc0000;
-}
-.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation div.content form select[name='parameterContentType'] {
- max-width: 300px;
-}
-.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation div.content div.response div.block pre {
- font-family: "Anonymous Pro", "Menlo", "Consolas", "Bitstream Vera Sans Mono", "Courier New", monospace;
- padding: 10px;
- font-size: 0.9em;
- max-height: 400px;
- overflow-y: auto;
-}
-.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.put div.heading {
- background-color: #f9f2e9;
- border: 1px solid #f0e0ca;
-}
-.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.put div.heading h3 span.http_method a {
- background-color: #c5862b;
-}
-.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.put div.heading ul.options li {
- border-right: 1px solid #dddddd;
- border-right-color: #f0e0ca;
- color: #c5862b;
-}
-.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.put div.heading ul.options li a {
- color: #c5862b;
-}
-.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.put div.content {
- background-color: #faf5ee;
- border: 1px solid #f0e0ca;
-}
-.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.put div.content h4 {
- color: #c5862b;
-}
-.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.put div.content div.sandbox_header a {
- color: #dcb67f;
-}
-.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.head div.heading {
- background-color: #fcffcd;
- border: 1px solid black;
- border-color: #ffd20f;
-}
-.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.head div.heading h3 span.http_method a {
- text-transform: uppercase;
- background-color: #ffd20f;
-}
-.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.head div.heading ul.options li {
- border-right: 1px solid #dddddd;
- border-right-color: #ffd20f;
- color: #ffd20f;
-}
-.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.head div.heading ul.options li a {
- color: #ffd20f;
-}
-.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.head div.content {
- background-color: #fcffcd;
- border: 1px solid black;
- border-color: #ffd20f;
-}
-.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.head div.content h4 {
- color: #ffd20f;
-}
-.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.head div.content div.sandbox_header a {
- color: #6fc992;
-}
-.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.delete div.heading {
- background-color: #f5e8e8;
- border: 1px solid #e8c6c7;
-}
-.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.delete div.heading h3 span.http_method a {
- text-transform: uppercase;
- background-color: #a41e22;
-}
-.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.delete div.heading ul.options li {
- border-right: 1px solid #dddddd;
- border-right-color: #e8c6c7;
- color: #a41e22;
-}
-.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.delete div.heading ul.options li a {
- color: #a41e22;
-}
-.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.delete div.content {
- background-color: #f7eded;
- border: 1px solid #e8c6c7;
-}
-.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.delete div.content h4 {
- color: #a41e22;
-}
-.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.delete div.content div.sandbox_header a {
- color: #c8787a;
-}
-.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.post div.heading {
- background-color: #e7f6ec;
- border: 1px solid #c3e8d1;
-}
-.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.post div.heading h3 span.http_method a {
- background-color: #10a54a;
-}
-.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.post div.heading ul.options li {
- border-right: 1px solid #dddddd;
- border-right-color: #c3e8d1;
- color: #10a54a;
-}
-.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.post div.heading ul.options li a {
- color: #10a54a;
-}
-.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.post div.content {
- background-color: #ebf7f0;
- border: 1px solid #c3e8d1;
-}
-.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.post div.content h4 {
- color: #10a54a;
-}
-.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.post div.content div.sandbox_header a {
- color: #6fc992;
-}
-.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.patch div.heading {
- background-color: #FCE9E3;
- border: 1px solid #F5D5C3;
-}
-.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.patch div.heading h3 span.http_method a {
- background-color: #D38042;
-}
-.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.patch div.heading ul.options li {
- border-right: 1px solid #dddddd;
- border-right-color: #f0cecb;
- color: #D38042;
-}
-.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.patch div.heading ul.options li a {
- color: #D38042;
-}
-.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.patch div.content {
- background-color: #faf0ef;
- border: 1px solid #f0cecb;
-}
-.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.patch div.content h4 {
- color: #D38042;
-}
-.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.patch div.content div.sandbox_header a {
- color: #dcb67f;
-}
-.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.get div.heading {
- background-color: #e7f0f7;
- border: 1px solid #c3d9ec;
-}
-.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.get div.heading h3 span.http_method a {
- background-color: #0f6ab4;
-}
-.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.get div.heading ul.options li {
- border-right: 1px solid #dddddd;
- border-right-color: #c3d9ec;
- color: #0f6ab4;
-}
-.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.get div.heading ul.options li a {
- color: #0f6ab4;
-}
-.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.get div.content {
- background-color: #ebf3f9;
- border: 1px solid #c3d9ec;
-}
-.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.get div.content h4 {
- color: #0f6ab4;
-}
-.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.get div.content div.sandbox_header a {
- color: #6fa5d2;
-}
-.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.options div.heading {
- background-color: #e7f0f7;
- border: 1px solid #c3d9ec;
-}
-.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.options div.heading h3 span.http_method a {
- background-color: #0f6ab4;
-}
-.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.options div.heading ul.options li {
- border-right: 1px solid #dddddd;
- border-right-color: #c3d9ec;
- color: #0f6ab4;
-}
-.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.options div.heading ul.options li a {
- color: #0f6ab4;
-}
-.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.options div.content {
- background-color: #ebf3f9;
- border: 1px solid #c3d9ec;
-}
-.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.options div.content h4 {
- color: #0f6ab4;
-}
-.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.options div.content div.sandbox_header a {
- color: #6fa5d2;
-}
-.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.get div.content,
-.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.post div.content,
-.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.head div.content,
-.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.put div.content,
-.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.patch div.content,
-.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.delete div.content {
- border-top: none;
-}
-.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.get div.heading ul.options li:last-child,
-.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.post div.heading ul.options li:last-child,
-.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.head div.heading ul.options li:last-child,
-.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.put div.heading ul.options li:last-child,
-.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.patch div.heading ul.options li:last-child,
-.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.delete div.heading ul.options li:last-child,
-.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.get div.heading ul.options li.last,
-.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.post div.heading ul.options li.last,
-.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.head div.heading ul.options li.last,
-.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.put div.heading ul.options li.last,
-.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.patch div.heading ul.options li.last,
-.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.delete div.heading ul.options li.last {
- padding-right: 0;
- border-right: none;
-}
-.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations ul.options li a:hover,
-.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations ul.options li a:active,
-.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations ul.options li a.active {
- text-decoration: underline;
-}
-.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations ul.options li:first-child,
-.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations ul.options li.first {
- padding-left: 0;
-}
-.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations:first-child,
-.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations.first {
- padding-left: 0;
-}
-.swagger-section .swagger-ui-wrap p#colophon {
- margin: 0 15px 40px 15px;
- padding: 10px 0;
- font-size: 0.8em;
- border-top: 1px solid #dddddd;
- font-family: "Droid Sans", sans-serif;
- color: #999999;
- font-style: italic;
-}
-.swagger-section .swagger-ui-wrap p#colophon a {
- text-decoration: none;
- color: #547f00;
-}
-.swagger-section .swagger-ui-wrap h3 {
- color: black;
- font-size: 1.1em;
- padding: 10px 0 10px 0;
-}
-.swagger-section .swagger-ui-wrap .markdown ol,
-.swagger-section .swagger-ui-wrap .markdown ul {
- font-family: "Droid Sans", sans-serif;
- margin: 5px 0 10px;
- padding: 0 0 0 18px;
- list-style-type: disc;
-}
-.swagger-section .swagger-ui-wrap form.form_box {
- background-color: #ebf3f9;
- border: 1px solid #c3d9ec;
- padding: 10px;
-}
-.swagger-section .swagger-ui-wrap form.form_box label {
- color: #0f6ab4 !important;
-}
-.swagger-section .swagger-ui-wrap form.form_box input[type=submit] {
- display: block;
- padding: 10px;
-}
-.swagger-section .swagger-ui-wrap form.form_box p.weak {
- font-size: 0.8em;
-}
-.swagger-section .swagger-ui-wrap form.form_box p {
- font-size: 0.9em;
- padding: 0 0 15px;
- color: #7e7b6d;
-}
-.swagger-section .swagger-ui-wrap form.form_box p a {
- color: #646257;
-}
-.swagger-section .swagger-ui-wrap form.form_box p strong {
- color: black;
-}
-.swagger-section .swagger-ui-wrap .operation-status td.markdown > p:last-child {
- padding-bottom: 0;
-}
-.swagger-section .title {
- font-style: bold;
-}
-.swagger-section .secondary_form {
- display: none;
-}
-.swagger-section .main_image {
- display: block;
- margin-left: auto;
- margin-right: auto;
-}
-.swagger-section .oauth_body {
- margin-left: 100px;
- margin-right: 100px;
-}
-.swagger-section .oauth_submit {
- text-align: center;
- display: inline-block;
-}
-.swagger-section .authorize-wrapper {
- margin: 15px 0 10px;
-}
-.swagger-section .authorize-wrapper_operation {
- float: right;
-}
-.swagger-section .authorize__btn:hover {
- text-decoration: underline;
- cursor: pointer;
-}
-.swagger-section .authorize__btn_operation:hover .authorize-scopes {
- display: block;
-}
-.swagger-section .authorize-scopes {
- position: absolute;
- margin-top: 20px;
- background: #FFF;
- border: 1px solid #ccc;
- border-radius: 5px;
- display: none;
- font-size: 13px;
- max-width: 300px;
- line-height: 30px;
- color: black;
- padding: 5px;
-}
-.swagger-section .authorize-scopes .authorize__scope {
- text-decoration: none;
-}
-.swagger-section .authorize__btn_operation {
- height: 18px;
- vertical-align: middle;
- display: inline-block;
- background: url(../images/explorer_icons.png) no-repeat;
-}
-.swagger-section .authorize__btn_operation_login {
- background-position: 0 0;
- width: 18px;
- margin-top: -6px;
- margin-left: 4px;
-}
-.swagger-section .authorize__btn_operation_logout {
- background-position: -30px 0;
- width: 18px;
- margin-top: -6px;
- margin-left: 4px;
-}
-.swagger-section #auth_container {
- color: #fff;
- display: inline-block;
- border: none;
- padding: 5px;
- width: 87px;
- height: 13px;
-}
-.swagger-section #auth_container .authorize__btn {
- color: #fff;
-}
-.swagger-section .auth_container {
- padding: 0 0 10px;
- margin-bottom: 5px;
- border-bottom: solid 1px #CCC;
- font-size: 0.9em;
-}
-.swagger-section .auth_container .auth__title {
- color: #547f00;
- font-size: 1.2em;
-}
-.swagger-section .auth_container .basic_auth__label {
- display: inline-block;
- width: 60px;
-}
-.swagger-section .auth_container .auth__description {
- color: #999999;
- margin-bottom: 5px;
-}
-.swagger-section .auth_container .auth__button {
- margin-top: 10px;
- height: 30px;
-}
-.swagger-section .auth_container .key_auth__field {
- margin: 5px 0;
-}
-.swagger-section .auth_container .key_auth__label {
- display: inline-block;
- width: 60px;
-}
-.swagger-section .api-popup-dialog {
- position: absolute;
- display: none;
-}
-.swagger-section .api-popup-dialog-wrapper {
- z-index: 1000;
- width: 500px;
- background: #FFF;
- padding: 20px;
- border: 1px solid #ccc;
- border-radius: 5px;
- font-size: 13px;
- color: #777;
- position: fixed;
- top: 50%;
- left: 50%;
- transform: translate(-50%, -50%);
-}
-.swagger-section .api-popup-dialog-shadow {
- position: fixed;
- top: 0;
- left: 0;
- width: 100%;
- height: 100%;
- opacity: 0.2;
- background-color: gray;
- z-index: 900;
-}
-.swagger-section .api-popup-dialog .api-popup-title {
- font-size: 24px;
- padding: 10px 0;
-}
-.swagger-section .api-popup-dialog .api-popup-title {
- font-size: 24px;
- padding: 10px 0;
-}
-.swagger-section .api-popup-dialog .error-msg {
- padding-left: 5px;
- padding-bottom: 5px;
-}
-.swagger-section .api-popup-dialog .api-popup-content {
- max-height: 500px;
- overflow-y: auto;
-}
-.swagger-section .api-popup-dialog .api-popup-authbtn {
- height: 30px;
-}
-.swagger-section .api-popup-dialog .api-popup-cancel {
- height: 30px;
-}
-.swagger-section .api-popup-scopes {
- padding: 10px 20px;
-}
-.swagger-section .api-popup-scopes li {
- padding: 5px 0;
- line-height: 20px;
-}
-.swagger-section .api-popup-scopes li input {
- position: relative;
- top: 2px;
-}
-.swagger-section .api-popup-scopes .api-scope-desc {
- padding-left: 20px;
- font-style: italic;
-}
-.swagger-section .api-popup-actions {
- padding-top: 10px;
-}
-#header {
- display: none;
-}
-.swagger-section .swagger-ui-wrap .model-signature pre {
- max-height: none;
-}
-.swagger-section .swagger-ui-wrap .body-textarea {
- width: 100px;
-}
-.swagger-section .swagger-ui-wrap input.parameter {
- width: 100px;
-}
-.swagger-section .swagger-ui-wrap ul#resources li.resource div.heading ul.options {
- display: none;
-}
-.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints {
- display: block !important;
-}
-.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation div.content {
- display: block !important;
-}
+/* Original style from softwaremaniacs.org (c) Ivan Sagalaev <Maniac@SoftwareManiacs.Org> */
+.swagger-section pre code {
+ display: block;
+ padding: 0.5em;
+ background: #F0F0F0;
+}
+.swagger-section pre code,
+.swagger-section pre .subst,
+.swagger-section pre .tag .title,
+.swagger-section pre .lisp .title,
+.swagger-section pre .clojure .built_in,
+.swagger-section pre .nginx .title {
+ color: black;
+}
+.swagger-section pre .string,
+.swagger-section pre .title,
+.swagger-section pre .constant,
+.swagger-section pre .parent,
+.swagger-section pre .tag .value,
+.swagger-section pre .rules .value,
+.swagger-section pre .rules .value .number,
+.swagger-section pre .preprocessor,
+.swagger-section pre .ruby .symbol,
+.swagger-section pre .ruby .symbol .string,
+.swagger-section pre .aggregate,
+.swagger-section pre .template_tag,
+.swagger-section pre .django .variable,
+.swagger-section pre .smalltalk .class,
+.swagger-section pre .addition,
+.swagger-section pre .flow,
+.swagger-section pre .stream,
+.swagger-section pre .bash .variable,
+.swagger-section pre .apache .tag,
+.swagger-section pre .apache .cbracket,
+.swagger-section pre .tex .command,
+.swagger-section pre .tex .special,
+.swagger-section pre .erlang_repl .function_or_atom,
+.swagger-section pre .markdown .header {
+ color: #800;
+}
+.swagger-section pre .comment,
+.swagger-section pre .annotation,
+.swagger-section pre .template_comment,
+.swagger-section pre .diff .header,
+.swagger-section pre .chunk,
+.swagger-section pre .markdown .blockquote {
+ color: #888;
+}
+.swagger-section pre .number,
+.swagger-section pre .date,
+.swagger-section pre .regexp,
+.swagger-section pre .literal,
+.swagger-section pre .smalltalk .symbol,
+.swagger-section pre .smalltalk .char,
+.swagger-section pre .go .constant,
+.swagger-section pre .change,
+.swagger-section pre .markdown .bullet,
+.swagger-section pre .markdown .link_url {
+ color: #080;
+}
+.swagger-section pre .label,
+.swagger-section pre .javadoc,
+.swagger-section pre .ruby .string,
+.swagger-section pre .decorator,
+.swagger-section pre .filter .argument,
+.swagger-section pre .localvars,
+.swagger-section pre .array,
+.swagger-section pre .attr_selector,
+.swagger-section pre .important,
+.swagger-section pre .pseudo,
+.swagger-section pre .pi,
+.swagger-section pre .doctype,
+.swagger-section pre .deletion,
+.swagger-section pre .envvar,
+.swagger-section pre .shebang,
+.swagger-section pre .apache .sqbracket,
+.swagger-section pre .nginx .built_in,
+.swagger-section pre .tex .formula,
+.swagger-section pre .erlang_repl .reserved,
+.swagger-section pre .prompt,
+.swagger-section pre .markdown .link_label,
+.swagger-section pre .vhdl .attribute,
+.swagger-section pre .clojure .attribute,
+.swagger-section pre .coffeescript .property {
+ color: #88F;
+}
+.swagger-section pre .keyword,
+.swagger-section pre .id,
+.swagger-section pre .phpdoc,
+.swagger-section pre .title,
+.swagger-section pre .built_in,
+.swagger-section pre .aggregate,
+.swagger-section pre .css .tag,
+.swagger-section pre .javadoctag,
+.swagger-section pre .phpdoc,
+.swagger-section pre .yardoctag,
+.swagger-section pre .smalltalk .class,
+.swagger-section pre .winutils,
+.swagger-section pre .bash .variable,
+.swagger-section pre .apache .tag,
+.swagger-section pre .go .typename,
+.swagger-section pre .tex .command,
+.swagger-section pre .markdown .strong,
+.swagger-section pre .request,
+.swagger-section pre .status {
+ font-weight: bold;
+}
+.swagger-section pre .markdown .emphasis {
+ font-style: italic;
+}
+.swagger-section pre .nginx .built_in {
+ font-weight: normal;
+}
+.swagger-section pre .coffeescript .javascript,
+.swagger-section pre .javascript .xml,
+.swagger-section pre .tex .formula,
+.swagger-section pre .xml .javascript,
+.swagger-section pre .xml .vbscript,
+.swagger-section pre .xml .css,
+.swagger-section pre .xml .cdata {
+ opacity: 0.5;
+}
+.swagger-section .hljs {
+ display: block;
+ overflow-x: auto;
+ padding: 0.5em;
+ background: #F0F0F0;
+}
+.swagger-section .hljs,
+.swagger-section .hljs-subst {
+ color: #444;
+}
+.swagger-section .hljs-keyword,
+.swagger-section .hljs-attribute,
+.swagger-section .hljs-selector-tag,
+.swagger-section .hljs-meta-keyword,
+.swagger-section .hljs-doctag,
+.swagger-section .hljs-name {
+ font-weight: bold;
+}
+.swagger-section .hljs-built_in,
+.swagger-section .hljs-literal,
+.swagger-section .hljs-bullet,
+.swagger-section .hljs-code,
+.swagger-section .hljs-addition {
+ color: #1F811F;
+}
+.swagger-section .hljs-regexp,
+.swagger-section .hljs-symbol,
+.swagger-section .hljs-variable,
+.swagger-section .hljs-template-variable,
+.swagger-section .hljs-link,
+.swagger-section .hljs-selector-attr,
+.swagger-section .hljs-selector-pseudo {
+ color: #BC6060;
+}
+.swagger-section .hljs-type,
+.swagger-section .hljs-string,
+.swagger-section .hljs-number,
+.swagger-section .hljs-selector-id,
+.swagger-section .hljs-selector-class,
+.swagger-section .hljs-quote,
+.swagger-section .hljs-template-tag,
+.swagger-section .hljs-deletion {
+ color: #880000;
+}
+.swagger-section .hljs-title,
+.swagger-section .hljs-section {
+ color: #880000;
+ font-weight: bold;
+}
+.swagger-section .hljs-comment {
+ color: #888888;
+}
+.swagger-section .hljs-meta {
+ color: #2B6EA1;
+}
+.swagger-section .hljs-emphasis {
+ font-style: italic;
+}
+.swagger-section .hljs-strong {
+ font-weight: bold;
+}
+.swagger-section .swagger-ui-wrap {
+ line-height: 1;
+ font-family: "Droid Sans", sans-serif;
+ min-width: 760px;
+ max-width: 960px;
+ margin-left: auto;
+ margin-right: auto;
+ /* JSONEditor specific styling */
+}
+.swagger-section .swagger-ui-wrap b,
+.swagger-section .swagger-ui-wrap strong {
+ font-family: "Droid Sans", sans-serif;
+ font-weight: bold;
+}
+.swagger-section .swagger-ui-wrap q,
+.swagger-section .swagger-ui-wrap blockquote {
+ quotes: none;
+}
+.swagger-section .swagger-ui-wrap p {
+ line-height: 1.4em;
+ padding: 0 0 10px;
+ color: #333333;
+}
+.swagger-section .swagger-ui-wrap q:before,
+.swagger-section .swagger-ui-wrap q:after,
+.swagger-section .swagger-ui-wrap blockquote:before,
+.swagger-section .swagger-ui-wrap blockquote:after {
+ content: none;
+}
+.swagger-section .swagger-ui-wrap .heading_with_menu h1,
+.swagger-section .swagger-ui-wrap .heading_with_menu h2,
+.swagger-section .swagger-ui-wrap .heading_with_menu h3,
+.swagger-section .swagger-ui-wrap .heading_with_menu h4,
+.swagger-section .swagger-ui-wrap .heading_with_menu h5,
+.swagger-section .swagger-ui-wrap .heading_with_menu h6 {
+ display: block;
+ clear: none;
+ float: left;
+ -moz-box-sizing: border-box;
+ -webkit-box-sizing: border-box;
+ -ms-box-sizing: border-box;
+ box-sizing: border-box;
+ width: 60%;
+}
+.swagger-section .swagger-ui-wrap table {
+ border-collapse: collapse;
+ border-spacing: 0;
+}
+.swagger-section .swagger-ui-wrap table thead tr th {
+ padding: 5px;
+ font-size: 0.9em;
+ color: #666666;
+ border-bottom: 1px solid #999999;
+}
+.swagger-section .swagger-ui-wrap table tbody tr:last-child td {
+ border-bottom: none;
+}
+.swagger-section .swagger-ui-wrap table tbody tr.offset {
+ background-color: #f0f0f0;
+}
+.swagger-section .swagger-ui-wrap table tbody tr td {
+ padding: 6px;
+ font-size: 0.9em;
+ border-bottom: 1px solid #cccccc;
+ vertical-align: top;
+ line-height: 1.3em;
+}
+.swagger-section .swagger-ui-wrap ol {
+ margin: 0px 0 10px;
+ padding: 0 0 0 18px;
+ list-style-type: decimal;
+}
+.swagger-section .swagger-ui-wrap ol li {
+ padding: 5px 0px;
+ font-size: 0.9em;
+ color: #333333;
+}
+.swagger-section .swagger-ui-wrap ol,
+.swagger-section .swagger-ui-wrap ul {
+ list-style: none;
+}
+.swagger-section .swagger-ui-wrap h1 a,
+.swagger-section .swagger-ui-wrap h2 a,
+.swagger-section .swagger-ui-wrap h3 a,
+.swagger-section .swagger-ui-wrap h4 a,
+.swagger-section .swagger-ui-wrap h5 a,
+.swagger-section .swagger-ui-wrap h6 a {
+ text-decoration: none;
+}
+.swagger-section .swagger-ui-wrap h1 a:hover,
+.swagger-section .swagger-ui-wrap h2 a:hover,
+.swagger-section .swagger-ui-wrap h3 a:hover,
+.swagger-section .swagger-ui-wrap h4 a:hover,
+.swagger-section .swagger-ui-wrap h5 a:hover,
+.swagger-section .swagger-ui-wrap h6 a:hover {
+ text-decoration: underline;
+}
+.swagger-section .swagger-ui-wrap h1 span.divider,
+.swagger-section .swagger-ui-wrap h2 span.divider,
+.swagger-section .swagger-ui-wrap h3 span.divider,
+.swagger-section .swagger-ui-wrap h4 span.divider,
+.swagger-section .swagger-ui-wrap h5 span.divider,
+.swagger-section .swagger-ui-wrap h6 span.divider {
+ color: #aaaaaa;
+}
+.swagger-section .swagger-ui-wrap a {
+ color: #547f00;
+}
+.swagger-section .swagger-ui-wrap a img {
+ border: none;
+}
+.swagger-section .swagger-ui-wrap article,
+.swagger-section .swagger-ui-wrap aside,
+.swagger-section .swagger-ui-wrap details,
+.swagger-section .swagger-ui-wrap figcaption,
+.swagger-section .swagger-ui-wrap figure,
+.swagger-section .swagger-ui-wrap footer,
+.swagger-section .swagger-ui-wrap header,
+.swagger-section .swagger-ui-wrap hgroup,
+.swagger-section .swagger-ui-wrap menu,
+.swagger-section .swagger-ui-wrap nav,
+.swagger-section .swagger-ui-wrap section,
+.swagger-section .swagger-ui-wrap summary {
+ display: block;
+}
+.swagger-section .swagger-ui-wrap pre {
+ font-family: "Anonymous Pro", "Menlo", "Consolas", "Bitstream Vera Sans Mono", "Courier New", monospace;
+ background-color: #fcf6db;
+ border: 1px solid #e5e0c6;
+ padding: 10px;
+}
+.swagger-section .swagger-ui-wrap pre code {
+ line-height: 1.6em;
+ background: none;
+}
+.swagger-section .swagger-ui-wrap .content > .content-type > div > label {
+ clear: both;
+ display: block;
+ color: #0F6AB4;
+ font-size: 1.1em;
+ margin: 0;
+ padding: 15px 0 5px;
+}
+.swagger-section .swagger-ui-wrap .content pre {
+ font-size: 12px;
+ margin-top: 5px;
+ padding: 5px;
+}
+.swagger-section .swagger-ui-wrap .icon-btn {
+ cursor: pointer;
+}
+.swagger-section .swagger-ui-wrap .info_title {
+ padding-bottom: 10px;
+ font-weight: bold;
+ font-size: 25px;
+}
+.swagger-section .swagger-ui-wrap .footer {
+ margin-top: 20px;
+}
+.swagger-section .swagger-ui-wrap p.big,
+.swagger-section .swagger-ui-wrap div.big p {
+ font-size: 1em;
+ margin-bottom: 10px;
+}
+.swagger-section .swagger-ui-wrap form.fullwidth ol li.string input,
+.swagger-section .swagger-ui-wrap form.fullwidth ol li.url input,
+.swagger-section .swagger-ui-wrap form.fullwidth ol li.text textarea,
+.swagger-section .swagger-ui-wrap form.fullwidth ol li.numeric input {
+ width: 500px !important;
+}
+.swagger-section .swagger-ui-wrap .info_license {
+ padding-bottom: 5px;
+}
+.swagger-section .swagger-ui-wrap .info_tos {
+ padding-bottom: 5px;
+}
+.swagger-section .swagger-ui-wrap .message-fail {
+ color: #cc0000;
+}
+.swagger-section .swagger-ui-wrap .info_url {
+ padding-bottom: 5px;
+}
+.swagger-section .swagger-ui-wrap .info_email {
+ padding-bottom: 5px;
+}
+.swagger-section .swagger-ui-wrap .info_name {
+ padding-bottom: 5px;
+}
+.swagger-section .swagger-ui-wrap .info_description {
+ padding-bottom: 10px;
+ font-size: 15px;
+}
+.swagger-section .swagger-ui-wrap .markdown ol li,
+.swagger-section .swagger-ui-wrap .markdown ul li {
+ padding: 3px 0px;
+ line-height: 1.4em;
+ color: #333333;
+}
+.swagger-section .swagger-ui-wrap form.formtastic fieldset.inputs ol li.string input,
+.swagger-section .swagger-ui-wrap form.formtastic fieldset.inputs ol li.url input,
+.swagger-section .swagger-ui-wrap form.formtastic fieldset.inputs ol li.numeric input {
+ display: block;
+ padding: 4px;
+ width: auto;
+ clear: both;
+}
+.swagger-section .swagger-ui-wrap form.formtastic fieldset.inputs ol li.string input.title,
+.swagger-section .swagger-ui-wrap form.formtastic fieldset.inputs ol li.url input.title,
+.swagger-section .swagger-ui-wrap form.formtastic fieldset.inputs ol li.numeric input.title {
+ font-size: 1.3em;
+}
+.swagger-section .swagger-ui-wrap table.fullwidth {
+ width: 100%;
+}
+.swagger-section .swagger-ui-wrap .model-signature {
+ font-family: "Droid Sans", sans-serif;
+ font-size: 1em;
+ line-height: 1.5em;
+}
+.swagger-section .swagger-ui-wrap .model-signature .signature-nav a {
+ text-decoration: none;
+ color: #AAA;
+}
+.swagger-section .swagger-ui-wrap .model-signature .signature-nav a:hover {
+ text-decoration: underline;
+ color: black;
+}
+.swagger-section .swagger-ui-wrap .model-signature .signature-nav .selected {
+ color: black;
+ text-decoration: none;
+}
+.swagger-section .swagger-ui-wrap .model-signature .propType {
+ color: #5555aa;
+}
+.swagger-section .swagger-ui-wrap .model-signature pre:hover {
+ background-color: #ffffdd;
+}
+.swagger-section .swagger-ui-wrap .model-signature pre {
+ font-size: .85em;
+ line-height: 1.2em;
+ overflow: auto;
+ max-height: 200px;
+ cursor: pointer;
+}
+.swagger-section .swagger-ui-wrap .model-signature ul.signature-nav {
+ display: block;
+ min-width: 230px;
+ margin: 0;
+ padding: 0;
+}
+.swagger-section .swagger-ui-wrap .model-signature ul.signature-nav li:last-child {
+ padding-right: 0;
+ border-right: none;
+}
+.swagger-section .swagger-ui-wrap .model-signature ul.signature-nav li {
+ float: left;
+ margin: 0 5px 5px 0;
+ padding: 2px 5px 2px 0;
+ border-right: 1px solid #ddd;
+}
+.swagger-section .swagger-ui-wrap .model-signature .propOpt {
+ color: #555;
+}
+.swagger-section .swagger-ui-wrap .model-signature .snippet small {
+ font-size: 0.75em;
+}
+.swagger-section .swagger-ui-wrap .model-signature .propOptKey {
+ font-style: italic;
+}
+.swagger-section .swagger-ui-wrap .model-signature .description .strong {
+ font-weight: bold;
+ color: #000;
+ font-size: .9em;
+}
+.swagger-section .swagger-ui-wrap .model-signature .description div {
+ font-size: 0.9em;
+ line-height: 1.5em;
+ margin-left: 1em;
+}
+.swagger-section .swagger-ui-wrap .model-signature .description .stronger {
+ font-weight: bold;
+ color: #000;
+}
+.swagger-section .swagger-ui-wrap .model-signature .description .propWrap .optionsWrapper {
+ border-spacing: 0;
+ position: absolute;
+ background-color: #ffffff;
+ border: 1px solid #bbbbbb;
+ display: none;
+ font-size: 11px;
+ max-width: 400px;
+ line-height: 30px;
+ color: black;
+ padding: 5px;
+ margin-left: 10px;
+}
+.swagger-section .swagger-ui-wrap .model-signature .description .propWrap .optionsWrapper th {
+ text-align: center;
+ background-color: #eeeeee;
+ border: 1px solid #bbbbbb;
+ font-size: 11px;
+ color: #666666;
+ font-weight: bold;
+ padding: 5px;
+ line-height: 15px;
+}
+.swagger-section .swagger-ui-wrap .model-signature .description .propWrap .optionsWrapper .optionName {
+ font-weight: bold;
+}
+.swagger-section .swagger-ui-wrap .model-signature .description .propDesc.markdown > p:first-child,
+.swagger-section .swagger-ui-wrap .model-signature .description .propDesc.markdown > p:last-child {
+ display: inline;
+}
+.swagger-section .swagger-ui-wrap .model-signature .description .propDesc.markdown > p:not(:first-child):before {
+ display: block;
+ content: '';
+}
+.swagger-section .swagger-ui-wrap .model-signature .description span:last-of-type.propDesc.markdown > p:only-child {
+ margin-right: -3px;
+}
+.swagger-section .swagger-ui-wrap .model-signature .propName {
+ font-weight: bold;
+}
+.swagger-section .swagger-ui-wrap .model-signature .signature-container {
+ clear: both;
+}
+.swagger-section .swagger-ui-wrap .body-textarea {
+ width: 300px;
+ height: 100px;
+ border: 1px solid #aaa;
+}
+.swagger-section .swagger-ui-wrap .markdown p code,
+.swagger-section .swagger-ui-wrap .markdown li code {
+ font-family: "Anonymous Pro", "Menlo", "Consolas", "Bitstream Vera Sans Mono", "Courier New", monospace;
+ background-color: #f0f0f0;
+ color: black;
+ padding: 1px 3px;
+}
+.swagger-section .swagger-ui-wrap .required {
+ font-weight: bold;
+}
+.swagger-section .swagger-ui-wrap .editor_holder {
+ font-family: "Anonymous Pro", "Menlo", "Consolas", "Bitstream Vera Sans Mono", "Courier New", monospace;
+ font-size: 0.9em;
+}
+.swagger-section .swagger-ui-wrap .editor_holder label {
+ font-weight: normal!important;
+ /* JSONEditor uses bold by default for all labels, we revert that back to normal to not give the impression that by default fields are required */
+}
+.swagger-section .swagger-ui-wrap .editor_holder label.required {
+ font-weight: bold!important;
+}
+.swagger-section .swagger-ui-wrap input.parameter {
+ width: 300px;
+ border: 1px solid #aaa;
+}
+.swagger-section .swagger-ui-wrap h1 {
+ color: black;
+ font-size: 1.5em;
+ line-height: 1.3em;
+ padding: 10px 0 10px 0;
+ font-family: "Droid Sans", sans-serif;
+ font-weight: bold;
+}
+.swagger-section .swagger-ui-wrap .heading_with_menu {
+ float: none;
+ clear: both;
+ overflow: hidden;
+ display: block;
+}
+.swagger-section .swagger-ui-wrap .heading_with_menu ul {
+ display: block;
+ clear: none;
+ float: right;
+ -moz-box-sizing: border-box;
+ -webkit-box-sizing: border-box;
+ -ms-box-sizing: border-box;
+ box-sizing: border-box;
+ margin-top: 10px;
+}
+.swagger-section .swagger-ui-wrap h2 {
+ color: black;
+ font-size: 1.3em;
+ padding: 10px 0 10px 0;
+}
+.swagger-section .swagger-ui-wrap h2 a {
+ color: black;
+}
+.swagger-section .swagger-ui-wrap h2 span.sub {
+ font-size: 0.7em;
+ color: #999999;
+ font-style: italic;
+}
+.swagger-section .swagger-ui-wrap h2 span.sub a {
+ color: #777777;
+}
+.swagger-section .swagger-ui-wrap span.weak {
+ color: #666666;
+}
+.swagger-section .swagger-ui-wrap .message-success {
+ color: #89BF04;
+}
+.swagger-section .swagger-ui-wrap caption,
+.swagger-section .swagger-ui-wrap th,
+.swagger-section .swagger-ui-wrap td {
+ text-align: left;
+ font-weight: normal;
+ vertical-align: middle;
+}
+.swagger-section .swagger-ui-wrap .code {
+ font-family: "Anonymous Pro", "Menlo", "Consolas", "Bitstream Vera Sans Mono", "Courier New", monospace;
+}
+.swagger-section .swagger-ui-wrap form.formtastic fieldset.inputs ol li.text textarea {
+ font-family: "Droid Sans", sans-serif;
+ height: 250px;
+ padding: 4px;
+ display: block;
+ clear: both;
+}
+.swagger-section .swagger-ui-wrap form.formtastic fieldset.inputs ol li.select select {
+ display: block;
+ clear: both;
+}
+.swagger-section .swagger-ui-wrap form.formtastic fieldset.inputs ol li.boolean {
+ float: none;
+ clear: both;
+ overflow: hidden;
+ display: block;
+}
+.swagger-section .swagger-ui-wrap form.formtastic fieldset.inputs ol li.boolean label {
+ display: block;
+ float: left;
+ clear: none;
+ margin: 0;
+ padding: 0;
+}
+.swagger-section .swagger-ui-wrap form.formtastic fieldset.inputs ol li.boolean input {
+ display: block;
+ float: left;
+ clear: none;
+ margin: 0 5px 0 0;
+}
+.swagger-section .swagger-ui-wrap form.formtastic fieldset.inputs ol li.required label {
+ color: black;
+}
+.swagger-section .swagger-ui-wrap form.formtastic fieldset.inputs ol li label {
+ display: block;
+ clear: both;
+ width: auto;
+ padding: 0 0 3px;
+ color: #666666;
+}
+.swagger-section .swagger-ui-wrap form.formtastic fieldset.inputs ol li label abbr {
+ padding-left: 3px;
+ color: #888888;
+}
+.swagger-section .swagger-ui-wrap form.formtastic fieldset.inputs ol li p.inline-hints {
+ margin-left: 0;
+ font-style: italic;
+ font-size: 0.9em;
+ margin: 0;
+}
+.swagger-section .swagger-ui-wrap form.formtastic fieldset.buttons {
+ margin: 0;
+ padding: 0;
+}
+.swagger-section .swagger-ui-wrap span.blank,
+.swagger-section .swagger-ui-wrap span.empty {
+ color: #888888;
+ font-style: italic;
+}
+.swagger-section .swagger-ui-wrap .markdown h3 {
+ color: #547f00;
+}
+.swagger-section .swagger-ui-wrap .markdown h4 {
+ color: #666666;
+}
+.swagger-section .swagger-ui-wrap .markdown pre {
+ font-family: "Anonymous Pro", "Menlo", "Consolas", "Bitstream Vera Sans Mono", "Courier New", monospace;
+ background-color: #fcf6db;
+ border: 1px solid #e5e0c6;
+ padding: 10px;
+ margin: 0 0 10px 0;
+}
+.swagger-section .swagger-ui-wrap .markdown pre code {
+ line-height: 1.6em;
+ overflow: auto;
+}
+.swagger-section .swagger-ui-wrap div.gist {
+ margin: 20px 0 25px 0 !important;
+}
+.swagger-section .swagger-ui-wrap ul#resources {
+ font-family: "Droid Sans", sans-serif;
+ font-size: 0.9em;
+}
+.swagger-section .swagger-ui-wrap ul#resources li.resource {
+ border-bottom: 1px solid #dddddd;
+}
+.swagger-section .swagger-ui-wrap ul#resources li.resource:hover div.heading h2 a,
+.swagger-section .swagger-ui-wrap ul#resources li.resource.active div.heading h2 a {
+ color: black;
+}
+.swagger-section .swagger-ui-wrap ul#resources li.resource:hover div.heading ul.options li a,
+.swagger-section .swagger-ui-wrap ul#resources li.resource.active div.heading ul.options li a {
+ color: #555555;
+}
+.swagger-section .swagger-ui-wrap ul#resources li.resource:last-child {
+ border-bottom: none;
+}
+.swagger-section .swagger-ui-wrap ul#resources li.resource div.heading {
+ border: 1px solid transparent;
+ float: none;
+ clear: both;
+ overflow: hidden;
+ display: block;
+}
+.swagger-section .swagger-ui-wrap ul#resources li.resource div.heading ul.options {
+ overflow: hidden;
+ padding: 0;
+ display: block;
+ clear: none;
+ float: right;
+ margin: 14px 10px 0 0;
+}
+.swagger-section .swagger-ui-wrap ul#resources li.resource div.heading ul.options li {
+ float: left;
+ clear: none;
+ margin: 0;
+ padding: 2px 10px;
+ border-right: 1px solid #dddddd;
+ color: #666666;
+ font-size: 0.9em;
+}
+.swagger-section .swagger-ui-wrap ul#resources li.resource div.heading ul.options li a {
+ color: #aaaaaa;
+ text-decoration: none;
+}
+.swagger-section .swagger-ui-wrap ul#resources li.resource div.heading ul.options li a:hover {
+ text-decoration: underline;
+ color: black;
+}
+.swagger-section .swagger-ui-wrap ul#resources li.resource div.heading ul.options li a:hover,
+.swagger-section .swagger-ui-wrap ul#resources li.resource div.heading ul.options li a:active,
+.swagger-section .swagger-ui-wrap ul#resources li.resource div.heading ul.options li a.active {
+ text-decoration: underline;
+}
+.swagger-section .swagger-ui-wrap ul#resources li.resource div.heading ul.options li:first-child,
+.swagger-section .swagger-ui-wrap ul#resources li.resource div.heading ul.options li.first {
+ padding-left: 0;
+}
+.swagger-section .swagger-ui-wrap ul#resources li.resource div.heading ul.options li:last-child,
+.swagger-section .swagger-ui-wrap ul#resources li.resource div.heading ul.options li.last {
+ padding-right: 0;
+ border-right: none;
+}
+.swagger-section .swagger-ui-wrap ul#resources li.resource div.heading ul.options:first-child,
+.swagger-section .swagger-ui-wrap ul#resources li.resource div.heading ul.options.first {
+ padding-left: 0;
+}
+.swagger-section .swagger-ui-wrap ul#resources li.resource div.heading h2 {
+ color: #999999;
+ padding-left: 0;
+ display: block;
+ clear: none;
+ float: left;
+ font-family: "Droid Sans", sans-serif;
+ font-weight: bold;
+}
+.swagger-section .swagger-ui-wrap ul#resources li.resource div.heading h2 a {
+ color: #999999;
+}
+.swagger-section .swagger-ui-wrap ul#resources li.resource div.heading h2 a:hover {
+ color: black;
+}
+.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation {
+ float: none;
+ clear: both;
+ overflow: hidden;
+ display: block;
+ margin: 0 0 10px;
+ padding: 0;
+}
+.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation div.heading {
+ float: none;
+ clear: both;
+ overflow: hidden;
+ display: block;
+ margin: 0;
+ padding: 0;
+}
+.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation div.heading h3 {
+ display: block;
+ clear: none;
+ float: left;
+ width: auto;
+ margin: 0;
+ padding: 0;
+ line-height: 1.1em;
+ color: black;
+}
+.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation div.heading h3 span.path {
+ padding-left: 10px;
+}
+.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation div.heading h3 span.path a {
+ color: black;
+ text-decoration: none;
+}
+.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation div.heading h3 span.path a.toggleOperation.deprecated {
+ text-decoration: line-through;
+}
+.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation div.heading h3 span.path a:hover {
+ text-decoration: underline;
+}
+.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation div.heading h3 span.http_method a {
+ text-transform: uppercase;
+ text-decoration: none;
+ color: white;
+ display: inline-block;
+ width: 50px;
+ font-size: 0.7em;
+ text-align: center;
+ padding: 7px 0 4px;
+ -moz-border-radius: 2px;
+ -webkit-border-radius: 2px;
+ -o-border-radius: 2px;
+ -ms-border-radius: 2px;
+ -khtml-border-radius: 2px;
+ border-radius: 2px;
+}
+.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation div.heading h3 span {
+ margin: 0;
+ padding: 0;
+}
+.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation div.heading ul.options {
+ overflow: hidden;
+ padding: 0;
+ display: block;
+ clear: none;
+ float: right;
+ margin: 6px 10px 0 0;
+}
+.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation div.heading ul.options li {
+ float: left;
+ clear: none;
+ margin: 0;
+ padding: 2px 10px;
+ font-size: 0.9em;
+}
+.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation div.heading ul.options li a {
+ text-decoration: none;
+}
+.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation div.heading ul.options li a .markdown p {
+ color: inherit;
+ padding: 0;
+ line-height: inherit;
+}
+.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation div.heading ul.options li.access {
+ color: black;
+}
+.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation div.content {
+ border-top: none;
+ padding: 10px;
+ -moz-border-radius-bottomleft: 6px;
+ -webkit-border-bottom-left-radius: 6px;
+ -o-border-bottom-left-radius: 6px;
+ -ms-border-bottom-left-radius: 6px;
+ -khtml-border-bottom-left-radius: 6px;
+ border-bottom-left-radius: 6px;
+ -moz-border-radius-bottomright: 6px;
+ -webkit-border-bottom-right-radius: 6px;
+ -o-border-bottom-right-radius: 6px;
+ -ms-border-bottom-right-radius: 6px;
+ -khtml-border-bottom-right-radius: 6px;
+ border-bottom-right-radius: 6px;
+ margin: 0 0 20px;
+}
+.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation div.content h4 {
+ font-size: 1.1em;
+ margin: 0;
+ padding: 15px 0 5px;
+}
+.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation div.content div.sandbox_header {
+ float: none;
+ clear: both;
+ overflow: hidden;
+ display: block;
+}
+.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation div.content div.sandbox_header a {
+ padding: 4px 0 0 10px;
+ display: inline-block;
+ font-size: 0.9em;
+}
+.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation div.content div.sandbox_header input.submit {
+ display: block;
+ clear: none;
+ float: left;
+ padding: 6px 8px;
+}
+.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation div.content div.sandbox_header span.response_throbber {
+ background-image: url('../images/throbber.gif');
+ width: 128px;
+ height: 16px;
+ display: block;
+ clear: none;
+ float: right;
+}
+.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation div.content form input[type='text'].error {
+ outline: 2px solid black;
+ outline-color: #cc0000;
+}
+.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation div.content form select[name='parameterContentType'] {
+ max-width: 300px;
+}
+.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation div.content div.response div.block pre {
+ font-family: "Anonymous Pro", "Menlo", "Consolas", "Bitstream Vera Sans Mono", "Courier New", monospace;
+ padding: 10px;
+ font-size: 0.9em;
+ max-height: 400px;
+ overflow-y: auto;
+}
+.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.put div.heading {
+ background-color: #f9f2e9;
+ border: 1px solid #f0e0ca;
+}
+.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.put div.heading h3 span.http_method a {
+ background-color: #c5862b;
+}
+.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.put div.heading ul.options li {
+ border-right: 1px solid #dddddd;
+ border-right-color: #f0e0ca;
+ color: #c5862b;
+}
+.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.put div.heading ul.options li a {
+ color: #c5862b;
+}
+.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.put div.content {
+ background-color: #faf5ee;
+ border: 1px solid #f0e0ca;
+}
+.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.put div.content h4 {
+ color: #c5862b;
+}
+.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.put div.content div.sandbox_header a {
+ color: #dcb67f;
+}
+.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.head div.heading {
+ background-color: #fcffcd;
+ border: 1px solid black;
+ border-color: #ffd20f;
+}
+.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.head div.heading h3 span.http_method a {
+ text-transform: uppercase;
+ background-color: #ffd20f;
+}
+.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.head div.heading ul.options li {
+ border-right: 1px solid #dddddd;
+ border-right-color: #ffd20f;
+ color: #ffd20f;
+}
+.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.head div.heading ul.options li a {
+ color: #ffd20f;
+}
+.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.head div.content {
+ background-color: #fcffcd;
+ border: 1px solid black;
+ border-color: #ffd20f;
+}
+.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.head div.content h4 {
+ color: #ffd20f;
+}
+.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.head div.content div.sandbox_header a {
+ color: #6fc992;
+}
+.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.delete div.heading {
+ background-color: #f5e8e8;
+ border: 1px solid #e8c6c7;
+}
+.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.delete div.heading h3 span.http_method a {
+ text-transform: uppercase;
+ background-color: #a41e22;
+}
+.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.delete div.heading ul.options li {
+ border-right: 1px solid #dddddd;
+ border-right-color: #e8c6c7;
+ color: #a41e22;
+}
+.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.delete div.heading ul.options li a {
+ color: #a41e22;
+}
+.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.delete div.content {
+ background-color: #f7eded;
+ border: 1px solid #e8c6c7;
+}
+.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.delete div.content h4 {
+ color: #a41e22;
+}
+.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.delete div.content div.sandbox_header a {
+ color: #c8787a;
+}
+.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.post div.heading {
+ background-color: #e7f6ec;
+ border: 1px solid #c3e8d1;
+}
+.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.post div.heading h3 span.http_method a {
+ background-color: #10a54a;
+}
+.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.post div.heading ul.options li {
+ border-right: 1px solid #dddddd;
+ border-right-color: #c3e8d1;
+ color: #10a54a;
+}
+.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.post div.heading ul.options li a {
+ color: #10a54a;
+}
+.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.post div.content {
+ background-color: #ebf7f0;
+ border: 1px solid #c3e8d1;
+}
+.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.post div.content h4 {
+ color: #10a54a;
+}
+.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.post div.content div.sandbox_header a {
+ color: #6fc992;
+}
+.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.patch div.heading {
+ background-color: #FCE9E3;
+ border: 1px solid #F5D5C3;
+}
+.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.patch div.heading h3 span.http_method a {
+ background-color: #D38042;
+}
+.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.patch div.heading ul.options li {
+ border-right: 1px solid #dddddd;
+ border-right-color: #f0cecb;
+ color: #D38042;
+}
+.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.patch div.heading ul.options li a {
+ color: #D38042;
+}
+.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.patch div.content {
+ background-color: #faf0ef;
+ border: 1px solid #f0cecb;
+}
+.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.patch div.content h4 {
+ color: #D38042;
+}
+.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.patch div.content div.sandbox_header a {
+ color: #dcb67f;
+}
+.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.get div.heading {
+ background-color: #e7f0f7;
+ border: 1px solid #c3d9ec;
+}
+.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.get div.heading h3 span.http_method a {
+ background-color: #0f6ab4;
+}
+.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.get div.heading ul.options li {
+ border-right: 1px solid #dddddd;
+ border-right-color: #c3d9ec;
+ color: #0f6ab4;
+}
+.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.get div.heading ul.options li a {
+ color: #0f6ab4;
+}
+.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.get div.content {
+ background-color: #ebf3f9;
+ border: 1px solid #c3d9ec;
+}
+.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.get div.content h4 {
+ color: #0f6ab4;
+}
+.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.get div.content div.sandbox_header a {
+ color: #6fa5d2;
+}
+.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.options div.heading {
+ background-color: #e7f0f7;
+ border: 1px solid #c3d9ec;
+}
+.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.options div.heading h3 span.http_method a {
+ background-color: #0f6ab4;
+}
+.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.options div.heading ul.options li {
+ border-right: 1px solid #dddddd;
+ border-right-color: #c3d9ec;
+ color: #0f6ab4;
+}
+.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.options div.heading ul.options li a {
+ color: #0f6ab4;
+}
+.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.options div.content {
+ background-color: #ebf3f9;
+ border: 1px solid #c3d9ec;
+}
+.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.options div.content h4 {
+ color: #0f6ab4;
+}
+.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.options div.content div.sandbox_header a {
+ color: #6fa5d2;
+}
+.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.get div.content,
+.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.post div.content,
+.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.head div.content,
+.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.put div.content,
+.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.patch div.content,
+.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.delete div.content {
+ border-top: none;
+}
+.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.get div.heading ul.options li:last-child,
+.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.post div.heading ul.options li:last-child,
+.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.head div.heading ul.options li:last-child,
+.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.put div.heading ul.options li:last-child,
+.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.patch div.heading ul.options li:last-child,
+.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.delete div.heading ul.options li:last-child,
+.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.get div.heading ul.options li.last,
+.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.post div.heading ul.options li.last,
+.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.head div.heading ul.options li.last,
+.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.put div.heading ul.options li.last,
+.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.patch div.heading ul.options li.last,
+.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.delete div.heading ul.options li.last {
+ padding-right: 0;
+ border-right: none;
+}
+.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations ul.options li a:hover,
+.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations ul.options li a:active,
+.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations ul.options li a.active {
+ text-decoration: underline;
+}
+.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations ul.options li:first-child,
+.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations ul.options li.first {
+ padding-left: 0;
+}
+.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations:first-child,
+.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations.first {
+ padding-left: 0;
+}
+.swagger-section .swagger-ui-wrap p#colophon {
+ margin: 0 15px 40px 15px;
+ padding: 10px 0;
+ font-size: 0.8em;
+ border-top: 1px solid #dddddd;
+ font-family: "Droid Sans", sans-serif;
+ color: #999999;
+ font-style: italic;
+}
+.swagger-section .swagger-ui-wrap p#colophon a {
+ text-decoration: none;
+ color: #547f00;
+}
+.swagger-section .swagger-ui-wrap h3 {
+ color: black;
+ font-size: 1.1em;
+ padding: 10px 0 10px 0;
+}
+.swagger-section .swagger-ui-wrap .markdown ol,
+.swagger-section .swagger-ui-wrap .markdown ul {
+ font-family: "Droid Sans", sans-serif;
+ margin: 5px 0 10px;
+ padding: 0 0 0 18px;
+ list-style-type: disc;
+}
+.swagger-section .swagger-ui-wrap form.form_box {
+ background-color: #ebf3f9;
+ border: 1px solid #c3d9ec;
+ padding: 10px;
+}
+.swagger-section .swagger-ui-wrap form.form_box label {
+ color: #0f6ab4 !important;
+}
+.swagger-section .swagger-ui-wrap form.form_box input[type=submit] {
+ display: block;
+ padding: 10px;
+}
+.swagger-section .swagger-ui-wrap form.form_box p.weak {
+ font-size: 0.8em;
+}
+.swagger-section .swagger-ui-wrap form.form_box p {
+ font-size: 0.9em;
+ padding: 0 0 15px;
+ color: #7e7b6d;
+}
+.swagger-section .swagger-ui-wrap form.form_box p a {
+ color: #646257;
+}
+.swagger-section .swagger-ui-wrap form.form_box p strong {
+ color: black;
+}
+.swagger-section .swagger-ui-wrap .operation-status td.markdown > p:last-child {
+ padding-bottom: 0;
+}
+.swagger-section .title {
+ font-style: bold;
+}
+.swagger-section .secondary_form {
+ display: none;
+}
+.swagger-section .main_image {
+ display: block;
+ margin-left: auto;
+ margin-right: auto;
+}
+.swagger-section .oauth_body {
+ margin-left: 100px;
+ margin-right: 100px;
+}
+.swagger-section .oauth_submit {
+ text-align: center;
+ display: inline-block;
+}
+.swagger-section .authorize-wrapper {
+ margin: 15px 0 10px;
+}
+.swagger-section .authorize-wrapper_operation {
+ float: right;
+}
+.swagger-section .authorize__btn:hover {
+ text-decoration: underline;
+ cursor: pointer;
+}
+.swagger-section .authorize__btn_operation:hover .authorize-scopes {
+ display: block;
+}
+.swagger-section .authorize-scopes {
+ position: absolute;
+ margin-top: 20px;
+ background: #FFF;
+ border: 1px solid #ccc;
+ border-radius: 5px;
+ display: none;
+ font-size: 13px;
+ max-width: 300px;
+ line-height: 30px;
+ color: black;
+ padding: 5px;
+}
+.swagger-section .authorize-scopes .authorize__scope {
+ text-decoration: none;
+}
+.swagger-section .authorize__btn_operation {
+ height: 18px;
+ vertical-align: middle;
+ display: inline-block;
+ background: url(../images/explorer_icons.png) no-repeat;
+}
+.swagger-section .authorize__btn_operation_login {
+ background-position: 0 0;
+ width: 18px;
+ margin-top: -6px;
+ margin-left: 4px;
+}
+.swagger-section .authorize__btn_operation_logout {
+ background-position: -30px 0;
+ width: 18px;
+ margin-top: -6px;
+ margin-left: 4px;
+}
+.swagger-section #auth_container {
+ color: #fff;
+ display: inline-block;
+ border: none;
+ padding: 5px;
+ width: 87px;
+ height: 13px;
+}
+.swagger-section #auth_container .authorize__btn {
+ color: #fff;
+}
+.swagger-section .auth_container {
+ padding: 0 0 10px;
+ margin-bottom: 5px;
+ border-bottom: solid 1px #CCC;
+ font-size: 0.9em;
+}
+.swagger-section .auth_container .auth__title {
+ color: #547f00;
+ font-size: 1.2em;
+}
+.swagger-section .auth_container .basic_auth__label {
+ display: inline-block;
+ width: 60px;
+}
+.swagger-section .auth_container .auth__description {
+ color: #999999;
+ margin-bottom: 5px;
+}
+.swagger-section .auth_container .auth__button {
+ margin-top: 10px;
+ height: 30px;
+}
+.swagger-section .auth_container .key_auth__field {
+ margin: 5px 0;
+}
+.swagger-section .auth_container .key_auth__label {
+ display: inline-block;
+ width: 60px;
+}
+.swagger-section .api-popup-dialog {
+ position: absolute;
+ display: none;
+}
+.swagger-section .api-popup-dialog-wrapper {
+ z-index: 1000;
+ width: 500px;
+ background: #FFF;
+ padding: 20px;
+ border: 1px solid #ccc;
+ border-radius: 5px;
+ font-size: 13px;
+ color: #777;
+ position: fixed;
+ top: 50%;
+ left: 50%;
+ transform: translate(-50%, -50%);
+}
+.swagger-section .api-popup-dialog-shadow {
+ position: fixed;
+ top: 0;
+ left: 0;
+ width: 100%;
+ height: 100%;
+ opacity: 0.2;
+ background-color: gray;
+ z-index: 900;
+}
+.swagger-section .api-popup-dialog .api-popup-title {
+ font-size: 24px;
+ padding: 10px 0;
+}
+.swagger-section .api-popup-dialog .api-popup-title {
+ font-size: 24px;
+ padding: 10px 0;
+}
+.swagger-section .api-popup-dialog .error-msg {
+ padding-left: 5px;
+ padding-bottom: 5px;
+}
+.swagger-section .api-popup-dialog .api-popup-content {
+ max-height: 500px;
+ overflow-y: auto;
+}
+.swagger-section .api-popup-dialog .api-popup-authbtn {
+ height: 30px;
+}
+.swagger-section .api-popup-dialog .api-popup-cancel {
+ height: 30px;
+}
+.swagger-section .api-popup-scopes {
+ padding: 10px 20px;
+}
+.swagger-section .api-popup-scopes li {
+ padding: 5px 0;
+ line-height: 20px;
+}
+.swagger-section .api-popup-scopes li input {
+ position: relative;
+ top: 2px;
+}
+.swagger-section .api-popup-scopes .api-scope-desc {
+ padding-left: 20px;
+ font-style: italic;
+}
+.swagger-section .api-popup-actions {
+ padding-top: 10px;
+}
+#header {
+ display: none;
+}
+.swagger-section .swagger-ui-wrap .model-signature pre {
+ max-height: none;
+}
+.swagger-section .swagger-ui-wrap .body-textarea {
+ width: 100px;
+}
+.swagger-section .swagger-ui-wrap input.parameter {
+ width: 100px;
+}
+.swagger-section .swagger-ui-wrap ul#resources li.resource div.heading ul.options {
+ display: none;
+}
+.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints {
+ display: block !important;
+}
+.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation div.content {
+ display: block !important;
+}
diff --git a/ydb/core/viewer/content/api/css/reset.css b/ydb/core/viewer/content/api/css/reset.css
index 53cbf520209..b2b078943c4 100644
--- a/ydb/core/viewer/content/api/css/reset.css
+++ b/ydb/core/viewer/content/api/css/reset.css
@@ -1,125 +1,125 @@
-/* http://meyerweb.com/eric/tools/css/reset/ v2.0 | 20110126 */
-html,
-body,
-div,
-span,
-applet,
-object,
-iframe,
-h1,
-h2,
-h3,
-h4,
-h5,
-h6,
-p,
-blockquote,
-pre,
-a,
-abbr,
-acronym,
-address,
-big,
-cite,
-code,
-del,
-dfn,
-em,
-img,
-ins,
-kbd,
-q,
-s,
-samp,
-small,
-strike,
-strong,
-sub,
-sup,
-tt,
-var,
-b,
-u,
-i,
-center,
-dl,
-dt,
-dd,
-ol,
-ul,
-li,
-fieldset,
-form,
-label,
-legend,
-table,
-caption,
-tbody,
-tfoot,
-thead,
-tr,
-th,
-td,
-article,
-aside,
-canvas,
-details,
-embed,
-figure,
-figcaption,
-footer,
-header,
-hgroup,
-menu,
-nav,
-output,
-ruby,
-section,
-summary,
-time,
-mark,
-audio,
-video {
- margin: 0;
- padding: 0;
- border: 0;
- font-size: 100%;
- font: inherit;
- vertical-align: baseline;
-}
-/* HTML5 display-role reset for older browsers */
-article,
-aside,
-details,
-figcaption,
-figure,
-footer,
-header,
-hgroup,
-menu,
-nav,
-section {
- display: block;
-}
-body {
- line-height: 1;
-}
-ol,
-ul {
- list-style: none;
-}
-blockquote,
-q {
- quotes: none;
-}
-blockquote:before,
-blockquote:after,
-q:before,
-q:after {
- content: '';
- content: none;
-}
-table {
- border-collapse: collapse;
- border-spacing: 0;
-}
+/* http://meyerweb.com/eric/tools/css/reset/ v2.0 | 20110126 */
+html,
+body,
+div,
+span,
+applet,
+object,
+iframe,
+h1,
+h2,
+h3,
+h4,
+h5,
+h6,
+p,
+blockquote,
+pre,
+a,
+abbr,
+acronym,
+address,
+big,
+cite,
+code,
+del,
+dfn,
+em,
+img,
+ins,
+kbd,
+q,
+s,
+samp,
+small,
+strike,
+strong,
+sub,
+sup,
+tt,
+var,
+b,
+u,
+i,
+center,
+dl,
+dt,
+dd,
+ol,
+ul,
+li,
+fieldset,
+form,
+label,
+legend,
+table,
+caption,
+tbody,
+tfoot,
+thead,
+tr,
+th,
+td,
+article,
+aside,
+canvas,
+details,
+embed,
+figure,
+figcaption,
+footer,
+header,
+hgroup,
+menu,
+nav,
+output,
+ruby,
+section,
+summary,
+time,
+mark,
+audio,
+video {
+ margin: 0;
+ padding: 0;
+ border: 0;
+ font-size: 100%;
+ font: inherit;
+ vertical-align: baseline;
+}
+/* HTML5 display-role reset for older browsers */
+article,
+aside,
+details,
+figcaption,
+figure,
+footer,
+header,
+hgroup,
+menu,
+nav,
+section {
+ display: block;
+}
+body {
+ line-height: 1;
+}
+ol,
+ul {
+ list-style: none;
+}
+blockquote,
+q {
+ quotes: none;
+}
+blockquote:before,
+blockquote:after,
+q:before,
+q:after {
+ content: '';
+ content: none;
+}
+table {
+ border-collapse: collapse;
+ border-spacing: 0;
+}
diff --git a/ydb/core/viewer/content/api/css/screen.css b/ydb/core/viewer/content/api/css/screen.css
index db971457cde..39ff583e834 100644
--- a/ydb/core/viewer/content/api/css/screen.css
+++ b/ydb/core/viewer/content/api/css/screen.css
@@ -1,1494 +1,1494 @@
-/* Original style from softwaremaniacs.org (c) Ivan Sagalaev <Maniac@SoftwareManiacs.Org> */
-.swagger-section pre code {
- display: block;
- padding: 0.5em;
- background: #F0F0F0;
-}
-.swagger-section pre code,
-.swagger-section pre .subst,
-.swagger-section pre .tag .title,
-.swagger-section pre .lisp .title,
-.swagger-section pre .clojure .built_in,
-.swagger-section pre .nginx .title {
- color: black;
-}
-.swagger-section pre .string,
-.swagger-section pre .title,
-.swagger-section pre .constant,
-.swagger-section pre .parent,
-.swagger-section pre .tag .value,
-.swagger-section pre .rules .value,
-.swagger-section pre .rules .value .number,
-.swagger-section pre .preprocessor,
-.swagger-section pre .ruby .symbol,
-.swagger-section pre .ruby .symbol .string,
-.swagger-section pre .aggregate,
-.swagger-section pre .template_tag,
-.swagger-section pre .django .variable,
-.swagger-section pre .smalltalk .class,
-.swagger-section pre .addition,
-.swagger-section pre .flow,
-.swagger-section pre .stream,
-.swagger-section pre .bash .variable,
-.swagger-section pre .apache .tag,
-.swagger-section pre .apache .cbracket,
-.swagger-section pre .tex .command,
-.swagger-section pre .tex .special,
-.swagger-section pre .erlang_repl .function_or_atom,
-.swagger-section pre .markdown .header {
- color: #800;
-}
-.swagger-section pre .comment,
-.swagger-section pre .annotation,
-.swagger-section pre .template_comment,
-.swagger-section pre .diff .header,
-.swagger-section pre .chunk,
-.swagger-section pre .markdown .blockquote {
- color: #888;
-}
-.swagger-section pre .number,
-.swagger-section pre .date,
-.swagger-section pre .regexp,
-.swagger-section pre .literal,
-.swagger-section pre .smalltalk .symbol,
-.swagger-section pre .smalltalk .char,
-.swagger-section pre .go .constant,
-.swagger-section pre .change,
-.swagger-section pre .markdown .bullet,
-.swagger-section pre .markdown .link_url {
- color: #080;
-}
-.swagger-section pre .label,
-.swagger-section pre .javadoc,
-.swagger-section pre .ruby .string,
-.swagger-section pre .decorator,
-.swagger-section pre .filter .argument,
-.swagger-section pre .localvars,
-.swagger-section pre .array,
-.swagger-section pre .attr_selector,
-.swagger-section pre .important,
-.swagger-section pre .pseudo,
-.swagger-section pre .pi,
-.swagger-section pre .doctype,
-.swagger-section pre .deletion,
-.swagger-section pre .envvar,
-.swagger-section pre .shebang,
-.swagger-section pre .apache .sqbracket,
-.swagger-section pre .nginx .built_in,
-.swagger-section pre .tex .formula,
-.swagger-section pre .erlang_repl .reserved,
-.swagger-section pre .prompt,
-.swagger-section pre .markdown .link_label,
-.swagger-section pre .vhdl .attribute,
-.swagger-section pre .clojure .attribute,
-.swagger-section pre .coffeescript .property {
- color: #88F;
-}
-.swagger-section pre .keyword,
-.swagger-section pre .id,
-.swagger-section pre .phpdoc,
-.swagger-section pre .title,
-.swagger-section pre .built_in,
-.swagger-section pre .aggregate,
-.swagger-section pre .css .tag,
-.swagger-section pre .javadoctag,
-.swagger-section pre .phpdoc,
-.swagger-section pre .yardoctag,
-.swagger-section pre .smalltalk .class,
-.swagger-section pre .winutils,
-.swagger-section pre .bash .variable,
-.swagger-section pre .apache .tag,
-.swagger-section pre .go .typename,
-.swagger-section pre .tex .command,
-.swagger-section pre .markdown .strong,
-.swagger-section pre .request,
-.swagger-section pre .status {
- font-weight: bold;
-}
-.swagger-section pre .markdown .emphasis {
- font-style: italic;
-}
-.swagger-section pre .nginx .built_in {
- font-weight: normal;
-}
-.swagger-section pre .coffeescript .javascript,
-.swagger-section pre .javascript .xml,
-.swagger-section pre .tex .formula,
-.swagger-section pre .xml .javascript,
-.swagger-section pre .xml .vbscript,
-.swagger-section pre .xml .css,
-.swagger-section pre .xml .cdata {
- opacity: 0.5;
-}
-.swagger-section .hljs {
- display: block;
- overflow-x: auto;
- padding: 0.5em;
- background: #F0F0F0;
-}
-.swagger-section .hljs,
-.swagger-section .hljs-subst {
- color: #444;
-}
-.swagger-section .hljs-keyword,
-.swagger-section .hljs-attribute,
-.swagger-section .hljs-selector-tag,
-.swagger-section .hljs-meta-keyword,
-.swagger-section .hljs-doctag,
-.swagger-section .hljs-name {
- font-weight: bold;
-}
-.swagger-section .hljs-built_in,
-.swagger-section .hljs-literal,
-.swagger-section .hljs-bullet,
-.swagger-section .hljs-code,
-.swagger-section .hljs-addition {
- color: #1F811F;
-}
-.swagger-section .hljs-regexp,
-.swagger-section .hljs-symbol,
-.swagger-section .hljs-variable,
-.swagger-section .hljs-template-variable,
-.swagger-section .hljs-link,
-.swagger-section .hljs-selector-attr,
-.swagger-section .hljs-selector-pseudo {
- color: #BC6060;
-}
-.swagger-section .hljs-type,
-.swagger-section .hljs-string,
-.swagger-section .hljs-number,
-.swagger-section .hljs-selector-id,
-.swagger-section .hljs-selector-class,
-.swagger-section .hljs-quote,
-.swagger-section .hljs-template-tag,
-.swagger-section .hljs-deletion {
- color: #880000;
-}
-.swagger-section .hljs-title,
-.swagger-section .hljs-section {
- color: #880000;
- font-weight: bold;
-}
-.swagger-section .hljs-comment {
- color: #888888;
-}
-.swagger-section .hljs-meta {
- color: #2B6EA1;
-}
-.swagger-section .hljs-emphasis {
- font-style: italic;
-}
-.swagger-section .hljs-strong {
- font-weight: bold;
-}
-.swagger-section .swagger-ui-wrap {
- line-height: 1;
- font-family: "Droid Sans", sans-serif;
- min-width: 760px;
- max-width: 960px;
- margin-left: auto;
- margin-right: auto;
- /* JSONEditor specific styling */
-}
-.swagger-section .swagger-ui-wrap b,
-.swagger-section .swagger-ui-wrap strong {
- font-family: "Droid Sans", sans-serif;
- font-weight: bold;
-}
-.swagger-section .swagger-ui-wrap q,
-.swagger-section .swagger-ui-wrap blockquote {
- quotes: none;
-}
-.swagger-section .swagger-ui-wrap p {
- line-height: 1.4em;
- padding: 0 0 10px;
- color: #333333;
-}
-.swagger-section .swagger-ui-wrap q:before,
-.swagger-section .swagger-ui-wrap q:after,
-.swagger-section .swagger-ui-wrap blockquote:before,
-.swagger-section .swagger-ui-wrap blockquote:after {
- content: none;
-}
-.swagger-section .swagger-ui-wrap .heading_with_menu h1,
-.swagger-section .swagger-ui-wrap .heading_with_menu h2,
-.swagger-section .swagger-ui-wrap .heading_with_menu h3,
-.swagger-section .swagger-ui-wrap .heading_with_menu h4,
-.swagger-section .swagger-ui-wrap .heading_with_menu h5,
-.swagger-section .swagger-ui-wrap .heading_with_menu h6 {
- display: block;
- clear: none;
- float: left;
- -moz-box-sizing: border-box;
- -webkit-box-sizing: border-box;
- -ms-box-sizing: border-box;
- box-sizing: border-box;
- width: 60%;
-}
-.swagger-section .swagger-ui-wrap table {
- border-collapse: collapse;
- border-spacing: 0;
-}
-.swagger-section .swagger-ui-wrap table thead tr th {
- padding: 5px;
- font-size: 0.9em;
- color: #666666;
- border-bottom: 1px solid #999999;
-}
-.swagger-section .swagger-ui-wrap table tbody tr:last-child td {
- border-bottom: none;
-}
-.swagger-section .swagger-ui-wrap table tbody tr.offset {
- background-color: #f0f0f0;
-}
-.swagger-section .swagger-ui-wrap table tbody tr td {
- padding: 6px;
- font-size: 0.9em;
- border-bottom: 1px solid #cccccc;
- vertical-align: top;
- line-height: 1.3em;
-}
-.swagger-section .swagger-ui-wrap ol {
- margin: 0px 0 10px;
- padding: 0 0 0 18px;
- list-style-type: decimal;
-}
-.swagger-section .swagger-ui-wrap ol li {
- padding: 5px 0px;
- font-size: 0.9em;
- color: #333333;
-}
-.swagger-section .swagger-ui-wrap ol,
-.swagger-section .swagger-ui-wrap ul {
- list-style: none;
-}
-.swagger-section .swagger-ui-wrap h1 a,
-.swagger-section .swagger-ui-wrap h2 a,
-.swagger-section .swagger-ui-wrap h3 a,
-.swagger-section .swagger-ui-wrap h4 a,
-.swagger-section .swagger-ui-wrap h5 a,
-.swagger-section .swagger-ui-wrap h6 a {
- text-decoration: none;
-}
-.swagger-section .swagger-ui-wrap h1 a:hover,
-.swagger-section .swagger-ui-wrap h2 a:hover,
-.swagger-section .swagger-ui-wrap h3 a:hover,
-.swagger-section .swagger-ui-wrap h4 a:hover,
-.swagger-section .swagger-ui-wrap h5 a:hover,
-.swagger-section .swagger-ui-wrap h6 a:hover {
- text-decoration: underline;
-}
-.swagger-section .swagger-ui-wrap h1 span.divider,
-.swagger-section .swagger-ui-wrap h2 span.divider,
-.swagger-section .swagger-ui-wrap h3 span.divider,
-.swagger-section .swagger-ui-wrap h4 span.divider,
-.swagger-section .swagger-ui-wrap h5 span.divider,
-.swagger-section .swagger-ui-wrap h6 span.divider {
- color: #aaaaaa;
-}
-.swagger-section .swagger-ui-wrap a {
- color: #547f00;
-}
-.swagger-section .swagger-ui-wrap a img {
- border: none;
-}
-.swagger-section .swagger-ui-wrap article,
-.swagger-section .swagger-ui-wrap aside,
-.swagger-section .swagger-ui-wrap details,
-.swagger-section .swagger-ui-wrap figcaption,
-.swagger-section .swagger-ui-wrap figure,
-.swagger-section .swagger-ui-wrap footer,
-.swagger-section .swagger-ui-wrap header,
-.swagger-section .swagger-ui-wrap hgroup,
-.swagger-section .swagger-ui-wrap menu,
-.swagger-section .swagger-ui-wrap nav,
-.swagger-section .swagger-ui-wrap section,
-.swagger-section .swagger-ui-wrap summary {
- display: block;
-}
-.swagger-section .swagger-ui-wrap pre {
- font-family: "Anonymous Pro", "Menlo", "Consolas", "Bitstream Vera Sans Mono", "Courier New", monospace;
- background-color: #fcf6db;
- border: 1px solid #e5e0c6;
- padding: 10px;
-}
-.swagger-section .swagger-ui-wrap pre code {
- line-height: 1.6em;
- background: none;
-}
-.swagger-section .swagger-ui-wrap .content > .content-type > div > label {
- clear: both;
- display: block;
- color: #0F6AB4;
- font-size: 1.1em;
- margin: 0;
- padding: 15px 0 5px;
-}
-.swagger-section .swagger-ui-wrap .content pre {
- font-size: 12px;
- margin-top: 5px;
- padding: 5px;
-}
-.swagger-section .swagger-ui-wrap .icon-btn {
- cursor: pointer;
-}
-.swagger-section .swagger-ui-wrap .info_title {
- padding-bottom: 10px;
- font-weight: bold;
- font-size: 25px;
-}
-.swagger-section .swagger-ui-wrap .footer {
- margin-top: 20px;
-}
-.swagger-section .swagger-ui-wrap p.big,
-.swagger-section .swagger-ui-wrap div.big p {
- font-size: 1em;
- margin-bottom: 10px;
-}
-.swagger-section .swagger-ui-wrap form.fullwidth ol li.string input,
-.swagger-section .swagger-ui-wrap form.fullwidth ol li.url input,
-.swagger-section .swagger-ui-wrap form.fullwidth ol li.text textarea,
-.swagger-section .swagger-ui-wrap form.fullwidth ol li.numeric input {
- width: 500px !important;
-}
-.swagger-section .swagger-ui-wrap .info_license {
- padding-bottom: 5px;
-}
-.swagger-section .swagger-ui-wrap .info_tos {
- padding-bottom: 5px;
-}
-.swagger-section .swagger-ui-wrap .message-fail {
- color: #cc0000;
-}
-.swagger-section .swagger-ui-wrap .info_url {
- padding-bottom: 5px;
-}
-.swagger-section .swagger-ui-wrap .info_email {
- padding-bottom: 5px;
-}
-.swagger-section .swagger-ui-wrap .info_name {
- padding-bottom: 5px;
-}
-.swagger-section .swagger-ui-wrap .info_description {
- padding-bottom: 10px;
- font-size: 15px;
-}
-.swagger-section .swagger-ui-wrap .markdown ol li,
-.swagger-section .swagger-ui-wrap .markdown ul li {
- padding: 3px 0px;
- line-height: 1.4em;
- color: #333333;
-}
-.swagger-section .swagger-ui-wrap form.formtastic fieldset.inputs ol li.string input,
-.swagger-section .swagger-ui-wrap form.formtastic fieldset.inputs ol li.url input,
-.swagger-section .swagger-ui-wrap form.formtastic fieldset.inputs ol li.numeric input {
- display: block;
- padding: 4px;
- width: auto;
- clear: both;
-}
-.swagger-section .swagger-ui-wrap form.formtastic fieldset.inputs ol li.string input.title,
-.swagger-section .swagger-ui-wrap form.formtastic fieldset.inputs ol li.url input.title,
-.swagger-section .swagger-ui-wrap form.formtastic fieldset.inputs ol li.numeric input.title {
- font-size: 1.3em;
-}
-.swagger-section .swagger-ui-wrap table.fullwidth {
- width: 100%;
-}
-.swagger-section .swagger-ui-wrap .model-signature {
- font-family: "Droid Sans", sans-serif;
- font-size: 1em;
- line-height: 1.5em;
-}
-.swagger-section .swagger-ui-wrap .model-signature .signature-nav a {
- text-decoration: none;
- color: #AAA;
-}
-.swagger-section .swagger-ui-wrap .model-signature .signature-nav a:hover {
- text-decoration: underline;
- color: black;
-}
-.swagger-section .swagger-ui-wrap .model-signature .signature-nav .selected {
- color: black;
- text-decoration: none;
-}
-.swagger-section .swagger-ui-wrap .model-signature .propType {
- color: #5555aa;
-}
-.swagger-section .swagger-ui-wrap .model-signature pre:hover {
- background-color: #ffffdd;
-}
-.swagger-section .swagger-ui-wrap .model-signature pre {
- font-size: .85em;
- line-height: 1.2em;
- overflow: auto;
- max-height: 200px;
- cursor: pointer;
-}
-.swagger-section .swagger-ui-wrap .model-signature ul.signature-nav {
- display: block;
- min-width: 230px;
- margin: 0;
- padding: 0;
-}
-.swagger-section .swagger-ui-wrap .model-signature ul.signature-nav li:last-child {
- padding-right: 0;
- border-right: none;
-}
-.swagger-section .swagger-ui-wrap .model-signature ul.signature-nav li {
- float: left;
- margin: 0 5px 5px 0;
- padding: 2px 5px 2px 0;
- border-right: 1px solid #ddd;
-}
-.swagger-section .swagger-ui-wrap .model-signature .propOpt {
- color: #555;
-}
-.swagger-section .swagger-ui-wrap .model-signature .snippet small {
- font-size: 0.75em;
-}
-.swagger-section .swagger-ui-wrap .model-signature .propOptKey {
- font-style: italic;
-}
-.swagger-section .swagger-ui-wrap .model-signature .description .strong {
- font-weight: bold;
- color: #000;
- font-size: .9em;
-}
-.swagger-section .swagger-ui-wrap .model-signature .description div {
- font-size: 0.9em;
- line-height: 1.5em;
- margin-left: 1em;
-}
-.swagger-section .swagger-ui-wrap .model-signature .description .stronger {
- font-weight: bold;
- color: #000;
-}
-.swagger-section .swagger-ui-wrap .model-signature .description .propWrap .optionsWrapper {
- border-spacing: 0;
- position: absolute;
- background-color: #ffffff;
- border: 1px solid #bbbbbb;
- display: none;
- font-size: 11px;
- max-width: 400px;
- line-height: 30px;
- color: black;
- padding: 5px;
- margin-left: 10px;
-}
-.swagger-section .swagger-ui-wrap .model-signature .description .propWrap .optionsWrapper th {
- text-align: center;
- background-color: #eeeeee;
- border: 1px solid #bbbbbb;
- font-size: 11px;
- color: #666666;
- font-weight: bold;
- padding: 5px;
- line-height: 15px;
-}
-.swagger-section .swagger-ui-wrap .model-signature .description .propWrap .optionsWrapper .optionName {
- font-weight: bold;
-}
-.swagger-section .swagger-ui-wrap .model-signature .description .propDesc.markdown > p:first-child,
-.swagger-section .swagger-ui-wrap .model-signature .description .propDesc.markdown > p:last-child {
- display: inline;
-}
-.swagger-section .swagger-ui-wrap .model-signature .description .propDesc.markdown > p:not(:first-child):before {
- display: block;
- content: '';
-}
-.swagger-section .swagger-ui-wrap .model-signature .description span:last-of-type.propDesc.markdown > p:only-child {
- margin-right: -3px;
-}
-.swagger-section .swagger-ui-wrap .model-signature .propName {
- font-weight: bold;
-}
-.swagger-section .swagger-ui-wrap .model-signature .signature-container {
- clear: both;
-}
-.swagger-section .swagger-ui-wrap .body-textarea {
- width: 300px;
- height: 100px;
- border: 1px solid #aaa;
-}
-.swagger-section .swagger-ui-wrap .markdown p code,
-.swagger-section .swagger-ui-wrap .markdown li code {
- font-family: "Anonymous Pro", "Menlo", "Consolas", "Bitstream Vera Sans Mono", "Courier New", monospace;
- background-color: #f0f0f0;
- color: black;
- padding: 1px 3px;
-}
-.swagger-section .swagger-ui-wrap .required {
- font-weight: bold;
-}
-.swagger-section .swagger-ui-wrap .editor_holder {
- font-family: "Anonymous Pro", "Menlo", "Consolas", "Bitstream Vera Sans Mono", "Courier New", monospace;
- font-size: 0.9em;
-}
-.swagger-section .swagger-ui-wrap .editor_holder label {
- font-weight: normal!important;
- /* JSONEditor uses bold by default for all labels, we revert that back to normal to not give the impression that by default fields are required */
-}
-.swagger-section .swagger-ui-wrap .editor_holder label.required {
- font-weight: bold!important;
-}
-.swagger-section .swagger-ui-wrap input.parameter {
- width: 300px;
- border: 1px solid #aaa;
-}
-.swagger-section .swagger-ui-wrap h1 {
- color: black;
- font-size: 1.5em;
- line-height: 1.3em;
- padding: 10px 0 10px 0;
- font-family: "Droid Sans", sans-serif;
- font-weight: bold;
-}
-.swagger-section .swagger-ui-wrap .heading_with_menu {
- float: none;
- clear: both;
- overflow: hidden;
- display: block;
-}
-.swagger-section .swagger-ui-wrap .heading_with_menu ul {
- display: block;
- clear: none;
- float: right;
- -moz-box-sizing: border-box;
- -webkit-box-sizing: border-box;
- -ms-box-sizing: border-box;
- box-sizing: border-box;
- margin-top: 10px;
-}
-.swagger-section .swagger-ui-wrap h2 {
- color: black;
- font-size: 1.3em;
- padding: 10px 0 10px 0;
-}
-.swagger-section .swagger-ui-wrap h2 a {
- color: black;
-}
-.swagger-section .swagger-ui-wrap h2 span.sub {
- font-size: 0.7em;
- color: #999999;
- font-style: italic;
-}
-.swagger-section .swagger-ui-wrap h2 span.sub a {
- color: #777777;
-}
-.swagger-section .swagger-ui-wrap span.weak {
- color: #666666;
-}
-.swagger-section .swagger-ui-wrap .message-success {
- color: #89BF04;
-}
-.swagger-section .swagger-ui-wrap caption,
-.swagger-section .swagger-ui-wrap th,
-.swagger-section .swagger-ui-wrap td {
- text-align: left;
- font-weight: normal;
- vertical-align: middle;
-}
-.swagger-section .swagger-ui-wrap .code {
- font-family: "Anonymous Pro", "Menlo", "Consolas", "Bitstream Vera Sans Mono", "Courier New", monospace;
-}
-.swagger-section .swagger-ui-wrap form.formtastic fieldset.inputs ol li.text textarea {
- font-family: "Droid Sans", sans-serif;
- height: 250px;
- padding: 4px;
- display: block;
- clear: both;
-}
-.swagger-section .swagger-ui-wrap form.formtastic fieldset.inputs ol li.select select {
- display: block;
- clear: both;
-}
-.swagger-section .swagger-ui-wrap form.formtastic fieldset.inputs ol li.boolean {
- float: none;
- clear: both;
- overflow: hidden;
- display: block;
-}
-.swagger-section .swagger-ui-wrap form.formtastic fieldset.inputs ol li.boolean label {
- display: block;
- float: left;
- clear: none;
- margin: 0;
- padding: 0;
-}
-.swagger-section .swagger-ui-wrap form.formtastic fieldset.inputs ol li.boolean input {
- display: block;
- float: left;
- clear: none;
- margin: 0 5px 0 0;
-}
-.swagger-section .swagger-ui-wrap form.formtastic fieldset.inputs ol li.required label {
- color: black;
-}
-.swagger-section .swagger-ui-wrap form.formtastic fieldset.inputs ol li label {
- display: block;
- clear: both;
- width: auto;
- padding: 0 0 3px;
- color: #666666;
-}
-.swagger-section .swagger-ui-wrap form.formtastic fieldset.inputs ol li label abbr {
- padding-left: 3px;
- color: #888888;
-}
-.swagger-section .swagger-ui-wrap form.formtastic fieldset.inputs ol li p.inline-hints {
- margin-left: 0;
- font-style: italic;
- font-size: 0.9em;
- margin: 0;
-}
-.swagger-section .swagger-ui-wrap form.formtastic fieldset.buttons {
- margin: 0;
- padding: 0;
-}
-.swagger-section .swagger-ui-wrap span.blank,
-.swagger-section .swagger-ui-wrap span.empty {
- color: #888888;
- font-style: italic;
-}
-.swagger-section .swagger-ui-wrap .markdown h3 {
- color: #547f00;
-}
-.swagger-section .swagger-ui-wrap .markdown h4 {
- color: #666666;
-}
-.swagger-section .swagger-ui-wrap .markdown pre {
- font-family: "Anonymous Pro", "Menlo", "Consolas", "Bitstream Vera Sans Mono", "Courier New", monospace;
- background-color: #fcf6db;
- border: 1px solid #e5e0c6;
- padding: 10px;
- margin: 0 0 10px 0;
-}
-.swagger-section .swagger-ui-wrap .markdown pre code {
- line-height: 1.6em;
- overflow: auto;
-}
-.swagger-section .swagger-ui-wrap div.gist {
- margin: 20px 0 25px 0 !important;
-}
-.swagger-section .swagger-ui-wrap ul#resources {
- font-family: "Droid Sans", sans-serif;
- font-size: 0.9em;
-}
-.swagger-section .swagger-ui-wrap ul#resources li.resource {
- border-bottom: 1px solid #dddddd;
-}
-.swagger-section .swagger-ui-wrap ul#resources li.resource:hover div.heading h2 a,
-.swagger-section .swagger-ui-wrap ul#resources li.resource.active div.heading h2 a {
- color: black;
-}
-.swagger-section .swagger-ui-wrap ul#resources li.resource:hover div.heading ul.options li a,
-.swagger-section .swagger-ui-wrap ul#resources li.resource.active div.heading ul.options li a {
- color: #555555;
-}
-.swagger-section .swagger-ui-wrap ul#resources li.resource:last-child {
- border-bottom: none;
-}
-.swagger-section .swagger-ui-wrap ul#resources li.resource div.heading {
- border: 1px solid transparent;
- float: none;
- clear: both;
- overflow: hidden;
- display: block;
-}
-.swagger-section .swagger-ui-wrap ul#resources li.resource div.heading ul.options {
- overflow: hidden;
- padding: 0;
- display: block;
- clear: none;
- float: right;
- margin: 14px 10px 0 0;
-}
-.swagger-section .swagger-ui-wrap ul#resources li.resource div.heading ul.options li {
- float: left;
- clear: none;
- margin: 0;
- padding: 2px 10px;
- border-right: 1px solid #dddddd;
- color: #666666;
- font-size: 0.9em;
-}
-.swagger-section .swagger-ui-wrap ul#resources li.resource div.heading ul.options li a {
- color: #aaaaaa;
- text-decoration: none;
-}
-.swagger-section .swagger-ui-wrap ul#resources li.resource div.heading ul.options li a:hover {
- text-decoration: underline;
- color: black;
-}
-.swagger-section .swagger-ui-wrap ul#resources li.resource div.heading ul.options li a:hover,
-.swagger-section .swagger-ui-wrap ul#resources li.resource div.heading ul.options li a:active,
-.swagger-section .swagger-ui-wrap ul#resources li.resource div.heading ul.options li a.active {
- text-decoration: underline;
-}
-.swagger-section .swagger-ui-wrap ul#resources li.resource div.heading ul.options li:first-child,
-.swagger-section .swagger-ui-wrap ul#resources li.resource div.heading ul.options li.first {
- padding-left: 0;
-}
-.swagger-section .swagger-ui-wrap ul#resources li.resource div.heading ul.options li:last-child,
-.swagger-section .swagger-ui-wrap ul#resources li.resource div.heading ul.options li.last {
- padding-right: 0;
- border-right: none;
-}
-.swagger-section .swagger-ui-wrap ul#resources li.resource div.heading ul.options:first-child,
-.swagger-section .swagger-ui-wrap ul#resources li.resource div.heading ul.options.first {
- padding-left: 0;
-}
-.swagger-section .swagger-ui-wrap ul#resources li.resource div.heading h2 {
- color: #999999;
- padding-left: 0;
- display: block;
- clear: none;
- float: left;
- font-family: "Droid Sans", sans-serif;
- font-weight: bold;
-}
-.swagger-section .swagger-ui-wrap ul#resources li.resource div.heading h2 a {
- color: #999999;
-}
-.swagger-section .swagger-ui-wrap ul#resources li.resource div.heading h2 a:hover {
- color: black;
-}
-.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation {
- float: none;
- clear: both;
- overflow: hidden;
- display: block;
- margin: 0 0 10px;
- padding: 0;
-}
-.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation div.heading {
- float: none;
- clear: both;
- overflow: hidden;
- display: block;
- margin: 0;
- padding: 0;
-}
-.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation div.heading h3 {
- display: block;
- clear: none;
- float: left;
- width: auto;
- margin: 0;
- padding: 0;
- line-height: 1.1em;
- color: black;
-}
-.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation div.heading h3 span.path {
- padding-left: 10px;
-}
-.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation div.heading h3 span.path a {
- color: black;
- text-decoration: none;
-}
-.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation div.heading h3 span.path a.toggleOperation.deprecated {
- text-decoration: line-through;
-}
-.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation div.heading h3 span.path a:hover {
- text-decoration: underline;
-}
-.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation div.heading h3 span.http_method a {
- text-transform: uppercase;
- text-decoration: none;
- color: white;
- display: inline-block;
- width: 50px;
- font-size: 0.7em;
- text-align: center;
- padding: 7px 0 4px;
- -moz-border-radius: 2px;
- -webkit-border-radius: 2px;
- -o-border-radius: 2px;
- -ms-border-radius: 2px;
- -khtml-border-radius: 2px;
- border-radius: 2px;
-}
-.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation div.heading h3 span {
- margin: 0;
- padding: 0;
-}
-.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation div.heading ul.options {
- overflow: hidden;
- padding: 0;
- display: block;
- clear: none;
- float: right;
- margin: 6px 10px 0 0;
-}
-.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation div.heading ul.options li {
- float: left;
- clear: none;
- margin: 0;
- padding: 2px 10px;
- font-size: 0.9em;
-}
-.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation div.heading ul.options li a {
- text-decoration: none;
-}
-.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation div.heading ul.options li a .markdown p {
- color: inherit;
- padding: 0;
- line-height: inherit;
-}
-.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation div.heading ul.options li.access {
- color: black;
-}
-.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation div.content {
- border-top: none;
- padding: 10px;
- -moz-border-radius-bottomleft: 6px;
- -webkit-border-bottom-left-radius: 6px;
- -o-border-bottom-left-radius: 6px;
- -ms-border-bottom-left-radius: 6px;
- -khtml-border-bottom-left-radius: 6px;
- border-bottom-left-radius: 6px;
- -moz-border-radius-bottomright: 6px;
- -webkit-border-bottom-right-radius: 6px;
- -o-border-bottom-right-radius: 6px;
- -ms-border-bottom-right-radius: 6px;
- -khtml-border-bottom-right-radius: 6px;
- border-bottom-right-radius: 6px;
- margin: 0 0 20px;
-}
-.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation div.content h4 {
- font-size: 1.1em;
- margin: 0;
- padding: 15px 0 5px;
-}
-.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation div.content div.sandbox_header {
- float: none;
- clear: both;
- overflow: hidden;
- display: block;
-}
-.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation div.content div.sandbox_header a {
- padding: 4px 0 0 10px;
- display: inline-block;
- font-size: 0.9em;
-}
-.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation div.content div.sandbox_header input.submit {
- display: block;
- clear: none;
- float: left;
- padding: 6px 8px;
-}
-.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation div.content div.sandbox_header span.response_throbber {
- background-image: url('../images/throbber.gif');
- width: 128px;
- height: 16px;
- display: block;
- clear: none;
- float: right;
-}
-.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation div.content form input[type='text'].error {
- outline: 2px solid black;
- outline-color: #cc0000;
-}
-.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation div.content form select[name='parameterContentType'] {
- max-width: 300px;
-}
-.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation div.content div.response div.block pre {
- font-family: "Anonymous Pro", "Menlo", "Consolas", "Bitstream Vera Sans Mono", "Courier New", monospace;
- padding: 10px;
- font-size: 0.9em;
- max-height: 400px;
- overflow-y: auto;
-}
-.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.put div.heading {
- background-color: #f9f2e9;
- border: 1px solid #f0e0ca;
-}
-.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.put div.heading h3 span.http_method a {
- background-color: #c5862b;
-}
-.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.put div.heading ul.options li {
- border-right: 1px solid #dddddd;
- border-right-color: #f0e0ca;
- color: #c5862b;
-}
-.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.put div.heading ul.options li a {
- color: #c5862b;
-}
-.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.put div.content {
- background-color: #faf5ee;
- border: 1px solid #f0e0ca;
-}
-.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.put div.content h4 {
- color: #c5862b;
-}
-.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.put div.content div.sandbox_header a {
- color: #dcb67f;
-}
-.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.head div.heading {
- background-color: #fcffcd;
- border: 1px solid black;
- border-color: #ffd20f;
-}
-.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.head div.heading h3 span.http_method a {
- text-transform: uppercase;
- background-color: #ffd20f;
-}
-.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.head div.heading ul.options li {
- border-right: 1px solid #dddddd;
- border-right-color: #ffd20f;
- color: #ffd20f;
-}
-.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.head div.heading ul.options li a {
- color: #ffd20f;
-}
-.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.head div.content {
- background-color: #fcffcd;
- border: 1px solid black;
- border-color: #ffd20f;
-}
-.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.head div.content h4 {
- color: #ffd20f;
-}
-.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.head div.content div.sandbox_header a {
- color: #6fc992;
-}
-.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.delete div.heading {
- background-color: #f5e8e8;
- border: 1px solid #e8c6c7;
-}
-.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.delete div.heading h3 span.http_method a {
- text-transform: uppercase;
- background-color: #a41e22;
-}
-.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.delete div.heading ul.options li {
- border-right: 1px solid #dddddd;
- border-right-color: #e8c6c7;
- color: #a41e22;
-}
-.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.delete div.heading ul.options li a {
- color: #a41e22;
-}
-.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.delete div.content {
- background-color: #f7eded;
- border: 1px solid #e8c6c7;
-}
-.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.delete div.content h4 {
- color: #a41e22;
-}
-.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.delete div.content div.sandbox_header a {
- color: #c8787a;
-}
-.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.post div.heading {
- background-color: #e7f6ec;
- border: 1px solid #c3e8d1;
-}
-.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.post div.heading h3 span.http_method a {
- background-color: #10a54a;
-}
-.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.post div.heading ul.options li {
- border-right: 1px solid #dddddd;
- border-right-color: #c3e8d1;
- color: #10a54a;
-}
-.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.post div.heading ul.options li a {
- color: #10a54a;
-}
-.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.post div.content {
- background-color: #ebf7f0;
- border: 1px solid #c3e8d1;
-}
-.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.post div.content h4 {
- color: #10a54a;
-}
-.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.post div.content div.sandbox_header a {
- color: #6fc992;
-}
-.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.patch div.heading {
- background-color: #FCE9E3;
- border: 1px solid #F5D5C3;
-}
-.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.patch div.heading h3 span.http_method a {
- background-color: #D38042;
-}
-.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.patch div.heading ul.options li {
- border-right: 1px solid #dddddd;
- border-right-color: #f0cecb;
- color: #D38042;
-}
-.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.patch div.heading ul.options li a {
- color: #D38042;
-}
-.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.patch div.content {
- background-color: #faf0ef;
- border: 1px solid #f0cecb;
-}
-.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.patch div.content h4 {
- color: #D38042;
-}
-.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.patch div.content div.sandbox_header a {
- color: #dcb67f;
-}
-.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.get div.heading {
- background-color: #e7f0f7;
- border: 1px solid #c3d9ec;
-}
-.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.get div.heading h3 span.http_method a {
- background-color: #0f6ab4;
-}
-.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.get div.heading ul.options li {
- border-right: 1px solid #dddddd;
- border-right-color: #c3d9ec;
- color: #0f6ab4;
-}
-.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.get div.heading ul.options li a {
- color: #0f6ab4;
-}
-.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.get div.content {
- background-color: #ebf3f9;
- border: 1px solid #c3d9ec;
-}
-.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.get div.content h4 {
- color: #0f6ab4;
-}
-.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.get div.content div.sandbox_header a {
- color: #6fa5d2;
-}
-.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.options div.heading {
- background-color: #e7f0f7;
- border: 1px solid #c3d9ec;
-}
-.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.options div.heading h3 span.http_method a {
- background-color: #0f6ab4;
-}
-.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.options div.heading ul.options li {
- border-right: 1px solid #dddddd;
- border-right-color: #c3d9ec;
- color: #0f6ab4;
-}
-.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.options div.heading ul.options li a {
- color: #0f6ab4;
-}
-.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.options div.content {
- background-color: #ebf3f9;
- border: 1px solid #c3d9ec;
-}
-.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.options div.content h4 {
- color: #0f6ab4;
-}
-.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.options div.content div.sandbox_header a {
- color: #6fa5d2;
-}
-.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.get div.content,
-.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.post div.content,
-.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.head div.content,
-.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.put div.content,
-.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.patch div.content,
-.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.delete div.content {
- border-top: none;
-}
-.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.get div.heading ul.options li:last-child,
-.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.post div.heading ul.options li:last-child,
-.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.head div.heading ul.options li:last-child,
-.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.put div.heading ul.options li:last-child,
-.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.patch div.heading ul.options li:last-child,
-.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.delete div.heading ul.options li:last-child,
-.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.get div.heading ul.options li.last,
-.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.post div.heading ul.options li.last,
-.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.head div.heading ul.options li.last,
-.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.put div.heading ul.options li.last,
-.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.patch div.heading ul.options li.last,
-.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.delete div.heading ul.options li.last {
- padding-right: 0;
- border-right: none;
-}
-.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations ul.options li a:hover,
-.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations ul.options li a:active,
-.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations ul.options li a.active {
- text-decoration: underline;
-}
-.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations ul.options li:first-child,
-.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations ul.options li.first {
- padding-left: 0;
-}
-.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations:first-child,
-.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations.first {
- padding-left: 0;
-}
-.swagger-section .swagger-ui-wrap p#colophon {
- margin: 0 15px 40px 15px;
- padding: 10px 0;
- font-size: 0.8em;
- border-top: 1px solid #dddddd;
- font-family: "Droid Sans", sans-serif;
- color: #999999;
- font-style: italic;
-}
-.swagger-section .swagger-ui-wrap p#colophon a {
- text-decoration: none;
- color: #547f00;
-}
-.swagger-section .swagger-ui-wrap h3 {
- color: black;
- font-size: 1.1em;
- padding: 10px 0 10px 0;
-}
-.swagger-section .swagger-ui-wrap .markdown ol,
-.swagger-section .swagger-ui-wrap .markdown ul {
- font-family: "Droid Sans", sans-serif;
- margin: 5px 0 10px;
- padding: 0 0 0 18px;
- list-style-type: disc;
-}
-.swagger-section .swagger-ui-wrap form.form_box {
- background-color: #ebf3f9;
- border: 1px solid #c3d9ec;
- padding: 10px;
-}
-.swagger-section .swagger-ui-wrap form.form_box label {
- color: #0f6ab4 !important;
-}
-.swagger-section .swagger-ui-wrap form.form_box input[type=submit] {
- display: block;
- padding: 10px;
-}
-.swagger-section .swagger-ui-wrap form.form_box p.weak {
- font-size: 0.8em;
-}
-.swagger-section .swagger-ui-wrap form.form_box p {
- font-size: 0.9em;
- padding: 0 0 15px;
- color: #7e7b6d;
-}
-.swagger-section .swagger-ui-wrap form.form_box p a {
- color: #646257;
-}
-.swagger-section .swagger-ui-wrap form.form_box p strong {
- color: black;
-}
-.swagger-section .swagger-ui-wrap .operation-status td.markdown > p:last-child {
- padding-bottom: 0;
-}
-.swagger-section .title {
- font-style: bold;
-}
-.swagger-section .secondary_form {
- display: none;
-}
-.swagger-section .main_image {
- display: block;
- margin-left: auto;
- margin-right: auto;
-}
-.swagger-section .oauth_body {
- margin-left: 100px;
- margin-right: 100px;
-}
-.swagger-section .oauth_submit {
- text-align: center;
- display: inline-block;
-}
-.swagger-section .authorize-wrapper {
- margin: 15px 0 10px;
-}
-.swagger-section .authorize-wrapper_operation {
- float: right;
-}
-.swagger-section .authorize__btn:hover {
- text-decoration: underline;
- cursor: pointer;
-}
-.swagger-section .authorize__btn_operation:hover .authorize-scopes {
- display: block;
-}
-.swagger-section .authorize-scopes {
- position: absolute;
- margin-top: 20px;
- background: #FFF;
- border: 1px solid #ccc;
- border-radius: 5px;
- display: none;
- font-size: 13px;
- max-width: 300px;
- line-height: 30px;
- color: black;
- padding: 5px;
-}
-.swagger-section .authorize-scopes .authorize__scope {
- text-decoration: none;
-}
-.swagger-section .authorize__btn_operation {
- height: 18px;
- vertical-align: middle;
- display: inline-block;
- background: url(../images/explorer_icons.png) no-repeat;
-}
-.swagger-section .authorize__btn_operation_login {
- background-position: 0 0;
- width: 18px;
- margin-top: -6px;
- margin-left: 4px;
-}
-.swagger-section .authorize__btn_operation_logout {
- background-position: -30px 0;
- width: 18px;
- margin-top: -6px;
- margin-left: 4px;
-}
-.swagger-section #auth_container {
- color: #fff;
- display: inline-block;
- border: none;
- padding: 5px;
- width: 87px;
- height: 13px;
-}
-.swagger-section #auth_container .authorize__btn {
- color: #fff;
-}
-.swagger-section .auth_container {
- padding: 0 0 10px;
- margin-bottom: 5px;
- border-bottom: solid 1px #CCC;
- font-size: 0.9em;
-}
-.swagger-section .auth_container .auth__title {
- color: #547f00;
- font-size: 1.2em;
-}
-.swagger-section .auth_container .basic_auth__label {
- display: inline-block;
- width: 60px;
-}
-.swagger-section .auth_container .auth__description {
- color: #999999;
- margin-bottom: 5px;
-}
-.swagger-section .auth_container .auth__button {
- margin-top: 10px;
- height: 30px;
-}
-.swagger-section .auth_container .key_auth__field {
- margin: 5px 0;
-}
-.swagger-section .auth_container .key_auth__label {
- display: inline-block;
- width: 60px;
-}
-.swagger-section .api-popup-dialog {
- position: absolute;
- display: none;
-}
-.swagger-section .api-popup-dialog-wrapper {
- z-index: 1000;
- width: 500px;
- background: #FFF;
- padding: 20px;
- border: 1px solid #ccc;
- border-radius: 5px;
- font-size: 13px;
- color: #777;
- position: fixed;
- top: 50%;
- left: 50%;
- transform: translate(-50%, -50%);
-}
-.swagger-section .api-popup-dialog-shadow {
- position: fixed;
- top: 0;
- left: 0;
- width: 100%;
- height: 100%;
- opacity: 0.2;
- background-color: gray;
- z-index: 900;
-}
-.swagger-section .api-popup-dialog .api-popup-title {
- font-size: 24px;
- padding: 10px 0;
-}
-.swagger-section .api-popup-dialog .api-popup-title {
- font-size: 24px;
- padding: 10px 0;
-}
-.swagger-section .api-popup-dialog .error-msg {
- padding-left: 5px;
- padding-bottom: 5px;
-}
-.swagger-section .api-popup-dialog .api-popup-content {
- max-height: 500px;
- overflow-y: auto;
-}
-.swagger-section .api-popup-dialog .api-popup-authbtn {
- height: 30px;
-}
-.swagger-section .api-popup-dialog .api-popup-cancel {
- height: 30px;
-}
-.swagger-section .api-popup-scopes {
- padding: 10px 20px;
-}
-.swagger-section .api-popup-scopes li {
- padding: 5px 0;
- line-height: 20px;
-}
-.swagger-section .api-popup-scopes li input {
- position: relative;
- top: 2px;
-}
-.swagger-section .api-popup-scopes .api-scope-desc {
- padding-left: 20px;
- font-style: italic;
-}
-.swagger-section .api-popup-actions {
- padding-top: 10px;
-}
-.swagger-section .access {
- float: right;
-}
-.swagger-section .auth {
- float: right;
-}
-.swagger-section .api-ic {
- height: 18px;
- vertical-align: middle;
- display: inline-block;
- background: url(../images/explorer_icons.png) no-repeat;
-}
-.swagger-section .api-ic .api_information_panel {
- position: relative;
- margin-top: 20px;
- margin-left: -5px;
- background: #FFF;
- border: 1px solid #ccc;
- border-radius: 5px;
- display: none;
- font-size: 13px;
- max-width: 300px;
- line-height: 30px;
- color: black;
- padding: 5px;
-}
-.swagger-section .api-ic .api_information_panel p .api-msg-enabled {
- color: green;
-}
-.swagger-section .api-ic .api_information_panel p .api-msg-disabled {
- color: red;
-}
-.swagger-section .api-ic:hover .api_information_panel {
- position: absolute;
- display: block;
-}
-.swagger-section .ic-info {
- background-position: 0 0;
- width: 18px;
- margin-top: -6px;
- margin-left: 4px;
-}
-.swagger-section .ic-warning {
- background-position: -60px 0;
- width: 18px;
- margin-top: -6px;
- margin-left: 4px;
-}
-.swagger-section .ic-error {
- background-position: -30px 0;
- width: 18px;
- margin-top: -6px;
- margin-left: 4px;
-}
-.swagger-section .ic-off {
- background-position: -90px 0;
- width: 58px;
- margin-top: -4px;
- cursor: pointer;
-}
-.swagger-section .ic-on {
- background-position: -160px 0;
- width: 58px;
- margin-top: -4px;
- cursor: pointer;
-}
-.swagger-section #header {
- background-color: #89bf04;
- padding: 9px 14px 19px 14px;
- height: 23px;
- min-width: 775px;
-}
-.swagger-section #input_baseUrl {
- width: 400px;
-}
-.swagger-section #api_selector {
- display: block;
- clear: none;
- float: right;
-}
-.swagger-section #api_selector .input {
- display: inline-block;
- clear: none;
- margin: 0 10px 0 0;
-}
-.swagger-section #api_selector input {
- font-size: 0.9em;
- padding: 3px;
- margin: 0;
-}
-.swagger-section #input_apiKey {
- width: 200px;
-}
-.swagger-section #explore,
-.swagger-section #auth_container .authorize__btn {
- display: block;
- text-decoration: none;
- font-weight: bold;
- padding: 6px 8px;
- font-size: 0.9em;
- color: white;
- background-color: #547f00;
- -moz-border-radius: 4px;
- -webkit-border-radius: 4px;
- -o-border-radius: 4px;
- -ms-border-radius: 4px;
- -khtml-border-radius: 4px;
- border-radius: 4px;
-}
-.swagger-section #explore:hover,
-.swagger-section #auth_container .authorize__btn:hover {
- background-color: #547f00;
-}
-.swagger-section #header #logo {
- font-size: 1.5em;
- font-weight: bold;
- text-decoration: none;
- color: white;
-}
-.swagger-section #header #logo .logo__img {
- display: block;
- float: left;
- margin-top: 2px;
-}
-.swagger-section #header #logo .logo__title {
- display: inline-block;
- padding: 5px 0 0 10px;
-}
-.swagger-section #content_message {
- margin: 10px 15px;
- font-style: italic;
- color: #999999;
-}
-.swagger-section #message-bar {
- min-height: 30px;
- text-align: center;
- padding-top: 10px;
-}
-.swagger-section .swagger-collapse:before {
- content: "-";
-}
-.swagger-section .swagger-expand:before {
- content: "+";
-}
-.swagger-section .error {
- outline-color: #cc0000;
- background-color: #f2dede;
-}
+/* Original style from softwaremaniacs.org (c) Ivan Sagalaev <Maniac@SoftwareManiacs.Org> */
+.swagger-section pre code {
+ display: block;
+ padding: 0.5em;
+ background: #F0F0F0;
+}
+.swagger-section pre code,
+.swagger-section pre .subst,
+.swagger-section pre .tag .title,
+.swagger-section pre .lisp .title,
+.swagger-section pre .clojure .built_in,
+.swagger-section pre .nginx .title {
+ color: black;
+}
+.swagger-section pre .string,
+.swagger-section pre .title,
+.swagger-section pre .constant,
+.swagger-section pre .parent,
+.swagger-section pre .tag .value,
+.swagger-section pre .rules .value,
+.swagger-section pre .rules .value .number,
+.swagger-section pre .preprocessor,
+.swagger-section pre .ruby .symbol,
+.swagger-section pre .ruby .symbol .string,
+.swagger-section pre .aggregate,
+.swagger-section pre .template_tag,
+.swagger-section pre .django .variable,
+.swagger-section pre .smalltalk .class,
+.swagger-section pre .addition,
+.swagger-section pre .flow,
+.swagger-section pre .stream,
+.swagger-section pre .bash .variable,
+.swagger-section pre .apache .tag,
+.swagger-section pre .apache .cbracket,
+.swagger-section pre .tex .command,
+.swagger-section pre .tex .special,
+.swagger-section pre .erlang_repl .function_or_atom,
+.swagger-section pre .markdown .header {
+ color: #800;
+}
+.swagger-section pre .comment,
+.swagger-section pre .annotation,
+.swagger-section pre .template_comment,
+.swagger-section pre .diff .header,
+.swagger-section pre .chunk,
+.swagger-section pre .markdown .blockquote {
+ color: #888;
+}
+.swagger-section pre .number,
+.swagger-section pre .date,
+.swagger-section pre .regexp,
+.swagger-section pre .literal,
+.swagger-section pre .smalltalk .symbol,
+.swagger-section pre .smalltalk .char,
+.swagger-section pre .go .constant,
+.swagger-section pre .change,
+.swagger-section pre .markdown .bullet,
+.swagger-section pre .markdown .link_url {
+ color: #080;
+}
+.swagger-section pre .label,
+.swagger-section pre .javadoc,
+.swagger-section pre .ruby .string,
+.swagger-section pre .decorator,
+.swagger-section pre .filter .argument,
+.swagger-section pre .localvars,
+.swagger-section pre .array,
+.swagger-section pre .attr_selector,
+.swagger-section pre .important,
+.swagger-section pre .pseudo,
+.swagger-section pre .pi,
+.swagger-section pre .doctype,
+.swagger-section pre .deletion,
+.swagger-section pre .envvar,
+.swagger-section pre .shebang,
+.swagger-section pre .apache .sqbracket,
+.swagger-section pre .nginx .built_in,
+.swagger-section pre .tex .formula,
+.swagger-section pre .erlang_repl .reserved,
+.swagger-section pre .prompt,
+.swagger-section pre .markdown .link_label,
+.swagger-section pre .vhdl .attribute,
+.swagger-section pre .clojure .attribute,
+.swagger-section pre .coffeescript .property {
+ color: #88F;
+}
+.swagger-section pre .keyword,
+.swagger-section pre .id,
+.swagger-section pre .phpdoc,
+.swagger-section pre .title,
+.swagger-section pre .built_in,
+.swagger-section pre .aggregate,
+.swagger-section pre .css .tag,
+.swagger-section pre .javadoctag,
+.swagger-section pre .phpdoc,
+.swagger-section pre .yardoctag,
+.swagger-section pre .smalltalk .class,
+.swagger-section pre .winutils,
+.swagger-section pre .bash .variable,
+.swagger-section pre .apache .tag,
+.swagger-section pre .go .typename,
+.swagger-section pre .tex .command,
+.swagger-section pre .markdown .strong,
+.swagger-section pre .request,
+.swagger-section pre .status {
+ font-weight: bold;
+}
+.swagger-section pre .markdown .emphasis {
+ font-style: italic;
+}
+.swagger-section pre .nginx .built_in {
+ font-weight: normal;
+}
+.swagger-section pre .coffeescript .javascript,
+.swagger-section pre .javascript .xml,
+.swagger-section pre .tex .formula,
+.swagger-section pre .xml .javascript,
+.swagger-section pre .xml .vbscript,
+.swagger-section pre .xml .css,
+.swagger-section pre .xml .cdata {
+ opacity: 0.5;
+}
+.swagger-section .hljs {
+ display: block;
+ overflow-x: auto;
+ padding: 0.5em;
+ background: #F0F0F0;
+}
+.swagger-section .hljs,
+.swagger-section .hljs-subst {
+ color: #444;
+}
+.swagger-section .hljs-keyword,
+.swagger-section .hljs-attribute,
+.swagger-section .hljs-selector-tag,
+.swagger-section .hljs-meta-keyword,
+.swagger-section .hljs-doctag,
+.swagger-section .hljs-name {
+ font-weight: bold;
+}
+.swagger-section .hljs-built_in,
+.swagger-section .hljs-literal,
+.swagger-section .hljs-bullet,
+.swagger-section .hljs-code,
+.swagger-section .hljs-addition {
+ color: #1F811F;
+}
+.swagger-section .hljs-regexp,
+.swagger-section .hljs-symbol,
+.swagger-section .hljs-variable,
+.swagger-section .hljs-template-variable,
+.swagger-section .hljs-link,
+.swagger-section .hljs-selector-attr,
+.swagger-section .hljs-selector-pseudo {
+ color: #BC6060;
+}
+.swagger-section .hljs-type,
+.swagger-section .hljs-string,
+.swagger-section .hljs-number,
+.swagger-section .hljs-selector-id,
+.swagger-section .hljs-selector-class,
+.swagger-section .hljs-quote,
+.swagger-section .hljs-template-tag,
+.swagger-section .hljs-deletion {
+ color: #880000;
+}
+.swagger-section .hljs-title,
+.swagger-section .hljs-section {
+ color: #880000;
+ font-weight: bold;
+}
+.swagger-section .hljs-comment {
+ color: #888888;
+}
+.swagger-section .hljs-meta {
+ color: #2B6EA1;
+}
+.swagger-section .hljs-emphasis {
+ font-style: italic;
+}
+.swagger-section .hljs-strong {
+ font-weight: bold;
+}
+.swagger-section .swagger-ui-wrap {
+ line-height: 1;
+ font-family: "Droid Sans", sans-serif;
+ min-width: 760px;
+ max-width: 960px;
+ margin-left: auto;
+ margin-right: auto;
+ /* JSONEditor specific styling */
+}
+.swagger-section .swagger-ui-wrap b,
+.swagger-section .swagger-ui-wrap strong {
+ font-family: "Droid Sans", sans-serif;
+ font-weight: bold;
+}
+.swagger-section .swagger-ui-wrap q,
+.swagger-section .swagger-ui-wrap blockquote {
+ quotes: none;
+}
+.swagger-section .swagger-ui-wrap p {
+ line-height: 1.4em;
+ padding: 0 0 10px;
+ color: #333333;
+}
+.swagger-section .swagger-ui-wrap q:before,
+.swagger-section .swagger-ui-wrap q:after,
+.swagger-section .swagger-ui-wrap blockquote:before,
+.swagger-section .swagger-ui-wrap blockquote:after {
+ content: none;
+}
+.swagger-section .swagger-ui-wrap .heading_with_menu h1,
+.swagger-section .swagger-ui-wrap .heading_with_menu h2,
+.swagger-section .swagger-ui-wrap .heading_with_menu h3,
+.swagger-section .swagger-ui-wrap .heading_with_menu h4,
+.swagger-section .swagger-ui-wrap .heading_with_menu h5,
+.swagger-section .swagger-ui-wrap .heading_with_menu h6 {
+ display: block;
+ clear: none;
+ float: left;
+ -moz-box-sizing: border-box;
+ -webkit-box-sizing: border-box;
+ -ms-box-sizing: border-box;
+ box-sizing: border-box;
+ width: 60%;
+}
+.swagger-section .swagger-ui-wrap table {
+ border-collapse: collapse;
+ border-spacing: 0;
+}
+.swagger-section .swagger-ui-wrap table thead tr th {
+ padding: 5px;
+ font-size: 0.9em;
+ color: #666666;
+ border-bottom: 1px solid #999999;
+}
+.swagger-section .swagger-ui-wrap table tbody tr:last-child td {
+ border-bottom: none;
+}
+.swagger-section .swagger-ui-wrap table tbody tr.offset {
+ background-color: #f0f0f0;
+}
+.swagger-section .swagger-ui-wrap table tbody tr td {
+ padding: 6px;
+ font-size: 0.9em;
+ border-bottom: 1px solid #cccccc;
+ vertical-align: top;
+ line-height: 1.3em;
+}
+.swagger-section .swagger-ui-wrap ol {
+ margin: 0px 0 10px;
+ padding: 0 0 0 18px;
+ list-style-type: decimal;
+}
+.swagger-section .swagger-ui-wrap ol li {
+ padding: 5px 0px;
+ font-size: 0.9em;
+ color: #333333;
+}
+.swagger-section .swagger-ui-wrap ol,
+.swagger-section .swagger-ui-wrap ul {
+ list-style: none;
+}
+.swagger-section .swagger-ui-wrap h1 a,
+.swagger-section .swagger-ui-wrap h2 a,
+.swagger-section .swagger-ui-wrap h3 a,
+.swagger-section .swagger-ui-wrap h4 a,
+.swagger-section .swagger-ui-wrap h5 a,
+.swagger-section .swagger-ui-wrap h6 a {
+ text-decoration: none;
+}
+.swagger-section .swagger-ui-wrap h1 a:hover,
+.swagger-section .swagger-ui-wrap h2 a:hover,
+.swagger-section .swagger-ui-wrap h3 a:hover,
+.swagger-section .swagger-ui-wrap h4 a:hover,
+.swagger-section .swagger-ui-wrap h5 a:hover,
+.swagger-section .swagger-ui-wrap h6 a:hover {
+ text-decoration: underline;
+}
+.swagger-section .swagger-ui-wrap h1 span.divider,
+.swagger-section .swagger-ui-wrap h2 span.divider,
+.swagger-section .swagger-ui-wrap h3 span.divider,
+.swagger-section .swagger-ui-wrap h4 span.divider,
+.swagger-section .swagger-ui-wrap h5 span.divider,
+.swagger-section .swagger-ui-wrap h6 span.divider {
+ color: #aaaaaa;
+}
+.swagger-section .swagger-ui-wrap a {
+ color: #547f00;
+}
+.swagger-section .swagger-ui-wrap a img {
+ border: none;
+}
+.swagger-section .swagger-ui-wrap article,
+.swagger-section .swagger-ui-wrap aside,
+.swagger-section .swagger-ui-wrap details,
+.swagger-section .swagger-ui-wrap figcaption,
+.swagger-section .swagger-ui-wrap figure,
+.swagger-section .swagger-ui-wrap footer,
+.swagger-section .swagger-ui-wrap header,
+.swagger-section .swagger-ui-wrap hgroup,
+.swagger-section .swagger-ui-wrap menu,
+.swagger-section .swagger-ui-wrap nav,
+.swagger-section .swagger-ui-wrap section,
+.swagger-section .swagger-ui-wrap summary {
+ display: block;
+}
+.swagger-section .swagger-ui-wrap pre {
+ font-family: "Anonymous Pro", "Menlo", "Consolas", "Bitstream Vera Sans Mono", "Courier New", monospace;
+ background-color: #fcf6db;
+ border: 1px solid #e5e0c6;
+ padding: 10px;
+}
+.swagger-section .swagger-ui-wrap pre code {
+ line-height: 1.6em;
+ background: none;
+}
+.swagger-section .swagger-ui-wrap .content > .content-type > div > label {
+ clear: both;
+ display: block;
+ color: #0F6AB4;
+ font-size: 1.1em;
+ margin: 0;
+ padding: 15px 0 5px;
+}
+.swagger-section .swagger-ui-wrap .content pre {
+ font-size: 12px;
+ margin-top: 5px;
+ padding: 5px;
+}
+.swagger-section .swagger-ui-wrap .icon-btn {
+ cursor: pointer;
+}
+.swagger-section .swagger-ui-wrap .info_title {
+ padding-bottom: 10px;
+ font-weight: bold;
+ font-size: 25px;
+}
+.swagger-section .swagger-ui-wrap .footer {
+ margin-top: 20px;
+}
+.swagger-section .swagger-ui-wrap p.big,
+.swagger-section .swagger-ui-wrap div.big p {
+ font-size: 1em;
+ margin-bottom: 10px;
+}
+.swagger-section .swagger-ui-wrap form.fullwidth ol li.string input,
+.swagger-section .swagger-ui-wrap form.fullwidth ol li.url input,
+.swagger-section .swagger-ui-wrap form.fullwidth ol li.text textarea,
+.swagger-section .swagger-ui-wrap form.fullwidth ol li.numeric input {
+ width: 500px !important;
+}
+.swagger-section .swagger-ui-wrap .info_license {
+ padding-bottom: 5px;
+}
+.swagger-section .swagger-ui-wrap .info_tos {
+ padding-bottom: 5px;
+}
+.swagger-section .swagger-ui-wrap .message-fail {
+ color: #cc0000;
+}
+.swagger-section .swagger-ui-wrap .info_url {
+ padding-bottom: 5px;
+}
+.swagger-section .swagger-ui-wrap .info_email {
+ padding-bottom: 5px;
+}
+.swagger-section .swagger-ui-wrap .info_name {
+ padding-bottom: 5px;
+}
+.swagger-section .swagger-ui-wrap .info_description {
+ padding-bottom: 10px;
+ font-size: 15px;
+}
+.swagger-section .swagger-ui-wrap .markdown ol li,
+.swagger-section .swagger-ui-wrap .markdown ul li {
+ padding: 3px 0px;
+ line-height: 1.4em;
+ color: #333333;
+}
+.swagger-section .swagger-ui-wrap form.formtastic fieldset.inputs ol li.string input,
+.swagger-section .swagger-ui-wrap form.formtastic fieldset.inputs ol li.url input,
+.swagger-section .swagger-ui-wrap form.formtastic fieldset.inputs ol li.numeric input {
+ display: block;
+ padding: 4px;
+ width: auto;
+ clear: both;
+}
+.swagger-section .swagger-ui-wrap form.formtastic fieldset.inputs ol li.string input.title,
+.swagger-section .swagger-ui-wrap form.formtastic fieldset.inputs ol li.url input.title,
+.swagger-section .swagger-ui-wrap form.formtastic fieldset.inputs ol li.numeric input.title {
+ font-size: 1.3em;
+}
+.swagger-section .swagger-ui-wrap table.fullwidth {
+ width: 100%;
+}
+.swagger-section .swagger-ui-wrap .model-signature {
+ font-family: "Droid Sans", sans-serif;
+ font-size: 1em;
+ line-height: 1.5em;
+}
+.swagger-section .swagger-ui-wrap .model-signature .signature-nav a {
+ text-decoration: none;
+ color: #AAA;
+}
+.swagger-section .swagger-ui-wrap .model-signature .signature-nav a:hover {
+ text-decoration: underline;
+ color: black;
+}
+.swagger-section .swagger-ui-wrap .model-signature .signature-nav .selected {
+ color: black;
+ text-decoration: none;
+}
+.swagger-section .swagger-ui-wrap .model-signature .propType {
+ color: #5555aa;
+}
+.swagger-section .swagger-ui-wrap .model-signature pre:hover {
+ background-color: #ffffdd;
+}
+.swagger-section .swagger-ui-wrap .model-signature pre {
+ font-size: .85em;
+ line-height: 1.2em;
+ overflow: auto;
+ max-height: 200px;
+ cursor: pointer;
+}
+.swagger-section .swagger-ui-wrap .model-signature ul.signature-nav {
+ display: block;
+ min-width: 230px;
+ margin: 0;
+ padding: 0;
+}
+.swagger-section .swagger-ui-wrap .model-signature ul.signature-nav li:last-child {
+ padding-right: 0;
+ border-right: none;
+}
+.swagger-section .swagger-ui-wrap .model-signature ul.signature-nav li {
+ float: left;
+ margin: 0 5px 5px 0;
+ padding: 2px 5px 2px 0;
+ border-right: 1px solid #ddd;
+}
+.swagger-section .swagger-ui-wrap .model-signature .propOpt {
+ color: #555;
+}
+.swagger-section .swagger-ui-wrap .model-signature .snippet small {
+ font-size: 0.75em;
+}
+.swagger-section .swagger-ui-wrap .model-signature .propOptKey {
+ font-style: italic;
+}
+.swagger-section .swagger-ui-wrap .model-signature .description .strong {
+ font-weight: bold;
+ color: #000;
+ font-size: .9em;
+}
+.swagger-section .swagger-ui-wrap .model-signature .description div {
+ font-size: 0.9em;
+ line-height: 1.5em;
+ margin-left: 1em;
+}
+.swagger-section .swagger-ui-wrap .model-signature .description .stronger {
+ font-weight: bold;
+ color: #000;
+}
+.swagger-section .swagger-ui-wrap .model-signature .description .propWrap .optionsWrapper {
+ border-spacing: 0;
+ position: absolute;
+ background-color: #ffffff;
+ border: 1px solid #bbbbbb;
+ display: none;
+ font-size: 11px;
+ max-width: 400px;
+ line-height: 30px;
+ color: black;
+ padding: 5px;
+ margin-left: 10px;
+}
+.swagger-section .swagger-ui-wrap .model-signature .description .propWrap .optionsWrapper th {
+ text-align: center;
+ background-color: #eeeeee;
+ border: 1px solid #bbbbbb;
+ font-size: 11px;
+ color: #666666;
+ font-weight: bold;
+ padding: 5px;
+ line-height: 15px;
+}
+.swagger-section .swagger-ui-wrap .model-signature .description .propWrap .optionsWrapper .optionName {
+ font-weight: bold;
+}
+.swagger-section .swagger-ui-wrap .model-signature .description .propDesc.markdown > p:first-child,
+.swagger-section .swagger-ui-wrap .model-signature .description .propDesc.markdown > p:last-child {
+ display: inline;
+}
+.swagger-section .swagger-ui-wrap .model-signature .description .propDesc.markdown > p:not(:first-child):before {
+ display: block;
+ content: '';
+}
+.swagger-section .swagger-ui-wrap .model-signature .description span:last-of-type.propDesc.markdown > p:only-child {
+ margin-right: -3px;
+}
+.swagger-section .swagger-ui-wrap .model-signature .propName {
+ font-weight: bold;
+}
+.swagger-section .swagger-ui-wrap .model-signature .signature-container {
+ clear: both;
+}
+.swagger-section .swagger-ui-wrap .body-textarea {
+ width: 300px;
+ height: 100px;
+ border: 1px solid #aaa;
+}
+.swagger-section .swagger-ui-wrap .markdown p code,
+.swagger-section .swagger-ui-wrap .markdown li code {
+ font-family: "Anonymous Pro", "Menlo", "Consolas", "Bitstream Vera Sans Mono", "Courier New", monospace;
+ background-color: #f0f0f0;
+ color: black;
+ padding: 1px 3px;
+}
+.swagger-section .swagger-ui-wrap .required {
+ font-weight: bold;
+}
+.swagger-section .swagger-ui-wrap .editor_holder {
+ font-family: "Anonymous Pro", "Menlo", "Consolas", "Bitstream Vera Sans Mono", "Courier New", monospace;
+ font-size: 0.9em;
+}
+.swagger-section .swagger-ui-wrap .editor_holder label {
+ font-weight: normal!important;
+ /* JSONEditor uses bold by default for all labels, we revert that back to normal to not give the impression that by default fields are required */
+}
+.swagger-section .swagger-ui-wrap .editor_holder label.required {
+ font-weight: bold!important;
+}
+.swagger-section .swagger-ui-wrap input.parameter {
+ width: 300px;
+ border: 1px solid #aaa;
+}
+.swagger-section .swagger-ui-wrap h1 {
+ color: black;
+ font-size: 1.5em;
+ line-height: 1.3em;
+ padding: 10px 0 10px 0;
+ font-family: "Droid Sans", sans-serif;
+ font-weight: bold;
+}
+.swagger-section .swagger-ui-wrap .heading_with_menu {
+ float: none;
+ clear: both;
+ overflow: hidden;
+ display: block;
+}
+.swagger-section .swagger-ui-wrap .heading_with_menu ul {
+ display: block;
+ clear: none;
+ float: right;
+ -moz-box-sizing: border-box;
+ -webkit-box-sizing: border-box;
+ -ms-box-sizing: border-box;
+ box-sizing: border-box;
+ margin-top: 10px;
+}
+.swagger-section .swagger-ui-wrap h2 {
+ color: black;
+ font-size: 1.3em;
+ padding: 10px 0 10px 0;
+}
+.swagger-section .swagger-ui-wrap h2 a {
+ color: black;
+}
+.swagger-section .swagger-ui-wrap h2 span.sub {
+ font-size: 0.7em;
+ color: #999999;
+ font-style: italic;
+}
+.swagger-section .swagger-ui-wrap h2 span.sub a {
+ color: #777777;
+}
+.swagger-section .swagger-ui-wrap span.weak {
+ color: #666666;
+}
+.swagger-section .swagger-ui-wrap .message-success {
+ color: #89BF04;
+}
+.swagger-section .swagger-ui-wrap caption,
+.swagger-section .swagger-ui-wrap th,
+.swagger-section .swagger-ui-wrap td {
+ text-align: left;
+ font-weight: normal;
+ vertical-align: middle;
+}
+.swagger-section .swagger-ui-wrap .code {
+ font-family: "Anonymous Pro", "Menlo", "Consolas", "Bitstream Vera Sans Mono", "Courier New", monospace;
+}
+.swagger-section .swagger-ui-wrap form.formtastic fieldset.inputs ol li.text textarea {
+ font-family: "Droid Sans", sans-serif;
+ height: 250px;
+ padding: 4px;
+ display: block;
+ clear: both;
+}
+.swagger-section .swagger-ui-wrap form.formtastic fieldset.inputs ol li.select select {
+ display: block;
+ clear: both;
+}
+.swagger-section .swagger-ui-wrap form.formtastic fieldset.inputs ol li.boolean {
+ float: none;
+ clear: both;
+ overflow: hidden;
+ display: block;
+}
+.swagger-section .swagger-ui-wrap form.formtastic fieldset.inputs ol li.boolean label {
+ display: block;
+ float: left;
+ clear: none;
+ margin: 0;
+ padding: 0;
+}
+.swagger-section .swagger-ui-wrap form.formtastic fieldset.inputs ol li.boolean input {
+ display: block;
+ float: left;
+ clear: none;
+ margin: 0 5px 0 0;
+}
+.swagger-section .swagger-ui-wrap form.formtastic fieldset.inputs ol li.required label {
+ color: black;
+}
+.swagger-section .swagger-ui-wrap form.formtastic fieldset.inputs ol li label {
+ display: block;
+ clear: both;
+ width: auto;
+ padding: 0 0 3px;
+ color: #666666;
+}
+.swagger-section .swagger-ui-wrap form.formtastic fieldset.inputs ol li label abbr {
+ padding-left: 3px;
+ color: #888888;
+}
+.swagger-section .swagger-ui-wrap form.formtastic fieldset.inputs ol li p.inline-hints {
+ margin-left: 0;
+ font-style: italic;
+ font-size: 0.9em;
+ margin: 0;
+}
+.swagger-section .swagger-ui-wrap form.formtastic fieldset.buttons {
+ margin: 0;
+ padding: 0;
+}
+.swagger-section .swagger-ui-wrap span.blank,
+.swagger-section .swagger-ui-wrap span.empty {
+ color: #888888;
+ font-style: italic;
+}
+.swagger-section .swagger-ui-wrap .markdown h3 {
+ color: #547f00;
+}
+.swagger-section .swagger-ui-wrap .markdown h4 {
+ color: #666666;
+}
+.swagger-section .swagger-ui-wrap .markdown pre {
+ font-family: "Anonymous Pro", "Menlo", "Consolas", "Bitstream Vera Sans Mono", "Courier New", monospace;
+ background-color: #fcf6db;
+ border: 1px solid #e5e0c6;
+ padding: 10px;
+ margin: 0 0 10px 0;
+}
+.swagger-section .swagger-ui-wrap .markdown pre code {
+ line-height: 1.6em;
+ overflow: auto;
+}
+.swagger-section .swagger-ui-wrap div.gist {
+ margin: 20px 0 25px 0 !important;
+}
+.swagger-section .swagger-ui-wrap ul#resources {
+ font-family: "Droid Sans", sans-serif;
+ font-size: 0.9em;
+}
+.swagger-section .swagger-ui-wrap ul#resources li.resource {
+ border-bottom: 1px solid #dddddd;
+}
+.swagger-section .swagger-ui-wrap ul#resources li.resource:hover div.heading h2 a,
+.swagger-section .swagger-ui-wrap ul#resources li.resource.active div.heading h2 a {
+ color: black;
+}
+.swagger-section .swagger-ui-wrap ul#resources li.resource:hover div.heading ul.options li a,
+.swagger-section .swagger-ui-wrap ul#resources li.resource.active div.heading ul.options li a {
+ color: #555555;
+}
+.swagger-section .swagger-ui-wrap ul#resources li.resource:last-child {
+ border-bottom: none;
+}
+.swagger-section .swagger-ui-wrap ul#resources li.resource div.heading {
+ border: 1px solid transparent;
+ float: none;
+ clear: both;
+ overflow: hidden;
+ display: block;
+}
+.swagger-section .swagger-ui-wrap ul#resources li.resource div.heading ul.options {
+ overflow: hidden;
+ padding: 0;
+ display: block;
+ clear: none;
+ float: right;
+ margin: 14px 10px 0 0;
+}
+.swagger-section .swagger-ui-wrap ul#resources li.resource div.heading ul.options li {
+ float: left;
+ clear: none;
+ margin: 0;
+ padding: 2px 10px;
+ border-right: 1px solid #dddddd;
+ color: #666666;
+ font-size: 0.9em;
+}
+.swagger-section .swagger-ui-wrap ul#resources li.resource div.heading ul.options li a {
+ color: #aaaaaa;
+ text-decoration: none;
+}
+.swagger-section .swagger-ui-wrap ul#resources li.resource div.heading ul.options li a:hover {
+ text-decoration: underline;
+ color: black;
+}
+.swagger-section .swagger-ui-wrap ul#resources li.resource div.heading ul.options li a:hover,
+.swagger-section .swagger-ui-wrap ul#resources li.resource div.heading ul.options li a:active,
+.swagger-section .swagger-ui-wrap ul#resources li.resource div.heading ul.options li a.active {
+ text-decoration: underline;
+}
+.swagger-section .swagger-ui-wrap ul#resources li.resource div.heading ul.options li:first-child,
+.swagger-section .swagger-ui-wrap ul#resources li.resource div.heading ul.options li.first {
+ padding-left: 0;
+}
+.swagger-section .swagger-ui-wrap ul#resources li.resource div.heading ul.options li:last-child,
+.swagger-section .swagger-ui-wrap ul#resources li.resource div.heading ul.options li.last {
+ padding-right: 0;
+ border-right: none;
+}
+.swagger-section .swagger-ui-wrap ul#resources li.resource div.heading ul.options:first-child,
+.swagger-section .swagger-ui-wrap ul#resources li.resource div.heading ul.options.first {
+ padding-left: 0;
+}
+.swagger-section .swagger-ui-wrap ul#resources li.resource div.heading h2 {
+ color: #999999;
+ padding-left: 0;
+ display: block;
+ clear: none;
+ float: left;
+ font-family: "Droid Sans", sans-serif;
+ font-weight: bold;
+}
+.swagger-section .swagger-ui-wrap ul#resources li.resource div.heading h2 a {
+ color: #999999;
+}
+.swagger-section .swagger-ui-wrap ul#resources li.resource div.heading h2 a:hover {
+ color: black;
+}
+.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation {
+ float: none;
+ clear: both;
+ overflow: hidden;
+ display: block;
+ margin: 0 0 10px;
+ padding: 0;
+}
+.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation div.heading {
+ float: none;
+ clear: both;
+ overflow: hidden;
+ display: block;
+ margin: 0;
+ padding: 0;
+}
+.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation div.heading h3 {
+ display: block;
+ clear: none;
+ float: left;
+ width: auto;
+ margin: 0;
+ padding: 0;
+ line-height: 1.1em;
+ color: black;
+}
+.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation div.heading h3 span.path {
+ padding-left: 10px;
+}
+.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation div.heading h3 span.path a {
+ color: black;
+ text-decoration: none;
+}
+.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation div.heading h3 span.path a.toggleOperation.deprecated {
+ text-decoration: line-through;
+}
+.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation div.heading h3 span.path a:hover {
+ text-decoration: underline;
+}
+.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation div.heading h3 span.http_method a {
+ text-transform: uppercase;
+ text-decoration: none;
+ color: white;
+ display: inline-block;
+ width: 50px;
+ font-size: 0.7em;
+ text-align: center;
+ padding: 7px 0 4px;
+ -moz-border-radius: 2px;
+ -webkit-border-radius: 2px;
+ -o-border-radius: 2px;
+ -ms-border-radius: 2px;
+ -khtml-border-radius: 2px;
+ border-radius: 2px;
+}
+.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation div.heading h3 span {
+ margin: 0;
+ padding: 0;
+}
+.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation div.heading ul.options {
+ overflow: hidden;
+ padding: 0;
+ display: block;
+ clear: none;
+ float: right;
+ margin: 6px 10px 0 0;
+}
+.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation div.heading ul.options li {
+ float: left;
+ clear: none;
+ margin: 0;
+ padding: 2px 10px;
+ font-size: 0.9em;
+}
+.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation div.heading ul.options li a {
+ text-decoration: none;
+}
+.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation div.heading ul.options li a .markdown p {
+ color: inherit;
+ padding: 0;
+ line-height: inherit;
+}
+.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation div.heading ul.options li.access {
+ color: black;
+}
+.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation div.content {
+ border-top: none;
+ padding: 10px;
+ -moz-border-radius-bottomleft: 6px;
+ -webkit-border-bottom-left-radius: 6px;
+ -o-border-bottom-left-radius: 6px;
+ -ms-border-bottom-left-radius: 6px;
+ -khtml-border-bottom-left-radius: 6px;
+ border-bottom-left-radius: 6px;
+ -moz-border-radius-bottomright: 6px;
+ -webkit-border-bottom-right-radius: 6px;
+ -o-border-bottom-right-radius: 6px;
+ -ms-border-bottom-right-radius: 6px;
+ -khtml-border-bottom-right-radius: 6px;
+ border-bottom-right-radius: 6px;
+ margin: 0 0 20px;
+}
+.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation div.content h4 {
+ font-size: 1.1em;
+ margin: 0;
+ padding: 15px 0 5px;
+}
+.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation div.content div.sandbox_header {
+ float: none;
+ clear: both;
+ overflow: hidden;
+ display: block;
+}
+.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation div.content div.sandbox_header a {
+ padding: 4px 0 0 10px;
+ display: inline-block;
+ font-size: 0.9em;
+}
+.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation div.content div.sandbox_header input.submit {
+ display: block;
+ clear: none;
+ float: left;
+ padding: 6px 8px;
+}
+.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation div.content div.sandbox_header span.response_throbber {
+ background-image: url('../images/throbber.gif');
+ width: 128px;
+ height: 16px;
+ display: block;
+ clear: none;
+ float: right;
+}
+.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation div.content form input[type='text'].error {
+ outline: 2px solid black;
+ outline-color: #cc0000;
+}
+.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation div.content form select[name='parameterContentType'] {
+ max-width: 300px;
+}
+.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation div.content div.response div.block pre {
+ font-family: "Anonymous Pro", "Menlo", "Consolas", "Bitstream Vera Sans Mono", "Courier New", monospace;
+ padding: 10px;
+ font-size: 0.9em;
+ max-height: 400px;
+ overflow-y: auto;
+}
+.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.put div.heading {
+ background-color: #f9f2e9;
+ border: 1px solid #f0e0ca;
+}
+.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.put div.heading h3 span.http_method a {
+ background-color: #c5862b;
+}
+.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.put div.heading ul.options li {
+ border-right: 1px solid #dddddd;
+ border-right-color: #f0e0ca;
+ color: #c5862b;
+}
+.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.put div.heading ul.options li a {
+ color: #c5862b;
+}
+.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.put div.content {
+ background-color: #faf5ee;
+ border: 1px solid #f0e0ca;
+}
+.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.put div.content h4 {
+ color: #c5862b;
+}
+.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.put div.content div.sandbox_header a {
+ color: #dcb67f;
+}
+.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.head div.heading {
+ background-color: #fcffcd;
+ border: 1px solid black;
+ border-color: #ffd20f;
+}
+.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.head div.heading h3 span.http_method a {
+ text-transform: uppercase;
+ background-color: #ffd20f;
+}
+.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.head div.heading ul.options li {
+ border-right: 1px solid #dddddd;
+ border-right-color: #ffd20f;
+ color: #ffd20f;
+}
+.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.head div.heading ul.options li a {
+ color: #ffd20f;
+}
+.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.head div.content {
+ background-color: #fcffcd;
+ border: 1px solid black;
+ border-color: #ffd20f;
+}
+.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.head div.content h4 {
+ color: #ffd20f;
+}
+.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.head div.content div.sandbox_header a {
+ color: #6fc992;
+}
+.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.delete div.heading {
+ background-color: #f5e8e8;
+ border: 1px solid #e8c6c7;
+}
+.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.delete div.heading h3 span.http_method a {
+ text-transform: uppercase;
+ background-color: #a41e22;
+}
+.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.delete div.heading ul.options li {
+ border-right: 1px solid #dddddd;
+ border-right-color: #e8c6c7;
+ color: #a41e22;
+}
+.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.delete div.heading ul.options li a {
+ color: #a41e22;
+}
+.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.delete div.content {
+ background-color: #f7eded;
+ border: 1px solid #e8c6c7;
+}
+.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.delete div.content h4 {
+ color: #a41e22;
+}
+.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.delete div.content div.sandbox_header a {
+ color: #c8787a;
+}
+.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.post div.heading {
+ background-color: #e7f6ec;
+ border: 1px solid #c3e8d1;
+}
+.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.post div.heading h3 span.http_method a {
+ background-color: #10a54a;
+}
+.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.post div.heading ul.options li {
+ border-right: 1px solid #dddddd;
+ border-right-color: #c3e8d1;
+ color: #10a54a;
+}
+.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.post div.heading ul.options li a {
+ color: #10a54a;
+}
+.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.post div.content {
+ background-color: #ebf7f0;
+ border: 1px solid #c3e8d1;
+}
+.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.post div.content h4 {
+ color: #10a54a;
+}
+.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.post div.content div.sandbox_header a {
+ color: #6fc992;
+}
+.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.patch div.heading {
+ background-color: #FCE9E3;
+ border: 1px solid #F5D5C3;
+}
+.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.patch div.heading h3 span.http_method a {
+ background-color: #D38042;
+}
+.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.patch div.heading ul.options li {
+ border-right: 1px solid #dddddd;
+ border-right-color: #f0cecb;
+ color: #D38042;
+}
+.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.patch div.heading ul.options li a {
+ color: #D38042;
+}
+.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.patch div.content {
+ background-color: #faf0ef;
+ border: 1px solid #f0cecb;
+}
+.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.patch div.content h4 {
+ color: #D38042;
+}
+.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.patch div.content div.sandbox_header a {
+ color: #dcb67f;
+}
+.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.get div.heading {
+ background-color: #e7f0f7;
+ border: 1px solid #c3d9ec;
+}
+.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.get div.heading h3 span.http_method a {
+ background-color: #0f6ab4;
+}
+.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.get div.heading ul.options li {
+ border-right: 1px solid #dddddd;
+ border-right-color: #c3d9ec;
+ color: #0f6ab4;
+}
+.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.get div.heading ul.options li a {
+ color: #0f6ab4;
+}
+.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.get div.content {
+ background-color: #ebf3f9;
+ border: 1px solid #c3d9ec;
+}
+.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.get div.content h4 {
+ color: #0f6ab4;
+}
+.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.get div.content div.sandbox_header a {
+ color: #6fa5d2;
+}
+.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.options div.heading {
+ background-color: #e7f0f7;
+ border: 1px solid #c3d9ec;
+}
+.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.options div.heading h3 span.http_method a {
+ background-color: #0f6ab4;
+}
+.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.options div.heading ul.options li {
+ border-right: 1px solid #dddddd;
+ border-right-color: #c3d9ec;
+ color: #0f6ab4;
+}
+.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.options div.heading ul.options li a {
+ color: #0f6ab4;
+}
+.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.options div.content {
+ background-color: #ebf3f9;
+ border: 1px solid #c3d9ec;
+}
+.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.options div.content h4 {
+ color: #0f6ab4;
+}
+.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.options div.content div.sandbox_header a {
+ color: #6fa5d2;
+}
+.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.get div.content,
+.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.post div.content,
+.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.head div.content,
+.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.put div.content,
+.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.patch div.content,
+.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.delete div.content {
+ border-top: none;
+}
+.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.get div.heading ul.options li:last-child,
+.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.post div.heading ul.options li:last-child,
+.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.head div.heading ul.options li:last-child,
+.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.put div.heading ul.options li:last-child,
+.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.patch div.heading ul.options li:last-child,
+.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.delete div.heading ul.options li:last-child,
+.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.get div.heading ul.options li.last,
+.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.post div.heading ul.options li.last,
+.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.head div.heading ul.options li.last,
+.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.put div.heading ul.options li.last,
+.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.patch div.heading ul.options li.last,
+.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.delete div.heading ul.options li.last {
+ padding-right: 0;
+ border-right: none;
+}
+.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations ul.options li a:hover,
+.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations ul.options li a:active,
+.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations ul.options li a.active {
+ text-decoration: underline;
+}
+.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations ul.options li:first-child,
+.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations ul.options li.first {
+ padding-left: 0;
+}
+.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations:first-child,
+.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations.first {
+ padding-left: 0;
+}
+.swagger-section .swagger-ui-wrap p#colophon {
+ margin: 0 15px 40px 15px;
+ padding: 10px 0;
+ font-size: 0.8em;
+ border-top: 1px solid #dddddd;
+ font-family: "Droid Sans", sans-serif;
+ color: #999999;
+ font-style: italic;
+}
+.swagger-section .swagger-ui-wrap p#colophon a {
+ text-decoration: none;
+ color: #547f00;
+}
+.swagger-section .swagger-ui-wrap h3 {
+ color: black;
+ font-size: 1.1em;
+ padding: 10px 0 10px 0;
+}
+.swagger-section .swagger-ui-wrap .markdown ol,
+.swagger-section .swagger-ui-wrap .markdown ul {
+ font-family: "Droid Sans", sans-serif;
+ margin: 5px 0 10px;
+ padding: 0 0 0 18px;
+ list-style-type: disc;
+}
+.swagger-section .swagger-ui-wrap form.form_box {
+ background-color: #ebf3f9;
+ border: 1px solid #c3d9ec;
+ padding: 10px;
+}
+.swagger-section .swagger-ui-wrap form.form_box label {
+ color: #0f6ab4 !important;
+}
+.swagger-section .swagger-ui-wrap form.form_box input[type=submit] {
+ display: block;
+ padding: 10px;
+}
+.swagger-section .swagger-ui-wrap form.form_box p.weak {
+ font-size: 0.8em;
+}
+.swagger-section .swagger-ui-wrap form.form_box p {
+ font-size: 0.9em;
+ padding: 0 0 15px;
+ color: #7e7b6d;
+}
+.swagger-section .swagger-ui-wrap form.form_box p a {
+ color: #646257;
+}
+.swagger-section .swagger-ui-wrap form.form_box p strong {
+ color: black;
+}
+.swagger-section .swagger-ui-wrap .operation-status td.markdown > p:last-child {
+ padding-bottom: 0;
+}
+.swagger-section .title {
+ font-style: bold;
+}
+.swagger-section .secondary_form {
+ display: none;
+}
+.swagger-section .main_image {
+ display: block;
+ margin-left: auto;
+ margin-right: auto;
+}
+.swagger-section .oauth_body {
+ margin-left: 100px;
+ margin-right: 100px;
+}
+.swagger-section .oauth_submit {
+ text-align: center;
+ display: inline-block;
+}
+.swagger-section .authorize-wrapper {
+ margin: 15px 0 10px;
+}
+.swagger-section .authorize-wrapper_operation {
+ float: right;
+}
+.swagger-section .authorize__btn:hover {
+ text-decoration: underline;
+ cursor: pointer;
+}
+.swagger-section .authorize__btn_operation:hover .authorize-scopes {
+ display: block;
+}
+.swagger-section .authorize-scopes {
+ position: absolute;
+ margin-top: 20px;
+ background: #FFF;
+ border: 1px solid #ccc;
+ border-radius: 5px;
+ display: none;
+ font-size: 13px;
+ max-width: 300px;
+ line-height: 30px;
+ color: black;
+ padding: 5px;
+}
+.swagger-section .authorize-scopes .authorize__scope {
+ text-decoration: none;
+}
+.swagger-section .authorize__btn_operation {
+ height: 18px;
+ vertical-align: middle;
+ display: inline-block;
+ background: url(../images/explorer_icons.png) no-repeat;
+}
+.swagger-section .authorize__btn_operation_login {
+ background-position: 0 0;
+ width: 18px;
+ margin-top: -6px;
+ margin-left: 4px;
+}
+.swagger-section .authorize__btn_operation_logout {
+ background-position: -30px 0;
+ width: 18px;
+ margin-top: -6px;
+ margin-left: 4px;
+}
+.swagger-section #auth_container {
+ color: #fff;
+ display: inline-block;
+ border: none;
+ padding: 5px;
+ width: 87px;
+ height: 13px;
+}
+.swagger-section #auth_container .authorize__btn {
+ color: #fff;
+}
+.swagger-section .auth_container {
+ padding: 0 0 10px;
+ margin-bottom: 5px;
+ border-bottom: solid 1px #CCC;
+ font-size: 0.9em;
+}
+.swagger-section .auth_container .auth__title {
+ color: #547f00;
+ font-size: 1.2em;
+}
+.swagger-section .auth_container .basic_auth__label {
+ display: inline-block;
+ width: 60px;
+}
+.swagger-section .auth_container .auth__description {
+ color: #999999;
+ margin-bottom: 5px;
+}
+.swagger-section .auth_container .auth__button {
+ margin-top: 10px;
+ height: 30px;
+}
+.swagger-section .auth_container .key_auth__field {
+ margin: 5px 0;
+}
+.swagger-section .auth_container .key_auth__label {
+ display: inline-block;
+ width: 60px;
+}
+.swagger-section .api-popup-dialog {
+ position: absolute;
+ display: none;
+}
+.swagger-section .api-popup-dialog-wrapper {
+ z-index: 1000;
+ width: 500px;
+ background: #FFF;
+ padding: 20px;
+ border: 1px solid #ccc;
+ border-radius: 5px;
+ font-size: 13px;
+ color: #777;
+ position: fixed;
+ top: 50%;
+ left: 50%;
+ transform: translate(-50%, -50%);
+}
+.swagger-section .api-popup-dialog-shadow {
+ position: fixed;
+ top: 0;
+ left: 0;
+ width: 100%;
+ height: 100%;
+ opacity: 0.2;
+ background-color: gray;
+ z-index: 900;
+}
+.swagger-section .api-popup-dialog .api-popup-title {
+ font-size: 24px;
+ padding: 10px 0;
+}
+.swagger-section .api-popup-dialog .api-popup-title {
+ font-size: 24px;
+ padding: 10px 0;
+}
+.swagger-section .api-popup-dialog .error-msg {
+ padding-left: 5px;
+ padding-bottom: 5px;
+}
+.swagger-section .api-popup-dialog .api-popup-content {
+ max-height: 500px;
+ overflow-y: auto;
+}
+.swagger-section .api-popup-dialog .api-popup-authbtn {
+ height: 30px;
+}
+.swagger-section .api-popup-dialog .api-popup-cancel {
+ height: 30px;
+}
+.swagger-section .api-popup-scopes {
+ padding: 10px 20px;
+}
+.swagger-section .api-popup-scopes li {
+ padding: 5px 0;
+ line-height: 20px;
+}
+.swagger-section .api-popup-scopes li input {
+ position: relative;
+ top: 2px;
+}
+.swagger-section .api-popup-scopes .api-scope-desc {
+ padding-left: 20px;
+ font-style: italic;
+}
+.swagger-section .api-popup-actions {
+ padding-top: 10px;
+}
+.swagger-section .access {
+ float: right;
+}
+.swagger-section .auth {
+ float: right;
+}
+.swagger-section .api-ic {
+ height: 18px;
+ vertical-align: middle;
+ display: inline-block;
+ background: url(../images/explorer_icons.png) no-repeat;
+}
+.swagger-section .api-ic .api_information_panel {
+ position: relative;
+ margin-top: 20px;
+ margin-left: -5px;
+ background: #FFF;
+ border: 1px solid #ccc;
+ border-radius: 5px;
+ display: none;
+ font-size: 13px;
+ max-width: 300px;
+ line-height: 30px;
+ color: black;
+ padding: 5px;
+}
+.swagger-section .api-ic .api_information_panel p .api-msg-enabled {
+ color: green;
+}
+.swagger-section .api-ic .api_information_panel p .api-msg-disabled {
+ color: red;
+}
+.swagger-section .api-ic:hover .api_information_panel {
+ position: absolute;
+ display: block;
+}
+.swagger-section .ic-info {
+ background-position: 0 0;
+ width: 18px;
+ margin-top: -6px;
+ margin-left: 4px;
+}
+.swagger-section .ic-warning {
+ background-position: -60px 0;
+ width: 18px;
+ margin-top: -6px;
+ margin-left: 4px;
+}
+.swagger-section .ic-error {
+ background-position: -30px 0;
+ width: 18px;
+ margin-top: -6px;
+ margin-left: 4px;
+}
+.swagger-section .ic-off {
+ background-position: -90px 0;
+ width: 58px;
+ margin-top: -4px;
+ cursor: pointer;
+}
+.swagger-section .ic-on {
+ background-position: -160px 0;
+ width: 58px;
+ margin-top: -4px;
+ cursor: pointer;
+}
+.swagger-section #header {
+ background-color: #89bf04;
+ padding: 9px 14px 19px 14px;
+ height: 23px;
+ min-width: 775px;
+}
+.swagger-section #input_baseUrl {
+ width: 400px;
+}
+.swagger-section #api_selector {
+ display: block;
+ clear: none;
+ float: right;
+}
+.swagger-section #api_selector .input {
+ display: inline-block;
+ clear: none;
+ margin: 0 10px 0 0;
+}
+.swagger-section #api_selector input {
+ font-size: 0.9em;
+ padding: 3px;
+ margin: 0;
+}
+.swagger-section #input_apiKey {
+ width: 200px;
+}
+.swagger-section #explore,
+.swagger-section #auth_container .authorize__btn {
+ display: block;
+ text-decoration: none;
+ font-weight: bold;
+ padding: 6px 8px;
+ font-size: 0.9em;
+ color: white;
+ background-color: #547f00;
+ -moz-border-radius: 4px;
+ -webkit-border-radius: 4px;
+ -o-border-radius: 4px;
+ -ms-border-radius: 4px;
+ -khtml-border-radius: 4px;
+ border-radius: 4px;
+}
+.swagger-section #explore:hover,
+.swagger-section #auth_container .authorize__btn:hover {
+ background-color: #547f00;
+}
+.swagger-section #header #logo {
+ font-size: 1.5em;
+ font-weight: bold;
+ text-decoration: none;
+ color: white;
+}
+.swagger-section #header #logo .logo__img {
+ display: block;
+ float: left;
+ margin-top: 2px;
+}
+.swagger-section #header #logo .logo__title {
+ display: inline-block;
+ padding: 5px 0 0 10px;
+}
+.swagger-section #content_message {
+ margin: 10px 15px;
+ font-style: italic;
+ color: #999999;
+}
+.swagger-section #message-bar {
+ min-height: 30px;
+ text-align: center;
+ padding-top: 10px;
+}
+.swagger-section .swagger-collapse:before {
+ content: "-";
+}
+.swagger-section .swagger-expand:before {
+ content: "+";
+}
+.swagger-section .error {
+ outline-color: #cc0000;
+ background-color: #f2dede;
+}
diff --git a/ydb/core/viewer/content/api/css/style.css b/ydb/core/viewer/content/api/css/style.css
index 0493f147aad..fc21a31db54 100644
--- a/ydb/core/viewer/content/api/css/style.css
+++ b/ydb/core/viewer/content/api/css/style.css
@@ -1,250 +1,250 @@
-.swagger-section #header a#logo {
- font-size: 1.5em;
- font-weight: bold;
- text-decoration: none;
- background: transparent url(../images/logo.png) no-repeat left center;
- padding: 20px 0 20px 40px;
-}
-#text-head {
- font-size: 80px;
- font-family: 'Roboto', sans-serif;
- color: #ffffff;
- float: right;
- margin-right: 20%;
-}
-.navbar-fixed-top .navbar-nav {
- height: auto;
-}
-.navbar-fixed-top .navbar-brand {
- height: auto;
-}
-.navbar-header {
- height: auto;
-}
-.navbar-inverse {
- background-color: #000;
- border-color: #000;
-}
-#navbar-brand {
- margin-left: 20%;
-}
-.navtext {
- font-size: 10px;
-}
-.h1,
-h1 {
- font-size: 60px;
-}
-.navbar-default .navbar-header .navbar-brand {
- color: #a2dfee;
-}
-/* tag titles */
-.swagger-section .swagger-ui-wrap ul#resources li.resource div.heading h2 a {
- color: #393939;
- font-family: 'Arvo', serif;
- font-size: 1.5em;
-}
-.swagger-section .swagger-ui-wrap ul#resources li.resource div.heading h2 a:hover {
- color: black;
-}
-.swagger-section .swagger-ui-wrap ul#resources li.resource div.heading h2 {
- color: #525252;
- padding-left: 0px;
- display: block;
- clear: none;
- float: left;
- font-family: 'Arvo', serif;
- font-weight: bold;
-}
-.navbar-default .navbar-collapse,
-.navbar-default .navbar-form {
- border-color: #0A0A0A;
-}
-.container1 {
- width: 1500px;
- margin: auto;
- margin-top: 0;
- background-image: url('../images/shield.png');
- background-repeat: no-repeat;
- background-position: -40px -20px;
- margin-bottom: 210px;
-}
-.container-inner {
- width: 1200px;
- margin: auto;
- background-color: rgba(223, 227, 228, 0.75);
- padding-bottom: 40px;
- padding-top: 40px;
- border-radius: 15px;
-}
-.header-content {
- padding: 0;
- width: 1000px;
-}
-.title1 {
- font-size: 80px;
- font-family: 'Vollkorn', serif;
- color: #404040;
- text-align: center;
- padding-top: 40px;
- padding-bottom: 100px;
-}
-#icon {
- margin-top: -18px;
-}
-.subtext {
- font-size: 25px;
- font-style: italic;
- color: #08b;
- text-align: right;
- padding-right: 250px;
-}
-.bg-primary {
- background-color: #00468b;
-}
-.navbar-default .nav > li > a,
-.navbar-default .nav > li > a:focus {
- color: #08b;
-}
-.navbar-default .nav > li > a,
-.navbar-default .nav > li > a:hover {
- color: #08b;
-}
-.navbar-default .nav > li > a,
-.navbar-default .nav > li > a:focus:hover {
- color: #08b;
-}
-.text-faded {
- font-size: 25px;
- font-family: 'Vollkorn', serif;
-}
-.section-heading {
- font-family: 'Vollkorn', serif;
- font-size: 45px;
- padding-bottom: 10px;
-}
-hr {
- border-color: #00468b;
- padding-bottom: 10px;
-}
-.description {
- margin-top: 20px;
- padding-bottom: 200px;
-}
-.description li {
- font-family: 'Vollkorn', serif;
- font-size: 25px;
- color: #525252;
- margin-left: 28%;
- padding-top: 5px;
-}
-.gap {
- margin-top: 200px;
-}
-.troubleshootingtext {
- color: rgba(255, 255, 255, 0.7);
- padding-left: 30%;
-}
-.troubleshootingtext li {
- list-style-type: circle;
- font-size: 25px;
- padding-bottom: 5px;
-}
-.overlay {
- position: absolute;
- top: 0;
- left: 0;
- width: 100%;
- height: 100%;
- z-index: 1000;
-}
-.block.response_body.json:hover {
- cursor: pointer;
-}
-.backdrop {
- color: blue;
-}
-#myModal {
- height: 100%;
-}
-.modal-backdrop {
- bottom: 0;
- position: fixed;
-}
-.curl {
- padding: 10px;
- font-family: "Anonymous Pro", "Menlo", "Consolas", "Bitstream Vera Sans Mono", "Courier New", monospace;
- font-size: 0.9em;
- max-height: 400px;
- margin-top: 5px;
- overflow-y: auto;
- background-color: #fcf6db;
- border: 1px solid #e5e0c6;
- border-radius: 4px;
-}
-.curl_title {
- font-size: 1.1em;
- margin: 0;
- padding: 15px 0 5px;
- font-family: 'Open Sans', 'Helvetica Neue', Arial, sans-serif;
- font-weight: 500;
- line-height: 1.1;
-}
-.footer {
- display: none;
-}
-.swagger-section .swagger-ui-wrap h2 {
- padding: 0;
-}
-h2 {
- margin: 0;
- margin-bottom: 5px;
-}
-.markdown p {
- font-size: 15px;
- font-family: 'Arvo', serif;
-}
-.swagger-section .swagger-ui-wrap .code {
- font-size: 15px;
- font-family: 'Arvo', serif;
-}
-.swagger-section .swagger-ui-wrap b {
- font-family: 'Arvo', serif;
-}
-#signin:hover {
- cursor: pointer;
-}
-.dropdown-menu {
- padding: 15px;
-}
-.navbar-right .dropdown-menu {
- left: 0;
- right: auto;
-}
-#signinbutton {
- width: 100%;
- height: 32px;
- font-size: 13px;
- font-weight: bold;
- color: #08b;
-}
-.navbar-default .nav > li .details {
- color: #000000;
- text-transform: none;
- font-size: 15px;
- font-weight: normal;
- font-family: 'Open Sans', sans-serif;
- font-style: italic;
- line-height: 20px;
- top: -2px;
-}
-.navbar-default .nav > li .details:hover {
- color: black;
-}
-#signout {
- width: 100%;
- height: 32px;
- font-size: 13px;
- font-weight: bold;
- color: #08b;
-}
+.swagger-section #header a#logo {
+ font-size: 1.5em;
+ font-weight: bold;
+ text-decoration: none;
+ background: transparent url(../images/logo.png) no-repeat left center;
+ padding: 20px 0 20px 40px;
+}
+#text-head {
+ font-size: 80px;
+ font-family: 'Roboto', sans-serif;
+ color: #ffffff;
+ float: right;
+ margin-right: 20%;
+}
+.navbar-fixed-top .navbar-nav {
+ height: auto;
+}
+.navbar-fixed-top .navbar-brand {
+ height: auto;
+}
+.navbar-header {
+ height: auto;
+}
+.navbar-inverse {
+ background-color: #000;
+ border-color: #000;
+}
+#navbar-brand {
+ margin-left: 20%;
+}
+.navtext {
+ font-size: 10px;
+}
+.h1,
+h1 {
+ font-size: 60px;
+}
+.navbar-default .navbar-header .navbar-brand {
+ color: #a2dfee;
+}
+/* tag titles */
+.swagger-section .swagger-ui-wrap ul#resources li.resource div.heading h2 a {
+ color: #393939;
+ font-family: 'Arvo', serif;
+ font-size: 1.5em;
+}
+.swagger-section .swagger-ui-wrap ul#resources li.resource div.heading h2 a:hover {
+ color: black;
+}
+.swagger-section .swagger-ui-wrap ul#resources li.resource div.heading h2 {
+ color: #525252;
+ padding-left: 0px;
+ display: block;
+ clear: none;
+ float: left;
+ font-family: 'Arvo', serif;
+ font-weight: bold;
+}
+.navbar-default .navbar-collapse,
+.navbar-default .navbar-form {
+ border-color: #0A0A0A;
+}
+.container1 {
+ width: 1500px;
+ margin: auto;
+ margin-top: 0;
+ background-image: url('../images/shield.png');
+ background-repeat: no-repeat;
+ background-position: -40px -20px;
+ margin-bottom: 210px;
+}
+.container-inner {
+ width: 1200px;
+ margin: auto;
+ background-color: rgba(223, 227, 228, 0.75);
+ padding-bottom: 40px;
+ padding-top: 40px;
+ border-radius: 15px;
+}
+.header-content {
+ padding: 0;
+ width: 1000px;
+}
+.title1 {
+ font-size: 80px;
+ font-family: 'Vollkorn', serif;
+ color: #404040;
+ text-align: center;
+ padding-top: 40px;
+ padding-bottom: 100px;
+}
+#icon {
+ margin-top: -18px;
+}
+.subtext {
+ font-size: 25px;
+ font-style: italic;
+ color: #08b;
+ text-align: right;
+ padding-right: 250px;
+}
+.bg-primary {
+ background-color: #00468b;
+}
+.navbar-default .nav > li > a,
+.navbar-default .nav > li > a:focus {
+ color: #08b;
+}
+.navbar-default .nav > li > a,
+.navbar-default .nav > li > a:hover {
+ color: #08b;
+}
+.navbar-default .nav > li > a,
+.navbar-default .nav > li > a:focus:hover {
+ color: #08b;
+}
+.text-faded {
+ font-size: 25px;
+ font-family: 'Vollkorn', serif;
+}
+.section-heading {
+ font-family: 'Vollkorn', serif;
+ font-size: 45px;
+ padding-bottom: 10px;
+}
+hr {
+ border-color: #00468b;
+ padding-bottom: 10px;
+}
+.description {
+ margin-top: 20px;
+ padding-bottom: 200px;
+}
+.description li {
+ font-family: 'Vollkorn', serif;
+ font-size: 25px;
+ color: #525252;
+ margin-left: 28%;
+ padding-top: 5px;
+}
+.gap {
+ margin-top: 200px;
+}
+.troubleshootingtext {
+ color: rgba(255, 255, 255, 0.7);
+ padding-left: 30%;
+}
+.troubleshootingtext li {
+ list-style-type: circle;
+ font-size: 25px;
+ padding-bottom: 5px;
+}
+.overlay {
+ position: absolute;
+ top: 0;
+ left: 0;
+ width: 100%;
+ height: 100%;
+ z-index: 1000;
+}
+.block.response_body.json:hover {
+ cursor: pointer;
+}
+.backdrop {
+ color: blue;
+}
+#myModal {
+ height: 100%;
+}
+.modal-backdrop {
+ bottom: 0;
+ position: fixed;
+}
+.curl {
+ padding: 10px;
+ font-family: "Anonymous Pro", "Menlo", "Consolas", "Bitstream Vera Sans Mono", "Courier New", monospace;
+ font-size: 0.9em;
+ max-height: 400px;
+ margin-top: 5px;
+ overflow-y: auto;
+ background-color: #fcf6db;
+ border: 1px solid #e5e0c6;
+ border-radius: 4px;
+}
+.curl_title {
+ font-size: 1.1em;
+ margin: 0;
+ padding: 15px 0 5px;
+ font-family: 'Open Sans', 'Helvetica Neue', Arial, sans-serif;
+ font-weight: 500;
+ line-height: 1.1;
+}
+.footer {
+ display: none;
+}
+.swagger-section .swagger-ui-wrap h2 {
+ padding: 0;
+}
+h2 {
+ margin: 0;
+ margin-bottom: 5px;
+}
+.markdown p {
+ font-size: 15px;
+ font-family: 'Arvo', serif;
+}
+.swagger-section .swagger-ui-wrap .code {
+ font-size: 15px;
+ font-family: 'Arvo', serif;
+}
+.swagger-section .swagger-ui-wrap b {
+ font-family: 'Arvo', serif;
+}
+#signin:hover {
+ cursor: pointer;
+}
+.dropdown-menu {
+ padding: 15px;
+}
+.navbar-right .dropdown-menu {
+ left: 0;
+ right: auto;
+}
+#signinbutton {
+ width: 100%;
+ height: 32px;
+ font-size: 13px;
+ font-weight: bold;
+ color: #08b;
+}
+.navbar-default .nav > li .details {
+ color: #000000;
+ text-transform: none;
+ font-size: 15px;
+ font-weight: normal;
+ font-family: 'Open Sans', sans-serif;
+ font-style: italic;
+ line-height: 20px;
+ top: -2px;
+}
+.navbar-default .nav > li .details:hover {
+ color: black;
+}
+#signout {
+ width: 100%;
+ height: 32px;
+ font-size: 13px;
+ font-weight: bold;
+ color: #08b;
+}
diff --git a/ydb/core/viewer/content/api/css/typography.css b/ydb/core/viewer/content/api/css/typography.css
index cfb04c40a3d..efb785fabb2 100644
--- a/ydb/core/viewer/content/api/css/typography.css
+++ b/ydb/core/viewer/content/api/css/typography.css
@@ -1,14 +1,14 @@
-/* Google Font's Droid Sans */
-@font-face {
- font-family: 'Droid Sans';
- font-style: normal;
- font-weight: 400;
- src: local('Droid Sans'), local('DroidSans'), url('../fonts/DroidSans.ttf'), format('truetype');
-}
-/* Google Font's Droid Sans Bold */
-@font-face {
- font-family: 'Droid Sans';
- font-style: normal;
- font-weight: 700;
- src: local('Droid Sans Bold'), local('DroidSans-Bold'), url('../fonts/DroidSans-Bold.ttf'), format('truetype');
-}
+/* Google Font's Droid Sans */
+@font-face {
+ font-family: 'Droid Sans';
+ font-style: normal;
+ font-weight: 400;
+ src: local('Droid Sans'), local('DroidSans'), url('../fonts/DroidSans.ttf'), format('truetype');
+}
+/* Google Font's Droid Sans Bold */
+@font-face {
+ font-family: 'Droid Sans';
+ font-style: normal;
+ font-weight: 700;
+ src: local('Droid Sans Bold'), local('DroidSans-Bold'), url('../fonts/DroidSans-Bold.ttf'), format('truetype');
+}
diff --git a/ydb/core/viewer/content/api/index.html b/ydb/core/viewer/content/api/index.html
index 34e7be40629..6e7403c4f3e 100644
--- a/ydb/core/viewer/content/api/index.html
+++ b/ydb/core/viewer/content/api/index.html
@@ -1,107 +1,107 @@
-<!DOCTYPE html>
-<html>
-<head>
- <meta charset="UTF-8">
- <title>Swagger UI</title>
- <link rel="icon" type="image/png" href="images/favicon-32x32.png" sizes="32x32" />
- <link rel="icon" type="image/png" href="images/favicon-16x16.png" sizes="16x16" />
- <link href='css/typography.css' media='screen' rel='stylesheet' type='text/css'/>
- <link href='css/reset.css' media='screen' rel='stylesheet' type='text/css'/>
- <link href='css/screen.css' media='screen' rel='stylesheet' type='text/css'/>
- <link href='css/reset.css' media='print' rel='stylesheet' type='text/css'/>
- <link href='css/print.css' media='print' rel='stylesheet' type='text/css'/>
-
- <script src='lib/object-assign-pollyfill.js' type='text/javascript'></script>
- <script src='lib/jquery-1.8.0.min.js' type='text/javascript'></script>
- <script src='lib/jquery.slideto.min.js' type='text/javascript'></script>
- <script src='lib/jquery.wiggle.min.js' type='text/javascript'></script>
- <script src='lib/jquery.ba-bbq.min.js' type='text/javascript'></script>
- <script src='lib/handlebars-4.0.5.js' type='text/javascript'></script>
- <script src='lib/lodash.min.js' type='text/javascript'></script>
- <script src='lib/backbone-min.js' type='text/javascript'></script>
- <script src='swagger-ui.min.js' type='text/javascript'></script>
- <script src='lib/highlight.9.1.0.pack.js' type='text/javascript'></script>
- <script src='lib/highlight.9.1.0.pack_extended.js' type='text/javascript'></script>
- <script src='lib/jsoneditor.min.js' type='text/javascript'></script>
- <script src='lib/marked.js' type='text/javascript'></script>
- <script src='lib/swagger-oauth.js' type='text/javascript'></script>
-
- <!-- Some basic translations -->
- <!-- <script src='lang/translator.js' type='text/javascript'></script> -->
- <!-- <script src='lang/ru.js' type='text/javascript'></script> -->
- <!-- <script src='lang/en.js' type='text/javascript'></script> -->
-
- <script type="text/javascript">
- $(function () {
- var url = window.location.search.match(/url=([^&]+)/);
- if (url && url.length > 1) {
- url = decodeURIComponent(url[1]);
- } else {
- url = "viewer.json?basepath=" + window.location.pathname + "&protocol=" + window.location.protocol.split(':')[0];
- }
-
- hljs.configure({
- highlightSizeThreshold: 5000
- });
-
- // Pre load translate...
- if(window.SwaggerTranslator) {
- window.SwaggerTranslator.translate();
- }
- window.swaggerUi = new SwaggerUi({
- url: url,
- dom_id: "swagger-ui-container",
- supportedSubmitMethods: ['get', 'post', 'put', 'delete', 'patch'],
- onComplete: function(swaggerApi, swaggerUi){
- if(typeof initOAuth == "function") {
- initOAuth({
- clientId: "your-client-id",
- clientSecret: "your-client-secret-if-required",
- realm: "your-realms",
- appName: "your-app-name",
- scopeSeparator: " ",
- additionalQueryStringParams: {}
- });
- }
-
- if(window.SwaggerTranslator) {
- window.SwaggerTranslator.translate();
- }
- },
- onFailure: function(data) {
- log("Unable to Load SwaggerUI");
- },
- docExpansion: "none",
- jsonEditor: false,
- defaultModelRendering: 'schema',
- showRequestHeaders: false,
- validatorUrl: null
- });
-
- window.swaggerUi.load();
-
- function log() {
- if ('console' in window) {
- console.log.apply(console, arguments);
- }
- }
- });
- </script>
-</head>
-
-<body class="swagger-section">
-<div id='header'>
- <div class="swagger-ui-wrap">
- <a id="logo" href="http://swagger.io"><img class="logo__img" alt="swagger" height="30" width="30" src="images/logo_small.png" /><span class="logo__title">swagger</span></a>
- <form id='api_selector'>
- <div class='input'><input placeholder="http://example.com/api" id="input_baseUrl" name="baseUrl" type="text"/></div>
- <div id='auth_container'></div>
- <div class='input'><a id="explore" class="header__btn" href="#" data-sw-translate>Explore</a></div>
- </form>
- </div>
-</div>
-
-<div id="message-bar" class="swagger-ui-wrap" data-sw-translate>&nbsp;</div>
-<div id="swagger-ui-container" class="swagger-ui-wrap"></div>
-</body>
-</html>
+<!DOCTYPE html>
+<html>
+<head>
+ <meta charset="UTF-8">
+ <title>Swagger UI</title>
+ <link rel="icon" type="image/png" href="images/favicon-32x32.png" sizes="32x32" />
+ <link rel="icon" type="image/png" href="images/favicon-16x16.png" sizes="16x16" />
+ <link href='css/typography.css' media='screen' rel='stylesheet' type='text/css'/>
+ <link href='css/reset.css' media='screen' rel='stylesheet' type='text/css'/>
+ <link href='css/screen.css' media='screen' rel='stylesheet' type='text/css'/>
+ <link href='css/reset.css' media='print' rel='stylesheet' type='text/css'/>
+ <link href='css/print.css' media='print' rel='stylesheet' type='text/css'/>
+
+ <script src='lib/object-assign-pollyfill.js' type='text/javascript'></script>
+ <script src='lib/jquery-1.8.0.min.js' type='text/javascript'></script>
+ <script src='lib/jquery.slideto.min.js' type='text/javascript'></script>
+ <script src='lib/jquery.wiggle.min.js' type='text/javascript'></script>
+ <script src='lib/jquery.ba-bbq.min.js' type='text/javascript'></script>
+ <script src='lib/handlebars-4.0.5.js' type='text/javascript'></script>
+ <script src='lib/lodash.min.js' type='text/javascript'></script>
+ <script src='lib/backbone-min.js' type='text/javascript'></script>
+ <script src='swagger-ui.min.js' type='text/javascript'></script>
+ <script src='lib/highlight.9.1.0.pack.js' type='text/javascript'></script>
+ <script src='lib/highlight.9.1.0.pack_extended.js' type='text/javascript'></script>
+ <script src='lib/jsoneditor.min.js' type='text/javascript'></script>
+ <script src='lib/marked.js' type='text/javascript'></script>
+ <script src='lib/swagger-oauth.js' type='text/javascript'></script>
+
+ <!-- Some basic translations -->
+ <!-- <script src='lang/translator.js' type='text/javascript'></script> -->
+ <!-- <script src='lang/ru.js' type='text/javascript'></script> -->
+ <!-- <script src='lang/en.js' type='text/javascript'></script> -->
+
+ <script type="text/javascript">
+ $(function () {
+ var url = window.location.search.match(/url=([^&]+)/);
+ if (url && url.length > 1) {
+ url = decodeURIComponent(url[1]);
+ } else {
+ url = "viewer.json?basepath=" + window.location.pathname + "&protocol=" + window.location.protocol.split(':')[0];
+ }
+
+ hljs.configure({
+ highlightSizeThreshold: 5000
+ });
+
+ // Pre load translate...
+ if(window.SwaggerTranslator) {
+ window.SwaggerTranslator.translate();
+ }
+ window.swaggerUi = new SwaggerUi({
+ url: url,
+ dom_id: "swagger-ui-container",
+ supportedSubmitMethods: ['get', 'post', 'put', 'delete', 'patch'],
+ onComplete: function(swaggerApi, swaggerUi){
+ if(typeof initOAuth == "function") {
+ initOAuth({
+ clientId: "your-client-id",
+ clientSecret: "your-client-secret-if-required",
+ realm: "your-realms",
+ appName: "your-app-name",
+ scopeSeparator: " ",
+ additionalQueryStringParams: {}
+ });
+ }
+
+ if(window.SwaggerTranslator) {
+ window.SwaggerTranslator.translate();
+ }
+ },
+ onFailure: function(data) {
+ log("Unable to Load SwaggerUI");
+ },
+ docExpansion: "none",
+ jsonEditor: false,
+ defaultModelRendering: 'schema',
+ showRequestHeaders: false,
+ validatorUrl: null
+ });
+
+ window.swaggerUi.load();
+
+ function log() {
+ if ('console' in window) {
+ console.log.apply(console, arguments);
+ }
+ }
+ });
+ </script>
+</head>
+
+<body class="swagger-section">
+<div id='header'>
+ <div class="swagger-ui-wrap">
+ <a id="logo" href="http://swagger.io"><img class="logo__img" alt="swagger" height="30" width="30" src="images/logo_small.png" /><span class="logo__title">swagger</span></a>
+ <form id='api_selector'>
+ <div class='input'><input placeholder="http://example.com/api" id="input_baseUrl" name="baseUrl" type="text"/></div>
+ <div id='auth_container'></div>
+ <div class='input'><a id="explore" class="header__btn" href="#" data-sw-translate>Explore</a></div>
+ </form>
+ </div>
+</div>
+
+<div id="message-bar" class="swagger-ui-wrap" data-sw-translate>&nbsp;</div>
+<div id="swagger-ui-container" class="swagger-ui-wrap"></div>
+</body>
+</html>
diff --git a/ydb/core/viewer/content/api/lang/ca.js b/ydb/core/viewer/content/api/lang/ca.js
index 0e48ec32039..f8c815aa92c 100644
--- a/ydb/core/viewer/content/api/lang/ca.js
+++ b/ydb/core/viewer/content/api/lang/ca.js
@@ -1,53 +1,53 @@
-'use strict';
-
-/* jshint quotmark: double */
-window.SwaggerTranslator.learn({
- "Warning: Deprecated":"Advertència: Obsolet",
- "Implementation Notes":"Notes d'implementació",
- "Response Class":"Classe de la Resposta",
- "Status":"Estatus",
- "Parameters":"Paràmetres",
- "Parameter":"Paràmetre",
- "Value":"Valor",
- "Description":"Descripció",
- "Parameter Type":"Tipus del Paràmetre",
- "Data Type":"Tipus de la Dada",
- "Response Messages":"Missatges de la Resposta",
- "HTTP Status Code":"Codi d'Estatus HTTP",
- "Reason":"Raó",
- "Response Model":"Model de la Resposta",
- "Request URL":"URL de la Sol·licitud",
- "Response Body":"Cos de la Resposta",
- "Response Code":"Codi de la Resposta",
- "Response Headers":"Capçaleres de la Resposta",
- "Hide Response":"Amagar Resposta",
- "Try it out!":"Prova-ho!",
- "Show/Hide":"Mostrar/Amagar",
- "List Operations":"Llista Operacions",
- "Expand Operations":"Expandir Operacions",
- "Raw":"Cru",
- "can't parse JSON. Raw result":"no puc analitzar el JSON. Resultat cru",
- "Example Value":"Valor d'Exemple",
- "Model Schema":"Esquema del Model",
- "Model":"Model",
- "apply":"aplicar",
- "Username":"Nom d'usuari",
- "Password":"Contrasenya",
- "Terms of service":"Termes del servei",
- "Created by":"Creat per",
- "See more at":"Veure més en",
- "Contact the developer":"Contactar amb el desenvolupador",
- "api version":"versió de la api",
- "Response Content Type":"Tipus de Contingut de la Resposta",
- "fetching resource":"recollint recurs",
- "fetching resource list":"recollins llista de recursos",
- "Explore":"Explorant",
- "Show Swagger Petstore Example Apis":"Mostrar API d'Exemple Swagger Petstore",
- "Can't read from server. It may not have the appropriate access-control-origin settings.":"No es pot llegir del servidor. Potser no teniu la configuració de control d'accés apropiada.",
- "Please specify the protocol for":"Si us plau, especifiqueu el protocol per a",
- "Can't read swagger JSON from":"No es pot llegir el JSON de swagger des de",
- "Finished Loading Resource Information. Rendering Swagger UI":"Finalitzada la càrrega del recurs informatiu. Renderitzant Swagger UI",
- "Unable to read api":"No es pot llegir l'api",
- "from path":"des de la ruta",
- "server returned":"el servidor ha retornat"
-});
+'use strict';
+
+/* jshint quotmark: double */
+window.SwaggerTranslator.learn({
+ "Warning: Deprecated":"Advertència: Obsolet",
+ "Implementation Notes":"Notes d'implementació",
+ "Response Class":"Classe de la Resposta",
+ "Status":"Estatus",
+ "Parameters":"Paràmetres",
+ "Parameter":"Paràmetre",
+ "Value":"Valor",
+ "Description":"Descripció",
+ "Parameter Type":"Tipus del Paràmetre",
+ "Data Type":"Tipus de la Dada",
+ "Response Messages":"Missatges de la Resposta",
+ "HTTP Status Code":"Codi d'Estatus HTTP",
+ "Reason":"Raó",
+ "Response Model":"Model de la Resposta",
+ "Request URL":"URL de la Sol·licitud",
+ "Response Body":"Cos de la Resposta",
+ "Response Code":"Codi de la Resposta",
+ "Response Headers":"Capçaleres de la Resposta",
+ "Hide Response":"Amagar Resposta",
+ "Try it out!":"Prova-ho!",
+ "Show/Hide":"Mostrar/Amagar",
+ "List Operations":"Llista Operacions",
+ "Expand Operations":"Expandir Operacions",
+ "Raw":"Cru",
+ "can't parse JSON. Raw result":"no puc analitzar el JSON. Resultat cru",
+ "Example Value":"Valor d'Exemple",
+ "Model Schema":"Esquema del Model",
+ "Model":"Model",
+ "apply":"aplicar",
+ "Username":"Nom d'usuari",
+ "Password":"Contrasenya",
+ "Terms of service":"Termes del servei",
+ "Created by":"Creat per",
+ "See more at":"Veure més en",
+ "Contact the developer":"Contactar amb el desenvolupador",
+ "api version":"versió de la api",
+ "Response Content Type":"Tipus de Contingut de la Resposta",
+ "fetching resource":"recollint recurs",
+ "fetching resource list":"recollins llista de recursos",
+ "Explore":"Explorant",
+ "Show Swagger Petstore Example Apis":"Mostrar API d'Exemple Swagger Petstore",
+ "Can't read from server. It may not have the appropriate access-control-origin settings.":"No es pot llegir del servidor. Potser no teniu la configuració de control d'accés apropiada.",
+ "Please specify the protocol for":"Si us plau, especifiqueu el protocol per a",
+ "Can't read swagger JSON from":"No es pot llegir el JSON de swagger des de",
+ "Finished Loading Resource Information. Rendering Swagger UI":"Finalitzada la càrrega del recurs informatiu. Renderitzant Swagger UI",
+ "Unable to read api":"No es pot llegir l'api",
+ "from path":"des de la ruta",
+ "server returned":"el servidor ha retornat"
+});
diff --git a/ydb/core/viewer/content/api/lang/en.js b/ydb/core/viewer/content/api/lang/en.js
index d06e76373e0..918313665db 100644
--- a/ydb/core/viewer/content/api/lang/en.js
+++ b/ydb/core/viewer/content/api/lang/en.js
@@ -1,56 +1,56 @@
-'use strict';
-
-/* jshint quotmark: double */
-window.SwaggerTranslator.learn({
- "Warning: Deprecated":"Warning: Deprecated",
- "Implementation Notes":"Implementation Notes",
- "Response Class":"Response Class",
- "Status":"Status",
- "Parameters":"Parameters",
- "Parameter":"Parameter",
- "Value":"Value",
- "Description":"Description",
- "Parameter Type":"Parameter Type",
- "Data Type":"Data Type",
- "Response Messages":"Response Messages",
- "HTTP Status Code":"HTTP Status Code",
- "Reason":"Reason",
- "Response Model":"Response Model",
- "Request URL":"Request URL",
- "Response Body":"Response Body",
- "Response Code":"Response Code",
- "Response Headers":"Response Headers",
- "Hide Response":"Hide Response",
- "Headers":"Headers",
- "Try it out!":"Try it out!",
- "Show/Hide":"Show/Hide",
- "List Operations":"List Operations",
- "Expand Operations":"Expand Operations",
- "Raw":"Raw",
- "can't parse JSON. Raw result":"can't parse JSON. Raw result",
- "Example Value":"Example Value",
- "Model Schema":"Model Schema",
- "Model":"Model",
- "Click to set as parameter value":"Click to set as parameter value",
- "apply":"apply",
- "Username":"Username",
- "Password":"Password",
- "Terms of service":"Terms of service",
- "Created by":"Created by",
- "See more at":"See more at",
- "Contact the developer":"Contact the developer",
- "api version":"api version",
- "Response Content Type":"Response Content Type",
- "Parameter content type:":"Parameter content type:",
- "fetching resource":"fetching resource",
- "fetching resource list":"fetching resource list",
- "Explore":"Explore",
- "Show Swagger Petstore Example Apis":"Show Swagger Petstore Example Apis",
- "Can't read from server. It may not have the appropriate access-control-origin settings.":"Can't read from server. It may not have the appropriate access-control-origin settings.",
- "Please specify the protocol for":"Please specify the protocol for",
- "Can't read swagger JSON from":"Can't read swagger JSON from",
- "Finished Loading Resource Information. Rendering Swagger UI":"Finished Loading Resource Information. Rendering Swagger UI",
- "Unable to read api":"Unable to read api",
- "from path":"from path",
- "server returned":"server returned"
-});
+'use strict';
+
+/* jshint quotmark: double */
+window.SwaggerTranslator.learn({
+ "Warning: Deprecated":"Warning: Deprecated",
+ "Implementation Notes":"Implementation Notes",
+ "Response Class":"Response Class",
+ "Status":"Status",
+ "Parameters":"Parameters",
+ "Parameter":"Parameter",
+ "Value":"Value",
+ "Description":"Description",
+ "Parameter Type":"Parameter Type",
+ "Data Type":"Data Type",
+ "Response Messages":"Response Messages",
+ "HTTP Status Code":"HTTP Status Code",
+ "Reason":"Reason",
+ "Response Model":"Response Model",
+ "Request URL":"Request URL",
+ "Response Body":"Response Body",
+ "Response Code":"Response Code",
+ "Response Headers":"Response Headers",
+ "Hide Response":"Hide Response",
+ "Headers":"Headers",
+ "Try it out!":"Try it out!",
+ "Show/Hide":"Show/Hide",
+ "List Operations":"List Operations",
+ "Expand Operations":"Expand Operations",
+ "Raw":"Raw",
+ "can't parse JSON. Raw result":"can't parse JSON. Raw result",
+ "Example Value":"Example Value",
+ "Model Schema":"Model Schema",
+ "Model":"Model",
+ "Click to set as parameter value":"Click to set as parameter value",
+ "apply":"apply",
+ "Username":"Username",
+ "Password":"Password",
+ "Terms of service":"Terms of service",
+ "Created by":"Created by",
+ "See more at":"See more at",
+ "Contact the developer":"Contact the developer",
+ "api version":"api version",
+ "Response Content Type":"Response Content Type",
+ "Parameter content type:":"Parameter content type:",
+ "fetching resource":"fetching resource",
+ "fetching resource list":"fetching resource list",
+ "Explore":"Explore",
+ "Show Swagger Petstore Example Apis":"Show Swagger Petstore Example Apis",
+ "Can't read from server. It may not have the appropriate access-control-origin settings.":"Can't read from server. It may not have the appropriate access-control-origin settings.",
+ "Please specify the protocol for":"Please specify the protocol for",
+ "Can't read swagger JSON from":"Can't read swagger JSON from",
+ "Finished Loading Resource Information. Rendering Swagger UI":"Finished Loading Resource Information. Rendering Swagger UI",
+ "Unable to read api":"Unable to read api",
+ "from path":"from path",
+ "server returned":"server returned"
+});
diff --git a/ydb/core/viewer/content/api/lang/es.js b/ydb/core/viewer/content/api/lang/es.js
index e0b20726f00..13fa015e6df 100644
--- a/ydb/core/viewer/content/api/lang/es.js
+++ b/ydb/core/viewer/content/api/lang/es.js
@@ -1,53 +1,53 @@
-'use strict';
-
-/* jshint quotmark: double */
-window.SwaggerTranslator.learn({
- "Warning: Deprecated":"Advertencia: Obsoleto",
- "Implementation Notes":"Notas de implementación",
- "Response Class":"Clase de la Respuesta",
- "Status":"Status",
- "Parameters":"Parámetros",
- "Parameter":"Parámetro",
- "Value":"Valor",
- "Description":"Descripción",
- "Parameter Type":"Tipo del Parámetro",
- "Data Type":"Tipo del Dato",
- "Response Messages":"Mensajes de la Respuesta",
- "HTTP Status Code":"Código de Status HTTP",
- "Reason":"Razón",
- "Response Model":"Modelo de la Respuesta",
- "Request URL":"URL de la Solicitud",
- "Response Body":"Cuerpo de la Respuesta",
- "Response Code":"Código de la Respuesta",
- "Response Headers":"Encabezados de la Respuesta",
- "Hide Response":"Ocultar Respuesta",
- "Try it out!":"Pruébalo!",
- "Show/Hide":"Mostrar/Ocultar",
- "List Operations":"Listar Operaciones",
- "Expand Operations":"Expandir Operaciones",
- "Raw":"Crudo",
- "can't parse JSON. Raw result":"no puede parsear el JSON. Resultado crudo",
- "Example Value":"Valor de Ejemplo",
- "Model Schema":"Esquema del Modelo",
- "Model":"Modelo",
- "apply":"aplicar",
- "Username":"Nombre de usuario",
- "Password":"Contraseña",
- "Terms of service":"Términos de Servicio",
- "Created by":"Creado por",
- "See more at":"Ver más en",
- "Contact the developer":"Contactar al desarrollador",
- "api version":"versión de la api",
- "Response Content Type":"Tipo de Contenido (Content Type) de la Respuesta",
- "fetching resource":"buscando recurso",
- "fetching resource list":"buscando lista del recurso",
- "Explore":"Explorar",
- "Show Swagger Petstore Example Apis":"Mostrar Api Ejemplo de Swagger Petstore",
- "Can't read from server. It may not have the appropriate access-control-origin settings.":"No se puede leer del servidor. Tal vez no tiene la configuración de control de acceso de origen (access-control-origin) apropiado.",
- "Please specify the protocol for":"Por favor, especificar el protocola para",
- "Can't read swagger JSON from":"No se puede leer el JSON de swagger desde",
- "Finished Loading Resource Information. Rendering Swagger UI":"Finalizada la carga del recurso de Información. Mostrando Swagger UI",
- "Unable to read api":"No se puede leer la api",
- "from path":"desde ruta",
- "server returned":"el servidor retornó"
-});
+'use strict';
+
+/* jshint quotmark: double */
+window.SwaggerTranslator.learn({
+ "Warning: Deprecated":"Advertencia: Obsoleto",
+ "Implementation Notes":"Notas de implementación",
+ "Response Class":"Clase de la Respuesta",
+ "Status":"Status",
+ "Parameters":"Parámetros",
+ "Parameter":"Parámetro",
+ "Value":"Valor",
+ "Description":"Descripción",
+ "Parameter Type":"Tipo del Parámetro",
+ "Data Type":"Tipo del Dato",
+ "Response Messages":"Mensajes de la Respuesta",
+ "HTTP Status Code":"Código de Status HTTP",
+ "Reason":"Razón",
+ "Response Model":"Modelo de la Respuesta",
+ "Request URL":"URL de la Solicitud",
+ "Response Body":"Cuerpo de la Respuesta",
+ "Response Code":"Código de la Respuesta",
+ "Response Headers":"Encabezados de la Respuesta",
+ "Hide Response":"Ocultar Respuesta",
+ "Try it out!":"Pruébalo!",
+ "Show/Hide":"Mostrar/Ocultar",
+ "List Operations":"Listar Operaciones",
+ "Expand Operations":"Expandir Operaciones",
+ "Raw":"Crudo",
+ "can't parse JSON. Raw result":"no puede parsear el JSON. Resultado crudo",
+ "Example Value":"Valor de Ejemplo",
+ "Model Schema":"Esquema del Modelo",
+ "Model":"Modelo",
+ "apply":"aplicar",
+ "Username":"Nombre de usuario",
+ "Password":"Contraseña",
+ "Terms of service":"Términos de Servicio",
+ "Created by":"Creado por",
+ "See more at":"Ver más en",
+ "Contact the developer":"Contactar al desarrollador",
+ "api version":"versión de la api",
+ "Response Content Type":"Tipo de Contenido (Content Type) de la Respuesta",
+ "fetching resource":"buscando recurso",
+ "fetching resource list":"buscando lista del recurso",
+ "Explore":"Explorar",
+ "Show Swagger Petstore Example Apis":"Mostrar Api Ejemplo de Swagger Petstore",
+ "Can't read from server. It may not have the appropriate access-control-origin settings.":"No se puede leer del servidor. Tal vez no tiene la configuración de control de acceso de origen (access-control-origin) apropiado.",
+ "Please specify the protocol for":"Por favor, especificar el protocola para",
+ "Can't read swagger JSON from":"No se puede leer el JSON de swagger desde",
+ "Finished Loading Resource Information. Rendering Swagger UI":"Finalizada la carga del recurso de Información. Mostrando Swagger UI",
+ "Unable to read api":"No se puede leer la api",
+ "from path":"desde ruta",
+ "server returned":"el servidor retornó"
+});
diff --git a/ydb/core/viewer/content/api/lang/fr.js b/ydb/core/viewer/content/api/lang/fr.js
index 6d32cb52d76..388dff14bac 100644
--- a/ydb/core/viewer/content/api/lang/fr.js
+++ b/ydb/core/viewer/content/api/lang/fr.js
@@ -1,54 +1,54 @@
-'use strict';
-
-/* jshint quotmark: double */
-window.SwaggerTranslator.learn({
- "Warning: Deprecated":"Avertissement : Obsolète",
- "Implementation Notes":"Notes d'implémentation",
- "Response Class":"Classe de la réponse",
- "Status":"Statut",
- "Parameters":"Paramètres",
- "Parameter":"Paramètre",
- "Value":"Valeur",
- "Description":"Description",
- "Parameter Type":"Type du paramètre",
- "Data Type":"Type de données",
- "Response Messages":"Messages de la réponse",
- "HTTP Status Code":"Code de statut HTTP",
- "Reason":"Raison",
- "Response Model":"Modèle de réponse",
- "Request URL":"URL appelée",
- "Response Body":"Corps de la réponse",
- "Response Code":"Code de la réponse",
- "Response Headers":"En-têtes de la réponse",
- "Hide Response":"Cacher la réponse",
- "Headers":"En-têtes",
- "Try it out!":"Testez !",
- "Show/Hide":"Afficher/Masquer",
- "List Operations":"Liste des opérations",
- "Expand Operations":"Développer les opérations",
- "Raw":"Brut",
- "can't parse JSON. Raw result":"impossible de décoder le JSON. Résultat brut",
- "Example Value":"Exemple la valeur",
- "Model Schema":"Définition du modèle",
- "Model":"Modèle",
- "apply":"appliquer",
- "Username":"Nom d'utilisateur",
- "Password":"Mot de passe",
- "Terms of service":"Conditions de service",
- "Created by":"Créé par",
- "See more at":"Voir plus sur",
- "Contact the developer":"Contacter le développeur",
- "api version":"version de l'api",
- "Response Content Type":"Content Type de la réponse",
- "fetching resource":"récupération de la ressource",
- "fetching resource list":"récupération de la liste de ressources",
- "Explore":"Explorer",
- "Show Swagger Petstore Example Apis":"Montrer les Apis de l'exemple Petstore de Swagger",
- "Can't read from server. It may not have the appropriate access-control-origin settings.":"Impossible de lire à partir du serveur. Il se peut que les réglages access-control-origin ne soient pas appropriés.",
- "Please specify the protocol for":"Veuillez spécifier un protocole pour",
- "Can't read swagger JSON from":"Impossible de lire le JSON swagger à partir de",
- "Finished Loading Resource Information. Rendering Swagger UI":"Chargement des informations terminé. Affichage de Swagger UI",
- "Unable to read api":"Impossible de lire l'api",
- "from path":"à partir du chemin",
- "server returned":"réponse du serveur"
-});
+'use strict';
+
+/* jshint quotmark: double */
+window.SwaggerTranslator.learn({
+ "Warning: Deprecated":"Avertissement : Obsolète",
+ "Implementation Notes":"Notes d'implémentation",
+ "Response Class":"Classe de la réponse",
+ "Status":"Statut",
+ "Parameters":"Paramètres",
+ "Parameter":"Paramètre",
+ "Value":"Valeur",
+ "Description":"Description",
+ "Parameter Type":"Type du paramètre",
+ "Data Type":"Type de données",
+ "Response Messages":"Messages de la réponse",
+ "HTTP Status Code":"Code de statut HTTP",
+ "Reason":"Raison",
+ "Response Model":"Modèle de réponse",
+ "Request URL":"URL appelée",
+ "Response Body":"Corps de la réponse",
+ "Response Code":"Code de la réponse",
+ "Response Headers":"En-têtes de la réponse",
+ "Hide Response":"Cacher la réponse",
+ "Headers":"En-têtes",
+ "Try it out!":"Testez !",
+ "Show/Hide":"Afficher/Masquer",
+ "List Operations":"Liste des opérations",
+ "Expand Operations":"Développer les opérations",
+ "Raw":"Brut",
+ "can't parse JSON. Raw result":"impossible de décoder le JSON. Résultat brut",
+ "Example Value":"Exemple la valeur",
+ "Model Schema":"Définition du modèle",
+ "Model":"Modèle",
+ "apply":"appliquer",
+ "Username":"Nom d'utilisateur",
+ "Password":"Mot de passe",
+ "Terms of service":"Conditions de service",
+ "Created by":"Créé par",
+ "See more at":"Voir plus sur",
+ "Contact the developer":"Contacter le développeur",
+ "api version":"version de l'api",
+ "Response Content Type":"Content Type de la réponse",
+ "fetching resource":"récupération de la ressource",
+ "fetching resource list":"récupération de la liste de ressources",
+ "Explore":"Explorer",
+ "Show Swagger Petstore Example Apis":"Montrer les Apis de l'exemple Petstore de Swagger",
+ "Can't read from server. It may not have the appropriate access-control-origin settings.":"Impossible de lire à partir du serveur. Il se peut que les réglages access-control-origin ne soient pas appropriés.",
+ "Please specify the protocol for":"Veuillez spécifier un protocole pour",
+ "Can't read swagger JSON from":"Impossible de lire le JSON swagger à partir de",
+ "Finished Loading Resource Information. Rendering Swagger UI":"Chargement des informations terminé. Affichage de Swagger UI",
+ "Unable to read api":"Impossible de lire l'api",
+ "from path":"à partir du chemin",
+ "server returned":"réponse du serveur"
+});
diff --git a/ydb/core/viewer/content/api/lang/geo.js b/ydb/core/viewer/content/api/lang/geo.js
index 3ccf8e528e6..609c20d9c86 100644
--- a/ydb/core/viewer/content/api/lang/geo.js
+++ b/ydb/core/viewer/content/api/lang/geo.js
@@ -1,56 +1,56 @@
-'use strict';
-
-/* jshint quotmark: double */
-window.SwaggerTranslator.learn({
- "Warning: Deprecated":"ყურადღება: აღარ გამოიყენება",
- "Implementation Notes":"იმპლემენტაციის აღწერა",
- "Response Class":"რესპონს კლასი",
- "Status":"სტატუსი",
- "Parameters":"პარამეტრები",
- "Parameter":"პარამეტრი",
- "Value":"მნიშვნელობა",
- "Description":"აღწერა",
- "Parameter Type":"პარამეტრის ტიპი",
- "Data Type":"მონაცემის ტიპი",
- "Response Messages":"პასუხი",
- "HTTP Status Code":"HTTP სტატუსი",
- "Reason":"მიზეზი",
- "Response Model":"რესპონს მოდელი",
- "Request URL":"მოთხოვნის URL",
- "Response Body":"პასუხის სხეული",
- "Response Code":"პასუხის კოდი",
- "Response Headers":"პასუხის ჰედერები",
- "Hide Response":"დამალე პასუხი",
- "Headers":"ჰედერები",
- "Try it out!":"ცადე !",
- "Show/Hide":"გამოჩენა/დამალვა",
- "List Operations":"ოპერაციების სია",
- "Expand Operations":"ოპერაციები ვრცლად",
- "Raw":"ნედლი",
- "can't parse JSON. Raw result":"JSON-ის დამუშავება ვერ მოხერხდა. ნედლი პასუხი",
- "Example Value":"მაგალითი",
- "Model Schema":"მოდელის სტრუქტურა",
- "Model":"მოდელი",
- "Click to set as parameter value":"პარამეტრისთვის მნიშვნელობის მისანიჭებლად, დააკლიკე",
- "apply":"გამოყენება",
- "Username":"მოხმარებელი",
- "Password":"პაროლი",
- "Terms of service":"მომსახურების პირობები",
- "Created by":"შექმნა",
- "See more at":"ნახე ვრცლად",
- "Contact the developer":"დაუკავშირდი დეველოპერს",
- "api version":"api ვერსია",
- "Response Content Type":"პასუხის კონტენტის ტიპი",
- "Parameter content type:":"პარამეტრის კონტენტის ტიპი:",
- "fetching resource":"რესურსების მიღება",
- "fetching resource list":"რესურსების სიის მიღება",
- "Explore":"ნახვა",
- "Show Swagger Petstore Example Apis":"ნახე Swagger Petstore სამაგალითო Api",
- "Can't read from server. It may not have the appropriate access-control-origin settings.":"სერვერთან დაკავშირება ვერ ხერხდება. შეამოწმეთ access-control-origin.",
- "Please specify the protocol for":"მიუთითეთ პროტოკოლი",
- "Can't read swagger JSON from":"swagger JSON წაკითხვა ვერ მოხერხდა",
- "Finished Loading Resource Information. Rendering Swagger UI":"რესურსების ჩატვირთვა სრულდება. Swagger UI რენდერდება",
- "Unable to read api":"api წაკითხვა ვერ მოხერხდა",
- "from path":"მისამართიდან",
- "server returned":"სერვერმა დააბრუნა"
-});
+'use strict';
+
+/* jshint quotmark: double */
+window.SwaggerTranslator.learn({
+ "Warning: Deprecated":"ყურადღება: აღარ გამოიყენება",
+ "Implementation Notes":"იმპლემენტაციის აღწერა",
+ "Response Class":"რესპონს კლასი",
+ "Status":"სტატუსი",
+ "Parameters":"პარამეტრები",
+ "Parameter":"პარამეტრი",
+ "Value":"მნიშვნელობა",
+ "Description":"აღწერა",
+ "Parameter Type":"პარამეტრის ტიპი",
+ "Data Type":"მონაცემის ტიპი",
+ "Response Messages":"პასუხი",
+ "HTTP Status Code":"HTTP სტატუსი",
+ "Reason":"მიზეზი",
+ "Response Model":"რესპონს მოდელი",
+ "Request URL":"მოთხოვნის URL",
+ "Response Body":"პასუხის სხეული",
+ "Response Code":"პასუხის კოდი",
+ "Response Headers":"პასუხის ჰედერები",
+ "Hide Response":"დამალე პასუხი",
+ "Headers":"ჰედერები",
+ "Try it out!":"ცადე !",
+ "Show/Hide":"გამოჩენა/დამალვა",
+ "List Operations":"ოპერაციების სია",
+ "Expand Operations":"ოპერაციები ვრცლად",
+ "Raw":"ნედლი",
+ "can't parse JSON. Raw result":"JSON-ის დამუშავება ვერ მოხერხდა. ნედლი პასუხი",
+ "Example Value":"მაგალითი",
+ "Model Schema":"მოდელის სტრუქტურა",
+ "Model":"მოდელი",
+ "Click to set as parameter value":"პარამეტრისთვის მნიშვნელობის მისანიჭებლად, დააკლიკე",
+ "apply":"გამოყენება",
+ "Username":"მოხმარებელი",
+ "Password":"პაროლი",
+ "Terms of service":"მომსახურების პირობები",
+ "Created by":"შექმნა",
+ "See more at":"ნახე ვრცლად",
+ "Contact the developer":"დაუკავშირდი დეველოპერს",
+ "api version":"api ვერსია",
+ "Response Content Type":"პასუხის კონტენტის ტიპი",
+ "Parameter content type:":"პარამეტრის კონტენტის ტიპი:",
+ "fetching resource":"რესურსების მიღება",
+ "fetching resource list":"რესურსების სიის მიღება",
+ "Explore":"ნახვა",
+ "Show Swagger Petstore Example Apis":"ნახე Swagger Petstore სამაგალითო Api",
+ "Can't read from server. It may not have the appropriate access-control-origin settings.":"სერვერთან დაკავშირება ვერ ხერხდება. შეამოწმეთ access-control-origin.",
+ "Please specify the protocol for":"მიუთითეთ პროტოკოლი",
+ "Can't read swagger JSON from":"swagger JSON წაკითხვა ვერ მოხერხდა",
+ "Finished Loading Resource Information. Rendering Swagger UI":"რესურსების ჩატვირთვა სრულდება. Swagger UI რენდერდება",
+ "Unable to read api":"api წაკითხვა ვერ მოხერხდა",
+ "from path":"მისამართიდან",
+ "server returned":"სერვერმა დააბრუნა"
+});
diff --git a/ydb/core/viewer/content/api/lang/it.js b/ydb/core/viewer/content/api/lang/it.js
index c007911f1a2..8529c2a90bc 100644
--- a/ydb/core/viewer/content/api/lang/it.js
+++ b/ydb/core/viewer/content/api/lang/it.js
@@ -1,52 +1,52 @@
-'use strict';
-
-/* jshint quotmark: double */
-window.SwaggerTranslator.learn({
- "Warning: Deprecated":"Attenzione: Deprecato",
- "Implementation Notes":"Note di implementazione",
- "Response Class":"Classe della risposta",
- "Status":"Stato",
- "Parameters":"Parametri",
- "Parameter":"Parametro",
- "Value":"Valore",
- "Description":"Descrizione",
- "Parameter Type":"Tipo di parametro",
- "Data Type":"Tipo di dato",
- "Response Messages":"Messaggi della risposta",
- "HTTP Status Code":"Codice stato HTTP",
- "Reason":"Motivo",
- "Response Model":"Modello di risposta",
- "Request URL":"URL della richiesta",
- "Response Body":"Corpo della risposta",
- "Response Code":"Oggetto della risposta",
- "Response Headers":"Intestazioni della risposta",
- "Hide Response":"Nascondi risposta",
- "Try it out!":"Provalo!",
- "Show/Hide":"Mostra/Nascondi",
- "List Operations":"Mostra operazioni",
- "Expand Operations":"Espandi operazioni",
- "Raw":"Grezzo (raw)",
- "can't parse JSON. Raw result":"non è possibile parsare il JSON. Risultato grezzo (raw).",
- "Model Schema":"Schema del modello",
- "Model":"Modello",
- "apply":"applica",
- "Username":"Nome utente",
- "Password":"Password",
- "Terms of service":"Condizioni del servizio",
- "Created by":"Creato da",
- "See more at":"Informazioni aggiuntive:",
- "Contact the developer":"Contatta lo sviluppatore",
- "api version":"versione api",
- "Response Content Type":"Tipo di contenuto (content type) della risposta",
- "fetching resource":"recuperando la risorsa",
- "fetching resource list":"recuperando lista risorse",
- "Explore":"Esplora",
- "Show Swagger Petstore Example Apis":"Mostra le api di esempio di Swagger Petstore",
- "Can't read from server. It may not have the appropriate access-control-origin settings.":"Non è possibile leggere dal server. Potrebbe non avere le impostazioni di controllo accesso origine (access-control-origin) appropriate.",
- "Please specify the protocol for":"Si prega di specificare il protocollo per",
- "Can't read swagger JSON from":"Impossibile leggere JSON swagger da:",
- "Finished Loading Resource Information. Rendering Swagger UI":"Lettura informazioni risorse termianta. Swagger UI viene mostrata",
- "Unable to read api":"Impossibile leggere la api",
- "from path":"da cartella",
- "server returned":"il server ha restituito"
-});
+'use strict';
+
+/* jshint quotmark: double */
+window.SwaggerTranslator.learn({
+ "Warning: Deprecated":"Attenzione: Deprecato",
+ "Implementation Notes":"Note di implementazione",
+ "Response Class":"Classe della risposta",
+ "Status":"Stato",
+ "Parameters":"Parametri",
+ "Parameter":"Parametro",
+ "Value":"Valore",
+ "Description":"Descrizione",
+ "Parameter Type":"Tipo di parametro",
+ "Data Type":"Tipo di dato",
+ "Response Messages":"Messaggi della risposta",
+ "HTTP Status Code":"Codice stato HTTP",
+ "Reason":"Motivo",
+ "Response Model":"Modello di risposta",
+ "Request URL":"URL della richiesta",
+ "Response Body":"Corpo della risposta",
+ "Response Code":"Oggetto della risposta",
+ "Response Headers":"Intestazioni della risposta",
+ "Hide Response":"Nascondi risposta",
+ "Try it out!":"Provalo!",
+ "Show/Hide":"Mostra/Nascondi",
+ "List Operations":"Mostra operazioni",
+ "Expand Operations":"Espandi operazioni",
+ "Raw":"Grezzo (raw)",
+ "can't parse JSON. Raw result":"non è possibile parsare il JSON. Risultato grezzo (raw).",
+ "Model Schema":"Schema del modello",
+ "Model":"Modello",
+ "apply":"applica",
+ "Username":"Nome utente",
+ "Password":"Password",
+ "Terms of service":"Condizioni del servizio",
+ "Created by":"Creato da",
+ "See more at":"Informazioni aggiuntive:",
+ "Contact the developer":"Contatta lo sviluppatore",
+ "api version":"versione api",
+ "Response Content Type":"Tipo di contenuto (content type) della risposta",
+ "fetching resource":"recuperando la risorsa",
+ "fetching resource list":"recuperando lista risorse",
+ "Explore":"Esplora",
+ "Show Swagger Petstore Example Apis":"Mostra le api di esempio di Swagger Petstore",
+ "Can't read from server. It may not have the appropriate access-control-origin settings.":"Non è possibile leggere dal server. Potrebbe non avere le impostazioni di controllo accesso origine (access-control-origin) appropriate.",
+ "Please specify the protocol for":"Si prega di specificare il protocollo per",
+ "Can't read swagger JSON from":"Impossibile leggere JSON swagger da:",
+ "Finished Loading Resource Information. Rendering Swagger UI":"Lettura informazioni risorse termianta. Swagger UI viene mostrata",
+ "Unable to read api":"Impossibile leggere la api",
+ "from path":"da cartella",
+ "server returned":"il server ha restituito"
+});
diff --git a/ydb/core/viewer/content/api/lang/ja.js b/ydb/core/viewer/content/api/lang/ja.js
index 928038ec6a0..3207bfc0baf 100755
--- a/ydb/core/viewer/content/api/lang/ja.js
+++ b/ydb/core/viewer/content/api/lang/ja.js
@@ -1,53 +1,53 @@
-'use strict';
-
-/* jshint quotmark: double */
-window.SwaggerTranslator.learn({
- "Warning: Deprecated":"警告: 廃止予定",
- "Implementation Notes":"実装メモ",
- "Response Class":"レスポンスクラス",
- "Status":"ステータス",
- "Parameters":"パラメータ群",
- "Parameter":"パラメータ",
- "Value":"値",
- "Description":"説明",
- "Parameter Type":"パラメータタイプ",
- "Data Type":"データタイプ",
- "Response Messages":"レスポンスメッセージ",
- "HTTP Status Code":"HTTPステータスコード",
- "Reason":"理由",
- "Response Model":"レスポンスモデル",
- "Request URL":"リクエストURL",
- "Response Body":"レスポンスボディ",
- "Response Code":"レスポンスコード",
- "Response Headers":"レスポンスヘッダ",
- "Hide Response":"レスポンスを隠す",
- "Headers":"ヘッダ",
- "Try it out!":"実際に実行!",
- "Show/Hide":"表示/非表示",
- "List Operations":"操作一覧",
- "Expand Operations":"操作の展開",
- "Raw":"Raw",
- "can't parse JSON. Raw result":"JSONへ解釈できません. 未加工の結果",
- "Model Schema":"モデルスキーマ",
- "Model":"モデル",
- "apply":"実行",
- "Username":"ユーザ名",
- "Password":"パスワード",
- "Terms of service":"サービス利用規約",
- "Created by":"Created by",
- "See more at":"See more at",
- "Contact the developer":"開発者に連絡",
- "api version":"APIバージョン",
- "Response Content Type":"レスポンス コンテンツタイプ",
- "fetching resource":"リソースの取得",
- "fetching resource list":"リソース一覧の取得",
- "Explore":"Explore",
- "Show Swagger Petstore Example Apis":"SwaggerペットストアAPIの表示",
- "Can't read from server. It may not have the appropriate access-control-origin settings.":"サーバから読み込めません. 適切なaccess-control-origin設定を持っていない可能性があります.",
- "Please specify the protocol for":"プロトコルを指定してください",
- "Can't read swagger JSON from":"次からswagger JSONを読み込めません",
- "Finished Loading Resource Information. Rendering Swagger UI":"リソース情報の読み込みが完了しました. Swagger UIを描画しています",
- "Unable to read api":"APIを読み込めません",
- "from path":"次のパスから",
- "server returned":"サーバからの返答"
-});
+'use strict';
+
+/* jshint quotmark: double */
+window.SwaggerTranslator.learn({
+ "Warning: Deprecated":"警告: 廃止予定",
+ "Implementation Notes":"実装メモ",
+ "Response Class":"レスポンスクラス",
+ "Status":"ステータス",
+ "Parameters":"パラメータ群",
+ "Parameter":"パラメータ",
+ "Value":"値",
+ "Description":"説明",
+ "Parameter Type":"パラメータタイプ",
+ "Data Type":"データタイプ",
+ "Response Messages":"レスポンスメッセージ",
+ "HTTP Status Code":"HTTPステータスコード",
+ "Reason":"理由",
+ "Response Model":"レスポンスモデル",
+ "Request URL":"リクエストURL",
+ "Response Body":"レスポンスボディ",
+ "Response Code":"レスポンスコード",
+ "Response Headers":"レスポンスヘッダ",
+ "Hide Response":"レスポンスを隠す",
+ "Headers":"ヘッダ",
+ "Try it out!":"実際に実行!",
+ "Show/Hide":"表示/非表示",
+ "List Operations":"操作一覧",
+ "Expand Operations":"操作の展開",
+ "Raw":"Raw",
+ "can't parse JSON. Raw result":"JSONへ解釈できません. 未加工の結果",
+ "Model Schema":"モデルスキーマ",
+ "Model":"モデル",
+ "apply":"実行",
+ "Username":"ユーザ名",
+ "Password":"パスワード",
+ "Terms of service":"サービス利用規約",
+ "Created by":"Created by",
+ "See more at":"See more at",
+ "Contact the developer":"開発者に連絡",
+ "api version":"APIバージョン",
+ "Response Content Type":"レスポンス コンテンツタイプ",
+ "fetching resource":"リソースの取得",
+ "fetching resource list":"リソース一覧の取得",
+ "Explore":"Explore",
+ "Show Swagger Petstore Example Apis":"SwaggerペットストアAPIの表示",
+ "Can't read from server. It may not have the appropriate access-control-origin settings.":"サーバから読み込めません. 適切なaccess-control-origin設定を持っていない可能性があります.",
+ "Please specify the protocol for":"プロトコルを指定してください",
+ "Can't read swagger JSON from":"次からswagger JSONを読み込めません",
+ "Finished Loading Resource Information. Rendering Swagger UI":"リソース情報の読み込みが完了しました. Swagger UIを描画しています",
+ "Unable to read api":"APIを読み込めません",
+ "from path":"次のパスから",
+ "server returned":"サーバからの返答"
+});
diff --git a/ydb/core/viewer/content/api/lang/ko-kr.js b/ydb/core/viewer/content/api/lang/ko-kr.js
index 93a9b531bff..03c7626d7f9 100644
--- a/ydb/core/viewer/content/api/lang/ko-kr.js
+++ b/ydb/core/viewer/content/api/lang/ko-kr.js
@@ -1,53 +1,53 @@
-'use strict';
-
-/* jshint quotmark: double */
-window.SwaggerTranslator.learn({
- "Warning: Deprecated":"경고:폐기예정됨",
- "Implementation Notes":"구현 노트",
- "Response Class":"응답 클래스",
- "Status":"상태",
- "Parameters":"매개변수들",
- "Parameter":"매개변수",
- "Value":"값",
- "Description":"설명",
- "Parameter Type":"매개변수 타입",
- "Data Type":"데이터 타입",
- "Response Messages":"응답 메세지",
- "HTTP Status Code":"HTTP 상태 코드",
- "Reason":"원인",
- "Response Model":"응답 모델",
- "Request URL":"요청 URL",
- "Response Body":"응답 본문",
- "Response Code":"응답 코드",
- "Response Headers":"응답 헤더",
- "Hide Response":"응답 숨기기",
- "Headers":"헤더",
- "Try it out!":"써보기!",
- "Show/Hide":"보이기/숨기기",
- "List Operations":"목록 작업",
- "Expand Operations":"전개 작업",
- "Raw":"원본",
- "can't parse JSON. Raw result":"JSON을 파싱할수 없음. 원본결과:",
- "Model Schema":"모델 스키마",
- "Model":"모델",
- "apply":"적용",
- "Username":"사용자 이름",
- "Password":"암호",
- "Terms of service":"이용약관",
- "Created by":"작성자",
- "See more at":"추가정보:",
- "Contact the developer":"개발자에게 문의",
- "api version":"api버전",
- "Response Content Type":"응답Content Type",
- "fetching resource":"리소스 가져오기",
- "fetching resource list":"리소스 목록 가져오기",
- "Explore":"탐색",
- "Show Swagger Petstore Example Apis":"Swagger Petstore 예제 보기",
- "Can't read from server. It may not have the appropriate access-control-origin settings.":"서버로부터 읽어들일수 없습니다. access-control-origin 설정이 올바르지 않을수 있습니다.",
- "Please specify the protocol for":"다음을 위한 프로토콜을 정하세요",
- "Can't read swagger JSON from":"swagger JSON 을 다음으로 부터 읽을수 없습니다",
- "Finished Loading Resource Information. Rendering Swagger UI":"리소스 정보 불러오기 완료. Swagger UI 랜더링",
- "Unable to read api":"api를 읽을 수 없습니다.",
- "from path":"다음 경로로 부터",
- "server returned":"서버 응답함."
-});
+'use strict';
+
+/* jshint quotmark: double */
+window.SwaggerTranslator.learn({
+ "Warning: Deprecated":"경고:폐기예정됨",
+ "Implementation Notes":"구현 노트",
+ "Response Class":"응답 클래스",
+ "Status":"상태",
+ "Parameters":"매개변수들",
+ "Parameter":"매개변수",
+ "Value":"값",
+ "Description":"설명",
+ "Parameter Type":"매개변수 타입",
+ "Data Type":"데이터 타입",
+ "Response Messages":"응답 메세지",
+ "HTTP Status Code":"HTTP 상태 코드",
+ "Reason":"원인",
+ "Response Model":"응답 모델",
+ "Request URL":"요청 URL",
+ "Response Body":"응답 본문",
+ "Response Code":"응답 코드",
+ "Response Headers":"응답 헤더",
+ "Hide Response":"응답 숨기기",
+ "Headers":"헤더",
+ "Try it out!":"써보기!",
+ "Show/Hide":"보이기/숨기기",
+ "List Operations":"목록 작업",
+ "Expand Operations":"전개 작업",
+ "Raw":"원본",
+ "can't parse JSON. Raw result":"JSON을 파싱할수 없음. 원본결과:",
+ "Model Schema":"모델 스키마",
+ "Model":"모델",
+ "apply":"적용",
+ "Username":"사용자 이름",
+ "Password":"암호",
+ "Terms of service":"이용약관",
+ "Created by":"작성자",
+ "See more at":"추가정보:",
+ "Contact the developer":"개발자에게 문의",
+ "api version":"api버전",
+ "Response Content Type":"응답Content Type",
+ "fetching resource":"리소스 가져오기",
+ "fetching resource list":"리소스 목록 가져오기",
+ "Explore":"탐색",
+ "Show Swagger Petstore Example Apis":"Swagger Petstore 예제 보기",
+ "Can't read from server. It may not have the appropriate access-control-origin settings.":"서버로부터 읽어들일수 없습니다. access-control-origin 설정이 올바르지 않을수 있습니다.",
+ "Please specify the protocol for":"다음을 위한 프로토콜을 정하세요",
+ "Can't read swagger JSON from":"swagger JSON 을 다음으로 부터 읽을수 없습니다",
+ "Finished Loading Resource Information. Rendering Swagger UI":"리소스 정보 불러오기 완료. Swagger UI 랜더링",
+ "Unable to read api":"api를 읽을 수 없습니다.",
+ "from path":"다음 경로로 부터",
+ "server returned":"서버 응답함."
+});
diff --git a/ydb/core/viewer/content/api/lang/pl.js b/ydb/core/viewer/content/api/lang/pl.js
index 54901dc4952..ce41e91799d 100644
--- a/ydb/core/viewer/content/api/lang/pl.js
+++ b/ydb/core/viewer/content/api/lang/pl.js
@@ -1,53 +1,53 @@
-'use strict';
-
-/* jshint quotmark: double */
-window.SwaggerTranslator.learn({
- "Warning: Deprecated":"Uwaga: Wycofane",
- "Implementation Notes":"Uwagi Implementacji",
- "Response Class":"Klasa Odpowiedzi",
- "Status":"Status",
- "Parameters":"Parametry",
- "Parameter":"Parametr",
- "Value":"Wartość",
- "Description":"Opis",
- "Parameter Type":"Typ Parametru",
- "Data Type":"Typ Danych",
- "Response Messages":"Wiadomości Odpowiedzi",
- "HTTP Status Code":"Kod Statusu HTTP",
- "Reason":"Przyczyna",
- "Response Model":"Model Odpowiedzi",
- "Request URL":"URL Wywołania",
- "Response Body":"Treść Odpowiedzi",
- "Response Code":"Kod Odpowiedzi",
- "Response Headers":"Nagłówki Odpowiedzi",
- "Hide Response":"Ukryj Odpowiedź",
- "Headers":"Nagłówki",
- "Try it out!":"Wypróbuj!",
- "Show/Hide":"Pokaż/Ukryj",
- "List Operations":"Lista Operacji",
- "Expand Operations":"Rozwiń Operacje",
- "Raw":"Nieprzetworzone",
- "can't parse JSON. Raw result":"nie można przetworzyć pliku JSON. Nieprzetworzone dane",
- "Model Schema":"Schemat Modelu",
- "Model":"Model",
- "apply":"użyj",
- "Username":"Nazwa użytkownika",
- "Password":"Hasło",
- "Terms of service":"Warunki używania",
- "Created by":"Utworzone przez",
- "See more at":"Zobacz więcej na",
- "Contact the developer":"Kontakt z deweloperem",
- "api version":"wersja api",
- "Response Content Type":"Typ Zasobu Odpowiedzi",
- "fetching resource":"ładowanie zasobu",
- "fetching resource list":"ładowanie listy zasobów",
- "Explore":"Eksploruj",
- "Show Swagger Petstore Example Apis":"Pokaż Przykładowe Api Swagger Petstore",
- "Can't read from server. It may not have the appropriate access-control-origin settings.":"Brak połączenia z serwerem. Może on nie mieć odpowiednich ustawień access-control-origin.",
- "Please specify the protocol for":"Proszę podać protokół dla",
- "Can't read swagger JSON from":"Nie można odczytać swagger JSON z",
- "Finished Loading Resource Information. Rendering Swagger UI":"Ukończono Ładowanie Informacji o Zasobie. Renderowanie Swagger UI",
- "Unable to read api":"Nie można odczytać api",
- "from path":"ze ścieżki",
- "server returned":"serwer zwrócił"
-});
+'use strict';
+
+/* jshint quotmark: double */
+window.SwaggerTranslator.learn({
+ "Warning: Deprecated":"Uwaga: Wycofane",
+ "Implementation Notes":"Uwagi Implementacji",
+ "Response Class":"Klasa Odpowiedzi",
+ "Status":"Status",
+ "Parameters":"Parametry",
+ "Parameter":"Parametr",
+ "Value":"Wartość",
+ "Description":"Opis",
+ "Parameter Type":"Typ Parametru",
+ "Data Type":"Typ Danych",
+ "Response Messages":"Wiadomości Odpowiedzi",
+ "HTTP Status Code":"Kod Statusu HTTP",
+ "Reason":"Przyczyna",
+ "Response Model":"Model Odpowiedzi",
+ "Request URL":"URL Wywołania",
+ "Response Body":"Treść Odpowiedzi",
+ "Response Code":"Kod Odpowiedzi",
+ "Response Headers":"Nagłówki Odpowiedzi",
+ "Hide Response":"Ukryj Odpowiedź",
+ "Headers":"Nagłówki",
+ "Try it out!":"Wypróbuj!",
+ "Show/Hide":"Pokaż/Ukryj",
+ "List Operations":"Lista Operacji",
+ "Expand Operations":"Rozwiń Operacje",
+ "Raw":"Nieprzetworzone",
+ "can't parse JSON. Raw result":"nie można przetworzyć pliku JSON. Nieprzetworzone dane",
+ "Model Schema":"Schemat Modelu",
+ "Model":"Model",
+ "apply":"użyj",
+ "Username":"Nazwa użytkownika",
+ "Password":"Hasło",
+ "Terms of service":"Warunki używania",
+ "Created by":"Utworzone przez",
+ "See more at":"Zobacz więcej na",
+ "Contact the developer":"Kontakt z deweloperem",
+ "api version":"wersja api",
+ "Response Content Type":"Typ Zasobu Odpowiedzi",
+ "fetching resource":"ładowanie zasobu",
+ "fetching resource list":"ładowanie listy zasobów",
+ "Explore":"Eksploruj",
+ "Show Swagger Petstore Example Apis":"Pokaż Przykładowe Api Swagger Petstore",
+ "Can't read from server. It may not have the appropriate access-control-origin settings.":"Brak połączenia z serwerem. Może on nie mieć odpowiednich ustawień access-control-origin.",
+ "Please specify the protocol for":"Proszę podać protokół dla",
+ "Can't read swagger JSON from":"Nie można odczytać swagger JSON z",
+ "Finished Loading Resource Information. Rendering Swagger UI":"Ukończono Ładowanie Informacji o Zasobie. Renderowanie Swagger UI",
+ "Unable to read api":"Nie można odczytać api",
+ "from path":"ze ścieżki",
+ "server returned":"serwer zwrócił"
+});
diff --git a/ydb/core/viewer/content/api/lang/pt.js b/ydb/core/viewer/content/api/lang/pt.js
index 0406ce2dec5..f2e7c13d413 100644
--- a/ydb/core/viewer/content/api/lang/pt.js
+++ b/ydb/core/viewer/content/api/lang/pt.js
@@ -1,53 +1,53 @@
-'use strict';
-
-/* jshint quotmark: double */
-window.SwaggerTranslator.learn({
- "Warning: Deprecated":"Aviso: Depreciado",
- "Implementation Notes":"Notas de Implementação",
- "Response Class":"Classe de resposta",
- "Status":"Status",
- "Parameters":"Parâmetros",
- "Parameter":"Parâmetro",
- "Value":"Valor",
- "Description":"Descrição",
- "Parameter Type":"Tipo de parâmetro",
- "Data Type":"Tipo de dados",
- "Response Messages":"Mensagens de resposta",
- "HTTP Status Code":"Código de status HTTP",
- "Reason":"Razão",
- "Response Model":"Modelo resposta",
- "Request URL":"URL requisição",
- "Response Body":"Corpo da resposta",
- "Response Code":"Código da resposta",
- "Response Headers":"Cabeçalho da resposta",
- "Headers":"Cabeçalhos",
- "Hide Response":"Esconder resposta",
- "Try it out!":"Tente agora!",
- "Show/Hide":"Mostrar/Esconder",
- "List Operations":"Listar operações",
- "Expand Operations":"Expandir operações",
- "Raw":"Cru",
- "can't parse JSON. Raw result":"Falha ao analisar JSON. Resulto cru",
- "Model Schema":"Modelo esquema",
- "Model":"Modelo",
- "apply":"Aplicar",
- "Username":"Usuário",
- "Password":"Senha",
- "Terms of service":"Termos do serviço",
- "Created by":"Criado por",
- "See more at":"Veja mais em",
- "Contact the developer":"Contate o desenvolvedor",
- "api version":"Versão api",
- "Response Content Type":"Tipo de conteúdo da resposta",
- "fetching resource":"busca recurso",
- "fetching resource list":"buscando lista de recursos",
- "Explore":"Explorar",
- "Show Swagger Petstore Example Apis":"Show Swagger Petstore Example Apis",
- "Can't read from server. It may not have the appropriate access-control-origin settings.":"Não é possível ler do servidor. Pode não ter as apropriadas configurações access-control-origin",
- "Please specify the protocol for":"Por favor especifique o protocolo",
- "Can't read swagger JSON from":"Não é possível ler o JSON Swagger de",
- "Finished Loading Resource Information. Rendering Swagger UI":"Carregar informação de recurso finalizada. Renderizando Swagger UI",
- "Unable to read api":"Não foi possível ler api",
- "from path":"do caminho",
- "server returned":"servidor retornou"
-});
+'use strict';
+
+/* jshint quotmark: double */
+window.SwaggerTranslator.learn({
+ "Warning: Deprecated":"Aviso: Depreciado",
+ "Implementation Notes":"Notas de Implementação",
+ "Response Class":"Classe de resposta",
+ "Status":"Status",
+ "Parameters":"Parâmetros",
+ "Parameter":"Parâmetro",
+ "Value":"Valor",
+ "Description":"Descrição",
+ "Parameter Type":"Tipo de parâmetro",
+ "Data Type":"Tipo de dados",
+ "Response Messages":"Mensagens de resposta",
+ "HTTP Status Code":"Código de status HTTP",
+ "Reason":"Razão",
+ "Response Model":"Modelo resposta",
+ "Request URL":"URL requisição",
+ "Response Body":"Corpo da resposta",
+ "Response Code":"Código da resposta",
+ "Response Headers":"Cabeçalho da resposta",
+ "Headers":"Cabeçalhos",
+ "Hide Response":"Esconder resposta",
+ "Try it out!":"Tente agora!",
+ "Show/Hide":"Mostrar/Esconder",
+ "List Operations":"Listar operações",
+ "Expand Operations":"Expandir operações",
+ "Raw":"Cru",
+ "can't parse JSON. Raw result":"Falha ao analisar JSON. Resulto cru",
+ "Model Schema":"Modelo esquema",
+ "Model":"Modelo",
+ "apply":"Aplicar",
+ "Username":"Usuário",
+ "Password":"Senha",
+ "Terms of service":"Termos do serviço",
+ "Created by":"Criado por",
+ "See more at":"Veja mais em",
+ "Contact the developer":"Contate o desenvolvedor",
+ "api version":"Versão api",
+ "Response Content Type":"Tipo de conteúdo da resposta",
+ "fetching resource":"busca recurso",
+ "fetching resource list":"buscando lista de recursos",
+ "Explore":"Explorar",
+ "Show Swagger Petstore Example Apis":"Show Swagger Petstore Example Apis",
+ "Can't read from server. It may not have the appropriate access-control-origin settings.":"Não é possível ler do servidor. Pode não ter as apropriadas configurações access-control-origin",
+ "Please specify the protocol for":"Por favor especifique o protocolo",
+ "Can't read swagger JSON from":"Não é possível ler o JSON Swagger de",
+ "Finished Loading Resource Information. Rendering Swagger UI":"Carregar informação de recurso finalizada. Renderizando Swagger UI",
+ "Unable to read api":"Não foi possível ler api",
+ "from path":"do caminho",
+ "server returned":"servidor retornou"
+});
diff --git a/ydb/core/viewer/content/api/lang/ru.js b/ydb/core/viewer/content/api/lang/ru.js
index 80492b64778..592744e957f 100644
--- a/ydb/core/viewer/content/api/lang/ru.js
+++ b/ydb/core/viewer/content/api/lang/ru.js
@@ -1,56 +1,56 @@
-'use strict';
-
-/* jshint quotmark: double */
-window.SwaggerTranslator.learn({
- "Warning: Deprecated":"Предупреждение: Устарело",
- "Implementation Notes":"Заметки",
- "Response Class":"Пример ответа",
- "Status":"Статус",
- "Parameters":"Параметры",
- "Parameter":"Параметр",
- "Value":"Значение",
- "Description":"Описание",
- "Parameter Type":"Тип параметра",
- "Data Type":"Тип данных",
- "HTTP Status Code":"HTTP код",
- "Reason":"Причина",
- "Response Model":"Структура ответа",
- "Request URL":"URL запроса",
- "Response Body":"Тело ответа",
- "Response Code":"HTTP код ответа",
- "Response Headers":"Заголовки ответа",
- "Hide Response":"Спрятать ответ",
- "Headers":"Заголовки",
- "Response Messages":"Что может прийти в ответ",
- "Try it out!":"Попробовать!",
- "Show/Hide":"Показать/Скрыть",
- "List Operations":"Операции кратко",
- "Expand Operations":"Операции подробно",
- "Raw":"В сыром виде",
- "can't parse JSON. Raw result":"Не удается распарсить ответ:",
- "Example Value":"Пример",
- "Model Schema":"Структура",
- "Model":"Описание",
- "Click to set as parameter value":"Нажмите, чтобы испльзовать в качестве значения параметра",
- "apply":"применить",
- "Username":"Имя пользователя",
- "Password":"Пароль",
- "Terms of service":"Условия использования",
- "Created by":"Разработано",
- "See more at":"Еще тут",
- "Contact the developer":"Связаться с разработчиком",
- "api version":"Версия API",
- "Response Content Type":"Content Type ответа",
- "Parameter content type:":"Content Type параметра:",
- "fetching resource":"Получение ресурса",
- "fetching resource list":"Получение ресурсов",
- "Explore":"Показать",
- "Show Swagger Petstore Example Apis":"Показать примеры АПИ",
- "Can't read from server. It may not have the appropriate access-control-origin settings.":"Не удается получить ответ от сервера. Возможно, проблема с настройками доступа",
- "Please specify the protocol for":"Пожалуйста, укажите протокол для",
- "Can't read swagger JSON from":"Не получается прочитать swagger json из",
- "Finished Loading Resource Information. Rendering Swagger UI":"Загрузка информации о ресурсах завершена. Рендерим",
- "Unable to read api":"Не удалось прочитать api",
- "from path":"по адресу",
- "server returned":"сервер сказал"
-});
+'use strict';
+
+/* jshint quotmark: double */
+window.SwaggerTranslator.learn({
+ "Warning: Deprecated":"Предупреждение: Устарело",
+ "Implementation Notes":"Заметки",
+ "Response Class":"Пример ответа",
+ "Status":"Статус",
+ "Parameters":"Параметры",
+ "Parameter":"Параметр",
+ "Value":"Значение",
+ "Description":"Описание",
+ "Parameter Type":"Тип параметра",
+ "Data Type":"Тип данных",
+ "HTTP Status Code":"HTTP код",
+ "Reason":"Причина",
+ "Response Model":"Структура ответа",
+ "Request URL":"URL запроса",
+ "Response Body":"Тело ответа",
+ "Response Code":"HTTP код ответа",
+ "Response Headers":"Заголовки ответа",
+ "Hide Response":"Спрятать ответ",
+ "Headers":"Заголовки",
+ "Response Messages":"Что может прийти в ответ",
+ "Try it out!":"Попробовать!",
+ "Show/Hide":"Показать/Скрыть",
+ "List Operations":"Операции кратко",
+ "Expand Operations":"Операции подробно",
+ "Raw":"В сыром виде",
+ "can't parse JSON. Raw result":"Не удается распарсить ответ:",
+ "Example Value":"Пример",
+ "Model Schema":"Структура",
+ "Model":"Описание",
+ "Click to set as parameter value":"Нажмите, чтобы испльзовать в качестве значения параметра",
+ "apply":"применить",
+ "Username":"Имя пользователя",
+ "Password":"Пароль",
+ "Terms of service":"Условия использования",
+ "Created by":"Разработано",
+ "See more at":"Еще тут",
+ "Contact the developer":"Связаться с разработчиком",
+ "api version":"Версия API",
+ "Response Content Type":"Content Type ответа",
+ "Parameter content type:":"Content Type параметра:",
+ "fetching resource":"Получение ресурса",
+ "fetching resource list":"Получение ресурсов",
+ "Explore":"Показать",
+ "Show Swagger Petstore Example Apis":"Показать примеры АПИ",
+ "Can't read from server. It may not have the appropriate access-control-origin settings.":"Не удается получить ответ от сервера. Возможно, проблема с настройками доступа",
+ "Please specify the protocol for":"Пожалуйста, укажите протокол для",
+ "Can't read swagger JSON from":"Не получается прочитать swagger json из",
+ "Finished Loading Resource Information. Rendering Swagger UI":"Загрузка информации о ресурсах завершена. Рендерим",
+ "Unable to read api":"Не удалось прочитать api",
+ "from path":"по адресу",
+ "server returned":"сервер сказал"
+});
diff --git a/ydb/core/viewer/content/api/lang/tr.js b/ydb/core/viewer/content/api/lang/tr.js
index 117fbd5afbb..16426a9c34b 100644
--- a/ydb/core/viewer/content/api/lang/tr.js
+++ b/ydb/core/viewer/content/api/lang/tr.js
@@ -1,53 +1,53 @@
-'use strict';
-
-/* jshint quotmark: double */
-window.SwaggerTranslator.learn({
- "Warning: Deprecated":"Uyarı: Deprecated",
- "Implementation Notes":"Gerçekleştirim Notları",
- "Response Class":"Dönen Sınıf",
- "Status":"Statü",
- "Parameters":"Parametreler",
- "Parameter":"Parametre",
- "Value":"Değer",
- "Description":"Açıklama",
- "Parameter Type":"Parametre Tipi",
- "Data Type":"Veri Tipi",
- "Response Messages":"Dönüş Mesajı",
- "HTTP Status Code":"HTTP Statü Kodu",
- "Reason":"Gerekçe",
- "Response Model":"Dönüş Modeli",
- "Request URL":"İstek URL",
- "Response Body":"Dönüş İçeriği",
- "Response Code":"Dönüş Kodu",
- "Response Headers":"Dönüş Üst Bilgileri",
- "Hide Response":"Dönüşü Gizle",
- "Headers":"Üst Bilgiler",
- "Try it out!":"Dene!",
- "Show/Hide":"Göster/Gizle",
- "List Operations":"Operasyonları Listele",
- "Expand Operations":"Operasyonları Aç",
- "Raw":"Ham",
- "can't parse JSON. Raw result":"JSON çözümlenemiyor. Ham sonuç",
- "Model Schema":"Model Şema",
- "Model":"Model",
- "apply":"uygula",
- "Username":"Kullanıcı Adı",
- "Password":"Parola",
- "Terms of service":"Servis şartları",
- "Created by":"Oluşturan",
- "See more at":"Daha fazlası için",
- "Contact the developer":"Geliştirici ile İletişime Geçin",
- "api version":"api versiyon",
- "Response Content Type":"Dönüş İçerik Tipi",
- "fetching resource":"kaynak getiriliyor",
- "fetching resource list":"kaynak listesi getiriliyor",
- "Explore":"Keşfet",
- "Show Swagger Petstore Example Apis":"Swagger Petstore Örnek Api'yi Gör",
- "Can't read from server. It may not have the appropriate access-control-origin settings.":"Sunucudan okuma yapılamıyor. Sunucu access-control-origin ayarlarınızı kontrol edin.",
- "Please specify the protocol for":"Lütfen istenen adres için protokol belirtiniz",
- "Can't read swagger JSON from":"Swagger JSON bu kaynaktan okunamıyor",
- "Finished Loading Resource Information. Rendering Swagger UI":"Kaynak baglantısı tamamlandı. Swagger UI gösterime hazırlanıyor",
- "Unable to read api":"api okunamadı",
- "from path":"yoldan",
- "server returned":"sunucuya dönüldü"
-});
+'use strict';
+
+/* jshint quotmark: double */
+window.SwaggerTranslator.learn({
+ "Warning: Deprecated":"Uyarı: Deprecated",
+ "Implementation Notes":"Gerçekleştirim Notları",
+ "Response Class":"Dönen Sınıf",
+ "Status":"Statü",
+ "Parameters":"Parametreler",
+ "Parameter":"Parametre",
+ "Value":"Değer",
+ "Description":"Açıklama",
+ "Parameter Type":"Parametre Tipi",
+ "Data Type":"Veri Tipi",
+ "Response Messages":"Dönüş Mesajı",
+ "HTTP Status Code":"HTTP Statü Kodu",
+ "Reason":"Gerekçe",
+ "Response Model":"Dönüş Modeli",
+ "Request URL":"İstek URL",
+ "Response Body":"Dönüş İçeriği",
+ "Response Code":"Dönüş Kodu",
+ "Response Headers":"Dönüş Üst Bilgileri",
+ "Hide Response":"Dönüşü Gizle",
+ "Headers":"Üst Bilgiler",
+ "Try it out!":"Dene!",
+ "Show/Hide":"Göster/Gizle",
+ "List Operations":"Operasyonları Listele",
+ "Expand Operations":"Operasyonları Aç",
+ "Raw":"Ham",
+ "can't parse JSON. Raw result":"JSON çözümlenemiyor. Ham sonuç",
+ "Model Schema":"Model Şema",
+ "Model":"Model",
+ "apply":"uygula",
+ "Username":"Kullanıcı Adı",
+ "Password":"Parola",
+ "Terms of service":"Servis şartları",
+ "Created by":"Oluşturan",
+ "See more at":"Daha fazlası için",
+ "Contact the developer":"Geliştirici ile İletişime Geçin",
+ "api version":"api versiyon",
+ "Response Content Type":"Dönüş İçerik Tipi",
+ "fetching resource":"kaynak getiriliyor",
+ "fetching resource list":"kaynak listesi getiriliyor",
+ "Explore":"Keşfet",
+ "Show Swagger Petstore Example Apis":"Swagger Petstore Örnek Api'yi Gör",
+ "Can't read from server. It may not have the appropriate access-control-origin settings.":"Sunucudan okuma yapılamıyor. Sunucu access-control-origin ayarlarınızı kontrol edin.",
+ "Please specify the protocol for":"Lütfen istenen adres için protokol belirtiniz",
+ "Can't read swagger JSON from":"Swagger JSON bu kaynaktan okunamıyor",
+ "Finished Loading Resource Information. Rendering Swagger UI":"Kaynak baglantısı tamamlandı. Swagger UI gösterime hazırlanıyor",
+ "Unable to read api":"api okunamadı",
+ "from path":"yoldan",
+ "server returned":"sunucuya dönüldü"
+});
diff --git a/ydb/core/viewer/content/api/lang/translator.js b/ydb/core/viewer/content/api/lang/translator.js
index 1f1fa4a3015..ffb879f9a27 100644
--- a/ydb/core/viewer/content/api/lang/translator.js
+++ b/ydb/core/viewer/content/api/lang/translator.js
@@ -1,39 +1,39 @@
-'use strict';
-
-/**
- * Translator for documentation pages.
- *
- * To enable translation you should include one of language-files in your index.html
- * after <script src='lang/translator.js' type='text/javascript'></script>.
- * For example - <script src='lang/ru.js' type='text/javascript'></script>
- *
- * If you wish to translate some new texts you should do two things:
- * 1. Add a new phrase pair ("New Phrase": "New Translation") into your language file (for example lang/ru.js). It will be great if you add it in other language files too.
- * 2. Mark that text it templates this way <anyHtmlTag data-sw-translate>New Phrase</anyHtmlTag> or <anyHtmlTag data-sw-translate value='New Phrase'/>.
- * The main thing here is attribute data-sw-translate. Only inner html, title-attribute and value-attribute are going to translate.
- *
- */
-window.SwaggerTranslator = {
-
- _words:[],
-
- translate: function(sel) {
- var $this = this;
- sel = sel || '[data-sw-translate]';
-
- $(sel).each(function() {
- $(this).html($this._tryTranslate($(this).html()));
-
- $(this).val($this._tryTranslate($(this).val()));
- $(this).attr('title', $this._tryTranslate($(this).attr('title')));
- });
- },
-
- _tryTranslate: function(word) {
- return this._words[$.trim(word)] !== undefined ? this._words[$.trim(word)] : word;
- },
-
- learn: function(wordsMap) {
- this._words = wordsMap;
- }
-};
+'use strict';
+
+/**
+ * Translator for documentation pages.
+ *
+ * To enable translation you should include one of language-files in your index.html
+ * after <script src='lang/translator.js' type='text/javascript'></script>.
+ * For example - <script src='lang/ru.js' type='text/javascript'></script>
+ *
+ * If you wish to translate some new texts you should do two things:
+ * 1. Add a new phrase pair ("New Phrase": "New Translation") into your language file (for example lang/ru.js). It will be great if you add it in other language files too.
+ * 2. Mark that text it templates this way <anyHtmlTag data-sw-translate>New Phrase</anyHtmlTag> or <anyHtmlTag data-sw-translate value='New Phrase'/>.
+ * The main thing here is attribute data-sw-translate. Only inner html, title-attribute and value-attribute are going to translate.
+ *
+ */
+window.SwaggerTranslator = {
+
+ _words:[],
+
+ translate: function(sel) {
+ var $this = this;
+ sel = sel || '[data-sw-translate]';
+
+ $(sel).each(function() {
+ $(this).html($this._tryTranslate($(this).html()));
+
+ $(this).val($this._tryTranslate($(this).val()));
+ $(this).attr('title', $this._tryTranslate($(this).attr('title')));
+ });
+ },
+
+ _tryTranslate: function(word) {
+ return this._words[$.trim(word)] !== undefined ? this._words[$.trim(word)] : word;
+ },
+
+ learn: function(wordsMap) {
+ this._words = wordsMap;
+ }
+};
diff --git a/ydb/core/viewer/content/api/lang/zh-cn.js b/ydb/core/viewer/content/api/lang/zh-cn.js
index 571ff5c8dd1..570319ba156 100644
--- a/ydb/core/viewer/content/api/lang/zh-cn.js
+++ b/ydb/core/viewer/content/api/lang/zh-cn.js
@@ -1,53 +1,53 @@
-'use strict';
-
-/* jshint quotmark: double */
-window.SwaggerTranslator.learn({
- "Warning: Deprecated":"警告:已过时",
- "Implementation Notes":"实现备注",
- "Response Class":"响应类",
- "Status":"状态",
- "Parameters":"参数",
- "Parameter":"参数",
- "Value":"值",
- "Description":"描述",
- "Parameter Type":"参数类型",
- "Data Type":"数据类型",
- "Response Messages":"响应消息",
- "HTTP Status Code":"HTTP状态码",
- "Reason":"原因",
- "Response Model":"响应模型",
- "Request URL":"请求URL",
- "Response Body":"响应体",
- "Response Code":"响应码",
- "Response Headers":"响应头",
- "Hide Response":"隐藏响应",
- "Headers":"头",
- "Try it out!":"试一下!",
- "Show/Hide":"显示/隐藏",
- "List Operations":"显示操作",
- "Expand Operations":"展开操作",
- "Raw":"原始",
- "can't parse JSON. Raw result":"无法解析JSON. 原始结果",
- "Model Schema":"模型架构",
- "Model":"模型",
- "apply":"应用",
- "Username":"用户名",
- "Password":"密码",
- "Terms of service":"服务条款",
- "Created by":"创建者",
- "See more at":"查看更多:",
- "Contact the developer":"联系开发者",
- "api version":"api版本",
- "Response Content Type":"响应Content Type",
- "fetching resource":"正在获取资源",
- "fetching resource list":"正在获取资源列表",
- "Explore":"浏览",
- "Show Swagger Petstore Example Apis":"显示 Swagger Petstore 示例 Apis",
- "Can't read from server. It may not have the appropriate access-control-origin settings.":"无法从服务器读取。可能没有正确设置access-control-origin。",
- "Please specify the protocol for":"请指定协议:",
- "Can't read swagger JSON from":"无法读取swagger JSON于",
- "Finished Loading Resource Information. Rendering Swagger UI":"已加载资源信息。正在渲染Swagger UI",
- "Unable to read api":"无法读取api",
- "from path":"从路径",
- "server returned":"服务器返回"
-});
+'use strict';
+
+/* jshint quotmark: double */
+window.SwaggerTranslator.learn({
+ "Warning: Deprecated":"警告:已过时",
+ "Implementation Notes":"实现备注",
+ "Response Class":"响应类",
+ "Status":"状态",
+ "Parameters":"参数",
+ "Parameter":"参数",
+ "Value":"值",
+ "Description":"描述",
+ "Parameter Type":"参数类型",
+ "Data Type":"数据类型",
+ "Response Messages":"响应消息",
+ "HTTP Status Code":"HTTP状态码",
+ "Reason":"原因",
+ "Response Model":"响应模型",
+ "Request URL":"请求URL",
+ "Response Body":"响应体",
+ "Response Code":"响应码",
+ "Response Headers":"响应头",
+ "Hide Response":"隐藏响应",
+ "Headers":"头",
+ "Try it out!":"试一下!",
+ "Show/Hide":"显示/隐藏",
+ "List Operations":"显示操作",
+ "Expand Operations":"展开操作",
+ "Raw":"原始",
+ "can't parse JSON. Raw result":"无法解析JSON. 原始结果",
+ "Model Schema":"模型架构",
+ "Model":"模型",
+ "apply":"应用",
+ "Username":"用户名",
+ "Password":"密码",
+ "Terms of service":"服务条款",
+ "Created by":"创建者",
+ "See more at":"查看更多:",
+ "Contact the developer":"联系开发者",
+ "api version":"api版本",
+ "Response Content Type":"响应Content Type",
+ "fetching resource":"正在获取资源",
+ "fetching resource list":"正在获取资源列表",
+ "Explore":"浏览",
+ "Show Swagger Petstore Example Apis":"显示 Swagger Petstore 示例 Apis",
+ "Can't read from server. It may not have the appropriate access-control-origin settings.":"无法从服务器读取。可能没有正确设置access-control-origin。",
+ "Please specify the protocol for":"请指定协议:",
+ "Can't read swagger JSON from":"无法读取swagger JSON于",
+ "Finished Loading Resource Information. Rendering Swagger UI":"已加载资源信息。正在渲染Swagger UI",
+ "Unable to read api":"无法读取api",
+ "from path":"从路径",
+ "server returned":"服务器返回"
+});
diff --git a/ydb/core/viewer/content/api/lib/backbone-min.js b/ydb/core/viewer/content/api/lib/backbone-min.js
index ca676852e35..a3f544be6d9 100644
--- a/ydb/core/viewer/content/api/lib/backbone-min.js
+++ b/ydb/core/viewer/content/api/lib/backbone-min.js
@@ -1,15 +1,15 @@
-// Backbone.js 1.1.2
-
-(function(t,e){if(typeof define==="function"&&define.amd){define(["underscore","jquery","exports"],function(i,r,s){t.Backbone=e(t,s,i,r)})}else if(typeof exports!=="undefined"){var i=require("underscore");e(t,exports,i)}else{t.Backbone=e(t,{},t._,t.jQuery||t.Zepto||t.ender||t.$)}})(this,function(t,e,i,r){var s=t.Backbone;var n=[];var a=n.push;var o=n.slice;var h=n.splice;e.VERSION="1.1.2";e.$=r;e.noConflict=function(){t.Backbone=s;return this};e.emulateHTTP=false;e.emulateJSON=false;var u=e.Events={on:function(t,e,i){if(!c(this,"on",t,[e,i])||!e)return this;this._events||(this._events={});var r=this._events[t]||(this._events[t]=[]);r.push({callback:e,context:i,ctx:i||this});return this},once:function(t,e,r){if(!c(this,"once",t,[e,r])||!e)return this;var s=this;var n=i.once(function(){s.off(t,n);e.apply(this,arguments)});n._callback=e;return this.on(t,n,r)},off:function(t,e,r){var s,n,a,o,h,u,l,f;if(!this._events||!c(this,"off",t,[e,r]))return this;if(!t&&!e&&!r){this._events=void 0;return this}o=t?[t]:i.keys(this._events);for(h=0,u=o.length;h<u;h++){t=o[h];if(a=this._events[t]){this._events[t]=s=[];if(e||r){for(l=0,f=a.length;l<f;l++){n=a[l];if(e&&e!==n.callback&&e!==n.callback._callback||r&&r!==n.context){s.push(n)}}}if(!s.length)delete this._events[t]}}return this},trigger:function(t){if(!this._events)return this;var e=o.call(arguments,1);if(!c(this,"trigger",t,e))return this;var i=this._events[t];var r=this._events.all;if(i)f(i,e);if(r)f(r,arguments);return this},stopListening:function(t,e,r){var s=this._listeningTo;if(!s)return this;var n=!e&&!r;if(!r&&typeof e==="object")r=this;if(t)(s={})[t._listenId]=t;for(var a in s){t=s[a];t.off(e,r,this);if(n||i.isEmpty(t._events))delete this._listeningTo[a]}return this}};var l=/\s+/;var c=function(t,e,i,r){if(!i)return true;if(typeof i==="object"){for(var s in i){t[e].apply(t,[s,i[s]].concat(r))}return false}if(l.test(i)){var n=i.split(l);for(var a=0,o=n.length;a<o;a++){t[e].apply(t,[n[a]].concat(r))}return false}return true};var f=function(t,e){var i,r=-1,s=t.length,n=e[0],a=e[1],o=e[2];switch(e.length){case 0:while(++r<s)(i=t[r]).callback.call(i.ctx);return;case 1:while(++r<s)(i=t[r]).callback.call(i.ctx,n);return;case 2:while(++r<s)(i=t[r]).callback.call(i.ctx,n,a);return;case 3:while(++r<s)(i=t[r]).callback.call(i.ctx,n,a,o);return;default:while(++r<s)(i=t[r]).callback.apply(i.ctx,e);return}};var d={listenTo:"on",listenToOnce:"once"};i.each(d,function(t,e){u[e]=function(e,r,s){var n=this._listeningTo||(this._listeningTo={});var a=e._listenId||(e._listenId=i.uniqueId("l"));n[a]=e;if(!s&&typeof r==="object")s=this;e[t](r,s,this);return this}});u.bind=u.on;u.unbind=u.off;i.extend(e,u);var p=e.Model=function(t,e){var r=t||{};e||(e={});this.cid=i.uniqueId("c");this.attributes={};if(e.collection)this.collection=e.collection;if(e.parse)r=this.parse(r,e)||{};r=i.defaults({},r,i.result(this,"defaults"));this.set(r,e);this.changed={};this.initialize.apply(this,arguments)};i.extend(p.prototype,u,{changed:null,validationError:null,idAttribute:"id",initialize:function(){},toJSON:function(t){return i.clone(this.attributes)},sync:function(){return e.sync.apply(this,arguments)},get:function(t){return this.attributes[t]},escape:function(t){return i.escape(this.get(t))},has:function(t){return this.get(t)!=null},set:function(t,e,r){var s,n,a,o,h,u,l,c;if(t==null)return this;if(typeof t==="object"){n=t;r=e}else{(n={})[t]=e}r||(r={});if(!this._validate(n,r))return false;a=r.unset;h=r.silent;o=[];u=this._changing;this._changing=true;if(!u){this._previousAttributes=i.clone(this.attributes);this.changed={}}c=this.attributes,l=this._previousAttributes;if(this.idAttribute in n)this.id=n[this.idAttribute];for(s in n){e=n[s];if(!i.isEqual(c[s],e))o.push(s);if(!i.isEqual(l[s],e)){this.changed[s]=e}else{delete this.changed[s]}a?delete c[s]:c[s]=e}if(!h){if(o.length)this._pending=r;for(var f=0,d=o.length;f<d;f++){this.trigger("change:"+o[f],this,c[o[f]],r)}}if(u)return this;if(!h){while(this._pending){r=this._pending;this._pending=false;this.trigger("change",this,r)}}this._pending=false;this._changing=false;return this},unset:function(t,e){return this.set(t,void 0,i.extend({},e,{unset:true}))},clear:function(t){var e={};for(var r in this.attributes)e[r]=void 0;return this.set(e,i.extend({},t,{unset:true}))},hasChanged:function(t){if(t==null)return!i.isEmpty(this.changed);return i.has(this.changed,t)},changedAttributes:function(t){if(!t)return this.hasChanged()?i.clone(this.changed):false;var e,r=false;var s=this._changing?this._previousAttributes:this.attributes;for(var n in t){if(i.isEqual(s[n],e=t[n]))continue;(r||(r={}))[n]=e}return r},previous:function(t){if(t==null||!this._previousAttributes)return null;return this._previousAttributes[t]},previousAttributes:function(){return i.clone(this._previousAttributes)},fetch:function(t){t=t?i.clone(t):{};if(t.parse===void 0)t.parse=true;var e=this;var r=t.success;t.success=function(i){if(!e.set(e.parse(i,t),t))return false;if(r)r(e,i,t);e.trigger("sync",e,i,t)};q(this,t);return this.sync("read",this,t)},save:function(t,e,r){var s,n,a,o=this.attributes;if(t==null||typeof t==="object"){s=t;r=e}else{(s={})[t]=e}r=i.extend({validate:true},r);if(s&&!r.wait){if(!this.set(s,r))return false}else{if(!this._validate(s,r))return false}if(s&&r.wait){this.attributes=i.extend({},o,s)}if(r.parse===void 0)r.parse=true;var h=this;var u=r.success;r.success=function(t){h.attributes=o;var e=h.parse(t,r);if(r.wait)e=i.extend(s||{},e);if(i.isObject(e)&&!h.set(e,r)){return false}if(u)u(h,t,r);h.trigger("sync",h,t,r)};q(this,r);n=this.isNew()?"create":r.patch?"patch":"update";if(n==="patch")r.attrs=s;a=this.sync(n,this,r);if(s&&r.wait)this.attributes=o;return a},destroy:function(t){t=t?i.clone(t):{};var e=this;var r=t.success;var s=function(){e.trigger("destroy",e,e.collection,t)};t.success=function(i){if(t.wait||e.isNew())s();if(r)r(e,i,t);if(!e.isNew())e.trigger("sync",e,i,t)};if(this.isNew()){t.success();return false}q(this,t);var n=this.sync("delete",this,t);if(!t.wait)s();return n},url:function(){var t=i.result(this,"urlRoot")||i.result(this.collection,"url")||M();if(this.isNew())return t;return t.replace(/([^\/])$/,"$1/")+encodeURIComponent(this.id)},parse:function(t,e){return t},clone:function(){return new this.constructor(this.attributes)},isNew:function(){return!this.has(this.idAttribute)},isValid:function(t){return this._validate({},i.extend(t||{},{validate:true}))},_validate:function(t,e){if(!e.validate||!this.validate)return true;t=i.extend({},this.attributes,t);var r=this.validationError=this.validate(t,e)||null;if(!r)return true;this.trigger("invalid",this,r,i.extend(e,{validationError:r}));return false}});var v=["keys","values","pairs","invert","pick","omit"];i.each(v,function(t){p.prototype[t]=function(){var e=o.call(arguments);e.unshift(this.attributes);return i[t].apply(i,e)}});var g=e.Collection=function(t,e){e||(e={});if(e.model)this.model=e.model;if(e.comparator!==void 0)this.comparator=e.comparator;this._reset();this.initialize.apply(this,arguments);if(t)this.reset(t,i.extend({silent:true},e))};var m={add:true,remove:true,merge:true};var y={add:true,remove:false};i.extend(g.prototype,u,{model:p,initialize:function(){},toJSON:function(t){return this.map(function(e){return e.toJSON(t)})},sync:function(){return e.sync.apply(this,arguments)},add:function(t,e){return this.set(t,i.extend({merge:false},e,y))},remove:function(t,e){var r=!i.isArray(t);t=r?[t]:i.clone(t);e||(e={});var s,n,a,o;for(s=0,n=t.length;s<n;s++){o=t[s]=this.get(t[s]);if(!o)continue;delete this._byId[o.id];delete this._byId[o.cid];a=this.indexOf(o);this.models.splice(a,1);this.length--;if(!e.silent){e.index=a;o.trigger("remove",o,this,e)}this._removeReference(o,e)}return r?t[0]:t},set:function(t,e){e=i.defaults({},e,m);if(e.parse)t=this.parse(t,e);var r=!i.isArray(t);t=r?t?[t]:[]:i.clone(t);var s,n,a,o,h,u,l;var c=e.at;var f=this.model;var d=this.comparator&&c==null&&e.sort!==false;var v=i.isString(this.comparator)?this.comparator:null;var g=[],y=[],_={};var b=e.add,w=e.merge,x=e.remove;var E=!d&&b&&x?[]:false;for(s=0,n=t.length;s<n;s++){h=t[s]||{};if(h instanceof p){a=o=h}else{a=h[f.prototype.idAttribute||"id"]}if(u=this.get(a)){if(x)_[u.cid]=true;if(w){h=h===o?o.attributes:h;if(e.parse)h=u.parse(h,e);u.set(h,e);if(d&&!l&&u.hasChanged(v))l=true}t[s]=u}else if(b){o=t[s]=this._prepareModel(h,e);if(!o)continue;g.push(o);this._addReference(o,e)}o=u||o;if(E&&(o.isNew()||!_[o.id]))E.push(o);_[o.id]=true}if(x){for(s=0,n=this.length;s<n;++s){if(!_[(o=this.models[s]).cid])y.push(o)}if(y.length)this.remove(y,e)}if(g.length||E&&E.length){if(d)l=true;this.length+=g.length;if(c!=null){for(s=0,n=g.length;s<n;s++){this.models.splice(c+s,0,g[s])}}else{if(E)this.models.length=0;var k=E||g;for(s=0,n=k.length;s<n;s++){this.models.push(k[s])}}}if(l)this.sort({silent:true});if(!e.silent){for(s=0,n=g.length;s<n;s++){(o=g[s]).trigger("add",o,this,e)}if(l||E&&E.length)this.trigger("sort",this,e)}return r?t[0]:t},reset:function(t,e){e||(e={});for(var r=0,s=this.models.length;r<s;r++){this._removeReference(this.models[r],e)}e.previousModels=this.models;this._reset();t=this.add(t,i.extend({silent:true},e));if(!e.silent)this.trigger("reset",this,e);return t},push:function(t,e){return this.add(t,i.extend({at:this.length},e))},pop:function(t){var e=this.at(this.length-1);this.remove(e,t);return e},unshift:function(t,e){return this.add(t,i.extend({at:0},e))},shift:function(t){var e=this.at(0);this.remove(e,t);return e},slice:function(){return o.apply(this.models,arguments)},get:function(t){if(t==null)return void 0;return this._byId[t]||this._byId[t.id]||this._byId[t.cid]},at:function(t){return this.models[t]},where:function(t,e){if(i.isEmpty(t))return e?void 0:[];return this[e?"find":"filter"](function(e){for(var i in t){if(t[i]!==e.get(i))return false}return true})},findWhere:function(t){return this.where(t,true)},sort:function(t){if(!this.comparator)throw new Error("Cannot sort a set without a comparator");t||(t={});if(i.isString(this.comparator)||this.comparator.length===1){this.models=this.sortBy(this.comparator,this)}else{this.models.sort(i.bind(this.comparator,this))}if(!t.silent)this.trigger("sort",this,t);return this},pluck:function(t){return i.invoke(this.models,"get",t)},fetch:function(t){t=t?i.clone(t):{};if(t.parse===void 0)t.parse=true;var e=t.success;var r=this;t.success=function(i){var s=t.reset?"reset":"set";r[s](i,t);if(e)e(r,i,t);r.trigger("sync",r,i,t)};q(this,t);return this.sync("read",this,t)},create:function(t,e){e=e?i.clone(e):{};if(!(t=this._prepareModel(t,e)))return false;if(!e.wait)this.add(t,e);var r=this;var s=e.success;e.success=function(t,i){if(e.wait)r.add(t,e);if(s)s(t,i,e)};t.save(null,e);return t},parse:function(t,e){return t},clone:function(){return new this.constructor(this.models)},_reset:function(){this.length=0;this.models=[];this._byId={}},_prepareModel:function(t,e){if(t instanceof p)return t;e=e?i.clone(e):{};e.collection=this;var r=new this.model(t,e);if(!r.validationError)return r;this.trigger("invalid",this,r.validationError,e);return false},_addReference:function(t,e){this._byId[t.cid]=t;if(t.id!=null)this._byId[t.id]=t;if(!t.collection)t.collection=this;t.on("all",this._onModelEvent,this)},_removeReference:function(t,e){if(this===t.collection)delete t.collection;t.off("all",this._onModelEvent,this)},_onModelEvent:function(t,e,i,r){if((t==="add"||t==="remove")&&i!==this)return;if(t==="destroy")this.remove(e,r);if(e&&t==="change:"+e.idAttribute){delete this._byId[e.previous(e.idAttribute)];if(e.id!=null)this._byId[e.id]=e}this.trigger.apply(this,arguments)}});var _=["forEach","each","map","collect","reduce","foldl","inject","reduceRight","foldr","find","detect","filter","select","reject","every","all","some","any","include","contains","invoke","max","min","toArray","size","first","head","take","initial","rest","tail","drop","last","without","difference","indexOf","shuffle","lastIndexOf","isEmpty","chain","sample"];i.each(_,function(t){g.prototype[t]=function(){var e=o.call(arguments);e.unshift(this.models);return i[t].apply(i,e)}});var b=["groupBy","countBy","sortBy","indexBy"];i.each(b,function(t){g.prototype[t]=function(e,r){var s=i.isFunction(e)?e:function(t){return t.get(e)};return i[t](this.models,s,r)}});var w=e.View=function(t){this.cid=i.uniqueId("view");t||(t={});i.extend(this,i.pick(t,E));this._ensureElement();this.initialize.apply(this,arguments);this.delegateEvents()};var x=/^(\S+)\s*(.*)$/;var E=["model","collection","el","id","attributes","className","tagName","events"];i.extend(w.prototype,u,{tagName:"div",$:function(t){return this.$el.find(t)},initialize:function(){},render:function(){return this},remove:function(){this.$el.remove();this.stopListening();return this},setElement:function(t,i){if(this.$el)this.undelegateEvents();this.$el=t instanceof e.$?t:e.$(t);this.el=this.$el[0];if(i!==false)this.delegateEvents();return this},delegateEvents:function(t){if(!(t||(t=i.result(this,"events"))))return this;this.undelegateEvents();for(var e in t){var r=t[e];if(!i.isFunction(r))r=this[t[e]];if(!r)continue;var s=e.match(x);var n=s[1],a=s[2];r=i.bind(r,this);n+=".delegateEvents"+this.cid;if(a===""){this.$el.on(n,r)}else{this.$el.on(n,a,r)}}return this},undelegateEvents:function(){this.$el.off(".delegateEvents"+this.cid);return this},_ensureElement:function(){if(!this.el){var t=i.extend({},i.result(this,"attributes"));if(this.id)t.id=i.result(this,"id");if(this.className)t["class"]=i.result(this,"className");var r=e.$("<"+i.result(this,"tagName")+">").attr(t);this.setElement(r,false)}else{this.setElement(i.result(this,"el"),false)}}});e.sync=function(t,r,s){var n=T[t];i.defaults(s||(s={}),{emulateHTTP:e.emulateHTTP,emulateJSON:e.emulateJSON});var a={type:n,dataType:"json"};if(!s.url){a.url=i.result(r,"url")||M()}if(s.data==null&&r&&(t==="create"||t==="update"||t==="patch")){a.contentType="application/json";a.data=JSON.stringify(s.attrs||r.toJSON(s))}if(s.emulateJSON){a.contentType="application/x-www-form-urlencoded";a.data=a.data?{model:a.data}:{}}if(s.emulateHTTP&&(n==="PUT"||n==="DELETE"||n==="PATCH")){a.type="POST";if(s.emulateJSON)a.data._method=n;var o=s.beforeSend;s.beforeSend=function(t){t.setRequestHeader("X-HTTP-Method-Override",n);if(o)return o.apply(this,arguments)}}if(a.type!=="GET"&&!s.emulateJSON){a.processData=false}if(a.type==="PATCH"&&k){a.xhr=function(){return new ActiveXObject("Microsoft.XMLHTTP")}}var h=s.xhr=e.ajax(i.extend(a,s));r.trigger("request",r,h,s);return h};var k=typeof window!=="undefined"&&!!window.ActiveXObject&&!(window.XMLHttpRequest&&(new XMLHttpRequest).dispatchEvent);var T={create:"POST",update:"PUT",patch:"PATCH","delete":"DELETE",read:"GET"};e.ajax=function(){return e.$.ajax.apply(e.$,arguments)};var $=e.Router=function(t){t||(t={});if(t.routes)this.routes=t.routes;this._bindRoutes();this.initialize.apply(this,arguments)};var S=/\((.*?)\)/g;var H=/(\(\?)?:\w+/g;var A=/\*\w+/g;var I=/[\-{}\[\]+?.,\\\^$|#\s]/g;i.extend($.prototype,u,{initialize:function(){},route:function(t,r,s){if(!i.isRegExp(t))t=this._routeToRegExp(t);if(i.isFunction(r)){s=r;r=""}if(!s)s=this[r];var n=this;e.history.route(t,function(i){var a=n._extractParameters(t,i);n.execute(s,a);n.trigger.apply(n,["route:"+r].concat(a));n.trigger("route",r,a);e.history.trigger("route",n,r,a)});return this},execute:function(t,e){if(t)t.apply(this,e)},navigate:function(t,i){e.history.navigate(t,i);return this},_bindRoutes:function(){if(!this.routes)return;this.routes=i.result(this,"routes");var t,e=i.keys(this.routes);while((t=e.pop())!=null){this.route(t,this.routes[t])}},_routeToRegExp:function(t){t=t.replace(I,"\\$&").replace(S,"(?:$1)?").replace(H,function(t,e){return e?t:"([^/?]+)"}).replace(A,"([^?]*?)");return new RegExp("^"+t+"(?:\\?([\\s\\S]*))?$")},_extractParameters:function(t,e){var r=t.exec(e).slice(1);return i.map(r,function(t,e){if(e===r.length-1)return t||null;return t?decodeURIComponent(t):null})}});var N=e.History=function(){this.handlers=[];i.bindAll(this,"checkUrl");if(typeof window!=="undefined"){this.location=window.location;this.history=window.history}};var R=/^[#\/]|\s+$/g;var O=/^\/+|\/+$/g;var P=/msie [\w.]+/;var C=/\/$/;var j=/#.*$/;N.started=false;i.extend(N.prototype,u,{interval:50,atRoot:function(){return this.location.pathname.replace(/[^\/]$/,"$&/")===this.root},getHash:function(t){var e=(t||this).location.href.match(/#(.*)$/);return e?e[1]:""},getFragment:function(t,e){if(t==null){if(this._hasPushState||!this._wantsHashChange||e){t=decodeURI(this.location.pathname+this.location.search);var i=this.root.replace(C,"");if(!t.indexOf(i))t=t.slice(i.length)}else{t=this.getHash()}}return t.replace(R,"")},start:function(t){if(N.started)throw new Error("Backbone.history has already been started");N.started=true;this.options=i.extend({root:"/"},this.options,t);this.root=this.options.root;this._wantsHashChange=this.options.hashChange!==false;this._wantsPushState=!!this.options.pushState;this._hasPushState=!!(this.options.pushState&&this.history&&this.history.pushState);var r=this.getFragment();var s=document.documentMode;var n=P.exec(navigator.userAgent.toLowerCase())&&(!s||s<=7);this.root=("/"+this.root+"/").replace(O,"/");if(n&&this._wantsHashChange){var a=e.$('<iframe src="javascript:0" tabindex="-1">');this.iframe=a.hide().appendTo("body")[0].contentWindow;this.navigate(r)}if(this._hasPushState){e.$(window).on("popstate",this.checkUrl)}else if(this._wantsHashChange&&"onhashchange"in window&&!n){e.$(window).on("hashchange",this.checkUrl)}else if(this._wantsHashChange){this._checkUrlInterval=setInterval(this.checkUrl,this.interval)}this.fragment=r;var o=this.location;if(this._wantsHashChange&&this._wantsPushState){if(!this._hasPushState&&!this.atRoot()){this.fragment=this.getFragment(null,true);this.location.replace(this.root+"#"+this.fragment);return true}else if(this._hasPushState&&this.atRoot()&&o.hash){this.fragment=this.getHash().replace(R,"");this.history.replaceState({},document.title,this.root+this.fragment)}}if(!this.options.silent)return this.loadUrl()},stop:function(){e.$(window).off("popstate",this.checkUrl).off("hashchange",this.checkUrl);if(this._checkUrlInterval)clearInterval(this._checkUrlInterval);N.started=false},route:function(t,e){this.handlers.unshift({route:t,callback:e})},checkUrl:function(t){var e=this.getFragment();if(e===this.fragment&&this.iframe){e=this.getFragment(this.getHash(this.iframe))}if(e===this.fragment)return false;if(this.iframe)this.navigate(e);this.loadUrl()},loadUrl:function(t){t=this.fragment=this.getFragment(t);return i.any(this.handlers,function(e){if(e.route.test(t)){e.callback(t);return true}})},navigate:function(t,e){if(!N.started)return false;if(!e||e===true)e={trigger:!!e};var i=this.root+(t=this.getFragment(t||""));t=t.replace(j,"");if(this.fragment===t)return;this.fragment=t;if(t===""&&i!=="/")i=i.slice(0,-1);if(this._hasPushState){this.history[e.replace?"replaceState":"pushState"]({},document.title,i)}else if(this._wantsHashChange){this._updateHash(this.location,t,e.replace);if(this.iframe&&t!==this.getFragment(this.getHash(this.iframe))){if(!e.replace)this.iframe.document.open().close();this._updateHash(this.iframe.location,t,e.replace)}}else{return this.location.assign(i)}if(e.trigger)return this.loadUrl(t)},_updateHash:function(t,e,i){if(i){var r=t.href.replace(/(javascript:|#).*$/,"");t.replace(r+"#"+e)}else{t.hash="#"+e}}});e.history=new N;var U=function(t,e){var r=this;var s;if(t&&i.has(t,"constructor")){s=t.constructor}else{s=function(){return r.apply(this,arguments)}}i.extend(s,r,e);var n=function(){this.constructor=s};n.prototype=r.prototype;s.prototype=new n;if(t)i.extend(s.prototype,t);s.__super__=r.prototype;return s};p.extend=g.extend=$.extend=w.extend=N.extend=U;var M=function(){throw new Error('A "url" property or function must be specified')};var q=function(t,e){var i=e.error;e.error=function(r){if(i)i(t,r,e);t.trigger("error",t,r,e)}};return e});
-
-// From http://stackoverflow.com/a/19431552
-// Compatibility override - Backbone 1.1 got rid of the 'options' binding
-// automatically to views in the constructor - we need to keep that.
-Backbone.View = (function(View) {
- return View.extend({
- constructor: function(options) {
- this.options = options || {};
- View.apply(this, arguments);
- }
- });
-})(Backbone.View); \ No newline at end of file
+// Backbone.js 1.1.2
+
+(function(t,e){if(typeof define==="function"&&define.amd){define(["underscore","jquery","exports"],function(i,r,s){t.Backbone=e(t,s,i,r)})}else if(typeof exports!=="undefined"){var i=require("underscore");e(t,exports,i)}else{t.Backbone=e(t,{},t._,t.jQuery||t.Zepto||t.ender||t.$)}})(this,function(t,e,i,r){var s=t.Backbone;var n=[];var a=n.push;var o=n.slice;var h=n.splice;e.VERSION="1.1.2";e.$=r;e.noConflict=function(){t.Backbone=s;return this};e.emulateHTTP=false;e.emulateJSON=false;var u=e.Events={on:function(t,e,i){if(!c(this,"on",t,[e,i])||!e)return this;this._events||(this._events={});var r=this._events[t]||(this._events[t]=[]);r.push({callback:e,context:i,ctx:i||this});return this},once:function(t,e,r){if(!c(this,"once",t,[e,r])||!e)return this;var s=this;var n=i.once(function(){s.off(t,n);e.apply(this,arguments)});n._callback=e;return this.on(t,n,r)},off:function(t,e,r){var s,n,a,o,h,u,l,f;if(!this._events||!c(this,"off",t,[e,r]))return this;if(!t&&!e&&!r){this._events=void 0;return this}o=t?[t]:i.keys(this._events);for(h=0,u=o.length;h<u;h++){t=o[h];if(a=this._events[t]){this._events[t]=s=[];if(e||r){for(l=0,f=a.length;l<f;l++){n=a[l];if(e&&e!==n.callback&&e!==n.callback._callback||r&&r!==n.context){s.push(n)}}}if(!s.length)delete this._events[t]}}return this},trigger:function(t){if(!this._events)return this;var e=o.call(arguments,1);if(!c(this,"trigger",t,e))return this;var i=this._events[t];var r=this._events.all;if(i)f(i,e);if(r)f(r,arguments);return this},stopListening:function(t,e,r){var s=this._listeningTo;if(!s)return this;var n=!e&&!r;if(!r&&typeof e==="object")r=this;if(t)(s={})[t._listenId]=t;for(var a in s){t=s[a];t.off(e,r,this);if(n||i.isEmpty(t._events))delete this._listeningTo[a]}return this}};var l=/\s+/;var c=function(t,e,i,r){if(!i)return true;if(typeof i==="object"){for(var s in i){t[e].apply(t,[s,i[s]].concat(r))}return false}if(l.test(i)){var n=i.split(l);for(var a=0,o=n.length;a<o;a++){t[e].apply(t,[n[a]].concat(r))}return false}return true};var f=function(t,e){var i,r=-1,s=t.length,n=e[0],a=e[1],o=e[2];switch(e.length){case 0:while(++r<s)(i=t[r]).callback.call(i.ctx);return;case 1:while(++r<s)(i=t[r]).callback.call(i.ctx,n);return;case 2:while(++r<s)(i=t[r]).callback.call(i.ctx,n,a);return;case 3:while(++r<s)(i=t[r]).callback.call(i.ctx,n,a,o);return;default:while(++r<s)(i=t[r]).callback.apply(i.ctx,e);return}};var d={listenTo:"on",listenToOnce:"once"};i.each(d,function(t,e){u[e]=function(e,r,s){var n=this._listeningTo||(this._listeningTo={});var a=e._listenId||(e._listenId=i.uniqueId("l"));n[a]=e;if(!s&&typeof r==="object")s=this;e[t](r,s,this);return this}});u.bind=u.on;u.unbind=u.off;i.extend(e,u);var p=e.Model=function(t,e){var r=t||{};e||(e={});this.cid=i.uniqueId("c");this.attributes={};if(e.collection)this.collection=e.collection;if(e.parse)r=this.parse(r,e)||{};r=i.defaults({},r,i.result(this,"defaults"));this.set(r,e);this.changed={};this.initialize.apply(this,arguments)};i.extend(p.prototype,u,{changed:null,validationError:null,idAttribute:"id",initialize:function(){},toJSON:function(t){return i.clone(this.attributes)},sync:function(){return e.sync.apply(this,arguments)},get:function(t){return this.attributes[t]},escape:function(t){return i.escape(this.get(t))},has:function(t){return this.get(t)!=null},set:function(t,e,r){var s,n,a,o,h,u,l,c;if(t==null)return this;if(typeof t==="object"){n=t;r=e}else{(n={})[t]=e}r||(r={});if(!this._validate(n,r))return false;a=r.unset;h=r.silent;o=[];u=this._changing;this._changing=true;if(!u){this._previousAttributes=i.clone(this.attributes);this.changed={}}c=this.attributes,l=this._previousAttributes;if(this.idAttribute in n)this.id=n[this.idAttribute];for(s in n){e=n[s];if(!i.isEqual(c[s],e))o.push(s);if(!i.isEqual(l[s],e)){this.changed[s]=e}else{delete this.changed[s]}a?delete c[s]:c[s]=e}if(!h){if(o.length)this._pending=r;for(var f=0,d=o.length;f<d;f++){this.trigger("change:"+o[f],this,c[o[f]],r)}}if(u)return this;if(!h){while(this._pending){r=this._pending;this._pending=false;this.trigger("change",this,r)}}this._pending=false;this._changing=false;return this},unset:function(t,e){return this.set(t,void 0,i.extend({},e,{unset:true}))},clear:function(t){var e={};for(var r in this.attributes)e[r]=void 0;return this.set(e,i.extend({},t,{unset:true}))},hasChanged:function(t){if(t==null)return!i.isEmpty(this.changed);return i.has(this.changed,t)},changedAttributes:function(t){if(!t)return this.hasChanged()?i.clone(this.changed):false;var e,r=false;var s=this._changing?this._previousAttributes:this.attributes;for(var n in t){if(i.isEqual(s[n],e=t[n]))continue;(r||(r={}))[n]=e}return r},previous:function(t){if(t==null||!this._previousAttributes)return null;return this._previousAttributes[t]},previousAttributes:function(){return i.clone(this._previousAttributes)},fetch:function(t){t=t?i.clone(t):{};if(t.parse===void 0)t.parse=true;var e=this;var r=t.success;t.success=function(i){if(!e.set(e.parse(i,t),t))return false;if(r)r(e,i,t);e.trigger("sync",e,i,t)};q(this,t);return this.sync("read",this,t)},save:function(t,e,r){var s,n,a,o=this.attributes;if(t==null||typeof t==="object"){s=t;r=e}else{(s={})[t]=e}r=i.extend({validate:true},r);if(s&&!r.wait){if(!this.set(s,r))return false}else{if(!this._validate(s,r))return false}if(s&&r.wait){this.attributes=i.extend({},o,s)}if(r.parse===void 0)r.parse=true;var h=this;var u=r.success;r.success=function(t){h.attributes=o;var e=h.parse(t,r);if(r.wait)e=i.extend(s||{},e);if(i.isObject(e)&&!h.set(e,r)){return false}if(u)u(h,t,r);h.trigger("sync",h,t,r)};q(this,r);n=this.isNew()?"create":r.patch?"patch":"update";if(n==="patch")r.attrs=s;a=this.sync(n,this,r);if(s&&r.wait)this.attributes=o;return a},destroy:function(t){t=t?i.clone(t):{};var e=this;var r=t.success;var s=function(){e.trigger("destroy",e,e.collection,t)};t.success=function(i){if(t.wait||e.isNew())s();if(r)r(e,i,t);if(!e.isNew())e.trigger("sync",e,i,t)};if(this.isNew()){t.success();return false}q(this,t);var n=this.sync("delete",this,t);if(!t.wait)s();return n},url:function(){var t=i.result(this,"urlRoot")||i.result(this.collection,"url")||M();if(this.isNew())return t;return t.replace(/([^\/])$/,"$1/")+encodeURIComponent(this.id)},parse:function(t,e){return t},clone:function(){return new this.constructor(this.attributes)},isNew:function(){return!this.has(this.idAttribute)},isValid:function(t){return this._validate({},i.extend(t||{},{validate:true}))},_validate:function(t,e){if(!e.validate||!this.validate)return true;t=i.extend({},this.attributes,t);var r=this.validationError=this.validate(t,e)||null;if(!r)return true;this.trigger("invalid",this,r,i.extend(e,{validationError:r}));return false}});var v=["keys","values","pairs","invert","pick","omit"];i.each(v,function(t){p.prototype[t]=function(){var e=o.call(arguments);e.unshift(this.attributes);return i[t].apply(i,e)}});var g=e.Collection=function(t,e){e||(e={});if(e.model)this.model=e.model;if(e.comparator!==void 0)this.comparator=e.comparator;this._reset();this.initialize.apply(this,arguments);if(t)this.reset(t,i.extend({silent:true},e))};var m={add:true,remove:true,merge:true};var y={add:true,remove:false};i.extend(g.prototype,u,{model:p,initialize:function(){},toJSON:function(t){return this.map(function(e){return e.toJSON(t)})},sync:function(){return e.sync.apply(this,arguments)},add:function(t,e){return this.set(t,i.extend({merge:false},e,y))},remove:function(t,e){var r=!i.isArray(t);t=r?[t]:i.clone(t);e||(e={});var s,n,a,o;for(s=0,n=t.length;s<n;s++){o=t[s]=this.get(t[s]);if(!o)continue;delete this._byId[o.id];delete this._byId[o.cid];a=this.indexOf(o);this.models.splice(a,1);this.length--;if(!e.silent){e.index=a;o.trigger("remove",o,this,e)}this._removeReference(o,e)}return r?t[0]:t},set:function(t,e){e=i.defaults({},e,m);if(e.parse)t=this.parse(t,e);var r=!i.isArray(t);t=r?t?[t]:[]:i.clone(t);var s,n,a,o,h,u,l;var c=e.at;var f=this.model;var d=this.comparator&&c==null&&e.sort!==false;var v=i.isString(this.comparator)?this.comparator:null;var g=[],y=[],_={};var b=e.add,w=e.merge,x=e.remove;var E=!d&&b&&x?[]:false;for(s=0,n=t.length;s<n;s++){h=t[s]||{};if(h instanceof p){a=o=h}else{a=h[f.prototype.idAttribute||"id"]}if(u=this.get(a)){if(x)_[u.cid]=true;if(w){h=h===o?o.attributes:h;if(e.parse)h=u.parse(h,e);u.set(h,e);if(d&&!l&&u.hasChanged(v))l=true}t[s]=u}else if(b){o=t[s]=this._prepareModel(h,e);if(!o)continue;g.push(o);this._addReference(o,e)}o=u||o;if(E&&(o.isNew()||!_[o.id]))E.push(o);_[o.id]=true}if(x){for(s=0,n=this.length;s<n;++s){if(!_[(o=this.models[s]).cid])y.push(o)}if(y.length)this.remove(y,e)}if(g.length||E&&E.length){if(d)l=true;this.length+=g.length;if(c!=null){for(s=0,n=g.length;s<n;s++){this.models.splice(c+s,0,g[s])}}else{if(E)this.models.length=0;var k=E||g;for(s=0,n=k.length;s<n;s++){this.models.push(k[s])}}}if(l)this.sort({silent:true});if(!e.silent){for(s=0,n=g.length;s<n;s++){(o=g[s]).trigger("add",o,this,e)}if(l||E&&E.length)this.trigger("sort",this,e)}return r?t[0]:t},reset:function(t,e){e||(e={});for(var r=0,s=this.models.length;r<s;r++){this._removeReference(this.models[r],e)}e.previousModels=this.models;this._reset();t=this.add(t,i.extend({silent:true},e));if(!e.silent)this.trigger("reset",this,e);return t},push:function(t,e){return this.add(t,i.extend({at:this.length},e))},pop:function(t){var e=this.at(this.length-1);this.remove(e,t);return e},unshift:function(t,e){return this.add(t,i.extend({at:0},e))},shift:function(t){var e=this.at(0);this.remove(e,t);return e},slice:function(){return o.apply(this.models,arguments)},get:function(t){if(t==null)return void 0;return this._byId[t]||this._byId[t.id]||this._byId[t.cid]},at:function(t){return this.models[t]},where:function(t,e){if(i.isEmpty(t))return e?void 0:[];return this[e?"find":"filter"](function(e){for(var i in t){if(t[i]!==e.get(i))return false}return true})},findWhere:function(t){return this.where(t,true)},sort:function(t){if(!this.comparator)throw new Error("Cannot sort a set without a comparator");t||(t={});if(i.isString(this.comparator)||this.comparator.length===1){this.models=this.sortBy(this.comparator,this)}else{this.models.sort(i.bind(this.comparator,this))}if(!t.silent)this.trigger("sort",this,t);return this},pluck:function(t){return i.invoke(this.models,"get",t)},fetch:function(t){t=t?i.clone(t):{};if(t.parse===void 0)t.parse=true;var e=t.success;var r=this;t.success=function(i){var s=t.reset?"reset":"set";r[s](i,t);if(e)e(r,i,t);r.trigger("sync",r,i,t)};q(this,t);return this.sync("read",this,t)},create:function(t,e){e=e?i.clone(e):{};if(!(t=this._prepareModel(t,e)))return false;if(!e.wait)this.add(t,e);var r=this;var s=e.success;e.success=function(t,i){if(e.wait)r.add(t,e);if(s)s(t,i,e)};t.save(null,e);return t},parse:function(t,e){return t},clone:function(){return new this.constructor(this.models)},_reset:function(){this.length=0;this.models=[];this._byId={}},_prepareModel:function(t,e){if(t instanceof p)return t;e=e?i.clone(e):{};e.collection=this;var r=new this.model(t,e);if(!r.validationError)return r;this.trigger("invalid",this,r.validationError,e);return false},_addReference:function(t,e){this._byId[t.cid]=t;if(t.id!=null)this._byId[t.id]=t;if(!t.collection)t.collection=this;t.on("all",this._onModelEvent,this)},_removeReference:function(t,e){if(this===t.collection)delete t.collection;t.off("all",this._onModelEvent,this)},_onModelEvent:function(t,e,i,r){if((t==="add"||t==="remove")&&i!==this)return;if(t==="destroy")this.remove(e,r);if(e&&t==="change:"+e.idAttribute){delete this._byId[e.previous(e.idAttribute)];if(e.id!=null)this._byId[e.id]=e}this.trigger.apply(this,arguments)}});var _=["forEach","each","map","collect","reduce","foldl","inject","reduceRight","foldr","find","detect","filter","select","reject","every","all","some","any","include","contains","invoke","max","min","toArray","size","first","head","take","initial","rest","tail","drop","last","without","difference","indexOf","shuffle","lastIndexOf","isEmpty","chain","sample"];i.each(_,function(t){g.prototype[t]=function(){var e=o.call(arguments);e.unshift(this.models);return i[t].apply(i,e)}});var b=["groupBy","countBy","sortBy","indexBy"];i.each(b,function(t){g.prototype[t]=function(e,r){var s=i.isFunction(e)?e:function(t){return t.get(e)};return i[t](this.models,s,r)}});var w=e.View=function(t){this.cid=i.uniqueId("view");t||(t={});i.extend(this,i.pick(t,E));this._ensureElement();this.initialize.apply(this,arguments);this.delegateEvents()};var x=/^(\S+)\s*(.*)$/;var E=["model","collection","el","id","attributes","className","tagName","events"];i.extend(w.prototype,u,{tagName:"div",$:function(t){return this.$el.find(t)},initialize:function(){},render:function(){return this},remove:function(){this.$el.remove();this.stopListening();return this},setElement:function(t,i){if(this.$el)this.undelegateEvents();this.$el=t instanceof e.$?t:e.$(t);this.el=this.$el[0];if(i!==false)this.delegateEvents();return this},delegateEvents:function(t){if(!(t||(t=i.result(this,"events"))))return this;this.undelegateEvents();for(var e in t){var r=t[e];if(!i.isFunction(r))r=this[t[e]];if(!r)continue;var s=e.match(x);var n=s[1],a=s[2];r=i.bind(r,this);n+=".delegateEvents"+this.cid;if(a===""){this.$el.on(n,r)}else{this.$el.on(n,a,r)}}return this},undelegateEvents:function(){this.$el.off(".delegateEvents"+this.cid);return this},_ensureElement:function(){if(!this.el){var t=i.extend({},i.result(this,"attributes"));if(this.id)t.id=i.result(this,"id");if(this.className)t["class"]=i.result(this,"className");var r=e.$("<"+i.result(this,"tagName")+">").attr(t);this.setElement(r,false)}else{this.setElement(i.result(this,"el"),false)}}});e.sync=function(t,r,s){var n=T[t];i.defaults(s||(s={}),{emulateHTTP:e.emulateHTTP,emulateJSON:e.emulateJSON});var a={type:n,dataType:"json"};if(!s.url){a.url=i.result(r,"url")||M()}if(s.data==null&&r&&(t==="create"||t==="update"||t==="patch")){a.contentType="application/json";a.data=JSON.stringify(s.attrs||r.toJSON(s))}if(s.emulateJSON){a.contentType="application/x-www-form-urlencoded";a.data=a.data?{model:a.data}:{}}if(s.emulateHTTP&&(n==="PUT"||n==="DELETE"||n==="PATCH")){a.type="POST";if(s.emulateJSON)a.data._method=n;var o=s.beforeSend;s.beforeSend=function(t){t.setRequestHeader("X-HTTP-Method-Override",n);if(o)return o.apply(this,arguments)}}if(a.type!=="GET"&&!s.emulateJSON){a.processData=false}if(a.type==="PATCH"&&k){a.xhr=function(){return new ActiveXObject("Microsoft.XMLHTTP")}}var h=s.xhr=e.ajax(i.extend(a,s));r.trigger("request",r,h,s);return h};var k=typeof window!=="undefined"&&!!window.ActiveXObject&&!(window.XMLHttpRequest&&(new XMLHttpRequest).dispatchEvent);var T={create:"POST",update:"PUT",patch:"PATCH","delete":"DELETE",read:"GET"};e.ajax=function(){return e.$.ajax.apply(e.$,arguments)};var $=e.Router=function(t){t||(t={});if(t.routes)this.routes=t.routes;this._bindRoutes();this.initialize.apply(this,arguments)};var S=/\((.*?)\)/g;var H=/(\(\?)?:\w+/g;var A=/\*\w+/g;var I=/[\-{}\[\]+?.,\\\^$|#\s]/g;i.extend($.prototype,u,{initialize:function(){},route:function(t,r,s){if(!i.isRegExp(t))t=this._routeToRegExp(t);if(i.isFunction(r)){s=r;r=""}if(!s)s=this[r];var n=this;e.history.route(t,function(i){var a=n._extractParameters(t,i);n.execute(s,a);n.trigger.apply(n,["route:"+r].concat(a));n.trigger("route",r,a);e.history.trigger("route",n,r,a)});return this},execute:function(t,e){if(t)t.apply(this,e)},navigate:function(t,i){e.history.navigate(t,i);return this},_bindRoutes:function(){if(!this.routes)return;this.routes=i.result(this,"routes");var t,e=i.keys(this.routes);while((t=e.pop())!=null){this.route(t,this.routes[t])}},_routeToRegExp:function(t){t=t.replace(I,"\\$&").replace(S,"(?:$1)?").replace(H,function(t,e){return e?t:"([^/?]+)"}).replace(A,"([^?]*?)");return new RegExp("^"+t+"(?:\\?([\\s\\S]*))?$")},_extractParameters:function(t,e){var r=t.exec(e).slice(1);return i.map(r,function(t,e){if(e===r.length-1)return t||null;return t?decodeURIComponent(t):null})}});var N=e.History=function(){this.handlers=[];i.bindAll(this,"checkUrl");if(typeof window!=="undefined"){this.location=window.location;this.history=window.history}};var R=/^[#\/]|\s+$/g;var O=/^\/+|\/+$/g;var P=/msie [\w.]+/;var C=/\/$/;var j=/#.*$/;N.started=false;i.extend(N.prototype,u,{interval:50,atRoot:function(){return this.location.pathname.replace(/[^\/]$/,"$&/")===this.root},getHash:function(t){var e=(t||this).location.href.match(/#(.*)$/);return e?e[1]:""},getFragment:function(t,e){if(t==null){if(this._hasPushState||!this._wantsHashChange||e){t=decodeURI(this.location.pathname+this.location.search);var i=this.root.replace(C,"");if(!t.indexOf(i))t=t.slice(i.length)}else{t=this.getHash()}}return t.replace(R,"")},start:function(t){if(N.started)throw new Error("Backbone.history has already been started");N.started=true;this.options=i.extend({root:"/"},this.options,t);this.root=this.options.root;this._wantsHashChange=this.options.hashChange!==false;this._wantsPushState=!!this.options.pushState;this._hasPushState=!!(this.options.pushState&&this.history&&this.history.pushState);var r=this.getFragment();var s=document.documentMode;var n=P.exec(navigator.userAgent.toLowerCase())&&(!s||s<=7);this.root=("/"+this.root+"/").replace(O,"/");if(n&&this._wantsHashChange){var a=e.$('<iframe src="javascript:0" tabindex="-1">');this.iframe=a.hide().appendTo("body")[0].contentWindow;this.navigate(r)}if(this._hasPushState){e.$(window).on("popstate",this.checkUrl)}else if(this._wantsHashChange&&"onhashchange"in window&&!n){e.$(window).on("hashchange",this.checkUrl)}else if(this._wantsHashChange){this._checkUrlInterval=setInterval(this.checkUrl,this.interval)}this.fragment=r;var o=this.location;if(this._wantsHashChange&&this._wantsPushState){if(!this._hasPushState&&!this.atRoot()){this.fragment=this.getFragment(null,true);this.location.replace(this.root+"#"+this.fragment);return true}else if(this._hasPushState&&this.atRoot()&&o.hash){this.fragment=this.getHash().replace(R,"");this.history.replaceState({},document.title,this.root+this.fragment)}}if(!this.options.silent)return this.loadUrl()},stop:function(){e.$(window).off("popstate",this.checkUrl).off("hashchange",this.checkUrl);if(this._checkUrlInterval)clearInterval(this._checkUrlInterval);N.started=false},route:function(t,e){this.handlers.unshift({route:t,callback:e})},checkUrl:function(t){var e=this.getFragment();if(e===this.fragment&&this.iframe){e=this.getFragment(this.getHash(this.iframe))}if(e===this.fragment)return false;if(this.iframe)this.navigate(e);this.loadUrl()},loadUrl:function(t){t=this.fragment=this.getFragment(t);return i.any(this.handlers,function(e){if(e.route.test(t)){e.callback(t);return true}})},navigate:function(t,e){if(!N.started)return false;if(!e||e===true)e={trigger:!!e};var i=this.root+(t=this.getFragment(t||""));t=t.replace(j,"");if(this.fragment===t)return;this.fragment=t;if(t===""&&i!=="/")i=i.slice(0,-1);if(this._hasPushState){this.history[e.replace?"replaceState":"pushState"]({},document.title,i)}else if(this._wantsHashChange){this._updateHash(this.location,t,e.replace);if(this.iframe&&t!==this.getFragment(this.getHash(this.iframe))){if(!e.replace)this.iframe.document.open().close();this._updateHash(this.iframe.location,t,e.replace)}}else{return this.location.assign(i)}if(e.trigger)return this.loadUrl(t)},_updateHash:function(t,e,i){if(i){var r=t.href.replace(/(javascript:|#).*$/,"");t.replace(r+"#"+e)}else{t.hash="#"+e}}});e.history=new N;var U=function(t,e){var r=this;var s;if(t&&i.has(t,"constructor")){s=t.constructor}else{s=function(){return r.apply(this,arguments)}}i.extend(s,r,e);var n=function(){this.constructor=s};n.prototype=r.prototype;s.prototype=new n;if(t)i.extend(s.prototype,t);s.__super__=r.prototype;return s};p.extend=g.extend=$.extend=w.extend=N.extend=U;var M=function(){throw new Error('A "url" property or function must be specified')};var q=function(t,e){var i=e.error;e.error=function(r){if(i)i(t,r,e);t.trigger("error",t,r,e)}};return e});
+
+// From http://stackoverflow.com/a/19431552
+// Compatibility override - Backbone 1.1 got rid of the 'options' binding
+// automatically to views in the constructor - we need to keep that.
+Backbone.View = (function(View) {
+ return View.extend({
+ constructor: function(options) {
+ this.options = options || {};
+ View.apply(this, arguments);
+ }
+ });
+})(Backbone.View); \ No newline at end of file
diff --git a/ydb/core/viewer/content/api/lib/es5-shim.js b/ydb/core/viewer/content/api/lib/es5-shim.js
index b0f9bf8f5bd..f94b4334fbb 100644
--- a/ydb/core/viewer/content/api/lib/es5-shim.js
+++ b/ydb/core/viewer/content/api/lib/es5-shim.js
@@ -1,2065 +1,2065 @@
-/*!
- * https://github.com/es-shims/es5-shim
- * @license es5-shim Copyright 2009-2015 by contributors, MIT License
- * see https://github.com/es-shims/es5-shim/blob/master/LICENSE
- */
-
-// vim: ts=4 sts=4 sw=4 expandtab
-
-// Add semicolon to prevent IIFE from being passed as argument to concatenated code.
-;
-
-// UMD (Universal Module Definition)
-// see https://github.com/umdjs/umd/blob/master/templates/returnExports.js
-(function (root, factory) {
- 'use strict';
-
- /* global define, exports, module */
- if (typeof define === 'function' && define.amd) {
- // AMD. Register as an anonymous module.
- define(factory);
- } else if (typeof exports === 'object') {
- // Node. Does not work with strict CommonJS, but
- // only CommonJS-like enviroments that support module.exports,
- // like Node.
- module.exports = factory();
- } else {
- // Browser globals (root is window)
- root.returnExports = factory();
- }
-}(this, function () {
- /**
- * Brings an environment as close to ECMAScript 5 compliance
- * as is possible with the facilities of erstwhile engines.
- *
- * Annotated ES5: http://es5.github.com/ (specific links below)
- * ES5 Spec: http://www.ecma-international.org/publications/files/ECMA-ST/Ecma-262.pdf
- * Required reading: http://javascriptweblog.wordpress.com/2011/12/05/extending-javascript-natives/
- */
-
- // Shortcut to an often accessed properties, in order to avoid multiple
- // dereference that costs universally. This also holds a reference to known-good
- // functions.
- var $Array = Array;
- var ArrayPrototype = $Array.prototype;
- var $Object = Object;
- var ObjectPrototype = $Object.prototype;
- var $Function = Function;
- var FunctionPrototype = $Function.prototype;
- var $String = String;
- var StringPrototype = $String.prototype;
- var $Number = Number;
- var NumberPrototype = $Number.prototype;
- var array_slice = ArrayPrototype.slice;
- var array_splice = ArrayPrototype.splice;
- var array_push = ArrayPrototype.push;
- var array_unshift = ArrayPrototype.unshift;
- var array_concat = ArrayPrototype.concat;
- var array_join = ArrayPrototype.join;
- var call = FunctionPrototype.call;
- var apply = FunctionPrototype.apply;
- var max = Math.max;
- var min = Math.min;
-
- // Having a toString local variable name breaks in Opera so use to_string.
- var to_string = ObjectPrototype.toString;
-
- /* global Symbol */
- /* eslint-disable one-var-declaration-per-line, no-redeclare, max-statements-per-line */
- var hasToStringTag = typeof Symbol === 'function' && typeof Symbol.toStringTag === 'symbol';
- var isCallable; /* inlined from https://npmjs.com/is-callable */ var fnToStr = Function.prototype.toString, constructorRegex = /^\s*class /, isES6ClassFn = function isES6ClassFn(value) { try { var fnStr = fnToStr.call(value); var singleStripped = fnStr.replace(/\/\/.*\n/g, ''); var multiStripped = singleStripped.replace(/\/\*[.\s\S]*\*\//g, ''); var spaceStripped = multiStripped.replace(/\n/mg, ' ').replace(/ {2}/g, ' '); return constructorRegex.test(spaceStripped); } catch (e) { return false; /* not a function */ } }, tryFunctionObject = function tryFunctionObject(value) { try { if (isES6ClassFn(value)) { return false; } fnToStr.call(value); return true; } catch (e) { return false; } }, fnClass = '[object Function]', genClass = '[object GeneratorFunction]', isCallable = function isCallable(value) { if (!value) { return false; } if (typeof value !== 'function' && typeof value !== 'object') { return false; } if (hasToStringTag) { return tryFunctionObject(value); } if (isES6ClassFn(value)) { return false; } var strClass = to_string.call(value); return strClass === fnClass || strClass === genClass; };
-
- var isRegex; /* inlined from https://npmjs.com/is-regex */ var regexExec = RegExp.prototype.exec, tryRegexExec = function tryRegexExec(value) { try { regexExec.call(value); return true; } catch (e) { return false; } }, regexClass = '[object RegExp]'; isRegex = function isRegex(value) { if (typeof value !== 'object') { return false; } return hasToStringTag ? tryRegexExec(value) : to_string.call(value) === regexClass; };
- var isString; /* inlined from https://npmjs.com/is-string */ var strValue = String.prototype.valueOf, tryStringObject = function tryStringObject(value) { try { strValue.call(value); return true; } catch (e) { return false; } }, stringClass = '[object String]'; isString = function isString(value) { if (typeof value === 'string') { return true; } if (typeof value !== 'object') { return false; } return hasToStringTag ? tryStringObject(value) : to_string.call(value) === stringClass; };
- /* eslint-enable one-var-declaration-per-line, no-redeclare, max-statements-per-line */
-
- /* inlined from http://npmjs.com/define-properties */
- var supportsDescriptors = $Object.defineProperty && (function () {
- try {
- var obj = {};
- $Object.defineProperty(obj, 'x', { enumerable: false, value: obj });
- for (var _ in obj) { // jscs:ignore disallowUnusedVariables
- return false;
- }
- return obj.x === obj;
- } catch (e) { /* this is ES3 */
- return false;
- }
- }());
- var defineProperties = (function (has) {
- // Define configurable, writable, and non-enumerable props
- // if they don't exist.
- var defineProperty;
- if (supportsDescriptors) {
- defineProperty = function (object, name, method, forceAssign) {
- if (!forceAssign && (name in object)) {
- return;
- }
- $Object.defineProperty(object, name, {
- configurable: true,
- enumerable: false,
- writable: true,
- value: method
- });
- };
- } else {
- defineProperty = function (object, name, method, forceAssign) {
- if (!forceAssign && (name in object)) {
- return;
- }
- object[name] = method;
- };
- }
- return function defineProperties(object, map, forceAssign) {
- for (var name in map) {
- if (has.call(map, name)) {
- defineProperty(object, name, map[name], forceAssign);
- }
- }
- };
- }(ObjectPrototype.hasOwnProperty));
-
- //
- // Util
- // ======
- //
-
- /* replaceable with https://npmjs.com/package/es-abstract /helpers/isPrimitive */
- var isPrimitive = function isPrimitive(input) {
- var type = typeof input;
- return input === null || (type !== 'object' && type !== 'function');
- };
-
- var isActualNaN = $Number.isNaN || function isActualNaN(x) {
- return x !== x;
- };
-
- var ES = {
- // ES5 9.4
- // http://es5.github.com/#x9.4
- // http://jsperf.com/to-integer
- /* replaceable with https://npmjs.com/package/es-abstract ES5.ToInteger */
- ToInteger: function ToInteger(num) {
- var n = +num;
- if (isActualNaN(n)) {
- n = 0;
- } else if (n !== 0 && n !== (1 / 0) && n !== -(1 / 0)) {
- n = (n > 0 || -1) * Math.floor(Math.abs(n));
- }
- return n;
- },
-
- /* replaceable with https://npmjs.com/package/es-abstract ES5.ToPrimitive */
- ToPrimitive: function ToPrimitive(input) {
- var val, valueOf, toStr;
- if (isPrimitive(input)) {
- return input;
- }
- valueOf = input.valueOf;
- if (isCallable(valueOf)) {
- val = valueOf.call(input);
- if (isPrimitive(val)) {
- return val;
- }
- }
- toStr = input.toString;
- if (isCallable(toStr)) {
- val = toStr.call(input);
- if (isPrimitive(val)) {
- return val;
- }
- }
- throw new TypeError();
- },
-
- // ES5 9.9
- // http://es5.github.com/#x9.9
- /* replaceable with https://npmjs.com/package/es-abstract ES5.ToObject */
- ToObject: function (o) {
- if (o == null) { // this matches both null and undefined
- throw new TypeError("can't convert " + o + ' to object');
- }
- return $Object(o);
- },
-
- /* replaceable with https://npmjs.com/package/es-abstract ES5.ToUint32 */
- ToUint32: function ToUint32(x) {
- return x >>> 0;
- }
- };
-
- //
- // Function
- // ========
- //
-
- // ES-5 15.3.4.5
- // http://es5.github.com/#x15.3.4.5
-
- var Empty = function Empty() {};
-
- defineProperties(FunctionPrototype, {
- bind: function bind(that) { // .length is 1
- // 1. Let Target be the this value.
- var target = this;
- // 2. If IsCallable(Target) is false, throw a TypeError exception.
- if (!isCallable(target)) {
- throw new TypeError('Function.prototype.bind called on incompatible ' + target);
- }
- // 3. Let A be a new (possibly empty) internal list of all of the
- // argument values provided after thisArg (arg1, arg2 etc), in order.
- // XXX slicedArgs will stand in for "A" if used
- var args = array_slice.call(arguments, 1); // for normal call
- // 4. Let F be a new native ECMAScript object.
- // 11. Set the [[Prototype]] internal property of F to the standard
- // built-in Function prototype object as specified in 15.3.3.1.
- // 12. Set the [[Call]] internal property of F as described in
- // 15.3.4.5.1.
- // 13. Set the [[Construct]] internal property of F as described in
- // 15.3.4.5.2.
- // 14. Set the [[HasInstance]] internal property of F as described in
- // 15.3.4.5.3.
- var bound;
- var binder = function () {
-
- if (this instanceof bound) {
- // 15.3.4.5.2 [[Construct]]
- // When the [[Construct]] internal method of a function object,
- // F that was created using the bind function is called with a
- // list of arguments ExtraArgs, the following steps are taken:
- // 1. Let target be the value of F's [[TargetFunction]]
- // internal property.
- // 2. If target has no [[Construct]] internal method, a
- // TypeError exception is thrown.
- // 3. Let boundArgs be the value of F's [[BoundArgs]] internal
- // property.
- // 4. Let args be a new list containing the same values as the
- // list boundArgs in the same order followed by the same
- // values as the list ExtraArgs in the same order.
- // 5. Return the result of calling the [[Construct]] internal
- // method of target providing args as the arguments.
-
- var result = apply.call(
- target,
- this,
- array_concat.call(args, array_slice.call(arguments))
- );
- if ($Object(result) === result) {
- return result;
- }
- return this;
-
- } else {
- // 15.3.4.5.1 [[Call]]
- // When the [[Call]] internal method of a function object, F,
- // which was created using the bind function is called with a
- // this value and a list of arguments ExtraArgs, the following
- // steps are taken:
- // 1. Let boundArgs be the value of F's [[BoundArgs]] internal
- // property.
- // 2. Let boundThis be the value of F's [[BoundThis]] internal
- // property.
- // 3. Let target be the value of F's [[TargetFunction]] internal
- // property.
- // 4. Let args be a new list containing the same values as the
- // list boundArgs in the same order followed by the same
- // values as the list ExtraArgs in the same order.
- // 5. Return the result of calling the [[Call]] internal method
- // of target providing boundThis as the this value and
- // providing args as the arguments.
-
- // equiv: target.call(this, ...boundArgs, ...args)
- return apply.call(
- target,
- that,
- array_concat.call(args, array_slice.call(arguments))
- );
-
- }
-
- };
-
- // 15. If the [[Class]] internal property of Target is "Function", then
- // a. Let L be the length property of Target minus the length of A.
- // b. Set the length own property of F to either 0 or L, whichever is
- // larger.
- // 16. Else set the length own property of F to 0.
-
- var boundLength = max(0, target.length - args.length);
-
- // 17. Set the attributes of the length own property of F to the values
- // specified in 15.3.5.1.
- var boundArgs = [];
- for (var i = 0; i < boundLength; i++) {
- array_push.call(boundArgs, '$' + i);
- }
-
- // XXX Build a dynamic function with desired amount of arguments is the only
- // way to set the length property of a function.
- // In environments where Content Security Policies enabled (Chrome extensions,
- // for ex.) all use of eval or Function costructor throws an exception.
- // However in all of these environments Function.prototype.bind exists
- // and so this code will never be executed.
- bound = $Function('binder', 'return function (' + array_join.call(boundArgs, ',') + '){ return binder.apply(this, arguments); }')(binder);
-
- if (target.prototype) {
- Empty.prototype = target.prototype;
- bound.prototype = new Empty();
- // Clean up dangling references.
- Empty.prototype = null;
- }
-
- // TODO
- // 18. Set the [[Extensible]] internal property of F to true.
-
- // TODO
- // 19. Let thrower be the [[ThrowTypeError]] function Object (13.2.3).
- // 20. Call the [[DefineOwnProperty]] internal method of F with
- // arguments "caller", PropertyDescriptor {[[Get]]: thrower, [[Set]]:
- // thrower, [[Enumerable]]: false, [[Configurable]]: false}, and
- // false.
- // 21. Call the [[DefineOwnProperty]] internal method of F with
- // arguments "arguments", PropertyDescriptor {[[Get]]: thrower,
- // [[Set]]: thrower, [[Enumerable]]: false, [[Configurable]]: false},
- // and false.
-
- // TODO
- // NOTE Function objects created using Function.prototype.bind do not
- // have a prototype property or the [[Code]], [[FormalParameters]], and
- // [[Scope]] internal properties.
- // XXX can't delete prototype in pure-js.
-
- // 22. Return F.
- return bound;
- }
- });
-
- // _Please note: Shortcuts are defined after `Function.prototype.bind` as we
- // use it in defining shortcuts.
- var owns = call.bind(ObjectPrototype.hasOwnProperty);
- var toStr = call.bind(ObjectPrototype.toString);
- var arraySlice = call.bind(array_slice);
- var arraySliceApply = apply.bind(array_slice);
- var strSlice = call.bind(StringPrototype.slice);
- var strSplit = call.bind(StringPrototype.split);
- var strIndexOf = call.bind(StringPrototype.indexOf);
- var pushCall = call.bind(array_push);
- var isEnum = call.bind(ObjectPrototype.propertyIsEnumerable);
- var arraySort = call.bind(ArrayPrototype.sort);
-
- //
- // Array
- // =====
- //
-
- var isArray = $Array.isArray || function isArray(obj) {
- return toStr(obj) === '[object Array]';
- };
-
- // ES5 15.4.4.12
- // http://es5.github.com/#x15.4.4.13
- // Return len+argCount.
- // [bugfix, ielt8]
- // IE < 8 bug: [].unshift(0) === undefined but should be "1"
- var hasUnshiftReturnValueBug = [].unshift(0) !== 1;
- defineProperties(ArrayPrototype, {
- unshift: function () {
- array_unshift.apply(this, arguments);
- return this.length;
- }
- }, hasUnshiftReturnValueBug);
-
- // ES5 15.4.3.2
- // http://es5.github.com/#x15.4.3.2
- // https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array/isArray
- defineProperties($Array, { isArray: isArray });
-
- // The IsCallable() check in the Array functions
- // has been replaced with a strict check on the
- // internal class of the object to trap cases where
- // the provided function was actually a regular
- // expression literal, which in V8 and
- // JavaScriptCore is a typeof "function". Only in
- // V8 are regular expression literals permitted as
- // reduce parameters, so it is desirable in the
- // general case for the shim to match the more
- // strict and common behavior of rejecting regular
- // expressions.
-
- // ES5 15.4.4.18
- // http://es5.github.com/#x15.4.4.18
- // https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/array/forEach
-
- // Check failure of by-index access of string characters (IE < 9)
- // and failure of `0 in boxedString` (Rhino)
- var boxedString = $Object('a');
- var splitString = boxedString[0] !== 'a' || !(0 in boxedString);
-
- var properlyBoxesContext = function properlyBoxed(method) {
- // Check node 0.6.21 bug where third parameter is not boxed
- var properlyBoxesNonStrict = true;
- var properlyBoxesStrict = true;
- var threwException = false;
- if (method) {
- try {
- method.call('foo', function (_, __, context) {
- if (typeof context !== 'object') {
- properlyBoxesNonStrict = false;
- }
- });
-
- method.call([1], function () {
- 'use strict';
-
- properlyBoxesStrict = typeof this === 'string';
- }, 'x');
- } catch (e) {
- threwException = true;
- }
- }
- return !!method && !threwException && properlyBoxesNonStrict && properlyBoxesStrict;
- };
-
- defineProperties(ArrayPrototype, {
- forEach: function forEach(callbackfn/*, thisArg*/) {
- var object = ES.ToObject(this);
- var self = splitString && isString(this) ? strSplit(this, '') : object;
- var i = -1;
- var length = ES.ToUint32(self.length);
- var T;
- if (arguments.length > 1) {
- T = arguments[1];
- }
-
- // If no callback function or if callback is not a callable function
- if (!isCallable(callbackfn)) {
- throw new TypeError('Array.prototype.forEach callback must be a function');
- }
-
- while (++i < length) {
- if (i in self) {
- // Invoke the callback function with call, passing arguments:
- // context, property value, property key, thisArg object
- if (typeof T === 'undefined') {
- callbackfn(self[i], i, object);
- } else {
- callbackfn.call(T, self[i], i, object);
- }
- }
- }
- }
- }, !properlyBoxesContext(ArrayPrototype.forEach));
-
- // ES5 15.4.4.19
- // http://es5.github.com/#x15.4.4.19
- // https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Objects/Array/map
- defineProperties(ArrayPrototype, {
- map: function map(callbackfn/*, thisArg*/) {
- var object = ES.ToObject(this);
- var self = splitString && isString(this) ? strSplit(this, '') : object;
- var length = ES.ToUint32(self.length);
- var result = $Array(length);
- var T;
- if (arguments.length > 1) {
- T = arguments[1];
- }
-
- // If no callback function or if callback is not a callable function
- if (!isCallable(callbackfn)) {
- throw new TypeError('Array.prototype.map callback must be a function');
- }
-
- for (var i = 0; i < length; i++) {
- if (i in self) {
- if (typeof T === 'undefined') {
- result[i] = callbackfn(self[i], i, object);
- } else {
- result[i] = callbackfn.call(T, self[i], i, object);
- }
- }
- }
- return result;
- }
- }, !properlyBoxesContext(ArrayPrototype.map));
-
- // ES5 15.4.4.20
- // http://es5.github.com/#x15.4.4.20
- // https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Objects/Array/filter
- defineProperties(ArrayPrototype, {
- filter: function filter(callbackfn/*, thisArg*/) {
- var object = ES.ToObject(this);
- var self = splitString && isString(this) ? strSplit(this, '') : object;
- var length = ES.ToUint32(self.length);
- var result = [];
- var value;
- var T;
- if (arguments.length > 1) {
- T = arguments[1];
- }
-
- // If no callback function or if callback is not a callable function
- if (!isCallable(callbackfn)) {
- throw new TypeError('Array.prototype.filter callback must be a function');
- }
-
- for (var i = 0; i < length; i++) {
- if (i in self) {
- value = self[i];
- if (typeof T === 'undefined' ? callbackfn(value, i, object) : callbackfn.call(T, value, i, object)) {
- pushCall(result, value);
- }
- }
- }
- return result;
- }
- }, !properlyBoxesContext(ArrayPrototype.filter));
-
- // ES5 15.4.4.16
- // http://es5.github.com/#x15.4.4.16
- // https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array/every
- defineProperties(ArrayPrototype, {
- every: function every(callbackfn/*, thisArg*/) {
- var object = ES.ToObject(this);
- var self = splitString && isString(this) ? strSplit(this, '') : object;
- var length = ES.ToUint32(self.length);
- var T;
- if (arguments.length > 1) {
- T = arguments[1];
- }
-
- // If no callback function or if callback is not a callable function
- if (!isCallable(callbackfn)) {
- throw new TypeError('Array.prototype.every callback must be a function');
- }
-
- for (var i = 0; i < length; i++) {
- if (i in self && !(typeof T === 'undefined' ? callbackfn(self[i], i, object) : callbackfn.call(T, self[i], i, object))) {
- return false;
- }
- }
- return true;
- }
- }, !properlyBoxesContext(ArrayPrototype.every));
-
- // ES5 15.4.4.17
- // http://es5.github.com/#x15.4.4.17
- // https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array/some
- defineProperties(ArrayPrototype, {
- some: function some(callbackfn/*, thisArg */) {
- var object = ES.ToObject(this);
- var self = splitString && isString(this) ? strSplit(this, '') : object;
- var length = ES.ToUint32(self.length);
- var T;
- if (arguments.length > 1) {
- T = arguments[1];
- }
-
- // If no callback function or if callback is not a callable function
- if (!isCallable(callbackfn)) {
- throw new TypeError('Array.prototype.some callback must be a function');
- }
-
- for (var i = 0; i < length; i++) {
- if (i in self && (typeof T === 'undefined' ? callbackfn(self[i], i, object) : callbackfn.call(T, self[i], i, object))) {
- return true;
- }
- }
- return false;
- }
- }, !properlyBoxesContext(ArrayPrototype.some));
-
- // ES5 15.4.4.21
- // http://es5.github.com/#x15.4.4.21
- // https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Objects/Array/reduce
- var reduceCoercesToObject = false;
- if (ArrayPrototype.reduce) {
- reduceCoercesToObject = typeof ArrayPrototype.reduce.call('es5', function (_, __, ___, list) {
- return list;
- }) === 'object';
- }
- defineProperties(ArrayPrototype, {
- reduce: function reduce(callbackfn/*, initialValue*/) {
- var object = ES.ToObject(this);
- var self = splitString && isString(this) ? strSplit(this, '') : object;
- var length = ES.ToUint32(self.length);
-
- // If no callback function or if callback is not a callable function
- if (!isCallable(callbackfn)) {
- throw new TypeError('Array.prototype.reduce callback must be a function');
- }
-
- // no value to return if no initial value and an empty array
- if (length === 0 && arguments.length === 1) {
- throw new TypeError('reduce of empty array with no initial value');
- }
-
- var i = 0;
- var result;
- if (arguments.length >= 2) {
- result = arguments[1];
- } else {
- do {
- if (i in self) {
- result = self[i++];
- break;
- }
-
- // if array contains no values, no initial value to return
- if (++i >= length) {
- throw new TypeError('reduce of empty array with no initial value');
- }
- } while (true);
- }
-
- for (; i < length; i++) {
- if (i in self) {
- result = callbackfn(result, self[i], i, object);
- }
- }
-
- return result;
- }
- }, !reduceCoercesToObject);
-
- // ES5 15.4.4.22
- // http://es5.github.com/#x15.4.4.22
- // https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Objects/Array/reduceRight
- var reduceRightCoercesToObject = false;
- if (ArrayPrototype.reduceRight) {
- reduceRightCoercesToObject = typeof ArrayPrototype.reduceRight.call('es5', function (_, __, ___, list) {
- return list;
- }) === 'object';
- }
- defineProperties(ArrayPrototype, {
- reduceRight: function reduceRight(callbackfn/*, initial*/) {
- var object = ES.ToObject(this);
- var self = splitString && isString(this) ? strSplit(this, '') : object;
- var length = ES.ToUint32(self.length);
-
- // If no callback function or if callback is not a callable function
- if (!isCallable(callbackfn)) {
- throw new TypeError('Array.prototype.reduceRight callback must be a function');
- }
-
- // no value to return if no initial value, empty array
- if (length === 0 && arguments.length === 1) {
- throw new TypeError('reduceRight of empty array with no initial value');
- }
-
- var result;
- var i = length - 1;
- if (arguments.length >= 2) {
- result = arguments[1];
- } else {
- do {
- if (i in self) {
- result = self[i--];
- break;
- }
-
- // if array contains no values, no initial value to return
- if (--i < 0) {
- throw new TypeError('reduceRight of empty array with no initial value');
- }
- } while (true);
- }
-
- if (i < 0) {
- return result;
- }
-
- do {
- if (i in self) {
- result = callbackfn(result, self[i], i, object);
- }
- } while (i--);
-
- return result;
- }
- }, !reduceRightCoercesToObject);
-
- // ES5 15.4.4.14
- // http://es5.github.com/#x15.4.4.14
- // https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array/indexOf
- var hasFirefox2IndexOfBug = ArrayPrototype.indexOf && [0, 1].indexOf(1, 2) !== -1;
- defineProperties(ArrayPrototype, {
- indexOf: function indexOf(searchElement/*, fromIndex */) {
- var self = splitString && isString(this) ? strSplit(this, '') : ES.ToObject(this);
- var length = ES.ToUint32(self.length);
-
- if (length === 0) {
- return -1;
- }
-
- var i = 0;
- if (arguments.length > 1) {
- i = ES.ToInteger(arguments[1]);
- }
-
- // handle negative indices
- i = i >= 0 ? i : max(0, length + i);
- for (; i < length; i++) {
- if (i in self && self[i] === searchElement) {
- return i;
- }
- }
- return -1;
- }
- }, hasFirefox2IndexOfBug);
-
- // ES5 15.4.4.15
- // http://es5.github.com/#x15.4.4.15
- // https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array/lastIndexOf
- var hasFirefox2LastIndexOfBug = ArrayPrototype.lastIndexOf && [0, 1].lastIndexOf(0, -3) !== -1;
- defineProperties(ArrayPrototype, {
- lastIndexOf: function lastIndexOf(searchElement/*, fromIndex */) {
- var self = splitString && isString(this) ? strSplit(this, '') : ES.ToObject(this);
- var length = ES.ToUint32(self.length);
-
- if (length === 0) {
- return -1;
- }
- var i = length - 1;
- if (arguments.length > 1) {
- i = min(i, ES.ToInteger(arguments[1]));
- }
- // handle negative indices
- i = i >= 0 ? i : length - Math.abs(i);
- for (; i >= 0; i--) {
- if (i in self && searchElement === self[i]) {
- return i;
- }
- }
- return -1;
- }
- }, hasFirefox2LastIndexOfBug);
-
- // ES5 15.4.4.12
- // http://es5.github.com/#x15.4.4.12
- var spliceNoopReturnsEmptyArray = (function () {
- var a = [1, 2];
- var result = a.splice();
- return a.length === 2 && isArray(result) && result.length === 0;
- }());
- defineProperties(ArrayPrototype, {
- // Safari 5.0 bug where .splice() returns undefined
- splice: function splice(start, deleteCount) {
- if (arguments.length === 0) {
- return [];
- } else {
- return array_splice.apply(this, arguments);
- }
- }
- }, !spliceNoopReturnsEmptyArray);
-
- var spliceWorksWithEmptyObject = (function () {
- var obj = {};
- ArrayPrototype.splice.call(obj, 0, 0, 1);
- return obj.length === 1;
- }());
- defineProperties(ArrayPrototype, {
- splice: function splice(start, deleteCount) {
- if (arguments.length === 0) {
- return [];
- }
- var args = arguments;
- this.length = max(ES.ToInteger(this.length), 0);
- if (arguments.length > 0 && typeof deleteCount !== 'number') {
- args = arraySlice(arguments);
- if (args.length < 2) {
- pushCall(args, this.length - start);
- } else {
- args[1] = ES.ToInteger(deleteCount);
- }
- }
- return array_splice.apply(this, args);
- }
- }, !spliceWorksWithEmptyObject);
- var spliceWorksWithLargeSparseArrays = (function () {
- // Per https://github.com/es-shims/es5-shim/issues/295
- // Safari 7/8 breaks with sparse arrays of size 1e5 or greater
- var arr = new $Array(1e5);
- // note: the index MUST be 8 or larger or the test will false pass
- arr[8] = 'x';
- arr.splice(1, 1);
- // note: this test must be defined *after* the indexOf shim
- // per https://github.com/es-shims/es5-shim/issues/313
- return arr.indexOf('x') === 7;
- }());
- var spliceWorksWithSmallSparseArrays = (function () {
- // Per https://github.com/es-shims/es5-shim/issues/295
- // Opera 12.15 breaks on this, no idea why.
- var n = 256;
- var arr = [];
- arr[n] = 'a';
- arr.splice(n + 1, 0, 'b');
- return arr[n] === 'a';
- }());
- defineProperties(ArrayPrototype, {
- splice: function splice(start, deleteCount) {
- var O = ES.ToObject(this);
- var A = [];
- var len = ES.ToUint32(O.length);
- var relativeStart = ES.ToInteger(start);
- var actualStart = relativeStart < 0 ? max((len + relativeStart), 0) : min(relativeStart, len);
- var actualDeleteCount = min(max(ES.ToInteger(deleteCount), 0), len - actualStart);
-
- var k = 0;
- var from;
- while (k < actualDeleteCount) {
- from = $String(actualStart + k);
- if (owns(O, from)) {
- A[k] = O[from];
- }
- k += 1;
- }
-
- var items = arraySlice(arguments, 2);
- var itemCount = items.length;
- var to;
- if (itemCount < actualDeleteCount) {
- k = actualStart;
- var maxK = len - actualDeleteCount;
- while (k < maxK) {
- from = $String(k + actualDeleteCount);
- to = $String(k + itemCount);
- if (owns(O, from)) {
- O[to] = O[from];
- } else {
- delete O[to];
- }
- k += 1;
- }
- k = len;
- var minK = len - actualDeleteCount + itemCount;
- while (k > minK) {
- delete O[k - 1];
- k -= 1;
- }
- } else if (itemCount > actualDeleteCount) {
- k = len - actualDeleteCount;
- while (k > actualStart) {
- from = $String(k + actualDeleteCount - 1);
- to = $String(k + itemCount - 1);
- if (owns(O, from)) {
- O[to] = O[from];
- } else {
- delete O[to];
- }
- k -= 1;
- }
- }
- k = actualStart;
- for (var i = 0; i < items.length; ++i) {
- O[k] = items[i];
- k += 1;
- }
- O.length = len - actualDeleteCount + itemCount;
-
- return A;
- }
- }, !spliceWorksWithLargeSparseArrays || !spliceWorksWithSmallSparseArrays);
-
- var originalJoin = ArrayPrototype.join;
- var hasStringJoinBug;
- try {
- hasStringJoinBug = Array.prototype.join.call('123', ',') !== '1,2,3';
- } catch (e) {
- hasStringJoinBug = true;
- }
- if (hasStringJoinBug) {
- defineProperties(ArrayPrototype, {
- join: function join(separator) {
- var sep = typeof separator === 'undefined' ? ',' : separator;
- return originalJoin.call(isString(this) ? strSplit(this, '') : this, sep);
- }
- }, hasStringJoinBug);
- }
-
- var hasJoinUndefinedBug = [1, 2].join(undefined) !== '1,2';
- if (hasJoinUndefinedBug) {
- defineProperties(ArrayPrototype, {
- join: function join(separator) {
- var sep = typeof separator === 'undefined' ? ',' : separator;
- return originalJoin.call(this, sep);
- }
- }, hasJoinUndefinedBug);
- }
-
- var pushShim = function push(item) {
- var O = ES.ToObject(this);
- var n = ES.ToUint32(O.length);
- var i = 0;
- while (i < arguments.length) {
- O[n + i] = arguments[i];
- i += 1;
- }
- O.length = n + i;
- return n + i;
- };
-
- var pushIsNotGeneric = (function () {
- var obj = {};
- var result = Array.prototype.push.call(obj, undefined);
- return result !== 1 || obj.length !== 1 || typeof obj[0] !== 'undefined' || !owns(obj, 0);
- }());
- defineProperties(ArrayPrototype, {
- push: function push(item) {
- if (isArray(this)) {
- return array_push.apply(this, arguments);
- }
- return pushShim.apply(this, arguments);
- }
- }, pushIsNotGeneric);
-
- // This fixes a very weird bug in Opera 10.6 when pushing `undefined
- var pushUndefinedIsWeird = (function () {
- var arr = [];
- var result = arr.push(undefined);
- return result !== 1 || arr.length !== 1 || typeof arr[0] !== 'undefined' || !owns(arr, 0);
- }());
- defineProperties(ArrayPrototype, { push: pushShim }, pushUndefinedIsWeird);
-
- // ES5 15.2.3.14
- // http://es5.github.io/#x15.4.4.10
- // Fix boxed string bug
- defineProperties(ArrayPrototype, {
- slice: function (start, end) {
- var arr = isString(this) ? strSplit(this, '') : this;
- return arraySliceApply(arr, arguments);
- }
- }, splitString);
-
- var sortIgnoresNonFunctions = (function () {
- try {
- [1, 2].sort(null);
- [1, 2].sort({});
- return true;
- } catch (e) {}
- return false;
- }());
- var sortThrowsOnRegex = (function () {
- // this is a problem in Firefox 4, in which `typeof /a/ === 'function'`
- try {
- [1, 2].sort(/a/);
- return false;
- } catch (e) {}
- return true;
- }());
- var sortIgnoresUndefined = (function () {
- // applies in IE 8, for one.
- try {
- [1, 2].sort(undefined);
- return true;
- } catch (e) {}
- return false;
- }());
- defineProperties(ArrayPrototype, {
- sort: function sort(compareFn) {
- if (typeof compareFn === 'undefined') {
- return arraySort(this);
- }
- if (!isCallable(compareFn)) {
- throw new TypeError('Array.prototype.sort callback must be a function');
- }
- return arraySort(this, compareFn);
- }
- }, sortIgnoresNonFunctions || !sortIgnoresUndefined || !sortThrowsOnRegex);
-
- //
- // Object
- // ======
- //
-
- // ES5 15.2.3.14
- // http://es5.github.com/#x15.2.3.14
-
- // http://whattheheadsaid.com/2010/10/a-safer-object-keys-compatibility-implementation
- var hasDontEnumBug = !isEnum({ 'toString': null }, 'toString');
- var hasProtoEnumBug = isEnum(function () {}, 'prototype');
- var hasStringEnumBug = !owns('x', '0');
- var equalsConstructorPrototype = function (o) {
- var ctor = o.constructor;
- return ctor && ctor.prototype === o;
- };
- var blacklistedKeys = {
- $window: true,
- $console: true,
- $parent: true,
- $self: true,
- $frame: true,
- $frames: true,
- $frameElement: true,
- $webkitIndexedDB: true,
- $webkitStorageInfo: true,
- $external: true
- };
- var hasAutomationEqualityBug = (function () {
- /* globals window */
- if (typeof window === 'undefined') {
- return false;
- }
- for (var k in window) {
- try {
- if (!blacklistedKeys['$' + k] && owns(window, k) && window[k] !== null && typeof window[k] === 'object') {
- equalsConstructorPrototype(window[k]);
- }
- } catch (e) {
- return true;
- }
- }
- return false;
- }());
- var equalsConstructorPrototypeIfNotBuggy = function (object) {
- if (typeof window === 'undefined' || !hasAutomationEqualityBug) {
- return equalsConstructorPrototype(object);
- }
- try {
- return equalsConstructorPrototype(object);
- } catch (e) {
- return false;
- }
- };
- var dontEnums = [
- 'toString',
- 'toLocaleString',
- 'valueOf',
- 'hasOwnProperty',
- 'isPrototypeOf',
- 'propertyIsEnumerable',
- 'constructor'
- ];
- var dontEnumsLength = dontEnums.length;
-
- // taken directly from https://github.com/ljharb/is-arguments/blob/master/index.js
- // can be replaced with require('is-arguments') if we ever use a build process instead
- var isStandardArguments = function isArguments(value) {
- return toStr(value) === '[object Arguments]';
- };
- var isLegacyArguments = function isArguments(value) {
- return value !== null &&
- typeof value === 'object' &&
- typeof value.length === 'number' &&
- value.length >= 0 &&
- !isArray(value) &&
- isCallable(value.callee);
- };
- var isArguments = isStandardArguments(arguments) ? isStandardArguments : isLegacyArguments;
-
- defineProperties($Object, {
- keys: function keys(object) {
- var isFn = isCallable(object);
- var isArgs = isArguments(object);
- var isObject = object !== null && typeof object === 'object';
- var isStr = isObject && isString(object);
-
- if (!isObject && !isFn && !isArgs) {
- throw new TypeError('Object.keys called on a non-object');
- }
-
- var theKeys = [];
- var skipProto = hasProtoEnumBug && isFn;
- if ((isStr && hasStringEnumBug) || isArgs) {
- for (var i = 0; i < object.length; ++i) {
- pushCall(theKeys, $String(i));
- }
- }
-
- if (!isArgs) {
- for (var name in object) {
- if (!(skipProto && name === 'prototype') && owns(object, name)) {
- pushCall(theKeys, $String(name));
- }
- }
- }
-
- if (hasDontEnumBug) {
- var skipConstructor = equalsConstructorPrototypeIfNotBuggy(object);
- for (var j = 0; j < dontEnumsLength; j++) {
- var dontEnum = dontEnums[j];
- if (!(skipConstructor && dontEnum === 'constructor') && owns(object, dontEnum)) {
- pushCall(theKeys, dontEnum);
- }
- }
- }
- return theKeys;
- }
- });
-
- var keysWorksWithArguments = $Object.keys && (function () {
- // Safari 5.0 bug
- return $Object.keys(arguments).length === 2;
- }(1, 2));
- var keysHasArgumentsLengthBug = $Object.keys && (function () {
- var argKeys = $Object.keys(arguments);
- return arguments.length !== 1 || argKeys.length !== 1 || argKeys[0] !== 1;
- }(1));
- var originalKeys = $Object.keys;
- defineProperties($Object, {
- keys: function keys(object) {
- if (isArguments(object)) {
- return originalKeys(arraySlice(object));
- } else {
- return originalKeys(object);
- }
- }
- }, !keysWorksWithArguments || keysHasArgumentsLengthBug);
-
- //
- // Date
- // ====
- //
-
- var hasNegativeMonthYearBug = new Date(-3509827329600292).getUTCMonth() !== 0;
- var aNegativeTestDate = new Date(-1509842289600292);
- var aPositiveTestDate = new Date(1449662400000);
- var hasToUTCStringFormatBug = aNegativeTestDate.toUTCString() !== 'Mon, 01 Jan -45875 11:59:59 GMT';
- var hasToDateStringFormatBug;
- var hasToStringFormatBug;
- var timeZoneOffset = aNegativeTestDate.getTimezoneOffset();
- if (timeZoneOffset < -720) {
- hasToDateStringFormatBug = aNegativeTestDate.toDateString() !== 'Tue Jan 02 -45875';
- hasToStringFormatBug = !(/^Thu Dec 10 2015 \d\d:\d\d:\d\d GMT[-\+]\d\d\d\d(?: |$)/).test(aPositiveTestDate.toString());
- } else {
- hasToDateStringFormatBug = aNegativeTestDate.toDateString() !== 'Mon Jan 01 -45875';
- hasToStringFormatBug = !(/^Wed Dec 09 2015 \d\d:\d\d:\d\d GMT[-\+]\d\d\d\d(?: |$)/).test(aPositiveTestDate.toString());
- }
-
- var originalGetFullYear = call.bind(Date.prototype.getFullYear);
- var originalGetMonth = call.bind(Date.prototype.getMonth);
- var originalGetDate = call.bind(Date.prototype.getDate);
- var originalGetUTCFullYear = call.bind(Date.prototype.getUTCFullYear);
- var originalGetUTCMonth = call.bind(Date.prototype.getUTCMonth);
- var originalGetUTCDate = call.bind(Date.prototype.getUTCDate);
- var originalGetUTCDay = call.bind(Date.prototype.getUTCDay);
- var originalGetUTCHours = call.bind(Date.prototype.getUTCHours);
- var originalGetUTCMinutes = call.bind(Date.prototype.getUTCMinutes);
- var originalGetUTCSeconds = call.bind(Date.prototype.getUTCSeconds);
- var originalGetUTCMilliseconds = call.bind(Date.prototype.getUTCMilliseconds);
- var dayName = ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'];
- var monthName = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'];
- var daysInMonth = function daysInMonth(month, year) {
- return originalGetDate(new Date(year, month, 0));
- };
-
- defineProperties(Date.prototype, {
- getFullYear: function getFullYear() {
- if (!this || !(this instanceof Date)) {
- throw new TypeError('this is not a Date object.');
- }
- var year = originalGetFullYear(this);
- if (year < 0 && originalGetMonth(this) > 11) {
- return year + 1;
- }
- return year;
- },
- getMonth: function getMonth() {
- if (!this || !(this instanceof Date)) {
- throw new TypeError('this is not a Date object.');
- }
- var year = originalGetFullYear(this);
- var month = originalGetMonth(this);
- if (year < 0 && month > 11) {
- return 0;
- }
- return month;
- },
- getDate: function getDate() {
- if (!this || !(this instanceof Date)) {
- throw new TypeError('this is not a Date object.');
- }
- var year = originalGetFullYear(this);
- var month = originalGetMonth(this);
- var date = originalGetDate(this);
- if (year < 0 && month > 11) {
- if (month === 12) {
- return date;
- }
- var days = daysInMonth(0, year + 1);
- return (days - date) + 1;
- }
- return date;
- },
- getUTCFullYear: function getUTCFullYear() {
- if (!this || !(this instanceof Date)) {
- throw new TypeError('this is not a Date object.');
- }
- var year = originalGetUTCFullYear(this);
- if (year < 0 && originalGetUTCMonth(this) > 11) {
- return year + 1;
- }
- return year;
- },
- getUTCMonth: function getUTCMonth() {
- if (!this || !(this instanceof Date)) {
- throw new TypeError('this is not a Date object.');
- }
- var year = originalGetUTCFullYear(this);
- var month = originalGetUTCMonth(this);
- if (year < 0 && month > 11) {
- return 0;
- }
- return month;
- },
- getUTCDate: function getUTCDate() {
- if (!this || !(this instanceof Date)) {
- throw new TypeError('this is not a Date object.');
- }
- var year = originalGetUTCFullYear(this);
- var month = originalGetUTCMonth(this);
- var date = originalGetUTCDate(this);
- if (year < 0 && month > 11) {
- if (month === 12) {
- return date;
- }
- var days = daysInMonth(0, year + 1);
- return (days - date) + 1;
- }
- return date;
- }
- }, hasNegativeMonthYearBug);
-
- defineProperties(Date.prototype, {
- toUTCString: function toUTCString() {
- if (!this || !(this instanceof Date)) {
- throw new TypeError('this is not a Date object.');
- }
- var day = originalGetUTCDay(this);
- var date = originalGetUTCDate(this);
- var month = originalGetUTCMonth(this);
- var year = originalGetUTCFullYear(this);
- var hour = originalGetUTCHours(this);
- var minute = originalGetUTCMinutes(this);
- var second = originalGetUTCSeconds(this);
- return dayName[day] + ', ' +
- (date < 10 ? '0' + date : date) + ' ' +
- monthName[month] + ' ' +
- year + ' ' +
- (hour < 10 ? '0' + hour : hour) + ':' +
- (minute < 10 ? '0' + minute : minute) + ':' +
- (second < 10 ? '0' + second : second) + ' GMT';
- }
- }, hasNegativeMonthYearBug || hasToUTCStringFormatBug);
-
- // Opera 12 has `,`
- defineProperties(Date.prototype, {
- toDateString: function toDateString() {
- if (!this || !(this instanceof Date)) {
- throw new TypeError('this is not a Date object.');
- }
- var day = this.getDay();
- var date = this.getDate();
- var month = this.getMonth();
- var year = this.getFullYear();
- return dayName[day] + ' ' +
- monthName[month] + ' ' +
- (date < 10 ? '0' + date : date) + ' ' +
- year;
- }
- }, hasNegativeMonthYearBug || hasToDateStringFormatBug);
-
- // can't use defineProperties here because of toString enumeration issue in IE <= 8
- if (hasNegativeMonthYearBug || hasToStringFormatBug) {
- Date.prototype.toString = function toString() {
- if (!this || !(this instanceof Date)) {
- throw new TypeError('this is not a Date object.');
- }
- var day = this.getDay();
- var date = this.getDate();
- var month = this.getMonth();
- var year = this.getFullYear();
- var hour = this.getHours();
- var minute = this.getMinutes();
- var second = this.getSeconds();
- var timezoneOffset = this.getTimezoneOffset();
- var hoursOffset = Math.floor(Math.abs(timezoneOffset) / 60);
- var minutesOffset = Math.floor(Math.abs(timezoneOffset) % 60);
- return dayName[day] + ' ' +
- monthName[month] + ' ' +
- (date < 10 ? '0' + date : date) + ' ' +
- year + ' ' +
- (hour < 10 ? '0' + hour : hour) + ':' +
- (minute < 10 ? '0' + minute : minute) + ':' +
- (second < 10 ? '0' + second : second) + ' GMT' +
- (timezoneOffset > 0 ? '-' : '+') +
- (hoursOffset < 10 ? '0' + hoursOffset : hoursOffset) +
- (minutesOffset < 10 ? '0' + minutesOffset : minutesOffset);
- };
- if (supportsDescriptors) {
- $Object.defineProperty(Date.prototype, 'toString', {
- configurable: true,
- enumerable: false,
- writable: true
- });
- }
- }
-
- // ES5 15.9.5.43
- // http://es5.github.com/#x15.9.5.43
- // This function returns a String value represent the instance in time
- // represented by this Date object. The format of the String is the Date Time
- // string format defined in 15.9.1.15. All fields are present in the String.
- // The time zone is always UTC, denoted by the suffix Z. If the time value of
- // this object is not a finite Number a RangeError exception is thrown.
- var negativeDate = -62198755200000;
- var negativeYearString = '-000001';
- var hasNegativeDateBug = Date.prototype.toISOString && new Date(negativeDate).toISOString().indexOf(negativeYearString) === -1;
- var hasSafari51DateBug = Date.prototype.toISOString && new Date(-1).toISOString() !== '1969-12-31T23:59:59.999Z';
-
- var getTime = call.bind(Date.prototype.getTime);
-
- defineProperties(Date.prototype, {
- toISOString: function toISOString() {
- if (!isFinite(this) || !isFinite(getTime(this))) {
- // Adope Photoshop requires the second check.
- throw new RangeError('Date.prototype.toISOString called on non-finite value.');
- }
-
- var year = originalGetUTCFullYear(this);
-
- var month = originalGetUTCMonth(this);
- // see https://github.com/es-shims/es5-shim/issues/111
- year += Math.floor(month / 12);
- month = (month % 12 + 12) % 12;
-
- // the date time string format is specified in 15.9.1.15.
- var result = [month + 1, originalGetUTCDate(this), originalGetUTCHours(this), originalGetUTCMinutes(this), originalGetUTCSeconds(this)];
- year = (
- (year < 0 ? '-' : (year > 9999 ? '+' : '')) +
- strSlice('00000' + Math.abs(year), (0 <= year && year <= 9999) ? -4 : -6)
- );
-
- for (var i = 0; i < result.length; ++i) {
- // pad months, days, hours, minutes, and seconds to have two digits.
- result[i] = strSlice('00' + result[i], -2);
- }
- // pad milliseconds to have three digits.
- return (
- year + '-' + arraySlice(result, 0, 2).join('-') +
- 'T' + arraySlice(result, 2).join(':') + '.' +
- strSlice('000' + originalGetUTCMilliseconds(this), -3) + 'Z'
- );
- }
- }, hasNegativeDateBug || hasSafari51DateBug);
-
- // ES5 15.9.5.44
- // http://es5.github.com/#x15.9.5.44
- // This function provides a String representation of a Date object for use by
- // JSON.stringify (15.12.3).
- var dateToJSONIsSupported = (function () {
- try {
- return Date.prototype.toJSON &&
- new Date(NaN).toJSON() === null &&
- new Date(negativeDate).toJSON().indexOf(negativeYearString) !== -1 &&
- Date.prototype.toJSON.call({ // generic
- toISOString: function () { return true; }
- });
- } catch (e) {
- return false;
- }
- }());
- if (!dateToJSONIsSupported) {
- Date.prototype.toJSON = function toJSON(key) {
- // When the toJSON method is called with argument key, the following
- // steps are taken:
-
- // 1. Let O be the result of calling ToObject, giving it the this
- // value as its argument.
- // 2. Let tv be ES.ToPrimitive(O, hint Number).
- var O = $Object(this);
- var tv = ES.ToPrimitive(O);
- // 3. If tv is a Number and is not finite, return null.
- if (typeof tv === 'number' && !isFinite(tv)) {
- return null;
- }
- // 4. Let toISO be the result of calling the [[Get]] internal method of
- // O with argument "toISOString".
- var toISO = O.toISOString;
- // 5. If IsCallable(toISO) is false, throw a TypeError exception.
- if (!isCallable(toISO)) {
- throw new TypeError('toISOString property is not callable');
- }
- // 6. Return the result of calling the [[Call]] internal method of
- // toISO with O as the this value and an empty argument list.
- return toISO.call(O);
-
- // NOTE 1 The argument is ignored.
-
- // NOTE 2 The toJSON function is intentionally generic; it does not
- // require that its this value be a Date object. Therefore, it can be
- // transferred to other kinds of objects for use as a method. However,
- // it does require that any such object have a toISOString method. An
- // object is free to use the argument key to filter its
- // stringification.
- };
- }
-
- // ES5 15.9.4.2
- // http://es5.github.com/#x15.9.4.2
- // based on work shared by Daniel Friesen (dantman)
- // http://gist.github.com/303249
- var supportsExtendedYears = Date.parse('+033658-09-27T01:46:40.000Z') === 1e15;
- var acceptsInvalidDates = !isNaN(Date.parse('2012-04-04T24:00:00.500Z')) || !isNaN(Date.parse('2012-11-31T23:59:59.000Z')) || !isNaN(Date.parse('2012-12-31T23:59:60.000Z'));
- var doesNotParseY2KNewYear = isNaN(Date.parse('2000-01-01T00:00:00.000Z'));
- if (doesNotParseY2KNewYear || acceptsInvalidDates || !supportsExtendedYears) {
- // XXX global assignment won't work in embeddings that use
- // an alternate object for the context.
- /* global Date: true */
- /* eslint-disable no-undef */
- var maxSafeUnsigned32Bit = Math.pow(2, 31) - 1;
- var hasSafariSignedIntBug = isActualNaN(new Date(1970, 0, 1, 0, 0, 0, maxSafeUnsigned32Bit + 1).getTime());
- /* eslint-disable no-implicit-globals */
- Date = (function (NativeDate) {
- /* eslint-enable no-implicit-globals */
- /* eslint-enable no-undef */
- // Date.length === 7
- var DateShim = function Date(Y, M, D, h, m, s, ms) {
- var length = arguments.length;
- var date;
- if (this instanceof NativeDate) {
- var seconds = s;
- var millis = ms;
- if (hasSafariSignedIntBug && length >= 7 && ms > maxSafeUnsigned32Bit) {
- // work around a Safari 8/9 bug where it treats the seconds as signed
- var msToShift = Math.floor(ms / maxSafeUnsigned32Bit) * maxSafeUnsigned32Bit;
- var sToShift = Math.floor(msToShift / 1e3);
- seconds += sToShift;
- millis -= sToShift * 1e3;
- }
- date = length === 1 && $String(Y) === Y ? // isString(Y)
- // We explicitly pass it through parse:
- new NativeDate(DateShim.parse(Y)) :
- // We have to manually make calls depending on argument
- // length here
- length >= 7 ? new NativeDate(Y, M, D, h, m, seconds, millis) :
- length >= 6 ? new NativeDate(Y, M, D, h, m, seconds) :
- length >= 5 ? new NativeDate(Y, M, D, h, m) :
- length >= 4 ? new NativeDate(Y, M, D, h) :
- length >= 3 ? new NativeDate(Y, M, D) :
- length >= 2 ? new NativeDate(Y, M) :
- length >= 1 ? new NativeDate(Y instanceof NativeDate ? +Y : Y) :
- new NativeDate();
- } else {
- date = NativeDate.apply(this, arguments);
- }
- if (!isPrimitive(date)) {
- // Prevent mixups with unfixed Date object
- defineProperties(date, { constructor: DateShim }, true);
- }
- return date;
- };
-
- // 15.9.1.15 Date Time String Format.
- var isoDateExpression = new RegExp('^' +
- '(\\d{4}|[+-]\\d{6})' + // four-digit year capture or sign +
- // 6-digit extended year
- '(?:-(\\d{2})' + // optional month capture
- '(?:-(\\d{2})' + // optional day capture
- '(?:' + // capture hours:minutes:seconds.milliseconds
- 'T(\\d{2})' + // hours capture
- ':(\\d{2})' + // minutes capture
- '(?:' + // optional :seconds.milliseconds
- ':(\\d{2})' + // seconds capture
- '(?:(\\.\\d{1,}))?' + // milliseconds capture
- ')?' +
- '(' + // capture UTC offset component
- 'Z|' + // UTC capture
- '(?:' + // offset specifier +/-hours:minutes
- '([-+])' + // sign capture
- '(\\d{2})' + // hours offset capture
- ':(\\d{2})' + // minutes offset capture
- ')' +
- ')?)?)?)?' +
- '$');
-
- var months = [0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365];
-
- var dayFromMonth = function dayFromMonth(year, month) {
- var t = month > 1 ? 1 : 0;
- return (
- months[month] +
- Math.floor((year - 1969 + t) / 4) -
- Math.floor((year - 1901 + t) / 100) +
- Math.floor((year - 1601 + t) / 400) +
- 365 * (year - 1970)
- );
- };
-
- var toUTC = function toUTC(t) {
- var s = 0;
- var ms = t;
- if (hasSafariSignedIntBug && ms > maxSafeUnsigned32Bit) {
- // work around a Safari 8/9 bug where it treats the seconds as signed
- var msToShift = Math.floor(ms / maxSafeUnsigned32Bit) * maxSafeUnsigned32Bit;
- var sToShift = Math.floor(msToShift / 1e3);
- s += sToShift;
- ms -= sToShift * 1e3;
- }
- return $Number(new NativeDate(1970, 0, 1, 0, 0, s, ms));
- };
-
- // Copy any custom methods a 3rd party library may have added
- for (var key in NativeDate) {
- if (owns(NativeDate, key)) {
- DateShim[key] = NativeDate[key];
- }
- }
-
- // Copy "native" methods explicitly; they may be non-enumerable
- defineProperties(DateShim, {
- now: NativeDate.now,
- UTC: NativeDate.UTC
- }, true);
- DateShim.prototype = NativeDate.prototype;
- defineProperties(DateShim.prototype, {
- constructor: DateShim
- }, true);
-
- // Upgrade Date.parse to handle simplified ISO 8601 strings
- var parseShim = function parse(string) {
- var match = isoDateExpression.exec(string);
- if (match) {
- // parse months, days, hours, minutes, seconds, and milliseconds
- // provide default values if necessary
- // parse the UTC offset component
- var year = $Number(match[1]),
- month = $Number(match[2] || 1) - 1,
- day = $Number(match[3] || 1) - 1,
- hour = $Number(match[4] || 0),
- minute = $Number(match[5] || 0),
- second = $Number(match[6] || 0),
- millisecond = Math.floor($Number(match[7] || 0) * 1000),
- // When time zone is missed, local offset should be used
- // (ES 5.1 bug)
- // see https://bugs.ecmascript.org/show_bug.cgi?id=112
- isLocalTime = Boolean(match[4] && !match[8]),
- signOffset = match[9] === '-' ? 1 : -1,
- hourOffset = $Number(match[10] || 0),
- minuteOffset = $Number(match[11] || 0),
- result;
- var hasMinutesOrSecondsOrMilliseconds = minute > 0 || second > 0 || millisecond > 0;
- if (
- hour < (hasMinutesOrSecondsOrMilliseconds ? 24 : 25) &&
- minute < 60 && second < 60 && millisecond < 1000 &&
- month > -1 && month < 12 && hourOffset < 24 &&
- minuteOffset < 60 && // detect invalid offsets
- day > -1 &&
- day < (dayFromMonth(year, month + 1) - dayFromMonth(year, month))
- ) {
- result = (
- (dayFromMonth(year, month) + day) * 24 +
- hour +
- hourOffset * signOffset
- ) * 60;
- result = (
- (result + minute + minuteOffset * signOffset) * 60 +
- second
- ) * 1000 + millisecond;
- if (isLocalTime) {
- result = toUTC(result);
- }
- if (-8.64e15 <= result && result <= 8.64e15) {
- return result;
- }
- }
- return NaN;
- }
- return NativeDate.parse.apply(this, arguments);
- };
- defineProperties(DateShim, { parse: parseShim });
-
- return DateShim;
- }(Date));
- /* global Date: false */
- }
-
- // ES5 15.9.4.4
- // http://es5.github.com/#x15.9.4.4
- if (!Date.now) {
- Date.now = function now() {
- return new Date().getTime();
- };
- }
-
- //
- // Number
- // ======
- //
-
- // ES5.1 15.7.4.5
- // http://es5.github.com/#x15.7.4.5
- var hasToFixedBugs = NumberPrototype.toFixed && (
- (0.00008).toFixed(3) !== '0.000' ||
- (0.9).toFixed(0) !== '1' ||
- (1.255).toFixed(2) !== '1.25' ||
- (1000000000000000128).toFixed(0) !== '1000000000000000128'
- );
-
- var toFixedHelpers = {
- base: 1e7,
- size: 6,
- data: [0, 0, 0, 0, 0, 0],
- multiply: function multiply(n, c) {
- var i = -1;
- var c2 = c;
- while (++i < toFixedHelpers.size) {
- c2 += n * toFixedHelpers.data[i];
- toFixedHelpers.data[i] = c2 % toFixedHelpers.base;
- c2 = Math.floor(c2 / toFixedHelpers.base);
- }
- },
- divide: function divide(n) {
- var i = toFixedHelpers.size;
- var c = 0;
- while (--i >= 0) {
- c += toFixedHelpers.data[i];
- toFixedHelpers.data[i] = Math.floor(c / n);
- c = (c % n) * toFixedHelpers.base;
- }
- },
- numToString: function numToString() {
- var i = toFixedHelpers.size;
- var s = '';
- while (--i >= 0) {
- if (s !== '' || i === 0 || toFixedHelpers.data[i] !== 0) {
- var t = $String(toFixedHelpers.data[i]);
- if (s === '') {
- s = t;
- } else {
- s += strSlice('0000000', 0, 7 - t.length) + t;
- }
- }
- }
- return s;
- },
- pow: function pow(x, n, acc) {
- return (n === 0 ? acc : (n % 2 === 1 ? pow(x, n - 1, acc * x) : pow(x * x, n / 2, acc)));
- },
- log: function log(x) {
- var n = 0;
- var x2 = x;
- while (x2 >= 4096) {
- n += 12;
- x2 /= 4096;
- }
- while (x2 >= 2) {
- n += 1;
- x2 /= 2;
- }
- return n;
- }
- };
-
- var toFixedShim = function toFixed(fractionDigits) {
- var f, x, s, m, e, z, j, k;
-
- // Test for NaN and round fractionDigits down
- f = $Number(fractionDigits);
- f = isActualNaN(f) ? 0 : Math.floor(f);
-
- if (f < 0 || f > 20) {
- throw new RangeError('Number.toFixed called with invalid number of decimals');
- }
-
- x = $Number(this);
-
- if (isActualNaN(x)) {
- return 'NaN';
- }
-
- // If it is too big or small, return the string value of the number
- if (x <= -1e21 || x >= 1e21) {
- return $String(x);
- }
-
- s = '';
-
- if (x < 0) {
- s = '-';
- x = -x;
- }
-
- m = '0';
-
- if (x > 1e-21) {
- // 1e-21 < x < 1e21
- // -70 < log2(x) < 70
- e = toFixedHelpers.log(x * toFixedHelpers.pow(2, 69, 1)) - 69;
- z = (e < 0 ? x * toFixedHelpers.pow(2, -e, 1) : x / toFixedHelpers.pow(2, e, 1));
- z *= 0x10000000000000; // Math.pow(2, 52);
- e = 52 - e;
-
- // -18 < e < 122
- // x = z / 2 ^ e
- if (e > 0) {
- toFixedHelpers.multiply(0, z);
- j = f;
-
- while (j >= 7) {
- toFixedHelpers.multiply(1e7, 0);
- j -= 7;
- }
-
- toFixedHelpers.multiply(toFixedHelpers.pow(10, j, 1), 0);
- j = e - 1;
-
- while (j >= 23) {
- toFixedHelpers.divide(1 << 23);
- j -= 23;
- }
-
- toFixedHelpers.divide(1 << j);
- toFixedHelpers.multiply(1, 1);
- toFixedHelpers.divide(2);
- m = toFixedHelpers.numToString();
- } else {
- toFixedHelpers.multiply(0, z);
- toFixedHelpers.multiply(1 << (-e), 0);
- m = toFixedHelpers.numToString() + strSlice('0.00000000000000000000', 2, 2 + f);
- }
- }
-
- if (f > 0) {
- k = m.length;
-
- if (k <= f) {
- m = s + strSlice('0.0000000000000000000', 0, f - k + 2) + m;
- } else {
- m = s + strSlice(m, 0, k - f) + '.' + strSlice(m, k - f);
- }
- } else {
- m = s + m;
- }
-
- return m;
- };
- defineProperties(NumberPrototype, { toFixed: toFixedShim }, hasToFixedBugs);
-
- var hasToPrecisionUndefinedBug = (function () {
- try {
- return 1.0.toPrecision(undefined) === '1';
- } catch (e) {
- return true;
- }
- }());
- var originalToPrecision = NumberPrototype.toPrecision;
- defineProperties(NumberPrototype, {
- toPrecision: function toPrecision(precision) {
- return typeof precision === 'undefined' ? originalToPrecision.call(this) : originalToPrecision.call(this, precision);
- }
- }, hasToPrecisionUndefinedBug);
-
- //
- // String
- // ======
- //
-
- // ES5 15.5.4.14
- // http://es5.github.com/#x15.5.4.14
-
- // [bugfix, IE lt 9, firefox 4, Konqueror, Opera, obscure browsers]
- // Many browsers do not split properly with regular expressions or they
- // do not perform the split correctly under obscure conditions.
- // See http://blog.stevenlevithan.com/archives/cross-browser-split
- // I've tested in many browsers and this seems to cover the deviant ones:
- // 'ab'.split(/(?:ab)*/) should be ["", ""], not [""]
- // '.'.split(/(.?)(.?)/) should be ["", ".", "", ""], not ["", ""]
- // 'tesst'.split(/(s)*/) should be ["t", undefined, "e", "s", "t"], not
- // [undefined, "t", undefined, "e", ...]
- // ''.split(/.?/) should be [], not [""]
- // '.'.split(/()()/) should be ["."], not ["", "", "."]
-
- if (
- 'ab'.split(/(?:ab)*/).length !== 2 ||
- '.'.split(/(.?)(.?)/).length !== 4 ||
- 'tesst'.split(/(s)*/)[1] === 't' ||
- 'test'.split(/(?:)/, -1).length !== 4 ||
- ''.split(/.?/).length ||
- '.'.split(/()()/).length > 1
- ) {
- (function () {
- var compliantExecNpcg = typeof (/()??/).exec('')[1] === 'undefined'; // NPCG: nonparticipating capturing group
- var maxSafe32BitInt = Math.pow(2, 32) - 1;
-
- StringPrototype.split = function (separator, limit) {
- var string = String(this);
- if (typeof separator === 'undefined' && limit === 0) {
- return [];
- }
-
- // If `separator` is not a regex, use native split
- if (!isRegex(separator)) {
- return strSplit(this, separator, limit);
- }
-
- var output = [];
- var flags = (separator.ignoreCase ? 'i' : '') +
- (separator.multiline ? 'm' : '') +
- (separator.unicode ? 'u' : '') + // in ES6
- (separator.sticky ? 'y' : ''), // Firefox 3+ and ES6
- lastLastIndex = 0,
- // Make `global` and avoid `lastIndex` issues by working with a copy
- separator2, match, lastIndex, lastLength;
- var separatorCopy = new RegExp(separator.source, flags + 'g');
- if (!compliantExecNpcg) {
- // Doesn't need flags gy, but they don't hurt
- separator2 = new RegExp('^' + separatorCopy.source + '$(?!\\s)', flags);
- }
- /* Values for `limit`, per the spec:
- * If undefined: 4294967295 // maxSafe32BitInt
- * If 0, Infinity, or NaN: 0
- * If positive number: limit = Math.floor(limit); if (limit > 4294967295) limit -= 4294967296;
- * If negative number: 4294967296 - Math.floor(Math.abs(limit))
- * If other: Type-convert, then use the above rules
- */
- var splitLimit = typeof limit === 'undefined' ? maxSafe32BitInt : ES.ToUint32(limit);
- match = separatorCopy.exec(string);
- while (match) {
- // `separatorCopy.lastIndex` is not reliable cross-browser
- lastIndex = match.index + match[0].length;
- if (lastIndex > lastLastIndex) {
- pushCall(output, strSlice(string, lastLastIndex, match.index));
- // Fix browsers whose `exec` methods don't consistently return `undefined` for
- // nonparticipating capturing groups
- if (!compliantExecNpcg && match.length > 1) {
- /* eslint-disable no-loop-func */
- match[0].replace(separator2, function () {
- for (var i = 1; i < arguments.length - 2; i++) {
- if (typeof arguments[i] === 'undefined') {
- match[i] = void 0;
- }
- }
- });
- /* eslint-enable no-loop-func */
- }
- if (match.length > 1 && match.index < string.length) {
- array_push.apply(output, arraySlice(match, 1));
- }
- lastLength = match[0].length;
- lastLastIndex = lastIndex;
- if (output.length >= splitLimit) {
- break;
- }
- }
- if (separatorCopy.lastIndex === match.index) {
- separatorCopy.lastIndex++; // Avoid an infinite loop
- }
- match = separatorCopy.exec(string);
- }
- if (lastLastIndex === string.length) {
- if (lastLength || !separatorCopy.test('')) {
- pushCall(output, '');
- }
- } else {
- pushCall(output, strSlice(string, lastLastIndex));
- }
- return output.length > splitLimit ? arraySlice(output, 0, splitLimit) : output;
- };
- }());
-
- // [bugfix, chrome]
- // If separator is undefined, then the result array contains just one String,
- // which is the this value (converted to a String). If limit is not undefined,
- // then the output array is truncated so that it contains no more than limit
- // elements.
- // "0".split(undefined, 0) -> []
- } else if ('0'.split(void 0, 0).length) {
- StringPrototype.split = function split(separator, limit) {
- if (typeof separator === 'undefined' && limit === 0) {
- return [];
- }
- return strSplit(this, separator, limit);
- };
- }
-
- var str_replace = StringPrototype.replace;
- var replaceReportsGroupsCorrectly = (function () {
- var groups = [];
- 'x'.replace(/x(.)?/g, function (match, group) {
- pushCall(groups, group);
- });
- return groups.length === 1 && typeof groups[0] === 'undefined';
- }());
-
- if (!replaceReportsGroupsCorrectly) {
- StringPrototype.replace = function replace(searchValue, replaceValue) {
- var isFn = isCallable(replaceValue);
- var hasCapturingGroups = isRegex(searchValue) && (/\)[*?]/).test(searchValue.source);
- if (!isFn || !hasCapturingGroups) {
- return str_replace.call(this, searchValue, replaceValue);
- } else {
- var wrappedReplaceValue = function (match) {
- var length = arguments.length;
- var originalLastIndex = searchValue.lastIndex;
- searchValue.lastIndex = 0;
- var args = searchValue.exec(match) || [];
- searchValue.lastIndex = originalLastIndex;
- pushCall(args, arguments[length - 2], arguments[length - 1]);
- return replaceValue.apply(this, args);
- };
- return str_replace.call(this, searchValue, wrappedReplaceValue);
- }
- };
- }
-
- // ECMA-262, 3rd B.2.3
- // Not an ECMAScript standard, although ECMAScript 3rd Edition has a
- // non-normative section suggesting uniform semantics and it should be
- // normalized across all browsers
- // [bugfix, IE lt 9] IE < 9 substr() with negative value not working in IE
- var string_substr = StringPrototype.substr;
- var hasNegativeSubstrBug = ''.substr && '0b'.substr(-1) !== 'b';
- defineProperties(StringPrototype, {
- substr: function substr(start, length) {
- var normalizedStart = start;
- if (start < 0) {
- normalizedStart = max(this.length + start, 0);
- }
- return string_substr.call(this, normalizedStart, length);
- }
- }, hasNegativeSubstrBug);
-
- // ES5 15.5.4.20
- // whitespace from: http://es5.github.io/#x15.5.4.20
- var ws = '\x09\x0A\x0B\x0C\x0D\x20\xA0\u1680\u180E\u2000\u2001\u2002\u2003' +
- '\u2004\u2005\u2006\u2007\u2008\u2009\u200A\u202F\u205F\u3000\u2028' +
- '\u2029\uFEFF';
- var zeroWidth = '\u200b';
- var wsRegexChars = '[' + ws + ']';
- var trimBeginRegexp = new RegExp('^' + wsRegexChars + wsRegexChars + '*');
- var trimEndRegexp = new RegExp(wsRegexChars + wsRegexChars + '*$');
- var hasTrimWhitespaceBug = StringPrototype.trim && (ws.trim() || !zeroWidth.trim());
- defineProperties(StringPrototype, {
- // http://blog.stevenlevithan.com/archives/faster-trim-javascript
- // http://perfectionkills.com/whitespace-deviations/
- trim: function trim() {
- if (typeof this === 'undefined' || this === null) {
- throw new TypeError("can't convert " + this + ' to object');
- }
- return $String(this).replace(trimBeginRegexp, '').replace(trimEndRegexp, '');
- }
- }, hasTrimWhitespaceBug);
- var trim = call.bind(String.prototype.trim);
-
- var hasLastIndexBug = StringPrototype.lastIndexOf && 'abcあい'.lastIndexOf('あい', 2) !== -1;
- defineProperties(StringPrototype, {
- lastIndexOf: function lastIndexOf(searchString) {
- if (typeof this === 'undefined' || this === null) {
- throw new TypeError("can't convert " + this + ' to object');
- }
- var S = $String(this);
- var searchStr = $String(searchString);
- var numPos = arguments.length > 1 ? $Number(arguments[1]) : NaN;
- var pos = isActualNaN(numPos) ? Infinity : ES.ToInteger(numPos);
- var start = min(max(pos, 0), S.length);
- var searchLen = searchStr.length;
- var k = start + searchLen;
- while (k > 0) {
- k = max(0, k - searchLen);
- var index = strIndexOf(strSlice(S, k, start + searchLen), searchStr);
- if (index !== -1) {
- return k + index;
- }
- }
- return -1;
- }
- }, hasLastIndexBug);
-
- var originalLastIndexOf = StringPrototype.lastIndexOf;
- defineProperties(StringPrototype, {
- lastIndexOf: function lastIndexOf(searchString) {
- return originalLastIndexOf.apply(this, arguments);
- }
- }, StringPrototype.lastIndexOf.length !== 1);
-
- // ES-5 15.1.2.2
- /* eslint-disable radix */
- if (parseInt(ws + '08') !== 8 || parseInt(ws + '0x16') !== 22) {
- /* eslint-enable radix */
- /* global parseInt: true */
- parseInt = (function (origParseInt) {
- var hexRegex = /^[\-+]?0[xX]/;
- return function parseInt(str, radix) {
- var string = trim(String(str));
- var defaultedRadix = $Number(radix) || (hexRegex.test(string) ? 16 : 10);
- return origParseInt(string, defaultedRadix);
- };
- }(parseInt));
- }
-
- // https://es5.github.io/#x15.1.2.3
- if (1 / parseFloat('-0') !== -Infinity) {
- /* global parseFloat: true */
- parseFloat = (function (origParseFloat) {
- return function parseFloat(string) {
- var inputString = trim(String(string));
- var result = origParseFloat(inputString);
- return result === 0 && strSlice(inputString, 0, 1) === '-' ? -0 : result;
- };
- }(parseFloat));
- }
-
- if (String(new RangeError('test')) !== 'RangeError: test') {
- var errorToStringShim = function toString() {
- if (typeof this === 'undefined' || this === null) {
- throw new TypeError("can't convert " + this + ' to object');
- }
- var name = this.name;
- if (typeof name === 'undefined') {
- name = 'Error';
- } else if (typeof name !== 'string') {
- name = $String(name);
- }
- var msg = this.message;
- if (typeof msg === 'undefined') {
- msg = '';
- } else if (typeof msg !== 'string') {
- msg = $String(msg);
- }
- if (!name) {
- return msg;
- }
- if (!msg) {
- return name;
- }
- return name + ': ' + msg;
- };
- // can't use defineProperties here because of toString enumeration issue in IE <= 8
- Error.prototype.toString = errorToStringShim;
- }
-
- if (supportsDescriptors) {
- var ensureNonEnumerable = function (obj, prop) {
- if (isEnum(obj, prop)) {
- var desc = Object.getOwnPropertyDescriptor(obj, prop);
- if (desc.configurable) {
- desc.enumerable = false;
- Object.defineProperty(obj, prop, desc);
- }
- }
- };
- ensureNonEnumerable(Error.prototype, 'message');
- if (Error.prototype.message !== '') {
- Error.prototype.message = '';
- }
- ensureNonEnumerable(Error.prototype, 'name');
- }
-
- if (String(/a/mig) !== '/a/gim') {
- var regexToString = function toString() {
- var str = '/' + this.source + '/';
- if (this.global) {
- str += 'g';
- }
- if (this.ignoreCase) {
- str += 'i';
- }
- if (this.multiline) {
- str += 'm';
- }
- return str;
- };
- // can't use defineProperties here because of toString enumeration issue in IE <= 8
- RegExp.prototype.toString = regexToString;
- }
-}));
+/*!
+ * https://github.com/es-shims/es5-shim
+ * @license es5-shim Copyright 2009-2015 by contributors, MIT License
+ * see https://github.com/es-shims/es5-shim/blob/master/LICENSE
+ */
+
+// vim: ts=4 sts=4 sw=4 expandtab
+
+// Add semicolon to prevent IIFE from being passed as argument to concatenated code.
+;
+
+// UMD (Universal Module Definition)
+// see https://github.com/umdjs/umd/blob/master/templates/returnExports.js
+(function (root, factory) {
+ 'use strict';
+
+ /* global define, exports, module */
+ if (typeof define === 'function' && define.amd) {
+ // AMD. Register as an anonymous module.
+ define(factory);
+ } else if (typeof exports === 'object') {
+ // Node. Does not work with strict CommonJS, but
+ // only CommonJS-like enviroments that support module.exports,
+ // like Node.
+ module.exports = factory();
+ } else {
+ // Browser globals (root is window)
+ root.returnExports = factory();
+ }
+}(this, function () {
+ /**
+ * Brings an environment as close to ECMAScript 5 compliance
+ * as is possible with the facilities of erstwhile engines.
+ *
+ * Annotated ES5: http://es5.github.com/ (specific links below)
+ * ES5 Spec: http://www.ecma-international.org/publications/files/ECMA-ST/Ecma-262.pdf
+ * Required reading: http://javascriptweblog.wordpress.com/2011/12/05/extending-javascript-natives/
+ */
+
+ // Shortcut to an often accessed properties, in order to avoid multiple
+ // dereference that costs universally. This also holds a reference to known-good
+ // functions.
+ var $Array = Array;
+ var ArrayPrototype = $Array.prototype;
+ var $Object = Object;
+ var ObjectPrototype = $Object.prototype;
+ var $Function = Function;
+ var FunctionPrototype = $Function.prototype;
+ var $String = String;
+ var StringPrototype = $String.prototype;
+ var $Number = Number;
+ var NumberPrototype = $Number.prototype;
+ var array_slice = ArrayPrototype.slice;
+ var array_splice = ArrayPrototype.splice;
+ var array_push = ArrayPrototype.push;
+ var array_unshift = ArrayPrototype.unshift;
+ var array_concat = ArrayPrototype.concat;
+ var array_join = ArrayPrototype.join;
+ var call = FunctionPrototype.call;
+ var apply = FunctionPrototype.apply;
+ var max = Math.max;
+ var min = Math.min;
+
+ // Having a toString local variable name breaks in Opera so use to_string.
+ var to_string = ObjectPrototype.toString;
+
+ /* global Symbol */
+ /* eslint-disable one-var-declaration-per-line, no-redeclare, max-statements-per-line */
+ var hasToStringTag = typeof Symbol === 'function' && typeof Symbol.toStringTag === 'symbol';
+ var isCallable; /* inlined from https://npmjs.com/is-callable */ var fnToStr = Function.prototype.toString, constructorRegex = /^\s*class /, isES6ClassFn = function isES6ClassFn(value) { try { var fnStr = fnToStr.call(value); var singleStripped = fnStr.replace(/\/\/.*\n/g, ''); var multiStripped = singleStripped.replace(/\/\*[.\s\S]*\*\//g, ''); var spaceStripped = multiStripped.replace(/\n/mg, ' ').replace(/ {2}/g, ' '); return constructorRegex.test(spaceStripped); } catch (e) { return false; /* not a function */ } }, tryFunctionObject = function tryFunctionObject(value) { try { if (isES6ClassFn(value)) { return false; } fnToStr.call(value); return true; } catch (e) { return false; } }, fnClass = '[object Function]', genClass = '[object GeneratorFunction]', isCallable = function isCallable(value) { if (!value) { return false; } if (typeof value !== 'function' && typeof value !== 'object') { return false; } if (hasToStringTag) { return tryFunctionObject(value); } if (isES6ClassFn(value)) { return false; } var strClass = to_string.call(value); return strClass === fnClass || strClass === genClass; };
+
+ var isRegex; /* inlined from https://npmjs.com/is-regex */ var regexExec = RegExp.prototype.exec, tryRegexExec = function tryRegexExec(value) { try { regexExec.call(value); return true; } catch (e) { return false; } }, regexClass = '[object RegExp]'; isRegex = function isRegex(value) { if (typeof value !== 'object') { return false; } return hasToStringTag ? tryRegexExec(value) : to_string.call(value) === regexClass; };
+ var isString; /* inlined from https://npmjs.com/is-string */ var strValue = String.prototype.valueOf, tryStringObject = function tryStringObject(value) { try { strValue.call(value); return true; } catch (e) { return false; } }, stringClass = '[object String]'; isString = function isString(value) { if (typeof value === 'string') { return true; } if (typeof value !== 'object') { return false; } return hasToStringTag ? tryStringObject(value) : to_string.call(value) === stringClass; };
+ /* eslint-enable one-var-declaration-per-line, no-redeclare, max-statements-per-line */
+
+ /* inlined from http://npmjs.com/define-properties */
+ var supportsDescriptors = $Object.defineProperty && (function () {
+ try {
+ var obj = {};
+ $Object.defineProperty(obj, 'x', { enumerable: false, value: obj });
+ for (var _ in obj) { // jscs:ignore disallowUnusedVariables
+ return false;
+ }
+ return obj.x === obj;
+ } catch (e) { /* this is ES3 */
+ return false;
+ }
+ }());
+ var defineProperties = (function (has) {
+ // Define configurable, writable, and non-enumerable props
+ // if they don't exist.
+ var defineProperty;
+ if (supportsDescriptors) {
+ defineProperty = function (object, name, method, forceAssign) {
+ if (!forceAssign && (name in object)) {
+ return;
+ }
+ $Object.defineProperty(object, name, {
+ configurable: true,
+ enumerable: false,
+ writable: true,
+ value: method
+ });
+ };
+ } else {
+ defineProperty = function (object, name, method, forceAssign) {
+ if (!forceAssign && (name in object)) {
+ return;
+ }
+ object[name] = method;
+ };
+ }
+ return function defineProperties(object, map, forceAssign) {
+ for (var name in map) {
+ if (has.call(map, name)) {
+ defineProperty(object, name, map[name], forceAssign);
+ }
+ }
+ };
+ }(ObjectPrototype.hasOwnProperty));
+
+ //
+ // Util
+ // ======
+ //
+
+ /* replaceable with https://npmjs.com/package/es-abstract /helpers/isPrimitive */
+ var isPrimitive = function isPrimitive(input) {
+ var type = typeof input;
+ return input === null || (type !== 'object' && type !== 'function');
+ };
+
+ var isActualNaN = $Number.isNaN || function isActualNaN(x) {
+ return x !== x;
+ };
+
+ var ES = {
+ // ES5 9.4
+ // http://es5.github.com/#x9.4
+ // http://jsperf.com/to-integer
+ /* replaceable with https://npmjs.com/package/es-abstract ES5.ToInteger */
+ ToInteger: function ToInteger(num) {
+ var n = +num;
+ if (isActualNaN(n)) {
+ n = 0;
+ } else if (n !== 0 && n !== (1 / 0) && n !== -(1 / 0)) {
+ n = (n > 0 || -1) * Math.floor(Math.abs(n));
+ }
+ return n;
+ },
+
+ /* replaceable with https://npmjs.com/package/es-abstract ES5.ToPrimitive */
+ ToPrimitive: function ToPrimitive(input) {
+ var val, valueOf, toStr;
+ if (isPrimitive(input)) {
+ return input;
+ }
+ valueOf = input.valueOf;
+ if (isCallable(valueOf)) {
+ val = valueOf.call(input);
+ if (isPrimitive(val)) {
+ return val;
+ }
+ }
+ toStr = input.toString;
+ if (isCallable(toStr)) {
+ val = toStr.call(input);
+ if (isPrimitive(val)) {
+ return val;
+ }
+ }
+ throw new TypeError();
+ },
+
+ // ES5 9.9
+ // http://es5.github.com/#x9.9
+ /* replaceable with https://npmjs.com/package/es-abstract ES5.ToObject */
+ ToObject: function (o) {
+ if (o == null) { // this matches both null and undefined
+ throw new TypeError("can't convert " + o + ' to object');
+ }
+ return $Object(o);
+ },
+
+ /* replaceable with https://npmjs.com/package/es-abstract ES5.ToUint32 */
+ ToUint32: function ToUint32(x) {
+ return x >>> 0;
+ }
+ };
+
+ //
+ // Function
+ // ========
+ //
+
+ // ES-5 15.3.4.5
+ // http://es5.github.com/#x15.3.4.5
+
+ var Empty = function Empty() {};
+
+ defineProperties(FunctionPrototype, {
+ bind: function bind(that) { // .length is 1
+ // 1. Let Target be the this value.
+ var target = this;
+ // 2. If IsCallable(Target) is false, throw a TypeError exception.
+ if (!isCallable(target)) {
+ throw new TypeError('Function.prototype.bind called on incompatible ' + target);
+ }
+ // 3. Let A be a new (possibly empty) internal list of all of the
+ // argument values provided after thisArg (arg1, arg2 etc), in order.
+ // XXX slicedArgs will stand in for "A" if used
+ var args = array_slice.call(arguments, 1); // for normal call
+ // 4. Let F be a new native ECMAScript object.
+ // 11. Set the [[Prototype]] internal property of F to the standard
+ // built-in Function prototype object as specified in 15.3.3.1.
+ // 12. Set the [[Call]] internal property of F as described in
+ // 15.3.4.5.1.
+ // 13. Set the [[Construct]] internal property of F as described in
+ // 15.3.4.5.2.
+ // 14. Set the [[HasInstance]] internal property of F as described in
+ // 15.3.4.5.3.
+ var bound;
+ var binder = function () {
+
+ if (this instanceof bound) {
+ // 15.3.4.5.2 [[Construct]]
+ // When the [[Construct]] internal method of a function object,
+ // F that was created using the bind function is called with a
+ // list of arguments ExtraArgs, the following steps are taken:
+ // 1. Let target be the value of F's [[TargetFunction]]
+ // internal property.
+ // 2. If target has no [[Construct]] internal method, a
+ // TypeError exception is thrown.
+ // 3. Let boundArgs be the value of F's [[BoundArgs]] internal
+ // property.
+ // 4. Let args be a new list containing the same values as the
+ // list boundArgs in the same order followed by the same
+ // values as the list ExtraArgs in the same order.
+ // 5. Return the result of calling the [[Construct]] internal
+ // method of target providing args as the arguments.
+
+ var result = apply.call(
+ target,
+ this,
+ array_concat.call(args, array_slice.call(arguments))
+ );
+ if ($Object(result) === result) {
+ return result;
+ }
+ return this;
+
+ } else {
+ // 15.3.4.5.1 [[Call]]
+ // When the [[Call]] internal method of a function object, F,
+ // which was created using the bind function is called with a
+ // this value and a list of arguments ExtraArgs, the following
+ // steps are taken:
+ // 1. Let boundArgs be the value of F's [[BoundArgs]] internal
+ // property.
+ // 2. Let boundThis be the value of F's [[BoundThis]] internal
+ // property.
+ // 3. Let target be the value of F's [[TargetFunction]] internal
+ // property.
+ // 4. Let args be a new list containing the same values as the
+ // list boundArgs in the same order followed by the same
+ // values as the list ExtraArgs in the same order.
+ // 5. Return the result of calling the [[Call]] internal method
+ // of target providing boundThis as the this value and
+ // providing args as the arguments.
+
+ // equiv: target.call(this, ...boundArgs, ...args)
+ return apply.call(
+ target,
+ that,
+ array_concat.call(args, array_slice.call(arguments))
+ );
+
+ }
+
+ };
+
+ // 15. If the [[Class]] internal property of Target is "Function", then
+ // a. Let L be the length property of Target minus the length of A.
+ // b. Set the length own property of F to either 0 or L, whichever is
+ // larger.
+ // 16. Else set the length own property of F to 0.
+
+ var boundLength = max(0, target.length - args.length);
+
+ // 17. Set the attributes of the length own property of F to the values
+ // specified in 15.3.5.1.
+ var boundArgs = [];
+ for (var i = 0; i < boundLength; i++) {
+ array_push.call(boundArgs, '$' + i);
+ }
+
+ // XXX Build a dynamic function with desired amount of arguments is the only
+ // way to set the length property of a function.
+ // In environments where Content Security Policies enabled (Chrome extensions,
+ // for ex.) all use of eval or Function costructor throws an exception.
+ // However in all of these environments Function.prototype.bind exists
+ // and so this code will never be executed.
+ bound = $Function('binder', 'return function (' + array_join.call(boundArgs, ',') + '){ return binder.apply(this, arguments); }')(binder);
+
+ if (target.prototype) {
+ Empty.prototype = target.prototype;
+ bound.prototype = new Empty();
+ // Clean up dangling references.
+ Empty.prototype = null;
+ }
+
+ // TODO
+ // 18. Set the [[Extensible]] internal property of F to true.
+
+ // TODO
+ // 19. Let thrower be the [[ThrowTypeError]] function Object (13.2.3).
+ // 20. Call the [[DefineOwnProperty]] internal method of F with
+ // arguments "caller", PropertyDescriptor {[[Get]]: thrower, [[Set]]:
+ // thrower, [[Enumerable]]: false, [[Configurable]]: false}, and
+ // false.
+ // 21. Call the [[DefineOwnProperty]] internal method of F with
+ // arguments "arguments", PropertyDescriptor {[[Get]]: thrower,
+ // [[Set]]: thrower, [[Enumerable]]: false, [[Configurable]]: false},
+ // and false.
+
+ // TODO
+ // NOTE Function objects created using Function.prototype.bind do not
+ // have a prototype property or the [[Code]], [[FormalParameters]], and
+ // [[Scope]] internal properties.
+ // XXX can't delete prototype in pure-js.
+
+ // 22. Return F.
+ return bound;
+ }
+ });
+
+ // _Please note: Shortcuts are defined after `Function.prototype.bind` as we
+ // use it in defining shortcuts.
+ var owns = call.bind(ObjectPrototype.hasOwnProperty);
+ var toStr = call.bind(ObjectPrototype.toString);
+ var arraySlice = call.bind(array_slice);
+ var arraySliceApply = apply.bind(array_slice);
+ var strSlice = call.bind(StringPrototype.slice);
+ var strSplit = call.bind(StringPrototype.split);
+ var strIndexOf = call.bind(StringPrototype.indexOf);
+ var pushCall = call.bind(array_push);
+ var isEnum = call.bind(ObjectPrototype.propertyIsEnumerable);
+ var arraySort = call.bind(ArrayPrototype.sort);
+
+ //
+ // Array
+ // =====
+ //
+
+ var isArray = $Array.isArray || function isArray(obj) {
+ return toStr(obj) === '[object Array]';
+ };
+
+ // ES5 15.4.4.12
+ // http://es5.github.com/#x15.4.4.13
+ // Return len+argCount.
+ // [bugfix, ielt8]
+ // IE < 8 bug: [].unshift(0) === undefined but should be "1"
+ var hasUnshiftReturnValueBug = [].unshift(0) !== 1;
+ defineProperties(ArrayPrototype, {
+ unshift: function () {
+ array_unshift.apply(this, arguments);
+ return this.length;
+ }
+ }, hasUnshiftReturnValueBug);
+
+ // ES5 15.4.3.2
+ // http://es5.github.com/#x15.4.3.2
+ // https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array/isArray
+ defineProperties($Array, { isArray: isArray });
+
+ // The IsCallable() check in the Array functions
+ // has been replaced with a strict check on the
+ // internal class of the object to trap cases where
+ // the provided function was actually a regular
+ // expression literal, which in V8 and
+ // JavaScriptCore is a typeof "function". Only in
+ // V8 are regular expression literals permitted as
+ // reduce parameters, so it is desirable in the
+ // general case for the shim to match the more
+ // strict and common behavior of rejecting regular
+ // expressions.
+
+ // ES5 15.4.4.18
+ // http://es5.github.com/#x15.4.4.18
+ // https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/array/forEach
+
+ // Check failure of by-index access of string characters (IE < 9)
+ // and failure of `0 in boxedString` (Rhino)
+ var boxedString = $Object('a');
+ var splitString = boxedString[0] !== 'a' || !(0 in boxedString);
+
+ var properlyBoxesContext = function properlyBoxed(method) {
+ // Check node 0.6.21 bug where third parameter is not boxed
+ var properlyBoxesNonStrict = true;
+ var properlyBoxesStrict = true;
+ var threwException = false;
+ if (method) {
+ try {
+ method.call('foo', function (_, __, context) {
+ if (typeof context !== 'object') {
+ properlyBoxesNonStrict = false;
+ }
+ });
+
+ method.call([1], function () {
+ 'use strict';
+
+ properlyBoxesStrict = typeof this === 'string';
+ }, 'x');
+ } catch (e) {
+ threwException = true;
+ }
+ }
+ return !!method && !threwException && properlyBoxesNonStrict && properlyBoxesStrict;
+ };
+
+ defineProperties(ArrayPrototype, {
+ forEach: function forEach(callbackfn/*, thisArg*/) {
+ var object = ES.ToObject(this);
+ var self = splitString && isString(this) ? strSplit(this, '') : object;
+ var i = -1;
+ var length = ES.ToUint32(self.length);
+ var T;
+ if (arguments.length > 1) {
+ T = arguments[1];
+ }
+
+ // If no callback function or if callback is not a callable function
+ if (!isCallable(callbackfn)) {
+ throw new TypeError('Array.prototype.forEach callback must be a function');
+ }
+
+ while (++i < length) {
+ if (i in self) {
+ // Invoke the callback function with call, passing arguments:
+ // context, property value, property key, thisArg object
+ if (typeof T === 'undefined') {
+ callbackfn(self[i], i, object);
+ } else {
+ callbackfn.call(T, self[i], i, object);
+ }
+ }
+ }
+ }
+ }, !properlyBoxesContext(ArrayPrototype.forEach));
+
+ // ES5 15.4.4.19
+ // http://es5.github.com/#x15.4.4.19
+ // https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Objects/Array/map
+ defineProperties(ArrayPrototype, {
+ map: function map(callbackfn/*, thisArg*/) {
+ var object = ES.ToObject(this);
+ var self = splitString && isString(this) ? strSplit(this, '') : object;
+ var length = ES.ToUint32(self.length);
+ var result = $Array(length);
+ var T;
+ if (arguments.length > 1) {
+ T = arguments[1];
+ }
+
+ // If no callback function or if callback is not a callable function
+ if (!isCallable(callbackfn)) {
+ throw new TypeError('Array.prototype.map callback must be a function');
+ }
+
+ for (var i = 0; i < length; i++) {
+ if (i in self) {
+ if (typeof T === 'undefined') {
+ result[i] = callbackfn(self[i], i, object);
+ } else {
+ result[i] = callbackfn.call(T, self[i], i, object);
+ }
+ }
+ }
+ return result;
+ }
+ }, !properlyBoxesContext(ArrayPrototype.map));
+
+ // ES5 15.4.4.20
+ // http://es5.github.com/#x15.4.4.20
+ // https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Objects/Array/filter
+ defineProperties(ArrayPrototype, {
+ filter: function filter(callbackfn/*, thisArg*/) {
+ var object = ES.ToObject(this);
+ var self = splitString && isString(this) ? strSplit(this, '') : object;
+ var length = ES.ToUint32(self.length);
+ var result = [];
+ var value;
+ var T;
+ if (arguments.length > 1) {
+ T = arguments[1];
+ }
+
+ // If no callback function or if callback is not a callable function
+ if (!isCallable(callbackfn)) {
+ throw new TypeError('Array.prototype.filter callback must be a function');
+ }
+
+ for (var i = 0; i < length; i++) {
+ if (i in self) {
+ value = self[i];
+ if (typeof T === 'undefined' ? callbackfn(value, i, object) : callbackfn.call(T, value, i, object)) {
+ pushCall(result, value);
+ }
+ }
+ }
+ return result;
+ }
+ }, !properlyBoxesContext(ArrayPrototype.filter));
+
+ // ES5 15.4.4.16
+ // http://es5.github.com/#x15.4.4.16
+ // https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array/every
+ defineProperties(ArrayPrototype, {
+ every: function every(callbackfn/*, thisArg*/) {
+ var object = ES.ToObject(this);
+ var self = splitString && isString(this) ? strSplit(this, '') : object;
+ var length = ES.ToUint32(self.length);
+ var T;
+ if (arguments.length > 1) {
+ T = arguments[1];
+ }
+
+ // If no callback function or if callback is not a callable function
+ if (!isCallable(callbackfn)) {
+ throw new TypeError('Array.prototype.every callback must be a function');
+ }
+
+ for (var i = 0; i < length; i++) {
+ if (i in self && !(typeof T === 'undefined' ? callbackfn(self[i], i, object) : callbackfn.call(T, self[i], i, object))) {
+ return false;
+ }
+ }
+ return true;
+ }
+ }, !properlyBoxesContext(ArrayPrototype.every));
+
+ // ES5 15.4.4.17
+ // http://es5.github.com/#x15.4.4.17
+ // https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array/some
+ defineProperties(ArrayPrototype, {
+ some: function some(callbackfn/*, thisArg */) {
+ var object = ES.ToObject(this);
+ var self = splitString && isString(this) ? strSplit(this, '') : object;
+ var length = ES.ToUint32(self.length);
+ var T;
+ if (arguments.length > 1) {
+ T = arguments[1];
+ }
+
+ // If no callback function or if callback is not a callable function
+ if (!isCallable(callbackfn)) {
+ throw new TypeError('Array.prototype.some callback must be a function');
+ }
+
+ for (var i = 0; i < length; i++) {
+ if (i in self && (typeof T === 'undefined' ? callbackfn(self[i], i, object) : callbackfn.call(T, self[i], i, object))) {
+ return true;
+ }
+ }
+ return false;
+ }
+ }, !properlyBoxesContext(ArrayPrototype.some));
+
+ // ES5 15.4.4.21
+ // http://es5.github.com/#x15.4.4.21
+ // https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Objects/Array/reduce
+ var reduceCoercesToObject = false;
+ if (ArrayPrototype.reduce) {
+ reduceCoercesToObject = typeof ArrayPrototype.reduce.call('es5', function (_, __, ___, list) {
+ return list;
+ }) === 'object';
+ }
+ defineProperties(ArrayPrototype, {
+ reduce: function reduce(callbackfn/*, initialValue*/) {
+ var object = ES.ToObject(this);
+ var self = splitString && isString(this) ? strSplit(this, '') : object;
+ var length = ES.ToUint32(self.length);
+
+ // If no callback function or if callback is not a callable function
+ if (!isCallable(callbackfn)) {
+ throw new TypeError('Array.prototype.reduce callback must be a function');
+ }
+
+ // no value to return if no initial value and an empty array
+ if (length === 0 && arguments.length === 1) {
+ throw new TypeError('reduce of empty array with no initial value');
+ }
+
+ var i = 0;
+ var result;
+ if (arguments.length >= 2) {
+ result = arguments[1];
+ } else {
+ do {
+ if (i in self) {
+ result = self[i++];
+ break;
+ }
+
+ // if array contains no values, no initial value to return
+ if (++i >= length) {
+ throw new TypeError('reduce of empty array with no initial value');
+ }
+ } while (true);
+ }
+
+ for (; i < length; i++) {
+ if (i in self) {
+ result = callbackfn(result, self[i], i, object);
+ }
+ }
+
+ return result;
+ }
+ }, !reduceCoercesToObject);
+
+ // ES5 15.4.4.22
+ // http://es5.github.com/#x15.4.4.22
+ // https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Objects/Array/reduceRight
+ var reduceRightCoercesToObject = false;
+ if (ArrayPrototype.reduceRight) {
+ reduceRightCoercesToObject = typeof ArrayPrototype.reduceRight.call('es5', function (_, __, ___, list) {
+ return list;
+ }) === 'object';
+ }
+ defineProperties(ArrayPrototype, {
+ reduceRight: function reduceRight(callbackfn/*, initial*/) {
+ var object = ES.ToObject(this);
+ var self = splitString && isString(this) ? strSplit(this, '') : object;
+ var length = ES.ToUint32(self.length);
+
+ // If no callback function or if callback is not a callable function
+ if (!isCallable(callbackfn)) {
+ throw new TypeError('Array.prototype.reduceRight callback must be a function');
+ }
+
+ // no value to return if no initial value, empty array
+ if (length === 0 && arguments.length === 1) {
+ throw new TypeError('reduceRight of empty array with no initial value');
+ }
+
+ var result;
+ var i = length - 1;
+ if (arguments.length >= 2) {
+ result = arguments[1];
+ } else {
+ do {
+ if (i in self) {
+ result = self[i--];
+ break;
+ }
+
+ // if array contains no values, no initial value to return
+ if (--i < 0) {
+ throw new TypeError('reduceRight of empty array with no initial value');
+ }
+ } while (true);
+ }
+
+ if (i < 0) {
+ return result;
+ }
+
+ do {
+ if (i in self) {
+ result = callbackfn(result, self[i], i, object);
+ }
+ } while (i--);
+
+ return result;
+ }
+ }, !reduceRightCoercesToObject);
+
+ // ES5 15.4.4.14
+ // http://es5.github.com/#x15.4.4.14
+ // https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array/indexOf
+ var hasFirefox2IndexOfBug = ArrayPrototype.indexOf && [0, 1].indexOf(1, 2) !== -1;
+ defineProperties(ArrayPrototype, {
+ indexOf: function indexOf(searchElement/*, fromIndex */) {
+ var self = splitString && isString(this) ? strSplit(this, '') : ES.ToObject(this);
+ var length = ES.ToUint32(self.length);
+
+ if (length === 0) {
+ return -1;
+ }
+
+ var i = 0;
+ if (arguments.length > 1) {
+ i = ES.ToInteger(arguments[1]);
+ }
+
+ // handle negative indices
+ i = i >= 0 ? i : max(0, length + i);
+ for (; i < length; i++) {
+ if (i in self && self[i] === searchElement) {
+ return i;
+ }
+ }
+ return -1;
+ }
+ }, hasFirefox2IndexOfBug);
+
+ // ES5 15.4.4.15
+ // http://es5.github.com/#x15.4.4.15
+ // https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array/lastIndexOf
+ var hasFirefox2LastIndexOfBug = ArrayPrototype.lastIndexOf && [0, 1].lastIndexOf(0, -3) !== -1;
+ defineProperties(ArrayPrototype, {
+ lastIndexOf: function lastIndexOf(searchElement/*, fromIndex */) {
+ var self = splitString && isString(this) ? strSplit(this, '') : ES.ToObject(this);
+ var length = ES.ToUint32(self.length);
+
+ if (length === 0) {
+ return -1;
+ }
+ var i = length - 1;
+ if (arguments.length > 1) {
+ i = min(i, ES.ToInteger(arguments[1]));
+ }
+ // handle negative indices
+ i = i >= 0 ? i : length - Math.abs(i);
+ for (; i >= 0; i--) {
+ if (i in self && searchElement === self[i]) {
+ return i;
+ }
+ }
+ return -1;
+ }
+ }, hasFirefox2LastIndexOfBug);
+
+ // ES5 15.4.4.12
+ // http://es5.github.com/#x15.4.4.12
+ var spliceNoopReturnsEmptyArray = (function () {
+ var a = [1, 2];
+ var result = a.splice();
+ return a.length === 2 && isArray(result) && result.length === 0;
+ }());
+ defineProperties(ArrayPrototype, {
+ // Safari 5.0 bug where .splice() returns undefined
+ splice: function splice(start, deleteCount) {
+ if (arguments.length === 0) {
+ return [];
+ } else {
+ return array_splice.apply(this, arguments);
+ }
+ }
+ }, !spliceNoopReturnsEmptyArray);
+
+ var spliceWorksWithEmptyObject = (function () {
+ var obj = {};
+ ArrayPrototype.splice.call(obj, 0, 0, 1);
+ return obj.length === 1;
+ }());
+ defineProperties(ArrayPrototype, {
+ splice: function splice(start, deleteCount) {
+ if (arguments.length === 0) {
+ return [];
+ }
+ var args = arguments;
+ this.length = max(ES.ToInteger(this.length), 0);
+ if (arguments.length > 0 && typeof deleteCount !== 'number') {
+ args = arraySlice(arguments);
+ if (args.length < 2) {
+ pushCall(args, this.length - start);
+ } else {
+ args[1] = ES.ToInteger(deleteCount);
+ }
+ }
+ return array_splice.apply(this, args);
+ }
+ }, !spliceWorksWithEmptyObject);
+ var spliceWorksWithLargeSparseArrays = (function () {
+ // Per https://github.com/es-shims/es5-shim/issues/295
+ // Safari 7/8 breaks with sparse arrays of size 1e5 or greater
+ var arr = new $Array(1e5);
+ // note: the index MUST be 8 or larger or the test will false pass
+ arr[8] = 'x';
+ arr.splice(1, 1);
+ // note: this test must be defined *after* the indexOf shim
+ // per https://github.com/es-shims/es5-shim/issues/313
+ return arr.indexOf('x') === 7;
+ }());
+ var spliceWorksWithSmallSparseArrays = (function () {
+ // Per https://github.com/es-shims/es5-shim/issues/295
+ // Opera 12.15 breaks on this, no idea why.
+ var n = 256;
+ var arr = [];
+ arr[n] = 'a';
+ arr.splice(n + 1, 0, 'b');
+ return arr[n] === 'a';
+ }());
+ defineProperties(ArrayPrototype, {
+ splice: function splice(start, deleteCount) {
+ var O = ES.ToObject(this);
+ var A = [];
+ var len = ES.ToUint32(O.length);
+ var relativeStart = ES.ToInteger(start);
+ var actualStart = relativeStart < 0 ? max((len + relativeStart), 0) : min(relativeStart, len);
+ var actualDeleteCount = min(max(ES.ToInteger(deleteCount), 0), len - actualStart);
+
+ var k = 0;
+ var from;
+ while (k < actualDeleteCount) {
+ from = $String(actualStart + k);
+ if (owns(O, from)) {
+ A[k] = O[from];
+ }
+ k += 1;
+ }
+
+ var items = arraySlice(arguments, 2);
+ var itemCount = items.length;
+ var to;
+ if (itemCount < actualDeleteCount) {
+ k = actualStart;
+ var maxK = len - actualDeleteCount;
+ while (k < maxK) {
+ from = $String(k + actualDeleteCount);
+ to = $String(k + itemCount);
+ if (owns(O, from)) {
+ O[to] = O[from];
+ } else {
+ delete O[to];
+ }
+ k += 1;
+ }
+ k = len;
+ var minK = len - actualDeleteCount + itemCount;
+ while (k > minK) {
+ delete O[k - 1];
+ k -= 1;
+ }
+ } else if (itemCount > actualDeleteCount) {
+ k = len - actualDeleteCount;
+ while (k > actualStart) {
+ from = $String(k + actualDeleteCount - 1);
+ to = $String(k + itemCount - 1);
+ if (owns(O, from)) {
+ O[to] = O[from];
+ } else {
+ delete O[to];
+ }
+ k -= 1;
+ }
+ }
+ k = actualStart;
+ for (var i = 0; i < items.length; ++i) {
+ O[k] = items[i];
+ k += 1;
+ }
+ O.length = len - actualDeleteCount + itemCount;
+
+ return A;
+ }
+ }, !spliceWorksWithLargeSparseArrays || !spliceWorksWithSmallSparseArrays);
+
+ var originalJoin = ArrayPrototype.join;
+ var hasStringJoinBug;
+ try {
+ hasStringJoinBug = Array.prototype.join.call('123', ',') !== '1,2,3';
+ } catch (e) {
+ hasStringJoinBug = true;
+ }
+ if (hasStringJoinBug) {
+ defineProperties(ArrayPrototype, {
+ join: function join(separator) {
+ var sep = typeof separator === 'undefined' ? ',' : separator;
+ return originalJoin.call(isString(this) ? strSplit(this, '') : this, sep);
+ }
+ }, hasStringJoinBug);
+ }
+
+ var hasJoinUndefinedBug = [1, 2].join(undefined) !== '1,2';
+ if (hasJoinUndefinedBug) {
+ defineProperties(ArrayPrototype, {
+ join: function join(separator) {
+ var sep = typeof separator === 'undefined' ? ',' : separator;
+ return originalJoin.call(this, sep);
+ }
+ }, hasJoinUndefinedBug);
+ }
+
+ var pushShim = function push(item) {
+ var O = ES.ToObject(this);
+ var n = ES.ToUint32(O.length);
+ var i = 0;
+ while (i < arguments.length) {
+ O[n + i] = arguments[i];
+ i += 1;
+ }
+ O.length = n + i;
+ return n + i;
+ };
+
+ var pushIsNotGeneric = (function () {
+ var obj = {};
+ var result = Array.prototype.push.call(obj, undefined);
+ return result !== 1 || obj.length !== 1 || typeof obj[0] !== 'undefined' || !owns(obj, 0);
+ }());
+ defineProperties(ArrayPrototype, {
+ push: function push(item) {
+ if (isArray(this)) {
+ return array_push.apply(this, arguments);
+ }
+ return pushShim.apply(this, arguments);
+ }
+ }, pushIsNotGeneric);
+
+ // This fixes a very weird bug in Opera 10.6 when pushing `undefined
+ var pushUndefinedIsWeird = (function () {
+ var arr = [];
+ var result = arr.push(undefined);
+ return result !== 1 || arr.length !== 1 || typeof arr[0] !== 'undefined' || !owns(arr, 0);
+ }());
+ defineProperties(ArrayPrototype, { push: pushShim }, pushUndefinedIsWeird);
+
+ // ES5 15.2.3.14
+ // http://es5.github.io/#x15.4.4.10
+ // Fix boxed string bug
+ defineProperties(ArrayPrototype, {
+ slice: function (start, end) {
+ var arr = isString(this) ? strSplit(this, '') : this;
+ return arraySliceApply(arr, arguments);
+ }
+ }, splitString);
+
+ var sortIgnoresNonFunctions = (function () {
+ try {
+ [1, 2].sort(null);
+ [1, 2].sort({});
+ return true;
+ } catch (e) {}
+ return false;
+ }());
+ var sortThrowsOnRegex = (function () {
+ // this is a problem in Firefox 4, in which `typeof /a/ === 'function'`
+ try {
+ [1, 2].sort(/a/);
+ return false;
+ } catch (e) {}
+ return true;
+ }());
+ var sortIgnoresUndefined = (function () {
+ // applies in IE 8, for one.
+ try {
+ [1, 2].sort(undefined);
+ return true;
+ } catch (e) {}
+ return false;
+ }());
+ defineProperties(ArrayPrototype, {
+ sort: function sort(compareFn) {
+ if (typeof compareFn === 'undefined') {
+ return arraySort(this);
+ }
+ if (!isCallable(compareFn)) {
+ throw new TypeError('Array.prototype.sort callback must be a function');
+ }
+ return arraySort(this, compareFn);
+ }
+ }, sortIgnoresNonFunctions || !sortIgnoresUndefined || !sortThrowsOnRegex);
+
+ //
+ // Object
+ // ======
+ //
+
+ // ES5 15.2.3.14
+ // http://es5.github.com/#x15.2.3.14
+
+ // http://whattheheadsaid.com/2010/10/a-safer-object-keys-compatibility-implementation
+ var hasDontEnumBug = !isEnum({ 'toString': null }, 'toString');
+ var hasProtoEnumBug = isEnum(function () {}, 'prototype');
+ var hasStringEnumBug = !owns('x', '0');
+ var equalsConstructorPrototype = function (o) {
+ var ctor = o.constructor;
+ return ctor && ctor.prototype === o;
+ };
+ var blacklistedKeys = {
+ $window: true,
+ $console: true,
+ $parent: true,
+ $self: true,
+ $frame: true,
+ $frames: true,
+ $frameElement: true,
+ $webkitIndexedDB: true,
+ $webkitStorageInfo: true,
+ $external: true
+ };
+ var hasAutomationEqualityBug = (function () {
+ /* globals window */
+ if (typeof window === 'undefined') {
+ return false;
+ }
+ for (var k in window) {
+ try {
+ if (!blacklistedKeys['$' + k] && owns(window, k) && window[k] !== null && typeof window[k] === 'object') {
+ equalsConstructorPrototype(window[k]);
+ }
+ } catch (e) {
+ return true;
+ }
+ }
+ return false;
+ }());
+ var equalsConstructorPrototypeIfNotBuggy = function (object) {
+ if (typeof window === 'undefined' || !hasAutomationEqualityBug) {
+ return equalsConstructorPrototype(object);
+ }
+ try {
+ return equalsConstructorPrototype(object);
+ } catch (e) {
+ return false;
+ }
+ };
+ var dontEnums = [
+ 'toString',
+ 'toLocaleString',
+ 'valueOf',
+ 'hasOwnProperty',
+ 'isPrototypeOf',
+ 'propertyIsEnumerable',
+ 'constructor'
+ ];
+ var dontEnumsLength = dontEnums.length;
+
+ // taken directly from https://github.com/ljharb/is-arguments/blob/master/index.js
+ // can be replaced with require('is-arguments') if we ever use a build process instead
+ var isStandardArguments = function isArguments(value) {
+ return toStr(value) === '[object Arguments]';
+ };
+ var isLegacyArguments = function isArguments(value) {
+ return value !== null &&
+ typeof value === 'object' &&
+ typeof value.length === 'number' &&
+ value.length >= 0 &&
+ !isArray(value) &&
+ isCallable(value.callee);
+ };
+ var isArguments = isStandardArguments(arguments) ? isStandardArguments : isLegacyArguments;
+
+ defineProperties($Object, {
+ keys: function keys(object) {
+ var isFn = isCallable(object);
+ var isArgs = isArguments(object);
+ var isObject = object !== null && typeof object === 'object';
+ var isStr = isObject && isString(object);
+
+ if (!isObject && !isFn && !isArgs) {
+ throw new TypeError('Object.keys called on a non-object');
+ }
+
+ var theKeys = [];
+ var skipProto = hasProtoEnumBug && isFn;
+ if ((isStr && hasStringEnumBug) || isArgs) {
+ for (var i = 0; i < object.length; ++i) {
+ pushCall(theKeys, $String(i));
+ }
+ }
+
+ if (!isArgs) {
+ for (var name in object) {
+ if (!(skipProto && name === 'prototype') && owns(object, name)) {
+ pushCall(theKeys, $String(name));
+ }
+ }
+ }
+
+ if (hasDontEnumBug) {
+ var skipConstructor = equalsConstructorPrototypeIfNotBuggy(object);
+ for (var j = 0; j < dontEnumsLength; j++) {
+ var dontEnum = dontEnums[j];
+ if (!(skipConstructor && dontEnum === 'constructor') && owns(object, dontEnum)) {
+ pushCall(theKeys, dontEnum);
+ }
+ }
+ }
+ return theKeys;
+ }
+ });
+
+ var keysWorksWithArguments = $Object.keys && (function () {
+ // Safari 5.0 bug
+ return $Object.keys(arguments).length === 2;
+ }(1, 2));
+ var keysHasArgumentsLengthBug = $Object.keys && (function () {
+ var argKeys = $Object.keys(arguments);
+ return arguments.length !== 1 || argKeys.length !== 1 || argKeys[0] !== 1;
+ }(1));
+ var originalKeys = $Object.keys;
+ defineProperties($Object, {
+ keys: function keys(object) {
+ if (isArguments(object)) {
+ return originalKeys(arraySlice(object));
+ } else {
+ return originalKeys(object);
+ }
+ }
+ }, !keysWorksWithArguments || keysHasArgumentsLengthBug);
+
+ //
+ // Date
+ // ====
+ //
+
+ var hasNegativeMonthYearBug = new Date(-3509827329600292).getUTCMonth() !== 0;
+ var aNegativeTestDate = new Date(-1509842289600292);
+ var aPositiveTestDate = new Date(1449662400000);
+ var hasToUTCStringFormatBug = aNegativeTestDate.toUTCString() !== 'Mon, 01 Jan -45875 11:59:59 GMT';
+ var hasToDateStringFormatBug;
+ var hasToStringFormatBug;
+ var timeZoneOffset = aNegativeTestDate.getTimezoneOffset();
+ if (timeZoneOffset < -720) {
+ hasToDateStringFormatBug = aNegativeTestDate.toDateString() !== 'Tue Jan 02 -45875';
+ hasToStringFormatBug = !(/^Thu Dec 10 2015 \d\d:\d\d:\d\d GMT[-\+]\d\d\d\d(?: |$)/).test(aPositiveTestDate.toString());
+ } else {
+ hasToDateStringFormatBug = aNegativeTestDate.toDateString() !== 'Mon Jan 01 -45875';
+ hasToStringFormatBug = !(/^Wed Dec 09 2015 \d\d:\d\d:\d\d GMT[-\+]\d\d\d\d(?: |$)/).test(aPositiveTestDate.toString());
+ }
+
+ var originalGetFullYear = call.bind(Date.prototype.getFullYear);
+ var originalGetMonth = call.bind(Date.prototype.getMonth);
+ var originalGetDate = call.bind(Date.prototype.getDate);
+ var originalGetUTCFullYear = call.bind(Date.prototype.getUTCFullYear);
+ var originalGetUTCMonth = call.bind(Date.prototype.getUTCMonth);
+ var originalGetUTCDate = call.bind(Date.prototype.getUTCDate);
+ var originalGetUTCDay = call.bind(Date.prototype.getUTCDay);
+ var originalGetUTCHours = call.bind(Date.prototype.getUTCHours);
+ var originalGetUTCMinutes = call.bind(Date.prototype.getUTCMinutes);
+ var originalGetUTCSeconds = call.bind(Date.prototype.getUTCSeconds);
+ var originalGetUTCMilliseconds = call.bind(Date.prototype.getUTCMilliseconds);
+ var dayName = ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'];
+ var monthName = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'];
+ var daysInMonth = function daysInMonth(month, year) {
+ return originalGetDate(new Date(year, month, 0));
+ };
+
+ defineProperties(Date.prototype, {
+ getFullYear: function getFullYear() {
+ if (!this || !(this instanceof Date)) {
+ throw new TypeError('this is not a Date object.');
+ }
+ var year = originalGetFullYear(this);
+ if (year < 0 && originalGetMonth(this) > 11) {
+ return year + 1;
+ }
+ return year;
+ },
+ getMonth: function getMonth() {
+ if (!this || !(this instanceof Date)) {
+ throw new TypeError('this is not a Date object.');
+ }
+ var year = originalGetFullYear(this);
+ var month = originalGetMonth(this);
+ if (year < 0 && month > 11) {
+ return 0;
+ }
+ return month;
+ },
+ getDate: function getDate() {
+ if (!this || !(this instanceof Date)) {
+ throw new TypeError('this is not a Date object.');
+ }
+ var year = originalGetFullYear(this);
+ var month = originalGetMonth(this);
+ var date = originalGetDate(this);
+ if (year < 0 && month > 11) {
+ if (month === 12) {
+ return date;
+ }
+ var days = daysInMonth(0, year + 1);
+ return (days - date) + 1;
+ }
+ return date;
+ },
+ getUTCFullYear: function getUTCFullYear() {
+ if (!this || !(this instanceof Date)) {
+ throw new TypeError('this is not a Date object.');
+ }
+ var year = originalGetUTCFullYear(this);
+ if (year < 0 && originalGetUTCMonth(this) > 11) {
+ return year + 1;
+ }
+ return year;
+ },
+ getUTCMonth: function getUTCMonth() {
+ if (!this || !(this instanceof Date)) {
+ throw new TypeError('this is not a Date object.');
+ }
+ var year = originalGetUTCFullYear(this);
+ var month = originalGetUTCMonth(this);
+ if (year < 0 && month > 11) {
+ return 0;
+ }
+ return month;
+ },
+ getUTCDate: function getUTCDate() {
+ if (!this || !(this instanceof Date)) {
+ throw new TypeError('this is not a Date object.');
+ }
+ var year = originalGetUTCFullYear(this);
+ var month = originalGetUTCMonth(this);
+ var date = originalGetUTCDate(this);
+ if (year < 0 && month > 11) {
+ if (month === 12) {
+ return date;
+ }
+ var days = daysInMonth(0, year + 1);
+ return (days - date) + 1;
+ }
+ return date;
+ }
+ }, hasNegativeMonthYearBug);
+
+ defineProperties(Date.prototype, {
+ toUTCString: function toUTCString() {
+ if (!this || !(this instanceof Date)) {
+ throw new TypeError('this is not a Date object.');
+ }
+ var day = originalGetUTCDay(this);
+ var date = originalGetUTCDate(this);
+ var month = originalGetUTCMonth(this);
+ var year = originalGetUTCFullYear(this);
+ var hour = originalGetUTCHours(this);
+ var minute = originalGetUTCMinutes(this);
+ var second = originalGetUTCSeconds(this);
+ return dayName[day] + ', ' +
+ (date < 10 ? '0' + date : date) + ' ' +
+ monthName[month] + ' ' +
+ year + ' ' +
+ (hour < 10 ? '0' + hour : hour) + ':' +
+ (minute < 10 ? '0' + minute : minute) + ':' +
+ (second < 10 ? '0' + second : second) + ' GMT';
+ }
+ }, hasNegativeMonthYearBug || hasToUTCStringFormatBug);
+
+ // Opera 12 has `,`
+ defineProperties(Date.prototype, {
+ toDateString: function toDateString() {
+ if (!this || !(this instanceof Date)) {
+ throw new TypeError('this is not a Date object.');
+ }
+ var day = this.getDay();
+ var date = this.getDate();
+ var month = this.getMonth();
+ var year = this.getFullYear();
+ return dayName[day] + ' ' +
+ monthName[month] + ' ' +
+ (date < 10 ? '0' + date : date) + ' ' +
+ year;
+ }
+ }, hasNegativeMonthYearBug || hasToDateStringFormatBug);
+
+ // can't use defineProperties here because of toString enumeration issue in IE <= 8
+ if (hasNegativeMonthYearBug || hasToStringFormatBug) {
+ Date.prototype.toString = function toString() {
+ if (!this || !(this instanceof Date)) {
+ throw new TypeError('this is not a Date object.');
+ }
+ var day = this.getDay();
+ var date = this.getDate();
+ var month = this.getMonth();
+ var year = this.getFullYear();
+ var hour = this.getHours();
+ var minute = this.getMinutes();
+ var second = this.getSeconds();
+ var timezoneOffset = this.getTimezoneOffset();
+ var hoursOffset = Math.floor(Math.abs(timezoneOffset) / 60);
+ var minutesOffset = Math.floor(Math.abs(timezoneOffset) % 60);
+ return dayName[day] + ' ' +
+ monthName[month] + ' ' +
+ (date < 10 ? '0' + date : date) + ' ' +
+ year + ' ' +
+ (hour < 10 ? '0' + hour : hour) + ':' +
+ (minute < 10 ? '0' + minute : minute) + ':' +
+ (second < 10 ? '0' + second : second) + ' GMT' +
+ (timezoneOffset > 0 ? '-' : '+') +
+ (hoursOffset < 10 ? '0' + hoursOffset : hoursOffset) +
+ (minutesOffset < 10 ? '0' + minutesOffset : minutesOffset);
+ };
+ if (supportsDescriptors) {
+ $Object.defineProperty(Date.prototype, 'toString', {
+ configurable: true,
+ enumerable: false,
+ writable: true
+ });
+ }
+ }
+
+ // ES5 15.9.5.43
+ // http://es5.github.com/#x15.9.5.43
+ // This function returns a String value represent the instance in time
+ // represented by this Date object. The format of the String is the Date Time
+ // string format defined in 15.9.1.15. All fields are present in the String.
+ // The time zone is always UTC, denoted by the suffix Z. If the time value of
+ // this object is not a finite Number a RangeError exception is thrown.
+ var negativeDate = -62198755200000;
+ var negativeYearString = '-000001';
+ var hasNegativeDateBug = Date.prototype.toISOString && new Date(negativeDate).toISOString().indexOf(negativeYearString) === -1;
+ var hasSafari51DateBug = Date.prototype.toISOString && new Date(-1).toISOString() !== '1969-12-31T23:59:59.999Z';
+
+ var getTime = call.bind(Date.prototype.getTime);
+
+ defineProperties(Date.prototype, {
+ toISOString: function toISOString() {
+ if (!isFinite(this) || !isFinite(getTime(this))) {
+ // Adope Photoshop requires the second check.
+ throw new RangeError('Date.prototype.toISOString called on non-finite value.');
+ }
+
+ var year = originalGetUTCFullYear(this);
+
+ var month = originalGetUTCMonth(this);
+ // see https://github.com/es-shims/es5-shim/issues/111
+ year += Math.floor(month / 12);
+ month = (month % 12 + 12) % 12;
+
+ // the date time string format is specified in 15.9.1.15.
+ var result = [month + 1, originalGetUTCDate(this), originalGetUTCHours(this), originalGetUTCMinutes(this), originalGetUTCSeconds(this)];
+ year = (
+ (year < 0 ? '-' : (year > 9999 ? '+' : '')) +
+ strSlice('00000' + Math.abs(year), (0 <= year && year <= 9999) ? -4 : -6)
+ );
+
+ for (var i = 0; i < result.length; ++i) {
+ // pad months, days, hours, minutes, and seconds to have two digits.
+ result[i] = strSlice('00' + result[i], -2);
+ }
+ // pad milliseconds to have three digits.
+ return (
+ year + '-' + arraySlice(result, 0, 2).join('-') +
+ 'T' + arraySlice(result, 2).join(':') + '.' +
+ strSlice('000' + originalGetUTCMilliseconds(this), -3) + 'Z'
+ );
+ }
+ }, hasNegativeDateBug || hasSafari51DateBug);
+
+ // ES5 15.9.5.44
+ // http://es5.github.com/#x15.9.5.44
+ // This function provides a String representation of a Date object for use by
+ // JSON.stringify (15.12.3).
+ var dateToJSONIsSupported = (function () {
+ try {
+ return Date.prototype.toJSON &&
+ new Date(NaN).toJSON() === null &&
+ new Date(negativeDate).toJSON().indexOf(negativeYearString) !== -1 &&
+ Date.prototype.toJSON.call({ // generic
+ toISOString: function () { return true; }
+ });
+ } catch (e) {
+ return false;
+ }
+ }());
+ if (!dateToJSONIsSupported) {
+ Date.prototype.toJSON = function toJSON(key) {
+ // When the toJSON method is called with argument key, the following
+ // steps are taken:
+
+ // 1. Let O be the result of calling ToObject, giving it the this
+ // value as its argument.
+ // 2. Let tv be ES.ToPrimitive(O, hint Number).
+ var O = $Object(this);
+ var tv = ES.ToPrimitive(O);
+ // 3. If tv is a Number and is not finite, return null.
+ if (typeof tv === 'number' && !isFinite(tv)) {
+ return null;
+ }
+ // 4. Let toISO be the result of calling the [[Get]] internal method of
+ // O with argument "toISOString".
+ var toISO = O.toISOString;
+ // 5. If IsCallable(toISO) is false, throw a TypeError exception.
+ if (!isCallable(toISO)) {
+ throw new TypeError('toISOString property is not callable');
+ }
+ // 6. Return the result of calling the [[Call]] internal method of
+ // toISO with O as the this value and an empty argument list.
+ return toISO.call(O);
+
+ // NOTE 1 The argument is ignored.
+
+ // NOTE 2 The toJSON function is intentionally generic; it does not
+ // require that its this value be a Date object. Therefore, it can be
+ // transferred to other kinds of objects for use as a method. However,
+ // it does require that any such object have a toISOString method. An
+ // object is free to use the argument key to filter its
+ // stringification.
+ };
+ }
+
+ // ES5 15.9.4.2
+ // http://es5.github.com/#x15.9.4.2
+ // based on work shared by Daniel Friesen (dantman)
+ // http://gist.github.com/303249
+ var supportsExtendedYears = Date.parse('+033658-09-27T01:46:40.000Z') === 1e15;
+ var acceptsInvalidDates = !isNaN(Date.parse('2012-04-04T24:00:00.500Z')) || !isNaN(Date.parse('2012-11-31T23:59:59.000Z')) || !isNaN(Date.parse('2012-12-31T23:59:60.000Z'));
+ var doesNotParseY2KNewYear = isNaN(Date.parse('2000-01-01T00:00:00.000Z'));
+ if (doesNotParseY2KNewYear || acceptsInvalidDates || !supportsExtendedYears) {
+ // XXX global assignment won't work in embeddings that use
+ // an alternate object for the context.
+ /* global Date: true */
+ /* eslint-disable no-undef */
+ var maxSafeUnsigned32Bit = Math.pow(2, 31) - 1;
+ var hasSafariSignedIntBug = isActualNaN(new Date(1970, 0, 1, 0, 0, 0, maxSafeUnsigned32Bit + 1).getTime());
+ /* eslint-disable no-implicit-globals */
+ Date = (function (NativeDate) {
+ /* eslint-enable no-implicit-globals */
+ /* eslint-enable no-undef */
+ // Date.length === 7
+ var DateShim = function Date(Y, M, D, h, m, s, ms) {
+ var length = arguments.length;
+ var date;
+ if (this instanceof NativeDate) {
+ var seconds = s;
+ var millis = ms;
+ if (hasSafariSignedIntBug && length >= 7 && ms > maxSafeUnsigned32Bit) {
+ // work around a Safari 8/9 bug where it treats the seconds as signed
+ var msToShift = Math.floor(ms / maxSafeUnsigned32Bit) * maxSafeUnsigned32Bit;
+ var sToShift = Math.floor(msToShift / 1e3);
+ seconds += sToShift;
+ millis -= sToShift * 1e3;
+ }
+ date = length === 1 && $String(Y) === Y ? // isString(Y)
+ // We explicitly pass it through parse:
+ new NativeDate(DateShim.parse(Y)) :
+ // We have to manually make calls depending on argument
+ // length here
+ length >= 7 ? new NativeDate(Y, M, D, h, m, seconds, millis) :
+ length >= 6 ? new NativeDate(Y, M, D, h, m, seconds) :
+ length >= 5 ? new NativeDate(Y, M, D, h, m) :
+ length >= 4 ? new NativeDate(Y, M, D, h) :
+ length >= 3 ? new NativeDate(Y, M, D) :
+ length >= 2 ? new NativeDate(Y, M) :
+ length >= 1 ? new NativeDate(Y instanceof NativeDate ? +Y : Y) :
+ new NativeDate();
+ } else {
+ date = NativeDate.apply(this, arguments);
+ }
+ if (!isPrimitive(date)) {
+ // Prevent mixups with unfixed Date object
+ defineProperties(date, { constructor: DateShim }, true);
+ }
+ return date;
+ };
+
+ // 15.9.1.15 Date Time String Format.
+ var isoDateExpression = new RegExp('^' +
+ '(\\d{4}|[+-]\\d{6})' + // four-digit year capture or sign +
+ // 6-digit extended year
+ '(?:-(\\d{2})' + // optional month capture
+ '(?:-(\\d{2})' + // optional day capture
+ '(?:' + // capture hours:minutes:seconds.milliseconds
+ 'T(\\d{2})' + // hours capture
+ ':(\\d{2})' + // minutes capture
+ '(?:' + // optional :seconds.milliseconds
+ ':(\\d{2})' + // seconds capture
+ '(?:(\\.\\d{1,}))?' + // milliseconds capture
+ ')?' +
+ '(' + // capture UTC offset component
+ 'Z|' + // UTC capture
+ '(?:' + // offset specifier +/-hours:minutes
+ '([-+])' + // sign capture
+ '(\\d{2})' + // hours offset capture
+ ':(\\d{2})' + // minutes offset capture
+ ')' +
+ ')?)?)?)?' +
+ '$');
+
+ var months = [0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365];
+
+ var dayFromMonth = function dayFromMonth(year, month) {
+ var t = month > 1 ? 1 : 0;
+ return (
+ months[month] +
+ Math.floor((year - 1969 + t) / 4) -
+ Math.floor((year - 1901 + t) / 100) +
+ Math.floor((year - 1601 + t) / 400) +
+ 365 * (year - 1970)
+ );
+ };
+
+ var toUTC = function toUTC(t) {
+ var s = 0;
+ var ms = t;
+ if (hasSafariSignedIntBug && ms > maxSafeUnsigned32Bit) {
+ // work around a Safari 8/9 bug where it treats the seconds as signed
+ var msToShift = Math.floor(ms / maxSafeUnsigned32Bit) * maxSafeUnsigned32Bit;
+ var sToShift = Math.floor(msToShift / 1e3);
+ s += sToShift;
+ ms -= sToShift * 1e3;
+ }
+ return $Number(new NativeDate(1970, 0, 1, 0, 0, s, ms));
+ };
+
+ // Copy any custom methods a 3rd party library may have added
+ for (var key in NativeDate) {
+ if (owns(NativeDate, key)) {
+ DateShim[key] = NativeDate[key];
+ }
+ }
+
+ // Copy "native" methods explicitly; they may be non-enumerable
+ defineProperties(DateShim, {
+ now: NativeDate.now,
+ UTC: NativeDate.UTC
+ }, true);
+ DateShim.prototype = NativeDate.prototype;
+ defineProperties(DateShim.prototype, {
+ constructor: DateShim
+ }, true);
+
+ // Upgrade Date.parse to handle simplified ISO 8601 strings
+ var parseShim = function parse(string) {
+ var match = isoDateExpression.exec(string);
+ if (match) {
+ // parse months, days, hours, minutes, seconds, and milliseconds
+ // provide default values if necessary
+ // parse the UTC offset component
+ var year = $Number(match[1]),
+ month = $Number(match[2] || 1) - 1,
+ day = $Number(match[3] || 1) - 1,
+ hour = $Number(match[4] || 0),
+ minute = $Number(match[5] || 0),
+ second = $Number(match[6] || 0),
+ millisecond = Math.floor($Number(match[7] || 0) * 1000),
+ // When time zone is missed, local offset should be used
+ // (ES 5.1 bug)
+ // see https://bugs.ecmascript.org/show_bug.cgi?id=112
+ isLocalTime = Boolean(match[4] && !match[8]),
+ signOffset = match[9] === '-' ? 1 : -1,
+ hourOffset = $Number(match[10] || 0),
+ minuteOffset = $Number(match[11] || 0),
+ result;
+ var hasMinutesOrSecondsOrMilliseconds = minute > 0 || second > 0 || millisecond > 0;
+ if (
+ hour < (hasMinutesOrSecondsOrMilliseconds ? 24 : 25) &&
+ minute < 60 && second < 60 && millisecond < 1000 &&
+ month > -1 && month < 12 && hourOffset < 24 &&
+ minuteOffset < 60 && // detect invalid offsets
+ day > -1 &&
+ day < (dayFromMonth(year, month + 1) - dayFromMonth(year, month))
+ ) {
+ result = (
+ (dayFromMonth(year, month) + day) * 24 +
+ hour +
+ hourOffset * signOffset
+ ) * 60;
+ result = (
+ (result + minute + minuteOffset * signOffset) * 60 +
+ second
+ ) * 1000 + millisecond;
+ if (isLocalTime) {
+ result = toUTC(result);
+ }
+ if (-8.64e15 <= result && result <= 8.64e15) {
+ return result;
+ }
+ }
+ return NaN;
+ }
+ return NativeDate.parse.apply(this, arguments);
+ };
+ defineProperties(DateShim, { parse: parseShim });
+
+ return DateShim;
+ }(Date));
+ /* global Date: false */
+ }
+
+ // ES5 15.9.4.4
+ // http://es5.github.com/#x15.9.4.4
+ if (!Date.now) {
+ Date.now = function now() {
+ return new Date().getTime();
+ };
+ }
+
+ //
+ // Number
+ // ======
+ //
+
+ // ES5.1 15.7.4.5
+ // http://es5.github.com/#x15.7.4.5
+ var hasToFixedBugs = NumberPrototype.toFixed && (
+ (0.00008).toFixed(3) !== '0.000' ||
+ (0.9).toFixed(0) !== '1' ||
+ (1.255).toFixed(2) !== '1.25' ||
+ (1000000000000000128).toFixed(0) !== '1000000000000000128'
+ );
+
+ var toFixedHelpers = {
+ base: 1e7,
+ size: 6,
+ data: [0, 0, 0, 0, 0, 0],
+ multiply: function multiply(n, c) {
+ var i = -1;
+ var c2 = c;
+ while (++i < toFixedHelpers.size) {
+ c2 += n * toFixedHelpers.data[i];
+ toFixedHelpers.data[i] = c2 % toFixedHelpers.base;
+ c2 = Math.floor(c2 / toFixedHelpers.base);
+ }
+ },
+ divide: function divide(n) {
+ var i = toFixedHelpers.size;
+ var c = 0;
+ while (--i >= 0) {
+ c += toFixedHelpers.data[i];
+ toFixedHelpers.data[i] = Math.floor(c / n);
+ c = (c % n) * toFixedHelpers.base;
+ }
+ },
+ numToString: function numToString() {
+ var i = toFixedHelpers.size;
+ var s = '';
+ while (--i >= 0) {
+ if (s !== '' || i === 0 || toFixedHelpers.data[i] !== 0) {
+ var t = $String(toFixedHelpers.data[i]);
+ if (s === '') {
+ s = t;
+ } else {
+ s += strSlice('0000000', 0, 7 - t.length) + t;
+ }
+ }
+ }
+ return s;
+ },
+ pow: function pow(x, n, acc) {
+ return (n === 0 ? acc : (n % 2 === 1 ? pow(x, n - 1, acc * x) : pow(x * x, n / 2, acc)));
+ },
+ log: function log(x) {
+ var n = 0;
+ var x2 = x;
+ while (x2 >= 4096) {
+ n += 12;
+ x2 /= 4096;
+ }
+ while (x2 >= 2) {
+ n += 1;
+ x2 /= 2;
+ }
+ return n;
+ }
+ };
+
+ var toFixedShim = function toFixed(fractionDigits) {
+ var f, x, s, m, e, z, j, k;
+
+ // Test for NaN and round fractionDigits down
+ f = $Number(fractionDigits);
+ f = isActualNaN(f) ? 0 : Math.floor(f);
+
+ if (f < 0 || f > 20) {
+ throw new RangeError('Number.toFixed called with invalid number of decimals');
+ }
+
+ x = $Number(this);
+
+ if (isActualNaN(x)) {
+ return 'NaN';
+ }
+
+ // If it is too big or small, return the string value of the number
+ if (x <= -1e21 || x >= 1e21) {
+ return $String(x);
+ }
+
+ s = '';
+
+ if (x < 0) {
+ s = '-';
+ x = -x;
+ }
+
+ m = '0';
+
+ if (x > 1e-21) {
+ // 1e-21 < x < 1e21
+ // -70 < log2(x) < 70
+ e = toFixedHelpers.log(x * toFixedHelpers.pow(2, 69, 1)) - 69;
+ z = (e < 0 ? x * toFixedHelpers.pow(2, -e, 1) : x / toFixedHelpers.pow(2, e, 1));
+ z *= 0x10000000000000; // Math.pow(2, 52);
+ e = 52 - e;
+
+ // -18 < e < 122
+ // x = z / 2 ^ e
+ if (e > 0) {
+ toFixedHelpers.multiply(0, z);
+ j = f;
+
+ while (j >= 7) {
+ toFixedHelpers.multiply(1e7, 0);
+ j -= 7;
+ }
+
+ toFixedHelpers.multiply(toFixedHelpers.pow(10, j, 1), 0);
+ j = e - 1;
+
+ while (j >= 23) {
+ toFixedHelpers.divide(1 << 23);
+ j -= 23;
+ }
+
+ toFixedHelpers.divide(1 << j);
+ toFixedHelpers.multiply(1, 1);
+ toFixedHelpers.divide(2);
+ m = toFixedHelpers.numToString();
+ } else {
+ toFixedHelpers.multiply(0, z);
+ toFixedHelpers.multiply(1 << (-e), 0);
+ m = toFixedHelpers.numToString() + strSlice('0.00000000000000000000', 2, 2 + f);
+ }
+ }
+
+ if (f > 0) {
+ k = m.length;
+
+ if (k <= f) {
+ m = s + strSlice('0.0000000000000000000', 0, f - k + 2) + m;
+ } else {
+ m = s + strSlice(m, 0, k - f) + '.' + strSlice(m, k - f);
+ }
+ } else {
+ m = s + m;
+ }
+
+ return m;
+ };
+ defineProperties(NumberPrototype, { toFixed: toFixedShim }, hasToFixedBugs);
+
+ var hasToPrecisionUndefinedBug = (function () {
+ try {
+ return 1.0.toPrecision(undefined) === '1';
+ } catch (e) {
+ return true;
+ }
+ }());
+ var originalToPrecision = NumberPrototype.toPrecision;
+ defineProperties(NumberPrototype, {
+ toPrecision: function toPrecision(precision) {
+ return typeof precision === 'undefined' ? originalToPrecision.call(this) : originalToPrecision.call(this, precision);
+ }
+ }, hasToPrecisionUndefinedBug);
+
+ //
+ // String
+ // ======
+ //
+
+ // ES5 15.5.4.14
+ // http://es5.github.com/#x15.5.4.14
+
+ // [bugfix, IE lt 9, firefox 4, Konqueror, Opera, obscure browsers]
+ // Many browsers do not split properly with regular expressions or they
+ // do not perform the split correctly under obscure conditions.
+ // See http://blog.stevenlevithan.com/archives/cross-browser-split
+ // I've tested in many browsers and this seems to cover the deviant ones:
+ // 'ab'.split(/(?:ab)*/) should be ["", ""], not [""]
+ // '.'.split(/(.?)(.?)/) should be ["", ".", "", ""], not ["", ""]
+ // 'tesst'.split(/(s)*/) should be ["t", undefined, "e", "s", "t"], not
+ // [undefined, "t", undefined, "e", ...]
+ // ''.split(/.?/) should be [], not [""]
+ // '.'.split(/()()/) should be ["."], not ["", "", "."]
+
+ if (
+ 'ab'.split(/(?:ab)*/).length !== 2 ||
+ '.'.split(/(.?)(.?)/).length !== 4 ||
+ 'tesst'.split(/(s)*/)[1] === 't' ||
+ 'test'.split(/(?:)/, -1).length !== 4 ||
+ ''.split(/.?/).length ||
+ '.'.split(/()()/).length > 1
+ ) {
+ (function () {
+ var compliantExecNpcg = typeof (/()??/).exec('')[1] === 'undefined'; // NPCG: nonparticipating capturing group
+ var maxSafe32BitInt = Math.pow(2, 32) - 1;
+
+ StringPrototype.split = function (separator, limit) {
+ var string = String(this);
+ if (typeof separator === 'undefined' && limit === 0) {
+ return [];
+ }
+
+ // If `separator` is not a regex, use native split
+ if (!isRegex(separator)) {
+ return strSplit(this, separator, limit);
+ }
+
+ var output = [];
+ var flags = (separator.ignoreCase ? 'i' : '') +
+ (separator.multiline ? 'm' : '') +
+ (separator.unicode ? 'u' : '') + // in ES6
+ (separator.sticky ? 'y' : ''), // Firefox 3+ and ES6
+ lastLastIndex = 0,
+ // Make `global` and avoid `lastIndex` issues by working with a copy
+ separator2, match, lastIndex, lastLength;
+ var separatorCopy = new RegExp(separator.source, flags + 'g');
+ if (!compliantExecNpcg) {
+ // Doesn't need flags gy, but they don't hurt
+ separator2 = new RegExp('^' + separatorCopy.source + '$(?!\\s)', flags);
+ }
+ /* Values for `limit`, per the spec:
+ * If undefined: 4294967295 // maxSafe32BitInt
+ * If 0, Infinity, or NaN: 0
+ * If positive number: limit = Math.floor(limit); if (limit > 4294967295) limit -= 4294967296;
+ * If negative number: 4294967296 - Math.floor(Math.abs(limit))
+ * If other: Type-convert, then use the above rules
+ */
+ var splitLimit = typeof limit === 'undefined' ? maxSafe32BitInt : ES.ToUint32(limit);
+ match = separatorCopy.exec(string);
+ while (match) {
+ // `separatorCopy.lastIndex` is not reliable cross-browser
+ lastIndex = match.index + match[0].length;
+ if (lastIndex > lastLastIndex) {
+ pushCall(output, strSlice(string, lastLastIndex, match.index));
+ // Fix browsers whose `exec` methods don't consistently return `undefined` for
+ // nonparticipating capturing groups
+ if (!compliantExecNpcg && match.length > 1) {
+ /* eslint-disable no-loop-func */
+ match[0].replace(separator2, function () {
+ for (var i = 1; i < arguments.length - 2; i++) {
+ if (typeof arguments[i] === 'undefined') {
+ match[i] = void 0;
+ }
+ }
+ });
+ /* eslint-enable no-loop-func */
+ }
+ if (match.length > 1 && match.index < string.length) {
+ array_push.apply(output, arraySlice(match, 1));
+ }
+ lastLength = match[0].length;
+ lastLastIndex = lastIndex;
+ if (output.length >= splitLimit) {
+ break;
+ }
+ }
+ if (separatorCopy.lastIndex === match.index) {
+ separatorCopy.lastIndex++; // Avoid an infinite loop
+ }
+ match = separatorCopy.exec(string);
+ }
+ if (lastLastIndex === string.length) {
+ if (lastLength || !separatorCopy.test('')) {
+ pushCall(output, '');
+ }
+ } else {
+ pushCall(output, strSlice(string, lastLastIndex));
+ }
+ return output.length > splitLimit ? arraySlice(output, 0, splitLimit) : output;
+ };
+ }());
+
+ // [bugfix, chrome]
+ // If separator is undefined, then the result array contains just one String,
+ // which is the this value (converted to a String). If limit is not undefined,
+ // then the output array is truncated so that it contains no more than limit
+ // elements.
+ // "0".split(undefined, 0) -> []
+ } else if ('0'.split(void 0, 0).length) {
+ StringPrototype.split = function split(separator, limit) {
+ if (typeof separator === 'undefined' && limit === 0) {
+ return [];
+ }
+ return strSplit(this, separator, limit);
+ };
+ }
+
+ var str_replace = StringPrototype.replace;
+ var replaceReportsGroupsCorrectly = (function () {
+ var groups = [];
+ 'x'.replace(/x(.)?/g, function (match, group) {
+ pushCall(groups, group);
+ });
+ return groups.length === 1 && typeof groups[0] === 'undefined';
+ }());
+
+ if (!replaceReportsGroupsCorrectly) {
+ StringPrototype.replace = function replace(searchValue, replaceValue) {
+ var isFn = isCallable(replaceValue);
+ var hasCapturingGroups = isRegex(searchValue) && (/\)[*?]/).test(searchValue.source);
+ if (!isFn || !hasCapturingGroups) {
+ return str_replace.call(this, searchValue, replaceValue);
+ } else {
+ var wrappedReplaceValue = function (match) {
+ var length = arguments.length;
+ var originalLastIndex = searchValue.lastIndex;
+ searchValue.lastIndex = 0;
+ var args = searchValue.exec(match) || [];
+ searchValue.lastIndex = originalLastIndex;
+ pushCall(args, arguments[length - 2], arguments[length - 1]);
+ return replaceValue.apply(this, args);
+ };
+ return str_replace.call(this, searchValue, wrappedReplaceValue);
+ }
+ };
+ }
+
+ // ECMA-262, 3rd B.2.3
+ // Not an ECMAScript standard, although ECMAScript 3rd Edition has a
+ // non-normative section suggesting uniform semantics and it should be
+ // normalized across all browsers
+ // [bugfix, IE lt 9] IE < 9 substr() with negative value not working in IE
+ var string_substr = StringPrototype.substr;
+ var hasNegativeSubstrBug = ''.substr && '0b'.substr(-1) !== 'b';
+ defineProperties(StringPrototype, {
+ substr: function substr(start, length) {
+ var normalizedStart = start;
+ if (start < 0) {
+ normalizedStart = max(this.length + start, 0);
+ }
+ return string_substr.call(this, normalizedStart, length);
+ }
+ }, hasNegativeSubstrBug);
+
+ // ES5 15.5.4.20
+ // whitespace from: http://es5.github.io/#x15.5.4.20
+ var ws = '\x09\x0A\x0B\x0C\x0D\x20\xA0\u1680\u180E\u2000\u2001\u2002\u2003' +
+ '\u2004\u2005\u2006\u2007\u2008\u2009\u200A\u202F\u205F\u3000\u2028' +
+ '\u2029\uFEFF';
+ var zeroWidth = '\u200b';
+ var wsRegexChars = '[' + ws + ']';
+ var trimBeginRegexp = new RegExp('^' + wsRegexChars + wsRegexChars + '*');
+ var trimEndRegexp = new RegExp(wsRegexChars + wsRegexChars + '*$');
+ var hasTrimWhitespaceBug = StringPrototype.trim && (ws.trim() || !zeroWidth.trim());
+ defineProperties(StringPrototype, {
+ // http://blog.stevenlevithan.com/archives/faster-trim-javascript
+ // http://perfectionkills.com/whitespace-deviations/
+ trim: function trim() {
+ if (typeof this === 'undefined' || this === null) {
+ throw new TypeError("can't convert " + this + ' to object');
+ }
+ return $String(this).replace(trimBeginRegexp, '').replace(trimEndRegexp, '');
+ }
+ }, hasTrimWhitespaceBug);
+ var trim = call.bind(String.prototype.trim);
+
+ var hasLastIndexBug = StringPrototype.lastIndexOf && 'abcあい'.lastIndexOf('あい', 2) !== -1;
+ defineProperties(StringPrototype, {
+ lastIndexOf: function lastIndexOf(searchString) {
+ if (typeof this === 'undefined' || this === null) {
+ throw new TypeError("can't convert " + this + ' to object');
+ }
+ var S = $String(this);
+ var searchStr = $String(searchString);
+ var numPos = arguments.length > 1 ? $Number(arguments[1]) : NaN;
+ var pos = isActualNaN(numPos) ? Infinity : ES.ToInteger(numPos);
+ var start = min(max(pos, 0), S.length);
+ var searchLen = searchStr.length;
+ var k = start + searchLen;
+ while (k > 0) {
+ k = max(0, k - searchLen);
+ var index = strIndexOf(strSlice(S, k, start + searchLen), searchStr);
+ if (index !== -1) {
+ return k + index;
+ }
+ }
+ return -1;
+ }
+ }, hasLastIndexBug);
+
+ var originalLastIndexOf = StringPrototype.lastIndexOf;
+ defineProperties(StringPrototype, {
+ lastIndexOf: function lastIndexOf(searchString) {
+ return originalLastIndexOf.apply(this, arguments);
+ }
+ }, StringPrototype.lastIndexOf.length !== 1);
+
+ // ES-5 15.1.2.2
+ /* eslint-disable radix */
+ if (parseInt(ws + '08') !== 8 || parseInt(ws + '0x16') !== 22) {
+ /* eslint-enable radix */
+ /* global parseInt: true */
+ parseInt = (function (origParseInt) {
+ var hexRegex = /^[\-+]?0[xX]/;
+ return function parseInt(str, radix) {
+ var string = trim(String(str));
+ var defaultedRadix = $Number(radix) || (hexRegex.test(string) ? 16 : 10);
+ return origParseInt(string, defaultedRadix);
+ };
+ }(parseInt));
+ }
+
+ // https://es5.github.io/#x15.1.2.3
+ if (1 / parseFloat('-0') !== -Infinity) {
+ /* global parseFloat: true */
+ parseFloat = (function (origParseFloat) {
+ return function parseFloat(string) {
+ var inputString = trim(String(string));
+ var result = origParseFloat(inputString);
+ return result === 0 && strSlice(inputString, 0, 1) === '-' ? -0 : result;
+ };
+ }(parseFloat));
+ }
+
+ if (String(new RangeError('test')) !== 'RangeError: test') {
+ var errorToStringShim = function toString() {
+ if (typeof this === 'undefined' || this === null) {
+ throw new TypeError("can't convert " + this + ' to object');
+ }
+ var name = this.name;
+ if (typeof name === 'undefined') {
+ name = 'Error';
+ } else if (typeof name !== 'string') {
+ name = $String(name);
+ }
+ var msg = this.message;
+ if (typeof msg === 'undefined') {
+ msg = '';
+ } else if (typeof msg !== 'string') {
+ msg = $String(msg);
+ }
+ if (!name) {
+ return msg;
+ }
+ if (!msg) {
+ return name;
+ }
+ return name + ': ' + msg;
+ };
+ // can't use defineProperties here because of toString enumeration issue in IE <= 8
+ Error.prototype.toString = errorToStringShim;
+ }
+
+ if (supportsDescriptors) {
+ var ensureNonEnumerable = function (obj, prop) {
+ if (isEnum(obj, prop)) {
+ var desc = Object.getOwnPropertyDescriptor(obj, prop);
+ if (desc.configurable) {
+ desc.enumerable = false;
+ Object.defineProperty(obj, prop, desc);
+ }
+ }
+ };
+ ensureNonEnumerable(Error.prototype, 'message');
+ if (Error.prototype.message !== '') {
+ Error.prototype.message = '';
+ }
+ ensureNonEnumerable(Error.prototype, 'name');
+ }
+
+ if (String(/a/mig) !== '/a/gim') {
+ var regexToString = function toString() {
+ var str = '/' + this.source + '/';
+ if (this.global) {
+ str += 'g';
+ }
+ if (this.ignoreCase) {
+ str += 'i';
+ }
+ if (this.multiline) {
+ str += 'm';
+ }
+ return str;
+ };
+ // can't use defineProperties here because of toString enumeration issue in IE <= 8
+ RegExp.prototype.toString = regexToString;
+ }
+}));
diff --git a/ydb/core/viewer/content/api/lib/handlebars-4.0.5.js b/ydb/core/viewer/content/api/lib/handlebars-4.0.5.js
index e0b35c2c13c..182c1be831d 100644
--- a/ydb/core/viewer/content/api/lib/handlebars-4.0.5.js
+++ b/ydb/core/viewer/content/api/lib/handlebars-4.0.5.js
@@ -1,4608 +1,4608 @@
-/*!
-
- handlebars v4.0.5
-
-Copyright (C) 2011-2015 by Yehuda Katz
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in
-all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-THE SOFTWARE.
-
-@license
-*/
-(function webpackUniversalModuleDefinition(root, factory) {
- if(typeof exports === 'object' && typeof module === 'object')
- module.exports = factory();
- else if(typeof define === 'function' && define.amd)
- define([], factory);
- else if(typeof exports === 'object')
- exports["Handlebars"] = factory();
- else
- root["Handlebars"] = factory();
-})(this, function() {
-return /******/ (function(modules) { // webpackBootstrap
-/******/ // The module cache
-/******/ var installedModules = {};
-
-/******/ // The require function
-/******/ function __webpack_require__(moduleId) {
-
-/******/ // Check if module is in cache
-/******/ if(installedModules[moduleId])
-/******/ return installedModules[moduleId].exports;
-
-/******/ // Create a new module (and put it into the cache)
-/******/ var module = installedModules[moduleId] = {
-/******/ exports: {},
-/******/ id: moduleId,
-/******/ loaded: false
-/******/ };
-
-/******/ // Execute the module function
-/******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);
-
-/******/ // Flag the module as loaded
-/******/ module.loaded = true;
-
-/******/ // Return the exports of the module
-/******/ return module.exports;
-/******/ }
-
-
-/******/ // expose the modules object (__webpack_modules__)
-/******/ __webpack_require__.m = modules;
-
-/******/ // expose the module cache
-/******/ __webpack_require__.c = installedModules;
-
-/******/ // __webpack_public_path__
-/******/ __webpack_require__.p = "";
-
-/******/ // Load entry module and return exports
-/******/ return __webpack_require__(0);
-/******/ })
-/************************************************************************/
-/******/ ([
-/* 0 */
-/***/ function(module, exports, __webpack_require__) {
-
- 'use strict';
-
- var _interopRequireDefault = __webpack_require__(1)['default'];
-
- exports.__esModule = true;
-
- var _handlebarsRuntime = __webpack_require__(2);
-
- var _handlebarsRuntime2 = _interopRequireDefault(_handlebarsRuntime);
-
- // Compiler imports
-
- var _handlebarsCompilerAst = __webpack_require__(21);
-
- var _handlebarsCompilerAst2 = _interopRequireDefault(_handlebarsCompilerAst);
-
- var _handlebarsCompilerBase = __webpack_require__(22);
-
- var _handlebarsCompilerCompiler = __webpack_require__(27);
-
- var _handlebarsCompilerJavascriptCompiler = __webpack_require__(28);
-
- var _handlebarsCompilerJavascriptCompiler2 = _interopRequireDefault(_handlebarsCompilerJavascriptCompiler);
-
- var _handlebarsCompilerVisitor = __webpack_require__(25);
-
- var _handlebarsCompilerVisitor2 = _interopRequireDefault(_handlebarsCompilerVisitor);
-
- var _handlebarsNoConflict = __webpack_require__(20);
-
- var _handlebarsNoConflict2 = _interopRequireDefault(_handlebarsNoConflict);
-
- var _create = _handlebarsRuntime2['default'].create;
- function create() {
- var hb = _create();
-
- hb.compile = function (input, options) {
- return _handlebarsCompilerCompiler.compile(input, options, hb);
- };
- hb.precompile = function (input, options) {
- return _handlebarsCompilerCompiler.precompile(input, options, hb);
- };
-
- hb.AST = _handlebarsCompilerAst2['default'];
- hb.Compiler = _handlebarsCompilerCompiler.Compiler;
- hb.JavaScriptCompiler = _handlebarsCompilerJavascriptCompiler2['default'];
- hb.Parser = _handlebarsCompilerBase.parser;
- hb.parse = _handlebarsCompilerBase.parse;
-
- return hb;
- }
-
- var inst = create();
- inst.create = create;
-
- _handlebarsNoConflict2['default'](inst);
-
- inst.Visitor = _handlebarsCompilerVisitor2['default'];
-
- inst['default'] = inst;
-
- exports['default'] = inst;
- module.exports = exports['default'];
-
-/***/ },
-/* 1 */
-/***/ function(module, exports) {
-
- "use strict";
-
- exports["default"] = function (obj) {
- return obj && obj.__esModule ? obj : {
- "default": obj
- };
- };
-
- exports.__esModule = true;
-
-/***/ },
-/* 2 */
-/***/ function(module, exports, __webpack_require__) {
-
- 'use strict';
-
- var _interopRequireWildcard = __webpack_require__(3)['default'];
-
- var _interopRequireDefault = __webpack_require__(1)['default'];
-
- exports.__esModule = true;
-
- var _handlebarsBase = __webpack_require__(4);
-
- var base = _interopRequireWildcard(_handlebarsBase);
-
- // Each of these augment the Handlebars object. No need to setup here.
- // (This is done to easily share code between commonjs and browse envs)
-
- var _handlebarsSafeString = __webpack_require__(18);
-
- var _handlebarsSafeString2 = _interopRequireDefault(_handlebarsSafeString);
-
- var _handlebarsException = __webpack_require__(6);
-
- var _handlebarsException2 = _interopRequireDefault(_handlebarsException);
-
- var _handlebarsUtils = __webpack_require__(5);
-
- var Utils = _interopRequireWildcard(_handlebarsUtils);
-
- var _handlebarsRuntime = __webpack_require__(19);
-
- var runtime = _interopRequireWildcard(_handlebarsRuntime);
-
- var _handlebarsNoConflict = __webpack_require__(20);
-
- var _handlebarsNoConflict2 = _interopRequireDefault(_handlebarsNoConflict);
-
- // For compatibility and usage outside of module systems, make the Handlebars object a namespace
- function create() {
- var hb = new base.HandlebarsEnvironment();
-
- Utils.extend(hb, base);
- hb.SafeString = _handlebarsSafeString2['default'];
- hb.Exception = _handlebarsException2['default'];
- hb.Utils = Utils;
- hb.escapeExpression = Utils.escapeExpression;
-
- hb.VM = runtime;
- hb.template = function (spec) {
- return runtime.template(spec, hb);
- };
-
- return hb;
- }
-
- var inst = create();
- inst.create = create;
-
- _handlebarsNoConflict2['default'](inst);
-
- inst['default'] = inst;
-
- exports['default'] = inst;
- module.exports = exports['default'];
-
-/***/ },
-/* 3 */
-/***/ function(module, exports) {
-
- "use strict";
-
- exports["default"] = function (obj) {
- if (obj && obj.__esModule) {
- return obj;
- } else {
- var newObj = {};
-
- if (obj != null) {
- for (var key in obj) {
- if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key];
- }
- }
-
- newObj["default"] = obj;
- return newObj;
- }
- };
-
- exports.__esModule = true;
-
-/***/ },
-/* 4 */
-/***/ function(module, exports, __webpack_require__) {
-
- 'use strict';
-
- var _interopRequireDefault = __webpack_require__(1)['default'];
-
- exports.__esModule = true;
- exports.HandlebarsEnvironment = HandlebarsEnvironment;
-
- var _utils = __webpack_require__(5);
-
- var _exception = __webpack_require__(6);
-
- var _exception2 = _interopRequireDefault(_exception);
-
- var _helpers = __webpack_require__(7);
-
- var _decorators = __webpack_require__(15);
-
- var _logger = __webpack_require__(17);
-
- var _logger2 = _interopRequireDefault(_logger);
-
- var VERSION = '4.0.5';
- exports.VERSION = VERSION;
- var COMPILER_REVISION = 7;
-
- exports.COMPILER_REVISION = COMPILER_REVISION;
- var REVISION_CHANGES = {
- 1: '<= 1.0.rc.2', // 1.0.rc.2 is actually rev2 but doesn't report it
- 2: '== 1.0.0-rc.3',
- 3: '== 1.0.0-rc.4',
- 4: '== 1.x.x',
- 5: '== 2.0.0-alpha.x',
- 6: '>= 2.0.0-beta.1',
- 7: '>= 4.0.0'
- };
-
- exports.REVISION_CHANGES = REVISION_CHANGES;
- var objectType = '[object Object]';
-
- function HandlebarsEnvironment(helpers, partials, decorators) {
- this.helpers = helpers || {};
- this.partials = partials || {};
- this.decorators = decorators || {};
-
- _helpers.registerDefaultHelpers(this);
- _decorators.registerDefaultDecorators(this);
- }
-
- HandlebarsEnvironment.prototype = {
- constructor: HandlebarsEnvironment,
-
- logger: _logger2['default'],
- log: _logger2['default'].log,
-
- registerHelper: function registerHelper(name, fn) {
- if (_utils.toString.call(name) === objectType) {
- if (fn) {
- throw new _exception2['default']('Arg not supported with multiple helpers');
- }
- _utils.extend(this.helpers, name);
- } else {
- this.helpers[name] = fn;
- }
- },
- unregisterHelper: function unregisterHelper(name) {
- delete this.helpers[name];
- },
-
- registerPartial: function registerPartial(name, partial) {
- if (_utils.toString.call(name) === objectType) {
- _utils.extend(this.partials, name);
- } else {
- if (typeof partial === 'undefined') {
- throw new _exception2['default']('Attempting to register a partial called "' + name + '" as undefined');
- }
- this.partials[name] = partial;
- }
- },
- unregisterPartial: function unregisterPartial(name) {
- delete this.partials[name];
- },
-
- registerDecorator: function registerDecorator(name, fn) {
- if (_utils.toString.call(name) === objectType) {
- if (fn) {
- throw new _exception2['default']('Arg not supported with multiple decorators');
- }
- _utils.extend(this.decorators, name);
- } else {
- this.decorators[name] = fn;
- }
- },
- unregisterDecorator: function unregisterDecorator(name) {
- delete this.decorators[name];
- }
- };
-
- var log = _logger2['default'].log;
-
- exports.log = log;
- exports.createFrame = _utils.createFrame;
- exports.logger = _logger2['default'];
-
-/***/ },
-/* 5 */
-/***/ function(module, exports) {
-
- 'use strict';
-
- exports.__esModule = true;
- exports.extend = extend;
- exports.indexOf = indexOf;
- exports.escapeExpression = escapeExpression;
- exports.isEmpty = isEmpty;
- exports.createFrame = createFrame;
- exports.blockParams = blockParams;
- exports.appendContextPath = appendContextPath;
- var escape = {
- '&': '&amp;',
- '<': '&lt;',
- '>': '&gt;',
- '"': '&quot;',
- "'": '&#x27;',
- '`': '&#x60;',
- '=': '&#x3D;'
- };
-
- var badChars = /[&<>"'`=]/g,
- possible = /[&<>"'`=]/;
-
- function escapeChar(chr) {
- return escape[chr];
- }
-
- function extend(obj /* , ...source */) {
- for (var i = 1; i < arguments.length; i++) {
- for (var key in arguments[i]) {
- if (Object.prototype.hasOwnProperty.call(arguments[i], key)) {
- obj[key] = arguments[i][key];
- }
- }
- }
-
- return obj;
- }
-
- var toString = Object.prototype.toString;
-
- exports.toString = toString;
- // Sourced from lodash
- // https://github.com/bestiejs/lodash/blob/master/LICENSE.txt
- /* eslint-disable func-style */
- var isFunction = function isFunction(value) {
- return typeof value === 'function';
- };
- // fallback for older versions of Chrome and Safari
- /* istanbul ignore next */
- if (isFunction(/x/)) {
- exports.isFunction = isFunction = function (value) {
- return typeof value === 'function' && toString.call(value) === '[object Function]';
- };
- }
- exports.isFunction = isFunction;
-
- /* eslint-enable func-style */
-
- /* istanbul ignore next */
- var isArray = Array.isArray || function (value) {
- return value && typeof value === 'object' ? toString.call(value) === '[object Array]' : false;
- };
-
- exports.isArray = isArray;
- // Older IE versions do not directly support indexOf so we must implement our own, sadly.
-
- function indexOf(array, value) {
- for (var i = 0, len = array.length; i < len; i++) {
- if (array[i] === value) {
- return i;
- }
- }
- return -1;
- }
-
- function escapeExpression(string) {
- if (typeof string !== 'string') {
- // don't escape SafeStrings, since they're already safe
- if (string && string.toHTML) {
- return string.toHTML();
- } else if (string == null) {
- return '';
- } else if (!string) {
- return string + '';
- }
-
- // Force a string conversion as this will be done by the append regardless and
- // the regex test will do this transparently behind the scenes, causing issues if
- // an object's to string has escaped characters in it.
- string = '' + string;
- }
-
- if (!possible.test(string)) {
- return string;
- }
- return string.replace(badChars, escapeChar);
- }
-
- function isEmpty(value) {
- if (!value && value !== 0) {
- return true;
- } else if (isArray(value) && value.length === 0) {
- return true;
- } else {
- return false;
- }
- }
-
- function createFrame(object) {
- var frame = extend({}, object);
- frame._parent = object;
- return frame;
- }
-
- function blockParams(params, ids) {
- params.path = ids;
- return params;
- }
-
- function appendContextPath(contextPath, id) {
- return (contextPath ? contextPath + '.' : '') + id;
- }
-
-/***/ },
-/* 6 */
-/***/ function(module, exports) {
-
- 'use strict';
-
- exports.__esModule = true;
-
- var errorProps = ['description', 'fileName', 'lineNumber', 'message', 'name', 'number', 'stack'];
-
- function Exception(message, node) {
- var loc = node && node.loc,
- line = undefined,
- column = undefined;
- if (loc) {
- line = loc.start.line;
- column = loc.start.column;
-
- message += ' - ' + line + ':' + column;
- }
-
- var tmp = Error.prototype.constructor.call(this, message);
-
- // Unfortunately errors are not enumerable in Chrome (at least), so `for prop in tmp` doesn't work.
- for (var idx = 0; idx < errorProps.length; idx++) {
- this[errorProps[idx]] = tmp[errorProps[idx]];
- }
-
- /* istanbul ignore else */
- if (Error.captureStackTrace) {
- Error.captureStackTrace(this, Exception);
- }
-
- if (loc) {
- this.lineNumber = line;
- this.column = column;
- }
- }
-
- Exception.prototype = new Error();
-
- exports['default'] = Exception;
- module.exports = exports['default'];
-
-/***/ },
-/* 7 */
-/***/ function(module, exports, __webpack_require__) {
-
- 'use strict';
-
- var _interopRequireDefault = __webpack_require__(1)['default'];
-
- exports.__esModule = true;
- exports.registerDefaultHelpers = registerDefaultHelpers;
-
- var _helpersBlockHelperMissing = __webpack_require__(8);
-
- var _helpersBlockHelperMissing2 = _interopRequireDefault(_helpersBlockHelperMissing);
-
- var _helpersEach = __webpack_require__(9);
-
- var _helpersEach2 = _interopRequireDefault(_helpersEach);
-
- var _helpersHelperMissing = __webpack_require__(10);
-
- var _helpersHelperMissing2 = _interopRequireDefault(_helpersHelperMissing);
-
- var _helpersIf = __webpack_require__(11);
-
- var _helpersIf2 = _interopRequireDefault(_helpersIf);
-
- var _helpersLog = __webpack_require__(12);
-
- var _helpersLog2 = _interopRequireDefault(_helpersLog);
-
- var _helpersLookup = __webpack_require__(13);
-
- var _helpersLookup2 = _interopRequireDefault(_helpersLookup);
-
- var _helpersWith = __webpack_require__(14);
-
- var _helpersWith2 = _interopRequireDefault(_helpersWith);
-
- function registerDefaultHelpers(instance) {
- _helpersBlockHelperMissing2['default'](instance);
- _helpersEach2['default'](instance);
- _helpersHelperMissing2['default'](instance);
- _helpersIf2['default'](instance);
- _helpersLog2['default'](instance);
- _helpersLookup2['default'](instance);
- _helpersWith2['default'](instance);
- }
-
-/***/ },
-/* 8 */
-/***/ function(module, exports, __webpack_require__) {
-
- 'use strict';
-
- exports.__esModule = true;
-
- var _utils = __webpack_require__(5);
-
- exports['default'] = function (instance) {
- instance.registerHelper('blockHelperMissing', function (context, options) {
- var inverse = options.inverse,
- fn = options.fn;
-
- if (context === true) {
- return fn(this);
- } else if (context === false || context == null) {
- return inverse(this);
- } else if (_utils.isArray(context)) {
- if (context.length > 0) {
- if (options.ids) {
- options.ids = [options.name];
- }
-
- return instance.helpers.each(context, options);
- } else {
- return inverse(this);
- }
- } else {
- if (options.data && options.ids) {
- var data = _utils.createFrame(options.data);
- data.contextPath = _utils.appendContextPath(options.data.contextPath, options.name);
- options = { data: data };
- }
-
- return fn(context, options);
- }
- });
- };
-
- module.exports = exports['default'];
-
-/***/ },
-/* 9 */
-/***/ function(module, exports, __webpack_require__) {
-
- 'use strict';
-
- var _interopRequireDefault = __webpack_require__(1)['default'];
-
- exports.__esModule = true;
-
- var _utils = __webpack_require__(5);
-
- var _exception = __webpack_require__(6);
-
- var _exception2 = _interopRequireDefault(_exception);
-
- exports['default'] = function (instance) {
- instance.registerHelper('each', function (context, options) {
- if (!options) {
- throw new _exception2['default']('Must pass iterator to #each');
- }
-
- var fn = options.fn,
- inverse = options.inverse,
- i = 0,
- ret = '',
- data = undefined,
- contextPath = undefined;
-
- if (options.data && options.ids) {
- contextPath = _utils.appendContextPath(options.data.contextPath, options.ids[0]) + '.';
- }
-
- if (_utils.isFunction(context)) {
- context = context.call(this);
- }
-
- if (options.data) {
- data = _utils.createFrame(options.data);
- }
-
- function execIteration(field, index, last) {
- if (data) {
- data.key = field;
- data.index = index;
- data.first = index === 0;
- data.last = !!last;
-
- if (contextPath) {
- data.contextPath = contextPath + field;
- }
- }
-
- ret = ret + fn(context[field], {
- data: data,
- blockParams: _utils.blockParams([context[field], field], [contextPath + field, null])
- });
- }
-
- if (context && typeof context === 'object') {
- if (_utils.isArray(context)) {
- for (var j = context.length; i < j; i++) {
- if (i in context) {
- execIteration(i, i, i === context.length - 1);
- }
- }
- } else {
- var priorKey = undefined;
-
- for (var key in context) {
- if (context.hasOwnProperty(key)) {
- // We're running the iterations one step out of sync so we can detect
- // the last iteration without have to scan the object twice and create
- // an itermediate keys array.
- if (priorKey !== undefined) {
- execIteration(priorKey, i - 1);
- }
- priorKey = key;
- i++;
- }
- }
- if (priorKey !== undefined) {
- execIteration(priorKey, i - 1, true);
- }
- }
- }
-
- if (i === 0) {
- ret = inverse(this);
- }
-
- return ret;
- });
- };
-
- module.exports = exports['default'];
-
-/***/ },
-/* 10 */
-/***/ function(module, exports, __webpack_require__) {
-
- 'use strict';
-
- var _interopRequireDefault = __webpack_require__(1)['default'];
-
- exports.__esModule = true;
-
- var _exception = __webpack_require__(6);
-
- var _exception2 = _interopRequireDefault(_exception);
-
- exports['default'] = function (instance) {
- instance.registerHelper('helperMissing', function () /* [args, ]options */{
- if (arguments.length === 1) {
- // A missing field in a {{foo}} construct.
- return undefined;
- } else {
- // Someone is actually trying to call something, blow up.
- throw new _exception2['default']('Missing helper: "' + arguments[arguments.length - 1].name + '"');
- }
- });
- };
-
- module.exports = exports['default'];
-
-/***/ },
-/* 11 */
-/***/ function(module, exports, __webpack_require__) {
-
- 'use strict';
-
- exports.__esModule = true;
-
- var _utils = __webpack_require__(5);
-
- exports['default'] = function (instance) {
- instance.registerHelper('if', function (conditional, options) {
- if (_utils.isFunction(conditional)) {
- conditional = conditional.call(this);
- }
-
- // Default behavior is to render the positive path if the value is truthy and not empty.
- // The `includeZero` option may be set to treat the condtional as purely not empty based on the
- // behavior of isEmpty. Effectively this determines if 0 is handled by the positive path or negative.
- if (!options.hash.includeZero && !conditional || _utils.isEmpty(conditional)) {
- return options.inverse(this);
- } else {
- return options.fn(this);
- }
- });
-
- instance.registerHelper('unless', function (conditional, options) {
- return instance.helpers['if'].call(this, conditional, { fn: options.inverse, inverse: options.fn, hash: options.hash });
- });
- };
-
- module.exports = exports['default'];
-
-/***/ },
-/* 12 */
-/***/ function(module, exports) {
-
- 'use strict';
-
- exports.__esModule = true;
-
- exports['default'] = function (instance) {
- instance.registerHelper('log', function () /* message, options */{
- var args = [undefined],
- options = arguments[arguments.length - 1];
- for (var i = 0; i < arguments.length - 1; i++) {
- args.push(arguments[i]);
- }
-
- var level = 1;
- if (options.hash.level != null) {
- level = options.hash.level;
- } else if (options.data && options.data.level != null) {
- level = options.data.level;
- }
- args[0] = level;
-
- instance.log.apply(instance, args);
- });
- };
-
- module.exports = exports['default'];
-
-/***/ },
-/* 13 */
-/***/ function(module, exports) {
-
- 'use strict';
-
- exports.__esModule = true;
-
- exports['default'] = function (instance) {
- instance.registerHelper('lookup', function (obj, field) {
- return obj && obj[field];
- });
- };
-
- module.exports = exports['default'];
-
-/***/ },
-/* 14 */
-/***/ function(module, exports, __webpack_require__) {
-
- 'use strict';
-
- exports.__esModule = true;
-
- var _utils = __webpack_require__(5);
-
- exports['default'] = function (instance) {
- instance.registerHelper('with', function (context, options) {
- if (_utils.isFunction(context)) {
- context = context.call(this);
- }
-
- var fn = options.fn;
-
- if (!_utils.isEmpty(context)) {
- var data = options.data;
- if (options.data && options.ids) {
- data = _utils.createFrame(options.data);
- data.contextPath = _utils.appendContextPath(options.data.contextPath, options.ids[0]);
- }
-
- return fn(context, {
- data: data,
- blockParams: _utils.blockParams([context], [data && data.contextPath])
- });
- } else {
- return options.inverse(this);
- }
- });
- };
-
- module.exports = exports['default'];
-
-/***/ },
-/* 15 */
-/***/ function(module, exports, __webpack_require__) {
-
- 'use strict';
-
- var _interopRequireDefault = __webpack_require__(1)['default'];
-
- exports.__esModule = true;
- exports.registerDefaultDecorators = registerDefaultDecorators;
-
- var _decoratorsInline = __webpack_require__(16);
-
- var _decoratorsInline2 = _interopRequireDefault(_decoratorsInline);
-
- function registerDefaultDecorators(instance) {
- _decoratorsInline2['default'](instance);
- }
-
-/***/ },
-/* 16 */
-/***/ function(module, exports, __webpack_require__) {
-
- 'use strict';
-
- exports.__esModule = true;
-
- var _utils = __webpack_require__(5);
-
- exports['default'] = function (instance) {
- instance.registerDecorator('inline', function (fn, props, container, options) {
- var ret = fn;
- if (!props.partials) {
- props.partials = {};
- ret = function (context, options) {
- // Create a new partials stack frame prior to exec.
- var original = container.partials;
- container.partials = _utils.extend({}, original, props.partials);
- var ret = fn(context, options);
- container.partials = original;
- return ret;
- };
- }
-
- props.partials[options.args[0]] = options.fn;
-
- return ret;
- });
- };
-
- module.exports = exports['default'];
-
-/***/ },
-/* 17 */
-/***/ function(module, exports, __webpack_require__) {
-
- 'use strict';
-
- exports.__esModule = true;
-
- var _utils = __webpack_require__(5);
-
- var logger = {
- methodMap: ['debug', 'info', 'warn', 'error'],
- level: 'info',
-
- // Maps a given level value to the `methodMap` indexes above.
- lookupLevel: function lookupLevel(level) {
- if (typeof level === 'string') {
- var levelMap = _utils.indexOf(logger.methodMap, level.toLowerCase());
- if (levelMap >= 0) {
- level = levelMap;
- } else {
- level = parseInt(level, 10);
- }
- }
-
- return level;
- },
-
- // Can be overridden in the host environment
- log: function log(level) {
- level = logger.lookupLevel(level);
-
- if (typeof console !== 'undefined' && logger.lookupLevel(logger.level) <= level) {
- var method = logger.methodMap[level];
- if (!console[method]) {
- // eslint-disable-line no-console
- method = 'log';
- }
-
- for (var _len = arguments.length, message = Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
- message[_key - 1] = arguments[_key];
- }
-
- console[method].apply(console, message); // eslint-disable-line no-console
- }
- }
- };
-
- exports['default'] = logger;
- module.exports = exports['default'];
-
-/***/ },
-/* 18 */
-/***/ function(module, exports) {
-
- // Build out our basic SafeString type
- 'use strict';
-
- exports.__esModule = true;
- function SafeString(string) {
- this.string = string;
- }
-
- SafeString.prototype.toString = SafeString.prototype.toHTML = function () {
- return '' + this.string;
- };
-
- exports['default'] = SafeString;
- module.exports = exports['default'];
-
-/***/ },
-/* 19 */
-/***/ function(module, exports, __webpack_require__) {
-
- 'use strict';
-
- var _interopRequireWildcard = __webpack_require__(3)['default'];
-
- var _interopRequireDefault = __webpack_require__(1)['default'];
-
- exports.__esModule = true;
- exports.checkRevision = checkRevision;
- exports.template = template;
- exports.wrapProgram = wrapProgram;
- exports.resolvePartial = resolvePartial;
- exports.invokePartial = invokePartial;
- exports.noop = noop;
-
- var _utils = __webpack_require__(5);
-
- var Utils = _interopRequireWildcard(_utils);
-
- var _exception = __webpack_require__(6);
-
- var _exception2 = _interopRequireDefault(_exception);
-
- var _base = __webpack_require__(4);
-
- function checkRevision(compilerInfo) {
- var compilerRevision = compilerInfo && compilerInfo[0] || 1,
- currentRevision = _base.COMPILER_REVISION;
-
- if (compilerRevision !== currentRevision) {
- if (compilerRevision < currentRevision) {
- var runtimeVersions = _base.REVISION_CHANGES[currentRevision],
- compilerVersions = _base.REVISION_CHANGES[compilerRevision];
- throw new _exception2['default']('Template was precompiled with an older version of Handlebars than the current runtime. ' + 'Please update your precompiler to a newer version (' + runtimeVersions + ') or downgrade your runtime to an older version (' + compilerVersions + ').');
- } else {
- // Use the embedded version info since the runtime doesn't know about this revision yet
- throw new _exception2['default']('Template was precompiled with a newer version of Handlebars than the current runtime. ' + 'Please update your runtime to a newer version (' + compilerInfo[1] + ').');
- }
- }
- }
-
- function template(templateSpec, env) {
- /* istanbul ignore next */
- if (!env) {
- throw new _exception2['default']('No environment passed to template');
- }
- if (!templateSpec || !templateSpec.main) {
- throw new _exception2['default']('Unknown template object: ' + typeof templateSpec);
- }
-
- templateSpec.main.decorator = templateSpec.main_d;
-
- // Note: Using env.VM references rather than local var references throughout this section to allow
- // for external users to override these as psuedo-supported APIs.
- env.VM.checkRevision(templateSpec.compiler);
-
- function invokePartialWrapper(partial, context, options) {
- if (options.hash) {
- context = Utils.extend({}, context, options.hash);
- if (options.ids) {
- options.ids[0] = true;
- }
- }
-
- partial = env.VM.resolvePartial.call(this, partial, context, options);
- var result = env.VM.invokePartial.call(this, partial, context, options);
-
- if (result == null && env.compile) {
- options.partials[options.name] = env.compile(partial, templateSpec.compilerOptions, env);
- result = options.partials[options.name](context, options);
- }
- if (result != null) {
- if (options.indent) {
- var lines = result.split('\n');
- for (var i = 0, l = lines.length; i < l; i++) {
- if (!lines[i] && i + 1 === l) {
- break;
- }
-
- lines[i] = options.indent + lines[i];
- }
- result = lines.join('\n');
- }
- return result;
- } else {
- throw new _exception2['default']('The partial ' + options.name + ' could not be compiled when running in runtime-only mode');
- }
- }
-
- // Just add water
- var container = {
- strict: function strict(obj, name) {
- if (!(name in obj)) {
- throw new _exception2['default']('"' + name + '" not defined in ' + obj);
- }
- return obj[name];
- },
- lookup: function lookup(depths, name) {
- var len = depths.length;
- for (var i = 0; i < len; i++) {
- if (depths[i] && depths[i][name] != null) {
- return depths[i][name];
- }
- }
- },
- lambda: function lambda(current, context) {
- return typeof current === 'function' ? current.call(context) : current;
- },
-
- escapeExpression: Utils.escapeExpression,
- invokePartial: invokePartialWrapper,
-
- fn: function fn(i) {
- var ret = templateSpec[i];
- ret.decorator = templateSpec[i + '_d'];
- return ret;
- },
-
- programs: [],
- program: function program(i, data, declaredBlockParams, blockParams, depths) {
- var programWrapper = this.programs[i],
- fn = this.fn(i);
- if (data || depths || blockParams || declaredBlockParams) {
- programWrapper = wrapProgram(this, i, fn, data, declaredBlockParams, blockParams, depths);
- } else if (!programWrapper) {
- programWrapper = this.programs[i] = wrapProgram(this, i, fn);
- }
- return programWrapper;
- },
-
- data: function data(value, depth) {
- while (value && depth--) {
- value = value._parent;
- }
- return value;
- },
- merge: function merge(param, common) {
- var obj = param || common;
-
- if (param && common && param !== common) {
- obj = Utils.extend({}, common, param);
- }
-
- return obj;
- },
-
- noop: env.VM.noop,
- compilerInfo: templateSpec.compiler
- };
-
- function ret(context) {
- var options = arguments.length <= 1 || arguments[1] === undefined ? {} : arguments[1];
-
- var data = options.data;
-
- ret._setup(options);
- if (!options.partial && templateSpec.useData) {
- data = initData(context, data);
- }
- var depths = undefined,
- blockParams = templateSpec.useBlockParams ? [] : undefined;
- if (templateSpec.useDepths) {
- if (options.depths) {
- depths = context !== options.depths[0] ? [context].concat(options.depths) : options.depths;
- } else {
- depths = [context];
- }
- }
-
- function main(context /*, options*/) {
- return '' + templateSpec.main(container, context, container.helpers, container.partials, data, blockParams, depths);
- }
- main = executeDecorators(templateSpec.main, main, container, options.depths || [], data, blockParams);
- return main(context, options);
- }
- ret.isTop = true;
-
- ret._setup = function (options) {
- if (!options.partial) {
- container.helpers = container.merge(options.helpers, env.helpers);
-
- if (templateSpec.usePartial) {
- container.partials = container.merge(options.partials, env.partials);
- }
- if (templateSpec.usePartial || templateSpec.useDecorators) {
- container.decorators = container.merge(options.decorators, env.decorators);
- }
- } else {
- container.helpers = options.helpers;
- container.partials = options.partials;
- container.decorators = options.decorators;
- }
- };
-
- ret._child = function (i, data, blockParams, depths) {
- if (templateSpec.useBlockParams && !blockParams) {
- throw new _exception2['default']('must pass block params');
- }
- if (templateSpec.useDepths && !depths) {
- throw new _exception2['default']('must pass parent depths');
- }
-
- return wrapProgram(container, i, templateSpec[i], data, 0, blockParams, depths);
- };
- return ret;
- }
-
- function wrapProgram(container, i, fn, data, declaredBlockParams, blockParams, depths) {
- function prog(context) {
- var options = arguments.length <= 1 || arguments[1] === undefined ? {} : arguments[1];
-
- var currentDepths = depths;
- if (depths && context !== depths[0]) {
- currentDepths = [context].concat(depths);
- }
-
- return fn(container, context, container.helpers, container.partials, options.data || data, blockParams && [options.blockParams].concat(blockParams), currentDepths);
- }
-
- prog = executeDecorators(fn, prog, container, depths, data, blockParams);
-
- prog.program = i;
- prog.depth = depths ? depths.length : 0;
- prog.blockParams = declaredBlockParams || 0;
- return prog;
- }
-
- function resolvePartial(partial, context, options) {
- if (!partial) {
- if (options.name === '@partial-block') {
- partial = options.data['partial-block'];
- } else {
- partial = options.partials[options.name];
- }
- } else if (!partial.call && !options.name) {
- // This is a dynamic partial that returned a string
- options.name = partial;
- partial = options.partials[partial];
- }
- return partial;
- }
-
- function invokePartial(partial, context, options) {
- options.partial = true;
- if (options.ids) {
- options.data.contextPath = options.ids[0] || options.data.contextPath;
- }
-
- var partialBlock = undefined;
- if (options.fn && options.fn !== noop) {
- options.data = _base.createFrame(options.data);
- partialBlock = options.data['partial-block'] = options.fn;
-
- if (partialBlock.partials) {
- options.partials = Utils.extend({}, options.partials, partialBlock.partials);
- }
- }
-
- if (partial === undefined && partialBlock) {
- partial = partialBlock;
- }
-
- if (partial === undefined) {
- throw new _exception2['default']('The partial ' + options.name + ' could not be found');
- } else if (partial instanceof Function) {
- return partial(context, options);
- }
- }
-
- function noop() {
- return '';
- }
-
- function initData(context, data) {
- if (!data || !('root' in data)) {
- data = data ? _base.createFrame(data) : {};
- data.root = context;
- }
- return data;
- }
-
- function executeDecorators(fn, prog, container, depths, data, blockParams) {
- if (fn.decorator) {
- var props = {};
- prog = fn.decorator(prog, props, container, depths && depths[0], data, blockParams, depths);
- Utils.extend(prog, props);
- }
- return prog;
- }
-
-/***/ },
-/* 20 */
-/***/ function(module, exports) {
-
- /* WEBPACK VAR INJECTION */(function(global) {/* global window */
- 'use strict';
-
- exports.__esModule = true;
-
- exports['default'] = function (Handlebars) {
- /* istanbul ignore next */
- var root = typeof global !== 'undefined' ? global : window,
- $Handlebars = root.Handlebars;
- /* istanbul ignore next */
- Handlebars.noConflict = function () {
- if (root.Handlebars === Handlebars) {
- root.Handlebars = $Handlebars;
- }
- return Handlebars;
- };
- };
-
- module.exports = exports['default'];
- /* WEBPACK VAR INJECTION */}.call(exports, (function() { return this; }())))
-
-/***/ },
-/* 21 */
-/***/ function(module, exports) {
-
- 'use strict';
-
- exports.__esModule = true;
- var AST = {
- // Public API used to evaluate derived attributes regarding AST nodes
- helpers: {
- // a mustache is definitely a helper if:
- // * it is an eligible helper, and
- // * it has at least one parameter or hash segment
- helperExpression: function helperExpression(node) {
- return node.type === 'SubExpression' || (node.type === 'MustacheStatement' || node.type === 'BlockStatement') && !!(node.params && node.params.length || node.hash);
- },
-
- scopedId: function scopedId(path) {
- return (/^\.|this\b/.test(path.original)
- );
- },
-
- // an ID is simple if it only has one part, and that part is not
- // `..` or `this`.
- simpleId: function simpleId(path) {
- return path.parts.length === 1 && !AST.helpers.scopedId(path) && !path.depth;
- }
- }
- };
-
- // Must be exported as an object rather than the root of the module as the jison lexer
- // must modify the object to operate properly.
- exports['default'] = AST;
- module.exports = exports['default'];
-
-/***/ },
-/* 22 */
-/***/ function(module, exports, __webpack_require__) {
-
- 'use strict';
-
- var _interopRequireDefault = __webpack_require__(1)['default'];
-
- var _interopRequireWildcard = __webpack_require__(3)['default'];
-
- exports.__esModule = true;
- exports.parse = parse;
-
- var _parser = __webpack_require__(23);
-
- var _parser2 = _interopRequireDefault(_parser);
-
- var _whitespaceControl = __webpack_require__(24);
-
- var _whitespaceControl2 = _interopRequireDefault(_whitespaceControl);
-
- var _helpers = __webpack_require__(26);
-
- var Helpers = _interopRequireWildcard(_helpers);
-
- var _utils = __webpack_require__(5);
-
- exports.parser = _parser2['default'];
-
- var yy = {};
- _utils.extend(yy, Helpers);
-
- function parse(input, options) {
- // Just return if an already-compiled AST was passed in.
- if (input.type === 'Program') {
- return input;
- }
-
- _parser2['default'].yy = yy;
-
- // Altering the shared object here, but this is ok as parser is a sync operation
- yy.locInfo = function (locInfo) {
- return new yy.SourceLocation(options && options.srcName, locInfo);
- };
-
- var strip = new _whitespaceControl2['default'](options);
- return strip.accept(_parser2['default'].parse(input));
- }
-
-/***/ },
-/* 23 */
-/***/ function(module, exports) {
-
- /* istanbul ignore next */
- /* Jison generated parser */
- "use strict";
-
- var handlebars = (function () {
- var parser = { trace: function trace() {},
- yy: {},
- symbols_: { "error": 2, "root": 3, "program": 4, "EOF": 5, "program_repetition0": 6, "statement": 7, "mustache": 8, "block": 9, "rawBlock": 10, "partial": 11, "partialBlock": 12, "content": 13, "COMMENT": 14, "CONTENT": 15, "openRawBlock": 16, "rawBlock_repetition_plus0": 17, "END_RAW_BLOCK": 18, "OPEN_RAW_BLOCK": 19, "helperName": 20, "openRawBlock_repetition0": 21, "openRawBlock_option0": 22, "CLOSE_RAW_BLOCK": 23, "openBlock": 24, "block_option0": 25, "closeBlock": 26, "openInverse": 27, "block_option1": 28, "OPEN_BLOCK": 29, "openBlock_repetition0": 30, "openBlock_option0": 31, "openBlock_option1": 32, "CLOSE": 33, "OPEN_INVERSE": 34, "openInverse_repetition0": 35, "openInverse_option0": 36, "openInverse_option1": 37, "openInverseChain": 38, "OPEN_INVERSE_CHAIN": 39, "openInverseChain_repetition0": 40, "openInverseChain_option0": 41, "openInverseChain_option1": 42, "inverseAndProgram": 43, "INVERSE": 44, "inverseChain": 45, "inverseChain_option0": 46, "OPEN_ENDBLOCK": 47, "OPEN": 48, "mustache_repetition0": 49, "mustache_option0": 50, "OPEN_UNESCAPED": 51, "mustache_repetition1": 52, "mustache_option1": 53, "CLOSE_UNESCAPED": 54, "OPEN_PARTIAL": 55, "partialName": 56, "partial_repetition0": 57, "partial_option0": 58, "openPartialBlock": 59, "OPEN_PARTIAL_BLOCK": 60, "openPartialBlock_repetition0": 61, "openPartialBlock_option0": 62, "param": 63, "sexpr": 64, "OPEN_SEXPR": 65, "sexpr_repetition0": 66, "sexpr_option0": 67, "CLOSE_SEXPR": 68, "hash": 69, "hash_repetition_plus0": 70, "hashSegment": 71, "ID": 72, "EQUALS": 73, "blockParams": 74, "OPEN_BLOCK_PARAMS": 75, "blockParams_repetition_plus0": 76, "CLOSE_BLOCK_PARAMS": 77, "path": 78, "dataName": 79, "STRING": 80, "NUMBER": 81, "BOOLEAN": 82, "UNDEFINED": 83, "NULL": 84, "DATA": 85, "pathSegments": 86, "SEP": 87, "$accept": 0, "$end": 1 },
- terminals_: { 2: "error", 5: "EOF", 14: "COMMENT", 15: "CONTENT", 18: "END_RAW_BLOCK", 19: "OPEN_RAW_BLOCK", 23: "CLOSE_RAW_BLOCK", 29: "OPEN_BLOCK", 33: "CLOSE", 34: "OPEN_INVERSE", 39: "OPEN_INVERSE_CHAIN", 44: "INVERSE", 47: "OPEN_ENDBLOCK", 48: "OPEN", 51: "OPEN_UNESCAPED", 54: "CLOSE_UNESCAPED", 55: "OPEN_PARTIAL", 60: "OPEN_PARTIAL_BLOCK", 65: "OPEN_SEXPR", 68: "CLOSE_SEXPR", 72: "ID", 73: "EQUALS", 75: "OPEN_BLOCK_PARAMS", 77: "CLOSE_BLOCK_PARAMS", 80: "STRING", 81: "NUMBER", 82: "BOOLEAN", 83: "UNDEFINED", 84: "NULL", 85: "DATA", 87: "SEP" },
- productions_: [0, [3, 2], [4, 1], [7, 1], [7, 1], [7, 1], [7, 1], [7, 1], [7, 1], [7, 1], [13, 1], [10, 3], [16, 5], [9, 4], [9, 4], [24, 6], [27, 6], [38, 6], [43, 2], [45, 3], [45, 1], [26, 3], [8, 5], [8, 5], [11, 5], [12, 3], [59, 5], [63, 1], [63, 1], [64, 5], [69, 1], [71, 3], [74, 3], [20, 1], [20, 1], [20, 1], [20, 1], [20, 1], [20, 1], [20, 1], [56, 1], [56, 1], [79, 2], [78, 1], [86, 3], [86, 1], [6, 0], [6, 2], [17, 1], [17, 2], [21, 0], [21, 2], [22, 0], [22, 1], [25, 0], [25, 1], [28, 0], [28, 1], [30, 0], [30, 2], [31, 0], [31, 1], [32, 0], [32, 1], [35, 0], [35, 2], [36, 0], [36, 1], [37, 0], [37, 1], [40, 0], [40, 2], [41, 0], [41, 1], [42, 0], [42, 1], [46, 0], [46, 1], [49, 0], [49, 2], [50, 0], [50, 1], [52, 0], [52, 2], [53, 0], [53, 1], [57, 0], [57, 2], [58, 0], [58, 1], [61, 0], [61, 2], [62, 0], [62, 1], [66, 0], [66, 2], [67, 0], [67, 1], [70, 1], [70, 2], [76, 1], [76, 2]],
- performAction: function anonymous(yytext, yyleng, yylineno, yy, yystate, $$, _$
- /**/) {
-
- var $0 = $$.length - 1;
- switch (yystate) {
- case 1:
- return $$[$0 - 1];
- break;
- case 2:
- this.$ = yy.prepareProgram($$[$0]);
- break;
- case 3:
- this.$ = $$[$0];
- break;
- case 4:
- this.$ = $$[$0];
- break;
- case 5:
- this.$ = $$[$0];
- break;
- case 6:
- this.$ = $$[$0];
- break;
- case 7:
- this.$ = $$[$0];
- break;
- case 8:
- this.$ = $$[$0];
- break;
- case 9:
- this.$ = {
- type: 'CommentStatement',
- value: yy.stripComment($$[$0]),
- strip: yy.stripFlags($$[$0], $$[$0]),
- loc: yy.locInfo(this._$)
- };
-
- break;
- case 10:
- this.$ = {
- type: 'ContentStatement',
- original: $$[$0],
- value: $$[$0],
- loc: yy.locInfo(this._$)
- };
-
- break;
- case 11:
- this.$ = yy.prepareRawBlock($$[$0 - 2], $$[$0 - 1], $$[$0], this._$);
- break;
- case 12:
- this.$ = { path: $$[$0 - 3], params: $$[$0 - 2], hash: $$[$0 - 1] };
- break;
- case 13:
- this.$ = yy.prepareBlock($$[$0 - 3], $$[$0 - 2], $$[$0 - 1], $$[$0], false, this._$);
- break;
- case 14:
- this.$ = yy.prepareBlock($$[$0 - 3], $$[$0 - 2], $$[$0 - 1], $$[$0], true, this._$);
- break;
- case 15:
- this.$ = { open: $$[$0 - 5], path: $$[$0 - 4], params: $$[$0 - 3], hash: $$[$0 - 2], blockParams: $$[$0 - 1], strip: yy.stripFlags($$[$0 - 5], $$[$0]) };
- break;
- case 16:
- this.$ = { path: $$[$0 - 4], params: $$[$0 - 3], hash: $$[$0 - 2], blockParams: $$[$0 - 1], strip: yy.stripFlags($$[$0 - 5], $$[$0]) };
- break;
- case 17:
- this.$ = { path: $$[$0 - 4], params: $$[$0 - 3], hash: $$[$0 - 2], blockParams: $$[$0 - 1], strip: yy.stripFlags($$[$0 - 5], $$[$0]) };
- break;
- case 18:
- this.$ = { strip: yy.stripFlags($$[$0 - 1], $$[$0 - 1]), program: $$[$0] };
- break;
- case 19:
- var inverse = yy.prepareBlock($$[$0 - 2], $$[$0 - 1], $$[$0], $$[$0], false, this._$),
- program = yy.prepareProgram([inverse], $$[$0 - 1].loc);
- program.chained = true;
-
- this.$ = { strip: $$[$0 - 2].strip, program: program, chain: true };
-
- break;
- case 20:
- this.$ = $$[$0];
- break;
- case 21:
- this.$ = { path: $$[$0 - 1], strip: yy.stripFlags($$[$0 - 2], $$[$0]) };
- break;
- case 22:
- this.$ = yy.prepareMustache($$[$0 - 3], $$[$0 - 2], $$[$0 - 1], $$[$0 - 4], yy.stripFlags($$[$0 - 4], $$[$0]), this._$);
- break;
- case 23:
- this.$ = yy.prepareMustache($$[$0 - 3], $$[$0 - 2], $$[$0 - 1], $$[$0 - 4], yy.stripFlags($$[$0 - 4], $$[$0]), this._$);
- break;
- case 24:
- this.$ = {
- type: 'PartialStatement',
- name: $$[$0 - 3],
- params: $$[$0 - 2],
- hash: $$[$0 - 1],
- indent: '',
- strip: yy.stripFlags($$[$0 - 4], $$[$0]),
- loc: yy.locInfo(this._$)
- };
-
- break;
- case 25:
- this.$ = yy.preparePartialBlock($$[$0 - 2], $$[$0 - 1], $$[$0], this._$);
- break;
- case 26:
- this.$ = { path: $$[$0 - 3], params: $$[$0 - 2], hash: $$[$0 - 1], strip: yy.stripFlags($$[$0 - 4], $$[$0]) };
- break;
- case 27:
- this.$ = $$[$0];
- break;
- case 28:
- this.$ = $$[$0];
- break;
- case 29:
- this.$ = {
- type: 'SubExpression',
- path: $$[$0 - 3],
- params: $$[$0 - 2],
- hash: $$[$0 - 1],
- loc: yy.locInfo(this._$)
- };
-
- break;
- case 30:
- this.$ = { type: 'Hash', pairs: $$[$0], loc: yy.locInfo(this._$) };
- break;
- case 31:
- this.$ = { type: 'HashPair', key: yy.id($$[$0 - 2]), value: $$[$0], loc: yy.locInfo(this._$) };
- break;
- case 32:
- this.$ = yy.id($$[$0 - 1]);
- break;
- case 33:
- this.$ = $$[$0];
- break;
- case 34:
- this.$ = $$[$0];
- break;
- case 35:
- this.$ = { type: 'StringLiteral', value: $$[$0], original: $$[$0], loc: yy.locInfo(this._$) };
- break;
- case 36:
- this.$ = { type: 'NumberLiteral', value: Number($$[$0]), original: Number($$[$0]), loc: yy.locInfo(this._$) };
- break;
- case 37:
- this.$ = { type: 'BooleanLiteral', value: $$[$0] === 'true', original: $$[$0] === 'true', loc: yy.locInfo(this._$) };
- break;
- case 38:
- this.$ = { type: 'UndefinedLiteral', original: undefined, value: undefined, loc: yy.locInfo(this._$) };
- break;
- case 39:
- this.$ = { type: 'NullLiteral', original: null, value: null, loc: yy.locInfo(this._$) };
- break;
- case 40:
- this.$ = $$[$0];
- break;
- case 41:
- this.$ = $$[$0];
- break;
- case 42:
- this.$ = yy.preparePath(true, $$[$0], this._$);
- break;
- case 43:
- this.$ = yy.preparePath(false, $$[$0], this._$);
- break;
- case 44:
- $$[$0 - 2].push({ part: yy.id($$[$0]), original: $$[$0], separator: $$[$0 - 1] });this.$ = $$[$0 - 2];
- break;
- case 45:
- this.$ = [{ part: yy.id($$[$0]), original: $$[$0] }];
- break;
- case 46:
- this.$ = [];
- break;
- case 47:
- $$[$0 - 1].push($$[$0]);
- break;
- case 48:
- this.$ = [$$[$0]];
- break;
- case 49:
- $$[$0 - 1].push($$[$0]);
- break;
- case 50:
- this.$ = [];
- break;
- case 51:
- $$[$0 - 1].push($$[$0]);
- break;
- case 58:
- this.$ = [];
- break;
- case 59:
- $$[$0 - 1].push($$[$0]);
- break;
- case 64:
- this.$ = [];
- break;
- case 65:
- $$[$0 - 1].push($$[$0]);
- break;
- case 70:
- this.$ = [];
- break;
- case 71:
- $$[$0 - 1].push($$[$0]);
- break;
- case 78:
- this.$ = [];
- break;
- case 79:
- $$[$0 - 1].push($$[$0]);
- break;
- case 82:
- this.$ = [];
- break;
- case 83:
- $$[$0 - 1].push($$[$0]);
- break;
- case 86:
- this.$ = [];
- break;
- case 87:
- $$[$0 - 1].push($$[$0]);
- break;
- case 90:
- this.$ = [];
- break;
- case 91:
- $$[$0 - 1].push($$[$0]);
- break;
- case 94:
- this.$ = [];
- break;
- case 95:
- $$[$0 - 1].push($$[$0]);
- break;
- case 98:
- this.$ = [$$[$0]];
- break;
- case 99:
- $$[$0 - 1].push($$[$0]);
- break;
- case 100:
- this.$ = [$$[$0]];
- break;
- case 101:
- $$[$0 - 1].push($$[$0]);
- break;
- }
- },
- table: [{ 3: 1, 4: 2, 5: [2, 46], 6: 3, 14: [2, 46], 15: [2, 46], 19: [2, 46], 29: [2, 46], 34: [2, 46], 48: [2, 46], 51: [2, 46], 55: [2, 46], 60: [2, 46] }, { 1: [3] }, { 5: [1, 4] }, { 5: [2, 2], 7: 5, 8: 6, 9: 7, 10: 8, 11: 9, 12: 10, 13: 11, 14: [1, 12], 15: [1, 20], 16: 17, 19: [1, 23], 24: 15, 27: 16, 29: [1, 21], 34: [1, 22], 39: [2, 2], 44: [2, 2], 47: [2, 2], 48: [1, 13], 51: [1, 14], 55: [1, 18], 59: 19, 60: [1, 24] }, { 1: [2, 1] }, { 5: [2, 47], 14: [2, 47], 15: [2, 47], 19: [2, 47], 29: [2, 47], 34: [2, 47], 39: [2, 47], 44: [2, 47], 47: [2, 47], 48: [2, 47], 51: [2, 47], 55: [2, 47], 60: [2, 47] }, { 5: [2, 3], 14: [2, 3], 15: [2, 3], 19: [2, 3], 29: [2, 3], 34: [2, 3], 39: [2, 3], 44: [2, 3], 47: [2, 3], 48: [2, 3], 51: [2, 3], 55: [2, 3], 60: [2, 3] }, { 5: [2, 4], 14: [2, 4], 15: [2, 4], 19: [2, 4], 29: [2, 4], 34: [2, 4], 39: [2, 4], 44: [2, 4], 47: [2, 4], 48: [2, 4], 51: [2, 4], 55: [2, 4], 60: [2, 4] }, { 5: [2, 5], 14: [2, 5], 15: [2, 5], 19: [2, 5], 29: [2, 5], 34: [2, 5], 39: [2, 5], 44: [2, 5], 47: [2, 5], 48: [2, 5], 51: [2, 5], 55: [2, 5], 60: [2, 5] }, { 5: [2, 6], 14: [2, 6], 15: [2, 6], 19: [2, 6], 29: [2, 6], 34: [2, 6], 39: [2, 6], 44: [2, 6], 47: [2, 6], 48: [2, 6], 51: [2, 6], 55: [2, 6], 60: [2, 6] }, { 5: [2, 7], 14: [2, 7], 15: [2, 7], 19: [2, 7], 29: [2, 7], 34: [2, 7], 39: [2, 7], 44: [2, 7], 47: [2, 7], 48: [2, 7], 51: [2, 7], 55: [2, 7], 60: [2, 7] }, { 5: [2, 8], 14: [2, 8], 15: [2, 8], 19: [2, 8], 29: [2, 8], 34: [2, 8], 39: [2, 8], 44: [2, 8], 47: [2, 8], 48: [2, 8], 51: [2, 8], 55: [2, 8], 60: [2, 8] }, { 5: [2, 9], 14: [2, 9], 15: [2, 9], 19: [2, 9], 29: [2, 9], 34: [2, 9], 39: [2, 9], 44: [2, 9], 47: [2, 9], 48: [2, 9], 51: [2, 9], 55: [2, 9], 60: [2, 9] }, { 20: 25, 72: [1, 35], 78: 26, 79: 27, 80: [1, 28], 81: [1, 29], 82: [1, 30], 83: [1, 31], 84: [1, 32], 85: [1, 34], 86: 33 }, { 20: 36, 72: [1, 35], 78: 26, 79: 27, 80: [1, 28], 81: [1, 29], 82: [1, 30], 83: [1, 31], 84: [1, 32], 85: [1, 34], 86: 33 }, { 4: 37, 6: 3, 14: [2, 46], 15: [2, 46], 19: [2, 46], 29: [2, 46], 34: [2, 46], 39: [2, 46], 44: [2, 46], 47: [2, 46], 48: [2, 46], 51: [2, 46], 55: [2, 46], 60: [2, 46] }, { 4: 38, 6: 3, 14: [2, 46], 15: [2, 46], 19: [2, 46], 29: [2, 46], 34: [2, 46], 44: [2, 46], 47: [2, 46], 48: [2, 46], 51: [2, 46], 55: [2, 46], 60: [2, 46] }, { 13: 40, 15: [1, 20], 17: 39 }, { 20: 42, 56: 41, 64: 43, 65: [1, 44], 72: [1, 35], 78: 26, 79: 27, 80: [1, 28], 81: [1, 29], 82: [1, 30], 83: [1, 31], 84: [1, 32], 85: [1, 34], 86: 33 }, { 4: 45, 6: 3, 14: [2, 46], 15: [2, 46], 19: [2, 46], 29: [2, 46], 34: [2, 46], 47: [2, 46], 48: [2, 46], 51: [2, 46], 55: [2, 46], 60: [2, 46] }, { 5: [2, 10], 14: [2, 10], 15: [2, 10], 18: [2, 10], 19: [2, 10], 29: [2, 10], 34: [2, 10], 39: [2, 10], 44: [2, 10], 47: [2, 10], 48: [2, 10], 51: [2, 10], 55: [2, 10], 60: [2, 10] }, { 20: 46, 72: [1, 35], 78: 26, 79: 27, 80: [1, 28], 81: [1, 29], 82: [1, 30], 83: [1, 31], 84: [1, 32], 85: [1, 34], 86: 33 }, { 20: 47, 72: [1, 35], 78: 26, 79: 27, 80: [1, 28], 81: [1, 29], 82: [1, 30], 83: [1, 31], 84: [1, 32], 85: [1, 34], 86: 33 }, { 20: 48, 72: [1, 35], 78: 26, 79: 27, 80: [1, 28], 81: [1, 29], 82: [1, 30], 83: [1, 31], 84: [1, 32], 85: [1, 34], 86: 33 }, { 20: 42, 56: 49, 64: 43, 65: [1, 44], 72: [1, 35], 78: 26, 79: 27, 80: [1, 28], 81: [1, 29], 82: [1, 30], 83: [1, 31], 84: [1, 32], 85: [1, 34], 86: 33 }, { 33: [2, 78], 49: 50, 65: [2, 78], 72: [2, 78], 80: [2, 78], 81: [2, 78], 82: [2, 78], 83: [2, 78], 84: [2, 78], 85: [2, 78] }, { 23: [2, 33], 33: [2, 33], 54: [2, 33], 65: [2, 33], 68: [2, 33], 72: [2, 33], 75: [2, 33], 80: [2, 33], 81: [2, 33], 82: [2, 33], 83: [2, 33], 84: [2, 33], 85: [2, 33] }, { 23: [2, 34], 33: [2, 34], 54: [2, 34], 65: [2, 34], 68: [2, 34], 72: [2, 34], 75: [2, 34], 80: [2, 34], 81: [2, 34], 82: [2, 34], 83: [2, 34], 84: [2, 34], 85: [2, 34] }, { 23: [2, 35], 33: [2, 35], 54: [2, 35], 65: [2, 35], 68: [2, 35], 72: [2, 35], 75: [2, 35], 80: [2, 35], 81: [2, 35], 82: [2, 35], 83: [2, 35], 84: [2, 35], 85: [2, 35] }, { 23: [2, 36], 33: [2, 36], 54: [2, 36], 65: [2, 36], 68: [2, 36], 72: [2, 36], 75: [2, 36], 80: [2, 36], 81: [2, 36], 82: [2, 36], 83: [2, 36], 84: [2, 36], 85: [2, 36] }, { 23: [2, 37], 33: [2, 37], 54: [2, 37], 65: [2, 37], 68: [2, 37], 72: [2, 37], 75: [2, 37], 80: [2, 37], 81: [2, 37], 82: [2, 37], 83: [2, 37], 84: [2, 37], 85: [2, 37] }, { 23: [2, 38], 33: [2, 38], 54: [2, 38], 65: [2, 38], 68: [2, 38], 72: [2, 38], 75: [2, 38], 80: [2, 38], 81: [2, 38], 82: [2, 38], 83: [2, 38], 84: [2, 38], 85: [2, 38] }, { 23: [2, 39], 33: [2, 39], 54: [2, 39], 65: [2, 39], 68: [2, 39], 72: [2, 39], 75: [2, 39], 80: [2, 39], 81: [2, 39], 82: [2, 39], 83: [2, 39], 84: [2, 39], 85: [2, 39] }, { 23: [2, 43], 33: [2, 43], 54: [2, 43], 65: [2, 43], 68: [2, 43], 72: [2, 43], 75: [2, 43], 80: [2, 43], 81: [2, 43], 82: [2, 43], 83: [2, 43], 84: [2, 43], 85: [2, 43], 87: [1, 51] }, { 72: [1, 35], 86: 52 }, { 23: [2, 45], 33: [2, 45], 54: [2, 45], 65: [2, 45], 68: [2, 45], 72: [2, 45], 75: [2, 45], 80: [2, 45], 81: [2, 45], 82: [2, 45], 83: [2, 45], 84: [2, 45], 85: [2, 45], 87: [2, 45] }, { 52: 53, 54: [2, 82], 65: [2, 82], 72: [2, 82], 80: [2, 82], 81: [2, 82], 82: [2, 82], 83: [2, 82], 84: [2, 82], 85: [2, 82] }, { 25: 54, 38: 56, 39: [1, 58], 43: 57, 44: [1, 59], 45: 55, 47: [2, 54] }, { 28: 60, 43: 61, 44: [1, 59], 47: [2, 56] }, { 13: 63, 15: [1, 20], 18: [1, 62] }, { 15: [2, 48], 18: [2, 48] }, { 33: [2, 86], 57: 64, 65: [2, 86], 72: [2, 86], 80: [2, 86], 81: [2, 86], 82: [2, 86], 83: [2, 86], 84: [2, 86], 85: [2, 86] }, { 33: [2, 40], 65: [2, 40], 72: [2, 40], 80: [2, 40], 81: [2, 40], 82: [2, 40], 83: [2, 40], 84: [2, 40], 85: [2, 40] }, { 33: [2, 41], 65: [2, 41], 72: [2, 41], 80: [2, 41], 81: [2, 41], 82: [2, 41], 83: [2, 41], 84: [2, 41], 85: [2, 41] }, { 20: 65, 72: [1, 35], 78: 26, 79: 27, 80: [1, 28], 81: [1, 29], 82: [1, 30], 83: [1, 31], 84: [1, 32], 85: [1, 34], 86: 33 }, { 26: 66, 47: [1, 67] }, { 30: 68, 33: [2, 58], 65: [2, 58], 72: [2, 58], 75: [2, 58], 80: [2, 58], 81: [2, 58], 82: [2, 58], 83: [2, 58], 84: [2, 58], 85: [2, 58] }, { 33: [2, 64], 35: 69, 65: [2, 64], 72: [2, 64], 75: [2, 64], 80: [2, 64], 81: [2, 64], 82: [2, 64], 83: [2, 64], 84: [2, 64], 85: [2, 64] }, { 21: 70, 23: [2, 50], 65: [2, 50], 72: [2, 50], 80: [2, 50], 81: [2, 50], 82: [2, 50], 83: [2, 50], 84: [2, 50], 85: [2, 50] }, { 33: [2, 90], 61: 71, 65: [2, 90], 72: [2, 90], 80: [2, 90], 81: [2, 90], 82: [2, 90], 83: [2, 90], 84: [2, 90], 85: [2, 90] }, { 20: 75, 33: [2, 80], 50: 72, 63: 73, 64: 76, 65: [1, 44], 69: 74, 70: 77, 71: 78, 72: [1, 79], 78: 26, 79: 27, 80: [1, 28], 81: [1, 29], 82: [1, 30], 83: [1, 31], 84: [1, 32], 85: [1, 34], 86: 33 }, { 72: [1, 80] }, { 23: [2, 42], 33: [2, 42], 54: [2, 42], 65: [2, 42], 68: [2, 42], 72: [2, 42], 75: [2, 42], 80: [2, 42], 81: [2, 42], 82: [2, 42], 83: [2, 42], 84: [2, 42], 85: [2, 42], 87: [1, 51] }, { 20: 75, 53: 81, 54: [2, 84], 63: 82, 64: 76, 65: [1, 44], 69: 83, 70: 77, 71: 78, 72: [1, 79], 78: 26, 79: 27, 80: [1, 28], 81: [1, 29], 82: [1, 30], 83: [1, 31], 84: [1, 32], 85: [1, 34], 86: 33 }, { 26: 84, 47: [1, 67] }, { 47: [2, 55] }, { 4: 85, 6: 3, 14: [2, 46], 15: [2, 46], 19: [2, 46], 29: [2, 46], 34: [2, 46], 39: [2, 46], 44: [2, 46], 47: [2, 46], 48: [2, 46], 51: [2, 46], 55: [2, 46], 60: [2, 46] }, { 47: [2, 20] }, { 20: 86, 72: [1, 35], 78: 26, 79: 27, 80: [1, 28], 81: [1, 29], 82: [1, 30], 83: [1, 31], 84: [1, 32], 85: [1, 34], 86: 33 }, { 4: 87, 6: 3, 14: [2, 46], 15: [2, 46], 19: [2, 46], 29: [2, 46], 34: [2, 46], 47: [2, 46], 48: [2, 46], 51: [2, 46], 55: [2, 46], 60: [2, 46] }, { 26: 88, 47: [1, 67] }, { 47: [2, 57] }, { 5: [2, 11], 14: [2, 11], 15: [2, 11], 19: [2, 11], 29: [2, 11], 34: [2, 11], 39: [2, 11], 44: [2, 11], 47: [2, 11], 48: [2, 11], 51: [2, 11], 55: [2, 11], 60: [2, 11] }, { 15: [2, 49], 18: [2, 49] }, { 20: 75, 33: [2, 88], 58: 89, 63: 90, 64: 76, 65: [1, 44], 69: 91, 70: 77, 71: 78, 72: [1, 79], 78: 26, 79: 27, 80: [1, 28], 81: [1, 29], 82: [1, 30], 83: [1, 31], 84: [1, 32], 85: [1, 34], 86: 33 }, { 65: [2, 94], 66: 92, 68: [2, 94], 72: [2, 94], 80: [2, 94], 81: [2, 94], 82: [2, 94], 83: [2, 94], 84: [2, 94], 85: [2, 94] }, { 5: [2, 25], 14: [2, 25], 15: [2, 25], 19: [2, 25], 29: [2, 25], 34: [2, 25], 39: [2, 25], 44: [2, 25], 47: [2, 25], 48: [2, 25], 51: [2, 25], 55: [2, 25], 60: [2, 25] }, { 20: 93, 72: [1, 35], 78: 26, 79: 27, 80: [1, 28], 81: [1, 29], 82: [1, 30], 83: [1, 31], 84: [1, 32], 85: [1, 34], 86: 33 }, { 20: 75, 31: 94, 33: [2, 60], 63: 95, 64: 76, 65: [1, 44], 69: 96, 70: 77, 71: 78, 72: [1, 79], 75: [2, 60], 78: 26, 79: 27, 80: [1, 28], 81: [1, 29], 82: [1, 30], 83: [1, 31], 84: [1, 32], 85: [1, 34], 86: 33 }, { 20: 75, 33: [2, 66], 36: 97, 63: 98, 64: 76, 65: [1, 44], 69: 99, 70: 77, 71: 78, 72: [1, 79], 75: [2, 66], 78: 26, 79: 27, 80: [1, 28], 81: [1, 29], 82: [1, 30], 83: [1, 31], 84: [1, 32], 85: [1, 34], 86: 33 }, { 20: 75, 22: 100, 23: [2, 52], 63: 101, 64: 76, 65: [1, 44], 69: 102, 70: 77, 71: 78, 72: [1, 79], 78: 26, 79: 27, 80: [1, 28], 81: [1, 29], 82: [1, 30], 83: [1, 31], 84: [1, 32], 85: [1, 34], 86: 33 }, { 20: 75, 33: [2, 92], 62: 103, 63: 104, 64: 76, 65: [1, 44], 69: 105, 70: 77, 71: 78, 72: [1, 79], 78: 26, 79: 27, 80: [1, 28], 81: [1, 29], 82: [1, 30], 83: [1, 31], 84: [1, 32], 85: [1, 34], 86: 33 }, { 33: [1, 106] }, { 33: [2, 79], 65: [2, 79], 72: [2, 79], 80: [2, 79], 81: [2, 79], 82: [2, 79], 83: [2, 79], 84: [2, 79], 85: [2, 79] }, { 33: [2, 81] }, { 23: [2, 27], 33: [2, 27], 54: [2, 27], 65: [2, 27], 68: [2, 27], 72: [2, 27], 75: [2, 27], 80: [2, 27], 81: [2, 27], 82: [2, 27], 83: [2, 27], 84: [2, 27], 85: [2, 27] }, { 23: [2, 28], 33: [2, 28], 54: [2, 28], 65: [2, 28], 68: [2, 28], 72: [2, 28], 75: [2, 28], 80: [2, 28], 81: [2, 28], 82: [2, 28], 83: [2, 28], 84: [2, 28], 85: [2, 28] }, { 23: [2, 30], 33: [2, 30], 54: [2, 30], 68: [2, 30], 71: 107, 72: [1, 108], 75: [2, 30] }, { 23: [2, 98], 33: [2, 98], 54: [2, 98], 68: [2, 98], 72: [2, 98], 75: [2, 98] }, { 23: [2, 45], 33: [2, 45], 54: [2, 45], 65: [2, 45], 68: [2, 45], 72: [2, 45], 73: [1, 109], 75: [2, 45], 80: [2, 45], 81: [2, 45], 82: [2, 45], 83: [2, 45], 84: [2, 45], 85: [2, 45], 87: [2, 45] }, { 23: [2, 44], 33: [2, 44], 54: [2, 44], 65: [2, 44], 68: [2, 44], 72: [2, 44], 75: [2, 44], 80: [2, 44], 81: [2, 44], 82: [2, 44], 83: [2, 44], 84: [2, 44], 85: [2, 44], 87: [2, 44] }, { 54: [1, 110] }, { 54: [2, 83], 65: [2, 83], 72: [2, 83], 80: [2, 83], 81: [2, 83], 82: [2, 83], 83: [2, 83], 84: [2, 83], 85: [2, 83] }, { 54: [2, 85] }, { 5: [2, 13], 14: [2, 13], 15: [2, 13], 19: [2, 13], 29: [2, 13], 34: [2, 13], 39: [2, 13], 44: [2, 13], 47: [2, 13], 48: [2, 13], 51: [2, 13], 55: [2, 13], 60: [2, 13] }, { 38: 56, 39: [1, 58], 43: 57, 44: [1, 59], 45: 112, 46: 111, 47: [2, 76] }, { 33: [2, 70], 40: 113, 65: [2, 70], 72: [2, 70], 75: [2, 70], 80: [2, 70], 81: [2, 70], 82: [2, 70], 83: [2, 70], 84: [2, 70], 85: [2, 70] }, { 47: [2, 18] }, { 5: [2, 14], 14: [2, 14], 15: [2, 14], 19: [2, 14], 29: [2, 14], 34: [2, 14], 39: [2, 14], 44: [2, 14], 47: [2, 14], 48: [2, 14], 51: [2, 14], 55: [2, 14], 60: [2, 14] }, { 33: [1, 114] }, { 33: [2, 87], 65: [2, 87], 72: [2, 87], 80: [2, 87], 81: [2, 87], 82: [2, 87], 83: [2, 87], 84: [2, 87], 85: [2, 87] }, { 33: [2, 89] }, { 20: 75, 63: 116, 64: 76, 65: [1, 44], 67: 115, 68: [2, 96], 69: 117, 70: 77, 71: 78, 72: [1, 79], 78: 26, 79: 27, 80: [1, 28], 81: [1, 29], 82: [1, 30], 83: [1, 31], 84: [1, 32], 85: [1, 34], 86: 33 }, { 33: [1, 118] }, { 32: 119, 33: [2, 62], 74: 120, 75: [1, 121] }, { 33: [2, 59], 65: [2, 59], 72: [2, 59], 75: [2, 59], 80: [2, 59], 81: [2, 59], 82: [2, 59], 83: [2, 59], 84: [2, 59], 85: [2, 59] }, { 33: [2, 61], 75: [2, 61] }, { 33: [2, 68], 37: 122, 74: 123, 75: [1, 121] }, { 33: [2, 65], 65: [2, 65], 72: [2, 65], 75: [2, 65], 80: [2, 65], 81: [2, 65], 82: [2, 65], 83: [2, 65], 84: [2, 65], 85: [2, 65] }, { 33: [2, 67], 75: [2, 67] }, { 23: [1, 124] }, { 23: [2, 51], 65: [2, 51], 72: [2, 51], 80: [2, 51], 81: [2, 51], 82: [2, 51], 83: [2, 51], 84: [2, 51], 85: [2, 51] }, { 23: [2, 53] }, { 33: [1, 125] }, { 33: [2, 91], 65: [2, 91], 72: [2, 91], 80: [2, 91], 81: [2, 91], 82: [2, 91], 83: [2, 91], 84: [2, 91], 85: [2, 91] }, { 33: [2, 93] }, { 5: [2, 22], 14: [2, 22], 15: [2, 22], 19: [2, 22], 29: [2, 22], 34: [2, 22], 39: [2, 22], 44: [2, 22], 47: [2, 22], 48: [2, 22], 51: [2, 22], 55: [2, 22], 60: [2, 22] }, { 23: [2, 99], 33: [2, 99], 54: [2, 99], 68: [2, 99], 72: [2, 99], 75: [2, 99] }, { 73: [1, 109] }, { 20: 75, 63: 126, 64: 76, 65: [1, 44], 72: [1, 35], 78: 26, 79: 27, 80: [1, 28], 81: [1, 29], 82: [1, 30], 83: [1, 31], 84: [1, 32], 85: [1, 34], 86: 33 }, { 5: [2, 23], 14: [2, 23], 15: [2, 23], 19: [2, 23], 29: [2, 23], 34: [2, 23], 39: [2, 23], 44: [2, 23], 47: [2, 23], 48: [2, 23], 51: [2, 23], 55: [2, 23], 60: [2, 23] }, { 47: [2, 19] }, { 47: [2, 77] }, { 20: 75, 33: [2, 72], 41: 127, 63: 128, 64: 76, 65: [1, 44], 69: 129, 70: 77, 71: 78, 72: [1, 79], 75: [2, 72], 78: 26, 79: 27, 80: [1, 28], 81: [1, 29], 82: [1, 30], 83: [1, 31], 84: [1, 32], 85: [1, 34], 86: 33 }, { 5: [2, 24], 14: [2, 24], 15: [2, 24], 19: [2, 24], 29: [2, 24], 34: [2, 24], 39: [2, 24], 44: [2, 24], 47: [2, 24], 48: [2, 24], 51: [2, 24], 55: [2, 24], 60: [2, 24] }, { 68: [1, 130] }, { 65: [2, 95], 68: [2, 95], 72: [2, 95], 80: [2, 95], 81: [2, 95], 82: [2, 95], 83: [2, 95], 84: [2, 95], 85: [2, 95] }, { 68: [2, 97] }, { 5: [2, 21], 14: [2, 21], 15: [2, 21], 19: [2, 21], 29: [2, 21], 34: [2, 21], 39: [2, 21], 44: [2, 21], 47: [2, 21], 48: [2, 21], 51: [2, 21], 55: [2, 21], 60: [2, 21] }, { 33: [1, 131] }, { 33: [2, 63] }, { 72: [1, 133], 76: 132 }, { 33: [1, 134] }, { 33: [2, 69] }, { 15: [2, 12] }, { 14: [2, 26], 15: [2, 26], 19: [2, 26], 29: [2, 26], 34: [2, 26], 47: [2, 26], 48: [2, 26], 51: [2, 26], 55: [2, 26], 60: [2, 26] }, { 23: [2, 31], 33: [2, 31], 54: [2, 31], 68: [2, 31], 72: [2, 31], 75: [2, 31] }, { 33: [2, 74], 42: 135, 74: 136, 75: [1, 121] }, { 33: [2, 71], 65: [2, 71], 72: [2, 71], 75: [2, 71], 80: [2, 71], 81: [2, 71], 82: [2, 71], 83: [2, 71], 84: [2, 71], 85: [2, 71] }, { 33: [2, 73], 75: [2, 73] }, { 23: [2, 29], 33: [2, 29], 54: [2, 29], 65: [2, 29], 68: [2, 29], 72: [2, 29], 75: [2, 29], 80: [2, 29], 81: [2, 29], 82: [2, 29], 83: [2, 29], 84: [2, 29], 85: [2, 29] }, { 14: [2, 15], 15: [2, 15], 19: [2, 15], 29: [2, 15], 34: [2, 15], 39: [2, 15], 44: [2, 15], 47: [2, 15], 48: [2, 15], 51: [2, 15], 55: [2, 15], 60: [2, 15] }, { 72: [1, 138], 77: [1, 137] }, { 72: [2, 100], 77: [2, 100] }, { 14: [2, 16], 15: [2, 16], 19: [2, 16], 29: [2, 16], 34: [2, 16], 44: [2, 16], 47: [2, 16], 48: [2, 16], 51: [2, 16], 55: [2, 16], 60: [2, 16] }, { 33: [1, 139] }, { 33: [2, 75] }, { 33: [2, 32] }, { 72: [2, 101], 77: [2, 101] }, { 14: [2, 17], 15: [2, 17], 19: [2, 17], 29: [2, 17], 34: [2, 17], 39: [2, 17], 44: [2, 17], 47: [2, 17], 48: [2, 17], 51: [2, 17], 55: [2, 17], 60: [2, 17] }],
- defaultActions: { 4: [2, 1], 55: [2, 55], 57: [2, 20], 61: [2, 57], 74: [2, 81], 83: [2, 85], 87: [2, 18], 91: [2, 89], 102: [2, 53], 105: [2, 93], 111: [2, 19], 112: [2, 77], 117: [2, 97], 120: [2, 63], 123: [2, 69], 124: [2, 12], 136: [2, 75], 137: [2, 32] },
- parseError: function parseError(str, hash) {
- throw new Error(str);
- },
- parse: function parse(input) {
- var self = this,
- stack = [0],
- vstack = [null],
- lstack = [],
- table = this.table,
- yytext = "",
- yylineno = 0,
- yyleng = 0,
- recovering = 0,
- TERROR = 2,
- EOF = 1;
- this.lexer.setInput(input);
- this.lexer.yy = this.yy;
- this.yy.lexer = this.lexer;
- this.yy.parser = this;
- if (typeof this.lexer.yylloc == "undefined") this.lexer.yylloc = {};
- var yyloc = this.lexer.yylloc;
- lstack.push(yyloc);
- var ranges = this.lexer.options && this.lexer.options.ranges;
- if (typeof this.yy.parseError === "function") this.parseError = this.yy.parseError;
- function popStack(n) {
- stack.length = stack.length - 2 * n;
- vstack.length = vstack.length - n;
- lstack.length = lstack.length - n;
- }
- function lex() {
- var token;
- token = self.lexer.lex() || 1;
- if (typeof token !== "number") {
- token = self.symbols_[token] || token;
- }
- return token;
- }
- var symbol,
- preErrorSymbol,
- state,
- action,
- a,
- r,
- yyval = {},
- p,
- len,
- newState,
- expected;
- while (true) {
- state = stack[stack.length - 1];
- if (this.defaultActions[state]) {
- action = this.defaultActions[state];
- } else {
- if (symbol === null || typeof symbol == "undefined") {
- symbol = lex();
- }
- action = table[state] && table[state][symbol];
- }
- if (typeof action === "undefined" || !action.length || !action[0]) {
- var errStr = "";
- if (!recovering) {
- expected = [];
- for (p in table[state]) if (this.terminals_[p] && p > 2) {
- expected.push("'" + this.terminals_[p] + "'");
- }
- if (this.lexer.showPosition) {
- errStr = "Parse error on line " + (yylineno + 1) + ":\n" + this.lexer.showPosition() + "\nExpecting " + expected.join(", ") + ", got '" + (this.terminals_[symbol] || symbol) + "'";
- } else {
- errStr = "Parse error on line " + (yylineno + 1) + ": Unexpected " + (symbol == 1 ? "end of input" : "'" + (this.terminals_[symbol] || symbol) + "'");
- }
- this.parseError(errStr, { text: this.lexer.match, token: this.terminals_[symbol] || symbol, line: this.lexer.yylineno, loc: yyloc, expected: expected });
- }
- }
- if (action[0] instanceof Array && action.length > 1) {
- throw new Error("Parse Error: multiple actions possible at state: " + state + ", token: " + symbol);
- }
- switch (action[0]) {
- case 1:
- stack.push(symbol);
- vstack.push(this.lexer.yytext);
- lstack.push(this.lexer.yylloc);
- stack.push(action[1]);
- symbol = null;
- if (!preErrorSymbol) {
- yyleng = this.lexer.yyleng;
- yytext = this.lexer.yytext;
- yylineno = this.lexer.yylineno;
- yyloc = this.lexer.yylloc;
- if (recovering > 0) recovering--;
- } else {
- symbol = preErrorSymbol;
- preErrorSymbol = null;
- }
- break;
- case 2:
- len = this.productions_[action[1]][1];
- yyval.$ = vstack[vstack.length - len];
- yyval._$ = { first_line: lstack[lstack.length - (len || 1)].first_line, last_line: lstack[lstack.length - 1].last_line, first_column: lstack[lstack.length - (len || 1)].first_column, last_column: lstack[lstack.length - 1].last_column };
- if (ranges) {
- yyval._$.range = [lstack[lstack.length - (len || 1)].range[0], lstack[lstack.length - 1].range[1]];
- }
- r = this.performAction.call(yyval, yytext, yyleng, yylineno, this.yy, action[1], vstack, lstack);
- if (typeof r !== "undefined") {
- return r;
- }
- if (len) {
- stack = stack.slice(0, -1 * len * 2);
- vstack = vstack.slice(0, -1 * len);
- lstack = lstack.slice(0, -1 * len);
- }
- stack.push(this.productions_[action[1]][0]);
- vstack.push(yyval.$);
- lstack.push(yyval._$);
- newState = table[stack[stack.length - 2]][stack[stack.length - 1]];
- stack.push(newState);
- break;
- case 3:
- return true;
- }
- }
- return true;
- }
- };
- /* Jison generated lexer */
- var lexer = (function () {
- var lexer = { EOF: 1,
- parseError: function parseError(str, hash) {
- if (this.yy.parser) {
- this.yy.parser.parseError(str, hash);
- } else {
- throw new Error(str);
- }
- },
- setInput: function setInput(input) {
- this._input = input;
- this._more = this._less = this.done = false;
- this.yylineno = this.yyleng = 0;
- this.yytext = this.matched = this.match = '';
- this.conditionStack = ['INITIAL'];
- this.yylloc = { first_line: 1, first_column: 0, last_line: 1, last_column: 0 };
- if (this.options.ranges) this.yylloc.range = [0, 0];
- this.offset = 0;
- return this;
- },
- input: function input() {
- var ch = this._input[0];
- this.yytext += ch;
- this.yyleng++;
- this.offset++;
- this.match += ch;
- this.matched += ch;
- var lines = ch.match(/(?:\r\n?|\n).*/g);
- if (lines) {
- this.yylineno++;
- this.yylloc.last_line++;
- } else {
- this.yylloc.last_column++;
- }
- if (this.options.ranges) this.yylloc.range[1]++;
-
- this._input = this._input.slice(1);
- return ch;
- },
- unput: function unput(ch) {
- var len = ch.length;
- var lines = ch.split(/(?:\r\n?|\n)/g);
-
- this._input = ch + this._input;
- this.yytext = this.yytext.substr(0, this.yytext.length - len - 1);
- //this.yyleng -= len;
- this.offset -= len;
- var oldLines = this.match.split(/(?:\r\n?|\n)/g);
- this.match = this.match.substr(0, this.match.length - 1);
- this.matched = this.matched.substr(0, this.matched.length - 1);
-
- if (lines.length - 1) this.yylineno -= lines.length - 1;
- var r = this.yylloc.range;
-
- this.yylloc = { first_line: this.yylloc.first_line,
- last_line: this.yylineno + 1,
- first_column: this.yylloc.first_column,
- last_column: lines ? (lines.length === oldLines.length ? this.yylloc.first_column : 0) + oldLines[oldLines.length - lines.length].length - lines[0].length : this.yylloc.first_column - len
- };
-
- if (this.options.ranges) {
- this.yylloc.range = [r[0], r[0] + this.yyleng - len];
- }
- return this;
- },
- more: function more() {
- this._more = true;
- return this;
- },
- less: function less(n) {
- this.unput(this.match.slice(n));
- },
- pastInput: function pastInput() {
- var past = this.matched.substr(0, this.matched.length - this.match.length);
- return (past.length > 20 ? '...' : '') + past.substr(-20).replace(/\n/g, "");
- },
- upcomingInput: function upcomingInput() {
- var next = this.match;
- if (next.length < 20) {
- next += this._input.substr(0, 20 - next.length);
- }
- return (next.substr(0, 20) + (next.length > 20 ? '...' : '')).replace(/\n/g, "");
- },
- showPosition: function showPosition() {
- var pre = this.pastInput();
- var c = new Array(pre.length + 1).join("-");
- return pre + this.upcomingInput() + "\n" + c + "^";
- },
- next: function next() {
- if (this.done) {
- return this.EOF;
- }
- if (!this._input) this.done = true;
-
- var token, match, tempMatch, index, col, lines;
- if (!this._more) {
- this.yytext = '';
- this.match = '';
- }
- var rules = this._currentRules();
- for (var i = 0; i < rules.length; i++) {
- tempMatch = this._input.match(this.rules[rules[i]]);
- if (tempMatch && (!match || tempMatch[0].length > match[0].length)) {
- match = tempMatch;
- index = i;
- if (!this.options.flex) break;
- }
- }
- if (match) {
- lines = match[0].match(/(?:\r\n?|\n).*/g);
- if (lines) this.yylineno += lines.length;
- this.yylloc = { first_line: this.yylloc.last_line,
- last_line: this.yylineno + 1,
- first_column: this.yylloc.last_column,
- last_column: lines ? lines[lines.length - 1].length - lines[lines.length - 1].match(/\r?\n?/)[0].length : this.yylloc.last_column + match[0].length };
- this.yytext += match[0];
- this.match += match[0];
- this.matches = match;
- this.yyleng = this.yytext.length;
- if (this.options.ranges) {
- this.yylloc.range = [this.offset, this.offset += this.yyleng];
- }
- this._more = false;
- this._input = this._input.slice(match[0].length);
- this.matched += match[0];
- token = this.performAction.call(this, this.yy, this, rules[index], this.conditionStack[this.conditionStack.length - 1]);
- if (this.done && this._input) this.done = false;
- if (token) return token;else return;
- }
- if (this._input === "") {
- return this.EOF;
- } else {
- return this.parseError('Lexical error on line ' + (this.yylineno + 1) + '. Unrecognized text.\n' + this.showPosition(), { text: "", token: null, line: this.yylineno });
- }
- },
- lex: function lex() {
- var r = this.next();
- if (typeof r !== 'undefined') {
- return r;
- } else {
- return this.lex();
- }
- },
- begin: function begin(condition) {
- this.conditionStack.push(condition);
- },
- popState: function popState() {
- return this.conditionStack.pop();
- },
- _currentRules: function _currentRules() {
- return this.conditions[this.conditionStack[this.conditionStack.length - 1]].rules;
- },
- topState: function topState() {
- return this.conditionStack[this.conditionStack.length - 2];
- },
- pushState: function begin(condition) {
- this.begin(condition);
- } };
- lexer.options = {};
- lexer.performAction = function anonymous(yy, yy_, $avoiding_name_collisions, YY_START
- /**/) {
-
- function strip(start, end) {
- return yy_.yytext = yy_.yytext.substr(start, yy_.yyleng - end);
- }
-
- var YYSTATE = YY_START;
- switch ($avoiding_name_collisions) {
- case 0:
- if (yy_.yytext.slice(-2) === "\\\\") {
- strip(0, 1);
- this.begin("mu");
- } else if (yy_.yytext.slice(-1) === "\\") {
- strip(0, 1);
- this.begin("emu");
- } else {
- this.begin("mu");
- }
- if (yy_.yytext) return 15;
-
- break;
- case 1:
- return 15;
- break;
- case 2:
- this.popState();
- return 15;
-
- break;
- case 3:
- this.begin('raw');return 15;
- break;
- case 4:
- this.popState();
- // Should be using `this.topState()` below, but it currently
- // returns the second top instead of the first top. Opened an
- // issue about it at https://github.com/zaach/jison/issues/291
- if (this.conditionStack[this.conditionStack.length - 1] === 'raw') {
- return 15;
- } else {
- yy_.yytext = yy_.yytext.substr(5, yy_.yyleng - 9);
- return 'END_RAW_BLOCK';
- }
-
- break;
- case 5:
- return 15;
- break;
- case 6:
- this.popState();
- return 14;
-
- break;
- case 7:
- return 65;
- break;
- case 8:
- return 68;
- break;
- case 9:
- return 19;
- break;
- case 10:
- this.popState();
- this.begin('raw');
- return 23;
-
- break;
- case 11:
- return 55;
- break;
- case 12:
- return 60;
- break;
- case 13:
- return 29;
- break;
- case 14:
- return 47;
- break;
- case 15:
- this.popState();return 44;
- break;
- case 16:
- this.popState();return 44;
- break;
- case 17:
- return 34;
- break;
- case 18:
- return 39;
- break;
- case 19:
- return 51;
- break;
- case 20:
- return 48;
- break;
- case 21:
- this.unput(yy_.yytext);
- this.popState();
- this.begin('com');
-
- break;
- case 22:
- this.popState();
- return 14;
-
- break;
- case 23:
- return 48;
- break;
- case 24:
- return 73;
- break;
- case 25:
- return 72;
- break;
- case 26:
- return 72;
- break;
- case 27:
- return 87;
- break;
- case 28:
- // ignore whitespace
- break;
- case 29:
- this.popState();return 54;
- break;
- case 30:
- this.popState();return 33;
- break;
- case 31:
- yy_.yytext = strip(1, 2).replace(/\\"/g, '"');return 80;
- break;
- case 32:
- yy_.yytext = strip(1, 2).replace(/\\'/g, "'");return 80;
- break;
- case 33:
- return 85;
- break;
- case 34:
- return 82;
- break;
- case 35:
- return 82;
- break;
- case 36:
- return 83;
- break;
- case 37:
- return 84;
- break;
- case 38:
- return 81;
- break;
- case 39:
- return 75;
- break;
- case 40:
- return 77;
- break;
- case 41:
- return 72;
- break;
- case 42:
- yy_.yytext = yy_.yytext.replace(/\\([\\\]])/g, '$1');return 72;
- break;
- case 43:
- return 'INVALID';
- break;
- case 44:
- return 5;
- break;
- }
- };
- lexer.rules = [/^(?:[^\x00]*?(?=(\{\{)))/, /^(?:[^\x00]+)/, /^(?:[^\x00]{2,}?(?=(\{\{|\\\{\{|\\\\\{\{|$)))/, /^(?:\{\{\{\{(?=[^\/]))/, /^(?:\{\{\{\{\/[^\s!"#%-,\.\/;->@\[-\^`\{-~]+(?=[=}\s\/.])\}\}\}\})/, /^(?:[^\x00]*?(?=(\{\{\{\{)))/, /^(?:[\s\S]*?--(~)?\}\})/, /^(?:\()/, /^(?:\))/, /^(?:\{\{\{\{)/, /^(?:\}\}\}\})/, /^(?:\{\{(~)?>)/, /^(?:\{\{(~)?#>)/, /^(?:\{\{(~)?#\*?)/, /^(?:\{\{(~)?\/)/, /^(?:\{\{(~)?\^\s*(~)?\}\})/, /^(?:\{\{(~)?\s*else\s*(~)?\}\})/, /^(?:\{\{(~)?\^)/, /^(?:\{\{(~)?\s*else\b)/, /^(?:\{\{(~)?\{)/, /^(?:\{\{(~)?&)/, /^(?:\{\{(~)?!--)/, /^(?:\{\{(~)?![\s\S]*?\}\})/, /^(?:\{\{(~)?\*?)/, /^(?:=)/, /^(?:\.\.)/, /^(?:\.(?=([=~}\s\/.)|])))/, /^(?:[\/.])/, /^(?:\s+)/, /^(?:\}(~)?\}\})/, /^(?:(~)?\}\})/, /^(?:"(\\["]|[^"])*")/, /^(?:'(\\[']|[^'])*')/, /^(?:@)/, /^(?:true(?=([~}\s)])))/, /^(?:false(?=([~}\s)])))/, /^(?:undefined(?=([~}\s)])))/, /^(?:null(?=([~}\s)])))/, /^(?:-?[0-9]+(?:\.[0-9]+)?(?=([~}\s)])))/, /^(?:as\s+\|)/, /^(?:\|)/, /^(?:([^\s!"#%-,\.\/;->@\[-\^`\{-~]+(?=([=~}\s\/.)|]))))/, /^(?:\[(\\\]|[^\]])*\])/, /^(?:.)/, /^(?:$)/];
- lexer.conditions = { "mu": { "rules": [7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44], "inclusive": false }, "emu": { "rules": [2], "inclusive": false }, "com": { "rules": [6], "inclusive": false }, "raw": { "rules": [3, 4, 5], "inclusive": false }, "INITIAL": { "rules": [0, 1, 44], "inclusive": true } };
- return lexer;
- })();
- parser.lexer = lexer;
- function Parser() {
- this.yy = {};
- }Parser.prototype = parser;parser.Parser = Parser;
- return new Parser();
- })();exports.__esModule = true;
- exports['default'] = handlebars;
-
-/***/ },
-/* 24 */
-/***/ function(module, exports, __webpack_require__) {
-
- 'use strict';
-
- var _interopRequireDefault = __webpack_require__(1)['default'];
-
- exports.__esModule = true;
-
- var _visitor = __webpack_require__(25);
-
- var _visitor2 = _interopRequireDefault(_visitor);
-
- function WhitespaceControl() {
- var options = arguments.length <= 0 || arguments[0] === undefined ? {} : arguments[0];
-
- this.options = options;
- }
- WhitespaceControl.prototype = new _visitor2['default']();
-
- WhitespaceControl.prototype.Program = function (program) {
- var doStandalone = !this.options.ignoreStandalone;
-
- var isRoot = !this.isRootSeen;
- this.isRootSeen = true;
-
- var body = program.body;
- for (var i = 0, l = body.length; i < l; i++) {
- var current = body[i],
- strip = this.accept(current);
-
- if (!strip) {
- continue;
- }
-
- var _isPrevWhitespace = isPrevWhitespace(body, i, isRoot),
- _isNextWhitespace = isNextWhitespace(body, i, isRoot),
- openStandalone = strip.openStandalone && _isPrevWhitespace,
- closeStandalone = strip.closeStandalone && _isNextWhitespace,
- inlineStandalone = strip.inlineStandalone && _isPrevWhitespace && _isNextWhitespace;
-
- if (strip.close) {
- omitRight(body, i, true);
- }
- if (strip.open) {
- omitLeft(body, i, true);
- }
-
- if (doStandalone && inlineStandalone) {
- omitRight(body, i);
-
- if (omitLeft(body, i)) {
- // If we are on a standalone node, save the indent info for partials
- if (current.type === 'PartialStatement') {
- // Pull out the whitespace from the final line
- current.indent = /([ \t]+$)/.exec(body[i - 1].original)[1];
- }
- }
- }
- if (doStandalone && openStandalone) {
- omitRight((current.program || current.inverse).body);
-
- // Strip out the previous content node if it's whitespace only
- omitLeft(body, i);
- }
- if (doStandalone && closeStandalone) {
- // Always strip the next node
- omitRight(body, i);
-
- omitLeft((current.inverse || current.program).body);
- }
- }
-
- return program;
- };
-
- WhitespaceControl.prototype.BlockStatement = WhitespaceControl.prototype.DecoratorBlock = WhitespaceControl.prototype.PartialBlockStatement = function (block) {
- this.accept(block.program);
- this.accept(block.inverse);
-
- // Find the inverse program that is involed with whitespace stripping.
- var program = block.program || block.inverse,
- inverse = block.program && block.inverse,
- firstInverse = inverse,
- lastInverse = inverse;
-
- if (inverse && inverse.chained) {
- firstInverse = inverse.body[0].program;
-
- // Walk the inverse chain to find the last inverse that is actually in the chain.
- while (lastInverse.chained) {
- lastInverse = lastInverse.body[lastInverse.body.length - 1].program;
- }
- }
-
- var strip = {
- open: block.openStrip.open,
- close: block.closeStrip.close,
-
- // Determine the standalone candiacy. Basically flag our content as being possibly standalone
- // so our parent can determine if we actually are standalone
- openStandalone: isNextWhitespace(program.body),
- closeStandalone: isPrevWhitespace((firstInverse || program).body)
- };
-
- if (block.openStrip.close) {
- omitRight(program.body, null, true);
- }
-
- if (inverse) {
- var inverseStrip = block.inverseStrip;
-
- if (inverseStrip.open) {
- omitLeft(program.body, null, true);
- }
-
- if (inverseStrip.close) {
- omitRight(firstInverse.body, null, true);
- }
- if (block.closeStrip.open) {
- omitLeft(lastInverse.body, null, true);
- }
-
- // Find standalone else statments
- if (!this.options.ignoreStandalone && isPrevWhitespace(program.body) && isNextWhitespace(firstInverse.body)) {
- omitLeft(program.body);
- omitRight(firstInverse.body);
- }
- } else if (block.closeStrip.open) {
- omitLeft(program.body, null, true);
- }
-
- return strip;
- };
-
- WhitespaceControl.prototype.Decorator = WhitespaceControl.prototype.MustacheStatement = function (mustache) {
- return mustache.strip;
- };
-
- WhitespaceControl.prototype.PartialStatement = WhitespaceControl.prototype.CommentStatement = function (node) {
- /* istanbul ignore next */
- var strip = node.strip || {};
- return {
- inlineStandalone: true,
- open: strip.open,
- close: strip.close
- };
- };
-
- function isPrevWhitespace(body, i, isRoot) {
- if (i === undefined) {
- i = body.length;
- }
-
- // Nodes that end with newlines are considered whitespace (but are special
- // cased for strip operations)
- var prev = body[i - 1],
- sibling = body[i - 2];
- if (!prev) {
- return isRoot;
- }
-
- if (prev.type === 'ContentStatement') {
- return (sibling || !isRoot ? /\r?\n\s*?$/ : /(^|\r?\n)\s*?$/).test(prev.original);
- }
- }
- function isNextWhitespace(body, i, isRoot) {
- if (i === undefined) {
- i = -1;
- }
-
- var next = body[i + 1],
- sibling = body[i + 2];
- if (!next) {
- return isRoot;
- }
-
- if (next.type === 'ContentStatement') {
- return (sibling || !isRoot ? /^\s*?\r?\n/ : /^\s*?(\r?\n|$)/).test(next.original);
- }
- }
-
- // Marks the node to the right of the position as omitted.
- // I.e. {{foo}}' ' will mark the ' ' node as omitted.
- //
- // If i is undefined, then the first child will be marked as such.
- //
- // If mulitple is truthy then all whitespace will be stripped out until non-whitespace
- // content is met.
- function omitRight(body, i, multiple) {
- var current = body[i == null ? 0 : i + 1];
- if (!current || current.type !== 'ContentStatement' || !multiple && current.rightStripped) {
- return;
- }
-
- var original = current.value;
- current.value = current.value.replace(multiple ? /^\s+/ : /^[ \t]*\r?\n?/, '');
- current.rightStripped = current.value !== original;
- }
-
- // Marks the node to the left of the position as omitted.
- // I.e. ' '{{foo}} will mark the ' ' node as omitted.
- //
- // If i is undefined then the last child will be marked as such.
- //
- // If mulitple is truthy then all whitespace will be stripped out until non-whitespace
- // content is met.
- function omitLeft(body, i, multiple) {
- var current = body[i == null ? body.length - 1 : i - 1];
- if (!current || current.type !== 'ContentStatement' || !multiple && current.leftStripped) {
- return;
- }
-
- // We omit the last node if it's whitespace only and not preceeded by a non-content node.
- var original = current.value;
- current.value = current.value.replace(multiple ? /\s+$/ : /[ \t]+$/, '');
- current.leftStripped = current.value !== original;
- return current.leftStripped;
- }
-
- exports['default'] = WhitespaceControl;
- module.exports = exports['default'];
-
-/***/ },
-/* 25 */
-/***/ function(module, exports, __webpack_require__) {
-
- 'use strict';
-
- var _interopRequireDefault = __webpack_require__(1)['default'];
-
- exports.__esModule = true;
-
- var _exception = __webpack_require__(6);
-
- var _exception2 = _interopRequireDefault(_exception);
-
- function Visitor() {
- this.parents = [];
- }
-
- Visitor.prototype = {
- constructor: Visitor,
- mutating: false,
-
- // Visits a given value. If mutating, will replace the value if necessary.
- acceptKey: function acceptKey(node, name) {
- var value = this.accept(node[name]);
- if (this.mutating) {
- // Hacky sanity check: This may have a few false positives for type for the helper
- // methods but will generally do the right thing without a lot of overhead.
- if (value && !Visitor.prototype[value.type]) {
- throw new _exception2['default']('Unexpected node type "' + value.type + '" found when accepting ' + name + ' on ' + node.type);
- }
- node[name] = value;
- }
- },
-
- // Performs an accept operation with added sanity check to ensure
- // required keys are not removed.
- acceptRequired: function acceptRequired(node, name) {
- this.acceptKey(node, name);
-
- if (!node[name]) {
- throw new _exception2['default'](node.type + ' requires ' + name);
- }
- },
-
- // Traverses a given array. If mutating, empty respnses will be removed
- // for child elements.
- acceptArray: function acceptArray(array) {
- for (var i = 0, l = array.length; i < l; i++) {
- this.acceptKey(array, i);
-
- if (!array[i]) {
- array.splice(i, 1);
- i--;
- l--;
- }
- }
- },
-
- accept: function accept(object) {
- if (!object) {
- return;
- }
-
- /* istanbul ignore next: Sanity code */
- if (!this[object.type]) {
- throw new _exception2['default']('Unknown type: ' + object.type, object);
- }
-
- if (this.current) {
- this.parents.unshift(this.current);
- }
- this.current = object;
-
- var ret = this[object.type](object);
-
- this.current = this.parents.shift();
-
- if (!this.mutating || ret) {
- return ret;
- } else if (ret !== false) {
- return object;
- }
- },
-
- Program: function Program(program) {
- this.acceptArray(program.body);
- },
-
- MustacheStatement: visitSubExpression,
- Decorator: visitSubExpression,
-
- BlockStatement: visitBlock,
- DecoratorBlock: visitBlock,
-
- PartialStatement: visitPartial,
- PartialBlockStatement: function PartialBlockStatement(partial) {
- visitPartial.call(this, partial);
-
- this.acceptKey(partial, 'program');
- },
-
- ContentStatement: function ContentStatement() /* content */{},
- CommentStatement: function CommentStatement() /* comment */{},
-
- SubExpression: visitSubExpression,
-
- PathExpression: function PathExpression() /* path */{},
-
- StringLiteral: function StringLiteral() /* string */{},
- NumberLiteral: function NumberLiteral() /* number */{},
- BooleanLiteral: function BooleanLiteral() /* bool */{},
- UndefinedLiteral: function UndefinedLiteral() /* literal */{},
- NullLiteral: function NullLiteral() /* literal */{},
-
- Hash: function Hash(hash) {
- this.acceptArray(hash.pairs);
- },
- HashPair: function HashPair(pair) {
- this.acceptRequired(pair, 'value');
- }
- };
-
- function visitSubExpression(mustache) {
- this.acceptRequired(mustache, 'path');
- this.acceptArray(mustache.params);
- this.acceptKey(mustache, 'hash');
- }
- function visitBlock(block) {
- visitSubExpression.call(this, block);
-
- this.acceptKey(block, 'program');
- this.acceptKey(block, 'inverse');
- }
- function visitPartial(partial) {
- this.acceptRequired(partial, 'name');
- this.acceptArray(partial.params);
- this.acceptKey(partial, 'hash');
- }
-
- exports['default'] = Visitor;
- module.exports = exports['default'];
-
-/***/ },
-/* 26 */
-/***/ function(module, exports, __webpack_require__) {
-
- 'use strict';
-
- var _interopRequireDefault = __webpack_require__(1)['default'];
-
- exports.__esModule = true;
- exports.SourceLocation = SourceLocation;
- exports.id = id;
- exports.stripFlags = stripFlags;
- exports.stripComment = stripComment;
- exports.preparePath = preparePath;
- exports.prepareMustache = prepareMustache;
- exports.prepareRawBlock = prepareRawBlock;
- exports.prepareBlock = prepareBlock;
- exports.prepareProgram = prepareProgram;
- exports.preparePartialBlock = preparePartialBlock;
-
- var _exception = __webpack_require__(6);
-
- var _exception2 = _interopRequireDefault(_exception);
-
- function validateClose(open, close) {
- close = close.path ? close.path.original : close;
-
- if (open.path.original !== close) {
- var errorNode = { loc: open.path.loc };
-
- throw new _exception2['default'](open.path.original + " doesn't match " + close, errorNode);
- }
- }
-
- function SourceLocation(source, locInfo) {
- this.source = source;
- this.start = {
- line: locInfo.first_line,
- column: locInfo.first_column
- };
- this.end = {
- line: locInfo.last_line,
- column: locInfo.last_column
- };
- }
-
- function id(token) {
- if (/^\[.*\]$/.test(token)) {
- return token.substr(1, token.length - 2);
- } else {
- return token;
- }
- }
-
- function stripFlags(open, close) {
- return {
- open: open.charAt(2) === '~',
- close: close.charAt(close.length - 3) === '~'
- };
- }
-
- function stripComment(comment) {
- return comment.replace(/^\{\{~?\!-?-?/, '').replace(/-?-?~?\}\}$/, '');
- }
-
- function preparePath(data, parts, loc) {
- loc = this.locInfo(loc);
-
- var original = data ? '@' : '',
- dig = [],
- depth = 0,
- depthString = '';
-
- for (var i = 0, l = parts.length; i < l; i++) {
- var part = parts[i].part,
-
- // If we have [] syntax then we do not treat path references as operators,
- // i.e. foo.[this] resolves to approximately context.foo['this']
- isLiteral = parts[i].original !== part;
- original += (parts[i].separator || '') + part;
-
- if (!isLiteral && (part === '..' || part === '.' || part === 'this')) {
- if (dig.length > 0) {
- throw new _exception2['default']('Invalid path: ' + original, { loc: loc });
- } else if (part === '..') {
- depth++;
- depthString += '../';
- }
- } else {
- dig.push(part);
- }
- }
-
- return {
- type: 'PathExpression',
- data: data,
- depth: depth,
- parts: dig,
- original: original,
- loc: loc
- };
- }
-
- function prepareMustache(path, params, hash, open, strip, locInfo) {
- // Must use charAt to support IE pre-10
- var escapeFlag = open.charAt(3) || open.charAt(2),
- escaped = escapeFlag !== '{' && escapeFlag !== '&';
-
- var decorator = /\*/.test(open);
- return {
- type: decorator ? 'Decorator' : 'MustacheStatement',
- path: path,
- params: params,
- hash: hash,
- escaped: escaped,
- strip: strip,
- loc: this.locInfo(locInfo)
- };
- }
-
- function prepareRawBlock(openRawBlock, contents, close, locInfo) {
- validateClose(openRawBlock, close);
-
- locInfo = this.locInfo(locInfo);
- var program = {
- type: 'Program',
- body: contents,
- strip: {},
- loc: locInfo
- };
-
- return {
- type: 'BlockStatement',
- path: openRawBlock.path,
- params: openRawBlock.params,
- hash: openRawBlock.hash,
- program: program,
- openStrip: {},
- inverseStrip: {},
- closeStrip: {},
- loc: locInfo
- };
- }
-
- function prepareBlock(openBlock, program, inverseAndProgram, close, inverted, locInfo) {
- if (close && close.path) {
- validateClose(openBlock, close);
- }
-
- var decorator = /\*/.test(openBlock.open);
-
- program.blockParams = openBlock.blockParams;
-
- var inverse = undefined,
- inverseStrip = undefined;
-
- if (inverseAndProgram) {
- if (decorator) {
- throw new _exception2['default']('Unexpected inverse block on decorator', inverseAndProgram);
- }
-
- if (inverseAndProgram.chain) {
- inverseAndProgram.program.body[0].closeStrip = close.strip;
- }
-
- inverseStrip = inverseAndProgram.strip;
- inverse = inverseAndProgram.program;
- }
-
- if (inverted) {
- inverted = inverse;
- inverse = program;
- program = inverted;
- }
-
- return {
- type: decorator ? 'DecoratorBlock' : 'BlockStatement',
- path: openBlock.path,
- params: openBlock.params,
- hash: openBlock.hash,
- program: program,
- inverse: inverse,
- openStrip: openBlock.strip,
- inverseStrip: inverseStrip,
- closeStrip: close && close.strip,
- loc: this.locInfo(locInfo)
- };
- }
-
- function prepareProgram(statements, loc) {
- if (!loc && statements.length) {
- var firstLoc = statements[0].loc,
- lastLoc = statements[statements.length - 1].loc;
-
- /* istanbul ignore else */
- if (firstLoc && lastLoc) {
- loc = {
- source: firstLoc.source,
- start: {
- line: firstLoc.start.line,
- column: firstLoc.start.column
- },
- end: {
- line: lastLoc.end.line,
- column: lastLoc.end.column
- }
- };
- }
- }
-
- return {
- type: 'Program',
- body: statements,
- strip: {},
- loc: loc
- };
- }
-
- function preparePartialBlock(open, program, close, locInfo) {
- validateClose(open, close);
-
- return {
- type: 'PartialBlockStatement',
- name: open.path,
- params: open.params,
- hash: open.hash,
- program: program,
- openStrip: open.strip,
- closeStrip: close && close.strip,
- loc: this.locInfo(locInfo)
- };
- }
-
-/***/ },
-/* 27 */
-/***/ function(module, exports, __webpack_require__) {
-
- /* eslint-disable new-cap */
-
- 'use strict';
-
- var _interopRequireDefault = __webpack_require__(1)['default'];
-
- exports.__esModule = true;
- exports.Compiler = Compiler;
- exports.precompile = precompile;
- exports.compile = compile;
-
- var _exception = __webpack_require__(6);
-
- var _exception2 = _interopRequireDefault(_exception);
-
- var _utils = __webpack_require__(5);
-
- var _ast = __webpack_require__(21);
-
- var _ast2 = _interopRequireDefault(_ast);
-
- var slice = [].slice;
-
- function Compiler() {}
-
- // the foundHelper register will disambiguate helper lookup from finding a
- // function in a context. This is necessary for mustache compatibility, which
- // requires that context functions in blocks are evaluated by blockHelperMissing,
- // and then proceed as if the resulting value was provided to blockHelperMissing.
-
- Compiler.prototype = {
- compiler: Compiler,
-
- equals: function equals(other) {
- var len = this.opcodes.length;
- if (other.opcodes.length !== len) {
- return false;
- }
-
- for (var i = 0; i < len; i++) {
- var opcode = this.opcodes[i],
- otherOpcode = other.opcodes[i];
- if (opcode.opcode !== otherOpcode.opcode || !argEquals(opcode.args, otherOpcode.args)) {
- return false;
- }
- }
-
- // We know that length is the same between the two arrays because they are directly tied
- // to the opcode behavior above.
- len = this.children.length;
- for (var i = 0; i < len; i++) {
- if (!this.children[i].equals(other.children[i])) {
- return false;
- }
- }
-
- return true;
- },
-
- guid: 0,
-
- compile: function compile(program, options) {
- this.sourceNode = [];
- this.opcodes = [];
- this.children = [];
- this.options = options;
- this.stringParams = options.stringParams;
- this.trackIds = options.trackIds;
-
- options.blockParams = options.blockParams || [];
-
- // These changes will propagate to the other compiler components
- var knownHelpers = options.knownHelpers;
- options.knownHelpers = {
- 'helperMissing': true,
- 'blockHelperMissing': true,
- 'each': true,
- 'if': true,
- 'unless': true,
- 'with': true,
- 'log': true,
- 'lookup': true
- };
- if (knownHelpers) {
- for (var _name in knownHelpers) {
- /* istanbul ignore else */
- if (_name in knownHelpers) {
- options.knownHelpers[_name] = knownHelpers[_name];
- }
- }
- }
-
- return this.accept(program);
- },
-
- compileProgram: function compileProgram(program) {
- var childCompiler = new this.compiler(),
- // eslint-disable-line new-cap
- result = childCompiler.compile(program, this.options),
- guid = this.guid++;
-
- this.usePartial = this.usePartial || result.usePartial;
-
- this.children[guid] = result;
- this.useDepths = this.useDepths || result.useDepths;
-
- return guid;
- },
-
- accept: function accept(node) {
- /* istanbul ignore next: Sanity code */
- if (!this[node.type]) {
- throw new _exception2['default']('Unknown type: ' + node.type, node);
- }
-
- this.sourceNode.unshift(node);
- var ret = this[node.type](node);
- this.sourceNode.shift();
- return ret;
- },
-
- Program: function Program(program) {
- this.options.blockParams.unshift(program.blockParams);
-
- var body = program.body,
- bodyLength = body.length;
- for (var i = 0; i < bodyLength; i++) {
- this.accept(body[i]);
- }
-
- this.options.blockParams.shift();
-
- this.isSimple = bodyLength === 1;
- this.blockParams = program.blockParams ? program.blockParams.length : 0;
-
- return this;
- },
-
- BlockStatement: function BlockStatement(block) {
- transformLiteralToPath(block);
-
- var program = block.program,
- inverse = block.inverse;
-
- program = program && this.compileProgram(program);
- inverse = inverse && this.compileProgram(inverse);
-
- var type = this.classifySexpr(block);
-
- if (type === 'helper') {
- this.helperSexpr(block, program, inverse);
- } else if (type === 'simple') {
- this.simpleSexpr(block);
-
- // now that the simple mustache is resolved, we need to
- // evaluate it by executing `blockHelperMissing`
- this.opcode('pushProgram', program);
- this.opcode('pushProgram', inverse);
- this.opcode('emptyHash');
- this.opcode('blockValue', block.path.original);
- } else {
- this.ambiguousSexpr(block, program, inverse);
-
- // now that the simple mustache is resolved, we need to
- // evaluate it by executing `blockHelperMissing`
- this.opcode('pushProgram', program);
- this.opcode('pushProgram', inverse);
- this.opcode('emptyHash');
- this.opcode('ambiguousBlockValue');
- }
-
- this.opcode('append');
- },
-
- DecoratorBlock: function DecoratorBlock(decorator) {
- var program = decorator.program && this.compileProgram(decorator.program);
- var params = this.setupFullMustacheParams(decorator, program, undefined),
- path = decorator.path;
-
- this.useDecorators = true;
- this.opcode('registerDecorator', params.length, path.original);
- },
-
- PartialStatement: function PartialStatement(partial) {
- this.usePartial = true;
-
- var program = partial.program;
- if (program) {
- program = this.compileProgram(partial.program);
- }
-
- var params = partial.params;
- if (params.length > 1) {
- throw new _exception2['default']('Unsupported number of partial arguments: ' + params.length, partial);
- } else if (!params.length) {
- if (this.options.explicitPartialContext) {
- this.opcode('pushLiteral', 'undefined');
- } else {
- params.push({ type: 'PathExpression', parts: [], depth: 0 });
- }
- }
-
- var partialName = partial.name.original,
- isDynamic = partial.name.type === 'SubExpression';
- if (isDynamic) {
- this.accept(partial.name);
- }
-
- this.setupFullMustacheParams(partial, program, undefined, true);
-
- var indent = partial.indent || '';
- if (this.options.preventIndent && indent) {
- this.opcode('appendContent', indent);
- indent = '';
- }
-
- this.opcode('invokePartial', isDynamic, partialName, indent);
- this.opcode('append');
- },
- PartialBlockStatement: function PartialBlockStatement(partialBlock) {
- this.PartialStatement(partialBlock);
- },
-
- MustacheStatement: function MustacheStatement(mustache) {
- this.SubExpression(mustache);
-
- if (mustache.escaped && !this.options.noEscape) {
- this.opcode('appendEscaped');
- } else {
- this.opcode('append');
- }
- },
- Decorator: function Decorator(decorator) {
- this.DecoratorBlock(decorator);
- },
-
- ContentStatement: function ContentStatement(content) {
- if (content.value) {
- this.opcode('appendContent', content.value);
- }
- },
-
- CommentStatement: function CommentStatement() {},
-
- SubExpression: function SubExpression(sexpr) {
- transformLiteralToPath(sexpr);
- var type = this.classifySexpr(sexpr);
-
- if (type === 'simple') {
- this.simpleSexpr(sexpr);
- } else if (type === 'helper') {
- this.helperSexpr(sexpr);
- } else {
- this.ambiguousSexpr(sexpr);
- }
- },
- ambiguousSexpr: function ambiguousSexpr(sexpr, program, inverse) {
- var path = sexpr.path,
- name = path.parts[0],
- isBlock = program != null || inverse != null;
-
- this.opcode('getContext', path.depth);
-
- this.opcode('pushProgram', program);
- this.opcode('pushProgram', inverse);
-
- path.strict = true;
- this.accept(path);
-
- this.opcode('invokeAmbiguous', name, isBlock);
- },
-
- simpleSexpr: function simpleSexpr(sexpr) {
- var path = sexpr.path;
- path.strict = true;
- this.accept(path);
- this.opcode('resolvePossibleLambda');
- },
-
- helperSexpr: function helperSexpr(sexpr, program, inverse) {
- var params = this.setupFullMustacheParams(sexpr, program, inverse),
- path = sexpr.path,
- name = path.parts[0];
-
- if (this.options.knownHelpers[name]) {
- this.opcode('invokeKnownHelper', params.length, name);
- } else if (this.options.knownHelpersOnly) {
- throw new _exception2['default']('You specified knownHelpersOnly, but used the unknown helper ' + name, sexpr);
- } else {
- path.strict = true;
- path.falsy = true;
-
- this.accept(path);
- this.opcode('invokeHelper', params.length, path.original, _ast2['default'].helpers.simpleId(path));
- }
- },
-
- PathExpression: function PathExpression(path) {
- this.addDepth(path.depth);
- this.opcode('getContext', path.depth);
-
- var name = path.parts[0],
- scoped = _ast2['default'].helpers.scopedId(path),
- blockParamId = !path.depth && !scoped && this.blockParamIndex(name);
-
- if (blockParamId) {
- this.opcode('lookupBlockParam', blockParamId, path.parts);
- } else if (!name) {
- // Context reference, i.e. `{{foo .}}` or `{{foo ..}}`
- this.opcode('pushContext');
- } else if (path.data) {
- this.options.data = true;
- this.opcode('lookupData', path.depth, path.parts, path.strict);
- } else {
- this.opcode('lookupOnContext', path.parts, path.falsy, path.strict, scoped);
- }
- },
-
- StringLiteral: function StringLiteral(string) {
- this.opcode('pushString', string.value);
- },
-
- NumberLiteral: function NumberLiteral(number) {
- this.opcode('pushLiteral', number.value);
- },
-
- BooleanLiteral: function BooleanLiteral(bool) {
- this.opcode('pushLiteral', bool.value);
- },
-
- UndefinedLiteral: function UndefinedLiteral() {
- this.opcode('pushLiteral', 'undefined');
- },
-
- NullLiteral: function NullLiteral() {
- this.opcode('pushLiteral', 'null');
- },
-
- Hash: function Hash(hash) {
- var pairs = hash.pairs,
- i = 0,
- l = pairs.length;
-
- this.opcode('pushHash');
-
- for (; i < l; i++) {
- this.pushParam(pairs[i].value);
- }
- while (i--) {
- this.opcode('assignToHash', pairs[i].key);
- }
- this.opcode('popHash');
- },
-
- // HELPERS
- opcode: function opcode(name) {
- this.opcodes.push({ opcode: name, args: slice.call(arguments, 1), loc: this.sourceNode[0].loc });
- },
-
- addDepth: function addDepth(depth) {
- if (!depth) {
- return;
- }
-
- this.useDepths = true;
- },
-
- classifySexpr: function classifySexpr(sexpr) {
- var isSimple = _ast2['default'].helpers.simpleId(sexpr.path);
-
- var isBlockParam = isSimple && !!this.blockParamIndex(sexpr.path.parts[0]);
-
- // a mustache is an eligible helper if:
- // * its id is simple (a single part, not `this` or `..`)
- var isHelper = !isBlockParam && _ast2['default'].helpers.helperExpression(sexpr);
-
- // if a mustache is an eligible helper but not a definite
- // helper, it is ambiguous, and will be resolved in a later
- // pass or at runtime.
- var isEligible = !isBlockParam && (isHelper || isSimple);
-
- // if ambiguous, we can possibly resolve the ambiguity now
- // An eligible helper is one that does not have a complex path, i.e. `this.foo`, `../foo` etc.
- if (isEligible && !isHelper) {
- var _name2 = sexpr.path.parts[0],
- options = this.options;
-
- if (options.knownHelpers[_name2]) {
- isHelper = true;
- } else if (options.knownHelpersOnly) {
- isEligible = false;
- }
- }
-
- if (isHelper) {
- return 'helper';
- } else if (isEligible) {
- return 'ambiguous';
- } else {
- return 'simple';
- }
- },
-
- pushParams: function pushParams(params) {
- for (var i = 0, l = params.length; i < l; i++) {
- this.pushParam(params[i]);
- }
- },
-
- pushParam: function pushParam(val) {
- var value = val.value != null ? val.value : val.original || '';
-
- if (this.stringParams) {
- if (value.replace) {
- value = value.replace(/^(\.?\.\/)*/g, '').replace(/\//g, '.');
- }
-
- if (val.depth) {
- this.addDepth(val.depth);
- }
- this.opcode('getContext', val.depth || 0);
- this.opcode('pushStringParam', value, val.type);
-
- if (val.type === 'SubExpression') {
- // SubExpressions get evaluated and passed in
- // in string params mode.
- this.accept(val);
- }
- } else {
- if (this.trackIds) {
- var blockParamIndex = undefined;
- if (val.parts && !_ast2['default'].helpers.scopedId(val) && !val.depth) {
- blockParamIndex = this.blockParamIndex(val.parts[0]);
- }
- if (blockParamIndex) {
- var blockParamChild = val.parts.slice(1).join('.');
- this.opcode('pushId', 'BlockParam', blockParamIndex, blockParamChild);
- } else {
- value = val.original || value;
- if (value.replace) {
- value = value.replace(/^this(?:\.|$)/, '').replace(/^\.\//, '').replace(/^\.$/, '');
- }
-
- this.opcode('pushId', val.type, value);
- }
- }
- this.accept(val);
- }
- },
-
- setupFullMustacheParams: function setupFullMustacheParams(sexpr, program, inverse, omitEmpty) {
- var params = sexpr.params;
- this.pushParams(params);
-
- this.opcode('pushProgram', program);
- this.opcode('pushProgram', inverse);
-
- if (sexpr.hash) {
- this.accept(sexpr.hash);
- } else {
- this.opcode('emptyHash', omitEmpty);
- }
-
- return params;
- },
-
- blockParamIndex: function blockParamIndex(name) {
- for (var depth = 0, len = this.options.blockParams.length; depth < len; depth++) {
- var blockParams = this.options.blockParams[depth],
- param = blockParams && _utils.indexOf(blockParams, name);
- if (blockParams && param >= 0) {
- return [depth, param];
- }
- }
- }
- };
-
- function precompile(input, options, env) {
- if (input == null || typeof input !== 'string' && input.type !== 'Program') {
- throw new _exception2['default']('You must pass a string or Handlebars AST to Handlebars.precompile. You passed ' + input);
- }
-
- options = options || {};
- if (!('data' in options)) {
- options.data = true;
- }
- if (options.compat) {
- options.useDepths = true;
- }
-
- var ast = env.parse(input, options),
- environment = new env.Compiler().compile(ast, options);
- return new env.JavaScriptCompiler().compile(environment, options);
- }
-
- function compile(input, options, env) {
- if (options === undefined) options = {};
-
- if (input == null || typeof input !== 'string' && input.type !== 'Program') {
- throw new _exception2['default']('You must pass a string or Handlebars AST to Handlebars.compile. You passed ' + input);
- }
-
- if (!('data' in options)) {
- options.data = true;
- }
- if (options.compat) {
- options.useDepths = true;
- }
-
- var compiled = undefined;
-
- function compileInput() {
- var ast = env.parse(input, options),
- environment = new env.Compiler().compile(ast, options),
- templateSpec = new env.JavaScriptCompiler().compile(environment, options, undefined, true);
- return env.template(templateSpec);
- }
-
- // Template is only compiled on first use and cached after that point.
- function ret(context, execOptions) {
- if (!compiled) {
- compiled = compileInput();
- }
- return compiled.call(this, context, execOptions);
- }
- ret._setup = function (setupOptions) {
- if (!compiled) {
- compiled = compileInput();
- }
- return compiled._setup(setupOptions);
- };
- ret._child = function (i, data, blockParams, depths) {
- if (!compiled) {
- compiled = compileInput();
- }
- return compiled._child(i, data, blockParams, depths);
- };
- return ret;
- }
-
- function argEquals(a, b) {
- if (a === b) {
- return true;
- }
-
- if (_utils.isArray(a) && _utils.isArray(b) && a.length === b.length) {
- for (var i = 0; i < a.length; i++) {
- if (!argEquals(a[i], b[i])) {
- return false;
- }
- }
- return true;
- }
- }
-
- function transformLiteralToPath(sexpr) {
- if (!sexpr.path.parts) {
- var literal = sexpr.path;
- // Casting to string here to make false and 0 literal values play nicely with the rest
- // of the system.
- sexpr.path = {
- type: 'PathExpression',
- data: false,
- depth: 0,
- parts: [literal.original + ''],
- original: literal.original + '',
- loc: literal.loc
- };
- }
- }
-
-/***/ },
-/* 28 */
-/***/ function(module, exports, __webpack_require__) {
-
- 'use strict';
-
- var _interopRequireDefault = __webpack_require__(1)['default'];
-
- exports.__esModule = true;
-
- var _base = __webpack_require__(4);
-
- var _exception = __webpack_require__(6);
-
- var _exception2 = _interopRequireDefault(_exception);
-
- var _utils = __webpack_require__(5);
-
- var _codeGen = __webpack_require__(29);
-
- var _codeGen2 = _interopRequireDefault(_codeGen);
-
- function Literal(value) {
- this.value = value;
- }
-
- function JavaScriptCompiler() {}
-
- JavaScriptCompiler.prototype = {
- // PUBLIC API: You can override these methods in a subclass to provide
- // alternative compiled forms for name lookup and buffering semantics
- nameLookup: function nameLookup(parent, name /* , type*/) {
- if (JavaScriptCompiler.isValidJavaScriptVariableName(name)) {
- return [parent, '.', name];
- } else {
- return [parent, '[', JSON.stringify(name), ']'];
- }
- },
- depthedLookup: function depthedLookup(name) {
- return [this.aliasable('container.lookup'), '(depths, "', name, '")'];
- },
-
- compilerInfo: function compilerInfo() {
- var revision = _base.COMPILER_REVISION,
- versions = _base.REVISION_CHANGES[revision];
- return [revision, versions];
- },
-
- appendToBuffer: function appendToBuffer(source, location, explicit) {
- // Force a source as this simplifies the merge logic.
- if (!_utils.isArray(source)) {
- source = [source];
- }
- source = this.source.wrap(source, location);
-
- if (this.environment.isSimple) {
- return ['return ', source, ';'];
- } else if (explicit) {
- // This is a case where the buffer operation occurs as a child of another
- // construct, generally braces. We have to explicitly output these buffer
- // operations to ensure that the emitted code goes in the correct location.
- return ['buffer += ', source, ';'];
- } else {
- source.appendToBuffer = true;
- return source;
- }
- },
-
- initializeBuffer: function initializeBuffer() {
- return this.quotedString('');
- },
- // END PUBLIC API
-
- compile: function compile(environment, options, context, asObject) {
- this.environment = environment;
- this.options = options;
- this.stringParams = this.options.stringParams;
- this.trackIds = this.options.trackIds;
- this.precompile = !asObject;
-
- this.name = this.environment.name;
- this.isChild = !!context;
- this.context = context || {
- decorators: [],
- programs: [],
- environments: []
- };
-
- this.preamble();
-
- this.stackSlot = 0;
- this.stackVars = [];
- this.aliases = {};
- this.registers = { list: [] };
- this.hashes = [];
- this.compileStack = [];
- this.inlineStack = [];
- this.blockParams = [];
-
- this.compileChildren(environment, options);
-
- this.useDepths = this.useDepths || environment.useDepths || environment.useDecorators || this.options.compat;
- this.useBlockParams = this.useBlockParams || environment.useBlockParams;
-
- var opcodes = environment.opcodes,
- opcode = undefined,
- firstLoc = undefined,
- i = undefined,
- l = undefined;
-
- for (i = 0, l = opcodes.length; i < l; i++) {
- opcode = opcodes[i];
-
- this.source.currentLocation = opcode.loc;
- firstLoc = firstLoc || opcode.loc;
- this[opcode.opcode].apply(this, opcode.args);
- }
-
- // Flush any trailing content that might be pending.
- this.source.currentLocation = firstLoc;
- this.pushSource('');
-
- /* istanbul ignore next */
- if (this.stackSlot || this.inlineStack.length || this.compileStack.length) {
- throw new _exception2['default']('Compile completed with content left on stack');
- }
-
- if (!this.decorators.isEmpty()) {
- this.useDecorators = true;
-
- this.decorators.prepend('var decorators = container.decorators;\n');
- this.decorators.push('return fn;');
-
- if (asObject) {
- this.decorators = Function.apply(this, ['fn', 'props', 'container', 'depth0', 'data', 'blockParams', 'depths', this.decorators.merge()]);
- } else {
- this.decorators.prepend('function(fn, props, container, depth0, data, blockParams, depths) {\n');
- this.decorators.push('}\n');
- this.decorators = this.decorators.merge();
- }
- } else {
- this.decorators = undefined;
- }
-
- var fn = this.createFunctionContext(asObject);
- if (!this.isChild) {
- var ret = {
- compiler: this.compilerInfo(),
- main: fn
- };
-
- if (this.decorators) {
- ret.main_d = this.decorators; // eslint-disable-line camelcase
- ret.useDecorators = true;
- }
-
- var _context = this.context;
- var programs = _context.programs;
- var decorators = _context.decorators;
-
- for (i = 0, l = programs.length; i < l; i++) {
- if (programs[i]) {
- ret[i] = programs[i];
- if (decorators[i]) {
- ret[i + '_d'] = decorators[i];
- ret.useDecorators = true;
- }
- }
- }
-
- if (this.environment.usePartial) {
- ret.usePartial = true;
- }
- if (this.options.data) {
- ret.useData = true;
- }
- if (this.useDepths) {
- ret.useDepths = true;
- }
- if (this.useBlockParams) {
- ret.useBlockParams = true;
- }
- if (this.options.compat) {
- ret.compat = true;
- }
-
- if (!asObject) {
- ret.compiler = JSON.stringify(ret.compiler);
-
- this.source.currentLocation = { start: { line: 1, column: 0 } };
- ret = this.objectLiteral(ret);
-
- if (options.srcName) {
- ret = ret.toStringWithSourceMap({ file: options.destName });
- ret.map = ret.map && ret.map.toString();
- } else {
- ret = ret.toString();
- }
- } else {
- ret.compilerOptions = this.options;
- }
-
- return ret;
- } else {
- return fn;
- }
- },
-
- preamble: function preamble() {
- // track the last context pushed into place to allow skipping the
- // getContext opcode when it would be a noop
- this.lastContext = 0;
- this.source = new _codeGen2['default'](this.options.srcName);
- this.decorators = new _codeGen2['default'](this.options.srcName);
- },
-
- createFunctionContext: function createFunctionContext(asObject) {
- var varDeclarations = '';
-
- var locals = this.stackVars.concat(this.registers.list);
- if (locals.length > 0) {
- varDeclarations += ', ' + locals.join(', ');
- }
-
- // Generate minimizer alias mappings
- //
- // When using true SourceNodes, this will update all references to the given alias
- // as the source nodes are reused in situ. For the non-source node compilation mode,
- // aliases will not be used, but this case is already being run on the client and
- // we aren't concern about minimizing the template size.
- var aliasCount = 0;
- for (var alias in this.aliases) {
- // eslint-disable-line guard-for-in
- var node = this.aliases[alias];
-
- if (this.aliases.hasOwnProperty(alias) && node.children && node.referenceCount > 1) {
- varDeclarations += ', alias' + ++aliasCount + '=' + alias;
- node.children[0] = 'alias' + aliasCount;
- }
- }
-
- var params = ['container', 'depth0', 'helpers', 'partials', 'data'];
-
- if (this.useBlockParams || this.useDepths) {
- params.push('blockParams');
- }
- if (this.useDepths) {
- params.push('depths');
- }
-
- // Perform a second pass over the output to merge content when possible
- var source = this.mergeSource(varDeclarations);
-
- if (asObject) {
- params.push(source);
-
- return Function.apply(this, params);
- } else {
- return this.source.wrap(['function(', params.join(','), ') {\n ', source, '}']);
- }
- },
- mergeSource: function mergeSource(varDeclarations) {
- var isSimple = this.environment.isSimple,
- appendOnly = !this.forceBuffer,
- appendFirst = undefined,
- sourceSeen = undefined,
- bufferStart = undefined,
- bufferEnd = undefined;
- this.source.each(function (line) {
- if (line.appendToBuffer) {
- if (bufferStart) {
- line.prepend(' + ');
- } else {
- bufferStart = line;
- }
- bufferEnd = line;
- } else {
- if (bufferStart) {
- if (!sourceSeen) {
- appendFirst = true;
- } else {
- bufferStart.prepend('buffer += ');
- }
- bufferEnd.add(';');
- bufferStart = bufferEnd = undefined;
- }
-
- sourceSeen = true;
- if (!isSimple) {
- appendOnly = false;
- }
- }
- });
-
- if (appendOnly) {
- if (bufferStart) {
- bufferStart.prepend('return ');
- bufferEnd.add(';');
- } else if (!sourceSeen) {
- this.source.push('return "";');
- }
- } else {
- varDeclarations += ', buffer = ' + (appendFirst ? '' : this.initializeBuffer());
-
- if (bufferStart) {
- bufferStart.prepend('return buffer + ');
- bufferEnd.add(';');
- } else {
- this.source.push('return buffer;');
- }
- }
-
- if (varDeclarations) {
- this.source.prepend('var ' + varDeclarations.substring(2) + (appendFirst ? '' : ';\n'));
- }
-
- return this.source.merge();
- },
-
- // [blockValue]
- //
- // On stack, before: hash, inverse, program, value
- // On stack, after: return value of blockHelperMissing
- //
- // The purpose of this opcode is to take a block of the form
- // `{{#this.foo}}...{{/this.foo}}`, resolve the value of `foo`, and
- // replace it on the stack with the result of properly
- // invoking blockHelperMissing.
- blockValue: function blockValue(name) {
- var blockHelperMissing = this.aliasable('helpers.blockHelperMissing'),
- params = [this.contextName(0)];
- this.setupHelperArgs(name, 0, params);
-
- var blockName = this.popStack();
- params.splice(1, 0, blockName);
-
- this.push(this.source.functionCall(blockHelperMissing, 'call', params));
- },
-
- // [ambiguousBlockValue]
- //
- // On stack, before: hash, inverse, program, value
- // Compiler value, before: lastHelper=value of last found helper, if any
- // On stack, after, if no lastHelper: same as [blockValue]
- // On stack, after, if lastHelper: value
- ambiguousBlockValue: function ambiguousBlockValue() {
- // We're being a bit cheeky and reusing the options value from the prior exec
- var blockHelperMissing = this.aliasable('helpers.blockHelperMissing'),
- params = [this.contextName(0)];
- this.setupHelperArgs('', 0, params, true);
-
- this.flushInline();
-
- var current = this.topStack();
- params.splice(1, 0, current);
-
- this.pushSource(['if (!', this.lastHelper, ') { ', current, ' = ', this.source.functionCall(blockHelperMissing, 'call', params), '}']);
- },
-
- // [appendContent]
- //
- // On stack, before: ...
- // On stack, after: ...
- //
- // Appends the string value of `content` to the current buffer
- appendContent: function appendContent(content) {
- if (this.pendingContent) {
- content = this.pendingContent + content;
- } else {
- this.pendingLocation = this.source.currentLocation;
- }
-
- this.pendingContent = content;
- },
-
- // [append]
- //
- // On stack, before: value, ...
- // On stack, after: ...
- //
- // Coerces `value` to a String and appends it to the current buffer.
- //
- // If `value` is truthy, or 0, it is coerced into a string and appended
- // Otherwise, the empty string is appended
- append: function append() {
- if (this.isInline()) {
- this.replaceStack(function (current) {
- return [' != null ? ', current, ' : ""'];
- });
-
- this.pushSource(this.appendToBuffer(this.popStack()));
- } else {
- var local = this.popStack();
- this.pushSource(['if (', local, ' != null) { ', this.appendToBuffer(local, undefined, true), ' }']);
- if (this.environment.isSimple) {
- this.pushSource(['else { ', this.appendToBuffer("''", undefined, true), ' }']);
- }
- }
- },
-
- // [appendEscaped]
- //
- // On stack, before: value, ...
- // On stack, after: ...
- //
- // Escape `value` and append it to the buffer
- appendEscaped: function appendEscaped() {
- this.pushSource(this.appendToBuffer([this.aliasable('container.escapeExpression'), '(', this.popStack(), ')']));
- },
-
- // [getContext]
- //
- // On stack, before: ...
- // On stack, after: ...
- // Compiler value, after: lastContext=depth
- //
- // Set the value of the `lastContext` compiler value to the depth
- getContext: function getContext(depth) {
- this.lastContext = depth;
- },
-
- // [pushContext]
- //
- // On stack, before: ...
- // On stack, after: currentContext, ...
- //
- // Pushes the value of the current context onto the stack.
- pushContext: function pushContext() {
- this.pushStackLiteral(this.contextName(this.lastContext));
- },
-
- // [lookupOnContext]
- //
- // On stack, before: ...
- // On stack, after: currentContext[name], ...
- //
- // Looks up the value of `name` on the current context and pushes
- // it onto the stack.
- lookupOnContext: function lookupOnContext(parts, falsy, strict, scoped) {
- var i = 0;
-
- if (!scoped && this.options.compat && !this.lastContext) {
- // The depthed query is expected to handle the undefined logic for the root level that
- // is implemented below, so we evaluate that directly in compat mode
- this.push(this.depthedLookup(parts[i++]));
- } else {
- this.pushContext();
- }
-
- this.resolvePath('context', parts, i, falsy, strict);
- },
-
- // [lookupBlockParam]
- //
- // On stack, before: ...
- // On stack, after: blockParam[name], ...
- //
- // Looks up the value of `parts` on the given block param and pushes
- // it onto the stack.
- lookupBlockParam: function lookupBlockParam(blockParamId, parts) {
- this.useBlockParams = true;
-
- this.push(['blockParams[', blockParamId[0], '][', blockParamId[1], ']']);
- this.resolvePath('context', parts, 1);
- },
-
- // [lookupData]
- //
- // On stack, before: ...
- // On stack, after: data, ...
- //
- // Push the data lookup operator
- lookupData: function lookupData(depth, parts, strict) {
- if (!depth) {
- this.pushStackLiteral('data');
- } else {
- this.pushStackLiteral('container.data(data, ' + depth + ')');
- }
-
- this.resolvePath('data', parts, 0, true, strict);
- },
-
- resolvePath: function resolvePath(type, parts, i, falsy, strict) {
- // istanbul ignore next
-
- var _this = this;
-
- if (this.options.strict || this.options.assumeObjects) {
- this.push(strictLookup(this.options.strict && strict, this, parts, type));
- return;
- }
-
- var len = parts.length;
- for (; i < len; i++) {
- /* eslint-disable no-loop-func */
- this.replaceStack(function (current) {
- var lookup = _this.nameLookup(current, parts[i], type);
- // We want to ensure that zero and false are handled properly if the context (falsy flag)
- // needs to have the special handling for these values.
- if (!falsy) {
- return [' != null ? ', lookup, ' : ', current];
- } else {
- // Otherwise we can use generic falsy handling
- return [' && ', lookup];
- }
- });
- /* eslint-enable no-loop-func */
- }
- },
-
- // [resolvePossibleLambda]
- //
- // On stack, before: value, ...
- // On stack, after: resolved value, ...
- //
- // If the `value` is a lambda, replace it on the stack by
- // the return value of the lambda
- resolvePossibleLambda: function resolvePossibleLambda() {
- this.push([this.aliasable('container.lambda'), '(', this.popStack(), ', ', this.contextName(0), ')']);
- },
-
- // [pushStringParam]
- //
- // On stack, before: ...
- // On stack, after: string, currentContext, ...
- //
- // This opcode is designed for use in string mode, which
- // provides the string value of a parameter along with its
- // depth rather than resolving it immediately.
- pushStringParam: function pushStringParam(string, type) {
- this.pushContext();
- this.pushString(type);
-
- // If it's a subexpression, the string result
- // will be pushed after this opcode.
- if (type !== 'SubExpression') {
- if (typeof string === 'string') {
- this.pushString(string);
- } else {
- this.pushStackLiteral(string);
- }
- }
- },
-
- emptyHash: function emptyHash(omitEmpty) {
- if (this.trackIds) {
- this.push('{}'); // hashIds
- }
- if (this.stringParams) {
- this.push('{}'); // hashContexts
- this.push('{}'); // hashTypes
- }
- this.pushStackLiteral(omitEmpty ? 'undefined' : '{}');
- },
- pushHash: function pushHash() {
- if (this.hash) {
- this.hashes.push(this.hash);
- }
- this.hash = { values: [], types: [], contexts: [], ids: [] };
- },
- popHash: function popHash() {
- var hash = this.hash;
- this.hash = this.hashes.pop();
-
- if (this.trackIds) {
- this.push(this.objectLiteral(hash.ids));
- }
- if (this.stringParams) {
- this.push(this.objectLiteral(hash.contexts));
- this.push(this.objectLiteral(hash.types));
- }
-
- this.push(this.objectLiteral(hash.values));
- },
-
- // [pushString]
- //
- // On stack, before: ...
- // On stack, after: quotedString(string), ...
- //
- // Push a quoted version of `string` onto the stack
- pushString: function pushString(string) {
- this.pushStackLiteral(this.quotedString(string));
- },
-
- // [pushLiteral]
- //
- // On stack, before: ...
- // On stack, after: value, ...
- //
- // Pushes a value onto the stack. This operation prevents
- // the compiler from creating a temporary variable to hold
- // it.
- pushLiteral: function pushLiteral(value) {
- this.pushStackLiteral(value);
- },
-
- // [pushProgram]
- //
- // On stack, before: ...
- // On stack, after: program(guid), ...
- //
- // Push a program expression onto the stack. This takes
- // a compile-time guid and converts it into a runtime-accessible
- // expression.
- pushProgram: function pushProgram(guid) {
- if (guid != null) {
- this.pushStackLiteral(this.programExpression(guid));
- } else {
- this.pushStackLiteral(null);
- }
- },
-
- // [registerDecorator]
- //
- // On stack, before: hash, program, params..., ...
- // On stack, after: ...
- //
- // Pops off the decorator's parameters, invokes the decorator,
- // and inserts the decorator into the decorators list.
- registerDecorator: function registerDecorator(paramSize, name) {
- var foundDecorator = this.nameLookup('decorators', name, 'decorator'),
- options = this.setupHelperArgs(name, paramSize);
-
- this.decorators.push(['fn = ', this.decorators.functionCall(foundDecorator, '', ['fn', 'props', 'container', options]), ' || fn;']);
- },
-
- // [invokeHelper]
- //
- // On stack, before: hash, inverse, program, params..., ...
- // On stack, after: result of helper invocation
- //
- // Pops off the helper's parameters, invokes the helper,
- // and pushes the helper's return value onto the stack.
- //
- // If the helper is not found, `helperMissing` is called.
- invokeHelper: function invokeHelper(paramSize, name, isSimple) {
- var nonHelper = this.popStack(),
- helper = this.setupHelper(paramSize, name),
- simple = isSimple ? [helper.name, ' || '] : '';
-
- var lookup = ['('].concat(simple, nonHelper);
- if (!this.options.strict) {
- lookup.push(' || ', this.aliasable('helpers.helperMissing'));
- }
- lookup.push(')');
-
- this.push(this.source.functionCall(lookup, 'call', helper.callParams));
- },
-
- // [invokeKnownHelper]
- //
- // On stack, before: hash, inverse, program, params..., ...
- // On stack, after: result of helper invocation
- //
- // This operation is used when the helper is known to exist,
- // so a `helperMissing` fallback is not required.
- invokeKnownHelper: function invokeKnownHelper(paramSize, name) {
- var helper = this.setupHelper(paramSize, name);
- this.push(this.source.functionCall(helper.name, 'call', helper.callParams));
- },
-
- // [invokeAmbiguous]
- //
- // On stack, before: hash, inverse, program, params..., ...
- // On stack, after: result of disambiguation
- //
- // This operation is used when an expression like `{{foo}}`
- // is provided, but we don't know at compile-time whether it
- // is a helper or a path.
- //
- // This operation emits more code than the other options,
- // and can be avoided by passing the `knownHelpers` and
- // `knownHelpersOnly` flags at compile-time.
- invokeAmbiguous: function invokeAmbiguous(name, helperCall) {
- this.useRegister('helper');
-
- var nonHelper = this.popStack();
-
- this.emptyHash();
- var helper = this.setupHelper(0, name, helperCall);
-
- var helperName = this.lastHelper = this.nameLookup('helpers', name, 'helper');
-
- var lookup = ['(', '(helper = ', helperName, ' || ', nonHelper, ')'];
- if (!this.options.strict) {
- lookup[0] = '(helper = ';
- lookup.push(' != null ? helper : ', this.aliasable('helpers.helperMissing'));
- }
-
- this.push(['(', lookup, helper.paramsInit ? ['),(', helper.paramsInit] : [], '),', '(typeof helper === ', this.aliasable('"function"'), ' ? ', this.source.functionCall('helper', 'call', helper.callParams), ' : helper))']);
- },
-
- // [invokePartial]
- //
- // On stack, before: context, ...
- // On stack after: result of partial invocation
- //
- // This operation pops off a context, invokes a partial with that context,
- // and pushes the result of the invocation back.
- invokePartial: function invokePartial(isDynamic, name, indent) {
- var params = [],
- options = this.setupParams(name, 1, params);
-
- if (isDynamic) {
- name = this.popStack();
- delete options.name;
- }
-
- if (indent) {
- options.indent = JSON.stringify(indent);
- }
- options.helpers = 'helpers';
- options.partials = 'partials';
- options.decorators = 'container.decorators';
-
- if (!isDynamic) {
- params.unshift(this.nameLookup('partials', name, 'partial'));
- } else {
- params.unshift(name);
- }
-
- if (this.options.compat) {
- options.depths = 'depths';
- }
- options = this.objectLiteral(options);
- params.push(options);
-
- this.push(this.source.functionCall('container.invokePartial', '', params));
- },
-
- // [assignToHash]
- //
- // On stack, before: value, ..., hash, ...
- // On stack, after: ..., hash, ...
- //
- // Pops a value off the stack and assigns it to the current hash
- assignToHash: function assignToHash(key) {
- var value = this.popStack(),
- context = undefined,
- type = undefined,
- id = undefined;
-
- if (this.trackIds) {
- id = this.popStack();
- }
- if (this.stringParams) {
- type = this.popStack();
- context = this.popStack();
- }
-
- var hash = this.hash;
- if (context) {
- hash.contexts[key] = context;
- }
- if (type) {
- hash.types[key] = type;
- }
- if (id) {
- hash.ids[key] = id;
- }
- hash.values[key] = value;
- },
-
- pushId: function pushId(type, name, child) {
- if (type === 'BlockParam') {
- this.pushStackLiteral('blockParams[' + name[0] + '].path[' + name[1] + ']' + (child ? ' + ' + JSON.stringify('.' + child) : ''));
- } else if (type === 'PathExpression') {
- this.pushString(name);
- } else if (type === 'SubExpression') {
- this.pushStackLiteral('true');
- } else {
- this.pushStackLiteral('null');
- }
- },
-
- // HELPERS
-
- compiler: JavaScriptCompiler,
-
- compileChildren: function compileChildren(environment, options) {
- var children = environment.children,
- child = undefined,
- compiler = undefined;
-
- for (var i = 0, l = children.length; i < l; i++) {
- child = children[i];
- compiler = new this.compiler(); // eslint-disable-line new-cap
-
- var index = this.matchExistingProgram(child);
-
- if (index == null) {
- this.context.programs.push(''); // Placeholder to prevent name conflicts for nested children
- index = this.context.programs.length;
- child.index = index;
- child.name = 'program' + index;
- this.context.programs[index] = compiler.compile(child, options, this.context, !this.precompile);
- this.context.decorators[index] = compiler.decorators;
- this.context.environments[index] = child;
-
- this.useDepths = this.useDepths || compiler.useDepths;
- this.useBlockParams = this.useBlockParams || compiler.useBlockParams;
- } else {
- child.index = index;
- child.name = 'program' + index;
-
- this.useDepths = this.useDepths || child.useDepths;
- this.useBlockParams = this.useBlockParams || child.useBlockParams;
- }
- }
- },
- matchExistingProgram: function matchExistingProgram(child) {
- for (var i = 0, len = this.context.environments.length; i < len; i++) {
- var environment = this.context.environments[i];
- if (environment && environment.equals(child)) {
- return i;
- }
- }
- },
-
- programExpression: function programExpression(guid) {
- var child = this.environment.children[guid],
- programParams = [child.index, 'data', child.blockParams];
-
- if (this.useBlockParams || this.useDepths) {
- programParams.push('blockParams');
- }
- if (this.useDepths) {
- programParams.push('depths');
- }
-
- return 'container.program(' + programParams.join(', ') + ')';
- },
-
- useRegister: function useRegister(name) {
- if (!this.registers[name]) {
- this.registers[name] = true;
- this.registers.list.push(name);
- }
- },
-
- push: function push(expr) {
- if (!(expr instanceof Literal)) {
- expr = this.source.wrap(expr);
- }
-
- this.inlineStack.push(expr);
- return expr;
- },
-
- pushStackLiteral: function pushStackLiteral(item) {
- this.push(new Literal(item));
- },
-
- pushSource: function pushSource(source) {
- if (this.pendingContent) {
- this.source.push(this.appendToBuffer(this.source.quotedString(this.pendingContent), this.pendingLocation));
- this.pendingContent = undefined;
- }
-
- if (source) {
- this.source.push(source);
- }
- },
-
- replaceStack: function replaceStack(callback) {
- var prefix = ['('],
- stack = undefined,
- createdStack = undefined,
- usedLiteral = undefined;
-
- /* istanbul ignore next */
- if (!this.isInline()) {
- throw new _exception2['default']('replaceStack on non-inline');
- }
-
- // We want to merge the inline statement into the replacement statement via ','
- var top = this.popStack(true);
-
- if (top instanceof Literal) {
- // Literals do not need to be inlined
- stack = [top.value];
- prefix = ['(', stack];
- usedLiteral = true;
- } else {
- // Get or create the current stack name for use by the inline
- createdStack = true;
- var _name = this.incrStack();
-
- prefix = ['((', this.push(_name), ' = ', top, ')'];
- stack = this.topStack();
- }
-
- var item = callback.call(this, stack);
-
- if (!usedLiteral) {
- this.popStack();
- }
- if (createdStack) {
- this.stackSlot--;
- }
- this.push(prefix.concat(item, ')'));
- },
-
- incrStack: function incrStack() {
- this.stackSlot++;
- if (this.stackSlot > this.stackVars.length) {
- this.stackVars.push('stack' + this.stackSlot);
- }
- return this.topStackName();
- },
- topStackName: function topStackName() {
- return 'stack' + this.stackSlot;
- },
- flushInline: function flushInline() {
- var inlineStack = this.inlineStack;
- this.inlineStack = [];
- for (var i = 0, len = inlineStack.length; i < len; i++) {
- var entry = inlineStack[i];
- /* istanbul ignore if */
- if (entry instanceof Literal) {
- this.compileStack.push(entry);
- } else {
- var stack = this.incrStack();
- this.pushSource([stack, ' = ', entry, ';']);
- this.compileStack.push(stack);
- }
- }
- },
- isInline: function isInline() {
- return this.inlineStack.length;
- },
-
- popStack: function popStack(wrapped) {
- var inline = this.isInline(),
- item = (inline ? this.inlineStack : this.compileStack).pop();
-
- if (!wrapped && item instanceof Literal) {
- return item.value;
- } else {
- if (!inline) {
- /* istanbul ignore next */
- if (!this.stackSlot) {
- throw new _exception2['default']('Invalid stack pop');
- }
- this.stackSlot--;
- }
- return item;
- }
- },
-
- topStack: function topStack() {
- var stack = this.isInline() ? this.inlineStack : this.compileStack,
- item = stack[stack.length - 1];
-
- /* istanbul ignore if */
- if (item instanceof Literal) {
- return item.value;
- } else {
- return item;
- }
- },
-
- contextName: function contextName(context) {
- if (this.useDepths && context) {
- return 'depths[' + context + ']';
- } else {
- return 'depth' + context;
- }
- },
-
- quotedString: function quotedString(str) {
- return this.source.quotedString(str);
- },
-
- objectLiteral: function objectLiteral(obj) {
- return this.source.objectLiteral(obj);
- },
-
- aliasable: function aliasable(name) {
- var ret = this.aliases[name];
- if (ret) {
- ret.referenceCount++;
- return ret;
- }
-
- ret = this.aliases[name] = this.source.wrap(name);
- ret.aliasable = true;
- ret.referenceCount = 1;
-
- return ret;
- },
-
- setupHelper: function setupHelper(paramSize, name, blockHelper) {
- var params = [],
- paramsInit = this.setupHelperArgs(name, paramSize, params, blockHelper);
- var foundHelper = this.nameLookup('helpers', name, 'helper'),
- callContext = this.aliasable(this.contextName(0) + ' != null ? ' + this.contextName(0) + ' : {}');
-
- return {
- params: params,
- paramsInit: paramsInit,
- name: foundHelper,
- callParams: [callContext].concat(params)
- };
- },
-
- setupParams: function setupParams(helper, paramSize, params) {
- var options = {},
- contexts = [],
- types = [],
- ids = [],
- objectArgs = !params,
- param = undefined;
-
- if (objectArgs) {
- params = [];
- }
-
- options.name = this.quotedString(helper);
- options.hash = this.popStack();
-
- if (this.trackIds) {
- options.hashIds = this.popStack();
- }
- if (this.stringParams) {
- options.hashTypes = this.popStack();
- options.hashContexts = this.popStack();
- }
-
- var inverse = this.popStack(),
- program = this.popStack();
-
- // Avoid setting fn and inverse if neither are set. This allows
- // helpers to do a check for `if (options.fn)`
- if (program || inverse) {
- options.fn = program || 'container.noop';
- options.inverse = inverse || 'container.noop';
- }
-
- // The parameters go on to the stack in order (making sure that they are evaluated in order)
- // so we need to pop them off the stack in reverse order
- var i = paramSize;
- while (i--) {
- param = this.popStack();
- params[i] = param;
-
- if (this.trackIds) {
- ids[i] = this.popStack();
- }
- if (this.stringParams) {
- types[i] = this.popStack();
- contexts[i] = this.popStack();
- }
- }
-
- if (objectArgs) {
- options.args = this.source.generateArray(params);
- }
-
- if (this.trackIds) {
- options.ids = this.source.generateArray(ids);
- }
- if (this.stringParams) {
- options.types = this.source.generateArray(types);
- options.contexts = this.source.generateArray(contexts);
- }
-
- if (this.options.data) {
- options.data = 'data';
- }
- if (this.useBlockParams) {
- options.blockParams = 'blockParams';
- }
- return options;
- },
-
- setupHelperArgs: function setupHelperArgs(helper, paramSize, params, useRegister) {
- var options = this.setupParams(helper, paramSize, params);
- options = this.objectLiteral(options);
- if (useRegister) {
- this.useRegister('options');
- params.push('options');
- return ['options=', options];
- } else if (params) {
- params.push(options);
- return '';
- } else {
- return options;
- }
- }
- };
-
- (function () {
- var reservedWords = ('break else new var' + ' case finally return void' + ' catch for switch while' + ' continue function this with' + ' default if throw' + ' delete in try' + ' do instanceof typeof' + ' abstract enum int short' + ' boolean export interface static' + ' byte extends long super' + ' char final native synchronized' + ' class float package throws' + ' const goto private transient' + ' debugger implements protected volatile' + ' double import public let yield await' + ' null true false').split(' ');
-
- var compilerWords = JavaScriptCompiler.RESERVED_WORDS = {};
-
- for (var i = 0, l = reservedWords.length; i < l; i++) {
- compilerWords[reservedWords[i]] = true;
- }
- })();
-
- JavaScriptCompiler.isValidJavaScriptVariableName = function (name) {
- return !JavaScriptCompiler.RESERVED_WORDS[name] && /^[a-zA-Z_$][0-9a-zA-Z_$]*$/.test(name);
- };
-
- function strictLookup(requireTerminal, compiler, parts, type) {
- var stack = compiler.popStack(),
- i = 0,
- len = parts.length;
- if (requireTerminal) {
- len--;
- }
-
- for (; i < len; i++) {
- stack = compiler.nameLookup(stack, parts[i], type);
- }
-
- if (requireTerminal) {
- return [compiler.aliasable('container.strict'), '(', stack, ', ', compiler.quotedString(parts[i]), ')'];
- } else {
- return stack;
- }
- }
-
- exports['default'] = JavaScriptCompiler;
- module.exports = exports['default'];
-
-/***/ },
-/* 29 */
-/***/ function(module, exports, __webpack_require__) {
-
- /* global define */
- 'use strict';
-
- exports.__esModule = true;
-
- var _utils = __webpack_require__(5);
-
- var SourceNode = undefined;
-
- try {
- /* istanbul ignore next */
- if (false) {
- // We don't support this in AMD environments. For these environments, we asusme that
- // they are running on the browser and thus have no need for the source-map library.
- var SourceMap = require('source-map');
- SourceNode = SourceMap.SourceNode;
- }
- } catch (err) {}
- /* NOP */
-
- /* istanbul ignore if: tested but not covered in istanbul due to dist build */
- if (!SourceNode) {
- SourceNode = function (line, column, srcFile, chunks) {
- this.src = '';
- if (chunks) {
- this.add(chunks);
- }
- };
- /* istanbul ignore next */
- SourceNode.prototype = {
- add: function add(chunks) {
- if (_utils.isArray(chunks)) {
- chunks = chunks.join('');
- }
- this.src += chunks;
- },
- prepend: function prepend(chunks) {
- if (_utils.isArray(chunks)) {
- chunks = chunks.join('');
- }
- this.src = chunks + this.src;
- },
- toStringWithSourceMap: function toStringWithSourceMap() {
- return { code: this.toString() };
- },
- toString: function toString() {
- return this.src;
- }
- };
- }
-
- function castChunk(chunk, codeGen, loc) {
- if (_utils.isArray(chunk)) {
- var ret = [];
-
- for (var i = 0, len = chunk.length; i < len; i++) {
- ret.push(codeGen.wrap(chunk[i], loc));
- }
- return ret;
- } else if (typeof chunk === 'boolean' || typeof chunk === 'number') {
- // Handle primitives that the SourceNode will throw up on
- return chunk + '';
- }
- return chunk;
- }
-
- function CodeGen(srcFile) {
- this.srcFile = srcFile;
- this.source = [];
- }
-
- CodeGen.prototype = {
- isEmpty: function isEmpty() {
- return !this.source.length;
- },
- prepend: function prepend(source, loc) {
- this.source.unshift(this.wrap(source, loc));
- },
- push: function push(source, loc) {
- this.source.push(this.wrap(source, loc));
- },
-
- merge: function merge() {
- var source = this.empty();
- this.each(function (line) {
- source.add([' ', line, '\n']);
- });
- return source;
- },
-
- each: function each(iter) {
- for (var i = 0, len = this.source.length; i < len; i++) {
- iter(this.source[i]);
- }
- },
-
- empty: function empty() {
- var loc = this.currentLocation || { start: {} };
- return new SourceNode(loc.start.line, loc.start.column, this.srcFile);
- },
- wrap: function wrap(chunk) {
- var loc = arguments.length <= 1 || arguments[1] === undefined ? this.currentLocation || { start: {} } : arguments[1];
-
- if (chunk instanceof SourceNode) {
- return chunk;
- }
-
- chunk = castChunk(chunk, this, loc);
-
- return new SourceNode(loc.start.line, loc.start.column, this.srcFile, chunk);
- },
-
- functionCall: function functionCall(fn, type, params) {
- params = this.generateList(params);
- return this.wrap([fn, type ? '.' + type + '(' : '(', params, ')']);
- },
-
- quotedString: function quotedString(str) {
- return '"' + (str + '').replace(/\\/g, '\\\\').replace(/"/g, '\\"').replace(/\n/g, '\\n').replace(/\r/g, '\\r').replace(/\u2028/g, '\\u2028') // Per Ecma-262 7.3 + 7.8.4
- .replace(/\u2029/g, '\\u2029') + '"';
- },
-
- objectLiteral: function objectLiteral(obj) {
- var pairs = [];
-
- for (var key in obj) {
- if (obj.hasOwnProperty(key)) {
- var value = castChunk(obj[key], this);
- if (value !== 'undefined') {
- pairs.push([this.quotedString(key), ':', value]);
- }
- }
- }
-
- var ret = this.generateList(pairs);
- ret.prepend('{');
- ret.add('}');
- return ret;
- },
-
- generateList: function generateList(entries) {
- var ret = this.empty();
-
- for (var i = 0, len = entries.length; i < len; i++) {
- if (i) {
- ret.add(',');
- }
-
- ret.add(castChunk(entries[i], this));
- }
-
- return ret;
- },
-
- generateArray: function generateArray(entries) {
- var ret = this.generateList(entries);
- ret.prepend('[');
- ret.add(']');
-
- return ret;
- }
- };
-
- exports['default'] = CodeGen;
- module.exports = exports['default'];
-
-/***/ }
-/******/ ])
-});
-; \ No newline at end of file
+/*!
+
+ handlebars v4.0.5
+
+Copyright (C) 2011-2015 by Yehuda Katz
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
+
+@license
+*/
+(function webpackUniversalModuleDefinition(root, factory) {
+ if(typeof exports === 'object' && typeof module === 'object')
+ module.exports = factory();
+ else if(typeof define === 'function' && define.amd)
+ define([], factory);
+ else if(typeof exports === 'object')
+ exports["Handlebars"] = factory();
+ else
+ root["Handlebars"] = factory();
+})(this, function() {
+return /******/ (function(modules) { // webpackBootstrap
+/******/ // The module cache
+/******/ var installedModules = {};
+
+/******/ // The require function
+/******/ function __webpack_require__(moduleId) {
+
+/******/ // Check if module is in cache
+/******/ if(installedModules[moduleId])
+/******/ return installedModules[moduleId].exports;
+
+/******/ // Create a new module (and put it into the cache)
+/******/ var module = installedModules[moduleId] = {
+/******/ exports: {},
+/******/ id: moduleId,
+/******/ loaded: false
+/******/ };
+
+/******/ // Execute the module function
+/******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);
+
+/******/ // Flag the module as loaded
+/******/ module.loaded = true;
+
+/******/ // Return the exports of the module
+/******/ return module.exports;
+/******/ }
+
+
+/******/ // expose the modules object (__webpack_modules__)
+/******/ __webpack_require__.m = modules;
+
+/******/ // expose the module cache
+/******/ __webpack_require__.c = installedModules;
+
+/******/ // __webpack_public_path__
+/******/ __webpack_require__.p = "";
+
+/******/ // Load entry module and return exports
+/******/ return __webpack_require__(0);
+/******/ })
+/************************************************************************/
+/******/ ([
+/* 0 */
+/***/ function(module, exports, __webpack_require__) {
+
+ 'use strict';
+
+ var _interopRequireDefault = __webpack_require__(1)['default'];
+
+ exports.__esModule = true;
+
+ var _handlebarsRuntime = __webpack_require__(2);
+
+ var _handlebarsRuntime2 = _interopRequireDefault(_handlebarsRuntime);
+
+ // Compiler imports
+
+ var _handlebarsCompilerAst = __webpack_require__(21);
+
+ var _handlebarsCompilerAst2 = _interopRequireDefault(_handlebarsCompilerAst);
+
+ var _handlebarsCompilerBase = __webpack_require__(22);
+
+ var _handlebarsCompilerCompiler = __webpack_require__(27);
+
+ var _handlebarsCompilerJavascriptCompiler = __webpack_require__(28);
+
+ var _handlebarsCompilerJavascriptCompiler2 = _interopRequireDefault(_handlebarsCompilerJavascriptCompiler);
+
+ var _handlebarsCompilerVisitor = __webpack_require__(25);
+
+ var _handlebarsCompilerVisitor2 = _interopRequireDefault(_handlebarsCompilerVisitor);
+
+ var _handlebarsNoConflict = __webpack_require__(20);
+
+ var _handlebarsNoConflict2 = _interopRequireDefault(_handlebarsNoConflict);
+
+ var _create = _handlebarsRuntime2['default'].create;
+ function create() {
+ var hb = _create();
+
+ hb.compile = function (input, options) {
+ return _handlebarsCompilerCompiler.compile(input, options, hb);
+ };
+ hb.precompile = function (input, options) {
+ return _handlebarsCompilerCompiler.precompile(input, options, hb);
+ };
+
+ hb.AST = _handlebarsCompilerAst2['default'];
+ hb.Compiler = _handlebarsCompilerCompiler.Compiler;
+ hb.JavaScriptCompiler = _handlebarsCompilerJavascriptCompiler2['default'];
+ hb.Parser = _handlebarsCompilerBase.parser;
+ hb.parse = _handlebarsCompilerBase.parse;
+
+ return hb;
+ }
+
+ var inst = create();
+ inst.create = create;
+
+ _handlebarsNoConflict2['default'](inst);
+
+ inst.Visitor = _handlebarsCompilerVisitor2['default'];
+
+ inst['default'] = inst;
+
+ exports['default'] = inst;
+ module.exports = exports['default'];
+
+/***/ },
+/* 1 */
+/***/ function(module, exports) {
+
+ "use strict";
+
+ exports["default"] = function (obj) {
+ return obj && obj.__esModule ? obj : {
+ "default": obj
+ };
+ };
+
+ exports.__esModule = true;
+
+/***/ },
+/* 2 */
+/***/ function(module, exports, __webpack_require__) {
+
+ 'use strict';
+
+ var _interopRequireWildcard = __webpack_require__(3)['default'];
+
+ var _interopRequireDefault = __webpack_require__(1)['default'];
+
+ exports.__esModule = true;
+
+ var _handlebarsBase = __webpack_require__(4);
+
+ var base = _interopRequireWildcard(_handlebarsBase);
+
+ // Each of these augment the Handlebars object. No need to setup here.
+ // (This is done to easily share code between commonjs and browse envs)
+
+ var _handlebarsSafeString = __webpack_require__(18);
+
+ var _handlebarsSafeString2 = _interopRequireDefault(_handlebarsSafeString);
+
+ var _handlebarsException = __webpack_require__(6);
+
+ var _handlebarsException2 = _interopRequireDefault(_handlebarsException);
+
+ var _handlebarsUtils = __webpack_require__(5);
+
+ var Utils = _interopRequireWildcard(_handlebarsUtils);
+
+ var _handlebarsRuntime = __webpack_require__(19);
+
+ var runtime = _interopRequireWildcard(_handlebarsRuntime);
+
+ var _handlebarsNoConflict = __webpack_require__(20);
+
+ var _handlebarsNoConflict2 = _interopRequireDefault(_handlebarsNoConflict);
+
+ // For compatibility and usage outside of module systems, make the Handlebars object a namespace
+ function create() {
+ var hb = new base.HandlebarsEnvironment();
+
+ Utils.extend(hb, base);
+ hb.SafeString = _handlebarsSafeString2['default'];
+ hb.Exception = _handlebarsException2['default'];
+ hb.Utils = Utils;
+ hb.escapeExpression = Utils.escapeExpression;
+
+ hb.VM = runtime;
+ hb.template = function (spec) {
+ return runtime.template(spec, hb);
+ };
+
+ return hb;
+ }
+
+ var inst = create();
+ inst.create = create;
+
+ _handlebarsNoConflict2['default'](inst);
+
+ inst['default'] = inst;
+
+ exports['default'] = inst;
+ module.exports = exports['default'];
+
+/***/ },
+/* 3 */
+/***/ function(module, exports) {
+
+ "use strict";
+
+ exports["default"] = function (obj) {
+ if (obj && obj.__esModule) {
+ return obj;
+ } else {
+ var newObj = {};
+
+ if (obj != null) {
+ for (var key in obj) {
+ if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key];
+ }
+ }
+
+ newObj["default"] = obj;
+ return newObj;
+ }
+ };
+
+ exports.__esModule = true;
+
+/***/ },
+/* 4 */
+/***/ function(module, exports, __webpack_require__) {
+
+ 'use strict';
+
+ var _interopRequireDefault = __webpack_require__(1)['default'];
+
+ exports.__esModule = true;
+ exports.HandlebarsEnvironment = HandlebarsEnvironment;
+
+ var _utils = __webpack_require__(5);
+
+ var _exception = __webpack_require__(6);
+
+ var _exception2 = _interopRequireDefault(_exception);
+
+ var _helpers = __webpack_require__(7);
+
+ var _decorators = __webpack_require__(15);
+
+ var _logger = __webpack_require__(17);
+
+ var _logger2 = _interopRequireDefault(_logger);
+
+ var VERSION = '4.0.5';
+ exports.VERSION = VERSION;
+ var COMPILER_REVISION = 7;
+
+ exports.COMPILER_REVISION = COMPILER_REVISION;
+ var REVISION_CHANGES = {
+ 1: '<= 1.0.rc.2', // 1.0.rc.2 is actually rev2 but doesn't report it
+ 2: '== 1.0.0-rc.3',
+ 3: '== 1.0.0-rc.4',
+ 4: '== 1.x.x',
+ 5: '== 2.0.0-alpha.x',
+ 6: '>= 2.0.0-beta.1',
+ 7: '>= 4.0.0'
+ };
+
+ exports.REVISION_CHANGES = REVISION_CHANGES;
+ var objectType = '[object Object]';
+
+ function HandlebarsEnvironment(helpers, partials, decorators) {
+ this.helpers = helpers || {};
+ this.partials = partials || {};
+ this.decorators = decorators || {};
+
+ _helpers.registerDefaultHelpers(this);
+ _decorators.registerDefaultDecorators(this);
+ }
+
+ HandlebarsEnvironment.prototype = {
+ constructor: HandlebarsEnvironment,
+
+ logger: _logger2['default'],
+ log: _logger2['default'].log,
+
+ registerHelper: function registerHelper(name, fn) {
+ if (_utils.toString.call(name) === objectType) {
+ if (fn) {
+ throw new _exception2['default']('Arg not supported with multiple helpers');
+ }
+ _utils.extend(this.helpers, name);
+ } else {
+ this.helpers[name] = fn;
+ }
+ },
+ unregisterHelper: function unregisterHelper(name) {
+ delete this.helpers[name];
+ },
+
+ registerPartial: function registerPartial(name, partial) {
+ if (_utils.toString.call(name) === objectType) {
+ _utils.extend(this.partials, name);
+ } else {
+ if (typeof partial === 'undefined') {
+ throw new _exception2['default']('Attempting to register a partial called "' + name + '" as undefined');
+ }
+ this.partials[name] = partial;
+ }
+ },
+ unregisterPartial: function unregisterPartial(name) {
+ delete this.partials[name];
+ },
+
+ registerDecorator: function registerDecorator(name, fn) {
+ if (_utils.toString.call(name) === objectType) {
+ if (fn) {
+ throw new _exception2['default']('Arg not supported with multiple decorators');
+ }
+ _utils.extend(this.decorators, name);
+ } else {
+ this.decorators[name] = fn;
+ }
+ },
+ unregisterDecorator: function unregisterDecorator(name) {
+ delete this.decorators[name];
+ }
+ };
+
+ var log = _logger2['default'].log;
+
+ exports.log = log;
+ exports.createFrame = _utils.createFrame;
+ exports.logger = _logger2['default'];
+
+/***/ },
+/* 5 */
+/***/ function(module, exports) {
+
+ 'use strict';
+
+ exports.__esModule = true;
+ exports.extend = extend;
+ exports.indexOf = indexOf;
+ exports.escapeExpression = escapeExpression;
+ exports.isEmpty = isEmpty;
+ exports.createFrame = createFrame;
+ exports.blockParams = blockParams;
+ exports.appendContextPath = appendContextPath;
+ var escape = {
+ '&': '&amp;',
+ '<': '&lt;',
+ '>': '&gt;',
+ '"': '&quot;',
+ "'": '&#x27;',
+ '`': '&#x60;',
+ '=': '&#x3D;'
+ };
+
+ var badChars = /[&<>"'`=]/g,
+ possible = /[&<>"'`=]/;
+
+ function escapeChar(chr) {
+ return escape[chr];
+ }
+
+ function extend(obj /* , ...source */) {
+ for (var i = 1; i < arguments.length; i++) {
+ for (var key in arguments[i]) {
+ if (Object.prototype.hasOwnProperty.call(arguments[i], key)) {
+ obj[key] = arguments[i][key];
+ }
+ }
+ }
+
+ return obj;
+ }
+
+ var toString = Object.prototype.toString;
+
+ exports.toString = toString;
+ // Sourced from lodash
+ // https://github.com/bestiejs/lodash/blob/master/LICENSE.txt
+ /* eslint-disable func-style */
+ var isFunction = function isFunction(value) {
+ return typeof value === 'function';
+ };
+ // fallback for older versions of Chrome and Safari
+ /* istanbul ignore next */
+ if (isFunction(/x/)) {
+ exports.isFunction = isFunction = function (value) {
+ return typeof value === 'function' && toString.call(value) === '[object Function]';
+ };
+ }
+ exports.isFunction = isFunction;
+
+ /* eslint-enable func-style */
+
+ /* istanbul ignore next */
+ var isArray = Array.isArray || function (value) {
+ return value && typeof value === 'object' ? toString.call(value) === '[object Array]' : false;
+ };
+
+ exports.isArray = isArray;
+ // Older IE versions do not directly support indexOf so we must implement our own, sadly.
+
+ function indexOf(array, value) {
+ for (var i = 0, len = array.length; i < len; i++) {
+ if (array[i] === value) {
+ return i;
+ }
+ }
+ return -1;
+ }
+
+ function escapeExpression(string) {
+ if (typeof string !== 'string') {
+ // don't escape SafeStrings, since they're already safe
+ if (string && string.toHTML) {
+ return string.toHTML();
+ } else if (string == null) {
+ return '';
+ } else if (!string) {
+ return string + '';
+ }
+
+ // Force a string conversion as this will be done by the append regardless and
+ // the regex test will do this transparently behind the scenes, causing issues if
+ // an object's to string has escaped characters in it.
+ string = '' + string;
+ }
+
+ if (!possible.test(string)) {
+ return string;
+ }
+ return string.replace(badChars, escapeChar);
+ }
+
+ function isEmpty(value) {
+ if (!value && value !== 0) {
+ return true;
+ } else if (isArray(value) && value.length === 0) {
+ return true;
+ } else {
+ return false;
+ }
+ }
+
+ function createFrame(object) {
+ var frame = extend({}, object);
+ frame._parent = object;
+ return frame;
+ }
+
+ function blockParams(params, ids) {
+ params.path = ids;
+ return params;
+ }
+
+ function appendContextPath(contextPath, id) {
+ return (contextPath ? contextPath + '.' : '') + id;
+ }
+
+/***/ },
+/* 6 */
+/***/ function(module, exports) {
+
+ 'use strict';
+
+ exports.__esModule = true;
+
+ var errorProps = ['description', 'fileName', 'lineNumber', 'message', 'name', 'number', 'stack'];
+
+ function Exception(message, node) {
+ var loc = node && node.loc,
+ line = undefined,
+ column = undefined;
+ if (loc) {
+ line = loc.start.line;
+ column = loc.start.column;
+
+ message += ' - ' + line + ':' + column;
+ }
+
+ var tmp = Error.prototype.constructor.call(this, message);
+
+ // Unfortunately errors are not enumerable in Chrome (at least), so `for prop in tmp` doesn't work.
+ for (var idx = 0; idx < errorProps.length; idx++) {
+ this[errorProps[idx]] = tmp[errorProps[idx]];
+ }
+
+ /* istanbul ignore else */
+ if (Error.captureStackTrace) {
+ Error.captureStackTrace(this, Exception);
+ }
+
+ if (loc) {
+ this.lineNumber = line;
+ this.column = column;
+ }
+ }
+
+ Exception.prototype = new Error();
+
+ exports['default'] = Exception;
+ module.exports = exports['default'];
+
+/***/ },
+/* 7 */
+/***/ function(module, exports, __webpack_require__) {
+
+ 'use strict';
+
+ var _interopRequireDefault = __webpack_require__(1)['default'];
+
+ exports.__esModule = true;
+ exports.registerDefaultHelpers = registerDefaultHelpers;
+
+ var _helpersBlockHelperMissing = __webpack_require__(8);
+
+ var _helpersBlockHelperMissing2 = _interopRequireDefault(_helpersBlockHelperMissing);
+
+ var _helpersEach = __webpack_require__(9);
+
+ var _helpersEach2 = _interopRequireDefault(_helpersEach);
+
+ var _helpersHelperMissing = __webpack_require__(10);
+
+ var _helpersHelperMissing2 = _interopRequireDefault(_helpersHelperMissing);
+
+ var _helpersIf = __webpack_require__(11);
+
+ var _helpersIf2 = _interopRequireDefault(_helpersIf);
+
+ var _helpersLog = __webpack_require__(12);
+
+ var _helpersLog2 = _interopRequireDefault(_helpersLog);
+
+ var _helpersLookup = __webpack_require__(13);
+
+ var _helpersLookup2 = _interopRequireDefault(_helpersLookup);
+
+ var _helpersWith = __webpack_require__(14);
+
+ var _helpersWith2 = _interopRequireDefault(_helpersWith);
+
+ function registerDefaultHelpers(instance) {
+ _helpersBlockHelperMissing2['default'](instance);
+ _helpersEach2['default'](instance);
+ _helpersHelperMissing2['default'](instance);
+ _helpersIf2['default'](instance);
+ _helpersLog2['default'](instance);
+ _helpersLookup2['default'](instance);
+ _helpersWith2['default'](instance);
+ }
+
+/***/ },
+/* 8 */
+/***/ function(module, exports, __webpack_require__) {
+
+ 'use strict';
+
+ exports.__esModule = true;
+
+ var _utils = __webpack_require__(5);
+
+ exports['default'] = function (instance) {
+ instance.registerHelper('blockHelperMissing', function (context, options) {
+ var inverse = options.inverse,
+ fn = options.fn;
+
+ if (context === true) {
+ return fn(this);
+ } else if (context === false || context == null) {
+ return inverse(this);
+ } else if (_utils.isArray(context)) {
+ if (context.length > 0) {
+ if (options.ids) {
+ options.ids = [options.name];
+ }
+
+ return instance.helpers.each(context, options);
+ } else {
+ return inverse(this);
+ }
+ } else {
+ if (options.data && options.ids) {
+ var data = _utils.createFrame(options.data);
+ data.contextPath = _utils.appendContextPath(options.data.contextPath, options.name);
+ options = { data: data };
+ }
+
+ return fn(context, options);
+ }
+ });
+ };
+
+ module.exports = exports['default'];
+
+/***/ },
+/* 9 */
+/***/ function(module, exports, __webpack_require__) {
+
+ 'use strict';
+
+ var _interopRequireDefault = __webpack_require__(1)['default'];
+
+ exports.__esModule = true;
+
+ var _utils = __webpack_require__(5);
+
+ var _exception = __webpack_require__(6);
+
+ var _exception2 = _interopRequireDefault(_exception);
+
+ exports['default'] = function (instance) {
+ instance.registerHelper('each', function (context, options) {
+ if (!options) {
+ throw new _exception2['default']('Must pass iterator to #each');
+ }
+
+ var fn = options.fn,
+ inverse = options.inverse,
+ i = 0,
+ ret = '',
+ data = undefined,
+ contextPath = undefined;
+
+ if (options.data && options.ids) {
+ contextPath = _utils.appendContextPath(options.data.contextPath, options.ids[0]) + '.';
+ }
+
+ if (_utils.isFunction(context)) {
+ context = context.call(this);
+ }
+
+ if (options.data) {
+ data = _utils.createFrame(options.data);
+ }
+
+ function execIteration(field, index, last) {
+ if (data) {
+ data.key = field;
+ data.index = index;
+ data.first = index === 0;
+ data.last = !!last;
+
+ if (contextPath) {
+ data.contextPath = contextPath + field;
+ }
+ }
+
+ ret = ret + fn(context[field], {
+ data: data,
+ blockParams: _utils.blockParams([context[field], field], [contextPath + field, null])
+ });
+ }
+
+ if (context && typeof context === 'object') {
+ if (_utils.isArray(context)) {
+ for (var j = context.length; i < j; i++) {
+ if (i in context) {
+ execIteration(i, i, i === context.length - 1);
+ }
+ }
+ } else {
+ var priorKey = undefined;
+
+ for (var key in context) {
+ if (context.hasOwnProperty(key)) {
+ // We're running the iterations one step out of sync so we can detect
+ // the last iteration without have to scan the object twice and create
+ // an itermediate keys array.
+ if (priorKey !== undefined) {
+ execIteration(priorKey, i - 1);
+ }
+ priorKey = key;
+ i++;
+ }
+ }
+ if (priorKey !== undefined) {
+ execIteration(priorKey, i - 1, true);
+ }
+ }
+ }
+
+ if (i === 0) {
+ ret = inverse(this);
+ }
+
+ return ret;
+ });
+ };
+
+ module.exports = exports['default'];
+
+/***/ },
+/* 10 */
+/***/ function(module, exports, __webpack_require__) {
+
+ 'use strict';
+
+ var _interopRequireDefault = __webpack_require__(1)['default'];
+
+ exports.__esModule = true;
+
+ var _exception = __webpack_require__(6);
+
+ var _exception2 = _interopRequireDefault(_exception);
+
+ exports['default'] = function (instance) {
+ instance.registerHelper('helperMissing', function () /* [args, ]options */{
+ if (arguments.length === 1) {
+ // A missing field in a {{foo}} construct.
+ return undefined;
+ } else {
+ // Someone is actually trying to call something, blow up.
+ throw new _exception2['default']('Missing helper: "' + arguments[arguments.length - 1].name + '"');
+ }
+ });
+ };
+
+ module.exports = exports['default'];
+
+/***/ },
+/* 11 */
+/***/ function(module, exports, __webpack_require__) {
+
+ 'use strict';
+
+ exports.__esModule = true;
+
+ var _utils = __webpack_require__(5);
+
+ exports['default'] = function (instance) {
+ instance.registerHelper('if', function (conditional, options) {
+ if (_utils.isFunction(conditional)) {
+ conditional = conditional.call(this);
+ }
+
+ // Default behavior is to render the positive path if the value is truthy and not empty.
+ // The `includeZero` option may be set to treat the condtional as purely not empty based on the
+ // behavior of isEmpty. Effectively this determines if 0 is handled by the positive path or negative.
+ if (!options.hash.includeZero && !conditional || _utils.isEmpty(conditional)) {
+ return options.inverse(this);
+ } else {
+ return options.fn(this);
+ }
+ });
+
+ instance.registerHelper('unless', function (conditional, options) {
+ return instance.helpers['if'].call(this, conditional, { fn: options.inverse, inverse: options.fn, hash: options.hash });
+ });
+ };
+
+ module.exports = exports['default'];
+
+/***/ },
+/* 12 */
+/***/ function(module, exports) {
+
+ 'use strict';
+
+ exports.__esModule = true;
+
+ exports['default'] = function (instance) {
+ instance.registerHelper('log', function () /* message, options */{
+ var args = [undefined],
+ options = arguments[arguments.length - 1];
+ for (var i = 0; i < arguments.length - 1; i++) {
+ args.push(arguments[i]);
+ }
+
+ var level = 1;
+ if (options.hash.level != null) {
+ level = options.hash.level;
+ } else if (options.data && options.data.level != null) {
+ level = options.data.level;
+ }
+ args[0] = level;
+
+ instance.log.apply(instance, args);
+ });
+ };
+
+ module.exports = exports['default'];
+
+/***/ },
+/* 13 */
+/***/ function(module, exports) {
+
+ 'use strict';
+
+ exports.__esModule = true;
+
+ exports['default'] = function (instance) {
+ instance.registerHelper('lookup', function (obj, field) {
+ return obj && obj[field];
+ });
+ };
+
+ module.exports = exports['default'];
+
+/***/ },
+/* 14 */
+/***/ function(module, exports, __webpack_require__) {
+
+ 'use strict';
+
+ exports.__esModule = true;
+
+ var _utils = __webpack_require__(5);
+
+ exports['default'] = function (instance) {
+ instance.registerHelper('with', function (context, options) {
+ if (_utils.isFunction(context)) {
+ context = context.call(this);
+ }
+
+ var fn = options.fn;
+
+ if (!_utils.isEmpty(context)) {
+ var data = options.data;
+ if (options.data && options.ids) {
+ data = _utils.createFrame(options.data);
+ data.contextPath = _utils.appendContextPath(options.data.contextPath, options.ids[0]);
+ }
+
+ return fn(context, {
+ data: data,
+ blockParams: _utils.blockParams([context], [data && data.contextPath])
+ });
+ } else {
+ return options.inverse(this);
+ }
+ });
+ };
+
+ module.exports = exports['default'];
+
+/***/ },
+/* 15 */
+/***/ function(module, exports, __webpack_require__) {
+
+ 'use strict';
+
+ var _interopRequireDefault = __webpack_require__(1)['default'];
+
+ exports.__esModule = true;
+ exports.registerDefaultDecorators = registerDefaultDecorators;
+
+ var _decoratorsInline = __webpack_require__(16);
+
+ var _decoratorsInline2 = _interopRequireDefault(_decoratorsInline);
+
+ function registerDefaultDecorators(instance) {
+ _decoratorsInline2['default'](instance);
+ }
+
+/***/ },
+/* 16 */
+/***/ function(module, exports, __webpack_require__) {
+
+ 'use strict';
+
+ exports.__esModule = true;
+
+ var _utils = __webpack_require__(5);
+
+ exports['default'] = function (instance) {
+ instance.registerDecorator('inline', function (fn, props, container, options) {
+ var ret = fn;
+ if (!props.partials) {
+ props.partials = {};
+ ret = function (context, options) {
+ // Create a new partials stack frame prior to exec.
+ var original = container.partials;
+ container.partials = _utils.extend({}, original, props.partials);
+ var ret = fn(context, options);
+ container.partials = original;
+ return ret;
+ };
+ }
+
+ props.partials[options.args[0]] = options.fn;
+
+ return ret;
+ });
+ };
+
+ module.exports = exports['default'];
+
+/***/ },
+/* 17 */
+/***/ function(module, exports, __webpack_require__) {
+
+ 'use strict';
+
+ exports.__esModule = true;
+
+ var _utils = __webpack_require__(5);
+
+ var logger = {
+ methodMap: ['debug', 'info', 'warn', 'error'],
+ level: 'info',
+
+ // Maps a given level value to the `methodMap` indexes above.
+ lookupLevel: function lookupLevel(level) {
+ if (typeof level === 'string') {
+ var levelMap = _utils.indexOf(logger.methodMap, level.toLowerCase());
+ if (levelMap >= 0) {
+ level = levelMap;
+ } else {
+ level = parseInt(level, 10);
+ }
+ }
+
+ return level;
+ },
+
+ // Can be overridden in the host environment
+ log: function log(level) {
+ level = logger.lookupLevel(level);
+
+ if (typeof console !== 'undefined' && logger.lookupLevel(logger.level) <= level) {
+ var method = logger.methodMap[level];
+ if (!console[method]) {
+ // eslint-disable-line no-console
+ method = 'log';
+ }
+
+ for (var _len = arguments.length, message = Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
+ message[_key - 1] = arguments[_key];
+ }
+
+ console[method].apply(console, message); // eslint-disable-line no-console
+ }
+ }
+ };
+
+ exports['default'] = logger;
+ module.exports = exports['default'];
+
+/***/ },
+/* 18 */
+/***/ function(module, exports) {
+
+ // Build out our basic SafeString type
+ 'use strict';
+
+ exports.__esModule = true;
+ function SafeString(string) {
+ this.string = string;
+ }
+
+ SafeString.prototype.toString = SafeString.prototype.toHTML = function () {
+ return '' + this.string;
+ };
+
+ exports['default'] = SafeString;
+ module.exports = exports['default'];
+
+/***/ },
+/* 19 */
+/***/ function(module, exports, __webpack_require__) {
+
+ 'use strict';
+
+ var _interopRequireWildcard = __webpack_require__(3)['default'];
+
+ var _interopRequireDefault = __webpack_require__(1)['default'];
+
+ exports.__esModule = true;
+ exports.checkRevision = checkRevision;
+ exports.template = template;
+ exports.wrapProgram = wrapProgram;
+ exports.resolvePartial = resolvePartial;
+ exports.invokePartial = invokePartial;
+ exports.noop = noop;
+
+ var _utils = __webpack_require__(5);
+
+ var Utils = _interopRequireWildcard(_utils);
+
+ var _exception = __webpack_require__(6);
+
+ var _exception2 = _interopRequireDefault(_exception);
+
+ var _base = __webpack_require__(4);
+
+ function checkRevision(compilerInfo) {
+ var compilerRevision = compilerInfo && compilerInfo[0] || 1,
+ currentRevision = _base.COMPILER_REVISION;
+
+ if (compilerRevision !== currentRevision) {
+ if (compilerRevision < currentRevision) {
+ var runtimeVersions = _base.REVISION_CHANGES[currentRevision],
+ compilerVersions = _base.REVISION_CHANGES[compilerRevision];
+ throw new _exception2['default']('Template was precompiled with an older version of Handlebars than the current runtime. ' + 'Please update your precompiler to a newer version (' + runtimeVersions + ') or downgrade your runtime to an older version (' + compilerVersions + ').');
+ } else {
+ // Use the embedded version info since the runtime doesn't know about this revision yet
+ throw new _exception2['default']('Template was precompiled with a newer version of Handlebars than the current runtime. ' + 'Please update your runtime to a newer version (' + compilerInfo[1] + ').');
+ }
+ }
+ }
+
+ function template(templateSpec, env) {
+ /* istanbul ignore next */
+ if (!env) {
+ throw new _exception2['default']('No environment passed to template');
+ }
+ if (!templateSpec || !templateSpec.main) {
+ throw new _exception2['default']('Unknown template object: ' + typeof templateSpec);
+ }
+
+ templateSpec.main.decorator = templateSpec.main_d;
+
+ // Note: Using env.VM references rather than local var references throughout this section to allow
+ // for external users to override these as psuedo-supported APIs.
+ env.VM.checkRevision(templateSpec.compiler);
+
+ function invokePartialWrapper(partial, context, options) {
+ if (options.hash) {
+ context = Utils.extend({}, context, options.hash);
+ if (options.ids) {
+ options.ids[0] = true;
+ }
+ }
+
+ partial = env.VM.resolvePartial.call(this, partial, context, options);
+ var result = env.VM.invokePartial.call(this, partial, context, options);
+
+ if (result == null && env.compile) {
+ options.partials[options.name] = env.compile(partial, templateSpec.compilerOptions, env);
+ result = options.partials[options.name](context, options);
+ }
+ if (result != null) {
+ if (options.indent) {
+ var lines = result.split('\n');
+ for (var i = 0, l = lines.length; i < l; i++) {
+ if (!lines[i] && i + 1 === l) {
+ break;
+ }
+
+ lines[i] = options.indent + lines[i];
+ }
+ result = lines.join('\n');
+ }
+ return result;
+ } else {
+ throw new _exception2['default']('The partial ' + options.name + ' could not be compiled when running in runtime-only mode');
+ }
+ }
+
+ // Just add water
+ var container = {
+ strict: function strict(obj, name) {
+ if (!(name in obj)) {
+ throw new _exception2['default']('"' + name + '" not defined in ' + obj);
+ }
+ return obj[name];
+ },
+ lookup: function lookup(depths, name) {
+ var len = depths.length;
+ for (var i = 0; i < len; i++) {
+ if (depths[i] && depths[i][name] != null) {
+ return depths[i][name];
+ }
+ }
+ },
+ lambda: function lambda(current, context) {
+ return typeof current === 'function' ? current.call(context) : current;
+ },
+
+ escapeExpression: Utils.escapeExpression,
+ invokePartial: invokePartialWrapper,
+
+ fn: function fn(i) {
+ var ret = templateSpec[i];
+ ret.decorator = templateSpec[i + '_d'];
+ return ret;
+ },
+
+ programs: [],
+ program: function program(i, data, declaredBlockParams, blockParams, depths) {
+ var programWrapper = this.programs[i],
+ fn = this.fn(i);
+ if (data || depths || blockParams || declaredBlockParams) {
+ programWrapper = wrapProgram(this, i, fn, data, declaredBlockParams, blockParams, depths);
+ } else if (!programWrapper) {
+ programWrapper = this.programs[i] = wrapProgram(this, i, fn);
+ }
+ return programWrapper;
+ },
+
+ data: function data(value, depth) {
+ while (value && depth--) {
+ value = value._parent;
+ }
+ return value;
+ },
+ merge: function merge(param, common) {
+ var obj = param || common;
+
+ if (param && common && param !== common) {
+ obj = Utils.extend({}, common, param);
+ }
+
+ return obj;
+ },
+
+ noop: env.VM.noop,
+ compilerInfo: templateSpec.compiler
+ };
+
+ function ret(context) {
+ var options = arguments.length <= 1 || arguments[1] === undefined ? {} : arguments[1];
+
+ var data = options.data;
+
+ ret._setup(options);
+ if (!options.partial && templateSpec.useData) {
+ data = initData(context, data);
+ }
+ var depths = undefined,
+ blockParams = templateSpec.useBlockParams ? [] : undefined;
+ if (templateSpec.useDepths) {
+ if (options.depths) {
+ depths = context !== options.depths[0] ? [context].concat(options.depths) : options.depths;
+ } else {
+ depths = [context];
+ }
+ }
+
+ function main(context /*, options*/) {
+ return '' + templateSpec.main(container, context, container.helpers, container.partials, data, blockParams, depths);
+ }
+ main = executeDecorators(templateSpec.main, main, container, options.depths || [], data, blockParams);
+ return main(context, options);
+ }
+ ret.isTop = true;
+
+ ret._setup = function (options) {
+ if (!options.partial) {
+ container.helpers = container.merge(options.helpers, env.helpers);
+
+ if (templateSpec.usePartial) {
+ container.partials = container.merge(options.partials, env.partials);
+ }
+ if (templateSpec.usePartial || templateSpec.useDecorators) {
+ container.decorators = container.merge(options.decorators, env.decorators);
+ }
+ } else {
+ container.helpers = options.helpers;
+ container.partials = options.partials;
+ container.decorators = options.decorators;
+ }
+ };
+
+ ret._child = function (i, data, blockParams, depths) {
+ if (templateSpec.useBlockParams && !blockParams) {
+ throw new _exception2['default']('must pass block params');
+ }
+ if (templateSpec.useDepths && !depths) {
+ throw new _exception2['default']('must pass parent depths');
+ }
+
+ return wrapProgram(container, i, templateSpec[i], data, 0, blockParams, depths);
+ };
+ return ret;
+ }
+
+ function wrapProgram(container, i, fn, data, declaredBlockParams, blockParams, depths) {
+ function prog(context) {
+ var options = arguments.length <= 1 || arguments[1] === undefined ? {} : arguments[1];
+
+ var currentDepths = depths;
+ if (depths && context !== depths[0]) {
+ currentDepths = [context].concat(depths);
+ }
+
+ return fn(container, context, container.helpers, container.partials, options.data || data, blockParams && [options.blockParams].concat(blockParams), currentDepths);
+ }
+
+ prog = executeDecorators(fn, prog, container, depths, data, blockParams);
+
+ prog.program = i;
+ prog.depth = depths ? depths.length : 0;
+ prog.blockParams = declaredBlockParams || 0;
+ return prog;
+ }
+
+ function resolvePartial(partial, context, options) {
+ if (!partial) {
+ if (options.name === '@partial-block') {
+ partial = options.data['partial-block'];
+ } else {
+ partial = options.partials[options.name];
+ }
+ } else if (!partial.call && !options.name) {
+ // This is a dynamic partial that returned a string
+ options.name = partial;
+ partial = options.partials[partial];
+ }
+ return partial;
+ }
+
+ function invokePartial(partial, context, options) {
+ options.partial = true;
+ if (options.ids) {
+ options.data.contextPath = options.ids[0] || options.data.contextPath;
+ }
+
+ var partialBlock = undefined;
+ if (options.fn && options.fn !== noop) {
+ options.data = _base.createFrame(options.data);
+ partialBlock = options.data['partial-block'] = options.fn;
+
+ if (partialBlock.partials) {
+ options.partials = Utils.extend({}, options.partials, partialBlock.partials);
+ }
+ }
+
+ if (partial === undefined && partialBlock) {
+ partial = partialBlock;
+ }
+
+ if (partial === undefined) {
+ throw new _exception2['default']('The partial ' + options.name + ' could not be found');
+ } else if (partial instanceof Function) {
+ return partial(context, options);
+ }
+ }
+
+ function noop() {
+ return '';
+ }
+
+ function initData(context, data) {
+ if (!data || !('root' in data)) {
+ data = data ? _base.createFrame(data) : {};
+ data.root = context;
+ }
+ return data;
+ }
+
+ function executeDecorators(fn, prog, container, depths, data, blockParams) {
+ if (fn.decorator) {
+ var props = {};
+ prog = fn.decorator(prog, props, container, depths && depths[0], data, blockParams, depths);
+ Utils.extend(prog, props);
+ }
+ return prog;
+ }
+
+/***/ },
+/* 20 */
+/***/ function(module, exports) {
+
+ /* WEBPACK VAR INJECTION */(function(global) {/* global window */
+ 'use strict';
+
+ exports.__esModule = true;
+
+ exports['default'] = function (Handlebars) {
+ /* istanbul ignore next */
+ var root = typeof global !== 'undefined' ? global : window,
+ $Handlebars = root.Handlebars;
+ /* istanbul ignore next */
+ Handlebars.noConflict = function () {
+ if (root.Handlebars === Handlebars) {
+ root.Handlebars = $Handlebars;
+ }
+ return Handlebars;
+ };
+ };
+
+ module.exports = exports['default'];
+ /* WEBPACK VAR INJECTION */}.call(exports, (function() { return this; }())))
+
+/***/ },
+/* 21 */
+/***/ function(module, exports) {
+
+ 'use strict';
+
+ exports.__esModule = true;
+ var AST = {
+ // Public API used to evaluate derived attributes regarding AST nodes
+ helpers: {
+ // a mustache is definitely a helper if:
+ // * it is an eligible helper, and
+ // * it has at least one parameter or hash segment
+ helperExpression: function helperExpression(node) {
+ return node.type === 'SubExpression' || (node.type === 'MustacheStatement' || node.type === 'BlockStatement') && !!(node.params && node.params.length || node.hash);
+ },
+
+ scopedId: function scopedId(path) {
+ return (/^\.|this\b/.test(path.original)
+ );
+ },
+
+ // an ID is simple if it only has one part, and that part is not
+ // `..` or `this`.
+ simpleId: function simpleId(path) {
+ return path.parts.length === 1 && !AST.helpers.scopedId(path) && !path.depth;
+ }
+ }
+ };
+
+ // Must be exported as an object rather than the root of the module as the jison lexer
+ // must modify the object to operate properly.
+ exports['default'] = AST;
+ module.exports = exports['default'];
+
+/***/ },
+/* 22 */
+/***/ function(module, exports, __webpack_require__) {
+
+ 'use strict';
+
+ var _interopRequireDefault = __webpack_require__(1)['default'];
+
+ var _interopRequireWildcard = __webpack_require__(3)['default'];
+
+ exports.__esModule = true;
+ exports.parse = parse;
+
+ var _parser = __webpack_require__(23);
+
+ var _parser2 = _interopRequireDefault(_parser);
+
+ var _whitespaceControl = __webpack_require__(24);
+
+ var _whitespaceControl2 = _interopRequireDefault(_whitespaceControl);
+
+ var _helpers = __webpack_require__(26);
+
+ var Helpers = _interopRequireWildcard(_helpers);
+
+ var _utils = __webpack_require__(5);
+
+ exports.parser = _parser2['default'];
+
+ var yy = {};
+ _utils.extend(yy, Helpers);
+
+ function parse(input, options) {
+ // Just return if an already-compiled AST was passed in.
+ if (input.type === 'Program') {
+ return input;
+ }
+
+ _parser2['default'].yy = yy;
+
+ // Altering the shared object here, but this is ok as parser is a sync operation
+ yy.locInfo = function (locInfo) {
+ return new yy.SourceLocation(options && options.srcName, locInfo);
+ };
+
+ var strip = new _whitespaceControl2['default'](options);
+ return strip.accept(_parser2['default'].parse(input));
+ }
+
+/***/ },
+/* 23 */
+/***/ function(module, exports) {
+
+ /* istanbul ignore next */
+ /* Jison generated parser */
+ "use strict";
+
+ var handlebars = (function () {
+ var parser = { trace: function trace() {},
+ yy: {},
+ symbols_: { "error": 2, "root": 3, "program": 4, "EOF": 5, "program_repetition0": 6, "statement": 7, "mustache": 8, "block": 9, "rawBlock": 10, "partial": 11, "partialBlock": 12, "content": 13, "COMMENT": 14, "CONTENT": 15, "openRawBlock": 16, "rawBlock_repetition_plus0": 17, "END_RAW_BLOCK": 18, "OPEN_RAW_BLOCK": 19, "helperName": 20, "openRawBlock_repetition0": 21, "openRawBlock_option0": 22, "CLOSE_RAW_BLOCK": 23, "openBlock": 24, "block_option0": 25, "closeBlock": 26, "openInverse": 27, "block_option1": 28, "OPEN_BLOCK": 29, "openBlock_repetition0": 30, "openBlock_option0": 31, "openBlock_option1": 32, "CLOSE": 33, "OPEN_INVERSE": 34, "openInverse_repetition0": 35, "openInverse_option0": 36, "openInverse_option1": 37, "openInverseChain": 38, "OPEN_INVERSE_CHAIN": 39, "openInverseChain_repetition0": 40, "openInverseChain_option0": 41, "openInverseChain_option1": 42, "inverseAndProgram": 43, "INVERSE": 44, "inverseChain": 45, "inverseChain_option0": 46, "OPEN_ENDBLOCK": 47, "OPEN": 48, "mustache_repetition0": 49, "mustache_option0": 50, "OPEN_UNESCAPED": 51, "mustache_repetition1": 52, "mustache_option1": 53, "CLOSE_UNESCAPED": 54, "OPEN_PARTIAL": 55, "partialName": 56, "partial_repetition0": 57, "partial_option0": 58, "openPartialBlock": 59, "OPEN_PARTIAL_BLOCK": 60, "openPartialBlock_repetition0": 61, "openPartialBlock_option0": 62, "param": 63, "sexpr": 64, "OPEN_SEXPR": 65, "sexpr_repetition0": 66, "sexpr_option0": 67, "CLOSE_SEXPR": 68, "hash": 69, "hash_repetition_plus0": 70, "hashSegment": 71, "ID": 72, "EQUALS": 73, "blockParams": 74, "OPEN_BLOCK_PARAMS": 75, "blockParams_repetition_plus0": 76, "CLOSE_BLOCK_PARAMS": 77, "path": 78, "dataName": 79, "STRING": 80, "NUMBER": 81, "BOOLEAN": 82, "UNDEFINED": 83, "NULL": 84, "DATA": 85, "pathSegments": 86, "SEP": 87, "$accept": 0, "$end": 1 },
+ terminals_: { 2: "error", 5: "EOF", 14: "COMMENT", 15: "CONTENT", 18: "END_RAW_BLOCK", 19: "OPEN_RAW_BLOCK", 23: "CLOSE_RAW_BLOCK", 29: "OPEN_BLOCK", 33: "CLOSE", 34: "OPEN_INVERSE", 39: "OPEN_INVERSE_CHAIN", 44: "INVERSE", 47: "OPEN_ENDBLOCK", 48: "OPEN", 51: "OPEN_UNESCAPED", 54: "CLOSE_UNESCAPED", 55: "OPEN_PARTIAL", 60: "OPEN_PARTIAL_BLOCK", 65: "OPEN_SEXPR", 68: "CLOSE_SEXPR", 72: "ID", 73: "EQUALS", 75: "OPEN_BLOCK_PARAMS", 77: "CLOSE_BLOCK_PARAMS", 80: "STRING", 81: "NUMBER", 82: "BOOLEAN", 83: "UNDEFINED", 84: "NULL", 85: "DATA", 87: "SEP" },
+ productions_: [0, [3, 2], [4, 1], [7, 1], [7, 1], [7, 1], [7, 1], [7, 1], [7, 1], [7, 1], [13, 1], [10, 3], [16, 5], [9, 4], [9, 4], [24, 6], [27, 6], [38, 6], [43, 2], [45, 3], [45, 1], [26, 3], [8, 5], [8, 5], [11, 5], [12, 3], [59, 5], [63, 1], [63, 1], [64, 5], [69, 1], [71, 3], [74, 3], [20, 1], [20, 1], [20, 1], [20, 1], [20, 1], [20, 1], [20, 1], [56, 1], [56, 1], [79, 2], [78, 1], [86, 3], [86, 1], [6, 0], [6, 2], [17, 1], [17, 2], [21, 0], [21, 2], [22, 0], [22, 1], [25, 0], [25, 1], [28, 0], [28, 1], [30, 0], [30, 2], [31, 0], [31, 1], [32, 0], [32, 1], [35, 0], [35, 2], [36, 0], [36, 1], [37, 0], [37, 1], [40, 0], [40, 2], [41, 0], [41, 1], [42, 0], [42, 1], [46, 0], [46, 1], [49, 0], [49, 2], [50, 0], [50, 1], [52, 0], [52, 2], [53, 0], [53, 1], [57, 0], [57, 2], [58, 0], [58, 1], [61, 0], [61, 2], [62, 0], [62, 1], [66, 0], [66, 2], [67, 0], [67, 1], [70, 1], [70, 2], [76, 1], [76, 2]],
+ performAction: function anonymous(yytext, yyleng, yylineno, yy, yystate, $$, _$
+ /**/) {
+
+ var $0 = $$.length - 1;
+ switch (yystate) {
+ case 1:
+ return $$[$0 - 1];
+ break;
+ case 2:
+ this.$ = yy.prepareProgram($$[$0]);
+ break;
+ case 3:
+ this.$ = $$[$0];
+ break;
+ case 4:
+ this.$ = $$[$0];
+ break;
+ case 5:
+ this.$ = $$[$0];
+ break;
+ case 6:
+ this.$ = $$[$0];
+ break;
+ case 7:
+ this.$ = $$[$0];
+ break;
+ case 8:
+ this.$ = $$[$0];
+ break;
+ case 9:
+ this.$ = {
+ type: 'CommentStatement',
+ value: yy.stripComment($$[$0]),
+ strip: yy.stripFlags($$[$0], $$[$0]),
+ loc: yy.locInfo(this._$)
+ };
+
+ break;
+ case 10:
+ this.$ = {
+ type: 'ContentStatement',
+ original: $$[$0],
+ value: $$[$0],
+ loc: yy.locInfo(this._$)
+ };
+
+ break;
+ case 11:
+ this.$ = yy.prepareRawBlock($$[$0 - 2], $$[$0 - 1], $$[$0], this._$);
+ break;
+ case 12:
+ this.$ = { path: $$[$0 - 3], params: $$[$0 - 2], hash: $$[$0 - 1] };
+ break;
+ case 13:
+ this.$ = yy.prepareBlock($$[$0 - 3], $$[$0 - 2], $$[$0 - 1], $$[$0], false, this._$);
+ break;
+ case 14:
+ this.$ = yy.prepareBlock($$[$0 - 3], $$[$0 - 2], $$[$0 - 1], $$[$0], true, this._$);
+ break;
+ case 15:
+ this.$ = { open: $$[$0 - 5], path: $$[$0 - 4], params: $$[$0 - 3], hash: $$[$0 - 2], blockParams: $$[$0 - 1], strip: yy.stripFlags($$[$0 - 5], $$[$0]) };
+ break;
+ case 16:
+ this.$ = { path: $$[$0 - 4], params: $$[$0 - 3], hash: $$[$0 - 2], blockParams: $$[$0 - 1], strip: yy.stripFlags($$[$0 - 5], $$[$0]) };
+ break;
+ case 17:
+ this.$ = { path: $$[$0 - 4], params: $$[$0 - 3], hash: $$[$0 - 2], blockParams: $$[$0 - 1], strip: yy.stripFlags($$[$0 - 5], $$[$0]) };
+ break;
+ case 18:
+ this.$ = { strip: yy.stripFlags($$[$0 - 1], $$[$0 - 1]), program: $$[$0] };
+ break;
+ case 19:
+ var inverse = yy.prepareBlock($$[$0 - 2], $$[$0 - 1], $$[$0], $$[$0], false, this._$),
+ program = yy.prepareProgram([inverse], $$[$0 - 1].loc);
+ program.chained = true;
+
+ this.$ = { strip: $$[$0 - 2].strip, program: program, chain: true };
+
+ break;
+ case 20:
+ this.$ = $$[$0];
+ break;
+ case 21:
+ this.$ = { path: $$[$0 - 1], strip: yy.stripFlags($$[$0 - 2], $$[$0]) };
+ break;
+ case 22:
+ this.$ = yy.prepareMustache($$[$0 - 3], $$[$0 - 2], $$[$0 - 1], $$[$0 - 4], yy.stripFlags($$[$0 - 4], $$[$0]), this._$);
+ break;
+ case 23:
+ this.$ = yy.prepareMustache($$[$0 - 3], $$[$0 - 2], $$[$0 - 1], $$[$0 - 4], yy.stripFlags($$[$0 - 4], $$[$0]), this._$);
+ break;
+ case 24:
+ this.$ = {
+ type: 'PartialStatement',
+ name: $$[$0 - 3],
+ params: $$[$0 - 2],
+ hash: $$[$0 - 1],
+ indent: '',
+ strip: yy.stripFlags($$[$0 - 4], $$[$0]),
+ loc: yy.locInfo(this._$)
+ };
+
+ break;
+ case 25:
+ this.$ = yy.preparePartialBlock($$[$0 - 2], $$[$0 - 1], $$[$0], this._$);
+ break;
+ case 26:
+ this.$ = { path: $$[$0 - 3], params: $$[$0 - 2], hash: $$[$0 - 1], strip: yy.stripFlags($$[$0 - 4], $$[$0]) };
+ break;
+ case 27:
+ this.$ = $$[$0];
+ break;
+ case 28:
+ this.$ = $$[$0];
+ break;
+ case 29:
+ this.$ = {
+ type: 'SubExpression',
+ path: $$[$0 - 3],
+ params: $$[$0 - 2],
+ hash: $$[$0 - 1],
+ loc: yy.locInfo(this._$)
+ };
+
+ break;
+ case 30:
+ this.$ = { type: 'Hash', pairs: $$[$0], loc: yy.locInfo(this._$) };
+ break;
+ case 31:
+ this.$ = { type: 'HashPair', key: yy.id($$[$0 - 2]), value: $$[$0], loc: yy.locInfo(this._$) };
+ break;
+ case 32:
+ this.$ = yy.id($$[$0 - 1]);
+ break;
+ case 33:
+ this.$ = $$[$0];
+ break;
+ case 34:
+ this.$ = $$[$0];
+ break;
+ case 35:
+ this.$ = { type: 'StringLiteral', value: $$[$0], original: $$[$0], loc: yy.locInfo(this._$) };
+ break;
+ case 36:
+ this.$ = { type: 'NumberLiteral', value: Number($$[$0]), original: Number($$[$0]), loc: yy.locInfo(this._$) };
+ break;
+ case 37:
+ this.$ = { type: 'BooleanLiteral', value: $$[$0] === 'true', original: $$[$0] === 'true', loc: yy.locInfo(this._$) };
+ break;
+ case 38:
+ this.$ = { type: 'UndefinedLiteral', original: undefined, value: undefined, loc: yy.locInfo(this._$) };
+ break;
+ case 39:
+ this.$ = { type: 'NullLiteral', original: null, value: null, loc: yy.locInfo(this._$) };
+ break;
+ case 40:
+ this.$ = $$[$0];
+ break;
+ case 41:
+ this.$ = $$[$0];
+ break;
+ case 42:
+ this.$ = yy.preparePath(true, $$[$0], this._$);
+ break;
+ case 43:
+ this.$ = yy.preparePath(false, $$[$0], this._$);
+ break;
+ case 44:
+ $$[$0 - 2].push({ part: yy.id($$[$0]), original: $$[$0], separator: $$[$0 - 1] });this.$ = $$[$0 - 2];
+ break;
+ case 45:
+ this.$ = [{ part: yy.id($$[$0]), original: $$[$0] }];
+ break;
+ case 46:
+ this.$ = [];
+ break;
+ case 47:
+ $$[$0 - 1].push($$[$0]);
+ break;
+ case 48:
+ this.$ = [$$[$0]];
+ break;
+ case 49:
+ $$[$0 - 1].push($$[$0]);
+ break;
+ case 50:
+ this.$ = [];
+ break;
+ case 51:
+ $$[$0 - 1].push($$[$0]);
+ break;
+ case 58:
+ this.$ = [];
+ break;
+ case 59:
+ $$[$0 - 1].push($$[$0]);
+ break;
+ case 64:
+ this.$ = [];
+ break;
+ case 65:
+ $$[$0 - 1].push($$[$0]);
+ break;
+ case 70:
+ this.$ = [];
+ break;
+ case 71:
+ $$[$0 - 1].push($$[$0]);
+ break;
+ case 78:
+ this.$ = [];
+ break;
+ case 79:
+ $$[$0 - 1].push($$[$0]);
+ break;
+ case 82:
+ this.$ = [];
+ break;
+ case 83:
+ $$[$0 - 1].push($$[$0]);
+ break;
+ case 86:
+ this.$ = [];
+ break;
+ case 87:
+ $$[$0 - 1].push($$[$0]);
+ break;
+ case 90:
+ this.$ = [];
+ break;
+ case 91:
+ $$[$0 - 1].push($$[$0]);
+ break;
+ case 94:
+ this.$ = [];
+ break;
+ case 95:
+ $$[$0 - 1].push($$[$0]);
+ break;
+ case 98:
+ this.$ = [$$[$0]];
+ break;
+ case 99:
+ $$[$0 - 1].push($$[$0]);
+ break;
+ case 100:
+ this.$ = [$$[$0]];
+ break;
+ case 101:
+ $$[$0 - 1].push($$[$0]);
+ break;
+ }
+ },
+ table: [{ 3: 1, 4: 2, 5: [2, 46], 6: 3, 14: [2, 46], 15: [2, 46], 19: [2, 46], 29: [2, 46], 34: [2, 46], 48: [2, 46], 51: [2, 46], 55: [2, 46], 60: [2, 46] }, { 1: [3] }, { 5: [1, 4] }, { 5: [2, 2], 7: 5, 8: 6, 9: 7, 10: 8, 11: 9, 12: 10, 13: 11, 14: [1, 12], 15: [1, 20], 16: 17, 19: [1, 23], 24: 15, 27: 16, 29: [1, 21], 34: [1, 22], 39: [2, 2], 44: [2, 2], 47: [2, 2], 48: [1, 13], 51: [1, 14], 55: [1, 18], 59: 19, 60: [1, 24] }, { 1: [2, 1] }, { 5: [2, 47], 14: [2, 47], 15: [2, 47], 19: [2, 47], 29: [2, 47], 34: [2, 47], 39: [2, 47], 44: [2, 47], 47: [2, 47], 48: [2, 47], 51: [2, 47], 55: [2, 47], 60: [2, 47] }, { 5: [2, 3], 14: [2, 3], 15: [2, 3], 19: [2, 3], 29: [2, 3], 34: [2, 3], 39: [2, 3], 44: [2, 3], 47: [2, 3], 48: [2, 3], 51: [2, 3], 55: [2, 3], 60: [2, 3] }, { 5: [2, 4], 14: [2, 4], 15: [2, 4], 19: [2, 4], 29: [2, 4], 34: [2, 4], 39: [2, 4], 44: [2, 4], 47: [2, 4], 48: [2, 4], 51: [2, 4], 55: [2, 4], 60: [2, 4] }, { 5: [2, 5], 14: [2, 5], 15: [2, 5], 19: [2, 5], 29: [2, 5], 34: [2, 5], 39: [2, 5], 44: [2, 5], 47: [2, 5], 48: [2, 5], 51: [2, 5], 55: [2, 5], 60: [2, 5] }, { 5: [2, 6], 14: [2, 6], 15: [2, 6], 19: [2, 6], 29: [2, 6], 34: [2, 6], 39: [2, 6], 44: [2, 6], 47: [2, 6], 48: [2, 6], 51: [2, 6], 55: [2, 6], 60: [2, 6] }, { 5: [2, 7], 14: [2, 7], 15: [2, 7], 19: [2, 7], 29: [2, 7], 34: [2, 7], 39: [2, 7], 44: [2, 7], 47: [2, 7], 48: [2, 7], 51: [2, 7], 55: [2, 7], 60: [2, 7] }, { 5: [2, 8], 14: [2, 8], 15: [2, 8], 19: [2, 8], 29: [2, 8], 34: [2, 8], 39: [2, 8], 44: [2, 8], 47: [2, 8], 48: [2, 8], 51: [2, 8], 55: [2, 8], 60: [2, 8] }, { 5: [2, 9], 14: [2, 9], 15: [2, 9], 19: [2, 9], 29: [2, 9], 34: [2, 9], 39: [2, 9], 44: [2, 9], 47: [2, 9], 48: [2, 9], 51: [2, 9], 55: [2, 9], 60: [2, 9] }, { 20: 25, 72: [1, 35], 78: 26, 79: 27, 80: [1, 28], 81: [1, 29], 82: [1, 30], 83: [1, 31], 84: [1, 32], 85: [1, 34], 86: 33 }, { 20: 36, 72: [1, 35], 78: 26, 79: 27, 80: [1, 28], 81: [1, 29], 82: [1, 30], 83: [1, 31], 84: [1, 32], 85: [1, 34], 86: 33 }, { 4: 37, 6: 3, 14: [2, 46], 15: [2, 46], 19: [2, 46], 29: [2, 46], 34: [2, 46], 39: [2, 46], 44: [2, 46], 47: [2, 46], 48: [2, 46], 51: [2, 46], 55: [2, 46], 60: [2, 46] }, { 4: 38, 6: 3, 14: [2, 46], 15: [2, 46], 19: [2, 46], 29: [2, 46], 34: [2, 46], 44: [2, 46], 47: [2, 46], 48: [2, 46], 51: [2, 46], 55: [2, 46], 60: [2, 46] }, { 13: 40, 15: [1, 20], 17: 39 }, { 20: 42, 56: 41, 64: 43, 65: [1, 44], 72: [1, 35], 78: 26, 79: 27, 80: [1, 28], 81: [1, 29], 82: [1, 30], 83: [1, 31], 84: [1, 32], 85: [1, 34], 86: 33 }, { 4: 45, 6: 3, 14: [2, 46], 15: [2, 46], 19: [2, 46], 29: [2, 46], 34: [2, 46], 47: [2, 46], 48: [2, 46], 51: [2, 46], 55: [2, 46], 60: [2, 46] }, { 5: [2, 10], 14: [2, 10], 15: [2, 10], 18: [2, 10], 19: [2, 10], 29: [2, 10], 34: [2, 10], 39: [2, 10], 44: [2, 10], 47: [2, 10], 48: [2, 10], 51: [2, 10], 55: [2, 10], 60: [2, 10] }, { 20: 46, 72: [1, 35], 78: 26, 79: 27, 80: [1, 28], 81: [1, 29], 82: [1, 30], 83: [1, 31], 84: [1, 32], 85: [1, 34], 86: 33 }, { 20: 47, 72: [1, 35], 78: 26, 79: 27, 80: [1, 28], 81: [1, 29], 82: [1, 30], 83: [1, 31], 84: [1, 32], 85: [1, 34], 86: 33 }, { 20: 48, 72: [1, 35], 78: 26, 79: 27, 80: [1, 28], 81: [1, 29], 82: [1, 30], 83: [1, 31], 84: [1, 32], 85: [1, 34], 86: 33 }, { 20: 42, 56: 49, 64: 43, 65: [1, 44], 72: [1, 35], 78: 26, 79: 27, 80: [1, 28], 81: [1, 29], 82: [1, 30], 83: [1, 31], 84: [1, 32], 85: [1, 34], 86: 33 }, { 33: [2, 78], 49: 50, 65: [2, 78], 72: [2, 78], 80: [2, 78], 81: [2, 78], 82: [2, 78], 83: [2, 78], 84: [2, 78], 85: [2, 78] }, { 23: [2, 33], 33: [2, 33], 54: [2, 33], 65: [2, 33], 68: [2, 33], 72: [2, 33], 75: [2, 33], 80: [2, 33], 81: [2, 33], 82: [2, 33], 83: [2, 33], 84: [2, 33], 85: [2, 33] }, { 23: [2, 34], 33: [2, 34], 54: [2, 34], 65: [2, 34], 68: [2, 34], 72: [2, 34], 75: [2, 34], 80: [2, 34], 81: [2, 34], 82: [2, 34], 83: [2, 34], 84: [2, 34], 85: [2, 34] }, { 23: [2, 35], 33: [2, 35], 54: [2, 35], 65: [2, 35], 68: [2, 35], 72: [2, 35], 75: [2, 35], 80: [2, 35], 81: [2, 35], 82: [2, 35], 83: [2, 35], 84: [2, 35], 85: [2, 35] }, { 23: [2, 36], 33: [2, 36], 54: [2, 36], 65: [2, 36], 68: [2, 36], 72: [2, 36], 75: [2, 36], 80: [2, 36], 81: [2, 36], 82: [2, 36], 83: [2, 36], 84: [2, 36], 85: [2, 36] }, { 23: [2, 37], 33: [2, 37], 54: [2, 37], 65: [2, 37], 68: [2, 37], 72: [2, 37], 75: [2, 37], 80: [2, 37], 81: [2, 37], 82: [2, 37], 83: [2, 37], 84: [2, 37], 85: [2, 37] }, { 23: [2, 38], 33: [2, 38], 54: [2, 38], 65: [2, 38], 68: [2, 38], 72: [2, 38], 75: [2, 38], 80: [2, 38], 81: [2, 38], 82: [2, 38], 83: [2, 38], 84: [2, 38], 85: [2, 38] }, { 23: [2, 39], 33: [2, 39], 54: [2, 39], 65: [2, 39], 68: [2, 39], 72: [2, 39], 75: [2, 39], 80: [2, 39], 81: [2, 39], 82: [2, 39], 83: [2, 39], 84: [2, 39], 85: [2, 39] }, { 23: [2, 43], 33: [2, 43], 54: [2, 43], 65: [2, 43], 68: [2, 43], 72: [2, 43], 75: [2, 43], 80: [2, 43], 81: [2, 43], 82: [2, 43], 83: [2, 43], 84: [2, 43], 85: [2, 43], 87: [1, 51] }, { 72: [1, 35], 86: 52 }, { 23: [2, 45], 33: [2, 45], 54: [2, 45], 65: [2, 45], 68: [2, 45], 72: [2, 45], 75: [2, 45], 80: [2, 45], 81: [2, 45], 82: [2, 45], 83: [2, 45], 84: [2, 45], 85: [2, 45], 87: [2, 45] }, { 52: 53, 54: [2, 82], 65: [2, 82], 72: [2, 82], 80: [2, 82], 81: [2, 82], 82: [2, 82], 83: [2, 82], 84: [2, 82], 85: [2, 82] }, { 25: 54, 38: 56, 39: [1, 58], 43: 57, 44: [1, 59], 45: 55, 47: [2, 54] }, { 28: 60, 43: 61, 44: [1, 59], 47: [2, 56] }, { 13: 63, 15: [1, 20], 18: [1, 62] }, { 15: [2, 48], 18: [2, 48] }, { 33: [2, 86], 57: 64, 65: [2, 86], 72: [2, 86], 80: [2, 86], 81: [2, 86], 82: [2, 86], 83: [2, 86], 84: [2, 86], 85: [2, 86] }, { 33: [2, 40], 65: [2, 40], 72: [2, 40], 80: [2, 40], 81: [2, 40], 82: [2, 40], 83: [2, 40], 84: [2, 40], 85: [2, 40] }, { 33: [2, 41], 65: [2, 41], 72: [2, 41], 80: [2, 41], 81: [2, 41], 82: [2, 41], 83: [2, 41], 84: [2, 41], 85: [2, 41] }, { 20: 65, 72: [1, 35], 78: 26, 79: 27, 80: [1, 28], 81: [1, 29], 82: [1, 30], 83: [1, 31], 84: [1, 32], 85: [1, 34], 86: 33 }, { 26: 66, 47: [1, 67] }, { 30: 68, 33: [2, 58], 65: [2, 58], 72: [2, 58], 75: [2, 58], 80: [2, 58], 81: [2, 58], 82: [2, 58], 83: [2, 58], 84: [2, 58], 85: [2, 58] }, { 33: [2, 64], 35: 69, 65: [2, 64], 72: [2, 64], 75: [2, 64], 80: [2, 64], 81: [2, 64], 82: [2, 64], 83: [2, 64], 84: [2, 64], 85: [2, 64] }, { 21: 70, 23: [2, 50], 65: [2, 50], 72: [2, 50], 80: [2, 50], 81: [2, 50], 82: [2, 50], 83: [2, 50], 84: [2, 50], 85: [2, 50] }, { 33: [2, 90], 61: 71, 65: [2, 90], 72: [2, 90], 80: [2, 90], 81: [2, 90], 82: [2, 90], 83: [2, 90], 84: [2, 90], 85: [2, 90] }, { 20: 75, 33: [2, 80], 50: 72, 63: 73, 64: 76, 65: [1, 44], 69: 74, 70: 77, 71: 78, 72: [1, 79], 78: 26, 79: 27, 80: [1, 28], 81: [1, 29], 82: [1, 30], 83: [1, 31], 84: [1, 32], 85: [1, 34], 86: 33 }, { 72: [1, 80] }, { 23: [2, 42], 33: [2, 42], 54: [2, 42], 65: [2, 42], 68: [2, 42], 72: [2, 42], 75: [2, 42], 80: [2, 42], 81: [2, 42], 82: [2, 42], 83: [2, 42], 84: [2, 42], 85: [2, 42], 87: [1, 51] }, { 20: 75, 53: 81, 54: [2, 84], 63: 82, 64: 76, 65: [1, 44], 69: 83, 70: 77, 71: 78, 72: [1, 79], 78: 26, 79: 27, 80: [1, 28], 81: [1, 29], 82: [1, 30], 83: [1, 31], 84: [1, 32], 85: [1, 34], 86: 33 }, { 26: 84, 47: [1, 67] }, { 47: [2, 55] }, { 4: 85, 6: 3, 14: [2, 46], 15: [2, 46], 19: [2, 46], 29: [2, 46], 34: [2, 46], 39: [2, 46], 44: [2, 46], 47: [2, 46], 48: [2, 46], 51: [2, 46], 55: [2, 46], 60: [2, 46] }, { 47: [2, 20] }, { 20: 86, 72: [1, 35], 78: 26, 79: 27, 80: [1, 28], 81: [1, 29], 82: [1, 30], 83: [1, 31], 84: [1, 32], 85: [1, 34], 86: 33 }, { 4: 87, 6: 3, 14: [2, 46], 15: [2, 46], 19: [2, 46], 29: [2, 46], 34: [2, 46], 47: [2, 46], 48: [2, 46], 51: [2, 46], 55: [2, 46], 60: [2, 46] }, { 26: 88, 47: [1, 67] }, { 47: [2, 57] }, { 5: [2, 11], 14: [2, 11], 15: [2, 11], 19: [2, 11], 29: [2, 11], 34: [2, 11], 39: [2, 11], 44: [2, 11], 47: [2, 11], 48: [2, 11], 51: [2, 11], 55: [2, 11], 60: [2, 11] }, { 15: [2, 49], 18: [2, 49] }, { 20: 75, 33: [2, 88], 58: 89, 63: 90, 64: 76, 65: [1, 44], 69: 91, 70: 77, 71: 78, 72: [1, 79], 78: 26, 79: 27, 80: [1, 28], 81: [1, 29], 82: [1, 30], 83: [1, 31], 84: [1, 32], 85: [1, 34], 86: 33 }, { 65: [2, 94], 66: 92, 68: [2, 94], 72: [2, 94], 80: [2, 94], 81: [2, 94], 82: [2, 94], 83: [2, 94], 84: [2, 94], 85: [2, 94] }, { 5: [2, 25], 14: [2, 25], 15: [2, 25], 19: [2, 25], 29: [2, 25], 34: [2, 25], 39: [2, 25], 44: [2, 25], 47: [2, 25], 48: [2, 25], 51: [2, 25], 55: [2, 25], 60: [2, 25] }, { 20: 93, 72: [1, 35], 78: 26, 79: 27, 80: [1, 28], 81: [1, 29], 82: [1, 30], 83: [1, 31], 84: [1, 32], 85: [1, 34], 86: 33 }, { 20: 75, 31: 94, 33: [2, 60], 63: 95, 64: 76, 65: [1, 44], 69: 96, 70: 77, 71: 78, 72: [1, 79], 75: [2, 60], 78: 26, 79: 27, 80: [1, 28], 81: [1, 29], 82: [1, 30], 83: [1, 31], 84: [1, 32], 85: [1, 34], 86: 33 }, { 20: 75, 33: [2, 66], 36: 97, 63: 98, 64: 76, 65: [1, 44], 69: 99, 70: 77, 71: 78, 72: [1, 79], 75: [2, 66], 78: 26, 79: 27, 80: [1, 28], 81: [1, 29], 82: [1, 30], 83: [1, 31], 84: [1, 32], 85: [1, 34], 86: 33 }, { 20: 75, 22: 100, 23: [2, 52], 63: 101, 64: 76, 65: [1, 44], 69: 102, 70: 77, 71: 78, 72: [1, 79], 78: 26, 79: 27, 80: [1, 28], 81: [1, 29], 82: [1, 30], 83: [1, 31], 84: [1, 32], 85: [1, 34], 86: 33 }, { 20: 75, 33: [2, 92], 62: 103, 63: 104, 64: 76, 65: [1, 44], 69: 105, 70: 77, 71: 78, 72: [1, 79], 78: 26, 79: 27, 80: [1, 28], 81: [1, 29], 82: [1, 30], 83: [1, 31], 84: [1, 32], 85: [1, 34], 86: 33 }, { 33: [1, 106] }, { 33: [2, 79], 65: [2, 79], 72: [2, 79], 80: [2, 79], 81: [2, 79], 82: [2, 79], 83: [2, 79], 84: [2, 79], 85: [2, 79] }, { 33: [2, 81] }, { 23: [2, 27], 33: [2, 27], 54: [2, 27], 65: [2, 27], 68: [2, 27], 72: [2, 27], 75: [2, 27], 80: [2, 27], 81: [2, 27], 82: [2, 27], 83: [2, 27], 84: [2, 27], 85: [2, 27] }, { 23: [2, 28], 33: [2, 28], 54: [2, 28], 65: [2, 28], 68: [2, 28], 72: [2, 28], 75: [2, 28], 80: [2, 28], 81: [2, 28], 82: [2, 28], 83: [2, 28], 84: [2, 28], 85: [2, 28] }, { 23: [2, 30], 33: [2, 30], 54: [2, 30], 68: [2, 30], 71: 107, 72: [1, 108], 75: [2, 30] }, { 23: [2, 98], 33: [2, 98], 54: [2, 98], 68: [2, 98], 72: [2, 98], 75: [2, 98] }, { 23: [2, 45], 33: [2, 45], 54: [2, 45], 65: [2, 45], 68: [2, 45], 72: [2, 45], 73: [1, 109], 75: [2, 45], 80: [2, 45], 81: [2, 45], 82: [2, 45], 83: [2, 45], 84: [2, 45], 85: [2, 45], 87: [2, 45] }, { 23: [2, 44], 33: [2, 44], 54: [2, 44], 65: [2, 44], 68: [2, 44], 72: [2, 44], 75: [2, 44], 80: [2, 44], 81: [2, 44], 82: [2, 44], 83: [2, 44], 84: [2, 44], 85: [2, 44], 87: [2, 44] }, { 54: [1, 110] }, { 54: [2, 83], 65: [2, 83], 72: [2, 83], 80: [2, 83], 81: [2, 83], 82: [2, 83], 83: [2, 83], 84: [2, 83], 85: [2, 83] }, { 54: [2, 85] }, { 5: [2, 13], 14: [2, 13], 15: [2, 13], 19: [2, 13], 29: [2, 13], 34: [2, 13], 39: [2, 13], 44: [2, 13], 47: [2, 13], 48: [2, 13], 51: [2, 13], 55: [2, 13], 60: [2, 13] }, { 38: 56, 39: [1, 58], 43: 57, 44: [1, 59], 45: 112, 46: 111, 47: [2, 76] }, { 33: [2, 70], 40: 113, 65: [2, 70], 72: [2, 70], 75: [2, 70], 80: [2, 70], 81: [2, 70], 82: [2, 70], 83: [2, 70], 84: [2, 70], 85: [2, 70] }, { 47: [2, 18] }, { 5: [2, 14], 14: [2, 14], 15: [2, 14], 19: [2, 14], 29: [2, 14], 34: [2, 14], 39: [2, 14], 44: [2, 14], 47: [2, 14], 48: [2, 14], 51: [2, 14], 55: [2, 14], 60: [2, 14] }, { 33: [1, 114] }, { 33: [2, 87], 65: [2, 87], 72: [2, 87], 80: [2, 87], 81: [2, 87], 82: [2, 87], 83: [2, 87], 84: [2, 87], 85: [2, 87] }, { 33: [2, 89] }, { 20: 75, 63: 116, 64: 76, 65: [1, 44], 67: 115, 68: [2, 96], 69: 117, 70: 77, 71: 78, 72: [1, 79], 78: 26, 79: 27, 80: [1, 28], 81: [1, 29], 82: [1, 30], 83: [1, 31], 84: [1, 32], 85: [1, 34], 86: 33 }, { 33: [1, 118] }, { 32: 119, 33: [2, 62], 74: 120, 75: [1, 121] }, { 33: [2, 59], 65: [2, 59], 72: [2, 59], 75: [2, 59], 80: [2, 59], 81: [2, 59], 82: [2, 59], 83: [2, 59], 84: [2, 59], 85: [2, 59] }, { 33: [2, 61], 75: [2, 61] }, { 33: [2, 68], 37: 122, 74: 123, 75: [1, 121] }, { 33: [2, 65], 65: [2, 65], 72: [2, 65], 75: [2, 65], 80: [2, 65], 81: [2, 65], 82: [2, 65], 83: [2, 65], 84: [2, 65], 85: [2, 65] }, { 33: [2, 67], 75: [2, 67] }, { 23: [1, 124] }, { 23: [2, 51], 65: [2, 51], 72: [2, 51], 80: [2, 51], 81: [2, 51], 82: [2, 51], 83: [2, 51], 84: [2, 51], 85: [2, 51] }, { 23: [2, 53] }, { 33: [1, 125] }, { 33: [2, 91], 65: [2, 91], 72: [2, 91], 80: [2, 91], 81: [2, 91], 82: [2, 91], 83: [2, 91], 84: [2, 91], 85: [2, 91] }, { 33: [2, 93] }, { 5: [2, 22], 14: [2, 22], 15: [2, 22], 19: [2, 22], 29: [2, 22], 34: [2, 22], 39: [2, 22], 44: [2, 22], 47: [2, 22], 48: [2, 22], 51: [2, 22], 55: [2, 22], 60: [2, 22] }, { 23: [2, 99], 33: [2, 99], 54: [2, 99], 68: [2, 99], 72: [2, 99], 75: [2, 99] }, { 73: [1, 109] }, { 20: 75, 63: 126, 64: 76, 65: [1, 44], 72: [1, 35], 78: 26, 79: 27, 80: [1, 28], 81: [1, 29], 82: [1, 30], 83: [1, 31], 84: [1, 32], 85: [1, 34], 86: 33 }, { 5: [2, 23], 14: [2, 23], 15: [2, 23], 19: [2, 23], 29: [2, 23], 34: [2, 23], 39: [2, 23], 44: [2, 23], 47: [2, 23], 48: [2, 23], 51: [2, 23], 55: [2, 23], 60: [2, 23] }, { 47: [2, 19] }, { 47: [2, 77] }, { 20: 75, 33: [2, 72], 41: 127, 63: 128, 64: 76, 65: [1, 44], 69: 129, 70: 77, 71: 78, 72: [1, 79], 75: [2, 72], 78: 26, 79: 27, 80: [1, 28], 81: [1, 29], 82: [1, 30], 83: [1, 31], 84: [1, 32], 85: [1, 34], 86: 33 }, { 5: [2, 24], 14: [2, 24], 15: [2, 24], 19: [2, 24], 29: [2, 24], 34: [2, 24], 39: [2, 24], 44: [2, 24], 47: [2, 24], 48: [2, 24], 51: [2, 24], 55: [2, 24], 60: [2, 24] }, { 68: [1, 130] }, { 65: [2, 95], 68: [2, 95], 72: [2, 95], 80: [2, 95], 81: [2, 95], 82: [2, 95], 83: [2, 95], 84: [2, 95], 85: [2, 95] }, { 68: [2, 97] }, { 5: [2, 21], 14: [2, 21], 15: [2, 21], 19: [2, 21], 29: [2, 21], 34: [2, 21], 39: [2, 21], 44: [2, 21], 47: [2, 21], 48: [2, 21], 51: [2, 21], 55: [2, 21], 60: [2, 21] }, { 33: [1, 131] }, { 33: [2, 63] }, { 72: [1, 133], 76: 132 }, { 33: [1, 134] }, { 33: [2, 69] }, { 15: [2, 12] }, { 14: [2, 26], 15: [2, 26], 19: [2, 26], 29: [2, 26], 34: [2, 26], 47: [2, 26], 48: [2, 26], 51: [2, 26], 55: [2, 26], 60: [2, 26] }, { 23: [2, 31], 33: [2, 31], 54: [2, 31], 68: [2, 31], 72: [2, 31], 75: [2, 31] }, { 33: [2, 74], 42: 135, 74: 136, 75: [1, 121] }, { 33: [2, 71], 65: [2, 71], 72: [2, 71], 75: [2, 71], 80: [2, 71], 81: [2, 71], 82: [2, 71], 83: [2, 71], 84: [2, 71], 85: [2, 71] }, { 33: [2, 73], 75: [2, 73] }, { 23: [2, 29], 33: [2, 29], 54: [2, 29], 65: [2, 29], 68: [2, 29], 72: [2, 29], 75: [2, 29], 80: [2, 29], 81: [2, 29], 82: [2, 29], 83: [2, 29], 84: [2, 29], 85: [2, 29] }, { 14: [2, 15], 15: [2, 15], 19: [2, 15], 29: [2, 15], 34: [2, 15], 39: [2, 15], 44: [2, 15], 47: [2, 15], 48: [2, 15], 51: [2, 15], 55: [2, 15], 60: [2, 15] }, { 72: [1, 138], 77: [1, 137] }, { 72: [2, 100], 77: [2, 100] }, { 14: [2, 16], 15: [2, 16], 19: [2, 16], 29: [2, 16], 34: [2, 16], 44: [2, 16], 47: [2, 16], 48: [2, 16], 51: [2, 16], 55: [2, 16], 60: [2, 16] }, { 33: [1, 139] }, { 33: [2, 75] }, { 33: [2, 32] }, { 72: [2, 101], 77: [2, 101] }, { 14: [2, 17], 15: [2, 17], 19: [2, 17], 29: [2, 17], 34: [2, 17], 39: [2, 17], 44: [2, 17], 47: [2, 17], 48: [2, 17], 51: [2, 17], 55: [2, 17], 60: [2, 17] }],
+ defaultActions: { 4: [2, 1], 55: [2, 55], 57: [2, 20], 61: [2, 57], 74: [2, 81], 83: [2, 85], 87: [2, 18], 91: [2, 89], 102: [2, 53], 105: [2, 93], 111: [2, 19], 112: [2, 77], 117: [2, 97], 120: [2, 63], 123: [2, 69], 124: [2, 12], 136: [2, 75], 137: [2, 32] },
+ parseError: function parseError(str, hash) {
+ throw new Error(str);
+ },
+ parse: function parse(input) {
+ var self = this,
+ stack = [0],
+ vstack = [null],
+ lstack = [],
+ table = this.table,
+ yytext = "",
+ yylineno = 0,
+ yyleng = 0,
+ recovering = 0,
+ TERROR = 2,
+ EOF = 1;
+ this.lexer.setInput(input);
+ this.lexer.yy = this.yy;
+ this.yy.lexer = this.lexer;
+ this.yy.parser = this;
+ if (typeof this.lexer.yylloc == "undefined") this.lexer.yylloc = {};
+ var yyloc = this.lexer.yylloc;
+ lstack.push(yyloc);
+ var ranges = this.lexer.options && this.lexer.options.ranges;
+ if (typeof this.yy.parseError === "function") this.parseError = this.yy.parseError;
+ function popStack(n) {
+ stack.length = stack.length - 2 * n;
+ vstack.length = vstack.length - n;
+ lstack.length = lstack.length - n;
+ }
+ function lex() {
+ var token;
+ token = self.lexer.lex() || 1;
+ if (typeof token !== "number") {
+ token = self.symbols_[token] || token;
+ }
+ return token;
+ }
+ var symbol,
+ preErrorSymbol,
+ state,
+ action,
+ a,
+ r,
+ yyval = {},
+ p,
+ len,
+ newState,
+ expected;
+ while (true) {
+ state = stack[stack.length - 1];
+ if (this.defaultActions[state]) {
+ action = this.defaultActions[state];
+ } else {
+ if (symbol === null || typeof symbol == "undefined") {
+ symbol = lex();
+ }
+ action = table[state] && table[state][symbol];
+ }
+ if (typeof action === "undefined" || !action.length || !action[0]) {
+ var errStr = "";
+ if (!recovering) {
+ expected = [];
+ for (p in table[state]) if (this.terminals_[p] && p > 2) {
+ expected.push("'" + this.terminals_[p] + "'");
+ }
+ if (this.lexer.showPosition) {
+ errStr = "Parse error on line " + (yylineno + 1) + ":\n" + this.lexer.showPosition() + "\nExpecting " + expected.join(", ") + ", got '" + (this.terminals_[symbol] || symbol) + "'";
+ } else {
+ errStr = "Parse error on line " + (yylineno + 1) + ": Unexpected " + (symbol == 1 ? "end of input" : "'" + (this.terminals_[symbol] || symbol) + "'");
+ }
+ this.parseError(errStr, { text: this.lexer.match, token: this.terminals_[symbol] || symbol, line: this.lexer.yylineno, loc: yyloc, expected: expected });
+ }
+ }
+ if (action[0] instanceof Array && action.length > 1) {
+ throw new Error("Parse Error: multiple actions possible at state: " + state + ", token: " + symbol);
+ }
+ switch (action[0]) {
+ case 1:
+ stack.push(symbol);
+ vstack.push(this.lexer.yytext);
+ lstack.push(this.lexer.yylloc);
+ stack.push(action[1]);
+ symbol = null;
+ if (!preErrorSymbol) {
+ yyleng = this.lexer.yyleng;
+ yytext = this.lexer.yytext;
+ yylineno = this.lexer.yylineno;
+ yyloc = this.lexer.yylloc;
+ if (recovering > 0) recovering--;
+ } else {
+ symbol = preErrorSymbol;
+ preErrorSymbol = null;
+ }
+ break;
+ case 2:
+ len = this.productions_[action[1]][1];
+ yyval.$ = vstack[vstack.length - len];
+ yyval._$ = { first_line: lstack[lstack.length - (len || 1)].first_line, last_line: lstack[lstack.length - 1].last_line, first_column: lstack[lstack.length - (len || 1)].first_column, last_column: lstack[lstack.length - 1].last_column };
+ if (ranges) {
+ yyval._$.range = [lstack[lstack.length - (len || 1)].range[0], lstack[lstack.length - 1].range[1]];
+ }
+ r = this.performAction.call(yyval, yytext, yyleng, yylineno, this.yy, action[1], vstack, lstack);
+ if (typeof r !== "undefined") {
+ return r;
+ }
+ if (len) {
+ stack = stack.slice(0, -1 * len * 2);
+ vstack = vstack.slice(0, -1 * len);
+ lstack = lstack.slice(0, -1 * len);
+ }
+ stack.push(this.productions_[action[1]][0]);
+ vstack.push(yyval.$);
+ lstack.push(yyval._$);
+ newState = table[stack[stack.length - 2]][stack[stack.length - 1]];
+ stack.push(newState);
+ break;
+ case 3:
+ return true;
+ }
+ }
+ return true;
+ }
+ };
+ /* Jison generated lexer */
+ var lexer = (function () {
+ var lexer = { EOF: 1,
+ parseError: function parseError(str, hash) {
+ if (this.yy.parser) {
+ this.yy.parser.parseError(str, hash);
+ } else {
+ throw new Error(str);
+ }
+ },
+ setInput: function setInput(input) {
+ this._input = input;
+ this._more = this._less = this.done = false;
+ this.yylineno = this.yyleng = 0;
+ this.yytext = this.matched = this.match = '';
+ this.conditionStack = ['INITIAL'];
+ this.yylloc = { first_line: 1, first_column: 0, last_line: 1, last_column: 0 };
+ if (this.options.ranges) this.yylloc.range = [0, 0];
+ this.offset = 0;
+ return this;
+ },
+ input: function input() {
+ var ch = this._input[0];
+ this.yytext += ch;
+ this.yyleng++;
+ this.offset++;
+ this.match += ch;
+ this.matched += ch;
+ var lines = ch.match(/(?:\r\n?|\n).*/g);
+ if (lines) {
+ this.yylineno++;
+ this.yylloc.last_line++;
+ } else {
+ this.yylloc.last_column++;
+ }
+ if (this.options.ranges) this.yylloc.range[1]++;
+
+ this._input = this._input.slice(1);
+ return ch;
+ },
+ unput: function unput(ch) {
+ var len = ch.length;
+ var lines = ch.split(/(?:\r\n?|\n)/g);
+
+ this._input = ch + this._input;
+ this.yytext = this.yytext.substr(0, this.yytext.length - len - 1);
+ //this.yyleng -= len;
+ this.offset -= len;
+ var oldLines = this.match.split(/(?:\r\n?|\n)/g);
+ this.match = this.match.substr(0, this.match.length - 1);
+ this.matched = this.matched.substr(0, this.matched.length - 1);
+
+ if (lines.length - 1) this.yylineno -= lines.length - 1;
+ var r = this.yylloc.range;
+
+ this.yylloc = { first_line: this.yylloc.first_line,
+ last_line: this.yylineno + 1,
+ first_column: this.yylloc.first_column,
+ last_column: lines ? (lines.length === oldLines.length ? this.yylloc.first_column : 0) + oldLines[oldLines.length - lines.length].length - lines[0].length : this.yylloc.first_column - len
+ };
+
+ if (this.options.ranges) {
+ this.yylloc.range = [r[0], r[0] + this.yyleng - len];
+ }
+ return this;
+ },
+ more: function more() {
+ this._more = true;
+ return this;
+ },
+ less: function less(n) {
+ this.unput(this.match.slice(n));
+ },
+ pastInput: function pastInput() {
+ var past = this.matched.substr(0, this.matched.length - this.match.length);
+ return (past.length > 20 ? '...' : '') + past.substr(-20).replace(/\n/g, "");
+ },
+ upcomingInput: function upcomingInput() {
+ var next = this.match;
+ if (next.length < 20) {
+ next += this._input.substr(0, 20 - next.length);
+ }
+ return (next.substr(0, 20) + (next.length > 20 ? '...' : '')).replace(/\n/g, "");
+ },
+ showPosition: function showPosition() {
+ var pre = this.pastInput();
+ var c = new Array(pre.length + 1).join("-");
+ return pre + this.upcomingInput() + "\n" + c + "^";
+ },
+ next: function next() {
+ if (this.done) {
+ return this.EOF;
+ }
+ if (!this._input) this.done = true;
+
+ var token, match, tempMatch, index, col, lines;
+ if (!this._more) {
+ this.yytext = '';
+ this.match = '';
+ }
+ var rules = this._currentRules();
+ for (var i = 0; i < rules.length; i++) {
+ tempMatch = this._input.match(this.rules[rules[i]]);
+ if (tempMatch && (!match || tempMatch[0].length > match[0].length)) {
+ match = tempMatch;
+ index = i;
+ if (!this.options.flex) break;
+ }
+ }
+ if (match) {
+ lines = match[0].match(/(?:\r\n?|\n).*/g);
+ if (lines) this.yylineno += lines.length;
+ this.yylloc = { first_line: this.yylloc.last_line,
+ last_line: this.yylineno + 1,
+ first_column: this.yylloc.last_column,
+ last_column: lines ? lines[lines.length - 1].length - lines[lines.length - 1].match(/\r?\n?/)[0].length : this.yylloc.last_column + match[0].length };
+ this.yytext += match[0];
+ this.match += match[0];
+ this.matches = match;
+ this.yyleng = this.yytext.length;
+ if (this.options.ranges) {
+ this.yylloc.range = [this.offset, this.offset += this.yyleng];
+ }
+ this._more = false;
+ this._input = this._input.slice(match[0].length);
+ this.matched += match[0];
+ token = this.performAction.call(this, this.yy, this, rules[index], this.conditionStack[this.conditionStack.length - 1]);
+ if (this.done && this._input) this.done = false;
+ if (token) return token;else return;
+ }
+ if (this._input === "") {
+ return this.EOF;
+ } else {
+ return this.parseError('Lexical error on line ' + (this.yylineno + 1) + '. Unrecognized text.\n' + this.showPosition(), { text: "", token: null, line: this.yylineno });
+ }
+ },
+ lex: function lex() {
+ var r = this.next();
+ if (typeof r !== 'undefined') {
+ return r;
+ } else {
+ return this.lex();
+ }
+ },
+ begin: function begin(condition) {
+ this.conditionStack.push(condition);
+ },
+ popState: function popState() {
+ return this.conditionStack.pop();
+ },
+ _currentRules: function _currentRules() {
+ return this.conditions[this.conditionStack[this.conditionStack.length - 1]].rules;
+ },
+ topState: function topState() {
+ return this.conditionStack[this.conditionStack.length - 2];
+ },
+ pushState: function begin(condition) {
+ this.begin(condition);
+ } };
+ lexer.options = {};
+ lexer.performAction = function anonymous(yy, yy_, $avoiding_name_collisions, YY_START
+ /**/) {
+
+ function strip(start, end) {
+ return yy_.yytext = yy_.yytext.substr(start, yy_.yyleng - end);
+ }
+
+ var YYSTATE = YY_START;
+ switch ($avoiding_name_collisions) {
+ case 0:
+ if (yy_.yytext.slice(-2) === "\\\\") {
+ strip(0, 1);
+ this.begin("mu");
+ } else if (yy_.yytext.slice(-1) === "\\") {
+ strip(0, 1);
+ this.begin("emu");
+ } else {
+ this.begin("mu");
+ }
+ if (yy_.yytext) return 15;
+
+ break;
+ case 1:
+ return 15;
+ break;
+ case 2:
+ this.popState();
+ return 15;
+
+ break;
+ case 3:
+ this.begin('raw');return 15;
+ break;
+ case 4:
+ this.popState();
+ // Should be using `this.topState()` below, but it currently
+ // returns the second top instead of the first top. Opened an
+ // issue about it at https://github.com/zaach/jison/issues/291
+ if (this.conditionStack[this.conditionStack.length - 1] === 'raw') {
+ return 15;
+ } else {
+ yy_.yytext = yy_.yytext.substr(5, yy_.yyleng - 9);
+ return 'END_RAW_BLOCK';
+ }
+
+ break;
+ case 5:
+ return 15;
+ break;
+ case 6:
+ this.popState();
+ return 14;
+
+ break;
+ case 7:
+ return 65;
+ break;
+ case 8:
+ return 68;
+ break;
+ case 9:
+ return 19;
+ break;
+ case 10:
+ this.popState();
+ this.begin('raw');
+ return 23;
+
+ break;
+ case 11:
+ return 55;
+ break;
+ case 12:
+ return 60;
+ break;
+ case 13:
+ return 29;
+ break;
+ case 14:
+ return 47;
+ break;
+ case 15:
+ this.popState();return 44;
+ break;
+ case 16:
+ this.popState();return 44;
+ break;
+ case 17:
+ return 34;
+ break;
+ case 18:
+ return 39;
+ break;
+ case 19:
+ return 51;
+ break;
+ case 20:
+ return 48;
+ break;
+ case 21:
+ this.unput(yy_.yytext);
+ this.popState();
+ this.begin('com');
+
+ break;
+ case 22:
+ this.popState();
+ return 14;
+
+ break;
+ case 23:
+ return 48;
+ break;
+ case 24:
+ return 73;
+ break;
+ case 25:
+ return 72;
+ break;
+ case 26:
+ return 72;
+ break;
+ case 27:
+ return 87;
+ break;
+ case 28:
+ // ignore whitespace
+ break;
+ case 29:
+ this.popState();return 54;
+ break;
+ case 30:
+ this.popState();return 33;
+ break;
+ case 31:
+ yy_.yytext = strip(1, 2).replace(/\\"/g, '"');return 80;
+ break;
+ case 32:
+ yy_.yytext = strip(1, 2).replace(/\\'/g, "'");return 80;
+ break;
+ case 33:
+ return 85;
+ break;
+ case 34:
+ return 82;
+ break;
+ case 35:
+ return 82;
+ break;
+ case 36:
+ return 83;
+ break;
+ case 37:
+ return 84;
+ break;
+ case 38:
+ return 81;
+ break;
+ case 39:
+ return 75;
+ break;
+ case 40:
+ return 77;
+ break;
+ case 41:
+ return 72;
+ break;
+ case 42:
+ yy_.yytext = yy_.yytext.replace(/\\([\\\]])/g, '$1');return 72;
+ break;
+ case 43:
+ return 'INVALID';
+ break;
+ case 44:
+ return 5;
+ break;
+ }
+ };
+ lexer.rules = [/^(?:[^\x00]*?(?=(\{\{)))/, /^(?:[^\x00]+)/, /^(?:[^\x00]{2,}?(?=(\{\{|\\\{\{|\\\\\{\{|$)))/, /^(?:\{\{\{\{(?=[^\/]))/, /^(?:\{\{\{\{\/[^\s!"#%-,\.\/;->@\[-\^`\{-~]+(?=[=}\s\/.])\}\}\}\})/, /^(?:[^\x00]*?(?=(\{\{\{\{)))/, /^(?:[\s\S]*?--(~)?\}\})/, /^(?:\()/, /^(?:\))/, /^(?:\{\{\{\{)/, /^(?:\}\}\}\})/, /^(?:\{\{(~)?>)/, /^(?:\{\{(~)?#>)/, /^(?:\{\{(~)?#\*?)/, /^(?:\{\{(~)?\/)/, /^(?:\{\{(~)?\^\s*(~)?\}\})/, /^(?:\{\{(~)?\s*else\s*(~)?\}\})/, /^(?:\{\{(~)?\^)/, /^(?:\{\{(~)?\s*else\b)/, /^(?:\{\{(~)?\{)/, /^(?:\{\{(~)?&)/, /^(?:\{\{(~)?!--)/, /^(?:\{\{(~)?![\s\S]*?\}\})/, /^(?:\{\{(~)?\*?)/, /^(?:=)/, /^(?:\.\.)/, /^(?:\.(?=([=~}\s\/.)|])))/, /^(?:[\/.])/, /^(?:\s+)/, /^(?:\}(~)?\}\})/, /^(?:(~)?\}\})/, /^(?:"(\\["]|[^"])*")/, /^(?:'(\\[']|[^'])*')/, /^(?:@)/, /^(?:true(?=([~}\s)])))/, /^(?:false(?=([~}\s)])))/, /^(?:undefined(?=([~}\s)])))/, /^(?:null(?=([~}\s)])))/, /^(?:-?[0-9]+(?:\.[0-9]+)?(?=([~}\s)])))/, /^(?:as\s+\|)/, /^(?:\|)/, /^(?:([^\s!"#%-,\.\/;->@\[-\^`\{-~]+(?=([=~}\s\/.)|]))))/, /^(?:\[(\\\]|[^\]])*\])/, /^(?:.)/, /^(?:$)/];
+ lexer.conditions = { "mu": { "rules": [7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44], "inclusive": false }, "emu": { "rules": [2], "inclusive": false }, "com": { "rules": [6], "inclusive": false }, "raw": { "rules": [3, 4, 5], "inclusive": false }, "INITIAL": { "rules": [0, 1, 44], "inclusive": true } };
+ return lexer;
+ })();
+ parser.lexer = lexer;
+ function Parser() {
+ this.yy = {};
+ }Parser.prototype = parser;parser.Parser = Parser;
+ return new Parser();
+ })();exports.__esModule = true;
+ exports['default'] = handlebars;
+
+/***/ },
+/* 24 */
+/***/ function(module, exports, __webpack_require__) {
+
+ 'use strict';
+
+ var _interopRequireDefault = __webpack_require__(1)['default'];
+
+ exports.__esModule = true;
+
+ var _visitor = __webpack_require__(25);
+
+ var _visitor2 = _interopRequireDefault(_visitor);
+
+ function WhitespaceControl() {
+ var options = arguments.length <= 0 || arguments[0] === undefined ? {} : arguments[0];
+
+ this.options = options;
+ }
+ WhitespaceControl.prototype = new _visitor2['default']();
+
+ WhitespaceControl.prototype.Program = function (program) {
+ var doStandalone = !this.options.ignoreStandalone;
+
+ var isRoot = !this.isRootSeen;
+ this.isRootSeen = true;
+
+ var body = program.body;
+ for (var i = 0, l = body.length; i < l; i++) {
+ var current = body[i],
+ strip = this.accept(current);
+
+ if (!strip) {
+ continue;
+ }
+
+ var _isPrevWhitespace = isPrevWhitespace(body, i, isRoot),
+ _isNextWhitespace = isNextWhitespace(body, i, isRoot),
+ openStandalone = strip.openStandalone && _isPrevWhitespace,
+ closeStandalone = strip.closeStandalone && _isNextWhitespace,
+ inlineStandalone = strip.inlineStandalone && _isPrevWhitespace && _isNextWhitespace;
+
+ if (strip.close) {
+ omitRight(body, i, true);
+ }
+ if (strip.open) {
+ omitLeft(body, i, true);
+ }
+
+ if (doStandalone && inlineStandalone) {
+ omitRight(body, i);
+
+ if (omitLeft(body, i)) {
+ // If we are on a standalone node, save the indent info for partials
+ if (current.type === 'PartialStatement') {
+ // Pull out the whitespace from the final line
+ current.indent = /([ \t]+$)/.exec(body[i - 1].original)[1];
+ }
+ }
+ }
+ if (doStandalone && openStandalone) {
+ omitRight((current.program || current.inverse).body);
+
+ // Strip out the previous content node if it's whitespace only
+ omitLeft(body, i);
+ }
+ if (doStandalone && closeStandalone) {
+ // Always strip the next node
+ omitRight(body, i);
+
+ omitLeft((current.inverse || current.program).body);
+ }
+ }
+
+ return program;
+ };
+
+ WhitespaceControl.prototype.BlockStatement = WhitespaceControl.prototype.DecoratorBlock = WhitespaceControl.prototype.PartialBlockStatement = function (block) {
+ this.accept(block.program);
+ this.accept(block.inverse);
+
+ // Find the inverse program that is involed with whitespace stripping.
+ var program = block.program || block.inverse,
+ inverse = block.program && block.inverse,
+ firstInverse = inverse,
+ lastInverse = inverse;
+
+ if (inverse && inverse.chained) {
+ firstInverse = inverse.body[0].program;
+
+ // Walk the inverse chain to find the last inverse that is actually in the chain.
+ while (lastInverse.chained) {
+ lastInverse = lastInverse.body[lastInverse.body.length - 1].program;
+ }
+ }
+
+ var strip = {
+ open: block.openStrip.open,
+ close: block.closeStrip.close,
+
+ // Determine the standalone candiacy. Basically flag our content as being possibly standalone
+ // so our parent can determine if we actually are standalone
+ openStandalone: isNextWhitespace(program.body),
+ closeStandalone: isPrevWhitespace((firstInverse || program).body)
+ };
+
+ if (block.openStrip.close) {
+ omitRight(program.body, null, true);
+ }
+
+ if (inverse) {
+ var inverseStrip = block.inverseStrip;
+
+ if (inverseStrip.open) {
+ omitLeft(program.body, null, true);
+ }
+
+ if (inverseStrip.close) {
+ omitRight(firstInverse.body, null, true);
+ }
+ if (block.closeStrip.open) {
+ omitLeft(lastInverse.body, null, true);
+ }
+
+ // Find standalone else statments
+ if (!this.options.ignoreStandalone && isPrevWhitespace(program.body) && isNextWhitespace(firstInverse.body)) {
+ omitLeft(program.body);
+ omitRight(firstInverse.body);
+ }
+ } else if (block.closeStrip.open) {
+ omitLeft(program.body, null, true);
+ }
+
+ return strip;
+ };
+
+ WhitespaceControl.prototype.Decorator = WhitespaceControl.prototype.MustacheStatement = function (mustache) {
+ return mustache.strip;
+ };
+
+ WhitespaceControl.prototype.PartialStatement = WhitespaceControl.prototype.CommentStatement = function (node) {
+ /* istanbul ignore next */
+ var strip = node.strip || {};
+ return {
+ inlineStandalone: true,
+ open: strip.open,
+ close: strip.close
+ };
+ };
+
+ function isPrevWhitespace(body, i, isRoot) {
+ if (i === undefined) {
+ i = body.length;
+ }
+
+ // Nodes that end with newlines are considered whitespace (but are special
+ // cased for strip operations)
+ var prev = body[i - 1],
+ sibling = body[i - 2];
+ if (!prev) {
+ return isRoot;
+ }
+
+ if (prev.type === 'ContentStatement') {
+ return (sibling || !isRoot ? /\r?\n\s*?$/ : /(^|\r?\n)\s*?$/).test(prev.original);
+ }
+ }
+ function isNextWhitespace(body, i, isRoot) {
+ if (i === undefined) {
+ i = -1;
+ }
+
+ var next = body[i + 1],
+ sibling = body[i + 2];
+ if (!next) {
+ return isRoot;
+ }
+
+ if (next.type === 'ContentStatement') {
+ return (sibling || !isRoot ? /^\s*?\r?\n/ : /^\s*?(\r?\n|$)/).test(next.original);
+ }
+ }
+
+ // Marks the node to the right of the position as omitted.
+ // I.e. {{foo}}' ' will mark the ' ' node as omitted.
+ //
+ // If i is undefined, then the first child will be marked as such.
+ //
+ // If mulitple is truthy then all whitespace will be stripped out until non-whitespace
+ // content is met.
+ function omitRight(body, i, multiple) {
+ var current = body[i == null ? 0 : i + 1];
+ if (!current || current.type !== 'ContentStatement' || !multiple && current.rightStripped) {
+ return;
+ }
+
+ var original = current.value;
+ current.value = current.value.replace(multiple ? /^\s+/ : /^[ \t]*\r?\n?/, '');
+ current.rightStripped = current.value !== original;
+ }
+
+ // Marks the node to the left of the position as omitted.
+ // I.e. ' '{{foo}} will mark the ' ' node as omitted.
+ //
+ // If i is undefined then the last child will be marked as such.
+ //
+ // If mulitple is truthy then all whitespace will be stripped out until non-whitespace
+ // content is met.
+ function omitLeft(body, i, multiple) {
+ var current = body[i == null ? body.length - 1 : i - 1];
+ if (!current || current.type !== 'ContentStatement' || !multiple && current.leftStripped) {
+ return;
+ }
+
+ // We omit the last node if it's whitespace only and not preceeded by a non-content node.
+ var original = current.value;
+ current.value = current.value.replace(multiple ? /\s+$/ : /[ \t]+$/, '');
+ current.leftStripped = current.value !== original;
+ return current.leftStripped;
+ }
+
+ exports['default'] = WhitespaceControl;
+ module.exports = exports['default'];
+
+/***/ },
+/* 25 */
+/***/ function(module, exports, __webpack_require__) {
+
+ 'use strict';
+
+ var _interopRequireDefault = __webpack_require__(1)['default'];
+
+ exports.__esModule = true;
+
+ var _exception = __webpack_require__(6);
+
+ var _exception2 = _interopRequireDefault(_exception);
+
+ function Visitor() {
+ this.parents = [];
+ }
+
+ Visitor.prototype = {
+ constructor: Visitor,
+ mutating: false,
+
+ // Visits a given value. If mutating, will replace the value if necessary.
+ acceptKey: function acceptKey(node, name) {
+ var value = this.accept(node[name]);
+ if (this.mutating) {
+ // Hacky sanity check: This may have a few false positives for type for the helper
+ // methods but will generally do the right thing without a lot of overhead.
+ if (value && !Visitor.prototype[value.type]) {
+ throw new _exception2['default']('Unexpected node type "' + value.type + '" found when accepting ' + name + ' on ' + node.type);
+ }
+ node[name] = value;
+ }
+ },
+
+ // Performs an accept operation with added sanity check to ensure
+ // required keys are not removed.
+ acceptRequired: function acceptRequired(node, name) {
+ this.acceptKey(node, name);
+
+ if (!node[name]) {
+ throw new _exception2['default'](node.type + ' requires ' + name);
+ }
+ },
+
+ // Traverses a given array. If mutating, empty respnses will be removed
+ // for child elements.
+ acceptArray: function acceptArray(array) {
+ for (var i = 0, l = array.length; i < l; i++) {
+ this.acceptKey(array, i);
+
+ if (!array[i]) {
+ array.splice(i, 1);
+ i--;
+ l--;
+ }
+ }
+ },
+
+ accept: function accept(object) {
+ if (!object) {
+ return;
+ }
+
+ /* istanbul ignore next: Sanity code */
+ if (!this[object.type]) {
+ throw new _exception2['default']('Unknown type: ' + object.type, object);
+ }
+
+ if (this.current) {
+ this.parents.unshift(this.current);
+ }
+ this.current = object;
+
+ var ret = this[object.type](object);
+
+ this.current = this.parents.shift();
+
+ if (!this.mutating || ret) {
+ return ret;
+ } else if (ret !== false) {
+ return object;
+ }
+ },
+
+ Program: function Program(program) {
+ this.acceptArray(program.body);
+ },
+
+ MustacheStatement: visitSubExpression,
+ Decorator: visitSubExpression,
+
+ BlockStatement: visitBlock,
+ DecoratorBlock: visitBlock,
+
+ PartialStatement: visitPartial,
+ PartialBlockStatement: function PartialBlockStatement(partial) {
+ visitPartial.call(this, partial);
+
+ this.acceptKey(partial, 'program');
+ },
+
+ ContentStatement: function ContentStatement() /* content */{},
+ CommentStatement: function CommentStatement() /* comment */{},
+
+ SubExpression: visitSubExpression,
+
+ PathExpression: function PathExpression() /* path */{},
+
+ StringLiteral: function StringLiteral() /* string */{},
+ NumberLiteral: function NumberLiteral() /* number */{},
+ BooleanLiteral: function BooleanLiteral() /* bool */{},
+ UndefinedLiteral: function UndefinedLiteral() /* literal */{},
+ NullLiteral: function NullLiteral() /* literal */{},
+
+ Hash: function Hash(hash) {
+ this.acceptArray(hash.pairs);
+ },
+ HashPair: function HashPair(pair) {
+ this.acceptRequired(pair, 'value');
+ }
+ };
+
+ function visitSubExpression(mustache) {
+ this.acceptRequired(mustache, 'path');
+ this.acceptArray(mustache.params);
+ this.acceptKey(mustache, 'hash');
+ }
+ function visitBlock(block) {
+ visitSubExpression.call(this, block);
+
+ this.acceptKey(block, 'program');
+ this.acceptKey(block, 'inverse');
+ }
+ function visitPartial(partial) {
+ this.acceptRequired(partial, 'name');
+ this.acceptArray(partial.params);
+ this.acceptKey(partial, 'hash');
+ }
+
+ exports['default'] = Visitor;
+ module.exports = exports['default'];
+
+/***/ },
+/* 26 */
+/***/ function(module, exports, __webpack_require__) {
+
+ 'use strict';
+
+ var _interopRequireDefault = __webpack_require__(1)['default'];
+
+ exports.__esModule = true;
+ exports.SourceLocation = SourceLocation;
+ exports.id = id;
+ exports.stripFlags = stripFlags;
+ exports.stripComment = stripComment;
+ exports.preparePath = preparePath;
+ exports.prepareMustache = prepareMustache;
+ exports.prepareRawBlock = prepareRawBlock;
+ exports.prepareBlock = prepareBlock;
+ exports.prepareProgram = prepareProgram;
+ exports.preparePartialBlock = preparePartialBlock;
+
+ var _exception = __webpack_require__(6);
+
+ var _exception2 = _interopRequireDefault(_exception);
+
+ function validateClose(open, close) {
+ close = close.path ? close.path.original : close;
+
+ if (open.path.original !== close) {
+ var errorNode = { loc: open.path.loc };
+
+ throw new _exception2['default'](open.path.original + " doesn't match " + close, errorNode);
+ }
+ }
+
+ function SourceLocation(source, locInfo) {
+ this.source = source;
+ this.start = {
+ line: locInfo.first_line,
+ column: locInfo.first_column
+ };
+ this.end = {
+ line: locInfo.last_line,
+ column: locInfo.last_column
+ };
+ }
+
+ function id(token) {
+ if (/^\[.*\]$/.test(token)) {
+ return token.substr(1, token.length - 2);
+ } else {
+ return token;
+ }
+ }
+
+ function stripFlags(open, close) {
+ return {
+ open: open.charAt(2) === '~',
+ close: close.charAt(close.length - 3) === '~'
+ };
+ }
+
+ function stripComment(comment) {
+ return comment.replace(/^\{\{~?\!-?-?/, '').replace(/-?-?~?\}\}$/, '');
+ }
+
+ function preparePath(data, parts, loc) {
+ loc = this.locInfo(loc);
+
+ var original = data ? '@' : '',
+ dig = [],
+ depth = 0,
+ depthString = '';
+
+ for (var i = 0, l = parts.length; i < l; i++) {
+ var part = parts[i].part,
+
+ // If we have [] syntax then we do not treat path references as operators,
+ // i.e. foo.[this] resolves to approximately context.foo['this']
+ isLiteral = parts[i].original !== part;
+ original += (parts[i].separator || '') + part;
+
+ if (!isLiteral && (part === '..' || part === '.' || part === 'this')) {
+ if (dig.length > 0) {
+ throw new _exception2['default']('Invalid path: ' + original, { loc: loc });
+ } else if (part === '..') {
+ depth++;
+ depthString += '../';
+ }
+ } else {
+ dig.push(part);
+ }
+ }
+
+ return {
+ type: 'PathExpression',
+ data: data,
+ depth: depth,
+ parts: dig,
+ original: original,
+ loc: loc
+ };
+ }
+
+ function prepareMustache(path, params, hash, open, strip, locInfo) {
+ // Must use charAt to support IE pre-10
+ var escapeFlag = open.charAt(3) || open.charAt(2),
+ escaped = escapeFlag !== '{' && escapeFlag !== '&';
+
+ var decorator = /\*/.test(open);
+ return {
+ type: decorator ? 'Decorator' : 'MustacheStatement',
+ path: path,
+ params: params,
+ hash: hash,
+ escaped: escaped,
+ strip: strip,
+ loc: this.locInfo(locInfo)
+ };
+ }
+
+ function prepareRawBlock(openRawBlock, contents, close, locInfo) {
+ validateClose(openRawBlock, close);
+
+ locInfo = this.locInfo(locInfo);
+ var program = {
+ type: 'Program',
+ body: contents,
+ strip: {},
+ loc: locInfo
+ };
+
+ return {
+ type: 'BlockStatement',
+ path: openRawBlock.path,
+ params: openRawBlock.params,
+ hash: openRawBlock.hash,
+ program: program,
+ openStrip: {},
+ inverseStrip: {},
+ closeStrip: {},
+ loc: locInfo
+ };
+ }
+
+ function prepareBlock(openBlock, program, inverseAndProgram, close, inverted, locInfo) {
+ if (close && close.path) {
+ validateClose(openBlock, close);
+ }
+
+ var decorator = /\*/.test(openBlock.open);
+
+ program.blockParams = openBlock.blockParams;
+
+ var inverse = undefined,
+ inverseStrip = undefined;
+
+ if (inverseAndProgram) {
+ if (decorator) {
+ throw new _exception2['default']('Unexpected inverse block on decorator', inverseAndProgram);
+ }
+
+ if (inverseAndProgram.chain) {
+ inverseAndProgram.program.body[0].closeStrip = close.strip;
+ }
+
+ inverseStrip = inverseAndProgram.strip;
+ inverse = inverseAndProgram.program;
+ }
+
+ if (inverted) {
+ inverted = inverse;
+ inverse = program;
+ program = inverted;
+ }
+
+ return {
+ type: decorator ? 'DecoratorBlock' : 'BlockStatement',
+ path: openBlock.path,
+ params: openBlock.params,
+ hash: openBlock.hash,
+ program: program,
+ inverse: inverse,
+ openStrip: openBlock.strip,
+ inverseStrip: inverseStrip,
+ closeStrip: close && close.strip,
+ loc: this.locInfo(locInfo)
+ };
+ }
+
+ function prepareProgram(statements, loc) {
+ if (!loc && statements.length) {
+ var firstLoc = statements[0].loc,
+ lastLoc = statements[statements.length - 1].loc;
+
+ /* istanbul ignore else */
+ if (firstLoc && lastLoc) {
+ loc = {
+ source: firstLoc.source,
+ start: {
+ line: firstLoc.start.line,
+ column: firstLoc.start.column
+ },
+ end: {
+ line: lastLoc.end.line,
+ column: lastLoc.end.column
+ }
+ };
+ }
+ }
+
+ return {
+ type: 'Program',
+ body: statements,
+ strip: {},
+ loc: loc
+ };
+ }
+
+ function preparePartialBlock(open, program, close, locInfo) {
+ validateClose(open, close);
+
+ return {
+ type: 'PartialBlockStatement',
+ name: open.path,
+ params: open.params,
+ hash: open.hash,
+ program: program,
+ openStrip: open.strip,
+ closeStrip: close && close.strip,
+ loc: this.locInfo(locInfo)
+ };
+ }
+
+/***/ },
+/* 27 */
+/***/ function(module, exports, __webpack_require__) {
+
+ /* eslint-disable new-cap */
+
+ 'use strict';
+
+ var _interopRequireDefault = __webpack_require__(1)['default'];
+
+ exports.__esModule = true;
+ exports.Compiler = Compiler;
+ exports.precompile = precompile;
+ exports.compile = compile;
+
+ var _exception = __webpack_require__(6);
+
+ var _exception2 = _interopRequireDefault(_exception);
+
+ var _utils = __webpack_require__(5);
+
+ var _ast = __webpack_require__(21);
+
+ var _ast2 = _interopRequireDefault(_ast);
+
+ var slice = [].slice;
+
+ function Compiler() {}
+
+ // the foundHelper register will disambiguate helper lookup from finding a
+ // function in a context. This is necessary for mustache compatibility, which
+ // requires that context functions in blocks are evaluated by blockHelperMissing,
+ // and then proceed as if the resulting value was provided to blockHelperMissing.
+
+ Compiler.prototype = {
+ compiler: Compiler,
+
+ equals: function equals(other) {
+ var len = this.opcodes.length;
+ if (other.opcodes.length !== len) {
+ return false;
+ }
+
+ for (var i = 0; i < len; i++) {
+ var opcode = this.opcodes[i],
+ otherOpcode = other.opcodes[i];
+ if (opcode.opcode !== otherOpcode.opcode || !argEquals(opcode.args, otherOpcode.args)) {
+ return false;
+ }
+ }
+
+ // We know that length is the same between the two arrays because they are directly tied
+ // to the opcode behavior above.
+ len = this.children.length;
+ for (var i = 0; i < len; i++) {
+ if (!this.children[i].equals(other.children[i])) {
+ return false;
+ }
+ }
+
+ return true;
+ },
+
+ guid: 0,
+
+ compile: function compile(program, options) {
+ this.sourceNode = [];
+ this.opcodes = [];
+ this.children = [];
+ this.options = options;
+ this.stringParams = options.stringParams;
+ this.trackIds = options.trackIds;
+
+ options.blockParams = options.blockParams || [];
+
+ // These changes will propagate to the other compiler components
+ var knownHelpers = options.knownHelpers;
+ options.knownHelpers = {
+ 'helperMissing': true,
+ 'blockHelperMissing': true,
+ 'each': true,
+ 'if': true,
+ 'unless': true,
+ 'with': true,
+ 'log': true,
+ 'lookup': true
+ };
+ if (knownHelpers) {
+ for (var _name in knownHelpers) {
+ /* istanbul ignore else */
+ if (_name in knownHelpers) {
+ options.knownHelpers[_name] = knownHelpers[_name];
+ }
+ }
+ }
+
+ return this.accept(program);
+ },
+
+ compileProgram: function compileProgram(program) {
+ var childCompiler = new this.compiler(),
+ // eslint-disable-line new-cap
+ result = childCompiler.compile(program, this.options),
+ guid = this.guid++;
+
+ this.usePartial = this.usePartial || result.usePartial;
+
+ this.children[guid] = result;
+ this.useDepths = this.useDepths || result.useDepths;
+
+ return guid;
+ },
+
+ accept: function accept(node) {
+ /* istanbul ignore next: Sanity code */
+ if (!this[node.type]) {
+ throw new _exception2['default']('Unknown type: ' + node.type, node);
+ }
+
+ this.sourceNode.unshift(node);
+ var ret = this[node.type](node);
+ this.sourceNode.shift();
+ return ret;
+ },
+
+ Program: function Program(program) {
+ this.options.blockParams.unshift(program.blockParams);
+
+ var body = program.body,
+ bodyLength = body.length;
+ for (var i = 0; i < bodyLength; i++) {
+ this.accept(body[i]);
+ }
+
+ this.options.blockParams.shift();
+
+ this.isSimple = bodyLength === 1;
+ this.blockParams = program.blockParams ? program.blockParams.length : 0;
+
+ return this;
+ },
+
+ BlockStatement: function BlockStatement(block) {
+ transformLiteralToPath(block);
+
+ var program = block.program,
+ inverse = block.inverse;
+
+ program = program && this.compileProgram(program);
+ inverse = inverse && this.compileProgram(inverse);
+
+ var type = this.classifySexpr(block);
+
+ if (type === 'helper') {
+ this.helperSexpr(block, program, inverse);
+ } else if (type === 'simple') {
+ this.simpleSexpr(block);
+
+ // now that the simple mustache is resolved, we need to
+ // evaluate it by executing `blockHelperMissing`
+ this.opcode('pushProgram', program);
+ this.opcode('pushProgram', inverse);
+ this.opcode('emptyHash');
+ this.opcode('blockValue', block.path.original);
+ } else {
+ this.ambiguousSexpr(block, program, inverse);
+
+ // now that the simple mustache is resolved, we need to
+ // evaluate it by executing `blockHelperMissing`
+ this.opcode('pushProgram', program);
+ this.opcode('pushProgram', inverse);
+ this.opcode('emptyHash');
+ this.opcode('ambiguousBlockValue');
+ }
+
+ this.opcode('append');
+ },
+
+ DecoratorBlock: function DecoratorBlock(decorator) {
+ var program = decorator.program && this.compileProgram(decorator.program);
+ var params = this.setupFullMustacheParams(decorator, program, undefined),
+ path = decorator.path;
+
+ this.useDecorators = true;
+ this.opcode('registerDecorator', params.length, path.original);
+ },
+
+ PartialStatement: function PartialStatement(partial) {
+ this.usePartial = true;
+
+ var program = partial.program;
+ if (program) {
+ program = this.compileProgram(partial.program);
+ }
+
+ var params = partial.params;
+ if (params.length > 1) {
+ throw new _exception2['default']('Unsupported number of partial arguments: ' + params.length, partial);
+ } else if (!params.length) {
+ if (this.options.explicitPartialContext) {
+ this.opcode('pushLiteral', 'undefined');
+ } else {
+ params.push({ type: 'PathExpression', parts: [], depth: 0 });
+ }
+ }
+
+ var partialName = partial.name.original,
+ isDynamic = partial.name.type === 'SubExpression';
+ if (isDynamic) {
+ this.accept(partial.name);
+ }
+
+ this.setupFullMustacheParams(partial, program, undefined, true);
+
+ var indent = partial.indent || '';
+ if (this.options.preventIndent && indent) {
+ this.opcode('appendContent', indent);
+ indent = '';
+ }
+
+ this.opcode('invokePartial', isDynamic, partialName, indent);
+ this.opcode('append');
+ },
+ PartialBlockStatement: function PartialBlockStatement(partialBlock) {
+ this.PartialStatement(partialBlock);
+ },
+
+ MustacheStatement: function MustacheStatement(mustache) {
+ this.SubExpression(mustache);
+
+ if (mustache.escaped && !this.options.noEscape) {
+ this.opcode('appendEscaped');
+ } else {
+ this.opcode('append');
+ }
+ },
+ Decorator: function Decorator(decorator) {
+ this.DecoratorBlock(decorator);
+ },
+
+ ContentStatement: function ContentStatement(content) {
+ if (content.value) {
+ this.opcode('appendContent', content.value);
+ }
+ },
+
+ CommentStatement: function CommentStatement() {},
+
+ SubExpression: function SubExpression(sexpr) {
+ transformLiteralToPath(sexpr);
+ var type = this.classifySexpr(sexpr);
+
+ if (type === 'simple') {
+ this.simpleSexpr(sexpr);
+ } else if (type === 'helper') {
+ this.helperSexpr(sexpr);
+ } else {
+ this.ambiguousSexpr(sexpr);
+ }
+ },
+ ambiguousSexpr: function ambiguousSexpr(sexpr, program, inverse) {
+ var path = sexpr.path,
+ name = path.parts[0],
+ isBlock = program != null || inverse != null;
+
+ this.opcode('getContext', path.depth);
+
+ this.opcode('pushProgram', program);
+ this.opcode('pushProgram', inverse);
+
+ path.strict = true;
+ this.accept(path);
+
+ this.opcode('invokeAmbiguous', name, isBlock);
+ },
+
+ simpleSexpr: function simpleSexpr(sexpr) {
+ var path = sexpr.path;
+ path.strict = true;
+ this.accept(path);
+ this.opcode('resolvePossibleLambda');
+ },
+
+ helperSexpr: function helperSexpr(sexpr, program, inverse) {
+ var params = this.setupFullMustacheParams(sexpr, program, inverse),
+ path = sexpr.path,
+ name = path.parts[0];
+
+ if (this.options.knownHelpers[name]) {
+ this.opcode('invokeKnownHelper', params.length, name);
+ } else if (this.options.knownHelpersOnly) {
+ throw new _exception2['default']('You specified knownHelpersOnly, but used the unknown helper ' + name, sexpr);
+ } else {
+ path.strict = true;
+ path.falsy = true;
+
+ this.accept(path);
+ this.opcode('invokeHelper', params.length, path.original, _ast2['default'].helpers.simpleId(path));
+ }
+ },
+
+ PathExpression: function PathExpression(path) {
+ this.addDepth(path.depth);
+ this.opcode('getContext', path.depth);
+
+ var name = path.parts[0],
+ scoped = _ast2['default'].helpers.scopedId(path),
+ blockParamId = !path.depth && !scoped && this.blockParamIndex(name);
+
+ if (blockParamId) {
+ this.opcode('lookupBlockParam', blockParamId, path.parts);
+ } else if (!name) {
+ // Context reference, i.e. `{{foo .}}` or `{{foo ..}}`
+ this.opcode('pushContext');
+ } else if (path.data) {
+ this.options.data = true;
+ this.opcode('lookupData', path.depth, path.parts, path.strict);
+ } else {
+ this.opcode('lookupOnContext', path.parts, path.falsy, path.strict, scoped);
+ }
+ },
+
+ StringLiteral: function StringLiteral(string) {
+ this.opcode('pushString', string.value);
+ },
+
+ NumberLiteral: function NumberLiteral(number) {
+ this.opcode('pushLiteral', number.value);
+ },
+
+ BooleanLiteral: function BooleanLiteral(bool) {
+ this.opcode('pushLiteral', bool.value);
+ },
+
+ UndefinedLiteral: function UndefinedLiteral() {
+ this.opcode('pushLiteral', 'undefined');
+ },
+
+ NullLiteral: function NullLiteral() {
+ this.opcode('pushLiteral', 'null');
+ },
+
+ Hash: function Hash(hash) {
+ var pairs = hash.pairs,
+ i = 0,
+ l = pairs.length;
+
+ this.opcode('pushHash');
+
+ for (; i < l; i++) {
+ this.pushParam(pairs[i].value);
+ }
+ while (i--) {
+ this.opcode('assignToHash', pairs[i].key);
+ }
+ this.opcode('popHash');
+ },
+
+ // HELPERS
+ opcode: function opcode(name) {
+ this.opcodes.push({ opcode: name, args: slice.call(arguments, 1), loc: this.sourceNode[0].loc });
+ },
+
+ addDepth: function addDepth(depth) {
+ if (!depth) {
+ return;
+ }
+
+ this.useDepths = true;
+ },
+
+ classifySexpr: function classifySexpr(sexpr) {
+ var isSimple = _ast2['default'].helpers.simpleId(sexpr.path);
+
+ var isBlockParam = isSimple && !!this.blockParamIndex(sexpr.path.parts[0]);
+
+ // a mustache is an eligible helper if:
+ // * its id is simple (a single part, not `this` or `..`)
+ var isHelper = !isBlockParam && _ast2['default'].helpers.helperExpression(sexpr);
+
+ // if a mustache is an eligible helper but not a definite
+ // helper, it is ambiguous, and will be resolved in a later
+ // pass or at runtime.
+ var isEligible = !isBlockParam && (isHelper || isSimple);
+
+ // if ambiguous, we can possibly resolve the ambiguity now
+ // An eligible helper is one that does not have a complex path, i.e. `this.foo`, `../foo` etc.
+ if (isEligible && !isHelper) {
+ var _name2 = sexpr.path.parts[0],
+ options = this.options;
+
+ if (options.knownHelpers[_name2]) {
+ isHelper = true;
+ } else if (options.knownHelpersOnly) {
+ isEligible = false;
+ }
+ }
+
+ if (isHelper) {
+ return 'helper';
+ } else if (isEligible) {
+ return 'ambiguous';
+ } else {
+ return 'simple';
+ }
+ },
+
+ pushParams: function pushParams(params) {
+ for (var i = 0, l = params.length; i < l; i++) {
+ this.pushParam(params[i]);
+ }
+ },
+
+ pushParam: function pushParam(val) {
+ var value = val.value != null ? val.value : val.original || '';
+
+ if (this.stringParams) {
+ if (value.replace) {
+ value = value.replace(/^(\.?\.\/)*/g, '').replace(/\//g, '.');
+ }
+
+ if (val.depth) {
+ this.addDepth(val.depth);
+ }
+ this.opcode('getContext', val.depth || 0);
+ this.opcode('pushStringParam', value, val.type);
+
+ if (val.type === 'SubExpression') {
+ // SubExpressions get evaluated and passed in
+ // in string params mode.
+ this.accept(val);
+ }
+ } else {
+ if (this.trackIds) {
+ var blockParamIndex = undefined;
+ if (val.parts && !_ast2['default'].helpers.scopedId(val) && !val.depth) {
+ blockParamIndex = this.blockParamIndex(val.parts[0]);
+ }
+ if (blockParamIndex) {
+ var blockParamChild = val.parts.slice(1).join('.');
+ this.opcode('pushId', 'BlockParam', blockParamIndex, blockParamChild);
+ } else {
+ value = val.original || value;
+ if (value.replace) {
+ value = value.replace(/^this(?:\.|$)/, '').replace(/^\.\//, '').replace(/^\.$/, '');
+ }
+
+ this.opcode('pushId', val.type, value);
+ }
+ }
+ this.accept(val);
+ }
+ },
+
+ setupFullMustacheParams: function setupFullMustacheParams(sexpr, program, inverse, omitEmpty) {
+ var params = sexpr.params;
+ this.pushParams(params);
+
+ this.opcode('pushProgram', program);
+ this.opcode('pushProgram', inverse);
+
+ if (sexpr.hash) {
+ this.accept(sexpr.hash);
+ } else {
+ this.opcode('emptyHash', omitEmpty);
+ }
+
+ return params;
+ },
+
+ blockParamIndex: function blockParamIndex(name) {
+ for (var depth = 0, len = this.options.blockParams.length; depth < len; depth++) {
+ var blockParams = this.options.blockParams[depth],
+ param = blockParams && _utils.indexOf(blockParams, name);
+ if (blockParams && param >= 0) {
+ return [depth, param];
+ }
+ }
+ }
+ };
+
+ function precompile(input, options, env) {
+ if (input == null || typeof input !== 'string' && input.type !== 'Program') {
+ throw new _exception2['default']('You must pass a string or Handlebars AST to Handlebars.precompile. You passed ' + input);
+ }
+
+ options = options || {};
+ if (!('data' in options)) {
+ options.data = true;
+ }
+ if (options.compat) {
+ options.useDepths = true;
+ }
+
+ var ast = env.parse(input, options),
+ environment = new env.Compiler().compile(ast, options);
+ return new env.JavaScriptCompiler().compile(environment, options);
+ }
+
+ function compile(input, options, env) {
+ if (options === undefined) options = {};
+
+ if (input == null || typeof input !== 'string' && input.type !== 'Program') {
+ throw new _exception2['default']('You must pass a string or Handlebars AST to Handlebars.compile. You passed ' + input);
+ }
+
+ if (!('data' in options)) {
+ options.data = true;
+ }
+ if (options.compat) {
+ options.useDepths = true;
+ }
+
+ var compiled = undefined;
+
+ function compileInput() {
+ var ast = env.parse(input, options),
+ environment = new env.Compiler().compile(ast, options),
+ templateSpec = new env.JavaScriptCompiler().compile(environment, options, undefined, true);
+ return env.template(templateSpec);
+ }
+
+ // Template is only compiled on first use and cached after that point.
+ function ret(context, execOptions) {
+ if (!compiled) {
+ compiled = compileInput();
+ }
+ return compiled.call(this, context, execOptions);
+ }
+ ret._setup = function (setupOptions) {
+ if (!compiled) {
+ compiled = compileInput();
+ }
+ return compiled._setup(setupOptions);
+ };
+ ret._child = function (i, data, blockParams, depths) {
+ if (!compiled) {
+ compiled = compileInput();
+ }
+ return compiled._child(i, data, blockParams, depths);
+ };
+ return ret;
+ }
+
+ function argEquals(a, b) {
+ if (a === b) {
+ return true;
+ }
+
+ if (_utils.isArray(a) && _utils.isArray(b) && a.length === b.length) {
+ for (var i = 0; i < a.length; i++) {
+ if (!argEquals(a[i], b[i])) {
+ return false;
+ }
+ }
+ return true;
+ }
+ }
+
+ function transformLiteralToPath(sexpr) {
+ if (!sexpr.path.parts) {
+ var literal = sexpr.path;
+ // Casting to string here to make false and 0 literal values play nicely with the rest
+ // of the system.
+ sexpr.path = {
+ type: 'PathExpression',
+ data: false,
+ depth: 0,
+ parts: [literal.original + ''],
+ original: literal.original + '',
+ loc: literal.loc
+ };
+ }
+ }
+
+/***/ },
+/* 28 */
+/***/ function(module, exports, __webpack_require__) {
+
+ 'use strict';
+
+ var _interopRequireDefault = __webpack_require__(1)['default'];
+
+ exports.__esModule = true;
+
+ var _base = __webpack_require__(4);
+
+ var _exception = __webpack_require__(6);
+
+ var _exception2 = _interopRequireDefault(_exception);
+
+ var _utils = __webpack_require__(5);
+
+ var _codeGen = __webpack_require__(29);
+
+ var _codeGen2 = _interopRequireDefault(_codeGen);
+
+ function Literal(value) {
+ this.value = value;
+ }
+
+ function JavaScriptCompiler() {}
+
+ JavaScriptCompiler.prototype = {
+ // PUBLIC API: You can override these methods in a subclass to provide
+ // alternative compiled forms for name lookup and buffering semantics
+ nameLookup: function nameLookup(parent, name /* , type*/) {
+ if (JavaScriptCompiler.isValidJavaScriptVariableName(name)) {
+ return [parent, '.', name];
+ } else {
+ return [parent, '[', JSON.stringify(name), ']'];
+ }
+ },
+ depthedLookup: function depthedLookup(name) {
+ return [this.aliasable('container.lookup'), '(depths, "', name, '")'];
+ },
+
+ compilerInfo: function compilerInfo() {
+ var revision = _base.COMPILER_REVISION,
+ versions = _base.REVISION_CHANGES[revision];
+ return [revision, versions];
+ },
+
+ appendToBuffer: function appendToBuffer(source, location, explicit) {
+ // Force a source as this simplifies the merge logic.
+ if (!_utils.isArray(source)) {
+ source = [source];
+ }
+ source = this.source.wrap(source, location);
+
+ if (this.environment.isSimple) {
+ return ['return ', source, ';'];
+ } else if (explicit) {
+ // This is a case where the buffer operation occurs as a child of another
+ // construct, generally braces. We have to explicitly output these buffer
+ // operations to ensure that the emitted code goes in the correct location.
+ return ['buffer += ', source, ';'];
+ } else {
+ source.appendToBuffer = true;
+ return source;
+ }
+ },
+
+ initializeBuffer: function initializeBuffer() {
+ return this.quotedString('');
+ },
+ // END PUBLIC API
+
+ compile: function compile(environment, options, context, asObject) {
+ this.environment = environment;
+ this.options = options;
+ this.stringParams = this.options.stringParams;
+ this.trackIds = this.options.trackIds;
+ this.precompile = !asObject;
+
+ this.name = this.environment.name;
+ this.isChild = !!context;
+ this.context = context || {
+ decorators: [],
+ programs: [],
+ environments: []
+ };
+
+ this.preamble();
+
+ this.stackSlot = 0;
+ this.stackVars = [];
+ this.aliases = {};
+ this.registers = { list: [] };
+ this.hashes = [];
+ this.compileStack = [];
+ this.inlineStack = [];
+ this.blockParams = [];
+
+ this.compileChildren(environment, options);
+
+ this.useDepths = this.useDepths || environment.useDepths || environment.useDecorators || this.options.compat;
+ this.useBlockParams = this.useBlockParams || environment.useBlockParams;
+
+ var opcodes = environment.opcodes,
+ opcode = undefined,
+ firstLoc = undefined,
+ i = undefined,
+ l = undefined;
+
+ for (i = 0, l = opcodes.length; i < l; i++) {
+ opcode = opcodes[i];
+
+ this.source.currentLocation = opcode.loc;
+ firstLoc = firstLoc || opcode.loc;
+ this[opcode.opcode].apply(this, opcode.args);
+ }
+
+ // Flush any trailing content that might be pending.
+ this.source.currentLocation = firstLoc;
+ this.pushSource('');
+
+ /* istanbul ignore next */
+ if (this.stackSlot || this.inlineStack.length || this.compileStack.length) {
+ throw new _exception2['default']('Compile completed with content left on stack');
+ }
+
+ if (!this.decorators.isEmpty()) {
+ this.useDecorators = true;
+
+ this.decorators.prepend('var decorators = container.decorators;\n');
+ this.decorators.push('return fn;');
+
+ if (asObject) {
+ this.decorators = Function.apply(this, ['fn', 'props', 'container', 'depth0', 'data', 'blockParams', 'depths', this.decorators.merge()]);
+ } else {
+ this.decorators.prepend('function(fn, props, container, depth0, data, blockParams, depths) {\n');
+ this.decorators.push('}\n');
+ this.decorators = this.decorators.merge();
+ }
+ } else {
+ this.decorators = undefined;
+ }
+
+ var fn = this.createFunctionContext(asObject);
+ if (!this.isChild) {
+ var ret = {
+ compiler: this.compilerInfo(),
+ main: fn
+ };
+
+ if (this.decorators) {
+ ret.main_d = this.decorators; // eslint-disable-line camelcase
+ ret.useDecorators = true;
+ }
+
+ var _context = this.context;
+ var programs = _context.programs;
+ var decorators = _context.decorators;
+
+ for (i = 0, l = programs.length; i < l; i++) {
+ if (programs[i]) {
+ ret[i] = programs[i];
+ if (decorators[i]) {
+ ret[i + '_d'] = decorators[i];
+ ret.useDecorators = true;
+ }
+ }
+ }
+
+ if (this.environment.usePartial) {
+ ret.usePartial = true;
+ }
+ if (this.options.data) {
+ ret.useData = true;
+ }
+ if (this.useDepths) {
+ ret.useDepths = true;
+ }
+ if (this.useBlockParams) {
+ ret.useBlockParams = true;
+ }
+ if (this.options.compat) {
+ ret.compat = true;
+ }
+
+ if (!asObject) {
+ ret.compiler = JSON.stringify(ret.compiler);
+
+ this.source.currentLocation = { start: { line: 1, column: 0 } };
+ ret = this.objectLiteral(ret);
+
+ if (options.srcName) {
+ ret = ret.toStringWithSourceMap({ file: options.destName });
+ ret.map = ret.map && ret.map.toString();
+ } else {
+ ret = ret.toString();
+ }
+ } else {
+ ret.compilerOptions = this.options;
+ }
+
+ return ret;
+ } else {
+ return fn;
+ }
+ },
+
+ preamble: function preamble() {
+ // track the last context pushed into place to allow skipping the
+ // getContext opcode when it would be a noop
+ this.lastContext = 0;
+ this.source = new _codeGen2['default'](this.options.srcName);
+ this.decorators = new _codeGen2['default'](this.options.srcName);
+ },
+
+ createFunctionContext: function createFunctionContext(asObject) {
+ var varDeclarations = '';
+
+ var locals = this.stackVars.concat(this.registers.list);
+ if (locals.length > 0) {
+ varDeclarations += ', ' + locals.join(', ');
+ }
+
+ // Generate minimizer alias mappings
+ //
+ // When using true SourceNodes, this will update all references to the given alias
+ // as the source nodes are reused in situ. For the non-source node compilation mode,
+ // aliases will not be used, but this case is already being run on the client and
+ // we aren't concern about minimizing the template size.
+ var aliasCount = 0;
+ for (var alias in this.aliases) {
+ // eslint-disable-line guard-for-in
+ var node = this.aliases[alias];
+
+ if (this.aliases.hasOwnProperty(alias) && node.children && node.referenceCount > 1) {
+ varDeclarations += ', alias' + ++aliasCount + '=' + alias;
+ node.children[0] = 'alias' + aliasCount;
+ }
+ }
+
+ var params = ['container', 'depth0', 'helpers', 'partials', 'data'];
+
+ if (this.useBlockParams || this.useDepths) {
+ params.push('blockParams');
+ }
+ if (this.useDepths) {
+ params.push('depths');
+ }
+
+ // Perform a second pass over the output to merge content when possible
+ var source = this.mergeSource(varDeclarations);
+
+ if (asObject) {
+ params.push(source);
+
+ return Function.apply(this, params);
+ } else {
+ return this.source.wrap(['function(', params.join(','), ') {\n ', source, '}']);
+ }
+ },
+ mergeSource: function mergeSource(varDeclarations) {
+ var isSimple = this.environment.isSimple,
+ appendOnly = !this.forceBuffer,
+ appendFirst = undefined,
+ sourceSeen = undefined,
+ bufferStart = undefined,
+ bufferEnd = undefined;
+ this.source.each(function (line) {
+ if (line.appendToBuffer) {
+ if (bufferStart) {
+ line.prepend(' + ');
+ } else {
+ bufferStart = line;
+ }
+ bufferEnd = line;
+ } else {
+ if (bufferStart) {
+ if (!sourceSeen) {
+ appendFirst = true;
+ } else {
+ bufferStart.prepend('buffer += ');
+ }
+ bufferEnd.add(';');
+ bufferStart = bufferEnd = undefined;
+ }
+
+ sourceSeen = true;
+ if (!isSimple) {
+ appendOnly = false;
+ }
+ }
+ });
+
+ if (appendOnly) {
+ if (bufferStart) {
+ bufferStart.prepend('return ');
+ bufferEnd.add(';');
+ } else if (!sourceSeen) {
+ this.source.push('return "";');
+ }
+ } else {
+ varDeclarations += ', buffer = ' + (appendFirst ? '' : this.initializeBuffer());
+
+ if (bufferStart) {
+ bufferStart.prepend('return buffer + ');
+ bufferEnd.add(';');
+ } else {
+ this.source.push('return buffer;');
+ }
+ }
+
+ if (varDeclarations) {
+ this.source.prepend('var ' + varDeclarations.substring(2) + (appendFirst ? '' : ';\n'));
+ }
+
+ return this.source.merge();
+ },
+
+ // [blockValue]
+ //
+ // On stack, before: hash, inverse, program, value
+ // On stack, after: return value of blockHelperMissing
+ //
+ // The purpose of this opcode is to take a block of the form
+ // `{{#this.foo}}...{{/this.foo}}`, resolve the value of `foo`, and
+ // replace it on the stack with the result of properly
+ // invoking blockHelperMissing.
+ blockValue: function blockValue(name) {
+ var blockHelperMissing = this.aliasable('helpers.blockHelperMissing'),
+ params = [this.contextName(0)];
+ this.setupHelperArgs(name, 0, params);
+
+ var blockName = this.popStack();
+ params.splice(1, 0, blockName);
+
+ this.push(this.source.functionCall(blockHelperMissing, 'call', params));
+ },
+
+ // [ambiguousBlockValue]
+ //
+ // On stack, before: hash, inverse, program, value
+ // Compiler value, before: lastHelper=value of last found helper, if any
+ // On stack, after, if no lastHelper: same as [blockValue]
+ // On stack, after, if lastHelper: value
+ ambiguousBlockValue: function ambiguousBlockValue() {
+ // We're being a bit cheeky and reusing the options value from the prior exec
+ var blockHelperMissing = this.aliasable('helpers.blockHelperMissing'),
+ params = [this.contextName(0)];
+ this.setupHelperArgs('', 0, params, true);
+
+ this.flushInline();
+
+ var current = this.topStack();
+ params.splice(1, 0, current);
+
+ this.pushSource(['if (!', this.lastHelper, ') { ', current, ' = ', this.source.functionCall(blockHelperMissing, 'call', params), '}']);
+ },
+
+ // [appendContent]
+ //
+ // On stack, before: ...
+ // On stack, after: ...
+ //
+ // Appends the string value of `content` to the current buffer
+ appendContent: function appendContent(content) {
+ if (this.pendingContent) {
+ content = this.pendingContent + content;
+ } else {
+ this.pendingLocation = this.source.currentLocation;
+ }
+
+ this.pendingContent = content;
+ },
+
+ // [append]
+ //
+ // On stack, before: value, ...
+ // On stack, after: ...
+ //
+ // Coerces `value` to a String and appends it to the current buffer.
+ //
+ // If `value` is truthy, or 0, it is coerced into a string and appended
+ // Otherwise, the empty string is appended
+ append: function append() {
+ if (this.isInline()) {
+ this.replaceStack(function (current) {
+ return [' != null ? ', current, ' : ""'];
+ });
+
+ this.pushSource(this.appendToBuffer(this.popStack()));
+ } else {
+ var local = this.popStack();
+ this.pushSource(['if (', local, ' != null) { ', this.appendToBuffer(local, undefined, true), ' }']);
+ if (this.environment.isSimple) {
+ this.pushSource(['else { ', this.appendToBuffer("''", undefined, true), ' }']);
+ }
+ }
+ },
+
+ // [appendEscaped]
+ //
+ // On stack, before: value, ...
+ // On stack, after: ...
+ //
+ // Escape `value` and append it to the buffer
+ appendEscaped: function appendEscaped() {
+ this.pushSource(this.appendToBuffer([this.aliasable('container.escapeExpression'), '(', this.popStack(), ')']));
+ },
+
+ // [getContext]
+ //
+ // On stack, before: ...
+ // On stack, after: ...
+ // Compiler value, after: lastContext=depth
+ //
+ // Set the value of the `lastContext` compiler value to the depth
+ getContext: function getContext(depth) {
+ this.lastContext = depth;
+ },
+
+ // [pushContext]
+ //
+ // On stack, before: ...
+ // On stack, after: currentContext, ...
+ //
+ // Pushes the value of the current context onto the stack.
+ pushContext: function pushContext() {
+ this.pushStackLiteral(this.contextName(this.lastContext));
+ },
+
+ // [lookupOnContext]
+ //
+ // On stack, before: ...
+ // On stack, after: currentContext[name], ...
+ //
+ // Looks up the value of `name` on the current context and pushes
+ // it onto the stack.
+ lookupOnContext: function lookupOnContext(parts, falsy, strict, scoped) {
+ var i = 0;
+
+ if (!scoped && this.options.compat && !this.lastContext) {
+ // The depthed query is expected to handle the undefined logic for the root level that
+ // is implemented below, so we evaluate that directly in compat mode
+ this.push(this.depthedLookup(parts[i++]));
+ } else {
+ this.pushContext();
+ }
+
+ this.resolvePath('context', parts, i, falsy, strict);
+ },
+
+ // [lookupBlockParam]
+ //
+ // On stack, before: ...
+ // On stack, after: blockParam[name], ...
+ //
+ // Looks up the value of `parts` on the given block param and pushes
+ // it onto the stack.
+ lookupBlockParam: function lookupBlockParam(blockParamId, parts) {
+ this.useBlockParams = true;
+
+ this.push(['blockParams[', blockParamId[0], '][', blockParamId[1], ']']);
+ this.resolvePath('context', parts, 1);
+ },
+
+ // [lookupData]
+ //
+ // On stack, before: ...
+ // On stack, after: data, ...
+ //
+ // Push the data lookup operator
+ lookupData: function lookupData(depth, parts, strict) {
+ if (!depth) {
+ this.pushStackLiteral('data');
+ } else {
+ this.pushStackLiteral('container.data(data, ' + depth + ')');
+ }
+
+ this.resolvePath('data', parts, 0, true, strict);
+ },
+
+ resolvePath: function resolvePath(type, parts, i, falsy, strict) {
+ // istanbul ignore next
+
+ var _this = this;
+
+ if (this.options.strict || this.options.assumeObjects) {
+ this.push(strictLookup(this.options.strict && strict, this, parts, type));
+ return;
+ }
+
+ var len = parts.length;
+ for (; i < len; i++) {
+ /* eslint-disable no-loop-func */
+ this.replaceStack(function (current) {
+ var lookup = _this.nameLookup(current, parts[i], type);
+ // We want to ensure that zero and false are handled properly if the context (falsy flag)
+ // needs to have the special handling for these values.
+ if (!falsy) {
+ return [' != null ? ', lookup, ' : ', current];
+ } else {
+ // Otherwise we can use generic falsy handling
+ return [' && ', lookup];
+ }
+ });
+ /* eslint-enable no-loop-func */
+ }
+ },
+
+ // [resolvePossibleLambda]
+ //
+ // On stack, before: value, ...
+ // On stack, after: resolved value, ...
+ //
+ // If the `value` is a lambda, replace it on the stack by
+ // the return value of the lambda
+ resolvePossibleLambda: function resolvePossibleLambda() {
+ this.push([this.aliasable('container.lambda'), '(', this.popStack(), ', ', this.contextName(0), ')']);
+ },
+
+ // [pushStringParam]
+ //
+ // On stack, before: ...
+ // On stack, after: string, currentContext, ...
+ //
+ // This opcode is designed for use in string mode, which
+ // provides the string value of a parameter along with its
+ // depth rather than resolving it immediately.
+ pushStringParam: function pushStringParam(string, type) {
+ this.pushContext();
+ this.pushString(type);
+
+ // If it's a subexpression, the string result
+ // will be pushed after this opcode.
+ if (type !== 'SubExpression') {
+ if (typeof string === 'string') {
+ this.pushString(string);
+ } else {
+ this.pushStackLiteral(string);
+ }
+ }
+ },
+
+ emptyHash: function emptyHash(omitEmpty) {
+ if (this.trackIds) {
+ this.push('{}'); // hashIds
+ }
+ if (this.stringParams) {
+ this.push('{}'); // hashContexts
+ this.push('{}'); // hashTypes
+ }
+ this.pushStackLiteral(omitEmpty ? 'undefined' : '{}');
+ },
+ pushHash: function pushHash() {
+ if (this.hash) {
+ this.hashes.push(this.hash);
+ }
+ this.hash = { values: [], types: [], contexts: [], ids: [] };
+ },
+ popHash: function popHash() {
+ var hash = this.hash;
+ this.hash = this.hashes.pop();
+
+ if (this.trackIds) {
+ this.push(this.objectLiteral(hash.ids));
+ }
+ if (this.stringParams) {
+ this.push(this.objectLiteral(hash.contexts));
+ this.push(this.objectLiteral(hash.types));
+ }
+
+ this.push(this.objectLiteral(hash.values));
+ },
+
+ // [pushString]
+ //
+ // On stack, before: ...
+ // On stack, after: quotedString(string), ...
+ //
+ // Push a quoted version of `string` onto the stack
+ pushString: function pushString(string) {
+ this.pushStackLiteral(this.quotedString(string));
+ },
+
+ // [pushLiteral]
+ //
+ // On stack, before: ...
+ // On stack, after: value, ...
+ //
+ // Pushes a value onto the stack. This operation prevents
+ // the compiler from creating a temporary variable to hold
+ // it.
+ pushLiteral: function pushLiteral(value) {
+ this.pushStackLiteral(value);
+ },
+
+ // [pushProgram]
+ //
+ // On stack, before: ...
+ // On stack, after: program(guid), ...
+ //
+ // Push a program expression onto the stack. This takes
+ // a compile-time guid and converts it into a runtime-accessible
+ // expression.
+ pushProgram: function pushProgram(guid) {
+ if (guid != null) {
+ this.pushStackLiteral(this.programExpression(guid));
+ } else {
+ this.pushStackLiteral(null);
+ }
+ },
+
+ // [registerDecorator]
+ //
+ // On stack, before: hash, program, params..., ...
+ // On stack, after: ...
+ //
+ // Pops off the decorator's parameters, invokes the decorator,
+ // and inserts the decorator into the decorators list.
+ registerDecorator: function registerDecorator(paramSize, name) {
+ var foundDecorator = this.nameLookup('decorators', name, 'decorator'),
+ options = this.setupHelperArgs(name, paramSize);
+
+ this.decorators.push(['fn = ', this.decorators.functionCall(foundDecorator, '', ['fn', 'props', 'container', options]), ' || fn;']);
+ },
+
+ // [invokeHelper]
+ //
+ // On stack, before: hash, inverse, program, params..., ...
+ // On stack, after: result of helper invocation
+ //
+ // Pops off the helper's parameters, invokes the helper,
+ // and pushes the helper's return value onto the stack.
+ //
+ // If the helper is not found, `helperMissing` is called.
+ invokeHelper: function invokeHelper(paramSize, name, isSimple) {
+ var nonHelper = this.popStack(),
+ helper = this.setupHelper(paramSize, name),
+ simple = isSimple ? [helper.name, ' || '] : '';
+
+ var lookup = ['('].concat(simple, nonHelper);
+ if (!this.options.strict) {
+ lookup.push(' || ', this.aliasable('helpers.helperMissing'));
+ }
+ lookup.push(')');
+
+ this.push(this.source.functionCall(lookup, 'call', helper.callParams));
+ },
+
+ // [invokeKnownHelper]
+ //
+ // On stack, before: hash, inverse, program, params..., ...
+ // On stack, after: result of helper invocation
+ //
+ // This operation is used when the helper is known to exist,
+ // so a `helperMissing` fallback is not required.
+ invokeKnownHelper: function invokeKnownHelper(paramSize, name) {
+ var helper = this.setupHelper(paramSize, name);
+ this.push(this.source.functionCall(helper.name, 'call', helper.callParams));
+ },
+
+ // [invokeAmbiguous]
+ //
+ // On stack, before: hash, inverse, program, params..., ...
+ // On stack, after: result of disambiguation
+ //
+ // This operation is used when an expression like `{{foo}}`
+ // is provided, but we don't know at compile-time whether it
+ // is a helper or a path.
+ //
+ // This operation emits more code than the other options,
+ // and can be avoided by passing the `knownHelpers` and
+ // `knownHelpersOnly` flags at compile-time.
+ invokeAmbiguous: function invokeAmbiguous(name, helperCall) {
+ this.useRegister('helper');
+
+ var nonHelper = this.popStack();
+
+ this.emptyHash();
+ var helper = this.setupHelper(0, name, helperCall);
+
+ var helperName = this.lastHelper = this.nameLookup('helpers', name, 'helper');
+
+ var lookup = ['(', '(helper = ', helperName, ' || ', nonHelper, ')'];
+ if (!this.options.strict) {
+ lookup[0] = '(helper = ';
+ lookup.push(' != null ? helper : ', this.aliasable('helpers.helperMissing'));
+ }
+
+ this.push(['(', lookup, helper.paramsInit ? ['),(', helper.paramsInit] : [], '),', '(typeof helper === ', this.aliasable('"function"'), ' ? ', this.source.functionCall('helper', 'call', helper.callParams), ' : helper))']);
+ },
+
+ // [invokePartial]
+ //
+ // On stack, before: context, ...
+ // On stack after: result of partial invocation
+ //
+ // This operation pops off a context, invokes a partial with that context,
+ // and pushes the result of the invocation back.
+ invokePartial: function invokePartial(isDynamic, name, indent) {
+ var params = [],
+ options = this.setupParams(name, 1, params);
+
+ if (isDynamic) {
+ name = this.popStack();
+ delete options.name;
+ }
+
+ if (indent) {
+ options.indent = JSON.stringify(indent);
+ }
+ options.helpers = 'helpers';
+ options.partials = 'partials';
+ options.decorators = 'container.decorators';
+
+ if (!isDynamic) {
+ params.unshift(this.nameLookup('partials', name, 'partial'));
+ } else {
+ params.unshift(name);
+ }
+
+ if (this.options.compat) {
+ options.depths = 'depths';
+ }
+ options = this.objectLiteral(options);
+ params.push(options);
+
+ this.push(this.source.functionCall('container.invokePartial', '', params));
+ },
+
+ // [assignToHash]
+ //
+ // On stack, before: value, ..., hash, ...
+ // On stack, after: ..., hash, ...
+ //
+ // Pops a value off the stack and assigns it to the current hash
+ assignToHash: function assignToHash(key) {
+ var value = this.popStack(),
+ context = undefined,
+ type = undefined,
+ id = undefined;
+
+ if (this.trackIds) {
+ id = this.popStack();
+ }
+ if (this.stringParams) {
+ type = this.popStack();
+ context = this.popStack();
+ }
+
+ var hash = this.hash;
+ if (context) {
+ hash.contexts[key] = context;
+ }
+ if (type) {
+ hash.types[key] = type;
+ }
+ if (id) {
+ hash.ids[key] = id;
+ }
+ hash.values[key] = value;
+ },
+
+ pushId: function pushId(type, name, child) {
+ if (type === 'BlockParam') {
+ this.pushStackLiteral('blockParams[' + name[0] + '].path[' + name[1] + ']' + (child ? ' + ' + JSON.stringify('.' + child) : ''));
+ } else if (type === 'PathExpression') {
+ this.pushString(name);
+ } else if (type === 'SubExpression') {
+ this.pushStackLiteral('true');
+ } else {
+ this.pushStackLiteral('null');
+ }
+ },
+
+ // HELPERS
+
+ compiler: JavaScriptCompiler,
+
+ compileChildren: function compileChildren(environment, options) {
+ var children = environment.children,
+ child = undefined,
+ compiler = undefined;
+
+ for (var i = 0, l = children.length; i < l; i++) {
+ child = children[i];
+ compiler = new this.compiler(); // eslint-disable-line new-cap
+
+ var index = this.matchExistingProgram(child);
+
+ if (index == null) {
+ this.context.programs.push(''); // Placeholder to prevent name conflicts for nested children
+ index = this.context.programs.length;
+ child.index = index;
+ child.name = 'program' + index;
+ this.context.programs[index] = compiler.compile(child, options, this.context, !this.precompile);
+ this.context.decorators[index] = compiler.decorators;
+ this.context.environments[index] = child;
+
+ this.useDepths = this.useDepths || compiler.useDepths;
+ this.useBlockParams = this.useBlockParams || compiler.useBlockParams;
+ } else {
+ child.index = index;
+ child.name = 'program' + index;
+
+ this.useDepths = this.useDepths || child.useDepths;
+ this.useBlockParams = this.useBlockParams || child.useBlockParams;
+ }
+ }
+ },
+ matchExistingProgram: function matchExistingProgram(child) {
+ for (var i = 0, len = this.context.environments.length; i < len; i++) {
+ var environment = this.context.environments[i];
+ if (environment && environment.equals(child)) {
+ return i;
+ }
+ }
+ },
+
+ programExpression: function programExpression(guid) {
+ var child = this.environment.children[guid],
+ programParams = [child.index, 'data', child.blockParams];
+
+ if (this.useBlockParams || this.useDepths) {
+ programParams.push('blockParams');
+ }
+ if (this.useDepths) {
+ programParams.push('depths');
+ }
+
+ return 'container.program(' + programParams.join(', ') + ')';
+ },
+
+ useRegister: function useRegister(name) {
+ if (!this.registers[name]) {
+ this.registers[name] = true;
+ this.registers.list.push(name);
+ }
+ },
+
+ push: function push(expr) {
+ if (!(expr instanceof Literal)) {
+ expr = this.source.wrap(expr);
+ }
+
+ this.inlineStack.push(expr);
+ return expr;
+ },
+
+ pushStackLiteral: function pushStackLiteral(item) {
+ this.push(new Literal(item));
+ },
+
+ pushSource: function pushSource(source) {
+ if (this.pendingContent) {
+ this.source.push(this.appendToBuffer(this.source.quotedString(this.pendingContent), this.pendingLocation));
+ this.pendingContent = undefined;
+ }
+
+ if (source) {
+ this.source.push(source);
+ }
+ },
+
+ replaceStack: function replaceStack(callback) {
+ var prefix = ['('],
+ stack = undefined,
+ createdStack = undefined,
+ usedLiteral = undefined;
+
+ /* istanbul ignore next */
+ if (!this.isInline()) {
+ throw new _exception2['default']('replaceStack on non-inline');
+ }
+
+ // We want to merge the inline statement into the replacement statement via ','
+ var top = this.popStack(true);
+
+ if (top instanceof Literal) {
+ // Literals do not need to be inlined
+ stack = [top.value];
+ prefix = ['(', stack];
+ usedLiteral = true;
+ } else {
+ // Get or create the current stack name for use by the inline
+ createdStack = true;
+ var _name = this.incrStack();
+
+ prefix = ['((', this.push(_name), ' = ', top, ')'];
+ stack = this.topStack();
+ }
+
+ var item = callback.call(this, stack);
+
+ if (!usedLiteral) {
+ this.popStack();
+ }
+ if (createdStack) {
+ this.stackSlot--;
+ }
+ this.push(prefix.concat(item, ')'));
+ },
+
+ incrStack: function incrStack() {
+ this.stackSlot++;
+ if (this.stackSlot > this.stackVars.length) {
+ this.stackVars.push('stack' + this.stackSlot);
+ }
+ return this.topStackName();
+ },
+ topStackName: function topStackName() {
+ return 'stack' + this.stackSlot;
+ },
+ flushInline: function flushInline() {
+ var inlineStack = this.inlineStack;
+ this.inlineStack = [];
+ for (var i = 0, len = inlineStack.length; i < len; i++) {
+ var entry = inlineStack[i];
+ /* istanbul ignore if */
+ if (entry instanceof Literal) {
+ this.compileStack.push(entry);
+ } else {
+ var stack = this.incrStack();
+ this.pushSource([stack, ' = ', entry, ';']);
+ this.compileStack.push(stack);
+ }
+ }
+ },
+ isInline: function isInline() {
+ return this.inlineStack.length;
+ },
+
+ popStack: function popStack(wrapped) {
+ var inline = this.isInline(),
+ item = (inline ? this.inlineStack : this.compileStack).pop();
+
+ if (!wrapped && item instanceof Literal) {
+ return item.value;
+ } else {
+ if (!inline) {
+ /* istanbul ignore next */
+ if (!this.stackSlot) {
+ throw new _exception2['default']('Invalid stack pop');
+ }
+ this.stackSlot--;
+ }
+ return item;
+ }
+ },
+
+ topStack: function topStack() {
+ var stack = this.isInline() ? this.inlineStack : this.compileStack,
+ item = stack[stack.length - 1];
+
+ /* istanbul ignore if */
+ if (item instanceof Literal) {
+ return item.value;
+ } else {
+ return item;
+ }
+ },
+
+ contextName: function contextName(context) {
+ if (this.useDepths && context) {
+ return 'depths[' + context + ']';
+ } else {
+ return 'depth' + context;
+ }
+ },
+
+ quotedString: function quotedString(str) {
+ return this.source.quotedString(str);
+ },
+
+ objectLiteral: function objectLiteral(obj) {
+ return this.source.objectLiteral(obj);
+ },
+
+ aliasable: function aliasable(name) {
+ var ret = this.aliases[name];
+ if (ret) {
+ ret.referenceCount++;
+ return ret;
+ }
+
+ ret = this.aliases[name] = this.source.wrap(name);
+ ret.aliasable = true;
+ ret.referenceCount = 1;
+
+ return ret;
+ },
+
+ setupHelper: function setupHelper(paramSize, name, blockHelper) {
+ var params = [],
+ paramsInit = this.setupHelperArgs(name, paramSize, params, blockHelper);
+ var foundHelper = this.nameLookup('helpers', name, 'helper'),
+ callContext = this.aliasable(this.contextName(0) + ' != null ? ' + this.contextName(0) + ' : {}');
+
+ return {
+ params: params,
+ paramsInit: paramsInit,
+ name: foundHelper,
+ callParams: [callContext].concat(params)
+ };
+ },
+
+ setupParams: function setupParams(helper, paramSize, params) {
+ var options = {},
+ contexts = [],
+ types = [],
+ ids = [],
+ objectArgs = !params,
+ param = undefined;
+
+ if (objectArgs) {
+ params = [];
+ }
+
+ options.name = this.quotedString(helper);
+ options.hash = this.popStack();
+
+ if (this.trackIds) {
+ options.hashIds = this.popStack();
+ }
+ if (this.stringParams) {
+ options.hashTypes = this.popStack();
+ options.hashContexts = this.popStack();
+ }
+
+ var inverse = this.popStack(),
+ program = this.popStack();
+
+ // Avoid setting fn and inverse if neither are set. This allows
+ // helpers to do a check for `if (options.fn)`
+ if (program || inverse) {
+ options.fn = program || 'container.noop';
+ options.inverse = inverse || 'container.noop';
+ }
+
+ // The parameters go on to the stack in order (making sure that they are evaluated in order)
+ // so we need to pop them off the stack in reverse order
+ var i = paramSize;
+ while (i--) {
+ param = this.popStack();
+ params[i] = param;
+
+ if (this.trackIds) {
+ ids[i] = this.popStack();
+ }
+ if (this.stringParams) {
+ types[i] = this.popStack();
+ contexts[i] = this.popStack();
+ }
+ }
+
+ if (objectArgs) {
+ options.args = this.source.generateArray(params);
+ }
+
+ if (this.trackIds) {
+ options.ids = this.source.generateArray(ids);
+ }
+ if (this.stringParams) {
+ options.types = this.source.generateArray(types);
+ options.contexts = this.source.generateArray(contexts);
+ }
+
+ if (this.options.data) {
+ options.data = 'data';
+ }
+ if (this.useBlockParams) {
+ options.blockParams = 'blockParams';
+ }
+ return options;
+ },
+
+ setupHelperArgs: function setupHelperArgs(helper, paramSize, params, useRegister) {
+ var options = this.setupParams(helper, paramSize, params);
+ options = this.objectLiteral(options);
+ if (useRegister) {
+ this.useRegister('options');
+ params.push('options');
+ return ['options=', options];
+ } else if (params) {
+ params.push(options);
+ return '';
+ } else {
+ return options;
+ }
+ }
+ };
+
+ (function () {
+ var reservedWords = ('break else new var' + ' case finally return void' + ' catch for switch while' + ' continue function this with' + ' default if throw' + ' delete in try' + ' do instanceof typeof' + ' abstract enum int short' + ' boolean export interface static' + ' byte extends long super' + ' char final native synchronized' + ' class float package throws' + ' const goto private transient' + ' debugger implements protected volatile' + ' double import public let yield await' + ' null true false').split(' ');
+
+ var compilerWords = JavaScriptCompiler.RESERVED_WORDS = {};
+
+ for (var i = 0, l = reservedWords.length; i < l; i++) {
+ compilerWords[reservedWords[i]] = true;
+ }
+ })();
+
+ JavaScriptCompiler.isValidJavaScriptVariableName = function (name) {
+ return !JavaScriptCompiler.RESERVED_WORDS[name] && /^[a-zA-Z_$][0-9a-zA-Z_$]*$/.test(name);
+ };
+
+ function strictLookup(requireTerminal, compiler, parts, type) {
+ var stack = compiler.popStack(),
+ i = 0,
+ len = parts.length;
+ if (requireTerminal) {
+ len--;
+ }
+
+ for (; i < len; i++) {
+ stack = compiler.nameLookup(stack, parts[i], type);
+ }
+
+ if (requireTerminal) {
+ return [compiler.aliasable('container.strict'), '(', stack, ', ', compiler.quotedString(parts[i]), ')'];
+ } else {
+ return stack;
+ }
+ }
+
+ exports['default'] = JavaScriptCompiler;
+ module.exports = exports['default'];
+
+/***/ },
+/* 29 */
+/***/ function(module, exports, __webpack_require__) {
+
+ /* global define */
+ 'use strict';
+
+ exports.__esModule = true;
+
+ var _utils = __webpack_require__(5);
+
+ var SourceNode = undefined;
+
+ try {
+ /* istanbul ignore next */
+ if (false) {
+ // We don't support this in AMD environments. For these environments, we asusme that
+ // they are running on the browser and thus have no need for the source-map library.
+ var SourceMap = require('source-map');
+ SourceNode = SourceMap.SourceNode;
+ }
+ } catch (err) {}
+ /* NOP */
+
+ /* istanbul ignore if: tested but not covered in istanbul due to dist build */
+ if (!SourceNode) {
+ SourceNode = function (line, column, srcFile, chunks) {
+ this.src = '';
+ if (chunks) {
+ this.add(chunks);
+ }
+ };
+ /* istanbul ignore next */
+ SourceNode.prototype = {
+ add: function add(chunks) {
+ if (_utils.isArray(chunks)) {
+ chunks = chunks.join('');
+ }
+ this.src += chunks;
+ },
+ prepend: function prepend(chunks) {
+ if (_utils.isArray(chunks)) {
+ chunks = chunks.join('');
+ }
+ this.src = chunks + this.src;
+ },
+ toStringWithSourceMap: function toStringWithSourceMap() {
+ return { code: this.toString() };
+ },
+ toString: function toString() {
+ return this.src;
+ }
+ };
+ }
+
+ function castChunk(chunk, codeGen, loc) {
+ if (_utils.isArray(chunk)) {
+ var ret = [];
+
+ for (var i = 0, len = chunk.length; i < len; i++) {
+ ret.push(codeGen.wrap(chunk[i], loc));
+ }
+ return ret;
+ } else if (typeof chunk === 'boolean' || typeof chunk === 'number') {
+ // Handle primitives that the SourceNode will throw up on
+ return chunk + '';
+ }
+ return chunk;
+ }
+
+ function CodeGen(srcFile) {
+ this.srcFile = srcFile;
+ this.source = [];
+ }
+
+ CodeGen.prototype = {
+ isEmpty: function isEmpty() {
+ return !this.source.length;
+ },
+ prepend: function prepend(source, loc) {
+ this.source.unshift(this.wrap(source, loc));
+ },
+ push: function push(source, loc) {
+ this.source.push(this.wrap(source, loc));
+ },
+
+ merge: function merge() {
+ var source = this.empty();
+ this.each(function (line) {
+ source.add([' ', line, '\n']);
+ });
+ return source;
+ },
+
+ each: function each(iter) {
+ for (var i = 0, len = this.source.length; i < len; i++) {
+ iter(this.source[i]);
+ }
+ },
+
+ empty: function empty() {
+ var loc = this.currentLocation || { start: {} };
+ return new SourceNode(loc.start.line, loc.start.column, this.srcFile);
+ },
+ wrap: function wrap(chunk) {
+ var loc = arguments.length <= 1 || arguments[1] === undefined ? this.currentLocation || { start: {} } : arguments[1];
+
+ if (chunk instanceof SourceNode) {
+ return chunk;
+ }
+
+ chunk = castChunk(chunk, this, loc);
+
+ return new SourceNode(loc.start.line, loc.start.column, this.srcFile, chunk);
+ },
+
+ functionCall: function functionCall(fn, type, params) {
+ params = this.generateList(params);
+ return this.wrap([fn, type ? '.' + type + '(' : '(', params, ')']);
+ },
+
+ quotedString: function quotedString(str) {
+ return '"' + (str + '').replace(/\\/g, '\\\\').replace(/"/g, '\\"').replace(/\n/g, '\\n').replace(/\r/g, '\\r').replace(/\u2028/g, '\\u2028') // Per Ecma-262 7.3 + 7.8.4
+ .replace(/\u2029/g, '\\u2029') + '"';
+ },
+
+ objectLiteral: function objectLiteral(obj) {
+ var pairs = [];
+
+ for (var key in obj) {
+ if (obj.hasOwnProperty(key)) {
+ var value = castChunk(obj[key], this);
+ if (value !== 'undefined') {
+ pairs.push([this.quotedString(key), ':', value]);
+ }
+ }
+ }
+
+ var ret = this.generateList(pairs);
+ ret.prepend('{');
+ ret.add('}');
+ return ret;
+ },
+
+ generateList: function generateList(entries) {
+ var ret = this.empty();
+
+ for (var i = 0, len = entries.length; i < len; i++) {
+ if (i) {
+ ret.add(',');
+ }
+
+ ret.add(castChunk(entries[i], this));
+ }
+
+ return ret;
+ },
+
+ generateArray: function generateArray(entries) {
+ var ret = this.generateList(entries);
+ ret.prepend('[');
+ ret.add(']');
+
+ return ret;
+ }
+ };
+
+ exports['default'] = CodeGen;
+ module.exports = exports['default'];
+
+/***/ }
+/******/ ])
+});
+; \ No newline at end of file
diff --git a/ydb/core/viewer/content/api/lib/highlight.9.1.0.pack.js b/ydb/core/viewer/content/api/lib/highlight.9.1.0.pack.js
index 720093fd79c..928386d4402 100644
--- a/ydb/core/viewer/content/api/lib/highlight.9.1.0.pack.js
+++ b/ydb/core/viewer/content/api/lib/highlight.9.1.0.pack.js
@@ -1,2 +1,2 @@
-/*! highlight.js v9.1.0 | BSD3 License | git.io/hljslicense */
-!function(e){"undefined"!=typeof exports?e(exports):(self.hljs=e({}),"function"==typeof define&&define.amd&&define("hljs",[],function(){return self.hljs}))}(function(e){function n(e){return e.replace(/&/gm,"&amp;").replace(/</gm,"&lt;").replace(/>/gm,"&gt;")}function t(e){return e.nodeName.toLowerCase()}function r(e,n){var t=e&&e.exec(n);return t&&0==t.index}function a(e){return/^(no-?highlight|plain|text)$/i.test(e)}function i(e){var n,t,r,i=e.className+" ";if(i+=e.parentNode?e.parentNode.className:"",t=/\blang(?:uage)?-([\w-]+)\b/i.exec(i))return E(t[1])?t[1]:"no-highlight";for(i=i.split(/\s+/),n=0,r=i.length;r>n;n++)if(E(i[n])||a(i[n]))return i[n]}function o(e,n){var t,r={};for(t in e)r[t]=e[t];if(n)for(t in n)r[t]=n[t];return r}function u(e){var n=[];return function r(e,a){for(var i=e.firstChild;i;i=i.nextSibling)3==i.nodeType?a+=i.nodeValue.length:1==i.nodeType&&(n.push({event:"start",offset:a,node:i}),a=r(i,a),t(i).match(/br|hr|img|input/)||n.push({event:"stop",offset:a,node:i}));return a}(e,0),n}function c(e,r,a){function i(){return e.length&&r.length?e[0].offset!=r[0].offset?e[0].offset<r[0].offset?e:r:"start"==r[0].event?e:r:e.length?e:r}function o(e){function r(e){return" "+e.nodeName+'="'+n(e.value)+'"'}l+="<"+t(e)+Array.prototype.map.call(e.attributes,r).join("")+">"}function u(e){l+="</"+t(e)+">"}function c(e){("start"==e.event?o:u)(e.node)}for(var s=0,l="",f=[];e.length||r.length;){var g=i();if(l+=n(a.substr(s,g[0].offset-s)),s=g[0].offset,g==e){f.reverse().forEach(u);do c(g.splice(0,1)[0]),g=i();while(g==e&&g.length&&g[0].offset==s);f.reverse().forEach(o)}else"start"==g[0].event?f.push(g[0].node):f.pop(),c(g.splice(0,1)[0])}return l+n(a.substr(s))}function s(e){function n(e){return e&&e.source||e}function t(t,r){return new RegExp(n(t),"m"+(e.cI?"i":"")+(r?"g":""))}function r(a,i){if(!a.compiled){if(a.compiled=!0,a.k=a.k||a.bK,a.k){var u={},c=function(n,t){e.cI&&(t=t.toLowerCase()),t.split(" ").forEach(function(e){var t=e.split("|");u[t[0]]=[n,t[1]?Number(t[1]):1]})};"string"==typeof a.k?c("keyword",a.k):Object.keys(a.k).forEach(function(e){c(e,a.k[e])}),a.k=u}a.lR=t(a.l||/\b\w+\b/,!0),i&&(a.bK&&(a.b="\\b("+a.bK.split(" ").join("|")+")\\b"),a.b||(a.b=/\B|\b/),a.bR=t(a.b),a.e||a.eW||(a.e=/\B|\b/),a.e&&(a.eR=t(a.e)),a.tE=n(a.e)||"",a.eW&&i.tE&&(a.tE+=(a.e?"|":"")+i.tE)),a.i&&(a.iR=t(a.i)),void 0===a.r&&(a.r=1),a.c||(a.c=[]);var s=[];a.c.forEach(function(e){e.v?e.v.forEach(function(n){s.push(o(e,n))}):s.push("self"==e?a:e)}),a.c=s,a.c.forEach(function(e){r(e,a)}),a.starts&&r(a.starts,i);var l=a.c.map(function(e){return e.bK?"\\.?("+e.b+")\\.?":e.b}).concat([a.tE,a.i]).map(n).filter(Boolean);a.t=l.length?t(l.join("|"),!0):{exec:function(){return null}}}}r(e)}function l(e,t,a,i){function o(e,n){for(var t=0;t<n.c.length;t++)if(r(n.c[t].bR,e))return n.c[t]}function u(e,n){if(r(e.eR,n)){for(;e.endsParent&&e.parent;)e=e.parent;return e}return e.eW?u(e.parent,n):void 0}function c(e,n){return!a&&r(n.iR,e)}function g(e,n){var t=N.cI?n[0].toLowerCase():n[0];return e.k.hasOwnProperty(t)&&e.k[t]}function h(e,n,t,r){var a=r?"":x.classPrefix,i='<span class="'+a,o=t?"":"</span>";return i+=e+'">',i+n+o}function p(){if(!L.k)return n(M);var e="",t=0;L.lR.lastIndex=0;for(var r=L.lR.exec(M);r;){e+=n(M.substr(t,r.index-t));var a=g(L,r);a?(B+=a[1],e+=h(a[0],n(r[0]))):e+=n(r[0]),t=L.lR.lastIndex,r=L.lR.exec(M)}return e+n(M.substr(t))}function d(){var e="string"==typeof L.sL;if(e&&!R[L.sL])return n(M);var t=e?l(L.sL,M,!0,y[L.sL]):f(M,L.sL.length?L.sL:void 0);return L.r>0&&(B+=t.r),e&&(y[L.sL]=t.top),h(t.language,t.value,!1,!0)}function b(){return void 0!==L.sL?d():p()}function v(e,t){var r=e.cN?h(e.cN,"",!0):"";e.rB?(k+=r,M=""):e.eB?(k+=n(t)+r,M=""):(k+=r,M=t),L=Object.create(e,{parent:{value:L}})}function m(e,t){if(M+=e,void 0===t)return k+=b(),0;var r=o(t,L);if(r)return k+=b(),v(r,t),r.rB?0:t.length;var a=u(L,t);if(a){var i=L;i.rE||i.eE||(M+=t),k+=b();do L.cN&&(k+="</span>"),B+=L.r,L=L.parent;while(L!=a.parent);return i.eE&&(k+=n(t)),M="",a.starts&&v(a.starts,""),i.rE?0:t.length}if(c(t,L))throw new Error('Illegal lexeme "'+t+'" for mode "'+(L.cN||"<unnamed>")+'"');return M+=t,t.length||1}var N=E(e);if(!N)throw new Error('Unknown language: "'+e+'"');s(N);var w,L=i||N,y={},k="";for(w=L;w!=N;w=w.parent)w.cN&&(k=h(w.cN,"",!0)+k);var M="",B=0;try{for(var C,j,I=0;;){if(L.t.lastIndex=I,C=L.t.exec(t),!C)break;j=m(t.substr(I,C.index-I),C[0]),I=C.index+j}for(m(t.substr(I)),w=L;w.parent;w=w.parent)w.cN&&(k+="</span>");return{r:B,value:k,language:e,top:L}}catch(O){if(-1!=O.message.indexOf("Illegal"))return{r:0,value:n(t)};throw O}}function f(e,t){t=t||x.languages||Object.keys(R);var r={r:0,value:n(e)},a=r;return t.forEach(function(n){if(E(n)){var t=l(n,e,!1);t.language=n,t.r>a.r&&(a=t),t.r>r.r&&(a=r,r=t)}}),a.language&&(r.second_best=a),r}function g(e){return x.tabReplace&&(e=e.replace(/^((<[^>]+>|\t)+)/gm,function(e,n){return n.replace(/\t/g,x.tabReplace)})),x.useBR&&(e=e.replace(/\n/g,"<br>")),e}function h(e,n,t){var r=n?w[n]:t,a=[e.trim()];return e.match(/\bhljs\b/)||a.push("hljs"),-1===e.indexOf(r)&&a.push(r),a.join(" ").trim()}function p(e){var n=i(e);if(!a(n)){var t;x.useBR?(t=document.createElementNS("http://www.w3.org/1999/xhtml","div"),t.innerHTML=e.innerHTML.replace(/\n/g,"").replace(/<br[ \/]*>/g,"\n")):t=e;var r=t.textContent,o=n?l(n,r,!0):f(r),s=u(t);if(s.length){var p=document.createElementNS("http://www.w3.org/1999/xhtml","div");p.innerHTML=o.value,o.value=c(s,u(p),r)}o.value=g(o.value),e.innerHTML=o.value,e.className=h(e.className,n,o.language),e.result={language:o.language,re:o.r},o.second_best&&(e.second_best={language:o.second_best.language,re:o.second_best.r})}}function d(e){x=o(x,e)}function b(){if(!b.called){b.called=!0;var e=document.querySelectorAll("pre code");Array.prototype.forEach.call(e,p)}}function v(){addEventListener("DOMContentLoaded",b,!1),addEventListener("load",b,!1)}function m(n,t){var r=R[n]=t(e);r.aliases&&r.aliases.forEach(function(e){w[e]=n})}function N(){return Object.keys(R)}function E(e){return e=(e||"").toLowerCase(),R[e]||R[w[e]]}var x={classPrefix:"hljs-",tabReplace:null,useBR:!1,languages:void 0},R={},w={};return e.highlight=l,e.highlightAuto=f,e.fixMarkup=g,e.highlightBlock=p,e.configure=d,e.initHighlighting=b,e.initHighlightingOnLoad=v,e.registerLanguage=m,e.listLanguages=N,e.getLanguage=E,e.inherit=o,e.IR="[a-zA-Z]\\w*",e.UIR="[a-zA-Z_]\\w*",e.NR="\\b\\d+(\\.\\d+)?",e.CNR="(-?)(\\b0[xX][a-fA-F0-9]+|(\\b\\d+(\\.\\d*)?|\\.\\d+)([eE][-+]?\\d+)?)",e.BNR="\\b(0b[01]+)",e.RSR="!|!=|!==|%|%=|&|&&|&=|\\*|\\*=|\\+|\\+=|,|-|-=|/=|/|:|;|<<|<<=|<=|<|===|==|=|>>>=|>>=|>=|>>>|>>|>|\\?|\\[|\\{|\\(|\\^|\\^=|\\||\\|=|\\|\\||~",e.BE={b:"\\\\[\\s\\S]",r:0},e.ASM={cN:"string",b:"'",e:"'",i:"\\n",c:[e.BE]},e.QSM={cN:"string",b:'"',e:'"',i:"\\n",c:[e.BE]},e.PWM={b:/\b(a|an|the|are|I|I'm|isn't|don't|doesn't|won't|but|just|should|pretty|simply|enough|gonna|going|wtf|so|such|will|you|your|like)\b/},e.C=function(n,t,r){var a=e.inherit({cN:"comment",b:n,e:t,c:[]},r||{});return a.c.push(e.PWM),a.c.push({cN:"doctag",b:"(?:TODO|FIXME|NOTE|BUG|XXX):",r:0}),a},e.CLCM=e.C("//","$"),e.CBCM=e.C("/\\*","\\*/"),e.HCM=e.C("#","$"),e.NM={cN:"number",b:e.NR,r:0},e.CNM={cN:"number",b:e.CNR,r:0},e.BNM={cN:"number",b:e.BNR,r:0},e.CSSNM={cN:"number",b:e.NR+"(%|em|ex|ch|rem|vw|vh|vmin|vmax|cm|mm|in|pt|pc|px|deg|grad|rad|turn|s|ms|Hz|kHz|dpi|dpcm|dppx)?",r:0},e.RM={cN:"regexp",b:/\//,e:/\/[gimuy]*/,i:/\n/,c:[e.BE,{b:/\[/,e:/\]/,r:0,c:[e.BE]}]},e.TM={cN:"title",b:e.IR,r:0},e.UTM={cN:"title",b:e.UIR,r:0},e});hljs.registerLanguage("json",function(e){var t={literal:"true false null"},i=[e.QSM,e.CNM],r={e:",",eW:!0,eE:!0,c:i,k:t},s={b:"{",e:"}",c:[{cN:"attr",b:'\\s*"',e:'"\\s*:\\s*',eB:!0,eE:!0,c:[e.BE],i:"\\n",starts:r}],i:"\\S"},n={b:"\\[",e:"\\]",c:[e.inherit(r)],i:"\\S"};return i.splice(i.length,0,s,n),{c:i,k:t,i:"\\S"}});hljs.registerLanguage("xml",function(s){var t="[A-Za-z0-9\\._:-]+",e={b:/<\?(php)?(?!\w)/,e:/\?>/,sL:"php"},r={eW:!0,i:/</,r:0,c:[e,{cN:"attr",b:t,r:0},{b:"=",r:0,c:[{cN:"string",c:[e],v:[{b:/"/,e:/"/},{b:/'/,e:/'/},{b:/[^\s\/>]+/}]}]}]};return{aliases:["html","xhtml","rss","atom","xsl","plist"],cI:!0,c:[{cN:"meta",b:"<!DOCTYPE",e:">",r:10,c:[{b:"\\[",e:"\\]"}]},s.C("<!--","-->",{r:10}),{b:"<\\!\\[CDATA\\[",e:"\\]\\]>",r:10},{cN:"tag",b:"<style(?=\\s|>|$)",e:">",k:{name:"style"},c:[r],starts:{e:"</style>",rE:!0,sL:["css","xml"]}},{cN:"tag",b:"<script(?=\\s|>|$)",e:">",k:{name:"script"},c:[r],starts:{e:"</script>",rE:!0,sL:["actionscript","javascript","handlebars","xml"]}},e,{cN:"meta",b:/<\?\w+/,e:/\?>/,r:10},{cN:"tag",b:"</?",e:"/?>",c:[{cN:"name",b:/[^\/><\s]+/,r:0},r]}]}});hljs.registerLanguage("javascript",function(e){return{aliases:["js"],k:{keyword:"in of if for while finally var new function do return void else break catch instanceof with throw case default try this switch continue typeof delete let yield const export super debugger as async await import from as",literal:"true false null undefined NaN Infinity",built_in:"eval isFinite isNaN parseFloat parseInt decodeURI decodeURIComponent encodeURI encodeURIComponent escape unescape Object Function Boolean Error EvalError InternalError RangeError ReferenceError StopIteration SyntaxError TypeError URIError Number Math Date String RegExp Array Float32Array Float64Array Int16Array Int32Array Int8Array Uint16Array Uint32Array Uint8Array Uint8ClampedArray ArrayBuffer DataView JSON Intl arguments require module console window document Symbol Set Map WeakSet WeakMap Proxy Reflect Promise"},c:[{cN:"meta",r:10,b:/^\s*['"]use (strict|asm)['"]/},{cN:"meta",b:/^#!/,e:/$/},e.ASM,e.QSM,{cN:"string",b:"`",e:"`",c:[e.BE,{cN:"subst",b:"\\$\\{",e:"\\}"}]},e.CLCM,e.CBCM,{cN:"number",v:[{b:"\\b(0[bB][01]+)"},{b:"\\b(0[oO][0-7]+)"},{b:e.CNR}],r:0},{b:"("+e.RSR+"|\\b(case|return|throw)\\b)\\s*",k:"return throw case",c:[e.CLCM,e.CBCM,e.RM,{b:/</,e:/>\s*[);\]]/,r:0,sL:"xml"}],r:0},{cN:"function",bK:"function",e:/\{/,eE:!0,c:[e.inherit(e.TM,{b:/[A-Za-z$_][0-9A-Za-z$_]*/}),{cN:"params",b:/\(/,e:/\)/,eB:!0,eE:!0,c:[e.CLCM,e.CBCM]}],i:/\[|%/},{b:/\$[(.]/},{b:"\\."+e.IR,r:0},{cN:"class",bK:"class",e:/[{;=]/,eE:!0,i:/[:"\[\]]/,c:[{bK:"extends"},e.UTM]},{bK:"constructor",e:/\{/,eE:!0}],i:/#(?!!)/}});hljs.registerLanguage("css",function(e){var c="[a-zA-Z-][a-zA-Z0-9_-]*",t={b:/[A-Z\_\.\-]+\s*:/,rB:!0,e:";",eW:!0,c:[{cN:"attribute",b:/\S/,e:":",eE:!0,starts:{eW:!0,eE:!0,c:[{b:/[\w-]+\s*\(/,rB:!0,c:[{cN:"built_in",b:/[\w-]+/}]},e.CSSNM,e.QSM,e.ASM,e.CBCM,{cN:"number",b:"#[0-9A-Fa-f]+"},{cN:"meta",b:"!important"}]}}]};return{cI:!0,i:/[=\/|'\$]/,c:[e.CBCM,{cN:"selector-id",b:/#[A-Za-z0-9_-]+/},{cN:"selector-class",b:/\.[A-Za-z0-9_-]+/},{cN:"selector-attr",b:/\[/,e:/\]/,i:"$"},{cN:"selector-pseudo",b:/:(:)?[a-zA-Z0-9\_\-\+\(\)"'.]+/},{b:"@(font-face|page)",l:"[a-z-]+",k:"font-face page"},{b:"@",e:"[{;]",c:[{cN:"keyword",b:/\S+/},{b:/\s/,eW:!0,eE:!0,r:0,c:[e.ASM,e.QSM,e.CSSNM]}]},{cN:"selector-tag",b:c,r:0},{b:"{",e:"}",i:/\S/,c:[e.CBCM,t]}]}}); \ No newline at end of file
+/*! highlight.js v9.1.0 | BSD3 License | git.io/hljslicense */
+!function(e){"undefined"!=typeof exports?e(exports):(self.hljs=e({}),"function"==typeof define&&define.amd&&define("hljs",[],function(){return self.hljs}))}(function(e){function n(e){return e.replace(/&/gm,"&amp;").replace(/</gm,"&lt;").replace(/>/gm,"&gt;")}function t(e){return e.nodeName.toLowerCase()}function r(e,n){var t=e&&e.exec(n);return t&&0==t.index}function a(e){return/^(no-?highlight|plain|text)$/i.test(e)}function i(e){var n,t,r,i=e.className+" ";if(i+=e.parentNode?e.parentNode.className:"",t=/\blang(?:uage)?-([\w-]+)\b/i.exec(i))return E(t[1])?t[1]:"no-highlight";for(i=i.split(/\s+/),n=0,r=i.length;r>n;n++)if(E(i[n])||a(i[n]))return i[n]}function o(e,n){var t,r={};for(t in e)r[t]=e[t];if(n)for(t in n)r[t]=n[t];return r}function u(e){var n=[];return function r(e,a){for(var i=e.firstChild;i;i=i.nextSibling)3==i.nodeType?a+=i.nodeValue.length:1==i.nodeType&&(n.push({event:"start",offset:a,node:i}),a=r(i,a),t(i).match(/br|hr|img|input/)||n.push({event:"stop",offset:a,node:i}));return a}(e,0),n}function c(e,r,a){function i(){return e.length&&r.length?e[0].offset!=r[0].offset?e[0].offset<r[0].offset?e:r:"start"==r[0].event?e:r:e.length?e:r}function o(e){function r(e){return" "+e.nodeName+'="'+n(e.value)+'"'}l+="<"+t(e)+Array.prototype.map.call(e.attributes,r).join("")+">"}function u(e){l+="</"+t(e)+">"}function c(e){("start"==e.event?o:u)(e.node)}for(var s=0,l="",f=[];e.length||r.length;){var g=i();if(l+=n(a.substr(s,g[0].offset-s)),s=g[0].offset,g==e){f.reverse().forEach(u);do c(g.splice(0,1)[0]),g=i();while(g==e&&g.length&&g[0].offset==s);f.reverse().forEach(o)}else"start"==g[0].event?f.push(g[0].node):f.pop(),c(g.splice(0,1)[0])}return l+n(a.substr(s))}function s(e){function n(e){return e&&e.source||e}function t(t,r){return new RegExp(n(t),"m"+(e.cI?"i":"")+(r?"g":""))}function r(a,i){if(!a.compiled){if(a.compiled=!0,a.k=a.k||a.bK,a.k){var u={},c=function(n,t){e.cI&&(t=t.toLowerCase()),t.split(" ").forEach(function(e){var t=e.split("|");u[t[0]]=[n,t[1]?Number(t[1]):1]})};"string"==typeof a.k?c("keyword",a.k):Object.keys(a.k).forEach(function(e){c(e,a.k[e])}),a.k=u}a.lR=t(a.l||/\b\w+\b/,!0),i&&(a.bK&&(a.b="\\b("+a.bK.split(" ").join("|")+")\\b"),a.b||(a.b=/\B|\b/),a.bR=t(a.b),a.e||a.eW||(a.e=/\B|\b/),a.e&&(a.eR=t(a.e)),a.tE=n(a.e)||"",a.eW&&i.tE&&(a.tE+=(a.e?"|":"")+i.tE)),a.i&&(a.iR=t(a.i)),void 0===a.r&&(a.r=1),a.c||(a.c=[]);var s=[];a.c.forEach(function(e){e.v?e.v.forEach(function(n){s.push(o(e,n))}):s.push("self"==e?a:e)}),a.c=s,a.c.forEach(function(e){r(e,a)}),a.starts&&r(a.starts,i);var l=a.c.map(function(e){return e.bK?"\\.?("+e.b+")\\.?":e.b}).concat([a.tE,a.i]).map(n).filter(Boolean);a.t=l.length?t(l.join("|"),!0):{exec:function(){return null}}}}r(e)}function l(e,t,a,i){function o(e,n){for(var t=0;t<n.c.length;t++)if(r(n.c[t].bR,e))return n.c[t]}function u(e,n){if(r(e.eR,n)){for(;e.endsParent&&e.parent;)e=e.parent;return e}return e.eW?u(e.parent,n):void 0}function c(e,n){return!a&&r(n.iR,e)}function g(e,n){var t=N.cI?n[0].toLowerCase():n[0];return e.k.hasOwnProperty(t)&&e.k[t]}function h(e,n,t,r){var a=r?"":x.classPrefix,i='<span class="'+a,o=t?"":"</span>";return i+=e+'">',i+n+o}function p(){if(!L.k)return n(M);var e="",t=0;L.lR.lastIndex=0;for(var r=L.lR.exec(M);r;){e+=n(M.substr(t,r.index-t));var a=g(L,r);a?(B+=a[1],e+=h(a[0],n(r[0]))):e+=n(r[0]),t=L.lR.lastIndex,r=L.lR.exec(M)}return e+n(M.substr(t))}function d(){var e="string"==typeof L.sL;if(e&&!R[L.sL])return n(M);var t=e?l(L.sL,M,!0,y[L.sL]):f(M,L.sL.length?L.sL:void 0);return L.r>0&&(B+=t.r),e&&(y[L.sL]=t.top),h(t.language,t.value,!1,!0)}function b(){return void 0!==L.sL?d():p()}function v(e,t){var r=e.cN?h(e.cN,"",!0):"";e.rB?(k+=r,M=""):e.eB?(k+=n(t)+r,M=""):(k+=r,M=t),L=Object.create(e,{parent:{value:L}})}function m(e,t){if(M+=e,void 0===t)return k+=b(),0;var r=o(t,L);if(r)return k+=b(),v(r,t),r.rB?0:t.length;var a=u(L,t);if(a){var i=L;i.rE||i.eE||(M+=t),k+=b();do L.cN&&(k+="</span>"),B+=L.r,L=L.parent;while(L!=a.parent);return i.eE&&(k+=n(t)),M="",a.starts&&v(a.starts,""),i.rE?0:t.length}if(c(t,L))throw new Error('Illegal lexeme "'+t+'" for mode "'+(L.cN||"<unnamed>")+'"');return M+=t,t.length||1}var N=E(e);if(!N)throw new Error('Unknown language: "'+e+'"');s(N);var w,L=i||N,y={},k="";for(w=L;w!=N;w=w.parent)w.cN&&(k=h(w.cN,"",!0)+k);var M="",B=0;try{for(var C,j,I=0;;){if(L.t.lastIndex=I,C=L.t.exec(t),!C)break;j=m(t.substr(I,C.index-I),C[0]),I=C.index+j}for(m(t.substr(I)),w=L;w.parent;w=w.parent)w.cN&&(k+="</span>");return{r:B,value:k,language:e,top:L}}catch(O){if(-1!=O.message.indexOf("Illegal"))return{r:0,value:n(t)};throw O}}function f(e,t){t=t||x.languages||Object.keys(R);var r={r:0,value:n(e)},a=r;return t.forEach(function(n){if(E(n)){var t=l(n,e,!1);t.language=n,t.r>a.r&&(a=t),t.r>r.r&&(a=r,r=t)}}),a.language&&(r.second_best=a),r}function g(e){return x.tabReplace&&(e=e.replace(/^((<[^>]+>|\t)+)/gm,function(e,n){return n.replace(/\t/g,x.tabReplace)})),x.useBR&&(e=e.replace(/\n/g,"<br>")),e}function h(e,n,t){var r=n?w[n]:t,a=[e.trim()];return e.match(/\bhljs\b/)||a.push("hljs"),-1===e.indexOf(r)&&a.push(r),a.join(" ").trim()}function p(e){var n=i(e);if(!a(n)){var t;x.useBR?(t=document.createElementNS("http://www.w3.org/1999/xhtml","div"),t.innerHTML=e.innerHTML.replace(/\n/g,"").replace(/<br[ \/]*>/g,"\n")):t=e;var r=t.textContent,o=n?l(n,r,!0):f(r),s=u(t);if(s.length){var p=document.createElementNS("http://www.w3.org/1999/xhtml","div");p.innerHTML=o.value,o.value=c(s,u(p),r)}o.value=g(o.value),e.innerHTML=o.value,e.className=h(e.className,n,o.language),e.result={language:o.language,re:o.r},o.second_best&&(e.second_best={language:o.second_best.language,re:o.second_best.r})}}function d(e){x=o(x,e)}function b(){if(!b.called){b.called=!0;var e=document.querySelectorAll("pre code");Array.prototype.forEach.call(e,p)}}function v(){addEventListener("DOMContentLoaded",b,!1),addEventListener("load",b,!1)}function m(n,t){var r=R[n]=t(e);r.aliases&&r.aliases.forEach(function(e){w[e]=n})}function N(){return Object.keys(R)}function E(e){return e=(e||"").toLowerCase(),R[e]||R[w[e]]}var x={classPrefix:"hljs-",tabReplace:null,useBR:!1,languages:void 0},R={},w={};return e.highlight=l,e.highlightAuto=f,e.fixMarkup=g,e.highlightBlock=p,e.configure=d,e.initHighlighting=b,e.initHighlightingOnLoad=v,e.registerLanguage=m,e.listLanguages=N,e.getLanguage=E,e.inherit=o,e.IR="[a-zA-Z]\\w*",e.UIR="[a-zA-Z_]\\w*",e.NR="\\b\\d+(\\.\\d+)?",e.CNR="(-?)(\\b0[xX][a-fA-F0-9]+|(\\b\\d+(\\.\\d*)?|\\.\\d+)([eE][-+]?\\d+)?)",e.BNR="\\b(0b[01]+)",e.RSR="!|!=|!==|%|%=|&|&&|&=|\\*|\\*=|\\+|\\+=|,|-|-=|/=|/|:|;|<<|<<=|<=|<|===|==|=|>>>=|>>=|>=|>>>|>>|>|\\?|\\[|\\{|\\(|\\^|\\^=|\\||\\|=|\\|\\||~",e.BE={b:"\\\\[\\s\\S]",r:0},e.ASM={cN:"string",b:"'",e:"'",i:"\\n",c:[e.BE]},e.QSM={cN:"string",b:'"',e:'"',i:"\\n",c:[e.BE]},e.PWM={b:/\b(a|an|the|are|I|I'm|isn't|don't|doesn't|won't|but|just|should|pretty|simply|enough|gonna|going|wtf|so|such|will|you|your|like)\b/},e.C=function(n,t,r){var a=e.inherit({cN:"comment",b:n,e:t,c:[]},r||{});return a.c.push(e.PWM),a.c.push({cN:"doctag",b:"(?:TODO|FIXME|NOTE|BUG|XXX):",r:0}),a},e.CLCM=e.C("//","$"),e.CBCM=e.C("/\\*","\\*/"),e.HCM=e.C("#","$"),e.NM={cN:"number",b:e.NR,r:0},e.CNM={cN:"number",b:e.CNR,r:0},e.BNM={cN:"number",b:e.BNR,r:0},e.CSSNM={cN:"number",b:e.NR+"(%|em|ex|ch|rem|vw|vh|vmin|vmax|cm|mm|in|pt|pc|px|deg|grad|rad|turn|s|ms|Hz|kHz|dpi|dpcm|dppx)?",r:0},e.RM={cN:"regexp",b:/\//,e:/\/[gimuy]*/,i:/\n/,c:[e.BE,{b:/\[/,e:/\]/,r:0,c:[e.BE]}]},e.TM={cN:"title",b:e.IR,r:0},e.UTM={cN:"title",b:e.UIR,r:0},e});hljs.registerLanguage("json",function(e){var t={literal:"true false null"},i=[e.QSM,e.CNM],r={e:",",eW:!0,eE:!0,c:i,k:t},s={b:"{",e:"}",c:[{cN:"attr",b:'\\s*"',e:'"\\s*:\\s*',eB:!0,eE:!0,c:[e.BE],i:"\\n",starts:r}],i:"\\S"},n={b:"\\[",e:"\\]",c:[e.inherit(r)],i:"\\S"};return i.splice(i.length,0,s,n),{c:i,k:t,i:"\\S"}});hljs.registerLanguage("xml",function(s){var t="[A-Za-z0-9\\._:-]+",e={b:/<\?(php)?(?!\w)/,e:/\?>/,sL:"php"},r={eW:!0,i:/</,r:0,c:[e,{cN:"attr",b:t,r:0},{b:"=",r:0,c:[{cN:"string",c:[e],v:[{b:/"/,e:/"/},{b:/'/,e:/'/},{b:/[^\s\/>]+/}]}]}]};return{aliases:["html","xhtml","rss","atom","xsl","plist"],cI:!0,c:[{cN:"meta",b:"<!DOCTYPE",e:">",r:10,c:[{b:"\\[",e:"\\]"}]},s.C("<!--","-->",{r:10}),{b:"<\\!\\[CDATA\\[",e:"\\]\\]>",r:10},{cN:"tag",b:"<style(?=\\s|>|$)",e:">",k:{name:"style"},c:[r],starts:{e:"</style>",rE:!0,sL:["css","xml"]}},{cN:"tag",b:"<script(?=\\s|>|$)",e:">",k:{name:"script"},c:[r],starts:{e:"</script>",rE:!0,sL:["actionscript","javascript","handlebars","xml"]}},e,{cN:"meta",b:/<\?\w+/,e:/\?>/,r:10},{cN:"tag",b:"</?",e:"/?>",c:[{cN:"name",b:/[^\/><\s]+/,r:0},r]}]}});hljs.registerLanguage("javascript",function(e){return{aliases:["js"],k:{keyword:"in of if for while finally var new function do return void else break catch instanceof with throw case default try this switch continue typeof delete let yield const export super debugger as async await import from as",literal:"true false null undefined NaN Infinity",built_in:"eval isFinite isNaN parseFloat parseInt decodeURI decodeURIComponent encodeURI encodeURIComponent escape unescape Object Function Boolean Error EvalError InternalError RangeError ReferenceError StopIteration SyntaxError TypeError URIError Number Math Date String RegExp Array Float32Array Float64Array Int16Array Int32Array Int8Array Uint16Array Uint32Array Uint8Array Uint8ClampedArray ArrayBuffer DataView JSON Intl arguments require module console window document Symbol Set Map WeakSet WeakMap Proxy Reflect Promise"},c:[{cN:"meta",r:10,b:/^\s*['"]use (strict|asm)['"]/},{cN:"meta",b:/^#!/,e:/$/},e.ASM,e.QSM,{cN:"string",b:"`",e:"`",c:[e.BE,{cN:"subst",b:"\\$\\{",e:"\\}"}]},e.CLCM,e.CBCM,{cN:"number",v:[{b:"\\b(0[bB][01]+)"},{b:"\\b(0[oO][0-7]+)"},{b:e.CNR}],r:0},{b:"("+e.RSR+"|\\b(case|return|throw)\\b)\\s*",k:"return throw case",c:[e.CLCM,e.CBCM,e.RM,{b:/</,e:/>\s*[);\]]/,r:0,sL:"xml"}],r:0},{cN:"function",bK:"function",e:/\{/,eE:!0,c:[e.inherit(e.TM,{b:/[A-Za-z$_][0-9A-Za-z$_]*/}),{cN:"params",b:/\(/,e:/\)/,eB:!0,eE:!0,c:[e.CLCM,e.CBCM]}],i:/\[|%/},{b:/\$[(.]/},{b:"\\."+e.IR,r:0},{cN:"class",bK:"class",e:/[{;=]/,eE:!0,i:/[:"\[\]]/,c:[{bK:"extends"},e.UTM]},{bK:"constructor",e:/\{/,eE:!0}],i:/#(?!!)/}});hljs.registerLanguage("css",function(e){var c="[a-zA-Z-][a-zA-Z0-9_-]*",t={b:/[A-Z\_\.\-]+\s*:/,rB:!0,e:";",eW:!0,c:[{cN:"attribute",b:/\S/,e:":",eE:!0,starts:{eW:!0,eE:!0,c:[{b:/[\w-]+\s*\(/,rB:!0,c:[{cN:"built_in",b:/[\w-]+/}]},e.CSSNM,e.QSM,e.ASM,e.CBCM,{cN:"number",b:"#[0-9A-Fa-f]+"},{cN:"meta",b:"!important"}]}}]};return{cI:!0,i:/[=\/|'\$]/,c:[e.CBCM,{cN:"selector-id",b:/#[A-Za-z0-9_-]+/},{cN:"selector-class",b:/\.[A-Za-z0-9_-]+/},{cN:"selector-attr",b:/\[/,e:/\]/,i:"$"},{cN:"selector-pseudo",b:/:(:)?[a-zA-Z0-9\_\-\+\(\)"'.]+/},{b:"@(font-face|page)",l:"[a-z-]+",k:"font-face page"},{b:"@",e:"[{;]",c:[{cN:"keyword",b:/\S+/},{b:/\s/,eW:!0,eE:!0,r:0,c:[e.ASM,e.QSM,e.CSSNM]}]},{cN:"selector-tag",b:c,r:0},{b:"{",e:"}",i:/\S/,c:[e.CBCM,t]}]}}); \ No newline at end of file
diff --git a/ydb/core/viewer/content/api/lib/highlight.9.1.0.pack_extended.js b/ydb/core/viewer/content/api/lib/highlight.9.1.0.pack_extended.js
index a68c8c9e811..571c740b1df 100644
--- a/ydb/core/viewer/content/api/lib/highlight.9.1.0.pack_extended.js
+++ b/ydb/core/viewer/content/api/lib/highlight.9.1.0.pack_extended.js
@@ -1,34 +1,34 @@
-'use strict';
-
-(function () {
- var configure, highlightBlock;
-
- configure = hljs.configure;
- // "extending" hljs.configure method
- hljs.configure = function _configure (options) {
- var size = options.highlightSizeThreshold;
-
- // added highlightSizeThreshold option to set maximum size
- // of processed string. Set to null if not a number
- hljs.highlightSizeThreshold = size === +size ? size : null;
-
- configure.call(this, options);
- };
-
- highlightBlock = hljs.highlightBlock;
-
- // "extending" hljs.highlightBlock method
- hljs.highlightBlock = function _highlightBlock (el) {
- var innerHTML = el.innerHTML;
- var size = hljs.highlightSizeThreshold;
-
- // check if highlightSizeThreshold is not set or element innerHTML
- // is less than set option highlightSizeThreshold
- if (size == null || size > innerHTML.length) {
- // proceed with hljs.highlightBlock
- highlightBlock.call(hljs, el);
- }
- };
-
-})();
-
+'use strict';
+
+(function () {
+ var configure, highlightBlock;
+
+ configure = hljs.configure;
+ // "extending" hljs.configure method
+ hljs.configure = function _configure (options) {
+ var size = options.highlightSizeThreshold;
+
+ // added highlightSizeThreshold option to set maximum size
+ // of processed string. Set to null if not a number
+ hljs.highlightSizeThreshold = size === +size ? size : null;
+
+ configure.call(this, options);
+ };
+
+ highlightBlock = hljs.highlightBlock;
+
+ // "extending" hljs.highlightBlock method
+ hljs.highlightBlock = function _highlightBlock (el) {
+ var innerHTML = el.innerHTML;
+ var size = hljs.highlightSizeThreshold;
+
+ // check if highlightSizeThreshold is not set or element innerHTML
+ // is less than set option highlightSizeThreshold
+ if (size == null || size > innerHTML.length) {
+ // proceed with hljs.highlightBlock
+ highlightBlock.call(hljs, el);
+ }
+ };
+
+})();
+
diff --git a/ydb/core/viewer/content/api/lib/jquery-1.8.0.min.js b/ydb/core/viewer/content/api/lib/jquery-1.8.0.min.js
index c4f7ea68054..066d72c7e3a 100644
--- a/ydb/core/viewer/content/api/lib/jquery-1.8.0.min.js
+++ b/ydb/core/viewer/content/api/lib/jquery-1.8.0.min.js
@@ -1,2 +1,2 @@
-/*! jQuery v@1.8.0 jquery.com | jquery.org/license */
-(function(a,b){function G(a){var b=F[a]={};return p.each(a.split(s),function(a,c){b[c]=!0}),b}function J(a,c,d){if(d===b&&a.nodeType===1){var e="data-"+c.replace(I,"-$1").toLowerCase();d=a.getAttribute(e);if(typeof d=="string"){try{d=d==="true"?!0:d==="false"?!1:d==="null"?null:+d+""===d?+d:H.test(d)?p.parseJSON(d):d}catch(f){}p.data(a,c,d)}else d=b}return d}function K(a){var b;for(b in a){if(b==="data"&&p.isEmptyObject(a[b]))continue;if(b!=="toJSON")return!1}return!0}function ba(){return!1}function bb(){return!0}function bh(a){return!a||!a.parentNode||a.parentNode.nodeType===11}function bi(a,b){do a=a[b];while(a&&a.nodeType!==1);return a}function bj(a,b,c){b=b||0;if(p.isFunction(b))return p.grep(a,function(a,d){var e=!!b.call(a,d,a);return e===c});if(b.nodeType)return p.grep(a,function(a,d){return a===b===c});if(typeof b=="string"){var d=p.grep(a,function(a){return a.nodeType===1});if(be.test(b))return p.filter(b,d,!c);b=p.filter(b,d)}return p.grep(a,function(a,d){return p.inArray(a,b)>=0===c})}function bk(a){var b=bl.split("|"),c=a.createDocumentFragment();if(c.createElement)while(b.length)c.createElement(b.pop());return c}function bC(a,b){return a.getElementsByTagName(b)[0]||a.appendChild(a.ownerDocument.createElement(b))}function bD(a,b){if(b.nodeType!==1||!p.hasData(a))return;var c,d,e,f=p._data(a),g=p._data(b,f),h=f.events;if(h){delete g.handle,g.events={};for(c in h)for(d=0,e=h[c].length;d<e;d++)p.event.add(b,c,h[c][d])}g.data&&(g.data=p.extend({},g.data))}function bE(a,b){var c;if(b.nodeType!==1)return;b.clearAttributes&&b.clearAttributes(),b.mergeAttributes&&b.mergeAttributes(a),c=b.nodeName.toLowerCase(),c==="object"?(b.parentNode&&(b.outerHTML=a.outerHTML),p.support.html5Clone&&a.innerHTML&&!p.trim(b.innerHTML)&&(b.innerHTML=a.innerHTML)):c==="input"&&bv.test(a.type)?(b.defaultChecked=b.checked=a.checked,b.value!==a.value&&(b.value=a.value)):c==="option"?b.selected=a.defaultSelected:c==="input"||c==="textarea"?b.defaultValue=a.defaultValue:c==="script"&&b.text!==a.text&&(b.text=a.text),b.removeAttribute(p.expando)}function bF(a){return typeof a.getElementsByTagName!="undefined"?a.getElementsByTagName("*"):typeof a.querySelectorAll!="undefined"?a.querySelectorAll("*"):[]}function bG(a){bv.test(a.type)&&(a.defaultChecked=a.checked)}function bX(a,b){if(b in a)return b;var c=b.charAt(0).toUpperCase()+b.slice(1),d=b,e=bV.length;while(e--){b=bV[e]+c;if(b in a)return b}return d}function bY(a,b){return a=b||a,p.css(a,"display")==="none"||!p.contains(a.ownerDocument,a)}function bZ(a,b){var c,d,e=[],f=0,g=a.length;for(;f<g;f++){c=a[f];if(!c.style)continue;e[f]=p._data(c,"olddisplay"),b?(!e[f]&&c.style.display==="none"&&(c.style.display=""),c.style.display===""&&bY(c)&&(e[f]=p._data(c,"olddisplay",cb(c.nodeName)))):(d=bH(c,"display"),!e[f]&&d!=="none"&&p._data(c,"olddisplay",d))}for(f=0;f<g;f++){c=a[f];if(!c.style)continue;if(!b||c.style.display==="none"||c.style.display==="")c.style.display=b?e[f]||"":"none"}return a}function b$(a,b,c){var d=bO.exec(b);return d?Math.max(0,d[1]-(c||0))+(d[2]||"px"):b}function b_(a,b,c,d){var e=c===(d?"border":"content")?4:b==="width"?1:0,f=0;for(;e<4;e+=2)c==="margin"&&(f+=p.css(a,c+bU[e],!0)),d?(c==="content"&&(f-=parseFloat(bH(a,"padding"+bU[e]))||0),c!=="margin"&&(f-=parseFloat(bH(a,"border"+bU[e]+"Width"))||0)):(f+=parseFloat(bH(a,"padding"+bU[e]))||0,c!=="padding"&&(f+=parseFloat(bH(a,"border"+bU[e]+"Width"))||0));return f}function ca(a,b,c){var d=b==="width"?a.offsetWidth:a.offsetHeight,e=!0,f=p.support.boxSizing&&p.css(a,"boxSizing")==="border-box";if(d<=0){d=bH(a,b);if(d<0||d==null)d=a.style[b];if(bP.test(d))return d;e=f&&(p.support.boxSizingReliable||d===a.style[b]),d=parseFloat(d)||0}return d+b_(a,b,c||(f?"border":"content"),e)+"px"}function cb(a){if(bR[a])return bR[a];var b=p("<"+a+">").appendTo(e.body),c=b.css("display");b.remove();if(c==="none"||c===""){bI=e.body.appendChild(bI||p.extend(e.createElement("iframe"),{frameBorder:0,width:0,height:0}));if(!bJ||!bI.createElement)bJ=(bI.contentWindow||bI.contentDocument).document,bJ.write("<!doctype html><html><body>"),bJ.close();b=bJ.body.appendChild(bJ.createElement(a)),c=bH(b,"display"),e.body.removeChild(bI)}return bR[a]=c,c}function ch(a,b,c,d){var e;if(p.isArray(b))p.each(b,function(b,e){c||cd.test(a)?d(a,e):ch(a+"["+(typeof e=="object"?b:"")+"]",e,c,d)});else if(!c&&p.type(b)==="object")for(e in b)ch(a+"["+e+"]",b[e],c,d);else d(a,b)}function cy(a){return function(b,c){typeof b!="string"&&(c=b,b="*");var d,e,f,g=b.toLowerCase().split(s),h=0,i=g.length;if(p.isFunction(c))for(;h<i;h++)d=g[h],f=/^\+/.test(d),f&&(d=d.substr(1)||"*"),e=a[d]=a[d]||[],e[f?"unshift":"push"](c)}}function cz(a,c,d,e,f,g){f=f||c.dataTypes[0],g=g||{},g[f]=!0;var h,i=a[f],j=0,k=i?i.length:0,l=a===cu;for(;j<k&&(l||!h);j++)h=i[j](c,d,e),typeof h=="string"&&(!l||g[h]?h=b:(c.dataTypes.unshift(h),h=cz(a,c,d,e,h,g)));return(l||!h)&&!g["*"]&&(h=cz(a,c,d,e,"*",g)),h}function cA(a,c){var d,e,f=p.ajaxSettings.flatOptions||{};for(d in c)c[d]!==b&&((f[d]?a:e||(e={}))[d]=c[d]);e&&p.extend(!0,a,e)}function cB(a,c,d){var e,f,g,h,i=a.contents,j=a.dataTypes,k=a.responseFields;for(f in k)f in d&&(c[k[f]]=d[f]);while(j[0]==="*")j.shift(),e===b&&(e=a.mimeType||c.getResponseHeader("content-type"));if(e)for(f in i)if(i[f]&&i[f].test(e)){j.unshift(f);break}if(j[0]in d)g=j[0];else{for(f in d){if(!j[0]||a.converters[f+" "+j[0]]){g=f;break}h||(h=f)}g=g||h}if(g)return g!==j[0]&&j.unshift(g),d[g]}function cC(a,b){var c,d,e,f,g=a.dataTypes.slice(),h=g[0],i={},j=0;a.dataFilter&&(b=a.dataFilter(b,a.dataType));if(g[1])for(c in a.converters)i[c.toLowerCase()]=a.converters[c];for(;e=g[++j];)if(e!=="*"){if(h!=="*"&&h!==e){c=i[h+" "+e]||i["* "+e];if(!c)for(d in i){f=d.split(" ");if(f[1]===e){c=i[h+" "+f[0]]||i["* "+f[0]];if(c){c===!0?c=i[d]:i[d]!==!0&&(e=f[0],g.splice(j--,0,e));break}}}if(c!==!0)if(c&&a["throws"])b=c(b);else try{b=c(b)}catch(k){return{state:"parsererror",error:c?k:"No conversion from "+h+" to "+e}}}h=e}return{state:"success",data:b}}function cK(){try{return new a.XMLHttpRequest}catch(b){}}function cL(){try{return new a.ActiveXObject("Microsoft.XMLHTTP")}catch(b){}}function cT(){return setTimeout(function(){cM=b},0),cM=p.now()}function cU(a,b){p.each(b,function(b,c){var d=(cS[b]||[]).concat(cS["*"]),e=0,f=d.length;for(;e<f;e++)if(d[e].call(a,b,c))return})}function cV(a,b,c){var d,e=0,f=0,g=cR.length,h=p.Deferred().always(function(){delete i.elem}),i=function(){var b=cM||cT(),c=Math.max(0,j.startTime+j.duration-b),d=1-(c/j.duration||0),e=0,f=j.tweens.length;for(;e<f;e++)j.tweens[e].run(d);return h.notifyWith(a,[j,d,c]),d<1&&f?c:(h.resolveWith(a,[j]),!1)},j=h.promise({elem:a,props:p.extend({},b),opts:p.extend(!0,{specialEasing:{}},c),originalProperties:b,originalOptions:c,startTime:cM||cT(),duration:c.duration,tweens:[],createTween:function(b,c,d){var e=p.Tween(a,j.opts,b,c,j.opts.specialEasing[b]||j.opts.easing);return j.tweens.push(e),e},stop:function(b){var c=0,d=b?j.tweens.length:0;for(;c<d;c++)j.tweens[c].run(1);return b?h.resolveWith(a,[j,b]):h.rejectWith(a,[j,b]),this}}),k=j.props;cW(k,j.opts.specialEasing);for(;e<g;e++){d=cR[e].call(j,a,k,j.opts);if(d)return d}return cU(j,k),p.isFunction(j.opts.start)&&j.opts.start.call(a,j),p.fx.timer(p.extend(i,{anim:j,queue:j.opts.queue,elem:a})),j.progress(j.opts.progress).done(j.opts.done,j.opts.complete).fail(j.opts.fail).always(j.opts.always)}function cW(a,b){var c,d,e,f,g;for(c in a){d=p.camelCase(c),e=b[d],f=a[c],p.isArray(f)&&(e=f[1],f=a[c]=f[0]),c!==d&&(a[d]=f,delete a[c]),g=p.cssHooks[d];if(g&&"expand"in g){f=g.expand(f),delete a[d];for(c in f)c in a||(a[c]=f[c],b[c]=e)}else b[d]=e}}function cX(a,b,c){var d,e,f,g,h,i,j,k,l=this,m=a.style,n={},o=[],q=a.nodeType&&bY(a);c.queue||(j=p._queueHooks(a,"fx"),j.unqueued==null&&(j.unqueued=0,k=j.empty.fire,j.empty.fire=function(){j.unqueued||k()}),j.unqueued++,l.always(function(){l.always(function(){j.unqueued--,p.queue(a,"fx").length||j.empty.fire()})})),a.nodeType===1&&("height"in b||"width"in b)&&(c.overflow=[m.overflow,m.overflowX,m.overflowY],p.css(a,"display")==="inline"&&p.css(a,"float")==="none"&&(!p.support.inlineBlockNeedsLayout||cb(a.nodeName)==="inline"?m.display="inline-block":m.zoom=1)),c.overflow&&(m.overflow="hidden",p.support.shrinkWrapBlocks||l.done(function(){m.overflow=c.overflow[0],m.overflowX=c.overflow[1],m.overflowY=c.overflow[2]}));for(d in b){f=b[d];if(cO.exec(f)){delete b[d];if(f===(q?"hide":"show"))continue;o.push(d)}}g=o.length;if(g){h=p._data(a,"fxshow")||p._data(a,"fxshow",{}),q?p(a).show():l.done(function(){p(a).hide()}),l.done(function(){var b;p.removeData(a,"fxshow",!0);for(b in n)p.style(a,b,n[b])});for(d=0;d<g;d++)e=o[d],i=l.createTween(e,q?h[e]:0),n[e]=h[e]||p.style(a,e),e in h||(h[e]=i.start,q&&(i.end=i.start,i.start=e==="width"||e==="height"?1:0))}}function cY(a,b,c,d,e){return new cY.prototype.init(a,b,c,d,e)}function cZ(a,b){var c,d={height:a},e=0;for(;e<4;e+=2-b)c=bU[e],d["margin"+c]=d["padding"+c]=a;return b&&(d.opacity=d.width=a),d}function c_(a){return p.isWindow(a)?a:a.nodeType===9?a.defaultView||a.parentWindow:!1}var c,d,e=a.document,f=a.location,g=a.navigator,h=a.jQuery,i=a.$,j=Array.prototype.push,k=Array.prototype.slice,l=Array.prototype.indexOf,m=Object.prototype.toString,n=Object.prototype.hasOwnProperty,o=String.prototype.trim,p=function(a,b){return new p.fn.init(a,b,c)},q=/[\-+]?(?:\d*\.|)\d+(?:[eE][\-+]?\d+|)/.source,r=/\S/,s=/\s+/,t=r.test(" ")?/^[\s\xA0]+|[\s\xA0]+$/g:/^\s+|\s+$/g,u=/^(?:[^#<]*(<[\w\W]+>)[^>]*$|#([\w\-]*)$)/,v=/^<(\w+)\s*\/?>(?:<\/\1>|)$/,w=/^[\],:{}\s]*$/,x=/(?:^|:|,)(?:\s*\[)+/g,y=/\\(?:["\\\/bfnrt]|u[\da-fA-F]{4})/g,z=/"[^"\\\r\n]*"|true|false|null|-?(?:\d\d*\.|)\d+(?:[eE][\-+]?\d+|)/g,A=/^-ms-/,B=/-([\da-z])/gi,C=function(a,b){return(b+"").toUpperCase()},D=function(){e.addEventListener?(e.removeEventListener("DOMContentLoaded",D,!1),p.ready()):e.readyState==="complete"&&(e.detachEvent("onreadystatechange",D),p.ready())},E={};p.fn=p.prototype={constructor:p,init:function(a,c,d){var f,g,h,i;if(!a)return this;if(a.nodeType)return this.context=this[0]=a,this.length=1,this;if(typeof a=="string"){a.charAt(0)==="<"&&a.charAt(a.length-1)===">"&&a.length>=3?f=[null,a,null]:f=u.exec(a);if(f&&(f[1]||!c)){if(f[1])return c=c instanceof p?c[0]:c,i=c&&c.nodeType?c.ownerDocument||c:e,a=p.parseHTML(f[1],i,!0),v.test(f[1])&&p.isPlainObject(c)&&this.attr.call(a,c,!0),p.merge(this,a);g=e.getElementById(f[2]);if(g&&g.parentNode){if(g.id!==f[2])return d.find(a);this.length=1,this[0]=g}return this.context=e,this.selector=a,this}return!c||c.jquery?(c||d).find(a):this.constructor(c).find(a)}return p.isFunction(a)?d.ready(a):(a.selector!==b&&(this.selector=a.selector,this.context=a.context),p.makeArray(a,this))},selector:"",jquery:"1.8.0",length:0,size:function(){return this.length},toArray:function(){return k.call(this)},get:function(a){return a==null?this.toArray():a<0?this[this.length+a]:this[a]},pushStack:function(a,b,c){var d=p.merge(this.constructor(),a);return d.prevObject=this,d.context=this.context,b==="find"?d.selector=this.selector+(this.selector?" ":"")+c:b&&(d.selector=this.selector+"."+b+"("+c+")"),d},each:function(a,b){return p.each(this,a,b)},ready:function(a){return p.ready.promise().done(a),this},eq:function(a){return a=+a,a===-1?this.slice(a):this.slice(a,a+1)},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},slice:function(){return this.pushStack(k.apply(this,arguments),"slice",k.call(arguments).join(","))},map:function(a){return this.pushStack(p.map(this,function(b,c){return a.call(b,c,b)}))},end:function(){return this.prevObject||this.constructor(null)},push:j,sort:[].sort,splice:[].splice},p.fn.init.prototype=p.fn,p.extend=p.fn.extend=function(){var a,c,d,e,f,g,h=arguments[0]||{},i=1,j=arguments.length,k=!1;typeof h=="boolean"&&(k=h,h=arguments[1]||{},i=2),typeof h!="object"&&!p.isFunction(h)&&(h={}),j===i&&(h=this,--i);for(;i<j;i++)if((a=arguments[i])!=null)for(c in a){d=h[c],e=a[c];if(h===e)continue;k&&e&&(p.isPlainObject(e)||(f=p.isArray(e)))?(f?(f=!1,g=d&&p.isArray(d)?d:[]):g=d&&p.isPlainObject(d)?d:{},h[c]=p.extend(k,g,e)):e!==b&&(h[c]=e)}return h},p.extend({noConflict:function(b){return a.$===p&&(a.$=i),b&&a.jQuery===p&&(a.jQuery=h),p},isReady:!1,readyWait:1,holdReady:function(a){a?p.readyWait++:p.ready(!0)},ready:function(a){if(a===!0?--p.readyWait:p.isReady)return;if(!e.body)return setTimeout(p.ready,1);p.isReady=!0;if(a!==!0&&--p.readyWait>0)return;d.resolveWith(e,[p]),p.fn.trigger&&p(e).trigger("ready").off("ready")},isFunction:function(a){return p.type(a)==="function"},isArray:Array.isArray||function(a){return p.type(a)==="array"},isWindow:function(a){return a!=null&&a==a.window},isNumeric:function(a){return!isNaN(parseFloat(a))&&isFinite(a)},type:function(a){return a==null?String(a):E[m.call(a)]||"object"},isPlainObject:function(a){if(!a||p.type(a)!=="object"||a.nodeType||p.isWindow(a))return!1;try{if(a.constructor&&!n.call(a,"constructor")&&!n.call(a.constructor.prototype,"isPrototypeOf"))return!1}catch(c){return!1}var d;for(d in a);return d===b||n.call(a,d)},isEmptyObject:function(a){var b;for(b in a)return!1;return!0},error:function(a){throw new Error(a)},parseHTML:function(a,b,c){var d;return!a||typeof a!="string"?null:(typeof b=="boolean"&&(c=b,b=0),b=b||e,(d=v.exec(a))?[b.createElement(d[1])]:(d=p.buildFragment([a],b,c?null:[]),p.merge([],(d.cacheable?p.clone(d.fragment):d.fragment).childNodes)))},parseJSON:function(b){if(!b||typeof b!="string")return null;b=p.trim(b);if(a.JSON&&a.JSON.parse)return a.JSON.parse(b);if(w.test(b.replace(y,"@").replace(z,"]").replace(x,"")))return(new Function("return "+b))();p.error("Invalid JSON: "+b)},parseXML:function(c){var d,e;if(!c||typeof c!="string")return null;try{a.DOMParser?(e=new DOMParser,d=e.parseFromString(c,"text/xml")):(d=new ActiveXObject("Microsoft.XMLDOM"),d.async="false",d.loadXML(c))}catch(f){d=b}return(!d||!d.documentElement||d.getElementsByTagName("parsererror").length)&&p.error("Invalid XML: "+c),d},noop:function(){},globalEval:function(b){b&&r.test(b)&&(a.execScript||function(b){a.eval.call(a,b)})(b)},camelCase:function(a){return a.replace(A,"ms-").replace(B,C)},nodeName:function(a,b){return a.nodeName&&a.nodeName.toUpperCase()===b.toUpperCase()},each:function(a,c,d){var e,f=0,g=a.length,h=g===b||p.isFunction(a);if(d){if(h){for(e in a)if(c.apply(a[e],d)===!1)break}else for(;f<g;)if(c.apply(a[f++],d)===!1)break}else if(h){for(e in a)if(c.call(a[e],e,a[e])===!1)break}else for(;f<g;)if(c.call(a[f],f,a[f++])===!1)break;return a},trim:o?function(a){return a==null?"":o.call(a)}:function(a){return a==null?"":a.toString().replace(t,"")},makeArray:function(a,b){var c,d=b||[];return a!=null&&(c=p.type(a),a.length==null||c==="string"||c==="function"||c==="regexp"||p.isWindow(a)?j.call(d,a):p.merge(d,a)),d},inArray:function(a,b,c){var d;if(b){if(l)return l.call(b,a,c);d=b.length,c=c?c<0?Math.max(0,d+c):c:0;for(;c<d;c++)if(c in b&&b[c]===a)return c}return-1},merge:function(a,c){var d=c.length,e=a.length,f=0;if(typeof d=="number")for(;f<d;f++)a[e++]=c[f];else while(c[f]!==b)a[e++]=c[f++];return a.length=e,a},grep:function(a,b,c){var d,e=[],f=0,g=a.length;c=!!c;for(;f<g;f++)d=!!b(a[f],f),c!==d&&e.push(a[f]);return e},map:function(a,c,d){var e,f,g=[],h=0,i=a.length,j=a instanceof p||i!==b&&typeof i=="number"&&(i>0&&a[0]&&a[i-1]||i===0||p.isArray(a));if(j)for(;h<i;h++)e=c(a[h],h,d),e!=null&&(g[g.length]=e);else for(f in a)e=c(a[f],f,d),e!=null&&(g[g.length]=e);return g.concat.apply([],g)},guid:1,proxy:function(a,c){var d,e,f;return typeof c=="string"&&(d=a[c],c=a,a=d),p.isFunction(a)?(e=k.call(arguments,2),f=function(){return a.apply(c,e.concat(k.call(arguments)))},f.guid=a.guid=a.guid||f.guid||p.guid++,f):b},access:function(a,c,d,e,f,g,h){var i,j=d==null,k=0,l=a.length;if(d&&typeof d=="object"){for(k in d)p.access(a,c,k,d[k],1,g,e);f=1}else if(e!==b){i=h===b&&p.isFunction(e),j&&(i?(i=c,c=function(a,b,c){return i.call(p(a),c)}):(c.call(a,e),c=null));if(c)for(;k<l;k++)c(a[k],d,i?e.call(a[k],k,c(a[k],d)):e,h);f=1}return f?a:j?c.call(a):l?c(a[0],d):g},now:function(){return(new Date).getTime()}}),p.ready.promise=function(b){if(!d){d=p.Deferred();if(e.readyState==="complete"||e.readyState!=="loading"&&e.addEventListener)setTimeout(p.ready,1);else if(e.addEventListener)e.addEventListener("DOMContentLoaded",D,!1),a.addEventListener("load",p.ready,!1);else{e.attachEvent("onreadystatechange",D),a.attachEvent("onload",p.ready);var c=!1;try{c=a.frameElement==null&&e.documentElement}catch(f){}c&&c.doScroll&&function g(){if(!p.isReady){try{c.doScroll("left")}catch(a){return setTimeout(g,50)}p.ready()}}()}}return d.promise(b)},p.each("Boolean Number String Function Array Date RegExp Object".split(" "),function(a,b){E["[object "+b+"]"]=b.toLowerCase()}),c=p(e);var F={};p.Callbacks=function(a){a=typeof a=="string"?F[a]||G(a):p.extend({},a);var c,d,e,f,g,h,i=[],j=!a.once&&[],k=function(b){c=a.memory&&b,d=!0,h=f||0,f=0,g=i.length,e=!0;for(;i&&h<g;h++)if(i[h].apply(b[0],b[1])===!1&&a.stopOnFalse){c=!1;break}e=!1,i&&(j?j.length&&k(j.shift()):c?i=[]:l.disable())},l={add:function(){if(i){var b=i.length;(function d(b){p.each(b,function(b,c){p.isFunction(c)&&(!a.unique||!l.has(c))?i.push(c):c&&c.length&&d(c)})})(arguments),e?g=i.length:c&&(f=b,k(c))}return this},remove:function(){return i&&p.each(arguments,function(a,b){var c;while((c=p.inArray(b,i,c))>-1)i.splice(c,1),e&&(c<=g&&g--,c<=h&&h--)}),this},has:function(a){return p.inArray(a,i)>-1},empty:function(){return i=[],this},disable:function(){return i=j=c=b,this},disabled:function(){return!i},lock:function(){return j=b,c||l.disable(),this},locked:function(){return!j},fireWith:function(a,b){return b=b||[],b=[a,b.slice?b.slice():b],i&&(!d||j)&&(e?j.push(b):k(b)),this},fire:function(){return l.fireWith(this,arguments),this},fired:function(){return!!d}};return l},p.extend({Deferred:function(a){var b=[["resolve","done",p.Callbacks("once memory"),"resolved"],["reject","fail",p.Callbacks("once memory"),"rejected"],["notify","progress",p.Callbacks("memory")]],c="pending",d={state:function(){return c},always:function(){return e.done(arguments).fail(arguments),this},then:function(){var a=arguments;return p.Deferred(function(c){p.each(b,function(b,d){var f=d[0],g=a[b];e[d[1]](p.isFunction(g)?function(){var a=g.apply(this,arguments);a&&p.isFunction(a.promise)?a.promise().done(c.resolve).fail(c.reject).progress(c.notify):c[f+"With"](this===e?c:this,[a])}:c[f])}),a=null}).promise()},promise:function(a){return typeof a=="object"?p.extend(a,d):d}},e={};return d.pipe=d.then,p.each(b,function(a,f){var g=f[2],h=f[3];d[f[1]]=g.add,h&&g.add(function(){c=h},b[a^1][2].disable,b[2][2].lock),e[f[0]]=g.fire,e[f[0]+"With"]=g.fireWith}),d.promise(e),a&&a.call(e,e),e},when:function(a){var b=0,c=k.call(arguments),d=c.length,e=d!==1||a&&p.isFunction(a.promise)?d:0,f=e===1?a:p.Deferred(),g=function(a,b,c){return function(d){b[a]=this,c[a]=arguments.length>1?k.call(arguments):d,c===h?f.notifyWith(b,c):--e||f.resolveWith(b,c)}},h,i,j;if(d>1){h=new Array(d),i=new Array(d),j=new Array(d);for(;b<d;b++)c[b]&&p.isFunction(c[b].promise)?c[b].promise().done(g(b,j,c)).fail(f.reject).progress(g(b,i,h)):--e}return e||f.resolveWith(j,c),f.promise()}}),p.support=function(){var b,c,d,f,g,h,i,j,k,l,m,n=e.createElement("div");n.setAttribute("className","t"),n.innerHTML=" <link/><table></table><a href='/a'>a</a><input type='checkbox'/>",c=n.getElementsByTagName("*"),d=n.getElementsByTagName("a")[0],d.style.cssText="top:1px;float:left;opacity:.5";if(!c||!c.length||!d)return{};f=e.createElement("select"),g=f.appendChild(e.createElement("option")),h=n.getElementsByTagName("input")[0],b={leadingWhitespace:n.firstChild.nodeType===3,tbody:!n.getElementsByTagName("tbody").length,htmlSerialize:!!n.getElementsByTagName("link").length,style:/top/.test(d.getAttribute("style")),hrefNormalized:d.getAttribute("href")==="/a",opacity:/^0.5/.test(d.style.opacity),cssFloat:!!d.style.cssFloat,checkOn:h.value==="on",optSelected:g.selected,getSetAttribute:n.className!=="t",enctype:!!e.createElement("form").enctype,html5Clone:e.createElement("nav").cloneNode(!0).outerHTML!=="<:nav></:nav>",boxModel:e.compatMode==="CSS1Compat",submitBubbles:!0,changeBubbles:!0,focusinBubbles:!1,deleteExpando:!0,noCloneEvent:!0,inlineBlockNeedsLayout:!1,shrinkWrapBlocks:!1,reliableMarginRight:!0,boxSizingReliable:!0,pixelPosition:!1},h.checked=!0,b.noCloneChecked=h.cloneNode(!0).checked,f.disabled=!0,b.optDisabled=!g.disabled;try{delete n.test}catch(o){b.deleteExpando=!1}!n.addEventListener&&n.attachEvent&&n.fireEvent&&(n.attachEvent("onclick",m=function(){b.noCloneEvent=!1}),n.cloneNode(!0).fireEvent("onclick"),n.detachEvent("onclick",m)),h=e.createElement("input"),h.value="t",h.setAttribute("type","radio"),b.radioValue=h.value==="t",h.setAttribute("checked","checked"),h.setAttribute("name","t"),n.appendChild(h),i=e.createDocumentFragment(),i.appendChild(n.lastChild),b.checkClone=i.cloneNode(!0).cloneNode(!0).lastChild.checked,b.appendChecked=h.checked,i.removeChild(h),i.appendChild(n);if(n.attachEvent)for(k in{submit:!0,change:!0,focusin:!0})j="on"+k,l=j in n,l||(n.setAttribute(j,"return;"),l=typeof n[j]=="function"),b[k+"Bubbles"]=l;return p(function(){var c,d,f,g,h="padding:0;margin:0;border:0;display:block;overflow:hidden;",i=e.getElementsByTagName("body")[0];if(!i)return;c=e.createElement("div"),c.style.cssText="visibility:hidden;border:0;width:0;height:0;position:static;top:0;margin-top:1px",i.insertBefore(c,i.firstChild),d=e.createElement("div"),c.appendChild(d),d.innerHTML="<table><tr><td></td><td>t</td></tr></table>",f=d.getElementsByTagName("td"),f[0].style.cssText="padding:0;margin:0;border:0;display:none",l=f[0].offsetHeight===0,f[0].style.display="",f[1].style.display="none",b.reliableHiddenOffsets=l&&f[0].offsetHeight===0,d.innerHTML="",d.style.cssText="box-sizing:border-box;-moz-box-sizing:border-box;-webkit-box-sizing:border-box;padding:1px;border:1px;display:block;width:4px;margin-top:1%;position:absolute;top:1%;",b.boxSizing=d.offsetWidth===4,b.doesNotIncludeMarginInBodyOffset=i.offsetTop!==1,a.getComputedStyle&&(b.pixelPosition=(a.getComputedStyle(d,null)||{}).top!=="1%",b.boxSizingReliable=(a.getComputedStyle(d,null)||{width:"4px"}).width==="4px",g=e.createElement("div"),g.style.cssText=d.style.cssText=h,g.style.marginRight=g.style.width="0",d.style.width="1px",d.appendChild(g),b.reliableMarginRight=!parseFloat((a.getComputedStyle(g,null)||{}).marginRight)),typeof d.style.zoom!="undefined"&&(d.innerHTML="",d.style.cssText=h+"width:1px;padding:1px;display:inline;zoom:1",b.inlineBlockNeedsLayout=d.offsetWidth===3,d.style.display="block",d.style.overflow="visible",d.innerHTML="<div></div>",d.firstChild.style.width="5px",b.shrinkWrapBlocks=d.offsetWidth!==3,c.style.zoom=1),i.removeChild(c),c=d=f=g=null}),i.removeChild(n),c=d=f=g=h=i=n=null,b}();var H=/^(?:\{.*\}|\[.*\])$/,I=/([A-Z])/g;p.extend({cache:{},deletedIds:[],uuid:0,expando:"jQuery"+(p.fn.jquery+Math.random()).replace(/\D/g,""),noData:{embed:!0,object:"clsid:D27CDB6E-AE6D-11cf-96B8-444553540000",applet:!0},hasData:function(a){return a=a.nodeType?p.cache[a[p.expando]]:a[p.expando],!!a&&!K(a)},data:function(a,c,d,e){if(!p.acceptData(a))return;var f,g,h=p.expando,i=typeof c=="string",j=a.nodeType,k=j?p.cache:a,l=j?a[h]:a[h]&&h;if((!l||!k[l]||!e&&!k[l].data)&&i&&d===b)return;l||(j?a[h]=l=p.deletedIds.pop()||++p.uuid:l=h),k[l]||(k[l]={},j||(k[l].toJSON=p.noop));if(typeof c=="object"||typeof c=="function")e?k[l]=p.extend(k[l],c):k[l].data=p.extend(k[l].data,c);return f=k[l],e||(f.data||(f.data={}),f=f.data),d!==b&&(f[p.camelCase(c)]=d),i?(g=f[c],g==null&&(g=f[p.camelCase(c)])):g=f,g},removeData:function(a,b,c){if(!p.acceptData(a))return;var d,e,f,g=a.nodeType,h=g?p.cache:a,i=g?a[p.expando]:p.expando;if(!h[i])return;if(b){d=c?h[i]:h[i].data;if(d){p.isArray(b)||(b in d?b=[b]:(b=p.camelCase(b),b in d?b=[b]:b=b.split(" ")));for(e=0,f=b.length;e<f;e++)delete d[b[e]];if(!(c?K:p.isEmptyObject)(d))return}}if(!c){delete h[i].data;if(!K(h[i]))return}g?p.cleanData([a],!0):p.support.deleteExpando||h!=h.window?delete h[i]:h[i]=null},_data:function(a,b,c){return p.data(a,b,c,!0)},acceptData:function(a){var b=a.nodeName&&p.noData[a.nodeName.toLowerCase()];return!b||b!==!0&&a.getAttribute("classid")===b}}),p.fn.extend({data:function(a,c){var d,e,f,g,h,i=this[0],j=0,k=null;if(a===b){if(this.length){k=p.data(i);if(i.nodeType===1&&!p._data(i,"parsedAttrs")){f=i.attributes;for(h=f.length;j<h;j++)g=f[j].name,g.indexOf("data-")===0&&(g=p.camelCase(g.substring(5)),J(i,g,k[g]));p._data(i,"parsedAttrs",!0)}}return k}return typeof a=="object"?this.each(function(){p.data(this,a)}):(d=a.split(".",2),d[1]=d[1]?"."+d[1]:"",e=d[1]+"!",p.access(this,function(c){if(c===b)return k=this.triggerHandler("getData"+e,[d[0]]),k===b&&i&&(k=p.data(i,a),k=J(i,a,k)),k===b&&d[1]?this.data(d[0]):k;d[1]=c,this.each(function(){var b=p(this);b.triggerHandler("setData"+e,d),p.data(this,a,c),b.triggerHandler("changeData"+e,d)})},null,c,arguments.length>1,null,!1))},removeData:function(a){return this.each(function(){p.removeData(this,a)})}}),p.extend({queue:function(a,b,c){var d;if(a)return b=(b||"fx")+"queue",d=p._data(a,b),c&&(!d||p.isArray(c)?d=p._data(a,b,p.makeArray(c)):d.push(c)),d||[]},dequeue:function(a,b){b=b||"fx";var c=p.queue(a,b),d=c.shift(),e=p._queueHooks(a,b),f=function(){p.dequeue(a,b)};d==="inprogress"&&(d=c.shift()),d&&(b==="fx"&&c.unshift("inprogress"),delete e.stop,d.call(a,f,e)),!c.length&&e&&e.empty.fire()},_queueHooks:function(a,b){var c=b+"queueHooks";return p._data(a,c)||p._data(a,c,{empty:p.Callbacks("once memory").add(function(){p.removeData(a,b+"queue",!0),p.removeData(a,c,!0)})})}}),p.fn.extend({queue:function(a,c){var d=2;return typeof a!="string"&&(c=a,a="fx",d--),arguments.length<d?p.queue(this[0],a):c===b?this:this.each(function(){var b=p.queue(this,a,c);p._queueHooks(this,a),a==="fx"&&b[0]!=="inprogress"&&p.dequeue(this,a)})},dequeue:function(a){return this.each(function(){p.dequeue(this,a)})},delay:function(a,b){return a=p.fx?p.fx.speeds[a]||a:a,b=b||"fx",this.queue(b,function(b,c){var d=setTimeout(b,a);c.stop=function(){clearTimeout(d)}})},clearQueue:function(a){return this.queue(a||"fx",[])},promise:function(a,c){var d,e=1,f=p.Deferred(),g=this,h=this.length,i=function(){--e||f.resolveWith(g,[g])};typeof a!="string"&&(c=a,a=b),a=a||"fx";while(h--)(d=p._data(g[h],a+"queueHooks"))&&d.empty&&(e++,d.empty.add(i));return i(),f.promise(c)}});var L,M,N,O=/[\t\r\n]/g,P=/\r/g,Q=/^(?:button|input)$/i,R=/^(?:button|input|object|select|textarea)$/i,S=/^a(?:rea|)$/i,T=/^(?:autofocus|autoplay|async|checked|controls|defer|disabled|hidden|loop|multiple|open|readonly|required|scoped|selected)$/i,U=p.support.getSetAttribute;p.fn.extend({attr:function(a,b){return p.access(this,p.attr,a,b,arguments.length>1)},removeAttr:function(a){return this.each(function(){p.removeAttr(this,a)})},prop:function(a,b){return p.access(this,p.prop,a,b,arguments.length>1)},removeProp:function(a){return a=p.propFix[a]||a,this.each(function(){try{this[a]=b,delete this[a]}catch(c){}})},addClass:function(a){var b,c,d,e,f,g,h;if(p.isFunction(a))return this.each(function(b){p(this).addClass(a.call(this,b,this.className))});if(a&&typeof a=="string"){b=a.split(s);for(c=0,d=this.length;c<d;c++){e=this[c];if(e.nodeType===1)if(!e.className&&b.length===1)e.className=a;else{f=" "+e.className+" ";for(g=0,h=b.length;g<h;g++)~f.indexOf(" "+b[g]+" ")||(f+=b[g]+" ");e.className=p.trim(f)}}}return this},removeClass:function(a){var c,d,e,f,g,h,i;if(p.isFunction(a))return this.each(function(b){p(this).removeClass(a.call(this,b,this.className))});if(a&&typeof a=="string"||a===b){c=(a||"").split(s);for(h=0,i=this.length;h<i;h++){e=this[h];if(e.nodeType===1&&e.className){d=(" "+e.className+" ").replace(O," ");for(f=0,g=c.length;f<g;f++)while(d.indexOf(" "+c[f]+" ")>-1)d=d.replace(" "+c[f]+" "," ");e.className=a?p.trim(d):""}}}return this},toggleClass:function(a,b){var c=typeof a,d=typeof b=="boolean";return p.isFunction(a)?this.each(function(c){p(this).toggleClass(a.call(this,c,this.className,b),b)}):this.each(function(){if(c==="string"){var e,f=0,g=p(this),h=b,i=a.split(s);while(e=i[f++])h=d?h:!g.hasClass(e),g[h?"addClass":"removeClass"](e)}else if(c==="undefined"||c==="boolean")this.className&&p._data(this,"__className__",this.className),this.className=this.className||a===!1?"":p._data(this,"__className__")||""})},hasClass:function(a){var b=" "+a+" ",c=0,d=this.length;for(;c<d;c++)if(this[c].nodeType===1&&(" "+this[c].className+" ").replace(O," ").indexOf(b)>-1)return!0;return!1},val:function(a){var c,d,e,f=this[0];if(!arguments.length){if(f)return c=p.valHooks[f.type]||p.valHooks[f.nodeName.toLowerCase()],c&&"get"in c&&(d=c.get(f,"value"))!==b?d:(d=f.value,typeof d=="string"?d.replace(P,""):d==null?"":d);return}return e=p.isFunction(a),this.each(function(d){var f,g=p(this);if(this.nodeType!==1)return;e?f=a.call(this,d,g.val()):f=a,f==null?f="":typeof f=="number"?f+="":p.isArray(f)&&(f=p.map(f,function(a){return a==null?"":a+""})),c=p.valHooks[this.type]||p.valHooks[this.nodeName.toLowerCase()];if(!c||!("set"in c)||c.set(this,f,"value")===b)this.value=f})}}),p.extend({valHooks:{option:{get:function(a){var b=a.attributes.value;return!b||b.specified?a.value:a.text}},select:{get:function(a){var b,c,d,e,f=a.selectedIndex,g=[],h=a.options,i=a.type==="select-one";if(f<0)return null;c=i?f:0,d=i?f+1:h.length;for(;c<d;c++){e=h[c];if(e.selected&&(p.support.optDisabled?!e.disabled:e.getAttribute("disabled")===null)&&(!e.parentNode.disabled||!p.nodeName(e.parentNode,"optgroup"))){b=p(e).val();if(i)return b;g.push(b)}}return i&&!g.length&&h.length?p(h[f]).val():g},set:function(a,b){var c=p.makeArray(b);return p(a).find("option").each(function(){this.selected=p.inArray(p(this).val(),c)>=0}),c.length||(a.selectedIndex=-1),c}}},attrFn:{},attr:function(a,c,d,e){var f,g,h,i=a.nodeType;if(!a||i===3||i===8||i===2)return;if(e&&p.isFunction(p.fn[c]))return p(a)[c](d);if(typeof a.getAttribute=="undefined")return p.prop(a,c,d);h=i!==1||!p.isXMLDoc(a),h&&(c=c.toLowerCase(),g=p.attrHooks[c]||(T.test(c)?M:L));if(d!==b){if(d===null){p.removeAttr(a,c);return}return g&&"set"in g&&h&&(f=g.set(a,d,c))!==b?f:(a.setAttribute(c,""+d),d)}return g&&"get"in g&&h&&(f=g.get(a,c))!==null?f:(f=a.getAttribute(c),f===null?b:f)},removeAttr:function(a,b){var c,d,e,f,g=0;if(b&&a.nodeType===1){d=b.split(s);for(;g<d.length;g++)e=d[g],e&&(c=p.propFix[e]||e,f=T.test(e),f||p.attr(a,e,""),a.removeAttribute(U?e:c),f&&c in a&&(a[c]=!1))}},attrHooks:{type:{set:function(a,b){if(Q.test(a.nodeName)&&a.parentNode)p.error("type property can't be changed");else if(!p.support.radioValue&&b==="radio"&&p.nodeName(a,"input")){var c=a.value;return a.setAttribute("type",b),c&&(a.value=c),b}}},value:{get:function(a,b){return L&&p.nodeName(a,"button")?L.get(a,b):b in a?a.value:null},set:function(a,b,c){if(L&&p.nodeName(a,"button"))return L.set(a,b,c);a.value=b}}},propFix:{tabindex:"tabIndex",readonly:"readOnly","for":"htmlFor","class":"className",maxlength:"maxLength",cellspacing:"cellSpacing",cellpadding:"cellPadding",rowspan:"rowSpan",colspan:"colSpan",usemap:"useMap",frameborder:"frameBorder",contenteditable:"contentEditable"},prop:function(a,c,d){var e,f,g,h=a.nodeType;if(!a||h===3||h===8||h===2)return;return g=h!==1||!p.isXMLDoc(a),g&&(c=p.propFix[c]||c,f=p.propHooks[c]),d!==b?f&&"set"in f&&(e=f.set(a,d,c))!==b?e:a[c]=d:f&&"get"in f&&(e=f.get(a,c))!==null?e:a[c]},propHooks:{tabIndex:{get:function(a){var c=a.getAttributeNode("tabindex");return c&&c.specified?parseInt(c.value,10):R.test(a.nodeName)||S.test(a.nodeName)&&a.href?0:b}}}}),M={get:function(a,c){var d,e=p.prop(a,c);return e===!0||typeof e!="boolean"&&(d=a.getAttributeNode(c))&&d.nodeValue!==!1?c.toLowerCase():b},set:function(a,b,c){var d;return b===!1?p.removeAttr(a,c):(d=p.propFix[c]||c,d in a&&(a[d]=!0),a.setAttribute(c,c.toLowerCase())),c}},U||(N={name:!0,id:!0,coords:!0},L=p.valHooks.button={get:function(a,c){var d;return d=a.getAttributeNode(c),d&&(N[c]?d.value!=="":d.specified)?d.value:b},set:function(a,b,c){var d=a.getAttributeNode(c);return d||(d=e.createAttribute(c),a.setAttributeNode(d)),d.value=b+""}},p.each(["width","height"],function(a,b){p.attrHooks[b]=p.extend(p.attrHooks[b],{set:function(a,c){if(c==="")return a.setAttribute(b,"auto"),c}})}),p.attrHooks.contenteditable={get:L.get,set:function(a,b,c){b===""&&(b="false"),L.set(a,b,c)}}),p.support.hrefNormalized||p.each(["href","src","width","height"],function(a,c){p.attrHooks[c]=p.extend(p.attrHooks[c],{get:function(a){var d=a.getAttribute(c,2);return d===null?b:d}})}),p.support.style||(p.attrHooks.style={get:function(a){return a.style.cssText.toLowerCase()||b},set:function(a,b){return a.style.cssText=""+b}}),p.support.optSelected||(p.propHooks.selected=p.extend(p.propHooks.selected,{get:function(a){var b=a.parentNode;return b&&(b.selectedIndex,b.parentNode&&b.parentNode.selectedIndex),null}})),p.support.enctype||(p.propFix.enctype="encoding"),p.support.checkOn||p.each(["radio","checkbox"],function(){p.valHooks[this]={get:function(a){return a.getAttribute("value")===null?"on":a.value}}}),p.each(["radio","checkbox"],function(){p.valHooks[this]=p.extend(p.valHooks[this],{set:function(a,b){if(p.isArray(b))return a.checked=p.inArray(p(a).val(),b)>=0}})});var V=/^(?:textarea|input|select)$/i,W=/^([^\.]*|)(?:\.(.+)|)$/,X=/(?:^|\s)hover(\.\S+|)\b/,Y=/^key/,Z=/^(?:mouse|contextmenu)|click/,$=/^(?:focusinfocus|focusoutblur)$/,_=function(a){return p.event.special.hover?a:a.replace(X,"mouseenter$1 mouseleave$1")};p.event={add:function(a,c,d,e,f){var g,h,i,j,k,l,m,n,o,q,r;if(a.nodeType===3||a.nodeType===8||!c||!d||!(g=p._data(a)))return;d.handler&&(o=d,d=o.handler,f=o.selector),d.guid||(d.guid=p.guid++),i=g.events,i||(g.events=i={}),h=g.handle,h||(g.handle=h=function(a){return typeof p!="undefined"&&(!a||p.event.triggered!==a.type)?p.event.dispatch.apply(h.elem,arguments):b},h.elem=a),c=p.trim(_(c)).split(" ");for(j=0;j<c.length;j++){k=W.exec(c[j])||[],l=k[1],m=(k[2]||"").split(".").sort(),r=p.event.special[l]||{},l=(f?r.delegateType:r.bindType)||l,r=p.event.special[l]||{},n=p.extend({type:l,origType:k[1],data:e,handler:d,guid:d.guid,selector:f,namespace:m.join(".")},o),q=i[l];if(!q){q=i[l]=[],q.delegateCount=0;if(!r.setup||r.setup.call(a,e,m,h)===!1)a.addEventListener?a.addEventListener(l,h,!1):a.attachEvent&&a.attachEvent("on"+l,h)}r.add&&(r.add.call(a,n),n.handler.guid||(n.handler.guid=d.guid)),f?q.splice(q.delegateCount++,0,n):q.push(n),p.event.global[l]=!0}a=null},global:{},remove:function(a,b,c,d,e){var f,g,h,i,j,k,l,m,n,o,q,r=p.hasData(a)&&p._data(a);if(!r||!(m=r.events))return;b=p.trim(_(b||"")).split(" ");for(f=0;f<b.length;f++){g=W.exec(b[f])||[],h=i=g[1],j=g[2];if(!h){for(h in m)p.event.remove(a,h+b[f],c,d,!0);continue}n=p.event.special[h]||{},h=(d?n.delegateType:n.bindType)||h,o=m[h]||[],k=o.length,j=j?new RegExp("(^|\\.)"+j.split(".").sort().join("\\.(?:.*\\.|)")+"(\\.|$)"):null;for(l=0;l<o.length;l++)q=o[l],(e||i===q.origType)&&(!c||c.guid===q.guid)&&(!j||j.test(q.namespace))&&(!d||d===q.selector||d==="**"&&q.selector)&&(o.splice(l--,1),q.selector&&o.delegateCount--,n.remove&&n.remove.call(a,q));o.length===0&&k!==o.length&&((!n.teardown||n.teardown.call(a,j,r.handle)===!1)&&p.removeEvent(a,h,r.handle),delete m[h])}p.isEmptyObject(m)&&(delete r.handle,p.removeData(a,"events",!0))},customEvent:{getData:!0,setData:!0,changeData:!0},trigger:function(c,d,f,g){if(!f||f.nodeType!==3&&f.nodeType!==8){var h,i,j,k,l,m,n,o,q,r,s=c.type||c,t=[];if($.test(s+p.event.triggered))return;s.indexOf("!")>=0&&(s=s.slice(0,-1),i=!0),s.indexOf(".")>=0&&(t=s.split("."),s=t.shift(),t.sort());if((!f||p.event.customEvent[s])&&!p.event.global[s])return;c=typeof c=="object"?c[p.expando]?c:new p.Event(s,c):new p.Event(s),c.type=s,c.isTrigger=!0,c.exclusive=i,c.namespace=t.join("."),c.namespace_re=c.namespace?new RegExp("(^|\\.)"+t.join("\\.(?:.*\\.|)")+"(\\.|$)"):null,m=s.indexOf(":")<0?"on"+s:"";if(!f){h=p.cache;for(j in h)h[j].events&&h[j].events[s]&&p.event.trigger(c,d,h[j].handle.elem,!0);return}c.result=b,c.target||(c.target=f),d=d!=null?p.makeArray(d):[],d.unshift(c),n=p.event.special[s]||{};if(n.trigger&&n.trigger.apply(f,d)===!1)return;q=[[f,n.bindType||s]];if(!g&&!n.noBubble&&!p.isWindow(f)){r=n.delegateType||s,k=$.test(r+s)?f:f.parentNode;for(l=f;k;k=k.parentNode)q.push([k,r]),l=k;l===(f.ownerDocument||e)&&q.push([l.defaultView||l.parentWindow||a,r])}for(j=0;j<q.length&&!c.isPropagationStopped();j++)k=q[j][0],c.type=q[j][1],o=(p._data(k,"events")||{})[c.type]&&p._data(k,"handle"),o&&o.apply(k,d),o=m&&k[m],o&&p.acceptData(k)&&o.apply(k,d)===!1&&c.preventDefault();return c.type=s,!g&&!c.isDefaultPrevented()&&(!n._default||n._default.apply(f.ownerDocument,d)===!1)&&(s!=="click"||!p.nodeName(f,"a"))&&p.acceptData(f)&&m&&f[s]&&(s!=="focus"&&s!=="blur"||c.target.offsetWidth!==0)&&!p.isWindow(f)&&(l=f[m],l&&(f[m]=null),p.event.triggered=s,f[s](),p.event.triggered=b,l&&(f[m]=l)),c.result}return},dispatch:function(c){c=p.event.fix(c||a.event);var d,e,f,g,h,i,j,k,l,m,n,o=(p._data(this,"events")||{})[c.type]||[],q=o.delegateCount,r=[].slice.call(arguments),s=!c.exclusive&&!c.namespace,t=p.event.special[c.type]||{},u=[];r[0]=c,c.delegateTarget=this;if(t.preDispatch&&t.preDispatch.call(this,c)===!1)return;if(q&&(!c.button||c.type!=="click")){g=p(this),g.context=this;for(f=c.target;f!=this;f=f.parentNode||this)if(f.disabled!==!0||c.type!=="click"){i={},k=[],g[0]=f;for(d=0;d<q;d++)l=o[d],m=l.selector,i[m]===b&&(i[m]=g.is(m)),i[m]&&k.push(l);k.length&&u.push({elem:f,matches:k})}}o.length>q&&u.push({elem:this,matches:o.slice(q)});for(d=0;d<u.length&&!c.isPropagationStopped();d++){j=u[d],c.currentTarget=j.elem;for(e=0;e<j.matches.length&&!c.isImmediatePropagationStopped();e++){l=j.matches[e];if(s||!c.namespace&&!l.namespace||c.namespace_re&&c.namespace_re.test(l.namespace))c.data=l.data,c.handleObj=l,h=((p.event.special[l.origType]||{}).handle||l.handler).apply(j.elem,r),h!==b&&(c.result=h,h===!1&&(c.preventDefault(),c.stopPropagation()))}}return t.postDispatch&&t.postDispatch.call(this,c),c.result},props:"attrChange attrName relatedNode srcElement altKey bubbles cancelable ctrlKey currentTarget eventPhase metaKey relatedTarget shiftKey target timeStamp view which".split(" "),fixHooks:{},keyHooks:{props:"char charCode key keyCode".split(" "),filter:function(a,b){return a.which==null&&(a.which=b.charCode!=null?b.charCode:b.keyCode),a}},mouseHooks:{props:"button buttons clientX clientY fromElement offsetX offsetY pageX pageY screenX screenY toElement".split(" "),filter:function(a,c){var d,f,g,h=c.button,i=c.fromElement;return a.pageX==null&&c.clientX!=null&&(d=a.target.ownerDocument||e,f=d.documentElement,g=d.body,a.pageX=c.clientX+(f&&f.scrollLeft||g&&g.scrollLeft||0)-(f&&f.clientLeft||g&&g.clientLeft||0),a.pageY=c.clientY+(f&&f.scrollTop||g&&g.scrollTop||0)-(f&&f.clientTop||g&&g.clientTop||0)),!a.relatedTarget&&i&&(a.relatedTarget=i===a.target?c.toElement:i),!a.which&&h!==b&&(a.which=h&1?1:h&2?3:h&4?2:0),a}},fix:function(a){if(a[p.expando])return a;var b,c,d=a,f=p.event.fixHooks[a.type]||{},g=f.props?this.props.concat(f.props):this.props;a=p.Event(d);for(b=g.length;b;)c=g[--b],a[c]=d[c];return a.target||(a.target=d.srcElement||e),a.target.nodeType===3&&(a.target=a.target.parentNode),a.metaKey=!!a.metaKey,f.filter?f.filter(a,d):a},special:{ready:{setup:p.bindReady},load:{noBubble:!0},focus:{delegateType:"focusin"},blur:{delegateType:"focusout"},beforeunload:{setup:function(a,b,c){p.isWindow(this)&&(this.onbeforeunload=c)},teardown:function(a,b){this.onbeforeunload===b&&(this.onbeforeunload=null)}}},simulate:function(a,b,c,d){var e=p.extend(new p.Event,c,{type:a,isSimulated:!0,originalEvent:{}});d?p.event.trigger(e,null,b):p.event.dispatch.call(b,e),e.isDefaultPrevented()&&c.preventDefault()}},p.event.handle=p.event.dispatch,p.removeEvent=e.removeEventListener?function(a,b,c){a.removeEventListener&&a.removeEventListener(b,c,!1)}:function(a,b,c){var d="on"+b;a.detachEvent&&(typeof a[d]=="undefined"&&(a[d]=null),a.detachEvent(d,c))},p.Event=function(a,b){if(this instanceof p.Event)a&&a.type?(this.originalEvent=a,this.type=a.type,this.isDefaultPrevented=a.defaultPrevented||a.returnValue===!1||a.getPreventDefault&&a.getPreventDefault()?bb:ba):this.type=a,b&&p.extend(this,b),this.timeStamp=a&&a.timeStamp||p.now(),this[p.expando]=!0;else return new p.Event(a,b)},p.Event.prototype={preventDefault:function(){this.isDefaultPrevented=bb;var a=this.originalEvent;if(!a)return;a.preventDefault?a.preventDefault():a.returnValue=!1},stopPropagation:function(){this.isPropagationStopped=bb;var a=this.originalEvent;if(!a)return;a.stopPropagation&&a.stopPropagation(),a.cancelBubble=!0},stopImmediatePropagation:function(){this.isImmediatePropagationStopped=bb,this.stopPropagation()},isDefaultPrevented:ba,isPropagationStopped:ba,isImmediatePropagationStopped:ba},p.each({mouseenter:"mouseover",mouseleave:"mouseout"},function(a,b){p.event.special[a]={delegateType:b,bindType:b,handle:function(a){var c,d=this,e=a.relatedTarget,f=a.handleObj,g=f.selector;if(!e||e!==d&&!p.contains(d,e))a.type=f.origType,c=f.handler.apply(this,arguments),a.type=b;return c}}}),p.support.submitBubbles||(p.event.special.submit={setup:function(){if(p.nodeName(this,"form"))return!1;p.event.add(this,"click._submit keypress._submit",function(a){var c=a.target,d=p.nodeName(c,"input")||p.nodeName(c,"button")?c.form:b;d&&!p._data(d,"_submit_attached")&&(p.event.add(d,"submit._submit",function(a){a._submit_bubble=!0}),p._data(d,"_submit_attached",!0))})},postDispatch:function(a){a._submit_bubble&&(delete a._submit_bubble,this.parentNode&&!a.isTrigger&&p.event.simulate("submit",this.parentNode,a,!0))},teardown:function(){if(p.nodeName(this,"form"))return!1;p.event.remove(this,"._submit")}}),p.support.changeBubbles||(p.event.special.change={setup:function(){if(V.test(this.nodeName)){if(this.type==="checkbox"||this.type==="radio")p.event.add(this,"propertychange._change",function(a){a.originalEvent.propertyName==="checked"&&(this._just_changed=!0)}),p.event.add(this,"click._change",function(a){this._just_changed&&!a.isTrigger&&(this._just_changed=!1),p.event.simulate("change",this,a,!0)});return!1}p.event.add(this,"beforeactivate._change",function(a){var b=a.target;V.test(b.nodeName)&&!p._data(b,"_change_attached")&&(p.event.add(b,"change._change",function(a){this.parentNode&&!a.isSimulated&&!a.isTrigger&&p.event.simulate("change",this.parentNode,a,!0)}),p._data(b,"_change_attached",!0))})},handle:function(a){var b=a.target;if(this!==b||a.isSimulated||a.isTrigger||b.type!=="radio"&&b.type!=="checkbox")return a.handleObj.handler.apply(this,arguments)},teardown:function(){return p.event.remove(this,"._change"),V.test(this.nodeName)}}),p.support.focusinBubbles||p.each({focus:"focusin",blur:"focusout"},function(a,b){var c=0,d=function(a){p.event.simulate(b,a.target,p.event.fix(a),!0)};p.event.special[b]={setup:function(){c++===0&&e.addEventListener(a,d,!0)},teardown:function(){--c===0&&e.removeEventListener(a,d,!0)}}}),p.fn.extend({on:function(a,c,d,e,f){var g,h;if(typeof a=="object"){typeof c!="string"&&(d=d||c,c=b);for(h in a)this.on(h,c,d,a[h],f);return this}d==null&&e==null?(e=c,d=c=b):e==null&&(typeof c=="string"?(e=d,d=b):(e=d,d=c,c=b));if(e===!1)e=ba;else if(!e)return this;return f===1&&(g=e,e=function(a){return p().off(a),g.apply(this,arguments)},e.guid=g.guid||(g.guid=p.guid++)),this.each(function(){p.event.add(this,a,e,d,c)})},one:function(a,b,c,d){return this.on(a,b,c,d,1)},off:function(a,c,d){var e,f;if(a&&a.preventDefault&&a.handleObj)return e=a.handleObj,p(a.delegateTarget).off(e.namespace?e.origType+"."+e.namespace:e.origType,e.selector,e.handler),this;if(typeof a=="object"){for(f in a)this.off(f,c,a[f]);return this}if(c===!1||typeof c=="function")d=c,c=b;return d===!1&&(d=ba),this.each(function(){p.event.remove(this,a,d,c)})},bind:function(a,b,c){return this.on(a,null,b,c)},unbind:function(a,b){return this.off(a,null,b)},live:function(a,b,c){return p(this.context).on(a,this.selector,b,c),this},die:function(a,b){return p(this.context).off(a,this.selector||"**",b),this},delegate:function(a,b,c,d){return this.on(b,a,c,d)},undelegate:function(a,b,c){return arguments.length==1?this.off(a,"**"):this.off(b,a||"**",c)},trigger:function(a,b){return this.each(function(){p.event.trigger(a,b,this)})},triggerHandler:function(a,b){if(this[0])return p.event.trigger(a,b,this[0],!0)},toggle:function(a){var b=arguments,c=a.guid||p.guid++,d=0,e=function(c){var e=(p._data(this,"lastToggle"+a.guid)||0)%d;return p._data(this,"lastToggle"+a.guid,e+1),c.preventDefault(),b[e].apply(this,arguments)||!1};e.guid=c;while(d<b.length)b[d++].guid=c;return this.click(e)},hover:function(a,b){return this.mouseenter(a).mouseleave(b||a)}}),p.each("blur focus focusin focusout load resize scroll unload click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave change select submit keydown keypress keyup error contextmenu".split(" "),function(a,b){p.fn[b]=function(a,c){return c==null&&(c=a,a=null),arguments.length>0?this.on(b,null,a,c):this.trigger(b)},Y.test(b)&&(p.event.fixHooks[b]=p.event.keyHooks),Z.test(b)&&(p.event.fixHooks[b]=p.event.mouseHooks)}),function(a,b){function bd(a,b,c,d){var e=0,f=b.length;for(;e<f;e++)Z(a,b[e],c,d)}function be(a,b,c,d,e,f){var g,h=$.setFilters[b.toLowerCase()];return h||Z.error(b),(a||!(g=e))&&bd(a||"*",d,g=[],e),g.length>0?h(g,c,f):[]}function bf(a,c,d,e,f){var g,h,i,j,k,l,m,n,p=0,q=f.length,s=L.POS,t=new RegExp("^"+s.source+"(?!"+r+")","i"),u=function(){var a=1,c=arguments.length-2;for(;a<c;a++)arguments[a]===b&&(g[a]=b)};for(;p<q;p++){s.exec(""),a=f[p],j=[],i=0,k=e;while(g=s.exec(a)){n=s.lastIndex=g.index+g[0].length;if(n>i){m=a.slice(i,g.index),i=n,l=[c],B.test(m)&&(k&&(l=k),k=e);if(h=H.test(m))m=m.slice(0,-5).replace(B,"$&*");g.length>1&&g[0].replace(t,u),k=be(m,g[1],g[2],l,k,h)}}k?(j=j.concat(k),(m=a.slice(i))&&m!==")"?B.test(m)?bd(m,j,d,e):Z(m,c,d,e?e.concat(k):k):o.apply(d,j)):Z(a,c,d,e)}return q===1?d:Z.uniqueSort(d)}function bg(a,b,c){var d,e,f,g=[],i=0,j=D.exec(a),k=!j.pop()&&!j.pop(),l=k&&a.match(C)||[""],m=$.preFilter,n=$.filter,o=!c&&b!==h;for(;(e=l[i])!=null&&k;i++){g.push(d=[]),o&&(e=" "+e);while(e){k=!1;if(j=B.exec(e))e=e.slice(j[0].length),k=d.push({part:j.pop().replace(A," "),captures:j});for(f in n)(j=L[f].exec(e))&&(!m[f]||(j=m[f](j,b,c)))&&(e=e.slice(j.shift().length),k=d.push({part:f,captures:j}));if(!k)break}}return k||Z.error(a),g}function bh(a,b,e){var f=b.dir,g=m++;return a||(a=function(a){return a===e}),b.first?function(b,c){while(b=b[f])if(b.nodeType===1)return a(b,c)&&b}:function(b,e){var h,i=g+"."+d,j=i+"."+c;while(b=b[f])if(b.nodeType===1){if((h=b[q])===j)return b.sizset;if(typeof h=="string"&&h.indexOf(i)===0){if(b.sizset)return b}else{b[q]=j;if(a(b,e))return b.sizset=!0,b;b.sizset=!1}}}}function bi(a,b){return a?function(c,d){var e=b(c,d);return e&&a(e===!0?c:e,d)}:b}function bj(a,b,c){var d,e,f=0;for(;d=a[f];f++)$.relative[d.part]?e=bh(e,$.relative[d.part],b):(d.captures.push(b,c),e=bi(e,$.filter[d.part].apply(null,d.captures)));return e}function bk(a){return function(b,c){var d,e=0;for(;d=a[e];e++)if(d(b,c))return!0;return!1}}var c,d,e,f,g,h=a.document,i=h.documentElement,j="undefined",k=!1,l=!0,m=0,n=[].slice,o=[].push,q=("sizcache"+Math.random()).replace(".",""),r="[\\x20\\t\\r\\n\\f]",s="(?:\\\\.|[-\\w]|[^\\x00-\\xa0])+",t=s.replace("w","w#"),u="([*^$|!~]?=)",v="\\["+r+"*("+s+")"+r+"*(?:"+u+r+"*(?:(['\"])((?:\\\\.|[^\\\\])*?)\\3|("+t+")|)|)"+r+"*\\]",w=":("+s+")(?:\\((?:(['\"])((?:\\\\.|[^\\\\])*?)\\2|((?:[^,]|\\\\,|(?:,(?=[^\\[]*\\]))|(?:,(?=[^\\(]*\\))))*))\\)|)",x=":(nth|eq|gt|lt|first|last|even|odd)(?:\\((\\d*)\\)|)(?=[^-]|$)",y=r+"*([\\x20\\t\\r\\n\\f>+~])"+r+"*",z="(?=[^\\x20\\t\\r\\n\\f])(?:\\\\.|"+v+"|"+w.replace(2,7)+"|[^\\\\(),])+",A=new RegExp("^"+r+"+|((?:^|[^\\\\])(?:\\\\.)*)"+r+"+$","g"),B=new RegExp("^"+y),C=new RegExp(z+"?(?="+r+"*,|$)","g"),D=new RegExp("^(?:(?!,)(?:(?:^|,)"+r+"*"+z+")*?|"+r+"*(.*?))(\\)|$)"),E=new RegExp(z.slice(19,-6)+"\\x20\\t\\r\\n\\f>+~])+|"+y,"g"),F=/^(?:#([\w\-]+)|(\w+)|\.([\w\-]+))$/,G=/[\x20\t\r\n\f]*[+~]/,H=/:not\($/,I=/h\d/i,J=/input|select|textarea|button/i,K=/\\(?!\\)/g,L={ID:new RegExp("^#("+s+")"),CLASS:new RegExp("^\\.("+s+")"),NAME:new RegExp("^\\[name=['\"]?("+s+")['\"]?\\]"),TAG:new RegExp("^("+s.replace("[-","[-\\*")+")"),ATTR:new RegExp("^"+v),PSEUDO:new RegExp("^"+w),CHILD:new RegExp("^:(only|nth|last|first)-child(?:\\("+r+"*(even|odd|(([+-]|)(\\d*)n|)"+r+"*(?:([+-]|)"+r+"*(\\d+)|))"+r+"*\\)|)","i"),POS:new RegExp(x,"ig"),needsContext:new RegExp("^"+r+"*[>+~]|"+x,"i")},M={},N=[],O={},P=[],Q=function(a){return a.sizzleFilter=!0,a},R=function(a){return function(b){return b.nodeName.toLowerCase()==="input"&&b.type===a}},S=function(a){return function(b){var c=b.nodeName.toLowerCase();return(c==="input"||c==="button")&&b.type===a}},T=function(a){var b=!1,c=h.createElement("div");try{b=a(c)}catch(d){}return c=null,b},U=T(function(a){a.innerHTML="<select></select>";var b=typeof a.lastChild.getAttribute("multiple");return b!=="boolean"&&b!=="string"}),V=T(function(a){a.id=q+0,a.innerHTML="<a name='"+q+"'></a><div name='"+q+"'></div>",i.insertBefore(a,i.firstChild);var b=h.getElementsByName&&h.getElementsByName(q).length===2+h.getElementsByName(q+0).length;return g=!h.getElementById(q),i.removeChild(a),b}),W=T(function(a){return a.appendChild(h.createComment("")),a.getElementsByTagName("*").length===0}),X=T(function(a){return a.innerHTML="<a href='#'></a>",a.firstChild&&typeof a.firstChild.getAttribute!==j&&a.firstChild.getAttribute("href")==="#"}),Y=T(function(a){return a.innerHTML="<div class='hidden e'></div><div class='hidden'></div>",!a.getElementsByClassName||a.getElementsByClassName("e").length===0?!1:(a.lastChild.className="e",a.getElementsByClassName("e").length!==1)}),Z=function(a,b,c,d){c=c||[],b=b||h;var e,f,g,i,j=b.nodeType;if(j!==1&&j!==9)return[];if(!a||typeof a!="string")return c;g=ba(b);if(!g&&!d)if(e=F.exec(a))if(i=e[1]){if(j===9){f=b.getElementById(i);if(!f||!f.parentNode)return c;if(f.id===i)return c.push(f),c}else if(b.ownerDocument&&(f=b.ownerDocument.getElementById(i))&&bb(b,f)&&f.id===i)return c.push(f),c}else{if(e[2])return o.apply(c,n.call(b.getElementsByTagName(a),0)),c;if((i=e[3])&&Y&&b.getElementsByClassName)return o.apply(c,n.call(b.getElementsByClassName(i),0)),c}return bm(a,b,c,d,g)},$=Z.selectors={cacheLength:50,match:L,order:["ID","TAG"],attrHandle:{},createPseudo:Q,find:{ID:g?function(a,b,c){if(typeof b.getElementById!==j&&!c){var d=b.getElementById(a);return d&&d.parentNode?[d]:[]}}:function(a,c,d){if(typeof c.getElementById!==j&&!d){var e=c.getElementById(a);return e?e.id===a||typeof e.getAttributeNode!==j&&e.getAttributeNode("id").value===a?[e]:b:[]}},TAG:W?function(a,b){if(typeof b.getElementsByTagName!==j)return b.getElementsByTagName(a)}:function(a,b){var c=b.getElementsByTagName(a);if(a==="*"){var d,e=[],f=0;for(;d=c[f];f++)d.nodeType===1&&e.push(d);return e}return c}},relative:{">":{dir:"parentNode",first:!0}," ":{dir:"parentNode"},"+":{dir:"previousSibling",first:!0},"~":{dir:"previousSibling"}},preFilter:{ATTR:function(a){return a[1]=a[1].replace(K,""),a[3]=(a[4]||a[5]||"").replace(K,""),a[2]==="~="&&(a[3]=" "+a[3]+" "),a.slice(0,4)},CHILD:function(a){return a[1]=a[1].toLowerCase(),a[1]==="nth"?(a[2]||Z.error(a[0]),a[3]=+(a[3]?a[4]+(a[5]||1):2*(a[2]==="even"||a[2]==="odd")),a[4]=+(a[6]+a[7]||a[2]==="odd")):a[2]&&Z.error(a[0]),a},PSEUDO:function(a){var b,c=a[4];return L.CHILD.test(a[0])?null:(c&&(b=D.exec(c))&&b.pop()&&(a[0]=a[0].slice(0,b[0].length-c.length-1),c=b[0].slice(0,-1)),a.splice(2,3,c||a[3]),a)}},filter:{ID:g?function(a){return a=a.replace(K,""),function(b){return b.getAttribute("id")===a}}:function(a){return a=a.replace(K,""),function(b){var c=typeof b.getAttributeNode!==j&&b.getAttributeNode("id");return c&&c.value===a}},TAG:function(a){return a==="*"?function(){return!0}:(a=a.replace(K,"").toLowerCase(),function(b){return b.nodeName&&b.nodeName.toLowerCase()===a})},CLASS:function(a){var b=M[a];return b||(b=M[a]=new RegExp("(^|"+r+")"+a+"("+r+"|$)"),N.push(a),N.length>$.cacheLength&&delete M[N.shift()]),function(a){return b.test(a.className||typeof a.getAttribute!==j&&a.getAttribute("class")||"")}},ATTR:function(a,b,c){return b?function(d){var e=Z.attr(d,a),f=e+"";if(e==null)return b==="!=";switch(b){case"=":return f===c;case"!=":return f!==c;case"^=":return c&&f.indexOf(c)===0;case"*=":return c&&f.indexOf(c)>-1;case"$=":return c&&f.substr(f.length-c.length)===c;case"~=":return(" "+f+" ").indexOf(c)>-1;case"|=":return f===c||f.substr(0,c.length+1)===c+"-"}}:function(b){return Z.attr(b,a)!=null}},CHILD:function(a,b,c,d){if(a==="nth"){var e=m++;return function(a){var b,f,g=0,h=a;if(c===1&&d===0)return!0;b=a.parentNode;if(b&&(b[q]!==e||!a.sizset)){for(h=b.firstChild;h;h=h.nextSibling)if(h.nodeType===1){h.sizset=++g;if(h===a)break}b[q]=e}return f=a.sizset-d,c===0?f===0:f%c===0&&f/c>=0}}return function(b){var c=b;switch(a){case"only":case"first":while(c=c.previousSibling)if(c.nodeType===1)return!1;if(a==="first")return!0;c=b;case"last":while(c=c.nextSibling)if(c.nodeType===1)return!1;return!0}}},PSEUDO:function(a,b,c,d){var e=$.pseudos[a]||$.pseudos[a.toLowerCase()];return e||Z.error("unsupported pseudo: "+a),e.sizzleFilter?e(b,c,d):e}},pseudos:{not:Q(function(a,b,c){var d=bl(a.replace(A,"$1"),b,c);return function(a){return!d(a)}}),enabled:function(a){return a.disabled===!1},disabled:function(a){return a.disabled===!0},checked:function(a){var b=a.nodeName.toLowerCase();return b==="input"&&!!a.checked||b==="option"&&!!a.selected},selected:function(a){return a.parentNode&&a.parentNode.selectedIndex,a.selected===!0},parent:function(a){return!$.pseudos.empty(a)},empty:function(a){var b;a=a.firstChild;while(a){if(a.nodeName>"@"||(b=a.nodeType)===3||b===4)return!1;a=a.nextSibling}return!0},contains:Q(function(a){return function(b){return(b.textContent||b.innerText||bc(b)).indexOf(a)>-1}}),has:Q(function(a){return function(b){return Z(a,b).length>0}}),header:function(a){return I.test(a.nodeName)},text:function(a){var b,c;return a.nodeName.toLowerCase()==="input"&&(b=a.type)==="text"&&((c=a.getAttribute("type"))==null||c.toLowerCase()===b)},radio:R("radio"),checkbox:R("checkbox"),file:R("file"),password:R("password"),image:R("image"),submit:S("submit"),reset:S("reset"),button:function(a){var b=a.nodeName.toLowerCase();return b==="input"&&a.type==="button"||b==="button"},input:function(a){return J.test(a.nodeName)},focus:function(a){var b=a.ownerDocument;return a===b.activeElement&&(!b.hasFocus||b.hasFocus())&&(!!a.type||!!a.href)},active:function(a){return a===a.ownerDocument.activeElement}},setFilters:{first:function(a,b,c){return c?a.slice(1):[a[0]]},last:function(a,b,c){var d=a.pop();return c?a:[d]},even:function(a,b,c){var d=[],e=c?1:0,f=a.length;for(;e<f;e=e+2)d.push(a[e]);return d},odd:function(a,b,c){var d=[],e=c?0:1,f=a.length;for(;e<f;e=e+2)d.push(a[e]);return d},lt:function(a,b,c){return c?a.slice(+b):a.slice(0,+b)},gt:function(a,b,c){return c?a.slice(0,+b+1):a.slice(+b+1)},eq:function(a,b,c){var d=a.splice(+b,1);return c?a:d}}};$.setFilters.nth=$.setFilters.eq,$.filters=$.pseudos,X||($.attrHandle={href:function(a){return a.getAttribute("href",2)},type:function(a){return a.getAttribute("type")}}),V&&($.order.push("NAME"),$.find.NAME=function(a,b){if(typeof b.getElementsByName!==j)return b.getElementsByName(a)}),Y&&($.order.splice(1,0,"CLASS"),$.find.CLASS=function(a,b,c){if(typeof b.getElementsByClassName!==j&&!c)return b.getElementsByClassName(a)});try{n.call(i.childNodes,0)[0].nodeType}catch(_){n=function(a){var b,c=[];for(;b=this[a];a++)c.push(b);return c}}var ba=Z.isXML=function(a){var b=a&&(a.ownerDocument||a).documentElement;return b?b.nodeName!=="HTML":!1},bb=Z.contains=i.compareDocumentPosition?function(a,b){return!!(a.compareDocumentPosition(b)&16)}:i.contains?function(a,b){var c=a.nodeType===9?a.documentElement:a,d=b.parentNode;return a===d||!!(d&&d.nodeType===1&&c.contains&&c.contains(d))}:function(a,b){while(b=b.parentNode)if(b===a)return!0;return!1},bc=Z.getText=function(a){var b,c="",d=0,e=a.nodeType;if(e){if(e===1||e===9||e===11){if(typeof a.textContent=="string")return a.textContent;for(a=a.firstChild;a;a=a.nextSibling)c+=bc(a)}else if(e===3||e===4)return a.nodeValue}else for(;b=a[d];d++)c+=bc(b);return c};Z.attr=function(a,b){var c,d=ba(a);return d||(b=b.toLowerCase()),$.attrHandle[b]?$.attrHandle[b](a):U||d?a.getAttribute(b):(c=a.getAttributeNode(b),c?typeof a[b]=="boolean"?a[b]?b:null:c.specified?c.value:null:null)},Z.error=function(a){throw new Error("Syntax error, unrecognized expression: "+a)},[0,0].sort(function(){return l=0}),i.compareDocumentPosition?e=function(a,b){return a===b?(k=!0,0):(!a.compareDocumentPosition||!b.compareDocumentPosition?a.compareDocumentPosition:a.compareDocumentPosition(b)&4)?-1:1}:(e=function(a,b){if(a===b)return k=!0,0;if(a.sourceIndex&&b.sourceIndex)return a.sourceIndex-b.sourceIndex;var c,d,e=[],g=[],h=a.parentNode,i=b.parentNode,j=h;if(h===i)return f(a,b);if(!h)return-1;if(!i)return 1;while(j)e.unshift(j),j=j.parentNode;j=i;while(j)g.unshift(j),j=j.parentNode;c=e.length,d=g.length;for(var l=0;l<c&&l<d;l++)if(e[l]!==g[l])return f(e[l],g[l]);return l===c?f(a,g[l],-1):f(e[l],b,1)},f=function(a,b,c){if(a===b)return c;var d=a.nextSibling;while(d){if(d===b)return-1;d=d.nextSibling}return 1}),Z.uniqueSort=function(a){var b,c=1;if(e){k=l,a.sort(e);if(k)for(;b=a[c];c++)b===a[c-1]&&a.splice(c--,1)}return a};var bl=Z.compile=function(a,b,c){var d,e,f,g=O[a];if(g&&g.context===b)return g;e=bg(a,b,c);for(f=0;d=e[f];f++)e[f]=bj(d,b,c);return g=O[a]=bk(e),g.context=b,g.runs=g.dirruns=0,P.push(a),P.length>$.cacheLength&&delete O[P.shift()],g};Z.matches=function(a,b){return Z(a,null,null,b)},Z.matchesSelector=function(a,b){return Z(b,null,null,[a]).length>0};var bm=function(a,b,e,f,g){a=a.replace(A,"$1");var h,i,j,k,l,m,p,q,r,s=a.match(C),t=a.match(E),u=b.nodeType;if(L.POS.test(a))return bf(a,b,e,f,s);if(f)h=n.call(f,0);else if(s&&s.length===1){if(t.length>1&&u===9&&!g&&(s=L.ID.exec(t[0]))){b=$.find.ID(s[1],b,g)[0];if(!b)return e;a=a.slice(t.shift().length)}q=(s=G.exec(t[0]))&&!s.index&&b.parentNode||b,r=t.pop(),m=r.split(":not")[0];for(j=0,k=$.order.length;j<k;j++){p=$.order[j];if(s=L[p].exec(m)){h=$.find[p]((s[1]||"").replace(K,""),q,g);if(h==null)continue;m===r&&(a=a.slice(0,a.length-r.length)+m.replace(L[p],""),a||o.apply(e,n.call(h,0)));break}}}if(a){i=bl(a,b,g),d=i.dirruns++,h==null&&(h=$.find.TAG("*",G.test(a)&&b.parentNode||b));for(j=0;l=h[j];j++)c=i.runs++,i(l,b)&&e.push(l)}return e};h.querySelectorAll&&function(){var a,b=bm,c=/'|\\/g,d=/\=[\x20\t\r\n\f]*([^'"\]]*)[\x20\t\r\n\f]*\]/g,e=[],f=[":active"],g=i.matchesSelector||i.mozMatchesSelector||i.webkitMatchesSelector||i.oMatchesSelector||i.msMatchesSelector;T(function(a){a.innerHTML="<select><option selected></option></select>",a.querySelectorAll("[selected]").length||e.push("\\["+r+"*(?:checked|disabled|ismap|multiple|readonly|selected|value)"),a.querySelectorAll(":checked").length||e.push(":checked")}),T(function(a){a.innerHTML="<p test=''></p>",a.querySelectorAll("[test^='']").length&&e.push("[*^$]="+r+"*(?:\"\"|'')"),a.innerHTML="<input type='hidden'>",a.querySelectorAll(":enabled").length||e.push(":enabled",":disabled")}),e=e.length&&new RegExp(e.join("|")),bm=function(a,d,f,g,h){if(!g&&!h&&(!e||!e.test(a)))if(d.nodeType===9)try{return o.apply(f,n.call(d.querySelectorAll(a),0)),f}catch(i){}else if(d.nodeType===1&&d.nodeName.toLowerCase()!=="object"){var j=d.getAttribute("id"),k=j||q,l=G.test(a)&&d.parentNode||d;j?k=k.replace(c,"\\$&"):d.setAttribute("id",k);try{return o.apply(f,n.call(l.querySelectorAll(a.replace(C,"[id='"+k+"'] $&")),0)),f}catch(i){}finally{j||d.removeAttribute("id")}}return b(a,d,f,g,h)},g&&(T(function(b){a=g.call(b,"div");try{g.call(b,"[test!='']:sizzle"),f.push($.match.PSEUDO)}catch(c){}}),f=new RegExp(f.join("|")),Z.matchesSelector=function(b,c){c=c.replace(d,"='$1']");if(!ba(b)&&!f.test(c)&&(!e||!e.test(c)))try{var h=g.call(b,c);if(h||a||b.document&&b.document.nodeType!==11)return h}catch(i){}return Z(c,null,null,[b]).length>0})}(),Z.attr=p.attr,p.find=Z,p.expr=Z.selectors,p.expr[":"]=p.expr.pseudos,p.unique=Z.uniqueSort,p.text=Z.getText,p.isXMLDoc=Z.isXML,p.contains=Z.contains}(a);var bc=/Until$/,bd=/^(?:parents|prev(?:Until|All))/,be=/^.[^:#\[\.,]*$/,bf=p.expr.match.needsContext,bg={children:!0,contents:!0,next:!0,prev:!0};p.fn.extend({find:function(a){var b,c,d,e,f,g,h=this;if(typeof a!="string")return p(a).filter(function(){for(b=0,c=h.length;b<c;b++)if(p.contains(h[b],this))return!0});g=this.pushStack("","find",a);for(b=0,c=this.length;b<c;b++){d=g.length,p.find(a,this[b],g);if(b>0)for(e=d;e<g.length;e++)for(f=0;f<d;f++)if(g[f]===g[e]){g.splice(e--,1);break}}return g},has:function(a){var b,c=p(a,this),d=c.length;return this.filter(function(){for(b=0;b<d;b++)if(p.contains(this,c[b]))return!0})},not:function(a){return this.pushStack(bj(this,a,!1),"not",a)},filter:function(a){return this.pushStack(bj(this,a,!0),"filter",a)},is:function(a){return!!a&&(typeof a=="string"?bf.test(a)?p(a,this.context).index(this[0])>=0:p.filter(a,this).length>0:this.filter(a).length>0)},closest:function(a,b){var c,d=0,e=this.length,f=[],g=bf.test(a)||typeof a!="string"?p(a,b||this.context):0;for(;d<e;d++){c=this[d];while(c&&c.ownerDocument&&c!==b&&c.nodeType!==11){if(g?g.index(c)>-1:p.find.matchesSelector(c,a)){f.push(c);break}c=c.parentNode}}return f=f.length>1?p.unique(f):f,this.pushStack(f,"closest",a)},index:function(a){return a?typeof a=="string"?p.inArray(this[0],p(a)):p.inArray(a.jquery?a[0]:a,this):this[0]&&this[0].parentNode?this.prevAll().length:-1},add:function(a,b){var c=typeof a=="string"?p(a,b):p.makeArray(a&&a.nodeType?[a]:a),d=p.merge(this.get(),c);return this.pushStack(bh(c[0])||bh(d[0])?d:p.unique(d))},addBack:function(a){return this.add(a==null?this.prevObject:this.prevObject.filter(a))}}),p.fn.andSelf=p.fn.addBack,p.each({parent:function(a){var b=a.parentNode;return b&&b.nodeType!==11?b:null},parents:function(a){return p.dir(a,"parentNode")},parentsUntil:function(a,b,c){return p.dir(a,"parentNode",c)},next:function(a){return bi(a,"nextSibling")},prev:function(a){return bi(a,"previousSibling")},nextAll:function(a){return p.dir(a,"nextSibling")},prevAll:function(a){return p.dir(a,"previousSibling")},nextUntil:function(a,b,c){return p.dir(a,"nextSibling",c)},prevUntil:function(a,b,c){return p.dir(a,"previousSibling",c)},siblings:function(a){return p.sibling((a.parentNode||{}).firstChild,a)},children:function(a){return p.sibling(a.firstChild)},contents:function(a){return p.nodeName(a,"iframe")?a.contentDocument||a.contentWindow.document:p.merge([],a.childNodes)}},function(a,b){p.fn[a]=function(c,d){var e=p.map(this,b,c);return bc.test(a)||(d=c),d&&typeof d=="string"&&(e=p.filter(d,e)),e=this.length>1&&!bg[a]?p.unique(e):e,this.length>1&&bd.test(a)&&(e=e.reverse()),this.pushStack(e,a,k.call(arguments).join(","))}}),p.extend({filter:function(a,b,c){return c&&(a=":not("+a+")"),b.length===1?p.find.matchesSelector(b[0],a)?[b[0]]:[]:p.find.matches(a,b)},dir:function(a,c,d){var e=[],f=a[c];while(f&&f.nodeType!==9&&(d===b||f.nodeType!==1||!p(f).is(d)))f.nodeType===1&&e.push(f),f=f[c];return e},sibling:function(a,b){var c=[];for(;a;a=a.nextSibling)a.nodeType===1&&a!==b&&c.push(a);return c}});var bl="abbr|article|aside|audio|bdi|canvas|data|datalist|details|figcaption|figure|footer|header|hgroup|mark|meter|nav|output|progress|section|summary|time|video",bm=/ jQuery\d+="(?:null|\d+)"/g,bn=/^\s+/,bo=/<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/gi,bp=/<([\w:]+)/,bq=/<tbody/i,br=/<|&#?\w+;/,bs=/<(?:script|style|link)/i,bt=/<(?:script|object|embed|option|style)/i,bu=new RegExp("<(?:"+bl+")[\\s/>]","i"),bv=/^(?:checkbox|radio)$/,bw=/checked\s*(?:[^=]|=\s*.checked.)/i,bx=/\/(java|ecma)script/i,by=/^\s*<!(?:\[CDATA\[|\-\-)|[\]\-]{2}>\s*$/g,bz={option:[1,"<select multiple='multiple'>","</select>"],legend:[1,"<fieldset>","</fieldset>"],thead:[1,"<table>","</table>"],tr:[2,"<table><tbody>","</tbody></table>"],td:[3,"<table><tbody><tr>","</tr></tbody></table>"],col:[2,"<table><tbody></tbody><colgroup>","</colgroup></table>"],area:[1,"<map>","</map>"],_default:[0,"",""]},bA=bk(e),bB=bA.appendChild(e.createElement("div"));bz.optgroup=bz.option,bz.tbody=bz.tfoot=bz.colgroup=bz.caption=bz.thead,bz.th=bz.td,p.support.htmlSerialize||(bz._default=[1,"X<div>","</div>"]),p.fn.extend({text:function(a){return p.access(this,function(a){return a===b?p.text(this):this.empty().append((this[0]&&this[0].ownerDocument||e).createTextNode(a))},null,a,arguments.length)},wrapAll:function(a){if(p.isFunction(a))return this.each(function(b){p(this).wrapAll(a.call(this,b))});if(this[0]){var b=p(a,this[0].ownerDocument).eq(0).clone(!0);this[0].parentNode&&b.insertBefore(this[0]),b.map(function(){var a=this;while(a.firstChild&&a.firstChild.nodeType===1)a=a.firstChild;return a}).append(this)}return this},wrapInner:function(a){return p.isFunction(a)?this.each(function(b){p(this).wrapInner(a.call(this,b))}):this.each(function(){var b=p(this),c=b.contents();c.length?c.wrapAll(a):b.append(a)})},wrap:function(a){var b=p.isFunction(a);return this.each(function(c){p(this).wrapAll(b?a.call(this,c):a)})},unwrap:function(){return this.parent().each(function(){p.nodeName(this,"body")||p(this).replaceWith(this.childNodes)}).end()},append:function(){return this.domManip(arguments,!0,function(a){(this.nodeType===1||this.nodeType===11)&&this.appendChild(a)})},prepend:function(){return this.domManip(arguments,!0,function(a){(this.nodeType===1||this.nodeType===11)&&this.insertBefore(a,this.firstChild)})},before:function(){if(!bh(this[0]))return this.domManip(arguments,!1,function(a){this.parentNode.insertBefore(a,this)});if(arguments.length){var a=p.clean(arguments);return this.pushStack(p.merge(a,this),"before",this.selector)}},after:function(){if(!bh(this[0]))return this.domManip(arguments,!1,function(a){this.parentNode.insertBefore(a,this.nextSibling)});if(arguments.length){var a=p.clean(arguments);return this.pushStack(p.merge(this,a),"after",this.selector)}},remove:function(a,b){var c,d=0;for(;(c=this[d])!=null;d++)if(!a||p.filter(a,[c]).length)!b&&c.nodeType===1&&(p.cleanData(c.getElementsByTagName("*")),p.cleanData([c])),c.parentNode&&c.parentNode.removeChild(c);return this},empty:function(){var a,b=0;for(;(a=this[b])!=null;b++){a.nodeType===1&&p.cleanData(a.getElementsByTagName("*"));while(a.firstChild)a.removeChild(a.firstChild)}return this},clone:function(a,b){return a=a==null?!1:a,b=b==null?a:b,this.map(function(){return p.clone(this,a,b)})},html:function(a){return p.access(this,function(a){var c=this[0]||{},d=0,e=this.length;if(a===b)return c.nodeType===1?c.innerHTML.replace(bm,""):b;if(typeof a=="string"&&!bs.test(a)&&(p.support.htmlSerialize||!bu.test(a))&&(p.support.leadingWhitespace||!bn.test(a))&&!bz[(bp.exec(a)||["",""])[1].toLowerCase()]){a=a.replace(bo,"<$1></$2>");try{for(;d<e;d++)c=this[d]||{},c.nodeType===1&&(p.cleanData(c.getElementsByTagName("*")),c.innerHTML=a);c=0}catch(f){}}c&&this.empty().append(a)},null,a,arguments.length)},replaceWith:function(a){return bh(this[0])?this.length?this.pushStack(p(p.isFunction(a)?a():a),"replaceWith",a):this:p.isFunction(a)?this.each(function(b){var c=p(this),d=c.html();c.replaceWith(a.call(this,b,d))}):(typeof a!="string"&&(a=p(a).detach()),this.each(function(){var b=this.nextSibling,c=this.parentNode;p(this).remove(),b?p(b).before(a):p(c).append(a)}))},detach:function(a){return this.remove(a,!0)},domManip:function(a,c,d){a=[].concat.apply([],a);var e,f,g,h,i=0,j=a[0],k=[],l=this.length;if(!p.support.checkClone&&l>1&&typeof j=="string"&&bw.test(j))return this.each(function(){p(this).domManip(a,c,d)});if(p.isFunction(j))return this.each(function(e){var f=p(this);a[0]=j.call(this,e,c?f.html():b),f.domManip(a,c,d)});if(this[0]){e=p.buildFragment(a,this,k),g=e.fragment,f=g.firstChild,g.childNodes.length===1&&(g=f);if(f){c=c&&p.nodeName(f,"tr");for(h=e.cacheable||l-1;i<l;i++)d.call(c&&p.nodeName(this[i],"table")?bC(this[i],"tbody"):this[i],i===h?g:p.clone(g,!0,!0))}g=f=null,k.length&&p.each(k,function(a,b){b.src?p.ajax?p.ajax({url:b.src,type:"GET",dataType:"script",async:!1,global:!1,"throws":!0}):p.error("no ajax"):p.globalEval((b.text||b.textContent||b.innerHTML||"").replace(by,"")),b.parentNode&&b.parentNode.removeChild(b)})}return this}}),p.buildFragment=function(a,c,d){var f,g,h,i=a[0];return c=c||e,c=(c[0]||c).ownerDocument||c[0]||c,typeof c.createDocumentFragment=="undefined"&&(c=e),a.length===1&&typeof i=="string"&&i.length<512&&c===e&&i.charAt(0)==="<"&&!bt.test(i)&&(p.support.checkClone||!bw.test(i))&&(p.support.html5Clone||!bu.test(i))&&(g=!0,f=p.fragments[i],h=f!==b),f||(f=c.createDocumentFragment(),p.clean(a,c,f,d),g&&(p.fragments[i]=h&&f)),{fragment:f,cacheable:g}},p.fragments={},p.each({appendTo:"append",prependTo:"prepend",insertBefore:"before",insertAfter:"after",replaceAll:"replaceWith"},function(a,b){p.fn[a]=function(c){var d,e=0,f=[],g=p(c),h=g.length,i=this.length===1&&this[0].parentNode;if((i==null||i&&i.nodeType===11&&i.childNodes.length===1)&&h===1)return g[b](this[0]),this;for(;e<h;e++)d=(e>0?this.clone(!0):this).get(),p(g[e])[b](d),f=f.concat(d);return this.pushStack(f,a,g.selector)}}),p.extend({clone:function(a,b,c){var d,e,f,g;p.support.html5Clone||p.isXMLDoc(a)||!bu.test("<"+a.nodeName+">")?g=a.cloneNode(!0):(bB.innerHTML=a.outerHTML,bB.removeChild(g=bB.firstChild));if((!p.support.noCloneEvent||!p.support.noCloneChecked)&&(a.nodeType===1||a.nodeType===11)&&!p.isXMLDoc(a)){bE(a,g),d=bF(a),e=bF(g);for(f=0;d[f];++f)e[f]&&bE(d[f],e[f])}if(b){bD(a,g);if(c){d=bF(a),e=bF(g);for(f=0;d[f];++f)bD(d[f],e[f])}}return d=e=null,g},clean:function(a,b,c,d){var f,g,h,i,j,k,l,m,n,o,q,r,s=0,t=[];if(!b||typeof b.createDocumentFragment=="undefined")b=e;for(g=b===e&&bA;(h=a[s])!=null;s++){typeof h=="number"&&(h+="");if(!h)continue;if(typeof h=="string")if(!br.test(h))h=b.createTextNode(h);else{g=g||bk(b),l=l||g.appendChild(b.createElement("div")),h=h.replace(bo,"<$1></$2>"),i=(bp.exec(h)||["",""])[1].toLowerCase(),j=bz[i]||bz._default,k=j[0],l.innerHTML=j[1]+h+j[2];while(k--)l=l.lastChild;if(!p.support.tbody){m=bq.test(h),n=i==="table"&&!m?l.firstChild&&l.firstChild.childNodes:j[1]==="<table>"&&!m?l.childNodes:[];for(f=n.length-1;f>=0;--f)p.nodeName(n[f],"tbody")&&!n[f].childNodes.length&&n[f].parentNode.removeChild(n[f])}!p.support.leadingWhitespace&&bn.test(h)&&l.insertBefore(b.createTextNode(bn.exec(h)[0]),l.firstChild),h=l.childNodes,l=g.lastChild}h.nodeType?t.push(h):t=p.merge(t,h)}l&&(g.removeChild(l),h=l=g=null);if(!p.support.appendChecked)for(s=0;(h=t[s])!=null;s++)p.nodeName(h,"input")?bG(h):typeof h.getElementsByTagName!="undefined"&&p.grep(h.getElementsByTagName("input"),bG);if(c){q=function(a){if(!a.type||bx.test(a.type))return d?d.push(a.parentNode?a.parentNode.removeChild(a):a):c.appendChild(a)};for(s=0;(h=t[s])!=null;s++)if(!p.nodeName(h,"script")||!q(h))c.appendChild(h),typeof h.getElementsByTagName!="undefined"&&(r=p.grep(p.merge([],h.getElementsByTagName("script")),q),t.splice.apply(t,[s+1,0].concat(r)),s+=r.length)}return t},cleanData:function(a,b){var c,d,e,f,g=0,h=p.expando,i=p.cache,j=p.support.deleteExpando,k=p.event.special;for(;(e=a[g])!=null;g++)if(b||p.acceptData(e)){d=e[h],c=d&&i[d];if(c){if(c.events)for(f in c.events)k[f]?p.event.remove(e,f):p.removeEvent(e,f,c.handle);i[d]&&(delete i[d],j?delete e[h]:e.removeAttribute?e.removeAttribute(h):e[h]=null,p.deletedIds.push(d))}}}}),function(){var a,b;p.uaMatch=function(a){a=a.toLowerCase();var b=/(chrome)[ \/]([\w.]+)/.exec(a)||/(webkit)[ \/]([\w.]+)/.exec(a)||/(opera)(?:.*version|)[ \/]([\w.]+)/.exec(a)||/(msie) ([\w.]+)/.exec(a)||a.indexOf("compatible")<0&&/(mozilla)(?:.*? rv:([\w.]+)|)/.exec(a)||[];return{browser:b[1]||"",version:b[2]||"0"}},a=p.uaMatch(g.userAgent),b={},a.browser&&(b[a.browser]=!0,b.version=a.version),b.webkit&&(b.safari=!0),p.browser=b,p.sub=function(){function a(b,c){return new a.fn.init(b,c)}p.extend(!0,a,this),a.superclass=this,a.fn=a.prototype=this(),a.fn.constructor=a,a.sub=this.sub,a.fn.init=function c(c,d){return d&&d instanceof p&&!(d instanceof a)&&(d=a(d)),p.fn.init.call(this,c,d,b)},a.fn.init.prototype=a.fn;var b=a(e);return a}}();var bH,bI,bJ,bK=/alpha\([^)]*\)/i,bL=/opacity=([^)]*)/,bM=/^(top|right|bottom|left)$/,bN=/^margin/,bO=new RegExp("^("+q+")(.*)$","i"),bP=new RegExp("^("+q+")(?!px)[a-z%]+$","i"),bQ=new RegExp("^([-+])=("+q+")","i"),bR={},bS={position:"absolute",visibility:"hidden",display:"block"},bT={letterSpacing:0,fontWeight:400,lineHeight:1},bU=["Top","Right","Bottom","Left"],bV=["Webkit","O","Moz","ms"],bW=p.fn.toggle;p.fn.extend({css:function(a,c){return p.access(this,function(a,c,d){return d!==b?p.style(a,c,d):p.css(a,c)},a,c,arguments.length>1)},show:function(){return bZ(this,!0)},hide:function(){return bZ(this)},toggle:function(a,b){var c=typeof a=="boolean";return p.isFunction(a)&&p.isFunction(b)?bW.apply(this,arguments):this.each(function(){(c?a:bY(this))?p(this).show():p(this).hide()})}}),p.extend({cssHooks:{opacity:{get:function(a,b){if(b){var c=bH(a,"opacity");return c===""?"1":c}}}},cssNumber:{fillOpacity:!0,fontWeight:!0,lineHeight:!0,opacity:!0,orphans:!0,widows:!0,zIndex:!0,zoom:!0},cssProps:{"float":p.support.cssFloat?"cssFloat":"styleFloat"},style:function(a,c,d,e){if(!a||a.nodeType===3||a.nodeType===8||!a.style)return;var f,g,h,i=p.camelCase(c),j=a.style;c=p.cssProps[i]||(p.cssProps[i]=bX(j,i)),h=p.cssHooks[c]||p.cssHooks[i];if(d===b)return h&&"get"in h&&(f=h.get(a,!1,e))!==b?f:j[c];g=typeof d,g==="string"&&(f=bQ.exec(d))&&(d=(f[1]+1)*f[2]+parseFloat(p.css(a,c)),g="number");if(d==null||g==="number"&&isNaN(d))return;g==="number"&&!p.cssNumber[i]&&(d+="px");if(!h||!("set"in h)||(d=h.set(a,d,e))!==b)try{j[c]=d}catch(k){}},css:function(a,c,d,e){var f,g,h,i=p.camelCase(c);return c=p.cssProps[i]||(p.cssProps[i]=bX(a.style,i)),h=p.cssHooks[c]||p.cssHooks[i],h&&"get"in h&&(f=h.get(a,!0,e)),f===b&&(f=bH(a,c)),f==="normal"&&c in bT&&(f=bT[c]),d||e!==b?(g=parseFloat(f),d||p.isNumeric(g)?g||0:f):f},swap:function(a,b,c){var d,e,f={};for(e in b)f[e]=a.style[e],a.style[e]=b[e];d=c.call(a);for(e in b)a.style[e]=f[e];return d}}),a.getComputedStyle?bH=function(a,b){var c,d,e,f,g=getComputedStyle(a,null),h=a.style;return g&&(c=g[b],c===""&&!p.contains(a.ownerDocument.documentElement,a)&&(c=p.style(a,b)),bP.test(c)&&bN.test(b)&&(d=h.width,e=h.minWidth,f=h.maxWidth,h.minWidth=h.maxWidth=h.width=c,c=g.width,h.width=d,h.minWidth=e,h.maxWidth=f)),c}:e.documentElement.currentStyle&&(bH=function(a,b){var c,d,e=a.currentStyle&&a.currentStyle[b],f=a.style;return e==null&&f&&f[b]&&(e=f[b]),bP.test(e)&&!bM.test(b)&&(c=f.left,d=a.runtimeStyle&&a.runtimeStyle.left,d&&(a.runtimeStyle.left=a.currentStyle.left),f.left=b==="fontSize"?"1em":e,e=f.pixelLeft+"px",f.left=c,d&&(a.runtimeStyle.left=d)),e===""?"auto":e}),p.each(["height","width"],function(a,b){p.cssHooks[b]={get:function(a,c,d){if(c)return a.offsetWidth!==0||bH(a,"display")!=="none"?ca(a,b,d):p.swap(a,bS,function(){return ca(a,b,d)})},set:function(a,c,d){return b$(a,c,d?b_(a,b,d,p.support.boxSizing&&p.css(a,"boxSizing")==="border-box"):0)}}}),p.support.opacity||(p.cssHooks.opacity={get:function(a,b){return bL.test((b&&a.currentStyle?a.currentStyle.filter:a.style.filter)||"")?.01*parseFloat(RegExp.$1)+"":b?"1":""},set:function(a,b){var c=a.style,d=a.currentStyle,e=p.isNumeric(b)?"alpha(opacity="+b*100+")":"",f=d&&d.filter||c.filter||"";c.zoom=1;if(b>=1&&p.trim(f.replace(bK,""))===""&&c.removeAttribute){c.removeAttribute("filter");if(d&&!d.filter)return}c.filter=bK.test(f)?f.replace(bK,e):f+" "+e}}),p(function(){p.support.reliableMarginRight||(p.cssHooks.marginRight={get:function(a,b){return p.swap(a,{display:"inline-block"},function(){if(b)return bH(a,"marginRight")})}}),!p.support.pixelPosition&&p.fn.position&&p.each(["top","left"],function(a,b){p.cssHooks[b]={get:function(a,c){if(c){var d=bH(a,b);return bP.test(d)?p(a).position()[b]+"px":d}}}})}),p.expr&&p.expr.filters&&(p.expr.filters.hidden=function(a){return a.offsetWidth===0&&a.offsetHeight===0||!p.support.reliableHiddenOffsets&&(a.style&&a.style.display||bH(a,"display"))==="none"},p.expr.filters.visible=function(a){return!p.expr.filters.hidden(a)}),p.each({margin:"",padding:"",border:"Width"},function(a,b){p.cssHooks[a+b]={expand:function(c){var d,e=typeof c=="string"?c.split(" "):[c],f={};for(d=0;d<4;d++)f[a+bU[d]+b]=e[d]||e[d-2]||e[0];return f}},bN.test(a)||(p.cssHooks[a+b].set=b$)});var cc=/%20/g,cd=/\[\]$/,ce=/\r?\n/g,cf=/^(?:color|date|datetime|datetime-local|email|hidden|month|number|password|range|search|tel|text|time|url|week)$/i,cg=/^(?:select|textarea)/i;p.fn.extend({serialize:function(){return p.param(this.serializeArray())},serializeArray:function(){return this.map(function(){return this.elements?p.makeArray(this.elements):this}).filter(function(){return this.name&&!this.disabled&&(this.checked||cg.test(this.nodeName)||cf.test(this.type))}).map(function(a,b){var c=p(this).val();return c==null?null:p.isArray(c)?p.map(c,function(a,c){return{name:b.name,value:a.replace(ce,"\r\n")}}):{name:b.name,value:c.replace(ce,"\r\n")}}).get()}}),p.param=function(a,c){var d,e=[],f=function(a,b){b=p.isFunction(b)?b():b==null?"":b,e[e.length]=encodeURIComponent(a)+"="+encodeURIComponent(b)};c===b&&(c=p.ajaxSettings&&p.ajaxSettings.traditional);if(p.isArray(a)||a.jquery&&!p.isPlainObject(a))p.each(a,function(){f(this.name,this.value)});else for(d in a)ch(d,a[d],c,f);return e.join("&").replace(cc,"+")};var ci,cj,ck=/#.*$/,cl=/^(.*?):[ \t]*([^\r\n]*)\r?$/mg,cm=/^(?:about|app|app\-storage|.+\-extension|file|res|widget):$/,cn=/^(?:GET|HEAD)$/,co=/^\/\//,cp=/\?/,cq=/<script\b[^<]*(?:(?!<\/script>)<[^<]*)*<\/script>/gi,cr=/([?&])_=[^&]*/,cs=/^([\w\+\.\-]+:)(?:\/\/([^\/?#:]*)(?::(\d+)|)|)/,ct=p.fn.load,cu={},cv={},cw=["*/"]+["*"];try{ci=f.href}catch(cx){ci=e.createElement("a"),ci.href="",ci=ci.href}cj=cs.exec(ci.toLowerCase())||[],p.fn.load=function(a,c,d){if(typeof a!="string"&&ct)return ct.apply(this,arguments);if(!this.length)return this;var e,f,g,h=this,i=a.indexOf(" ");return i>=0&&(e=a.slice(i,a.length),a=a.slice(0,i)),p.isFunction(c)?(d=c,c=b):typeof c=="object"&&(f="POST"),p.ajax({url:a,type:f,dataType:"html",data:c,complete:function(a,b){d&&h.each(d,g||[a.responseText,b,a])}}).done(function(a){g=arguments,h.html(e?p("<div>").append(a.replace(cq,"")).find(e):a)}),this},p.each("ajaxStart ajaxStop ajaxComplete ajaxError ajaxSuccess ajaxSend".split(" "),function(a,b){p.fn[b]=function(a){return this.on(b,a)}}),p.each(["get","post"],function(a,c){p[c]=function(a,d,e,f){return p.isFunction(d)&&(f=f||e,e=d,d=b),p.ajax({type:c,url:a,data:d,success:e,dataType:f})}}),p.extend({getScript:function(a,c){return p.get(a,b,c,"script")},getJSON:function(a,b,c){return p.get(a,b,c,"json")},ajaxSetup:function(a,b){return b?cA(a,p.ajaxSettings):(b=a,a=p.ajaxSettings),cA(a,b),a},ajaxSettings:{url:ci,isLocal:cm.test(cj[1]),global:!0,type:"GET",contentType:"application/x-www-form-urlencoded; charset=UTF-8",processData:!0,async:!0,accepts:{xml:"application/xml, text/xml",html:"text/html",text:"text/plain",json:"application/json, text/javascript","*":cw},contents:{xml:/xml/,html:/html/,json:/json/},responseFields:{xml:"responseXML",text:"responseText"},converters:{"* text":a.String,"text html":!0,"text json":p.parseJSON,"text xml":p.parseXML},flatOptions:{context:!0,url:!0}},ajaxPrefilter:cy(cu),ajaxTransport:cy(cv),ajax:function(a,c){function y(a,c,f,i){var k,s,t,u,w,y=c;if(v===2)return;v=2,h&&clearTimeout(h),g=b,e=i||"",x.readyState=a>0?4:0,f&&(u=cB(l,x,f));if(a>=200&&a<300||a===304)l.ifModified&&(w=x.getResponseHeader("Last-Modified"),w&&(p.lastModified[d]=w),w=x.getResponseHeader("Etag"),w&&(p.etag[d]=w)),a===304?(y="notmodified",k=!0):(k=cC(l,u),y=k.state,s=k.data,t=k.error,k=!t);else{t=y;if(!y||a)y="error",a<0&&(a=0)}x.status=a,x.statusText=""+(c||y),k?o.resolveWith(m,[s,y,x]):o.rejectWith(m,[x,y,t]),x.statusCode(r),r=b,j&&n.trigger("ajax"+(k?"Success":"Error"),[x,l,k?s:t]),q.fireWith(m,[x,y]),j&&(n.trigger("ajaxComplete",[x,l]),--p.active||p.event.trigger("ajaxStop"))}typeof a=="object"&&(c=a,a=b),c=c||{};var d,e,f,g,h,i,j,k,l=p.ajaxSetup({},c),m=l.context||l,n=m!==l&&(m.nodeType||m instanceof p)?p(m):p.event,o=p.Deferred(),q=p.Callbacks("once memory"),r=l.statusCode||{},t={},u={},v=0,w="canceled",x={readyState:0,setRequestHeader:function(a,b){if(!v){var c=a.toLowerCase();a=u[c]=u[c]||a,t[a]=b}return this},getAllResponseHeaders:function(){return v===2?e:null},getResponseHeader:function(a){var c;if(v===2){if(!f){f={};while(c=cl.exec(e))f[c[1].toLowerCase()]=c[2]}c=f[a.toLowerCase()]}return c===b?null:c},overrideMimeType:function(a){return v||(l.mimeType=a),this},abort:function(a){return a=a||w,g&&g.abort(a),y(0,a),this}};o.promise(x),x.success=x.done,x.error=x.fail,x.complete=q.add,x.statusCode=function(a){if(a){var b;if(v<2)for(b in a)r[b]=[r[b],a[b]];else b=a[x.status],x.always(b)}return this},l.url=((a||l.url)+"").replace(ck,"").replace(co,cj[1]+"//"),l.dataTypes=p.trim(l.dataType||"*").toLowerCase().split(s),l.crossDomain==null&&(i=cs.exec(l.url.toLowerCase()),l.crossDomain=!(!i||i[1]==cj[1]&&i[2]==cj[2]&&(i[3]||(i[1]==="http:"?80:443))==(cj[3]||(cj[1]==="http:"?80:443)))),l.data&&l.processData&&typeof l.data!="string"&&(l.data=p.param(l.data,l.traditional)),cz(cu,l,c,x);if(v===2)return x;j=l.global,l.type=l.type.toUpperCase(),l.hasContent=!cn.test(l.type),j&&p.active++===0&&p.event.trigger("ajaxStart");if(!l.hasContent){l.data&&(l.url+=(cp.test(l.url)?"&":"?")+l.data,delete l.data),d=l.url;if(l.cache===!1){var z=p.now(),A=l.url.replace(cr,"$1_="+z);l.url=A+(A===l.url?(cp.test(l.url)?"&":"?")+"_="+z:"")}}(l.data&&l.hasContent&&l.contentType!==!1||c.contentType)&&x.setRequestHeader("Content-Type",l.contentType),l.ifModified&&(d=d||l.url,p.lastModified[d]&&x.setRequestHeader("If-Modified-Since",p.lastModified[d]),p.etag[d]&&x.setRequestHeader("If-None-Match",p.etag[d])),x.setRequestHeader("Accept",l.dataTypes[0]&&l.accepts[l.dataTypes[0]]?l.accepts[l.dataTypes[0]]+(l.dataTypes[0]!=="*"?", "+cw+"; q=0.01":""):l.accepts["*"]);for(k in l.headers)x.setRequestHeader(k,l.headers[k]);if(!l.beforeSend||l.beforeSend.call(m,x,l)!==!1&&v!==2){w="abort";for(k in{success:1,error:1,complete:1})x[k](l[k]);g=cz(cv,l,c,x);if(!g)y(-1,"No Transport");else{x.readyState=1,j&&n.trigger("ajaxSend",[x,l]),l.async&&l.timeout>0&&(h=setTimeout(function(){x.abort("timeout")},l.timeout));try{v=1,g.send(t,y)}catch(B){if(v<2)y(-1,B);else throw B}}return x}return x.abort()},active:0,lastModified:{},etag:{}});var cD=[],cE=/\?/,cF=/(=)\?(?=&|$)|\?\?/,cG=p.now();p.ajaxSetup({jsonp:"callback",jsonpCallback:function(){var a=cD.pop()||p.expando+"_"+cG++;return this[a]=!0,a}}),p.ajaxPrefilter("json jsonp",function(c,d,e){var f,g,h,i=c.data,j=c.url,k=c.jsonp!==!1,l=k&&cF.test(j),m=k&&!l&&typeof i=="string"&&!(c.contentType||"").indexOf("application/x-www-form-urlencoded")&&cF.test(i);if(c.dataTypes[0]==="jsonp"||l||m)return f=c.jsonpCallback=p.isFunction(c.jsonpCallback)?c.jsonpCallback():c.jsonpCallback,g=a[f],l?c.url=j.replace(cF,"$1"+f):m?c.data=i.replace(cF,"$1"+f):k&&(c.url+=(cE.test(j)?"&":"?")+c.jsonp+"="+f),c.converters["script json"]=function(){return h||p.error(f+" was not called"),h[0]},c.dataTypes[0]="json",a[f]=function(){h=arguments},e.always(function(){a[f]=g,c[f]&&(c.jsonpCallback=d.jsonpCallback,cD.push(f)),h&&p.isFunction(g)&&g(h[0]),h=g=b}),"script"}),p.ajaxSetup({accepts:{script:"text/javascript, application/javascript, application/ecmascript, application/x-ecmascript"},contents:{script:/javascript|ecmascript/},converters:{"text script":function(a){return p.globalEval(a),a}}}),p.ajaxPrefilter("script",function(a){a.cache===b&&(a.cache=!1),a.crossDomain&&(a.type="GET",a.global=!1)}),p.ajaxTransport("script",function(a){if(a.crossDomain){var c,d=e.head||e.getElementsByTagName("head")[0]||e.documentElement;return{send:function(f,g){c=e.createElement("script"),c.async="async",a.scriptCharset&&(c.charset=a.scriptCharset),c.src=a.url,c.onload=c.onreadystatechange=function(a,e){if(e||!c.readyState||/loaded|complete/.test(c.readyState))c.onload=c.onreadystatechange=null,d&&c.parentNode&&d.removeChild(c),c=b,e||g(200,"success")},d.insertBefore(c,d.firstChild)},abort:function(){c&&c.onload(0,1)}}}});var cH,cI=a.ActiveXObject?function(){for(var a in cH)cH[a](0,1)}:!1,cJ=0;p.ajaxSettings.xhr=a.ActiveXObject?function(){return!this.isLocal&&cK()||cL()}:cK,function(a){p.extend(p.support,{ajax:!!a,cors:!!a&&"withCredentials"in a})}(p.ajaxSettings.xhr()),p.support.ajax&&p.ajaxTransport(function(c){if(!c.crossDomain||p.support.cors){var d;return{send:function(e,f){var g,h,i=c.xhr();c.username?i.open(c.type,c.url,c.async,c.username,c.password):i.open(c.type,c.url,c.async);if(c.xhrFields)for(h in c.xhrFields)i[h]=c.xhrFields[h];c.mimeType&&i.overrideMimeType&&i.overrideMimeType(c.mimeType),!c.crossDomain&&!e["X-Requested-With"]&&(e["X-Requested-With"]="XMLHttpRequest");try{for(h in e)i.setRequestHeader(h,e[h])}catch(j){}i.send(c.hasContent&&c.data||null),d=function(a,e){var h,j,k,l,m;try{if(d&&(e||i.readyState===4)){d=b,g&&(i.onreadystatechange=p.noop,cI&&delete cH[g]);if(e)i.readyState!==4&&i.abort();else{h=i.status,k=i.getAllResponseHeaders(),l={},m=i.responseXML,m&&m.documentElement&&(l.xml=m);try{l.text=i.responseText}catch(a){}try{j=i.statusText}catch(n){j=""}!h&&c.isLocal&&!c.crossDomain?h=l.text?200:404:h===1223&&(h=204)}}}catch(o){e||f(-1,o)}l&&f(h,j,l,k)},c.async?i.readyState===4?setTimeout(d,0):(g=++cJ,cI&&(cH||(cH={},p(a).unload(cI)),cH[g]=d),i.onreadystatechange=d):d()},abort:function(){d&&d(0,1)}}}});var cM,cN,cO=/^(?:toggle|show|hide)$/,cP=new RegExp("^(?:([-+])=|)("+q+")([a-z%]*)$","i"),cQ=/queueHooks$/,cR=[cX],cS={"*":[function(a,b){var c,d,e,f=this.createTween(a,b),g=cP.exec(b),h=f.cur(),i=+h||0,j=1;if(g){c=+g[2],d=g[3]||(p.cssNumber[a]?"":"px");if(d!=="px"&&i){i=p.css(f.elem,a,!0)||c||1;do e=j=j||".5",i=i/j,p.style(f.elem,a,i+d),j=f.cur()/h;while(j!==1&&j!==e)}f.unit=d,f.start=i,f.end=g[1]?i+(g[1]+1)*c:c}return f}]};p.Animation=p.extend(cV,{tweener:function(a,b){p.isFunction(a)?(b=a,a=["*"]):a=a.split(" ");var c,d=0,e=a.length;for(;d<e;d++)c=a[d],cS[c]=cS[c]||[],cS[c].unshift(b)},prefilter:function(a,b){b?cR.unshift(a):cR.push(a)}}),p.Tween=cY,cY.prototype={constructor:cY,init:function(a,b,c,d,e,f){this.elem=a,this.prop=c,this.easing=e||"swing",this.options=b,this.start=this.now=this.cur(),this.end=d,this.unit=f||(p.cssNumber[c]?"":"px")},cur:function(){var a=cY.propHooks[this.prop];return a&&a.get?a.get(this):cY.propHooks._default.get(this)},run:function(a){var b,c=cY.propHooks[this.prop];return this.pos=b=p.easing[this.easing](a,this.options.duration*a,0,1,this.options.duration),this.now=(this.end-this.start)*b+this.start,this.options.step&&this.options.step.call(this.elem,this.now,this),c&&c.set?c.set(this):cY.propHooks._default.set(this),this}},cY.prototype.init.prototype=cY.prototype,cY.propHooks={_default:{get:function(a){var b;return a.elem[a.prop]==null||!!a.elem.style&&a.elem.style[a.prop]!=null?(b=p.css(a.elem,a.prop,!1,""),!b||b==="auto"?0:b):a.elem[a.prop]},set:function(a){p.fx.step[a.prop]?p.fx.step[a.prop](a):a.elem.style&&(a.elem.style[p.cssProps[a.prop]]!=null||p.cssHooks[a.prop])?p.style(a.elem,a.prop,a.now+a.unit):a.elem[a.prop]=a.now}}},cY.propHooks.scrollTop=cY.propHooks.scrollLeft={set:function(a){a.elem.nodeType&&a.elem.parentNode&&(a.elem[a.prop]=a.now)}},p.each(["toggle","show","hide"],function(a,b){var c=p.fn[b];p.fn[b]=function(d,e,f){return d==null||typeof d=="boolean"||!a&&p.isFunction(d)&&p.isFunction(e)?c.apply(this,arguments):this.animate(cZ(b,!0),d,e,f)}}),p.fn.extend({fadeTo:function(a,b,c,d){return this.filter(bY).css("opacity",0).show().end().animate({opacity:b},a,c,d)},animate:function(a,b,c,d){var e=p.isEmptyObject(a),f=p.speed(b,c,d),g=function(){var b=cV(this,p.extend({},a),f);e&&b.stop(!0)};return e||f.queue===!1?this.each(g):this.queue(f.queue,g)},stop:function(a,c,d){var e=function(a){var b=a.stop;delete a.stop,b(d)};return typeof a!="string"&&(d=c,c=a,a=b),c&&a!==!1&&this.queue(a||"fx",[]),this.each(function(){var b=!0,c=a!=null&&a+"queueHooks",f=p.timers,g=p._data(this);if(c)g[c]&&g[c].stop&&e(g[c]);else for(c in g)g[c]&&g[c].stop&&cQ.test(c)&&e(g[c]);for(c=f.length;c--;)f[c].elem===this&&(a==null||f[c].queue===a)&&(f[c].anim.stop(d),b=!1,f.splice(c,1));(b||!d)&&p.dequeue(this,a)})}}),p.each({slideDown:cZ("show"),slideUp:cZ("hide"),slideToggle:cZ("toggle"),fadeIn:{opacity:"show"},fadeOut:{opacity:"hide"},fadeToggle:{opacity:"toggle"}},function(a,b){p.fn[a]=function(a,c,d){return this.animate(b,a,c,d)}}),p.speed=function(a,b,c){var d=a&&typeof a=="object"?p.extend({},a):{complete:c||!c&&b||p.isFunction(a)&&a,duration:a,easing:c&&b||b&&!p.isFunction(b)&&b};d.duration=p.fx.off?0:typeof d.duration=="number"?d.duration:d.duration in p.fx.speeds?p.fx.speeds[d.duration]:p.fx.speeds._default;if(d.queue==null||d.queue===!0)d.queue="fx";return d.old=d.complete,d.complete=function(){p.isFunction(d.old)&&d.old.call(this),d.queue&&p.dequeue(this,d.queue)},d},p.easing={linear:function(a){return a},swing:function(a){return.5-Math.cos(a*Math.PI)/2}},p.timers=[],p.fx=cY.prototype.init,p.fx.tick=function(){var a,b=p.timers,c=0;for(;c<b.length;c++)a=b[c],!a()&&b[c]===a&&b.splice(c--,1);b.length||p.fx.stop()},p.fx.timer=function(a){a()&&p.timers.push(a)&&!cN&&(cN=setInterval(p.fx.tick,p.fx.interval))},p.fx.interval=13,p.fx.stop=function(){clearInterval(cN),cN=null},p.fx.speeds={slow:600,fast:200,_default:400},p.fx.step={},p.expr&&p.expr.filters&&(p.expr.filters.animated=function(a){return p.grep(p.timers,function(b){return a===b.elem}).length});var c$=/^(?:body|html)$/i;p.fn.offset=function(a){if(arguments.length)return a===b?this:this.each(function(b){p.offset.setOffset(this,a,b)});var c,d,e,f,g,h,i,j,k,l,m=this[0],n=m&&m.ownerDocument;if(!n)return;return(e=n.body)===m?p.offset.bodyOffset(m):(d=n.documentElement,p.contains(d,m)?(c=m.getBoundingClientRect(),f=c_(n),g=d.clientTop||e.clientTop||0,h=d.clientLeft||e.clientLeft||0,i=f.pageYOffset||d.scrollTop,j=f.pageXOffset||d.scrollLeft,k=c.top+i-g,l=c.left+j-h,{top:k,left:l}):{top:0,left:0})},p.offset={bodyOffset:function(a){var b=a.offsetTop,c=a.offsetLeft;return p.support.doesNotIncludeMarginInBodyOffset&&(b+=parseFloat(p.css(a,"marginTop"))||0,c+=parseFloat(p.css(a,"marginLeft"))||0),{top:b,left:c}},setOffset:function(a,b,c){var d=p.css(a,"position");d==="static"&&(a.style.position="relative");var e=p(a),f=e.offset(),g=p.css(a,"top"),h=p.css(a,"left"),i=(d==="absolute"||d==="fixed")&&p.inArray("auto",[g,h])>-1,j={},k={},l,m;i?(k=e.position(),l=k.top,m=k.left):(l=parseFloat(g)||0,m=parseFloat(h)||0),p.isFunction(b)&&(b=b.call(a,c,f)),b.top!=null&&(j.top=b.top-f.top+l),b.left!=null&&(j.left=b.left-f.left+m),"using"in b?b.using.call(a,j):e.css(j)}},p.fn.extend({position:function(){if(!this[0])return;var a=this[0],b=this.offsetParent(),c=this.offset(),d=c$.test(b[0].nodeName)?{top:0,left:0}:b.offset();return c.top-=parseFloat(p.css(a,"marginTop"))||0,c.left-=parseFloat(p.css(a,"marginLeft"))||0,d.top+=parseFloat(p.css(b[0],"borderTopWidth"))||0,d.left+=parseFloat(p.css(b[0],"borderLeftWidth"))||0,{top:c.top-d.top,left:c.left-d.left}},offsetParent:function(){return this.map(function(){var a=this.offsetParent||e.body;while(a&&!c$.test(a.nodeName)&&p.css(a,"position")==="static")a=a.offsetParent;return a||e.body})}}),p.each({scrollLeft:"pageXOffset",scrollTop:"pageYOffset"},function(a,c){var d=/Y/.test(c);p.fn[a]=function(e){return p.access(this,function(a,e,f){var g=c_(a);if(f===b)return g?c in g?g[c]:g.document.documentElement[e]:a[e];g?g.scrollTo(d?p(g).scrollLeft():f,d?f:p(g).scrollTop()):a[e]=f},a,e,arguments.length,null)}}),p.each({Height:"height",Width:"width"},function(a,c){p.each({padding:"inner"+a,content:c,"":"outer"+a},function(d,e){p.fn[e]=function(e,f){var g=arguments.length&&(d||typeof e!="boolean"),h=d||(e===!0||f===!0?"margin":"border");return p.access(this,function(c,d,e){var f;return p.isWindow(c)?c.document.documentElement["client"+a]:c.nodeType===9?(f=c.documentElement,Math.max(c.body["scroll"+a],f["scroll"+a],c.body["offset"+a],f["offset"+a],f["client"+a])):e===b?p.css(c,d,e,h):p.style(c,d,e,h)},c,g?e:b,g)}})}),a.jQuery=a.$=p,typeof define=="function"&&define.amd&&define.amd.jQuery&&define("jquery",[],function(){return p})})(window); \ No newline at end of file
+/*! jQuery v@1.8.0 jquery.com | jquery.org/license */
+(function(a,b){function G(a){var b=F[a]={};return p.each(a.split(s),function(a,c){b[c]=!0}),b}function J(a,c,d){if(d===b&&a.nodeType===1){var e="data-"+c.replace(I,"-$1").toLowerCase();d=a.getAttribute(e);if(typeof d=="string"){try{d=d==="true"?!0:d==="false"?!1:d==="null"?null:+d+""===d?+d:H.test(d)?p.parseJSON(d):d}catch(f){}p.data(a,c,d)}else d=b}return d}function K(a){var b;for(b in a){if(b==="data"&&p.isEmptyObject(a[b]))continue;if(b!=="toJSON")return!1}return!0}function ba(){return!1}function bb(){return!0}function bh(a){return!a||!a.parentNode||a.parentNode.nodeType===11}function bi(a,b){do a=a[b];while(a&&a.nodeType!==1);return a}function bj(a,b,c){b=b||0;if(p.isFunction(b))return p.grep(a,function(a,d){var e=!!b.call(a,d,a);return e===c});if(b.nodeType)return p.grep(a,function(a,d){return a===b===c});if(typeof b=="string"){var d=p.grep(a,function(a){return a.nodeType===1});if(be.test(b))return p.filter(b,d,!c);b=p.filter(b,d)}return p.grep(a,function(a,d){return p.inArray(a,b)>=0===c})}function bk(a){var b=bl.split("|"),c=a.createDocumentFragment();if(c.createElement)while(b.length)c.createElement(b.pop());return c}function bC(a,b){return a.getElementsByTagName(b)[0]||a.appendChild(a.ownerDocument.createElement(b))}function bD(a,b){if(b.nodeType!==1||!p.hasData(a))return;var c,d,e,f=p._data(a),g=p._data(b,f),h=f.events;if(h){delete g.handle,g.events={};for(c in h)for(d=0,e=h[c].length;d<e;d++)p.event.add(b,c,h[c][d])}g.data&&(g.data=p.extend({},g.data))}function bE(a,b){var c;if(b.nodeType!==1)return;b.clearAttributes&&b.clearAttributes(),b.mergeAttributes&&b.mergeAttributes(a),c=b.nodeName.toLowerCase(),c==="object"?(b.parentNode&&(b.outerHTML=a.outerHTML),p.support.html5Clone&&a.innerHTML&&!p.trim(b.innerHTML)&&(b.innerHTML=a.innerHTML)):c==="input"&&bv.test(a.type)?(b.defaultChecked=b.checked=a.checked,b.value!==a.value&&(b.value=a.value)):c==="option"?b.selected=a.defaultSelected:c==="input"||c==="textarea"?b.defaultValue=a.defaultValue:c==="script"&&b.text!==a.text&&(b.text=a.text),b.removeAttribute(p.expando)}function bF(a){return typeof a.getElementsByTagName!="undefined"?a.getElementsByTagName("*"):typeof a.querySelectorAll!="undefined"?a.querySelectorAll("*"):[]}function bG(a){bv.test(a.type)&&(a.defaultChecked=a.checked)}function bX(a,b){if(b in a)return b;var c=b.charAt(0).toUpperCase()+b.slice(1),d=b,e=bV.length;while(e--){b=bV[e]+c;if(b in a)return b}return d}function bY(a,b){return a=b||a,p.css(a,"display")==="none"||!p.contains(a.ownerDocument,a)}function bZ(a,b){var c,d,e=[],f=0,g=a.length;for(;f<g;f++){c=a[f];if(!c.style)continue;e[f]=p._data(c,"olddisplay"),b?(!e[f]&&c.style.display==="none"&&(c.style.display=""),c.style.display===""&&bY(c)&&(e[f]=p._data(c,"olddisplay",cb(c.nodeName)))):(d=bH(c,"display"),!e[f]&&d!=="none"&&p._data(c,"olddisplay",d))}for(f=0;f<g;f++){c=a[f];if(!c.style)continue;if(!b||c.style.display==="none"||c.style.display==="")c.style.display=b?e[f]||"":"none"}return a}function b$(a,b,c){var d=bO.exec(b);return d?Math.max(0,d[1]-(c||0))+(d[2]||"px"):b}function b_(a,b,c,d){var e=c===(d?"border":"content")?4:b==="width"?1:0,f=0;for(;e<4;e+=2)c==="margin"&&(f+=p.css(a,c+bU[e],!0)),d?(c==="content"&&(f-=parseFloat(bH(a,"padding"+bU[e]))||0),c!=="margin"&&(f-=parseFloat(bH(a,"border"+bU[e]+"Width"))||0)):(f+=parseFloat(bH(a,"padding"+bU[e]))||0,c!=="padding"&&(f+=parseFloat(bH(a,"border"+bU[e]+"Width"))||0));return f}function ca(a,b,c){var d=b==="width"?a.offsetWidth:a.offsetHeight,e=!0,f=p.support.boxSizing&&p.css(a,"boxSizing")==="border-box";if(d<=0){d=bH(a,b);if(d<0||d==null)d=a.style[b];if(bP.test(d))return d;e=f&&(p.support.boxSizingReliable||d===a.style[b]),d=parseFloat(d)||0}return d+b_(a,b,c||(f?"border":"content"),e)+"px"}function cb(a){if(bR[a])return bR[a];var b=p("<"+a+">").appendTo(e.body),c=b.css("display");b.remove();if(c==="none"||c===""){bI=e.body.appendChild(bI||p.extend(e.createElement("iframe"),{frameBorder:0,width:0,height:0}));if(!bJ||!bI.createElement)bJ=(bI.contentWindow||bI.contentDocument).document,bJ.write("<!doctype html><html><body>"),bJ.close();b=bJ.body.appendChild(bJ.createElement(a)),c=bH(b,"display"),e.body.removeChild(bI)}return bR[a]=c,c}function ch(a,b,c,d){var e;if(p.isArray(b))p.each(b,function(b,e){c||cd.test(a)?d(a,e):ch(a+"["+(typeof e=="object"?b:"")+"]",e,c,d)});else if(!c&&p.type(b)==="object")for(e in b)ch(a+"["+e+"]",b[e],c,d);else d(a,b)}function cy(a){return function(b,c){typeof b!="string"&&(c=b,b="*");var d,e,f,g=b.toLowerCase().split(s),h=0,i=g.length;if(p.isFunction(c))for(;h<i;h++)d=g[h],f=/^\+/.test(d),f&&(d=d.substr(1)||"*"),e=a[d]=a[d]||[],e[f?"unshift":"push"](c)}}function cz(a,c,d,e,f,g){f=f||c.dataTypes[0],g=g||{},g[f]=!0;var h,i=a[f],j=0,k=i?i.length:0,l=a===cu;for(;j<k&&(l||!h);j++)h=i[j](c,d,e),typeof h=="string"&&(!l||g[h]?h=b:(c.dataTypes.unshift(h),h=cz(a,c,d,e,h,g)));return(l||!h)&&!g["*"]&&(h=cz(a,c,d,e,"*",g)),h}function cA(a,c){var d,e,f=p.ajaxSettings.flatOptions||{};for(d in c)c[d]!==b&&((f[d]?a:e||(e={}))[d]=c[d]);e&&p.extend(!0,a,e)}function cB(a,c,d){var e,f,g,h,i=a.contents,j=a.dataTypes,k=a.responseFields;for(f in k)f in d&&(c[k[f]]=d[f]);while(j[0]==="*")j.shift(),e===b&&(e=a.mimeType||c.getResponseHeader("content-type"));if(e)for(f in i)if(i[f]&&i[f].test(e)){j.unshift(f);break}if(j[0]in d)g=j[0];else{for(f in d){if(!j[0]||a.converters[f+" "+j[0]]){g=f;break}h||(h=f)}g=g||h}if(g)return g!==j[0]&&j.unshift(g),d[g]}function cC(a,b){var c,d,e,f,g=a.dataTypes.slice(),h=g[0],i={},j=0;a.dataFilter&&(b=a.dataFilter(b,a.dataType));if(g[1])for(c in a.converters)i[c.toLowerCase()]=a.converters[c];for(;e=g[++j];)if(e!=="*"){if(h!=="*"&&h!==e){c=i[h+" "+e]||i["* "+e];if(!c)for(d in i){f=d.split(" ");if(f[1]===e){c=i[h+" "+f[0]]||i["* "+f[0]];if(c){c===!0?c=i[d]:i[d]!==!0&&(e=f[0],g.splice(j--,0,e));break}}}if(c!==!0)if(c&&a["throws"])b=c(b);else try{b=c(b)}catch(k){return{state:"parsererror",error:c?k:"No conversion from "+h+" to "+e}}}h=e}return{state:"success",data:b}}function cK(){try{return new a.XMLHttpRequest}catch(b){}}function cL(){try{return new a.ActiveXObject("Microsoft.XMLHTTP")}catch(b){}}function cT(){return setTimeout(function(){cM=b},0),cM=p.now()}function cU(a,b){p.each(b,function(b,c){var d=(cS[b]||[]).concat(cS["*"]),e=0,f=d.length;for(;e<f;e++)if(d[e].call(a,b,c))return})}function cV(a,b,c){var d,e=0,f=0,g=cR.length,h=p.Deferred().always(function(){delete i.elem}),i=function(){var b=cM||cT(),c=Math.max(0,j.startTime+j.duration-b),d=1-(c/j.duration||0),e=0,f=j.tweens.length;for(;e<f;e++)j.tweens[e].run(d);return h.notifyWith(a,[j,d,c]),d<1&&f?c:(h.resolveWith(a,[j]),!1)},j=h.promise({elem:a,props:p.extend({},b),opts:p.extend(!0,{specialEasing:{}},c),originalProperties:b,originalOptions:c,startTime:cM||cT(),duration:c.duration,tweens:[],createTween:function(b,c,d){var e=p.Tween(a,j.opts,b,c,j.opts.specialEasing[b]||j.opts.easing);return j.tweens.push(e),e},stop:function(b){var c=0,d=b?j.tweens.length:0;for(;c<d;c++)j.tweens[c].run(1);return b?h.resolveWith(a,[j,b]):h.rejectWith(a,[j,b]),this}}),k=j.props;cW(k,j.opts.specialEasing);for(;e<g;e++){d=cR[e].call(j,a,k,j.opts);if(d)return d}return cU(j,k),p.isFunction(j.opts.start)&&j.opts.start.call(a,j),p.fx.timer(p.extend(i,{anim:j,queue:j.opts.queue,elem:a})),j.progress(j.opts.progress).done(j.opts.done,j.opts.complete).fail(j.opts.fail).always(j.opts.always)}function cW(a,b){var c,d,e,f,g;for(c in a){d=p.camelCase(c),e=b[d],f=a[c],p.isArray(f)&&(e=f[1],f=a[c]=f[0]),c!==d&&(a[d]=f,delete a[c]),g=p.cssHooks[d];if(g&&"expand"in g){f=g.expand(f),delete a[d];for(c in f)c in a||(a[c]=f[c],b[c]=e)}else b[d]=e}}function cX(a,b,c){var d,e,f,g,h,i,j,k,l=this,m=a.style,n={},o=[],q=a.nodeType&&bY(a);c.queue||(j=p._queueHooks(a,"fx"),j.unqueued==null&&(j.unqueued=0,k=j.empty.fire,j.empty.fire=function(){j.unqueued||k()}),j.unqueued++,l.always(function(){l.always(function(){j.unqueued--,p.queue(a,"fx").length||j.empty.fire()})})),a.nodeType===1&&("height"in b||"width"in b)&&(c.overflow=[m.overflow,m.overflowX,m.overflowY],p.css(a,"display")==="inline"&&p.css(a,"float")==="none"&&(!p.support.inlineBlockNeedsLayout||cb(a.nodeName)==="inline"?m.display="inline-block":m.zoom=1)),c.overflow&&(m.overflow="hidden",p.support.shrinkWrapBlocks||l.done(function(){m.overflow=c.overflow[0],m.overflowX=c.overflow[1],m.overflowY=c.overflow[2]}));for(d in b){f=b[d];if(cO.exec(f)){delete b[d];if(f===(q?"hide":"show"))continue;o.push(d)}}g=o.length;if(g){h=p._data(a,"fxshow")||p._data(a,"fxshow",{}),q?p(a).show():l.done(function(){p(a).hide()}),l.done(function(){var b;p.removeData(a,"fxshow",!0);for(b in n)p.style(a,b,n[b])});for(d=0;d<g;d++)e=o[d],i=l.createTween(e,q?h[e]:0),n[e]=h[e]||p.style(a,e),e in h||(h[e]=i.start,q&&(i.end=i.start,i.start=e==="width"||e==="height"?1:0))}}function cY(a,b,c,d,e){return new cY.prototype.init(a,b,c,d,e)}function cZ(a,b){var c,d={height:a},e=0;for(;e<4;e+=2-b)c=bU[e],d["margin"+c]=d["padding"+c]=a;return b&&(d.opacity=d.width=a),d}function c_(a){return p.isWindow(a)?a:a.nodeType===9?a.defaultView||a.parentWindow:!1}var c,d,e=a.document,f=a.location,g=a.navigator,h=a.jQuery,i=a.$,j=Array.prototype.push,k=Array.prototype.slice,l=Array.prototype.indexOf,m=Object.prototype.toString,n=Object.prototype.hasOwnProperty,o=String.prototype.trim,p=function(a,b){return new p.fn.init(a,b,c)},q=/[\-+]?(?:\d*\.|)\d+(?:[eE][\-+]?\d+|)/.source,r=/\S/,s=/\s+/,t=r.test(" ")?/^[\s\xA0]+|[\s\xA0]+$/g:/^\s+|\s+$/g,u=/^(?:[^#<]*(<[\w\W]+>)[^>]*$|#([\w\-]*)$)/,v=/^<(\w+)\s*\/?>(?:<\/\1>|)$/,w=/^[\],:{}\s]*$/,x=/(?:^|:|,)(?:\s*\[)+/g,y=/\\(?:["\\\/bfnrt]|u[\da-fA-F]{4})/g,z=/"[^"\\\r\n]*"|true|false|null|-?(?:\d\d*\.|)\d+(?:[eE][\-+]?\d+|)/g,A=/^-ms-/,B=/-([\da-z])/gi,C=function(a,b){return(b+"").toUpperCase()},D=function(){e.addEventListener?(e.removeEventListener("DOMContentLoaded",D,!1),p.ready()):e.readyState==="complete"&&(e.detachEvent("onreadystatechange",D),p.ready())},E={};p.fn=p.prototype={constructor:p,init:function(a,c,d){var f,g,h,i;if(!a)return this;if(a.nodeType)return this.context=this[0]=a,this.length=1,this;if(typeof a=="string"){a.charAt(0)==="<"&&a.charAt(a.length-1)===">"&&a.length>=3?f=[null,a,null]:f=u.exec(a);if(f&&(f[1]||!c)){if(f[1])return c=c instanceof p?c[0]:c,i=c&&c.nodeType?c.ownerDocument||c:e,a=p.parseHTML(f[1],i,!0),v.test(f[1])&&p.isPlainObject(c)&&this.attr.call(a,c,!0),p.merge(this,a);g=e.getElementById(f[2]);if(g&&g.parentNode){if(g.id!==f[2])return d.find(a);this.length=1,this[0]=g}return this.context=e,this.selector=a,this}return!c||c.jquery?(c||d).find(a):this.constructor(c).find(a)}return p.isFunction(a)?d.ready(a):(a.selector!==b&&(this.selector=a.selector,this.context=a.context),p.makeArray(a,this))},selector:"",jquery:"1.8.0",length:0,size:function(){return this.length},toArray:function(){return k.call(this)},get:function(a){return a==null?this.toArray():a<0?this[this.length+a]:this[a]},pushStack:function(a,b,c){var d=p.merge(this.constructor(),a);return d.prevObject=this,d.context=this.context,b==="find"?d.selector=this.selector+(this.selector?" ":"")+c:b&&(d.selector=this.selector+"."+b+"("+c+")"),d},each:function(a,b){return p.each(this,a,b)},ready:function(a){return p.ready.promise().done(a),this},eq:function(a){return a=+a,a===-1?this.slice(a):this.slice(a,a+1)},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},slice:function(){return this.pushStack(k.apply(this,arguments),"slice",k.call(arguments).join(","))},map:function(a){return this.pushStack(p.map(this,function(b,c){return a.call(b,c,b)}))},end:function(){return this.prevObject||this.constructor(null)},push:j,sort:[].sort,splice:[].splice},p.fn.init.prototype=p.fn,p.extend=p.fn.extend=function(){var a,c,d,e,f,g,h=arguments[0]||{},i=1,j=arguments.length,k=!1;typeof h=="boolean"&&(k=h,h=arguments[1]||{},i=2),typeof h!="object"&&!p.isFunction(h)&&(h={}),j===i&&(h=this,--i);for(;i<j;i++)if((a=arguments[i])!=null)for(c in a){d=h[c],e=a[c];if(h===e)continue;k&&e&&(p.isPlainObject(e)||(f=p.isArray(e)))?(f?(f=!1,g=d&&p.isArray(d)?d:[]):g=d&&p.isPlainObject(d)?d:{},h[c]=p.extend(k,g,e)):e!==b&&(h[c]=e)}return h},p.extend({noConflict:function(b){return a.$===p&&(a.$=i),b&&a.jQuery===p&&(a.jQuery=h),p},isReady:!1,readyWait:1,holdReady:function(a){a?p.readyWait++:p.ready(!0)},ready:function(a){if(a===!0?--p.readyWait:p.isReady)return;if(!e.body)return setTimeout(p.ready,1);p.isReady=!0;if(a!==!0&&--p.readyWait>0)return;d.resolveWith(e,[p]),p.fn.trigger&&p(e).trigger("ready").off("ready")},isFunction:function(a){return p.type(a)==="function"},isArray:Array.isArray||function(a){return p.type(a)==="array"},isWindow:function(a){return a!=null&&a==a.window},isNumeric:function(a){return!isNaN(parseFloat(a))&&isFinite(a)},type:function(a){return a==null?String(a):E[m.call(a)]||"object"},isPlainObject:function(a){if(!a||p.type(a)!=="object"||a.nodeType||p.isWindow(a))return!1;try{if(a.constructor&&!n.call(a,"constructor")&&!n.call(a.constructor.prototype,"isPrototypeOf"))return!1}catch(c){return!1}var d;for(d in a);return d===b||n.call(a,d)},isEmptyObject:function(a){var b;for(b in a)return!1;return!0},error:function(a){throw new Error(a)},parseHTML:function(a,b,c){var d;return!a||typeof a!="string"?null:(typeof b=="boolean"&&(c=b,b=0),b=b||e,(d=v.exec(a))?[b.createElement(d[1])]:(d=p.buildFragment([a],b,c?null:[]),p.merge([],(d.cacheable?p.clone(d.fragment):d.fragment).childNodes)))},parseJSON:function(b){if(!b||typeof b!="string")return null;b=p.trim(b);if(a.JSON&&a.JSON.parse)return a.JSON.parse(b);if(w.test(b.replace(y,"@").replace(z,"]").replace(x,"")))return(new Function("return "+b))();p.error("Invalid JSON: "+b)},parseXML:function(c){var d,e;if(!c||typeof c!="string")return null;try{a.DOMParser?(e=new DOMParser,d=e.parseFromString(c,"text/xml")):(d=new ActiveXObject("Microsoft.XMLDOM"),d.async="false",d.loadXML(c))}catch(f){d=b}return(!d||!d.documentElement||d.getElementsByTagName("parsererror").length)&&p.error("Invalid XML: "+c),d},noop:function(){},globalEval:function(b){b&&r.test(b)&&(a.execScript||function(b){a.eval.call(a,b)})(b)},camelCase:function(a){return a.replace(A,"ms-").replace(B,C)},nodeName:function(a,b){return a.nodeName&&a.nodeName.toUpperCase()===b.toUpperCase()},each:function(a,c,d){var e,f=0,g=a.length,h=g===b||p.isFunction(a);if(d){if(h){for(e in a)if(c.apply(a[e],d)===!1)break}else for(;f<g;)if(c.apply(a[f++],d)===!1)break}else if(h){for(e in a)if(c.call(a[e],e,a[e])===!1)break}else for(;f<g;)if(c.call(a[f],f,a[f++])===!1)break;return a},trim:o?function(a){return a==null?"":o.call(a)}:function(a){return a==null?"":a.toString().replace(t,"")},makeArray:function(a,b){var c,d=b||[];return a!=null&&(c=p.type(a),a.length==null||c==="string"||c==="function"||c==="regexp"||p.isWindow(a)?j.call(d,a):p.merge(d,a)),d},inArray:function(a,b,c){var d;if(b){if(l)return l.call(b,a,c);d=b.length,c=c?c<0?Math.max(0,d+c):c:0;for(;c<d;c++)if(c in b&&b[c]===a)return c}return-1},merge:function(a,c){var d=c.length,e=a.length,f=0;if(typeof d=="number")for(;f<d;f++)a[e++]=c[f];else while(c[f]!==b)a[e++]=c[f++];return a.length=e,a},grep:function(a,b,c){var d,e=[],f=0,g=a.length;c=!!c;for(;f<g;f++)d=!!b(a[f],f),c!==d&&e.push(a[f]);return e},map:function(a,c,d){var e,f,g=[],h=0,i=a.length,j=a instanceof p||i!==b&&typeof i=="number"&&(i>0&&a[0]&&a[i-1]||i===0||p.isArray(a));if(j)for(;h<i;h++)e=c(a[h],h,d),e!=null&&(g[g.length]=e);else for(f in a)e=c(a[f],f,d),e!=null&&(g[g.length]=e);return g.concat.apply([],g)},guid:1,proxy:function(a,c){var d,e,f;return typeof c=="string"&&(d=a[c],c=a,a=d),p.isFunction(a)?(e=k.call(arguments,2),f=function(){return a.apply(c,e.concat(k.call(arguments)))},f.guid=a.guid=a.guid||f.guid||p.guid++,f):b},access:function(a,c,d,e,f,g,h){var i,j=d==null,k=0,l=a.length;if(d&&typeof d=="object"){for(k in d)p.access(a,c,k,d[k],1,g,e);f=1}else if(e!==b){i=h===b&&p.isFunction(e),j&&(i?(i=c,c=function(a,b,c){return i.call(p(a),c)}):(c.call(a,e),c=null));if(c)for(;k<l;k++)c(a[k],d,i?e.call(a[k],k,c(a[k],d)):e,h);f=1}return f?a:j?c.call(a):l?c(a[0],d):g},now:function(){return(new Date).getTime()}}),p.ready.promise=function(b){if(!d){d=p.Deferred();if(e.readyState==="complete"||e.readyState!=="loading"&&e.addEventListener)setTimeout(p.ready,1);else if(e.addEventListener)e.addEventListener("DOMContentLoaded",D,!1),a.addEventListener("load",p.ready,!1);else{e.attachEvent("onreadystatechange",D),a.attachEvent("onload",p.ready);var c=!1;try{c=a.frameElement==null&&e.documentElement}catch(f){}c&&c.doScroll&&function g(){if(!p.isReady){try{c.doScroll("left")}catch(a){return setTimeout(g,50)}p.ready()}}()}}return d.promise(b)},p.each("Boolean Number String Function Array Date RegExp Object".split(" "),function(a,b){E["[object "+b+"]"]=b.toLowerCase()}),c=p(e);var F={};p.Callbacks=function(a){a=typeof a=="string"?F[a]||G(a):p.extend({},a);var c,d,e,f,g,h,i=[],j=!a.once&&[],k=function(b){c=a.memory&&b,d=!0,h=f||0,f=0,g=i.length,e=!0;for(;i&&h<g;h++)if(i[h].apply(b[0],b[1])===!1&&a.stopOnFalse){c=!1;break}e=!1,i&&(j?j.length&&k(j.shift()):c?i=[]:l.disable())},l={add:function(){if(i){var b=i.length;(function d(b){p.each(b,function(b,c){p.isFunction(c)&&(!a.unique||!l.has(c))?i.push(c):c&&c.length&&d(c)})})(arguments),e?g=i.length:c&&(f=b,k(c))}return this},remove:function(){return i&&p.each(arguments,function(a,b){var c;while((c=p.inArray(b,i,c))>-1)i.splice(c,1),e&&(c<=g&&g--,c<=h&&h--)}),this},has:function(a){return p.inArray(a,i)>-1},empty:function(){return i=[],this},disable:function(){return i=j=c=b,this},disabled:function(){return!i},lock:function(){return j=b,c||l.disable(),this},locked:function(){return!j},fireWith:function(a,b){return b=b||[],b=[a,b.slice?b.slice():b],i&&(!d||j)&&(e?j.push(b):k(b)),this},fire:function(){return l.fireWith(this,arguments),this},fired:function(){return!!d}};return l},p.extend({Deferred:function(a){var b=[["resolve","done",p.Callbacks("once memory"),"resolved"],["reject","fail",p.Callbacks("once memory"),"rejected"],["notify","progress",p.Callbacks("memory")]],c="pending",d={state:function(){return c},always:function(){return e.done(arguments).fail(arguments),this},then:function(){var a=arguments;return p.Deferred(function(c){p.each(b,function(b,d){var f=d[0],g=a[b];e[d[1]](p.isFunction(g)?function(){var a=g.apply(this,arguments);a&&p.isFunction(a.promise)?a.promise().done(c.resolve).fail(c.reject).progress(c.notify):c[f+"With"](this===e?c:this,[a])}:c[f])}),a=null}).promise()},promise:function(a){return typeof a=="object"?p.extend(a,d):d}},e={};return d.pipe=d.then,p.each(b,function(a,f){var g=f[2],h=f[3];d[f[1]]=g.add,h&&g.add(function(){c=h},b[a^1][2].disable,b[2][2].lock),e[f[0]]=g.fire,e[f[0]+"With"]=g.fireWith}),d.promise(e),a&&a.call(e,e),e},when:function(a){var b=0,c=k.call(arguments),d=c.length,e=d!==1||a&&p.isFunction(a.promise)?d:0,f=e===1?a:p.Deferred(),g=function(a,b,c){return function(d){b[a]=this,c[a]=arguments.length>1?k.call(arguments):d,c===h?f.notifyWith(b,c):--e||f.resolveWith(b,c)}},h,i,j;if(d>1){h=new Array(d),i=new Array(d),j=new Array(d);for(;b<d;b++)c[b]&&p.isFunction(c[b].promise)?c[b].promise().done(g(b,j,c)).fail(f.reject).progress(g(b,i,h)):--e}return e||f.resolveWith(j,c),f.promise()}}),p.support=function(){var b,c,d,f,g,h,i,j,k,l,m,n=e.createElement("div");n.setAttribute("className","t"),n.innerHTML=" <link/><table></table><a href='/a'>a</a><input type='checkbox'/>",c=n.getElementsByTagName("*"),d=n.getElementsByTagName("a")[0],d.style.cssText="top:1px;float:left;opacity:.5";if(!c||!c.length||!d)return{};f=e.createElement("select"),g=f.appendChild(e.createElement("option")),h=n.getElementsByTagName("input")[0],b={leadingWhitespace:n.firstChild.nodeType===3,tbody:!n.getElementsByTagName("tbody").length,htmlSerialize:!!n.getElementsByTagName("link").length,style:/top/.test(d.getAttribute("style")),hrefNormalized:d.getAttribute("href")==="/a",opacity:/^0.5/.test(d.style.opacity),cssFloat:!!d.style.cssFloat,checkOn:h.value==="on",optSelected:g.selected,getSetAttribute:n.className!=="t",enctype:!!e.createElement("form").enctype,html5Clone:e.createElement("nav").cloneNode(!0).outerHTML!=="<:nav></:nav>",boxModel:e.compatMode==="CSS1Compat",submitBubbles:!0,changeBubbles:!0,focusinBubbles:!1,deleteExpando:!0,noCloneEvent:!0,inlineBlockNeedsLayout:!1,shrinkWrapBlocks:!1,reliableMarginRight:!0,boxSizingReliable:!0,pixelPosition:!1},h.checked=!0,b.noCloneChecked=h.cloneNode(!0).checked,f.disabled=!0,b.optDisabled=!g.disabled;try{delete n.test}catch(o){b.deleteExpando=!1}!n.addEventListener&&n.attachEvent&&n.fireEvent&&(n.attachEvent("onclick",m=function(){b.noCloneEvent=!1}),n.cloneNode(!0).fireEvent("onclick"),n.detachEvent("onclick",m)),h=e.createElement("input"),h.value="t",h.setAttribute("type","radio"),b.radioValue=h.value==="t",h.setAttribute("checked","checked"),h.setAttribute("name","t"),n.appendChild(h),i=e.createDocumentFragment(),i.appendChild(n.lastChild),b.checkClone=i.cloneNode(!0).cloneNode(!0).lastChild.checked,b.appendChecked=h.checked,i.removeChild(h),i.appendChild(n);if(n.attachEvent)for(k in{submit:!0,change:!0,focusin:!0})j="on"+k,l=j in n,l||(n.setAttribute(j,"return;"),l=typeof n[j]=="function"),b[k+"Bubbles"]=l;return p(function(){var c,d,f,g,h="padding:0;margin:0;border:0;display:block;overflow:hidden;",i=e.getElementsByTagName("body")[0];if(!i)return;c=e.createElement("div"),c.style.cssText="visibility:hidden;border:0;width:0;height:0;position:static;top:0;margin-top:1px",i.insertBefore(c,i.firstChild),d=e.createElement("div"),c.appendChild(d),d.innerHTML="<table><tr><td></td><td>t</td></tr></table>",f=d.getElementsByTagName("td"),f[0].style.cssText="padding:0;margin:0;border:0;display:none",l=f[0].offsetHeight===0,f[0].style.display="",f[1].style.display="none",b.reliableHiddenOffsets=l&&f[0].offsetHeight===0,d.innerHTML="",d.style.cssText="box-sizing:border-box;-moz-box-sizing:border-box;-webkit-box-sizing:border-box;padding:1px;border:1px;display:block;width:4px;margin-top:1%;position:absolute;top:1%;",b.boxSizing=d.offsetWidth===4,b.doesNotIncludeMarginInBodyOffset=i.offsetTop!==1,a.getComputedStyle&&(b.pixelPosition=(a.getComputedStyle(d,null)||{}).top!=="1%",b.boxSizingReliable=(a.getComputedStyle(d,null)||{width:"4px"}).width==="4px",g=e.createElement("div"),g.style.cssText=d.style.cssText=h,g.style.marginRight=g.style.width="0",d.style.width="1px",d.appendChild(g),b.reliableMarginRight=!parseFloat((a.getComputedStyle(g,null)||{}).marginRight)),typeof d.style.zoom!="undefined"&&(d.innerHTML="",d.style.cssText=h+"width:1px;padding:1px;display:inline;zoom:1",b.inlineBlockNeedsLayout=d.offsetWidth===3,d.style.display="block",d.style.overflow="visible",d.innerHTML="<div></div>",d.firstChild.style.width="5px",b.shrinkWrapBlocks=d.offsetWidth!==3,c.style.zoom=1),i.removeChild(c),c=d=f=g=null}),i.removeChild(n),c=d=f=g=h=i=n=null,b}();var H=/^(?:\{.*\}|\[.*\])$/,I=/([A-Z])/g;p.extend({cache:{},deletedIds:[],uuid:0,expando:"jQuery"+(p.fn.jquery+Math.random()).replace(/\D/g,""),noData:{embed:!0,object:"clsid:D27CDB6E-AE6D-11cf-96B8-444553540000",applet:!0},hasData:function(a){return a=a.nodeType?p.cache[a[p.expando]]:a[p.expando],!!a&&!K(a)},data:function(a,c,d,e){if(!p.acceptData(a))return;var f,g,h=p.expando,i=typeof c=="string",j=a.nodeType,k=j?p.cache:a,l=j?a[h]:a[h]&&h;if((!l||!k[l]||!e&&!k[l].data)&&i&&d===b)return;l||(j?a[h]=l=p.deletedIds.pop()||++p.uuid:l=h),k[l]||(k[l]={},j||(k[l].toJSON=p.noop));if(typeof c=="object"||typeof c=="function")e?k[l]=p.extend(k[l],c):k[l].data=p.extend(k[l].data,c);return f=k[l],e||(f.data||(f.data={}),f=f.data),d!==b&&(f[p.camelCase(c)]=d),i?(g=f[c],g==null&&(g=f[p.camelCase(c)])):g=f,g},removeData:function(a,b,c){if(!p.acceptData(a))return;var d,e,f,g=a.nodeType,h=g?p.cache:a,i=g?a[p.expando]:p.expando;if(!h[i])return;if(b){d=c?h[i]:h[i].data;if(d){p.isArray(b)||(b in d?b=[b]:(b=p.camelCase(b),b in d?b=[b]:b=b.split(" ")));for(e=0,f=b.length;e<f;e++)delete d[b[e]];if(!(c?K:p.isEmptyObject)(d))return}}if(!c){delete h[i].data;if(!K(h[i]))return}g?p.cleanData([a],!0):p.support.deleteExpando||h!=h.window?delete h[i]:h[i]=null},_data:function(a,b,c){return p.data(a,b,c,!0)},acceptData:function(a){var b=a.nodeName&&p.noData[a.nodeName.toLowerCase()];return!b||b!==!0&&a.getAttribute("classid")===b}}),p.fn.extend({data:function(a,c){var d,e,f,g,h,i=this[0],j=0,k=null;if(a===b){if(this.length){k=p.data(i);if(i.nodeType===1&&!p._data(i,"parsedAttrs")){f=i.attributes;for(h=f.length;j<h;j++)g=f[j].name,g.indexOf("data-")===0&&(g=p.camelCase(g.substring(5)),J(i,g,k[g]));p._data(i,"parsedAttrs",!0)}}return k}return typeof a=="object"?this.each(function(){p.data(this,a)}):(d=a.split(".",2),d[1]=d[1]?"."+d[1]:"",e=d[1]+"!",p.access(this,function(c){if(c===b)return k=this.triggerHandler("getData"+e,[d[0]]),k===b&&i&&(k=p.data(i,a),k=J(i,a,k)),k===b&&d[1]?this.data(d[0]):k;d[1]=c,this.each(function(){var b=p(this);b.triggerHandler("setData"+e,d),p.data(this,a,c),b.triggerHandler("changeData"+e,d)})},null,c,arguments.length>1,null,!1))},removeData:function(a){return this.each(function(){p.removeData(this,a)})}}),p.extend({queue:function(a,b,c){var d;if(a)return b=(b||"fx")+"queue",d=p._data(a,b),c&&(!d||p.isArray(c)?d=p._data(a,b,p.makeArray(c)):d.push(c)),d||[]},dequeue:function(a,b){b=b||"fx";var c=p.queue(a,b),d=c.shift(),e=p._queueHooks(a,b),f=function(){p.dequeue(a,b)};d==="inprogress"&&(d=c.shift()),d&&(b==="fx"&&c.unshift("inprogress"),delete e.stop,d.call(a,f,e)),!c.length&&e&&e.empty.fire()},_queueHooks:function(a,b){var c=b+"queueHooks";return p._data(a,c)||p._data(a,c,{empty:p.Callbacks("once memory").add(function(){p.removeData(a,b+"queue",!0),p.removeData(a,c,!0)})})}}),p.fn.extend({queue:function(a,c){var d=2;return typeof a!="string"&&(c=a,a="fx",d--),arguments.length<d?p.queue(this[0],a):c===b?this:this.each(function(){var b=p.queue(this,a,c);p._queueHooks(this,a),a==="fx"&&b[0]!=="inprogress"&&p.dequeue(this,a)})},dequeue:function(a){return this.each(function(){p.dequeue(this,a)})},delay:function(a,b){return a=p.fx?p.fx.speeds[a]||a:a,b=b||"fx",this.queue(b,function(b,c){var d=setTimeout(b,a);c.stop=function(){clearTimeout(d)}})},clearQueue:function(a){return this.queue(a||"fx",[])},promise:function(a,c){var d,e=1,f=p.Deferred(),g=this,h=this.length,i=function(){--e||f.resolveWith(g,[g])};typeof a!="string"&&(c=a,a=b),a=a||"fx";while(h--)(d=p._data(g[h],a+"queueHooks"))&&d.empty&&(e++,d.empty.add(i));return i(),f.promise(c)}});var L,M,N,O=/[\t\r\n]/g,P=/\r/g,Q=/^(?:button|input)$/i,R=/^(?:button|input|object|select|textarea)$/i,S=/^a(?:rea|)$/i,T=/^(?:autofocus|autoplay|async|checked|controls|defer|disabled|hidden|loop|multiple|open|readonly|required|scoped|selected)$/i,U=p.support.getSetAttribute;p.fn.extend({attr:function(a,b){return p.access(this,p.attr,a,b,arguments.length>1)},removeAttr:function(a){return this.each(function(){p.removeAttr(this,a)})},prop:function(a,b){return p.access(this,p.prop,a,b,arguments.length>1)},removeProp:function(a){return a=p.propFix[a]||a,this.each(function(){try{this[a]=b,delete this[a]}catch(c){}})},addClass:function(a){var b,c,d,e,f,g,h;if(p.isFunction(a))return this.each(function(b){p(this).addClass(a.call(this,b,this.className))});if(a&&typeof a=="string"){b=a.split(s);for(c=0,d=this.length;c<d;c++){e=this[c];if(e.nodeType===1)if(!e.className&&b.length===1)e.className=a;else{f=" "+e.className+" ";for(g=0,h=b.length;g<h;g++)~f.indexOf(" "+b[g]+" ")||(f+=b[g]+" ");e.className=p.trim(f)}}}return this},removeClass:function(a){var c,d,e,f,g,h,i;if(p.isFunction(a))return this.each(function(b){p(this).removeClass(a.call(this,b,this.className))});if(a&&typeof a=="string"||a===b){c=(a||"").split(s);for(h=0,i=this.length;h<i;h++){e=this[h];if(e.nodeType===1&&e.className){d=(" "+e.className+" ").replace(O," ");for(f=0,g=c.length;f<g;f++)while(d.indexOf(" "+c[f]+" ")>-1)d=d.replace(" "+c[f]+" "," ");e.className=a?p.trim(d):""}}}return this},toggleClass:function(a,b){var c=typeof a,d=typeof b=="boolean";return p.isFunction(a)?this.each(function(c){p(this).toggleClass(a.call(this,c,this.className,b),b)}):this.each(function(){if(c==="string"){var e,f=0,g=p(this),h=b,i=a.split(s);while(e=i[f++])h=d?h:!g.hasClass(e),g[h?"addClass":"removeClass"](e)}else if(c==="undefined"||c==="boolean")this.className&&p._data(this,"__className__",this.className),this.className=this.className||a===!1?"":p._data(this,"__className__")||""})},hasClass:function(a){var b=" "+a+" ",c=0,d=this.length;for(;c<d;c++)if(this[c].nodeType===1&&(" "+this[c].className+" ").replace(O," ").indexOf(b)>-1)return!0;return!1},val:function(a){var c,d,e,f=this[0];if(!arguments.length){if(f)return c=p.valHooks[f.type]||p.valHooks[f.nodeName.toLowerCase()],c&&"get"in c&&(d=c.get(f,"value"))!==b?d:(d=f.value,typeof d=="string"?d.replace(P,""):d==null?"":d);return}return e=p.isFunction(a),this.each(function(d){var f,g=p(this);if(this.nodeType!==1)return;e?f=a.call(this,d,g.val()):f=a,f==null?f="":typeof f=="number"?f+="":p.isArray(f)&&(f=p.map(f,function(a){return a==null?"":a+""})),c=p.valHooks[this.type]||p.valHooks[this.nodeName.toLowerCase()];if(!c||!("set"in c)||c.set(this,f,"value")===b)this.value=f})}}),p.extend({valHooks:{option:{get:function(a){var b=a.attributes.value;return!b||b.specified?a.value:a.text}},select:{get:function(a){var b,c,d,e,f=a.selectedIndex,g=[],h=a.options,i=a.type==="select-one";if(f<0)return null;c=i?f:0,d=i?f+1:h.length;for(;c<d;c++){e=h[c];if(e.selected&&(p.support.optDisabled?!e.disabled:e.getAttribute("disabled")===null)&&(!e.parentNode.disabled||!p.nodeName(e.parentNode,"optgroup"))){b=p(e).val();if(i)return b;g.push(b)}}return i&&!g.length&&h.length?p(h[f]).val():g},set:function(a,b){var c=p.makeArray(b);return p(a).find("option").each(function(){this.selected=p.inArray(p(this).val(),c)>=0}),c.length||(a.selectedIndex=-1),c}}},attrFn:{},attr:function(a,c,d,e){var f,g,h,i=a.nodeType;if(!a||i===3||i===8||i===2)return;if(e&&p.isFunction(p.fn[c]))return p(a)[c](d);if(typeof a.getAttribute=="undefined")return p.prop(a,c,d);h=i!==1||!p.isXMLDoc(a),h&&(c=c.toLowerCase(),g=p.attrHooks[c]||(T.test(c)?M:L));if(d!==b){if(d===null){p.removeAttr(a,c);return}return g&&"set"in g&&h&&(f=g.set(a,d,c))!==b?f:(a.setAttribute(c,""+d),d)}return g&&"get"in g&&h&&(f=g.get(a,c))!==null?f:(f=a.getAttribute(c),f===null?b:f)},removeAttr:function(a,b){var c,d,e,f,g=0;if(b&&a.nodeType===1){d=b.split(s);for(;g<d.length;g++)e=d[g],e&&(c=p.propFix[e]||e,f=T.test(e),f||p.attr(a,e,""),a.removeAttribute(U?e:c),f&&c in a&&(a[c]=!1))}},attrHooks:{type:{set:function(a,b){if(Q.test(a.nodeName)&&a.parentNode)p.error("type property can't be changed");else if(!p.support.radioValue&&b==="radio"&&p.nodeName(a,"input")){var c=a.value;return a.setAttribute("type",b),c&&(a.value=c),b}}},value:{get:function(a,b){return L&&p.nodeName(a,"button")?L.get(a,b):b in a?a.value:null},set:function(a,b,c){if(L&&p.nodeName(a,"button"))return L.set(a,b,c);a.value=b}}},propFix:{tabindex:"tabIndex",readonly:"readOnly","for":"htmlFor","class":"className",maxlength:"maxLength",cellspacing:"cellSpacing",cellpadding:"cellPadding",rowspan:"rowSpan",colspan:"colSpan",usemap:"useMap",frameborder:"frameBorder",contenteditable:"contentEditable"},prop:function(a,c,d){var e,f,g,h=a.nodeType;if(!a||h===3||h===8||h===2)return;return g=h!==1||!p.isXMLDoc(a),g&&(c=p.propFix[c]||c,f=p.propHooks[c]),d!==b?f&&"set"in f&&(e=f.set(a,d,c))!==b?e:a[c]=d:f&&"get"in f&&(e=f.get(a,c))!==null?e:a[c]},propHooks:{tabIndex:{get:function(a){var c=a.getAttributeNode("tabindex");return c&&c.specified?parseInt(c.value,10):R.test(a.nodeName)||S.test(a.nodeName)&&a.href?0:b}}}}),M={get:function(a,c){var d,e=p.prop(a,c);return e===!0||typeof e!="boolean"&&(d=a.getAttributeNode(c))&&d.nodeValue!==!1?c.toLowerCase():b},set:function(a,b,c){var d;return b===!1?p.removeAttr(a,c):(d=p.propFix[c]||c,d in a&&(a[d]=!0),a.setAttribute(c,c.toLowerCase())),c}},U||(N={name:!0,id:!0,coords:!0},L=p.valHooks.button={get:function(a,c){var d;return d=a.getAttributeNode(c),d&&(N[c]?d.value!=="":d.specified)?d.value:b},set:function(a,b,c){var d=a.getAttributeNode(c);return d||(d=e.createAttribute(c),a.setAttributeNode(d)),d.value=b+""}},p.each(["width","height"],function(a,b){p.attrHooks[b]=p.extend(p.attrHooks[b],{set:function(a,c){if(c==="")return a.setAttribute(b,"auto"),c}})}),p.attrHooks.contenteditable={get:L.get,set:function(a,b,c){b===""&&(b="false"),L.set(a,b,c)}}),p.support.hrefNormalized||p.each(["href","src","width","height"],function(a,c){p.attrHooks[c]=p.extend(p.attrHooks[c],{get:function(a){var d=a.getAttribute(c,2);return d===null?b:d}})}),p.support.style||(p.attrHooks.style={get:function(a){return a.style.cssText.toLowerCase()||b},set:function(a,b){return a.style.cssText=""+b}}),p.support.optSelected||(p.propHooks.selected=p.extend(p.propHooks.selected,{get:function(a){var b=a.parentNode;return b&&(b.selectedIndex,b.parentNode&&b.parentNode.selectedIndex),null}})),p.support.enctype||(p.propFix.enctype="encoding"),p.support.checkOn||p.each(["radio","checkbox"],function(){p.valHooks[this]={get:function(a){return a.getAttribute("value")===null?"on":a.value}}}),p.each(["radio","checkbox"],function(){p.valHooks[this]=p.extend(p.valHooks[this],{set:function(a,b){if(p.isArray(b))return a.checked=p.inArray(p(a).val(),b)>=0}})});var V=/^(?:textarea|input|select)$/i,W=/^([^\.]*|)(?:\.(.+)|)$/,X=/(?:^|\s)hover(\.\S+|)\b/,Y=/^key/,Z=/^(?:mouse|contextmenu)|click/,$=/^(?:focusinfocus|focusoutblur)$/,_=function(a){return p.event.special.hover?a:a.replace(X,"mouseenter$1 mouseleave$1")};p.event={add:function(a,c,d,e,f){var g,h,i,j,k,l,m,n,o,q,r;if(a.nodeType===3||a.nodeType===8||!c||!d||!(g=p._data(a)))return;d.handler&&(o=d,d=o.handler,f=o.selector),d.guid||(d.guid=p.guid++),i=g.events,i||(g.events=i={}),h=g.handle,h||(g.handle=h=function(a){return typeof p!="undefined"&&(!a||p.event.triggered!==a.type)?p.event.dispatch.apply(h.elem,arguments):b},h.elem=a),c=p.trim(_(c)).split(" ");for(j=0;j<c.length;j++){k=W.exec(c[j])||[],l=k[1],m=(k[2]||"").split(".").sort(),r=p.event.special[l]||{},l=(f?r.delegateType:r.bindType)||l,r=p.event.special[l]||{},n=p.extend({type:l,origType:k[1],data:e,handler:d,guid:d.guid,selector:f,namespace:m.join(".")},o),q=i[l];if(!q){q=i[l]=[],q.delegateCount=0;if(!r.setup||r.setup.call(a,e,m,h)===!1)a.addEventListener?a.addEventListener(l,h,!1):a.attachEvent&&a.attachEvent("on"+l,h)}r.add&&(r.add.call(a,n),n.handler.guid||(n.handler.guid=d.guid)),f?q.splice(q.delegateCount++,0,n):q.push(n),p.event.global[l]=!0}a=null},global:{},remove:function(a,b,c,d,e){var f,g,h,i,j,k,l,m,n,o,q,r=p.hasData(a)&&p._data(a);if(!r||!(m=r.events))return;b=p.trim(_(b||"")).split(" ");for(f=0;f<b.length;f++){g=W.exec(b[f])||[],h=i=g[1],j=g[2];if(!h){for(h in m)p.event.remove(a,h+b[f],c,d,!0);continue}n=p.event.special[h]||{},h=(d?n.delegateType:n.bindType)||h,o=m[h]||[],k=o.length,j=j?new RegExp("(^|\\.)"+j.split(".").sort().join("\\.(?:.*\\.|)")+"(\\.|$)"):null;for(l=0;l<o.length;l++)q=o[l],(e||i===q.origType)&&(!c||c.guid===q.guid)&&(!j||j.test(q.namespace))&&(!d||d===q.selector||d==="**"&&q.selector)&&(o.splice(l--,1),q.selector&&o.delegateCount--,n.remove&&n.remove.call(a,q));o.length===0&&k!==o.length&&((!n.teardown||n.teardown.call(a,j,r.handle)===!1)&&p.removeEvent(a,h,r.handle),delete m[h])}p.isEmptyObject(m)&&(delete r.handle,p.removeData(a,"events",!0))},customEvent:{getData:!0,setData:!0,changeData:!0},trigger:function(c,d,f,g){if(!f||f.nodeType!==3&&f.nodeType!==8){var h,i,j,k,l,m,n,o,q,r,s=c.type||c,t=[];if($.test(s+p.event.triggered))return;s.indexOf("!")>=0&&(s=s.slice(0,-1),i=!0),s.indexOf(".")>=0&&(t=s.split("."),s=t.shift(),t.sort());if((!f||p.event.customEvent[s])&&!p.event.global[s])return;c=typeof c=="object"?c[p.expando]?c:new p.Event(s,c):new p.Event(s),c.type=s,c.isTrigger=!0,c.exclusive=i,c.namespace=t.join("."),c.namespace_re=c.namespace?new RegExp("(^|\\.)"+t.join("\\.(?:.*\\.|)")+"(\\.|$)"):null,m=s.indexOf(":")<0?"on"+s:"";if(!f){h=p.cache;for(j in h)h[j].events&&h[j].events[s]&&p.event.trigger(c,d,h[j].handle.elem,!0);return}c.result=b,c.target||(c.target=f),d=d!=null?p.makeArray(d):[],d.unshift(c),n=p.event.special[s]||{};if(n.trigger&&n.trigger.apply(f,d)===!1)return;q=[[f,n.bindType||s]];if(!g&&!n.noBubble&&!p.isWindow(f)){r=n.delegateType||s,k=$.test(r+s)?f:f.parentNode;for(l=f;k;k=k.parentNode)q.push([k,r]),l=k;l===(f.ownerDocument||e)&&q.push([l.defaultView||l.parentWindow||a,r])}for(j=0;j<q.length&&!c.isPropagationStopped();j++)k=q[j][0],c.type=q[j][1],o=(p._data(k,"events")||{})[c.type]&&p._data(k,"handle"),o&&o.apply(k,d),o=m&&k[m],o&&p.acceptData(k)&&o.apply(k,d)===!1&&c.preventDefault();return c.type=s,!g&&!c.isDefaultPrevented()&&(!n._default||n._default.apply(f.ownerDocument,d)===!1)&&(s!=="click"||!p.nodeName(f,"a"))&&p.acceptData(f)&&m&&f[s]&&(s!=="focus"&&s!=="blur"||c.target.offsetWidth!==0)&&!p.isWindow(f)&&(l=f[m],l&&(f[m]=null),p.event.triggered=s,f[s](),p.event.triggered=b,l&&(f[m]=l)),c.result}return},dispatch:function(c){c=p.event.fix(c||a.event);var d,e,f,g,h,i,j,k,l,m,n,o=(p._data(this,"events")||{})[c.type]||[],q=o.delegateCount,r=[].slice.call(arguments),s=!c.exclusive&&!c.namespace,t=p.event.special[c.type]||{},u=[];r[0]=c,c.delegateTarget=this;if(t.preDispatch&&t.preDispatch.call(this,c)===!1)return;if(q&&(!c.button||c.type!=="click")){g=p(this),g.context=this;for(f=c.target;f!=this;f=f.parentNode||this)if(f.disabled!==!0||c.type!=="click"){i={},k=[],g[0]=f;for(d=0;d<q;d++)l=o[d],m=l.selector,i[m]===b&&(i[m]=g.is(m)),i[m]&&k.push(l);k.length&&u.push({elem:f,matches:k})}}o.length>q&&u.push({elem:this,matches:o.slice(q)});for(d=0;d<u.length&&!c.isPropagationStopped();d++){j=u[d],c.currentTarget=j.elem;for(e=0;e<j.matches.length&&!c.isImmediatePropagationStopped();e++){l=j.matches[e];if(s||!c.namespace&&!l.namespace||c.namespace_re&&c.namespace_re.test(l.namespace))c.data=l.data,c.handleObj=l,h=((p.event.special[l.origType]||{}).handle||l.handler).apply(j.elem,r),h!==b&&(c.result=h,h===!1&&(c.preventDefault(),c.stopPropagation()))}}return t.postDispatch&&t.postDispatch.call(this,c),c.result},props:"attrChange attrName relatedNode srcElement altKey bubbles cancelable ctrlKey currentTarget eventPhase metaKey relatedTarget shiftKey target timeStamp view which".split(" "),fixHooks:{},keyHooks:{props:"char charCode key keyCode".split(" "),filter:function(a,b){return a.which==null&&(a.which=b.charCode!=null?b.charCode:b.keyCode),a}},mouseHooks:{props:"button buttons clientX clientY fromElement offsetX offsetY pageX pageY screenX screenY toElement".split(" "),filter:function(a,c){var d,f,g,h=c.button,i=c.fromElement;return a.pageX==null&&c.clientX!=null&&(d=a.target.ownerDocument||e,f=d.documentElement,g=d.body,a.pageX=c.clientX+(f&&f.scrollLeft||g&&g.scrollLeft||0)-(f&&f.clientLeft||g&&g.clientLeft||0),a.pageY=c.clientY+(f&&f.scrollTop||g&&g.scrollTop||0)-(f&&f.clientTop||g&&g.clientTop||0)),!a.relatedTarget&&i&&(a.relatedTarget=i===a.target?c.toElement:i),!a.which&&h!==b&&(a.which=h&1?1:h&2?3:h&4?2:0),a}},fix:function(a){if(a[p.expando])return a;var b,c,d=a,f=p.event.fixHooks[a.type]||{},g=f.props?this.props.concat(f.props):this.props;a=p.Event(d);for(b=g.length;b;)c=g[--b],a[c]=d[c];return a.target||(a.target=d.srcElement||e),a.target.nodeType===3&&(a.target=a.target.parentNode),a.metaKey=!!a.metaKey,f.filter?f.filter(a,d):a},special:{ready:{setup:p.bindReady},load:{noBubble:!0},focus:{delegateType:"focusin"},blur:{delegateType:"focusout"},beforeunload:{setup:function(a,b,c){p.isWindow(this)&&(this.onbeforeunload=c)},teardown:function(a,b){this.onbeforeunload===b&&(this.onbeforeunload=null)}}},simulate:function(a,b,c,d){var e=p.extend(new p.Event,c,{type:a,isSimulated:!0,originalEvent:{}});d?p.event.trigger(e,null,b):p.event.dispatch.call(b,e),e.isDefaultPrevented()&&c.preventDefault()}},p.event.handle=p.event.dispatch,p.removeEvent=e.removeEventListener?function(a,b,c){a.removeEventListener&&a.removeEventListener(b,c,!1)}:function(a,b,c){var d="on"+b;a.detachEvent&&(typeof a[d]=="undefined"&&(a[d]=null),a.detachEvent(d,c))},p.Event=function(a,b){if(this instanceof p.Event)a&&a.type?(this.originalEvent=a,this.type=a.type,this.isDefaultPrevented=a.defaultPrevented||a.returnValue===!1||a.getPreventDefault&&a.getPreventDefault()?bb:ba):this.type=a,b&&p.extend(this,b),this.timeStamp=a&&a.timeStamp||p.now(),this[p.expando]=!0;else return new p.Event(a,b)},p.Event.prototype={preventDefault:function(){this.isDefaultPrevented=bb;var a=this.originalEvent;if(!a)return;a.preventDefault?a.preventDefault():a.returnValue=!1},stopPropagation:function(){this.isPropagationStopped=bb;var a=this.originalEvent;if(!a)return;a.stopPropagation&&a.stopPropagation(),a.cancelBubble=!0},stopImmediatePropagation:function(){this.isImmediatePropagationStopped=bb,this.stopPropagation()},isDefaultPrevented:ba,isPropagationStopped:ba,isImmediatePropagationStopped:ba},p.each({mouseenter:"mouseover",mouseleave:"mouseout"},function(a,b){p.event.special[a]={delegateType:b,bindType:b,handle:function(a){var c,d=this,e=a.relatedTarget,f=a.handleObj,g=f.selector;if(!e||e!==d&&!p.contains(d,e))a.type=f.origType,c=f.handler.apply(this,arguments),a.type=b;return c}}}),p.support.submitBubbles||(p.event.special.submit={setup:function(){if(p.nodeName(this,"form"))return!1;p.event.add(this,"click._submit keypress._submit",function(a){var c=a.target,d=p.nodeName(c,"input")||p.nodeName(c,"button")?c.form:b;d&&!p._data(d,"_submit_attached")&&(p.event.add(d,"submit._submit",function(a){a._submit_bubble=!0}),p._data(d,"_submit_attached",!0))})},postDispatch:function(a){a._submit_bubble&&(delete a._submit_bubble,this.parentNode&&!a.isTrigger&&p.event.simulate("submit",this.parentNode,a,!0))},teardown:function(){if(p.nodeName(this,"form"))return!1;p.event.remove(this,"._submit")}}),p.support.changeBubbles||(p.event.special.change={setup:function(){if(V.test(this.nodeName)){if(this.type==="checkbox"||this.type==="radio")p.event.add(this,"propertychange._change",function(a){a.originalEvent.propertyName==="checked"&&(this._just_changed=!0)}),p.event.add(this,"click._change",function(a){this._just_changed&&!a.isTrigger&&(this._just_changed=!1),p.event.simulate("change",this,a,!0)});return!1}p.event.add(this,"beforeactivate._change",function(a){var b=a.target;V.test(b.nodeName)&&!p._data(b,"_change_attached")&&(p.event.add(b,"change._change",function(a){this.parentNode&&!a.isSimulated&&!a.isTrigger&&p.event.simulate("change",this.parentNode,a,!0)}),p._data(b,"_change_attached",!0))})},handle:function(a){var b=a.target;if(this!==b||a.isSimulated||a.isTrigger||b.type!=="radio"&&b.type!=="checkbox")return a.handleObj.handler.apply(this,arguments)},teardown:function(){return p.event.remove(this,"._change"),V.test(this.nodeName)}}),p.support.focusinBubbles||p.each({focus:"focusin",blur:"focusout"},function(a,b){var c=0,d=function(a){p.event.simulate(b,a.target,p.event.fix(a),!0)};p.event.special[b]={setup:function(){c++===0&&e.addEventListener(a,d,!0)},teardown:function(){--c===0&&e.removeEventListener(a,d,!0)}}}),p.fn.extend({on:function(a,c,d,e,f){var g,h;if(typeof a=="object"){typeof c!="string"&&(d=d||c,c=b);for(h in a)this.on(h,c,d,a[h],f);return this}d==null&&e==null?(e=c,d=c=b):e==null&&(typeof c=="string"?(e=d,d=b):(e=d,d=c,c=b));if(e===!1)e=ba;else if(!e)return this;return f===1&&(g=e,e=function(a){return p().off(a),g.apply(this,arguments)},e.guid=g.guid||(g.guid=p.guid++)),this.each(function(){p.event.add(this,a,e,d,c)})},one:function(a,b,c,d){return this.on(a,b,c,d,1)},off:function(a,c,d){var e,f;if(a&&a.preventDefault&&a.handleObj)return e=a.handleObj,p(a.delegateTarget).off(e.namespace?e.origType+"."+e.namespace:e.origType,e.selector,e.handler),this;if(typeof a=="object"){for(f in a)this.off(f,c,a[f]);return this}if(c===!1||typeof c=="function")d=c,c=b;return d===!1&&(d=ba),this.each(function(){p.event.remove(this,a,d,c)})},bind:function(a,b,c){return this.on(a,null,b,c)},unbind:function(a,b){return this.off(a,null,b)},live:function(a,b,c){return p(this.context).on(a,this.selector,b,c),this},die:function(a,b){return p(this.context).off(a,this.selector||"**",b),this},delegate:function(a,b,c,d){return this.on(b,a,c,d)},undelegate:function(a,b,c){return arguments.length==1?this.off(a,"**"):this.off(b,a||"**",c)},trigger:function(a,b){return this.each(function(){p.event.trigger(a,b,this)})},triggerHandler:function(a,b){if(this[0])return p.event.trigger(a,b,this[0],!0)},toggle:function(a){var b=arguments,c=a.guid||p.guid++,d=0,e=function(c){var e=(p._data(this,"lastToggle"+a.guid)||0)%d;return p._data(this,"lastToggle"+a.guid,e+1),c.preventDefault(),b[e].apply(this,arguments)||!1};e.guid=c;while(d<b.length)b[d++].guid=c;return this.click(e)},hover:function(a,b){return this.mouseenter(a).mouseleave(b||a)}}),p.each("blur focus focusin focusout load resize scroll unload click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave change select submit keydown keypress keyup error contextmenu".split(" "),function(a,b){p.fn[b]=function(a,c){return c==null&&(c=a,a=null),arguments.length>0?this.on(b,null,a,c):this.trigger(b)},Y.test(b)&&(p.event.fixHooks[b]=p.event.keyHooks),Z.test(b)&&(p.event.fixHooks[b]=p.event.mouseHooks)}),function(a,b){function bd(a,b,c,d){var e=0,f=b.length;for(;e<f;e++)Z(a,b[e],c,d)}function be(a,b,c,d,e,f){var g,h=$.setFilters[b.toLowerCase()];return h||Z.error(b),(a||!(g=e))&&bd(a||"*",d,g=[],e),g.length>0?h(g,c,f):[]}function bf(a,c,d,e,f){var g,h,i,j,k,l,m,n,p=0,q=f.length,s=L.POS,t=new RegExp("^"+s.source+"(?!"+r+")","i"),u=function(){var a=1,c=arguments.length-2;for(;a<c;a++)arguments[a]===b&&(g[a]=b)};for(;p<q;p++){s.exec(""),a=f[p],j=[],i=0,k=e;while(g=s.exec(a)){n=s.lastIndex=g.index+g[0].length;if(n>i){m=a.slice(i,g.index),i=n,l=[c],B.test(m)&&(k&&(l=k),k=e);if(h=H.test(m))m=m.slice(0,-5).replace(B,"$&*");g.length>1&&g[0].replace(t,u),k=be(m,g[1],g[2],l,k,h)}}k?(j=j.concat(k),(m=a.slice(i))&&m!==")"?B.test(m)?bd(m,j,d,e):Z(m,c,d,e?e.concat(k):k):o.apply(d,j)):Z(a,c,d,e)}return q===1?d:Z.uniqueSort(d)}function bg(a,b,c){var d,e,f,g=[],i=0,j=D.exec(a),k=!j.pop()&&!j.pop(),l=k&&a.match(C)||[""],m=$.preFilter,n=$.filter,o=!c&&b!==h;for(;(e=l[i])!=null&&k;i++){g.push(d=[]),o&&(e=" "+e);while(e){k=!1;if(j=B.exec(e))e=e.slice(j[0].length),k=d.push({part:j.pop().replace(A," "),captures:j});for(f in n)(j=L[f].exec(e))&&(!m[f]||(j=m[f](j,b,c)))&&(e=e.slice(j.shift().length),k=d.push({part:f,captures:j}));if(!k)break}}return k||Z.error(a),g}function bh(a,b,e){var f=b.dir,g=m++;return a||(a=function(a){return a===e}),b.first?function(b,c){while(b=b[f])if(b.nodeType===1)return a(b,c)&&b}:function(b,e){var h,i=g+"."+d,j=i+"."+c;while(b=b[f])if(b.nodeType===1){if((h=b[q])===j)return b.sizset;if(typeof h=="string"&&h.indexOf(i)===0){if(b.sizset)return b}else{b[q]=j;if(a(b,e))return b.sizset=!0,b;b.sizset=!1}}}}function bi(a,b){return a?function(c,d){var e=b(c,d);return e&&a(e===!0?c:e,d)}:b}function bj(a,b,c){var d,e,f=0;for(;d=a[f];f++)$.relative[d.part]?e=bh(e,$.relative[d.part],b):(d.captures.push(b,c),e=bi(e,$.filter[d.part].apply(null,d.captures)));return e}function bk(a){return function(b,c){var d,e=0;for(;d=a[e];e++)if(d(b,c))return!0;return!1}}var c,d,e,f,g,h=a.document,i=h.documentElement,j="undefined",k=!1,l=!0,m=0,n=[].slice,o=[].push,q=("sizcache"+Math.random()).replace(".",""),r="[\\x20\\t\\r\\n\\f]",s="(?:\\\\.|[-\\w]|[^\\x00-\\xa0])+",t=s.replace("w","w#"),u="([*^$|!~]?=)",v="\\["+r+"*("+s+")"+r+"*(?:"+u+r+"*(?:(['\"])((?:\\\\.|[^\\\\])*?)\\3|("+t+")|)|)"+r+"*\\]",w=":("+s+")(?:\\((?:(['\"])((?:\\\\.|[^\\\\])*?)\\2|((?:[^,]|\\\\,|(?:,(?=[^\\[]*\\]))|(?:,(?=[^\\(]*\\))))*))\\)|)",x=":(nth|eq|gt|lt|first|last|even|odd)(?:\\((\\d*)\\)|)(?=[^-]|$)",y=r+"*([\\x20\\t\\r\\n\\f>+~])"+r+"*",z="(?=[^\\x20\\t\\r\\n\\f])(?:\\\\.|"+v+"|"+w.replace(2,7)+"|[^\\\\(),])+",A=new RegExp("^"+r+"+|((?:^|[^\\\\])(?:\\\\.)*)"+r+"+$","g"),B=new RegExp("^"+y),C=new RegExp(z+"?(?="+r+"*,|$)","g"),D=new RegExp("^(?:(?!,)(?:(?:^|,)"+r+"*"+z+")*?|"+r+"*(.*?))(\\)|$)"),E=new RegExp(z.slice(19,-6)+"\\x20\\t\\r\\n\\f>+~])+|"+y,"g"),F=/^(?:#([\w\-]+)|(\w+)|\.([\w\-]+))$/,G=/[\x20\t\r\n\f]*[+~]/,H=/:not\($/,I=/h\d/i,J=/input|select|textarea|button/i,K=/\\(?!\\)/g,L={ID:new RegExp("^#("+s+")"),CLASS:new RegExp("^\\.("+s+")"),NAME:new RegExp("^\\[name=['\"]?("+s+")['\"]?\\]"),TAG:new RegExp("^("+s.replace("[-","[-\\*")+")"),ATTR:new RegExp("^"+v),PSEUDO:new RegExp("^"+w),CHILD:new RegExp("^:(only|nth|last|first)-child(?:\\("+r+"*(even|odd|(([+-]|)(\\d*)n|)"+r+"*(?:([+-]|)"+r+"*(\\d+)|))"+r+"*\\)|)","i"),POS:new RegExp(x,"ig"),needsContext:new RegExp("^"+r+"*[>+~]|"+x,"i")},M={},N=[],O={},P=[],Q=function(a){return a.sizzleFilter=!0,a},R=function(a){return function(b){return b.nodeName.toLowerCase()==="input"&&b.type===a}},S=function(a){return function(b){var c=b.nodeName.toLowerCase();return(c==="input"||c==="button")&&b.type===a}},T=function(a){var b=!1,c=h.createElement("div");try{b=a(c)}catch(d){}return c=null,b},U=T(function(a){a.innerHTML="<select></select>";var b=typeof a.lastChild.getAttribute("multiple");return b!=="boolean"&&b!=="string"}),V=T(function(a){a.id=q+0,a.innerHTML="<a name='"+q+"'></a><div name='"+q+"'></div>",i.insertBefore(a,i.firstChild);var b=h.getElementsByName&&h.getElementsByName(q).length===2+h.getElementsByName(q+0).length;return g=!h.getElementById(q),i.removeChild(a),b}),W=T(function(a){return a.appendChild(h.createComment("")),a.getElementsByTagName("*").length===0}),X=T(function(a){return a.innerHTML="<a href='#'></a>",a.firstChild&&typeof a.firstChild.getAttribute!==j&&a.firstChild.getAttribute("href")==="#"}),Y=T(function(a){return a.innerHTML="<div class='hidden e'></div><div class='hidden'></div>",!a.getElementsByClassName||a.getElementsByClassName("e").length===0?!1:(a.lastChild.className="e",a.getElementsByClassName("e").length!==1)}),Z=function(a,b,c,d){c=c||[],b=b||h;var e,f,g,i,j=b.nodeType;if(j!==1&&j!==9)return[];if(!a||typeof a!="string")return c;g=ba(b);if(!g&&!d)if(e=F.exec(a))if(i=e[1]){if(j===9){f=b.getElementById(i);if(!f||!f.parentNode)return c;if(f.id===i)return c.push(f),c}else if(b.ownerDocument&&(f=b.ownerDocument.getElementById(i))&&bb(b,f)&&f.id===i)return c.push(f),c}else{if(e[2])return o.apply(c,n.call(b.getElementsByTagName(a),0)),c;if((i=e[3])&&Y&&b.getElementsByClassName)return o.apply(c,n.call(b.getElementsByClassName(i),0)),c}return bm(a,b,c,d,g)},$=Z.selectors={cacheLength:50,match:L,order:["ID","TAG"],attrHandle:{},createPseudo:Q,find:{ID:g?function(a,b,c){if(typeof b.getElementById!==j&&!c){var d=b.getElementById(a);return d&&d.parentNode?[d]:[]}}:function(a,c,d){if(typeof c.getElementById!==j&&!d){var e=c.getElementById(a);return e?e.id===a||typeof e.getAttributeNode!==j&&e.getAttributeNode("id").value===a?[e]:b:[]}},TAG:W?function(a,b){if(typeof b.getElementsByTagName!==j)return b.getElementsByTagName(a)}:function(a,b){var c=b.getElementsByTagName(a);if(a==="*"){var d,e=[],f=0;for(;d=c[f];f++)d.nodeType===1&&e.push(d);return e}return c}},relative:{">":{dir:"parentNode",first:!0}," ":{dir:"parentNode"},"+":{dir:"previousSibling",first:!0},"~":{dir:"previousSibling"}},preFilter:{ATTR:function(a){return a[1]=a[1].replace(K,""),a[3]=(a[4]||a[5]||"").replace(K,""),a[2]==="~="&&(a[3]=" "+a[3]+" "),a.slice(0,4)},CHILD:function(a){return a[1]=a[1].toLowerCase(),a[1]==="nth"?(a[2]||Z.error(a[0]),a[3]=+(a[3]?a[4]+(a[5]||1):2*(a[2]==="even"||a[2]==="odd")),a[4]=+(a[6]+a[7]||a[2]==="odd")):a[2]&&Z.error(a[0]),a},PSEUDO:function(a){var b,c=a[4];return L.CHILD.test(a[0])?null:(c&&(b=D.exec(c))&&b.pop()&&(a[0]=a[0].slice(0,b[0].length-c.length-1),c=b[0].slice(0,-1)),a.splice(2,3,c||a[3]),a)}},filter:{ID:g?function(a){return a=a.replace(K,""),function(b){return b.getAttribute("id")===a}}:function(a){return a=a.replace(K,""),function(b){var c=typeof b.getAttributeNode!==j&&b.getAttributeNode("id");return c&&c.value===a}},TAG:function(a){return a==="*"?function(){return!0}:(a=a.replace(K,"").toLowerCase(),function(b){return b.nodeName&&b.nodeName.toLowerCase()===a})},CLASS:function(a){var b=M[a];return b||(b=M[a]=new RegExp("(^|"+r+")"+a+"("+r+"|$)"),N.push(a),N.length>$.cacheLength&&delete M[N.shift()]),function(a){return b.test(a.className||typeof a.getAttribute!==j&&a.getAttribute("class")||"")}},ATTR:function(a,b,c){return b?function(d){var e=Z.attr(d,a),f=e+"";if(e==null)return b==="!=";switch(b){case"=":return f===c;case"!=":return f!==c;case"^=":return c&&f.indexOf(c)===0;case"*=":return c&&f.indexOf(c)>-1;case"$=":return c&&f.substr(f.length-c.length)===c;case"~=":return(" "+f+" ").indexOf(c)>-1;case"|=":return f===c||f.substr(0,c.length+1)===c+"-"}}:function(b){return Z.attr(b,a)!=null}},CHILD:function(a,b,c,d){if(a==="nth"){var e=m++;return function(a){var b,f,g=0,h=a;if(c===1&&d===0)return!0;b=a.parentNode;if(b&&(b[q]!==e||!a.sizset)){for(h=b.firstChild;h;h=h.nextSibling)if(h.nodeType===1){h.sizset=++g;if(h===a)break}b[q]=e}return f=a.sizset-d,c===0?f===0:f%c===0&&f/c>=0}}return function(b){var c=b;switch(a){case"only":case"first":while(c=c.previousSibling)if(c.nodeType===1)return!1;if(a==="first")return!0;c=b;case"last":while(c=c.nextSibling)if(c.nodeType===1)return!1;return!0}}},PSEUDO:function(a,b,c,d){var e=$.pseudos[a]||$.pseudos[a.toLowerCase()];return e||Z.error("unsupported pseudo: "+a),e.sizzleFilter?e(b,c,d):e}},pseudos:{not:Q(function(a,b,c){var d=bl(a.replace(A,"$1"),b,c);return function(a){return!d(a)}}),enabled:function(a){return a.disabled===!1},disabled:function(a){return a.disabled===!0},checked:function(a){var b=a.nodeName.toLowerCase();return b==="input"&&!!a.checked||b==="option"&&!!a.selected},selected:function(a){return a.parentNode&&a.parentNode.selectedIndex,a.selected===!0},parent:function(a){return!$.pseudos.empty(a)},empty:function(a){var b;a=a.firstChild;while(a){if(a.nodeName>"@"||(b=a.nodeType)===3||b===4)return!1;a=a.nextSibling}return!0},contains:Q(function(a){return function(b){return(b.textContent||b.innerText||bc(b)).indexOf(a)>-1}}),has:Q(function(a){return function(b){return Z(a,b).length>0}}),header:function(a){return I.test(a.nodeName)},text:function(a){var b,c;return a.nodeName.toLowerCase()==="input"&&(b=a.type)==="text"&&((c=a.getAttribute("type"))==null||c.toLowerCase()===b)},radio:R("radio"),checkbox:R("checkbox"),file:R("file"),password:R("password"),image:R("image"),submit:S("submit"),reset:S("reset"),button:function(a){var b=a.nodeName.toLowerCase();return b==="input"&&a.type==="button"||b==="button"},input:function(a){return J.test(a.nodeName)},focus:function(a){var b=a.ownerDocument;return a===b.activeElement&&(!b.hasFocus||b.hasFocus())&&(!!a.type||!!a.href)},active:function(a){return a===a.ownerDocument.activeElement}},setFilters:{first:function(a,b,c){return c?a.slice(1):[a[0]]},last:function(a,b,c){var d=a.pop();return c?a:[d]},even:function(a,b,c){var d=[],e=c?1:0,f=a.length;for(;e<f;e=e+2)d.push(a[e]);return d},odd:function(a,b,c){var d=[],e=c?0:1,f=a.length;for(;e<f;e=e+2)d.push(a[e]);return d},lt:function(a,b,c){return c?a.slice(+b):a.slice(0,+b)},gt:function(a,b,c){return c?a.slice(0,+b+1):a.slice(+b+1)},eq:function(a,b,c){var d=a.splice(+b,1);return c?a:d}}};$.setFilters.nth=$.setFilters.eq,$.filters=$.pseudos,X||($.attrHandle={href:function(a){return a.getAttribute("href",2)},type:function(a){return a.getAttribute("type")}}),V&&($.order.push("NAME"),$.find.NAME=function(a,b){if(typeof b.getElementsByName!==j)return b.getElementsByName(a)}),Y&&($.order.splice(1,0,"CLASS"),$.find.CLASS=function(a,b,c){if(typeof b.getElementsByClassName!==j&&!c)return b.getElementsByClassName(a)});try{n.call(i.childNodes,0)[0].nodeType}catch(_){n=function(a){var b,c=[];for(;b=this[a];a++)c.push(b);return c}}var ba=Z.isXML=function(a){var b=a&&(a.ownerDocument||a).documentElement;return b?b.nodeName!=="HTML":!1},bb=Z.contains=i.compareDocumentPosition?function(a,b){return!!(a.compareDocumentPosition(b)&16)}:i.contains?function(a,b){var c=a.nodeType===9?a.documentElement:a,d=b.parentNode;return a===d||!!(d&&d.nodeType===1&&c.contains&&c.contains(d))}:function(a,b){while(b=b.parentNode)if(b===a)return!0;return!1},bc=Z.getText=function(a){var b,c="",d=0,e=a.nodeType;if(e){if(e===1||e===9||e===11){if(typeof a.textContent=="string")return a.textContent;for(a=a.firstChild;a;a=a.nextSibling)c+=bc(a)}else if(e===3||e===4)return a.nodeValue}else for(;b=a[d];d++)c+=bc(b);return c};Z.attr=function(a,b){var c,d=ba(a);return d||(b=b.toLowerCase()),$.attrHandle[b]?$.attrHandle[b](a):U||d?a.getAttribute(b):(c=a.getAttributeNode(b),c?typeof a[b]=="boolean"?a[b]?b:null:c.specified?c.value:null:null)},Z.error=function(a){throw new Error("Syntax error, unrecognized expression: "+a)},[0,0].sort(function(){return l=0}),i.compareDocumentPosition?e=function(a,b){return a===b?(k=!0,0):(!a.compareDocumentPosition||!b.compareDocumentPosition?a.compareDocumentPosition:a.compareDocumentPosition(b)&4)?-1:1}:(e=function(a,b){if(a===b)return k=!0,0;if(a.sourceIndex&&b.sourceIndex)return a.sourceIndex-b.sourceIndex;var c,d,e=[],g=[],h=a.parentNode,i=b.parentNode,j=h;if(h===i)return f(a,b);if(!h)return-1;if(!i)return 1;while(j)e.unshift(j),j=j.parentNode;j=i;while(j)g.unshift(j),j=j.parentNode;c=e.length,d=g.length;for(var l=0;l<c&&l<d;l++)if(e[l]!==g[l])return f(e[l],g[l]);return l===c?f(a,g[l],-1):f(e[l],b,1)},f=function(a,b,c){if(a===b)return c;var d=a.nextSibling;while(d){if(d===b)return-1;d=d.nextSibling}return 1}),Z.uniqueSort=function(a){var b,c=1;if(e){k=l,a.sort(e);if(k)for(;b=a[c];c++)b===a[c-1]&&a.splice(c--,1)}return a};var bl=Z.compile=function(a,b,c){var d,e,f,g=O[a];if(g&&g.context===b)return g;e=bg(a,b,c);for(f=0;d=e[f];f++)e[f]=bj(d,b,c);return g=O[a]=bk(e),g.context=b,g.runs=g.dirruns=0,P.push(a),P.length>$.cacheLength&&delete O[P.shift()],g};Z.matches=function(a,b){return Z(a,null,null,b)},Z.matchesSelector=function(a,b){return Z(b,null,null,[a]).length>0};var bm=function(a,b,e,f,g){a=a.replace(A,"$1");var h,i,j,k,l,m,p,q,r,s=a.match(C),t=a.match(E),u=b.nodeType;if(L.POS.test(a))return bf(a,b,e,f,s);if(f)h=n.call(f,0);else if(s&&s.length===1){if(t.length>1&&u===9&&!g&&(s=L.ID.exec(t[0]))){b=$.find.ID(s[1],b,g)[0];if(!b)return e;a=a.slice(t.shift().length)}q=(s=G.exec(t[0]))&&!s.index&&b.parentNode||b,r=t.pop(),m=r.split(":not")[0];for(j=0,k=$.order.length;j<k;j++){p=$.order[j];if(s=L[p].exec(m)){h=$.find[p]((s[1]||"").replace(K,""),q,g);if(h==null)continue;m===r&&(a=a.slice(0,a.length-r.length)+m.replace(L[p],""),a||o.apply(e,n.call(h,0)));break}}}if(a){i=bl(a,b,g),d=i.dirruns++,h==null&&(h=$.find.TAG("*",G.test(a)&&b.parentNode||b));for(j=0;l=h[j];j++)c=i.runs++,i(l,b)&&e.push(l)}return e};h.querySelectorAll&&function(){var a,b=bm,c=/'|\\/g,d=/\=[\x20\t\r\n\f]*([^'"\]]*)[\x20\t\r\n\f]*\]/g,e=[],f=[":active"],g=i.matchesSelector||i.mozMatchesSelector||i.webkitMatchesSelector||i.oMatchesSelector||i.msMatchesSelector;T(function(a){a.innerHTML="<select><option selected></option></select>",a.querySelectorAll("[selected]").length||e.push("\\["+r+"*(?:checked|disabled|ismap|multiple|readonly|selected|value)"),a.querySelectorAll(":checked").length||e.push(":checked")}),T(function(a){a.innerHTML="<p test=''></p>",a.querySelectorAll("[test^='']").length&&e.push("[*^$]="+r+"*(?:\"\"|'')"),a.innerHTML="<input type='hidden'>",a.querySelectorAll(":enabled").length||e.push(":enabled",":disabled")}),e=e.length&&new RegExp(e.join("|")),bm=function(a,d,f,g,h){if(!g&&!h&&(!e||!e.test(a)))if(d.nodeType===9)try{return o.apply(f,n.call(d.querySelectorAll(a),0)),f}catch(i){}else if(d.nodeType===1&&d.nodeName.toLowerCase()!=="object"){var j=d.getAttribute("id"),k=j||q,l=G.test(a)&&d.parentNode||d;j?k=k.replace(c,"\\$&"):d.setAttribute("id",k);try{return o.apply(f,n.call(l.querySelectorAll(a.replace(C,"[id='"+k+"'] $&")),0)),f}catch(i){}finally{j||d.removeAttribute("id")}}return b(a,d,f,g,h)},g&&(T(function(b){a=g.call(b,"div");try{g.call(b,"[test!='']:sizzle"),f.push($.match.PSEUDO)}catch(c){}}),f=new RegExp(f.join("|")),Z.matchesSelector=function(b,c){c=c.replace(d,"='$1']");if(!ba(b)&&!f.test(c)&&(!e||!e.test(c)))try{var h=g.call(b,c);if(h||a||b.document&&b.document.nodeType!==11)return h}catch(i){}return Z(c,null,null,[b]).length>0})}(),Z.attr=p.attr,p.find=Z,p.expr=Z.selectors,p.expr[":"]=p.expr.pseudos,p.unique=Z.uniqueSort,p.text=Z.getText,p.isXMLDoc=Z.isXML,p.contains=Z.contains}(a);var bc=/Until$/,bd=/^(?:parents|prev(?:Until|All))/,be=/^.[^:#\[\.,]*$/,bf=p.expr.match.needsContext,bg={children:!0,contents:!0,next:!0,prev:!0};p.fn.extend({find:function(a){var b,c,d,e,f,g,h=this;if(typeof a!="string")return p(a).filter(function(){for(b=0,c=h.length;b<c;b++)if(p.contains(h[b],this))return!0});g=this.pushStack("","find",a);for(b=0,c=this.length;b<c;b++){d=g.length,p.find(a,this[b],g);if(b>0)for(e=d;e<g.length;e++)for(f=0;f<d;f++)if(g[f]===g[e]){g.splice(e--,1);break}}return g},has:function(a){var b,c=p(a,this),d=c.length;return this.filter(function(){for(b=0;b<d;b++)if(p.contains(this,c[b]))return!0})},not:function(a){return this.pushStack(bj(this,a,!1),"not",a)},filter:function(a){return this.pushStack(bj(this,a,!0),"filter",a)},is:function(a){return!!a&&(typeof a=="string"?bf.test(a)?p(a,this.context).index(this[0])>=0:p.filter(a,this).length>0:this.filter(a).length>0)},closest:function(a,b){var c,d=0,e=this.length,f=[],g=bf.test(a)||typeof a!="string"?p(a,b||this.context):0;for(;d<e;d++){c=this[d];while(c&&c.ownerDocument&&c!==b&&c.nodeType!==11){if(g?g.index(c)>-1:p.find.matchesSelector(c,a)){f.push(c);break}c=c.parentNode}}return f=f.length>1?p.unique(f):f,this.pushStack(f,"closest",a)},index:function(a){return a?typeof a=="string"?p.inArray(this[0],p(a)):p.inArray(a.jquery?a[0]:a,this):this[0]&&this[0].parentNode?this.prevAll().length:-1},add:function(a,b){var c=typeof a=="string"?p(a,b):p.makeArray(a&&a.nodeType?[a]:a),d=p.merge(this.get(),c);return this.pushStack(bh(c[0])||bh(d[0])?d:p.unique(d))},addBack:function(a){return this.add(a==null?this.prevObject:this.prevObject.filter(a))}}),p.fn.andSelf=p.fn.addBack,p.each({parent:function(a){var b=a.parentNode;return b&&b.nodeType!==11?b:null},parents:function(a){return p.dir(a,"parentNode")},parentsUntil:function(a,b,c){return p.dir(a,"parentNode",c)},next:function(a){return bi(a,"nextSibling")},prev:function(a){return bi(a,"previousSibling")},nextAll:function(a){return p.dir(a,"nextSibling")},prevAll:function(a){return p.dir(a,"previousSibling")},nextUntil:function(a,b,c){return p.dir(a,"nextSibling",c)},prevUntil:function(a,b,c){return p.dir(a,"previousSibling",c)},siblings:function(a){return p.sibling((a.parentNode||{}).firstChild,a)},children:function(a){return p.sibling(a.firstChild)},contents:function(a){return p.nodeName(a,"iframe")?a.contentDocument||a.contentWindow.document:p.merge([],a.childNodes)}},function(a,b){p.fn[a]=function(c,d){var e=p.map(this,b,c);return bc.test(a)||(d=c),d&&typeof d=="string"&&(e=p.filter(d,e)),e=this.length>1&&!bg[a]?p.unique(e):e,this.length>1&&bd.test(a)&&(e=e.reverse()),this.pushStack(e,a,k.call(arguments).join(","))}}),p.extend({filter:function(a,b,c){return c&&(a=":not("+a+")"),b.length===1?p.find.matchesSelector(b[0],a)?[b[0]]:[]:p.find.matches(a,b)},dir:function(a,c,d){var e=[],f=a[c];while(f&&f.nodeType!==9&&(d===b||f.nodeType!==1||!p(f).is(d)))f.nodeType===1&&e.push(f),f=f[c];return e},sibling:function(a,b){var c=[];for(;a;a=a.nextSibling)a.nodeType===1&&a!==b&&c.push(a);return c}});var bl="abbr|article|aside|audio|bdi|canvas|data|datalist|details|figcaption|figure|footer|header|hgroup|mark|meter|nav|output|progress|section|summary|time|video",bm=/ jQuery\d+="(?:null|\d+)"/g,bn=/^\s+/,bo=/<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/gi,bp=/<([\w:]+)/,bq=/<tbody/i,br=/<|&#?\w+;/,bs=/<(?:script|style|link)/i,bt=/<(?:script|object|embed|option|style)/i,bu=new RegExp("<(?:"+bl+")[\\s/>]","i"),bv=/^(?:checkbox|radio)$/,bw=/checked\s*(?:[^=]|=\s*.checked.)/i,bx=/\/(java|ecma)script/i,by=/^\s*<!(?:\[CDATA\[|\-\-)|[\]\-]{2}>\s*$/g,bz={option:[1,"<select multiple='multiple'>","</select>"],legend:[1,"<fieldset>","</fieldset>"],thead:[1,"<table>","</table>"],tr:[2,"<table><tbody>","</tbody></table>"],td:[3,"<table><tbody><tr>","</tr></tbody></table>"],col:[2,"<table><tbody></tbody><colgroup>","</colgroup></table>"],area:[1,"<map>","</map>"],_default:[0,"",""]},bA=bk(e),bB=bA.appendChild(e.createElement("div"));bz.optgroup=bz.option,bz.tbody=bz.tfoot=bz.colgroup=bz.caption=bz.thead,bz.th=bz.td,p.support.htmlSerialize||(bz._default=[1,"X<div>","</div>"]),p.fn.extend({text:function(a){return p.access(this,function(a){return a===b?p.text(this):this.empty().append((this[0]&&this[0].ownerDocument||e).createTextNode(a))},null,a,arguments.length)},wrapAll:function(a){if(p.isFunction(a))return this.each(function(b){p(this).wrapAll(a.call(this,b))});if(this[0]){var b=p(a,this[0].ownerDocument).eq(0).clone(!0);this[0].parentNode&&b.insertBefore(this[0]),b.map(function(){var a=this;while(a.firstChild&&a.firstChild.nodeType===1)a=a.firstChild;return a}).append(this)}return this},wrapInner:function(a){return p.isFunction(a)?this.each(function(b){p(this).wrapInner(a.call(this,b))}):this.each(function(){var b=p(this),c=b.contents();c.length?c.wrapAll(a):b.append(a)})},wrap:function(a){var b=p.isFunction(a);return this.each(function(c){p(this).wrapAll(b?a.call(this,c):a)})},unwrap:function(){return this.parent().each(function(){p.nodeName(this,"body")||p(this).replaceWith(this.childNodes)}).end()},append:function(){return this.domManip(arguments,!0,function(a){(this.nodeType===1||this.nodeType===11)&&this.appendChild(a)})},prepend:function(){return this.domManip(arguments,!0,function(a){(this.nodeType===1||this.nodeType===11)&&this.insertBefore(a,this.firstChild)})},before:function(){if(!bh(this[0]))return this.domManip(arguments,!1,function(a){this.parentNode.insertBefore(a,this)});if(arguments.length){var a=p.clean(arguments);return this.pushStack(p.merge(a,this),"before",this.selector)}},after:function(){if(!bh(this[0]))return this.domManip(arguments,!1,function(a){this.parentNode.insertBefore(a,this.nextSibling)});if(arguments.length){var a=p.clean(arguments);return this.pushStack(p.merge(this,a),"after",this.selector)}},remove:function(a,b){var c,d=0;for(;(c=this[d])!=null;d++)if(!a||p.filter(a,[c]).length)!b&&c.nodeType===1&&(p.cleanData(c.getElementsByTagName("*")),p.cleanData([c])),c.parentNode&&c.parentNode.removeChild(c);return this},empty:function(){var a,b=0;for(;(a=this[b])!=null;b++){a.nodeType===1&&p.cleanData(a.getElementsByTagName("*"));while(a.firstChild)a.removeChild(a.firstChild)}return this},clone:function(a,b){return a=a==null?!1:a,b=b==null?a:b,this.map(function(){return p.clone(this,a,b)})},html:function(a){return p.access(this,function(a){var c=this[0]||{},d=0,e=this.length;if(a===b)return c.nodeType===1?c.innerHTML.replace(bm,""):b;if(typeof a=="string"&&!bs.test(a)&&(p.support.htmlSerialize||!bu.test(a))&&(p.support.leadingWhitespace||!bn.test(a))&&!bz[(bp.exec(a)||["",""])[1].toLowerCase()]){a=a.replace(bo,"<$1></$2>");try{for(;d<e;d++)c=this[d]||{},c.nodeType===1&&(p.cleanData(c.getElementsByTagName("*")),c.innerHTML=a);c=0}catch(f){}}c&&this.empty().append(a)},null,a,arguments.length)},replaceWith:function(a){return bh(this[0])?this.length?this.pushStack(p(p.isFunction(a)?a():a),"replaceWith",a):this:p.isFunction(a)?this.each(function(b){var c=p(this),d=c.html();c.replaceWith(a.call(this,b,d))}):(typeof a!="string"&&(a=p(a).detach()),this.each(function(){var b=this.nextSibling,c=this.parentNode;p(this).remove(),b?p(b).before(a):p(c).append(a)}))},detach:function(a){return this.remove(a,!0)},domManip:function(a,c,d){a=[].concat.apply([],a);var e,f,g,h,i=0,j=a[0],k=[],l=this.length;if(!p.support.checkClone&&l>1&&typeof j=="string"&&bw.test(j))return this.each(function(){p(this).domManip(a,c,d)});if(p.isFunction(j))return this.each(function(e){var f=p(this);a[0]=j.call(this,e,c?f.html():b),f.domManip(a,c,d)});if(this[0]){e=p.buildFragment(a,this,k),g=e.fragment,f=g.firstChild,g.childNodes.length===1&&(g=f);if(f){c=c&&p.nodeName(f,"tr");for(h=e.cacheable||l-1;i<l;i++)d.call(c&&p.nodeName(this[i],"table")?bC(this[i],"tbody"):this[i],i===h?g:p.clone(g,!0,!0))}g=f=null,k.length&&p.each(k,function(a,b){b.src?p.ajax?p.ajax({url:b.src,type:"GET",dataType:"script",async:!1,global:!1,"throws":!0}):p.error("no ajax"):p.globalEval((b.text||b.textContent||b.innerHTML||"").replace(by,"")),b.parentNode&&b.parentNode.removeChild(b)})}return this}}),p.buildFragment=function(a,c,d){var f,g,h,i=a[0];return c=c||e,c=(c[0]||c).ownerDocument||c[0]||c,typeof c.createDocumentFragment=="undefined"&&(c=e),a.length===1&&typeof i=="string"&&i.length<512&&c===e&&i.charAt(0)==="<"&&!bt.test(i)&&(p.support.checkClone||!bw.test(i))&&(p.support.html5Clone||!bu.test(i))&&(g=!0,f=p.fragments[i],h=f!==b),f||(f=c.createDocumentFragment(),p.clean(a,c,f,d),g&&(p.fragments[i]=h&&f)),{fragment:f,cacheable:g}},p.fragments={},p.each({appendTo:"append",prependTo:"prepend",insertBefore:"before",insertAfter:"after",replaceAll:"replaceWith"},function(a,b){p.fn[a]=function(c){var d,e=0,f=[],g=p(c),h=g.length,i=this.length===1&&this[0].parentNode;if((i==null||i&&i.nodeType===11&&i.childNodes.length===1)&&h===1)return g[b](this[0]),this;for(;e<h;e++)d=(e>0?this.clone(!0):this).get(),p(g[e])[b](d),f=f.concat(d);return this.pushStack(f,a,g.selector)}}),p.extend({clone:function(a,b,c){var d,e,f,g;p.support.html5Clone||p.isXMLDoc(a)||!bu.test("<"+a.nodeName+">")?g=a.cloneNode(!0):(bB.innerHTML=a.outerHTML,bB.removeChild(g=bB.firstChild));if((!p.support.noCloneEvent||!p.support.noCloneChecked)&&(a.nodeType===1||a.nodeType===11)&&!p.isXMLDoc(a)){bE(a,g),d=bF(a),e=bF(g);for(f=0;d[f];++f)e[f]&&bE(d[f],e[f])}if(b){bD(a,g);if(c){d=bF(a),e=bF(g);for(f=0;d[f];++f)bD(d[f],e[f])}}return d=e=null,g},clean:function(a,b,c,d){var f,g,h,i,j,k,l,m,n,o,q,r,s=0,t=[];if(!b||typeof b.createDocumentFragment=="undefined")b=e;for(g=b===e&&bA;(h=a[s])!=null;s++){typeof h=="number"&&(h+="");if(!h)continue;if(typeof h=="string")if(!br.test(h))h=b.createTextNode(h);else{g=g||bk(b),l=l||g.appendChild(b.createElement("div")),h=h.replace(bo,"<$1></$2>"),i=(bp.exec(h)||["",""])[1].toLowerCase(),j=bz[i]||bz._default,k=j[0],l.innerHTML=j[1]+h+j[2];while(k--)l=l.lastChild;if(!p.support.tbody){m=bq.test(h),n=i==="table"&&!m?l.firstChild&&l.firstChild.childNodes:j[1]==="<table>"&&!m?l.childNodes:[];for(f=n.length-1;f>=0;--f)p.nodeName(n[f],"tbody")&&!n[f].childNodes.length&&n[f].parentNode.removeChild(n[f])}!p.support.leadingWhitespace&&bn.test(h)&&l.insertBefore(b.createTextNode(bn.exec(h)[0]),l.firstChild),h=l.childNodes,l=g.lastChild}h.nodeType?t.push(h):t=p.merge(t,h)}l&&(g.removeChild(l),h=l=g=null);if(!p.support.appendChecked)for(s=0;(h=t[s])!=null;s++)p.nodeName(h,"input")?bG(h):typeof h.getElementsByTagName!="undefined"&&p.grep(h.getElementsByTagName("input"),bG);if(c){q=function(a){if(!a.type||bx.test(a.type))return d?d.push(a.parentNode?a.parentNode.removeChild(a):a):c.appendChild(a)};for(s=0;(h=t[s])!=null;s++)if(!p.nodeName(h,"script")||!q(h))c.appendChild(h),typeof h.getElementsByTagName!="undefined"&&(r=p.grep(p.merge([],h.getElementsByTagName("script")),q),t.splice.apply(t,[s+1,0].concat(r)),s+=r.length)}return t},cleanData:function(a,b){var c,d,e,f,g=0,h=p.expando,i=p.cache,j=p.support.deleteExpando,k=p.event.special;for(;(e=a[g])!=null;g++)if(b||p.acceptData(e)){d=e[h],c=d&&i[d];if(c){if(c.events)for(f in c.events)k[f]?p.event.remove(e,f):p.removeEvent(e,f,c.handle);i[d]&&(delete i[d],j?delete e[h]:e.removeAttribute?e.removeAttribute(h):e[h]=null,p.deletedIds.push(d))}}}}),function(){var a,b;p.uaMatch=function(a){a=a.toLowerCase();var b=/(chrome)[ \/]([\w.]+)/.exec(a)||/(webkit)[ \/]([\w.]+)/.exec(a)||/(opera)(?:.*version|)[ \/]([\w.]+)/.exec(a)||/(msie) ([\w.]+)/.exec(a)||a.indexOf("compatible")<0&&/(mozilla)(?:.*? rv:([\w.]+)|)/.exec(a)||[];return{browser:b[1]||"",version:b[2]||"0"}},a=p.uaMatch(g.userAgent),b={},a.browser&&(b[a.browser]=!0,b.version=a.version),b.webkit&&(b.safari=!0),p.browser=b,p.sub=function(){function a(b,c){return new a.fn.init(b,c)}p.extend(!0,a,this),a.superclass=this,a.fn=a.prototype=this(),a.fn.constructor=a,a.sub=this.sub,a.fn.init=function c(c,d){return d&&d instanceof p&&!(d instanceof a)&&(d=a(d)),p.fn.init.call(this,c,d,b)},a.fn.init.prototype=a.fn;var b=a(e);return a}}();var bH,bI,bJ,bK=/alpha\([^)]*\)/i,bL=/opacity=([^)]*)/,bM=/^(top|right|bottom|left)$/,bN=/^margin/,bO=new RegExp("^("+q+")(.*)$","i"),bP=new RegExp("^("+q+")(?!px)[a-z%]+$","i"),bQ=new RegExp("^([-+])=("+q+")","i"),bR={},bS={position:"absolute",visibility:"hidden",display:"block"},bT={letterSpacing:0,fontWeight:400,lineHeight:1},bU=["Top","Right","Bottom","Left"],bV=["Webkit","O","Moz","ms"],bW=p.fn.toggle;p.fn.extend({css:function(a,c){return p.access(this,function(a,c,d){return d!==b?p.style(a,c,d):p.css(a,c)},a,c,arguments.length>1)},show:function(){return bZ(this,!0)},hide:function(){return bZ(this)},toggle:function(a,b){var c=typeof a=="boolean";return p.isFunction(a)&&p.isFunction(b)?bW.apply(this,arguments):this.each(function(){(c?a:bY(this))?p(this).show():p(this).hide()})}}),p.extend({cssHooks:{opacity:{get:function(a,b){if(b){var c=bH(a,"opacity");return c===""?"1":c}}}},cssNumber:{fillOpacity:!0,fontWeight:!0,lineHeight:!0,opacity:!0,orphans:!0,widows:!0,zIndex:!0,zoom:!0},cssProps:{"float":p.support.cssFloat?"cssFloat":"styleFloat"},style:function(a,c,d,e){if(!a||a.nodeType===3||a.nodeType===8||!a.style)return;var f,g,h,i=p.camelCase(c),j=a.style;c=p.cssProps[i]||(p.cssProps[i]=bX(j,i)),h=p.cssHooks[c]||p.cssHooks[i];if(d===b)return h&&"get"in h&&(f=h.get(a,!1,e))!==b?f:j[c];g=typeof d,g==="string"&&(f=bQ.exec(d))&&(d=(f[1]+1)*f[2]+parseFloat(p.css(a,c)),g="number");if(d==null||g==="number"&&isNaN(d))return;g==="number"&&!p.cssNumber[i]&&(d+="px");if(!h||!("set"in h)||(d=h.set(a,d,e))!==b)try{j[c]=d}catch(k){}},css:function(a,c,d,e){var f,g,h,i=p.camelCase(c);return c=p.cssProps[i]||(p.cssProps[i]=bX(a.style,i)),h=p.cssHooks[c]||p.cssHooks[i],h&&"get"in h&&(f=h.get(a,!0,e)),f===b&&(f=bH(a,c)),f==="normal"&&c in bT&&(f=bT[c]),d||e!==b?(g=parseFloat(f),d||p.isNumeric(g)?g||0:f):f},swap:function(a,b,c){var d,e,f={};for(e in b)f[e]=a.style[e],a.style[e]=b[e];d=c.call(a);for(e in b)a.style[e]=f[e];return d}}),a.getComputedStyle?bH=function(a,b){var c,d,e,f,g=getComputedStyle(a,null),h=a.style;return g&&(c=g[b],c===""&&!p.contains(a.ownerDocument.documentElement,a)&&(c=p.style(a,b)),bP.test(c)&&bN.test(b)&&(d=h.width,e=h.minWidth,f=h.maxWidth,h.minWidth=h.maxWidth=h.width=c,c=g.width,h.width=d,h.minWidth=e,h.maxWidth=f)),c}:e.documentElement.currentStyle&&(bH=function(a,b){var c,d,e=a.currentStyle&&a.currentStyle[b],f=a.style;return e==null&&f&&f[b]&&(e=f[b]),bP.test(e)&&!bM.test(b)&&(c=f.left,d=a.runtimeStyle&&a.runtimeStyle.left,d&&(a.runtimeStyle.left=a.currentStyle.left),f.left=b==="fontSize"?"1em":e,e=f.pixelLeft+"px",f.left=c,d&&(a.runtimeStyle.left=d)),e===""?"auto":e}),p.each(["height","width"],function(a,b){p.cssHooks[b]={get:function(a,c,d){if(c)return a.offsetWidth!==0||bH(a,"display")!=="none"?ca(a,b,d):p.swap(a,bS,function(){return ca(a,b,d)})},set:function(a,c,d){return b$(a,c,d?b_(a,b,d,p.support.boxSizing&&p.css(a,"boxSizing")==="border-box"):0)}}}),p.support.opacity||(p.cssHooks.opacity={get:function(a,b){return bL.test((b&&a.currentStyle?a.currentStyle.filter:a.style.filter)||"")?.01*parseFloat(RegExp.$1)+"":b?"1":""},set:function(a,b){var c=a.style,d=a.currentStyle,e=p.isNumeric(b)?"alpha(opacity="+b*100+")":"",f=d&&d.filter||c.filter||"";c.zoom=1;if(b>=1&&p.trim(f.replace(bK,""))===""&&c.removeAttribute){c.removeAttribute("filter");if(d&&!d.filter)return}c.filter=bK.test(f)?f.replace(bK,e):f+" "+e}}),p(function(){p.support.reliableMarginRight||(p.cssHooks.marginRight={get:function(a,b){return p.swap(a,{display:"inline-block"},function(){if(b)return bH(a,"marginRight")})}}),!p.support.pixelPosition&&p.fn.position&&p.each(["top","left"],function(a,b){p.cssHooks[b]={get:function(a,c){if(c){var d=bH(a,b);return bP.test(d)?p(a).position()[b]+"px":d}}}})}),p.expr&&p.expr.filters&&(p.expr.filters.hidden=function(a){return a.offsetWidth===0&&a.offsetHeight===0||!p.support.reliableHiddenOffsets&&(a.style&&a.style.display||bH(a,"display"))==="none"},p.expr.filters.visible=function(a){return!p.expr.filters.hidden(a)}),p.each({margin:"",padding:"",border:"Width"},function(a,b){p.cssHooks[a+b]={expand:function(c){var d,e=typeof c=="string"?c.split(" "):[c],f={};for(d=0;d<4;d++)f[a+bU[d]+b]=e[d]||e[d-2]||e[0];return f}},bN.test(a)||(p.cssHooks[a+b].set=b$)});var cc=/%20/g,cd=/\[\]$/,ce=/\r?\n/g,cf=/^(?:color|date|datetime|datetime-local|email|hidden|month|number|password|range|search|tel|text|time|url|week)$/i,cg=/^(?:select|textarea)/i;p.fn.extend({serialize:function(){return p.param(this.serializeArray())},serializeArray:function(){return this.map(function(){return this.elements?p.makeArray(this.elements):this}).filter(function(){return this.name&&!this.disabled&&(this.checked||cg.test(this.nodeName)||cf.test(this.type))}).map(function(a,b){var c=p(this).val();return c==null?null:p.isArray(c)?p.map(c,function(a,c){return{name:b.name,value:a.replace(ce,"\r\n")}}):{name:b.name,value:c.replace(ce,"\r\n")}}).get()}}),p.param=function(a,c){var d,e=[],f=function(a,b){b=p.isFunction(b)?b():b==null?"":b,e[e.length]=encodeURIComponent(a)+"="+encodeURIComponent(b)};c===b&&(c=p.ajaxSettings&&p.ajaxSettings.traditional);if(p.isArray(a)||a.jquery&&!p.isPlainObject(a))p.each(a,function(){f(this.name,this.value)});else for(d in a)ch(d,a[d],c,f);return e.join("&").replace(cc,"+")};var ci,cj,ck=/#.*$/,cl=/^(.*?):[ \t]*([^\r\n]*)\r?$/mg,cm=/^(?:about|app|app\-storage|.+\-extension|file|res|widget):$/,cn=/^(?:GET|HEAD)$/,co=/^\/\//,cp=/\?/,cq=/<script\b[^<]*(?:(?!<\/script>)<[^<]*)*<\/script>/gi,cr=/([?&])_=[^&]*/,cs=/^([\w\+\.\-]+:)(?:\/\/([^\/?#:]*)(?::(\d+)|)|)/,ct=p.fn.load,cu={},cv={},cw=["*/"]+["*"];try{ci=f.href}catch(cx){ci=e.createElement("a"),ci.href="",ci=ci.href}cj=cs.exec(ci.toLowerCase())||[],p.fn.load=function(a,c,d){if(typeof a!="string"&&ct)return ct.apply(this,arguments);if(!this.length)return this;var e,f,g,h=this,i=a.indexOf(" ");return i>=0&&(e=a.slice(i,a.length),a=a.slice(0,i)),p.isFunction(c)?(d=c,c=b):typeof c=="object"&&(f="POST"),p.ajax({url:a,type:f,dataType:"html",data:c,complete:function(a,b){d&&h.each(d,g||[a.responseText,b,a])}}).done(function(a){g=arguments,h.html(e?p("<div>").append(a.replace(cq,"")).find(e):a)}),this},p.each("ajaxStart ajaxStop ajaxComplete ajaxError ajaxSuccess ajaxSend".split(" "),function(a,b){p.fn[b]=function(a){return this.on(b,a)}}),p.each(["get","post"],function(a,c){p[c]=function(a,d,e,f){return p.isFunction(d)&&(f=f||e,e=d,d=b),p.ajax({type:c,url:a,data:d,success:e,dataType:f})}}),p.extend({getScript:function(a,c){return p.get(a,b,c,"script")},getJSON:function(a,b,c){return p.get(a,b,c,"json")},ajaxSetup:function(a,b){return b?cA(a,p.ajaxSettings):(b=a,a=p.ajaxSettings),cA(a,b),a},ajaxSettings:{url:ci,isLocal:cm.test(cj[1]),global:!0,type:"GET",contentType:"application/x-www-form-urlencoded; charset=UTF-8",processData:!0,async:!0,accepts:{xml:"application/xml, text/xml",html:"text/html",text:"text/plain",json:"application/json, text/javascript","*":cw},contents:{xml:/xml/,html:/html/,json:/json/},responseFields:{xml:"responseXML",text:"responseText"},converters:{"* text":a.String,"text html":!0,"text json":p.parseJSON,"text xml":p.parseXML},flatOptions:{context:!0,url:!0}},ajaxPrefilter:cy(cu),ajaxTransport:cy(cv),ajax:function(a,c){function y(a,c,f,i){var k,s,t,u,w,y=c;if(v===2)return;v=2,h&&clearTimeout(h),g=b,e=i||"",x.readyState=a>0?4:0,f&&(u=cB(l,x,f));if(a>=200&&a<300||a===304)l.ifModified&&(w=x.getResponseHeader("Last-Modified"),w&&(p.lastModified[d]=w),w=x.getResponseHeader("Etag"),w&&(p.etag[d]=w)),a===304?(y="notmodified",k=!0):(k=cC(l,u),y=k.state,s=k.data,t=k.error,k=!t);else{t=y;if(!y||a)y="error",a<0&&(a=0)}x.status=a,x.statusText=""+(c||y),k?o.resolveWith(m,[s,y,x]):o.rejectWith(m,[x,y,t]),x.statusCode(r),r=b,j&&n.trigger("ajax"+(k?"Success":"Error"),[x,l,k?s:t]),q.fireWith(m,[x,y]),j&&(n.trigger("ajaxComplete",[x,l]),--p.active||p.event.trigger("ajaxStop"))}typeof a=="object"&&(c=a,a=b),c=c||{};var d,e,f,g,h,i,j,k,l=p.ajaxSetup({},c),m=l.context||l,n=m!==l&&(m.nodeType||m instanceof p)?p(m):p.event,o=p.Deferred(),q=p.Callbacks("once memory"),r=l.statusCode||{},t={},u={},v=0,w="canceled",x={readyState:0,setRequestHeader:function(a,b){if(!v){var c=a.toLowerCase();a=u[c]=u[c]||a,t[a]=b}return this},getAllResponseHeaders:function(){return v===2?e:null},getResponseHeader:function(a){var c;if(v===2){if(!f){f={};while(c=cl.exec(e))f[c[1].toLowerCase()]=c[2]}c=f[a.toLowerCase()]}return c===b?null:c},overrideMimeType:function(a){return v||(l.mimeType=a),this},abort:function(a){return a=a||w,g&&g.abort(a),y(0,a),this}};o.promise(x),x.success=x.done,x.error=x.fail,x.complete=q.add,x.statusCode=function(a){if(a){var b;if(v<2)for(b in a)r[b]=[r[b],a[b]];else b=a[x.status],x.always(b)}return this},l.url=((a||l.url)+"").replace(ck,"").replace(co,cj[1]+"//"),l.dataTypes=p.trim(l.dataType||"*").toLowerCase().split(s),l.crossDomain==null&&(i=cs.exec(l.url.toLowerCase()),l.crossDomain=!(!i||i[1]==cj[1]&&i[2]==cj[2]&&(i[3]||(i[1]==="http:"?80:443))==(cj[3]||(cj[1]==="http:"?80:443)))),l.data&&l.processData&&typeof l.data!="string"&&(l.data=p.param(l.data,l.traditional)),cz(cu,l,c,x);if(v===2)return x;j=l.global,l.type=l.type.toUpperCase(),l.hasContent=!cn.test(l.type),j&&p.active++===0&&p.event.trigger("ajaxStart");if(!l.hasContent){l.data&&(l.url+=(cp.test(l.url)?"&":"?")+l.data,delete l.data),d=l.url;if(l.cache===!1){var z=p.now(),A=l.url.replace(cr,"$1_="+z);l.url=A+(A===l.url?(cp.test(l.url)?"&":"?")+"_="+z:"")}}(l.data&&l.hasContent&&l.contentType!==!1||c.contentType)&&x.setRequestHeader("Content-Type",l.contentType),l.ifModified&&(d=d||l.url,p.lastModified[d]&&x.setRequestHeader("If-Modified-Since",p.lastModified[d]),p.etag[d]&&x.setRequestHeader("If-None-Match",p.etag[d])),x.setRequestHeader("Accept",l.dataTypes[0]&&l.accepts[l.dataTypes[0]]?l.accepts[l.dataTypes[0]]+(l.dataTypes[0]!=="*"?", "+cw+"; q=0.01":""):l.accepts["*"]);for(k in l.headers)x.setRequestHeader(k,l.headers[k]);if(!l.beforeSend||l.beforeSend.call(m,x,l)!==!1&&v!==2){w="abort";for(k in{success:1,error:1,complete:1})x[k](l[k]);g=cz(cv,l,c,x);if(!g)y(-1,"No Transport");else{x.readyState=1,j&&n.trigger("ajaxSend",[x,l]),l.async&&l.timeout>0&&(h=setTimeout(function(){x.abort("timeout")},l.timeout));try{v=1,g.send(t,y)}catch(B){if(v<2)y(-1,B);else throw B}}return x}return x.abort()},active:0,lastModified:{},etag:{}});var cD=[],cE=/\?/,cF=/(=)\?(?=&|$)|\?\?/,cG=p.now();p.ajaxSetup({jsonp:"callback",jsonpCallback:function(){var a=cD.pop()||p.expando+"_"+cG++;return this[a]=!0,a}}),p.ajaxPrefilter("json jsonp",function(c,d,e){var f,g,h,i=c.data,j=c.url,k=c.jsonp!==!1,l=k&&cF.test(j),m=k&&!l&&typeof i=="string"&&!(c.contentType||"").indexOf("application/x-www-form-urlencoded")&&cF.test(i);if(c.dataTypes[0]==="jsonp"||l||m)return f=c.jsonpCallback=p.isFunction(c.jsonpCallback)?c.jsonpCallback():c.jsonpCallback,g=a[f],l?c.url=j.replace(cF,"$1"+f):m?c.data=i.replace(cF,"$1"+f):k&&(c.url+=(cE.test(j)?"&":"?")+c.jsonp+"="+f),c.converters["script json"]=function(){return h||p.error(f+" was not called"),h[0]},c.dataTypes[0]="json",a[f]=function(){h=arguments},e.always(function(){a[f]=g,c[f]&&(c.jsonpCallback=d.jsonpCallback,cD.push(f)),h&&p.isFunction(g)&&g(h[0]),h=g=b}),"script"}),p.ajaxSetup({accepts:{script:"text/javascript, application/javascript, application/ecmascript, application/x-ecmascript"},contents:{script:/javascript|ecmascript/},converters:{"text script":function(a){return p.globalEval(a),a}}}),p.ajaxPrefilter("script",function(a){a.cache===b&&(a.cache=!1),a.crossDomain&&(a.type="GET",a.global=!1)}),p.ajaxTransport("script",function(a){if(a.crossDomain){var c,d=e.head||e.getElementsByTagName("head")[0]||e.documentElement;return{send:function(f,g){c=e.createElement("script"),c.async="async",a.scriptCharset&&(c.charset=a.scriptCharset),c.src=a.url,c.onload=c.onreadystatechange=function(a,e){if(e||!c.readyState||/loaded|complete/.test(c.readyState))c.onload=c.onreadystatechange=null,d&&c.parentNode&&d.removeChild(c),c=b,e||g(200,"success")},d.insertBefore(c,d.firstChild)},abort:function(){c&&c.onload(0,1)}}}});var cH,cI=a.ActiveXObject?function(){for(var a in cH)cH[a](0,1)}:!1,cJ=0;p.ajaxSettings.xhr=a.ActiveXObject?function(){return!this.isLocal&&cK()||cL()}:cK,function(a){p.extend(p.support,{ajax:!!a,cors:!!a&&"withCredentials"in a})}(p.ajaxSettings.xhr()),p.support.ajax&&p.ajaxTransport(function(c){if(!c.crossDomain||p.support.cors){var d;return{send:function(e,f){var g,h,i=c.xhr();c.username?i.open(c.type,c.url,c.async,c.username,c.password):i.open(c.type,c.url,c.async);if(c.xhrFields)for(h in c.xhrFields)i[h]=c.xhrFields[h];c.mimeType&&i.overrideMimeType&&i.overrideMimeType(c.mimeType),!c.crossDomain&&!e["X-Requested-With"]&&(e["X-Requested-With"]="XMLHttpRequest");try{for(h in e)i.setRequestHeader(h,e[h])}catch(j){}i.send(c.hasContent&&c.data||null),d=function(a,e){var h,j,k,l,m;try{if(d&&(e||i.readyState===4)){d=b,g&&(i.onreadystatechange=p.noop,cI&&delete cH[g]);if(e)i.readyState!==4&&i.abort();else{h=i.status,k=i.getAllResponseHeaders(),l={},m=i.responseXML,m&&m.documentElement&&(l.xml=m);try{l.text=i.responseText}catch(a){}try{j=i.statusText}catch(n){j=""}!h&&c.isLocal&&!c.crossDomain?h=l.text?200:404:h===1223&&(h=204)}}}catch(o){e||f(-1,o)}l&&f(h,j,l,k)},c.async?i.readyState===4?setTimeout(d,0):(g=++cJ,cI&&(cH||(cH={},p(a).unload(cI)),cH[g]=d),i.onreadystatechange=d):d()},abort:function(){d&&d(0,1)}}}});var cM,cN,cO=/^(?:toggle|show|hide)$/,cP=new RegExp("^(?:([-+])=|)("+q+")([a-z%]*)$","i"),cQ=/queueHooks$/,cR=[cX],cS={"*":[function(a,b){var c,d,e,f=this.createTween(a,b),g=cP.exec(b),h=f.cur(),i=+h||0,j=1;if(g){c=+g[2],d=g[3]||(p.cssNumber[a]?"":"px");if(d!=="px"&&i){i=p.css(f.elem,a,!0)||c||1;do e=j=j||".5",i=i/j,p.style(f.elem,a,i+d),j=f.cur()/h;while(j!==1&&j!==e)}f.unit=d,f.start=i,f.end=g[1]?i+(g[1]+1)*c:c}return f}]};p.Animation=p.extend(cV,{tweener:function(a,b){p.isFunction(a)?(b=a,a=["*"]):a=a.split(" ");var c,d=0,e=a.length;for(;d<e;d++)c=a[d],cS[c]=cS[c]||[],cS[c].unshift(b)},prefilter:function(a,b){b?cR.unshift(a):cR.push(a)}}),p.Tween=cY,cY.prototype={constructor:cY,init:function(a,b,c,d,e,f){this.elem=a,this.prop=c,this.easing=e||"swing",this.options=b,this.start=this.now=this.cur(),this.end=d,this.unit=f||(p.cssNumber[c]?"":"px")},cur:function(){var a=cY.propHooks[this.prop];return a&&a.get?a.get(this):cY.propHooks._default.get(this)},run:function(a){var b,c=cY.propHooks[this.prop];return this.pos=b=p.easing[this.easing](a,this.options.duration*a,0,1,this.options.duration),this.now=(this.end-this.start)*b+this.start,this.options.step&&this.options.step.call(this.elem,this.now,this),c&&c.set?c.set(this):cY.propHooks._default.set(this),this}},cY.prototype.init.prototype=cY.prototype,cY.propHooks={_default:{get:function(a){var b;return a.elem[a.prop]==null||!!a.elem.style&&a.elem.style[a.prop]!=null?(b=p.css(a.elem,a.prop,!1,""),!b||b==="auto"?0:b):a.elem[a.prop]},set:function(a){p.fx.step[a.prop]?p.fx.step[a.prop](a):a.elem.style&&(a.elem.style[p.cssProps[a.prop]]!=null||p.cssHooks[a.prop])?p.style(a.elem,a.prop,a.now+a.unit):a.elem[a.prop]=a.now}}},cY.propHooks.scrollTop=cY.propHooks.scrollLeft={set:function(a){a.elem.nodeType&&a.elem.parentNode&&(a.elem[a.prop]=a.now)}},p.each(["toggle","show","hide"],function(a,b){var c=p.fn[b];p.fn[b]=function(d,e,f){return d==null||typeof d=="boolean"||!a&&p.isFunction(d)&&p.isFunction(e)?c.apply(this,arguments):this.animate(cZ(b,!0),d,e,f)}}),p.fn.extend({fadeTo:function(a,b,c,d){return this.filter(bY).css("opacity",0).show().end().animate({opacity:b},a,c,d)},animate:function(a,b,c,d){var e=p.isEmptyObject(a),f=p.speed(b,c,d),g=function(){var b=cV(this,p.extend({},a),f);e&&b.stop(!0)};return e||f.queue===!1?this.each(g):this.queue(f.queue,g)},stop:function(a,c,d){var e=function(a){var b=a.stop;delete a.stop,b(d)};return typeof a!="string"&&(d=c,c=a,a=b),c&&a!==!1&&this.queue(a||"fx",[]),this.each(function(){var b=!0,c=a!=null&&a+"queueHooks",f=p.timers,g=p._data(this);if(c)g[c]&&g[c].stop&&e(g[c]);else for(c in g)g[c]&&g[c].stop&&cQ.test(c)&&e(g[c]);for(c=f.length;c--;)f[c].elem===this&&(a==null||f[c].queue===a)&&(f[c].anim.stop(d),b=!1,f.splice(c,1));(b||!d)&&p.dequeue(this,a)})}}),p.each({slideDown:cZ("show"),slideUp:cZ("hide"),slideToggle:cZ("toggle"),fadeIn:{opacity:"show"},fadeOut:{opacity:"hide"},fadeToggle:{opacity:"toggle"}},function(a,b){p.fn[a]=function(a,c,d){return this.animate(b,a,c,d)}}),p.speed=function(a,b,c){var d=a&&typeof a=="object"?p.extend({},a):{complete:c||!c&&b||p.isFunction(a)&&a,duration:a,easing:c&&b||b&&!p.isFunction(b)&&b};d.duration=p.fx.off?0:typeof d.duration=="number"?d.duration:d.duration in p.fx.speeds?p.fx.speeds[d.duration]:p.fx.speeds._default;if(d.queue==null||d.queue===!0)d.queue="fx";return d.old=d.complete,d.complete=function(){p.isFunction(d.old)&&d.old.call(this),d.queue&&p.dequeue(this,d.queue)},d},p.easing={linear:function(a){return a},swing:function(a){return.5-Math.cos(a*Math.PI)/2}},p.timers=[],p.fx=cY.prototype.init,p.fx.tick=function(){var a,b=p.timers,c=0;for(;c<b.length;c++)a=b[c],!a()&&b[c]===a&&b.splice(c--,1);b.length||p.fx.stop()},p.fx.timer=function(a){a()&&p.timers.push(a)&&!cN&&(cN=setInterval(p.fx.tick,p.fx.interval))},p.fx.interval=13,p.fx.stop=function(){clearInterval(cN),cN=null},p.fx.speeds={slow:600,fast:200,_default:400},p.fx.step={},p.expr&&p.expr.filters&&(p.expr.filters.animated=function(a){return p.grep(p.timers,function(b){return a===b.elem}).length});var c$=/^(?:body|html)$/i;p.fn.offset=function(a){if(arguments.length)return a===b?this:this.each(function(b){p.offset.setOffset(this,a,b)});var c,d,e,f,g,h,i,j,k,l,m=this[0],n=m&&m.ownerDocument;if(!n)return;return(e=n.body)===m?p.offset.bodyOffset(m):(d=n.documentElement,p.contains(d,m)?(c=m.getBoundingClientRect(),f=c_(n),g=d.clientTop||e.clientTop||0,h=d.clientLeft||e.clientLeft||0,i=f.pageYOffset||d.scrollTop,j=f.pageXOffset||d.scrollLeft,k=c.top+i-g,l=c.left+j-h,{top:k,left:l}):{top:0,left:0})},p.offset={bodyOffset:function(a){var b=a.offsetTop,c=a.offsetLeft;return p.support.doesNotIncludeMarginInBodyOffset&&(b+=parseFloat(p.css(a,"marginTop"))||0,c+=parseFloat(p.css(a,"marginLeft"))||0),{top:b,left:c}},setOffset:function(a,b,c){var d=p.css(a,"position");d==="static"&&(a.style.position="relative");var e=p(a),f=e.offset(),g=p.css(a,"top"),h=p.css(a,"left"),i=(d==="absolute"||d==="fixed")&&p.inArray("auto",[g,h])>-1,j={},k={},l,m;i?(k=e.position(),l=k.top,m=k.left):(l=parseFloat(g)||0,m=parseFloat(h)||0),p.isFunction(b)&&(b=b.call(a,c,f)),b.top!=null&&(j.top=b.top-f.top+l),b.left!=null&&(j.left=b.left-f.left+m),"using"in b?b.using.call(a,j):e.css(j)}},p.fn.extend({position:function(){if(!this[0])return;var a=this[0],b=this.offsetParent(),c=this.offset(),d=c$.test(b[0].nodeName)?{top:0,left:0}:b.offset();return c.top-=parseFloat(p.css(a,"marginTop"))||0,c.left-=parseFloat(p.css(a,"marginLeft"))||0,d.top+=parseFloat(p.css(b[0],"borderTopWidth"))||0,d.left+=parseFloat(p.css(b[0],"borderLeftWidth"))||0,{top:c.top-d.top,left:c.left-d.left}},offsetParent:function(){return this.map(function(){var a=this.offsetParent||e.body;while(a&&!c$.test(a.nodeName)&&p.css(a,"position")==="static")a=a.offsetParent;return a||e.body})}}),p.each({scrollLeft:"pageXOffset",scrollTop:"pageYOffset"},function(a,c){var d=/Y/.test(c);p.fn[a]=function(e){return p.access(this,function(a,e,f){var g=c_(a);if(f===b)return g?c in g?g[c]:g.document.documentElement[e]:a[e];g?g.scrollTo(d?p(g).scrollLeft():f,d?f:p(g).scrollTop()):a[e]=f},a,e,arguments.length,null)}}),p.each({Height:"height",Width:"width"},function(a,c){p.each({padding:"inner"+a,content:c,"":"outer"+a},function(d,e){p.fn[e]=function(e,f){var g=arguments.length&&(d||typeof e!="boolean"),h=d||(e===!0||f===!0?"margin":"border");return p.access(this,function(c,d,e){var f;return p.isWindow(c)?c.document.documentElement["client"+a]:c.nodeType===9?(f=c.documentElement,Math.max(c.body["scroll"+a],f["scroll"+a],c.body["offset"+a],f["offset"+a],f["client"+a])):e===b?p.css(c,d,e,h):p.style(c,d,e,h)},c,g?e:b,g)}})}),a.jQuery=a.$=p,typeof define=="function"&&define.amd&&define.amd.jQuery&&define("jquery",[],function(){return p})})(window); \ No newline at end of file
diff --git a/ydb/core/viewer/content/api/lib/jquery.ba-bbq.min.js b/ydb/core/viewer/content/api/lib/jquery.ba-bbq.min.js
index 72952e70caf..bcbf24834ac 100644
--- a/ydb/core/viewer/content/api/lib/jquery.ba-bbq.min.js
+++ b/ydb/core/viewer/content/api/lib/jquery.ba-bbq.min.js
@@ -1,18 +1,18 @@
-/*
- * jQuery BBQ: Back Button & Query Library - v1.2.1 - 2/17/2010
- * http://benalman.com/projects/jquery-bbq-plugin/
- *
- * Copyright (c) 2010 "Cowboy" Ben Alman
- * Dual licensed under the MIT and GPL licenses.
- * http://benalman.com/about/license/
- */
-(function($,p){var i,m=Array.prototype.slice,r=decodeURIComponent,a=$.param,c,l,v,b=$.bbq=$.bbq||{},q,u,j,e=$.event.special,d="hashchange",A="querystring",D="fragment",y="elemUrlAttr",g="location",k="href",t="src",x=/^.*\?|#.*$/g,w=/^.*\#/,h,C={};function E(F){return typeof F==="string"}function B(G){var F=m.call(arguments,1);return function(){return G.apply(this,F.concat(m.call(arguments)))}}function n(F){return F.replace(/^[^#]*#?(.*)$/,"$1")}function o(F){return F.replace(/(?:^[^?#]*\?([^#]*).*$)?.*/,"$1")}function f(H,M,F,I,G){var O,L,K,N,J;if(I!==i){K=F.match(H?/^([^#]*)\#?(.*)$/:/^([^#?]*)\??([^#]*)(#?.*)/);J=K[3]||"";if(G===2&&E(I)){L=I.replace(H?w:x,"")}else{N=l(K[2]);I=E(I)?l[H?D:A](I):I;L=G===2?I:G===1?$.extend({},I,N):$.extend({},N,I);L=a(L);if(H){L=L.replace(h,r)}}O=K[1]+(H?"#":L||!K[1]?"?":"")+L+J}else{O=M(F!==i?F:p[g][k])}return O}a[A]=B(f,0,o);a[D]=c=B(f,1,n);c.noEscape=function(G){G=G||"";var F=$.map(G.split(""),encodeURIComponent);h=new RegExp(F.join("|"),"g")};c.noEscape(",/");$.deparam=l=function(I,F){var H={},G={"true":!0,"false":!1,"null":null};$.each(I.replace(/\+/g," ").split("&"),function(L,Q){var K=Q.split("="),P=r(K[0]),J,O=H,M=0,R=P.split("]["),N=R.length-1;if(/\[/.test(R[0])&&/\]$/.test(R[N])){R[N]=R[N].replace(/\]$/,"");R=R.shift().split("[").concat(R);N=R.length-1}else{N=0}if(K.length===2){J=r(K[1]);if(F){J=J&&!isNaN(J)?+J:J==="undefined"?i:G[J]!==i?G[J]:J}if(N){for(;M<=N;M++){P=R[M]===""?O.length:R[M];O=O[P]=M<N?O[P]||(R[M+1]&&isNaN(R[M+1])?{}:[]):J}}else{if($.isArray(H[P])){H[P].push(J)}else{if(H[P]!==i){H[P]=[H[P],J]}else{H[P]=J}}}}else{if(P){H[P]=F?i:""}}});return H};function z(H,F,G){if(F===i||typeof F==="boolean"){G=F;F=a[H?D:A]()}else{F=E(F)?F.replace(H?w:x,""):F}return l(F,G)}l[A]=B(z,0);l[D]=v=B(z,1);$[y]||($[y]=function(F){return $.extend(C,F)})({a:k,base:k,iframe:t,img:t,input:t,form:"action",link:k,script:t});j=$[y];function s(I,G,H,F){if(!E(H)&&typeof H!=="object"){F=H;H=G;G=i}return this.each(function(){var L=$(this),J=G||j()[(this.nodeName||"").toLowerCase()]||"",K=J&&L.attr(J)||"";L.attr(J,a[I](K,H,F))})}$.fn[A]=B(s,A);$.fn[D]=B(s,D);b.pushState=q=function(I,F){if(E(I)&&/^#/.test(I)&&F===i){F=2}var H=I!==i,G=c(p[g][k],H?I:{},H?F:2);p[g][k]=G+(/#/.test(G)?"":"#")};b.getState=u=function(F,G){return F===i||typeof F==="boolean"?v(F):v(G)[F]};b.removeState=function(F){var G={};if(F!==i){G=u();$.each($.isArray(F)?F:arguments,function(I,H){delete G[H]})}q(G,2)};e[d]=$.extend(e[d],{add:function(F){var H;function G(J){var I=J[D]=c();J.getState=function(K,L){return K===i||typeof K==="boolean"?l(I,K):l(I,L)[K]};H.apply(this,arguments)}if($.isFunction(F)){H=F;return G}else{H=F.handler;F.handler=G}}})})(jQuery,this);
-/*
- * jQuery hashchange event - v1.2 - 2/11/2010
- * http://benalman.com/projects/jquery-hashchange-plugin/
- *
- * Copyright (c) 2010 "Cowboy" Ben Alman
- * Dual licensed under the MIT and GPL licenses.
- * http://benalman.com/about/license/
- */
-(function($,i,b){var j,k=$.event.special,c="location",d="hashchange",l="href",f=$.browser,g=document.documentMode,h=f.msie&&(g===b||g<8),e="on"+d in i&&!h;function a(m){m=m||i[c][l];return m.replace(/^[^#]*#?(.*)$/,"$1")}$[d+"Delay"]=100;k[d]=$.extend(k[d],{setup:function(){if(e){return false}$(j.start)},teardown:function(){if(e){return false}$(j.stop)}});j=(function(){var m={},r,n,o,q;function p(){o=q=function(s){return s};if(h){n=$('<iframe src="javascript:0"/>').hide().insertAfter("body")[0].contentWindow;q=function(){return a(n.document[c][l])};o=function(u,s){if(u!==s){var t=n.document;t.open().close();t[c].hash="#"+u}};o(a())}}m.start=function(){if(r){return}var t=a();o||p();(function s(){var v=a(),u=q(t);if(v!==t){o(t=v,u);$(i).trigger(d)}else{if(u!==t){i[c][l]=i[c][l].replace(/#.*/,"")+"#"+u}}r=setTimeout(s,$[d+"Delay"])})()};m.stop=function(){if(!n){r&&clearTimeout(r);r=0}};return m})()})(jQuery,this); \ No newline at end of file
+/*
+ * jQuery BBQ: Back Button & Query Library - v1.2.1 - 2/17/2010
+ * http://benalman.com/projects/jquery-bbq-plugin/
+ *
+ * Copyright (c) 2010 "Cowboy" Ben Alman
+ * Dual licensed under the MIT and GPL licenses.
+ * http://benalman.com/about/license/
+ */
+(function($,p){var i,m=Array.prototype.slice,r=decodeURIComponent,a=$.param,c,l,v,b=$.bbq=$.bbq||{},q,u,j,e=$.event.special,d="hashchange",A="querystring",D="fragment",y="elemUrlAttr",g="location",k="href",t="src",x=/^.*\?|#.*$/g,w=/^.*\#/,h,C={};function E(F){return typeof F==="string"}function B(G){var F=m.call(arguments,1);return function(){return G.apply(this,F.concat(m.call(arguments)))}}function n(F){return F.replace(/^[^#]*#?(.*)$/,"$1")}function o(F){return F.replace(/(?:^[^?#]*\?([^#]*).*$)?.*/,"$1")}function f(H,M,F,I,G){var O,L,K,N,J;if(I!==i){K=F.match(H?/^([^#]*)\#?(.*)$/:/^([^#?]*)\??([^#]*)(#?.*)/);J=K[3]||"";if(G===2&&E(I)){L=I.replace(H?w:x,"")}else{N=l(K[2]);I=E(I)?l[H?D:A](I):I;L=G===2?I:G===1?$.extend({},I,N):$.extend({},N,I);L=a(L);if(H){L=L.replace(h,r)}}O=K[1]+(H?"#":L||!K[1]?"?":"")+L+J}else{O=M(F!==i?F:p[g][k])}return O}a[A]=B(f,0,o);a[D]=c=B(f,1,n);c.noEscape=function(G){G=G||"";var F=$.map(G.split(""),encodeURIComponent);h=new RegExp(F.join("|"),"g")};c.noEscape(",/");$.deparam=l=function(I,F){var H={},G={"true":!0,"false":!1,"null":null};$.each(I.replace(/\+/g," ").split("&"),function(L,Q){var K=Q.split("="),P=r(K[0]),J,O=H,M=0,R=P.split("]["),N=R.length-1;if(/\[/.test(R[0])&&/\]$/.test(R[N])){R[N]=R[N].replace(/\]$/,"");R=R.shift().split("[").concat(R);N=R.length-1}else{N=0}if(K.length===2){J=r(K[1]);if(F){J=J&&!isNaN(J)?+J:J==="undefined"?i:G[J]!==i?G[J]:J}if(N){for(;M<=N;M++){P=R[M]===""?O.length:R[M];O=O[P]=M<N?O[P]||(R[M+1]&&isNaN(R[M+1])?{}:[]):J}}else{if($.isArray(H[P])){H[P].push(J)}else{if(H[P]!==i){H[P]=[H[P],J]}else{H[P]=J}}}}else{if(P){H[P]=F?i:""}}});return H};function z(H,F,G){if(F===i||typeof F==="boolean"){G=F;F=a[H?D:A]()}else{F=E(F)?F.replace(H?w:x,""):F}return l(F,G)}l[A]=B(z,0);l[D]=v=B(z,1);$[y]||($[y]=function(F){return $.extend(C,F)})({a:k,base:k,iframe:t,img:t,input:t,form:"action",link:k,script:t});j=$[y];function s(I,G,H,F){if(!E(H)&&typeof H!=="object"){F=H;H=G;G=i}return this.each(function(){var L=$(this),J=G||j()[(this.nodeName||"").toLowerCase()]||"",K=J&&L.attr(J)||"";L.attr(J,a[I](K,H,F))})}$.fn[A]=B(s,A);$.fn[D]=B(s,D);b.pushState=q=function(I,F){if(E(I)&&/^#/.test(I)&&F===i){F=2}var H=I!==i,G=c(p[g][k],H?I:{},H?F:2);p[g][k]=G+(/#/.test(G)?"":"#")};b.getState=u=function(F,G){return F===i||typeof F==="boolean"?v(F):v(G)[F]};b.removeState=function(F){var G={};if(F!==i){G=u();$.each($.isArray(F)?F:arguments,function(I,H){delete G[H]})}q(G,2)};e[d]=$.extend(e[d],{add:function(F){var H;function G(J){var I=J[D]=c();J.getState=function(K,L){return K===i||typeof K==="boolean"?l(I,K):l(I,L)[K]};H.apply(this,arguments)}if($.isFunction(F)){H=F;return G}else{H=F.handler;F.handler=G}}})})(jQuery,this);
+/*
+ * jQuery hashchange event - v1.2 - 2/11/2010
+ * http://benalman.com/projects/jquery-hashchange-plugin/
+ *
+ * Copyright (c) 2010 "Cowboy" Ben Alman
+ * Dual licensed under the MIT and GPL licenses.
+ * http://benalman.com/about/license/
+ */
+(function($,i,b){var j,k=$.event.special,c="location",d="hashchange",l="href",f=$.browser,g=document.documentMode,h=f.msie&&(g===b||g<8),e="on"+d in i&&!h;function a(m){m=m||i[c][l];return m.replace(/^[^#]*#?(.*)$/,"$1")}$[d+"Delay"]=100;k[d]=$.extend(k[d],{setup:function(){if(e){return false}$(j.start)},teardown:function(){if(e){return false}$(j.stop)}});j=(function(){var m={},r,n,o,q;function p(){o=q=function(s){return s};if(h){n=$('<iframe src="javascript:0"/>').hide().insertAfter("body")[0].contentWindow;q=function(){return a(n.document[c][l])};o=function(u,s){if(u!==s){var t=n.document;t.open().close();t[c].hash="#"+u}};o(a())}}m.start=function(){if(r){return}var t=a();o||p();(function s(){var v=a(),u=q(t);if(v!==t){o(t=v,u);$(i).trigger(d)}else{if(u!==t){i[c][l]=i[c][l].replace(/#.*/,"")+"#"+u}}r=setTimeout(s,$[d+"Delay"])})()};m.stop=function(){if(!n){r&&clearTimeout(r);r=0}};return m})()})(jQuery,this); \ No newline at end of file
diff --git a/ydb/core/viewer/content/api/lib/jquery.slideto.min.js b/ydb/core/viewer/content/api/lib/jquery.slideto.min.js
index 89eab8eb0ca..ba32cff3651 100644
--- a/ydb/core/viewer/content/api/lib/jquery.slideto.min.js
+++ b/ydb/core/viewer/content/api/lib/jquery.slideto.min.js
@@ -1 +1 @@
-(function(b){b.fn.slideto=function(a){a=b.extend({slide_duration:"slow",highlight_duration:3E3,highlight:true,highlight_color:"#FFFF99"},a);return this.each(function(){obj=b(this);b("body").animate({scrollTop:obj.offset().top},a.slide_duration,function(){a.highlight&&b.ui.version&&obj.effect("highlight",{color:a.highlight_color},a.highlight_duration)})})}})(jQuery);
+(function(b){b.fn.slideto=function(a){a=b.extend({slide_duration:"slow",highlight_duration:3E3,highlight:true,highlight_color:"#FFFF99"},a);return this.each(function(){obj=b(this);b("body").animate({scrollTop:obj.offset().top},a.slide_duration,function(){a.highlight&&b.ui.version&&obj.effect("highlight",{color:a.highlight_color},a.highlight_duration)})})}})(jQuery);
diff --git a/ydb/core/viewer/content/api/lib/jquery.wiggle.min.js b/ydb/core/viewer/content/api/lib/jquery.wiggle.min.js
index a9f1993cdbe..2adb0d6d54a 100644
--- a/ydb/core/viewer/content/api/lib/jquery.wiggle.min.js
+++ b/ydb/core/viewer/content/api/lib/jquery.wiggle.min.js
@@ -1,8 +1,8 @@
-/*
-jQuery Wiggle
-Author: WonderGroup, Jordan Thomas
-URL: http://labs.wondergroup.com/demos/mini-ui/index.html
-License: MIT (http://en.wikipedia.org/wiki/MIT_License)
-*/
-jQuery.fn.wiggle=function(o){var d={speed:50,wiggles:3,travel:5,callback:null};var o=jQuery.extend(d,o);return this.each(function(){var cache=this;var wrap=jQuery(this).wrap('<div class="wiggle-wrap"></div>').css("position","relative");var calls=0;for(i=1;i<=o.wiggles;i++){jQuery(this).animate({left:"-="+o.travel},o.speed).animate({left:"+="+o.travel*2},o.speed*2).animate({left:"-="+o.travel},o.speed,function(){calls++;if(jQuery(cache).parent().hasClass('wiggle-wrap')){jQuery(cache).parent().replaceWith(cache);}
-if(calls==o.wiggles&&jQuery.isFunction(o.callback)){o.callback();}});}});}; \ No newline at end of file
+/*
+jQuery Wiggle
+Author: WonderGroup, Jordan Thomas
+URL: http://labs.wondergroup.com/demos/mini-ui/index.html
+License: MIT (http://en.wikipedia.org/wiki/MIT_License)
+*/
+jQuery.fn.wiggle=function(o){var d={speed:50,wiggles:3,travel:5,callback:null};var o=jQuery.extend(d,o);return this.each(function(){var cache=this;var wrap=jQuery(this).wrap('<div class="wiggle-wrap"></div>').css("position","relative");var calls=0;for(i=1;i<=o.wiggles;i++){jQuery(this).animate({left:"-="+o.travel},o.speed).animate({left:"+="+o.travel*2},o.speed*2).animate({left:"-="+o.travel},o.speed,function(){calls++;if(jQuery(cache).parent().hasClass('wiggle-wrap')){jQuery(cache).parent().replaceWith(cache);}
+if(calls==o.wiggles&&jQuery.isFunction(o.callback)){o.callback();}});}});}; \ No newline at end of file
diff --git a/ydb/core/viewer/content/api/lib/js-yaml.min.js b/ydb/core/viewer/content/api/lib/js-yaml.min.js
index 21c8d6b8242..c3d07adaae5 100644
--- a/ydb/core/viewer/content/api/lib/js-yaml.min.js
+++ b/ydb/core/viewer/content/api/lib/js-yaml.min.js
@@ -1,3 +1,3 @@
-/* js-yaml 3.4.6 https://github.com/nodeca/js-yaml */
-!function(t){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=t();else if("function"==typeof define&&define.amd)define([],t);else{var e;e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:this,e.jsyaml=t()}}(function(){var t;return function e(t,n,i){function r(a,s){if(!n[a]){if(!t[a]){var c="function"==typeof require&&require;if(!s&&c)return c(a,!0);if(o)return o(a,!0);var u=new Error("Cannot find module '"+a+"'");throw u.code="MODULE_NOT_FOUND",u}var l=n[a]={exports:{}};t[a][0].call(l.exports,function(e){var n=t[a][1][e];return r(n?n:e)},l,l.exports,e,t,n,i)}return n[a].exports}for(var o="function"==typeof require&&require,a=0;a<i.length;a++)r(i[a]);return r}({1:[function(t,e,n){"use strict";function i(t){return function(){throw new Error("Function "+t+" is deprecated and cannot be used.")}}var r=t("./js-yaml/loader"),o=t("./js-yaml/dumper");e.exports.Type=t("./js-yaml/type"),e.exports.Schema=t("./js-yaml/schema"),e.exports.FAILSAFE_SCHEMA=t("./js-yaml/schema/failsafe"),e.exports.JSON_SCHEMA=t("./js-yaml/schema/json"),e.exports.CORE_SCHEMA=t("./js-yaml/schema/core"),e.exports.DEFAULT_SAFE_SCHEMA=t("./js-yaml/schema/default_safe"),e.exports.DEFAULT_FULL_SCHEMA=t("./js-yaml/schema/default_full"),e.exports.load=r.load,e.exports.loadAll=r.loadAll,e.exports.safeLoad=r.safeLoad,e.exports.safeLoadAll=r.safeLoadAll,e.exports.dump=o.dump,e.exports.safeDump=o.safeDump,e.exports.YAMLException=t("./js-yaml/exception"),e.exports.MINIMAL_SCHEMA=t("./js-yaml/schema/failsafe"),e.exports.SAFE_SCHEMA=t("./js-yaml/schema/default_safe"),e.exports.DEFAULT_SCHEMA=t("./js-yaml/schema/default_full"),e.exports.scan=i("scan"),e.exports.parse=i("parse"),e.exports.compose=i("compose"),e.exports.addConstructor=i("addConstructor")},{"./js-yaml/dumper":3,"./js-yaml/exception":4,"./js-yaml/loader":5,"./js-yaml/schema":7,"./js-yaml/schema/core":8,"./js-yaml/schema/default_full":9,"./js-yaml/schema/default_safe":10,"./js-yaml/schema/failsafe":11,"./js-yaml/schema/json":12,"./js-yaml/type":13}],2:[function(t,e,n){"use strict";function i(t){return"undefined"==typeof t||null===t}function r(t){return"object"==typeof t&&null!==t}function o(t){return Array.isArray(t)?t:i(t)?[]:[t]}function a(t,e){var n,i,r,o;if(e)for(o=Object.keys(e),n=0,i=o.length;i>n;n+=1)r=o[n],t[r]=e[r];return t}function s(t,e){var n,i="";for(n=0;e>n;n+=1)i+=t;return i}function c(t){return 0===t&&Number.NEGATIVE_INFINITY===1/t}e.exports.isNothing=i,e.exports.isObject=r,e.exports.toArray=o,e.exports.repeat=s,e.exports.isNegativeZero=c,e.exports.extend=a},{}],3:[function(t,e,n){"use strict";function i(t,e){var n,i,r,o,a,s,c;if(null===e)return{};for(n={},i=Object.keys(e),r=0,o=i.length;o>r;r+=1)a=i[r],s=String(e[a]),"!!"===a.slice(0,2)&&(a="tag:yaml.org,2002:"+a.slice(2)),c=t.compiledTypeMap[a],c&&E.call(c.styleAliases,s)&&(s=c.styleAliases[s]),n[a]=s;return n}function r(t){var e,n,i;if(e=t.toString(16).toUpperCase(),255>=t)n="x",i=2;else if(65535>=t)n="u",i=4;else{if(!(4294967295>=t))throw new O("code point within a string may not be greater than 0xFFFFFFFF");n="U",i=8}return"\\"+n+j.repeat("0",i-e.length)+e}function o(t){this.schema=t.schema||S,this.indent=Math.max(1,t.indent||2),this.skipInvalid=t.skipInvalid||!1,this.flowLevel=j.isNothing(t.flowLevel)?-1:t.flowLevel,this.styleMap=i(this.schema,t.styles||null),this.sortKeys=t.sortKeys||!1,this.lineWidth=t.lineWidth||80,this.implicitTypes=this.schema.compiledImplicit,this.explicitTypes=this.schema.compiledExplicit,this.tag=null,this.result="",this.duplicates=[],this.usedDuplicates=null}function a(t,e){for(var n,i=j.repeat(" ",e),r=0,o=-1,a="",s=t.length;s>r;)o=t.indexOf("\n",r),-1===o?(n=t.slice(r),r=s):(n=t.slice(r,o+1),r=o+1),n.length&&"\n"!==n&&(a+=i),a+=n;return a}function s(t,e){return"\n"+j.repeat(" ",t.indent*e)}function c(t,e){var n,i,r;for(n=0,i=t.implicitTypes.length;i>n;n+=1)if(r=t.implicitTypes[n],r.resolve(e))return!0;return!1}function u(t){this.source=t,this.result="",this.checkpoint=0}function l(t,e,n,i){var r,o,s,l,f,m,g,y,v,x,A,b,w,k,C,j,O,S,_,I,E;if(0===e.length)return void(t.dump="''");if(-1!==et.indexOf(e))return void(t.dump="'"+e+"'");for(r=!0,o=e.length?e.charCodeAt(0):0,s=M===o||M===e.charCodeAt(e.length-1),(K===o||W===o||G===o||z===o)&&(r=!1),s?(r=!1,l=!1,f=!1):(l=!i,f=!i),m=!0,g=new u(e),y=!1,v=0,x=0,A=t.indent*n,b=t.lineWidth,-1===b&&(b=9007199254740991),40>A?b-=A:b=40,k=0;k<e.length;k++){if(w=e.charCodeAt(k),r){if(h(w))continue;r=!1}m&&w===P&&(m=!1),C=tt[w],j=d(w),(C||j)&&(w!==N&&w!==D&&w!==P?(l=!1,f=!1):w===N&&(y=!0,m=!1,k>0&&(O=e.charCodeAt(k-1),O===M&&(f=!1,l=!1)),l&&(S=k-v,v=k,S>x&&(x=S))),w!==D&&(m=!1),g.takeUpTo(k),g.escapeChar())}if(r&&c(t,e)&&(r=!1),_="",(l||f)&&(I=0,e.charCodeAt(e.length-1)===N&&(I+=1,e.charCodeAt(e.length-2)===N&&(I+=1)),0===I?_="-":2===I&&(_="+")),f&&b>x&&(l=!1),y||(f=!1),r)t.dump=e;else if(m)t.dump="'"+e+"'";else if(l)E=p(e,b),t.dump=">"+_+"\n"+a(E,A);else if(f)_||(e=e.replace(/\n$/,"")),t.dump="|"+_+"\n"+a(e,A);else{if(!g)throw new Error("Failed to dump scalar value");g.finish(),t.dump='"'+g.result+'"'}}function p(t,e){var n,i="",r=0,o=t.length,a=/\n+$/.exec(t);for(a&&(o=a.index+1);o>r;)n=t.indexOf("\n",r),n>o||-1===n?(i&&(i+="\n\n"),i+=f(t.slice(r,o),e),r=o):(i&&(i+="\n\n"),i+=f(t.slice(r,n),e),r=n+1);return a&&"\n"!==a[0]&&(i+=a[0]),i}function f(t,e){if(""===t)return t;for(var n,i,r,o=/[^\s] [^\s]/g,a="",s=0,c=0,u=o.exec(t);u;)n=u.index,n-c>e&&(i=s!==c?s:n,a&&(a+="\n"),r=t.slice(c,i),a+=r,c=i+1),s=n+1,u=o.exec(t);return a&&(a+="\n"),a+=c!==s&&t.length-c>e?t.slice(c,s)+"\n"+t.slice(s+1):t.slice(c)}function h(t){return F!==t&&N!==t&&T!==t&&B!==t&&V!==t&&Z!==t&&J!==t&&X!==t&&U!==t&&Y!==t&&$!==t&&L!==t&&Q!==t&&R!==t&&P!==t&&D!==t&&q!==t&&H!==t&&!tt[t]&&!d(t)}function d(t){return!(t>=32&&126>=t||133===t||t>=160&&55295>=t||t>=57344&&65533>=t||t>=65536&&1114111>=t)}function m(t,e,n){var i,r,o="",a=t.tag;for(i=0,r=n.length;r>i;i+=1)A(t,e,n[i],!1,!1)&&(0!==i&&(o+=", "),o+=t.dump);t.tag=a,t.dump="["+o+"]"}function g(t,e,n,i){var r,o,a="",c=t.tag;for(r=0,o=n.length;o>r;r+=1)A(t,e+1,n[r],!0,!0)&&(i&&0===r||(a+=s(t,e)),a+="- "+t.dump);t.tag=c,t.dump=a||"[]"}function y(t,e,n){var i,r,o,a,s,c="",u=t.tag,l=Object.keys(n);for(i=0,r=l.length;r>i;i+=1)s="",0!==i&&(s+=", "),o=l[i],a=n[o],A(t,e,o,!1,!1)&&(t.dump.length>1024&&(s+="? "),s+=t.dump+": ",A(t,e,a,!1,!1)&&(s+=t.dump,c+=s));t.tag=u,t.dump="{"+c+"}"}function v(t,e,n,i){var r,o,a,c,u,l,p="",f=t.tag,h=Object.keys(n);if(t.sortKeys===!0)h.sort();else if("function"==typeof t.sortKeys)h.sort(t.sortKeys);else if(t.sortKeys)throw new O("sortKeys must be a boolean or a function");for(r=0,o=h.length;o>r;r+=1)l="",i&&0===r||(l+=s(t,e)),a=h[r],c=n[a],A(t,e+1,a,!0,!0,!0)&&(u=null!==t.tag&&"?"!==t.tag||t.dump&&t.dump.length>1024,u&&(l+=t.dump&&N===t.dump.charCodeAt(0)?"?":"? "),l+=t.dump,u&&(l+=s(t,e)),A(t,e+1,c,!0,u)&&(l+=t.dump&&N===t.dump.charCodeAt(0)?":":": ",l+=t.dump,p+=l));t.tag=f,t.dump=p||"{}"}function x(t,e,n){var i,r,o,a,s,c;for(r=n?t.explicitTypes:t.implicitTypes,o=0,a=r.length;a>o;o+=1)if(s=r[o],(s.instanceOf||s.predicate)&&(!s.instanceOf||"object"==typeof e&&e instanceof s.instanceOf)&&(!s.predicate||s.predicate(e))){if(t.tag=n?s.tag:"?",s.represent){if(c=t.styleMap[s.tag]||s.defaultStyle,"[object Function]"===I.call(s.represent))i=s.represent(e,c);else{if(!E.call(s.represent,c))throw new O("!<"+s.tag+'> tag resolver accepts not "'+c+'" style');i=s.represent[c](e,c)}t.dump=i}return!0}return!1}function A(t,e,n,i,r,o){t.tag=null,t.dump=n,x(t,n,!1)||x(t,n,!0);var a=I.call(t.dump);i&&(i=0>t.flowLevel||t.flowLevel>e);var s,c,u="[object Object]"===a||"[object Array]"===a;if(u&&(s=t.duplicates.indexOf(n),c=-1!==s),(null!==t.tag&&"?"!==t.tag||c||2!==t.indent&&e>0)&&(r=!1),c&&t.usedDuplicates[s])t.dump="*ref_"+s;else{if(u&&c&&!t.usedDuplicates[s]&&(t.usedDuplicates[s]=!0),"[object Object]"===a)i&&0!==Object.keys(t.dump).length?(v(t,e,t.dump,r),c&&(t.dump="&ref_"+s+t.dump)):(y(t,e,t.dump),c&&(t.dump="&ref_"+s+" "+t.dump));else if("[object Array]"===a)i&&0!==t.dump.length?(g(t,e,t.dump,r),c&&(t.dump="&ref_"+s+t.dump)):(m(t,e,t.dump),c&&(t.dump="&ref_"+s+" "+t.dump));else{if("[object String]"!==a){if(t.skipInvalid)return!1;throw new O("unacceptable kind of an object to dump "+a)}"?"!==t.tag&&l(t,t.dump,e,o)}null!==t.tag&&"?"!==t.tag&&(t.dump="!<"+t.tag+"> "+t.dump)}return!0}function b(t,e){var n,i,r=[],o=[];for(w(t,r,o),n=0,i=o.length;i>n;n+=1)e.duplicates.push(r[o[n]]);e.usedDuplicates=new Array(i)}function w(t,e,n){var i,r,o;if(null!==t&&"object"==typeof t)if(r=e.indexOf(t),-1!==r)-1===n.indexOf(r)&&n.push(r);else if(e.push(t),Array.isArray(t))for(r=0,o=t.length;o>r;r+=1)w(t[r],e,n);else for(i=Object.keys(t),r=0,o=i.length;o>r;r+=1)w(t[i[r]],e,n)}function k(t,e){e=e||{};var n=new o(e);return b(t,n),A(n,0,t,!0,!0)?n.dump+"\n":""}function C(t,e){return k(t,j.extend({schema:_},e))}var j=t("./common"),O=t("./exception"),S=t("./schema/default_full"),_=t("./schema/default_safe"),I=Object.prototype.toString,E=Object.prototype.hasOwnProperty,F=9,N=10,T=13,M=32,L=33,D=34,U=35,q=37,Y=38,P=39,$=42,B=44,K=45,H=58,R=62,W=63,G=64,V=91,Z=93,z=96,J=123,Q=124,X=125,tt={};tt[0]="\\0",tt[7]="\\a",tt[8]="\\b",tt[9]="\\t",tt[10]="\\n",tt[11]="\\v",tt[12]="\\f",tt[13]="\\r",tt[27]="\\e",tt[34]='\\"',tt[92]="\\\\",tt[133]="\\N",tt[160]="\\_",tt[8232]="\\L",tt[8233]="\\P";var et=["y","Y","yes","Yes","YES","on","On","ON","n","N","no","No","NO","off","Off","OFF"];u.prototype.takeUpTo=function(t){var e;if(t<this.checkpoint)throw e=new Error("position should be > checkpoint"),e.position=t,e.checkpoint=this.checkpoint,e;return this.result+=this.source.slice(this.checkpoint,t),this.checkpoint=t,this},u.prototype.escapeChar=function(){var t,e;return t=this.source.charCodeAt(this.checkpoint),e=tt[t]||r(t),this.result+=e,this.checkpoint+=1,this},u.prototype.finish=function(){this.source.length>this.checkpoint&&this.takeUpTo(this.source.length)},e.exports.dump=k,e.exports.safeDump=C},{"./common":2,"./exception":4,"./schema/default_full":9,"./schema/default_safe":10}],4:[function(t,e,n){"use strict";function i(t,e){Error.call(this),Error.captureStackTrace?Error.captureStackTrace(this,this.constructor):this.stack=(new Error).stack||"",this.name="YAMLException",this.reason=t,this.mark=e,this.message=(this.reason||"(unknown reason)")+(this.mark?" "+this.mark.toString():"")}var r=t("inherit");r(i,Error),i.prototype.toString=function(t){var e=this.name+": ";return e+=this.reason||"(unknown reason)",!t&&this.mark&&(e+=" "+this.mark.toString()),e},e.exports=i},{inherit:31}],5:[function(t,e,n){"use strict";function i(t){return 10===t||13===t}function r(t){return 9===t||32===t}function o(t){return 9===t||32===t||10===t||13===t}function a(t){return 44===t||91===t||93===t||123===t||125===t}function s(t){var e;return t>=48&&57>=t?t-48:(e=32|t,e>=97&&102>=e?e-97+10:-1)}function c(t){return 120===t?2:117===t?4:85===t?8:0}function u(t){return t>=48&&57>=t?t-48:-1}function l(t){return 48===t?"\x00":97===t?"":98===t?"\b":116===t?" ":9===t?" ":110===t?"\n":118===t?" ":102===t?"\f":114===t?"\r":101===t?"":32===t?" ":34===t?'"':47===t?"/":92===t?"\\":78===t?"…":95===t?" ":76===t?"\u2028":80===t?"\u2029":""}function p(t){return 65535>=t?String.fromCharCode(t):String.fromCharCode((t-65536>>10)+55296,(t-65536&1023)+56320)}function f(t,e){this.input=t,this.filename=e.filename||null,this.schema=e.schema||H,this.onWarning=e.onWarning||null,this.legacy=e.legacy||!1,this.implicitTypes=this.schema.compiledImplicit,this.typeMap=this.schema.compiledTypeMap,this.length=t.length,this.position=0,this.line=0,this.lineStart=0,this.lineIndent=0,this.documents=[]}function h(t,e){return new $(e,new B(t.filename,t.input,t.position,t.line,t.position-t.lineStart))}function d(t,e){throw h(t,e)}function m(t,e){t.onWarning&&t.onWarning.call(null,h(t,e))}function g(t,e,n,i){var r,o,a,s;if(n>e){if(s=t.input.slice(e,n),i)for(r=0,o=s.length;o>r;r+=1)a=s.charCodeAt(r),9===a||a>=32&&1114111>=a||d(t,"expected valid JSON character");else X.test(s)&&d(t,"the stream contains non-printable characters");t.result+=s}}function y(t,e,n){var i,r,o,a;for(P.isObject(n)||d(t,"cannot merge mappings; the provided source object is unacceptable"),i=Object.keys(n),o=0,a=i.length;a>o;o+=1)r=i[o],R.call(e,r)||(e[r]=n[r])}function v(t,e,n,i,r){var o,a;if(i=String(i),null===e&&(e={}),"tag:yaml.org,2002:merge"===n)if(Array.isArray(r))for(o=0,a=r.length;a>o;o+=1)y(t,e,r[o]);else y(t,e,r);else e[i]=r;return e}function x(t){var e;e=t.input.charCodeAt(t.position),10===e?t.position++:13===e?(t.position++,10===t.input.charCodeAt(t.position)&&t.position++):d(t,"a line break is expected"),t.line+=1,t.lineStart=t.position}function A(t,e,n){for(var o=0,a=t.input.charCodeAt(t.position);0!==a;){for(;r(a);)a=t.input.charCodeAt(++t.position);if(e&&35===a)do a=t.input.charCodeAt(++t.position);while(10!==a&&13!==a&&0!==a);if(!i(a))break;for(x(t),a=t.input.charCodeAt(t.position),o++,t.lineIndent=0;32===a;)t.lineIndent++,a=t.input.charCodeAt(++t.position)}return-1!==n&&0!==o&&t.lineIndent<n&&m(t,"deficient indentation"),o}function b(t){var e,n=t.position;return e=t.input.charCodeAt(n),45!==e&&46!==e||t.input.charCodeAt(n+1)!==e||t.input.charCodeAt(n+2)!==e||(n+=3,e=t.input.charCodeAt(n),0!==e&&!o(e))?!1:!0}function w(t,e){1===e?t.result+=" ":e>1&&(t.result+=P.repeat("\n",e-1))}function k(t,e,n){var s,c,u,l,p,f,h,d,m,y=t.kind,v=t.result;if(m=t.input.charCodeAt(t.position),o(m)||a(m)||35===m||38===m||42===m||33===m||124===m||62===m||39===m||34===m||37===m||64===m||96===m)return!1;if((63===m||45===m)&&(c=t.input.charCodeAt(t.position+1),o(c)||n&&a(c)))return!1;for(t.kind="scalar",t.result="",u=l=t.position,p=!1;0!==m;){if(58===m){if(c=t.input.charCodeAt(t.position+1),o(c)||n&&a(c))break}else if(35===m){if(s=t.input.charCodeAt(t.position-1),o(s))break}else{if(t.position===t.lineStart&&b(t)||n&&a(m))break;if(i(m)){if(f=t.line,h=t.lineStart,d=t.lineIndent,A(t,!1,-1),t.lineIndent>=e){p=!0,m=t.input.charCodeAt(t.position);continue}t.position=l,t.line=f,t.lineStart=h,t.lineIndent=d;break}}p&&(g(t,u,l,!1),w(t,t.line-f),u=l=t.position,p=!1),r(m)||(l=t.position+1),m=t.input.charCodeAt(++t.position)}return g(t,u,l,!1),t.result?!0:(t.kind=y,t.result=v,!1)}function C(t,e){var n,r,o;if(n=t.input.charCodeAt(t.position),39!==n)return!1;for(t.kind="scalar",t.result="",t.position++,r=o=t.position;0!==(n=t.input.charCodeAt(t.position));)if(39===n){if(g(t,r,t.position,!0),n=t.input.charCodeAt(++t.position),39!==n)return!0;r=o=t.position,t.position++}else i(n)?(g(t,r,o,!0),w(t,A(t,!1,e)),r=o=t.position):t.position===t.lineStart&&b(t)?d(t,"unexpected end of the document within a single quoted scalar"):(t.position++,o=t.position);d(t,"unexpected end of the stream within a single quoted scalar")}function j(t,e){var n,r,o,a,u,l;if(l=t.input.charCodeAt(t.position),34!==l)return!1;for(t.kind="scalar",t.result="",t.position++,n=r=t.position;0!==(l=t.input.charCodeAt(t.position));){if(34===l)return g(t,n,t.position,!0),t.position++,!0;if(92===l){if(g(t,n,t.position,!0),l=t.input.charCodeAt(++t.position),i(l))A(t,!1,e);else if(256>l&&rt[l])t.result+=ot[l],t.position++;else if((u=c(l))>0){for(o=u,a=0;o>0;o--)l=t.input.charCodeAt(++t.position),(u=s(l))>=0?a=(a<<4)+u:d(t,"expected hexadecimal character");t.result+=p(a),t.position++}else d(t,"unknown escape sequence");n=r=t.position}else i(l)?(g(t,n,r,!0),w(t,A(t,!1,e)),n=r=t.position):t.position===t.lineStart&&b(t)?d(t,"unexpected end of the document within a double quoted scalar"):(t.position++,r=t.position)}d(t,"unexpected end of the stream within a double quoted scalar")}function O(t,e){var n,i,r,a,s,c,u,l,p,f,h,m=!0,g=t.tag,y=t.anchor;if(h=t.input.charCodeAt(t.position),91===h)a=93,u=!1,i=[];else{if(123!==h)return!1;a=125,u=!0,i={}}for(null!==t.anchor&&(t.anchorMap[t.anchor]=i),h=t.input.charCodeAt(++t.position);0!==h;){if(A(t,!0,e),h=t.input.charCodeAt(t.position),h===a)return t.position++,t.tag=g,t.anchor=y,t.kind=u?"mapping":"sequence",t.result=i,!0;m||d(t,"missed comma between flow collection entries"),p=l=f=null,s=c=!1,63===h&&(r=t.input.charCodeAt(t.position+1),o(r)&&(s=c=!0,t.position++,A(t,!0,e))),n=t.line,T(t,e,W,!1,!0),p=t.tag,l=t.result,A(t,!0,e),h=t.input.charCodeAt(t.position),!c&&t.line!==n||58!==h||(s=!0,h=t.input.charCodeAt(++t.position),A(t,!0,e),T(t,e,W,!1,!0),f=t.result),u?v(t,i,p,l,f):i.push(s?v(t,null,p,l,f):l),A(t,!0,e),h=t.input.charCodeAt(t.position),44===h?(m=!0,h=t.input.charCodeAt(++t.position)):m=!1}d(t,"unexpected end of the stream within a flow collection")}function S(t,e){var n,o,a,s,c=z,l=!1,p=e,f=0,h=!1;if(s=t.input.charCodeAt(t.position),124===s)o=!1;else{if(62!==s)return!1;o=!0}for(t.kind="scalar",t.result="";0!==s;)if(s=t.input.charCodeAt(++t.position),43===s||45===s)z===c?c=43===s?Q:J:d(t,"repeat of a chomping mode identifier");else{if(!((a=u(s))>=0))break;0===a?d(t,"bad explicit indentation width of a block scalar; it cannot be less than one"):l?d(t,"repeat of an indentation width identifier"):(p=e+a-1,l=!0)}if(r(s)){do s=t.input.charCodeAt(++t.position);while(r(s));if(35===s)do s=t.input.charCodeAt(++t.position);while(!i(s)&&0!==s)}for(;0!==s;){for(x(t),t.lineIndent=0,s=t.input.charCodeAt(t.position);(!l||t.lineIndent<p)&&32===s;)t.lineIndent++,s=t.input.charCodeAt(++t.position);if(!l&&t.lineIndent>p&&(p=t.lineIndent),i(s))f++;else{if(t.lineIndent<p){c===Q?t.result+=P.repeat("\n",f):c===z&&l&&(t.result+="\n");break}for(o?r(s)?(h=!0,t.result+=P.repeat("\n",f+1)):h?(h=!1,t.result+=P.repeat("\n",f+1)):0===f?l&&(t.result+=" "):t.result+=P.repeat("\n",f):l?t.result+=P.repeat("\n",f+1):t.result+=P.repeat("\n",f),l=!0,f=0,n=t.position;!i(s)&&0!==s;)s=t.input.charCodeAt(++t.position);g(t,n,t.position,!1)}}return!0}function _(t,e){var n,i,r,a=t.tag,s=t.anchor,c=[],u=!1;for(null!==t.anchor&&(t.anchorMap[t.anchor]=c),r=t.input.charCodeAt(t.position);0!==r&&45===r&&(i=t.input.charCodeAt(t.position+1),o(i));)if(u=!0,t.position++,A(t,!0,-1)&&t.lineIndent<=e)c.push(null),r=t.input.charCodeAt(t.position);else if(n=t.line,T(t,e,V,!1,!0),c.push(t.result),A(t,!0,-1),r=t.input.charCodeAt(t.position),(t.line===n||t.lineIndent>e)&&0!==r)d(t,"bad indentation of a sequence entry");else if(t.lineIndent<e)break;return u?(t.tag=a,t.anchor=s,t.kind="sequence",t.result=c,!0):!1}function I(t,e,n){var i,a,s,c,u=t.tag,l=t.anchor,p={},f=null,h=null,m=null,g=!1,y=!1;for(null!==t.anchor&&(t.anchorMap[t.anchor]=p),c=t.input.charCodeAt(t.position);0!==c;){if(i=t.input.charCodeAt(t.position+1),s=t.line,63!==c&&58!==c||!o(i)){if(!T(t,n,G,!1,!0))break;if(t.line===s){for(c=t.input.charCodeAt(t.position);r(c);)c=t.input.charCodeAt(++t.position);if(58===c)c=t.input.charCodeAt(++t.position),o(c)||d(t,"a whitespace character is expected after the key-value separator within a block mapping"),g&&(v(t,p,f,h,null),f=h=m=null),y=!0,g=!1,a=!1,f=t.tag,h=t.result;else{if(!y)return t.tag=u,t.anchor=l,!0;d(t,"can not read an implicit mapping pair; a colon is missed")}}else{if(!y)return t.tag=u,t.anchor=l,!0;d(t,"can not read a block mapping entry; a multiline key may not be an implicit key")}}else 63===c?(g&&(v(t,p,f,h,null),f=h=m=null),y=!0,g=!0,a=!0):g?(g=!1,a=!0):d(t,"incomplete explicit mapping pair; a key node is missed"),t.position+=1,c=i;if((t.line===s||t.lineIndent>e)&&(T(t,e,Z,!0,a)&&(g?h=t.result:m=t.result),g||(v(t,p,f,h,m),f=h=m=null),A(t,!0,-1),c=t.input.charCodeAt(t.position)),t.lineIndent>e&&0!==c)d(t,"bad indentation of a mapping entry");else if(t.lineIndent<e)break}return g&&v(t,p,f,h,null),y&&(t.tag=u,t.anchor=l,t.kind="mapping",t.result=p),y}function E(t){var e,n,i,r,a=!1,s=!1;if(r=t.input.charCodeAt(t.position),33!==r)return!1;if(null!==t.tag&&d(t,"duplication of a tag property"),r=t.input.charCodeAt(++t.position),60===r?(a=!0,r=t.input.charCodeAt(++t.position)):33===r?(s=!0,n="!!",r=t.input.charCodeAt(++t.position)):n="!",e=t.position,a){do r=t.input.charCodeAt(++t.position);while(0!==r&&62!==r);t.position<t.length?(i=t.input.slice(e,t.position),r=t.input.charCodeAt(++t.position)):d(t,"unexpected end of the stream within a verbatim tag")}else{for(;0!==r&&!o(r);)33===r&&(s?d(t,"tag suffix cannot contain exclamation marks"):(n=t.input.slice(e-1,t.position+1),nt.test(n)||d(t,"named tag handle cannot contain such characters"),s=!0,e=t.position+1)),r=t.input.charCodeAt(++t.position);i=t.input.slice(e,t.position),et.test(i)&&d(t,"tag suffix cannot contain flow indicator characters")}return i&&!it.test(i)&&d(t,"tag name cannot contain such characters: "+i),a?t.tag=i:R.call(t.tagMap,n)?t.tag=t.tagMap[n]+i:"!"===n?t.tag="!"+i:"!!"===n?t.tag="tag:yaml.org,2002:"+i:d(t,'undeclared tag handle "'+n+'"'),!0}function F(t){var e,n;if(n=t.input.charCodeAt(t.position),38!==n)return!1;for(null!==t.anchor&&d(t,"duplication of an anchor property"),n=t.input.charCodeAt(++t.position),e=t.position;0!==n&&!o(n)&&!a(n);)n=t.input.charCodeAt(++t.position);return t.position===e&&d(t,"name of an anchor node must contain at least one character"),t.anchor=t.input.slice(e,t.position),!0}function N(t){var e,n,i;if(i=t.input.charCodeAt(t.position),42!==i)return!1;for(i=t.input.charCodeAt(++t.position),e=t.position;0!==i&&!o(i)&&!a(i);)i=t.input.charCodeAt(++t.position);return t.position===e&&d(t,"name of an alias node must contain at least one character"),n=t.input.slice(e,t.position),t.anchorMap.hasOwnProperty(n)||d(t,'unidentified alias "'+n+'"'),t.result=t.anchorMap[n],A(t,!0,-1),!0}function T(t,e,n,i,r){var o,a,s,c,u,l,p,f,h=1,m=!1,g=!1;if(t.tag=null,t.anchor=null,t.kind=null,t.result=null,o=a=s=Z===n||V===n,i&&A(t,!0,-1)&&(m=!0,t.lineIndent>e?h=1:t.lineIndent===e?h=0:t.lineIndent<e&&(h=-1)),1===h)for(;E(t)||F(t);)A(t,!0,-1)?(m=!0,s=o,t.lineIndent>e?h=1:t.lineIndent===e?h=0:t.lineIndent<e&&(h=-1)):s=!1;if(s&&(s=m||r),(1===h||Z===n)&&(p=W===n||G===n?e:e+1,f=t.position-t.lineStart,1===h?s&&(_(t,f)||I(t,f,p))||O(t,p)?g=!0:(a&&S(t,p)||C(t,p)||j(t,p)?g=!0:N(t)?(g=!0,(null!==t.tag||null!==t.anchor)&&d(t,"alias node should not have any properties")):k(t,p,W===n)&&(g=!0,null===t.tag&&(t.tag="?")),null!==t.anchor&&(t.anchorMap[t.anchor]=t.result)):0===h&&(g=s&&_(t,f))),null!==t.tag&&"!"!==t.tag)if("?"===t.tag){for(c=0,u=t.implicitTypes.length;u>c;c+=1)if(l=t.implicitTypes[c],l.resolve(t.result)){t.result=l.construct(t.result),t.tag=l.tag,null!==t.anchor&&(t.anchorMap[t.anchor]=t.result);break}}else R.call(t.typeMap,t.tag)?(l=t.typeMap[t.tag],null!==t.result&&l.kind!==t.kind&&d(t,"unacceptable node kind for !<"+t.tag+'> tag; it should be "'+l.kind+'", not "'+t.kind+'"'),l.resolve(t.result)?(t.result=l.construct(t.result),null!==t.anchor&&(t.anchorMap[t.anchor]=t.result)):d(t,"cannot resolve a node with !<"+t.tag+"> explicit tag")):d(t,"unknown tag !<"+t.tag+">");return null!==t.tag||null!==t.anchor||g}function M(t){var e,n,a,s,c=t.position,u=!1;for(t.version=null,t.checkLineBreaks=t.legacy,t.tagMap={},t.anchorMap={};0!==(s=t.input.charCodeAt(t.position))&&(A(t,!0,-1),s=t.input.charCodeAt(t.position),!(t.lineIndent>0||37!==s));){for(u=!0,s=t.input.charCodeAt(++t.position),e=t.position;0!==s&&!o(s);)s=t.input.charCodeAt(++t.position);for(n=t.input.slice(e,t.position),a=[],n.length<1&&d(t,"directive name must not be less than one character in length");0!==s;){for(;r(s);)s=t.input.charCodeAt(++t.position);if(35===s){do s=t.input.charCodeAt(++t.position);while(0!==s&&!i(s));break}if(i(s))break;for(e=t.position;0!==s&&!o(s);)s=t.input.charCodeAt(++t.position);a.push(t.input.slice(e,t.position))}0!==s&&x(t),R.call(st,n)?st[n](t,n,a):m(t,'unknown document directive "'+n+'"')}return A(t,!0,-1),0===t.lineIndent&&45===t.input.charCodeAt(t.position)&&45===t.input.charCodeAt(t.position+1)&&45===t.input.charCodeAt(t.position+2)?(t.position+=3,A(t,!0,-1)):u&&d(t,"directives end mark is expected"),T(t,t.lineIndent-1,Z,!1,!0),A(t,!0,-1),t.checkLineBreaks&&tt.test(t.input.slice(c,t.position))&&m(t,"non-ASCII line breaks are interpreted as content"),t.documents.push(t.result),t.position===t.lineStart&&b(t)?void(46===t.input.charCodeAt(t.position)&&(t.position+=3,A(t,!0,-1))):void(t.position<t.length-1&&d(t,"end of the stream or a document separator is expected"))}function L(t,e){t=String(t),e=e||{},0!==t.length&&(10!==t.charCodeAt(t.length-1)&&13!==t.charCodeAt(t.length-1)&&(t+="\n"),65279===t.charCodeAt(0)&&(t=t.slice(1)));var n=new f(t,e);for(n.input+="\x00";32===n.input.charCodeAt(n.position);)n.lineIndent+=1,n.position+=1;for(;n.position<n.length-1;)M(n);return n.documents}function D(t,e,n){var i,r,o=L(t,n);for(i=0,r=o.length;r>i;i+=1)e(o[i])}function U(t,e){var n=L(t,e);if(0===n.length)return void 0;if(1===n.length)return n[0];throw new $("expected a single document in the stream, but found more")}function q(t,e,n){D(t,e,P.extend({schema:K},n))}function Y(t,e){return U(t,P.extend({schema:K},e))}for(var P=t("./common"),$=t("./exception"),B=t("./mark"),K=t("./schema/default_safe"),H=t("./schema/default_full"),R=Object.prototype.hasOwnProperty,W=1,G=2,V=3,Z=4,z=1,J=2,Q=3,X=/[\x00-\x08\x0B\x0C\x0E-\x1F\x7F-\x84\x86-\x9F\uFFFE\uFFFF]|[\uD800-\uDBFF](?![\uDC00-\uDFFF])|(?:[^\uD800-\uDBFF]|^)[\uDC00-\uDFFF]/,tt=/[\x85\u2028\u2029]/,et=/[,\[\]\{\}]/,nt=/^(?:!|!!|![a-z\-]+!)$/i,it=/^(?:!|[^,\[\]\{\}])(?:%[0-9a-f]{2}|[0-9a-z\-#;\/\?:@&=\+\$,_\.!~\*'\(\)\[\]])*$/i,rt=new Array(256),ot=new Array(256),at=0;256>at;at++)rt[at]=l(at)?1:0,ot[at]=l(at);var st={YAML:function(t,e,n){var i,r,o;null!==t.version&&d(t,"duplication of %YAML directive"),1!==n.length&&d(t,"YAML directive accepts exactly one argument"),i=/^([0-9]+)\.([0-9]+)$/.exec(n[0]),null===i&&d(t,"ill-formed argument of the YAML directive"),r=parseInt(i[1],10),o=parseInt(i[2],10),1!==r&&d(t,"unacceptable YAML version of the document"),t.version=n[0],t.checkLineBreaks=2>o,1!==o&&2!==o&&m(t,"unsupported YAML version of the document")},TAG:function(t,e,n){var i,r;2!==n.length&&d(t,"TAG directive accepts exactly two arguments"),i=n[0],r=n[1],nt.test(i)||d(t,"ill-formed tag handle (first argument) of the TAG directive"),R.call(t.tagMap,i)&&d(t,'there is a previously declared suffix for "'+i+'" tag handle'),it.test(r)||d(t,"ill-formed tag prefix (second argument) of the TAG directive"),t.tagMap[i]=r}};e.exports.loadAll=D,e.exports.load=U,e.exports.safeLoadAll=q,e.exports.safeLoad=Y},{"./common":2,"./exception":4,"./mark":6,"./schema/default_full":9,"./schema/default_safe":10}],6:[function(t,e,n){"use strict";function i(t,e,n,i,r){this.name=t,this.buffer=e,this.position=n,this.line=i,this.column=r}var r=t("./common");i.prototype.getSnippet=function(t,e){var n,i,o,a,s;if(!this.buffer)return null;for(t=t||4,e=e||75,n="",i=this.position;i>0&&-1==="\x00\r\n…\u2028\u2029".indexOf(this.buffer.charAt(i-1));)if(i-=1,this.position-i>e/2-1){n=" ... ",i+=5;break}for(o="",a=this.position;a<this.buffer.length&&-1==="\x00\r\n…\u2028\u2029".indexOf(this.buffer.charAt(a));)if(a+=1,a-this.position>e/2-1){o=" ... ",a-=5;break}return s=this.buffer.slice(i,a),r.repeat(" ",t)+n+s+o+"\n"+r.repeat(" ",t+this.position-i+n.length)+"^"},i.prototype.toString=function(t){var e,n="";return this.name&&(n+='in "'+this.name+'" '),n+="at line "+(this.line+1)+", column "+(this.column+1),t||(e=this.getSnippet(),e&&(n+=":\n"+e)),n},e.exports=i},{"./common":2}],7:[function(t,e,n){"use strict";function i(t,e,n){var r=[];return t.include.forEach(function(t){n=i(t,e,n)}),t[e].forEach(function(t){n.forEach(function(e,n){e.tag===t.tag&&r.push(n)}),n.push(t)}),n.filter(function(t,e){return-1===r.indexOf(e)})}function r(){function t(t){i[t.tag]=t}var e,n,i={};for(e=0,n=arguments.length;n>e;e+=1)arguments[e].forEach(t);return i}function o(t){this.include=t.include||[],this.implicit=t.implicit||[],this.explicit=t.explicit||[],this.implicit.forEach(function(t){if(t.loadKind&&"scalar"!==t.loadKind)throw new s("There is a non-scalar type in the implicit list of a schema. Implicit resolving of such types is not supported.")}),this.compiledImplicit=i(this,"implicit",[]),this.compiledExplicit=i(this,"explicit",[]),this.compiledTypeMap=r(this.compiledImplicit,this.compiledExplicit)}var a=t("./common"),s=t("./exception"),c=t("./type");o.DEFAULT=null,o.create=function(){var t,e;switch(arguments.length){case 1:t=o.DEFAULT,e=arguments[0];break;case 2:t=arguments[0],e=arguments[1];break;default:throw new s("Wrong number of arguments for Schema.create function")}if(t=a.toArray(t),e=a.toArray(e),!t.every(function(t){return t instanceof o}))throw new s("Specified list of super schemas (or a single Schema object) contains a non-Schema object.");if(!e.every(function(t){return t instanceof c}))throw new s("Specified list of YAML types (or a single Type object) contains a non-Type object.");return new o({include:t,explicit:e})},e.exports=o},{"./common":2,"./exception":4,"./type":13}],8:[function(t,e,n){"use strict";var i=t("../schema");e.exports=new i({include:[t("./json")]})},{"../schema":7,"./json":12}],9:[function(t,e,n){"use strict";var i=t("../schema");e.exports=i.DEFAULT=new i({include:[t("./default_safe")],explicit:[t("../type/js/undefined"),t("../type/js/regexp"),t("../type/js/function")]})},{"../schema":7,"../type/js/function":18,"../type/js/regexp":19,"../type/js/undefined":20,"./default_safe":10}],10:[function(t,e,n){"use strict";var i=t("../schema");e.exports=new i({include:[t("./core")],implicit:[t("../type/timestamp"),t("../type/merge")],explicit:[t("../type/binary"),t("../type/omap"),t("../type/pairs"),t("../type/set")]})},{"../schema":7,"../type/binary":14,"../type/merge":22,"../type/omap":24,"../type/pairs":25,"../type/set":27,"../type/timestamp":29,"./core":8}],11:[function(t,e,n){"use strict";var i=t("../schema");e.exports=new i({explicit:[t("../type/str"),t("../type/seq"),t("../type/map")]})},{"../schema":7,"../type/map":21,"../type/seq":26,"../type/str":28}],12:[function(t,e,n){"use strict";var i=t("../schema");e.exports=new i({include:[t("./failsafe")],implicit:[t("../type/null"),t("../type/bool"),t("../type/int"),t("../type/float")]})},{"../schema":7,"../type/bool":15,"../type/float":16,"../type/int":17,"../type/null":23,"./failsafe":11}],13:[function(t,e,n){"use strict";function i(t){var e={};return null!==t&&Object.keys(t).forEach(function(n){t[n].forEach(function(t){e[String(t)]=n})}),e}function r(t,e){if(e=e||{},Object.keys(e).forEach(function(e){if(-1===a.indexOf(e))throw new o('Unknown option "'+e+'" is met in definition of "'+t+'" YAML type.')}),this.tag=t,this.kind=e.kind||null,this.resolve=e.resolve||function(){return!0},this.construct=e.construct||function(t){return t},this.instanceOf=e.instanceOf||null,this.predicate=e.predicate||null,this.represent=e.represent||null,this.defaultStyle=e.defaultStyle||null,this.styleAliases=i(e.styleAliases||null),-1===s.indexOf(this.kind))throw new o('Unknown kind "'+this.kind+'" is specified for "'+t+'" YAML type.')}var o=t("./exception"),a=["kind","resolve","construct","instanceOf","predicate","represent","defaultStyle","styleAliases"],s=["scalar","sequence","mapping"];e.exports=r},{"./exception":4}],14:[function(t,e,n){"use strict";function i(t){if(null===t)return!1;var e,n,i=0,r=t.length,o=u;for(n=0;r>n;n++)if(e=o.indexOf(t.charAt(n)),!(e>64)){if(0>e)return!1;i+=6}return i%8===0}function r(t){var e,n,i=t.replace(/[\r\n=]/g,""),r=i.length,o=u,a=0,c=[];for(e=0;r>e;e++)e%4===0&&e&&(c.push(a>>16&255),c.push(a>>8&255),c.push(255&a)),a=a<<6|o.indexOf(i.charAt(e));return n=r%4*6,0===n?(c.push(a>>16&255),c.push(a>>8&255),c.push(255&a)):18===n?(c.push(a>>10&255),c.push(a>>2&255)):12===n&&c.push(a>>4&255),s?new s(c):c}function o(t){var e,n,i="",r=0,o=t.length,a=u;for(e=0;o>e;e++)e%3===0&&e&&(i+=a[r>>18&63],i+=a[r>>12&63],i+=a[r>>6&63],i+=a[63&r]),r=(r<<8)+t[e];return n=o%3,0===n?(i+=a[r>>18&63],i+=a[r>>12&63],i+=a[r>>6&63],i+=a[63&r]):2===n?(i+=a[r>>10&63],i+=a[r>>4&63],i+=a[r<<2&63],i+=a[64]):1===n&&(i+=a[r>>2&63],i+=a[r<<4&63],i+=a[64],i+=a[64]),i}function a(t){return s&&s.isBuffer(t)}var s=t("buffer").Buffer,c=t("../type"),u="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=\n\r";e.exports=new c("tag:yaml.org,2002:binary",{kind:"scalar",resolve:i,
-construct:r,predicate:a,represent:o})},{"../type":13,buffer:30}],15:[function(t,e,n){"use strict";function i(t){if(null===t)return!1;var e=t.length;return 4===e&&("true"===t||"True"===t||"TRUE"===t)||5===e&&("false"===t||"False"===t||"FALSE"===t)}function r(t){return"true"===t||"True"===t||"TRUE"===t}function o(t){return"[object Boolean]"===Object.prototype.toString.call(t)}var a=t("../type");e.exports=new a("tag:yaml.org,2002:bool",{kind:"scalar",resolve:i,construct:r,predicate:o,represent:{lowercase:function(t){return t?"true":"false"},uppercase:function(t){return t?"TRUE":"FALSE"},camelcase:function(t){return t?"True":"False"}},defaultStyle:"lowercase"})},{"../type":13}],16:[function(t,e,n){"use strict";function i(t){return null===t?!1:u.test(t)?!0:!1}function r(t){var e,n,i,r;return e=t.replace(/_/g,"").toLowerCase(),n="-"===e[0]?-1:1,r=[],0<="+-".indexOf(e[0])&&(e=e.slice(1)),".inf"===e?1===n?Number.POSITIVE_INFINITY:Number.NEGATIVE_INFINITY:".nan"===e?NaN:0<=e.indexOf(":")?(e.split(":").forEach(function(t){r.unshift(parseFloat(t,10))}),e=0,i=1,r.forEach(function(t){e+=t*i,i*=60}),n*e):n*parseFloat(e,10)}function o(t,e){var n;if(isNaN(t))switch(e){case"lowercase":return".nan";case"uppercase":return".NAN";case"camelcase":return".NaN"}else if(Number.POSITIVE_INFINITY===t)switch(e){case"lowercase":return".inf";case"uppercase":return".INF";case"camelcase":return".Inf"}else if(Number.NEGATIVE_INFINITY===t)switch(e){case"lowercase":return"-.inf";case"uppercase":return"-.INF";case"camelcase":return"-.Inf"}else if(s.isNegativeZero(t))return"-0.0";return n=t.toString(10),l.test(n)?n.replace("e",".e"):n}function a(t){return"[object Number]"===Object.prototype.toString.call(t)&&(0!==t%1||s.isNegativeZero(t))}var s=t("../common"),c=t("../type"),u=new RegExp("^(?:[-+]?(?:[0-9][0-9_]*)\\.[0-9_]*(?:[eE][-+][0-9]+)?|\\.[0-9_]+(?:[eE][-+][0-9]+)?|[-+]?[0-9][0-9_]*(?::[0-5]?[0-9])+\\.[0-9_]*|[-+]?\\.(?:inf|Inf|INF)|\\.(?:nan|NaN|NAN))$"),l=/^[-+]?[0-9]+e/;e.exports=new c("tag:yaml.org,2002:float",{kind:"scalar",resolve:i,construct:r,predicate:a,represent:o,defaultStyle:"lowercase"})},{"../common":2,"../type":13}],17:[function(t,e,n){"use strict";function i(t){return t>=48&&57>=t||t>=65&&70>=t||t>=97&&102>=t}function r(t){return t>=48&&55>=t}function o(t){return t>=48&&57>=t}function a(t){if(null===t)return!1;var e,n=t.length,a=0,s=!1;if(!n)return!1;if(e=t[a],("-"===e||"+"===e)&&(e=t[++a]),"0"===e){if(a+1===n)return!0;if(e=t[++a],"b"===e){for(a++;n>a;a++)if(e=t[a],"_"!==e){if("0"!==e&&"1"!==e)return!1;s=!0}return s}if("x"===e){for(a++;n>a;a++)if(e=t[a],"_"!==e){if(!i(t.charCodeAt(a)))return!1;s=!0}return s}for(;n>a;a++)if(e=t[a],"_"!==e){if(!r(t.charCodeAt(a)))return!1;s=!0}return s}for(;n>a;a++)if(e=t[a],"_"!==e){if(":"===e)break;if(!o(t.charCodeAt(a)))return!1;s=!0}return s?":"!==e?!0:/^(:[0-5]?[0-9])+$/.test(t.slice(a)):!1}function s(t){var e,n,i=t,r=1,o=[];return-1!==i.indexOf("_")&&(i=i.replace(/_/g,"")),e=i[0],("-"===e||"+"===e)&&("-"===e&&(r=-1),i=i.slice(1),e=i[0]),"0"===i?0:"0"===e?"b"===i[1]?r*parseInt(i.slice(2),2):"x"===i[1]?r*parseInt(i,16):r*parseInt(i,8):-1!==i.indexOf(":")?(i.split(":").forEach(function(t){o.unshift(parseInt(t,10))}),i=0,n=1,o.forEach(function(t){i+=t*n,n*=60}),r*i):r*parseInt(i,10)}function c(t){return"[object Number]"===Object.prototype.toString.call(t)&&0===t%1&&!u.isNegativeZero(t)}var u=t("../common"),l=t("../type");e.exports=new l("tag:yaml.org,2002:int",{kind:"scalar",resolve:a,construct:s,predicate:c,represent:{binary:function(t){return"0b"+t.toString(2)},octal:function(t){return"0"+t.toString(8)},decimal:function(t){return t.toString(10)},hexadecimal:function(t){return"0x"+t.toString(16).toUpperCase()}},defaultStyle:"decimal",styleAliases:{binary:[2,"bin"],octal:[8,"oct"],decimal:[10,"dec"],hexadecimal:[16,"hex"]}})},{"../common":2,"../type":13}],18:[function(t,e,n){"use strict";function i(t){if(null===t)return!1;try{var e="("+t+")",n=s.parse(e,{range:!0});return"Program"!==n.type||1!==n.body.length||"ExpressionStatement"!==n.body[0].type||"FunctionExpression"!==n.body[0].expression.type?!1:!0}catch(i){return!1}}function r(t){var e,n="("+t+")",i=s.parse(n,{range:!0}),r=[];if("Program"!==i.type||1!==i.body.length||"ExpressionStatement"!==i.body[0].type||"FunctionExpression"!==i.body[0].expression.type)throw new Error("Failed to resolve function");return i.body[0].expression.params.forEach(function(t){r.push(t.name)}),e=i.body[0].expression.body.range,new Function(r,n.slice(e[0]+1,e[1]-1))}function o(t){return t.toString()}function a(t){return"[object Function]"===Object.prototype.toString.call(t)}var s;try{s=t("esprima")}catch(c){"undefined"!=typeof window&&(s=window.esprima)}var u=t("../../type");e.exports=new u("tag:yaml.org,2002:js/function",{kind:"scalar",resolve:i,construct:r,predicate:a,represent:o})},{"../../type":13,esprima:"esprima"}],19:[function(t,e,n){"use strict";function i(t){if(null===t)return!1;if(0===t.length)return!1;var e=t,n=/\/([gim]*)$/.exec(t),i="";if("/"===e[0]){if(n&&(i=n[1]),i.length>3)return!1;if("/"!==e[e.length-i.length-1])return!1;e=e.slice(1,e.length-i.length-1)}try{return!0}catch(r){return!1}}function r(t){var e=t,n=/\/([gim]*)$/.exec(t),i="";return"/"===e[0]&&(n&&(i=n[1]),e=e.slice(1,e.length-i.length-1)),new RegExp(e,i)}function o(t){var e="/"+t.source+"/";return t.global&&(e+="g"),t.multiline&&(e+="m"),t.ignoreCase&&(e+="i"),e}function a(t){return"[object RegExp]"===Object.prototype.toString.call(t)}var s=t("../../type");e.exports=new s("tag:yaml.org,2002:js/regexp",{kind:"scalar",resolve:i,construct:r,predicate:a,represent:o})},{"../../type":13}],20:[function(t,e,n){"use strict";function i(){return!0}function r(){return void 0}function o(){return""}function a(t){return"undefined"==typeof t}var s=t("../../type");e.exports=new s("tag:yaml.org,2002:js/undefined",{kind:"scalar",resolve:i,construct:r,predicate:a,represent:o})},{"../../type":13}],21:[function(t,e,n){"use strict";var i=t("../type");e.exports=new i("tag:yaml.org,2002:map",{kind:"mapping",construct:function(t){return null!==t?t:{}}})},{"../type":13}],22:[function(t,e,n){"use strict";function i(t){return"<<"===t||null===t}var r=t("../type");e.exports=new r("tag:yaml.org,2002:merge",{kind:"scalar",resolve:i})},{"../type":13}],23:[function(t,e,n){"use strict";function i(t){if(null===t)return!0;var e=t.length;return 1===e&&"~"===t||4===e&&("null"===t||"Null"===t||"NULL"===t)}function r(){return null}function o(t){return null===t}var a=t("../type");e.exports=new a("tag:yaml.org,2002:null",{kind:"scalar",resolve:i,construct:r,predicate:o,represent:{canonical:function(){return"~"},lowercase:function(){return"null"},uppercase:function(){return"NULL"},camelcase:function(){return"Null"}},defaultStyle:"lowercase"})},{"../type":13}],24:[function(t,e,n){"use strict";function i(t){if(null===t)return!0;var e,n,i,r,o,c=[],u=t;for(e=0,n=u.length;n>e;e+=1){if(i=u[e],o=!1,"[object Object]"!==s.call(i))return!1;for(r in i)if(a.call(i,r)){if(o)return!1;o=!0}if(!o)return!1;if(-1!==c.indexOf(r))return!1;c.push(r)}return!0}function r(t){return null!==t?t:[]}var o=t("../type"),a=Object.prototype.hasOwnProperty,s=Object.prototype.toString;e.exports=new o("tag:yaml.org,2002:omap",{kind:"sequence",resolve:i,construct:r})},{"../type":13}],25:[function(t,e,n){"use strict";function i(t){if(null===t)return!0;var e,n,i,r,o,s=t;for(o=new Array(s.length),e=0,n=s.length;n>e;e+=1){if(i=s[e],"[object Object]"!==a.call(i))return!1;if(r=Object.keys(i),1!==r.length)return!1;o[e]=[r[0],i[r[0]]]}return!0}function r(t){if(null===t)return[];var e,n,i,r,o,a=t;for(o=new Array(a.length),e=0,n=a.length;n>e;e+=1)i=a[e],r=Object.keys(i),o[e]=[r[0],i[r[0]]];return o}var o=t("../type"),a=Object.prototype.toString;e.exports=new o("tag:yaml.org,2002:pairs",{kind:"sequence",resolve:i,construct:r})},{"../type":13}],26:[function(t,e,n){"use strict";var i=t("../type");e.exports=new i("tag:yaml.org,2002:seq",{kind:"sequence",construct:function(t){return null!==t?t:[]}})},{"../type":13}],27:[function(t,e,n){"use strict";function i(t){if(null===t)return!0;var e,n=t;for(e in n)if(a.call(n,e)&&null!==n[e])return!1;return!0}function r(t){return null!==t?t:{}}var o=t("../type"),a=Object.prototype.hasOwnProperty;e.exports=new o("tag:yaml.org,2002:set",{kind:"mapping",resolve:i,construct:r})},{"../type":13}],28:[function(t,e,n){"use strict";var i=t("../type");e.exports=new i("tag:yaml.org,2002:str",{kind:"scalar",construct:function(t){return null!==t?t:""}})},{"../type":13}],29:[function(t,e,n){"use strict";function i(t){return null===t?!1:null===s.exec(t)?!1:!0}function r(t){var e,n,i,r,o,a,c,u,l,p,f=0,h=null;if(e=s.exec(t),null===e)throw new Error("Date resolve error");if(n=+e[1],i=+e[2]-1,r=+e[3],!e[4])return new Date(Date.UTC(n,i,r));if(o=+e[4],a=+e[5],c=+e[6],e[7]){for(f=e[7].slice(0,3);f.length<3;)f+="0";f=+f}return e[9]&&(u=+e[10],l=+(e[11]||0),h=6e4*(60*u+l),"-"===e[9]&&(h=-h)),p=new Date(Date.UTC(n,i,r,o,a,c,f)),h&&p.setTime(p.getTime()-h),p}function o(t){return t.toISOString()}var a=t("../type"),s=new RegExp("^([0-9][0-9][0-9][0-9])-([0-9][0-9]?)-([0-9][0-9]?)(?:(?:[Tt]|[ \\t]+)([0-9][0-9]?):([0-9][0-9]):([0-9][0-9])(?:\\.([0-9]*))?(?:[ \\t]*(Z|([-+])([0-9][0-9]?)(?::([0-9][0-9]))?))?)?$");e.exports=new a("tag:yaml.org,2002:timestamp",{kind:"scalar",resolve:i,construct:r,instanceOf:Date,represent:o})},{"../type":13}],30:[function(t,e,n){},{}],31:[function(t,e,n){e.exports=t("./lib/inherit")},{"./lib/inherit":32}],32:[function(e,n,i){!function(e){function r(t){var e=f(t);if(v)for(var n,i=0;n=b[i++];)t.hasOwnProperty(n)&&e.push(n);return e}function o(t,e,n){for(var i,o,a=r(n),s=0,u=a.length;u>s;)"__self"!==(i=a[s++])&&(o=n[i],g(o)&&(!c||o.toString().indexOf(".__base")>-1)?e[i]=function(n,i){var r=t[n]?t[n]:"__constructor"===n?e.__self.__parent:y;return function(){var t=this.__base;this.__base=r;var e=i.apply(this,arguments);return this.__base=t,e}}(i,o):e[i]=o)}function a(t,e){for(var n,i=1;n=t[i++];)e?g(n)?s.self(e,n.prototype,n):s.self(e,n):e=g(n)?s(t[0],n.prototype,n):s(t[0],n);return e||t[0]}function s(){var t=arguments,e=m(t[0]),n=e||g(t[0]),i=n?e?a(t[0]):t[0]:u,r=t[n?1:0]||{},s=t[n?2:1],c=r.__constructor||n&&i.prototype.__constructor?function(){return this.__constructor.apply(this,arguments)}:n?function(){return i.apply(this,arguments)}:function(){};if(!n)return c.prototype=r,c.prototype.__self=c.prototype.constructor=c,h(c,s);h(c,i),c.__parent=i;var l=i.prototype,f=c.prototype=p(l);return f.__self=f.constructor=c,r&&o(l,f,r),s&&o(i,c,s),c}var c=function(){"_"}.toString().indexOf("_")>-1,u=function(){},l=Object.prototype.hasOwnProperty,p=Object.create||function(t){var e=function(){};return e.prototype=t,new e},f=Object.keys||function(t){var e=[];for(var n in t)l.call(t,n)&&e.push(n);return e},h=function(t,e){for(var n in e)l.call(e,n)&&(t[n]=e[n]);return t},d=Object.prototype.toString,m=Array.isArray||function(t){return"[object Array]"===d.call(t)},g=function(t){return"[object Function]"===d.call(t)},y=function(){},v=!0,x={toString:""};for(var A in x)x.hasOwnProperty(A)&&(v=!1);var b=v?["toString","valueOf"]:null;s.self=function(){var t=arguments,e=m(t[0]),n=e?a(t[0],t[0][0]):t[0],i=t[1],r=t[2],s=n.prototype;return i&&o(s,s,i),r&&o(n,n,r),n};var w=!0;"object"==typeof i&&(n.exports=s,w=!1),"object"==typeof modules&&(modules.define("inherit",function(t){t(s)}),w=!1),"function"==typeof t&&(t(function(t,e,n){n.exports=s}),w=!1),w&&(e.inherit=s)}(this)},{}],"/":[function(t,e,n){"use strict";var i=t("./lib/js-yaml.js");e.exports=i},{"./lib/js-yaml.js":1}]},{},[])("/")});
+/* js-yaml 3.4.6 https://github.com/nodeca/js-yaml */
+!function(t){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=t();else if("function"==typeof define&&define.amd)define([],t);else{var e;e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:this,e.jsyaml=t()}}(function(){var t;return function e(t,n,i){function r(a,s){if(!n[a]){if(!t[a]){var c="function"==typeof require&&require;if(!s&&c)return c(a,!0);if(o)return o(a,!0);var u=new Error("Cannot find module '"+a+"'");throw u.code="MODULE_NOT_FOUND",u}var l=n[a]={exports:{}};t[a][0].call(l.exports,function(e){var n=t[a][1][e];return r(n?n:e)},l,l.exports,e,t,n,i)}return n[a].exports}for(var o="function"==typeof require&&require,a=0;a<i.length;a++)r(i[a]);return r}({1:[function(t,e,n){"use strict";function i(t){return function(){throw new Error("Function "+t+" is deprecated and cannot be used.")}}var r=t("./js-yaml/loader"),o=t("./js-yaml/dumper");e.exports.Type=t("./js-yaml/type"),e.exports.Schema=t("./js-yaml/schema"),e.exports.FAILSAFE_SCHEMA=t("./js-yaml/schema/failsafe"),e.exports.JSON_SCHEMA=t("./js-yaml/schema/json"),e.exports.CORE_SCHEMA=t("./js-yaml/schema/core"),e.exports.DEFAULT_SAFE_SCHEMA=t("./js-yaml/schema/default_safe"),e.exports.DEFAULT_FULL_SCHEMA=t("./js-yaml/schema/default_full"),e.exports.load=r.load,e.exports.loadAll=r.loadAll,e.exports.safeLoad=r.safeLoad,e.exports.safeLoadAll=r.safeLoadAll,e.exports.dump=o.dump,e.exports.safeDump=o.safeDump,e.exports.YAMLException=t("./js-yaml/exception"),e.exports.MINIMAL_SCHEMA=t("./js-yaml/schema/failsafe"),e.exports.SAFE_SCHEMA=t("./js-yaml/schema/default_safe"),e.exports.DEFAULT_SCHEMA=t("./js-yaml/schema/default_full"),e.exports.scan=i("scan"),e.exports.parse=i("parse"),e.exports.compose=i("compose"),e.exports.addConstructor=i("addConstructor")},{"./js-yaml/dumper":3,"./js-yaml/exception":4,"./js-yaml/loader":5,"./js-yaml/schema":7,"./js-yaml/schema/core":8,"./js-yaml/schema/default_full":9,"./js-yaml/schema/default_safe":10,"./js-yaml/schema/failsafe":11,"./js-yaml/schema/json":12,"./js-yaml/type":13}],2:[function(t,e,n){"use strict";function i(t){return"undefined"==typeof t||null===t}function r(t){return"object"==typeof t&&null!==t}function o(t){return Array.isArray(t)?t:i(t)?[]:[t]}function a(t,e){var n,i,r,o;if(e)for(o=Object.keys(e),n=0,i=o.length;i>n;n+=1)r=o[n],t[r]=e[r];return t}function s(t,e){var n,i="";for(n=0;e>n;n+=1)i+=t;return i}function c(t){return 0===t&&Number.NEGATIVE_INFINITY===1/t}e.exports.isNothing=i,e.exports.isObject=r,e.exports.toArray=o,e.exports.repeat=s,e.exports.isNegativeZero=c,e.exports.extend=a},{}],3:[function(t,e,n){"use strict";function i(t,e){var n,i,r,o,a,s,c;if(null===e)return{};for(n={},i=Object.keys(e),r=0,o=i.length;o>r;r+=1)a=i[r],s=String(e[a]),"!!"===a.slice(0,2)&&(a="tag:yaml.org,2002:"+a.slice(2)),c=t.compiledTypeMap[a],c&&E.call(c.styleAliases,s)&&(s=c.styleAliases[s]),n[a]=s;return n}function r(t){var e,n,i;if(e=t.toString(16).toUpperCase(),255>=t)n="x",i=2;else if(65535>=t)n="u",i=4;else{if(!(4294967295>=t))throw new O("code point within a string may not be greater than 0xFFFFFFFF");n="U",i=8}return"\\"+n+j.repeat("0",i-e.length)+e}function o(t){this.schema=t.schema||S,this.indent=Math.max(1,t.indent||2),this.skipInvalid=t.skipInvalid||!1,this.flowLevel=j.isNothing(t.flowLevel)?-1:t.flowLevel,this.styleMap=i(this.schema,t.styles||null),this.sortKeys=t.sortKeys||!1,this.lineWidth=t.lineWidth||80,this.implicitTypes=this.schema.compiledImplicit,this.explicitTypes=this.schema.compiledExplicit,this.tag=null,this.result="",this.duplicates=[],this.usedDuplicates=null}function a(t,e){for(var n,i=j.repeat(" ",e),r=0,o=-1,a="",s=t.length;s>r;)o=t.indexOf("\n",r),-1===o?(n=t.slice(r),r=s):(n=t.slice(r,o+1),r=o+1),n.length&&"\n"!==n&&(a+=i),a+=n;return a}function s(t,e){return"\n"+j.repeat(" ",t.indent*e)}function c(t,e){var n,i,r;for(n=0,i=t.implicitTypes.length;i>n;n+=1)if(r=t.implicitTypes[n],r.resolve(e))return!0;return!1}function u(t){this.source=t,this.result="",this.checkpoint=0}function l(t,e,n,i){var r,o,s,l,f,m,g,y,v,x,A,b,w,k,C,j,O,S,_,I,E;if(0===e.length)return void(t.dump="''");if(-1!==et.indexOf(e))return void(t.dump="'"+e+"'");for(r=!0,o=e.length?e.charCodeAt(0):0,s=M===o||M===e.charCodeAt(e.length-1),(K===o||W===o||G===o||z===o)&&(r=!1),s?(r=!1,l=!1,f=!1):(l=!i,f=!i),m=!0,g=new u(e),y=!1,v=0,x=0,A=t.indent*n,b=t.lineWidth,-1===b&&(b=9007199254740991),40>A?b-=A:b=40,k=0;k<e.length;k++){if(w=e.charCodeAt(k),r){if(h(w))continue;r=!1}m&&w===P&&(m=!1),C=tt[w],j=d(w),(C||j)&&(w!==N&&w!==D&&w!==P?(l=!1,f=!1):w===N&&(y=!0,m=!1,k>0&&(O=e.charCodeAt(k-1),O===M&&(f=!1,l=!1)),l&&(S=k-v,v=k,S>x&&(x=S))),w!==D&&(m=!1),g.takeUpTo(k),g.escapeChar())}if(r&&c(t,e)&&(r=!1),_="",(l||f)&&(I=0,e.charCodeAt(e.length-1)===N&&(I+=1,e.charCodeAt(e.length-2)===N&&(I+=1)),0===I?_="-":2===I&&(_="+")),f&&b>x&&(l=!1),y||(f=!1),r)t.dump=e;else if(m)t.dump="'"+e+"'";else if(l)E=p(e,b),t.dump=">"+_+"\n"+a(E,A);else if(f)_||(e=e.replace(/\n$/,"")),t.dump="|"+_+"\n"+a(e,A);else{if(!g)throw new Error("Failed to dump scalar value");g.finish(),t.dump='"'+g.result+'"'}}function p(t,e){var n,i="",r=0,o=t.length,a=/\n+$/.exec(t);for(a&&(o=a.index+1);o>r;)n=t.indexOf("\n",r),n>o||-1===n?(i&&(i+="\n\n"),i+=f(t.slice(r,o),e),r=o):(i&&(i+="\n\n"),i+=f(t.slice(r,n),e),r=n+1);return a&&"\n"!==a[0]&&(i+=a[0]),i}function f(t,e){if(""===t)return t;for(var n,i,r,o=/[^\s] [^\s]/g,a="",s=0,c=0,u=o.exec(t);u;)n=u.index,n-c>e&&(i=s!==c?s:n,a&&(a+="\n"),r=t.slice(c,i),a+=r,c=i+1),s=n+1,u=o.exec(t);return a&&(a+="\n"),a+=c!==s&&t.length-c>e?t.slice(c,s)+"\n"+t.slice(s+1):t.slice(c)}function h(t){return F!==t&&N!==t&&T!==t&&B!==t&&V!==t&&Z!==t&&J!==t&&X!==t&&U!==t&&Y!==t&&$!==t&&L!==t&&Q!==t&&R!==t&&P!==t&&D!==t&&q!==t&&H!==t&&!tt[t]&&!d(t)}function d(t){return!(t>=32&&126>=t||133===t||t>=160&&55295>=t||t>=57344&&65533>=t||t>=65536&&1114111>=t)}function m(t,e,n){var i,r,o="",a=t.tag;for(i=0,r=n.length;r>i;i+=1)A(t,e,n[i],!1,!1)&&(0!==i&&(o+=", "),o+=t.dump);t.tag=a,t.dump="["+o+"]"}function g(t,e,n,i){var r,o,a="",c=t.tag;for(r=0,o=n.length;o>r;r+=1)A(t,e+1,n[r],!0,!0)&&(i&&0===r||(a+=s(t,e)),a+="- "+t.dump);t.tag=c,t.dump=a||"[]"}function y(t,e,n){var i,r,o,a,s,c="",u=t.tag,l=Object.keys(n);for(i=0,r=l.length;r>i;i+=1)s="",0!==i&&(s+=", "),o=l[i],a=n[o],A(t,e,o,!1,!1)&&(t.dump.length>1024&&(s+="? "),s+=t.dump+": ",A(t,e,a,!1,!1)&&(s+=t.dump,c+=s));t.tag=u,t.dump="{"+c+"}"}function v(t,e,n,i){var r,o,a,c,u,l,p="",f=t.tag,h=Object.keys(n);if(t.sortKeys===!0)h.sort();else if("function"==typeof t.sortKeys)h.sort(t.sortKeys);else if(t.sortKeys)throw new O("sortKeys must be a boolean or a function");for(r=0,o=h.length;o>r;r+=1)l="",i&&0===r||(l+=s(t,e)),a=h[r],c=n[a],A(t,e+1,a,!0,!0,!0)&&(u=null!==t.tag&&"?"!==t.tag||t.dump&&t.dump.length>1024,u&&(l+=t.dump&&N===t.dump.charCodeAt(0)?"?":"? "),l+=t.dump,u&&(l+=s(t,e)),A(t,e+1,c,!0,u)&&(l+=t.dump&&N===t.dump.charCodeAt(0)?":":": ",l+=t.dump,p+=l));t.tag=f,t.dump=p||"{}"}function x(t,e,n){var i,r,o,a,s,c;for(r=n?t.explicitTypes:t.implicitTypes,o=0,a=r.length;a>o;o+=1)if(s=r[o],(s.instanceOf||s.predicate)&&(!s.instanceOf||"object"==typeof e&&e instanceof s.instanceOf)&&(!s.predicate||s.predicate(e))){if(t.tag=n?s.tag:"?",s.represent){if(c=t.styleMap[s.tag]||s.defaultStyle,"[object Function]"===I.call(s.represent))i=s.represent(e,c);else{if(!E.call(s.represent,c))throw new O("!<"+s.tag+'> tag resolver accepts not "'+c+'" style');i=s.represent[c](e,c)}t.dump=i}return!0}return!1}function A(t,e,n,i,r,o){t.tag=null,t.dump=n,x(t,n,!1)||x(t,n,!0);var a=I.call(t.dump);i&&(i=0>t.flowLevel||t.flowLevel>e);var s,c,u="[object Object]"===a||"[object Array]"===a;if(u&&(s=t.duplicates.indexOf(n),c=-1!==s),(null!==t.tag&&"?"!==t.tag||c||2!==t.indent&&e>0)&&(r=!1),c&&t.usedDuplicates[s])t.dump="*ref_"+s;else{if(u&&c&&!t.usedDuplicates[s]&&(t.usedDuplicates[s]=!0),"[object Object]"===a)i&&0!==Object.keys(t.dump).length?(v(t,e,t.dump,r),c&&(t.dump="&ref_"+s+t.dump)):(y(t,e,t.dump),c&&(t.dump="&ref_"+s+" "+t.dump));else if("[object Array]"===a)i&&0!==t.dump.length?(g(t,e,t.dump,r),c&&(t.dump="&ref_"+s+t.dump)):(m(t,e,t.dump),c&&(t.dump="&ref_"+s+" "+t.dump));else{if("[object String]"!==a){if(t.skipInvalid)return!1;throw new O("unacceptable kind of an object to dump "+a)}"?"!==t.tag&&l(t,t.dump,e,o)}null!==t.tag&&"?"!==t.tag&&(t.dump="!<"+t.tag+"> "+t.dump)}return!0}function b(t,e){var n,i,r=[],o=[];for(w(t,r,o),n=0,i=o.length;i>n;n+=1)e.duplicates.push(r[o[n]]);e.usedDuplicates=new Array(i)}function w(t,e,n){var i,r,o;if(null!==t&&"object"==typeof t)if(r=e.indexOf(t),-1!==r)-1===n.indexOf(r)&&n.push(r);else if(e.push(t),Array.isArray(t))for(r=0,o=t.length;o>r;r+=1)w(t[r],e,n);else for(i=Object.keys(t),r=0,o=i.length;o>r;r+=1)w(t[i[r]],e,n)}function k(t,e){e=e||{};var n=new o(e);return b(t,n),A(n,0,t,!0,!0)?n.dump+"\n":""}function C(t,e){return k(t,j.extend({schema:_},e))}var j=t("./common"),O=t("./exception"),S=t("./schema/default_full"),_=t("./schema/default_safe"),I=Object.prototype.toString,E=Object.prototype.hasOwnProperty,F=9,N=10,T=13,M=32,L=33,D=34,U=35,q=37,Y=38,P=39,$=42,B=44,K=45,H=58,R=62,W=63,G=64,V=91,Z=93,z=96,J=123,Q=124,X=125,tt={};tt[0]="\\0",tt[7]="\\a",tt[8]="\\b",tt[9]="\\t",tt[10]="\\n",tt[11]="\\v",tt[12]="\\f",tt[13]="\\r",tt[27]="\\e",tt[34]='\\"',tt[92]="\\\\",tt[133]="\\N",tt[160]="\\_",tt[8232]="\\L",tt[8233]="\\P";var et=["y","Y","yes","Yes","YES","on","On","ON","n","N","no","No","NO","off","Off","OFF"];u.prototype.takeUpTo=function(t){var e;if(t<this.checkpoint)throw e=new Error("position should be > checkpoint"),e.position=t,e.checkpoint=this.checkpoint,e;return this.result+=this.source.slice(this.checkpoint,t),this.checkpoint=t,this},u.prototype.escapeChar=function(){var t,e;return t=this.source.charCodeAt(this.checkpoint),e=tt[t]||r(t),this.result+=e,this.checkpoint+=1,this},u.prototype.finish=function(){this.source.length>this.checkpoint&&this.takeUpTo(this.source.length)},e.exports.dump=k,e.exports.safeDump=C},{"./common":2,"./exception":4,"./schema/default_full":9,"./schema/default_safe":10}],4:[function(t,e,n){"use strict";function i(t,e){Error.call(this),Error.captureStackTrace?Error.captureStackTrace(this,this.constructor):this.stack=(new Error).stack||"",this.name="YAMLException",this.reason=t,this.mark=e,this.message=(this.reason||"(unknown reason)")+(this.mark?" "+this.mark.toString():"")}var r=t("inherit");r(i,Error),i.prototype.toString=function(t){var e=this.name+": ";return e+=this.reason||"(unknown reason)",!t&&this.mark&&(e+=" "+this.mark.toString()),e},e.exports=i},{inherit:31}],5:[function(t,e,n){"use strict";function i(t){return 10===t||13===t}function r(t){return 9===t||32===t}function o(t){return 9===t||32===t||10===t||13===t}function a(t){return 44===t||91===t||93===t||123===t||125===t}function s(t){var e;return t>=48&&57>=t?t-48:(e=32|t,e>=97&&102>=e?e-97+10:-1)}function c(t){return 120===t?2:117===t?4:85===t?8:0}function u(t){return t>=48&&57>=t?t-48:-1}function l(t){return 48===t?"\x00":97===t?"":98===t?"\b":116===t?" ":9===t?" ":110===t?"\n":118===t?" ":102===t?"\f":114===t?"\r":101===t?"":32===t?" ":34===t?'"':47===t?"/":92===t?"\\":78===t?"…":95===t?" ":76===t?"\u2028":80===t?"\u2029":""}function p(t){return 65535>=t?String.fromCharCode(t):String.fromCharCode((t-65536>>10)+55296,(t-65536&1023)+56320)}function f(t,e){this.input=t,this.filename=e.filename||null,this.schema=e.schema||H,this.onWarning=e.onWarning||null,this.legacy=e.legacy||!1,this.implicitTypes=this.schema.compiledImplicit,this.typeMap=this.schema.compiledTypeMap,this.length=t.length,this.position=0,this.line=0,this.lineStart=0,this.lineIndent=0,this.documents=[]}function h(t,e){return new $(e,new B(t.filename,t.input,t.position,t.line,t.position-t.lineStart))}function d(t,e){throw h(t,e)}function m(t,e){t.onWarning&&t.onWarning.call(null,h(t,e))}function g(t,e,n,i){var r,o,a,s;if(n>e){if(s=t.input.slice(e,n),i)for(r=0,o=s.length;o>r;r+=1)a=s.charCodeAt(r),9===a||a>=32&&1114111>=a||d(t,"expected valid JSON character");else X.test(s)&&d(t,"the stream contains non-printable characters");t.result+=s}}function y(t,e,n){var i,r,o,a;for(P.isObject(n)||d(t,"cannot merge mappings; the provided source object is unacceptable"),i=Object.keys(n),o=0,a=i.length;a>o;o+=1)r=i[o],R.call(e,r)||(e[r]=n[r])}function v(t,e,n,i,r){var o,a;if(i=String(i),null===e&&(e={}),"tag:yaml.org,2002:merge"===n)if(Array.isArray(r))for(o=0,a=r.length;a>o;o+=1)y(t,e,r[o]);else y(t,e,r);else e[i]=r;return e}function x(t){var e;e=t.input.charCodeAt(t.position),10===e?t.position++:13===e?(t.position++,10===t.input.charCodeAt(t.position)&&t.position++):d(t,"a line break is expected"),t.line+=1,t.lineStart=t.position}function A(t,e,n){for(var o=0,a=t.input.charCodeAt(t.position);0!==a;){for(;r(a);)a=t.input.charCodeAt(++t.position);if(e&&35===a)do a=t.input.charCodeAt(++t.position);while(10!==a&&13!==a&&0!==a);if(!i(a))break;for(x(t),a=t.input.charCodeAt(t.position),o++,t.lineIndent=0;32===a;)t.lineIndent++,a=t.input.charCodeAt(++t.position)}return-1!==n&&0!==o&&t.lineIndent<n&&m(t,"deficient indentation"),o}function b(t){var e,n=t.position;return e=t.input.charCodeAt(n),45!==e&&46!==e||t.input.charCodeAt(n+1)!==e||t.input.charCodeAt(n+2)!==e||(n+=3,e=t.input.charCodeAt(n),0!==e&&!o(e))?!1:!0}function w(t,e){1===e?t.result+=" ":e>1&&(t.result+=P.repeat("\n",e-1))}function k(t,e,n){var s,c,u,l,p,f,h,d,m,y=t.kind,v=t.result;if(m=t.input.charCodeAt(t.position),o(m)||a(m)||35===m||38===m||42===m||33===m||124===m||62===m||39===m||34===m||37===m||64===m||96===m)return!1;if((63===m||45===m)&&(c=t.input.charCodeAt(t.position+1),o(c)||n&&a(c)))return!1;for(t.kind="scalar",t.result="",u=l=t.position,p=!1;0!==m;){if(58===m){if(c=t.input.charCodeAt(t.position+1),o(c)||n&&a(c))break}else if(35===m){if(s=t.input.charCodeAt(t.position-1),o(s))break}else{if(t.position===t.lineStart&&b(t)||n&&a(m))break;if(i(m)){if(f=t.line,h=t.lineStart,d=t.lineIndent,A(t,!1,-1),t.lineIndent>=e){p=!0,m=t.input.charCodeAt(t.position);continue}t.position=l,t.line=f,t.lineStart=h,t.lineIndent=d;break}}p&&(g(t,u,l,!1),w(t,t.line-f),u=l=t.position,p=!1),r(m)||(l=t.position+1),m=t.input.charCodeAt(++t.position)}return g(t,u,l,!1),t.result?!0:(t.kind=y,t.result=v,!1)}function C(t,e){var n,r,o;if(n=t.input.charCodeAt(t.position),39!==n)return!1;for(t.kind="scalar",t.result="",t.position++,r=o=t.position;0!==(n=t.input.charCodeAt(t.position));)if(39===n){if(g(t,r,t.position,!0),n=t.input.charCodeAt(++t.position),39!==n)return!0;r=o=t.position,t.position++}else i(n)?(g(t,r,o,!0),w(t,A(t,!1,e)),r=o=t.position):t.position===t.lineStart&&b(t)?d(t,"unexpected end of the document within a single quoted scalar"):(t.position++,o=t.position);d(t,"unexpected end of the stream within a single quoted scalar")}function j(t,e){var n,r,o,a,u,l;if(l=t.input.charCodeAt(t.position),34!==l)return!1;for(t.kind="scalar",t.result="",t.position++,n=r=t.position;0!==(l=t.input.charCodeAt(t.position));){if(34===l)return g(t,n,t.position,!0),t.position++,!0;if(92===l){if(g(t,n,t.position,!0),l=t.input.charCodeAt(++t.position),i(l))A(t,!1,e);else if(256>l&&rt[l])t.result+=ot[l],t.position++;else if((u=c(l))>0){for(o=u,a=0;o>0;o--)l=t.input.charCodeAt(++t.position),(u=s(l))>=0?a=(a<<4)+u:d(t,"expected hexadecimal character");t.result+=p(a),t.position++}else d(t,"unknown escape sequence");n=r=t.position}else i(l)?(g(t,n,r,!0),w(t,A(t,!1,e)),n=r=t.position):t.position===t.lineStart&&b(t)?d(t,"unexpected end of the document within a double quoted scalar"):(t.position++,r=t.position)}d(t,"unexpected end of the stream within a double quoted scalar")}function O(t,e){var n,i,r,a,s,c,u,l,p,f,h,m=!0,g=t.tag,y=t.anchor;if(h=t.input.charCodeAt(t.position),91===h)a=93,u=!1,i=[];else{if(123!==h)return!1;a=125,u=!0,i={}}for(null!==t.anchor&&(t.anchorMap[t.anchor]=i),h=t.input.charCodeAt(++t.position);0!==h;){if(A(t,!0,e),h=t.input.charCodeAt(t.position),h===a)return t.position++,t.tag=g,t.anchor=y,t.kind=u?"mapping":"sequence",t.result=i,!0;m||d(t,"missed comma between flow collection entries"),p=l=f=null,s=c=!1,63===h&&(r=t.input.charCodeAt(t.position+1),o(r)&&(s=c=!0,t.position++,A(t,!0,e))),n=t.line,T(t,e,W,!1,!0),p=t.tag,l=t.result,A(t,!0,e),h=t.input.charCodeAt(t.position),!c&&t.line!==n||58!==h||(s=!0,h=t.input.charCodeAt(++t.position),A(t,!0,e),T(t,e,W,!1,!0),f=t.result),u?v(t,i,p,l,f):i.push(s?v(t,null,p,l,f):l),A(t,!0,e),h=t.input.charCodeAt(t.position),44===h?(m=!0,h=t.input.charCodeAt(++t.position)):m=!1}d(t,"unexpected end of the stream within a flow collection")}function S(t,e){var n,o,a,s,c=z,l=!1,p=e,f=0,h=!1;if(s=t.input.charCodeAt(t.position),124===s)o=!1;else{if(62!==s)return!1;o=!0}for(t.kind="scalar",t.result="";0!==s;)if(s=t.input.charCodeAt(++t.position),43===s||45===s)z===c?c=43===s?Q:J:d(t,"repeat of a chomping mode identifier");else{if(!((a=u(s))>=0))break;0===a?d(t,"bad explicit indentation width of a block scalar; it cannot be less than one"):l?d(t,"repeat of an indentation width identifier"):(p=e+a-1,l=!0)}if(r(s)){do s=t.input.charCodeAt(++t.position);while(r(s));if(35===s)do s=t.input.charCodeAt(++t.position);while(!i(s)&&0!==s)}for(;0!==s;){for(x(t),t.lineIndent=0,s=t.input.charCodeAt(t.position);(!l||t.lineIndent<p)&&32===s;)t.lineIndent++,s=t.input.charCodeAt(++t.position);if(!l&&t.lineIndent>p&&(p=t.lineIndent),i(s))f++;else{if(t.lineIndent<p){c===Q?t.result+=P.repeat("\n",f):c===z&&l&&(t.result+="\n");break}for(o?r(s)?(h=!0,t.result+=P.repeat("\n",f+1)):h?(h=!1,t.result+=P.repeat("\n",f+1)):0===f?l&&(t.result+=" "):t.result+=P.repeat("\n",f):l?t.result+=P.repeat("\n",f+1):t.result+=P.repeat("\n",f),l=!0,f=0,n=t.position;!i(s)&&0!==s;)s=t.input.charCodeAt(++t.position);g(t,n,t.position,!1)}}return!0}function _(t,e){var n,i,r,a=t.tag,s=t.anchor,c=[],u=!1;for(null!==t.anchor&&(t.anchorMap[t.anchor]=c),r=t.input.charCodeAt(t.position);0!==r&&45===r&&(i=t.input.charCodeAt(t.position+1),o(i));)if(u=!0,t.position++,A(t,!0,-1)&&t.lineIndent<=e)c.push(null),r=t.input.charCodeAt(t.position);else if(n=t.line,T(t,e,V,!1,!0),c.push(t.result),A(t,!0,-1),r=t.input.charCodeAt(t.position),(t.line===n||t.lineIndent>e)&&0!==r)d(t,"bad indentation of a sequence entry");else if(t.lineIndent<e)break;return u?(t.tag=a,t.anchor=s,t.kind="sequence",t.result=c,!0):!1}function I(t,e,n){var i,a,s,c,u=t.tag,l=t.anchor,p={},f=null,h=null,m=null,g=!1,y=!1;for(null!==t.anchor&&(t.anchorMap[t.anchor]=p),c=t.input.charCodeAt(t.position);0!==c;){if(i=t.input.charCodeAt(t.position+1),s=t.line,63!==c&&58!==c||!o(i)){if(!T(t,n,G,!1,!0))break;if(t.line===s){for(c=t.input.charCodeAt(t.position);r(c);)c=t.input.charCodeAt(++t.position);if(58===c)c=t.input.charCodeAt(++t.position),o(c)||d(t,"a whitespace character is expected after the key-value separator within a block mapping"),g&&(v(t,p,f,h,null),f=h=m=null),y=!0,g=!1,a=!1,f=t.tag,h=t.result;else{if(!y)return t.tag=u,t.anchor=l,!0;d(t,"can not read an implicit mapping pair; a colon is missed")}}else{if(!y)return t.tag=u,t.anchor=l,!0;d(t,"can not read a block mapping entry; a multiline key may not be an implicit key")}}else 63===c?(g&&(v(t,p,f,h,null),f=h=m=null),y=!0,g=!0,a=!0):g?(g=!1,a=!0):d(t,"incomplete explicit mapping pair; a key node is missed"),t.position+=1,c=i;if((t.line===s||t.lineIndent>e)&&(T(t,e,Z,!0,a)&&(g?h=t.result:m=t.result),g||(v(t,p,f,h,m),f=h=m=null),A(t,!0,-1),c=t.input.charCodeAt(t.position)),t.lineIndent>e&&0!==c)d(t,"bad indentation of a mapping entry");else if(t.lineIndent<e)break}return g&&v(t,p,f,h,null),y&&(t.tag=u,t.anchor=l,t.kind="mapping",t.result=p),y}function E(t){var e,n,i,r,a=!1,s=!1;if(r=t.input.charCodeAt(t.position),33!==r)return!1;if(null!==t.tag&&d(t,"duplication of a tag property"),r=t.input.charCodeAt(++t.position),60===r?(a=!0,r=t.input.charCodeAt(++t.position)):33===r?(s=!0,n="!!",r=t.input.charCodeAt(++t.position)):n="!",e=t.position,a){do r=t.input.charCodeAt(++t.position);while(0!==r&&62!==r);t.position<t.length?(i=t.input.slice(e,t.position),r=t.input.charCodeAt(++t.position)):d(t,"unexpected end of the stream within a verbatim tag")}else{for(;0!==r&&!o(r);)33===r&&(s?d(t,"tag suffix cannot contain exclamation marks"):(n=t.input.slice(e-1,t.position+1),nt.test(n)||d(t,"named tag handle cannot contain such characters"),s=!0,e=t.position+1)),r=t.input.charCodeAt(++t.position);i=t.input.slice(e,t.position),et.test(i)&&d(t,"tag suffix cannot contain flow indicator characters")}return i&&!it.test(i)&&d(t,"tag name cannot contain such characters: "+i),a?t.tag=i:R.call(t.tagMap,n)?t.tag=t.tagMap[n]+i:"!"===n?t.tag="!"+i:"!!"===n?t.tag="tag:yaml.org,2002:"+i:d(t,'undeclared tag handle "'+n+'"'),!0}function F(t){var e,n;if(n=t.input.charCodeAt(t.position),38!==n)return!1;for(null!==t.anchor&&d(t,"duplication of an anchor property"),n=t.input.charCodeAt(++t.position),e=t.position;0!==n&&!o(n)&&!a(n);)n=t.input.charCodeAt(++t.position);return t.position===e&&d(t,"name of an anchor node must contain at least one character"),t.anchor=t.input.slice(e,t.position),!0}function N(t){var e,n,i;if(i=t.input.charCodeAt(t.position),42!==i)return!1;for(i=t.input.charCodeAt(++t.position),e=t.position;0!==i&&!o(i)&&!a(i);)i=t.input.charCodeAt(++t.position);return t.position===e&&d(t,"name of an alias node must contain at least one character"),n=t.input.slice(e,t.position),t.anchorMap.hasOwnProperty(n)||d(t,'unidentified alias "'+n+'"'),t.result=t.anchorMap[n],A(t,!0,-1),!0}function T(t,e,n,i,r){var o,a,s,c,u,l,p,f,h=1,m=!1,g=!1;if(t.tag=null,t.anchor=null,t.kind=null,t.result=null,o=a=s=Z===n||V===n,i&&A(t,!0,-1)&&(m=!0,t.lineIndent>e?h=1:t.lineIndent===e?h=0:t.lineIndent<e&&(h=-1)),1===h)for(;E(t)||F(t);)A(t,!0,-1)?(m=!0,s=o,t.lineIndent>e?h=1:t.lineIndent===e?h=0:t.lineIndent<e&&(h=-1)):s=!1;if(s&&(s=m||r),(1===h||Z===n)&&(p=W===n||G===n?e:e+1,f=t.position-t.lineStart,1===h?s&&(_(t,f)||I(t,f,p))||O(t,p)?g=!0:(a&&S(t,p)||C(t,p)||j(t,p)?g=!0:N(t)?(g=!0,(null!==t.tag||null!==t.anchor)&&d(t,"alias node should not have any properties")):k(t,p,W===n)&&(g=!0,null===t.tag&&(t.tag="?")),null!==t.anchor&&(t.anchorMap[t.anchor]=t.result)):0===h&&(g=s&&_(t,f))),null!==t.tag&&"!"!==t.tag)if("?"===t.tag){for(c=0,u=t.implicitTypes.length;u>c;c+=1)if(l=t.implicitTypes[c],l.resolve(t.result)){t.result=l.construct(t.result),t.tag=l.tag,null!==t.anchor&&(t.anchorMap[t.anchor]=t.result);break}}else R.call(t.typeMap,t.tag)?(l=t.typeMap[t.tag],null!==t.result&&l.kind!==t.kind&&d(t,"unacceptable node kind for !<"+t.tag+'> tag; it should be "'+l.kind+'", not "'+t.kind+'"'),l.resolve(t.result)?(t.result=l.construct(t.result),null!==t.anchor&&(t.anchorMap[t.anchor]=t.result)):d(t,"cannot resolve a node with !<"+t.tag+"> explicit tag")):d(t,"unknown tag !<"+t.tag+">");return null!==t.tag||null!==t.anchor||g}function M(t){var e,n,a,s,c=t.position,u=!1;for(t.version=null,t.checkLineBreaks=t.legacy,t.tagMap={},t.anchorMap={};0!==(s=t.input.charCodeAt(t.position))&&(A(t,!0,-1),s=t.input.charCodeAt(t.position),!(t.lineIndent>0||37!==s));){for(u=!0,s=t.input.charCodeAt(++t.position),e=t.position;0!==s&&!o(s);)s=t.input.charCodeAt(++t.position);for(n=t.input.slice(e,t.position),a=[],n.length<1&&d(t,"directive name must not be less than one character in length");0!==s;){for(;r(s);)s=t.input.charCodeAt(++t.position);if(35===s){do s=t.input.charCodeAt(++t.position);while(0!==s&&!i(s));break}if(i(s))break;for(e=t.position;0!==s&&!o(s);)s=t.input.charCodeAt(++t.position);a.push(t.input.slice(e,t.position))}0!==s&&x(t),R.call(st,n)?st[n](t,n,a):m(t,'unknown document directive "'+n+'"')}return A(t,!0,-1),0===t.lineIndent&&45===t.input.charCodeAt(t.position)&&45===t.input.charCodeAt(t.position+1)&&45===t.input.charCodeAt(t.position+2)?(t.position+=3,A(t,!0,-1)):u&&d(t,"directives end mark is expected"),T(t,t.lineIndent-1,Z,!1,!0),A(t,!0,-1),t.checkLineBreaks&&tt.test(t.input.slice(c,t.position))&&m(t,"non-ASCII line breaks are interpreted as content"),t.documents.push(t.result),t.position===t.lineStart&&b(t)?void(46===t.input.charCodeAt(t.position)&&(t.position+=3,A(t,!0,-1))):void(t.position<t.length-1&&d(t,"end of the stream or a document separator is expected"))}function L(t,e){t=String(t),e=e||{},0!==t.length&&(10!==t.charCodeAt(t.length-1)&&13!==t.charCodeAt(t.length-1)&&(t+="\n"),65279===t.charCodeAt(0)&&(t=t.slice(1)));var n=new f(t,e);for(n.input+="\x00";32===n.input.charCodeAt(n.position);)n.lineIndent+=1,n.position+=1;for(;n.position<n.length-1;)M(n);return n.documents}function D(t,e,n){var i,r,o=L(t,n);for(i=0,r=o.length;r>i;i+=1)e(o[i])}function U(t,e){var n=L(t,e);if(0===n.length)return void 0;if(1===n.length)return n[0];throw new $("expected a single document in the stream, but found more")}function q(t,e,n){D(t,e,P.extend({schema:K},n))}function Y(t,e){return U(t,P.extend({schema:K},e))}for(var P=t("./common"),$=t("./exception"),B=t("./mark"),K=t("./schema/default_safe"),H=t("./schema/default_full"),R=Object.prototype.hasOwnProperty,W=1,G=2,V=3,Z=4,z=1,J=2,Q=3,X=/[\x00-\x08\x0B\x0C\x0E-\x1F\x7F-\x84\x86-\x9F\uFFFE\uFFFF]|[\uD800-\uDBFF](?![\uDC00-\uDFFF])|(?:[^\uD800-\uDBFF]|^)[\uDC00-\uDFFF]/,tt=/[\x85\u2028\u2029]/,et=/[,\[\]\{\}]/,nt=/^(?:!|!!|![a-z\-]+!)$/i,it=/^(?:!|[^,\[\]\{\}])(?:%[0-9a-f]{2}|[0-9a-z\-#;\/\?:@&=\+\$,_\.!~\*'\(\)\[\]])*$/i,rt=new Array(256),ot=new Array(256),at=0;256>at;at++)rt[at]=l(at)?1:0,ot[at]=l(at);var st={YAML:function(t,e,n){var i,r,o;null!==t.version&&d(t,"duplication of %YAML directive"),1!==n.length&&d(t,"YAML directive accepts exactly one argument"),i=/^([0-9]+)\.([0-9]+)$/.exec(n[0]),null===i&&d(t,"ill-formed argument of the YAML directive"),r=parseInt(i[1],10),o=parseInt(i[2],10),1!==r&&d(t,"unacceptable YAML version of the document"),t.version=n[0],t.checkLineBreaks=2>o,1!==o&&2!==o&&m(t,"unsupported YAML version of the document")},TAG:function(t,e,n){var i,r;2!==n.length&&d(t,"TAG directive accepts exactly two arguments"),i=n[0],r=n[1],nt.test(i)||d(t,"ill-formed tag handle (first argument) of the TAG directive"),R.call(t.tagMap,i)&&d(t,'there is a previously declared suffix for "'+i+'" tag handle'),it.test(r)||d(t,"ill-formed tag prefix (second argument) of the TAG directive"),t.tagMap[i]=r}};e.exports.loadAll=D,e.exports.load=U,e.exports.safeLoadAll=q,e.exports.safeLoad=Y},{"./common":2,"./exception":4,"./mark":6,"./schema/default_full":9,"./schema/default_safe":10}],6:[function(t,e,n){"use strict";function i(t,e,n,i,r){this.name=t,this.buffer=e,this.position=n,this.line=i,this.column=r}var r=t("./common");i.prototype.getSnippet=function(t,e){var n,i,o,a,s;if(!this.buffer)return null;for(t=t||4,e=e||75,n="",i=this.position;i>0&&-1==="\x00\r\n…\u2028\u2029".indexOf(this.buffer.charAt(i-1));)if(i-=1,this.position-i>e/2-1){n=" ... ",i+=5;break}for(o="",a=this.position;a<this.buffer.length&&-1==="\x00\r\n…\u2028\u2029".indexOf(this.buffer.charAt(a));)if(a+=1,a-this.position>e/2-1){o=" ... ",a-=5;break}return s=this.buffer.slice(i,a),r.repeat(" ",t)+n+s+o+"\n"+r.repeat(" ",t+this.position-i+n.length)+"^"},i.prototype.toString=function(t){var e,n="";return this.name&&(n+='in "'+this.name+'" '),n+="at line "+(this.line+1)+", column "+(this.column+1),t||(e=this.getSnippet(),e&&(n+=":\n"+e)),n},e.exports=i},{"./common":2}],7:[function(t,e,n){"use strict";function i(t,e,n){var r=[];return t.include.forEach(function(t){n=i(t,e,n)}),t[e].forEach(function(t){n.forEach(function(e,n){e.tag===t.tag&&r.push(n)}),n.push(t)}),n.filter(function(t,e){return-1===r.indexOf(e)})}function r(){function t(t){i[t.tag]=t}var e,n,i={};for(e=0,n=arguments.length;n>e;e+=1)arguments[e].forEach(t);return i}function o(t){this.include=t.include||[],this.implicit=t.implicit||[],this.explicit=t.explicit||[],this.implicit.forEach(function(t){if(t.loadKind&&"scalar"!==t.loadKind)throw new s("There is a non-scalar type in the implicit list of a schema. Implicit resolving of such types is not supported.")}),this.compiledImplicit=i(this,"implicit",[]),this.compiledExplicit=i(this,"explicit",[]),this.compiledTypeMap=r(this.compiledImplicit,this.compiledExplicit)}var a=t("./common"),s=t("./exception"),c=t("./type");o.DEFAULT=null,o.create=function(){var t,e;switch(arguments.length){case 1:t=o.DEFAULT,e=arguments[0];break;case 2:t=arguments[0],e=arguments[1];break;default:throw new s("Wrong number of arguments for Schema.create function")}if(t=a.toArray(t),e=a.toArray(e),!t.every(function(t){return t instanceof o}))throw new s("Specified list of super schemas (or a single Schema object) contains a non-Schema object.");if(!e.every(function(t){return t instanceof c}))throw new s("Specified list of YAML types (or a single Type object) contains a non-Type object.");return new o({include:t,explicit:e})},e.exports=o},{"./common":2,"./exception":4,"./type":13}],8:[function(t,e,n){"use strict";var i=t("../schema");e.exports=new i({include:[t("./json")]})},{"../schema":7,"./json":12}],9:[function(t,e,n){"use strict";var i=t("../schema");e.exports=i.DEFAULT=new i({include:[t("./default_safe")],explicit:[t("../type/js/undefined"),t("../type/js/regexp"),t("../type/js/function")]})},{"../schema":7,"../type/js/function":18,"../type/js/regexp":19,"../type/js/undefined":20,"./default_safe":10}],10:[function(t,e,n){"use strict";var i=t("../schema");e.exports=new i({include:[t("./core")],implicit:[t("../type/timestamp"),t("../type/merge")],explicit:[t("../type/binary"),t("../type/omap"),t("../type/pairs"),t("../type/set")]})},{"../schema":7,"../type/binary":14,"../type/merge":22,"../type/omap":24,"../type/pairs":25,"../type/set":27,"../type/timestamp":29,"./core":8}],11:[function(t,e,n){"use strict";var i=t("../schema");e.exports=new i({explicit:[t("../type/str"),t("../type/seq"),t("../type/map")]})},{"../schema":7,"../type/map":21,"../type/seq":26,"../type/str":28}],12:[function(t,e,n){"use strict";var i=t("../schema");e.exports=new i({include:[t("./failsafe")],implicit:[t("../type/null"),t("../type/bool"),t("../type/int"),t("../type/float")]})},{"../schema":7,"../type/bool":15,"../type/float":16,"../type/int":17,"../type/null":23,"./failsafe":11}],13:[function(t,e,n){"use strict";function i(t){var e={};return null!==t&&Object.keys(t).forEach(function(n){t[n].forEach(function(t){e[String(t)]=n})}),e}function r(t,e){if(e=e||{},Object.keys(e).forEach(function(e){if(-1===a.indexOf(e))throw new o('Unknown option "'+e+'" is met in definition of "'+t+'" YAML type.')}),this.tag=t,this.kind=e.kind||null,this.resolve=e.resolve||function(){return!0},this.construct=e.construct||function(t){return t},this.instanceOf=e.instanceOf||null,this.predicate=e.predicate||null,this.represent=e.represent||null,this.defaultStyle=e.defaultStyle||null,this.styleAliases=i(e.styleAliases||null),-1===s.indexOf(this.kind))throw new o('Unknown kind "'+this.kind+'" is specified for "'+t+'" YAML type.')}var o=t("./exception"),a=["kind","resolve","construct","instanceOf","predicate","represent","defaultStyle","styleAliases"],s=["scalar","sequence","mapping"];e.exports=r},{"./exception":4}],14:[function(t,e,n){"use strict";function i(t){if(null===t)return!1;var e,n,i=0,r=t.length,o=u;for(n=0;r>n;n++)if(e=o.indexOf(t.charAt(n)),!(e>64)){if(0>e)return!1;i+=6}return i%8===0}function r(t){var e,n,i=t.replace(/[\r\n=]/g,""),r=i.length,o=u,a=0,c=[];for(e=0;r>e;e++)e%4===0&&e&&(c.push(a>>16&255),c.push(a>>8&255),c.push(255&a)),a=a<<6|o.indexOf(i.charAt(e));return n=r%4*6,0===n?(c.push(a>>16&255),c.push(a>>8&255),c.push(255&a)):18===n?(c.push(a>>10&255),c.push(a>>2&255)):12===n&&c.push(a>>4&255),s?new s(c):c}function o(t){var e,n,i="",r=0,o=t.length,a=u;for(e=0;o>e;e++)e%3===0&&e&&(i+=a[r>>18&63],i+=a[r>>12&63],i+=a[r>>6&63],i+=a[63&r]),r=(r<<8)+t[e];return n=o%3,0===n?(i+=a[r>>18&63],i+=a[r>>12&63],i+=a[r>>6&63],i+=a[63&r]):2===n?(i+=a[r>>10&63],i+=a[r>>4&63],i+=a[r<<2&63],i+=a[64]):1===n&&(i+=a[r>>2&63],i+=a[r<<4&63],i+=a[64],i+=a[64]),i}function a(t){return s&&s.isBuffer(t)}var s=t("buffer").Buffer,c=t("../type"),u="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=\n\r";e.exports=new c("tag:yaml.org,2002:binary",{kind:"scalar",resolve:i,
+construct:r,predicate:a,represent:o})},{"../type":13,buffer:30}],15:[function(t,e,n){"use strict";function i(t){if(null===t)return!1;var e=t.length;return 4===e&&("true"===t||"True"===t||"TRUE"===t)||5===e&&("false"===t||"False"===t||"FALSE"===t)}function r(t){return"true"===t||"True"===t||"TRUE"===t}function o(t){return"[object Boolean]"===Object.prototype.toString.call(t)}var a=t("../type");e.exports=new a("tag:yaml.org,2002:bool",{kind:"scalar",resolve:i,construct:r,predicate:o,represent:{lowercase:function(t){return t?"true":"false"},uppercase:function(t){return t?"TRUE":"FALSE"},camelcase:function(t){return t?"True":"False"}},defaultStyle:"lowercase"})},{"../type":13}],16:[function(t,e,n){"use strict";function i(t){return null===t?!1:u.test(t)?!0:!1}function r(t){var e,n,i,r;return e=t.replace(/_/g,"").toLowerCase(),n="-"===e[0]?-1:1,r=[],0<="+-".indexOf(e[0])&&(e=e.slice(1)),".inf"===e?1===n?Number.POSITIVE_INFINITY:Number.NEGATIVE_INFINITY:".nan"===e?NaN:0<=e.indexOf(":")?(e.split(":").forEach(function(t){r.unshift(parseFloat(t,10))}),e=0,i=1,r.forEach(function(t){e+=t*i,i*=60}),n*e):n*parseFloat(e,10)}function o(t,e){var n;if(isNaN(t))switch(e){case"lowercase":return".nan";case"uppercase":return".NAN";case"camelcase":return".NaN"}else if(Number.POSITIVE_INFINITY===t)switch(e){case"lowercase":return".inf";case"uppercase":return".INF";case"camelcase":return".Inf"}else if(Number.NEGATIVE_INFINITY===t)switch(e){case"lowercase":return"-.inf";case"uppercase":return"-.INF";case"camelcase":return"-.Inf"}else if(s.isNegativeZero(t))return"-0.0";return n=t.toString(10),l.test(n)?n.replace("e",".e"):n}function a(t){return"[object Number]"===Object.prototype.toString.call(t)&&(0!==t%1||s.isNegativeZero(t))}var s=t("../common"),c=t("../type"),u=new RegExp("^(?:[-+]?(?:[0-9][0-9_]*)\\.[0-9_]*(?:[eE][-+][0-9]+)?|\\.[0-9_]+(?:[eE][-+][0-9]+)?|[-+]?[0-9][0-9_]*(?::[0-5]?[0-9])+\\.[0-9_]*|[-+]?\\.(?:inf|Inf|INF)|\\.(?:nan|NaN|NAN))$"),l=/^[-+]?[0-9]+e/;e.exports=new c("tag:yaml.org,2002:float",{kind:"scalar",resolve:i,construct:r,predicate:a,represent:o,defaultStyle:"lowercase"})},{"../common":2,"../type":13}],17:[function(t,e,n){"use strict";function i(t){return t>=48&&57>=t||t>=65&&70>=t||t>=97&&102>=t}function r(t){return t>=48&&55>=t}function o(t){return t>=48&&57>=t}function a(t){if(null===t)return!1;var e,n=t.length,a=0,s=!1;if(!n)return!1;if(e=t[a],("-"===e||"+"===e)&&(e=t[++a]),"0"===e){if(a+1===n)return!0;if(e=t[++a],"b"===e){for(a++;n>a;a++)if(e=t[a],"_"!==e){if("0"!==e&&"1"!==e)return!1;s=!0}return s}if("x"===e){for(a++;n>a;a++)if(e=t[a],"_"!==e){if(!i(t.charCodeAt(a)))return!1;s=!0}return s}for(;n>a;a++)if(e=t[a],"_"!==e){if(!r(t.charCodeAt(a)))return!1;s=!0}return s}for(;n>a;a++)if(e=t[a],"_"!==e){if(":"===e)break;if(!o(t.charCodeAt(a)))return!1;s=!0}return s?":"!==e?!0:/^(:[0-5]?[0-9])+$/.test(t.slice(a)):!1}function s(t){var e,n,i=t,r=1,o=[];return-1!==i.indexOf("_")&&(i=i.replace(/_/g,"")),e=i[0],("-"===e||"+"===e)&&("-"===e&&(r=-1),i=i.slice(1),e=i[0]),"0"===i?0:"0"===e?"b"===i[1]?r*parseInt(i.slice(2),2):"x"===i[1]?r*parseInt(i,16):r*parseInt(i,8):-1!==i.indexOf(":")?(i.split(":").forEach(function(t){o.unshift(parseInt(t,10))}),i=0,n=1,o.forEach(function(t){i+=t*n,n*=60}),r*i):r*parseInt(i,10)}function c(t){return"[object Number]"===Object.prototype.toString.call(t)&&0===t%1&&!u.isNegativeZero(t)}var u=t("../common"),l=t("../type");e.exports=new l("tag:yaml.org,2002:int",{kind:"scalar",resolve:a,construct:s,predicate:c,represent:{binary:function(t){return"0b"+t.toString(2)},octal:function(t){return"0"+t.toString(8)},decimal:function(t){return t.toString(10)},hexadecimal:function(t){return"0x"+t.toString(16).toUpperCase()}},defaultStyle:"decimal",styleAliases:{binary:[2,"bin"],octal:[8,"oct"],decimal:[10,"dec"],hexadecimal:[16,"hex"]}})},{"../common":2,"../type":13}],18:[function(t,e,n){"use strict";function i(t){if(null===t)return!1;try{var e="("+t+")",n=s.parse(e,{range:!0});return"Program"!==n.type||1!==n.body.length||"ExpressionStatement"!==n.body[0].type||"FunctionExpression"!==n.body[0].expression.type?!1:!0}catch(i){return!1}}function r(t){var e,n="("+t+")",i=s.parse(n,{range:!0}),r=[];if("Program"!==i.type||1!==i.body.length||"ExpressionStatement"!==i.body[0].type||"FunctionExpression"!==i.body[0].expression.type)throw new Error("Failed to resolve function");return i.body[0].expression.params.forEach(function(t){r.push(t.name)}),e=i.body[0].expression.body.range,new Function(r,n.slice(e[0]+1,e[1]-1))}function o(t){return t.toString()}function a(t){return"[object Function]"===Object.prototype.toString.call(t)}var s;try{s=t("esprima")}catch(c){"undefined"!=typeof window&&(s=window.esprima)}var u=t("../../type");e.exports=new u("tag:yaml.org,2002:js/function",{kind:"scalar",resolve:i,construct:r,predicate:a,represent:o})},{"../../type":13,esprima:"esprima"}],19:[function(t,e,n){"use strict";function i(t){if(null===t)return!1;if(0===t.length)return!1;var e=t,n=/\/([gim]*)$/.exec(t),i="";if("/"===e[0]){if(n&&(i=n[1]),i.length>3)return!1;if("/"!==e[e.length-i.length-1])return!1;e=e.slice(1,e.length-i.length-1)}try{return!0}catch(r){return!1}}function r(t){var e=t,n=/\/([gim]*)$/.exec(t),i="";return"/"===e[0]&&(n&&(i=n[1]),e=e.slice(1,e.length-i.length-1)),new RegExp(e,i)}function o(t){var e="/"+t.source+"/";return t.global&&(e+="g"),t.multiline&&(e+="m"),t.ignoreCase&&(e+="i"),e}function a(t){return"[object RegExp]"===Object.prototype.toString.call(t)}var s=t("../../type");e.exports=new s("tag:yaml.org,2002:js/regexp",{kind:"scalar",resolve:i,construct:r,predicate:a,represent:o})},{"../../type":13}],20:[function(t,e,n){"use strict";function i(){return!0}function r(){return void 0}function o(){return""}function a(t){return"undefined"==typeof t}var s=t("../../type");e.exports=new s("tag:yaml.org,2002:js/undefined",{kind:"scalar",resolve:i,construct:r,predicate:a,represent:o})},{"../../type":13}],21:[function(t,e,n){"use strict";var i=t("../type");e.exports=new i("tag:yaml.org,2002:map",{kind:"mapping",construct:function(t){return null!==t?t:{}}})},{"../type":13}],22:[function(t,e,n){"use strict";function i(t){return"<<"===t||null===t}var r=t("../type");e.exports=new r("tag:yaml.org,2002:merge",{kind:"scalar",resolve:i})},{"../type":13}],23:[function(t,e,n){"use strict";function i(t){if(null===t)return!0;var e=t.length;return 1===e&&"~"===t||4===e&&("null"===t||"Null"===t||"NULL"===t)}function r(){return null}function o(t){return null===t}var a=t("../type");e.exports=new a("tag:yaml.org,2002:null",{kind:"scalar",resolve:i,construct:r,predicate:o,represent:{canonical:function(){return"~"},lowercase:function(){return"null"},uppercase:function(){return"NULL"},camelcase:function(){return"Null"}},defaultStyle:"lowercase"})},{"../type":13}],24:[function(t,e,n){"use strict";function i(t){if(null===t)return!0;var e,n,i,r,o,c=[],u=t;for(e=0,n=u.length;n>e;e+=1){if(i=u[e],o=!1,"[object Object]"!==s.call(i))return!1;for(r in i)if(a.call(i,r)){if(o)return!1;o=!0}if(!o)return!1;if(-1!==c.indexOf(r))return!1;c.push(r)}return!0}function r(t){return null!==t?t:[]}var o=t("../type"),a=Object.prototype.hasOwnProperty,s=Object.prototype.toString;e.exports=new o("tag:yaml.org,2002:omap",{kind:"sequence",resolve:i,construct:r})},{"../type":13}],25:[function(t,e,n){"use strict";function i(t){if(null===t)return!0;var e,n,i,r,o,s=t;for(o=new Array(s.length),e=0,n=s.length;n>e;e+=1){if(i=s[e],"[object Object]"!==a.call(i))return!1;if(r=Object.keys(i),1!==r.length)return!1;o[e]=[r[0],i[r[0]]]}return!0}function r(t){if(null===t)return[];var e,n,i,r,o,a=t;for(o=new Array(a.length),e=0,n=a.length;n>e;e+=1)i=a[e],r=Object.keys(i),o[e]=[r[0],i[r[0]]];return o}var o=t("../type"),a=Object.prototype.toString;e.exports=new o("tag:yaml.org,2002:pairs",{kind:"sequence",resolve:i,construct:r})},{"../type":13}],26:[function(t,e,n){"use strict";var i=t("../type");e.exports=new i("tag:yaml.org,2002:seq",{kind:"sequence",construct:function(t){return null!==t?t:[]}})},{"../type":13}],27:[function(t,e,n){"use strict";function i(t){if(null===t)return!0;var e,n=t;for(e in n)if(a.call(n,e)&&null!==n[e])return!1;return!0}function r(t){return null!==t?t:{}}var o=t("../type"),a=Object.prototype.hasOwnProperty;e.exports=new o("tag:yaml.org,2002:set",{kind:"mapping",resolve:i,construct:r})},{"../type":13}],28:[function(t,e,n){"use strict";var i=t("../type");e.exports=new i("tag:yaml.org,2002:str",{kind:"scalar",construct:function(t){return null!==t?t:""}})},{"../type":13}],29:[function(t,e,n){"use strict";function i(t){return null===t?!1:null===s.exec(t)?!1:!0}function r(t){var e,n,i,r,o,a,c,u,l,p,f=0,h=null;if(e=s.exec(t),null===e)throw new Error("Date resolve error");if(n=+e[1],i=+e[2]-1,r=+e[3],!e[4])return new Date(Date.UTC(n,i,r));if(o=+e[4],a=+e[5],c=+e[6],e[7]){for(f=e[7].slice(0,3);f.length<3;)f+="0";f=+f}return e[9]&&(u=+e[10],l=+(e[11]||0),h=6e4*(60*u+l),"-"===e[9]&&(h=-h)),p=new Date(Date.UTC(n,i,r,o,a,c,f)),h&&p.setTime(p.getTime()-h),p}function o(t){return t.toISOString()}var a=t("../type"),s=new RegExp("^([0-9][0-9][0-9][0-9])-([0-9][0-9]?)-([0-9][0-9]?)(?:(?:[Tt]|[ \\t]+)([0-9][0-9]?):([0-9][0-9]):([0-9][0-9])(?:\\.([0-9]*))?(?:[ \\t]*(Z|([-+])([0-9][0-9]?)(?::([0-9][0-9]))?))?)?$");e.exports=new a("tag:yaml.org,2002:timestamp",{kind:"scalar",resolve:i,construct:r,instanceOf:Date,represent:o})},{"../type":13}],30:[function(t,e,n){},{}],31:[function(t,e,n){e.exports=t("./lib/inherit")},{"./lib/inherit":32}],32:[function(e,n,i){!function(e){function r(t){var e=f(t);if(v)for(var n,i=0;n=b[i++];)t.hasOwnProperty(n)&&e.push(n);return e}function o(t,e,n){for(var i,o,a=r(n),s=0,u=a.length;u>s;)"__self"!==(i=a[s++])&&(o=n[i],g(o)&&(!c||o.toString().indexOf(".__base")>-1)?e[i]=function(n,i){var r=t[n]?t[n]:"__constructor"===n?e.__self.__parent:y;return function(){var t=this.__base;this.__base=r;var e=i.apply(this,arguments);return this.__base=t,e}}(i,o):e[i]=o)}function a(t,e){for(var n,i=1;n=t[i++];)e?g(n)?s.self(e,n.prototype,n):s.self(e,n):e=g(n)?s(t[0],n.prototype,n):s(t[0],n);return e||t[0]}function s(){var t=arguments,e=m(t[0]),n=e||g(t[0]),i=n?e?a(t[0]):t[0]:u,r=t[n?1:0]||{},s=t[n?2:1],c=r.__constructor||n&&i.prototype.__constructor?function(){return this.__constructor.apply(this,arguments)}:n?function(){return i.apply(this,arguments)}:function(){};if(!n)return c.prototype=r,c.prototype.__self=c.prototype.constructor=c,h(c,s);h(c,i),c.__parent=i;var l=i.prototype,f=c.prototype=p(l);return f.__self=f.constructor=c,r&&o(l,f,r),s&&o(i,c,s),c}var c=function(){"_"}.toString().indexOf("_")>-1,u=function(){},l=Object.prototype.hasOwnProperty,p=Object.create||function(t){var e=function(){};return e.prototype=t,new e},f=Object.keys||function(t){var e=[];for(var n in t)l.call(t,n)&&e.push(n);return e},h=function(t,e){for(var n in e)l.call(e,n)&&(t[n]=e[n]);return t},d=Object.prototype.toString,m=Array.isArray||function(t){return"[object Array]"===d.call(t)},g=function(t){return"[object Function]"===d.call(t)},y=function(){},v=!0,x={toString:""};for(var A in x)x.hasOwnProperty(A)&&(v=!1);var b=v?["toString","valueOf"]:null;s.self=function(){var t=arguments,e=m(t[0]),n=e?a(t[0],t[0][0]):t[0],i=t[1],r=t[2],s=n.prototype;return i&&o(s,s,i),r&&o(n,n,r),n};var w=!0;"object"==typeof i&&(n.exports=s,w=!1),"object"==typeof modules&&(modules.define("inherit",function(t){t(s)}),w=!1),"function"==typeof t&&(t(function(t,e,n){n.exports=s}),w=!1),w&&(e.inherit=s)}(this)},{}],"/":[function(t,e,n){"use strict";var i=t("./lib/js-yaml.js");e.exports=i},{"./lib/js-yaml.js":1}]},{},[])("/")});
diff --git a/ydb/core/viewer/content/api/lib/jsoneditor.min.js b/ydb/core/viewer/content/api/lib/jsoneditor.min.js
index 9e1970295ef..343397f955f 100644
--- a/ydb/core/viewer/content/api/lib/jsoneditor.min.js
+++ b/ydb/core/viewer/content/api/lib/jsoneditor.min.js
@@ -1,11 +1,11 @@
-/*! JSON Editor v0.7.22 - JSON Schema -> HTML Editor
- * By Jeremy Dorn - https://github.com/jdorn/json-editor/
- * Released under the MIT license
- *
- * Date: 2015-08-12
- */
-!function(){var a;!function(){var b=!1,c=/xyz/.test(function(){window.postMessage("xyz")})?/\b_super\b/:/.*/;return a=function(){},a.extend=function(a){function d(){!b&&this.init&&this.init.apply(this,arguments)}var e=this.prototype;b=!0;var f=new this;b=!1;for(var g in a)f[g]="function"==typeof a[g]&&"function"==typeof e[g]&&c.test(a[g])?function(a,b){return function(){var c=this._super;this._super=e[a];var d=b.apply(this,arguments);return this._super=c,d}}(g,a[g]):a[g];return d.prototype=f,d.prototype.constructor=d,d.extend=arguments.callee,d},a}(),function(){function a(a,b){b=b||{bubbles:!1,cancelable:!1,detail:void 0};var c=document.createEvent("CustomEvent");return c.initCustomEvent(a,b.bubbles,b.cancelable,b.detail),c}a.prototype=window.Event.prototype,window.CustomEvent=a}(),function(){for(var a=0,b=["ms","moz","webkit","o"],c=0;c<b.length&&!window.requestAnimationFrame;++c)window.requestAnimationFrame=window[b[c]+"RequestAnimationFrame"],window.cancelAnimationFrame=window[b[c]+"CancelAnimationFrame"]||window[b[c]+"CancelRequestAnimationFrame"];window.requestAnimationFrame||(window.requestAnimationFrame=function(b,c){var d=(new Date).getTime(),e=Math.max(0,16-(d-a)),f=window.setTimeout(function(){b(d+e)},e);return a=d+e,f}),window.cancelAnimationFrame||(window.cancelAnimationFrame=function(a){clearTimeout(a)})}(),function(){Array.isArray||(Array.isArray=function(a){return"[object Array]"===Object.prototype.toString.call(a)})}();var b=function(a){return"object"!=typeof a||a.nodeType||null!==a&&a===a.window?!1:a.constructor&&!Object.prototype.hasOwnProperty.call(a.constructor.prototype,"isPrototypeOf")?!1:!0},c=function(a){var d,e,f;for(e=1;e<arguments.length;e++){d=arguments[e];for(f in d)d.hasOwnProperty(f)&&(d[f]&&b(d[f])?(a.hasOwnProperty(f)||(a[f]={}),c(a[f],d[f])):a[f]=d[f])}return a},d=function(a,b){if(a&&"object"==typeof a){var c;if(Array.isArray(a)||"number"==typeof a.length&&a.length>0&&a.length-1 in a){for(c=0;c<a.length;c++)if(b(c,a[c])===!1)return}else if(Object.keys){var d=Object.keys(a);for(c=0;c<d.length;c++)if(b(d[c],a[d[c]])===!1)return}else for(c in a)if(a.hasOwnProperty(c)&&b(c,a[c])===!1)return}},e=function(a,b){var c=document.createEvent("HTMLEvents");c.initEvent(b,!0,!0),a.dispatchEvent(c)},f=function(a,b){if(!(a instanceof Element))throw new Error("element should be an instance of Element");b=c({},f.defaults.options,b||{}),this.element=a,this.options=b,this.init()};f.prototype={constructor:f,init:function(){var a=this;this.ready=!1;var b=f.defaults.themes[this.options.theme||f.defaults.theme];if(!b)throw"Unknown theme "+(this.options.theme||f.defaults.theme);this.schema=this.options.schema,this.theme=new b,this.template=this.options.template,this.refs=this.options.refs||{},this.uuid=0,this.__data={};var c=f.defaults.iconlibs[this.options.iconlib||f.defaults.iconlib];c&&(this.iconlib=new c),this.root_container=this.theme.getContainer(),this.element.appendChild(this.root_container),this.translate=this.options.translate||f.defaults.translate,this._loadExternalRefs(this.schema,function(){a._getDefinitions(a.schema),a.validator=new f.Validator(a);var b=a.getEditorClass(a.schema);a.root=a.createEditor(b,{jsoneditor:a,schema:a.schema,required:!0,container:a.root_container}),a.root.preBuild(),a.root.build(),a.root.postBuild(),a.options.startval&&a.root.setValue(a.options.startval),a.validation_results=a.validator.validate(a.root.getValue()),a.root.showValidationErrors(a.validation_results),a.ready=!0,window.requestAnimationFrame(function(){a.ready&&(a.validation_results=a.validator.validate(a.root.getValue()),a.root.showValidationErrors(a.validation_results),a.trigger("ready"),a.trigger("change"))})})},getValue:function(){if(!this.ready)throw"JSON Editor not ready yet. Listen for 'ready' event before getting the value";return this.root.getValue()},setValue:function(a){if(!this.ready)throw"JSON Editor not ready yet. Listen for 'ready' event before setting the value";return this.root.setValue(a),this},validate:function(a){if(!this.ready)throw"JSON Editor not ready yet. Listen for 'ready' event before validating";return 1===arguments.length?this.validator.validate(a):this.validation_results},destroy:function(){this.destroyed||this.ready&&(this.schema=null,this.options=null,this.root.destroy(),this.root=null,this.root_container=null,this.validator=null,this.validation_results=null,this.theme=null,this.iconlib=null,this.template=null,this.__data=null,this.ready=!1,this.element.innerHTML="",this.destroyed=!0)},on:function(a,b){return this.callbacks=this.callbacks||{},this.callbacks[a]=this.callbacks[a]||[],this.callbacks[a].push(b),this},off:function(a,b){if(a&&b){this.callbacks=this.callbacks||{},this.callbacks[a]=this.callbacks[a]||[];for(var c=[],d=0;d<this.callbacks[a].length;d++)this.callbacks[a][d]!==b&&c.push(this.callbacks[a][d]);this.callbacks[a]=c}else a?(this.callbacks=this.callbacks||{},this.callbacks[a]=[]):this.callbacks={};return this},trigger:function(a){if(this.callbacks&&this.callbacks[a]&&this.callbacks[a].length)for(var b=0;b<this.callbacks[a].length;b++)this.callbacks[a][b]();return this},setOption:function(a,b){if("show_errors"!==a)throw"Option "+a+" must be set during instantiation and cannot be changed later";return this.options.show_errors=b,this.onChange(),this},getEditorClass:function(a){var b;if(a=this.expandSchema(a),d(f.defaults.resolvers,function(c,d){var e=d(a);return e&&f.defaults.editors[e]?(b=e,!1):void 0}),!b)throw"Unknown editor for schema "+JSON.stringify(a);if(!f.defaults.editors[b])throw"Unknown editor "+b;return f.defaults.editors[b]},createEditor:function(a,b){return b=c({},a.options||{},b),new a(b)},onChange:function(){if(this.ready&&!this.firing_change){this.firing_change=!0;var a=this;return window.requestAnimationFrame(function(){a.firing_change=!1,a.ready&&(a.validation_results=a.validator.validate(a.root.getValue()),"never"!==a.options.show_errors?a.root.showValidationErrors(a.validation_results):a.root.showValidationErrors([]),a.trigger("change"))}),this}},compileTemplate:function(a,b){b=b||f.defaults.template;var c;if("string"==typeof b){if(!f.defaults.templates[b])throw"Unknown template engine "+b;if(c=f.defaults.templates[b](),!c)throw"Template engine "+b+" missing required library."}else c=b;if(!c)throw"No template engine set";if(!c.compile)throw"Invalid template engine set";return c.compile(a)},_data:function(a,b,c){if(3!==arguments.length)return a.hasAttribute("data-jsoneditor-"+b)?this.__data[a.getAttribute("data-jsoneditor-"+b)]:null;var d;a.hasAttribute("data-jsoneditor-"+b)?d=a.getAttribute("data-jsoneditor-"+b):(d=this.uuid++,a.setAttribute("data-jsoneditor-"+b,d)),this.__data[d]=c},registerEditor:function(a){return this.editors=this.editors||{},this.editors[a.path]=a,this},unregisterEditor:function(a){return this.editors=this.editors||{},this.editors[a.path]=null,this},getEditor:function(a){return this.editors?this.editors[a]:void 0},watch:function(a,b){return this.watchlist=this.watchlist||{},this.watchlist[a]=this.watchlist[a]||[],this.watchlist[a].push(b),this},unwatch:function(a,b){if(!this.watchlist||!this.watchlist[a])return this;if(!b)return this.watchlist[a]=null,this;for(var c=[],d=0;d<this.watchlist[a].length;d++)this.watchlist[a][d]!==b&&c.push(this.watchlist[a][d]);return this.watchlist[a]=c.length?c:null,this},notifyWatchers:function(a){if(!this.watchlist||!this.watchlist[a])return this;for(var b=0;b<this.watchlist[a].length;b++)this.watchlist[a][b]()},isEnabled:function(){return!this.root||this.root.isEnabled()},enable:function(){this.root.enable()},disable:function(){this.root.disable()},_getDefinitions:function(a,b){if(b=b||"#/definitions/",a.definitions)for(var c in a.definitions)a.definitions.hasOwnProperty(c)&&(this.refs[b+c]=a.definitions[c],a.definitions[c].definitions&&this._getDefinitions(a.definitions[c],b+c+"/definitions/"))},_getExternalRefs:function(a){var b={},c=function(a){for(var c in a)a.hasOwnProperty(c)&&(b[c]=!0)};a.$ref&&"object"!=typeof a.$ref&&"#"!==a.$ref.substr(0,1)&&!this.refs[a.$ref]&&(b[a.$ref]=!0);for(var d in a)if(a.hasOwnProperty(d))if(a[d]&&"object"==typeof a[d]&&Array.isArray(a[d]))for(var e=0;e<a[d].length;e++)"object"==typeof a[d][e]&&c(this._getExternalRefs(a[d][e]));else a[d]&&"object"==typeof a[d]&&c(this._getExternalRefs(a[d]));return b},_loadExternalRefs:function(a,b){var c=this,e=this._getExternalRefs(a),f=0,g=0,h=!1;d(e,function(a){if(!c.refs[a]){if(!c.options.ajax)throw"Must set ajax option to true to load external ref "+a;c.refs[a]="loading",g++;var d=new XMLHttpRequest;d.open("GET",a,!0),d.onreadystatechange=function(){if(4==d.readyState){if(200!==d.status)throw window.console.log(d),"Failed to fetch ref via ajax- "+a;var e;try{e=JSON.parse(d.responseText)}catch(i){throw window.console.log(i),"Failed to parse external ref "+a}if(!e||"object"!=typeof e)throw"External ref does not contain a valid schema - "+a;c.refs[a]=e,c._loadExternalRefs(e,function(){f++,f>=g&&!h&&(h=!0,b())})}},d.send()}}),g||b()},expandRefs:function(a){for(a=c({},a);a.$ref;){var b=a.$ref;delete a.$ref,this.refs[b]||(b=decodeURIComponent(b)),a=this.extendSchemas(a,this.refs[b])}return a},expandSchema:function(a){var b,e=this,f=c({},a);if("object"==typeof a.type&&(Array.isArray(a.type)?d(a.type,function(b,c){"object"==typeof c&&(a.type[b]=e.expandSchema(c))}):a.type=e.expandSchema(a.type)),"object"==typeof a.disallow&&(Array.isArray(a.disallow)?d(a.disallow,function(b,c){"object"==typeof c&&(a.disallow[b]=e.expandSchema(c))}):a.disallow=e.expandSchema(a.disallow)),a.anyOf&&d(a.anyOf,function(b,c){a.anyOf[b]=e.expandSchema(c)}),a.dependencies&&d(a.dependencies,function(b,c){"object"!=typeof c||Array.isArray(c)||(a.dependencies[b]=e.expandSchema(c))}),a.not&&(a.not=this.expandSchema(a.not)),a.allOf){for(b=0;b<a.allOf.length;b++)f=this.extendSchemas(f,this.expandSchema(a.allOf[b]));delete f.allOf}if(a["extends"]){if(Array.isArray(a["extends"]))for(b=0;b<a["extends"].length;b++)f=this.extendSchemas(f,this.expandSchema(a["extends"][b]));else f=this.extendSchemas(f,this.expandSchema(a["extends"]));delete f["extends"]}if(a.oneOf){var g=c({},f);for(delete g.oneOf,b=0;b<a.oneOf.length;b++)f.oneOf[b]=this.extendSchemas(this.expandSchema(a.oneOf[b]),g)}return this.expandRefs(f)},extendSchemas:function(a,b){a=c({},a),b=c({},b);var e=this,f={};return d(a,function(a,c){"undefined"!=typeof b[a]?"required"===a&&"object"==typeof c&&Array.isArray(c)?f.required=c.concat(b[a]).reduce(function(a,b){return a.indexOf(b)<0&&a.push(b),a},[]):"type"!==a||"string"!=typeof c&&!Array.isArray(c)?"object"==typeof c&&Array.isArray(c)?f[a]=c.filter(function(c){return-1!==b[a].indexOf(c)}):"object"==typeof c&&null!==c?f[a]=e.extendSchemas(c,b[a]):f[a]=c:("string"==typeof c&&(c=[c]),"string"==typeof b.type&&(b.type=[b.type]),f.type=c.filter(function(a){return-1!==b.type.indexOf(a)}),1===f.type.length&&"string"==typeof f.type[0]&&(f.type=f.type[0])):f[a]=c}),d(b,function(b,c){"undefined"==typeof a[b]&&(f[b]=c)}),f}},f.defaults={themes:{},templates:{},iconlibs:{},editors:{},languages:{},resolvers:[],custom_validators:[]},f.Validator=a.extend({init:function(a,b){this.jsoneditor=a,this.schema=b||this.jsoneditor.schema,this.options={},this.translate=this.jsoneditor.translate||f.defaults.translate},validate:function(a){return this._validateSchema(this.schema,a)},_validateSchema:function(a,b,e){var g,h,i,j=this,k=[],l=JSON.stringify(b);if(e=e||"root",a=c({},this.jsoneditor.expandRefs(a)),a.required&&a.required===!0){if("undefined"==typeof b)return k.push({path:e,property:"required",message:this.translate("error_notset")}),k}else if("undefined"==typeof b){if(!this.jsoneditor.options.required_by_default)return k;k.push({path:e,property:"required",message:this.translate("error_notset")})}if(a["enum"]){for(g=!1,h=0;h<a["enum"].length;h++)l===JSON.stringify(a["enum"][h])&&(g=!0);g||k.push({path:e,property:"enum",message:this.translate("error_enum")})}if(a["extends"])for(h=0;h<a["extends"].length;h++)k=k.concat(this._validateSchema(a["extends"][h],b,e));if(a.allOf)for(h=0;h<a.allOf.length;h++)k=k.concat(this._validateSchema(a.allOf[h],b,e));if(a.anyOf){for(g=!1,h=0;h<a.anyOf.length;h++)if(!this._validateSchema(a.anyOf[h],b,e).length){g=!0;break}g||k.push({path:e,property:"anyOf",message:this.translate("error_anyOf")})}if(a.oneOf){g=0;var m=[];for(h=0;h<a.oneOf.length;h++){var n=this._validateSchema(a.oneOf[h],b,e);for(n.length||g++,i=0;i<n.length;i++)n[i].path=e+".oneOf["+h+"]"+n[i].path.substr(e.length);m=m.concat(n)}1!==g&&(k.push({path:e,property:"oneOf",message:this.translate("error_oneOf",[g])}),k=k.concat(m))}if(a.not&&(this._validateSchema(a.not,b,e).length||k.push({path:e,property:"not",message:this.translate("error_not")})),a.type)if(Array.isArray(a.type)){for(g=!1,h=0;h<a.type.length;h++)if(this._checkType(a.type[h],b)){g=!0;break}g||k.push({path:e,property:"type",message:this.translate("error_type_union")})}else this._checkType(a.type,b)||k.push({path:e,property:"type",message:this.translate("error_type",[a.type])});if(a.disallow)if(Array.isArray(a.disallow)){for(g=!0,h=0;h<a.disallow.length;h++)if(this._checkType(a.disallow[h],b)){g=!1;break}g||k.push({path:e,property:"disallow",message:this.translate("error_disallow_union")})}else this._checkType(a.disallow,b)&&k.push({path:e,property:"disallow",message:this.translate("error_disallow",[a.disallow])});if("number"==typeof b)(a.multipleOf||a.divisibleBy)&&(g=b/(a.multipleOf||a.divisibleBy),g!==Math.floor(g)&&k.push({path:e,property:a.multipleOf?"multipleOf":"divisibleBy",message:this.translate("error_multipleOf",[a.multipleOf||a.divisibleBy])})),a.hasOwnProperty("maximum")&&(a.exclusiveMaximum&&b>=a.maximum?k.push({path:e,property:"maximum",message:this.translate("error_maximum_excl",[a.maximum])}):!a.exclusiveMaximum&&b>a.maximum&&k.push({path:e,property:"maximum",message:this.translate("error_maximum_incl",[a.maximum])})),a.hasOwnProperty("minimum")&&(a.exclusiveMinimum&&b<=a.minimum?k.push({path:e,property:"minimum",message:this.translate("error_minimum_excl",[a.minimum])}):!a.exclusiveMinimum&&b<a.minimum&&k.push({path:e,property:"minimum",message:this.translate("error_minimum_incl",[a.minimum])}));else if("string"==typeof b)a.maxLength&&(b+"").length>a.maxLength&&k.push({path:e,property:"maxLength",message:this.translate("error_maxLength",[a.maxLength])}),a.minLength&&(b+"").length<a.minLength&&k.push({path:e,property:"minLength",message:this.translate(1===a.minLength?"error_notempty":"error_minLength",[a.minLength])}),a.pattern&&(new RegExp(a.pattern).test(b)||k.push({path:e,property:"pattern",message:this.translate("error_pattern")}));else if("object"==typeof b&&null!==b&&Array.isArray(b)){if(a.items)if(Array.isArray(a.items))for(h=0;h<b.length;h++)if(a.items[h])k=k.concat(this._validateSchema(a.items[h],b[h],e+"."+h));else{if(a.additionalItems===!0)break;if(!a.additionalItems){if(a.additionalItems===!1){k.push({path:e,property:"additionalItems",message:this.translate("error_additionalItems")});break}break}k=k.concat(this._validateSchema(a.additionalItems,b[h],e+"."+h))}else for(h=0;h<b.length;h++)k=k.concat(this._validateSchema(a.items,b[h],e+"."+h));if(a.maxItems&&b.length>a.maxItems&&k.push({path:e,property:"maxItems",message:this.translate("error_maxItems",[a.maxItems])}),a.minItems&&b.length<a.minItems&&k.push({path:e,property:"minItems",message:this.translate("error_minItems",[a.minItems])}),a.uniqueItems){var o={};for(h=0;h<b.length;h++){if(g=JSON.stringify(b[h]),o[g]){k.push({path:e,property:"uniqueItems",message:this.translate("error_uniqueItems")});break}o[g]=!0}}}else if("object"==typeof b&&null!==b){if(a.maxProperties){g=0;for(h in b)b.hasOwnProperty(h)&&g++;g>a.maxProperties&&k.push({path:e,property:"maxProperties",message:this.translate("error_maxProperties",[a.maxProperties])})}if(a.minProperties){g=0;for(h in b)b.hasOwnProperty(h)&&g++;g<a.minProperties&&k.push({path:e,property:"minProperties",message:this.translate("error_minProperties",[a.minProperties])})}if(a.required&&Array.isArray(a.required))for(h=0;h<a.required.length;h++)"undefined"==typeof b[a.required[h]]&&k.push({path:e,property:"required",message:this.translate("error_required",[a.required[h]])});var p={};if(a.properties)for(h in a.properties)a.properties.hasOwnProperty(h)&&(p[h]=!0,k=k.concat(this._validateSchema(a.properties[h],b[h],e+"."+h)));if(a.patternProperties)for(h in a.patternProperties)if(a.patternProperties.hasOwnProperty(h)){var q=new RegExp(h);for(i in b)b.hasOwnProperty(i)&&q.test(i)&&(p[i]=!0,k=k.concat(this._validateSchema(a.patternProperties[h],b[i],e+"."+i)))}if("undefined"!=typeof a.additionalProperties||!this.jsoneditor.options.no_additional_properties||a.oneOf||a.anyOf||(a.additionalProperties=!1),"undefined"!=typeof a.additionalProperties)for(h in b)if(b.hasOwnProperty(h)&&!p[h]){if(!a.additionalProperties){k.push({path:e,property:"additionalProperties",message:this.translate("error_additional_properties",[h])});break}if(a.additionalProperties===!0)break;k=k.concat(this._validateSchema(a.additionalProperties,b[h],e+"."+h))}if(a.dependencies)for(h in a.dependencies)if(a.dependencies.hasOwnProperty(h)&&"undefined"!=typeof b[h])if(Array.isArray(a.dependencies[h]))for(i=0;i<a.dependencies[h].length;i++)"undefined"==typeof b[a.dependencies[h][i]]&&k.push({path:e,property:"dependencies",message:this.translate("error_dependency",[a.dependencies[h][i]])});else k=k.concat(this._validateSchema(a.dependencies[h],b,e))}return d(f.defaults.custom_validators,function(c,d){k=k.concat(d.call(j,a,b,e))}),k},_checkType:function(a,b){return"string"==typeof a?"string"===a?"string"==typeof b:"number"===a?"number"==typeof b:"integer"===a?"number"==typeof b&&b===Math.floor(b):"boolean"===a?"boolean"==typeof b:"array"===a?Array.isArray(b):"object"===a?null!==b&&!Array.isArray(b)&&"object"==typeof b:"null"===a?null===b:!0:!this._validateSchema(a,b).length}}),f.AbstractEditor=a.extend({onChildEditorChange:function(a){this.onChange(!0)},notify:function(){this.jsoneditor.notifyWatchers(this.path)},change:function(){this.parent?this.parent.onChildEditorChange(this):this.jsoneditor.onChange()},onChange:function(a){this.notify(),this.watch_listener&&this.watch_listener(),a&&this.change()},register:function(){this.jsoneditor.registerEditor(this),this.onChange()},unregister:function(){this.jsoneditor&&this.jsoneditor.unregisterEditor(this)},getNumColumns:function(){return 12},init:function(a){this.jsoneditor=a.jsoneditor,this.theme=this.jsoneditor.theme,this.template_engine=this.jsoneditor.template,this.iconlib=this.jsoneditor.iconlib,this.original_schema=a.schema,this.schema=this.jsoneditor.expandSchema(this.original_schema),this.options=c({},this.options||{},a.schema.options||{},a),a.path||this.schema.id||(this.schema.id="root"),this.path=a.path||"root",this.formname=a.formname||this.path.replace(/\.([^.]+)/g,"[$1]"),this.jsoneditor.options.form_name_root&&(this.formname=this.formname.replace(/^root\[/,this.jsoneditor.options.form_name_root+"[")),this.key=this.path.split(".").pop(),this.parent=a.parent,this.link_watchers=[],a.container&&this.setContainer(a.container)},setContainer:function(a){this.container=a,this.schema.id&&this.container.setAttribute("data-schemaid",this.schema.id),this.schema.type&&"string"==typeof this.schema.type&&this.container.setAttribute("data-schematype",this.schema.type),this.container.setAttribute("data-schemapath",this.path)},preBuild:function(){},build:function(){},postBuild:function(){this.setupWatchListeners(),this.addLinks(),this.setValue(this.getDefault(),!0),this.updateHeaderText(),this.register(),this.onWatchedFieldChange()},setupWatchListeners:function(){var a=this;if(this.watched={},this.schema.vars&&(this.schema.watch=this.schema.vars),this.watched_values={},this.watch_listener=function(){a.refreshWatchedFieldValues()&&a.onWatchedFieldChange()},this.register(),this.schema.hasOwnProperty("watch")){var b,c,d,e,f;for(var g in this.schema.watch)if(this.schema.watch.hasOwnProperty(g)){if(b=this.schema.watch[g],Array.isArray(b)?c=[b[0]].concat(b[1].split(".")):(c=b.split("."),a.theme.closest(a.container,'[data-schemaid="'+c[0]+'"]')||c.unshift("#")),d=c.shift(),"#"===d&&(d=a.jsoneditor.schema.id||"root"),e=a.theme.closest(a.container,'[data-schemaid="'+d+'"]'),!e)throw"Could not find ancestor node with id "+d;f=e.getAttribute("data-schemapath")+"."+c.join("."),a.jsoneditor.watch(f,a.watch_listener),a.watched[g]=f}}this.schema.headerTemplate&&(this.header_template=this.jsoneditor.compileTemplate(this.schema.headerTemplate,this.template_engine))},addLinks:function(){if(!this.no_link_holder&&(this.link_holder=this.theme.getLinksHolder(),this.container.appendChild(this.link_holder),this.schema.links))for(var a=0;a<this.schema.links.length;a++)this.addLink(this.getLink(this.schema.links[a]))},getButton:function(a,b,c){var d="json-editor-btn-"+b;b=this.iconlib?this.iconlib.getIcon(b):null,!b&&c&&(a=c,c=null);var e=this.theme.getButton(a,b,c);return e.className+=" "+d+" ",e},setButtonText:function(a,b,c,d){return c=this.iconlib?this.iconlib.getIcon(c):null,!c&&d&&(b=d,d=null),this.theme.setButtonText(a,b,c,d)},addLink:function(a){this.link_holder&&this.link_holder.appendChild(a)},getLink:function(a){var b,c,d=a.mediaType||"application/javascript",e=d.split("/")[0],f=this.jsoneditor.compileTemplate(a.href,this.template_engine);if("image"===e){b=this.theme.getBlockLinkHolder(),c=document.createElement("a"),c.setAttribute("target","_blank");var g=document.createElement("img");this.theme.createImageLink(b,c,g),this.link_watchers.push(function(b){var d=f(b);c.setAttribute("href",d),c.setAttribute("title",a.rel||d),g.setAttribute("src",d)})}else if(["audio","video"].indexOf(e)>=0){b=this.theme.getBlockLinkHolder(),c=this.theme.getBlockLink(),c.setAttribute("target","_blank");var h=document.createElement(e);h.setAttribute("controls","controls"),this.theme.createMediaLink(b,c,h),this.link_watchers.push(function(b){var d=f(b);c.setAttribute("href",d),c.textContent=a.rel||d,h.setAttribute("src",d)})}else b=this.theme.getBlockLink(),b.setAttribute("target","_blank"),b.textContent=a.rel,this.link_watchers.push(function(c){var d=f(c);b.setAttribute("href",d),b.textContent=a.rel||d});return b},refreshWatchedFieldValues:function(){if(this.watched_values){var a={},b=!1,c=this;if(this.watched){var d,e;for(var f in this.watched)this.watched.hasOwnProperty(f)&&(e=c.jsoneditor.getEditor(this.watched[f]),d=e?e.getValue():null,c.watched_values[f]!==d&&(b=!0),a[f]=d)}return a.self=this.getValue(),this.watched_values.self!==a.self&&(b=!0),this.watched_values=a,b}},getWatchedFieldValues:function(){return this.watched_values},updateHeaderText:function(){if(this.header)if(this.header.children.length){for(var a=0;a<this.header.childNodes.length;a++)if(3===this.header.childNodes[a].nodeType){this.header.childNodes[a].nodeValue=this.getHeaderText();break}}else this.header.textContent=this.getHeaderText()},getHeaderText:function(a){return this.header_text?this.header_text:a?this.schema.title:this.getTitle()},onWatchedFieldChange:function(){var a;if(this.header_template){a=c(this.getWatchedFieldValues(),{key:this.key,i:this.key,i0:1*this.key,i1:1*this.key+1,title:this.getTitle()});var b=this.header_template(a);b!==this.header_text&&(this.header_text=b,this.updateHeaderText(),this.notify())}if(this.link_watchers.length){a=this.getWatchedFieldValues();for(var d=0;d<this.link_watchers.length;d++)this.link_watchers[d](a)}},setValue:function(a){this.value=a},getValue:function(){return this.value},refreshValue:function(){},getChildEditors:function(){return!1},destroy:function(){var a=this;this.unregister(this),d(this.watched,function(b,c){a.jsoneditor.unwatch(c,a.watch_listener)}),this.watched=null,this.watched_values=null,this.watch_listener=null,this.header_text=null,this.header_template=null,this.value=null,this.container&&this.container.parentNode&&this.container.parentNode.removeChild(this.container),this.container=null,this.jsoneditor=null,this.schema=null,this.path=null,this.key=null,this.parent=null},getDefault:function(){if(this.schema["default"])return this.schema["default"];if(this.schema["enum"])return this.schema["enum"][0];var a=this.schema.type||this.schema.oneOf;if(a&&Array.isArray(a)&&(a=a[0]),a&&"object"==typeof a&&(a=a.type),a&&Array.isArray(a)&&(a=a[0]),"string"==typeof a){if("number"===a)return 0;if("boolean"===a)return!1;if("integer"===a)return 0;if("string"===a)return"";if("object"===a)return{};if("array"===a)return[]}return null},getTitle:function(){return this.schema.title||this.key},enable:function(){this.disabled=!1},disable:function(){this.disabled=!0},isEnabled:function(){return!this.disabled},isRequired:function(){return"boolean"==typeof this.schema.required?this.schema.required:this.parent&&this.parent.schema&&Array.isArray(this.parent.schema.required)?this.parent.schema.required.indexOf(this.key)>-1:this.jsoneditor.options.required_by_default?!0:!1},getDisplayText:function(a){var b=[],c={};d(a,function(a,b){b.title&&(c[b.title]=c[b.title]||0,c[b.title]++),b.description&&(c[b.description]=c[b.description]||0,c[b.description]++),b.format&&(c[b.format]=c[b.format]||0,c[b.format]++),b.type&&(c[b.type]=c[b.type]||0,c[b.type]++)}),d(a,function(a,d){var e;e="string"==typeof d?d:d.title&&c[d.title]<=1?d.title:d.format&&c[d.format]<=1?d.format:d.type&&c[d.type]<=1?d.type:d.description&&c[d.description]<=1?d.descripton:d.title?d.title:d.format?d.format:d.type?d.type:d.description?d.description:JSON.stringify(d).length<50?JSON.stringify(d):"type",b.push(e)});var e={};return d(b,function(a,d){e[d]=e[d]||0,e[d]++,c[d]>1&&(b[a]=d+" "+e[d])}),b},getOption:function(a){try{throw"getOption is deprecated"}catch(b){window.console.error(b)}return this.options[a]},showValidationErrors:function(a){}}),f.defaults.editors["null"]=f.AbstractEditor.extend({getValue:function(){return null},setValue:function(){this.onChange()},getNumColumns:function(){return 2}}),f.defaults.editors.string=f.AbstractEditor.extend({register:function(){this._super(),this.input&&this.input.setAttribute("name",this.formname)},unregister:function(){this._super(),this.input&&this.input.removeAttribute("name")},setValue:function(a,b,c){if((!this.template||c)&&(null===a||"undefined"==typeof a?a="":"object"==typeof a?a=JSON.stringify(a):"string"!=typeof a&&(a=""+a),a!==this.serialized)){var d=this.sanitize(a);if(this.input.value!==d){this.input.value=d,this.sceditor_instance?this.sceditor_instance.val(d):this.epiceditor?this.epiceditor.importFile(null,d):this.ace_editor&&this.ace_editor.setValue(d);var e=c||this.getValue()!==a;this.refreshValue(),b?this.is_dirty=!1:"change"===this.jsoneditor.options.show_errors&&(this.is_dirty=!0),this.adjust_height&&this.adjust_height(this.input),this.onChange(e)}}},getNumColumns:function(){var a,b=Math.ceil(Math.max(this.getTitle().length,this.schema.maxLength||0,this.schema.minLength||0)/5);return a="textarea"===this.input_type?6:["text","email"].indexOf(this.input_type)>=0?4:2,Math.min(12,Math.max(b,a))},build:function(){var a=this;if(this.options.compact||(this.header=this.label=this.theme.getFormInputLabel(this.getTitle(),this.isRequired())),this.schema.description&&(this.description=this.theme.getFormInputDescription(this.schema.description)),this.format=this.schema.format,!this.format&&this.schema.media&&this.schema.media.type&&(this.format=this.schema.media.type.replace(/(^(application|text)\/(x-)?(script\.)?)|(-source$)/g,"")),!this.format&&this.options.default_format&&(this.format=this.options.default_format),this.options.format&&(this.format=this.options.format),this.format)if("textarea"===this.format)this.input_type="textarea",this.input=this.theme.getTextareaInput();else if("range"===this.format){this.input_type="range";var b=this.schema.minimum||0,c=this.schema.maximum||Math.max(100,b+1),d=1;this.schema.multipleOf&&(b%this.schema.multipleOf&&(b=Math.ceil(b/this.schema.multipleOf)*this.schema.multipleOf),c%this.schema.multipleOf&&(c=Math.floor(c/this.schema.multipleOf)*this.schema.multipleOf),d=this.schema.multipleOf),this.input=this.theme.getRangeInput(b,c,d)}else["actionscript","batchfile","bbcode","c","c++","cpp","coffee","csharp","css","dart","django","ejs","erlang","golang","handlebars","haskell","haxe","html","ini","jade","java","javascript","json","less","lisp","lua","makefile","markdown","matlab","mysql","objectivec","pascal","perl","pgsql","php","python","r","ruby","sass","scala","scss","smarty","sql","stylus","svg","twig","vbscript","xml","yaml"].indexOf(this.format)>=0?(this.input_type=this.format,this.source_code=!0,this.input=this.theme.getTextareaInput()):(this.input_type=this.format,this.input=this.theme.getFormInputField(this.input_type));else this.input_type="text",this.input=this.theme.getFormInputField(this.input_type);"undefined"!=typeof this.schema.maxLength&&this.input.setAttribute("maxlength",this.schema.maxLength),"undefined"!=typeof this.schema.pattern?this.input.setAttribute("pattern",this.schema.pattern):"undefined"!=typeof this.schema.minLength&&this.input.setAttribute("pattern",".{"+this.schema.minLength+",}"),this.options.compact?this.container.className+=" compact":this.options.input_width&&(this.input.style.width=this.options.input_width),(this.schema.readOnly||this.schema.readonly||this.schema.template)&&(this.always_disabled=!0,this.input.disabled=!0),this.input.addEventListener("change",function(b){if(b.preventDefault(),b.stopPropagation(),a.schema.template)return void(this.value=a.value);var c=this.value,d=a.sanitize(c);c!==d&&(this.value=d),a.is_dirty=!0,a.refreshValue(),a.onChange(!0)}),this.options.input_height&&(this.input.style.height=this.options.input_height),this.options.expand_height&&(this.adjust_height=function(a){if(a){var b,c=a.offsetHeight;if(a.offsetHeight<a.scrollHeight)for(b=0;a.offsetHeight<a.scrollHeight+3&&!(b>100);)b++,c++,a.style.height=c+"px";else{for(b=0;a.offsetHeight>=a.scrollHeight+3&&!(b>100);)b++,c--,a.style.height=c+"px";a.style.height=c+1+"px"}}},this.input.addEventListener("keyup",function(b){a.adjust_height(this)}),this.input.addEventListener("change",function(b){a.adjust_height(this)}),this.adjust_height()),this.format&&this.input.setAttribute("data-schemaformat",this.format),this.control=this.theme.getFormControl(this.label,this.input,this.description),this.container.appendChild(this.control),window.requestAnimationFrame(function(){a.input.parentNode&&a.afterInputReady(),a.adjust_height&&a.adjust_height(a.input)}),this.schema.template?(this.template=this.jsoneditor.compileTemplate(this.schema.template,this.template_engine),this.refreshValue()):this.refreshValue()},enable:function(){this.always_disabled||(this.input.disabled=!1),this._super()},disable:function(){this.input.disabled=!0,this._super()},afterInputReady:function(){var a,b=this;if(this.source_code)if(this.options.wysiwyg&&["html","bbcode"].indexOf(this.input_type)>=0&&window.jQuery&&window.jQuery.fn&&window.jQuery.fn.sceditor)a=c({},{plugins:"html"===b.input_type?"xhtml":"bbcode",emoticonsEnabled:!1,width:"100%",height:300},f.plugins.sceditor,b.options.sceditor_options||{}),window.jQuery(b.input).sceditor(a),b.sceditor_instance=window.jQuery(b.input).sceditor("instance"),b.sceditor_instance.blur(function(){var a=window.jQuery("<div>"+b.sceditor_instance.val()+"</div>");window.jQuery("#sceditor-start-marker,#sceditor-end-marker,.sceditor-nlf",a).remove(),b.input.value=a.html(),b.value=b.input.value,b.is_dirty=!0,b.onChange(!0)});else if("markdown"===this.input_type&&window.EpicEditor)this.epiceditor_container=document.createElement("div"),this.input.parentNode.insertBefore(this.epiceditor_container,this.input),this.input.style.display="none",a=c({},f.plugins.epiceditor,{container:this.epiceditor_container,clientSideStorage:!1}),this.epiceditor=new window.EpicEditor(a).load(),this.epiceditor.importFile(null,this.getValue()),this.epiceditor.on("update",function(){var a=b.epiceditor.exportFile();b.input.value=a,b.value=a,b.is_dirty=!0,b.onChange(!0);
-});else if(window.ace){var d=this.input_type;("cpp"===d||"c++"===d||"c"===d)&&(d="c_cpp"),this.ace_container=document.createElement("div"),this.ace_container.style.width="100%",this.ace_container.style.position="relative",this.ace_container.style.height="400px",this.input.parentNode.insertBefore(this.ace_container,this.input),this.input.style.display="none",this.ace_editor=window.ace.edit(this.ace_container),this.ace_editor.setValue(this.getValue()),f.plugins.ace.theme&&this.ace_editor.setTheme("ace/theme/"+f.plugins.ace.theme),d=window.ace.require("ace/mode/"+d),d&&this.ace_editor.getSession().setMode(new d.Mode),this.ace_editor.on("change",function(){var a=b.ace_editor.getValue();b.input.value=a,b.refreshValue(),b.is_dirty=!0,b.onChange(!0)})}b.theme.afterInputReady(b.input)},refreshValue:function(){this.value=this.input.value,"string"!=typeof this.value&&(this.value=""),this.serialized=this.value},destroy:function(){this.sceditor_instance?this.sceditor_instance.destroy():this.epiceditor?this.epiceditor.unload():this.ace_editor&&this.ace_editor.destroy(),this.template=null,this.input&&this.input.parentNode&&this.input.parentNode.removeChild(this.input),this.label&&this.label.parentNode&&this.label.parentNode.removeChild(this.label),this.description&&this.description.parentNode&&this.description.parentNode.removeChild(this.description),this._super()},sanitize:function(a){return a},onWatchedFieldChange:function(){var a;this.template&&(a=this.getWatchedFieldValues(),this.setValue(this.template(a),!1,!0)),this._super()},showValidationErrors:function(a){var b=this;if("always"===this.jsoneditor.options.show_errors);else if(!this.is_dirty&&this.previous_error_setting===this.jsoneditor.options.show_errors)return;this.previous_error_setting=this.jsoneditor.options.show_errors;var c=[];d(a,function(a,d){d.path===b.path&&c.push(d.message)}),c.length?this.theme.addInputError(this.input,c.join(". ")+"."):this.theme.removeInputError(this.input)}}),f.defaults.editors.number=f.defaults.editors.string.extend({sanitize:function(a){return(a+"").replace(/[^0-9\.\-eE]/g,"")},getNumColumns:function(){return 2},getValue:function(){return 1*this.value}}),f.defaults.editors.integer=f.defaults.editors.number.extend({sanitize:function(a){return a+="",a.replace(/[^0-9\-]/g,"")},getNumColumns:function(){return 2}}),f.defaults.editors.object=f.AbstractEditor.extend({getDefault:function(){return c({},this.schema["default"]||{})},getChildEditors:function(){return this.editors},register:function(){if(this._super(),this.editors)for(var a in this.editors)this.editors.hasOwnProperty(a)&&this.editors[a].register()},unregister:function(){if(this._super(),this.editors)for(var a in this.editors)this.editors.hasOwnProperty(a)&&this.editors[a].unregister()},getNumColumns:function(){return Math.max(Math.min(12,this.maxwidth),3)},enable:function(){if(this.editjson_button&&(this.editjson_button.disabled=!1),this.addproperty_button&&(this.addproperty_button.disabled=!1),this._super(),this.editors)for(var a in this.editors)this.editors.hasOwnProperty(a)&&this.editors[a].enable()},disable:function(){if(this.editjson_button&&(this.editjson_button.disabled=!0),this.addproperty_button&&(this.addproperty_button.disabled=!0),this.hideEditJSON(),this._super(),this.editors)for(var a in this.editors)this.editors.hasOwnProperty(a)&&this.editors[a].disable()},layoutEditors:function(){var a,b,c=this;if(this.row_container){this.property_order=Object.keys(this.editors),this.property_order=this.property_order.sort(function(a,b){var d=c.editors[a].schema.propertyOrder,e=c.editors[b].schema.propertyOrder;return"number"!=typeof d&&(d=1e3),"number"!=typeof e&&(e=1e3),d-e});var e;if("grid"===this.format){var f=[];for(d(this.property_order,function(a,b){var d=c.editors[b];if(!d.property_removed){for(var e=!1,g=d.options.hidden?0:d.options.grid_columns||d.getNumColumns(),h=d.options.hidden?0:d.container.offsetHeight,i=0;i<f.length;i++)f[i].width+g<=12&&(!h||.5*f[i].minh<h&&2*f[i].maxh>h)&&(e=i);e===!1&&(f.push({width:0,minh:999999,maxh:0,editors:[]}),e=f.length-1),f[e].editors.push({key:b,width:g,height:h}),f[e].width+=g,f[e].minh=Math.min(f[e].minh,h),f[e].maxh=Math.max(f[e].maxh,h)}}),a=0;a<f.length;a++)if(f[a].width<12){var g=!1,h=0;for(b=0;b<f[a].editors.length;b++)g===!1?g=b:f[a].editors[b].width>f[a].editors[g].width&&(g=b),f[a].editors[b].width*=12/f[a].width,f[a].editors[b].width=Math.floor(f[a].editors[b].width),h+=f[a].editors[b].width;12>h&&(f[a].editors[g].width+=12-h),f[a].width=12}if(this.layout===JSON.stringify(f))return!1;for(this.layout=JSON.stringify(f),e=document.createElement("div"),a=0;a<f.length;a++){var i=this.theme.getGridRow();for(e.appendChild(i),b=0;b<f[a].editors.length;b++){var j=f[a].editors[b].key,k=this.editors[j];k.options.hidden?k.container.style.display="none":this.theme.setGridColumnSize(k.container,f[a].editors[b].width),i.appendChild(k.container)}}}else e=document.createElement("div"),d(this.property_order,function(a,b){var d=c.editors[b];if(!d.property_removed){var f=c.theme.getGridRow();e.appendChild(f),d.options.hidden?d.container.style.display="none":c.theme.setGridColumnSize(d.container,12),f.appendChild(d.container)}});this.row_container.innerHTML="",this.row_container.appendChild(e)}},getPropertySchema:function(a){var b=this.schema.properties[a]||{};b=c({},b);var d=this.schema.properties[a]?!0:!1;if(this.schema.patternProperties)for(var e in this.schema.patternProperties)if(this.schema.patternProperties.hasOwnProperty(e)){var f=new RegExp(e);f.test(a)&&(b.allOf=b.allOf||[],b.allOf.push(this.schema.patternProperties[e]),d=!0)}return!d&&this.schema.additionalProperties&&"object"==typeof this.schema.additionalProperties&&(b=c({},this.schema.additionalProperties)),b},preBuild:function(){this._super(),this.editors={},this.cached_editors={};var a=this;if(this.format=this.options.layout||this.options.object_layout||this.schema.format||this.jsoneditor.options.object_layout||"normal",this.schema.properties=this.schema.properties||{},this.minwidth=0,this.maxwidth=0,this.options.table_row)d(this.schema.properties,function(b,c){var d=a.jsoneditor.getEditorClass(c);a.editors[b]=a.jsoneditor.createEditor(d,{jsoneditor:a.jsoneditor,schema:c,path:a.path+"."+b,parent:a,compact:!0,required:!0}),a.editors[b].preBuild();var e=a.editors[b].options.hidden?0:a.editors[b].options.grid_columns||a.editors[b].getNumColumns();a.minwidth+=e,a.maxwidth+=e}),this.no_link_holder=!0;else{if(this.options.table)throw"Not supported yet";this.defaultProperties=this.schema.defaultProperties||Object.keys(this.schema.properties),a.maxwidth+=1,d(this.defaultProperties,function(b,c){a.addObjectProperty(c,!0),a.editors[c]&&(a.minwidth=Math.max(a.minwidth,a.editors[c].options.grid_columns||a.editors[c].getNumColumns()),a.maxwidth+=a.editors[c].options.grid_columns||a.editors[c].getNumColumns())})}this.property_order=Object.keys(this.editors),this.property_order=this.property_order.sort(function(b,c){var d=a.editors[b].schema.propertyOrder,e=a.editors[c].schema.propertyOrder;return"number"!=typeof d&&(d=1e3),"number"!=typeof e&&(e=1e3),d-e})},build:function(){var a=this;if(this.options.table_row)this.editor_holder=this.container,d(this.editors,function(b,c){var d=a.theme.getTableCell();a.editor_holder.appendChild(d),c.setContainer(d),c.build(),c.postBuild(),a.editors[b].options.hidden&&(d.style.display="none"),a.editors[b].options.input_width&&(d.style.width=a.editors[b].options.input_width)});else{if(this.options.table)throw"Not supported yet";this.header=document.createElement("span"),this.header.textContent=this.getTitle(),this.title=this.theme.getHeader(this.header),this.container.appendChild(this.title),this.container.style.position="relative",this.editjson_holder=this.theme.getModal(),this.editjson_textarea=this.theme.getTextareaInput(),this.editjson_textarea.style.height="170px",this.editjson_textarea.style.width="300px",this.editjson_textarea.style.display="block",this.editjson_save=this.getButton("Save","save","Save"),this.editjson_save.addEventListener("click",function(b){b.preventDefault(),b.stopPropagation(),a.saveJSON()}),this.editjson_cancel=this.getButton("Cancel","cancel","Cancel"),this.editjson_cancel.addEventListener("click",function(b){b.preventDefault(),b.stopPropagation(),a.hideEditJSON()}),this.editjson_holder.appendChild(this.editjson_textarea),this.editjson_holder.appendChild(this.editjson_save),this.editjson_holder.appendChild(this.editjson_cancel),this.addproperty_holder=this.theme.getModal(),this.addproperty_list=document.createElement("div"),this.addproperty_list.style.width="295px",this.addproperty_list.style.maxHeight="160px",this.addproperty_list.style.padding="5px 0",this.addproperty_list.style.overflowY="auto",this.addproperty_list.style.overflowX="hidden",this.addproperty_list.style.paddingLeft="5px",this.addproperty_list.setAttribute("class","property-selector"),this.addproperty_add=this.getButton("add","add","add"),this.addproperty_input=this.theme.getFormInputField("text"),this.addproperty_input.setAttribute("placeholder","Property name..."),this.addproperty_input.style.width="220px",this.addproperty_input.style.marginBottom="0",this.addproperty_input.style.display="inline-block",this.addproperty_add.addEventListener("click",function(b){if(b.preventDefault(),b.stopPropagation(),a.addproperty_input.value){if(a.editors[a.addproperty_input.value])return void window.alert("there is already a property with that name");a.addObjectProperty(a.addproperty_input.value),a.editors[a.addproperty_input.value]&&a.editors[a.addproperty_input.value].disable(),a.onChange(!0)}}),this.addproperty_holder.appendChild(this.addproperty_list),this.addproperty_holder.appendChild(this.addproperty_input),this.addproperty_holder.appendChild(this.addproperty_add);var b=document.createElement("div");b.style.clear="both",this.addproperty_holder.appendChild(b),this.schema.description&&(this.description=this.theme.getDescription(this.schema.description),this.container.appendChild(this.description)),this.error_holder=document.createElement("div"),this.container.appendChild(this.error_holder),this.editor_holder=this.theme.getIndentedPanel(),this.editor_holder.style.paddingBottom="0",this.container.appendChild(this.editor_holder),this.row_container=this.theme.getGridContainer(),this.editor_holder.appendChild(this.row_container),d(this.editors,function(b,c){var d=a.theme.getGridColumn();a.row_container.appendChild(d),c.setContainer(d),c.build(),c.postBuild()}),this.title_controls=this.theme.getHeaderButtonHolder(),this.editjson_controls=this.theme.getHeaderButtonHolder(),this.addproperty_controls=this.theme.getHeaderButtonHolder(),this.title.appendChild(this.title_controls),this.title.appendChild(this.editjson_controls),this.title.appendChild(this.addproperty_controls),this.collapsed=!1,this.toggle_button=this.getButton("","collapse","Collapse"),this.title_controls.appendChild(this.toggle_button),this.toggle_button.addEventListener("click",function(b){b.preventDefault(),b.stopPropagation(),a.collapsed?(a.editor_holder.style.display="",a.collapsed=!1,a.setButtonText(a.toggle_button,"","collapse","Collapse")):(a.editor_holder.style.display="none",a.collapsed=!0,a.setButtonText(a.toggle_button,"","expand","Expand"))}),this.options.collapsed&&e(this.toggle_button,"click"),this.schema.options&&"undefined"!=typeof this.schema.options.disable_collapse?this.schema.options.disable_collapse&&(this.toggle_button.style.display="none"):this.jsoneditor.options.disable_collapse&&(this.toggle_button.style.display="none"),this.editjson_button=this.getButton("JSON","edit","Edit JSON"),this.editjson_button.addEventListener("click",function(b){b.preventDefault(),b.stopPropagation(),a.toggleEditJSON()}),this.editjson_controls.appendChild(this.editjson_button),this.editjson_controls.appendChild(this.editjson_holder),this.schema.options&&"undefined"!=typeof this.schema.options.disable_edit_json?this.schema.options.disable_edit_json&&(this.editjson_button.style.display="none"):this.jsoneditor.options.disable_edit_json&&(this.editjson_button.style.display="none"),this.addproperty_button=this.getButton("Properties","edit","Object Properties"),this.addproperty_button.addEventListener("click",function(b){b.preventDefault(),b.stopPropagation(),a.toggleAddProperty()}),this.addproperty_controls.appendChild(this.addproperty_button),this.addproperty_controls.appendChild(this.addproperty_holder),this.refreshAddProperties()}this.options.table_row?(this.editor_holder=this.container,d(this.property_order,function(b,c){a.editor_holder.appendChild(a.editors[c].container)})):(this.layoutEditors(),this.layoutEditors())},showEditJSON:function(){this.editjson_holder&&(this.hideAddProperty(),this.editjson_holder.style.left=this.editjson_button.offsetLeft+"px",this.editjson_holder.style.top=this.editjson_button.offsetTop+this.editjson_button.offsetHeight+"px",this.editjson_textarea.value=JSON.stringify(this.getValue(),null,2),this.disable(),this.editjson_holder.style.display="",this.editjson_button.disabled=!1,this.editing_json=!0)},hideEditJSON:function(){this.editjson_holder&&this.editing_json&&(this.editjson_holder.style.display="none",this.enable(),this.editing_json=!1)},saveJSON:function(){if(this.editjson_holder)try{var a=JSON.parse(this.editjson_textarea.value);this.setValue(a),this.hideEditJSON()}catch(b){throw window.alert("invalid JSON"),b}},toggleEditJSON:function(){this.editing_json?this.hideEditJSON():this.showEditJSON()},insertPropertyControlUsingPropertyOrder:function(a,b,c){var d;this.schema.properties[a]&&(d=this.schema.properties[a].propertyOrder),"number"!=typeof d&&(d=1e3),b.propertyOrder=d;for(var e=0;e<c.childNodes.length;e++){var f=c.childNodes[e];if(b.propertyOrder<f.propertyOrder){this.addproperty_list.insertBefore(b,f),b=null;break}}b&&this.addproperty_list.appendChild(b)},addPropertyCheckbox:function(a){var b,c,d,e,f=this;return b=f.theme.getCheckbox(),b.style.width="auto",d=this.schema.properties[a]&&this.schema.properties[a].title?this.schema.properties[a].title:a,c=f.theme.getCheckboxLabel(d),e=f.theme.getFormControl(c,b),e.style.paddingBottom=e.style.marginBottom=e.style.paddingTop=e.style.marginTop=0,e.style.height="auto",this.insertPropertyControlUsingPropertyOrder(a,e,this.addproperty_list),b.checked=a in this.editors,b.addEventListener("change",function(){b.checked?f.addObjectProperty(a):f.removeObjectProperty(a),f.onChange(!0)}),f.addproperty_checkboxes[a]=b,b},showAddProperty:function(){this.addproperty_holder&&(this.hideEditJSON(),this.addproperty_holder.style.left=this.addproperty_button.offsetLeft+"px",this.addproperty_holder.style.top=this.addproperty_button.offsetTop+this.addproperty_button.offsetHeight+"px",this.disable(),this.adding_property=!0,this.addproperty_button.disabled=!1,this.addproperty_holder.style.display="",this.refreshAddProperties())},hideAddProperty:function(){this.addproperty_holder&&this.adding_property&&(this.addproperty_holder.style.display="none",this.enable(),this.adding_property=!1)},toggleAddProperty:function(){this.adding_property?this.hideAddProperty():this.showAddProperty()},removeObjectProperty:function(a){this.editors[a]&&(this.editors[a].unregister(),delete this.editors[a],this.refreshValue(),this.layoutEditors())},addObjectProperty:function(a,b){var c=this;if(!this.editors[a]){if(this.cached_editors[a]){if(this.editors[a]=this.cached_editors[a],b)return;this.editors[a].register()}else{if(!(this.canHaveAdditionalProperties()||this.schema.properties&&this.schema.properties[a]))return;var d=c.getPropertySchema(a),e=c.jsoneditor.getEditorClass(d);if(c.editors[a]=c.jsoneditor.createEditor(e,{jsoneditor:c.jsoneditor,schema:d,path:c.path+"."+a,parent:c}),c.editors[a].preBuild(),!b){var f=c.theme.getChildEditorHolder();c.editor_holder.appendChild(f),c.editors[a].setContainer(f),c.editors[a].build(),c.editors[a].postBuild()}c.cached_editors[a]=c.editors[a]}b||(c.refreshValue(),c.layoutEditors())}},onChildEditorChange:function(a){this.refreshValue(),this._super(a)},canHaveAdditionalProperties:function(){return"boolean"==typeof this.schema.additionalProperties?this.schema.additionalProperties:!this.jsoneditor.options.no_additional_properties},destroy:function(){d(this.cached_editors,function(a,b){b.destroy()}),this.editor_holder&&(this.editor_holder.innerHTML=""),this.title&&this.title.parentNode&&this.title.parentNode.removeChild(this.title),this.error_holder&&this.error_holder.parentNode&&this.error_holder.parentNode.removeChild(this.error_holder),this.editors=null,this.cached_editors=null,this.editor_holder&&this.editor_holder.parentNode&&this.editor_holder.parentNode.removeChild(this.editor_holder),this.editor_holder=null,this._super()},getValue:function(){var a=this._super();if(this.jsoneditor.options.remove_empty_properties||this.options.remove_empty_properties)for(var b in a)a.hasOwnProperty(b)&&(a[b]||delete a[b]);return a},refreshValue:function(){this.value={};for(var a in this.editors)this.editors.hasOwnProperty(a)&&(this.value[a]=this.editors[a].getValue());this.adding_property&&this.refreshAddProperties()},refreshAddProperties:function(){if(this.options.disable_properties||this.options.disable_properties!==!1&&this.jsoneditor.options.disable_properties)return void(this.addproperty_controls.style.display="none");var a,b=!1,c=!1,d=0,e=!1;for(a in this.editors)this.editors.hasOwnProperty(a)&&d++;b=this.canHaveAdditionalProperties()&&!("undefined"!=typeof this.schema.maxProperties&&d>=this.schema.maxProperties),this.addproperty_checkboxes&&(this.addproperty_list.innerHTML=""),this.addproperty_checkboxes={};for(a in this.cached_editors)this.cached_editors.hasOwnProperty(a)&&(this.addPropertyCheckbox(a),this.isRequired(this.cached_editors[a])&&a in this.editors&&(this.addproperty_checkboxes[a].disabled=!0),"undefined"!=typeof this.schema.minProperties&&d<=this.schema.minProperties?(this.addproperty_checkboxes[a].disabled=this.addproperty_checkboxes[a].checked,this.addproperty_checkboxes[a].checked||(e=!0)):a in this.editors?(e=!0,c=!0):b||this.schema.properties.hasOwnProperty(a)?(this.addproperty_checkboxes[a].disabled=!1,e=!0):this.addproperty_checkboxes[a].disabled=!0);this.canHaveAdditionalProperties()&&(e=!0);for(a in this.schema.properties)this.schema.properties.hasOwnProperty(a)&&(this.cached_editors[a]||(e=!0,this.addPropertyCheckbox(a)));e?this.canHaveAdditionalProperties()?b?this.addproperty_add.disabled=!1:this.addproperty_add.disabled=!0:(this.addproperty_add.style.display="none",this.addproperty_input.style.display="none"):(this.hideAddProperty(),this.addproperty_controls.style.display="none")},isRequired:function(a){return"boolean"==typeof a.schema.required?a.schema.required:Array.isArray(this.schema.required)?this.schema.required.indexOf(a.key)>-1:this.jsoneditor.options.required_by_default?!0:!1},setValue:function(a,b){var c=this;a=a||{},("object"!=typeof a||Array.isArray(a))&&(a={}),d(this.cached_editors,function(d,e){"undefined"!=typeof a[d]?(c.addObjectProperty(d),e.setValue(a[d],b)):b||c.isRequired(e)?e.setValue(e.getDefault(),b):c.removeObjectProperty(d)}),d(a,function(a,d){c.cached_editors[a]||(c.addObjectProperty(a),c.editors[a]&&c.editors[a].setValue(d,b))}),this.refreshValue(),this.layoutEditors(),this.onChange()},showValidationErrors:function(a){var b=this,c=[],e=[];if(d(a,function(a,d){d.path===b.path?c.push(d):e.push(d)}),this.error_holder)if(c.length){this.error_holder.innerHTML="",this.error_holder.style.display="",d(c,function(a,c){b.error_holder.appendChild(b.theme.getErrorMessage(c.message))})}else this.error_holder.style.display="none";this.options.table_row&&(c.length?this.theme.addTableRowError(this.container):this.theme.removeTableRowError(this.container)),d(this.editors,function(a,b){b.showValidationErrors(e)})}}),f.defaults.editors.array=f.AbstractEditor.extend({getDefault:function(){return this.schema["default"]||[]},register:function(){if(this._super(),this.rows)for(var a=0;a<this.rows.length;a++)this.rows[a].register()},unregister:function(){if(this._super(),this.rows)for(var a=0;a<this.rows.length;a++)this.rows[a].unregister()},getNumColumns:function(){var a=this.getItemInfo(0);return this.tabs_holder?Math.max(Math.min(12,a.width+2),4):a.width},enable:function(){if(this.add_row_button&&(this.add_row_button.disabled=!1),this.remove_all_rows_button&&(this.remove_all_rows_button.disabled=!1),this.delete_last_row_button&&(this.delete_last_row_button.disabled=!1),this.rows)for(var a=0;a<this.rows.length;a++)this.rows[a].enable(),this.rows[a].moveup_button&&(this.rows[a].moveup_button.disabled=!1),this.rows[a].movedown_button&&(this.rows[a].movedown_button.disabled=!1),this.rows[a].delete_button&&(this.rows[a].delete_button.disabled=!1);this._super()},disable:function(){if(this.add_row_button&&(this.add_row_button.disabled=!0),this.remove_all_rows_button&&(this.remove_all_rows_button.disabled=!0),this.delete_last_row_button&&(this.delete_last_row_button.disabled=!0),this.rows)for(var a=0;a<this.rows.length;a++)this.rows[a].disable(),this.rows[a].moveup_button&&(this.rows[a].moveup_button.disabled=!0),this.rows[a].movedown_button&&(this.rows[a].movedown_button.disabled=!0),this.rows[a].delete_button&&(this.rows[a].delete_button.disabled=!0);this._super()},preBuild:function(){this._super(),this.rows=[],this.row_cache=[],this.hide_delete_buttons=this.options.disable_array_delete||this.jsoneditor.options.disable_array_delete,this.hide_move_buttons=this.options.disable_array_reorder||this.jsoneditor.options.disable_array_reorder,this.hide_add_button=this.options.disable_array_add||this.jsoneditor.options.disable_array_add},build:function(){this.options.compact?(this.panel=this.theme.getIndentedPanel(),this.container.appendChild(this.panel),this.controls=this.theme.getButtonHolder(),this.panel.appendChild(this.controls),this.row_holder=document.createElement("div"),this.panel.appendChild(this.row_holder)):(this.header=document.createElement("span"),this.header.textContent=this.getTitle(),this.title=this.theme.getHeader(this.header,this.isRequired()),this.container.appendChild(this.title),this.title_controls=this.theme.getHeaderButtonHolder(),this.title.appendChild(this.title_controls),this.schema.description&&(this.description=this.theme.getDescription(this.schema.description),this.container.appendChild(this.description)),this.error_holder=document.createElement("div"),this.container.appendChild(this.error_holder),"tabs"===this.schema.format?(this.controls=this.theme.getHeaderButtonHolder(),this.title.appendChild(this.controls),this.tabs_holder=this.theme.getTabHolder(),this.container.appendChild(this.tabs_holder),this.row_holder=this.theme.getTabContentHolder(this.tabs_holder),this.active_tab=null):(this.panel=this.theme.getIndentedPanel(),this.container.appendChild(this.panel),this.row_holder=document.createElement("div"),this.panel.appendChild(this.row_holder),this.controls=this.theme.getButtonHolder(),this.panel.appendChild(this.controls))),this.addControls()},onChildEditorChange:function(a){this.refreshValue(),this.refreshTabs(!0),this._super(a)},getItemTitle:function(){if(!this.item_title)if(this.schema.items&&!Array.isArray(this.schema.items)){var a=this.jsoneditor.expandRefs(this.schema.items);this.item_title=a.title||"item"}else this.item_title="item";return this.item_title},getItemSchema:function(a){return Array.isArray(this.schema.items)?a>=this.schema.items.length?this.schema.additionalItems===!0?{}:this.schema.additionalItems?c({},this.schema.additionalItems):void 0:c({},this.schema.items[a]):this.schema.items?c({},this.schema.items):{}},getItemInfo:function(a){var b=this.getItemSchema(a);this.item_info=this.item_info||{};var c=JSON.stringify(b);return"undefined"!=typeof this.item_info[c]?this.item_info[c]:(b=this.jsoneditor.expandRefs(b),this.item_info[c]={title:b.title||"item","default":b["default"],width:12,child_editors:b.properties||b.items},this.item_info[c])},getElementEditor:function(a){var b=this.getItemInfo(a),c=this.getItemSchema(a);c=this.jsoneditor.expandRefs(c),c.title=b.title+" "+(a+1);var d,e=this.jsoneditor.getEditorClass(c);d=this.tabs_holder?this.theme.getTabContent():b.child_editors?this.theme.getChildEditorHolder():this.theme.getIndentedPanel(),this.row_holder.appendChild(d);var f=this.jsoneditor.createEditor(e,{jsoneditor:this.jsoneditor,schema:c,container:d,path:this.path+"."+a,parent:this,required:!0});return f.preBuild(),f.build(),f.postBuild(),f.title_controls||(f.array_controls=this.theme.getButtonHolder(),d.appendChild(f.array_controls)),f},destroy:function(){this.empty(!0),this.title&&this.title.parentNode&&this.title.parentNode.removeChild(this.title),this.description&&this.description.parentNode&&this.description.parentNode.removeChild(this.description),this.row_holder&&this.row_holder.parentNode&&this.row_holder.parentNode.removeChild(this.row_holder),this.controls&&this.controls.parentNode&&this.controls.parentNode.removeChild(this.controls),this.panel&&this.panel.parentNode&&this.panel.parentNode.removeChild(this.panel),this.rows=this.row_cache=this.title=this.description=this.row_holder=this.panel=this.controls=null,this._super()},empty:function(a){if(this.rows){var b=this;d(this.rows,function(c,d){a&&(d.tab&&d.tab.parentNode&&d.tab.parentNode.removeChild(d.tab),b.destroyRow(d,!0),b.row_cache[c]=null),b.rows[c]=null}),b.rows=[],a&&(b.row_cache=[])}},destroyRow:function(a,b){var c=a.container;b?(a.destroy(),c.parentNode&&c.parentNode.removeChild(c),a.tab&&a.tab.parentNode&&a.tab.parentNode.removeChild(a.tab)):(a.tab&&(a.tab.style.display="none"),c.style.display="none",a.unregister())},getMax:function(){return Array.isArray(this.schema.items)&&this.schema.additionalItems===!1?Math.min(this.schema.items.length,this.schema.maxItems||1/0):this.schema.maxItems||1/0},refreshTabs:function(a){var b=this;d(this.rows,function(c,d){d.tab&&(a?d.tab_text.textContent=d.getHeaderText():d.tab===b.active_tab?(b.theme.markTabActive(d.tab),d.container.style.display=""):(b.theme.markTabInactive(d.tab),d.container.style.display="none"))})},setValue:function(a,b){a=a||[],Array.isArray(a)||(a=[a]);var c=JSON.stringify(a);if(c!==this.serialized){if(this.schema.minItems)for(;a.length<this.schema.minItems;)a.push(this.getItemInfo(a.length)["default"]);this.getMax()&&a.length>this.getMax()&&(a=a.slice(0,this.getMax()));var e=this;d(a,function(a,c){e.rows[a]?e.rows[a].setValue(c,b):e.row_cache[a]?(e.rows[a]=e.row_cache[a],e.rows[a].setValue(c,b),e.rows[a].container.style.display="",e.rows[a].tab&&(e.rows[a].tab.style.display=""),e.rows[a].register()):e.addRow(c,b)});for(var f=a.length;f<e.rows.length;f++)e.destroyRow(e.rows[f]),e.rows[f]=null;e.rows=e.rows.slice(0,a.length);var g=null;d(e.rows,function(a,b){return b.tab===e.active_tab?(g=b.tab,!1):void 0}),!g&&e.rows.length&&(g=e.rows[0].tab),e.active_tab=g,e.refreshValue(b),e.refreshTabs(!0),e.refreshTabs(),e.onChange()}},refreshValue:function(a){var b=this,c=this.value?this.value.length:0;if(this.value=[],d(this.rows,function(a,c){b.value[a]=c.getValue()}),c!==this.value.length||a){var e=this.schema.minItems&&this.schema.minItems>=this.rows.length;d(this.rows,function(a,c){c.movedown_button&&(a===b.rows.length-1?c.movedown_button.style.display="none":c.movedown_button.style.display=""),c.delete_button&&(e?c.delete_button.style.display="none":c.delete_button.style.display=""),b.value[a]=c.getValue()});var f=!1;this.value.length?1===this.value.length?(this.remove_all_rows_button.style.display="none",e||this.hide_delete_buttons?this.delete_last_row_button.style.display="none":(this.delete_last_row_button.style.display="",f=!0)):e||this.hide_delete_buttons?(this.delete_last_row_button.style.display="none",this.remove_all_rows_button.style.display="none"):(this.delete_last_row_button.style.display="",this.remove_all_rows_button.style.display="",f=!0):(this.delete_last_row_button.style.display="none",this.remove_all_rows_button.style.display="none"),this.getMax()&&this.getMax()<=this.rows.length||this.hide_add_button?this.add_row_button.style.display="none":(this.add_row_button.style.display="",f=!0),!this.collapsed&&f?this.controls.style.display="inline-block":this.controls.style.display="none"}},addRow:function(a,b){var c=this,e=this.rows.length;c.rows[e]=this.getElementEditor(e),c.row_cache[e]=c.rows[e],c.tabs_holder&&(c.rows[e].tab_text=document.createElement("span"),c.rows[e].tab_text.textContent=c.rows[e].getHeaderText(),c.rows[e].tab=c.theme.getTab(c.rows[e].tab_text),c.rows[e].tab.addEventListener("click",function(a){c.active_tab=c.rows[e].tab,c.refreshTabs(),a.preventDefault(),a.stopPropagation()}),c.theme.addTab(c.tabs_holder,c.rows[e].tab));var f=c.rows[e].title_controls||c.rows[e].array_controls;c.hide_delete_buttons||(c.rows[e].delete_button=this.getButton(c.getItemTitle(),"delete","Delete "+c.getItemTitle()),c.rows[e].delete_button.className+=" delete",c.rows[e].delete_button.setAttribute("data-i",e),c.rows[e].delete_button.addEventListener("click",function(a){a.preventDefault(),a.stopPropagation();var b=1*this.getAttribute("data-i"),e=c.getValue(),f=[],g=null;d(e,function(a,d){return a===b?void(c.rows[a].tab===c.active_tab&&(c.rows[a+1]?g=c.rows[a].tab:a&&(g=c.rows[a-1].tab))):void f.push(d)}),c.setValue(f),g&&(c.active_tab=g,c.refreshTabs()),c.onChange(!0)}),f&&f.appendChild(c.rows[e].delete_button)),e&&!c.hide_move_buttons&&(c.rows[e].moveup_button=this.getButton("","moveup","Move up"),c.rows[e].moveup_button.className+=" moveup",c.rows[e].moveup_button.setAttribute("data-i",e),c.rows[e].moveup_button.addEventListener("click",function(a){a.preventDefault(),a.stopPropagation();var b=1*this.getAttribute("data-i");if(!(0>=b)){var d=c.getValue(),e=d[b-1];d[b-1]=d[b],d[b]=e,c.setValue(d),c.active_tab=c.rows[b-1].tab,c.refreshTabs(),c.onChange(!0)}}),f&&f.appendChild(c.rows[e].moveup_button)),c.hide_move_buttons||(c.rows[e].movedown_button=this.getButton("","movedown","Move down"),c.rows[e].movedown_button.className+=" movedown",c.rows[e].movedown_button.setAttribute("data-i",e),c.rows[e].movedown_button.addEventListener("click",function(a){a.preventDefault(),a.stopPropagation();var b=1*this.getAttribute("data-i"),d=c.getValue();if(!(b>=d.length-1)){var e=d[b+1];d[b+1]=d[b],d[b]=e,c.setValue(d),c.active_tab=c.rows[b+1].tab,c.refreshTabs(),c.onChange(!0)}}),f&&f.appendChild(c.rows[e].movedown_button)),a&&c.rows[e].setValue(a,b),c.refreshTabs()},addControls:function(){var a=this;this.collapsed=!1,this.toggle_button=this.getButton("","collapse","Collapse"),this.title_controls.appendChild(this.toggle_button);var b=a.row_holder.style.display,c=a.controls.style.display;this.toggle_button.addEventListener("click",function(d){d.preventDefault(),d.stopPropagation(),a.collapsed?(a.collapsed=!1,a.panel&&(a.panel.style.display=""),a.row_holder.style.display=b,a.tabs_holder&&(a.tabs_holder.style.display=""),a.controls.style.display=c,a.setButtonText(this,"","collapse","Collapse")):(a.collapsed=!0,a.row_holder.style.display="none",a.tabs_holder&&(a.tabs_holder.style.display="none"),a.controls.style.display="none",a.panel&&(a.panel.style.display="none"),a.setButtonText(this,"","expand","Expand"))}),this.options.collapsed&&e(this.toggle_button,"click"),this.schema.options&&"undefined"!=typeof this.schema.options.disable_collapse?this.schema.options.disable_collapse&&(this.toggle_button.style.display="none"):this.jsoneditor.options.disable_collapse&&(this.toggle_button.style.display="none"),this.add_row_button=this.getButton(this.getItemTitle(),"add","Add "+this.getItemTitle()),this.add_row_button.addEventListener("click",function(b){b.preventDefault(),b.stopPropagation();var c=a.rows.length;a.row_cache[c]?(a.rows[c]=a.row_cache[c],a.rows[c].setValue(a.rows[c].getDefault()),a.rows[c].container.style.display="",a.rows[c].tab&&(a.rows[c].tab.style.display=""),a.rows[c].register()):a.addRow(),a.active_tab=a.rows[c].tab,a.refreshTabs(),a.refreshValue(),a.onChange(!0)}),a.controls.appendChild(this.add_row_button),this.delete_last_row_button=this.getButton("Last "+this.getItemTitle(),"delete","Delete Last "+this.getItemTitle()),
-this.delete_last_row_button.addEventListener("click",function(b){b.preventDefault(),b.stopPropagation();var c=a.getValue(),d=null;a.rows.length>1&&a.rows[a.rows.length-1].tab===a.active_tab&&(d=a.rows[a.rows.length-2].tab),c.pop(),a.setValue(c),d&&(a.active_tab=d,a.refreshTabs()),a.onChange(!0)}),a.controls.appendChild(this.delete_last_row_button),this.remove_all_rows_button=this.getButton("All","delete","Delete All"),this.remove_all_rows_button.addEventListener("click",function(b){b.preventDefault(),b.stopPropagation(),a.setValue([]),a.onChange(!0)}),a.controls.appendChild(this.remove_all_rows_button),a.tabs&&(this.add_row_button.style.width="100%",this.add_row_button.style.textAlign="left",this.add_row_button.style.marginBottom="3px",this.delete_last_row_button.style.width="100%",this.delete_last_row_button.style.textAlign="left",this.delete_last_row_button.style.marginBottom="3px",this.remove_all_rows_button.style.width="100%",this.remove_all_rows_button.style.textAlign="left",this.remove_all_rows_button.style.marginBottom="3px")},showValidationErrors:function(a){var b=this,c=[],e=[];if(d(a,function(a,d){d.path===b.path?c.push(d):e.push(d)}),this.error_holder)if(c.length){this.error_holder.innerHTML="",this.error_holder.style.display="",d(c,function(a,c){b.error_holder.appendChild(b.theme.getErrorMessage(c.message))})}else this.error_holder.style.display="none";d(this.rows,function(a,b){b.showValidationErrors(e)})}}),f.defaults.editors.table=f.defaults.editors.array.extend({register:function(){if(this._super(),this.rows)for(var a=0;a<this.rows.length;a++)this.rows[a].register()},unregister:function(){if(this._super(),this.rows)for(var a=0;a<this.rows.length;a++)this.rows[a].unregister()},getNumColumns:function(){return Math.max(Math.min(12,this.width),3)},preBuild:function(){var a=this.jsoneditor.expandRefs(this.schema.items||{});this.item_title=a.title||"row",this.item_default=a["default"]||null,this.item_has_child_editors=a.properties||a.items,this.width=12,this._super()},build:function(){var a=this;this.table=this.theme.getTable(),this.container.appendChild(this.table),this.thead=this.theme.getTableHead(),this.table.appendChild(this.thead),this.header_row=this.theme.getTableRow(),this.thead.appendChild(this.header_row),this.row_holder=this.theme.getTableBody(),this.table.appendChild(this.row_holder);var b=this.getElementEditor(0,!0);if(this.item_default=b.getDefault(),this.width=b.getNumColumns()+2,this.options.compact?(this.panel=document.createElement("div"),this.container.appendChild(this.panel)):(this.title=this.theme.getHeader(this.getTitle(),this.isRequired()),this.container.appendChild(this.title),this.title_controls=this.theme.getHeaderButtonHolder(),this.title.appendChild(this.title_controls),this.schema.description&&(this.description=this.theme.getDescription(this.schema.description),this.container.appendChild(this.description)),this.panel=this.theme.getIndentedPanel(),this.container.appendChild(this.panel),this.error_holder=document.createElement("div"),this.panel.appendChild(this.error_holder)),this.panel.appendChild(this.table),this.controls=this.theme.getButtonHolder(),this.panel.appendChild(this.controls),this.item_has_child_editors)for(var c=b.getChildEditors(),d=b.property_order||Object.keys(c),e=0;e<d.length;e++){var f=a.theme.getTableHeaderCell(c[d[e]].getTitle());c[d[e]].options.hidden&&(f.style.display="none"),a.header_row.appendChild(f)}else a.header_row.appendChild(a.theme.getTableHeaderCell(this.item_title));b.destroy(),this.row_holder.innerHTML="",this.controls_header_cell=a.theme.getTableHeaderCell(" "),a.header_row.appendChild(this.controls_header_cell),this.addControls()},onChildEditorChange:function(a){this.refreshValue(),this._super()},getItemDefault:function(){return c({},{"default":this.item_default})["default"]},getItemTitle:function(){return this.item_title},getElementEditor:function(a,b){var d=c({},this.schema.items),e=this.jsoneditor.getEditorClass(d,this.jsoneditor),f=this.row_holder.appendChild(this.theme.getTableRow()),g=f;this.item_has_child_editors||(g=this.theme.getTableCell(),f.appendChild(g));var h=this.jsoneditor.createEditor(e,{jsoneditor:this.jsoneditor,schema:d,container:g,path:this.path+"."+a,parent:this,compact:!0,table_row:!0});return h.preBuild(),b||(h.build(),h.postBuild(),h.controls_cell=f.appendChild(this.theme.getTableCell()),h.row=f,h.table_controls=this.theme.getButtonHolder(),h.controls_cell.appendChild(h.table_controls),h.table_controls.style.margin=0,h.table_controls.style.padding=0),h},destroy:function(){this.innerHTML="",this.title&&this.title.parentNode&&this.title.parentNode.removeChild(this.title),this.description&&this.description.parentNode&&this.description.parentNode.removeChild(this.description),this.row_holder&&this.row_holder.parentNode&&this.row_holder.parentNode.removeChild(this.row_holder),this.table&&this.table.parentNode&&this.table.parentNode.removeChild(this.table),this.panel&&this.panel.parentNode&&this.panel.parentNode.removeChild(this.panel),this.rows=this.title=this.description=this.row_holder=this.table=this.panel=null,this._super()},setValue:function(a,b){if(a=a||[],this.schema.minItems)for(;a.length<this.schema.minItems;)a.push(this.getItemDefault());this.schema.maxItems&&a.length>this.schema.maxItems&&(a=a.slice(0,this.schema.maxItems));var c=JSON.stringify(a);if(c!==this.serialized){var e=!1,f=this;d(a,function(a,b){f.rows[a]?f.rows[a].setValue(b):(f.addRow(b),e=!0)});for(var g=a.length;g<f.rows.length;g++){var h=f.rows[g].container;f.item_has_child_editors||f.rows[g].row.parentNode.removeChild(f.rows[g].row),f.rows[g].destroy(),h.parentNode&&h.parentNode.removeChild(h),f.rows[g]=null,e=!0}f.rows=f.rows.slice(0,a.length),f.refreshValue(),(e||b)&&f.refreshRowButtons(),f.onChange()}},refreshRowButtons:function(){var a=this,b=this.schema.minItems&&this.schema.minItems>=this.rows.length,c=!1;d(this.rows,function(d,e){e.movedown_button&&(d===a.rows.length-1?e.movedown_button.style.display="none":(c=!0,e.movedown_button.style.display="")),e.delete_button&&(b?e.delete_button.style.display="none":(c=!0,e.delete_button.style.display="")),e.moveup_button&&(c=!0)}),d(this.rows,function(a,b){c?b.controls_cell.style.display="":b.controls_cell.style.display="none"}),c?this.controls_header_cell.style.display="":this.controls_header_cell.style.display="none";var e=!1;this.value.length?1===this.value.length||this.hide_delete_buttons?(this.table.style.display="",this.remove_all_rows_button.style.display="none",b||this.hide_delete_buttons?this.delete_last_row_button.style.display="none":(this.delete_last_row_button.style.display="",e=!0)):(this.table.style.display="",b||this.hide_delete_buttons?(this.delete_last_row_button.style.display="none",this.remove_all_rows_button.style.display="none"):(this.delete_last_row_button.style.display="",this.remove_all_rows_button.style.display="",e=!0)):(this.delete_last_row_button.style.display="none",this.remove_all_rows_button.style.display="none",this.table.style.display="none"),this.schema.maxItems&&this.schema.maxItems<=this.rows.length||this.hide_add_button?this.add_row_button.style.display="none":(this.add_row_button.style.display="",e=!0),e?this.controls.style.display="":this.controls.style.display="none"},refreshValue:function(){var a=this;this.value=[],d(this.rows,function(b,c){a.value[b]=c.getValue()}),this.serialized=JSON.stringify(this.value)},addRow:function(a){var b=this,c=this.rows.length;b.rows[c]=this.getElementEditor(c);var e=b.rows[c].table_controls;this.hide_delete_buttons||(b.rows[c].delete_button=this.getButton("","delete","Delete"),b.rows[c].delete_button.className+=" delete",b.rows[c].delete_button.setAttribute("data-i",c),b.rows[c].delete_button.addEventListener("click",function(a){a.preventDefault(),a.stopPropagation();var c=1*this.getAttribute("data-i"),e=b.getValue(),f=[];d(e,function(a,b){a!==c&&f.push(b)}),b.setValue(f),b.onChange(!0)}),e.appendChild(b.rows[c].delete_button)),c&&!this.hide_move_buttons&&(b.rows[c].moveup_button=this.getButton("","moveup","Move up"),b.rows[c].moveup_button.className+=" moveup",b.rows[c].moveup_button.setAttribute("data-i",c),b.rows[c].moveup_button.addEventListener("click",function(a){a.preventDefault(),a.stopPropagation();var c=1*this.getAttribute("data-i");if(!(0>=c)){var d=b.getValue(),e=d[c-1];d[c-1]=d[c],d[c]=e,b.setValue(d),b.onChange(!0)}}),e.appendChild(b.rows[c].moveup_button)),this.hide_move_buttons||(b.rows[c].movedown_button=this.getButton("","movedown","Move down"),b.rows[c].movedown_button.className+=" movedown",b.rows[c].movedown_button.setAttribute("data-i",c),b.rows[c].movedown_button.addEventListener("click",function(a){a.preventDefault(),a.stopPropagation();var c=1*this.getAttribute("data-i"),d=b.getValue();if(!(c>=d.length-1)){var e=d[c+1];d[c+1]=d[c],d[c]=e,b.setValue(d),b.onChange(!0)}}),e.appendChild(b.rows[c].movedown_button)),a&&b.rows[c].setValue(a)},addControls:function(){var a=this;this.collapsed=!1,this.toggle_button=this.getButton("","collapse","Collapse"),this.title_controls&&(this.title_controls.appendChild(this.toggle_button),this.toggle_button.addEventListener("click",function(b){b.preventDefault(),b.stopPropagation(),a.collapsed?(a.collapsed=!1,a.panel.style.display="",a.setButtonText(this,"","collapse","Collapse")):(a.collapsed=!0,a.panel.style.display="none",a.setButtonText(this,"","expand","Expand"))}),this.options.collapsed&&e(this.toggle_button,"click"),this.schema.options&&"undefined"!=typeof this.schema.options.disable_collapse?this.schema.options.disable_collapse&&(this.toggle_button.style.display="none"):this.jsoneditor.options.disable_collapse&&(this.toggle_button.style.display="none")),this.add_row_button=this.getButton(this.getItemTitle(),"add","Add "+this.getItemTitle()),this.add_row_button.addEventListener("click",function(b){b.preventDefault(),b.stopPropagation(),a.addRow(),a.refreshValue(),a.refreshRowButtons(),a.onChange(!0)}),a.controls.appendChild(this.add_row_button),this.delete_last_row_button=this.getButton("Last "+this.getItemTitle(),"delete","Delete Last "+this.getItemTitle()),this.delete_last_row_button.addEventListener("click",function(b){b.preventDefault(),b.stopPropagation();var c=a.getValue();c.pop(),a.setValue(c),a.onChange(!0)}),a.controls.appendChild(this.delete_last_row_button),this.remove_all_rows_button=this.getButton("All","delete","Delete All"),this.remove_all_rows_button.addEventListener("click",function(b){b.preventDefault(),b.stopPropagation(),a.setValue([]),a.onChange(!0)}),a.controls.appendChild(this.remove_all_rows_button)}}),f.defaults.editors.multiple=f.AbstractEditor.extend({register:function(){if(this.editors){for(var a=0;a<this.editors.length;a++)this.editors[a]&&this.editors[a].unregister();this.editors[this.type]&&this.editors[this.type].register()}this._super()},unregister:function(){if(this._super(),this.editors)for(var a=0;a<this.editors.length;a++)this.editors[a]&&this.editors[a].unregister()},getNumColumns:function(){return this.editors[this.type]?Math.max(this.editors[this.type].getNumColumns(),4):4},enable:function(){if(this.editors)for(var a=0;a<this.editors.length;a++)this.editors[a]&&this.editors[a].enable();this.switcher.disabled=!1,this._super()},disable:function(){if(this.editors)for(var a=0;a<this.editors.length;a++)this.editors[a]&&this.editors[a].disable();this.switcher.disabled=!0,this._super()},switchEditor:function(a){var b=this;this.editors[a]||this.buildChildEditor(a),b.type=a,b.register();var c=b.getValue();d(b.editors,function(a,d){d&&(b.type===a?(b.keep_values&&d.setValue(c,!0),d.container.style.display=""):d.container.style.display="none")}),b.refreshValue(),b.refreshHeaderText()},buildChildEditor:function(a){var b=this,d=this.types[a],e=b.theme.getChildEditorHolder();b.editor_holder.appendChild(e);var f;"string"==typeof d?(f=c({},b.schema),f.type=d):(f=c({},b.schema,d),f=b.jsoneditor.expandRefs(f),d.required&&Array.isArray(d.required)&&b.schema.required&&Array.isArray(b.schema.required)&&(f.required=b.schema.required.concat(d.required)));var g=b.jsoneditor.getEditorClass(f);b.editors[a]=b.jsoneditor.createEditor(g,{jsoneditor:b.jsoneditor,schema:f,container:e,path:b.path,parent:b,required:!0}),b.editors[a].preBuild(),b.editors[a].build(),b.editors[a].postBuild(),b.editors[a].header&&(b.editors[a].header.style.display="none"),b.editors[a].option=b.switcher_options[a],e.addEventListener("change_header_text",function(){b.refreshHeaderText()}),a!==b.type&&(e.style.display="none")},preBuild:function(){if(this.types=[],this.type=0,this.editors=[],this.validators=[],this.keep_values=!0,"undefined"!=typeof this.jsoneditor.options.keep_oneof_values&&(this.keep_values=this.jsoneditor.options.keep_oneof_values),"undefined"!=typeof this.options.keep_oneof_values&&(this.keep_values=this.options.keep_oneof_values),this.schema.oneOf)this.oneOf=!0,this.types=this.schema.oneOf,d(this.types,function(a,b){}),delete this.schema.oneOf;else{if(this.schema.type&&"any"!==this.schema.type)Array.isArray(this.schema.type)?this.types=this.schema.type:this.types=[this.schema.type];else if(this.types=["string","number","integer","boolean","object","array","null"],this.schema.disallow){var a=this.schema.disallow;"object"==typeof a&&Array.isArray(a)||(a=[a]);var b=[];d(this.types,function(c,d){-1===a.indexOf(d)&&b.push(d)}),this.types=b}delete this.schema.type}this.display_text=this.getDisplayText(this.types)},build:function(){var a=this,b=this.container;this.header=this.label=this.theme.getFormInputLabel(this.getTitle(),this.isRequired()),this.container.appendChild(this.header),this.switcher=this.theme.getSwitcher(this.display_text),b.appendChild(this.switcher),this.switcher.addEventListener("change",function(b){b.preventDefault(),b.stopPropagation(),a.switchEditor(a.display_text.indexOf(this.value)),a.onChange(!0)}),this.editor_holder=document.createElement("div"),b.appendChild(this.editor_holder),this.switcher_options=this.theme.getSwitcherOptions(this.switcher),d(this.types,function(b,d){a.editors[b]=!1;var e;"string"==typeof d?(e=c({},a.schema),e.type=d):(e=c({},a.schema,d),d.required&&Array.isArray(d.required)&&a.schema.required&&Array.isArray(a.schema.required)&&(e.required=a.schema.required.concat(d.required))),a.validators[b]=new f.Validator(a.jsoneditor,e)}),this.switchEditor(0)},onChildEditorChange:function(a){this.editors[this.type]&&(this.refreshValue(),this.refreshHeaderText()),this._super()},refreshHeaderText:function(){var a=this.getDisplayText(this.types);d(this.switcher_options,function(b,c){c.textContent=a[b]})},refreshValue:function(){this.value=this.editors[this.type].getValue()},setValue:function(a,b){var c=this;d(this.validators,function(b,d){return d.validate(a).length?void 0:(c.type=b,c.switcher.value=c.display_text[b],!1)}),this.switchEditor(this.type),this.editors[this.type].setValue(a,b),this.refreshValue(),c.onChange()},destroy:function(){d(this.editors,function(a,b){b&&b.destroy()}),this.editor_holder&&this.editor_holder.parentNode&&this.editor_holder.parentNode.removeChild(this.editor_holder),this.switcher&&this.switcher.parentNode&&this.switcher.parentNode.removeChild(this.switcher),this._super()},showValidationErrors:function(a){var b=this;this.oneOf?d(this.editors,function(e,f){if(f){var g=b.path+".oneOf["+e+"]",h=[];d(a,function(a,d){if(d.path.substr(0,g.length)===g){var e=c({},d);e.path=b.path+e.path.substr(g.length),h.push(e)}}),f.showValidationErrors(h)}}):d(this.editors,function(b,c){c&&c.showValidationErrors(a)})}}),f.defaults.editors["enum"]=f.AbstractEditor.extend({getNumColumns:function(){return 4},build:function(){this.container;this.title=this.header=this.label=this.theme.getFormInputLabel(this.getTitle(),this.isRequired()),this.container.appendChild(this.title),this.options.enum_titles=this.options.enum_titles||[],this["enum"]=this.schema["enum"],this.selected=0,this.select_options=[],this.html_values=[];for(var a=this,b=0;b<this["enum"].length;b++)this.select_options[b]=this.options.enum_titles[b]||"Value "+(b+1),this.html_values[b]=this.getHTML(this["enum"][b]);this.switcher=this.theme.getSwitcher(this.select_options),this.container.appendChild(this.switcher),this.display_area=this.theme.getIndentedPanel(),this.container.appendChild(this.display_area),this.options.hide_display&&(this.display_area.style.display="none"),this.switcher.addEventListener("change",function(){a.selected=a.select_options.indexOf(this.value),a.value=a["enum"][a.selected],a.refreshValue(),a.onChange(!0)}),this.value=this["enum"][0],this.refreshValue(),1===this["enum"].length&&(this.switcher.style.display="none")},refreshValue:function(){var a=this;a.selected=-1;var b=JSON.stringify(this.value);return d(this["enum"],function(c,d){return b===JSON.stringify(d)?(a.selected=c,!1):void 0}),a.selected<0?void a.setValue(a["enum"][0]):(this.switcher.value=this.select_options[this.selected],void(this.display_area.innerHTML=this.html_values[this.selected]))},enable:function(){this.always_disabled||(this.switcher.disabled=!1),this._super()},disable:function(){this.switcher.disabled=!0,this._super()},getHTML:function(a){var b=this;if(null===a)return"<em>null</em>";if("object"==typeof a){var c="";return d(a,function(d,e){var f=b.getHTML(e);Array.isArray(a)||(f="<div><em>"+d+"</em>: "+f+"</div>"),c+="<li>"+f+"</li>"}),c=Array.isArray(a)?"<ol>"+c+"</ol>":"<ul style='margin-top:0;margin-bottom:0;padding-top:0;padding-bottom:0;'>"+c+"</ul>"}return"boolean"==typeof a?a?"true":"false":"string"==typeof a?a.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;"):a},setValue:function(a){this.value!==a&&(this.value=a,this.refreshValue(),this.onChange())},destroy:function(){this.display_area&&this.display_area.parentNode&&this.display_area.parentNode.removeChild(this.display_area),this.title&&this.title.parentNode&&this.title.parentNode.removeChild(this.title),this.switcher&&this.switcher.parentNode&&this.switcher.parentNode.removeChild(this.switcher),this._super()}}),f.defaults.editors.select=f.AbstractEditor.extend({setValue:function(a,b){a=this.typecast(a||"");var c=a;this.enum_values.indexOf(c)<0&&(c=this.enum_values[0]),this.value!==c&&(this.input.value=this.enum_options[this.enum_values.indexOf(c)],this.select2&&this.select2.select2("val",this.input.value),this.value=c,this.onChange())},register:function(){this._super(),this.input&&this.input.setAttribute("name",this.formname)},unregister:function(){this._super(),this.input&&this.input.removeAttribute("name")},getNumColumns:function(){if(!this.enum_options)return 3;for(var a=this.getTitle().length,b=0;b<this.enum_options.length;b++)a=Math.max(a,this.enum_options[b].length+4);return Math.min(12,Math.max(a/7,2))},typecast:function(a){return"boolean"===this.schema.type?!!a:"number"===this.schema.type?1*a:"integer"===this.schema.type?Math.floor(1*a):""+a},getValue:function(){return this.value},preBuild:function(){var a=this;if(this.input_type="select",this.enum_options=[],this.enum_values=[],this.enum_display=[],this.schema["enum"]){var b=this.schema.options&&this.schema.options.enum_titles||[];d(this.schema["enum"],function(c,d){a.enum_options[c]=""+d,a.enum_display[c]=""+(b[c]||d),a.enum_values[c]=a.typecast(d)}),this.isRequired()||(a.enum_display.unshift(" "),a.enum_options.unshift("undefined"),a.enum_values.unshift(void 0))}else if("boolean"===this.schema.type)a.enum_display=this.schema.options&&this.schema.options.enum_titles||["true","false"],a.enum_options=["1",""],a.enum_values=[!0,!1],this.isRequired()||(a.enum_display.unshift(" "),a.enum_options.unshift("undefined"),a.enum_values.unshift(void 0));else{if(!this.schema.enumSource)throw"'select' editor requires the enum property to be set.";if(this.enumSource=[],this.enum_display=[],this.enum_options=[],this.enum_values=[],Array.isArray(this.schema.enumSource))for(h=0;h<this.schema.enumSource.length;h++)"string"==typeof this.schema.enumSource[h]?this.enumSource[h]={source:this.schema.enumSource[h]}:Array.isArray(this.schema.enumSource[h])?this.enumSource[h]=this.schema.enumSource[h]:this.enumSource[h]=c({},this.schema.enumSource[h]);else this.schema.enumValue?this.enumSource=[{source:this.schema.enumSource,value:this.schema.enumValue}]:this.enumSource=[{source:this.schema.enumSource}];for(h=0;h<this.enumSource.length;h++)this.enumSource[h].value&&(this.enumSource[h].value=this.jsoneditor.compileTemplate(this.enumSource[h].value,this.template_engine)),this.enumSource[h].title&&(this.enumSource[h].title=this.jsoneditor.compileTemplate(this.enumSource[h].title,this.template_engine)),this.enumSource[h].filter&&(this.enumSource[h].filter=this.jsoneditor.compileTemplate(this.enumSource[h].filter,this.template_engine))}},build:function(){var a=this;this.options.compact||(this.header=this.label=this.theme.getFormInputLabel(this.getTitle(),this.isRequired())),this.schema.description&&(this.description=this.theme.getFormInputDescription(this.schema.description)),this.options.compact&&(this.container.className+=" compact"),this.input=this.theme.getSelectInput(this.enum_options),this.theme.setSelectOptions(this.input,this.enum_options,this.enum_display),(this.schema.readOnly||this.schema.readonly)&&(this.always_disabled=!0,this.input.disabled=!0),this.input.addEventListener("change",function(b){b.preventDefault(),b.stopPropagation(),a.onInputChange()}),this.control=this.theme.getFormControl(this.label,this.input,this.description),this.container.appendChild(this.control),this.value=this.enum_values[0]},onInputChange:function(){var a=this.input.value,b=a;-1===this.enum_options.indexOf(a)&&(b=this.enum_options[0]),this.value=this.enum_values[this.enum_options.indexOf(a)],this.onChange(!0)},setupSelect2:function(){if(window.jQuery&&window.jQuery.fn&&window.jQuery.fn.select2&&(this.enum_options.length>2||this.enum_options.length&&this.enumSource)){var a=c({},f.plugins.select2);this.schema.options&&this.schema.options.select2_options&&(a=c(a,this.schema.options.select2_options)),this.select2=window.jQuery(this.input).select2(a);var b=this;this.select2.on("select2-blur",function(){b.input.value=b.select2.select2("val"),b.onInputChange()})}else this.select2=null},postBuild:function(){this._super(),this.theme.afterInputReady(this.input),this.setupSelect2()},onWatchedFieldChange:function(){var a,b;if(this.enumSource){a=this.getWatchedFieldValues();for(var c=[],d=[],e=0;e<this.enumSource.length;e++)if(Array.isArray(this.enumSource[e]))c=c.concat(this.enumSource[e]),d=d.concat(this.enumSource[e]);else{var f=[];if(f=Array.isArray(this.enumSource[e].source)?this.enumSource[e].source:a[this.enumSource[e].source]){if(this.enumSource[e].slice&&(f=Array.prototype.slice.apply(f,this.enumSource[e].slice)),this.enumSource[e].filter){var g=[];for(b=0;b<f.length;b++)this.enumSource[e].filter({i:b,item:f[b],watched:a})&&g.push(f[b]);f=g}var h=[],i=[];for(b=0;b<f.length;b++){var j=f[b];this.enumSource[e].value?i[b]=this.enumSource[e].value({i:b,item:j}):i[b]=f[b],this.enumSource[e].title?h[b]=this.enumSource[e].title({i:b,item:j}):h[b]=i[b]}c=c.concat(i),d=d.concat(h)}}var k=this.value;this.theme.setSelectOptions(this.input,c,d),this.enum_options=c,this.enum_display=d,this.enum_values=c,this.select2&&this.select2.select2("destroy"),-1!==c.indexOf(k)?(this.input.value=k,this.value=k):(this.input.value=c[0],this.value=c[0]||"",this.parent?this.parent.onChildEditorChange(this):this.jsoneditor.onChange(),this.jsoneditor.notifyWatchers(this.path)),this.setupSelect2()}this._super()},enable:function(){this.always_disabled||(this.input.disabled=!1,this.select2&&this.select2.select2("enable",!0)),this._super()},disable:function(){this.input.disabled=!0,this.select2&&this.select2.select2("enable",!1),this._super()},destroy:function(){this.label&&this.label.parentNode&&this.label.parentNode.removeChild(this.label),this.description&&this.description.parentNode&&this.description.parentNode.removeChild(this.description),this.input&&this.input.parentNode&&this.input.parentNode.removeChild(this.input),this.select2&&(this.select2.select2("destroy"),this.select2=null),this._super()}}),f.defaults.editors.multiselect=f.AbstractEditor.extend({preBuild:function(){this._super(),this.select_options={},this.select_values={};var a=this.jsoneditor.expandRefs(this.schema.items||{}),b=a["enum"]||[];for(this.option_keys=[],h=0;h<b.length;h++)this.sanitize(b[h])===b[h]&&(this.option_keys.push(b[h]+""),this.select_values[b[h]+""]=b[h])},build:function(){var a,b=this;if(this.options.compact||(this.header=this.label=this.theme.getFormInputLabel(this.getTitle(),this.isRequired())),this.schema.description&&(this.description=this.theme.getFormInputDescription(this.schema.description)),!this.schema.format&&this.option_keys.length<8||"checkbox"===this.schema.format){for(this.input_type="checkboxes",this.inputs={},this.controls={},a=0;a<this.option_keys.length;a++){this.inputs[this.option_keys[a]]=this.theme.getCheckbox(),this.select_options[this.option_keys[a]]=this.inputs[this.option_keys[a]];var c=this.theme.getCheckboxLabel(this.option_keys[a]);this.controls[this.option_keys[a]]=this.theme.getFormControl(c,this.inputs[this.option_keys[a]])}this.control=this.theme.getMultiCheckboxHolder(this.controls,this.label,this.description)}else{for(this.input_type="select",this.input=this.theme.getSelectInput(this.option_keys),this.input.multiple=!0,this.input.size=Math.min(10,this.option_keys.length),a=0;a<this.option_keys.length;a++)this.select_options[this.option_keys[a]]=this.input.children[a];(this.schema.readOnly||this.schema.readonly)&&(this.always_disabled=!0,this.input.disabled=!0),this.control=this.theme.getFormControl(this.label,this.input,this.description)}this.container.appendChild(this.control),this.control.addEventListener("change",function(c){c.preventDefault(),c.stopPropagation();var d=[];for(a=0;a<b.option_keys.length;a++)(b.select_options[b.option_keys[a]].selected||b.select_options[b.option_keys[a]].checked)&&d.push(b.select_values[b.option_keys[a]]);b.updateValue(d),b.onChange(!0)})},setValue:function(a,b){var c;for(a=a||[],"object"!=typeof a?a=[a]:Array.isArray(a)||(a=[]),c=0;c<a.length;c++)"string"!=typeof a[c]&&(a[c]+="");for(c in this.select_options)this.select_options.hasOwnProperty(c)&&(this.select_options[c]["select"===this.input_type?"selected":"checked"]=-1!==a.indexOf(c));this.updateValue(a),this.onChange()},setupSelect2:function(){if(window.jQuery&&window.jQuery.fn&&window.jQuery.fn.select2){var a=window.jQuery.extend({},f.plugins.select2);this.schema.options&&this.schema.options.select2_options&&(a=c(a,this.schema.options.select2_options)),this.select2=window.jQuery(this.input).select2(a);var b=this;this.select2.on("select2-blur",function(){var a=b.select2.select2("val");b.value=a,b.onChange(!0)})}else this.select2=null},onInputChange:function(){this.value=this.input.value,this.onChange(!0)},postBuild:function(){this._super(),this.setupSelect2()},register:function(){this._super(),this.input&&this.input.setAttribute("name",this.formname)},unregister:function(){this._super(),this.input&&this.input.removeAttribute("name")},getNumColumns:function(){var a=this.getTitle().length;for(var b in this.select_values)this.select_values.hasOwnProperty(b)&&(a=Math.max(a,(this.select_values[b]+"").length+4));return Math.min(12,Math.max(a/7,2))},updateValue:function(a){for(var b=!1,c=[],d=0;d<a.length;d++)if(this.select_options[a[d]+""]){var e=this.sanitize(this.select_values[a[d]]);c.push(e),e!==a[d]&&(b=!0)}else b=!0;return this.value=c,this.select2&&this.select2.select2("val",this.value),b},sanitize:function(a){return"number"===this.schema.items.type?1*a:"integer"===this.schema.items.type?Math.floor(1*a):""+a},enable:function(){if(!this.always_disabled){if(this.input)this.input.disabled=!1;else if(this.inputs)for(var a in this.inputs)this.inputs.hasOwnProperty(a)&&(this.inputs[a].disabled=!1);this.select2&&this.select2.select2("enable",!0)}this._super()},disable:function(){if(this.input)this.input.disabled=!0;else if(this.inputs)for(var a in this.inputs)this.inputs.hasOwnProperty(a)&&(this.inputs[a].disabled=!0);this.select2&&this.select2.select2("enable",!1),this._super()},destroy:function(){this.select2&&(this.select2.select2("destroy"),this.select2=null),this._super()}}),f.defaults.editors.base64=f.AbstractEditor.extend({getNumColumns:function(){return 4},build:function(){var a=this;if(this.title=this.header=this.label=this.theme.getFormInputLabel(this.getTitle(),this.isRequired()),this.input=this.theme.getFormInputField("hidden"),this.container.appendChild(this.input),!this.schema.readOnly&&!this.schema.readonly){if(!window.FileReader)throw"FileReader required for base64 editor";this.uploader=this.theme.getFormInputField("file"),this.uploader.addEventListener("change",function(b){if(b.preventDefault(),b.stopPropagation(),this.files&&this.files.length){var c=new FileReader;c.onload=function(b){a.value=b.target.result,a.refreshPreview(),a.onChange(!0),c=null},c.readAsDataURL(this.files[0])}})}this.preview=this.theme.getFormInputDescription(this.schema.description),this.container.appendChild(this.preview),this.control=this.theme.getFormControl(this.label,this.uploader||this.input,this.preview),this.container.appendChild(this.control)},refreshPreview:function(){if(this.last_preview!==this.value&&(this.last_preview=this.value,this.preview.innerHTML="",this.value)){var a=this.value.match(/^data:([^;,]+)[;,]/);if(a&&(a=a[1]),a){if(this.preview.innerHTML="<strong>Type:</strong> "+a+", <strong>Size:</strong> "+Math.floor((this.value.length-this.value.split(",")[0].length-1)/1.33333)+" bytes","image"===a.substr(0,5)){this.preview.innerHTML+="<br>";var b=document.createElement("img");b.style.maxWidth="100%",b.style.maxHeight="100px",b.src=this.value,this.preview.appendChild(b)}}else this.preview.innerHTML="<em>Invalid data URI</em>"}},enable:function(){this.uploader&&(this.uploader.disabled=!1),this._super()},disable:function(){this.uploader&&(this.uploader.disabled=!0),this._super()},setValue:function(a){this.value!==a&&(this.value=a,this.input.value=this.value,this.refreshPreview(),this.onChange())},destroy:function(){this.preview&&this.preview.parentNode&&this.preview.parentNode.removeChild(this.preview),this.title&&this.title.parentNode&&this.title.parentNode.removeChild(this.title),this.input&&this.input.parentNode&&this.input.parentNode.removeChild(this.input),this.uploader&&this.uploader.parentNode&&this.uploader.parentNode.removeChild(this.uploader),this._super()}}),f.defaults.editors.upload=f.AbstractEditor.extend({getNumColumns:function(){return 4},build:function(){var a=this;if(this.title=this.header=this.label=this.theme.getFormInputLabel(this.getTitle(),this.isRequired()),this.input=this.theme.getFormInputField("hidden"),this.container.appendChild(this.input),!this.schema.readOnly&&!this.schema.readonly){if(!this.jsoneditor.options.upload)throw"Upload handler required for upload editor";this.uploader=this.theme.getFormInputField("file"),this.uploader.addEventListener("change",function(b){if(b.preventDefault(),b.stopPropagation(),this.files&&this.files.length){var c=new FileReader;c.onload=function(b){a.preview_value=b.target.result,a.refreshPreview(),a.onChange(!0),c=null},c.readAsDataURL(this.files[0])}})}var b=this.schema.description;b||(b=""),this.preview=this.theme.getFormInputDescription(b),this.container.appendChild(this.preview),this.control=this.theme.getFormControl(this.label,this.uploader||this.input,this.preview),this.container.appendChild(this.control)},refreshPreview:function(){if(this.last_preview!==this.preview_value&&(this.last_preview=this.preview_value,this.preview.innerHTML="",this.preview_value)){var a=this,b=this.preview_value.match(/^data:([^;,]+)[;,]/);b&&(b=b[1]),b||(b="unknown");var c=this.uploader.files[0];if(this.preview.innerHTML="<strong>Type:</strong> "+b+", <strong>Size:</strong> "+c.size+" bytes","image"===b.substr(0,5)){this.preview.innerHTML+="<br>";var d=document.createElement("img");d.style.maxWidth="100%",d.style.maxHeight="100px",d.src=this.preview_value,
-this.preview.appendChild(d)}this.preview.innerHTML+="<br>";var e=this.getButton("Upload","upload","Upload");this.preview.appendChild(e),e.addEventListener("click",function(b){b.preventDefault(),e.setAttribute("disabled","disabled"),a.theme.removeInputError(a.uploader),a.theme.getProgressBar&&(a.progressBar=a.theme.getProgressBar(),a.preview.appendChild(a.progressBar)),a.jsoneditor.options.upload(a.path,c,{success:function(b){a.setValue(b),a.parent?a.parent.onChildEditorChange(a):a.jsoneditor.onChange(),a.progressBar&&a.preview.removeChild(a.progressBar),e.removeAttribute("disabled")},failure:function(b){a.theme.addInputError(a.uploader,b),a.progressBar&&a.preview.removeChild(a.progressBar),e.removeAttribute("disabled")},updateProgress:function(b){a.progressBar&&(b?a.theme.updateProgressBar(a.progressBar,b):a.theme.updateProgressBarUnknown(a.progressBar))}})})}},enable:function(){this.uploader&&(this.uploader.disabled=!1),this._super()},disable:function(){this.uploader&&(this.uploader.disabled=!0),this._super()},setValue:function(a){this.value!==a&&(this.value=a,this.input.value=this.value,this.onChange())},destroy:function(){this.preview&&this.preview.parentNode&&this.preview.parentNode.removeChild(this.preview),this.title&&this.title.parentNode&&this.title.parentNode.removeChild(this.title),this.input&&this.input.parentNode&&this.input.parentNode.removeChild(this.input),this.uploader&&this.uploader.parentNode&&this.uploader.parentNode.removeChild(this.uploader),this._super()}}),f.defaults.editors.checkbox=f.AbstractEditor.extend({setValue:function(a,b){this.value=!!a,this.input.checked=this.value,this.onChange()},register:function(){this._super(),this.input&&this.input.setAttribute("name",this.formname)},unregister:function(){this._super(),this.input&&this.input.removeAttribute("name")},getNumColumns:function(){return Math.min(12,Math.max(this.getTitle().length/7,2))},build:function(){var a=this;this.options.compact||(this.label=this.header=this.theme.getCheckboxLabel(this.getTitle())),this.schema.description&&(this.description=this.theme.getFormInputDescription(this.schema.description)),this.options.compact&&(this.container.className+=" compact"),this.input=this.theme.getCheckbox(),this.control=this.theme.getFormControl(this.label,this.input,this.description),(this.schema.readOnly||this.schema.readonly)&&(this.always_disabled=!0,this.input.disabled=!0),this.input.addEventListener("change",function(b){b.preventDefault(),b.stopPropagation(),a.value=this.checked,a.onChange(!0)}),this.container.appendChild(this.control)},enable:function(){this.always_disabled||(this.input.disabled=!1),this._super()},disable:function(){this.input.disabled=!0,this._super()},destroy:function(){this.label&&this.label.parentNode&&this.label.parentNode.removeChild(this.label),this.description&&this.description.parentNode&&this.description.parentNode.removeChild(this.description),this.input&&this.input.parentNode&&this.input.parentNode.removeChild(this.input),this._super()}});var g=function(){var a=document.documentElement;return a.matches?"matches":a.webkitMatchesSelector?"webkitMatchesSelector":a.mozMatchesSelector?"mozMatchesSelector":a.msMatchesSelector?"msMatchesSelector":a.oMatchesSelector?"oMatchesSelector":void 0}();f.AbstractTheme=a.extend({getContainer:function(){return document.createElement("div")},getFloatRightLinkHolder:function(){var a=document.createElement("div");return a.style=a.style||{},a.style.cssFloat="right",a.style.marginLeft="10px",a},getModal:function(){var a=document.createElement("div");return a.style.backgroundColor="white",a.style.border="1px solid black",a.style.boxShadow="3px 3px black",a.style.position="absolute",a.style.zIndex="10",a.style.display="none",a},getGridContainer:function(){var a=document.createElement("div");return a},getGridRow:function(){var a=document.createElement("div");return a.className="row",a},getGridColumn:function(){var a=document.createElement("div");return a},setGridColumnSize:function(a,b){},getLink:function(a){var b=document.createElement("a");return b.setAttribute("href","#"),b.appendChild(document.createTextNode(a)),b},disableHeader:function(a){a.style.color="#ccc"},disableLabel:function(a){a.style.color="#ccc"},enableHeader:function(a){a.style.color=""},enableLabel:function(a){a.style.color=""},getFormInputLabel:function(a){var b=document.createElement("label");return b.appendChild(document.createTextNode(a)),b},getCheckboxLabel:function(a){var b=this.getFormInputLabel(a);return b.style.fontWeight="normal",b},getHeader:function(a,b){var c=document.createElement("h3");return"string"==typeof a?c.textContent=a:c.appendChild(a),b&&(c.className+=" required"),c},getCheckbox:function(){var a=this.getFormInputField("checkbox");return a.style.display="inline-block",a.style.width="auto",a},getMultiCheckboxHolder:function(a,b,c){var d=document.createElement("div");b&&(b.style.display="block",d.appendChild(b));for(var e in a)a.hasOwnProperty(e)&&(a[e].style.display="inline-block",a[e].style.marginRight="20px",d.appendChild(a[e]));return c&&d.appendChild(c),d},getSelectInput:function(a){var b=document.createElement("select");return a&&this.setSelectOptions(b,a),b},getSwitcher:function(a){var b=this.getSelectInput(a);return b.style.backgroundColor="transparent",b.style.display="inline-block",b.style.fontStyle="italic",b.style.fontWeight="normal",b.style.height="auto",b.style.marginBottom=0,b.style.marginLeft="5px",b.style.padding="0 0 0 3px",b.style.width="auto",b},getSwitcherOptions:function(a){return a.getElementsByTagName("option")},setSwitcherOptions:function(a,b,c){this.setSelectOptions(a,b,c)},setSelectOptions:function(a,b,c){c=c||[],a.innerHTML="";for(var d=0;d<b.length;d++){var e=document.createElement("option");e.setAttribute("value",b[d]),e.textContent=c[d]||b[d],a.appendChild(e)}},getTextareaInput:function(){var a=document.createElement("textarea");return a.style=a.style||{},a.style.width="100%",a.style.height="300px",a.style.boxSizing="border-box",a},getRangeInput:function(a,b,c){var d=this.getFormInputField("range");return d.setAttribute("min",a),d.setAttribute("max",b),d.setAttribute("step",c),d},getFormInputField:function(a){var b=document.createElement("input");return b.setAttribute("type",a),b},afterInputReady:function(a){},getFormControl:function(a,b,c){var d=document.createElement("div");return d.className="form-control",a&&d.appendChild(a),"checkbox"===b.type?a.insertBefore(b,a.firstChild):d.appendChild(b),c&&d.appendChild(c),d},getIndentedPanel:function(){var a=document.createElement("div");return a.style=a.style||{},a.style.paddingLeft="10px",a.style.marginLeft="10px",a.style.borderLeft="1px solid #ccc",a},getChildEditorHolder:function(){return document.createElement("div")},getDescription:function(a){var b=document.createElement("p");return b.innerHTML=a,b},getCheckboxDescription:function(a){return this.getDescription(a)},getFormInputDescription:function(a){return this.getDescription(a)},getHeaderButtonHolder:function(){return this.getButtonHolder()},getButtonHolder:function(){return document.createElement("div")},getButton:function(a,b,c){var d=document.createElement("button");return d.type="button",this.setButtonText(d,a,b,c),d},setButtonText:function(a,b,c,d){a.innerHTML="",c&&(a.appendChild(c),a.innerHTML+=" "),a.appendChild(document.createTextNode(b)),d&&a.setAttribute("title",d)},getTable:function(){return document.createElement("table")},getTableRow:function(){return document.createElement("tr")},getTableHead:function(){return document.createElement("thead")},getTableBody:function(){return document.createElement("tbody")},getTableHeaderCell:function(a){var b=document.createElement("th");return b.textContent=a,b},getTableCell:function(){var a=document.createElement("td");return a},getErrorMessage:function(a){var b=document.createElement("p");return b.style=b.style||{},b.style.color="red",b.appendChild(document.createTextNode(a)),b},addInputError:function(a,b){},removeInputError:function(a){},addTableRowError:function(a){},removeTableRowError:function(a){},getTabHolder:function(){var a=document.createElement("div");return a.innerHTML="<div style='float: left; width: 130px;' class='tabs'></div><div class='content' style='margin-left: 130px;'></div><div style='clear:both;'></div>",a},applyStyles:function(a,b){a.style=a.style||{};for(var c in b)b.hasOwnProperty(c)&&(a.style[c]=b[c])},closest:function(a,b){for(;a&&a!==document;){if(!g)return!1;if(a[g](b))return a;a=a.parentNode}return!1},getTab:function(a){var b=document.createElement("div");return b.appendChild(a),b.style=b.style||{},this.applyStyles(b,{border:"1px solid #ccc",borderWidth:"1px 0 1px 1px",textAlign:"center",lineHeight:"30px",borderRadius:"5px",borderBottomRightRadius:0,borderTopRightRadius:0,fontWeight:"bold",cursor:"pointer"}),b},getTabContentHolder:function(a){return a.children[1]},getTabContent:function(){return this.getIndentedPanel()},markTabActive:function(a){this.applyStyles(a,{opacity:1,background:"white"})},markTabInactive:function(a){this.applyStyles(a,{opacity:.5,background:""})},addTab:function(a,b){a.children[0].appendChild(b)},getBlockLink:function(){var a=document.createElement("a");return a.style.display="block",a},getBlockLinkHolder:function(){var a=document.createElement("div");return a},getLinksHolder:function(){var a=document.createElement("div");return a},createMediaLink:function(a,b,c){a.appendChild(b),c.style.width="100%",a.appendChild(c)},createImageLink:function(a,b,c){a.appendChild(b),b.appendChild(c)}}),f.defaults.themes.bootstrap2=f.AbstractTheme.extend({getRangeInput:function(a,b,c){return this._super(a,b,c)},getGridContainer:function(){var a=document.createElement("div");return a.className="container-fluid",a},getGridRow:function(){var a=document.createElement("div");return a.className="row-fluid",a},getFormInputLabel:function(a,b){var c=this._super(a);return c.style.display="inline-block",c.style.fontWeight="bold",b&&(c.className+=" required"),c},setGridColumnSize:function(a,b){a.className="span"+b},getSelectInput:function(a){var b=this._super(a);return b.style.width="auto",b.style.maxWidth="98%",b},getFormInputField:function(a){var b=this._super(a);return b.style.width="98%",b},afterInputReady:function(a){a.controlgroup||(a.controlgroup=this.closest(a,".control-group"),a.controls=this.closest(a,".controls"),this.closest(a,".compact")&&(a.controlgroup.className=a.controlgroup.className.replace(/control-group/g,"").replace(/[ ]{2,}/g," "),a.controls.className=a.controlgroup.className.replace(/controls/g,"").replace(/[ ]{2,}/g," "),a.style.marginBottom=0))},getIndentedPanel:function(){var a=document.createElement("div");return a.className="well well-small",a},getFormInputDescription:function(a){var b=document.createElement("p");return b.className="help-inline",b.textContent=a,b},getFormControl:function(a,b,c){var d=document.createElement("div");d.className="control-group";var e=document.createElement("div");return e.className="controls",a&&"checkbox"===b.getAttribute("type")?(d.appendChild(e),a.className+=" checkbox",a.appendChild(b),e.appendChild(a),e.style.height="30px"):(a&&(a.className+=" control-label",d.appendChild(a)),e.appendChild(b),d.appendChild(e)),c&&e.appendChild(c),d},getHeaderButtonHolder:function(){var a=this.getButtonHolder();return a.style.marginLeft="10px",a},getButtonHolder:function(){var a=document.createElement("div");return a.className="btn-group",a},getButton:function(a,b,c){var d=this._super(a,b,c);return d.className+=" btn btn-default",d},getTable:function(){var a=document.createElement("table");return a.className="table table-bordered",a.style.width="auto",a.style.maxWidth="none",a},addInputError:function(a,b){a.controlgroup&&a.controls&&(a.controlgroup.className+=" error",a.errmsg?a.errmsg.style.display="":(a.errmsg=document.createElement("p"),a.errmsg.className="help-block errormsg",a.controls.appendChild(a.errmsg)),a.errmsg.textContent=b)},removeInputError:function(a){a.errmsg&&(a.errmsg.style.display="none",a.controlgroup.className=a.controlgroup.className.replace(/\s?error/g,""))},getTabHolder:function(){var a=document.createElement("div");return a.className="tabbable tabs-left",a.innerHTML="<ul class='nav nav-tabs span2' style='margin-right: 0;'></ul><div class='tab-content span10' style='overflow:visible;'></div>",a},getTab:function(a){var b=document.createElement("li"),c=document.createElement("a");return c.setAttribute("href","#"),c.appendChild(a),b.appendChild(c),b},getTabContentHolder:function(a){return a.children[1]},getTabContent:function(){var a=document.createElement("div");return a.className="tab-pane active",a},markTabActive:function(a){a.className+=" active"},markTabInactive:function(a){a.className=a.className.replace(/\s?active/g,"")},addTab:function(a,b){a.children[0].appendChild(b)},getProgressBar:function(){var a=document.createElement("div");a.className="progress";var b=document.createElement("div");return b.className="bar",b.style.width="0%",a.appendChild(b),a},updateProgressBar:function(a,b){a&&(a.firstChild.style.width=b+"%")},updateProgressBarUnknown:function(a){a&&(a.className="progress progress-striped active",a.firstChild.style.width="100%")}}),f.defaults.themes.bootstrap3=f.AbstractTheme.extend({getSelectInput:function(a){var b=this._super(a);return b.className+="form-control",b},setGridColumnSize:function(a,b){a.className="col-md-"+b},afterInputReady:function(a){a.controlgroup||(a.controlgroup=this.closest(a,".form-group"),this.closest(a,".compact")&&(a.controlgroup.style.marginBottom=0))},getTextareaInput:function(){var a=document.createElement("textarea");return a.className="form-control",a},getRangeInput:function(a,b,c){return this._super(a,b,c)},getFormInputField:function(a){var b=this._super(a);return"checkbox"!==a&&(b.className+="form-control"),b},getFormControl:function(a,b,c){var d=document.createElement("div");return a&&"checkbox"===b.type?(d.className+=" checkbox",a.appendChild(b),a.style.fontSize="14px",d.style.marginTop="0",d.appendChild(a),b.style.position="relative",b.style.cssFloat="left"):(d.className+=" form-group",a&&(a.className+=" control-label",d.appendChild(a)),d.appendChild(b)),c&&d.appendChild(c),d},getIndentedPanel:function(){var a=document.createElement("div");return a.className="well well-sm",a},getFormInputDescription:function(a){var b=document.createElement("p");return b.className="help-block",b.innerHTML=a,b},getHeaderButtonHolder:function(){var a=this.getButtonHolder();return a.style.marginLeft="10px",a},getButtonHolder:function(){var a=document.createElement("div");return a.className="btn-group",a},getButton:function(a,b,c){var d=this._super(a,b,c);return d.className+="btn btn-default",d},getTable:function(){var a=document.createElement("table");return a.className="table table-bordered",a.style.width="auto",a.style.maxWidth="none",a},addInputError:function(a,b){a.controlgroup&&(a.controlgroup.className+=" has-error",a.errmsg?a.errmsg.style.display="":(a.errmsg=document.createElement("p"),a.errmsg.className="help-block errormsg",a.controlgroup.appendChild(a.errmsg)),a.errmsg.textContent=b)},removeInputError:function(a){a.errmsg&&(a.errmsg.style.display="none",a.controlgroup.className=a.controlgroup.className.replace(/\s?has-error/g,""))},getTabHolder:function(){var a=document.createElement("div");return a.innerHTML="<div class='tabs list-group col-md-2'></div><div class='col-md-10'></div>",a.className="rows",a},getTab:function(a){var b=document.createElement("a");return b.className="list-group-item",b.setAttribute("href","#"),b.appendChild(a),b},markTabActive:function(a){a.className+=" active"},markTabInactive:function(a){a.className=a.className.replace(/\s?active/g,"")},getProgressBar:function(){var a=0,b=100,c=0,d=document.createElement("div");d.className="progress";var e=document.createElement("div");return e.className="progress-bar",e.setAttribute("role","progressbar"),e.setAttribute("aria-valuenow",c),e.setAttribute("aria-valuemin",a),e.setAttribute("aria-valuenax",b),e.innerHTML=c+"%",d.appendChild(e),d},updateProgressBar:function(a,b){if(a){var c=a.firstChild,d=b+"%";c.setAttribute("aria-valuenow",b),c.style.width=d,c.innerHTML=d}},updateProgressBarUnknown:function(a){if(a){var b=a.firstChild;a.className="progress progress-striped active",b.removeAttribute("aria-valuenow"),b.style.width="100%",b.innerHTML=""}}}),f.defaults.themes.foundation=f.AbstractTheme.extend({getChildEditorHolder:function(){var a=document.createElement("div");return a.style.marginBottom="15px",a},getSelectInput:function(a){var b=this._super(a);return b.style.minWidth="none",b.style.padding="5px",b.style.marginTop="3px",b},getSwitcher:function(a){var b=this._super(a);return b.style.paddingRight="8px",b},afterInputReady:function(a){this.closest(a,".compact")&&(a.style.marginBottom=0),a.group=this.closest(a,".form-control")},getFormInputLabel:function(a,b){var c=this._super(a);return c.style.display="inline-block",b&&(c.className+=" required"),c},getFormInputField:function(a){var b=this._super(a);return b.style.width="100%",b.style.marginBottom="checkbox"===a?"0":"12px",b},getFormInputDescription:function(a){var b=document.createElement("p");return b.textContent=a,b.style.marginTop="-10px",b.style.fontStyle="italic",b},getIndentedPanel:function(){var a=document.createElement("div");return a.className="panel",a},getHeaderButtonHolder:function(){var a=this.getButtonHolder();return a.style.display="inline-block",a.style.marginLeft="10px",a.style.verticalAlign="middle",a},getButtonHolder:function(){var a=document.createElement("div");return a.className="button-group",a},getButton:function(a,b,c){var d=this._super(a,b,c);return d.className+=" small button",d},addInputError:function(a,b){a.group&&(a.group.className+=" error",a.errmsg?a.errmsg.style.display="":(a.insertAdjacentHTML("afterend",'<small class="error"></small>'),a.errmsg=a.parentNode.getElementsByClassName("error")[0]),a.errmsg.textContent=b)},removeInputError:function(a){a.errmsg&&(a.group.className=a.group.className.replace(/ error/g,""),a.errmsg.style.display="none")},getProgressBar:function(){var a=document.createElement("div");a.className="progress";var b=document.createElement("span");return b.className="meter",b.style.width="0%",a.appendChild(b),a},updateProgressBar:function(a,b){a&&(a.firstChild.style.width=b+"%")},updateProgressBarUnknown:function(a){a&&(a.firstChild.style.width="100%")}}),f.defaults.themes.foundation3=f.defaults.themes.foundation.extend({getHeaderButtonHolder:function(){var a=this._super();return a.style.fontSize=".6em",a},getFormInputLabel:function(a,b){var c=this._super(a);return c.style.fontWeight="bold",b&&(c.className+=" required"),c},getTabHolder:function(){var a=document.createElement("div");return a.className="row",a.innerHTML="<dl class='tabs vertical two columns'></dl><div class='tabs-content ten columns'></div>",a},setGridColumnSize:function(a,b){var c=["zero","one","two","three","four","five","six","seven","eight","nine","ten","eleven","twelve"];a.className="columns "+c[b]},getTab:function(a){var b=document.createElement("dd"),c=document.createElement("a");return c.setAttribute("href","#"),c.appendChild(a),b.appendChild(c),b},getTabContentHolder:function(a){return a.children[1]},getTabContent:function(){var a=document.createElement("div");return a.className="content active",a.style.paddingLeft="5px",a},markTabActive:function(a){a.className+=" active"},markTabInactive:function(a){a.className=a.className.replace(/\s*active/g,"")},addTab:function(a,b){a.children[0].appendChild(b)}}),f.defaults.themes.foundation4=f.defaults.themes.foundation.extend({getHeaderButtonHolder:function(){var a=this._super();return a.style.fontSize=".6em",a},setGridColumnSize:function(a,b){a.className="columns large-"+b},getFormInputDescription:function(a){var b=this._super(a);return b.style.fontSize=".8rem",b},getFormInputLabel:function(a,b){var c=this._super(a);return c.style.fontWeight="bold",b&&(c.className+=" required"),c}}),f.defaults.themes.foundation5=f.defaults.themes.foundation.extend({getFormInputDescription:function(a){var b=this._super(a);return b.style.fontSize=".8rem",b},setGridColumnSize:function(a,b){a.className="columns medium-"+b},getButton:function(a,b,c){var d=this._super(a,b,c);return d.className=d.className.replace(/\s*small/g,"")+" tiny",d},getTabHolder:function(){var a=document.createElement("div");return a.innerHTML="<dl class='tabs vertical'></dl><div class='tabs-content vertical'></div>",a},getTab:function(a){var b=document.createElement("dd"),c=document.createElement("a");return c.setAttribute("href","#"),c.appendChild(a),b.appendChild(c),b},getTabContentHolder:function(a){return a.children[1]},getTabContent:function(){var a=document.createElement("div");return a.className="content active",a.style.paddingLeft="5px",a},markTabActive:function(a){a.className+=" active"},markTabInactive:function(a){a.className=a.className.replace(/\s*active/g,"")},addTab:function(a,b){a.children[0].appendChild(b)}}),f.defaults.themes.html=f.AbstractTheme.extend({getFormInputLabel:function(a,b){var c=this._super(a);return c.style.display="block",c.style.marginBottom="3px",c.style.fontWeight="bold",b&&(c.className+=" required"),c},getFormInputDescription:function(a){var b=this._super(a);return b.style.fontSize=".8em",b.style.margin=0,b.style.display="inline-block",b.style.fontStyle="italic",b},getIndentedPanel:function(){var a=this._super();return a.style.border="1px solid #ddd",a.style.padding="5px",a.style.margin="5px",a.style.borderRadius="3px",a},getChildEditorHolder:function(){var a=this._super();return a.style.marginBottom="8px",a},getHeaderButtonHolder:function(){var a=this.getButtonHolder();return a.style.display="inline-block",a.style.marginLeft="10px",a.style.fontSize=".8em",a.style.verticalAlign="middle",a},getTable:function(){var a=this._super();return a.style.borderBottom="1px solid #ccc",a.style.marginBottom="5px",a},addInputError:function(a,b){if(a.style.borderColor="red",a.errmsg)a.errmsg.style.display="block";else{var c=this.closest(a,".form-control");a.errmsg=document.createElement("div"),a.errmsg.setAttribute("class","errmsg"),a.errmsg.style=a.errmsg.style||{},a.errmsg.style.color="red",c.appendChild(a.errmsg)}a.errmsg.innerHTML="",a.errmsg.appendChild(document.createTextNode(b))},removeInputError:function(a){a.style.borderColor="",a.errmsg&&(a.errmsg.style.display="none")},getProgressBar:function(){var a=100,b=0,c=document.createElement("progress");return c.setAttribute("max",a),c.setAttribute("value",b),c},updateProgressBar:function(a,b){a&&a.setAttribute("value",b)},updateProgressBarUnknown:function(a){a&&a.removeAttribute("value")}}),f.defaults.themes.jqueryui=f.AbstractTheme.extend({getTable:function(){var a=this._super();return a.setAttribute("cellpadding",5),a.setAttribute("cellspacing",0),a},getTableHeaderCell:function(a){var b=this._super(a);return b.className="ui-state-active",b.style.fontWeight="bold",b},getTableCell:function(){var a=this._super();return a.className="ui-widget-content",a},getHeaderButtonHolder:function(){var a=this.getButtonHolder();return a.style.marginLeft="10px",a.style.fontSize=".6em",a.style.display="inline-block",a},getFormInputDescription:function(a){var b=this.getDescription(a);return b.style.marginLeft="10px",b.style.display="inline-block",b},getFormControl:function(a,b,c){var d=this._super(a,b,c);return"checkbox"===b.type?(d.style.lineHeight="25px",d.style.padding="3px 0"):d.style.padding="4px 0 8px 0",d},getDescription:function(a){var b=document.createElement("span");return b.style.fontSize=".8em",b.style.fontStyle="italic",b.textContent=a,b},getButtonHolder:function(){var a=document.createElement("div");return a.className="ui-buttonset",a.style.fontSize=".7em",a},getFormInputLabel:function(a,b){var c=document.createElement("label");return c.style.fontWeight="bold",c.style.display="block",b&&(c.className+=" required"),c.textContent=a,c},getButton:function(a,b,c){var d=document.createElement("button");d.className="ui-button ui-widget ui-state-default ui-corner-all",b&&!a?(d.className+=" ui-button-icon-only",b.className+=" ui-button-icon-primary ui-icon-primary",d.appendChild(b)):b?(d.className+=" ui-button-text-icon-primary",b.className+=" ui-button-icon-primary ui-icon-primary",d.appendChild(b)):d.className+=" ui-button-text-only";var e=document.createElement("span");return e.className="ui-button-text",e.textContent=a||c||".",d.appendChild(e),d.setAttribute("title",c),d},setButtonText:function(a,b,c,d){a.innerHTML="",a.className="ui-button ui-widget ui-state-default ui-corner-all",c&&!b?(a.className+=" ui-button-icon-only",c.className+=" ui-button-icon-primary ui-icon-primary",a.appendChild(c)):c?(a.className+=" ui-button-text-icon-primary",c.className+=" ui-button-icon-primary ui-icon-primary",a.appendChild(c)):a.className+=" ui-button-text-only";var e=document.createElement("span");e.className="ui-button-text",e.textContent=b||d||".",a.appendChild(e),a.setAttribute("title",d)},getIndentedPanel:function(){var a=document.createElement("div");return a.className="ui-widget-content ui-corner-all",a.style.padding="1em 1.4em",a.style.marginBottom="20px",a},afterInputReady:function(a){a.controls||(a.controls=this.closest(a,".form-control"))},addInputError:function(a,b){a.controls&&(a.errmsg?a.errmsg.style.display="":(a.errmsg=document.createElement("div"),a.errmsg.className="ui-state-error",a.controls.appendChild(a.errmsg)),a.errmsg.textContent=b)},removeInputError:function(a){a.errmsg&&(a.errmsg.style.display="none")},markTabActive:function(a){a.className=a.className.replace(/\s*ui-widget-header/g,"")+" ui-state-active"},markTabInactive:function(a){a.className=a.className.replace(/\s*ui-state-active/g,"")+" ui-widget-header"}}),f.AbstractIconLib=a.extend({mapping:{collapse:"",expand:"","delete":"",edit:"",add:"",cancel:"",save:"",moveup:"",movedown:""},icon_prefix:"",getIconClass:function(a){return this.mapping[a]?this.icon_prefix+this.mapping[a]:null},getIcon:function(a){var b=this.getIconClass(a);if(!b)return null;var c=document.createElement("i");return c.className=b,c}}),f.defaults.iconlibs.bootstrap2=f.AbstractIconLib.extend({mapping:{collapse:"chevron-down",expand:"chevron-up","delete":"trash",edit:"pencil",add:"plus",cancel:"ban-circle",save:"ok",moveup:"arrow-up",movedown:"arrow-down"},icon_prefix:"icon-"}),f.defaults.iconlibs.bootstrap3=f.AbstractIconLib.extend({mapping:{collapse:"chevron-down",expand:"chevron-right","delete":"remove",edit:"pencil",add:"plus",cancel:"floppy-remove",save:"floppy-saved",moveup:"arrow-up",movedown:"arrow-down"},icon_prefix:"glyphicon glyphicon-"}),f.defaults.iconlibs.fontawesome3=f.AbstractIconLib.extend({mapping:{collapse:"chevron-down",expand:"chevron-right","delete":"remove",edit:"pencil",add:"plus",cancel:"ban-circle",save:"save",moveup:"arrow-up",movedown:"arrow-down"},icon_prefix:"icon-"}),f.defaults.iconlibs.fontawesome4=f.AbstractIconLib.extend({mapping:{collapse:"caret-square-o-down",expand:"caret-square-o-right","delete":"times",edit:"pencil",add:"plus",cancel:"ban",save:"save",moveup:"arrow-up",movedown:"arrow-down"},icon_prefix:"fa fa-"}),f.defaults.iconlibs.foundation2=f.AbstractIconLib.extend({mapping:{collapse:"minus",expand:"plus","delete":"remove",edit:"edit",add:"add-doc",cancel:"error",save:"checkmark",moveup:"up-arrow",movedown:"down-arrow"},icon_prefix:"foundicon-"}),f.defaults.iconlibs.foundation3=f.AbstractIconLib.extend({mapping:{collapse:"minus",expand:"plus","delete":"x",edit:"pencil",add:"page-add",cancel:"x-circle",save:"save",moveup:"arrow-up",movedown:"arrow-down"},icon_prefix:"fi-"}),f.defaults.iconlibs.jqueryui=f.AbstractIconLib.extend({mapping:{collapse:"triangle-1-s",expand:"triangle-1-e","delete":"trash",edit:"pencil",add:"plusthick",cancel:"closethick",save:"disk",moveup:"arrowthick-1-n",movedown:"arrowthick-1-s"},icon_prefix:"ui-icon ui-icon-"}),f.defaults.templates["default"]=function(){return{compile:function(a){var b=a.match(/{{\s*([a-zA-Z0-9\-_ \.]+)\s*}}/g),c=b&&b.length;if(!c)return function(){return a};for(var d=[],e=function(a){var c,e=b[a].replace(/[{}]+/g,"").trim().split("."),f=e.length;if(f>1){var g;c=function(b){for(g=b,a=0;f>a&&(g=g[e[a]],g);a++);return g}}else e=e[0],c=function(a){return a[e]};d.push({s:b[a],r:c})},f=0;c>f;f++)e(f);return function(b){var e,g=a+"";for(f=0;c>f;f++)e=d[f],g=g.replace(e.s,e.r(b));return g}}}},f.defaults.templates.ejs=function(){return window.EJS?{compile:function(a){var b=new window.EJS({text:a});return function(a){return b.render(a)}}}:!1},f.defaults.templates.handlebars=function(){return window.Handlebars},f.defaults.templates.hogan=function(){return window.Hogan?{compile:function(a){var b=window.Hogan.compile(a);return function(a){return b.render(a)}}}:!1},f.defaults.templates.markup=function(){return window.Mark&&window.Mark.up?{compile:function(a){return function(b){return window.Mark.up(a,b)}}}:!1},f.defaults.templates.mustache=function(){return window.Mustache?{compile:function(a){return function(b){return window.Mustache.render(a,b)}}}:!1},f.defaults.templates.swig=function(){return window.swig},f.defaults.templates.underscore=function(){return window._?{compile:function(a){return function(b){return window._.template(a,b)}}}:!1},f.defaults.theme="html",f.defaults.template="default",f.defaults.options={},f.defaults.translate=function(a,b){var c=f.defaults.languages[f.defaults.language];if(!c)throw"Unknown language "+f.defaults.language;var d=c[a]||f.defaults.languages[f.defaults.default_language][a];if("undefined"==typeof d)throw"Unknown translate string "+a;if(b)for(var e=0;e<b.length;e++)d=d.replace(new RegExp("\\{\\{"+e+"}}","g"),b[e]);return d},f.defaults.default_language="en",f.defaults.language=f.defaults.default_language,f.defaults.languages.en={error_notset:"Property must be set",error_notempty:"Value required",error_enum:"Value must be one of the enumerated values",error_anyOf:"Value must validate against at least one of the provided schemas",error_oneOf:"Value must validate against exactly one of the provided schemas. It currently validates against {{0}} of the schemas.",error_not:"Value must not validate against the provided schema",error_type_union:"Value must be one of the provided types",error_type:"Value must be of type {{0}}",error_disallow_union:"Value must not be one of the provided disallowed types",error_disallow:"Value must not be of type {{0}}",error_multipleOf:"Value must be a multiple of {{0}}",error_maximum_excl:"Value must be less than {{0}}",error_maximum_incl:"Value must at most {{0}}",error_minimum_excl:"Value must be greater than {{0}}",error_minimum_incl:"Value must be at least {{0}}",error_maxLength:"Value must be at most {{0}} characters long",error_minLength:"Value must be at least {{0}} characters long",error_pattern:"Value must match the provided pattern",error_additionalItems:"No additional items allowed in this array",error_maxItems:"Value must have at most {{0}} items",error_minItems:"Value must have at least {{0}} items",error_uniqueItems:"Array must have unique items",error_maxProperties:"Object must have at most {{0}} properties",error_minProperties:"Object must have at least {{0}} properties",error_required:"Object is missing the required property '{{0}}'",error_additional_properties:"No additional properties allowed, but property {{0}} is set",error_dependency:"Must have property {{0}}"},f.plugins={ace:{theme:""},epiceditor:{},sceditor:{},select2:{}};for(var h in f.defaults.editors)f.defaults.editors.hasOwnProperty(h)&&(f.defaults.editors[h].options=f.defaults.editors.options||{});f.defaults.resolvers.unshift(function(a){return"string"!=typeof a.type?"multiple":void 0}),f.defaults.resolvers.unshift(function(a){return!a.type&&a.properties?"object":void 0}),f.defaults.resolvers.unshift(function(a){return"string"==typeof a.type?a.type:void 0}),f.defaults.resolvers.unshift(function(a){return"boolean"===a.type?"checkbox"===a.format||a.options&&a.options.checkbox?"checkbox":"select":void 0;
-}),f.defaults.resolvers.unshift(function(a){return"any"===a.type?"multiple":void 0}),f.defaults.resolvers.unshift(function(a){return"string"===a.type&&a.media&&"base64"===a.media.binaryEncoding?"base64":void 0}),f.defaults.resolvers.unshift(function(a){return"string"===a.type&&"url"===a.format&&a.options&&a.options.upload===!0&&window.FileReader?"upload":void 0}),f.defaults.resolvers.unshift(function(a){return"array"==a.type&&"table"==a.format?"table":void 0}),f.defaults.resolvers.unshift(function(a){return a.enumSource?"select":void 0}),f.defaults.resolvers.unshift(function(a){if(a["enum"]){if("array"===a.type||"object"===a.type)return"enum";if("number"===a.type||"integer"===a.type||"string"===a.type)return"select"}}),f.defaults.resolvers.unshift(function(a){return"array"===a.type&&a.items&&!Array.isArray(a.items)&&a.uniqueItems&&a.items["enum"]&&["string","number","integer"].indexOf(a.items.type)>=0?"multiselect":void 0}),f.defaults.resolvers.unshift(function(a){return a.oneOf?"multiple":void 0}),function(){if(window.jQuery||window.Zepto){var a=window.jQuery||window.Zepto;a.jsoneditor=f.defaults,a.fn.jsoneditor=function(a){var b=this,c=this.data("jsoneditor");if("value"===a){if(!c)throw"Must initialize jsoneditor before getting/setting the value";if(!(arguments.length>1))return c.getValue();c.setValue(arguments[1])}else{if("validate"===a){if(!c)throw"Must initialize jsoneditor before validating";return arguments.length>1?c.validate(arguments[1]):c.validate()}"destroy"===a?c&&(c.destroy(),this.data("jsoneditor",null)):(c&&c.destroy(),c=new f(this.get(0),a),this.data("jsoneditor",c),c.on("change",function(){b.trigger("change")}),c.on("ready",function(){b.trigger("ready")}))}return this}}}(),window.JSONEditor=f}(); \ No newline at end of file
+/*! JSON Editor v0.7.22 - JSON Schema -> HTML Editor
+ * By Jeremy Dorn - https://github.com/jdorn/json-editor/
+ * Released under the MIT license
+ *
+ * Date: 2015-08-12
+ */
+!function(){var a;!function(){var b=!1,c=/xyz/.test(function(){window.postMessage("xyz")})?/\b_super\b/:/.*/;return a=function(){},a.extend=function(a){function d(){!b&&this.init&&this.init.apply(this,arguments)}var e=this.prototype;b=!0;var f=new this;b=!1;for(var g in a)f[g]="function"==typeof a[g]&&"function"==typeof e[g]&&c.test(a[g])?function(a,b){return function(){var c=this._super;this._super=e[a];var d=b.apply(this,arguments);return this._super=c,d}}(g,a[g]):a[g];return d.prototype=f,d.prototype.constructor=d,d.extend=arguments.callee,d},a}(),function(){function a(a,b){b=b||{bubbles:!1,cancelable:!1,detail:void 0};var c=document.createEvent("CustomEvent");return c.initCustomEvent(a,b.bubbles,b.cancelable,b.detail),c}a.prototype=window.Event.prototype,window.CustomEvent=a}(),function(){for(var a=0,b=["ms","moz","webkit","o"],c=0;c<b.length&&!window.requestAnimationFrame;++c)window.requestAnimationFrame=window[b[c]+"RequestAnimationFrame"],window.cancelAnimationFrame=window[b[c]+"CancelAnimationFrame"]||window[b[c]+"CancelRequestAnimationFrame"];window.requestAnimationFrame||(window.requestAnimationFrame=function(b,c){var d=(new Date).getTime(),e=Math.max(0,16-(d-a)),f=window.setTimeout(function(){b(d+e)},e);return a=d+e,f}),window.cancelAnimationFrame||(window.cancelAnimationFrame=function(a){clearTimeout(a)})}(),function(){Array.isArray||(Array.isArray=function(a){return"[object Array]"===Object.prototype.toString.call(a)})}();var b=function(a){return"object"!=typeof a||a.nodeType||null!==a&&a===a.window?!1:a.constructor&&!Object.prototype.hasOwnProperty.call(a.constructor.prototype,"isPrototypeOf")?!1:!0},c=function(a){var d,e,f;for(e=1;e<arguments.length;e++){d=arguments[e];for(f in d)d.hasOwnProperty(f)&&(d[f]&&b(d[f])?(a.hasOwnProperty(f)||(a[f]={}),c(a[f],d[f])):a[f]=d[f])}return a},d=function(a,b){if(a&&"object"==typeof a){var c;if(Array.isArray(a)||"number"==typeof a.length&&a.length>0&&a.length-1 in a){for(c=0;c<a.length;c++)if(b(c,a[c])===!1)return}else if(Object.keys){var d=Object.keys(a);for(c=0;c<d.length;c++)if(b(d[c],a[d[c]])===!1)return}else for(c in a)if(a.hasOwnProperty(c)&&b(c,a[c])===!1)return}},e=function(a,b){var c=document.createEvent("HTMLEvents");c.initEvent(b,!0,!0),a.dispatchEvent(c)},f=function(a,b){if(!(a instanceof Element))throw new Error("element should be an instance of Element");b=c({},f.defaults.options,b||{}),this.element=a,this.options=b,this.init()};f.prototype={constructor:f,init:function(){var a=this;this.ready=!1;var b=f.defaults.themes[this.options.theme||f.defaults.theme];if(!b)throw"Unknown theme "+(this.options.theme||f.defaults.theme);this.schema=this.options.schema,this.theme=new b,this.template=this.options.template,this.refs=this.options.refs||{},this.uuid=0,this.__data={};var c=f.defaults.iconlibs[this.options.iconlib||f.defaults.iconlib];c&&(this.iconlib=new c),this.root_container=this.theme.getContainer(),this.element.appendChild(this.root_container),this.translate=this.options.translate||f.defaults.translate,this._loadExternalRefs(this.schema,function(){a._getDefinitions(a.schema),a.validator=new f.Validator(a);var b=a.getEditorClass(a.schema);a.root=a.createEditor(b,{jsoneditor:a,schema:a.schema,required:!0,container:a.root_container}),a.root.preBuild(),a.root.build(),a.root.postBuild(),a.options.startval&&a.root.setValue(a.options.startval),a.validation_results=a.validator.validate(a.root.getValue()),a.root.showValidationErrors(a.validation_results),a.ready=!0,window.requestAnimationFrame(function(){a.ready&&(a.validation_results=a.validator.validate(a.root.getValue()),a.root.showValidationErrors(a.validation_results),a.trigger("ready"),a.trigger("change"))})})},getValue:function(){if(!this.ready)throw"JSON Editor not ready yet. Listen for 'ready' event before getting the value";return this.root.getValue()},setValue:function(a){if(!this.ready)throw"JSON Editor not ready yet. Listen for 'ready' event before setting the value";return this.root.setValue(a),this},validate:function(a){if(!this.ready)throw"JSON Editor not ready yet. Listen for 'ready' event before validating";return 1===arguments.length?this.validator.validate(a):this.validation_results},destroy:function(){this.destroyed||this.ready&&(this.schema=null,this.options=null,this.root.destroy(),this.root=null,this.root_container=null,this.validator=null,this.validation_results=null,this.theme=null,this.iconlib=null,this.template=null,this.__data=null,this.ready=!1,this.element.innerHTML="",this.destroyed=!0)},on:function(a,b){return this.callbacks=this.callbacks||{},this.callbacks[a]=this.callbacks[a]||[],this.callbacks[a].push(b),this},off:function(a,b){if(a&&b){this.callbacks=this.callbacks||{},this.callbacks[a]=this.callbacks[a]||[];for(var c=[],d=0;d<this.callbacks[a].length;d++)this.callbacks[a][d]!==b&&c.push(this.callbacks[a][d]);this.callbacks[a]=c}else a?(this.callbacks=this.callbacks||{},this.callbacks[a]=[]):this.callbacks={};return this},trigger:function(a){if(this.callbacks&&this.callbacks[a]&&this.callbacks[a].length)for(var b=0;b<this.callbacks[a].length;b++)this.callbacks[a][b]();return this},setOption:function(a,b){if("show_errors"!==a)throw"Option "+a+" must be set during instantiation and cannot be changed later";return this.options.show_errors=b,this.onChange(),this},getEditorClass:function(a){var b;if(a=this.expandSchema(a),d(f.defaults.resolvers,function(c,d){var e=d(a);return e&&f.defaults.editors[e]?(b=e,!1):void 0}),!b)throw"Unknown editor for schema "+JSON.stringify(a);if(!f.defaults.editors[b])throw"Unknown editor "+b;return f.defaults.editors[b]},createEditor:function(a,b){return b=c({},a.options||{},b),new a(b)},onChange:function(){if(this.ready&&!this.firing_change){this.firing_change=!0;var a=this;return window.requestAnimationFrame(function(){a.firing_change=!1,a.ready&&(a.validation_results=a.validator.validate(a.root.getValue()),"never"!==a.options.show_errors?a.root.showValidationErrors(a.validation_results):a.root.showValidationErrors([]),a.trigger("change"))}),this}},compileTemplate:function(a,b){b=b||f.defaults.template;var c;if("string"==typeof b){if(!f.defaults.templates[b])throw"Unknown template engine "+b;if(c=f.defaults.templates[b](),!c)throw"Template engine "+b+" missing required library."}else c=b;if(!c)throw"No template engine set";if(!c.compile)throw"Invalid template engine set";return c.compile(a)},_data:function(a,b,c){if(3!==arguments.length)return a.hasAttribute("data-jsoneditor-"+b)?this.__data[a.getAttribute("data-jsoneditor-"+b)]:null;var d;a.hasAttribute("data-jsoneditor-"+b)?d=a.getAttribute("data-jsoneditor-"+b):(d=this.uuid++,a.setAttribute("data-jsoneditor-"+b,d)),this.__data[d]=c},registerEditor:function(a){return this.editors=this.editors||{},this.editors[a.path]=a,this},unregisterEditor:function(a){return this.editors=this.editors||{},this.editors[a.path]=null,this},getEditor:function(a){return this.editors?this.editors[a]:void 0},watch:function(a,b){return this.watchlist=this.watchlist||{},this.watchlist[a]=this.watchlist[a]||[],this.watchlist[a].push(b),this},unwatch:function(a,b){if(!this.watchlist||!this.watchlist[a])return this;if(!b)return this.watchlist[a]=null,this;for(var c=[],d=0;d<this.watchlist[a].length;d++)this.watchlist[a][d]!==b&&c.push(this.watchlist[a][d]);return this.watchlist[a]=c.length?c:null,this},notifyWatchers:function(a){if(!this.watchlist||!this.watchlist[a])return this;for(var b=0;b<this.watchlist[a].length;b++)this.watchlist[a][b]()},isEnabled:function(){return!this.root||this.root.isEnabled()},enable:function(){this.root.enable()},disable:function(){this.root.disable()},_getDefinitions:function(a,b){if(b=b||"#/definitions/",a.definitions)for(var c in a.definitions)a.definitions.hasOwnProperty(c)&&(this.refs[b+c]=a.definitions[c],a.definitions[c].definitions&&this._getDefinitions(a.definitions[c],b+c+"/definitions/"))},_getExternalRefs:function(a){var b={},c=function(a){for(var c in a)a.hasOwnProperty(c)&&(b[c]=!0)};a.$ref&&"object"!=typeof a.$ref&&"#"!==a.$ref.substr(0,1)&&!this.refs[a.$ref]&&(b[a.$ref]=!0);for(var d in a)if(a.hasOwnProperty(d))if(a[d]&&"object"==typeof a[d]&&Array.isArray(a[d]))for(var e=0;e<a[d].length;e++)"object"==typeof a[d][e]&&c(this._getExternalRefs(a[d][e]));else a[d]&&"object"==typeof a[d]&&c(this._getExternalRefs(a[d]));return b},_loadExternalRefs:function(a,b){var c=this,e=this._getExternalRefs(a),f=0,g=0,h=!1;d(e,function(a){if(!c.refs[a]){if(!c.options.ajax)throw"Must set ajax option to true to load external ref "+a;c.refs[a]="loading",g++;var d=new XMLHttpRequest;d.open("GET",a,!0),d.onreadystatechange=function(){if(4==d.readyState){if(200!==d.status)throw window.console.log(d),"Failed to fetch ref via ajax- "+a;var e;try{e=JSON.parse(d.responseText)}catch(i){throw window.console.log(i),"Failed to parse external ref "+a}if(!e||"object"!=typeof e)throw"External ref does not contain a valid schema - "+a;c.refs[a]=e,c._loadExternalRefs(e,function(){f++,f>=g&&!h&&(h=!0,b())})}},d.send()}}),g||b()},expandRefs:function(a){for(a=c({},a);a.$ref;){var b=a.$ref;delete a.$ref,this.refs[b]||(b=decodeURIComponent(b)),a=this.extendSchemas(a,this.refs[b])}return a},expandSchema:function(a){var b,e=this,f=c({},a);if("object"==typeof a.type&&(Array.isArray(a.type)?d(a.type,function(b,c){"object"==typeof c&&(a.type[b]=e.expandSchema(c))}):a.type=e.expandSchema(a.type)),"object"==typeof a.disallow&&(Array.isArray(a.disallow)?d(a.disallow,function(b,c){"object"==typeof c&&(a.disallow[b]=e.expandSchema(c))}):a.disallow=e.expandSchema(a.disallow)),a.anyOf&&d(a.anyOf,function(b,c){a.anyOf[b]=e.expandSchema(c)}),a.dependencies&&d(a.dependencies,function(b,c){"object"!=typeof c||Array.isArray(c)||(a.dependencies[b]=e.expandSchema(c))}),a.not&&(a.not=this.expandSchema(a.not)),a.allOf){for(b=0;b<a.allOf.length;b++)f=this.extendSchemas(f,this.expandSchema(a.allOf[b]));delete f.allOf}if(a["extends"]){if(Array.isArray(a["extends"]))for(b=0;b<a["extends"].length;b++)f=this.extendSchemas(f,this.expandSchema(a["extends"][b]));else f=this.extendSchemas(f,this.expandSchema(a["extends"]));delete f["extends"]}if(a.oneOf){var g=c({},f);for(delete g.oneOf,b=0;b<a.oneOf.length;b++)f.oneOf[b]=this.extendSchemas(this.expandSchema(a.oneOf[b]),g)}return this.expandRefs(f)},extendSchemas:function(a,b){a=c({},a),b=c({},b);var e=this,f={};return d(a,function(a,c){"undefined"!=typeof b[a]?"required"===a&&"object"==typeof c&&Array.isArray(c)?f.required=c.concat(b[a]).reduce(function(a,b){return a.indexOf(b)<0&&a.push(b),a},[]):"type"!==a||"string"!=typeof c&&!Array.isArray(c)?"object"==typeof c&&Array.isArray(c)?f[a]=c.filter(function(c){return-1!==b[a].indexOf(c)}):"object"==typeof c&&null!==c?f[a]=e.extendSchemas(c,b[a]):f[a]=c:("string"==typeof c&&(c=[c]),"string"==typeof b.type&&(b.type=[b.type]),f.type=c.filter(function(a){return-1!==b.type.indexOf(a)}),1===f.type.length&&"string"==typeof f.type[0]&&(f.type=f.type[0])):f[a]=c}),d(b,function(b,c){"undefined"==typeof a[b]&&(f[b]=c)}),f}},f.defaults={themes:{},templates:{},iconlibs:{},editors:{},languages:{},resolvers:[],custom_validators:[]},f.Validator=a.extend({init:function(a,b){this.jsoneditor=a,this.schema=b||this.jsoneditor.schema,this.options={},this.translate=this.jsoneditor.translate||f.defaults.translate},validate:function(a){return this._validateSchema(this.schema,a)},_validateSchema:function(a,b,e){var g,h,i,j=this,k=[],l=JSON.stringify(b);if(e=e||"root",a=c({},this.jsoneditor.expandRefs(a)),a.required&&a.required===!0){if("undefined"==typeof b)return k.push({path:e,property:"required",message:this.translate("error_notset")}),k}else if("undefined"==typeof b){if(!this.jsoneditor.options.required_by_default)return k;k.push({path:e,property:"required",message:this.translate("error_notset")})}if(a["enum"]){for(g=!1,h=0;h<a["enum"].length;h++)l===JSON.stringify(a["enum"][h])&&(g=!0);g||k.push({path:e,property:"enum",message:this.translate("error_enum")})}if(a["extends"])for(h=0;h<a["extends"].length;h++)k=k.concat(this._validateSchema(a["extends"][h],b,e));if(a.allOf)for(h=0;h<a.allOf.length;h++)k=k.concat(this._validateSchema(a.allOf[h],b,e));if(a.anyOf){for(g=!1,h=0;h<a.anyOf.length;h++)if(!this._validateSchema(a.anyOf[h],b,e).length){g=!0;break}g||k.push({path:e,property:"anyOf",message:this.translate("error_anyOf")})}if(a.oneOf){g=0;var m=[];for(h=0;h<a.oneOf.length;h++){var n=this._validateSchema(a.oneOf[h],b,e);for(n.length||g++,i=0;i<n.length;i++)n[i].path=e+".oneOf["+h+"]"+n[i].path.substr(e.length);m=m.concat(n)}1!==g&&(k.push({path:e,property:"oneOf",message:this.translate("error_oneOf",[g])}),k=k.concat(m))}if(a.not&&(this._validateSchema(a.not,b,e).length||k.push({path:e,property:"not",message:this.translate("error_not")})),a.type)if(Array.isArray(a.type)){for(g=!1,h=0;h<a.type.length;h++)if(this._checkType(a.type[h],b)){g=!0;break}g||k.push({path:e,property:"type",message:this.translate("error_type_union")})}else this._checkType(a.type,b)||k.push({path:e,property:"type",message:this.translate("error_type",[a.type])});if(a.disallow)if(Array.isArray(a.disallow)){for(g=!0,h=0;h<a.disallow.length;h++)if(this._checkType(a.disallow[h],b)){g=!1;break}g||k.push({path:e,property:"disallow",message:this.translate("error_disallow_union")})}else this._checkType(a.disallow,b)&&k.push({path:e,property:"disallow",message:this.translate("error_disallow",[a.disallow])});if("number"==typeof b)(a.multipleOf||a.divisibleBy)&&(g=b/(a.multipleOf||a.divisibleBy),g!==Math.floor(g)&&k.push({path:e,property:a.multipleOf?"multipleOf":"divisibleBy",message:this.translate("error_multipleOf",[a.multipleOf||a.divisibleBy])})),a.hasOwnProperty("maximum")&&(a.exclusiveMaximum&&b>=a.maximum?k.push({path:e,property:"maximum",message:this.translate("error_maximum_excl",[a.maximum])}):!a.exclusiveMaximum&&b>a.maximum&&k.push({path:e,property:"maximum",message:this.translate("error_maximum_incl",[a.maximum])})),a.hasOwnProperty("minimum")&&(a.exclusiveMinimum&&b<=a.minimum?k.push({path:e,property:"minimum",message:this.translate("error_minimum_excl",[a.minimum])}):!a.exclusiveMinimum&&b<a.minimum&&k.push({path:e,property:"minimum",message:this.translate("error_minimum_incl",[a.minimum])}));else if("string"==typeof b)a.maxLength&&(b+"").length>a.maxLength&&k.push({path:e,property:"maxLength",message:this.translate("error_maxLength",[a.maxLength])}),a.minLength&&(b+"").length<a.minLength&&k.push({path:e,property:"minLength",message:this.translate(1===a.minLength?"error_notempty":"error_minLength",[a.minLength])}),a.pattern&&(new RegExp(a.pattern).test(b)||k.push({path:e,property:"pattern",message:this.translate("error_pattern")}));else if("object"==typeof b&&null!==b&&Array.isArray(b)){if(a.items)if(Array.isArray(a.items))for(h=0;h<b.length;h++)if(a.items[h])k=k.concat(this._validateSchema(a.items[h],b[h],e+"."+h));else{if(a.additionalItems===!0)break;if(!a.additionalItems){if(a.additionalItems===!1){k.push({path:e,property:"additionalItems",message:this.translate("error_additionalItems")});break}break}k=k.concat(this._validateSchema(a.additionalItems,b[h],e+"."+h))}else for(h=0;h<b.length;h++)k=k.concat(this._validateSchema(a.items,b[h],e+"."+h));if(a.maxItems&&b.length>a.maxItems&&k.push({path:e,property:"maxItems",message:this.translate("error_maxItems",[a.maxItems])}),a.minItems&&b.length<a.minItems&&k.push({path:e,property:"minItems",message:this.translate("error_minItems",[a.minItems])}),a.uniqueItems){var o={};for(h=0;h<b.length;h++){if(g=JSON.stringify(b[h]),o[g]){k.push({path:e,property:"uniqueItems",message:this.translate("error_uniqueItems")});break}o[g]=!0}}}else if("object"==typeof b&&null!==b){if(a.maxProperties){g=0;for(h in b)b.hasOwnProperty(h)&&g++;g>a.maxProperties&&k.push({path:e,property:"maxProperties",message:this.translate("error_maxProperties",[a.maxProperties])})}if(a.minProperties){g=0;for(h in b)b.hasOwnProperty(h)&&g++;g<a.minProperties&&k.push({path:e,property:"minProperties",message:this.translate("error_minProperties",[a.minProperties])})}if(a.required&&Array.isArray(a.required))for(h=0;h<a.required.length;h++)"undefined"==typeof b[a.required[h]]&&k.push({path:e,property:"required",message:this.translate("error_required",[a.required[h]])});var p={};if(a.properties)for(h in a.properties)a.properties.hasOwnProperty(h)&&(p[h]=!0,k=k.concat(this._validateSchema(a.properties[h],b[h],e+"."+h)));if(a.patternProperties)for(h in a.patternProperties)if(a.patternProperties.hasOwnProperty(h)){var q=new RegExp(h);for(i in b)b.hasOwnProperty(i)&&q.test(i)&&(p[i]=!0,k=k.concat(this._validateSchema(a.patternProperties[h],b[i],e+"."+i)))}if("undefined"!=typeof a.additionalProperties||!this.jsoneditor.options.no_additional_properties||a.oneOf||a.anyOf||(a.additionalProperties=!1),"undefined"!=typeof a.additionalProperties)for(h in b)if(b.hasOwnProperty(h)&&!p[h]){if(!a.additionalProperties){k.push({path:e,property:"additionalProperties",message:this.translate("error_additional_properties",[h])});break}if(a.additionalProperties===!0)break;k=k.concat(this._validateSchema(a.additionalProperties,b[h],e+"."+h))}if(a.dependencies)for(h in a.dependencies)if(a.dependencies.hasOwnProperty(h)&&"undefined"!=typeof b[h])if(Array.isArray(a.dependencies[h]))for(i=0;i<a.dependencies[h].length;i++)"undefined"==typeof b[a.dependencies[h][i]]&&k.push({path:e,property:"dependencies",message:this.translate("error_dependency",[a.dependencies[h][i]])});else k=k.concat(this._validateSchema(a.dependencies[h],b,e))}return d(f.defaults.custom_validators,function(c,d){k=k.concat(d.call(j,a,b,e))}),k},_checkType:function(a,b){return"string"==typeof a?"string"===a?"string"==typeof b:"number"===a?"number"==typeof b:"integer"===a?"number"==typeof b&&b===Math.floor(b):"boolean"===a?"boolean"==typeof b:"array"===a?Array.isArray(b):"object"===a?null!==b&&!Array.isArray(b)&&"object"==typeof b:"null"===a?null===b:!0:!this._validateSchema(a,b).length}}),f.AbstractEditor=a.extend({onChildEditorChange:function(a){this.onChange(!0)},notify:function(){this.jsoneditor.notifyWatchers(this.path)},change:function(){this.parent?this.parent.onChildEditorChange(this):this.jsoneditor.onChange()},onChange:function(a){this.notify(),this.watch_listener&&this.watch_listener(),a&&this.change()},register:function(){this.jsoneditor.registerEditor(this),this.onChange()},unregister:function(){this.jsoneditor&&this.jsoneditor.unregisterEditor(this)},getNumColumns:function(){return 12},init:function(a){this.jsoneditor=a.jsoneditor,this.theme=this.jsoneditor.theme,this.template_engine=this.jsoneditor.template,this.iconlib=this.jsoneditor.iconlib,this.original_schema=a.schema,this.schema=this.jsoneditor.expandSchema(this.original_schema),this.options=c({},this.options||{},a.schema.options||{},a),a.path||this.schema.id||(this.schema.id="root"),this.path=a.path||"root",this.formname=a.formname||this.path.replace(/\.([^.]+)/g,"[$1]"),this.jsoneditor.options.form_name_root&&(this.formname=this.formname.replace(/^root\[/,this.jsoneditor.options.form_name_root+"[")),this.key=this.path.split(".").pop(),this.parent=a.parent,this.link_watchers=[],a.container&&this.setContainer(a.container)},setContainer:function(a){this.container=a,this.schema.id&&this.container.setAttribute("data-schemaid",this.schema.id),this.schema.type&&"string"==typeof this.schema.type&&this.container.setAttribute("data-schematype",this.schema.type),this.container.setAttribute("data-schemapath",this.path)},preBuild:function(){},build:function(){},postBuild:function(){this.setupWatchListeners(),this.addLinks(),this.setValue(this.getDefault(),!0),this.updateHeaderText(),this.register(),this.onWatchedFieldChange()},setupWatchListeners:function(){var a=this;if(this.watched={},this.schema.vars&&(this.schema.watch=this.schema.vars),this.watched_values={},this.watch_listener=function(){a.refreshWatchedFieldValues()&&a.onWatchedFieldChange()},this.register(),this.schema.hasOwnProperty("watch")){var b,c,d,e,f;for(var g in this.schema.watch)if(this.schema.watch.hasOwnProperty(g)){if(b=this.schema.watch[g],Array.isArray(b)?c=[b[0]].concat(b[1].split(".")):(c=b.split("."),a.theme.closest(a.container,'[data-schemaid="'+c[0]+'"]')||c.unshift("#")),d=c.shift(),"#"===d&&(d=a.jsoneditor.schema.id||"root"),e=a.theme.closest(a.container,'[data-schemaid="'+d+'"]'),!e)throw"Could not find ancestor node with id "+d;f=e.getAttribute("data-schemapath")+"."+c.join("."),a.jsoneditor.watch(f,a.watch_listener),a.watched[g]=f}}this.schema.headerTemplate&&(this.header_template=this.jsoneditor.compileTemplate(this.schema.headerTemplate,this.template_engine))},addLinks:function(){if(!this.no_link_holder&&(this.link_holder=this.theme.getLinksHolder(),this.container.appendChild(this.link_holder),this.schema.links))for(var a=0;a<this.schema.links.length;a++)this.addLink(this.getLink(this.schema.links[a]))},getButton:function(a,b,c){var d="json-editor-btn-"+b;b=this.iconlib?this.iconlib.getIcon(b):null,!b&&c&&(a=c,c=null);var e=this.theme.getButton(a,b,c);return e.className+=" "+d+" ",e},setButtonText:function(a,b,c,d){return c=this.iconlib?this.iconlib.getIcon(c):null,!c&&d&&(b=d,d=null),this.theme.setButtonText(a,b,c,d)},addLink:function(a){this.link_holder&&this.link_holder.appendChild(a)},getLink:function(a){var b,c,d=a.mediaType||"application/javascript",e=d.split("/")[0],f=this.jsoneditor.compileTemplate(a.href,this.template_engine);if("image"===e){b=this.theme.getBlockLinkHolder(),c=document.createElement("a"),c.setAttribute("target","_blank");var g=document.createElement("img");this.theme.createImageLink(b,c,g),this.link_watchers.push(function(b){var d=f(b);c.setAttribute("href",d),c.setAttribute("title",a.rel||d),g.setAttribute("src",d)})}else if(["audio","video"].indexOf(e)>=0){b=this.theme.getBlockLinkHolder(),c=this.theme.getBlockLink(),c.setAttribute("target","_blank");var h=document.createElement(e);h.setAttribute("controls","controls"),this.theme.createMediaLink(b,c,h),this.link_watchers.push(function(b){var d=f(b);c.setAttribute("href",d),c.textContent=a.rel||d,h.setAttribute("src",d)})}else b=this.theme.getBlockLink(),b.setAttribute("target","_blank"),b.textContent=a.rel,this.link_watchers.push(function(c){var d=f(c);b.setAttribute("href",d),b.textContent=a.rel||d});return b},refreshWatchedFieldValues:function(){if(this.watched_values){var a={},b=!1,c=this;if(this.watched){var d,e;for(var f in this.watched)this.watched.hasOwnProperty(f)&&(e=c.jsoneditor.getEditor(this.watched[f]),d=e?e.getValue():null,c.watched_values[f]!==d&&(b=!0),a[f]=d)}return a.self=this.getValue(),this.watched_values.self!==a.self&&(b=!0),this.watched_values=a,b}},getWatchedFieldValues:function(){return this.watched_values},updateHeaderText:function(){if(this.header)if(this.header.children.length){for(var a=0;a<this.header.childNodes.length;a++)if(3===this.header.childNodes[a].nodeType){this.header.childNodes[a].nodeValue=this.getHeaderText();break}}else this.header.textContent=this.getHeaderText()},getHeaderText:function(a){return this.header_text?this.header_text:a?this.schema.title:this.getTitle()},onWatchedFieldChange:function(){var a;if(this.header_template){a=c(this.getWatchedFieldValues(),{key:this.key,i:this.key,i0:1*this.key,i1:1*this.key+1,title:this.getTitle()});var b=this.header_template(a);b!==this.header_text&&(this.header_text=b,this.updateHeaderText(),this.notify())}if(this.link_watchers.length){a=this.getWatchedFieldValues();for(var d=0;d<this.link_watchers.length;d++)this.link_watchers[d](a)}},setValue:function(a){this.value=a},getValue:function(){return this.value},refreshValue:function(){},getChildEditors:function(){return!1},destroy:function(){var a=this;this.unregister(this),d(this.watched,function(b,c){a.jsoneditor.unwatch(c,a.watch_listener)}),this.watched=null,this.watched_values=null,this.watch_listener=null,this.header_text=null,this.header_template=null,this.value=null,this.container&&this.container.parentNode&&this.container.parentNode.removeChild(this.container),this.container=null,this.jsoneditor=null,this.schema=null,this.path=null,this.key=null,this.parent=null},getDefault:function(){if(this.schema["default"])return this.schema["default"];if(this.schema["enum"])return this.schema["enum"][0];var a=this.schema.type||this.schema.oneOf;if(a&&Array.isArray(a)&&(a=a[0]),a&&"object"==typeof a&&(a=a.type),a&&Array.isArray(a)&&(a=a[0]),"string"==typeof a){if("number"===a)return 0;if("boolean"===a)return!1;if("integer"===a)return 0;if("string"===a)return"";if("object"===a)return{};if("array"===a)return[]}return null},getTitle:function(){return this.schema.title||this.key},enable:function(){this.disabled=!1},disable:function(){this.disabled=!0},isEnabled:function(){return!this.disabled},isRequired:function(){return"boolean"==typeof this.schema.required?this.schema.required:this.parent&&this.parent.schema&&Array.isArray(this.parent.schema.required)?this.parent.schema.required.indexOf(this.key)>-1:this.jsoneditor.options.required_by_default?!0:!1},getDisplayText:function(a){var b=[],c={};d(a,function(a,b){b.title&&(c[b.title]=c[b.title]||0,c[b.title]++),b.description&&(c[b.description]=c[b.description]||0,c[b.description]++),b.format&&(c[b.format]=c[b.format]||0,c[b.format]++),b.type&&(c[b.type]=c[b.type]||0,c[b.type]++)}),d(a,function(a,d){var e;e="string"==typeof d?d:d.title&&c[d.title]<=1?d.title:d.format&&c[d.format]<=1?d.format:d.type&&c[d.type]<=1?d.type:d.description&&c[d.description]<=1?d.descripton:d.title?d.title:d.format?d.format:d.type?d.type:d.description?d.description:JSON.stringify(d).length<50?JSON.stringify(d):"type",b.push(e)});var e={};return d(b,function(a,d){e[d]=e[d]||0,e[d]++,c[d]>1&&(b[a]=d+" "+e[d])}),b},getOption:function(a){try{throw"getOption is deprecated"}catch(b){window.console.error(b)}return this.options[a]},showValidationErrors:function(a){}}),f.defaults.editors["null"]=f.AbstractEditor.extend({getValue:function(){return null},setValue:function(){this.onChange()},getNumColumns:function(){return 2}}),f.defaults.editors.string=f.AbstractEditor.extend({register:function(){this._super(),this.input&&this.input.setAttribute("name",this.formname)},unregister:function(){this._super(),this.input&&this.input.removeAttribute("name")},setValue:function(a,b,c){if((!this.template||c)&&(null===a||"undefined"==typeof a?a="":"object"==typeof a?a=JSON.stringify(a):"string"!=typeof a&&(a=""+a),a!==this.serialized)){var d=this.sanitize(a);if(this.input.value!==d){this.input.value=d,this.sceditor_instance?this.sceditor_instance.val(d):this.epiceditor?this.epiceditor.importFile(null,d):this.ace_editor&&this.ace_editor.setValue(d);var e=c||this.getValue()!==a;this.refreshValue(),b?this.is_dirty=!1:"change"===this.jsoneditor.options.show_errors&&(this.is_dirty=!0),this.adjust_height&&this.adjust_height(this.input),this.onChange(e)}}},getNumColumns:function(){var a,b=Math.ceil(Math.max(this.getTitle().length,this.schema.maxLength||0,this.schema.minLength||0)/5);return a="textarea"===this.input_type?6:["text","email"].indexOf(this.input_type)>=0?4:2,Math.min(12,Math.max(b,a))},build:function(){var a=this;if(this.options.compact||(this.header=this.label=this.theme.getFormInputLabel(this.getTitle(),this.isRequired())),this.schema.description&&(this.description=this.theme.getFormInputDescription(this.schema.description)),this.format=this.schema.format,!this.format&&this.schema.media&&this.schema.media.type&&(this.format=this.schema.media.type.replace(/(^(application|text)\/(x-)?(script\.)?)|(-source$)/g,"")),!this.format&&this.options.default_format&&(this.format=this.options.default_format),this.options.format&&(this.format=this.options.format),this.format)if("textarea"===this.format)this.input_type="textarea",this.input=this.theme.getTextareaInput();else if("range"===this.format){this.input_type="range";var b=this.schema.minimum||0,c=this.schema.maximum||Math.max(100,b+1),d=1;this.schema.multipleOf&&(b%this.schema.multipleOf&&(b=Math.ceil(b/this.schema.multipleOf)*this.schema.multipleOf),c%this.schema.multipleOf&&(c=Math.floor(c/this.schema.multipleOf)*this.schema.multipleOf),d=this.schema.multipleOf),this.input=this.theme.getRangeInput(b,c,d)}else["actionscript","batchfile","bbcode","c","c++","cpp","coffee","csharp","css","dart","django","ejs","erlang","golang","handlebars","haskell","haxe","html","ini","jade","java","javascript","json","less","lisp","lua","makefile","markdown","matlab","mysql","objectivec","pascal","perl","pgsql","php","python","r","ruby","sass","scala","scss","smarty","sql","stylus","svg","twig","vbscript","xml","yaml"].indexOf(this.format)>=0?(this.input_type=this.format,this.source_code=!0,this.input=this.theme.getTextareaInput()):(this.input_type=this.format,this.input=this.theme.getFormInputField(this.input_type));else this.input_type="text",this.input=this.theme.getFormInputField(this.input_type);"undefined"!=typeof this.schema.maxLength&&this.input.setAttribute("maxlength",this.schema.maxLength),"undefined"!=typeof this.schema.pattern?this.input.setAttribute("pattern",this.schema.pattern):"undefined"!=typeof this.schema.minLength&&this.input.setAttribute("pattern",".{"+this.schema.minLength+",}"),this.options.compact?this.container.className+=" compact":this.options.input_width&&(this.input.style.width=this.options.input_width),(this.schema.readOnly||this.schema.readonly||this.schema.template)&&(this.always_disabled=!0,this.input.disabled=!0),this.input.addEventListener("change",function(b){if(b.preventDefault(),b.stopPropagation(),a.schema.template)return void(this.value=a.value);var c=this.value,d=a.sanitize(c);c!==d&&(this.value=d),a.is_dirty=!0,a.refreshValue(),a.onChange(!0)}),this.options.input_height&&(this.input.style.height=this.options.input_height),this.options.expand_height&&(this.adjust_height=function(a){if(a){var b,c=a.offsetHeight;if(a.offsetHeight<a.scrollHeight)for(b=0;a.offsetHeight<a.scrollHeight+3&&!(b>100);)b++,c++,a.style.height=c+"px";else{for(b=0;a.offsetHeight>=a.scrollHeight+3&&!(b>100);)b++,c--,a.style.height=c+"px";a.style.height=c+1+"px"}}},this.input.addEventListener("keyup",function(b){a.adjust_height(this)}),this.input.addEventListener("change",function(b){a.adjust_height(this)}),this.adjust_height()),this.format&&this.input.setAttribute("data-schemaformat",this.format),this.control=this.theme.getFormControl(this.label,this.input,this.description),this.container.appendChild(this.control),window.requestAnimationFrame(function(){a.input.parentNode&&a.afterInputReady(),a.adjust_height&&a.adjust_height(a.input)}),this.schema.template?(this.template=this.jsoneditor.compileTemplate(this.schema.template,this.template_engine),this.refreshValue()):this.refreshValue()},enable:function(){this.always_disabled||(this.input.disabled=!1),this._super()},disable:function(){this.input.disabled=!0,this._super()},afterInputReady:function(){var a,b=this;if(this.source_code)if(this.options.wysiwyg&&["html","bbcode"].indexOf(this.input_type)>=0&&window.jQuery&&window.jQuery.fn&&window.jQuery.fn.sceditor)a=c({},{plugins:"html"===b.input_type?"xhtml":"bbcode",emoticonsEnabled:!1,width:"100%",height:300},f.plugins.sceditor,b.options.sceditor_options||{}),window.jQuery(b.input).sceditor(a),b.sceditor_instance=window.jQuery(b.input).sceditor("instance"),b.sceditor_instance.blur(function(){var a=window.jQuery("<div>"+b.sceditor_instance.val()+"</div>");window.jQuery("#sceditor-start-marker,#sceditor-end-marker,.sceditor-nlf",a).remove(),b.input.value=a.html(),b.value=b.input.value,b.is_dirty=!0,b.onChange(!0)});else if("markdown"===this.input_type&&window.EpicEditor)this.epiceditor_container=document.createElement("div"),this.input.parentNode.insertBefore(this.epiceditor_container,this.input),this.input.style.display="none",a=c({},f.plugins.epiceditor,{container:this.epiceditor_container,clientSideStorage:!1}),this.epiceditor=new window.EpicEditor(a).load(),this.epiceditor.importFile(null,this.getValue()),this.epiceditor.on("update",function(){var a=b.epiceditor.exportFile();b.input.value=a,b.value=a,b.is_dirty=!0,b.onChange(!0);
+});else if(window.ace){var d=this.input_type;("cpp"===d||"c++"===d||"c"===d)&&(d="c_cpp"),this.ace_container=document.createElement("div"),this.ace_container.style.width="100%",this.ace_container.style.position="relative",this.ace_container.style.height="400px",this.input.parentNode.insertBefore(this.ace_container,this.input),this.input.style.display="none",this.ace_editor=window.ace.edit(this.ace_container),this.ace_editor.setValue(this.getValue()),f.plugins.ace.theme&&this.ace_editor.setTheme("ace/theme/"+f.plugins.ace.theme),d=window.ace.require("ace/mode/"+d),d&&this.ace_editor.getSession().setMode(new d.Mode),this.ace_editor.on("change",function(){var a=b.ace_editor.getValue();b.input.value=a,b.refreshValue(),b.is_dirty=!0,b.onChange(!0)})}b.theme.afterInputReady(b.input)},refreshValue:function(){this.value=this.input.value,"string"!=typeof this.value&&(this.value=""),this.serialized=this.value},destroy:function(){this.sceditor_instance?this.sceditor_instance.destroy():this.epiceditor?this.epiceditor.unload():this.ace_editor&&this.ace_editor.destroy(),this.template=null,this.input&&this.input.parentNode&&this.input.parentNode.removeChild(this.input),this.label&&this.label.parentNode&&this.label.parentNode.removeChild(this.label),this.description&&this.description.parentNode&&this.description.parentNode.removeChild(this.description),this._super()},sanitize:function(a){return a},onWatchedFieldChange:function(){var a;this.template&&(a=this.getWatchedFieldValues(),this.setValue(this.template(a),!1,!0)),this._super()},showValidationErrors:function(a){var b=this;if("always"===this.jsoneditor.options.show_errors);else if(!this.is_dirty&&this.previous_error_setting===this.jsoneditor.options.show_errors)return;this.previous_error_setting=this.jsoneditor.options.show_errors;var c=[];d(a,function(a,d){d.path===b.path&&c.push(d.message)}),c.length?this.theme.addInputError(this.input,c.join(". ")+"."):this.theme.removeInputError(this.input)}}),f.defaults.editors.number=f.defaults.editors.string.extend({sanitize:function(a){return(a+"").replace(/[^0-9\.\-eE]/g,"")},getNumColumns:function(){return 2},getValue:function(){return 1*this.value}}),f.defaults.editors.integer=f.defaults.editors.number.extend({sanitize:function(a){return a+="",a.replace(/[^0-9\-]/g,"")},getNumColumns:function(){return 2}}),f.defaults.editors.object=f.AbstractEditor.extend({getDefault:function(){return c({},this.schema["default"]||{})},getChildEditors:function(){return this.editors},register:function(){if(this._super(),this.editors)for(var a in this.editors)this.editors.hasOwnProperty(a)&&this.editors[a].register()},unregister:function(){if(this._super(),this.editors)for(var a in this.editors)this.editors.hasOwnProperty(a)&&this.editors[a].unregister()},getNumColumns:function(){return Math.max(Math.min(12,this.maxwidth),3)},enable:function(){if(this.editjson_button&&(this.editjson_button.disabled=!1),this.addproperty_button&&(this.addproperty_button.disabled=!1),this._super(),this.editors)for(var a in this.editors)this.editors.hasOwnProperty(a)&&this.editors[a].enable()},disable:function(){if(this.editjson_button&&(this.editjson_button.disabled=!0),this.addproperty_button&&(this.addproperty_button.disabled=!0),this.hideEditJSON(),this._super(),this.editors)for(var a in this.editors)this.editors.hasOwnProperty(a)&&this.editors[a].disable()},layoutEditors:function(){var a,b,c=this;if(this.row_container){this.property_order=Object.keys(this.editors),this.property_order=this.property_order.sort(function(a,b){var d=c.editors[a].schema.propertyOrder,e=c.editors[b].schema.propertyOrder;return"number"!=typeof d&&(d=1e3),"number"!=typeof e&&(e=1e3),d-e});var e;if("grid"===this.format){var f=[];for(d(this.property_order,function(a,b){var d=c.editors[b];if(!d.property_removed){for(var e=!1,g=d.options.hidden?0:d.options.grid_columns||d.getNumColumns(),h=d.options.hidden?0:d.container.offsetHeight,i=0;i<f.length;i++)f[i].width+g<=12&&(!h||.5*f[i].minh<h&&2*f[i].maxh>h)&&(e=i);e===!1&&(f.push({width:0,minh:999999,maxh:0,editors:[]}),e=f.length-1),f[e].editors.push({key:b,width:g,height:h}),f[e].width+=g,f[e].minh=Math.min(f[e].minh,h),f[e].maxh=Math.max(f[e].maxh,h)}}),a=0;a<f.length;a++)if(f[a].width<12){var g=!1,h=0;for(b=0;b<f[a].editors.length;b++)g===!1?g=b:f[a].editors[b].width>f[a].editors[g].width&&(g=b),f[a].editors[b].width*=12/f[a].width,f[a].editors[b].width=Math.floor(f[a].editors[b].width),h+=f[a].editors[b].width;12>h&&(f[a].editors[g].width+=12-h),f[a].width=12}if(this.layout===JSON.stringify(f))return!1;for(this.layout=JSON.stringify(f),e=document.createElement("div"),a=0;a<f.length;a++){var i=this.theme.getGridRow();for(e.appendChild(i),b=0;b<f[a].editors.length;b++){var j=f[a].editors[b].key,k=this.editors[j];k.options.hidden?k.container.style.display="none":this.theme.setGridColumnSize(k.container,f[a].editors[b].width),i.appendChild(k.container)}}}else e=document.createElement("div"),d(this.property_order,function(a,b){var d=c.editors[b];if(!d.property_removed){var f=c.theme.getGridRow();e.appendChild(f),d.options.hidden?d.container.style.display="none":c.theme.setGridColumnSize(d.container,12),f.appendChild(d.container)}});this.row_container.innerHTML="",this.row_container.appendChild(e)}},getPropertySchema:function(a){var b=this.schema.properties[a]||{};b=c({},b);var d=this.schema.properties[a]?!0:!1;if(this.schema.patternProperties)for(var e in this.schema.patternProperties)if(this.schema.patternProperties.hasOwnProperty(e)){var f=new RegExp(e);f.test(a)&&(b.allOf=b.allOf||[],b.allOf.push(this.schema.patternProperties[e]),d=!0)}return!d&&this.schema.additionalProperties&&"object"==typeof this.schema.additionalProperties&&(b=c({},this.schema.additionalProperties)),b},preBuild:function(){this._super(),this.editors={},this.cached_editors={};var a=this;if(this.format=this.options.layout||this.options.object_layout||this.schema.format||this.jsoneditor.options.object_layout||"normal",this.schema.properties=this.schema.properties||{},this.minwidth=0,this.maxwidth=0,this.options.table_row)d(this.schema.properties,function(b,c){var d=a.jsoneditor.getEditorClass(c);a.editors[b]=a.jsoneditor.createEditor(d,{jsoneditor:a.jsoneditor,schema:c,path:a.path+"."+b,parent:a,compact:!0,required:!0}),a.editors[b].preBuild();var e=a.editors[b].options.hidden?0:a.editors[b].options.grid_columns||a.editors[b].getNumColumns();a.minwidth+=e,a.maxwidth+=e}),this.no_link_holder=!0;else{if(this.options.table)throw"Not supported yet";this.defaultProperties=this.schema.defaultProperties||Object.keys(this.schema.properties),a.maxwidth+=1,d(this.defaultProperties,function(b,c){a.addObjectProperty(c,!0),a.editors[c]&&(a.minwidth=Math.max(a.minwidth,a.editors[c].options.grid_columns||a.editors[c].getNumColumns()),a.maxwidth+=a.editors[c].options.grid_columns||a.editors[c].getNumColumns())})}this.property_order=Object.keys(this.editors),this.property_order=this.property_order.sort(function(b,c){var d=a.editors[b].schema.propertyOrder,e=a.editors[c].schema.propertyOrder;return"number"!=typeof d&&(d=1e3),"number"!=typeof e&&(e=1e3),d-e})},build:function(){var a=this;if(this.options.table_row)this.editor_holder=this.container,d(this.editors,function(b,c){var d=a.theme.getTableCell();a.editor_holder.appendChild(d),c.setContainer(d),c.build(),c.postBuild(),a.editors[b].options.hidden&&(d.style.display="none"),a.editors[b].options.input_width&&(d.style.width=a.editors[b].options.input_width)});else{if(this.options.table)throw"Not supported yet";this.header=document.createElement("span"),this.header.textContent=this.getTitle(),this.title=this.theme.getHeader(this.header),this.container.appendChild(this.title),this.container.style.position="relative",this.editjson_holder=this.theme.getModal(),this.editjson_textarea=this.theme.getTextareaInput(),this.editjson_textarea.style.height="170px",this.editjson_textarea.style.width="300px",this.editjson_textarea.style.display="block",this.editjson_save=this.getButton("Save","save","Save"),this.editjson_save.addEventListener("click",function(b){b.preventDefault(),b.stopPropagation(),a.saveJSON()}),this.editjson_cancel=this.getButton("Cancel","cancel","Cancel"),this.editjson_cancel.addEventListener("click",function(b){b.preventDefault(),b.stopPropagation(),a.hideEditJSON()}),this.editjson_holder.appendChild(this.editjson_textarea),this.editjson_holder.appendChild(this.editjson_save),this.editjson_holder.appendChild(this.editjson_cancel),this.addproperty_holder=this.theme.getModal(),this.addproperty_list=document.createElement("div"),this.addproperty_list.style.width="295px",this.addproperty_list.style.maxHeight="160px",this.addproperty_list.style.padding="5px 0",this.addproperty_list.style.overflowY="auto",this.addproperty_list.style.overflowX="hidden",this.addproperty_list.style.paddingLeft="5px",this.addproperty_list.setAttribute("class","property-selector"),this.addproperty_add=this.getButton("add","add","add"),this.addproperty_input=this.theme.getFormInputField("text"),this.addproperty_input.setAttribute("placeholder","Property name..."),this.addproperty_input.style.width="220px",this.addproperty_input.style.marginBottom="0",this.addproperty_input.style.display="inline-block",this.addproperty_add.addEventListener("click",function(b){if(b.preventDefault(),b.stopPropagation(),a.addproperty_input.value){if(a.editors[a.addproperty_input.value])return void window.alert("there is already a property with that name");a.addObjectProperty(a.addproperty_input.value),a.editors[a.addproperty_input.value]&&a.editors[a.addproperty_input.value].disable(),a.onChange(!0)}}),this.addproperty_holder.appendChild(this.addproperty_list),this.addproperty_holder.appendChild(this.addproperty_input),this.addproperty_holder.appendChild(this.addproperty_add);var b=document.createElement("div");b.style.clear="both",this.addproperty_holder.appendChild(b),this.schema.description&&(this.description=this.theme.getDescription(this.schema.description),this.container.appendChild(this.description)),this.error_holder=document.createElement("div"),this.container.appendChild(this.error_holder),this.editor_holder=this.theme.getIndentedPanel(),this.editor_holder.style.paddingBottom="0",this.container.appendChild(this.editor_holder),this.row_container=this.theme.getGridContainer(),this.editor_holder.appendChild(this.row_container),d(this.editors,function(b,c){var d=a.theme.getGridColumn();a.row_container.appendChild(d),c.setContainer(d),c.build(),c.postBuild()}),this.title_controls=this.theme.getHeaderButtonHolder(),this.editjson_controls=this.theme.getHeaderButtonHolder(),this.addproperty_controls=this.theme.getHeaderButtonHolder(),this.title.appendChild(this.title_controls),this.title.appendChild(this.editjson_controls),this.title.appendChild(this.addproperty_controls),this.collapsed=!1,this.toggle_button=this.getButton("","collapse","Collapse"),this.title_controls.appendChild(this.toggle_button),this.toggle_button.addEventListener("click",function(b){b.preventDefault(),b.stopPropagation(),a.collapsed?(a.editor_holder.style.display="",a.collapsed=!1,a.setButtonText(a.toggle_button,"","collapse","Collapse")):(a.editor_holder.style.display="none",a.collapsed=!0,a.setButtonText(a.toggle_button,"","expand","Expand"))}),this.options.collapsed&&e(this.toggle_button,"click"),this.schema.options&&"undefined"!=typeof this.schema.options.disable_collapse?this.schema.options.disable_collapse&&(this.toggle_button.style.display="none"):this.jsoneditor.options.disable_collapse&&(this.toggle_button.style.display="none"),this.editjson_button=this.getButton("JSON","edit","Edit JSON"),this.editjson_button.addEventListener("click",function(b){b.preventDefault(),b.stopPropagation(),a.toggleEditJSON()}),this.editjson_controls.appendChild(this.editjson_button),this.editjson_controls.appendChild(this.editjson_holder),this.schema.options&&"undefined"!=typeof this.schema.options.disable_edit_json?this.schema.options.disable_edit_json&&(this.editjson_button.style.display="none"):this.jsoneditor.options.disable_edit_json&&(this.editjson_button.style.display="none"),this.addproperty_button=this.getButton("Properties","edit","Object Properties"),this.addproperty_button.addEventListener("click",function(b){b.preventDefault(),b.stopPropagation(),a.toggleAddProperty()}),this.addproperty_controls.appendChild(this.addproperty_button),this.addproperty_controls.appendChild(this.addproperty_holder),this.refreshAddProperties()}this.options.table_row?(this.editor_holder=this.container,d(this.property_order,function(b,c){a.editor_holder.appendChild(a.editors[c].container)})):(this.layoutEditors(),this.layoutEditors())},showEditJSON:function(){this.editjson_holder&&(this.hideAddProperty(),this.editjson_holder.style.left=this.editjson_button.offsetLeft+"px",this.editjson_holder.style.top=this.editjson_button.offsetTop+this.editjson_button.offsetHeight+"px",this.editjson_textarea.value=JSON.stringify(this.getValue(),null,2),this.disable(),this.editjson_holder.style.display="",this.editjson_button.disabled=!1,this.editing_json=!0)},hideEditJSON:function(){this.editjson_holder&&this.editing_json&&(this.editjson_holder.style.display="none",this.enable(),this.editing_json=!1)},saveJSON:function(){if(this.editjson_holder)try{var a=JSON.parse(this.editjson_textarea.value);this.setValue(a),this.hideEditJSON()}catch(b){throw window.alert("invalid JSON"),b}},toggleEditJSON:function(){this.editing_json?this.hideEditJSON():this.showEditJSON()},insertPropertyControlUsingPropertyOrder:function(a,b,c){var d;this.schema.properties[a]&&(d=this.schema.properties[a].propertyOrder),"number"!=typeof d&&(d=1e3),b.propertyOrder=d;for(var e=0;e<c.childNodes.length;e++){var f=c.childNodes[e];if(b.propertyOrder<f.propertyOrder){this.addproperty_list.insertBefore(b,f),b=null;break}}b&&this.addproperty_list.appendChild(b)},addPropertyCheckbox:function(a){var b,c,d,e,f=this;return b=f.theme.getCheckbox(),b.style.width="auto",d=this.schema.properties[a]&&this.schema.properties[a].title?this.schema.properties[a].title:a,c=f.theme.getCheckboxLabel(d),e=f.theme.getFormControl(c,b),e.style.paddingBottom=e.style.marginBottom=e.style.paddingTop=e.style.marginTop=0,e.style.height="auto",this.insertPropertyControlUsingPropertyOrder(a,e,this.addproperty_list),b.checked=a in this.editors,b.addEventListener("change",function(){b.checked?f.addObjectProperty(a):f.removeObjectProperty(a),f.onChange(!0)}),f.addproperty_checkboxes[a]=b,b},showAddProperty:function(){this.addproperty_holder&&(this.hideEditJSON(),this.addproperty_holder.style.left=this.addproperty_button.offsetLeft+"px",this.addproperty_holder.style.top=this.addproperty_button.offsetTop+this.addproperty_button.offsetHeight+"px",this.disable(),this.adding_property=!0,this.addproperty_button.disabled=!1,this.addproperty_holder.style.display="",this.refreshAddProperties())},hideAddProperty:function(){this.addproperty_holder&&this.adding_property&&(this.addproperty_holder.style.display="none",this.enable(),this.adding_property=!1)},toggleAddProperty:function(){this.adding_property?this.hideAddProperty():this.showAddProperty()},removeObjectProperty:function(a){this.editors[a]&&(this.editors[a].unregister(),delete this.editors[a],this.refreshValue(),this.layoutEditors())},addObjectProperty:function(a,b){var c=this;if(!this.editors[a]){if(this.cached_editors[a]){if(this.editors[a]=this.cached_editors[a],b)return;this.editors[a].register()}else{if(!(this.canHaveAdditionalProperties()||this.schema.properties&&this.schema.properties[a]))return;var d=c.getPropertySchema(a),e=c.jsoneditor.getEditorClass(d);if(c.editors[a]=c.jsoneditor.createEditor(e,{jsoneditor:c.jsoneditor,schema:d,path:c.path+"."+a,parent:c}),c.editors[a].preBuild(),!b){var f=c.theme.getChildEditorHolder();c.editor_holder.appendChild(f),c.editors[a].setContainer(f),c.editors[a].build(),c.editors[a].postBuild()}c.cached_editors[a]=c.editors[a]}b||(c.refreshValue(),c.layoutEditors())}},onChildEditorChange:function(a){this.refreshValue(),this._super(a)},canHaveAdditionalProperties:function(){return"boolean"==typeof this.schema.additionalProperties?this.schema.additionalProperties:!this.jsoneditor.options.no_additional_properties},destroy:function(){d(this.cached_editors,function(a,b){b.destroy()}),this.editor_holder&&(this.editor_holder.innerHTML=""),this.title&&this.title.parentNode&&this.title.parentNode.removeChild(this.title),this.error_holder&&this.error_holder.parentNode&&this.error_holder.parentNode.removeChild(this.error_holder),this.editors=null,this.cached_editors=null,this.editor_holder&&this.editor_holder.parentNode&&this.editor_holder.parentNode.removeChild(this.editor_holder),this.editor_holder=null,this._super()},getValue:function(){var a=this._super();if(this.jsoneditor.options.remove_empty_properties||this.options.remove_empty_properties)for(var b in a)a.hasOwnProperty(b)&&(a[b]||delete a[b]);return a},refreshValue:function(){this.value={};for(var a in this.editors)this.editors.hasOwnProperty(a)&&(this.value[a]=this.editors[a].getValue());this.adding_property&&this.refreshAddProperties()},refreshAddProperties:function(){if(this.options.disable_properties||this.options.disable_properties!==!1&&this.jsoneditor.options.disable_properties)return void(this.addproperty_controls.style.display="none");var a,b=!1,c=!1,d=0,e=!1;for(a in this.editors)this.editors.hasOwnProperty(a)&&d++;b=this.canHaveAdditionalProperties()&&!("undefined"!=typeof this.schema.maxProperties&&d>=this.schema.maxProperties),this.addproperty_checkboxes&&(this.addproperty_list.innerHTML=""),this.addproperty_checkboxes={};for(a in this.cached_editors)this.cached_editors.hasOwnProperty(a)&&(this.addPropertyCheckbox(a),this.isRequired(this.cached_editors[a])&&a in this.editors&&(this.addproperty_checkboxes[a].disabled=!0),"undefined"!=typeof this.schema.minProperties&&d<=this.schema.minProperties?(this.addproperty_checkboxes[a].disabled=this.addproperty_checkboxes[a].checked,this.addproperty_checkboxes[a].checked||(e=!0)):a in this.editors?(e=!0,c=!0):b||this.schema.properties.hasOwnProperty(a)?(this.addproperty_checkboxes[a].disabled=!1,e=!0):this.addproperty_checkboxes[a].disabled=!0);this.canHaveAdditionalProperties()&&(e=!0);for(a in this.schema.properties)this.schema.properties.hasOwnProperty(a)&&(this.cached_editors[a]||(e=!0,this.addPropertyCheckbox(a)));e?this.canHaveAdditionalProperties()?b?this.addproperty_add.disabled=!1:this.addproperty_add.disabled=!0:(this.addproperty_add.style.display="none",this.addproperty_input.style.display="none"):(this.hideAddProperty(),this.addproperty_controls.style.display="none")},isRequired:function(a){return"boolean"==typeof a.schema.required?a.schema.required:Array.isArray(this.schema.required)?this.schema.required.indexOf(a.key)>-1:this.jsoneditor.options.required_by_default?!0:!1},setValue:function(a,b){var c=this;a=a||{},("object"!=typeof a||Array.isArray(a))&&(a={}),d(this.cached_editors,function(d,e){"undefined"!=typeof a[d]?(c.addObjectProperty(d),e.setValue(a[d],b)):b||c.isRequired(e)?e.setValue(e.getDefault(),b):c.removeObjectProperty(d)}),d(a,function(a,d){c.cached_editors[a]||(c.addObjectProperty(a),c.editors[a]&&c.editors[a].setValue(d,b))}),this.refreshValue(),this.layoutEditors(),this.onChange()},showValidationErrors:function(a){var b=this,c=[],e=[];if(d(a,function(a,d){d.path===b.path?c.push(d):e.push(d)}),this.error_holder)if(c.length){this.error_holder.innerHTML="",this.error_holder.style.display="",d(c,function(a,c){b.error_holder.appendChild(b.theme.getErrorMessage(c.message))})}else this.error_holder.style.display="none";this.options.table_row&&(c.length?this.theme.addTableRowError(this.container):this.theme.removeTableRowError(this.container)),d(this.editors,function(a,b){b.showValidationErrors(e)})}}),f.defaults.editors.array=f.AbstractEditor.extend({getDefault:function(){return this.schema["default"]||[]},register:function(){if(this._super(),this.rows)for(var a=0;a<this.rows.length;a++)this.rows[a].register()},unregister:function(){if(this._super(),this.rows)for(var a=0;a<this.rows.length;a++)this.rows[a].unregister()},getNumColumns:function(){var a=this.getItemInfo(0);return this.tabs_holder?Math.max(Math.min(12,a.width+2),4):a.width},enable:function(){if(this.add_row_button&&(this.add_row_button.disabled=!1),this.remove_all_rows_button&&(this.remove_all_rows_button.disabled=!1),this.delete_last_row_button&&(this.delete_last_row_button.disabled=!1),this.rows)for(var a=0;a<this.rows.length;a++)this.rows[a].enable(),this.rows[a].moveup_button&&(this.rows[a].moveup_button.disabled=!1),this.rows[a].movedown_button&&(this.rows[a].movedown_button.disabled=!1),this.rows[a].delete_button&&(this.rows[a].delete_button.disabled=!1);this._super()},disable:function(){if(this.add_row_button&&(this.add_row_button.disabled=!0),this.remove_all_rows_button&&(this.remove_all_rows_button.disabled=!0),this.delete_last_row_button&&(this.delete_last_row_button.disabled=!0),this.rows)for(var a=0;a<this.rows.length;a++)this.rows[a].disable(),this.rows[a].moveup_button&&(this.rows[a].moveup_button.disabled=!0),this.rows[a].movedown_button&&(this.rows[a].movedown_button.disabled=!0),this.rows[a].delete_button&&(this.rows[a].delete_button.disabled=!0);this._super()},preBuild:function(){this._super(),this.rows=[],this.row_cache=[],this.hide_delete_buttons=this.options.disable_array_delete||this.jsoneditor.options.disable_array_delete,this.hide_move_buttons=this.options.disable_array_reorder||this.jsoneditor.options.disable_array_reorder,this.hide_add_button=this.options.disable_array_add||this.jsoneditor.options.disable_array_add},build:function(){this.options.compact?(this.panel=this.theme.getIndentedPanel(),this.container.appendChild(this.panel),this.controls=this.theme.getButtonHolder(),this.panel.appendChild(this.controls),this.row_holder=document.createElement("div"),this.panel.appendChild(this.row_holder)):(this.header=document.createElement("span"),this.header.textContent=this.getTitle(),this.title=this.theme.getHeader(this.header,this.isRequired()),this.container.appendChild(this.title),this.title_controls=this.theme.getHeaderButtonHolder(),this.title.appendChild(this.title_controls),this.schema.description&&(this.description=this.theme.getDescription(this.schema.description),this.container.appendChild(this.description)),this.error_holder=document.createElement("div"),this.container.appendChild(this.error_holder),"tabs"===this.schema.format?(this.controls=this.theme.getHeaderButtonHolder(),this.title.appendChild(this.controls),this.tabs_holder=this.theme.getTabHolder(),this.container.appendChild(this.tabs_holder),this.row_holder=this.theme.getTabContentHolder(this.tabs_holder),this.active_tab=null):(this.panel=this.theme.getIndentedPanel(),this.container.appendChild(this.panel),this.row_holder=document.createElement("div"),this.panel.appendChild(this.row_holder),this.controls=this.theme.getButtonHolder(),this.panel.appendChild(this.controls))),this.addControls()},onChildEditorChange:function(a){this.refreshValue(),this.refreshTabs(!0),this._super(a)},getItemTitle:function(){if(!this.item_title)if(this.schema.items&&!Array.isArray(this.schema.items)){var a=this.jsoneditor.expandRefs(this.schema.items);this.item_title=a.title||"item"}else this.item_title="item";return this.item_title},getItemSchema:function(a){return Array.isArray(this.schema.items)?a>=this.schema.items.length?this.schema.additionalItems===!0?{}:this.schema.additionalItems?c({},this.schema.additionalItems):void 0:c({},this.schema.items[a]):this.schema.items?c({},this.schema.items):{}},getItemInfo:function(a){var b=this.getItemSchema(a);this.item_info=this.item_info||{};var c=JSON.stringify(b);return"undefined"!=typeof this.item_info[c]?this.item_info[c]:(b=this.jsoneditor.expandRefs(b),this.item_info[c]={title:b.title||"item","default":b["default"],width:12,child_editors:b.properties||b.items},this.item_info[c])},getElementEditor:function(a){var b=this.getItemInfo(a),c=this.getItemSchema(a);c=this.jsoneditor.expandRefs(c),c.title=b.title+" "+(a+1);var d,e=this.jsoneditor.getEditorClass(c);d=this.tabs_holder?this.theme.getTabContent():b.child_editors?this.theme.getChildEditorHolder():this.theme.getIndentedPanel(),this.row_holder.appendChild(d);var f=this.jsoneditor.createEditor(e,{jsoneditor:this.jsoneditor,schema:c,container:d,path:this.path+"."+a,parent:this,required:!0});return f.preBuild(),f.build(),f.postBuild(),f.title_controls||(f.array_controls=this.theme.getButtonHolder(),d.appendChild(f.array_controls)),f},destroy:function(){this.empty(!0),this.title&&this.title.parentNode&&this.title.parentNode.removeChild(this.title),this.description&&this.description.parentNode&&this.description.parentNode.removeChild(this.description),this.row_holder&&this.row_holder.parentNode&&this.row_holder.parentNode.removeChild(this.row_holder),this.controls&&this.controls.parentNode&&this.controls.parentNode.removeChild(this.controls),this.panel&&this.panel.parentNode&&this.panel.parentNode.removeChild(this.panel),this.rows=this.row_cache=this.title=this.description=this.row_holder=this.panel=this.controls=null,this._super()},empty:function(a){if(this.rows){var b=this;d(this.rows,function(c,d){a&&(d.tab&&d.tab.parentNode&&d.tab.parentNode.removeChild(d.tab),b.destroyRow(d,!0),b.row_cache[c]=null),b.rows[c]=null}),b.rows=[],a&&(b.row_cache=[])}},destroyRow:function(a,b){var c=a.container;b?(a.destroy(),c.parentNode&&c.parentNode.removeChild(c),a.tab&&a.tab.parentNode&&a.tab.parentNode.removeChild(a.tab)):(a.tab&&(a.tab.style.display="none"),c.style.display="none",a.unregister())},getMax:function(){return Array.isArray(this.schema.items)&&this.schema.additionalItems===!1?Math.min(this.schema.items.length,this.schema.maxItems||1/0):this.schema.maxItems||1/0},refreshTabs:function(a){var b=this;d(this.rows,function(c,d){d.tab&&(a?d.tab_text.textContent=d.getHeaderText():d.tab===b.active_tab?(b.theme.markTabActive(d.tab),d.container.style.display=""):(b.theme.markTabInactive(d.tab),d.container.style.display="none"))})},setValue:function(a,b){a=a||[],Array.isArray(a)||(a=[a]);var c=JSON.stringify(a);if(c!==this.serialized){if(this.schema.minItems)for(;a.length<this.schema.minItems;)a.push(this.getItemInfo(a.length)["default"]);this.getMax()&&a.length>this.getMax()&&(a=a.slice(0,this.getMax()));var e=this;d(a,function(a,c){e.rows[a]?e.rows[a].setValue(c,b):e.row_cache[a]?(e.rows[a]=e.row_cache[a],e.rows[a].setValue(c,b),e.rows[a].container.style.display="",e.rows[a].tab&&(e.rows[a].tab.style.display=""),e.rows[a].register()):e.addRow(c,b)});for(var f=a.length;f<e.rows.length;f++)e.destroyRow(e.rows[f]),e.rows[f]=null;e.rows=e.rows.slice(0,a.length);var g=null;d(e.rows,function(a,b){return b.tab===e.active_tab?(g=b.tab,!1):void 0}),!g&&e.rows.length&&(g=e.rows[0].tab),e.active_tab=g,e.refreshValue(b),e.refreshTabs(!0),e.refreshTabs(),e.onChange()}},refreshValue:function(a){var b=this,c=this.value?this.value.length:0;if(this.value=[],d(this.rows,function(a,c){b.value[a]=c.getValue()}),c!==this.value.length||a){var e=this.schema.minItems&&this.schema.minItems>=this.rows.length;d(this.rows,function(a,c){c.movedown_button&&(a===b.rows.length-1?c.movedown_button.style.display="none":c.movedown_button.style.display=""),c.delete_button&&(e?c.delete_button.style.display="none":c.delete_button.style.display=""),b.value[a]=c.getValue()});var f=!1;this.value.length?1===this.value.length?(this.remove_all_rows_button.style.display="none",e||this.hide_delete_buttons?this.delete_last_row_button.style.display="none":(this.delete_last_row_button.style.display="",f=!0)):e||this.hide_delete_buttons?(this.delete_last_row_button.style.display="none",this.remove_all_rows_button.style.display="none"):(this.delete_last_row_button.style.display="",this.remove_all_rows_button.style.display="",f=!0):(this.delete_last_row_button.style.display="none",this.remove_all_rows_button.style.display="none"),this.getMax()&&this.getMax()<=this.rows.length||this.hide_add_button?this.add_row_button.style.display="none":(this.add_row_button.style.display="",f=!0),!this.collapsed&&f?this.controls.style.display="inline-block":this.controls.style.display="none"}},addRow:function(a,b){var c=this,e=this.rows.length;c.rows[e]=this.getElementEditor(e),c.row_cache[e]=c.rows[e],c.tabs_holder&&(c.rows[e].tab_text=document.createElement("span"),c.rows[e].tab_text.textContent=c.rows[e].getHeaderText(),c.rows[e].tab=c.theme.getTab(c.rows[e].tab_text),c.rows[e].tab.addEventListener("click",function(a){c.active_tab=c.rows[e].tab,c.refreshTabs(),a.preventDefault(),a.stopPropagation()}),c.theme.addTab(c.tabs_holder,c.rows[e].tab));var f=c.rows[e].title_controls||c.rows[e].array_controls;c.hide_delete_buttons||(c.rows[e].delete_button=this.getButton(c.getItemTitle(),"delete","Delete "+c.getItemTitle()),c.rows[e].delete_button.className+=" delete",c.rows[e].delete_button.setAttribute("data-i",e),c.rows[e].delete_button.addEventListener("click",function(a){a.preventDefault(),a.stopPropagation();var b=1*this.getAttribute("data-i"),e=c.getValue(),f=[],g=null;d(e,function(a,d){return a===b?void(c.rows[a].tab===c.active_tab&&(c.rows[a+1]?g=c.rows[a].tab:a&&(g=c.rows[a-1].tab))):void f.push(d)}),c.setValue(f),g&&(c.active_tab=g,c.refreshTabs()),c.onChange(!0)}),f&&f.appendChild(c.rows[e].delete_button)),e&&!c.hide_move_buttons&&(c.rows[e].moveup_button=this.getButton("","moveup","Move up"),c.rows[e].moveup_button.className+=" moveup",c.rows[e].moveup_button.setAttribute("data-i",e),c.rows[e].moveup_button.addEventListener("click",function(a){a.preventDefault(),a.stopPropagation();var b=1*this.getAttribute("data-i");if(!(0>=b)){var d=c.getValue(),e=d[b-1];d[b-1]=d[b],d[b]=e,c.setValue(d),c.active_tab=c.rows[b-1].tab,c.refreshTabs(),c.onChange(!0)}}),f&&f.appendChild(c.rows[e].moveup_button)),c.hide_move_buttons||(c.rows[e].movedown_button=this.getButton("","movedown","Move down"),c.rows[e].movedown_button.className+=" movedown",c.rows[e].movedown_button.setAttribute("data-i",e),c.rows[e].movedown_button.addEventListener("click",function(a){a.preventDefault(),a.stopPropagation();var b=1*this.getAttribute("data-i"),d=c.getValue();if(!(b>=d.length-1)){var e=d[b+1];d[b+1]=d[b],d[b]=e,c.setValue(d),c.active_tab=c.rows[b+1].tab,c.refreshTabs(),c.onChange(!0)}}),f&&f.appendChild(c.rows[e].movedown_button)),a&&c.rows[e].setValue(a,b),c.refreshTabs()},addControls:function(){var a=this;this.collapsed=!1,this.toggle_button=this.getButton("","collapse","Collapse"),this.title_controls.appendChild(this.toggle_button);var b=a.row_holder.style.display,c=a.controls.style.display;this.toggle_button.addEventListener("click",function(d){d.preventDefault(),d.stopPropagation(),a.collapsed?(a.collapsed=!1,a.panel&&(a.panel.style.display=""),a.row_holder.style.display=b,a.tabs_holder&&(a.tabs_holder.style.display=""),a.controls.style.display=c,a.setButtonText(this,"","collapse","Collapse")):(a.collapsed=!0,a.row_holder.style.display="none",a.tabs_holder&&(a.tabs_holder.style.display="none"),a.controls.style.display="none",a.panel&&(a.panel.style.display="none"),a.setButtonText(this,"","expand","Expand"))}),this.options.collapsed&&e(this.toggle_button,"click"),this.schema.options&&"undefined"!=typeof this.schema.options.disable_collapse?this.schema.options.disable_collapse&&(this.toggle_button.style.display="none"):this.jsoneditor.options.disable_collapse&&(this.toggle_button.style.display="none"),this.add_row_button=this.getButton(this.getItemTitle(),"add","Add "+this.getItemTitle()),this.add_row_button.addEventListener("click",function(b){b.preventDefault(),b.stopPropagation();var c=a.rows.length;a.row_cache[c]?(a.rows[c]=a.row_cache[c],a.rows[c].setValue(a.rows[c].getDefault()),a.rows[c].container.style.display="",a.rows[c].tab&&(a.rows[c].tab.style.display=""),a.rows[c].register()):a.addRow(),a.active_tab=a.rows[c].tab,a.refreshTabs(),a.refreshValue(),a.onChange(!0)}),a.controls.appendChild(this.add_row_button),this.delete_last_row_button=this.getButton("Last "+this.getItemTitle(),"delete","Delete Last "+this.getItemTitle()),
+this.delete_last_row_button.addEventListener("click",function(b){b.preventDefault(),b.stopPropagation();var c=a.getValue(),d=null;a.rows.length>1&&a.rows[a.rows.length-1].tab===a.active_tab&&(d=a.rows[a.rows.length-2].tab),c.pop(),a.setValue(c),d&&(a.active_tab=d,a.refreshTabs()),a.onChange(!0)}),a.controls.appendChild(this.delete_last_row_button),this.remove_all_rows_button=this.getButton("All","delete","Delete All"),this.remove_all_rows_button.addEventListener("click",function(b){b.preventDefault(),b.stopPropagation(),a.setValue([]),a.onChange(!0)}),a.controls.appendChild(this.remove_all_rows_button),a.tabs&&(this.add_row_button.style.width="100%",this.add_row_button.style.textAlign="left",this.add_row_button.style.marginBottom="3px",this.delete_last_row_button.style.width="100%",this.delete_last_row_button.style.textAlign="left",this.delete_last_row_button.style.marginBottom="3px",this.remove_all_rows_button.style.width="100%",this.remove_all_rows_button.style.textAlign="left",this.remove_all_rows_button.style.marginBottom="3px")},showValidationErrors:function(a){var b=this,c=[],e=[];if(d(a,function(a,d){d.path===b.path?c.push(d):e.push(d)}),this.error_holder)if(c.length){this.error_holder.innerHTML="",this.error_holder.style.display="",d(c,function(a,c){b.error_holder.appendChild(b.theme.getErrorMessage(c.message))})}else this.error_holder.style.display="none";d(this.rows,function(a,b){b.showValidationErrors(e)})}}),f.defaults.editors.table=f.defaults.editors.array.extend({register:function(){if(this._super(),this.rows)for(var a=0;a<this.rows.length;a++)this.rows[a].register()},unregister:function(){if(this._super(),this.rows)for(var a=0;a<this.rows.length;a++)this.rows[a].unregister()},getNumColumns:function(){return Math.max(Math.min(12,this.width),3)},preBuild:function(){var a=this.jsoneditor.expandRefs(this.schema.items||{});this.item_title=a.title||"row",this.item_default=a["default"]||null,this.item_has_child_editors=a.properties||a.items,this.width=12,this._super()},build:function(){var a=this;this.table=this.theme.getTable(),this.container.appendChild(this.table),this.thead=this.theme.getTableHead(),this.table.appendChild(this.thead),this.header_row=this.theme.getTableRow(),this.thead.appendChild(this.header_row),this.row_holder=this.theme.getTableBody(),this.table.appendChild(this.row_holder);var b=this.getElementEditor(0,!0);if(this.item_default=b.getDefault(),this.width=b.getNumColumns()+2,this.options.compact?(this.panel=document.createElement("div"),this.container.appendChild(this.panel)):(this.title=this.theme.getHeader(this.getTitle(),this.isRequired()),this.container.appendChild(this.title),this.title_controls=this.theme.getHeaderButtonHolder(),this.title.appendChild(this.title_controls),this.schema.description&&(this.description=this.theme.getDescription(this.schema.description),this.container.appendChild(this.description)),this.panel=this.theme.getIndentedPanel(),this.container.appendChild(this.panel),this.error_holder=document.createElement("div"),this.panel.appendChild(this.error_holder)),this.panel.appendChild(this.table),this.controls=this.theme.getButtonHolder(),this.panel.appendChild(this.controls),this.item_has_child_editors)for(var c=b.getChildEditors(),d=b.property_order||Object.keys(c),e=0;e<d.length;e++){var f=a.theme.getTableHeaderCell(c[d[e]].getTitle());c[d[e]].options.hidden&&(f.style.display="none"),a.header_row.appendChild(f)}else a.header_row.appendChild(a.theme.getTableHeaderCell(this.item_title));b.destroy(),this.row_holder.innerHTML="",this.controls_header_cell=a.theme.getTableHeaderCell(" "),a.header_row.appendChild(this.controls_header_cell),this.addControls()},onChildEditorChange:function(a){this.refreshValue(),this._super()},getItemDefault:function(){return c({},{"default":this.item_default})["default"]},getItemTitle:function(){return this.item_title},getElementEditor:function(a,b){var d=c({},this.schema.items),e=this.jsoneditor.getEditorClass(d,this.jsoneditor),f=this.row_holder.appendChild(this.theme.getTableRow()),g=f;this.item_has_child_editors||(g=this.theme.getTableCell(),f.appendChild(g));var h=this.jsoneditor.createEditor(e,{jsoneditor:this.jsoneditor,schema:d,container:g,path:this.path+"."+a,parent:this,compact:!0,table_row:!0});return h.preBuild(),b||(h.build(),h.postBuild(),h.controls_cell=f.appendChild(this.theme.getTableCell()),h.row=f,h.table_controls=this.theme.getButtonHolder(),h.controls_cell.appendChild(h.table_controls),h.table_controls.style.margin=0,h.table_controls.style.padding=0),h},destroy:function(){this.innerHTML="",this.title&&this.title.parentNode&&this.title.parentNode.removeChild(this.title),this.description&&this.description.parentNode&&this.description.parentNode.removeChild(this.description),this.row_holder&&this.row_holder.parentNode&&this.row_holder.parentNode.removeChild(this.row_holder),this.table&&this.table.parentNode&&this.table.parentNode.removeChild(this.table),this.panel&&this.panel.parentNode&&this.panel.parentNode.removeChild(this.panel),this.rows=this.title=this.description=this.row_holder=this.table=this.panel=null,this._super()},setValue:function(a,b){if(a=a||[],this.schema.minItems)for(;a.length<this.schema.minItems;)a.push(this.getItemDefault());this.schema.maxItems&&a.length>this.schema.maxItems&&(a=a.slice(0,this.schema.maxItems));var c=JSON.stringify(a);if(c!==this.serialized){var e=!1,f=this;d(a,function(a,b){f.rows[a]?f.rows[a].setValue(b):(f.addRow(b),e=!0)});for(var g=a.length;g<f.rows.length;g++){var h=f.rows[g].container;f.item_has_child_editors||f.rows[g].row.parentNode.removeChild(f.rows[g].row),f.rows[g].destroy(),h.parentNode&&h.parentNode.removeChild(h),f.rows[g]=null,e=!0}f.rows=f.rows.slice(0,a.length),f.refreshValue(),(e||b)&&f.refreshRowButtons(),f.onChange()}},refreshRowButtons:function(){var a=this,b=this.schema.minItems&&this.schema.minItems>=this.rows.length,c=!1;d(this.rows,function(d,e){e.movedown_button&&(d===a.rows.length-1?e.movedown_button.style.display="none":(c=!0,e.movedown_button.style.display="")),e.delete_button&&(b?e.delete_button.style.display="none":(c=!0,e.delete_button.style.display="")),e.moveup_button&&(c=!0)}),d(this.rows,function(a,b){c?b.controls_cell.style.display="":b.controls_cell.style.display="none"}),c?this.controls_header_cell.style.display="":this.controls_header_cell.style.display="none";var e=!1;this.value.length?1===this.value.length||this.hide_delete_buttons?(this.table.style.display="",this.remove_all_rows_button.style.display="none",b||this.hide_delete_buttons?this.delete_last_row_button.style.display="none":(this.delete_last_row_button.style.display="",e=!0)):(this.table.style.display="",b||this.hide_delete_buttons?(this.delete_last_row_button.style.display="none",this.remove_all_rows_button.style.display="none"):(this.delete_last_row_button.style.display="",this.remove_all_rows_button.style.display="",e=!0)):(this.delete_last_row_button.style.display="none",this.remove_all_rows_button.style.display="none",this.table.style.display="none"),this.schema.maxItems&&this.schema.maxItems<=this.rows.length||this.hide_add_button?this.add_row_button.style.display="none":(this.add_row_button.style.display="",e=!0),e?this.controls.style.display="":this.controls.style.display="none"},refreshValue:function(){var a=this;this.value=[],d(this.rows,function(b,c){a.value[b]=c.getValue()}),this.serialized=JSON.stringify(this.value)},addRow:function(a){var b=this,c=this.rows.length;b.rows[c]=this.getElementEditor(c);var e=b.rows[c].table_controls;this.hide_delete_buttons||(b.rows[c].delete_button=this.getButton("","delete","Delete"),b.rows[c].delete_button.className+=" delete",b.rows[c].delete_button.setAttribute("data-i",c),b.rows[c].delete_button.addEventListener("click",function(a){a.preventDefault(),a.stopPropagation();var c=1*this.getAttribute("data-i"),e=b.getValue(),f=[];d(e,function(a,b){a!==c&&f.push(b)}),b.setValue(f),b.onChange(!0)}),e.appendChild(b.rows[c].delete_button)),c&&!this.hide_move_buttons&&(b.rows[c].moveup_button=this.getButton("","moveup","Move up"),b.rows[c].moveup_button.className+=" moveup",b.rows[c].moveup_button.setAttribute("data-i",c),b.rows[c].moveup_button.addEventListener("click",function(a){a.preventDefault(),a.stopPropagation();var c=1*this.getAttribute("data-i");if(!(0>=c)){var d=b.getValue(),e=d[c-1];d[c-1]=d[c],d[c]=e,b.setValue(d),b.onChange(!0)}}),e.appendChild(b.rows[c].moveup_button)),this.hide_move_buttons||(b.rows[c].movedown_button=this.getButton("","movedown","Move down"),b.rows[c].movedown_button.className+=" movedown",b.rows[c].movedown_button.setAttribute("data-i",c),b.rows[c].movedown_button.addEventListener("click",function(a){a.preventDefault(),a.stopPropagation();var c=1*this.getAttribute("data-i"),d=b.getValue();if(!(c>=d.length-1)){var e=d[c+1];d[c+1]=d[c],d[c]=e,b.setValue(d),b.onChange(!0)}}),e.appendChild(b.rows[c].movedown_button)),a&&b.rows[c].setValue(a)},addControls:function(){var a=this;this.collapsed=!1,this.toggle_button=this.getButton("","collapse","Collapse"),this.title_controls&&(this.title_controls.appendChild(this.toggle_button),this.toggle_button.addEventListener("click",function(b){b.preventDefault(),b.stopPropagation(),a.collapsed?(a.collapsed=!1,a.panel.style.display="",a.setButtonText(this,"","collapse","Collapse")):(a.collapsed=!0,a.panel.style.display="none",a.setButtonText(this,"","expand","Expand"))}),this.options.collapsed&&e(this.toggle_button,"click"),this.schema.options&&"undefined"!=typeof this.schema.options.disable_collapse?this.schema.options.disable_collapse&&(this.toggle_button.style.display="none"):this.jsoneditor.options.disable_collapse&&(this.toggle_button.style.display="none")),this.add_row_button=this.getButton(this.getItemTitle(),"add","Add "+this.getItemTitle()),this.add_row_button.addEventListener("click",function(b){b.preventDefault(),b.stopPropagation(),a.addRow(),a.refreshValue(),a.refreshRowButtons(),a.onChange(!0)}),a.controls.appendChild(this.add_row_button),this.delete_last_row_button=this.getButton("Last "+this.getItemTitle(),"delete","Delete Last "+this.getItemTitle()),this.delete_last_row_button.addEventListener("click",function(b){b.preventDefault(),b.stopPropagation();var c=a.getValue();c.pop(),a.setValue(c),a.onChange(!0)}),a.controls.appendChild(this.delete_last_row_button),this.remove_all_rows_button=this.getButton("All","delete","Delete All"),this.remove_all_rows_button.addEventListener("click",function(b){b.preventDefault(),b.stopPropagation(),a.setValue([]),a.onChange(!0)}),a.controls.appendChild(this.remove_all_rows_button)}}),f.defaults.editors.multiple=f.AbstractEditor.extend({register:function(){if(this.editors){for(var a=0;a<this.editors.length;a++)this.editors[a]&&this.editors[a].unregister();this.editors[this.type]&&this.editors[this.type].register()}this._super()},unregister:function(){if(this._super(),this.editors)for(var a=0;a<this.editors.length;a++)this.editors[a]&&this.editors[a].unregister()},getNumColumns:function(){return this.editors[this.type]?Math.max(this.editors[this.type].getNumColumns(),4):4},enable:function(){if(this.editors)for(var a=0;a<this.editors.length;a++)this.editors[a]&&this.editors[a].enable();this.switcher.disabled=!1,this._super()},disable:function(){if(this.editors)for(var a=0;a<this.editors.length;a++)this.editors[a]&&this.editors[a].disable();this.switcher.disabled=!0,this._super()},switchEditor:function(a){var b=this;this.editors[a]||this.buildChildEditor(a),b.type=a,b.register();var c=b.getValue();d(b.editors,function(a,d){d&&(b.type===a?(b.keep_values&&d.setValue(c,!0),d.container.style.display=""):d.container.style.display="none")}),b.refreshValue(),b.refreshHeaderText()},buildChildEditor:function(a){var b=this,d=this.types[a],e=b.theme.getChildEditorHolder();b.editor_holder.appendChild(e);var f;"string"==typeof d?(f=c({},b.schema),f.type=d):(f=c({},b.schema,d),f=b.jsoneditor.expandRefs(f),d.required&&Array.isArray(d.required)&&b.schema.required&&Array.isArray(b.schema.required)&&(f.required=b.schema.required.concat(d.required)));var g=b.jsoneditor.getEditorClass(f);b.editors[a]=b.jsoneditor.createEditor(g,{jsoneditor:b.jsoneditor,schema:f,container:e,path:b.path,parent:b,required:!0}),b.editors[a].preBuild(),b.editors[a].build(),b.editors[a].postBuild(),b.editors[a].header&&(b.editors[a].header.style.display="none"),b.editors[a].option=b.switcher_options[a],e.addEventListener("change_header_text",function(){b.refreshHeaderText()}),a!==b.type&&(e.style.display="none")},preBuild:function(){if(this.types=[],this.type=0,this.editors=[],this.validators=[],this.keep_values=!0,"undefined"!=typeof this.jsoneditor.options.keep_oneof_values&&(this.keep_values=this.jsoneditor.options.keep_oneof_values),"undefined"!=typeof this.options.keep_oneof_values&&(this.keep_values=this.options.keep_oneof_values),this.schema.oneOf)this.oneOf=!0,this.types=this.schema.oneOf,d(this.types,function(a,b){}),delete this.schema.oneOf;else{if(this.schema.type&&"any"!==this.schema.type)Array.isArray(this.schema.type)?this.types=this.schema.type:this.types=[this.schema.type];else if(this.types=["string","number","integer","boolean","object","array","null"],this.schema.disallow){var a=this.schema.disallow;"object"==typeof a&&Array.isArray(a)||(a=[a]);var b=[];d(this.types,function(c,d){-1===a.indexOf(d)&&b.push(d)}),this.types=b}delete this.schema.type}this.display_text=this.getDisplayText(this.types)},build:function(){var a=this,b=this.container;this.header=this.label=this.theme.getFormInputLabel(this.getTitle(),this.isRequired()),this.container.appendChild(this.header),this.switcher=this.theme.getSwitcher(this.display_text),b.appendChild(this.switcher),this.switcher.addEventListener("change",function(b){b.preventDefault(),b.stopPropagation(),a.switchEditor(a.display_text.indexOf(this.value)),a.onChange(!0)}),this.editor_holder=document.createElement("div"),b.appendChild(this.editor_holder),this.switcher_options=this.theme.getSwitcherOptions(this.switcher),d(this.types,function(b,d){a.editors[b]=!1;var e;"string"==typeof d?(e=c({},a.schema),e.type=d):(e=c({},a.schema,d),d.required&&Array.isArray(d.required)&&a.schema.required&&Array.isArray(a.schema.required)&&(e.required=a.schema.required.concat(d.required))),a.validators[b]=new f.Validator(a.jsoneditor,e)}),this.switchEditor(0)},onChildEditorChange:function(a){this.editors[this.type]&&(this.refreshValue(),this.refreshHeaderText()),this._super()},refreshHeaderText:function(){var a=this.getDisplayText(this.types);d(this.switcher_options,function(b,c){c.textContent=a[b]})},refreshValue:function(){this.value=this.editors[this.type].getValue()},setValue:function(a,b){var c=this;d(this.validators,function(b,d){return d.validate(a).length?void 0:(c.type=b,c.switcher.value=c.display_text[b],!1)}),this.switchEditor(this.type),this.editors[this.type].setValue(a,b),this.refreshValue(),c.onChange()},destroy:function(){d(this.editors,function(a,b){b&&b.destroy()}),this.editor_holder&&this.editor_holder.parentNode&&this.editor_holder.parentNode.removeChild(this.editor_holder),this.switcher&&this.switcher.parentNode&&this.switcher.parentNode.removeChild(this.switcher),this._super()},showValidationErrors:function(a){var b=this;this.oneOf?d(this.editors,function(e,f){if(f){var g=b.path+".oneOf["+e+"]",h=[];d(a,function(a,d){if(d.path.substr(0,g.length)===g){var e=c({},d);e.path=b.path+e.path.substr(g.length),h.push(e)}}),f.showValidationErrors(h)}}):d(this.editors,function(b,c){c&&c.showValidationErrors(a)})}}),f.defaults.editors["enum"]=f.AbstractEditor.extend({getNumColumns:function(){return 4},build:function(){this.container;this.title=this.header=this.label=this.theme.getFormInputLabel(this.getTitle(),this.isRequired()),this.container.appendChild(this.title),this.options.enum_titles=this.options.enum_titles||[],this["enum"]=this.schema["enum"],this.selected=0,this.select_options=[],this.html_values=[];for(var a=this,b=0;b<this["enum"].length;b++)this.select_options[b]=this.options.enum_titles[b]||"Value "+(b+1),this.html_values[b]=this.getHTML(this["enum"][b]);this.switcher=this.theme.getSwitcher(this.select_options),this.container.appendChild(this.switcher),this.display_area=this.theme.getIndentedPanel(),this.container.appendChild(this.display_area),this.options.hide_display&&(this.display_area.style.display="none"),this.switcher.addEventListener("change",function(){a.selected=a.select_options.indexOf(this.value),a.value=a["enum"][a.selected],a.refreshValue(),a.onChange(!0)}),this.value=this["enum"][0],this.refreshValue(),1===this["enum"].length&&(this.switcher.style.display="none")},refreshValue:function(){var a=this;a.selected=-1;var b=JSON.stringify(this.value);return d(this["enum"],function(c,d){return b===JSON.stringify(d)?(a.selected=c,!1):void 0}),a.selected<0?void a.setValue(a["enum"][0]):(this.switcher.value=this.select_options[this.selected],void(this.display_area.innerHTML=this.html_values[this.selected]))},enable:function(){this.always_disabled||(this.switcher.disabled=!1),this._super()},disable:function(){this.switcher.disabled=!0,this._super()},getHTML:function(a){var b=this;if(null===a)return"<em>null</em>";if("object"==typeof a){var c="";return d(a,function(d,e){var f=b.getHTML(e);Array.isArray(a)||(f="<div><em>"+d+"</em>: "+f+"</div>"),c+="<li>"+f+"</li>"}),c=Array.isArray(a)?"<ol>"+c+"</ol>":"<ul style='margin-top:0;margin-bottom:0;padding-top:0;padding-bottom:0;'>"+c+"</ul>"}return"boolean"==typeof a?a?"true":"false":"string"==typeof a?a.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;"):a},setValue:function(a){this.value!==a&&(this.value=a,this.refreshValue(),this.onChange())},destroy:function(){this.display_area&&this.display_area.parentNode&&this.display_area.parentNode.removeChild(this.display_area),this.title&&this.title.parentNode&&this.title.parentNode.removeChild(this.title),this.switcher&&this.switcher.parentNode&&this.switcher.parentNode.removeChild(this.switcher),this._super()}}),f.defaults.editors.select=f.AbstractEditor.extend({setValue:function(a,b){a=this.typecast(a||"");var c=a;this.enum_values.indexOf(c)<0&&(c=this.enum_values[0]),this.value!==c&&(this.input.value=this.enum_options[this.enum_values.indexOf(c)],this.select2&&this.select2.select2("val",this.input.value),this.value=c,this.onChange())},register:function(){this._super(),this.input&&this.input.setAttribute("name",this.formname)},unregister:function(){this._super(),this.input&&this.input.removeAttribute("name")},getNumColumns:function(){if(!this.enum_options)return 3;for(var a=this.getTitle().length,b=0;b<this.enum_options.length;b++)a=Math.max(a,this.enum_options[b].length+4);return Math.min(12,Math.max(a/7,2))},typecast:function(a){return"boolean"===this.schema.type?!!a:"number"===this.schema.type?1*a:"integer"===this.schema.type?Math.floor(1*a):""+a},getValue:function(){return this.value},preBuild:function(){var a=this;if(this.input_type="select",this.enum_options=[],this.enum_values=[],this.enum_display=[],this.schema["enum"]){var b=this.schema.options&&this.schema.options.enum_titles||[];d(this.schema["enum"],function(c,d){a.enum_options[c]=""+d,a.enum_display[c]=""+(b[c]||d),a.enum_values[c]=a.typecast(d)}),this.isRequired()||(a.enum_display.unshift(" "),a.enum_options.unshift("undefined"),a.enum_values.unshift(void 0))}else if("boolean"===this.schema.type)a.enum_display=this.schema.options&&this.schema.options.enum_titles||["true","false"],a.enum_options=["1",""],a.enum_values=[!0,!1],this.isRequired()||(a.enum_display.unshift(" "),a.enum_options.unshift("undefined"),a.enum_values.unshift(void 0));else{if(!this.schema.enumSource)throw"'select' editor requires the enum property to be set.";if(this.enumSource=[],this.enum_display=[],this.enum_options=[],this.enum_values=[],Array.isArray(this.schema.enumSource))for(h=0;h<this.schema.enumSource.length;h++)"string"==typeof this.schema.enumSource[h]?this.enumSource[h]={source:this.schema.enumSource[h]}:Array.isArray(this.schema.enumSource[h])?this.enumSource[h]=this.schema.enumSource[h]:this.enumSource[h]=c({},this.schema.enumSource[h]);else this.schema.enumValue?this.enumSource=[{source:this.schema.enumSource,value:this.schema.enumValue}]:this.enumSource=[{source:this.schema.enumSource}];for(h=0;h<this.enumSource.length;h++)this.enumSource[h].value&&(this.enumSource[h].value=this.jsoneditor.compileTemplate(this.enumSource[h].value,this.template_engine)),this.enumSource[h].title&&(this.enumSource[h].title=this.jsoneditor.compileTemplate(this.enumSource[h].title,this.template_engine)),this.enumSource[h].filter&&(this.enumSource[h].filter=this.jsoneditor.compileTemplate(this.enumSource[h].filter,this.template_engine))}},build:function(){var a=this;this.options.compact||(this.header=this.label=this.theme.getFormInputLabel(this.getTitle(),this.isRequired())),this.schema.description&&(this.description=this.theme.getFormInputDescription(this.schema.description)),this.options.compact&&(this.container.className+=" compact"),this.input=this.theme.getSelectInput(this.enum_options),this.theme.setSelectOptions(this.input,this.enum_options,this.enum_display),(this.schema.readOnly||this.schema.readonly)&&(this.always_disabled=!0,this.input.disabled=!0),this.input.addEventListener("change",function(b){b.preventDefault(),b.stopPropagation(),a.onInputChange()}),this.control=this.theme.getFormControl(this.label,this.input,this.description),this.container.appendChild(this.control),this.value=this.enum_values[0]},onInputChange:function(){var a=this.input.value,b=a;-1===this.enum_options.indexOf(a)&&(b=this.enum_options[0]),this.value=this.enum_values[this.enum_options.indexOf(a)],this.onChange(!0)},setupSelect2:function(){if(window.jQuery&&window.jQuery.fn&&window.jQuery.fn.select2&&(this.enum_options.length>2||this.enum_options.length&&this.enumSource)){var a=c({},f.plugins.select2);this.schema.options&&this.schema.options.select2_options&&(a=c(a,this.schema.options.select2_options)),this.select2=window.jQuery(this.input).select2(a);var b=this;this.select2.on("select2-blur",function(){b.input.value=b.select2.select2("val"),b.onInputChange()})}else this.select2=null},postBuild:function(){this._super(),this.theme.afterInputReady(this.input),this.setupSelect2()},onWatchedFieldChange:function(){var a,b;if(this.enumSource){a=this.getWatchedFieldValues();for(var c=[],d=[],e=0;e<this.enumSource.length;e++)if(Array.isArray(this.enumSource[e]))c=c.concat(this.enumSource[e]),d=d.concat(this.enumSource[e]);else{var f=[];if(f=Array.isArray(this.enumSource[e].source)?this.enumSource[e].source:a[this.enumSource[e].source]){if(this.enumSource[e].slice&&(f=Array.prototype.slice.apply(f,this.enumSource[e].slice)),this.enumSource[e].filter){var g=[];for(b=0;b<f.length;b++)this.enumSource[e].filter({i:b,item:f[b],watched:a})&&g.push(f[b]);f=g}var h=[],i=[];for(b=0;b<f.length;b++){var j=f[b];this.enumSource[e].value?i[b]=this.enumSource[e].value({i:b,item:j}):i[b]=f[b],this.enumSource[e].title?h[b]=this.enumSource[e].title({i:b,item:j}):h[b]=i[b]}c=c.concat(i),d=d.concat(h)}}var k=this.value;this.theme.setSelectOptions(this.input,c,d),this.enum_options=c,this.enum_display=d,this.enum_values=c,this.select2&&this.select2.select2("destroy"),-1!==c.indexOf(k)?(this.input.value=k,this.value=k):(this.input.value=c[0],this.value=c[0]||"",this.parent?this.parent.onChildEditorChange(this):this.jsoneditor.onChange(),this.jsoneditor.notifyWatchers(this.path)),this.setupSelect2()}this._super()},enable:function(){this.always_disabled||(this.input.disabled=!1,this.select2&&this.select2.select2("enable",!0)),this._super()},disable:function(){this.input.disabled=!0,this.select2&&this.select2.select2("enable",!1),this._super()},destroy:function(){this.label&&this.label.parentNode&&this.label.parentNode.removeChild(this.label),this.description&&this.description.parentNode&&this.description.parentNode.removeChild(this.description),this.input&&this.input.parentNode&&this.input.parentNode.removeChild(this.input),this.select2&&(this.select2.select2("destroy"),this.select2=null),this._super()}}),f.defaults.editors.multiselect=f.AbstractEditor.extend({preBuild:function(){this._super(),this.select_options={},this.select_values={};var a=this.jsoneditor.expandRefs(this.schema.items||{}),b=a["enum"]||[];for(this.option_keys=[],h=0;h<b.length;h++)this.sanitize(b[h])===b[h]&&(this.option_keys.push(b[h]+""),this.select_values[b[h]+""]=b[h])},build:function(){var a,b=this;if(this.options.compact||(this.header=this.label=this.theme.getFormInputLabel(this.getTitle(),this.isRequired())),this.schema.description&&(this.description=this.theme.getFormInputDescription(this.schema.description)),!this.schema.format&&this.option_keys.length<8||"checkbox"===this.schema.format){for(this.input_type="checkboxes",this.inputs={},this.controls={},a=0;a<this.option_keys.length;a++){this.inputs[this.option_keys[a]]=this.theme.getCheckbox(),this.select_options[this.option_keys[a]]=this.inputs[this.option_keys[a]];var c=this.theme.getCheckboxLabel(this.option_keys[a]);this.controls[this.option_keys[a]]=this.theme.getFormControl(c,this.inputs[this.option_keys[a]])}this.control=this.theme.getMultiCheckboxHolder(this.controls,this.label,this.description)}else{for(this.input_type="select",this.input=this.theme.getSelectInput(this.option_keys),this.input.multiple=!0,this.input.size=Math.min(10,this.option_keys.length),a=0;a<this.option_keys.length;a++)this.select_options[this.option_keys[a]]=this.input.children[a];(this.schema.readOnly||this.schema.readonly)&&(this.always_disabled=!0,this.input.disabled=!0),this.control=this.theme.getFormControl(this.label,this.input,this.description)}this.container.appendChild(this.control),this.control.addEventListener("change",function(c){c.preventDefault(),c.stopPropagation();var d=[];for(a=0;a<b.option_keys.length;a++)(b.select_options[b.option_keys[a]].selected||b.select_options[b.option_keys[a]].checked)&&d.push(b.select_values[b.option_keys[a]]);b.updateValue(d),b.onChange(!0)})},setValue:function(a,b){var c;for(a=a||[],"object"!=typeof a?a=[a]:Array.isArray(a)||(a=[]),c=0;c<a.length;c++)"string"!=typeof a[c]&&(a[c]+="");for(c in this.select_options)this.select_options.hasOwnProperty(c)&&(this.select_options[c]["select"===this.input_type?"selected":"checked"]=-1!==a.indexOf(c));this.updateValue(a),this.onChange()},setupSelect2:function(){if(window.jQuery&&window.jQuery.fn&&window.jQuery.fn.select2){var a=window.jQuery.extend({},f.plugins.select2);this.schema.options&&this.schema.options.select2_options&&(a=c(a,this.schema.options.select2_options)),this.select2=window.jQuery(this.input).select2(a);var b=this;this.select2.on("select2-blur",function(){var a=b.select2.select2("val");b.value=a,b.onChange(!0)})}else this.select2=null},onInputChange:function(){this.value=this.input.value,this.onChange(!0)},postBuild:function(){this._super(),this.setupSelect2()},register:function(){this._super(),this.input&&this.input.setAttribute("name",this.formname)},unregister:function(){this._super(),this.input&&this.input.removeAttribute("name")},getNumColumns:function(){var a=this.getTitle().length;for(var b in this.select_values)this.select_values.hasOwnProperty(b)&&(a=Math.max(a,(this.select_values[b]+"").length+4));return Math.min(12,Math.max(a/7,2))},updateValue:function(a){for(var b=!1,c=[],d=0;d<a.length;d++)if(this.select_options[a[d]+""]){var e=this.sanitize(this.select_values[a[d]]);c.push(e),e!==a[d]&&(b=!0)}else b=!0;return this.value=c,this.select2&&this.select2.select2("val",this.value),b},sanitize:function(a){return"number"===this.schema.items.type?1*a:"integer"===this.schema.items.type?Math.floor(1*a):""+a},enable:function(){if(!this.always_disabled){if(this.input)this.input.disabled=!1;else if(this.inputs)for(var a in this.inputs)this.inputs.hasOwnProperty(a)&&(this.inputs[a].disabled=!1);this.select2&&this.select2.select2("enable",!0)}this._super()},disable:function(){if(this.input)this.input.disabled=!0;else if(this.inputs)for(var a in this.inputs)this.inputs.hasOwnProperty(a)&&(this.inputs[a].disabled=!0);this.select2&&this.select2.select2("enable",!1),this._super()},destroy:function(){this.select2&&(this.select2.select2("destroy"),this.select2=null),this._super()}}),f.defaults.editors.base64=f.AbstractEditor.extend({getNumColumns:function(){return 4},build:function(){var a=this;if(this.title=this.header=this.label=this.theme.getFormInputLabel(this.getTitle(),this.isRequired()),this.input=this.theme.getFormInputField("hidden"),this.container.appendChild(this.input),!this.schema.readOnly&&!this.schema.readonly){if(!window.FileReader)throw"FileReader required for base64 editor";this.uploader=this.theme.getFormInputField("file"),this.uploader.addEventListener("change",function(b){if(b.preventDefault(),b.stopPropagation(),this.files&&this.files.length){var c=new FileReader;c.onload=function(b){a.value=b.target.result,a.refreshPreview(),a.onChange(!0),c=null},c.readAsDataURL(this.files[0])}})}this.preview=this.theme.getFormInputDescription(this.schema.description),this.container.appendChild(this.preview),this.control=this.theme.getFormControl(this.label,this.uploader||this.input,this.preview),this.container.appendChild(this.control)},refreshPreview:function(){if(this.last_preview!==this.value&&(this.last_preview=this.value,this.preview.innerHTML="",this.value)){var a=this.value.match(/^data:([^;,]+)[;,]/);if(a&&(a=a[1]),a){if(this.preview.innerHTML="<strong>Type:</strong> "+a+", <strong>Size:</strong> "+Math.floor((this.value.length-this.value.split(",")[0].length-1)/1.33333)+" bytes","image"===a.substr(0,5)){this.preview.innerHTML+="<br>";var b=document.createElement("img");b.style.maxWidth="100%",b.style.maxHeight="100px",b.src=this.value,this.preview.appendChild(b)}}else this.preview.innerHTML="<em>Invalid data URI</em>"}},enable:function(){this.uploader&&(this.uploader.disabled=!1),this._super()},disable:function(){this.uploader&&(this.uploader.disabled=!0),this._super()},setValue:function(a){this.value!==a&&(this.value=a,this.input.value=this.value,this.refreshPreview(),this.onChange())},destroy:function(){this.preview&&this.preview.parentNode&&this.preview.parentNode.removeChild(this.preview),this.title&&this.title.parentNode&&this.title.parentNode.removeChild(this.title),this.input&&this.input.parentNode&&this.input.parentNode.removeChild(this.input),this.uploader&&this.uploader.parentNode&&this.uploader.parentNode.removeChild(this.uploader),this._super()}}),f.defaults.editors.upload=f.AbstractEditor.extend({getNumColumns:function(){return 4},build:function(){var a=this;if(this.title=this.header=this.label=this.theme.getFormInputLabel(this.getTitle(),this.isRequired()),this.input=this.theme.getFormInputField("hidden"),this.container.appendChild(this.input),!this.schema.readOnly&&!this.schema.readonly){if(!this.jsoneditor.options.upload)throw"Upload handler required for upload editor";this.uploader=this.theme.getFormInputField("file"),this.uploader.addEventListener("change",function(b){if(b.preventDefault(),b.stopPropagation(),this.files&&this.files.length){var c=new FileReader;c.onload=function(b){a.preview_value=b.target.result,a.refreshPreview(),a.onChange(!0),c=null},c.readAsDataURL(this.files[0])}})}var b=this.schema.description;b||(b=""),this.preview=this.theme.getFormInputDescription(b),this.container.appendChild(this.preview),this.control=this.theme.getFormControl(this.label,this.uploader||this.input,this.preview),this.container.appendChild(this.control)},refreshPreview:function(){if(this.last_preview!==this.preview_value&&(this.last_preview=this.preview_value,this.preview.innerHTML="",this.preview_value)){var a=this,b=this.preview_value.match(/^data:([^;,]+)[;,]/);b&&(b=b[1]),b||(b="unknown");var c=this.uploader.files[0];if(this.preview.innerHTML="<strong>Type:</strong> "+b+", <strong>Size:</strong> "+c.size+" bytes","image"===b.substr(0,5)){this.preview.innerHTML+="<br>";var d=document.createElement("img");d.style.maxWidth="100%",d.style.maxHeight="100px",d.src=this.preview_value,
+this.preview.appendChild(d)}this.preview.innerHTML+="<br>";var e=this.getButton("Upload","upload","Upload");this.preview.appendChild(e),e.addEventListener("click",function(b){b.preventDefault(),e.setAttribute("disabled","disabled"),a.theme.removeInputError(a.uploader),a.theme.getProgressBar&&(a.progressBar=a.theme.getProgressBar(),a.preview.appendChild(a.progressBar)),a.jsoneditor.options.upload(a.path,c,{success:function(b){a.setValue(b),a.parent?a.parent.onChildEditorChange(a):a.jsoneditor.onChange(),a.progressBar&&a.preview.removeChild(a.progressBar),e.removeAttribute("disabled")},failure:function(b){a.theme.addInputError(a.uploader,b),a.progressBar&&a.preview.removeChild(a.progressBar),e.removeAttribute("disabled")},updateProgress:function(b){a.progressBar&&(b?a.theme.updateProgressBar(a.progressBar,b):a.theme.updateProgressBarUnknown(a.progressBar))}})})}},enable:function(){this.uploader&&(this.uploader.disabled=!1),this._super()},disable:function(){this.uploader&&(this.uploader.disabled=!0),this._super()},setValue:function(a){this.value!==a&&(this.value=a,this.input.value=this.value,this.onChange())},destroy:function(){this.preview&&this.preview.parentNode&&this.preview.parentNode.removeChild(this.preview),this.title&&this.title.parentNode&&this.title.parentNode.removeChild(this.title),this.input&&this.input.parentNode&&this.input.parentNode.removeChild(this.input),this.uploader&&this.uploader.parentNode&&this.uploader.parentNode.removeChild(this.uploader),this._super()}}),f.defaults.editors.checkbox=f.AbstractEditor.extend({setValue:function(a,b){this.value=!!a,this.input.checked=this.value,this.onChange()},register:function(){this._super(),this.input&&this.input.setAttribute("name",this.formname)},unregister:function(){this._super(),this.input&&this.input.removeAttribute("name")},getNumColumns:function(){return Math.min(12,Math.max(this.getTitle().length/7,2))},build:function(){var a=this;this.options.compact||(this.label=this.header=this.theme.getCheckboxLabel(this.getTitle())),this.schema.description&&(this.description=this.theme.getFormInputDescription(this.schema.description)),this.options.compact&&(this.container.className+=" compact"),this.input=this.theme.getCheckbox(),this.control=this.theme.getFormControl(this.label,this.input,this.description),(this.schema.readOnly||this.schema.readonly)&&(this.always_disabled=!0,this.input.disabled=!0),this.input.addEventListener("change",function(b){b.preventDefault(),b.stopPropagation(),a.value=this.checked,a.onChange(!0)}),this.container.appendChild(this.control)},enable:function(){this.always_disabled||(this.input.disabled=!1),this._super()},disable:function(){this.input.disabled=!0,this._super()},destroy:function(){this.label&&this.label.parentNode&&this.label.parentNode.removeChild(this.label),this.description&&this.description.parentNode&&this.description.parentNode.removeChild(this.description),this.input&&this.input.parentNode&&this.input.parentNode.removeChild(this.input),this._super()}});var g=function(){var a=document.documentElement;return a.matches?"matches":a.webkitMatchesSelector?"webkitMatchesSelector":a.mozMatchesSelector?"mozMatchesSelector":a.msMatchesSelector?"msMatchesSelector":a.oMatchesSelector?"oMatchesSelector":void 0}();f.AbstractTheme=a.extend({getContainer:function(){return document.createElement("div")},getFloatRightLinkHolder:function(){var a=document.createElement("div");return a.style=a.style||{},a.style.cssFloat="right",a.style.marginLeft="10px",a},getModal:function(){var a=document.createElement("div");return a.style.backgroundColor="white",a.style.border="1px solid black",a.style.boxShadow="3px 3px black",a.style.position="absolute",a.style.zIndex="10",a.style.display="none",a},getGridContainer:function(){var a=document.createElement("div");return a},getGridRow:function(){var a=document.createElement("div");return a.className="row",a},getGridColumn:function(){var a=document.createElement("div");return a},setGridColumnSize:function(a,b){},getLink:function(a){var b=document.createElement("a");return b.setAttribute("href","#"),b.appendChild(document.createTextNode(a)),b},disableHeader:function(a){a.style.color="#ccc"},disableLabel:function(a){a.style.color="#ccc"},enableHeader:function(a){a.style.color=""},enableLabel:function(a){a.style.color=""},getFormInputLabel:function(a){var b=document.createElement("label");return b.appendChild(document.createTextNode(a)),b},getCheckboxLabel:function(a){var b=this.getFormInputLabel(a);return b.style.fontWeight="normal",b},getHeader:function(a,b){var c=document.createElement("h3");return"string"==typeof a?c.textContent=a:c.appendChild(a),b&&(c.className+=" required"),c},getCheckbox:function(){var a=this.getFormInputField("checkbox");return a.style.display="inline-block",a.style.width="auto",a},getMultiCheckboxHolder:function(a,b,c){var d=document.createElement("div");b&&(b.style.display="block",d.appendChild(b));for(var e in a)a.hasOwnProperty(e)&&(a[e].style.display="inline-block",a[e].style.marginRight="20px",d.appendChild(a[e]));return c&&d.appendChild(c),d},getSelectInput:function(a){var b=document.createElement("select");return a&&this.setSelectOptions(b,a),b},getSwitcher:function(a){var b=this.getSelectInput(a);return b.style.backgroundColor="transparent",b.style.display="inline-block",b.style.fontStyle="italic",b.style.fontWeight="normal",b.style.height="auto",b.style.marginBottom=0,b.style.marginLeft="5px",b.style.padding="0 0 0 3px",b.style.width="auto",b},getSwitcherOptions:function(a){return a.getElementsByTagName("option")},setSwitcherOptions:function(a,b,c){this.setSelectOptions(a,b,c)},setSelectOptions:function(a,b,c){c=c||[],a.innerHTML="";for(var d=0;d<b.length;d++){var e=document.createElement("option");e.setAttribute("value",b[d]),e.textContent=c[d]||b[d],a.appendChild(e)}},getTextareaInput:function(){var a=document.createElement("textarea");return a.style=a.style||{},a.style.width="100%",a.style.height="300px",a.style.boxSizing="border-box",a},getRangeInput:function(a,b,c){var d=this.getFormInputField("range");return d.setAttribute("min",a),d.setAttribute("max",b),d.setAttribute("step",c),d},getFormInputField:function(a){var b=document.createElement("input");return b.setAttribute("type",a),b},afterInputReady:function(a){},getFormControl:function(a,b,c){var d=document.createElement("div");return d.className="form-control",a&&d.appendChild(a),"checkbox"===b.type?a.insertBefore(b,a.firstChild):d.appendChild(b),c&&d.appendChild(c),d},getIndentedPanel:function(){var a=document.createElement("div");return a.style=a.style||{},a.style.paddingLeft="10px",a.style.marginLeft="10px",a.style.borderLeft="1px solid #ccc",a},getChildEditorHolder:function(){return document.createElement("div")},getDescription:function(a){var b=document.createElement("p");return b.innerHTML=a,b},getCheckboxDescription:function(a){return this.getDescription(a)},getFormInputDescription:function(a){return this.getDescription(a)},getHeaderButtonHolder:function(){return this.getButtonHolder()},getButtonHolder:function(){return document.createElement("div")},getButton:function(a,b,c){var d=document.createElement("button");return d.type="button",this.setButtonText(d,a,b,c),d},setButtonText:function(a,b,c,d){a.innerHTML="",c&&(a.appendChild(c),a.innerHTML+=" "),a.appendChild(document.createTextNode(b)),d&&a.setAttribute("title",d)},getTable:function(){return document.createElement("table")},getTableRow:function(){return document.createElement("tr")},getTableHead:function(){return document.createElement("thead")},getTableBody:function(){return document.createElement("tbody")},getTableHeaderCell:function(a){var b=document.createElement("th");return b.textContent=a,b},getTableCell:function(){var a=document.createElement("td");return a},getErrorMessage:function(a){var b=document.createElement("p");return b.style=b.style||{},b.style.color="red",b.appendChild(document.createTextNode(a)),b},addInputError:function(a,b){},removeInputError:function(a){},addTableRowError:function(a){},removeTableRowError:function(a){},getTabHolder:function(){var a=document.createElement("div");return a.innerHTML="<div style='float: left; width: 130px;' class='tabs'></div><div class='content' style='margin-left: 130px;'></div><div style='clear:both;'></div>",a},applyStyles:function(a,b){a.style=a.style||{};for(var c in b)b.hasOwnProperty(c)&&(a.style[c]=b[c])},closest:function(a,b){for(;a&&a!==document;){if(!g)return!1;if(a[g](b))return a;a=a.parentNode}return!1},getTab:function(a){var b=document.createElement("div");return b.appendChild(a),b.style=b.style||{},this.applyStyles(b,{border:"1px solid #ccc",borderWidth:"1px 0 1px 1px",textAlign:"center",lineHeight:"30px",borderRadius:"5px",borderBottomRightRadius:0,borderTopRightRadius:0,fontWeight:"bold",cursor:"pointer"}),b},getTabContentHolder:function(a){return a.children[1]},getTabContent:function(){return this.getIndentedPanel()},markTabActive:function(a){this.applyStyles(a,{opacity:1,background:"white"})},markTabInactive:function(a){this.applyStyles(a,{opacity:.5,background:""})},addTab:function(a,b){a.children[0].appendChild(b)},getBlockLink:function(){var a=document.createElement("a");return a.style.display="block",a},getBlockLinkHolder:function(){var a=document.createElement("div");return a},getLinksHolder:function(){var a=document.createElement("div");return a},createMediaLink:function(a,b,c){a.appendChild(b),c.style.width="100%",a.appendChild(c)},createImageLink:function(a,b,c){a.appendChild(b),b.appendChild(c)}}),f.defaults.themes.bootstrap2=f.AbstractTheme.extend({getRangeInput:function(a,b,c){return this._super(a,b,c)},getGridContainer:function(){var a=document.createElement("div");return a.className="container-fluid",a},getGridRow:function(){var a=document.createElement("div");return a.className="row-fluid",a},getFormInputLabel:function(a,b){var c=this._super(a);return c.style.display="inline-block",c.style.fontWeight="bold",b&&(c.className+=" required"),c},setGridColumnSize:function(a,b){a.className="span"+b},getSelectInput:function(a){var b=this._super(a);return b.style.width="auto",b.style.maxWidth="98%",b},getFormInputField:function(a){var b=this._super(a);return b.style.width="98%",b},afterInputReady:function(a){a.controlgroup||(a.controlgroup=this.closest(a,".control-group"),a.controls=this.closest(a,".controls"),this.closest(a,".compact")&&(a.controlgroup.className=a.controlgroup.className.replace(/control-group/g,"").replace(/[ ]{2,}/g," "),a.controls.className=a.controlgroup.className.replace(/controls/g,"").replace(/[ ]{2,}/g," "),a.style.marginBottom=0))},getIndentedPanel:function(){var a=document.createElement("div");return a.className="well well-small",a},getFormInputDescription:function(a){var b=document.createElement("p");return b.className="help-inline",b.textContent=a,b},getFormControl:function(a,b,c){var d=document.createElement("div");d.className="control-group";var e=document.createElement("div");return e.className="controls",a&&"checkbox"===b.getAttribute("type")?(d.appendChild(e),a.className+=" checkbox",a.appendChild(b),e.appendChild(a),e.style.height="30px"):(a&&(a.className+=" control-label",d.appendChild(a)),e.appendChild(b),d.appendChild(e)),c&&e.appendChild(c),d},getHeaderButtonHolder:function(){var a=this.getButtonHolder();return a.style.marginLeft="10px",a},getButtonHolder:function(){var a=document.createElement("div");return a.className="btn-group",a},getButton:function(a,b,c){var d=this._super(a,b,c);return d.className+=" btn btn-default",d},getTable:function(){var a=document.createElement("table");return a.className="table table-bordered",a.style.width="auto",a.style.maxWidth="none",a},addInputError:function(a,b){a.controlgroup&&a.controls&&(a.controlgroup.className+=" error",a.errmsg?a.errmsg.style.display="":(a.errmsg=document.createElement("p"),a.errmsg.className="help-block errormsg",a.controls.appendChild(a.errmsg)),a.errmsg.textContent=b)},removeInputError:function(a){a.errmsg&&(a.errmsg.style.display="none",a.controlgroup.className=a.controlgroup.className.replace(/\s?error/g,""))},getTabHolder:function(){var a=document.createElement("div");return a.className="tabbable tabs-left",a.innerHTML="<ul class='nav nav-tabs span2' style='margin-right: 0;'></ul><div class='tab-content span10' style='overflow:visible;'></div>",a},getTab:function(a){var b=document.createElement("li"),c=document.createElement("a");return c.setAttribute("href","#"),c.appendChild(a),b.appendChild(c),b},getTabContentHolder:function(a){return a.children[1]},getTabContent:function(){var a=document.createElement("div");return a.className="tab-pane active",a},markTabActive:function(a){a.className+=" active"},markTabInactive:function(a){a.className=a.className.replace(/\s?active/g,"")},addTab:function(a,b){a.children[0].appendChild(b)},getProgressBar:function(){var a=document.createElement("div");a.className="progress";var b=document.createElement("div");return b.className="bar",b.style.width="0%",a.appendChild(b),a},updateProgressBar:function(a,b){a&&(a.firstChild.style.width=b+"%")},updateProgressBarUnknown:function(a){a&&(a.className="progress progress-striped active",a.firstChild.style.width="100%")}}),f.defaults.themes.bootstrap3=f.AbstractTheme.extend({getSelectInput:function(a){var b=this._super(a);return b.className+="form-control",b},setGridColumnSize:function(a,b){a.className="col-md-"+b},afterInputReady:function(a){a.controlgroup||(a.controlgroup=this.closest(a,".form-group"),this.closest(a,".compact")&&(a.controlgroup.style.marginBottom=0))},getTextareaInput:function(){var a=document.createElement("textarea");return a.className="form-control",a},getRangeInput:function(a,b,c){return this._super(a,b,c)},getFormInputField:function(a){var b=this._super(a);return"checkbox"!==a&&(b.className+="form-control"),b},getFormControl:function(a,b,c){var d=document.createElement("div");return a&&"checkbox"===b.type?(d.className+=" checkbox",a.appendChild(b),a.style.fontSize="14px",d.style.marginTop="0",d.appendChild(a),b.style.position="relative",b.style.cssFloat="left"):(d.className+=" form-group",a&&(a.className+=" control-label",d.appendChild(a)),d.appendChild(b)),c&&d.appendChild(c),d},getIndentedPanel:function(){var a=document.createElement("div");return a.className="well well-sm",a},getFormInputDescription:function(a){var b=document.createElement("p");return b.className="help-block",b.innerHTML=a,b},getHeaderButtonHolder:function(){var a=this.getButtonHolder();return a.style.marginLeft="10px",a},getButtonHolder:function(){var a=document.createElement("div");return a.className="btn-group",a},getButton:function(a,b,c){var d=this._super(a,b,c);return d.className+="btn btn-default",d},getTable:function(){var a=document.createElement("table");return a.className="table table-bordered",a.style.width="auto",a.style.maxWidth="none",a},addInputError:function(a,b){a.controlgroup&&(a.controlgroup.className+=" has-error",a.errmsg?a.errmsg.style.display="":(a.errmsg=document.createElement("p"),a.errmsg.className="help-block errormsg",a.controlgroup.appendChild(a.errmsg)),a.errmsg.textContent=b)},removeInputError:function(a){a.errmsg&&(a.errmsg.style.display="none",a.controlgroup.className=a.controlgroup.className.replace(/\s?has-error/g,""))},getTabHolder:function(){var a=document.createElement("div");return a.innerHTML="<div class='tabs list-group col-md-2'></div><div class='col-md-10'></div>",a.className="rows",a},getTab:function(a){var b=document.createElement("a");return b.className="list-group-item",b.setAttribute("href","#"),b.appendChild(a),b},markTabActive:function(a){a.className+=" active"},markTabInactive:function(a){a.className=a.className.replace(/\s?active/g,"")},getProgressBar:function(){var a=0,b=100,c=0,d=document.createElement("div");d.className="progress";var e=document.createElement("div");return e.className="progress-bar",e.setAttribute("role","progressbar"),e.setAttribute("aria-valuenow",c),e.setAttribute("aria-valuemin",a),e.setAttribute("aria-valuenax",b),e.innerHTML=c+"%",d.appendChild(e),d},updateProgressBar:function(a,b){if(a){var c=a.firstChild,d=b+"%";c.setAttribute("aria-valuenow",b),c.style.width=d,c.innerHTML=d}},updateProgressBarUnknown:function(a){if(a){var b=a.firstChild;a.className="progress progress-striped active",b.removeAttribute("aria-valuenow"),b.style.width="100%",b.innerHTML=""}}}),f.defaults.themes.foundation=f.AbstractTheme.extend({getChildEditorHolder:function(){var a=document.createElement("div");return a.style.marginBottom="15px",a},getSelectInput:function(a){var b=this._super(a);return b.style.minWidth="none",b.style.padding="5px",b.style.marginTop="3px",b},getSwitcher:function(a){var b=this._super(a);return b.style.paddingRight="8px",b},afterInputReady:function(a){this.closest(a,".compact")&&(a.style.marginBottom=0),a.group=this.closest(a,".form-control")},getFormInputLabel:function(a,b){var c=this._super(a);return c.style.display="inline-block",b&&(c.className+=" required"),c},getFormInputField:function(a){var b=this._super(a);return b.style.width="100%",b.style.marginBottom="checkbox"===a?"0":"12px",b},getFormInputDescription:function(a){var b=document.createElement("p");return b.textContent=a,b.style.marginTop="-10px",b.style.fontStyle="italic",b},getIndentedPanel:function(){var a=document.createElement("div");return a.className="panel",a},getHeaderButtonHolder:function(){var a=this.getButtonHolder();return a.style.display="inline-block",a.style.marginLeft="10px",a.style.verticalAlign="middle",a},getButtonHolder:function(){var a=document.createElement("div");return a.className="button-group",a},getButton:function(a,b,c){var d=this._super(a,b,c);return d.className+=" small button",d},addInputError:function(a,b){a.group&&(a.group.className+=" error",a.errmsg?a.errmsg.style.display="":(a.insertAdjacentHTML("afterend",'<small class="error"></small>'),a.errmsg=a.parentNode.getElementsByClassName("error")[0]),a.errmsg.textContent=b)},removeInputError:function(a){a.errmsg&&(a.group.className=a.group.className.replace(/ error/g,""),a.errmsg.style.display="none")},getProgressBar:function(){var a=document.createElement("div");a.className="progress";var b=document.createElement("span");return b.className="meter",b.style.width="0%",a.appendChild(b),a},updateProgressBar:function(a,b){a&&(a.firstChild.style.width=b+"%")},updateProgressBarUnknown:function(a){a&&(a.firstChild.style.width="100%")}}),f.defaults.themes.foundation3=f.defaults.themes.foundation.extend({getHeaderButtonHolder:function(){var a=this._super();return a.style.fontSize=".6em",a},getFormInputLabel:function(a,b){var c=this._super(a);return c.style.fontWeight="bold",b&&(c.className+=" required"),c},getTabHolder:function(){var a=document.createElement("div");return a.className="row",a.innerHTML="<dl class='tabs vertical two columns'></dl><div class='tabs-content ten columns'></div>",a},setGridColumnSize:function(a,b){var c=["zero","one","two","three","four","five","six","seven","eight","nine","ten","eleven","twelve"];a.className="columns "+c[b]},getTab:function(a){var b=document.createElement("dd"),c=document.createElement("a");return c.setAttribute("href","#"),c.appendChild(a),b.appendChild(c),b},getTabContentHolder:function(a){return a.children[1]},getTabContent:function(){var a=document.createElement("div");return a.className="content active",a.style.paddingLeft="5px",a},markTabActive:function(a){a.className+=" active"},markTabInactive:function(a){a.className=a.className.replace(/\s*active/g,"")},addTab:function(a,b){a.children[0].appendChild(b)}}),f.defaults.themes.foundation4=f.defaults.themes.foundation.extend({getHeaderButtonHolder:function(){var a=this._super();return a.style.fontSize=".6em",a},setGridColumnSize:function(a,b){a.className="columns large-"+b},getFormInputDescription:function(a){var b=this._super(a);return b.style.fontSize=".8rem",b},getFormInputLabel:function(a,b){var c=this._super(a);return c.style.fontWeight="bold",b&&(c.className+=" required"),c}}),f.defaults.themes.foundation5=f.defaults.themes.foundation.extend({getFormInputDescription:function(a){var b=this._super(a);return b.style.fontSize=".8rem",b},setGridColumnSize:function(a,b){a.className="columns medium-"+b},getButton:function(a,b,c){var d=this._super(a,b,c);return d.className=d.className.replace(/\s*small/g,"")+" tiny",d},getTabHolder:function(){var a=document.createElement("div");return a.innerHTML="<dl class='tabs vertical'></dl><div class='tabs-content vertical'></div>",a},getTab:function(a){var b=document.createElement("dd"),c=document.createElement("a");return c.setAttribute("href","#"),c.appendChild(a),b.appendChild(c),b},getTabContentHolder:function(a){return a.children[1]},getTabContent:function(){var a=document.createElement("div");return a.className="content active",a.style.paddingLeft="5px",a},markTabActive:function(a){a.className+=" active"},markTabInactive:function(a){a.className=a.className.replace(/\s*active/g,"")},addTab:function(a,b){a.children[0].appendChild(b)}}),f.defaults.themes.html=f.AbstractTheme.extend({getFormInputLabel:function(a,b){var c=this._super(a);return c.style.display="block",c.style.marginBottom="3px",c.style.fontWeight="bold",b&&(c.className+=" required"),c},getFormInputDescription:function(a){var b=this._super(a);return b.style.fontSize=".8em",b.style.margin=0,b.style.display="inline-block",b.style.fontStyle="italic",b},getIndentedPanel:function(){var a=this._super();return a.style.border="1px solid #ddd",a.style.padding="5px",a.style.margin="5px",a.style.borderRadius="3px",a},getChildEditorHolder:function(){var a=this._super();return a.style.marginBottom="8px",a},getHeaderButtonHolder:function(){var a=this.getButtonHolder();return a.style.display="inline-block",a.style.marginLeft="10px",a.style.fontSize=".8em",a.style.verticalAlign="middle",a},getTable:function(){var a=this._super();return a.style.borderBottom="1px solid #ccc",a.style.marginBottom="5px",a},addInputError:function(a,b){if(a.style.borderColor="red",a.errmsg)a.errmsg.style.display="block";else{var c=this.closest(a,".form-control");a.errmsg=document.createElement("div"),a.errmsg.setAttribute("class","errmsg"),a.errmsg.style=a.errmsg.style||{},a.errmsg.style.color="red",c.appendChild(a.errmsg)}a.errmsg.innerHTML="",a.errmsg.appendChild(document.createTextNode(b))},removeInputError:function(a){a.style.borderColor="",a.errmsg&&(a.errmsg.style.display="none")},getProgressBar:function(){var a=100,b=0,c=document.createElement("progress");return c.setAttribute("max",a),c.setAttribute("value",b),c},updateProgressBar:function(a,b){a&&a.setAttribute("value",b)},updateProgressBarUnknown:function(a){a&&a.removeAttribute("value")}}),f.defaults.themes.jqueryui=f.AbstractTheme.extend({getTable:function(){var a=this._super();return a.setAttribute("cellpadding",5),a.setAttribute("cellspacing",0),a},getTableHeaderCell:function(a){var b=this._super(a);return b.className="ui-state-active",b.style.fontWeight="bold",b},getTableCell:function(){var a=this._super();return a.className="ui-widget-content",a},getHeaderButtonHolder:function(){var a=this.getButtonHolder();return a.style.marginLeft="10px",a.style.fontSize=".6em",a.style.display="inline-block",a},getFormInputDescription:function(a){var b=this.getDescription(a);return b.style.marginLeft="10px",b.style.display="inline-block",b},getFormControl:function(a,b,c){var d=this._super(a,b,c);return"checkbox"===b.type?(d.style.lineHeight="25px",d.style.padding="3px 0"):d.style.padding="4px 0 8px 0",d},getDescription:function(a){var b=document.createElement("span");return b.style.fontSize=".8em",b.style.fontStyle="italic",b.textContent=a,b},getButtonHolder:function(){var a=document.createElement("div");return a.className="ui-buttonset",a.style.fontSize=".7em",a},getFormInputLabel:function(a,b){var c=document.createElement("label");return c.style.fontWeight="bold",c.style.display="block",b&&(c.className+=" required"),c.textContent=a,c},getButton:function(a,b,c){var d=document.createElement("button");d.className="ui-button ui-widget ui-state-default ui-corner-all",b&&!a?(d.className+=" ui-button-icon-only",b.className+=" ui-button-icon-primary ui-icon-primary",d.appendChild(b)):b?(d.className+=" ui-button-text-icon-primary",b.className+=" ui-button-icon-primary ui-icon-primary",d.appendChild(b)):d.className+=" ui-button-text-only";var e=document.createElement("span");return e.className="ui-button-text",e.textContent=a||c||".",d.appendChild(e),d.setAttribute("title",c),d},setButtonText:function(a,b,c,d){a.innerHTML="",a.className="ui-button ui-widget ui-state-default ui-corner-all",c&&!b?(a.className+=" ui-button-icon-only",c.className+=" ui-button-icon-primary ui-icon-primary",a.appendChild(c)):c?(a.className+=" ui-button-text-icon-primary",c.className+=" ui-button-icon-primary ui-icon-primary",a.appendChild(c)):a.className+=" ui-button-text-only";var e=document.createElement("span");e.className="ui-button-text",e.textContent=b||d||".",a.appendChild(e),a.setAttribute("title",d)},getIndentedPanel:function(){var a=document.createElement("div");return a.className="ui-widget-content ui-corner-all",a.style.padding="1em 1.4em",a.style.marginBottom="20px",a},afterInputReady:function(a){a.controls||(a.controls=this.closest(a,".form-control"))},addInputError:function(a,b){a.controls&&(a.errmsg?a.errmsg.style.display="":(a.errmsg=document.createElement("div"),a.errmsg.className="ui-state-error",a.controls.appendChild(a.errmsg)),a.errmsg.textContent=b)},removeInputError:function(a){a.errmsg&&(a.errmsg.style.display="none")},markTabActive:function(a){a.className=a.className.replace(/\s*ui-widget-header/g,"")+" ui-state-active"},markTabInactive:function(a){a.className=a.className.replace(/\s*ui-state-active/g,"")+" ui-widget-header"}}),f.AbstractIconLib=a.extend({mapping:{collapse:"",expand:"","delete":"",edit:"",add:"",cancel:"",save:"",moveup:"",movedown:""},icon_prefix:"",getIconClass:function(a){return this.mapping[a]?this.icon_prefix+this.mapping[a]:null},getIcon:function(a){var b=this.getIconClass(a);if(!b)return null;var c=document.createElement("i");return c.className=b,c}}),f.defaults.iconlibs.bootstrap2=f.AbstractIconLib.extend({mapping:{collapse:"chevron-down",expand:"chevron-up","delete":"trash",edit:"pencil",add:"plus",cancel:"ban-circle",save:"ok",moveup:"arrow-up",movedown:"arrow-down"},icon_prefix:"icon-"}),f.defaults.iconlibs.bootstrap3=f.AbstractIconLib.extend({mapping:{collapse:"chevron-down",expand:"chevron-right","delete":"remove",edit:"pencil",add:"plus",cancel:"floppy-remove",save:"floppy-saved",moveup:"arrow-up",movedown:"arrow-down"},icon_prefix:"glyphicon glyphicon-"}),f.defaults.iconlibs.fontawesome3=f.AbstractIconLib.extend({mapping:{collapse:"chevron-down",expand:"chevron-right","delete":"remove",edit:"pencil",add:"plus",cancel:"ban-circle",save:"save",moveup:"arrow-up",movedown:"arrow-down"},icon_prefix:"icon-"}),f.defaults.iconlibs.fontawesome4=f.AbstractIconLib.extend({mapping:{collapse:"caret-square-o-down",expand:"caret-square-o-right","delete":"times",edit:"pencil",add:"plus",cancel:"ban",save:"save",moveup:"arrow-up",movedown:"arrow-down"},icon_prefix:"fa fa-"}),f.defaults.iconlibs.foundation2=f.AbstractIconLib.extend({mapping:{collapse:"minus",expand:"plus","delete":"remove",edit:"edit",add:"add-doc",cancel:"error",save:"checkmark",moveup:"up-arrow",movedown:"down-arrow"},icon_prefix:"foundicon-"}),f.defaults.iconlibs.foundation3=f.AbstractIconLib.extend({mapping:{collapse:"minus",expand:"plus","delete":"x",edit:"pencil",add:"page-add",cancel:"x-circle",save:"save",moveup:"arrow-up",movedown:"arrow-down"},icon_prefix:"fi-"}),f.defaults.iconlibs.jqueryui=f.AbstractIconLib.extend({mapping:{collapse:"triangle-1-s",expand:"triangle-1-e","delete":"trash",edit:"pencil",add:"plusthick",cancel:"closethick",save:"disk",moveup:"arrowthick-1-n",movedown:"arrowthick-1-s"},icon_prefix:"ui-icon ui-icon-"}),f.defaults.templates["default"]=function(){return{compile:function(a){var b=a.match(/{{\s*([a-zA-Z0-9\-_ \.]+)\s*}}/g),c=b&&b.length;if(!c)return function(){return a};for(var d=[],e=function(a){var c,e=b[a].replace(/[{}]+/g,"").trim().split("."),f=e.length;if(f>1){var g;c=function(b){for(g=b,a=0;f>a&&(g=g[e[a]],g);a++);return g}}else e=e[0],c=function(a){return a[e]};d.push({s:b[a],r:c})},f=0;c>f;f++)e(f);return function(b){var e,g=a+"";for(f=0;c>f;f++)e=d[f],g=g.replace(e.s,e.r(b));return g}}}},f.defaults.templates.ejs=function(){return window.EJS?{compile:function(a){var b=new window.EJS({text:a});return function(a){return b.render(a)}}}:!1},f.defaults.templates.handlebars=function(){return window.Handlebars},f.defaults.templates.hogan=function(){return window.Hogan?{compile:function(a){var b=window.Hogan.compile(a);return function(a){return b.render(a)}}}:!1},f.defaults.templates.markup=function(){return window.Mark&&window.Mark.up?{compile:function(a){return function(b){return window.Mark.up(a,b)}}}:!1},f.defaults.templates.mustache=function(){return window.Mustache?{compile:function(a){return function(b){return window.Mustache.render(a,b)}}}:!1},f.defaults.templates.swig=function(){return window.swig},f.defaults.templates.underscore=function(){return window._?{compile:function(a){return function(b){return window._.template(a,b)}}}:!1},f.defaults.theme="html",f.defaults.template="default",f.defaults.options={},f.defaults.translate=function(a,b){var c=f.defaults.languages[f.defaults.language];if(!c)throw"Unknown language "+f.defaults.language;var d=c[a]||f.defaults.languages[f.defaults.default_language][a];if("undefined"==typeof d)throw"Unknown translate string "+a;if(b)for(var e=0;e<b.length;e++)d=d.replace(new RegExp("\\{\\{"+e+"}}","g"),b[e]);return d},f.defaults.default_language="en",f.defaults.language=f.defaults.default_language,f.defaults.languages.en={error_notset:"Property must be set",error_notempty:"Value required",error_enum:"Value must be one of the enumerated values",error_anyOf:"Value must validate against at least one of the provided schemas",error_oneOf:"Value must validate against exactly one of the provided schemas. It currently validates against {{0}} of the schemas.",error_not:"Value must not validate against the provided schema",error_type_union:"Value must be one of the provided types",error_type:"Value must be of type {{0}}",error_disallow_union:"Value must not be one of the provided disallowed types",error_disallow:"Value must not be of type {{0}}",error_multipleOf:"Value must be a multiple of {{0}}",error_maximum_excl:"Value must be less than {{0}}",error_maximum_incl:"Value must at most {{0}}",error_minimum_excl:"Value must be greater than {{0}}",error_minimum_incl:"Value must be at least {{0}}",error_maxLength:"Value must be at most {{0}} characters long",error_minLength:"Value must be at least {{0}} characters long",error_pattern:"Value must match the provided pattern",error_additionalItems:"No additional items allowed in this array",error_maxItems:"Value must have at most {{0}} items",error_minItems:"Value must have at least {{0}} items",error_uniqueItems:"Array must have unique items",error_maxProperties:"Object must have at most {{0}} properties",error_minProperties:"Object must have at least {{0}} properties",error_required:"Object is missing the required property '{{0}}'",error_additional_properties:"No additional properties allowed, but property {{0}} is set",error_dependency:"Must have property {{0}}"},f.plugins={ace:{theme:""},epiceditor:{},sceditor:{},select2:{}};for(var h in f.defaults.editors)f.defaults.editors.hasOwnProperty(h)&&(f.defaults.editors[h].options=f.defaults.editors.options||{});f.defaults.resolvers.unshift(function(a){return"string"!=typeof a.type?"multiple":void 0}),f.defaults.resolvers.unshift(function(a){return!a.type&&a.properties?"object":void 0}),f.defaults.resolvers.unshift(function(a){return"string"==typeof a.type?a.type:void 0}),f.defaults.resolvers.unshift(function(a){return"boolean"===a.type?"checkbox"===a.format||a.options&&a.options.checkbox?"checkbox":"select":void 0;
+}),f.defaults.resolvers.unshift(function(a){return"any"===a.type?"multiple":void 0}),f.defaults.resolvers.unshift(function(a){return"string"===a.type&&a.media&&"base64"===a.media.binaryEncoding?"base64":void 0}),f.defaults.resolvers.unshift(function(a){return"string"===a.type&&"url"===a.format&&a.options&&a.options.upload===!0&&window.FileReader?"upload":void 0}),f.defaults.resolvers.unshift(function(a){return"array"==a.type&&"table"==a.format?"table":void 0}),f.defaults.resolvers.unshift(function(a){return a.enumSource?"select":void 0}),f.defaults.resolvers.unshift(function(a){if(a["enum"]){if("array"===a.type||"object"===a.type)return"enum";if("number"===a.type||"integer"===a.type||"string"===a.type)return"select"}}),f.defaults.resolvers.unshift(function(a){return"array"===a.type&&a.items&&!Array.isArray(a.items)&&a.uniqueItems&&a.items["enum"]&&["string","number","integer"].indexOf(a.items.type)>=0?"multiselect":void 0}),f.defaults.resolvers.unshift(function(a){return a.oneOf?"multiple":void 0}),function(){if(window.jQuery||window.Zepto){var a=window.jQuery||window.Zepto;a.jsoneditor=f.defaults,a.fn.jsoneditor=function(a){var b=this,c=this.data("jsoneditor");if("value"===a){if(!c)throw"Must initialize jsoneditor before getting/setting the value";if(!(arguments.length>1))return c.getValue();c.setValue(arguments[1])}else{if("validate"===a){if(!c)throw"Must initialize jsoneditor before validating";return arguments.length>1?c.validate(arguments[1]):c.validate()}"destroy"===a?c&&(c.destroy(),this.data("jsoneditor",null)):(c&&c.destroy(),c=new f(this.get(0),a),this.data("jsoneditor",c),c.on("change",function(){b.trigger("change")}),c.on("ready",function(){b.trigger("ready")}))}return this}}}(),window.JSONEditor=f}(); \ No newline at end of file
diff --git a/ydb/core/viewer/content/api/lib/lodash.min.js b/ydb/core/viewer/content/api/lib/lodash.min.js
index 5563ccdfe59..05870d1c638 100644
--- a/ydb/core/viewer/content/api/lib/lodash.min.js
+++ b/ydb/core/viewer/content/api/lib/lodash.min.js
@@ -1,102 +1,102 @@
-/**
- * @license
- * lodash 3.10.1 (Custom Build) lodash.com/license | Underscore.js 1.8.3 underscorejs.org/LICENSE
- * Build: `lodash compat -o ./lodash.js`
- */
-;(function(){function n(n,t){if(n!==t){var r=null===n,e=n===w,u=n===n,o=null===t,i=t===w,f=t===t;if(n>t&&!o||!u||r&&!i&&f||e&&f)return 1;if(n<t&&!r||!f||o&&!e&&u||i&&u)return-1}return 0}function t(n,t,r){for(var e=n.length,u=r?e:-1;r?u--:++u<e;)if(t(n[u],u,n))return u;return-1}function r(n,t,r){if(t!==t)return p(n,r);r-=1;for(var e=n.length;++r<e;)if(n[r]===t)return r;return-1}function e(n){return typeof n=="function"||false}function u(n){return null==n?"":n+""}function o(n,t){for(var r=-1,e=n.length;++r<e&&-1<t.indexOf(n.charAt(r)););
-return r}function i(n,t){for(var r=n.length;r--&&-1<t.indexOf(n.charAt(r)););return r}function f(t,r){return n(t.a,r.a)||t.b-r.b}function a(n){return Nn[n]}function c(n){return Tn[n]}function l(n,t,r){return t?n=Bn[n]:r&&(n=Dn[n]),"\\"+n}function s(n){return"\\"+Dn[n]}function p(n,t,r){var e=n.length;for(t+=r?0:-1;r?t--:++t<e;){var u=n[t];if(u!==u)return t}return-1}function h(n){return!!n&&typeof n=="object"}function _(n){return 160>=n&&9<=n&&13>=n||32==n||160==n||5760==n||6158==n||8192<=n&&(8202>=n||8232==n||8233==n||8239==n||8287==n||12288==n||65279==n);
-}function v(n,t){for(var r=-1,e=n.length,u=-1,o=[];++r<e;)n[r]===t&&(n[r]=P,o[++u]=r);return o}function g(n){for(var t=-1,r=n.length;++t<r&&_(n.charCodeAt(t)););return t}function y(n){for(var t=n.length;t--&&_(n.charCodeAt(t)););return t}function d(n){return Pn[n]}function m(_){function Nn(n){if(h(n)&&!(Wo(n)||n instanceof zn)){if(n instanceof Pn)return n;if(eu.call(n,"__chain__")&&eu.call(n,"__wrapped__"))return qr(n)}return new Pn(n)}function Tn(){}function Pn(n,t,r){this.__wrapped__=n,this.__actions__=r||[],
-this.__chain__=!!t}function zn(n){this.__wrapped__=n,this.__actions__=[],this.__dir__=1,this.__filtered__=false,this.__iteratees__=[],this.__takeCount__=Cu,this.__views__=[]}function Bn(){this.__data__={}}function Dn(n){var t=n?n.length:0;for(this.data={hash:mu(null),set:new hu};t--;)this.push(n[t])}function Mn(n,t){var r=n.data;return(typeof t=="string"||de(t)?r.set.has(t):r.hash[t])?0:-1}function qn(n,t){var r=-1,e=n.length;for(t||(t=De(e));++r<e;)t[r]=n[r];return t}function Kn(n,t){for(var r=-1,e=n.length;++r<e&&false!==t(n[r],r,n););
-return n}function Vn(n,t){for(var r=-1,e=n.length;++r<e;)if(!t(n[r],r,n))return false;return true}function Zn(n,t){for(var r=-1,e=n.length,u=-1,o=[];++r<e;){var i=n[r];t(i,r,n)&&(o[++u]=i)}return o}function Xn(n,t){for(var r=-1,e=n.length,u=De(e);++r<e;)u[r]=t(n[r],r,n);return u}function Hn(n,t){for(var r=-1,e=t.length,u=n.length;++r<e;)n[u+r]=t[r];return n}function Qn(n,t,r,e){var u=-1,o=n.length;for(e&&o&&(r=n[++u]);++u<o;)r=t(r,n[u],u,n);return r}function nt(n,t){for(var r=-1,e=n.length;++r<e;)if(t(n[r],r,n))return true;
-return false}function tt(n,t,r,e){return n!==w&&eu.call(e,r)?n:t}function rt(n,t,r){for(var e=-1,u=Ko(t),o=u.length;++e<o;){var i=u[e],f=n[i],a=r(f,t[i],i,n,t);(a===a?a===f:f!==f)&&(f!==w||i in n)||(n[i]=a)}return n}function et(n,t){return null==t?n:ot(t,Ko(t),n)}function ut(n,t){for(var r=-1,e=null==n,u=!e&&Sr(n),o=u?n.length:0,i=t.length,f=De(i);++r<i;){var a=t[r];f[r]=u?Ur(a,o)?n[a]:w:e?w:n[a]}return f}function ot(n,t,r){r||(r={});for(var e=-1,u=t.length;++e<u;){var o=t[e];r[o]=n[o]}return r}function it(n,t,r){
-var e=typeof n;return"function"==e?t===w?n:Dt(n,t,r):null==n?Ne:"object"==e?At(n):t===w?Be(n):jt(n,t)}function ft(n,t,r,e,u,o,i){var f;if(r&&(f=u?r(n,e,u):r(n)),f!==w)return f;if(!de(n))return n;if(e=Wo(n)){if(f=Ir(n),!t)return qn(n,f)}else{var a=ou.call(n),c=a==K;if(a!=Z&&a!=z&&(!c||u))return Ln[a]?Er(n,a,t):u?n:{};if(Gn(n))return u?n:{};if(f=Rr(c?{}:n),!t)return et(f,n)}for(o||(o=[]),i||(i=[]),u=o.length;u--;)if(o[u]==n)return i[u];return o.push(n),i.push(f),(e?Kn:gt)(n,function(e,u){f[u]=ft(e,t,r,u,n,o,i);
-}),f}function at(n,t,r){if(typeof n!="function")throw new Xe(T);return _u(function(){n.apply(w,r)},t)}function ct(n,t){var e=n?n.length:0,u=[];if(!e)return u;var o=-1,i=jr(),f=i===r,a=f&&t.length>=F&&mu&&hu?new Dn(t):null,c=t.length;a&&(i=Mn,f=false,t=a);n:for(;++o<e;)if(a=n[o],f&&a===a){for(var l=c;l--;)if(t[l]===a)continue n;u.push(a)}else 0>i(t,a,0)&&u.push(a);return u}function lt(n,t){var r=true;return zu(n,function(n,e,u){return r=!!t(n,e,u)}),r}function st(n,t,r,e){var u=e,o=u;return zu(n,function(n,i,f){
-i=+t(n,i,f),(r(i,u)||i===e&&i===o)&&(u=i,o=n)}),o}function pt(n,t){var r=[];return zu(n,function(n,e,u){t(n,e,u)&&r.push(n)}),r}function ht(n,t,r,e){var u;return r(n,function(n,r,o){return t(n,r,o)?(u=e?r:n,false):void 0}),u}function _t(n,t,r,e){e||(e=[]);for(var u=-1,o=n.length;++u<o;){var i=n[u];h(i)&&Sr(i)&&(r||Wo(i)||_e(i))?t?_t(i,t,r,e):Hn(e,i):r||(e[e.length]=i)}return e}function vt(n,t){return Du(n,t,Ee)}function gt(n,t){return Du(n,t,Ko)}function yt(n,t){return Mu(n,t,Ko)}function dt(n,t){for(var r=-1,e=t.length,u=-1,o=[];++r<e;){
-var i=t[r];ye(n[i])&&(o[++u]=i)}return o}function mt(n,t,r){if(null!=n){n=Dr(n),r!==w&&r in n&&(t=[r]),r=0;for(var e=t.length;null!=n&&r<e;)n=Dr(n)[t[r++]];return r&&r==e?n:w}}function wt(n,t,r,e,u,o){if(n===t)return true;if(null==n||null==t||!de(n)&&!h(t))return n!==n&&t!==t;n:{var i=wt,f=Wo(n),a=Wo(t),c=B,l=B;f||(c=ou.call(n),c==z?c=Z:c!=Z&&(f=je(n))),a||(l=ou.call(t),l==z?l=Z:l!=Z&&je(t));var s=c==Z&&!Gn(n),a=l==Z&&!Gn(t),l=c==l;if(!l||f||s){if(!e&&(c=s&&eu.call(n,"__wrapped__"),a=a&&eu.call(t,"__wrapped__"),
-c||a)){n=i(c?n.value():n,a?t.value():t,r,e,u,o);break n}if(l){for(u||(u=[]),o||(o=[]),c=u.length;c--;)if(u[c]==n){n=o[c]==t;break n}u.push(n),o.push(t),n=(f?mr:xr)(n,t,i,r,e,u,o),u.pop(),o.pop()}else n=false}else n=wr(n,t,c)}return n}function xt(n,t,r){var e=t.length,u=e,o=!r;if(null==n)return!u;for(n=Dr(n);e--;){var i=t[e];if(o&&i[2]?i[1]!==n[i[0]]:!(i[0]in n))return false}for(;++e<u;){var i=t[e],f=i[0],a=n[f],c=i[1];if(o&&i[2]){if(a===w&&!(f in n))return false}else if(i=r?r(a,c,f):w,i===w?!wt(c,a,r,true):!i)return false;
-}return true}function bt(n,t){var r=-1,e=Sr(n)?De(n.length):[];return zu(n,function(n,u,o){e[++r]=t(n,u,o)}),e}function At(n){var t=kr(n);if(1==t.length&&t[0][2]){var r=t[0][0],e=t[0][1];return function(n){return null==n?false:(n=Dr(n),n[r]===e&&(e!==w||r in n))}}return function(n){return xt(n,t)}}function jt(n,t){var r=Wo(n),e=Wr(n)&&t===t&&!de(t),u=n+"";return n=Mr(n),function(o){if(null==o)return false;var i=u;if(o=Dr(o),!(!r&&e||i in o)){if(o=1==n.length?o:mt(o,St(n,0,-1)),null==o)return false;i=Gr(n),o=Dr(o);
-}return o[i]===t?t!==w||i in o:wt(t,o[i],w,true)}}function kt(n,t,r,e,u){if(!de(n))return n;var o=Sr(t)&&(Wo(t)||je(t)),i=o?w:Ko(t);return Kn(i||t,function(f,a){if(i&&(a=f,f=t[a]),h(f)){e||(e=[]),u||(u=[]);n:{for(var c=a,l=e,s=u,p=l.length,_=t[c];p--;)if(l[p]==_){n[c]=s[p];break n}var p=n[c],v=r?r(p,_,c,n,t):w,g=v===w;g&&(v=_,Sr(_)&&(Wo(_)||je(_))?v=Wo(p)?p:Sr(p)?qn(p):[]:xe(_)||_e(_)?v=_e(p)?Ie(p):xe(p)?p:{}:g=false),l.push(_),s.push(v),g?n[c]=kt(v,_,r,l,s):(v===v?v!==p:p===p)&&(n[c]=v)}}else c=n[a],
-l=r?r(c,f,a,n,t):w,(s=l===w)&&(l=f),l===w&&(!o||a in n)||!s&&(l===l?l===c:c!==c)||(n[a]=l)}),n}function Ot(n){return function(t){return null==t?w:Dr(t)[n]}}function It(n){var t=n+"";return n=Mr(n),function(r){return mt(r,n,t)}}function Rt(n,t){for(var r=n?t.length:0;r--;){var e=t[r];if(e!=u&&Ur(e)){var u=e;vu.call(n,e,1)}}return n}function Et(n,t){return n+wu(Ru()*(t-n+1))}function Ct(n,t,r,e,u){return u(n,function(n,u,o){r=e?(e=false,n):t(r,n,u,o)}),r}function St(n,t,r){var e=-1,u=n.length;for(t=null==t?0:+t||0,
-0>t&&(t=-t>u?0:u+t),r=r===w||r>u?u:+r||0,0>r&&(r+=u),u=t>r?0:r-t>>>0,t>>>=0,r=De(u);++e<u;)r[e]=n[e+t];return r}function Ut(n,t){var r;return zu(n,function(n,e,u){return r=t(n,e,u),!r}),!!r}function $t(n,t){var r=n.length;for(n.sort(t);r--;)n[r]=n[r].c;return n}function Wt(t,r,e){var u=br(),o=-1;return r=Xn(r,function(n){return u(n)}),t=bt(t,function(n){return{a:Xn(r,function(t){return t(n)}),b:++o,c:n}}),$t(t,function(t,r){var u;n:{for(var o=-1,i=t.a,f=r.a,a=i.length,c=e.length;++o<a;)if(u=n(i[o],f[o])){
-if(o>=c)break n;o=e[o],u*="asc"===o||true===o?1:-1;break n}u=t.b-r.b}return u})}function Ft(n,t){var r=0;return zu(n,function(n,e,u){r+=+t(n,e,u)||0}),r}function Lt(n,t){var e=-1,u=jr(),o=n.length,i=u===r,f=i&&o>=F,a=f&&mu&&hu?new Dn(void 0):null,c=[];a?(u=Mn,i=false):(f=false,a=t?[]:c);n:for(;++e<o;){var l=n[e],s=t?t(l,e,n):l;if(i&&l===l){for(var p=a.length;p--;)if(a[p]===s)continue n;t&&a.push(s),c.push(l)}else 0>u(a,s,0)&&((t||f)&&a.push(s),c.push(l))}return c}function Nt(n,t){for(var r=-1,e=t.length,u=De(e);++r<e;)u[r]=n[t[r]];
-return u}function Tt(n,t,r,e){for(var u=n.length,o=e?u:-1;(e?o--:++o<u)&&t(n[o],o,n););return r?St(n,e?0:o,e?o+1:u):St(n,e?o+1:0,e?u:o)}function Pt(n,t){var r=n;r instanceof zn&&(r=r.value());for(var e=-1,u=t.length;++e<u;)var o=t[e],r=o.func.apply(o.thisArg,Hn([r],o.args));return r}function zt(n,t,r){var e=0,u=n?n.length:e;if(typeof t=="number"&&t===t&&u<=Uu){for(;e<u;){var o=e+u>>>1,i=n[o];(r?i<=t:i<t)&&null!==i?e=o+1:u=o}return u}return Bt(n,t,Ne,r)}function Bt(n,t,r,e){t=r(t);for(var u=0,o=n?n.length:0,i=t!==t,f=null===t,a=t===w;u<o;){
-var c=wu((u+o)/2),l=r(n[c]),s=l!==w,p=l===l;(i?p||e:f?p&&s&&(e||null!=l):a?p&&(e||s):null==l?0:e?l<=t:l<t)?u=c+1:o=c}return ku(o,Su)}function Dt(n,t,r){if(typeof n!="function")return Ne;if(t===w)return n;switch(r){case 1:return function(r){return n.call(t,r)};case 3:return function(r,e,u){return n.call(t,r,e,u)};case 4:return function(r,e,u,o){return n.call(t,r,e,u,o)};case 5:return function(r,e,u,o,i){return n.call(t,r,e,u,o,i)}}return function(){return n.apply(t,arguments)}}function Mt(n){var t=new au(n.byteLength);
-return new gu(t).set(new gu(n)),t}function qt(n,t,r){for(var e=r.length,u=-1,o=ju(n.length-e,0),i=-1,f=t.length,a=De(f+o);++i<f;)a[i]=t[i];for(;++u<e;)a[r[u]]=n[u];for(;o--;)a[i++]=n[u++];return a}function Kt(n,t,r){for(var e=-1,u=r.length,o=-1,i=ju(n.length-u,0),f=-1,a=t.length,c=De(i+a);++o<i;)c[o]=n[o];for(i=o;++f<a;)c[i+f]=t[f];for(;++e<u;)c[i+r[e]]=n[o++];return c}function Vt(n,t){return function(r,e,u){var o=t?t():{};if(e=br(e,u,3),Wo(r)){u=-1;for(var i=r.length;++u<i;){var f=r[u];n(o,f,e(f,u,r),r);
-}}else zu(r,function(t,r,u){n(o,t,e(t,r,u),u)});return o}}function Zt(n){return pe(function(t,r){var e=-1,u=null==t?0:r.length,o=2<u?r[u-2]:w,i=2<u?r[2]:w,f=1<u?r[u-1]:w;for(typeof o=="function"?(o=Dt(o,f,5),u-=2):(o=typeof f=="function"?f:w,u-=o?1:0),i&&$r(r[0],r[1],i)&&(o=3>u?w:o,u=1);++e<u;)(i=r[e])&&n(t,i,o);return t})}function Yt(n,t){return function(r,e){var u=r?Vu(r):0;if(!Lr(u))return n(r,e);for(var o=t?u:-1,i=Dr(r);(t?o--:++o<u)&&false!==e(i[o],o,i););return r}}function Gt(n){return function(t,r,e){
-var u=Dr(t);e=e(t);for(var o=e.length,i=n?o:-1;n?i--:++i<o;){var f=e[i];if(false===r(u[f],f,u))break}return t}}function Jt(n,t){function r(){return(this&&this!==Yn&&this instanceof r?e:n).apply(t,arguments)}var e=Ht(n);return r}function Xt(n){return function(t){var r=-1;t=Fe(Ue(t));for(var e=t.length,u="";++r<e;)u=n(u,t[r],r);return u}}function Ht(n){return function(){var t=arguments;switch(t.length){case 0:return new n;case 1:return new n(t[0]);case 2:return new n(t[0],t[1]);case 3:return new n(t[0],t[1],t[2]);
-case 4:return new n(t[0],t[1],t[2],t[3]);case 5:return new n(t[0],t[1],t[2],t[3],t[4]);case 6:return new n(t[0],t[1],t[2],t[3],t[4],t[5]);case 7:return new n(t[0],t[1],t[2],t[3],t[4],t[5],t[6])}var r=Pu(n.prototype),t=n.apply(r,t);return de(t)?t:r}}function Qt(n){function t(r,e,u){return u&&$r(r,e,u)&&(e=w),r=dr(r,n,w,w,w,w,w,e),r.placeholder=t.placeholder,r}return t}function nr(n,t){return pe(function(r){var e=r[0];return null==e?e:(r.push(t),n.apply(w,r))})}function tr(n,t){return function(r,e,u){
-if(u&&$r(r,e,u)&&(e=w),e=br(e,u,3),1==e.length){u=r=Wo(r)?r:Br(r);for(var o=e,i=-1,f=u.length,a=t,c=a;++i<f;){var l=u[i],s=+o(l);n(s,a)&&(a=s,c=l)}if(u=c,!r.length||u!==t)return u}return st(r,e,n,t)}}function rr(n,r){return function(e,u,o){return u=br(u,o,3),Wo(e)?(u=t(e,u,r),-1<u?e[u]:w):ht(e,u,n)}}function er(n){return function(r,e,u){return r&&r.length?(e=br(e,u,3),t(r,e,n)):-1}}function ur(n){return function(t,r,e){return r=br(r,e,3),ht(t,r,n,true)}}function or(n){return function(){for(var t,r=arguments.length,e=n?r:-1,u=0,o=De(r);n?e--:++e<r;){
-var i=o[u++]=arguments[e];if(typeof i!="function")throw new Xe(T);!t&&Pn.prototype.thru&&"wrapper"==Ar(i)&&(t=new Pn([],true))}for(e=t?-1:r;++e<r;){var i=o[e],u=Ar(i),f="wrapper"==u?Ku(i):w;t=f&&Fr(f[0])&&f[1]==(E|k|I|C)&&!f[4].length&&1==f[9]?t[Ar(f[0])].apply(t,f[3]):1==i.length&&Fr(i)?t[u]():t.thru(i)}return function(){var n=arguments,e=n[0];if(t&&1==n.length&&Wo(e)&&e.length>=F)return t.plant(e).value();for(var u=0,n=r?o[u].apply(this,n):e;++u<r;)n=o[u].call(this,n);return n}}}function ir(n,t){
-return function(r,e,u){return typeof e=="function"&&u===w&&Wo(r)?n(r,e):t(r,Dt(e,u,3))}}function fr(n){return function(t,r,e){return(typeof r!="function"||e!==w)&&(r=Dt(r,e,3)),n(t,r,Ee)}}function ar(n){return function(t,r,e){return(typeof r!="function"||e!==w)&&(r=Dt(r,e,3)),n(t,r)}}function cr(n){return function(t,r,e){var u={};return r=br(r,e,3),gt(t,function(t,e,o){o=r(t,e,o),e=n?o:e,t=n?t:o,u[e]=t}),u}}function lr(n){return function(t,r,e){return t=u(t),(n?t:"")+_r(t,r,e)+(n?"":t)}}function sr(n){
-var t=pe(function(r,e){var u=v(e,t.placeholder);return dr(r,n,w,e,u)});return t}function pr(n,t){return function(r,e,u,o){var i=3>arguments.length;return typeof e=="function"&&o===w&&Wo(r)?n(r,e,u,i):Ct(r,br(e,o,4),u,i,t)}}function hr(n,t,r,e,u,o,i,f,a,c){function l(){for(var m=arguments.length,x=m,j=De(m);x--;)j[x]=arguments[x];if(e&&(j=qt(j,e,u)),o&&(j=Kt(j,o,i)),_||y){var x=l.placeholder,k=v(j,x),m=m-k.length;if(m<c){var O=f?qn(f):w,m=ju(c-m,0),E=_?k:w,k=_?w:k,C=_?j:w,j=_?w:j;return t|=_?I:R,t&=~(_?R:I),
-g||(t&=~(b|A)),j=[n,t,r,C,E,j,k,O,a,m],O=hr.apply(w,j),Fr(n)&&Zu(O,j),O.placeholder=x,O}}if(x=p?r:this,O=h?x[n]:n,f)for(m=j.length,E=ku(f.length,m),k=qn(j);E--;)C=f[E],j[E]=Ur(C,m)?k[C]:w;return s&&a<j.length&&(j.length=a),this&&this!==Yn&&this instanceof l&&(O=d||Ht(n)),O.apply(x,j)}var s=t&E,p=t&b,h=t&A,_=t&k,g=t&j,y=t&O,d=h?w:Ht(n);return l}function _r(n,t,r){return n=n.length,t=+t,n<t&&bu(t)?(t-=n,r=null==r?" ":r+"",$e(r,du(t/r.length)).slice(0,t)):""}function vr(n,t,r,e){function u(){for(var t=-1,f=arguments.length,a=-1,c=e.length,l=De(c+f);++a<c;)l[a]=e[a];
-for(;f--;)l[a++]=arguments[++t];return(this&&this!==Yn&&this instanceof u?i:n).apply(o?r:this,l)}var o=t&b,i=Ht(n);return u}function gr(n){var t=Ve[n];return function(n,r){return(r=r===w?0:+r||0)?(r=su(10,r),t(n*r)/r):t(n)}}function yr(n){return function(t,r,e,u){var o=br(e);return null==e&&o===it?zt(t,r,n):Bt(t,r,o(e,u,1),n)}}function dr(n,t,r,e,u,o,i,f){var a=t&A;if(!a&&typeof n!="function")throw new Xe(T);var c=e?e.length:0;if(c||(t&=~(I|R),e=u=w),c-=u?u.length:0,t&R){var l=e,s=u;e=u=w}var p=a?w:Ku(n);
-return r=[n,t,r,e,u,l,s,o,i,f],p&&(e=r[1],t=p[1],f=e|t,u=t==E&&e==k||t==E&&e==C&&r[7].length<=p[8]||t==(E|C)&&e==k,(f<E||u)&&(t&b&&(r[2]=p[2],f|=e&b?0:j),(e=p[3])&&(u=r[3],r[3]=u?qt(u,e,p[4]):qn(e),r[4]=u?v(r[3],P):qn(p[4])),(e=p[5])&&(u=r[5],r[5]=u?Kt(u,e,p[6]):qn(e),r[6]=u?v(r[5],P):qn(p[6])),(e=p[7])&&(r[7]=qn(e)),t&E&&(r[8]=null==r[8]?p[8]:ku(r[8],p[8])),null==r[9]&&(r[9]=p[9]),r[0]=p[0],r[1]=f),t=r[1],f=r[9]),r[9]=null==f?a?0:n.length:ju(f-c,0)||0,n=t==b?Jt(r[0],r[2]):t!=I&&t!=(b|I)||r[4].length?hr.apply(w,r):vr.apply(w,r),
-(p?qu:Zu)(n,r)}function mr(n,t,r,e,u,o,i){var f=-1,a=n.length,c=t.length;if(a!=c&&(!u||c<=a))return false;for(;++f<a;){var l=n[f],c=t[f],s=e?e(u?c:l,u?l:c,f):w;if(s!==w){if(s)continue;return false}if(u){if(!nt(t,function(n){return l===n||r(l,n,e,u,o,i)}))return false}else if(l!==c&&!r(l,c,e,u,o,i))return false}return true}function wr(n,t,r){switch(r){case D:case M:return+n==+t;case q:return n.name==t.name&&n.message==t.message;case V:return n!=+n?t!=+t:n==+t;case Y:case G:return n==t+""}return false}function xr(n,t,r,e,u,o,i){
-var f=Ko(n),a=f.length,c=Ko(t).length;if(a!=c&&!u)return false;for(c=a;c--;){var l=f[c];if(!(u?l in t:eu.call(t,l)))return false}for(var s=u;++c<a;){var l=f[c],p=n[l],h=t[l],_=e?e(u?h:p,u?p:h,l):w;if(_===w?!r(p,h,e,u,o,i):!_)return false;s||(s="constructor"==l)}return s||(r=n.constructor,e=t.constructor,!(r!=e&&"constructor"in n&&"constructor"in t)||typeof r=="function"&&r instanceof r&&typeof e=="function"&&e instanceof e)?true:false}function br(n,t,r){var e=Nn.callback||Le,e=e===Le?it:e;return r?e(n,t,r):e}function Ar(n){
-for(var t=n.name+"",r=Fu[t],e=r?r.length:0;e--;){var u=r[e],o=u.func;if(null==o||o==n)return u.name}return t}function jr(n,t,e){var u=Nn.indexOf||Yr,u=u===Yr?r:u;return n?u(n,t,e):u}function kr(n){n=Ce(n);for(var t=n.length;t--;){var r,e=n[t];r=n[t][1],r=r===r&&!de(r),e[2]=r}return n}function Or(n,t){var r=null==n?w:n[t];return me(r)?r:w}function Ir(n){var t=n.length,r=new n.constructor(t);return t&&"string"==typeof n[0]&&eu.call(n,"index")&&(r.index=n.index,r.input=n.input),r}function Rr(n){return n=n.constructor,
-typeof n=="function"&&n instanceof n||(n=Ye),new n}function Er(n,t,r){var e=n.constructor;switch(t){case J:return Mt(n);case D:case M:return new e(+n);case X:case H:case Q:case nn:case tn:case rn:case en:case un:case on:return e instanceof e&&(e=Lu[t]),t=n.buffer,new e(r?Mt(t):t,n.byteOffset,n.length);case V:case G:return new e(n);case Y:var u=new e(n.source,kn.exec(n));u.lastIndex=n.lastIndex}return u}function Cr(n,t,r){return null==n||Wr(t,n)||(t=Mr(t),n=1==t.length?n:mt(n,St(t,0,-1)),t=Gr(t)),
-t=null==n?n:n[t],null==t?w:t.apply(n,r)}function Sr(n){return null!=n&&Lr(Vu(n))}function Ur(n,t){return n=typeof n=="number"||Rn.test(n)?+n:-1,t=null==t?$u:t,-1<n&&0==n%1&&n<t}function $r(n,t,r){if(!de(r))return false;var e=typeof t;return("number"==e?Sr(r)&&Ur(t,r.length):"string"==e&&t in r)?(t=r[t],n===n?n===t:t!==t):false}function Wr(n,t){var r=typeof n;return"string"==r&&dn.test(n)||"number"==r?true:Wo(n)?false:!yn.test(n)||null!=t&&n in Dr(t)}function Fr(n){var t=Ar(n),r=Nn[t];return typeof r=="function"&&t in zn.prototype?n===r?true:(t=Ku(r),
-!!t&&n===t[0]):false}function Lr(n){return typeof n=="number"&&-1<n&&0==n%1&&n<=$u}function Nr(n,t){return n===w?t:Fo(n,t,Nr)}function Tr(n,t){n=Dr(n);for(var r=-1,e=t.length,u={};++r<e;){var o=t[r];o in n&&(u[o]=n[o])}return u}function Pr(n,t){var r={};return vt(n,function(n,e,u){t(n,e,u)&&(r[e]=n)}),r}function zr(n){for(var t=Ee(n),r=t.length,e=r&&n.length,u=!!e&&Lr(e)&&(Wo(n)||_e(n)||Ae(n)),o=-1,i=[];++o<r;){var f=t[o];(u&&Ur(f,e)||eu.call(n,f))&&i.push(f)}return i}function Br(n){return null==n?[]:Sr(n)?Nn.support.unindexedChars&&Ae(n)?n.split(""):de(n)?n:Ye(n):Se(n);
-}function Dr(n){if(Nn.support.unindexedChars&&Ae(n)){for(var t=-1,r=n.length,e=Ye(n);++t<r;)e[t]=n.charAt(t);return e}return de(n)?n:Ye(n)}function Mr(n){if(Wo(n))return n;var t=[];return u(n).replace(mn,function(n,r,e,u){t.push(e?u.replace(An,"$1"):r||n)}),t}function qr(n){return n instanceof zn?n.clone():new Pn(n.__wrapped__,n.__chain__,qn(n.__actions__))}function Kr(n,t,r){return n&&n.length?((r?$r(n,t,r):null==t)&&(t=1),St(n,0>t?0:t)):[]}function Vr(n,t,r){var e=n?n.length:0;return e?((r?$r(n,t,r):null==t)&&(t=1),
-t=e-(+t||0),St(n,0,0>t?0:t)):[]}function Zr(n){return n?n[0]:w}function Yr(n,t,e){var u=n?n.length:0;if(!u)return-1;if(typeof e=="number")e=0>e?ju(u+e,0):e;else if(e)return e=zt(n,t),e<u&&(t===t?t===n[e]:n[e]!==n[e])?e:-1;return r(n,t,e||0)}function Gr(n){var t=n?n.length:0;return t?n[t-1]:w}function Jr(n){return Kr(n,1)}function Xr(n,t,e,u){if(!n||!n.length)return[];null!=t&&typeof t!="boolean"&&(u=e,e=$r(n,t,u)?w:t,t=false);var o=br();if((null!=e||o!==it)&&(e=o(e,u,3)),t&&jr()===r){t=e;var i;e=-1,
-u=n.length;for(var o=-1,f=[];++e<u;){var a=n[e],c=t?t(a,e,n):a;e&&i===c||(i=c,f[++o]=a)}n=f}else n=Lt(n,e);return n}function Hr(n){if(!n||!n.length)return[];var t=-1,r=0;n=Zn(n,function(n){return Sr(n)?(r=ju(n.length,r),true):void 0});for(var e=De(r);++t<r;)e[t]=Xn(n,Ot(t));return e}function Qr(n,t,r){return n&&n.length?(n=Hr(n),null==t?n:(t=Dt(t,r,4),Xn(n,function(n){return Qn(n,t,w,true)}))):[]}function ne(n,t){var r=-1,e=n?n.length:0,u={};for(!e||t||Wo(n[0])||(t=[]);++r<e;){var o=n[r];t?u[o]=t[r]:o&&(u[o[0]]=o[1]);
-}return u}function te(n){return n=Nn(n),n.__chain__=true,n}function re(n,t,r){return t.call(r,n)}function ee(n,t,r){var e=Wo(n)?Vn:lt;return r&&$r(n,t,r)&&(t=w),(typeof t!="function"||r!==w)&&(t=br(t,r,3)),e(n,t)}function ue(n,t,r){var e=Wo(n)?Zn:pt;return t=br(t,r,3),e(n,t)}function oe(n,t,r,e){var u=n?Vu(n):0;return Lr(u)||(n=Se(n),u=n.length),r=typeof r!="number"||e&&$r(t,r,e)?0:0>r?ju(u+r,0):r||0,typeof n=="string"||!Wo(n)&&Ae(n)?r<=u&&-1<n.indexOf(t,r):!!u&&-1<jr(n,t,r)}function ie(n,t,r){var e=Wo(n)?Xn:bt;
-return t=br(t,r,3),e(n,t)}function fe(n,t,r){if(r?$r(n,t,r):null==t){n=Br(n);var e=n.length;return 0<e?n[Et(0,e-1)]:w}r=-1,n=Oe(n);var e=n.length,u=e-1;for(t=ku(0>t?0:+t||0,e);++r<t;){var e=Et(r,u),o=n[e];n[e]=n[r],n[r]=o}return n.length=t,n}function ae(n,t,r){var e=Wo(n)?nt:Ut;return r&&$r(n,t,r)&&(t=w),(typeof t!="function"||r!==w)&&(t=br(t,r,3)),e(n,t)}function ce(n,t){var r;if(typeof t!="function"){if(typeof n!="function")throw new Xe(T);var e=n;n=t,t=e}return function(){return 0<--n&&(r=t.apply(this,arguments)),
-1>=n&&(t=w),r}}function le(n,t,r){function e(t,r){r&&cu(r),a=p=h=w,t&&(_=wo(),c=n.apply(s,f),p||a||(f=s=w))}function u(){var n=t-(wo()-l);0>=n||n>t?e(h,a):p=_u(u,n)}function o(){e(g,p)}function i(){if(f=arguments,l=wo(),s=this,h=g&&(p||!y),false===v)var r=y&&!p;else{a||y||(_=l);var e=v-(l-_),i=0>=e||e>v;i?(a&&(a=cu(a)),_=l,c=n.apply(s,f)):a||(a=_u(o,e))}return i&&p?p=cu(p):p||t===v||(p=_u(u,t)),r&&(i=true,c=n.apply(s,f)),!i||p||a||(f=s=w),c}var f,a,c,l,s,p,h,_=0,v=false,g=true;if(typeof n!="function")throw new Xe(T);
-if(t=0>t?0:+t||0,true===r)var y=true,g=false;else de(r)&&(y=!!r.leading,v="maxWait"in r&&ju(+r.maxWait||0,t),g="trailing"in r?!!r.trailing:g);return i.cancel=function(){p&&cu(p),a&&cu(a),_=0,a=p=h=w},i}function se(n,t){if(typeof n!="function"||t&&typeof t!="function")throw new Xe(T);var r=function(){var e=arguments,u=t?t.apply(this,e):e[0],o=r.cache;return o.has(u)?o.get(u):(e=n.apply(this,e),r.cache=o.set(u,e),e)};return r.cache=new se.Cache,r}function pe(n,t){if(typeof n!="function")throw new Xe(T);return t=ju(t===w?n.length-1:+t||0,0),
-function(){for(var r=arguments,e=-1,u=ju(r.length-t,0),o=De(u);++e<u;)o[e]=r[t+e];switch(t){case 0:return n.call(this,o);case 1:return n.call(this,r[0],o);case 2:return n.call(this,r[0],r[1],o)}for(u=De(t+1),e=-1;++e<t;)u[e]=r[e];return u[t]=o,n.apply(this,u)}}function he(n,t){return n>t}function _e(n){return h(n)&&Sr(n)&&eu.call(n,"callee")&&!pu.call(n,"callee")}function ve(n,t,r,e){return e=(r=typeof r=="function"?Dt(r,e,3):w)?r(n,t):w,e===w?wt(n,t,r):!!e}function ge(n){return h(n)&&typeof n.message=="string"&&ou.call(n)==q;
-}function ye(n){return de(n)&&ou.call(n)==K}function de(n){var t=typeof n;return!!n&&("object"==t||"function"==t)}function me(n){return null==n?false:ye(n)?fu.test(ru.call(n)):h(n)&&(Gn(n)?fu:In).test(n)}function we(n){return typeof n=="number"||h(n)&&ou.call(n)==V}function xe(n){var t;if(!h(n)||ou.call(n)!=Z||Gn(n)||_e(n)||!(eu.call(n,"constructor")||(t=n.constructor,typeof t!="function"||t instanceof t)))return false;var r;return Nn.support.ownLast?(vt(n,function(n,t,e){return r=eu.call(e,t),false}),false!==r):(vt(n,function(n,t){
-r=t}),r===w||eu.call(n,r))}function be(n){return de(n)&&ou.call(n)==Y}function Ae(n){return typeof n=="string"||h(n)&&ou.call(n)==G}function je(n){return h(n)&&Lr(n.length)&&!!Fn[ou.call(n)]}function ke(n,t){return n<t}function Oe(n){var t=n?Vu(n):0;return Lr(t)?t?Nn.support.unindexedChars&&Ae(n)?n.split(""):qn(n):[]:Se(n)}function Ie(n){return ot(n,Ee(n))}function Re(n){return dt(n,Ee(n))}function Ee(n){if(null==n)return[];de(n)||(n=Ye(n));for(var t=n.length,r=Nn.support,t=t&&Lr(t)&&(Wo(n)||_e(n)||Ae(n))&&t||0,e=n.constructor,u=-1,e=ye(e)&&e.prototype||nu,o=e===n,i=De(t),f=0<t,a=r.enumErrorProps&&(n===Qe||n instanceof qe),c=r.enumPrototypes&&ye(n);++u<t;)i[u]=u+"";
-for(var l in n)c&&"prototype"==l||a&&("message"==l||"name"==l)||f&&Ur(l,t)||"constructor"==l&&(o||!eu.call(n,l))||i.push(l);if(r.nonEnumShadows&&n!==nu)for(t=n===tu?G:n===Qe?q:ou.call(n),r=Nu[t]||Nu[Z],t==Z&&(e=nu),t=Wn.length;t--;)l=Wn[t],u=r[l],o&&u||(u?!eu.call(n,l):n[l]===e[l])||i.push(l);return i}function Ce(n){n=Dr(n);for(var t=-1,r=Ko(n),e=r.length,u=De(e);++t<e;){var o=r[t];u[t]=[o,n[o]]}return u}function Se(n){return Nt(n,Ko(n))}function Ue(n){return(n=u(n))&&n.replace(En,a).replace(bn,"");
-}function $e(n,t){var r="";if(n=u(n),t=+t,1>t||!n||!bu(t))return r;do t%2&&(r+=n),t=wu(t/2),n+=n;while(t);return r}function We(n,t,r){var e=n;return(n=u(n))?(r?$r(e,t,r):null==t)?n.slice(g(n),y(n)+1):(t+="",n.slice(o(n,t),i(n,t)+1)):n}function Fe(n,t,r){return r&&$r(n,t,r)&&(t=w),n=u(n),n.match(t||Un)||[]}function Le(n,t,r){return r&&$r(n,t,r)&&(t=w),h(n)?Te(n):it(n,t)}function Ne(n){return n}function Te(n){return At(ft(n,true))}function Pe(n,t,r){if(null==r){var e=de(t),u=e?Ko(t):w;((u=u&&u.length?dt(t,u):w)?u.length:e)||(u=false,
-r=t,t=n,n=this)}u||(u=dt(t,Ko(t)));var o=true,e=-1,i=ye(n),f=u.length;false===r?o=false:de(r)&&"chain"in r&&(o=r.chain);for(;++e<f;){r=u[e];var a=t[r];n[r]=a,i&&(n.prototype[r]=function(t){return function(){var r=this.__chain__;if(o||r){var e=n(this.__wrapped__);return(e.__actions__=qn(this.__actions__)).push({func:t,args:arguments,thisArg:n}),e.__chain__=r,e}return t.apply(n,Hn([this.value()],arguments))}}(a))}return n}function ze(){}function Be(n){return Wr(n)?Ot(n):It(n)}_=_?Jn.defaults(Yn.Object(),_,Jn.pick(Yn,$n)):Yn;
-var De=_.Array,Me=_.Date,qe=_.Error,Ke=_.Function,Ve=_.Math,Ze=_.Number,Ye=_.Object,Ge=_.RegExp,Je=_.String,Xe=_.TypeError,He=De.prototype,Qe=qe.prototype,nu=Ye.prototype,tu=Je.prototype,ru=Ke.prototype.toString,eu=nu.hasOwnProperty,uu=0,ou=nu.toString,iu=Yn._,fu=Ge("^"+ru.call(eu).replace(/[\\^$.*+?()[\]{}|]/g,"\\$&").replace(/hasOwnProperty|(function).*?(?=\\\()| for .+?(?=\\\])/g,"$1.*?")+"$"),au=_.ArrayBuffer,cu=_.clearTimeout,lu=_.parseFloat,su=Ve.pow,pu=nu.propertyIsEnumerable,hu=Or(_,"Set"),_u=_.setTimeout,vu=He.splice,gu=_.Uint8Array,yu=Or(_,"WeakMap"),du=Ve.ceil,mu=Or(Ye,"create"),wu=Ve.floor,xu=Or(De,"isArray"),bu=_.isFinite,Au=Or(Ye,"keys"),ju=Ve.max,ku=Ve.min,Ou=Or(Me,"now"),Iu=_.parseInt,Ru=Ve.random,Eu=Ze.NEGATIVE_INFINITY,Cu=Ze.POSITIVE_INFINITY,Su=4294967294,Uu=2147483647,$u=9007199254740991,Wu=yu&&new yu,Fu={},Lu={};
-Lu[X]=_.Float32Array,Lu[H]=_.Float64Array,Lu[Q]=_.Int8Array,Lu[nn]=_.Int16Array,Lu[tn]=_.Int32Array,Lu[rn]=gu,Lu[en]=_.Uint8ClampedArray,Lu[un]=_.Uint16Array,Lu[on]=_.Uint32Array;var Nu={};Nu[B]=Nu[M]=Nu[V]={constructor:true,toLocaleString:true,toString:true,valueOf:true},Nu[D]=Nu[G]={constructor:true,toString:true,valueOf:true},Nu[q]=Nu[K]=Nu[Y]={constructor:true,toString:true},Nu[Z]={constructor:true},Kn(Wn,function(n){for(var t in Nu)if(eu.call(Nu,t)){var r=Nu[t];r[n]=eu.call(r,n)}});var Tu=Nn.support={};!function(n){
-var t=function(){this.x=n},r={0:n,length:n},e=[];t.prototype={valueOf:n,y:n};for(var u in new t)e.push(u);Tu.enumErrorProps=pu.call(Qe,"message")||pu.call(Qe,"name"),Tu.enumPrototypes=pu.call(t,"prototype"),Tu.nonEnumShadows=!/valueOf/.test(e),Tu.ownLast="x"!=e[0],Tu.spliceObjects=(vu.call(r,0,1),!r[0]),Tu.unindexedChars="xx"!="x"[0]+Ye("x")[0]}(1,0),Nn.templateSettings={escape:_n,evaluate:vn,interpolate:gn,variable:"",imports:{_:Nn}};var Pu=function(){function n(){}return function(t){if(de(t)){n.prototype=t;
-var r=new n;n.prototype=w}return r||{}}}(),zu=Yt(gt),Bu=Yt(yt,true),Du=Gt(),Mu=Gt(true),qu=Wu?function(n,t){return Wu.set(n,t),n}:Ne,Ku=Wu?function(n){return Wu.get(n)}:ze,Vu=Ot("length"),Zu=function(){var n=0,t=0;return function(r,e){var u=wo(),o=W-(u-t);if(t=u,0<o){if(++n>=$)return r}else n=0;return qu(r,e)}}(),Yu=pe(function(n,t){return h(n)&&Sr(n)?ct(n,_t(t,false,true)):[]}),Gu=er(),Ju=er(true),Xu=pe(function(n){for(var t=n.length,e=t,u=De(l),o=jr(),i=o===r,f=[];e--;){var a=n[e]=Sr(a=n[e])?a:[];u[e]=i&&120<=a.length&&mu&&hu?new Dn(e&&a):null;
-}var i=n[0],c=-1,l=i?i.length:0,s=u[0];n:for(;++c<l;)if(a=i[c],0>(s?Mn(s,a):o(f,a,0))){for(e=t;--e;){var p=u[e];if(0>(p?Mn(p,a):o(n[e],a,0)))continue n}s&&s.push(a),f.push(a)}return f}),Hu=pe(function(t,r){r=_t(r);var e=ut(t,r);return Rt(t,r.sort(n)),e}),Qu=yr(),no=yr(true),to=pe(function(n){return Lt(_t(n,false,true))}),ro=pe(function(n,t){return Sr(n)?ct(n,t):[]}),eo=pe(Hr),uo=pe(function(n){var t=n.length,r=2<t?n[t-2]:w,e=1<t?n[t-1]:w;return 2<t&&typeof r=="function"?t-=2:(r=1<t&&typeof e=="function"?(--t,
-e):w,e=w),n.length=t,Qr(n,r,e)}),oo=pe(function(n){return n=_t(n),this.thru(function(t){t=Wo(t)?t:[Dr(t)];for(var r=n,e=-1,u=t.length,o=-1,i=r.length,f=De(u+i);++e<u;)f[e]=t[e];for(;++o<i;)f[e++]=r[o];return f})}),io=pe(function(n,t){return Sr(n)&&(n=Br(n)),ut(n,_t(t))}),fo=Vt(function(n,t,r){eu.call(n,r)?++n[r]:n[r]=1}),ao=rr(zu),co=rr(Bu,true),lo=ir(Kn,zu),so=ir(function(n,t){for(var r=n.length;r--&&false!==t(n[r],r,n););return n},Bu),po=Vt(function(n,t,r){eu.call(n,r)?n[r].push(t):n[r]=[t]}),ho=Vt(function(n,t,r){
-n[r]=t}),_o=pe(function(n,t,r){var e=-1,u=typeof t=="function",o=Wr(t),i=Sr(n)?De(n.length):[];return zu(n,function(n){var f=u?t:o&&null!=n?n[t]:w;i[++e]=f?f.apply(n,r):Cr(n,t,r)}),i}),vo=Vt(function(n,t,r){n[r?0:1].push(t)},function(){return[[],[]]}),go=pr(Qn,zu),yo=pr(function(n,t,r,e){var u=n.length;for(e&&u&&(r=n[--u]);u--;)r=t(r,n[u],u,n);return r},Bu),mo=pe(function(n,t){if(null==n)return[];var r=t[2];return r&&$r(t[0],t[1],r)&&(t.length=1),Wt(n,_t(t),[])}),wo=Ou||function(){return(new Me).getTime();
-},xo=pe(function(n,t,r){var e=b;if(r.length)var u=v(r,xo.placeholder),e=e|I;return dr(n,e,t,r,u)}),bo=pe(function(n,t){t=t.length?_t(t):Re(n);for(var r=-1,e=t.length;++r<e;){var u=t[r];n[u]=dr(n[u],b,n)}return n}),Ao=pe(function(n,t,r){var e=b|A;if(r.length)var u=v(r,Ao.placeholder),e=e|I;return dr(t,e,n,r,u)}),jo=Qt(k),ko=Qt(O),Oo=pe(function(n,t){return at(n,1,t)}),Io=pe(function(n,t,r){return at(n,t,r)}),Ro=or(),Eo=or(true),Co=pe(function(n,t){if(t=_t(t),typeof n!="function"||!Vn(t,e))throw new Xe(T);
-var r=t.length;return pe(function(e){for(var u=ku(e.length,r);u--;)e[u]=t[u](e[u]);return n.apply(this,e)})}),So=sr(I),Uo=sr(R),$o=pe(function(n,t){return dr(n,C,w,w,w,_t(t))}),Wo=xu||function(n){return h(n)&&Lr(n.length)&&ou.call(n)==B},Fo=Zt(kt),Lo=Zt(function(n,t,r){return r?rt(n,t,r):et(n,t)}),No=nr(Lo,function(n,t){return n===w?t:n}),To=nr(Fo,Nr),Po=ur(gt),zo=ur(yt),Bo=fr(Du),Do=fr(Mu),Mo=ar(gt),qo=ar(yt),Ko=Au?function(n){var t=null==n?w:n.constructor;return typeof t=="function"&&t.prototype===n||(typeof n=="function"?Nn.support.enumPrototypes:Sr(n))?zr(n):de(n)?Au(n):[];
-}:zr,Vo=cr(true),Zo=cr(),Yo=pe(function(n,t){if(null==n)return{};if("function"!=typeof t[0])return t=Xn(_t(t),Je),Tr(n,ct(Ee(n),t));var r=Dt(t[0],t[1],3);return Pr(n,function(n,t,e){return!r(n,t,e)})}),Go=pe(function(n,t){return null==n?{}:"function"==typeof t[0]?Pr(n,Dt(t[0],t[1],3)):Tr(n,_t(t))}),Jo=Xt(function(n,t,r){return t=t.toLowerCase(),n+(r?t.charAt(0).toUpperCase()+t.slice(1):t)}),Xo=Xt(function(n,t,r){return n+(r?"-":"")+t.toLowerCase()}),Ho=lr(),Qo=lr(true),ni=Xt(function(n,t,r){return n+(r?"_":"")+t.toLowerCase();
-}),ti=Xt(function(n,t,r){return n+(r?" ":"")+(t.charAt(0).toUpperCase()+t.slice(1))}),ri=pe(function(n,t){try{return n.apply(w,t)}catch(r){return ge(r)?r:new qe(r)}}),ei=pe(function(n,t){return function(r){return Cr(r,n,t)}}),ui=pe(function(n,t){return function(r){return Cr(n,r,t)}}),oi=gr("ceil"),ii=gr("floor"),fi=tr(he,Eu),ai=tr(ke,Cu),ci=gr("round");return Nn.prototype=Tn.prototype,Pn.prototype=Pu(Tn.prototype),Pn.prototype.constructor=Pn,zn.prototype=Pu(Tn.prototype),zn.prototype.constructor=zn,
-Bn.prototype["delete"]=function(n){return this.has(n)&&delete this.__data__[n]},Bn.prototype.get=function(n){return"__proto__"==n?w:this.__data__[n]},Bn.prototype.has=function(n){return"__proto__"!=n&&eu.call(this.__data__,n)},Bn.prototype.set=function(n,t){return"__proto__"!=n&&(this.__data__[n]=t),this},Dn.prototype.push=function(n){var t=this.data;typeof n=="string"||de(n)?t.set.add(n):t.hash[n]=true},se.Cache=Bn,Nn.after=function(n,t){if(typeof t!="function"){if(typeof n!="function")throw new Xe(T);
-var r=n;n=t,t=r}return n=bu(n=+n)?n:0,function(){return 1>--n?t.apply(this,arguments):void 0}},Nn.ary=function(n,t,r){return r&&$r(n,t,r)&&(t=w),t=n&&null==t?n.length:ju(+t||0,0),dr(n,E,w,w,w,w,t)},Nn.assign=Lo,Nn.at=io,Nn.before=ce,Nn.bind=xo,Nn.bindAll=bo,Nn.bindKey=Ao,Nn.callback=Le,Nn.chain=te,Nn.chunk=function(n,t,r){t=(r?$r(n,t,r):null==t)?1:ju(wu(t)||1,1),r=0;for(var e=n?n.length:0,u=-1,o=De(du(e/t));r<e;)o[++u]=St(n,r,r+=t);return o},Nn.compact=function(n){for(var t=-1,r=n?n.length:0,e=-1,u=[];++t<r;){
-var o=n[t];o&&(u[++e]=o)}return u},Nn.constant=function(n){return function(){return n}},Nn.countBy=fo,Nn.create=function(n,t,r){var e=Pu(n);return r&&$r(n,t,r)&&(t=w),t?et(e,t):e},Nn.curry=jo,Nn.curryRight=ko,Nn.debounce=le,Nn.defaults=No,Nn.defaultsDeep=To,Nn.defer=Oo,Nn.delay=Io,Nn.difference=Yu,Nn.drop=Kr,Nn.dropRight=Vr,Nn.dropRightWhile=function(n,t,r){return n&&n.length?Tt(n,br(t,r,3),true,true):[]},Nn.dropWhile=function(n,t,r){return n&&n.length?Tt(n,br(t,r,3),true):[]},Nn.fill=function(n,t,r,e){
-var u=n?n.length:0;if(!u)return[];for(r&&typeof r!="number"&&$r(n,t,r)&&(r=0,e=u),u=n.length,r=null==r?0:+r||0,0>r&&(r=-r>u?0:u+r),e=e===w||e>u?u:+e||0,0>e&&(e+=u),u=r>e?0:e>>>0,r>>>=0;r<u;)n[r++]=t;return n},Nn.filter=ue,Nn.flatten=function(n,t,r){var e=n?n.length:0;return r&&$r(n,t,r)&&(t=false),e?_t(n,t):[]},Nn.flattenDeep=function(n){return n&&n.length?_t(n,true):[]},Nn.flow=Ro,Nn.flowRight=Eo,Nn.forEach=lo,Nn.forEachRight=so,Nn.forIn=Bo,Nn.forInRight=Do,Nn.forOwn=Mo,Nn.forOwnRight=qo,Nn.functions=Re,
-Nn.groupBy=po,Nn.indexBy=ho,Nn.initial=function(n){return Vr(n,1)},Nn.intersection=Xu,Nn.invert=function(n,t,r){r&&$r(n,t,r)&&(t=w),r=-1;for(var e=Ko(n),u=e.length,o={};++r<u;){var i=e[r],f=n[i];t?eu.call(o,f)?o[f].push(i):o[f]=[i]:o[f]=i}return o},Nn.invoke=_o,Nn.keys=Ko,Nn.keysIn=Ee,Nn.map=ie,Nn.mapKeys=Vo,Nn.mapValues=Zo,Nn.matches=Te,Nn.matchesProperty=function(n,t){return jt(n,ft(t,true))},Nn.memoize=se,Nn.merge=Fo,Nn.method=ei,Nn.methodOf=ui,Nn.mixin=Pe,Nn.modArgs=Co,Nn.negate=function(n){if(typeof n!="function")throw new Xe(T);
-return function(){return!n.apply(this,arguments)}},Nn.omit=Yo,Nn.once=function(n){return ce(2,n)},Nn.pairs=Ce,Nn.partial=So,Nn.partialRight=Uo,Nn.partition=vo,Nn.pick=Go,Nn.pluck=function(n,t){return ie(n,Be(t))},Nn.property=Be,Nn.propertyOf=function(n){return function(t){return mt(n,Mr(t),t+"")}},Nn.pull=function(){var n=arguments,t=n[0];if(!t||!t.length)return t;for(var r=0,e=jr(),u=n.length;++r<u;)for(var o=0,i=n[r];-1<(o=e(t,i,o));)vu.call(t,o,1);return t},Nn.pullAt=Hu,Nn.range=function(n,t,r){
-r&&$r(n,t,r)&&(t=r=w),n=+n||0,r=null==r?1:+r||0,null==t?(t=n,n=0):t=+t||0;var e=-1;t=ju(du((t-n)/(r||1)),0);for(var u=De(t);++e<t;)u[e]=n,n+=r;return u},Nn.rearg=$o,Nn.reject=function(n,t,r){var e=Wo(n)?Zn:pt;return t=br(t,r,3),e(n,function(n,r,e){return!t(n,r,e)})},Nn.remove=function(n,t,r){var e=[];if(!n||!n.length)return e;var u=-1,o=[],i=n.length;for(t=br(t,r,3);++u<i;)r=n[u],t(r,u,n)&&(e.push(r),o.push(u));return Rt(n,o),e},Nn.rest=Jr,Nn.restParam=pe,Nn.set=function(n,t,r){if(null==n)return n;
-var e=t+"";t=null!=n[e]||Wr(t,n)?[e]:Mr(t);for(var e=-1,u=t.length,o=u-1,i=n;null!=i&&++e<u;){var f=t[e];de(i)&&(e==o?i[f]=r:null==i[f]&&(i[f]=Ur(t[e+1])?[]:{})),i=i[f]}return n},Nn.shuffle=function(n){return fe(n,Cu)},Nn.slice=function(n,t,r){var e=n?n.length:0;return e?(r&&typeof r!="number"&&$r(n,t,r)&&(t=0,r=e),St(n,t,r)):[]},Nn.sortBy=function(n,t,r){if(null==n)return[];r&&$r(n,t,r)&&(t=w);var e=-1;return t=br(t,r,3),n=bt(n,function(n,r,u){return{a:t(n,r,u),b:++e,c:n}}),$t(n,f)},Nn.sortByAll=mo,
-Nn.sortByOrder=function(n,t,r,e){return null==n?[]:(e&&$r(t,r,e)&&(r=w),Wo(t)||(t=null==t?[]:[t]),Wo(r)||(r=null==r?[]:[r]),Wt(n,t,r))},Nn.spread=function(n){if(typeof n!="function")throw new Xe(T);return function(t){return n.apply(this,t)}},Nn.take=function(n,t,r){return n&&n.length?((r?$r(n,t,r):null==t)&&(t=1),St(n,0,0>t?0:t)):[]},Nn.takeRight=function(n,t,r){var e=n?n.length:0;return e?((r?$r(n,t,r):null==t)&&(t=1),t=e-(+t||0),St(n,0>t?0:t)):[]},Nn.takeRightWhile=function(n,t,r){return n&&n.length?Tt(n,br(t,r,3),false,true):[];
-},Nn.takeWhile=function(n,t,r){return n&&n.length?Tt(n,br(t,r,3)):[]},Nn.tap=function(n,t,r){return t.call(r,n),n},Nn.throttle=function(n,t,r){var e=true,u=true;if(typeof n!="function")throw new Xe(T);return false===r?e=false:de(r)&&(e="leading"in r?!!r.leading:e,u="trailing"in r?!!r.trailing:u),le(n,t,{leading:e,maxWait:+t,trailing:u})},Nn.thru=re,Nn.times=function(n,t,r){if(n=wu(n),1>n||!bu(n))return[];var e=-1,u=De(ku(n,4294967295));for(t=Dt(t,r,1);++e<n;)4294967295>e?u[e]=t(e):t(e);return u},Nn.toArray=Oe,
-Nn.toPlainObject=Ie,Nn.transform=function(n,t,r,e){var u=Wo(n)||je(n);return t=br(t,e,4),null==r&&(u||de(n)?(e=n.constructor,r=u?Wo(n)?new e:[]:Pu(ye(e)?e.prototype:w)):r={}),(u?Kn:gt)(n,function(n,e,u){return t(r,n,e,u)}),r},Nn.union=to,Nn.uniq=Xr,Nn.unzip=Hr,Nn.unzipWith=Qr,Nn.values=Se,Nn.valuesIn=function(n){return Nt(n,Ee(n))},Nn.where=function(n,t){return ue(n,At(t))},Nn.without=ro,Nn.wrap=function(n,t){return t=null==t?Ne:t,dr(t,I,w,[n],[])},Nn.xor=function(){for(var n=-1,t=arguments.length;++n<t;){
-var r=arguments[n];if(Sr(r))var e=e?Hn(ct(e,r),ct(r,e)):r}return e?Lt(e):[]},Nn.zip=eo,Nn.zipObject=ne,Nn.zipWith=uo,Nn.backflow=Eo,Nn.collect=ie,Nn.compose=Eo,Nn.each=lo,Nn.eachRight=so,Nn.extend=Lo,Nn.iteratee=Le,Nn.methods=Re,Nn.object=ne,Nn.select=ue,Nn.tail=Jr,Nn.unique=Xr,Pe(Nn,Nn),Nn.add=function(n,t){return(+n||0)+(+t||0)},Nn.attempt=ri,Nn.camelCase=Jo,Nn.capitalize=function(n){return(n=u(n))&&n.charAt(0).toUpperCase()+n.slice(1)},Nn.ceil=oi,Nn.clone=function(n,t,r,e){return t&&typeof t!="boolean"&&$r(n,t,r)?t=false:typeof t=="function"&&(e=r,
-r=t,t=false),typeof r=="function"?ft(n,t,Dt(r,e,3)):ft(n,t)},Nn.cloneDeep=function(n,t,r){return typeof t=="function"?ft(n,true,Dt(t,r,3)):ft(n,true)},Nn.deburr=Ue,Nn.endsWith=function(n,t,r){n=u(n),t+="";var e=n.length;return r=r===w?e:ku(0>r?0:+r||0,e),r-=t.length,0<=r&&n.indexOf(t,r)==r},Nn.escape=function(n){return(n=u(n))&&hn.test(n)?n.replace(sn,c):n},Nn.escapeRegExp=function(n){return(n=u(n))&&xn.test(n)?n.replace(wn,l):n||"(?:)"},Nn.every=ee,Nn.find=ao,Nn.findIndex=Gu,Nn.findKey=Po,Nn.findLast=co,
-Nn.findLastIndex=Ju,Nn.findLastKey=zo,Nn.findWhere=function(n,t){return ao(n,At(t))},Nn.first=Zr,Nn.floor=ii,Nn.get=function(n,t,r){return n=null==n?w:mt(n,Mr(t),t+""),n===w?r:n},Nn.gt=he,Nn.gte=function(n,t){return n>=t},Nn.has=function(n,t){if(null==n)return false;var r=eu.call(n,t);if(!r&&!Wr(t)){if(t=Mr(t),n=1==t.length?n:mt(n,St(t,0,-1)),null==n)return false;t=Gr(t),r=eu.call(n,t)}return r||Lr(n.length)&&Ur(t,n.length)&&(Wo(n)||_e(n)||Ae(n))},Nn.identity=Ne,Nn.includes=oe,Nn.indexOf=Yr,Nn.inRange=function(n,t,r){
-return t=+t||0,r===w?(r=t,t=0):r=+r||0,n>=ku(t,r)&&n<ju(t,r)},Nn.isArguments=_e,Nn.isArray=Wo,Nn.isBoolean=function(n){return true===n||false===n||h(n)&&ou.call(n)==D},Nn.isDate=function(n){return h(n)&&ou.call(n)==M},Nn.isElement=function(n){return!!n&&1===n.nodeType&&h(n)&&!xe(n)},Nn.isEmpty=function(n){return null==n?true:Sr(n)&&(Wo(n)||Ae(n)||_e(n)||h(n)&&ye(n.splice))?!n.length:!Ko(n).length},Nn.isEqual=ve,Nn.isError=ge,Nn.isFinite=function(n){return typeof n=="number"&&bu(n)},Nn.isFunction=ye,Nn.isMatch=function(n,t,r,e){
-return r=typeof r=="function"?Dt(r,e,3):w,xt(n,kr(t),r)},Nn.isNaN=function(n){return we(n)&&n!=+n},Nn.isNative=me,Nn.isNull=function(n){return null===n},Nn.isNumber=we,Nn.isObject=de,Nn.isPlainObject=xe,Nn.isRegExp=be,Nn.isString=Ae,Nn.isTypedArray=je,Nn.isUndefined=function(n){return n===w},Nn.kebabCase=Xo,Nn.last=Gr,Nn.lastIndexOf=function(n,t,r){var e=n?n.length:0;if(!e)return-1;var u=e;if(typeof r=="number")u=(0>r?ju(e+r,0):ku(r||0,e-1))+1;else if(r)return u=zt(n,t,true)-1,n=n[u],(t===t?t===n:n!==n)?u:-1;
-if(t!==t)return p(n,u,true);for(;u--;)if(n[u]===t)return u;return-1},Nn.lt=ke,Nn.lte=function(n,t){return n<=t},Nn.max=fi,Nn.min=ai,Nn.noConflict=function(){return Yn._=iu,this},Nn.noop=ze,Nn.now=wo,Nn.pad=function(n,t,r){n=u(n),t=+t;var e=n.length;return e<t&&bu(t)?(e=(t-e)/2,t=wu(e),e=du(e),r=_r("",e,r),r.slice(0,t)+n+r):n},Nn.padLeft=Ho,Nn.padRight=Qo,Nn.parseInt=function(n,t,r){return(r?$r(n,t,r):null==t)?t=0:t&&(t=+t),n=We(n),Iu(n,t||(On.test(n)?16:10))},Nn.random=function(n,t,r){r&&$r(n,t,r)&&(t=r=w);
-var e=null==n,u=null==t;return null==r&&(u&&typeof n=="boolean"?(r=n,n=1):typeof t=="boolean"&&(r=t,u=true)),e&&u&&(t=1,u=false),n=+n||0,u?(t=n,n=0):t=+t||0,r||n%1||t%1?(r=Ru(),ku(n+r*(t-n+lu("1e-"+((r+"").length-1))),t)):Et(n,t)},Nn.reduce=go,Nn.reduceRight=yo,Nn.repeat=$e,Nn.result=function(n,t,r){var e=null==n?w:Dr(n)[t];return e===w&&(null==n||Wr(t,n)||(t=Mr(t),n=1==t.length?n:mt(n,St(t,0,-1)),e=null==n?w:Dr(n)[Gr(t)]),e=e===w?r:e),ye(e)?e.call(n):e},Nn.round=ci,Nn.runInContext=m,Nn.size=function(n){
-var t=n?Vu(n):0;return Lr(t)?t:Ko(n).length},Nn.snakeCase=ni,Nn.some=ae,Nn.sortedIndex=Qu,Nn.sortedLastIndex=no,Nn.startCase=ti,Nn.startsWith=function(n,t,r){return n=u(n),r=null==r?0:ku(0>r?0:+r||0,n.length),n.lastIndexOf(t,r)==r},Nn.sum=function(n,t,r){if(r&&$r(n,t,r)&&(t=w),t=br(t,r,3),1==t.length){n=Wo(n)?n:Br(n),r=n.length;for(var e=0;r--;)e+=+t(n[r])||0;n=e}else n=Ft(n,t);return n},Nn.template=function(n,t,r){var e=Nn.templateSettings;r&&$r(n,t,r)&&(t=r=w),n=u(n),t=rt(et({},r||t),e,tt),r=rt(et({},t.imports),e.imports,tt);
-var o,i,f=Ko(r),a=Nt(r,f),c=0;r=t.interpolate||Cn;var l="__p+='";r=Ge((t.escape||Cn).source+"|"+r.source+"|"+(r===gn?jn:Cn).source+"|"+(t.evaluate||Cn).source+"|$","g");var p="sourceURL"in t?"//# sourceURL="+t.sourceURL+"\n":"";if(n.replace(r,function(t,r,e,u,f,a){return e||(e=u),l+=n.slice(c,a).replace(Sn,s),r&&(o=true,l+="'+__e("+r+")+'"),f&&(i=true,l+="';"+f+";\n__p+='"),e&&(l+="'+((__t=("+e+"))==null?'':__t)+'"),c=a+t.length,t}),l+="';",(t=t.variable)||(l="with(obj){"+l+"}"),l=(i?l.replace(fn,""):l).replace(an,"$1").replace(cn,"$1;"),
-l="function("+(t||"obj")+"){"+(t?"":"obj||(obj={});")+"var __t,__p=''"+(o?",__e=_.escape":"")+(i?",__j=Array.prototype.join;function print(){__p+=__j.call(arguments,'')}":";")+l+"return __p}",t=ri(function(){return Ke(f,p+"return "+l).apply(w,a)}),t.source=l,ge(t))throw t;return t},Nn.trim=We,Nn.trimLeft=function(n,t,r){var e=n;return(n=u(n))?n.slice((r?$r(e,t,r):null==t)?g(n):o(n,t+"")):n},Nn.trimRight=function(n,t,r){var e=n;return(n=u(n))?(r?$r(e,t,r):null==t)?n.slice(0,y(n)+1):n.slice(0,i(n,t+"")+1):n;
-},Nn.trunc=function(n,t,r){r&&$r(n,t,r)&&(t=w);var e=S;if(r=U,null!=t)if(de(t)){var o="separator"in t?t.separator:o,e="length"in t?+t.length||0:e;r="omission"in t?u(t.omission):r}else e=+t||0;if(n=u(n),e>=n.length)return n;if(e-=r.length,1>e)return r;if(t=n.slice(0,e),null==o)return t+r;if(be(o)){if(n.slice(e).search(o)){var i,f=n.slice(0,e);for(o.global||(o=Ge(o.source,(kn.exec(o)||"")+"g")),o.lastIndex=0;n=o.exec(f);)i=n.index;t=t.slice(0,null==i?e:i)}}else n.indexOf(o,e)!=e&&(o=t.lastIndexOf(o),
--1<o&&(t=t.slice(0,o)));return t+r},Nn.unescape=function(n){return(n=u(n))&&pn.test(n)?n.replace(ln,d):n},Nn.uniqueId=function(n){var t=++uu;return u(n)+t},Nn.words=Fe,Nn.all=ee,Nn.any=ae,Nn.contains=oe,Nn.eq=ve,Nn.detect=ao,Nn.foldl=go,Nn.foldr=yo,Nn.head=Zr,Nn.include=oe,Nn.inject=go,Pe(Nn,function(){var n={};return gt(Nn,function(t,r){Nn.prototype[r]||(n[r]=t)}),n}(),false),Nn.sample=fe,Nn.prototype.sample=function(n){return this.__chain__||null!=n?this.thru(function(t){return fe(t,n)}):fe(this.value());
-},Nn.VERSION=x,Kn("bind bindKey curry curryRight partial partialRight".split(" "),function(n){Nn[n].placeholder=Nn}),Kn(["drop","take"],function(n,t){zn.prototype[n]=function(r){var e=this.__filtered__;if(e&&!t)return new zn(this);r=null==r?1:ju(wu(r)||0,0);var u=this.clone();return e?u.__takeCount__=ku(u.__takeCount__,r):u.__views__.push({size:r,type:n+(0>u.__dir__?"Right":"")}),u},zn.prototype[n+"Right"]=function(t){return this.reverse()[n](t).reverse()}}),Kn(["filter","map","takeWhile"],function(n,t){
-var r=t+1,e=r!=N;zn.prototype[n]=function(n,t){var u=this.clone();return u.__iteratees__.push({iteratee:br(n,t,1),type:r}),u.__filtered__=u.__filtered__||e,u}}),Kn(["first","last"],function(n,t){var r="take"+(t?"Right":"");zn.prototype[n]=function(){return this[r](1).value()[0]}}),Kn(["initial","rest"],function(n,t){var r="drop"+(t?"":"Right");zn.prototype[n]=function(){return this.__filtered__?new zn(this):this[r](1)}}),Kn(["pluck","where"],function(n,t){var r=t?"filter":"map",e=t?At:Be;zn.prototype[n]=function(n){
-return this[r](e(n))}}),zn.prototype.compact=function(){return this.filter(Ne)},zn.prototype.reject=function(n,t){return n=br(n,t,1),this.filter(function(t){return!n(t)})},zn.prototype.slice=function(n,t){n=null==n?0:+n||0;var r=this;return r.__filtered__&&(0<n||0>t)?new zn(r):(0>n?r=r.takeRight(-n):n&&(r=r.drop(n)),t!==w&&(t=+t||0,r=0>t?r.dropRight(-t):r.take(t-n)),r)},zn.prototype.takeRightWhile=function(n,t){return this.reverse().takeWhile(n,t).reverse()},zn.prototype.toArray=function(){return this.take(Cu);
-},gt(zn.prototype,function(n,t){var r=/^(?:filter|map|reject)|While$/.test(t),e=/^(?:first|last)$/.test(t),u=Nn[e?"take"+("last"==t?"Right":""):t];u&&(Nn.prototype[t]=function(){var t=e?[1]:arguments,o=this.__chain__,i=this.__wrapped__,f=!!this.__actions__.length,a=i instanceof zn,c=t[0],l=a||Wo(i);l&&r&&typeof c=="function"&&1!=c.length&&(a=l=false);var s=function(n){return e&&o?u(n,1)[0]:u.apply(w,Hn([n],t))},c={func:re,args:[s],thisArg:w},f=a&&!f;return e&&!o?f?(i=i.clone(),i.__actions__.push(c),
-n.call(i)):u.call(w,this.value())[0]:!e&&l?(i=f?i:new zn(this),i=n.apply(i,t),i.__actions__.push(c),new Pn(i,o)):this.thru(s)})}),Kn("join pop push replace shift sort splice split unshift".split(" "),function(n){var t=(/^(?:replace|split)$/.test(n)?tu:He)[n],r=/^(?:push|sort|unshift)$/.test(n)?"tap":"thru",e=!Tu.spliceObjects&&/^(?:pop|shift|splice)$/.test(n),u=/^(?:join|pop|replace|shift)$/.test(n),o=e?function(){var n=t.apply(this,arguments);return 0===this.length&&delete this[0],n}:t;Nn.prototype[n]=function(){
-var n=arguments;return u&&!this.__chain__?o.apply(this.value(),n):this[r](function(t){return o.apply(t,n)})}}),gt(zn.prototype,function(n,t){var r=Nn[t];if(r){var e=r.name+"";(Fu[e]||(Fu[e]=[])).push({name:t,func:r})}}),Fu[hr(w,A).name]=[{name:"wrapper",func:w}],zn.prototype.clone=function(){var n=new zn(this.__wrapped__);return n.__actions__=qn(this.__actions__),n.__dir__=this.__dir__,n.__filtered__=this.__filtered__,n.__iteratees__=qn(this.__iteratees__),n.__takeCount__=this.__takeCount__,n.__views__=qn(this.__views__),
-n},zn.prototype.reverse=function(){if(this.__filtered__){var n=new zn(this);n.__dir__=-1,n.__filtered__=true}else n=this.clone(),n.__dir__*=-1;return n},zn.prototype.value=function(){var n,t=this.__wrapped__.value(),r=this.__dir__,e=Wo(t),u=0>r,o=e?t.length:0;n=0;for(var i=o,f=this.__views__,a=-1,c=f.length;++a<c;){var l=f[a],s=l.size;switch(l.type){case"drop":n+=s;break;case"dropRight":i-=s;break;case"take":i=ku(i,n+s);break;case"takeRight":n=ju(n,i-s)}}if(n={start:n,end:i},i=n.start,f=n.end,n=f-i,
-u=u?f:i-1,i=this.__iteratees__,f=i.length,a=0,c=ku(n,this.__takeCount__),!e||o<F||o==n&&c==n)return Pt(t,this.__actions__);e=[];n:for(;n--&&a<c;){for(u+=r,o=-1,l=t[u];++o<f;){var p=i[o],s=p.type,p=p.iteratee(l);if(s==N)l=p;else if(!p){if(s==L)continue n;break n}}e[a++]=l}return e},Nn.prototype.chain=function(){return te(this)},Nn.prototype.commit=function(){return new Pn(this.value(),this.__chain__)},Nn.prototype.concat=oo,Nn.prototype.plant=function(n){for(var t,r=this;r instanceof Tn;){var e=qr(r);
-t?u.__wrapped__=e:t=e;var u=e,r=r.__wrapped__}return u.__wrapped__=n,t},Nn.prototype.reverse=function(){var n=this.__wrapped__,t=function(n){return n.reverse()};return n instanceof zn?(this.__actions__.length&&(n=new zn(this)),n=n.reverse(),n.__actions__.push({func:re,args:[t],thisArg:w}),new Pn(n,this.__chain__)):this.thru(t)},Nn.prototype.toString=function(){return this.value()+""},Nn.prototype.run=Nn.prototype.toJSON=Nn.prototype.valueOf=Nn.prototype.value=function(){return Pt(this.__wrapped__,this.__actions__);
-},Nn.prototype.collect=Nn.prototype.map,Nn.prototype.head=Nn.prototype.first,Nn.prototype.select=Nn.prototype.filter,Nn.prototype.tail=Nn.prototype.rest,Nn}var w,x="3.10.1",b=1,A=2,j=4,k=8,O=16,I=32,R=64,E=128,C=256,S=30,U="...",$=150,W=16,F=200,L=1,N=2,T="Expected a function",P="__lodash_placeholder__",z="[object Arguments]",B="[object Array]",D="[object Boolean]",M="[object Date]",q="[object Error]",K="[object Function]",V="[object Number]",Z="[object Object]",Y="[object RegExp]",G="[object String]",J="[object ArrayBuffer]",X="[object Float32Array]",H="[object Float64Array]",Q="[object Int8Array]",nn="[object Int16Array]",tn="[object Int32Array]",rn="[object Uint8Array]",en="[object Uint8ClampedArray]",un="[object Uint16Array]",on="[object Uint32Array]",fn=/\b__p\+='';/g,an=/\b(__p\+=)''\+/g,cn=/(__e\(.*?\)|\b__t\))\+'';/g,ln=/&(?:amp|lt|gt|quot|#39|#96);/g,sn=/[&<>"'`]/g,pn=RegExp(ln.source),hn=RegExp(sn.source),_n=/<%-([\s\S]+?)%>/g,vn=/<%([\s\S]+?)%>/g,gn=/<%=([\s\S]+?)%>/g,yn=/\.|\[(?:[^[\]]*|(["'])(?:(?!\1)[^\n\\]|\\.)*?\1)\]/,dn=/^\w*$/,mn=/[^.[\]]+|\[(?:(-?\d+(?:\.\d+)?)|(["'])((?:(?!\2)[^\n\\]|\\.)*?)\2)\]/g,wn=/^[:!,]|[\\^$.*+?()[\]{}|\/]|(^[0-9a-fA-Fnrtuvx])|([\n\r\u2028\u2029])/g,xn=RegExp(wn.source),bn=/[\u0300-\u036f\ufe20-\ufe23]/g,An=/\\(\\)?/g,jn=/\$\{([^\\}]*(?:\\.[^\\}]*)*)\}/g,kn=/\w*$/,On=/^0[xX]/,In=/^\[object .+?Constructor\]$/,Rn=/^\d+$/,En=/[\xc0-\xd6\xd8-\xde\xdf-\xf6\xf8-\xff]/g,Cn=/($^)/,Sn=/['\n\r\u2028\u2029\\]/g,Un=RegExp("[A-Z\\xc0-\\xd6\\xd8-\\xde]+(?=[A-Z\\xc0-\\xd6\\xd8-\\xde][a-z\\xdf-\\xf6\\xf8-\\xff]+)|[A-Z\\xc0-\\xd6\\xd8-\\xde]?[a-z\\xdf-\\xf6\\xf8-\\xff]+|[A-Z\\xc0-\\xd6\\xd8-\\xde]+|[0-9]+","g"),$n="Array ArrayBuffer Date Error Float32Array Float64Array Function Int8Array Int16Array Int32Array Math Number Object RegExp Set String _ clearTimeout isFinite parseFloat parseInt setTimeout TypeError Uint8Array Uint8ClampedArray Uint16Array Uint32Array WeakMap".split(" "),Wn="constructor hasOwnProperty isPrototypeOf propertyIsEnumerable toLocaleString toString valueOf".split(" "),Fn={};
-Fn[X]=Fn[H]=Fn[Q]=Fn[nn]=Fn[tn]=Fn[rn]=Fn[en]=Fn[un]=Fn[on]=true,Fn[z]=Fn[B]=Fn[J]=Fn[D]=Fn[M]=Fn[q]=Fn[K]=Fn["[object Map]"]=Fn[V]=Fn[Z]=Fn[Y]=Fn["[object Set]"]=Fn[G]=Fn["[object WeakMap]"]=false;var Ln={};Ln[z]=Ln[B]=Ln[J]=Ln[D]=Ln[M]=Ln[X]=Ln[H]=Ln[Q]=Ln[nn]=Ln[tn]=Ln[V]=Ln[Z]=Ln[Y]=Ln[G]=Ln[rn]=Ln[en]=Ln[un]=Ln[on]=true,Ln[q]=Ln[K]=Ln["[object Map]"]=Ln["[object Set]"]=Ln["[object WeakMap]"]=false;var Nn={"\xc0":"A","\xc1":"A","\xc2":"A","\xc3":"A","\xc4":"A","\xc5":"A","\xe0":"a","\xe1":"a","\xe2":"a",
-"\xe3":"a","\xe4":"a","\xe5":"a","\xc7":"C","\xe7":"c","\xd0":"D","\xf0":"d","\xc8":"E","\xc9":"E","\xca":"E","\xcb":"E","\xe8":"e","\xe9":"e","\xea":"e","\xeb":"e","\xcc":"I","\xcd":"I","\xce":"I","\xcf":"I","\xec":"i","\xed":"i","\xee":"i","\xef":"i","\xd1":"N","\xf1":"n","\xd2":"O","\xd3":"O","\xd4":"O","\xd5":"O","\xd6":"O","\xd8":"O","\xf2":"o","\xf3":"o","\xf4":"o","\xf5":"o","\xf6":"o","\xf8":"o","\xd9":"U","\xda":"U","\xdb":"U","\xdc":"U","\xf9":"u","\xfa":"u","\xfb":"u","\xfc":"u","\xdd":"Y",
-"\xfd":"y","\xff":"y","\xc6":"Ae","\xe6":"ae","\xde":"Th","\xfe":"th","\xdf":"ss"},Tn={"&":"&amp;","<":"&lt;",">":"&gt;",'"':"&quot;","'":"&#39;","`":"&#96;"},Pn={"&amp;":"&","&lt;":"<","&gt;":">","&quot;":'"',"&#39;":"'","&#96;":"`"},zn={"function":true,object:true},Bn={0:"x30",1:"x31",2:"x32",3:"x33",4:"x34",5:"x35",6:"x36",7:"x37",8:"x38",9:"x39",A:"x41",B:"x42",C:"x43",D:"x44",E:"x45",F:"x46",a:"x61",b:"x62",c:"x63",d:"x64",e:"x65",f:"x66",n:"x6e",r:"x72",t:"x74",u:"x75",v:"x76",x:"x78"},Dn={"\\":"\\",
-"'":"'","\n":"n","\r":"r","\u2028":"u2028","\u2029":"u2029"},Mn=zn[typeof exports]&&exports&&!exports.nodeType&&exports,qn=zn[typeof module]&&module&&!module.nodeType&&module,Kn=zn[typeof self]&&self&&self.Object&&self,Vn=zn[typeof window]&&window&&window.Object&&window,Zn=qn&&qn.exports===Mn&&Mn,Yn=Mn&&qn&&typeof global=="object"&&global&&global.Object&&global||Vn!==(this&&this.window)&&Vn||Kn||this,Gn=function(){try{Object({toString:0}+"")}catch(n){return function(){return false}}return function(n){
-return typeof n.toString!="function"&&typeof(n+"")=="string"}}(),Jn=m();typeof define=="function"&&typeof define.amd=="object"&&define.amd?(Yn._=Jn, define(function(){return Jn})):Mn&&qn?Zn?(qn.exports=Jn)._=Jn:Mn._=Jn:Yn._=Jn}).call(this); \ No newline at end of file
+/**
+ * @license
+ * lodash 3.10.1 (Custom Build) lodash.com/license | Underscore.js 1.8.3 underscorejs.org/LICENSE
+ * Build: `lodash compat -o ./lodash.js`
+ */
+;(function(){function n(n,t){if(n!==t){var r=null===n,e=n===w,u=n===n,o=null===t,i=t===w,f=t===t;if(n>t&&!o||!u||r&&!i&&f||e&&f)return 1;if(n<t&&!r||!f||o&&!e&&u||i&&u)return-1}return 0}function t(n,t,r){for(var e=n.length,u=r?e:-1;r?u--:++u<e;)if(t(n[u],u,n))return u;return-1}function r(n,t,r){if(t!==t)return p(n,r);r-=1;for(var e=n.length;++r<e;)if(n[r]===t)return r;return-1}function e(n){return typeof n=="function"||false}function u(n){return null==n?"":n+""}function o(n,t){for(var r=-1,e=n.length;++r<e&&-1<t.indexOf(n.charAt(r)););
+return r}function i(n,t){for(var r=n.length;r--&&-1<t.indexOf(n.charAt(r)););return r}function f(t,r){return n(t.a,r.a)||t.b-r.b}function a(n){return Nn[n]}function c(n){return Tn[n]}function l(n,t,r){return t?n=Bn[n]:r&&(n=Dn[n]),"\\"+n}function s(n){return"\\"+Dn[n]}function p(n,t,r){var e=n.length;for(t+=r?0:-1;r?t--:++t<e;){var u=n[t];if(u!==u)return t}return-1}function h(n){return!!n&&typeof n=="object"}function _(n){return 160>=n&&9<=n&&13>=n||32==n||160==n||5760==n||6158==n||8192<=n&&(8202>=n||8232==n||8233==n||8239==n||8287==n||12288==n||65279==n);
+}function v(n,t){for(var r=-1,e=n.length,u=-1,o=[];++r<e;)n[r]===t&&(n[r]=P,o[++u]=r);return o}function g(n){for(var t=-1,r=n.length;++t<r&&_(n.charCodeAt(t)););return t}function y(n){for(var t=n.length;t--&&_(n.charCodeAt(t)););return t}function d(n){return Pn[n]}function m(_){function Nn(n){if(h(n)&&!(Wo(n)||n instanceof zn)){if(n instanceof Pn)return n;if(eu.call(n,"__chain__")&&eu.call(n,"__wrapped__"))return qr(n)}return new Pn(n)}function Tn(){}function Pn(n,t,r){this.__wrapped__=n,this.__actions__=r||[],
+this.__chain__=!!t}function zn(n){this.__wrapped__=n,this.__actions__=[],this.__dir__=1,this.__filtered__=false,this.__iteratees__=[],this.__takeCount__=Cu,this.__views__=[]}function Bn(){this.__data__={}}function Dn(n){var t=n?n.length:0;for(this.data={hash:mu(null),set:new hu};t--;)this.push(n[t])}function Mn(n,t){var r=n.data;return(typeof t=="string"||de(t)?r.set.has(t):r.hash[t])?0:-1}function qn(n,t){var r=-1,e=n.length;for(t||(t=De(e));++r<e;)t[r]=n[r];return t}function Kn(n,t){for(var r=-1,e=n.length;++r<e&&false!==t(n[r],r,n););
+return n}function Vn(n,t){for(var r=-1,e=n.length;++r<e;)if(!t(n[r],r,n))return false;return true}function Zn(n,t){for(var r=-1,e=n.length,u=-1,o=[];++r<e;){var i=n[r];t(i,r,n)&&(o[++u]=i)}return o}function Xn(n,t){for(var r=-1,e=n.length,u=De(e);++r<e;)u[r]=t(n[r],r,n);return u}function Hn(n,t){for(var r=-1,e=t.length,u=n.length;++r<e;)n[u+r]=t[r];return n}function Qn(n,t,r,e){var u=-1,o=n.length;for(e&&o&&(r=n[++u]);++u<o;)r=t(r,n[u],u,n);return r}function nt(n,t){for(var r=-1,e=n.length;++r<e;)if(t(n[r],r,n))return true;
+return false}function tt(n,t,r,e){return n!==w&&eu.call(e,r)?n:t}function rt(n,t,r){for(var e=-1,u=Ko(t),o=u.length;++e<o;){var i=u[e],f=n[i],a=r(f,t[i],i,n,t);(a===a?a===f:f!==f)&&(f!==w||i in n)||(n[i]=a)}return n}function et(n,t){return null==t?n:ot(t,Ko(t),n)}function ut(n,t){for(var r=-1,e=null==n,u=!e&&Sr(n),o=u?n.length:0,i=t.length,f=De(i);++r<i;){var a=t[r];f[r]=u?Ur(a,o)?n[a]:w:e?w:n[a]}return f}function ot(n,t,r){r||(r={});for(var e=-1,u=t.length;++e<u;){var o=t[e];r[o]=n[o]}return r}function it(n,t,r){
+var e=typeof n;return"function"==e?t===w?n:Dt(n,t,r):null==n?Ne:"object"==e?At(n):t===w?Be(n):jt(n,t)}function ft(n,t,r,e,u,o,i){var f;if(r&&(f=u?r(n,e,u):r(n)),f!==w)return f;if(!de(n))return n;if(e=Wo(n)){if(f=Ir(n),!t)return qn(n,f)}else{var a=ou.call(n),c=a==K;if(a!=Z&&a!=z&&(!c||u))return Ln[a]?Er(n,a,t):u?n:{};if(Gn(n))return u?n:{};if(f=Rr(c?{}:n),!t)return et(f,n)}for(o||(o=[]),i||(i=[]),u=o.length;u--;)if(o[u]==n)return i[u];return o.push(n),i.push(f),(e?Kn:gt)(n,function(e,u){f[u]=ft(e,t,r,u,n,o,i);
+}),f}function at(n,t,r){if(typeof n!="function")throw new Xe(T);return _u(function(){n.apply(w,r)},t)}function ct(n,t){var e=n?n.length:0,u=[];if(!e)return u;var o=-1,i=jr(),f=i===r,a=f&&t.length>=F&&mu&&hu?new Dn(t):null,c=t.length;a&&(i=Mn,f=false,t=a);n:for(;++o<e;)if(a=n[o],f&&a===a){for(var l=c;l--;)if(t[l]===a)continue n;u.push(a)}else 0>i(t,a,0)&&u.push(a);return u}function lt(n,t){var r=true;return zu(n,function(n,e,u){return r=!!t(n,e,u)}),r}function st(n,t,r,e){var u=e,o=u;return zu(n,function(n,i,f){
+i=+t(n,i,f),(r(i,u)||i===e&&i===o)&&(u=i,o=n)}),o}function pt(n,t){var r=[];return zu(n,function(n,e,u){t(n,e,u)&&r.push(n)}),r}function ht(n,t,r,e){var u;return r(n,function(n,r,o){return t(n,r,o)?(u=e?r:n,false):void 0}),u}function _t(n,t,r,e){e||(e=[]);for(var u=-1,o=n.length;++u<o;){var i=n[u];h(i)&&Sr(i)&&(r||Wo(i)||_e(i))?t?_t(i,t,r,e):Hn(e,i):r||(e[e.length]=i)}return e}function vt(n,t){return Du(n,t,Ee)}function gt(n,t){return Du(n,t,Ko)}function yt(n,t){return Mu(n,t,Ko)}function dt(n,t){for(var r=-1,e=t.length,u=-1,o=[];++r<e;){
+var i=t[r];ye(n[i])&&(o[++u]=i)}return o}function mt(n,t,r){if(null!=n){n=Dr(n),r!==w&&r in n&&(t=[r]),r=0;for(var e=t.length;null!=n&&r<e;)n=Dr(n)[t[r++]];return r&&r==e?n:w}}function wt(n,t,r,e,u,o){if(n===t)return true;if(null==n||null==t||!de(n)&&!h(t))return n!==n&&t!==t;n:{var i=wt,f=Wo(n),a=Wo(t),c=B,l=B;f||(c=ou.call(n),c==z?c=Z:c!=Z&&(f=je(n))),a||(l=ou.call(t),l==z?l=Z:l!=Z&&je(t));var s=c==Z&&!Gn(n),a=l==Z&&!Gn(t),l=c==l;if(!l||f||s){if(!e&&(c=s&&eu.call(n,"__wrapped__"),a=a&&eu.call(t,"__wrapped__"),
+c||a)){n=i(c?n.value():n,a?t.value():t,r,e,u,o);break n}if(l){for(u||(u=[]),o||(o=[]),c=u.length;c--;)if(u[c]==n){n=o[c]==t;break n}u.push(n),o.push(t),n=(f?mr:xr)(n,t,i,r,e,u,o),u.pop(),o.pop()}else n=false}else n=wr(n,t,c)}return n}function xt(n,t,r){var e=t.length,u=e,o=!r;if(null==n)return!u;for(n=Dr(n);e--;){var i=t[e];if(o&&i[2]?i[1]!==n[i[0]]:!(i[0]in n))return false}for(;++e<u;){var i=t[e],f=i[0],a=n[f],c=i[1];if(o&&i[2]){if(a===w&&!(f in n))return false}else if(i=r?r(a,c,f):w,i===w?!wt(c,a,r,true):!i)return false;
+}return true}function bt(n,t){var r=-1,e=Sr(n)?De(n.length):[];return zu(n,function(n,u,o){e[++r]=t(n,u,o)}),e}function At(n){var t=kr(n);if(1==t.length&&t[0][2]){var r=t[0][0],e=t[0][1];return function(n){return null==n?false:(n=Dr(n),n[r]===e&&(e!==w||r in n))}}return function(n){return xt(n,t)}}function jt(n,t){var r=Wo(n),e=Wr(n)&&t===t&&!de(t),u=n+"";return n=Mr(n),function(o){if(null==o)return false;var i=u;if(o=Dr(o),!(!r&&e||i in o)){if(o=1==n.length?o:mt(o,St(n,0,-1)),null==o)return false;i=Gr(n),o=Dr(o);
+}return o[i]===t?t!==w||i in o:wt(t,o[i],w,true)}}function kt(n,t,r,e,u){if(!de(n))return n;var o=Sr(t)&&(Wo(t)||je(t)),i=o?w:Ko(t);return Kn(i||t,function(f,a){if(i&&(a=f,f=t[a]),h(f)){e||(e=[]),u||(u=[]);n:{for(var c=a,l=e,s=u,p=l.length,_=t[c];p--;)if(l[p]==_){n[c]=s[p];break n}var p=n[c],v=r?r(p,_,c,n,t):w,g=v===w;g&&(v=_,Sr(_)&&(Wo(_)||je(_))?v=Wo(p)?p:Sr(p)?qn(p):[]:xe(_)||_e(_)?v=_e(p)?Ie(p):xe(p)?p:{}:g=false),l.push(_),s.push(v),g?n[c]=kt(v,_,r,l,s):(v===v?v!==p:p===p)&&(n[c]=v)}}else c=n[a],
+l=r?r(c,f,a,n,t):w,(s=l===w)&&(l=f),l===w&&(!o||a in n)||!s&&(l===l?l===c:c!==c)||(n[a]=l)}),n}function Ot(n){return function(t){return null==t?w:Dr(t)[n]}}function It(n){var t=n+"";return n=Mr(n),function(r){return mt(r,n,t)}}function Rt(n,t){for(var r=n?t.length:0;r--;){var e=t[r];if(e!=u&&Ur(e)){var u=e;vu.call(n,e,1)}}return n}function Et(n,t){return n+wu(Ru()*(t-n+1))}function Ct(n,t,r,e,u){return u(n,function(n,u,o){r=e?(e=false,n):t(r,n,u,o)}),r}function St(n,t,r){var e=-1,u=n.length;for(t=null==t?0:+t||0,
+0>t&&(t=-t>u?0:u+t),r=r===w||r>u?u:+r||0,0>r&&(r+=u),u=t>r?0:r-t>>>0,t>>>=0,r=De(u);++e<u;)r[e]=n[e+t];return r}function Ut(n,t){var r;return zu(n,function(n,e,u){return r=t(n,e,u),!r}),!!r}function $t(n,t){var r=n.length;for(n.sort(t);r--;)n[r]=n[r].c;return n}function Wt(t,r,e){var u=br(),o=-1;return r=Xn(r,function(n){return u(n)}),t=bt(t,function(n){return{a:Xn(r,function(t){return t(n)}),b:++o,c:n}}),$t(t,function(t,r){var u;n:{for(var o=-1,i=t.a,f=r.a,a=i.length,c=e.length;++o<a;)if(u=n(i[o],f[o])){
+if(o>=c)break n;o=e[o],u*="asc"===o||true===o?1:-1;break n}u=t.b-r.b}return u})}function Ft(n,t){var r=0;return zu(n,function(n,e,u){r+=+t(n,e,u)||0}),r}function Lt(n,t){var e=-1,u=jr(),o=n.length,i=u===r,f=i&&o>=F,a=f&&mu&&hu?new Dn(void 0):null,c=[];a?(u=Mn,i=false):(f=false,a=t?[]:c);n:for(;++e<o;){var l=n[e],s=t?t(l,e,n):l;if(i&&l===l){for(var p=a.length;p--;)if(a[p]===s)continue n;t&&a.push(s),c.push(l)}else 0>u(a,s,0)&&((t||f)&&a.push(s),c.push(l))}return c}function Nt(n,t){for(var r=-1,e=t.length,u=De(e);++r<e;)u[r]=n[t[r]];
+return u}function Tt(n,t,r,e){for(var u=n.length,o=e?u:-1;(e?o--:++o<u)&&t(n[o],o,n););return r?St(n,e?0:o,e?o+1:u):St(n,e?o+1:0,e?u:o)}function Pt(n,t){var r=n;r instanceof zn&&(r=r.value());for(var e=-1,u=t.length;++e<u;)var o=t[e],r=o.func.apply(o.thisArg,Hn([r],o.args));return r}function zt(n,t,r){var e=0,u=n?n.length:e;if(typeof t=="number"&&t===t&&u<=Uu){for(;e<u;){var o=e+u>>>1,i=n[o];(r?i<=t:i<t)&&null!==i?e=o+1:u=o}return u}return Bt(n,t,Ne,r)}function Bt(n,t,r,e){t=r(t);for(var u=0,o=n?n.length:0,i=t!==t,f=null===t,a=t===w;u<o;){
+var c=wu((u+o)/2),l=r(n[c]),s=l!==w,p=l===l;(i?p||e:f?p&&s&&(e||null!=l):a?p&&(e||s):null==l?0:e?l<=t:l<t)?u=c+1:o=c}return ku(o,Su)}function Dt(n,t,r){if(typeof n!="function")return Ne;if(t===w)return n;switch(r){case 1:return function(r){return n.call(t,r)};case 3:return function(r,e,u){return n.call(t,r,e,u)};case 4:return function(r,e,u,o){return n.call(t,r,e,u,o)};case 5:return function(r,e,u,o,i){return n.call(t,r,e,u,o,i)}}return function(){return n.apply(t,arguments)}}function Mt(n){var t=new au(n.byteLength);
+return new gu(t).set(new gu(n)),t}function qt(n,t,r){for(var e=r.length,u=-1,o=ju(n.length-e,0),i=-1,f=t.length,a=De(f+o);++i<f;)a[i]=t[i];for(;++u<e;)a[r[u]]=n[u];for(;o--;)a[i++]=n[u++];return a}function Kt(n,t,r){for(var e=-1,u=r.length,o=-1,i=ju(n.length-u,0),f=-1,a=t.length,c=De(i+a);++o<i;)c[o]=n[o];for(i=o;++f<a;)c[i+f]=t[f];for(;++e<u;)c[i+r[e]]=n[o++];return c}function Vt(n,t){return function(r,e,u){var o=t?t():{};if(e=br(e,u,3),Wo(r)){u=-1;for(var i=r.length;++u<i;){var f=r[u];n(o,f,e(f,u,r),r);
+}}else zu(r,function(t,r,u){n(o,t,e(t,r,u),u)});return o}}function Zt(n){return pe(function(t,r){var e=-1,u=null==t?0:r.length,o=2<u?r[u-2]:w,i=2<u?r[2]:w,f=1<u?r[u-1]:w;for(typeof o=="function"?(o=Dt(o,f,5),u-=2):(o=typeof f=="function"?f:w,u-=o?1:0),i&&$r(r[0],r[1],i)&&(o=3>u?w:o,u=1);++e<u;)(i=r[e])&&n(t,i,o);return t})}function Yt(n,t){return function(r,e){var u=r?Vu(r):0;if(!Lr(u))return n(r,e);for(var o=t?u:-1,i=Dr(r);(t?o--:++o<u)&&false!==e(i[o],o,i););return r}}function Gt(n){return function(t,r,e){
+var u=Dr(t);e=e(t);for(var o=e.length,i=n?o:-1;n?i--:++i<o;){var f=e[i];if(false===r(u[f],f,u))break}return t}}function Jt(n,t){function r(){return(this&&this!==Yn&&this instanceof r?e:n).apply(t,arguments)}var e=Ht(n);return r}function Xt(n){return function(t){var r=-1;t=Fe(Ue(t));for(var e=t.length,u="";++r<e;)u=n(u,t[r],r);return u}}function Ht(n){return function(){var t=arguments;switch(t.length){case 0:return new n;case 1:return new n(t[0]);case 2:return new n(t[0],t[1]);case 3:return new n(t[0],t[1],t[2]);
+case 4:return new n(t[0],t[1],t[2],t[3]);case 5:return new n(t[0],t[1],t[2],t[3],t[4]);case 6:return new n(t[0],t[1],t[2],t[3],t[4],t[5]);case 7:return new n(t[0],t[1],t[2],t[3],t[4],t[5],t[6])}var r=Pu(n.prototype),t=n.apply(r,t);return de(t)?t:r}}function Qt(n){function t(r,e,u){return u&&$r(r,e,u)&&(e=w),r=dr(r,n,w,w,w,w,w,e),r.placeholder=t.placeholder,r}return t}function nr(n,t){return pe(function(r){var e=r[0];return null==e?e:(r.push(t),n.apply(w,r))})}function tr(n,t){return function(r,e,u){
+if(u&&$r(r,e,u)&&(e=w),e=br(e,u,3),1==e.length){u=r=Wo(r)?r:Br(r);for(var o=e,i=-1,f=u.length,a=t,c=a;++i<f;){var l=u[i],s=+o(l);n(s,a)&&(a=s,c=l)}if(u=c,!r.length||u!==t)return u}return st(r,e,n,t)}}function rr(n,r){return function(e,u,o){return u=br(u,o,3),Wo(e)?(u=t(e,u,r),-1<u?e[u]:w):ht(e,u,n)}}function er(n){return function(r,e,u){return r&&r.length?(e=br(e,u,3),t(r,e,n)):-1}}function ur(n){return function(t,r,e){return r=br(r,e,3),ht(t,r,n,true)}}function or(n){return function(){for(var t,r=arguments.length,e=n?r:-1,u=0,o=De(r);n?e--:++e<r;){
+var i=o[u++]=arguments[e];if(typeof i!="function")throw new Xe(T);!t&&Pn.prototype.thru&&"wrapper"==Ar(i)&&(t=new Pn([],true))}for(e=t?-1:r;++e<r;){var i=o[e],u=Ar(i),f="wrapper"==u?Ku(i):w;t=f&&Fr(f[0])&&f[1]==(E|k|I|C)&&!f[4].length&&1==f[9]?t[Ar(f[0])].apply(t,f[3]):1==i.length&&Fr(i)?t[u]():t.thru(i)}return function(){var n=arguments,e=n[0];if(t&&1==n.length&&Wo(e)&&e.length>=F)return t.plant(e).value();for(var u=0,n=r?o[u].apply(this,n):e;++u<r;)n=o[u].call(this,n);return n}}}function ir(n,t){
+return function(r,e,u){return typeof e=="function"&&u===w&&Wo(r)?n(r,e):t(r,Dt(e,u,3))}}function fr(n){return function(t,r,e){return(typeof r!="function"||e!==w)&&(r=Dt(r,e,3)),n(t,r,Ee)}}function ar(n){return function(t,r,e){return(typeof r!="function"||e!==w)&&(r=Dt(r,e,3)),n(t,r)}}function cr(n){return function(t,r,e){var u={};return r=br(r,e,3),gt(t,function(t,e,o){o=r(t,e,o),e=n?o:e,t=n?t:o,u[e]=t}),u}}function lr(n){return function(t,r,e){return t=u(t),(n?t:"")+_r(t,r,e)+(n?"":t)}}function sr(n){
+var t=pe(function(r,e){var u=v(e,t.placeholder);return dr(r,n,w,e,u)});return t}function pr(n,t){return function(r,e,u,o){var i=3>arguments.length;return typeof e=="function"&&o===w&&Wo(r)?n(r,e,u,i):Ct(r,br(e,o,4),u,i,t)}}function hr(n,t,r,e,u,o,i,f,a,c){function l(){for(var m=arguments.length,x=m,j=De(m);x--;)j[x]=arguments[x];if(e&&(j=qt(j,e,u)),o&&(j=Kt(j,o,i)),_||y){var x=l.placeholder,k=v(j,x),m=m-k.length;if(m<c){var O=f?qn(f):w,m=ju(c-m,0),E=_?k:w,k=_?w:k,C=_?j:w,j=_?w:j;return t|=_?I:R,t&=~(_?R:I),
+g||(t&=~(b|A)),j=[n,t,r,C,E,j,k,O,a,m],O=hr.apply(w,j),Fr(n)&&Zu(O,j),O.placeholder=x,O}}if(x=p?r:this,O=h?x[n]:n,f)for(m=j.length,E=ku(f.length,m),k=qn(j);E--;)C=f[E],j[E]=Ur(C,m)?k[C]:w;return s&&a<j.length&&(j.length=a),this&&this!==Yn&&this instanceof l&&(O=d||Ht(n)),O.apply(x,j)}var s=t&E,p=t&b,h=t&A,_=t&k,g=t&j,y=t&O,d=h?w:Ht(n);return l}function _r(n,t,r){return n=n.length,t=+t,n<t&&bu(t)?(t-=n,r=null==r?" ":r+"",$e(r,du(t/r.length)).slice(0,t)):""}function vr(n,t,r,e){function u(){for(var t=-1,f=arguments.length,a=-1,c=e.length,l=De(c+f);++a<c;)l[a]=e[a];
+for(;f--;)l[a++]=arguments[++t];return(this&&this!==Yn&&this instanceof u?i:n).apply(o?r:this,l)}var o=t&b,i=Ht(n);return u}function gr(n){var t=Ve[n];return function(n,r){return(r=r===w?0:+r||0)?(r=su(10,r),t(n*r)/r):t(n)}}function yr(n){return function(t,r,e,u){var o=br(e);return null==e&&o===it?zt(t,r,n):Bt(t,r,o(e,u,1),n)}}function dr(n,t,r,e,u,o,i,f){var a=t&A;if(!a&&typeof n!="function")throw new Xe(T);var c=e?e.length:0;if(c||(t&=~(I|R),e=u=w),c-=u?u.length:0,t&R){var l=e,s=u;e=u=w}var p=a?w:Ku(n);
+return r=[n,t,r,e,u,l,s,o,i,f],p&&(e=r[1],t=p[1],f=e|t,u=t==E&&e==k||t==E&&e==C&&r[7].length<=p[8]||t==(E|C)&&e==k,(f<E||u)&&(t&b&&(r[2]=p[2],f|=e&b?0:j),(e=p[3])&&(u=r[3],r[3]=u?qt(u,e,p[4]):qn(e),r[4]=u?v(r[3],P):qn(p[4])),(e=p[5])&&(u=r[5],r[5]=u?Kt(u,e,p[6]):qn(e),r[6]=u?v(r[5],P):qn(p[6])),(e=p[7])&&(r[7]=qn(e)),t&E&&(r[8]=null==r[8]?p[8]:ku(r[8],p[8])),null==r[9]&&(r[9]=p[9]),r[0]=p[0],r[1]=f),t=r[1],f=r[9]),r[9]=null==f?a?0:n.length:ju(f-c,0)||0,n=t==b?Jt(r[0],r[2]):t!=I&&t!=(b|I)||r[4].length?hr.apply(w,r):vr.apply(w,r),
+(p?qu:Zu)(n,r)}function mr(n,t,r,e,u,o,i){var f=-1,a=n.length,c=t.length;if(a!=c&&(!u||c<=a))return false;for(;++f<a;){var l=n[f],c=t[f],s=e?e(u?c:l,u?l:c,f):w;if(s!==w){if(s)continue;return false}if(u){if(!nt(t,function(n){return l===n||r(l,n,e,u,o,i)}))return false}else if(l!==c&&!r(l,c,e,u,o,i))return false}return true}function wr(n,t,r){switch(r){case D:case M:return+n==+t;case q:return n.name==t.name&&n.message==t.message;case V:return n!=+n?t!=+t:n==+t;case Y:case G:return n==t+""}return false}function xr(n,t,r,e,u,o,i){
+var f=Ko(n),a=f.length,c=Ko(t).length;if(a!=c&&!u)return false;for(c=a;c--;){var l=f[c];if(!(u?l in t:eu.call(t,l)))return false}for(var s=u;++c<a;){var l=f[c],p=n[l],h=t[l],_=e?e(u?h:p,u?p:h,l):w;if(_===w?!r(p,h,e,u,o,i):!_)return false;s||(s="constructor"==l)}return s||(r=n.constructor,e=t.constructor,!(r!=e&&"constructor"in n&&"constructor"in t)||typeof r=="function"&&r instanceof r&&typeof e=="function"&&e instanceof e)?true:false}function br(n,t,r){var e=Nn.callback||Le,e=e===Le?it:e;return r?e(n,t,r):e}function Ar(n){
+for(var t=n.name+"",r=Fu[t],e=r?r.length:0;e--;){var u=r[e],o=u.func;if(null==o||o==n)return u.name}return t}function jr(n,t,e){var u=Nn.indexOf||Yr,u=u===Yr?r:u;return n?u(n,t,e):u}function kr(n){n=Ce(n);for(var t=n.length;t--;){var r,e=n[t];r=n[t][1],r=r===r&&!de(r),e[2]=r}return n}function Or(n,t){var r=null==n?w:n[t];return me(r)?r:w}function Ir(n){var t=n.length,r=new n.constructor(t);return t&&"string"==typeof n[0]&&eu.call(n,"index")&&(r.index=n.index,r.input=n.input),r}function Rr(n){return n=n.constructor,
+typeof n=="function"&&n instanceof n||(n=Ye),new n}function Er(n,t,r){var e=n.constructor;switch(t){case J:return Mt(n);case D:case M:return new e(+n);case X:case H:case Q:case nn:case tn:case rn:case en:case un:case on:return e instanceof e&&(e=Lu[t]),t=n.buffer,new e(r?Mt(t):t,n.byteOffset,n.length);case V:case G:return new e(n);case Y:var u=new e(n.source,kn.exec(n));u.lastIndex=n.lastIndex}return u}function Cr(n,t,r){return null==n||Wr(t,n)||(t=Mr(t),n=1==t.length?n:mt(n,St(t,0,-1)),t=Gr(t)),
+t=null==n?n:n[t],null==t?w:t.apply(n,r)}function Sr(n){return null!=n&&Lr(Vu(n))}function Ur(n,t){return n=typeof n=="number"||Rn.test(n)?+n:-1,t=null==t?$u:t,-1<n&&0==n%1&&n<t}function $r(n,t,r){if(!de(r))return false;var e=typeof t;return("number"==e?Sr(r)&&Ur(t,r.length):"string"==e&&t in r)?(t=r[t],n===n?n===t:t!==t):false}function Wr(n,t){var r=typeof n;return"string"==r&&dn.test(n)||"number"==r?true:Wo(n)?false:!yn.test(n)||null!=t&&n in Dr(t)}function Fr(n){var t=Ar(n),r=Nn[t];return typeof r=="function"&&t in zn.prototype?n===r?true:(t=Ku(r),
+!!t&&n===t[0]):false}function Lr(n){return typeof n=="number"&&-1<n&&0==n%1&&n<=$u}function Nr(n,t){return n===w?t:Fo(n,t,Nr)}function Tr(n,t){n=Dr(n);for(var r=-1,e=t.length,u={};++r<e;){var o=t[r];o in n&&(u[o]=n[o])}return u}function Pr(n,t){var r={};return vt(n,function(n,e,u){t(n,e,u)&&(r[e]=n)}),r}function zr(n){for(var t=Ee(n),r=t.length,e=r&&n.length,u=!!e&&Lr(e)&&(Wo(n)||_e(n)||Ae(n)),o=-1,i=[];++o<r;){var f=t[o];(u&&Ur(f,e)||eu.call(n,f))&&i.push(f)}return i}function Br(n){return null==n?[]:Sr(n)?Nn.support.unindexedChars&&Ae(n)?n.split(""):de(n)?n:Ye(n):Se(n);
+}function Dr(n){if(Nn.support.unindexedChars&&Ae(n)){for(var t=-1,r=n.length,e=Ye(n);++t<r;)e[t]=n.charAt(t);return e}return de(n)?n:Ye(n)}function Mr(n){if(Wo(n))return n;var t=[];return u(n).replace(mn,function(n,r,e,u){t.push(e?u.replace(An,"$1"):r||n)}),t}function qr(n){return n instanceof zn?n.clone():new Pn(n.__wrapped__,n.__chain__,qn(n.__actions__))}function Kr(n,t,r){return n&&n.length?((r?$r(n,t,r):null==t)&&(t=1),St(n,0>t?0:t)):[]}function Vr(n,t,r){var e=n?n.length:0;return e?((r?$r(n,t,r):null==t)&&(t=1),
+t=e-(+t||0),St(n,0,0>t?0:t)):[]}function Zr(n){return n?n[0]:w}function Yr(n,t,e){var u=n?n.length:0;if(!u)return-1;if(typeof e=="number")e=0>e?ju(u+e,0):e;else if(e)return e=zt(n,t),e<u&&(t===t?t===n[e]:n[e]!==n[e])?e:-1;return r(n,t,e||0)}function Gr(n){var t=n?n.length:0;return t?n[t-1]:w}function Jr(n){return Kr(n,1)}function Xr(n,t,e,u){if(!n||!n.length)return[];null!=t&&typeof t!="boolean"&&(u=e,e=$r(n,t,u)?w:t,t=false);var o=br();if((null!=e||o!==it)&&(e=o(e,u,3)),t&&jr()===r){t=e;var i;e=-1,
+u=n.length;for(var o=-1,f=[];++e<u;){var a=n[e],c=t?t(a,e,n):a;e&&i===c||(i=c,f[++o]=a)}n=f}else n=Lt(n,e);return n}function Hr(n){if(!n||!n.length)return[];var t=-1,r=0;n=Zn(n,function(n){return Sr(n)?(r=ju(n.length,r),true):void 0});for(var e=De(r);++t<r;)e[t]=Xn(n,Ot(t));return e}function Qr(n,t,r){return n&&n.length?(n=Hr(n),null==t?n:(t=Dt(t,r,4),Xn(n,function(n){return Qn(n,t,w,true)}))):[]}function ne(n,t){var r=-1,e=n?n.length:0,u={};for(!e||t||Wo(n[0])||(t=[]);++r<e;){var o=n[r];t?u[o]=t[r]:o&&(u[o[0]]=o[1]);
+}return u}function te(n){return n=Nn(n),n.__chain__=true,n}function re(n,t,r){return t.call(r,n)}function ee(n,t,r){var e=Wo(n)?Vn:lt;return r&&$r(n,t,r)&&(t=w),(typeof t!="function"||r!==w)&&(t=br(t,r,3)),e(n,t)}function ue(n,t,r){var e=Wo(n)?Zn:pt;return t=br(t,r,3),e(n,t)}function oe(n,t,r,e){var u=n?Vu(n):0;return Lr(u)||(n=Se(n),u=n.length),r=typeof r!="number"||e&&$r(t,r,e)?0:0>r?ju(u+r,0):r||0,typeof n=="string"||!Wo(n)&&Ae(n)?r<=u&&-1<n.indexOf(t,r):!!u&&-1<jr(n,t,r)}function ie(n,t,r){var e=Wo(n)?Xn:bt;
+return t=br(t,r,3),e(n,t)}function fe(n,t,r){if(r?$r(n,t,r):null==t){n=Br(n);var e=n.length;return 0<e?n[Et(0,e-1)]:w}r=-1,n=Oe(n);var e=n.length,u=e-1;for(t=ku(0>t?0:+t||0,e);++r<t;){var e=Et(r,u),o=n[e];n[e]=n[r],n[r]=o}return n.length=t,n}function ae(n,t,r){var e=Wo(n)?nt:Ut;return r&&$r(n,t,r)&&(t=w),(typeof t!="function"||r!==w)&&(t=br(t,r,3)),e(n,t)}function ce(n,t){var r;if(typeof t!="function"){if(typeof n!="function")throw new Xe(T);var e=n;n=t,t=e}return function(){return 0<--n&&(r=t.apply(this,arguments)),
+1>=n&&(t=w),r}}function le(n,t,r){function e(t,r){r&&cu(r),a=p=h=w,t&&(_=wo(),c=n.apply(s,f),p||a||(f=s=w))}function u(){var n=t-(wo()-l);0>=n||n>t?e(h,a):p=_u(u,n)}function o(){e(g,p)}function i(){if(f=arguments,l=wo(),s=this,h=g&&(p||!y),false===v)var r=y&&!p;else{a||y||(_=l);var e=v-(l-_),i=0>=e||e>v;i?(a&&(a=cu(a)),_=l,c=n.apply(s,f)):a||(a=_u(o,e))}return i&&p?p=cu(p):p||t===v||(p=_u(u,t)),r&&(i=true,c=n.apply(s,f)),!i||p||a||(f=s=w),c}var f,a,c,l,s,p,h,_=0,v=false,g=true;if(typeof n!="function")throw new Xe(T);
+if(t=0>t?0:+t||0,true===r)var y=true,g=false;else de(r)&&(y=!!r.leading,v="maxWait"in r&&ju(+r.maxWait||0,t),g="trailing"in r?!!r.trailing:g);return i.cancel=function(){p&&cu(p),a&&cu(a),_=0,a=p=h=w},i}function se(n,t){if(typeof n!="function"||t&&typeof t!="function")throw new Xe(T);var r=function(){var e=arguments,u=t?t.apply(this,e):e[0],o=r.cache;return o.has(u)?o.get(u):(e=n.apply(this,e),r.cache=o.set(u,e),e)};return r.cache=new se.Cache,r}function pe(n,t){if(typeof n!="function")throw new Xe(T);return t=ju(t===w?n.length-1:+t||0,0),
+function(){for(var r=arguments,e=-1,u=ju(r.length-t,0),o=De(u);++e<u;)o[e]=r[t+e];switch(t){case 0:return n.call(this,o);case 1:return n.call(this,r[0],o);case 2:return n.call(this,r[0],r[1],o)}for(u=De(t+1),e=-1;++e<t;)u[e]=r[e];return u[t]=o,n.apply(this,u)}}function he(n,t){return n>t}function _e(n){return h(n)&&Sr(n)&&eu.call(n,"callee")&&!pu.call(n,"callee")}function ve(n,t,r,e){return e=(r=typeof r=="function"?Dt(r,e,3):w)?r(n,t):w,e===w?wt(n,t,r):!!e}function ge(n){return h(n)&&typeof n.message=="string"&&ou.call(n)==q;
+}function ye(n){return de(n)&&ou.call(n)==K}function de(n){var t=typeof n;return!!n&&("object"==t||"function"==t)}function me(n){return null==n?false:ye(n)?fu.test(ru.call(n)):h(n)&&(Gn(n)?fu:In).test(n)}function we(n){return typeof n=="number"||h(n)&&ou.call(n)==V}function xe(n){var t;if(!h(n)||ou.call(n)!=Z||Gn(n)||_e(n)||!(eu.call(n,"constructor")||(t=n.constructor,typeof t!="function"||t instanceof t)))return false;var r;return Nn.support.ownLast?(vt(n,function(n,t,e){return r=eu.call(e,t),false}),false!==r):(vt(n,function(n,t){
+r=t}),r===w||eu.call(n,r))}function be(n){return de(n)&&ou.call(n)==Y}function Ae(n){return typeof n=="string"||h(n)&&ou.call(n)==G}function je(n){return h(n)&&Lr(n.length)&&!!Fn[ou.call(n)]}function ke(n,t){return n<t}function Oe(n){var t=n?Vu(n):0;return Lr(t)?t?Nn.support.unindexedChars&&Ae(n)?n.split(""):qn(n):[]:Se(n)}function Ie(n){return ot(n,Ee(n))}function Re(n){return dt(n,Ee(n))}function Ee(n){if(null==n)return[];de(n)||(n=Ye(n));for(var t=n.length,r=Nn.support,t=t&&Lr(t)&&(Wo(n)||_e(n)||Ae(n))&&t||0,e=n.constructor,u=-1,e=ye(e)&&e.prototype||nu,o=e===n,i=De(t),f=0<t,a=r.enumErrorProps&&(n===Qe||n instanceof qe),c=r.enumPrototypes&&ye(n);++u<t;)i[u]=u+"";
+for(var l in n)c&&"prototype"==l||a&&("message"==l||"name"==l)||f&&Ur(l,t)||"constructor"==l&&(o||!eu.call(n,l))||i.push(l);if(r.nonEnumShadows&&n!==nu)for(t=n===tu?G:n===Qe?q:ou.call(n),r=Nu[t]||Nu[Z],t==Z&&(e=nu),t=Wn.length;t--;)l=Wn[t],u=r[l],o&&u||(u?!eu.call(n,l):n[l]===e[l])||i.push(l);return i}function Ce(n){n=Dr(n);for(var t=-1,r=Ko(n),e=r.length,u=De(e);++t<e;){var o=r[t];u[t]=[o,n[o]]}return u}function Se(n){return Nt(n,Ko(n))}function Ue(n){return(n=u(n))&&n.replace(En,a).replace(bn,"");
+}function $e(n,t){var r="";if(n=u(n),t=+t,1>t||!n||!bu(t))return r;do t%2&&(r+=n),t=wu(t/2),n+=n;while(t);return r}function We(n,t,r){var e=n;return(n=u(n))?(r?$r(e,t,r):null==t)?n.slice(g(n),y(n)+1):(t+="",n.slice(o(n,t),i(n,t)+1)):n}function Fe(n,t,r){return r&&$r(n,t,r)&&(t=w),n=u(n),n.match(t||Un)||[]}function Le(n,t,r){return r&&$r(n,t,r)&&(t=w),h(n)?Te(n):it(n,t)}function Ne(n){return n}function Te(n){return At(ft(n,true))}function Pe(n,t,r){if(null==r){var e=de(t),u=e?Ko(t):w;((u=u&&u.length?dt(t,u):w)?u.length:e)||(u=false,
+r=t,t=n,n=this)}u||(u=dt(t,Ko(t)));var o=true,e=-1,i=ye(n),f=u.length;false===r?o=false:de(r)&&"chain"in r&&(o=r.chain);for(;++e<f;){r=u[e];var a=t[r];n[r]=a,i&&(n.prototype[r]=function(t){return function(){var r=this.__chain__;if(o||r){var e=n(this.__wrapped__);return(e.__actions__=qn(this.__actions__)).push({func:t,args:arguments,thisArg:n}),e.__chain__=r,e}return t.apply(n,Hn([this.value()],arguments))}}(a))}return n}function ze(){}function Be(n){return Wr(n)?Ot(n):It(n)}_=_?Jn.defaults(Yn.Object(),_,Jn.pick(Yn,$n)):Yn;
+var De=_.Array,Me=_.Date,qe=_.Error,Ke=_.Function,Ve=_.Math,Ze=_.Number,Ye=_.Object,Ge=_.RegExp,Je=_.String,Xe=_.TypeError,He=De.prototype,Qe=qe.prototype,nu=Ye.prototype,tu=Je.prototype,ru=Ke.prototype.toString,eu=nu.hasOwnProperty,uu=0,ou=nu.toString,iu=Yn._,fu=Ge("^"+ru.call(eu).replace(/[\\^$.*+?()[\]{}|]/g,"\\$&").replace(/hasOwnProperty|(function).*?(?=\\\()| for .+?(?=\\\])/g,"$1.*?")+"$"),au=_.ArrayBuffer,cu=_.clearTimeout,lu=_.parseFloat,su=Ve.pow,pu=nu.propertyIsEnumerable,hu=Or(_,"Set"),_u=_.setTimeout,vu=He.splice,gu=_.Uint8Array,yu=Or(_,"WeakMap"),du=Ve.ceil,mu=Or(Ye,"create"),wu=Ve.floor,xu=Or(De,"isArray"),bu=_.isFinite,Au=Or(Ye,"keys"),ju=Ve.max,ku=Ve.min,Ou=Or(Me,"now"),Iu=_.parseInt,Ru=Ve.random,Eu=Ze.NEGATIVE_INFINITY,Cu=Ze.POSITIVE_INFINITY,Su=4294967294,Uu=2147483647,$u=9007199254740991,Wu=yu&&new yu,Fu={},Lu={};
+Lu[X]=_.Float32Array,Lu[H]=_.Float64Array,Lu[Q]=_.Int8Array,Lu[nn]=_.Int16Array,Lu[tn]=_.Int32Array,Lu[rn]=gu,Lu[en]=_.Uint8ClampedArray,Lu[un]=_.Uint16Array,Lu[on]=_.Uint32Array;var Nu={};Nu[B]=Nu[M]=Nu[V]={constructor:true,toLocaleString:true,toString:true,valueOf:true},Nu[D]=Nu[G]={constructor:true,toString:true,valueOf:true},Nu[q]=Nu[K]=Nu[Y]={constructor:true,toString:true},Nu[Z]={constructor:true},Kn(Wn,function(n){for(var t in Nu)if(eu.call(Nu,t)){var r=Nu[t];r[n]=eu.call(r,n)}});var Tu=Nn.support={};!function(n){
+var t=function(){this.x=n},r={0:n,length:n},e=[];t.prototype={valueOf:n,y:n};for(var u in new t)e.push(u);Tu.enumErrorProps=pu.call(Qe,"message")||pu.call(Qe,"name"),Tu.enumPrototypes=pu.call(t,"prototype"),Tu.nonEnumShadows=!/valueOf/.test(e),Tu.ownLast="x"!=e[0],Tu.spliceObjects=(vu.call(r,0,1),!r[0]),Tu.unindexedChars="xx"!="x"[0]+Ye("x")[0]}(1,0),Nn.templateSettings={escape:_n,evaluate:vn,interpolate:gn,variable:"",imports:{_:Nn}};var Pu=function(){function n(){}return function(t){if(de(t)){n.prototype=t;
+var r=new n;n.prototype=w}return r||{}}}(),zu=Yt(gt),Bu=Yt(yt,true),Du=Gt(),Mu=Gt(true),qu=Wu?function(n,t){return Wu.set(n,t),n}:Ne,Ku=Wu?function(n){return Wu.get(n)}:ze,Vu=Ot("length"),Zu=function(){var n=0,t=0;return function(r,e){var u=wo(),o=W-(u-t);if(t=u,0<o){if(++n>=$)return r}else n=0;return qu(r,e)}}(),Yu=pe(function(n,t){return h(n)&&Sr(n)?ct(n,_t(t,false,true)):[]}),Gu=er(),Ju=er(true),Xu=pe(function(n){for(var t=n.length,e=t,u=De(l),o=jr(),i=o===r,f=[];e--;){var a=n[e]=Sr(a=n[e])?a:[];u[e]=i&&120<=a.length&&mu&&hu?new Dn(e&&a):null;
+}var i=n[0],c=-1,l=i?i.length:0,s=u[0];n:for(;++c<l;)if(a=i[c],0>(s?Mn(s,a):o(f,a,0))){for(e=t;--e;){var p=u[e];if(0>(p?Mn(p,a):o(n[e],a,0)))continue n}s&&s.push(a),f.push(a)}return f}),Hu=pe(function(t,r){r=_t(r);var e=ut(t,r);return Rt(t,r.sort(n)),e}),Qu=yr(),no=yr(true),to=pe(function(n){return Lt(_t(n,false,true))}),ro=pe(function(n,t){return Sr(n)?ct(n,t):[]}),eo=pe(Hr),uo=pe(function(n){var t=n.length,r=2<t?n[t-2]:w,e=1<t?n[t-1]:w;return 2<t&&typeof r=="function"?t-=2:(r=1<t&&typeof e=="function"?(--t,
+e):w,e=w),n.length=t,Qr(n,r,e)}),oo=pe(function(n){return n=_t(n),this.thru(function(t){t=Wo(t)?t:[Dr(t)];for(var r=n,e=-1,u=t.length,o=-1,i=r.length,f=De(u+i);++e<u;)f[e]=t[e];for(;++o<i;)f[e++]=r[o];return f})}),io=pe(function(n,t){return Sr(n)&&(n=Br(n)),ut(n,_t(t))}),fo=Vt(function(n,t,r){eu.call(n,r)?++n[r]:n[r]=1}),ao=rr(zu),co=rr(Bu,true),lo=ir(Kn,zu),so=ir(function(n,t){for(var r=n.length;r--&&false!==t(n[r],r,n););return n},Bu),po=Vt(function(n,t,r){eu.call(n,r)?n[r].push(t):n[r]=[t]}),ho=Vt(function(n,t,r){
+n[r]=t}),_o=pe(function(n,t,r){var e=-1,u=typeof t=="function",o=Wr(t),i=Sr(n)?De(n.length):[];return zu(n,function(n){var f=u?t:o&&null!=n?n[t]:w;i[++e]=f?f.apply(n,r):Cr(n,t,r)}),i}),vo=Vt(function(n,t,r){n[r?0:1].push(t)},function(){return[[],[]]}),go=pr(Qn,zu),yo=pr(function(n,t,r,e){var u=n.length;for(e&&u&&(r=n[--u]);u--;)r=t(r,n[u],u,n);return r},Bu),mo=pe(function(n,t){if(null==n)return[];var r=t[2];return r&&$r(t[0],t[1],r)&&(t.length=1),Wt(n,_t(t),[])}),wo=Ou||function(){return(new Me).getTime();
+},xo=pe(function(n,t,r){var e=b;if(r.length)var u=v(r,xo.placeholder),e=e|I;return dr(n,e,t,r,u)}),bo=pe(function(n,t){t=t.length?_t(t):Re(n);for(var r=-1,e=t.length;++r<e;){var u=t[r];n[u]=dr(n[u],b,n)}return n}),Ao=pe(function(n,t,r){var e=b|A;if(r.length)var u=v(r,Ao.placeholder),e=e|I;return dr(t,e,n,r,u)}),jo=Qt(k),ko=Qt(O),Oo=pe(function(n,t){return at(n,1,t)}),Io=pe(function(n,t,r){return at(n,t,r)}),Ro=or(),Eo=or(true),Co=pe(function(n,t){if(t=_t(t),typeof n!="function"||!Vn(t,e))throw new Xe(T);
+var r=t.length;return pe(function(e){for(var u=ku(e.length,r);u--;)e[u]=t[u](e[u]);return n.apply(this,e)})}),So=sr(I),Uo=sr(R),$o=pe(function(n,t){return dr(n,C,w,w,w,_t(t))}),Wo=xu||function(n){return h(n)&&Lr(n.length)&&ou.call(n)==B},Fo=Zt(kt),Lo=Zt(function(n,t,r){return r?rt(n,t,r):et(n,t)}),No=nr(Lo,function(n,t){return n===w?t:n}),To=nr(Fo,Nr),Po=ur(gt),zo=ur(yt),Bo=fr(Du),Do=fr(Mu),Mo=ar(gt),qo=ar(yt),Ko=Au?function(n){var t=null==n?w:n.constructor;return typeof t=="function"&&t.prototype===n||(typeof n=="function"?Nn.support.enumPrototypes:Sr(n))?zr(n):de(n)?Au(n):[];
+}:zr,Vo=cr(true),Zo=cr(),Yo=pe(function(n,t){if(null==n)return{};if("function"!=typeof t[0])return t=Xn(_t(t),Je),Tr(n,ct(Ee(n),t));var r=Dt(t[0],t[1],3);return Pr(n,function(n,t,e){return!r(n,t,e)})}),Go=pe(function(n,t){return null==n?{}:"function"==typeof t[0]?Pr(n,Dt(t[0],t[1],3)):Tr(n,_t(t))}),Jo=Xt(function(n,t,r){return t=t.toLowerCase(),n+(r?t.charAt(0).toUpperCase()+t.slice(1):t)}),Xo=Xt(function(n,t,r){return n+(r?"-":"")+t.toLowerCase()}),Ho=lr(),Qo=lr(true),ni=Xt(function(n,t,r){return n+(r?"_":"")+t.toLowerCase();
+}),ti=Xt(function(n,t,r){return n+(r?" ":"")+(t.charAt(0).toUpperCase()+t.slice(1))}),ri=pe(function(n,t){try{return n.apply(w,t)}catch(r){return ge(r)?r:new qe(r)}}),ei=pe(function(n,t){return function(r){return Cr(r,n,t)}}),ui=pe(function(n,t){return function(r){return Cr(n,r,t)}}),oi=gr("ceil"),ii=gr("floor"),fi=tr(he,Eu),ai=tr(ke,Cu),ci=gr("round");return Nn.prototype=Tn.prototype,Pn.prototype=Pu(Tn.prototype),Pn.prototype.constructor=Pn,zn.prototype=Pu(Tn.prototype),zn.prototype.constructor=zn,
+Bn.prototype["delete"]=function(n){return this.has(n)&&delete this.__data__[n]},Bn.prototype.get=function(n){return"__proto__"==n?w:this.__data__[n]},Bn.prototype.has=function(n){return"__proto__"!=n&&eu.call(this.__data__,n)},Bn.prototype.set=function(n,t){return"__proto__"!=n&&(this.__data__[n]=t),this},Dn.prototype.push=function(n){var t=this.data;typeof n=="string"||de(n)?t.set.add(n):t.hash[n]=true},se.Cache=Bn,Nn.after=function(n,t){if(typeof t!="function"){if(typeof n!="function")throw new Xe(T);
+var r=n;n=t,t=r}return n=bu(n=+n)?n:0,function(){return 1>--n?t.apply(this,arguments):void 0}},Nn.ary=function(n,t,r){return r&&$r(n,t,r)&&(t=w),t=n&&null==t?n.length:ju(+t||0,0),dr(n,E,w,w,w,w,t)},Nn.assign=Lo,Nn.at=io,Nn.before=ce,Nn.bind=xo,Nn.bindAll=bo,Nn.bindKey=Ao,Nn.callback=Le,Nn.chain=te,Nn.chunk=function(n,t,r){t=(r?$r(n,t,r):null==t)?1:ju(wu(t)||1,1),r=0;for(var e=n?n.length:0,u=-1,o=De(du(e/t));r<e;)o[++u]=St(n,r,r+=t);return o},Nn.compact=function(n){for(var t=-1,r=n?n.length:0,e=-1,u=[];++t<r;){
+var o=n[t];o&&(u[++e]=o)}return u},Nn.constant=function(n){return function(){return n}},Nn.countBy=fo,Nn.create=function(n,t,r){var e=Pu(n);return r&&$r(n,t,r)&&(t=w),t?et(e,t):e},Nn.curry=jo,Nn.curryRight=ko,Nn.debounce=le,Nn.defaults=No,Nn.defaultsDeep=To,Nn.defer=Oo,Nn.delay=Io,Nn.difference=Yu,Nn.drop=Kr,Nn.dropRight=Vr,Nn.dropRightWhile=function(n,t,r){return n&&n.length?Tt(n,br(t,r,3),true,true):[]},Nn.dropWhile=function(n,t,r){return n&&n.length?Tt(n,br(t,r,3),true):[]},Nn.fill=function(n,t,r,e){
+var u=n?n.length:0;if(!u)return[];for(r&&typeof r!="number"&&$r(n,t,r)&&(r=0,e=u),u=n.length,r=null==r?0:+r||0,0>r&&(r=-r>u?0:u+r),e=e===w||e>u?u:+e||0,0>e&&(e+=u),u=r>e?0:e>>>0,r>>>=0;r<u;)n[r++]=t;return n},Nn.filter=ue,Nn.flatten=function(n,t,r){var e=n?n.length:0;return r&&$r(n,t,r)&&(t=false),e?_t(n,t):[]},Nn.flattenDeep=function(n){return n&&n.length?_t(n,true):[]},Nn.flow=Ro,Nn.flowRight=Eo,Nn.forEach=lo,Nn.forEachRight=so,Nn.forIn=Bo,Nn.forInRight=Do,Nn.forOwn=Mo,Nn.forOwnRight=qo,Nn.functions=Re,
+Nn.groupBy=po,Nn.indexBy=ho,Nn.initial=function(n){return Vr(n,1)},Nn.intersection=Xu,Nn.invert=function(n,t,r){r&&$r(n,t,r)&&(t=w),r=-1;for(var e=Ko(n),u=e.length,o={};++r<u;){var i=e[r],f=n[i];t?eu.call(o,f)?o[f].push(i):o[f]=[i]:o[f]=i}return o},Nn.invoke=_o,Nn.keys=Ko,Nn.keysIn=Ee,Nn.map=ie,Nn.mapKeys=Vo,Nn.mapValues=Zo,Nn.matches=Te,Nn.matchesProperty=function(n,t){return jt(n,ft(t,true))},Nn.memoize=se,Nn.merge=Fo,Nn.method=ei,Nn.methodOf=ui,Nn.mixin=Pe,Nn.modArgs=Co,Nn.negate=function(n){if(typeof n!="function")throw new Xe(T);
+return function(){return!n.apply(this,arguments)}},Nn.omit=Yo,Nn.once=function(n){return ce(2,n)},Nn.pairs=Ce,Nn.partial=So,Nn.partialRight=Uo,Nn.partition=vo,Nn.pick=Go,Nn.pluck=function(n,t){return ie(n,Be(t))},Nn.property=Be,Nn.propertyOf=function(n){return function(t){return mt(n,Mr(t),t+"")}},Nn.pull=function(){var n=arguments,t=n[0];if(!t||!t.length)return t;for(var r=0,e=jr(),u=n.length;++r<u;)for(var o=0,i=n[r];-1<(o=e(t,i,o));)vu.call(t,o,1);return t},Nn.pullAt=Hu,Nn.range=function(n,t,r){
+r&&$r(n,t,r)&&(t=r=w),n=+n||0,r=null==r?1:+r||0,null==t?(t=n,n=0):t=+t||0;var e=-1;t=ju(du((t-n)/(r||1)),0);for(var u=De(t);++e<t;)u[e]=n,n+=r;return u},Nn.rearg=$o,Nn.reject=function(n,t,r){var e=Wo(n)?Zn:pt;return t=br(t,r,3),e(n,function(n,r,e){return!t(n,r,e)})},Nn.remove=function(n,t,r){var e=[];if(!n||!n.length)return e;var u=-1,o=[],i=n.length;for(t=br(t,r,3);++u<i;)r=n[u],t(r,u,n)&&(e.push(r),o.push(u));return Rt(n,o),e},Nn.rest=Jr,Nn.restParam=pe,Nn.set=function(n,t,r){if(null==n)return n;
+var e=t+"";t=null!=n[e]||Wr(t,n)?[e]:Mr(t);for(var e=-1,u=t.length,o=u-1,i=n;null!=i&&++e<u;){var f=t[e];de(i)&&(e==o?i[f]=r:null==i[f]&&(i[f]=Ur(t[e+1])?[]:{})),i=i[f]}return n},Nn.shuffle=function(n){return fe(n,Cu)},Nn.slice=function(n,t,r){var e=n?n.length:0;return e?(r&&typeof r!="number"&&$r(n,t,r)&&(t=0,r=e),St(n,t,r)):[]},Nn.sortBy=function(n,t,r){if(null==n)return[];r&&$r(n,t,r)&&(t=w);var e=-1;return t=br(t,r,3),n=bt(n,function(n,r,u){return{a:t(n,r,u),b:++e,c:n}}),$t(n,f)},Nn.sortByAll=mo,
+Nn.sortByOrder=function(n,t,r,e){return null==n?[]:(e&&$r(t,r,e)&&(r=w),Wo(t)||(t=null==t?[]:[t]),Wo(r)||(r=null==r?[]:[r]),Wt(n,t,r))},Nn.spread=function(n){if(typeof n!="function")throw new Xe(T);return function(t){return n.apply(this,t)}},Nn.take=function(n,t,r){return n&&n.length?((r?$r(n,t,r):null==t)&&(t=1),St(n,0,0>t?0:t)):[]},Nn.takeRight=function(n,t,r){var e=n?n.length:0;return e?((r?$r(n,t,r):null==t)&&(t=1),t=e-(+t||0),St(n,0>t?0:t)):[]},Nn.takeRightWhile=function(n,t,r){return n&&n.length?Tt(n,br(t,r,3),false,true):[];
+},Nn.takeWhile=function(n,t,r){return n&&n.length?Tt(n,br(t,r,3)):[]},Nn.tap=function(n,t,r){return t.call(r,n),n},Nn.throttle=function(n,t,r){var e=true,u=true;if(typeof n!="function")throw new Xe(T);return false===r?e=false:de(r)&&(e="leading"in r?!!r.leading:e,u="trailing"in r?!!r.trailing:u),le(n,t,{leading:e,maxWait:+t,trailing:u})},Nn.thru=re,Nn.times=function(n,t,r){if(n=wu(n),1>n||!bu(n))return[];var e=-1,u=De(ku(n,4294967295));for(t=Dt(t,r,1);++e<n;)4294967295>e?u[e]=t(e):t(e);return u},Nn.toArray=Oe,
+Nn.toPlainObject=Ie,Nn.transform=function(n,t,r,e){var u=Wo(n)||je(n);return t=br(t,e,4),null==r&&(u||de(n)?(e=n.constructor,r=u?Wo(n)?new e:[]:Pu(ye(e)?e.prototype:w)):r={}),(u?Kn:gt)(n,function(n,e,u){return t(r,n,e,u)}),r},Nn.union=to,Nn.uniq=Xr,Nn.unzip=Hr,Nn.unzipWith=Qr,Nn.values=Se,Nn.valuesIn=function(n){return Nt(n,Ee(n))},Nn.where=function(n,t){return ue(n,At(t))},Nn.without=ro,Nn.wrap=function(n,t){return t=null==t?Ne:t,dr(t,I,w,[n],[])},Nn.xor=function(){for(var n=-1,t=arguments.length;++n<t;){
+var r=arguments[n];if(Sr(r))var e=e?Hn(ct(e,r),ct(r,e)):r}return e?Lt(e):[]},Nn.zip=eo,Nn.zipObject=ne,Nn.zipWith=uo,Nn.backflow=Eo,Nn.collect=ie,Nn.compose=Eo,Nn.each=lo,Nn.eachRight=so,Nn.extend=Lo,Nn.iteratee=Le,Nn.methods=Re,Nn.object=ne,Nn.select=ue,Nn.tail=Jr,Nn.unique=Xr,Pe(Nn,Nn),Nn.add=function(n,t){return(+n||0)+(+t||0)},Nn.attempt=ri,Nn.camelCase=Jo,Nn.capitalize=function(n){return(n=u(n))&&n.charAt(0).toUpperCase()+n.slice(1)},Nn.ceil=oi,Nn.clone=function(n,t,r,e){return t&&typeof t!="boolean"&&$r(n,t,r)?t=false:typeof t=="function"&&(e=r,
+r=t,t=false),typeof r=="function"?ft(n,t,Dt(r,e,3)):ft(n,t)},Nn.cloneDeep=function(n,t,r){return typeof t=="function"?ft(n,true,Dt(t,r,3)):ft(n,true)},Nn.deburr=Ue,Nn.endsWith=function(n,t,r){n=u(n),t+="";var e=n.length;return r=r===w?e:ku(0>r?0:+r||0,e),r-=t.length,0<=r&&n.indexOf(t,r)==r},Nn.escape=function(n){return(n=u(n))&&hn.test(n)?n.replace(sn,c):n},Nn.escapeRegExp=function(n){return(n=u(n))&&xn.test(n)?n.replace(wn,l):n||"(?:)"},Nn.every=ee,Nn.find=ao,Nn.findIndex=Gu,Nn.findKey=Po,Nn.findLast=co,
+Nn.findLastIndex=Ju,Nn.findLastKey=zo,Nn.findWhere=function(n,t){return ao(n,At(t))},Nn.first=Zr,Nn.floor=ii,Nn.get=function(n,t,r){return n=null==n?w:mt(n,Mr(t),t+""),n===w?r:n},Nn.gt=he,Nn.gte=function(n,t){return n>=t},Nn.has=function(n,t){if(null==n)return false;var r=eu.call(n,t);if(!r&&!Wr(t)){if(t=Mr(t),n=1==t.length?n:mt(n,St(t,0,-1)),null==n)return false;t=Gr(t),r=eu.call(n,t)}return r||Lr(n.length)&&Ur(t,n.length)&&(Wo(n)||_e(n)||Ae(n))},Nn.identity=Ne,Nn.includes=oe,Nn.indexOf=Yr,Nn.inRange=function(n,t,r){
+return t=+t||0,r===w?(r=t,t=0):r=+r||0,n>=ku(t,r)&&n<ju(t,r)},Nn.isArguments=_e,Nn.isArray=Wo,Nn.isBoolean=function(n){return true===n||false===n||h(n)&&ou.call(n)==D},Nn.isDate=function(n){return h(n)&&ou.call(n)==M},Nn.isElement=function(n){return!!n&&1===n.nodeType&&h(n)&&!xe(n)},Nn.isEmpty=function(n){return null==n?true:Sr(n)&&(Wo(n)||Ae(n)||_e(n)||h(n)&&ye(n.splice))?!n.length:!Ko(n).length},Nn.isEqual=ve,Nn.isError=ge,Nn.isFinite=function(n){return typeof n=="number"&&bu(n)},Nn.isFunction=ye,Nn.isMatch=function(n,t,r,e){
+return r=typeof r=="function"?Dt(r,e,3):w,xt(n,kr(t),r)},Nn.isNaN=function(n){return we(n)&&n!=+n},Nn.isNative=me,Nn.isNull=function(n){return null===n},Nn.isNumber=we,Nn.isObject=de,Nn.isPlainObject=xe,Nn.isRegExp=be,Nn.isString=Ae,Nn.isTypedArray=je,Nn.isUndefined=function(n){return n===w},Nn.kebabCase=Xo,Nn.last=Gr,Nn.lastIndexOf=function(n,t,r){var e=n?n.length:0;if(!e)return-1;var u=e;if(typeof r=="number")u=(0>r?ju(e+r,0):ku(r||0,e-1))+1;else if(r)return u=zt(n,t,true)-1,n=n[u],(t===t?t===n:n!==n)?u:-1;
+if(t!==t)return p(n,u,true);for(;u--;)if(n[u]===t)return u;return-1},Nn.lt=ke,Nn.lte=function(n,t){return n<=t},Nn.max=fi,Nn.min=ai,Nn.noConflict=function(){return Yn._=iu,this},Nn.noop=ze,Nn.now=wo,Nn.pad=function(n,t,r){n=u(n),t=+t;var e=n.length;return e<t&&bu(t)?(e=(t-e)/2,t=wu(e),e=du(e),r=_r("",e,r),r.slice(0,t)+n+r):n},Nn.padLeft=Ho,Nn.padRight=Qo,Nn.parseInt=function(n,t,r){return(r?$r(n,t,r):null==t)?t=0:t&&(t=+t),n=We(n),Iu(n,t||(On.test(n)?16:10))},Nn.random=function(n,t,r){r&&$r(n,t,r)&&(t=r=w);
+var e=null==n,u=null==t;return null==r&&(u&&typeof n=="boolean"?(r=n,n=1):typeof t=="boolean"&&(r=t,u=true)),e&&u&&(t=1,u=false),n=+n||0,u?(t=n,n=0):t=+t||0,r||n%1||t%1?(r=Ru(),ku(n+r*(t-n+lu("1e-"+((r+"").length-1))),t)):Et(n,t)},Nn.reduce=go,Nn.reduceRight=yo,Nn.repeat=$e,Nn.result=function(n,t,r){var e=null==n?w:Dr(n)[t];return e===w&&(null==n||Wr(t,n)||(t=Mr(t),n=1==t.length?n:mt(n,St(t,0,-1)),e=null==n?w:Dr(n)[Gr(t)]),e=e===w?r:e),ye(e)?e.call(n):e},Nn.round=ci,Nn.runInContext=m,Nn.size=function(n){
+var t=n?Vu(n):0;return Lr(t)?t:Ko(n).length},Nn.snakeCase=ni,Nn.some=ae,Nn.sortedIndex=Qu,Nn.sortedLastIndex=no,Nn.startCase=ti,Nn.startsWith=function(n,t,r){return n=u(n),r=null==r?0:ku(0>r?0:+r||0,n.length),n.lastIndexOf(t,r)==r},Nn.sum=function(n,t,r){if(r&&$r(n,t,r)&&(t=w),t=br(t,r,3),1==t.length){n=Wo(n)?n:Br(n),r=n.length;for(var e=0;r--;)e+=+t(n[r])||0;n=e}else n=Ft(n,t);return n},Nn.template=function(n,t,r){var e=Nn.templateSettings;r&&$r(n,t,r)&&(t=r=w),n=u(n),t=rt(et({},r||t),e,tt),r=rt(et({},t.imports),e.imports,tt);
+var o,i,f=Ko(r),a=Nt(r,f),c=0;r=t.interpolate||Cn;var l="__p+='";r=Ge((t.escape||Cn).source+"|"+r.source+"|"+(r===gn?jn:Cn).source+"|"+(t.evaluate||Cn).source+"|$","g");var p="sourceURL"in t?"//# sourceURL="+t.sourceURL+"\n":"";if(n.replace(r,function(t,r,e,u,f,a){return e||(e=u),l+=n.slice(c,a).replace(Sn,s),r&&(o=true,l+="'+__e("+r+")+'"),f&&(i=true,l+="';"+f+";\n__p+='"),e&&(l+="'+((__t=("+e+"))==null?'':__t)+'"),c=a+t.length,t}),l+="';",(t=t.variable)||(l="with(obj){"+l+"}"),l=(i?l.replace(fn,""):l).replace(an,"$1").replace(cn,"$1;"),
+l="function("+(t||"obj")+"){"+(t?"":"obj||(obj={});")+"var __t,__p=''"+(o?",__e=_.escape":"")+(i?",__j=Array.prototype.join;function print(){__p+=__j.call(arguments,'')}":";")+l+"return __p}",t=ri(function(){return Ke(f,p+"return "+l).apply(w,a)}),t.source=l,ge(t))throw t;return t},Nn.trim=We,Nn.trimLeft=function(n,t,r){var e=n;return(n=u(n))?n.slice((r?$r(e,t,r):null==t)?g(n):o(n,t+"")):n},Nn.trimRight=function(n,t,r){var e=n;return(n=u(n))?(r?$r(e,t,r):null==t)?n.slice(0,y(n)+1):n.slice(0,i(n,t+"")+1):n;
+},Nn.trunc=function(n,t,r){r&&$r(n,t,r)&&(t=w);var e=S;if(r=U,null!=t)if(de(t)){var o="separator"in t?t.separator:o,e="length"in t?+t.length||0:e;r="omission"in t?u(t.omission):r}else e=+t||0;if(n=u(n),e>=n.length)return n;if(e-=r.length,1>e)return r;if(t=n.slice(0,e),null==o)return t+r;if(be(o)){if(n.slice(e).search(o)){var i,f=n.slice(0,e);for(o.global||(o=Ge(o.source,(kn.exec(o)||"")+"g")),o.lastIndex=0;n=o.exec(f);)i=n.index;t=t.slice(0,null==i?e:i)}}else n.indexOf(o,e)!=e&&(o=t.lastIndexOf(o),
+-1<o&&(t=t.slice(0,o)));return t+r},Nn.unescape=function(n){return(n=u(n))&&pn.test(n)?n.replace(ln,d):n},Nn.uniqueId=function(n){var t=++uu;return u(n)+t},Nn.words=Fe,Nn.all=ee,Nn.any=ae,Nn.contains=oe,Nn.eq=ve,Nn.detect=ao,Nn.foldl=go,Nn.foldr=yo,Nn.head=Zr,Nn.include=oe,Nn.inject=go,Pe(Nn,function(){var n={};return gt(Nn,function(t,r){Nn.prototype[r]||(n[r]=t)}),n}(),false),Nn.sample=fe,Nn.prototype.sample=function(n){return this.__chain__||null!=n?this.thru(function(t){return fe(t,n)}):fe(this.value());
+},Nn.VERSION=x,Kn("bind bindKey curry curryRight partial partialRight".split(" "),function(n){Nn[n].placeholder=Nn}),Kn(["drop","take"],function(n,t){zn.prototype[n]=function(r){var e=this.__filtered__;if(e&&!t)return new zn(this);r=null==r?1:ju(wu(r)||0,0);var u=this.clone();return e?u.__takeCount__=ku(u.__takeCount__,r):u.__views__.push({size:r,type:n+(0>u.__dir__?"Right":"")}),u},zn.prototype[n+"Right"]=function(t){return this.reverse()[n](t).reverse()}}),Kn(["filter","map","takeWhile"],function(n,t){
+var r=t+1,e=r!=N;zn.prototype[n]=function(n,t){var u=this.clone();return u.__iteratees__.push({iteratee:br(n,t,1),type:r}),u.__filtered__=u.__filtered__||e,u}}),Kn(["first","last"],function(n,t){var r="take"+(t?"Right":"");zn.prototype[n]=function(){return this[r](1).value()[0]}}),Kn(["initial","rest"],function(n,t){var r="drop"+(t?"":"Right");zn.prototype[n]=function(){return this.__filtered__?new zn(this):this[r](1)}}),Kn(["pluck","where"],function(n,t){var r=t?"filter":"map",e=t?At:Be;zn.prototype[n]=function(n){
+return this[r](e(n))}}),zn.prototype.compact=function(){return this.filter(Ne)},zn.prototype.reject=function(n,t){return n=br(n,t,1),this.filter(function(t){return!n(t)})},zn.prototype.slice=function(n,t){n=null==n?0:+n||0;var r=this;return r.__filtered__&&(0<n||0>t)?new zn(r):(0>n?r=r.takeRight(-n):n&&(r=r.drop(n)),t!==w&&(t=+t||0,r=0>t?r.dropRight(-t):r.take(t-n)),r)},zn.prototype.takeRightWhile=function(n,t){return this.reverse().takeWhile(n,t).reverse()},zn.prototype.toArray=function(){return this.take(Cu);
+},gt(zn.prototype,function(n,t){var r=/^(?:filter|map|reject)|While$/.test(t),e=/^(?:first|last)$/.test(t),u=Nn[e?"take"+("last"==t?"Right":""):t];u&&(Nn.prototype[t]=function(){var t=e?[1]:arguments,o=this.__chain__,i=this.__wrapped__,f=!!this.__actions__.length,a=i instanceof zn,c=t[0],l=a||Wo(i);l&&r&&typeof c=="function"&&1!=c.length&&(a=l=false);var s=function(n){return e&&o?u(n,1)[0]:u.apply(w,Hn([n],t))},c={func:re,args:[s],thisArg:w},f=a&&!f;return e&&!o?f?(i=i.clone(),i.__actions__.push(c),
+n.call(i)):u.call(w,this.value())[0]:!e&&l?(i=f?i:new zn(this),i=n.apply(i,t),i.__actions__.push(c),new Pn(i,o)):this.thru(s)})}),Kn("join pop push replace shift sort splice split unshift".split(" "),function(n){var t=(/^(?:replace|split)$/.test(n)?tu:He)[n],r=/^(?:push|sort|unshift)$/.test(n)?"tap":"thru",e=!Tu.spliceObjects&&/^(?:pop|shift|splice)$/.test(n),u=/^(?:join|pop|replace|shift)$/.test(n),o=e?function(){var n=t.apply(this,arguments);return 0===this.length&&delete this[0],n}:t;Nn.prototype[n]=function(){
+var n=arguments;return u&&!this.__chain__?o.apply(this.value(),n):this[r](function(t){return o.apply(t,n)})}}),gt(zn.prototype,function(n,t){var r=Nn[t];if(r){var e=r.name+"";(Fu[e]||(Fu[e]=[])).push({name:t,func:r})}}),Fu[hr(w,A).name]=[{name:"wrapper",func:w}],zn.prototype.clone=function(){var n=new zn(this.__wrapped__);return n.__actions__=qn(this.__actions__),n.__dir__=this.__dir__,n.__filtered__=this.__filtered__,n.__iteratees__=qn(this.__iteratees__),n.__takeCount__=this.__takeCount__,n.__views__=qn(this.__views__),
+n},zn.prototype.reverse=function(){if(this.__filtered__){var n=new zn(this);n.__dir__=-1,n.__filtered__=true}else n=this.clone(),n.__dir__*=-1;return n},zn.prototype.value=function(){var n,t=this.__wrapped__.value(),r=this.__dir__,e=Wo(t),u=0>r,o=e?t.length:0;n=0;for(var i=o,f=this.__views__,a=-1,c=f.length;++a<c;){var l=f[a],s=l.size;switch(l.type){case"drop":n+=s;break;case"dropRight":i-=s;break;case"take":i=ku(i,n+s);break;case"takeRight":n=ju(n,i-s)}}if(n={start:n,end:i},i=n.start,f=n.end,n=f-i,
+u=u?f:i-1,i=this.__iteratees__,f=i.length,a=0,c=ku(n,this.__takeCount__),!e||o<F||o==n&&c==n)return Pt(t,this.__actions__);e=[];n:for(;n--&&a<c;){for(u+=r,o=-1,l=t[u];++o<f;){var p=i[o],s=p.type,p=p.iteratee(l);if(s==N)l=p;else if(!p){if(s==L)continue n;break n}}e[a++]=l}return e},Nn.prototype.chain=function(){return te(this)},Nn.prototype.commit=function(){return new Pn(this.value(),this.__chain__)},Nn.prototype.concat=oo,Nn.prototype.plant=function(n){for(var t,r=this;r instanceof Tn;){var e=qr(r);
+t?u.__wrapped__=e:t=e;var u=e,r=r.__wrapped__}return u.__wrapped__=n,t},Nn.prototype.reverse=function(){var n=this.__wrapped__,t=function(n){return n.reverse()};return n instanceof zn?(this.__actions__.length&&(n=new zn(this)),n=n.reverse(),n.__actions__.push({func:re,args:[t],thisArg:w}),new Pn(n,this.__chain__)):this.thru(t)},Nn.prototype.toString=function(){return this.value()+""},Nn.prototype.run=Nn.prototype.toJSON=Nn.prototype.valueOf=Nn.prototype.value=function(){return Pt(this.__wrapped__,this.__actions__);
+},Nn.prototype.collect=Nn.prototype.map,Nn.prototype.head=Nn.prototype.first,Nn.prototype.select=Nn.prototype.filter,Nn.prototype.tail=Nn.prototype.rest,Nn}var w,x="3.10.1",b=1,A=2,j=4,k=8,O=16,I=32,R=64,E=128,C=256,S=30,U="...",$=150,W=16,F=200,L=1,N=2,T="Expected a function",P="__lodash_placeholder__",z="[object Arguments]",B="[object Array]",D="[object Boolean]",M="[object Date]",q="[object Error]",K="[object Function]",V="[object Number]",Z="[object Object]",Y="[object RegExp]",G="[object String]",J="[object ArrayBuffer]",X="[object Float32Array]",H="[object Float64Array]",Q="[object Int8Array]",nn="[object Int16Array]",tn="[object Int32Array]",rn="[object Uint8Array]",en="[object Uint8ClampedArray]",un="[object Uint16Array]",on="[object Uint32Array]",fn=/\b__p\+='';/g,an=/\b(__p\+=)''\+/g,cn=/(__e\(.*?\)|\b__t\))\+'';/g,ln=/&(?:amp|lt|gt|quot|#39|#96);/g,sn=/[&<>"'`]/g,pn=RegExp(ln.source),hn=RegExp(sn.source),_n=/<%-([\s\S]+?)%>/g,vn=/<%([\s\S]+?)%>/g,gn=/<%=([\s\S]+?)%>/g,yn=/\.|\[(?:[^[\]]*|(["'])(?:(?!\1)[^\n\\]|\\.)*?\1)\]/,dn=/^\w*$/,mn=/[^.[\]]+|\[(?:(-?\d+(?:\.\d+)?)|(["'])((?:(?!\2)[^\n\\]|\\.)*?)\2)\]/g,wn=/^[:!,]|[\\^$.*+?()[\]{}|\/]|(^[0-9a-fA-Fnrtuvx])|([\n\r\u2028\u2029])/g,xn=RegExp(wn.source),bn=/[\u0300-\u036f\ufe20-\ufe23]/g,An=/\\(\\)?/g,jn=/\$\{([^\\}]*(?:\\.[^\\}]*)*)\}/g,kn=/\w*$/,On=/^0[xX]/,In=/^\[object .+?Constructor\]$/,Rn=/^\d+$/,En=/[\xc0-\xd6\xd8-\xde\xdf-\xf6\xf8-\xff]/g,Cn=/($^)/,Sn=/['\n\r\u2028\u2029\\]/g,Un=RegExp("[A-Z\\xc0-\\xd6\\xd8-\\xde]+(?=[A-Z\\xc0-\\xd6\\xd8-\\xde][a-z\\xdf-\\xf6\\xf8-\\xff]+)|[A-Z\\xc0-\\xd6\\xd8-\\xde]?[a-z\\xdf-\\xf6\\xf8-\\xff]+|[A-Z\\xc0-\\xd6\\xd8-\\xde]+|[0-9]+","g"),$n="Array ArrayBuffer Date Error Float32Array Float64Array Function Int8Array Int16Array Int32Array Math Number Object RegExp Set String _ clearTimeout isFinite parseFloat parseInt setTimeout TypeError Uint8Array Uint8ClampedArray Uint16Array Uint32Array WeakMap".split(" "),Wn="constructor hasOwnProperty isPrototypeOf propertyIsEnumerable toLocaleString toString valueOf".split(" "),Fn={};
+Fn[X]=Fn[H]=Fn[Q]=Fn[nn]=Fn[tn]=Fn[rn]=Fn[en]=Fn[un]=Fn[on]=true,Fn[z]=Fn[B]=Fn[J]=Fn[D]=Fn[M]=Fn[q]=Fn[K]=Fn["[object Map]"]=Fn[V]=Fn[Z]=Fn[Y]=Fn["[object Set]"]=Fn[G]=Fn["[object WeakMap]"]=false;var Ln={};Ln[z]=Ln[B]=Ln[J]=Ln[D]=Ln[M]=Ln[X]=Ln[H]=Ln[Q]=Ln[nn]=Ln[tn]=Ln[V]=Ln[Z]=Ln[Y]=Ln[G]=Ln[rn]=Ln[en]=Ln[un]=Ln[on]=true,Ln[q]=Ln[K]=Ln["[object Map]"]=Ln["[object Set]"]=Ln["[object WeakMap]"]=false;var Nn={"\xc0":"A","\xc1":"A","\xc2":"A","\xc3":"A","\xc4":"A","\xc5":"A","\xe0":"a","\xe1":"a","\xe2":"a",
+"\xe3":"a","\xe4":"a","\xe5":"a","\xc7":"C","\xe7":"c","\xd0":"D","\xf0":"d","\xc8":"E","\xc9":"E","\xca":"E","\xcb":"E","\xe8":"e","\xe9":"e","\xea":"e","\xeb":"e","\xcc":"I","\xcd":"I","\xce":"I","\xcf":"I","\xec":"i","\xed":"i","\xee":"i","\xef":"i","\xd1":"N","\xf1":"n","\xd2":"O","\xd3":"O","\xd4":"O","\xd5":"O","\xd6":"O","\xd8":"O","\xf2":"o","\xf3":"o","\xf4":"o","\xf5":"o","\xf6":"o","\xf8":"o","\xd9":"U","\xda":"U","\xdb":"U","\xdc":"U","\xf9":"u","\xfa":"u","\xfb":"u","\xfc":"u","\xdd":"Y",
+"\xfd":"y","\xff":"y","\xc6":"Ae","\xe6":"ae","\xde":"Th","\xfe":"th","\xdf":"ss"},Tn={"&":"&amp;","<":"&lt;",">":"&gt;",'"':"&quot;","'":"&#39;","`":"&#96;"},Pn={"&amp;":"&","&lt;":"<","&gt;":">","&quot;":'"',"&#39;":"'","&#96;":"`"},zn={"function":true,object:true},Bn={0:"x30",1:"x31",2:"x32",3:"x33",4:"x34",5:"x35",6:"x36",7:"x37",8:"x38",9:"x39",A:"x41",B:"x42",C:"x43",D:"x44",E:"x45",F:"x46",a:"x61",b:"x62",c:"x63",d:"x64",e:"x65",f:"x66",n:"x6e",r:"x72",t:"x74",u:"x75",v:"x76",x:"x78"},Dn={"\\":"\\",
+"'":"'","\n":"n","\r":"r","\u2028":"u2028","\u2029":"u2029"},Mn=zn[typeof exports]&&exports&&!exports.nodeType&&exports,qn=zn[typeof module]&&module&&!module.nodeType&&module,Kn=zn[typeof self]&&self&&self.Object&&self,Vn=zn[typeof window]&&window&&window.Object&&window,Zn=qn&&qn.exports===Mn&&Mn,Yn=Mn&&qn&&typeof global=="object"&&global&&global.Object&&global||Vn!==(this&&this.window)&&Vn||Kn||this,Gn=function(){try{Object({toString:0}+"")}catch(n){return function(){return false}}return function(n){
+return typeof n.toString!="function"&&typeof(n+"")=="string"}}(),Jn=m();typeof define=="function"&&typeof define.amd=="object"&&define.amd?(Yn._=Jn, define(function(){return Jn})):Mn&&qn?Zn?(qn.exports=Jn)._=Jn:Mn._=Jn:Yn._=Jn}).call(this); \ No newline at end of file
diff --git a/ydb/core/viewer/content/api/lib/marked.js b/ydb/core/viewer/content/api/lib/marked.js
index 291ff19d4b3..c2a678d5504 100644
--- a/ydb/core/viewer/content/api/lib/marked.js
+++ b/ydb/core/viewer/content/api/lib/marked.js
@@ -1,1272 +1,1272 @@
-/**
- * marked - a markdown parser
- * Copyright (c) 2011-2014, Christopher Jeffrey. (MIT Licensed)
- * https://github.com/chjj/marked
- */
-
-;(function() {
-
-/**
- * Block-Level Grammar
- */
-
-var block = {
- newline: /^\n+/,
- code: /^( {4}[^\n]+\n*)+/,
- fences: noop,
- hr: /^( *[-*_]){3,} *(?:\n+|$)/,
- heading: /^ *(#{1,6}) *([^\n]+?) *#* *(?:\n+|$)/,
- nptable: noop,
- lheading: /^([^\n]+)\n *(=|-){2,} *(?:\n+|$)/,
- blockquote: /^( *>[^\n]+(\n(?!def)[^\n]+)*\n*)+/,
- list: /^( *)(bull) [\s\S]+?(?:hr|def|\n{2,}(?! )(?!\1bull )\n*|\s*$)/,
- html: /^ *(?:comment *(?:\n|\s*$)|closed *(?:\n{2,}|\s*$)|closing *(?:\n{2,}|\s*$))/,
- def: /^ *\[([^\]]+)\]: *<?([^\s>]+)>?(?: +["(]([^\n]+)[")])? *(?:\n+|$)/,
- table: noop,
- paragraph: /^((?:[^\n]+\n?(?!hr|heading|lheading|blockquote|tag|def))+)\n*/,
- text: /^[^\n]+/
-};
-
-block.bullet = /(?:[*+-]|\d+\.)/;
-block.item = /^( *)(bull) [^\n]*(?:\n(?!\1bull )[^\n]*)*/;
-block.item = replace(block.item, 'gm')
- (/bull/g, block.bullet)
- ();
-
-block.list = replace(block.list)
- (/bull/g, block.bullet)
- ('hr', '\\n+(?=\\1?(?:[-*_] *){3,}(?:\\n+|$))')
- ('def', '\\n+(?=' + block.def.source + ')')
- ();
-
-block.blockquote = replace(block.blockquote)
- ('def', block.def)
- ();
-
-block._tag = '(?!(?:'
- + 'a|em|strong|small|s|cite|q|dfn|abbr|data|time|code'
- + '|var|samp|kbd|sub|sup|i|b|u|mark|ruby|rt|rp|bdi|bdo'
- + '|span|br|wbr|ins|del|img)\\b)\\w+(?!:/|[^\\w\\s@]*@)\\b';
-
-block.html = replace(block.html)
- ('comment', /<!--[\s\S]*?-->/)
- ('closed', /<(tag)[\s\S]+?<\/\1>/)
- ('closing', /<tag(?:"[^"]*"|'[^']*'|[^'">])*?>/)
- (/tag/g, block._tag)
- ();
-
-block.paragraph = replace(block.paragraph)
- ('hr', block.hr)
- ('heading', block.heading)
- ('lheading', block.lheading)
- ('blockquote', block.blockquote)
- ('tag', '<' + block._tag)
- ('def', block.def)
- ();
-
-/**
- * Normal Block Grammar
- */
-
-block.normal = merge({}, block);
-
-/**
- * GFM Block Grammar
- */
-
-block.gfm = merge({}, block.normal, {
- fences: /^ *(`{3,}|~{3,}) *(\S+)? *\n([\s\S]+?)\s*\1 *(?:\n+|$)/,
- paragraph: /^/
-});
-
-block.gfm.paragraph = replace(block.paragraph)
- ('(?!', '(?!'
- + block.gfm.fences.source.replace('\\1', '\\2') + '|'
- + block.list.source.replace('\\1', '\\3') + '|')
- ();
-
-/**
- * GFM + Tables Block Grammar
- */
-
-block.tables = merge({}, block.gfm, {
- nptable: /^ *(\S.*\|.*)\n *([-:]+ *\|[-| :]*)\n((?:.*\|.*(?:\n|$))*)\n*/,
- table: /^ *\|(.+)\n *\|( *[-:]+[-| :]*)\n((?: *\|.*(?:\n|$))*)\n*/
-});
-
-/**
- * Block Lexer
- */
-
-function Lexer(options) {
- this.tokens = [];
- this.tokens.links = {};
- this.options = options || marked.defaults;
- this.rules = block.normal;
-
- if (this.options.gfm) {
- if (this.options.tables) {
- this.rules = block.tables;
- } else {
- this.rules = block.gfm;
- }
- }
-}
-
-/**
- * Expose Block Rules
- */
-
-Lexer.rules = block;
-
-/**
- * Static Lex Method
- */
-
-Lexer.lex = function(src, options) {
- var lexer = new Lexer(options);
- return lexer.lex(src);
-};
-
-/**
- * Preprocessing
- */
-
-Lexer.prototype.lex = function(src) {
- src = src
- .replace(/\r\n|\r/g, '\n')
- .replace(/\t/g, ' ')
- .replace(/\u00a0/g, ' ')
- .replace(/\u2424/g, '\n');
-
- return this.token(src, true);
-};
-
-/**
- * Lexing
- */
-
-Lexer.prototype.token = function(src, top, bq) {
- var src = src.replace(/^ +$/gm, '')
- , next
- , loose
- , cap
- , bull
- , b
- , item
- , space
- , i
- , l;
-
- while (src) {
- // newline
- if (cap = this.rules.newline.exec(src)) {
- src = src.substring(cap[0].length);
- if (cap[0].length > 1) {
- this.tokens.push({
- type: 'space'
- });
- }
- }
-
- // code
- if (cap = this.rules.code.exec(src)) {
- src = src.substring(cap[0].length);
- cap = cap[0].replace(/^ {4}/gm, '');
- this.tokens.push({
- type: 'code',
- text: !this.options.pedantic
- ? cap.replace(/\n+$/, '')
- : cap
- });
- continue;
- }
-
- // fences (gfm)
- if (cap = this.rules.fences.exec(src)) {
- src = src.substring(cap[0].length);
- this.tokens.push({
- type: 'code',
- lang: cap[2],
- text: cap[3]
- });
- continue;
- }
-
- // heading
- if (cap = this.rules.heading.exec(src)) {
- src = src.substring(cap[0].length);
- this.tokens.push({
- type: 'heading',
- depth: cap[1].length,
- text: cap[2]
- });
- continue;
- }
-
- // table no leading pipe (gfm)
- if (top && (cap = this.rules.nptable.exec(src))) {
- src = src.substring(cap[0].length);
-
- item = {
- type: 'table',
- header: cap[1].replace(/^ *| *\| *$/g, '').split(/ *\| */),
- align: cap[2].replace(/^ *|\| *$/g, '').split(/ *\| */),
- cells: cap[3].replace(/\n$/, '').split('\n')
- };
-
- for (i = 0; i < item.align.length; i++) {
- if (/^ *-+: *$/.test(item.align[i])) {
- item.align[i] = 'right';
- } else if (/^ *:-+: *$/.test(item.align[i])) {
- item.align[i] = 'center';
- } else if (/^ *:-+ *$/.test(item.align[i])) {
- item.align[i] = 'left';
- } else {
- item.align[i] = null;
- }
- }
-
- for (i = 0; i < item.cells.length; i++) {
- item.cells[i] = item.cells[i].split(/ *\| */);
- }
-
- this.tokens.push(item);
-
- continue;
- }
-
- // lheading
- if (cap = this.rules.lheading.exec(src)) {
- src = src.substring(cap[0].length);
- this.tokens.push({
- type: 'heading',
- depth: cap[2] === '=' ? 1 : 2,
- text: cap[1]
- });
- continue;
- }
-
- // hr
- if (cap = this.rules.hr.exec(src)) {
- src = src.substring(cap[0].length);
- this.tokens.push({
- type: 'hr'
- });
- continue;
- }
-
- // blockquote
- if (cap = this.rules.blockquote.exec(src)) {
- src = src.substring(cap[0].length);
-
- this.tokens.push({
- type: 'blockquote_start'
- });
-
- cap = cap[0].replace(/^ *> ?/gm, '');
-
- // Pass `top` to keep the current
- // "toplevel" state. This is exactly
- // how markdown.pl works.
- this.token(cap, top, true);
-
- this.tokens.push({
- type: 'blockquote_end'
- });
-
- continue;
- }
-
- // list
- if (cap = this.rules.list.exec(src)) {
- src = src.substring(cap[0].length);
- bull = cap[2];
-
- this.tokens.push({
- type: 'list_start',
- ordered: bull.length > 1
- });
-
- // Get each top-level item.
- cap = cap[0].match(this.rules.item);
-
- next = false;
- l = cap.length;
- i = 0;
-
- for (; i < l; i++) {
- item = cap[i];
-
- // Remove the list item's bullet
- // so it is seen as the next token.
- space = item.length;
- item = item.replace(/^ *([*+-]|\d+\.) +/, '');
-
- // Outdent whatever the
- // list item contains. Hacky.
- if (~item.indexOf('\n ')) {
- space -= item.length;
- item = !this.options.pedantic
- ? item.replace(new RegExp('^ {1,' + space + '}', 'gm'), '')
- : item.replace(/^ {1,4}/gm, '');
- }
-
- // Determine whether the next list item belongs here.
- // Backpedal if it does not belong in this list.
- if (this.options.smartLists && i !== l - 1) {
- b = block.bullet.exec(cap[i + 1])[0];
- if (bull !== b && !(bull.length > 1 && b.length > 1)) {
- src = cap.slice(i + 1).join('\n') + src;
- i = l - 1;
- }
- }
-
- // Determine whether item is loose or not.
- // Use: /(^|\n)(?! )[^\n]+\n\n(?!\s*$)/
- // for discount behavior.
- loose = next || /\n\n(?!\s*$)/.test(item);
- if (i !== l - 1) {
- next = item.charAt(item.length - 1) === '\n';
- if (!loose) loose = next;
- }
-
- this.tokens.push({
- type: loose
- ? 'loose_item_start'
- : 'list_item_start'
- });
-
- // Recurse.
- this.token(item, false, bq);
-
- this.tokens.push({
- type: 'list_item_end'
- });
- }
-
- this.tokens.push({
- type: 'list_end'
- });
-
- continue;
- }
-
- // html
- if (cap = this.rules.html.exec(src)) {
- src = src.substring(cap[0].length);
- this.tokens.push({
- type: this.options.sanitize
- ? 'paragraph'
- : 'html',
- pre: cap[1] === 'pre' || cap[1] === 'script' || cap[1] === 'style',
- text: cap[0]
- });
- continue;
- }
-
- // def
- if ((!bq && top) && (cap = this.rules.def.exec(src))) {
- src = src.substring(cap[0].length);
- this.tokens.links[cap[1].toLowerCase()] = {
- href: cap[2],
- title: cap[3]
- };
- continue;
- }
-
- // table (gfm)
- if (top && (cap = this.rules.table.exec(src))) {
- src = src.substring(cap[0].length);
-
- item = {
- type: 'table',
- header: cap[1].replace(/^ *| *\| *$/g, '').split(/ *\| */),
- align: cap[2].replace(/^ *|\| *$/g, '').split(/ *\| */),
- cells: cap[3].replace(/(?: *\| *)?\n$/, '').split('\n')
- };
-
- for (i = 0; i < item.align.length; i++) {
- if (/^ *-+: *$/.test(item.align[i])) {
- item.align[i] = 'right';
- } else if (/^ *:-+: *$/.test(item.align[i])) {
- item.align[i] = 'center';
- } else if (/^ *:-+ *$/.test(item.align[i])) {
- item.align[i] = 'left';
- } else {
- item.align[i] = null;
- }
- }
-
- for (i = 0; i < item.cells.length; i++) {
- item.cells[i] = item.cells[i]
- .replace(/^ *\| *| *\| *$/g, '')
- .split(/ *\| */);
- }
-
- this.tokens.push(item);
-
- continue;
- }
-
- // top-level paragraph
- if (top && (cap = this.rules.paragraph.exec(src))) {
- src = src.substring(cap[0].length);
- this.tokens.push({
- type: 'paragraph',
- text: cap[1].charAt(cap[1].length - 1) === '\n'
- ? cap[1].slice(0, -1)
- : cap[1]
- });
- continue;
- }
-
- // text
- if (cap = this.rules.text.exec(src)) {
- // Top-level should never reach here.
- src = src.substring(cap[0].length);
- this.tokens.push({
- type: 'text',
- text: cap[0]
- });
- continue;
- }
-
- if (src) {
- throw new
- Error('Infinite loop on byte: ' + src.charCodeAt(0));
- }
- }
-
- return this.tokens;
-};
-
-/**
- * Inline-Level Grammar
- */
-
-var inline = {
- escape: /^\\([\\`*{}\[\]()#+\-.!_>])/,
- autolink: /^<([^ >]+(@|:\/)[^ >]+)>/,
- url: noop,
- tag: /^<!--[\s\S]*?-->|^<\/?\w+(?:"[^"]*"|'[^']*'|[^'">])*?>/,
- link: /^!?\[(inside)\]\(href\)/,
- reflink: /^!?\[(inside)\]\s*\[([^\]]*)\]/,
- nolink: /^!?\[((?:\[[^\]]*\]|[^\[\]])*)\]/,
- strong: /^__([\s\S]+?)__(?!_)|^\*\*([\s\S]+?)\*\*(?!\*)/,
- em: /^\b_((?:__|[\s\S])+?)_\b|^\*((?:\*\*|[\s\S])+?)\*(?!\*)/,
- code: /^(`+)\s*([\s\S]*?[^`])\s*\1(?!`)/,
- br: /^ {2,}\n(?!\s*$)/,
- del: noop,
- text: /^[\s\S]+?(?=[\\<!\[_*`]| {2,}\n|$)/
-};
-
-inline._inside = /(?:\[[^\]]*\]|[^\[\]]|\](?=[^\[]*\]))*/;
-inline._href = /\s*<?([\s\S]*?)>?(?:\s+['"]([\s\S]*?)['"])?\s*/;
-
-inline.link = replace(inline.link)
- ('inside', inline._inside)
- ('href', inline._href)
- ();
-
-inline.reflink = replace(inline.reflink)
- ('inside', inline._inside)
- ();
-
-/**
- * Normal Inline Grammar
- */
-
-inline.normal = merge({}, inline);
-
-/**
- * Pedantic Inline Grammar
- */
-
-inline.pedantic = merge({}, inline.normal, {
- strong: /^__(?=\S)([\s\S]*?\S)__(?!_)|^\*\*(?=\S)([\s\S]*?\S)\*\*(?!\*)/,
- em: /^_(?=\S)([\s\S]*?\S)_(?!_)|^\*(?=\S)([\s\S]*?\S)\*(?!\*)/
-});
-
-/**
- * GFM Inline Grammar
- */
-
-inline.gfm = merge({}, inline.normal, {
- escape: replace(inline.escape)('])', '~|])')(),
- url: /^(https?:\/\/[^\s<]+[^<.,:;"')\]\s])/,
- del: /^~~(?=\S)([\s\S]*?\S)~~/,
- text: replace(inline.text)
- (']|', '~]|')
- ('|', '|https?://|')
- ()
-});
-
-/**
- * GFM + Line Breaks Inline Grammar
- */
-
-inline.breaks = merge({}, inline.gfm, {
- br: replace(inline.br)('{2,}', '*')(),
- text: replace(inline.gfm.text)('{2,}', '*')()
-});
-
-/**
- * Inline Lexer & Compiler
- */
-
-function InlineLexer(links, options) {
- this.options = options || marked.defaults;
- this.links = links;
- this.rules = inline.normal;
- this.renderer = this.options.renderer || new Renderer;
- this.renderer.options = this.options;
-
- if (!this.links) {
- throw new
- Error('Tokens array requires a `links` property.');
- }
-
- if (this.options.gfm) {
- if (this.options.breaks) {
- this.rules = inline.breaks;
- } else {
- this.rules = inline.gfm;
- }
- } else if (this.options.pedantic) {
- this.rules = inline.pedantic;
- }
-}
-
-/**
- * Expose Inline Rules
- */
-
-InlineLexer.rules = inline;
-
-/**
- * Static Lexing/Compiling Method
- */
-
-InlineLexer.output = function(src, links, options) {
- var inline = new InlineLexer(links, options);
- return inline.output(src);
-};
-
-/**
- * Lexing/Compiling
- */
-
-InlineLexer.prototype.output = function(src) {
- var out = ''
- , link
- , text
- , href
- , cap;
-
- while (src) {
- // escape
- if (cap = this.rules.escape.exec(src)) {
- src = src.substring(cap[0].length);
- out += cap[1];
- continue;
- }
-
- // autolink
- if (cap = this.rules.autolink.exec(src)) {
- src = src.substring(cap[0].length);
- if (cap[2] === '@') {
- text = cap[1].charAt(6) === ':'
- ? this.mangle(cap[1].substring(7))
- : this.mangle(cap[1]);
- href = this.mangle('mailto:') + text;
- } else {
- text = escape(cap[1]);
- href = text;
- }
- out += this.renderer.link(href, null, text);
- continue;
- }
-
- // url (gfm)
- if (!this.inLink && (cap = this.rules.url.exec(src))) {
- src = src.substring(cap[0].length);
- text = escape(cap[1]);
- href = text;
- out += this.renderer.link(href, null, text);
- continue;
- }
-
- // tag
- if (cap = this.rules.tag.exec(src)) {
- if (!this.inLink && /^<a /i.test(cap[0])) {
- this.inLink = true;
- } else if (this.inLink && /^<\/a>/i.test(cap[0])) {
- this.inLink = false;
- }
- src = src.substring(cap[0].length);
- out += this.options.sanitize
- ? escape(cap[0])
- : cap[0];
- continue;
- }
-
- // link
- if (cap = this.rules.link.exec(src)) {
- src = src.substring(cap[0].length);
- this.inLink = true;
- out += this.outputLink(cap, {
- href: cap[2],
- title: cap[3]
- });
- this.inLink = false;
- continue;
- }
-
- // reflink, nolink
- if ((cap = this.rules.reflink.exec(src))
- || (cap = this.rules.nolink.exec(src))) {
- src = src.substring(cap[0].length);
- link = (cap[2] || cap[1]).replace(/\s+/g, ' ');
- link = this.links[link.toLowerCase()];
- if (!link || !link.href) {
- out += cap[0].charAt(0);
- src = cap[0].substring(1) + src;
- continue;
- }
- this.inLink = true;
- out += this.outputLink(cap, link);
- this.inLink = false;
- continue;
- }
-
- // strong
- if (cap = this.rules.strong.exec(src)) {
- src = src.substring(cap[0].length);
- out += this.renderer.strong(this.output(cap[2] || cap[1]));
- continue;
- }
-
- // em
- if (cap = this.rules.em.exec(src)) {
- src = src.substring(cap[0].length);
- out += this.renderer.em(this.output(cap[2] || cap[1]));
- continue;
- }
-
- // code
- if (cap = this.rules.code.exec(src)) {
- src = src.substring(cap[0].length);
- out += this.renderer.codespan(escape(cap[2], true));
- continue;
- }
-
- // br
- if (cap = this.rules.br.exec(src)) {
- src = src.substring(cap[0].length);
- out += this.renderer.br();
- continue;
- }
-
- // del (gfm)
- if (cap = this.rules.del.exec(src)) {
- src = src.substring(cap[0].length);
- out += this.renderer.del(this.output(cap[1]));
- continue;
- }
-
- // text
- if (cap = this.rules.text.exec(src)) {
- src = src.substring(cap[0].length);
- out += escape(this.smartypants(cap[0]));
- continue;
- }
-
- if (src) {
- throw new
- Error('Infinite loop on byte: ' + src.charCodeAt(0));
- }
- }
-
- return out;
-};
-
-/**
- * Compile Link
- */
-
-InlineLexer.prototype.outputLink = function(cap, link) {
- var href = escape(link.href)
- , title = link.title ? escape(link.title) : null;
-
- return cap[0].charAt(0) !== '!'
- ? this.renderer.link(href, title, this.output(cap[1]))
- : this.renderer.image(href, title, escape(cap[1]));
-};
-
-/**
- * Smartypants Transformations
- */
-
-InlineLexer.prototype.smartypants = function(text) {
- if (!this.options.smartypants) return text;
- return text
- // em-dashes
- .replace(/--/g, '\u2014')
- // opening singles
- .replace(/(^|[-\u2014/(\[{"\s])'/g, '$1\u2018')
- // closing singles & apostrophes
- .replace(/'/g, '\u2019')
- // opening doubles
- .replace(/(^|[-\u2014/(\[{\u2018\s])"/g, '$1\u201c')
- // closing doubles
- .replace(/"/g, '\u201d')
- // ellipses
- .replace(/\.{3}/g, '\u2026');
-};
-
-/**
- * Mangle Links
- */
-
-InlineLexer.prototype.mangle = function(text) {
- var out = ''
- , l = text.length
- , i = 0
- , ch;
-
- for (; i < l; i++) {
- ch = text.charCodeAt(i);
- if (Math.random() > 0.5) {
- ch = 'x' + ch.toString(16);
- }
- out += '&#' + ch + ';';
- }
-
- return out;
-};
-
-/**
- * Renderer
- */
-
-function Renderer(options) {
- this.options = options || {};
-}
-
-Renderer.prototype.code = function(code, lang, escaped) {
- if (this.options.highlight) {
- var out = this.options.highlight(code, lang);
- if (out != null && out !== code) {
- escaped = true;
- code = out;
- }
- }
-
- if (!lang) {
- return '<pre><code>'
- + (escaped ? code : escape(code, true))
- + '\n</code></pre>';
- }
-
- return '<pre><code class="'
- + this.options.langPrefix
- + escape(lang, true)
- + '">'
- + (escaped ? code : escape(code, true))
- + '\n</code></pre>\n';
-};
-
-Renderer.prototype.blockquote = function(quote) {
- return '<blockquote>\n' + quote + '</blockquote>\n';
-};
-
-Renderer.prototype.html = function(html) {
- return html;
-};
-
-Renderer.prototype.heading = function(text, level, raw) {
- return '<h'
- + level
- + ' id="'
- + this.options.headerPrefix
- + raw.toLowerCase().replace(/[^\w]+/g, '-')
- + '">'
- + text
- + '</h'
- + level
- + '>\n';
-};
-
-Renderer.prototype.hr = function() {
- return this.options.xhtml ? '<hr/>\n' : '<hr>\n';
-};
-
-Renderer.prototype.list = function(body, ordered) {
- var type = ordered ? 'ol' : 'ul';
- return '<' + type + '>\n' + body + '</' + type + '>\n';
-};
-
-Renderer.prototype.listitem = function(text) {
- return '<li>' + text + '</li>\n';
-};
-
-Renderer.prototype.paragraph = function(text) {
- return '<p>' + text + '</p>\n';
-};
-
-Renderer.prototype.table = function(header, body) {
- return '<table>\n'
- + '<thead>\n'
- + header
- + '</thead>\n'
- + '<tbody>\n'
- + body
- + '</tbody>\n'
- + '</table>\n';
-};
-
-Renderer.prototype.tablerow = function(content) {
- return '<tr>\n' + content + '</tr>\n';
-};
-
-Renderer.prototype.tablecell = function(content, flags) {
- var type = flags.header ? 'th' : 'td';
- var tag = flags.align
- ? '<' + type + ' style="text-align:' + flags.align + '">'
- : '<' + type + '>';
- return tag + content + '</' + type + '>\n';
-};
-
-// span level renderer
-Renderer.prototype.strong = function(text) {
- return '<strong>' + text + '</strong>';
-};
-
-Renderer.prototype.em = function(text) {
- return '<em>' + text + '</em>';
-};
-
-Renderer.prototype.codespan = function(text) {
- return '<code>' + text + '</code>';
-};
-
-Renderer.prototype.br = function() {
- return this.options.xhtml ? '<br/>' : '<br>';
-};
-
-Renderer.prototype.del = function(text) {
- return '<del>' + text + '</del>';
-};
-
-Renderer.prototype.link = function(href, title, text) {
- if (this.options.sanitize) {
- try {
- var prot = decodeURIComponent(unescape(href))
- .replace(/[^\w:]/g, '')
- .toLowerCase();
- } catch (e) {
- return '';
- }
- if (prot.indexOf('javascript:') === 0) {
- return '';
- }
- }
- var out = '<a href="' + href + '"';
- if (title) {
- out += ' title="' + title + '"';
- }
- out += '>' + text + '</a>';
- return out;
-};
-
-Renderer.prototype.image = function(href, title, text) {
- var out = '<img src="' + href + '" alt="' + text + '"';
- if (title) {
- out += ' title="' + title + '"';
- }
- out += this.options.xhtml ? '/>' : '>';
- return out;
-};
-
-/**
- * Parsing & Compiling
- */
-
-function Parser(options) {
- this.tokens = [];
- this.token = null;
- this.options = options || marked.defaults;
- this.options.renderer = this.options.renderer || new Renderer;
- this.renderer = this.options.renderer;
- this.renderer.options = this.options;
-}
-
-/**
- * Static Parse Method
- */
-
-Parser.parse = function(src, options, renderer) {
- var parser = new Parser(options, renderer);
- return parser.parse(src);
-};
-
-/**
- * Parse Loop
- */
-
-Parser.prototype.parse = function(src) {
- this.inline = new InlineLexer(src.links, this.options, this.renderer);
- this.tokens = src.reverse();
-
- var out = '';
- while (this.next()) {
- out += this.tok();
- }
-
- return out;
-};
-
-/**
- * Next Token
- */
-
-Parser.prototype.next = function() {
- return this.token = this.tokens.pop();
-};
-
-/**
- * Preview Next Token
- */
-
-Parser.prototype.peek = function() {
- return this.tokens[this.tokens.length - 1] || 0;
-};
-
-/**
- * Parse Text Tokens
- */
-
-Parser.prototype.parseText = function() {
- var body = this.token.text;
-
- while (this.peek().type === 'text') {
- body += '\n' + this.next().text;
- }
-
- return this.inline.output(body);
-};
-
-/**
- * Parse Current Token
- */
-
-Parser.prototype.tok = function() {
- switch (this.token.type) {
- case 'space': {
- return '';
- }
- case 'hr': {
- return this.renderer.hr();
- }
- case 'heading': {
- return this.renderer.heading(
- this.inline.output(this.token.text),
- this.token.depth,
- this.token.text);
- }
- case 'code': {
- return this.renderer.code(this.token.text,
- this.token.lang,
- this.token.escaped);
- }
- case 'table': {
- var header = ''
- , body = ''
- , i
- , row
- , cell
- , flags
- , j;
-
- // header
- cell = '';
- for (i = 0; i < this.token.header.length; i++) {
- flags = { header: true, align: this.token.align[i] };
- cell += this.renderer.tablecell(
- this.inline.output(this.token.header[i]),
- { header: true, align: this.token.align[i] }
- );
- }
- header += this.renderer.tablerow(cell);
-
- for (i = 0; i < this.token.cells.length; i++) {
- row = this.token.cells[i];
-
- cell = '';
- for (j = 0; j < row.length; j++) {
- cell += this.renderer.tablecell(
- this.inline.output(row[j]),
- { header: false, align: this.token.align[j] }
- );
- }
-
- body += this.renderer.tablerow(cell);
- }
- return this.renderer.table(header, body);
- }
- case 'blockquote_start': {
- var body = '';
-
- while (this.next().type !== 'blockquote_end') {
- body += this.tok();
- }
-
- return this.renderer.blockquote(body);
- }
- case 'list_start': {
- var body = ''
- , ordered = this.token.ordered;
-
- while (this.next().type !== 'list_end') {
- body += this.tok();
- }
-
- return this.renderer.list(body, ordered);
- }
- case 'list_item_start': {
- var body = '';
-
- while (this.next().type !== 'list_item_end') {
- body += this.token.type === 'text'
- ? this.parseText()
- : this.tok();
- }
-
- return this.renderer.listitem(body);
- }
- case 'loose_item_start': {
- var body = '';
-
- while (this.next().type !== 'list_item_end') {
- body += this.tok();
- }
-
- return this.renderer.listitem(body);
- }
- case 'html': {
- var html = !this.token.pre && !this.options.pedantic
- ? this.inline.output(this.token.text)
- : this.token.text;
- return this.renderer.html(html);
- }
- case 'paragraph': {
- return this.renderer.paragraph(this.inline.output(this.token.text));
- }
- case 'text': {
- return this.renderer.paragraph(this.parseText());
- }
- }
-};
-
-/**
- * Helpers
- */
-
-function escape(html, encode) {
- return html
- .replace(!encode ? /&(?!#?\w+;)/g : /&/g, '&amp;')
- .replace(/</g, '&lt;')
- .replace(/>/g, '&gt;')
- .replace(/"/g, '&quot;')
- .replace(/'/g, '&#39;');
-}
-
-function unescape(html) {
- return html.replace(/&([#\w]+);/g, function(_, n) {
- n = n.toLowerCase();
- if (n === 'colon') return ':';
- if (n.charAt(0) === '#') {
- return n.charAt(1) === 'x'
- ? String.fromCharCode(parseInt(n.substring(2), 16))
- : String.fromCharCode(+n.substring(1));
- }
- return '';
- });
-}
-
-function replace(regex, opt) {
- regex = regex.source;
- opt = opt || '';
- return function self(name, val) {
- if (!name) return new RegExp(regex, opt);
- val = val.source || val;
- val = val.replace(/(^|[^\[])\^/g, '$1');
- regex = regex.replace(name, val);
- return self;
- };
-}
-
-function noop() {}
-noop.exec = noop;
-
-function merge(obj) {
- var i = 1
- , target
- , key;
-
- for (; i < arguments.length; i++) {
- target = arguments[i];
- for (key in target) {
- if (Object.prototype.hasOwnProperty.call(target, key)) {
- obj[key] = target[key];
- }
- }
- }
-
- return obj;
-}
-
-
-/**
- * Marked
- */
-
-function marked(src, opt, callback) {
- if (callback || typeof opt === 'function') {
- if (!callback) {
- callback = opt;
- opt = null;
- }
-
- opt = merge({}, marked.defaults, opt || {});
-
- var highlight = opt.highlight
- , tokens
- , pending
- , i = 0;
-
- try {
- tokens = Lexer.lex(src, opt)
- } catch (e) {
- return callback(e);
- }
-
- pending = tokens.length;
-
- var done = function(err) {
- if (err) {
- opt.highlight = highlight;
- return callback(err);
- }
-
- var out;
-
- try {
- out = Parser.parse(tokens, opt);
- } catch (e) {
- err = e;
- }
-
- opt.highlight = highlight;
-
- return err
- ? callback(err)
- : callback(null, out);
- };
-
- if (!highlight || highlight.length < 3) {
- return done();
- }
-
- delete opt.highlight;
-
- if (!pending) return done();
-
- for (; i < tokens.length; i++) {
- (function(token) {
- if (token.type !== 'code') {
- return --pending || done();
- }
- return highlight(token.text, token.lang, function(err, code) {
- if (err) return done(err);
- if (code == null || code === token.text) {
- return --pending || done();
- }
- token.text = code;
- token.escaped = true;
- --pending || done();
- });
- })(tokens[i]);
- }
-
- return;
- }
- try {
- if (opt) opt = merge({}, marked.defaults, opt);
- return Parser.parse(Lexer.lex(src, opt), opt);
- } catch (e) {
- e.message += '\nPlease report this to https://github.com/chjj/marked.';
- if ((opt || marked.defaults).silent) {
- return '<p>An error occured:</p><pre>'
- + escape(e.message + '', true)
- + '</pre>';
- }
- throw e;
- }
-}
-
-/**
- * Options
- */
-
-marked.options =
-marked.setOptions = function(opt) {
- merge(marked.defaults, opt);
- return marked;
-};
-
-marked.defaults = {
- gfm: true,
- tables: true,
- breaks: false,
- pedantic: false,
- sanitize: false,
- smartLists: false,
- silent: false,
- highlight: null,
- langPrefix: 'lang-',
- smartypants: false,
- headerPrefix: '',
- renderer: new Renderer,
- xhtml: false
-};
-
-/**
- * Expose
- */
-
-marked.Parser = Parser;
-marked.parser = Parser.parse;
-
-marked.Renderer = Renderer;
-
-marked.Lexer = Lexer;
-marked.lexer = Lexer.lex;
-
-marked.InlineLexer = InlineLexer;
-marked.inlineLexer = InlineLexer.output;
-
-marked.parse = marked;
-
-if (typeof module !== 'undefined' && typeof exports === 'object') {
- module.exports = marked;
-} else if (typeof define === 'function' && define.amd) {
- define(function() { return marked; });
-} else {
- this.marked = marked;
-}
-
-}).call(function() {
- return this || (typeof window !== 'undefined' ? window : global);
-}()); \ No newline at end of file
+/**
+ * marked - a markdown parser
+ * Copyright (c) 2011-2014, Christopher Jeffrey. (MIT Licensed)
+ * https://github.com/chjj/marked
+ */
+
+;(function() {
+
+/**
+ * Block-Level Grammar
+ */
+
+var block = {
+ newline: /^\n+/,
+ code: /^( {4}[^\n]+\n*)+/,
+ fences: noop,
+ hr: /^( *[-*_]){3,} *(?:\n+|$)/,
+ heading: /^ *(#{1,6}) *([^\n]+?) *#* *(?:\n+|$)/,
+ nptable: noop,
+ lheading: /^([^\n]+)\n *(=|-){2,} *(?:\n+|$)/,
+ blockquote: /^( *>[^\n]+(\n(?!def)[^\n]+)*\n*)+/,
+ list: /^( *)(bull) [\s\S]+?(?:hr|def|\n{2,}(?! )(?!\1bull )\n*|\s*$)/,
+ html: /^ *(?:comment *(?:\n|\s*$)|closed *(?:\n{2,}|\s*$)|closing *(?:\n{2,}|\s*$))/,
+ def: /^ *\[([^\]]+)\]: *<?([^\s>]+)>?(?: +["(]([^\n]+)[")])? *(?:\n+|$)/,
+ table: noop,
+ paragraph: /^((?:[^\n]+\n?(?!hr|heading|lheading|blockquote|tag|def))+)\n*/,
+ text: /^[^\n]+/
+};
+
+block.bullet = /(?:[*+-]|\d+\.)/;
+block.item = /^( *)(bull) [^\n]*(?:\n(?!\1bull )[^\n]*)*/;
+block.item = replace(block.item, 'gm')
+ (/bull/g, block.bullet)
+ ();
+
+block.list = replace(block.list)
+ (/bull/g, block.bullet)
+ ('hr', '\\n+(?=\\1?(?:[-*_] *){3,}(?:\\n+|$))')
+ ('def', '\\n+(?=' + block.def.source + ')')
+ ();
+
+block.blockquote = replace(block.blockquote)
+ ('def', block.def)
+ ();
+
+block._tag = '(?!(?:'
+ + 'a|em|strong|small|s|cite|q|dfn|abbr|data|time|code'
+ + '|var|samp|kbd|sub|sup|i|b|u|mark|ruby|rt|rp|bdi|bdo'
+ + '|span|br|wbr|ins|del|img)\\b)\\w+(?!:/|[^\\w\\s@]*@)\\b';
+
+block.html = replace(block.html)
+ ('comment', /<!--[\s\S]*?-->/)
+ ('closed', /<(tag)[\s\S]+?<\/\1>/)
+ ('closing', /<tag(?:"[^"]*"|'[^']*'|[^'">])*?>/)
+ (/tag/g, block._tag)
+ ();
+
+block.paragraph = replace(block.paragraph)
+ ('hr', block.hr)
+ ('heading', block.heading)
+ ('lheading', block.lheading)
+ ('blockquote', block.blockquote)
+ ('tag', '<' + block._tag)
+ ('def', block.def)
+ ();
+
+/**
+ * Normal Block Grammar
+ */
+
+block.normal = merge({}, block);
+
+/**
+ * GFM Block Grammar
+ */
+
+block.gfm = merge({}, block.normal, {
+ fences: /^ *(`{3,}|~{3,}) *(\S+)? *\n([\s\S]+?)\s*\1 *(?:\n+|$)/,
+ paragraph: /^/
+});
+
+block.gfm.paragraph = replace(block.paragraph)
+ ('(?!', '(?!'
+ + block.gfm.fences.source.replace('\\1', '\\2') + '|'
+ + block.list.source.replace('\\1', '\\3') + '|')
+ ();
+
+/**
+ * GFM + Tables Block Grammar
+ */
+
+block.tables = merge({}, block.gfm, {
+ nptable: /^ *(\S.*\|.*)\n *([-:]+ *\|[-| :]*)\n((?:.*\|.*(?:\n|$))*)\n*/,
+ table: /^ *\|(.+)\n *\|( *[-:]+[-| :]*)\n((?: *\|.*(?:\n|$))*)\n*/
+});
+
+/**
+ * Block Lexer
+ */
+
+function Lexer(options) {
+ this.tokens = [];
+ this.tokens.links = {};
+ this.options = options || marked.defaults;
+ this.rules = block.normal;
+
+ if (this.options.gfm) {
+ if (this.options.tables) {
+ this.rules = block.tables;
+ } else {
+ this.rules = block.gfm;
+ }
+ }
+}
+
+/**
+ * Expose Block Rules
+ */
+
+Lexer.rules = block;
+
+/**
+ * Static Lex Method
+ */
+
+Lexer.lex = function(src, options) {
+ var lexer = new Lexer(options);
+ return lexer.lex(src);
+};
+
+/**
+ * Preprocessing
+ */
+
+Lexer.prototype.lex = function(src) {
+ src = src
+ .replace(/\r\n|\r/g, '\n')
+ .replace(/\t/g, ' ')
+ .replace(/\u00a0/g, ' ')
+ .replace(/\u2424/g, '\n');
+
+ return this.token(src, true);
+};
+
+/**
+ * Lexing
+ */
+
+Lexer.prototype.token = function(src, top, bq) {
+ var src = src.replace(/^ +$/gm, '')
+ , next
+ , loose
+ , cap
+ , bull
+ , b
+ , item
+ , space
+ , i
+ , l;
+
+ while (src) {
+ // newline
+ if (cap = this.rules.newline.exec(src)) {
+ src = src.substring(cap[0].length);
+ if (cap[0].length > 1) {
+ this.tokens.push({
+ type: 'space'
+ });
+ }
+ }
+
+ // code
+ if (cap = this.rules.code.exec(src)) {
+ src = src.substring(cap[0].length);
+ cap = cap[0].replace(/^ {4}/gm, '');
+ this.tokens.push({
+ type: 'code',
+ text: !this.options.pedantic
+ ? cap.replace(/\n+$/, '')
+ : cap
+ });
+ continue;
+ }
+
+ // fences (gfm)
+ if (cap = this.rules.fences.exec(src)) {
+ src = src.substring(cap[0].length);
+ this.tokens.push({
+ type: 'code',
+ lang: cap[2],
+ text: cap[3]
+ });
+ continue;
+ }
+
+ // heading
+ if (cap = this.rules.heading.exec(src)) {
+ src = src.substring(cap[0].length);
+ this.tokens.push({
+ type: 'heading',
+ depth: cap[1].length,
+ text: cap[2]
+ });
+ continue;
+ }
+
+ // table no leading pipe (gfm)
+ if (top && (cap = this.rules.nptable.exec(src))) {
+ src = src.substring(cap[0].length);
+
+ item = {
+ type: 'table',
+ header: cap[1].replace(/^ *| *\| *$/g, '').split(/ *\| */),
+ align: cap[2].replace(/^ *|\| *$/g, '').split(/ *\| */),
+ cells: cap[3].replace(/\n$/, '').split('\n')
+ };
+
+ for (i = 0; i < item.align.length; i++) {
+ if (/^ *-+: *$/.test(item.align[i])) {
+ item.align[i] = 'right';
+ } else if (/^ *:-+: *$/.test(item.align[i])) {
+ item.align[i] = 'center';
+ } else if (/^ *:-+ *$/.test(item.align[i])) {
+ item.align[i] = 'left';
+ } else {
+ item.align[i] = null;
+ }
+ }
+
+ for (i = 0; i < item.cells.length; i++) {
+ item.cells[i] = item.cells[i].split(/ *\| */);
+ }
+
+ this.tokens.push(item);
+
+ continue;
+ }
+
+ // lheading
+ if (cap = this.rules.lheading.exec(src)) {
+ src = src.substring(cap[0].length);
+ this.tokens.push({
+ type: 'heading',
+ depth: cap[2] === '=' ? 1 : 2,
+ text: cap[1]
+ });
+ continue;
+ }
+
+ // hr
+ if (cap = this.rules.hr.exec(src)) {
+ src = src.substring(cap[0].length);
+ this.tokens.push({
+ type: 'hr'
+ });
+ continue;
+ }
+
+ // blockquote
+ if (cap = this.rules.blockquote.exec(src)) {
+ src = src.substring(cap[0].length);
+
+ this.tokens.push({
+ type: 'blockquote_start'
+ });
+
+ cap = cap[0].replace(/^ *> ?/gm, '');
+
+ // Pass `top` to keep the current
+ // "toplevel" state. This is exactly
+ // how markdown.pl works.
+ this.token(cap, top, true);
+
+ this.tokens.push({
+ type: 'blockquote_end'
+ });
+
+ continue;
+ }
+
+ // list
+ if (cap = this.rules.list.exec(src)) {
+ src = src.substring(cap[0].length);
+ bull = cap[2];
+
+ this.tokens.push({
+ type: 'list_start',
+ ordered: bull.length > 1
+ });
+
+ // Get each top-level item.
+ cap = cap[0].match(this.rules.item);
+
+ next = false;
+ l = cap.length;
+ i = 0;
+
+ for (; i < l; i++) {
+ item = cap[i];
+
+ // Remove the list item's bullet
+ // so it is seen as the next token.
+ space = item.length;
+ item = item.replace(/^ *([*+-]|\d+\.) +/, '');
+
+ // Outdent whatever the
+ // list item contains. Hacky.
+ if (~item.indexOf('\n ')) {
+ space -= item.length;
+ item = !this.options.pedantic
+ ? item.replace(new RegExp('^ {1,' + space + '}', 'gm'), '')
+ : item.replace(/^ {1,4}/gm, '');
+ }
+
+ // Determine whether the next list item belongs here.
+ // Backpedal if it does not belong in this list.
+ if (this.options.smartLists && i !== l - 1) {
+ b = block.bullet.exec(cap[i + 1])[0];
+ if (bull !== b && !(bull.length > 1 && b.length > 1)) {
+ src = cap.slice(i + 1).join('\n') + src;
+ i = l - 1;
+ }
+ }
+
+ // Determine whether item is loose or not.
+ // Use: /(^|\n)(?! )[^\n]+\n\n(?!\s*$)/
+ // for discount behavior.
+ loose = next || /\n\n(?!\s*$)/.test(item);
+ if (i !== l - 1) {
+ next = item.charAt(item.length - 1) === '\n';
+ if (!loose) loose = next;
+ }
+
+ this.tokens.push({
+ type: loose
+ ? 'loose_item_start'
+ : 'list_item_start'
+ });
+
+ // Recurse.
+ this.token(item, false, bq);
+
+ this.tokens.push({
+ type: 'list_item_end'
+ });
+ }
+
+ this.tokens.push({
+ type: 'list_end'
+ });
+
+ continue;
+ }
+
+ // html
+ if (cap = this.rules.html.exec(src)) {
+ src = src.substring(cap[0].length);
+ this.tokens.push({
+ type: this.options.sanitize
+ ? 'paragraph'
+ : 'html',
+ pre: cap[1] === 'pre' || cap[1] === 'script' || cap[1] === 'style',
+ text: cap[0]
+ });
+ continue;
+ }
+
+ // def
+ if ((!bq && top) && (cap = this.rules.def.exec(src))) {
+ src = src.substring(cap[0].length);
+ this.tokens.links[cap[1].toLowerCase()] = {
+ href: cap[2],
+ title: cap[3]
+ };
+ continue;
+ }
+
+ // table (gfm)
+ if (top && (cap = this.rules.table.exec(src))) {
+ src = src.substring(cap[0].length);
+
+ item = {
+ type: 'table',
+ header: cap[1].replace(/^ *| *\| *$/g, '').split(/ *\| */),
+ align: cap[2].replace(/^ *|\| *$/g, '').split(/ *\| */),
+ cells: cap[3].replace(/(?: *\| *)?\n$/, '').split('\n')
+ };
+
+ for (i = 0; i < item.align.length; i++) {
+ if (/^ *-+: *$/.test(item.align[i])) {
+ item.align[i] = 'right';
+ } else if (/^ *:-+: *$/.test(item.align[i])) {
+ item.align[i] = 'center';
+ } else if (/^ *:-+ *$/.test(item.align[i])) {
+ item.align[i] = 'left';
+ } else {
+ item.align[i] = null;
+ }
+ }
+
+ for (i = 0; i < item.cells.length; i++) {
+ item.cells[i] = item.cells[i]
+ .replace(/^ *\| *| *\| *$/g, '')
+ .split(/ *\| */);
+ }
+
+ this.tokens.push(item);
+
+ continue;
+ }
+
+ // top-level paragraph
+ if (top && (cap = this.rules.paragraph.exec(src))) {
+ src = src.substring(cap[0].length);
+ this.tokens.push({
+ type: 'paragraph',
+ text: cap[1].charAt(cap[1].length - 1) === '\n'
+ ? cap[1].slice(0, -1)
+ : cap[1]
+ });
+ continue;
+ }
+
+ // text
+ if (cap = this.rules.text.exec(src)) {
+ // Top-level should never reach here.
+ src = src.substring(cap[0].length);
+ this.tokens.push({
+ type: 'text',
+ text: cap[0]
+ });
+ continue;
+ }
+
+ if (src) {
+ throw new
+ Error('Infinite loop on byte: ' + src.charCodeAt(0));
+ }
+ }
+
+ return this.tokens;
+};
+
+/**
+ * Inline-Level Grammar
+ */
+
+var inline = {
+ escape: /^\\([\\`*{}\[\]()#+\-.!_>])/,
+ autolink: /^<([^ >]+(@|:\/)[^ >]+)>/,
+ url: noop,
+ tag: /^<!--[\s\S]*?-->|^<\/?\w+(?:"[^"]*"|'[^']*'|[^'">])*?>/,
+ link: /^!?\[(inside)\]\(href\)/,
+ reflink: /^!?\[(inside)\]\s*\[([^\]]*)\]/,
+ nolink: /^!?\[((?:\[[^\]]*\]|[^\[\]])*)\]/,
+ strong: /^__([\s\S]+?)__(?!_)|^\*\*([\s\S]+?)\*\*(?!\*)/,
+ em: /^\b_((?:__|[\s\S])+?)_\b|^\*((?:\*\*|[\s\S])+?)\*(?!\*)/,
+ code: /^(`+)\s*([\s\S]*?[^`])\s*\1(?!`)/,
+ br: /^ {2,}\n(?!\s*$)/,
+ del: noop,
+ text: /^[\s\S]+?(?=[\\<!\[_*`]| {2,}\n|$)/
+};
+
+inline._inside = /(?:\[[^\]]*\]|[^\[\]]|\](?=[^\[]*\]))*/;
+inline._href = /\s*<?([\s\S]*?)>?(?:\s+['"]([\s\S]*?)['"])?\s*/;
+
+inline.link = replace(inline.link)
+ ('inside', inline._inside)
+ ('href', inline._href)
+ ();
+
+inline.reflink = replace(inline.reflink)
+ ('inside', inline._inside)
+ ();
+
+/**
+ * Normal Inline Grammar
+ */
+
+inline.normal = merge({}, inline);
+
+/**
+ * Pedantic Inline Grammar
+ */
+
+inline.pedantic = merge({}, inline.normal, {
+ strong: /^__(?=\S)([\s\S]*?\S)__(?!_)|^\*\*(?=\S)([\s\S]*?\S)\*\*(?!\*)/,
+ em: /^_(?=\S)([\s\S]*?\S)_(?!_)|^\*(?=\S)([\s\S]*?\S)\*(?!\*)/
+});
+
+/**
+ * GFM Inline Grammar
+ */
+
+inline.gfm = merge({}, inline.normal, {
+ escape: replace(inline.escape)('])', '~|])')(),
+ url: /^(https?:\/\/[^\s<]+[^<.,:;"')\]\s])/,
+ del: /^~~(?=\S)([\s\S]*?\S)~~/,
+ text: replace(inline.text)
+ (']|', '~]|')
+ ('|', '|https?://|')
+ ()
+});
+
+/**
+ * GFM + Line Breaks Inline Grammar
+ */
+
+inline.breaks = merge({}, inline.gfm, {
+ br: replace(inline.br)('{2,}', '*')(),
+ text: replace(inline.gfm.text)('{2,}', '*')()
+});
+
+/**
+ * Inline Lexer & Compiler
+ */
+
+function InlineLexer(links, options) {
+ this.options = options || marked.defaults;
+ this.links = links;
+ this.rules = inline.normal;
+ this.renderer = this.options.renderer || new Renderer;
+ this.renderer.options = this.options;
+
+ if (!this.links) {
+ throw new
+ Error('Tokens array requires a `links` property.');
+ }
+
+ if (this.options.gfm) {
+ if (this.options.breaks) {
+ this.rules = inline.breaks;
+ } else {
+ this.rules = inline.gfm;
+ }
+ } else if (this.options.pedantic) {
+ this.rules = inline.pedantic;
+ }
+}
+
+/**
+ * Expose Inline Rules
+ */
+
+InlineLexer.rules = inline;
+
+/**
+ * Static Lexing/Compiling Method
+ */
+
+InlineLexer.output = function(src, links, options) {
+ var inline = new InlineLexer(links, options);
+ return inline.output(src);
+};
+
+/**
+ * Lexing/Compiling
+ */
+
+InlineLexer.prototype.output = function(src) {
+ var out = ''
+ , link
+ , text
+ , href
+ , cap;
+
+ while (src) {
+ // escape
+ if (cap = this.rules.escape.exec(src)) {
+ src = src.substring(cap[0].length);
+ out += cap[1];
+ continue;
+ }
+
+ // autolink
+ if (cap = this.rules.autolink.exec(src)) {
+ src = src.substring(cap[0].length);
+ if (cap[2] === '@') {
+ text = cap[1].charAt(6) === ':'
+ ? this.mangle(cap[1].substring(7))
+ : this.mangle(cap[1]);
+ href = this.mangle('mailto:') + text;
+ } else {
+ text = escape(cap[1]);
+ href = text;
+ }
+ out += this.renderer.link(href, null, text);
+ continue;
+ }
+
+ // url (gfm)
+ if (!this.inLink && (cap = this.rules.url.exec(src))) {
+ src = src.substring(cap[0].length);
+ text = escape(cap[1]);
+ href = text;
+ out += this.renderer.link(href, null, text);
+ continue;
+ }
+
+ // tag
+ if (cap = this.rules.tag.exec(src)) {
+ if (!this.inLink && /^<a /i.test(cap[0])) {
+ this.inLink = true;
+ } else if (this.inLink && /^<\/a>/i.test(cap[0])) {
+ this.inLink = false;
+ }
+ src = src.substring(cap[0].length);
+ out += this.options.sanitize
+ ? escape(cap[0])
+ : cap[0];
+ continue;
+ }
+
+ // link
+ if (cap = this.rules.link.exec(src)) {
+ src = src.substring(cap[0].length);
+ this.inLink = true;
+ out += this.outputLink(cap, {
+ href: cap[2],
+ title: cap[3]
+ });
+ this.inLink = false;
+ continue;
+ }
+
+ // reflink, nolink
+ if ((cap = this.rules.reflink.exec(src))
+ || (cap = this.rules.nolink.exec(src))) {
+ src = src.substring(cap[0].length);
+ link = (cap[2] || cap[1]).replace(/\s+/g, ' ');
+ link = this.links[link.toLowerCase()];
+ if (!link || !link.href) {
+ out += cap[0].charAt(0);
+ src = cap[0].substring(1) + src;
+ continue;
+ }
+ this.inLink = true;
+ out += this.outputLink(cap, link);
+ this.inLink = false;
+ continue;
+ }
+
+ // strong
+ if (cap = this.rules.strong.exec(src)) {
+ src = src.substring(cap[0].length);
+ out += this.renderer.strong(this.output(cap[2] || cap[1]));
+ continue;
+ }
+
+ // em
+ if (cap = this.rules.em.exec(src)) {
+ src = src.substring(cap[0].length);
+ out += this.renderer.em(this.output(cap[2] || cap[1]));
+ continue;
+ }
+
+ // code
+ if (cap = this.rules.code.exec(src)) {
+ src = src.substring(cap[0].length);
+ out += this.renderer.codespan(escape(cap[2], true));
+ continue;
+ }
+
+ // br
+ if (cap = this.rules.br.exec(src)) {
+ src = src.substring(cap[0].length);
+ out += this.renderer.br();
+ continue;
+ }
+
+ // del (gfm)
+ if (cap = this.rules.del.exec(src)) {
+ src = src.substring(cap[0].length);
+ out += this.renderer.del(this.output(cap[1]));
+ continue;
+ }
+
+ // text
+ if (cap = this.rules.text.exec(src)) {
+ src = src.substring(cap[0].length);
+ out += escape(this.smartypants(cap[0]));
+ continue;
+ }
+
+ if (src) {
+ throw new
+ Error('Infinite loop on byte: ' + src.charCodeAt(0));
+ }
+ }
+
+ return out;
+};
+
+/**
+ * Compile Link
+ */
+
+InlineLexer.prototype.outputLink = function(cap, link) {
+ var href = escape(link.href)
+ , title = link.title ? escape(link.title) : null;
+
+ return cap[0].charAt(0) !== '!'
+ ? this.renderer.link(href, title, this.output(cap[1]))
+ : this.renderer.image(href, title, escape(cap[1]));
+};
+
+/**
+ * Smartypants Transformations
+ */
+
+InlineLexer.prototype.smartypants = function(text) {
+ if (!this.options.smartypants) return text;
+ return text
+ // em-dashes
+ .replace(/--/g, '\u2014')
+ // opening singles
+ .replace(/(^|[-\u2014/(\[{"\s])'/g, '$1\u2018')
+ // closing singles & apostrophes
+ .replace(/'/g, '\u2019')
+ // opening doubles
+ .replace(/(^|[-\u2014/(\[{\u2018\s])"/g, '$1\u201c')
+ // closing doubles
+ .replace(/"/g, '\u201d')
+ // ellipses
+ .replace(/\.{3}/g, '\u2026');
+};
+
+/**
+ * Mangle Links
+ */
+
+InlineLexer.prototype.mangle = function(text) {
+ var out = ''
+ , l = text.length
+ , i = 0
+ , ch;
+
+ for (; i < l; i++) {
+ ch = text.charCodeAt(i);
+ if (Math.random() > 0.5) {
+ ch = 'x' + ch.toString(16);
+ }
+ out += '&#' + ch + ';';
+ }
+
+ return out;
+};
+
+/**
+ * Renderer
+ */
+
+function Renderer(options) {
+ this.options = options || {};
+}
+
+Renderer.prototype.code = function(code, lang, escaped) {
+ if (this.options.highlight) {
+ var out = this.options.highlight(code, lang);
+ if (out != null && out !== code) {
+ escaped = true;
+ code = out;
+ }
+ }
+
+ if (!lang) {
+ return '<pre><code>'
+ + (escaped ? code : escape(code, true))
+ + '\n</code></pre>';
+ }
+
+ return '<pre><code class="'
+ + this.options.langPrefix
+ + escape(lang, true)
+ + '">'
+ + (escaped ? code : escape(code, true))
+ + '\n</code></pre>\n';
+};
+
+Renderer.prototype.blockquote = function(quote) {
+ return '<blockquote>\n' + quote + '</blockquote>\n';
+};
+
+Renderer.prototype.html = function(html) {
+ return html;
+};
+
+Renderer.prototype.heading = function(text, level, raw) {
+ return '<h'
+ + level
+ + ' id="'
+ + this.options.headerPrefix
+ + raw.toLowerCase().replace(/[^\w]+/g, '-')
+ + '">'
+ + text
+ + '</h'
+ + level
+ + '>\n';
+};
+
+Renderer.prototype.hr = function() {
+ return this.options.xhtml ? '<hr/>\n' : '<hr>\n';
+};
+
+Renderer.prototype.list = function(body, ordered) {
+ var type = ordered ? 'ol' : 'ul';
+ return '<' + type + '>\n' + body + '</' + type + '>\n';
+};
+
+Renderer.prototype.listitem = function(text) {
+ return '<li>' + text + '</li>\n';
+};
+
+Renderer.prototype.paragraph = function(text) {
+ return '<p>' + text + '</p>\n';
+};
+
+Renderer.prototype.table = function(header, body) {
+ return '<table>\n'
+ + '<thead>\n'
+ + header
+ + '</thead>\n'
+ + '<tbody>\n'
+ + body
+ + '</tbody>\n'
+ + '</table>\n';
+};
+
+Renderer.prototype.tablerow = function(content) {
+ return '<tr>\n' + content + '</tr>\n';
+};
+
+Renderer.prototype.tablecell = function(content, flags) {
+ var type = flags.header ? 'th' : 'td';
+ var tag = flags.align
+ ? '<' + type + ' style="text-align:' + flags.align + '">'
+ : '<' + type + '>';
+ return tag + content + '</' + type + '>\n';
+};
+
+// span level renderer
+Renderer.prototype.strong = function(text) {
+ return '<strong>' + text + '</strong>';
+};
+
+Renderer.prototype.em = function(text) {
+ return '<em>' + text + '</em>';
+};
+
+Renderer.prototype.codespan = function(text) {
+ return '<code>' + text + '</code>';
+};
+
+Renderer.prototype.br = function() {
+ return this.options.xhtml ? '<br/>' : '<br>';
+};
+
+Renderer.prototype.del = function(text) {
+ return '<del>' + text + '</del>';
+};
+
+Renderer.prototype.link = function(href, title, text) {
+ if (this.options.sanitize) {
+ try {
+ var prot = decodeURIComponent(unescape(href))
+ .replace(/[^\w:]/g, '')
+ .toLowerCase();
+ } catch (e) {
+ return '';
+ }
+ if (prot.indexOf('javascript:') === 0) {
+ return '';
+ }
+ }
+ var out = '<a href="' + href + '"';
+ if (title) {
+ out += ' title="' + title + '"';
+ }
+ out += '>' + text + '</a>';
+ return out;
+};
+
+Renderer.prototype.image = function(href, title, text) {
+ var out = '<img src="' + href + '" alt="' + text + '"';
+ if (title) {
+ out += ' title="' + title + '"';
+ }
+ out += this.options.xhtml ? '/>' : '>';
+ return out;
+};
+
+/**
+ * Parsing & Compiling
+ */
+
+function Parser(options) {
+ this.tokens = [];
+ this.token = null;
+ this.options = options || marked.defaults;
+ this.options.renderer = this.options.renderer || new Renderer;
+ this.renderer = this.options.renderer;
+ this.renderer.options = this.options;
+}
+
+/**
+ * Static Parse Method
+ */
+
+Parser.parse = function(src, options, renderer) {
+ var parser = new Parser(options, renderer);
+ return parser.parse(src);
+};
+
+/**
+ * Parse Loop
+ */
+
+Parser.prototype.parse = function(src) {
+ this.inline = new InlineLexer(src.links, this.options, this.renderer);
+ this.tokens = src.reverse();
+
+ var out = '';
+ while (this.next()) {
+ out += this.tok();
+ }
+
+ return out;
+};
+
+/**
+ * Next Token
+ */
+
+Parser.prototype.next = function() {
+ return this.token = this.tokens.pop();
+};
+
+/**
+ * Preview Next Token
+ */
+
+Parser.prototype.peek = function() {
+ return this.tokens[this.tokens.length - 1] || 0;
+};
+
+/**
+ * Parse Text Tokens
+ */
+
+Parser.prototype.parseText = function() {
+ var body = this.token.text;
+
+ while (this.peek().type === 'text') {
+ body += '\n' + this.next().text;
+ }
+
+ return this.inline.output(body);
+};
+
+/**
+ * Parse Current Token
+ */
+
+Parser.prototype.tok = function() {
+ switch (this.token.type) {
+ case 'space': {
+ return '';
+ }
+ case 'hr': {
+ return this.renderer.hr();
+ }
+ case 'heading': {
+ return this.renderer.heading(
+ this.inline.output(this.token.text),
+ this.token.depth,
+ this.token.text);
+ }
+ case 'code': {
+ return this.renderer.code(this.token.text,
+ this.token.lang,
+ this.token.escaped);
+ }
+ case 'table': {
+ var header = ''
+ , body = ''
+ , i
+ , row
+ , cell
+ , flags
+ , j;
+
+ // header
+ cell = '';
+ for (i = 0; i < this.token.header.length; i++) {
+ flags = { header: true, align: this.token.align[i] };
+ cell += this.renderer.tablecell(
+ this.inline.output(this.token.header[i]),
+ { header: true, align: this.token.align[i] }
+ );
+ }
+ header += this.renderer.tablerow(cell);
+
+ for (i = 0; i < this.token.cells.length; i++) {
+ row = this.token.cells[i];
+
+ cell = '';
+ for (j = 0; j < row.length; j++) {
+ cell += this.renderer.tablecell(
+ this.inline.output(row[j]),
+ { header: false, align: this.token.align[j] }
+ );
+ }
+
+ body += this.renderer.tablerow(cell);
+ }
+ return this.renderer.table(header, body);
+ }
+ case 'blockquote_start': {
+ var body = '';
+
+ while (this.next().type !== 'blockquote_end') {
+ body += this.tok();
+ }
+
+ return this.renderer.blockquote(body);
+ }
+ case 'list_start': {
+ var body = ''
+ , ordered = this.token.ordered;
+
+ while (this.next().type !== 'list_end') {
+ body += this.tok();
+ }
+
+ return this.renderer.list(body, ordered);
+ }
+ case 'list_item_start': {
+ var body = '';
+
+ while (this.next().type !== 'list_item_end') {
+ body += this.token.type === 'text'
+ ? this.parseText()
+ : this.tok();
+ }
+
+ return this.renderer.listitem(body);
+ }
+ case 'loose_item_start': {
+ var body = '';
+
+ while (this.next().type !== 'list_item_end') {
+ body += this.tok();
+ }
+
+ return this.renderer.listitem(body);
+ }
+ case 'html': {
+ var html = !this.token.pre && !this.options.pedantic
+ ? this.inline.output(this.token.text)
+ : this.token.text;
+ return this.renderer.html(html);
+ }
+ case 'paragraph': {
+ return this.renderer.paragraph(this.inline.output(this.token.text));
+ }
+ case 'text': {
+ return this.renderer.paragraph(this.parseText());
+ }
+ }
+};
+
+/**
+ * Helpers
+ */
+
+function escape(html, encode) {
+ return html
+ .replace(!encode ? /&(?!#?\w+;)/g : /&/g, '&amp;')
+ .replace(/</g, '&lt;')
+ .replace(/>/g, '&gt;')
+ .replace(/"/g, '&quot;')
+ .replace(/'/g, '&#39;');
+}
+
+function unescape(html) {
+ return html.replace(/&([#\w]+);/g, function(_, n) {
+ n = n.toLowerCase();
+ if (n === 'colon') return ':';
+ if (n.charAt(0) === '#') {
+ return n.charAt(1) === 'x'
+ ? String.fromCharCode(parseInt(n.substring(2), 16))
+ : String.fromCharCode(+n.substring(1));
+ }
+ return '';
+ });
+}
+
+function replace(regex, opt) {
+ regex = regex.source;
+ opt = opt || '';
+ return function self(name, val) {
+ if (!name) return new RegExp(regex, opt);
+ val = val.source || val;
+ val = val.replace(/(^|[^\[])\^/g, '$1');
+ regex = regex.replace(name, val);
+ return self;
+ };
+}
+
+function noop() {}
+noop.exec = noop;
+
+function merge(obj) {
+ var i = 1
+ , target
+ , key;
+
+ for (; i < arguments.length; i++) {
+ target = arguments[i];
+ for (key in target) {
+ if (Object.prototype.hasOwnProperty.call(target, key)) {
+ obj[key] = target[key];
+ }
+ }
+ }
+
+ return obj;
+}
+
+
+/**
+ * Marked
+ */
+
+function marked(src, opt, callback) {
+ if (callback || typeof opt === 'function') {
+ if (!callback) {
+ callback = opt;
+ opt = null;
+ }
+
+ opt = merge({}, marked.defaults, opt || {});
+
+ var highlight = opt.highlight
+ , tokens
+ , pending
+ , i = 0;
+
+ try {
+ tokens = Lexer.lex(src, opt)
+ } catch (e) {
+ return callback(e);
+ }
+
+ pending = tokens.length;
+
+ var done = function(err) {
+ if (err) {
+ opt.highlight = highlight;
+ return callback(err);
+ }
+
+ var out;
+
+ try {
+ out = Parser.parse(tokens, opt);
+ } catch (e) {
+ err = e;
+ }
+
+ opt.highlight = highlight;
+
+ return err
+ ? callback(err)
+ : callback(null, out);
+ };
+
+ if (!highlight || highlight.length < 3) {
+ return done();
+ }
+
+ delete opt.highlight;
+
+ if (!pending) return done();
+
+ for (; i < tokens.length; i++) {
+ (function(token) {
+ if (token.type !== 'code') {
+ return --pending || done();
+ }
+ return highlight(token.text, token.lang, function(err, code) {
+ if (err) return done(err);
+ if (code == null || code === token.text) {
+ return --pending || done();
+ }
+ token.text = code;
+ token.escaped = true;
+ --pending || done();
+ });
+ })(tokens[i]);
+ }
+
+ return;
+ }
+ try {
+ if (opt) opt = merge({}, marked.defaults, opt);
+ return Parser.parse(Lexer.lex(src, opt), opt);
+ } catch (e) {
+ e.message += '\nPlease report this to https://github.com/chjj/marked.';
+ if ((opt || marked.defaults).silent) {
+ return '<p>An error occured:</p><pre>'
+ + escape(e.message + '', true)
+ + '</pre>';
+ }
+ throw e;
+ }
+}
+
+/**
+ * Options
+ */
+
+marked.options =
+marked.setOptions = function(opt) {
+ merge(marked.defaults, opt);
+ return marked;
+};
+
+marked.defaults = {
+ gfm: true,
+ tables: true,
+ breaks: false,
+ pedantic: false,
+ sanitize: false,
+ smartLists: false,
+ silent: false,
+ highlight: null,
+ langPrefix: 'lang-',
+ smartypants: false,
+ headerPrefix: '',
+ renderer: new Renderer,
+ xhtml: false
+};
+
+/**
+ * Expose
+ */
+
+marked.Parser = Parser;
+marked.parser = Parser.parse;
+
+marked.Renderer = Renderer;
+
+marked.Lexer = Lexer;
+marked.lexer = Lexer.lex;
+
+marked.InlineLexer = InlineLexer;
+marked.inlineLexer = InlineLexer.output;
+
+marked.parse = marked;
+
+if (typeof module !== 'undefined' && typeof exports === 'object') {
+ module.exports = marked;
+} else if (typeof define === 'function' && define.amd) {
+ define(function() { return marked; });
+} else {
+ this.marked = marked;
+}
+
+}).call(function() {
+ return this || (typeof window !== 'undefined' ? window : global);
+}()); \ No newline at end of file
diff --git a/ydb/core/viewer/content/api/lib/object-assign-pollyfill.js b/ydb/core/viewer/content/api/lib/object-assign-pollyfill.js
index 0ddfdf2494a..517992077f8 100644
--- a/ydb/core/viewer/content/api/lib/object-assign-pollyfill.js
+++ b/ydb/core/viewer/content/api/lib/object-assign-pollyfill.js
@@ -1,23 +1,23 @@
-if (typeof Object.assign != 'function') {
- (function () {
- Object.assign = function (target) {
- 'use strict';
- if (target === undefined || target === null) {
- throw new TypeError('Cannot convert undefined or null to object');
- }
-
- var output = Object(target);
- for (var index = 1; index < arguments.length; index++) {
- var source = arguments[index];
- if (source !== undefined && source !== null) {
- for (var nextKey in source) {
- if (Object.prototype.hasOwnProperty.call(source, nextKey)) {
- output[nextKey] = source[nextKey];
- }
- }
- }
- }
- return output;
- };
- })();
-}
+if (typeof Object.assign != 'function') {
+ (function () {
+ Object.assign = function (target) {
+ 'use strict';
+ if (target === undefined || target === null) {
+ throw new TypeError('Cannot convert undefined or null to object');
+ }
+
+ var output = Object(target);
+ for (var index = 1; index < arguments.length; index++) {
+ var source = arguments[index];
+ if (source !== undefined && source !== null) {
+ for (var nextKey in source) {
+ if (Object.prototype.hasOwnProperty.call(source, nextKey)) {
+ output[nextKey] = source[nextKey];
+ }
+ }
+ }
+ }
+ return output;
+ };
+ })();
+}
diff --git a/ydb/core/viewer/content/api/lib/sanitize-html.min.js b/ydb/core/viewer/content/api/lib/sanitize-html.min.js
index 95a820ceb7d..3e3b48d6cc5 100644
--- a/ydb/core/viewer/content/api/lib/sanitize-html.min.js
+++ b/ydb/core/viewer/content/api/lib/sanitize-html.min.js
@@ -1,6 +1,6 @@
-(function(f){if(typeof exports==="object"&&typeof module!=="undefined"){module.exports=f()}else if(typeof define==="function"&&define.amd){define([],f)}else{var g;if(typeof window!=="undefined"){g=window}else if(typeof global!=="undefined"){g=global}else if(typeof self!=="undefined"){g=self}else{g=this}g.sanitizeHtml=f()}})(function(){var define,module,exports;return function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s}({1:[function(require,module,exports){var htmlparser=require("htmlparser2");var extend=require("xtend");var quoteRegexp=require("regexp-quote");function each(obj,cb){if(obj)Object.keys(obj).forEach(function(key){cb(obj[key],key)})}function has(obj,key){return{}.hasOwnProperty.call(obj,key)}module.exports=sanitizeHtml;function sanitizeHtml(html,options,_recursing){var result="";function Frame(tag,attribs){var that=this;this.tag=tag;this.attribs=attribs||{};this.tagPosition=result.length;this.text="";this.updateParentNodeText=function(){if(stack.length){var parentFrame=stack[stack.length-1];parentFrame.text+=that.text}}}if(!options){options=sanitizeHtml.defaults;options.parser=htmlParserDefaults}else{options=extend(sanitizeHtml.defaults,options);if(options.parser){options.parser=extend(htmlParserDefaults,options.parser)}else{options.parser=htmlParserDefaults}}var nonTextTagsArray=options.nonTextTags||["script","style","textarea"];var allowedAttributesMap;var allowedAttributesGlobMap;if(options.allowedAttributes){allowedAttributesMap={};allowedAttributesGlobMap={};each(options.allowedAttributes,function(attributes,tag){allowedAttributesMap[tag]=[];var globRegex=[];attributes.forEach(function(name){if(name.indexOf("*")>=0){globRegex.push(quoteRegexp(name).replace(/\\\*/g,".*"))}else{allowedAttributesMap[tag].push(name)}});allowedAttributesGlobMap[tag]=new RegExp("^("+globRegex.join("|")+")$")})}var allowedClassesMap={};each(options.allowedClasses,function(classes,tag){if(allowedAttributesMap){if(!has(allowedAttributesMap,tag)){allowedAttributesMap[tag]=[]}allowedAttributesMap[tag].push("class")}allowedClassesMap[tag]=classes});var transformTagsMap={};var transformTagsAll;each(options.transformTags,function(transform,tag){var transFun;if(typeof transform==="function"){transFun=transform}else if(typeof transform==="string"){transFun=sanitizeHtml.simpleTransform(transform)}if(tag==="*"){transformTagsAll=transFun}else{transformTagsMap[tag]=transFun}});var depth=0;var stack=[];var skipMap={};var transformMap={};var skipText=false;var skipTextDepth=0;var parser=new htmlparser.Parser({onopentag:function(name,attribs){if(skipText){skipTextDepth++;return}var frame=new Frame(name,attribs);stack.push(frame);var skip=false;var hasText=frame.text?true:false;var transformedTag;if(has(transformTagsMap,name)){transformedTag=transformTagsMap[name](name,attribs);frame.attribs=attribs=transformedTag.attribs;if(transformedTag.text!==undefined){frame.innerText=transformedTag.text}if(name!==transformedTag.tagName){frame.name=name=transformedTag.tagName;transformMap[depth]=transformedTag.tagName}}if(transformTagsAll){transformedTag=transformTagsAll(name,attribs);frame.attribs=attribs=transformedTag.attribs;if(name!==transformedTag.tagName){frame.name=name=transformedTag.tagName;transformMap[depth]=transformedTag.tagName}}if(options.allowedTags&&options.allowedTags.indexOf(name)===-1){skip=true;if(nonTextTagsArray.indexOf(name)!==-1){skipText=true;skipTextDepth=1}skipMap[depth]=true}depth++;if(skip){return}result+="<"+name;if(!allowedAttributesMap||has(allowedAttributesMap,name)||allowedAttributesMap["*"]){each(attribs,function(value,a){if(!allowedAttributesMap||has(allowedAttributesMap,name)&&allowedAttributesMap[name].indexOf(a)!==-1||allowedAttributesMap["*"]&&allowedAttributesMap["*"].indexOf(a)!==-1||has(allowedAttributesGlobMap,name)&&allowedAttributesGlobMap[name].test(a)||allowedAttributesGlobMap["*"]&&allowedAttributesGlobMap["*"].test(a)){if(a==="href"||a==="src"){if(naughtyHref(name,value)){delete frame.attribs[a];return}}if(a==="class"){value=filterClasses(value,allowedClassesMap[name]);if(!value.length){delete frame.attribs[a];return}}result+=" "+a;if(value.length){result+='="'+escapeHtml(value)+'"'}}else{delete frame.attribs[a]}})}if(options.selfClosing.indexOf(name)!==-1){result+=" />"}else{result+=">";if(frame.innerText&&!hasText&&!options.textFilter){result+=frame.innerText}}},ontext:function(text){if(skipText){return}var lastFrame=stack[stack.length-1];var tag;if(lastFrame){tag=lastFrame.tag;text=lastFrame.innerText!==undefined?lastFrame.innerText:text}if(tag==="script"||tag==="style"){result+=text}else{var escaped=escapeHtml(text);if(options.textFilter){result+=options.textFilter(escaped)}else{result+=escaped}}if(stack.length){var frame=stack[stack.length-1];frame.text+=text}},onclosetag:function(name){if(skipText){skipTextDepth--;if(!skipTextDepth){skipText=false}else{return}}var frame=stack.pop();if(!frame){return}skipText=false;depth--;if(skipMap[depth]){delete skipMap[depth];frame.updateParentNodeText();return}if(transformMap[depth]){name=transformMap[depth];delete transformMap[depth]}if(options.exclusiveFilter&&options.exclusiveFilter(frame)){result=result.substr(0,frame.tagPosition);return}frame.updateParentNodeText();if(options.selfClosing.indexOf(name)!==-1){return}result+="</"+name+">"}},options.parser);parser.write(html);parser.end();return result;function escapeHtml(s){if(typeof s!=="string"){s=s+""}return s.replace(/\&/g,"&amp;").replace(/</g,"&lt;").replace(/\>/g,"&gt;").replace(/\"/g,"&quot;")}function naughtyHref(name,href){href=href.replace(/[\x00-\x20]+/g,"");href=href.replace(/<\!\-\-.*?\-\-\>/g,"");var matches=href.match(/^([a-zA-Z]+)\:/);if(!matches){return false}var scheme=matches[1].toLowerCase();if(has(options.allowedSchemesByTag,name)){return options.allowedSchemesByTag[name].indexOf(scheme)===-1}return!options.allowedSchemes||options.allowedSchemes.indexOf(scheme)===-1}function filterClasses(classes,allowed){if(!allowed){return classes}classes=classes.split(/\s+/);return classes.filter(function(clss){return allowed.indexOf(clss)!==-1}).join(" ")}}var htmlParserDefaults={decodeEntities:true};sanitizeHtml.defaults={allowedTags:["h3","h4","h5","h6","blockquote","p","a","ul","ol","nl","li","b","i","strong","em","strike","code","hr","br","div","table","thead","caption","tbody","tr","th","td","pre"],allowedAttributes:{a:["href","name","target"],img:["src"]},selfClosing:["img","br","hr","area","base","basefont","input","link","meta"],allowedSchemes:["http","https","ftp","mailto"],allowedSchemesByTag:{}};sanitizeHtml.simpleTransform=function(newTagName,newAttribs,merge){merge=merge===undefined?true:merge;newAttribs=newAttribs||{};return function(tagName,attribs){var attrib;if(merge){for(attrib in newAttribs){attribs[attrib]=newAttribs[attrib]}}else{attribs=newAttribs}return{tagName:newTagName,attribs:attribs}}}},{htmlparser2:36,"regexp-quote":54,xtend:58}],2:[function(require,module,exports){"use strict";exports.toByteArray=toByteArray;exports.fromByteArray=fromByteArray;var lookup=[];var revLookup=[];var Arr=typeof Uint8Array!=="undefined"?Uint8Array:Array;function init(){var code="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";for(var i=0,len=code.length;i<len;++i){lookup[i]=code[i];revLookup[code.charCodeAt(i)]=i}revLookup["-".charCodeAt(0)]=62;revLookup["_".charCodeAt(0)]=63}init();function toByteArray(b64){var i,j,l,tmp,placeHolders,arr;var len=b64.length;if(len%4>0){throw new Error("Invalid string. Length must be a multiple of 4")}placeHolders=b64[len-2]==="="?2:b64[len-1]==="="?1:0;arr=new Arr(len*3/4-placeHolders);l=placeHolders>0?len-4:len;var L=0;for(i=0,j=0;i<l;i+=4,j+=3){tmp=revLookup[b64.charCodeAt(i)]<<18|revLookup[b64.charCodeAt(i+1)]<<12|revLookup[b64.charCodeAt(i+2)]<<6|revLookup[b64.charCodeAt(i+3)];arr[L++]=tmp>>16&255;arr[L++]=tmp>>8&255;arr[L++]=tmp&255}if(placeHolders===2){tmp=revLookup[b64.charCodeAt(i)]<<2|revLookup[b64.charCodeAt(i+1)]>>4;arr[L++]=tmp&255}else if(placeHolders===1){tmp=revLookup[b64.charCodeAt(i)]<<10|revLookup[b64.charCodeAt(i+1)]<<4|revLookup[b64.charCodeAt(i+2)]>>2;arr[L++]=tmp>>8&255;arr[L++]=tmp&255}return arr}function tripletToBase64(num){return lookup[num>>18&63]+lookup[num>>12&63]+lookup[num>>6&63]+lookup[num&63]}function encodeChunk(uint8,start,end){var tmp;var output=[];for(var i=start;i<end;i+=3){tmp=(uint8[i]<<16)+(uint8[i+1]<<8)+uint8[i+2];output.push(tripletToBase64(tmp))}return output.join("")}function fromByteArray(uint8){var tmp;var len=uint8.length;var extraBytes=len%3;var output="";var parts=[];var maxChunkLength=16383;for(var i=0,len2=len-extraBytes;i<len2;i+=maxChunkLength){parts.push(encodeChunk(uint8,i,i+maxChunkLength>len2?len2:i+maxChunkLength))}if(extraBytes===1){tmp=uint8[len-1];output+=lookup[tmp>>2];output+=lookup[tmp<<4&63];output+="=="}else if(extraBytes===2){tmp=(uint8[len-2]<<8)+uint8[len-1];output+=lookup[tmp>>10];output+=lookup[tmp>>4&63];output+=lookup[tmp<<2&63];output+="="}parts.push(output);return parts.join("")}},{}],3:[function(require,module,exports){},{}],4:[function(require,module,exports){(function(global){"use strict";var buffer=require("buffer");var Buffer=buffer.Buffer;var SlowBuffer=buffer.SlowBuffer;var MAX_LEN=buffer.kMaxLength||2147483647;exports.alloc=function alloc(size,fill,encoding){if(typeof Buffer.alloc==="function"){return Buffer.alloc(size,fill,encoding)}if(typeof encoding==="number"){throw new TypeError("encoding must not be number")}if(typeof size!=="number"){throw new TypeError("size must be a number")}if(size>MAX_LEN){throw new RangeError("size is too large")}var enc=encoding;var _fill=fill;if(_fill===undefined){enc=undefined;_fill=0}var buf=new Buffer(size);if(typeof _fill==="string"){var fillBuf=new Buffer(_fill,enc);var flen=fillBuf.length;var i=-1;while(++i<size){buf[i]=fillBuf[i%flen]}}else{buf.fill(_fill)}return buf};exports.allocUnsafe=function allocUnsafe(size){if(typeof Buffer.allocUnsafe==="function"){return Buffer.allocUnsafe(size)}if(typeof size!=="number"){throw new TypeError("size must be a number")}if(size>MAX_LEN){throw new RangeError("size is too large")}return new Buffer(size)};exports.from=function from(value,encodingOrOffset,length){if(typeof Buffer.from==="function"&&(!global.Uint8Array||Uint8Array.from!==Buffer.from)){return Buffer.from(value,encodingOrOffset,length)}if(typeof value==="number"){throw new TypeError('"value" argument must not be a number')}if(typeof value==="string"){return new Buffer(value,encodingOrOffset)}if(typeof ArrayBuffer!=="undefined"&&value instanceof ArrayBuffer){var offset=encodingOrOffset;if(arguments.length===1){return new Buffer(value)}if(typeof offset==="undefined"){offset=0}var len=length;if(typeof len==="undefined"){len=value.byteLength-offset}if(offset>=value.byteLength){throw new RangeError("'offset' is out of bounds")}if(len>value.byteLength-offset){throw new RangeError("'length' is out of bounds")}return new Buffer(value.slice(offset,offset+len))}if(Buffer.isBuffer(value)){var out=new Buffer(value.length);value.copy(out,0,0,value.length);return out}if(value){if(Array.isArray(value)||typeof ArrayBuffer!=="undefined"&&value.buffer instanceof ArrayBuffer||"length"in value){return new Buffer(value)}if(value.type==="Buffer"&&Array.isArray(value.data)){return new Buffer(value.data)}}throw new TypeError("First argument must be a string, Buffer, "+"ArrayBuffer, Array, or array-like object.")};exports.allocUnsafeSlow=function allocUnsafeSlow(size){if(typeof Buffer.allocUnsafeSlow==="function"){return Buffer.allocUnsafeSlow(size)}if(typeof size!=="number"){throw new TypeError("size must be a number")}if(size>=MAX_LEN){throw new RangeError("size is too large")}return new SlowBuffer(size)}}).call(this,typeof global!=="undefined"?global:typeof self!=="undefined"?self:typeof window!=="undefined"?window:{})},{buffer:5}],5:[function(require,module,exports){(function(global){"use strict";var base64=require("base64-js");var ieee754=require("ieee754");var isArray=require("isarray");exports.Buffer=Buffer;exports.SlowBuffer=SlowBuffer;exports.INSPECT_MAX_BYTES=50;Buffer.TYPED_ARRAY_SUPPORT=global.TYPED_ARRAY_SUPPORT!==undefined?global.TYPED_ARRAY_SUPPORT:typedArraySupport();exports.kMaxLength=kMaxLength();function typedArraySupport(){try{var arr=new Uint8Array(1);arr.__proto__={__proto__:Uint8Array.prototype,foo:function(){return 42}};return arr.foo()===42&&typeof arr.subarray==="function"&&arr.subarray(1,1).byteLength===0}catch(e){return false}}function kMaxLength(){return Buffer.TYPED_ARRAY_SUPPORT?2147483647:1073741823}function createBuffer(that,length){if(kMaxLength()<length){throw new RangeError("Invalid typed array length")}if(Buffer.TYPED_ARRAY_SUPPORT){that=new Uint8Array(length);that.__proto__=Buffer.prototype}else{if(that===null){that=new Buffer(length)}that.length=length}return that}function Buffer(arg,encodingOrOffset,length){if(!Buffer.TYPED_ARRAY_SUPPORT&&!(this instanceof Buffer)){return new Buffer(arg,encodingOrOffset,length)}if(typeof arg==="number"){if(typeof encodingOrOffset==="string"){throw new Error("If encoding is specified then the first argument must be a string")}return allocUnsafe(this,arg)}return from(this,arg,encodingOrOffset,length)}Buffer.poolSize=8192;Buffer._augment=function(arr){arr.__proto__=Buffer.prototype;return arr};function from(that,value,encodingOrOffset,length){if(typeof value==="number"){throw new TypeError('"value" argument must not be a number')}if(typeof ArrayBuffer!=="undefined"&&value instanceof ArrayBuffer){return fromArrayBuffer(that,value,encodingOrOffset,length)}if(typeof value==="string"){return fromString(that,value,encodingOrOffset)}return fromObject(that,value)}Buffer.from=function(value,encodingOrOffset,length){return from(null,value,encodingOrOffset,length)};if(Buffer.TYPED_ARRAY_SUPPORT){Buffer.prototype.__proto__=Uint8Array.prototype;Buffer.__proto__=Uint8Array;if(typeof Symbol!=="undefined"&&Symbol.species&&Buffer[Symbol.species]===Buffer){Object.defineProperty(Buffer,Symbol.species,{value:null,configurable:true})}}function assertSize(size){if(typeof size!=="number"){throw new TypeError('"size" argument must be a number')}else if(size<0){throw new RangeError('"size" argument must not be negative')}}function alloc(that,size,fill,encoding){assertSize(size);if(size<=0){return createBuffer(that,size)}if(fill!==undefined){return typeof encoding==="string"?createBuffer(that,size).fill(fill,encoding):createBuffer(that,size).fill(fill)}return createBuffer(that,size)}Buffer.alloc=function(size,fill,encoding){return alloc(null,size,fill,encoding)};function allocUnsafe(that,size){assertSize(size);that=createBuffer(that,size<0?0:checked(size)|0);if(!Buffer.TYPED_ARRAY_SUPPORT){for(var i=0;i<size;++i){that[i]=0}}return that}Buffer.allocUnsafe=function(size){return allocUnsafe(null,size)};Buffer.allocUnsafeSlow=function(size){return allocUnsafe(null,size)};function fromString(that,string,encoding){if(typeof encoding!=="string"||encoding===""){encoding="utf8"}if(!Buffer.isEncoding(encoding)){throw new TypeError('"encoding" must be a valid string encoding')}var length=byteLength(string,encoding)|0;that=createBuffer(that,length);var actual=that.write(string,encoding);if(actual!==length){that=that.slice(0,actual)}return that}function fromArrayLike(that,array){var length=array.length<0?0:checked(array.length)|0;that=createBuffer(that,length);for(var i=0;i<length;i+=1){that[i]=array[i]&255}return that}function fromArrayBuffer(that,array,byteOffset,length){array.byteLength;if(byteOffset<0||array.byteLength<byteOffset){throw new RangeError("'offset' is out of bounds")}if(array.byteLength<byteOffset+(length||0)){throw new RangeError("'length' is out of bounds")}if(byteOffset===undefined&&length===undefined){array=new Uint8Array(array)}else if(length===undefined){array=new Uint8Array(array,byteOffset)}else{array=new Uint8Array(array,byteOffset,length)}if(Buffer.TYPED_ARRAY_SUPPORT){that=array;that.__proto__=Buffer.prototype}else{that=fromArrayLike(that,array)}return that}function fromObject(that,obj){if(Buffer.isBuffer(obj)){var len=checked(obj.length)|0;that=createBuffer(that,len);if(that.length===0){return that}obj.copy(that,0,0,len);return that}if(obj){if(typeof ArrayBuffer!=="undefined"&&obj.buffer instanceof ArrayBuffer||"length"in obj){if(typeof obj.length!=="number"||isnan(obj.length)){return createBuffer(that,0)}return fromArrayLike(that,obj)}if(obj.type==="Buffer"&&isArray(obj.data)){return fromArrayLike(that,obj.data)}}throw new TypeError("First argument must be a string, Buffer, ArrayBuffer, Array, or array-like object.")}function checked(length){if(length>=kMaxLength()){throw new RangeError("Attempt to allocate Buffer larger than maximum "+"size: 0x"+kMaxLength().toString(16)+" bytes")}return length|0}function SlowBuffer(length){if(+length!=length){length=0}return Buffer.alloc(+length)}Buffer.isBuffer=function isBuffer(b){return!!(b!=null&&b._isBuffer)};Buffer.compare=function compare(a,b){if(!Buffer.isBuffer(a)||!Buffer.isBuffer(b)){throw new TypeError("Arguments must be Buffers")}if(a===b)return 0;var x=a.length;var y=b.length;for(var i=0,len=Math.min(x,y);i<len;++i){if(a[i]!==b[i]){x=a[i];y=b[i];break}}if(x<y)return-1;if(y<x)return 1;return 0};Buffer.isEncoding=function isEncoding(encoding){switch(String(encoding).toLowerCase()){case"hex":case"utf8":case"utf-8":case"ascii":case"latin1":case"binary":case"base64":case"ucs2":case"ucs-2":case"utf16le":case"utf-16le":return true;default:return false}};Buffer.concat=function concat(list,length){if(!isArray(list)){throw new TypeError('"list" argument must be an Array of Buffers')}if(list.length===0){return Buffer.alloc(0)}var i;if(length===undefined){length=0;for(i=0;i<list.length;++i){length+=list[i].length}}var buffer=Buffer.allocUnsafe(length);var pos=0;for(i=0;i<list.length;++i){var buf=list[i];if(!Buffer.isBuffer(buf)){throw new TypeError('"list" argument must be an Array of Buffers')}buf.copy(buffer,pos);pos+=buf.length}return buffer};function byteLength(string,encoding){if(Buffer.isBuffer(string)){return string.length}if(typeof ArrayBuffer!=="undefined"&&typeof ArrayBuffer.isView==="function"&&(ArrayBuffer.isView(string)||string instanceof ArrayBuffer)){return string.byteLength}if(typeof string!=="string"){string=""+string}var len=string.length;if(len===0)return 0;var loweredCase=false;for(;;){switch(encoding){case"ascii":case"latin1":case"binary":return len;case"utf8":case"utf-8":case undefined:return utf8ToBytes(string).length;case"ucs2":case"ucs-2":case"utf16le":case"utf-16le":return len*2;case"hex":return len>>>1;case"base64":return base64ToBytes(string).length;default:if(loweredCase)return utf8ToBytes(string).length;encoding=(""+encoding).toLowerCase();loweredCase=true}}}Buffer.byteLength=byteLength;function slowToString(encoding,start,end){var loweredCase=false;if(start===undefined||start<0){start=0}if(start>this.length){return""}if(end===undefined||end>this.length){end=this.length}if(end<=0){return""}end>>>=0;start>>>=0;if(end<=start){return""}if(!encoding)encoding="utf8";while(true){switch(encoding){case"hex":return hexSlice(this,start,end);case"utf8":case"utf-8":return utf8Slice(this,start,end);case"ascii":return asciiSlice(this,start,end);case"latin1":case"binary":return latin1Slice(this,start,end);case"base64":return base64Slice(this,start,end);case"ucs2":case"ucs-2":case"utf16le":case"utf-16le":return utf16leSlice(this,start,end);default:if(loweredCase)throw new TypeError("Unknown encoding: "+encoding);encoding=(encoding+"").toLowerCase();loweredCase=true}}}Buffer.prototype._isBuffer=true;function swap(b,n,m){var i=b[n];b[n]=b[m];b[m]=i}Buffer.prototype.swap16=function swap16(){var len=this.length;if(len%2!==0){throw new RangeError("Buffer size must be a multiple of 16-bits")}for(var i=0;i<len;i+=2){swap(this,i,i+1)}return this};Buffer.prototype.swap32=function swap32(){var len=this.length;if(len%4!==0){throw new RangeError("Buffer size must be a multiple of 32-bits")}for(var i=0;i<len;i+=4){swap(this,i,i+3);swap(this,i+1,i+2)}return this};Buffer.prototype.swap64=function swap64(){var len=this.length;if(len%8!==0){throw new RangeError("Buffer size must be a multiple of 64-bits")}for(var i=0;i<len;i+=8){swap(this,i,i+7);swap(this,i+1,i+6);swap(this,i+2,i+5);swap(this,i+3,i+4)}return this};Buffer.prototype.toString=function toString(){var length=this.length|0;if(length===0)return"";if(arguments.length===0)return utf8Slice(this,0,length);return slowToString.apply(this,arguments)};Buffer.prototype.equals=function equals(b){if(!Buffer.isBuffer(b))throw new TypeError("Argument must be a Buffer");if(this===b)return true;return Buffer.compare(this,b)===0};Buffer.prototype.inspect=function inspect(){var str="";var max=exports.INSPECT_MAX_BYTES;if(this.length>0){str=this.toString("hex",0,max).match(/.{2}/g).join(" ");if(this.length>max)str+=" ... "}return"<Buffer "+str+">"};Buffer.prototype.compare=function compare(target,start,end,thisStart,thisEnd){if(!Buffer.isBuffer(target)){throw new TypeError("Argument must be a Buffer")}if(start===undefined){start=0}if(end===undefined){end=target?target.length:0}if(thisStart===undefined){thisStart=0}if(thisEnd===undefined){thisEnd=this.length}if(start<0||end>target.length||thisStart<0||thisEnd>this.length){throw new RangeError("out of range index")}if(thisStart>=thisEnd&&start>=end){return 0}if(thisStart>=thisEnd){return-1}if(start>=end){return 1}start>>>=0;end>>>=0;thisStart>>>=0;thisEnd>>>=0;if(this===target)return 0;var x=thisEnd-thisStart;var y=end-start;var len=Math.min(x,y);var thisCopy=this.slice(thisStart,thisEnd);var targetCopy=target.slice(start,end);for(var i=0;i<len;++i){if(thisCopy[i]!==targetCopy[i]){x=thisCopy[i];y=targetCopy[i];break}}if(x<y)return-1;if(y<x)return 1;return 0};function bidirectionalIndexOf(buffer,val,byteOffset,encoding,dir){if(buffer.length===0)return-1;if(typeof byteOffset==="string"){encoding=byteOffset;byteOffset=0}else if(byteOffset>2147483647){byteOffset=2147483647}else if(byteOffset<-2147483648){byteOffset=-2147483648}byteOffset=+byteOffset;if(isNaN(byteOffset)){byteOffset=dir?0:buffer.length-1}if(byteOffset<0)byteOffset=buffer.length+byteOffset;if(byteOffset>=buffer.length){if(dir)return-1;else byteOffset=buffer.length-1}else if(byteOffset<0){if(dir)byteOffset=0;else return-1}if(typeof val==="string"){val=Buffer.from(val,encoding)}if(Buffer.isBuffer(val)){if(val.length===0){return-1}return arrayIndexOf(buffer,val,byteOffset,encoding,dir)}else if(typeof val==="number"){val=val&255;if(Buffer.TYPED_ARRAY_SUPPORT&&typeof Uint8Array.prototype.indexOf==="function"){if(dir){return Uint8Array.prototype.indexOf.call(buffer,val,byteOffset)}else{return Uint8Array.prototype.lastIndexOf.call(buffer,val,byteOffset)}}return arrayIndexOf(buffer,[val],byteOffset,encoding,dir)}throw new TypeError("val must be string, number or Buffer")}function arrayIndexOf(arr,val,byteOffset,encoding,dir){var indexSize=1;var arrLength=arr.length;var valLength=val.length;if(encoding!==undefined){encoding=String(encoding).toLowerCase();if(encoding==="ucs2"||encoding==="ucs-2"||encoding==="utf16le"||encoding==="utf-16le"){if(arr.length<2||val.length<2){return-1}indexSize=2;arrLength/=2;valLength/=2;byteOffset/=2}}function read(buf,i){if(indexSize===1){return buf[i]}else{return buf.readUInt16BE(i*indexSize)}}var i;if(dir){var foundIndex=-1;for(i=byteOffset;i<arrLength;i++){if(read(arr,i)===read(val,foundIndex===-1?0:i-foundIndex)){if(foundIndex===-1)foundIndex=i;if(i-foundIndex+1===valLength)return foundIndex*indexSize}else{if(foundIndex!==-1)i-=i-foundIndex;foundIndex=-1}}}else{if(byteOffset+valLength>arrLength)byteOffset=arrLength-valLength;for(i=byteOffset;i>=0;i--){var found=true;for(var j=0;j<valLength;j++){if(read(arr,i+j)!==read(val,j)){found=false;break}}if(found)return i}}return-1}Buffer.prototype.includes=function includes(val,byteOffset,encoding){return this.indexOf(val,byteOffset,encoding)!==-1};Buffer.prototype.indexOf=function indexOf(val,byteOffset,encoding){return bidirectionalIndexOf(this,val,byteOffset,encoding,true)};Buffer.prototype.lastIndexOf=function lastIndexOf(val,byteOffset,encoding){return bidirectionalIndexOf(this,val,byteOffset,encoding,false)};function hexWrite(buf,string,offset,length){offset=Number(offset)||0;var remaining=buf.length-offset;if(!length){length=remaining}else{length=Number(length);if(length>remaining){length=remaining}}var strLen=string.length;if(strLen%2!==0)throw new TypeError("Invalid hex string");if(length>strLen/2){length=strLen/2}for(var i=0;i<length;++i){var parsed=parseInt(string.substr(i*2,2),16);if(isNaN(parsed))return i;buf[offset+i]=parsed}return i}function utf8Write(buf,string,offset,length){return blitBuffer(utf8ToBytes(string,buf.length-offset),buf,offset,length)}function asciiWrite(buf,string,offset,length){return blitBuffer(asciiToBytes(string),buf,offset,length)}function latin1Write(buf,string,offset,length){return asciiWrite(buf,string,offset,length)}function base64Write(buf,string,offset,length){return blitBuffer(base64ToBytes(string),buf,offset,length)}function ucs2Write(buf,string,offset,length){return blitBuffer(utf16leToBytes(string,buf.length-offset),buf,offset,length)}Buffer.prototype.write=function write(string,offset,length,encoding){if(offset===undefined){encoding="utf8";length=this.length;offset=0}else if(length===undefined&&typeof offset==="string"){encoding=offset;length=this.length;offset=0}else if(isFinite(offset)){offset=offset|0;if(isFinite(length)){length=length|0;if(encoding===undefined)encoding="utf8"}else{encoding=length;length=undefined}}else{throw new Error("Buffer.write(string, encoding, offset[, length]) is no longer supported")}var remaining=this.length-offset;if(length===undefined||length>remaining)length=remaining;if(string.length>0&&(length<0||offset<0)||offset>this.length){throw new RangeError("Attempt to write outside buffer bounds")}if(!encoding)encoding="utf8";var loweredCase=false;for(;;){switch(encoding){case"hex":return hexWrite(this,string,offset,length);case"utf8":case"utf-8":return utf8Write(this,string,offset,length);case"ascii":return asciiWrite(this,string,offset,length);case"latin1":case"binary":return latin1Write(this,string,offset,length);case"base64":return base64Write(this,string,offset,length);case"ucs2":case"ucs-2":case"utf16le":case"utf-16le":return ucs2Write(this,string,offset,length);default:if(loweredCase)throw new TypeError("Unknown encoding: "+encoding);encoding=(""+encoding).toLowerCase();loweredCase=true}}};Buffer.prototype.toJSON=function toJSON(){return{type:"Buffer",data:Array.prototype.slice.call(this._arr||this,0)}};function base64Slice(buf,start,end){if(start===0&&end===buf.length){return base64.fromByteArray(buf)}else{return base64.fromByteArray(buf.slice(start,end))}}function utf8Slice(buf,start,end){end=Math.min(buf.length,end);var res=[];var i=start;while(i<end){var firstByte=buf[i];var codePoint=null;var bytesPerSequence=firstByte>239?4:firstByte>223?3:firstByte>191?2:1;if(i+bytesPerSequence<=end){var secondByte,thirdByte,fourthByte,tempCodePoint;switch(bytesPerSequence){case 1:if(firstByte<128){codePoint=firstByte}break;case 2:secondByte=buf[i+1];if((secondByte&192)===128){tempCodePoint=(firstByte&31)<<6|secondByte&63;if(tempCodePoint>127){codePoint=tempCodePoint}}break;case 3:secondByte=buf[i+1];thirdByte=buf[i+2];if((secondByte&192)===128&&(thirdByte&192)===128){tempCodePoint=(firstByte&15)<<12|(secondByte&63)<<6|thirdByte&63;if(tempCodePoint>2047&&(tempCodePoint<55296||tempCodePoint>57343)){codePoint=tempCodePoint}}break;case 4:secondByte=buf[i+1];thirdByte=buf[i+2];fourthByte=buf[i+3];if((secondByte&192)===128&&(thirdByte&192)===128&&(fourthByte&192)===128){tempCodePoint=(firstByte&15)<<18|(secondByte&63)<<12|(thirdByte&63)<<6|fourthByte&63;if(tempCodePoint>65535&&tempCodePoint<1114112){codePoint=tempCodePoint}}}}if(codePoint===null){codePoint=65533;bytesPerSequence=1}else if(codePoint>65535){codePoint-=65536;res.push(codePoint>>>10&1023|55296);codePoint=56320|codePoint&1023}res.push(codePoint);i+=bytesPerSequence}return decodeCodePointsArray(res)}var MAX_ARGUMENTS_LENGTH=4096;function decodeCodePointsArray(codePoints){var len=codePoints.length;if(len<=MAX_ARGUMENTS_LENGTH){return String.fromCharCode.apply(String,codePoints)}var res="";var i=0;while(i<len){res+=String.fromCharCode.apply(String,codePoints.slice(i,i+=MAX_ARGUMENTS_LENGTH))}return res}function asciiSlice(buf,start,end){var ret="";end=Math.min(buf.length,end);for(var i=start;i<end;++i){ret+=String.fromCharCode(buf[i]&127)}return ret}function latin1Slice(buf,start,end){var ret="";end=Math.min(buf.length,end);for(var i=start;i<end;++i){ret+=String.fromCharCode(buf[i])}return ret}function hexSlice(buf,start,end){var len=buf.length;if(!start||start<0)start=0;if(!end||end<0||end>len)end=len;var out="";for(var i=start;i<end;++i){out+=toHex(buf[i])}return out}function utf16leSlice(buf,start,end){var bytes=buf.slice(start,end);var res="";for(var i=0;i<bytes.length;i+=2){res+=String.fromCharCode(bytes[i]+bytes[i+1]*256)}return res}Buffer.prototype.slice=function slice(start,end){var len=this.length;start=~~start;end=end===undefined?len:~~end;if(start<0){start+=len;if(start<0)start=0}else if(start>len){start=len}if(end<0){end+=len;if(end<0)end=0}else if(end>len){end=len}if(end<start)end=start;var newBuf;if(Buffer.TYPED_ARRAY_SUPPORT){newBuf=this.subarray(start,end);newBuf.__proto__=Buffer.prototype}else{var sliceLen=end-start;newBuf=new Buffer(sliceLen,undefined);for(var i=0;i<sliceLen;++i){newBuf[i]=this[i+start]}}return newBuf};function checkOffset(offset,ext,length){if(offset%1!==0||offset<0)throw new RangeError("offset is not uint");if(offset+ext>length)throw new RangeError("Trying to access beyond buffer length")}Buffer.prototype.readUIntLE=function readUIntLE(offset,byteLength,noAssert){offset=offset|0;byteLength=byteLength|0;if(!noAssert)checkOffset(offset,byteLength,this.length);var val=this[offset];var mul=1;var i=0;while(++i<byteLength&&(mul*=256)){val+=this[offset+i]*mul}return val};Buffer.prototype.readUIntBE=function readUIntBE(offset,byteLength,noAssert){offset=offset|0;byteLength=byteLength|0;if(!noAssert){checkOffset(offset,byteLength,this.length)}var val=this[offset+--byteLength];var mul=1;while(byteLength>0&&(mul*=256)){val+=this[offset+--byteLength]*mul}return val};Buffer.prototype.readUInt8=function readUInt8(offset,noAssert){if(!noAssert)checkOffset(offset,1,this.length);return this[offset]};Buffer.prototype.readUInt16LE=function readUInt16LE(offset,noAssert){if(!noAssert)checkOffset(offset,2,this.length);return this[offset]|this[offset+1]<<8};Buffer.prototype.readUInt16BE=function readUInt16BE(offset,noAssert){if(!noAssert)checkOffset(offset,2,this.length);return this[offset]<<8|this[offset+1]};Buffer.prototype.readUInt32LE=function readUInt32LE(offset,noAssert){if(!noAssert)checkOffset(offset,4,this.length);return(this[offset]|this[offset+1]<<8|this[offset+2]<<16)+this[offset+3]*16777216};Buffer.prototype.readUInt32BE=function readUInt32BE(offset,noAssert){if(!noAssert)checkOffset(offset,4,this.length);return this[offset]*16777216+(this[offset+1]<<16|this[offset+2]<<8|this[offset+3])};Buffer.prototype.readIntLE=function readIntLE(offset,byteLength,noAssert){offset=offset|0;byteLength=byteLength|0;if(!noAssert)checkOffset(offset,byteLength,this.length);var val=this[offset];var mul=1;var i=0;while(++i<byteLength&&(mul*=256)){val+=this[offset+i]*mul}mul*=128;if(val>=mul)val-=Math.pow(2,8*byteLength);return val};Buffer.prototype.readIntBE=function readIntBE(offset,byteLength,noAssert){offset=offset|0;byteLength=byteLength|0;if(!noAssert)checkOffset(offset,byteLength,this.length);
-var i=byteLength;var mul=1;var val=this[offset+--i];while(i>0&&(mul*=256)){val+=this[offset+--i]*mul}mul*=128;if(val>=mul)val-=Math.pow(2,8*byteLength);return val};Buffer.prototype.readInt8=function readInt8(offset,noAssert){if(!noAssert)checkOffset(offset,1,this.length);if(!(this[offset]&128))return this[offset];return(255-this[offset]+1)*-1};Buffer.prototype.readInt16LE=function readInt16LE(offset,noAssert){if(!noAssert)checkOffset(offset,2,this.length);var val=this[offset]|this[offset+1]<<8;return val&32768?val|4294901760:val};Buffer.prototype.readInt16BE=function readInt16BE(offset,noAssert){if(!noAssert)checkOffset(offset,2,this.length);var val=this[offset+1]|this[offset]<<8;return val&32768?val|4294901760:val};Buffer.prototype.readInt32LE=function readInt32LE(offset,noAssert){if(!noAssert)checkOffset(offset,4,this.length);return this[offset]|this[offset+1]<<8|this[offset+2]<<16|this[offset+3]<<24};Buffer.prototype.readInt32BE=function readInt32BE(offset,noAssert){if(!noAssert)checkOffset(offset,4,this.length);return this[offset]<<24|this[offset+1]<<16|this[offset+2]<<8|this[offset+3]};Buffer.prototype.readFloatLE=function readFloatLE(offset,noAssert){if(!noAssert)checkOffset(offset,4,this.length);return ieee754.read(this,offset,true,23,4)};Buffer.prototype.readFloatBE=function readFloatBE(offset,noAssert){if(!noAssert)checkOffset(offset,4,this.length);return ieee754.read(this,offset,false,23,4)};Buffer.prototype.readDoubleLE=function readDoubleLE(offset,noAssert){if(!noAssert)checkOffset(offset,8,this.length);return ieee754.read(this,offset,true,52,8)};Buffer.prototype.readDoubleBE=function readDoubleBE(offset,noAssert){if(!noAssert)checkOffset(offset,8,this.length);return ieee754.read(this,offset,false,52,8)};function checkInt(buf,value,offset,ext,max,min){if(!Buffer.isBuffer(buf))throw new TypeError('"buffer" argument must be a Buffer instance');if(value>max||value<min)throw new RangeError('"value" argument is out of bounds');if(offset+ext>buf.length)throw new RangeError("Index out of range")}Buffer.prototype.writeUIntLE=function writeUIntLE(value,offset,byteLength,noAssert){value=+value;offset=offset|0;byteLength=byteLength|0;if(!noAssert){var maxBytes=Math.pow(2,8*byteLength)-1;checkInt(this,value,offset,byteLength,maxBytes,0)}var mul=1;var i=0;this[offset]=value&255;while(++i<byteLength&&(mul*=256)){this[offset+i]=value/mul&255}return offset+byteLength};Buffer.prototype.writeUIntBE=function writeUIntBE(value,offset,byteLength,noAssert){value=+value;offset=offset|0;byteLength=byteLength|0;if(!noAssert){var maxBytes=Math.pow(2,8*byteLength)-1;checkInt(this,value,offset,byteLength,maxBytes,0)}var i=byteLength-1;var mul=1;this[offset+i]=value&255;while(--i>=0&&(mul*=256)){this[offset+i]=value/mul&255}return offset+byteLength};Buffer.prototype.writeUInt8=function writeUInt8(value,offset,noAssert){value=+value;offset=offset|0;if(!noAssert)checkInt(this,value,offset,1,255,0);if(!Buffer.TYPED_ARRAY_SUPPORT)value=Math.floor(value);this[offset]=value&255;return offset+1};function objectWriteUInt16(buf,value,offset,littleEndian){if(value<0)value=65535+value+1;for(var i=0,j=Math.min(buf.length-offset,2);i<j;++i){buf[offset+i]=(value&255<<8*(littleEndian?i:1-i))>>>(littleEndian?i:1-i)*8}}Buffer.prototype.writeUInt16LE=function writeUInt16LE(value,offset,noAssert){value=+value;offset=offset|0;if(!noAssert)checkInt(this,value,offset,2,65535,0);if(Buffer.TYPED_ARRAY_SUPPORT){this[offset]=value&255;this[offset+1]=value>>>8}else{objectWriteUInt16(this,value,offset,true)}return offset+2};Buffer.prototype.writeUInt16BE=function writeUInt16BE(value,offset,noAssert){value=+value;offset=offset|0;if(!noAssert)checkInt(this,value,offset,2,65535,0);if(Buffer.TYPED_ARRAY_SUPPORT){this[offset]=value>>>8;this[offset+1]=value&255}else{objectWriteUInt16(this,value,offset,false)}return offset+2};function objectWriteUInt32(buf,value,offset,littleEndian){if(value<0)value=4294967295+value+1;for(var i=0,j=Math.min(buf.length-offset,4);i<j;++i){buf[offset+i]=value>>>(littleEndian?i:3-i)*8&255}}Buffer.prototype.writeUInt32LE=function writeUInt32LE(value,offset,noAssert){value=+value;offset=offset|0;if(!noAssert)checkInt(this,value,offset,4,4294967295,0);if(Buffer.TYPED_ARRAY_SUPPORT){this[offset+3]=value>>>24;this[offset+2]=value>>>16;this[offset+1]=value>>>8;this[offset]=value&255}else{objectWriteUInt32(this,value,offset,true)}return offset+4};Buffer.prototype.writeUInt32BE=function writeUInt32BE(value,offset,noAssert){value=+value;offset=offset|0;if(!noAssert)checkInt(this,value,offset,4,4294967295,0);if(Buffer.TYPED_ARRAY_SUPPORT){this[offset]=value>>>24;this[offset+1]=value>>>16;this[offset+2]=value>>>8;this[offset+3]=value&255}else{objectWriteUInt32(this,value,offset,false)}return offset+4};Buffer.prototype.writeIntLE=function writeIntLE(value,offset,byteLength,noAssert){value=+value;offset=offset|0;if(!noAssert){var limit=Math.pow(2,8*byteLength-1);checkInt(this,value,offset,byteLength,limit-1,-limit)}var i=0;var mul=1;var sub=0;this[offset]=value&255;while(++i<byteLength&&(mul*=256)){if(value<0&&sub===0&&this[offset+i-1]!==0){sub=1}this[offset+i]=(value/mul>>0)-sub&255}return offset+byteLength};Buffer.prototype.writeIntBE=function writeIntBE(value,offset,byteLength,noAssert){value=+value;offset=offset|0;if(!noAssert){var limit=Math.pow(2,8*byteLength-1);checkInt(this,value,offset,byteLength,limit-1,-limit)}var i=byteLength-1;var mul=1;var sub=0;this[offset+i]=value&255;while(--i>=0&&(mul*=256)){if(value<0&&sub===0&&this[offset+i+1]!==0){sub=1}this[offset+i]=(value/mul>>0)-sub&255}return offset+byteLength};Buffer.prototype.writeInt8=function writeInt8(value,offset,noAssert){value=+value;offset=offset|0;if(!noAssert)checkInt(this,value,offset,1,127,-128);if(!Buffer.TYPED_ARRAY_SUPPORT)value=Math.floor(value);if(value<0)value=255+value+1;this[offset]=value&255;return offset+1};Buffer.prototype.writeInt16LE=function writeInt16LE(value,offset,noAssert){value=+value;offset=offset|0;if(!noAssert)checkInt(this,value,offset,2,32767,-32768);if(Buffer.TYPED_ARRAY_SUPPORT){this[offset]=value&255;this[offset+1]=value>>>8}else{objectWriteUInt16(this,value,offset,true)}return offset+2};Buffer.prototype.writeInt16BE=function writeInt16BE(value,offset,noAssert){value=+value;offset=offset|0;if(!noAssert)checkInt(this,value,offset,2,32767,-32768);if(Buffer.TYPED_ARRAY_SUPPORT){this[offset]=value>>>8;this[offset+1]=value&255}else{objectWriteUInt16(this,value,offset,false)}return offset+2};Buffer.prototype.writeInt32LE=function writeInt32LE(value,offset,noAssert){value=+value;offset=offset|0;if(!noAssert)checkInt(this,value,offset,4,2147483647,-2147483648);if(Buffer.TYPED_ARRAY_SUPPORT){this[offset]=value&255;this[offset+1]=value>>>8;this[offset+2]=value>>>16;this[offset+3]=value>>>24}else{objectWriteUInt32(this,value,offset,true)}return offset+4};Buffer.prototype.writeInt32BE=function writeInt32BE(value,offset,noAssert){value=+value;offset=offset|0;if(!noAssert)checkInt(this,value,offset,4,2147483647,-2147483648);if(value<0)value=4294967295+value+1;if(Buffer.TYPED_ARRAY_SUPPORT){this[offset]=value>>>24;this[offset+1]=value>>>16;this[offset+2]=value>>>8;this[offset+3]=value&255}else{objectWriteUInt32(this,value,offset,false)}return offset+4};function checkIEEE754(buf,value,offset,ext,max,min){if(offset+ext>buf.length)throw new RangeError("Index out of range");if(offset<0)throw new RangeError("Index out of range")}function writeFloat(buf,value,offset,littleEndian,noAssert){if(!noAssert){checkIEEE754(buf,value,offset,4,3.4028234663852886e38,-3.4028234663852886e38)}ieee754.write(buf,value,offset,littleEndian,23,4);return offset+4}Buffer.prototype.writeFloatLE=function writeFloatLE(value,offset,noAssert){return writeFloat(this,value,offset,true,noAssert)};Buffer.prototype.writeFloatBE=function writeFloatBE(value,offset,noAssert){return writeFloat(this,value,offset,false,noAssert)};function writeDouble(buf,value,offset,littleEndian,noAssert){if(!noAssert){checkIEEE754(buf,value,offset,8,1.7976931348623157e308,-1.7976931348623157e308)}ieee754.write(buf,value,offset,littleEndian,52,8);return offset+8}Buffer.prototype.writeDoubleLE=function writeDoubleLE(value,offset,noAssert){return writeDouble(this,value,offset,true,noAssert)};Buffer.prototype.writeDoubleBE=function writeDoubleBE(value,offset,noAssert){return writeDouble(this,value,offset,false,noAssert)};Buffer.prototype.copy=function copy(target,targetStart,start,end){if(!start)start=0;if(!end&&end!==0)end=this.length;if(targetStart>=target.length)targetStart=target.length;if(!targetStart)targetStart=0;if(end>0&&end<start)end=start;if(end===start)return 0;if(target.length===0||this.length===0)return 0;if(targetStart<0){throw new RangeError("targetStart out of bounds")}if(start<0||start>=this.length)throw new RangeError("sourceStart out of bounds");if(end<0)throw new RangeError("sourceEnd out of bounds");if(end>this.length)end=this.length;if(target.length-targetStart<end-start){end=target.length-targetStart+start}var len=end-start;var i;if(this===target&&start<targetStart&&targetStart<end){for(i=len-1;i>=0;--i){target[i+targetStart]=this[i+start]}}else if(len<1e3||!Buffer.TYPED_ARRAY_SUPPORT){for(i=0;i<len;++i){target[i+targetStart]=this[i+start]}}else{Uint8Array.prototype.set.call(target,this.subarray(start,start+len),targetStart)}return len};Buffer.prototype.fill=function fill(val,start,end,encoding){if(typeof val==="string"){if(typeof start==="string"){encoding=start;start=0;end=this.length}else if(typeof end==="string"){encoding=end;end=this.length}if(val.length===1){var code=val.charCodeAt(0);if(code<256){val=code}}if(encoding!==undefined&&typeof encoding!=="string"){throw new TypeError("encoding must be a string")}if(typeof encoding==="string"&&!Buffer.isEncoding(encoding)){throw new TypeError("Unknown encoding: "+encoding)}}else if(typeof val==="number"){val=val&255}if(start<0||this.length<start||this.length<end){throw new RangeError("Out of range index")}if(end<=start){return this}start=start>>>0;end=end===undefined?this.length:end>>>0;if(!val)val=0;var i;if(typeof val==="number"){for(i=start;i<end;++i){this[i]=val}}else{var bytes=Buffer.isBuffer(val)?val:utf8ToBytes(new Buffer(val,encoding).toString());var len=bytes.length;for(i=0;i<end-start;++i){this[i+start]=bytes[i%len]}}return this};var INVALID_BASE64_RE=/[^+\/0-9A-Za-z-_]/g;function base64clean(str){str=stringtrim(str).replace(INVALID_BASE64_RE,"");if(str.length<2)return"";while(str.length%4!==0){str=str+"="}return str}function stringtrim(str){if(str.trim)return str.trim();return str.replace(/^\s+|\s+$/g,"")}function toHex(n){if(n<16)return"0"+n.toString(16);return n.toString(16)}function utf8ToBytes(string,units){units=units||Infinity;var codePoint;var length=string.length;var leadSurrogate=null;var bytes=[];for(var i=0;i<length;++i){codePoint=string.charCodeAt(i);if(codePoint>55295&&codePoint<57344){if(!leadSurrogate){if(codePoint>56319){if((units-=3)>-1)bytes.push(239,191,189);continue}else if(i+1===length){if((units-=3)>-1)bytes.push(239,191,189);continue}leadSurrogate=codePoint;continue}if(codePoint<56320){if((units-=3)>-1)bytes.push(239,191,189);leadSurrogate=codePoint;continue}codePoint=(leadSurrogate-55296<<10|codePoint-56320)+65536}else if(leadSurrogate){if((units-=3)>-1)bytes.push(239,191,189)}leadSurrogate=null;if(codePoint<128){if((units-=1)<0)break;bytes.push(codePoint)}else if(codePoint<2048){if((units-=2)<0)break;bytes.push(codePoint>>6|192,codePoint&63|128)}else if(codePoint<65536){if((units-=3)<0)break;bytes.push(codePoint>>12|224,codePoint>>6&63|128,codePoint&63|128)}else if(codePoint<1114112){if((units-=4)<0)break;bytes.push(codePoint>>18|240,codePoint>>12&63|128,codePoint>>6&63|128,codePoint&63|128)}else{throw new Error("Invalid code point")}}return bytes}function asciiToBytes(str){var byteArray=[];for(var i=0;i<str.length;++i){byteArray.push(str.charCodeAt(i)&255)}return byteArray}function utf16leToBytes(str,units){var c,hi,lo;var byteArray=[];for(var i=0;i<str.length;++i){if((units-=2)<0)break;c=str.charCodeAt(i);hi=c>>8;lo=c%256;byteArray.push(lo);byteArray.push(hi)}return byteArray}function base64ToBytes(str){return base64.toByteArray(base64clean(str))}function blitBuffer(src,dst,offset,length){for(var i=0;i<length;++i){if(i+offset>=dst.length||i>=src.length)break;dst[i+offset]=src[i]}return i}function isnan(val){return val!==val}}).call(this,typeof global!=="undefined"?global:typeof self!=="undefined"?self:typeof window!=="undefined"?window:{})},{"base64-js":2,ieee754:37,isarray:40}],6:[function(require,module,exports){(function(Buffer){function isArray(arg){if(Array.isArray){return Array.isArray(arg)}return objectToString(arg)==="[object Array]"}exports.isArray=isArray;function isBoolean(arg){return typeof arg==="boolean"}exports.isBoolean=isBoolean;function isNull(arg){return arg===null}exports.isNull=isNull;function isNullOrUndefined(arg){return arg==null}exports.isNullOrUndefined=isNullOrUndefined;function isNumber(arg){return typeof arg==="number"}exports.isNumber=isNumber;function isString(arg){return typeof arg==="string"}exports.isString=isString;function isSymbol(arg){return typeof arg==="symbol"}exports.isSymbol=isSymbol;function isUndefined(arg){return arg===void 0}exports.isUndefined=isUndefined;function isRegExp(re){return objectToString(re)==="[object RegExp]"}exports.isRegExp=isRegExp;function isObject(arg){return typeof arg==="object"&&arg!==null}exports.isObject=isObject;function isDate(d){return objectToString(d)==="[object Date]"}exports.isDate=isDate;function isError(e){return objectToString(e)==="[object Error]"||e instanceof Error}exports.isError=isError;function isFunction(arg){return typeof arg==="function"}exports.isFunction=isFunction;function isPrimitive(arg){return arg===null||typeof arg==="boolean"||typeof arg==="number"||typeof arg==="string"||typeof arg==="symbol"||typeof arg==="undefined"}exports.isPrimitive=isPrimitive;exports.isBuffer=Buffer.isBuffer;function objectToString(o){return Object.prototype.toString.call(o)}}).call(this,{isBuffer:require("../../is-buffer/index.js")})},{"../../is-buffer/index.js":39}],7:[function(require,module,exports){var ElementType=require("domelementtype");var entities=require("entities");var booleanAttributes={__proto__:null,allowfullscreen:true,async:true,autofocus:true,autoplay:true,checked:true,controls:true,default:true,defer:true,disabled:true,hidden:true,ismap:true,loop:true,multiple:true,muted:true,open:true,readonly:true,required:true,reversed:true,scoped:true,seamless:true,selected:true,typemustmatch:true};var unencodedElements={__proto__:null,style:true,script:true,xmp:true,iframe:true,noembed:true,noframes:true,plaintext:true,noscript:true};function formatAttrs(attributes,opts){if(!attributes)return;var output="",value;for(var key in attributes){value=attributes[key];if(output){output+=" "}if(!value&&booleanAttributes[key]){output+=key}else{output+=key+'="'+(opts.decodeEntities?entities.encodeXML(value):value)+'"'}}return output}var singleTag={__proto__:null,area:true,base:true,basefont:true,br:true,col:true,command:true,embed:true,frame:true,hr:true,img:true,input:true,isindex:true,keygen:true,link:true,meta:true,param:true,source:true,track:true,wbr:true};var render=module.exports=function(dom,opts){if(!Array.isArray(dom)&&!dom.cheerio)dom=[dom];opts=opts||{};var output="";for(var i=0;i<dom.length;i++){var elem=dom[i];if(elem.type==="root")output+=render(elem.children,opts);else if(ElementType.isTag(elem))output+=renderTag(elem,opts);else if(elem.type===ElementType.Directive)output+=renderDirective(elem);else if(elem.type===ElementType.Comment)output+=renderComment(elem);else if(elem.type===ElementType.CDATA)output+=renderCdata(elem);else output+=renderText(elem,opts)}return output};function renderTag(elem,opts){if(elem.name==="svg")opts={decodeEntities:opts.decodeEntities,xmlMode:true};var tag="<"+elem.name,attribs=formatAttrs(elem.attribs,opts);if(attribs){tag+=" "+attribs}if(opts.xmlMode&&(!elem.children||elem.children.length===0)){tag+="/>"}else{tag+=">";if(elem.children){tag+=render(elem.children,opts)}if(!singleTag[elem.name]||opts.xmlMode){tag+="</"+elem.name+">"}}return tag}function renderDirective(elem){return"<"+elem.data+">"}function renderText(elem,opts){var data=elem.data||"";if(opts.decodeEntities&&!(elem.parent&&elem.parent.name in unencodedElements)){data=entities.encodeXML(data)}return data}function renderCdata(elem){return"<![CDATA["+elem.children[0].data+"]]>"}function renderComment(elem){return"<!--"+elem.data+"-->"}},{domelementtype:8,entities:20}],8:[function(require,module,exports){module.exports={Text:"text",Directive:"directive",Comment:"comment",Script:"script",Style:"style",Tag:"tag",CDATA:"cdata",isTag:function(elem){return elem.type==="tag"||elem.type==="script"||elem.type==="style"}}},{}],9:[function(require,module,exports){module.exports={Text:"text",Directive:"directive",Comment:"comment",Script:"script",Style:"style",Tag:"tag",CDATA:"cdata",Doctype:"doctype",isTag:function(elem){return elem.type==="tag"||elem.type==="script"||elem.type==="style"}}},{}],10:[function(require,module,exports){var ElementType=require("domelementtype");var re_whitespace=/\s+/g;var NodePrototype=require("./lib/node");var ElementPrototype=require("./lib/element");function DomHandler(callback,options,elementCB){if(typeof callback==="object"){elementCB=options;options=callback;callback=null}else if(typeof options==="function"){elementCB=options;options=defaultOpts}this._callback=callback;this._options=options||defaultOpts;this._elementCB=elementCB;this.dom=[];this._done=false;this._tagStack=[];this._parser=this._parser||null}var defaultOpts={normalizeWhitespace:false,withStartIndices:false};DomHandler.prototype.onparserinit=function(parser){this._parser=parser};DomHandler.prototype.onreset=function(){DomHandler.call(this,this._callback,this._options,this._elementCB)};DomHandler.prototype.onend=function(){if(this._done)return;this._done=true;this._parser=null;this._handleCallback(null)};DomHandler.prototype._handleCallback=DomHandler.prototype.onerror=function(error){if(typeof this._callback==="function"){this._callback(error,this.dom)}else{if(error)throw error}};DomHandler.prototype.onclosetag=function(){var elem=this._tagStack.pop();if(this._elementCB)this._elementCB(elem)};DomHandler.prototype._addDomElement=function(element){var parent=this._tagStack[this._tagStack.length-1];var siblings=parent?parent.children:this.dom;var previousSibling=siblings[siblings.length-1];element.next=null;if(this._options.withStartIndices){element.startIndex=this._parser.startIndex}if(this._options.withDomLvl1){element.__proto__=element.type==="tag"?ElementPrototype:NodePrototype}if(previousSibling){element.prev=previousSibling;previousSibling.next=element}else{element.prev=null}siblings.push(element);element.parent=parent||null};DomHandler.prototype.onopentag=function(name,attribs){var element={type:name==="script"?ElementType.Script:name==="style"?ElementType.Style:ElementType.Tag,name:name,attribs:attribs,children:[]};this._addDomElement(element);this._tagStack.push(element)};DomHandler.prototype.ontext=function(data){var normalize=this._options.normalizeWhitespace||this._options.ignoreWhitespace;var lastTag;if(!this._tagStack.length&&this.dom.length&&(lastTag=this.dom[this.dom.length-1]).type===ElementType.Text){if(normalize){lastTag.data=(lastTag.data+data).replace(re_whitespace," ")}else{lastTag.data+=data}}else{if(this._tagStack.length&&(lastTag=this._tagStack[this._tagStack.length-1])&&(lastTag=lastTag.children[lastTag.children.length-1])&&lastTag.type===ElementType.Text){if(normalize){lastTag.data=(lastTag.data+data).replace(re_whitespace," ")}else{lastTag.data+=data}}else{if(normalize){data=data.replace(re_whitespace," ")}this._addDomElement({data:data,type:ElementType.Text})}}};DomHandler.prototype.oncomment=function(data){var lastTag=this._tagStack[this._tagStack.length-1];if(lastTag&&lastTag.type===ElementType.Comment){lastTag.data+=data;return}var element={data:data,type:ElementType.Comment};this._addDomElement(element);this._tagStack.push(element)};DomHandler.prototype.oncdatastart=function(){var element={children:[{data:"",type:ElementType.Text}],type:ElementType.CDATA};this._addDomElement(element);this._tagStack.push(element)};DomHandler.prototype.oncommentend=DomHandler.prototype.oncdataend=function(){this._tagStack.pop()};DomHandler.prototype.onprocessinginstruction=function(name,data){this._addDomElement({name:name,data:data,type:ElementType.Directive})};module.exports=DomHandler},{"./lib/element":11,"./lib/node":12,domelementtype:9}],11:[function(require,module,exports){var NodePrototype=require("./node");var ElementPrototype=module.exports=Object.create(NodePrototype);var domLvl1={tagName:"name"};Object.keys(domLvl1).forEach(function(key){var shorthand=domLvl1[key];Object.defineProperty(ElementPrototype,key,{get:function(){return this[shorthand]||null},set:function(val){this[shorthand]=val;return val}})})},{"./node":12}],12:[function(require,module,exports){var NodePrototype=module.exports={get firstChild(){var children=this.children;return children&&children[0]||null},get lastChild(){var children=this.children;return children&&children[children.length-1]||null},get nodeType(){return nodeTypes[this.type]||nodeTypes.element}};var domLvl1={tagName:"name",childNodes:"children",parentNode:"parent",previousSibling:"prev",nextSibling:"next",nodeValue:"data"};var nodeTypes={element:1,text:3,cdata:4,comment:8};Object.keys(domLvl1).forEach(function(key){var shorthand=domLvl1[key];Object.defineProperty(NodePrototype,key,{get:function(){return this[shorthand]||null},set:function(val){this[shorthand]=val;return val}})})},{}],13:[function(require,module,exports){var DomUtils=module.exports;[require("./lib/stringify"),require("./lib/traversal"),require("./lib/manipulation"),require("./lib/querying"),require("./lib/legacy"),require("./lib/helpers")].forEach(function(ext){Object.keys(ext).forEach(function(key){DomUtils[key]=ext[key].bind(DomUtils)})})},{"./lib/helpers":14,"./lib/legacy":15,"./lib/manipulation":16,"./lib/querying":17,"./lib/stringify":18,"./lib/traversal":19}],14:[function(require,module,exports){exports.removeSubsets=function(nodes){var idx=nodes.length,node,ancestor,replace;while(--idx>-1){node=ancestor=nodes[idx];nodes[idx]=null;replace=true;while(ancestor){if(nodes.indexOf(ancestor)>-1){replace=false;nodes.splice(idx,1);break}ancestor=ancestor.parent}if(replace){nodes[idx]=node}}return nodes};var POSITION={DISCONNECTED:1,PRECEDING:2,FOLLOWING:4,CONTAINS:8,CONTAINED_BY:16};var comparePos=exports.compareDocumentPosition=function(nodeA,nodeB){var aParents=[];var bParents=[];var current,sharedParent,siblings,aSibling,bSibling,idx;if(nodeA===nodeB){return 0}current=nodeA;while(current){aParents.unshift(current);current=current.parent}current=nodeB;while(current){bParents.unshift(current);current=current.parent}idx=0;while(aParents[idx]===bParents[idx]){idx++}if(idx===0){return POSITION.DISCONNECTED}sharedParent=aParents[idx-1];siblings=sharedParent.children;aSibling=aParents[idx];bSibling=bParents[idx];if(siblings.indexOf(aSibling)>siblings.indexOf(bSibling)){if(sharedParent===nodeB){return POSITION.FOLLOWING|POSITION.CONTAINED_BY}return POSITION.FOLLOWING}else{if(sharedParent===nodeA){return POSITION.PRECEDING|POSITION.CONTAINS}return POSITION.PRECEDING}};exports.uniqueSort=function(nodes){var idx=nodes.length,node,position;nodes=nodes.slice();while(--idx>-1){node=nodes[idx];position=nodes.indexOf(node);if(position>-1&&position<idx){nodes.splice(idx,1)}}nodes.sort(function(a,b){var relative=comparePos(a,b);if(relative&POSITION.PRECEDING){return-1}else if(relative&POSITION.FOLLOWING){return 1}return 0});return nodes}},{}],15:[function(require,module,exports){var ElementType=require("domelementtype");var isTag=exports.isTag=ElementType.isTag;exports.testElement=function(options,element){for(var key in options){if(!options.hasOwnProperty(key));else if(key==="tag_name"){if(!isTag(element)||!options.tag_name(element.name)){return false}}else if(key==="tag_type"){if(!options.tag_type(element.type))return false}else if(key==="tag_contains"){if(isTag(element)||!options.tag_contains(element.data)){return false}}else if(!element.attribs||!options[key](element.attribs[key])){return false}}return true};var Checks={tag_name:function(name){if(typeof name==="function"){return function(elem){return isTag(elem)&&name(elem.name)}}else if(name==="*"){return isTag}else{return function(elem){return isTag(elem)&&elem.name===name}}},tag_type:function(type){if(typeof type==="function"){return function(elem){return type(elem.type)}}else{return function(elem){return elem.type===type}}},tag_contains:function(data){if(typeof data==="function"){return function(elem){return!isTag(elem)&&data(elem.data)}}else{return function(elem){return!isTag(elem)&&elem.data===data}}}};function getAttribCheck(attrib,value){if(typeof value==="function"){return function(elem){return elem.attribs&&value(elem.attribs[attrib])}}else{return function(elem){return elem.attribs&&elem.attribs[attrib]===value}}}function combineFuncs(a,b){return function(elem){return a(elem)||b(elem)}}exports.getElements=function(options,element,recurse,limit){var funcs=Object.keys(options).map(function(key){var value=options[key];return key in Checks?Checks[key](value):getAttribCheck(key,value)});return funcs.length===0?[]:this.filter(funcs.reduce(combineFuncs),element,recurse,limit)};exports.getElementById=function(id,element,recurse){if(!Array.isArray(element))element=[element];return this.findOne(getAttribCheck("id",id),element,recurse!==false)};exports.getElementsByTagName=function(name,element,recurse,limit){return this.filter(Checks.tag_name(name),element,recurse,limit)};exports.getElementsByTagType=function(type,element,recurse,limit){return this.filter(Checks.tag_type(type),element,recurse,limit)}},{domelementtype:9}],16:[function(require,module,exports){exports.removeElement=function(elem){if(elem.prev)elem.prev.next=elem.next;if(elem.next)elem.next.prev=elem.prev;if(elem.parent){var childs=elem.parent.children;childs.splice(childs.lastIndexOf(elem),1)}};exports.replaceElement=function(elem,replacement){var prev=replacement.prev=elem.prev;if(prev){prev.next=replacement}var next=replacement.next=elem.next;if(next){next.prev=replacement}var parent=replacement.parent=elem.parent;if(parent){var childs=parent.children;childs[childs.lastIndexOf(elem)]=replacement}};exports.appendChild=function(elem,child){child.parent=elem;if(elem.children.push(child)!==1){var sibling=elem.children[elem.children.length-2];sibling.next=child;child.prev=sibling;child.next=null}};exports.append=function(elem,next){var parent=elem.parent,currNext=elem.next;next.next=currNext;next.prev=elem;elem.next=next;next.parent=parent;if(currNext){currNext.prev=next;if(parent){var childs=parent.children;childs.splice(childs.lastIndexOf(currNext),0,next)}}else if(parent){parent.children.push(next)}};exports.prepend=function(elem,prev){var parent=elem.parent;if(parent){var childs=parent.children;childs.splice(childs.lastIndexOf(elem),0,prev)}if(elem.prev){elem.prev.next=prev}prev.parent=parent;prev.prev=elem.prev;prev.next=elem;elem.prev=prev}},{}],17:[function(require,module,exports){var isTag=require("domelementtype").isTag;module.exports={filter:filter,find:find,findOneChild:findOneChild,findOne:findOne,existsOne:existsOne,findAll:findAll};function filter(test,element,recurse,limit){if(!Array.isArray(element))element=[element];if(typeof limit!=="number"||!isFinite(limit)){limit=Infinity}return find(test,element,recurse!==false,limit)}function find(test,elems,recurse,limit){var result=[],childs;for(var i=0,j=elems.length;i<j;i++){if(test(elems[i])){result.push(elems[i]);if(--limit<=0)break}childs=elems[i].children;if(recurse&&childs&&childs.length>0){childs=find(test,childs,recurse,limit);result=result.concat(childs);limit-=childs.length;if(limit<=0)break}}return result}function findOneChild(test,elems){for(var i=0,l=elems.length;i<l;i++){if(test(elems[i]))return elems[i]}return null}function findOne(test,elems){var elem=null;for(var i=0,l=elems.length;i<l&&!elem;i++){if(!isTag(elems[i])){continue}else if(test(elems[i])){elem=elems[i]}else if(elems[i].children.length>0){elem=findOne(test,elems[i].children)}}return elem}function existsOne(test,elems){for(var i=0,l=elems.length;i<l;i++){if(isTag(elems[i])&&(test(elems[i])||elems[i].children.length>0&&existsOne(test,elems[i].children))){return true}}return false}function findAll(test,elems){var result=[];for(var i=0,j=elems.length;i<j;i++){if(!isTag(elems[i]))continue;if(test(elems[i]))result.push(elems[i]);if(elems[i].children.length>0){result=result.concat(findAll(test,elems[i].children))}}return result}},{domelementtype:9}],18:[function(require,module,exports){var ElementType=require("domelementtype"),getOuterHTML=require("dom-serializer"),isTag=ElementType.isTag;module.exports={getInnerHTML:getInnerHTML,getOuterHTML:getOuterHTML,getText:getText};function getInnerHTML(elem,opts){return elem.children?elem.children.map(function(elem){return getOuterHTML(elem,opts)}).join(""):""}function getText(elem){if(Array.isArray(elem))return elem.map(getText).join("");if(isTag(elem)||elem.type===ElementType.CDATA)return getText(elem.children);if(elem.type===ElementType.Text)return elem.data;return""}},{"dom-serializer":7,domelementtype:9}],19:[function(require,module,exports){var getChildren=exports.getChildren=function(elem){return elem.children};var getParent=exports.getParent=function(elem){return elem.parent};exports.getSiblings=function(elem){var parent=getParent(elem);return parent?getChildren(parent):[elem]};exports.getAttributeValue=function(elem,name){return elem.attribs&&elem.attribs[name]};exports.hasAttrib=function(elem,name){return!!elem.attribs&&hasOwnProperty.call(elem.attribs,name)};exports.getName=function(elem){return elem.name}},{}],20:[function(require,module,exports){var encode=require("./lib/encode.js"),decode=require("./lib/decode.js");exports.decode=function(data,level){return(!level||level<=0?decode.XML:decode.HTML)(data)};exports.decodeStrict=function(data,level){return(!level||level<=0?decode.XML:decode.HTMLStrict)(data)};exports.encode=function(data,level){return(!level||level<=0?encode.XML:encode.HTML)(data)};exports.encodeXML=encode.XML;exports.encodeHTML4=exports.encodeHTML5=exports.encodeHTML=encode.HTML;exports.decodeXML=exports.decodeXMLStrict=decode.XML;exports.decodeHTML4=exports.decodeHTML5=exports.decodeHTML=decode.HTML;exports.decodeHTML4Strict=exports.decodeHTML5Strict=exports.decodeHTMLStrict=decode.HTMLStrict;exports.escape=encode.escape},{"./lib/decode.js":21,"./lib/encode.js":23}],21:[function(require,module,exports){var entityMap=require("../maps/entities.json"),legacyMap=require("../maps/legacy.json"),xmlMap=require("../maps/xml.json"),decodeCodePoint=require("./decode_codepoint.js");var decodeXMLStrict=getStrictDecoder(xmlMap),decodeHTMLStrict=getStrictDecoder(entityMap);function getStrictDecoder(map){var keys=Object.keys(map).join("|"),replace=getReplacer(map);keys+="|#[xX][\\da-fA-F]+|#\\d+";var re=new RegExp("&(?:"+keys+");","g");return function(str){return String(str).replace(re,replace)}}var decodeHTML=function(){var legacy=Object.keys(legacyMap).sort(sorter);var keys=Object.keys(entityMap).sort(sorter);for(var i=0,j=0;i<keys.length;i++){if(legacy[j]===keys[i]){keys[i]+=";?";j++}else{keys[i]+=";"}}var re=new RegExp("&(?:"+keys.join("|")+"|#[xX][\\da-fA-F]+;?|#\\d+;?)","g"),replace=getReplacer(entityMap);function replacer(str){if(str.substr(-1)!==";")str+=";";return replace(str)}return function(str){return String(str).replace(re,replacer)}}();function sorter(a,b){return a<b?1:-1}function getReplacer(map){return function replace(str){if(str.charAt(1)==="#"){if(str.charAt(2)==="X"||str.charAt(2)==="x"){return decodeCodePoint(parseInt(str.substr(3),16))}return decodeCodePoint(parseInt(str.substr(2),10))}return map[str.slice(1,-1)];
-}}module.exports={XML:decodeXMLStrict,HTML:decodeHTML,HTMLStrict:decodeHTMLStrict}},{"../maps/entities.json":25,"../maps/legacy.json":26,"../maps/xml.json":27,"./decode_codepoint.js":22}],22:[function(require,module,exports){var decodeMap=require("../maps/decode.json");module.exports=decodeCodePoint;function decodeCodePoint(codePoint){if(codePoint>=55296&&codePoint<=57343||codePoint>1114111){return"�"}if(codePoint in decodeMap){codePoint=decodeMap[codePoint]}var output="";if(codePoint>65535){codePoint-=65536;output+=String.fromCharCode(codePoint>>>10&1023|55296);codePoint=56320|codePoint&1023}output+=String.fromCharCode(codePoint);return output}},{"../maps/decode.json":24}],23:[function(require,module,exports){var inverseXML=getInverseObj(require("../maps/xml.json")),xmlReplacer=getInverseReplacer(inverseXML);exports.XML=getInverse(inverseXML,xmlReplacer);var inverseHTML=getInverseObj(require("../maps/entities.json")),htmlReplacer=getInverseReplacer(inverseHTML);exports.HTML=getInverse(inverseHTML,htmlReplacer);function getInverseObj(obj){return Object.keys(obj).sort().reduce(function(inverse,name){inverse[obj[name]]="&"+name+";";return inverse},{})}function getInverseReplacer(inverse){var single=[],multiple=[];Object.keys(inverse).forEach(function(k){if(k.length===1){single.push("\\"+k)}else{multiple.push(k)}});multiple.unshift("["+single.join("")+"]");return new RegExp(multiple.join("|"),"g")}var re_nonASCII=/[^\0-\x7F]/g,re_astralSymbols=/[\uD800-\uDBFF][\uDC00-\uDFFF]/g;function singleCharReplacer(c){return"&#x"+c.charCodeAt(0).toString(16).toUpperCase()+";"}function astralReplacer(c){var high=c.charCodeAt(0);var low=c.charCodeAt(1);var codePoint=(high-55296)*1024+low-56320+65536;return"&#x"+codePoint.toString(16).toUpperCase()+";"}function getInverse(inverse,re){function func(name){return inverse[name]}return function(data){return data.replace(re,func).replace(re_astralSymbols,astralReplacer).replace(re_nonASCII,singleCharReplacer)}}var re_xmlChars=getInverseReplacer(inverseXML);function escapeXML(data){return data.replace(re_xmlChars,singleCharReplacer).replace(re_astralSymbols,astralReplacer).replace(re_nonASCII,singleCharReplacer)}exports.escape=escapeXML},{"../maps/entities.json":25,"../maps/xml.json":27}],24:[function(require,module,exports){module.exports={0:65533,128:8364,130:8218,131:402,132:8222,133:8230,134:8224,135:8225,136:710,137:8240,138:352,139:8249,140:338,142:381,145:8216,146:8217,147:8220,148:8221,149:8226,150:8211,151:8212,152:732,153:8482,154:353,155:8250,156:339,158:382,159:376}},{}],25:[function(require,module,exports){module.exports={Aacute:"Á",aacute:"á",Abreve:"Ă",abreve:"ă",ac:"∾",acd:"∿",acE:"∾̳",Acirc:"Â",acirc:"â",acute:"´",Acy:"А",acy:"а",AElig:"Æ",aelig:"æ",af:"⁡",Afr:"𝔄",afr:"𝔞",Agrave:"À",agrave:"à",alefsym:"ℵ",aleph:"ℵ",Alpha:"Α",alpha:"α",Amacr:"Ā",amacr:"ā",amalg:"⨿",amp:"&",AMP:"&",andand:"⩕",And:"⩓",and:"∧",andd:"⩜",andslope:"⩘",andv:"⩚",ang:"∠",ange:"⦤",angle:"∠",angmsdaa:"⦨",angmsdab:"⦩",angmsdac:"⦪",angmsdad:"⦫",angmsdae:"⦬",angmsdaf:"⦭",angmsdag:"⦮",angmsdah:"⦯",angmsd:"∡",angrt:"∟",angrtvb:"⊾",angrtvbd:"⦝",angsph:"∢",angst:"Å",angzarr:"⍼",Aogon:"Ą",aogon:"ą",Aopf:"𝔸",aopf:"𝕒",apacir:"⩯",ap:"≈",apE:"⩰",ape:"≊",apid:"≋",apos:"'",ApplyFunction:"⁡",approx:"≈",approxeq:"≊",Aring:"Å",aring:"å",Ascr:"𝒜",ascr:"𝒶",Assign:"≔",ast:"*",asymp:"≈",asympeq:"≍",Atilde:"Ã",atilde:"ã",Auml:"Ä",auml:"ä",awconint:"∳",awint:"⨑",backcong:"≌",backepsilon:"϶",backprime:"‵",backsim:"∽",backsimeq:"⋍",Backslash:"∖",Barv:"⫧",barvee:"⊽",barwed:"⌅",Barwed:"⌆",barwedge:"⌅",bbrk:"⎵",bbrktbrk:"⎶",bcong:"≌",Bcy:"Б",bcy:"б",bdquo:"„",becaus:"∵",because:"∵",Because:"∵",bemptyv:"⦰",bepsi:"϶",bernou:"ℬ",Bernoullis:"ℬ",Beta:"Β",beta:"β",beth:"ℶ",between:"≬",Bfr:"𝔅",bfr:"𝔟",bigcap:"⋂",bigcirc:"◯",bigcup:"⋃",bigodot:"⨀",bigoplus:"⨁",bigotimes:"⨂",bigsqcup:"⨆",bigstar:"★",bigtriangledown:"▽",bigtriangleup:"△",biguplus:"⨄",bigvee:"⋁",bigwedge:"⋀",bkarow:"⤍",blacklozenge:"⧫",blacksquare:"▪",blacktriangle:"▴",blacktriangledown:"▾",blacktriangleleft:"◂",blacktriangleright:"▸",blank:"␣",blk12:"▒",blk14:"░",blk34:"▓",block:"█",bne:"=⃥",bnequiv:"≡⃥",bNot:"⫭",bnot:"⌐",Bopf:"𝔹",bopf:"𝕓",bot:"⊥",bottom:"⊥",bowtie:"⋈",boxbox:"⧉",boxdl:"┐",boxdL:"╕",boxDl:"╖",boxDL:"╗",boxdr:"┌",boxdR:"╒",boxDr:"╓",boxDR:"╔",boxh:"─",boxH:"═",boxhd:"┬",boxHd:"╤",boxhD:"╥",boxHD:"╦",boxhu:"┴",boxHu:"╧",boxhU:"╨",boxHU:"╩",boxminus:"⊟",boxplus:"⊞",boxtimes:"⊠",boxul:"┘",boxuL:"╛",boxUl:"╜",boxUL:"╝",boxur:"└",boxuR:"╘",boxUr:"╙",boxUR:"╚",boxv:"│",boxV:"║",boxvh:"┼",boxvH:"╪",boxVh:"╫",boxVH:"╬",boxvl:"┤",boxvL:"╡",boxVl:"╢",boxVL:"╣",boxvr:"├",boxvR:"╞",boxVr:"╟",boxVR:"╠",bprime:"‵",breve:"˘",Breve:"˘",brvbar:"¦",bscr:"𝒷",Bscr:"ℬ",bsemi:"⁏",bsim:"∽",bsime:"⋍",bsolb:"⧅",bsol:"\\",bsolhsub:"⟈",bull:"•",bullet:"•",bump:"≎",bumpE:"⪮",bumpe:"≏",Bumpeq:"≎",bumpeq:"≏",Cacute:"Ć",cacute:"ć",capand:"⩄",capbrcup:"⩉",capcap:"⩋",cap:"∩",Cap:"⋒",capcup:"⩇",capdot:"⩀",CapitalDifferentialD:"ⅅ",caps:"∩︀",caret:"⁁",caron:"ˇ",Cayleys:"ℭ",ccaps:"⩍",Ccaron:"Č",ccaron:"č",Ccedil:"Ç",ccedil:"ç",Ccirc:"Ĉ",ccirc:"ĉ",Cconint:"∰",ccups:"⩌",ccupssm:"⩐",Cdot:"Ċ",cdot:"ċ",cedil:"¸",Cedilla:"¸",cemptyv:"⦲",cent:"¢",centerdot:"·",CenterDot:"·",cfr:"𝔠",Cfr:"ℭ",CHcy:"Ч",chcy:"ч",check:"✓",checkmark:"✓",Chi:"Χ",chi:"χ",circ:"ˆ",circeq:"≗",circlearrowleft:"↺",circlearrowright:"↻",circledast:"⊛",circledcirc:"⊚",circleddash:"⊝",CircleDot:"⊙",circledR:"®",circledS:"Ⓢ",CircleMinus:"⊖",CirclePlus:"⊕",CircleTimes:"⊗",cir:"○",cirE:"⧃",cire:"≗",cirfnint:"⨐",cirmid:"⫯",cirscir:"⧂",ClockwiseContourIntegral:"∲",CloseCurlyDoubleQuote:"”",CloseCurlyQuote:"’",clubs:"♣",clubsuit:"♣",colon:":",Colon:"∷",Colone:"⩴",colone:"≔",coloneq:"≔",comma:",",commat:"@",comp:"∁",compfn:"∘",complement:"∁",complexes:"ℂ",cong:"≅",congdot:"⩭",Congruent:"≡",conint:"∮",Conint:"∯",ContourIntegral:"∮",copf:"𝕔",Copf:"ℂ",coprod:"∐",Coproduct:"∐",copy:"©",COPY:"©",copysr:"℗",CounterClockwiseContourIntegral:"∳",crarr:"↵",cross:"✗",Cross:"⨯",Cscr:"𝒞",cscr:"𝒸",csub:"⫏",csube:"⫑",csup:"⫐",csupe:"⫒",ctdot:"⋯",cudarrl:"⤸",cudarrr:"⤵",cuepr:"⋞",cuesc:"⋟",cularr:"↶",cularrp:"⤽",cupbrcap:"⩈",cupcap:"⩆",CupCap:"≍",cup:"∪",Cup:"⋓",cupcup:"⩊",cupdot:"⊍",cupor:"⩅",cups:"∪︀",curarr:"↷",curarrm:"⤼",curlyeqprec:"⋞",curlyeqsucc:"⋟",curlyvee:"⋎",curlywedge:"⋏",curren:"¤",curvearrowleft:"↶",curvearrowright:"↷",cuvee:"⋎",cuwed:"⋏",cwconint:"∲",cwint:"∱",cylcty:"⌭",dagger:"†",Dagger:"‡",daleth:"ℸ",darr:"↓",Darr:"↡",dArr:"⇓",dash:"‐",Dashv:"⫤",dashv:"⊣",dbkarow:"⤏",dblac:"˝",Dcaron:"Ď",dcaron:"ď",Dcy:"Д",dcy:"д",ddagger:"‡",ddarr:"⇊",DD:"ⅅ",dd:"ⅆ",DDotrahd:"⤑",ddotseq:"⩷",deg:"°",Del:"∇",Delta:"Δ",delta:"δ",demptyv:"⦱",dfisht:"⥿",Dfr:"𝔇",dfr:"𝔡",dHar:"⥥",dharl:"⇃",dharr:"⇂",DiacriticalAcute:"´",DiacriticalDot:"˙",DiacriticalDoubleAcute:"˝",DiacriticalGrave:"`",DiacriticalTilde:"˜",diam:"⋄",diamond:"⋄",Diamond:"⋄",diamondsuit:"♦",diams:"♦",die:"¨",DifferentialD:"ⅆ",digamma:"ϝ",disin:"⋲",div:"÷",divide:"÷",divideontimes:"⋇",divonx:"⋇",DJcy:"Ђ",djcy:"ђ",dlcorn:"⌞",dlcrop:"⌍",dollar:"$",Dopf:"𝔻",dopf:"𝕕",Dot:"¨",dot:"˙",DotDot:"⃜",doteq:"≐",doteqdot:"≑",DotEqual:"≐",dotminus:"∸",dotplus:"∔",dotsquare:"⊡",doublebarwedge:"⌆",DoubleContourIntegral:"∯",DoubleDot:"¨",DoubleDownArrow:"⇓",DoubleLeftArrow:"⇐",DoubleLeftRightArrow:"⇔",DoubleLeftTee:"⫤",DoubleLongLeftArrow:"⟸",DoubleLongLeftRightArrow:"⟺",DoubleLongRightArrow:"⟹",DoubleRightArrow:"⇒",DoubleRightTee:"⊨",DoubleUpArrow:"⇑",DoubleUpDownArrow:"⇕",DoubleVerticalBar:"∥",DownArrowBar:"⤓",downarrow:"↓",DownArrow:"↓",Downarrow:"⇓",DownArrowUpArrow:"⇵",DownBreve:"̑",downdownarrows:"⇊",downharpoonleft:"⇃",downharpoonright:"⇂",DownLeftRightVector:"⥐",DownLeftTeeVector:"⥞",DownLeftVectorBar:"⥖",DownLeftVector:"↽",DownRightTeeVector:"⥟",DownRightVectorBar:"⥗",DownRightVector:"⇁",DownTeeArrow:"↧",DownTee:"⊤",drbkarow:"⤐",drcorn:"⌟",drcrop:"⌌",Dscr:"𝒟",dscr:"𝒹",DScy:"Ѕ",dscy:"ѕ",dsol:"⧶",Dstrok:"Đ",dstrok:"đ",dtdot:"⋱",dtri:"▿",dtrif:"▾",duarr:"⇵",duhar:"⥯",dwangle:"⦦",DZcy:"Џ",dzcy:"џ",dzigrarr:"⟿",Eacute:"É",eacute:"é",easter:"⩮",Ecaron:"Ě",ecaron:"ě",Ecirc:"Ê",ecirc:"ê",ecir:"≖",ecolon:"≕",Ecy:"Э",ecy:"э",eDDot:"⩷",Edot:"Ė",edot:"ė",eDot:"≑",ee:"ⅇ",efDot:"≒",Efr:"𝔈",efr:"𝔢",eg:"⪚",Egrave:"È",egrave:"è",egs:"⪖",egsdot:"⪘",el:"⪙",Element:"∈",elinters:"⏧",ell:"ℓ",els:"⪕",elsdot:"⪗",Emacr:"Ē",emacr:"ē",empty:"∅",emptyset:"∅",EmptySmallSquare:"◻",emptyv:"∅",EmptyVerySmallSquare:"▫",emsp13:" ",emsp14:" ",emsp:" ",ENG:"Ŋ",eng:"ŋ",ensp:" ",Eogon:"Ę",eogon:"ę",Eopf:"𝔼",eopf:"𝕖",epar:"⋕",eparsl:"⧣",eplus:"⩱",epsi:"ε",Epsilon:"Ε",epsilon:"ε",epsiv:"ϵ",eqcirc:"≖",eqcolon:"≕",eqsim:"≂",eqslantgtr:"⪖",eqslantless:"⪕",Equal:"⩵",equals:"=",EqualTilde:"≂",equest:"≟",Equilibrium:"⇌",equiv:"≡",equivDD:"⩸",eqvparsl:"⧥",erarr:"⥱",erDot:"≓",escr:"ℯ",Escr:"ℰ",esdot:"≐",Esim:"⩳",esim:"≂",Eta:"Η",eta:"η",ETH:"Ð",eth:"ð",Euml:"Ë",euml:"ë",euro:"€",excl:"!",exist:"∃",Exists:"∃",expectation:"ℰ",exponentiale:"ⅇ",ExponentialE:"ⅇ",fallingdotseq:"≒",Fcy:"Ф",fcy:"ф",female:"♀",ffilig:"ffi",fflig:"ff",ffllig:"ffl",Ffr:"𝔉",ffr:"𝔣",filig:"fi",FilledSmallSquare:"◼",FilledVerySmallSquare:"▪",fjlig:"fj",flat:"♭",fllig:"fl",fltns:"▱",fnof:"ƒ",Fopf:"𝔽",fopf:"𝕗",forall:"∀",ForAll:"∀",fork:"⋔",forkv:"⫙",Fouriertrf:"ℱ",fpartint:"⨍",frac12:"½",frac13:"⅓",frac14:"¼",frac15:"⅕",frac16:"⅙",frac18:"⅛",frac23:"⅔",frac25:"⅖",frac34:"¾",frac35:"⅗",frac38:"⅜",frac45:"⅘",frac56:"⅚",frac58:"⅝",frac78:"⅞",frasl:"⁄",frown:"⌢",fscr:"𝒻",Fscr:"ℱ",gacute:"ǵ",Gamma:"Γ",gamma:"γ",Gammad:"Ϝ",gammad:"ϝ",gap:"⪆",Gbreve:"Ğ",gbreve:"ğ",Gcedil:"Ģ",Gcirc:"Ĝ",gcirc:"ĝ",Gcy:"Г",gcy:"г",Gdot:"Ġ",gdot:"ġ",ge:"≥",gE:"≧",gEl:"⪌",gel:"⋛",geq:"≥",geqq:"≧",geqslant:"⩾",gescc:"⪩",ges:"⩾",gesdot:"⪀",gesdoto:"⪂",gesdotol:"⪄",gesl:"⋛︀",gesles:"⪔",Gfr:"𝔊",gfr:"𝔤",gg:"≫",Gg:"⋙",ggg:"⋙",gimel:"ℷ",GJcy:"Ѓ",gjcy:"ѓ",gla:"⪥",gl:"≷",glE:"⪒",glj:"⪤",gnap:"⪊",gnapprox:"⪊",gne:"⪈",gnE:"≩",gneq:"⪈",gneqq:"≩",gnsim:"⋧",Gopf:"𝔾",gopf:"𝕘",grave:"`",GreaterEqual:"≥",GreaterEqualLess:"⋛",GreaterFullEqual:"≧",GreaterGreater:"⪢",GreaterLess:"≷",GreaterSlantEqual:"⩾",GreaterTilde:"≳",Gscr:"𝒢",gscr:"ℊ",gsim:"≳",gsime:"⪎",gsiml:"⪐",gtcc:"⪧",gtcir:"⩺",gt:">",GT:">",Gt:"≫",gtdot:"⋗",gtlPar:"⦕",gtquest:"⩼",gtrapprox:"⪆",gtrarr:"⥸",gtrdot:"⋗",gtreqless:"⋛",gtreqqless:"⪌",gtrless:"≷",gtrsim:"≳",gvertneqq:"≩︀",gvnE:"≩︀",Hacek:"ˇ",hairsp:" ",half:"½",hamilt:"ℋ",HARDcy:"Ъ",hardcy:"ъ",harrcir:"⥈",harr:"↔",hArr:"⇔",harrw:"↭",Hat:"^",hbar:"ℏ",Hcirc:"Ĥ",hcirc:"ĥ",hearts:"♥",heartsuit:"♥",hellip:"…",hercon:"⊹",hfr:"𝔥",Hfr:"ℌ",HilbertSpace:"ℋ",hksearow:"⤥",hkswarow:"⤦",hoarr:"⇿",homtht:"∻",hookleftarrow:"↩",hookrightarrow:"↪",hopf:"𝕙",Hopf:"ℍ",horbar:"―",HorizontalLine:"─",hscr:"𝒽",Hscr:"ℋ",hslash:"ℏ",Hstrok:"Ħ",hstrok:"ħ",HumpDownHump:"≎",HumpEqual:"≏",hybull:"⁃",hyphen:"‐",Iacute:"Í",iacute:"í",ic:"⁣",Icirc:"Î",icirc:"î",Icy:"И",icy:"и",Idot:"İ",IEcy:"Е",iecy:"е",iexcl:"¡",iff:"⇔",ifr:"𝔦",Ifr:"ℑ",Igrave:"Ì",igrave:"ì",ii:"ⅈ",iiiint:"⨌",iiint:"∭",iinfin:"⧜",iiota:"℩",IJlig:"IJ",ijlig:"ij",Imacr:"Ī",imacr:"ī",image:"ℑ",ImaginaryI:"ⅈ",imagline:"ℐ",imagpart:"ℑ",imath:"ı",Im:"ℑ",imof:"⊷",imped:"Ƶ",Implies:"⇒",incare:"℅",in:"∈",infin:"∞",infintie:"⧝",inodot:"ı",intcal:"⊺",int:"∫",Int:"∬",integers:"ℤ",Integral:"∫",intercal:"⊺",Intersection:"⋂",intlarhk:"⨗",intprod:"⨼",InvisibleComma:"⁣",InvisibleTimes:"⁢",IOcy:"Ё",iocy:"ё",Iogon:"Į",iogon:"į",Iopf:"𝕀",iopf:"𝕚",Iota:"Ι",iota:"ι",iprod:"⨼",iquest:"¿",iscr:"𝒾",Iscr:"ℐ",isin:"∈",isindot:"⋵",isinE:"⋹",isins:"⋴",isinsv:"⋳",isinv:"∈",it:"⁢",Itilde:"Ĩ",itilde:"ĩ",Iukcy:"І",iukcy:"і",Iuml:"Ï",iuml:"ï",Jcirc:"Ĵ",jcirc:"ĵ",Jcy:"Й",jcy:"й",Jfr:"𝔍",jfr:"𝔧",jmath:"ȷ",Jopf:"𝕁",jopf:"𝕛",Jscr:"𝒥",jscr:"𝒿",Jsercy:"Ј",jsercy:"ј",Jukcy:"Є",jukcy:"є",Kappa:"Κ",kappa:"κ",kappav:"ϰ",Kcedil:"Ķ",kcedil:"ķ",Kcy:"К",kcy:"к",Kfr:"𝔎",kfr:"𝔨",kgreen:"ĸ",KHcy:"Х",khcy:"х",KJcy:"Ќ",kjcy:"ќ",Kopf:"𝕂",kopf:"𝕜",Kscr:"𝒦",kscr:"𝓀",lAarr:"⇚",Lacute:"Ĺ",lacute:"ĺ",laemptyv:"⦴",lagran:"ℒ",Lambda:"Λ",lambda:"λ",lang:"⟨",Lang:"⟪",langd:"⦑",langle:"⟨",lap:"⪅",Laplacetrf:"ℒ",laquo:"«",larrb:"⇤",larrbfs:"⤟",larr:"←",Larr:"↞",lArr:"⇐",larrfs:"⤝",larrhk:"↩",larrlp:"↫",larrpl:"⤹",larrsim:"⥳",larrtl:"↢",latail:"⤙",lAtail:"⤛",lat:"⪫",late:"⪭",lates:"⪭︀",lbarr:"⤌",lBarr:"⤎",lbbrk:"❲",lbrace:"{",lbrack:"[",lbrke:"⦋",lbrksld:"⦏",lbrkslu:"⦍",Lcaron:"Ľ",lcaron:"ľ",Lcedil:"Ļ",lcedil:"ļ",lceil:"⌈",lcub:"{",Lcy:"Л",lcy:"л",ldca:"⤶",ldquo:"“",ldquor:"„",ldrdhar:"⥧",ldrushar:"⥋",ldsh:"↲",le:"≤",lE:"≦",LeftAngleBracket:"⟨",LeftArrowBar:"⇤",leftarrow:"←",LeftArrow:"←",Leftarrow:"⇐",LeftArrowRightArrow:"⇆",leftarrowtail:"↢",LeftCeiling:"⌈",LeftDoubleBracket:"⟦",LeftDownTeeVector:"⥡",LeftDownVectorBar:"⥙",LeftDownVector:"⇃",LeftFloor:"⌊",leftharpoondown:"↽",leftharpoonup:"↼",leftleftarrows:"⇇",leftrightarrow:"↔",LeftRightArrow:"↔",Leftrightarrow:"⇔",leftrightarrows:"⇆",leftrightharpoons:"⇋",leftrightsquigarrow:"↭",LeftRightVector:"⥎",LeftTeeArrow:"↤",LeftTee:"⊣",LeftTeeVector:"⥚",leftthreetimes:"⋋",LeftTriangleBar:"⧏",LeftTriangle:"⊲",LeftTriangleEqual:"⊴",LeftUpDownVector:"⥑",LeftUpTeeVector:"⥠",LeftUpVectorBar:"⥘",LeftUpVector:"↿",LeftVectorBar:"⥒",LeftVector:"↼",lEg:"⪋",leg:"⋚",leq:"≤",leqq:"≦",leqslant:"⩽",lescc:"⪨",les:"⩽",lesdot:"⩿",lesdoto:"⪁",lesdotor:"⪃",lesg:"⋚︀",lesges:"⪓",lessapprox:"⪅",lessdot:"⋖",lesseqgtr:"⋚",lesseqqgtr:"⪋",LessEqualGreater:"⋚",LessFullEqual:"≦",LessGreater:"≶",lessgtr:"≶",LessLess:"⪡",lesssim:"≲",LessSlantEqual:"⩽",LessTilde:"≲",lfisht:"⥼",lfloor:"⌊",Lfr:"𝔏",lfr:"𝔩",lg:"≶",lgE:"⪑",lHar:"⥢",lhard:"↽",lharu:"↼",lharul:"⥪",lhblk:"▄",LJcy:"Љ",ljcy:"љ",llarr:"⇇",ll:"≪",Ll:"⋘",llcorner:"⌞",Lleftarrow:"⇚",llhard:"⥫",lltri:"◺",Lmidot:"Ŀ",lmidot:"ŀ",lmoustache:"⎰",lmoust:"⎰",lnap:"⪉",lnapprox:"⪉",lne:"⪇",lnE:"≨",lneq:"⪇",lneqq:"≨",lnsim:"⋦",loang:"⟬",loarr:"⇽",lobrk:"⟦",longleftarrow:"⟵",LongLeftArrow:"⟵",Longleftarrow:"⟸",longleftrightarrow:"⟷",LongLeftRightArrow:"⟷",Longleftrightarrow:"⟺",longmapsto:"⟼",longrightarrow:"⟶",LongRightArrow:"⟶",Longrightarrow:"⟹",looparrowleft:"↫",looparrowright:"↬",lopar:"⦅",Lopf:"𝕃",lopf:"𝕝",loplus:"⨭",lotimes:"⨴",lowast:"∗",lowbar:"_",LowerLeftArrow:"↙",LowerRightArrow:"↘",loz:"◊",lozenge:"◊",lozf:"⧫",lpar:"(",lparlt:"⦓",lrarr:"⇆",lrcorner:"⌟",lrhar:"⇋",lrhard:"⥭",lrm:"‎",lrtri:"⊿",lsaquo:"‹",lscr:"𝓁",Lscr:"ℒ",lsh:"↰",Lsh:"↰",lsim:"≲",lsime:"⪍",lsimg:"⪏",lsqb:"[",lsquo:"‘",lsquor:"‚",Lstrok:"Ł",lstrok:"ł",ltcc:"⪦",ltcir:"⩹",lt:"<",LT:"<",Lt:"≪",ltdot:"⋖",lthree:"⋋",ltimes:"⋉",ltlarr:"⥶",ltquest:"⩻",ltri:"◃",ltrie:"⊴",ltrif:"◂",ltrPar:"⦖",lurdshar:"⥊",luruhar:"⥦",lvertneqq:"≨︀",lvnE:"≨︀",macr:"¯",male:"♂",malt:"✠",maltese:"✠",Map:"⤅",map:"↦",mapsto:"↦",mapstodown:"↧",mapstoleft:"↤",mapstoup:"↥",marker:"▮",mcomma:"⨩",Mcy:"М",mcy:"м",mdash:"—",mDDot:"∺",measuredangle:"∡",MediumSpace:" ",Mellintrf:"ℳ",Mfr:"𝔐",mfr:"𝔪",mho:"℧",micro:"µ",midast:"*",midcir:"⫰",mid:"∣",middot:"·",minusb:"⊟",minus:"−",minusd:"∸",minusdu:"⨪",MinusPlus:"∓",mlcp:"⫛",mldr:"…",mnplus:"∓",models:"⊧",Mopf:"𝕄",mopf:"𝕞",mp:"∓",mscr:"𝓂",Mscr:"ℳ",mstpos:"∾",Mu:"Μ",mu:"μ",multimap:"⊸",mumap:"⊸",nabla:"∇",Nacute:"Ń",nacute:"ń",nang:"∠⃒",nap:"≉",napE:"⩰̸",napid:"≋̸",napos:"ʼn",napprox:"≉",natural:"♮",naturals:"ℕ",natur:"♮",nbsp:" ",nbump:"≎̸",nbumpe:"≏̸",ncap:"⩃",Ncaron:"Ň",ncaron:"ň",Ncedil:"Ņ",ncedil:"ņ",ncong:"≇",ncongdot:"⩭̸",ncup:"⩂",Ncy:"Н",ncy:"н",ndash:"–",nearhk:"⤤",nearr:"↗",neArr:"⇗",nearrow:"↗",ne:"≠",nedot:"≐̸",NegativeMediumSpace:"​",NegativeThickSpace:"​",NegativeThinSpace:"​",NegativeVeryThinSpace:"​",nequiv:"≢",nesear:"⤨",nesim:"≂̸",NestedGreaterGreater:"≫",NestedLessLess:"≪",NewLine:"\n",nexist:"∄",nexists:"∄",Nfr:"𝔑",nfr:"𝔫",ngE:"≧̸",nge:"≱",ngeq:"≱",ngeqq:"≧̸",ngeqslant:"⩾̸",nges:"⩾̸",nGg:"⋙̸",ngsim:"≵",nGt:"≫⃒",ngt:"≯",ngtr:"≯",nGtv:"≫̸",nharr:"↮",nhArr:"⇎",nhpar:"⫲",ni:"∋",nis:"⋼",nisd:"⋺",niv:"∋",NJcy:"Њ",njcy:"њ",nlarr:"↚",nlArr:"⇍",nldr:"‥",nlE:"≦̸",nle:"≰",nleftarrow:"↚",nLeftarrow:"⇍",nleftrightarrow:"↮",nLeftrightarrow:"⇎",nleq:"≰",nleqq:"≦̸",nleqslant:"⩽̸",nles:"⩽̸",nless:"≮",nLl:"⋘̸",nlsim:"≴",nLt:"≪⃒",nlt:"≮",nltri:"⋪",nltrie:"⋬",nLtv:"≪̸",nmid:"∤",NoBreak:"⁠",NonBreakingSpace:" ",nopf:"𝕟",Nopf:"ℕ",Not:"⫬",not:"¬",NotCongruent:"≢",NotCupCap:"≭",NotDoubleVerticalBar:"∦",NotElement:"∉",NotEqual:"≠",NotEqualTilde:"≂̸",NotExists:"∄",NotGreater:"≯",NotGreaterEqual:"≱",NotGreaterFullEqual:"≧̸",NotGreaterGreater:"≫̸",NotGreaterLess:"≹",NotGreaterSlantEqual:"⩾̸",NotGreaterTilde:"≵",NotHumpDownHump:"≎̸",NotHumpEqual:"≏̸",notin:"∉",notindot:"⋵̸",notinE:"⋹̸",notinva:"∉",notinvb:"⋷",notinvc:"⋶",NotLeftTriangleBar:"⧏̸",NotLeftTriangle:"⋪",NotLeftTriangleEqual:"⋬",NotLess:"≮",NotLessEqual:"≰",NotLessGreater:"≸",NotLessLess:"≪̸",NotLessSlantEqual:"⩽̸",NotLessTilde:"≴",NotNestedGreaterGreater:"⪢̸",NotNestedLessLess:"⪡̸",notni:"∌",notniva:"∌",notnivb:"⋾",notnivc:"⋽",NotPrecedes:"⊀",NotPrecedesEqual:"⪯̸",NotPrecedesSlantEqual:"⋠",NotReverseElement:"∌",NotRightTriangleBar:"⧐̸",NotRightTriangle:"⋫",NotRightTriangleEqual:"⋭",NotSquareSubset:"⊏̸",NotSquareSubsetEqual:"⋢",NotSquareSuperset:"⊐̸",NotSquareSupersetEqual:"⋣",NotSubset:"⊂⃒",NotSubsetEqual:"⊈",NotSucceeds:"⊁",NotSucceedsEqual:"⪰̸",NotSucceedsSlantEqual:"⋡",NotSucceedsTilde:"≿̸",NotSuperset:"⊃⃒",NotSupersetEqual:"⊉",NotTilde:"≁",NotTildeEqual:"≄",NotTildeFullEqual:"≇",NotTildeTilde:"≉",NotVerticalBar:"∤",nparallel:"∦",npar:"∦",nparsl:"⫽⃥",npart:"∂̸",npolint:"⨔",npr:"⊀",nprcue:"⋠",nprec:"⊀",npreceq:"⪯̸",npre:"⪯̸",nrarrc:"⤳̸",nrarr:"↛",nrArr:"⇏",nrarrw:"↝̸",nrightarrow:"↛",nRightarrow:"⇏",nrtri:"⋫",nrtrie:"⋭",nsc:"⊁",nsccue:"⋡",nsce:"⪰̸",Nscr:"𝒩",nscr:"𝓃",nshortmid:"∤",nshortparallel:"∦",nsim:"≁",nsime:"≄",nsimeq:"≄",nsmid:"∤",nspar:"∦",nsqsube:"⋢",nsqsupe:"⋣",nsub:"⊄",nsubE:"⫅̸",nsube:"⊈",nsubset:"⊂⃒",nsubseteq:"⊈",nsubseteqq:"⫅̸",nsucc:"⊁",nsucceq:"⪰̸",nsup:"⊅",nsupE:"⫆̸",nsupe:"⊉",nsupset:"⊃⃒",nsupseteq:"⊉",nsupseteqq:"⫆̸",ntgl:"≹",Ntilde:"Ñ",ntilde:"ñ",ntlg:"≸",ntriangleleft:"⋪",ntrianglelefteq:"⋬",ntriangleright:"⋫",ntrianglerighteq:"⋭",Nu:"Ν",nu:"ν",num:"#",numero:"№",numsp:" ",nvap:"≍⃒",nvdash:"⊬",nvDash:"⊭",nVdash:"⊮",nVDash:"⊯",nvge:"≥⃒",nvgt:">⃒",nvHarr:"⤄",nvinfin:"⧞",nvlArr:"⤂",nvle:"≤⃒",nvlt:"<⃒",nvltrie:"⊴⃒",nvrArr:"⤃",nvrtrie:"⊵⃒",nvsim:"∼⃒",nwarhk:"⤣",nwarr:"↖",nwArr:"⇖",nwarrow:"↖",nwnear:"⤧",Oacute:"Ó",oacute:"ó",oast:"⊛",Ocirc:"Ô",ocirc:"ô",ocir:"⊚",Ocy:"О",ocy:"о",odash:"⊝",Odblac:"Ő",odblac:"ő",odiv:"⨸",odot:"⊙",odsold:"⦼",OElig:"Œ",oelig:"œ",ofcir:"⦿",Ofr:"𝔒",ofr:"𝔬",ogon:"˛",Ograve:"Ò",ograve:"ò",ogt:"⧁",ohbar:"⦵",ohm:"Ω",oint:"∮",olarr:"↺",olcir:"⦾",olcross:"⦻",oline:"‾",olt:"⧀",Omacr:"Ō",omacr:"ō",Omega:"Ω",omega:"ω",Omicron:"Ο",omicron:"ο",omid:"⦶",ominus:"⊖",Oopf:"𝕆",oopf:"𝕠",opar:"⦷",OpenCurlyDoubleQuote:"“",OpenCurlyQuote:"‘",operp:"⦹",oplus:"⊕",orarr:"↻",Or:"⩔",or:"∨",ord:"⩝",order:"ℴ",orderof:"ℴ",ordf:"ª",ordm:"º",origof:"⊶",oror:"⩖",orslope:"⩗",orv:"⩛",oS:"Ⓢ",Oscr:"𝒪",oscr:"ℴ",Oslash:"Ø",oslash:"ø",osol:"⊘",Otilde:"Õ",otilde:"õ",otimesas:"⨶",Otimes:"⨷",otimes:"⊗",Ouml:"Ö",ouml:"ö",ovbar:"⌽",OverBar:"‾",OverBrace:"⏞",OverBracket:"⎴",OverParenthesis:"⏜",para:"¶",parallel:"∥",par:"∥",parsim:"⫳",parsl:"⫽",part:"∂",PartialD:"∂",Pcy:"П",pcy:"п",percnt:"%",period:".",permil:"‰",perp:"⊥",pertenk:"‱",Pfr:"𝔓",pfr:"𝔭",Phi:"Φ",phi:"φ",phiv:"ϕ",phmmat:"ℳ",phone:"☎",Pi:"Π",pi:"π",pitchfork:"⋔",piv:"ϖ",planck:"ℏ",planckh:"ℎ",plankv:"ℏ",plusacir:"⨣",plusb:"⊞",pluscir:"⨢",plus:"+",plusdo:"∔",plusdu:"⨥",pluse:"⩲",PlusMinus:"±",plusmn:"±",plussim:"⨦",plustwo:"⨧",pm:"±",Poincareplane:"ℌ",pointint:"⨕",popf:"𝕡",Popf:"ℙ",pound:"£",prap:"⪷",Pr:"⪻",pr:"≺",prcue:"≼",precapprox:"⪷",prec:"≺",preccurlyeq:"≼",Precedes:"≺",PrecedesEqual:"⪯",PrecedesSlantEqual:"≼",PrecedesTilde:"≾",preceq:"⪯",precnapprox:"⪹",precneqq:"⪵",precnsim:"⋨",pre:"⪯",prE:"⪳",precsim:"≾",prime:"′",Prime:"″",primes:"ℙ",prnap:"⪹",prnE:"⪵",prnsim:"⋨",prod:"∏",Product:"∏",profalar:"⌮",profline:"⌒",profsurf:"⌓",prop:"∝",Proportional:"∝",Proportion:"∷",propto:"∝",prsim:"≾",prurel:"⊰",Pscr:"𝒫",pscr:"𝓅",Psi:"Ψ",psi:"ψ",puncsp:" ",Qfr:"𝔔",qfr:"𝔮",qint:"⨌",qopf:"𝕢",Qopf:"ℚ",qprime:"⁗",Qscr:"𝒬",qscr:"𝓆",quaternions:"ℍ",quatint:"⨖",quest:"?",questeq:"≟",quot:'"',QUOT:'"',rAarr:"⇛",race:"∽̱",Racute:"Ŕ",racute:"ŕ",radic:"√",raemptyv:"⦳",rang:"⟩",Rang:"⟫",rangd:"⦒",range:"⦥",rangle:"⟩",raquo:"»",rarrap:"⥵",rarrb:"⇥",rarrbfs:"⤠",rarrc:"⤳",rarr:"→",Rarr:"↠",rArr:"⇒",rarrfs:"⤞",rarrhk:"↪",rarrlp:"↬",rarrpl:"⥅",rarrsim:"⥴",Rarrtl:"⤖",rarrtl:"↣",rarrw:"↝",ratail:"⤚",rAtail:"⤜",ratio:"∶",rationals:"ℚ",rbarr:"⤍",rBarr:"⤏",RBarr:"⤐",rbbrk:"❳",rbrace:"}",rbrack:"]",rbrke:"⦌",rbrksld:"⦎",rbrkslu:"⦐",Rcaron:"Ř",rcaron:"ř",Rcedil:"Ŗ",rcedil:"ŗ",rceil:"⌉",rcub:"}",Rcy:"Р",rcy:"р",rdca:"⤷",rdldhar:"⥩",rdquo:"”",rdquor:"”",rdsh:"↳",real:"ℜ",realine:"ℛ",realpart:"ℜ",reals:"ℝ",Re:"ℜ",rect:"▭",reg:"®",REG:"®",ReverseElement:"∋",ReverseEquilibrium:"⇋",ReverseUpEquilibrium:"⥯",rfisht:"⥽",rfloor:"⌋",rfr:"𝔯",Rfr:"ℜ",rHar:"⥤",rhard:"⇁",rharu:"⇀",rharul:"⥬",Rho:"Ρ",rho:"ρ",rhov:"ϱ",RightAngleBracket:"⟩",RightArrowBar:"⇥",rightarrow:"→",RightArrow:"→",Rightarrow:"⇒",RightArrowLeftArrow:"⇄",rightarrowtail:"↣",RightCeiling:"⌉",RightDoubleBracket:"⟧",RightDownTeeVector:"⥝",RightDownVectorBar:"⥕",RightDownVector:"⇂",RightFloor:"⌋",rightharpoondown:"⇁",rightharpoonup:"⇀",rightleftarrows:"⇄",rightleftharpoons:"⇌",rightrightarrows:"⇉",rightsquigarrow:"↝",RightTeeArrow:"↦",RightTee:"⊢",RightTeeVector:"⥛",rightthreetimes:"⋌",RightTriangleBar:"⧐",RightTriangle:"⊳",RightTriangleEqual:"⊵",RightUpDownVector:"⥏",RightUpTeeVector:"⥜",RightUpVectorBar:"⥔",RightUpVector:"↾",RightVectorBar:"⥓",RightVector:"⇀",ring:"˚",risingdotseq:"≓",rlarr:"⇄",rlhar:"⇌",rlm:"‏",rmoustache:"⎱",rmoust:"⎱",rnmid:"⫮",roang:"⟭",roarr:"⇾",robrk:"⟧",ropar:"⦆",ropf:"𝕣",Ropf:"ℝ",roplus:"⨮",rotimes:"⨵",RoundImplies:"⥰",rpar:")",rpargt:"⦔",rppolint:"⨒",rrarr:"⇉",Rrightarrow:"⇛",rsaquo:"›",rscr:"𝓇",Rscr:"ℛ",rsh:"↱",Rsh:"↱",rsqb:"]",rsquo:"’",rsquor:"’",rthree:"⋌",rtimes:"⋊",rtri:"▹",rtrie:"⊵",rtrif:"▸",rtriltri:"⧎",RuleDelayed:"⧴",ruluhar:"⥨",rx:"℞",Sacute:"Ś",sacute:"ś",sbquo:"‚",scap:"⪸",Scaron:"Š",scaron:"š",Sc:"⪼",sc:"≻",sccue:"≽",sce:"⪰",scE:"⪴",Scedil:"Ş",scedil:"ş",Scirc:"Ŝ",scirc:"ŝ",scnap:"⪺",scnE:"⪶",scnsim:"⋩",scpolint:"⨓",scsim:"≿",Scy:"С",scy:"с",sdotb:"⊡",sdot:"⋅",sdote:"⩦",searhk:"⤥",searr:"↘",seArr:"⇘",searrow:"↘",sect:"§",semi:";",seswar:"⤩",setminus:"∖",setmn:"∖",sext:"✶",Sfr:"𝔖",sfr:"𝔰",sfrown:"⌢",sharp:"♯",SHCHcy:"Щ",shchcy:"щ",SHcy:"Ш",shcy:"ш",ShortDownArrow:"↓",ShortLeftArrow:"←",shortmid:"∣",shortparallel:"∥",ShortRightArrow:"→",ShortUpArrow:"↑",shy:"­",Sigma:"Σ",sigma:"σ",sigmaf:"ς",sigmav:"ς",sim:"∼",simdot:"⩪",sime:"≃",simeq:"≃",simg:"⪞",simgE:"⪠",siml:"⪝",simlE:"⪟",simne:"≆",simplus:"⨤",simrarr:"⥲",slarr:"←",SmallCircle:"∘",smallsetminus:"∖",smashp:"⨳",smeparsl:"⧤",smid:"∣",smile:"⌣",smt:"⪪",smte:"⪬",smtes:"⪬︀",SOFTcy:"Ь",softcy:"ь",solbar:"⌿",solb:"⧄",sol:"/",Sopf:"𝕊",sopf:"𝕤",spades:"♠",spadesuit:"♠",spar:"∥",sqcap:"⊓",sqcaps:"⊓︀",sqcup:"⊔",sqcups:"⊔︀",Sqrt:"√",sqsub:"⊏",sqsube:"⊑",sqsubset:"⊏",sqsubseteq:"⊑",sqsup:"⊐",sqsupe:"⊒",sqsupset:"⊐",sqsupseteq:"⊒",square:"□",Square:"□",SquareIntersection:"⊓",SquareSubset:"⊏",SquareSubsetEqual:"⊑",SquareSuperset:"⊐",SquareSupersetEqual:"⊒",SquareUnion:"⊔",squarf:"▪",squ:"□",squf:"▪",srarr:"→",Sscr:"𝒮",sscr:"𝓈",ssetmn:"∖",ssmile:"⌣",sstarf:"⋆",Star:"⋆",star:"☆",starf:"★",straightepsilon:"ϵ",straightphi:"ϕ",strns:"¯",sub:"⊂",Sub:"⋐",subdot:"⪽",subE:"⫅",sube:"⊆",subedot:"⫃",submult:"⫁",subnE:"⫋",subne:"⊊",subplus:"⪿",subrarr:"⥹",subset:"⊂",Subset:"⋐",subseteq:"⊆",subseteqq:"⫅",SubsetEqual:"⊆",subsetneq:"⊊",subsetneqq:"⫋",subsim:"⫇",subsub:"⫕",subsup:"⫓",succapprox:"⪸",succ:"≻",succcurlyeq:"≽",Succeeds:"≻",SucceedsEqual:"⪰",SucceedsSlantEqual:"≽",SucceedsTilde:"≿",succeq:"⪰",succnapprox:"⪺",succneqq:"⪶",succnsim:"⋩",succsim:"≿",SuchThat:"∋",sum:"∑",Sum:"∑",sung:"♪",sup1:"¹",sup2:"²",sup3:"³",sup:"⊃",Sup:"⋑",supdot:"⪾",supdsub:"⫘",supE:"⫆",supe:"⊇",supedot:"⫄",Superset:"⊃",SupersetEqual:"⊇",suphsol:"⟉",suphsub:"⫗",suplarr:"⥻",supmult:"⫂",supnE:"⫌",supne:"⊋",supplus:"⫀",supset:"⊃",Supset:"⋑",supseteq:"⊇",supseteqq:"⫆",supsetneq:"⊋",supsetneqq:"⫌",supsim:"⫈",supsub:"⫔",supsup:"⫖",swarhk:"⤦",swarr:"↙",swArr:"⇙",swarrow:"↙",swnwar:"⤪",szlig:"ß",Tab:"\t",target:"⌖",Tau:"Τ",tau:"τ",tbrk:"⎴",Tcaron:"Ť",tcaron:"ť",Tcedil:"Ţ",tcedil:"ţ",Tcy:"Т",tcy:"т",tdot:"⃛",telrec:"⌕",Tfr:"𝔗",tfr:"𝔱",there4:"∴",therefore:"∴",Therefore:"∴",Theta:"Θ",theta:"θ",thetasym:"ϑ",thetav:"ϑ",thickapprox:"≈",thicksim:"∼",ThickSpace:"  ",ThinSpace:" ",thinsp:" ",thkap:"≈",thksim:"∼",THORN:"Þ",thorn:"þ",tilde:"˜",Tilde:"∼",TildeEqual:"≃",TildeFullEqual:"≅",TildeTilde:"≈",timesbar:"⨱",timesb:"⊠",times:"×",timesd:"⨰",tint:"∭",toea:"⤨",topbot:"⌶",topcir:"⫱",top:"⊤",Topf:"𝕋",topf:"𝕥",topfork:"⫚",tosa:"⤩",tprime:"‴",trade:"™",TRADE:"™",triangle:"▵",triangledown:"▿",triangleleft:"◃",trianglelefteq:"⊴",triangleq:"≜",triangleright:"▹",trianglerighteq:"⊵",tridot:"◬",trie:"≜",triminus:"⨺",TripleDot:"⃛",triplus:"⨹",trisb:"⧍",tritime:"⨻",trpezium:"⏢",Tscr:"𝒯",tscr:"𝓉",TScy:"Ц",tscy:"ц",TSHcy:"Ћ",tshcy:"ћ",Tstrok:"Ŧ",tstrok:"ŧ",twixt:"≬",twoheadleftarrow:"↞",twoheadrightarrow:"↠",Uacute:"Ú",uacute:"ú",uarr:"↑",Uarr:"↟",uArr:"⇑",Uarrocir:"⥉",Ubrcy:"Ў",ubrcy:"ў",Ubreve:"Ŭ",ubreve:"ŭ",Ucirc:"Û",ucirc:"û",Ucy:"У",ucy:"у",udarr:"⇅",Udblac:"Ű",udblac:"ű",udhar:"⥮",ufisht:"⥾",Ufr:"𝔘",ufr:"𝔲",Ugrave:"Ù",ugrave:"ù",uHar:"⥣",uharl:"↿",uharr:"↾",uhblk:"▀",ulcorn:"⌜",ulcorner:"⌜",ulcrop:"⌏",ultri:"◸",Umacr:"Ū",umacr:"ū",uml:"¨",UnderBar:"_",UnderBrace:"⏟",UnderBracket:"⎵",UnderParenthesis:"⏝",Union:"⋃",UnionPlus:"⊎",Uogon:"Ų",uogon:"ų",Uopf:"𝕌",uopf:"𝕦",UpArrowBar:"⤒",uparrow:"↑",UpArrow:"↑",Uparrow:"⇑",UpArrowDownArrow:"⇅",updownarrow:"↕",UpDownArrow:"↕",Updownarrow:"⇕",UpEquilibrium:"⥮",upharpoonleft:"↿",upharpoonright:"↾",uplus:"⊎",UpperLeftArrow:"↖",UpperRightArrow:"↗",upsi:"υ",Upsi:"ϒ",upsih:"ϒ",Upsilon:"Υ",upsilon:"υ",UpTeeArrow:"↥",UpTee:"⊥",upuparrows:"⇈",urcorn:"⌝",urcorner:"⌝",urcrop:"⌎",Uring:"Ů",uring:"ů",urtri:"◹",Uscr:"𝒰",uscr:"𝓊",utdot:"⋰",Utilde:"Ũ",utilde:"ũ",utri:"▵",utrif:"▴",uuarr:"⇈",Uuml:"Ü",uuml:"ü",uwangle:"⦧",vangrt:"⦜",varepsilon:"ϵ",varkappa:"ϰ",varnothing:"∅",varphi:"ϕ",varpi:"ϖ",varpropto:"∝",varr:"↕",vArr:"⇕",varrho:"ϱ",varsigma:"ς",varsubsetneq:"⊊︀",varsubsetneqq:"⫋︀",varsupsetneq:"⊋︀",varsupsetneqq:"⫌︀",vartheta:"ϑ",vartriangleleft:"⊲",vartriangleright:"⊳",vBar:"⫨",Vbar:"⫫",vBarv:"⫩",Vcy:"В",vcy:"в",vdash:"⊢",vDash:"⊨",Vdash:"⊩",VDash:"⊫",Vdashl:"⫦",veebar:"⊻",vee:"∨",Vee:"⋁",veeeq:"≚",vellip:"⋮",verbar:"|",Verbar:"‖",vert:"|",Vert:"‖",VerticalBar:"∣",VerticalLine:"|",VerticalSeparator:"❘",VerticalTilde:"≀",VeryThinSpace:" ",Vfr:"𝔙",vfr:"𝔳",vltri:"⊲",vnsub:"⊂⃒",vnsup:"⊃⃒",Vopf:"𝕍",vopf:"𝕧",vprop:"∝",vrtri:"⊳",Vscr:"𝒱",vscr:"𝓋",vsubnE:"⫋︀",vsubne:"⊊︀",vsupnE:"⫌︀",vsupne:"⊋︀",Vvdash:"⊪",vzigzag:"⦚",Wcirc:"Ŵ",wcirc:"ŵ",wedbar:"⩟",wedge:"∧",Wedge:"⋀",wedgeq:"≙",weierp:"℘",Wfr:"𝔚",wfr:"𝔴",Wopf:"𝕎",wopf:"𝕨",wp:"℘",wr:"≀",wreath:"≀",Wscr:"𝒲",wscr:"𝓌",xcap:"⋂",xcirc:"◯",xcup:"⋃",xdtri:"▽",Xfr:"𝔛",xfr:"𝔵",xharr:"⟷",xhArr:"⟺",Xi:"Ξ",xi:"ξ",xlarr:"⟵",xlArr:"⟸",xmap:"⟼",xnis:"⋻",xodot:"⨀",Xopf:"𝕏",xopf:"𝕩",xoplus:"⨁",xotime:"⨂",xrarr:"⟶",xrArr:"⟹",Xscr:"𝒳",xscr:"𝓍",xsqcup:"⨆",xuplus:"⨄",xutri:"△",xvee:"⋁",xwedge:"⋀",Yacute:"Ý",yacute:"ý",YAcy:"Я",yacy:"я",Ycirc:"Ŷ",ycirc:"ŷ",Ycy:"Ы",ycy:"ы",yen:"¥",Yfr:"𝔜",yfr:"𝔶",YIcy:"Ї",yicy:"ї",Yopf:"𝕐",yopf:"𝕪",Yscr:"𝒴",yscr:"𝓎",YUcy:"Ю",yucy:"ю",yuml:"ÿ",Yuml:"Ÿ",Zacute:"Ź",zacute:"ź",Zcaron:"Ž",zcaron:"ž",Zcy:"З",zcy:"з",Zdot:"Ż",zdot:"ż",zeetrf:"ℨ",ZeroWidthSpace:"​",Zeta:"Ζ",zeta:"ζ",zfr:"𝔷",Zfr:"ℨ",ZHcy:"Ж",zhcy:"ж",zigrarr:"⇝",zopf:"𝕫",Zopf:"ℤ",Zscr:"𝒵",zscr:"𝓏",zwj:"‍",zwnj:"‌"}},{}],26:[function(require,module,exports){module.exports={Aacute:"Á",aacute:"á",Acirc:"Â",acirc:"â",acute:"´",AElig:"Æ",aelig:"æ",Agrave:"À",agrave:"à",amp:"&",AMP:"&",Aring:"Å",aring:"å",Atilde:"Ã",atilde:"ã",Auml:"Ä",auml:"ä",brvbar:"¦",Ccedil:"Ç",ccedil:"ç",cedil:"¸",cent:"¢",copy:"©",COPY:"©",curren:"¤",deg:"°",divide:"÷",Eacute:"É",eacute:"é",Ecirc:"Ê",ecirc:"ê",Egrave:"È",egrave:"è",ETH:"Ð",eth:"ð",Euml:"Ë",euml:"ë",frac12:"½",frac14:"¼",frac34:"¾",gt:">",GT:">",Iacute:"Í",iacute:"í",Icirc:"Î",icirc:"î",iexcl:"¡",Igrave:"Ì",igrave:"ì",iquest:"¿",Iuml:"Ï",iuml:"ï",laquo:"«",lt:"<",LT:"<",macr:"¯",micro:"µ",middot:"·",nbsp:" ",not:"¬",Ntilde:"Ñ",ntilde:"ñ",Oacute:"Ó",oacute:"ó",Ocirc:"Ô",ocirc:"ô",Ograve:"Ò",ograve:"ò",ordf:"ª",ordm:"º",Oslash:"Ø",oslash:"ø",Otilde:"Õ",otilde:"õ",Ouml:"Ö",ouml:"ö",para:"¶",plusmn:"±",pound:"£",quot:'"',QUOT:'"',raquo:"»",reg:"®",REG:"®",sect:"§",shy:"­",sup1:"¹",sup2:"²",sup3:"³",szlig:"ß",THORN:"Þ",thorn:"þ",times:"×",Uacute:"Ú",uacute:"ú",Ucirc:"Û",ucirc:"û",Ugrave:"Ù",ugrave:"ù",uml:"¨",Uuml:"Ü",uuml:"ü",Yacute:"Ý",yacute:"ý",yen:"¥",yuml:"ÿ"}},{}],27:[function(require,module,exports){module.exports={amp:"&",apos:"'",gt:">",lt:"<",quot:'"'}},{}],28:[function(require,module,exports){function EventEmitter(){this._events=this._events||{};this._maxListeners=this._maxListeners||undefined}module.exports=EventEmitter;EventEmitter.EventEmitter=EventEmitter;EventEmitter.prototype._events=undefined;EventEmitter.prototype._maxListeners=undefined;EventEmitter.defaultMaxListeners=10;EventEmitter.prototype.setMaxListeners=function(n){if(!isNumber(n)||n<0||isNaN(n))throw TypeError("n must be a positive number");this._maxListeners=n;return this};EventEmitter.prototype.emit=function(type){var er,handler,len,args,i,listeners;if(!this._events)this._events={};if(type==="error"){if(!this._events.error||isObject(this._events.error)&&!this._events.error.length){er=arguments[1];if(er instanceof Error){throw er}else{var err=new Error('Uncaught, unspecified "error" event. ('+er+")");err.context=er;throw err}}}handler=this._events[type];if(isUndefined(handler))return false;if(isFunction(handler)){switch(arguments.length){case 1:handler.call(this);break;case 2:handler.call(this,arguments[1]);break;case 3:handler.call(this,arguments[1],arguments[2]);break;default:args=Array.prototype.slice.call(arguments,1);handler.apply(this,args)}}else if(isObject(handler)){args=Array.prototype.slice.call(arguments,1);listeners=handler.slice();len=listeners.length;for(i=0;i<len;i++)listeners[i].apply(this,args)}return true};EventEmitter.prototype.addListener=function(type,listener){var m;if(!isFunction(listener))throw TypeError("listener must be a function");if(!this._events)this._events={};if(this._events.newListener)this.emit("newListener",type,isFunction(listener.listener)?listener.listener:listener);if(!this._events[type])this._events[type]=listener;else if(isObject(this._events[type]))this._events[type].push(listener);else this._events[type]=[this._events[type],listener];if(isObject(this._events[type])&&!this._events[type].warned){if(!isUndefined(this._maxListeners)){m=this._maxListeners}else{m=EventEmitter.defaultMaxListeners}if(m&&m>0&&this._events[type].length>m){this._events[type].warned=true;console.error("(node) warning: possible EventEmitter memory "+"leak detected. %d listeners added. "+"Use emitter.setMaxListeners() to increase limit.",this._events[type].length);if(typeof console.trace==="function"){console.trace()}}}return this};EventEmitter.prototype.on=EventEmitter.prototype.addListener;EventEmitter.prototype.once=function(type,listener){if(!isFunction(listener))throw TypeError("listener must be a function");var fired=false;function g(){this.removeListener(type,g);if(!fired){fired=true;listener.apply(this,arguments)}}g.listener=listener;this.on(type,g);return this};EventEmitter.prototype.removeListener=function(type,listener){var list,position,length,i;if(!isFunction(listener))throw TypeError("listener must be a function");if(!this._events||!this._events[type])return this;list=this._events[type];length=list.length;position=-1;if(list===listener||isFunction(list.listener)&&list.listener===listener){delete this._events[type];if(this._events.removeListener)this.emit("removeListener",type,listener)}else if(isObject(list)){for(i=length;i-- >0;){if(list[i]===listener||list[i].listener&&list[i].listener===listener){position=i;break}}if(position<0)return this;if(list.length===1){list.length=0;delete this._events[type]}else{list.splice(position,1);
-}if(this._events.removeListener)this.emit("removeListener",type,listener)}return this};EventEmitter.prototype.removeAllListeners=function(type){var key,listeners;if(!this._events)return this;if(!this._events.removeListener){if(arguments.length===0)this._events={};else if(this._events[type])delete this._events[type];return this}if(arguments.length===0){for(key in this._events){if(key==="removeListener")continue;this.removeAllListeners(key)}this.removeAllListeners("removeListener");this._events={};return this}listeners=this._events[type];if(isFunction(listeners)){this.removeListener(type,listeners)}else if(listeners){while(listeners.length)this.removeListener(type,listeners[listeners.length-1])}delete this._events[type];return this};EventEmitter.prototype.listeners=function(type){var ret;if(!this._events||!this._events[type])ret=[];else if(isFunction(this._events[type]))ret=[this._events[type]];else ret=this._events[type].slice();return ret};EventEmitter.prototype.listenerCount=function(type){if(this._events){var evlistener=this._events[type];if(isFunction(evlistener))return 1;else if(evlistener)return evlistener.length}return 0};EventEmitter.listenerCount=function(emitter,type){return emitter.listenerCount(type)};function isFunction(arg){return typeof arg==="function"}function isNumber(arg){return typeof arg==="number"}function isObject(arg){return typeof arg==="object"&&arg!==null}function isUndefined(arg){return arg===void 0}},{}],29:[function(require,module,exports){module.exports=CollectingHandler;function CollectingHandler(cbs){this._cbs=cbs||{};this.events=[]}var EVENTS=require("./").EVENTS;Object.keys(EVENTS).forEach(function(name){if(EVENTS[name]===0){name="on"+name;CollectingHandler.prototype[name]=function(){this.events.push([name]);if(this._cbs[name])this._cbs[name]()}}else if(EVENTS[name]===1){name="on"+name;CollectingHandler.prototype[name]=function(a){this.events.push([name,a]);if(this._cbs[name])this._cbs[name](a)}}else if(EVENTS[name]===2){name="on"+name;CollectingHandler.prototype[name]=function(a,b){this.events.push([name,a,b]);if(this._cbs[name])this._cbs[name](a,b)}}else{throw Error("wrong number of arguments")}});CollectingHandler.prototype.onreset=function(){this.events=[];if(this._cbs.onreset)this._cbs.onreset()};CollectingHandler.prototype.restart=function(){if(this._cbs.onreset)this._cbs.onreset();for(var i=0,len=this.events.length;i<len;i++){if(this._cbs[this.events[i][0]]){var num=this.events[i].length;if(num===1){this._cbs[this.events[i][0]]()}else if(num===2){this._cbs[this.events[i][0]](this.events[i][1])}else{this._cbs[this.events[i][0]](this.events[i][1],this.events[i][2])}}}}},{"./":36}],30:[function(require,module,exports){var index=require("./index.js"),DomHandler=index.DomHandler,DomUtils=index.DomUtils;function FeedHandler(callback,options){this.init(callback,options)}require("inherits")(FeedHandler,DomHandler);FeedHandler.prototype.init=DomHandler;function getElements(what,where){return DomUtils.getElementsByTagName(what,where,true)}function getOneElement(what,where){return DomUtils.getElementsByTagName(what,where,true,1)[0]}function fetch(what,where,recurse){return DomUtils.getText(DomUtils.getElementsByTagName(what,where,recurse,1)).trim()}function addConditionally(obj,prop,what,where,recurse){var tmp=fetch(what,where,recurse);if(tmp)obj[prop]=tmp}var isValidFeed=function(value){return value==="rss"||value==="feed"||value==="rdf:RDF"};FeedHandler.prototype.onend=function(){var feed={},feedRoot=getOneElement(isValidFeed,this.dom),tmp,childs;if(feedRoot){if(feedRoot.name==="feed"){childs=feedRoot.children;feed.type="atom";addConditionally(feed,"id","id",childs);addConditionally(feed,"title","title",childs);if((tmp=getOneElement("link",childs))&&(tmp=tmp.attribs)&&(tmp=tmp.href))feed.link=tmp;addConditionally(feed,"description","subtitle",childs);if(tmp=fetch("updated",childs))feed.updated=new Date(tmp);addConditionally(feed,"author","email",childs,true);feed.items=getElements("entry",childs).map(function(item){var entry={},tmp;item=item.children;addConditionally(entry,"id","id",item);addConditionally(entry,"title","title",item);if((tmp=getOneElement("link",item))&&(tmp=tmp.attribs)&&(tmp=tmp.href))entry.link=tmp;if(tmp=fetch("summary",item)||fetch("content",item))entry.description=tmp;if(tmp=fetch("updated",item))entry.pubDate=new Date(tmp);return entry})}else{childs=getOneElement("channel",feedRoot.children).children;feed.type=feedRoot.name.substr(0,3);feed.id="";addConditionally(feed,"title","title",childs);addConditionally(feed,"link","link",childs);addConditionally(feed,"description","description",childs);if(tmp=fetch("lastBuildDate",childs))feed.updated=new Date(tmp);addConditionally(feed,"author","managingEditor",childs,true);feed.items=getElements("item",feedRoot.children).map(function(item){var entry={},tmp;item=item.children;addConditionally(entry,"id","guid",item);addConditionally(entry,"title","title",item);addConditionally(entry,"link","link",item);addConditionally(entry,"description","description",item);if(tmp=fetch("pubDate",item))entry.pubDate=new Date(tmp);return entry})}}this.dom=feed;DomHandler.prototype._handleCallback.call(this,feedRoot?null:Error("couldn't find root of feed"))};module.exports=FeedHandler},{"./index.js":36,inherits:38}],31:[function(require,module,exports){var Tokenizer=require("./Tokenizer.js");var formTags={input:true,option:true,optgroup:true,select:true,button:true,datalist:true,textarea:true};var openImpliesClose={tr:{tr:true,th:true,td:true},th:{th:true},td:{thead:true,th:true,td:true},body:{head:true,link:true,script:true},li:{li:true},p:{p:true},h1:{p:true},h2:{p:true},h3:{p:true},h4:{p:true},h5:{p:true},h6:{p:true},select:formTags,input:formTags,output:formTags,button:formTags,datalist:formTags,textarea:formTags,option:{option:true},optgroup:{optgroup:true}};var voidElements={__proto__:null,area:true,base:true,basefont:true,br:true,col:true,command:true,embed:true,frame:true,hr:true,img:true,input:true,isindex:true,keygen:true,link:true,meta:true,param:true,source:true,track:true,wbr:true,path:true,circle:true,ellipse:true,line:true,rect:true,use:true,stop:true,polyline:true,polygon:true};var re_nameEnd=/\s|\//;function Parser(cbs,options){this._options=options||{};this._cbs=cbs||{};this._tagname="";this._attribname="";this._attribvalue="";this._attribs=null;this._stack=[];this.startIndex=0;this.endIndex=null;this._lowerCaseTagNames="lowerCaseTags"in this._options?!!this._options.lowerCaseTags:!this._options.xmlMode;this._lowerCaseAttributeNames="lowerCaseAttributeNames"in this._options?!!this._options.lowerCaseAttributeNames:!this._options.xmlMode;if(this._options.Tokenizer){Tokenizer=this._options.Tokenizer}this._tokenizer=new Tokenizer(this._options,this);if(this._cbs.onparserinit)this._cbs.onparserinit(this)}require("inherits")(Parser,require("events").EventEmitter);Parser.prototype._updatePosition=function(initialOffset){if(this.endIndex===null){if(this._tokenizer._sectionStart<=initialOffset){this.startIndex=0}else{this.startIndex=this._tokenizer._sectionStart-initialOffset}}else this.startIndex=this.endIndex+1;this.endIndex=this._tokenizer.getAbsoluteIndex()};Parser.prototype.ontext=function(data){this._updatePosition(1);this.endIndex--;if(this._cbs.ontext)this._cbs.ontext(data)};Parser.prototype.onopentagname=function(name){if(this._lowerCaseTagNames){name=name.toLowerCase()}this._tagname=name;if(!this._options.xmlMode&&name in openImpliesClose){for(var el;(el=this._stack[this._stack.length-1])in openImpliesClose[name];this.onclosetag(el));}if(this._options.xmlMode||!(name in voidElements)){this._stack.push(name)}if(this._cbs.onopentagname)this._cbs.onopentagname(name);if(this._cbs.onopentag)this._attribs={}};Parser.prototype.onopentagend=function(){this._updatePosition(1);if(this._attribs){if(this._cbs.onopentag)this._cbs.onopentag(this._tagname,this._attribs);this._attribs=null}if(!this._options.xmlMode&&this._cbs.onclosetag&&this._tagname in voidElements){this._cbs.onclosetag(this._tagname)}this._tagname=""};Parser.prototype.onclosetag=function(name){this._updatePosition(1);if(this._lowerCaseTagNames){name=name.toLowerCase()}if(this._stack.length&&(!(name in voidElements)||this._options.xmlMode)){var pos=this._stack.lastIndexOf(name);if(pos!==-1){if(this._cbs.onclosetag){pos=this._stack.length-pos;while(pos--)this._cbs.onclosetag(this._stack.pop())}else this._stack.length=pos}else if(name==="p"&&!this._options.xmlMode){this.onopentagname(name);this._closeCurrentTag()}}else if(!this._options.xmlMode&&(name==="br"||name==="p")){this.onopentagname(name);this._closeCurrentTag()}};Parser.prototype.onselfclosingtag=function(){if(this._options.xmlMode||this._options.recognizeSelfClosing){this._closeCurrentTag()}else{this.onopentagend()}};Parser.prototype._closeCurrentTag=function(){var name=this._tagname;this.onopentagend();if(this._stack[this._stack.length-1]===name){if(this._cbs.onclosetag){this._cbs.onclosetag(name)}this._stack.pop()}};Parser.prototype.onattribname=function(name){if(this._lowerCaseAttributeNames){name=name.toLowerCase()}this._attribname=name};Parser.prototype.onattribdata=function(value){this._attribvalue+=value};Parser.prototype.onattribend=function(){if(this._cbs.onattribute)this._cbs.onattribute(this._attribname,this._attribvalue);if(this._attribs&&!Object.prototype.hasOwnProperty.call(this._attribs,this._attribname)){this._attribs[this._attribname]=this._attribvalue}this._attribname="";this._attribvalue=""};Parser.prototype._getInstructionName=function(value){var idx=value.search(re_nameEnd),name=idx<0?value:value.substr(0,idx);if(this._lowerCaseTagNames){name=name.toLowerCase()}return name};Parser.prototype.ondeclaration=function(value){if(this._cbs.onprocessinginstruction){var name=this._getInstructionName(value);this._cbs.onprocessinginstruction("!"+name,"!"+value)}};Parser.prototype.onprocessinginstruction=function(value){if(this._cbs.onprocessinginstruction){var name=this._getInstructionName(value);this._cbs.onprocessinginstruction("?"+name,"?"+value)}};Parser.prototype.oncomment=function(value){this._updatePosition(4);if(this._cbs.oncomment)this._cbs.oncomment(value);if(this._cbs.oncommentend)this._cbs.oncommentend()};Parser.prototype.oncdata=function(value){this._updatePosition(1);if(this._options.xmlMode||this._options.recognizeCDATA){if(this._cbs.oncdatastart)this._cbs.oncdatastart();if(this._cbs.ontext)this._cbs.ontext(value);if(this._cbs.oncdataend)this._cbs.oncdataend()}else{this.oncomment("[CDATA["+value+"]]")}};Parser.prototype.onerror=function(err){if(this._cbs.onerror)this._cbs.onerror(err)};Parser.prototype.onend=function(){if(this._cbs.onclosetag){for(var i=this._stack.length;i>0;this._cbs.onclosetag(this._stack[--i]));}if(this._cbs.onend)this._cbs.onend()};Parser.prototype.reset=function(){if(this._cbs.onreset)this._cbs.onreset();this._tokenizer.reset();this._tagname="";this._attribname="";this._attribs=null;this._stack=[];if(this._cbs.onparserinit)this._cbs.onparserinit(this)};Parser.prototype.parseComplete=function(data){this.reset();this.end(data)};Parser.prototype.write=function(chunk){this._tokenizer.write(chunk)};Parser.prototype.end=function(chunk){this._tokenizer.end(chunk)};Parser.prototype.pause=function(){this._tokenizer.pause()};Parser.prototype.resume=function(){this._tokenizer.resume()};Parser.prototype.parseChunk=Parser.prototype.write;Parser.prototype.done=Parser.prototype.end;module.exports=Parser},{"./Tokenizer.js":34,events:28,inherits:38}],32:[function(require,module,exports){module.exports=ProxyHandler;function ProxyHandler(cbs){this._cbs=cbs||{}}var EVENTS=require("./").EVENTS;Object.keys(EVENTS).forEach(function(name){if(EVENTS[name]===0){name="on"+name;ProxyHandler.prototype[name]=function(){if(this._cbs[name])this._cbs[name]()}}else if(EVENTS[name]===1){name="on"+name;ProxyHandler.prototype[name]=function(a){if(this._cbs[name])this._cbs[name](a)}}else if(EVENTS[name]===2){name="on"+name;ProxyHandler.prototype[name]=function(a,b){if(this._cbs[name])this._cbs[name](a,b)}}else{throw Error("wrong number of arguments")}})},{"./":36}],33:[function(require,module,exports){module.exports=Stream;var Parser=require("./WritableStream.js");function Stream(options){Parser.call(this,new Cbs(this),options)}require("inherits")(Stream,Parser);Stream.prototype.readable=true;function Cbs(scope){this.scope=scope}var EVENTS=require("../").EVENTS;Object.keys(EVENTS).forEach(function(name){if(EVENTS[name]===0){Cbs.prototype["on"+name]=function(){this.scope.emit(name)}}else if(EVENTS[name]===1){Cbs.prototype["on"+name]=function(a){this.scope.emit(name,a)}}else if(EVENTS[name]===2){Cbs.prototype["on"+name]=function(a,b){this.scope.emit(name,a,b)}}else{throw Error("wrong number of arguments!")}})},{"../":36,"./WritableStream.js":35,inherits:38}],34:[function(require,module,exports){module.exports=Tokenizer;var decodeCodePoint=require("entities/lib/decode_codepoint.js"),entityMap=require("entities/maps/entities.json"),legacyMap=require("entities/maps/legacy.json"),xmlMap=require("entities/maps/xml.json"),i=0,TEXT=i++,BEFORE_TAG_NAME=i++,IN_TAG_NAME=i++,IN_SELF_CLOSING_TAG=i++,BEFORE_CLOSING_TAG_NAME=i++,IN_CLOSING_TAG_NAME=i++,AFTER_CLOSING_TAG_NAME=i++,BEFORE_ATTRIBUTE_NAME=i++,IN_ATTRIBUTE_NAME=i++,AFTER_ATTRIBUTE_NAME=i++,BEFORE_ATTRIBUTE_VALUE=i++,IN_ATTRIBUTE_VALUE_DQ=i++,IN_ATTRIBUTE_VALUE_SQ=i++,IN_ATTRIBUTE_VALUE_NQ=i++,BEFORE_DECLARATION=i++,IN_DECLARATION=i++,IN_PROCESSING_INSTRUCTION=i++,BEFORE_COMMENT=i++,IN_COMMENT=i++,AFTER_COMMENT_1=i++,AFTER_COMMENT_2=i++,BEFORE_CDATA_1=i++,BEFORE_CDATA_2=i++,BEFORE_CDATA_3=i++,BEFORE_CDATA_4=i++,BEFORE_CDATA_5=i++,BEFORE_CDATA_6=i++,IN_CDATA=i++,AFTER_CDATA_1=i++,AFTER_CDATA_2=i++,BEFORE_SPECIAL=i++,BEFORE_SPECIAL_END=i++,BEFORE_SCRIPT_1=i++,BEFORE_SCRIPT_2=i++,BEFORE_SCRIPT_3=i++,BEFORE_SCRIPT_4=i++,BEFORE_SCRIPT_5=i++,AFTER_SCRIPT_1=i++,AFTER_SCRIPT_2=i++,AFTER_SCRIPT_3=i++,AFTER_SCRIPT_4=i++,AFTER_SCRIPT_5=i++,BEFORE_STYLE_1=i++,BEFORE_STYLE_2=i++,BEFORE_STYLE_3=i++,BEFORE_STYLE_4=i++,AFTER_STYLE_1=i++,AFTER_STYLE_2=i++,AFTER_STYLE_3=i++,AFTER_STYLE_4=i++,BEFORE_ENTITY=i++,BEFORE_NUMERIC_ENTITY=i++,IN_NAMED_ENTITY=i++,IN_NUMERIC_ENTITY=i++,IN_HEX_ENTITY=i++,j=0,SPECIAL_NONE=j++,SPECIAL_SCRIPT=j++,SPECIAL_STYLE=j++;function whitespace(c){return c===" "||c==="\n"||c==="\t"||c==="\f"||c==="\r"}function characterState(char,SUCCESS){return function(c){if(c===char)this._state=SUCCESS}}function ifElseState(upper,SUCCESS,FAILURE){var lower=upper.toLowerCase();if(upper===lower){return function(c){if(c===lower){this._state=SUCCESS}else{this._state=FAILURE;this._index--}}}else{return function(c){if(c===lower||c===upper){this._state=SUCCESS}else{this._state=FAILURE;this._index--}}}}function consumeSpecialNameChar(upper,NEXT_STATE){var lower=upper.toLowerCase();return function(c){if(c===lower||c===upper){this._state=NEXT_STATE}else{this._state=IN_TAG_NAME;this._index--}}}function Tokenizer(options,cbs){this._state=TEXT;this._buffer="";this._sectionStart=0;this._index=0;this._bufferOffset=0;this._baseState=TEXT;this._special=SPECIAL_NONE;this._cbs=cbs;this._running=true;this._ended=false;this._xmlMode=!!(options&&options.xmlMode);this._decodeEntities=!!(options&&options.decodeEntities)}Tokenizer.prototype._stateText=function(c){if(c==="<"){if(this._index>this._sectionStart){this._cbs.ontext(this._getSection())}this._state=BEFORE_TAG_NAME;this._sectionStart=this._index}else if(this._decodeEntities&&this._special===SPECIAL_NONE&&c==="&"){if(this._index>this._sectionStart){this._cbs.ontext(this._getSection())}this._baseState=TEXT;this._state=BEFORE_ENTITY;this._sectionStart=this._index}};Tokenizer.prototype._stateBeforeTagName=function(c){if(c==="/"){this._state=BEFORE_CLOSING_TAG_NAME}else if(c==="<"){this._cbs.ontext(this._getSection());this._sectionStart=this._index}else if(c===">"||this._special!==SPECIAL_NONE||whitespace(c)){this._state=TEXT}else if(c==="!"){this._state=BEFORE_DECLARATION;this._sectionStart=this._index+1}else if(c==="?"){this._state=IN_PROCESSING_INSTRUCTION;this._sectionStart=this._index+1}else{this._state=!this._xmlMode&&(c==="s"||c==="S")?BEFORE_SPECIAL:IN_TAG_NAME;this._sectionStart=this._index}};Tokenizer.prototype._stateInTagName=function(c){if(c==="/"||c===">"||whitespace(c)){this._emitToken("onopentagname");this._state=BEFORE_ATTRIBUTE_NAME;this._index--}};Tokenizer.prototype._stateBeforeCloseingTagName=function(c){if(whitespace(c));else if(c===">"){this._state=TEXT}else if(this._special!==SPECIAL_NONE){if(c==="s"||c==="S"){this._state=BEFORE_SPECIAL_END}else{this._state=TEXT;this._index--}}else{this._state=IN_CLOSING_TAG_NAME;this._sectionStart=this._index}};Tokenizer.prototype._stateInCloseingTagName=function(c){if(c===">"||whitespace(c)){this._emitToken("onclosetag");this._state=AFTER_CLOSING_TAG_NAME;this._index--}};Tokenizer.prototype._stateAfterCloseingTagName=function(c){if(c===">"){this._state=TEXT;this._sectionStart=this._index+1}};Tokenizer.prototype._stateBeforeAttributeName=function(c){if(c===">"){this._cbs.onopentagend();this._state=TEXT;this._sectionStart=this._index+1}else if(c==="/"){this._state=IN_SELF_CLOSING_TAG}else if(!whitespace(c)){this._state=IN_ATTRIBUTE_NAME;this._sectionStart=this._index}};Tokenizer.prototype._stateInSelfClosingTag=function(c){if(c===">"){this._cbs.onselfclosingtag();this._state=TEXT;this._sectionStart=this._index+1}else if(!whitespace(c)){this._state=BEFORE_ATTRIBUTE_NAME;this._index--}};Tokenizer.prototype._stateInAttributeName=function(c){if(c==="="||c==="/"||c===">"||whitespace(c)){this._cbs.onattribname(this._getSection());this._sectionStart=-1;this._state=AFTER_ATTRIBUTE_NAME;this._index--}};Tokenizer.prototype._stateAfterAttributeName=function(c){if(c==="="){this._state=BEFORE_ATTRIBUTE_VALUE}else if(c==="/"||c===">"){this._cbs.onattribend();this._state=BEFORE_ATTRIBUTE_NAME;this._index--}else if(!whitespace(c)){this._cbs.onattribend();this._state=IN_ATTRIBUTE_NAME;this._sectionStart=this._index}};Tokenizer.prototype._stateBeforeAttributeValue=function(c){if(c==='"'){this._state=IN_ATTRIBUTE_VALUE_DQ;this._sectionStart=this._index+1}else if(c==="'"){this._state=IN_ATTRIBUTE_VALUE_SQ;this._sectionStart=this._index+1}else if(!whitespace(c)){this._state=IN_ATTRIBUTE_VALUE_NQ;this._sectionStart=this._index;this._index--}};Tokenizer.prototype._stateInAttributeValueDoubleQuotes=function(c){if(c==='"'){this._emitToken("onattribdata");this._cbs.onattribend();this._state=BEFORE_ATTRIBUTE_NAME}else if(this._decodeEntities&&c==="&"){this._emitToken("onattribdata");this._baseState=this._state;this._state=BEFORE_ENTITY;this._sectionStart=this._index}};Tokenizer.prototype._stateInAttributeValueSingleQuotes=function(c){if(c==="'"){this._emitToken("onattribdata");this._cbs.onattribend();this._state=BEFORE_ATTRIBUTE_NAME}else if(this._decodeEntities&&c==="&"){this._emitToken("onattribdata");this._baseState=this._state;this._state=BEFORE_ENTITY;this._sectionStart=this._index}};Tokenizer.prototype._stateInAttributeValueNoQuotes=function(c){if(whitespace(c)||c===">"){this._emitToken("onattribdata");this._cbs.onattribend();this._state=BEFORE_ATTRIBUTE_NAME;this._index--}else if(this._decodeEntities&&c==="&"){this._emitToken("onattribdata");this._baseState=this._state;this._state=BEFORE_ENTITY;this._sectionStart=this._index}};Tokenizer.prototype._stateBeforeDeclaration=function(c){this._state=c==="["?BEFORE_CDATA_1:c==="-"?BEFORE_COMMENT:IN_DECLARATION};Tokenizer.prototype._stateInDeclaration=function(c){if(c===">"){this._cbs.ondeclaration(this._getSection());this._state=TEXT;this._sectionStart=this._index+1}};Tokenizer.prototype._stateInProcessingInstruction=function(c){if(c===">"){this._cbs.onprocessinginstruction(this._getSection());this._state=TEXT;this._sectionStart=this._index+1}};Tokenizer.prototype._stateBeforeComment=function(c){if(c==="-"){this._state=IN_COMMENT;this._sectionStart=this._index+1}else{this._state=IN_DECLARATION}};Tokenizer.prototype._stateInComment=function(c){if(c==="-")this._state=AFTER_COMMENT_1};Tokenizer.prototype._stateAfterComment1=function(c){if(c==="-"){this._state=AFTER_COMMENT_2}else{this._state=IN_COMMENT}};Tokenizer.prototype._stateAfterComment2=function(c){if(c===">"){this._cbs.oncomment(this._buffer.substring(this._sectionStart,this._index-2));this._state=TEXT;this._sectionStart=this._index+1}else if(c!=="-"){this._state=IN_COMMENT}};Tokenizer.prototype._stateBeforeCdata1=ifElseState("C",BEFORE_CDATA_2,IN_DECLARATION);Tokenizer.prototype._stateBeforeCdata2=ifElseState("D",BEFORE_CDATA_3,IN_DECLARATION);Tokenizer.prototype._stateBeforeCdata3=ifElseState("A",BEFORE_CDATA_4,IN_DECLARATION);Tokenizer.prototype._stateBeforeCdata4=ifElseState("T",BEFORE_CDATA_5,IN_DECLARATION);Tokenizer.prototype._stateBeforeCdata5=ifElseState("A",BEFORE_CDATA_6,IN_DECLARATION);Tokenizer.prototype._stateBeforeCdata6=function(c){if(c==="["){this._state=IN_CDATA;this._sectionStart=this._index+1}else{this._state=IN_DECLARATION;this._index--}};Tokenizer.prototype._stateInCdata=function(c){if(c==="]")this._state=AFTER_CDATA_1};Tokenizer.prototype._stateAfterCdata1=characterState("]",AFTER_CDATA_2);Tokenizer.prototype._stateAfterCdata2=function(c){if(c===">"){this._cbs.oncdata(this._buffer.substring(this._sectionStart,this._index-2));this._state=TEXT;this._sectionStart=this._index+1}else if(c!=="]"){this._state=IN_CDATA}};Tokenizer.prototype._stateBeforeSpecial=function(c){if(c==="c"||c==="C"){this._state=BEFORE_SCRIPT_1}else if(c==="t"||c==="T"){this._state=BEFORE_STYLE_1}else{this._state=IN_TAG_NAME;this._index--}};Tokenizer.prototype._stateBeforeSpecialEnd=function(c){if(this._special===SPECIAL_SCRIPT&&(c==="c"||c==="C")){this._state=AFTER_SCRIPT_1}else if(this._special===SPECIAL_STYLE&&(c==="t"||c==="T")){this._state=AFTER_STYLE_1}else this._state=TEXT};Tokenizer.prototype._stateBeforeScript1=consumeSpecialNameChar("R",BEFORE_SCRIPT_2);Tokenizer.prototype._stateBeforeScript2=consumeSpecialNameChar("I",BEFORE_SCRIPT_3);Tokenizer.prototype._stateBeforeScript3=consumeSpecialNameChar("P",BEFORE_SCRIPT_4);Tokenizer.prototype._stateBeforeScript4=consumeSpecialNameChar("T",BEFORE_SCRIPT_5);Tokenizer.prototype._stateBeforeScript5=function(c){if(c==="/"||c===">"||whitespace(c)){this._special=SPECIAL_SCRIPT}this._state=IN_TAG_NAME;this._index--};Tokenizer.prototype._stateAfterScript1=ifElseState("R",AFTER_SCRIPT_2,TEXT);Tokenizer.prototype._stateAfterScript2=ifElseState("I",AFTER_SCRIPT_3,TEXT);Tokenizer.prototype._stateAfterScript3=ifElseState("P",AFTER_SCRIPT_4,TEXT);Tokenizer.prototype._stateAfterScript4=ifElseState("T",AFTER_SCRIPT_5,TEXT);Tokenizer.prototype._stateAfterScript5=function(c){if(c===">"||whitespace(c)){this._special=SPECIAL_NONE;this._state=IN_CLOSING_TAG_NAME;this._sectionStart=this._index-6;this._index--}else this._state=TEXT};Tokenizer.prototype._stateBeforeStyle1=consumeSpecialNameChar("Y",BEFORE_STYLE_2);Tokenizer.prototype._stateBeforeStyle2=consumeSpecialNameChar("L",BEFORE_STYLE_3);Tokenizer.prototype._stateBeforeStyle3=consumeSpecialNameChar("E",BEFORE_STYLE_4);Tokenizer.prototype._stateBeforeStyle4=function(c){if(c==="/"||c===">"||whitespace(c)){this._special=SPECIAL_STYLE}this._state=IN_TAG_NAME;this._index--};Tokenizer.prototype._stateAfterStyle1=ifElseState("Y",AFTER_STYLE_2,TEXT);Tokenizer.prototype._stateAfterStyle2=ifElseState("L",AFTER_STYLE_3,TEXT);Tokenizer.prototype._stateAfterStyle3=ifElseState("E",AFTER_STYLE_4,TEXT);Tokenizer.prototype._stateAfterStyle4=function(c){if(c===">"||whitespace(c)){this._special=SPECIAL_NONE;this._state=IN_CLOSING_TAG_NAME;this._sectionStart=this._index-5;this._index--}else this._state=TEXT};Tokenizer.prototype._stateBeforeEntity=ifElseState("#",BEFORE_NUMERIC_ENTITY,IN_NAMED_ENTITY);Tokenizer.prototype._stateBeforeNumericEntity=ifElseState("X",IN_HEX_ENTITY,IN_NUMERIC_ENTITY);Tokenizer.prototype._parseNamedEntityStrict=function(){if(this._sectionStart+1<this._index){var entity=this._buffer.substring(this._sectionStart+1,this._index),map=this._xmlMode?xmlMap:entityMap;if(map.hasOwnProperty(entity)){this._emitPartial(map[entity]);this._sectionStart=this._index+1}}};Tokenizer.prototype._parseLegacyEntity=function(){var start=this._sectionStart+1,limit=this._index-start;if(limit>6)limit=6;while(limit>=2){var entity=this._buffer.substr(start,limit);if(legacyMap.hasOwnProperty(entity)){this._emitPartial(legacyMap[entity]);this._sectionStart+=limit+1;return}else{limit--}}};Tokenizer.prototype._stateInNamedEntity=function(c){if(c===";"){this._parseNamedEntityStrict();if(this._sectionStart+1<this._index&&!this._xmlMode){this._parseLegacyEntity()}this._state=this._baseState}else if((c<"a"||c>"z")&&(c<"A"||c>"Z")&&(c<"0"||c>"9")){if(this._xmlMode);else if(this._sectionStart+1===this._index);else if(this._baseState!==TEXT){if(c!=="="){this._parseNamedEntityStrict()}}else{this._parseLegacyEntity()}this._state=this._baseState;this._index--}};Tokenizer.prototype._decodeNumericEntity=function(offset,base){var sectionStart=this._sectionStart+offset;if(sectionStart!==this._index){var entity=this._buffer.substring(sectionStart,this._index);var parsed=parseInt(entity,base);this._emitPartial(decodeCodePoint(parsed));this._sectionStart=this._index}else{this._sectionStart--}this._state=this._baseState};Tokenizer.prototype._stateInNumericEntity=function(c){if(c===";"){this._decodeNumericEntity(2,10);this._sectionStart++}else if(c<"0"||c>"9"){if(!this._xmlMode){this._decodeNumericEntity(2,10)}else{this._state=this._baseState}this._index--}};Tokenizer.prototype._stateInHexEntity=function(c){if(c===";"){this._decodeNumericEntity(3,16);this._sectionStart++}else if((c<"a"||c>"f")&&(c<"A"||c>"F")&&(c<"0"||c>"9")){if(!this._xmlMode){this._decodeNumericEntity(3,16)}else{this._state=this._baseState}this._index--}};Tokenizer.prototype._cleanup=function(){if(this._sectionStart<0){this._buffer="";this._index=0;this._bufferOffset+=this._index}else if(this._running){if(this._state===TEXT){if(this._sectionStart!==this._index){this._cbs.ontext(this._buffer.substr(this._sectionStart))}this._buffer="";this._bufferOffset+=this._index;this._index=0}else if(this._sectionStart===this._index){this._buffer="";this._bufferOffset+=this._index;this._index=0}else{this._buffer=this._buffer.substr(this._sectionStart);this._index-=this._sectionStart;this._bufferOffset+=this._sectionStart}this._sectionStart=0}};Tokenizer.prototype.write=function(chunk){if(this._ended)this._cbs.onerror(Error(".write() after done!"));this._buffer+=chunk;this._parse()};Tokenizer.prototype._parse=function(){while(this._index<this._buffer.length&&this._running){var c=this._buffer.charAt(this._index);if(this._state===TEXT){this._stateText(c)}else if(this._state===BEFORE_TAG_NAME){this._stateBeforeTagName(c)}else if(this._state===IN_TAG_NAME){this._stateInTagName(c)}else if(this._state===BEFORE_CLOSING_TAG_NAME){this._stateBeforeCloseingTagName(c)}else if(this._state===IN_CLOSING_TAG_NAME){this._stateInCloseingTagName(c)}else if(this._state===AFTER_CLOSING_TAG_NAME){this._stateAfterCloseingTagName(c)}else if(this._state===IN_SELF_CLOSING_TAG){this._stateInSelfClosingTag(c)}else if(this._state===BEFORE_ATTRIBUTE_NAME){this._stateBeforeAttributeName(c)}else if(this._state===IN_ATTRIBUTE_NAME){this._stateInAttributeName(c)}else if(this._state===AFTER_ATTRIBUTE_NAME){this._stateAfterAttributeName(c)}else if(this._state===BEFORE_ATTRIBUTE_VALUE){this._stateBeforeAttributeValue(c)}else if(this._state===IN_ATTRIBUTE_VALUE_DQ){this._stateInAttributeValueDoubleQuotes(c)}else if(this._state===IN_ATTRIBUTE_VALUE_SQ){this._stateInAttributeValueSingleQuotes(c)}else if(this._state===IN_ATTRIBUTE_VALUE_NQ){this._stateInAttributeValueNoQuotes(c)}else if(this._state===BEFORE_DECLARATION){this._stateBeforeDeclaration(c)}else if(this._state===IN_DECLARATION){this._stateInDeclaration(c)}else if(this._state===IN_PROCESSING_INSTRUCTION){this._stateInProcessingInstruction(c)}else if(this._state===BEFORE_COMMENT){this._stateBeforeComment(c)}else if(this._state===IN_COMMENT){this._stateInComment(c)}else if(this._state===AFTER_COMMENT_1){this._stateAfterComment1(c)}else if(this._state===AFTER_COMMENT_2){this._stateAfterComment2(c)}else if(this._state===BEFORE_CDATA_1){this._stateBeforeCdata1(c)}else if(this._state===BEFORE_CDATA_2){this._stateBeforeCdata2(c)}else if(this._state===BEFORE_CDATA_3){this._stateBeforeCdata3(c)}else if(this._state===BEFORE_CDATA_4){this._stateBeforeCdata4(c)}else if(this._state===BEFORE_CDATA_5){this._stateBeforeCdata5(c)}else if(this._state===BEFORE_CDATA_6){this._stateBeforeCdata6(c)}else if(this._state===IN_CDATA){this._stateInCdata(c)}else if(this._state===AFTER_CDATA_1){this._stateAfterCdata1(c)}else if(this._state===AFTER_CDATA_2){this._stateAfterCdata2(c)}else if(this._state===BEFORE_SPECIAL){this._stateBeforeSpecial(c)}else if(this._state===BEFORE_SPECIAL_END){this._stateBeforeSpecialEnd(c)}else if(this._state===BEFORE_SCRIPT_1){this._stateBeforeScript1(c)}else if(this._state===BEFORE_SCRIPT_2){this._stateBeforeScript2(c)}else if(this._state===BEFORE_SCRIPT_3){this._stateBeforeScript3(c)}else if(this._state===BEFORE_SCRIPT_4){this._stateBeforeScript4(c)}else if(this._state===BEFORE_SCRIPT_5){this._stateBeforeScript5(c)}else if(this._state===AFTER_SCRIPT_1){this._stateAfterScript1(c)}else if(this._state===AFTER_SCRIPT_2){this._stateAfterScript2(c)}else if(this._state===AFTER_SCRIPT_3){this._stateAfterScript3(c)}else if(this._state===AFTER_SCRIPT_4){this._stateAfterScript4(c)}else if(this._state===AFTER_SCRIPT_5){this._stateAfterScript5(c)}else if(this._state===BEFORE_STYLE_1){this._stateBeforeStyle1(c)}else if(this._state===BEFORE_STYLE_2){this._stateBeforeStyle2(c)}else if(this._state===BEFORE_STYLE_3){this._stateBeforeStyle3(c)}else if(this._state===BEFORE_STYLE_4){this._stateBeforeStyle4(c)}else if(this._state===AFTER_STYLE_1){this._stateAfterStyle1(c)}else if(this._state===AFTER_STYLE_2){this._stateAfterStyle2(c)}else if(this._state===AFTER_STYLE_3){this._stateAfterStyle3(c)}else if(this._state===AFTER_STYLE_4){this._stateAfterStyle4(c)}else if(this._state===BEFORE_ENTITY){this._stateBeforeEntity(c)}else if(this._state===BEFORE_NUMERIC_ENTITY){this._stateBeforeNumericEntity(c)}else if(this._state===IN_NAMED_ENTITY){this._stateInNamedEntity(c)}else if(this._state===IN_NUMERIC_ENTITY){this._stateInNumericEntity(c)}else if(this._state===IN_HEX_ENTITY){this._stateInHexEntity(c)}else{this._cbs.onerror(Error("unknown _state"),this._state)}this._index++}this._cleanup()};Tokenizer.prototype.pause=function(){this._running=false};Tokenizer.prototype.resume=function(){this._running=true;if(this._index<this._buffer.length){this._parse()}if(this._ended){this._finish()}};Tokenizer.prototype.end=function(chunk){if(this._ended)this._cbs.onerror(Error(".end() after done!"));if(chunk)this.write(chunk);this._ended=true;if(this._running)this._finish()};Tokenizer.prototype._finish=function(){if(this._sectionStart<this._index){this._handleTrailingData()}this._cbs.onend()};Tokenizer.prototype._handleTrailingData=function(){var data=this._buffer.substr(this._sectionStart);if(this._state===IN_CDATA||this._state===AFTER_CDATA_1||this._state===AFTER_CDATA_2){this._cbs.oncdata(data)}else if(this._state===IN_COMMENT||this._state===AFTER_COMMENT_1||this._state===AFTER_COMMENT_2){this._cbs.oncomment(data)}else if(this._state===IN_NAMED_ENTITY&&!this._xmlMode){this._parseLegacyEntity();if(this._sectionStart<this._index){this._state=this._baseState;this._handleTrailingData()}}else if(this._state===IN_NUMERIC_ENTITY&&!this._xmlMode){this._decodeNumericEntity(2,10);if(this._sectionStart<this._index){this._state=this._baseState;this._handleTrailingData()}}else if(this._state===IN_HEX_ENTITY&&!this._xmlMode){this._decodeNumericEntity(3,16);if(this._sectionStart<this._index){this._state=this._baseState;this._handleTrailingData()}}else if(this._state!==IN_TAG_NAME&&this._state!==BEFORE_ATTRIBUTE_NAME&&this._state!==BEFORE_ATTRIBUTE_VALUE&&this._state!==AFTER_ATTRIBUTE_NAME&&this._state!==IN_ATTRIBUTE_NAME&&this._state!==IN_ATTRIBUTE_VALUE_SQ&&this._state!==IN_ATTRIBUTE_VALUE_DQ&&this._state!==IN_ATTRIBUTE_VALUE_NQ&&this._state!==IN_CLOSING_TAG_NAME){
-this._cbs.ontext(data)}};Tokenizer.prototype.reset=function(){Tokenizer.call(this,{xmlMode:this._xmlMode,decodeEntities:this._decodeEntities},this._cbs)};Tokenizer.prototype.getAbsoluteIndex=function(){return this._bufferOffset+this._index};Tokenizer.prototype._getSection=function(){return this._buffer.substring(this._sectionStart,this._index)};Tokenizer.prototype._emitToken=function(name){this._cbs[name](this._getSection());this._sectionStart=-1};Tokenizer.prototype._emitPartial=function(value){if(this._baseState!==TEXT){this._cbs.onattribdata(value)}else{this._cbs.ontext(value)}}},{"entities/lib/decode_codepoint.js":22,"entities/maps/entities.json":25,"entities/maps/legacy.json":26,"entities/maps/xml.json":27}],35:[function(require,module,exports){module.exports=Stream;var Parser=require("./Parser.js"),WritableStream=require("stream").Writable||require("readable-stream").Writable,StringDecoder=require("string_decoder").StringDecoder,Buffer=require("buffer").Buffer;function Stream(cbs,options){var parser=this._parser=new Parser(cbs,options);var decoder=this._decoder=new StringDecoder;WritableStream.call(this,{decodeStrings:false});this.once("finish",function(){parser.end(decoder.end())})}require("inherits")(Stream,WritableStream);WritableStream.prototype._write=function(chunk,encoding,cb){if(chunk instanceof Buffer)chunk=this._decoder.write(chunk);this._parser.write(chunk);cb()}},{"./Parser.js":31,buffer:5,inherits:38,"readable-stream":3,stream:55,string_decoder:56}],36:[function(require,module,exports){var Parser=require("./Parser.js"),DomHandler=require("domhandler");function defineProp(name,value){delete module.exports[name];module.exports[name]=value;return value}module.exports={Parser:Parser,Tokenizer:require("./Tokenizer.js"),ElementType:require("domelementtype"),DomHandler:DomHandler,get FeedHandler(){return defineProp("FeedHandler",require("./FeedHandler.js"))},get Stream(){return defineProp("Stream",require("./Stream.js"))},get WritableStream(){return defineProp("WritableStream",require("./WritableStream.js"))},get ProxyHandler(){return defineProp("ProxyHandler",require("./ProxyHandler.js"))},get DomUtils(){return defineProp("DomUtils",require("domutils"))},get CollectingHandler(){return defineProp("CollectingHandler",require("./CollectingHandler.js"))},DefaultHandler:DomHandler,get RssHandler(){return defineProp("RssHandler",this.FeedHandler)},parseDOM:function(data,options){var handler=new DomHandler(options);new Parser(handler,options).end(data);return handler.dom},parseFeed:function(feed,options){var handler=new module.exports.FeedHandler(options);new Parser(handler,options).end(feed);return handler.dom},createDomStream:function(cb,options,elementCb){var handler=new DomHandler(cb,options,elementCb);return new Parser(handler,options)},EVENTS:{attribute:2,cdatastart:0,cdataend:0,text:1,processinginstruction:2,comment:1,commentend:0,closetag:1,opentag:2,opentagname:1,error:1,end:0}}},{"./CollectingHandler.js":29,"./FeedHandler.js":30,"./Parser.js":31,"./ProxyHandler.js":32,"./Stream.js":33,"./Tokenizer.js":34,"./WritableStream.js":35,domelementtype:9,domhandler:10,domutils:13}],37:[function(require,module,exports){exports.read=function(buffer,offset,isLE,mLen,nBytes){var e,m;var eLen=nBytes*8-mLen-1;var eMax=(1<<eLen)-1;var eBias=eMax>>1;var nBits=-7;var i=isLE?nBytes-1:0;var d=isLE?-1:1;var s=buffer[offset+i];i+=d;e=s&(1<<-nBits)-1;s>>=-nBits;nBits+=eLen;for(;nBits>0;e=e*256+buffer[offset+i],i+=d,nBits-=8){}m=e&(1<<-nBits)-1;e>>=-nBits;nBits+=mLen;for(;nBits>0;m=m*256+buffer[offset+i],i+=d,nBits-=8){}if(e===0){e=1-eBias}else if(e===eMax){return m?NaN:(s?-1:1)*Infinity}else{m=m+Math.pow(2,mLen);e=e-eBias}return(s?-1:1)*m*Math.pow(2,e-mLen)};exports.write=function(buffer,value,offset,isLE,mLen,nBytes){var e,m,c;var eLen=nBytes*8-mLen-1;var eMax=(1<<eLen)-1;var eBias=eMax>>1;var rt=mLen===23?Math.pow(2,-24)-Math.pow(2,-77):0;var i=isLE?0:nBytes-1;var d=isLE?1:-1;var s=value<0||value===0&&1/value<0?1:0;value=Math.abs(value);if(isNaN(value)||value===Infinity){m=isNaN(value)?1:0;e=eMax}else{e=Math.floor(Math.log(value)/Math.LN2);if(value*(c=Math.pow(2,-e))<1){e--;c*=2}if(e+eBias>=1){value+=rt/c}else{value+=rt*Math.pow(2,1-eBias)}if(value*c>=2){e++;c/=2}if(e+eBias>=eMax){m=0;e=eMax}else if(e+eBias>=1){m=(value*c-1)*Math.pow(2,mLen);e=e+eBias}else{m=value*Math.pow(2,eBias-1)*Math.pow(2,mLen);e=0}}for(;mLen>=8;buffer[offset+i]=m&255,i+=d,m/=256,mLen-=8){}e=e<<mLen|m;eLen+=mLen;for(;eLen>0;buffer[offset+i]=e&255,i+=d,e/=256,eLen-=8){}buffer[offset+i-d]|=s*128}},{}],38:[function(require,module,exports){if(typeof Object.create==="function"){module.exports=function inherits(ctor,superCtor){ctor.super_=superCtor;ctor.prototype=Object.create(superCtor.prototype,{constructor:{value:ctor,enumerable:false,writable:true,configurable:true}})}}else{module.exports=function inherits(ctor,superCtor){ctor.super_=superCtor;var TempCtor=function(){};TempCtor.prototype=superCtor.prototype;ctor.prototype=new TempCtor;ctor.prototype.constructor=ctor}}},{}],39:[function(require,module,exports){module.exports=function(obj){return obj!=null&&(isBuffer(obj)||isSlowBuffer(obj)||!!obj._isBuffer)};function isBuffer(obj){return!!obj.constructor&&typeof obj.constructor.isBuffer==="function"&&obj.constructor.isBuffer(obj)}function isSlowBuffer(obj){return typeof obj.readFloatLE==="function"&&typeof obj.slice==="function"&&isBuffer(obj.slice(0,0))}},{}],40:[function(require,module,exports){var toString={}.toString;module.exports=Array.isArray||function(arr){return toString.call(arr)=="[object Array]"}},{}],41:[function(require,module,exports){(function(process){"use strict";if(!process.version||process.version.indexOf("v0.")===0||process.version.indexOf("v1.")===0&&process.version.indexOf("v1.8.")!==0){module.exports=nextTick}else{module.exports=process.nextTick}function nextTick(fn,arg1,arg2,arg3){if(typeof fn!=="function"){throw new TypeError('"callback" argument must be a function')}var len=arguments.length;var args,i;switch(len){case 0:case 1:return process.nextTick(fn);case 2:return process.nextTick(function afterTickOne(){fn.call(null,arg1)});case 3:return process.nextTick(function afterTickTwo(){fn.call(null,arg1,arg2)});case 4:return process.nextTick(function afterTickThree(){fn.call(null,arg1,arg2,arg3)});default:args=new Array(len-1);i=0;while(i<args.length){args[i++]=arguments[i]}return process.nextTick(function afterTick(){fn.apply(null,args)})}}}).call(this,require("_process"))},{_process:42}],42:[function(require,module,exports){var process=module.exports={};var cachedSetTimeout;var cachedClearTimeout;function defaultSetTimout(){throw new Error("setTimeout has not been defined")}function defaultClearTimeout(){throw new Error("clearTimeout has not been defined")}(function(){try{if(typeof setTimeout==="function"){cachedSetTimeout=setTimeout}else{cachedSetTimeout=defaultSetTimout}}catch(e){cachedSetTimeout=defaultSetTimout}try{if(typeof clearTimeout==="function"){cachedClearTimeout=clearTimeout}else{cachedClearTimeout=defaultClearTimeout}}catch(e){cachedClearTimeout=defaultClearTimeout}})();function runTimeout(fun){if(cachedSetTimeout===setTimeout){return setTimeout(fun,0)}if((cachedSetTimeout===defaultSetTimout||!cachedSetTimeout)&&setTimeout){cachedSetTimeout=setTimeout;return setTimeout(fun,0)}try{return cachedSetTimeout(fun,0)}catch(e){try{return cachedSetTimeout.call(null,fun,0)}catch(e){return cachedSetTimeout.call(this,fun,0)}}}function runClearTimeout(marker){if(cachedClearTimeout===clearTimeout){return clearTimeout(marker)}if((cachedClearTimeout===defaultClearTimeout||!cachedClearTimeout)&&clearTimeout){cachedClearTimeout=clearTimeout;return clearTimeout(marker)}try{return cachedClearTimeout(marker)}catch(e){try{return cachedClearTimeout.call(null,marker)}catch(e){return cachedClearTimeout.call(this,marker)}}}var queue=[];var draining=false;var currentQueue;var queueIndex=-1;function cleanUpNextTick(){if(!draining||!currentQueue){return}draining=false;if(currentQueue.length){queue=currentQueue.concat(queue)}else{queueIndex=-1}if(queue.length){drainQueue()}}function drainQueue(){if(draining){return}var timeout=runTimeout(cleanUpNextTick);draining=true;var len=queue.length;while(len){currentQueue=queue;queue=[];while(++queueIndex<len){if(currentQueue){currentQueue[queueIndex].run()}}queueIndex=-1;len=queue.length}currentQueue=null;draining=false;runClearTimeout(timeout)}process.nextTick=function(fun){var args=new Array(arguments.length-1);if(arguments.length>1){for(var i=1;i<arguments.length;i++){args[i-1]=arguments[i]}}queue.push(new Item(fun,args));if(queue.length===1&&!draining){runTimeout(drainQueue)}};function Item(fun,array){this.fun=fun;this.array=array}Item.prototype.run=function(){this.fun.apply(null,this.array)};process.title="browser";process.browser=true;process.env={};process.argv=[];process.version="";process.versions={};function noop(){}process.on=noop;process.addListener=noop;process.once=noop;process.off=noop;process.removeListener=noop;process.removeAllListeners=noop;process.emit=noop;process.binding=function(name){throw new Error("process.binding is not supported")};process.cwd=function(){return"/"};process.chdir=function(dir){throw new Error("process.chdir is not supported")};process.umask=function(){return 0}},{}],43:[function(require,module,exports){module.exports=require("./lib/_stream_duplex.js")},{"./lib/_stream_duplex.js":44}],44:[function(require,module,exports){"use strict";var objectKeys=Object.keys||function(obj){var keys=[];for(var key in obj){keys.push(key)}return keys};module.exports=Duplex;var processNextTick=require("process-nextick-args");var util=require("core-util-is");util.inherits=require("inherits");var Readable=require("./_stream_readable");var Writable=require("./_stream_writable");util.inherits(Duplex,Readable);var keys=objectKeys(Writable.prototype);for(var v=0;v<keys.length;v++){var method=keys[v];if(!Duplex.prototype[method])Duplex.prototype[method]=Writable.prototype[method]}function Duplex(options){if(!(this instanceof Duplex))return new Duplex(options);Readable.call(this,options);Writable.call(this,options);if(options&&options.readable===false)this.readable=false;if(options&&options.writable===false)this.writable=false;this.allowHalfOpen=true;if(options&&options.allowHalfOpen===false)this.allowHalfOpen=false;this.once("end",onend)}function onend(){if(this.allowHalfOpen||this._writableState.ended)return;processNextTick(onEndNT,this)}function onEndNT(self){self.end()}function forEach(xs,f){for(var i=0,l=xs.length;i<l;i++){f(xs[i],i)}}},{"./_stream_readable":46,"./_stream_writable":48,"core-util-is":6,inherits:38,"process-nextick-args":41}],45:[function(require,module,exports){"use strict";module.exports=PassThrough;var Transform=require("./_stream_transform");var util=require("core-util-is");util.inherits=require("inherits");util.inherits(PassThrough,Transform);function PassThrough(options){if(!(this instanceof PassThrough))return new PassThrough(options);Transform.call(this,options)}PassThrough.prototype._transform=function(chunk,encoding,cb){cb(null,chunk)}},{"./_stream_transform":47,"core-util-is":6,inherits:38}],46:[function(require,module,exports){(function(process){"use strict";module.exports=Readable;var processNextTick=require("process-nextick-args");var isArray=require("isarray");Readable.ReadableState=ReadableState;var EE=require("events").EventEmitter;var EElistenerCount=function(emitter,type){return emitter.listeners(type).length};var Stream;(function(){try{Stream=require("st"+"ream")}catch(_){}finally{if(!Stream)Stream=require("events").EventEmitter}})();var Buffer=require("buffer").Buffer;var bufferShim=require("buffer-shims");var util=require("core-util-is");util.inherits=require("inherits");var debugUtil=require("util");var debug=void 0;if(debugUtil&&debugUtil.debuglog){debug=debugUtil.debuglog("stream")}else{debug=function(){}}var BufferList=require("./internal/streams/BufferList");var StringDecoder;util.inherits(Readable,Stream);function prependListener(emitter,event,fn){if(typeof emitter.prependListener==="function"){return emitter.prependListener(event,fn)}else{if(!emitter._events||!emitter._events[event])emitter.on(event,fn);else if(isArray(emitter._events[event]))emitter._events[event].unshift(fn);else emitter._events[event]=[fn,emitter._events[event]]}}var Duplex;function ReadableState(options,stream){Duplex=Duplex||require("./_stream_duplex");options=options||{};this.objectMode=!!options.objectMode;if(stream instanceof Duplex)this.objectMode=this.objectMode||!!options.readableObjectMode;var hwm=options.highWaterMark;var defaultHwm=this.objectMode?16:16*1024;this.highWaterMark=hwm||hwm===0?hwm:defaultHwm;this.highWaterMark=~~this.highWaterMark;this.buffer=new BufferList;this.length=0;this.pipes=null;this.pipesCount=0;this.flowing=null;this.ended=false;this.endEmitted=false;this.reading=false;this.sync=true;this.needReadable=false;this.emittedReadable=false;this.readableListening=false;this.resumeScheduled=false;this.defaultEncoding=options.defaultEncoding||"utf8";this.ranOut=false;this.awaitDrain=0;this.readingMore=false;this.decoder=null;this.encoding=null;if(options.encoding){if(!StringDecoder)StringDecoder=require("string_decoder/").StringDecoder;this.decoder=new StringDecoder(options.encoding);this.encoding=options.encoding}}var Duplex;function Readable(options){Duplex=Duplex||require("./_stream_duplex");if(!(this instanceof Readable))return new Readable(options);this._readableState=new ReadableState(options,this);this.readable=true;if(options&&typeof options.read==="function")this._read=options.read;Stream.call(this)}Readable.prototype.push=function(chunk,encoding){var state=this._readableState;if(!state.objectMode&&typeof chunk==="string"){encoding=encoding||state.defaultEncoding;if(encoding!==state.encoding){chunk=bufferShim.from(chunk,encoding);encoding=""}}return readableAddChunk(this,state,chunk,encoding,false)};Readable.prototype.unshift=function(chunk){var state=this._readableState;return readableAddChunk(this,state,chunk,"",true)};Readable.prototype.isPaused=function(){return this._readableState.flowing===false};function readableAddChunk(stream,state,chunk,encoding,addToFront){var er=chunkInvalid(state,chunk);if(er){stream.emit("error",er)}else if(chunk===null){state.reading=false;onEofChunk(stream,state)}else if(state.objectMode||chunk&&chunk.length>0){if(state.ended&&!addToFront){var e=new Error("stream.push() after EOF");stream.emit("error",e)}else if(state.endEmitted&&addToFront){var _e=new Error("stream.unshift() after end event");stream.emit("error",_e)}else{var skipAdd;if(state.decoder&&!addToFront&&!encoding){chunk=state.decoder.write(chunk);skipAdd=!state.objectMode&&chunk.length===0}if(!addToFront)state.reading=false;if(!skipAdd){if(state.flowing&&state.length===0&&!state.sync){stream.emit("data",chunk);stream.read(0)}else{state.length+=state.objectMode?1:chunk.length;if(addToFront)state.buffer.unshift(chunk);else state.buffer.push(chunk);if(state.needReadable)emitReadable(stream)}}maybeReadMore(stream,state)}}else if(!addToFront){state.reading=false}return needMoreData(state)}function needMoreData(state){return!state.ended&&(state.needReadable||state.length<state.highWaterMark||state.length===0)}Readable.prototype.setEncoding=function(enc){if(!StringDecoder)StringDecoder=require("string_decoder/").StringDecoder;this._readableState.decoder=new StringDecoder(enc);this._readableState.encoding=enc;return this};var MAX_HWM=8388608;function computeNewHighWaterMark(n){if(n>=MAX_HWM){n=MAX_HWM}else{n--;n|=n>>>1;n|=n>>>2;n|=n>>>4;n|=n>>>8;n|=n>>>16;n++}return n}function howMuchToRead(n,state){if(n<=0||state.length===0&&state.ended)return 0;if(state.objectMode)return 1;if(n!==n){if(state.flowing&&state.length)return state.buffer.head.data.length;else return state.length}if(n>state.highWaterMark)state.highWaterMark=computeNewHighWaterMark(n);if(n<=state.length)return n;if(!state.ended){state.needReadable=true;return 0}return state.length}Readable.prototype.read=function(n){debug("read",n);n=parseInt(n,10);var state=this._readableState;var nOrig=n;if(n!==0)state.emittedReadable=false;if(n===0&&state.needReadable&&(state.length>=state.highWaterMark||state.ended)){debug("read: emitReadable",state.length,state.ended);if(state.length===0&&state.ended)endReadable(this);else emitReadable(this);return null}n=howMuchToRead(n,state);if(n===0&&state.ended){if(state.length===0)endReadable(this);return null}var doRead=state.needReadable;debug("need readable",doRead);if(state.length===0||state.length-n<state.highWaterMark){doRead=true;debug("length less than watermark",doRead)}if(state.ended||state.reading){doRead=false;debug("reading or ended",doRead)}else if(doRead){debug("do read");state.reading=true;state.sync=true;if(state.length===0)state.needReadable=true;this._read(state.highWaterMark);state.sync=false;if(!state.reading)n=howMuchToRead(nOrig,state)}var ret;if(n>0)ret=fromList(n,state);else ret=null;if(ret===null){state.needReadable=true;n=0}else{state.length-=n}if(state.length===0){if(!state.ended)state.needReadable=true;if(nOrig!==n&&state.ended)endReadable(this)}if(ret!==null)this.emit("data",ret);return ret};function chunkInvalid(state,chunk){var er=null;if(!Buffer.isBuffer(chunk)&&typeof chunk!=="string"&&chunk!==null&&chunk!==undefined&&!state.objectMode){er=new TypeError("Invalid non-string/buffer chunk")}return er}function onEofChunk(stream,state){if(state.ended)return;if(state.decoder){var chunk=state.decoder.end();if(chunk&&chunk.length){state.buffer.push(chunk);state.length+=state.objectMode?1:chunk.length}}state.ended=true;emitReadable(stream)}function emitReadable(stream){var state=stream._readableState;state.needReadable=false;if(!state.emittedReadable){debug("emitReadable",state.flowing);state.emittedReadable=true;if(state.sync)processNextTick(emitReadable_,stream);else emitReadable_(stream)}}function emitReadable_(stream){debug("emit readable");stream.emit("readable");flow(stream)}function maybeReadMore(stream,state){if(!state.readingMore){state.readingMore=true;processNextTick(maybeReadMore_,stream,state)}}function maybeReadMore_(stream,state){var len=state.length;while(!state.reading&&!state.flowing&&!state.ended&&state.length<state.highWaterMark){debug("maybeReadMore read 0");stream.read(0);if(len===state.length)break;else len=state.length}state.readingMore=false}Readable.prototype._read=function(n){this.emit("error",new Error("not implemented"))};Readable.prototype.pipe=function(dest,pipeOpts){var src=this;var state=this._readableState;switch(state.pipesCount){case 0:state.pipes=dest;break;case 1:state.pipes=[state.pipes,dest];break;default:state.pipes.push(dest);break}state.pipesCount+=1;debug("pipe count=%d opts=%j",state.pipesCount,pipeOpts);var doEnd=(!pipeOpts||pipeOpts.end!==false)&&dest!==process.stdout&&dest!==process.stderr;var endFn=doEnd?onend:cleanup;if(state.endEmitted)processNextTick(endFn);else src.once("end",endFn);dest.on("unpipe",onunpipe);function onunpipe(readable){debug("onunpipe");if(readable===src){cleanup()}}function onend(){debug("onend");dest.end()}var ondrain=pipeOnDrain(src);dest.on("drain",ondrain);var cleanedUp=false;function cleanup(){debug("cleanup");dest.removeListener("close",onclose);dest.removeListener("finish",onfinish);dest.removeListener("drain",ondrain);dest.removeListener("error",onerror);dest.removeListener("unpipe",onunpipe);src.removeListener("end",onend);src.removeListener("end",cleanup);src.removeListener("data",ondata);cleanedUp=true;if(state.awaitDrain&&(!dest._writableState||dest._writableState.needDrain))ondrain()}var increasedAwaitDrain=false;src.on("data",ondata);function ondata(chunk){debug("ondata");increasedAwaitDrain=false;var ret=dest.write(chunk);if(false===ret&&!increasedAwaitDrain){if((state.pipesCount===1&&state.pipes===dest||state.pipesCount>1&&indexOf(state.pipes,dest)!==-1)&&!cleanedUp){debug("false write response, pause",src._readableState.awaitDrain);src._readableState.awaitDrain++;increasedAwaitDrain=true}src.pause()}}function onerror(er){debug("onerror",er);unpipe();dest.removeListener("error",onerror);if(EElistenerCount(dest,"error")===0)dest.emit("error",er)}prependListener(dest,"error",onerror);function onclose(){dest.removeListener("finish",onfinish);unpipe()}dest.once("close",onclose);function onfinish(){debug("onfinish");dest.removeListener("close",onclose);unpipe()}dest.once("finish",onfinish);function unpipe(){debug("unpipe");src.unpipe(dest)}dest.emit("pipe",src);if(!state.flowing){debug("pipe resume");src.resume()}return dest};function pipeOnDrain(src){return function(){var state=src._readableState;debug("pipeOnDrain",state.awaitDrain);if(state.awaitDrain)state.awaitDrain--;if(state.awaitDrain===0&&EElistenerCount(src,"data")){state.flowing=true;flow(src)}}}Readable.prototype.unpipe=function(dest){var state=this._readableState;if(state.pipesCount===0)return this;if(state.pipesCount===1){if(dest&&dest!==state.pipes)return this;if(!dest)dest=state.pipes;state.pipes=null;state.pipesCount=0;state.flowing=false;if(dest)dest.emit("unpipe",this);return this}if(!dest){var dests=state.pipes;var len=state.pipesCount;state.pipes=null;state.pipesCount=0;state.flowing=false;for(var _i=0;_i<len;_i++){dests[_i].emit("unpipe",this)}return this}var i=indexOf(state.pipes,dest);if(i===-1)return this;state.pipes.splice(i,1);state.pipesCount-=1;if(state.pipesCount===1)state.pipes=state.pipes[0];dest.emit("unpipe",this);return this};Readable.prototype.on=function(ev,fn){var res=Stream.prototype.on.call(this,ev,fn);if(ev==="data"){if(this._readableState.flowing!==false)this.resume()}else if(ev==="readable"){var state=this._readableState;if(!state.endEmitted&&!state.readableListening){state.readableListening=state.needReadable=true;state.emittedReadable=false;if(!state.reading){processNextTick(nReadingNextTick,this)}else if(state.length){emitReadable(this,state)}}}return res};Readable.prototype.addListener=Readable.prototype.on;function nReadingNextTick(self){debug("readable nexttick read 0");self.read(0)}Readable.prototype.resume=function(){var state=this._readableState;if(!state.flowing){debug("resume");state.flowing=true;resume(this,state)}return this};function resume(stream,state){if(!state.resumeScheduled){state.resumeScheduled=true;processNextTick(resume_,stream,state)}}function resume_(stream,state){if(!state.reading){debug("resume read 0");stream.read(0)}state.resumeScheduled=false;state.awaitDrain=0;stream.emit("resume");flow(stream);if(state.flowing&&!state.reading)stream.read(0)}Readable.prototype.pause=function(){debug("call pause flowing=%j",this._readableState.flowing);if(false!==this._readableState.flowing){debug("pause");this._readableState.flowing=false;this.emit("pause")}return this};function flow(stream){var state=stream._readableState;debug("flow",state.flowing);while(state.flowing&&stream.read()!==null){}}Readable.prototype.wrap=function(stream){var state=this._readableState;var paused=false;var self=this;stream.on("end",function(){debug("wrapped end");if(state.decoder&&!state.ended){var chunk=state.decoder.end();if(chunk&&chunk.length)self.push(chunk)}self.push(null)});stream.on("data",function(chunk){debug("wrapped data");if(state.decoder)chunk=state.decoder.write(chunk);if(state.objectMode&&(chunk===null||chunk===undefined))return;else if(!state.objectMode&&(!chunk||!chunk.length))return;var ret=self.push(chunk);if(!ret){paused=true;stream.pause()}});for(var i in stream){if(this[i]===undefined&&typeof stream[i]==="function"){this[i]=function(method){return function(){return stream[method].apply(stream,arguments)}}(i)}}var events=["error","close","destroy","pause","resume"];forEach(events,function(ev){stream.on(ev,self.emit.bind(self,ev))});self._read=function(n){debug("wrapped _read",n);if(paused){paused=false;stream.resume()}};return self};Readable._fromList=fromList;function fromList(n,state){if(state.length===0)return null;var ret;if(state.objectMode)ret=state.buffer.shift();else if(!n||n>=state.length){if(state.decoder)ret=state.buffer.join("");else if(state.buffer.length===1)ret=state.buffer.head.data;else ret=state.buffer.concat(state.length);state.buffer.clear()}else{ret=fromListPartial(n,state.buffer,state.decoder)}return ret}function fromListPartial(n,list,hasStrings){var ret;if(n<list.head.data.length){ret=list.head.data.slice(0,n);list.head.data=list.head.data.slice(n)}else if(n===list.head.data.length){ret=list.shift()}else{ret=hasStrings?copyFromBufferString(n,list):copyFromBuffer(n,list)}return ret}function copyFromBufferString(n,list){var p=list.head;var c=1;var ret=p.data;n-=ret.length;while(p=p.next){var str=p.data;var nb=n>str.length?str.length:n;if(nb===str.length)ret+=str;else ret+=str.slice(0,n);n-=nb;if(n===0){if(nb===str.length){++c;if(p.next)list.head=p.next;else list.head=list.tail=null}else{list.head=p;p.data=str.slice(nb)}break}++c}list.length-=c;return ret}function copyFromBuffer(n,list){var ret=bufferShim.allocUnsafe(n);var p=list.head;var c=1;p.data.copy(ret);n-=p.data.length;while(p=p.next){var buf=p.data;var nb=n>buf.length?buf.length:n;buf.copy(ret,ret.length-n,0,nb);n-=nb;if(n===0){if(nb===buf.length){++c;if(p.next)list.head=p.next;else list.head=list.tail=null}else{list.head=p;p.data=buf.slice(nb)}break}++c}list.length-=c;return ret}function endReadable(stream){var state=stream._readableState;if(state.length>0)throw new Error('"endReadable()" called on non-empty stream');if(!state.endEmitted){state.ended=true;processNextTick(endReadableNT,state,stream)}}function endReadableNT(state,stream){if(!state.endEmitted&&state.length===0){state.endEmitted=true;stream.readable=false;stream.emit("end")}}function forEach(xs,f){for(var i=0,l=xs.length;i<l;i++){f(xs[i],i)}}function indexOf(xs,x){for(var i=0,l=xs.length;i<l;i++){if(xs[i]===x)return i}return-1}}).call(this,require("_process"))},{"./_stream_duplex":44,"./internal/streams/BufferList":49,_process:42,buffer:5,"buffer-shims":4,"core-util-is":6,events:28,inherits:38,isarray:40,"process-nextick-args":41,"string_decoder/":56,util:3}],47:[function(require,module,exports){"use strict";module.exports=Transform;var Duplex=require("./_stream_duplex");var util=require("core-util-is");util.inherits=require("inherits");util.inherits(Transform,Duplex);function TransformState(stream){this.afterTransform=function(er,data){return afterTransform(stream,er,data)};this.needTransform=false;this.transforming=false;this.writecb=null;this.writechunk=null;this.writeencoding=null}function afterTransform(stream,er,data){var ts=stream._transformState;ts.transforming=false;var cb=ts.writecb;if(!cb)return stream.emit("error",new Error("no writecb in Transform class"));ts.writechunk=null;ts.writecb=null;if(data!==null&&data!==undefined)stream.push(data);cb(er);var rs=stream._readableState;rs.reading=false;if(rs.needReadable||rs.length<rs.highWaterMark){stream._read(rs.highWaterMark)}}function Transform(options){if(!(this instanceof Transform))return new Transform(options);Duplex.call(this,options);this._transformState=new TransformState(this);var stream=this;this._readableState.needReadable=true;this._readableState.sync=false;if(options){if(typeof options.transform==="function")this._transform=options.transform;if(typeof options.flush==="function")this._flush=options.flush}this.once("prefinish",function(){if(typeof this._flush==="function")this._flush(function(er){done(stream,er)});else done(stream)})}Transform.prototype.push=function(chunk,encoding){this._transformState.needTransform=false;return Duplex.prototype.push.call(this,chunk,encoding)};Transform.prototype._transform=function(chunk,encoding,cb){throw new Error("Not implemented")};Transform.prototype._write=function(chunk,encoding,cb){var ts=this._transformState;ts.writecb=cb;ts.writechunk=chunk;ts.writeencoding=encoding;if(!ts.transforming){var rs=this._readableState;if(ts.needTransform||rs.needReadable||rs.length<rs.highWaterMark)this._read(rs.highWaterMark)}};Transform.prototype._read=function(n){var ts=this._transformState;if(ts.writechunk!==null&&ts.writecb&&!ts.transforming){ts.transforming=true;this._transform(ts.writechunk,ts.writeencoding,ts.afterTransform)}else{ts.needTransform=true}};function done(stream,er){if(er)return stream.emit("error",er);var ws=stream._writableState;var ts=stream._transformState;if(ws.length)throw new Error("Calling transform done when ws.length != 0");if(ts.transforming)throw new Error("Calling transform done when still transforming");return stream.push(null)}},{"./_stream_duplex":44,"core-util-is":6,inherits:38}],48:[function(require,module,exports){(function(process){"use strict";module.exports=Writable;var processNextTick=require("process-nextick-args");var asyncWrite=!process.browser&&["v0.10","v0.9."].indexOf(process.version.slice(0,5))>-1?setImmediate:processNextTick;Writable.WritableState=WritableState;var util=require("core-util-is");util.inherits=require("inherits");var internalUtil={deprecate:require("util-deprecate")};var Stream;(function(){try{Stream=require("st"+"ream")}catch(_){}finally{if(!Stream)Stream=require("events").EventEmitter}})();var Buffer=require("buffer").Buffer;var bufferShim=require("buffer-shims");util.inherits(Writable,Stream);function nop(){}function WriteReq(chunk,encoding,cb){this.chunk=chunk;this.encoding=encoding;this.callback=cb;this.next=null}var Duplex;function WritableState(options,stream){Duplex=Duplex||require("./_stream_duplex");options=options||{};this.objectMode=!!options.objectMode;if(stream instanceof Duplex)this.objectMode=this.objectMode||!!options.writableObjectMode;var hwm=options.highWaterMark;var defaultHwm=this.objectMode?16:16*1024;this.highWaterMark=hwm||hwm===0?hwm:defaultHwm;this.highWaterMark=~~this.highWaterMark;this.needDrain=false;this.ending=false;this.ended=false;this.finished=false;var noDecode=options.decodeStrings===false;this.decodeStrings=!noDecode;this.defaultEncoding=options.defaultEncoding||"utf8";this.length=0;this.writing=false;this.corked=0;this.sync=true;this.bufferProcessing=false;this.onwrite=function(er){onwrite(stream,er)};this.writecb=null;this.writelen=0;this.bufferedRequest=null;this.lastBufferedRequest=null;this.pendingcb=0;this.prefinished=false;this.errorEmitted=false;this.bufferedRequestCount=0;this.corkedRequestsFree=new CorkedRequest(this)}WritableState.prototype.getBuffer=function writableStateGetBuffer(){var current=this.bufferedRequest;var out=[];while(current){out.push(current);current=current.next}return out};(function(){try{Object.defineProperty(WritableState.prototype,"buffer",{get:internalUtil.deprecate(function(){return this.getBuffer()},"_writableState.buffer is deprecated. Use _writableState.getBuffer "+"instead.")})}catch(_){}})();var Duplex;function Writable(options){Duplex=Duplex||require("./_stream_duplex");if(!(this instanceof Writable)&&!(this instanceof Duplex))return new Writable(options);this._writableState=new WritableState(options,this);this.writable=true;if(options){if(typeof options.write==="function")this._write=options.write;if(typeof options.writev==="function")this._writev=options.writev}Stream.call(this)}Writable.prototype.pipe=function(){this.emit("error",new Error("Cannot pipe, not readable"))};function writeAfterEnd(stream,cb){var er=new Error("write after end");stream.emit("error",er);processNextTick(cb,er)}function validChunk(stream,state,chunk,cb){var valid=true;var er=false;if(chunk===null){er=new TypeError("May not write null values to stream")}else if(!Buffer.isBuffer(chunk)&&typeof chunk!=="string"&&chunk!==undefined&&!state.objectMode){er=new TypeError("Invalid non-string/buffer chunk")}if(er){stream.emit("error",er);processNextTick(cb,er);valid=false}return valid}Writable.prototype.write=function(chunk,encoding,cb){var state=this._writableState;var ret=false;if(typeof encoding==="function"){cb=encoding;encoding=null}if(Buffer.isBuffer(chunk))encoding="buffer";else if(!encoding)encoding=state.defaultEncoding;if(typeof cb!=="function")cb=nop;if(state.ended)writeAfterEnd(this,cb);else if(validChunk(this,state,chunk,cb)){
-state.pendingcb++;ret=writeOrBuffer(this,state,chunk,encoding,cb)}return ret};Writable.prototype.cork=function(){var state=this._writableState;state.corked++};Writable.prototype.uncork=function(){var state=this._writableState;if(state.corked){state.corked--;if(!state.writing&&!state.corked&&!state.finished&&!state.bufferProcessing&&state.bufferedRequest)clearBuffer(this,state)}};Writable.prototype.setDefaultEncoding=function setDefaultEncoding(encoding){if(typeof encoding==="string")encoding=encoding.toLowerCase();if(!(["hex","utf8","utf-8","ascii","binary","base64","ucs2","ucs-2","utf16le","utf-16le","raw"].indexOf((encoding+"").toLowerCase())>-1))throw new TypeError("Unknown encoding: "+encoding);this._writableState.defaultEncoding=encoding;return this};function decodeChunk(state,chunk,encoding){if(!state.objectMode&&state.decodeStrings!==false&&typeof chunk==="string"){chunk=bufferShim.from(chunk,encoding)}return chunk}function writeOrBuffer(stream,state,chunk,encoding,cb){chunk=decodeChunk(state,chunk,encoding);if(Buffer.isBuffer(chunk))encoding="buffer";var len=state.objectMode?1:chunk.length;state.length+=len;var ret=state.length<state.highWaterMark;if(!ret)state.needDrain=true;if(state.writing||state.corked){var last=state.lastBufferedRequest;state.lastBufferedRequest=new WriteReq(chunk,encoding,cb);if(last){last.next=state.lastBufferedRequest}else{state.bufferedRequest=state.lastBufferedRequest}state.bufferedRequestCount+=1}else{doWrite(stream,state,false,len,chunk,encoding,cb)}return ret}function doWrite(stream,state,writev,len,chunk,encoding,cb){state.writelen=len;state.writecb=cb;state.writing=true;state.sync=true;if(writev)stream._writev(chunk,state.onwrite);else stream._write(chunk,encoding,state.onwrite);state.sync=false}function onwriteError(stream,state,sync,er,cb){--state.pendingcb;if(sync)processNextTick(cb,er);else cb(er);stream._writableState.errorEmitted=true;stream.emit("error",er)}function onwriteStateUpdate(state){state.writing=false;state.writecb=null;state.length-=state.writelen;state.writelen=0}function onwrite(stream,er){var state=stream._writableState;var sync=state.sync;var cb=state.writecb;onwriteStateUpdate(state);if(er)onwriteError(stream,state,sync,er,cb);else{var finished=needFinish(state);if(!finished&&!state.corked&&!state.bufferProcessing&&state.bufferedRequest){clearBuffer(stream,state)}if(sync){asyncWrite(afterWrite,stream,state,finished,cb)}else{afterWrite(stream,state,finished,cb)}}}function afterWrite(stream,state,finished,cb){if(!finished)onwriteDrain(stream,state);state.pendingcb--;cb();finishMaybe(stream,state)}function onwriteDrain(stream,state){if(state.length===0&&state.needDrain){state.needDrain=false;stream.emit("drain")}}function clearBuffer(stream,state){state.bufferProcessing=true;var entry=state.bufferedRequest;if(stream._writev&&entry&&entry.next){var l=state.bufferedRequestCount;var buffer=new Array(l);var holder=state.corkedRequestsFree;holder.entry=entry;var count=0;while(entry){buffer[count]=entry;entry=entry.next;count+=1}doWrite(stream,state,true,state.length,buffer,"",holder.finish);state.pendingcb++;state.lastBufferedRequest=null;if(holder.next){state.corkedRequestsFree=holder.next;holder.next=null}else{state.corkedRequestsFree=new CorkedRequest(state)}}else{while(entry){var chunk=entry.chunk;var encoding=entry.encoding;var cb=entry.callback;var len=state.objectMode?1:chunk.length;doWrite(stream,state,false,len,chunk,encoding,cb);entry=entry.next;if(state.writing){break}}if(entry===null)state.lastBufferedRequest=null}state.bufferedRequestCount=0;state.bufferedRequest=entry;state.bufferProcessing=false}Writable.prototype._write=function(chunk,encoding,cb){cb(new Error("not implemented"))};Writable.prototype._writev=null;Writable.prototype.end=function(chunk,encoding,cb){var state=this._writableState;if(typeof chunk==="function"){cb=chunk;chunk=null;encoding=null}else if(typeof encoding==="function"){cb=encoding;encoding=null}if(chunk!==null&&chunk!==undefined)this.write(chunk,encoding);if(state.corked){state.corked=1;this.uncork()}if(!state.ending&&!state.finished)endWritable(this,state,cb)};function needFinish(state){return state.ending&&state.length===0&&state.bufferedRequest===null&&!state.finished&&!state.writing}function prefinish(stream,state){if(!state.prefinished){state.prefinished=true;stream.emit("prefinish")}}function finishMaybe(stream,state){var need=needFinish(state);if(need){if(state.pendingcb===0){prefinish(stream,state);state.finished=true;stream.emit("finish")}else{prefinish(stream,state)}}return need}function endWritable(stream,state,cb){state.ending=true;finishMaybe(stream,state);if(cb){if(state.finished)processNextTick(cb);else stream.once("finish",cb)}state.ended=true;stream.writable=false}function CorkedRequest(state){var _this=this;this.next=null;this.entry=null;this.finish=function(err){var entry=_this.entry;_this.entry=null;while(entry){var cb=entry.callback;state.pendingcb--;cb(err);entry=entry.next}if(state.corkedRequestsFree){state.corkedRequestsFree.next=_this}else{state.corkedRequestsFree=_this}}}}).call(this,require("_process"))},{"./_stream_duplex":44,_process:42,buffer:5,"buffer-shims":4,"core-util-is":6,events:28,inherits:38,"process-nextick-args":41,"util-deprecate":57}],49:[function(require,module,exports){"use strict";var Buffer=require("buffer").Buffer;var bufferShim=require("buffer-shims");module.exports=BufferList;function BufferList(){this.head=null;this.tail=null;this.length=0}BufferList.prototype.push=function(v){var entry={data:v,next:null};if(this.length>0)this.tail.next=entry;else this.head=entry;this.tail=entry;++this.length};BufferList.prototype.unshift=function(v){var entry={data:v,next:this.head};if(this.length===0)this.tail=entry;this.head=entry;++this.length};BufferList.prototype.shift=function(){if(this.length===0)return;var ret=this.head.data;if(this.length===1)this.head=this.tail=null;else this.head=this.head.next;--this.length;return ret};BufferList.prototype.clear=function(){this.head=this.tail=null;this.length=0};BufferList.prototype.join=function(s){if(this.length===0)return"";var p=this.head;var ret=""+p.data;while(p=p.next){ret+=s+p.data}return ret};BufferList.prototype.concat=function(n){if(this.length===0)return bufferShim.alloc(0);if(this.length===1)return this.head.data;var ret=bufferShim.allocUnsafe(n>>>0);var p=this.head;var i=0;while(p){p.data.copy(ret,i);i+=p.data.length;p=p.next}return ret}},{buffer:5,"buffer-shims":4}],50:[function(require,module,exports){module.exports=require("./lib/_stream_passthrough.js")},{"./lib/_stream_passthrough.js":45}],51:[function(require,module,exports){(function(process){var Stream=function(){try{return require("st"+"ream")}catch(_){}}();exports=module.exports=require("./lib/_stream_readable.js");exports.Stream=Stream||exports;exports.Readable=exports;exports.Writable=require("./lib/_stream_writable.js");exports.Duplex=require("./lib/_stream_duplex.js");exports.Transform=require("./lib/_stream_transform.js");exports.PassThrough=require("./lib/_stream_passthrough.js");if(!process.browser&&process.env.READABLE_STREAM==="disable"&&Stream){module.exports=Stream}}).call(this,require("_process"))},{"./lib/_stream_duplex.js":44,"./lib/_stream_passthrough.js":45,"./lib/_stream_readable.js":46,"./lib/_stream_transform.js":47,"./lib/_stream_writable.js":48,_process:42}],52:[function(require,module,exports){module.exports=require("./lib/_stream_transform.js")},{"./lib/_stream_transform.js":47}],53:[function(require,module,exports){module.exports=require("./lib/_stream_writable.js")},{"./lib/_stream_writable.js":48}],54:[function(require,module,exports){module.exports=function(string){return string.replace(/[-\\^$*+?.()|[\]{}]/g,"\\$&")}},{}],55:[function(require,module,exports){module.exports=Stream;var EE=require("events").EventEmitter;var inherits=require("inherits");inherits(Stream,EE);Stream.Readable=require("readable-stream/readable.js");Stream.Writable=require("readable-stream/writable.js");Stream.Duplex=require("readable-stream/duplex.js");Stream.Transform=require("readable-stream/transform.js");Stream.PassThrough=require("readable-stream/passthrough.js");Stream.Stream=Stream;function Stream(){EE.call(this)}Stream.prototype.pipe=function(dest,options){var source=this;function ondata(chunk){if(dest.writable){if(false===dest.write(chunk)&&source.pause){source.pause()}}}source.on("data",ondata);function ondrain(){if(source.readable&&source.resume){source.resume()}}dest.on("drain",ondrain);if(!dest._isStdio&&(!options||options.end!==false)){source.on("end",onend);source.on("close",onclose)}var didOnEnd=false;function onend(){if(didOnEnd)return;didOnEnd=true;dest.end()}function onclose(){if(didOnEnd)return;didOnEnd=true;if(typeof dest.destroy==="function")dest.destroy()}function onerror(er){cleanup();if(EE.listenerCount(this,"error")===0){throw er}}source.on("error",onerror);dest.on("error",onerror);function cleanup(){source.removeListener("data",ondata);dest.removeListener("drain",ondrain);source.removeListener("end",onend);source.removeListener("close",onclose);source.removeListener("error",onerror);dest.removeListener("error",onerror);source.removeListener("end",cleanup);source.removeListener("close",cleanup);dest.removeListener("close",cleanup)}source.on("end",cleanup);source.on("close",cleanup);dest.on("close",cleanup);dest.emit("pipe",source);return dest}},{events:28,inherits:38,"readable-stream/duplex.js":43,"readable-stream/passthrough.js":50,"readable-stream/readable.js":51,"readable-stream/transform.js":52,"readable-stream/writable.js":53}],56:[function(require,module,exports){var Buffer=require("buffer").Buffer;var isBufferEncoding=Buffer.isEncoding||function(encoding){switch(encoding&&encoding.toLowerCase()){case"hex":case"utf8":case"utf-8":case"ascii":case"binary":case"base64":case"ucs2":case"ucs-2":case"utf16le":case"utf-16le":case"raw":return true;default:return false}};function assertEncoding(encoding){if(encoding&&!isBufferEncoding(encoding)){throw new Error("Unknown encoding: "+encoding)}}var StringDecoder=exports.StringDecoder=function(encoding){this.encoding=(encoding||"utf8").toLowerCase().replace(/[-_]/,"");assertEncoding(encoding);switch(this.encoding){case"utf8":this.surrogateSize=3;break;case"ucs2":case"utf16le":this.surrogateSize=2;this.detectIncompleteChar=utf16DetectIncompleteChar;break;case"base64":this.surrogateSize=3;this.detectIncompleteChar=base64DetectIncompleteChar;break;default:this.write=passThroughWrite;return}this.charBuffer=new Buffer(6);this.charReceived=0;this.charLength=0};StringDecoder.prototype.write=function(buffer){var charStr="";while(this.charLength){var available=buffer.length>=this.charLength-this.charReceived?this.charLength-this.charReceived:buffer.length;buffer.copy(this.charBuffer,this.charReceived,0,available);this.charReceived+=available;if(this.charReceived<this.charLength){return""}buffer=buffer.slice(available,buffer.length);charStr=this.charBuffer.slice(0,this.charLength).toString(this.encoding);var charCode=charStr.charCodeAt(charStr.length-1);if(charCode>=55296&&charCode<=56319){this.charLength+=this.surrogateSize;charStr="";continue}this.charReceived=this.charLength=0;if(buffer.length===0){return charStr}break}this.detectIncompleteChar(buffer);var end=buffer.length;if(this.charLength){buffer.copy(this.charBuffer,0,buffer.length-this.charReceived,end);end-=this.charReceived}charStr+=buffer.toString(this.encoding,0,end);var end=charStr.length-1;var charCode=charStr.charCodeAt(end);if(charCode>=55296&&charCode<=56319){var size=this.surrogateSize;this.charLength+=size;this.charReceived+=size;this.charBuffer.copy(this.charBuffer,size,0,size);buffer.copy(this.charBuffer,0,0,size);return charStr.substring(0,end)}return charStr};StringDecoder.prototype.detectIncompleteChar=function(buffer){var i=buffer.length>=3?3:buffer.length;for(;i>0;i--){var c=buffer[buffer.length-i];if(i==1&&c>>5==6){this.charLength=2;break}if(i<=2&&c>>4==14){this.charLength=3;break}if(i<=3&&c>>3==30){this.charLength=4;break}}this.charReceived=i};StringDecoder.prototype.end=function(buffer){var res="";if(buffer&&buffer.length)res=this.write(buffer);if(this.charReceived){var cr=this.charReceived;var buf=this.charBuffer;var enc=this.encoding;res+=buf.slice(0,cr).toString(enc)}return res};function passThroughWrite(buffer){return buffer.toString(this.encoding)}function utf16DetectIncompleteChar(buffer){this.charReceived=buffer.length%2;this.charLength=this.charReceived?2:0}function base64DetectIncompleteChar(buffer){this.charReceived=buffer.length%3;this.charLength=this.charReceived?3:0}},{buffer:5}],57:[function(require,module,exports){(function(global){module.exports=deprecate;function deprecate(fn,msg){if(config("noDeprecation")){return fn}var warned=false;function deprecated(){if(!warned){if(config("throwDeprecation")){throw new Error(msg)}else if(config("traceDeprecation")){console.trace(msg)}else{console.warn(msg)}warned=true}return fn.apply(this,arguments)}return deprecated}function config(name){try{if(!global.localStorage)return false}catch(_){return false}var val=global.localStorage[name];if(null==val)return false;return String(val).toLowerCase()==="true"}}).call(this,typeof global!=="undefined"?global:typeof self!=="undefined"?self:typeof window!=="undefined"?window:{})},{}],58:[function(require,module,exports){module.exports=extend;var hasOwnProperty=Object.prototype.hasOwnProperty;function extend(){var target={};for(var i=0;i<arguments.length;i++){var source=arguments[i];for(var key in source){if(hasOwnProperty.call(source,key)){target[key]=source[key]}}}return target}},{}]},{},[1])(1)});
+(function(f){if(typeof exports==="object"&&typeof module!=="undefined"){module.exports=f()}else if(typeof define==="function"&&define.amd){define([],f)}else{var g;if(typeof window!=="undefined"){g=window}else if(typeof global!=="undefined"){g=global}else if(typeof self!=="undefined"){g=self}else{g=this}g.sanitizeHtml=f()}})(function(){var define,module,exports;return function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s}({1:[function(require,module,exports){var htmlparser=require("htmlparser2");var extend=require("xtend");var quoteRegexp=require("regexp-quote");function each(obj,cb){if(obj)Object.keys(obj).forEach(function(key){cb(obj[key],key)})}function has(obj,key){return{}.hasOwnProperty.call(obj,key)}module.exports=sanitizeHtml;function sanitizeHtml(html,options,_recursing){var result="";function Frame(tag,attribs){var that=this;this.tag=tag;this.attribs=attribs||{};this.tagPosition=result.length;this.text="";this.updateParentNodeText=function(){if(stack.length){var parentFrame=stack[stack.length-1];parentFrame.text+=that.text}}}if(!options){options=sanitizeHtml.defaults;options.parser=htmlParserDefaults}else{options=extend(sanitizeHtml.defaults,options);if(options.parser){options.parser=extend(htmlParserDefaults,options.parser)}else{options.parser=htmlParserDefaults}}var nonTextTagsArray=options.nonTextTags||["script","style","textarea"];var allowedAttributesMap;var allowedAttributesGlobMap;if(options.allowedAttributes){allowedAttributesMap={};allowedAttributesGlobMap={};each(options.allowedAttributes,function(attributes,tag){allowedAttributesMap[tag]=[];var globRegex=[];attributes.forEach(function(name){if(name.indexOf("*")>=0){globRegex.push(quoteRegexp(name).replace(/\\\*/g,".*"))}else{allowedAttributesMap[tag].push(name)}});allowedAttributesGlobMap[tag]=new RegExp("^("+globRegex.join("|")+")$")})}var allowedClassesMap={};each(options.allowedClasses,function(classes,tag){if(allowedAttributesMap){if(!has(allowedAttributesMap,tag)){allowedAttributesMap[tag]=[]}allowedAttributesMap[tag].push("class")}allowedClassesMap[tag]=classes});var transformTagsMap={};var transformTagsAll;each(options.transformTags,function(transform,tag){var transFun;if(typeof transform==="function"){transFun=transform}else if(typeof transform==="string"){transFun=sanitizeHtml.simpleTransform(transform)}if(tag==="*"){transformTagsAll=transFun}else{transformTagsMap[tag]=transFun}});var depth=0;var stack=[];var skipMap={};var transformMap={};var skipText=false;var skipTextDepth=0;var parser=new htmlparser.Parser({onopentag:function(name,attribs){if(skipText){skipTextDepth++;return}var frame=new Frame(name,attribs);stack.push(frame);var skip=false;var hasText=frame.text?true:false;var transformedTag;if(has(transformTagsMap,name)){transformedTag=transformTagsMap[name](name,attribs);frame.attribs=attribs=transformedTag.attribs;if(transformedTag.text!==undefined){frame.innerText=transformedTag.text}if(name!==transformedTag.tagName){frame.name=name=transformedTag.tagName;transformMap[depth]=transformedTag.tagName}}if(transformTagsAll){transformedTag=transformTagsAll(name,attribs);frame.attribs=attribs=transformedTag.attribs;if(name!==transformedTag.tagName){frame.name=name=transformedTag.tagName;transformMap[depth]=transformedTag.tagName}}if(options.allowedTags&&options.allowedTags.indexOf(name)===-1){skip=true;if(nonTextTagsArray.indexOf(name)!==-1){skipText=true;skipTextDepth=1}skipMap[depth]=true}depth++;if(skip){return}result+="<"+name;if(!allowedAttributesMap||has(allowedAttributesMap,name)||allowedAttributesMap["*"]){each(attribs,function(value,a){if(!allowedAttributesMap||has(allowedAttributesMap,name)&&allowedAttributesMap[name].indexOf(a)!==-1||allowedAttributesMap["*"]&&allowedAttributesMap["*"].indexOf(a)!==-1||has(allowedAttributesGlobMap,name)&&allowedAttributesGlobMap[name].test(a)||allowedAttributesGlobMap["*"]&&allowedAttributesGlobMap["*"].test(a)){if(a==="href"||a==="src"){if(naughtyHref(name,value)){delete frame.attribs[a];return}}if(a==="class"){value=filterClasses(value,allowedClassesMap[name]);if(!value.length){delete frame.attribs[a];return}}result+=" "+a;if(value.length){result+='="'+escapeHtml(value)+'"'}}else{delete frame.attribs[a]}})}if(options.selfClosing.indexOf(name)!==-1){result+=" />"}else{result+=">";if(frame.innerText&&!hasText&&!options.textFilter){result+=frame.innerText}}},ontext:function(text){if(skipText){return}var lastFrame=stack[stack.length-1];var tag;if(lastFrame){tag=lastFrame.tag;text=lastFrame.innerText!==undefined?lastFrame.innerText:text}if(tag==="script"||tag==="style"){result+=text}else{var escaped=escapeHtml(text);if(options.textFilter){result+=options.textFilter(escaped)}else{result+=escaped}}if(stack.length){var frame=stack[stack.length-1];frame.text+=text}},onclosetag:function(name){if(skipText){skipTextDepth--;if(!skipTextDepth){skipText=false}else{return}}var frame=stack.pop();if(!frame){return}skipText=false;depth--;if(skipMap[depth]){delete skipMap[depth];frame.updateParentNodeText();return}if(transformMap[depth]){name=transformMap[depth];delete transformMap[depth]}if(options.exclusiveFilter&&options.exclusiveFilter(frame)){result=result.substr(0,frame.tagPosition);return}frame.updateParentNodeText();if(options.selfClosing.indexOf(name)!==-1){return}result+="</"+name+">"}},options.parser);parser.write(html);parser.end();return result;function escapeHtml(s){if(typeof s!=="string"){s=s+""}return s.replace(/\&/g,"&amp;").replace(/</g,"&lt;").replace(/\>/g,"&gt;").replace(/\"/g,"&quot;")}function naughtyHref(name,href){href=href.replace(/[\x00-\x20]+/g,"");href=href.replace(/<\!\-\-.*?\-\-\>/g,"");var matches=href.match(/^([a-zA-Z]+)\:/);if(!matches){return false}var scheme=matches[1].toLowerCase();if(has(options.allowedSchemesByTag,name)){return options.allowedSchemesByTag[name].indexOf(scheme)===-1}return!options.allowedSchemes||options.allowedSchemes.indexOf(scheme)===-1}function filterClasses(classes,allowed){if(!allowed){return classes}classes=classes.split(/\s+/);return classes.filter(function(clss){return allowed.indexOf(clss)!==-1}).join(" ")}}var htmlParserDefaults={decodeEntities:true};sanitizeHtml.defaults={allowedTags:["h3","h4","h5","h6","blockquote","p","a","ul","ol","nl","li","b","i","strong","em","strike","code","hr","br","div","table","thead","caption","tbody","tr","th","td","pre"],allowedAttributes:{a:["href","name","target"],img:["src"]},selfClosing:["img","br","hr","area","base","basefont","input","link","meta"],allowedSchemes:["http","https","ftp","mailto"],allowedSchemesByTag:{}};sanitizeHtml.simpleTransform=function(newTagName,newAttribs,merge){merge=merge===undefined?true:merge;newAttribs=newAttribs||{};return function(tagName,attribs){var attrib;if(merge){for(attrib in newAttribs){attribs[attrib]=newAttribs[attrib]}}else{attribs=newAttribs}return{tagName:newTagName,attribs:attribs}}}},{htmlparser2:36,"regexp-quote":54,xtend:58}],2:[function(require,module,exports){"use strict";exports.toByteArray=toByteArray;exports.fromByteArray=fromByteArray;var lookup=[];var revLookup=[];var Arr=typeof Uint8Array!=="undefined"?Uint8Array:Array;function init(){var code="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";for(var i=0,len=code.length;i<len;++i){lookup[i]=code[i];revLookup[code.charCodeAt(i)]=i}revLookup["-".charCodeAt(0)]=62;revLookup["_".charCodeAt(0)]=63}init();function toByteArray(b64){var i,j,l,tmp,placeHolders,arr;var len=b64.length;if(len%4>0){throw new Error("Invalid string. Length must be a multiple of 4")}placeHolders=b64[len-2]==="="?2:b64[len-1]==="="?1:0;arr=new Arr(len*3/4-placeHolders);l=placeHolders>0?len-4:len;var L=0;for(i=0,j=0;i<l;i+=4,j+=3){tmp=revLookup[b64.charCodeAt(i)]<<18|revLookup[b64.charCodeAt(i+1)]<<12|revLookup[b64.charCodeAt(i+2)]<<6|revLookup[b64.charCodeAt(i+3)];arr[L++]=tmp>>16&255;arr[L++]=tmp>>8&255;arr[L++]=tmp&255}if(placeHolders===2){tmp=revLookup[b64.charCodeAt(i)]<<2|revLookup[b64.charCodeAt(i+1)]>>4;arr[L++]=tmp&255}else if(placeHolders===1){tmp=revLookup[b64.charCodeAt(i)]<<10|revLookup[b64.charCodeAt(i+1)]<<4|revLookup[b64.charCodeAt(i+2)]>>2;arr[L++]=tmp>>8&255;arr[L++]=tmp&255}return arr}function tripletToBase64(num){return lookup[num>>18&63]+lookup[num>>12&63]+lookup[num>>6&63]+lookup[num&63]}function encodeChunk(uint8,start,end){var tmp;var output=[];for(var i=start;i<end;i+=3){tmp=(uint8[i]<<16)+(uint8[i+1]<<8)+uint8[i+2];output.push(tripletToBase64(tmp))}return output.join("")}function fromByteArray(uint8){var tmp;var len=uint8.length;var extraBytes=len%3;var output="";var parts=[];var maxChunkLength=16383;for(var i=0,len2=len-extraBytes;i<len2;i+=maxChunkLength){parts.push(encodeChunk(uint8,i,i+maxChunkLength>len2?len2:i+maxChunkLength))}if(extraBytes===1){tmp=uint8[len-1];output+=lookup[tmp>>2];output+=lookup[tmp<<4&63];output+="=="}else if(extraBytes===2){tmp=(uint8[len-2]<<8)+uint8[len-1];output+=lookup[tmp>>10];output+=lookup[tmp>>4&63];output+=lookup[tmp<<2&63];output+="="}parts.push(output);return parts.join("")}},{}],3:[function(require,module,exports){},{}],4:[function(require,module,exports){(function(global){"use strict";var buffer=require("buffer");var Buffer=buffer.Buffer;var SlowBuffer=buffer.SlowBuffer;var MAX_LEN=buffer.kMaxLength||2147483647;exports.alloc=function alloc(size,fill,encoding){if(typeof Buffer.alloc==="function"){return Buffer.alloc(size,fill,encoding)}if(typeof encoding==="number"){throw new TypeError("encoding must not be number")}if(typeof size!=="number"){throw new TypeError("size must be a number")}if(size>MAX_LEN){throw new RangeError("size is too large")}var enc=encoding;var _fill=fill;if(_fill===undefined){enc=undefined;_fill=0}var buf=new Buffer(size);if(typeof _fill==="string"){var fillBuf=new Buffer(_fill,enc);var flen=fillBuf.length;var i=-1;while(++i<size){buf[i]=fillBuf[i%flen]}}else{buf.fill(_fill)}return buf};exports.allocUnsafe=function allocUnsafe(size){if(typeof Buffer.allocUnsafe==="function"){return Buffer.allocUnsafe(size)}if(typeof size!=="number"){throw new TypeError("size must be a number")}if(size>MAX_LEN){throw new RangeError("size is too large")}return new Buffer(size)};exports.from=function from(value,encodingOrOffset,length){if(typeof Buffer.from==="function"&&(!global.Uint8Array||Uint8Array.from!==Buffer.from)){return Buffer.from(value,encodingOrOffset,length)}if(typeof value==="number"){throw new TypeError('"value" argument must not be a number')}if(typeof value==="string"){return new Buffer(value,encodingOrOffset)}if(typeof ArrayBuffer!=="undefined"&&value instanceof ArrayBuffer){var offset=encodingOrOffset;if(arguments.length===1){return new Buffer(value)}if(typeof offset==="undefined"){offset=0}var len=length;if(typeof len==="undefined"){len=value.byteLength-offset}if(offset>=value.byteLength){throw new RangeError("'offset' is out of bounds")}if(len>value.byteLength-offset){throw new RangeError("'length' is out of bounds")}return new Buffer(value.slice(offset,offset+len))}if(Buffer.isBuffer(value)){var out=new Buffer(value.length);value.copy(out,0,0,value.length);return out}if(value){if(Array.isArray(value)||typeof ArrayBuffer!=="undefined"&&value.buffer instanceof ArrayBuffer||"length"in value){return new Buffer(value)}if(value.type==="Buffer"&&Array.isArray(value.data)){return new Buffer(value.data)}}throw new TypeError("First argument must be a string, Buffer, "+"ArrayBuffer, Array, or array-like object.")};exports.allocUnsafeSlow=function allocUnsafeSlow(size){if(typeof Buffer.allocUnsafeSlow==="function"){return Buffer.allocUnsafeSlow(size)}if(typeof size!=="number"){throw new TypeError("size must be a number")}if(size>=MAX_LEN){throw new RangeError("size is too large")}return new SlowBuffer(size)}}).call(this,typeof global!=="undefined"?global:typeof self!=="undefined"?self:typeof window!=="undefined"?window:{})},{buffer:5}],5:[function(require,module,exports){(function(global){"use strict";var base64=require("base64-js");var ieee754=require("ieee754");var isArray=require("isarray");exports.Buffer=Buffer;exports.SlowBuffer=SlowBuffer;exports.INSPECT_MAX_BYTES=50;Buffer.TYPED_ARRAY_SUPPORT=global.TYPED_ARRAY_SUPPORT!==undefined?global.TYPED_ARRAY_SUPPORT:typedArraySupport();exports.kMaxLength=kMaxLength();function typedArraySupport(){try{var arr=new Uint8Array(1);arr.__proto__={__proto__:Uint8Array.prototype,foo:function(){return 42}};return arr.foo()===42&&typeof arr.subarray==="function"&&arr.subarray(1,1).byteLength===0}catch(e){return false}}function kMaxLength(){return Buffer.TYPED_ARRAY_SUPPORT?2147483647:1073741823}function createBuffer(that,length){if(kMaxLength()<length){throw new RangeError("Invalid typed array length")}if(Buffer.TYPED_ARRAY_SUPPORT){that=new Uint8Array(length);that.__proto__=Buffer.prototype}else{if(that===null){that=new Buffer(length)}that.length=length}return that}function Buffer(arg,encodingOrOffset,length){if(!Buffer.TYPED_ARRAY_SUPPORT&&!(this instanceof Buffer)){return new Buffer(arg,encodingOrOffset,length)}if(typeof arg==="number"){if(typeof encodingOrOffset==="string"){throw new Error("If encoding is specified then the first argument must be a string")}return allocUnsafe(this,arg)}return from(this,arg,encodingOrOffset,length)}Buffer.poolSize=8192;Buffer._augment=function(arr){arr.__proto__=Buffer.prototype;return arr};function from(that,value,encodingOrOffset,length){if(typeof value==="number"){throw new TypeError('"value" argument must not be a number')}if(typeof ArrayBuffer!=="undefined"&&value instanceof ArrayBuffer){return fromArrayBuffer(that,value,encodingOrOffset,length)}if(typeof value==="string"){return fromString(that,value,encodingOrOffset)}return fromObject(that,value)}Buffer.from=function(value,encodingOrOffset,length){return from(null,value,encodingOrOffset,length)};if(Buffer.TYPED_ARRAY_SUPPORT){Buffer.prototype.__proto__=Uint8Array.prototype;Buffer.__proto__=Uint8Array;if(typeof Symbol!=="undefined"&&Symbol.species&&Buffer[Symbol.species]===Buffer){Object.defineProperty(Buffer,Symbol.species,{value:null,configurable:true})}}function assertSize(size){if(typeof size!=="number"){throw new TypeError('"size" argument must be a number')}else if(size<0){throw new RangeError('"size" argument must not be negative')}}function alloc(that,size,fill,encoding){assertSize(size);if(size<=0){return createBuffer(that,size)}if(fill!==undefined){return typeof encoding==="string"?createBuffer(that,size).fill(fill,encoding):createBuffer(that,size).fill(fill)}return createBuffer(that,size)}Buffer.alloc=function(size,fill,encoding){return alloc(null,size,fill,encoding)};function allocUnsafe(that,size){assertSize(size);that=createBuffer(that,size<0?0:checked(size)|0);if(!Buffer.TYPED_ARRAY_SUPPORT){for(var i=0;i<size;++i){that[i]=0}}return that}Buffer.allocUnsafe=function(size){return allocUnsafe(null,size)};Buffer.allocUnsafeSlow=function(size){return allocUnsafe(null,size)};function fromString(that,string,encoding){if(typeof encoding!=="string"||encoding===""){encoding="utf8"}if(!Buffer.isEncoding(encoding)){throw new TypeError('"encoding" must be a valid string encoding')}var length=byteLength(string,encoding)|0;that=createBuffer(that,length);var actual=that.write(string,encoding);if(actual!==length){that=that.slice(0,actual)}return that}function fromArrayLike(that,array){var length=array.length<0?0:checked(array.length)|0;that=createBuffer(that,length);for(var i=0;i<length;i+=1){that[i]=array[i]&255}return that}function fromArrayBuffer(that,array,byteOffset,length){array.byteLength;if(byteOffset<0||array.byteLength<byteOffset){throw new RangeError("'offset' is out of bounds")}if(array.byteLength<byteOffset+(length||0)){throw new RangeError("'length' is out of bounds")}if(byteOffset===undefined&&length===undefined){array=new Uint8Array(array)}else if(length===undefined){array=new Uint8Array(array,byteOffset)}else{array=new Uint8Array(array,byteOffset,length)}if(Buffer.TYPED_ARRAY_SUPPORT){that=array;that.__proto__=Buffer.prototype}else{that=fromArrayLike(that,array)}return that}function fromObject(that,obj){if(Buffer.isBuffer(obj)){var len=checked(obj.length)|0;that=createBuffer(that,len);if(that.length===0){return that}obj.copy(that,0,0,len);return that}if(obj){if(typeof ArrayBuffer!=="undefined"&&obj.buffer instanceof ArrayBuffer||"length"in obj){if(typeof obj.length!=="number"||isnan(obj.length)){return createBuffer(that,0)}return fromArrayLike(that,obj)}if(obj.type==="Buffer"&&isArray(obj.data)){return fromArrayLike(that,obj.data)}}throw new TypeError("First argument must be a string, Buffer, ArrayBuffer, Array, or array-like object.")}function checked(length){if(length>=kMaxLength()){throw new RangeError("Attempt to allocate Buffer larger than maximum "+"size: 0x"+kMaxLength().toString(16)+" bytes")}return length|0}function SlowBuffer(length){if(+length!=length){length=0}return Buffer.alloc(+length)}Buffer.isBuffer=function isBuffer(b){return!!(b!=null&&b._isBuffer)};Buffer.compare=function compare(a,b){if(!Buffer.isBuffer(a)||!Buffer.isBuffer(b)){throw new TypeError("Arguments must be Buffers")}if(a===b)return 0;var x=a.length;var y=b.length;for(var i=0,len=Math.min(x,y);i<len;++i){if(a[i]!==b[i]){x=a[i];y=b[i];break}}if(x<y)return-1;if(y<x)return 1;return 0};Buffer.isEncoding=function isEncoding(encoding){switch(String(encoding).toLowerCase()){case"hex":case"utf8":case"utf-8":case"ascii":case"latin1":case"binary":case"base64":case"ucs2":case"ucs-2":case"utf16le":case"utf-16le":return true;default:return false}};Buffer.concat=function concat(list,length){if(!isArray(list)){throw new TypeError('"list" argument must be an Array of Buffers')}if(list.length===0){return Buffer.alloc(0)}var i;if(length===undefined){length=0;for(i=0;i<list.length;++i){length+=list[i].length}}var buffer=Buffer.allocUnsafe(length);var pos=0;for(i=0;i<list.length;++i){var buf=list[i];if(!Buffer.isBuffer(buf)){throw new TypeError('"list" argument must be an Array of Buffers')}buf.copy(buffer,pos);pos+=buf.length}return buffer};function byteLength(string,encoding){if(Buffer.isBuffer(string)){return string.length}if(typeof ArrayBuffer!=="undefined"&&typeof ArrayBuffer.isView==="function"&&(ArrayBuffer.isView(string)||string instanceof ArrayBuffer)){return string.byteLength}if(typeof string!=="string"){string=""+string}var len=string.length;if(len===0)return 0;var loweredCase=false;for(;;){switch(encoding){case"ascii":case"latin1":case"binary":return len;case"utf8":case"utf-8":case undefined:return utf8ToBytes(string).length;case"ucs2":case"ucs-2":case"utf16le":case"utf-16le":return len*2;case"hex":return len>>>1;case"base64":return base64ToBytes(string).length;default:if(loweredCase)return utf8ToBytes(string).length;encoding=(""+encoding).toLowerCase();loweredCase=true}}}Buffer.byteLength=byteLength;function slowToString(encoding,start,end){var loweredCase=false;if(start===undefined||start<0){start=0}if(start>this.length){return""}if(end===undefined||end>this.length){end=this.length}if(end<=0){return""}end>>>=0;start>>>=0;if(end<=start){return""}if(!encoding)encoding="utf8";while(true){switch(encoding){case"hex":return hexSlice(this,start,end);case"utf8":case"utf-8":return utf8Slice(this,start,end);case"ascii":return asciiSlice(this,start,end);case"latin1":case"binary":return latin1Slice(this,start,end);case"base64":return base64Slice(this,start,end);case"ucs2":case"ucs-2":case"utf16le":case"utf-16le":return utf16leSlice(this,start,end);default:if(loweredCase)throw new TypeError("Unknown encoding: "+encoding);encoding=(encoding+"").toLowerCase();loweredCase=true}}}Buffer.prototype._isBuffer=true;function swap(b,n,m){var i=b[n];b[n]=b[m];b[m]=i}Buffer.prototype.swap16=function swap16(){var len=this.length;if(len%2!==0){throw new RangeError("Buffer size must be a multiple of 16-bits")}for(var i=0;i<len;i+=2){swap(this,i,i+1)}return this};Buffer.prototype.swap32=function swap32(){var len=this.length;if(len%4!==0){throw new RangeError("Buffer size must be a multiple of 32-bits")}for(var i=0;i<len;i+=4){swap(this,i,i+3);swap(this,i+1,i+2)}return this};Buffer.prototype.swap64=function swap64(){var len=this.length;if(len%8!==0){throw new RangeError("Buffer size must be a multiple of 64-bits")}for(var i=0;i<len;i+=8){swap(this,i,i+7);swap(this,i+1,i+6);swap(this,i+2,i+5);swap(this,i+3,i+4)}return this};Buffer.prototype.toString=function toString(){var length=this.length|0;if(length===0)return"";if(arguments.length===0)return utf8Slice(this,0,length);return slowToString.apply(this,arguments)};Buffer.prototype.equals=function equals(b){if(!Buffer.isBuffer(b))throw new TypeError("Argument must be a Buffer");if(this===b)return true;return Buffer.compare(this,b)===0};Buffer.prototype.inspect=function inspect(){var str="";var max=exports.INSPECT_MAX_BYTES;if(this.length>0){str=this.toString("hex",0,max).match(/.{2}/g).join(" ");if(this.length>max)str+=" ... "}return"<Buffer "+str+">"};Buffer.prototype.compare=function compare(target,start,end,thisStart,thisEnd){if(!Buffer.isBuffer(target)){throw new TypeError("Argument must be a Buffer")}if(start===undefined){start=0}if(end===undefined){end=target?target.length:0}if(thisStart===undefined){thisStart=0}if(thisEnd===undefined){thisEnd=this.length}if(start<0||end>target.length||thisStart<0||thisEnd>this.length){throw new RangeError("out of range index")}if(thisStart>=thisEnd&&start>=end){return 0}if(thisStart>=thisEnd){return-1}if(start>=end){return 1}start>>>=0;end>>>=0;thisStart>>>=0;thisEnd>>>=0;if(this===target)return 0;var x=thisEnd-thisStart;var y=end-start;var len=Math.min(x,y);var thisCopy=this.slice(thisStart,thisEnd);var targetCopy=target.slice(start,end);for(var i=0;i<len;++i){if(thisCopy[i]!==targetCopy[i]){x=thisCopy[i];y=targetCopy[i];break}}if(x<y)return-1;if(y<x)return 1;return 0};function bidirectionalIndexOf(buffer,val,byteOffset,encoding,dir){if(buffer.length===0)return-1;if(typeof byteOffset==="string"){encoding=byteOffset;byteOffset=0}else if(byteOffset>2147483647){byteOffset=2147483647}else if(byteOffset<-2147483648){byteOffset=-2147483648}byteOffset=+byteOffset;if(isNaN(byteOffset)){byteOffset=dir?0:buffer.length-1}if(byteOffset<0)byteOffset=buffer.length+byteOffset;if(byteOffset>=buffer.length){if(dir)return-1;else byteOffset=buffer.length-1}else if(byteOffset<0){if(dir)byteOffset=0;else return-1}if(typeof val==="string"){val=Buffer.from(val,encoding)}if(Buffer.isBuffer(val)){if(val.length===0){return-1}return arrayIndexOf(buffer,val,byteOffset,encoding,dir)}else if(typeof val==="number"){val=val&255;if(Buffer.TYPED_ARRAY_SUPPORT&&typeof Uint8Array.prototype.indexOf==="function"){if(dir){return Uint8Array.prototype.indexOf.call(buffer,val,byteOffset)}else{return Uint8Array.prototype.lastIndexOf.call(buffer,val,byteOffset)}}return arrayIndexOf(buffer,[val],byteOffset,encoding,dir)}throw new TypeError("val must be string, number or Buffer")}function arrayIndexOf(arr,val,byteOffset,encoding,dir){var indexSize=1;var arrLength=arr.length;var valLength=val.length;if(encoding!==undefined){encoding=String(encoding).toLowerCase();if(encoding==="ucs2"||encoding==="ucs-2"||encoding==="utf16le"||encoding==="utf-16le"){if(arr.length<2||val.length<2){return-1}indexSize=2;arrLength/=2;valLength/=2;byteOffset/=2}}function read(buf,i){if(indexSize===1){return buf[i]}else{return buf.readUInt16BE(i*indexSize)}}var i;if(dir){var foundIndex=-1;for(i=byteOffset;i<arrLength;i++){if(read(arr,i)===read(val,foundIndex===-1?0:i-foundIndex)){if(foundIndex===-1)foundIndex=i;if(i-foundIndex+1===valLength)return foundIndex*indexSize}else{if(foundIndex!==-1)i-=i-foundIndex;foundIndex=-1}}}else{if(byteOffset+valLength>arrLength)byteOffset=arrLength-valLength;for(i=byteOffset;i>=0;i--){var found=true;for(var j=0;j<valLength;j++){if(read(arr,i+j)!==read(val,j)){found=false;break}}if(found)return i}}return-1}Buffer.prototype.includes=function includes(val,byteOffset,encoding){return this.indexOf(val,byteOffset,encoding)!==-1};Buffer.prototype.indexOf=function indexOf(val,byteOffset,encoding){return bidirectionalIndexOf(this,val,byteOffset,encoding,true)};Buffer.prototype.lastIndexOf=function lastIndexOf(val,byteOffset,encoding){return bidirectionalIndexOf(this,val,byteOffset,encoding,false)};function hexWrite(buf,string,offset,length){offset=Number(offset)||0;var remaining=buf.length-offset;if(!length){length=remaining}else{length=Number(length);if(length>remaining){length=remaining}}var strLen=string.length;if(strLen%2!==0)throw new TypeError("Invalid hex string");if(length>strLen/2){length=strLen/2}for(var i=0;i<length;++i){var parsed=parseInt(string.substr(i*2,2),16);if(isNaN(parsed))return i;buf[offset+i]=parsed}return i}function utf8Write(buf,string,offset,length){return blitBuffer(utf8ToBytes(string,buf.length-offset),buf,offset,length)}function asciiWrite(buf,string,offset,length){return blitBuffer(asciiToBytes(string),buf,offset,length)}function latin1Write(buf,string,offset,length){return asciiWrite(buf,string,offset,length)}function base64Write(buf,string,offset,length){return blitBuffer(base64ToBytes(string),buf,offset,length)}function ucs2Write(buf,string,offset,length){return blitBuffer(utf16leToBytes(string,buf.length-offset),buf,offset,length)}Buffer.prototype.write=function write(string,offset,length,encoding){if(offset===undefined){encoding="utf8";length=this.length;offset=0}else if(length===undefined&&typeof offset==="string"){encoding=offset;length=this.length;offset=0}else if(isFinite(offset)){offset=offset|0;if(isFinite(length)){length=length|0;if(encoding===undefined)encoding="utf8"}else{encoding=length;length=undefined}}else{throw new Error("Buffer.write(string, encoding, offset[, length]) is no longer supported")}var remaining=this.length-offset;if(length===undefined||length>remaining)length=remaining;if(string.length>0&&(length<0||offset<0)||offset>this.length){throw new RangeError("Attempt to write outside buffer bounds")}if(!encoding)encoding="utf8";var loweredCase=false;for(;;){switch(encoding){case"hex":return hexWrite(this,string,offset,length);case"utf8":case"utf-8":return utf8Write(this,string,offset,length);case"ascii":return asciiWrite(this,string,offset,length);case"latin1":case"binary":return latin1Write(this,string,offset,length);case"base64":return base64Write(this,string,offset,length);case"ucs2":case"ucs-2":case"utf16le":case"utf-16le":return ucs2Write(this,string,offset,length);default:if(loweredCase)throw new TypeError("Unknown encoding: "+encoding);encoding=(""+encoding).toLowerCase();loweredCase=true}}};Buffer.prototype.toJSON=function toJSON(){return{type:"Buffer",data:Array.prototype.slice.call(this._arr||this,0)}};function base64Slice(buf,start,end){if(start===0&&end===buf.length){return base64.fromByteArray(buf)}else{return base64.fromByteArray(buf.slice(start,end))}}function utf8Slice(buf,start,end){end=Math.min(buf.length,end);var res=[];var i=start;while(i<end){var firstByte=buf[i];var codePoint=null;var bytesPerSequence=firstByte>239?4:firstByte>223?3:firstByte>191?2:1;if(i+bytesPerSequence<=end){var secondByte,thirdByte,fourthByte,tempCodePoint;switch(bytesPerSequence){case 1:if(firstByte<128){codePoint=firstByte}break;case 2:secondByte=buf[i+1];if((secondByte&192)===128){tempCodePoint=(firstByte&31)<<6|secondByte&63;if(tempCodePoint>127){codePoint=tempCodePoint}}break;case 3:secondByte=buf[i+1];thirdByte=buf[i+2];if((secondByte&192)===128&&(thirdByte&192)===128){tempCodePoint=(firstByte&15)<<12|(secondByte&63)<<6|thirdByte&63;if(tempCodePoint>2047&&(tempCodePoint<55296||tempCodePoint>57343)){codePoint=tempCodePoint}}break;case 4:secondByte=buf[i+1];thirdByte=buf[i+2];fourthByte=buf[i+3];if((secondByte&192)===128&&(thirdByte&192)===128&&(fourthByte&192)===128){tempCodePoint=(firstByte&15)<<18|(secondByte&63)<<12|(thirdByte&63)<<6|fourthByte&63;if(tempCodePoint>65535&&tempCodePoint<1114112){codePoint=tempCodePoint}}}}if(codePoint===null){codePoint=65533;bytesPerSequence=1}else if(codePoint>65535){codePoint-=65536;res.push(codePoint>>>10&1023|55296);codePoint=56320|codePoint&1023}res.push(codePoint);i+=bytesPerSequence}return decodeCodePointsArray(res)}var MAX_ARGUMENTS_LENGTH=4096;function decodeCodePointsArray(codePoints){var len=codePoints.length;if(len<=MAX_ARGUMENTS_LENGTH){return String.fromCharCode.apply(String,codePoints)}var res="";var i=0;while(i<len){res+=String.fromCharCode.apply(String,codePoints.slice(i,i+=MAX_ARGUMENTS_LENGTH))}return res}function asciiSlice(buf,start,end){var ret="";end=Math.min(buf.length,end);for(var i=start;i<end;++i){ret+=String.fromCharCode(buf[i]&127)}return ret}function latin1Slice(buf,start,end){var ret="";end=Math.min(buf.length,end);for(var i=start;i<end;++i){ret+=String.fromCharCode(buf[i])}return ret}function hexSlice(buf,start,end){var len=buf.length;if(!start||start<0)start=0;if(!end||end<0||end>len)end=len;var out="";for(var i=start;i<end;++i){out+=toHex(buf[i])}return out}function utf16leSlice(buf,start,end){var bytes=buf.slice(start,end);var res="";for(var i=0;i<bytes.length;i+=2){res+=String.fromCharCode(bytes[i]+bytes[i+1]*256)}return res}Buffer.prototype.slice=function slice(start,end){var len=this.length;start=~~start;end=end===undefined?len:~~end;if(start<0){start+=len;if(start<0)start=0}else if(start>len){start=len}if(end<0){end+=len;if(end<0)end=0}else if(end>len){end=len}if(end<start)end=start;var newBuf;if(Buffer.TYPED_ARRAY_SUPPORT){newBuf=this.subarray(start,end);newBuf.__proto__=Buffer.prototype}else{var sliceLen=end-start;newBuf=new Buffer(sliceLen,undefined);for(var i=0;i<sliceLen;++i){newBuf[i]=this[i+start]}}return newBuf};function checkOffset(offset,ext,length){if(offset%1!==0||offset<0)throw new RangeError("offset is not uint");if(offset+ext>length)throw new RangeError("Trying to access beyond buffer length")}Buffer.prototype.readUIntLE=function readUIntLE(offset,byteLength,noAssert){offset=offset|0;byteLength=byteLength|0;if(!noAssert)checkOffset(offset,byteLength,this.length);var val=this[offset];var mul=1;var i=0;while(++i<byteLength&&(mul*=256)){val+=this[offset+i]*mul}return val};Buffer.prototype.readUIntBE=function readUIntBE(offset,byteLength,noAssert){offset=offset|0;byteLength=byteLength|0;if(!noAssert){checkOffset(offset,byteLength,this.length)}var val=this[offset+--byteLength];var mul=1;while(byteLength>0&&(mul*=256)){val+=this[offset+--byteLength]*mul}return val};Buffer.prototype.readUInt8=function readUInt8(offset,noAssert){if(!noAssert)checkOffset(offset,1,this.length);return this[offset]};Buffer.prototype.readUInt16LE=function readUInt16LE(offset,noAssert){if(!noAssert)checkOffset(offset,2,this.length);return this[offset]|this[offset+1]<<8};Buffer.prototype.readUInt16BE=function readUInt16BE(offset,noAssert){if(!noAssert)checkOffset(offset,2,this.length);return this[offset]<<8|this[offset+1]};Buffer.prototype.readUInt32LE=function readUInt32LE(offset,noAssert){if(!noAssert)checkOffset(offset,4,this.length);return(this[offset]|this[offset+1]<<8|this[offset+2]<<16)+this[offset+3]*16777216};Buffer.prototype.readUInt32BE=function readUInt32BE(offset,noAssert){if(!noAssert)checkOffset(offset,4,this.length);return this[offset]*16777216+(this[offset+1]<<16|this[offset+2]<<8|this[offset+3])};Buffer.prototype.readIntLE=function readIntLE(offset,byteLength,noAssert){offset=offset|0;byteLength=byteLength|0;if(!noAssert)checkOffset(offset,byteLength,this.length);var val=this[offset];var mul=1;var i=0;while(++i<byteLength&&(mul*=256)){val+=this[offset+i]*mul}mul*=128;if(val>=mul)val-=Math.pow(2,8*byteLength);return val};Buffer.prototype.readIntBE=function readIntBE(offset,byteLength,noAssert){offset=offset|0;byteLength=byteLength|0;if(!noAssert)checkOffset(offset,byteLength,this.length);
+var i=byteLength;var mul=1;var val=this[offset+--i];while(i>0&&(mul*=256)){val+=this[offset+--i]*mul}mul*=128;if(val>=mul)val-=Math.pow(2,8*byteLength);return val};Buffer.prototype.readInt8=function readInt8(offset,noAssert){if(!noAssert)checkOffset(offset,1,this.length);if(!(this[offset]&128))return this[offset];return(255-this[offset]+1)*-1};Buffer.prototype.readInt16LE=function readInt16LE(offset,noAssert){if(!noAssert)checkOffset(offset,2,this.length);var val=this[offset]|this[offset+1]<<8;return val&32768?val|4294901760:val};Buffer.prototype.readInt16BE=function readInt16BE(offset,noAssert){if(!noAssert)checkOffset(offset,2,this.length);var val=this[offset+1]|this[offset]<<8;return val&32768?val|4294901760:val};Buffer.prototype.readInt32LE=function readInt32LE(offset,noAssert){if(!noAssert)checkOffset(offset,4,this.length);return this[offset]|this[offset+1]<<8|this[offset+2]<<16|this[offset+3]<<24};Buffer.prototype.readInt32BE=function readInt32BE(offset,noAssert){if(!noAssert)checkOffset(offset,4,this.length);return this[offset]<<24|this[offset+1]<<16|this[offset+2]<<8|this[offset+3]};Buffer.prototype.readFloatLE=function readFloatLE(offset,noAssert){if(!noAssert)checkOffset(offset,4,this.length);return ieee754.read(this,offset,true,23,4)};Buffer.prototype.readFloatBE=function readFloatBE(offset,noAssert){if(!noAssert)checkOffset(offset,4,this.length);return ieee754.read(this,offset,false,23,4)};Buffer.prototype.readDoubleLE=function readDoubleLE(offset,noAssert){if(!noAssert)checkOffset(offset,8,this.length);return ieee754.read(this,offset,true,52,8)};Buffer.prototype.readDoubleBE=function readDoubleBE(offset,noAssert){if(!noAssert)checkOffset(offset,8,this.length);return ieee754.read(this,offset,false,52,8)};function checkInt(buf,value,offset,ext,max,min){if(!Buffer.isBuffer(buf))throw new TypeError('"buffer" argument must be a Buffer instance');if(value>max||value<min)throw new RangeError('"value" argument is out of bounds');if(offset+ext>buf.length)throw new RangeError("Index out of range")}Buffer.prototype.writeUIntLE=function writeUIntLE(value,offset,byteLength,noAssert){value=+value;offset=offset|0;byteLength=byteLength|0;if(!noAssert){var maxBytes=Math.pow(2,8*byteLength)-1;checkInt(this,value,offset,byteLength,maxBytes,0)}var mul=1;var i=0;this[offset]=value&255;while(++i<byteLength&&(mul*=256)){this[offset+i]=value/mul&255}return offset+byteLength};Buffer.prototype.writeUIntBE=function writeUIntBE(value,offset,byteLength,noAssert){value=+value;offset=offset|0;byteLength=byteLength|0;if(!noAssert){var maxBytes=Math.pow(2,8*byteLength)-1;checkInt(this,value,offset,byteLength,maxBytes,0)}var i=byteLength-1;var mul=1;this[offset+i]=value&255;while(--i>=0&&(mul*=256)){this[offset+i]=value/mul&255}return offset+byteLength};Buffer.prototype.writeUInt8=function writeUInt8(value,offset,noAssert){value=+value;offset=offset|0;if(!noAssert)checkInt(this,value,offset,1,255,0);if(!Buffer.TYPED_ARRAY_SUPPORT)value=Math.floor(value);this[offset]=value&255;return offset+1};function objectWriteUInt16(buf,value,offset,littleEndian){if(value<0)value=65535+value+1;for(var i=0,j=Math.min(buf.length-offset,2);i<j;++i){buf[offset+i]=(value&255<<8*(littleEndian?i:1-i))>>>(littleEndian?i:1-i)*8}}Buffer.prototype.writeUInt16LE=function writeUInt16LE(value,offset,noAssert){value=+value;offset=offset|0;if(!noAssert)checkInt(this,value,offset,2,65535,0);if(Buffer.TYPED_ARRAY_SUPPORT){this[offset]=value&255;this[offset+1]=value>>>8}else{objectWriteUInt16(this,value,offset,true)}return offset+2};Buffer.prototype.writeUInt16BE=function writeUInt16BE(value,offset,noAssert){value=+value;offset=offset|0;if(!noAssert)checkInt(this,value,offset,2,65535,0);if(Buffer.TYPED_ARRAY_SUPPORT){this[offset]=value>>>8;this[offset+1]=value&255}else{objectWriteUInt16(this,value,offset,false)}return offset+2};function objectWriteUInt32(buf,value,offset,littleEndian){if(value<0)value=4294967295+value+1;for(var i=0,j=Math.min(buf.length-offset,4);i<j;++i){buf[offset+i]=value>>>(littleEndian?i:3-i)*8&255}}Buffer.prototype.writeUInt32LE=function writeUInt32LE(value,offset,noAssert){value=+value;offset=offset|0;if(!noAssert)checkInt(this,value,offset,4,4294967295,0);if(Buffer.TYPED_ARRAY_SUPPORT){this[offset+3]=value>>>24;this[offset+2]=value>>>16;this[offset+1]=value>>>8;this[offset]=value&255}else{objectWriteUInt32(this,value,offset,true)}return offset+4};Buffer.prototype.writeUInt32BE=function writeUInt32BE(value,offset,noAssert){value=+value;offset=offset|0;if(!noAssert)checkInt(this,value,offset,4,4294967295,0);if(Buffer.TYPED_ARRAY_SUPPORT){this[offset]=value>>>24;this[offset+1]=value>>>16;this[offset+2]=value>>>8;this[offset+3]=value&255}else{objectWriteUInt32(this,value,offset,false)}return offset+4};Buffer.prototype.writeIntLE=function writeIntLE(value,offset,byteLength,noAssert){value=+value;offset=offset|0;if(!noAssert){var limit=Math.pow(2,8*byteLength-1);checkInt(this,value,offset,byteLength,limit-1,-limit)}var i=0;var mul=1;var sub=0;this[offset]=value&255;while(++i<byteLength&&(mul*=256)){if(value<0&&sub===0&&this[offset+i-1]!==0){sub=1}this[offset+i]=(value/mul>>0)-sub&255}return offset+byteLength};Buffer.prototype.writeIntBE=function writeIntBE(value,offset,byteLength,noAssert){value=+value;offset=offset|0;if(!noAssert){var limit=Math.pow(2,8*byteLength-1);checkInt(this,value,offset,byteLength,limit-1,-limit)}var i=byteLength-1;var mul=1;var sub=0;this[offset+i]=value&255;while(--i>=0&&(mul*=256)){if(value<0&&sub===0&&this[offset+i+1]!==0){sub=1}this[offset+i]=(value/mul>>0)-sub&255}return offset+byteLength};Buffer.prototype.writeInt8=function writeInt8(value,offset,noAssert){value=+value;offset=offset|0;if(!noAssert)checkInt(this,value,offset,1,127,-128);if(!Buffer.TYPED_ARRAY_SUPPORT)value=Math.floor(value);if(value<0)value=255+value+1;this[offset]=value&255;return offset+1};Buffer.prototype.writeInt16LE=function writeInt16LE(value,offset,noAssert){value=+value;offset=offset|0;if(!noAssert)checkInt(this,value,offset,2,32767,-32768);if(Buffer.TYPED_ARRAY_SUPPORT){this[offset]=value&255;this[offset+1]=value>>>8}else{objectWriteUInt16(this,value,offset,true)}return offset+2};Buffer.prototype.writeInt16BE=function writeInt16BE(value,offset,noAssert){value=+value;offset=offset|0;if(!noAssert)checkInt(this,value,offset,2,32767,-32768);if(Buffer.TYPED_ARRAY_SUPPORT){this[offset]=value>>>8;this[offset+1]=value&255}else{objectWriteUInt16(this,value,offset,false)}return offset+2};Buffer.prototype.writeInt32LE=function writeInt32LE(value,offset,noAssert){value=+value;offset=offset|0;if(!noAssert)checkInt(this,value,offset,4,2147483647,-2147483648);if(Buffer.TYPED_ARRAY_SUPPORT){this[offset]=value&255;this[offset+1]=value>>>8;this[offset+2]=value>>>16;this[offset+3]=value>>>24}else{objectWriteUInt32(this,value,offset,true)}return offset+4};Buffer.prototype.writeInt32BE=function writeInt32BE(value,offset,noAssert){value=+value;offset=offset|0;if(!noAssert)checkInt(this,value,offset,4,2147483647,-2147483648);if(value<0)value=4294967295+value+1;if(Buffer.TYPED_ARRAY_SUPPORT){this[offset]=value>>>24;this[offset+1]=value>>>16;this[offset+2]=value>>>8;this[offset+3]=value&255}else{objectWriteUInt32(this,value,offset,false)}return offset+4};function checkIEEE754(buf,value,offset,ext,max,min){if(offset+ext>buf.length)throw new RangeError("Index out of range");if(offset<0)throw new RangeError("Index out of range")}function writeFloat(buf,value,offset,littleEndian,noAssert){if(!noAssert){checkIEEE754(buf,value,offset,4,3.4028234663852886e38,-3.4028234663852886e38)}ieee754.write(buf,value,offset,littleEndian,23,4);return offset+4}Buffer.prototype.writeFloatLE=function writeFloatLE(value,offset,noAssert){return writeFloat(this,value,offset,true,noAssert)};Buffer.prototype.writeFloatBE=function writeFloatBE(value,offset,noAssert){return writeFloat(this,value,offset,false,noAssert)};function writeDouble(buf,value,offset,littleEndian,noAssert){if(!noAssert){checkIEEE754(buf,value,offset,8,1.7976931348623157e308,-1.7976931348623157e308)}ieee754.write(buf,value,offset,littleEndian,52,8);return offset+8}Buffer.prototype.writeDoubleLE=function writeDoubleLE(value,offset,noAssert){return writeDouble(this,value,offset,true,noAssert)};Buffer.prototype.writeDoubleBE=function writeDoubleBE(value,offset,noAssert){return writeDouble(this,value,offset,false,noAssert)};Buffer.prototype.copy=function copy(target,targetStart,start,end){if(!start)start=0;if(!end&&end!==0)end=this.length;if(targetStart>=target.length)targetStart=target.length;if(!targetStart)targetStart=0;if(end>0&&end<start)end=start;if(end===start)return 0;if(target.length===0||this.length===0)return 0;if(targetStart<0){throw new RangeError("targetStart out of bounds")}if(start<0||start>=this.length)throw new RangeError("sourceStart out of bounds");if(end<0)throw new RangeError("sourceEnd out of bounds");if(end>this.length)end=this.length;if(target.length-targetStart<end-start){end=target.length-targetStart+start}var len=end-start;var i;if(this===target&&start<targetStart&&targetStart<end){for(i=len-1;i>=0;--i){target[i+targetStart]=this[i+start]}}else if(len<1e3||!Buffer.TYPED_ARRAY_SUPPORT){for(i=0;i<len;++i){target[i+targetStart]=this[i+start]}}else{Uint8Array.prototype.set.call(target,this.subarray(start,start+len),targetStart)}return len};Buffer.prototype.fill=function fill(val,start,end,encoding){if(typeof val==="string"){if(typeof start==="string"){encoding=start;start=0;end=this.length}else if(typeof end==="string"){encoding=end;end=this.length}if(val.length===1){var code=val.charCodeAt(0);if(code<256){val=code}}if(encoding!==undefined&&typeof encoding!=="string"){throw new TypeError("encoding must be a string")}if(typeof encoding==="string"&&!Buffer.isEncoding(encoding)){throw new TypeError("Unknown encoding: "+encoding)}}else if(typeof val==="number"){val=val&255}if(start<0||this.length<start||this.length<end){throw new RangeError("Out of range index")}if(end<=start){return this}start=start>>>0;end=end===undefined?this.length:end>>>0;if(!val)val=0;var i;if(typeof val==="number"){for(i=start;i<end;++i){this[i]=val}}else{var bytes=Buffer.isBuffer(val)?val:utf8ToBytes(new Buffer(val,encoding).toString());var len=bytes.length;for(i=0;i<end-start;++i){this[i+start]=bytes[i%len]}}return this};var INVALID_BASE64_RE=/[^+\/0-9A-Za-z-_]/g;function base64clean(str){str=stringtrim(str).replace(INVALID_BASE64_RE,"");if(str.length<2)return"";while(str.length%4!==0){str=str+"="}return str}function stringtrim(str){if(str.trim)return str.trim();return str.replace(/^\s+|\s+$/g,"")}function toHex(n){if(n<16)return"0"+n.toString(16);return n.toString(16)}function utf8ToBytes(string,units){units=units||Infinity;var codePoint;var length=string.length;var leadSurrogate=null;var bytes=[];for(var i=0;i<length;++i){codePoint=string.charCodeAt(i);if(codePoint>55295&&codePoint<57344){if(!leadSurrogate){if(codePoint>56319){if((units-=3)>-1)bytes.push(239,191,189);continue}else if(i+1===length){if((units-=3)>-1)bytes.push(239,191,189);continue}leadSurrogate=codePoint;continue}if(codePoint<56320){if((units-=3)>-1)bytes.push(239,191,189);leadSurrogate=codePoint;continue}codePoint=(leadSurrogate-55296<<10|codePoint-56320)+65536}else if(leadSurrogate){if((units-=3)>-1)bytes.push(239,191,189)}leadSurrogate=null;if(codePoint<128){if((units-=1)<0)break;bytes.push(codePoint)}else if(codePoint<2048){if((units-=2)<0)break;bytes.push(codePoint>>6|192,codePoint&63|128)}else if(codePoint<65536){if((units-=3)<0)break;bytes.push(codePoint>>12|224,codePoint>>6&63|128,codePoint&63|128)}else if(codePoint<1114112){if((units-=4)<0)break;bytes.push(codePoint>>18|240,codePoint>>12&63|128,codePoint>>6&63|128,codePoint&63|128)}else{throw new Error("Invalid code point")}}return bytes}function asciiToBytes(str){var byteArray=[];for(var i=0;i<str.length;++i){byteArray.push(str.charCodeAt(i)&255)}return byteArray}function utf16leToBytes(str,units){var c,hi,lo;var byteArray=[];for(var i=0;i<str.length;++i){if((units-=2)<0)break;c=str.charCodeAt(i);hi=c>>8;lo=c%256;byteArray.push(lo);byteArray.push(hi)}return byteArray}function base64ToBytes(str){return base64.toByteArray(base64clean(str))}function blitBuffer(src,dst,offset,length){for(var i=0;i<length;++i){if(i+offset>=dst.length||i>=src.length)break;dst[i+offset]=src[i]}return i}function isnan(val){return val!==val}}).call(this,typeof global!=="undefined"?global:typeof self!=="undefined"?self:typeof window!=="undefined"?window:{})},{"base64-js":2,ieee754:37,isarray:40}],6:[function(require,module,exports){(function(Buffer){function isArray(arg){if(Array.isArray){return Array.isArray(arg)}return objectToString(arg)==="[object Array]"}exports.isArray=isArray;function isBoolean(arg){return typeof arg==="boolean"}exports.isBoolean=isBoolean;function isNull(arg){return arg===null}exports.isNull=isNull;function isNullOrUndefined(arg){return arg==null}exports.isNullOrUndefined=isNullOrUndefined;function isNumber(arg){return typeof arg==="number"}exports.isNumber=isNumber;function isString(arg){return typeof arg==="string"}exports.isString=isString;function isSymbol(arg){return typeof arg==="symbol"}exports.isSymbol=isSymbol;function isUndefined(arg){return arg===void 0}exports.isUndefined=isUndefined;function isRegExp(re){return objectToString(re)==="[object RegExp]"}exports.isRegExp=isRegExp;function isObject(arg){return typeof arg==="object"&&arg!==null}exports.isObject=isObject;function isDate(d){return objectToString(d)==="[object Date]"}exports.isDate=isDate;function isError(e){return objectToString(e)==="[object Error]"||e instanceof Error}exports.isError=isError;function isFunction(arg){return typeof arg==="function"}exports.isFunction=isFunction;function isPrimitive(arg){return arg===null||typeof arg==="boolean"||typeof arg==="number"||typeof arg==="string"||typeof arg==="symbol"||typeof arg==="undefined"}exports.isPrimitive=isPrimitive;exports.isBuffer=Buffer.isBuffer;function objectToString(o){return Object.prototype.toString.call(o)}}).call(this,{isBuffer:require("../../is-buffer/index.js")})},{"../../is-buffer/index.js":39}],7:[function(require,module,exports){var ElementType=require("domelementtype");var entities=require("entities");var booleanAttributes={__proto__:null,allowfullscreen:true,async:true,autofocus:true,autoplay:true,checked:true,controls:true,default:true,defer:true,disabled:true,hidden:true,ismap:true,loop:true,multiple:true,muted:true,open:true,readonly:true,required:true,reversed:true,scoped:true,seamless:true,selected:true,typemustmatch:true};var unencodedElements={__proto__:null,style:true,script:true,xmp:true,iframe:true,noembed:true,noframes:true,plaintext:true,noscript:true};function formatAttrs(attributes,opts){if(!attributes)return;var output="",value;for(var key in attributes){value=attributes[key];if(output){output+=" "}if(!value&&booleanAttributes[key]){output+=key}else{output+=key+'="'+(opts.decodeEntities?entities.encodeXML(value):value)+'"'}}return output}var singleTag={__proto__:null,area:true,base:true,basefont:true,br:true,col:true,command:true,embed:true,frame:true,hr:true,img:true,input:true,isindex:true,keygen:true,link:true,meta:true,param:true,source:true,track:true,wbr:true};var render=module.exports=function(dom,opts){if(!Array.isArray(dom)&&!dom.cheerio)dom=[dom];opts=opts||{};var output="";for(var i=0;i<dom.length;i++){var elem=dom[i];if(elem.type==="root")output+=render(elem.children,opts);else if(ElementType.isTag(elem))output+=renderTag(elem,opts);else if(elem.type===ElementType.Directive)output+=renderDirective(elem);else if(elem.type===ElementType.Comment)output+=renderComment(elem);else if(elem.type===ElementType.CDATA)output+=renderCdata(elem);else output+=renderText(elem,opts)}return output};function renderTag(elem,opts){if(elem.name==="svg")opts={decodeEntities:opts.decodeEntities,xmlMode:true};var tag="<"+elem.name,attribs=formatAttrs(elem.attribs,opts);if(attribs){tag+=" "+attribs}if(opts.xmlMode&&(!elem.children||elem.children.length===0)){tag+="/>"}else{tag+=">";if(elem.children){tag+=render(elem.children,opts)}if(!singleTag[elem.name]||opts.xmlMode){tag+="</"+elem.name+">"}}return tag}function renderDirective(elem){return"<"+elem.data+">"}function renderText(elem,opts){var data=elem.data||"";if(opts.decodeEntities&&!(elem.parent&&elem.parent.name in unencodedElements)){data=entities.encodeXML(data)}return data}function renderCdata(elem){return"<![CDATA["+elem.children[0].data+"]]>"}function renderComment(elem){return"<!--"+elem.data+"-->"}},{domelementtype:8,entities:20}],8:[function(require,module,exports){module.exports={Text:"text",Directive:"directive",Comment:"comment",Script:"script",Style:"style",Tag:"tag",CDATA:"cdata",isTag:function(elem){return elem.type==="tag"||elem.type==="script"||elem.type==="style"}}},{}],9:[function(require,module,exports){module.exports={Text:"text",Directive:"directive",Comment:"comment",Script:"script",Style:"style",Tag:"tag",CDATA:"cdata",Doctype:"doctype",isTag:function(elem){return elem.type==="tag"||elem.type==="script"||elem.type==="style"}}},{}],10:[function(require,module,exports){var ElementType=require("domelementtype");var re_whitespace=/\s+/g;var NodePrototype=require("./lib/node");var ElementPrototype=require("./lib/element");function DomHandler(callback,options,elementCB){if(typeof callback==="object"){elementCB=options;options=callback;callback=null}else if(typeof options==="function"){elementCB=options;options=defaultOpts}this._callback=callback;this._options=options||defaultOpts;this._elementCB=elementCB;this.dom=[];this._done=false;this._tagStack=[];this._parser=this._parser||null}var defaultOpts={normalizeWhitespace:false,withStartIndices:false};DomHandler.prototype.onparserinit=function(parser){this._parser=parser};DomHandler.prototype.onreset=function(){DomHandler.call(this,this._callback,this._options,this._elementCB)};DomHandler.prototype.onend=function(){if(this._done)return;this._done=true;this._parser=null;this._handleCallback(null)};DomHandler.prototype._handleCallback=DomHandler.prototype.onerror=function(error){if(typeof this._callback==="function"){this._callback(error,this.dom)}else{if(error)throw error}};DomHandler.prototype.onclosetag=function(){var elem=this._tagStack.pop();if(this._elementCB)this._elementCB(elem)};DomHandler.prototype._addDomElement=function(element){var parent=this._tagStack[this._tagStack.length-1];var siblings=parent?parent.children:this.dom;var previousSibling=siblings[siblings.length-1];element.next=null;if(this._options.withStartIndices){element.startIndex=this._parser.startIndex}if(this._options.withDomLvl1){element.__proto__=element.type==="tag"?ElementPrototype:NodePrototype}if(previousSibling){element.prev=previousSibling;previousSibling.next=element}else{element.prev=null}siblings.push(element);element.parent=parent||null};DomHandler.prototype.onopentag=function(name,attribs){var element={type:name==="script"?ElementType.Script:name==="style"?ElementType.Style:ElementType.Tag,name:name,attribs:attribs,children:[]};this._addDomElement(element);this._tagStack.push(element)};DomHandler.prototype.ontext=function(data){var normalize=this._options.normalizeWhitespace||this._options.ignoreWhitespace;var lastTag;if(!this._tagStack.length&&this.dom.length&&(lastTag=this.dom[this.dom.length-1]).type===ElementType.Text){if(normalize){lastTag.data=(lastTag.data+data).replace(re_whitespace," ")}else{lastTag.data+=data}}else{if(this._tagStack.length&&(lastTag=this._tagStack[this._tagStack.length-1])&&(lastTag=lastTag.children[lastTag.children.length-1])&&lastTag.type===ElementType.Text){if(normalize){lastTag.data=(lastTag.data+data).replace(re_whitespace," ")}else{lastTag.data+=data}}else{if(normalize){data=data.replace(re_whitespace," ")}this._addDomElement({data:data,type:ElementType.Text})}}};DomHandler.prototype.oncomment=function(data){var lastTag=this._tagStack[this._tagStack.length-1];if(lastTag&&lastTag.type===ElementType.Comment){lastTag.data+=data;return}var element={data:data,type:ElementType.Comment};this._addDomElement(element);this._tagStack.push(element)};DomHandler.prototype.oncdatastart=function(){var element={children:[{data:"",type:ElementType.Text}],type:ElementType.CDATA};this._addDomElement(element);this._tagStack.push(element)};DomHandler.prototype.oncommentend=DomHandler.prototype.oncdataend=function(){this._tagStack.pop()};DomHandler.prototype.onprocessinginstruction=function(name,data){this._addDomElement({name:name,data:data,type:ElementType.Directive})};module.exports=DomHandler},{"./lib/element":11,"./lib/node":12,domelementtype:9}],11:[function(require,module,exports){var NodePrototype=require("./node");var ElementPrototype=module.exports=Object.create(NodePrototype);var domLvl1={tagName:"name"};Object.keys(domLvl1).forEach(function(key){var shorthand=domLvl1[key];Object.defineProperty(ElementPrototype,key,{get:function(){return this[shorthand]||null},set:function(val){this[shorthand]=val;return val}})})},{"./node":12}],12:[function(require,module,exports){var NodePrototype=module.exports={get firstChild(){var children=this.children;return children&&children[0]||null},get lastChild(){var children=this.children;return children&&children[children.length-1]||null},get nodeType(){return nodeTypes[this.type]||nodeTypes.element}};var domLvl1={tagName:"name",childNodes:"children",parentNode:"parent",previousSibling:"prev",nextSibling:"next",nodeValue:"data"};var nodeTypes={element:1,text:3,cdata:4,comment:8};Object.keys(domLvl1).forEach(function(key){var shorthand=domLvl1[key];Object.defineProperty(NodePrototype,key,{get:function(){return this[shorthand]||null},set:function(val){this[shorthand]=val;return val}})})},{}],13:[function(require,module,exports){var DomUtils=module.exports;[require("./lib/stringify"),require("./lib/traversal"),require("./lib/manipulation"),require("./lib/querying"),require("./lib/legacy"),require("./lib/helpers")].forEach(function(ext){Object.keys(ext).forEach(function(key){DomUtils[key]=ext[key].bind(DomUtils)})})},{"./lib/helpers":14,"./lib/legacy":15,"./lib/manipulation":16,"./lib/querying":17,"./lib/stringify":18,"./lib/traversal":19}],14:[function(require,module,exports){exports.removeSubsets=function(nodes){var idx=nodes.length,node,ancestor,replace;while(--idx>-1){node=ancestor=nodes[idx];nodes[idx]=null;replace=true;while(ancestor){if(nodes.indexOf(ancestor)>-1){replace=false;nodes.splice(idx,1);break}ancestor=ancestor.parent}if(replace){nodes[idx]=node}}return nodes};var POSITION={DISCONNECTED:1,PRECEDING:2,FOLLOWING:4,CONTAINS:8,CONTAINED_BY:16};var comparePos=exports.compareDocumentPosition=function(nodeA,nodeB){var aParents=[];var bParents=[];var current,sharedParent,siblings,aSibling,bSibling,idx;if(nodeA===nodeB){return 0}current=nodeA;while(current){aParents.unshift(current);current=current.parent}current=nodeB;while(current){bParents.unshift(current);current=current.parent}idx=0;while(aParents[idx]===bParents[idx]){idx++}if(idx===0){return POSITION.DISCONNECTED}sharedParent=aParents[idx-1];siblings=sharedParent.children;aSibling=aParents[idx];bSibling=bParents[idx];if(siblings.indexOf(aSibling)>siblings.indexOf(bSibling)){if(sharedParent===nodeB){return POSITION.FOLLOWING|POSITION.CONTAINED_BY}return POSITION.FOLLOWING}else{if(sharedParent===nodeA){return POSITION.PRECEDING|POSITION.CONTAINS}return POSITION.PRECEDING}};exports.uniqueSort=function(nodes){var idx=nodes.length,node,position;nodes=nodes.slice();while(--idx>-1){node=nodes[idx];position=nodes.indexOf(node);if(position>-1&&position<idx){nodes.splice(idx,1)}}nodes.sort(function(a,b){var relative=comparePos(a,b);if(relative&POSITION.PRECEDING){return-1}else if(relative&POSITION.FOLLOWING){return 1}return 0});return nodes}},{}],15:[function(require,module,exports){var ElementType=require("domelementtype");var isTag=exports.isTag=ElementType.isTag;exports.testElement=function(options,element){for(var key in options){if(!options.hasOwnProperty(key));else if(key==="tag_name"){if(!isTag(element)||!options.tag_name(element.name)){return false}}else if(key==="tag_type"){if(!options.tag_type(element.type))return false}else if(key==="tag_contains"){if(isTag(element)||!options.tag_contains(element.data)){return false}}else if(!element.attribs||!options[key](element.attribs[key])){return false}}return true};var Checks={tag_name:function(name){if(typeof name==="function"){return function(elem){return isTag(elem)&&name(elem.name)}}else if(name==="*"){return isTag}else{return function(elem){return isTag(elem)&&elem.name===name}}},tag_type:function(type){if(typeof type==="function"){return function(elem){return type(elem.type)}}else{return function(elem){return elem.type===type}}},tag_contains:function(data){if(typeof data==="function"){return function(elem){return!isTag(elem)&&data(elem.data)}}else{return function(elem){return!isTag(elem)&&elem.data===data}}}};function getAttribCheck(attrib,value){if(typeof value==="function"){return function(elem){return elem.attribs&&value(elem.attribs[attrib])}}else{return function(elem){return elem.attribs&&elem.attribs[attrib]===value}}}function combineFuncs(a,b){return function(elem){return a(elem)||b(elem)}}exports.getElements=function(options,element,recurse,limit){var funcs=Object.keys(options).map(function(key){var value=options[key];return key in Checks?Checks[key](value):getAttribCheck(key,value)});return funcs.length===0?[]:this.filter(funcs.reduce(combineFuncs),element,recurse,limit)};exports.getElementById=function(id,element,recurse){if(!Array.isArray(element))element=[element];return this.findOne(getAttribCheck("id",id),element,recurse!==false)};exports.getElementsByTagName=function(name,element,recurse,limit){return this.filter(Checks.tag_name(name),element,recurse,limit)};exports.getElementsByTagType=function(type,element,recurse,limit){return this.filter(Checks.tag_type(type),element,recurse,limit)}},{domelementtype:9}],16:[function(require,module,exports){exports.removeElement=function(elem){if(elem.prev)elem.prev.next=elem.next;if(elem.next)elem.next.prev=elem.prev;if(elem.parent){var childs=elem.parent.children;childs.splice(childs.lastIndexOf(elem),1)}};exports.replaceElement=function(elem,replacement){var prev=replacement.prev=elem.prev;if(prev){prev.next=replacement}var next=replacement.next=elem.next;if(next){next.prev=replacement}var parent=replacement.parent=elem.parent;if(parent){var childs=parent.children;childs[childs.lastIndexOf(elem)]=replacement}};exports.appendChild=function(elem,child){child.parent=elem;if(elem.children.push(child)!==1){var sibling=elem.children[elem.children.length-2];sibling.next=child;child.prev=sibling;child.next=null}};exports.append=function(elem,next){var parent=elem.parent,currNext=elem.next;next.next=currNext;next.prev=elem;elem.next=next;next.parent=parent;if(currNext){currNext.prev=next;if(parent){var childs=parent.children;childs.splice(childs.lastIndexOf(currNext),0,next)}}else if(parent){parent.children.push(next)}};exports.prepend=function(elem,prev){var parent=elem.parent;if(parent){var childs=parent.children;childs.splice(childs.lastIndexOf(elem),0,prev)}if(elem.prev){elem.prev.next=prev}prev.parent=parent;prev.prev=elem.prev;prev.next=elem;elem.prev=prev}},{}],17:[function(require,module,exports){var isTag=require("domelementtype").isTag;module.exports={filter:filter,find:find,findOneChild:findOneChild,findOne:findOne,existsOne:existsOne,findAll:findAll};function filter(test,element,recurse,limit){if(!Array.isArray(element))element=[element];if(typeof limit!=="number"||!isFinite(limit)){limit=Infinity}return find(test,element,recurse!==false,limit)}function find(test,elems,recurse,limit){var result=[],childs;for(var i=0,j=elems.length;i<j;i++){if(test(elems[i])){result.push(elems[i]);if(--limit<=0)break}childs=elems[i].children;if(recurse&&childs&&childs.length>0){childs=find(test,childs,recurse,limit);result=result.concat(childs);limit-=childs.length;if(limit<=0)break}}return result}function findOneChild(test,elems){for(var i=0,l=elems.length;i<l;i++){if(test(elems[i]))return elems[i]}return null}function findOne(test,elems){var elem=null;for(var i=0,l=elems.length;i<l&&!elem;i++){if(!isTag(elems[i])){continue}else if(test(elems[i])){elem=elems[i]}else if(elems[i].children.length>0){elem=findOne(test,elems[i].children)}}return elem}function existsOne(test,elems){for(var i=0,l=elems.length;i<l;i++){if(isTag(elems[i])&&(test(elems[i])||elems[i].children.length>0&&existsOne(test,elems[i].children))){return true}}return false}function findAll(test,elems){var result=[];for(var i=0,j=elems.length;i<j;i++){if(!isTag(elems[i]))continue;if(test(elems[i]))result.push(elems[i]);if(elems[i].children.length>0){result=result.concat(findAll(test,elems[i].children))}}return result}},{domelementtype:9}],18:[function(require,module,exports){var ElementType=require("domelementtype"),getOuterHTML=require("dom-serializer"),isTag=ElementType.isTag;module.exports={getInnerHTML:getInnerHTML,getOuterHTML:getOuterHTML,getText:getText};function getInnerHTML(elem,opts){return elem.children?elem.children.map(function(elem){return getOuterHTML(elem,opts)}).join(""):""}function getText(elem){if(Array.isArray(elem))return elem.map(getText).join("");if(isTag(elem)||elem.type===ElementType.CDATA)return getText(elem.children);if(elem.type===ElementType.Text)return elem.data;return""}},{"dom-serializer":7,domelementtype:9}],19:[function(require,module,exports){var getChildren=exports.getChildren=function(elem){return elem.children};var getParent=exports.getParent=function(elem){return elem.parent};exports.getSiblings=function(elem){var parent=getParent(elem);return parent?getChildren(parent):[elem]};exports.getAttributeValue=function(elem,name){return elem.attribs&&elem.attribs[name]};exports.hasAttrib=function(elem,name){return!!elem.attribs&&hasOwnProperty.call(elem.attribs,name)};exports.getName=function(elem){return elem.name}},{}],20:[function(require,module,exports){var encode=require("./lib/encode.js"),decode=require("./lib/decode.js");exports.decode=function(data,level){return(!level||level<=0?decode.XML:decode.HTML)(data)};exports.decodeStrict=function(data,level){return(!level||level<=0?decode.XML:decode.HTMLStrict)(data)};exports.encode=function(data,level){return(!level||level<=0?encode.XML:encode.HTML)(data)};exports.encodeXML=encode.XML;exports.encodeHTML4=exports.encodeHTML5=exports.encodeHTML=encode.HTML;exports.decodeXML=exports.decodeXMLStrict=decode.XML;exports.decodeHTML4=exports.decodeHTML5=exports.decodeHTML=decode.HTML;exports.decodeHTML4Strict=exports.decodeHTML5Strict=exports.decodeHTMLStrict=decode.HTMLStrict;exports.escape=encode.escape},{"./lib/decode.js":21,"./lib/encode.js":23}],21:[function(require,module,exports){var entityMap=require("../maps/entities.json"),legacyMap=require("../maps/legacy.json"),xmlMap=require("../maps/xml.json"),decodeCodePoint=require("./decode_codepoint.js");var decodeXMLStrict=getStrictDecoder(xmlMap),decodeHTMLStrict=getStrictDecoder(entityMap);function getStrictDecoder(map){var keys=Object.keys(map).join("|"),replace=getReplacer(map);keys+="|#[xX][\\da-fA-F]+|#\\d+";var re=new RegExp("&(?:"+keys+");","g");return function(str){return String(str).replace(re,replace)}}var decodeHTML=function(){var legacy=Object.keys(legacyMap).sort(sorter);var keys=Object.keys(entityMap).sort(sorter);for(var i=0,j=0;i<keys.length;i++){if(legacy[j]===keys[i]){keys[i]+=";?";j++}else{keys[i]+=";"}}var re=new RegExp("&(?:"+keys.join("|")+"|#[xX][\\da-fA-F]+;?|#\\d+;?)","g"),replace=getReplacer(entityMap);function replacer(str){if(str.substr(-1)!==";")str+=";";return replace(str)}return function(str){return String(str).replace(re,replacer)}}();function sorter(a,b){return a<b?1:-1}function getReplacer(map){return function replace(str){if(str.charAt(1)==="#"){if(str.charAt(2)==="X"||str.charAt(2)==="x"){return decodeCodePoint(parseInt(str.substr(3),16))}return decodeCodePoint(parseInt(str.substr(2),10))}return map[str.slice(1,-1)];
+}}module.exports={XML:decodeXMLStrict,HTML:decodeHTML,HTMLStrict:decodeHTMLStrict}},{"../maps/entities.json":25,"../maps/legacy.json":26,"../maps/xml.json":27,"./decode_codepoint.js":22}],22:[function(require,module,exports){var decodeMap=require("../maps/decode.json");module.exports=decodeCodePoint;function decodeCodePoint(codePoint){if(codePoint>=55296&&codePoint<=57343||codePoint>1114111){return"�"}if(codePoint in decodeMap){codePoint=decodeMap[codePoint]}var output="";if(codePoint>65535){codePoint-=65536;output+=String.fromCharCode(codePoint>>>10&1023|55296);codePoint=56320|codePoint&1023}output+=String.fromCharCode(codePoint);return output}},{"../maps/decode.json":24}],23:[function(require,module,exports){var inverseXML=getInverseObj(require("../maps/xml.json")),xmlReplacer=getInverseReplacer(inverseXML);exports.XML=getInverse(inverseXML,xmlReplacer);var inverseHTML=getInverseObj(require("../maps/entities.json")),htmlReplacer=getInverseReplacer(inverseHTML);exports.HTML=getInverse(inverseHTML,htmlReplacer);function getInverseObj(obj){return Object.keys(obj).sort().reduce(function(inverse,name){inverse[obj[name]]="&"+name+";";return inverse},{})}function getInverseReplacer(inverse){var single=[],multiple=[];Object.keys(inverse).forEach(function(k){if(k.length===1){single.push("\\"+k)}else{multiple.push(k)}});multiple.unshift("["+single.join("")+"]");return new RegExp(multiple.join("|"),"g")}var re_nonASCII=/[^\0-\x7F]/g,re_astralSymbols=/[\uD800-\uDBFF][\uDC00-\uDFFF]/g;function singleCharReplacer(c){return"&#x"+c.charCodeAt(0).toString(16).toUpperCase()+";"}function astralReplacer(c){var high=c.charCodeAt(0);var low=c.charCodeAt(1);var codePoint=(high-55296)*1024+low-56320+65536;return"&#x"+codePoint.toString(16).toUpperCase()+";"}function getInverse(inverse,re){function func(name){return inverse[name]}return function(data){return data.replace(re,func).replace(re_astralSymbols,astralReplacer).replace(re_nonASCII,singleCharReplacer)}}var re_xmlChars=getInverseReplacer(inverseXML);function escapeXML(data){return data.replace(re_xmlChars,singleCharReplacer).replace(re_astralSymbols,astralReplacer).replace(re_nonASCII,singleCharReplacer)}exports.escape=escapeXML},{"../maps/entities.json":25,"../maps/xml.json":27}],24:[function(require,module,exports){module.exports={0:65533,128:8364,130:8218,131:402,132:8222,133:8230,134:8224,135:8225,136:710,137:8240,138:352,139:8249,140:338,142:381,145:8216,146:8217,147:8220,148:8221,149:8226,150:8211,151:8212,152:732,153:8482,154:353,155:8250,156:339,158:382,159:376}},{}],25:[function(require,module,exports){module.exports={Aacute:"Á",aacute:"á",Abreve:"Ă",abreve:"ă",ac:"∾",acd:"∿",acE:"∾̳",Acirc:"Â",acirc:"â",acute:"´",Acy:"А",acy:"а",AElig:"Æ",aelig:"æ",af:"⁡",Afr:"𝔄",afr:"𝔞",Agrave:"À",agrave:"à",alefsym:"ℵ",aleph:"ℵ",Alpha:"Α",alpha:"α",Amacr:"Ā",amacr:"ā",amalg:"⨿",amp:"&",AMP:"&",andand:"⩕",And:"⩓",and:"∧",andd:"⩜",andslope:"⩘",andv:"⩚",ang:"∠",ange:"⦤",angle:"∠",angmsdaa:"⦨",angmsdab:"⦩",angmsdac:"⦪",angmsdad:"⦫",angmsdae:"⦬",angmsdaf:"⦭",angmsdag:"⦮",angmsdah:"⦯",angmsd:"∡",angrt:"∟",angrtvb:"⊾",angrtvbd:"⦝",angsph:"∢",angst:"Å",angzarr:"⍼",Aogon:"Ą",aogon:"ą",Aopf:"𝔸",aopf:"𝕒",apacir:"⩯",ap:"≈",apE:"⩰",ape:"≊",apid:"≋",apos:"'",ApplyFunction:"⁡",approx:"≈",approxeq:"≊",Aring:"Å",aring:"å",Ascr:"𝒜",ascr:"𝒶",Assign:"≔",ast:"*",asymp:"≈",asympeq:"≍",Atilde:"Ã",atilde:"ã",Auml:"Ä",auml:"ä",awconint:"∳",awint:"⨑",backcong:"≌",backepsilon:"϶",backprime:"‵",backsim:"∽",backsimeq:"⋍",Backslash:"∖",Barv:"⫧",barvee:"⊽",barwed:"⌅",Barwed:"⌆",barwedge:"⌅",bbrk:"⎵",bbrktbrk:"⎶",bcong:"≌",Bcy:"Б",bcy:"б",bdquo:"„",becaus:"∵",because:"∵",Because:"∵",bemptyv:"⦰",bepsi:"϶",bernou:"ℬ",Bernoullis:"ℬ",Beta:"Β",beta:"β",beth:"ℶ",between:"≬",Bfr:"𝔅",bfr:"𝔟",bigcap:"⋂",bigcirc:"◯",bigcup:"⋃",bigodot:"⨀",bigoplus:"⨁",bigotimes:"⨂",bigsqcup:"⨆",bigstar:"★",bigtriangledown:"▽",bigtriangleup:"△",biguplus:"⨄",bigvee:"⋁",bigwedge:"⋀",bkarow:"⤍",blacklozenge:"⧫",blacksquare:"▪",blacktriangle:"▴",blacktriangledown:"▾",blacktriangleleft:"◂",blacktriangleright:"▸",blank:"␣",blk12:"▒",blk14:"░",blk34:"▓",block:"█",bne:"=⃥",bnequiv:"≡⃥",bNot:"⫭",bnot:"⌐",Bopf:"𝔹",bopf:"𝕓",bot:"⊥",bottom:"⊥",bowtie:"⋈",boxbox:"⧉",boxdl:"┐",boxdL:"╕",boxDl:"╖",boxDL:"╗",boxdr:"┌",boxdR:"╒",boxDr:"╓",boxDR:"╔",boxh:"─",boxH:"═",boxhd:"┬",boxHd:"╤",boxhD:"╥",boxHD:"╦",boxhu:"┴",boxHu:"╧",boxhU:"╨",boxHU:"╩",boxminus:"⊟",boxplus:"⊞",boxtimes:"⊠",boxul:"┘",boxuL:"╛",boxUl:"╜",boxUL:"╝",boxur:"└",boxuR:"╘",boxUr:"╙",boxUR:"╚",boxv:"│",boxV:"║",boxvh:"┼",boxvH:"╪",boxVh:"╫",boxVH:"╬",boxvl:"┤",boxvL:"╡",boxVl:"╢",boxVL:"╣",boxvr:"├",boxvR:"╞",boxVr:"╟",boxVR:"╠",bprime:"‵",breve:"˘",Breve:"˘",brvbar:"¦",bscr:"𝒷",Bscr:"ℬ",bsemi:"⁏",bsim:"∽",bsime:"⋍",bsolb:"⧅",bsol:"\\",bsolhsub:"⟈",bull:"•",bullet:"•",bump:"≎",bumpE:"⪮",bumpe:"≏",Bumpeq:"≎",bumpeq:"≏",Cacute:"Ć",cacute:"ć",capand:"⩄",capbrcup:"⩉",capcap:"⩋",cap:"∩",Cap:"⋒",capcup:"⩇",capdot:"⩀",CapitalDifferentialD:"ⅅ",caps:"∩︀",caret:"⁁",caron:"ˇ",Cayleys:"ℭ",ccaps:"⩍",Ccaron:"Č",ccaron:"č",Ccedil:"Ç",ccedil:"ç",Ccirc:"Ĉ",ccirc:"ĉ",Cconint:"∰",ccups:"⩌",ccupssm:"⩐",Cdot:"Ċ",cdot:"ċ",cedil:"¸",Cedilla:"¸",cemptyv:"⦲",cent:"¢",centerdot:"·",CenterDot:"·",cfr:"𝔠",Cfr:"ℭ",CHcy:"Ч",chcy:"ч",check:"✓",checkmark:"✓",Chi:"Χ",chi:"χ",circ:"ˆ",circeq:"≗",circlearrowleft:"↺",circlearrowright:"↻",circledast:"⊛",circledcirc:"⊚",circleddash:"⊝",CircleDot:"⊙",circledR:"®",circledS:"Ⓢ",CircleMinus:"⊖",CirclePlus:"⊕",CircleTimes:"⊗",cir:"○",cirE:"⧃",cire:"≗",cirfnint:"⨐",cirmid:"⫯",cirscir:"⧂",ClockwiseContourIntegral:"∲",CloseCurlyDoubleQuote:"”",CloseCurlyQuote:"’",clubs:"♣",clubsuit:"♣",colon:":",Colon:"∷",Colone:"⩴",colone:"≔",coloneq:"≔",comma:",",commat:"@",comp:"∁",compfn:"∘",complement:"∁",complexes:"ℂ",cong:"≅",congdot:"⩭",Congruent:"≡",conint:"∮",Conint:"∯",ContourIntegral:"∮",copf:"𝕔",Copf:"ℂ",coprod:"∐",Coproduct:"∐",copy:"©",COPY:"©",copysr:"℗",CounterClockwiseContourIntegral:"∳",crarr:"↵",cross:"✗",Cross:"⨯",Cscr:"𝒞",cscr:"𝒸",csub:"⫏",csube:"⫑",csup:"⫐",csupe:"⫒",ctdot:"⋯",cudarrl:"⤸",cudarrr:"⤵",cuepr:"⋞",cuesc:"⋟",cularr:"↶",cularrp:"⤽",cupbrcap:"⩈",cupcap:"⩆",CupCap:"≍",cup:"∪",Cup:"⋓",cupcup:"⩊",cupdot:"⊍",cupor:"⩅",cups:"∪︀",curarr:"↷",curarrm:"⤼",curlyeqprec:"⋞",curlyeqsucc:"⋟",curlyvee:"⋎",curlywedge:"⋏",curren:"¤",curvearrowleft:"↶",curvearrowright:"↷",cuvee:"⋎",cuwed:"⋏",cwconint:"∲",cwint:"∱",cylcty:"⌭",dagger:"†",Dagger:"‡",daleth:"ℸ",darr:"↓",Darr:"↡",dArr:"⇓",dash:"‐",Dashv:"⫤",dashv:"⊣",dbkarow:"⤏",dblac:"˝",Dcaron:"Ď",dcaron:"ď",Dcy:"Д",dcy:"д",ddagger:"‡",ddarr:"⇊",DD:"ⅅ",dd:"ⅆ",DDotrahd:"⤑",ddotseq:"⩷",deg:"°",Del:"∇",Delta:"Δ",delta:"δ",demptyv:"⦱",dfisht:"⥿",Dfr:"𝔇",dfr:"𝔡",dHar:"⥥",dharl:"⇃",dharr:"⇂",DiacriticalAcute:"´",DiacriticalDot:"˙",DiacriticalDoubleAcute:"˝",DiacriticalGrave:"`",DiacriticalTilde:"˜",diam:"⋄",diamond:"⋄",Diamond:"⋄",diamondsuit:"♦",diams:"♦",die:"¨",DifferentialD:"ⅆ",digamma:"ϝ",disin:"⋲",div:"÷",divide:"÷",divideontimes:"⋇",divonx:"⋇",DJcy:"Ђ",djcy:"ђ",dlcorn:"⌞",dlcrop:"⌍",dollar:"$",Dopf:"𝔻",dopf:"𝕕",Dot:"¨",dot:"˙",DotDot:"⃜",doteq:"≐",doteqdot:"≑",DotEqual:"≐",dotminus:"∸",dotplus:"∔",dotsquare:"⊡",doublebarwedge:"⌆",DoubleContourIntegral:"∯",DoubleDot:"¨",DoubleDownArrow:"⇓",DoubleLeftArrow:"⇐",DoubleLeftRightArrow:"⇔",DoubleLeftTee:"⫤",DoubleLongLeftArrow:"⟸",DoubleLongLeftRightArrow:"⟺",DoubleLongRightArrow:"⟹",DoubleRightArrow:"⇒",DoubleRightTee:"⊨",DoubleUpArrow:"⇑",DoubleUpDownArrow:"⇕",DoubleVerticalBar:"∥",DownArrowBar:"⤓",downarrow:"↓",DownArrow:"↓",Downarrow:"⇓",DownArrowUpArrow:"⇵",DownBreve:"̑",downdownarrows:"⇊",downharpoonleft:"⇃",downharpoonright:"⇂",DownLeftRightVector:"⥐",DownLeftTeeVector:"⥞",DownLeftVectorBar:"⥖",DownLeftVector:"↽",DownRightTeeVector:"⥟",DownRightVectorBar:"⥗",DownRightVector:"⇁",DownTeeArrow:"↧",DownTee:"⊤",drbkarow:"⤐",drcorn:"⌟",drcrop:"⌌",Dscr:"𝒟",dscr:"𝒹",DScy:"Ѕ",dscy:"ѕ",dsol:"⧶",Dstrok:"Đ",dstrok:"đ",dtdot:"⋱",dtri:"▿",dtrif:"▾",duarr:"⇵",duhar:"⥯",dwangle:"⦦",DZcy:"Џ",dzcy:"џ",dzigrarr:"⟿",Eacute:"É",eacute:"é",easter:"⩮",Ecaron:"Ě",ecaron:"ě",Ecirc:"Ê",ecirc:"ê",ecir:"≖",ecolon:"≕",Ecy:"Э",ecy:"э",eDDot:"⩷",Edot:"Ė",edot:"ė",eDot:"≑",ee:"ⅇ",efDot:"≒",Efr:"𝔈",efr:"𝔢",eg:"⪚",Egrave:"È",egrave:"è",egs:"⪖",egsdot:"⪘",el:"⪙",Element:"∈",elinters:"⏧",ell:"ℓ",els:"⪕",elsdot:"⪗",Emacr:"Ē",emacr:"ē",empty:"∅",emptyset:"∅",EmptySmallSquare:"◻",emptyv:"∅",EmptyVerySmallSquare:"▫",emsp13:" ",emsp14:" ",emsp:" ",ENG:"Ŋ",eng:"ŋ",ensp:" ",Eogon:"Ę",eogon:"ę",Eopf:"𝔼",eopf:"𝕖",epar:"⋕",eparsl:"⧣",eplus:"⩱",epsi:"ε",Epsilon:"Ε",epsilon:"ε",epsiv:"ϵ",eqcirc:"≖",eqcolon:"≕",eqsim:"≂",eqslantgtr:"⪖",eqslantless:"⪕",Equal:"⩵",equals:"=",EqualTilde:"≂",equest:"≟",Equilibrium:"⇌",equiv:"≡",equivDD:"⩸",eqvparsl:"⧥",erarr:"⥱",erDot:"≓",escr:"ℯ",Escr:"ℰ",esdot:"≐",Esim:"⩳",esim:"≂",Eta:"Η",eta:"η",ETH:"Ð",eth:"ð",Euml:"Ë",euml:"ë",euro:"€",excl:"!",exist:"∃",Exists:"∃",expectation:"ℰ",exponentiale:"ⅇ",ExponentialE:"ⅇ",fallingdotseq:"≒",Fcy:"Ф",fcy:"ф",female:"♀",ffilig:"ffi",fflig:"ff",ffllig:"ffl",Ffr:"𝔉",ffr:"𝔣",filig:"fi",FilledSmallSquare:"◼",FilledVerySmallSquare:"▪",fjlig:"fj",flat:"♭",fllig:"fl",fltns:"▱",fnof:"ƒ",Fopf:"𝔽",fopf:"𝕗",forall:"∀",ForAll:"∀",fork:"⋔",forkv:"⫙",Fouriertrf:"ℱ",fpartint:"⨍",frac12:"½",frac13:"⅓",frac14:"¼",frac15:"⅕",frac16:"⅙",frac18:"⅛",frac23:"⅔",frac25:"⅖",frac34:"¾",frac35:"⅗",frac38:"⅜",frac45:"⅘",frac56:"⅚",frac58:"⅝",frac78:"⅞",frasl:"⁄",frown:"⌢",fscr:"𝒻",Fscr:"ℱ",gacute:"ǵ",Gamma:"Γ",gamma:"γ",Gammad:"Ϝ",gammad:"ϝ",gap:"⪆",Gbreve:"Ğ",gbreve:"ğ",Gcedil:"Ģ",Gcirc:"Ĝ",gcirc:"ĝ",Gcy:"Г",gcy:"г",Gdot:"Ġ",gdot:"ġ",ge:"≥",gE:"≧",gEl:"⪌",gel:"⋛",geq:"≥",geqq:"≧",geqslant:"⩾",gescc:"⪩",ges:"⩾",gesdot:"⪀",gesdoto:"⪂",gesdotol:"⪄",gesl:"⋛︀",gesles:"⪔",Gfr:"𝔊",gfr:"𝔤",gg:"≫",Gg:"⋙",ggg:"⋙",gimel:"ℷ",GJcy:"Ѓ",gjcy:"ѓ",gla:"⪥",gl:"≷",glE:"⪒",glj:"⪤",gnap:"⪊",gnapprox:"⪊",gne:"⪈",gnE:"≩",gneq:"⪈",gneqq:"≩",gnsim:"⋧",Gopf:"𝔾",gopf:"𝕘",grave:"`",GreaterEqual:"≥",GreaterEqualLess:"⋛",GreaterFullEqual:"≧",GreaterGreater:"⪢",GreaterLess:"≷",GreaterSlantEqual:"⩾",GreaterTilde:"≳",Gscr:"𝒢",gscr:"ℊ",gsim:"≳",gsime:"⪎",gsiml:"⪐",gtcc:"⪧",gtcir:"⩺",gt:">",GT:">",Gt:"≫",gtdot:"⋗",gtlPar:"⦕",gtquest:"⩼",gtrapprox:"⪆",gtrarr:"⥸",gtrdot:"⋗",gtreqless:"⋛",gtreqqless:"⪌",gtrless:"≷",gtrsim:"≳",gvertneqq:"≩︀",gvnE:"≩︀",Hacek:"ˇ",hairsp:" ",half:"½",hamilt:"ℋ",HARDcy:"Ъ",hardcy:"ъ",harrcir:"⥈",harr:"↔",hArr:"⇔",harrw:"↭",Hat:"^",hbar:"ℏ",Hcirc:"Ĥ",hcirc:"ĥ",hearts:"♥",heartsuit:"♥",hellip:"…",hercon:"⊹",hfr:"𝔥",Hfr:"ℌ",HilbertSpace:"ℋ",hksearow:"⤥",hkswarow:"⤦",hoarr:"⇿",homtht:"∻",hookleftarrow:"↩",hookrightarrow:"↪",hopf:"𝕙",Hopf:"ℍ",horbar:"―",HorizontalLine:"─",hscr:"𝒽",Hscr:"ℋ",hslash:"ℏ",Hstrok:"Ħ",hstrok:"ħ",HumpDownHump:"≎",HumpEqual:"≏",hybull:"⁃",hyphen:"‐",Iacute:"Í",iacute:"í",ic:"⁣",Icirc:"Î",icirc:"î",Icy:"И",icy:"и",Idot:"İ",IEcy:"Е",iecy:"е",iexcl:"¡",iff:"⇔",ifr:"𝔦",Ifr:"ℑ",Igrave:"Ì",igrave:"ì",ii:"ⅈ",iiiint:"⨌",iiint:"∭",iinfin:"⧜",iiota:"℩",IJlig:"IJ",ijlig:"ij",Imacr:"Ī",imacr:"ī",image:"ℑ",ImaginaryI:"ⅈ",imagline:"ℐ",imagpart:"ℑ",imath:"ı",Im:"ℑ",imof:"⊷",imped:"Ƶ",Implies:"⇒",incare:"℅",in:"∈",infin:"∞",infintie:"⧝",inodot:"ı",intcal:"⊺",int:"∫",Int:"∬",integers:"ℤ",Integral:"∫",intercal:"⊺",Intersection:"⋂",intlarhk:"⨗",intprod:"⨼",InvisibleComma:"⁣",InvisibleTimes:"⁢",IOcy:"Ё",iocy:"ё",Iogon:"Į",iogon:"į",Iopf:"𝕀",iopf:"𝕚",Iota:"Ι",iota:"ι",iprod:"⨼",iquest:"¿",iscr:"𝒾",Iscr:"ℐ",isin:"∈",isindot:"⋵",isinE:"⋹",isins:"⋴",isinsv:"⋳",isinv:"∈",it:"⁢",Itilde:"Ĩ",itilde:"ĩ",Iukcy:"І",iukcy:"і",Iuml:"Ï",iuml:"ï",Jcirc:"Ĵ",jcirc:"ĵ",Jcy:"Й",jcy:"й",Jfr:"𝔍",jfr:"𝔧",jmath:"ȷ",Jopf:"𝕁",jopf:"𝕛",Jscr:"𝒥",jscr:"𝒿",Jsercy:"Ј",jsercy:"ј",Jukcy:"Є",jukcy:"є",Kappa:"Κ",kappa:"κ",kappav:"ϰ",Kcedil:"Ķ",kcedil:"ķ",Kcy:"К",kcy:"к",Kfr:"𝔎",kfr:"𝔨",kgreen:"ĸ",KHcy:"Х",khcy:"х",KJcy:"Ќ",kjcy:"ќ",Kopf:"𝕂",kopf:"𝕜",Kscr:"𝒦",kscr:"𝓀",lAarr:"⇚",Lacute:"Ĺ",lacute:"ĺ",laemptyv:"⦴",lagran:"ℒ",Lambda:"Λ",lambda:"λ",lang:"⟨",Lang:"⟪",langd:"⦑",langle:"⟨",lap:"⪅",Laplacetrf:"ℒ",laquo:"«",larrb:"⇤",larrbfs:"⤟",larr:"←",Larr:"↞",lArr:"⇐",larrfs:"⤝",larrhk:"↩",larrlp:"↫",larrpl:"⤹",larrsim:"⥳",larrtl:"↢",latail:"⤙",lAtail:"⤛",lat:"⪫",late:"⪭",lates:"⪭︀",lbarr:"⤌",lBarr:"⤎",lbbrk:"❲",lbrace:"{",lbrack:"[",lbrke:"⦋",lbrksld:"⦏",lbrkslu:"⦍",Lcaron:"Ľ",lcaron:"ľ",Lcedil:"Ļ",lcedil:"ļ",lceil:"⌈",lcub:"{",Lcy:"Л",lcy:"л",ldca:"⤶",ldquo:"“",ldquor:"„",ldrdhar:"⥧",ldrushar:"⥋",ldsh:"↲",le:"≤",lE:"≦",LeftAngleBracket:"⟨",LeftArrowBar:"⇤",leftarrow:"←",LeftArrow:"←",Leftarrow:"⇐",LeftArrowRightArrow:"⇆",leftarrowtail:"↢",LeftCeiling:"⌈",LeftDoubleBracket:"⟦",LeftDownTeeVector:"⥡",LeftDownVectorBar:"⥙",LeftDownVector:"⇃",LeftFloor:"⌊",leftharpoondown:"↽",leftharpoonup:"↼",leftleftarrows:"⇇",leftrightarrow:"↔",LeftRightArrow:"↔",Leftrightarrow:"⇔",leftrightarrows:"⇆",leftrightharpoons:"⇋",leftrightsquigarrow:"↭",LeftRightVector:"⥎",LeftTeeArrow:"↤",LeftTee:"⊣",LeftTeeVector:"⥚",leftthreetimes:"⋋",LeftTriangleBar:"⧏",LeftTriangle:"⊲",LeftTriangleEqual:"⊴",LeftUpDownVector:"⥑",LeftUpTeeVector:"⥠",LeftUpVectorBar:"⥘",LeftUpVector:"↿",LeftVectorBar:"⥒",LeftVector:"↼",lEg:"⪋",leg:"⋚",leq:"≤",leqq:"≦",leqslant:"⩽",lescc:"⪨",les:"⩽",lesdot:"⩿",lesdoto:"⪁",lesdotor:"⪃",lesg:"⋚︀",lesges:"⪓",lessapprox:"⪅",lessdot:"⋖",lesseqgtr:"⋚",lesseqqgtr:"⪋",LessEqualGreater:"⋚",LessFullEqual:"≦",LessGreater:"≶",lessgtr:"≶",LessLess:"⪡",lesssim:"≲",LessSlantEqual:"⩽",LessTilde:"≲",lfisht:"⥼",lfloor:"⌊",Lfr:"𝔏",lfr:"𝔩",lg:"≶",lgE:"⪑",lHar:"⥢",lhard:"↽",lharu:"↼",lharul:"⥪",lhblk:"▄",LJcy:"Љ",ljcy:"љ",llarr:"⇇",ll:"≪",Ll:"⋘",llcorner:"⌞",Lleftarrow:"⇚",llhard:"⥫",lltri:"◺",Lmidot:"Ŀ",lmidot:"ŀ",lmoustache:"⎰",lmoust:"⎰",lnap:"⪉",lnapprox:"⪉",lne:"⪇",lnE:"≨",lneq:"⪇",lneqq:"≨",lnsim:"⋦",loang:"⟬",loarr:"⇽",lobrk:"⟦",longleftarrow:"⟵",LongLeftArrow:"⟵",Longleftarrow:"⟸",longleftrightarrow:"⟷",LongLeftRightArrow:"⟷",Longleftrightarrow:"⟺",longmapsto:"⟼",longrightarrow:"⟶",LongRightArrow:"⟶",Longrightarrow:"⟹",looparrowleft:"↫",looparrowright:"↬",lopar:"⦅",Lopf:"𝕃",lopf:"𝕝",loplus:"⨭",lotimes:"⨴",lowast:"∗",lowbar:"_",LowerLeftArrow:"↙",LowerRightArrow:"↘",loz:"◊",lozenge:"◊",lozf:"⧫",lpar:"(",lparlt:"⦓",lrarr:"⇆",lrcorner:"⌟",lrhar:"⇋",lrhard:"⥭",lrm:"‎",lrtri:"⊿",lsaquo:"‹",lscr:"𝓁",Lscr:"ℒ",lsh:"↰",Lsh:"↰",lsim:"≲",lsime:"⪍",lsimg:"⪏",lsqb:"[",lsquo:"‘",lsquor:"‚",Lstrok:"Ł",lstrok:"ł",ltcc:"⪦",ltcir:"⩹",lt:"<",LT:"<",Lt:"≪",ltdot:"⋖",lthree:"⋋",ltimes:"⋉",ltlarr:"⥶",ltquest:"⩻",ltri:"◃",ltrie:"⊴",ltrif:"◂",ltrPar:"⦖",lurdshar:"⥊",luruhar:"⥦",lvertneqq:"≨︀",lvnE:"≨︀",macr:"¯",male:"♂",malt:"✠",maltese:"✠",Map:"⤅",map:"↦",mapsto:"↦",mapstodown:"↧",mapstoleft:"↤",mapstoup:"↥",marker:"▮",mcomma:"⨩",Mcy:"М",mcy:"м",mdash:"—",mDDot:"∺",measuredangle:"∡",MediumSpace:" ",Mellintrf:"ℳ",Mfr:"𝔐",mfr:"𝔪",mho:"℧",micro:"µ",midast:"*",midcir:"⫰",mid:"∣",middot:"·",minusb:"⊟",minus:"−",minusd:"∸",minusdu:"⨪",MinusPlus:"∓",mlcp:"⫛",mldr:"…",mnplus:"∓",models:"⊧",Mopf:"𝕄",mopf:"𝕞",mp:"∓",mscr:"𝓂",Mscr:"ℳ",mstpos:"∾",Mu:"Μ",mu:"μ",multimap:"⊸",mumap:"⊸",nabla:"∇",Nacute:"Ń",nacute:"ń",nang:"∠⃒",nap:"≉",napE:"⩰̸",napid:"≋̸",napos:"ʼn",napprox:"≉",natural:"♮",naturals:"ℕ",natur:"♮",nbsp:" ",nbump:"≎̸",nbumpe:"≏̸",ncap:"⩃",Ncaron:"Ň",ncaron:"ň",Ncedil:"Ņ",ncedil:"ņ",ncong:"≇",ncongdot:"⩭̸",ncup:"⩂",Ncy:"Н",ncy:"н",ndash:"–",nearhk:"⤤",nearr:"↗",neArr:"⇗",nearrow:"↗",ne:"≠",nedot:"≐̸",NegativeMediumSpace:"​",NegativeThickSpace:"​",NegativeThinSpace:"​",NegativeVeryThinSpace:"​",nequiv:"≢",nesear:"⤨",nesim:"≂̸",NestedGreaterGreater:"≫",NestedLessLess:"≪",NewLine:"\n",nexist:"∄",nexists:"∄",Nfr:"𝔑",nfr:"𝔫",ngE:"≧̸",nge:"≱",ngeq:"≱",ngeqq:"≧̸",ngeqslant:"⩾̸",nges:"⩾̸",nGg:"⋙̸",ngsim:"≵",nGt:"≫⃒",ngt:"≯",ngtr:"≯",nGtv:"≫̸",nharr:"↮",nhArr:"⇎",nhpar:"⫲",ni:"∋",nis:"⋼",nisd:"⋺",niv:"∋",NJcy:"Њ",njcy:"њ",nlarr:"↚",nlArr:"⇍",nldr:"‥",nlE:"≦̸",nle:"≰",nleftarrow:"↚",nLeftarrow:"⇍",nleftrightarrow:"↮",nLeftrightarrow:"⇎",nleq:"≰",nleqq:"≦̸",nleqslant:"⩽̸",nles:"⩽̸",nless:"≮",nLl:"⋘̸",nlsim:"≴",nLt:"≪⃒",nlt:"≮",nltri:"⋪",nltrie:"⋬",nLtv:"≪̸",nmid:"∤",NoBreak:"⁠",NonBreakingSpace:" ",nopf:"𝕟",Nopf:"ℕ",Not:"⫬",not:"¬",NotCongruent:"≢",NotCupCap:"≭",NotDoubleVerticalBar:"∦",NotElement:"∉",NotEqual:"≠",NotEqualTilde:"≂̸",NotExists:"∄",NotGreater:"≯",NotGreaterEqual:"≱",NotGreaterFullEqual:"≧̸",NotGreaterGreater:"≫̸",NotGreaterLess:"≹",NotGreaterSlantEqual:"⩾̸",NotGreaterTilde:"≵",NotHumpDownHump:"≎̸",NotHumpEqual:"≏̸",notin:"∉",notindot:"⋵̸",notinE:"⋹̸",notinva:"∉",notinvb:"⋷",notinvc:"⋶",NotLeftTriangleBar:"⧏̸",NotLeftTriangle:"⋪",NotLeftTriangleEqual:"⋬",NotLess:"≮",NotLessEqual:"≰",NotLessGreater:"≸",NotLessLess:"≪̸",NotLessSlantEqual:"⩽̸",NotLessTilde:"≴",NotNestedGreaterGreater:"⪢̸",NotNestedLessLess:"⪡̸",notni:"∌",notniva:"∌",notnivb:"⋾",notnivc:"⋽",NotPrecedes:"⊀",NotPrecedesEqual:"⪯̸",NotPrecedesSlantEqual:"⋠",NotReverseElement:"∌",NotRightTriangleBar:"⧐̸",NotRightTriangle:"⋫",NotRightTriangleEqual:"⋭",NotSquareSubset:"⊏̸",NotSquareSubsetEqual:"⋢",NotSquareSuperset:"⊐̸",NotSquareSupersetEqual:"⋣",NotSubset:"⊂⃒",NotSubsetEqual:"⊈",NotSucceeds:"⊁",NotSucceedsEqual:"⪰̸",NotSucceedsSlantEqual:"⋡",NotSucceedsTilde:"≿̸",NotSuperset:"⊃⃒",NotSupersetEqual:"⊉",NotTilde:"≁",NotTildeEqual:"≄",NotTildeFullEqual:"≇",NotTildeTilde:"≉",NotVerticalBar:"∤",nparallel:"∦",npar:"∦",nparsl:"⫽⃥",npart:"∂̸",npolint:"⨔",npr:"⊀",nprcue:"⋠",nprec:"⊀",npreceq:"⪯̸",npre:"⪯̸",nrarrc:"⤳̸",nrarr:"↛",nrArr:"⇏",nrarrw:"↝̸",nrightarrow:"↛",nRightarrow:"⇏",nrtri:"⋫",nrtrie:"⋭",nsc:"⊁",nsccue:"⋡",nsce:"⪰̸",Nscr:"𝒩",nscr:"𝓃",nshortmid:"∤",nshortparallel:"∦",nsim:"≁",nsime:"≄",nsimeq:"≄",nsmid:"∤",nspar:"∦",nsqsube:"⋢",nsqsupe:"⋣",nsub:"⊄",nsubE:"⫅̸",nsube:"⊈",nsubset:"⊂⃒",nsubseteq:"⊈",nsubseteqq:"⫅̸",nsucc:"⊁",nsucceq:"⪰̸",nsup:"⊅",nsupE:"⫆̸",nsupe:"⊉",nsupset:"⊃⃒",nsupseteq:"⊉",nsupseteqq:"⫆̸",ntgl:"≹",Ntilde:"Ñ",ntilde:"ñ",ntlg:"≸",ntriangleleft:"⋪",ntrianglelefteq:"⋬",ntriangleright:"⋫",ntrianglerighteq:"⋭",Nu:"Ν",nu:"ν",num:"#",numero:"№",numsp:" ",nvap:"≍⃒",nvdash:"⊬",nvDash:"⊭",nVdash:"⊮",nVDash:"⊯",nvge:"≥⃒",nvgt:">⃒",nvHarr:"⤄",nvinfin:"⧞",nvlArr:"⤂",nvle:"≤⃒",nvlt:"<⃒",nvltrie:"⊴⃒",nvrArr:"⤃",nvrtrie:"⊵⃒",nvsim:"∼⃒",nwarhk:"⤣",nwarr:"↖",nwArr:"⇖",nwarrow:"↖",nwnear:"⤧",Oacute:"Ó",oacute:"ó",oast:"⊛",Ocirc:"Ô",ocirc:"ô",ocir:"⊚",Ocy:"О",ocy:"о",odash:"⊝",Odblac:"Ő",odblac:"ő",odiv:"⨸",odot:"⊙",odsold:"⦼",OElig:"Œ",oelig:"œ",ofcir:"⦿",Ofr:"𝔒",ofr:"𝔬",ogon:"˛",Ograve:"Ò",ograve:"ò",ogt:"⧁",ohbar:"⦵",ohm:"Ω",oint:"∮",olarr:"↺",olcir:"⦾",olcross:"⦻",oline:"‾",olt:"⧀",Omacr:"Ō",omacr:"ō",Omega:"Ω",omega:"ω",Omicron:"Ο",omicron:"ο",omid:"⦶",ominus:"⊖",Oopf:"𝕆",oopf:"𝕠",opar:"⦷",OpenCurlyDoubleQuote:"“",OpenCurlyQuote:"‘",operp:"⦹",oplus:"⊕",orarr:"↻",Or:"⩔",or:"∨",ord:"⩝",order:"ℴ",orderof:"ℴ",ordf:"ª",ordm:"º",origof:"⊶",oror:"⩖",orslope:"⩗",orv:"⩛",oS:"Ⓢ",Oscr:"𝒪",oscr:"ℴ",Oslash:"Ø",oslash:"ø",osol:"⊘",Otilde:"Õ",otilde:"õ",otimesas:"⨶",Otimes:"⨷",otimes:"⊗",Ouml:"Ö",ouml:"ö",ovbar:"⌽",OverBar:"‾",OverBrace:"⏞",OverBracket:"⎴",OverParenthesis:"⏜",para:"¶",parallel:"∥",par:"∥",parsim:"⫳",parsl:"⫽",part:"∂",PartialD:"∂",Pcy:"П",pcy:"п",percnt:"%",period:".",permil:"‰",perp:"⊥",pertenk:"‱",Pfr:"𝔓",pfr:"𝔭",Phi:"Φ",phi:"φ",phiv:"ϕ",phmmat:"ℳ",phone:"☎",Pi:"Π",pi:"π",pitchfork:"⋔",piv:"ϖ",planck:"ℏ",planckh:"ℎ",plankv:"ℏ",plusacir:"⨣",plusb:"⊞",pluscir:"⨢",plus:"+",plusdo:"∔",plusdu:"⨥",pluse:"⩲",PlusMinus:"±",plusmn:"±",plussim:"⨦",plustwo:"⨧",pm:"±",Poincareplane:"ℌ",pointint:"⨕",popf:"𝕡",Popf:"ℙ",pound:"£",prap:"⪷",Pr:"⪻",pr:"≺",prcue:"≼",precapprox:"⪷",prec:"≺",preccurlyeq:"≼",Precedes:"≺",PrecedesEqual:"⪯",PrecedesSlantEqual:"≼",PrecedesTilde:"≾",preceq:"⪯",precnapprox:"⪹",precneqq:"⪵",precnsim:"⋨",pre:"⪯",prE:"⪳",precsim:"≾",prime:"′",Prime:"″",primes:"ℙ",prnap:"⪹",prnE:"⪵",prnsim:"⋨",prod:"∏",Product:"∏",profalar:"⌮",profline:"⌒",profsurf:"⌓",prop:"∝",Proportional:"∝",Proportion:"∷",propto:"∝",prsim:"≾",prurel:"⊰",Pscr:"𝒫",pscr:"𝓅",Psi:"Ψ",psi:"ψ",puncsp:" ",Qfr:"𝔔",qfr:"𝔮",qint:"⨌",qopf:"𝕢",Qopf:"ℚ",qprime:"⁗",Qscr:"𝒬",qscr:"𝓆",quaternions:"ℍ",quatint:"⨖",quest:"?",questeq:"≟",quot:'"',QUOT:'"',rAarr:"⇛",race:"∽̱",Racute:"Ŕ",racute:"ŕ",radic:"√",raemptyv:"⦳",rang:"⟩",Rang:"⟫",rangd:"⦒",range:"⦥",rangle:"⟩",raquo:"»",rarrap:"⥵",rarrb:"⇥",rarrbfs:"⤠",rarrc:"⤳",rarr:"→",Rarr:"↠",rArr:"⇒",rarrfs:"⤞",rarrhk:"↪",rarrlp:"↬",rarrpl:"⥅",rarrsim:"⥴",Rarrtl:"⤖",rarrtl:"↣",rarrw:"↝",ratail:"⤚",rAtail:"⤜",ratio:"∶",rationals:"ℚ",rbarr:"⤍",rBarr:"⤏",RBarr:"⤐",rbbrk:"❳",rbrace:"}",rbrack:"]",rbrke:"⦌",rbrksld:"⦎",rbrkslu:"⦐",Rcaron:"Ř",rcaron:"ř",Rcedil:"Ŗ",rcedil:"ŗ",rceil:"⌉",rcub:"}",Rcy:"Р",rcy:"р",rdca:"⤷",rdldhar:"⥩",rdquo:"”",rdquor:"”",rdsh:"↳",real:"ℜ",realine:"ℛ",realpart:"ℜ",reals:"ℝ",Re:"ℜ",rect:"▭",reg:"®",REG:"®",ReverseElement:"∋",ReverseEquilibrium:"⇋",ReverseUpEquilibrium:"⥯",rfisht:"⥽",rfloor:"⌋",rfr:"𝔯",Rfr:"ℜ",rHar:"⥤",rhard:"⇁",rharu:"⇀",rharul:"⥬",Rho:"Ρ",rho:"ρ",rhov:"ϱ",RightAngleBracket:"⟩",RightArrowBar:"⇥",rightarrow:"→",RightArrow:"→",Rightarrow:"⇒",RightArrowLeftArrow:"⇄",rightarrowtail:"↣",RightCeiling:"⌉",RightDoubleBracket:"⟧",RightDownTeeVector:"⥝",RightDownVectorBar:"⥕",RightDownVector:"⇂",RightFloor:"⌋",rightharpoondown:"⇁",rightharpoonup:"⇀",rightleftarrows:"⇄",rightleftharpoons:"⇌",rightrightarrows:"⇉",rightsquigarrow:"↝",RightTeeArrow:"↦",RightTee:"⊢",RightTeeVector:"⥛",rightthreetimes:"⋌",RightTriangleBar:"⧐",RightTriangle:"⊳",RightTriangleEqual:"⊵",RightUpDownVector:"⥏",RightUpTeeVector:"⥜",RightUpVectorBar:"⥔",RightUpVector:"↾",RightVectorBar:"⥓",RightVector:"⇀",ring:"˚",risingdotseq:"≓",rlarr:"⇄",rlhar:"⇌",rlm:"‏",rmoustache:"⎱",rmoust:"⎱",rnmid:"⫮",roang:"⟭",roarr:"⇾",robrk:"⟧",ropar:"⦆",ropf:"𝕣",Ropf:"ℝ",roplus:"⨮",rotimes:"⨵",RoundImplies:"⥰",rpar:")",rpargt:"⦔",rppolint:"⨒",rrarr:"⇉",Rrightarrow:"⇛",rsaquo:"›",rscr:"𝓇",Rscr:"ℛ",rsh:"↱",Rsh:"↱",rsqb:"]",rsquo:"’",rsquor:"’",rthree:"⋌",rtimes:"⋊",rtri:"▹",rtrie:"⊵",rtrif:"▸",rtriltri:"⧎",RuleDelayed:"⧴",ruluhar:"⥨",rx:"℞",Sacute:"Ś",sacute:"ś",sbquo:"‚",scap:"⪸",Scaron:"Š",scaron:"š",Sc:"⪼",sc:"≻",sccue:"≽",sce:"⪰",scE:"⪴",Scedil:"Ş",scedil:"ş",Scirc:"Ŝ",scirc:"ŝ",scnap:"⪺",scnE:"⪶",scnsim:"⋩",scpolint:"⨓",scsim:"≿",Scy:"С",scy:"с",sdotb:"⊡",sdot:"⋅",sdote:"⩦",searhk:"⤥",searr:"↘",seArr:"⇘",searrow:"↘",sect:"§",semi:";",seswar:"⤩",setminus:"∖",setmn:"∖",sext:"✶",Sfr:"𝔖",sfr:"𝔰",sfrown:"⌢",sharp:"♯",SHCHcy:"Щ",shchcy:"щ",SHcy:"Ш",shcy:"ш",ShortDownArrow:"↓",ShortLeftArrow:"←",shortmid:"∣",shortparallel:"∥",ShortRightArrow:"→",ShortUpArrow:"↑",shy:"­",Sigma:"Σ",sigma:"σ",sigmaf:"ς",sigmav:"ς",sim:"∼",simdot:"⩪",sime:"≃",simeq:"≃",simg:"⪞",simgE:"⪠",siml:"⪝",simlE:"⪟",simne:"≆",simplus:"⨤",simrarr:"⥲",slarr:"←",SmallCircle:"∘",smallsetminus:"∖",smashp:"⨳",smeparsl:"⧤",smid:"∣",smile:"⌣",smt:"⪪",smte:"⪬",smtes:"⪬︀",SOFTcy:"Ь",softcy:"ь",solbar:"⌿",solb:"⧄",sol:"/",Sopf:"𝕊",sopf:"𝕤",spades:"♠",spadesuit:"♠",spar:"∥",sqcap:"⊓",sqcaps:"⊓︀",sqcup:"⊔",sqcups:"⊔︀",Sqrt:"√",sqsub:"⊏",sqsube:"⊑",sqsubset:"⊏",sqsubseteq:"⊑",sqsup:"⊐",sqsupe:"⊒",sqsupset:"⊐",sqsupseteq:"⊒",square:"□",Square:"□",SquareIntersection:"⊓",SquareSubset:"⊏",SquareSubsetEqual:"⊑",SquareSuperset:"⊐",SquareSupersetEqual:"⊒",SquareUnion:"⊔",squarf:"▪",squ:"□",squf:"▪",srarr:"→",Sscr:"𝒮",sscr:"𝓈",ssetmn:"∖",ssmile:"⌣",sstarf:"⋆",Star:"⋆",star:"☆",starf:"★",straightepsilon:"ϵ",straightphi:"ϕ",strns:"¯",sub:"⊂",Sub:"⋐",subdot:"⪽",subE:"⫅",sube:"⊆",subedot:"⫃",submult:"⫁",subnE:"⫋",subne:"⊊",subplus:"⪿",subrarr:"⥹",subset:"⊂",Subset:"⋐",subseteq:"⊆",subseteqq:"⫅",SubsetEqual:"⊆",subsetneq:"⊊",subsetneqq:"⫋",subsim:"⫇",subsub:"⫕",subsup:"⫓",succapprox:"⪸",succ:"≻",succcurlyeq:"≽",Succeeds:"≻",SucceedsEqual:"⪰",SucceedsSlantEqual:"≽",SucceedsTilde:"≿",succeq:"⪰",succnapprox:"⪺",succneqq:"⪶",succnsim:"⋩",succsim:"≿",SuchThat:"∋",sum:"∑",Sum:"∑",sung:"♪",sup1:"¹",sup2:"²",sup3:"³",sup:"⊃",Sup:"⋑",supdot:"⪾",supdsub:"⫘",supE:"⫆",supe:"⊇",supedot:"⫄",Superset:"⊃",SupersetEqual:"⊇",suphsol:"⟉",suphsub:"⫗",suplarr:"⥻",supmult:"⫂",supnE:"⫌",supne:"⊋",supplus:"⫀",supset:"⊃",Supset:"⋑",supseteq:"⊇",supseteqq:"⫆",supsetneq:"⊋",supsetneqq:"⫌",supsim:"⫈",supsub:"⫔",supsup:"⫖",swarhk:"⤦",swarr:"↙",swArr:"⇙",swarrow:"↙",swnwar:"⤪",szlig:"ß",Tab:"\t",target:"⌖",Tau:"Τ",tau:"τ",tbrk:"⎴",Tcaron:"Ť",tcaron:"ť",Tcedil:"Ţ",tcedil:"ţ",Tcy:"Т",tcy:"т",tdot:"⃛",telrec:"⌕",Tfr:"𝔗",tfr:"𝔱",there4:"∴",therefore:"∴",Therefore:"∴",Theta:"Θ",theta:"θ",thetasym:"ϑ",thetav:"ϑ",thickapprox:"≈",thicksim:"∼",ThickSpace:"  ",ThinSpace:" ",thinsp:" ",thkap:"≈",thksim:"∼",THORN:"Þ",thorn:"þ",tilde:"˜",Tilde:"∼",TildeEqual:"≃",TildeFullEqual:"≅",TildeTilde:"≈",timesbar:"⨱",timesb:"⊠",times:"×",timesd:"⨰",tint:"∭",toea:"⤨",topbot:"⌶",topcir:"⫱",top:"⊤",Topf:"𝕋",topf:"𝕥",topfork:"⫚",tosa:"⤩",tprime:"‴",trade:"™",TRADE:"™",triangle:"▵",triangledown:"▿",triangleleft:"◃",trianglelefteq:"⊴",triangleq:"≜",triangleright:"▹",trianglerighteq:"⊵",tridot:"◬",trie:"≜",triminus:"⨺",TripleDot:"⃛",triplus:"⨹",trisb:"⧍",tritime:"⨻",trpezium:"⏢",Tscr:"𝒯",tscr:"𝓉",TScy:"Ц",tscy:"ц",TSHcy:"Ћ",tshcy:"ћ",Tstrok:"Ŧ",tstrok:"ŧ",twixt:"≬",twoheadleftarrow:"↞",twoheadrightarrow:"↠",Uacute:"Ú",uacute:"ú",uarr:"↑",Uarr:"↟",uArr:"⇑",Uarrocir:"⥉",Ubrcy:"Ў",ubrcy:"ў",Ubreve:"Ŭ",ubreve:"ŭ",Ucirc:"Û",ucirc:"û",Ucy:"У",ucy:"у",udarr:"⇅",Udblac:"Ű",udblac:"ű",udhar:"⥮",ufisht:"⥾",Ufr:"𝔘",ufr:"𝔲",Ugrave:"Ù",ugrave:"ù",uHar:"⥣",uharl:"↿",uharr:"↾",uhblk:"▀",ulcorn:"⌜",ulcorner:"⌜",ulcrop:"⌏",ultri:"◸",Umacr:"Ū",umacr:"ū",uml:"¨",UnderBar:"_",UnderBrace:"⏟",UnderBracket:"⎵",UnderParenthesis:"⏝",Union:"⋃",UnionPlus:"⊎",Uogon:"Ų",uogon:"ų",Uopf:"𝕌",uopf:"𝕦",UpArrowBar:"⤒",uparrow:"↑",UpArrow:"↑",Uparrow:"⇑",UpArrowDownArrow:"⇅",updownarrow:"↕",UpDownArrow:"↕",Updownarrow:"⇕",UpEquilibrium:"⥮",upharpoonleft:"↿",upharpoonright:"↾",uplus:"⊎",UpperLeftArrow:"↖",UpperRightArrow:"↗",upsi:"υ",Upsi:"ϒ",upsih:"ϒ",Upsilon:"Υ",upsilon:"υ",UpTeeArrow:"↥",UpTee:"⊥",upuparrows:"⇈",urcorn:"⌝",urcorner:"⌝",urcrop:"⌎",Uring:"Ů",uring:"ů",urtri:"◹",Uscr:"𝒰",uscr:"𝓊",utdot:"⋰",Utilde:"Ũ",utilde:"ũ",utri:"▵",utrif:"▴",uuarr:"⇈",Uuml:"Ü",uuml:"ü",uwangle:"⦧",vangrt:"⦜",varepsilon:"ϵ",varkappa:"ϰ",varnothing:"∅",varphi:"ϕ",varpi:"ϖ",varpropto:"∝",varr:"↕",vArr:"⇕",varrho:"ϱ",varsigma:"ς",varsubsetneq:"⊊︀",varsubsetneqq:"⫋︀",varsupsetneq:"⊋︀",varsupsetneqq:"⫌︀",vartheta:"ϑ",vartriangleleft:"⊲",vartriangleright:"⊳",vBar:"⫨",Vbar:"⫫",vBarv:"⫩",Vcy:"В",vcy:"в",vdash:"⊢",vDash:"⊨",Vdash:"⊩",VDash:"⊫",Vdashl:"⫦",veebar:"⊻",vee:"∨",Vee:"⋁",veeeq:"≚",vellip:"⋮",verbar:"|",Verbar:"‖",vert:"|",Vert:"‖",VerticalBar:"∣",VerticalLine:"|",VerticalSeparator:"❘",VerticalTilde:"≀",VeryThinSpace:" ",Vfr:"𝔙",vfr:"𝔳",vltri:"⊲",vnsub:"⊂⃒",vnsup:"⊃⃒",Vopf:"𝕍",vopf:"𝕧",vprop:"∝",vrtri:"⊳",Vscr:"𝒱",vscr:"𝓋",vsubnE:"⫋︀",vsubne:"⊊︀",vsupnE:"⫌︀",vsupne:"⊋︀",Vvdash:"⊪",vzigzag:"⦚",Wcirc:"Ŵ",wcirc:"ŵ",wedbar:"⩟",wedge:"∧",Wedge:"⋀",wedgeq:"≙",weierp:"℘",Wfr:"𝔚",wfr:"𝔴",Wopf:"𝕎",wopf:"𝕨",wp:"℘",wr:"≀",wreath:"≀",Wscr:"𝒲",wscr:"𝓌",xcap:"⋂",xcirc:"◯",xcup:"⋃",xdtri:"▽",Xfr:"𝔛",xfr:"𝔵",xharr:"⟷",xhArr:"⟺",Xi:"Ξ",xi:"ξ",xlarr:"⟵",xlArr:"⟸",xmap:"⟼",xnis:"⋻",xodot:"⨀",Xopf:"𝕏",xopf:"𝕩",xoplus:"⨁",xotime:"⨂",xrarr:"⟶",xrArr:"⟹",Xscr:"𝒳",xscr:"𝓍",xsqcup:"⨆",xuplus:"⨄",xutri:"△",xvee:"⋁",xwedge:"⋀",Yacute:"Ý",yacute:"ý",YAcy:"Я",yacy:"я",Ycirc:"Ŷ",ycirc:"ŷ",Ycy:"Ы",ycy:"ы",yen:"¥",Yfr:"𝔜",yfr:"𝔶",YIcy:"Ї",yicy:"ї",Yopf:"𝕐",yopf:"𝕪",Yscr:"𝒴",yscr:"𝓎",YUcy:"Ю",yucy:"ю",yuml:"ÿ",Yuml:"Ÿ",Zacute:"Ź",zacute:"ź",Zcaron:"Ž",zcaron:"ž",Zcy:"З",zcy:"з",Zdot:"Ż",zdot:"ż",zeetrf:"ℨ",ZeroWidthSpace:"​",Zeta:"Ζ",zeta:"ζ",zfr:"𝔷",Zfr:"ℨ",ZHcy:"Ж",zhcy:"ж",zigrarr:"⇝",zopf:"𝕫",Zopf:"ℤ",Zscr:"𝒵",zscr:"𝓏",zwj:"‍",zwnj:"‌"}},{}],26:[function(require,module,exports){module.exports={Aacute:"Á",aacute:"á",Acirc:"Â",acirc:"â",acute:"´",AElig:"Æ",aelig:"æ",Agrave:"À",agrave:"à",amp:"&",AMP:"&",Aring:"Å",aring:"å",Atilde:"Ã",atilde:"ã",Auml:"Ä",auml:"ä",brvbar:"¦",Ccedil:"Ç",ccedil:"ç",cedil:"¸",cent:"¢",copy:"©",COPY:"©",curren:"¤",deg:"°",divide:"÷",Eacute:"É",eacute:"é",Ecirc:"Ê",ecirc:"ê",Egrave:"È",egrave:"è",ETH:"Ð",eth:"ð",Euml:"Ë",euml:"ë",frac12:"½",frac14:"¼",frac34:"¾",gt:">",GT:">",Iacute:"Í",iacute:"í",Icirc:"Î",icirc:"î",iexcl:"¡",Igrave:"Ì",igrave:"ì",iquest:"¿",Iuml:"Ï",iuml:"ï",laquo:"«",lt:"<",LT:"<",macr:"¯",micro:"µ",middot:"·",nbsp:" ",not:"¬",Ntilde:"Ñ",ntilde:"ñ",Oacute:"Ó",oacute:"ó",Ocirc:"Ô",ocirc:"ô",Ograve:"Ò",ograve:"ò",ordf:"ª",ordm:"º",Oslash:"Ø",oslash:"ø",Otilde:"Õ",otilde:"õ",Ouml:"Ö",ouml:"ö",para:"¶",plusmn:"±",pound:"£",quot:'"',QUOT:'"',raquo:"»",reg:"®",REG:"®",sect:"§",shy:"­",sup1:"¹",sup2:"²",sup3:"³",szlig:"ß",THORN:"Þ",thorn:"þ",times:"×",Uacute:"Ú",uacute:"ú",Ucirc:"Û",ucirc:"û",Ugrave:"Ù",ugrave:"ù",uml:"¨",Uuml:"Ü",uuml:"ü",Yacute:"Ý",yacute:"ý",yen:"¥",yuml:"ÿ"}},{}],27:[function(require,module,exports){module.exports={amp:"&",apos:"'",gt:">",lt:"<",quot:'"'}},{}],28:[function(require,module,exports){function EventEmitter(){this._events=this._events||{};this._maxListeners=this._maxListeners||undefined}module.exports=EventEmitter;EventEmitter.EventEmitter=EventEmitter;EventEmitter.prototype._events=undefined;EventEmitter.prototype._maxListeners=undefined;EventEmitter.defaultMaxListeners=10;EventEmitter.prototype.setMaxListeners=function(n){if(!isNumber(n)||n<0||isNaN(n))throw TypeError("n must be a positive number");this._maxListeners=n;return this};EventEmitter.prototype.emit=function(type){var er,handler,len,args,i,listeners;if(!this._events)this._events={};if(type==="error"){if(!this._events.error||isObject(this._events.error)&&!this._events.error.length){er=arguments[1];if(er instanceof Error){throw er}else{var err=new Error('Uncaught, unspecified "error" event. ('+er+")");err.context=er;throw err}}}handler=this._events[type];if(isUndefined(handler))return false;if(isFunction(handler)){switch(arguments.length){case 1:handler.call(this);break;case 2:handler.call(this,arguments[1]);break;case 3:handler.call(this,arguments[1],arguments[2]);break;default:args=Array.prototype.slice.call(arguments,1);handler.apply(this,args)}}else if(isObject(handler)){args=Array.prototype.slice.call(arguments,1);listeners=handler.slice();len=listeners.length;for(i=0;i<len;i++)listeners[i].apply(this,args)}return true};EventEmitter.prototype.addListener=function(type,listener){var m;if(!isFunction(listener))throw TypeError("listener must be a function");if(!this._events)this._events={};if(this._events.newListener)this.emit("newListener",type,isFunction(listener.listener)?listener.listener:listener);if(!this._events[type])this._events[type]=listener;else if(isObject(this._events[type]))this._events[type].push(listener);else this._events[type]=[this._events[type],listener];if(isObject(this._events[type])&&!this._events[type].warned){if(!isUndefined(this._maxListeners)){m=this._maxListeners}else{m=EventEmitter.defaultMaxListeners}if(m&&m>0&&this._events[type].length>m){this._events[type].warned=true;console.error("(node) warning: possible EventEmitter memory "+"leak detected. %d listeners added. "+"Use emitter.setMaxListeners() to increase limit.",this._events[type].length);if(typeof console.trace==="function"){console.trace()}}}return this};EventEmitter.prototype.on=EventEmitter.prototype.addListener;EventEmitter.prototype.once=function(type,listener){if(!isFunction(listener))throw TypeError("listener must be a function");var fired=false;function g(){this.removeListener(type,g);if(!fired){fired=true;listener.apply(this,arguments)}}g.listener=listener;this.on(type,g);return this};EventEmitter.prototype.removeListener=function(type,listener){var list,position,length,i;if(!isFunction(listener))throw TypeError("listener must be a function");if(!this._events||!this._events[type])return this;list=this._events[type];length=list.length;position=-1;if(list===listener||isFunction(list.listener)&&list.listener===listener){delete this._events[type];if(this._events.removeListener)this.emit("removeListener",type,listener)}else if(isObject(list)){for(i=length;i-- >0;){if(list[i]===listener||list[i].listener&&list[i].listener===listener){position=i;break}}if(position<0)return this;if(list.length===1){list.length=0;delete this._events[type]}else{list.splice(position,1);
+}if(this._events.removeListener)this.emit("removeListener",type,listener)}return this};EventEmitter.prototype.removeAllListeners=function(type){var key,listeners;if(!this._events)return this;if(!this._events.removeListener){if(arguments.length===0)this._events={};else if(this._events[type])delete this._events[type];return this}if(arguments.length===0){for(key in this._events){if(key==="removeListener")continue;this.removeAllListeners(key)}this.removeAllListeners("removeListener");this._events={};return this}listeners=this._events[type];if(isFunction(listeners)){this.removeListener(type,listeners)}else if(listeners){while(listeners.length)this.removeListener(type,listeners[listeners.length-1])}delete this._events[type];return this};EventEmitter.prototype.listeners=function(type){var ret;if(!this._events||!this._events[type])ret=[];else if(isFunction(this._events[type]))ret=[this._events[type]];else ret=this._events[type].slice();return ret};EventEmitter.prototype.listenerCount=function(type){if(this._events){var evlistener=this._events[type];if(isFunction(evlistener))return 1;else if(evlistener)return evlistener.length}return 0};EventEmitter.listenerCount=function(emitter,type){return emitter.listenerCount(type)};function isFunction(arg){return typeof arg==="function"}function isNumber(arg){return typeof arg==="number"}function isObject(arg){return typeof arg==="object"&&arg!==null}function isUndefined(arg){return arg===void 0}},{}],29:[function(require,module,exports){module.exports=CollectingHandler;function CollectingHandler(cbs){this._cbs=cbs||{};this.events=[]}var EVENTS=require("./").EVENTS;Object.keys(EVENTS).forEach(function(name){if(EVENTS[name]===0){name="on"+name;CollectingHandler.prototype[name]=function(){this.events.push([name]);if(this._cbs[name])this._cbs[name]()}}else if(EVENTS[name]===1){name="on"+name;CollectingHandler.prototype[name]=function(a){this.events.push([name,a]);if(this._cbs[name])this._cbs[name](a)}}else if(EVENTS[name]===2){name="on"+name;CollectingHandler.prototype[name]=function(a,b){this.events.push([name,a,b]);if(this._cbs[name])this._cbs[name](a,b)}}else{throw Error("wrong number of arguments")}});CollectingHandler.prototype.onreset=function(){this.events=[];if(this._cbs.onreset)this._cbs.onreset()};CollectingHandler.prototype.restart=function(){if(this._cbs.onreset)this._cbs.onreset();for(var i=0,len=this.events.length;i<len;i++){if(this._cbs[this.events[i][0]]){var num=this.events[i].length;if(num===1){this._cbs[this.events[i][0]]()}else if(num===2){this._cbs[this.events[i][0]](this.events[i][1])}else{this._cbs[this.events[i][0]](this.events[i][1],this.events[i][2])}}}}},{"./":36}],30:[function(require,module,exports){var index=require("./index.js"),DomHandler=index.DomHandler,DomUtils=index.DomUtils;function FeedHandler(callback,options){this.init(callback,options)}require("inherits")(FeedHandler,DomHandler);FeedHandler.prototype.init=DomHandler;function getElements(what,where){return DomUtils.getElementsByTagName(what,where,true)}function getOneElement(what,where){return DomUtils.getElementsByTagName(what,where,true,1)[0]}function fetch(what,where,recurse){return DomUtils.getText(DomUtils.getElementsByTagName(what,where,recurse,1)).trim()}function addConditionally(obj,prop,what,where,recurse){var tmp=fetch(what,where,recurse);if(tmp)obj[prop]=tmp}var isValidFeed=function(value){return value==="rss"||value==="feed"||value==="rdf:RDF"};FeedHandler.prototype.onend=function(){var feed={},feedRoot=getOneElement(isValidFeed,this.dom),tmp,childs;if(feedRoot){if(feedRoot.name==="feed"){childs=feedRoot.children;feed.type="atom";addConditionally(feed,"id","id",childs);addConditionally(feed,"title","title",childs);if((tmp=getOneElement("link",childs))&&(tmp=tmp.attribs)&&(tmp=tmp.href))feed.link=tmp;addConditionally(feed,"description","subtitle",childs);if(tmp=fetch("updated",childs))feed.updated=new Date(tmp);addConditionally(feed,"author","email",childs,true);feed.items=getElements("entry",childs).map(function(item){var entry={},tmp;item=item.children;addConditionally(entry,"id","id",item);addConditionally(entry,"title","title",item);if((tmp=getOneElement("link",item))&&(tmp=tmp.attribs)&&(tmp=tmp.href))entry.link=tmp;if(tmp=fetch("summary",item)||fetch("content",item))entry.description=tmp;if(tmp=fetch("updated",item))entry.pubDate=new Date(tmp);return entry})}else{childs=getOneElement("channel",feedRoot.children).children;feed.type=feedRoot.name.substr(0,3);feed.id="";addConditionally(feed,"title","title",childs);addConditionally(feed,"link","link",childs);addConditionally(feed,"description","description",childs);if(tmp=fetch("lastBuildDate",childs))feed.updated=new Date(tmp);addConditionally(feed,"author","managingEditor",childs,true);feed.items=getElements("item",feedRoot.children).map(function(item){var entry={},tmp;item=item.children;addConditionally(entry,"id","guid",item);addConditionally(entry,"title","title",item);addConditionally(entry,"link","link",item);addConditionally(entry,"description","description",item);if(tmp=fetch("pubDate",item))entry.pubDate=new Date(tmp);return entry})}}this.dom=feed;DomHandler.prototype._handleCallback.call(this,feedRoot?null:Error("couldn't find root of feed"))};module.exports=FeedHandler},{"./index.js":36,inherits:38}],31:[function(require,module,exports){var Tokenizer=require("./Tokenizer.js");var formTags={input:true,option:true,optgroup:true,select:true,button:true,datalist:true,textarea:true};var openImpliesClose={tr:{tr:true,th:true,td:true},th:{th:true},td:{thead:true,th:true,td:true},body:{head:true,link:true,script:true},li:{li:true},p:{p:true},h1:{p:true},h2:{p:true},h3:{p:true},h4:{p:true},h5:{p:true},h6:{p:true},select:formTags,input:formTags,output:formTags,button:formTags,datalist:formTags,textarea:formTags,option:{option:true},optgroup:{optgroup:true}};var voidElements={__proto__:null,area:true,base:true,basefont:true,br:true,col:true,command:true,embed:true,frame:true,hr:true,img:true,input:true,isindex:true,keygen:true,link:true,meta:true,param:true,source:true,track:true,wbr:true,path:true,circle:true,ellipse:true,line:true,rect:true,use:true,stop:true,polyline:true,polygon:true};var re_nameEnd=/\s|\//;function Parser(cbs,options){this._options=options||{};this._cbs=cbs||{};this._tagname="";this._attribname="";this._attribvalue="";this._attribs=null;this._stack=[];this.startIndex=0;this.endIndex=null;this._lowerCaseTagNames="lowerCaseTags"in this._options?!!this._options.lowerCaseTags:!this._options.xmlMode;this._lowerCaseAttributeNames="lowerCaseAttributeNames"in this._options?!!this._options.lowerCaseAttributeNames:!this._options.xmlMode;if(this._options.Tokenizer){Tokenizer=this._options.Tokenizer}this._tokenizer=new Tokenizer(this._options,this);if(this._cbs.onparserinit)this._cbs.onparserinit(this)}require("inherits")(Parser,require("events").EventEmitter);Parser.prototype._updatePosition=function(initialOffset){if(this.endIndex===null){if(this._tokenizer._sectionStart<=initialOffset){this.startIndex=0}else{this.startIndex=this._tokenizer._sectionStart-initialOffset}}else this.startIndex=this.endIndex+1;this.endIndex=this._tokenizer.getAbsoluteIndex()};Parser.prototype.ontext=function(data){this._updatePosition(1);this.endIndex--;if(this._cbs.ontext)this._cbs.ontext(data)};Parser.prototype.onopentagname=function(name){if(this._lowerCaseTagNames){name=name.toLowerCase()}this._tagname=name;if(!this._options.xmlMode&&name in openImpliesClose){for(var el;(el=this._stack[this._stack.length-1])in openImpliesClose[name];this.onclosetag(el));}if(this._options.xmlMode||!(name in voidElements)){this._stack.push(name)}if(this._cbs.onopentagname)this._cbs.onopentagname(name);if(this._cbs.onopentag)this._attribs={}};Parser.prototype.onopentagend=function(){this._updatePosition(1);if(this._attribs){if(this._cbs.onopentag)this._cbs.onopentag(this._tagname,this._attribs);this._attribs=null}if(!this._options.xmlMode&&this._cbs.onclosetag&&this._tagname in voidElements){this._cbs.onclosetag(this._tagname)}this._tagname=""};Parser.prototype.onclosetag=function(name){this._updatePosition(1);if(this._lowerCaseTagNames){name=name.toLowerCase()}if(this._stack.length&&(!(name in voidElements)||this._options.xmlMode)){var pos=this._stack.lastIndexOf(name);if(pos!==-1){if(this._cbs.onclosetag){pos=this._stack.length-pos;while(pos--)this._cbs.onclosetag(this._stack.pop())}else this._stack.length=pos}else if(name==="p"&&!this._options.xmlMode){this.onopentagname(name);this._closeCurrentTag()}}else if(!this._options.xmlMode&&(name==="br"||name==="p")){this.onopentagname(name);this._closeCurrentTag()}};Parser.prototype.onselfclosingtag=function(){if(this._options.xmlMode||this._options.recognizeSelfClosing){this._closeCurrentTag()}else{this.onopentagend()}};Parser.prototype._closeCurrentTag=function(){var name=this._tagname;this.onopentagend();if(this._stack[this._stack.length-1]===name){if(this._cbs.onclosetag){this._cbs.onclosetag(name)}this._stack.pop()}};Parser.prototype.onattribname=function(name){if(this._lowerCaseAttributeNames){name=name.toLowerCase()}this._attribname=name};Parser.prototype.onattribdata=function(value){this._attribvalue+=value};Parser.prototype.onattribend=function(){if(this._cbs.onattribute)this._cbs.onattribute(this._attribname,this._attribvalue);if(this._attribs&&!Object.prototype.hasOwnProperty.call(this._attribs,this._attribname)){this._attribs[this._attribname]=this._attribvalue}this._attribname="";this._attribvalue=""};Parser.prototype._getInstructionName=function(value){var idx=value.search(re_nameEnd),name=idx<0?value:value.substr(0,idx);if(this._lowerCaseTagNames){name=name.toLowerCase()}return name};Parser.prototype.ondeclaration=function(value){if(this._cbs.onprocessinginstruction){var name=this._getInstructionName(value);this._cbs.onprocessinginstruction("!"+name,"!"+value)}};Parser.prototype.onprocessinginstruction=function(value){if(this._cbs.onprocessinginstruction){var name=this._getInstructionName(value);this._cbs.onprocessinginstruction("?"+name,"?"+value)}};Parser.prototype.oncomment=function(value){this._updatePosition(4);if(this._cbs.oncomment)this._cbs.oncomment(value);if(this._cbs.oncommentend)this._cbs.oncommentend()};Parser.prototype.oncdata=function(value){this._updatePosition(1);if(this._options.xmlMode||this._options.recognizeCDATA){if(this._cbs.oncdatastart)this._cbs.oncdatastart();if(this._cbs.ontext)this._cbs.ontext(value);if(this._cbs.oncdataend)this._cbs.oncdataend()}else{this.oncomment("[CDATA["+value+"]]")}};Parser.prototype.onerror=function(err){if(this._cbs.onerror)this._cbs.onerror(err)};Parser.prototype.onend=function(){if(this._cbs.onclosetag){for(var i=this._stack.length;i>0;this._cbs.onclosetag(this._stack[--i]));}if(this._cbs.onend)this._cbs.onend()};Parser.prototype.reset=function(){if(this._cbs.onreset)this._cbs.onreset();this._tokenizer.reset();this._tagname="";this._attribname="";this._attribs=null;this._stack=[];if(this._cbs.onparserinit)this._cbs.onparserinit(this)};Parser.prototype.parseComplete=function(data){this.reset();this.end(data)};Parser.prototype.write=function(chunk){this._tokenizer.write(chunk)};Parser.prototype.end=function(chunk){this._tokenizer.end(chunk)};Parser.prototype.pause=function(){this._tokenizer.pause()};Parser.prototype.resume=function(){this._tokenizer.resume()};Parser.prototype.parseChunk=Parser.prototype.write;Parser.prototype.done=Parser.prototype.end;module.exports=Parser},{"./Tokenizer.js":34,events:28,inherits:38}],32:[function(require,module,exports){module.exports=ProxyHandler;function ProxyHandler(cbs){this._cbs=cbs||{}}var EVENTS=require("./").EVENTS;Object.keys(EVENTS).forEach(function(name){if(EVENTS[name]===0){name="on"+name;ProxyHandler.prototype[name]=function(){if(this._cbs[name])this._cbs[name]()}}else if(EVENTS[name]===1){name="on"+name;ProxyHandler.prototype[name]=function(a){if(this._cbs[name])this._cbs[name](a)}}else if(EVENTS[name]===2){name="on"+name;ProxyHandler.prototype[name]=function(a,b){if(this._cbs[name])this._cbs[name](a,b)}}else{throw Error("wrong number of arguments")}})},{"./":36}],33:[function(require,module,exports){module.exports=Stream;var Parser=require("./WritableStream.js");function Stream(options){Parser.call(this,new Cbs(this),options)}require("inherits")(Stream,Parser);Stream.prototype.readable=true;function Cbs(scope){this.scope=scope}var EVENTS=require("../").EVENTS;Object.keys(EVENTS).forEach(function(name){if(EVENTS[name]===0){Cbs.prototype["on"+name]=function(){this.scope.emit(name)}}else if(EVENTS[name]===1){Cbs.prototype["on"+name]=function(a){this.scope.emit(name,a)}}else if(EVENTS[name]===2){Cbs.prototype["on"+name]=function(a,b){this.scope.emit(name,a,b)}}else{throw Error("wrong number of arguments!")}})},{"../":36,"./WritableStream.js":35,inherits:38}],34:[function(require,module,exports){module.exports=Tokenizer;var decodeCodePoint=require("entities/lib/decode_codepoint.js"),entityMap=require("entities/maps/entities.json"),legacyMap=require("entities/maps/legacy.json"),xmlMap=require("entities/maps/xml.json"),i=0,TEXT=i++,BEFORE_TAG_NAME=i++,IN_TAG_NAME=i++,IN_SELF_CLOSING_TAG=i++,BEFORE_CLOSING_TAG_NAME=i++,IN_CLOSING_TAG_NAME=i++,AFTER_CLOSING_TAG_NAME=i++,BEFORE_ATTRIBUTE_NAME=i++,IN_ATTRIBUTE_NAME=i++,AFTER_ATTRIBUTE_NAME=i++,BEFORE_ATTRIBUTE_VALUE=i++,IN_ATTRIBUTE_VALUE_DQ=i++,IN_ATTRIBUTE_VALUE_SQ=i++,IN_ATTRIBUTE_VALUE_NQ=i++,BEFORE_DECLARATION=i++,IN_DECLARATION=i++,IN_PROCESSING_INSTRUCTION=i++,BEFORE_COMMENT=i++,IN_COMMENT=i++,AFTER_COMMENT_1=i++,AFTER_COMMENT_2=i++,BEFORE_CDATA_1=i++,BEFORE_CDATA_2=i++,BEFORE_CDATA_3=i++,BEFORE_CDATA_4=i++,BEFORE_CDATA_5=i++,BEFORE_CDATA_6=i++,IN_CDATA=i++,AFTER_CDATA_1=i++,AFTER_CDATA_2=i++,BEFORE_SPECIAL=i++,BEFORE_SPECIAL_END=i++,BEFORE_SCRIPT_1=i++,BEFORE_SCRIPT_2=i++,BEFORE_SCRIPT_3=i++,BEFORE_SCRIPT_4=i++,BEFORE_SCRIPT_5=i++,AFTER_SCRIPT_1=i++,AFTER_SCRIPT_2=i++,AFTER_SCRIPT_3=i++,AFTER_SCRIPT_4=i++,AFTER_SCRIPT_5=i++,BEFORE_STYLE_1=i++,BEFORE_STYLE_2=i++,BEFORE_STYLE_3=i++,BEFORE_STYLE_4=i++,AFTER_STYLE_1=i++,AFTER_STYLE_2=i++,AFTER_STYLE_3=i++,AFTER_STYLE_4=i++,BEFORE_ENTITY=i++,BEFORE_NUMERIC_ENTITY=i++,IN_NAMED_ENTITY=i++,IN_NUMERIC_ENTITY=i++,IN_HEX_ENTITY=i++,j=0,SPECIAL_NONE=j++,SPECIAL_SCRIPT=j++,SPECIAL_STYLE=j++;function whitespace(c){return c===" "||c==="\n"||c==="\t"||c==="\f"||c==="\r"}function characterState(char,SUCCESS){return function(c){if(c===char)this._state=SUCCESS}}function ifElseState(upper,SUCCESS,FAILURE){var lower=upper.toLowerCase();if(upper===lower){return function(c){if(c===lower){this._state=SUCCESS}else{this._state=FAILURE;this._index--}}}else{return function(c){if(c===lower||c===upper){this._state=SUCCESS}else{this._state=FAILURE;this._index--}}}}function consumeSpecialNameChar(upper,NEXT_STATE){var lower=upper.toLowerCase();return function(c){if(c===lower||c===upper){this._state=NEXT_STATE}else{this._state=IN_TAG_NAME;this._index--}}}function Tokenizer(options,cbs){this._state=TEXT;this._buffer="";this._sectionStart=0;this._index=0;this._bufferOffset=0;this._baseState=TEXT;this._special=SPECIAL_NONE;this._cbs=cbs;this._running=true;this._ended=false;this._xmlMode=!!(options&&options.xmlMode);this._decodeEntities=!!(options&&options.decodeEntities)}Tokenizer.prototype._stateText=function(c){if(c==="<"){if(this._index>this._sectionStart){this._cbs.ontext(this._getSection())}this._state=BEFORE_TAG_NAME;this._sectionStart=this._index}else if(this._decodeEntities&&this._special===SPECIAL_NONE&&c==="&"){if(this._index>this._sectionStart){this._cbs.ontext(this._getSection())}this._baseState=TEXT;this._state=BEFORE_ENTITY;this._sectionStart=this._index}};Tokenizer.prototype._stateBeforeTagName=function(c){if(c==="/"){this._state=BEFORE_CLOSING_TAG_NAME}else if(c==="<"){this._cbs.ontext(this._getSection());this._sectionStart=this._index}else if(c===">"||this._special!==SPECIAL_NONE||whitespace(c)){this._state=TEXT}else if(c==="!"){this._state=BEFORE_DECLARATION;this._sectionStart=this._index+1}else if(c==="?"){this._state=IN_PROCESSING_INSTRUCTION;this._sectionStart=this._index+1}else{this._state=!this._xmlMode&&(c==="s"||c==="S")?BEFORE_SPECIAL:IN_TAG_NAME;this._sectionStart=this._index}};Tokenizer.prototype._stateInTagName=function(c){if(c==="/"||c===">"||whitespace(c)){this._emitToken("onopentagname");this._state=BEFORE_ATTRIBUTE_NAME;this._index--}};Tokenizer.prototype._stateBeforeCloseingTagName=function(c){if(whitespace(c));else if(c===">"){this._state=TEXT}else if(this._special!==SPECIAL_NONE){if(c==="s"||c==="S"){this._state=BEFORE_SPECIAL_END}else{this._state=TEXT;this._index--}}else{this._state=IN_CLOSING_TAG_NAME;this._sectionStart=this._index}};Tokenizer.prototype._stateInCloseingTagName=function(c){if(c===">"||whitespace(c)){this._emitToken("onclosetag");this._state=AFTER_CLOSING_TAG_NAME;this._index--}};Tokenizer.prototype._stateAfterCloseingTagName=function(c){if(c===">"){this._state=TEXT;this._sectionStart=this._index+1}};Tokenizer.prototype._stateBeforeAttributeName=function(c){if(c===">"){this._cbs.onopentagend();this._state=TEXT;this._sectionStart=this._index+1}else if(c==="/"){this._state=IN_SELF_CLOSING_TAG}else if(!whitespace(c)){this._state=IN_ATTRIBUTE_NAME;this._sectionStart=this._index}};Tokenizer.prototype._stateInSelfClosingTag=function(c){if(c===">"){this._cbs.onselfclosingtag();this._state=TEXT;this._sectionStart=this._index+1}else if(!whitespace(c)){this._state=BEFORE_ATTRIBUTE_NAME;this._index--}};Tokenizer.prototype._stateInAttributeName=function(c){if(c==="="||c==="/"||c===">"||whitespace(c)){this._cbs.onattribname(this._getSection());this._sectionStart=-1;this._state=AFTER_ATTRIBUTE_NAME;this._index--}};Tokenizer.prototype._stateAfterAttributeName=function(c){if(c==="="){this._state=BEFORE_ATTRIBUTE_VALUE}else if(c==="/"||c===">"){this._cbs.onattribend();this._state=BEFORE_ATTRIBUTE_NAME;this._index--}else if(!whitespace(c)){this._cbs.onattribend();this._state=IN_ATTRIBUTE_NAME;this._sectionStart=this._index}};Tokenizer.prototype._stateBeforeAttributeValue=function(c){if(c==='"'){this._state=IN_ATTRIBUTE_VALUE_DQ;this._sectionStart=this._index+1}else if(c==="'"){this._state=IN_ATTRIBUTE_VALUE_SQ;this._sectionStart=this._index+1}else if(!whitespace(c)){this._state=IN_ATTRIBUTE_VALUE_NQ;this._sectionStart=this._index;this._index--}};Tokenizer.prototype._stateInAttributeValueDoubleQuotes=function(c){if(c==='"'){this._emitToken("onattribdata");this._cbs.onattribend();this._state=BEFORE_ATTRIBUTE_NAME}else if(this._decodeEntities&&c==="&"){this._emitToken("onattribdata");this._baseState=this._state;this._state=BEFORE_ENTITY;this._sectionStart=this._index}};Tokenizer.prototype._stateInAttributeValueSingleQuotes=function(c){if(c==="'"){this._emitToken("onattribdata");this._cbs.onattribend();this._state=BEFORE_ATTRIBUTE_NAME}else if(this._decodeEntities&&c==="&"){this._emitToken("onattribdata");this._baseState=this._state;this._state=BEFORE_ENTITY;this._sectionStart=this._index}};Tokenizer.prototype._stateInAttributeValueNoQuotes=function(c){if(whitespace(c)||c===">"){this._emitToken("onattribdata");this._cbs.onattribend();this._state=BEFORE_ATTRIBUTE_NAME;this._index--}else if(this._decodeEntities&&c==="&"){this._emitToken("onattribdata");this._baseState=this._state;this._state=BEFORE_ENTITY;this._sectionStart=this._index}};Tokenizer.prototype._stateBeforeDeclaration=function(c){this._state=c==="["?BEFORE_CDATA_1:c==="-"?BEFORE_COMMENT:IN_DECLARATION};Tokenizer.prototype._stateInDeclaration=function(c){if(c===">"){this._cbs.ondeclaration(this._getSection());this._state=TEXT;this._sectionStart=this._index+1}};Tokenizer.prototype._stateInProcessingInstruction=function(c){if(c===">"){this._cbs.onprocessinginstruction(this._getSection());this._state=TEXT;this._sectionStart=this._index+1}};Tokenizer.prototype._stateBeforeComment=function(c){if(c==="-"){this._state=IN_COMMENT;this._sectionStart=this._index+1}else{this._state=IN_DECLARATION}};Tokenizer.prototype._stateInComment=function(c){if(c==="-")this._state=AFTER_COMMENT_1};Tokenizer.prototype._stateAfterComment1=function(c){if(c==="-"){this._state=AFTER_COMMENT_2}else{this._state=IN_COMMENT}};Tokenizer.prototype._stateAfterComment2=function(c){if(c===">"){this._cbs.oncomment(this._buffer.substring(this._sectionStart,this._index-2));this._state=TEXT;this._sectionStart=this._index+1}else if(c!=="-"){this._state=IN_COMMENT}};Tokenizer.prototype._stateBeforeCdata1=ifElseState("C",BEFORE_CDATA_2,IN_DECLARATION);Tokenizer.prototype._stateBeforeCdata2=ifElseState("D",BEFORE_CDATA_3,IN_DECLARATION);Tokenizer.prototype._stateBeforeCdata3=ifElseState("A",BEFORE_CDATA_4,IN_DECLARATION);Tokenizer.prototype._stateBeforeCdata4=ifElseState("T",BEFORE_CDATA_5,IN_DECLARATION);Tokenizer.prototype._stateBeforeCdata5=ifElseState("A",BEFORE_CDATA_6,IN_DECLARATION);Tokenizer.prototype._stateBeforeCdata6=function(c){if(c==="["){this._state=IN_CDATA;this._sectionStart=this._index+1}else{this._state=IN_DECLARATION;this._index--}};Tokenizer.prototype._stateInCdata=function(c){if(c==="]")this._state=AFTER_CDATA_1};Tokenizer.prototype._stateAfterCdata1=characterState("]",AFTER_CDATA_2);Tokenizer.prototype._stateAfterCdata2=function(c){if(c===">"){this._cbs.oncdata(this._buffer.substring(this._sectionStart,this._index-2));this._state=TEXT;this._sectionStart=this._index+1}else if(c!=="]"){this._state=IN_CDATA}};Tokenizer.prototype._stateBeforeSpecial=function(c){if(c==="c"||c==="C"){this._state=BEFORE_SCRIPT_1}else if(c==="t"||c==="T"){this._state=BEFORE_STYLE_1}else{this._state=IN_TAG_NAME;this._index--}};Tokenizer.prototype._stateBeforeSpecialEnd=function(c){if(this._special===SPECIAL_SCRIPT&&(c==="c"||c==="C")){this._state=AFTER_SCRIPT_1}else if(this._special===SPECIAL_STYLE&&(c==="t"||c==="T")){this._state=AFTER_STYLE_1}else this._state=TEXT};Tokenizer.prototype._stateBeforeScript1=consumeSpecialNameChar("R",BEFORE_SCRIPT_2);Tokenizer.prototype._stateBeforeScript2=consumeSpecialNameChar("I",BEFORE_SCRIPT_3);Tokenizer.prototype._stateBeforeScript3=consumeSpecialNameChar("P",BEFORE_SCRIPT_4);Tokenizer.prototype._stateBeforeScript4=consumeSpecialNameChar("T",BEFORE_SCRIPT_5);Tokenizer.prototype._stateBeforeScript5=function(c){if(c==="/"||c===">"||whitespace(c)){this._special=SPECIAL_SCRIPT}this._state=IN_TAG_NAME;this._index--};Tokenizer.prototype._stateAfterScript1=ifElseState("R",AFTER_SCRIPT_2,TEXT);Tokenizer.prototype._stateAfterScript2=ifElseState("I",AFTER_SCRIPT_3,TEXT);Tokenizer.prototype._stateAfterScript3=ifElseState("P",AFTER_SCRIPT_4,TEXT);Tokenizer.prototype._stateAfterScript4=ifElseState("T",AFTER_SCRIPT_5,TEXT);Tokenizer.prototype._stateAfterScript5=function(c){if(c===">"||whitespace(c)){this._special=SPECIAL_NONE;this._state=IN_CLOSING_TAG_NAME;this._sectionStart=this._index-6;this._index--}else this._state=TEXT};Tokenizer.prototype._stateBeforeStyle1=consumeSpecialNameChar("Y",BEFORE_STYLE_2);Tokenizer.prototype._stateBeforeStyle2=consumeSpecialNameChar("L",BEFORE_STYLE_3);Tokenizer.prototype._stateBeforeStyle3=consumeSpecialNameChar("E",BEFORE_STYLE_4);Tokenizer.prototype._stateBeforeStyle4=function(c){if(c==="/"||c===">"||whitespace(c)){this._special=SPECIAL_STYLE}this._state=IN_TAG_NAME;this._index--};Tokenizer.prototype._stateAfterStyle1=ifElseState("Y",AFTER_STYLE_2,TEXT);Tokenizer.prototype._stateAfterStyle2=ifElseState("L",AFTER_STYLE_3,TEXT);Tokenizer.prototype._stateAfterStyle3=ifElseState("E",AFTER_STYLE_4,TEXT);Tokenizer.prototype._stateAfterStyle4=function(c){if(c===">"||whitespace(c)){this._special=SPECIAL_NONE;this._state=IN_CLOSING_TAG_NAME;this._sectionStart=this._index-5;this._index--}else this._state=TEXT};Tokenizer.prototype._stateBeforeEntity=ifElseState("#",BEFORE_NUMERIC_ENTITY,IN_NAMED_ENTITY);Tokenizer.prototype._stateBeforeNumericEntity=ifElseState("X",IN_HEX_ENTITY,IN_NUMERIC_ENTITY);Tokenizer.prototype._parseNamedEntityStrict=function(){if(this._sectionStart+1<this._index){var entity=this._buffer.substring(this._sectionStart+1,this._index),map=this._xmlMode?xmlMap:entityMap;if(map.hasOwnProperty(entity)){this._emitPartial(map[entity]);this._sectionStart=this._index+1}}};Tokenizer.prototype._parseLegacyEntity=function(){var start=this._sectionStart+1,limit=this._index-start;if(limit>6)limit=6;while(limit>=2){var entity=this._buffer.substr(start,limit);if(legacyMap.hasOwnProperty(entity)){this._emitPartial(legacyMap[entity]);this._sectionStart+=limit+1;return}else{limit--}}};Tokenizer.prototype._stateInNamedEntity=function(c){if(c===";"){this._parseNamedEntityStrict();if(this._sectionStart+1<this._index&&!this._xmlMode){this._parseLegacyEntity()}this._state=this._baseState}else if((c<"a"||c>"z")&&(c<"A"||c>"Z")&&(c<"0"||c>"9")){if(this._xmlMode);else if(this._sectionStart+1===this._index);else if(this._baseState!==TEXT){if(c!=="="){this._parseNamedEntityStrict()}}else{this._parseLegacyEntity()}this._state=this._baseState;this._index--}};Tokenizer.prototype._decodeNumericEntity=function(offset,base){var sectionStart=this._sectionStart+offset;if(sectionStart!==this._index){var entity=this._buffer.substring(sectionStart,this._index);var parsed=parseInt(entity,base);this._emitPartial(decodeCodePoint(parsed));this._sectionStart=this._index}else{this._sectionStart--}this._state=this._baseState};Tokenizer.prototype._stateInNumericEntity=function(c){if(c===";"){this._decodeNumericEntity(2,10);this._sectionStart++}else if(c<"0"||c>"9"){if(!this._xmlMode){this._decodeNumericEntity(2,10)}else{this._state=this._baseState}this._index--}};Tokenizer.prototype._stateInHexEntity=function(c){if(c===";"){this._decodeNumericEntity(3,16);this._sectionStart++}else if((c<"a"||c>"f")&&(c<"A"||c>"F")&&(c<"0"||c>"9")){if(!this._xmlMode){this._decodeNumericEntity(3,16)}else{this._state=this._baseState}this._index--}};Tokenizer.prototype._cleanup=function(){if(this._sectionStart<0){this._buffer="";this._index=0;this._bufferOffset+=this._index}else if(this._running){if(this._state===TEXT){if(this._sectionStart!==this._index){this._cbs.ontext(this._buffer.substr(this._sectionStart))}this._buffer="";this._bufferOffset+=this._index;this._index=0}else if(this._sectionStart===this._index){this._buffer="";this._bufferOffset+=this._index;this._index=0}else{this._buffer=this._buffer.substr(this._sectionStart);this._index-=this._sectionStart;this._bufferOffset+=this._sectionStart}this._sectionStart=0}};Tokenizer.prototype.write=function(chunk){if(this._ended)this._cbs.onerror(Error(".write() after done!"));this._buffer+=chunk;this._parse()};Tokenizer.prototype._parse=function(){while(this._index<this._buffer.length&&this._running){var c=this._buffer.charAt(this._index);if(this._state===TEXT){this._stateText(c)}else if(this._state===BEFORE_TAG_NAME){this._stateBeforeTagName(c)}else if(this._state===IN_TAG_NAME){this._stateInTagName(c)}else if(this._state===BEFORE_CLOSING_TAG_NAME){this._stateBeforeCloseingTagName(c)}else if(this._state===IN_CLOSING_TAG_NAME){this._stateInCloseingTagName(c)}else if(this._state===AFTER_CLOSING_TAG_NAME){this._stateAfterCloseingTagName(c)}else if(this._state===IN_SELF_CLOSING_TAG){this._stateInSelfClosingTag(c)}else if(this._state===BEFORE_ATTRIBUTE_NAME){this._stateBeforeAttributeName(c)}else if(this._state===IN_ATTRIBUTE_NAME){this._stateInAttributeName(c)}else if(this._state===AFTER_ATTRIBUTE_NAME){this._stateAfterAttributeName(c)}else if(this._state===BEFORE_ATTRIBUTE_VALUE){this._stateBeforeAttributeValue(c)}else if(this._state===IN_ATTRIBUTE_VALUE_DQ){this._stateInAttributeValueDoubleQuotes(c)}else if(this._state===IN_ATTRIBUTE_VALUE_SQ){this._stateInAttributeValueSingleQuotes(c)}else if(this._state===IN_ATTRIBUTE_VALUE_NQ){this._stateInAttributeValueNoQuotes(c)}else if(this._state===BEFORE_DECLARATION){this._stateBeforeDeclaration(c)}else if(this._state===IN_DECLARATION){this._stateInDeclaration(c)}else if(this._state===IN_PROCESSING_INSTRUCTION){this._stateInProcessingInstruction(c)}else if(this._state===BEFORE_COMMENT){this._stateBeforeComment(c)}else if(this._state===IN_COMMENT){this._stateInComment(c)}else if(this._state===AFTER_COMMENT_1){this._stateAfterComment1(c)}else if(this._state===AFTER_COMMENT_2){this._stateAfterComment2(c)}else if(this._state===BEFORE_CDATA_1){this._stateBeforeCdata1(c)}else if(this._state===BEFORE_CDATA_2){this._stateBeforeCdata2(c)}else if(this._state===BEFORE_CDATA_3){this._stateBeforeCdata3(c)}else if(this._state===BEFORE_CDATA_4){this._stateBeforeCdata4(c)}else if(this._state===BEFORE_CDATA_5){this._stateBeforeCdata5(c)}else if(this._state===BEFORE_CDATA_6){this._stateBeforeCdata6(c)}else if(this._state===IN_CDATA){this._stateInCdata(c)}else if(this._state===AFTER_CDATA_1){this._stateAfterCdata1(c)}else if(this._state===AFTER_CDATA_2){this._stateAfterCdata2(c)}else if(this._state===BEFORE_SPECIAL){this._stateBeforeSpecial(c)}else if(this._state===BEFORE_SPECIAL_END){this._stateBeforeSpecialEnd(c)}else if(this._state===BEFORE_SCRIPT_1){this._stateBeforeScript1(c)}else if(this._state===BEFORE_SCRIPT_2){this._stateBeforeScript2(c)}else if(this._state===BEFORE_SCRIPT_3){this._stateBeforeScript3(c)}else if(this._state===BEFORE_SCRIPT_4){this._stateBeforeScript4(c)}else if(this._state===BEFORE_SCRIPT_5){this._stateBeforeScript5(c)}else if(this._state===AFTER_SCRIPT_1){this._stateAfterScript1(c)}else if(this._state===AFTER_SCRIPT_2){this._stateAfterScript2(c)}else if(this._state===AFTER_SCRIPT_3){this._stateAfterScript3(c)}else if(this._state===AFTER_SCRIPT_4){this._stateAfterScript4(c)}else if(this._state===AFTER_SCRIPT_5){this._stateAfterScript5(c)}else if(this._state===BEFORE_STYLE_1){this._stateBeforeStyle1(c)}else if(this._state===BEFORE_STYLE_2){this._stateBeforeStyle2(c)}else if(this._state===BEFORE_STYLE_3){this._stateBeforeStyle3(c)}else if(this._state===BEFORE_STYLE_4){this._stateBeforeStyle4(c)}else if(this._state===AFTER_STYLE_1){this._stateAfterStyle1(c)}else if(this._state===AFTER_STYLE_2){this._stateAfterStyle2(c)}else if(this._state===AFTER_STYLE_3){this._stateAfterStyle3(c)}else if(this._state===AFTER_STYLE_4){this._stateAfterStyle4(c)}else if(this._state===BEFORE_ENTITY){this._stateBeforeEntity(c)}else if(this._state===BEFORE_NUMERIC_ENTITY){this._stateBeforeNumericEntity(c)}else if(this._state===IN_NAMED_ENTITY){this._stateInNamedEntity(c)}else if(this._state===IN_NUMERIC_ENTITY){this._stateInNumericEntity(c)}else if(this._state===IN_HEX_ENTITY){this._stateInHexEntity(c)}else{this._cbs.onerror(Error("unknown _state"),this._state)}this._index++}this._cleanup()};Tokenizer.prototype.pause=function(){this._running=false};Tokenizer.prototype.resume=function(){this._running=true;if(this._index<this._buffer.length){this._parse()}if(this._ended){this._finish()}};Tokenizer.prototype.end=function(chunk){if(this._ended)this._cbs.onerror(Error(".end() after done!"));if(chunk)this.write(chunk);this._ended=true;if(this._running)this._finish()};Tokenizer.prototype._finish=function(){if(this._sectionStart<this._index){this._handleTrailingData()}this._cbs.onend()};Tokenizer.prototype._handleTrailingData=function(){var data=this._buffer.substr(this._sectionStart);if(this._state===IN_CDATA||this._state===AFTER_CDATA_1||this._state===AFTER_CDATA_2){this._cbs.oncdata(data)}else if(this._state===IN_COMMENT||this._state===AFTER_COMMENT_1||this._state===AFTER_COMMENT_2){this._cbs.oncomment(data)}else if(this._state===IN_NAMED_ENTITY&&!this._xmlMode){this._parseLegacyEntity();if(this._sectionStart<this._index){this._state=this._baseState;this._handleTrailingData()}}else if(this._state===IN_NUMERIC_ENTITY&&!this._xmlMode){this._decodeNumericEntity(2,10);if(this._sectionStart<this._index){this._state=this._baseState;this._handleTrailingData()}}else if(this._state===IN_HEX_ENTITY&&!this._xmlMode){this._decodeNumericEntity(3,16);if(this._sectionStart<this._index){this._state=this._baseState;this._handleTrailingData()}}else if(this._state!==IN_TAG_NAME&&this._state!==BEFORE_ATTRIBUTE_NAME&&this._state!==BEFORE_ATTRIBUTE_VALUE&&this._state!==AFTER_ATTRIBUTE_NAME&&this._state!==IN_ATTRIBUTE_NAME&&this._state!==IN_ATTRIBUTE_VALUE_SQ&&this._state!==IN_ATTRIBUTE_VALUE_DQ&&this._state!==IN_ATTRIBUTE_VALUE_NQ&&this._state!==IN_CLOSING_TAG_NAME){
+this._cbs.ontext(data)}};Tokenizer.prototype.reset=function(){Tokenizer.call(this,{xmlMode:this._xmlMode,decodeEntities:this._decodeEntities},this._cbs)};Tokenizer.prototype.getAbsoluteIndex=function(){return this._bufferOffset+this._index};Tokenizer.prototype._getSection=function(){return this._buffer.substring(this._sectionStart,this._index)};Tokenizer.prototype._emitToken=function(name){this._cbs[name](this._getSection());this._sectionStart=-1};Tokenizer.prototype._emitPartial=function(value){if(this._baseState!==TEXT){this._cbs.onattribdata(value)}else{this._cbs.ontext(value)}}},{"entities/lib/decode_codepoint.js":22,"entities/maps/entities.json":25,"entities/maps/legacy.json":26,"entities/maps/xml.json":27}],35:[function(require,module,exports){module.exports=Stream;var Parser=require("./Parser.js"),WritableStream=require("stream").Writable||require("readable-stream").Writable,StringDecoder=require("string_decoder").StringDecoder,Buffer=require("buffer").Buffer;function Stream(cbs,options){var parser=this._parser=new Parser(cbs,options);var decoder=this._decoder=new StringDecoder;WritableStream.call(this,{decodeStrings:false});this.once("finish",function(){parser.end(decoder.end())})}require("inherits")(Stream,WritableStream);WritableStream.prototype._write=function(chunk,encoding,cb){if(chunk instanceof Buffer)chunk=this._decoder.write(chunk);this._parser.write(chunk);cb()}},{"./Parser.js":31,buffer:5,inherits:38,"readable-stream":3,stream:55,string_decoder:56}],36:[function(require,module,exports){var Parser=require("./Parser.js"),DomHandler=require("domhandler");function defineProp(name,value){delete module.exports[name];module.exports[name]=value;return value}module.exports={Parser:Parser,Tokenizer:require("./Tokenizer.js"),ElementType:require("domelementtype"),DomHandler:DomHandler,get FeedHandler(){return defineProp("FeedHandler",require("./FeedHandler.js"))},get Stream(){return defineProp("Stream",require("./Stream.js"))},get WritableStream(){return defineProp("WritableStream",require("./WritableStream.js"))},get ProxyHandler(){return defineProp("ProxyHandler",require("./ProxyHandler.js"))},get DomUtils(){return defineProp("DomUtils",require("domutils"))},get CollectingHandler(){return defineProp("CollectingHandler",require("./CollectingHandler.js"))},DefaultHandler:DomHandler,get RssHandler(){return defineProp("RssHandler",this.FeedHandler)},parseDOM:function(data,options){var handler=new DomHandler(options);new Parser(handler,options).end(data);return handler.dom},parseFeed:function(feed,options){var handler=new module.exports.FeedHandler(options);new Parser(handler,options).end(feed);return handler.dom},createDomStream:function(cb,options,elementCb){var handler=new DomHandler(cb,options,elementCb);return new Parser(handler,options)},EVENTS:{attribute:2,cdatastart:0,cdataend:0,text:1,processinginstruction:2,comment:1,commentend:0,closetag:1,opentag:2,opentagname:1,error:1,end:0}}},{"./CollectingHandler.js":29,"./FeedHandler.js":30,"./Parser.js":31,"./ProxyHandler.js":32,"./Stream.js":33,"./Tokenizer.js":34,"./WritableStream.js":35,domelementtype:9,domhandler:10,domutils:13}],37:[function(require,module,exports){exports.read=function(buffer,offset,isLE,mLen,nBytes){var e,m;var eLen=nBytes*8-mLen-1;var eMax=(1<<eLen)-1;var eBias=eMax>>1;var nBits=-7;var i=isLE?nBytes-1:0;var d=isLE?-1:1;var s=buffer[offset+i];i+=d;e=s&(1<<-nBits)-1;s>>=-nBits;nBits+=eLen;for(;nBits>0;e=e*256+buffer[offset+i],i+=d,nBits-=8){}m=e&(1<<-nBits)-1;e>>=-nBits;nBits+=mLen;for(;nBits>0;m=m*256+buffer[offset+i],i+=d,nBits-=8){}if(e===0){e=1-eBias}else if(e===eMax){return m?NaN:(s?-1:1)*Infinity}else{m=m+Math.pow(2,mLen);e=e-eBias}return(s?-1:1)*m*Math.pow(2,e-mLen)};exports.write=function(buffer,value,offset,isLE,mLen,nBytes){var e,m,c;var eLen=nBytes*8-mLen-1;var eMax=(1<<eLen)-1;var eBias=eMax>>1;var rt=mLen===23?Math.pow(2,-24)-Math.pow(2,-77):0;var i=isLE?0:nBytes-1;var d=isLE?1:-1;var s=value<0||value===0&&1/value<0?1:0;value=Math.abs(value);if(isNaN(value)||value===Infinity){m=isNaN(value)?1:0;e=eMax}else{e=Math.floor(Math.log(value)/Math.LN2);if(value*(c=Math.pow(2,-e))<1){e--;c*=2}if(e+eBias>=1){value+=rt/c}else{value+=rt*Math.pow(2,1-eBias)}if(value*c>=2){e++;c/=2}if(e+eBias>=eMax){m=0;e=eMax}else if(e+eBias>=1){m=(value*c-1)*Math.pow(2,mLen);e=e+eBias}else{m=value*Math.pow(2,eBias-1)*Math.pow(2,mLen);e=0}}for(;mLen>=8;buffer[offset+i]=m&255,i+=d,m/=256,mLen-=8){}e=e<<mLen|m;eLen+=mLen;for(;eLen>0;buffer[offset+i]=e&255,i+=d,e/=256,eLen-=8){}buffer[offset+i-d]|=s*128}},{}],38:[function(require,module,exports){if(typeof Object.create==="function"){module.exports=function inherits(ctor,superCtor){ctor.super_=superCtor;ctor.prototype=Object.create(superCtor.prototype,{constructor:{value:ctor,enumerable:false,writable:true,configurable:true}})}}else{module.exports=function inherits(ctor,superCtor){ctor.super_=superCtor;var TempCtor=function(){};TempCtor.prototype=superCtor.prototype;ctor.prototype=new TempCtor;ctor.prototype.constructor=ctor}}},{}],39:[function(require,module,exports){module.exports=function(obj){return obj!=null&&(isBuffer(obj)||isSlowBuffer(obj)||!!obj._isBuffer)};function isBuffer(obj){return!!obj.constructor&&typeof obj.constructor.isBuffer==="function"&&obj.constructor.isBuffer(obj)}function isSlowBuffer(obj){return typeof obj.readFloatLE==="function"&&typeof obj.slice==="function"&&isBuffer(obj.slice(0,0))}},{}],40:[function(require,module,exports){var toString={}.toString;module.exports=Array.isArray||function(arr){return toString.call(arr)=="[object Array]"}},{}],41:[function(require,module,exports){(function(process){"use strict";if(!process.version||process.version.indexOf("v0.")===0||process.version.indexOf("v1.")===0&&process.version.indexOf("v1.8.")!==0){module.exports=nextTick}else{module.exports=process.nextTick}function nextTick(fn,arg1,arg2,arg3){if(typeof fn!=="function"){throw new TypeError('"callback" argument must be a function')}var len=arguments.length;var args,i;switch(len){case 0:case 1:return process.nextTick(fn);case 2:return process.nextTick(function afterTickOne(){fn.call(null,arg1)});case 3:return process.nextTick(function afterTickTwo(){fn.call(null,arg1,arg2)});case 4:return process.nextTick(function afterTickThree(){fn.call(null,arg1,arg2,arg3)});default:args=new Array(len-1);i=0;while(i<args.length){args[i++]=arguments[i]}return process.nextTick(function afterTick(){fn.apply(null,args)})}}}).call(this,require("_process"))},{_process:42}],42:[function(require,module,exports){var process=module.exports={};var cachedSetTimeout;var cachedClearTimeout;function defaultSetTimout(){throw new Error("setTimeout has not been defined")}function defaultClearTimeout(){throw new Error("clearTimeout has not been defined")}(function(){try{if(typeof setTimeout==="function"){cachedSetTimeout=setTimeout}else{cachedSetTimeout=defaultSetTimout}}catch(e){cachedSetTimeout=defaultSetTimout}try{if(typeof clearTimeout==="function"){cachedClearTimeout=clearTimeout}else{cachedClearTimeout=defaultClearTimeout}}catch(e){cachedClearTimeout=defaultClearTimeout}})();function runTimeout(fun){if(cachedSetTimeout===setTimeout){return setTimeout(fun,0)}if((cachedSetTimeout===defaultSetTimout||!cachedSetTimeout)&&setTimeout){cachedSetTimeout=setTimeout;return setTimeout(fun,0)}try{return cachedSetTimeout(fun,0)}catch(e){try{return cachedSetTimeout.call(null,fun,0)}catch(e){return cachedSetTimeout.call(this,fun,0)}}}function runClearTimeout(marker){if(cachedClearTimeout===clearTimeout){return clearTimeout(marker)}if((cachedClearTimeout===defaultClearTimeout||!cachedClearTimeout)&&clearTimeout){cachedClearTimeout=clearTimeout;return clearTimeout(marker)}try{return cachedClearTimeout(marker)}catch(e){try{return cachedClearTimeout.call(null,marker)}catch(e){return cachedClearTimeout.call(this,marker)}}}var queue=[];var draining=false;var currentQueue;var queueIndex=-1;function cleanUpNextTick(){if(!draining||!currentQueue){return}draining=false;if(currentQueue.length){queue=currentQueue.concat(queue)}else{queueIndex=-1}if(queue.length){drainQueue()}}function drainQueue(){if(draining){return}var timeout=runTimeout(cleanUpNextTick);draining=true;var len=queue.length;while(len){currentQueue=queue;queue=[];while(++queueIndex<len){if(currentQueue){currentQueue[queueIndex].run()}}queueIndex=-1;len=queue.length}currentQueue=null;draining=false;runClearTimeout(timeout)}process.nextTick=function(fun){var args=new Array(arguments.length-1);if(arguments.length>1){for(var i=1;i<arguments.length;i++){args[i-1]=arguments[i]}}queue.push(new Item(fun,args));if(queue.length===1&&!draining){runTimeout(drainQueue)}};function Item(fun,array){this.fun=fun;this.array=array}Item.prototype.run=function(){this.fun.apply(null,this.array)};process.title="browser";process.browser=true;process.env={};process.argv=[];process.version="";process.versions={};function noop(){}process.on=noop;process.addListener=noop;process.once=noop;process.off=noop;process.removeListener=noop;process.removeAllListeners=noop;process.emit=noop;process.binding=function(name){throw new Error("process.binding is not supported")};process.cwd=function(){return"/"};process.chdir=function(dir){throw new Error("process.chdir is not supported")};process.umask=function(){return 0}},{}],43:[function(require,module,exports){module.exports=require("./lib/_stream_duplex.js")},{"./lib/_stream_duplex.js":44}],44:[function(require,module,exports){"use strict";var objectKeys=Object.keys||function(obj){var keys=[];for(var key in obj){keys.push(key)}return keys};module.exports=Duplex;var processNextTick=require("process-nextick-args");var util=require("core-util-is");util.inherits=require("inherits");var Readable=require("./_stream_readable");var Writable=require("./_stream_writable");util.inherits(Duplex,Readable);var keys=objectKeys(Writable.prototype);for(var v=0;v<keys.length;v++){var method=keys[v];if(!Duplex.prototype[method])Duplex.prototype[method]=Writable.prototype[method]}function Duplex(options){if(!(this instanceof Duplex))return new Duplex(options);Readable.call(this,options);Writable.call(this,options);if(options&&options.readable===false)this.readable=false;if(options&&options.writable===false)this.writable=false;this.allowHalfOpen=true;if(options&&options.allowHalfOpen===false)this.allowHalfOpen=false;this.once("end",onend)}function onend(){if(this.allowHalfOpen||this._writableState.ended)return;processNextTick(onEndNT,this)}function onEndNT(self){self.end()}function forEach(xs,f){for(var i=0,l=xs.length;i<l;i++){f(xs[i],i)}}},{"./_stream_readable":46,"./_stream_writable":48,"core-util-is":6,inherits:38,"process-nextick-args":41}],45:[function(require,module,exports){"use strict";module.exports=PassThrough;var Transform=require("./_stream_transform");var util=require("core-util-is");util.inherits=require("inherits");util.inherits(PassThrough,Transform);function PassThrough(options){if(!(this instanceof PassThrough))return new PassThrough(options);Transform.call(this,options)}PassThrough.prototype._transform=function(chunk,encoding,cb){cb(null,chunk)}},{"./_stream_transform":47,"core-util-is":6,inherits:38}],46:[function(require,module,exports){(function(process){"use strict";module.exports=Readable;var processNextTick=require("process-nextick-args");var isArray=require("isarray");Readable.ReadableState=ReadableState;var EE=require("events").EventEmitter;var EElistenerCount=function(emitter,type){return emitter.listeners(type).length};var Stream;(function(){try{Stream=require("st"+"ream")}catch(_){}finally{if(!Stream)Stream=require("events").EventEmitter}})();var Buffer=require("buffer").Buffer;var bufferShim=require("buffer-shims");var util=require("core-util-is");util.inherits=require("inherits");var debugUtil=require("util");var debug=void 0;if(debugUtil&&debugUtil.debuglog){debug=debugUtil.debuglog("stream")}else{debug=function(){}}var BufferList=require("./internal/streams/BufferList");var StringDecoder;util.inherits(Readable,Stream);function prependListener(emitter,event,fn){if(typeof emitter.prependListener==="function"){return emitter.prependListener(event,fn)}else{if(!emitter._events||!emitter._events[event])emitter.on(event,fn);else if(isArray(emitter._events[event]))emitter._events[event].unshift(fn);else emitter._events[event]=[fn,emitter._events[event]]}}var Duplex;function ReadableState(options,stream){Duplex=Duplex||require("./_stream_duplex");options=options||{};this.objectMode=!!options.objectMode;if(stream instanceof Duplex)this.objectMode=this.objectMode||!!options.readableObjectMode;var hwm=options.highWaterMark;var defaultHwm=this.objectMode?16:16*1024;this.highWaterMark=hwm||hwm===0?hwm:defaultHwm;this.highWaterMark=~~this.highWaterMark;this.buffer=new BufferList;this.length=0;this.pipes=null;this.pipesCount=0;this.flowing=null;this.ended=false;this.endEmitted=false;this.reading=false;this.sync=true;this.needReadable=false;this.emittedReadable=false;this.readableListening=false;this.resumeScheduled=false;this.defaultEncoding=options.defaultEncoding||"utf8";this.ranOut=false;this.awaitDrain=0;this.readingMore=false;this.decoder=null;this.encoding=null;if(options.encoding){if(!StringDecoder)StringDecoder=require("string_decoder/").StringDecoder;this.decoder=new StringDecoder(options.encoding);this.encoding=options.encoding}}var Duplex;function Readable(options){Duplex=Duplex||require("./_stream_duplex");if(!(this instanceof Readable))return new Readable(options);this._readableState=new ReadableState(options,this);this.readable=true;if(options&&typeof options.read==="function")this._read=options.read;Stream.call(this)}Readable.prototype.push=function(chunk,encoding){var state=this._readableState;if(!state.objectMode&&typeof chunk==="string"){encoding=encoding||state.defaultEncoding;if(encoding!==state.encoding){chunk=bufferShim.from(chunk,encoding);encoding=""}}return readableAddChunk(this,state,chunk,encoding,false)};Readable.prototype.unshift=function(chunk){var state=this._readableState;return readableAddChunk(this,state,chunk,"",true)};Readable.prototype.isPaused=function(){return this._readableState.flowing===false};function readableAddChunk(stream,state,chunk,encoding,addToFront){var er=chunkInvalid(state,chunk);if(er){stream.emit("error",er)}else if(chunk===null){state.reading=false;onEofChunk(stream,state)}else if(state.objectMode||chunk&&chunk.length>0){if(state.ended&&!addToFront){var e=new Error("stream.push() after EOF");stream.emit("error",e)}else if(state.endEmitted&&addToFront){var _e=new Error("stream.unshift() after end event");stream.emit("error",_e)}else{var skipAdd;if(state.decoder&&!addToFront&&!encoding){chunk=state.decoder.write(chunk);skipAdd=!state.objectMode&&chunk.length===0}if(!addToFront)state.reading=false;if(!skipAdd){if(state.flowing&&state.length===0&&!state.sync){stream.emit("data",chunk);stream.read(0)}else{state.length+=state.objectMode?1:chunk.length;if(addToFront)state.buffer.unshift(chunk);else state.buffer.push(chunk);if(state.needReadable)emitReadable(stream)}}maybeReadMore(stream,state)}}else if(!addToFront){state.reading=false}return needMoreData(state)}function needMoreData(state){return!state.ended&&(state.needReadable||state.length<state.highWaterMark||state.length===0)}Readable.prototype.setEncoding=function(enc){if(!StringDecoder)StringDecoder=require("string_decoder/").StringDecoder;this._readableState.decoder=new StringDecoder(enc);this._readableState.encoding=enc;return this};var MAX_HWM=8388608;function computeNewHighWaterMark(n){if(n>=MAX_HWM){n=MAX_HWM}else{n--;n|=n>>>1;n|=n>>>2;n|=n>>>4;n|=n>>>8;n|=n>>>16;n++}return n}function howMuchToRead(n,state){if(n<=0||state.length===0&&state.ended)return 0;if(state.objectMode)return 1;if(n!==n){if(state.flowing&&state.length)return state.buffer.head.data.length;else return state.length}if(n>state.highWaterMark)state.highWaterMark=computeNewHighWaterMark(n);if(n<=state.length)return n;if(!state.ended){state.needReadable=true;return 0}return state.length}Readable.prototype.read=function(n){debug("read",n);n=parseInt(n,10);var state=this._readableState;var nOrig=n;if(n!==0)state.emittedReadable=false;if(n===0&&state.needReadable&&(state.length>=state.highWaterMark||state.ended)){debug("read: emitReadable",state.length,state.ended);if(state.length===0&&state.ended)endReadable(this);else emitReadable(this);return null}n=howMuchToRead(n,state);if(n===0&&state.ended){if(state.length===0)endReadable(this);return null}var doRead=state.needReadable;debug("need readable",doRead);if(state.length===0||state.length-n<state.highWaterMark){doRead=true;debug("length less than watermark",doRead)}if(state.ended||state.reading){doRead=false;debug("reading or ended",doRead)}else if(doRead){debug("do read");state.reading=true;state.sync=true;if(state.length===0)state.needReadable=true;this._read(state.highWaterMark);state.sync=false;if(!state.reading)n=howMuchToRead(nOrig,state)}var ret;if(n>0)ret=fromList(n,state);else ret=null;if(ret===null){state.needReadable=true;n=0}else{state.length-=n}if(state.length===0){if(!state.ended)state.needReadable=true;if(nOrig!==n&&state.ended)endReadable(this)}if(ret!==null)this.emit("data",ret);return ret};function chunkInvalid(state,chunk){var er=null;if(!Buffer.isBuffer(chunk)&&typeof chunk!=="string"&&chunk!==null&&chunk!==undefined&&!state.objectMode){er=new TypeError("Invalid non-string/buffer chunk")}return er}function onEofChunk(stream,state){if(state.ended)return;if(state.decoder){var chunk=state.decoder.end();if(chunk&&chunk.length){state.buffer.push(chunk);state.length+=state.objectMode?1:chunk.length}}state.ended=true;emitReadable(stream)}function emitReadable(stream){var state=stream._readableState;state.needReadable=false;if(!state.emittedReadable){debug("emitReadable",state.flowing);state.emittedReadable=true;if(state.sync)processNextTick(emitReadable_,stream);else emitReadable_(stream)}}function emitReadable_(stream){debug("emit readable");stream.emit("readable");flow(stream)}function maybeReadMore(stream,state){if(!state.readingMore){state.readingMore=true;processNextTick(maybeReadMore_,stream,state)}}function maybeReadMore_(stream,state){var len=state.length;while(!state.reading&&!state.flowing&&!state.ended&&state.length<state.highWaterMark){debug("maybeReadMore read 0");stream.read(0);if(len===state.length)break;else len=state.length}state.readingMore=false}Readable.prototype._read=function(n){this.emit("error",new Error("not implemented"))};Readable.prototype.pipe=function(dest,pipeOpts){var src=this;var state=this._readableState;switch(state.pipesCount){case 0:state.pipes=dest;break;case 1:state.pipes=[state.pipes,dest];break;default:state.pipes.push(dest);break}state.pipesCount+=1;debug("pipe count=%d opts=%j",state.pipesCount,pipeOpts);var doEnd=(!pipeOpts||pipeOpts.end!==false)&&dest!==process.stdout&&dest!==process.stderr;var endFn=doEnd?onend:cleanup;if(state.endEmitted)processNextTick(endFn);else src.once("end",endFn);dest.on("unpipe",onunpipe);function onunpipe(readable){debug("onunpipe");if(readable===src){cleanup()}}function onend(){debug("onend");dest.end()}var ondrain=pipeOnDrain(src);dest.on("drain",ondrain);var cleanedUp=false;function cleanup(){debug("cleanup");dest.removeListener("close",onclose);dest.removeListener("finish",onfinish);dest.removeListener("drain",ondrain);dest.removeListener("error",onerror);dest.removeListener("unpipe",onunpipe);src.removeListener("end",onend);src.removeListener("end",cleanup);src.removeListener("data",ondata);cleanedUp=true;if(state.awaitDrain&&(!dest._writableState||dest._writableState.needDrain))ondrain()}var increasedAwaitDrain=false;src.on("data",ondata);function ondata(chunk){debug("ondata");increasedAwaitDrain=false;var ret=dest.write(chunk);if(false===ret&&!increasedAwaitDrain){if((state.pipesCount===1&&state.pipes===dest||state.pipesCount>1&&indexOf(state.pipes,dest)!==-1)&&!cleanedUp){debug("false write response, pause",src._readableState.awaitDrain);src._readableState.awaitDrain++;increasedAwaitDrain=true}src.pause()}}function onerror(er){debug("onerror",er);unpipe();dest.removeListener("error",onerror);if(EElistenerCount(dest,"error")===0)dest.emit("error",er)}prependListener(dest,"error",onerror);function onclose(){dest.removeListener("finish",onfinish);unpipe()}dest.once("close",onclose);function onfinish(){debug("onfinish");dest.removeListener("close",onclose);unpipe()}dest.once("finish",onfinish);function unpipe(){debug("unpipe");src.unpipe(dest)}dest.emit("pipe",src);if(!state.flowing){debug("pipe resume");src.resume()}return dest};function pipeOnDrain(src){return function(){var state=src._readableState;debug("pipeOnDrain",state.awaitDrain);if(state.awaitDrain)state.awaitDrain--;if(state.awaitDrain===0&&EElistenerCount(src,"data")){state.flowing=true;flow(src)}}}Readable.prototype.unpipe=function(dest){var state=this._readableState;if(state.pipesCount===0)return this;if(state.pipesCount===1){if(dest&&dest!==state.pipes)return this;if(!dest)dest=state.pipes;state.pipes=null;state.pipesCount=0;state.flowing=false;if(dest)dest.emit("unpipe",this);return this}if(!dest){var dests=state.pipes;var len=state.pipesCount;state.pipes=null;state.pipesCount=0;state.flowing=false;for(var _i=0;_i<len;_i++){dests[_i].emit("unpipe",this)}return this}var i=indexOf(state.pipes,dest);if(i===-1)return this;state.pipes.splice(i,1);state.pipesCount-=1;if(state.pipesCount===1)state.pipes=state.pipes[0];dest.emit("unpipe",this);return this};Readable.prototype.on=function(ev,fn){var res=Stream.prototype.on.call(this,ev,fn);if(ev==="data"){if(this._readableState.flowing!==false)this.resume()}else if(ev==="readable"){var state=this._readableState;if(!state.endEmitted&&!state.readableListening){state.readableListening=state.needReadable=true;state.emittedReadable=false;if(!state.reading){processNextTick(nReadingNextTick,this)}else if(state.length){emitReadable(this,state)}}}return res};Readable.prototype.addListener=Readable.prototype.on;function nReadingNextTick(self){debug("readable nexttick read 0");self.read(0)}Readable.prototype.resume=function(){var state=this._readableState;if(!state.flowing){debug("resume");state.flowing=true;resume(this,state)}return this};function resume(stream,state){if(!state.resumeScheduled){state.resumeScheduled=true;processNextTick(resume_,stream,state)}}function resume_(stream,state){if(!state.reading){debug("resume read 0");stream.read(0)}state.resumeScheduled=false;state.awaitDrain=0;stream.emit("resume");flow(stream);if(state.flowing&&!state.reading)stream.read(0)}Readable.prototype.pause=function(){debug("call pause flowing=%j",this._readableState.flowing);if(false!==this._readableState.flowing){debug("pause");this._readableState.flowing=false;this.emit("pause")}return this};function flow(stream){var state=stream._readableState;debug("flow",state.flowing);while(state.flowing&&stream.read()!==null){}}Readable.prototype.wrap=function(stream){var state=this._readableState;var paused=false;var self=this;stream.on("end",function(){debug("wrapped end");if(state.decoder&&!state.ended){var chunk=state.decoder.end();if(chunk&&chunk.length)self.push(chunk)}self.push(null)});stream.on("data",function(chunk){debug("wrapped data");if(state.decoder)chunk=state.decoder.write(chunk);if(state.objectMode&&(chunk===null||chunk===undefined))return;else if(!state.objectMode&&(!chunk||!chunk.length))return;var ret=self.push(chunk);if(!ret){paused=true;stream.pause()}});for(var i in stream){if(this[i]===undefined&&typeof stream[i]==="function"){this[i]=function(method){return function(){return stream[method].apply(stream,arguments)}}(i)}}var events=["error","close","destroy","pause","resume"];forEach(events,function(ev){stream.on(ev,self.emit.bind(self,ev))});self._read=function(n){debug("wrapped _read",n);if(paused){paused=false;stream.resume()}};return self};Readable._fromList=fromList;function fromList(n,state){if(state.length===0)return null;var ret;if(state.objectMode)ret=state.buffer.shift();else if(!n||n>=state.length){if(state.decoder)ret=state.buffer.join("");else if(state.buffer.length===1)ret=state.buffer.head.data;else ret=state.buffer.concat(state.length);state.buffer.clear()}else{ret=fromListPartial(n,state.buffer,state.decoder)}return ret}function fromListPartial(n,list,hasStrings){var ret;if(n<list.head.data.length){ret=list.head.data.slice(0,n);list.head.data=list.head.data.slice(n)}else if(n===list.head.data.length){ret=list.shift()}else{ret=hasStrings?copyFromBufferString(n,list):copyFromBuffer(n,list)}return ret}function copyFromBufferString(n,list){var p=list.head;var c=1;var ret=p.data;n-=ret.length;while(p=p.next){var str=p.data;var nb=n>str.length?str.length:n;if(nb===str.length)ret+=str;else ret+=str.slice(0,n);n-=nb;if(n===0){if(nb===str.length){++c;if(p.next)list.head=p.next;else list.head=list.tail=null}else{list.head=p;p.data=str.slice(nb)}break}++c}list.length-=c;return ret}function copyFromBuffer(n,list){var ret=bufferShim.allocUnsafe(n);var p=list.head;var c=1;p.data.copy(ret);n-=p.data.length;while(p=p.next){var buf=p.data;var nb=n>buf.length?buf.length:n;buf.copy(ret,ret.length-n,0,nb);n-=nb;if(n===0){if(nb===buf.length){++c;if(p.next)list.head=p.next;else list.head=list.tail=null}else{list.head=p;p.data=buf.slice(nb)}break}++c}list.length-=c;return ret}function endReadable(stream){var state=stream._readableState;if(state.length>0)throw new Error('"endReadable()" called on non-empty stream');if(!state.endEmitted){state.ended=true;processNextTick(endReadableNT,state,stream)}}function endReadableNT(state,stream){if(!state.endEmitted&&state.length===0){state.endEmitted=true;stream.readable=false;stream.emit("end")}}function forEach(xs,f){for(var i=0,l=xs.length;i<l;i++){f(xs[i],i)}}function indexOf(xs,x){for(var i=0,l=xs.length;i<l;i++){if(xs[i]===x)return i}return-1}}).call(this,require("_process"))},{"./_stream_duplex":44,"./internal/streams/BufferList":49,_process:42,buffer:5,"buffer-shims":4,"core-util-is":6,events:28,inherits:38,isarray:40,"process-nextick-args":41,"string_decoder/":56,util:3}],47:[function(require,module,exports){"use strict";module.exports=Transform;var Duplex=require("./_stream_duplex");var util=require("core-util-is");util.inherits=require("inherits");util.inherits(Transform,Duplex);function TransformState(stream){this.afterTransform=function(er,data){return afterTransform(stream,er,data)};this.needTransform=false;this.transforming=false;this.writecb=null;this.writechunk=null;this.writeencoding=null}function afterTransform(stream,er,data){var ts=stream._transformState;ts.transforming=false;var cb=ts.writecb;if(!cb)return stream.emit("error",new Error("no writecb in Transform class"));ts.writechunk=null;ts.writecb=null;if(data!==null&&data!==undefined)stream.push(data);cb(er);var rs=stream._readableState;rs.reading=false;if(rs.needReadable||rs.length<rs.highWaterMark){stream._read(rs.highWaterMark)}}function Transform(options){if(!(this instanceof Transform))return new Transform(options);Duplex.call(this,options);this._transformState=new TransformState(this);var stream=this;this._readableState.needReadable=true;this._readableState.sync=false;if(options){if(typeof options.transform==="function")this._transform=options.transform;if(typeof options.flush==="function")this._flush=options.flush}this.once("prefinish",function(){if(typeof this._flush==="function")this._flush(function(er){done(stream,er)});else done(stream)})}Transform.prototype.push=function(chunk,encoding){this._transformState.needTransform=false;return Duplex.prototype.push.call(this,chunk,encoding)};Transform.prototype._transform=function(chunk,encoding,cb){throw new Error("Not implemented")};Transform.prototype._write=function(chunk,encoding,cb){var ts=this._transformState;ts.writecb=cb;ts.writechunk=chunk;ts.writeencoding=encoding;if(!ts.transforming){var rs=this._readableState;if(ts.needTransform||rs.needReadable||rs.length<rs.highWaterMark)this._read(rs.highWaterMark)}};Transform.prototype._read=function(n){var ts=this._transformState;if(ts.writechunk!==null&&ts.writecb&&!ts.transforming){ts.transforming=true;this._transform(ts.writechunk,ts.writeencoding,ts.afterTransform)}else{ts.needTransform=true}};function done(stream,er){if(er)return stream.emit("error",er);var ws=stream._writableState;var ts=stream._transformState;if(ws.length)throw new Error("Calling transform done when ws.length != 0");if(ts.transforming)throw new Error("Calling transform done when still transforming");return stream.push(null)}},{"./_stream_duplex":44,"core-util-is":6,inherits:38}],48:[function(require,module,exports){(function(process){"use strict";module.exports=Writable;var processNextTick=require("process-nextick-args");var asyncWrite=!process.browser&&["v0.10","v0.9."].indexOf(process.version.slice(0,5))>-1?setImmediate:processNextTick;Writable.WritableState=WritableState;var util=require("core-util-is");util.inherits=require("inherits");var internalUtil={deprecate:require("util-deprecate")};var Stream;(function(){try{Stream=require("st"+"ream")}catch(_){}finally{if(!Stream)Stream=require("events").EventEmitter}})();var Buffer=require("buffer").Buffer;var bufferShim=require("buffer-shims");util.inherits(Writable,Stream);function nop(){}function WriteReq(chunk,encoding,cb){this.chunk=chunk;this.encoding=encoding;this.callback=cb;this.next=null}var Duplex;function WritableState(options,stream){Duplex=Duplex||require("./_stream_duplex");options=options||{};this.objectMode=!!options.objectMode;if(stream instanceof Duplex)this.objectMode=this.objectMode||!!options.writableObjectMode;var hwm=options.highWaterMark;var defaultHwm=this.objectMode?16:16*1024;this.highWaterMark=hwm||hwm===0?hwm:defaultHwm;this.highWaterMark=~~this.highWaterMark;this.needDrain=false;this.ending=false;this.ended=false;this.finished=false;var noDecode=options.decodeStrings===false;this.decodeStrings=!noDecode;this.defaultEncoding=options.defaultEncoding||"utf8";this.length=0;this.writing=false;this.corked=0;this.sync=true;this.bufferProcessing=false;this.onwrite=function(er){onwrite(stream,er)};this.writecb=null;this.writelen=0;this.bufferedRequest=null;this.lastBufferedRequest=null;this.pendingcb=0;this.prefinished=false;this.errorEmitted=false;this.bufferedRequestCount=0;this.corkedRequestsFree=new CorkedRequest(this)}WritableState.prototype.getBuffer=function writableStateGetBuffer(){var current=this.bufferedRequest;var out=[];while(current){out.push(current);current=current.next}return out};(function(){try{Object.defineProperty(WritableState.prototype,"buffer",{get:internalUtil.deprecate(function(){return this.getBuffer()},"_writableState.buffer is deprecated. Use _writableState.getBuffer "+"instead.")})}catch(_){}})();var Duplex;function Writable(options){Duplex=Duplex||require("./_stream_duplex");if(!(this instanceof Writable)&&!(this instanceof Duplex))return new Writable(options);this._writableState=new WritableState(options,this);this.writable=true;if(options){if(typeof options.write==="function")this._write=options.write;if(typeof options.writev==="function")this._writev=options.writev}Stream.call(this)}Writable.prototype.pipe=function(){this.emit("error",new Error("Cannot pipe, not readable"))};function writeAfterEnd(stream,cb){var er=new Error("write after end");stream.emit("error",er);processNextTick(cb,er)}function validChunk(stream,state,chunk,cb){var valid=true;var er=false;if(chunk===null){er=new TypeError("May not write null values to stream")}else if(!Buffer.isBuffer(chunk)&&typeof chunk!=="string"&&chunk!==undefined&&!state.objectMode){er=new TypeError("Invalid non-string/buffer chunk")}if(er){stream.emit("error",er);processNextTick(cb,er);valid=false}return valid}Writable.prototype.write=function(chunk,encoding,cb){var state=this._writableState;var ret=false;if(typeof encoding==="function"){cb=encoding;encoding=null}if(Buffer.isBuffer(chunk))encoding="buffer";else if(!encoding)encoding=state.defaultEncoding;if(typeof cb!=="function")cb=nop;if(state.ended)writeAfterEnd(this,cb);else if(validChunk(this,state,chunk,cb)){
+state.pendingcb++;ret=writeOrBuffer(this,state,chunk,encoding,cb)}return ret};Writable.prototype.cork=function(){var state=this._writableState;state.corked++};Writable.prototype.uncork=function(){var state=this._writableState;if(state.corked){state.corked--;if(!state.writing&&!state.corked&&!state.finished&&!state.bufferProcessing&&state.bufferedRequest)clearBuffer(this,state)}};Writable.prototype.setDefaultEncoding=function setDefaultEncoding(encoding){if(typeof encoding==="string")encoding=encoding.toLowerCase();if(!(["hex","utf8","utf-8","ascii","binary","base64","ucs2","ucs-2","utf16le","utf-16le","raw"].indexOf((encoding+"").toLowerCase())>-1))throw new TypeError("Unknown encoding: "+encoding);this._writableState.defaultEncoding=encoding;return this};function decodeChunk(state,chunk,encoding){if(!state.objectMode&&state.decodeStrings!==false&&typeof chunk==="string"){chunk=bufferShim.from(chunk,encoding)}return chunk}function writeOrBuffer(stream,state,chunk,encoding,cb){chunk=decodeChunk(state,chunk,encoding);if(Buffer.isBuffer(chunk))encoding="buffer";var len=state.objectMode?1:chunk.length;state.length+=len;var ret=state.length<state.highWaterMark;if(!ret)state.needDrain=true;if(state.writing||state.corked){var last=state.lastBufferedRequest;state.lastBufferedRequest=new WriteReq(chunk,encoding,cb);if(last){last.next=state.lastBufferedRequest}else{state.bufferedRequest=state.lastBufferedRequest}state.bufferedRequestCount+=1}else{doWrite(stream,state,false,len,chunk,encoding,cb)}return ret}function doWrite(stream,state,writev,len,chunk,encoding,cb){state.writelen=len;state.writecb=cb;state.writing=true;state.sync=true;if(writev)stream._writev(chunk,state.onwrite);else stream._write(chunk,encoding,state.onwrite);state.sync=false}function onwriteError(stream,state,sync,er,cb){--state.pendingcb;if(sync)processNextTick(cb,er);else cb(er);stream._writableState.errorEmitted=true;stream.emit("error",er)}function onwriteStateUpdate(state){state.writing=false;state.writecb=null;state.length-=state.writelen;state.writelen=0}function onwrite(stream,er){var state=stream._writableState;var sync=state.sync;var cb=state.writecb;onwriteStateUpdate(state);if(er)onwriteError(stream,state,sync,er,cb);else{var finished=needFinish(state);if(!finished&&!state.corked&&!state.bufferProcessing&&state.bufferedRequest){clearBuffer(stream,state)}if(sync){asyncWrite(afterWrite,stream,state,finished,cb)}else{afterWrite(stream,state,finished,cb)}}}function afterWrite(stream,state,finished,cb){if(!finished)onwriteDrain(stream,state);state.pendingcb--;cb();finishMaybe(stream,state)}function onwriteDrain(stream,state){if(state.length===0&&state.needDrain){state.needDrain=false;stream.emit("drain")}}function clearBuffer(stream,state){state.bufferProcessing=true;var entry=state.bufferedRequest;if(stream._writev&&entry&&entry.next){var l=state.bufferedRequestCount;var buffer=new Array(l);var holder=state.corkedRequestsFree;holder.entry=entry;var count=0;while(entry){buffer[count]=entry;entry=entry.next;count+=1}doWrite(stream,state,true,state.length,buffer,"",holder.finish);state.pendingcb++;state.lastBufferedRequest=null;if(holder.next){state.corkedRequestsFree=holder.next;holder.next=null}else{state.corkedRequestsFree=new CorkedRequest(state)}}else{while(entry){var chunk=entry.chunk;var encoding=entry.encoding;var cb=entry.callback;var len=state.objectMode?1:chunk.length;doWrite(stream,state,false,len,chunk,encoding,cb);entry=entry.next;if(state.writing){break}}if(entry===null)state.lastBufferedRequest=null}state.bufferedRequestCount=0;state.bufferedRequest=entry;state.bufferProcessing=false}Writable.prototype._write=function(chunk,encoding,cb){cb(new Error("not implemented"))};Writable.prototype._writev=null;Writable.prototype.end=function(chunk,encoding,cb){var state=this._writableState;if(typeof chunk==="function"){cb=chunk;chunk=null;encoding=null}else if(typeof encoding==="function"){cb=encoding;encoding=null}if(chunk!==null&&chunk!==undefined)this.write(chunk,encoding);if(state.corked){state.corked=1;this.uncork()}if(!state.ending&&!state.finished)endWritable(this,state,cb)};function needFinish(state){return state.ending&&state.length===0&&state.bufferedRequest===null&&!state.finished&&!state.writing}function prefinish(stream,state){if(!state.prefinished){state.prefinished=true;stream.emit("prefinish")}}function finishMaybe(stream,state){var need=needFinish(state);if(need){if(state.pendingcb===0){prefinish(stream,state);state.finished=true;stream.emit("finish")}else{prefinish(stream,state)}}return need}function endWritable(stream,state,cb){state.ending=true;finishMaybe(stream,state);if(cb){if(state.finished)processNextTick(cb);else stream.once("finish",cb)}state.ended=true;stream.writable=false}function CorkedRequest(state){var _this=this;this.next=null;this.entry=null;this.finish=function(err){var entry=_this.entry;_this.entry=null;while(entry){var cb=entry.callback;state.pendingcb--;cb(err);entry=entry.next}if(state.corkedRequestsFree){state.corkedRequestsFree.next=_this}else{state.corkedRequestsFree=_this}}}}).call(this,require("_process"))},{"./_stream_duplex":44,_process:42,buffer:5,"buffer-shims":4,"core-util-is":6,events:28,inherits:38,"process-nextick-args":41,"util-deprecate":57}],49:[function(require,module,exports){"use strict";var Buffer=require("buffer").Buffer;var bufferShim=require("buffer-shims");module.exports=BufferList;function BufferList(){this.head=null;this.tail=null;this.length=0}BufferList.prototype.push=function(v){var entry={data:v,next:null};if(this.length>0)this.tail.next=entry;else this.head=entry;this.tail=entry;++this.length};BufferList.prototype.unshift=function(v){var entry={data:v,next:this.head};if(this.length===0)this.tail=entry;this.head=entry;++this.length};BufferList.prototype.shift=function(){if(this.length===0)return;var ret=this.head.data;if(this.length===1)this.head=this.tail=null;else this.head=this.head.next;--this.length;return ret};BufferList.prototype.clear=function(){this.head=this.tail=null;this.length=0};BufferList.prototype.join=function(s){if(this.length===0)return"";var p=this.head;var ret=""+p.data;while(p=p.next){ret+=s+p.data}return ret};BufferList.prototype.concat=function(n){if(this.length===0)return bufferShim.alloc(0);if(this.length===1)return this.head.data;var ret=bufferShim.allocUnsafe(n>>>0);var p=this.head;var i=0;while(p){p.data.copy(ret,i);i+=p.data.length;p=p.next}return ret}},{buffer:5,"buffer-shims":4}],50:[function(require,module,exports){module.exports=require("./lib/_stream_passthrough.js")},{"./lib/_stream_passthrough.js":45}],51:[function(require,module,exports){(function(process){var Stream=function(){try{return require("st"+"ream")}catch(_){}}();exports=module.exports=require("./lib/_stream_readable.js");exports.Stream=Stream||exports;exports.Readable=exports;exports.Writable=require("./lib/_stream_writable.js");exports.Duplex=require("./lib/_stream_duplex.js");exports.Transform=require("./lib/_stream_transform.js");exports.PassThrough=require("./lib/_stream_passthrough.js");if(!process.browser&&process.env.READABLE_STREAM==="disable"&&Stream){module.exports=Stream}}).call(this,require("_process"))},{"./lib/_stream_duplex.js":44,"./lib/_stream_passthrough.js":45,"./lib/_stream_readable.js":46,"./lib/_stream_transform.js":47,"./lib/_stream_writable.js":48,_process:42}],52:[function(require,module,exports){module.exports=require("./lib/_stream_transform.js")},{"./lib/_stream_transform.js":47}],53:[function(require,module,exports){module.exports=require("./lib/_stream_writable.js")},{"./lib/_stream_writable.js":48}],54:[function(require,module,exports){module.exports=function(string){return string.replace(/[-\\^$*+?.()|[\]{}]/g,"\\$&")}},{}],55:[function(require,module,exports){module.exports=Stream;var EE=require("events").EventEmitter;var inherits=require("inherits");inherits(Stream,EE);Stream.Readable=require("readable-stream/readable.js");Stream.Writable=require("readable-stream/writable.js");Stream.Duplex=require("readable-stream/duplex.js");Stream.Transform=require("readable-stream/transform.js");Stream.PassThrough=require("readable-stream/passthrough.js");Stream.Stream=Stream;function Stream(){EE.call(this)}Stream.prototype.pipe=function(dest,options){var source=this;function ondata(chunk){if(dest.writable){if(false===dest.write(chunk)&&source.pause){source.pause()}}}source.on("data",ondata);function ondrain(){if(source.readable&&source.resume){source.resume()}}dest.on("drain",ondrain);if(!dest._isStdio&&(!options||options.end!==false)){source.on("end",onend);source.on("close",onclose)}var didOnEnd=false;function onend(){if(didOnEnd)return;didOnEnd=true;dest.end()}function onclose(){if(didOnEnd)return;didOnEnd=true;if(typeof dest.destroy==="function")dest.destroy()}function onerror(er){cleanup();if(EE.listenerCount(this,"error")===0){throw er}}source.on("error",onerror);dest.on("error",onerror);function cleanup(){source.removeListener("data",ondata);dest.removeListener("drain",ondrain);source.removeListener("end",onend);source.removeListener("close",onclose);source.removeListener("error",onerror);dest.removeListener("error",onerror);source.removeListener("end",cleanup);source.removeListener("close",cleanup);dest.removeListener("close",cleanup)}source.on("end",cleanup);source.on("close",cleanup);dest.on("close",cleanup);dest.emit("pipe",source);return dest}},{events:28,inherits:38,"readable-stream/duplex.js":43,"readable-stream/passthrough.js":50,"readable-stream/readable.js":51,"readable-stream/transform.js":52,"readable-stream/writable.js":53}],56:[function(require,module,exports){var Buffer=require("buffer").Buffer;var isBufferEncoding=Buffer.isEncoding||function(encoding){switch(encoding&&encoding.toLowerCase()){case"hex":case"utf8":case"utf-8":case"ascii":case"binary":case"base64":case"ucs2":case"ucs-2":case"utf16le":case"utf-16le":case"raw":return true;default:return false}};function assertEncoding(encoding){if(encoding&&!isBufferEncoding(encoding)){throw new Error("Unknown encoding: "+encoding)}}var StringDecoder=exports.StringDecoder=function(encoding){this.encoding=(encoding||"utf8").toLowerCase().replace(/[-_]/,"");assertEncoding(encoding);switch(this.encoding){case"utf8":this.surrogateSize=3;break;case"ucs2":case"utf16le":this.surrogateSize=2;this.detectIncompleteChar=utf16DetectIncompleteChar;break;case"base64":this.surrogateSize=3;this.detectIncompleteChar=base64DetectIncompleteChar;break;default:this.write=passThroughWrite;return}this.charBuffer=new Buffer(6);this.charReceived=0;this.charLength=0};StringDecoder.prototype.write=function(buffer){var charStr="";while(this.charLength){var available=buffer.length>=this.charLength-this.charReceived?this.charLength-this.charReceived:buffer.length;buffer.copy(this.charBuffer,this.charReceived,0,available);this.charReceived+=available;if(this.charReceived<this.charLength){return""}buffer=buffer.slice(available,buffer.length);charStr=this.charBuffer.slice(0,this.charLength).toString(this.encoding);var charCode=charStr.charCodeAt(charStr.length-1);if(charCode>=55296&&charCode<=56319){this.charLength+=this.surrogateSize;charStr="";continue}this.charReceived=this.charLength=0;if(buffer.length===0){return charStr}break}this.detectIncompleteChar(buffer);var end=buffer.length;if(this.charLength){buffer.copy(this.charBuffer,0,buffer.length-this.charReceived,end);end-=this.charReceived}charStr+=buffer.toString(this.encoding,0,end);var end=charStr.length-1;var charCode=charStr.charCodeAt(end);if(charCode>=55296&&charCode<=56319){var size=this.surrogateSize;this.charLength+=size;this.charReceived+=size;this.charBuffer.copy(this.charBuffer,size,0,size);buffer.copy(this.charBuffer,0,0,size);return charStr.substring(0,end)}return charStr};StringDecoder.prototype.detectIncompleteChar=function(buffer){var i=buffer.length>=3?3:buffer.length;for(;i>0;i--){var c=buffer[buffer.length-i];if(i==1&&c>>5==6){this.charLength=2;break}if(i<=2&&c>>4==14){this.charLength=3;break}if(i<=3&&c>>3==30){this.charLength=4;break}}this.charReceived=i};StringDecoder.prototype.end=function(buffer){var res="";if(buffer&&buffer.length)res=this.write(buffer);if(this.charReceived){var cr=this.charReceived;var buf=this.charBuffer;var enc=this.encoding;res+=buf.slice(0,cr).toString(enc)}return res};function passThroughWrite(buffer){return buffer.toString(this.encoding)}function utf16DetectIncompleteChar(buffer){this.charReceived=buffer.length%2;this.charLength=this.charReceived?2:0}function base64DetectIncompleteChar(buffer){this.charReceived=buffer.length%3;this.charLength=this.charReceived?3:0}},{buffer:5}],57:[function(require,module,exports){(function(global){module.exports=deprecate;function deprecate(fn,msg){if(config("noDeprecation")){return fn}var warned=false;function deprecated(){if(!warned){if(config("throwDeprecation")){throw new Error(msg)}else if(config("traceDeprecation")){console.trace(msg)}else{console.warn(msg)}warned=true}return fn.apply(this,arguments)}return deprecated}function config(name){try{if(!global.localStorage)return false}catch(_){return false}var val=global.localStorage[name];if(null==val)return false;return String(val).toLowerCase()==="true"}}).call(this,typeof global!=="undefined"?global:typeof self!=="undefined"?self:typeof window!=="undefined"?window:{})},{}],58:[function(require,module,exports){module.exports=extend;var hasOwnProperty=Object.prototype.hasOwnProperty;function extend(){var target={};for(var i=0;i<arguments.length;i++){var source=arguments[i];for(var key in source){if(hasOwnProperty.call(source,key)){target[key]=source[key]}}}return target}},{}]},{},[1])(1)});
diff --git a/ydb/core/viewer/content/api/lib/swagger-oauth.js b/ydb/core/viewer/content/api/lib/swagger-oauth.js
index 109f9fc33e0..a35bda3c082 100644
--- a/ydb/core/viewer/content/api/lib/swagger-oauth.js
+++ b/ydb/core/viewer/content/api/lib/swagger-oauth.js
@@ -1,347 +1,347 @@
-var appName;
-var popupMask;
-var popupDialog;
-var clientId;
-var realm;
-var redirect_uri;
-var clientSecret;
-var scopeSeparator;
-var additionalQueryStringParams;
-
-function handleLogin() {
- var scopes = [];
-
- var auths = window.swaggerUi.api.authSchemes || window.swaggerUi.api.securityDefinitions;
- if(auths) {
- var key;
- var defs = auths;
- for(key in defs) {
- var auth = defs[key];
- if(auth.type === 'oauth2' && auth.scopes) {
- var scope;
- if(Array.isArray(auth.scopes)) {
- // 1.2 support
- var i;
- for(i = 0; i < auth.scopes.length; i++) {
- scopes.push(auth.scopes[i]);
- }
- }
- else {
- // 2.0 support
- for(scope in auth.scopes) {
- scopes.push({scope: scope, description: auth.scopes[scope], OAuthSchemeKey: key});
- }
- }
- }
- }
- }
-
- if(window.swaggerUi.api
- && window.swaggerUi.api.info) {
- appName = window.swaggerUi.api.info.title;
- }
-
- $('.api-popup-dialog').remove();
- popupDialog = $(
- [
- '<div class="api-popup-dialog">',
- '<div class="api-popup-title">Select OAuth2.0 Scopes</div>',
- '<div class="api-popup-content">',
- '<p>Scopes are used to grant an application different levels of access to data on behalf of the end user. Each API may declare one or more scopes.',
- '<a href="#">Learn how to use</a>',
- '</p>',
- '<p><strong>' + appName + '</strong> API requires the following scopes. Select which ones you want to grant to Swagger UI.</p>',
- '<ul class="api-popup-scopes">',
- '</ul>',
- '<p class="error-msg"></p>',
- '<div class="api-popup-actions"><button class="api-popup-authbtn api-button green" type="button">Authorize</button><button class="api-popup-cancel api-button gray" type="button">Cancel</button></div>',
- '</div>',
- '</div>'].join(''));
- $(document.body).append(popupDialog);
-
- //TODO: only display applicable scopes (will need to pass them into handleLogin)
- popup = popupDialog.find('ul.api-popup-scopes').empty();
- for (i = 0; i < scopes.length; i ++) {
- scope = scopes[i];
- str = '<li><input type="checkbox" id="scope_' + i + '" scope="' + scope.scope + '"' +'" oauthtype="' + scope.OAuthSchemeKey +'"/>' + '<label for="scope_' + i + '">' + scope.scope ;
- if (scope.description) {
- if ($.map(auths, function(n, i) { return i; }).length > 1) //if we have more than one scheme, display schemes
- str += '<br/><span class="api-scope-desc">' + scope.description + ' ('+ scope.OAuthSchemeKey+')' +'</span>';
- else
- str += '<br/><span class="api-scope-desc">' + scope.description + '</span>';
- }
- str += '</label></li>';
- popup.append(str);
- }
-
- var $win = $(window),
- dw = $win.width(),
- dh = $win.height(),
- st = $win.scrollTop(),
- dlgWd = popupDialog.outerWidth(),
- dlgHt = popupDialog.outerHeight(),
- top = (dh -dlgHt)/2 + st,
- left = (dw - dlgWd)/2;
-
- popupDialog.css({
- top: (top < 0? 0 : top) + 'px',
- left: (left < 0? 0 : left) + 'px'
- });
-
- popupDialog.find('button.api-popup-cancel').click(function() {
- popupMask.hide();
- popupDialog.hide();
- popupDialog.empty();
- popupDialog = [];
- });
-
- $('button.api-popup-authbtn').unbind();
- popupDialog.find('button.api-popup-authbtn').click(function() {
- popupMask.hide();
- popupDialog.hide();
-
- var authSchemes = window.swaggerUi.api.authSchemes;
- var host = window.location;
- var pathname = location.pathname.substring(0, location.pathname.lastIndexOf("/"));
- var defaultRedirectUrl = host.protocol + '//' + host.host + pathname + '/o2c.html';
- var redirectUrl = window.oAuthRedirectUrl || defaultRedirectUrl;
- var url = null;
- var scopes = []
- var o = popup.find('input:checked');
- var OAuthSchemeKeys = [];
- var state;
- for(k =0; k < o.length; k++) {
- var scope = $(o[k]).attr('scope');
- if (scopes.indexOf(scope) === -1)
- scopes.push(scope);
- var OAuthSchemeKey = $(o[k]).attr('oauthtype');
- if (OAuthSchemeKeys.indexOf(OAuthSchemeKey) === -1)
- OAuthSchemeKeys.push(OAuthSchemeKey);
- }
-
- //TODO: merge not replace if scheme is different from any existing
- //(needs to be aware of schemes to do so correctly)
- window.enabledScopes=scopes;
-
- for (var key in authSchemes) {
- if (authSchemes.hasOwnProperty(key) && OAuthSchemeKeys.indexOf(key) != -1) { //only look at keys that match this scope.
- var flow = authSchemes[key].flow;
-
- if(authSchemes[key].type === 'oauth2' && flow && (flow === 'implicit' || flow === 'accessCode')) {
- var dets = authSchemes[key];
- url = dets.authorizationUrl + '?response_type=' + (flow === 'implicit' ? 'token' : 'code');
- window.swaggerUi.tokenName = dets.tokenName || 'access_token';
- window.swaggerUi.tokenUrl = (flow === 'accessCode' ? dets.tokenUrl : null);
- state = key;
- }
- else if(authSchemes[key].type === 'oauth2' && flow && (flow === 'application')) {
- var dets = authSchemes[key];
- window.swaggerUi.tokenName = dets.tokenName || 'access_token';
- clientCredentialsFlow(scopes, dets.tokenUrl, key);
- return;
- }
- else if(authSchemes[key].grantTypes) {
- // 1.2 support
- var o = authSchemes[key].grantTypes;
- for(var t in o) {
- if(o.hasOwnProperty(t) && t === 'implicit') {
- var dets = o[t];
- var ep = dets.loginEndpoint.url;
- url = dets.loginEndpoint.url + '?response_type=token';
- window.swaggerUi.tokenName = dets.tokenName;
- }
- else if (o.hasOwnProperty(t) && t === 'accessCode') {
- var dets = o[t];
- var ep = dets.tokenRequestEndpoint.url;
- url = dets.tokenRequestEndpoint.url + '?response_type=code';
- window.swaggerUi.tokenName = dets.tokenName;
- }
- }
- }
- }
- }
-
- redirect_uri = redirectUrl;
-
- url += '&redirect_uri=' + encodeURIComponent(redirectUrl);
- url += '&realm=' + encodeURIComponent(realm);
- url += '&client_id=' + encodeURIComponent(clientId);
- url += '&scope=' + encodeURIComponent(scopes.join(scopeSeparator));
- url += '&state=' + encodeURIComponent(state);
- for (var key in additionalQueryStringParams) {
- url += '&' + key + '=' + encodeURIComponent(additionalQueryStringParams[key]);
- }
-
- window.open(url);
- });
-
- popupMask.show();
- popupDialog.show();
- return;
-}
-
-
-function handleLogout() {
- for(key in window.swaggerUi.api.clientAuthorizations.authz){
- window.swaggerUi.api.clientAuthorizations.remove(key)
- }
- window.enabledScopes = null;
- $('.api-ic.ic-on').addClass('ic-off');
- $('.api-ic.ic-on').removeClass('ic-on');
-
- // set the info box
- $('.api-ic.ic-warning').addClass('ic-error');
- $('.api-ic.ic-warning').removeClass('ic-warning');
-}
-
-function initOAuth(opts) {
- var o = (opts||{});
- var errors = [];
-
- appName = (o.appName||errors.push('missing appName'));
- popupMask = (o.popupMask||$('#api-common-mask'));
- popupDialog = (o.popupDialog||$('.api-popup-dialog'));
- clientId = (o.clientId||errors.push('missing client id'));
- clientSecret = (o.clientSecret||null);
- realm = (o.realm||errors.push('missing realm'));
- scopeSeparator = (o.scopeSeparator||' ');
- additionalQueryStringParams = (o.additionalQueryStringParams||{});
-
- if(errors.length > 0){
- log('auth unable initialize oauth: ' + errors);
- return;
- }
-
- $('pre code').each(function(i, e) {hljs.highlightBlock(e)});
- $('.api-ic').unbind();
- $('.api-ic').click(function(s) {
- if($(s.target).hasClass('ic-off'))
- handleLogin();
- else {
- handleLogout();
- }
- false;
- });
-}
-
-function clientCredentialsFlow(scopes, tokenUrl, OAuthSchemeKey) {
- var params = {
- 'client_id': clientId,
- 'client_secret': clientSecret,
- 'scope': scopes.join(' '),
- 'grant_type': 'client_credentials'
- }
- $.ajax(
- {
- url : tokenUrl,
- type: "POST",
- data: params,
- success:function(data, textStatus, jqXHR)
- {
- onOAuthComplete(data,OAuthSchemeKey);
- },
- error: function(jqXHR, textStatus, errorThrown)
- {
- onOAuthComplete("");
- }
- });
-
- }
-
-window.processOAuthCode = function processOAuthCode(data) {
- var OAuthSchemeKey = data.state;
-
- // redirect_uri is required in auth code flow
- // see https://tools.ietf.org/html/draft-ietf-oauth-v2-31#section-4.1.3
- var host = window.location;
- var pathname = location.pathname.substring(0, location.pathname.lastIndexOf("/"));
- var defaultRedirectUrl = host.protocol + '//' + host.host + pathname + '/o2c.html';
- var redirectUrl = window.oAuthRedirectUrl || defaultRedirectUrl;
-
- var params = {
- 'client_id': clientId,
- 'code': data.code,
- 'grant_type': 'authorization_code',
- 'redirect_uri': redirectUrl
- };
-
- if (clientSecret) {
- params.client_secret = clientSecret;
- }
-
- $.ajax(
- {
- url : window.swaggerUi.tokenUrl,
- type: "POST",
- data: params,
- success:function(data, textStatus, jqXHR)
- {
- onOAuthComplete(data, OAuthSchemeKey);
- },
- error: function(jqXHR, textStatus, errorThrown)
- {
- onOAuthComplete("");
- }
- });
-};
-
-window.onOAuthComplete = function onOAuthComplete(token,OAuthSchemeKey) {
- if(token) {
- if(token.error) {
- var checkbox = $('input[type=checkbox],.secured')
- checkbox.each(function(pos){
- checkbox[pos].checked = false;
- });
- alert(token.error);
- }
- else {
- var b = token[window.swaggerUi.tokenName];
- if (!OAuthSchemeKey){
- OAuthSchemeKey = token.state;
- }
- if(b){
- // if all roles are satisfied
- var o = null;
- $.each($('.auth .api-ic .api_information_panel'), function(k, v) {
- var children = v;
- if(children && children.childNodes) {
- var requiredScopes = [];
- $.each((children.childNodes), function (k1, v1){
- var inner = v1.innerHTML;
- if(inner)
- requiredScopes.push(inner);
- });
- var diff = [];
- for(var i=0; i < requiredScopes.length; i++) {
- var s = requiredScopes[i];
- if(window.enabledScopes && window.enabledScopes.indexOf(s) == -1) {
- diff.push(s);
- }
- }
- if(diff.length > 0){
- o = v.parentNode.parentNode;
- $(o.parentNode).find('.api-ic.ic-on').addClass('ic-off');
- $(o.parentNode).find('.api-ic.ic-on').removeClass('ic-on');
-
- // sorry, not all scopes are satisfied
- $(o).find('.api-ic').addClass('ic-warning');
- $(o).find('.api-ic').removeClass('ic-error');
- }
- else {
- o = v.parentNode.parentNode;
- $(o.parentNode).find('.api-ic.ic-off').addClass('ic-on');
- $(o.parentNode).find('.api-ic.ic-off').removeClass('ic-off');
-
- // all scopes are satisfied
- $(o).find('.api-ic').addClass('ic-info');
- $(o).find('.api-ic').removeClass('ic-warning');
- $(o).find('.api-ic').removeClass('ic-error');
- }
- }
- });
- window.swaggerUi.api.clientAuthorizations.add(window.OAuthSchemeKey, new SwaggerClient.ApiKeyAuthorization('Authorization', 'Bearer ' + b, 'header'));
- window.swaggerUi.load();
- }
- }
- }
-};
+var appName;
+var popupMask;
+var popupDialog;
+var clientId;
+var realm;
+var redirect_uri;
+var clientSecret;
+var scopeSeparator;
+var additionalQueryStringParams;
+
+function handleLogin() {
+ var scopes = [];
+
+ var auths = window.swaggerUi.api.authSchemes || window.swaggerUi.api.securityDefinitions;
+ if(auths) {
+ var key;
+ var defs = auths;
+ for(key in defs) {
+ var auth = defs[key];
+ if(auth.type === 'oauth2' && auth.scopes) {
+ var scope;
+ if(Array.isArray(auth.scopes)) {
+ // 1.2 support
+ var i;
+ for(i = 0; i < auth.scopes.length; i++) {
+ scopes.push(auth.scopes[i]);
+ }
+ }
+ else {
+ // 2.0 support
+ for(scope in auth.scopes) {
+ scopes.push({scope: scope, description: auth.scopes[scope], OAuthSchemeKey: key});
+ }
+ }
+ }
+ }
+ }
+
+ if(window.swaggerUi.api
+ && window.swaggerUi.api.info) {
+ appName = window.swaggerUi.api.info.title;
+ }
+
+ $('.api-popup-dialog').remove();
+ popupDialog = $(
+ [
+ '<div class="api-popup-dialog">',
+ '<div class="api-popup-title">Select OAuth2.0 Scopes</div>',
+ '<div class="api-popup-content">',
+ '<p>Scopes are used to grant an application different levels of access to data on behalf of the end user. Each API may declare one or more scopes.',
+ '<a href="#">Learn how to use</a>',
+ '</p>',
+ '<p><strong>' + appName + '</strong> API requires the following scopes. Select which ones you want to grant to Swagger UI.</p>',
+ '<ul class="api-popup-scopes">',
+ '</ul>',
+ '<p class="error-msg"></p>',
+ '<div class="api-popup-actions"><button class="api-popup-authbtn api-button green" type="button">Authorize</button><button class="api-popup-cancel api-button gray" type="button">Cancel</button></div>',
+ '</div>',
+ '</div>'].join(''));
+ $(document.body).append(popupDialog);
+
+ //TODO: only display applicable scopes (will need to pass them into handleLogin)
+ popup = popupDialog.find('ul.api-popup-scopes').empty();
+ for (i = 0; i < scopes.length; i ++) {
+ scope = scopes[i];
+ str = '<li><input type="checkbox" id="scope_' + i + '" scope="' + scope.scope + '"' +'" oauthtype="' + scope.OAuthSchemeKey +'"/>' + '<label for="scope_' + i + '">' + scope.scope ;
+ if (scope.description) {
+ if ($.map(auths, function(n, i) { return i; }).length > 1) //if we have more than one scheme, display schemes
+ str += '<br/><span class="api-scope-desc">' + scope.description + ' ('+ scope.OAuthSchemeKey+')' +'</span>';
+ else
+ str += '<br/><span class="api-scope-desc">' + scope.description + '</span>';
+ }
+ str += '</label></li>';
+ popup.append(str);
+ }
+
+ var $win = $(window),
+ dw = $win.width(),
+ dh = $win.height(),
+ st = $win.scrollTop(),
+ dlgWd = popupDialog.outerWidth(),
+ dlgHt = popupDialog.outerHeight(),
+ top = (dh -dlgHt)/2 + st,
+ left = (dw - dlgWd)/2;
+
+ popupDialog.css({
+ top: (top < 0? 0 : top) + 'px',
+ left: (left < 0? 0 : left) + 'px'
+ });
+
+ popupDialog.find('button.api-popup-cancel').click(function() {
+ popupMask.hide();
+ popupDialog.hide();
+ popupDialog.empty();
+ popupDialog = [];
+ });
+
+ $('button.api-popup-authbtn').unbind();
+ popupDialog.find('button.api-popup-authbtn').click(function() {
+ popupMask.hide();
+ popupDialog.hide();
+
+ var authSchemes = window.swaggerUi.api.authSchemes;
+ var host = window.location;
+ var pathname = location.pathname.substring(0, location.pathname.lastIndexOf("/"));
+ var defaultRedirectUrl = host.protocol + '//' + host.host + pathname + '/o2c.html';
+ var redirectUrl = window.oAuthRedirectUrl || defaultRedirectUrl;
+ var url = null;
+ var scopes = []
+ var o = popup.find('input:checked');
+ var OAuthSchemeKeys = [];
+ var state;
+ for(k =0; k < o.length; k++) {
+ var scope = $(o[k]).attr('scope');
+ if (scopes.indexOf(scope) === -1)
+ scopes.push(scope);
+ var OAuthSchemeKey = $(o[k]).attr('oauthtype');
+ if (OAuthSchemeKeys.indexOf(OAuthSchemeKey) === -1)
+ OAuthSchemeKeys.push(OAuthSchemeKey);
+ }
+
+ //TODO: merge not replace if scheme is different from any existing
+ //(needs to be aware of schemes to do so correctly)
+ window.enabledScopes=scopes;
+
+ for (var key in authSchemes) {
+ if (authSchemes.hasOwnProperty(key) && OAuthSchemeKeys.indexOf(key) != -1) { //only look at keys that match this scope.
+ var flow = authSchemes[key].flow;
+
+ if(authSchemes[key].type === 'oauth2' && flow && (flow === 'implicit' || flow === 'accessCode')) {
+ var dets = authSchemes[key];
+ url = dets.authorizationUrl + '?response_type=' + (flow === 'implicit' ? 'token' : 'code');
+ window.swaggerUi.tokenName = dets.tokenName || 'access_token';
+ window.swaggerUi.tokenUrl = (flow === 'accessCode' ? dets.tokenUrl : null);
+ state = key;
+ }
+ else if(authSchemes[key].type === 'oauth2' && flow && (flow === 'application')) {
+ var dets = authSchemes[key];
+ window.swaggerUi.tokenName = dets.tokenName || 'access_token';
+ clientCredentialsFlow(scopes, dets.tokenUrl, key);
+ return;
+ }
+ else if(authSchemes[key].grantTypes) {
+ // 1.2 support
+ var o = authSchemes[key].grantTypes;
+ for(var t in o) {
+ if(o.hasOwnProperty(t) && t === 'implicit') {
+ var dets = o[t];
+ var ep = dets.loginEndpoint.url;
+ url = dets.loginEndpoint.url + '?response_type=token';
+ window.swaggerUi.tokenName = dets.tokenName;
+ }
+ else if (o.hasOwnProperty(t) && t === 'accessCode') {
+ var dets = o[t];
+ var ep = dets.tokenRequestEndpoint.url;
+ url = dets.tokenRequestEndpoint.url + '?response_type=code';
+ window.swaggerUi.tokenName = dets.tokenName;
+ }
+ }
+ }
+ }
+ }
+
+ redirect_uri = redirectUrl;
+
+ url += '&redirect_uri=' + encodeURIComponent(redirectUrl);
+ url += '&realm=' + encodeURIComponent(realm);
+ url += '&client_id=' + encodeURIComponent(clientId);
+ url += '&scope=' + encodeURIComponent(scopes.join(scopeSeparator));
+ url += '&state=' + encodeURIComponent(state);
+ for (var key in additionalQueryStringParams) {
+ url += '&' + key + '=' + encodeURIComponent(additionalQueryStringParams[key]);
+ }
+
+ window.open(url);
+ });
+
+ popupMask.show();
+ popupDialog.show();
+ return;
+}
+
+
+function handleLogout() {
+ for(key in window.swaggerUi.api.clientAuthorizations.authz){
+ window.swaggerUi.api.clientAuthorizations.remove(key)
+ }
+ window.enabledScopes = null;
+ $('.api-ic.ic-on').addClass('ic-off');
+ $('.api-ic.ic-on').removeClass('ic-on');
+
+ // set the info box
+ $('.api-ic.ic-warning').addClass('ic-error');
+ $('.api-ic.ic-warning').removeClass('ic-warning');
+}
+
+function initOAuth(opts) {
+ var o = (opts||{});
+ var errors = [];
+
+ appName = (o.appName||errors.push('missing appName'));
+ popupMask = (o.popupMask||$('#api-common-mask'));
+ popupDialog = (o.popupDialog||$('.api-popup-dialog'));
+ clientId = (o.clientId||errors.push('missing client id'));
+ clientSecret = (o.clientSecret||null);
+ realm = (o.realm||errors.push('missing realm'));
+ scopeSeparator = (o.scopeSeparator||' ');
+ additionalQueryStringParams = (o.additionalQueryStringParams||{});
+
+ if(errors.length > 0){
+ log('auth unable initialize oauth: ' + errors);
+ return;
+ }
+
+ $('pre code').each(function(i, e) {hljs.highlightBlock(e)});
+ $('.api-ic').unbind();
+ $('.api-ic').click(function(s) {
+ if($(s.target).hasClass('ic-off'))
+ handleLogin();
+ else {
+ handleLogout();
+ }
+ false;
+ });
+}
+
+function clientCredentialsFlow(scopes, tokenUrl, OAuthSchemeKey) {
+ var params = {
+ 'client_id': clientId,
+ 'client_secret': clientSecret,
+ 'scope': scopes.join(' '),
+ 'grant_type': 'client_credentials'
+ }
+ $.ajax(
+ {
+ url : tokenUrl,
+ type: "POST",
+ data: params,
+ success:function(data, textStatus, jqXHR)
+ {
+ onOAuthComplete(data,OAuthSchemeKey);
+ },
+ error: function(jqXHR, textStatus, errorThrown)
+ {
+ onOAuthComplete("");
+ }
+ });
+
+ }
+
+window.processOAuthCode = function processOAuthCode(data) {
+ var OAuthSchemeKey = data.state;
+
+ // redirect_uri is required in auth code flow
+ // see https://tools.ietf.org/html/draft-ietf-oauth-v2-31#section-4.1.3
+ var host = window.location;
+ var pathname = location.pathname.substring(0, location.pathname.lastIndexOf("/"));
+ var defaultRedirectUrl = host.protocol + '//' + host.host + pathname + '/o2c.html';
+ var redirectUrl = window.oAuthRedirectUrl || defaultRedirectUrl;
+
+ var params = {
+ 'client_id': clientId,
+ 'code': data.code,
+ 'grant_type': 'authorization_code',
+ 'redirect_uri': redirectUrl
+ };
+
+ if (clientSecret) {
+ params.client_secret = clientSecret;
+ }
+
+ $.ajax(
+ {
+ url : window.swaggerUi.tokenUrl,
+ type: "POST",
+ data: params,
+ success:function(data, textStatus, jqXHR)
+ {
+ onOAuthComplete(data, OAuthSchemeKey);
+ },
+ error: function(jqXHR, textStatus, errorThrown)
+ {
+ onOAuthComplete("");
+ }
+ });
+};
+
+window.onOAuthComplete = function onOAuthComplete(token,OAuthSchemeKey) {
+ if(token) {
+ if(token.error) {
+ var checkbox = $('input[type=checkbox],.secured')
+ checkbox.each(function(pos){
+ checkbox[pos].checked = false;
+ });
+ alert(token.error);
+ }
+ else {
+ var b = token[window.swaggerUi.tokenName];
+ if (!OAuthSchemeKey){
+ OAuthSchemeKey = token.state;
+ }
+ if(b){
+ // if all roles are satisfied
+ var o = null;
+ $.each($('.auth .api-ic .api_information_panel'), function(k, v) {
+ var children = v;
+ if(children && children.childNodes) {
+ var requiredScopes = [];
+ $.each((children.childNodes), function (k1, v1){
+ var inner = v1.innerHTML;
+ if(inner)
+ requiredScopes.push(inner);
+ });
+ var diff = [];
+ for(var i=0; i < requiredScopes.length; i++) {
+ var s = requiredScopes[i];
+ if(window.enabledScopes && window.enabledScopes.indexOf(s) == -1) {
+ diff.push(s);
+ }
+ }
+ if(diff.length > 0){
+ o = v.parentNode.parentNode;
+ $(o.parentNode).find('.api-ic.ic-on').addClass('ic-off');
+ $(o.parentNode).find('.api-ic.ic-on').removeClass('ic-on');
+
+ // sorry, not all scopes are satisfied
+ $(o).find('.api-ic').addClass('ic-warning');
+ $(o).find('.api-ic').removeClass('ic-error');
+ }
+ else {
+ o = v.parentNode.parentNode;
+ $(o.parentNode).find('.api-ic.ic-off').addClass('ic-on');
+ $(o.parentNode).find('.api-ic.ic-off').removeClass('ic-off');
+
+ // all scopes are satisfied
+ $(o).find('.api-ic').addClass('ic-info');
+ $(o).find('.api-ic').removeClass('ic-warning');
+ $(o).find('.api-ic').removeClass('ic-error');
+ }
+ }
+ });
+ window.swaggerUi.api.clientAuthorizations.add(window.OAuthSchemeKey, new SwaggerClient.ApiKeyAuthorization('Authorization', 'Bearer ' + b, 'header'));
+ window.swaggerUi.load();
+ }
+ }
+ }
+};
diff --git a/ydb/core/viewer/content/api/swagger-ui.min.js b/ydb/core/viewer/content/api/swagger-ui.min.js
index 1f490b1fea1..7123f95d626 100644
--- a/ydb/core/viewer/content/api/swagger-ui.min.js
+++ b/ydb/core/viewer/content/api/swagger-ui.min.js
@@ -1,14 +1,14 @@
-(function(){function e(){e.history=e.history||[],e.history.push(arguments),this.console&&console.log(Array.prototype.slice.call(arguments)[0])}!function(){var e=Handlebars.template,t=Handlebars.templates=Handlebars.templates||{};t.apikey_auth=e({1:function(e,t,n,r,i){var a;return' <span class="key_auth__value">'+(null!=(a=(n.sanitize||t&&t.sanitize||n.helperMissing).call(null!=t?t:{},null!=t?t.value:t,{name:"sanitize",hash:{},data:i}))?a:"")+"</span>\n"},3:function(e,t,n,r,i){return' <input placeholder="api_key" class="auth_input input_apiKey_entry" name="apiKey" type="text"/>\n'},compiler:[7,">= 4.0.0"],main:function(e,t,n,r,i){var a,o=null!=t?t:{},s=n.helperMissing;return'<div class="key_input_container">\n <h3 class="auth__title">Api key authorization</h3>\n <div class="auth__description">'+(null!=(a=(n.sanitize||t&&t.sanitize||s).call(o,null!=t?t.description:t,{name:"sanitize",hash:{},data:i}))?a:"")+'</div>\n <div>\n <div class="key_auth__field">\n <span class="key_auth__label">name:</span>\n <span class="key_auth__value">'+(null!=(a=(n.escape||t&&t.escape||s).call(o,null!=t?t.name:t,{name:"escape",hash:{},data:i}))?a:"")+'</span>\n </div>\n <div class="key_auth__field">\n <span class="key_auth__label">in:</span>\n <span class="key_auth__value">'+(null!=(a=(n.escape||t&&t.escape||s).call(o,null!=t?t["in"]:t,{name:"escape",hash:{},data:i}))?a:"")+'</span>\n </div>\n <div class="key_auth__field">\n <span class="key_auth__label">value:</span>\n'+(null!=(a=n["if"].call(o,null!=t?t.isLogout:t,{name:"if",hash:{},fn:e.program(1,i,0),inverse:e.program(3,i,0),data:i}))?a:"")+" </div>\n </div>\n</div>\n"},useData:!0}),t.auth_button=e({compiler:[7,">= 4.0.0"],main:function(e,t,n,r,i){return"<a class='authorize__btn' href=\"#\">Authorize</a>\n"},useData:!0}),t.auth_button_operation=e({1:function(e,t,n,r,i){return" authorize__btn_operation_login\n"},3:function(e,t,n,r,i){return" authorize__btn_operation_logout\n"},5:function(e,t,n,r,i){var a;return' <ul class="authorize-scopes">\n'+(null!=(a=n.each.call(null!=t?t:{},null!=t?t.scopes:t,{name:"each",hash:{},fn:e.program(6,i,0),inverse:e.noop,data:i}))?a:"")+" </ul>\n"},6:function(e,t,n,r,i){var a,o=null!=t?t:{},s=n.helperMissing;return' <li class="authorize__scope" title="'+(null!=(a=(n.escape||t&&t.escape||s).call(o,null!=t?t.description:t,{name:"escape",hash:{},data:i}))?a:"")+'">'+(null!=(a=(n.escape||t&&t.escape||s).call(o,null!=t?t.scope:t,{name:"escape",hash:{},data:i}))?a:"")+"</li>\n"},compiler:[7,">= 4.0.0"],main:function(e,t,n,r,i){var a,o=null!=t?t:{};return'<div class="authorize__btn authorize__btn_operation\n'+(null!=(a=n["if"].call(o,null!=t?t.isLogout:t,{name:"if",hash:{},fn:e.program(1,i,0),inverse:e.program(3,i,0),data:i}))?a:"")+'">\n'+(null!=(a=n["if"].call(o,null!=t?t.scopes:t,{name:"if",hash:{},fn:e.program(5,i,0),inverse:e.noop,data:i}))?a:"")+"</div>\n"},useData:!0}),t.auth_view=e({1:function(e,t,n,r,i){return' <button type="button" class="auth__button auth_submit__button" data-sw-translate>Authorize</button>\n'},3:function(e,t,n,r,i){return' <button type="button" class="auth__button auth_logout__button" data-sw-translate>Logout</button>\n'},compiler:[7,">= 4.0.0"],main:function(e,t,n,r,i){var a,o=null!=t?t:{};return'<div class="auth_container">\n\n <div class="auth_inner"></div>\n <div class="auth_submit">\n'+(null!=(a=n.unless.call(o,null!=t?t.isLogout:t,{name:"unless",hash:{},fn:e.program(1,i,0),inverse:e.noop,data:i}))?a:"")+(null!=(a=n["if"].call(o,null!=t?t.isAuthorized:t,{name:"if",hash:{},fn:e.program(3,i,0),inverse:e.noop,data:i}))?a:"")+" </div>\n\n</div>\n"},useData:!0}),t.basic_auth=e({1:function(e,t,n,r,i){return" - authorized"},3:function(e,t,n,r,i){var a;return' <span class="basic_auth__value">'+(null!=(a=(n.escape||t&&t.escape||n.helperMissing).call(null!=t?t:{},null!=t?t.username:t,{name:"escape",hash:{},data:i}))?a:"")+"</span>\n"},5:function(e,t,n,r,i){return' <input required placeholder="username" class="basic_auth__username auth_input" name="username" type="text"/>\n'},7:function(e,t,n,r,i){return' <div class="auth_label">\n <span class="basic_auth__label" data-sw-translate>password:</span>\n <input required placeholder="password" class="basic_auth__password auth_input" name="password" type="password"/></label>\n </div>\n'},compiler:[7,">= 4.0.0"],main:function(e,t,n,r,i){var a,o=null!=t?t:{};return"<div class='basic_auth_container'>\n <h3 class=\"auth__title\">Basic authentication"+(null!=(a=n["if"].call(o,null!=t?t.isLogout:t,{name:"if",hash:{},fn:e.program(1,i,0),inverse:e.noop,data:i}))?a:"")+'</h3>\n <form class="basic_input_container">\n <div class="auth__description">'+(null!=(a=(n.sanitize||t&&t.sanitize||n.helperMissing).call(o,null!=t?t.description:t,{name:"sanitize",hash:{},data:i}))?a:"")+'</div>\n <div class="auth_label">\n <span class="basic_auth__label" data-sw-translate>username:</span>\n'+(null!=(a=n["if"].call(o,null!=t?t.isLogout:t,{name:"if",hash:{},fn:e.program(3,i,0),inverse:e.program(5,i,0),data:i}))?a:"")+" </div>\n"+(null!=(a=n.unless.call(o,null!=t?t.isLogout:t,{name:"unless",hash:{},fn:e.program(7,i,0),inverse:e.noop,data:i}))?a:"")+" </form>\n</div>\n"},useData:!0}),t.content_type=e({1:function(e,t,n,r,i){var a;return null!=(a=n.each.call(null!=t?t:{},null!=t?t.produces:t,{name:"each",hash:{},fn:e.program(2,i,0),inverse:e.noop,data:i}))?a:""},2:function(e,t,n,r,i){var a,o=null!=t?t:{},s=n.helperMissing;return'\t<option value="'+(null!=(a=(n.sanitize||t&&t.sanitize||s).call(o,t,{name:"sanitize",hash:{},data:i}))?a:"")+'">'+(null!=(a=(n.sanitize||t&&t.sanitize||s).call(o,t,{name:"sanitize",hash:{},data:i}))?a:"")+"</option>\n"},4:function(e,t,n,r,i){return' <option value="application/json">application/json</option>\n'},compiler:[7,">= 4.0.0"],main:function(e,t,n,r,i){var a,o=null!=t?t:{},s=n.helperMissing;return'<label data-sw-translate for="'+(null!=(a=(n.escape||t&&t.escape||s).call(o,null!=t?t.contentTypeId:t,{name:"escape",hash:{},data:i}))?a:"")+'">Response Content Type</label>\n<select name="contentType" id="'+(null!=(a=(n.escape||t&&t.escape||s).call(o,null!=t?t.contentTypeId:t,{name:"escape",hash:{},data:i}))?a:"")+'">\n'+(null!=(a=n["if"].call(o,null!=t?t.produces:t,{name:"if",hash:{},fn:e.program(1,i,0),inverse:e.program(4,i,0),data:i}))?a:"")+"</select>\n"},useData:!0}),t.main=e({1:function(e,t,n,r,i){var a,o=null!=t?t:{},s=n.helperMissing;return' <div class="info_title">'+(null!=(a=(n.sanitize||t&&t.sanitize||s).call(o,null!=(a=null!=t?t.info:t)?a.title:a,{name:"sanitize",hash:{},data:i}))?a:"")+'</div>\n <div class="info_description markdown">'+(null!=(a=(n.sanitize||t&&t.sanitize||s).call(o,null!=(a=null!=t?t.info:t)?a.description:a,{name:"sanitize",hash:{},data:i}))?a:"")+"</div>\n"+(null!=(a=n["if"].call(o,null!=t?t.externalDocs:t,{name:"if",hash:{},fn:e.program(2,i,0),inverse:e.noop,data:i}))?a:"")+" "+(null!=(a=n["if"].call(o,null!=(a=null!=t?t.info:t)?a.termsOfServiceUrl:a,{name:"if",hash:{},fn:e.program(4,i,0),inverse:e.noop,data:i}))?a:"")+"\n "+(null!=(a=n["if"].call(o,null!=(a=null!=(a=null!=t?t.info:t)?a.contact:a)?a.name:a,{name:"if",hash:{},fn:e.program(6,i,0),inverse:e.noop,data:i}))?a:"")+"\n "+(null!=(a=n["if"].call(o,null!=(a=null!=(a=null!=t?t.info:t)?a.contact:a)?a.url:a,{name:"if",hash:{},fn:e.program(8,i,0),inverse:e.noop,data:i}))?a:"")+"\n "+(null!=(a=n["if"].call(o,null!=(a=null!=(a=null!=t?t.info:t)?a.contact:a)?a.email:a,{name:"if",hash:{},fn:e.program(10,i,0),inverse:e.noop,data:i}))?a:"")+"\n "+(null!=(a=n["if"].call(o,null!=(a=null!=t?t.info:t)?a.license:a,{name:"if",hash:{},fn:e.program(12,i,0),inverse:e.noop,data:i}))?a:"")+"\n"},2:function(e,t,n,r,i){var a,o=null!=t?t:{},s=n.helperMissing;return" <p>"+(null!=(a=(n.sanitize||t&&t.sanitize||s).call(o,null!=(a=null!=t?t.externalDocs:t)?a.description:a,{name:"sanitize",hash:{},data:i}))?a:"")+'</p>\n <a href="'+(null!=(a=(n.escape||t&&t.escape||s).call(o,null!=(a=null!=t?t.externalDocs:t)?a.url:a,{name:"escape",hash:{},data:i}))?a:"")+'" target="_blank">'+(null!=(a=(n.escape||t&&t.escape||s).call(o,null!=(a=null!=t?t.externalDocs:t)?a.url:a,{name:"escape",hash:{},data:i}))?a:"")+"</a>\n"},4:function(e,t,n,r,i){var a;return'<div class="info_tos"><a target="_blank" href="'+(null!=(a=(n.escape||t&&t.escape||n.helperMissing).call(null!=t?t:{},null!=(a=null!=t?t.info:t)?a.termsOfServiceUrl:a,{name:"escape",hash:{},data:i}))?a:"")+'" data-sw-translate>Terms of service</a></div>'},6:function(e,t,n,r,i){var a;return"<div><div class='info_name' style=\"display: inline\" data-sw-translate>Created by </div> "+(null!=(a=(n.escape||t&&t.escape||n.helperMissing).call(null!=t?t:{},null!=(a=null!=(a=null!=t?t.info:t)?a.contact:a)?a.name:a,{name:"escape",hash:{},data:i}))?a:"")+"</div>"},8:function(e,t,n,r,i){var a,o=null!=t?t:{},s=n.helperMissing;return"<div class='info_url' data-sw-translate>See more at <a href=\""+(null!=(a=(n.escape||t&&t.escape||s).call(o,null!=(a=null!=(a=null!=t?t.info:t)?a.contact:a)?a.url:a,{name:"escape",hash:{},data:i}))?a:"")+'">'+(null!=(a=(n.escape||t&&t.escape||s).call(o,null!=(a=null!=(a=null!=t?t.info:t)?a.contact:a)?a.url:a,{name:"escape",hash:{},data:i}))?a:"")+"</a></div>"},10:function(e,t,n,r,i){var a,o=null!=t?t:{},s=n.helperMissing;return'<div class=\'info_email\'><a target="_parent" href="mailto:'+(null!=(a=(n.escape||t&&t.escape||s).call(o,null!=(a=null!=(a=null!=t?t.info:t)?a.contact:a)?a.email:a,{name:"escape",hash:{},data:i}))?a:"")+"?subject="+(null!=(a=(n.escape||t&&t.escape||s).call(o,null!=(a=null!=t?t.info:t)?a.title:a,{name:"escape",hash:{},data:i}))?a:"")+'" data-sw-translate>Contact the developer</a></div>'},12:function(e,t,n,r,i){var a,o=null!=t?t:{},s=n.helperMissing;return"<div class='info_license'><a target=\"_blank\" href='"+(null!=(a=(n.escape||t&&t.escape||s).call(o,null!=(a=null!=(a=null!=t?t.info:t)?a.license:a)?a.url:a,{name:"escape",hash:{},data:i}))?a:"")+"'>"+(null!=(a=(n.escape||t&&t.escape||s).call(o,null!=(a=null!=(a=null!=t?t.info:t)?a.license:a)?a.name:a,{name:"escape",hash:{},data:i}))?a:"")+"</a></div>"},14:function(e,t,n,r,i){var a;return' , <span style="font-variant: small-caps" data-sw-translate>api version</span>: '+(null!=(a=(n.escape||t&&t.escape||n.helperMissing).call(null!=t?t:{},null!=(a=null!=t?t.info:t)?a.version:a,{name:"escape",hash:{},data:i}))?a:"")+"\n "},16:function(e,t,n,r,i){var a,o=null!=t?t:{},s=n.helperMissing;return' <span style="float:right"><a target="_blank" href="'+(null!=(a=(n.escape||t&&t.escape||s).call(o,null!=t?t.validatorUrl:t,{name:"escape",hash:{},data:i}))?a:"")+"/debug?url="+(null!=(a=(n.escape||t&&t.escape||s).call(o,null!=t?t.url:t,{name:"escape",hash:{},data:i}))?a:"")+'"><img id="validator" src="'+(null!=(a=(n.escape||t&&t.escape||s).call(o,null!=t?t.validatorUrl:t,{name:"escape",hash:{},data:i}))?a:"")+"?url="+(null!=(a=(n.escape||t&&t.escape||s).call(o,null!=t?t.url:t,{name:"escape",hash:{},data:i}))?a:"")+'"></a>\n </span>\n'},compiler:[7,">= 4.0.0"],main:function(e,t,n,r,i){var a,o=null!=t?t:{};return"<div class='info' id='api_info'>\n"+(null!=(a=n["if"].call(o,null!=t?t.info:t,{name:"if",hash:{},fn:e.program(1,i,0),inverse:e.noop,data:i}))?a:"")+"</div>\n<div class='container' id='resources_container'>\n <div class='authorize-wrapper'></div>\n\n <ul id='resources'></ul>\n\n <div class=\"footer\">\n <h4 style=\"color: #999\">[ <span style=\"font-variant: small-caps\">base url</span>: "+(null!=(a=(n.escape||t&&t.escape||n.helperMissing).call(o,null!=t?t.basePath:t,{name:"escape",hash:{},data:i}))?a:"")+"\n"+(null!=(a=n["if"].call(o,null!=(a=null!=t?t.info:t)?a.version:a,{name:"if",hash:{},fn:e.program(14,i,0),inverse:e.noop,data:i}))?a:"")+"]\n"+(null!=(a=n["if"].call(o,null!=t?t.validatorUrl:t,{name:"if",hash:{},fn:e.program(16,i,0),inverse:e.noop,data:i}))?a:"")+" </h4>\n </div>\n</div>\n"},useData:!0}),t.oauth2=e({1:function(e,t,n,r,i){var a,o=null!=t?t:{},s=n.helperMissing;return' <li>\n <input class="oauth-scope" type="checkbox" data-scope="'+(null!=(a=(n.escape||t&&t.escape||s).call(o,null!=t?t.scope:t,{name:"escape",hash:{},data:i}))?a:"")+'" oauthtype="'+(null!=(a=(n.escape||t&&t.escape||s).call(o,null!=t?t.OAuthSchemeKey:t,{name:"escape",hash:{},data:i}))?a:"")+'"/>\n <label>'+(null!=(a=(n.escape||t&&t.escape||s).call(o,null!=t?t.scope:t,{name:"escape",hash:{},data:i}))?a:"")+'</label><br/>\n <span class="api-scope-desc">'+(null!=(a=(n.escape||t&&t.escape||s).call(o,null!=t?t.description:t,{name:"escape",hash:{},data:i}))?a:"")+"\n"+(null!=(a=n["if"].call(o,null!=t?t.OAuthSchemeKey:t,{name:"if",hash:{},fn:e.program(2,i,0),inverse:e.noop,data:i}))?a:"")+" </span>\n </li>\n"},2:function(e,t,n,r,i){var a;return" ("+(null!=(a=(n.escape||t&&t.escape||n.helperMissing).call(null!=t?t:{},null!=t?t.OAuthSchemeKey:t,{name:"escape",hash:{},data:i}))?a:"")+")\n"},compiler:[7,">= 4.0.0"],main:function(e,t,n,r,i){var a,o=null!=t?t:{},s=n.helperMissing;return'<div>\n <h3 class="auth__title">Select OAuth2.0 Scopes</h3>\n <p>'+(null!=(a=(n.sanitize||t&&t.sanitize||s).call(o,null!=t?t.description:t,{name:"sanitize",hash:{},data:i}))?a:"")+'</p>\n <p>Scopes are used to grant an application different levels of access to data on behalf of the end user. Each API may declare one or more scopes.\n <a href="#">Learn how to use</a>\n </p>\n <p><strong> '+(null!=(a=(n.escape||t&&t.escape||s).call(o,null!=t?t.appName:t,{name:"escape",hash:{},data:i}))?a:"")+" </strong> API requires the following scopes. Select which ones you want to grant to Swagger UI.</p>\n <p>Authorization URL: "+(null!=(a=(n.sanitize||t&&t.sanitize||s).call(o,null!=t?t.authorizationUrl:t,{name:"sanitize",hash:{},data:i}))?a:"")+"</p>\n <p>flow: "+(null!=(a=(n.escape||t&&t.escape||s).call(o,null!=t?t.flow:t,{name:"escape",hash:{},data:i}))?a:"")+'</p>\n <ul class="api-popup-scopes">\n'+(null!=(a=n.each.call(o,null!=t?t.scopes:t,{name:"each",hash:{},fn:e.program(1,i,0),inverse:e.noop,data:i}))?a:"")+" </ul>\n</div>"},useData:!0}),t.operation=e({1:function(e,t,n,r,i){return"deprecated"},3:function(e,t,n,r,i){return" <h4><span data-sw-translate>Warning: Deprecated</span></h4>\n"},5:function(e,t,n,r,i){var a;return' <h4><span data-sw-translate>Implementation Notes</span></h4>\n <div class="markdown">'+(null!=(a=(n.sanitize||t&&t.sanitize||n.helperMissing).call(null!=t?t:{},null!=t?t.description:t,{name:"sanitize",hash:{},data:i}))?a:"")+"</div>\n"},7:function(e,t,n,r,i){return" <div class='authorize-wrapper authorize-wrapper_operation'></div>\n"},9:function(e,t,n,r,i){var a,o=null!=t?t:{};return' <div class="response-class">\n <h4><span data-sw-translate>Response Class</span> (<span data-sw-translate>Status</span> '+(null!=(a=(n.escape||t&&t.escape||n.helperMissing).call(o,null!=t?t.successCode:t,{name:"escape",hash:{},data:i}))?a:"")+")</h4>\n "+(null!=(a=n["if"].call(o,null!=t?t.successDescription:t,{name:"if",hash:{},fn:e.program(10,i,0),inverse:e.noop,data:i}))?a:"")+'\n <p><span class="model-signature" /></p>\n <br/>\n <div class="response-content-type" />\n </div>\n'},10:function(e,t,n,r,i){var a;return'<div class="markdown">'+(null!=(a=(n.sanitize||t&&t.sanitize||n.helperMissing).call(null!=t?t:{},null!=t?t.successDescription:t,{name:"sanitize",hash:{},data:i}))?a:"")+"</div>"},12:function(e,t,n,r,i){var a;return' <h4 data-sw-translate>Headers</h4>\n <table class="headers">\n <thead>\n <tr>\n <th style="width: 100px; max-width: 100px" data-sw-translate>Header</th>\n <th style="width: 310px; max-width: 310px" data-sw-translate>Description</th>\n <th style="width: 200px; max-width: 200px" data-sw-translate>Type</th>\n <th style="width: 320px; max-width: 320px" data-sw-translate>Other</th>\n </tr>\n </thead>\n <tbody>\n'+(null!=(a=n.each.call(null!=t?t:{},null!=t?t.headers:t,{name:"each",hash:{},fn:e.program(13,i,0),inverse:e.noop,data:i}))?a:"")+" </tbody>\n </table>\n"},13:function(e,t,n,r,i){var a,o,s=null!=t?t:{},l=n.helperMissing;return" <tr>\n <td>"+e.escapeExpression((o=null!=(o=n.key||i&&i.key)?o:l,"function"==typeof o?o.call(s,{name:"key",hash:{},data:i}):o))+"</td>\n <td>"+(null!=(a=(n.sanitize||t&&t.sanitize||l).call(s,null!=t?t.description:t,{name:"sanitize",hash:{},data:i}))?a:"")+"</td>\n <td>"+(null!=(a=(n.escape||t&&t.escape||l).call(s,null!=t?t.type:t,{name:"escape",hash:{},data:i}))?a:"")+"</td>\n <td>"+(null!=(a=(n.escape||t&&t.escape||l).call(s,null!=t?t.other:t,{name:"escape",hash:{},data:i}))?a:"")+"</td>\n </tr>\n"},15:function(e,t,n,r,i){return' <h4 data-sw-translate>Parameters</h4>\n <table class=\'fullwidth parameters\'>\n <thead>\n <tr>\n <th style="width: 100px; max-width: 100px" data-sw-translate>Parameter</th>\n <th style="width: 310px; max-width: 310px" data-sw-translate>Value</th>\n <th style="width: 200px; max-width: 200px" data-sw-translate>Description</th>\n <th style="width: 100px; max-width: 100px" data-sw-translate>Parameter Type</th>\n <th style="width: 220px; max-width: 230px" data-sw-translate>Data Type</th>\n </tr>\n </thead>\n <tbody class="operation-params">\n\n </tbody>\n </table>\n'},17:function(e,t,n,r,i){return" <div style='margin:0;padding:0;display:inline'></div>\n <h4 data-sw-translate>Response Messages</h4>\n <table class='fullwidth response-messages'>\n <thead>\n <tr>\n <th data-sw-translate>HTTP Status Code</th>\n <th data-sw-translate>Reason</th>\n <th data-sw-translate>Response Model</th>\n <th data-sw-translate>Headers</th>\n </tr>\n </thead>\n <tbody class=\"operation-status\">\n </tbody>\n </table>\n"},19:function(e,t,n,r,i){return""},21:function(e,t,n,r,i){return" <div class='sandbox_header'>\n <input class='submit' type='submit' value='Try it out!' data-sw-translate/>\n <a href='#' class='response_hider' style='display:none' data-sw-translate>Hide Response</a>\n <span class='response_throbber' style='display:none'></span>\n </div>\n"},23:function(e,t,n,r,i){return" <h4 data-sw-translate>Request Headers</h4>\n <div class='block request_headers'></div>\n"},compiler:[7,">= 4.0.0"],main:function(e,t,n,r,i){var a,o=null!=t?t:{},s=n.helperMissing,l=e.escapeExpression;return" <ul class='operations' >\n <li class='"+(null!=(a=(n.escape||t&&t.escape||s).call(o,null!=t?t.method:t,{name:"escape",hash:{},data:i}))?a:"")+" operation' id='"+(null!=(a=(n.escape||t&&t.escape||s).call(o,null!=t?t.parentId:t,{name:"escape",hash:{},data:i}))?a:"")+"_"+(null!=(a=(n.escape||t&&t.escape||s).call(o,null!=t?t.nickname:t,{name:"escape",hash:{},data:i}))?a:"")+"'>\n <div class='heading'>\n <h3>\n <span class='http_method'>\n <a href='#!/"+l((n.sanitize||t&&t.sanitize||s).call(o,null!=t?t.encodedParentId:t,{name:"sanitize",hash:{},data:i}))+"/"+l((n.sanitize||t&&t.sanitize||s).call(o,null!=t?t.nickname:t,{name:"sanitize",hash:{},data:i}))+'\' class="toggleOperation">'+(null!=(a=(n.escape||t&&t.escape||s).call(o,null!=t?t.method:t,{name:"escape",hash:{},data:i}))?a:"")+"</a>\n </span>\n <span class='path'>\n <a href='#!/"+l((n.sanitize||t&&t.sanitize||s).call(o,null!=t?t.encodedParentId:t,{name:"sanitize",hash:{},data:i}))+"/"+l((n.sanitize||t&&t.sanitize||s).call(o,null!=t?t.nickname:t,{name:"sanitize",hash:{},data:i}))+"' class=\"toggleOperation "+(null!=(a=n["if"].call(o,null!=t?t.deprecated:t,{name:"if",hash:{},fn:e.program(1,i,0),inverse:e.noop,data:i}))?a:"")+'">'+(null!=(a=(n.escape||t&&t.escape||s).call(o,null!=t?t.path:t,{name:"escape",hash:{},data:i}))?a:"")+"</a>\n </span>\n </h3>\n <ul class='options'>\n <li>\n <a href='#!/"+l((n.sanitize||t&&t.sanitize||s).call(o,null!=t?t.encodedParentId:t,{name:"sanitize",hash:{},data:i}))+"/"+l((n.sanitize||t&&t.sanitize||s).call(o,null!=t?t.nickname:t,{name:"sanitize",hash:{},data:i}))+'\' class="toggleOperation"><span class="markdown">'+(null!=(a=(n.escape||t&&t.escape||s).call(o,null!=t?t.summary:t,{name:"escape",hash:{},data:i}))?a:"")+"</span></a>\n </li>\n </ul>\n </div>\n <div class='content' id='"+l((n.sanitize||t&&t.sanitize||s).call(o,null!=t?t.encodedParentId:t,{name:"sanitize",hash:{},data:i}))+"_"+l((n.sanitize||t&&t.sanitize||s).call(o,null!=t?t.nickname:t,{name:"sanitize",hash:{},data:i}))+"_content' style='display:none'>\n"+(null!=(a=n["if"].call(o,null!=t?t.deprecated:t,{name:"if",hash:{},fn:e.program(3,i,0),inverse:e.noop,data:i}))?a:"")+(null!=(a=n["if"].call(o,null!=t?t.description:t,{name:"if",hash:{},fn:e.program(5,i,0),inverse:e.noop,data:i}))?a:"")+(null!=(a=n["if"].call(o,null!=t?t.security:t,{name:"if",hash:{},fn:e.program(7,i,0),inverse:e.noop,data:i}))?a:"")+(null!=(a=n["if"].call(o,null!=t?t.type:t,{name:"if",hash:{},fn:e.program(9,i,0),inverse:e.noop,data:i}))?a:"")+"\n"+(null!=(a=n["if"].call(o,null!=t?t.headers:t,{name:"if",hash:{},fn:e.program(12,i,0),inverse:e.noop,data:i}))?a:"")+"\n <form accept-charset='UTF-8' class='sandbox'>\n <div style='margin:0;padding:0;display:inline'></div>\n"+(null!=(a=n["if"].call(o,null!=t?t.parameters:t,{name:"if",hash:{},fn:e.program(15,i,0),inverse:e.noop,data:i}))?a:"")+(null!=(a=n["if"].call(o,null!=t?t.responseMessages:t,{name:"if",hash:{},fn:e.program(17,i,0),inverse:e.noop,data:i}))?a:"")+(null!=(a=n["if"].call(o,null!=t?t.isReadOnly:t,{name:"if",hash:{},fn:e.program(19,i,0),inverse:e.program(21,i,0),data:i}))?a:"")+" </form>\n <div class='response' style='display:none'>\n <h4 class='curl'>Curl</h4>\n <div class='block curl'></div>\n <h4 data-sw-translate>Request URL</h4>\n <div class='block request_url'></div>\n"+(null!=(a=n["if"].call(o,null!=t?t.showRequestHeaders:t,{name:"if",hash:{},fn:e.program(23,i,0),inverse:e.noop,data:i}))?a:"")+" <h4 data-sw-translate>Response Body</h4>\n <div class='block response_body'></div>\n <h4 data-sw-translate>Response Code</h4>\n <div class='block response_code'></div>\n <h4 data-sw-translate>Response Headers</h4>\n <div class='block response_headers'></div>\n </div>\n </div>\n </li>\n </ul>\n"},useData:!0}),t.param=e({1:function(e,t,n,r,i){var a;return null!=(a=n["if"].call(null!=t?t:{},null!=t?t.isFile:t,{name:"if",hash:{},fn:e.program(2,i,0),inverse:e.program(4,i,0),data:i}))?a:""},2:function(e,t,n,r,i){var a,o=null!=t?t:{},s=n.helperMissing;return'\t\t\t<input type="file" name=\''+(null!=(a=(n.escape||t&&t.escape||s).call(o,null!=t?t.name:t,{name:"escape",hash:{},data:i}))?a:"")+"' id='"+(null!=(a=(n.escape||t&&t.escape||s).call(o,null!=t?t.valueId:t,{name:"escape",hash:{},data:i}))?a:"")+'\'/>\n\t\t\t<div class="parameter-content-type" />\n'},4:function(e,t,n,r,i){var a;return null!=(a=n["if"].call(null!=t?t:{},null!=t?t["default"]:t,{name:"if",hash:{},fn:e.program(5,i,0),inverse:e.program(7,i,0),data:i}))?a:""},5:function(e,t,n,r,i){var a,o=null!=t?t:{},s=n.helperMissing;return"\t\t\t\t<div class=\"editor_holder\"></div>\n\t\t\t\t<textarea class='body-textarea' name='"+(null!=(a=(n.escape||t&&t.escape||s).call(o,null!=t?t.name:t,{name:"escape",hash:{},data:i}))?a:"")+"' id='"+(null!=(a=(n.escape||t&&t.escape||s).call(o,null!=t?t.valueId:t,{name:"escape",hash:{},data:i}))?a:"")+"'>"+(null!=(a=(n.escape||t&&t.escape||s).call(o,null!=t?t["default"]:t,{name:"escape",hash:{},data:i}))?a:"")+'</textarea>\n <br />\n <div class="parameter-content-type" />\n'},7:function(e,t,n,r,i){var a,o=null!=t?t:{},s=n.helperMissing;return"\t\t\t\t<textarea class='body-textarea' name='"+(null!=(a=(n.escape||t&&t.escape||s).call(o,null!=t?t.name:t,{name:"escape",hash:{},data:i}))?a:"")+"' id='"+(null!=(a=(n.escape||t&&t.escape||s).call(o,null!=t?t.valueId:t,{name:"escape",hash:{},data:i}))?a:"")+'\'></textarea>\n\t\t\t\t<div class="editor_holder"></div>\n\t\t\t\t<br />\n\t\t\t\t<div class="parameter-content-type" />\n'},9:function(e,t,n,r,i){var a;return null!=(a=n["if"].call(null!=t?t:{},null!=t?t.isFile:t,{name:"if",hash:{},fn:e.program(2,i,0),inverse:e.program(10,i,0),data:i}))?a:""},10:function(e,t,n,r,i){var a;return null!=(a=(n.renderTextParam||t&&t.renderTextParam||n.helperMissing).call(null!=t?t:{},t,{name:"renderTextParam",hash:{},fn:e.program(11,i,0),inverse:e.noop,data:i}))?a:""},11:function(e,t,n,r,i){return""},compiler:[7,">= 4.0.0"],main:function(e,t,n,r,i){var a,o=null!=t?t:{},s=n.helperMissing;return"<td class='code'><label for='"+(null!=(a=(n.escape||t&&t.escape||s).call(o,null!=t?t.valueId:t,{name:"escape",hash:{},data:i}))?a:"")+"'>"+(null!=(a=(n.escape||t&&t.escape||s).call(o,null!=t?t.name:t,{name:"escape",hash:{},data:i}))?a:"")+"</label></td>\n<td>\n\n"+(null!=(a=n["if"].call(o,null!=t?t.isBody:t,{name:"if",hash:{},fn:e.program(1,i,0),inverse:e.program(9,i,0),data:i}))?a:"")+'\n</td>\n<td class="markdown">'+(null!=(a=(n.sanitize||t&&t.sanitize||s).call(o,null!=t?t.description:t,{name:"sanitize",hash:{},data:i}))?a:"")+"</td>\n<td>"+(null!=(a=(n.escape||t&&t.escape||s).call(o,null!=t?t.paramType:t,{name:"escape",hash:{},data:i}))?a:"")+'</td>\n<td>\n\t<span class="model-signature"></span>\n</td>\n'},useData:!0}),t.param_list=e({1:function(e,t,n,r,i){return" required"},3:function(e,t,n,r,i){return' multiple="multiple"'},5:function(e,t,n,r,i){return" required "},7:function(e,t,n,r,i){var a;return" <option "+(null!=(a=n.unless.call(null!=t?t:{},null!=t?t.hasDefault:t,{name:"unless",hash:{},fn:e.program(8,i,0),inverse:e.noop,data:i}))?a:"")+" value=''></option>\n"},8:function(e,t,n,r,i){return' selected="" '},10:function(e,t,n,r,i){var a,o=null!=t?t:{},s=n.helperMissing;return"\n <option "+(null!=(a=n["if"].call(o,null!=t?t.isDefault:t,{name:"if",hash:{},fn:e.program(11,i,0),inverse:e.noop,data:i}))?a:"")+" value='"+(null!=(a=(n.sanitize||t&&t.sanitize||s).call(o,null!=t?t.value:t,{name:"sanitize",hash:{},data:i}))?a:"")+"'> "+(null!=(a=(n.sanitize||t&&t.sanitize||s).call(o,null!=t?t.value:t,{name:"sanitize",hash:{},data:i}))?a:"")+" "+(null!=(a=n["if"].call(o,null!=t?t.isDefault:t,{name:"if",hash:{},fn:e.program(13,i,0),inverse:e.noop,data:i}))?a:"")+" </option>\n\n"},11:function(e,t,n,r,i){return' selected="" '},13:function(e,t,n,r,i){return" (default) "},15:function(e,t,n,r,i){return"<strong>"},17:function(e,t,n,r,i){return"</strong>"},compiler:[7,">= 4.0.0"],main:function(e,t,n,r,i){var a,o,s=null!=t?t:{},l=n.helperMissing;return"<td class='code"+(null!=(a=n["if"].call(s,null!=t?t.required:t,{name:"if",hash:{},fn:e.program(1,i,0),inverse:e.noop,data:i}))?a:"")+"'><label for='"+(null!=(a=(n.escape||t&&t.escape||l).call(s,null!=t?t.valueId:t,{name:"escape",hash:{},data:i}))?a:"")+"'>"+(null!=(a=(n.sanitize||t&&t.sanitize||l).call(s,null!=t?t.name:t,{name:"sanitize",hash:{},data:i}))?a:"")+"</label></td>\n<td>\n <select "+(null!=(a=(n.isArray||t&&t.isArray||l).call(s,t,{name:"isArray",hash:{},fn:e.program(3,i,0),inverse:e.noop,data:i}))?a:"")+' class="parameter '+(null!=(a=n["if"].call(s,null!=t?t.required:t,{name:"if",hash:{},fn:e.program(5,i,0),inverse:e.noop,data:i}))?a:"")+'" name="'+(null!=(a=(n.sanitize||t&&t.sanitize||l).call(s,null!=t?t.name:t,{name:"sanitize",hash:{},data:i}))?a:"")+'" id="'+(null!=(a=(n.escape||t&&t.escape||l).call(s,null!=t?t.valueId:t,{name:"escape",hash:{},data:i}))?a:"")+'">\n\n'+(null!=(a=n.unless.call(s,null!=t?t.required:t,{name:"unless",hash:{},fn:e.program(7,i,0),inverse:e.noop,data:i}))?a:"")+"\n"+(null!=(a=n.each.call(s,null!=(a=null!=t?t.allowableValues:t)?a.descriptiveValues:a,{name:"each",hash:{},fn:e.program(10,i,0),inverse:e.noop,data:i}))?a:"")+'\n </select>\n</td>\n<td class="markdown">'+(null!=(a=n["if"].call(s,null!=t?t.required:t,{name:"if",hash:{},fn:e.program(15,i,0),inverse:e.noop,data:i}))?a:"")+(null!=(o=null!=(o=n.description||(null!=t?t.description:t))?o:l,a="function"==typeof o?o.call(s,{name:"description",hash:{},data:i}):o)?a:"")+(null!=(a=n["if"].call(s,null!=t?t.required:t,{name:"if",hash:{},fn:e.program(17,i,0),inverse:e.noop,data:i}))?a:"")+"</td>\n<td>"+(null!=(a=(n.escape||t&&t.escape||l).call(s,null!=t?t.paramType:t,{name:"escape",hash:{},data:i}))?a:"")+'</td>\n<td><span class="model-signature"></span></td>\n'},useData:!0}),t.param_readonly=e({1:function(e,t,n,r,i){var a,o=null!=t?t:{},s=n.helperMissing;return" <textarea class='body-textarea' readonly='readonly' name='"+(null!=(a=(n.sanitize||t&&t.sanitize||s).call(o,null!=t?t.name:t,{name:"sanitize",hash:{},data:i}))?a:"")+"' id='"+(null!=(a=(n.escape||t&&t.escape||s).call(o,null!=t?t.valueId:t,{name:"escape",hash:{},data:i}))?a:"")+"'>"+(null!=(a=(n.sanitize||t&&t.sanitize||s).call(o,null!=t?t["default"]:t,{name:"sanitize",hash:{},data:i}))?a:"")+'</textarea>\n <div class="parameter-content-type" />\n'},3:function(e,t,n,r,i){var a;return null!=(a=n["if"].call(null!=t?t:{},null!=t?t["default"]:t,{name:"if",hash:{},fn:e.program(4,i,0),inverse:e.program(6,i,0),data:i}))?a:""},4:function(e,t,n,r,i){var a;return" "+(null!=(a=(n.sanitize||t&&t.sanitize||n.helperMissing).call(null!=t?t:{},null!=t?t["default"]:t,{name:"sanitize",hash:{},data:i}))?a:"")+"\n"},6:function(e,t,n,r,i){return" (empty)\n"},compiler:[7,">= 4.0.0"],main:function(e,t,n,r,i){var a,o=null!=t?t:{},s=n.helperMissing;return"<td class='code'><label for='"+(null!=(a=(n.escape||t&&t.escape||s).call(o,null!=t?t.valueId:t,{name:"escape",hash:{},data:i}))?a:"")+"'>"+(null!=(a=(n.sanitize||t&&t.sanitize||s).call(o,null!=t?t.name:t,{name:"sanitize",hash:{},data:i}))?a:"")+"</label></td>\n<td>\n"+(null!=(a=n["if"].call(o,null!=t?t.isBody:t,{name:"if",hash:{},fn:e.program(1,i,0),inverse:e.program(3,i,0),data:i}))?a:"")+'</td>\n<td class="markdown">'+(null!=(a=(n.sanitize||t&&t.sanitize||s).call(o,null!=t?t.description:t,{name:"sanitize",hash:{},data:i}))?a:"")+"</td>\n<td>"+(null!=(a=(n.escape||t&&t.escape||s).call(o,null!=t?t.paramType:t,{name:"escape",hash:{},data:i}))?a:"")+'</td>\n<td><span class="model-signature"></span></td>\n'},useData:!0}),t.param_readonly_required=e({1:function(e,t,n,r,i){var a,o=null!=t?t:{},s=n.helperMissing;return" <textarea class='body-textarea' readonly='readonly' placeholder='(required)' name='"+(null!=(a=(n.sanitize||t&&t.sanitize||s).call(o,null!=t?t.name:t,{name:"sanitize",hash:{},data:i}))?a:"")+"' id='"+(null!=(a=(n.escape||t&&t.escape||s).call(o,null!=t?t.valueId:t,{name:"escape",hash:{},data:i}))?a:"")+"'>"+(null!=(a=(n.sanitize||t&&t.sanitize||s).call(o,null!=t?t["default"]:t,{name:"sanitize",hash:{},data:i}))?a:"")+"</textarea>\n"},3:function(e,t,n,r,i){var a;return null!=(a=n["if"].call(null!=t?t:{},null!=t?t["default"]:t,{name:"if",hash:{},fn:e.program(4,i,0),inverse:e.program(6,i,0),data:i}))?a:""},4:function(e,t,n,r,i){var a;return" "+(null!=(a=(n.sanitize||t&&t.sanitize||n.helperMissing).call(null!=t?t:{},null!=t?t["default"]:t,{name:"sanitize",hash:{},data:i}))?a:"")+"\n"},6:function(e,t,n,r,i){
-return" (empty)\n"},compiler:[7,">= 4.0.0"],main:function(e,t,n,r,i){var a,o=null!=t?t:{},s=n.helperMissing;return"<td class='code required'><label for='"+(null!=(a=(n.escape||t&&t.escape||s).call(o,null!=t?t.valueId:t,{name:"escape",hash:{},data:i}))?a:"")+"'>"+(null!=(a=(n.sanitize||t&&t.sanitize||s).call(o,null!=t?t.name:t,{name:"sanitize",hash:{},data:i}))?a:"")+"</label></td>\n<td>\n"+(null!=(a=n["if"].call(o,null!=t?t.isBody:t,{name:"if",hash:{},fn:e.program(1,i,0),inverse:e.program(3,i,0),data:i}))?a:"")+'</td>\n<td class="markdown">'+(null!=(a=(n.sanitize||t&&t.sanitize||s).call(o,null!=t?t.description:t,{name:"sanitize",hash:{},data:i}))?a:"")+"</td>\n<td>"+(null!=(a=(n.escape||t&&t.escape||s).call(o,null!=t?t.paramType:t,{name:"escape",hash:{},data:i}))?a:"")+'</td>\n<td><span class="model-signature"></span></td>\n'},useData:!0}),t.param_required=e({1:function(e,t,n,r,i){var a;return null!=(a=n["if"].call(null!=t?t:{},null!=t?t.isFile:t,{name:"if",hash:{},fn:e.program(2,i,0),inverse:e.program(4,i,0),data:i}))?a:""},2:function(e,t,n,r,i){var a,o=null!=t?t:{},s=n.helperMissing;return'\t\t\t<input type="file" name=\''+(null!=(a=(n.escape||t&&t.escape||s).call(o,null!=t?t.name:t,{name:"escape",hash:{},data:i}))?a:"")+"' id='"+(null!=(a=(n.escape||t&&t.escape||s).call(o,null!=t?t.valueId:t,{name:"escape",hash:{},data:i}))?a:"")+"'/>\n"},4:function(e,t,n,r,i){var a;return null!=(a=n["if"].call(null!=t?t:{},null!=t?t["default"]:t,{name:"if",hash:{},fn:e.program(5,i,0),inverse:e.program(7,i,0),data:i}))?a:""},5:function(e,t,n,r,i){var a,o=null!=t?t:{},s=n.helperMissing;return"\t\t\t\t<div class=\"editor_holder\"></div>\n\t\t\t\t<textarea class='body-textarea required' placeholder='(required)' name='"+(null!=(a=(n.sanitize||t&&t.sanitize||s).call(o,null!=t?t.name:t,{name:"sanitize",hash:{},data:i}))?a:"")+"' id=\""+(null!=(a=(n.escape||t&&t.escape||s).call(o,null!=t?t.valueId:t,{name:"escape",hash:{},data:i}))?a:"")+'">'+(null!=(a=(n.sanitize||t&&t.sanitize||s).call(o,null!=t?t["default"]:t,{name:"sanitize",hash:{},data:i}))?a:"")+'</textarea>\n <br />\n <div class="parameter-content-type" />\n'},7:function(e,t,n,r,i){var a,o=null!=t?t:{},s=n.helperMissing;return"\t\t\t\t<textarea class='body-textarea required' placeholder='(required)' name='"+(null!=(a=(n.sanitize||t&&t.sanitize||s).call(o,null!=t?t.name:t,{name:"sanitize",hash:{},data:i}))?a:"")+"' id='"+(null!=(a=(n.escape||t&&t.escape||s).call(o,null!=t?t.valueId:t,{name:"escape",hash:{},data:i}))?a:"")+'\'></textarea>\n\t\t\t\t<div class="editor_holder"></div>\n\t\t\t\t<br />\n\t\t\t\t<div class="parameter-content-type" />\n'},9:function(e,t,n,r,i){var a;return null!=(a=n["if"].call(null!=t?t:{},null!=t?t.isFile:t,{name:"if",hash:{},fn:e.program(10,i,0),inverse:e.program(12,i,0),data:i}))?a:""},10:function(e,t,n,r,i){var a,o=null!=t?t:{},s=n.helperMissing;return"\t\t\t<input class='parameter' class='required' type='file' name='"+(null!=(a=(n.sanitize||t&&t.sanitize||s).call(o,null!=t?t.name:t,{name:"sanitize",hash:{},data:i}))?a:"")+"' id='"+(null!=(a=(n.escape||t&&t.escape||s).call(o,null!=t?t.valueId:t,{name:"escape",hash:{},data:i}))?a:"")+"'/>\n"},12:function(e,t,n,r,i){var a;return null!=(a=(n.renderTextParam||t&&t.renderTextParam||n.helperMissing).call(null!=t?t:{},t,{name:"renderTextParam",hash:{},fn:e.program(13,i,0),inverse:e.noop,data:i}))?a:""},13:function(e,t,n,r,i){return""},compiler:[7,">= 4.0.0"],main:function(e,t,n,r,i){var a,o=null!=t?t:{},s=n.helperMissing;return"<td class='code required'><label for='"+(null!=(a=(n.escape||t&&t.escape||s).call(o,null!=t?t.valueId:t,{name:"escape",hash:{},data:i}))?a:"")+"'>"+(null!=(a=(n.escape||t&&t.escape||s).call(o,null!=t?t.name:t,{name:"escape",hash:{},data:i}))?a:"")+"</label></td>\n<td>\n"+(null!=(a=n["if"].call(o,null!=t?t.isBody:t,{name:"if",hash:{},fn:e.program(1,i,0),inverse:e.program(9,i,0),data:i}))?a:"")+'</td>\n<td>\n\t<strong><span class="markdown">'+(null!=(a=(n.sanitize||t&&t.sanitize||s).call(o,null!=t?t.description:t,{name:"sanitize",hash:{},data:i}))?a:"")+"</span></strong>\n</td>\n<td>"+(null!=(a=(n.escape||t&&t.escape||s).call(o,null!=t?t.paramType:t,{name:"escape",hash:{},data:i}))?a:"")+'</td>\n<td><span class="model-signature"></span></td>\n'},useData:!0}),t.parameter_content_type=e({1:function(e,t,n,r,i){var a;return null!=(a=n.each.call(null!=t?t:{},null!=t?t.consumes:t,{name:"each",hash:{},fn:e.program(2,i,0),inverse:e.noop,data:i}))?a:""},2:function(e,t,n,r,i){var a,o=null!=t?t:{},s=n.helperMissing;return' <option value="'+(null!=(a=(n.sanitize||t&&t.sanitize||s).call(o,t,{name:"sanitize",hash:{},data:i}))?a:"")+'">'+(null!=(a=(n.sanitize||t&&t.sanitize||s).call(o,t,{name:"sanitize",hash:{},data:i}))?a:"")+"</option>\n"},4:function(e,t,n,r,i){return' <option value="application/json">application/json</option>\n'},compiler:[7,">= 4.0.0"],main:function(e,t,n,r,i){var a,o,s=null!=t?t:{},l=n.helperMissing;return'<label for="'+e.escapeExpression((o=null!=(o=n.parameterContentTypeId||(null!=t?t.parameterContentTypeId:t))?o:l,"function"==typeof o?o.call(s,{name:"parameterContentTypeId",hash:{},data:i}):o))+'" data-sw-translate>Parameter content type:</label>\n<select name="parameterContentType" id="'+(null!=(a=(n.sanitize||t&&t.sanitize||l).call(s,null!=t?t.parameterContentTypeId:t,{name:"sanitize",hash:{},data:i}))?a:"")+'">\n'+(null!=(a=n["if"].call(s,null!=t?t.consumes:t,{name:"if",hash:{},fn:e.program(1,i,0),inverse:e.program(4,i,0),data:i}))?a:"")+"</select>\n"},useData:!0}),t.popup=e({compiler:[7,">= 4.0.0"],main:function(e,t,n,r,i){var a;return'<div class="api-popup-dialog-wrapper">\n <div class="api-popup-title">'+e.escapeExpression((a=null!=(a=n.title||(null!=t?t.title:t))?a:n.helperMissing,"function"==typeof a?a.call(null!=t?t:{},{name:"title",hash:{},data:i}):a))+'</div>\n <div class="api-popup-content"></div>\n <p class="error-msg"></p>\n <div class="api-popup-actions">\n <button class="api-popup-cancel api-button gray" type="button">Cancel</button>\n </div>\n</div>\n<div class="api-popup-dialog-shadow"></div>'},useData:!0}),t.resource=e({1:function(e,t,n,r,i){return" : "},3:function(e,t,n,r,i){var a;return" <li>\n <a href='"+(null!=(a=(n.sanitize||t&&t.sanitize||n.helperMissing).call(null!=t?t:{},null!=t?t.url:t,{name:"sanitize",hash:{},data:i}))?a:"")+"' data-sw-translate>Raw</a>\n </li>\n"},compiler:[7,">= 4.0.0"],main:function(e,t,n,r,i){var a,o,s,l=null!=t?t:{},u=n.helperMissing,c="<div class='heading'>\n <h2>\n <a href='#!/"+(null!=(a=(n.sanitize||t&&t.sanitize||u).call(l,null!=t?t.id:t,{name:"sanitize",hash:{},data:i}))?a:"")+'\' class="toggleEndpointList" data-id="'+(null!=(a=(n.sanitize||t&&t.sanitize||u).call(l,null!=t?t.id:t,{name:"sanitize",hash:{},data:i}))?a:"")+'">'+(null!=(a=(n.sanitize||t&&t.sanitize||u).call(l,null!=t?t.name:t,{name:"sanitize",hash:{},data:i}))?a:"")+"</a> ";return o=null!=(o=n.summary||(null!=t?t.summary:t))?o:u,s={name:"summary",hash:{},fn:e.program(1,i,0),inverse:e.noop,data:i},a="function"==typeof o?o.call(l,s):o,n.summary||(a=n.blockHelperMissing.call(t,a,s)),null!=a&&(c+=a),c+(null!=(a=(n.sanitize||t&&t.sanitize||u).call(l,null!=t?t.summary:t,{name:"sanitize",hash:{},data:i}))?a:"")+"\n </h2>\n <ul class='options'>\n <li>\n <a href='#!/"+(null!=(a=(n.sanitize||t&&t.sanitize||u).call(l,null!=t?t.id:t,{name:"sanitize",hash:{},data:i}))?a:"")+"' id='endpointListTogger_"+(null!=(a=(n.sanitize||t&&t.sanitize||u).call(l,null!=t?t.id:t,{name:"sanitize",hash:{},data:i}))?a:"")+'\' class="toggleEndpointList" data-id="'+(null!=(a=(n.sanitize||t&&t.sanitize||u).call(l,null!=t?t.id:t,{name:"sanitize",hash:{},data:i}))?a:"")+'" data-sw-translate>Show/Hide</a>\n </li>\n <li>\n <a href=\'#\' class="collapseResource" data-id="'+(null!=(a=(n.sanitize||t&&t.sanitize||u).call(l,null!=t?t.id:t,{name:"sanitize",hash:{},data:i}))?a:"")+'" data-sw-translate>\n List Operations\n </a>\n </li>\n <li>\n <a href=\'#\' class="expandResource" data-id="'+(null!=(a=(n.sanitize||t&&t.sanitize||u).call(l,null!=t?t.id:t,{name:"sanitize",hash:{},data:i}))?a:"")+'" data-sw-translate>\n Expand Operations\n </a>\n </li>\n'+(null!=(a=n["if"].call(l,null!=t?t.url:t,{name:"if",hash:{},fn:e.program(3,i,0),inverse:e.noop,data:i}))?a:"")+" </ul>\n</div>\n<ul class='endpoints' id='"+(null!=(a=(n.sanitize||t&&t.sanitize||u).call(l,null!=t?t.id:t,{name:"sanitize",hash:{},data:i}))?a:"")+"_endpoint_list' style='display:none'>\n\n</ul>\n"},useData:!0}),t.response_content_type=e({1:function(e,t,n,r,i){var a;return null!=(a=n.each.call(null!=t?t:{},null!=t?t.produces:t,{name:"each",hash:{},fn:e.program(2,i,0),inverse:e.noop,data:i}))?a:""},2:function(e,t,n,r,i){var a,o=null!=t?t:{},s=n.helperMissing;return' <option value="'+(null!=(a=(n.sanitize||t&&t.sanitize||s).call(o,t,{name:"sanitize",hash:{},data:i}))?a:"")+'">'+(null!=(a=(n.sanitize||t&&t.sanitize||s).call(o,t,{name:"sanitize",hash:{},data:i}))?a:"")+"</option>\n"},4:function(e,t,n,r,i){return' <option value="application/json">application/json</option>\n'},compiler:[7,">= 4.0.0"],main:function(e,t,n,r,i){var a,o,s=null!=t?t:{},l=n.helperMissing,u="function",c=e.escapeExpression;return'<label data-sw-translate for="'+c((o=null!=(o=n.responseContentTypeId||(null!=t?t.responseContentTypeId:t))?o:l,typeof o===u?o.call(s,{name:"responseContentTypeId",hash:{},data:i}):o))+'">Response Content Type</label>\n<select name="responseContentType" id="'+c((o=null!=(o=n.responseContentTypeId||(null!=t?t.responseContentTypeId:t))?o:l,typeof o===u?o.call(s,{name:"responseContentTypeId",hash:{},data:i}):o))+'">\n'+(null!=(a=n["if"].call(s,null!=t?t.produces:t,{name:"if",hash:{},fn:e.program(1,i,0),inverse:e.program(4,i,0),data:i}))?a:"")+"</select>\n"},useData:!0}),t.signature=e({1:function(e,t,n,r,i){var a,o=null!=t?t:{};return'\n<div>\n<ul class="signature-nav">\n <li><a class="description-link" href="#" data-sw-translate>Model</a></li>\n <li><a class="snippet-link" href="#" data-sw-translate>Example Value</a></li>\n</ul>\n<div>\n\n<div class="signature-container">\n <div class="description">\n '+e.escapeExpression((n.sanitize||t&&t.sanitize||n.helperMissing).call(o,null!=t?t.signature:t,{name:"sanitize",hash:{},data:i}))+'\n </div>\n\n <div class="snippet">\n'+(null!=(a=n["if"].call(o,null!=t?t.sampleJSON:t,{name:"if",hash:{},fn:e.program(2,i,0),inverse:e.noop,data:i}))?a:"")+(null!=(a=n["if"].call(o,null!=t?t.sampleXML:t,{name:"if",hash:{},fn:e.program(5,i,0),inverse:e.noop,data:i}))?a:"")+" </div>\n</div>\n"},2:function(e,t,n,r,i){var a,o=null!=t?t:{};return' <div class="snippet_json">\n <pre><code>'+(null!=(a=(n.escape||t&&t.escape||n.helperMissing).call(o,null!=t?t.sampleJSON:t,{name:"escape",hash:{},data:i}))?a:"")+"</code></pre>\n "+(null!=(a=n["if"].call(o,null!=t?t.isParam:t,{name:"if",hash:{},fn:e.program(3,i,0),inverse:e.noop,data:i}))?a:"")+"\n </div>\n"},3:function(e,t,n,r,i){return'<small class="notice" data-sw-translate></small>'},5:function(e,t,n,r,i){var a,o=null!=t?t:{};return' <div class="snippet_xml">\n <pre><code>'+(null!=(a=(n.escape||t&&t.escape||n.helperMissing).call(o,null!=t?t.sampleXML:t,{name:"escape",hash:{},data:i}))?a:"")+"</code></pre>\n "+(null!=(a=n["if"].call(o,null!=t?t.isParam:t,{name:"if",hash:{},fn:e.program(3,i,0),inverse:e.noop,data:i}))?a:"")+"\n </div>\n"},7:function(e,t,n,r,i){var a;return" "+(null!=(a=(n.escape||t&&t.escape||n.helperMissing).call(null!=t?t:{},null!=t?t.signature:t,{name:"escape",hash:{},data:i}))?a:"")+"\n"},compiler:[7,">= 4.0.0"],main:function(e,t,n,r,i){var a;return null!=(a=(n.ifCond||t&&t.ifCond||n.helperMissing).call(null!=t?t:{},null!=t?t.sampleJSON:t,"||",null!=t?t.sampleXML:t,{name:"ifCond",hash:{},fn:e.program(1,i,0),inverse:e.program(7,i,0),data:i}))?a:""},useData:!0}),t.status_code=e({1:function(e,t,n,r,i){var a,o,s=null!=t?t:{},l=n.helperMissing;return" <tr>\n <td>"+e.escapeExpression((o=null!=(o=n.key||i&&i.key)?o:l,"function"==typeof o?o.call(s,{name:"key",hash:{},data:i}):o))+"</td>\n <td>"+(null!=(a=(n.sanitize||t&&t.sanitize||l).call(s,null!=t?t.description:t,{name:"sanitize",hash:{},data:i}))?a:"")+"</td>\n <td>"+(null!=(a=(n.escape||t&&t.escape||l).call(s,null!=t?t.type:t,{name:"escape",hash:{},data:i}))?a:"")+"</td>\n </tr>\n"},compiler:[7,">= 4.0.0"],main:function(e,t,n,r,i){var a,o=null!=t?t:{},s=n.helperMissing;return"<td width='15%' class='code'>"+(null!=(a=(n.escape||t&&t.escape||s).call(o,null!=t?t.code:t,{name:"escape",hash:{},data:i}))?a:"")+'</td>\n<td class="markdown">'+(null!=(a=(n.escape||t&&t.escape||s).call(o,null!=t?t.message:t,{name:"escape",hash:{},data:i}))?a:"")+'</td>\n<td width=\'50%\'><span class="model-signature" /></td>\n<td class="headers">\n <table>\n <tbody>\n'+(null!=(a=n.each.call(o,null!=t?t.headers:t,{name:"each",hash:{},fn:e.program(1,i,0),inverse:e.noop,data:i}))?a:"")+" </tbody>\n </table>\n</td>"},useData:!0})}(),$(function(){$.fn.vAlign=function(){return this.each(function(){var e=$(this).height(),t=$(this).parent().height(),n=(t-e)/2;$(this).css("margin-top",n)})},$.fn.stretchFormtasticInputWidthToParent=function(){return this.each(function(){var e=$(this).closest("form").innerWidth(),t=parseInt($(this).closest("form").css("padding-left"),10)+parseInt($(this).closest("form").css("padding-right"),10),n=parseInt($(this).css("padding-left"),10)+parseInt($(this).css("padding-right"),10);$(this).css("width",e-t-n)})},$("form.formtastic li.string input, form.formtastic textarea").stretchFormtasticInputWidthToParent(),$("ul.downplayed li div.content p").vAlign(),$("form.sandbox").submit(function(){var e=!0;return $(this).find("input.required").each(function(){$(this).removeClass("error"),""===$(this).val()&&($(this).addClass("error"),$(this).wiggle(),e=!1)}),e})}),Function.prototype.bind&&console&&"object"==typeof console.log&&["log","info","warn","error","assert","dir","clear","profile","profileEnd"].forEach(function(e){console[e]=this.bind(console[e],console)},Function.prototype.call),window.Docs={shebang:function(){var e=$.param.fragment().split("/");switch(e.shift(),e.length){case 1:if(e[0].length>0){var t="resource_"+e[0];Docs.expandEndpointListForResource(e[0]),$("#"+t).slideto({highlight:!1})}break;case 2:Docs.expandEndpointListForResource(e[0]),$("#"+t).slideto({highlight:!1});var n=e.join("_"),r=n+"_content";Docs.expandOperation($("#"+r)),$("#"+n).slideto({highlight:!1})}},toggleEndpointListForResource:function(e){var t=$("li#resource_"+Docs.escapeResourceName(e)+" ul.endpoints");t.is(":visible")?($.bbq.pushState("#/",2),Docs.collapseEndpointListForResource(e)):($.bbq.pushState("#/"+e,2),Docs.expandEndpointListForResource(e))},expandEndpointListForResource:function(e){var e=Docs.escapeResourceName(e);if(""==e)return void $(".resource ul.endpoints").slideDown();$("li#resource_"+e).addClass("active");var t=$("li#resource_"+e+" ul.endpoints");t.slideDown()},collapseEndpointListForResource:function(e){var e=Docs.escapeResourceName(e);if(""==e)return void $(".resource ul.endpoints").slideUp();$("li#resource_"+e).removeClass("active");var t=$("li#resource_"+e+" ul.endpoints");t.slideUp()},expandOperationsForResource:function(e){return Docs.expandEndpointListForResource(e),""==e?void $(".resource ul.endpoints li.operation div.content").slideDown():void $("li#resource_"+Docs.escapeResourceName(e)+" li.operation div.content").each(function(){Docs.expandOperation($(this))})},collapseOperationsForResource:function(e){return Docs.expandEndpointListForResource(e),""==e?void $(".resource ul.endpoints li.operation div.content").slideUp():void $("li#resource_"+Docs.escapeResourceName(e)+" li.operation div.content").each(function(){Docs.collapseOperation($(this))})},escapeResourceName:function(e){return e.replace(/[!"#$%&'()*+,.\/:;<=>?@\[\\\]\^`{|}~]/g,"\\$&")},expandOperation:function(e){e.slideDown()},collapseOperation:function(e){e.slideUp()}},function(e,t){"use strict";"function"==typeof define&&define.amd?define(t):"object"==typeof exports?module.exports=t():e.returnExports=t()}(this,function(){var e,t,n=Array,r=n.prototype,i=Object,a=i.prototype,o=Function,s=o.prototype,l=String,u=l.prototype,c=Number,p=c.prototype,h=r.slice,f=r.splice,d=r.push,m=r.unshift,g=r.concat,y=r.join,v=s.call,b=s.apply,w=Math.max,_=Math.min,x=a.toString,A="function"==typeof Symbol&&"symbol"==typeof Symbol.toStringTag,S=Function.prototype.toString,j=/^\s*class /,E=function(e){try{var t=S.call(e),n=t.replace(/\/\/.*\n/g,""),r=n.replace(/\/\*[.\s\S]*\*\//g,""),i=r.replace(/\n/gm," ").replace(/ {2}/g," ");return j.test(i)}catch(a){return!1}},O=function(e){try{return!E(e)&&(S.call(e),!0)}catch(t){return!1}},k="[object Function]",T="[object GeneratorFunction]",e=function(e){if(!e)return!1;if("function"!=typeof e&&"object"!=typeof e)return!1;if(A)return O(e);if(E(e))return!1;var t=x.call(e);return t===k||t===T},C=RegExp.prototype.exec,I=function(e){try{return C.call(e),!0}catch(t){return!1}},D="[object RegExp]";t=function(e){return"object"==typeof e&&(A?I(e):x.call(e)===D)};var L,M=String.prototype.valueOf,R=function(e){try{return M.call(e),!0}catch(t){return!1}},U="[object String]";L=function(e){return"string"==typeof e||"object"==typeof e&&(A?R(e):x.call(e)===U)};var P=i.defineProperty&&function(){try{var e={};i.defineProperty(e,"x",{enumerable:!1,value:e});for(var t in e)return!1;return e.x===e}catch(n){return!1}}(),q=function(e){var t;return t=P?function(e,t,n,r){!r&&t in e||i.defineProperty(e,t,{configurable:!0,enumerable:!1,writable:!0,value:n})}:function(e,t,n,r){!r&&t in e||(e[t]=n)},function(n,r,i){for(var a in r)e.call(r,a)&&t(n,a,r[a],i)}}(a.hasOwnProperty),B=function(e){var t=typeof e;return null===e||"object"!==t&&"function"!==t},N=c.isNaN||function(e){return e!==e},z={ToInteger:function(e){var t=+e;return N(t)?t=0:0!==t&&t!==1/0&&t!==-(1/0)&&(t=(t>0||-1)*Math.floor(Math.abs(t))),t},ToPrimitive:function(t){var n,r,i;if(B(t))return t;if(r=t.valueOf,e(r)&&(n=r.call(t),B(n)))return n;if(i=t.toString,e(i)&&(n=i.call(t),B(n)))return n;throw new TypeError},ToObject:function(e){if(null==e)throw new TypeError("can't convert "+e+" to object");return i(e)},ToUint32:function(e){return e>>>0}},$=function(){};q(s,{bind:function(t){var n=this;if(!e(n))throw new TypeError("Function.prototype.bind called on incompatible "+n);for(var r,a=h.call(arguments,1),s=function(){if(this instanceof r){var e=b.call(n,this,g.call(a,h.call(arguments)));return i(e)===e?e:this}return b.call(n,t,g.call(a,h.call(arguments)))},l=w(0,n.length-a.length),u=[],c=0;c<l;c++)d.call(u,"$"+c);return r=o("binder","return function ("+y.call(u,",")+"){ return binder.apply(this, arguments); }")(s),n.prototype&&($.prototype=n.prototype,r.prototype=new $,$.prototype=null),r}});var F=v.bind(a.hasOwnProperty),V=v.bind(a.toString),H=v.bind(h),Y=b.bind(h),J=v.bind(u.slice),W=v.bind(u.split),Q=v.bind(u.indexOf),G=v.bind(d),K=v.bind(a.propertyIsEnumerable),X=v.bind(r.sort),Z=n.isArray||function(e){return"[object Array]"===V(e)},ee=1!==[].unshift(0);q(r,{unshift:function(){return m.apply(this,arguments),this.length}},ee),q(n,{isArray:Z});var te=i("a"),ne="a"!==te[0]||!(0 in te),re=function(e){var t=!0,n=!0,r=!1;if(e)try{e.call("foo",function(e,n,r){"object"!=typeof r&&(t=!1)}),e.call([1],function(){"use strict";n="string"==typeof this},"x")}catch(i){r=!0}return!!e&&!r&&t&&n};q(r,{forEach:function(t){var n,r=z.ToObject(this),i=ne&&L(this)?W(this,""):r,a=-1,o=z.ToUint32(i.length);if(arguments.length>1&&(n=arguments[1]),!e(t))throw new TypeError("Array.prototype.forEach callback must be a function");for(;++a<o;)a in i&&("undefined"==typeof n?t(i[a],a,r):t.call(n,i[a],a,r))}},!re(r.forEach)),q(r,{map:function(t){var r,i=z.ToObject(this),a=ne&&L(this)?W(this,""):i,o=z.ToUint32(a.length),s=n(o);if(arguments.length>1&&(r=arguments[1]),!e(t))throw new TypeError("Array.prototype.map callback must be a function");for(var l=0;l<o;l++)l in a&&("undefined"==typeof r?s[l]=t(a[l],l,i):s[l]=t.call(r,a[l],l,i));return s}},!re(r.map)),q(r,{filter:function(t){var n,r,i=z.ToObject(this),a=ne&&L(this)?W(this,""):i,o=z.ToUint32(a.length),s=[];if(arguments.length>1&&(r=arguments[1]),!e(t))throw new TypeError("Array.prototype.filter callback must be a function");for(var l=0;l<o;l++)l in a&&(n=a[l],("undefined"==typeof r?t(n,l,i):t.call(r,n,l,i))&&G(s,n));return s}},!re(r.filter)),q(r,{every:function(t){var n,r=z.ToObject(this),i=ne&&L(this)?W(this,""):r,a=z.ToUint32(i.length);if(arguments.length>1&&(n=arguments[1]),!e(t))throw new TypeError("Array.prototype.every callback must be a function");for(var o=0;o<a;o++)if(o in i&&!("undefined"==typeof n?t(i[o],o,r):t.call(n,i[o],o,r)))return!1;return!0}},!re(r.every)),q(r,{some:function(t){var n,r=z.ToObject(this),i=ne&&L(this)?W(this,""):r,a=z.ToUint32(i.length);if(arguments.length>1&&(n=arguments[1]),!e(t))throw new TypeError("Array.prototype.some callback must be a function");for(var o=0;o<a;o++)if(o in i&&("undefined"==typeof n?t(i[o],o,r):t.call(n,i[o],o,r)))return!0;return!1}},!re(r.some));var ie=!1;r.reduce&&(ie="object"==typeof r.reduce.call("es5",function(e,t,n,r){return r})),q(r,{reduce:function(t){var n=z.ToObject(this),r=ne&&L(this)?W(this,""):n,i=z.ToUint32(r.length);if(!e(t))throw new TypeError("Array.prototype.reduce callback must be a function");if(0===i&&1===arguments.length)throw new TypeError("reduce of empty array with no initial value");var a,o=0;if(arguments.length>=2)a=arguments[1];else for(;;){if(o in r){a=r[o++];break}if(++o>=i)throw new TypeError("reduce of empty array with no initial value")}for(;o<i;o++)o in r&&(a=t(a,r[o],o,n));return a}},!ie);var ae=!1;r.reduceRight&&(ae="object"==typeof r.reduceRight.call("es5",function(e,t,n,r){return r})),q(r,{reduceRight:function(t){var n=z.ToObject(this),r=ne&&L(this)?W(this,""):n,i=z.ToUint32(r.length);if(!e(t))throw new TypeError("Array.prototype.reduceRight callback must be a function");if(0===i&&1===arguments.length)throw new TypeError("reduceRight of empty array with no initial value");var a,o=i-1;if(arguments.length>=2)a=arguments[1];else for(;;){if(o in r){a=r[o--];break}if(--o<0)throw new TypeError("reduceRight of empty array with no initial value")}if(o<0)return a;do o in r&&(a=t(a,r[o],o,n));while(o--);return a}},!ae);var oe=r.indexOf&&[0,1].indexOf(1,2)!==-1;q(r,{indexOf:function(e){var t=ne&&L(this)?W(this,""):z.ToObject(this),n=z.ToUint32(t.length);if(0===n)return-1;var r=0;for(arguments.length>1&&(r=z.ToInteger(arguments[1])),r=r>=0?r:w(0,n+r);r<n;r++)if(r in t&&t[r]===e)return r;return-1}},oe);var se=r.lastIndexOf&&[0,1].lastIndexOf(0,-3)!==-1;q(r,{lastIndexOf:function(e){var t=ne&&L(this)?W(this,""):z.ToObject(this),n=z.ToUint32(t.length);if(0===n)return-1;var r=n-1;for(arguments.length>1&&(r=_(r,z.ToInteger(arguments[1]))),r=r>=0?r:n-Math.abs(r);r>=0;r--)if(r in t&&e===t[r])return r;return-1}},se);var le=function(){var e=[1,2],t=e.splice();return 2===e.length&&Z(t)&&0===t.length}();q(r,{splice:function(e,t){return 0===arguments.length?[]:f.apply(this,arguments)}},!le);var ue=function(){var e={};return r.splice.call(e,0,0,1),1===e.length}();q(r,{splice:function(e,t){if(0===arguments.length)return[];var n=arguments;return this.length=w(z.ToInteger(this.length),0),arguments.length>0&&"number"!=typeof t&&(n=H(arguments),n.length<2?G(n,this.length-e):n[1]=z.ToInteger(t)),f.apply(this,n)}},!ue);var ce=function(){var e=new n(1e5);return e[8]="x",e.splice(1,1),7===e.indexOf("x")}(),pe=function(){var e=256,t=[];return t[e]="a",t.splice(e+1,0,"b"),"a"===t[e]}();q(r,{splice:function(e,t){for(var n,r=z.ToObject(this),i=[],a=z.ToUint32(r.length),o=z.ToInteger(e),s=o<0?w(a+o,0):_(o,a),u=_(w(z.ToInteger(t),0),a-s),c=0;c<u;)n=l(s+c),F(r,n)&&(i[c]=r[n]),c+=1;var p,h=H(arguments,2),f=h.length;if(f<u){c=s;for(var d=a-u;c<d;)n=l(c+u),p=l(c+f),F(r,n)?r[p]=r[n]:delete r[p],c+=1;c=a;for(var m=a-u+f;c>m;)delete r[c-1],c-=1}else if(f>u)for(c=a-u;c>s;)n=l(c+u-1),p=l(c+f-1),F(r,n)?r[p]=r[n]:delete r[p],c-=1;c=s;for(var g=0;g<h.length;++g)r[c]=h[g],c+=1;return r.length=a-u+f,i}},!ce||!pe);var he,fe=r.join;try{he="1,2,3"!==Array.prototype.join.call("123",",")}catch(de){he=!0}he&&q(r,{join:function(e){var t="undefined"==typeof e?",":e;return fe.call(L(this)?W(this,""):this,t)}},he);var me="1,2"!==[1,2].join(void 0);me&&q(r,{join:function(e){var t="undefined"==typeof e?",":e;return fe.call(this,t)}},me);var ge=function(e){for(var t=z.ToObject(this),n=z.ToUint32(t.length),r=0;r<arguments.length;)t[n+r]=arguments[r],r+=1;return t.length=n+r,n+r},ye=function(){var e={},t=Array.prototype.push.call(e,void 0);return 1!==t||1!==e.length||"undefined"!=typeof e[0]||!F(e,0)}();q(r,{push:function(e){return Z(this)?d.apply(this,arguments):ge.apply(this,arguments)}},ye);var ve=function(){var e=[],t=e.push(void 0);return 1!==t||1!==e.length||"undefined"!=typeof e[0]||!F(e,0)}();q(r,{push:ge},ve),q(r,{slice:function(e,t){var n=L(this)?W(this,""):this;return Y(n,arguments)}},ne);var be=function(){try{return[1,2].sort(null),[1,2].sort({}),!0}catch(e){}return!1}(),we=function(){try{return[1,2].sort(/a/),!1}catch(e){}return!0}(),_e=function(){try{return[1,2].sort(void 0),!0}catch(e){}return!1}();q(r,{sort:function(t){if("undefined"==typeof t)return X(this);if(!e(t))throw new TypeError("Array.prototype.sort callback must be a function");return X(this,t)}},be||!_e||!we);var xe=!K({toString:null},"toString"),Ae=K(function(){},"prototype"),Se=!F("x","0"),je=function(e){var t=e.constructor;return t&&t.prototype===e},Ee={$window:!0,$console:!0,$parent:!0,$self:!0,$frame:!0,$frames:!0,$frameElement:!0,$webkitIndexedDB:!0,$webkitStorageInfo:!0,$external:!0},Oe=function(){if("undefined"==typeof window)return!1;for(var e in window)try{!Ee["$"+e]&&F(window,e)&&null!==window[e]&&"object"==typeof window[e]&&je(window[e])}catch(t){return!0}return!1}(),ke=function(e){if("undefined"==typeof window||!Oe)return je(e);try{return je(e)}catch(t){return!1}},Te=["toString","toLocaleString","valueOf","hasOwnProperty","isPrototypeOf","propertyIsEnumerable","constructor"],Ce=Te.length,Ie=function(e){return"[object Arguments]"===V(e)},De=function(t){return null!==t&&"object"==typeof t&&"number"==typeof t.length&&t.length>=0&&!Z(t)&&e(t.callee)},Le=Ie(arguments)?Ie:De;q(i,{keys:function(t){var n=e(t),r=Le(t),i=null!==t&&"object"==typeof t,a=i&&L(t);if(!i&&!n&&!r)throw new TypeError("Object.keys called on a non-object");var o=[],s=Ae&&n;if(a&&Se||r)for(var u=0;u<t.length;++u)G(o,l(u));if(!r)for(var c in t)s&&"prototype"===c||!F(t,c)||G(o,l(c));if(xe)for(var p=ke(t),h=0;h<Ce;h++){var f=Te[h];p&&"constructor"===f||!F(t,f)||G(o,f)}return o}});var Me=i.keys&&function(){return 2===i.keys(arguments).length}(1,2),Re=i.keys&&function(){var e=i.keys(arguments);return 1!==arguments.length||1!==e.length||1!==e[0]}(1),Ue=i.keys;q(i,{keys:function(e){return Ue(Le(e)?H(e):e)}},!Me||Re);var Pe,qe,Be=0!==new Date((-0xc782b5b342b24)).getUTCMonth(),Ne=new Date((-0x55d318d56a724)),ze=new Date(14496624e5),$e="Mon, 01 Jan -45875 11:59:59 GMT"!==Ne.toUTCString(),Fe=Ne.getTimezoneOffset();Fe<-720?(Pe="Tue Jan 02 -45875"!==Ne.toDateString(),qe=!/^Thu Dec 10 2015 \d\d:\d\d:\d\d GMT[-\+]\d\d\d\d(?: |$)/.test(ze.toString())):(Pe="Mon Jan 01 -45875"!==Ne.toDateString(),qe=!/^Wed Dec 09 2015 \d\d:\d\d:\d\d GMT[-\+]\d\d\d\d(?: |$)/.test(ze.toString()));var Ve=v.bind(Date.prototype.getFullYear),He=v.bind(Date.prototype.getMonth),Ye=v.bind(Date.prototype.getDate),Je=v.bind(Date.prototype.getUTCFullYear),We=v.bind(Date.prototype.getUTCMonth),Qe=v.bind(Date.prototype.getUTCDate),Ge=v.bind(Date.prototype.getUTCDay),Ke=v.bind(Date.prototype.getUTCHours),Xe=v.bind(Date.prototype.getUTCMinutes),Ze=v.bind(Date.prototype.getUTCSeconds),et=v.bind(Date.prototype.getUTCMilliseconds),tt=["Sun","Mon","Tue","Wed","Thu","Fri","Sat"],nt=["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"],rt=function(e,t){return Ye(new Date(t,e,0))};q(Date.prototype,{getFullYear:function(){if(!(this&&this instanceof Date))throw new TypeError("this is not a Date object.");var e=Ve(this);return e<0&&He(this)>11?e+1:e},getMonth:function(){if(!(this&&this instanceof Date))throw new TypeError("this is not a Date object.");var e=Ve(this),t=He(this);return e<0&&t>11?0:t},getDate:function(){if(!(this&&this instanceof Date))throw new TypeError("this is not a Date object.");var e=Ve(this),t=He(this),n=Ye(this);if(e<0&&t>11){if(12===t)return n;var r=rt(0,e+1);return r-n+1}return n},getUTCFullYear:function(){if(!(this&&this instanceof Date))throw new TypeError("this is not a Date object.");var e=Je(this);return e<0&&We(this)>11?e+1:e},getUTCMonth:function(){if(!(this&&this instanceof Date))throw new TypeError("this is not a Date object.");var e=Je(this),t=We(this);return e<0&&t>11?0:t},getUTCDate:function(){if(!(this&&this instanceof Date))throw new TypeError("this is not a Date object.");var e=Je(this),t=We(this),n=Qe(this);if(e<0&&t>11){if(12===t)return n;var r=rt(0,e+1);return r-n+1}return n}},Be),q(Date.prototype,{toUTCString:function(){if(!(this&&this instanceof Date))throw new TypeError("this is not a Date object.");var e=Ge(this),t=Qe(this),n=We(this),r=Je(this),i=Ke(this),a=Xe(this),o=Ze(this);return tt[e]+", "+(t<10?"0"+t:t)+" "+nt[n]+" "+r+" "+(i<10?"0"+i:i)+":"+(a<10?"0"+a:a)+":"+(o<10?"0"+o:o)+" GMT"}},Be||$e),q(Date.prototype,{toDateString:function(){if(!(this&&this instanceof Date))throw new TypeError("this is not a Date object.");var e=this.getDay(),t=this.getDate(),n=this.getMonth(),r=this.getFullYear();return tt[e]+" "+nt[n]+" "+(t<10?"0"+t:t)+" "+r}},Be||Pe),(Be||qe)&&(Date.prototype.toString=function(){if(!(this&&this instanceof Date))throw new TypeError("this is not a Date object.");var e=this.getDay(),t=this.getDate(),n=this.getMonth(),r=this.getFullYear(),i=this.getHours(),a=this.getMinutes(),o=this.getSeconds(),s=this.getTimezoneOffset(),l=Math.floor(Math.abs(s)/60),u=Math.floor(Math.abs(s)%60);return tt[e]+" "+nt[n]+" "+(t<10?"0"+t:t)+" "+r+" "+(i<10?"0"+i:i)+":"+(a<10?"0"+a:a)+":"+(o<10?"0"+o:o)+" GMT"+(s>0?"-":"+")+(l<10?"0"+l:l)+(u<10?"0"+u:u)},P&&i.defineProperty(Date.prototype,"toString",{configurable:!0,enumerable:!1,writable:!0}));var it=-621987552e5,at="-000001",ot=Date.prototype.toISOString&&new Date(it).toISOString().indexOf(at)===-1,st=Date.prototype.toISOString&&"1969-12-31T23:59:59.999Z"!==new Date((-1)).toISOString(),lt=v.bind(Date.prototype.getTime);q(Date.prototype,{toISOString:function(){if(!isFinite(this)||!isFinite(lt(this)))throw new RangeError("Date.prototype.toISOString called on non-finite value.");var e=Je(this),t=We(this);e+=Math.floor(t/12),t=(t%12+12)%12;var n=[t+1,Qe(this),Ke(this),Xe(this),Ze(this)];e=(e<0?"-":e>9999?"+":"")+J("00000"+Math.abs(e),0<=e&&e<=9999?-4:-6);for(var r=0;r<n.length;++r)n[r]=J("00"+n[r],-2);return e+"-"+H(n,0,2).join("-")+"T"+H(n,2).join(":")+"."+J("000"+et(this),-3)+"Z"}},ot||st);var ut=function(){try{return Date.prototype.toJSON&&null===new Date(NaN).toJSON()&&new Date(it).toJSON().indexOf(at)!==-1&&Date.prototype.toJSON.call({toISOString:function(){return!0}})}catch(e){return!1}}();ut||(Date.prototype.toJSON=function(t){var n=i(this),r=z.ToPrimitive(n);if("number"==typeof r&&!isFinite(r))return null;var a=n.toISOString;if(!e(a))throw new TypeError("toISOString property is not callable");return a.call(n)});var ct=1e15===Date.parse("+033658-09-27T01:46:40.000Z"),pt=!isNaN(Date.parse("2012-04-04T24:00:00.500Z"))||!isNaN(Date.parse("2012-11-31T23:59:59.000Z"))||!isNaN(Date.parse("2012-12-31T23:59:60.000Z")),ht=isNaN(Date.parse("2000-01-01T00:00:00.000Z"));if(ht||pt||!ct){var ft=Math.pow(2,31)-1,dt=N(new Date(1970,0,1,0,0,0,ft+1).getTime());Date=function(e){var t=function(n,r,i,a,o,s,u){var c,p=arguments.length;if(this instanceof e){var h=s,f=u;if(dt&&p>=7&&u>ft){var d=Math.floor(u/ft)*ft,m=Math.floor(d/1e3);h+=m,f-=1e3*m}c=1===p&&l(n)===n?new e(t.parse(n)):p>=7?new e(n,r,i,a,o,h,f):p>=6?new e(n,r,i,a,o,h):p>=5?new e(n,r,i,a,o):p>=4?new e(n,r,i,a):p>=3?new e(n,r,i):p>=2?new e(n,r):p>=1?new e(n instanceof e?+n:n):new e;
-}else c=e.apply(this,arguments);return B(c)||q(c,{constructor:t},!0),c},n=new RegExp("^(\\d{4}|[+-]\\d{6})(?:-(\\d{2})(?:-(\\d{2})(?:T(\\d{2}):(\\d{2})(?::(\\d{2})(?:(\\.\\d{1,}))?)?(Z|(?:([-+])(\\d{2}):(\\d{2})))?)?)?)?$"),r=[0,31,59,90,120,151,181,212,243,273,304,334,365],i=function(e,t){var n=t>1?1:0;return r[t]+Math.floor((e-1969+n)/4)-Math.floor((e-1901+n)/100)+Math.floor((e-1601+n)/400)+365*(e-1970)},a=function(t){var n=0,r=t;if(dt&&r>ft){var i=Math.floor(r/ft)*ft,a=Math.floor(i/1e3);n+=a,r-=1e3*a}return c(new e(1970,0,1,0,0,n,r))};for(var o in e)F(e,o)&&(t[o]=e[o]);q(t,{now:e.now,UTC:e.UTC},!0),t.prototype=e.prototype,q(t.prototype,{constructor:t},!0);var s=function(t){var r=n.exec(t);if(r){var o,s=c(r[1]),l=c(r[2]||1)-1,u=c(r[3]||1)-1,p=c(r[4]||0),h=c(r[5]||0),f=c(r[6]||0),d=Math.floor(1e3*c(r[7]||0)),m=Boolean(r[4]&&!r[8]),g="-"===r[9]?1:-1,y=c(r[10]||0),v=c(r[11]||0),b=h>0||f>0||d>0;return p<(b?24:25)&&h<60&&f<60&&d<1e3&&l>-1&&l<12&&y<24&&v<60&&u>-1&&u<i(s,l+1)-i(s,l)&&(o=60*(24*(i(s,l)+u)+p+y*g),o=1e3*(60*(o+h+v*g)+f)+d,m&&(o=a(o)),-864e13<=o&&o<=864e13)?o:NaN}return e.parse.apply(this,arguments)};return q(t,{parse:s}),t}(Date)}Date.now||(Date.now=function(){return(new Date).getTime()});var mt=p.toFixed&&("0.000"!==8e-5.toFixed(3)||"1"!==.9.toFixed(0)||"1.25"!==1.255.toFixed(2)||"1000000000000000128"!==(0xde0b6b3a7640080).toFixed(0)),gt={base:1e7,size:6,data:[0,0,0,0,0,0],multiply:function(e,t){for(var n=-1,r=t;++n<gt.size;)r+=e*gt.data[n],gt.data[n]=r%gt.base,r=Math.floor(r/gt.base)},divide:function(e){for(var t=gt.size,n=0;--t>=0;)n+=gt.data[t],gt.data[t]=Math.floor(n/e),n=n%e*gt.base},numToString:function(){for(var e=gt.size,t="";--e>=0;)if(""!==t||0===e||0!==gt.data[e]){var n=l(gt.data[e]);""===t?t=n:t+=J("0000000",0,7-n.length)+n}return t},pow:function Ut(e,t,n){return 0===t?n:t%2===1?Ut(e,t-1,n*e):Ut(e*e,t/2,n)},log:function(e){for(var t=0,n=e;n>=4096;)t+=12,n/=4096;for(;n>=2;)t+=1,n/=2;return t}},yt=function(e){var t,n,r,i,a,o,s,u;if(t=c(e),t=N(t)?0:Math.floor(t),t<0||t>20)throw new RangeError("Number.toFixed called with invalid number of decimals");if(n=c(this),N(n))return"NaN";if(n<=-1e21||n>=1e21)return l(n);if(r="",n<0&&(r="-",n=-n),i="0",n>1e-21)if(a=gt.log(n*gt.pow(2,69,1))-69,o=a<0?n*gt.pow(2,-a,1):n/gt.pow(2,a,1),o*=4503599627370496,a=52-a,a>0){for(gt.multiply(0,o),s=t;s>=7;)gt.multiply(1e7,0),s-=7;for(gt.multiply(gt.pow(10,s,1),0),s=a-1;s>=23;)gt.divide(1<<23),s-=23;gt.divide(1<<s),gt.multiply(1,1),gt.divide(2),i=gt.numToString()}else gt.multiply(0,o),gt.multiply(1<<-a,0),i=gt.numToString()+J("0.00000000000000000000",2,2+t);return t>0?(u=i.length,i=u<=t?r+J("0.0000000000000000000",0,t-u+2)+i:r+J(i,0,u-t)+"."+J(i,u-t)):i=r+i,i};q(p,{toFixed:yt},mt);var vt=function(){try{return"1"===1..toPrecision(void 0)}catch(e){return!0}}(),bt=p.toPrecision;q(p,{toPrecision:function(e){return"undefined"==typeof e?bt.call(this):bt.call(this,e)}},vt),2!=="ab".split(/(?:ab)*/).length||4!==".".split(/(.?)(.?)/).length||"t"==="tesst".split(/(s)*/)[1]||4!=="test".split(/(?:)/,-1).length||"".split(/.?/).length||".".split(/()()/).length>1?!function(){var e="undefined"==typeof/()??/.exec("")[1],n=Math.pow(2,32)-1;u.split=function(r,i){var a=String(this);if("undefined"==typeof r&&0===i)return[];if(!t(r))return W(this,r,i);var o,s,l,u,c=[],p=(r.ignoreCase?"i":"")+(r.multiline?"m":"")+(r.unicode?"u":"")+(r.sticky?"y":""),h=0,f=new RegExp(r.source,p+"g");e||(o=new RegExp("^"+f.source+"$(?!\\s)",p));var m="undefined"==typeof i?n:z.ToUint32(i);for(s=f.exec(a);s&&(l=s.index+s[0].length,!(l>h&&(G(c,J(a,h,s.index)),!e&&s.length>1&&s[0].replace(o,function(){for(var e=1;e<arguments.length-2;e++)"undefined"==typeof arguments[e]&&(s[e]=void 0)}),s.length>1&&s.index<a.length&&d.apply(c,H(s,1)),u=s[0].length,h=l,c.length>=m)));)f.lastIndex===s.index&&f.lastIndex++,s=f.exec(a);return h===a.length?!u&&f.test("")||G(c,""):G(c,J(a,h)),c.length>m?H(c,0,m):c}}():"0".split(void 0,0).length&&(u.split=function(e,t){return"undefined"==typeof e&&0===t?[]:W(this,e,t)});var wt=u.replace,_t=function(){var e=[];return"x".replace(/x(.)?/g,function(t,n){G(e,n)}),1===e.length&&"undefined"==typeof e[0]}();_t||(u.replace=function(n,r){var i=e(r),a=t(n)&&/\)[*?]/.test(n.source);if(i&&a){var o=function(e){var t=arguments.length,i=n.lastIndex;n.lastIndex=0;var a=n.exec(e)||[];return n.lastIndex=i,G(a,arguments[t-2],arguments[t-1]),r.apply(this,a)};return wt.call(this,n,o)}return wt.call(this,n,r)});var xt=u.substr,At="".substr&&"b"!=="0b".substr(-1);q(u,{substr:function(e,t){var n=e;return e<0&&(n=w(this.length+e,0)),xt.call(this,n,t)}},At);var St="\t\n\x0B\f\r   ᠎              \u2028\u2029\ufeff",jt="​",Et="["+St+"]",Ot=new RegExp("^"+Et+Et+"*"),kt=new RegExp(Et+Et+"*$"),Tt=u.trim&&(St.trim()||!jt.trim());q(u,{trim:function(){if("undefined"==typeof this||null===this)throw new TypeError("can't convert "+this+" to object");return l(this).replace(Ot,"").replace(kt,"")}},Tt);var Ct=v.bind(String.prototype.trim),It=u.lastIndexOf&&"abcあい".lastIndexOf("あい",2)!==-1;q(u,{lastIndexOf:function(e){if("undefined"==typeof this||null===this)throw new TypeError("can't convert "+this+" to object");for(var t=l(this),n=l(e),r=arguments.length>1?c(arguments[1]):NaN,i=N(r)?1/0:z.ToInteger(r),a=_(w(i,0),t.length),o=n.length,s=a+o;s>0;){s=w(0,s-o);var u=Q(J(t,s,a+o),n);if(u!==-1)return s+u}return-1}},It);var Dt=u.lastIndexOf;if(q(u,{lastIndexOf:function(e){return Dt.apply(this,arguments)}},1!==u.lastIndexOf.length),8===parseInt(St+"08")&&22===parseInt(St+"0x16")||(parseInt=function(e){var t=/^[\-+]?0[xX]/;return function(n,r){var i=Ct(String(n)),a=c(r)||(t.test(i)?16:10);return e(i,a)}}(parseInt)),1/parseFloat("-0")!==-(1/0)&&(parseFloat=function(e){return function(t){var n=Ct(String(t)),r=e(n);return 0===r&&"-"===J(n,0,1)?-0:r}}(parseFloat)),"RangeError: test"!==String(new RangeError("test"))){var Lt=function(){if("undefined"==typeof this||null===this)throw new TypeError("can't convert "+this+" to object");var e=this.name;"undefined"==typeof e?e="Error":"string"!=typeof e&&(e=l(e));var t=this.message;return"undefined"==typeof t?t="":"string"!=typeof t&&(t=l(t)),e?t?e+": "+t:e:t};Error.prototype.toString=Lt}if(P){var Mt=function(e,t){if(K(e,t)){var n=Object.getOwnPropertyDescriptor(e,t);n.configurable&&(n.enumerable=!1,Object.defineProperty(e,t,n))}};Mt(Error.prototype,"message"),""!==Error.prototype.message&&(Error.prototype.message=""),Mt(Error.prototype,"name")}if("/a/gim"!==String(/a/gim)){var Rt=function(){var e="/"+this.source+"/";return this.global&&(e+="g"),this.ignoreCase&&(e+="i"),this.multiline&&(e+="m"),e};RegExp.prototype.toString=Rt}}),Handlebars.registerHelper("sanitize",function(e){var t;return void 0===e?"":(t=sanitizeHtml(e,{allowedTags:["div","span","b","i","em","strong","a"],allowedAttributes:{div:["class"],span:["class"],a:["href"]}}),new Handlebars.SafeString(t))}),Handlebars.registerHelper("renderTextParam",function(e){var t,n="text",r="",i=e.type||e.schema&&e.schema.type||"",a="array"===i.toLowerCase()||e.allowMultiple,o=a&&Array.isArray(e["default"])?e["default"].join("\n"):e["default"],s=Handlebars.Utils.escapeExpression(e.name),l=Handlebars.Utils.escapeExpression(e.valueId);i=Handlebars.Utils.escapeExpression(i);var u=Object.keys(e).filter(function(e){return null!==e.match(/^X-data-/i)}).reduce(function(t,n){return t+=" "+n.substring(2,n.length)+"='"+e[n]+"'"},"");if(e.format&&"password"===e.format&&(n="password"),l&&(r=" id='"+l+"'"),o=o?sanitizeHtml(o):"",a)t="<textarea class='body-textarea"+(e.required?" required":"")+"' name='"+s+"'"+r+u,t+=" placeholder='Provide multiple values in new lines"+(e.required?" (at least one required).":".")+"'>",t+=o+"</textarea>";else{var c="parameter";e.required&&(c+=" required"),t="<input class='"+c+"' minlength='"+(e.required?1:0)+"'",t+=" name='"+s+"' placeholder='"+(e.required?"(required)":"")+"'"+r+u,t+=" type='"+n+"' value='"+o+"'/>"}return new Handlebars.SafeString(t)}),Handlebars.registerHelper("ifCond",function(e,t,n,r){switch(t){case"==":return e==n?r.fn(this):r.inverse(this);case"===":return e===n?r.fn(this):r.inverse(this);case"<":return e<n?r.fn(this):r.inverse(this);case"<=":return e<=n?r.fn(this):r.inverse(this);case">":return e>n?r.fn(this):r.inverse(this);case">=":return e>=n?r.fn(this):r.inverse(this);case"&&":return e&&n?r.fn(this):r.inverse(this);case"||":return e||n?r.fn(this):r.inverse(this);default:return r.inverse(this)}}),Handlebars.registerHelper("escape",function(e){var t=Handlebars.Utils.escapeExpression(e);return new Handlebars.SafeString(t)}),function(e){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=e();else if("function"==typeof define&&define.amd)define([],e);else{var t;t="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:this,t.sanitizeHtml=e()}}(function(){return function e(t,n,r){function i(o,s){if(!n[o]){if(!t[o]){var l="function"==typeof require&&require;if(!s&&l)return l(o,!0);if(a)return a(o,!0);var u=new Error("Cannot find module '"+o+"'");throw u.code="MODULE_NOT_FOUND",u}var c=n[o]={exports:{}};t[o][0].call(c.exports,function(e){var n=t[o][1][e];return i(n?n:e)},c,c.exports,e,t,n,r)}return n[o].exports}for(var a="function"==typeof require&&require,o=0;o<r.length;o++)i(r[o]);return i}({1:[function(e,t,n){function r(e,t){e&&Object.keys(e).forEach(function(n){t(e[n],n)})}function i(e,t){return{}.hasOwnProperty.call(e,t)}function a(e,t,n){function c(e,t){var n=this;this.tag=e,this.attribs=t||{},this.tagPosition=d.length,this.text="",this.updateParentNodeText=function(){if(x.length){var e=x[x.length-1];e.text+=n.text}}}function p(e){return"string"!=typeof e&&(e+=""),e.replace(/\&/g,"&amp;").replace(/</g,"&lt;").replace(/\>/g,"&gt;").replace(/\"/g,"&quot;")}function h(e,n){n=n.replace(/[\x00-\x20]+/g,""),n=n.replace(/<\!\-\-.*?\-\-\>/g,"");var r=n.match(/^([a-zA-Z]+)\:/);if(!r)return!1;var a=r[1].toLowerCase();return i(t.allowedSchemesByTag,e)?t.allowedSchemesByTag[e].indexOf(a)===-1:!t.allowedSchemes||t.allowedSchemes.indexOf(a)===-1}function f(e,t){return t?(e=e.split(/\s+/),e.filter(function(e){return t.indexOf(e)!==-1}).join(" ")):e}var d="";t?(t=s(a.defaults,t),t.parser?t.parser=s(u,t.parser):t.parser=u):(t=a.defaults,t.parser=u);var m,g,y=t.nonTextTags||["script","style","textarea"];t.allowedAttributes&&(m={},g={},r(t.allowedAttributes,function(e,t){m[t]=[];var n=[];e.forEach(function(e){e.indexOf("*")>=0?n.push(l(e).replace(/\\\*/g,".*")):m[t].push(e)}),g[t]=new RegExp("^("+n.join("|")+")$")}));var v={};r(t.allowedClasses,function(e,t){m&&(i(m,t)||(m[t]=[]),m[t].push("class")),v[t]=e});var b,w={};r(t.transformTags,function(e,t){var n;"function"==typeof e?n=e:"string"==typeof e&&(n=a.simpleTransform(e)),"*"===t?b=n:w[t]=n});var _=0,x=[],A={},S={},j=!1,E=0,O=new o.Parser({onopentag:function(e,n){if(j)return void E++;var a=new c(e,n);x.push(a);var o,s=!1,l=!!a.text;i(w,e)&&(o=w[e](e,n),a.attribs=n=o.attribs,void 0!==o.text&&(a.innerText=o.text),e!==o.tagName&&(a.name=e=o.tagName,S[_]=o.tagName)),b&&(o=b(e,n),a.attribs=n=o.attribs,e!==o.tagName&&(a.name=e=o.tagName,S[_]=o.tagName)),t.allowedTags&&t.allowedTags.indexOf(e)===-1&&(s=!0,y.indexOf(e)!==-1&&(j=!0,E=1),A[_]=!0),_++,s||(d+="<"+e,(!m||i(m,e)||m["*"])&&r(n,function(t,n){if(!m||i(m,e)&&m[e].indexOf(n)!==-1||m["*"]&&m["*"].indexOf(n)!==-1||i(g,e)&&g[e].test(n)||g["*"]&&g["*"].test(n)){if(("href"===n||"src"===n)&&h(e,t))return void delete a.attribs[n];if("class"===n&&(t=f(t,v[e]),!t.length))return void delete a.attribs[n];d+=" "+n,t.length&&(d+='="'+p(t)+'"')}else delete a.attribs[n]}),t.selfClosing.indexOf(e)!==-1?d+=" />":(d+=">",!a.innerText||l||t.textFilter||(d+=a.innerText)))},ontext:function(e){if(!j){var n,r=x[x.length-1];if(r&&(n=r.tag,e=void 0!==r.innerText?r.innerText:e),"script"===n||"style"===n)d+=e;else{var i=p(e);d+=t.textFilter?t.textFilter(i):i}if(x.length){var a=x[x.length-1];a.text+=e}}},onclosetag:function(e){if(j){if(E--,E)return;j=!1}var n=x.pop();if(n){if(j=!1,_--,A[_])return delete A[_],void n.updateParentNodeText();if(S[_]&&(e=S[_],delete S[_]),t.exclusiveFilter&&t.exclusiveFilter(n))return void(d=d.substr(0,n.tagPosition));n.updateParentNodeText(),t.selfClosing.indexOf(e)===-1&&(d+="</"+e+">")}}},t.parser);return O.write(e),O.end(),d}var o=e("htmlparser2"),s=e("xtend"),l=e("regexp-quote");t.exports=a;var u={decodeEntities:!0};a.defaults={allowedTags:["h3","h4","h5","h6","blockquote","p","a","ul","ol","nl","li","b","i","strong","em","strike","code","hr","br","div","table","thead","caption","tbody","tr","th","td","pre"],allowedAttributes:{a:["href","name","target"],img:["src"]},selfClosing:["img","br","hr","area","base","basefont","input","link","meta"],allowedSchemes:["http","https","ftp","mailto"],allowedSchemesByTag:{}},a.simpleTransform=function(e,t,n){return n=void 0===n||n,t=t||{},function(r,i){var a;if(n)for(a in t)i[a]=t[a];else i=t;return{tagName:e,attribs:i}}}},{htmlparser2:36,"regexp-quote":54,xtend:58}],2:[function(e,t,n){"use strict";function r(){for(var e="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/",t=0,n=e.length;t<n;++t)l[t]=e[t],u[e.charCodeAt(t)]=t;u["-".charCodeAt(0)]=62,u["_".charCodeAt(0)]=63}function i(e){var t,n,r,i,a,o,s=e.length;if(s%4>0)throw new Error("Invalid string. Length must be a multiple of 4");a="="===e[s-2]?2:"="===e[s-1]?1:0,o=new c(3*s/4-a),r=a>0?s-4:s;var l=0;for(t=0,n=0;t<r;t+=4,n+=3)i=u[e.charCodeAt(t)]<<18|u[e.charCodeAt(t+1)]<<12|u[e.charCodeAt(t+2)]<<6|u[e.charCodeAt(t+3)],o[l++]=i>>16&255,o[l++]=i>>8&255,o[l++]=255&i;return 2===a?(i=u[e.charCodeAt(t)]<<2|u[e.charCodeAt(t+1)]>>4,o[l++]=255&i):1===a&&(i=u[e.charCodeAt(t)]<<10|u[e.charCodeAt(t+1)]<<4|u[e.charCodeAt(t+2)]>>2,o[l++]=i>>8&255,o[l++]=255&i),o}function a(e){return l[e>>18&63]+l[e>>12&63]+l[e>>6&63]+l[63&e]}function o(e,t,n){for(var r,i=[],o=t;o<n;o+=3)r=(e[o]<<16)+(e[o+1]<<8)+e[o+2],i.push(a(r));return i.join("")}function s(e){for(var t,n=e.length,r=n%3,i="",a=[],s=16383,u=0,c=n-r;u<c;u+=s)a.push(o(e,u,u+s>c?c:u+s));return 1===r?(t=e[n-1],i+=l[t>>2],i+=l[t<<4&63],i+="=="):2===r&&(t=(e[n-2]<<8)+e[n-1],i+=l[t>>10],i+=l[t>>4&63],i+=l[t<<2&63],i+="="),a.push(i),a.join("")}n.toByteArray=i,n.fromByteArray=s;var l=[],u=[],c="undefined"!=typeof Uint8Array?Uint8Array:Array;r()},{}],3:[function(e,t,n){},{}],4:[function(e,t,n){(function(t){"use strict";var r=e("buffer"),i=r.Buffer,a=r.SlowBuffer,o=r.kMaxLength||2147483647;n.alloc=function(e,t,n){if("function"==typeof i.alloc)return i.alloc(e,t,n);if("number"==typeof n)throw new TypeError("encoding must not be number");if("number"!=typeof e)throw new TypeError("size must be a number");if(e>o)throw new RangeError("size is too large");var r=n,a=t;void 0===a&&(r=void 0,a=0);var s=new i(e);if("string"==typeof a)for(var l=new i(a,r),u=l.length,c=-1;++c<e;)s[c]=l[c%u];else s.fill(a);return s},n.allocUnsafe=function(e){if("function"==typeof i.allocUnsafe)return i.allocUnsafe(e);if("number"!=typeof e)throw new TypeError("size must be a number");if(e>o)throw new RangeError("size is too large");return new i(e)},n.from=function(e,n,r){if("function"==typeof i.from&&(!t.Uint8Array||Uint8Array.from!==i.from))return i.from(e,n,r);if("number"==typeof e)throw new TypeError('"value" argument must not be a number');if("string"==typeof e)return new i(e,n);if("undefined"!=typeof ArrayBuffer&&e instanceof ArrayBuffer){var a=n;if(1===arguments.length)return new i(e);"undefined"==typeof a&&(a=0);var o=r;if("undefined"==typeof o&&(o=e.byteLength-a),a>=e.byteLength)throw new RangeError("'offset' is out of bounds");if(o>e.byteLength-a)throw new RangeError("'length' is out of bounds");return new i(e.slice(a,a+o))}if(i.isBuffer(e)){var s=new i(e.length);return e.copy(s,0,0,e.length),s}if(e){if(Array.isArray(e)||"undefined"!=typeof ArrayBuffer&&e.buffer instanceof ArrayBuffer||"length"in e)return new i(e);if("Buffer"===e.type&&Array.isArray(e.data))return new i(e.data)}throw new TypeError("First argument must be a string, Buffer, ArrayBuffer, Array, or array-like object.")},n.allocUnsafeSlow=function(e){if("function"==typeof i.allocUnsafeSlow)return i.allocUnsafeSlow(e);if("number"!=typeof e)throw new TypeError("size must be a number");if(e>=o)throw new RangeError("size is too large");return new a(e)}}).call(this,"undefined"!=typeof global?global:"undefined"!=typeof self?self:"undefined"!=typeof window?window:{})},{buffer:5}],5:[function(e,t,n){(function(t){"use strict";function r(){try{var e=new Uint8Array(1);return e.__proto__={__proto__:Uint8Array.prototype,foo:function(){return 42}},42===e.foo()&&"function"==typeof e.subarray&&0===e.subarray(1,1).byteLength}catch(t){return!1}}function i(){return o.TYPED_ARRAY_SUPPORT?2147483647:1073741823}function a(e,t){if(i()<t)throw new RangeError("Invalid typed array length");return o.TYPED_ARRAY_SUPPORT?(e=new Uint8Array(t),e.__proto__=o.prototype):(null===e&&(e=new o(t)),e.length=t),e}function o(e,t,n){if(!(o.TYPED_ARRAY_SUPPORT||this instanceof o))return new o(e,t,n);if("number"==typeof e){if("string"==typeof t)throw new Error("If encoding is specified then the first argument must be a string");return c(this,e)}return s(this,e,t,n)}function s(e,t,n,r){if("number"==typeof t)throw new TypeError('"value" argument must not be a number');return"undefined"!=typeof ArrayBuffer&&t instanceof ArrayBuffer?f(e,t,n,r):"string"==typeof t?p(e,t,n):d(e,t)}function l(e){if("number"!=typeof e)throw new TypeError('"size" argument must be a number');if(e<0)throw new RangeError('"size" argument must not be negative')}function u(e,t,n,r){return l(t),t<=0?a(e,t):void 0!==n?"string"==typeof r?a(e,t).fill(n,r):a(e,t).fill(n):a(e,t)}function c(e,t){if(l(t),e=a(e,t<0?0:0|m(t)),!o.TYPED_ARRAY_SUPPORT)for(var n=0;n<t;++n)e[n]=0;return e}function p(e,t,n){if("string"==typeof n&&""!==n||(n="utf8"),!o.isEncoding(n))throw new TypeError('"encoding" must be a valid string encoding');var r=0|y(t,n);e=a(e,r);var i=e.write(t,n);return i!==r&&(e=e.slice(0,i)),e}function h(e,t){var n=t.length<0?0:0|m(t.length);e=a(e,n);for(var r=0;r<n;r+=1)e[r]=255&t[r];return e}function f(e,t,n,r){if(t.byteLength,n<0||t.byteLength<n)throw new RangeError("'offset' is out of bounds");if(t.byteLength<n+(r||0))throw new RangeError("'length' is out of bounds");return t=void 0===n&&void 0===r?new Uint8Array(t):void 0===r?new Uint8Array(t,n):new Uint8Array(t,n,r),o.TYPED_ARRAY_SUPPORT?(e=t,e.__proto__=o.prototype):e=h(e,t),e}function d(e,t){if(o.isBuffer(t)){var n=0|m(t.length);return e=a(e,n),0===e.length?e:(t.copy(e,0,0,n),e)}if(t){if("undefined"!=typeof ArrayBuffer&&t.buffer instanceof ArrayBuffer||"length"in t)return"number"!=typeof t.length||G(t.length)?a(e,0):h(e,t);if("Buffer"===t.type&&Z(t.data))return h(e,t.data)}throw new TypeError("First argument must be a string, Buffer, ArrayBuffer, Array, or array-like object.")}function m(e){if(e>=i())throw new RangeError("Attempt to allocate Buffer larger than maximum size: 0x"+i().toString(16)+" bytes");return 0|e}function g(e){return+e!=e&&(e=0),o.alloc(+e)}function y(e,t){if(o.isBuffer(e))return e.length;if("undefined"!=typeof ArrayBuffer&&"function"==typeof ArrayBuffer.isView&&(ArrayBuffer.isView(e)||e instanceof ArrayBuffer))return e.byteLength;"string"!=typeof e&&(e=""+e);var n=e.length;if(0===n)return 0;for(var r=!1;;)switch(t){case"ascii":case"latin1":case"binary":return n;case"utf8":case"utf-8":case void 0:return H(e).length;case"ucs2":case"ucs-2":case"utf16le":case"utf-16le":return 2*n;case"hex":return n>>>1;case"base64":return W(e).length;default:if(r)return H(e).length;t=(""+t).toLowerCase(),r=!0}}function v(e,t,n){var r=!1;if((void 0===t||t<0)&&(t=0),t>this.length)return"";if((void 0===n||n>this.length)&&(n=this.length),n<=0)return"";if(n>>>=0,t>>>=0,n<=t)return"";for(e||(e="utf8");;)switch(e){case"hex":return L(this,t,n);case"utf8":case"utf-8":return T(this,t,n);case"ascii":return I(this,t,n);case"latin1":case"binary":return D(this,t,n);case"base64":return k(this,t,n);case"ucs2":case"ucs-2":case"utf16le":case"utf-16le":return M(this,t,n);default:if(r)throw new TypeError("Unknown encoding: "+e);e=(e+"").toLowerCase(),r=!0}}function b(e,t,n){var r=e[t];e[t]=e[n],e[n]=r}function w(e,t,n,r,i){if(0===e.length)return-1;if("string"==typeof n?(r=n,n=0):n>2147483647?n=2147483647:n<-2147483648&&(n=-2147483648),n=+n,isNaN(n)&&(n=i?0:e.length-1),n<0&&(n=e.length+n),n>=e.length){if(i)return-1;n=e.length-1}else if(n<0){if(!i)return-1;n=0}if("string"==typeof t&&(t=o.from(t,r)),o.isBuffer(t))return 0===t.length?-1:_(e,t,n,r,i);if("number"==typeof t)return t=255&t,o.TYPED_ARRAY_SUPPORT&&"function"==typeof Uint8Array.prototype.indexOf?i?Uint8Array.prototype.indexOf.call(e,t,n):Uint8Array.prototype.lastIndexOf.call(e,t,n):_(e,[t],n,r,i);throw new TypeError("val must be string, number or Buffer")}function _(e,t,n,r,i){function a(e,t){return 1===o?e[t]:e.readUInt16BE(t*o)}var o=1,s=e.length,l=t.length;if(void 0!==r&&(r=String(r).toLowerCase(),"ucs2"===r||"ucs-2"===r||"utf16le"===r||"utf-16le"===r)){if(e.length<2||t.length<2)return-1;o=2,s/=2,l/=2,n/=2}var u;if(i){var c=-1;for(u=n;u<s;u++)if(a(e,u)===a(t,c===-1?0:u-c)){if(c===-1&&(c=u),u-c+1===l)return c*o}else c!==-1&&(u-=u-c),c=-1}else for(n+l>s&&(n=s-l),u=n;u>=0;u--){for(var p=!0,h=0;h<l;h++)if(a(e,u+h)!==a(t,h)){p=!1;break}if(p)return u}return-1}function x(e,t,n,r){n=Number(n)||0;var i=e.length-n;r?(r=Number(r),r>i&&(r=i)):r=i;var a=t.length;if(a%2!==0)throw new TypeError("Invalid hex string");r>a/2&&(r=a/2);for(var o=0;o<r;++o){var s=parseInt(t.substr(2*o,2),16);if(isNaN(s))return o;e[n+o]=s}return o}function A(e,t,n,r){return Q(H(t,e.length-n),e,n,r)}function S(e,t,n,r){return Q(Y(t),e,n,r)}function j(e,t,n,r){return S(e,t,n,r)}function E(e,t,n,r){return Q(W(t),e,n,r)}function O(e,t,n,r){return Q(J(t,e.length-n),e,n,r)}function k(e,t,n){return 0===t&&n===e.length?K.fromByteArray(e):K.fromByteArray(e.slice(t,n))}function T(e,t,n){n=Math.min(e.length,n);for(var r=[],i=t;i<n;){var a=e[i],o=null,s=a>239?4:a>223?3:a>191?2:1;if(i+s<=n){var l,u,c,p;switch(s){case 1:a<128&&(o=a);break;case 2:l=e[i+1],128===(192&l)&&(p=(31&a)<<6|63&l,p>127&&(o=p));break;case 3:l=e[i+1],u=e[i+2],128===(192&l)&&128===(192&u)&&(p=(15&a)<<12|(63&l)<<6|63&u,p>2047&&(p<55296||p>57343)&&(o=p));break;case 4:l=e[i+1],u=e[i+2],c=e[i+3],128===(192&l)&&128===(192&u)&&128===(192&c)&&(p=(15&a)<<18|(63&l)<<12|(63&u)<<6|63&c,p>65535&&p<1114112&&(o=p))}}null===o?(o=65533,s=1):o>65535&&(o-=65536,r.push(o>>>10&1023|55296),o=56320|1023&o),r.push(o),i+=s}return C(r)}function C(e){var t=e.length;if(t<=ee)return String.fromCharCode.apply(String,e);for(var n="",r=0;r<t;)n+=String.fromCharCode.apply(String,e.slice(r,r+=ee));return n}function I(e,t,n){var r="";n=Math.min(e.length,n);for(var i=t;i<n;++i)r+=String.fromCharCode(127&e[i]);return r}function D(e,t,n){var r="";n=Math.min(e.length,n);for(var i=t;i<n;++i)r+=String.fromCharCode(e[i]);return r}function L(e,t,n){var r=e.length;(!t||t<0)&&(t=0),(!n||n<0||n>r)&&(n=r);for(var i="",a=t;a<n;++a)i+=V(e[a]);return i}function M(e,t,n){for(var r=e.slice(t,n),i="",a=0;a<r.length;a+=2)i+=String.fromCharCode(r[a]+256*r[a+1]);return i}function R(e,t,n){if(e%1!==0||e<0)throw new RangeError("offset is not uint");if(e+t>n)throw new RangeError("Trying to access beyond buffer length")}function U(e,t,n,r,i,a){if(!o.isBuffer(e))throw new TypeError('"buffer" argument must be a Buffer instance');if(t>i||t<a)throw new RangeError('"value" argument is out of bounds');if(n+r>e.length)throw new RangeError("Index out of range")}function P(e,t,n,r){t<0&&(t=65535+t+1);for(var i=0,a=Math.min(e.length-n,2);i<a;++i)e[n+i]=(t&255<<8*(r?i:1-i))>>>8*(r?i:1-i)}function q(e,t,n,r){t<0&&(t=4294967295+t+1);for(var i=0,a=Math.min(e.length-n,4);i<a;++i)e[n+i]=t>>>8*(r?i:3-i)&255}function B(e,t,n,r,i,a){if(n+r>e.length)throw new RangeError("Index out of range");if(n<0)throw new RangeError("Index out of range")}function N(e,t,n,r,i){return i||B(e,t,n,4,3.4028234663852886e38,-3.4028234663852886e38),X.write(e,t,n,r,23,4),n+4}function z(e,t,n,r,i){return i||B(e,t,n,8,1.7976931348623157e308,-1.7976931348623157e308),X.write(e,t,n,r,52,8),n+8}function $(e){if(e=F(e).replace(te,""),e.length<2)return"";for(;e.length%4!==0;)e+="=";return e}function F(e){return e.trim?e.trim():e.replace(/^\s+|\s+$/g,"")}function V(e){return e<16?"0"+e.toString(16):e.toString(16)}function H(e,t){t=t||1/0;for(var n,r=e.length,i=null,a=[],o=0;o<r;++o){if(n=e.charCodeAt(o),n>55295&&n<57344){if(!i){if(n>56319){(t-=3)>-1&&a.push(239,191,189);continue}if(o+1===r){(t-=3)>-1&&a.push(239,191,189);continue}i=n;continue}if(n<56320){(t-=3)>-1&&a.push(239,191,189),i=n;continue}n=(i-55296<<10|n-56320)+65536}else i&&(t-=3)>-1&&a.push(239,191,189);if(i=null,n<128){if((t-=1)<0)break;a.push(n)}else if(n<2048){if((t-=2)<0)break;a.push(n>>6|192,63&n|128)}else if(n<65536){if((t-=3)<0)break;a.push(n>>12|224,n>>6&63|128,63&n|128)}else{if(!(n<1114112))throw new Error("Invalid code point");if((t-=4)<0)break;a.push(n>>18|240,n>>12&63|128,n>>6&63|128,63&n|128)}}return a}function Y(e){for(var t=[],n=0;n<e.length;++n)t.push(255&e.charCodeAt(n));return t}function J(e,t){for(var n,r,i,a=[],o=0;o<e.length&&!((t-=2)<0);++o)n=e.charCodeAt(o),r=n>>8,i=n%256,a.push(i),a.push(r);return a}function W(e){return K.toByteArray($(e))}function Q(e,t,n,r){for(var i=0;i<r&&!(i+n>=t.length||i>=e.length);++i)t[i+n]=e[i];return i}function G(e){return e!==e}var K=e("base64-js"),X=e("ieee754"),Z=e("isarray");n.Buffer=o,n.SlowBuffer=g,n.INSPECT_MAX_BYTES=50,o.TYPED_ARRAY_SUPPORT=void 0!==t.TYPED_ARRAY_SUPPORT?t.TYPED_ARRAY_SUPPORT:r(),n.kMaxLength=i(),o.poolSize=8192,o._augment=function(e){return e.__proto__=o.prototype,e},o.from=function(e,t,n){return s(null,e,t,n)},o.TYPED_ARRAY_SUPPORT&&(o.prototype.__proto__=Uint8Array.prototype,o.__proto__=Uint8Array,"undefined"!=typeof Symbol&&Symbol.species&&o[Symbol.species]===o&&Object.defineProperty(o,Symbol.species,{value:null,configurable:!0})),o.alloc=function(e,t,n){return u(null,e,t,n)},o.allocUnsafe=function(e){return c(null,e)},o.allocUnsafeSlow=function(e){return c(null,e)},o.isBuffer=function(e){return!(null==e||!e._isBuffer)},o.compare=function(e,t){if(!o.isBuffer(e)||!o.isBuffer(t))throw new TypeError("Arguments must be Buffers");if(e===t)return 0;for(var n=e.length,r=t.length,i=0,a=Math.min(n,r);i<a;++i)if(e[i]!==t[i]){n=e[i],r=t[i];break}return n<r?-1:r<n?1:0},o.isEncoding=function(e){switch(String(e).toLowerCase()){case"hex":case"utf8":case"utf-8":case"ascii":case"latin1":case"binary":case"base64":case"ucs2":case"ucs-2":case"utf16le":case"utf-16le":return!0;default:return!1}},o.concat=function(e,t){if(!Z(e))throw new TypeError('"list" argument must be an Array of Buffers');if(0===e.length)return o.alloc(0);var n;if(void 0===t)for(t=0,n=0;n<e.length;++n)t+=e[n].length;var r=o.allocUnsafe(t),i=0;for(n=0;n<e.length;++n){var a=e[n];if(!o.isBuffer(a))throw new TypeError('"list" argument must be an Array of Buffers');a.copy(r,i),i+=a.length}return r},o.byteLength=y,o.prototype._isBuffer=!0,o.prototype.swap16=function(){var e=this.length;if(e%2!==0)throw new RangeError("Buffer size must be a multiple of 16-bits");for(var t=0;t<e;t+=2)b(this,t,t+1);return this},o.prototype.swap32=function(){var e=this.length;if(e%4!==0)throw new RangeError("Buffer size must be a multiple of 32-bits");for(var t=0;t<e;t+=4)b(this,t,t+3),b(this,t+1,t+2);return this},o.prototype.swap64=function(){var e=this.length;if(e%8!==0)throw new RangeError("Buffer size must be a multiple of 64-bits");for(var t=0;t<e;t+=8)b(this,t,t+7),b(this,t+1,t+6),b(this,t+2,t+5),b(this,t+3,t+4);return this},o.prototype.toString=function(){var e=0|this.length;return 0===e?"":0===arguments.length?T(this,0,e):v.apply(this,arguments)},o.prototype.equals=function(e){if(!o.isBuffer(e))throw new TypeError("Argument must be a Buffer");return this===e||0===o.compare(this,e)},o.prototype.inspect=function(){var e="",t=n.INSPECT_MAX_BYTES;return this.length>0&&(e=this.toString("hex",0,t).match(/.{2}/g).join(" "),this.length>t&&(e+=" ... ")),"<Buffer "+e+">"},o.prototype.compare=function(e,t,n,r,i){if(!o.isBuffer(e))throw new TypeError("Argument must be a Buffer");if(void 0===t&&(t=0),void 0===n&&(n=e?e.length:0),void 0===r&&(r=0),void 0===i&&(i=this.length),t<0||n>e.length||r<0||i>this.length)throw new RangeError("out of range index");if(r>=i&&t>=n)return 0;if(r>=i)return-1;if(t>=n)return 1;if(t>>>=0,n>>>=0,r>>>=0,i>>>=0,this===e)return 0;for(var a=i-r,s=n-t,l=Math.min(a,s),u=this.slice(r,i),c=e.slice(t,n),p=0;p<l;++p)if(u[p]!==c[p]){a=u[p],s=c[p];break}return a<s?-1:s<a?1:0},o.prototype.includes=function(e,t,n){return this.indexOf(e,t,n)!==-1},o.prototype.indexOf=function(e,t,n){return w(this,e,t,n,!0)},o.prototype.lastIndexOf=function(e,t,n){return w(this,e,t,n,!1)},o.prototype.write=function(e,t,n,r){if(void 0===t)r="utf8",n=this.length,t=0;else if(void 0===n&&"string"==typeof t)r=t,n=this.length,t=0;else{if(!isFinite(t))throw new Error("Buffer.write(string, encoding, offset[, length]) is no longer supported");t=0|t,isFinite(n)?(n=0|n,void 0===r&&(r="utf8")):(r=n,n=void 0)}var i=this.length-t;if((void 0===n||n>i)&&(n=i),e.length>0&&(n<0||t<0)||t>this.length)throw new RangeError("Attempt to write outside buffer bounds");r||(r="utf8");for(var a=!1;;)switch(r){case"hex":return x(this,e,t,n);case"utf8":case"utf-8":return A(this,e,t,n);case"ascii":return S(this,e,t,n);case"latin1":case"binary":return j(this,e,t,n);case"base64":return E(this,e,t,n);case"ucs2":case"ucs-2":case"utf16le":case"utf-16le":return O(this,e,t,n);default:if(a)throw new TypeError("Unknown encoding: "+r);r=(""+r).toLowerCase(),a=!0}},o.prototype.toJSON=function(){return{type:"Buffer",data:Array.prototype.slice.call(this._arr||this,0)}};var ee=4096;o.prototype.slice=function(e,t){var n=this.length;e=~~e,t=void 0===t?n:~~t,e<0?(e+=n,e<0&&(e=0)):e>n&&(e=n),t<0?(t+=n,t<0&&(t=0)):t>n&&(t=n),t<e&&(t=e);var r;if(o.TYPED_ARRAY_SUPPORT)r=this.subarray(e,t),r.__proto__=o.prototype;else{var i=t-e;r=new o(i,(void 0));for(var a=0;a<i;++a)r[a]=this[a+e]}return r},o.prototype.readUIntLE=function(e,t,n){e=0|e,t=0|t,n||R(e,t,this.length);for(var r=this[e],i=1,a=0;++a<t&&(i*=256);)r+=this[e+a]*i;return r},o.prototype.readUIntBE=function(e,t,n){e=0|e,t=0|t,n||R(e,t,this.length);for(var r=this[e+--t],i=1;t>0&&(i*=256);)r+=this[e+--t]*i;return r},o.prototype.readUInt8=function(e,t){return t||R(e,1,this.length),this[e]},o.prototype.readUInt16LE=function(e,t){return t||R(e,2,this.length),this[e]|this[e+1]<<8},o.prototype.readUInt16BE=function(e,t){return t||R(e,2,this.length),this[e]<<8|this[e+1]},o.prototype.readUInt32LE=function(e,t){return t||R(e,4,this.length),(this[e]|this[e+1]<<8|this[e+2]<<16)+16777216*this[e+3]},o.prototype.readUInt32BE=function(e,t){return t||R(e,4,this.length),16777216*this[e]+(this[e+1]<<16|this[e+2]<<8|this[e+3])},o.prototype.readIntLE=function(e,t,n){e=0|e,t=0|t,n||R(e,t,this.length);for(var r=this[e],i=1,a=0;++a<t&&(i*=256);)r+=this[e+a]*i;return i*=128,r>=i&&(r-=Math.pow(2,8*t)),r},o.prototype.readIntBE=function(e,t,n){e=0|e,t=0|t,n||R(e,t,this.length);for(var r=t,i=1,a=this[e+--r];r>0&&(i*=256);)a+=this[e+--r]*i;return i*=128,a>=i&&(a-=Math.pow(2,8*t)),a},o.prototype.readInt8=function(e,t){return t||R(e,1,this.length),128&this[e]?(255-this[e]+1)*-1:this[e]},o.prototype.readInt16LE=function(e,t){t||R(e,2,this.length);var n=this[e]|this[e+1]<<8;return 32768&n?4294901760|n:n},o.prototype.readInt16BE=function(e,t){t||R(e,2,this.length);var n=this[e+1]|this[e]<<8;return 32768&n?4294901760|n:n},o.prototype.readInt32LE=function(e,t){return t||R(e,4,this.length),this[e]|this[e+1]<<8|this[e+2]<<16|this[e+3]<<24},o.prototype.readInt32BE=function(e,t){return t||R(e,4,this.length),this[e]<<24|this[e+1]<<16|this[e+2]<<8|this[e+3]},o.prototype.readFloatLE=function(e,t){return t||R(e,4,this.length),X.read(this,e,!0,23,4)},o.prototype.readFloatBE=function(e,t){return t||R(e,4,this.length),X.read(this,e,!1,23,4)},o.prototype.readDoubleLE=function(e,t){return t||R(e,8,this.length),X.read(this,e,!0,52,8)},o.prototype.readDoubleBE=function(e,t){
-return t||R(e,8,this.length),X.read(this,e,!1,52,8)},o.prototype.writeUIntLE=function(e,t,n,r){if(e=+e,t=0|t,n=0|n,!r){var i=Math.pow(2,8*n)-1;U(this,e,t,n,i,0)}var a=1,o=0;for(this[t]=255&e;++o<n&&(a*=256);)this[t+o]=e/a&255;return t+n},o.prototype.writeUIntBE=function(e,t,n,r){if(e=+e,t=0|t,n=0|n,!r){var i=Math.pow(2,8*n)-1;U(this,e,t,n,i,0)}var a=n-1,o=1;for(this[t+a]=255&e;--a>=0&&(o*=256);)this[t+a]=e/o&255;return t+n},o.prototype.writeUInt8=function(e,t,n){return e=+e,t=0|t,n||U(this,e,t,1,255,0),o.TYPED_ARRAY_SUPPORT||(e=Math.floor(e)),this[t]=255&e,t+1},o.prototype.writeUInt16LE=function(e,t,n){return e=+e,t=0|t,n||U(this,e,t,2,65535,0),o.TYPED_ARRAY_SUPPORT?(this[t]=255&e,this[t+1]=e>>>8):P(this,e,t,!0),t+2},o.prototype.writeUInt16BE=function(e,t,n){return e=+e,t=0|t,n||U(this,e,t,2,65535,0),o.TYPED_ARRAY_SUPPORT?(this[t]=e>>>8,this[t+1]=255&e):P(this,e,t,!1),t+2},o.prototype.writeUInt32LE=function(e,t,n){return e=+e,t=0|t,n||U(this,e,t,4,4294967295,0),o.TYPED_ARRAY_SUPPORT?(this[t+3]=e>>>24,this[t+2]=e>>>16,this[t+1]=e>>>8,this[t]=255&e):q(this,e,t,!0),t+4},o.prototype.writeUInt32BE=function(e,t,n){return e=+e,t=0|t,n||U(this,e,t,4,4294967295,0),o.TYPED_ARRAY_SUPPORT?(this[t]=e>>>24,this[t+1]=e>>>16,this[t+2]=e>>>8,this[t+3]=255&e):q(this,e,t,!1),t+4},o.prototype.writeIntLE=function(e,t,n,r){if(e=+e,t=0|t,!r){var i=Math.pow(2,8*n-1);U(this,e,t,n,i-1,-i)}var a=0,o=1,s=0;for(this[t]=255&e;++a<n&&(o*=256);)e<0&&0===s&&0!==this[t+a-1]&&(s=1),this[t+a]=(e/o>>0)-s&255;return t+n},o.prototype.writeIntBE=function(e,t,n,r){if(e=+e,t=0|t,!r){var i=Math.pow(2,8*n-1);U(this,e,t,n,i-1,-i)}var a=n-1,o=1,s=0;for(this[t+a]=255&e;--a>=0&&(o*=256);)e<0&&0===s&&0!==this[t+a+1]&&(s=1),this[t+a]=(e/o>>0)-s&255;return t+n},o.prototype.writeInt8=function(e,t,n){return e=+e,t=0|t,n||U(this,e,t,1,127,-128),o.TYPED_ARRAY_SUPPORT||(e=Math.floor(e)),e<0&&(e=255+e+1),this[t]=255&e,t+1},o.prototype.writeInt16LE=function(e,t,n){return e=+e,t=0|t,n||U(this,e,t,2,32767,-32768),o.TYPED_ARRAY_SUPPORT?(this[t]=255&e,this[t+1]=e>>>8):P(this,e,t,!0),t+2},o.prototype.writeInt16BE=function(e,t,n){return e=+e,t=0|t,n||U(this,e,t,2,32767,-32768),o.TYPED_ARRAY_SUPPORT?(this[t]=e>>>8,this[t+1]=255&e):P(this,e,t,!1),t+2},o.prototype.writeInt32LE=function(e,t,n){return e=+e,t=0|t,n||U(this,e,t,4,2147483647,-2147483648),o.TYPED_ARRAY_SUPPORT?(this[t]=255&e,this[t+1]=e>>>8,this[t+2]=e>>>16,this[t+3]=e>>>24):q(this,e,t,!0),t+4},o.prototype.writeInt32BE=function(e,t,n){return e=+e,t=0|t,n||U(this,e,t,4,2147483647,-2147483648),e<0&&(e=4294967295+e+1),o.TYPED_ARRAY_SUPPORT?(this[t]=e>>>24,this[t+1]=e>>>16,this[t+2]=e>>>8,this[t+3]=255&e):q(this,e,t,!1),t+4},o.prototype.writeFloatLE=function(e,t,n){return N(this,e,t,!0,n)},o.prototype.writeFloatBE=function(e,t,n){return N(this,e,t,!1,n)},o.prototype.writeDoubleLE=function(e,t,n){return z(this,e,t,!0,n)},o.prototype.writeDoubleBE=function(e,t,n){return z(this,e,t,!1,n)},o.prototype.copy=function(e,t,n,r){if(n||(n=0),r||0===r||(r=this.length),t>=e.length&&(t=e.length),t||(t=0),r>0&&r<n&&(r=n),r===n)return 0;if(0===e.length||0===this.length)return 0;if(t<0)throw new RangeError("targetStart out of bounds");if(n<0||n>=this.length)throw new RangeError("sourceStart out of bounds");if(r<0)throw new RangeError("sourceEnd out of bounds");r>this.length&&(r=this.length),e.length-t<r-n&&(r=e.length-t+n);var i,a=r-n;if(this===e&&n<t&&t<r)for(i=a-1;i>=0;--i)e[i+t]=this[i+n];else if(a<1e3||!o.TYPED_ARRAY_SUPPORT)for(i=0;i<a;++i)e[i+t]=this[i+n];else Uint8Array.prototype.set.call(e,this.subarray(n,n+a),t);return a},o.prototype.fill=function(e,t,n,r){if("string"==typeof e){if("string"==typeof t?(r=t,t=0,n=this.length):"string"==typeof n&&(r=n,n=this.length),1===e.length){var i=e.charCodeAt(0);i<256&&(e=i)}if(void 0!==r&&"string"!=typeof r)throw new TypeError("encoding must be a string");if("string"==typeof r&&!o.isEncoding(r))throw new TypeError("Unknown encoding: "+r)}else"number"==typeof e&&(e=255&e);if(t<0||this.length<t||this.length<n)throw new RangeError("Out of range index");if(n<=t)return this;t>>>=0,n=void 0===n?this.length:n>>>0,e||(e=0);var a;if("number"==typeof e)for(a=t;a<n;++a)this[a]=e;else{var s=o.isBuffer(e)?e:H(new o(e,r).toString()),l=s.length;for(a=0;a<n-t;++a)this[a+t]=s[a%l]}return this};var te=/[^+\/0-9A-Za-z-_]/g}).call(this,"undefined"!=typeof global?global:"undefined"!=typeof self?self:"undefined"!=typeof window?window:{})},{"base64-js":2,ieee754:37,isarray:40}],6:[function(e,t,n){(function(e){function t(e){return Array.isArray?Array.isArray(e):"[object Array]"===g(e)}function r(e){return"boolean"==typeof e}function i(e){return null===e}function a(e){return null==e}function o(e){return"number"==typeof e}function s(e){return"string"==typeof e}function l(e){return"symbol"==typeof e}function u(e){return void 0===e}function c(e){return"[object RegExp]"===g(e)}function p(e){return"object"==typeof e&&null!==e}function h(e){return"[object Date]"===g(e)}function f(e){return"[object Error]"===g(e)||e instanceof Error}function d(e){return"function"==typeof e}function m(e){return null===e||"boolean"==typeof e||"number"==typeof e||"string"==typeof e||"symbol"==typeof e||"undefined"==typeof e}function g(e){return Object.prototype.toString.call(e)}n.isArray=t,n.isBoolean=r,n.isNull=i,n.isNullOrUndefined=a,n.isNumber=o,n.isString=s,n.isSymbol=l,n.isUndefined=u,n.isRegExp=c,n.isObject=p,n.isDate=h,n.isError=f,n.isFunction=d,n.isPrimitive=m,n.isBuffer=e.isBuffer}).call(this,{isBuffer:e("../../is-buffer/index.js")})},{"../../is-buffer/index.js":39}],7:[function(e,t,n){function r(e,t){if(e){var n,r="";for(var i in e)n=e[i],r&&(r+=" "),r+=!n&&p[i]?i:i+'="'+(t.decodeEntities?c.encodeXML(n):n)+'"';return r}}function i(e,t){"svg"===e.name&&(t={decodeEntities:t.decodeEntities,xmlMode:!0});var n="<"+e.name,i=r(e.attribs,t);return i&&(n+=" "+i),!t.xmlMode||e.children&&0!==e.children.length?(n+=">",e.children&&(n+=d(e.children,t)),f[e.name]&&!t.xmlMode||(n+="</"+e.name+">")):n+="/>",n}function a(e){return"<"+e.data+">"}function o(e,t){var n=e.data||"";return!t.decodeEntities||e.parent&&e.parent.name in h||(n=c.encodeXML(n)),n}function s(e){return"<![CDATA["+e.children[0].data+"]]>"}function l(e){return"<!--"+e.data+"-->"}var u=e("domelementtype"),c=e("entities"),p={__proto__:null,allowfullscreen:!0,async:!0,autofocus:!0,autoplay:!0,checked:!0,controls:!0,"default":!0,defer:!0,disabled:!0,hidden:!0,ismap:!0,loop:!0,multiple:!0,muted:!0,open:!0,readonly:!0,required:!0,reversed:!0,scoped:!0,seamless:!0,selected:!0,typemustmatch:!0},h={__proto__:null,style:!0,script:!0,xmp:!0,iframe:!0,noembed:!0,noframes:!0,plaintext:!0,noscript:!0},f={__proto__:null,area:!0,base:!0,basefont:!0,br:!0,col:!0,command:!0,embed:!0,frame:!0,hr:!0,img:!0,input:!0,isindex:!0,keygen:!0,link:!0,meta:!0,param:!0,source:!0,track:!0,wbr:!0},d=t.exports=function(e,t){Array.isArray(e)||e.cheerio||(e=[e]),t=t||{};for(var n="",r=0;r<e.length;r++){var c=e[r];n+="root"===c.type?d(c.children,t):u.isTag(c)?i(c,t):c.type===u.Directive?a(c):c.type===u.Comment?l(c):c.type===u.CDATA?s(c):o(c,t)}return n}},{domelementtype:8,entities:20}],8:[function(e,t,n){t.exports={Text:"text",Directive:"directive",Comment:"comment",Script:"script",Style:"style",Tag:"tag",CDATA:"cdata",isTag:function(e){return"tag"===e.type||"script"===e.type||"style"===e.type}}},{}],9:[function(e,t,n){t.exports={Text:"text",Directive:"directive",Comment:"comment",Script:"script",Style:"style",Tag:"tag",CDATA:"cdata",Doctype:"doctype",isTag:function(e){return"tag"===e.type||"script"===e.type||"style"===e.type}}},{}],10:[function(e,t,n){function r(e,t,n){"object"==typeof e?(n=t,t=e,e=null):"function"==typeof t&&(n=t,t=l),this._callback=e,this._options=t||l,this._elementCB=n,this.dom=[],this._done=!1,this._tagStack=[],this._parser=this._parser||null}var i=e("domelementtype"),a=/\s+/g,o=e("./lib/node"),s=e("./lib/element"),l={normalizeWhitespace:!1,withStartIndices:!1};r.prototype.onparserinit=function(e){this._parser=e},r.prototype.onreset=function(){r.call(this,this._callback,this._options,this._elementCB)},r.prototype.onend=function(){this._done||(this._done=!0,this._parser=null,this._handleCallback(null))},r.prototype._handleCallback=r.prototype.onerror=function(e){if("function"==typeof this._callback)this._callback(e,this.dom);else if(e)throw e},r.prototype.onclosetag=function(){var e=this._tagStack.pop();this._elementCB&&this._elementCB(e)},r.prototype._addDomElement=function(e){var t=this._tagStack[this._tagStack.length-1],n=t?t.children:this.dom,r=n[n.length-1];e.next=null,this._options.withStartIndices&&(e.startIndex=this._parser.startIndex),this._options.withDomLvl1&&(e.__proto__="tag"===e.type?s:o),r?(e.prev=r,r.next=e):e.prev=null,n.push(e),e.parent=t||null},r.prototype.onopentag=function(e,t){var n={type:"script"===e?i.Script:"style"===e?i.Style:i.Tag,name:e,attribs:t,children:[]};this._addDomElement(n),this._tagStack.push(n)},r.prototype.ontext=function(e){var t,n=this._options.normalizeWhitespace||this._options.ignoreWhitespace;!this._tagStack.length&&this.dom.length&&(t=this.dom[this.dom.length-1]).type===i.Text?n?t.data=(t.data+e).replace(a," "):t.data+=e:this._tagStack.length&&(t=this._tagStack[this._tagStack.length-1])&&(t=t.children[t.children.length-1])&&t.type===i.Text?n?t.data=(t.data+e).replace(a," "):t.data+=e:(n&&(e=e.replace(a," ")),this._addDomElement({data:e,type:i.Text}))},r.prototype.oncomment=function(e){var t=this._tagStack[this._tagStack.length-1];if(t&&t.type===i.Comment)return void(t.data+=e);var n={data:e,type:i.Comment};this._addDomElement(n),this._tagStack.push(n)},r.prototype.oncdatastart=function(){var e={children:[{data:"",type:i.Text}],type:i.CDATA};this._addDomElement(e),this._tagStack.push(e)},r.prototype.oncommentend=r.prototype.oncdataend=function(){this._tagStack.pop()},r.prototype.onprocessinginstruction=function(e,t){this._addDomElement({name:e,data:t,type:i.Directive})},t.exports=r},{"./lib/element":11,"./lib/node":12,domelementtype:9}],11:[function(e,t,n){var r=e("./node"),i=t.exports=Object.create(r),a={tagName:"name"};Object.keys(a).forEach(function(e){var t=a[e];Object.defineProperty(i,e,{get:function(){return this[t]||null},set:function(e){return this[t]=e,e}})})},{"./node":12}],12:[function(e,t,n){var r=t.exports={get firstChild(){var e=this.children;return e&&e[0]||null},get lastChild(){var e=this.children;return e&&e[e.length-1]||null},get nodeType(){return a[this.type]||a.element}},i={tagName:"name",childNodes:"children",parentNode:"parent",previousSibling:"prev",nextSibling:"next",nodeValue:"data"},a={element:1,text:3,cdata:4,comment:8};Object.keys(i).forEach(function(e){var t=i[e];Object.defineProperty(r,e,{get:function(){return this[t]||null},set:function(e){return this[t]=e,e}})})},{}],13:[function(e,t,n){var r=t.exports;[e("./lib/stringify"),e("./lib/traversal"),e("./lib/manipulation"),e("./lib/querying"),e("./lib/legacy"),e("./lib/helpers")].forEach(function(e){Object.keys(e).forEach(function(t){r[t]=e[t].bind(r)})})},{"./lib/helpers":14,"./lib/legacy":15,"./lib/manipulation":16,"./lib/querying":17,"./lib/stringify":18,"./lib/traversal":19}],14:[function(e,t,n){n.removeSubsets=function(e){for(var t,n,r,i=e.length;--i>-1;){for(t=n=e[i],e[i]=null,r=!0;n;){if(e.indexOf(n)>-1){r=!1,e.splice(i,1);break}n=n.parent}r&&(e[i]=t)}return e};var r={DISCONNECTED:1,PRECEDING:2,FOLLOWING:4,CONTAINS:8,CONTAINED_BY:16},i=n.compareDocumentPosition=function(e,t){var n,i,a,o,s,l,u=[],c=[];if(e===t)return 0;for(n=e;n;)u.unshift(n),n=n.parent;for(n=t;n;)c.unshift(n),n=n.parent;for(l=0;u[l]===c[l];)l++;return 0===l?r.DISCONNECTED:(i=u[l-1],a=i.children,o=u[l],s=c[l],a.indexOf(o)>a.indexOf(s)?i===t?r.FOLLOWING|r.CONTAINED_BY:r.FOLLOWING:i===e?r.PRECEDING|r.CONTAINS:r.PRECEDING)};n.uniqueSort=function(e){var t,n,a=e.length;for(e=e.slice();--a>-1;)t=e[a],n=e.indexOf(t),n>-1&&n<a&&e.splice(a,1);return e.sort(function(e,t){var n=i(e,t);return n&r.PRECEDING?-1:n&r.FOLLOWING?1:0}),e}},{}],15:[function(e,t,n){function r(e,t){return"function"==typeof t?function(n){return n.attribs&&t(n.attribs[e])}:function(n){return n.attribs&&n.attribs[e]===t}}function i(e,t){return function(n){return e(n)||t(n)}}var a=e("domelementtype"),o=n.isTag=a.isTag;n.testElement=function(e,t){for(var n in e)if(e.hasOwnProperty(n)){if("tag_name"===n){if(!o(t)||!e.tag_name(t.name))return!1}else if("tag_type"===n){if(!e.tag_type(t.type))return!1}else if("tag_contains"===n){if(o(t)||!e.tag_contains(t.data))return!1}else if(!t.attribs||!e[n](t.attribs[n]))return!1}else;return!0};var s={tag_name:function(e){return"function"==typeof e?function(t){return o(t)&&e(t.name)}:"*"===e?o:function(t){return o(t)&&t.name===e}},tag_type:function(e){return"function"==typeof e?function(t){return e(t.type)}:function(t){return t.type===e}},tag_contains:function(e){return"function"==typeof e?function(t){return!o(t)&&e(t.data)}:function(t){return!o(t)&&t.data===e}}};n.getElements=function(e,t,n,a){var o=Object.keys(e).map(function(t){var n=e[t];return t in s?s[t](n):r(t,n)});return 0===o.length?[]:this.filter(o.reduce(i),t,n,a)},n.getElementById=function(e,t,n){return Array.isArray(t)||(t=[t]),this.findOne(r("id",e),t,n!==!1)},n.getElementsByTagName=function(e,t,n,r){return this.filter(s.tag_name(e),t,n,r)},n.getElementsByTagType=function(e,t,n,r){return this.filter(s.tag_type(e),t,n,r)}},{domelementtype:9}],16:[function(e,t,n){n.removeElement=function(e){if(e.prev&&(e.prev.next=e.next),e.next&&(e.next.prev=e.prev),e.parent){var t=e.parent.children;t.splice(t.lastIndexOf(e),1)}},n.replaceElement=function(e,t){var n=t.prev=e.prev;n&&(n.next=t);var r=t.next=e.next;r&&(r.prev=t);var i=t.parent=e.parent;if(i){var a=i.children;a[a.lastIndexOf(e)]=t}},n.appendChild=function(e,t){if(t.parent=e,1!==e.children.push(t)){var n=e.children[e.children.length-2];n.next=t,t.prev=n,t.next=null}},n.append=function(e,t){var n=e.parent,r=e.next;if(t.next=r,t.prev=e,e.next=t,t.parent=n,r){if(r.prev=t,n){var i=n.children;i.splice(i.lastIndexOf(r),0,t)}}else n&&n.children.push(t)},n.prepend=function(e,t){var n=e.parent;if(n){var r=n.children;r.splice(r.lastIndexOf(e),0,t)}e.prev&&(e.prev.next=t),t.parent=n,t.prev=e.prev,t.next=e,e.prev=t}},{}],17:[function(e,t,n){function r(e,t,n,r){return Array.isArray(t)||(t=[t]),"number"==typeof r&&isFinite(r)||(r=1/0),i(e,t,n!==!1,r)}function i(e,t,n,r){for(var a,o=[],s=0,l=t.length;s<l&&!(e(t[s])&&(o.push(t[s]),--r<=0))&&(a=t[s].children,!(n&&a&&a.length>0&&(a=i(e,a,n,r),o=o.concat(a),r-=a.length,r<=0)));s++);return o}function a(e,t){for(var n=0,r=t.length;n<r;n++)if(e(t[n]))return t[n];return null}function o(e,t){for(var n=null,r=0,i=t.length;r<i&&!n;r++)u(t[r])&&(e(t[r])?n=t[r]:t[r].children.length>0&&(n=o(e,t[r].children)));return n}function s(e,t){for(var n=0,r=t.length;n<r;n++)if(u(t[n])&&(e(t[n])||t[n].children.length>0&&s(e,t[n].children)))return!0;return!1}function l(e,t){for(var n=[],r=0,i=t.length;r<i;r++)u(t[r])&&(e(t[r])&&n.push(t[r]),t[r].children.length>0&&(n=n.concat(l(e,t[r].children))));return n}var u=e("domelementtype").isTag;t.exports={filter:r,find:i,findOneChild:a,findOne:o,existsOne:s,findAll:l}},{domelementtype:9}],18:[function(e,t,n){function r(e,t){return e.children?e.children.map(function(e){return o(e,t)}).join(""):""}function i(e){return Array.isArray(e)?e.map(i).join(""):s(e)||e.type===a.CDATA?i(e.children):e.type===a.Text?e.data:""}var a=e("domelementtype"),o=e("dom-serializer"),s=a.isTag;t.exports={getInnerHTML:r,getOuterHTML:o,getText:i}},{"dom-serializer":7,domelementtype:9}],19:[function(e,t,n){var r=n.getChildren=function(e){return e.children},i=n.getParent=function(e){return e.parent};n.getSiblings=function(e){var t=i(e);return t?r(t):[e]},n.getAttributeValue=function(e,t){return e.attribs&&e.attribs[t]},n.hasAttrib=function(e,t){return!!e.attribs&&hasOwnProperty.call(e.attribs,t)},n.getName=function(e){return e.name}},{}],20:[function(e,t,n){var r=e("./lib/encode.js"),i=e("./lib/decode.js");n.decode=function(e,t){return(!t||t<=0?i.XML:i.HTML)(e)},n.decodeStrict=function(e,t){return(!t||t<=0?i.XML:i.HTMLStrict)(e)},n.encode=function(e,t){return(!t||t<=0?r.XML:r.HTML)(e)},n.encodeXML=r.XML,n.encodeHTML4=n.encodeHTML5=n.encodeHTML=r.HTML,n.decodeXML=n.decodeXMLStrict=i.XML,n.decodeHTML4=n.decodeHTML5=n.decodeHTML=i.HTML,n.decodeHTML4Strict=n.decodeHTML5Strict=n.decodeHTMLStrict=i.HTMLStrict,n.escape=r.escape},{"./lib/decode.js":21,"./lib/encode.js":23}],21:[function(e,t,n){function r(e){var t=Object.keys(e).join("|"),n=a(e);t+="|#[xX][\\da-fA-F]+|#\\d+";var r=new RegExp("&(?:"+t+");","g");return function(e){return String(e).replace(r,n)}}function i(e,t){return e<t?1:-1}function a(e){return function(t){return"#"===t.charAt(1)?u("X"===t.charAt(2)||"x"===t.charAt(2)?parseInt(t.substr(3),16):parseInt(t.substr(2),10)):e[t.slice(1,-1)]}}var o=e("../maps/entities.json"),s=e("../maps/legacy.json"),l=e("../maps/xml.json"),u=e("./decode_codepoint.js"),c=r(l),p=r(o),h=function(){function e(e){return";"!==e.substr(-1)&&(e+=";"),c(e)}for(var t=Object.keys(s).sort(i),n=Object.keys(o).sort(i),r=0,l=0;r<n.length;r++)t[l]===n[r]?(n[r]+=";?",l++):n[r]+=";";var u=new RegExp("&(?:"+n.join("|")+"|#[xX][\\da-fA-F]+;?|#\\d+;?)","g"),c=a(o);return function(t){return String(t).replace(u,e)}}();t.exports={XML:c,HTML:h,HTMLStrict:p}},{"../maps/entities.json":25,"../maps/legacy.json":26,"../maps/xml.json":27,"./decode_codepoint.js":22}],22:[function(e,t,n){function r(e){if(e>=55296&&e<=57343||e>1114111)return"�";e in i&&(e=i[e]);var t="";return e>65535&&(e-=65536,t+=String.fromCharCode(e>>>10&1023|55296),e=56320|1023&e),t+=String.fromCharCode(e)}var i=e("../maps/decode.json");t.exports=r},{"../maps/decode.json":24}],23:[function(e,t,n){function r(e){return Object.keys(e).sort().reduce(function(t,n){return t[e[n]]="&"+n+";",t},{})}function i(e){var t=[],n=[];return Object.keys(e).forEach(function(e){1===e.length?t.push("\\"+e):n.push(e)}),n.unshift("["+t.join("")+"]"),new RegExp(n.join("|"),"g")}function a(e){return"&#x"+e.charCodeAt(0).toString(16).toUpperCase()+";"}function o(e){var t=e.charCodeAt(0),n=e.charCodeAt(1),r=1024*(t-55296)+n-56320+65536;return"&#x"+r.toString(16).toUpperCase()+";"}function s(e,t){function n(t){return e[t]}return function(e){return e.replace(t,n).replace(d,o).replace(f,a)}}function l(e){return e.replace(m,a).replace(d,o).replace(f,a)}var u=r(e("../maps/xml.json")),c=i(u);n.XML=s(u,c);var p=r(e("../maps/entities.json")),h=i(p);n.HTML=s(p,h);var f=/[^\0-\x7F]/g,d=/[\uD800-\uDBFF][\uDC00-\uDFFF]/g,m=i(u);n.escape=l},{"../maps/entities.json":25,"../maps/xml.json":27}],24:[function(e,t,n){t.exports={0:65533,128:8364,130:8218,131:402,132:8222,133:8230,134:8224,135:8225,136:710,137:8240,138:352,139:8249,140:338,142:381,145:8216,146:8217,147:8220,148:8221,149:8226,150:8211,151:8212,152:732,153:8482,154:353,155:8250,156:339,158:382,159:376}},{}],25:[function(e,t,n){t.exports={Aacute:"Á",aacute:"á",Abreve:"Ă",abreve:"ă",ac:"∾",acd:"∿",acE:"∾̳",Acirc:"Â",acirc:"â",acute:"´",Acy:"А",acy:"а",AElig:"Æ",aelig:"æ",af:"⁡",Afr:"𝔄",afr:"𝔞",Agrave:"À",agrave:"à",alefsym:"ℵ",aleph:"ℵ",Alpha:"Α",alpha:"α",Amacr:"Ā",amacr:"ā",amalg:"⨿",amp:"&",AMP:"&",andand:"⩕",And:"⩓",and:"∧",andd:"⩜",andslope:"⩘",andv:"⩚",ang:"∠",ange:"⦤",angle:"∠",angmsdaa:"⦨",angmsdab:"⦩",angmsdac:"⦪",angmsdad:"⦫",angmsdae:"⦬",angmsdaf:"⦭",angmsdag:"⦮",angmsdah:"⦯",angmsd:"∡",angrt:"∟",angrtvb:"⊾",angrtvbd:"⦝",angsph:"∢",angst:"Å",angzarr:"⍼",Aogon:"Ą",aogon:"ą",Aopf:"𝔸",aopf:"𝕒",apacir:"⩯",ap:"≈",apE:"⩰",ape:"≊",apid:"≋",apos:"'",ApplyFunction:"⁡",approx:"≈",approxeq:"≊",Aring:"Å",aring:"å",Ascr:"𝒜",ascr:"𝒶",Assign:"≔",ast:"*",asymp:"≈",asympeq:"≍",Atilde:"Ã",atilde:"ã",Auml:"Ä",auml:"ä",awconint:"∳",awint:"⨑",backcong:"≌",backepsilon:"϶",backprime:"‵",backsim:"∽",backsimeq:"⋍",Backslash:"∖",Barv:"⫧",barvee:"⊽",barwed:"⌅",Barwed:"⌆",barwedge:"⌅",bbrk:"⎵",bbrktbrk:"⎶",bcong:"≌",Bcy:"Б",bcy:"б",bdquo:"„",becaus:"∵",because:"∵",Because:"∵",bemptyv:"⦰",bepsi:"϶",bernou:"ℬ",Bernoullis:"ℬ",Beta:"Β",beta:"β",beth:"ℶ",between:"≬",Bfr:"𝔅",bfr:"𝔟",bigcap:"⋂",bigcirc:"◯",bigcup:"⋃",bigodot:"⨀",bigoplus:"⨁",bigotimes:"⨂",bigsqcup:"⨆",bigstar:"★",bigtriangledown:"▽",bigtriangleup:"△",biguplus:"⨄",bigvee:"⋁",bigwedge:"⋀",bkarow:"⤍",blacklozenge:"⧫",blacksquare:"▪",blacktriangle:"▴",blacktriangledown:"▾",blacktriangleleft:"◂",blacktriangleright:"▸",blank:"␣",blk12:"▒",blk14:"░",blk34:"▓",block:"█",bne:"=⃥",bnequiv:"≡⃥",bNot:"⫭",bnot:"⌐",Bopf:"𝔹",bopf:"𝕓",bot:"⊥",bottom:"⊥",bowtie:"⋈",boxbox:"⧉",boxdl:"┐",boxdL:"╕",boxDl:"╖",boxDL:"╗",boxdr:"┌",boxdR:"╒",boxDr:"╓",boxDR:"╔",boxh:"─",boxH:"═",boxhd:"┬",boxHd:"╤",boxhD:"╥",boxHD:"╦",boxhu:"┴",boxHu:"╧",boxhU:"╨",boxHU:"╩",boxminus:"⊟",boxplus:"⊞",boxtimes:"⊠",boxul:"┘",boxuL:"╛",boxUl:"╜",boxUL:"╝",boxur:"└",boxuR:"╘",boxUr:"╙",boxUR:"╚",boxv:"│",boxV:"║",boxvh:"┼",boxvH:"╪",boxVh:"╫",boxVH:"╬",boxvl:"┤",boxvL:"╡",boxVl:"╢",boxVL:"╣",boxvr:"├",boxvR:"╞",boxVr:"╟",boxVR:"╠",bprime:"‵",breve:"˘",Breve:"˘",brvbar:"¦",bscr:"𝒷",Bscr:"ℬ",bsemi:"⁏",bsim:"∽",bsime:"⋍",bsolb:"⧅",bsol:"\\",bsolhsub:"⟈",bull:"•",bullet:"•",bump:"≎",bumpE:"⪮",bumpe:"≏",Bumpeq:"≎",bumpeq:"≏",Cacute:"Ć",cacute:"ć",capand:"⩄",capbrcup:"⩉",capcap:"⩋",cap:"∩",Cap:"⋒",capcup:"⩇",capdot:"⩀",CapitalDifferentialD:"ⅅ",caps:"∩︀",caret:"⁁",caron:"ˇ",Cayleys:"ℭ",ccaps:"⩍",Ccaron:"Č",ccaron:"č",Ccedil:"Ç",ccedil:"ç",Ccirc:"Ĉ",ccirc:"ĉ",Cconint:"∰",ccups:"⩌",ccupssm:"⩐",Cdot:"Ċ",cdot:"ċ",cedil:"¸",Cedilla:"¸",cemptyv:"⦲",cent:"¢",centerdot:"·",CenterDot:"·",cfr:"𝔠",Cfr:"ℭ",CHcy:"Ч",chcy:"ч",check:"✓",checkmark:"✓",Chi:"Χ",chi:"χ",circ:"ˆ",circeq:"≗",circlearrowleft:"↺",circlearrowright:"↻",circledast:"⊛",circledcirc:"⊚",circleddash:"⊝",CircleDot:"⊙",circledR:"®",circledS:"Ⓢ",CircleMinus:"⊖",CirclePlus:"⊕",CircleTimes:"⊗",cir:"○",cirE:"⧃",cire:"≗",cirfnint:"⨐",cirmid:"⫯",cirscir:"⧂",ClockwiseContourIntegral:"∲",CloseCurlyDoubleQuote:"”",CloseCurlyQuote:"’",clubs:"♣",clubsuit:"♣",colon:":",Colon:"∷",Colone:"⩴",colone:"≔",coloneq:"≔",comma:",",commat:"@",comp:"∁",compfn:"∘",complement:"∁",complexes:"ℂ",cong:"≅",congdot:"⩭",Congruent:"≡",conint:"∮",Conint:"∯",ContourIntegral:"∮",copf:"𝕔",Copf:"ℂ",coprod:"∐",Coproduct:"∐",copy:"©",COPY:"©",copysr:"℗",CounterClockwiseContourIntegral:"∳",crarr:"↵",cross:"✗",Cross:"⨯",Cscr:"𝒞",cscr:"𝒸",csub:"⫏",csube:"⫑",csup:"⫐",csupe:"⫒",ctdot:"⋯",cudarrl:"⤸",cudarrr:"⤵",cuepr:"⋞",cuesc:"⋟",cularr:"↶",cularrp:"⤽",cupbrcap:"⩈",cupcap:"⩆",CupCap:"≍",cup:"∪",Cup:"⋓",cupcup:"⩊",cupdot:"⊍",cupor:"⩅",cups:"∪︀",curarr:"↷",curarrm:"⤼",curlyeqprec:"⋞",curlyeqsucc:"⋟",curlyvee:"⋎",curlywedge:"⋏",curren:"¤",curvearrowleft:"↶",curvearrowright:"↷",cuvee:"⋎",cuwed:"⋏",cwconint:"∲",cwint:"∱",cylcty:"⌭",dagger:"†",Dagger:"‡",daleth:"ℸ",darr:"↓",Darr:"↡",dArr:"⇓",dash:"‐",Dashv:"⫤",dashv:"⊣",dbkarow:"⤏",dblac:"˝",Dcaron:"Ď",dcaron:"ď",Dcy:"Д",dcy:"д",ddagger:"‡",ddarr:"⇊",DD:"ⅅ",dd:"ⅆ",DDotrahd:"⤑",ddotseq:"⩷",deg:"°",Del:"∇",Delta:"Δ",delta:"δ",demptyv:"⦱",dfisht:"⥿",Dfr:"𝔇",dfr:"𝔡",dHar:"⥥",dharl:"⇃",dharr:"⇂",DiacriticalAcute:"´",DiacriticalDot:"˙",DiacriticalDoubleAcute:"˝",DiacriticalGrave:"`",DiacriticalTilde:"˜",diam:"⋄",diamond:"⋄",Diamond:"⋄",diamondsuit:"♦",diams:"♦",die:"¨",DifferentialD:"ⅆ",digamma:"ϝ",disin:"⋲",div:"÷",divide:"÷",divideontimes:"⋇",divonx:"⋇",DJcy:"Ђ",djcy:"ђ",dlcorn:"⌞",dlcrop:"⌍",dollar:"$",Dopf:"𝔻",dopf:"𝕕",Dot:"¨",dot:"˙",DotDot:"⃜",doteq:"≐",doteqdot:"≑",DotEqual:"≐",dotminus:"∸",dotplus:"∔",dotsquare:"⊡",doublebarwedge:"⌆",DoubleContourIntegral:"∯",DoubleDot:"¨",DoubleDownArrow:"⇓",DoubleLeftArrow:"⇐",DoubleLeftRightArrow:"⇔",DoubleLeftTee:"⫤",DoubleLongLeftArrow:"⟸",DoubleLongLeftRightArrow:"⟺",DoubleLongRightArrow:"⟹",DoubleRightArrow:"⇒",DoubleRightTee:"⊨",DoubleUpArrow:"⇑",DoubleUpDownArrow:"⇕",DoubleVerticalBar:"∥",DownArrowBar:"⤓",downarrow:"↓",DownArrow:"↓",Downarrow:"⇓",DownArrowUpArrow:"⇵",DownBreve:"̑",downdownarrows:"⇊",downharpoonleft:"⇃",downharpoonright:"⇂",DownLeftRightVector:"⥐",DownLeftTeeVector:"⥞",DownLeftVectorBar:"⥖",DownLeftVector:"↽",DownRightTeeVector:"⥟",DownRightVectorBar:"⥗",DownRightVector:"⇁",DownTeeArrow:"↧",DownTee:"⊤",drbkarow:"⤐",drcorn:"⌟",drcrop:"⌌",Dscr:"𝒟",dscr:"𝒹",DScy:"Ѕ",dscy:"ѕ",dsol:"⧶",Dstrok:"Đ",dstrok:"đ",dtdot:"⋱",dtri:"▿",dtrif:"▾",duarr:"⇵",duhar:"⥯",dwangle:"⦦",DZcy:"Џ",dzcy:"џ",dzigrarr:"⟿",Eacute:"É",eacute:"é",easter:"⩮",Ecaron:"Ě",ecaron:"ě",Ecirc:"Ê",ecirc:"ê",ecir:"≖",ecolon:"≕",Ecy:"Э",ecy:"э",eDDot:"⩷",Edot:"Ė",edot:"ė",eDot:"≑",ee:"ⅇ",efDot:"≒",Efr:"𝔈",efr:"𝔢",eg:"⪚",Egrave:"È",egrave:"è",egs:"⪖",egsdot:"⪘",el:"⪙",Element:"∈",elinters:"⏧",ell:"ℓ",els:"⪕",elsdot:"⪗",Emacr:"Ē",emacr:"ē",empty:"∅",emptyset:"∅",EmptySmallSquare:"◻",emptyv:"∅",EmptyVerySmallSquare:"▫",emsp13:" ",emsp14:" ",emsp:" ",ENG:"Ŋ",eng:"ŋ",ensp:" ",Eogon:"Ę",eogon:"ę",Eopf:"𝔼",eopf:"𝕖",epar:"⋕",eparsl:"⧣",eplus:"⩱",epsi:"ε",Epsilon:"Ε",epsilon:"ε",epsiv:"ϵ",eqcirc:"≖",eqcolon:"≕",eqsim:"≂",eqslantgtr:"⪖",eqslantless:"⪕",Equal:"⩵",equals:"=",EqualTilde:"≂",equest:"≟",Equilibrium:"⇌",equiv:"≡",equivDD:"⩸",eqvparsl:"⧥",erarr:"⥱",erDot:"≓",escr:"ℯ",Escr:"ℰ",esdot:"≐",Esim:"⩳",esim:"≂",Eta:"Η",eta:"η",ETH:"Ð",eth:"ð",Euml:"Ë",euml:"ë",euro:"€",excl:"!",exist:"∃",Exists:"∃",expectation:"ℰ",exponentiale:"ⅇ",ExponentialE:"ⅇ",fallingdotseq:"≒",Fcy:"Ф",fcy:"ф",female:"♀",ffilig:"ffi",fflig:"ff",ffllig:"ffl",Ffr:"𝔉",ffr:"𝔣",filig:"fi",FilledSmallSquare:"◼",FilledVerySmallSquare:"▪",fjlig:"fj",flat:"♭",fllig:"fl",fltns:"▱",fnof:"ƒ",Fopf:"𝔽",fopf:"𝕗",forall:"∀",ForAll:"∀",fork:"⋔",forkv:"⫙",Fouriertrf:"ℱ",fpartint:"⨍",frac12:"½",frac13:"⅓",frac14:"¼",frac15:"⅕",frac16:"⅙",frac18:"⅛",frac23:"⅔",frac25:"⅖",frac34:"¾",frac35:"⅗",frac38:"⅜",frac45:"⅘",frac56:"⅚",frac58:"⅝",frac78:"⅞",frasl:"⁄",frown:"⌢",fscr:"𝒻",Fscr:"ℱ",gacute:"ǵ",Gamma:"Γ",gamma:"γ",Gammad:"Ϝ",gammad:"ϝ",gap:"⪆",Gbreve:"Ğ",gbreve:"ğ",Gcedil:"Ģ",Gcirc:"Ĝ",gcirc:"ĝ",Gcy:"Г",gcy:"г",Gdot:"Ġ",gdot:"ġ",ge:"≥",gE:"≧",gEl:"⪌",gel:"⋛",geq:"≥",geqq:"≧",geqslant:"⩾",gescc:"⪩",ges:"⩾",gesdot:"⪀",gesdoto:"⪂",gesdotol:"⪄",gesl:"⋛︀",gesles:"⪔",Gfr:"𝔊",gfr:"𝔤",gg:"≫",Gg:"⋙",ggg:"⋙",gimel:"ℷ",GJcy:"Ѓ",gjcy:"ѓ",gla:"⪥",gl:"≷",glE:"⪒",glj:"⪤",gnap:"⪊",gnapprox:"⪊",gne:"⪈",gnE:"≩",gneq:"⪈",gneqq:"≩",gnsim:"⋧",Gopf:"𝔾",gopf:"𝕘",grave:"`",GreaterEqual:"≥",GreaterEqualLess:"⋛",GreaterFullEqual:"≧",GreaterGreater:"⪢",GreaterLess:"≷",GreaterSlantEqual:"⩾",GreaterTilde:"≳",Gscr:"𝒢",gscr:"ℊ",gsim:"≳",gsime:"⪎",gsiml:"⪐",gtcc:"⪧",gtcir:"⩺",gt:">",GT:">",Gt:"≫",gtdot:"⋗",gtlPar:"⦕",gtquest:"⩼",gtrapprox:"⪆",gtrarr:"⥸",gtrdot:"⋗",gtreqless:"⋛",gtreqqless:"⪌",gtrless:"≷",gtrsim:"≳",gvertneqq:"≩︀",gvnE:"≩︀",Hacek:"ˇ",hairsp:" ",half:"½",hamilt:"ℋ",HARDcy:"Ъ",hardcy:"ъ",harrcir:"⥈",harr:"↔",hArr:"⇔",harrw:"↭",Hat:"^",hbar:"ℏ",Hcirc:"Ĥ",hcirc:"ĥ",hearts:"♥",heartsuit:"♥",hellip:"…",hercon:"⊹",hfr:"𝔥",Hfr:"ℌ",HilbertSpace:"ℋ",hksearow:"⤥",hkswarow:"⤦",hoarr:"⇿",homtht:"∻",hookleftarrow:"↩",hookrightarrow:"↪",hopf:"𝕙",Hopf:"ℍ",horbar:"―",HorizontalLine:"─",hscr:"𝒽",Hscr:"ℋ",hslash:"ℏ",Hstrok:"Ħ",hstrok:"ħ",HumpDownHump:"≎",HumpEqual:"≏",hybull:"⁃",hyphen:"‐",Iacute:"Í",iacute:"í",ic:"⁣",Icirc:"Î",icirc:"î",Icy:"И",icy:"и",Idot:"İ",IEcy:"Е",iecy:"е",iexcl:"¡",iff:"⇔",ifr:"𝔦",Ifr:"ℑ",Igrave:"Ì",igrave:"ì",ii:"ⅈ",iiiint:"⨌",iiint:"∭",iinfin:"⧜",iiota:"℩",IJlig:"IJ",ijlig:"ij",Imacr:"Ī",imacr:"ī",image:"ℑ",ImaginaryI:"ⅈ",imagline:"ℐ",imagpart:"ℑ",imath:"ı",Im:"ℑ",imof:"⊷",imped:"Ƶ",Implies:"⇒",incare:"℅","in":"∈",infin:"∞",infintie:"⧝",inodot:"ı",intcal:"⊺","int":"∫",Int:"∬",integers:"ℤ",Integral:"∫",intercal:"⊺",Intersection:"⋂",intlarhk:"⨗",intprod:"⨼",InvisibleComma:"⁣",InvisibleTimes:"⁢",IOcy:"Ё",iocy:"ё",Iogon:"Į",iogon:"į",Iopf:"𝕀",iopf:"𝕚",Iota:"Ι",iota:"ι",iprod:"⨼",iquest:"¿",iscr:"𝒾",Iscr:"ℐ",isin:"∈",isindot:"⋵",isinE:"⋹",isins:"⋴",isinsv:"⋳",isinv:"∈",it:"⁢",Itilde:"Ĩ",itilde:"ĩ",Iukcy:"І",iukcy:"і",Iuml:"Ï",iuml:"ï",Jcirc:"Ĵ",jcirc:"ĵ",Jcy:"Й",jcy:"й",Jfr:"𝔍",jfr:"𝔧",jmath:"ȷ",Jopf:"𝕁",jopf:"𝕛",Jscr:"𝒥",jscr:"𝒿",Jsercy:"Ј",jsercy:"ј",Jukcy:"Є",jukcy:"є",Kappa:"Κ",kappa:"κ",kappav:"ϰ",Kcedil:"Ķ",kcedil:"ķ",Kcy:"К",kcy:"к",Kfr:"𝔎",kfr:"𝔨",kgreen:"ĸ",KHcy:"Х",khcy:"х",KJcy:"Ќ",kjcy:"ќ",Kopf:"𝕂",kopf:"𝕜",Kscr:"𝒦",kscr:"𝓀",lAarr:"⇚",Lacute:"Ĺ",lacute:"ĺ",laemptyv:"⦴",lagran:"ℒ",Lambda:"Λ",lambda:"λ",lang:"⟨",Lang:"⟪",langd:"⦑",langle:"⟨",lap:"⪅",Laplacetrf:"ℒ",laquo:"«",larrb:"⇤",larrbfs:"⤟",larr:"←",Larr:"↞",lArr:"⇐",larrfs:"⤝",larrhk:"↩",larrlp:"↫",larrpl:"⤹",larrsim:"⥳",larrtl:"↢",latail:"⤙",lAtail:"⤛",lat:"⪫",late:"⪭",lates:"⪭︀",lbarr:"⤌",lBarr:"⤎",lbbrk:"❲",lbrace:"{",lbrack:"[",lbrke:"⦋",lbrksld:"⦏",lbrkslu:"⦍",Lcaron:"Ľ",lcaron:"ľ",Lcedil:"Ļ",lcedil:"ļ",lceil:"⌈",lcub:"{",Lcy:"Л",lcy:"л",ldca:"⤶",ldquo:"“",ldquor:"„",ldrdhar:"⥧",ldrushar:"⥋",ldsh:"↲",le:"≤",lE:"≦",LeftAngleBracket:"⟨",LeftArrowBar:"⇤",leftarrow:"←",LeftArrow:"←",Leftarrow:"⇐",LeftArrowRightArrow:"⇆",leftarrowtail:"↢",LeftCeiling:"⌈",LeftDoubleBracket:"⟦",LeftDownTeeVector:"⥡",LeftDownVectorBar:"⥙",LeftDownVector:"⇃",LeftFloor:"⌊",leftharpoondown:"↽",leftharpoonup:"↼",leftleftarrows:"⇇",leftrightarrow:"↔",LeftRightArrow:"↔",Leftrightarrow:"⇔",leftrightarrows:"⇆",leftrightharpoons:"⇋",leftrightsquigarrow:"↭",LeftRightVector:"⥎",LeftTeeArrow:"↤",LeftTee:"⊣",LeftTeeVector:"⥚",leftthreetimes:"⋋",LeftTriangleBar:"⧏",LeftTriangle:"⊲",LeftTriangleEqual:"⊴",LeftUpDownVector:"⥑",LeftUpTeeVector:"⥠",LeftUpVectorBar:"⥘",LeftUpVector:"↿",LeftVectorBar:"⥒",LeftVector:"↼",lEg:"⪋",leg:"⋚",leq:"≤",leqq:"≦",leqslant:"⩽",lescc:"⪨",les:"⩽",lesdot:"⩿",lesdoto:"⪁",lesdotor:"⪃",lesg:"⋚︀",lesges:"⪓",lessapprox:"⪅",lessdot:"⋖",lesseqgtr:"⋚",lesseqqgtr:"⪋",LessEqualGreater:"⋚",LessFullEqual:"≦",LessGreater:"≶",lessgtr:"≶",LessLess:"⪡",lesssim:"≲",LessSlantEqual:"⩽",LessTilde:"≲",lfisht:"⥼",lfloor:"⌊",Lfr:"𝔏",lfr:"𝔩",lg:"≶",lgE:"⪑",lHar:"⥢",lhard:"↽",lharu:"↼",lharul:"⥪",lhblk:"▄",LJcy:"Љ",ljcy:"љ",llarr:"⇇",ll:"≪",Ll:"⋘",llcorner:"⌞",Lleftarrow:"⇚",llhard:"⥫",lltri:"◺",Lmidot:"Ŀ",lmidot:"ŀ",lmoustache:"⎰",lmoust:"⎰",lnap:"⪉",lnapprox:"⪉",lne:"⪇",lnE:"≨",lneq:"⪇",lneqq:"≨",lnsim:"⋦",loang:"⟬",loarr:"⇽",lobrk:"⟦",longleftarrow:"⟵",LongLeftArrow:"⟵",Longleftarrow:"⟸",longleftrightarrow:"⟷",LongLeftRightArrow:"⟷",Longleftrightarrow:"⟺",longmapsto:"⟼",longrightarrow:"⟶",LongRightArrow:"⟶",Longrightarrow:"⟹",looparrowleft:"↫",looparrowright:"↬",lopar:"⦅",Lopf:"𝕃",lopf:"𝕝",loplus:"⨭",lotimes:"⨴",lowast:"∗",lowbar:"_",LowerLeftArrow:"↙",LowerRightArrow:"↘",loz:"◊",lozenge:"◊",lozf:"⧫",lpar:"(",lparlt:"⦓",lrarr:"⇆",lrcorner:"⌟",lrhar:"⇋",lrhard:"⥭",lrm:"‎",lrtri:"⊿",lsaquo:"‹",lscr:"𝓁",Lscr:"ℒ",lsh:"↰",Lsh:"↰",lsim:"≲",lsime:"⪍",lsimg:"⪏",lsqb:"[",lsquo:"‘",lsquor:"‚",Lstrok:"Ł",lstrok:"ł",ltcc:"⪦",ltcir:"⩹",lt:"<",LT:"<",Lt:"≪",ltdot:"⋖",lthree:"⋋",ltimes:"⋉",ltlarr:"⥶",ltquest:"⩻",ltri:"◃",ltrie:"⊴",ltrif:"◂",ltrPar:"⦖",lurdshar:"⥊",luruhar:"⥦",lvertneqq:"≨︀",lvnE:"≨︀",macr:"¯",male:"♂",malt:"✠",maltese:"✠",Map:"⤅",map:"↦",mapsto:"↦",mapstodown:"↧",mapstoleft:"↤",mapstoup:"↥",marker:"▮",mcomma:"⨩",Mcy:"М",mcy:"м",mdash:"—",mDDot:"∺",measuredangle:"∡",MediumSpace:" ",Mellintrf:"ℳ",Mfr:"𝔐",mfr:"𝔪",mho:"℧",micro:"µ",midast:"*",midcir:"⫰",mid:"∣",middot:"·",minusb:"⊟",minus:"−",minusd:"∸",minusdu:"⨪",MinusPlus:"∓",mlcp:"⫛",mldr:"…",mnplus:"∓",models:"⊧",Mopf:"𝕄",mopf:"𝕞",mp:"∓",mscr:"𝓂",Mscr:"ℳ",mstpos:"∾",Mu:"Μ",mu:"μ",multimap:"⊸",mumap:"⊸",nabla:"∇",Nacute:"Ń",nacute:"ń",nang:"∠⃒",nap:"≉",napE:"⩰̸",napid:"≋̸",napos:"ʼn",napprox:"≉",natural:"♮",naturals:"ℕ",natur:"♮",nbsp:" ",nbump:"≎̸",nbumpe:"≏̸",ncap:"⩃",Ncaron:"Ň",ncaron:"ň",Ncedil:"Ņ",ncedil:"ņ",ncong:"≇",ncongdot:"⩭̸",ncup:"⩂",Ncy:"Н",ncy:"н",ndash:"–",nearhk:"⤤",nearr:"↗",neArr:"⇗",nearrow:"↗",ne:"≠",nedot:"≐̸",NegativeMediumSpace:"​",NegativeThickSpace:"​",NegativeThinSpace:"​",NegativeVeryThinSpace:"​",nequiv:"≢",nesear:"⤨",nesim:"≂̸",NestedGreaterGreater:"≫",NestedLessLess:"≪",NewLine:"\n",nexist:"∄",nexists:"∄",Nfr:"𝔑",nfr:"𝔫",ngE:"≧̸",nge:"≱",ngeq:"≱",ngeqq:"≧̸",ngeqslant:"⩾̸",nges:"⩾̸",nGg:"⋙̸",ngsim:"≵",nGt:"≫⃒",ngt:"≯",ngtr:"≯",nGtv:"≫̸",nharr:"↮",nhArr:"⇎",nhpar:"⫲",ni:"∋",nis:"⋼",nisd:"⋺",niv:"∋",NJcy:"Њ",njcy:"њ",nlarr:"↚",nlArr:"⇍",nldr:"‥",
-nlE:"≦̸",nle:"≰",nleftarrow:"↚",nLeftarrow:"⇍",nleftrightarrow:"↮",nLeftrightarrow:"⇎",nleq:"≰",nleqq:"≦̸",nleqslant:"⩽̸",nles:"⩽̸",nless:"≮",nLl:"⋘̸",nlsim:"≴",nLt:"≪⃒",nlt:"≮",nltri:"⋪",nltrie:"⋬",nLtv:"≪̸",nmid:"∤",NoBreak:"⁠",NonBreakingSpace:" ",nopf:"𝕟",Nopf:"ℕ",Not:"⫬",not:"¬",NotCongruent:"≢",NotCupCap:"≭",NotDoubleVerticalBar:"∦",NotElement:"∉",NotEqual:"≠",NotEqualTilde:"≂̸",NotExists:"∄",NotGreater:"≯",NotGreaterEqual:"≱",NotGreaterFullEqual:"≧̸",NotGreaterGreater:"≫̸",NotGreaterLess:"≹",NotGreaterSlantEqual:"⩾̸",NotGreaterTilde:"≵",NotHumpDownHump:"≎̸",NotHumpEqual:"≏̸",notin:"∉",notindot:"⋵̸",notinE:"⋹̸",notinva:"∉",notinvb:"⋷",notinvc:"⋶",NotLeftTriangleBar:"⧏̸",NotLeftTriangle:"⋪",NotLeftTriangleEqual:"⋬",NotLess:"≮",NotLessEqual:"≰",NotLessGreater:"≸",NotLessLess:"≪̸",NotLessSlantEqual:"⩽̸",NotLessTilde:"≴",NotNestedGreaterGreater:"⪢̸",NotNestedLessLess:"⪡̸",notni:"∌",notniva:"∌",notnivb:"⋾",notnivc:"⋽",NotPrecedes:"⊀",NotPrecedesEqual:"⪯̸",NotPrecedesSlantEqual:"⋠",NotReverseElement:"∌",NotRightTriangleBar:"⧐̸",NotRightTriangle:"⋫",NotRightTriangleEqual:"⋭",NotSquareSubset:"⊏̸",NotSquareSubsetEqual:"⋢",NotSquareSuperset:"⊐̸",NotSquareSupersetEqual:"⋣",NotSubset:"⊂⃒",NotSubsetEqual:"⊈",NotSucceeds:"⊁",NotSucceedsEqual:"⪰̸",NotSucceedsSlantEqual:"⋡",NotSucceedsTilde:"≿̸",NotSuperset:"⊃⃒",NotSupersetEqual:"⊉",NotTilde:"≁",NotTildeEqual:"≄",NotTildeFullEqual:"≇",NotTildeTilde:"≉",NotVerticalBar:"∤",nparallel:"∦",npar:"∦",nparsl:"⫽⃥",npart:"∂̸",npolint:"⨔",npr:"⊀",nprcue:"⋠",nprec:"⊀",npreceq:"⪯̸",npre:"⪯̸",nrarrc:"⤳̸",nrarr:"↛",nrArr:"⇏",nrarrw:"↝̸",nrightarrow:"↛",nRightarrow:"⇏",nrtri:"⋫",nrtrie:"⋭",nsc:"⊁",nsccue:"⋡",nsce:"⪰̸",Nscr:"𝒩",nscr:"𝓃",nshortmid:"∤",nshortparallel:"∦",nsim:"≁",nsime:"≄",nsimeq:"≄",nsmid:"∤",nspar:"∦",nsqsube:"⋢",nsqsupe:"⋣",nsub:"⊄",nsubE:"⫅̸",nsube:"⊈",nsubset:"⊂⃒",nsubseteq:"⊈",nsubseteqq:"⫅̸",nsucc:"⊁",nsucceq:"⪰̸",nsup:"⊅",nsupE:"⫆̸",nsupe:"⊉",nsupset:"⊃⃒",nsupseteq:"⊉",nsupseteqq:"⫆̸",ntgl:"≹",Ntilde:"Ñ",ntilde:"ñ",ntlg:"≸",ntriangleleft:"⋪",ntrianglelefteq:"⋬",ntriangleright:"⋫",ntrianglerighteq:"⋭",Nu:"Ν",nu:"ν",num:"#",numero:"№",numsp:" ",nvap:"≍⃒",nvdash:"⊬",nvDash:"⊭",nVdash:"⊮",nVDash:"⊯",nvge:"≥⃒",nvgt:">⃒",nvHarr:"⤄",nvinfin:"⧞",nvlArr:"⤂",nvle:"≤⃒",nvlt:"<⃒",nvltrie:"⊴⃒",nvrArr:"⤃",nvrtrie:"⊵⃒",nvsim:"∼⃒",nwarhk:"⤣",nwarr:"↖",nwArr:"⇖",nwarrow:"↖",nwnear:"⤧",Oacute:"Ó",oacute:"ó",oast:"⊛",Ocirc:"Ô",ocirc:"ô",ocir:"⊚",Ocy:"О",ocy:"о",odash:"⊝",Odblac:"Ő",odblac:"ő",odiv:"⨸",odot:"⊙",odsold:"⦼",OElig:"Œ",oelig:"œ",ofcir:"⦿",Ofr:"𝔒",ofr:"𝔬",ogon:"˛",Ograve:"Ò",ograve:"ò",ogt:"⧁",ohbar:"⦵",ohm:"Ω",oint:"∮",olarr:"↺",olcir:"⦾",olcross:"⦻",oline:"‾",olt:"⧀",Omacr:"Ō",omacr:"ō",Omega:"Ω",omega:"ω",Omicron:"Ο",omicron:"ο",omid:"⦶",ominus:"⊖",Oopf:"𝕆",oopf:"𝕠",opar:"⦷",OpenCurlyDoubleQuote:"“",OpenCurlyQuote:"‘",operp:"⦹",oplus:"⊕",orarr:"↻",Or:"⩔",or:"∨",ord:"⩝",order:"ℴ",orderof:"ℴ",ordf:"ª",ordm:"º",origof:"⊶",oror:"⩖",orslope:"⩗",orv:"⩛",oS:"Ⓢ",Oscr:"𝒪",oscr:"ℴ",Oslash:"Ø",oslash:"ø",osol:"⊘",Otilde:"Õ",otilde:"õ",otimesas:"⨶",Otimes:"⨷",otimes:"⊗",Ouml:"Ö",ouml:"ö",ovbar:"⌽",OverBar:"‾",OverBrace:"⏞",OverBracket:"⎴",OverParenthesis:"⏜",para:"¶",parallel:"∥",par:"∥",parsim:"⫳",parsl:"⫽",part:"∂",PartialD:"∂",Pcy:"П",pcy:"п",percnt:"%",period:".",permil:"‰",perp:"⊥",pertenk:"‱",Pfr:"𝔓",pfr:"𝔭",Phi:"Φ",phi:"φ",phiv:"ϕ",phmmat:"ℳ",phone:"☎",Pi:"Π",pi:"π",pitchfork:"⋔",piv:"ϖ",planck:"ℏ",planckh:"ℎ",plankv:"ℏ",plusacir:"⨣",plusb:"⊞",pluscir:"⨢",plus:"+",plusdo:"∔",plusdu:"⨥",pluse:"⩲",PlusMinus:"±",plusmn:"±",plussim:"⨦",plustwo:"⨧",pm:"±",Poincareplane:"ℌ",pointint:"⨕",popf:"𝕡",Popf:"ℙ",pound:"£",prap:"⪷",Pr:"⪻",pr:"≺",prcue:"≼",precapprox:"⪷",prec:"≺",preccurlyeq:"≼",Precedes:"≺",PrecedesEqual:"⪯",PrecedesSlantEqual:"≼",PrecedesTilde:"≾",preceq:"⪯",precnapprox:"⪹",precneqq:"⪵",precnsim:"⋨",pre:"⪯",prE:"⪳",precsim:"≾",prime:"′",Prime:"″",primes:"ℙ",prnap:"⪹",prnE:"⪵",prnsim:"⋨",prod:"∏",Product:"∏",profalar:"⌮",profline:"⌒",profsurf:"⌓",prop:"∝",Proportional:"∝",Proportion:"∷",propto:"∝",prsim:"≾",prurel:"⊰",Pscr:"𝒫",pscr:"𝓅",Psi:"Ψ",psi:"ψ",puncsp:" ",Qfr:"𝔔",qfr:"𝔮",qint:"⨌",qopf:"𝕢",Qopf:"ℚ",qprime:"⁗",Qscr:"𝒬",qscr:"𝓆",quaternions:"ℍ",quatint:"⨖",quest:"?",questeq:"≟",quot:'"',QUOT:'"',rAarr:"⇛",race:"∽̱",Racute:"Ŕ",racute:"ŕ",radic:"√",raemptyv:"⦳",rang:"⟩",Rang:"⟫",rangd:"⦒",range:"⦥",rangle:"⟩",raquo:"»",rarrap:"⥵",rarrb:"⇥",rarrbfs:"⤠",rarrc:"⤳",rarr:"→",Rarr:"↠",rArr:"⇒",rarrfs:"⤞",rarrhk:"↪",rarrlp:"↬",rarrpl:"⥅",rarrsim:"⥴",Rarrtl:"⤖",rarrtl:"↣",rarrw:"↝",ratail:"⤚",rAtail:"⤜",ratio:"∶",rationals:"ℚ",rbarr:"⤍",rBarr:"⤏",RBarr:"⤐",rbbrk:"❳",rbrace:"}",rbrack:"]",rbrke:"⦌",rbrksld:"⦎",rbrkslu:"⦐",Rcaron:"Ř",rcaron:"ř",Rcedil:"Ŗ",rcedil:"ŗ",rceil:"⌉",rcub:"}",Rcy:"Р",rcy:"р",rdca:"⤷",rdldhar:"⥩",rdquo:"”",rdquor:"”",rdsh:"↳",real:"ℜ",realine:"ℛ",realpart:"ℜ",reals:"ℝ",Re:"ℜ",rect:"▭",reg:"®",REG:"®",ReverseElement:"∋",ReverseEquilibrium:"⇋",ReverseUpEquilibrium:"⥯",rfisht:"⥽",rfloor:"⌋",rfr:"𝔯",Rfr:"ℜ",rHar:"⥤",rhard:"⇁",rharu:"⇀",rharul:"⥬",Rho:"Ρ",rho:"ρ",rhov:"ϱ",RightAngleBracket:"⟩",RightArrowBar:"⇥",rightarrow:"→",RightArrow:"→",Rightarrow:"⇒",RightArrowLeftArrow:"⇄",rightarrowtail:"↣",RightCeiling:"⌉",RightDoubleBracket:"⟧",RightDownTeeVector:"⥝",RightDownVectorBar:"⥕",RightDownVector:"⇂",RightFloor:"⌋",rightharpoondown:"⇁",rightharpoonup:"⇀",rightleftarrows:"⇄",rightleftharpoons:"⇌",rightrightarrows:"⇉",rightsquigarrow:"↝",RightTeeArrow:"↦",RightTee:"⊢",RightTeeVector:"⥛",rightthreetimes:"⋌",RightTriangleBar:"⧐",RightTriangle:"⊳",RightTriangleEqual:"⊵",RightUpDownVector:"⥏",RightUpTeeVector:"⥜",RightUpVectorBar:"⥔",RightUpVector:"↾",RightVectorBar:"⥓",RightVector:"⇀",ring:"˚",risingdotseq:"≓",rlarr:"⇄",rlhar:"⇌",rlm:"‏",rmoustache:"⎱",rmoust:"⎱",rnmid:"⫮",roang:"⟭",roarr:"⇾",robrk:"⟧",ropar:"⦆",ropf:"𝕣",Ropf:"ℝ",roplus:"⨮",rotimes:"⨵",RoundImplies:"⥰",rpar:")",rpargt:"⦔",rppolint:"⨒",rrarr:"⇉",Rrightarrow:"⇛",rsaquo:"›",rscr:"𝓇",Rscr:"ℛ",rsh:"↱",Rsh:"↱",rsqb:"]",rsquo:"’",rsquor:"’",rthree:"⋌",rtimes:"⋊",rtri:"▹",rtrie:"⊵",rtrif:"▸",rtriltri:"⧎",RuleDelayed:"⧴",ruluhar:"⥨",rx:"℞",Sacute:"Ś",sacute:"ś",sbquo:"‚",scap:"⪸",Scaron:"Š",scaron:"š",Sc:"⪼",sc:"≻",sccue:"≽",sce:"⪰",scE:"⪴",Scedil:"Ş",scedil:"ş",Scirc:"Ŝ",scirc:"ŝ",scnap:"⪺",scnE:"⪶",scnsim:"⋩",scpolint:"⨓",scsim:"≿",Scy:"С",scy:"с",sdotb:"⊡",sdot:"⋅",sdote:"⩦",searhk:"⤥",searr:"↘",seArr:"⇘",searrow:"↘",sect:"§",semi:";",seswar:"⤩",setminus:"∖",setmn:"∖",sext:"✶",Sfr:"𝔖",sfr:"𝔰",sfrown:"⌢",sharp:"♯",SHCHcy:"Щ",shchcy:"щ",SHcy:"Ш",shcy:"ш",ShortDownArrow:"↓",ShortLeftArrow:"←",shortmid:"∣",shortparallel:"∥",ShortRightArrow:"→",ShortUpArrow:"↑",shy:"­",Sigma:"Σ",sigma:"σ",sigmaf:"ς",sigmav:"ς",sim:"∼",simdot:"⩪",sime:"≃",simeq:"≃",simg:"⪞",simgE:"⪠",siml:"⪝",simlE:"⪟",simne:"≆",simplus:"⨤",simrarr:"⥲",slarr:"←",SmallCircle:"∘",smallsetminus:"∖",smashp:"⨳",smeparsl:"⧤",smid:"∣",smile:"⌣",smt:"⪪",smte:"⪬",smtes:"⪬︀",SOFTcy:"Ь",softcy:"ь",solbar:"⌿",solb:"⧄",sol:"/",Sopf:"𝕊",sopf:"𝕤",spades:"♠",spadesuit:"♠",spar:"∥",sqcap:"⊓",sqcaps:"⊓︀",sqcup:"⊔",sqcups:"⊔︀",Sqrt:"√",sqsub:"⊏",sqsube:"⊑",sqsubset:"⊏",sqsubseteq:"⊑",sqsup:"⊐",sqsupe:"⊒",sqsupset:"⊐",sqsupseteq:"⊒",square:"□",Square:"□",SquareIntersection:"⊓",SquareSubset:"⊏",SquareSubsetEqual:"⊑",SquareSuperset:"⊐",SquareSupersetEqual:"⊒",SquareUnion:"⊔",squarf:"▪",squ:"□",squf:"▪",srarr:"→",Sscr:"𝒮",sscr:"𝓈",ssetmn:"∖",ssmile:"⌣",sstarf:"⋆",Star:"⋆",star:"☆",starf:"★",straightepsilon:"ϵ",straightphi:"ϕ",strns:"¯",sub:"⊂",Sub:"⋐",subdot:"⪽",subE:"⫅",sube:"⊆",subedot:"⫃",submult:"⫁",subnE:"⫋",subne:"⊊",subplus:"⪿",subrarr:"⥹",subset:"⊂",Subset:"⋐",subseteq:"⊆",subseteqq:"⫅",SubsetEqual:"⊆",subsetneq:"⊊",subsetneqq:"⫋",subsim:"⫇",subsub:"⫕",subsup:"⫓",succapprox:"⪸",succ:"≻",succcurlyeq:"≽",Succeeds:"≻",SucceedsEqual:"⪰",SucceedsSlantEqual:"≽",SucceedsTilde:"≿",succeq:"⪰",succnapprox:"⪺",succneqq:"⪶",succnsim:"⋩",succsim:"≿",SuchThat:"∋",sum:"∑",Sum:"∑",sung:"♪",sup1:"¹",sup2:"²",sup3:"³",sup:"⊃",Sup:"⋑",supdot:"⪾",supdsub:"⫘",supE:"⫆",supe:"⊇",supedot:"⫄",Superset:"⊃",SupersetEqual:"⊇",suphsol:"⟉",suphsub:"⫗",suplarr:"⥻",supmult:"⫂",supnE:"⫌",supne:"⊋",supplus:"⫀",supset:"⊃",Supset:"⋑",supseteq:"⊇",supseteqq:"⫆",supsetneq:"⊋",supsetneqq:"⫌",supsim:"⫈",supsub:"⫔",supsup:"⫖",swarhk:"⤦",swarr:"↙",swArr:"⇙",swarrow:"↙",swnwar:"⤪",szlig:"ß",Tab:"\t",target:"⌖",Tau:"Τ",tau:"τ",tbrk:"⎴",Tcaron:"Ť",tcaron:"ť",Tcedil:"Ţ",tcedil:"ţ",Tcy:"Т",tcy:"т",tdot:"⃛",telrec:"⌕",Tfr:"𝔗",tfr:"𝔱",there4:"∴",therefore:"∴",Therefore:"∴",Theta:"Θ",theta:"θ",thetasym:"ϑ",thetav:"ϑ",thickapprox:"≈",thicksim:"∼",ThickSpace:"  ",ThinSpace:" ",thinsp:" ",thkap:"≈",thksim:"∼",THORN:"Þ",thorn:"þ",tilde:"˜",Tilde:"∼",TildeEqual:"≃",TildeFullEqual:"≅",TildeTilde:"≈",timesbar:"⨱",timesb:"⊠",times:"×",timesd:"⨰",tint:"∭",toea:"⤨",topbot:"⌶",topcir:"⫱",top:"⊤",Topf:"𝕋",topf:"𝕥",topfork:"⫚",tosa:"⤩",tprime:"‴",trade:"™",TRADE:"™",triangle:"▵",triangledown:"▿",triangleleft:"◃",trianglelefteq:"⊴",triangleq:"≜",triangleright:"▹",trianglerighteq:"⊵",tridot:"◬",trie:"≜",triminus:"⨺",TripleDot:"⃛",triplus:"⨹",trisb:"⧍",tritime:"⨻",trpezium:"⏢",Tscr:"𝒯",tscr:"𝓉",TScy:"Ц",tscy:"ц",TSHcy:"Ћ",tshcy:"ћ",Tstrok:"Ŧ",tstrok:"ŧ",twixt:"≬",twoheadleftarrow:"↞",twoheadrightarrow:"↠",Uacute:"Ú",uacute:"ú",uarr:"↑",Uarr:"↟",uArr:"⇑",Uarrocir:"⥉",Ubrcy:"Ў",ubrcy:"ў",Ubreve:"Ŭ",ubreve:"ŭ",Ucirc:"Û",ucirc:"û",Ucy:"У",ucy:"у",udarr:"⇅",Udblac:"Ű",udblac:"ű",udhar:"⥮",ufisht:"⥾",Ufr:"𝔘",ufr:"𝔲",Ugrave:"Ù",ugrave:"ù",uHar:"⥣",uharl:"↿",uharr:"↾",uhblk:"▀",ulcorn:"⌜",ulcorner:"⌜",ulcrop:"⌏",ultri:"◸",Umacr:"Ū",umacr:"ū",uml:"¨",UnderBar:"_",UnderBrace:"⏟",UnderBracket:"⎵",UnderParenthesis:"⏝",Union:"⋃",UnionPlus:"⊎",Uogon:"Ų",uogon:"ų",Uopf:"𝕌",uopf:"𝕦",UpArrowBar:"⤒",uparrow:"↑",UpArrow:"↑",Uparrow:"⇑",UpArrowDownArrow:"⇅",updownarrow:"↕",UpDownArrow:"↕",Updownarrow:"⇕",UpEquilibrium:"⥮",upharpoonleft:"↿",upharpoonright:"↾",uplus:"⊎",UpperLeftArrow:"↖",UpperRightArrow:"↗",upsi:"υ",Upsi:"ϒ",upsih:"ϒ",Upsilon:"Υ",upsilon:"υ",UpTeeArrow:"↥",UpTee:"⊥",upuparrows:"⇈",urcorn:"⌝",urcorner:"⌝",urcrop:"⌎",Uring:"Ů",uring:"ů",urtri:"◹",Uscr:"𝒰",uscr:"𝓊",utdot:"⋰",Utilde:"Ũ",utilde:"ũ",utri:"▵",utrif:"▴",uuarr:"⇈",Uuml:"Ü",uuml:"ü",uwangle:"⦧",vangrt:"⦜",varepsilon:"ϵ",varkappa:"ϰ",varnothing:"∅",varphi:"ϕ",varpi:"ϖ",varpropto:"∝",varr:"↕",vArr:"⇕",varrho:"ϱ",varsigma:"ς",varsubsetneq:"⊊︀",varsubsetneqq:"⫋︀",varsupsetneq:"⊋︀",varsupsetneqq:"⫌︀",vartheta:"ϑ",vartriangleleft:"⊲",vartriangleright:"⊳",vBar:"⫨",Vbar:"⫫",vBarv:"⫩",Vcy:"В",vcy:"в",vdash:"⊢",vDash:"⊨",Vdash:"⊩",VDash:"⊫",Vdashl:"⫦",veebar:"⊻",vee:"∨",Vee:"⋁",veeeq:"≚",vellip:"⋮",verbar:"|",Verbar:"‖",vert:"|",Vert:"‖",VerticalBar:"∣",VerticalLine:"|",VerticalSeparator:"❘",VerticalTilde:"≀",VeryThinSpace:" ",Vfr:"𝔙",vfr:"𝔳",vltri:"⊲",vnsub:"⊂⃒",vnsup:"⊃⃒",Vopf:"𝕍",vopf:"𝕧",vprop:"∝",vrtri:"⊳",Vscr:"𝒱",vscr:"𝓋",vsubnE:"⫋︀",vsubne:"⊊︀",vsupnE:"⫌︀",vsupne:"⊋︀",Vvdash:"⊪",vzigzag:"⦚",Wcirc:"Ŵ",wcirc:"ŵ",wedbar:"⩟",wedge:"∧",Wedge:"⋀",wedgeq:"≙",weierp:"℘",Wfr:"𝔚",wfr:"𝔴",Wopf:"𝕎",wopf:"𝕨",wp:"℘",wr:"≀",wreath:"≀",Wscr:"𝒲",wscr:"𝓌",xcap:"⋂",xcirc:"◯",xcup:"⋃",xdtri:"▽",Xfr:"𝔛",xfr:"𝔵",xharr:"⟷",xhArr:"⟺",Xi:"Ξ",xi:"ξ",xlarr:"⟵",xlArr:"⟸",xmap:"⟼",xnis:"⋻",xodot:"⨀",Xopf:"𝕏",xopf:"𝕩",xoplus:"⨁",xotime:"⨂",xrarr:"⟶",xrArr:"⟹",Xscr:"𝒳",xscr:"𝓍",xsqcup:"⨆",xuplus:"⨄",xutri:"△",xvee:"⋁",xwedge:"⋀",Yacute:"Ý",yacute:"ý",YAcy:"Я",yacy:"я",Ycirc:"Ŷ",ycirc:"ŷ",Ycy:"Ы",ycy:"ы",yen:"¥",Yfr:"𝔜",yfr:"𝔶",YIcy:"Ї",yicy:"ї",Yopf:"𝕐",yopf:"𝕪",Yscr:"𝒴",yscr:"𝓎",YUcy:"Ю",yucy:"ю",yuml:"ÿ",Yuml:"Ÿ",Zacute:"Ź",zacute:"ź",Zcaron:"Ž",zcaron:"ž",Zcy:"З",zcy:"з",Zdot:"Ż",zdot:"ż",zeetrf:"ℨ",ZeroWidthSpace:"​",Zeta:"Ζ",zeta:"ζ",zfr:"𝔷",Zfr:"ℨ",ZHcy:"Ж",zhcy:"ж",zigrarr:"⇝",zopf:"𝕫",Zopf:"ℤ",Zscr:"𝒵",zscr:"𝓏",zwj:"‍",zwnj:"‌"}},{}],26:[function(e,t,n){t.exports={Aacute:"Á",aacute:"á",Acirc:"Â",acirc:"â",acute:"´",AElig:"Æ",aelig:"æ",Agrave:"À",agrave:"à",amp:"&",AMP:"&",Aring:"Å",aring:"å",Atilde:"Ã",atilde:"ã",Auml:"Ä",auml:"ä",brvbar:"¦",Ccedil:"Ç",ccedil:"ç",cedil:"¸",cent:"¢",copy:"©",COPY:"©",curren:"¤",deg:"°",divide:"÷",Eacute:"É",eacute:"é",Ecirc:"Ê",ecirc:"ê",Egrave:"È",egrave:"è",ETH:"Ð",eth:"ð",Euml:"Ë",euml:"ë",frac12:"½",frac14:"¼",frac34:"¾",gt:">",GT:">",Iacute:"Í",iacute:"í",Icirc:"Î",icirc:"î",iexcl:"¡",Igrave:"Ì",igrave:"ì",iquest:"¿",Iuml:"Ï",iuml:"ï",laquo:"«",lt:"<",LT:"<",macr:"¯",micro:"µ",middot:"·",nbsp:" ",not:"¬",Ntilde:"Ñ",ntilde:"ñ",Oacute:"Ó",oacute:"ó",Ocirc:"Ô",ocirc:"ô",Ograve:"Ò",ograve:"ò",ordf:"ª",ordm:"º",Oslash:"Ø",oslash:"ø",Otilde:"Õ",otilde:"õ",Ouml:"Ö",ouml:"ö",para:"¶",plusmn:"±",pound:"£",quot:'"',QUOT:'"',raquo:"»",reg:"®",REG:"®",sect:"§",shy:"­",sup1:"¹",sup2:"²",sup3:"³",szlig:"ß",THORN:"Þ",thorn:"þ",times:"×",Uacute:"Ú",uacute:"ú",Ucirc:"Û",ucirc:"û",Ugrave:"Ù",ugrave:"ù",uml:"¨",Uuml:"Ü",uuml:"ü",Yacute:"Ý",yacute:"ý",yen:"¥",yuml:"ÿ"}},{}],27:[function(e,t,n){t.exports={amp:"&",apos:"'",gt:">",lt:"<",quot:'"'}},{}],28:[function(e,t,n){function r(){this._events=this._events||{},this._maxListeners=this._maxListeners||void 0}function i(e){return"function"==typeof e}function a(e){return"number"==typeof e}function o(e){return"object"==typeof e&&null!==e}function s(e){return void 0===e}t.exports=r,r.EventEmitter=r,r.prototype._events=void 0,r.prototype._maxListeners=void 0,r.defaultMaxListeners=10,r.prototype.setMaxListeners=function(e){if(!a(e)||e<0||isNaN(e))throw TypeError("n must be a positive number");return this._maxListeners=e,this},r.prototype.emit=function(e){var t,n,r,a,l,u;if(this._events||(this._events={}),"error"===e&&(!this._events.error||o(this._events.error)&&!this._events.error.length)){if(t=arguments[1],t instanceof Error)throw t;var c=new Error('Uncaught, unspecified "error" event. ('+t+")");throw c.context=t,c}if(n=this._events[e],s(n))return!1;if(i(n))switch(arguments.length){case 1:n.call(this);break;case 2:n.call(this,arguments[1]);break;case 3:n.call(this,arguments[1],arguments[2]);break;default:a=Array.prototype.slice.call(arguments,1),n.apply(this,a)}else if(o(n))for(a=Array.prototype.slice.call(arguments,1),u=n.slice(),r=u.length,l=0;l<r;l++)u[l].apply(this,a);return!0},r.prototype.addListener=function(e,t){var n;if(!i(t))throw TypeError("listener must be a function");return this._events||(this._events={}),this._events.newListener&&this.emit("newListener",e,i(t.listener)?t.listener:t),this._events[e]?o(this._events[e])?this._events[e].push(t):this._events[e]=[this._events[e],t]:this._events[e]=t,o(this._events[e])&&!this._events[e].warned&&(n=s(this._maxListeners)?r.defaultMaxListeners:this._maxListeners,n&&n>0&&this._events[e].length>n&&(this._events[e].warned=!0,console.error("(node) warning: possible EventEmitter memory leak detected. %d listeners added. Use emitter.setMaxListeners() to increase limit.",this._events[e].length),"function"==typeof console.trace&&console.trace())),this},r.prototype.on=r.prototype.addListener,r.prototype.once=function(e,t){function n(){this.removeListener(e,n),r||(r=!0,t.apply(this,arguments))}if(!i(t))throw TypeError("listener must be a function");var r=!1;return n.listener=t,this.on(e,n),this},r.prototype.removeListener=function(e,t){var n,r,a,s;if(!i(t))throw TypeError("listener must be a function");if(!this._events||!this._events[e])return this;if(n=this._events[e],a=n.length,r=-1,n===t||i(n.listener)&&n.listener===t)delete this._events[e],this._events.removeListener&&this.emit("removeListener",e,t);else if(o(n)){for(s=a;s-- >0;)if(n[s]===t||n[s].listener&&n[s].listener===t){r=s;break}if(r<0)return this;1===n.length?(n.length=0,delete this._events[e]):n.splice(r,1),this._events.removeListener&&this.emit("removeListener",e,t)}return this},r.prototype.removeAllListeners=function(e){var t,n;if(!this._events)return this;if(!this._events.removeListener)return 0===arguments.length?this._events={}:this._events[e]&&delete this._events[e],this;if(0===arguments.length){for(t in this._events)"removeListener"!==t&&this.removeAllListeners(t);return this.removeAllListeners("removeListener"),this._events={},this}if(n=this._events[e],i(n))this.removeListener(e,n);else if(n)for(;n.length;)this.removeListener(e,n[n.length-1]);return delete this._events[e],this},r.prototype.listeners=function(e){var t;return t=this._events&&this._events[e]?i(this._events[e])?[this._events[e]]:this._events[e].slice():[]},r.prototype.listenerCount=function(e){if(this._events){var t=this._events[e];if(i(t))return 1;if(t)return t.length}return 0},r.listenerCount=function(e,t){return e.listenerCount(t)}},{}],29:[function(e,t,n){function r(e){this._cbs=e||{},this.events=[]}t.exports=r;var i=e("./").EVENTS;Object.keys(i).forEach(function(e){if(0===i[e])e="on"+e,r.prototype[e]=function(){this.events.push([e]),this._cbs[e]&&this._cbs[e]()};else if(1===i[e])e="on"+e,r.prototype[e]=function(t){this.events.push([e,t]),this._cbs[e]&&this._cbs[e](t)};else{if(2!==i[e])throw Error("wrong number of arguments");e="on"+e,r.prototype[e]=function(t,n){this.events.push([e,t,n]),this._cbs[e]&&this._cbs[e](t,n)}}}),r.prototype.onreset=function(){this.events=[],this._cbs.onreset&&this._cbs.onreset()},r.prototype.restart=function(){this._cbs.onreset&&this._cbs.onreset();for(var e=0,t=this.events.length;e<t;e++)if(this._cbs[this.events[e][0]]){var n=this.events[e].length;1===n?this._cbs[this.events[e][0]]():2===n?this._cbs[this.events[e][0]](this.events[e][1]):this._cbs[this.events[e][0]](this.events[e][1],this.events[e][2])}}},{"./":36}],30:[function(e,t,n){function r(e,t){this.init(e,t)}function i(e,t){return c.getElementsByTagName(e,t,!0)}function a(e,t){return c.getElementsByTagName(e,t,!0,1)[0]}function o(e,t,n){return c.getText(c.getElementsByTagName(e,t,n,1)).trim()}function s(e,t,n,r,i){var a=o(n,r,i);a&&(e[t]=a)}var l=e("./index.js"),u=l.DomHandler,c=l.DomUtils;e("inherits")(r,u),r.prototype.init=u;var p=function(e){return"rss"===e||"feed"===e||"rdf:RDF"===e};r.prototype.onend=function(){var e,t,n={},r=a(p,this.dom);r&&("feed"===r.name?(t=r.children,n.type="atom",s(n,"id","id",t),s(n,"title","title",t),(e=a("link",t))&&(e=e.attribs)&&(e=e.href)&&(n.link=e),s(n,"description","subtitle",t),(e=o("updated",t))&&(n.updated=new Date(e)),s(n,"author","email",t,!0),n.items=i("entry",t).map(function(e){var t,n={};return e=e.children,s(n,"id","id",e),s(n,"title","title",e),(t=a("link",e))&&(t=t.attribs)&&(t=t.href)&&(n.link=t),(t=o("summary",e)||o("content",e))&&(n.description=t),(t=o("updated",e))&&(n.pubDate=new Date(t)),n})):(t=a("channel",r.children).children,n.type=r.name.substr(0,3),n.id="",s(n,"title","title",t),s(n,"link","link",t),s(n,"description","description",t),(e=o("lastBuildDate",t))&&(n.updated=new Date(e)),s(n,"author","managingEditor",t,!0),n.items=i("item",r.children).map(function(e){var t,n={};return e=e.children,s(n,"id","guid",e),s(n,"title","title",e),s(n,"link","link",e),s(n,"description","description",e),(t=o("pubDate",e))&&(n.pubDate=new Date(t)),n}))),this.dom=n,u.prototype._handleCallback.call(this,r?null:Error("couldn't find root of feed"))},t.exports=r},{"./index.js":36,inherits:38}],31:[function(e,t,n){function r(e,t){this._options=t||{},this._cbs=e||{},this._tagname="",this._attribname="",this._attribvalue="",this._attribs=null,this._stack=[],this.startIndex=0,this.endIndex=null,this._lowerCaseTagNames="lowerCaseTags"in this._options?!!this._options.lowerCaseTags:!this._options.xmlMode,this._lowerCaseAttributeNames="lowerCaseAttributeNames"in this._options?!!this._options.lowerCaseAttributeNames:!this._options.xmlMode,this._options.Tokenizer&&(i=this._options.Tokenizer),this._tokenizer=new i(this._options,this),this._cbs.onparserinit&&this._cbs.onparserinit(this)}var i=e("./Tokenizer.js"),a={input:!0,option:!0,optgroup:!0,select:!0,button:!0,datalist:!0,textarea:!0},o={tr:{tr:!0,th:!0,td:!0},th:{th:!0},td:{thead:!0,th:!0,td:!0},body:{head:!0,link:!0,script:!0},li:{li:!0},p:{p:!0},h1:{p:!0},h2:{p:!0},h3:{p:!0},h4:{p:!0},h5:{p:!0},h6:{p:!0},select:a,input:a,output:a,button:a,datalist:a,textarea:a,option:{option:!0},optgroup:{optgroup:!0}},s={__proto__:null,area:!0,base:!0,basefont:!0,br:!0,col:!0,command:!0,embed:!0,frame:!0,hr:!0,img:!0,input:!0,isindex:!0,keygen:!0,link:!0,meta:!0,param:!0,source:!0,track:!0,wbr:!0,path:!0,circle:!0,ellipse:!0,line:!0,rect:!0,use:!0,stop:!0,polyline:!0,polygon:!0},l=/\s|\//;e("inherits")(r,e("events").EventEmitter),r.prototype._updatePosition=function(e){null===this.endIndex?this._tokenizer._sectionStart<=e?this.startIndex=0:this.startIndex=this._tokenizer._sectionStart-e:this.startIndex=this.endIndex+1,this.endIndex=this._tokenizer.getAbsoluteIndex()},r.prototype.ontext=function(e){this._updatePosition(1),this.endIndex--,this._cbs.ontext&&this._cbs.ontext(e)},r.prototype.onopentagname=function(e){if(this._lowerCaseTagNames&&(e=e.toLowerCase()),this._tagname=e,!this._options.xmlMode&&e in o)for(var t;(t=this._stack[this._stack.length-1])in o[e];this.onclosetag(t));!this._options.xmlMode&&e in s||this._stack.push(e),this._cbs.onopentagname&&this._cbs.onopentagname(e),this._cbs.onopentag&&(this._attribs={})},r.prototype.onopentagend=function(){this._updatePosition(1),this._attribs&&(this._cbs.onopentag&&this._cbs.onopentag(this._tagname,this._attribs),this._attribs=null),!this._options.xmlMode&&this._cbs.onclosetag&&this._tagname in s&&this._cbs.onclosetag(this._tagname),this._tagname=""},r.prototype.onclosetag=function(e){if(this._updatePosition(1),this._lowerCaseTagNames&&(e=e.toLowerCase()),!this._stack.length||e in s&&!this._options.xmlMode)this._options.xmlMode||"br"!==e&&"p"!==e||(this.onopentagname(e),this._closeCurrentTag());else{var t=this._stack.lastIndexOf(e);if(t!==-1)if(this._cbs.onclosetag)for(t=this._stack.length-t;t--;)this._cbs.onclosetag(this._stack.pop());else this._stack.length=t;else"p"!==e||this._options.xmlMode||(this.onopentagname(e),this._closeCurrentTag())}},r.prototype.onselfclosingtag=function(){this._options.xmlMode||this._options.recognizeSelfClosing?this._closeCurrentTag():this.onopentagend()},r.prototype._closeCurrentTag=function(){var e=this._tagname;this.onopentagend(),this._stack[this._stack.length-1]===e&&(this._cbs.onclosetag&&this._cbs.onclosetag(e),this._stack.pop())},r.prototype.onattribname=function(e){this._lowerCaseAttributeNames&&(e=e.toLowerCase()),this._attribname=e},r.prototype.onattribdata=function(e){this._attribvalue+=e},r.prototype.onattribend=function(){this._cbs.onattribute&&this._cbs.onattribute(this._attribname,this._attribvalue),this._attribs&&!Object.prototype.hasOwnProperty.call(this._attribs,this._attribname)&&(this._attribs[this._attribname]=this._attribvalue),this._attribname="",this._attribvalue=""},r.prototype._getInstructionName=function(e){var t=e.search(l),n=t<0?e:e.substr(0,t);return this._lowerCaseTagNames&&(n=n.toLowerCase()),n},r.prototype.ondeclaration=function(e){if(this._cbs.onprocessinginstruction){var t=this._getInstructionName(e);this._cbs.onprocessinginstruction("!"+t,"!"+e)}},r.prototype.onprocessinginstruction=function(e){if(this._cbs.onprocessinginstruction){var t=this._getInstructionName(e);this._cbs.onprocessinginstruction("?"+t,"?"+e)}},r.prototype.oncomment=function(e){this._updatePosition(4),this._cbs.oncomment&&this._cbs.oncomment(e),this._cbs.oncommentend&&this._cbs.oncommentend()},r.prototype.oncdata=function(e){this._updatePosition(1),this._options.xmlMode||this._options.recognizeCDATA?(this._cbs.oncdatastart&&this._cbs.oncdatastart(),this._cbs.ontext&&this._cbs.ontext(e),this._cbs.oncdataend&&this._cbs.oncdataend()):this.oncomment("[CDATA["+e+"]]")},r.prototype.onerror=function(e){this._cbs.onerror&&this._cbs.onerror(e)},r.prototype.onend=function(){if(this._cbs.onclosetag)for(var e=this._stack.length;e>0;this._cbs.onclosetag(this._stack[--e]));this._cbs.onend&&this._cbs.onend()},r.prototype.reset=function(){this._cbs.onreset&&this._cbs.onreset(),this._tokenizer.reset(),this._tagname="",this._attribname="",this._attribs=null,this._stack=[],this._cbs.onparserinit&&this._cbs.onparserinit(this)},r.prototype.parseComplete=function(e){this.reset(),this.end(e)},r.prototype.write=function(e){this._tokenizer.write(e)},r.prototype.end=function(e){this._tokenizer.end(e)},r.prototype.pause=function(){this._tokenizer.pause()},r.prototype.resume=function(){this._tokenizer.resume()},r.prototype.parseChunk=r.prototype.write,r.prototype.done=r.prototype.end,t.exports=r},{"./Tokenizer.js":34,events:28,inherits:38}],32:[function(e,t,n){function r(e){this._cbs=e||{}}t.exports=r;var i=e("./").EVENTS;Object.keys(i).forEach(function(e){if(0===i[e])e="on"+e,r.prototype[e]=function(){this._cbs[e]&&this._cbs[e]()};else if(1===i[e])e="on"+e,r.prototype[e]=function(t){this._cbs[e]&&this._cbs[e](t)};else{if(2!==i[e])throw Error("wrong number of arguments");e="on"+e,r.prototype[e]=function(t,n){this._cbs[e]&&this._cbs[e](t,n)}}})},{"./":36}],33:[function(e,t,n){function r(e){a.call(this,new i(this),e)}function i(e){this.scope=e}t.exports=r;var a=e("./WritableStream.js");e("inherits")(r,a),r.prototype.readable=!0;var o=e("../").EVENTS;Object.keys(o).forEach(function(e){if(0===o[e])i.prototype["on"+e]=function(){this.scope.emit(e)};else if(1===o[e])i.prototype["on"+e]=function(t){this.scope.emit(e,t)};else{if(2!==o[e])throw Error("wrong number of arguments!");i.prototype["on"+e]=function(t,n){this.scope.emit(e,t,n)}}})},{"../":36,"./WritableStream.js":35,inherits:38}],34:[function(e,t,n){function r(e){return" "===e||"\n"===e||"\t"===e||"\f"===e||"\r"===e}function i(e,t){return function(n){n===e&&(this._state=t)}}function a(e,t,n){var r=e.toLowerCase();return e===r?function(e){e===r?this._state=t:(this._state=n,this._index--)}:function(i){i===r||i===e?this._state=t:(this._state=n,this._index--)}}function o(e,t){var n=e.toLowerCase();return function(r){r===n||r===e?this._state=t:(this._state=m,this._index--)}}function s(e,t){this._state=f,this._buffer="",this._sectionStart=0,this._index=0,this._bufferOffset=0,this._baseState=f,this._special=me,this._cbs=t,this._running=!0,this._ended=!1,this._xmlMode=!(!e||!e.xmlMode),this._decodeEntities=!(!e||!e.decodeEntities)}t.exports=s;var l=e("entities/lib/decode_codepoint.js"),u=e("entities/maps/entities.json"),c=e("entities/maps/legacy.json"),p=e("entities/maps/xml.json"),h=0,f=h++,d=h++,m=h++,g=h++,y=h++,v=h++,b=h++,w=h++,_=h++,x=h++,A=h++,S=h++,j=h++,E=h++,O=h++,k=h++,T=h++,C=h++,I=h++,D=h++,L=h++,M=h++,R=h++,U=h++,P=h++,q=h++,B=h++,N=h++,z=h++,$=h++,F=h++,V=h++,H=h++,Y=h++,J=h++,W=h++,Q=h++,G=h++,K=h++,X=h++,Z=h++,ee=h++,te=h++,ne=h++,re=h++,ie=h++,ae=h++,oe=h++,se=h++,le=h++,ue=h++,ce=h++,pe=h++,he=h++,fe=h++,de=0,me=de++,ge=de++,ye=de++;s.prototype._stateText=function(e){"<"===e?(this._index>this._sectionStart&&this._cbs.ontext(this._getSection()),this._state=d,this._sectionStart=this._index):this._decodeEntities&&this._special===me&&"&"===e&&(this._index>this._sectionStart&&this._cbs.ontext(this._getSection()),this._baseState=f,this._state=ue,this._sectionStart=this._index)},s.prototype._stateBeforeTagName=function(e){"/"===e?this._state=y:"<"===e?(this._cbs.ontext(this._getSection()),this._sectionStart=this._index):">"===e||this._special!==me||r(e)?this._state=f:"!"===e?(this._state=O,this._sectionStart=this._index+1):"?"===e?(this._state=T,this._sectionStart=this._index+1):(this._state=this._xmlMode||"s"!==e&&"S"!==e?m:F,this._sectionStart=this._index)},s.prototype._stateInTagName=function(e){("/"===e||">"===e||r(e))&&(this._emitToken("onopentagname"),this._state=w,this._index--)},s.prototype._stateBeforeCloseingTagName=function(e){r(e)||(">"===e?this._state=f:this._special!==me?"s"===e||"S"===e?this._state=V:(this._state=f,this._index--):(this._state=v,this._sectionStart=this._index))},s.prototype._stateInCloseingTagName=function(e){(">"===e||r(e))&&(this._emitToken("onclosetag"),this._state=b,this._index--)},s.prototype._stateAfterCloseingTagName=function(e){">"===e&&(this._state=f,this._sectionStart=this._index+1)},s.prototype._stateBeforeAttributeName=function(e){">"===e?(this._cbs.onopentagend(),this._state=f,this._sectionStart=this._index+1):"/"===e?this._state=g:r(e)||(this._state=_,this._sectionStart=this._index)},s.prototype._stateInSelfClosingTag=function(e){">"===e?(this._cbs.onselfclosingtag(),this._state=f,this._sectionStart=this._index+1):r(e)||(this._state=w,this._index--)},s.prototype._stateInAttributeName=function(e){("="===e||"/"===e||">"===e||r(e))&&(this._cbs.onattribname(this._getSection()),this._sectionStart=-1,this._state=x,this._index--)},s.prototype._stateAfterAttributeName=function(e){"="===e?this._state=A:"/"===e||">"===e?(this._cbs.onattribend(),this._state=w,this._index--):r(e)||(this._cbs.onattribend(),this._state=_,this._sectionStart=this._index)},s.prototype._stateBeforeAttributeValue=function(e){'"'===e?(this._state=S,this._sectionStart=this._index+1):"'"===e?(this._state=j,this._sectionStart=this._index+1):r(e)||(this._state=E,this._sectionStart=this._index,this._index--)},s.prototype._stateInAttributeValueDoubleQuotes=function(e){'"'===e?(this._emitToken("onattribdata"),this._cbs.onattribend(),this._state=w):this._decodeEntities&&"&"===e&&(this._emitToken("onattribdata"),this._baseState=this._state,this._state=ue,this._sectionStart=this._index)},s.prototype._stateInAttributeValueSingleQuotes=function(e){"'"===e?(this._emitToken("onattribdata"),this._cbs.onattribend(),this._state=w):this._decodeEntities&&"&"===e&&(this._emitToken("onattribdata"),this._baseState=this._state,this._state=ue,this._sectionStart=this._index)},s.prototype._stateInAttributeValueNoQuotes=function(e){r(e)||">"===e?(this._emitToken("onattribdata"),this._cbs.onattribend(),this._state=w,this._index--):this._decodeEntities&&"&"===e&&(this._emitToken("onattribdata"),this._baseState=this._state,this._state=ue,this._sectionStart=this._index)},s.prototype._stateBeforeDeclaration=function(e){this._state="["===e?M:"-"===e?C:k},s.prototype._stateInDeclaration=function(e){">"===e&&(this._cbs.ondeclaration(this._getSection()),this._state=f,this._sectionStart=this._index+1)},s.prototype._stateInProcessingInstruction=function(e){">"===e&&(this._cbs.onprocessinginstruction(this._getSection()),this._state=f,this._sectionStart=this._index+1)},s.prototype._stateBeforeComment=function(e){"-"===e?(this._state=I,this._sectionStart=this._index+1):this._state=k},s.prototype._stateInComment=function(e){"-"===e&&(this._state=D)},s.prototype._stateAfterComment1=function(e){"-"===e?this._state=L:this._state=I},s.prototype._stateAfterComment2=function(e){">"===e?(this._cbs.oncomment(this._buffer.substring(this._sectionStart,this._index-2)),this._state=f,this._sectionStart=this._index+1):"-"!==e&&(this._state=I)},s.prototype._stateBeforeCdata1=a("C",R,k),s.prototype._stateBeforeCdata2=a("D",U,k),s.prototype._stateBeforeCdata3=a("A",P,k),s.prototype._stateBeforeCdata4=a("T",q,k),s.prototype._stateBeforeCdata5=a("A",B,k),s.prototype._stateBeforeCdata6=function(e){"["===e?(this._state=N,this._sectionStart=this._index+1):(this._state=k,this._index--)},s.prototype._stateInCdata=function(e){"]"===e&&(this._state=z)},s.prototype._stateAfterCdata1=i("]",$),s.prototype._stateAfterCdata2=function(e){">"===e?(this._cbs.oncdata(this._buffer.substring(this._sectionStart,this._index-2)),this._state=f,this._sectionStart=this._index+1):"]"!==e&&(this._state=N)},s.prototype._stateBeforeSpecial=function(e){"c"===e||"C"===e?this._state=H:"t"===e||"T"===e?this._state=te:(this._state=m,this._index--)},s.prototype._stateBeforeSpecialEnd=function(e){this._special!==ge||"c"!==e&&"C"!==e?this._special!==ye||"t"!==e&&"T"!==e?this._state=f:this._state=ae:this._state=G},s.prototype._stateBeforeScript1=o("R",Y),s.prototype._stateBeforeScript2=o("I",J),s.prototype._stateBeforeScript3=o("P",W),s.prototype._stateBeforeScript4=o("T",Q),s.prototype._stateBeforeScript5=function(e){("/"===e||">"===e||r(e))&&(this._special=ge),this._state=m,this._index--},s.prototype._stateAfterScript1=a("R",K,f),s.prototype._stateAfterScript2=a("I",X,f),s.prototype._stateAfterScript3=a("P",Z,f),s.prototype._stateAfterScript4=a("T",ee,f),s.prototype._stateAfterScript5=function(e){
-">"===e||r(e)?(this._special=me,this._state=v,this._sectionStart=this._index-6,this._index--):this._state=f},s.prototype._stateBeforeStyle1=o("Y",ne),s.prototype._stateBeforeStyle2=o("L",re),s.prototype._stateBeforeStyle3=o("E",ie),s.prototype._stateBeforeStyle4=function(e){("/"===e||">"===e||r(e))&&(this._special=ye),this._state=m,this._index--},s.prototype._stateAfterStyle1=a("Y",oe,f),s.prototype._stateAfterStyle2=a("L",se,f),s.prototype._stateAfterStyle3=a("E",le,f),s.prototype._stateAfterStyle4=function(e){">"===e||r(e)?(this._special=me,this._state=v,this._sectionStart=this._index-5,this._index--):this._state=f},s.prototype._stateBeforeEntity=a("#",ce,pe),s.prototype._stateBeforeNumericEntity=a("X",fe,he),s.prototype._parseNamedEntityStrict=function(){if(this._sectionStart+1<this._index){var e=this._buffer.substring(this._sectionStart+1,this._index),t=this._xmlMode?p:u;t.hasOwnProperty(e)&&(this._emitPartial(t[e]),this._sectionStart=this._index+1)}},s.prototype._parseLegacyEntity=function(){var e=this._sectionStart+1,t=this._index-e;for(t>6&&(t=6);t>=2;){var n=this._buffer.substr(e,t);if(c.hasOwnProperty(n))return this._emitPartial(c[n]),void(this._sectionStart+=t+1);t--}},s.prototype._stateInNamedEntity=function(e){";"===e?(this._parseNamedEntityStrict(),this._sectionStart+1<this._index&&!this._xmlMode&&this._parseLegacyEntity(),this._state=this._baseState):(e<"a"||e>"z")&&(e<"A"||e>"Z")&&(e<"0"||e>"9")&&(this._xmlMode||this._sectionStart+1===this._index||(this._baseState!==f?"="!==e&&this._parseNamedEntityStrict():this._parseLegacyEntity()),this._state=this._baseState,this._index--)},s.prototype._decodeNumericEntity=function(e,t){var n=this._sectionStart+e;if(n!==this._index){var r=this._buffer.substring(n,this._index),i=parseInt(r,t);this._emitPartial(l(i)),this._sectionStart=this._index}else this._sectionStart--;this._state=this._baseState},s.prototype._stateInNumericEntity=function(e){";"===e?(this._decodeNumericEntity(2,10),this._sectionStart++):(e<"0"||e>"9")&&(this._xmlMode?this._state=this._baseState:this._decodeNumericEntity(2,10),this._index--)},s.prototype._stateInHexEntity=function(e){";"===e?(this._decodeNumericEntity(3,16),this._sectionStart++):(e<"a"||e>"f")&&(e<"A"||e>"F")&&(e<"0"||e>"9")&&(this._xmlMode?this._state=this._baseState:this._decodeNumericEntity(3,16),this._index--)},s.prototype._cleanup=function(){this._sectionStart<0?(this._buffer="",this._index=0,this._bufferOffset+=this._index):this._running&&(this._state===f?(this._sectionStart!==this._index&&this._cbs.ontext(this._buffer.substr(this._sectionStart)),this._buffer="",this._bufferOffset+=this._index,this._index=0):this._sectionStart===this._index?(this._buffer="",this._bufferOffset+=this._index,this._index=0):(this._buffer=this._buffer.substr(this._sectionStart),this._index-=this._sectionStart,this._bufferOffset+=this._sectionStart),this._sectionStart=0)},s.prototype.write=function(e){this._ended&&this._cbs.onerror(Error(".write() after done!")),this._buffer+=e,this._parse()},s.prototype._parse=function(){for(;this._index<this._buffer.length&&this._running;){var e=this._buffer.charAt(this._index);this._state===f?this._stateText(e):this._state===d?this._stateBeforeTagName(e):this._state===m?this._stateInTagName(e):this._state===y?this._stateBeforeCloseingTagName(e):this._state===v?this._stateInCloseingTagName(e):this._state===b?this._stateAfterCloseingTagName(e):this._state===g?this._stateInSelfClosingTag(e):this._state===w?this._stateBeforeAttributeName(e):this._state===_?this._stateInAttributeName(e):this._state===x?this._stateAfterAttributeName(e):this._state===A?this._stateBeforeAttributeValue(e):this._state===S?this._stateInAttributeValueDoubleQuotes(e):this._state===j?this._stateInAttributeValueSingleQuotes(e):this._state===E?this._stateInAttributeValueNoQuotes(e):this._state===O?this._stateBeforeDeclaration(e):this._state===k?this._stateInDeclaration(e):this._state===T?this._stateInProcessingInstruction(e):this._state===C?this._stateBeforeComment(e):this._state===I?this._stateInComment(e):this._state===D?this._stateAfterComment1(e):this._state===L?this._stateAfterComment2(e):this._state===M?this._stateBeforeCdata1(e):this._state===R?this._stateBeforeCdata2(e):this._state===U?this._stateBeforeCdata3(e):this._state===P?this._stateBeforeCdata4(e):this._state===q?this._stateBeforeCdata5(e):this._state===B?this._stateBeforeCdata6(e):this._state===N?this._stateInCdata(e):this._state===z?this._stateAfterCdata1(e):this._state===$?this._stateAfterCdata2(e):this._state===F?this._stateBeforeSpecial(e):this._state===V?this._stateBeforeSpecialEnd(e):this._state===H?this._stateBeforeScript1(e):this._state===Y?this._stateBeforeScript2(e):this._state===J?this._stateBeforeScript3(e):this._state===W?this._stateBeforeScript4(e):this._state===Q?this._stateBeforeScript5(e):this._state===G?this._stateAfterScript1(e):this._state===K?this._stateAfterScript2(e):this._state===X?this._stateAfterScript3(e):this._state===Z?this._stateAfterScript4(e):this._state===ee?this._stateAfterScript5(e):this._state===te?this._stateBeforeStyle1(e):this._state===ne?this._stateBeforeStyle2(e):this._state===re?this._stateBeforeStyle3(e):this._state===ie?this._stateBeforeStyle4(e):this._state===ae?this._stateAfterStyle1(e):this._state===oe?this._stateAfterStyle2(e):this._state===se?this._stateAfterStyle3(e):this._state===le?this._stateAfterStyle4(e):this._state===ue?this._stateBeforeEntity(e):this._state===ce?this._stateBeforeNumericEntity(e):this._state===pe?this._stateInNamedEntity(e):this._state===he?this._stateInNumericEntity(e):this._state===fe?this._stateInHexEntity(e):this._cbs.onerror(Error("unknown _state"),this._state),this._index++}this._cleanup()},s.prototype.pause=function(){this._running=!1},s.prototype.resume=function(){this._running=!0,this._index<this._buffer.length&&this._parse(),this._ended&&this._finish()},s.prototype.end=function(e){this._ended&&this._cbs.onerror(Error(".end() after done!")),e&&this.write(e),this._ended=!0,this._running&&this._finish()},s.prototype._finish=function(){this._sectionStart<this._index&&this._handleTrailingData(),this._cbs.onend()},s.prototype._handleTrailingData=function(){var e=this._buffer.substr(this._sectionStart);this._state===N||this._state===z||this._state===$?this._cbs.oncdata(e):this._state===I||this._state===D||this._state===L?this._cbs.oncomment(e):this._state!==pe||this._xmlMode?this._state!==he||this._xmlMode?this._state!==fe||this._xmlMode?this._state!==m&&this._state!==w&&this._state!==A&&this._state!==x&&this._state!==_&&this._state!==j&&this._state!==S&&this._state!==E&&this._state!==v&&this._cbs.ontext(e):(this._decodeNumericEntity(3,16),this._sectionStart<this._index&&(this._state=this._baseState,this._handleTrailingData())):(this._decodeNumericEntity(2,10),this._sectionStart<this._index&&(this._state=this._baseState,this._handleTrailingData())):(this._parseLegacyEntity(),this._sectionStart<this._index&&(this._state=this._baseState,this._handleTrailingData()))},s.prototype.reset=function(){s.call(this,{xmlMode:this._xmlMode,decodeEntities:this._decodeEntities},this._cbs)},s.prototype.getAbsoluteIndex=function(){return this._bufferOffset+this._index},s.prototype._getSection=function(){return this._buffer.substring(this._sectionStart,this._index)},s.prototype._emitToken=function(e){this._cbs[e](this._getSection()),this._sectionStart=-1},s.prototype._emitPartial=function(e){this._baseState!==f?this._cbs.onattribdata(e):this._cbs.ontext(e)}},{"entities/lib/decode_codepoint.js":22,"entities/maps/entities.json":25,"entities/maps/legacy.json":26,"entities/maps/xml.json":27}],35:[function(e,t,n){function r(e,t){var n=this._parser=new i(e,t),r=this._decoder=new o;a.call(this,{decodeStrings:!1}),this.once("finish",function(){n.end(r.end())})}t.exports=r;var i=e("./Parser.js"),a=e("stream").Writable||e("readable-stream").Writable,o=e("string_decoder").StringDecoder,s=e("buffer").Buffer;e("inherits")(r,a),a.prototype._write=function(e,t,n){e instanceof s&&(e=this._decoder.write(e)),this._parser.write(e),n()}},{"./Parser.js":31,buffer:5,inherits:38,"readable-stream":3,stream:55,string_decoder:56}],36:[function(e,t,n){function r(e,n){return delete t.exports[e],t.exports[e]=n,n}var i=e("./Parser.js"),a=e("domhandler");t.exports={Parser:i,Tokenizer:e("./Tokenizer.js"),ElementType:e("domelementtype"),DomHandler:a,get FeedHandler(){return r("FeedHandler",e("./FeedHandler.js"))},get Stream(){return r("Stream",e("./Stream.js"))},get WritableStream(){return r("WritableStream",e("./WritableStream.js"))},get ProxyHandler(){return r("ProxyHandler",e("./ProxyHandler.js"))},get DomUtils(){return r("DomUtils",e("domutils"))},get CollectingHandler(){return r("CollectingHandler",e("./CollectingHandler.js"))},DefaultHandler:a,get RssHandler(){return r("RssHandler",this.FeedHandler)},parseDOM:function(e,t){var n=new a(t);return new i(n,t).end(e),n.dom},parseFeed:function(e,n){var r=new t.exports.FeedHandler(n);return new i(r,n).end(e),r.dom},createDomStream:function(e,t,n){var r=new a(e,t,n);return new i(r,t)},EVENTS:{attribute:2,cdatastart:0,cdataend:0,text:1,processinginstruction:2,comment:1,commentend:0,closetag:1,opentag:2,opentagname:1,error:1,end:0}}},{"./CollectingHandler.js":29,"./FeedHandler.js":30,"./Parser.js":31,"./ProxyHandler.js":32,"./Stream.js":33,"./Tokenizer.js":34,"./WritableStream.js":35,domelementtype:9,domhandler:10,domutils:13}],37:[function(e,t,n){n.read=function(e,t,n,r,i){var a,o,s=8*i-r-1,l=(1<<s)-1,u=l>>1,c=-7,p=n?i-1:0,h=n?-1:1,f=e[t+p];for(p+=h,a=f&(1<<-c)-1,f>>=-c,c+=s;c>0;a=256*a+e[t+p],p+=h,c-=8);for(o=a&(1<<-c)-1,a>>=-c,c+=r;c>0;o=256*o+e[t+p],p+=h,c-=8);if(0===a)a=1-u;else{if(a===l)return o?NaN:(f?-1:1)*(1/0);o+=Math.pow(2,r),a-=u}return(f?-1:1)*o*Math.pow(2,a-r)},n.write=function(e,t,n,r,i,a){var o,s,l,u=8*a-i-1,c=(1<<u)-1,p=c>>1,h=23===i?Math.pow(2,-24)-Math.pow(2,-77):0,f=r?0:a-1,d=r?1:-1,m=t<0||0===t&&1/t<0?1:0;for(t=Math.abs(t),isNaN(t)||t===1/0?(s=isNaN(t)?1:0,o=c):(o=Math.floor(Math.log(t)/Math.LN2),t*(l=Math.pow(2,-o))<1&&(o--,l*=2),t+=o+p>=1?h/l:h*Math.pow(2,1-p),t*l>=2&&(o++,l/=2),o+p>=c?(s=0,o=c):o+p>=1?(s=(t*l-1)*Math.pow(2,i),o+=p):(s=t*Math.pow(2,p-1)*Math.pow(2,i),o=0));i>=8;e[n+f]=255&s,f+=d,s/=256,i-=8);for(o=o<<i|s,u+=i;u>0;e[n+f]=255&o,f+=d,o/=256,u-=8);e[n+f-d]|=128*m}},{}],38:[function(e,t,n){"function"==typeof Object.create?t.exports=function(e,t){e.super_=t,e.prototype=Object.create(t.prototype,{constructor:{value:e,enumerable:!1,writable:!0,configurable:!0}})}:t.exports=function(e,t){e.super_=t;var n=function(){};n.prototype=t.prototype,e.prototype=new n,e.prototype.constructor=e}},{}],39:[function(e,t,n){function r(e){return!!e.constructor&&"function"==typeof e.constructor.isBuffer&&e.constructor.isBuffer(e)}function i(e){return"function"==typeof e.readFloatLE&&"function"==typeof e.slice&&r(e.slice(0,0))}t.exports=function(e){return null!=e&&(r(e)||i(e)||!!e._isBuffer)}},{}],40:[function(e,t,n){var r={}.toString;t.exports=Array.isArray||function(e){return"[object Array]"==r.call(e)}},{}],41:[function(e,t,n){(function(e){"use strict";function n(t,n,r,i){if("function"!=typeof t)throw new TypeError('"callback" argument must be a function');var a,o,s=arguments.length;switch(s){case 0:case 1:return e.nextTick(t);case 2:return e.nextTick(function(){t.call(null,n)});case 3:return e.nextTick(function(){t.call(null,n,r)});case 4:return e.nextTick(function(){t.call(null,n,r,i)});default:for(a=new Array(s-1),o=0;o<a.length;)a[o++]=arguments[o];return e.nextTick(function(){t.apply(null,a)})}}!e.version||0===e.version.indexOf("v0.")||0===e.version.indexOf("v1.")&&0!==e.version.indexOf("v1.8.")?t.exports=n:t.exports=e.nextTick}).call(this,e("_process"))},{_process:42}],42:[function(e,t,n){function r(){throw new Error("setTimeout has not been defined")}function i(){throw new Error("clearTimeout has not been defined")}function a(e){if(p===setTimeout)return setTimeout(e,0);if((p===r||!p)&&setTimeout)return p=setTimeout,setTimeout(e,0);try{return p(e,0)}catch(t){try{return p.call(null,e,0)}catch(t){return p.call(this,e,0)}}}function o(e){if(h===clearTimeout)return clearTimeout(e);if((h===i||!h)&&clearTimeout)return h=clearTimeout,clearTimeout(e);try{return h(e)}catch(t){try{return h.call(null,e)}catch(t){return h.call(this,e)}}}function s(){g&&d&&(g=!1,d.length?m=d.concat(m):y=-1,m.length&&l())}function l(){if(!g){var e=a(s);g=!0;for(var t=m.length;t;){for(d=m,m=[];++y<t;)d&&d[y].run();y=-1,t=m.length}d=null,g=!1,o(e)}}function u(e,t){this.fun=e,this.array=t}function c(){}var p,h,f=t.exports={};!function(){try{p="function"==typeof setTimeout?setTimeout:r}catch(e){p=r}try{h="function"==typeof clearTimeout?clearTimeout:i}catch(e){h=i}}();var d,m=[],g=!1,y=-1;f.nextTick=function(e){var t=new Array(arguments.length-1);if(arguments.length>1)for(var n=1;n<arguments.length;n++)t[n-1]=arguments[n];m.push(new u(e,t)),1!==m.length||g||a(l)},u.prototype.run=function(){this.fun.apply(null,this.array)},f.title="browser",f.browser=!0,f.env={},f.argv=[],f.version="",f.versions={},f.on=c,f.addListener=c,f.once=c,f.off=c,f.removeListener=c,f.removeAllListeners=c,f.emit=c,f.binding=function(e){throw new Error("process.binding is not supported")},f.cwd=function(){return"/"},f.chdir=function(e){throw new Error("process.chdir is not supported")},f.umask=function(){return 0}},{}],43:[function(e,t,n){t.exports=e("./lib/_stream_duplex.js")},{"./lib/_stream_duplex.js":44}],44:[function(e,t,n){"use strict";function r(e){return this instanceof r?(u.call(this,e),c.call(this,e),e&&e.readable===!1&&(this.readable=!1),e&&e.writable===!1&&(this.writable=!1),this.allowHalfOpen=!0,e&&e.allowHalfOpen===!1&&(this.allowHalfOpen=!1),void this.once("end",i)):new r(e)}function i(){this.allowHalfOpen||this._writableState.ended||s(a,this)}function a(e){e.end()}var o=Object.keys||function(e){var t=[];for(var n in e)t.push(n);return t};t.exports=r;var s=e("process-nextick-args"),l=e("core-util-is");l.inherits=e("inherits");var u=e("./_stream_readable"),c=e("./_stream_writable");l.inherits(r,u);for(var p=o(c.prototype),h=0;h<p.length;h++){var f=p[h];r.prototype[f]||(r.prototype[f]=c.prototype[f])}},{"./_stream_readable":46,"./_stream_writable":48,"core-util-is":6,inherits:38,"process-nextick-args":41}],45:[function(e,t,n){"use strict";function r(e){return this instanceof r?void i.call(this,e):new r(e)}t.exports=r;var i=e("./_stream_transform"),a=e("core-util-is");a.inherits=e("inherits"),a.inherits(r,i),r.prototype._transform=function(e,t,n){n(null,e)}},{"./_stream_transform":47,"core-util-is":6,inherits:38}],46:[function(e,t,n){(function(n){"use strict";function r(e,t,n){return"function"==typeof e.prependListener?e.prependListener(t,n):void(e._events&&e._events[t]?C(e._events[t])?e._events[t].unshift(n):e._events[t]=[n,e._events[t]]:e.on(t,n))}function i(t,n){N=N||e("./_stream_duplex"),t=t||{},this.objectMode=!!t.objectMode,n instanceof N&&(this.objectMode=this.objectMode||!!t.readableObjectMode);var r=t.highWaterMark,i=this.objectMode?16:16384;this.highWaterMark=r||0===r?r:i,this.highWaterMark=~~this.highWaterMark,this.buffer=new B,this.length=0,this.pipes=null,this.pipesCount=0,this.flowing=null,this.ended=!1,this.endEmitted=!1,this.reading=!1,this.sync=!0,this.needReadable=!1,this.emittedReadable=!1,this.readableListening=!1,this.resumeScheduled=!1,this.defaultEncoding=t.defaultEncoding||"utf8",this.ranOut=!1,this.awaitDrain=0,this.readingMore=!1,this.decoder=null,this.encoding=null,t.encoding&&(q||(q=e("string_decoder/").StringDecoder),this.decoder=new q(t.encoding),this.encoding=t.encoding)}function a(t){return N=N||e("./_stream_duplex"),this instanceof a?(this._readableState=new i(t,this),this.readable=!0,t&&"function"==typeof t.read&&(this._read=t.read),void I.call(this)):new a(t)}function o(e,t,n,r,i){var a=c(t,n);if(a)e.emit("error",a);else if(null===n)t.reading=!1,p(e,t);else if(t.objectMode||n&&n.length>0)if(t.ended&&!i){var o=new Error("stream.push() after EOF");e.emit("error",o)}else if(t.endEmitted&&i){var l=new Error("stream.unshift() after end event");e.emit("error",l)}else{var u;!t.decoder||i||r||(n=t.decoder.write(n),u=!t.objectMode&&0===n.length),i||(t.reading=!1),u||(t.flowing&&0===t.length&&!t.sync?(e.emit("data",n),e.read(0)):(t.length+=t.objectMode?1:n.length,i?t.buffer.unshift(n):t.buffer.push(n),t.needReadable&&h(e))),d(e,t)}else i||(t.reading=!1);return s(t)}function s(e){return!e.ended&&(e.needReadable||e.length<e.highWaterMark||0===e.length)}function l(e){return e>=z?e=z:(e--,e|=e>>>1,e|=e>>>2,e|=e>>>4,e|=e>>>8,e|=e>>>16,e++),e}function u(e,t){return e<=0||0===t.length&&t.ended?0:t.objectMode?1:e!==e?t.flowing&&t.length?t.buffer.head.data.length:t.length:(e>t.highWaterMark&&(t.highWaterMark=l(e)),e<=t.length?e:t.ended?t.length:(t.needReadable=!0,0))}function c(e,t){var n=null;return L.isBuffer(t)||"string"==typeof t||null===t||void 0===t||e.objectMode||(n=new TypeError("Invalid non-string/buffer chunk")),n}function p(e,t){if(!t.ended){if(t.decoder){var n=t.decoder.end();n&&n.length&&(t.buffer.push(n),t.length+=t.objectMode?1:n.length)}t.ended=!0,h(e)}}function h(e){var t=e._readableState;t.needReadable=!1,t.emittedReadable||(P("emitReadable",t.flowing),t.emittedReadable=!0,t.sync?T(f,e):f(e))}function f(e){P("emit readable"),e.emit("readable"),w(e)}function d(e,t){t.readingMore||(t.readingMore=!0,T(m,e,t))}function m(e,t){for(var n=t.length;!t.reading&&!t.flowing&&!t.ended&&t.length<t.highWaterMark&&(P("maybeReadMore read 0"),e.read(0),n!==t.length);)n=t.length;t.readingMore=!1}function g(e){return function(){var t=e._readableState;P("pipeOnDrain",t.awaitDrain),t.awaitDrain&&t.awaitDrain--,0===t.awaitDrain&&D(e,"data")&&(t.flowing=!0,w(e))}}function y(e){P("readable nexttick read 0"),e.read(0)}function v(e,t){t.resumeScheduled||(t.resumeScheduled=!0,T(b,e,t))}function b(e,t){t.reading||(P("resume read 0"),e.read(0)),t.resumeScheduled=!1,t.awaitDrain=0,e.emit("resume"),w(e),t.flowing&&!t.reading&&e.read(0)}function w(e){var t=e._readableState;for(P("flow",t.flowing);t.flowing&&null!==e.read(););}function _(e,t){if(0===t.length)return null;var n;return t.objectMode?n=t.buffer.shift():!e||e>=t.length?(n=t.decoder?t.buffer.join(""):1===t.buffer.length?t.buffer.head.data:t.buffer.concat(t.length),t.buffer.clear()):n=x(e,t.buffer,t.decoder),n}function x(e,t,n){var r;return e<t.head.data.length?(r=t.head.data.slice(0,e),t.head.data=t.head.data.slice(e)):r=e===t.head.data.length?t.shift():n?A(e,t):S(e,t),r}function A(e,t){var n=t.head,r=1,i=n.data;for(e-=i.length;n=n.next;){var a=n.data,o=e>a.length?a.length:e;if(i+=o===a.length?a:a.slice(0,e),e-=o,0===e){o===a.length?(++r,n.next?t.head=n.next:t.head=t.tail=null):(t.head=n,n.data=a.slice(o));break}++r}return t.length-=r,i}function S(e,t){var n=M.allocUnsafe(e),r=t.head,i=1;for(r.data.copy(n),e-=r.data.length;r=r.next;){var a=r.data,o=e>a.length?a.length:e;if(a.copy(n,n.length-e,0,o),e-=o,0===e){o===a.length?(++i,r.next?t.head=r.next:t.head=t.tail=null):(t.head=r,r.data=a.slice(o));break}++i}return t.length-=i,n}function j(e){var t=e._readableState;if(t.length>0)throw new Error('"endReadable()" called on non-empty stream');t.endEmitted||(t.ended=!0,T(E,t,e))}function E(e,t){e.endEmitted||0!==e.length||(e.endEmitted=!0,t.readable=!1,t.emit("end"))}function O(e,t){for(var n=0,r=e.length;n<r;n++)t(e[n],n)}function k(e,t){for(var n=0,r=e.length;n<r;n++)if(e[n]===t)return n;return-1}t.exports=a;var T=e("process-nextick-args"),C=e("isarray");a.ReadableState=i;var I,D=(e("events").EventEmitter,function(e,t){return e.listeners(t).length});!function(){try{I=e("stream")}catch(t){}finally{I||(I=e("events").EventEmitter)}}();var L=e("buffer").Buffer,M=e("buffer-shims"),R=e("core-util-is");R.inherits=e("inherits");var U=e("util"),P=void 0;P=U&&U.debuglog?U.debuglog("stream"):function(){};var q,B=e("./internal/streams/BufferList");R.inherits(a,I);var N,N;a.prototype.push=function(e,t){var n=this._readableState;return n.objectMode||"string"!=typeof e||(t=t||n.defaultEncoding,t!==n.encoding&&(e=M.from(e,t),t="")),o(this,n,e,t,!1)},a.prototype.unshift=function(e){var t=this._readableState;return o(this,t,e,"",!0)},a.prototype.isPaused=function(){return this._readableState.flowing===!1},a.prototype.setEncoding=function(t){return q||(q=e("string_decoder/").StringDecoder),this._readableState.decoder=new q(t),this._readableState.encoding=t,this};var z=8388608;a.prototype.read=function(e){P("read",e),e=parseInt(e,10);var t=this._readableState,n=e;if(0!==e&&(t.emittedReadable=!1),0===e&&t.needReadable&&(t.length>=t.highWaterMark||t.ended))return P("read: emitReadable",t.length,t.ended),0===t.length&&t.ended?j(this):h(this),null;if(e=u(e,t),0===e&&t.ended)return 0===t.length&&j(this),null;var r=t.needReadable;P("need readable",r),(0===t.length||t.length-e<t.highWaterMark)&&(r=!0,P("length less than watermark",r)),t.ended||t.reading?(r=!1,P("reading or ended",r)):r&&(P("do read"),t.reading=!0,t.sync=!0,0===t.length&&(t.needReadable=!0),this._read(t.highWaterMark),t.sync=!1,t.reading||(e=u(n,t)));var i;return i=e>0?_(e,t):null,null===i?(t.needReadable=!0,e=0):t.length-=e,0===t.length&&(t.ended||(t.needReadable=!0),n!==e&&t.ended&&j(this)),null!==i&&this.emit("data",i),i},a.prototype._read=function(e){this.emit("error",new Error("not implemented"))},a.prototype.pipe=function(e,t){function i(e){P("onunpipe"),e===h&&o()}function a(){P("onend"),e.end()}function o(){P("cleanup"),e.removeListener("close",u),e.removeListener("finish",c),e.removeListener("drain",y),e.removeListener("error",l),e.removeListener("unpipe",i),h.removeListener("end",a),h.removeListener("end",o),h.removeListener("data",s),v=!0,!f.awaitDrain||e._writableState&&!e._writableState.needDrain||y()}function s(t){P("ondata"),b=!1;var n=e.write(t);!1!==n||b||((1===f.pipesCount&&f.pipes===e||f.pipesCount>1&&k(f.pipes,e)!==-1)&&!v&&(P("false write response, pause",h._readableState.awaitDrain),h._readableState.awaitDrain++,b=!0),h.pause())}function l(t){P("onerror",t),p(),e.removeListener("error",l),0===D(e,"error")&&e.emit("error",t)}function u(){e.removeListener("finish",c),p()}function c(){P("onfinish"),e.removeListener("close",u),p()}function p(){P("unpipe"),h.unpipe(e)}var h=this,f=this._readableState;switch(f.pipesCount){case 0:f.pipes=e;break;case 1:f.pipes=[f.pipes,e];break;default:f.pipes.push(e)}f.pipesCount+=1,P("pipe count=%d opts=%j",f.pipesCount,t);var d=(!t||t.end!==!1)&&e!==n.stdout&&e!==n.stderr,m=d?a:o;f.endEmitted?T(m):h.once("end",m),e.on("unpipe",i);var y=g(h);e.on("drain",y);var v=!1,b=!1;return h.on("data",s),r(e,"error",l),e.once("close",u),e.once("finish",c),e.emit("pipe",h),f.flowing||(P("pipe resume"),h.resume()),e},a.prototype.unpipe=function(e){var t=this._readableState;if(0===t.pipesCount)return this;if(1===t.pipesCount)return e&&e!==t.pipes?this:(e||(e=t.pipes),t.pipes=null,t.pipesCount=0,t.flowing=!1,e&&e.emit("unpipe",this),this);if(!e){var n=t.pipes,r=t.pipesCount;t.pipes=null,t.pipesCount=0,t.flowing=!1;for(var i=0;i<r;i++)n[i].emit("unpipe",this);return this}var a=k(t.pipes,e);return a===-1?this:(t.pipes.splice(a,1),t.pipesCount-=1,1===t.pipesCount&&(t.pipes=t.pipes[0]),e.emit("unpipe",this),this)},a.prototype.on=function(e,t){var n=I.prototype.on.call(this,e,t);if("data"===e)this._readableState.flowing!==!1&&this.resume();else if("readable"===e){var r=this._readableState;r.endEmitted||r.readableListening||(r.readableListening=r.needReadable=!0,r.emittedReadable=!1,r.reading?r.length&&h(this,r):T(y,this))}return n},a.prototype.addListener=a.prototype.on,a.prototype.resume=function(){var e=this._readableState;return e.flowing||(P("resume"),e.flowing=!0,v(this,e)),this},a.prototype.pause=function(){return P("call pause flowing=%j",this._readableState.flowing),!1!==this._readableState.flowing&&(P("pause"),this._readableState.flowing=!1,this.emit("pause")),this},a.prototype.wrap=function(e){var t=this._readableState,n=!1,r=this;e.on("end",function(){if(P("wrapped end"),t.decoder&&!t.ended){var e=t.decoder.end();e&&e.length&&r.push(e)}r.push(null)}),e.on("data",function(i){if(P("wrapped data"),t.decoder&&(i=t.decoder.write(i)),(!t.objectMode||null!==i&&void 0!==i)&&(t.objectMode||i&&i.length)){var a=r.push(i);a||(n=!0,e.pause())}});for(var i in e)void 0===this[i]&&"function"==typeof e[i]&&(this[i]=function(t){return function(){return e[t].apply(e,arguments)}}(i));var a=["error","close","destroy","pause","resume"];return O(a,function(t){e.on(t,r.emit.bind(r,t))}),r._read=function(t){P("wrapped _read",t),n&&(n=!1,e.resume())},r},a._fromList=_}).call(this,e("_process"))},{"./_stream_duplex":44,"./internal/streams/BufferList":49,_process:42,buffer:5,"buffer-shims":4,"core-util-is":6,events:28,inherits:38,isarray:40,"process-nextick-args":41,"string_decoder/":56,util:3}],47:[function(e,t,n){"use strict";function r(e){this.afterTransform=function(t,n){return i(e,t,n)},this.needTransform=!1,this.transforming=!1,this.writecb=null,this.writechunk=null,this.writeencoding=null}function i(e,t,n){var r=e._transformState;r.transforming=!1;var i=r.writecb;if(!i)return e.emit("error",new Error("no writecb in Transform class"));r.writechunk=null,r.writecb=null,null!==n&&void 0!==n&&e.push(n),i(t);var a=e._readableState;a.reading=!1,(a.needReadable||a.length<a.highWaterMark)&&e._read(a.highWaterMark)}function a(e){if(!(this instanceof a))return new a(e);s.call(this,e),this._transformState=new r(this);var t=this;this._readableState.needReadable=!0,this._readableState.sync=!1,e&&("function"==typeof e.transform&&(this._transform=e.transform),"function"==typeof e.flush&&(this._flush=e.flush)),this.once("prefinish",function(){"function"==typeof this._flush?this._flush(function(e){o(t,e)}):o(t)})}function o(e,t){if(t)return e.emit("error",t);var n=e._writableState,r=e._transformState;if(n.length)throw new Error("Calling transform done when ws.length != 0");if(r.transforming)throw new Error("Calling transform done when still transforming");return e.push(null)}t.exports=a;var s=e("./_stream_duplex"),l=e("core-util-is");l.inherits=e("inherits"),l.inherits(a,s),a.prototype.push=function(e,t){return this._transformState.needTransform=!1,s.prototype.push.call(this,e,t)},a.prototype._transform=function(e,t,n){throw new Error("Not implemented")},a.prototype._write=function(e,t,n){var r=this._transformState;if(r.writecb=n,r.writechunk=e,r.writeencoding=t,!r.transforming){var i=this._readableState;(r.needTransform||i.needReadable||i.length<i.highWaterMark)&&this._read(i.highWaterMark)}},a.prototype._read=function(e){var t=this._transformState;null!==t.writechunk&&t.writecb&&!t.transforming?(t.transforming=!0,this._transform(t.writechunk,t.writeencoding,t.afterTransform)):t.needTransform=!0}},{"./_stream_duplex":44,"core-util-is":6,inherits:38}],48:[function(e,t,n){(function(n){"use strict";function r(){}function i(e,t,n){this.chunk=e,this.encoding=t,this.callback=n,this.next=null}function a(t,n){C=C||e("./_stream_duplex"),t=t||{},this.objectMode=!!t.objectMode,n instanceof C&&(this.objectMode=this.objectMode||!!t.writableObjectMode);var r=t.highWaterMark,i=this.objectMode?16:16384;this.highWaterMark=r||0===r?r:i,this.highWaterMark=~~this.highWaterMark,this.needDrain=!1,this.ending=!1,this.ended=!1,this.finished=!1;var a=t.decodeStrings===!1;this.decodeStrings=!a,this.defaultEncoding=t.defaultEncoding||"utf8",this.length=0,this.writing=!1,this.corked=0,this.sync=!0,this.bufferProcessing=!1,this.onwrite=function(e){d(n,e)},this.writecb=null,this.writelen=0,this.bufferedRequest=null,this.lastBufferedRequest=null,this.pendingcb=0,this.prefinished=!1,this.errorEmitted=!1,this.bufferedRequestCount=0,this.corkedRequestsFree=new x(this)}function o(t){return C=C||e("./_stream_duplex"),this instanceof o||this instanceof C?(this._writableState=new a(t,this),this.writable=!0,t&&("function"==typeof t.write&&(this._write=t.write),"function"==typeof t.writev&&(this._writev=t.writev)),void E.call(this)):new o(t)}function s(e,t){var n=new Error("write after end");e.emit("error",n),A(t,n)}function l(e,t,n,r){var i=!0,a=!1;return null===n?a=new TypeError("May not write null values to stream"):k.isBuffer(n)||"string"==typeof n||void 0===n||t.objectMode||(a=new TypeError("Invalid non-string/buffer chunk")),a&&(e.emit("error",a),A(r,a),i=!1),i}function u(e,t,n){return e.objectMode||e.decodeStrings===!1||"string"!=typeof t||(t=T.from(t,n)),t}function c(e,t,n,r,a){n=u(t,n,r),k.isBuffer(n)&&(r="buffer");var o=t.objectMode?1:n.length;t.length+=o;var s=t.length<t.highWaterMark;if(s||(t.needDrain=!0),t.writing||t.corked){var l=t.lastBufferedRequest;t.lastBufferedRequest=new i(n,r,a),l?l.next=t.lastBufferedRequest:t.bufferedRequest=t.lastBufferedRequest,t.bufferedRequestCount+=1}else p(e,t,!1,o,n,r,a);return s}function p(e,t,n,r,i,a,o){t.writelen=r,t.writecb=o,t.writing=!0,t.sync=!0,n?e._writev(i,t.onwrite):e._write(i,a,t.onwrite),t.sync=!1}function h(e,t,n,r,i){--t.pendingcb,n?A(i,r):i(r),e._writableState.errorEmitted=!0,e.emit("error",r)}function f(e){e.writing=!1,e.writecb=null,e.length-=e.writelen,e.writelen=0}function d(e,t){var n=e._writableState,r=n.sync,i=n.writecb;if(f(n),t)h(e,n,r,t,i);else{var a=v(n);a||n.corked||n.bufferProcessing||!n.bufferedRequest||y(e,n),r?S(m,e,n,a,i):m(e,n,a,i)}}function m(e,t,n,r){n||g(e,t),t.pendingcb--,r(),w(e,t)}function g(e,t){0===t.length&&t.needDrain&&(t.needDrain=!1,e.emit("drain"))}function y(e,t){t.bufferProcessing=!0;var n=t.bufferedRequest;if(e._writev&&n&&n.next){var r=t.bufferedRequestCount,i=new Array(r),a=t.corkedRequestsFree;a.entry=n;for(var o=0;n;)i[o]=n,n=n.next,o+=1;p(e,t,!0,t.length,i,"",a.finish),t.pendingcb++,t.lastBufferedRequest=null,a.next?(t.corkedRequestsFree=a.next,a.next=null):t.corkedRequestsFree=new x(t)}else{for(;n;){var s=n.chunk,l=n.encoding,u=n.callback,c=t.objectMode?1:s.length;if(p(e,t,!1,c,s,l,u),n=n.next,t.writing)break}null===n&&(t.lastBufferedRequest=null)}t.bufferedRequestCount=0,t.bufferedRequest=n,t.bufferProcessing=!1}function v(e){return e.ending&&0===e.length&&null===e.bufferedRequest&&!e.finished&&!e.writing}function b(e,t){t.prefinished||(t.prefinished=!0,e.emit("prefinish"))}function w(e,t){var n=v(t);return n&&(0===t.pendingcb?(b(e,t),t.finished=!0,e.emit("finish")):b(e,t)),n}function _(e,t,n){t.ending=!0,w(e,t),n&&(t.finished?A(n):e.once("finish",n)),t.ended=!0,e.writable=!1}function x(e){var t=this;this.next=null,this.entry=null,this.finish=function(n){var r=t.entry;for(t.entry=null;r;){var i=r.callback;e.pendingcb--,i(n),r=r.next}e.corkedRequestsFree?e.corkedRequestsFree.next=t:e.corkedRequestsFree=t}}t.exports=o;var A=e("process-nextick-args"),S=!n.browser&&["v0.10","v0.9."].indexOf(n.version.slice(0,5))>-1?setImmediate:A;o.WritableState=a;var j=e("core-util-is");j.inherits=e("inherits");var E,O={deprecate:e("util-deprecate")};!function(){try{E=e("stream")}catch(t){}finally{E||(E=e("events").EventEmitter)}}();var k=e("buffer").Buffer,T=e("buffer-shims");j.inherits(o,E);var C;a.prototype.getBuffer=function(){for(var e=this.bufferedRequest,t=[];e;)t.push(e),e=e.next;return t},function(){try{Object.defineProperty(a.prototype,"buffer",{get:O.deprecate(function(){return this.getBuffer()},"_writableState.buffer is deprecated. Use _writableState.getBuffer instead.")})}catch(e){}}();var C;o.prototype.pipe=function(){this.emit("error",new Error("Cannot pipe, not readable"))},o.prototype.write=function(e,t,n){var i=this._writableState,a=!1;return"function"==typeof t&&(n=t,t=null),k.isBuffer(e)?t="buffer":t||(t=i.defaultEncoding),"function"!=typeof n&&(n=r),i.ended?s(this,n):l(this,i,e,n)&&(i.pendingcb++,a=c(this,i,e,t,n)),a},o.prototype.cork=function(){var e=this._writableState;e.corked++},o.prototype.uncork=function(){var e=this._writableState;e.corked&&(e.corked--,e.writing||e.corked||e.finished||e.bufferProcessing||!e.bufferedRequest||y(this,e))},o.prototype.setDefaultEncoding=function(e){if("string"==typeof e&&(e=e.toLowerCase()),!(["hex","utf8","utf-8","ascii","binary","base64","ucs2","ucs-2","utf16le","utf-16le","raw"].indexOf((e+"").toLowerCase())>-1))throw new TypeError("Unknown encoding: "+e);
-return this._writableState.defaultEncoding=e,this},o.prototype._write=function(e,t,n){n(new Error("not implemented"))},o.prototype._writev=null,o.prototype.end=function(e,t,n){var r=this._writableState;"function"==typeof e?(n=e,e=null,t=null):"function"==typeof t&&(n=t,t=null),null!==e&&void 0!==e&&this.write(e,t),r.corked&&(r.corked=1,this.uncork()),r.ending||r.finished||_(this,r,n)}}).call(this,e("_process"))},{"./_stream_duplex":44,_process:42,buffer:5,"buffer-shims":4,"core-util-is":6,events:28,inherits:38,"process-nextick-args":41,"util-deprecate":57}],49:[function(e,t,n){"use strict";function r(){this.head=null,this.tail=null,this.length=0}var i=(e("buffer").Buffer,e("buffer-shims"));t.exports=r,r.prototype.push=function(e){var t={data:e,next:null};this.length>0?this.tail.next=t:this.head=t,this.tail=t,++this.length},r.prototype.unshift=function(e){var t={data:e,next:this.head};0===this.length&&(this.tail=t),this.head=t,++this.length},r.prototype.shift=function(){if(0!==this.length){var e=this.head.data;return 1===this.length?this.head=this.tail=null:this.head=this.head.next,--this.length,e}},r.prototype.clear=function(){this.head=this.tail=null,this.length=0},r.prototype.join=function(e){if(0===this.length)return"";for(var t=this.head,n=""+t.data;t=t.next;)n+=e+t.data;return n},r.prototype.concat=function(e){if(0===this.length)return i.alloc(0);if(1===this.length)return this.head.data;for(var t=i.allocUnsafe(e>>>0),n=this.head,r=0;n;)n.data.copy(t,r),r+=n.data.length,n=n.next;return t}},{buffer:5,"buffer-shims":4}],50:[function(e,t,n){t.exports=e("./lib/_stream_passthrough.js")},{"./lib/_stream_passthrough.js":45}],51:[function(e,t,n){(function(r){var i=function(){try{return e("stream")}catch(t){}}();n=t.exports=e("./lib/_stream_readable.js"),n.Stream=i||n,n.Readable=n,n.Writable=e("./lib/_stream_writable.js"),n.Duplex=e("./lib/_stream_duplex.js"),n.Transform=e("./lib/_stream_transform.js"),n.PassThrough=e("./lib/_stream_passthrough.js"),!r.browser&&"disable"===r.env.READABLE_STREAM&&i&&(t.exports=i)}).call(this,e("_process"))},{"./lib/_stream_duplex.js":44,"./lib/_stream_passthrough.js":45,"./lib/_stream_readable.js":46,"./lib/_stream_transform.js":47,"./lib/_stream_writable.js":48,_process:42}],52:[function(e,t,n){t.exports=e("./lib/_stream_transform.js")},{"./lib/_stream_transform.js":47}],53:[function(e,t,n){t.exports=e("./lib/_stream_writable.js")},{"./lib/_stream_writable.js":48}],54:[function(e,t,n){t.exports=function(e){return e.replace(/[-\\^$*+?.()|[\]{}]/g,"\\$&")}},{}],55:[function(e,t,n){function r(){i.call(this)}t.exports=r;var i=e("events").EventEmitter,a=e("inherits");a(r,i),r.Readable=e("readable-stream/readable.js"),r.Writable=e("readable-stream/writable.js"),r.Duplex=e("readable-stream/duplex.js"),r.Transform=e("readable-stream/transform.js"),r.PassThrough=e("readable-stream/passthrough.js"),r.Stream=r,r.prototype.pipe=function(e,t){function n(t){e.writable&&!1===e.write(t)&&u.pause&&u.pause()}function r(){u.readable&&u.resume&&u.resume()}function a(){c||(c=!0,e.end())}function o(){c||(c=!0,"function"==typeof e.destroy&&e.destroy())}function s(e){if(l(),0===i.listenerCount(this,"error"))throw e}function l(){u.removeListener("data",n),e.removeListener("drain",r),u.removeListener("end",a),u.removeListener("close",o),u.removeListener("error",s),e.removeListener("error",s),u.removeListener("end",l),u.removeListener("close",l),e.removeListener("close",l)}var u=this;u.on("data",n),e.on("drain",r),e._isStdio||t&&t.end===!1||(u.on("end",a),u.on("close",o));var c=!1;return u.on("error",s),e.on("error",s),u.on("end",l),u.on("close",l),e.on("close",l),e.emit("pipe",u),e}},{events:28,inherits:38,"readable-stream/duplex.js":43,"readable-stream/passthrough.js":50,"readable-stream/readable.js":51,"readable-stream/transform.js":52,"readable-stream/writable.js":53}],56:[function(e,t,n){function r(e){if(e&&!l(e))throw new Error("Unknown encoding: "+e)}function i(e){return e.toString(this.encoding)}function a(e){this.charReceived=e.length%2,this.charLength=this.charReceived?2:0}function o(e){this.charReceived=e.length%3,this.charLength=this.charReceived?3:0}var s=e("buffer").Buffer,l=s.isEncoding||function(e){switch(e&&e.toLowerCase()){case"hex":case"utf8":case"utf-8":case"ascii":case"binary":case"base64":case"ucs2":case"ucs-2":case"utf16le":case"utf-16le":case"raw":return!0;default:return!1}},u=n.StringDecoder=function(e){switch(this.encoding=(e||"utf8").toLowerCase().replace(/[-_]/,""),r(e),this.encoding){case"utf8":this.surrogateSize=3;break;case"ucs2":case"utf16le":this.surrogateSize=2,this.detectIncompleteChar=a;break;case"base64":this.surrogateSize=3,this.detectIncompleteChar=o;break;default:return void(this.write=i)}this.charBuffer=new s(6),this.charReceived=0,this.charLength=0};u.prototype.write=function(e){for(var t="";this.charLength;){var n=e.length>=this.charLength-this.charReceived?this.charLength-this.charReceived:e.length;if(e.copy(this.charBuffer,this.charReceived,0,n),this.charReceived+=n,this.charReceived<this.charLength)return"";e=e.slice(n,e.length),t=this.charBuffer.slice(0,this.charLength).toString(this.encoding);var r=t.charCodeAt(t.length-1);if(!(r>=55296&&r<=56319)){if(this.charReceived=this.charLength=0,0===e.length)return t;break}this.charLength+=this.surrogateSize,t=""}this.detectIncompleteChar(e);var i=e.length;this.charLength&&(e.copy(this.charBuffer,0,e.length-this.charReceived,i),i-=this.charReceived),t+=e.toString(this.encoding,0,i);var i=t.length-1,r=t.charCodeAt(i);if(r>=55296&&r<=56319){var a=this.surrogateSize;return this.charLength+=a,this.charReceived+=a,this.charBuffer.copy(this.charBuffer,a,0,a),e.copy(this.charBuffer,0,0,a),t.substring(0,i)}return t},u.prototype.detectIncompleteChar=function(e){for(var t=e.length>=3?3:e.length;t>0;t--){var n=e[e.length-t];if(1==t&&n>>5==6){this.charLength=2;break}if(t<=2&&n>>4==14){this.charLength=3;break}if(t<=3&&n>>3==30){this.charLength=4;break}}this.charReceived=t},u.prototype.end=function(e){var t="";if(e&&e.length&&(t=this.write(e)),this.charReceived){var n=this.charReceived,r=this.charBuffer,i=this.encoding;t+=r.slice(0,n).toString(i)}return t}},{buffer:5}],57:[function(e,t,n){(function(e){function n(e,t){function n(){if(!i){if(r("throwDeprecation"))throw new Error(t);r("traceDeprecation")?console.trace(t):console.warn(t),i=!0}return e.apply(this,arguments)}if(r("noDeprecation"))return e;var i=!1;return n}function r(t){try{if(!e.localStorage)return!1}catch(n){return!1}var r=e.localStorage[t];return null!=r&&"true"===String(r).toLowerCase()}t.exports=n}).call(this,"undefined"!=typeof global?global:"undefined"!=typeof self?self:"undefined"!=typeof window?window:{})},{}],58:[function(e,t,n){function r(){for(var e={},t=0;t<arguments.length;t++){var n=arguments[t];for(var r in n)i.call(n,r)&&(e[r]=n[r])}return e}t.exports=r;var i=Object.prototype.hasOwnProperty},{}]},{},[1])(1)}),function(e){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=e();else if("function"==typeof define&&define.amd)define([],e);else{var t;t="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:this,t.SwaggerClient=e()}}(function(){var t;return function n(e,t,r){function i(o,s){if(!t[o]){if(!e[o]){var l="function"==typeof require&&require;if(!s&&l)return l(o,!0);if(a)return a(o,!0);var u=new Error("Cannot find module '"+o+"'");throw u.code="MODULE_NOT_FOUND",u}var c=t[o]={exports:{}};e[o][0].call(c.exports,function(t){var n=e[o][1][t];return i(n?n:t)},c,c.exports,n,e,t,r)}return t[o].exports}for(var a="function"==typeof require&&require,o=0;o<r.length;o++)i(r[o]);return i}({1:[function(e,t,n){"use strict";var r=e("./lib/auth"),i=e("./lib/helpers"),a=e("./lib/client"),o=function(e,t){return i.log('This is deprecated, use "new SwaggerClient" instead.'),new a(e,t)};Array.prototype.indexOf||(Array.prototype.indexOf=function(e,t){for(var n=t||0,r=this.length;n<r;n++)if(this[n]===e)return n;return-1}),String.prototype.trim||(String.prototype.trim=function(){return this.replace(/^\s+|\s+$/g,"")}),String.prototype.endsWith||(String.prototype.endsWith=function(e){return this.indexOf(e,this.length-e.length)!==-1}),t.exports=a,a.ApiKeyAuthorization=r.ApiKeyAuthorization,a.PasswordAuthorization=r.PasswordAuthorization,a.CookieAuthorization=r.CookieAuthorization,a.SwaggerApi=o,a.SwaggerClient=o,a.SchemaMarkup=e("./lib/schema-markup")},{"./lib/auth":2,"./lib/client":3,"./lib/helpers":4,"./lib/schema-markup":7}],2:[function(e,t,n){"use strict";var r=e("./helpers"),i=e("btoa"),a=e("cookiejar").CookieJar,o={each:e("lodash-compat/collection/each"),includes:e("lodash-compat/collection/includes"),isObject:e("lodash-compat/lang/isObject"),isArray:e("lodash-compat/lang/isArray")},s=t.exports.SwaggerAuthorizations=function(e){this.authz=e||{}};s.prototype.add=function(e,t){if(o.isObject(e))for(var n in e)this.authz[n]=e[n];else"string"==typeof e&&(this.authz[e]=t);return t},s.prototype.remove=function(e){return delete this.authz[e]},s.prototype.apply=function(e,t){var n=!0,r=!t,i=[],a=e.clientAuthorizations||this.authz;return o.each(t,function(e,t){"string"==typeof t&&i.push(t),o.each(e,function(e,t){i.push(t)})}),o.each(a,function(t,a){if(r||o.includes(i,a)){var s=t.apply(e);n=n&&!!s}}),n};var l=t.exports.ApiKeyAuthorization=function(e,t,n){this.name=e,this.value=t,this.type=n};l.prototype.apply=function(e){if("query"===this.type){var t;if(e.url.indexOf("?")>0){t=e.url.substring(e.url.indexOf("?")+1);var n=t.split("&");if(n&&n.length>0)for(var r=0;r<n.length;r++){var i=n[r].split("=");if(i&&i.length>0&&i[0]===this.name)return!1}}return e.url.indexOf("?")>0?e.url=e.url+"&"+this.name+"="+this.value:e.url=e.url+"?"+this.name+"="+this.value,!0}if("header"===this.type)return"undefined"==typeof e.headers[this.name]&&(e.headers[this.name]=this.value),!0};var u=t.exports.CookieAuthorization=function(e){this.cookie=e};u.prototype.apply=function(e){return e.cookieJar=e.cookieJar||new a,e.cookieJar.setCookie(this.cookie),!0};var c=t.exports.PasswordAuthorization=function(e,t){3===arguments.length&&(r.log("PasswordAuthorization: the 'name' argument has been removed, pass only username and password"),e=arguments[1],t=arguments[2]),this.username=e,this.password=t};c.prototype.apply=function(e){return"undefined"==typeof e.headers.Authorization&&(e.headers.Authorization="Basic "+i(this.username+":"+this.password)),!0}},{"./helpers":4,btoa:13,cookiejar:18,"lodash-compat/collection/each":52,"lodash-compat/collection/includes":55,"lodash-compat/lang/isArray":140,"lodash-compat/lang/isObject":144}],3:[function(e,t,n){"use strict";var r={bind:e("lodash-compat/function/bind"),cloneDeep:e("lodash-compat/lang/cloneDeep"),find:e("lodash-compat/collection/find"),forEach:e("lodash-compat/collection/forEach"),indexOf:e("lodash-compat/array/indexOf"),isArray:e("lodash-compat/lang/isArray"),isObject:e("lodash-compat/lang/isObject"),isFunction:e("lodash-compat/lang/isFunction"),isPlainObject:e("lodash-compat/lang/isPlainObject"),isUndefined:e("lodash-compat/lang/isUndefined")},i=e("./auth"),a=e("./helpers"),o=e("./types/model"),s=e("./types/operation"),l=e("./types/operationGroup"),u=e("./resolver"),c=e("./http"),p=e("./spec-converter"),h=e("q"),f=["apis","authorizationScheme","authorizations","basePath","build","buildFrom1_1Spec","buildFrom1_2Spec","buildFromSpec","clientAuthorizations","convertInfo","debug","defaultErrorCallback","defaultSuccessCallback","enableCookies","fail","failure","finish","help","host","idFromOp","info","initialize","isBuilt","isValid","modelPropertyMacro","models","modelsArray","options","parameterMacro","parseUri","progress","resourceCount","sampleModels","selfReflect","setConsolidatedModels","spec","supportedSubmitMethods","swaggerRequestHeaders","tagFromLabel","title","url","useJQuery","jqueryAjaxCache"],d=["apis","asCurl","description","externalDocs","help","label","name","operation","operations","operationsArray","path","tag"],m=["delete","get","head","options","patch","post","put"],g=t.exports=function(e,t){return this.authorizations=null,this.authorizationScheme=null,this.basePath=null,this.debug=!1,this.enableCookies=!1,this.info=null,this.isBuilt=!1,this.isValid=!1,this.modelsArray=[],this.resourceCount=0,this.url=null,this.useJQuery=!1,this.jqueryAjaxCache=!1,this.swaggerObject={},this.deferredClient=void 0,this.clientAuthorizations=new i.SwaggerAuthorizations,"undefined"!=typeof e?this.initialize(e,t):this};g.prototype.initialize=function(e,t){if(this.models={},this.sampleModels={},"string"==typeof e?this.url=e:r.isObject(e)&&(t=e,this.url=t.url),this.url&&this.url.indexOf("http:")===-1&&this.url.indexOf("https:")===-1&&"undefined"!=typeof window&&window&&window.location&&(this.url=window.location.origin+this.url),t=t||{},this.clientAuthorizations.add(t.authorizations),this.swaggerRequestHeaders=t.swaggerRequestHeaders||"application/json;charset=utf-8,*/*",this.defaultSuccessCallback=t.defaultSuccessCallback||null,this.defaultErrorCallback=t.defaultErrorCallback||null,this.modelPropertyMacro=t.modelPropertyMacro||null,this.parameterMacro=t.parameterMacro||null,this.usePromise=t.usePromise||null,this.usePromise&&(this.deferredClient=h.defer()),"function"==typeof t.success&&(this.success=t.success),t.useJQuery&&(this.useJQuery=t.useJQuery),t.jqueryAjaxCache&&(this.jqueryAjaxCache=t.jqueryAjaxCache),t.enableCookies&&(this.enableCookies=t.enableCookies),this.options=t||{},this.supportedSubmitMethods=t.supportedSubmitMethods||[],this.failure=t.failure||function(e){throw e},this.progress=t.progress||function(){},this.spec=r.cloneDeep(t.spec),t.scheme&&(this.scheme=t.scheme),this.usePromise||"function"==typeof t.success)return this.ready=!0,this.build()},g.prototype.build=function(e){if(this.isBuilt)return this;var t=this;this.spec?this.progress("fetching resource list; Please wait."):this.progress("fetching resource list: "+this.url+"; Please wait.");var n={useJQuery:this.useJQuery,jqueryAjaxCache:this.jqueryAjaxCache,url:this.url,method:"get",headers:{accept:this.swaggerRequestHeaders},on:{error:function(e){return"http"!==t.url.substring(0,4)?t.fail("Please specify the protocol for "+t.url):0===e.status?t.fail("Can't read from server. It may not have the appropriate access-control-origin settings."):404===e.status?t.fail("Can't read swagger JSON from "+t.url):t.fail(e.status+" : "+e.statusText+" "+t.url)},response:function(e){var n=e.obj;if(!n)return t.fail("failed to parse JSON/YAML response");if(t.swaggerVersion=n.swaggerVersion,t.swaggerObject=n,n.swagger&&2===parseInt(n.swagger))t.swaggerVersion=n.swagger,(new u).resolve(n,t.url,t.buildFromSpec,t),t.isValid=!0;else{var r=new p;t.oldSwaggerObject=t.swaggerObject,r.setDocumentationLocation(t.url),r.convert(n,t.clientAuthorizations,t.options,function(e){t.swaggerObject=e,(new u).resolve(e,t.url,t.buildFromSpec,t),t.isValid=!0})}}}};if(this.spec)t.swaggerObject=this.spec,setTimeout(function(){(new u).resolve(t.spec,t.url,t.buildFromSpec,t)},10);else{if(this.clientAuthorizations.apply(n),e)return n;(new c).execute(n,this.options)}return this.usePromise?this.deferredClient.promise:this},g.prototype.buildFromSpec=function(e){if(this.isBuilt)return this;this.apis={},this.apisArray=[],this.basePath=e.basePath||"",this.consumes=e.consumes,this.host=e.host||"",this.info=e.info||{},this.produces=e.produces,this.schemes=e.schemes||[],this.securityDefinitions=e.securityDefinitions,this.security=e.security,this.title=e.title||"",e.externalDocs&&(this.externalDocs=e.externalDocs),this.authSchemes=e.securityDefinitions;var t,n={};if(Array.isArray(e.tags))for(n={},t=0;t<e.tags.length;t++){var i=e.tags[t];n[i.name]=i}var u;"string"==typeof this.url?(u=this.parseUri(this.url),"undefined"==typeof this.scheme&&"undefined"==typeof this.schemes||0===this.schemes.length?this.scheme=u.scheme||"http":"undefined"==typeof this.scheme&&(this.scheme=this.schemes[0]||u.scheme),"undefined"!=typeof this.host&&""!==this.host||(this.host=u.host,u.port&&(this.host=this.host+":"+u.port))):"undefined"==typeof this.schemes||0===this.schemes.length?this.scheme="http":"undefined"==typeof this.scheme&&(this.scheme=this.schemes[0]),this.definitions=e.definitions;var c;for(c in this.definitions){var p=new o(c,this.definitions[c],this.models,this.modelPropertyMacro);p&&(this.models[c]=p)}var h=this;h.apis.help=r.bind(h.help,h),r.forEach(e.paths,function(e,t){r.isPlainObject(e)&&r.forEach(m,function(i){var o=e[i];if(!r.isUndefined(o)){if(!r.isPlainObject(o))return void a.log("The '"+i+"' operation for '"+t+"' path is not an Operation Object");var u=o.tags;!r.isUndefined(u)&&r.isArray(u)&&0!==u.length||(u=o.tags=["default"]);var c=h.idFromOp(t,i,o),p=new s(h,o.scheme,c,i,t,o,h.definitions,h.models,h.clientAuthorizations);r.forEach(u,function(e){var t=r.indexOf(f,e)>-1?"_"+e:e,i=r.indexOf(d,e)>-1?"_"+e:e,o=h[t];if(t!==e&&a.log("The '"+e+"' tag conflicts with a SwaggerClient function/property name. Use 'client."+t+"' or 'client.apis."+e+"' instead of 'client."+e+"'."),i!==e&&a.log("The '"+e+"' tag conflicts with a SwaggerClient operation function/property name. Use 'client.apis."+i+"' instead of 'client.apis."+e+"'."),r.indexOf(d,c)>-1&&(a.log("The '"+c+"' operationId conflicts with a SwaggerClient operation function/property name. Use 'client.apis."+i+"._"+c+"' instead of 'client.apis."+i+"."+c+"'."),c="_"+c,p.nickname=c),r.isUndefined(o)){o=h[t]=h.apis[i]={},o.operations={},o.label=i,o.apis={};var s=n[e];r.isUndefined(s)||(o.description=s.description,o.externalDocs=s.externalDocs),h[t].help=r.bind(h.help,o),h.apisArray.push(new l(e,o.description,o.externalDocs,p))}c=h.makeUniqueOperationId(c,h.apis[i]),r.isFunction(o.help)||(o.help=r.bind(h.help,o)),h.apis[i][c]=o[c]=r.bind(p.execute,p),h.apis[i][c].help=o[c].help=r.bind(p.help,p),h.apis[i][c].asCurl=o[c].asCurl=r.bind(p.asCurl,p),o.apis[c]=o.operations[c]=p;var u=r.find(h.apisArray,function(t){return t.tag===e});u&&u.operationsArray.push(p)})}})});var g=[];return r.forEach(Object.keys(n),function(e){var t;for(t in h.apisArray){var n=h.apisArray[t];n&&e===n.name&&(g.push(n),h.apisArray[t]=null)}}),r.forEach(h.apisArray,function(e){e&&g.push(e)}),h.apisArray=g,r.forEach(e.definitions,function(e,t){e.id=t.toLowerCase(),e.name=t,h.modelsArray.push(e)}),this.isBuilt=!0,this.usePromise?(this.isValid=!0,this.isBuilt=!0,this.deferredClient.resolve(this),this.deferredClient.promise):(this.success&&this.success(),this)},g.prototype.makeUniqueOperationId=function(e,t){for(var n=0,i=e;;){var a=!1;if(r.forEach(t.operations,function(e){e.nickname===i&&(a=!0)}),!a)return i;i=e+"_"+n,n++}return e},g.prototype.parseUri=function(e){var t=/^(((([^:\/#\?]+:)?(?:(\/\/)((?:(([^:@\/#\?]+)(?:\:([^:@\/#\?]+))?)@)?(([^:\/#\?\]\[]+|\[[^\/\]@#?]+\])(?:\:([0-9]+))?))?)?)?((\/?(?:[^\/\?#]+\/+)*)([^\?#]*)))?(\?[^#]+)?)(#.*)?/,n=t.exec(e);return{scheme:n[4]?n[4].replace(":",""):void 0,host:n[11],port:n[12],path:n[15]}},g.prototype.help=function(e){var t="";return this instanceof g?r.forEach(this.apis,function(e,n){r.isPlainObject(e)&&(t+="operations for the '"+n+"' tag\n",r.forEach(e.operations,function(e,n){t+=" * "+n+": "+e.summary+"\n"}))}):(this instanceof l||r.isPlainObject(this))&&(t+="operations for the '"+this.label+"' tag\n",r.forEach(this.apis,function(e,n){t+=" * "+n+": "+e.summary+"\n"})),e?t:(a.log(t),t)},g.prototype.tagFromLabel=function(e){return e},g.prototype.idFromOp=function(e,t,n){n&&n.operationId||(n=n||{},n.operationId=t+"_"+e);var r=n.operationId.replace(/[\s!@#$%^&*()_+=\[{\]};:<>|.\/?,\\'""-]/g,"_")||e.substring(1)+"_"+t;return r=r.replace(/((_){2,})/g,"_"),r=r.replace(/^(_)*/g,""),r=r.replace(/([_])*$/g,"")},g.prototype.setHost=function(e){this.host=e,this.apis&&r.forEach(this.apis,function(t){t.operations&&r.forEach(t.operations,function(t){t.host=e})})},g.prototype.setBasePath=function(e){this.basePath=e,this.apis&&r.forEach(this.apis,function(t){t.operations&&r.forEach(t.operations,function(t){t.basePath=e})})},g.prototype.setSchemes=function(e){this.schemes=e,e&&e.length>0&&this.apis&&r.forEach(this.apis,function(t){t.operations&&r.forEach(t.operations,function(t){t.scheme=e[0]})})},g.prototype.fail=function(e){return this.usePromise?(this.deferredClient.reject(e),this.deferredClient.promise):void(this.failure?this.failure(e):this.failure(e))}},{"./auth":2,"./helpers":4,"./http":5,"./resolver":6,"./spec-converter":8,"./types/model":9,"./types/operation":10,"./types/operationGroup":11,"lodash-compat/array/indexOf":49,"lodash-compat/collection/find":53,"lodash-compat/collection/forEach":54,"lodash-compat/function/bind":58,"lodash-compat/lang/cloneDeep":138,"lodash-compat/lang/isArray":140,"lodash-compat/lang/isFunction":142,"lodash-compat/lang/isObject":144,"lodash-compat/lang/isPlainObject":145,"lodash-compat/lang/isUndefined":148,q:157}],4:[function(e,t,n){(function(n){"use strict";var r={isPlainObject:e("lodash-compat/lang/isPlainObject"),indexOf:e("lodash-compat/array/indexOf")};t.exports.__bind=function(e,t){return function(){return e.apply(t,arguments)}};var i=t.exports.log=function(){console&&"test"!==n.env.NODE_ENV&&console.log(Array.prototype.slice.call(arguments)[0])};t.exports.fail=function(e){i(e)};var a=(t.exports.optionHtml=function(e,t){return'<tr><td class="optionName">'+e+":</td><td>"+t+"</td></tr>"},t.exports.resolveSchema=function(e){return r.isPlainObject(e.schema)&&(e=a(e.schema)),e});t.exports.simpleRef=function(e){return"undefined"==typeof e?null:0===e.indexOf("#/definitions/")?e.substring("#/definitions/".length):e}}).call(this,e("_process"))},{_process:12,"lodash-compat/array/indexOf":49,"lodash-compat/lang/isPlainObject":145}],5:[function(t,n,r){"use strict";var i=t("./helpers"),a=t("superagent"),o=t("js-yaml"),s={isObject:t("lodash-compat/lang/isObject"),keys:t("lodash-compat/object/keys")},l=function(){this.type="JQueryHttpClient"},u=function(){this.type="SuperagentHttpClient"},c=n.exports=function(){};c.prototype.execute=function(t,n){var r;r=n&&n.client?n.client:new u(n),r.opts=n||{};var i=!1;if("undefined"!=typeof window&&"undefined"!=typeof window.jQuery&&(i=!0),"options"===t.method.toLowerCase()&&"SuperagentHttpClient"===r.type&&(e("forcing jQuery as OPTIONS are not supported by SuperAgent"),t.useJQuery=!0),this.isInternetExplorer()&&(t.useJQuery===!1||!i))throw new Error("Unsupported configuration! JQuery is required but not available");(t&&t.useJQuery===!0||this.isInternetExplorer()&&i)&&(r=new l(n));var a=t.on.response,o=t.on.error,c=function(e){return n&&n.requestInterceptor&&(e=n.requestInterceptor.apply(e)),e},p=function(e){return n&&n.responseInterceptor&&(e=n.responseInterceptor.apply(e)),a(e)},h=function(e){n&&n.responseInterceptor&&(e=n.responseInterceptor.apply(e)),o(e)};return t.on.error=function(e){h(e)},t.on.response=function(e){p(e)},s.isObject(t)&&s.isObject(t.body)&&t.body.type&&"formData"===t.body.type&&n.useJQuery&&(t.contentType=!1,t.processData=!1,delete t.headers["Content-Type"]),t=c(t)||t,t.beforeSend?t.beforeSend(function(e){r.execute(e||t)}):r.execute(t),t.deferred?t.deferred.promise:t},c.prototype.isInternetExplorer=function(){var e=!1;if("undefined"!=typeof navigator&&navigator.userAgent){var t=navigator.userAgent.toLowerCase();if(t.indexOf("msie")!==-1){var n=parseInt(t.split("msie")[1]);n<=8&&(e=!0)}}return e},l.prototype.execute=function(e){var t=this.jQuery||"undefined"!=typeof window&&window.jQuery,n=e.on,r=e;if("undefined"==typeof t||t===!1)throw new Error("Unsupported configuration! JQuery is required but not available");return e.type=e.method,e.cache=e.jqueryAjaxCache,e.data=e.body,delete e.jqueryAjaxCache,delete e.useJQuery,delete e.body,e.complete=function(e){for(var t={},a=e.getAllResponseHeaders().split("\n"),s=0;s<a.length;s++){var l=a[s].trim();if(0!==l.length){var u=l.indexOf(":");if(u!==-1){var c=l.substring(0,u).trim(),p=l.substring(u+1).trim();t[c]=p}else t[l]=null}}var h={url:r.url,method:r.method,status:e.status,statusText:e.statusText,data:e.responseText,headers:t};try{var f=e.responseJSON||o.safeLoad(e.responseText);h.obj="string"==typeof f?{}:f}catch(d){i.log("unable to parse JSON/YAML content")}if(h.obj=h.obj||null,e.status>=200&&e.status<300)n.response(h);else{if(!(0===e.status||e.status>=400&&e.status<599))return n.response(h);n.error(h)}},t.support.cors=!0,t.ajax(e)},u.prototype.execute=function(e){var t=e.method.toLowerCase();"delete"===t&&(t="del");var n=e.headers||{},r=a[t](e.url);if(e.enableCookies&&r.withCredentials(),e.body)if(s.isObject(e.body)){var l=e.headers["Content-Type"]||"";if(0===l.indexOf("multipart/form-data"))if(delete n["Content-Type"],"[object FormData]"==={}.toString.apply(e.body))for(var u=e.body.keys();;){var c=u.next();if(c.done)break;var p=c.value,h=e.body.get(p);console.log({}.toString.apply(h)),"[object File]"==={}.toString.apply(h)?r.attach(p,h):r.field(p,h)}else{var f;for(var f in e.body){var h=e.body[f];r.field(f,h)}}else s.isObject(e.body)&&(e.body=JSON.stringify(e.body),r.send(e.body))}else r.send(e.body);var d;for(d in n)r.set(d,n[d]);"function"==typeof r.buffer&&r.buffer(),r.end(function(t,n){n=n||{status:0,headers:{error:"no response from server"}};var r,a={url:e.url,method:e.method,headers:n.headers};if(!t&&n.error&&(t=n.error),t&&e.on&&e.on.error){if(a.errObj=t,a.status=n?n.status:500,a.statusText=n?n.text:t.message,n.headers&&n.headers["content-type"]&&n.headers["content-type"].indexOf("application/json")>=0)try{a.obj=JSON.parse(a.statusText)}catch(l){a.obj=null}r=e.on.error}else if(n&&e.on&&e.on.response){var u;if(n.body&&s.keys(n.body).length>0)u=n.body;else try{u=o.safeLoad(n.text),u="string"==typeof u?null:u}catch(l){i.log("cannot parse JSON/YAML content")}a.obj="object"==typeof u?u:null,a.status=n.status,a.statusText=n.text,r=e.on.response}a.data=a.statusText,r&&r(a)})}},{"./helpers":4,"js-yaml":19,"lodash-compat/lang/isObject":144,"lodash-compat/object/keys":149,superagent:158}],6:[function(e,t,n){"use strict";var r=e("./http"),i={isObject:e("lodash-compat/lang/isObject"),cloneDeep:e("lodash-compat/lang/cloneDeep"),isArray:e("lodash-compat/lang/isArray"),isString:e("lodash-compat/lang/isString")},a=t.exports=function(){this.failedUrls=[],this.resolverCache={},this.pendingUrls={}};a.prototype.processAllOf=function(e,t,n,r,i,a){var o,s,l;n["x-resolved-from"]=["#/definitions/"+t];var u=n.allOf;for(u.sort(function(e,t){return e.$ref&&t.$ref?0:e.$ref?-1:1}),o=0;o<u.length;o++)l=u[o],s="/definitions/"+t+"/allOf",this.resolveInline(e,a,l,r,i,s)},a.prototype.resolve=function(e,t,n,a){this.spec=e;var o,s,l=t,u=n,c=a,p={};"function"==typeof t&&(l=null,u=t,c=n);var h=l;this.scope=c||this,this.iteration=this.iteration||0,this.scope.options&&this.scope.options.requestInterceptor&&(p.requestInterceptor=this.scope.options.requestInterceptor),this.scope.options&&this.scope.options.responseInterceptor&&(p.responseInterceptor=this.scope.options.responseInterceptor);var f,d,m,g,y=0,v={},b={},w=[];e.definitions=e.definitions||{};for(f in e.definitions){var _=e.definitions[f];if(_.$ref)this.resolveInline(l,e,_,w,b,_);else{for(g in _.properties)m=_.properties[g],i.isArray(m.allOf)?this.processAllOf(l,f,m,w,b,e):this.resolveTo(l,m,w,"/definitions");_.allOf&&this.processAllOf(l,f,_,w,b,e)}}e.parameters=e.parameters||{};for(f in e.parameters){var x=e.parameters[f];if("body"===x["in"]&&x.schema)if(i.isArray(x.schema.allOf)){for(var A="inline_model",f=A,S=!1,j=0;!S;){if("undefined"==typeof e.definitions[f]){S=!0;break}f=A+"_"+j,j++}e.definitions[f]={allOf:x.schema.allOf},delete x.schema.allOf,x.schema.$ref="#/definitions/"+f,this.processAllOf(l,f,e.definitions[f],w,b,e)}else this.resolveTo(l,x.schema,w,o);x.$ref&&this.resolveInline(l,e,x,w,b,x.$ref)}for(f in e.paths){var E,O,k;d=e.paths[f];for(E in d)if("$ref"===E)o="/paths"+f,this.resolveInline(l,e,d,w,b,o);else{O=d[E];var T=d.parameters||[],C=O.parameters||[];for(s in T){var x=T[s];C.unshift(x)}"parameters"!==E&&i.isObject(O)&&(O.parameters=O.parameters||C);for(s in C){var x=C[s];if(o="/paths"+f+"/"+E+"/parameters","body"===x["in"]&&x.schema)if(i.isArray(x.schema.allOf)){for(var A="inline_model",f=A,S=!1,j=0;!S;){if("undefined"==typeof e.definitions[f]){S=!0;break}f=A+"_"+j,j++}e.definitions[f]={allOf:x.schema.allOf},delete x.schema.allOf,x.schema.$ref="#/definitions/"+f,this.processAllOf(l,f,e.definitions[f],w,b,e)}else this.resolveTo(l,x.schema,w,o);x.$ref&&this.resolveInline(l,e,x,w,b,x.$ref)}for(k in O.responses){var I=O.responses[k];if(o="/paths"+f+"/"+E+"/responses/"+k,i.isObject(I)&&(I.$ref&&this.resolveInline(l,e,I,w,b,o),I.schema)){var D=I;if(i.isArray(D.schema.allOf)){for(var A="inline_model",f=A,S=!1,j=0;!S;){if("undefined"==typeof e.definitions[f]){S=!0;break}f=A+"_"+j,j++}e.definitions[f]={allOf:D.schema.allOf},delete D.schema.allOf,delete D.schema.type,D.schema.$ref="#/definitions/"+f,this.processAllOf(l,f,e.definitions[f],w,b,e)}else"array"===D.schema.type?D.schema.items&&D.schema.items.$ref&&this.resolveInline(l,e,D.schema.items,w,b,o):this.resolveTo(l,I.schema,w,o)}}}d.parameters=[]}var L,M=0,R=[],U=w;for(s=0;s<U.length;s++){var P=U[s];if(l===P.root){if("ref"===P.resolveAs){var q,B=((P.root||"")+"/"+P.key).split("/"),N=[],z="";if(P.key.indexOf("../")>=0){for(var $=0;$<B.length;$++)".."===B[$]?N=N.slice(0,N.length-1):N.push(B[$]);for(q=0;q<N.length;q++)q>0&&(z+="/"),z+=N[q];P.root=z,R.push(P)}else if(L=P.key.split("#"),2===L.length){0!==L[0].indexOf("http:")&&0!==L[0].indexOf("https:")||(P.root=L[0]),o=L[1].split("/");var F,V=e;for(q=0;q<o.length;q++){var H=o[q];if(""!==H){if(V=V[H],"undefined"==typeof V){F=null;break}F=V}}null===F&&R.push(P)}}else if("inline"===P.resolveAs){if(P.key&&P.key.indexOf("#")===-1&&"/"!==P.key.charAt(0)){for(L=P.root.split("/"),o="",s=0;s<L.length-1;s++)o+=L[s]+"/";o+=P.key,P.root=o,P.location=""}R.push(P)}}else R.push(P)}M=R.length;for(var Y={},J=0;J<R.length;J++)!function(e,t,n,a,o){if(e.root&&e.root!==l)if(n.failedUrls.indexOf(e.root)===-1){var s={useJQuery:!1,url:e.root,method:"get",headers:{accept:n.scope.swaggerRequestHeaders||"application/json"},on:{error:function(r){y+=1,console.log("failed url: "+s.url),n.failedUrls.push(s.url),a&&delete a[e.root],b[e.key]={root:e.root,location:e.location},y===M&&n.finish(t,h,w,v,b,u)},response:function(r){var i=r.obj;a&&delete a[e.root],n.resolverCache&&(n.resolverCache[e.root]=i),n.resolveItem(i,e.root,w,v,b,e),y+=1,y===M&&n.finish(t,h,w,v,b,u)}}};c&&c.clientAuthorizations&&c.clientAuthorizations.apply(s),function f(){setTimeout(function(){if(a[s.url])f();else{var e=n.resolverCache[s.url];i.isObject(e)?(s.on.response({obj:e}),1):(a[s.url]=!0,(new r).execute(s,p))}},0)}()}else y+=1,b[e.key]={root:e.root,location:e.location},y===M&&n.finish(t,h,w,v,b,u);else n.resolveItem(t,h,w,v,b,e),y+=1,y===M&&n.finish(t,l,w,v,b,u,!0)}(R[J],e,this,Y,J);0===Object.keys(R).length&&this.finish(e,h,w,v,b,u)},a.prototype.resolveItem=function(e,t,n,r,i,a){var o=a.location,s=e,l=o.split("/");if(""!==o)for(var u=0;u<l.length;u++){var c=l[u];if(c.indexOf("~1")!==-1&&(c=l[u].replace(/~0/g,"~").replace(/~1/g,"/"),"/"!==c.charAt(0)&&(c="/"+c)),"undefined"==typeof s||null===s)break;if(""===c&&u===l.length-1&&l.length>1){s=null;break}c.length>0&&(s=s[c])}var p=a.key;l=a.key.split("/");var h=l[l.length-1];h.indexOf("#")>=0&&(h=h.split("#")[1]),null!==s&&"undefined"!=typeof s?r[p]={name:h,obj:s,key:a.key,root:a.root}:i[p]={root:a.root,location:a.location}},a.prototype.finish=function(e,t,n,r,i,a,o){var s;for(s in n){var l=n[s],u=l.key,c=r[u];if(c)if(e.definitions=e.definitions||{},"ref"===l.resolveAs){if(o!==!0)for(u in c.obj){var p=this.retainRoot(u,c.obj[u],l.root);c.obj[u]=p}e.definitions[c.name]=c.obj,l.obj.$ref="#/definitions/"+c.name}else if("inline"===l.resolveAs){var h=l.obj;h["x-resolved-from"]=[l.key],delete h.$ref;for(u in c.obj){var p=c.obj[u];o!==!0&&(p=this.retainRoot(u,c.obj[u],l.root)),h[u]=p}}}var f=this.countUnresolvedRefs(e);0===f||this.iteration>5?(this.resolveAllOf(e.definitions),this.resolverCache=null,a.call(this.scope,e,i)):(this.iteration+=1,this.resolve(e,t,a,this.scope))},a.prototype.countUnresolvedRefs=function(e){
-var t,n=this.getRefs(e),r=[],i=[];for(t in n)0===t.indexOf("#")?r.push(t.substring(1)):i.push(t);for(t=0;t<r.length;t++)for(var a=r[t],o=a.split("/"),s=e,l=0;l<o.length;l++){var u=o[l];if(""!==u&&(s=s[u],"undefined"==typeof s)){i.push(a);break}}return i.length},a.prototype.getRefs=function(e,t){t=t||e;var n={};for(var r in t)if(t.hasOwnProperty(r)){var a=t[r];if("$ref"===r&&"string"==typeof a)n[a]=null;else if(i.isObject(a)){var o=this.getRefs(a);for(var s in o)n[s]=null}}return n},a.prototype.retainRoot=function(e,t,n){if(i.isObject(t))for(var r in t){var a=t[r];if("$ref"===r&&"string"==typeof a){if(0!==a.indexOf("http:")&&0!==a.indexOf("https:")){var o=!0;if(n){var s=n.slice(-1);if("/"!==s&&0!==a.indexOf("#")&&0!==a.indexOf("http:")&&a.indexOf("https:")){o=!1;var l=n.split("/");l=l.splice(0,l.length-1),n="";for(var u=0;u<l.length;u++)n+=l[u]+"/"}}0!==a.indexOf("#")&&o&&(a="#"+a),a=(n||"")+a,t[r]=a}}else i.isObject(a)&&this.retainRoot(r,a,n)}else i.isString(t)&&"$ref"===e&&t.indexOf("http:")===-1&&t.indexOf("https:")===-1&&(t=n+t);return t},a.prototype.resolveInline=function(e,t,n,r,i,a){var o,s,l,u,c=n.$ref,p=n.$ref,h=!1;if(e=e||"",p){if(0===p.indexOf("../")){for(s=p.split("../"),l=e.split("/"),p="",o=0;o<s.length;o++)""===s[o]?l=l.slice(0,l.length-1):p+=s[o];for(e="",o=0;o<l.length-1;o++)o>0&&(e+="/"),e+=l[o];h=!0}if(p.indexOf("#")>=0)if(0===p.indexOf("/"))u=p.split("#"),s=e.split("//"),l=s[1].split("/"),e=s[0]+"//"+l[0]+u[0],a=u[1];else{if(u=p.split("#"),""!==u[0]){if(l=e.split("/"),l=l.slice(0,l.length-1),!h){e="";for(var f=0;f<l.length;f++)f>0&&(e+="/"),e+=l[f]}e+="/"+p.split("#")[0]}a=u[1]}if(0===p.indexOf("http:")||0===p.indexOf("https:"))p.indexOf("#")>=0?(e=p.split("#")[0],a=p.split("#")[1]):(e=p,a=""),r.push({obj:n,resolveAs:"inline",root:e,key:c,location:a});else if(0===p.indexOf("#"))a=p.split("#")[1],r.push({obj:n,resolveAs:"inline",root:e,key:c,location:a});else if(0===p.indexOf("/")&&p.indexOf("#")===-1){a=p;var d=e.match(/^https?\:\/\/([^\/?#]+)(?:[\/?#]|$)/i);d&&(e=d[0]+p.substring(1),a=""),r.push({obj:n,resolveAs:"inline",root:e,key:c,location:a})}else r.push({obj:n,resolveAs:"inline",root:e,key:c,location:a})}else"array"===n.type&&this.resolveTo(e,n.items,r,a)},a.prototype.resolveTo=function(e,t,n,r){var a,o,s=t.$ref,l=e;if("undefined"!=typeof s&&null!==s){if(s.indexOf("#")>=0){var u=s.split("#");if(u[0]&&0===s.indexOf("/"));else if(!u[0]||0!==u[0].indexOf("http:")&&0!==u[0].indexOf("https:")){if(u[0]&&u[0].length>0){for(a=e.split("/"),l="",o=0;o<a.length-1;o++)l+=a[o]+"/";l+=u[0]}}else l=u[0],s=u[1];r=u[1]}else if(0===s.indexOf("http:")||0===s.indexOf("https:"))l=s,r="";else{for(a=e.split("/"),l="",o=0;o<a.length-1;o++)l+=a[o]+"/";l+=s,r=""}n.push({obj:t,resolveAs:"ref",root:l,key:s,location:r})}else if("array"===t.type){var c=t.items;this.resolveTo(e,c,n,r)}else if(t&&(t.properties||t.additionalProperties)){var p=this.uniqueName("inline_model");t.title&&(p=this.uniqueName(t.title)),delete t.title,this.spec.definitions[p]=i.cloneDeep(t),t.$ref="#/definitions/"+p,delete t.type,delete t.properties}},a.prototype.uniqueName=function(e){for(var t=e,n=0;;){if(!i.isObject(this.spec.definitions[t]))return t;t=e+"_"+n,n++}},a.prototype.resolveAllOf=function(e,t,n){n=n||0,t=t||e;var r;for(var a in t)if(t.hasOwnProperty(a)){var o=t[a];if(null===o)throw new TypeError("Swagger 2.0 does not support null types ("+t+"). See https://github.com/swagger-api/swagger-spec/issues/229.");if("object"==typeof o&&this.resolveAllOf(e,o,n+1),o&&"undefined"!=typeof o.allOf){var s=o.allOf;if(i.isArray(s)){var l=i.cloneDeep(o);delete l.allOf,l["x-composed"]=!0,"undefined"!=typeof o["x-resolved-from"]&&(l["x-resolved-from"]=o["x-resolved-from"]);for(var u=0;u<s.length;u++){var c=s[u],p="self";"undefined"!=typeof c["x-resolved-from"]&&(p=c["x-resolved-from"][0]);for(var h in c)if(l.hasOwnProperty(h))if("properties"===h){var f=c[h];for(r in f){l.properties[r]=i.cloneDeep(f[r]);var d=f[r]["x-resolved-from"];"undefined"!=typeof d&&"self"!==d||(d=p),l.properties[r]["x-resolved-from"]=d}}else if("required"===h){for(var m=l.required.concat(c[h]),g=0;g<m.length;++g)for(var y=g+1;y<m.length;++y)m[g]===m[y]&&m.splice(y--,1);l.required=m}else"x-resolved-from"===h&&l["x-resolved-from"].push(p);else if(l[h]=i.cloneDeep(c[h]),"properties"===h)for(r in l[h])l[h][r]["x-resolved-from"]=p}t[a]=l}}}}},{"./http":5,"lodash-compat/lang/cloneDeep":138,"lodash-compat/lang/isArray":140,"lodash-compat/lang/isObject":144,"lodash-compat/lang/isString":146}],7:[function(e,t,n){"use strict";function r(e,t){return'<tr><td class="optionName">'+e+":</td><td>"+t+"</td></tr>"}function i(e,t){var n;return"integer"===e&&"int32"===t?n="integer":"integer"===e&&"int64"===t?n="long":"integer"===e&&"undefined"==typeof t?n="long":"string"===e&&"date-time"===t?n="date-time":"string"===e&&"date"===t?n="date":"number"===e&&"float"===t?n="float":"number"===e&&"double"===t?n="double":"number"===e&&"undefined"==typeof t?n="double":"boolean"===e?n="boolean":"string"===e&&(n="string"),n}function a(e,t){var n="";return"undefined"!=typeof e.$ref?n+=l.simpleRef(e.$ref):"undefined"==typeof e.type?n+="object":"array"===e.type?t?n+=a(e.items||e.$ref||{}):(n+="Array[",n+=a(e.items||e.$ref||{}),n+="]"):n+="integer"===e.type&&"int32"===e.format?"integer":"integer"===e.type&&"int64"===e.format?"long":"integer"===e.type&&"undefined"==typeof e.format?"long":"string"===e.type&&"date-time"===e.format?"date-time":"string"===e.type&&"date"===e.format?"date":"string"===e.type&&"undefined"==typeof e.format?"string":"number"===e.type&&"float"===e.format?"float":"number"===e.type&&"double"===e.format?"double":"number"===e.type&&"undefined"==typeof e.format?"double":"boolean"===e.type?"boolean":e.$ref?l.simpleRef(e.$ref):e.type,n}function o(e,t,n,r){e=l.resolveSchema(e),"function"!=typeof r&&(r=function(e){return(e||{})["default"]}),n=n||{};var i,a,s=e.type||"object",c=e.format;return u.isUndefined(e.example)?u.isUndefined(e.items)&&u.isArray(e["enum"])&&(a=e["enum"][0]):a=e.example,u.isUndefined(a)&&(e.$ref?(i=t[l.simpleRef(e.$ref)],u.isUndefined(i)||(u.isUndefined(n[i.name])?(n[i.name]=i,a=o(i.definition,t,n,r),delete n[i.name]):a="array"===i.type?[]:{})):u.isUndefined(e["default"])?"string"===s?a="date-time"===c?(new Date).toISOString():"date"===c?(new Date).toISOString().split("T")[0]:"string":"integer"===s?a=0:"number"===s?a=0:"boolean"===s?a=!0:"object"===s?(a={},u.forEach(e.properties,function(e,i){var s=u.cloneDeep(e);s["default"]=r(e),a[i]=o(s,t,n,r)})):"array"===s&&(a=[],u.isArray(e.items)?u.forEach(e.items,function(e){a.push(o(e,t,n,r))}):u.isPlainObject(e.items)?a.push(o(e.items,t,n,r)):u.isUndefined(e.items)?a.push({}):l.log("Array type's 'items' property is not an array or an object, cannot process")):a=e["default"]),a}function s(e,t,n,i){function a(e,t,r){var i,a=t;return e.$ref?(a=e.title||l.simpleRef(e.$ref),i=n[a]):u.isUndefined(t)&&(a=e.title||"Inline Model "+ ++m,i={definition:e}),r!==!0&&(f[a]=u.isUndefined(i)?{}:i.definition),a}function o(e){var t='<span class="propType">',n=e.type||"object";return e.$ref?t+=a(e,l.simpleRef(e.$ref)):"object"===n?t+=u.isUndefined(e.properties)?"object":a(e):"array"===n?(t+="Array[",u.isArray(e.items)?t+=u.map(e.items,a).join(","):u.isPlainObject(e.items)?t+=u.isUndefined(e.items.$ref)?u.isUndefined(e.items.type)||u.indexOf(["array","object"],e.items.type)!==-1?a(e.items):e.items.type:a(e.items,l.simpleRef(e.items.$ref)):(l.log("Array type's 'items' schema is not an array or an object, cannot process"),t+="object"),t+="]"):t+=e.type,t+="</span>"}function s(e,t){var n="",i=e.type||"object",a="array"===i;switch(a&&(i=u.isPlainObject(e.items)&&!u.isUndefined(e.items.type)?e.items.type:"object"),u.isUndefined(e["default"])||(n+=r("Default",e["default"])),i){case"string":e.minLength&&(n+=r("Min. Length",e.minLength)),e.maxLength&&(n+=r("Max. Length",e.maxLength)),e.pattern&&(n+=r("Reg. Exp.",e.pattern));break;case"integer":case"number":e.minimum&&(n+=r("Min. Value",e.minimum)),e.exclusiveMinimum&&(n+=r("Exclusive Min.","true")),e.maximum&&(n+=r("Max. Value",e.maximum)),e.exclusiveMaximum&&(n+=r("Exclusive Max.","true")),e.multipleOf&&(n+=r("Multiple Of",e.multipleOf))}if(a&&(e.minItems&&(n+=r("Min. Items",e.minItems)),e.maxItems&&(n+=r("Max. Items",e.maxItems)),e.uniqueItems&&(n+=r("Unique Items","true")),e.collectionFormat&&(n+=r("Coll. Format",e.collectionFormat))),u.isUndefined(e.items)&&u.isArray(e["enum"])){var o;o="number"===i||"integer"===i?e["enum"].join(", "):'"'+e["enum"].join('", "')+'"',n+=r("Enum",o)}return n.length>0&&(t='<span class="propWrap">'+t+'<table class="optionsWrapper"><tr><th colspan="2">'+i+"</th></tr>"+n+"</table></span>"),t}function c(e,t){var r=e.type||"object",c="array"===e.type,f=p+t+" "+(c?"[":"{")+h;if(t&&d.push(t),c)u.isArray(e.items)?f+="<div>"+u.map(e.items,function(e){var t=e.type||"object";return u.isUndefined(e.$ref)?u.indexOf(["array","object"],t)>-1?"object"===t&&u.isUndefined(e.properties)?"object":a(e):s(e,t):a(e,l.simpleRef(e.$ref))}).join(",</div><div>"):u.isPlainObject(e.items)?f+=u.isUndefined(e.items.$ref)?u.indexOf(["array","object"],e.items.type||"object")>-1?(u.isUndefined(e.items.type)||"object"===e.items.type)&&u.isUndefined(e.items.properties)?"<div>object</div>":"<div>"+a(e.items)+"</div>":"<div>"+s(e.items,e.items.type)+"</div>":"<div>"+a(e.items,l.simpleRef(e.items.$ref))+"</div>":(l.log("Array type's 'items' property is not an array or an object, cannot process"),f+="<div>object</div>");else if(e.$ref)f+="<div>"+a(e,t)+"</div>";else if("object"===r){if(u.isPlainObject(e.properties)){var m=u.map(e.properties,function(t,r){var a,c,p=u.indexOf(e.required,r)>=0,h=u.cloneDeep(t),f=p?"required":"",d='<span class="propName '+f+'">'+r+"</span> (";return h["default"]=i(h),h=l.resolveSchema(h),c=t.description||h.description,u.isUndefined(h.$ref)||(a=n[l.simpleRef(h.$ref)],u.isUndefined(a)||u.indexOf([void 0,"array","object"],a.definition.type)!==-1||(h=l.resolveSchema(a.definition))),d+=o(h),p||(d+=', <span class="propOptKey">optional</span>'),t.readOnly&&(d+=', <span class="propReadOnly">read only</span>'),d+=")",u.isUndefined(c)||(d+=': <span class="propDesc">'+c+"</span>"),h["enum"]&&(d+=' = <span class="propVals">[\''+h["enum"].join("', '")+"']</span>"),"<div"+(t.readOnly?' class="readOnly"':"")+">"+s(h,d)}).join(",</div>");m&&(f+=m+"</div>")}}else f+="<div>"+s(e,r)+"</div>";return f+p+(c?"]":"}")+h}var p='<span class="strong">',h="</span>";if(u.isObject(arguments[0])&&(e=void 0,t=arguments[0],n=arguments[1],i=arguments[2]),n=n||{},t=l.resolveSchema(t),u.isEmpty(t))return p+"Empty"+h;if("string"==typeof t.$ref&&(e=l.simpleRef(t.$ref),t=n[e],"undefined"==typeof t))return p+e+" is not defined!"+h;"string"!=typeof e&&(e=t.title||"Inline Model"),t.definition&&(t=t.definition),"function"!=typeof i&&(i=function(e){return(e||{})["default"]});for(var f={},d=[],m=0,g=c(t,e);u.keys(f).length>0;)u.forEach(f,function(e,t){var n=u.indexOf(d,t)>-1;delete f[t],n||(d.push(t),g+="<br />"+c(e,t))});return g}var l=e("./helpers"),u={isPlainObject:e("lodash-compat/lang/isPlainObject"),isUndefined:e("lodash-compat/lang/isUndefined"),isArray:e("lodash-compat/lang/isArray"),isObject:e("lodash-compat/lang/isObject"),isEmpty:e("lodash-compat/lang/isEmpty"),map:e("lodash-compat/collection/map"),indexOf:e("lodash-compat/array/indexOf"),cloneDeep:e("lodash-compat/lang/cloneDeep"),keys:e("lodash-compat/object/keys"),forEach:e("lodash-compat/collection/forEach")};t.exports.optionHtml=r,t.exports.typeFromJsonSchema=i,t.exports.getStringSignature=a,t.exports.schemaToHTML=s,t.exports.schemaToJSON=o},{"./helpers":4,"lodash-compat/array/indexOf":49,"lodash-compat/collection/forEach":54,"lodash-compat/collection/map":56,"lodash-compat/lang/cloneDeep":138,"lodash-compat/lang/isArray":140,"lodash-compat/lang/isEmpty":141,"lodash-compat/lang/isObject":144,"lodash-compat/lang/isPlainObject":145,"lodash-compat/lang/isUndefined":148,"lodash-compat/object/keys":149}],8:[function(e,t,n){"use strict";var r=e("./http"),i={isObject:e("lodash-compat/lang/isObject")},a=t.exports=function(){this.errors=[],this.warnings=[],this.modelMap={}};a.prototype.setDocumentationLocation=function(e){this.docLocation=e},a.prototype.convert=function(e,t,n,r){if(!e||!Array.isArray(e.apis))return this.finish(r,null);this.clientAuthorizations=t;var i={swagger:"2.0"};i.originalVersion=e.swaggerVersion,this.apiInfo(e,i),this.securityDefinitions(e,i),e.basePath&&this.setDocumentationLocation(e.basePath);var a,o=!1;for(a=0;a<e.apis.length;a++){var s=e.apis[a];Array.isArray(s.operations)&&(o=!0)}o?(this.declaration(e,i),this.finish(r,i)):this.resourceListing(e,i,n,r)},a.prototype.declaration=function(e,t){var n,r,a,o;if(e.apis){0===e.basePath.indexOf("http://")?(a=e.basePath.substring("http://".length),o=a.indexOf("/"),o>0?(t.host=a.substring(0,o),t.basePath=a.substring(o)):(t.host=a,t.basePath="/")):0===e.basePath.indexOf("https://")?(a=e.basePath.substring("https://".length),o=a.indexOf("/"),o>0?(t.host=a.substring(0,o),t.basePath=a.substring(o)):(t.host=a,t.basePath="/")):t.basePath=e.basePath;var s;if(e.authorizations&&(s=e.authorizations),e.consumes&&(t.consumes=e.consumes),e.produces&&(t.produces=e.produces),i.isObject(e))for(n in e.models){var l=e.models[n],u=l.id||n;this.modelMap[u]=n}for(r=0;r<e.apis.length;r++){var c=e.apis[r],p=c.path,h=c.operations;this.operations(p,e.resourcePath,h,s,t)}var f=e.models||{};this.models(f,t)}},a.prototype.models=function(e,t){if(i.isObject(e)){var n;t.definitions=t.definitions||{};for(n in e){var r,a=e[n],o=[],s={properties:{}};for(r in a.properties){var l=a.properties[r],u={};this.dataType(l,u),l.description&&(u.description=l.description),l["enum"]&&(u["enum"]=l["enum"]),"boolean"==typeof l.required&&l.required===!0&&o.push(r),"string"==typeof l.required&&"true"===l.required&&o.push(r),s.properties[r]=u}o.length>0?s.required=o:s.required=a.required,t.definitions[n]=s}}},a.prototype.extractTag=function(e){var t=e||"default";return 0!==t.indexOf("http:")&&0!==t.indexOf("https:")||(t=t.split(["/"]),t=t[t.length-1].substring()),t.endsWith(".json")&&(t=t.substring(0,t.length-".json".length)),t.replace("/","")},a.prototype.operations=function(e,t,n,r,i){if(Array.isArray(n)){var a;i.paths||(i.paths={});var o=i.paths[e]||{},s=this.extractTag(t);i.tags=i.tags||[];var l=!1;for(a=0;a<i.tags.length;a++){var u=i.tags[a];u.name===s&&(l=!0)}for(l||i.tags.push({name:s}),a=0;a<n.length;a++){var c=n[a],p=(c.method||c.httpMethod).toLowerCase(),h={tags:[s]},f=c.authorizations;if(f&&0===Object.keys(f).length&&(f=r),"undefined"!=typeof f){var d;for(var m in f){h.security=h.security||[];var g=f[m];if(g){var y=[];for(var v in g)y.push(g[v].scope);d={},d[m]=y,h.security.push(d)}else d={},d[m]=[],h.security.push(d)}}c.consumes?h.consumes=c.consumes:i.consumes&&(h.consumes=i.consumes),c.produces?h.produces=c.produces:i.produces&&(h.produces=i.produces),c.summary&&(h.summary=c.summary),c.notes&&(h.description=c.notes),c.nickname&&(h.operationId=c.nickname),c.deprecated&&(h.deprecated=c.deprecated),this.authorizations(f,i),this.parameters(h,c.parameters,i),this.responseMessages(h,c,i),o[p]=h}i.paths[e]=o}},a.prototype.responseMessages=function(e,t){if(i.isObject(t)){var n={};this.dataType(t,n),!n.schema&&n.type&&(n={schema:n}),e.responses=e.responses||{};var r=!1;if(Array.isArray(t.responseMessages)){var a,o=t.responseMessages;for(a=0;a<o.length;a++){var s=o[a],l={description:s.message};200===s.code&&(r=!0),s.responseModel&&(l.schema={$ref:"#/definitions/"+s.responseModel}),e.responses[""+s.code]=l}}r?e.responses["default"]=n:e.responses[200]=n}},a.prototype.authorizations=function(e){!i.isObject(e)},a.prototype.parameters=function(e,t){if(Array.isArray(t)){var n;for(n=0;n<t.length;n++){var r=t[n],i={};if(i.name=r.name,i.description=r.description,i.required=r.required,i["in"]=r.paramType,"body"===i["in"]&&(i.name="body"),"form"===i["in"]&&(i["in"]="formData"),r["enum"]&&(i["enum"]=r["enum"]),r.allowMultiple===!0||"true"===r.allowMultiple){var a={};if(this.dataType(r,a),i.type="array",i.items=a,r.allowableValues){var o=r.allowableValues;"LIST"===o.valueType&&(i["enum"]=o.values)}}else this.dataType(r,i);"undefined"!=typeof r.defaultValue&&(i["default"]=r.defaultValue),e.parameters=e.parameters||[],e.parameters.push(i)}}},a.prototype.dataType=function(e,t){if(i.isObject(e)){e.minimum&&(t.minimum=e.minimum),e.maximum&&(t.maximum=e.maximum),e.format&&(t.format=e.format),"undefined"!=typeof e.defaultValue&&(t["default"]=e.defaultValue);var n=this.toJsonSchema(e);n&&(t=t||{},n.type&&(t.type=n.type),n.format&&(t.format=n.format),n.$ref&&(t.schema={$ref:n.$ref}),n.items&&(t.items=n.items))}},a.prototype.toJsonSchema=function(e){if(!e)return"object";var t=e.type||e.dataType||e.responseClass||"",n=t.toLowerCase(),r=(e.format||"").toLowerCase();if(0===n.indexOf("list[")){var i=t.substring(5,t.length-1),a=this.toJsonSchema({type:i});return{type:"array",items:a}}if("int"===n||"integer"===n&&"int32"===r)return{type:"integer",format:"int32"};if("long"===n||"integer"===n&&"int64"===r)return{type:"integer",format:"int64"};if("integer"===n)return{type:"integer",format:"int64"};if("float"===n||"number"===n&&"float"===r)return{type:"number",format:"float"};if("double"===n||"number"===n&&"double"===r)return{type:"number",format:"double"};if("string"===n&&"date-time"===r||"date"===n)return{type:"string",format:"date-time"};if("string"===n)return{type:"string"};if("file"===n)return{type:"file"};if("boolean"===n)return{type:"boolean"};if("boolean"===n)return{type:"boolean"};if("array"===n||"list"===n){if(e.items){var o=this.toJsonSchema(e.items);return{type:"array",items:o}}return{type:"array",items:{type:"object"}}}return e.$ref?{$ref:this.modelMap[e.$ref]?"#/definitions/"+this.modelMap[e.$ref]:e.$ref}:"void"===n||""===n?{}:this.modelMap[e.type]?{$ref:"#/definitions/"+this.modelMap[e.type]}:{type:e.type}},a.prototype.resourceListing=function(e,t,n,i){var a,o=0,s=this,l=e.apis.length,u=t,c={};n&&n.requestInterceptor&&(c.requestInterceptor=n.requestInterceptor),n&&n.responseInterceptor&&(c.responseInterceptor=n.responseInterceptor);var p="application/json";for(n&&n.swaggerRequestHeaders&&(p=n.swaggerRequestHeaders),0===l&&this.finish(i,t),a=0;a<l;a++){var h=e.apis[a],f=h.path,d=this.getAbsolutePath(e.swaggerVersion,this.docLocation,f);h.description&&(t.tags=t.tags||[],t.tags.push({name:this.extractTag(h.path),description:h.description||""}));var m={url:d,headers:{accept:p},on:{},method:"get"};m.on.response=function(e){o+=1;var t=e.obj;t&&s.declaration(t,u),o===l&&s.finish(i,u)},m.on.error=function(e){console.error(e),o+=1,o===l&&s.finish(i,u)},this.clientAuthorizations&&"function"==typeof this.clientAuthorizations.apply&&this.clientAuthorizations.apply(m),(new r).execute(m,c)}},a.prototype.getAbsolutePath=function(e,t,n){if("1.0"===e&&t.endsWith(".json")){var r=t.lastIndexOf("/");r>0&&(t=t.substring(0,r))}var i=t;return 0===n.indexOf("http:")||0===n.indexOf("https:")?i=n:(t.endsWith("/")&&(i=t.substring(0,t.length-1)),i+=n),i=i.replace("{format}","json")},a.prototype.securityDefinitions=function(e,t){if(e.authorizations){var n;for(n in e.authorizations){var r=!1,i={},a=e.authorizations[n];if("apiKey"===a.type)i.type="apiKey",i["in"]=a.passAs,i.name=a.keyname||n,r=!0;else if("basicAuth"===a.type)i.type="basicAuth",r=!0;else if("oauth2"===a.type){var o,s=a.scopes||[],l={};for(o in s){var u=s[o];l[u.scope]=u.description}if(i.type="oauth2",o>0&&(i.scopes=l),a.grantTypes){if(a.grantTypes.implicit){var c=a.grantTypes.implicit;i.flow="implicit",i.authorizationUrl=c.loginEndpoint,r=!0}if(a.grantTypes.authorization_code&&!i.flow){var p=a.grantTypes.authorization_code;i.flow="accessCode",i.authorizationUrl=p.tokenRequestEndpoint.url,i.tokenUrl=p.tokenEndpoint.url,r=!0}}}r&&(t.securityDefinitions=t.securityDefinitions||{},t.securityDefinitions[n]=i)}}},a.prototype.apiInfo=function(e,t){if(e.info){var n=e.info;t.info={},n.contact&&(t.info.contact={},t.info.contact.email=n.contact),n.description&&(t.info.description=n.description),n.title&&(t.info.title=n.title),n.termsOfServiceUrl&&(t.info.termsOfService=n.termsOfServiceUrl),(n.license||n.licenseUrl)&&(t.license={},n.license&&(t.license.name=n.license),n.licenseUrl&&(t.license.url=n.licenseUrl))}else this.warnings.push("missing info section")},a.prototype.finish=function(e,t){e(t)}},{"./http":5,"lodash-compat/lang/isObject":144}],9:[function(e,t,n){"use strict";var r=(e("../helpers").log,{isPlainObject:e("lodash-compat/lang/isPlainObject"),isString:e("lodash-compat/lang/isString")}),i=e("../schema-markup.js"),a=e("js-yaml"),o=t.exports=function(e,t,n,r){return this.definition=t||{},this.isArray="array"===t.type,this.models=n||{},this.name=e||t.title||"Inline Model",this.modelPropertyMacro=r||function(e){return e["default"]},this};o.prototype.createJSONSample=o.prototype.getSampleValue=function(e){return e=e||{},e[this.name]=this,this.examples&&r.isPlainObject(this.examples)&&this.examples["application/json"]?(this.definition.example=this.examples["application/json"],r.isString(this.definition.example)&&(this.definition.example=a.safeLoad(this.definition.example))):this.definition.example||(this.definition.example=this.examples),i.schemaToJSON(this.definition,this.models,e,this.modelPropertyMacro)},o.prototype.getMockSignature=function(){return i.schemaToHTML(this.name,this.definition,this.models,this.modelPropertyMacro)}},{"../helpers":4,"../schema-markup.js":7,"js-yaml":19,"lodash-compat/lang/isPlainObject":145,"lodash-compat/lang/isString":146}],10:[function(e,t,n){"use strict";function r(e,t){if(i.isEmpty(t))return e[0];for(var n=0,r=t.length;n<r;n++)if(e.indexOf(t[n])>-1)return t[n];return e[0]}var i={cloneDeep:e("lodash-compat/lang/cloneDeep"),isUndefined:e("lodash-compat/lang/isUndefined"),isEmpty:e("lodash-compat/lang/isEmpty"),isObject:e("lodash-compat/lang/isObject")},a=e("../helpers"),o=e("./model"),s=e("../http"),l=e("q"),u=t.exports=function(e,t,n,r,i,a,s,l,u){var c=[];if(e=e||{},a=a||{},e&&e.options&&(this.client=e.options.client||null,this.requestInterceptor=e.options.requestInterceptor||null,this.responseInterceptor=e.options.responseInterceptor||null),this.authorizations=a.security,this.basePath=e.basePath||"/",this.clientAuthorizations=u,this.consumes=a.consumes||e.consumes||["application/json"],this.produces=a.produces||e.produces||["application/json"],this.deprecated=a.deprecated,this.description=a.description,this.host=e.host||"localhost",this.method=r||c.push("Operation "+n+" is missing method."),this.models=l||{},this.nickname=n||c.push("Operations must have a nickname."),this.operation=a,this.operations={},this.parameters=null!==a?a.parameters||[]:{},this.parent=e,this.path=i||c.push("Operation "+this.nickname+" is missing path."),this.responses=a.responses||{},this.scheme=t||e.scheme||"http",this.schemes=a.schemes||e.schemes,this.security=a.security||e.security,this.summary=a.summary||"",this.type=null,this.useJQuery=e.useJQuery,this.jqueryAjaxCache=e.jqueryAjaxCache,this.enableCookies=e.enableCookies,this.parameterMacro=e.parameterMacro||function(e,t){return t["default"]},this.inlineModels=[],"/"!==this.basePath&&"/"===this.basePath.slice(-1)&&(this.basePath=this.basePath.slice(0,-1)),"string"==typeof this.deprecated)switch(this.deprecated.toLowerCase()){case"true":case"yes":case"1":this.deprecated=!0;break;case"false":case"no":case"0":case null:this.deprecated=!1;break;default:this.deprecated=Boolean(this.deprecated)}var p,h;if(s){var f;for(f in s)h=new o(f,s[f],this.models,e.modelPropertyMacro),h&&(this.models[f]=h)}else s={};for(p=0;p<this.parameters.length;p++){var d=this.parameters[p];d["default"]=this.parameterMacro(this,d),"array"===d.type&&(d.isList=!0,d.allowMultiple=!0);var m=this.getType(d);if(m&&"boolean"===m.toString().toLowerCase()&&(d.allowableValues={},d.isList=!0,d["enum"]=[!0,!1]),"undefined"!=typeof d["x-example"]){var g=d["x-example"];d["default"]=g}if(d["x-examples"]){var g=d["x-examples"]["default"];"undefined"!=typeof g&&(d["default"]=g)}var y=d["enum"]||d.items&&d.items["enum"];if("undefined"!=typeof y){var v;for(d.allowableValues={},d.allowableValues.values=[],d.allowableValues.descriptiveValues=[],v=0;v<y.length;v++){var b=y[v],w=b===d["default"]||b+""===d["default"];d.allowableValues.values.push(b),d.allowableValues.descriptiveValues.push({value:b+"",isDefault:w})}}"array"===d.type&&(m=[m],"undefined"==typeof d.allowableValues&&(delete d.isList,delete d.allowMultiple)),d.modelSignature={type:m,definitions:this.models},d.signature=this.getModelSignature(m,this.models).toString(),d.sampleJSON=this.getModelSampleJSON(m,this.models),d.responseClassSignature=d.signature}var _,x,A=this.responses;if(A[200]?(x=A[200],_="200"):A[201]?(x=A[201],_="201"):A[202]?(x=A[202],_="202"):A[203]?(x=A[203],_="203"):A[204]?(x=A[204],_="204"):A[205]?(x=A[205],_="205"):A[206]?(x=A[206],_="206"):A["default"]&&(x=A["default"],_="default"),x&&x.schema){var S,j=this.resolveModel(x.schema,s);delete A[_],j?(this.successResponse={},S=this.successResponse[_]=j):x.schema.type&&"object"!==x.schema.type&&"array"!==x.schema.type?(this.successResponse={},S=this.successResponse[_]=x.schema):(this.successResponse={},S=this.successResponse[_]=new o((void 0),x.schema||{},this.models,e.modelPropertyMacro)),S&&(x.description&&(S.description=x.description),x.examples&&(S.examples=x.examples),x.headers&&(S.headers=x.headers)),this.type=x}return c.length>0&&this.resource&&this.resource.api&&this.resource.api.fail&&this.resource.api.fail(c),this};u.prototype.isDefaultArrayItemValue=function(e,t){return t["default"]&&Array.isArray(t["default"])?t["default"].indexOf(e)!==-1:e===t["default"]},u.prototype.getType=function(e){var t,n=e.type,r=e.format,i=!1;"integer"===n&&"int32"===r?t="integer":"integer"===n&&"int64"===r?t="long":"integer"===n?t="integer":"string"===n?t="date-time"===r?"date-time":"date"===r?"date":"string":"number"===n&&"float"===r?t="float":"number"===n&&"double"===r?t="double":"number"===n?t="double":"boolean"===n?t="boolean":"array"===n?(i=!0,e.items&&(t=this.getType(e.items))):"file"===n&&(t="file"),e.$ref&&(t=a.simpleRef(e.$ref));var o=e.schema;if(o){var s=o.$ref;return s?(s=a.simpleRef(s),i?[s]:s):"object"===o.type?this.addInlineModel(o):this.getType(o)}return i?[t]:t},u.prototype.addInlineModel=function(e){var t=this.inlineModels.length,n=this.resolveModel(e,{});return n?(this.inlineModels.push(n),"Inline Model "+t):null},u.prototype.getInlineModel=function(e){if(/^Inline Model \d+$/.test(e)){var t=parseInt(e.substr("Inline Model".length).trim(),10),n=this.inlineModels[t];return n}return null},u.prototype.resolveModel=function(e,t){if("undefined"!=typeof e.$ref){var n=e.$ref;if(0===n.indexOf("#/definitions/")&&(n=n.substring("#/definitions/".length)),t[n])return new o(n,t[n],this.models,this.parent.modelPropertyMacro)}else if(e&&"object"==typeof e&&("object"===e.type||i.isUndefined(e.type)))return new o((void 0),e,this.models,this.parent.modelPropertyMacro);return null},u.prototype.help=function(e){for(var t=this.nickname+": "+this.summary+"\n",n=0;n<this.parameters.length;n++){var r=this.parameters[n],i=r.signature;t+="\n * "+r.name+" ("+i+"): "+r.description}return"undefined"==typeof e&&a.log(t),t},u.prototype.getModelSignature=function(e,t){var n,r;return e instanceof Array&&(r=!0,e=e[0]),"undefined"==typeof e?(e="undefined",n=!0):t[e]?(e=t[e],n=!1):this.getInlineModel(e)?(e=this.getInlineModel(e),n=!1):n=!0,n?r?"Array["+e+"]":e.toString():r?"Array["+e.getMockSignature()+"]":e.getMockSignature()},u.prototype.supportHeaderParams=function(){return!0},u.prototype.supportedSubmitMethods=function(){return this.parent.supportedSubmitMethods},u.prototype.getHeaderParams=function(e){for(var t=this.setContentTypes(e,{}),n=0;n<this.parameters.length;n++){var r=this.parameters[n];if("undefined"!=typeof e[r.name]&&"header"===r["in"]){var i=e[r.name];Array.isArray(i)&&(i=i.toString()),t[r.name]=i}}return t},u.prototype.urlify=function(e){for(var t={},n=this.path.replace(/#.*/,""),r="",i=0;i<this.parameters.length;i++){var a=this.parameters[i];if("undefined"!=typeof e[a.name])if("path"===a["in"]){var o=new RegExp("{"+a.name+"}","gi"),s=e[a.name];s=Array.isArray(s)?this.encodePathCollection(a.collectionFormat,a.name,s):this.encodePathParam(s),n=n.replace(o,s)}else if("query"===a["in"]&&"undefined"!=typeof e[a.name])if(r+=""===r&&n.indexOf("?")<0?"?":"&","undefined"!=typeof a.collectionFormat){var l=e[a.name];r+=Array.isArray(l)?this.encodeQueryCollection(a.collectionFormat,a.name,l):this.encodeQueryKey(a.name)+"="+this.encodeQueryParam(e[a.name])}else r+=this.encodeQueryKey(a.name)+"="+this.encodeQueryParam(e[a.name]);else"formData"===a["in"]&&(t[a.name]=e[a.name])}var u=this.scheme+"://"+this.host;return"/"!==this.basePath&&(u+=this.basePath),u+n+r},u.prototype.getMissingParams=function(e){var t,n=[];for(t=0;t<this.parameters.length;t++){var r=this.parameters[t];r.required===!0&&"undefined"==typeof e[r.name]&&(n=r.name)}return n},u.prototype.getBody=function(e,t,n){for(var r,i,a,o,s={},l=!1,u=0;u<this.parameters.length;u++){var c=this.parameters[u];"undefined"!=typeof t[c.name]?"body"===c["in"]?i=t[c.name]:"formData"===c["in"]&&(s[c.name]={param:c,value:t[c.name]},r=!0):"body"===c["in"]&&(l=!0)}if(l&&"undefined"==typeof i){var p=e["Content-Type"];p&&0===p.indexOf("application/json")&&(i="{}")}var h=!1;if(e["Content-Type"]&&e["Content-Type"].indexOf("multipart/form-data")>=0&&(h=!0),r&&!h){var f="";for(a in s){var c=s[a].param;o=s[a].value,"undefined"!=typeof o&&(Array.isArray(o)?(""!==f&&(f+="&"),f+=this.encodeQueryCollection(c.collectionFormat,a,o)):(""!==f&&(f+="&"),f+=encodeURIComponent(a)+"="+encodeURIComponent(o)))}i=f}else if(h){if("function"==typeof FormData){var d=new FormData;d.type="formData";for(a in s)o=t[a],"undefined"!=typeof o&&("[object File]"==={}.toString.apply(o)?d.append(a,o):"file"===o.type&&o.value?d.append(a,o.value):Array.isArray(o)?d.append(a,this.encodeQueryCollection(c.collectionFormat,a,o)):d.append(a,o));i=d}else{d={};for(a in s)if(o=t[a],Array.isArray(o)){var m,g=c.collectionFormat||"multi";m="ssv"===g?" ":"pipes"===g?"|":"tsv"===g?"\t":",";var y;o.forEach(function(e){y?y+=m:y="",y+=e}),d[a]=y}else d[a]=o;i=d}e["Content-Type"]="multipart/form-data"}return i},u.prototype.getModelSampleJSON=function(e,t){var n,r,a;if(t=t||{},n=e instanceof Array,a=n?e[0]:e,t[a]?r=t[a].createJSONSample():this.getInlineModel(a)&&(r=this.getInlineModel(a).createJSONSample()),r){if(r=n?[r]:r,"string"==typeof r)return r;if(i.isObject(r)){var o=r;if(r instanceof Array&&r.length>0&&(o=r[0]),o.nodeName&&"Node"==typeof o){var s=(new XMLSerializer).serializeToString(o);return this.formatXml(s)}return JSON.stringify(r,null,2)}return r}},u.prototype["do"]=function(e,t,n,r,i){return this.execute(e,t,n,r,i)},u.prototype.execute=function(e,t,n,r,o){var u,c,p,h=e||{},f={};i.isObject(t)&&(f=t,u=n,c=r),this.client&&(f.client=this.client),!f.requestInterceptor&&this.requestInterceptor&&(f.requestInterceptor=this.requestInterceptor),!f.responseInterceptor&&this.responseInterceptor&&(f.responseInterceptor=this.responseInterceptor),"function"==typeof t&&(u=t,c=n),this.parent.usePromise?p=l.defer():(u=u||this.parent.defaultSuccessCallback||a.log,c=c||this.parent.defaultErrorCallback||a.log),"undefined"==typeof f.useJQuery&&(f.useJQuery=this.useJQuery),"undefined"==typeof f.jqueryAjaxCache&&(f.jqueryAjaxCache=this.jqueryAjaxCache),"undefined"==typeof f.enableCookies&&(f.enableCookies=this.enableCookies);var d=this.getMissingParams(h);if(d.length>0){var m="missing required params: "+d;return a.fail(m),this.parent.usePromise?(p.reject(m),p.promise):(c(m,o),{})}var g,y=this.getHeaderParams(h),v=this.setContentTypes(h,f),b={};for(g in y)b[g]=y[g];for(g in v)b[g]=v[g];var w=this.getBody(v,h,f),_=this.urlify(h);if(_.indexOf(".{format}")>0&&b){var x=b.Accept||b.accept;x&&x.indexOf("json")>0?_=_.replace(".{format}",".json"):x&&x.indexOf("xml")>0&&(_=_.replace(".{format}",".xml"))}var A={url:_,method:this.method.toUpperCase(),
-body:w,enableCookies:f.enableCookies,useJQuery:f.useJQuery,jqueryAjaxCache:f.jqueryAjaxCache,deferred:p,headers:b,clientAuthorizations:f.clientAuthorizations,on:{response:function(e){return p?(p.resolve(e),p.promise):u(e,o)},error:function(e){return p?(p.reject(e),p.promise):c(e,o)}}};return this.clientAuthorizations.apply(A,this.operation.security),f.mock===!0?A:(new s).execute(A,f)},u.prototype.setContentTypes=function(e,t){var n,i,o=this.parameters,s=e.parameterContentType||r(this.consumes,["application/json","application/yaml"]),l=t.responseContentType||r(this.produces,["application/json","application/yaml"]),u=[],c=[],p={};for(i=0;i<o.length;i++){var h=o[i];if("formData"===h["in"])"file"===h.type?u.push(h):c.push(h);else if("header"===h["in"]&&t){var f=h.name,d=t[h.name];"undefined"!=typeof t[h.name]&&(p[f]=d)}else"body"===h["in"]&&"undefined"!=typeof e[h.name]&&(n=e[h.name])}var m=n||u.length||c.length;if("post"===this.method||"put"===this.method||"patch"===this.method||("delete"===this.method||"get"===this.method)&&m){if(t.requestContentType&&(s=t.requestContentType),c.length>0){if(s=void 0,t.requestContentType)s=t.requestContentType;else if(u.length>0)s="multipart/form-data";else if(this.consumes&&this.consumes.length>0)for(var g in this.consumes){var y=this.consumes[g];0!==y.indexOf("application/x-www-form-urlencoded")&&0!==y.indexOf("multipart/form-data")||(s=y)}"undefined"==typeof s&&(s="application/x-www-form-urlencoded")}}else s=null;return s&&this.consumes&&this.consumes.indexOf(s)===-1&&a.log("server doesn't consume "+s+", try "+JSON.stringify(this.consumes)),this.matchesAccept(l)||a.log("server can't produce "+l),s&&""!==n||"application/x-www-form-urlencoded"===s?p["Content-Type"]=s:this.consumes&&this.consumes.length>0&&"application/x-www-form-urlencoded"===this.consumes[0]&&(p["Content-Type"]=this.consumes[0]),l&&(p.Accept=l),p},u.prototype.matchesAccept=function(e){return!e||!this.produces||(this.produces.indexOf(e)!==-1||this.produces.indexOf("*/*")!==-1)},u.prototype.asCurl=function(e,t){var n={mock:!0};if("object"==typeof t)for(var r in t)n[r]=t[r];var a=this.execute(e,n);this.clientAuthorizations.apply(a,this.operation.security);var o=[];if(o.push("-X "+this.method.toUpperCase()),"undefined"!=typeof a.headers){var s;for(s in a.headers){var l=a.headers[s];"string"==typeof l&&(l=l.replace(/\'/g,"\\u0027")),o.push("--header '"+s+": "+l+"'")}}var u=!1,c=!1,p=a.headers["Content-Type"];if(p&&0===p.indexOf("application/x-www-form-urlencoded")?u=!0:p&&0===p.indexOf("multipart/form-data")&&(u=!0,c=!0),a.body){var h;if(i.isObject(a.body)){if(c){c=!0;for(var f=0;f<this.parameters.length;f++){var d=this.parameters[f];if("formData"===d["in"]){h||(h="");var m;m="function"==typeof FormData&&a.body instanceof FormData?a.body.get(d.name):a.body[d.name],m&&("file"===d.type?m.name&&(h+="-F "+d.name+'=@"'+m.name+'" '):(h+="-F ",h+=Array.isArray(m)?this.encodeQueryCollection(d.collectionFormat,d.name,m):this.encodeQueryKey(d.name)+"="+m,h+=" "))}}}h||(h=JSON.stringify(a.body))}else h=a.body;h=h.replace(/\'/g,"%27").replace(/\n/g," \\ \n "),u||(h=h.replace(/&/g,"%26")),c?o.push(h):o.push("-d '"+h.replace(/@/g,"%40")+"'")}return"curl "+o.join(" ")+" '"+a.url+"'"},u.prototype.encodePathCollection=function(e,t,n){var r,i="",a="";for(a="ssv"===e?"%20":"tsv"===e?"%09":"pipes"===e?"|":",",r=0;r<n.length;r++)0===r?i=this.encodeQueryParam(n[r]):i+=a+this.encodeQueryParam(n[r]);return i},u.prototype.encodeQueryCollection=function(e,t,n){var r,i="";if(e=e||"default","default"===e||"multi"===e)for(r=0;r<n.length;r++)r>0&&(i+="&"),i+=this.encodeQueryKey(t)+"="+this.encodeQueryParam(n[r]);else{var a="";if("csv"===e)a=",";else if("ssv"===e)a="%20";else if("tsv"===e)a="%09";else if("pipes"===e)a="|";else if("brackets"===e)for(r=0;r<n.length;r++)0!==r&&(i+="&"),i+=this.encodeQueryKey(t)+"[]="+this.encodeQueryParam(n[r]);if(""!==a)for(r=0;r<n.length;r++)0===r?i=this.encodeQueryKey(t)+"="+this.encodeQueryParam(n[r]):i+=a+this.encodeQueryParam(n[r])}return i},u.prototype.encodeQueryKey=function(e){return encodeURIComponent(e).replace("%5B","[").replace("%5D","]").replace("%24","$")},u.prototype.encodeQueryParam=function(e){return encodeURIComponent(e)},u.prototype.encodePathParam=function(e){return encodeURIComponent(e)}},{"../helpers":4,"../http":5,"./model":9,"lodash-compat/lang/cloneDeep":138,"lodash-compat/lang/isEmpty":141,"lodash-compat/lang/isObject":144,"lodash-compat/lang/isUndefined":148,q:157}],11:[function(e,t,n){"use strict";var r=t.exports=function(e,t,n,r){this.description=t,this.externalDocs=n,this.name=e,this.operation=r,this.operationsArray=[],this.path=e,this.tag=e};r.prototype.sort=function(){}},{}],12:[function(e,t,n){function r(){if(!s){s=!0;for(var e,t=o.length;t;){e=o,o=[];for(var n=-1;++n<t;)e[n]();t=o.length}s=!1}}function i(){}var a=t.exports={},o=[],s=!1;a.nextTick=function(e){o.push(e),s||setTimeout(r,0)},a.title="browser",a.browser=!0,a.env={},a.argv=[],a.version="",a.versions={},a.on=i,a.addListener=i,a.once=i,a.off=i,a.removeListener=i,a.removeAllListeners=i,a.emit=i,a.binding=function(e){throw new Error("process.binding is not supported")},a.cwd=function(){return"/"},a.chdir=function(e){throw new Error("process.chdir is not supported")},a.umask=function(){return 0}},{}],13:[function(e,t,n){(function(e){!function(){"use strict";function n(t){var n;return n=t instanceof e?t:new e(t.toString(),"binary"),n.toString("base64")}t.exports=n}()}).call(this,e("buffer").Buffer)},{buffer:14}],14:[function(e,t,n){function r(){return i.TYPED_ARRAY_SUPPORT?2147483647:1073741823}function i(e){return this instanceof i?(this.length=0,this.parent=void 0,"number"==typeof e?a(this,e):"string"==typeof e?o(this,e,arguments.length>1?arguments[1]:"utf8"):s(this,e)):arguments.length>1?new i(e,arguments[1]):new i(e)}function a(e,t){if(e=d(e,t<0?0:0|m(t)),!i.TYPED_ARRAY_SUPPORT)for(var n=0;n<t;n++)e[n]=0;return e}function o(e,t,n){"string"==typeof n&&""!==n||(n="utf8");var r=0|y(t,n);return e=d(e,r),e.write(t,n),e}function s(e,t){if(i.isBuffer(t))return l(e,t);if(Q(t))return u(e,t);if(null==t)throw new TypeError("must start with number, buffer, array or string");if("undefined"!=typeof ArrayBuffer){if(t.buffer instanceof ArrayBuffer)return c(e,t);if(t instanceof ArrayBuffer)return p(e,t)}return t.length?h(e,t):f(e,t)}function l(e,t){var n=0|m(t.length);return e=d(e,n),t.copy(e,0,0,n),e}function u(e,t){var n=0|m(t.length);e=d(e,n);for(var r=0;r<n;r+=1)e[r]=255&t[r];return e}function c(e,t){var n=0|m(t.length);e=d(e,n);for(var r=0;r<n;r+=1)e[r]=255&t[r];return e}function p(e,t){return i.TYPED_ARRAY_SUPPORT?(t.byteLength,e=i._augment(new Uint8Array(t))):e=c(e,new Uint8Array(t)),e}function h(e,t){var n=0|m(t.length);e=d(e,n);for(var r=0;r<n;r+=1)e[r]=255&t[r];return e}function f(e,t){var n,r=0;"Buffer"===t.type&&Q(t.data)&&(n=t.data,r=0|m(n.length)),e=d(e,r);for(var i=0;i<r;i+=1)e[i]=255&n[i];return e}function d(e,t){i.TYPED_ARRAY_SUPPORT?e=i._augment(new Uint8Array(t)):(e.length=t,e._isBuffer=!0);var n=0!==t&&t<=i.poolSize>>>1;return n&&(e.parent=G),e}function m(e){if(e>=r())throw new RangeError("Attempt to allocate Buffer larger than maximum size: 0x"+r().toString(16)+" bytes");return 0|e}function g(e,t){if(!(this instanceof g))return new g(e,t);var n=new i(e,t);return delete n.parent,n}function y(e,t){"string"!=typeof e&&(e=""+e);var n=e.length;if(0===n)return 0;for(var r=!1;;)switch(t){case"ascii":case"binary":case"raw":case"raws":return n;case"utf8":case"utf-8":return $(e).length;case"ucs2":case"ucs-2":case"utf16le":case"utf-16le":return 2*n;case"hex":return n>>>1;case"base64":return H(e).length;default:if(r)return $(e).length;t=(""+t).toLowerCase(),r=!0}}function v(e,t,n){var r=!1;if(t=0|t,n=void 0===n||n===1/0?this.length:0|n,e||(e="utf8"),t<0&&(t=0),n>this.length&&(n=this.length),n<=t)return"";for(;;)switch(e){case"hex":return C(this,t,n);case"utf8":case"utf-8":return E(this,t,n);case"ascii":return k(this,t,n);case"binary":return T(this,t,n);case"base64":return j(this,t,n);case"ucs2":case"ucs-2":case"utf16le":case"utf-16le":return I(this,t,n);default:if(r)throw new TypeError("Unknown encoding: "+e);e=(e+"").toLowerCase(),r=!0}}function b(e,t,n,r){n=Number(n)||0;var i=e.length-n;r?(r=Number(r),r>i&&(r=i)):r=i;var a=t.length;if(a%2!==0)throw new Error("Invalid hex string");r>a/2&&(r=a/2);for(var o=0;o<r;o++){var s=parseInt(t.substr(2*o,2),16);if(isNaN(s))throw new Error("Invalid hex string");e[n+o]=s}return o}function w(e,t,n,r){return Y($(t,e.length-n),e,n,r)}function _(e,t,n,r){return Y(F(t),e,n,r)}function x(e,t,n,r){return _(e,t,n,r)}function A(e,t,n,r){return Y(H(t),e,n,r)}function S(e,t,n,r){return Y(V(t,e.length-n),e,n,r)}function j(e,t,n){return 0===t&&n===e.length?J.fromByteArray(e):J.fromByteArray(e.slice(t,n))}function E(e,t,n){n=Math.min(e.length,n);for(var r=[],i=t;i<n;){var a=e[i],o=null,s=a>239?4:a>223?3:a>191?2:1;if(i+s<=n){var l,u,c,p;switch(s){case 1:a<128&&(o=a);break;case 2:l=e[i+1],128===(192&l)&&(p=(31&a)<<6|63&l,p>127&&(o=p));break;case 3:l=e[i+1],u=e[i+2],128===(192&l)&&128===(192&u)&&(p=(15&a)<<12|(63&l)<<6|63&u,p>2047&&(p<55296||p>57343)&&(o=p));break;case 4:l=e[i+1],u=e[i+2],c=e[i+3],128===(192&l)&&128===(192&u)&&128===(192&c)&&(p=(15&a)<<18|(63&l)<<12|(63&u)<<6|63&c,p>65535&&p<1114112&&(o=p))}}null===o?(o=65533,s=1):o>65535&&(o-=65536,r.push(o>>>10&1023|55296),o=56320|1023&o),r.push(o),i+=s}return O(r)}function O(e){var t=e.length;if(t<=K)return String.fromCharCode.apply(String,e);for(var n="",r=0;r<t;)n+=String.fromCharCode.apply(String,e.slice(r,r+=K));return n}function k(e,t,n){var r="";n=Math.min(e.length,n);for(var i=t;i<n;i++)r+=String.fromCharCode(127&e[i]);return r}function T(e,t,n){var r="";n=Math.min(e.length,n);for(var i=t;i<n;i++)r+=String.fromCharCode(e[i]);return r}function C(e,t,n){var r=e.length;(!t||t<0)&&(t=0),(!n||n<0||n>r)&&(n=r);for(var i="",a=t;a<n;a++)i+=z(e[a]);return i}function I(e,t,n){for(var r=e.slice(t,n),i="",a=0;a<r.length;a+=2)i+=String.fromCharCode(r[a]+256*r[a+1]);return i}function D(e,t,n){if(e%1!==0||e<0)throw new RangeError("offset is not uint");if(e+t>n)throw new RangeError("Trying to access beyond buffer length")}function L(e,t,n,r,a,o){if(!i.isBuffer(e))throw new TypeError("buffer must be a Buffer instance");if(t>a||t<o)throw new RangeError("value is out of bounds");if(n+r>e.length)throw new RangeError("index out of range")}function M(e,t,n,r){t<0&&(t=65535+t+1);for(var i=0,a=Math.min(e.length-n,2);i<a;i++)e[n+i]=(t&255<<8*(r?i:1-i))>>>8*(r?i:1-i)}function R(e,t,n,r){t<0&&(t=4294967295+t+1);for(var i=0,a=Math.min(e.length-n,4);i<a;i++)e[n+i]=t>>>8*(r?i:3-i)&255}function U(e,t,n,r,i,a){if(t>i||t<a)throw new RangeError("value is out of bounds");if(n+r>e.length)throw new RangeError("index out of range");if(n<0)throw new RangeError("index out of range")}function P(e,t,n,r,i){return i||U(e,t,n,4,3.4028234663852886e38,-3.4028234663852886e38),W.write(e,t,n,r,23,4),n+4}function q(e,t,n,r,i){return i||U(e,t,n,8,1.7976931348623157e308,-1.7976931348623157e308),W.write(e,t,n,r,52,8),n+8}function B(e){if(e=N(e).replace(Z,""),e.length<2)return"";for(;e.length%4!==0;)e+="=";return e}function N(e){return e.trim?e.trim():e.replace(/^\s+|\s+$/g,"")}function z(e){return e<16?"0"+e.toString(16):e.toString(16)}function $(e,t){t=t||1/0;for(var n,r=e.length,i=null,a=[],o=0;o<r;o++){if(n=e.charCodeAt(o),n>55295&&n<57344){if(!i){if(n>56319){(t-=3)>-1&&a.push(239,191,189);continue}if(o+1===r){(t-=3)>-1&&a.push(239,191,189);continue}i=n;continue}if(n<56320){(t-=3)>-1&&a.push(239,191,189),i=n;continue}n=i-55296<<10|n-56320|65536}else i&&(t-=3)>-1&&a.push(239,191,189);if(i=null,n<128){if((t-=1)<0)break;a.push(n)}else if(n<2048){if((t-=2)<0)break;a.push(n>>6|192,63&n|128)}else if(n<65536){if((t-=3)<0)break;a.push(n>>12|224,n>>6&63|128,63&n|128)}else{if(!(n<1114112))throw new Error("Invalid code point");if((t-=4)<0)break;a.push(n>>18|240,n>>12&63|128,n>>6&63|128,63&n|128)}}return a}function F(e){for(var t=[],n=0;n<e.length;n++)t.push(255&e.charCodeAt(n));return t}function V(e,t){for(var n,r,i,a=[],o=0;o<e.length&&!((t-=2)<0);o++)n=e.charCodeAt(o),r=n>>8,i=n%256,a.push(i),a.push(r);return a}function H(e){return J.toByteArray(B(e))}function Y(e,t,n,r){for(var i=0;i<r&&!(i+n>=t.length||i>=e.length);i++)t[i+n]=e[i];return i}var J=e("base64-js"),W=e("ieee754"),Q=e("is-array");n.Buffer=i,n.SlowBuffer=g,n.INSPECT_MAX_BYTES=50,i.poolSize=8192;var G={};i.TYPED_ARRAY_SUPPORT=function(){function e(){}try{var t=new Uint8Array(1);return t.foo=function(){return 42},t.constructor=e,42===t.foo()&&t.constructor===e&&"function"==typeof t.subarray&&0===t.subarray(1,1).byteLength}catch(n){return!1}}(),i.isBuffer=function(e){return!(null==e||!e._isBuffer)},i.compare=function(e,t){if(!i.isBuffer(e)||!i.isBuffer(t))throw new TypeError("Arguments must be Buffers");if(e===t)return 0;for(var n=e.length,r=t.length,a=0,o=Math.min(n,r);a<o&&e[a]===t[a];)++a;return a!==o&&(n=e[a],r=t[a]),n<r?-1:r<n?1:0},i.isEncoding=function(e){switch(String(e).toLowerCase()){case"hex":case"utf8":case"utf-8":case"ascii":case"binary":case"base64":case"raw":case"ucs2":case"ucs-2":case"utf16le":case"utf-16le":return!0;default:return!1}},i.concat=function(e,t){if(!Q(e))throw new TypeError("list argument must be an Array of Buffers.");if(0===e.length)return new i(0);var n;if(void 0===t)for(t=0,n=0;n<e.length;n++)t+=e[n].length;var r=new i(t),a=0;for(n=0;n<e.length;n++){var o=e[n];o.copy(r,a),a+=o.length}return r},i.byteLength=y,i.prototype.length=void 0,i.prototype.parent=void 0,i.prototype.toString=function(){var e=0|this.length;return 0===e?"":0===arguments.length?E(this,0,e):v.apply(this,arguments)},i.prototype.equals=function(e){if(!i.isBuffer(e))throw new TypeError("Argument must be a Buffer");return this===e||0===i.compare(this,e)},i.prototype.inspect=function(){var e="",t=n.INSPECT_MAX_BYTES;return this.length>0&&(e=this.toString("hex",0,t).match(/.{2}/g).join(" "),this.length>t&&(e+=" ... ")),"<Buffer "+e+">"},i.prototype.compare=function(e){if(!i.isBuffer(e))throw new TypeError("Argument must be a Buffer");return this===e?0:i.compare(this,e)},i.prototype.indexOf=function(e,t){function n(e,t,n){for(var r=-1,i=0;n+i<e.length;i++)if(e[n+i]===t[r===-1?0:i-r]){if(r===-1&&(r=i),i-r+1===t.length)return n+r}else r=-1;return-1}if(t>2147483647?t=2147483647:t<-2147483648&&(t=-2147483648),t>>=0,0===this.length)return-1;if(t>=this.length)return-1;if(t<0&&(t=Math.max(this.length+t,0)),"string"==typeof e)return 0===e.length?-1:String.prototype.indexOf.call(this,e,t);if(i.isBuffer(e))return n(this,e,t);if("number"==typeof e)return i.TYPED_ARRAY_SUPPORT&&"function"===Uint8Array.prototype.indexOf?Uint8Array.prototype.indexOf.call(this,e,t):n(this,[e],t);throw new TypeError("val must be string, number or Buffer")},i.prototype.get=function(e){return console.log(".get() is deprecated. Access using array indexes instead."),this.readUInt8(e)},i.prototype.set=function(e,t){return console.log(".set() is deprecated. Access using array indexes instead."),this.writeUInt8(e,t)},i.prototype.write=function(e,t,n,r){if(void 0===t)r="utf8",n=this.length,t=0;else if(void 0===n&&"string"==typeof t)r=t,n=this.length,t=0;else if(isFinite(t))t=0|t,isFinite(n)?(n=0|n,void 0===r&&(r="utf8")):(r=n,n=void 0);else{var i=r;r=t,t=0|n,n=i}var a=this.length-t;if((void 0===n||n>a)&&(n=a),e.length>0&&(n<0||t<0)||t>this.length)throw new RangeError("attempt to write outside buffer bounds");r||(r="utf8");for(var o=!1;;)switch(r){case"hex":return b(this,e,t,n);case"utf8":case"utf-8":return w(this,e,t,n);case"ascii":return _(this,e,t,n);case"binary":return x(this,e,t,n);case"base64":return A(this,e,t,n);case"ucs2":case"ucs-2":case"utf16le":case"utf-16le":return S(this,e,t,n);default:if(o)throw new TypeError("Unknown encoding: "+r);r=(""+r).toLowerCase(),o=!0}},i.prototype.toJSON=function(){return{type:"Buffer",data:Array.prototype.slice.call(this._arr||this,0)}};var K=4096;i.prototype.slice=function(e,t){var n=this.length;e=~~e,t=void 0===t?n:~~t,e<0?(e+=n,e<0&&(e=0)):e>n&&(e=n),t<0?(t+=n,t<0&&(t=0)):t>n&&(t=n),t<e&&(t=e);var r;if(i.TYPED_ARRAY_SUPPORT)r=i._augment(this.subarray(e,t));else{var a=t-e;r=new i(a,(void 0));for(var o=0;o<a;o++)r[o]=this[o+e]}return r.length&&(r.parent=this.parent||this),r},i.prototype.readUIntLE=function(e,t,n){e=0|e,t=0|t,n||D(e,t,this.length);for(var r=this[e],i=1,a=0;++a<t&&(i*=256);)r+=this[e+a]*i;return r},i.prototype.readUIntBE=function(e,t,n){e=0|e,t=0|t,n||D(e,t,this.length);for(var r=this[e+--t],i=1;t>0&&(i*=256);)r+=this[e+--t]*i;return r},i.prototype.readUInt8=function(e,t){return t||D(e,1,this.length),this[e]},i.prototype.readUInt16LE=function(e,t){return t||D(e,2,this.length),this[e]|this[e+1]<<8},i.prototype.readUInt16BE=function(e,t){return t||D(e,2,this.length),this[e]<<8|this[e+1]},i.prototype.readUInt32LE=function(e,t){return t||D(e,4,this.length),(this[e]|this[e+1]<<8|this[e+2]<<16)+16777216*this[e+3]},i.prototype.readUInt32BE=function(e,t){return t||D(e,4,this.length),16777216*this[e]+(this[e+1]<<16|this[e+2]<<8|this[e+3])},i.prototype.readIntLE=function(e,t,n){e=0|e,t=0|t,n||D(e,t,this.length);for(var r=this[e],i=1,a=0;++a<t&&(i*=256);)r+=this[e+a]*i;return i*=128,r>=i&&(r-=Math.pow(2,8*t)),r},i.prototype.readIntBE=function(e,t,n){e=0|e,t=0|t,n||D(e,t,this.length);for(var r=t,i=1,a=this[e+--r];r>0&&(i*=256);)a+=this[e+--r]*i;return i*=128,a>=i&&(a-=Math.pow(2,8*t)),a},i.prototype.readInt8=function(e,t){return t||D(e,1,this.length),128&this[e]?(255-this[e]+1)*-1:this[e]},i.prototype.readInt16LE=function(e,t){t||D(e,2,this.length);var n=this[e]|this[e+1]<<8;return 32768&n?4294901760|n:n},i.prototype.readInt16BE=function(e,t){t||D(e,2,this.length);var n=this[e+1]|this[e]<<8;return 32768&n?4294901760|n:n},i.prototype.readInt32LE=function(e,t){return t||D(e,4,this.length),this[e]|this[e+1]<<8|this[e+2]<<16|this[e+3]<<24},i.prototype.readInt32BE=function(e,t){return t||D(e,4,this.length),this[e]<<24|this[e+1]<<16|this[e+2]<<8|this[e+3]},i.prototype.readFloatLE=function(e,t){return t||D(e,4,this.length),W.read(this,e,!0,23,4)},i.prototype.readFloatBE=function(e,t){return t||D(e,4,this.length),W.read(this,e,!1,23,4)},i.prototype.readDoubleLE=function(e,t){return t||D(e,8,this.length),W.read(this,e,!0,52,8)},i.prototype.readDoubleBE=function(e,t){return t||D(e,8,this.length),W.read(this,e,!1,52,8)},i.prototype.writeUIntLE=function(e,t,n,r){e=+e,t=0|t,n=0|n,r||L(this,e,t,n,Math.pow(2,8*n),0);var i=1,a=0;for(this[t]=255&e;++a<n&&(i*=256);)this[t+a]=e/i&255;return t+n},i.prototype.writeUIntBE=function(e,t,n,r){e=+e,t=0|t,n=0|n,r||L(this,e,t,n,Math.pow(2,8*n),0);var i=n-1,a=1;for(this[t+i]=255&e;--i>=0&&(a*=256);)this[t+i]=e/a&255;return t+n},i.prototype.writeUInt8=function(e,t,n){return e=+e,t=0|t,n||L(this,e,t,1,255,0),i.TYPED_ARRAY_SUPPORT||(e=Math.floor(e)),this[t]=e,t+1},i.prototype.writeUInt16LE=function(e,t,n){return e=+e,t=0|t,n||L(this,e,t,2,65535,0),i.TYPED_ARRAY_SUPPORT?(this[t]=e,this[t+1]=e>>>8):M(this,e,t,!0),t+2},i.prototype.writeUInt16BE=function(e,t,n){return e=+e,t=0|t,n||L(this,e,t,2,65535,0),i.TYPED_ARRAY_SUPPORT?(this[t]=e>>>8,this[t+1]=e):M(this,e,t,!1),t+2},i.prototype.writeUInt32LE=function(e,t,n){return e=+e,t=0|t,n||L(this,e,t,4,4294967295,0),i.TYPED_ARRAY_SUPPORT?(this[t+3]=e>>>24,this[t+2]=e>>>16,this[t+1]=e>>>8,this[t]=e):R(this,e,t,!0),t+4},i.prototype.writeUInt32BE=function(e,t,n){return e=+e,t=0|t,n||L(this,e,t,4,4294967295,0),i.TYPED_ARRAY_SUPPORT?(this[t]=e>>>24,this[t+1]=e>>>16,this[t+2]=e>>>8,this[t+3]=e):R(this,e,t,!1),t+4},i.prototype.writeIntLE=function(e,t,n,r){if(e=+e,t=0|t,!r){var i=Math.pow(2,8*n-1);L(this,e,t,n,i-1,-i)}var a=0,o=1,s=e<0?1:0;for(this[t]=255&e;++a<n&&(o*=256);)this[t+a]=(e/o>>0)-s&255;return t+n},i.prototype.writeIntBE=function(e,t,n,r){if(e=+e,t=0|t,!r){var i=Math.pow(2,8*n-1);L(this,e,t,n,i-1,-i)}var a=n-1,o=1,s=e<0?1:0;for(this[t+a]=255&e;--a>=0&&(o*=256);)this[t+a]=(e/o>>0)-s&255;return t+n},i.prototype.writeInt8=function(e,t,n){return e=+e,t=0|t,n||L(this,e,t,1,127,-128),i.TYPED_ARRAY_SUPPORT||(e=Math.floor(e)),e<0&&(e=255+e+1),this[t]=e,t+1},i.prototype.writeInt16LE=function(e,t,n){return e=+e,t=0|t,n||L(this,e,t,2,32767,-32768),i.TYPED_ARRAY_SUPPORT?(this[t]=e,this[t+1]=e>>>8):M(this,e,t,!0),t+2},i.prototype.writeInt16BE=function(e,t,n){return e=+e,t=0|t,n||L(this,e,t,2,32767,-32768),i.TYPED_ARRAY_SUPPORT?(this[t]=e>>>8,this[t+1]=e):M(this,e,t,!1),t+2},i.prototype.writeInt32LE=function(e,t,n){return e=+e,t=0|t,n||L(this,e,t,4,2147483647,-2147483648),i.TYPED_ARRAY_SUPPORT?(this[t]=e,this[t+1]=e>>>8,this[t+2]=e>>>16,this[t+3]=e>>>24):R(this,e,t,!0),t+4},i.prototype.writeInt32BE=function(e,t,n){return e=+e,t=0|t,n||L(this,e,t,4,2147483647,-2147483648),e<0&&(e=4294967295+e+1),i.TYPED_ARRAY_SUPPORT?(this[t]=e>>>24,this[t+1]=e>>>16,this[t+2]=e>>>8,this[t+3]=e):R(this,e,t,!1),t+4},i.prototype.writeFloatLE=function(e,t,n){return P(this,e,t,!0,n)},i.prototype.writeFloatBE=function(e,t,n){return P(this,e,t,!1,n)},i.prototype.writeDoubleLE=function(e,t,n){return q(this,e,t,!0,n)},i.prototype.writeDoubleBE=function(e,t,n){return q(this,e,t,!1,n)},i.prototype.copy=function(e,t,n,r){if(n||(n=0),r||0===r||(r=this.length),t>=e.length&&(t=e.length),t||(t=0),r>0&&r<n&&(r=n),r===n)return 0;if(0===e.length||0===this.length)return 0;if(t<0)throw new RangeError("targetStart out of bounds");if(n<0||n>=this.length)throw new RangeError("sourceStart out of bounds");if(r<0)throw new RangeError("sourceEnd out of bounds");r>this.length&&(r=this.length),e.length-t<r-n&&(r=e.length-t+n);var a,o=r-n;if(this===e&&n<t&&t<r)for(a=o-1;a>=0;a--)e[a+t]=this[a+n];else if(o<1e3||!i.TYPED_ARRAY_SUPPORT)for(a=0;a<o;a++)e[a+t]=this[a+n];else e._set(this.subarray(n,n+o),t);return o},i.prototype.fill=function(e,t,n){if(e||(e=0),t||(t=0),n||(n=this.length),n<t)throw new RangeError("end < start");if(n!==t&&0!==this.length){if(t<0||t>=this.length)throw new RangeError("start out of bounds");if(n<0||n>this.length)throw new RangeError("end out of bounds");var r;if("number"==typeof e)for(r=t;r<n;r++)this[r]=e;else{var i=$(e.toString()),a=i.length;for(r=t;r<n;r++)this[r]=i[r%a]}return this}},i.prototype.toArrayBuffer=function(){if("undefined"!=typeof Uint8Array){if(i.TYPED_ARRAY_SUPPORT)return new i(this).buffer;for(var e=new Uint8Array(this.length),t=0,n=e.length;t<n;t+=1)e[t]=this[t];return e.buffer}throw new TypeError("Buffer.toArrayBuffer not supported in this browser")};var X=i.prototype;i._augment=function(e){return e.constructor=i,e._isBuffer=!0,e._set=e.set,e.get=X.get,e.set=X.set,e.write=X.write,e.toString=X.toString,e.toLocaleString=X.toString,e.toJSON=X.toJSON,e.equals=X.equals,e.compare=X.compare,e.indexOf=X.indexOf,e.copy=X.copy,e.slice=X.slice,e.readUIntLE=X.readUIntLE,e.readUIntBE=X.readUIntBE,e.readUInt8=X.readUInt8,e.readUInt16LE=X.readUInt16LE,e.readUInt16BE=X.readUInt16BE,e.readUInt32LE=X.readUInt32LE,e.readUInt32BE=X.readUInt32BE,e.readIntLE=X.readIntLE,e.readIntBE=X.readIntBE,e.readInt8=X.readInt8,e.readInt16LE=X.readInt16LE,e.readInt16BE=X.readInt16BE,e.readInt32LE=X.readInt32LE,e.readInt32BE=X.readInt32BE,e.readFloatLE=X.readFloatLE,e.readFloatBE=X.readFloatBE,e.readDoubleLE=X.readDoubleLE,e.readDoubleBE=X.readDoubleBE,e.writeUInt8=X.writeUInt8,e.writeUIntLE=X.writeUIntLE,e.writeUIntBE=X.writeUIntBE,e.writeUInt16LE=X.writeUInt16LE,e.writeUInt16BE=X.writeUInt16BE,e.writeUInt32LE=X.writeUInt32LE,e.writeUInt32BE=X.writeUInt32BE,e.writeIntLE=X.writeIntLE,e.writeIntBE=X.writeIntBE,e.writeInt8=X.writeInt8,e.writeInt16LE=X.writeInt16LE,e.writeInt16BE=X.writeInt16BE,e.writeInt32LE=X.writeInt32LE,e.writeInt32BE=X.writeInt32BE,e.writeFloatLE=X.writeFloatLE,e.writeFloatBE=X.writeFloatBE,e.writeDoubleLE=X.writeDoubleLE,e.writeDoubleBE=X.writeDoubleBE,e.fill=X.fill,e.inspect=X.inspect,e.toArrayBuffer=X.toArrayBuffer,e};var Z=/[^+\/0-9A-Za-z-_]/g},{"base64-js":15,ieee754:16,"is-array":17}],15:[function(e,t,n){var r="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";!function(e){"use strict";function t(e){var t=e.charCodeAt(0);return t===o||t===p?62:t===s||t===h?63:t<l?-1:t<l+10?t-l+26+26:t<c+26?t-c:t<u+26?t-u+26:void 0}function n(e){function n(e){u[p++]=e}var r,i,o,s,l,u;if(e.length%4>0)throw new Error("Invalid string. Length must be a multiple of 4");var c=e.length;l="="===e.charAt(c-2)?2:"="===e.charAt(c-1)?1:0,u=new a(3*e.length/4-l),o=l>0?e.length-4:e.length;var p=0;for(r=0,i=0;r<o;r+=4,i+=3)s=t(e.charAt(r))<<18|t(e.charAt(r+1))<<12|t(e.charAt(r+2))<<6|t(e.charAt(r+3)),n((16711680&s)>>16),n((65280&s)>>8),n(255&s);return 2===l?(s=t(e.charAt(r))<<2|t(e.charAt(r+1))>>4,n(255&s)):1===l&&(s=t(e.charAt(r))<<10|t(e.charAt(r+1))<<4|t(e.charAt(r+2))>>2,n(s>>8&255),n(255&s)),u}function i(e){function t(e){return r.charAt(e)}function n(e){return t(e>>18&63)+t(e>>12&63)+t(e>>6&63)+t(63&e)}var i,a,o,s=e.length%3,l="";for(i=0,o=e.length-s;i<o;i+=3)a=(e[i]<<16)+(e[i+1]<<8)+e[i+2],l+=n(a);switch(s){case 1:a=e[e.length-1],l+=t(a>>2),l+=t(a<<4&63),l+="==";break;case 2:a=(e[e.length-2]<<8)+e[e.length-1],l+=t(a>>10),l+=t(a>>4&63),l+=t(a<<2&63),l+="="}return l}var a="undefined"!=typeof Uint8Array?Uint8Array:Array,o="+".charCodeAt(0),s="/".charCodeAt(0),l="0".charCodeAt(0),u="a".charCodeAt(0),c="A".charCodeAt(0),p="-".charCodeAt(0),h="_".charCodeAt(0);e.toByteArray=n,e.fromByteArray=i}("undefined"==typeof n?this.base64js={}:n)},{}],16:[function(e,t,n){n.read=function(e,t,n,r,i){var a,o,s=8*i-r-1,l=(1<<s)-1,u=l>>1,c=-7,p=n?i-1:0,h=n?-1:1,f=e[t+p];for(p+=h,a=f&(1<<-c)-1,f>>=-c,c+=s;c>0;a=256*a+e[t+p],p+=h,c-=8);for(o=a&(1<<-c)-1,a>>=-c,c+=r;c>0;o=256*o+e[t+p],p+=h,c-=8);if(0===a)a=1-u;else{if(a===l)return o?NaN:(f?-1:1)*(1/0);o+=Math.pow(2,r),a-=u}return(f?-1:1)*o*Math.pow(2,a-r)},n.write=function(e,t,n,r,i,a){var o,s,l,u=8*a-i-1,c=(1<<u)-1,p=c>>1,h=23===i?Math.pow(2,-24)-Math.pow(2,-77):0,f=r?0:a-1,d=r?1:-1,m=t<0||0===t&&1/t<0?1:0;for(t=Math.abs(t),isNaN(t)||t===1/0?(s=isNaN(t)?1:0,o=c):(o=Math.floor(Math.log(t)/Math.LN2),t*(l=Math.pow(2,-o))<1&&(o--,l*=2),t+=o+p>=1?h/l:h*Math.pow(2,1-p),t*l>=2&&(o++,l/=2),o+p>=c?(s=0,o=c):o+p>=1?(s=(t*l-1)*Math.pow(2,i),o+=p):(s=t*Math.pow(2,p-1)*Math.pow(2,i),o=0));i>=8;e[n+f]=255&s,f+=d,s/=256,i-=8);for(o=o<<i|s,u+=i;u>0;e[n+f]=255&o,f+=d,o/=256,u-=8);e[n+f-d]|=128*m}},{}],17:[function(e,t,n){var r=Array.isArray,i=Object.prototype.toString;t.exports=r||function(e){return!!e&&"[object Array]"==i.call(e)}},{}],18:[function(e,t,n){!function(){"use strict";function e(t,n,r,i){return this instanceof e?(this.domain=t||void 0,this.path=n||"/",this.secure=!!r,this.script=!!i,this):new e(t,n,r,i)}function t(e,n,r){return e instanceof t?e:this instanceof t?(this.name=null,this.value=null,this.expiration_date=1/0,this.path=String(r||"/"),this.explicit_path=!1,this.domain=n||null,this.explicit_domain=!1,this.secure=!1,this.noscript=!1,e&&this.parse(e,n,r),this):new t(e,n,r)}function r(){var e,n,i;return this instanceof r?(e=Object.create(null),this.setCookie=function(r,a,o){var s,l;if(r=new t(r,a,o),s=r.expiration_date<=Date.now(),void 0!==e[r.name]){for(n=e[r.name],l=0;l<n.length;l+=1)if(i=n[l],i.collidesWith(r))return s?(n.splice(l,1),0===n.length&&delete e[r.name],!1):(n[l]=r,r);return!s&&(n.push(r),r)}return!s&&(e[r.name]=[r],e[r.name])},this.getCookie=function(t,r){var i,a;if(n=e[t])for(a=0;a<n.length;a+=1)if(i=n[a],i.expiration_date<=Date.now())0===n.length&&delete e[i.name];else if(i.matches(r))return i},this.getCookies=function(t){var n,r,i=[];for(n in e)r=this.getCookie(n,t),r&&i.push(r);return i.toString=function(){return i.join(":")},i.toValueString=function(){return i.map(function(e){return e.toValueString()}).join(";")},i},this):new r}n.CookieAccessInfo=e,n.Cookie=t,t.prototype.toString=function(){var e=[this.name+"="+this.value];return this.expiration_date!==1/0&&e.push("expires="+new Date(this.expiration_date).toGMTString()),this.domain&&e.push("domain="+this.domain),this.path&&e.push("path="+this.path),this.secure&&e.push("secure"),this.noscript&&e.push("httponly"),e.join("; ")},t.prototype.toValueString=function(){return this.name+"="+this.value};var i=/[:](?=\s*[a-zA-Z0-9_\-]+\s*[=])/g;t.prototype.parse=function(e,n,r){if(this instanceof t){var i,a=e.split(";").filter(function(e){return!!e}),o=a[0].match(/([^=]+)=([\s\S]*)/),s=o[1],l=o[2];for(this.name=s,this.value=l,i=1;i<a.length;i+=1)switch(o=a[i].match(/([^=]+)(?:=([\s\S]*))?/),s=o[1].trim().toLowerCase(),l=o[2],s){case"httponly":this.noscript=!0;break;case"expires":this.expiration_date=l?Number(Date.parse(l)):1/0;break;case"path":this.path=l?l.trim():"",this.explicit_path=!0;break;case"domain":this.domain=l?l.trim():"",this.explicit_domain=!!this.domain;break;case"secure":this.secure=!0}return this.explicit_path||(this.path=r||"/"),this.explicit_domain||(this.domain=n),this}return(new t).parse(e,n,r)},t.prototype.matches=function(e){return!(this.noscript&&e.script||this.secure&&!e.secure||!this.collidesWith(e))},t.prototype.collidesWith=function(e){if(this.path&&!e.path||this.domain&&!e.domain)return!1;if(this.path&&0!==e.path.indexOf(this.path))return!1;if(this.explicit_path&&0!==e.path.indexOf(this.path))return!1;var t=e.domain&&e.domain.replace(/^[\.]/,""),n=this.domain&&this.domain.replace(/^[\.]/,"");if(n===t)return!0;if(n){if(!this.explicit_domain)return!1;var r=t.indexOf(n);return r!==-1&&r===t.length-n.length}return!0},n.CookieJar=r,r.prototype.setCookies=function(e,n,r){e=Array.isArray(e)?e:e.split(i);var a,o,s=[];for(e=e.map(function(e){return new t(e,n,r)}),a=0;a<e.length;a+=1)o=e[a],this.setCookie(o,n,r)&&s.push(o);return s}}()},{}],19:[function(e,t,n){"use strict";var r=e("./lib/js-yaml.js");t.exports=r},{"./lib/js-yaml.js":20}],20:[function(e,t,n){"use strict";function r(e){return function(){throw new Error("Function "+e+" is deprecated and cannot be used.")}}var i=e("./js-yaml/loader"),a=e("./js-yaml/dumper");t.exports.Type=e("./js-yaml/type"),t.exports.Schema=e("./js-yaml/schema"),t.exports.FAILSAFE_SCHEMA=e("./js-yaml/schema/failsafe"),t.exports.JSON_SCHEMA=e("./js-yaml/schema/json"),t.exports.CORE_SCHEMA=e("./js-yaml/schema/core"),t.exports.DEFAULT_SAFE_SCHEMA=e("./js-yaml/schema/default_safe"),t.exports.DEFAULT_FULL_SCHEMA=e("./js-yaml/schema/default_full"),t.exports.load=i.load,t.exports.loadAll=i.loadAll,t.exports.safeLoad=i.safeLoad,t.exports.safeLoadAll=i.safeLoadAll,t.exports.dump=a.dump,t.exports.safeDump=a.safeDump,t.exports.YAMLException=e("./js-yaml/exception"),t.exports.MINIMAL_SCHEMA=e("./js-yaml/schema/failsafe"),t.exports.SAFE_SCHEMA=e("./js-yaml/schema/default_safe"),t.exports.DEFAULT_SCHEMA=e("./js-yaml/schema/default_full"),t.exports.scan=r("scan"),t.exports.parse=r("parse"),t.exports.compose=r("compose"),t.exports.addConstructor=r("addConstructor")},{"./js-yaml/dumper":22,"./js-yaml/exception":23,"./js-yaml/loader":24,"./js-yaml/schema":26,"./js-yaml/schema/core":27,"./js-yaml/schema/default_full":28,"./js-yaml/schema/default_safe":29,"./js-yaml/schema/failsafe":30,"./js-yaml/schema/json":31,"./js-yaml/type":32}],21:[function(e,t,n){"use strict";function r(e){return"undefined"==typeof e||null===e}function i(e){return"object"==typeof e&&null!==e}function a(e){return Array.isArray(e)?e:r(e)?[]:[e]}function o(e,t){var n,r,i,a;if(t)for(a=Object.keys(t),n=0,r=a.length;n<r;n+=1)i=a[n],e[i]=t[i];return e}function s(e,t){var n,r="";for(n=0;n<t;n+=1)r+=e;return r}function l(e){return 0===e&&Number.NEGATIVE_INFINITY===1/e}t.exports.isNothing=r,t.exports.isObject=i,t.exports.toArray=a,t.exports.repeat=s,t.exports.isNegativeZero=l,t.exports.extend=o},{}],22:[function(e,t,n){"use strict";function r(e,t){var n,r,i,a,o,s,l;if(null===t)return{};for(n={},r=Object.keys(t),i=0,a=r.length;i<a;i+=1)o=r[i],s=String(t[o]),"!!"===o.slice(0,2)&&(o="tag:yaml.org,2002:"+o.slice(2)),l=e.compiledTypeMap[o],l&&R.call(l.styleAliases,s)&&(s=l.styleAliases[s]),n[o]=s;return n}function i(e){var t,n,r;if(t=e.toString(16).toUpperCase(),e<=255)n="x",r=2;else if(e<=65535)n="u",r=4;else{if(!(e<=4294967295))throw new I("code point within a string may not be greater than 0xFFFFFFFF");n="U",r=8}return"\\"+n+C.repeat("0",r-t.length)+t;
-}function a(e){this.schema=e.schema||D,this.indent=Math.max(1,e.indent||2),this.skipInvalid=e.skipInvalid||!1,this.flowLevel=C.isNothing(e.flowLevel)?-1:e.flowLevel,this.styleMap=r(this.schema,e.styles||null),this.sortKeys=e.sortKeys||!1,this.lineWidth=e.lineWidth||80,this.noRefs=e.noRefs||!1,this.noCompatMode=e.noCompatMode||!1,this.implicitTypes=this.schema.compiledImplicit,this.explicitTypes=this.schema.compiledExplicit,this.tag=null,this.result="",this.duplicates=[],this.usedDuplicates=null}function o(e,t){for(var n,r=C.repeat(" ",t),i=0,a=-1,o="",s=e.length;i<s;)a=e.indexOf("\n",i),a===-1?(n=e.slice(i),i=s):(n=e.slice(i,a+1),i=a+1),n.length&&"\n"!==n&&(o+=r),o+=n;return o}function s(e,t){return"\n"+C.repeat(" ",e.indent*t)}function l(e,t){var n,r,i;for(n=0,r=e.implicitTypes.length;n<r;n+=1)if(i=e.implicitTypes[n],i.resolve(t))return!0;return!1}function u(e){return e===q||e===U}function c(e){return 32<=e&&e<=126||161<=e&&e<=55295&&8232!==e&&8233!==e||57344<=e&&e<=65533&&65279!==e||65536<=e&&e<=1114111}function p(e){return c(e)&&65279!==e&&e!==Y&&e!==X&&e!==Z&&e!==te&&e!==re&&e!==W&&e!==z}function h(e){return c(e)&&65279!==e&&!u(e)&&e!==J&&e!==G&&e!==W&&e!==Y&&e!==X&&e!==Z&&e!==te&&e!==re&&e!==z&&e!==F&&e!==H&&e!==B&&e!==ne&&e!==Q&&e!==V&&e!==N&&e!==$&&e!==K&&e!==ee}function f(e,t,n,r,i){var a,o,s=!1,l=!1,f=r!==-1,d=-1,m=h(e.charCodeAt(0))&&!u(e.charCodeAt(e.length-1));if(t)for(a=0;a<e.length;a++){if(o=e.charCodeAt(a),!c(o))return ce;m=m&&p(o)}else{for(a=0;a<e.length;a++){if(o=e.charCodeAt(a),o===P)s=!0,f&&(l=l||a-d-1>r&&" "!==e[d+1],d=a);else if(!c(o))return ce;m=m&&p(o)}l=l||f&&a-d-1>r&&" "!==e[d+1]}return s||l?" "===e[0]&&n>9?ce:l?ue:le:m&&!i(e)?oe:se}function d(e,t,n,r){e.dump=function(){function i(t){return l(e,t)}if(0===t.length)return"''";if(!e.noCompatMode&&ae.indexOf(t)!==-1)return"'"+t+"'";var a=e.indent*Math.max(1,n),s=e.lineWidth===-1?-1:Math.max(Math.min(e.lineWidth,40),e.lineWidth-a),u=r||e.flowLevel>-1&&n>=e.flowLevel;switch(f(t,u,e.indent,s,i)){case oe:return t;case se:return"'"+t.replace(/'/g,"''")+"'";case le:return"|"+m(t,e.indent)+g(o(t,a));case ue:return">"+m(t,e.indent)+g(o(y(t,s),a));case ce:return'"'+b(t,s)+'"';default:throw new I("impossible error: invalid scalar style")}}()}function m(e,t){var n=" "===e[0]?String(t):"",r="\n"===e[e.length-1],i=r&&("\n"===e[e.length-2]||"\n"===e),a=i?"+":r?"":"-";return n+a+"\n"}function g(e){return"\n"===e[e.length-1]?e.slice(0,-1):e}function y(e,t){for(var n,r,i=/(\n+)([^\n]*)/g,a=function(){var n=e.indexOf("\n");return n=n!==-1?n:e.length,i.lastIndex=n,v(e.slice(0,n),t)}(),o="\n"===e[0]||" "===e[0];r=i.exec(e);){var s=r[1],l=r[2];n=" "===l[0],a+=s+(o||n||""===l?"":"\n")+v(l,t),o=n}return a}function v(e,t){if(""===e||" "===e[0])return e;for(var n,r,i=/ [^ ]/g,a=0,o=0,s=0,l="";n=i.exec(e);)s=n.index,s-a>t&&(r=o>a?o:s,l+="\n"+e.slice(a,r),a=r+1),o=s;return l+="\n",l+=e.length-a>t&&o>a?e.slice(a,o)+"\n"+e.slice(o+1):e.slice(a),l.slice(1)}function b(e){for(var t,n,r="",a=0;a<e.length;a++)t=e.charCodeAt(a),n=ie[t],r+=!n&&c(t)?e[a]:n||i(t);return r}function w(e,t,n){var r,i,a="",o=e.tag;for(r=0,i=n.length;r<i;r+=1)j(e,t,n[r],!1,!1)&&(0!==r&&(a+=", "),a+=e.dump);e.tag=o,e.dump="["+a+"]"}function _(e,t,n,r){var i,a,o="",l=e.tag;for(i=0,a=n.length;i<a;i+=1)j(e,t+1,n[i],!0,!0)&&(r&&0===i||(o+=s(e,t)),o+="- "+e.dump);e.tag=l,e.dump=o||"[]"}function x(e,t,n){var r,i,a,o,s,l="",u=e.tag,c=Object.keys(n);for(r=0,i=c.length;r<i;r+=1)s="",0!==r&&(s+=", "),a=c[r],o=n[a],j(e,t,a,!1,!1)&&(e.dump.length>1024&&(s+="? "),s+=e.dump+": ",j(e,t,o,!1,!1)&&(s+=e.dump,l+=s));e.tag=u,e.dump="{"+l+"}"}function A(e,t,n,r){var i,a,o,l,u,c,p="",h=e.tag,f=Object.keys(n);if(e.sortKeys===!0)f.sort();else if("function"==typeof e.sortKeys)f.sort(e.sortKeys);else if(e.sortKeys)throw new I("sortKeys must be a boolean or a function");for(i=0,a=f.length;i<a;i+=1)c="",r&&0===i||(c+=s(e,t)),o=f[i],l=n[o],j(e,t+1,o,!0,!0,!0)&&(u=null!==e.tag&&"?"!==e.tag||e.dump&&e.dump.length>1024,u&&(c+=e.dump&&P===e.dump.charCodeAt(0)?"?":"? "),c+=e.dump,u&&(c+=s(e,t)),j(e,t+1,l,!0,u)&&(c+=e.dump&&P===e.dump.charCodeAt(0)?":":": ",c+=e.dump,p+=c));e.tag=h,e.dump=p||"{}"}function S(e,t,n){var r,i,a,o,s,l;for(i=n?e.explicitTypes:e.implicitTypes,a=0,o=i.length;a<o;a+=1)if(s=i[a],(s.instanceOf||s.predicate)&&(!s.instanceOf||"object"==typeof t&&t instanceof s.instanceOf)&&(!s.predicate||s.predicate(t))){if(e.tag=n?s.tag:"?",s.represent){if(l=e.styleMap[s.tag]||s.defaultStyle,"[object Function]"===M.call(s.represent))r=s.represent(t,l);else{if(!R.call(s.represent,l))throw new I("!<"+s.tag+'> tag resolver accepts not "'+l+'" style');r=s.represent[l](t,l)}e.dump=r}return!0}return!1}function j(e,t,n,r,i,a){e.tag=null,e.dump=n,S(e,n,!1)||S(e,n,!0);var o=M.call(e.dump);r&&(r=e.flowLevel<0||e.flowLevel>t);var s,l,u="[object Object]"===o||"[object Array]"===o;if(u&&(s=e.duplicates.indexOf(n),l=s!==-1),(null!==e.tag&&"?"!==e.tag||l||2!==e.indent&&t>0)&&(i=!1),l&&e.usedDuplicates[s])e.dump="*ref_"+s;else{if(u&&l&&!e.usedDuplicates[s]&&(e.usedDuplicates[s]=!0),"[object Object]"===o)r&&0!==Object.keys(e.dump).length?(A(e,t,e.dump,i),l&&(e.dump="&ref_"+s+e.dump)):(x(e,t,e.dump),l&&(e.dump="&ref_"+s+" "+e.dump));else if("[object Array]"===o)r&&0!==e.dump.length?(_(e,t,e.dump,i),l&&(e.dump="&ref_"+s+e.dump)):(w(e,t,e.dump),l&&(e.dump="&ref_"+s+" "+e.dump));else{if("[object String]"!==o){if(e.skipInvalid)return!1;throw new I("unacceptable kind of an object to dump "+o)}"?"!==e.tag&&d(e,e.dump,t,a)}null!==e.tag&&"?"!==e.tag&&(e.dump="!<"+e.tag+"> "+e.dump)}return!0}function E(e,t){var n,r,i=[],a=[];for(O(e,i,a),n=0,r=a.length;n<r;n+=1)t.duplicates.push(i[a[n]]);t.usedDuplicates=new Array(r)}function O(e,t,n){var r,i,a;if(null!==e&&"object"==typeof e)if(i=t.indexOf(e),i!==-1)n.indexOf(i)===-1&&n.push(i);else if(t.push(e),Array.isArray(e))for(i=0,a=e.length;i<a;i+=1)O(e[i],t,n);else for(r=Object.keys(e),i=0,a=r.length;i<a;i+=1)O(e[r[i]],t,n)}function k(e,t){t=t||{};var n=new a(t);return n.noRefs||E(e,n),j(n,0,e,!0,!0)?n.dump+"\n":""}function T(e,t){return k(e,C.extend({schema:L},t))}var C=e("./common"),I=e("./exception"),D=e("./schema/default_full"),L=e("./schema/default_safe"),M=Object.prototype.toString,R=Object.prototype.hasOwnProperty,U=9,P=10,q=32,B=33,N=34,z=35,$=37,F=38,V=39,H=42,Y=44,J=45,W=58,Q=62,G=63,K=64,X=91,Z=93,ee=96,te=123,ne=124,re=125,ie={};ie[0]="\\0",ie[7]="\\a",ie[8]="\\b",ie[9]="\\t",ie[10]="\\n",ie[11]="\\v",ie[12]="\\f",ie[13]="\\r",ie[27]="\\e",ie[34]='\\"',ie[92]="\\\\",ie[133]="\\N",ie[160]="\\_",ie[8232]="\\L",ie[8233]="\\P";var ae=["y","Y","yes","Yes","YES","on","On","ON","n","N","no","No","NO","off","Off","OFF"],oe=1,se=2,le=3,ue=4,ce=5;t.exports.dump=k,t.exports.safeDump=T},{"./common":21,"./exception":23,"./schema/default_full":28,"./schema/default_safe":29}],23:[function(e,t,n){"use strict";function r(e,t){Error.call(this),Error.captureStackTrace?Error.captureStackTrace(this,this.constructor):this.stack=(new Error).stack||"",this.name="YAMLException",this.reason=e,this.mark=t,this.message=(this.reason||"(unknown reason)")+(this.mark?" "+this.mark.toString():"")}r.prototype=Object.create(Error.prototype),r.prototype.constructor=r,r.prototype.toString=function(e){var t=this.name+": ";return t+=this.reason||"(unknown reason)",!e&&this.mark&&(t+=" "+this.mark.toString()),t},t.exports=r},{}],24:[function(e,t,n){"use strict";function r(e){return 10===e||13===e}function i(e){return 9===e||32===e}function a(e){return 9===e||32===e||10===e||13===e}function o(e){return 44===e||91===e||93===e||123===e||125===e}function s(e){var t;return 48<=e&&e<=57?e-48:(t=32|e,97<=t&&t<=102?t-97+10:-1)}function l(e){return 120===e?2:117===e?4:85===e?8:0}function u(e){return 48<=e&&e<=57?e-48:-1}function c(e){return 48===e?"\0":97===e?"":98===e?"\b":116===e?"\t":9===e?"\t":110===e?"\n":118===e?"\x0B":102===e?"\f":114===e?"\r":101===e?"":32===e?" ":34===e?'"':47===e?"/":92===e?"\\":78===e?"…":95===e?" ":76===e?"\u2028":80===e?"\u2029":""}function p(e){return e<=65535?String.fromCharCode(e):String.fromCharCode((e-65536>>10)+55296,(e-65536&1023)+56320)}function h(e,t){this.input=e,this.filename=t.filename||null,this.schema=t.schema||V,this.onWarning=t.onWarning||null,this.legacy=t.legacy||!1,this.json=t.json||!1,this.listener=t.listener||null,this.implicitTypes=this.schema.compiledImplicit,this.typeMap=this.schema.compiledTypeMap,this.length=e.length,this.position=0,this.line=0,this.lineStart=0,this.lineIndent=0,this.documents=[]}function f(e,t){return new z(t,new $(e.filename,e.input,e.position,e.line,e.position-e.lineStart))}function d(e,t){throw f(e,t)}function m(e,t){e.onWarning&&e.onWarning.call(null,f(e,t))}function g(e,t,n,r){var i,a,o,s;if(t<n){if(s=e.input.slice(t,n),r)for(i=0,a=s.length;i<a;i+=1)o=s.charCodeAt(i),9===o||32<=o&&o<=1114111||d(e,"expected valid JSON character");else Z.test(s)&&d(e,"the stream contains non-printable characters");e.result+=s}}function y(e,t,n,r){var i,a,o,s;for(N.isObject(n)||d(e,"cannot merge mappings; the provided source object is unacceptable"),i=Object.keys(n),o=0,s=i.length;o<s;o+=1)a=i[o],H.call(t,a)||(t[a]=n[a],r[a]=!0)}function v(e,t,n,r,i,a){var o,s;if(i=String(i),null===t&&(t={}),"tag:yaml.org,2002:merge"===r)if(Array.isArray(a))for(o=0,s=a.length;o<s;o+=1)y(e,t,a[o],n);else y(e,t,a,n);else e.json||H.call(n,i)||!H.call(t,i)||d(e,"duplicated mapping key"),t[i]=a,delete n[i];return t}function b(e){var t;t=e.input.charCodeAt(e.position),10===t?e.position++:13===t?(e.position++,10===e.input.charCodeAt(e.position)&&e.position++):d(e,"a line break is expected"),e.line+=1,e.lineStart=e.position}function w(e,t,n){for(var a=0,o=e.input.charCodeAt(e.position);0!==o;){for(;i(o);)o=e.input.charCodeAt(++e.position);if(t&&35===o)do o=e.input.charCodeAt(++e.position);while(10!==o&&13!==o&&0!==o);if(!r(o))break;for(b(e),o=e.input.charCodeAt(e.position),a++,e.lineIndent=0;32===o;)e.lineIndent++,o=e.input.charCodeAt(++e.position)}return n!==-1&&0!==a&&e.lineIndent<n&&m(e,"deficient indentation"),a}function _(e){var t,n=e.position;return t=e.input.charCodeAt(n),!(45!==t&&46!==t||t!==e.input.charCodeAt(n+1)||t!==e.input.charCodeAt(n+2)||(n+=3,t=e.input.charCodeAt(n),0!==t&&!a(t)))}function x(e,t){1===t?e.result+=" ":t>1&&(e.result+=N.repeat("\n",t-1))}function A(e,t,n){var s,l,u,c,p,h,f,d,m,y=e.kind,v=e.result;if(m=e.input.charCodeAt(e.position),a(m)||o(m)||35===m||38===m||42===m||33===m||124===m||62===m||39===m||34===m||37===m||64===m||96===m)return!1;if((63===m||45===m)&&(l=e.input.charCodeAt(e.position+1),a(l)||n&&o(l)))return!1;for(e.kind="scalar",e.result="",u=c=e.position,p=!1;0!==m;){if(58===m){if(l=e.input.charCodeAt(e.position+1),a(l)||n&&o(l))break}else if(35===m){if(s=e.input.charCodeAt(e.position-1),a(s))break}else{if(e.position===e.lineStart&&_(e)||n&&o(m))break;if(r(m)){if(h=e.line,f=e.lineStart,d=e.lineIndent,w(e,!1,-1),e.lineIndent>=t){p=!0,m=e.input.charCodeAt(e.position);continue}e.position=c,e.line=h,e.lineStart=f,e.lineIndent=d;break}}p&&(g(e,u,c,!1),x(e,e.line-h),u=c=e.position,p=!1),i(m)||(c=e.position+1),m=e.input.charCodeAt(++e.position)}return g(e,u,c,!1),!!e.result||(e.kind=y,e.result=v,!1)}function S(e,t){var n,i,a;if(n=e.input.charCodeAt(e.position),39!==n)return!1;for(e.kind="scalar",e.result="",e.position++,i=a=e.position;0!==(n=e.input.charCodeAt(e.position));)if(39===n){if(g(e,i,e.position,!0),n=e.input.charCodeAt(++e.position),39!==n)return!0;i=a=e.position,e.position++}else r(n)?(g(e,i,a,!0),x(e,w(e,!1,t)),i=a=e.position):e.position===e.lineStart&&_(e)?d(e,"unexpected end of the document within a single quoted scalar"):(e.position++,a=e.position);d(e,"unexpected end of the stream within a single quoted scalar")}function j(e,t){var n,i,a,o,u,c;if(c=e.input.charCodeAt(e.position),34!==c)return!1;for(e.kind="scalar",e.result="",e.position++,n=i=e.position;0!==(c=e.input.charCodeAt(e.position));){if(34===c)return g(e,n,e.position,!0),e.position++,!0;if(92===c){if(g(e,n,e.position,!0),c=e.input.charCodeAt(++e.position),r(c))w(e,!1,t);else if(c<256&&ie[c])e.result+=ae[c],e.position++;else if((u=l(c))>0){for(a=u,o=0;a>0;a--)c=e.input.charCodeAt(++e.position),(u=s(c))>=0?o=(o<<4)+u:d(e,"expected hexadecimal character");e.result+=p(o),e.position++}else d(e,"unknown escape sequence");n=i=e.position}else r(c)?(g(e,n,i,!0),x(e,w(e,!1,t)),n=i=e.position):e.position===e.lineStart&&_(e)?d(e,"unexpected end of the document within a double quoted scalar"):(e.position++,i=e.position)}d(e,"unexpected end of the stream within a double quoted scalar")}function E(e,t){var n,r,i,o,s,l,u,c,p,h,f,m=!0,g=e.tag,y=e.anchor,b={};if(f=e.input.charCodeAt(e.position),91===f)o=93,u=!1,r=[];else{if(123!==f)return!1;o=125,u=!0,r={}}for(null!==e.anchor&&(e.anchorMap[e.anchor]=r),f=e.input.charCodeAt(++e.position);0!==f;){if(w(e,!0,t),f=e.input.charCodeAt(e.position),f===o)return e.position++,e.tag=g,e.anchor=y,e.kind=u?"mapping":"sequence",e.result=r,!0;m||d(e,"missed comma between flow collection entries"),p=c=h=null,s=l=!1,63===f&&(i=e.input.charCodeAt(e.position+1),a(i)&&(s=l=!0,e.position++,w(e,!0,t))),n=e.line,L(e,t,Y,!1,!0),p=e.tag,c=e.result,w(e,!0,t),f=e.input.charCodeAt(e.position),!l&&e.line!==n||58!==f||(s=!0,f=e.input.charCodeAt(++e.position),w(e,!0,t),L(e,t,Y,!1,!0),h=e.result),u?v(e,r,b,p,c,h):s?r.push(v(e,null,b,p,c,h)):r.push(c),w(e,!0,t),f=e.input.charCodeAt(e.position),44===f?(m=!0,f=e.input.charCodeAt(++e.position)):m=!1}d(e,"unexpected end of the stream within a flow collection")}function O(e,t){var n,a,o,s,l=G,c=!1,p=!1,h=t,f=0,m=!1;if(s=e.input.charCodeAt(e.position),124===s)a=!1;else{if(62!==s)return!1;a=!0}for(e.kind="scalar",e.result="";0!==s;)if(s=e.input.charCodeAt(++e.position),43===s||45===s)G===l?l=43===s?X:K:d(e,"repeat of a chomping mode identifier");else{if(!((o=u(s))>=0))break;0===o?d(e,"bad explicit indentation width of a block scalar; it cannot be less than one"):p?d(e,"repeat of an indentation width identifier"):(h=t+o-1,p=!0)}if(i(s)){do s=e.input.charCodeAt(++e.position);while(i(s));if(35===s)do s=e.input.charCodeAt(++e.position);while(!r(s)&&0!==s)}for(;0!==s;){for(b(e),e.lineIndent=0,s=e.input.charCodeAt(e.position);(!p||e.lineIndent<h)&&32===s;)e.lineIndent++,s=e.input.charCodeAt(++e.position);if(!p&&e.lineIndent>h&&(h=e.lineIndent),r(s))f++;else{if(e.lineIndent<h){l===X?e.result+=N.repeat("\n",c?1+f:f):l===G&&c&&(e.result+="\n");break}for(a?i(s)?(m=!0,e.result+=N.repeat("\n",c?1+f:f)):m?(m=!1,e.result+=N.repeat("\n",f+1)):0===f?c&&(e.result+=" "):e.result+=N.repeat("\n",f):e.result+=N.repeat("\n",c?1+f:f),c=!0,p=!0,f=0,n=e.position;!r(s)&&0!==s;)s=e.input.charCodeAt(++e.position);g(e,n,e.position,!1)}}return!0}function k(e,t){var n,r,i,o=e.tag,s=e.anchor,l=[],u=!1;for(null!==e.anchor&&(e.anchorMap[e.anchor]=l),i=e.input.charCodeAt(e.position);0!==i&&45===i&&(r=e.input.charCodeAt(e.position+1),a(r));)if(u=!0,e.position++,w(e,!0,-1)&&e.lineIndent<=t)l.push(null),i=e.input.charCodeAt(e.position);else if(n=e.line,L(e,t,W,!1,!0),l.push(e.result),w(e,!0,-1),i=e.input.charCodeAt(e.position),(e.line===n||e.lineIndent>t)&&0!==i)d(e,"bad indentation of a sequence entry");else if(e.lineIndent<t)break;return!!u&&(e.tag=o,e.anchor=s,e.kind="sequence",e.result=l,!0)}function T(e,t,n){var r,o,s,l,u=e.tag,c=e.anchor,p={},h={},f=null,m=null,g=null,y=!1,b=!1;for(null!==e.anchor&&(e.anchorMap[e.anchor]=p),l=e.input.charCodeAt(e.position);0!==l;){if(r=e.input.charCodeAt(e.position+1),s=e.line,63!==l&&58!==l||!a(r)){if(!L(e,n,J,!1,!0))break;if(e.line===s){for(l=e.input.charCodeAt(e.position);i(l);)l=e.input.charCodeAt(++e.position);if(58===l)l=e.input.charCodeAt(++e.position),a(l)||d(e,"a whitespace character is expected after the key-value separator within a block mapping"),y&&(v(e,p,h,f,m,null),f=m=g=null),b=!0,y=!1,o=!1,f=e.tag,m=e.result;else{if(!b)return e.tag=u,e.anchor=c,!0;d(e,"can not read an implicit mapping pair; a colon is missed")}}else{if(!b)return e.tag=u,e.anchor=c,!0;d(e,"can not read a block mapping entry; a multiline key may not be an implicit key")}}else 63===l?(y&&(v(e,p,h,f,m,null),f=m=g=null),b=!0,y=!0,o=!0):y?(y=!1,o=!0):d(e,"incomplete explicit mapping pair; a key node is missed"),e.position+=1,l=r;if((e.line===s||e.lineIndent>t)&&(L(e,t,Q,!0,o)&&(y?m=e.result:g=e.result),y||(v(e,p,h,f,m,g),f=m=g=null),w(e,!0,-1),l=e.input.charCodeAt(e.position)),e.lineIndent>t&&0!==l)d(e,"bad indentation of a mapping entry");else if(e.lineIndent<t)break}return y&&v(e,p,h,f,m,null),b&&(e.tag=u,e.anchor=c,e.kind="mapping",e.result=p),b}function C(e){var t,n,r,i,o=!1,s=!1;if(i=e.input.charCodeAt(e.position),33!==i)return!1;if(null!==e.tag&&d(e,"duplication of a tag property"),i=e.input.charCodeAt(++e.position),60===i?(o=!0,i=e.input.charCodeAt(++e.position)):33===i?(s=!0,n="!!",i=e.input.charCodeAt(++e.position)):n="!",t=e.position,o){do i=e.input.charCodeAt(++e.position);while(0!==i&&62!==i);e.position<e.length?(r=e.input.slice(t,e.position),i=e.input.charCodeAt(++e.position)):d(e,"unexpected end of the stream within a verbatim tag")}else{for(;0!==i&&!a(i);)33===i&&(s?d(e,"tag suffix cannot contain exclamation marks"):(n=e.input.slice(t-1,e.position+1),ne.test(n)||d(e,"named tag handle cannot contain such characters"),s=!0,t=e.position+1)),i=e.input.charCodeAt(++e.position);r=e.input.slice(t,e.position),te.test(r)&&d(e,"tag suffix cannot contain flow indicator characters")}return r&&!re.test(r)&&d(e,"tag name cannot contain such characters: "+r),o?e.tag=r:H.call(e.tagMap,n)?e.tag=e.tagMap[n]+r:"!"===n?e.tag="!"+r:"!!"===n?e.tag="tag:yaml.org,2002:"+r:d(e,'undeclared tag handle "'+n+'"'),!0}function I(e){var t,n;if(n=e.input.charCodeAt(e.position),38!==n)return!1;for(null!==e.anchor&&d(e,"duplication of an anchor property"),n=e.input.charCodeAt(++e.position),t=e.position;0!==n&&!a(n)&&!o(n);)n=e.input.charCodeAt(++e.position);return e.position===t&&d(e,"name of an anchor node must contain at least one character"),e.anchor=e.input.slice(t,e.position),!0}function D(e){var t,n,r;if(r=e.input.charCodeAt(e.position),42!==r)return!1;for(r=e.input.charCodeAt(++e.position),t=e.position;0!==r&&!a(r)&&!o(r);)r=e.input.charCodeAt(++e.position);return e.position===t&&d(e,"name of an alias node must contain at least one character"),n=e.input.slice(t,e.position),e.anchorMap.hasOwnProperty(n)||d(e,'unidentified alias "'+n+'"'),e.result=e.anchorMap[n],w(e,!0,-1),!0}function L(e,t,n,r,i){var a,o,s,l,u,c,p,h,f=1,m=!1,g=!1;if(null!==e.listener&&e.listener("open",e),e.tag=null,e.anchor=null,e.kind=null,e.result=null,a=o=s=Q===n||W===n,r&&w(e,!0,-1)&&(m=!0,e.lineIndent>t?f=1:e.lineIndent===t?f=0:e.lineIndent<t&&(f=-1)),1===f)for(;C(e)||I(e);)w(e,!0,-1)?(m=!0,s=a,e.lineIndent>t?f=1:e.lineIndent===t?f=0:e.lineIndent<t&&(f=-1)):s=!1;if(s&&(s=m||i),1!==f&&Q!==n||(p=Y===n||J===n?t:t+1,h=e.position-e.lineStart,1===f?s&&(k(e,h)||T(e,h,p))||E(e,p)?g=!0:(o&&O(e,p)||S(e,p)||j(e,p)?g=!0:D(e)?(g=!0,null===e.tag&&null===e.anchor||d(e,"alias node should not have any properties")):A(e,p,Y===n)&&(g=!0,null===e.tag&&(e.tag="?")),null!==e.anchor&&(e.anchorMap[e.anchor]=e.result)):0===f&&(g=s&&k(e,h))),null!==e.tag&&"!"!==e.tag)if("?"===e.tag){for(l=0,u=e.implicitTypes.length;l<u;l+=1)if(c=e.implicitTypes[l],c.resolve(e.result)){e.result=c.construct(e.result),e.tag=c.tag,null!==e.anchor&&(e.anchorMap[e.anchor]=e.result);break}}else H.call(e.typeMap,e.tag)?(c=e.typeMap[e.tag],null!==e.result&&c.kind!==e.kind&&d(e,"unacceptable node kind for !<"+e.tag+'> tag; it should be "'+c.kind+'", not "'+e.kind+'"'),c.resolve(e.result)?(e.result=c.construct(e.result),null!==e.anchor&&(e.anchorMap[e.anchor]=e.result)):d(e,"cannot resolve a node with !<"+e.tag+"> explicit tag")):d(e,"unknown tag !<"+e.tag+">");return null!==e.listener&&e.listener("close",e),null!==e.tag||null!==e.anchor||g}function M(e){var t,n,o,s,l=e.position,u=!1;for(e.version=null,e.checkLineBreaks=e.legacy,e.tagMap={},e.anchorMap={};0!==(s=e.input.charCodeAt(e.position))&&(w(e,!0,-1),s=e.input.charCodeAt(e.position),!(e.lineIndent>0||37!==s));){for(u=!0,s=e.input.charCodeAt(++e.position),t=e.position;0!==s&&!a(s);)s=e.input.charCodeAt(++e.position);for(n=e.input.slice(t,e.position),o=[],n.length<1&&d(e,"directive name must not be less than one character in length");0!==s;){for(;i(s);)s=e.input.charCodeAt(++e.position);if(35===s){do s=e.input.charCodeAt(++e.position);while(0!==s&&!r(s));break}if(r(s))break;for(t=e.position;0!==s&&!a(s);)s=e.input.charCodeAt(++e.position);o.push(e.input.slice(t,e.position))}0!==s&&b(e),H.call(se,n)?se[n](e,n,o):m(e,'unknown document directive "'+n+'"')}return w(e,!0,-1),0===e.lineIndent&&45===e.input.charCodeAt(e.position)&&45===e.input.charCodeAt(e.position+1)&&45===e.input.charCodeAt(e.position+2)?(e.position+=3,w(e,!0,-1)):u&&d(e,"directives end mark is expected"),L(e,e.lineIndent-1,Q,!1,!0),w(e,!0,-1),e.checkLineBreaks&&ee.test(e.input.slice(l,e.position))&&m(e,"non-ASCII line breaks are interpreted as content"),e.documents.push(e.result),e.position===e.lineStart&&_(e)?void(46===e.input.charCodeAt(e.position)&&(e.position+=3,w(e,!0,-1))):void(e.position<e.length-1&&d(e,"end of the stream or a document separator is expected"))}function R(e,t){e=String(e),t=t||{},0!==e.length&&(10!==e.charCodeAt(e.length-1)&&13!==e.charCodeAt(e.length-1)&&(e+="\n"),65279===e.charCodeAt(0)&&(e=e.slice(1)));var n=new h(e,t);for(n.input+="\0";32===n.input.charCodeAt(n.position);)n.lineIndent+=1,n.position+=1;for(;n.position<n.length-1;)M(n);return n.documents}function U(e,t,n){var r,i,a=R(e,n);for(r=0,i=a.length;r<i;r+=1)t(a[r])}function P(e,t){var n=R(e,t);if(0!==n.length){if(1===n.length)return n[0];throw new z("expected a single document in the stream, but found more")}}function q(e,t,n){U(e,t,N.extend({schema:F},n))}function B(e,t){return P(e,N.extend({schema:F},t))}for(var N=e("./common"),z=e("./exception"),$=e("./mark"),F=e("./schema/default_safe"),V=e("./schema/default_full"),H=Object.prototype.hasOwnProperty,Y=1,J=2,W=3,Q=4,G=1,K=2,X=3,Z=/[\x00-\x08\x0B\x0C\x0E-\x1F\x7F-\x84\x86-\x9F\uFFFE\uFFFF]|[\uD800-\uDBFF](?![\uDC00-\uDFFF])|(?:[^\uD800-\uDBFF]|^)[\uDC00-\uDFFF]/,ee=/[\x85\u2028\u2029]/,te=/[,\[\]\{\}]/,ne=/^(?:!|!!|![a-z\-]+!)$/i,re=/^(?:!|[^,\[\]\{\}])(?:%[0-9a-f]{2}|[0-9a-z\-#;\/\?:@&=\+\$,_\.!~\*'\(\)\[\]])*$/i,ie=new Array(256),ae=new Array(256),oe=0;oe<256;oe++)ie[oe]=c(oe)?1:0,ae[oe]=c(oe);var se={YAML:function(e,t,n){var r,i,a;null!==e.version&&d(e,"duplication of %YAML directive"),1!==n.length&&d(e,"YAML directive accepts exactly one argument"),r=/^([0-9]+)\.([0-9]+)$/.exec(n[0]),null===r&&d(e,"ill-formed argument of the YAML directive"),i=parseInt(r[1],10),a=parseInt(r[2],10),1!==i&&d(e,"unacceptable YAML version of the document"),e.version=n[0],e.checkLineBreaks=a<2,1!==a&&2!==a&&m(e,"unsupported YAML version of the document")},TAG:function(e,t,n){var r,i;2!==n.length&&d(e,"TAG directive accepts exactly two arguments"),r=n[0],i=n[1],ne.test(r)||d(e,"ill-formed tag handle (first argument) of the TAG directive"),H.call(e.tagMap,r)&&d(e,'there is a previously declared suffix for "'+r+'" tag handle'),re.test(i)||d(e,"ill-formed tag prefix (second argument) of the TAG directive"),e.tagMap[r]=i}};t.exports.loadAll=U,t.exports.load=P,t.exports.safeLoadAll=q,t.exports.safeLoad=B},{"./common":21,"./exception":23,"./mark":25,"./schema/default_full":28,"./schema/default_safe":29}],25:[function(e,t,n){"use strict";function r(e,t,n,r,i){this.name=e,this.buffer=t,this.position=n,this.line=r,this.column=i}var i=e("./common");r.prototype.getSnippet=function(e,t){var n,r,a,o,s;if(!this.buffer)return null;for(e=e||4,t=t||75,n="",r=this.position;r>0&&"\0\r\n…\u2028\u2029".indexOf(this.buffer.charAt(r-1))===-1;)if(r-=1,this.position-r>t/2-1){n=" ... ",r+=5;break}for(a="",o=this.position;o<this.buffer.length&&"\0\r\n…\u2028\u2029".indexOf(this.buffer.charAt(o))===-1;)if(o+=1,o-this.position>t/2-1){a=" ... ",o-=5;break}return s=this.buffer.slice(r,o),i.repeat(" ",e)+n+s+a+"\n"+i.repeat(" ",e+this.position-r+n.length)+"^"},r.prototype.toString=function(e){var t,n="";return this.name&&(n+='in "'+this.name+'" '),n+="at line "+(this.line+1)+", column "+(this.column+1),e||(t=this.getSnippet(),t&&(n+=":\n"+t)),n},t.exports=r},{"./common":21}],26:[function(e,t,n){"use strict";function r(e,t,n){var i=[];return e.include.forEach(function(e){n=r(e,t,n)}),e[t].forEach(function(e){n.forEach(function(t,n){t.tag===e.tag&&i.push(n)}),n.push(e)}),n.filter(function(e,t){return i.indexOf(t)===-1})}function i(){function e(e){r[e.tag]=e}var t,n,r={};for(t=0,n=arguments.length;t<n;t+=1)arguments[t].forEach(e);return r}function a(e){this.include=e.include||[],this.implicit=e.implicit||[],this.explicit=e.explicit||[],this.implicit.forEach(function(e){if(e.loadKind&&"scalar"!==e.loadKind)throw new s("There is a non-scalar type in the implicit list of a schema. Implicit resolving of such types is not supported.")}),this.compiledImplicit=r(this,"implicit",[]),this.compiledExplicit=r(this,"explicit",[]),this.compiledTypeMap=i(this.compiledImplicit,this.compiledExplicit)}var o=e("./common"),s=e("./exception"),l=e("./type");a.DEFAULT=null,a.create=function(){var e,t;switch(arguments.length){case 1:e=a.DEFAULT,t=arguments[0];break;case 2:e=arguments[0],t=arguments[1];break;default:throw new s("Wrong number of arguments for Schema.create function")}if(e=o.toArray(e),t=o.toArray(t),!e.every(function(e){return e instanceof a}))throw new s("Specified list of super schemas (or a single Schema object) contains a non-Schema object.");if(!t.every(function(e){return e instanceof l}))throw new s("Specified list of YAML types (or a single Type object) contains a non-Type object.");return new a({include:e,explicit:t})},t.exports=a},{"./common":21,"./exception":23,"./type":32}],27:[function(e,t,n){"use strict";var r=e("../schema");t.exports=new r({include:[e("./json")]})},{"../schema":26,"./json":31}],28:[function(e,t,n){"use strict";var r=e("../schema");t.exports=r.DEFAULT=new r({include:[e("./default_safe")],explicit:[e("../type/js/undefined"),e("../type/js/regexp"),e("../type/js/function")]})},{"../schema":26,"../type/js/function":37,"../type/js/regexp":38,"../type/js/undefined":39,"./default_safe":29}],29:[function(e,t,n){"use strict";var r=e("../schema");t.exports=new r({include:[e("./core")],implicit:[e("../type/timestamp"),e("../type/merge")],explicit:[e("../type/binary"),e("../type/omap"),e("../type/pairs"),e("../type/set")]})},{"../schema":26,"../type/binary":33,"../type/merge":41,"../type/omap":43,"../type/pairs":44,"../type/set":46,"../type/timestamp":48,"./core":27}],30:[function(e,t,n){"use strict";var r=e("../schema");t.exports=new r({explicit:[e("../type/str"),e("../type/seq"),e("../type/map")]})},{"../schema":26,"../type/map":40,"../type/seq":45,"../type/str":47}],31:[function(e,t,n){"use strict";var r=e("../schema");t.exports=new r({include:[e("./failsafe")],implicit:[e("../type/null"),e("../type/bool"),e("../type/int"),e("../type/float")]})},{"../schema":26,"../type/bool":34,"../type/float":35,"../type/int":36,"../type/null":42,"./failsafe":30}],32:[function(e,t,n){"use strict";function r(e){var t={};return null!==e&&Object.keys(e).forEach(function(n){e[n].forEach(function(e){t[String(e)]=n})}),t}function i(e,t){if(t=t||{},Object.keys(t).forEach(function(t){if(o.indexOf(t)===-1)throw new a('Unknown option "'+t+'" is met in definition of "'+e+'" YAML type.')}),this.tag=e,this.kind=t.kind||null,this.resolve=t.resolve||function(){return!0},this.construct=t.construct||function(e){return e},this.instanceOf=t.instanceOf||null,this.predicate=t.predicate||null,this.represent=t.represent||null,this.defaultStyle=t.defaultStyle||null,this.styleAliases=r(t.styleAliases||null),s.indexOf(this.kind)===-1)throw new a('Unknown kind "'+this.kind+'" is specified for "'+e+'" YAML type.')}var a=e("./exception"),o=["kind","resolve","construct","instanceOf","predicate","represent","defaultStyle","styleAliases"],s=["scalar","sequence","mapping"];t.exports=i},{"./exception":23}],33:[function(e,t,n){"use strict";function r(e){if(null===e)return!1;var t,n,r=0,i=e.length,a=p;for(n=0;n<i;n++)if(t=a.indexOf(e.charAt(n)),!(t>64)){if(t<0)return!1;r+=6}return r%8===0}function i(e){var t,n,r=e.replace(/[\r\n=]/g,""),i=r.length,a=p,o=0,l=[];for(t=0;t<i;t++)t%4===0&&t&&(l.push(o>>16&255),l.push(o>>8&255),l.push(255&o)),o=o<<6|a.indexOf(r.charAt(t));return n=i%4*6,0===n?(l.push(o>>16&255),l.push(o>>8&255),l.push(255&o)):18===n?(l.push(o>>10&255),l.push(o>>2&255)):12===n&&l.push(o>>4&255),s?new s(l):l}function a(e){var t,n,r="",i=0,a=e.length,o=p;for(t=0;t<a;t++)t%3===0&&t&&(r+=o[i>>18&63],r+=o[i>>12&63],r+=o[i>>6&63],r+=o[63&i]),i=(i<<8)+e[t];return n=a%3,0===n?(r+=o[i>>18&63],r+=o[i>>12&63],r+=o[i>>6&63],r+=o[63&i]):2===n?(r+=o[i>>10&63],r+=o[i>>4&63],r+=o[i<<2&63],r+=o[64]):1===n&&(r+=o[i>>2&63],r+=o[i<<4&63],r+=o[64],r+=o[64]),r}function o(e){return s&&s.isBuffer(e)}var s;try{var l=e;s=l("buffer").Buffer}catch(u){}var c=e("../type"),p="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=\n\r";t.exports=new c("tag:yaml.org,2002:binary",{kind:"scalar",resolve:r,construct:i,predicate:o,represent:a})},{"../type":32}],34:[function(e,t,n){"use strict";function r(e){if(null===e)return!1;var t=e.length;return 4===t&&("true"===e||"True"===e||"TRUE"===e)||5===t&&("false"===e||"False"===e||"FALSE"===e)}function i(e){return"true"===e||"True"===e||"TRUE"===e}function a(e){return"[object Boolean]"===Object.prototype.toString.call(e)}var o=e("../type");t.exports=new o("tag:yaml.org,2002:bool",{kind:"scalar",resolve:r,construct:i,predicate:a,represent:{lowercase:function(e){return e?"true":"false"},uppercase:function(e){return e?"TRUE":"FALSE"},camelcase:function(e){return e?"True":"False"}},defaultStyle:"lowercase"})},{"../type":32}],35:[function(e,t,n){"use strict";function r(e){return null!==e&&!!u.test(e)}function i(e){var t,n,r,i;return t=e.replace(/_/g,"").toLowerCase(),n="-"===t[0]?-1:1,i=[],"+-".indexOf(t[0])>=0&&(t=t.slice(1)),".inf"===t?1===n?Number.POSITIVE_INFINITY:Number.NEGATIVE_INFINITY:".nan"===t?NaN:t.indexOf(":")>=0?(t.split(":").forEach(function(e){i.unshift(parseFloat(e,10))}),t=0,r=1,i.forEach(function(e){t+=e*r,r*=60}),n*t):n*parseFloat(t,10)}function a(e,t){var n;if(isNaN(e))switch(t){case"lowercase":return".nan";case"uppercase":return".NAN";case"camelcase":return".NaN"}else if(Number.POSITIVE_INFINITY===e)switch(t){case"lowercase":return".inf";case"uppercase":return".INF";case"camelcase":return".Inf"}else if(Number.NEGATIVE_INFINITY===e)switch(t){case"lowercase":return"-.inf";case"uppercase":return"-.INF";case"camelcase":return"-.Inf"}else if(s.isNegativeZero(e))return"-0.0";return n=e.toString(10),c.test(n)?n.replace("e",".e"):n}function o(e){return"[object Number]"===Object.prototype.toString.call(e)&&(e%1!==0||s.isNegativeZero(e))}var s=e("../common"),l=e("../type"),u=new RegExp("^(?:[-+]?(?:[0-9][0-9_]*)\\.[0-9_]*(?:[eE][-+][0-9]+)?|\\.[0-9_]+(?:[eE][-+][0-9]+)?|[-+]?[0-9][0-9_]*(?::[0-5]?[0-9])+\\.[0-9_]*|[-+]?\\.(?:inf|Inf|INF)|\\.(?:nan|NaN|NAN))$"),c=/^[-+]?[0-9]+e/;t.exports=new l("tag:yaml.org,2002:float",{kind:"scalar",resolve:r,construct:i,predicate:o,represent:a,defaultStyle:"lowercase"})},{"../common":21,"../type":32}],36:[function(e,t,n){"use strict";function r(e){return 48<=e&&e<=57||65<=e&&e<=70||97<=e&&e<=102}function i(e){return 48<=e&&e<=55}function a(e){return 48<=e&&e<=57}function o(e){if(null===e)return!1;var t,n=e.length,o=0,s=!1;if(!n)return!1;if(t=e[o],"-"!==t&&"+"!==t||(t=e[++o]),"0"===t){if(o+1===n)return!0;if(t=e[++o],"b"===t){for(o++;o<n;o++)if(t=e[o],"_"!==t){if("0"!==t&&"1"!==t)return!1;s=!0}return s}if("x"===t){for(o++;o<n;o++)if(t=e[o],"_"!==t){if(!r(e.charCodeAt(o)))return!1;s=!0}return s}for(;o<n;o++)if(t=e[o],"_"!==t){if(!i(e.charCodeAt(o)))return!1;s=!0}return s}for(;o<n;o++)if(t=e[o],"_"!==t){if(":"===t)break;if(!a(e.charCodeAt(o)))return!1;s=!0}return!!s&&(":"!==t||/^(:[0-5]?[0-9])+$/.test(e.slice(o)))}function s(e){var t,n,r=e,i=1,a=[];return r.indexOf("_")!==-1&&(r=r.replace(/_/g,"")),t=r[0],"-"!==t&&"+"!==t||("-"===t&&(i=-1),
-r=r.slice(1),t=r[0]),"0"===r?0:"0"===t?"b"===r[1]?i*parseInt(r.slice(2),2):"x"===r[1]?i*parseInt(r,16):i*parseInt(r,8):r.indexOf(":")!==-1?(r.split(":").forEach(function(e){a.unshift(parseInt(e,10))}),r=0,n=1,a.forEach(function(e){r+=e*n,n*=60}),i*r):i*parseInt(r,10)}function l(e){return"[object Number]"===Object.prototype.toString.call(e)&&e%1===0&&!u.isNegativeZero(e)}var u=e("../common"),c=e("../type");t.exports=new c("tag:yaml.org,2002:int",{kind:"scalar",resolve:o,construct:s,predicate:l,represent:{binary:function(e){return"0b"+e.toString(2)},octal:function(e){return"0"+e.toString(8)},decimal:function(e){return e.toString(10)},hexadecimal:function(e){return"0x"+e.toString(16).toUpperCase()}},defaultStyle:"decimal",styleAliases:{binary:[2,"bin"],octal:[8,"oct"],decimal:[10,"dec"],hexadecimal:[16,"hex"]}})},{"../common":21,"../type":32}],37:[function(e,t,n){"use strict";function r(e){if(null===e)return!1;try{var t="("+e+")",n=s.parse(t,{range:!0});return"Program"===n.type&&1===n.body.length&&"ExpressionStatement"===n.body[0].type&&"FunctionExpression"===n.body[0].expression.type}catch(r){return!1}}function i(e){var t,n="("+e+")",r=s.parse(n,{range:!0}),i=[];if("Program"!==r.type||1!==r.body.length||"ExpressionStatement"!==r.body[0].type||"FunctionExpression"!==r.body[0].expression.type)throw new Error("Failed to resolve function");return r.body[0].expression.params.forEach(function(e){i.push(e.name)}),t=r.body[0].expression.body.range,new Function(i,n.slice(t[0]+1,t[1]-1))}function a(e){return e.toString()}function o(e){return"[object Function]"===Object.prototype.toString.call(e)}var s;try{var l=e;s=l("esprima")}catch(u){"undefined"!=typeof window&&(s=window.esprima)}var c=e("../../type");t.exports=new c("tag:yaml.org,2002:js/function",{kind:"scalar",resolve:r,construct:i,predicate:o,represent:a})},{"../../type":32}],38:[function(e,t,n){"use strict";function r(e){if(null===e)return!1;if(0===e.length)return!1;var t=e,n=/\/([gim]*)$/.exec(e),r="";if("/"===t[0]){if(n&&(r=n[1]),r.length>3)return!1;if("/"!==t[t.length-r.length-1])return!1}return!0}function i(e){var t=e,n=/\/([gim]*)$/.exec(e),r="";return"/"===t[0]&&(n&&(r=n[1]),t=t.slice(1,t.length-r.length-1)),new RegExp(t,r)}function a(e){var t="/"+e.source+"/";return e.global&&(t+="g"),e.multiline&&(t+="m"),e.ignoreCase&&(t+="i"),t}function o(e){return"[object RegExp]"===Object.prototype.toString.call(e)}var s=e("../../type");t.exports=new s("tag:yaml.org,2002:js/regexp",{kind:"scalar",resolve:r,construct:i,predicate:o,represent:a})},{"../../type":32}],39:[function(e,t,n){"use strict";function r(){return!0}function i(){}function a(){return""}function o(e){return"undefined"==typeof e}var s=e("../../type");t.exports=new s("tag:yaml.org,2002:js/undefined",{kind:"scalar",resolve:r,construct:i,predicate:o,represent:a})},{"../../type":32}],40:[function(e,t,n){"use strict";var r=e("../type");t.exports=new r("tag:yaml.org,2002:map",{kind:"mapping",construct:function(e){return null!==e?e:{}}})},{"../type":32}],41:[function(e,t,n){"use strict";function r(e){return"<<"===e||null===e}var i=e("../type");t.exports=new i("tag:yaml.org,2002:merge",{kind:"scalar",resolve:r})},{"../type":32}],42:[function(e,t,n){"use strict";function r(e){if(null===e)return!0;var t=e.length;return 1===t&&"~"===e||4===t&&("null"===e||"Null"===e||"NULL"===e)}function i(){return null}function a(e){return null===e}var o=e("../type");t.exports=new o("tag:yaml.org,2002:null",{kind:"scalar",resolve:r,construct:i,predicate:a,represent:{canonical:function(){return"~"},lowercase:function(){return"null"},uppercase:function(){return"NULL"},camelcase:function(){return"Null"}},defaultStyle:"lowercase"})},{"../type":32}],43:[function(e,t,n){"use strict";function r(e){if(null===e)return!0;var t,n,r,i,a,l=[],u=e;for(t=0,n=u.length;t<n;t+=1){if(r=u[t],a=!1,"[object Object]"!==s.call(r))return!1;for(i in r)if(o.call(r,i)){if(a)return!1;a=!0}if(!a)return!1;if(l.indexOf(i)!==-1)return!1;l.push(i)}return!0}function i(e){return null!==e?e:[]}var a=e("../type"),o=Object.prototype.hasOwnProperty,s=Object.prototype.toString;t.exports=new a("tag:yaml.org,2002:omap",{kind:"sequence",resolve:r,construct:i})},{"../type":32}],44:[function(e,t,n){"use strict";function r(e){if(null===e)return!0;var t,n,r,i,a,s=e;for(a=new Array(s.length),t=0,n=s.length;t<n;t+=1){if(r=s[t],"[object Object]"!==o.call(r))return!1;if(i=Object.keys(r),1!==i.length)return!1;a[t]=[i[0],r[i[0]]]}return!0}function i(e){if(null===e)return[];var t,n,r,i,a,o=e;for(a=new Array(o.length),t=0,n=o.length;t<n;t+=1)r=o[t],i=Object.keys(r),a[t]=[i[0],r[i[0]]];return a}var a=e("../type"),o=Object.prototype.toString;t.exports=new a("tag:yaml.org,2002:pairs",{kind:"sequence",resolve:r,construct:i})},{"../type":32}],45:[function(e,t,n){"use strict";var r=e("../type");t.exports=new r("tag:yaml.org,2002:seq",{kind:"sequence",construct:function(e){return null!==e?e:[]}})},{"../type":32}],46:[function(e,t,n){"use strict";function r(e){if(null===e)return!0;var t,n=e;for(t in n)if(o.call(n,t)&&null!==n[t])return!1;return!0}function i(e){return null!==e?e:{}}var a=e("../type"),o=Object.prototype.hasOwnProperty;t.exports=new a("tag:yaml.org,2002:set",{kind:"mapping",resolve:r,construct:i})},{"../type":32}],47:[function(e,t,n){"use strict";var r=e("../type");t.exports=new r("tag:yaml.org,2002:str",{kind:"scalar",construct:function(e){return null!==e?e:""}})},{"../type":32}],48:[function(e,t,n){"use strict";function r(e){return null!==e&&(null!==s.exec(e)||null!==l.exec(e))}function i(e){var t,n,r,i,a,o,u,c,p,h,f=0,d=null;if(t=s.exec(e),null===t&&(t=l.exec(e)),null===t)throw new Error("Date resolve error");if(n=+t[1],r=+t[2]-1,i=+t[3],!t[4])return new Date(Date.UTC(n,r,i));if(a=+t[4],o=+t[5],u=+t[6],t[7]){for(f=t[7].slice(0,3);f.length<3;)f+="0";f=+f}return t[9]&&(c=+t[10],p=+(t[11]||0),d=6e4*(60*c+p),"-"===t[9]&&(d=-d)),h=new Date(Date.UTC(n,r,i,a,o,u,f)),d&&h.setTime(h.getTime()-d),h}function a(e){return e.toISOString()}var o=e("../type"),s=new RegExp("^([0-9][0-9][0-9][0-9])-([0-9][0-9])-([0-9][0-9])$"),l=new RegExp("^([0-9][0-9][0-9][0-9])-([0-9][0-9]?)-([0-9][0-9]?)(?:[Tt]|[ \\t]+)([0-9][0-9]?):([0-9][0-9]):([0-9][0-9])(?:\\.([0-9]*))?(?:[ \\t]*(Z|([-+])([0-9][0-9]?)(?::([0-9][0-9]))?))?$");t.exports=new o("tag:yaml.org,2002:timestamp",{kind:"scalar",resolve:r,construct:i,instanceOf:Date,represent:a})},{"../type":32}],49:[function(e,t,n){function r(e,t,n){var r=e?e.length:0;if(!r)return-1;if("number"==typeof n)n=n<0?o(r+n,0):n;else if(n){var s=a(e,t);return s<r&&(t===t?t===e[s]:e[s]!==e[s])?s:-1}return i(e,t,n||0)}var i=e("../internal/baseIndexOf"),a=e("../internal/binaryIndex"),o=Math.max;t.exports=r},{"../internal/baseIndexOf":78,"../internal/binaryIndex":92}],50:[function(e,t,n){function r(e){var t=e?e.length:0;return t?e[t-1]:void 0}t.exports=r},{}],51:[function(e,t,n){function r(e){if(l(e)&&!s(e)&&!(e instanceof i)){if(e instanceof a)return e;if(p.call(e,"__chain__")&&p.call(e,"__wrapped__"))return u(e)}return new a(e)}var i=e("../internal/LazyWrapper"),a=e("../internal/LodashWrapper"),o=e("../internal/baseLodash"),s=e("../lang/isArray"),l=e("../internal/isObjectLike"),u=e("../internal/wrapperClone"),c=Object.prototype,p=c.hasOwnProperty;r.prototype=o.prototype,t.exports=r},{"../internal/LazyWrapper":60,"../internal/LodashWrapper":61,"../internal/baseLodash":82,"../internal/isObjectLike":126,"../internal/wrapperClone":137,"../lang/isArray":140}],52:[function(e,t,n){t.exports=e("./forEach")},{"./forEach":54}],53:[function(e,t,n){var r=e("../internal/baseEach"),i=e("../internal/createFind"),a=i(r);t.exports=a},{"../internal/baseEach":71,"../internal/createFind":102}],54:[function(e,t,n){var r=e("../internal/arrayEach"),i=e("../internal/baseEach"),a=e("../internal/createForEach"),o=a(r,i);t.exports=o},{"../internal/arrayEach":63,"../internal/baseEach":71,"../internal/createForEach":103}],55:[function(e,t,n){function r(e,t,n,r){var h=e?a(e):0;return l(h)||(e=c(e),h=e.length),n="number"!=typeof n||r&&s(t,n,r)?0:n<0?p(h+n,0):n||0,"string"==typeof e||!o(e)&&u(e)?n<=h&&e.indexOf(t,n)>-1:!!h&&i(e,t,n)>-1}var i=e("../internal/baseIndexOf"),a=e("../internal/getLength"),o=e("../lang/isArray"),s=e("../internal/isIterateeCall"),l=e("../internal/isLength"),u=e("../lang/isString"),c=e("../object/values"),p=Math.max;t.exports=r},{"../internal/baseIndexOf":78,"../internal/getLength":112,"../internal/isIterateeCall":122,"../internal/isLength":125,"../lang/isArray":140,"../lang/isString":146,"../object/values":152}],56:[function(e,t,n){function r(e,t,n){var r=s(e)?i:o;return t=a(t,n,3),r(e,t)}var i=e("../internal/arrayMap"),a=e("../internal/baseCallback"),o=e("../internal/baseMap"),s=e("../lang/isArray");t.exports=r},{"../internal/arrayMap":64,"../internal/baseCallback":67,"../internal/baseMap":83,"../lang/isArray":140}],57:[function(e,t,n){var r=e("../internal/getNative"),i=r(Date,"now"),a=i||function(){return(new Date).getTime()};t.exports=a},{"../internal/getNative":114}],58:[function(e,t,n){var r=e("../internal/createWrapper"),i=e("../internal/replaceHolders"),a=e("./restParam"),o=1,s=32,l=a(function(e,t,n){var a=o;if(n.length){var u=i(n,l.placeholder);a|=s}return r(e,a,t,n,u)});l.placeholder={},t.exports=l},{"../internal/createWrapper":106,"../internal/replaceHolders":132,"./restParam":59}],59:[function(e,t,n){function r(e,t){if("function"!=typeof e)throw new TypeError(i);return t=a(void 0===t?e.length-1:+t||0,0),function(){for(var n=arguments,r=-1,i=a(n.length-t,0),o=Array(i);++r<i;)o[r]=n[t+r];switch(t){case 0:return e.call(this,o);case 1:return e.call(this,n[0],o);case 2:return e.call(this,n[0],n[1],o)}var s=Array(t+1);for(r=-1;++r<t;)s[r]=n[r];return s[t]=o,e.apply(this,s)}}var i="Expected a function",a=Math.max;t.exports=r},{}],60:[function(e,t,n){function r(e){this.__wrapped__=e,this.__actions__=[],this.__dir__=1,this.__filtered__=!1,this.__iteratees__=[],this.__takeCount__=o,this.__views__=[]}var i=e("./baseCreate"),a=e("./baseLodash"),o=Number.POSITIVE_INFINITY;r.prototype=i(a.prototype),r.prototype.constructor=r,t.exports=r},{"./baseCreate":70,"./baseLodash":82}],61:[function(e,t,n){function r(e,t,n){this.__wrapped__=e,this.__actions__=n||[],this.__chain__=!!t}var i=e("./baseCreate"),a=e("./baseLodash");r.prototype=i(a.prototype),r.prototype.constructor=r,t.exports=r},{"./baseCreate":70,"./baseLodash":82}],62:[function(e,t,n){function r(e,t){var n=-1,r=e.length;for(t||(t=Array(r));++n<r;)t[n]=e[n];return t}t.exports=r},{}],63:[function(e,t,n){function r(e,t){for(var n=-1,r=e.length;++n<r&&t(e[n],n,e)!==!1;);return e}t.exports=r},{}],64:[function(e,t,n){function r(e,t){for(var n=-1,r=e.length,i=Array(r);++n<r;)i[n]=t(e[n],n,e);return i}t.exports=r},{}],65:[function(e,t,n){function r(e,t){for(var n=-1,r=e.length;++n<r;)if(t(e[n],n,e))return!0;return!1}t.exports=r},{}],66:[function(e,t,n){function r(e,t){return null==t?e:i(t,a(t),e)}var i=e("./baseCopy"),a=e("../object/keys");t.exports=r},{"../object/keys":149,"./baseCopy":69}],67:[function(e,t,n){function r(e,t,n){var r=typeof e;return"function"==r?void 0===t?e:o(e,t,n):null==e?s:"object"==r?i(e):void 0===t?l(e):a(e,t)}var i=e("./baseMatches"),a=e("./baseMatchesProperty"),o=e("./bindCallback"),s=e("../utility/identity"),l=e("../utility/property");t.exports=r},{"../utility/identity":154,"../utility/property":156,"./baseMatches":84,"./baseMatchesProperty":85,"./bindCallback":94}],68:[function(e,t,n){function r(e,t,n,m,g,y,v){var w;if(n&&(w=g?n(e,m,g):n(e)),void 0!==w)return w;if(!f(e))return e;var _=p(e);if(_){if(w=l(e),!t)return i(e,w)}else{var A=B.call(e),S=A==b;if(A!=x&&A!=d&&(!S||g))return P[A]?u(e,A,t):g?e:{};if(h(e))return g?e:{};if(w=c(S?{}:e),!t)return o(w,e)}y||(y=[]),v||(v=[]);for(var j=y.length;j--;)if(y[j]==e)return v[j];return y.push(e),v.push(w),(_?a:s)(e,function(i,a){w[a]=r(i,t,n,a,e,y,v)}),w}var i=e("./arrayCopy"),a=e("./arrayEach"),o=e("./baseAssign"),s=e("./baseForOwn"),l=e("./initCloneArray"),u=e("./initCloneByTag"),c=e("./initCloneObject"),p=e("../lang/isArray"),h=e("./isHostObject"),f=e("../lang/isObject"),d="[object Arguments]",m="[object Array]",g="[object Boolean]",y="[object Date]",v="[object Error]",b="[object Function]",w="[object Map]",_="[object Number]",x="[object Object]",A="[object RegExp]",S="[object Set]",j="[object String]",E="[object WeakMap]",O="[object ArrayBuffer]",k="[object Float32Array]",T="[object Float64Array]",C="[object Int8Array]",I="[object Int16Array]",D="[object Int32Array]",L="[object Uint8Array]",M="[object Uint8ClampedArray]",R="[object Uint16Array]",U="[object Uint32Array]",P={};P[d]=P[m]=P[O]=P[g]=P[y]=P[k]=P[T]=P[C]=P[I]=P[D]=P[_]=P[x]=P[A]=P[j]=P[L]=P[M]=P[R]=P[U]=!0,P[v]=P[b]=P[w]=P[S]=P[E]=!1;var q=Object.prototype,B=q.toString;t.exports=r},{"../lang/isArray":140,"../lang/isObject":144,"./arrayCopy":62,"./arrayEach":63,"./baseAssign":66,"./baseForOwn":76,"./initCloneArray":116,"./initCloneByTag":117,"./initCloneObject":118,"./isHostObject":120}],69:[function(e,t,n){function r(e,t,n){n||(n={});for(var r=-1,i=t.length;++r<i;){var a=t[r];n[a]=e[a]}return n}t.exports=r},{}],70:[function(e,t,n){var r=e("../lang/isObject"),i=function(){function e(){}return function(t){if(r(t)){e.prototype=t;var n=new e;e.prototype=void 0}return n||{}}}();t.exports=i},{"../lang/isObject":144}],71:[function(e,t,n){var r=e("./baseForOwn"),i=e("./createBaseEach"),a=i(r);t.exports=a},{"./baseForOwn":76,"./createBaseEach":98}],72:[function(e,t,n){function r(e,t,n,r){var i;return n(e,function(e,n,a){if(t(e,n,a))return i=r?n:e,!1}),i}t.exports=r},{}],73:[function(e,t,n){function r(e,t,n){for(var r=e.length,i=n?r:-1;n?i--:++i<r;)if(t(e[i],i,e))return i;return-1}t.exports=r},{}],74:[function(e,t,n){var r=e("./createBaseFor"),i=r();t.exports=i},{"./createBaseFor":99}],75:[function(e,t,n){function r(e,t){return i(e,t,a)}var i=e("./baseFor"),a=e("../object/keysIn");t.exports=r},{"../object/keysIn":150,"./baseFor":74}],76:[function(e,t,n){function r(e,t){return i(e,t,a)}var i=e("./baseFor"),a=e("../object/keys");t.exports=r},{"../object/keys":149,"./baseFor":74}],77:[function(e,t,n){function r(e,t,n){if(null!=e){e=i(e),void 0!==n&&n in e&&(t=[n]);for(var r=0,a=t.length;null!=e&&r<a;)e=i(e)[t[r++]];return r&&r==a?e:void 0}}var i=e("./toObject");t.exports=r},{"./toObject":135}],78:[function(e,t,n){function r(e,t,n){if(t!==t)return i(e,n);for(var r=n-1,a=e.length;++r<a;)if(e[r]===t)return r;return-1}var i=e("./indexOfNaN");t.exports=r},{"./indexOfNaN":115}],79:[function(e,t,n){function r(e,t,n,s,l,u){return e===t||(null==e||null==t||!a(e)&&!o(t)?e!==e&&t!==t:i(e,t,r,n,s,l,u))}var i=e("./baseIsEqualDeep"),a=e("../lang/isObject"),o=e("./isObjectLike");t.exports=r},{"../lang/isObject":144,"./baseIsEqualDeep":80,"./isObjectLike":126}],80:[function(e,t,n){function r(e,t,n,r,f,g,y){var v=s(e),b=s(t),w=p,_=p;v||(w=m.call(e),w==c?w=h:w!=h&&(v=u(e))),b||(_=m.call(t),_==c?_=h:_!=h&&(b=u(t)));var x=w==h&&!l(e),A=_==h&&!l(t),S=w==_;if(S&&!v&&!x)return a(e,t,w);if(!f){var j=x&&d.call(e,"__wrapped__"),E=A&&d.call(t,"__wrapped__");if(j||E)return n(j?e.value():e,E?t.value():t,r,f,g,y)}if(!S)return!1;g||(g=[]),y||(y=[]);for(var O=g.length;O--;)if(g[O]==e)return y[O]==t;g.push(e),y.push(t);var k=(v?i:o)(e,t,n,r,f,g,y);return g.pop(),y.pop(),k}var i=e("./equalArrays"),a=e("./equalByTag"),o=e("./equalObjects"),s=e("../lang/isArray"),l=e("./isHostObject"),u=e("../lang/isTypedArray"),c="[object Arguments]",p="[object Array]",h="[object Object]",f=Object.prototype,d=f.hasOwnProperty,m=f.toString;t.exports=r},{"../lang/isArray":140,"../lang/isTypedArray":147,"./equalArrays":107,"./equalByTag":108,"./equalObjects":109,"./isHostObject":120}],81:[function(e,t,n){function r(e,t,n){var r=t.length,o=r,s=!n;if(null==e)return!o;for(e=a(e);r--;){var l=t[r];if(s&&l[2]?l[1]!==e[l[0]]:!(l[0]in e))return!1}for(;++r<o;){l=t[r];var u=l[0],c=e[u],p=l[1];if(s&&l[2]){if(void 0===c&&!(u in e))return!1}else{var h=n?n(c,p,u):void 0;if(!(void 0===h?i(p,c,n,!0):h))return!1}}return!0}var i=e("./baseIsEqual"),a=e("./toObject");t.exports=r},{"./baseIsEqual":79,"./toObject":135}],82:[function(e,t,n){function r(){}t.exports=r},{}],83:[function(e,t,n){function r(e,t){var n=-1,r=a(e)?Array(e.length):[];return i(e,function(e,i,a){r[++n]=t(e,i,a)}),r}var i=e("./baseEach"),a=e("./isArrayLike");t.exports=r},{"./baseEach":71,"./isArrayLike":119}],84:[function(e,t,n){function r(e){var t=a(e);if(1==t.length&&t[0][2]){var n=t[0][0],r=t[0][1];return function(e){return null!=e&&(e=o(e),e[n]===r&&(void 0!==r||n in e))}}return function(e){return i(e,t)}}var i=e("./baseIsMatch"),a=e("./getMatchData"),o=e("./toObject");t.exports=r},{"./baseIsMatch":81,"./getMatchData":113,"./toObject":135}],85:[function(e,t,n){function r(e,t){var n=s(e),r=l(e)&&u(t),f=e+"";return e=h(e),function(s){if(null==s)return!1;var l=f;if(s=p(s),(n||!r)&&!(l in s)){if(s=1==e.length?s:i(s,o(e,0,-1)),null==s)return!1;l=c(e),s=p(s)}return s[l]===t?void 0!==t||l in s:a(t,s[l],void 0,!0)}}var i=e("./baseGet"),a=e("./baseIsEqual"),o=e("./baseSlice"),s=e("../lang/isArray"),l=e("./isKey"),u=e("./isStrictComparable"),c=e("../array/last"),p=e("./toObject"),h=e("./toPath");t.exports=r},{"../array/last":50,"../lang/isArray":140,"./baseGet":77,"./baseIsEqual":79,"./baseSlice":89,"./isKey":123,"./isStrictComparable":127,"./toObject":135,"./toPath":136}],86:[function(e,t,n){function r(e){return function(t){return null==t?void 0:i(t)[e]}}var i=e("./toObject");t.exports=r},{"./toObject":135}],87:[function(e,t,n){function r(e){var t=e+"";return e=a(e),function(n){return i(n,e,t)}}var i=e("./baseGet"),a=e("./toPath");t.exports=r},{"./baseGet":77,"./toPath":136}],88:[function(e,t,n){var r=e("../utility/identity"),i=e("./metaMap"),a=i?function(e,t){return i.set(e,t),e}:r;t.exports=a},{"../utility/identity":154,"./metaMap":129}],89:[function(e,t,n){function r(e,t,n){var r=-1,i=e.length;t=null==t?0:+t||0,t<0&&(t=-t>i?0:i+t),n=void 0===n||n>i?i:+n||0,n<0&&(n+=i),i=t>n?0:n-t>>>0,t>>>=0;for(var a=Array(i);++r<i;)a[r]=e[r+t];return a}t.exports=r},{}],90:[function(e,t,n){function r(e){return null==e?"":e+""}t.exports=r},{}],91:[function(e,t,n){function r(e,t){for(var n=-1,r=t.length,i=Array(r);++n<r;)i[n]=e[t[n]];return i}t.exports=r},{}],92:[function(e,t,n){function r(e,t,n){var r=0,o=e?e.length:r;if("number"==typeof t&&t===t&&o<=s){for(;r<o;){var l=r+o>>>1,u=e[l];(n?u<=t:u<t)&&null!==u?r=l+1:o=l}return o}return i(e,t,a,n)}var i=e("./binaryIndexBy"),a=e("../utility/identity"),o=4294967295,s=o>>>1;t.exports=r},{"../utility/identity":154,"./binaryIndexBy":93}],93:[function(e,t,n){function r(e,t,n,r){t=n(t);for(var o=0,l=e?e.length:0,u=t!==t,c=null===t,p=void 0===t;o<l;){var h=i((o+l)/2),f=n(e[h]),d=void 0!==f,m=f===f;if(u)var g=m||r;else g=c?m&&d&&(r||null!=f):p?m&&(r||d):null!=f&&(r?f<=t:f<t);g?o=h+1:l=h}return a(l,s)}var i=Math.floor,a=Math.min,o=4294967295,s=o-1;t.exports=r},{}],94:[function(e,t,n){function r(e,t,n){if("function"!=typeof e)return i;if(void 0===t)return e;switch(n){case 1:return function(n){return e.call(t,n)};case 3:return function(n,r,i){return e.call(t,n,r,i)};case 4:return function(n,r,i,a){return e.call(t,n,r,i,a)};case 5:return function(n,r,i,a,o){return e.call(t,n,r,i,a,o)}}return function(){return e.apply(t,arguments)}}var i=e("../utility/identity");t.exports=r},{"../utility/identity":154}],95:[function(e,t,n){(function(e){function n(e){var t=new r(e.byteLength),n=new i(t);return n.set(new i(e)),t}var r=e.ArrayBuffer,i=e.Uint8Array;t.exports=n}).call(this,"undefined"!=typeof global?global:"undefined"!=typeof self?self:"undefined"!=typeof window?window:{})},{}],96:[function(e,t,n){function r(e,t,n){for(var r=n.length,a=-1,o=i(e.length-r,0),s=-1,l=t.length,u=Array(l+o);++s<l;)u[s]=t[s];for(;++a<r;)u[n[a]]=e[a];for(;o--;)u[s++]=e[a++];return u}var i=Math.max;t.exports=r},{}],97:[function(e,t,n){function r(e,t,n){for(var r=-1,a=n.length,o=-1,s=i(e.length-a,0),l=-1,u=t.length,c=Array(s+u);++o<s;)c[o]=e[o];for(var p=o;++l<u;)c[p+l]=t[l];for(;++r<a;)c[p+n[r]]=e[o++];return c}var i=Math.max;t.exports=r},{}],98:[function(e,t,n){function r(e,t){return function(n,r){var s=n?i(n):0;if(!a(s))return e(n,r);for(var l=t?s:-1,u=o(n);(t?l--:++l<s)&&r(u[l],l,u)!==!1;);return n}}var i=e("./getLength"),a=e("./isLength"),o=e("./toObject");t.exports=r},{"./getLength":112,"./isLength":125,"./toObject":135}],99:[function(e,t,n){function r(e){return function(t,n,r){for(var a=i(t),o=r(t),s=o.length,l=e?s:-1;e?l--:++l<s;){var u=o[l];if(n(a[u],u,a)===!1)break}return t}}var i=e("./toObject");t.exports=r},{"./toObject":135}],100:[function(e,t,n){(function(n){function r(e,t){function r(){var i=this&&this!==n&&this instanceof r?a:e;return i.apply(t,arguments)}var a=i(e);return r}var i=e("./createCtorWrapper");t.exports=r}).call(this,"undefined"!=typeof global?global:"undefined"!=typeof self?self:"undefined"!=typeof window?window:{})},{"./createCtorWrapper":101}],101:[function(e,t,n){function r(e){return function(){var t=arguments;switch(t.length){case 0:return new e;case 1:return new e(t[0]);case 2:return new e(t[0],t[1]);case 3:return new e(t[0],t[1],t[2]);case 4:return new e(t[0],t[1],t[2],t[3]);case 5:return new e(t[0],t[1],t[2],t[3],t[4]);case 6:return new e(t[0],t[1],t[2],t[3],t[4],t[5]);case 7:return new e(t[0],t[1],t[2],t[3],t[4],t[5],t[6])}var n=i(e.prototype),r=e.apply(n,t);return a(r)?r:n}}var i=e("./baseCreate"),a=e("../lang/isObject");t.exports=r},{"../lang/isObject":144,"./baseCreate":70}],102:[function(e,t,n){function r(e,t){return function(n,r,l){if(r=i(r,l,3),s(n)){var u=o(n,r,t);return u>-1?n[u]:void 0}return a(n,r,e)}}var i=e("./baseCallback"),a=e("./baseFind"),o=e("./baseFindIndex"),s=e("../lang/isArray");t.exports=r},{"../lang/isArray":140,"./baseCallback":67,"./baseFind":72,"./baseFindIndex":73}],103:[function(e,t,n){function r(e,t){return function(n,r,o){return"function"==typeof r&&void 0===o&&a(n)?e(n,r):t(n,i(r,o,3))}}var i=e("./bindCallback"),a=e("../lang/isArray");t.exports=r},{"../lang/isArray":140,"./bindCallback":94}],104:[function(e,t,n){(function(n){function r(e,t,_,x,A,S,j,E,O,k){function T(){for(var d=arguments.length,m=d,g=Array(d);m--;)g[m]=arguments[m];if(x&&(g=a(g,x,A)),S&&(g=o(g,S,j)),L||R){var b=T.placeholder,P=c(g,b);if(d-=P.length,d<k){var q=E?i(E):void 0,B=w(k-d,0),N=L?P:void 0,z=L?void 0:P,$=L?g:void 0,F=L?void 0:g;t|=L?y:v,t&=~(L?v:y),M||(t&=~(h|f));var V=[e,t,_,$,N,F,z,q,O,B],H=r.apply(void 0,V);return l(e)&&p(H,V),H.placeholder=b,H}}var Y=I?_:this,J=D?Y[e]:e;return E&&(g=u(g,E)),C&&O<g.length&&(g.length=O),this&&this!==n&&this instanceof T&&(J=U||s(e)),J.apply(Y,g)}var C=t&b,I=t&h,D=t&f,L=t&m,M=t&d,R=t&g,U=D?void 0:s(e);return T}var i=e("./arrayCopy"),a=e("./composeArgs"),o=e("./composeArgsRight"),s=e("./createCtorWrapper"),l=e("./isLaziable"),u=e("./reorder"),c=e("./replaceHolders"),p=e("./setData"),h=1,f=2,d=4,m=8,g=16,y=32,v=64,b=128,w=Math.max;t.exports=r}).call(this,"undefined"!=typeof global?global:"undefined"!=typeof self?self:"undefined"!=typeof window?window:{})},{"./arrayCopy":62,"./composeArgs":96,"./composeArgsRight":97,"./createCtorWrapper":101,"./isLaziable":124,"./reorder":131,"./replaceHolders":132,"./setData":133}],105:[function(e,t,n){(function(n){function r(e,t,r,o){function s(){for(var t=-1,i=arguments.length,a=-1,c=o.length,p=Array(c+i);++a<c;)p[a]=o[a];for(;i--;)p[a++]=arguments[++t];var h=this&&this!==n&&this instanceof s?u:e;return h.apply(l?r:this,p)}var l=t&a,u=i(e);return s}var i=e("./createCtorWrapper"),a=1;t.exports=r}).call(this,"undefined"!=typeof global?global:"undefined"!=typeof self?self:"undefined"!=typeof window?window:{})},{"./createCtorWrapper":101}],106:[function(e,t,n){function r(e,t,n,r,y,v,b,w){var _=t&h;if(!_&&"function"!=typeof e)throw new TypeError(m);var x=r?r.length:0;if(x||(t&=~(f|d),r=y=void 0),x-=y?y.length:0,t&d){var A=r,S=y;r=y=void 0}var j=_?void 0:l(e),E=[e,t,n,r,y,A,S,v,b,w];if(j&&(u(E,j),t=E[1],w=E[9]),E[9]=null==w?_?0:e.length:g(w-x,0)||0,t==p)var O=a(E[0],E[2]);else O=t!=f&&t!=(p|f)||E[4].length?o.apply(void 0,E):s.apply(void 0,E);var k=j?i:c;return k(O,E)}var i=e("./baseSetData"),a=e("./createBindWrapper"),o=e("./createHybridWrapper"),s=e("./createPartialWrapper"),l=e("./getData"),u=e("./mergeData"),c=e("./setData"),p=1,h=2,f=32,d=64,m="Expected a function",g=Math.max;t.exports=r},{"./baseSetData":88,"./createBindWrapper":100,"./createHybridWrapper":104,"./createPartialWrapper":105,"./getData":110,"./mergeData":128,"./setData":133}],107:[function(e,t,n){function r(e,t,n,r,a,o,s){var l=-1,u=e.length,c=t.length;if(u!=c&&!(a&&c>u))return!1;for(;++l<u;){var p=e[l],h=t[l],f=r?r(a?h:p,a?p:h,l):void 0;if(void 0!==f){if(f)continue;return!1}if(a){if(!i(t,function(e){return p===e||n(p,e,r,a,o,s)}))return!1}else if(p!==h&&!n(p,h,r,a,o,s))return!1}return!0}var i=e("./arraySome");t.exports=r},{"./arraySome":65}],108:[function(e,t,n){function r(e,t,n){switch(n){case i:case a:return+e==+t;case o:return e.name==t.name&&e.message==t.message;case s:return e!=+e?t!=+t:e==+t;case l:case u:return e==t+""}return!1}var i="[object Boolean]",a="[object Date]",o="[object Error]",s="[object Number]",l="[object RegExp]",u="[object String]";t.exports=r},{}],109:[function(e,t,n){function r(e,t,n,r,a,s,l){var u=i(e),c=u.length,p=i(t),h=p.length;if(c!=h&&!a)return!1;for(var f=c;f--;){var d=u[f];if(!(a?d in t:o.call(t,d)))return!1}for(var m=a;++f<c;){d=u[f];var g=e[d],y=t[d],v=r?r(a?y:g,a?g:y,d):void 0;if(!(void 0===v?n(g,y,r,a,s,l):v))return!1;m||(m="constructor"==d)}if(!m){var b=e.constructor,w=t.constructor;if(b!=w&&"constructor"in e&&"constructor"in t&&!("function"==typeof b&&b instanceof b&&"function"==typeof w&&w instanceof w))return!1}return!0}var i=e("../object/keys"),a=Object.prototype,o=a.hasOwnProperty;t.exports=r},{"../object/keys":149}],110:[function(e,t,n){var r=e("./metaMap"),i=e("../utility/noop"),a=r?function(e){return r.get(e)}:i;t.exports=a},{"../utility/noop":155,"./metaMap":129}],111:[function(e,t,n){function r(e){for(var t=e.name+"",n=i[t],r=n?n.length:0;r--;){var a=n[r],o=a.func;if(null==o||o==e)return a.name}return t}var i=e("./realNames");t.exports=r},{"./realNames":130}],112:[function(e,t,n){var r=e("./baseProperty"),i=r("length");t.exports=i},{"./baseProperty":86}],113:[function(e,t,n){function r(e){for(var t=a(e),n=t.length;n--;)t[n][2]=i(t[n][1]);return t}var i=e("./isStrictComparable"),a=e("../object/pairs");t.exports=r},{"../object/pairs":151,"./isStrictComparable":127}],114:[function(e,t,n){function r(e,t){var n=null==e?void 0:e[t];return i(n)?n:void 0}var i=e("../lang/isNative");t.exports=r},{"../lang/isNative":143}],115:[function(e,t,n){function r(e,t,n){for(var r=e.length,i=t+(n?0:-1);n?i--:++i<r;){var a=e[i];if(a!==a)return i}return-1}t.exports=r},{}],116:[function(e,t,n){function r(e){var t=e.length,n=new e.constructor(t);return t&&"string"==typeof e[0]&&a.call(e,"index")&&(n.index=e.index,n.input=e.input),n}var i=Object.prototype,a=i.hasOwnProperty;t.exports=r},{}],117:[function(e,t,n){(function(n){function r(e,t,n){var r=e.constructor;switch(t){case c:return i(e);case a:case o:return new r((+e));case p:case h:case f:case d:case m:case g:case y:case v:case b:r instanceof r&&(r=x[t]);var _=e.buffer;return new r(n?i(_):_,e.byteOffset,e.length);case s:case u:return new r(e);case l:var A=new r(e.source,w.exec(e));A.lastIndex=e.lastIndex}return A}var i=e("./bufferClone"),a="[object Boolean]",o="[object Date]",s="[object Number]",l="[object RegExp]",u="[object String]",c="[object ArrayBuffer]",p="[object Float32Array]",h="[object Float64Array]",f="[object Int8Array]",d="[object Int16Array]",m="[object Int32Array]",g="[object Uint8Array]",y="[object Uint8ClampedArray]",v="[object Uint16Array]",b="[object Uint32Array]",w=/\w*$/,_=n.Uint8Array,x={};x[p]=n.Float32Array,x[h]=n.Float64Array,x[f]=n.Int8Array,x[d]=n.Int16Array,x[m]=n.Int32Array,x[g]=_,x[y]=n.Uint8ClampedArray,x[v]=n.Uint16Array,x[b]=n.Uint32Array,t.exports=r}).call(this,"undefined"!=typeof global?global:"undefined"!=typeof self?self:"undefined"!=typeof window?window:{})},{"./bufferClone":95}],118:[function(e,t,n){function r(e){var t=e.constructor;return"function"==typeof t&&t instanceof t||(t=Object),new t}t.exports=r},{}],119:[function(e,t,n){function r(e){return null!=e&&a(i(e))}var i=e("./getLength"),a=e("./isLength");t.exports=r},{"./getLength":112,"./isLength":125}],120:[function(e,t,n){var r=function(){try{Object({toString:0}+"")}catch(e){return function(){return!1}}return function(e){return"function"!=typeof e.toString&&"string"==typeof(e+"")}}();t.exports=r},{}],121:[function(e,t,n){function r(e,t){return e="number"==typeof e||i.test(e)?+e:-1,t=null==t?a:t,e>-1&&e%1==0&&e<t}var i=/^\d+$/,a=9007199254740991;t.exports=r},{}],122:[function(e,t,n){function r(e,t,n){if(!o(n))return!1;var r=typeof t;if("number"==r?i(n)&&a(t,n.length):"string"==r&&t in n){var s=n[t];return e===e?e===s:s!==s}return!1}var i=e("./isArrayLike"),a=e("./isIndex"),o=e("../lang/isObject");t.exports=r},{"../lang/isObject":144,"./isArrayLike":119,"./isIndex":121}],123:[function(e,t,n){function r(e,t){var n=typeof e;if("string"==n&&s.test(e)||"number"==n)return!0;if(i(e))return!1;var r=!o.test(e);return r||null!=t&&e in a(t)}var i=e("../lang/isArray"),a=e("./toObject"),o=/\.|\[(?:[^[\]]*|(["'])(?:(?!\1)[^\n\\]|\\.)*?\1)\]/,s=/^\w*$/;t.exports=r},{"../lang/isArray":140,"./toObject":135}],124:[function(e,t,n){function r(e){var t=o(e),n=s[t];if("function"!=typeof n||!(t in i.prototype))return!1;if(e===n)return!0;var r=a(n);return!!r&&e===r[0]}var i=e("./LazyWrapper"),a=e("./getData"),o=e("./getFuncName"),s=e("../chain/lodash");t.exports=r},{"../chain/lodash":51,"./LazyWrapper":60,"./getData":110,"./getFuncName":111}],125:[function(e,t,n){function r(e){return"number"==typeof e&&e>-1&&e%1==0&&e<=i}var i=9007199254740991;t.exports=r},{}],126:[function(e,t,n){function r(e){return!!e&&"object"==typeof e}t.exports=r},{}],127:[function(e,t,n){function r(e){return e===e&&!i(e)}var i=e("../lang/isObject");t.exports=r},{"../lang/isObject":144}],128:[function(e,t,n){function r(e,t){var n=e[1],r=t[1],m=n|r,g=m<p,y=r==p&&n==c||r==p&&n==h&&e[7].length<=t[8]||r==(p|h)&&n==c;if(!g&&!y)return e;r&l&&(e[2]=t[2],m|=n&l?0:u);var v=t[3];if(v){var b=e[3];e[3]=b?a(b,v,t[4]):i(v),e[4]=b?s(e[3],f):i(t[4])}return v=t[5],v&&(b=e[5],e[5]=b?o(b,v,t[6]):i(v),e[6]=b?s(e[5],f):i(t[6])),v=t[7],v&&(e[7]=i(v)),r&p&&(e[8]=null==e[8]?t[8]:d(e[8],t[8])),null==e[9]&&(e[9]=t[9]),e[0]=t[0],e[1]=m,e}var i=e("./arrayCopy"),a=e("./composeArgs"),o=e("./composeArgsRight"),s=e("./replaceHolders"),l=1,u=4,c=8,p=128,h=256,f="__lodash_placeholder__",d=Math.min;t.exports=r},{"./arrayCopy":62,"./composeArgs":96,"./composeArgsRight":97,"./replaceHolders":132}],129:[function(e,t,n){(function(n){var r=e("./getNative"),i=r(n,"WeakMap"),a=i&&new i;t.exports=a}).call(this,"undefined"!=typeof global?global:"undefined"!=typeof self?self:"undefined"!=typeof window?window:{})},{"./getNative":114}],130:[function(e,t,n){var r={};t.exports=r},{}],131:[function(e,t,n){function r(e,t){for(var n=e.length,r=o(t.length,n),s=i(e);r--;){var l=t[r];e[r]=a(l,n)?s[l]:void 0}return e}var i=e("./arrayCopy"),a=e("./isIndex"),o=Math.min;t.exports=r},{"./arrayCopy":62,"./isIndex":121}],132:[function(e,t,n){function r(e,t){for(var n=-1,r=e.length,a=-1,o=[];++n<r;)e[n]===t&&(e[n]=i,o[++a]=n);return o}var i="__lodash_placeholder__";t.exports=r},{}],133:[function(e,t,n){var r=e("./baseSetData"),i=e("../date/now"),a=150,o=16,s=function(){var e=0,t=0;return function(n,s){var l=i(),u=o-(l-t);if(t=l,u>0){if(++e>=a)return n}else e=0;return r(n,s)}}();t.exports=s},{"../date/now":57,"./baseSetData":88}],134:[function(e,t,n){function r(e){for(var t=u(e),n=t.length,r=n&&e.length,c=!!r&&s(r)&&(a(e)||i(e)||l(e)),h=-1,f=[];++h<n;){var d=t[h];(c&&o(d,r)||p.call(e,d))&&f.push(d)}return f}var i=e("../lang/isArguments"),a=e("../lang/isArray"),o=e("./isIndex"),s=e("./isLength"),l=e("../lang/isString"),u=e("../object/keysIn"),c=Object.prototype,p=c.hasOwnProperty;t.exports=r},{"../lang/isArguments":139,"../lang/isArray":140,"../lang/isString":146,"../object/keysIn":150,
-"./isIndex":121,"./isLength":125}],135:[function(e,t,n){function r(e){if(o.unindexedChars&&a(e)){for(var t=-1,n=e.length,r=Object(e);++t<n;)r[t]=e.charAt(t);return r}return i(e)?e:Object(e)}var i=e("../lang/isObject"),a=e("../lang/isString"),o=e("../support");t.exports=r},{"../lang/isObject":144,"../lang/isString":146,"../support":153}],136:[function(e,t,n){function r(e){if(a(e))return e;var t=[];return i(e).replace(o,function(e,n,r,i){t.push(r?i.replace(s,"$1"):n||e)}),t}var i=e("./baseToString"),a=e("../lang/isArray"),o=/[^.[\]]+|\[(?:(-?\d+(?:\.\d+)?)|(["'])((?:(?!\2)[^\n\\]|\\.)*?)\2)\]/g,s=/\\(\\)?/g;t.exports=r},{"../lang/isArray":140,"./baseToString":90}],137:[function(e,t,n){function r(e){return e instanceof i?e.clone():new a(e.__wrapped__,e.__chain__,o(e.__actions__))}var i=e("./LazyWrapper"),a=e("./LodashWrapper"),o=e("./arrayCopy");t.exports=r},{"./LazyWrapper":60,"./LodashWrapper":61,"./arrayCopy":62}],138:[function(e,t,n){function r(e,t,n){return"function"==typeof t?i(e,!0,a(t,n,3)):i(e,!0)}var i=e("../internal/baseClone"),a=e("../internal/bindCallback");t.exports=r},{"../internal/baseClone":68,"../internal/bindCallback":94}],139:[function(e,t,n){function r(e){return a(e)&&i(e)&&s.call(e,"callee")&&!l.call(e,"callee")}var i=e("../internal/isArrayLike"),a=e("../internal/isObjectLike"),o=Object.prototype,s=o.hasOwnProperty,l=o.propertyIsEnumerable;t.exports=r},{"../internal/isArrayLike":119,"../internal/isObjectLike":126}],140:[function(e,t,n){var r=e("../internal/getNative"),i=e("../internal/isLength"),a=e("../internal/isObjectLike"),o="[object Array]",s=Object.prototype,l=s.toString,u=r(Array,"isArray"),c=u||function(e){return a(e)&&i(e.length)&&l.call(e)==o};t.exports=c},{"../internal/getNative":114,"../internal/isLength":125,"../internal/isObjectLike":126}],141:[function(e,t,n){function r(e){return null==e||(o(e)&&(a(e)||u(e)||i(e)||l(e)&&s(e.splice))?!e.length:!c(e).length)}var i=e("./isArguments"),a=e("./isArray"),o=e("../internal/isArrayLike"),s=e("./isFunction"),l=e("../internal/isObjectLike"),u=e("./isString"),c=e("../object/keys");t.exports=r},{"../internal/isArrayLike":119,"../internal/isObjectLike":126,"../object/keys":149,"./isArguments":139,"./isArray":140,"./isFunction":142,"./isString":146}],142:[function(e,t,n){function r(e){return i(e)&&s.call(e)==a}var i=e("./isObject"),a="[object Function]",o=Object.prototype,s=o.toString;t.exports=r},{"./isObject":144}],143:[function(e,t,n){function r(e){return null!=e&&(i(e)?p.test(u.call(e)):o(e)&&(a(e)?p:s).test(e))}var i=e("./isFunction"),a=e("../internal/isHostObject"),o=e("../internal/isObjectLike"),s=/^\[object .+?Constructor\]$/,l=Object.prototype,u=Function.prototype.toString,c=l.hasOwnProperty,p=RegExp("^"+u.call(c).replace(/[\\^$.*+?()[\]{}|]/g,"\\$&").replace(/hasOwnProperty|(function).*?(?=\\\()| for .+?(?=\\\])/g,"$1.*?")+"$");t.exports=r},{"../internal/isHostObject":120,"../internal/isObjectLike":126,"./isFunction":142}],144:[function(e,t,n){function r(e){var t=typeof e;return!!e&&("object"==t||"function"==t)}t.exports=r},{}],145:[function(e,t,n){function r(e){var t;if(!s(e)||h.call(e)!=u||o(e)||a(e)||!p.call(e,"constructor")&&(t=e.constructor,"function"==typeof t&&!(t instanceof t)))return!1;var n;return l.ownLast?(i(e,function(e,t,r){return n=p.call(r,t),!1}),n!==!1):(i(e,function(e,t){n=t}),void 0===n||p.call(e,n))}var i=e("../internal/baseForIn"),a=e("./isArguments"),o=e("../internal/isHostObject"),s=e("../internal/isObjectLike"),l=e("../support"),u="[object Object]",c=Object.prototype,p=c.hasOwnProperty,h=c.toString;t.exports=r},{"../internal/baseForIn":75,"../internal/isHostObject":120,"../internal/isObjectLike":126,"../support":153,"./isArguments":139}],146:[function(e,t,n){function r(e){return"string"==typeof e||i(e)&&s.call(e)==a}var i=e("../internal/isObjectLike"),a="[object String]",o=Object.prototype,s=o.toString;t.exports=r},{"../internal/isObjectLike":126}],147:[function(e,t,n){function r(e){return a(e)&&i(e.length)&&!!T[I.call(e)]}var i=e("../internal/isLength"),a=e("../internal/isObjectLike"),o="[object Arguments]",s="[object Array]",l="[object Boolean]",u="[object Date]",c="[object Error]",p="[object Function]",h="[object Map]",f="[object Number]",d="[object Object]",m="[object RegExp]",g="[object Set]",y="[object String]",v="[object WeakMap]",b="[object ArrayBuffer]",w="[object Float32Array]",_="[object Float64Array]",x="[object Int8Array]",A="[object Int16Array]",S="[object Int32Array]",j="[object Uint8Array]",E="[object Uint8ClampedArray]",O="[object Uint16Array]",k="[object Uint32Array]",T={};T[w]=T[_]=T[x]=T[A]=T[S]=T[j]=T[E]=T[O]=T[k]=!0,T[o]=T[s]=T[b]=T[l]=T[u]=T[c]=T[p]=T[h]=T[f]=T[d]=T[m]=T[g]=T[y]=T[v]=!1;var C=Object.prototype,I=C.toString;t.exports=r},{"../internal/isLength":125,"../internal/isObjectLike":126}],148:[function(e,t,n){function r(e){return void 0===e}t.exports=r},{}],149:[function(e,t,n){var r=e("../internal/getNative"),i=e("../internal/isArrayLike"),a=e("../lang/isObject"),o=e("../internal/shimKeys"),s=e("../support"),l=r(Object,"keys"),u=l?function(e){var t=null==e?void 0:e.constructor;return"function"==typeof t&&t.prototype===e||("function"==typeof e?s.enumPrototypes:i(e))?o(e):a(e)?l(e):[]}:o;t.exports=u},{"../internal/getNative":114,"../internal/isArrayLike":119,"../internal/shimKeys":134,"../lang/isObject":144,"../support":153}],150:[function(e,t,n){function r(e){if(null==e)return[];c(e)||(e=Object(e));var t=e.length;t=t&&u(t)&&(o(e)||a(e)||p(e))&&t||0;for(var n=e.constructor,r=-1,i=s(n)&&n.prototype||S,f=i===e,d=Array(t),m=t>0,y=h.enumErrorProps&&(e===A||e instanceof Error),v=h.enumPrototypes&&s(e);++r<t;)d[r]=r+"";for(var w in e)v&&"prototype"==w||y&&("message"==w||"name"==w)||m&&l(w,t)||"constructor"==w&&(f||!E.call(e,w))||d.push(w);if(h.nonEnumShadows&&e!==S){var T=e===j?_:e===A?g:O.call(e),C=k[T]||k[b];for(T==b&&(i=S),t=x.length;t--;){w=x[t];var I=C[w];f&&I||(I?!E.call(e,w):e[w]===i[w])||d.push(w)}}return d}var i=e("../internal/arrayEach"),a=e("../lang/isArguments"),o=e("../lang/isArray"),s=e("../lang/isFunction"),l=e("../internal/isIndex"),u=e("../internal/isLength"),c=e("../lang/isObject"),p=e("../lang/isString"),h=e("../support"),f="[object Array]",d="[object Boolean]",m="[object Date]",g="[object Error]",y="[object Function]",v="[object Number]",b="[object Object]",w="[object RegExp]",_="[object String]",x=["constructor","hasOwnProperty","isPrototypeOf","propertyIsEnumerable","toLocaleString","toString","valueOf"],A=Error.prototype,S=Object.prototype,j=String.prototype,E=S.hasOwnProperty,O=S.toString,k={};k[f]=k[m]=k[v]={constructor:!0,toLocaleString:!0,toString:!0,valueOf:!0},k[d]=k[_]={constructor:!0,toString:!0,valueOf:!0},k[g]=k[y]=k[w]={constructor:!0,toString:!0},k[b]={constructor:!0},i(x,function(e){for(var t in k)if(E.call(k,t)){var n=k[t];n[e]=E.call(n,e)}}),t.exports=r},{"../internal/arrayEach":63,"../internal/isIndex":121,"../internal/isLength":125,"../lang/isArguments":139,"../lang/isArray":140,"../lang/isFunction":142,"../lang/isObject":144,"../lang/isString":146,"../support":153}],151:[function(e,t,n){function r(e){e=a(e);for(var t=-1,n=i(e),r=n.length,o=Array(r);++t<r;){var s=n[t];o[t]=[s,e[s]]}return o}var i=e("./keys"),a=e("../internal/toObject");t.exports=r},{"../internal/toObject":135,"./keys":149}],152:[function(e,t,n){function r(e){return i(e,a(e))}var i=e("../internal/baseValues"),a=e("./keys");t.exports=r},{"../internal/baseValues":91,"./keys":149}],153:[function(e,t,n){var r=Array.prototype,i=Error.prototype,a=Object.prototype,o=a.propertyIsEnumerable,s=r.splice,l={};!function(e){var t=function(){this.x=e},n={0:e,length:e},r=[];t.prototype={valueOf:e,y:e};for(var a in new t)r.push(a);l.enumErrorProps=o.call(i,"message")||o.call(i,"name"),l.enumPrototypes=o.call(t,"prototype"),l.nonEnumShadows=!/valueOf/.test(r),l.ownLast="x"!=r[0],l.spliceObjects=(s.call(n,0,1),!n[0]),l.unindexedChars="x"[0]+Object("x")[0]!="xx"}(1,0),t.exports=l},{}],154:[function(e,t,n){function r(e){return e}t.exports=r},{}],155:[function(e,t,n){function r(){}t.exports=r},{}],156:[function(e,t,n){function r(e){return o(e)?i(e):a(e)}var i=e("../internal/baseProperty"),a=e("../internal/basePropertyDeep"),o=e("../internal/isKey");t.exports=r},{"../internal/baseProperty":86,"../internal/basePropertyDeep":87,"../internal/isKey":123}],157:[function(e,n,r){(function(e){!function(e){"use strict";if("function"==typeof bootstrap)bootstrap("promise",e);else if("object"==typeof r&&"object"==typeof n)n.exports=e();else if("function"==typeof t&&t.amd)t(e);else if("undefined"!=typeof ses){if(!ses.ok())return;ses.makeQ=e}else{if("undefined"==typeof window&&"undefined"==typeof self)throw new Error("This environment was not anticipated by Q. Please file a bug.");var i="undefined"!=typeof window?window:self,a=i.Q;i.Q=e(),i.Q.noConflict=function(){return i.Q=a,this}}}(function(){"use strict";function t(e){return function(){return Q.apply(e,arguments)}}function n(e){return e===Object(e)}function r(e){return"[object StopIteration]"===re(e)||e instanceof H}function i(e,t){if($&&t.stack&&"object"==typeof e&&null!==e&&e.stack&&e.stack.indexOf(ie)===-1){for(var n=[],r=t;r;r=r.source)r.stack&&n.unshift(r.stack);n.unshift(e.stack);var i=n.join("\n"+ie+"\n");e.stack=a(i)}}function a(e){for(var t=e.split("\n"),n=[],r=0;r<t.length;++r){var i=t[r];l(i)||o(i)||!i||n.push(i)}return n.join("\n")}function o(e){return e.indexOf("(module.js:")!==-1||e.indexOf("(node.js:")!==-1}function s(e){var t=/at .+ \((.+):(\d+):(?:\d+)\)$/.exec(e);if(t)return[t[1],Number(t[2])];var n=/at ([^ ]+):(\d+):(?:\d+)$/.exec(e);if(n)return[n[1],Number(n[2])];var r=/.*@(.+):(\d+)$/.exec(e);return r?[r[1],Number(r[2])]:void 0}function l(e){var t=s(e);if(!t)return!1;var n=t[0],r=t[1];return n===V&&r>=Y&&r<=ue}function u(){if($)try{throw new Error}catch(e){var t=e.stack.split("\n"),n=t[0].indexOf("@")>0?t[1]:t[2],r=s(n);if(!r)return;return V=r[0],r[1]}}function c(e,t,n){return function(){return"undefined"!=typeof console&&"function"==typeof console.warn&&console.warn(t+" is deprecated, use "+n+" instead.",new Error("").stack),e.apply(e,arguments)}}function p(e){return e instanceof m?e:b(e)?k(e):O(e)}function h(){function e(e){t=e,a.source=e,K(n,function(t,n){p.nextTick(function(){e.promiseDispatch.apply(e,n)})},void 0),n=void 0,r=void 0}var t,n=[],r=[],i=ee(h.prototype),a=ee(m.prototype);if(a.promiseDispatch=function(e,i,a){var o=G(arguments);n?(n.push(o),"when"===i&&a[1]&&r.push(a[1])):p.nextTick(function(){t.promiseDispatch.apply(t,o)})},a.valueOf=function(){if(n)return a;var e=y(t);return v(e)&&(t=e),e},a.inspect=function(){return t?t.inspect():{state:"pending"}},p.longStackSupport&&$)try{throw new Error}catch(o){a.stack=o.stack.substring(o.stack.indexOf("\n")+1)}return i.promise=a,i.resolve=function(n){t||e(p(n))},i.fulfill=function(n){t||e(O(n))},i.reject=function(n){t||e(E(n))},i.notify=function(e){t||K(r,function(t,n){p.nextTick(function(){n(e)})},void 0)},i}function f(e){if("function"!=typeof e)throw new TypeError("resolver must be a function.");var t=h();try{e(t.resolve,t.reject,t.notify)}catch(n){t.reject(n)}return t.promise}function d(e){return f(function(t,n){for(var r=0,i=e.length;r<i;r++)p(e[r]).then(t,n)})}function m(e,t,n){void 0===t&&(t=function(e){return E(new Error("Promise does not support operation: "+e))}),void 0===n&&(n=function(){return{state:"unknown"}});var r=ee(m.prototype);if(r.promiseDispatch=function(n,i,a){var o;try{o=e[i]?e[i].apply(r,a):t.call(r,i,a)}catch(s){o=E(s)}n&&n(o)},r.inspect=n,n){var i=n();"rejected"===i.state&&(r.exception=i.reason),r.valueOf=function(){var e=n();return"pending"===e.state||"rejected"===e.state?r:e.value}}return r}function g(e,t,n,r){return p(e).then(t,n,r)}function y(e){if(v(e)){var t=e.inspect();if("fulfilled"===t.state)return t.value}return e}function v(e){return e instanceof m}function b(e){return n(e)&&"function"==typeof e.then}function w(e){return v(e)&&"pending"===e.inspect().state}function _(e){return!v(e)||"fulfilled"===e.inspect().state}function x(e){return v(e)&&"rejected"===e.inspect().state}function A(){ae.length=0,oe.length=0,le||(le=!0)}function S(t,n){le&&("object"==typeof e&&"function"==typeof e.emit&&p.nextTick.runAfter(function(){X(oe,t)!==-1&&(e.emit("unhandledRejection",n,t),se.push(t))}),oe.push(t),n&&"undefined"!=typeof n.stack?ae.push(n.stack):ae.push("(no stack) "+n))}function j(t){if(le){var n=X(oe,t);n!==-1&&("object"==typeof e&&"function"==typeof e.emit&&p.nextTick.runAfter(function(){var r=X(se,t);r!==-1&&(e.emit("rejectionHandled",ae[n],t),se.splice(r,1))}),oe.splice(n,1),ae.splice(n,1))}}function E(e){var t=m({when:function(t){return t&&j(this),t?t(e):this}},function(){return this},function(){return{state:"rejected",reason:e}});return S(t,e),t}function O(e){return m({when:function(){return e},get:function(t){return e[t]},set:function(t,n){e[t]=n},"delete":function(t){delete e[t]},post:function(t,n){return null===t||void 0===t?e.apply(void 0,n):e[t].apply(e,n)},apply:function(t,n){return e.apply(t,n)},keys:function(){return ne(e)}},void 0,function(){return{state:"fulfilled",value:e}})}function k(e){var t=h();return p.nextTick(function(){try{e.then(t.resolve,t.reject,t.notify)}catch(n){t.reject(n)}}),t.promise}function T(e){return m({isDef:function(){}},function(t,n){return R(e,t,n)},function(){return p(e).inspect()})}function C(e,t,n){return p(e).spread(t,n)}function I(e){return function(){function t(e,t){var o;if("undefined"==typeof StopIteration){try{o=n[e](t)}catch(s){return E(s)}return o.done?p(o.value):g(o.value,i,a)}try{o=n[e](t)}catch(s){return r(s)?p(s.value):E(s)}return g(o,i,a)}var n=e.apply(this,arguments),i=t.bind(t,"next"),a=t.bind(t,"throw");return i()}}function D(e){p.done(p.async(e)())}function L(e){throw new H(e)}function M(e){return function(){return C([this,U(arguments)],function(t,n){return e.apply(t,n)})}}function R(e,t,n){return p(e).dispatch(t,n)}function U(e){return g(e,function(e){var t=0,n=h();return K(e,function(r,i,a){var o;v(i)&&"fulfilled"===(o=i.inspect()).state?e[a]=o.value:(++t,g(i,function(r){e[a]=r,0===--t&&n.resolve(e)},n.reject,function(e){n.notify({index:a,value:e})}))},void 0),0===t&&n.resolve(e),n.promise})}function P(e){if(0===e.length)return p.resolve();var t=p.defer(),n=0;return K(e,function(r,i,a){function o(e){t.resolve(e)}function s(){n--,0===n&&t.reject(new Error("Can't get fulfillment value from any promise, all promises were rejected."))}function l(e){t.notify({index:a,value:e})}var u=e[a];n++,g(u,o,s,l)},void 0),t.promise}function q(e){return g(e,function(e){return e=Z(e,p),g(U(Z(e,function(e){return g(e,J,J)})),function(){return e})})}function B(e){return p(e).allSettled()}function N(e,t){return p(e).then(void 0,void 0,t)}function z(e,t){return p(e).nodeify(t)}var $=!1;try{throw new Error}catch(F){$=!!F.stack}var V,H,Y=u(),J=function(){},W=function(){function t(){for(var e,t;r.next;)r=r.next,e=r.task,r.task=void 0,t=r.domain,t&&(r.domain=void 0,t.enter()),n(e,t);for(;l.length;)e=l.pop(),n(e);a=!1}function n(e,n){try{e()}catch(r){if(s)throw n&&n.exit(),setTimeout(t,0),n&&n.enter(),r;setTimeout(function(){throw r},0)}n&&n.exit()}var r={task:void 0,next:null},i=r,a=!1,o=void 0,s=!1,l=[];if(W=function(t){i=i.next={task:t,domain:s&&e.domain,next:null},a||(a=!0,o())},"object"==typeof e&&"[object process]"===e.toString()&&e.nextTick)s=!0,o=function(){e.nextTick(t)};else if("function"==typeof setImmediate)o="undefined"!=typeof window?setImmediate.bind(window,t):function(){setImmediate(t)};else if("undefined"!=typeof MessageChannel){var u=new MessageChannel;u.port1.onmessage=function(){o=c,u.port1.onmessage=t,t()};var c=function(){u.port2.postMessage(0)};o=function(){setTimeout(t,0),c()}}else o=function(){setTimeout(t,0)};return W.runAfter=function(e){l.push(e),a||(a=!0,o())},W}(),Q=Function.call,G=t(Array.prototype.slice),K=t(Array.prototype.reduce||function(e,t){var n=0,r=this.length;if(1===arguments.length)for(;;){if(n in this){t=this[n++];break}if(++n>=r)throw new TypeError}for(;n<r;n++)n in this&&(t=e(t,this[n],n));return t}),X=t(Array.prototype.indexOf||function(e){for(var t=0;t<this.length;t++)if(this[t]===e)return t;return-1}),Z=t(Array.prototype.map||function(e,t){var n=this,r=[];return K(n,function(i,a,o){r.push(e.call(t,a,o,n))},void 0),r}),ee=Object.create||function(e){function t(){}return t.prototype=e,new t},te=t(Object.prototype.hasOwnProperty),ne=Object.keys||function(e){var t=[];for(var n in e)te(e,n)&&t.push(n);return t},re=t(Object.prototype.toString);H="undefined"!=typeof ReturnValue?ReturnValue:function(e){this.value=e};var ie="From previous event:";p.resolve=p,p.nextTick=W,p.longStackSupport=!1,"object"==typeof e&&e&&e.env&&e.env.Q_DEBUG&&(p.longStackSupport=!0),p.defer=h,h.prototype.makeNodeResolver=function(){var e=this;return function(t,n){t?e.reject(t):arguments.length>2?e.resolve(G(arguments,1)):e.resolve(n)}},p.Promise=f,p.promise=f,f.race=d,f.all=U,f.reject=E,f.resolve=p,p.passByCopy=function(e){return e},m.prototype.passByCopy=function(){return this},p.join=function(e,t){return p(e).join(t)},m.prototype.join=function(e){return p([this,e]).spread(function(e,t){if(e===t)return e;throw new Error("Can't join: not the same: "+e+" "+t)})},p.race=d,m.prototype.race=function(){return this.then(p.race)},p.makePromise=m,m.prototype.toString=function(){return"[object Promise]"},m.prototype.then=function(e,t,n){function r(t){try{return"function"==typeof e?e(t):t}catch(n){return E(n)}}function a(e){if("function"==typeof t){i(e,s);try{return t(e)}catch(n){return E(n)}}return E(e)}function o(e){return"function"==typeof n?n(e):e}var s=this,l=h(),u=!1;return p.nextTick(function(){s.promiseDispatch(function(e){u||(u=!0,l.resolve(r(e)))},"when",[function(e){u||(u=!0,l.resolve(a(e)))}])}),s.promiseDispatch(void 0,"when",[void 0,function(e){var t,n=!1;try{t=o(e)}catch(r){if(n=!0,!p.onerror)throw r;p.onerror(r)}n||l.notify(t)}]),l.promise},p.tap=function(e,t){return p(e).tap(t)},m.prototype.tap=function(e){return e=p(e),this.then(function(t){return e.fcall(t).thenResolve(t)})},p.when=g,m.prototype.thenResolve=function(e){return this.then(function(){return e})},p.thenResolve=function(e,t){return p(e).thenResolve(t)},m.prototype.thenReject=function(e){return this.then(function(){throw e})},p.thenReject=function(e,t){return p(e).thenReject(t)},p.nearer=y,p.isPromise=v,p.isPromiseAlike=b,p.isPending=w,m.prototype.isPending=function(){return"pending"===this.inspect().state},p.isFulfilled=_,m.prototype.isFulfilled=function(){return"fulfilled"===this.inspect().state},p.isRejected=x,m.prototype.isRejected=function(){return"rejected"===this.inspect().state};var ae=[],oe=[],se=[],le=!0;p.resetUnhandledRejections=A,p.getUnhandledReasons=function(){return ae.slice()},p.stopUnhandledRejectionTracking=function(){A(),le=!1},A(),p.reject=E,p.fulfill=O,p.master=T,p.spread=C,m.prototype.spread=function(e,t){return this.all().then(function(t){return e.apply(void 0,t)},t)},p.async=I,p.spawn=D,p["return"]=L,p.promised=M,p.dispatch=R,m.prototype.dispatch=function(e,t){var n=this,r=h();return p.nextTick(function(){n.promiseDispatch(r.resolve,e,t)}),r.promise},p.get=function(e,t){return p(e).dispatch("get",[t])},m.prototype.get=function(e){return this.dispatch("get",[e])},p.set=function(e,t,n){return p(e).dispatch("set",[t,n])},m.prototype.set=function(e,t){return this.dispatch("set",[e,t])},p.del=p["delete"]=function(e,t){return p(e).dispatch("delete",[t])},m.prototype.del=m.prototype["delete"]=function(e){return this.dispatch("delete",[e])},p.mapply=p.post=function(e,t,n){return p(e).dispatch("post",[t,n])},m.prototype.mapply=m.prototype.post=function(e,t){return this.dispatch("post",[e,t])},p.send=p.mcall=p.invoke=function(e,t){return p(e).dispatch("post",[t,G(arguments,2)])},m.prototype.send=m.prototype.mcall=m.prototype.invoke=function(e){return this.dispatch("post",[e,G(arguments,1)])},p.fapply=function(e,t){return p(e).dispatch("apply",[void 0,t])},m.prototype.fapply=function(e){return this.dispatch("apply",[void 0,e])},p["try"]=p.fcall=function(e){return p(e).dispatch("apply",[void 0,G(arguments,1)])},m.prototype.fcall=function(){return this.dispatch("apply",[void 0,G(arguments)])},p.fbind=function(e){var t=p(e),n=G(arguments,1);return function(){return t.dispatch("apply",[this,n.concat(G(arguments))])}},m.prototype.fbind=function(){var e=this,t=G(arguments);return function(){return e.dispatch("apply",[this,t.concat(G(arguments))])}},p.keys=function(e){return p(e).dispatch("keys",[])},m.prototype.keys=function(){return this.dispatch("keys",[])},p.all=U,m.prototype.all=function(){return U(this)},p.any=P,m.prototype.any=function(){return P(this)},p.allResolved=c(q,"allResolved","allSettled"),m.prototype.allResolved=function(){return q(this)},p.allSettled=B,m.prototype.allSettled=function(){return this.then(function(e){return U(Z(e,function(e){function t(){return e.inspect()}return e=p(e),e.then(t,t)}))})},p.fail=p["catch"]=function(e,t){return p(e).then(void 0,t)},m.prototype.fail=m.prototype["catch"]=function(e){return this.then(void 0,e)},p.progress=N,m.prototype.progress=function(e){return this.then(void 0,void 0,e)},p.fin=p["finally"]=function(e,t){return p(e)["finally"](t)},m.prototype.fin=m.prototype["finally"]=function(e){return e=p(e),this.then(function(t){return e.fcall().then(function(){return t})},function(t){return e.fcall().then(function(){throw t})})},p.done=function(e,t,n,r){return p(e).done(t,n,r)},m.prototype.done=function(t,n,r){var a=function(e){p.nextTick(function(){if(i(e,o),!p.onerror)throw e;p.onerror(e)})},o=t||n||r?this.then(t,n,r):this;"object"==typeof e&&e&&e.domain&&(a=e.domain.bind(a)),o.then(void 0,a)},p.timeout=function(e,t,n){return p(e).timeout(t,n)},m.prototype.timeout=function(e,t){var n=h(),r=setTimeout(function(){t&&"string"!=typeof t||(t=new Error(t||"Timed out after "+e+" ms"),t.code="ETIMEDOUT"),n.reject(t)},e);return this.then(function(e){clearTimeout(r),n.resolve(e)},function(e){clearTimeout(r),n.reject(e)},n.notify),n.promise},p.delay=function(e,t){return void 0===t&&(t=e,e=void 0),p(e).delay(t)},m.prototype.delay=function(e){return this.then(function(t){var n=h();return setTimeout(function(){n.resolve(t)},e),n.promise})},p.nfapply=function(e,t){return p(e).nfapply(t)},m.prototype.nfapply=function(e){var t=h(),n=G(e);return n.push(t.makeNodeResolver()),this.fapply(n).fail(t.reject),t.promise},p.nfcall=function(e){var t=G(arguments,1);return p(e).nfapply(t)},m.prototype.nfcall=function(){var e=G(arguments),t=h();return e.push(t.makeNodeResolver()),this.fapply(e).fail(t.reject),t.promise},p.nfbind=p.denodeify=function(e){var t=G(arguments,1);return function(){var n=t.concat(G(arguments)),r=h();return n.push(r.makeNodeResolver()),p(e).fapply(n).fail(r.reject),r.promise}},m.prototype.nfbind=m.prototype.denodeify=function(){var e=G(arguments);return e.unshift(this),p.denodeify.apply(void 0,e)},p.nbind=function(e,t){var n=G(arguments,2);return function(){function r(){return e.apply(t,arguments)}var i=n.concat(G(arguments)),a=h();return i.push(a.makeNodeResolver()),p(r).fapply(i).fail(a.reject),a.promise}},m.prototype.nbind=function(){var e=G(arguments,0);return e.unshift(this),p.nbind.apply(void 0,e)},p.nmapply=p.npost=function(e,t,n){return p(e).npost(t,n)},m.prototype.nmapply=m.prototype.npost=function(e,t){var n=G(t||[]),r=h();return n.push(r.makeNodeResolver()),this.dispatch("post",[e,n]).fail(r.reject),r.promise},p.nsend=p.nmcall=p.ninvoke=function(e,t){var n=G(arguments,2),r=h();return n.push(r.makeNodeResolver()),p(e).dispatch("post",[t,n]).fail(r.reject),r.promise},m.prototype.nsend=m.prototype.nmcall=m.prototype.ninvoke=function(e){var t=G(arguments,1),n=h();return t.push(n.makeNodeResolver()),this.dispatch("post",[e,t]).fail(n.reject),n.promise},p.nodeify=z,m.prototype.nodeify=function(e){return e?void this.then(function(t){p.nextTick(function(){e(null,t)})},function(t){p.nextTick(function(){e(t)})}):this},p.noConflict=function(){throw new Error("Q.noConflict only works when Q is used as a global")};var ue=u();return p})}).call(this,e("_process"))},{_process:12}],158:[function(e,t,n){function r(){}function i(e){var t={}.toString.call(e);switch(t){case"[object File]":case"[object Blob]":case"[object FormData]":return!0;default:return!1}}function a(e){if(!b(e))return e;var t=[];for(var n in e)null!=e[n]&&o(t,n,e[n]);return t.join("&")}function o(e,t,n){return Array.isArray(n)?n.forEach(function(n){o(e,t,n)}):void e.push(encodeURIComponent(t)+"="+encodeURIComponent(n))}function s(e){for(var t,n,r={},i=e.split("&"),a=0,o=i.length;a<o;++a)n=i[a],t=n.split("="),r[decodeURIComponent(t[0])]=decodeURIComponent(t[1]);return r}function l(e){var t,n,r,i,a=e.split(/\r?\n/),o={};a.pop();for(var s=0,l=a.length;s<l;++s)n=a[s],t=n.indexOf(":"),r=n.slice(0,t).toLowerCase(),i=_(n.slice(t+1)),o[r]=i;return o}function u(e){return/[\/+]json\b/.test(e)}function c(e){return e.split(/ *; */).shift()}function p(e){return y(e.split(/ *; */),function(e,t){var n=t.split(/ *= */),r=n.shift(),i=n.shift();return r&&i&&(e[r]=i),e},{})}function h(e,t){t=t||{},this.req=e,this.xhr=this.req.xhr,this.text="HEAD"!=this.req.method&&(""===this.xhr.responseType||"text"===this.xhr.responseType)||"undefined"==typeof this.xhr.responseType?this.xhr.responseText:null,this.statusText=this.req.xhr.statusText,this.setStatusProperties(this.xhr.status),this.header=this.headers=l(this.xhr.getAllResponseHeaders()),this.header["content-type"]=this.xhr.getResponseHeader("content-type"),this.setHeaderProperties(this.header),this.body="HEAD"!=this.req.method?this.parseBody(this.text?this.text:this.xhr.response):null}function f(e,t){var n=this;this._query=this._query||[],this.method=e,this.url=t,this.header={},this._header={},this.on("end",function(){var e=null,t=null;try{t=new h(n)}catch(r){return e=new Error("Parser is unable to parse the response"),e.parse=!0,e.original=r,e.rawResponse=n.xhr&&n.xhr.responseText?n.xhr.responseText:null,e.statusCode=n.xhr&&n.xhr.status?n.xhr.status:null,n.callback(e)}if(n.emit("response",t),e)return n.callback(e,t);if(t.status>=200&&t.status<300)return n.callback(e,t);var i=new Error(t.statusText||"Unsuccessful HTTP response");i.original=e,i.response=t,i.status=t.status,n.callback(i,t)})}function d(e,t){var n=w("DELETE",e);return t&&n.end(t),n}var m,g=e("emitter"),y=e("reduce"),v=e("./request-base"),b=e("./is-object");m="undefined"!=typeof window?window:"undefined"!=typeof self?self:this;var w=t.exports=e("./request").bind(null,f);w.getXHR=function(){if(!(!m.XMLHttpRequest||m.location&&"file:"==m.location.protocol&&m.ActiveXObject))return new XMLHttpRequest;try{return new ActiveXObject("Microsoft.XMLHTTP")}catch(e){}try{return new ActiveXObject("Msxml2.XMLHTTP.6.0")}catch(e){}try{return new ActiveXObject("Msxml2.XMLHTTP.3.0")}catch(e){}try{return new ActiveXObject("Msxml2.XMLHTTP")}catch(e){}return!1};var _="".trim?function(e){return e.trim()}:function(e){return e.replace(/(^\s*|\s*$)/g,"")};w.serializeObject=a,w.parseString=s,w.types={html:"text/html",json:"application/json",xml:"application/xml",urlencoded:"application/x-www-form-urlencoded",form:"application/x-www-form-urlencoded","form-data":"application/x-www-form-urlencoded"},w.serialize={"application/x-www-form-urlencoded":a,"application/json":JSON.stringify},w.parse={"application/x-www-form-urlencoded":s,"application/json":JSON.parse},h.prototype.get=function(e){return this.header[e.toLowerCase()]},h.prototype.setHeaderProperties=function(e){var t=this.header["content-type"]||"";this.type=c(t);var n=p(t);for(var r in n)this[r]=n[r]},h.prototype.parseBody=function(e){var t=w.parse[this.type];return!t&&u(this.type)&&(t=w.parse["application/json"]),t&&e&&(e.length||e instanceof Object)?t(e):null},h.prototype.setStatusProperties=function(e){1223===e&&(e=204);var t=e/100|0;this.status=this.statusCode=e,this.statusType=t,this.info=1==t,this.ok=2==t,this.clientError=4==t,this.serverError=5==t,this.error=(4==t||5==t)&&this.toError(),this.accepted=202==e,this.noContent=204==e,this.badRequest=400==e,this.unauthorized=401==e,this.notAcceptable=406==e,this.notFound=404==e,this.forbidden=403==e},h.prototype.toError=function(){var e=this.req,t=e.method,n=e.url,r="cannot "+t+" "+n+" ("+this.status+")",i=new Error(r);return i.status=this.status,i.method=t,i.url=n,i},w.Response=h,g(f.prototype);for(var x in v)f.prototype[x]=v[x];f.prototype.abort=function(){if(!this.aborted)return this.aborted=!0,this.xhr.abort(),this.clearTimeout(),this.emit("abort"),this},f.prototype.type=function(e){return this.set("Content-Type",w.types[e]||e),this},f.prototype.responseType=function(e){return this._responseType=e,this},f.prototype.accept=function(e){return this.set("Accept",w.types[e]||e),this},f.prototype.auth=function(e,t,n){switch(n||(n={type:"basic"}),n.type){case"basic":var r=btoa(e+":"+t);this.set("Authorization","Basic "+r);break;case"auto":this.username=e,this.password=t}return this},f.prototype.query=function(e){return"string"!=typeof e&&(e=a(e)),e&&this._query.push(e),this},f.prototype.attach=function(e,t,n){return this._getFormData().append(e,t,n||t.name),this},f.prototype._getFormData=function(){return this._formData||(this._formData=new m.FormData),this._formData},f.prototype.send=function(e){var t=b(e),n=this._header["content-type"];if(t&&b(this._data))for(var r in e)this._data[r]=e[r];else"string"==typeof e?(n||this.type("form"),n=this._header["content-type"],"application/x-www-form-urlencoded"==n?this._data=this._data?this._data+"&"+e:e:this._data=(this._data||"")+e):this._data=e;return!t||i(e)?this:(n||this.type("json"),this)},h.prototype.parse=function(e){return m.console&&console.warn("Client-side parse() method has been renamed to serialize(). This method is not compatible with superagent v2.0"),this.serialize(e),this},h.prototype.serialize=function(e){return this._parser=e,this},f.prototype.callback=function(e,t){var n=this._callback;this.clearTimeout(),n(e,t)},f.prototype.crossDomainError=function(){var e=new Error("Request has been terminated\nPossible causes: the network is offline, Origin is not allowed by Access-Control-Allow-Origin, the page is being unloaded, etc.");e.crossDomain=!0,e.status=this.status,e.method=this.method,e.url=this.url,this.callback(e)},f.prototype.timeoutError=function(){var e=this._timeout,t=new Error("timeout of "+e+"ms exceeded");t.timeout=e,this.callback(t)},f.prototype.withCredentials=function(){return this._withCredentials=!0,this},f.prototype.end=function(e){var t=this,n=this.xhr=w.getXHR(),a=this._query.join("&"),o=this._timeout,s=this._formData||this._data;this._callback=e||r,n.onreadystatechange=function(){if(4==n.readyState){var e;try{e=n.status}catch(r){e=0}if(0==e){if(t.timedout)return t.timeoutError();if(t.aborted)return;return t.crossDomainError()}t.emit("end")}};var l=function(e){e.total>0&&(e.percent=e.loaded/e.total*100),e.direction="download",t.emit("progress",e)};this.hasListeners("progress")&&(n.onprogress=l);try{n.upload&&this.hasListeners("progress")&&(n.upload.onprogress=l)}catch(c){}if(o&&!this._timer&&(this._timer=setTimeout(function(){t.timedout=!0,t.abort()},o)),a&&(a=w.serializeObject(a),this.url+=~this.url.indexOf("?")?"&"+a:"?"+a),this.username&&this.password?n.open(this.method,this.url,!0,this.username,this.password):n.open(this.method,this.url,!0),this._withCredentials&&(n.withCredentials=!0),"GET"!=this.method&&"HEAD"!=this.method&&"string"!=typeof s&&!i(s)){var p=this._header["content-type"],h=this._parser||w.serialize[p?p.split(";")[0]:""];!h&&u(p)&&(h=w.serialize["application/json"]),h&&(s=h(s))}for(var f in this.header)null!=this.header[f]&&n.setRequestHeader(f,this.header[f]);return this._responseType&&(n.responseType=this._responseType),this.emit("request",this),n.send("undefined"!=typeof s?s:null),this},w.Request=f,w.get=function(e,t,n){var r=w("GET",e);return"function"==typeof t&&(n=t,t=null),t&&r.query(t),n&&r.end(n),r},w.head=function(e,t,n){var r=w("HEAD",e);return"function"==typeof t&&(n=t,t=null),t&&r.send(t),n&&r.end(n),r},w.del=d,w["delete"]=d,w.patch=function(e,t,n){
-var r=w("PATCH",e);return"function"==typeof t&&(n=t,t=null),t&&r.send(t),n&&r.end(n),r},w.post=function(e,t,n){var r=w("POST",e);return"function"==typeof t&&(n=t,t=null),t&&r.send(t),n&&r.end(n),r},w.put=function(e,t,n){var r=w("PUT",e);return"function"==typeof t&&(n=t,t=null),t&&r.send(t),n&&r.end(n),r}},{"./is-object":159,"./request":161,"./request-base":160,emitter:162,reduce:163}],159:[function(e,t,n){function r(e){return null!=e&&"object"==typeof e}t.exports=r},{}],160:[function(e,t,n){var r=e("./is-object");n.clearTimeout=function(){return this._timeout=0,clearTimeout(this._timer),this},n.parse=function(e){return this._parser=e,this},n.timeout=function(e){return this._timeout=e,this},n.then=function(e,t){return this.end(function(n,r){n?t(n):e(r)})},n.use=function(e){return e(this),this},n.get=function(e){return this._header[e.toLowerCase()]},n.getHeader=n.get,n.set=function(e,t){if(r(e)){for(var n in e)this.set(n,e[n]);return this}return this._header[e.toLowerCase()]=t,this.header[e]=t,this},n.unset=function(e){return delete this._header[e.toLowerCase()],delete this.header[e],this},n.field=function(e,t){return this._getFormData().append(e,t),this}},{"./is-object":159}],161:[function(e,t,n){function r(e,t,n){return"function"==typeof n?new e("GET",t).end(n):2==arguments.length?new e("GET",t):new e(t,n)}t.exports=r},{}],162:[function(e,t,n){function r(e){if(e)return i(e)}function i(e){for(var t in r.prototype)e[t]=r.prototype[t];return e}"undefined"!=typeof t&&(t.exports=r),r.prototype.on=r.prototype.addEventListener=function(e,t){return this._callbacks=this._callbacks||{},(this._callbacks["$"+e]=this._callbacks["$"+e]||[]).push(t),this},r.prototype.once=function(e,t){function n(){this.off(e,n),t.apply(this,arguments)}return n.fn=t,this.on(e,n),this},r.prototype.off=r.prototype.removeListener=r.prototype.removeAllListeners=r.prototype.removeEventListener=function(e,t){if(this._callbacks=this._callbacks||{},0==arguments.length)return this._callbacks={},this;var n=this._callbacks["$"+e];if(!n)return this;if(1==arguments.length)return delete this._callbacks["$"+e],this;for(var r,i=0;i<n.length;i++)if(r=n[i],r===t||r.fn===t){n.splice(i,1);break}return this},r.prototype.emit=function(e){this._callbacks=this._callbacks||{};var t=[].slice.call(arguments,1),n=this._callbacks["$"+e];if(n){n=n.slice(0);for(var r=0,i=n.length;r<i;++r)n[r].apply(this,t)}return this},r.prototype.listeners=function(e){return this._callbacks=this._callbacks||{},this._callbacks["$"+e]||[]},r.prototype.hasListeners=function(e){return!!this.listeners(e).length}},{}],163:[function(e,t,n){t.exports=function(e,t,n){for(var r=0,i=e.length,a=3==arguments.length?n:e[r++];r<i;)a=t.call(null,a,e[r],++r,e);return a}},{}]},{},[1])(1)}),window.SwaggerUi=Backbone.Router.extend({dom_id:"swagger_ui",options:null,api:null,headerView:null,mainView:null,initialize:function(e){e=e||{},"model"!==e.defaultModelRendering&&(e.defaultModelRendering="schema"),e.highlightSizeThreshold||(e.highlightSizeThreshold=1e5),e.dom_id&&(this.dom_id=e.dom_id,delete e.dom_id),e.supportedSubmitMethods||(e.supportedSubmitMethods=["get","put","post","delete","head","options","patch"]),"string"==typeof e.oauth2RedirectUrl&&(window.oAuthRedirectUrl=e.oauth2RedirectUrl),$("#"+this.dom_id).length||$("body").append('<div id="'+this.dom_id+'"></div>'),this.options=e,marked.setOptions({gfm:!0});var t=this;this.options.success=function(){return t.render()},this.options.progress=function(e){return t.showMessage(e)},this.options.failure=function(e){return t.onLoadFailure(e)},this.headerView=new SwaggerUi.Views.HeaderView({el:$("#header")}),this.headerView.on("update-swagger-ui",function(e){return t.updateSwaggerUi(e)}),JSONEditor.defaults.iconlibs.swagger=JSONEditor.AbstractIconLib.extend({mapping:{collapse:"collapse",expand:"expand"},icon_prefix:"swagger-"})},setOption:function(e,t){this.options[e]=t},getOption:function(e){return this.options[e]},updateSwaggerUi:function(e){this.options.url=e.url,this.load()},load:function(){this.mainView&&this.mainView.clear(),this.authView&&this.authView.remove();var e=this.options.url;e&&0!==e.indexOf("http")&&(e=this.buildUrl(window.location.href.toString(),e)),this.api&&(this.options.authorizations=this.api.clientAuthorizations.authz),this.options.url=e,this.headerView.update(e),this.api=new SwaggerClient(this.options)},collapseAll:function(){Docs.collapseEndpointListForResource("")},listAll:function(){Docs.collapseOperationsForResource("")},expandAll:function(){Docs.expandOperationsForResource("")},render:function(){var e;switch(this.showMessage("Finished Loading Resource Information. Rendering Swagger UI..."),this.mainView=new SwaggerUi.Views.MainView({model:this.api,el:$("#"+this.dom_id),swaggerOptions:this.options,router:this}).render(),_.isEmpty(this.api.securityDefinitions)||(e=_.map(this.api.securityDefinitions,function(e,t){var n={};return n[t]=e,n}),this.authView=new SwaggerUi.Views.AuthButtonView({data:SwaggerUi.utils.parseSecurityDefinitions(e),router:this}),$("#auth_container").append(this.authView.render().el)),this.showMessage(),this.options.docExpansion){case"full":this.expandAll();break;case"list":this.listAll()}this.renderGFM(),this.options.onComplete&&this.options.onComplete(this.api,this),setTimeout(Docs.shebang.bind(this),100)},buildUrl:function(e,t){if(0===t.indexOf("/")){var n=e.split("/");return e=n[0]+"//"+n[2],e+t}var r=e.length;return e.indexOf("?")>-1&&(r=Math.min(r,e.indexOf("?"))),e.indexOf("#")>-1&&(r=Math.min(r,e.indexOf("#"))),e=e.substring(0,r),e.indexOf("/",e.length-1)!==-1?e+t:e+"/"+t},showMessage:function(e){void 0===e&&(e="");var t=$("#message-bar");t.removeClass("message-fail"),t.addClass("message-success"),t.text(e),window.SwaggerTranslator&&window.SwaggerTranslator.translate(t)},onLoadFailure:function(e){void 0===e&&(e=""),$("#message-bar").removeClass("message-success"),$("#message-bar").addClass("message-fail");var t=$("#message-bar").text(e);return this.options.onFailure&&this.options.onFailure(e),t},renderGFM:function(){$(".markdown").each(function(){$(this).html(marked($(this).html()))}),$(".propDesc",".model-signature .description").each(function(){$(this).html(marked($(this).html())).addClass("markdown")})}}),window.SwaggerUi.Views={},window.SwaggerUi.Models={},window.SwaggerUi.Collections={},window.SwaggerUi.partials={},window.SwaggerUi.utils={},function(){function e(e){"console"in window&&"function"==typeof window.console.warn&&console.warn(e)}window.authorizations={add:function(){if(e("Using window.authorizations is deprecated. Please use SwaggerUi.api.clientAuthorizations.add()."),"undefined"==typeof window.swaggerUi)throw new TypeError("window.swaggerUi is not defined");window.swaggerUi instanceof SwaggerUi&&window.swaggerUi.api.clientAuthorizations.add.apply(window.swaggerUi.api.clientAuthorizations,arguments)}},window.ApiKeyAuthorization=function(){e("window.ApiKeyAuthorization is deprecated. Please use SwaggerClient.ApiKeyAuthorization."),SwaggerClient.ApiKeyAuthorization.apply(window,arguments)},window.PasswordAuthorization=function(){e("window.PasswordAuthorization is deprecated. Please use SwaggerClient.PasswordAuthorization."),SwaggerClient.PasswordAuthorization.apply(window,arguments)}}(),function(e,t){"function"==typeof define&&define.amd?define(["b"],function(n){return e.SwaggerUi=t(n)}):"object"==typeof exports?module.exports=t(require("b")):e.SwaggerUi=t(e.b)}(this,function(){return SwaggerUi}),window.SwaggerUi.utils={parseSecurityDefinitions:function(e){var t=Object.assign({},window.swaggerUi.api.authSchemes||window.swaggerUi.api.securityDefinitions),n=[],r=[],i=[],a=window.SwaggerUi.utils;return Array.isArray(e)?(e.forEach(function(e){var o={},s={};for(var l in e)if(Array.isArray(e[l])){if(!t[l])continue;if(t[l]=t[l]||{},"oauth2"===t[l].type){s[l]=Object.assign({},t[l]),s[l].scopes=Object.assign({},t[l].scopes);for(var u in s[l].scopes)e[l].indexOf(u)<0&&delete s[l].scopes[u];s[l].scopes=a.parseOauth2Scopes(s[l].scopes),i=_.merge(i,s[l].scopes)}else o[l]=Object.assign({},t[l])}else"oauth2"===e[l].type?(s[l]=Object.assign({},e[l]),s[l].scopes=a.parseOauth2Scopes(s[l].scopes),i=_.merge(i,s[l].scopes)):o[l]=e[l];_.isEmpty(o)||r.push(o),_.isEmpty(s)||n.push(s)}),{auths:r,oauth2:n,scopes:i}):null},parseOauth2Scopes:function(e){var t,n=Object.assign({},e),r=[];for(t in n)r.push({scope:t,description:n[t]});return r},sanitize:function(e){return e=e.replace(/<script\b[^<]*(?:(?!<\/script>)<[^<]*)*<\/script>/gi,""),e=e.replace(/(on\w+="[^"]*")*(on\w+='[^']*')*(on\w+=\w*\(\w*\))*/gi,"")}},SwaggerUi.Models.ApiKeyAuthModel=Backbone.Model.extend({defaults:{"in":"",name:"",title:"",value:""},initialize:function(){this.on("change",this.validate)},validate:function(){var e=!!this.get("value");return this.set("valid",e),e}}),SwaggerUi.Views.ApiKeyAuthView=Backbone.View.extend({events:{"change .input_apiKey_entry":"apiKeyChange"},selectors:{apikeyInput:".input_apiKey_entry"},template:Handlebars.templates.apikey_auth,initialize:function(e){this.options=e||{},this.router=this.options.router},render:function(){return this.$el.html(this.template(this.model.toJSON())),this},apiKeyChange:function(e){var t=$(e.target).val();t&&this.$(this.selectors.apikeyInput).removeClass("error"),this.model.set("value",t)},isValid:function(){return this.model.validate()},highlightInvalid:function(){this.isValid()||this.$(this.selectors.apikeyInput).addClass("error")}}),SwaggerUi.Views.AuthButtonView=Backbone.View.extend({events:{"click .authorize__btn":"authorizeBtnClick"},tpls:{popup:Handlebars.templates.popup,authBtn:Handlebars.templates.auth_button,authBtnOperation:Handlebars.templates.auth_button_operation},initialize:function(e){this.options=e||{},this.options.data=this.options.data||{},this.isOperation=this.options.isOperation,this.model=this.model||{},this.router=this.options.router,this.auths=this.options.data.oauth2.concat(this.options.data.auths)},render:function(){var e=this.isOperation?"authBtnOperation":"authBtn";return this.$authEl=this.renderAuths(this.auths),this.$el.html(this.tpls[e](this.model)),this},authorizeBtnClick:function(e){var t;e.preventDefault(),t={title:"Available authorizations",content:this.$authEl},this.render(),this.popup=new SwaggerUi.Views.PopupView({model:t}),this.popup.render()},renderAuths:function(e){var t=$("<div>"),n=!1;return e.forEach(function(e){var r=new SwaggerUi.Views.AuthView({data:e,router:this.router}),i=r.render().el;t.append(i),r.isLogout&&(n=!0)},this),this.model.isLogout=n,t}}),SwaggerUi.Collections.AuthsCollection=Backbone.Collection.extend({constructor:function(){var e=Array.prototype.slice.call(arguments);e[0]=this.parse(e[0]),Backbone.Collection.apply(this,e)},add:function(e){var t=Array.prototype.slice.call(arguments);Array.isArray(e)?t[0]=_.map(e,function(e){return this.handleOne(e)},this):t[0]=this.handleOne(e),Backbone.Collection.prototype.add.apply(this,t)},handleOne:function(e){var t=e;if(!(e instanceof Backbone.Model))switch(e.type){case"oauth2":t=new SwaggerUi.Models.Oauth2Model(e);break;case"basic":t=new SwaggerUi.Models.BasicAuthModel(e);break;case"apiKey":t=new SwaggerUi.Models.ApiKeyAuthModel(e);break;default:t=new Backbone.Model(e)}return t},isValid:function(){var e=!0;return this.models.forEach(function(t){t.validate()||(e=!1)}),e},isAuthorized:function(){return this.length===this.where({isLogout:!0}).length},isPartiallyAuthorized:function(){return this.where({isLogout:!0}).length>0},parse:function(e){var t=Object.assign({},window.swaggerUi.api.clientAuthorizations.authz);return _.map(e,function(e,n){var r=t[n]&&"basic"===e.type&&t[n].username&&t[n].password;return _.extend(e,{title:n}),(t[n]||r)&&_.extend(e,{isLogout:!0,value:r?void 0:t[n].value,username:r?t[n].username:void 0,password:r?t[n].password:void 0,valid:!0}),e})}}),SwaggerUi.Views.AuthsCollectionView=Backbone.View.extend({initialize:function(e){this.options=e||{},this.options.data=this.options.data||{},this.router=this.options.router,this.collection=new SwaggerUi.Collections.AuthsCollection(e.data),this.$innerEl=$("<div>"),this.authViews=[]},render:function(){return this.collection.each(function(e){this.renderOneAuth(e)},this),this.$el.html(this.$innerEl.html()?this.$innerEl:""),this},renderOneAuth:function(e){var t,n,r,i=e.get("type");"apiKey"===i?r="ApiKeyAuthView":"basic"===i&&0===this.$innerEl.find(".basic_auth_container").length?r="BasicAuthView":"oauth2"===i&&(r="Oauth2View"),r&&(n=new SwaggerUi.Views[r]({model:e,router:this.router}),t=n.render().el,this.authViews.push(n)),this.$innerEl.append(t)},highlightInvalid:function(){this.authViews.forEach(function(e){e.highlightInvalid()},this)}}),SwaggerUi.Views.AuthView=Backbone.View.extend({events:{"click .auth_submit__button":"authorizeClick","click .auth_logout__button":"logoutClick"},tpls:{main:Handlebars.templates.auth_view},selectors:{innerEl:".auth_inner",authBtn:".auth_submit__button"},initialize:function(e){this.options=e||{},e.data=e.data||{},this.router=this.options.router,this.authsCollectionView=new SwaggerUi.Views.AuthsCollectionView({data:e.data}),this.$el.html(this.tpls.main({isLogout:this.authsCollectionView.collection.isAuthorized(),isAuthorized:this.authsCollectionView.collection.isPartiallyAuthorized()})),this.$innerEl=this.$(this.selectors.innerEl),this.isLogout=this.authsCollectionView.collection.isPartiallyAuthorized()},render:function(){return this.$innerEl.html(this.authsCollectionView.render().el),this},authorizeClick:function(e){e.preventDefault(),e.stopPropagation(),this.authsCollectionView.collection.isValid()?this.authorize():this.authsCollectionView.highlightInvalid()},authorize:function(){this.authsCollectionView.collection.forEach(function(e){var t,n,r=e.get("type");"apiKey"===r?(t=new SwaggerClient.ApiKeyAuthorization(e.get("name"),e.get("value"),e.get("in")),this.router.api.clientAuthorizations.add(e.get("title"),t)):"basic"===r?(n=new SwaggerClient.PasswordAuthorization(e.get("username"),e.get("password")),this.router.api.clientAuthorizations.add(e.get("title"),n)):"oauth2"===r&&this.handleOauth2Login(e)},this),this.router.load()},logoutClick:function(e){e.preventDefault(),this.authsCollectionView.collection.forEach(function(e){window.swaggerUi.api.clientAuthorizations.remove(e.get("title"))}),this.router.load()},handleOauth2Login:function(e){var t,n,r,i=window.location,a=location.pathname.substring(0,location.pathname.lastIndexOf("/")),o=i.protocol+"//"+i.host+a+"/o2c.html",s=window.oAuthRedirectUrl||o,l=null,u=_.map(e.get("scopes"),function(e){return e.scope});window.OAuthSchemeKey=e.get("title"),window.enabledScopes=u;var c=e.get("flow");if("oauth2"!==e.get("type")||!c||"implicit"!==c&&"accessCode"!==c){if("oauth2"===e.get("type")&&c&&"application"===c)return n=e.attributes,window.swaggerUi.tokenName=n.tokenName||"access_token",void this.clientCredentialsFlow(u,n.tokenUrl,window.OAuthSchemeKey);if(e.get("grantTypes")){var p=e.get("grantTypes");for(var h in p)p.hasOwnProperty(h)&&"implicit"===h?(n=p[h],r=n.loginEndpoint.url,l=n.loginEndpoint.url+"?response_type=token",window.swaggerUi.tokenName=n.tokenName):p.hasOwnProperty(h)&&"accessCode"===h&&(n=p[h],r=n.tokenRequestEndpoint.url,l=n.tokenRequestEndpoint.url+"?response_type=code",window.swaggerUi.tokenName=n.tokenName)}}else n=e.attributes,l=n.authorizationUrl+"?response_type="+("implicit"===c?"token":"code"),window.swaggerUi.tokenName=n.tokenName||"access_token",window.swaggerUi.tokenUrl="accessCode"===c?n.tokenUrl:null,t=window.OAuthSchemeKey;redirect_uri=s,l+="&redirect_uri="+encodeURIComponent(s),l+="&realm="+encodeURIComponent(realm),l+="&client_id="+encodeURIComponent(clientId),l+="&scope="+encodeURIComponent(u.join(scopeSeparator)),l+="&state="+encodeURIComponent(t);for(var f in additionalQueryStringParams)l+="&"+f+"="+encodeURIComponent(additionalQueryStringParams[f]);window.open(l)},clientCredentialsFlow:function(e,t,n){var r={client_id:clientId,client_secret:clientSecret,scope:e.join(" "),grant_type:"client_credentials"};$.ajax({url:t,type:"POST",data:r,success:function(e){onOAuthComplete(e,n)},error:function(){onOAuthComplete("")}})}}),SwaggerUi.Models.BasicAuthModel=Backbone.Model.extend({defaults:{username:"",password:"",title:"basic"},initialize:function(){this.on("change",this.validate)},validate:function(){var e=!!this.get("password")&&!!this.get("username");return this.set("valid",e),e}}),SwaggerUi.Views.BasicAuthView=Backbone.View.extend({initialize:function(e){this.options=e||{},this.router=this.options.router},events:{"change .auth_input":"inputChange"},selectors:{usernameInput:".basic_auth__username",passwordInput:".basic_auth__password"},cls:{error:"error"},template:Handlebars.templates.basic_auth,render:function(){return $(this.el).html(this.template(this.model.toJSON())),this},inputChange:function(e){var t=$(e.target),n=t.val(),r=t.prop("name");n&&t.removeClass(this.cls.error),this.model.set(r,n)},isValid:function(){return this.model.validate()},highlightInvalid:function(){this.model.get("username")||this.$(this.selectors.usernameInput).addClass(this.cls.error)}}),SwaggerUi.Views.ContentTypeView=Backbone.View.extend({initialize:function(){},render:function(){return this.model.contentTypeId="ct"+Math.random(),$(this.el).html(Handlebars.templates.content_type(this.model)),this}}),SwaggerUi.Views.HeaderView=Backbone.View.extend({events:{"click #show-pet-store-icon":"showPetStore","click #explore":"showCustom","submit #api_selector":"showCustom","keyup #input_baseUrl":"showCustomOnKeyup","keyup #input_apiKey":"showCustomOnKeyup"},initialize:function(){},showPetStore:function(){this.trigger("update-swagger-ui",{url:"http://petstore.swagger.io/v2/swagger.json"})},showCustomOnKeyup:function(e){13===e.keyCode&&this.showCustom()},showCustom:function(e){e&&e.preventDefault(),this.trigger("update-swagger-ui",{url:$("#input_baseUrl").val()})},update:function(e,t,n){void 0===n&&(n=!1),$("#input_baseUrl").val(e),n&&this.trigger("update-swagger-ui",{url:e})}}),SwaggerUi.Views.MainView=Backbone.View.extend({apisSorter:{alpha:function(e,t){return e.name.localeCompare(t.name)}},operationsSorters:{alpha:function(e,t){return e.path.localeCompare(t.path)},method:function(e,t){return e.method.localeCompare(t.method)}},initialize:function(e){var t,n,r,i;if(e=e||{},this.router=e.router,e.swaggerOptions.apisSorter&&(t=e.swaggerOptions.apisSorter,n=_.isFunction(t)?t:this.apisSorter[t],_.isFunction(n)&&this.model.apisArray.sort(n)),e.swaggerOptions.operationsSorter&&(t=e.swaggerOptions.operationsSorter,n=_.isFunction(t)?t:this.operationsSorters[t],_.isFunction(n)))for(r in this.model.apisArray)this.model.apisArray[r].operationsArray.sort(n);this.model.auths=[];for(r in this.model.securityDefinitions)i=this.model.securityDefinitions[r],this.model.auths.push({name:r,type:i.type,value:i});"validatorUrl"in e.swaggerOptions?this.model.validatorUrl=e.swaggerOptions.validatorUrl:this.model.url.indexOf("localhost")>0||this.model.url.indexOf("127.0.0.1")>0?this.model.validatorUrl=null:this.model.validatorUrl="//online.swagger.io/validator";var a;for(a in this.model.definitions)this.model.definitions[a].type||(this.model.definitions[a].type="object")},render:function(){$(this.el).html(Handlebars.templates.main(this.model)),this.info=this.$(".info")[0],this.info&&this.info.addEventListener("click",this.onLinkClick,!0),this.model.securityDefinitions=this.model.securityDefinitions||{};for(var e={},t=0,n=0;n<this.model.apisArray.length;n++){for(var r=this.model.apisArray[n],i=r.name;"undefined"!=typeof e[i];)i=i+"_"+t,t+=1;r.id=sanitizeHtml(i),e[i]=r,this.addResource(r,this.model.auths)}return $(".propWrap").hover(function(){$(".optionsWrapper",$(this)).show()},function(){$(".optionsWrapper",$(this)).hide()}),this},addResource:function(e,t){e.id=e.id.replace(/\s/g,"_"),e.definitions=this.model.definitions;var n=new SwaggerUi.Views.ResourceView({model:e,router:this.router,tagName:"li",id:"resource_"+e.id,className:"resource",auths:t,swaggerOptions:this.options.swaggerOptions});$("#resources",this.el).append(n.render().el)},clear:function(){$(this.el).html("")},onLinkClick:function(e){var t=e.target;"A"===t.tagName&&t.href&&!t.target&&(e.preventDefault(),window.open(t.href,"_blank"))}}),SwaggerUi.Models.Oauth2Model=Backbone.Model.extend({defaults:{scopes:{}},initialize:function(){this.on("change",this.validate)},setScopes:function(e,t){var n=_.extend({},this.attributes),r=_.findIndex(n.scopes,function(t){return t.scope===e});n.scopes[r].checked=t,this.set(n),this.validate()},validate:function(){var e=!1,t=this.get("scopes"),n=_.findIndex(t,function(e){return e.checked===!0});return t.length>0&&n>=0&&(e=!0),0===t.length&&(e=!0),this.set("valid",e),e}}),SwaggerUi.Views.Oauth2View=Backbone.View.extend({events:{"change .oauth-scope":"scopeChange"},template:Handlebars.templates.oauth2,render:function(){return this.$el.html(this.template(this.model.toJSON())),this},scopeChange:function(e){var t=$(e.target).prop("checked"),n=$(e.target).data("scope");this.model.setScopes(n,t)}}),SwaggerUi.Views.OperationView=Backbone.View.extend({invocationUrl:null,events:{"submit .sandbox":"submitOperation","click .submit":"submitOperation","click .response_hider":"hideResponse","click .toggleOperation":"toggleOperationContent","mouseenter .api-ic":"mouseEnter","dblclick .curl":"selectText","change [name=responseContentType]":"showSnippet"},initialize:function(e){return e=e||{},this.router=e.router,this.auths=e.auths,this.parentId=this.model.parentId,this.nickname=this.model.nickname,this.model.encodedParentId=encodeURIComponent(this.parentId),e.swaggerOptions&&(this.model.defaultRendering=e.swaggerOptions.defaultModelRendering,e.swaggerOptions.showRequestHeaders&&(this.model.showRequestHeaders=!0)),this},selectText:function(e){var t,n,r=document,i=e.target.firstChild;r.body.createTextRange?(t=document.body.createTextRange(),t.moveToElementText(i),t.select()):window.getSelection&&(n=window.getSelection(),t=document.createRange(),t.selectNodeContents(i),n.removeAllRanges(),n.addRange(t))},mouseEnter:function(e){var t=$(this.el).find(".content"),n=e.pageX,r=e.pageY,i=$(window).scrollLeft(),a=$(window).scrollTop(),o=i+$(window).width(),s=a+$(window).height(),l=t.width(),u=t.height();n+l>o&&(n=o-l),n<i&&(n=i),r+u>s&&(r=s-u),r<a&&(r=a);var c={};c.top=r,c.left=n,t.css(c)},render:function(){var e,t,n,r,i,a,o,s,l,u,c,p,h,f,d,m,g,y,v,b,w,x,A,S,j,E,O,k,T,C,I,D,L,M,R,U,P,q,B,N,z;if(a=jQuery.inArray(this.model.method,this.model.supportedSubmitMethods())>=0,a||(this.model.isReadOnly=!0),this.model.description=this.model.description||this.model.notes,this.model.oauth=null,m=this.model.authorizations||this.model.security)if(Array.isArray(m))for(l=0,u=m.length;l<u;l++){n=m[l];for(s in n)for(e in this.auths)if(t=this.auths[e],s===t.name&&"oauth2"===t.type){this.model.oauth={},this.model.oauth.scopes=[],A=t.value.scopes;for(o in A)P=A[o],D=n[s].indexOf(o),D>=0&&(y={scope:o,description:P},this.model.oauth.scopes.push(y))}}else for(o in m)if(P=m[o],"oauth2"===o)for(null===this.model.oauth&&(this.model.oauth={}),void 0===this.model.oauth.scopes&&(this.model.oauth.scopes=[]),d=0,c=P.length;d<c;d++)y=P[d],this.model.oauth.scopes.push(y);if("undefined"!=typeof this.model.responses){this.model.responseMessages=[],S=this.model.responses;for(r in S)q=S[r],C=null,I=this.model.responses[r].schema,I&&I.$ref&&(C=I.$ref,C.indexOf("#/definitions/")!==-1&&(C=C.replace(/^.*#\/definitions\//,""))),this.model.responseMessages.push({code:r,message:q.description,responseModel:C,headers:q.headers,schema:I})}if("undefined"==typeof this.model.responseMessages&&(this.model.responseMessages=[]),L=null,B=this.model.produces,N=this.contains(B,"xml"),z=!N||this.contains(B,"json"),this.model.successResponse){R=this.model.successResponse;for(s in R)q=R[s],this.model.successCode=s,"object"==typeof q&&"function"==typeof q.createJSONSample?(this.model.successDescription=q.description,this.model.headers=this.parseResponseHeaders(q.headers),L={sampleJSON:!!z&&JSON.stringify(SwaggerUi.partials.signature.createJSONSample(q),void 0,2),isParam:!1,sampleXML:!!N&&SwaggerUi.partials.signature.createXMLSample(q.name,q.definition,q.models),signature:SwaggerUi.partials.signature.getModelSignature(q.name,q.definition,q.models,q.modelPropertyMacro)}):L={signature:SwaggerUi.partials.signature.getPrimitiveSignature(q)}}else this.model.responseClassSignature&&"string"!==this.model.responseClassSignature&&(L={sampleJSON:this.model.responseSampleJSON,isParam:!1,signature:this.model.responseClassSignature});for($(this.el).html(Handlebars.templates.operation(this.model)),L?(L.defaultRendering=this.model.defaultRendering,T=new SwaggerUi.Views.SignatureView({model:L,router:this.router,tagName:"div"}),$(".model-signature",$(this.el)).append(T.render().el)):(this.model.responseClassSignature="string",$(".model-signature",$(this.el)).html(this.model.type)),i={isParam:!1},i.consumes=this.model.consumes,i.produces=this.model.produces,j=this.model.parameters,g=0,p=j.length;g<p;g++)b=j[g],U=b.type||b.dataType||"","undefined"==typeof U&&(C=b.schema,C&&C.$ref&&(x=C.$ref,U=0===x.indexOf("#/definitions/")?x.substring("#/definitions/".length):x)),U&&"file"===U.toLowerCase()&&(i.consumes||(i.consumes="multipart/form-data")),b.type=U;for(k=new SwaggerUi.Views.ResponseContentTypeView({model:i,router:this.router}),$(".response-content-type",$(this.el)).append(k.render().el),E=this.model.parameters,v=0,h=E.length;v<h;v++)b=E[v],this.addParameter(b,i.consumes);for(O=this.model.responseMessages,w=0,f=O.length;w<f;w++)M=O[w],M.isXML=N,M.isJSON=z,_.isUndefined(M.headers)||(M.headers=this.parseHeadersType(M.headers)),this.addStatusCode(M);if(Array.isArray(this.model.security)){var F=SwaggerUi.utils.parseSecurityDefinitions(this.model.security);F.isLogout=!_.isEmpty(window.swaggerUi.api.clientAuthorizations.authz),this.authView=new SwaggerUi.Views.AuthButtonView({data:F,router:this.router,isOperation:!0,model:{scopes:F.scopes}}),this.$(".authorize-wrapper").append(this.authView.render().el)}return this.showSnippet(),this},parseHeadersType:function(e){var t={string:{"date-time":"dateTime",date:"date"}};return _.forEach(e,function(e){var n;e=e||{},n=t[e.type]&&t[e.type][e.format],_.isUndefined(n)||(e.type=n)}),e},contains:function(e,t){return e.filter(function(e){if(e.indexOf(t)>-1)return!0}).length},parseResponseHeaders:function(e){var t="; ",n=_.clone(e);return _.forEach(n,function(e){var n=[];_.forEach(e,function(e,t){var r=["type","description"];r.indexOf(t.toLowerCase())===-1&&n.push(t+": "+e)}),n.join(t),e.other=n}),n},addParameter:function(e,t){e.consumes=t,e.defaultRendering=this.model.defaultRendering,e.schema&&($.extend(!0,e.schema,this.model.definitions[e.type]),e.schema.definitions=this.model.definitions,e.schema.type||(e.schema.type="object"),e.schema.title||(e.schema.title=" "));var n=new SwaggerUi.Views.ParameterView({model:e,tagName:"tr",readOnly:this.model.isReadOnly,swaggerOptions:this.options.swaggerOptions});$(".operation-params",$(this.el)).append(n.render().el)},addStatusCode:function(e){e.defaultRendering=this.model.defaultRendering;var t=new SwaggerUi.Views.StatusCodeView({model:e,tagName:"tr",router:this.router});$(".operation-status",$(this.el)).append(t.render().el)},submitOperation:function(e){var t,n,r,i,a;if(null!==e&&e.preventDefault(),n=$(".sandbox",$(this.el)),t=!0,n.find("input.required").each(function(){$(this).removeClass("error"),""===jQuery.trim($(this).val())&&($(this).addClass("error"),$(this).wiggle({callback:function(e){return function(){$(e).focus()}}(this)}),t=!1)}),n.find("textarea.required:visible").each(function(){$(this).removeClass("error"),""===jQuery.trim($(this).val())&&($(this).addClass("error"),$(this).wiggle({callback:function(e){return function(){return $(e).focus()}}(this)}),t=!1)}),n.find("select.required").each(function(){$(this).removeClass("error"),this.selectedIndex===-1&&($(this).addClass("error"),$(this).wiggle({callback:function(e){return function(){$(e).focus()}}(this)}),t=!1)}),t){if(i=this.getInputMap(n),r=this.isFileUpload(n),a={parent:this},this.options.swaggerOptions)for(var o in this.options.swaggerOptions)a[o]=this.options.swaggerOptions[o];var s;for(s=0;s<this.model.parameters.length;s++){var l=this.model.parameters[s];if(l.jsonEditor&&l.jsonEditor.isEnabled()){var u=l.jsonEditor.getValue();i[l.name]=JSON.stringify(u)}}return a.responseContentType=$("div select[name=responseContentType]",$(this.el)).val(),a.requestContentType=$("div select[name=parameterContentType]",$(this.el)).val(),$(".response_throbber",$(this.el)).show(),r?($(".request_url",$(this.el)).html("<pre></pre>"),$(".request_url pre",$(this.el)).text(this.invocationUrl),a.useJQuery=!0,i.parameterContentType="multipart/form-data",this.map=i,this.model.execute(i,a,this.showCompleteStatus,this.showErrorStatus,this)):(this.map=i,this.model.execute(i,a,this.showCompleteStatus,this.showErrorStatus,this))}},getInputMap:function(e){var t,n,r,i,a,o,s,l,u,c,p,h;for(t={},n=e.find("input"),r=0,i=n.length;r<i;r++)a=n[r],null!==a.value&&jQuery.trim(a.value).length>0&&(t[a.name]=a.value),"file"===a.type&&(t[a.name]=a.files[0]);for(o=e.find("textarea"),s=0,l=o.length;s<l;s++)a=o[s],u=this.getTextAreaValue(a),null!==u&&jQuery.trim(u).length>0&&(t[a.name]=u);for(c=e.find("select"),p=0,h=c.length;p<h;p++)a=c[p],u=this.getSelectedValue(a),null!==u&&jQuery.trim(u).length>0&&(t[a.name]=u);return t},isFileUpload:function(e){var t,n,r,i,a=!1;for(t=e.find("input"),n=0,r=t.length;n<r;n++)i=t[n],"file"===i.type&&(a=!0);return a},success:function(e,t){t.showCompleteStatus(e)},wrap:function(e){var t,n,r,i,a,o,s;for(r={},n=e.getAllResponseHeaders().split("\r"),a=0,o=n.length;a<o;a++)i=n[a],t=i.match(/^([^:]*?):(.*)$/),t||(t=[]),t.shift(),void 0!==t[0]&&void 0!==t[1]&&(r[t[0].trim()]=t[1].trim());return s={},s.content={},s.content.data=e.responseText,s.headers=r,s.request={},s.request.url=this.invocationUrl,s.status=e.status,s},getSelectedValue:function(e){if(e.multiple){for(var t=[],n=0,r=e.options.length;n<r;n++){var i=e.options[n];i.selected&&t.push(i.value)}return t.length>0?t:null}return e.value},hideResponse:function(e){e&&e.preventDefault(),$(".response",$(this.el)).slideUp(),$(".response_hider",$(this.el)).fadeOut()},showResponse:function(e){var t=JSON.stringify(e,null,"\t").replace(/\n/g,"<br>");$(".response_body",$(this.el)).html(_.escape(t))},showErrorStatus:function(e,t){t.showStatus(e)},showCompleteStatus:function(e,t){t.showStatus(e)},formatXml:function(e){var t,n,r,i,a,o,s,l,u,c,p,h,f;for(p=/(>)(<)(\/*)/g,f=/[ ]*(.*)[ ]+\n/g,t=/(<.+>)(.+\n)/g,e=e.replace(/\r\n/g,"\n").replace(p,"$1\n$2$3").replace(f,"$1\n").replace(t,"$1\n$2"),c=0,r="",l=e.split("\n"),i=0,o="other",h={"single->single":0,"single->closing":-1,"single->opening":0,"single->other":0,"closing->single":0,"closing->closing":-1,"closing->opening":0,"closing->other":0,"opening->single":1,"opening->closing":0,"opening->opening":1,"opening->other":1,"other->single":0,"other->closing":-1,"other->opening":0,"other->other":0},n=function(e){var t,n,a,s,l,u,c;u={single:Boolean(e.match(/<.+\/>/)),closing:Boolean(e.match(/<\/.+>/)),opening:Boolean(e.match(/<[^!?].*>/))},l=function(){var e;e=[];for(a in u)c=u[a],c&&e.push(a);return e}()[0],l=void 0===l?"other":l,t=o+"->"+l,o=l,s="",i+=h[t],s=function(){var e,t,r;for(r=[],n=e=0,t=i;0<=t?e<t:e>t;n=0<=t?++e:--e)r.push(" ");return r}().join(""),"opening->closing"===t?r=r.substr(0,r.length-1)+e+"\n":r+=s+e+"\n"},a=0,s=l.length;a<s;a++)u=l[a],n(u);return r},showStatus:function(e){var t,n;void 0===e.content?(n=e.data,t=e.url):(n=e.content.data,t=e.request.url);var r=e.headers;n=jQuery.trim(n);var i=null;r&&(i=r["Content-Type"]||r["content-type"],i&&(i=i.split(";")[0].trim())),$(".response_body",$(this.el)).removeClass("json"),$(".response_body",$(this.el)).removeClass("xml");var a,o,s=function(e){var t=document.createElement("audio");return!(!t.canPlayType||!t.canPlayType(e).replace(/no/,""))};if(n)if("application/json"===i||/\+json$/.test(i)){var l=null;
-try{l=JSON.stringify(JSON.parse(n),null," ")}catch(u){l="can't parse JSON. Raw result:\n\n"+n}o=$("<code />").text(l),a=$('<pre class="json" />').append(o)}else if("application/xml"===i||/\+xml$/.test(i))o=$("<code />").text(this.formatXml(n)),a=$('<pre class="xml" />').append(o);else if("text/html"===i)o=$("<code />").html(_.escape(n)),a=$('<pre class="xml" />').append(o);else if(/text\/plain/.test(i))o=$("<code />").text(n),a=$('<pre class="plain" />').append(o);else if(/^image\//.test(i))a=$("<img>").attr("src",t);else if(/^audio\//.test(i)&&s(i))a=$("<audio controls>").append($("<source>").attr("src",t).attr("type",i));else if(r["Content-Disposition"]&&/attachment/.test(r["Content-Disposition"])||r["content-disposition"]&&/attachment/.test(r["content-disposition"])||r["Content-Description"]&&/File Transfer/.test(r["Content-Description"])||r["content-description"]&&/File Transfer/.test(r["content-description"]))if("Blob"in window){var c=i||"text/html",p=new Blob([n],{type:c}),h=document.createElement("a"),f=window.URL.createObjectURL(p),d=e.url.substr(e.url.lastIndexOf("/")+1),m=[c,d,f].join(":"),g=r["content-disposition"]||r["Content-Disposition"];if("undefined"!=typeof g){var y=/filename=([^;]*);?/.exec(g);null!==y&&y.length>1&&(m=y[1])}h.setAttribute("href",f),h.setAttribute("download",m),h.innerText="Download "+d,a=$("<div/>").append(h)}else a=$('<pre class="json" />').append("Download headers detected but your browser does not support downloading binary via XHR (Blob).");else r.location||r.Location?window.location=e.url:(o=$("<code />").text(n),a=$('<pre class="json" />').append(o));else o=$("<code />").text("no content"),a=$('<pre class="json" />').append(o);var v=a;$(".request_url",$(this.el)).html("<pre></pre>"),$(".request_url pre",$(this.el)).text(t),$(".response_code",$(this.el)).html("<pre>"+e.status+"</pre>"),$(".response_body",$(this.el)).html(v),$(".response_headers",$(this.el)).html("<pre>"+_.escape(JSON.stringify(e.headers,null," ")).replace(/\n/g,"<br>")+"</pre>"),$(".response",$(this.el)).slideDown(),$(".response_hider",$(this.el)).show(),$(".response_throbber",$(this.el)).hide();var b=this.model.asCurl(this.map,{responseContentType:i});b=b.replace("!","&#33;"),$("div.curl",$(this.el)).html("<pre>"+_.escape(b)+"</pre>");var w=this.options.swaggerOptions;if(w.showRequestHeaders){var x=$(".sandbox",$(this.el)),A=this.getInputMap(x),S=this.model.getHeaderParams(A);delete S["Content-Type"],$(".request_headers",$(this.el)).html("<pre>"+_.escape(JSON.stringify(S,null," ")).replace(/\n/g,"<br>")+"</pre>")}var j=$(".response_body",$(this.el))[0];return w.highlightSizeThreshold&&"undefined"!=typeof e.data&&e.data.length>w.highlightSizeThreshold?j:hljs.highlightBlock(j)},toggleOperationContent:function(e){var t=$("#"+Docs.escapeResourceName(this.parentId+"_"+this.nickname+"_content"));t.is(":visible")?($.bbq.pushState("#/",2),e.preventDefault(),Docs.collapseOperation(t)):Docs.expandOperation(t)},getTextAreaValue:function(e){var t,n,r,i;if(null===e.value||0===jQuery.trim(e.value).length)return null;if(t=this.getParamByName(e.name),t&&t.type&&"array"===t.type.toLowerCase()){for(n=e.value.split("\n"),r=[],i=0;i<n.length;i++)null!==n[i]&&jQuery.trim(n[i]).length>0&&r.push(n[i]);return r.length>0?r:null}return e.value},showSnippet:function(){var e,t=this.$("[name=responseContentType]"),n=this.$(".operation-status .snippet_xml, .response-class .snippet_xml"),r=this.$(".operation-status .snippet_json, .response-class .snippet_json");t.length&&(e=t.val(),e.indexOf("xml")>-1?(n.show(),r.hide()):(r.show(),n.hide()))},getParamByName:function(e){var t;if(this.model.parameters)for(t=0;t<this.model.parameters.length;t++)if(this.model.parameters[t].name===e)return this.model.parameters[t];return null}}),SwaggerUi.Views.ParameterContentTypeView=Backbone.View.extend({initialize:function(){},render:function(){return this.model.parameterContentTypeId="pct"+Math.random(),$(this.el).html(Handlebars.templates.parameter_content_type(this.model)),this}}),SwaggerUi.Views.ParameterView=Backbone.View.extend({events:{"change [name=parameterContentType]":"toggleParameterSnippet"},initialize:function(){Handlebars.registerHelper("isArray",function(e,t){var n=e.type&&e.type.toLowerCase();return"array"===n||e.allowMultiple?t.fn(this):t.inverse(this)})},render:function(){var e,t,n=this.model.type||this.model.dataType,r=this.model.modelSignature.type,i=this.model.modelSignature.definitions,a=this.model.schema||{},o=this.model.consumes||[];if("undefined"==typeof n&&a.$ref){var s=a.$ref;n=0===s.indexOf("#/definitions/")?s.substring("#/definitions/".length):s}this.model.type=n,this.model.paramType=this.model["in"]||this.model.paramType,this.model.isBody="body"===this.model.paramType||"body"===this.model["in"],this.model.isFile=n&&"file"===n.toLowerCase(),"undefined"==typeof this.model["default"]&&(this.model["default"]=this.model.defaultValue),this.model.hasDefault="undefined"!=typeof this.model["default"],this.model.valueId="m"+this.model.name+Math.random(),this.model.allowableValues&&(this.model.isList=!0);var l=this.contains(o,"xml"),u=!l||this.contains(o,"json");e=SwaggerUi.partials.signature.createParameterJSONSample(r,i);var c=this.template();$(this.el).html(c(this.model));var p={sampleJSON:!!u&&e,sampleXML:!(!e||!l)&&SwaggerUi.partials.signature.createXMLSample("",a,i,!0),isParam:!0,signature:SwaggerUi.partials.signature.getParameterModelSignature(r,i),defaultRendering:this.model.defaultRendering};e?(t=new SwaggerUi.Views.SignatureView({model:p,tagName:"div"}),$(".model-signature",$(this.el)).append(t.render().el)):$(".model-signature",$(this.el)).html(this.model.signature);var h=!1;if(this.options.swaggerOptions.jsonEditor&&this.model.isBody&&this.model.schema){var f=$(this.el);this.model.jsonEditor=new JSONEditor($(".editor_holder",f)[0],{schema:this.model.schema,startval:this.model["default"],ajax:!0,disable_properties:!0,disable_edit_json:!0,iconlib:"swagger"}),p.jsonEditor=this.model.jsonEditor,$(".body-textarea",f).hide(),$(".editor_holder",f).show(),$(".parameter-content-type",f).change(function(e){"application/xml"===e.target.value?($(".body-textarea",f).show(),$(".editor_holder",f).hide(),this.model.jsonEditor.disable()):($(".body-textarea",f).hide(),$(".editor_holder",f).show(),this.model.jsonEditor.enable())})}this.model.isBody&&(h=!0);var d={isParam:h};if(d.consumes=this.model.consumes,h){var m=new SwaggerUi.Views.ParameterContentTypeView({model:d});$(".parameter-content-type",$(this.el)).append(m.render().el),this.toggleParameterSnippet()}else{var g=new SwaggerUi.Views.ResponseContentTypeView({model:d});$(".response-content-type",$(this.el)).append(g.render().el),this.toggleResponseSnippet()}return this},contains:function(e,t){return e.filter(function(e){if(e.indexOf(t)>-1)return!0}).length},toggleParameterSnippet:function(){var e=this.$("[name=parameterContentType]").val();this.toggleSnippet(e)},toggleResponseSnippet:function(){var e=this.$("[name=responseContentType]");e.length&&this.toggleSnippet(e.val())},toggleSnippet:function(e){e=e||"",e.indexOf("xml")>-1?(this.$(".snippet_xml").show(),this.$(".snippet_json").hide()):(this.$(".snippet_json").show(),this.$(".snippet_xml").hide())},template:function(){return this.model.isList?Handlebars.templates.param_list:this.options.readOnly?this.model.required?Handlebars.templates.param_readonly_required:Handlebars.templates.param_readonly:this.model.required?Handlebars.templates.param_required:Handlebars.templates.param}}),SwaggerUi.partials.signature=function(){function e(e){var t,i=e.name,a=e.definition,o=e.config,s=e.models,l=e.config.isParam,u=[],c=a.properties,p=a.additionalProperties,h=a.xml,f=b(h);return f&&u.push(f),c||p?(c=c||{},t=_.map(c,function(e,t){var n,i;return l&&e.readOnly?"":(n=e.xml||{},i=r(t,e,s,o),n.attribute?(u.push(i),""):i)}).join(""),p&&(t+="<!-- additional elements allowed -->"),y(i,t,u)):n()}function t(e,t){return y(e,"<!-- Infinite loop $ref:"+t+" -->")}function n(e){return e=e?": "+e:"","<!-- invalid XML"+e+" -->"}function r(r,i,s,l){var u,c,p=_.isObject(i)?i.$ref:null;l=l||{},l.modelsToIgnore=l.modelsToIgnore||[];var h=_.isString(p)?a(p,r,s,l):o(r,i,s,l);if(!h)return n();switch(h.type){case"array":u=w(h);break;case"object":u=e(h);break;case"loop":u=t(h.name,h.config.loopTo);break;default:u=A(h)}return p&&"loop"!==h.type&&(c=l.modelsToIgnore.indexOf(p),c>-1&&l.modelsToIgnore.splice(c,1)),u}function i(e,t,n,r,i){if(arguments.length<4)throw new Error;this.config=i||{},this.config.modelsToIgnore=this.config.modelsToIgnore||[],this.name=v(e,n.xml),this.definition=n,this.models=r,this.type=t}function a(e,t,n,r){var a=u(e),o=n[a]||{},s=o.definition&&o.definition.type?o.definition.type:"object";return t=t||o.name,r.modelsToIgnore.indexOf(e)>-1?(s="loop",r.loopTo=a):r.modelsToIgnore.push(e),o.definition?new i(t,s,o.definition,n,r):null}function o(e,t,n,r){var a=t.type||"object";return t?new i(e,a,t,n,r):null}function s(e,t,n,i){var a='<?xml version="1.0"?>';return p(a+r(e,t,n,{isParam:i}))}var l=function(e){return _.isPlainObject(e.schema)&&(e=l(e.schema)),e},u=function(e){return"undefined"==typeof e?null:0===e.indexOf("#/definitions/")?e.substring("#/definitions/".length):e},c=function(e){if(/^Inline Model \d+$/.test(e)&&this.inlineModels){var t=parseInt(e.substr("Inline Model".length).trim(),10),n=this.inlineModels[t];return n}return null},p=function(e){var t,n,r,i,a,o,s,l,u,c,p,h,f;for(p=/(>)(<)(\/*)/g,f=/[ ]*(.*)[ ]+\n/g,t=/(<.+>)(.+\n)/g,e=e.replace(p,"$1\n$2$3").replace(f,"$1\n").replace(t,"$1\n$2"),c=0,r="",l=e.split("\n"),i=0,o="other",h={"single->single":0,"single->closing":-1,"single->opening":0,"single->other":0,"closing->single":0,"closing->closing":-1,"closing->opening":0,"closing->other":0,"opening->single":1,"opening->closing":0,"opening->opening":1,"opening->other":1,"other->single":0,"other->closing":-1,"other->opening":0,"other->other":0},n=function(e){var t,n,a,s,l,u,c;u={single:Boolean(e.match(/<.+\/>/)),closing:Boolean(e.match(/<\/.+>/)),opening:Boolean(e.match(/<[^!?].*>/))},l=function(){var e;e=[];for(a in u)c=u[a],c&&e.push(a);return e}()[0],l=void 0===l?"other":l,t=o+"->"+l,o=l,s="",i+=h[t],s=function(){var e,t,r;for(r=[],n=e=0,t=i;0<=t?e<t:e>t;n=0<=t?++e:--e)r.push(" ");return r}().join(""),"opening->closing"===t?r=r.substr(0,r.length-1)+e+"\n":r+=s+e+"\n"},a=0,s=l.length;a<s;a++)u=l[a],n(u);return r},h=function(e,t,n,r){function i(e,t,r){var i,a=t;return e.$ref?(a=e.title||u(e.$ref),i=n[u(e.$ref)]):_.isUndefined(t)&&(a=e.title||"Inline Model "+ ++m,i={definition:e}),r!==!0&&(f[a]=_.isUndefined(i)?{}:i.definition),a}function a(e){var t='<span class="propType">',n=e.type||"object";return e.$ref?t+=i(e,u(e.$ref)):"object"===n?t+=_.isUndefined(e.properties)?"object":i(e):"array"===n?(t+="Array[",_.isArray(e.items)?t+=_.map(e.items,i).join(","):_.isPlainObject(e.items)?t+=_.isUndefined(e.items.$ref)?_.isUndefined(e.items.type)||_.indexOf(["array","object"],e.items.type)!==-1?i(e.items):e.items.type:i(e.items,u(e.items.$ref)):(console.log("Array type's 'items' schema is not an array or an object, cannot process"),t+="object"),t+="]"):t+=e.type,t+="</span>"}function o(e,t){var n="",r=e.type||"object",i="array"===r;switch(_.isUndefined(e.description)||(t+=': <span class="propDesc">'+e.description+"</span>"),e["enum"]&&(t+=' = <span class="propVals">[\''+e["enum"].join("', '")+"']</span>"),i&&(r=_.isPlainObject(e.items)&&!_.isUndefined(e.items.type)?e.items.type:"object"),_.isUndefined(e["default"])||(n+=h("Default",e["default"])),r){case"string":e.minLength&&(n+=h("Min. Length",e.minLength)),e.maxLength&&(n+=h("Max. Length",e.maxLength)),e.pattern&&(n+=h("Reg. Exp.",e.pattern));break;case"integer":case"number":e.minimum&&(n+=h("Min. Value",e.minimum)),e.exclusiveMinimum&&(n+=h("Exclusive Min.","true")),e.maximum&&(n+=h("Max. Value",e.maximum)),e.exclusiveMaximum&&(n+=h("Exclusive Max.","true")),e.multipleOf&&(n+=h("Multiple Of",e.multipleOf))}if(i&&(e.minItems&&(n+=h("Min. Items",e.minItems)),e.maxItems&&(n+=h("Max. Items",e.maxItems)),e.uniqueItems&&(n+=h("Unique Items","true")),e.collectionFormat&&(n+=h("Coll. Format",e.collectionFormat))),_.isUndefined(e.items)&&_.isArray(e["enum"])){var a;a="number"===r||"integer"===r?e["enum"].join(", "):'"'+e["enum"].join('", "')+'"',n+=h("Enum",a)}return n.length>0&&(t='<span class="propWrap">'+t+'<table class="optionsWrapper"><tr><th colspan="2">'+r+"</th></tr>"+n+"</table></span>"),t}function s(e,t){var s,h=e.type||"object",f="array"===e.type,m=c+t+" "+(f?"[":"{")+p;return t&&d.push(t),f?_.isArray(e.items)?m+="<div>"+_.map(e.items,function(e){var t=e.type||"object";return _.isUndefined(e.$ref)?_.indexOf(["array","object"],t)>-1?"object"===t&&_.isUndefined(e.properties)?"object":i(e):o(e,t):i(e,u(e.$ref))}).join(",</div><div>"):_.isPlainObject(e.items)?m+=_.isUndefined(e.items.$ref)?_.indexOf(["array","object"],e.items.type||"object")>-1?(_.isUndefined(e.items.type)||"object"===e.items.type)&&_.isUndefined(e.items.properties)?"<div>object</div>":"<div>"+i(e.items)+"</div>":"<div>"+o(e.items,e.items.type)+"</div>":"<div>"+i(e.items,u(e.items.$ref))+"</div>":(console.log("Array type's 'items' property is not an array or an object, cannot process"),m+="<div>object</div>"):e.$ref?m+="<div>"+i(e,t)+"</div>":"object"===h?(_.isPlainObject(e.properties)&&(s=_.map(e.properties,function(t,i){var s,c=_.indexOf(e.required,i)>=0,p=_.cloneDeep(t),h=c?"required":"",f='<span class="propName '+h+'">'+i+"</span> (";return p["default"]=r(p),p=l(p),_.isUndefined(p.$ref)||(s=n[u(p.$ref)],_.isUndefined(s)||_.indexOf([void 0,"array","object"],s.definition.type)!==-1||(p=l(s.definition))),f+=a(p),c||(f+=', <span class="propOptKey">optional</span>'),t.readOnly&&(f+=', <span class="propReadOnly">read only</span>'),f+=")","<div"+(t.readOnly?' class="readOnly"':"")+">"+o(p,f)}).join(",</div>")),s&&(m+=s+"</div>")):m+="<div>"+o(e,h)+"</div>",m+c+(f?"]":"}")+p}var c='<span class="strong">',p="</span>",h=function(e,t){return'<tr><td class="optionName">'+e+":</td><td>"+t+"</td></tr>"};if(_.isObject(arguments[0])&&(e=void 0,t=arguments[0],n=arguments[1],r=arguments[2]),n=n||{},t=l(t),_.isEmpty(t))return c+"Empty"+p;if("string"==typeof t.$ref&&(e=u(t.$ref),t=n[e],"undefined"==typeof t))return c+e+" is not defined!"+p;"string"!=typeof e&&(e=t.title||"Inline Model"),t.definition&&(t=t.definition),"function"!=typeof r&&(r=function(e){return(e||{})["default"]});for(var f={},d=[],m=0,g=s(t,e);_.keys(f).length>0;)_.forEach(f,function(e,t){var n=_.indexOf(d,t)>-1;delete f[t],n||(d.push(t),g+="<br />"+s(e,t))});return g},f=function(e,t,n,r){e=l(e),"function"!=typeof r&&(r=function(e){return(e||{})["default"]}),n=n||{};var i,a,o=e.type||"object",s=e.format;return _.isUndefined(e.example)?_.isUndefined(e.items)&&_.isArray(e["enum"])&&(a=e["enum"][0]):a=e.example,_.isUndefined(a)&&(e.$ref?(i=t[u(e.$ref)],_.isUndefined(i)||(_.isUndefined(n[i.name])?(n[i.name]=i,a=f(i.definition,t,n,r),delete n[i.name]):a="array"===i.type?[]:{})):_.isUndefined(e["default"])?"string"===o?a="date-time"===s?(new Date).toISOString():"date"===s?(new Date).toISOString().split("T")[0]:"string":"integer"===o?a=0:"number"===o?a=0:"boolean"===o?a=!0:"object"===o?(a={},_.forEach(e.properties,function(e,i){var o=_.cloneDeep(e);o["default"]=r(e),a[i]=f(o,t,n,r)})):"array"===o&&(a=[],_.isArray(e.items)?_.forEach(e.items,function(e){a.push(f(e,t,n,r))}):_.isPlainObject(e.items)?a.push(f(e.items,t,n,r)):_.isUndefined(e.items)?a.push({}):console.log("Array type's 'items' property is not an array or an object, cannot process")):a=e["default"]),a},d=function(e,t){return t=t||{},t[e.name]=e,e.examples&&_.isPlainObject(e.examples)&&e.examples["application/json"]?(e.definition.example=e.examples["application/json"],_.isString(e.definition.example)&&(e.definition.example=jsyaml.safeLoad(e.definition.example))):e.definition.example||(e.definition.example=e.examples),f(e.definition,e.models,t,e.modelPropertyMacro)},m=function(e,t){var n,r;return e instanceof Array&&(r=!0,e=e[0]),"undefined"==typeof e?(e="undefined",n=!0):t[e]?(e=t[e],n=!1):c(e)?(e=c(e),n=!1):n=!0,n?r?"Array["+e+"]":e.toString():r?"Array["+h(e.name,e.definition,e.models,e.modelPropertyMacro)+"]":h(e.name,e.definition,e.models,e.modelPropertyMacro)},g=function(e,t){var n,r,i;if(t=t||{},n=e instanceof Array,i=n?e[0]:e,t[i]?r=d(t[i]):c(i)&&(r=d(c(i))),r){if(r=n?[r]:r,"string"==typeof r)return r;if(_.isObject(r)){var a=r;if(r instanceof Array&&r.length>0&&(a=r[0]),a.nodeName&&"Node"==typeof a){var o=(new XMLSerializer).serializeToString(a);return p(o)}return JSON.stringify(r,null,2)}return r}},y=function(e,t,r){var i,a;return r=r||[],a=r.map(function(e){return" "+e.name+'="'+e.value+'"'}).join(""),e?(i=["<",e,a,">",t,"</",e,">"],i.join("")):n("Node name is not provided")},v=function(e,t){var n=e||"";return t=t||{},t.name&&(n=t.name),t.prefix&&(n=t.prefix+":"+n),n},b=function(e){var t="",n="xmlns";return e=e||{},e.namespace?(t=e.namespace,e.prefix&&(n+=":"+e.prefix),{name:n,value:t}):t},w=function(e){var t,i=e.name,a=e.config,o=e.definition,s=e.models,l=o.items,u=o.xml||{},c=b(u),p=[];return l?(t=r(i,l,s,a),c&&p.push(c),u.wrapped&&(t=y(i,t,p)),t):n()},x=function(e){var t,n;switch(e=e||{},n=e.items||{},t=e.type||""){case"object":return"Object is not a primitive";case"array":return"Array["+(n.format||n.type)+"]";default:return e.format||t}},A=function(e){var t,r=e.name,i=e.definition,a={string:{date:new Date(1).toISOString().split("T")[0],"date-time":new Date(1).toISOString(),"default":"string"},integer:{"default":1},number:{"default":1.1},"boolean":{"default":!0}},o=i.type,s=i.format,l=i.xml||{},u=b(l),c=[];return _.keys(a).indexOf(o)<0?n():(t=_.isArray(i["enum"])?i["enum"][0]:i.example||a[o][s]||a[o]["default"],l.attribute?{name:r,value:t}:(u&&c.push(u),y(r,t,c)))};return{getModelSignature:h,createJSONSample:d,getParameterModelSignature:m,createParameterJSONSample:g,createSchemaXML:r,createXMLSample:s,getPrimitiveSignature:x}}(),SwaggerUi.Views.PopupView=Backbone.View.extend({events:{"click .api-popup-cancel":"cancelClick"},template:Handlebars.templates.popup,className:"api-popup-dialog",selectors:{content:".api-popup-content",main:"#swagger-ui-container"},initialize:function(){this.$el.html(this.template(this.model))},render:function(){return this.$(this.selectors.content).append(this.model.content),$(this.selectors.main).first().append(this.el),this.showPopup(),this},showPopup:function(){this.$el.show()},cancelClick:function(){this.remove()}}),SwaggerUi.Views.ResourceView=Backbone.View.extend({initialize:function(e){e=e||{},this.router=e.router,this.auths=e.auths,""===this.model.description&&(this.model.description=null),this.model.description&&(this.model.summary=this.model.description),this.number=0},render:function(){var e={};$(this.el).html(Handlebars.templates.resource(this.model));for(var t=0;t<this.model.operationsArray.length;t++){for(var n=this.model.operationsArray[t],r=0,i=n.nickname;"undefined"!=typeof e[i];)i=i+"_"+r,r+=1;e[i]=n,n.nickname=i,n.parentId=this.model.id,n.definitions=this.model.definitions,this.addOperation(n)}return $(".toggleEndpointList",this.el).click(this.callDocs.bind(this,"toggleEndpointListForResource")),$(".collapseResource",this.el).click(this.callDocs.bind(this,"collapseOperationsForResource")),$(".expandResource",this.el).click(this.callDocs.bind(this,"expandOperationsForResource")),this},addOperation:function(e){e.number=this.number;var t=new SwaggerUi.Views.OperationView({model:e,router:this.router,tagName:"li",className:"endpoint",swaggerOptions:this.options.swaggerOptions,auths:this.auths});$(".endpoints",$(this.el)).append(t.render().el),this.number++},callDocs:function(e,t){t.preventDefault(),Docs[e](t.currentTarget.getAttribute("data-id"))}}),SwaggerUi.Views.ResponseContentTypeView=Backbone.View.extend({initialize:function(){},render:function(){return this.model.responseContentTypeId="rct"+Math.random(),$(this.el).html(Handlebars.templates.response_content_type(this.model)),this}}),SwaggerUi.Views.SignatureView=Backbone.View.extend({events:{"click a.description-link":"switchToDescription","click a.snippet-link":"switchToSnippet","mousedown .snippet_json":"jsonSnippetMouseDown","mousedown .snippet_xml":"xmlSnippetMouseDown"},initialize:function(){},render:function(){return $(this.el).html(Handlebars.templates.signature(this.model)),"model"===this.model.defaultRendering?this.switchToDescription():this.switchToSnippet(),this},switchToDescription:function(e){e&&e.preventDefault(),$(".snippet",$(this.el)).hide(),$(".description",$(this.el)).show(),$(".description-link",$(this.el)).addClass("selected"),$(".snippet-link",$(this.el)).removeClass("selected")},switchToSnippet:function(e){e&&e.preventDefault(),$(".snippet",$(this.el)).show(),$(".description",$(this.el)).hide(),$(".snippet-link",$(this.el)).addClass("selected"),$(".description-link",$(this.el)).removeClass("selected")},snippetToTextArea:function(e){var t=$("textarea",$(this.el.parentNode.parentNode.parentNode));""!==$.trim(t.val())&&t.prop("placeholder")!==t.val()||(t.val(e),this.model.jsonEditor&&this.model.jsonEditor.isEnabled()&&this.model.jsonEditor.setValue(JSON.parse(this.model.sampleJSON)))},jsonSnippetMouseDown:function(e){this.model.isParam&&(e&&e.preventDefault(),this.snippetToTextArea(this.model.sampleJSON))},xmlSnippetMouseDown:function(e){this.model.isParam&&(e&&e.preventDefault(),this.snippetToTextArea(this.model.sampleXML))}}),SwaggerUi.Views.StatusCodeView=Backbone.View.extend({initialize:function(e){this.options=e||{},this.router=this.options.router},render:function(){var e,t,n=this.router.api.models[this.model.responseModel];return $(this.el).html(Handlebars.templates.status_code(this.model)),e=this.router.api.models.hasOwnProperty(this.model.responseModel)?{sampleJSON:JSON.stringify(SwaggerUi.partials.signature.createJSONSample(n),void 0,2),sampleXML:!!this.model.isXML&&SwaggerUi.partials.signature.createXMLSample("",this.model.schema,this.router.api.models),isParam:!1,signature:SwaggerUi.partials.signature.getModelSignature(this.model.responseModel,n,this.router.api.models),defaultRendering:this.model.defaultRendering}:{signature:SwaggerUi.partials.signature.getPrimitiveSignature(this.model.schema)},t=new SwaggerUi.Views.SignatureView({model:e,tagName:"div"}),$(".model-signature",this.$el).append(t.render().el),this}})}).call(this); \ No newline at end of file
+(function(){function e(){e.history=e.history||[],e.history.push(arguments),this.console&&console.log(Array.prototype.slice.call(arguments)[0])}!function(){var e=Handlebars.template,t=Handlebars.templates=Handlebars.templates||{};t.apikey_auth=e({1:function(e,t,n,r,i){var a;return' <span class="key_auth__value">'+(null!=(a=(n.sanitize||t&&t.sanitize||n.helperMissing).call(null!=t?t:{},null!=t?t.value:t,{name:"sanitize",hash:{},data:i}))?a:"")+"</span>\n"},3:function(e,t,n,r,i){return' <input placeholder="api_key" class="auth_input input_apiKey_entry" name="apiKey" type="text"/>\n'},compiler:[7,">= 4.0.0"],main:function(e,t,n,r,i){var a,o=null!=t?t:{},s=n.helperMissing;return'<div class="key_input_container">\n <h3 class="auth__title">Api key authorization</h3>\n <div class="auth__description">'+(null!=(a=(n.sanitize||t&&t.sanitize||s).call(o,null!=t?t.description:t,{name:"sanitize",hash:{},data:i}))?a:"")+'</div>\n <div>\n <div class="key_auth__field">\n <span class="key_auth__label">name:</span>\n <span class="key_auth__value">'+(null!=(a=(n.escape||t&&t.escape||s).call(o,null!=t?t.name:t,{name:"escape",hash:{},data:i}))?a:"")+'</span>\n </div>\n <div class="key_auth__field">\n <span class="key_auth__label">in:</span>\n <span class="key_auth__value">'+(null!=(a=(n.escape||t&&t.escape||s).call(o,null!=t?t["in"]:t,{name:"escape",hash:{},data:i}))?a:"")+'</span>\n </div>\n <div class="key_auth__field">\n <span class="key_auth__label">value:</span>\n'+(null!=(a=n["if"].call(o,null!=t?t.isLogout:t,{name:"if",hash:{},fn:e.program(1,i,0),inverse:e.program(3,i,0),data:i}))?a:"")+" </div>\n </div>\n</div>\n"},useData:!0}),t.auth_button=e({compiler:[7,">= 4.0.0"],main:function(e,t,n,r,i){return"<a class='authorize__btn' href=\"#\">Authorize</a>\n"},useData:!0}),t.auth_button_operation=e({1:function(e,t,n,r,i){return" authorize__btn_operation_login\n"},3:function(e,t,n,r,i){return" authorize__btn_operation_logout\n"},5:function(e,t,n,r,i){var a;return' <ul class="authorize-scopes">\n'+(null!=(a=n.each.call(null!=t?t:{},null!=t?t.scopes:t,{name:"each",hash:{},fn:e.program(6,i,0),inverse:e.noop,data:i}))?a:"")+" </ul>\n"},6:function(e,t,n,r,i){var a,o=null!=t?t:{},s=n.helperMissing;return' <li class="authorize__scope" title="'+(null!=(a=(n.escape||t&&t.escape||s).call(o,null!=t?t.description:t,{name:"escape",hash:{},data:i}))?a:"")+'">'+(null!=(a=(n.escape||t&&t.escape||s).call(o,null!=t?t.scope:t,{name:"escape",hash:{},data:i}))?a:"")+"</li>\n"},compiler:[7,">= 4.0.0"],main:function(e,t,n,r,i){var a,o=null!=t?t:{};return'<div class="authorize__btn authorize__btn_operation\n'+(null!=(a=n["if"].call(o,null!=t?t.isLogout:t,{name:"if",hash:{},fn:e.program(1,i,0),inverse:e.program(3,i,0),data:i}))?a:"")+'">\n'+(null!=(a=n["if"].call(o,null!=t?t.scopes:t,{name:"if",hash:{},fn:e.program(5,i,0),inverse:e.noop,data:i}))?a:"")+"</div>\n"},useData:!0}),t.auth_view=e({1:function(e,t,n,r,i){return' <button type="button" class="auth__button auth_submit__button" data-sw-translate>Authorize</button>\n'},3:function(e,t,n,r,i){return' <button type="button" class="auth__button auth_logout__button" data-sw-translate>Logout</button>\n'},compiler:[7,">= 4.0.0"],main:function(e,t,n,r,i){var a,o=null!=t?t:{};return'<div class="auth_container">\n\n <div class="auth_inner"></div>\n <div class="auth_submit">\n'+(null!=(a=n.unless.call(o,null!=t?t.isLogout:t,{name:"unless",hash:{},fn:e.program(1,i,0),inverse:e.noop,data:i}))?a:"")+(null!=(a=n["if"].call(o,null!=t?t.isAuthorized:t,{name:"if",hash:{},fn:e.program(3,i,0),inverse:e.noop,data:i}))?a:"")+" </div>\n\n</div>\n"},useData:!0}),t.basic_auth=e({1:function(e,t,n,r,i){return" - authorized"},3:function(e,t,n,r,i){var a;return' <span class="basic_auth__value">'+(null!=(a=(n.escape||t&&t.escape||n.helperMissing).call(null!=t?t:{},null!=t?t.username:t,{name:"escape",hash:{},data:i}))?a:"")+"</span>\n"},5:function(e,t,n,r,i){return' <input required placeholder="username" class="basic_auth__username auth_input" name="username" type="text"/>\n'},7:function(e,t,n,r,i){return' <div class="auth_label">\n <span class="basic_auth__label" data-sw-translate>password:</span>\n <input required placeholder="password" class="basic_auth__password auth_input" name="password" type="password"/></label>\n </div>\n'},compiler:[7,">= 4.0.0"],main:function(e,t,n,r,i){var a,o=null!=t?t:{};return"<div class='basic_auth_container'>\n <h3 class=\"auth__title\">Basic authentication"+(null!=(a=n["if"].call(o,null!=t?t.isLogout:t,{name:"if",hash:{},fn:e.program(1,i,0),inverse:e.noop,data:i}))?a:"")+'</h3>\n <form class="basic_input_container">\n <div class="auth__description">'+(null!=(a=(n.sanitize||t&&t.sanitize||n.helperMissing).call(o,null!=t?t.description:t,{name:"sanitize",hash:{},data:i}))?a:"")+'</div>\n <div class="auth_label">\n <span class="basic_auth__label" data-sw-translate>username:</span>\n'+(null!=(a=n["if"].call(o,null!=t?t.isLogout:t,{name:"if",hash:{},fn:e.program(3,i,0),inverse:e.program(5,i,0),data:i}))?a:"")+" </div>\n"+(null!=(a=n.unless.call(o,null!=t?t.isLogout:t,{name:"unless",hash:{},fn:e.program(7,i,0),inverse:e.noop,data:i}))?a:"")+" </form>\n</div>\n"},useData:!0}),t.content_type=e({1:function(e,t,n,r,i){var a;return null!=(a=n.each.call(null!=t?t:{},null!=t?t.produces:t,{name:"each",hash:{},fn:e.program(2,i,0),inverse:e.noop,data:i}))?a:""},2:function(e,t,n,r,i){var a,o=null!=t?t:{},s=n.helperMissing;return'\t<option value="'+(null!=(a=(n.sanitize||t&&t.sanitize||s).call(o,t,{name:"sanitize",hash:{},data:i}))?a:"")+'">'+(null!=(a=(n.sanitize||t&&t.sanitize||s).call(o,t,{name:"sanitize",hash:{},data:i}))?a:"")+"</option>\n"},4:function(e,t,n,r,i){return' <option value="application/json">application/json</option>\n'},compiler:[7,">= 4.0.0"],main:function(e,t,n,r,i){var a,o=null!=t?t:{},s=n.helperMissing;return'<label data-sw-translate for="'+(null!=(a=(n.escape||t&&t.escape||s).call(o,null!=t?t.contentTypeId:t,{name:"escape",hash:{},data:i}))?a:"")+'">Response Content Type</label>\n<select name="contentType" id="'+(null!=(a=(n.escape||t&&t.escape||s).call(o,null!=t?t.contentTypeId:t,{name:"escape",hash:{},data:i}))?a:"")+'">\n'+(null!=(a=n["if"].call(o,null!=t?t.produces:t,{name:"if",hash:{},fn:e.program(1,i,0),inverse:e.program(4,i,0),data:i}))?a:"")+"</select>\n"},useData:!0}),t.main=e({1:function(e,t,n,r,i){var a,o=null!=t?t:{},s=n.helperMissing;return' <div class="info_title">'+(null!=(a=(n.sanitize||t&&t.sanitize||s).call(o,null!=(a=null!=t?t.info:t)?a.title:a,{name:"sanitize",hash:{},data:i}))?a:"")+'</div>\n <div class="info_description markdown">'+(null!=(a=(n.sanitize||t&&t.sanitize||s).call(o,null!=(a=null!=t?t.info:t)?a.description:a,{name:"sanitize",hash:{},data:i}))?a:"")+"</div>\n"+(null!=(a=n["if"].call(o,null!=t?t.externalDocs:t,{name:"if",hash:{},fn:e.program(2,i,0),inverse:e.noop,data:i}))?a:"")+" "+(null!=(a=n["if"].call(o,null!=(a=null!=t?t.info:t)?a.termsOfServiceUrl:a,{name:"if",hash:{},fn:e.program(4,i,0),inverse:e.noop,data:i}))?a:"")+"\n "+(null!=(a=n["if"].call(o,null!=(a=null!=(a=null!=t?t.info:t)?a.contact:a)?a.name:a,{name:"if",hash:{},fn:e.program(6,i,0),inverse:e.noop,data:i}))?a:"")+"\n "+(null!=(a=n["if"].call(o,null!=(a=null!=(a=null!=t?t.info:t)?a.contact:a)?a.url:a,{name:"if",hash:{},fn:e.program(8,i,0),inverse:e.noop,data:i}))?a:"")+"\n "+(null!=(a=n["if"].call(o,null!=(a=null!=(a=null!=t?t.info:t)?a.contact:a)?a.email:a,{name:"if",hash:{},fn:e.program(10,i,0),inverse:e.noop,data:i}))?a:"")+"\n "+(null!=(a=n["if"].call(o,null!=(a=null!=t?t.info:t)?a.license:a,{name:"if",hash:{},fn:e.program(12,i,0),inverse:e.noop,data:i}))?a:"")+"\n"},2:function(e,t,n,r,i){var a,o=null!=t?t:{},s=n.helperMissing;return" <p>"+(null!=(a=(n.sanitize||t&&t.sanitize||s).call(o,null!=(a=null!=t?t.externalDocs:t)?a.description:a,{name:"sanitize",hash:{},data:i}))?a:"")+'</p>\n <a href="'+(null!=(a=(n.escape||t&&t.escape||s).call(o,null!=(a=null!=t?t.externalDocs:t)?a.url:a,{name:"escape",hash:{},data:i}))?a:"")+'" target="_blank">'+(null!=(a=(n.escape||t&&t.escape||s).call(o,null!=(a=null!=t?t.externalDocs:t)?a.url:a,{name:"escape",hash:{},data:i}))?a:"")+"</a>\n"},4:function(e,t,n,r,i){var a;return'<div class="info_tos"><a target="_blank" href="'+(null!=(a=(n.escape||t&&t.escape||n.helperMissing).call(null!=t?t:{},null!=(a=null!=t?t.info:t)?a.termsOfServiceUrl:a,{name:"escape",hash:{},data:i}))?a:"")+'" data-sw-translate>Terms of service</a></div>'},6:function(e,t,n,r,i){var a;return"<div><div class='info_name' style=\"display: inline\" data-sw-translate>Created by </div> "+(null!=(a=(n.escape||t&&t.escape||n.helperMissing).call(null!=t?t:{},null!=(a=null!=(a=null!=t?t.info:t)?a.contact:a)?a.name:a,{name:"escape",hash:{},data:i}))?a:"")+"</div>"},8:function(e,t,n,r,i){var a,o=null!=t?t:{},s=n.helperMissing;return"<div class='info_url' data-sw-translate>See more at <a href=\""+(null!=(a=(n.escape||t&&t.escape||s).call(o,null!=(a=null!=(a=null!=t?t.info:t)?a.contact:a)?a.url:a,{name:"escape",hash:{},data:i}))?a:"")+'">'+(null!=(a=(n.escape||t&&t.escape||s).call(o,null!=(a=null!=(a=null!=t?t.info:t)?a.contact:a)?a.url:a,{name:"escape",hash:{},data:i}))?a:"")+"</a></div>"},10:function(e,t,n,r,i){var a,o=null!=t?t:{},s=n.helperMissing;return'<div class=\'info_email\'><a target="_parent" href="mailto:'+(null!=(a=(n.escape||t&&t.escape||s).call(o,null!=(a=null!=(a=null!=t?t.info:t)?a.contact:a)?a.email:a,{name:"escape",hash:{},data:i}))?a:"")+"?subject="+(null!=(a=(n.escape||t&&t.escape||s).call(o,null!=(a=null!=t?t.info:t)?a.title:a,{name:"escape",hash:{},data:i}))?a:"")+'" data-sw-translate>Contact the developer</a></div>'},12:function(e,t,n,r,i){var a,o=null!=t?t:{},s=n.helperMissing;return"<div class='info_license'><a target=\"_blank\" href='"+(null!=(a=(n.escape||t&&t.escape||s).call(o,null!=(a=null!=(a=null!=t?t.info:t)?a.license:a)?a.url:a,{name:"escape",hash:{},data:i}))?a:"")+"'>"+(null!=(a=(n.escape||t&&t.escape||s).call(o,null!=(a=null!=(a=null!=t?t.info:t)?a.license:a)?a.name:a,{name:"escape",hash:{},data:i}))?a:"")+"</a></div>"},14:function(e,t,n,r,i){var a;return' , <span style="font-variant: small-caps" data-sw-translate>api version</span>: '+(null!=(a=(n.escape||t&&t.escape||n.helperMissing).call(null!=t?t:{},null!=(a=null!=t?t.info:t)?a.version:a,{name:"escape",hash:{},data:i}))?a:"")+"\n "},16:function(e,t,n,r,i){var a,o=null!=t?t:{},s=n.helperMissing;return' <span style="float:right"><a target="_blank" href="'+(null!=(a=(n.escape||t&&t.escape||s).call(o,null!=t?t.validatorUrl:t,{name:"escape",hash:{},data:i}))?a:"")+"/debug?url="+(null!=(a=(n.escape||t&&t.escape||s).call(o,null!=t?t.url:t,{name:"escape",hash:{},data:i}))?a:"")+'"><img id="validator" src="'+(null!=(a=(n.escape||t&&t.escape||s).call(o,null!=t?t.validatorUrl:t,{name:"escape",hash:{},data:i}))?a:"")+"?url="+(null!=(a=(n.escape||t&&t.escape||s).call(o,null!=t?t.url:t,{name:"escape",hash:{},data:i}))?a:"")+'"></a>\n </span>\n'},compiler:[7,">= 4.0.0"],main:function(e,t,n,r,i){var a,o=null!=t?t:{};return"<div class='info' id='api_info'>\n"+(null!=(a=n["if"].call(o,null!=t?t.info:t,{name:"if",hash:{},fn:e.program(1,i,0),inverse:e.noop,data:i}))?a:"")+"</div>\n<div class='container' id='resources_container'>\n <div class='authorize-wrapper'></div>\n\n <ul id='resources'></ul>\n\n <div class=\"footer\">\n <h4 style=\"color: #999\">[ <span style=\"font-variant: small-caps\">base url</span>: "+(null!=(a=(n.escape||t&&t.escape||n.helperMissing).call(o,null!=t?t.basePath:t,{name:"escape",hash:{},data:i}))?a:"")+"\n"+(null!=(a=n["if"].call(o,null!=(a=null!=t?t.info:t)?a.version:a,{name:"if",hash:{},fn:e.program(14,i,0),inverse:e.noop,data:i}))?a:"")+"]\n"+(null!=(a=n["if"].call(o,null!=t?t.validatorUrl:t,{name:"if",hash:{},fn:e.program(16,i,0),inverse:e.noop,data:i}))?a:"")+" </h4>\n </div>\n</div>\n"},useData:!0}),t.oauth2=e({1:function(e,t,n,r,i){var a,o=null!=t?t:{},s=n.helperMissing;return' <li>\n <input class="oauth-scope" type="checkbox" data-scope="'+(null!=(a=(n.escape||t&&t.escape||s).call(o,null!=t?t.scope:t,{name:"escape",hash:{},data:i}))?a:"")+'" oauthtype="'+(null!=(a=(n.escape||t&&t.escape||s).call(o,null!=t?t.OAuthSchemeKey:t,{name:"escape",hash:{},data:i}))?a:"")+'"/>\n <label>'+(null!=(a=(n.escape||t&&t.escape||s).call(o,null!=t?t.scope:t,{name:"escape",hash:{},data:i}))?a:"")+'</label><br/>\n <span class="api-scope-desc">'+(null!=(a=(n.escape||t&&t.escape||s).call(o,null!=t?t.description:t,{name:"escape",hash:{},data:i}))?a:"")+"\n"+(null!=(a=n["if"].call(o,null!=t?t.OAuthSchemeKey:t,{name:"if",hash:{},fn:e.program(2,i,0),inverse:e.noop,data:i}))?a:"")+" </span>\n </li>\n"},2:function(e,t,n,r,i){var a;return" ("+(null!=(a=(n.escape||t&&t.escape||n.helperMissing).call(null!=t?t:{},null!=t?t.OAuthSchemeKey:t,{name:"escape",hash:{},data:i}))?a:"")+")\n"},compiler:[7,">= 4.0.0"],main:function(e,t,n,r,i){var a,o=null!=t?t:{},s=n.helperMissing;return'<div>\n <h3 class="auth__title">Select OAuth2.0 Scopes</h3>\n <p>'+(null!=(a=(n.sanitize||t&&t.sanitize||s).call(o,null!=t?t.description:t,{name:"sanitize",hash:{},data:i}))?a:"")+'</p>\n <p>Scopes are used to grant an application different levels of access to data on behalf of the end user. Each API may declare one or more scopes.\n <a href="#">Learn how to use</a>\n </p>\n <p><strong> '+(null!=(a=(n.escape||t&&t.escape||s).call(o,null!=t?t.appName:t,{name:"escape",hash:{},data:i}))?a:"")+" </strong> API requires the following scopes. Select which ones you want to grant to Swagger UI.</p>\n <p>Authorization URL: "+(null!=(a=(n.sanitize||t&&t.sanitize||s).call(o,null!=t?t.authorizationUrl:t,{name:"sanitize",hash:{},data:i}))?a:"")+"</p>\n <p>flow: "+(null!=(a=(n.escape||t&&t.escape||s).call(o,null!=t?t.flow:t,{name:"escape",hash:{},data:i}))?a:"")+'</p>\n <ul class="api-popup-scopes">\n'+(null!=(a=n.each.call(o,null!=t?t.scopes:t,{name:"each",hash:{},fn:e.program(1,i,0),inverse:e.noop,data:i}))?a:"")+" </ul>\n</div>"},useData:!0}),t.operation=e({1:function(e,t,n,r,i){return"deprecated"},3:function(e,t,n,r,i){return" <h4><span data-sw-translate>Warning: Deprecated</span></h4>\n"},5:function(e,t,n,r,i){var a;return' <h4><span data-sw-translate>Implementation Notes</span></h4>\n <div class="markdown">'+(null!=(a=(n.sanitize||t&&t.sanitize||n.helperMissing).call(null!=t?t:{},null!=t?t.description:t,{name:"sanitize",hash:{},data:i}))?a:"")+"</div>\n"},7:function(e,t,n,r,i){return" <div class='authorize-wrapper authorize-wrapper_operation'></div>\n"},9:function(e,t,n,r,i){var a,o=null!=t?t:{};return' <div class="response-class">\n <h4><span data-sw-translate>Response Class</span> (<span data-sw-translate>Status</span> '+(null!=(a=(n.escape||t&&t.escape||n.helperMissing).call(o,null!=t?t.successCode:t,{name:"escape",hash:{},data:i}))?a:"")+")</h4>\n "+(null!=(a=n["if"].call(o,null!=t?t.successDescription:t,{name:"if",hash:{},fn:e.program(10,i,0),inverse:e.noop,data:i}))?a:"")+'\n <p><span class="model-signature" /></p>\n <br/>\n <div class="response-content-type" />\n </div>\n'},10:function(e,t,n,r,i){var a;return'<div class="markdown">'+(null!=(a=(n.sanitize||t&&t.sanitize||n.helperMissing).call(null!=t?t:{},null!=t?t.successDescription:t,{name:"sanitize",hash:{},data:i}))?a:"")+"</div>"},12:function(e,t,n,r,i){var a;return' <h4 data-sw-translate>Headers</h4>\n <table class="headers">\n <thead>\n <tr>\n <th style="width: 100px; max-width: 100px" data-sw-translate>Header</th>\n <th style="width: 310px; max-width: 310px" data-sw-translate>Description</th>\n <th style="width: 200px; max-width: 200px" data-sw-translate>Type</th>\n <th style="width: 320px; max-width: 320px" data-sw-translate>Other</th>\n </tr>\n </thead>\n <tbody>\n'+(null!=(a=n.each.call(null!=t?t:{},null!=t?t.headers:t,{name:"each",hash:{},fn:e.program(13,i,0),inverse:e.noop,data:i}))?a:"")+" </tbody>\n </table>\n"},13:function(e,t,n,r,i){var a,o,s=null!=t?t:{},l=n.helperMissing;return" <tr>\n <td>"+e.escapeExpression((o=null!=(o=n.key||i&&i.key)?o:l,"function"==typeof o?o.call(s,{name:"key",hash:{},data:i}):o))+"</td>\n <td>"+(null!=(a=(n.sanitize||t&&t.sanitize||l).call(s,null!=t?t.description:t,{name:"sanitize",hash:{},data:i}))?a:"")+"</td>\n <td>"+(null!=(a=(n.escape||t&&t.escape||l).call(s,null!=t?t.type:t,{name:"escape",hash:{},data:i}))?a:"")+"</td>\n <td>"+(null!=(a=(n.escape||t&&t.escape||l).call(s,null!=t?t.other:t,{name:"escape",hash:{},data:i}))?a:"")+"</td>\n </tr>\n"},15:function(e,t,n,r,i){return' <h4 data-sw-translate>Parameters</h4>\n <table class=\'fullwidth parameters\'>\n <thead>\n <tr>\n <th style="width: 100px; max-width: 100px" data-sw-translate>Parameter</th>\n <th style="width: 310px; max-width: 310px" data-sw-translate>Value</th>\n <th style="width: 200px; max-width: 200px" data-sw-translate>Description</th>\n <th style="width: 100px; max-width: 100px" data-sw-translate>Parameter Type</th>\n <th style="width: 220px; max-width: 230px" data-sw-translate>Data Type</th>\n </tr>\n </thead>\n <tbody class="operation-params">\n\n </tbody>\n </table>\n'},17:function(e,t,n,r,i){return" <div style='margin:0;padding:0;display:inline'></div>\n <h4 data-sw-translate>Response Messages</h4>\n <table class='fullwidth response-messages'>\n <thead>\n <tr>\n <th data-sw-translate>HTTP Status Code</th>\n <th data-sw-translate>Reason</th>\n <th data-sw-translate>Response Model</th>\n <th data-sw-translate>Headers</th>\n </tr>\n </thead>\n <tbody class=\"operation-status\">\n </tbody>\n </table>\n"},19:function(e,t,n,r,i){return""},21:function(e,t,n,r,i){return" <div class='sandbox_header'>\n <input class='submit' type='submit' value='Try it out!' data-sw-translate/>\n <a href='#' class='response_hider' style='display:none' data-sw-translate>Hide Response</a>\n <span class='response_throbber' style='display:none'></span>\n </div>\n"},23:function(e,t,n,r,i){return" <h4 data-sw-translate>Request Headers</h4>\n <div class='block request_headers'></div>\n"},compiler:[7,">= 4.0.0"],main:function(e,t,n,r,i){var a,o=null!=t?t:{},s=n.helperMissing,l=e.escapeExpression;return" <ul class='operations' >\n <li class='"+(null!=(a=(n.escape||t&&t.escape||s).call(o,null!=t?t.method:t,{name:"escape",hash:{},data:i}))?a:"")+" operation' id='"+(null!=(a=(n.escape||t&&t.escape||s).call(o,null!=t?t.parentId:t,{name:"escape",hash:{},data:i}))?a:"")+"_"+(null!=(a=(n.escape||t&&t.escape||s).call(o,null!=t?t.nickname:t,{name:"escape",hash:{},data:i}))?a:"")+"'>\n <div class='heading'>\n <h3>\n <span class='http_method'>\n <a href='#!/"+l((n.sanitize||t&&t.sanitize||s).call(o,null!=t?t.encodedParentId:t,{name:"sanitize",hash:{},data:i}))+"/"+l((n.sanitize||t&&t.sanitize||s).call(o,null!=t?t.nickname:t,{name:"sanitize",hash:{},data:i}))+'\' class="toggleOperation">'+(null!=(a=(n.escape||t&&t.escape||s).call(o,null!=t?t.method:t,{name:"escape",hash:{},data:i}))?a:"")+"</a>\n </span>\n <span class='path'>\n <a href='#!/"+l((n.sanitize||t&&t.sanitize||s).call(o,null!=t?t.encodedParentId:t,{name:"sanitize",hash:{},data:i}))+"/"+l((n.sanitize||t&&t.sanitize||s).call(o,null!=t?t.nickname:t,{name:"sanitize",hash:{},data:i}))+"' class=\"toggleOperation "+(null!=(a=n["if"].call(o,null!=t?t.deprecated:t,{name:"if",hash:{},fn:e.program(1,i,0),inverse:e.noop,data:i}))?a:"")+'">'+(null!=(a=(n.escape||t&&t.escape||s).call(o,null!=t?t.path:t,{name:"escape",hash:{},data:i}))?a:"")+"</a>\n </span>\n </h3>\n <ul class='options'>\n <li>\n <a href='#!/"+l((n.sanitize||t&&t.sanitize||s).call(o,null!=t?t.encodedParentId:t,{name:"sanitize",hash:{},data:i}))+"/"+l((n.sanitize||t&&t.sanitize||s).call(o,null!=t?t.nickname:t,{name:"sanitize",hash:{},data:i}))+'\' class="toggleOperation"><span class="markdown">'+(null!=(a=(n.escape||t&&t.escape||s).call(o,null!=t?t.summary:t,{name:"escape",hash:{},data:i}))?a:"")+"</span></a>\n </li>\n </ul>\n </div>\n <div class='content' id='"+l((n.sanitize||t&&t.sanitize||s).call(o,null!=t?t.encodedParentId:t,{name:"sanitize",hash:{},data:i}))+"_"+l((n.sanitize||t&&t.sanitize||s).call(o,null!=t?t.nickname:t,{name:"sanitize",hash:{},data:i}))+"_content' style='display:none'>\n"+(null!=(a=n["if"].call(o,null!=t?t.deprecated:t,{name:"if",hash:{},fn:e.program(3,i,0),inverse:e.noop,data:i}))?a:"")+(null!=(a=n["if"].call(o,null!=t?t.description:t,{name:"if",hash:{},fn:e.program(5,i,0),inverse:e.noop,data:i}))?a:"")+(null!=(a=n["if"].call(o,null!=t?t.security:t,{name:"if",hash:{},fn:e.program(7,i,0),inverse:e.noop,data:i}))?a:"")+(null!=(a=n["if"].call(o,null!=t?t.type:t,{name:"if",hash:{},fn:e.program(9,i,0),inverse:e.noop,data:i}))?a:"")+"\n"+(null!=(a=n["if"].call(o,null!=t?t.headers:t,{name:"if",hash:{},fn:e.program(12,i,0),inverse:e.noop,data:i}))?a:"")+"\n <form accept-charset='UTF-8' class='sandbox'>\n <div style='margin:0;padding:0;display:inline'></div>\n"+(null!=(a=n["if"].call(o,null!=t?t.parameters:t,{name:"if",hash:{},fn:e.program(15,i,0),inverse:e.noop,data:i}))?a:"")+(null!=(a=n["if"].call(o,null!=t?t.responseMessages:t,{name:"if",hash:{},fn:e.program(17,i,0),inverse:e.noop,data:i}))?a:"")+(null!=(a=n["if"].call(o,null!=t?t.isReadOnly:t,{name:"if",hash:{},fn:e.program(19,i,0),inverse:e.program(21,i,0),data:i}))?a:"")+" </form>\n <div class='response' style='display:none'>\n <h4 class='curl'>Curl</h4>\n <div class='block curl'></div>\n <h4 data-sw-translate>Request URL</h4>\n <div class='block request_url'></div>\n"+(null!=(a=n["if"].call(o,null!=t?t.showRequestHeaders:t,{name:"if",hash:{},fn:e.program(23,i,0),inverse:e.noop,data:i}))?a:"")+" <h4 data-sw-translate>Response Body</h4>\n <div class='block response_body'></div>\n <h4 data-sw-translate>Response Code</h4>\n <div class='block response_code'></div>\n <h4 data-sw-translate>Response Headers</h4>\n <div class='block response_headers'></div>\n </div>\n </div>\n </li>\n </ul>\n"},useData:!0}),t.param=e({1:function(e,t,n,r,i){var a;return null!=(a=n["if"].call(null!=t?t:{},null!=t?t.isFile:t,{name:"if",hash:{},fn:e.program(2,i,0),inverse:e.program(4,i,0),data:i}))?a:""},2:function(e,t,n,r,i){var a,o=null!=t?t:{},s=n.helperMissing;return'\t\t\t<input type="file" name=\''+(null!=(a=(n.escape||t&&t.escape||s).call(o,null!=t?t.name:t,{name:"escape",hash:{},data:i}))?a:"")+"' id='"+(null!=(a=(n.escape||t&&t.escape||s).call(o,null!=t?t.valueId:t,{name:"escape",hash:{},data:i}))?a:"")+'\'/>\n\t\t\t<div class="parameter-content-type" />\n'},4:function(e,t,n,r,i){var a;return null!=(a=n["if"].call(null!=t?t:{},null!=t?t["default"]:t,{name:"if",hash:{},fn:e.program(5,i,0),inverse:e.program(7,i,0),data:i}))?a:""},5:function(e,t,n,r,i){var a,o=null!=t?t:{},s=n.helperMissing;return"\t\t\t\t<div class=\"editor_holder\"></div>\n\t\t\t\t<textarea class='body-textarea' name='"+(null!=(a=(n.escape||t&&t.escape||s).call(o,null!=t?t.name:t,{name:"escape",hash:{},data:i}))?a:"")+"' id='"+(null!=(a=(n.escape||t&&t.escape||s).call(o,null!=t?t.valueId:t,{name:"escape",hash:{},data:i}))?a:"")+"'>"+(null!=(a=(n.escape||t&&t.escape||s).call(o,null!=t?t["default"]:t,{name:"escape",hash:{},data:i}))?a:"")+'</textarea>\n <br />\n <div class="parameter-content-type" />\n'},7:function(e,t,n,r,i){var a,o=null!=t?t:{},s=n.helperMissing;return"\t\t\t\t<textarea class='body-textarea' name='"+(null!=(a=(n.escape||t&&t.escape||s).call(o,null!=t?t.name:t,{name:"escape",hash:{},data:i}))?a:"")+"' id='"+(null!=(a=(n.escape||t&&t.escape||s).call(o,null!=t?t.valueId:t,{name:"escape",hash:{},data:i}))?a:"")+'\'></textarea>\n\t\t\t\t<div class="editor_holder"></div>\n\t\t\t\t<br />\n\t\t\t\t<div class="parameter-content-type" />\n'},9:function(e,t,n,r,i){var a;return null!=(a=n["if"].call(null!=t?t:{},null!=t?t.isFile:t,{name:"if",hash:{},fn:e.program(2,i,0),inverse:e.program(10,i,0),data:i}))?a:""},10:function(e,t,n,r,i){var a;return null!=(a=(n.renderTextParam||t&&t.renderTextParam||n.helperMissing).call(null!=t?t:{},t,{name:"renderTextParam",hash:{},fn:e.program(11,i,0),inverse:e.noop,data:i}))?a:""},11:function(e,t,n,r,i){return""},compiler:[7,">= 4.0.0"],main:function(e,t,n,r,i){var a,o=null!=t?t:{},s=n.helperMissing;return"<td class='code'><label for='"+(null!=(a=(n.escape||t&&t.escape||s).call(o,null!=t?t.valueId:t,{name:"escape",hash:{},data:i}))?a:"")+"'>"+(null!=(a=(n.escape||t&&t.escape||s).call(o,null!=t?t.name:t,{name:"escape",hash:{},data:i}))?a:"")+"</label></td>\n<td>\n\n"+(null!=(a=n["if"].call(o,null!=t?t.isBody:t,{name:"if",hash:{},fn:e.program(1,i,0),inverse:e.program(9,i,0),data:i}))?a:"")+'\n</td>\n<td class="markdown">'+(null!=(a=(n.sanitize||t&&t.sanitize||s).call(o,null!=t?t.description:t,{name:"sanitize",hash:{},data:i}))?a:"")+"</td>\n<td>"+(null!=(a=(n.escape||t&&t.escape||s).call(o,null!=t?t.paramType:t,{name:"escape",hash:{},data:i}))?a:"")+'</td>\n<td>\n\t<span class="model-signature"></span>\n</td>\n'},useData:!0}),t.param_list=e({1:function(e,t,n,r,i){return" required"},3:function(e,t,n,r,i){return' multiple="multiple"'},5:function(e,t,n,r,i){return" required "},7:function(e,t,n,r,i){var a;return" <option "+(null!=(a=n.unless.call(null!=t?t:{},null!=t?t.hasDefault:t,{name:"unless",hash:{},fn:e.program(8,i,0),inverse:e.noop,data:i}))?a:"")+" value=''></option>\n"},8:function(e,t,n,r,i){return' selected="" '},10:function(e,t,n,r,i){var a,o=null!=t?t:{},s=n.helperMissing;return"\n <option "+(null!=(a=n["if"].call(o,null!=t?t.isDefault:t,{name:"if",hash:{},fn:e.program(11,i,0),inverse:e.noop,data:i}))?a:"")+" value='"+(null!=(a=(n.sanitize||t&&t.sanitize||s).call(o,null!=t?t.value:t,{name:"sanitize",hash:{},data:i}))?a:"")+"'> "+(null!=(a=(n.sanitize||t&&t.sanitize||s).call(o,null!=t?t.value:t,{name:"sanitize",hash:{},data:i}))?a:"")+" "+(null!=(a=n["if"].call(o,null!=t?t.isDefault:t,{name:"if",hash:{},fn:e.program(13,i,0),inverse:e.noop,data:i}))?a:"")+" </option>\n\n"},11:function(e,t,n,r,i){return' selected="" '},13:function(e,t,n,r,i){return" (default) "},15:function(e,t,n,r,i){return"<strong>"},17:function(e,t,n,r,i){return"</strong>"},compiler:[7,">= 4.0.0"],main:function(e,t,n,r,i){var a,o,s=null!=t?t:{},l=n.helperMissing;return"<td class='code"+(null!=(a=n["if"].call(s,null!=t?t.required:t,{name:"if",hash:{},fn:e.program(1,i,0),inverse:e.noop,data:i}))?a:"")+"'><label for='"+(null!=(a=(n.escape||t&&t.escape||l).call(s,null!=t?t.valueId:t,{name:"escape",hash:{},data:i}))?a:"")+"'>"+(null!=(a=(n.sanitize||t&&t.sanitize||l).call(s,null!=t?t.name:t,{name:"sanitize",hash:{},data:i}))?a:"")+"</label></td>\n<td>\n <select "+(null!=(a=(n.isArray||t&&t.isArray||l).call(s,t,{name:"isArray",hash:{},fn:e.program(3,i,0),inverse:e.noop,data:i}))?a:"")+' class="parameter '+(null!=(a=n["if"].call(s,null!=t?t.required:t,{name:"if",hash:{},fn:e.program(5,i,0),inverse:e.noop,data:i}))?a:"")+'" name="'+(null!=(a=(n.sanitize||t&&t.sanitize||l).call(s,null!=t?t.name:t,{name:"sanitize",hash:{},data:i}))?a:"")+'" id="'+(null!=(a=(n.escape||t&&t.escape||l).call(s,null!=t?t.valueId:t,{name:"escape",hash:{},data:i}))?a:"")+'">\n\n'+(null!=(a=n.unless.call(s,null!=t?t.required:t,{name:"unless",hash:{},fn:e.program(7,i,0),inverse:e.noop,data:i}))?a:"")+"\n"+(null!=(a=n.each.call(s,null!=(a=null!=t?t.allowableValues:t)?a.descriptiveValues:a,{name:"each",hash:{},fn:e.program(10,i,0),inverse:e.noop,data:i}))?a:"")+'\n </select>\n</td>\n<td class="markdown">'+(null!=(a=n["if"].call(s,null!=t?t.required:t,{name:"if",hash:{},fn:e.program(15,i,0),inverse:e.noop,data:i}))?a:"")+(null!=(o=null!=(o=n.description||(null!=t?t.description:t))?o:l,a="function"==typeof o?o.call(s,{name:"description",hash:{},data:i}):o)?a:"")+(null!=(a=n["if"].call(s,null!=t?t.required:t,{name:"if",hash:{},fn:e.program(17,i,0),inverse:e.noop,data:i}))?a:"")+"</td>\n<td>"+(null!=(a=(n.escape||t&&t.escape||l).call(s,null!=t?t.paramType:t,{name:"escape",hash:{},data:i}))?a:"")+'</td>\n<td><span class="model-signature"></span></td>\n'},useData:!0}),t.param_readonly=e({1:function(e,t,n,r,i){var a,o=null!=t?t:{},s=n.helperMissing;return" <textarea class='body-textarea' readonly='readonly' name='"+(null!=(a=(n.sanitize||t&&t.sanitize||s).call(o,null!=t?t.name:t,{name:"sanitize",hash:{},data:i}))?a:"")+"' id='"+(null!=(a=(n.escape||t&&t.escape||s).call(o,null!=t?t.valueId:t,{name:"escape",hash:{},data:i}))?a:"")+"'>"+(null!=(a=(n.sanitize||t&&t.sanitize||s).call(o,null!=t?t["default"]:t,{name:"sanitize",hash:{},data:i}))?a:"")+'</textarea>\n <div class="parameter-content-type" />\n'},3:function(e,t,n,r,i){var a;return null!=(a=n["if"].call(null!=t?t:{},null!=t?t["default"]:t,{name:"if",hash:{},fn:e.program(4,i,0),inverse:e.program(6,i,0),data:i}))?a:""},4:function(e,t,n,r,i){var a;return" "+(null!=(a=(n.sanitize||t&&t.sanitize||n.helperMissing).call(null!=t?t:{},null!=t?t["default"]:t,{name:"sanitize",hash:{},data:i}))?a:"")+"\n"},6:function(e,t,n,r,i){return" (empty)\n"},compiler:[7,">= 4.0.0"],main:function(e,t,n,r,i){var a,o=null!=t?t:{},s=n.helperMissing;return"<td class='code'><label for='"+(null!=(a=(n.escape||t&&t.escape||s).call(o,null!=t?t.valueId:t,{name:"escape",hash:{},data:i}))?a:"")+"'>"+(null!=(a=(n.sanitize||t&&t.sanitize||s).call(o,null!=t?t.name:t,{name:"sanitize",hash:{},data:i}))?a:"")+"</label></td>\n<td>\n"+(null!=(a=n["if"].call(o,null!=t?t.isBody:t,{name:"if",hash:{},fn:e.program(1,i,0),inverse:e.program(3,i,0),data:i}))?a:"")+'</td>\n<td class="markdown">'+(null!=(a=(n.sanitize||t&&t.sanitize||s).call(o,null!=t?t.description:t,{name:"sanitize",hash:{},data:i}))?a:"")+"</td>\n<td>"+(null!=(a=(n.escape||t&&t.escape||s).call(o,null!=t?t.paramType:t,{name:"escape",hash:{},data:i}))?a:"")+'</td>\n<td><span class="model-signature"></span></td>\n'},useData:!0}),t.param_readonly_required=e({1:function(e,t,n,r,i){var a,o=null!=t?t:{},s=n.helperMissing;return" <textarea class='body-textarea' readonly='readonly' placeholder='(required)' name='"+(null!=(a=(n.sanitize||t&&t.sanitize||s).call(o,null!=t?t.name:t,{name:"sanitize",hash:{},data:i}))?a:"")+"' id='"+(null!=(a=(n.escape||t&&t.escape||s).call(o,null!=t?t.valueId:t,{name:"escape",hash:{},data:i}))?a:"")+"'>"+(null!=(a=(n.sanitize||t&&t.sanitize||s).call(o,null!=t?t["default"]:t,{name:"sanitize",hash:{},data:i}))?a:"")+"</textarea>\n"},3:function(e,t,n,r,i){var a;return null!=(a=n["if"].call(null!=t?t:{},null!=t?t["default"]:t,{name:"if",hash:{},fn:e.program(4,i,0),inverse:e.program(6,i,0),data:i}))?a:""},4:function(e,t,n,r,i){var a;return" "+(null!=(a=(n.sanitize||t&&t.sanitize||n.helperMissing).call(null!=t?t:{},null!=t?t["default"]:t,{name:"sanitize",hash:{},data:i}))?a:"")+"\n"},6:function(e,t,n,r,i){
+return" (empty)\n"},compiler:[7,">= 4.0.0"],main:function(e,t,n,r,i){var a,o=null!=t?t:{},s=n.helperMissing;return"<td class='code required'><label for='"+(null!=(a=(n.escape||t&&t.escape||s).call(o,null!=t?t.valueId:t,{name:"escape",hash:{},data:i}))?a:"")+"'>"+(null!=(a=(n.sanitize||t&&t.sanitize||s).call(o,null!=t?t.name:t,{name:"sanitize",hash:{},data:i}))?a:"")+"</label></td>\n<td>\n"+(null!=(a=n["if"].call(o,null!=t?t.isBody:t,{name:"if",hash:{},fn:e.program(1,i,0),inverse:e.program(3,i,0),data:i}))?a:"")+'</td>\n<td class="markdown">'+(null!=(a=(n.sanitize||t&&t.sanitize||s).call(o,null!=t?t.description:t,{name:"sanitize",hash:{},data:i}))?a:"")+"</td>\n<td>"+(null!=(a=(n.escape||t&&t.escape||s).call(o,null!=t?t.paramType:t,{name:"escape",hash:{},data:i}))?a:"")+'</td>\n<td><span class="model-signature"></span></td>\n'},useData:!0}),t.param_required=e({1:function(e,t,n,r,i){var a;return null!=(a=n["if"].call(null!=t?t:{},null!=t?t.isFile:t,{name:"if",hash:{},fn:e.program(2,i,0),inverse:e.program(4,i,0),data:i}))?a:""},2:function(e,t,n,r,i){var a,o=null!=t?t:{},s=n.helperMissing;return'\t\t\t<input type="file" name=\''+(null!=(a=(n.escape||t&&t.escape||s).call(o,null!=t?t.name:t,{name:"escape",hash:{},data:i}))?a:"")+"' id='"+(null!=(a=(n.escape||t&&t.escape||s).call(o,null!=t?t.valueId:t,{name:"escape",hash:{},data:i}))?a:"")+"'/>\n"},4:function(e,t,n,r,i){var a;return null!=(a=n["if"].call(null!=t?t:{},null!=t?t["default"]:t,{name:"if",hash:{},fn:e.program(5,i,0),inverse:e.program(7,i,0),data:i}))?a:""},5:function(e,t,n,r,i){var a,o=null!=t?t:{},s=n.helperMissing;return"\t\t\t\t<div class=\"editor_holder\"></div>\n\t\t\t\t<textarea class='body-textarea required' placeholder='(required)' name='"+(null!=(a=(n.sanitize||t&&t.sanitize||s).call(o,null!=t?t.name:t,{name:"sanitize",hash:{},data:i}))?a:"")+"' id=\""+(null!=(a=(n.escape||t&&t.escape||s).call(o,null!=t?t.valueId:t,{name:"escape",hash:{},data:i}))?a:"")+'">'+(null!=(a=(n.sanitize||t&&t.sanitize||s).call(o,null!=t?t["default"]:t,{name:"sanitize",hash:{},data:i}))?a:"")+'</textarea>\n <br />\n <div class="parameter-content-type" />\n'},7:function(e,t,n,r,i){var a,o=null!=t?t:{},s=n.helperMissing;return"\t\t\t\t<textarea class='body-textarea required' placeholder='(required)' name='"+(null!=(a=(n.sanitize||t&&t.sanitize||s).call(o,null!=t?t.name:t,{name:"sanitize",hash:{},data:i}))?a:"")+"' id='"+(null!=(a=(n.escape||t&&t.escape||s).call(o,null!=t?t.valueId:t,{name:"escape",hash:{},data:i}))?a:"")+'\'></textarea>\n\t\t\t\t<div class="editor_holder"></div>\n\t\t\t\t<br />\n\t\t\t\t<div class="parameter-content-type" />\n'},9:function(e,t,n,r,i){var a;return null!=(a=n["if"].call(null!=t?t:{},null!=t?t.isFile:t,{name:"if",hash:{},fn:e.program(10,i,0),inverse:e.program(12,i,0),data:i}))?a:""},10:function(e,t,n,r,i){var a,o=null!=t?t:{},s=n.helperMissing;return"\t\t\t<input class='parameter' class='required' type='file' name='"+(null!=(a=(n.sanitize||t&&t.sanitize||s).call(o,null!=t?t.name:t,{name:"sanitize",hash:{},data:i}))?a:"")+"' id='"+(null!=(a=(n.escape||t&&t.escape||s).call(o,null!=t?t.valueId:t,{name:"escape",hash:{},data:i}))?a:"")+"'/>\n"},12:function(e,t,n,r,i){var a;return null!=(a=(n.renderTextParam||t&&t.renderTextParam||n.helperMissing).call(null!=t?t:{},t,{name:"renderTextParam",hash:{},fn:e.program(13,i,0),inverse:e.noop,data:i}))?a:""},13:function(e,t,n,r,i){return""},compiler:[7,">= 4.0.0"],main:function(e,t,n,r,i){var a,o=null!=t?t:{},s=n.helperMissing;return"<td class='code required'><label for='"+(null!=(a=(n.escape||t&&t.escape||s).call(o,null!=t?t.valueId:t,{name:"escape",hash:{},data:i}))?a:"")+"'>"+(null!=(a=(n.escape||t&&t.escape||s).call(o,null!=t?t.name:t,{name:"escape",hash:{},data:i}))?a:"")+"</label></td>\n<td>\n"+(null!=(a=n["if"].call(o,null!=t?t.isBody:t,{name:"if",hash:{},fn:e.program(1,i,0),inverse:e.program(9,i,0),data:i}))?a:"")+'</td>\n<td>\n\t<strong><span class="markdown">'+(null!=(a=(n.sanitize||t&&t.sanitize||s).call(o,null!=t?t.description:t,{name:"sanitize",hash:{},data:i}))?a:"")+"</span></strong>\n</td>\n<td>"+(null!=(a=(n.escape||t&&t.escape||s).call(o,null!=t?t.paramType:t,{name:"escape",hash:{},data:i}))?a:"")+'</td>\n<td><span class="model-signature"></span></td>\n'},useData:!0}),t.parameter_content_type=e({1:function(e,t,n,r,i){var a;return null!=(a=n.each.call(null!=t?t:{},null!=t?t.consumes:t,{name:"each",hash:{},fn:e.program(2,i,0),inverse:e.noop,data:i}))?a:""},2:function(e,t,n,r,i){var a,o=null!=t?t:{},s=n.helperMissing;return' <option value="'+(null!=(a=(n.sanitize||t&&t.sanitize||s).call(o,t,{name:"sanitize",hash:{},data:i}))?a:"")+'">'+(null!=(a=(n.sanitize||t&&t.sanitize||s).call(o,t,{name:"sanitize",hash:{},data:i}))?a:"")+"</option>\n"},4:function(e,t,n,r,i){return' <option value="application/json">application/json</option>\n'},compiler:[7,">= 4.0.0"],main:function(e,t,n,r,i){var a,o,s=null!=t?t:{},l=n.helperMissing;return'<label for="'+e.escapeExpression((o=null!=(o=n.parameterContentTypeId||(null!=t?t.parameterContentTypeId:t))?o:l,"function"==typeof o?o.call(s,{name:"parameterContentTypeId",hash:{},data:i}):o))+'" data-sw-translate>Parameter content type:</label>\n<select name="parameterContentType" id="'+(null!=(a=(n.sanitize||t&&t.sanitize||l).call(s,null!=t?t.parameterContentTypeId:t,{name:"sanitize",hash:{},data:i}))?a:"")+'">\n'+(null!=(a=n["if"].call(s,null!=t?t.consumes:t,{name:"if",hash:{},fn:e.program(1,i,0),inverse:e.program(4,i,0),data:i}))?a:"")+"</select>\n"},useData:!0}),t.popup=e({compiler:[7,">= 4.0.0"],main:function(e,t,n,r,i){var a;return'<div class="api-popup-dialog-wrapper">\n <div class="api-popup-title">'+e.escapeExpression((a=null!=(a=n.title||(null!=t?t.title:t))?a:n.helperMissing,"function"==typeof a?a.call(null!=t?t:{},{name:"title",hash:{},data:i}):a))+'</div>\n <div class="api-popup-content"></div>\n <p class="error-msg"></p>\n <div class="api-popup-actions">\n <button class="api-popup-cancel api-button gray" type="button">Cancel</button>\n </div>\n</div>\n<div class="api-popup-dialog-shadow"></div>'},useData:!0}),t.resource=e({1:function(e,t,n,r,i){return" : "},3:function(e,t,n,r,i){var a;return" <li>\n <a href='"+(null!=(a=(n.sanitize||t&&t.sanitize||n.helperMissing).call(null!=t?t:{},null!=t?t.url:t,{name:"sanitize",hash:{},data:i}))?a:"")+"' data-sw-translate>Raw</a>\n </li>\n"},compiler:[7,">= 4.0.0"],main:function(e,t,n,r,i){var a,o,s,l=null!=t?t:{},u=n.helperMissing,c="<div class='heading'>\n <h2>\n <a href='#!/"+(null!=(a=(n.sanitize||t&&t.sanitize||u).call(l,null!=t?t.id:t,{name:"sanitize",hash:{},data:i}))?a:"")+'\' class="toggleEndpointList" data-id="'+(null!=(a=(n.sanitize||t&&t.sanitize||u).call(l,null!=t?t.id:t,{name:"sanitize",hash:{},data:i}))?a:"")+'">'+(null!=(a=(n.sanitize||t&&t.sanitize||u).call(l,null!=t?t.name:t,{name:"sanitize",hash:{},data:i}))?a:"")+"</a> ";return o=null!=(o=n.summary||(null!=t?t.summary:t))?o:u,s={name:"summary",hash:{},fn:e.program(1,i,0),inverse:e.noop,data:i},a="function"==typeof o?o.call(l,s):o,n.summary||(a=n.blockHelperMissing.call(t,a,s)),null!=a&&(c+=a),c+(null!=(a=(n.sanitize||t&&t.sanitize||u).call(l,null!=t?t.summary:t,{name:"sanitize",hash:{},data:i}))?a:"")+"\n </h2>\n <ul class='options'>\n <li>\n <a href='#!/"+(null!=(a=(n.sanitize||t&&t.sanitize||u).call(l,null!=t?t.id:t,{name:"sanitize",hash:{},data:i}))?a:"")+"' id='endpointListTogger_"+(null!=(a=(n.sanitize||t&&t.sanitize||u).call(l,null!=t?t.id:t,{name:"sanitize",hash:{},data:i}))?a:"")+'\' class="toggleEndpointList" data-id="'+(null!=(a=(n.sanitize||t&&t.sanitize||u).call(l,null!=t?t.id:t,{name:"sanitize",hash:{},data:i}))?a:"")+'" data-sw-translate>Show/Hide</a>\n </li>\n <li>\n <a href=\'#\' class="collapseResource" data-id="'+(null!=(a=(n.sanitize||t&&t.sanitize||u).call(l,null!=t?t.id:t,{name:"sanitize",hash:{},data:i}))?a:"")+'" data-sw-translate>\n List Operations\n </a>\n </li>\n <li>\n <a href=\'#\' class="expandResource" data-id="'+(null!=(a=(n.sanitize||t&&t.sanitize||u).call(l,null!=t?t.id:t,{name:"sanitize",hash:{},data:i}))?a:"")+'" data-sw-translate>\n Expand Operations\n </a>\n </li>\n'+(null!=(a=n["if"].call(l,null!=t?t.url:t,{name:"if",hash:{},fn:e.program(3,i,0),inverse:e.noop,data:i}))?a:"")+" </ul>\n</div>\n<ul class='endpoints' id='"+(null!=(a=(n.sanitize||t&&t.sanitize||u).call(l,null!=t?t.id:t,{name:"sanitize",hash:{},data:i}))?a:"")+"_endpoint_list' style='display:none'>\n\n</ul>\n"},useData:!0}),t.response_content_type=e({1:function(e,t,n,r,i){var a;return null!=(a=n.each.call(null!=t?t:{},null!=t?t.produces:t,{name:"each",hash:{},fn:e.program(2,i,0),inverse:e.noop,data:i}))?a:""},2:function(e,t,n,r,i){var a,o=null!=t?t:{},s=n.helperMissing;return' <option value="'+(null!=(a=(n.sanitize||t&&t.sanitize||s).call(o,t,{name:"sanitize",hash:{},data:i}))?a:"")+'">'+(null!=(a=(n.sanitize||t&&t.sanitize||s).call(o,t,{name:"sanitize",hash:{},data:i}))?a:"")+"</option>\n"},4:function(e,t,n,r,i){return' <option value="application/json">application/json</option>\n'},compiler:[7,">= 4.0.0"],main:function(e,t,n,r,i){var a,o,s=null!=t?t:{},l=n.helperMissing,u="function",c=e.escapeExpression;return'<label data-sw-translate for="'+c((o=null!=(o=n.responseContentTypeId||(null!=t?t.responseContentTypeId:t))?o:l,typeof o===u?o.call(s,{name:"responseContentTypeId",hash:{},data:i}):o))+'">Response Content Type</label>\n<select name="responseContentType" id="'+c((o=null!=(o=n.responseContentTypeId||(null!=t?t.responseContentTypeId:t))?o:l,typeof o===u?o.call(s,{name:"responseContentTypeId",hash:{},data:i}):o))+'">\n'+(null!=(a=n["if"].call(s,null!=t?t.produces:t,{name:"if",hash:{},fn:e.program(1,i,0),inverse:e.program(4,i,0),data:i}))?a:"")+"</select>\n"},useData:!0}),t.signature=e({1:function(e,t,n,r,i){var a,o=null!=t?t:{};return'\n<div>\n<ul class="signature-nav">\n <li><a class="description-link" href="#" data-sw-translate>Model</a></li>\n <li><a class="snippet-link" href="#" data-sw-translate>Example Value</a></li>\n</ul>\n<div>\n\n<div class="signature-container">\n <div class="description">\n '+e.escapeExpression((n.sanitize||t&&t.sanitize||n.helperMissing).call(o,null!=t?t.signature:t,{name:"sanitize",hash:{},data:i}))+'\n </div>\n\n <div class="snippet">\n'+(null!=(a=n["if"].call(o,null!=t?t.sampleJSON:t,{name:"if",hash:{},fn:e.program(2,i,0),inverse:e.noop,data:i}))?a:"")+(null!=(a=n["if"].call(o,null!=t?t.sampleXML:t,{name:"if",hash:{},fn:e.program(5,i,0),inverse:e.noop,data:i}))?a:"")+" </div>\n</div>\n"},2:function(e,t,n,r,i){var a,o=null!=t?t:{};return' <div class="snippet_json">\n <pre><code>'+(null!=(a=(n.escape||t&&t.escape||n.helperMissing).call(o,null!=t?t.sampleJSON:t,{name:"escape",hash:{},data:i}))?a:"")+"</code></pre>\n "+(null!=(a=n["if"].call(o,null!=t?t.isParam:t,{name:"if",hash:{},fn:e.program(3,i,0),inverse:e.noop,data:i}))?a:"")+"\n </div>\n"},3:function(e,t,n,r,i){return'<small class="notice" data-sw-translate></small>'},5:function(e,t,n,r,i){var a,o=null!=t?t:{};return' <div class="snippet_xml">\n <pre><code>'+(null!=(a=(n.escape||t&&t.escape||n.helperMissing).call(o,null!=t?t.sampleXML:t,{name:"escape",hash:{},data:i}))?a:"")+"</code></pre>\n "+(null!=(a=n["if"].call(o,null!=t?t.isParam:t,{name:"if",hash:{},fn:e.program(3,i,0),inverse:e.noop,data:i}))?a:"")+"\n </div>\n"},7:function(e,t,n,r,i){var a;return" "+(null!=(a=(n.escape||t&&t.escape||n.helperMissing).call(null!=t?t:{},null!=t?t.signature:t,{name:"escape",hash:{},data:i}))?a:"")+"\n"},compiler:[7,">= 4.0.0"],main:function(e,t,n,r,i){var a;return null!=(a=(n.ifCond||t&&t.ifCond||n.helperMissing).call(null!=t?t:{},null!=t?t.sampleJSON:t,"||",null!=t?t.sampleXML:t,{name:"ifCond",hash:{},fn:e.program(1,i,0),inverse:e.program(7,i,0),data:i}))?a:""},useData:!0}),t.status_code=e({1:function(e,t,n,r,i){var a,o,s=null!=t?t:{},l=n.helperMissing;return" <tr>\n <td>"+e.escapeExpression((o=null!=(o=n.key||i&&i.key)?o:l,"function"==typeof o?o.call(s,{name:"key",hash:{},data:i}):o))+"</td>\n <td>"+(null!=(a=(n.sanitize||t&&t.sanitize||l).call(s,null!=t?t.description:t,{name:"sanitize",hash:{},data:i}))?a:"")+"</td>\n <td>"+(null!=(a=(n.escape||t&&t.escape||l).call(s,null!=t?t.type:t,{name:"escape",hash:{},data:i}))?a:"")+"</td>\n </tr>\n"},compiler:[7,">= 4.0.0"],main:function(e,t,n,r,i){var a,o=null!=t?t:{},s=n.helperMissing;return"<td width='15%' class='code'>"+(null!=(a=(n.escape||t&&t.escape||s).call(o,null!=t?t.code:t,{name:"escape",hash:{},data:i}))?a:"")+'</td>\n<td class="markdown">'+(null!=(a=(n.escape||t&&t.escape||s).call(o,null!=t?t.message:t,{name:"escape",hash:{},data:i}))?a:"")+'</td>\n<td width=\'50%\'><span class="model-signature" /></td>\n<td class="headers">\n <table>\n <tbody>\n'+(null!=(a=n.each.call(o,null!=t?t.headers:t,{name:"each",hash:{},fn:e.program(1,i,0),inverse:e.noop,data:i}))?a:"")+" </tbody>\n </table>\n</td>"},useData:!0})}(),$(function(){$.fn.vAlign=function(){return this.each(function(){var e=$(this).height(),t=$(this).parent().height(),n=(t-e)/2;$(this).css("margin-top",n)})},$.fn.stretchFormtasticInputWidthToParent=function(){return this.each(function(){var e=$(this).closest("form").innerWidth(),t=parseInt($(this).closest("form").css("padding-left"),10)+parseInt($(this).closest("form").css("padding-right"),10),n=parseInt($(this).css("padding-left"),10)+parseInt($(this).css("padding-right"),10);$(this).css("width",e-t-n)})},$("form.formtastic li.string input, form.formtastic textarea").stretchFormtasticInputWidthToParent(),$("ul.downplayed li div.content p").vAlign(),$("form.sandbox").submit(function(){var e=!0;return $(this).find("input.required").each(function(){$(this).removeClass("error"),""===$(this).val()&&($(this).addClass("error"),$(this).wiggle(),e=!1)}),e})}),Function.prototype.bind&&console&&"object"==typeof console.log&&["log","info","warn","error","assert","dir","clear","profile","profileEnd"].forEach(function(e){console[e]=this.bind(console[e],console)},Function.prototype.call),window.Docs={shebang:function(){var e=$.param.fragment().split("/");switch(e.shift(),e.length){case 1:if(e[0].length>0){var t="resource_"+e[0];Docs.expandEndpointListForResource(e[0]),$("#"+t).slideto({highlight:!1})}break;case 2:Docs.expandEndpointListForResource(e[0]),$("#"+t).slideto({highlight:!1});var n=e.join("_"),r=n+"_content";Docs.expandOperation($("#"+r)),$("#"+n).slideto({highlight:!1})}},toggleEndpointListForResource:function(e){var t=$("li#resource_"+Docs.escapeResourceName(e)+" ul.endpoints");t.is(":visible")?($.bbq.pushState("#/",2),Docs.collapseEndpointListForResource(e)):($.bbq.pushState("#/"+e,2),Docs.expandEndpointListForResource(e))},expandEndpointListForResource:function(e){var e=Docs.escapeResourceName(e);if(""==e)return void $(".resource ul.endpoints").slideDown();$("li#resource_"+e).addClass("active");var t=$("li#resource_"+e+" ul.endpoints");t.slideDown()},collapseEndpointListForResource:function(e){var e=Docs.escapeResourceName(e);if(""==e)return void $(".resource ul.endpoints").slideUp();$("li#resource_"+e).removeClass("active");var t=$("li#resource_"+e+" ul.endpoints");t.slideUp()},expandOperationsForResource:function(e){return Docs.expandEndpointListForResource(e),""==e?void $(".resource ul.endpoints li.operation div.content").slideDown():void $("li#resource_"+Docs.escapeResourceName(e)+" li.operation div.content").each(function(){Docs.expandOperation($(this))})},collapseOperationsForResource:function(e){return Docs.expandEndpointListForResource(e),""==e?void $(".resource ul.endpoints li.operation div.content").slideUp():void $("li#resource_"+Docs.escapeResourceName(e)+" li.operation div.content").each(function(){Docs.collapseOperation($(this))})},escapeResourceName:function(e){return e.replace(/[!"#$%&'()*+,.\/:;<=>?@\[\\\]\^`{|}~]/g,"\\$&")},expandOperation:function(e){e.slideDown()},collapseOperation:function(e){e.slideUp()}},function(e,t){"use strict";"function"==typeof define&&define.amd?define(t):"object"==typeof exports?module.exports=t():e.returnExports=t()}(this,function(){var e,t,n=Array,r=n.prototype,i=Object,a=i.prototype,o=Function,s=o.prototype,l=String,u=l.prototype,c=Number,p=c.prototype,h=r.slice,f=r.splice,d=r.push,m=r.unshift,g=r.concat,y=r.join,v=s.call,b=s.apply,w=Math.max,_=Math.min,x=a.toString,A="function"==typeof Symbol&&"symbol"==typeof Symbol.toStringTag,S=Function.prototype.toString,j=/^\s*class /,E=function(e){try{var t=S.call(e),n=t.replace(/\/\/.*\n/g,""),r=n.replace(/\/\*[.\s\S]*\*\//g,""),i=r.replace(/\n/gm," ").replace(/ {2}/g," ");return j.test(i)}catch(a){return!1}},O=function(e){try{return!E(e)&&(S.call(e),!0)}catch(t){return!1}},k="[object Function]",T="[object GeneratorFunction]",e=function(e){if(!e)return!1;if("function"!=typeof e&&"object"!=typeof e)return!1;if(A)return O(e);if(E(e))return!1;var t=x.call(e);return t===k||t===T},C=RegExp.prototype.exec,I=function(e){try{return C.call(e),!0}catch(t){return!1}},D="[object RegExp]";t=function(e){return"object"==typeof e&&(A?I(e):x.call(e)===D)};var L,M=String.prototype.valueOf,R=function(e){try{return M.call(e),!0}catch(t){return!1}},U="[object String]";L=function(e){return"string"==typeof e||"object"==typeof e&&(A?R(e):x.call(e)===U)};var P=i.defineProperty&&function(){try{var e={};i.defineProperty(e,"x",{enumerable:!1,value:e});for(var t in e)return!1;return e.x===e}catch(n){return!1}}(),q=function(e){var t;return t=P?function(e,t,n,r){!r&&t in e||i.defineProperty(e,t,{configurable:!0,enumerable:!1,writable:!0,value:n})}:function(e,t,n,r){!r&&t in e||(e[t]=n)},function(n,r,i){for(var a in r)e.call(r,a)&&t(n,a,r[a],i)}}(a.hasOwnProperty),B=function(e){var t=typeof e;return null===e||"object"!==t&&"function"!==t},N=c.isNaN||function(e){return e!==e},z={ToInteger:function(e){var t=+e;return N(t)?t=0:0!==t&&t!==1/0&&t!==-(1/0)&&(t=(t>0||-1)*Math.floor(Math.abs(t))),t},ToPrimitive:function(t){var n,r,i;if(B(t))return t;if(r=t.valueOf,e(r)&&(n=r.call(t),B(n)))return n;if(i=t.toString,e(i)&&(n=i.call(t),B(n)))return n;throw new TypeError},ToObject:function(e){if(null==e)throw new TypeError("can't convert "+e+" to object");return i(e)},ToUint32:function(e){return e>>>0}},$=function(){};q(s,{bind:function(t){var n=this;if(!e(n))throw new TypeError("Function.prototype.bind called on incompatible "+n);for(var r,a=h.call(arguments,1),s=function(){if(this instanceof r){var e=b.call(n,this,g.call(a,h.call(arguments)));return i(e)===e?e:this}return b.call(n,t,g.call(a,h.call(arguments)))},l=w(0,n.length-a.length),u=[],c=0;c<l;c++)d.call(u,"$"+c);return r=o("binder","return function ("+y.call(u,",")+"){ return binder.apply(this, arguments); }")(s),n.prototype&&($.prototype=n.prototype,r.prototype=new $,$.prototype=null),r}});var F=v.bind(a.hasOwnProperty),V=v.bind(a.toString),H=v.bind(h),Y=b.bind(h),J=v.bind(u.slice),W=v.bind(u.split),Q=v.bind(u.indexOf),G=v.bind(d),K=v.bind(a.propertyIsEnumerable),X=v.bind(r.sort),Z=n.isArray||function(e){return"[object Array]"===V(e)},ee=1!==[].unshift(0);q(r,{unshift:function(){return m.apply(this,arguments),this.length}},ee),q(n,{isArray:Z});var te=i("a"),ne="a"!==te[0]||!(0 in te),re=function(e){var t=!0,n=!0,r=!1;if(e)try{e.call("foo",function(e,n,r){"object"!=typeof r&&(t=!1)}),e.call([1],function(){"use strict";n="string"==typeof this},"x")}catch(i){r=!0}return!!e&&!r&&t&&n};q(r,{forEach:function(t){var n,r=z.ToObject(this),i=ne&&L(this)?W(this,""):r,a=-1,o=z.ToUint32(i.length);if(arguments.length>1&&(n=arguments[1]),!e(t))throw new TypeError("Array.prototype.forEach callback must be a function");for(;++a<o;)a in i&&("undefined"==typeof n?t(i[a],a,r):t.call(n,i[a],a,r))}},!re(r.forEach)),q(r,{map:function(t){var r,i=z.ToObject(this),a=ne&&L(this)?W(this,""):i,o=z.ToUint32(a.length),s=n(o);if(arguments.length>1&&(r=arguments[1]),!e(t))throw new TypeError("Array.prototype.map callback must be a function");for(var l=0;l<o;l++)l in a&&("undefined"==typeof r?s[l]=t(a[l],l,i):s[l]=t.call(r,a[l],l,i));return s}},!re(r.map)),q(r,{filter:function(t){var n,r,i=z.ToObject(this),a=ne&&L(this)?W(this,""):i,o=z.ToUint32(a.length),s=[];if(arguments.length>1&&(r=arguments[1]),!e(t))throw new TypeError("Array.prototype.filter callback must be a function");for(var l=0;l<o;l++)l in a&&(n=a[l],("undefined"==typeof r?t(n,l,i):t.call(r,n,l,i))&&G(s,n));return s}},!re(r.filter)),q(r,{every:function(t){var n,r=z.ToObject(this),i=ne&&L(this)?W(this,""):r,a=z.ToUint32(i.length);if(arguments.length>1&&(n=arguments[1]),!e(t))throw new TypeError("Array.prototype.every callback must be a function");for(var o=0;o<a;o++)if(o in i&&!("undefined"==typeof n?t(i[o],o,r):t.call(n,i[o],o,r)))return!1;return!0}},!re(r.every)),q(r,{some:function(t){var n,r=z.ToObject(this),i=ne&&L(this)?W(this,""):r,a=z.ToUint32(i.length);if(arguments.length>1&&(n=arguments[1]),!e(t))throw new TypeError("Array.prototype.some callback must be a function");for(var o=0;o<a;o++)if(o in i&&("undefined"==typeof n?t(i[o],o,r):t.call(n,i[o],o,r)))return!0;return!1}},!re(r.some));var ie=!1;r.reduce&&(ie="object"==typeof r.reduce.call("es5",function(e,t,n,r){return r})),q(r,{reduce:function(t){var n=z.ToObject(this),r=ne&&L(this)?W(this,""):n,i=z.ToUint32(r.length);if(!e(t))throw new TypeError("Array.prototype.reduce callback must be a function");if(0===i&&1===arguments.length)throw new TypeError("reduce of empty array with no initial value");var a,o=0;if(arguments.length>=2)a=arguments[1];else for(;;){if(o in r){a=r[o++];break}if(++o>=i)throw new TypeError("reduce of empty array with no initial value")}for(;o<i;o++)o in r&&(a=t(a,r[o],o,n));return a}},!ie);var ae=!1;r.reduceRight&&(ae="object"==typeof r.reduceRight.call("es5",function(e,t,n,r){return r})),q(r,{reduceRight:function(t){var n=z.ToObject(this),r=ne&&L(this)?W(this,""):n,i=z.ToUint32(r.length);if(!e(t))throw new TypeError("Array.prototype.reduceRight callback must be a function");if(0===i&&1===arguments.length)throw new TypeError("reduceRight of empty array with no initial value");var a,o=i-1;if(arguments.length>=2)a=arguments[1];else for(;;){if(o in r){a=r[o--];break}if(--o<0)throw new TypeError("reduceRight of empty array with no initial value")}if(o<0)return a;do o in r&&(a=t(a,r[o],o,n));while(o--);return a}},!ae);var oe=r.indexOf&&[0,1].indexOf(1,2)!==-1;q(r,{indexOf:function(e){var t=ne&&L(this)?W(this,""):z.ToObject(this),n=z.ToUint32(t.length);if(0===n)return-1;var r=0;for(arguments.length>1&&(r=z.ToInteger(arguments[1])),r=r>=0?r:w(0,n+r);r<n;r++)if(r in t&&t[r]===e)return r;return-1}},oe);var se=r.lastIndexOf&&[0,1].lastIndexOf(0,-3)!==-1;q(r,{lastIndexOf:function(e){var t=ne&&L(this)?W(this,""):z.ToObject(this),n=z.ToUint32(t.length);if(0===n)return-1;var r=n-1;for(arguments.length>1&&(r=_(r,z.ToInteger(arguments[1]))),r=r>=0?r:n-Math.abs(r);r>=0;r--)if(r in t&&e===t[r])return r;return-1}},se);var le=function(){var e=[1,2],t=e.splice();return 2===e.length&&Z(t)&&0===t.length}();q(r,{splice:function(e,t){return 0===arguments.length?[]:f.apply(this,arguments)}},!le);var ue=function(){var e={};return r.splice.call(e,0,0,1),1===e.length}();q(r,{splice:function(e,t){if(0===arguments.length)return[];var n=arguments;return this.length=w(z.ToInteger(this.length),0),arguments.length>0&&"number"!=typeof t&&(n=H(arguments),n.length<2?G(n,this.length-e):n[1]=z.ToInteger(t)),f.apply(this,n)}},!ue);var ce=function(){var e=new n(1e5);return e[8]="x",e.splice(1,1),7===e.indexOf("x")}(),pe=function(){var e=256,t=[];return t[e]="a",t.splice(e+1,0,"b"),"a"===t[e]}();q(r,{splice:function(e,t){for(var n,r=z.ToObject(this),i=[],a=z.ToUint32(r.length),o=z.ToInteger(e),s=o<0?w(a+o,0):_(o,a),u=_(w(z.ToInteger(t),0),a-s),c=0;c<u;)n=l(s+c),F(r,n)&&(i[c]=r[n]),c+=1;var p,h=H(arguments,2),f=h.length;if(f<u){c=s;for(var d=a-u;c<d;)n=l(c+u),p=l(c+f),F(r,n)?r[p]=r[n]:delete r[p],c+=1;c=a;for(var m=a-u+f;c>m;)delete r[c-1],c-=1}else if(f>u)for(c=a-u;c>s;)n=l(c+u-1),p=l(c+f-1),F(r,n)?r[p]=r[n]:delete r[p],c-=1;c=s;for(var g=0;g<h.length;++g)r[c]=h[g],c+=1;return r.length=a-u+f,i}},!ce||!pe);var he,fe=r.join;try{he="1,2,3"!==Array.prototype.join.call("123",",")}catch(de){he=!0}he&&q(r,{join:function(e){var t="undefined"==typeof e?",":e;return fe.call(L(this)?W(this,""):this,t)}},he);var me="1,2"!==[1,2].join(void 0);me&&q(r,{join:function(e){var t="undefined"==typeof e?",":e;return fe.call(this,t)}},me);var ge=function(e){for(var t=z.ToObject(this),n=z.ToUint32(t.length),r=0;r<arguments.length;)t[n+r]=arguments[r],r+=1;return t.length=n+r,n+r},ye=function(){var e={},t=Array.prototype.push.call(e,void 0);return 1!==t||1!==e.length||"undefined"!=typeof e[0]||!F(e,0)}();q(r,{push:function(e){return Z(this)?d.apply(this,arguments):ge.apply(this,arguments)}},ye);var ve=function(){var e=[],t=e.push(void 0);return 1!==t||1!==e.length||"undefined"!=typeof e[0]||!F(e,0)}();q(r,{push:ge},ve),q(r,{slice:function(e,t){var n=L(this)?W(this,""):this;return Y(n,arguments)}},ne);var be=function(){try{return[1,2].sort(null),[1,2].sort({}),!0}catch(e){}return!1}(),we=function(){try{return[1,2].sort(/a/),!1}catch(e){}return!0}(),_e=function(){try{return[1,2].sort(void 0),!0}catch(e){}return!1}();q(r,{sort:function(t){if("undefined"==typeof t)return X(this);if(!e(t))throw new TypeError("Array.prototype.sort callback must be a function");return X(this,t)}},be||!_e||!we);var xe=!K({toString:null},"toString"),Ae=K(function(){},"prototype"),Se=!F("x","0"),je=function(e){var t=e.constructor;return t&&t.prototype===e},Ee={$window:!0,$console:!0,$parent:!0,$self:!0,$frame:!0,$frames:!0,$frameElement:!0,$webkitIndexedDB:!0,$webkitStorageInfo:!0,$external:!0},Oe=function(){if("undefined"==typeof window)return!1;for(var e in window)try{!Ee["$"+e]&&F(window,e)&&null!==window[e]&&"object"==typeof window[e]&&je(window[e])}catch(t){return!0}return!1}(),ke=function(e){if("undefined"==typeof window||!Oe)return je(e);try{return je(e)}catch(t){return!1}},Te=["toString","toLocaleString","valueOf","hasOwnProperty","isPrototypeOf","propertyIsEnumerable","constructor"],Ce=Te.length,Ie=function(e){return"[object Arguments]"===V(e)},De=function(t){return null!==t&&"object"==typeof t&&"number"==typeof t.length&&t.length>=0&&!Z(t)&&e(t.callee)},Le=Ie(arguments)?Ie:De;q(i,{keys:function(t){var n=e(t),r=Le(t),i=null!==t&&"object"==typeof t,a=i&&L(t);if(!i&&!n&&!r)throw new TypeError("Object.keys called on a non-object");var o=[],s=Ae&&n;if(a&&Se||r)for(var u=0;u<t.length;++u)G(o,l(u));if(!r)for(var c in t)s&&"prototype"===c||!F(t,c)||G(o,l(c));if(xe)for(var p=ke(t),h=0;h<Ce;h++){var f=Te[h];p&&"constructor"===f||!F(t,f)||G(o,f)}return o}});var Me=i.keys&&function(){return 2===i.keys(arguments).length}(1,2),Re=i.keys&&function(){var e=i.keys(arguments);return 1!==arguments.length||1!==e.length||1!==e[0]}(1),Ue=i.keys;q(i,{keys:function(e){return Ue(Le(e)?H(e):e)}},!Me||Re);var Pe,qe,Be=0!==new Date((-0xc782b5b342b24)).getUTCMonth(),Ne=new Date((-0x55d318d56a724)),ze=new Date(14496624e5),$e="Mon, 01 Jan -45875 11:59:59 GMT"!==Ne.toUTCString(),Fe=Ne.getTimezoneOffset();Fe<-720?(Pe="Tue Jan 02 -45875"!==Ne.toDateString(),qe=!/^Thu Dec 10 2015 \d\d:\d\d:\d\d GMT[-\+]\d\d\d\d(?: |$)/.test(ze.toString())):(Pe="Mon Jan 01 -45875"!==Ne.toDateString(),qe=!/^Wed Dec 09 2015 \d\d:\d\d:\d\d GMT[-\+]\d\d\d\d(?: |$)/.test(ze.toString()));var Ve=v.bind(Date.prototype.getFullYear),He=v.bind(Date.prototype.getMonth),Ye=v.bind(Date.prototype.getDate),Je=v.bind(Date.prototype.getUTCFullYear),We=v.bind(Date.prototype.getUTCMonth),Qe=v.bind(Date.prototype.getUTCDate),Ge=v.bind(Date.prototype.getUTCDay),Ke=v.bind(Date.prototype.getUTCHours),Xe=v.bind(Date.prototype.getUTCMinutes),Ze=v.bind(Date.prototype.getUTCSeconds),et=v.bind(Date.prototype.getUTCMilliseconds),tt=["Sun","Mon","Tue","Wed","Thu","Fri","Sat"],nt=["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"],rt=function(e,t){return Ye(new Date(t,e,0))};q(Date.prototype,{getFullYear:function(){if(!(this&&this instanceof Date))throw new TypeError("this is not a Date object.");var e=Ve(this);return e<0&&He(this)>11?e+1:e},getMonth:function(){if(!(this&&this instanceof Date))throw new TypeError("this is not a Date object.");var e=Ve(this),t=He(this);return e<0&&t>11?0:t},getDate:function(){if(!(this&&this instanceof Date))throw new TypeError("this is not a Date object.");var e=Ve(this),t=He(this),n=Ye(this);if(e<0&&t>11){if(12===t)return n;var r=rt(0,e+1);return r-n+1}return n},getUTCFullYear:function(){if(!(this&&this instanceof Date))throw new TypeError("this is not a Date object.");var e=Je(this);return e<0&&We(this)>11?e+1:e},getUTCMonth:function(){if(!(this&&this instanceof Date))throw new TypeError("this is not a Date object.");var e=Je(this),t=We(this);return e<0&&t>11?0:t},getUTCDate:function(){if(!(this&&this instanceof Date))throw new TypeError("this is not a Date object.");var e=Je(this),t=We(this),n=Qe(this);if(e<0&&t>11){if(12===t)return n;var r=rt(0,e+1);return r-n+1}return n}},Be),q(Date.prototype,{toUTCString:function(){if(!(this&&this instanceof Date))throw new TypeError("this is not a Date object.");var e=Ge(this),t=Qe(this),n=We(this),r=Je(this),i=Ke(this),a=Xe(this),o=Ze(this);return tt[e]+", "+(t<10?"0"+t:t)+" "+nt[n]+" "+r+" "+(i<10?"0"+i:i)+":"+(a<10?"0"+a:a)+":"+(o<10?"0"+o:o)+" GMT"}},Be||$e),q(Date.prototype,{toDateString:function(){if(!(this&&this instanceof Date))throw new TypeError("this is not a Date object.");var e=this.getDay(),t=this.getDate(),n=this.getMonth(),r=this.getFullYear();return tt[e]+" "+nt[n]+" "+(t<10?"0"+t:t)+" "+r}},Be||Pe),(Be||qe)&&(Date.prototype.toString=function(){if(!(this&&this instanceof Date))throw new TypeError("this is not a Date object.");var e=this.getDay(),t=this.getDate(),n=this.getMonth(),r=this.getFullYear(),i=this.getHours(),a=this.getMinutes(),o=this.getSeconds(),s=this.getTimezoneOffset(),l=Math.floor(Math.abs(s)/60),u=Math.floor(Math.abs(s)%60);return tt[e]+" "+nt[n]+" "+(t<10?"0"+t:t)+" "+r+" "+(i<10?"0"+i:i)+":"+(a<10?"0"+a:a)+":"+(o<10?"0"+o:o)+" GMT"+(s>0?"-":"+")+(l<10?"0"+l:l)+(u<10?"0"+u:u)},P&&i.defineProperty(Date.prototype,"toString",{configurable:!0,enumerable:!1,writable:!0}));var it=-621987552e5,at="-000001",ot=Date.prototype.toISOString&&new Date(it).toISOString().indexOf(at)===-1,st=Date.prototype.toISOString&&"1969-12-31T23:59:59.999Z"!==new Date((-1)).toISOString(),lt=v.bind(Date.prototype.getTime);q(Date.prototype,{toISOString:function(){if(!isFinite(this)||!isFinite(lt(this)))throw new RangeError("Date.prototype.toISOString called on non-finite value.");var e=Je(this),t=We(this);e+=Math.floor(t/12),t=(t%12+12)%12;var n=[t+1,Qe(this),Ke(this),Xe(this),Ze(this)];e=(e<0?"-":e>9999?"+":"")+J("00000"+Math.abs(e),0<=e&&e<=9999?-4:-6);for(var r=0;r<n.length;++r)n[r]=J("00"+n[r],-2);return e+"-"+H(n,0,2).join("-")+"T"+H(n,2).join(":")+"."+J("000"+et(this),-3)+"Z"}},ot||st);var ut=function(){try{return Date.prototype.toJSON&&null===new Date(NaN).toJSON()&&new Date(it).toJSON().indexOf(at)!==-1&&Date.prototype.toJSON.call({toISOString:function(){return!0}})}catch(e){return!1}}();ut||(Date.prototype.toJSON=function(t){var n=i(this),r=z.ToPrimitive(n);if("number"==typeof r&&!isFinite(r))return null;var a=n.toISOString;if(!e(a))throw new TypeError("toISOString property is not callable");return a.call(n)});var ct=1e15===Date.parse("+033658-09-27T01:46:40.000Z"),pt=!isNaN(Date.parse("2012-04-04T24:00:00.500Z"))||!isNaN(Date.parse("2012-11-31T23:59:59.000Z"))||!isNaN(Date.parse("2012-12-31T23:59:60.000Z")),ht=isNaN(Date.parse("2000-01-01T00:00:00.000Z"));if(ht||pt||!ct){var ft=Math.pow(2,31)-1,dt=N(new Date(1970,0,1,0,0,0,ft+1).getTime());Date=function(e){var t=function(n,r,i,a,o,s,u){var c,p=arguments.length;if(this instanceof e){var h=s,f=u;if(dt&&p>=7&&u>ft){var d=Math.floor(u/ft)*ft,m=Math.floor(d/1e3);h+=m,f-=1e3*m}c=1===p&&l(n)===n?new e(t.parse(n)):p>=7?new e(n,r,i,a,o,h,f):p>=6?new e(n,r,i,a,o,h):p>=5?new e(n,r,i,a,o):p>=4?new e(n,r,i,a):p>=3?new e(n,r,i):p>=2?new e(n,r):p>=1?new e(n instanceof e?+n:n):new e;
+}else c=e.apply(this,arguments);return B(c)||q(c,{constructor:t},!0),c},n=new RegExp("^(\\d{4}|[+-]\\d{6})(?:-(\\d{2})(?:-(\\d{2})(?:T(\\d{2}):(\\d{2})(?::(\\d{2})(?:(\\.\\d{1,}))?)?(Z|(?:([-+])(\\d{2}):(\\d{2})))?)?)?)?$"),r=[0,31,59,90,120,151,181,212,243,273,304,334,365],i=function(e,t){var n=t>1?1:0;return r[t]+Math.floor((e-1969+n)/4)-Math.floor((e-1901+n)/100)+Math.floor((e-1601+n)/400)+365*(e-1970)},a=function(t){var n=0,r=t;if(dt&&r>ft){var i=Math.floor(r/ft)*ft,a=Math.floor(i/1e3);n+=a,r-=1e3*a}return c(new e(1970,0,1,0,0,n,r))};for(var o in e)F(e,o)&&(t[o]=e[o]);q(t,{now:e.now,UTC:e.UTC},!0),t.prototype=e.prototype,q(t.prototype,{constructor:t},!0);var s=function(t){var r=n.exec(t);if(r){var o,s=c(r[1]),l=c(r[2]||1)-1,u=c(r[3]||1)-1,p=c(r[4]||0),h=c(r[5]||0),f=c(r[6]||0),d=Math.floor(1e3*c(r[7]||0)),m=Boolean(r[4]&&!r[8]),g="-"===r[9]?1:-1,y=c(r[10]||0),v=c(r[11]||0),b=h>0||f>0||d>0;return p<(b?24:25)&&h<60&&f<60&&d<1e3&&l>-1&&l<12&&y<24&&v<60&&u>-1&&u<i(s,l+1)-i(s,l)&&(o=60*(24*(i(s,l)+u)+p+y*g),o=1e3*(60*(o+h+v*g)+f)+d,m&&(o=a(o)),-864e13<=o&&o<=864e13)?o:NaN}return e.parse.apply(this,arguments)};return q(t,{parse:s}),t}(Date)}Date.now||(Date.now=function(){return(new Date).getTime()});var mt=p.toFixed&&("0.000"!==8e-5.toFixed(3)||"1"!==.9.toFixed(0)||"1.25"!==1.255.toFixed(2)||"1000000000000000128"!==(0xde0b6b3a7640080).toFixed(0)),gt={base:1e7,size:6,data:[0,0,0,0,0,0],multiply:function(e,t){for(var n=-1,r=t;++n<gt.size;)r+=e*gt.data[n],gt.data[n]=r%gt.base,r=Math.floor(r/gt.base)},divide:function(e){for(var t=gt.size,n=0;--t>=0;)n+=gt.data[t],gt.data[t]=Math.floor(n/e),n=n%e*gt.base},numToString:function(){for(var e=gt.size,t="";--e>=0;)if(""!==t||0===e||0!==gt.data[e]){var n=l(gt.data[e]);""===t?t=n:t+=J("0000000",0,7-n.length)+n}return t},pow:function Ut(e,t,n){return 0===t?n:t%2===1?Ut(e,t-1,n*e):Ut(e*e,t/2,n)},log:function(e){for(var t=0,n=e;n>=4096;)t+=12,n/=4096;for(;n>=2;)t+=1,n/=2;return t}},yt=function(e){var t,n,r,i,a,o,s,u;if(t=c(e),t=N(t)?0:Math.floor(t),t<0||t>20)throw new RangeError("Number.toFixed called with invalid number of decimals");if(n=c(this),N(n))return"NaN";if(n<=-1e21||n>=1e21)return l(n);if(r="",n<0&&(r="-",n=-n),i="0",n>1e-21)if(a=gt.log(n*gt.pow(2,69,1))-69,o=a<0?n*gt.pow(2,-a,1):n/gt.pow(2,a,1),o*=4503599627370496,a=52-a,a>0){for(gt.multiply(0,o),s=t;s>=7;)gt.multiply(1e7,0),s-=7;for(gt.multiply(gt.pow(10,s,1),0),s=a-1;s>=23;)gt.divide(1<<23),s-=23;gt.divide(1<<s),gt.multiply(1,1),gt.divide(2),i=gt.numToString()}else gt.multiply(0,o),gt.multiply(1<<-a,0),i=gt.numToString()+J("0.00000000000000000000",2,2+t);return t>0?(u=i.length,i=u<=t?r+J("0.0000000000000000000",0,t-u+2)+i:r+J(i,0,u-t)+"."+J(i,u-t)):i=r+i,i};q(p,{toFixed:yt},mt);var vt=function(){try{return"1"===1..toPrecision(void 0)}catch(e){return!0}}(),bt=p.toPrecision;q(p,{toPrecision:function(e){return"undefined"==typeof e?bt.call(this):bt.call(this,e)}},vt),2!=="ab".split(/(?:ab)*/).length||4!==".".split(/(.?)(.?)/).length||"t"==="tesst".split(/(s)*/)[1]||4!=="test".split(/(?:)/,-1).length||"".split(/.?/).length||".".split(/()()/).length>1?!function(){var e="undefined"==typeof/()??/.exec("")[1],n=Math.pow(2,32)-1;u.split=function(r,i){var a=String(this);if("undefined"==typeof r&&0===i)return[];if(!t(r))return W(this,r,i);var o,s,l,u,c=[],p=(r.ignoreCase?"i":"")+(r.multiline?"m":"")+(r.unicode?"u":"")+(r.sticky?"y":""),h=0,f=new RegExp(r.source,p+"g");e||(o=new RegExp("^"+f.source+"$(?!\\s)",p));var m="undefined"==typeof i?n:z.ToUint32(i);for(s=f.exec(a);s&&(l=s.index+s[0].length,!(l>h&&(G(c,J(a,h,s.index)),!e&&s.length>1&&s[0].replace(o,function(){for(var e=1;e<arguments.length-2;e++)"undefined"==typeof arguments[e]&&(s[e]=void 0)}),s.length>1&&s.index<a.length&&d.apply(c,H(s,1)),u=s[0].length,h=l,c.length>=m)));)f.lastIndex===s.index&&f.lastIndex++,s=f.exec(a);return h===a.length?!u&&f.test("")||G(c,""):G(c,J(a,h)),c.length>m?H(c,0,m):c}}():"0".split(void 0,0).length&&(u.split=function(e,t){return"undefined"==typeof e&&0===t?[]:W(this,e,t)});var wt=u.replace,_t=function(){var e=[];return"x".replace(/x(.)?/g,function(t,n){G(e,n)}),1===e.length&&"undefined"==typeof e[0]}();_t||(u.replace=function(n,r){var i=e(r),a=t(n)&&/\)[*?]/.test(n.source);if(i&&a){var o=function(e){var t=arguments.length,i=n.lastIndex;n.lastIndex=0;var a=n.exec(e)||[];return n.lastIndex=i,G(a,arguments[t-2],arguments[t-1]),r.apply(this,a)};return wt.call(this,n,o)}return wt.call(this,n,r)});var xt=u.substr,At="".substr&&"b"!=="0b".substr(-1);q(u,{substr:function(e,t){var n=e;return e<0&&(n=w(this.length+e,0)),xt.call(this,n,t)}},At);var St="\t\n\x0B\f\r   ᠎              \u2028\u2029\ufeff",jt="​",Et="["+St+"]",Ot=new RegExp("^"+Et+Et+"*"),kt=new RegExp(Et+Et+"*$"),Tt=u.trim&&(St.trim()||!jt.trim());q(u,{trim:function(){if("undefined"==typeof this||null===this)throw new TypeError("can't convert "+this+" to object");return l(this).replace(Ot,"").replace(kt,"")}},Tt);var Ct=v.bind(String.prototype.trim),It=u.lastIndexOf&&"abcあい".lastIndexOf("あい",2)!==-1;q(u,{lastIndexOf:function(e){if("undefined"==typeof this||null===this)throw new TypeError("can't convert "+this+" to object");for(var t=l(this),n=l(e),r=arguments.length>1?c(arguments[1]):NaN,i=N(r)?1/0:z.ToInteger(r),a=_(w(i,0),t.length),o=n.length,s=a+o;s>0;){s=w(0,s-o);var u=Q(J(t,s,a+o),n);if(u!==-1)return s+u}return-1}},It);var Dt=u.lastIndexOf;if(q(u,{lastIndexOf:function(e){return Dt.apply(this,arguments)}},1!==u.lastIndexOf.length),8===parseInt(St+"08")&&22===parseInt(St+"0x16")||(parseInt=function(e){var t=/^[\-+]?0[xX]/;return function(n,r){var i=Ct(String(n)),a=c(r)||(t.test(i)?16:10);return e(i,a)}}(parseInt)),1/parseFloat("-0")!==-(1/0)&&(parseFloat=function(e){return function(t){var n=Ct(String(t)),r=e(n);return 0===r&&"-"===J(n,0,1)?-0:r}}(parseFloat)),"RangeError: test"!==String(new RangeError("test"))){var Lt=function(){if("undefined"==typeof this||null===this)throw new TypeError("can't convert "+this+" to object");var e=this.name;"undefined"==typeof e?e="Error":"string"!=typeof e&&(e=l(e));var t=this.message;return"undefined"==typeof t?t="":"string"!=typeof t&&(t=l(t)),e?t?e+": "+t:e:t};Error.prototype.toString=Lt}if(P){var Mt=function(e,t){if(K(e,t)){var n=Object.getOwnPropertyDescriptor(e,t);n.configurable&&(n.enumerable=!1,Object.defineProperty(e,t,n))}};Mt(Error.prototype,"message"),""!==Error.prototype.message&&(Error.prototype.message=""),Mt(Error.prototype,"name")}if("/a/gim"!==String(/a/gim)){var Rt=function(){var e="/"+this.source+"/";return this.global&&(e+="g"),this.ignoreCase&&(e+="i"),this.multiline&&(e+="m"),e};RegExp.prototype.toString=Rt}}),Handlebars.registerHelper("sanitize",function(e){var t;return void 0===e?"":(t=sanitizeHtml(e,{allowedTags:["div","span","b","i","em","strong","a"],allowedAttributes:{div:["class"],span:["class"],a:["href"]}}),new Handlebars.SafeString(t))}),Handlebars.registerHelper("renderTextParam",function(e){var t,n="text",r="",i=e.type||e.schema&&e.schema.type||"",a="array"===i.toLowerCase()||e.allowMultiple,o=a&&Array.isArray(e["default"])?e["default"].join("\n"):e["default"],s=Handlebars.Utils.escapeExpression(e.name),l=Handlebars.Utils.escapeExpression(e.valueId);i=Handlebars.Utils.escapeExpression(i);var u=Object.keys(e).filter(function(e){return null!==e.match(/^X-data-/i)}).reduce(function(t,n){return t+=" "+n.substring(2,n.length)+"='"+e[n]+"'"},"");if(e.format&&"password"===e.format&&(n="password"),l&&(r=" id='"+l+"'"),o=o?sanitizeHtml(o):"",a)t="<textarea class='body-textarea"+(e.required?" required":"")+"' name='"+s+"'"+r+u,t+=" placeholder='Provide multiple values in new lines"+(e.required?" (at least one required).":".")+"'>",t+=o+"</textarea>";else{var c="parameter";e.required&&(c+=" required"),t="<input class='"+c+"' minlength='"+(e.required?1:0)+"'",t+=" name='"+s+"' placeholder='"+(e.required?"(required)":"")+"'"+r+u,t+=" type='"+n+"' value='"+o+"'/>"}return new Handlebars.SafeString(t)}),Handlebars.registerHelper("ifCond",function(e,t,n,r){switch(t){case"==":return e==n?r.fn(this):r.inverse(this);case"===":return e===n?r.fn(this):r.inverse(this);case"<":return e<n?r.fn(this):r.inverse(this);case"<=":return e<=n?r.fn(this):r.inverse(this);case">":return e>n?r.fn(this):r.inverse(this);case">=":return e>=n?r.fn(this):r.inverse(this);case"&&":return e&&n?r.fn(this):r.inverse(this);case"||":return e||n?r.fn(this):r.inverse(this);default:return r.inverse(this)}}),Handlebars.registerHelper("escape",function(e){var t=Handlebars.Utils.escapeExpression(e);return new Handlebars.SafeString(t)}),function(e){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=e();else if("function"==typeof define&&define.amd)define([],e);else{var t;t="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:this,t.sanitizeHtml=e()}}(function(){return function e(t,n,r){function i(o,s){if(!n[o]){if(!t[o]){var l="function"==typeof require&&require;if(!s&&l)return l(o,!0);if(a)return a(o,!0);var u=new Error("Cannot find module '"+o+"'");throw u.code="MODULE_NOT_FOUND",u}var c=n[o]={exports:{}};t[o][0].call(c.exports,function(e){var n=t[o][1][e];return i(n?n:e)},c,c.exports,e,t,n,r)}return n[o].exports}for(var a="function"==typeof require&&require,o=0;o<r.length;o++)i(r[o]);return i}({1:[function(e,t,n){function r(e,t){e&&Object.keys(e).forEach(function(n){t(e[n],n)})}function i(e,t){return{}.hasOwnProperty.call(e,t)}function a(e,t,n){function c(e,t){var n=this;this.tag=e,this.attribs=t||{},this.tagPosition=d.length,this.text="",this.updateParentNodeText=function(){if(x.length){var e=x[x.length-1];e.text+=n.text}}}function p(e){return"string"!=typeof e&&(e+=""),e.replace(/\&/g,"&amp;").replace(/</g,"&lt;").replace(/\>/g,"&gt;").replace(/\"/g,"&quot;")}function h(e,n){n=n.replace(/[\x00-\x20]+/g,""),n=n.replace(/<\!\-\-.*?\-\-\>/g,"");var r=n.match(/^([a-zA-Z]+)\:/);if(!r)return!1;var a=r[1].toLowerCase();return i(t.allowedSchemesByTag,e)?t.allowedSchemesByTag[e].indexOf(a)===-1:!t.allowedSchemes||t.allowedSchemes.indexOf(a)===-1}function f(e,t){return t?(e=e.split(/\s+/),e.filter(function(e){return t.indexOf(e)!==-1}).join(" ")):e}var d="";t?(t=s(a.defaults,t),t.parser?t.parser=s(u,t.parser):t.parser=u):(t=a.defaults,t.parser=u);var m,g,y=t.nonTextTags||["script","style","textarea"];t.allowedAttributes&&(m={},g={},r(t.allowedAttributes,function(e,t){m[t]=[];var n=[];e.forEach(function(e){e.indexOf("*")>=0?n.push(l(e).replace(/\\\*/g,".*")):m[t].push(e)}),g[t]=new RegExp("^("+n.join("|")+")$")}));var v={};r(t.allowedClasses,function(e,t){m&&(i(m,t)||(m[t]=[]),m[t].push("class")),v[t]=e});var b,w={};r(t.transformTags,function(e,t){var n;"function"==typeof e?n=e:"string"==typeof e&&(n=a.simpleTransform(e)),"*"===t?b=n:w[t]=n});var _=0,x=[],A={},S={},j=!1,E=0,O=new o.Parser({onopentag:function(e,n){if(j)return void E++;var a=new c(e,n);x.push(a);var o,s=!1,l=!!a.text;i(w,e)&&(o=w[e](e,n),a.attribs=n=o.attribs,void 0!==o.text&&(a.innerText=o.text),e!==o.tagName&&(a.name=e=o.tagName,S[_]=o.tagName)),b&&(o=b(e,n),a.attribs=n=o.attribs,e!==o.tagName&&(a.name=e=o.tagName,S[_]=o.tagName)),t.allowedTags&&t.allowedTags.indexOf(e)===-1&&(s=!0,y.indexOf(e)!==-1&&(j=!0,E=1),A[_]=!0),_++,s||(d+="<"+e,(!m||i(m,e)||m["*"])&&r(n,function(t,n){if(!m||i(m,e)&&m[e].indexOf(n)!==-1||m["*"]&&m["*"].indexOf(n)!==-1||i(g,e)&&g[e].test(n)||g["*"]&&g["*"].test(n)){if(("href"===n||"src"===n)&&h(e,t))return void delete a.attribs[n];if("class"===n&&(t=f(t,v[e]),!t.length))return void delete a.attribs[n];d+=" "+n,t.length&&(d+='="'+p(t)+'"')}else delete a.attribs[n]}),t.selfClosing.indexOf(e)!==-1?d+=" />":(d+=">",!a.innerText||l||t.textFilter||(d+=a.innerText)))},ontext:function(e){if(!j){var n,r=x[x.length-1];if(r&&(n=r.tag,e=void 0!==r.innerText?r.innerText:e),"script"===n||"style"===n)d+=e;else{var i=p(e);d+=t.textFilter?t.textFilter(i):i}if(x.length){var a=x[x.length-1];a.text+=e}}},onclosetag:function(e){if(j){if(E--,E)return;j=!1}var n=x.pop();if(n){if(j=!1,_--,A[_])return delete A[_],void n.updateParentNodeText();if(S[_]&&(e=S[_],delete S[_]),t.exclusiveFilter&&t.exclusiveFilter(n))return void(d=d.substr(0,n.tagPosition));n.updateParentNodeText(),t.selfClosing.indexOf(e)===-1&&(d+="</"+e+">")}}},t.parser);return O.write(e),O.end(),d}var o=e("htmlparser2"),s=e("xtend"),l=e("regexp-quote");t.exports=a;var u={decodeEntities:!0};a.defaults={allowedTags:["h3","h4","h5","h6","blockquote","p","a","ul","ol","nl","li","b","i","strong","em","strike","code","hr","br","div","table","thead","caption","tbody","tr","th","td","pre"],allowedAttributes:{a:["href","name","target"],img:["src"]},selfClosing:["img","br","hr","area","base","basefont","input","link","meta"],allowedSchemes:["http","https","ftp","mailto"],allowedSchemesByTag:{}},a.simpleTransform=function(e,t,n){return n=void 0===n||n,t=t||{},function(r,i){var a;if(n)for(a in t)i[a]=t[a];else i=t;return{tagName:e,attribs:i}}}},{htmlparser2:36,"regexp-quote":54,xtend:58}],2:[function(e,t,n){"use strict";function r(){for(var e="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/",t=0,n=e.length;t<n;++t)l[t]=e[t],u[e.charCodeAt(t)]=t;u["-".charCodeAt(0)]=62,u["_".charCodeAt(0)]=63}function i(e){var t,n,r,i,a,o,s=e.length;if(s%4>0)throw new Error("Invalid string. Length must be a multiple of 4");a="="===e[s-2]?2:"="===e[s-1]?1:0,o=new c(3*s/4-a),r=a>0?s-4:s;var l=0;for(t=0,n=0;t<r;t+=4,n+=3)i=u[e.charCodeAt(t)]<<18|u[e.charCodeAt(t+1)]<<12|u[e.charCodeAt(t+2)]<<6|u[e.charCodeAt(t+3)],o[l++]=i>>16&255,o[l++]=i>>8&255,o[l++]=255&i;return 2===a?(i=u[e.charCodeAt(t)]<<2|u[e.charCodeAt(t+1)]>>4,o[l++]=255&i):1===a&&(i=u[e.charCodeAt(t)]<<10|u[e.charCodeAt(t+1)]<<4|u[e.charCodeAt(t+2)]>>2,o[l++]=i>>8&255,o[l++]=255&i),o}function a(e){return l[e>>18&63]+l[e>>12&63]+l[e>>6&63]+l[63&e]}function o(e,t,n){for(var r,i=[],o=t;o<n;o+=3)r=(e[o]<<16)+(e[o+1]<<8)+e[o+2],i.push(a(r));return i.join("")}function s(e){for(var t,n=e.length,r=n%3,i="",a=[],s=16383,u=0,c=n-r;u<c;u+=s)a.push(o(e,u,u+s>c?c:u+s));return 1===r?(t=e[n-1],i+=l[t>>2],i+=l[t<<4&63],i+="=="):2===r&&(t=(e[n-2]<<8)+e[n-1],i+=l[t>>10],i+=l[t>>4&63],i+=l[t<<2&63],i+="="),a.push(i),a.join("")}n.toByteArray=i,n.fromByteArray=s;var l=[],u=[],c="undefined"!=typeof Uint8Array?Uint8Array:Array;r()},{}],3:[function(e,t,n){},{}],4:[function(e,t,n){(function(t){"use strict";var r=e("buffer"),i=r.Buffer,a=r.SlowBuffer,o=r.kMaxLength||2147483647;n.alloc=function(e,t,n){if("function"==typeof i.alloc)return i.alloc(e,t,n);if("number"==typeof n)throw new TypeError("encoding must not be number");if("number"!=typeof e)throw new TypeError("size must be a number");if(e>o)throw new RangeError("size is too large");var r=n,a=t;void 0===a&&(r=void 0,a=0);var s=new i(e);if("string"==typeof a)for(var l=new i(a,r),u=l.length,c=-1;++c<e;)s[c]=l[c%u];else s.fill(a);return s},n.allocUnsafe=function(e){if("function"==typeof i.allocUnsafe)return i.allocUnsafe(e);if("number"!=typeof e)throw new TypeError("size must be a number");if(e>o)throw new RangeError("size is too large");return new i(e)},n.from=function(e,n,r){if("function"==typeof i.from&&(!t.Uint8Array||Uint8Array.from!==i.from))return i.from(e,n,r);if("number"==typeof e)throw new TypeError('"value" argument must not be a number');if("string"==typeof e)return new i(e,n);if("undefined"!=typeof ArrayBuffer&&e instanceof ArrayBuffer){var a=n;if(1===arguments.length)return new i(e);"undefined"==typeof a&&(a=0);var o=r;if("undefined"==typeof o&&(o=e.byteLength-a),a>=e.byteLength)throw new RangeError("'offset' is out of bounds");if(o>e.byteLength-a)throw new RangeError("'length' is out of bounds");return new i(e.slice(a,a+o))}if(i.isBuffer(e)){var s=new i(e.length);return e.copy(s,0,0,e.length),s}if(e){if(Array.isArray(e)||"undefined"!=typeof ArrayBuffer&&e.buffer instanceof ArrayBuffer||"length"in e)return new i(e);if("Buffer"===e.type&&Array.isArray(e.data))return new i(e.data)}throw new TypeError("First argument must be a string, Buffer, ArrayBuffer, Array, or array-like object.")},n.allocUnsafeSlow=function(e){if("function"==typeof i.allocUnsafeSlow)return i.allocUnsafeSlow(e);if("number"!=typeof e)throw new TypeError("size must be a number");if(e>=o)throw new RangeError("size is too large");return new a(e)}}).call(this,"undefined"!=typeof global?global:"undefined"!=typeof self?self:"undefined"!=typeof window?window:{})},{buffer:5}],5:[function(e,t,n){(function(t){"use strict";function r(){try{var e=new Uint8Array(1);return e.__proto__={__proto__:Uint8Array.prototype,foo:function(){return 42}},42===e.foo()&&"function"==typeof e.subarray&&0===e.subarray(1,1).byteLength}catch(t){return!1}}function i(){return o.TYPED_ARRAY_SUPPORT?2147483647:1073741823}function a(e,t){if(i()<t)throw new RangeError("Invalid typed array length");return o.TYPED_ARRAY_SUPPORT?(e=new Uint8Array(t),e.__proto__=o.prototype):(null===e&&(e=new o(t)),e.length=t),e}function o(e,t,n){if(!(o.TYPED_ARRAY_SUPPORT||this instanceof o))return new o(e,t,n);if("number"==typeof e){if("string"==typeof t)throw new Error("If encoding is specified then the first argument must be a string");return c(this,e)}return s(this,e,t,n)}function s(e,t,n,r){if("number"==typeof t)throw new TypeError('"value" argument must not be a number');return"undefined"!=typeof ArrayBuffer&&t instanceof ArrayBuffer?f(e,t,n,r):"string"==typeof t?p(e,t,n):d(e,t)}function l(e){if("number"!=typeof e)throw new TypeError('"size" argument must be a number');if(e<0)throw new RangeError('"size" argument must not be negative')}function u(e,t,n,r){return l(t),t<=0?a(e,t):void 0!==n?"string"==typeof r?a(e,t).fill(n,r):a(e,t).fill(n):a(e,t)}function c(e,t){if(l(t),e=a(e,t<0?0:0|m(t)),!o.TYPED_ARRAY_SUPPORT)for(var n=0;n<t;++n)e[n]=0;return e}function p(e,t,n){if("string"==typeof n&&""!==n||(n="utf8"),!o.isEncoding(n))throw new TypeError('"encoding" must be a valid string encoding');var r=0|y(t,n);e=a(e,r);var i=e.write(t,n);return i!==r&&(e=e.slice(0,i)),e}function h(e,t){var n=t.length<0?0:0|m(t.length);e=a(e,n);for(var r=0;r<n;r+=1)e[r]=255&t[r];return e}function f(e,t,n,r){if(t.byteLength,n<0||t.byteLength<n)throw new RangeError("'offset' is out of bounds");if(t.byteLength<n+(r||0))throw new RangeError("'length' is out of bounds");return t=void 0===n&&void 0===r?new Uint8Array(t):void 0===r?new Uint8Array(t,n):new Uint8Array(t,n,r),o.TYPED_ARRAY_SUPPORT?(e=t,e.__proto__=o.prototype):e=h(e,t),e}function d(e,t){if(o.isBuffer(t)){var n=0|m(t.length);return e=a(e,n),0===e.length?e:(t.copy(e,0,0,n),e)}if(t){if("undefined"!=typeof ArrayBuffer&&t.buffer instanceof ArrayBuffer||"length"in t)return"number"!=typeof t.length||G(t.length)?a(e,0):h(e,t);if("Buffer"===t.type&&Z(t.data))return h(e,t.data)}throw new TypeError("First argument must be a string, Buffer, ArrayBuffer, Array, or array-like object.")}function m(e){if(e>=i())throw new RangeError("Attempt to allocate Buffer larger than maximum size: 0x"+i().toString(16)+" bytes");return 0|e}function g(e){return+e!=e&&(e=0),o.alloc(+e)}function y(e,t){if(o.isBuffer(e))return e.length;if("undefined"!=typeof ArrayBuffer&&"function"==typeof ArrayBuffer.isView&&(ArrayBuffer.isView(e)||e instanceof ArrayBuffer))return e.byteLength;"string"!=typeof e&&(e=""+e);var n=e.length;if(0===n)return 0;for(var r=!1;;)switch(t){case"ascii":case"latin1":case"binary":return n;case"utf8":case"utf-8":case void 0:return H(e).length;case"ucs2":case"ucs-2":case"utf16le":case"utf-16le":return 2*n;case"hex":return n>>>1;case"base64":return W(e).length;default:if(r)return H(e).length;t=(""+t).toLowerCase(),r=!0}}function v(e,t,n){var r=!1;if((void 0===t||t<0)&&(t=0),t>this.length)return"";if((void 0===n||n>this.length)&&(n=this.length),n<=0)return"";if(n>>>=0,t>>>=0,n<=t)return"";for(e||(e="utf8");;)switch(e){case"hex":return L(this,t,n);case"utf8":case"utf-8":return T(this,t,n);case"ascii":return I(this,t,n);case"latin1":case"binary":return D(this,t,n);case"base64":return k(this,t,n);case"ucs2":case"ucs-2":case"utf16le":case"utf-16le":return M(this,t,n);default:if(r)throw new TypeError("Unknown encoding: "+e);e=(e+"").toLowerCase(),r=!0}}function b(e,t,n){var r=e[t];e[t]=e[n],e[n]=r}function w(e,t,n,r,i){if(0===e.length)return-1;if("string"==typeof n?(r=n,n=0):n>2147483647?n=2147483647:n<-2147483648&&(n=-2147483648),n=+n,isNaN(n)&&(n=i?0:e.length-1),n<0&&(n=e.length+n),n>=e.length){if(i)return-1;n=e.length-1}else if(n<0){if(!i)return-1;n=0}if("string"==typeof t&&(t=o.from(t,r)),o.isBuffer(t))return 0===t.length?-1:_(e,t,n,r,i);if("number"==typeof t)return t=255&t,o.TYPED_ARRAY_SUPPORT&&"function"==typeof Uint8Array.prototype.indexOf?i?Uint8Array.prototype.indexOf.call(e,t,n):Uint8Array.prototype.lastIndexOf.call(e,t,n):_(e,[t],n,r,i);throw new TypeError("val must be string, number or Buffer")}function _(e,t,n,r,i){function a(e,t){return 1===o?e[t]:e.readUInt16BE(t*o)}var o=1,s=e.length,l=t.length;if(void 0!==r&&(r=String(r).toLowerCase(),"ucs2"===r||"ucs-2"===r||"utf16le"===r||"utf-16le"===r)){if(e.length<2||t.length<2)return-1;o=2,s/=2,l/=2,n/=2}var u;if(i){var c=-1;for(u=n;u<s;u++)if(a(e,u)===a(t,c===-1?0:u-c)){if(c===-1&&(c=u),u-c+1===l)return c*o}else c!==-1&&(u-=u-c),c=-1}else for(n+l>s&&(n=s-l),u=n;u>=0;u--){for(var p=!0,h=0;h<l;h++)if(a(e,u+h)!==a(t,h)){p=!1;break}if(p)return u}return-1}function x(e,t,n,r){n=Number(n)||0;var i=e.length-n;r?(r=Number(r),r>i&&(r=i)):r=i;var a=t.length;if(a%2!==0)throw new TypeError("Invalid hex string");r>a/2&&(r=a/2);for(var o=0;o<r;++o){var s=parseInt(t.substr(2*o,2),16);if(isNaN(s))return o;e[n+o]=s}return o}function A(e,t,n,r){return Q(H(t,e.length-n),e,n,r)}function S(e,t,n,r){return Q(Y(t),e,n,r)}function j(e,t,n,r){return S(e,t,n,r)}function E(e,t,n,r){return Q(W(t),e,n,r)}function O(e,t,n,r){return Q(J(t,e.length-n),e,n,r)}function k(e,t,n){return 0===t&&n===e.length?K.fromByteArray(e):K.fromByteArray(e.slice(t,n))}function T(e,t,n){n=Math.min(e.length,n);for(var r=[],i=t;i<n;){var a=e[i],o=null,s=a>239?4:a>223?3:a>191?2:1;if(i+s<=n){var l,u,c,p;switch(s){case 1:a<128&&(o=a);break;case 2:l=e[i+1],128===(192&l)&&(p=(31&a)<<6|63&l,p>127&&(o=p));break;case 3:l=e[i+1],u=e[i+2],128===(192&l)&&128===(192&u)&&(p=(15&a)<<12|(63&l)<<6|63&u,p>2047&&(p<55296||p>57343)&&(o=p));break;case 4:l=e[i+1],u=e[i+2],c=e[i+3],128===(192&l)&&128===(192&u)&&128===(192&c)&&(p=(15&a)<<18|(63&l)<<12|(63&u)<<6|63&c,p>65535&&p<1114112&&(o=p))}}null===o?(o=65533,s=1):o>65535&&(o-=65536,r.push(o>>>10&1023|55296),o=56320|1023&o),r.push(o),i+=s}return C(r)}function C(e){var t=e.length;if(t<=ee)return String.fromCharCode.apply(String,e);for(var n="",r=0;r<t;)n+=String.fromCharCode.apply(String,e.slice(r,r+=ee));return n}function I(e,t,n){var r="";n=Math.min(e.length,n);for(var i=t;i<n;++i)r+=String.fromCharCode(127&e[i]);return r}function D(e,t,n){var r="";n=Math.min(e.length,n);for(var i=t;i<n;++i)r+=String.fromCharCode(e[i]);return r}function L(e,t,n){var r=e.length;(!t||t<0)&&(t=0),(!n||n<0||n>r)&&(n=r);for(var i="",a=t;a<n;++a)i+=V(e[a]);return i}function M(e,t,n){for(var r=e.slice(t,n),i="",a=0;a<r.length;a+=2)i+=String.fromCharCode(r[a]+256*r[a+1]);return i}function R(e,t,n){if(e%1!==0||e<0)throw new RangeError("offset is not uint");if(e+t>n)throw new RangeError("Trying to access beyond buffer length")}function U(e,t,n,r,i,a){if(!o.isBuffer(e))throw new TypeError('"buffer" argument must be a Buffer instance');if(t>i||t<a)throw new RangeError('"value" argument is out of bounds');if(n+r>e.length)throw new RangeError("Index out of range")}function P(e,t,n,r){t<0&&(t=65535+t+1);for(var i=0,a=Math.min(e.length-n,2);i<a;++i)e[n+i]=(t&255<<8*(r?i:1-i))>>>8*(r?i:1-i)}function q(e,t,n,r){t<0&&(t=4294967295+t+1);for(var i=0,a=Math.min(e.length-n,4);i<a;++i)e[n+i]=t>>>8*(r?i:3-i)&255}function B(e,t,n,r,i,a){if(n+r>e.length)throw new RangeError("Index out of range");if(n<0)throw new RangeError("Index out of range")}function N(e,t,n,r,i){return i||B(e,t,n,4,3.4028234663852886e38,-3.4028234663852886e38),X.write(e,t,n,r,23,4),n+4}function z(e,t,n,r,i){return i||B(e,t,n,8,1.7976931348623157e308,-1.7976931348623157e308),X.write(e,t,n,r,52,8),n+8}function $(e){if(e=F(e).replace(te,""),e.length<2)return"";for(;e.length%4!==0;)e+="=";return e}function F(e){return e.trim?e.trim():e.replace(/^\s+|\s+$/g,"")}function V(e){return e<16?"0"+e.toString(16):e.toString(16)}function H(e,t){t=t||1/0;for(var n,r=e.length,i=null,a=[],o=0;o<r;++o){if(n=e.charCodeAt(o),n>55295&&n<57344){if(!i){if(n>56319){(t-=3)>-1&&a.push(239,191,189);continue}if(o+1===r){(t-=3)>-1&&a.push(239,191,189);continue}i=n;continue}if(n<56320){(t-=3)>-1&&a.push(239,191,189),i=n;continue}n=(i-55296<<10|n-56320)+65536}else i&&(t-=3)>-1&&a.push(239,191,189);if(i=null,n<128){if((t-=1)<0)break;a.push(n)}else if(n<2048){if((t-=2)<0)break;a.push(n>>6|192,63&n|128)}else if(n<65536){if((t-=3)<0)break;a.push(n>>12|224,n>>6&63|128,63&n|128)}else{if(!(n<1114112))throw new Error("Invalid code point");if((t-=4)<0)break;a.push(n>>18|240,n>>12&63|128,n>>6&63|128,63&n|128)}}return a}function Y(e){for(var t=[],n=0;n<e.length;++n)t.push(255&e.charCodeAt(n));return t}function J(e,t){for(var n,r,i,a=[],o=0;o<e.length&&!((t-=2)<0);++o)n=e.charCodeAt(o),r=n>>8,i=n%256,a.push(i),a.push(r);return a}function W(e){return K.toByteArray($(e))}function Q(e,t,n,r){for(var i=0;i<r&&!(i+n>=t.length||i>=e.length);++i)t[i+n]=e[i];return i}function G(e){return e!==e}var K=e("base64-js"),X=e("ieee754"),Z=e("isarray");n.Buffer=o,n.SlowBuffer=g,n.INSPECT_MAX_BYTES=50,o.TYPED_ARRAY_SUPPORT=void 0!==t.TYPED_ARRAY_SUPPORT?t.TYPED_ARRAY_SUPPORT:r(),n.kMaxLength=i(),o.poolSize=8192,o._augment=function(e){return e.__proto__=o.prototype,e},o.from=function(e,t,n){return s(null,e,t,n)},o.TYPED_ARRAY_SUPPORT&&(o.prototype.__proto__=Uint8Array.prototype,o.__proto__=Uint8Array,"undefined"!=typeof Symbol&&Symbol.species&&o[Symbol.species]===o&&Object.defineProperty(o,Symbol.species,{value:null,configurable:!0})),o.alloc=function(e,t,n){return u(null,e,t,n)},o.allocUnsafe=function(e){return c(null,e)},o.allocUnsafeSlow=function(e){return c(null,e)},o.isBuffer=function(e){return!(null==e||!e._isBuffer)},o.compare=function(e,t){if(!o.isBuffer(e)||!o.isBuffer(t))throw new TypeError("Arguments must be Buffers");if(e===t)return 0;for(var n=e.length,r=t.length,i=0,a=Math.min(n,r);i<a;++i)if(e[i]!==t[i]){n=e[i],r=t[i];break}return n<r?-1:r<n?1:0},o.isEncoding=function(e){switch(String(e).toLowerCase()){case"hex":case"utf8":case"utf-8":case"ascii":case"latin1":case"binary":case"base64":case"ucs2":case"ucs-2":case"utf16le":case"utf-16le":return!0;default:return!1}},o.concat=function(e,t){if(!Z(e))throw new TypeError('"list" argument must be an Array of Buffers');if(0===e.length)return o.alloc(0);var n;if(void 0===t)for(t=0,n=0;n<e.length;++n)t+=e[n].length;var r=o.allocUnsafe(t),i=0;for(n=0;n<e.length;++n){var a=e[n];if(!o.isBuffer(a))throw new TypeError('"list" argument must be an Array of Buffers');a.copy(r,i),i+=a.length}return r},o.byteLength=y,o.prototype._isBuffer=!0,o.prototype.swap16=function(){var e=this.length;if(e%2!==0)throw new RangeError("Buffer size must be a multiple of 16-bits");for(var t=0;t<e;t+=2)b(this,t,t+1);return this},o.prototype.swap32=function(){var e=this.length;if(e%4!==0)throw new RangeError("Buffer size must be a multiple of 32-bits");for(var t=0;t<e;t+=4)b(this,t,t+3),b(this,t+1,t+2);return this},o.prototype.swap64=function(){var e=this.length;if(e%8!==0)throw new RangeError("Buffer size must be a multiple of 64-bits");for(var t=0;t<e;t+=8)b(this,t,t+7),b(this,t+1,t+6),b(this,t+2,t+5),b(this,t+3,t+4);return this},o.prototype.toString=function(){var e=0|this.length;return 0===e?"":0===arguments.length?T(this,0,e):v.apply(this,arguments)},o.prototype.equals=function(e){if(!o.isBuffer(e))throw new TypeError("Argument must be a Buffer");return this===e||0===o.compare(this,e)},o.prototype.inspect=function(){var e="",t=n.INSPECT_MAX_BYTES;return this.length>0&&(e=this.toString("hex",0,t).match(/.{2}/g).join(" "),this.length>t&&(e+=" ... ")),"<Buffer "+e+">"},o.prototype.compare=function(e,t,n,r,i){if(!o.isBuffer(e))throw new TypeError("Argument must be a Buffer");if(void 0===t&&(t=0),void 0===n&&(n=e?e.length:0),void 0===r&&(r=0),void 0===i&&(i=this.length),t<0||n>e.length||r<0||i>this.length)throw new RangeError("out of range index");if(r>=i&&t>=n)return 0;if(r>=i)return-1;if(t>=n)return 1;if(t>>>=0,n>>>=0,r>>>=0,i>>>=0,this===e)return 0;for(var a=i-r,s=n-t,l=Math.min(a,s),u=this.slice(r,i),c=e.slice(t,n),p=0;p<l;++p)if(u[p]!==c[p]){a=u[p],s=c[p];break}return a<s?-1:s<a?1:0},o.prototype.includes=function(e,t,n){return this.indexOf(e,t,n)!==-1},o.prototype.indexOf=function(e,t,n){return w(this,e,t,n,!0)},o.prototype.lastIndexOf=function(e,t,n){return w(this,e,t,n,!1)},o.prototype.write=function(e,t,n,r){if(void 0===t)r="utf8",n=this.length,t=0;else if(void 0===n&&"string"==typeof t)r=t,n=this.length,t=0;else{if(!isFinite(t))throw new Error("Buffer.write(string, encoding, offset[, length]) is no longer supported");t=0|t,isFinite(n)?(n=0|n,void 0===r&&(r="utf8")):(r=n,n=void 0)}var i=this.length-t;if((void 0===n||n>i)&&(n=i),e.length>0&&(n<0||t<0)||t>this.length)throw new RangeError("Attempt to write outside buffer bounds");r||(r="utf8");for(var a=!1;;)switch(r){case"hex":return x(this,e,t,n);case"utf8":case"utf-8":return A(this,e,t,n);case"ascii":return S(this,e,t,n);case"latin1":case"binary":return j(this,e,t,n);case"base64":return E(this,e,t,n);case"ucs2":case"ucs-2":case"utf16le":case"utf-16le":return O(this,e,t,n);default:if(a)throw new TypeError("Unknown encoding: "+r);r=(""+r).toLowerCase(),a=!0}},o.prototype.toJSON=function(){return{type:"Buffer",data:Array.prototype.slice.call(this._arr||this,0)}};var ee=4096;o.prototype.slice=function(e,t){var n=this.length;e=~~e,t=void 0===t?n:~~t,e<0?(e+=n,e<0&&(e=0)):e>n&&(e=n),t<0?(t+=n,t<0&&(t=0)):t>n&&(t=n),t<e&&(t=e);var r;if(o.TYPED_ARRAY_SUPPORT)r=this.subarray(e,t),r.__proto__=o.prototype;else{var i=t-e;r=new o(i,(void 0));for(var a=0;a<i;++a)r[a]=this[a+e]}return r},o.prototype.readUIntLE=function(e,t,n){e=0|e,t=0|t,n||R(e,t,this.length);for(var r=this[e],i=1,a=0;++a<t&&(i*=256);)r+=this[e+a]*i;return r},o.prototype.readUIntBE=function(e,t,n){e=0|e,t=0|t,n||R(e,t,this.length);for(var r=this[e+--t],i=1;t>0&&(i*=256);)r+=this[e+--t]*i;return r},o.prototype.readUInt8=function(e,t){return t||R(e,1,this.length),this[e]},o.prototype.readUInt16LE=function(e,t){return t||R(e,2,this.length),this[e]|this[e+1]<<8},o.prototype.readUInt16BE=function(e,t){return t||R(e,2,this.length),this[e]<<8|this[e+1]},o.prototype.readUInt32LE=function(e,t){return t||R(e,4,this.length),(this[e]|this[e+1]<<8|this[e+2]<<16)+16777216*this[e+3]},o.prototype.readUInt32BE=function(e,t){return t||R(e,4,this.length),16777216*this[e]+(this[e+1]<<16|this[e+2]<<8|this[e+3])},o.prototype.readIntLE=function(e,t,n){e=0|e,t=0|t,n||R(e,t,this.length);for(var r=this[e],i=1,a=0;++a<t&&(i*=256);)r+=this[e+a]*i;return i*=128,r>=i&&(r-=Math.pow(2,8*t)),r},o.prototype.readIntBE=function(e,t,n){e=0|e,t=0|t,n||R(e,t,this.length);for(var r=t,i=1,a=this[e+--r];r>0&&(i*=256);)a+=this[e+--r]*i;return i*=128,a>=i&&(a-=Math.pow(2,8*t)),a},o.prototype.readInt8=function(e,t){return t||R(e,1,this.length),128&this[e]?(255-this[e]+1)*-1:this[e]},o.prototype.readInt16LE=function(e,t){t||R(e,2,this.length);var n=this[e]|this[e+1]<<8;return 32768&n?4294901760|n:n},o.prototype.readInt16BE=function(e,t){t||R(e,2,this.length);var n=this[e+1]|this[e]<<8;return 32768&n?4294901760|n:n},o.prototype.readInt32LE=function(e,t){return t||R(e,4,this.length),this[e]|this[e+1]<<8|this[e+2]<<16|this[e+3]<<24},o.prototype.readInt32BE=function(e,t){return t||R(e,4,this.length),this[e]<<24|this[e+1]<<16|this[e+2]<<8|this[e+3]},o.prototype.readFloatLE=function(e,t){return t||R(e,4,this.length),X.read(this,e,!0,23,4)},o.prototype.readFloatBE=function(e,t){return t||R(e,4,this.length),X.read(this,e,!1,23,4)},o.prototype.readDoubleLE=function(e,t){return t||R(e,8,this.length),X.read(this,e,!0,52,8)},o.prototype.readDoubleBE=function(e,t){
+return t||R(e,8,this.length),X.read(this,e,!1,52,8)},o.prototype.writeUIntLE=function(e,t,n,r){if(e=+e,t=0|t,n=0|n,!r){var i=Math.pow(2,8*n)-1;U(this,e,t,n,i,0)}var a=1,o=0;for(this[t]=255&e;++o<n&&(a*=256);)this[t+o]=e/a&255;return t+n},o.prototype.writeUIntBE=function(e,t,n,r){if(e=+e,t=0|t,n=0|n,!r){var i=Math.pow(2,8*n)-1;U(this,e,t,n,i,0)}var a=n-1,o=1;for(this[t+a]=255&e;--a>=0&&(o*=256);)this[t+a]=e/o&255;return t+n},o.prototype.writeUInt8=function(e,t,n){return e=+e,t=0|t,n||U(this,e,t,1,255,0),o.TYPED_ARRAY_SUPPORT||(e=Math.floor(e)),this[t]=255&e,t+1},o.prototype.writeUInt16LE=function(e,t,n){return e=+e,t=0|t,n||U(this,e,t,2,65535,0),o.TYPED_ARRAY_SUPPORT?(this[t]=255&e,this[t+1]=e>>>8):P(this,e,t,!0),t+2},o.prototype.writeUInt16BE=function(e,t,n){return e=+e,t=0|t,n||U(this,e,t,2,65535,0),o.TYPED_ARRAY_SUPPORT?(this[t]=e>>>8,this[t+1]=255&e):P(this,e,t,!1),t+2},o.prototype.writeUInt32LE=function(e,t,n){return e=+e,t=0|t,n||U(this,e,t,4,4294967295,0),o.TYPED_ARRAY_SUPPORT?(this[t+3]=e>>>24,this[t+2]=e>>>16,this[t+1]=e>>>8,this[t]=255&e):q(this,e,t,!0),t+4},o.prototype.writeUInt32BE=function(e,t,n){return e=+e,t=0|t,n||U(this,e,t,4,4294967295,0),o.TYPED_ARRAY_SUPPORT?(this[t]=e>>>24,this[t+1]=e>>>16,this[t+2]=e>>>8,this[t+3]=255&e):q(this,e,t,!1),t+4},o.prototype.writeIntLE=function(e,t,n,r){if(e=+e,t=0|t,!r){var i=Math.pow(2,8*n-1);U(this,e,t,n,i-1,-i)}var a=0,o=1,s=0;for(this[t]=255&e;++a<n&&(o*=256);)e<0&&0===s&&0!==this[t+a-1]&&(s=1),this[t+a]=(e/o>>0)-s&255;return t+n},o.prototype.writeIntBE=function(e,t,n,r){if(e=+e,t=0|t,!r){var i=Math.pow(2,8*n-1);U(this,e,t,n,i-1,-i)}var a=n-1,o=1,s=0;for(this[t+a]=255&e;--a>=0&&(o*=256);)e<0&&0===s&&0!==this[t+a+1]&&(s=1),this[t+a]=(e/o>>0)-s&255;return t+n},o.prototype.writeInt8=function(e,t,n){return e=+e,t=0|t,n||U(this,e,t,1,127,-128),o.TYPED_ARRAY_SUPPORT||(e=Math.floor(e)),e<0&&(e=255+e+1),this[t]=255&e,t+1},o.prototype.writeInt16LE=function(e,t,n){return e=+e,t=0|t,n||U(this,e,t,2,32767,-32768),o.TYPED_ARRAY_SUPPORT?(this[t]=255&e,this[t+1]=e>>>8):P(this,e,t,!0),t+2},o.prototype.writeInt16BE=function(e,t,n){return e=+e,t=0|t,n||U(this,e,t,2,32767,-32768),o.TYPED_ARRAY_SUPPORT?(this[t]=e>>>8,this[t+1]=255&e):P(this,e,t,!1),t+2},o.prototype.writeInt32LE=function(e,t,n){return e=+e,t=0|t,n||U(this,e,t,4,2147483647,-2147483648),o.TYPED_ARRAY_SUPPORT?(this[t]=255&e,this[t+1]=e>>>8,this[t+2]=e>>>16,this[t+3]=e>>>24):q(this,e,t,!0),t+4},o.prototype.writeInt32BE=function(e,t,n){return e=+e,t=0|t,n||U(this,e,t,4,2147483647,-2147483648),e<0&&(e=4294967295+e+1),o.TYPED_ARRAY_SUPPORT?(this[t]=e>>>24,this[t+1]=e>>>16,this[t+2]=e>>>8,this[t+3]=255&e):q(this,e,t,!1),t+4},o.prototype.writeFloatLE=function(e,t,n){return N(this,e,t,!0,n)},o.prototype.writeFloatBE=function(e,t,n){return N(this,e,t,!1,n)},o.prototype.writeDoubleLE=function(e,t,n){return z(this,e,t,!0,n)},o.prototype.writeDoubleBE=function(e,t,n){return z(this,e,t,!1,n)},o.prototype.copy=function(e,t,n,r){if(n||(n=0),r||0===r||(r=this.length),t>=e.length&&(t=e.length),t||(t=0),r>0&&r<n&&(r=n),r===n)return 0;if(0===e.length||0===this.length)return 0;if(t<0)throw new RangeError("targetStart out of bounds");if(n<0||n>=this.length)throw new RangeError("sourceStart out of bounds");if(r<0)throw new RangeError("sourceEnd out of bounds");r>this.length&&(r=this.length),e.length-t<r-n&&(r=e.length-t+n);var i,a=r-n;if(this===e&&n<t&&t<r)for(i=a-1;i>=0;--i)e[i+t]=this[i+n];else if(a<1e3||!o.TYPED_ARRAY_SUPPORT)for(i=0;i<a;++i)e[i+t]=this[i+n];else Uint8Array.prototype.set.call(e,this.subarray(n,n+a),t);return a},o.prototype.fill=function(e,t,n,r){if("string"==typeof e){if("string"==typeof t?(r=t,t=0,n=this.length):"string"==typeof n&&(r=n,n=this.length),1===e.length){var i=e.charCodeAt(0);i<256&&(e=i)}if(void 0!==r&&"string"!=typeof r)throw new TypeError("encoding must be a string");if("string"==typeof r&&!o.isEncoding(r))throw new TypeError("Unknown encoding: "+r)}else"number"==typeof e&&(e=255&e);if(t<0||this.length<t||this.length<n)throw new RangeError("Out of range index");if(n<=t)return this;t>>>=0,n=void 0===n?this.length:n>>>0,e||(e=0);var a;if("number"==typeof e)for(a=t;a<n;++a)this[a]=e;else{var s=o.isBuffer(e)?e:H(new o(e,r).toString()),l=s.length;for(a=0;a<n-t;++a)this[a+t]=s[a%l]}return this};var te=/[^+\/0-9A-Za-z-_]/g}).call(this,"undefined"!=typeof global?global:"undefined"!=typeof self?self:"undefined"!=typeof window?window:{})},{"base64-js":2,ieee754:37,isarray:40}],6:[function(e,t,n){(function(e){function t(e){return Array.isArray?Array.isArray(e):"[object Array]"===g(e)}function r(e){return"boolean"==typeof e}function i(e){return null===e}function a(e){return null==e}function o(e){return"number"==typeof e}function s(e){return"string"==typeof e}function l(e){return"symbol"==typeof e}function u(e){return void 0===e}function c(e){return"[object RegExp]"===g(e)}function p(e){return"object"==typeof e&&null!==e}function h(e){return"[object Date]"===g(e)}function f(e){return"[object Error]"===g(e)||e instanceof Error}function d(e){return"function"==typeof e}function m(e){return null===e||"boolean"==typeof e||"number"==typeof e||"string"==typeof e||"symbol"==typeof e||"undefined"==typeof e}function g(e){return Object.prototype.toString.call(e)}n.isArray=t,n.isBoolean=r,n.isNull=i,n.isNullOrUndefined=a,n.isNumber=o,n.isString=s,n.isSymbol=l,n.isUndefined=u,n.isRegExp=c,n.isObject=p,n.isDate=h,n.isError=f,n.isFunction=d,n.isPrimitive=m,n.isBuffer=e.isBuffer}).call(this,{isBuffer:e("../../is-buffer/index.js")})},{"../../is-buffer/index.js":39}],7:[function(e,t,n){function r(e,t){if(e){var n,r="";for(var i in e)n=e[i],r&&(r+=" "),r+=!n&&p[i]?i:i+'="'+(t.decodeEntities?c.encodeXML(n):n)+'"';return r}}function i(e,t){"svg"===e.name&&(t={decodeEntities:t.decodeEntities,xmlMode:!0});var n="<"+e.name,i=r(e.attribs,t);return i&&(n+=" "+i),!t.xmlMode||e.children&&0!==e.children.length?(n+=">",e.children&&(n+=d(e.children,t)),f[e.name]&&!t.xmlMode||(n+="</"+e.name+">")):n+="/>",n}function a(e){return"<"+e.data+">"}function o(e,t){var n=e.data||"";return!t.decodeEntities||e.parent&&e.parent.name in h||(n=c.encodeXML(n)),n}function s(e){return"<![CDATA["+e.children[0].data+"]]>"}function l(e){return"<!--"+e.data+"-->"}var u=e("domelementtype"),c=e("entities"),p={__proto__:null,allowfullscreen:!0,async:!0,autofocus:!0,autoplay:!0,checked:!0,controls:!0,"default":!0,defer:!0,disabled:!0,hidden:!0,ismap:!0,loop:!0,multiple:!0,muted:!0,open:!0,readonly:!0,required:!0,reversed:!0,scoped:!0,seamless:!0,selected:!0,typemustmatch:!0},h={__proto__:null,style:!0,script:!0,xmp:!0,iframe:!0,noembed:!0,noframes:!0,plaintext:!0,noscript:!0},f={__proto__:null,area:!0,base:!0,basefont:!0,br:!0,col:!0,command:!0,embed:!0,frame:!0,hr:!0,img:!0,input:!0,isindex:!0,keygen:!0,link:!0,meta:!0,param:!0,source:!0,track:!0,wbr:!0},d=t.exports=function(e,t){Array.isArray(e)||e.cheerio||(e=[e]),t=t||{};for(var n="",r=0;r<e.length;r++){var c=e[r];n+="root"===c.type?d(c.children,t):u.isTag(c)?i(c,t):c.type===u.Directive?a(c):c.type===u.Comment?l(c):c.type===u.CDATA?s(c):o(c,t)}return n}},{domelementtype:8,entities:20}],8:[function(e,t,n){t.exports={Text:"text",Directive:"directive",Comment:"comment",Script:"script",Style:"style",Tag:"tag",CDATA:"cdata",isTag:function(e){return"tag"===e.type||"script"===e.type||"style"===e.type}}},{}],9:[function(e,t,n){t.exports={Text:"text",Directive:"directive",Comment:"comment",Script:"script",Style:"style",Tag:"tag",CDATA:"cdata",Doctype:"doctype",isTag:function(e){return"tag"===e.type||"script"===e.type||"style"===e.type}}},{}],10:[function(e,t,n){function r(e,t,n){"object"==typeof e?(n=t,t=e,e=null):"function"==typeof t&&(n=t,t=l),this._callback=e,this._options=t||l,this._elementCB=n,this.dom=[],this._done=!1,this._tagStack=[],this._parser=this._parser||null}var i=e("domelementtype"),a=/\s+/g,o=e("./lib/node"),s=e("./lib/element"),l={normalizeWhitespace:!1,withStartIndices:!1};r.prototype.onparserinit=function(e){this._parser=e},r.prototype.onreset=function(){r.call(this,this._callback,this._options,this._elementCB)},r.prototype.onend=function(){this._done||(this._done=!0,this._parser=null,this._handleCallback(null))},r.prototype._handleCallback=r.prototype.onerror=function(e){if("function"==typeof this._callback)this._callback(e,this.dom);else if(e)throw e},r.prototype.onclosetag=function(){var e=this._tagStack.pop();this._elementCB&&this._elementCB(e)},r.prototype._addDomElement=function(e){var t=this._tagStack[this._tagStack.length-1],n=t?t.children:this.dom,r=n[n.length-1];e.next=null,this._options.withStartIndices&&(e.startIndex=this._parser.startIndex),this._options.withDomLvl1&&(e.__proto__="tag"===e.type?s:o),r?(e.prev=r,r.next=e):e.prev=null,n.push(e),e.parent=t||null},r.prototype.onopentag=function(e,t){var n={type:"script"===e?i.Script:"style"===e?i.Style:i.Tag,name:e,attribs:t,children:[]};this._addDomElement(n),this._tagStack.push(n)},r.prototype.ontext=function(e){var t,n=this._options.normalizeWhitespace||this._options.ignoreWhitespace;!this._tagStack.length&&this.dom.length&&(t=this.dom[this.dom.length-1]).type===i.Text?n?t.data=(t.data+e).replace(a," "):t.data+=e:this._tagStack.length&&(t=this._tagStack[this._tagStack.length-1])&&(t=t.children[t.children.length-1])&&t.type===i.Text?n?t.data=(t.data+e).replace(a," "):t.data+=e:(n&&(e=e.replace(a," ")),this._addDomElement({data:e,type:i.Text}))},r.prototype.oncomment=function(e){var t=this._tagStack[this._tagStack.length-1];if(t&&t.type===i.Comment)return void(t.data+=e);var n={data:e,type:i.Comment};this._addDomElement(n),this._tagStack.push(n)},r.prototype.oncdatastart=function(){var e={children:[{data:"",type:i.Text}],type:i.CDATA};this._addDomElement(e),this._tagStack.push(e)},r.prototype.oncommentend=r.prototype.oncdataend=function(){this._tagStack.pop()},r.prototype.onprocessinginstruction=function(e,t){this._addDomElement({name:e,data:t,type:i.Directive})},t.exports=r},{"./lib/element":11,"./lib/node":12,domelementtype:9}],11:[function(e,t,n){var r=e("./node"),i=t.exports=Object.create(r),a={tagName:"name"};Object.keys(a).forEach(function(e){var t=a[e];Object.defineProperty(i,e,{get:function(){return this[t]||null},set:function(e){return this[t]=e,e}})})},{"./node":12}],12:[function(e,t,n){var r=t.exports={get firstChild(){var e=this.children;return e&&e[0]||null},get lastChild(){var e=this.children;return e&&e[e.length-1]||null},get nodeType(){return a[this.type]||a.element}},i={tagName:"name",childNodes:"children",parentNode:"parent",previousSibling:"prev",nextSibling:"next",nodeValue:"data"},a={element:1,text:3,cdata:4,comment:8};Object.keys(i).forEach(function(e){var t=i[e];Object.defineProperty(r,e,{get:function(){return this[t]||null},set:function(e){return this[t]=e,e}})})},{}],13:[function(e,t,n){var r=t.exports;[e("./lib/stringify"),e("./lib/traversal"),e("./lib/manipulation"),e("./lib/querying"),e("./lib/legacy"),e("./lib/helpers")].forEach(function(e){Object.keys(e).forEach(function(t){r[t]=e[t].bind(r)})})},{"./lib/helpers":14,"./lib/legacy":15,"./lib/manipulation":16,"./lib/querying":17,"./lib/stringify":18,"./lib/traversal":19}],14:[function(e,t,n){n.removeSubsets=function(e){for(var t,n,r,i=e.length;--i>-1;){for(t=n=e[i],e[i]=null,r=!0;n;){if(e.indexOf(n)>-1){r=!1,e.splice(i,1);break}n=n.parent}r&&(e[i]=t)}return e};var r={DISCONNECTED:1,PRECEDING:2,FOLLOWING:4,CONTAINS:8,CONTAINED_BY:16},i=n.compareDocumentPosition=function(e,t){var n,i,a,o,s,l,u=[],c=[];if(e===t)return 0;for(n=e;n;)u.unshift(n),n=n.parent;for(n=t;n;)c.unshift(n),n=n.parent;for(l=0;u[l]===c[l];)l++;return 0===l?r.DISCONNECTED:(i=u[l-1],a=i.children,o=u[l],s=c[l],a.indexOf(o)>a.indexOf(s)?i===t?r.FOLLOWING|r.CONTAINED_BY:r.FOLLOWING:i===e?r.PRECEDING|r.CONTAINS:r.PRECEDING)};n.uniqueSort=function(e){var t,n,a=e.length;for(e=e.slice();--a>-1;)t=e[a],n=e.indexOf(t),n>-1&&n<a&&e.splice(a,1);return e.sort(function(e,t){var n=i(e,t);return n&r.PRECEDING?-1:n&r.FOLLOWING?1:0}),e}},{}],15:[function(e,t,n){function r(e,t){return"function"==typeof t?function(n){return n.attribs&&t(n.attribs[e])}:function(n){return n.attribs&&n.attribs[e]===t}}function i(e,t){return function(n){return e(n)||t(n)}}var a=e("domelementtype"),o=n.isTag=a.isTag;n.testElement=function(e,t){for(var n in e)if(e.hasOwnProperty(n)){if("tag_name"===n){if(!o(t)||!e.tag_name(t.name))return!1}else if("tag_type"===n){if(!e.tag_type(t.type))return!1}else if("tag_contains"===n){if(o(t)||!e.tag_contains(t.data))return!1}else if(!t.attribs||!e[n](t.attribs[n]))return!1}else;return!0};var s={tag_name:function(e){return"function"==typeof e?function(t){return o(t)&&e(t.name)}:"*"===e?o:function(t){return o(t)&&t.name===e}},tag_type:function(e){return"function"==typeof e?function(t){return e(t.type)}:function(t){return t.type===e}},tag_contains:function(e){return"function"==typeof e?function(t){return!o(t)&&e(t.data)}:function(t){return!o(t)&&t.data===e}}};n.getElements=function(e,t,n,a){var o=Object.keys(e).map(function(t){var n=e[t];return t in s?s[t](n):r(t,n)});return 0===o.length?[]:this.filter(o.reduce(i),t,n,a)},n.getElementById=function(e,t,n){return Array.isArray(t)||(t=[t]),this.findOne(r("id",e),t,n!==!1)},n.getElementsByTagName=function(e,t,n,r){return this.filter(s.tag_name(e),t,n,r)},n.getElementsByTagType=function(e,t,n,r){return this.filter(s.tag_type(e),t,n,r)}},{domelementtype:9}],16:[function(e,t,n){n.removeElement=function(e){if(e.prev&&(e.prev.next=e.next),e.next&&(e.next.prev=e.prev),e.parent){var t=e.parent.children;t.splice(t.lastIndexOf(e),1)}},n.replaceElement=function(e,t){var n=t.prev=e.prev;n&&(n.next=t);var r=t.next=e.next;r&&(r.prev=t);var i=t.parent=e.parent;if(i){var a=i.children;a[a.lastIndexOf(e)]=t}},n.appendChild=function(e,t){if(t.parent=e,1!==e.children.push(t)){var n=e.children[e.children.length-2];n.next=t,t.prev=n,t.next=null}},n.append=function(e,t){var n=e.parent,r=e.next;if(t.next=r,t.prev=e,e.next=t,t.parent=n,r){if(r.prev=t,n){var i=n.children;i.splice(i.lastIndexOf(r),0,t)}}else n&&n.children.push(t)},n.prepend=function(e,t){var n=e.parent;if(n){var r=n.children;r.splice(r.lastIndexOf(e),0,t)}e.prev&&(e.prev.next=t),t.parent=n,t.prev=e.prev,t.next=e,e.prev=t}},{}],17:[function(e,t,n){function r(e,t,n,r){return Array.isArray(t)||(t=[t]),"number"==typeof r&&isFinite(r)||(r=1/0),i(e,t,n!==!1,r)}function i(e,t,n,r){for(var a,o=[],s=0,l=t.length;s<l&&!(e(t[s])&&(o.push(t[s]),--r<=0))&&(a=t[s].children,!(n&&a&&a.length>0&&(a=i(e,a,n,r),o=o.concat(a),r-=a.length,r<=0)));s++);return o}function a(e,t){for(var n=0,r=t.length;n<r;n++)if(e(t[n]))return t[n];return null}function o(e,t){for(var n=null,r=0,i=t.length;r<i&&!n;r++)u(t[r])&&(e(t[r])?n=t[r]:t[r].children.length>0&&(n=o(e,t[r].children)));return n}function s(e,t){for(var n=0,r=t.length;n<r;n++)if(u(t[n])&&(e(t[n])||t[n].children.length>0&&s(e,t[n].children)))return!0;return!1}function l(e,t){for(var n=[],r=0,i=t.length;r<i;r++)u(t[r])&&(e(t[r])&&n.push(t[r]),t[r].children.length>0&&(n=n.concat(l(e,t[r].children))));return n}var u=e("domelementtype").isTag;t.exports={filter:r,find:i,findOneChild:a,findOne:o,existsOne:s,findAll:l}},{domelementtype:9}],18:[function(e,t,n){function r(e,t){return e.children?e.children.map(function(e){return o(e,t)}).join(""):""}function i(e){return Array.isArray(e)?e.map(i).join(""):s(e)||e.type===a.CDATA?i(e.children):e.type===a.Text?e.data:""}var a=e("domelementtype"),o=e("dom-serializer"),s=a.isTag;t.exports={getInnerHTML:r,getOuterHTML:o,getText:i}},{"dom-serializer":7,domelementtype:9}],19:[function(e,t,n){var r=n.getChildren=function(e){return e.children},i=n.getParent=function(e){return e.parent};n.getSiblings=function(e){var t=i(e);return t?r(t):[e]},n.getAttributeValue=function(e,t){return e.attribs&&e.attribs[t]},n.hasAttrib=function(e,t){return!!e.attribs&&hasOwnProperty.call(e.attribs,t)},n.getName=function(e){return e.name}},{}],20:[function(e,t,n){var r=e("./lib/encode.js"),i=e("./lib/decode.js");n.decode=function(e,t){return(!t||t<=0?i.XML:i.HTML)(e)},n.decodeStrict=function(e,t){return(!t||t<=0?i.XML:i.HTMLStrict)(e)},n.encode=function(e,t){return(!t||t<=0?r.XML:r.HTML)(e)},n.encodeXML=r.XML,n.encodeHTML4=n.encodeHTML5=n.encodeHTML=r.HTML,n.decodeXML=n.decodeXMLStrict=i.XML,n.decodeHTML4=n.decodeHTML5=n.decodeHTML=i.HTML,n.decodeHTML4Strict=n.decodeHTML5Strict=n.decodeHTMLStrict=i.HTMLStrict,n.escape=r.escape},{"./lib/decode.js":21,"./lib/encode.js":23}],21:[function(e,t,n){function r(e){var t=Object.keys(e).join("|"),n=a(e);t+="|#[xX][\\da-fA-F]+|#\\d+";var r=new RegExp("&(?:"+t+");","g");return function(e){return String(e).replace(r,n)}}function i(e,t){return e<t?1:-1}function a(e){return function(t){return"#"===t.charAt(1)?u("X"===t.charAt(2)||"x"===t.charAt(2)?parseInt(t.substr(3),16):parseInt(t.substr(2),10)):e[t.slice(1,-1)]}}var o=e("../maps/entities.json"),s=e("../maps/legacy.json"),l=e("../maps/xml.json"),u=e("./decode_codepoint.js"),c=r(l),p=r(o),h=function(){function e(e){return";"!==e.substr(-1)&&(e+=";"),c(e)}for(var t=Object.keys(s).sort(i),n=Object.keys(o).sort(i),r=0,l=0;r<n.length;r++)t[l]===n[r]?(n[r]+=";?",l++):n[r]+=";";var u=new RegExp("&(?:"+n.join("|")+"|#[xX][\\da-fA-F]+;?|#\\d+;?)","g"),c=a(o);return function(t){return String(t).replace(u,e)}}();t.exports={XML:c,HTML:h,HTMLStrict:p}},{"../maps/entities.json":25,"../maps/legacy.json":26,"../maps/xml.json":27,"./decode_codepoint.js":22}],22:[function(e,t,n){function r(e){if(e>=55296&&e<=57343||e>1114111)return"�";e in i&&(e=i[e]);var t="";return e>65535&&(e-=65536,t+=String.fromCharCode(e>>>10&1023|55296),e=56320|1023&e),t+=String.fromCharCode(e)}var i=e("../maps/decode.json");t.exports=r},{"../maps/decode.json":24}],23:[function(e,t,n){function r(e){return Object.keys(e).sort().reduce(function(t,n){return t[e[n]]="&"+n+";",t},{})}function i(e){var t=[],n=[];return Object.keys(e).forEach(function(e){1===e.length?t.push("\\"+e):n.push(e)}),n.unshift("["+t.join("")+"]"),new RegExp(n.join("|"),"g")}function a(e){return"&#x"+e.charCodeAt(0).toString(16).toUpperCase()+";"}function o(e){var t=e.charCodeAt(0),n=e.charCodeAt(1),r=1024*(t-55296)+n-56320+65536;return"&#x"+r.toString(16).toUpperCase()+";"}function s(e,t){function n(t){return e[t]}return function(e){return e.replace(t,n).replace(d,o).replace(f,a)}}function l(e){return e.replace(m,a).replace(d,o).replace(f,a)}var u=r(e("../maps/xml.json")),c=i(u);n.XML=s(u,c);var p=r(e("../maps/entities.json")),h=i(p);n.HTML=s(p,h);var f=/[^\0-\x7F]/g,d=/[\uD800-\uDBFF][\uDC00-\uDFFF]/g,m=i(u);n.escape=l},{"../maps/entities.json":25,"../maps/xml.json":27}],24:[function(e,t,n){t.exports={0:65533,128:8364,130:8218,131:402,132:8222,133:8230,134:8224,135:8225,136:710,137:8240,138:352,139:8249,140:338,142:381,145:8216,146:8217,147:8220,148:8221,149:8226,150:8211,151:8212,152:732,153:8482,154:353,155:8250,156:339,158:382,159:376}},{}],25:[function(e,t,n){t.exports={Aacute:"Á",aacute:"á",Abreve:"Ă",abreve:"ă",ac:"∾",acd:"∿",acE:"∾̳",Acirc:"Â",acirc:"â",acute:"´",Acy:"А",acy:"а",AElig:"Æ",aelig:"æ",af:"⁡",Afr:"𝔄",afr:"𝔞",Agrave:"À",agrave:"à",alefsym:"ℵ",aleph:"ℵ",Alpha:"Α",alpha:"α",Amacr:"Ā",amacr:"ā",amalg:"⨿",amp:"&",AMP:"&",andand:"⩕",And:"⩓",and:"∧",andd:"⩜",andslope:"⩘",andv:"⩚",ang:"∠",ange:"⦤",angle:"∠",angmsdaa:"⦨",angmsdab:"⦩",angmsdac:"⦪",angmsdad:"⦫",angmsdae:"⦬",angmsdaf:"⦭",angmsdag:"⦮",angmsdah:"⦯",angmsd:"∡",angrt:"∟",angrtvb:"⊾",angrtvbd:"⦝",angsph:"∢",angst:"Å",angzarr:"⍼",Aogon:"Ą",aogon:"ą",Aopf:"𝔸",aopf:"𝕒",apacir:"⩯",ap:"≈",apE:"⩰",ape:"≊",apid:"≋",apos:"'",ApplyFunction:"⁡",approx:"≈",approxeq:"≊",Aring:"Å",aring:"å",Ascr:"𝒜",ascr:"𝒶",Assign:"≔",ast:"*",asymp:"≈",asympeq:"≍",Atilde:"Ã",atilde:"ã",Auml:"Ä",auml:"ä",awconint:"∳",awint:"⨑",backcong:"≌",backepsilon:"϶",backprime:"‵",backsim:"∽",backsimeq:"⋍",Backslash:"∖",Barv:"⫧",barvee:"⊽",barwed:"⌅",Barwed:"⌆",barwedge:"⌅",bbrk:"⎵",bbrktbrk:"⎶",bcong:"≌",Bcy:"Б",bcy:"б",bdquo:"„",becaus:"∵",because:"∵",Because:"∵",bemptyv:"⦰",bepsi:"϶",bernou:"ℬ",Bernoullis:"ℬ",Beta:"Β",beta:"β",beth:"ℶ",between:"≬",Bfr:"𝔅",bfr:"𝔟",bigcap:"⋂",bigcirc:"◯",bigcup:"⋃",bigodot:"⨀",bigoplus:"⨁",bigotimes:"⨂",bigsqcup:"⨆",bigstar:"★",bigtriangledown:"▽",bigtriangleup:"△",biguplus:"⨄",bigvee:"⋁",bigwedge:"⋀",bkarow:"⤍",blacklozenge:"⧫",blacksquare:"▪",blacktriangle:"▴",blacktriangledown:"▾",blacktriangleleft:"◂",blacktriangleright:"▸",blank:"␣",blk12:"▒",blk14:"░",blk34:"▓",block:"█",bne:"=⃥",bnequiv:"≡⃥",bNot:"⫭",bnot:"⌐",Bopf:"𝔹",bopf:"𝕓",bot:"⊥",bottom:"⊥",bowtie:"⋈",boxbox:"⧉",boxdl:"┐",boxdL:"╕",boxDl:"╖",boxDL:"╗",boxdr:"┌",boxdR:"╒",boxDr:"╓",boxDR:"╔",boxh:"─",boxH:"═",boxhd:"┬",boxHd:"╤",boxhD:"╥",boxHD:"╦",boxhu:"┴",boxHu:"╧",boxhU:"╨",boxHU:"╩",boxminus:"⊟",boxplus:"⊞",boxtimes:"⊠",boxul:"┘",boxuL:"╛",boxUl:"╜",boxUL:"╝",boxur:"└",boxuR:"╘",boxUr:"╙",boxUR:"╚",boxv:"│",boxV:"║",boxvh:"┼",boxvH:"╪",boxVh:"╫",boxVH:"╬",boxvl:"┤",boxvL:"╡",boxVl:"╢",boxVL:"╣",boxvr:"├",boxvR:"╞",boxVr:"╟",boxVR:"╠",bprime:"‵",breve:"˘",Breve:"˘",brvbar:"¦",bscr:"𝒷",Bscr:"ℬ",bsemi:"⁏",bsim:"∽",bsime:"⋍",bsolb:"⧅",bsol:"\\",bsolhsub:"⟈",bull:"•",bullet:"•",bump:"≎",bumpE:"⪮",bumpe:"≏",Bumpeq:"≎",bumpeq:"≏",Cacute:"Ć",cacute:"ć",capand:"⩄",capbrcup:"⩉",capcap:"⩋",cap:"∩",Cap:"⋒",capcup:"⩇",capdot:"⩀",CapitalDifferentialD:"ⅅ",caps:"∩︀",caret:"⁁",caron:"ˇ",Cayleys:"ℭ",ccaps:"⩍",Ccaron:"Č",ccaron:"č",Ccedil:"Ç",ccedil:"ç",Ccirc:"Ĉ",ccirc:"ĉ",Cconint:"∰",ccups:"⩌",ccupssm:"⩐",Cdot:"Ċ",cdot:"ċ",cedil:"¸",Cedilla:"¸",cemptyv:"⦲",cent:"¢",centerdot:"·",CenterDot:"·",cfr:"𝔠",Cfr:"ℭ",CHcy:"Ч",chcy:"ч",check:"✓",checkmark:"✓",Chi:"Χ",chi:"χ",circ:"ˆ",circeq:"≗",circlearrowleft:"↺",circlearrowright:"↻",circledast:"⊛",circledcirc:"⊚",circleddash:"⊝",CircleDot:"⊙",circledR:"®",circledS:"Ⓢ",CircleMinus:"⊖",CirclePlus:"⊕",CircleTimes:"⊗",cir:"○",cirE:"⧃",cire:"≗",cirfnint:"⨐",cirmid:"⫯",cirscir:"⧂",ClockwiseContourIntegral:"∲",CloseCurlyDoubleQuote:"”",CloseCurlyQuote:"’",clubs:"♣",clubsuit:"♣",colon:":",Colon:"∷",Colone:"⩴",colone:"≔",coloneq:"≔",comma:",",commat:"@",comp:"∁",compfn:"∘",complement:"∁",complexes:"ℂ",cong:"≅",congdot:"⩭",Congruent:"≡",conint:"∮",Conint:"∯",ContourIntegral:"∮",copf:"𝕔",Copf:"ℂ",coprod:"∐",Coproduct:"∐",copy:"©",COPY:"©",copysr:"℗",CounterClockwiseContourIntegral:"∳",crarr:"↵",cross:"✗",Cross:"⨯",Cscr:"𝒞",cscr:"𝒸",csub:"⫏",csube:"⫑",csup:"⫐",csupe:"⫒",ctdot:"⋯",cudarrl:"⤸",cudarrr:"⤵",cuepr:"⋞",cuesc:"⋟",cularr:"↶",cularrp:"⤽",cupbrcap:"⩈",cupcap:"⩆",CupCap:"≍",cup:"∪",Cup:"⋓",cupcup:"⩊",cupdot:"⊍",cupor:"⩅",cups:"∪︀",curarr:"↷",curarrm:"⤼",curlyeqprec:"⋞",curlyeqsucc:"⋟",curlyvee:"⋎",curlywedge:"⋏",curren:"¤",curvearrowleft:"↶",curvearrowright:"↷",cuvee:"⋎",cuwed:"⋏",cwconint:"∲",cwint:"∱",cylcty:"⌭",dagger:"†",Dagger:"‡",daleth:"ℸ",darr:"↓",Darr:"↡",dArr:"⇓",dash:"‐",Dashv:"⫤",dashv:"⊣",dbkarow:"⤏",dblac:"˝",Dcaron:"Ď",dcaron:"ď",Dcy:"Д",dcy:"д",ddagger:"‡",ddarr:"⇊",DD:"ⅅ",dd:"ⅆ",DDotrahd:"⤑",ddotseq:"⩷",deg:"°",Del:"∇",Delta:"Δ",delta:"δ",demptyv:"⦱",dfisht:"⥿",Dfr:"𝔇",dfr:"𝔡",dHar:"⥥",dharl:"⇃",dharr:"⇂",DiacriticalAcute:"´",DiacriticalDot:"˙",DiacriticalDoubleAcute:"˝",DiacriticalGrave:"`",DiacriticalTilde:"˜",diam:"⋄",diamond:"⋄",Diamond:"⋄",diamondsuit:"♦",diams:"♦",die:"¨",DifferentialD:"ⅆ",digamma:"ϝ",disin:"⋲",div:"÷",divide:"÷",divideontimes:"⋇",divonx:"⋇",DJcy:"Ђ",djcy:"ђ",dlcorn:"⌞",dlcrop:"⌍",dollar:"$",Dopf:"𝔻",dopf:"𝕕",Dot:"¨",dot:"˙",DotDot:"⃜",doteq:"≐",doteqdot:"≑",DotEqual:"≐",dotminus:"∸",dotplus:"∔",dotsquare:"⊡",doublebarwedge:"⌆",DoubleContourIntegral:"∯",DoubleDot:"¨",DoubleDownArrow:"⇓",DoubleLeftArrow:"⇐",DoubleLeftRightArrow:"⇔",DoubleLeftTee:"⫤",DoubleLongLeftArrow:"⟸",DoubleLongLeftRightArrow:"⟺",DoubleLongRightArrow:"⟹",DoubleRightArrow:"⇒",DoubleRightTee:"⊨",DoubleUpArrow:"⇑",DoubleUpDownArrow:"⇕",DoubleVerticalBar:"∥",DownArrowBar:"⤓",downarrow:"↓",DownArrow:"↓",Downarrow:"⇓",DownArrowUpArrow:"⇵",DownBreve:"̑",downdownarrows:"⇊",downharpoonleft:"⇃",downharpoonright:"⇂",DownLeftRightVector:"⥐",DownLeftTeeVector:"⥞",DownLeftVectorBar:"⥖",DownLeftVector:"↽",DownRightTeeVector:"⥟",DownRightVectorBar:"⥗",DownRightVector:"⇁",DownTeeArrow:"↧",DownTee:"⊤",drbkarow:"⤐",drcorn:"⌟",drcrop:"⌌",Dscr:"𝒟",dscr:"𝒹",DScy:"Ѕ",dscy:"ѕ",dsol:"⧶",Dstrok:"Đ",dstrok:"đ",dtdot:"⋱",dtri:"▿",dtrif:"▾",duarr:"⇵",duhar:"⥯",dwangle:"⦦",DZcy:"Џ",dzcy:"џ",dzigrarr:"⟿",Eacute:"É",eacute:"é",easter:"⩮",Ecaron:"Ě",ecaron:"ě",Ecirc:"Ê",ecirc:"ê",ecir:"≖",ecolon:"≕",Ecy:"Э",ecy:"э",eDDot:"⩷",Edot:"Ė",edot:"ė",eDot:"≑",ee:"ⅇ",efDot:"≒",Efr:"𝔈",efr:"𝔢",eg:"⪚",Egrave:"È",egrave:"è",egs:"⪖",egsdot:"⪘",el:"⪙",Element:"∈",elinters:"⏧",ell:"ℓ",els:"⪕",elsdot:"⪗",Emacr:"Ē",emacr:"ē",empty:"∅",emptyset:"∅",EmptySmallSquare:"◻",emptyv:"∅",EmptyVerySmallSquare:"▫",emsp13:" ",emsp14:" ",emsp:" ",ENG:"Ŋ",eng:"ŋ",ensp:" ",Eogon:"Ę",eogon:"ę",Eopf:"𝔼",eopf:"𝕖",epar:"⋕",eparsl:"⧣",eplus:"⩱",epsi:"ε",Epsilon:"Ε",epsilon:"ε",epsiv:"ϵ",eqcirc:"≖",eqcolon:"≕",eqsim:"≂",eqslantgtr:"⪖",eqslantless:"⪕",Equal:"⩵",equals:"=",EqualTilde:"≂",equest:"≟",Equilibrium:"⇌",equiv:"≡",equivDD:"⩸",eqvparsl:"⧥",erarr:"⥱",erDot:"≓",escr:"ℯ",Escr:"ℰ",esdot:"≐",Esim:"⩳",esim:"≂",Eta:"Η",eta:"η",ETH:"Ð",eth:"ð",Euml:"Ë",euml:"ë",euro:"€",excl:"!",exist:"∃",Exists:"∃",expectation:"ℰ",exponentiale:"ⅇ",ExponentialE:"ⅇ",fallingdotseq:"≒",Fcy:"Ф",fcy:"ф",female:"♀",ffilig:"ffi",fflig:"ff",ffllig:"ffl",Ffr:"𝔉",ffr:"𝔣",filig:"fi",FilledSmallSquare:"◼",FilledVerySmallSquare:"▪",fjlig:"fj",flat:"♭",fllig:"fl",fltns:"▱",fnof:"ƒ",Fopf:"𝔽",fopf:"𝕗",forall:"∀",ForAll:"∀",fork:"⋔",forkv:"⫙",Fouriertrf:"ℱ",fpartint:"⨍",frac12:"½",frac13:"⅓",frac14:"¼",frac15:"⅕",frac16:"⅙",frac18:"⅛",frac23:"⅔",frac25:"⅖",frac34:"¾",frac35:"⅗",frac38:"⅜",frac45:"⅘",frac56:"⅚",frac58:"⅝",frac78:"⅞",frasl:"⁄",frown:"⌢",fscr:"𝒻",Fscr:"ℱ",gacute:"ǵ",Gamma:"Γ",gamma:"γ",Gammad:"Ϝ",gammad:"ϝ",gap:"⪆",Gbreve:"Ğ",gbreve:"ğ",Gcedil:"Ģ",Gcirc:"Ĝ",gcirc:"ĝ",Gcy:"Г",gcy:"г",Gdot:"Ġ",gdot:"ġ",ge:"≥",gE:"≧",gEl:"⪌",gel:"⋛",geq:"≥",geqq:"≧",geqslant:"⩾",gescc:"⪩",ges:"⩾",gesdot:"⪀",gesdoto:"⪂",gesdotol:"⪄",gesl:"⋛︀",gesles:"⪔",Gfr:"𝔊",gfr:"𝔤",gg:"≫",Gg:"⋙",ggg:"⋙",gimel:"ℷ",GJcy:"Ѓ",gjcy:"ѓ",gla:"⪥",gl:"≷",glE:"⪒",glj:"⪤",gnap:"⪊",gnapprox:"⪊",gne:"⪈",gnE:"≩",gneq:"⪈",gneqq:"≩",gnsim:"⋧",Gopf:"𝔾",gopf:"𝕘",grave:"`",GreaterEqual:"≥",GreaterEqualLess:"⋛",GreaterFullEqual:"≧",GreaterGreater:"⪢",GreaterLess:"≷",GreaterSlantEqual:"⩾",GreaterTilde:"≳",Gscr:"𝒢",gscr:"ℊ",gsim:"≳",gsime:"⪎",gsiml:"⪐",gtcc:"⪧",gtcir:"⩺",gt:">",GT:">",Gt:"≫",gtdot:"⋗",gtlPar:"⦕",gtquest:"⩼",gtrapprox:"⪆",gtrarr:"⥸",gtrdot:"⋗",gtreqless:"⋛",gtreqqless:"⪌",gtrless:"≷",gtrsim:"≳",gvertneqq:"≩︀",gvnE:"≩︀",Hacek:"ˇ",hairsp:" ",half:"½",hamilt:"ℋ",HARDcy:"Ъ",hardcy:"ъ",harrcir:"⥈",harr:"↔",hArr:"⇔",harrw:"↭",Hat:"^",hbar:"ℏ",Hcirc:"Ĥ",hcirc:"ĥ",hearts:"♥",heartsuit:"♥",hellip:"…",hercon:"⊹",hfr:"𝔥",Hfr:"ℌ",HilbertSpace:"ℋ",hksearow:"⤥",hkswarow:"⤦",hoarr:"⇿",homtht:"∻",hookleftarrow:"↩",hookrightarrow:"↪",hopf:"𝕙",Hopf:"ℍ",horbar:"―",HorizontalLine:"─",hscr:"𝒽",Hscr:"ℋ",hslash:"ℏ",Hstrok:"Ħ",hstrok:"ħ",HumpDownHump:"≎",HumpEqual:"≏",hybull:"⁃",hyphen:"‐",Iacute:"Í",iacute:"í",ic:"⁣",Icirc:"Î",icirc:"î",Icy:"И",icy:"и",Idot:"İ",IEcy:"Е",iecy:"е",iexcl:"¡",iff:"⇔",ifr:"𝔦",Ifr:"ℑ",Igrave:"Ì",igrave:"ì",ii:"ⅈ",iiiint:"⨌",iiint:"∭",iinfin:"⧜",iiota:"℩",IJlig:"IJ",ijlig:"ij",Imacr:"Ī",imacr:"ī",image:"ℑ",ImaginaryI:"ⅈ",imagline:"ℐ",imagpart:"ℑ",imath:"ı",Im:"ℑ",imof:"⊷",imped:"Ƶ",Implies:"⇒",incare:"℅","in":"∈",infin:"∞",infintie:"⧝",inodot:"ı",intcal:"⊺","int":"∫",Int:"∬",integers:"ℤ",Integral:"∫",intercal:"⊺",Intersection:"⋂",intlarhk:"⨗",intprod:"⨼",InvisibleComma:"⁣",InvisibleTimes:"⁢",IOcy:"Ё",iocy:"ё",Iogon:"Į",iogon:"į",Iopf:"𝕀",iopf:"𝕚",Iota:"Ι",iota:"ι",iprod:"⨼",iquest:"¿",iscr:"𝒾",Iscr:"ℐ",isin:"∈",isindot:"⋵",isinE:"⋹",isins:"⋴",isinsv:"⋳",isinv:"∈",it:"⁢",Itilde:"Ĩ",itilde:"ĩ",Iukcy:"І",iukcy:"і",Iuml:"Ï",iuml:"ï",Jcirc:"Ĵ",jcirc:"ĵ",Jcy:"Й",jcy:"й",Jfr:"𝔍",jfr:"𝔧",jmath:"ȷ",Jopf:"𝕁",jopf:"𝕛",Jscr:"𝒥",jscr:"𝒿",Jsercy:"Ј",jsercy:"ј",Jukcy:"Є",jukcy:"є",Kappa:"Κ",kappa:"κ",kappav:"ϰ",Kcedil:"Ķ",kcedil:"ķ",Kcy:"К",kcy:"к",Kfr:"𝔎",kfr:"𝔨",kgreen:"ĸ",KHcy:"Х",khcy:"х",KJcy:"Ќ",kjcy:"ќ",Kopf:"𝕂",kopf:"𝕜",Kscr:"𝒦",kscr:"𝓀",lAarr:"⇚",Lacute:"Ĺ",lacute:"ĺ",laemptyv:"⦴",lagran:"ℒ",Lambda:"Λ",lambda:"λ",lang:"⟨",Lang:"⟪",langd:"⦑",langle:"⟨",lap:"⪅",Laplacetrf:"ℒ",laquo:"«",larrb:"⇤",larrbfs:"⤟",larr:"←",Larr:"↞",lArr:"⇐",larrfs:"⤝",larrhk:"↩",larrlp:"↫",larrpl:"⤹",larrsim:"⥳",larrtl:"↢",latail:"⤙",lAtail:"⤛",lat:"⪫",late:"⪭",lates:"⪭︀",lbarr:"⤌",lBarr:"⤎",lbbrk:"❲",lbrace:"{",lbrack:"[",lbrke:"⦋",lbrksld:"⦏",lbrkslu:"⦍",Lcaron:"Ľ",lcaron:"ľ",Lcedil:"Ļ",lcedil:"ļ",lceil:"⌈",lcub:"{",Lcy:"Л",lcy:"л",ldca:"⤶",ldquo:"“",ldquor:"„",ldrdhar:"⥧",ldrushar:"⥋",ldsh:"↲",le:"≤",lE:"≦",LeftAngleBracket:"⟨",LeftArrowBar:"⇤",leftarrow:"←",LeftArrow:"←",Leftarrow:"⇐",LeftArrowRightArrow:"⇆",leftarrowtail:"↢",LeftCeiling:"⌈",LeftDoubleBracket:"⟦",LeftDownTeeVector:"⥡",LeftDownVectorBar:"⥙",LeftDownVector:"⇃",LeftFloor:"⌊",leftharpoondown:"↽",leftharpoonup:"↼",leftleftarrows:"⇇",leftrightarrow:"↔",LeftRightArrow:"↔",Leftrightarrow:"⇔",leftrightarrows:"⇆",leftrightharpoons:"⇋",leftrightsquigarrow:"↭",LeftRightVector:"⥎",LeftTeeArrow:"↤",LeftTee:"⊣",LeftTeeVector:"⥚",leftthreetimes:"⋋",LeftTriangleBar:"⧏",LeftTriangle:"⊲",LeftTriangleEqual:"⊴",LeftUpDownVector:"⥑",LeftUpTeeVector:"⥠",LeftUpVectorBar:"⥘",LeftUpVector:"↿",LeftVectorBar:"⥒",LeftVector:"↼",lEg:"⪋",leg:"⋚",leq:"≤",leqq:"≦",leqslant:"⩽",lescc:"⪨",les:"⩽",lesdot:"⩿",lesdoto:"⪁",lesdotor:"⪃",lesg:"⋚︀",lesges:"⪓",lessapprox:"⪅",lessdot:"⋖",lesseqgtr:"⋚",lesseqqgtr:"⪋",LessEqualGreater:"⋚",LessFullEqual:"≦",LessGreater:"≶",lessgtr:"≶",LessLess:"⪡",lesssim:"≲",LessSlantEqual:"⩽",LessTilde:"≲",lfisht:"⥼",lfloor:"⌊",Lfr:"𝔏",lfr:"𝔩",lg:"≶",lgE:"⪑",lHar:"⥢",lhard:"↽",lharu:"↼",lharul:"⥪",lhblk:"▄",LJcy:"Љ",ljcy:"љ",llarr:"⇇",ll:"≪",Ll:"⋘",llcorner:"⌞",Lleftarrow:"⇚",llhard:"⥫",lltri:"◺",Lmidot:"Ŀ",lmidot:"ŀ",lmoustache:"⎰",lmoust:"⎰",lnap:"⪉",lnapprox:"⪉",lne:"⪇",lnE:"≨",lneq:"⪇",lneqq:"≨",lnsim:"⋦",loang:"⟬",loarr:"⇽",lobrk:"⟦",longleftarrow:"⟵",LongLeftArrow:"⟵",Longleftarrow:"⟸",longleftrightarrow:"⟷",LongLeftRightArrow:"⟷",Longleftrightarrow:"⟺",longmapsto:"⟼",longrightarrow:"⟶",LongRightArrow:"⟶",Longrightarrow:"⟹",looparrowleft:"↫",looparrowright:"↬",lopar:"⦅",Lopf:"𝕃",lopf:"𝕝",loplus:"⨭",lotimes:"⨴",lowast:"∗",lowbar:"_",LowerLeftArrow:"↙",LowerRightArrow:"↘",loz:"◊",lozenge:"◊",lozf:"⧫",lpar:"(",lparlt:"⦓",lrarr:"⇆",lrcorner:"⌟",lrhar:"⇋",lrhard:"⥭",lrm:"‎",lrtri:"⊿",lsaquo:"‹",lscr:"𝓁",Lscr:"ℒ",lsh:"↰",Lsh:"↰",lsim:"≲",lsime:"⪍",lsimg:"⪏",lsqb:"[",lsquo:"‘",lsquor:"‚",Lstrok:"Ł",lstrok:"ł",ltcc:"⪦",ltcir:"⩹",lt:"<",LT:"<",Lt:"≪",ltdot:"⋖",lthree:"⋋",ltimes:"⋉",ltlarr:"⥶",ltquest:"⩻",ltri:"◃",ltrie:"⊴",ltrif:"◂",ltrPar:"⦖",lurdshar:"⥊",luruhar:"⥦",lvertneqq:"≨︀",lvnE:"≨︀",macr:"¯",male:"♂",malt:"✠",maltese:"✠",Map:"⤅",map:"↦",mapsto:"↦",mapstodown:"↧",mapstoleft:"↤",mapstoup:"↥",marker:"▮",mcomma:"⨩",Mcy:"М",mcy:"м",mdash:"—",mDDot:"∺",measuredangle:"∡",MediumSpace:" ",Mellintrf:"ℳ",Mfr:"𝔐",mfr:"𝔪",mho:"℧",micro:"µ",midast:"*",midcir:"⫰",mid:"∣",middot:"·",minusb:"⊟",minus:"−",minusd:"∸",minusdu:"⨪",MinusPlus:"∓",mlcp:"⫛",mldr:"…",mnplus:"∓",models:"⊧",Mopf:"𝕄",mopf:"𝕞",mp:"∓",mscr:"𝓂",Mscr:"ℳ",mstpos:"∾",Mu:"Μ",mu:"μ",multimap:"⊸",mumap:"⊸",nabla:"∇",Nacute:"Ń",nacute:"ń",nang:"∠⃒",nap:"≉",napE:"⩰̸",napid:"≋̸",napos:"ʼn",napprox:"≉",natural:"♮",naturals:"ℕ",natur:"♮",nbsp:" ",nbump:"≎̸",nbumpe:"≏̸",ncap:"⩃",Ncaron:"Ň",ncaron:"ň",Ncedil:"Ņ",ncedil:"ņ",ncong:"≇",ncongdot:"⩭̸",ncup:"⩂",Ncy:"Н",ncy:"н",ndash:"–",nearhk:"⤤",nearr:"↗",neArr:"⇗",nearrow:"↗",ne:"≠",nedot:"≐̸",NegativeMediumSpace:"​",NegativeThickSpace:"​",NegativeThinSpace:"​",NegativeVeryThinSpace:"​",nequiv:"≢",nesear:"⤨",nesim:"≂̸",NestedGreaterGreater:"≫",NestedLessLess:"≪",NewLine:"\n",nexist:"∄",nexists:"∄",Nfr:"𝔑",nfr:"𝔫",ngE:"≧̸",nge:"≱",ngeq:"≱",ngeqq:"≧̸",ngeqslant:"⩾̸",nges:"⩾̸",nGg:"⋙̸",ngsim:"≵",nGt:"≫⃒",ngt:"≯",ngtr:"≯",nGtv:"≫̸",nharr:"↮",nhArr:"⇎",nhpar:"⫲",ni:"∋",nis:"⋼",nisd:"⋺",niv:"∋",NJcy:"Њ",njcy:"њ",nlarr:"↚",nlArr:"⇍",nldr:"‥",
+nlE:"≦̸",nle:"≰",nleftarrow:"↚",nLeftarrow:"⇍",nleftrightarrow:"↮",nLeftrightarrow:"⇎",nleq:"≰",nleqq:"≦̸",nleqslant:"⩽̸",nles:"⩽̸",nless:"≮",nLl:"⋘̸",nlsim:"≴",nLt:"≪⃒",nlt:"≮",nltri:"⋪",nltrie:"⋬",nLtv:"≪̸",nmid:"∤",NoBreak:"⁠",NonBreakingSpace:" ",nopf:"𝕟",Nopf:"ℕ",Not:"⫬",not:"¬",NotCongruent:"≢",NotCupCap:"≭",NotDoubleVerticalBar:"∦",NotElement:"∉",NotEqual:"≠",NotEqualTilde:"≂̸",NotExists:"∄",NotGreater:"≯",NotGreaterEqual:"≱",NotGreaterFullEqual:"≧̸",NotGreaterGreater:"≫̸",NotGreaterLess:"≹",NotGreaterSlantEqual:"⩾̸",NotGreaterTilde:"≵",NotHumpDownHump:"≎̸",NotHumpEqual:"≏̸",notin:"∉",notindot:"⋵̸",notinE:"⋹̸",notinva:"∉",notinvb:"⋷",notinvc:"⋶",NotLeftTriangleBar:"⧏̸",NotLeftTriangle:"⋪",NotLeftTriangleEqual:"⋬",NotLess:"≮",NotLessEqual:"≰",NotLessGreater:"≸",NotLessLess:"≪̸",NotLessSlantEqual:"⩽̸",NotLessTilde:"≴",NotNestedGreaterGreater:"⪢̸",NotNestedLessLess:"⪡̸",notni:"∌",notniva:"∌",notnivb:"⋾",notnivc:"⋽",NotPrecedes:"⊀",NotPrecedesEqual:"⪯̸",NotPrecedesSlantEqual:"⋠",NotReverseElement:"∌",NotRightTriangleBar:"⧐̸",NotRightTriangle:"⋫",NotRightTriangleEqual:"⋭",NotSquareSubset:"⊏̸",NotSquareSubsetEqual:"⋢",NotSquareSuperset:"⊐̸",NotSquareSupersetEqual:"⋣",NotSubset:"⊂⃒",NotSubsetEqual:"⊈",NotSucceeds:"⊁",NotSucceedsEqual:"⪰̸",NotSucceedsSlantEqual:"⋡",NotSucceedsTilde:"≿̸",NotSuperset:"⊃⃒",NotSupersetEqual:"⊉",NotTilde:"≁",NotTildeEqual:"≄",NotTildeFullEqual:"≇",NotTildeTilde:"≉",NotVerticalBar:"∤",nparallel:"∦",npar:"∦",nparsl:"⫽⃥",npart:"∂̸",npolint:"⨔",npr:"⊀",nprcue:"⋠",nprec:"⊀",npreceq:"⪯̸",npre:"⪯̸",nrarrc:"⤳̸",nrarr:"↛",nrArr:"⇏",nrarrw:"↝̸",nrightarrow:"↛",nRightarrow:"⇏",nrtri:"⋫",nrtrie:"⋭",nsc:"⊁",nsccue:"⋡",nsce:"⪰̸",Nscr:"𝒩",nscr:"𝓃",nshortmid:"∤",nshortparallel:"∦",nsim:"≁",nsime:"≄",nsimeq:"≄",nsmid:"∤",nspar:"∦",nsqsube:"⋢",nsqsupe:"⋣",nsub:"⊄",nsubE:"⫅̸",nsube:"⊈",nsubset:"⊂⃒",nsubseteq:"⊈",nsubseteqq:"⫅̸",nsucc:"⊁",nsucceq:"⪰̸",nsup:"⊅",nsupE:"⫆̸",nsupe:"⊉",nsupset:"⊃⃒",nsupseteq:"⊉",nsupseteqq:"⫆̸",ntgl:"≹",Ntilde:"Ñ",ntilde:"ñ",ntlg:"≸",ntriangleleft:"⋪",ntrianglelefteq:"⋬",ntriangleright:"⋫",ntrianglerighteq:"⋭",Nu:"Ν",nu:"ν",num:"#",numero:"№",numsp:" ",nvap:"≍⃒",nvdash:"⊬",nvDash:"⊭",nVdash:"⊮",nVDash:"⊯",nvge:"≥⃒",nvgt:">⃒",nvHarr:"⤄",nvinfin:"⧞",nvlArr:"⤂",nvle:"≤⃒",nvlt:"<⃒",nvltrie:"⊴⃒",nvrArr:"⤃",nvrtrie:"⊵⃒",nvsim:"∼⃒",nwarhk:"⤣",nwarr:"↖",nwArr:"⇖",nwarrow:"↖",nwnear:"⤧",Oacute:"Ó",oacute:"ó",oast:"⊛",Ocirc:"Ô",ocirc:"ô",ocir:"⊚",Ocy:"О",ocy:"о",odash:"⊝",Odblac:"Ő",odblac:"ő",odiv:"⨸",odot:"⊙",odsold:"⦼",OElig:"Œ",oelig:"œ",ofcir:"⦿",Ofr:"𝔒",ofr:"𝔬",ogon:"˛",Ograve:"Ò",ograve:"ò",ogt:"⧁",ohbar:"⦵",ohm:"Ω",oint:"∮",olarr:"↺",olcir:"⦾",olcross:"⦻",oline:"‾",olt:"⧀",Omacr:"Ō",omacr:"ō",Omega:"Ω",omega:"ω",Omicron:"Ο",omicron:"ο",omid:"⦶",ominus:"⊖",Oopf:"𝕆",oopf:"𝕠",opar:"⦷",OpenCurlyDoubleQuote:"“",OpenCurlyQuote:"‘",operp:"⦹",oplus:"⊕",orarr:"↻",Or:"⩔",or:"∨",ord:"⩝",order:"ℴ",orderof:"ℴ",ordf:"ª",ordm:"º",origof:"⊶",oror:"⩖",orslope:"⩗",orv:"⩛",oS:"Ⓢ",Oscr:"𝒪",oscr:"ℴ",Oslash:"Ø",oslash:"ø",osol:"⊘",Otilde:"Õ",otilde:"õ",otimesas:"⨶",Otimes:"⨷",otimes:"⊗",Ouml:"Ö",ouml:"ö",ovbar:"⌽",OverBar:"‾",OverBrace:"⏞",OverBracket:"⎴",OverParenthesis:"⏜",para:"¶",parallel:"∥",par:"∥",parsim:"⫳",parsl:"⫽",part:"∂",PartialD:"∂",Pcy:"П",pcy:"п",percnt:"%",period:".",permil:"‰",perp:"⊥",pertenk:"‱",Pfr:"𝔓",pfr:"𝔭",Phi:"Φ",phi:"φ",phiv:"ϕ",phmmat:"ℳ",phone:"☎",Pi:"Π",pi:"π",pitchfork:"⋔",piv:"ϖ",planck:"ℏ",planckh:"ℎ",plankv:"ℏ",plusacir:"⨣",plusb:"⊞",pluscir:"⨢",plus:"+",plusdo:"∔",plusdu:"⨥",pluse:"⩲",PlusMinus:"±",plusmn:"±",plussim:"⨦",plustwo:"⨧",pm:"±",Poincareplane:"ℌ",pointint:"⨕",popf:"𝕡",Popf:"ℙ",pound:"£",prap:"⪷",Pr:"⪻",pr:"≺",prcue:"≼",precapprox:"⪷",prec:"≺",preccurlyeq:"≼",Precedes:"≺",PrecedesEqual:"⪯",PrecedesSlantEqual:"≼",PrecedesTilde:"≾",preceq:"⪯",precnapprox:"⪹",precneqq:"⪵",precnsim:"⋨",pre:"⪯",prE:"⪳",precsim:"≾",prime:"′",Prime:"″",primes:"ℙ",prnap:"⪹",prnE:"⪵",prnsim:"⋨",prod:"∏",Product:"∏",profalar:"⌮",profline:"⌒",profsurf:"⌓",prop:"∝",Proportional:"∝",Proportion:"∷",propto:"∝",prsim:"≾",prurel:"⊰",Pscr:"𝒫",pscr:"𝓅",Psi:"Ψ",psi:"ψ",puncsp:" ",Qfr:"𝔔",qfr:"𝔮",qint:"⨌",qopf:"𝕢",Qopf:"ℚ",qprime:"⁗",Qscr:"𝒬",qscr:"𝓆",quaternions:"ℍ",quatint:"⨖",quest:"?",questeq:"≟",quot:'"',QUOT:'"',rAarr:"⇛",race:"∽̱",Racute:"Ŕ",racute:"ŕ",radic:"√",raemptyv:"⦳",rang:"⟩",Rang:"⟫",rangd:"⦒",range:"⦥",rangle:"⟩",raquo:"»",rarrap:"⥵",rarrb:"⇥",rarrbfs:"⤠",rarrc:"⤳",rarr:"→",Rarr:"↠",rArr:"⇒",rarrfs:"⤞",rarrhk:"↪",rarrlp:"↬",rarrpl:"⥅",rarrsim:"⥴",Rarrtl:"⤖",rarrtl:"↣",rarrw:"↝",ratail:"⤚",rAtail:"⤜",ratio:"∶",rationals:"ℚ",rbarr:"⤍",rBarr:"⤏",RBarr:"⤐",rbbrk:"❳",rbrace:"}",rbrack:"]",rbrke:"⦌",rbrksld:"⦎",rbrkslu:"⦐",Rcaron:"Ř",rcaron:"ř",Rcedil:"Ŗ",rcedil:"ŗ",rceil:"⌉",rcub:"}",Rcy:"Р",rcy:"р",rdca:"⤷",rdldhar:"⥩",rdquo:"”",rdquor:"”",rdsh:"↳",real:"ℜ",realine:"ℛ",realpart:"ℜ",reals:"ℝ",Re:"ℜ",rect:"▭",reg:"®",REG:"®",ReverseElement:"∋",ReverseEquilibrium:"⇋",ReverseUpEquilibrium:"⥯",rfisht:"⥽",rfloor:"⌋",rfr:"𝔯",Rfr:"ℜ",rHar:"⥤",rhard:"⇁",rharu:"⇀",rharul:"⥬",Rho:"Ρ",rho:"ρ",rhov:"ϱ",RightAngleBracket:"⟩",RightArrowBar:"⇥",rightarrow:"→",RightArrow:"→",Rightarrow:"⇒",RightArrowLeftArrow:"⇄",rightarrowtail:"↣",RightCeiling:"⌉",RightDoubleBracket:"⟧",RightDownTeeVector:"⥝",RightDownVectorBar:"⥕",RightDownVector:"⇂",RightFloor:"⌋",rightharpoondown:"⇁",rightharpoonup:"⇀",rightleftarrows:"⇄",rightleftharpoons:"⇌",rightrightarrows:"⇉",rightsquigarrow:"↝",RightTeeArrow:"↦",RightTee:"⊢",RightTeeVector:"⥛",rightthreetimes:"⋌",RightTriangleBar:"⧐",RightTriangle:"⊳",RightTriangleEqual:"⊵",RightUpDownVector:"⥏",RightUpTeeVector:"⥜",RightUpVectorBar:"⥔",RightUpVector:"↾",RightVectorBar:"⥓",RightVector:"⇀",ring:"˚",risingdotseq:"≓",rlarr:"⇄",rlhar:"⇌",rlm:"‏",rmoustache:"⎱",rmoust:"⎱",rnmid:"⫮",roang:"⟭",roarr:"⇾",robrk:"⟧",ropar:"⦆",ropf:"𝕣",Ropf:"ℝ",roplus:"⨮",rotimes:"⨵",RoundImplies:"⥰",rpar:")",rpargt:"⦔",rppolint:"⨒",rrarr:"⇉",Rrightarrow:"⇛",rsaquo:"›",rscr:"𝓇",Rscr:"ℛ",rsh:"↱",Rsh:"↱",rsqb:"]",rsquo:"’",rsquor:"’",rthree:"⋌",rtimes:"⋊",rtri:"▹",rtrie:"⊵",rtrif:"▸",rtriltri:"⧎",RuleDelayed:"⧴",ruluhar:"⥨",rx:"℞",Sacute:"Ś",sacute:"ś",sbquo:"‚",scap:"⪸",Scaron:"Š",scaron:"š",Sc:"⪼",sc:"≻",sccue:"≽",sce:"⪰",scE:"⪴",Scedil:"Ş",scedil:"ş",Scirc:"Ŝ",scirc:"ŝ",scnap:"⪺",scnE:"⪶",scnsim:"⋩",scpolint:"⨓",scsim:"≿",Scy:"С",scy:"с",sdotb:"⊡",sdot:"⋅",sdote:"⩦",searhk:"⤥",searr:"↘",seArr:"⇘",searrow:"↘",sect:"§",semi:";",seswar:"⤩",setminus:"∖",setmn:"∖",sext:"✶",Sfr:"𝔖",sfr:"𝔰",sfrown:"⌢",sharp:"♯",SHCHcy:"Щ",shchcy:"щ",SHcy:"Ш",shcy:"ш",ShortDownArrow:"↓",ShortLeftArrow:"←",shortmid:"∣",shortparallel:"∥",ShortRightArrow:"→",ShortUpArrow:"↑",shy:"­",Sigma:"Σ",sigma:"σ",sigmaf:"ς",sigmav:"ς",sim:"∼",simdot:"⩪",sime:"≃",simeq:"≃",simg:"⪞",simgE:"⪠",siml:"⪝",simlE:"⪟",simne:"≆",simplus:"⨤",simrarr:"⥲",slarr:"←",SmallCircle:"∘",smallsetminus:"∖",smashp:"⨳",smeparsl:"⧤",smid:"∣",smile:"⌣",smt:"⪪",smte:"⪬",smtes:"⪬︀",SOFTcy:"Ь",softcy:"ь",solbar:"⌿",solb:"⧄",sol:"/",Sopf:"𝕊",sopf:"𝕤",spades:"♠",spadesuit:"♠",spar:"∥",sqcap:"⊓",sqcaps:"⊓︀",sqcup:"⊔",sqcups:"⊔︀",Sqrt:"√",sqsub:"⊏",sqsube:"⊑",sqsubset:"⊏",sqsubseteq:"⊑",sqsup:"⊐",sqsupe:"⊒",sqsupset:"⊐",sqsupseteq:"⊒",square:"□",Square:"□",SquareIntersection:"⊓",SquareSubset:"⊏",SquareSubsetEqual:"⊑",SquareSuperset:"⊐",SquareSupersetEqual:"⊒",SquareUnion:"⊔",squarf:"▪",squ:"□",squf:"▪",srarr:"→",Sscr:"𝒮",sscr:"𝓈",ssetmn:"∖",ssmile:"⌣",sstarf:"⋆",Star:"⋆",star:"☆",starf:"★",straightepsilon:"ϵ",straightphi:"ϕ",strns:"¯",sub:"⊂",Sub:"⋐",subdot:"⪽",subE:"⫅",sube:"⊆",subedot:"⫃",submult:"⫁",subnE:"⫋",subne:"⊊",subplus:"⪿",subrarr:"⥹",subset:"⊂",Subset:"⋐",subseteq:"⊆",subseteqq:"⫅",SubsetEqual:"⊆",subsetneq:"⊊",subsetneqq:"⫋",subsim:"⫇",subsub:"⫕",subsup:"⫓",succapprox:"⪸",succ:"≻",succcurlyeq:"≽",Succeeds:"≻",SucceedsEqual:"⪰",SucceedsSlantEqual:"≽",SucceedsTilde:"≿",succeq:"⪰",succnapprox:"⪺",succneqq:"⪶",succnsim:"⋩",succsim:"≿",SuchThat:"∋",sum:"∑",Sum:"∑",sung:"♪",sup1:"¹",sup2:"²",sup3:"³",sup:"⊃",Sup:"⋑",supdot:"⪾",supdsub:"⫘",supE:"⫆",supe:"⊇",supedot:"⫄",Superset:"⊃",SupersetEqual:"⊇",suphsol:"⟉",suphsub:"⫗",suplarr:"⥻",supmult:"⫂",supnE:"⫌",supne:"⊋",supplus:"⫀",supset:"⊃",Supset:"⋑",supseteq:"⊇",supseteqq:"⫆",supsetneq:"⊋",supsetneqq:"⫌",supsim:"⫈",supsub:"⫔",supsup:"⫖",swarhk:"⤦",swarr:"↙",swArr:"⇙",swarrow:"↙",swnwar:"⤪",szlig:"ß",Tab:"\t",target:"⌖",Tau:"Τ",tau:"τ",tbrk:"⎴",Tcaron:"Ť",tcaron:"ť",Tcedil:"Ţ",tcedil:"ţ",Tcy:"Т",tcy:"т",tdot:"⃛",telrec:"⌕",Tfr:"𝔗",tfr:"𝔱",there4:"∴",therefore:"∴",Therefore:"∴",Theta:"Θ",theta:"θ",thetasym:"ϑ",thetav:"ϑ",thickapprox:"≈",thicksim:"∼",ThickSpace:"  ",ThinSpace:" ",thinsp:" ",thkap:"≈",thksim:"∼",THORN:"Þ",thorn:"þ",tilde:"˜",Tilde:"∼",TildeEqual:"≃",TildeFullEqual:"≅",TildeTilde:"≈",timesbar:"⨱",timesb:"⊠",times:"×",timesd:"⨰",tint:"∭",toea:"⤨",topbot:"⌶",topcir:"⫱",top:"⊤",Topf:"𝕋",topf:"𝕥",topfork:"⫚",tosa:"⤩",tprime:"‴",trade:"™",TRADE:"™",triangle:"▵",triangledown:"▿",triangleleft:"◃",trianglelefteq:"⊴",triangleq:"≜",triangleright:"▹",trianglerighteq:"⊵",tridot:"◬",trie:"≜",triminus:"⨺",TripleDot:"⃛",triplus:"⨹",trisb:"⧍",tritime:"⨻",trpezium:"⏢",Tscr:"𝒯",tscr:"𝓉",TScy:"Ц",tscy:"ц",TSHcy:"Ћ",tshcy:"ћ",Tstrok:"Ŧ",tstrok:"ŧ",twixt:"≬",twoheadleftarrow:"↞",twoheadrightarrow:"↠",Uacute:"Ú",uacute:"ú",uarr:"↑",Uarr:"↟",uArr:"⇑",Uarrocir:"⥉",Ubrcy:"Ў",ubrcy:"ў",Ubreve:"Ŭ",ubreve:"ŭ",Ucirc:"Û",ucirc:"û",Ucy:"У",ucy:"у",udarr:"⇅",Udblac:"Ű",udblac:"ű",udhar:"⥮",ufisht:"⥾",Ufr:"𝔘",ufr:"𝔲",Ugrave:"Ù",ugrave:"ù",uHar:"⥣",uharl:"↿",uharr:"↾",uhblk:"▀",ulcorn:"⌜",ulcorner:"⌜",ulcrop:"⌏",ultri:"◸",Umacr:"Ū",umacr:"ū",uml:"¨",UnderBar:"_",UnderBrace:"⏟",UnderBracket:"⎵",UnderParenthesis:"⏝",Union:"⋃",UnionPlus:"⊎",Uogon:"Ų",uogon:"ų",Uopf:"𝕌",uopf:"𝕦",UpArrowBar:"⤒",uparrow:"↑",UpArrow:"↑",Uparrow:"⇑",UpArrowDownArrow:"⇅",updownarrow:"↕",UpDownArrow:"↕",Updownarrow:"⇕",UpEquilibrium:"⥮",upharpoonleft:"↿",upharpoonright:"↾",uplus:"⊎",UpperLeftArrow:"↖",UpperRightArrow:"↗",upsi:"υ",Upsi:"ϒ",upsih:"ϒ",Upsilon:"Υ",upsilon:"υ",UpTeeArrow:"↥",UpTee:"⊥",upuparrows:"⇈",urcorn:"⌝",urcorner:"⌝",urcrop:"⌎",Uring:"Ů",uring:"ů",urtri:"◹",Uscr:"𝒰",uscr:"𝓊",utdot:"⋰",Utilde:"Ũ",utilde:"ũ",utri:"▵",utrif:"▴",uuarr:"⇈",Uuml:"Ü",uuml:"ü",uwangle:"⦧",vangrt:"⦜",varepsilon:"ϵ",varkappa:"ϰ",varnothing:"∅",varphi:"ϕ",varpi:"ϖ",varpropto:"∝",varr:"↕",vArr:"⇕",varrho:"ϱ",varsigma:"ς",varsubsetneq:"⊊︀",varsubsetneqq:"⫋︀",varsupsetneq:"⊋︀",varsupsetneqq:"⫌︀",vartheta:"ϑ",vartriangleleft:"⊲",vartriangleright:"⊳",vBar:"⫨",Vbar:"⫫",vBarv:"⫩",Vcy:"В",vcy:"в",vdash:"⊢",vDash:"⊨",Vdash:"⊩",VDash:"⊫",Vdashl:"⫦",veebar:"⊻",vee:"∨",Vee:"⋁",veeeq:"≚",vellip:"⋮",verbar:"|",Verbar:"‖",vert:"|",Vert:"‖",VerticalBar:"∣",VerticalLine:"|",VerticalSeparator:"❘",VerticalTilde:"≀",VeryThinSpace:" ",Vfr:"𝔙",vfr:"𝔳",vltri:"⊲",vnsub:"⊂⃒",vnsup:"⊃⃒",Vopf:"𝕍",vopf:"𝕧",vprop:"∝",vrtri:"⊳",Vscr:"𝒱",vscr:"𝓋",vsubnE:"⫋︀",vsubne:"⊊︀",vsupnE:"⫌︀",vsupne:"⊋︀",Vvdash:"⊪",vzigzag:"⦚",Wcirc:"Ŵ",wcirc:"ŵ",wedbar:"⩟",wedge:"∧",Wedge:"⋀",wedgeq:"≙",weierp:"℘",Wfr:"𝔚",wfr:"𝔴",Wopf:"𝕎",wopf:"𝕨",wp:"℘",wr:"≀",wreath:"≀",Wscr:"𝒲",wscr:"𝓌",xcap:"⋂",xcirc:"◯",xcup:"⋃",xdtri:"▽",Xfr:"𝔛",xfr:"𝔵",xharr:"⟷",xhArr:"⟺",Xi:"Ξ",xi:"ξ",xlarr:"⟵",xlArr:"⟸",xmap:"⟼",xnis:"⋻",xodot:"⨀",Xopf:"𝕏",xopf:"𝕩",xoplus:"⨁",xotime:"⨂",xrarr:"⟶",xrArr:"⟹",Xscr:"𝒳",xscr:"𝓍",xsqcup:"⨆",xuplus:"⨄",xutri:"△",xvee:"⋁",xwedge:"⋀",Yacute:"Ý",yacute:"ý",YAcy:"Я",yacy:"я",Ycirc:"Ŷ",ycirc:"ŷ",Ycy:"Ы",ycy:"ы",yen:"¥",Yfr:"𝔜",yfr:"𝔶",YIcy:"Ї",yicy:"ї",Yopf:"𝕐",yopf:"𝕪",Yscr:"𝒴",yscr:"𝓎",YUcy:"Ю",yucy:"ю",yuml:"ÿ",Yuml:"Ÿ",Zacute:"Ź",zacute:"ź",Zcaron:"Ž",zcaron:"ž",Zcy:"З",zcy:"з",Zdot:"Ż",zdot:"ż",zeetrf:"ℨ",ZeroWidthSpace:"​",Zeta:"Ζ",zeta:"ζ",zfr:"𝔷",Zfr:"ℨ",ZHcy:"Ж",zhcy:"ж",zigrarr:"⇝",zopf:"𝕫",Zopf:"ℤ",Zscr:"𝒵",zscr:"𝓏",zwj:"‍",zwnj:"‌"}},{}],26:[function(e,t,n){t.exports={Aacute:"Á",aacute:"á",Acirc:"Â",acirc:"â",acute:"´",AElig:"Æ",aelig:"æ",Agrave:"À",agrave:"à",amp:"&",AMP:"&",Aring:"Å",aring:"å",Atilde:"Ã",atilde:"ã",Auml:"Ä",auml:"ä",brvbar:"¦",Ccedil:"Ç",ccedil:"ç",cedil:"¸",cent:"¢",copy:"©",COPY:"©",curren:"¤",deg:"°",divide:"÷",Eacute:"É",eacute:"é",Ecirc:"Ê",ecirc:"ê",Egrave:"È",egrave:"è",ETH:"Ð",eth:"ð",Euml:"Ë",euml:"ë",frac12:"½",frac14:"¼",frac34:"¾",gt:">",GT:">",Iacute:"Í",iacute:"í",Icirc:"Î",icirc:"î",iexcl:"¡",Igrave:"Ì",igrave:"ì",iquest:"¿",Iuml:"Ï",iuml:"ï",laquo:"«",lt:"<",LT:"<",macr:"¯",micro:"µ",middot:"·",nbsp:" ",not:"¬",Ntilde:"Ñ",ntilde:"ñ",Oacute:"Ó",oacute:"ó",Ocirc:"Ô",ocirc:"ô",Ograve:"Ò",ograve:"ò",ordf:"ª",ordm:"º",Oslash:"Ø",oslash:"ø",Otilde:"Õ",otilde:"õ",Ouml:"Ö",ouml:"ö",para:"¶",plusmn:"±",pound:"£",quot:'"',QUOT:'"',raquo:"»",reg:"®",REG:"®",sect:"§",shy:"­",sup1:"¹",sup2:"²",sup3:"³",szlig:"ß",THORN:"Þ",thorn:"þ",times:"×",Uacute:"Ú",uacute:"ú",Ucirc:"Û",ucirc:"û",Ugrave:"Ù",ugrave:"ù",uml:"¨",Uuml:"Ü",uuml:"ü",Yacute:"Ý",yacute:"ý",yen:"¥",yuml:"ÿ"}},{}],27:[function(e,t,n){t.exports={amp:"&",apos:"'",gt:">",lt:"<",quot:'"'}},{}],28:[function(e,t,n){function r(){this._events=this._events||{},this._maxListeners=this._maxListeners||void 0}function i(e){return"function"==typeof e}function a(e){return"number"==typeof e}function o(e){return"object"==typeof e&&null!==e}function s(e){return void 0===e}t.exports=r,r.EventEmitter=r,r.prototype._events=void 0,r.prototype._maxListeners=void 0,r.defaultMaxListeners=10,r.prototype.setMaxListeners=function(e){if(!a(e)||e<0||isNaN(e))throw TypeError("n must be a positive number");return this._maxListeners=e,this},r.prototype.emit=function(e){var t,n,r,a,l,u;if(this._events||(this._events={}),"error"===e&&(!this._events.error||o(this._events.error)&&!this._events.error.length)){if(t=arguments[1],t instanceof Error)throw t;var c=new Error('Uncaught, unspecified "error" event. ('+t+")");throw c.context=t,c}if(n=this._events[e],s(n))return!1;if(i(n))switch(arguments.length){case 1:n.call(this);break;case 2:n.call(this,arguments[1]);break;case 3:n.call(this,arguments[1],arguments[2]);break;default:a=Array.prototype.slice.call(arguments,1),n.apply(this,a)}else if(o(n))for(a=Array.prototype.slice.call(arguments,1),u=n.slice(),r=u.length,l=0;l<r;l++)u[l].apply(this,a);return!0},r.prototype.addListener=function(e,t){var n;if(!i(t))throw TypeError("listener must be a function");return this._events||(this._events={}),this._events.newListener&&this.emit("newListener",e,i(t.listener)?t.listener:t),this._events[e]?o(this._events[e])?this._events[e].push(t):this._events[e]=[this._events[e],t]:this._events[e]=t,o(this._events[e])&&!this._events[e].warned&&(n=s(this._maxListeners)?r.defaultMaxListeners:this._maxListeners,n&&n>0&&this._events[e].length>n&&(this._events[e].warned=!0,console.error("(node) warning: possible EventEmitter memory leak detected. %d listeners added. Use emitter.setMaxListeners() to increase limit.",this._events[e].length),"function"==typeof console.trace&&console.trace())),this},r.prototype.on=r.prototype.addListener,r.prototype.once=function(e,t){function n(){this.removeListener(e,n),r||(r=!0,t.apply(this,arguments))}if(!i(t))throw TypeError("listener must be a function");var r=!1;return n.listener=t,this.on(e,n),this},r.prototype.removeListener=function(e,t){var n,r,a,s;if(!i(t))throw TypeError("listener must be a function");if(!this._events||!this._events[e])return this;if(n=this._events[e],a=n.length,r=-1,n===t||i(n.listener)&&n.listener===t)delete this._events[e],this._events.removeListener&&this.emit("removeListener",e,t);else if(o(n)){for(s=a;s-- >0;)if(n[s]===t||n[s].listener&&n[s].listener===t){r=s;break}if(r<0)return this;1===n.length?(n.length=0,delete this._events[e]):n.splice(r,1),this._events.removeListener&&this.emit("removeListener",e,t)}return this},r.prototype.removeAllListeners=function(e){var t,n;if(!this._events)return this;if(!this._events.removeListener)return 0===arguments.length?this._events={}:this._events[e]&&delete this._events[e],this;if(0===arguments.length){for(t in this._events)"removeListener"!==t&&this.removeAllListeners(t);return this.removeAllListeners("removeListener"),this._events={},this}if(n=this._events[e],i(n))this.removeListener(e,n);else if(n)for(;n.length;)this.removeListener(e,n[n.length-1]);return delete this._events[e],this},r.prototype.listeners=function(e){var t;return t=this._events&&this._events[e]?i(this._events[e])?[this._events[e]]:this._events[e].slice():[]},r.prototype.listenerCount=function(e){if(this._events){var t=this._events[e];if(i(t))return 1;if(t)return t.length}return 0},r.listenerCount=function(e,t){return e.listenerCount(t)}},{}],29:[function(e,t,n){function r(e){this._cbs=e||{},this.events=[]}t.exports=r;var i=e("./").EVENTS;Object.keys(i).forEach(function(e){if(0===i[e])e="on"+e,r.prototype[e]=function(){this.events.push([e]),this._cbs[e]&&this._cbs[e]()};else if(1===i[e])e="on"+e,r.prototype[e]=function(t){this.events.push([e,t]),this._cbs[e]&&this._cbs[e](t)};else{if(2!==i[e])throw Error("wrong number of arguments");e="on"+e,r.prototype[e]=function(t,n){this.events.push([e,t,n]),this._cbs[e]&&this._cbs[e](t,n)}}}),r.prototype.onreset=function(){this.events=[],this._cbs.onreset&&this._cbs.onreset()},r.prototype.restart=function(){this._cbs.onreset&&this._cbs.onreset();for(var e=0,t=this.events.length;e<t;e++)if(this._cbs[this.events[e][0]]){var n=this.events[e].length;1===n?this._cbs[this.events[e][0]]():2===n?this._cbs[this.events[e][0]](this.events[e][1]):this._cbs[this.events[e][0]](this.events[e][1],this.events[e][2])}}},{"./":36}],30:[function(e,t,n){function r(e,t){this.init(e,t)}function i(e,t){return c.getElementsByTagName(e,t,!0)}function a(e,t){return c.getElementsByTagName(e,t,!0,1)[0]}function o(e,t,n){return c.getText(c.getElementsByTagName(e,t,n,1)).trim()}function s(e,t,n,r,i){var a=o(n,r,i);a&&(e[t]=a)}var l=e("./index.js"),u=l.DomHandler,c=l.DomUtils;e("inherits")(r,u),r.prototype.init=u;var p=function(e){return"rss"===e||"feed"===e||"rdf:RDF"===e};r.prototype.onend=function(){var e,t,n={},r=a(p,this.dom);r&&("feed"===r.name?(t=r.children,n.type="atom",s(n,"id","id",t),s(n,"title","title",t),(e=a("link",t))&&(e=e.attribs)&&(e=e.href)&&(n.link=e),s(n,"description","subtitle",t),(e=o("updated",t))&&(n.updated=new Date(e)),s(n,"author","email",t,!0),n.items=i("entry",t).map(function(e){var t,n={};return e=e.children,s(n,"id","id",e),s(n,"title","title",e),(t=a("link",e))&&(t=t.attribs)&&(t=t.href)&&(n.link=t),(t=o("summary",e)||o("content",e))&&(n.description=t),(t=o("updated",e))&&(n.pubDate=new Date(t)),n})):(t=a("channel",r.children).children,n.type=r.name.substr(0,3),n.id="",s(n,"title","title",t),s(n,"link","link",t),s(n,"description","description",t),(e=o("lastBuildDate",t))&&(n.updated=new Date(e)),s(n,"author","managingEditor",t,!0),n.items=i("item",r.children).map(function(e){var t,n={};return e=e.children,s(n,"id","guid",e),s(n,"title","title",e),s(n,"link","link",e),s(n,"description","description",e),(t=o("pubDate",e))&&(n.pubDate=new Date(t)),n}))),this.dom=n,u.prototype._handleCallback.call(this,r?null:Error("couldn't find root of feed"))},t.exports=r},{"./index.js":36,inherits:38}],31:[function(e,t,n){function r(e,t){this._options=t||{},this._cbs=e||{},this._tagname="",this._attribname="",this._attribvalue="",this._attribs=null,this._stack=[],this.startIndex=0,this.endIndex=null,this._lowerCaseTagNames="lowerCaseTags"in this._options?!!this._options.lowerCaseTags:!this._options.xmlMode,this._lowerCaseAttributeNames="lowerCaseAttributeNames"in this._options?!!this._options.lowerCaseAttributeNames:!this._options.xmlMode,this._options.Tokenizer&&(i=this._options.Tokenizer),this._tokenizer=new i(this._options,this),this._cbs.onparserinit&&this._cbs.onparserinit(this)}var i=e("./Tokenizer.js"),a={input:!0,option:!0,optgroup:!0,select:!0,button:!0,datalist:!0,textarea:!0},o={tr:{tr:!0,th:!0,td:!0},th:{th:!0},td:{thead:!0,th:!0,td:!0},body:{head:!0,link:!0,script:!0},li:{li:!0},p:{p:!0},h1:{p:!0},h2:{p:!0},h3:{p:!0},h4:{p:!0},h5:{p:!0},h6:{p:!0},select:a,input:a,output:a,button:a,datalist:a,textarea:a,option:{option:!0},optgroup:{optgroup:!0}},s={__proto__:null,area:!0,base:!0,basefont:!0,br:!0,col:!0,command:!0,embed:!0,frame:!0,hr:!0,img:!0,input:!0,isindex:!0,keygen:!0,link:!0,meta:!0,param:!0,source:!0,track:!0,wbr:!0,path:!0,circle:!0,ellipse:!0,line:!0,rect:!0,use:!0,stop:!0,polyline:!0,polygon:!0},l=/\s|\//;e("inherits")(r,e("events").EventEmitter),r.prototype._updatePosition=function(e){null===this.endIndex?this._tokenizer._sectionStart<=e?this.startIndex=0:this.startIndex=this._tokenizer._sectionStart-e:this.startIndex=this.endIndex+1,this.endIndex=this._tokenizer.getAbsoluteIndex()},r.prototype.ontext=function(e){this._updatePosition(1),this.endIndex--,this._cbs.ontext&&this._cbs.ontext(e)},r.prototype.onopentagname=function(e){if(this._lowerCaseTagNames&&(e=e.toLowerCase()),this._tagname=e,!this._options.xmlMode&&e in o)for(var t;(t=this._stack[this._stack.length-1])in o[e];this.onclosetag(t));!this._options.xmlMode&&e in s||this._stack.push(e),this._cbs.onopentagname&&this._cbs.onopentagname(e),this._cbs.onopentag&&(this._attribs={})},r.prototype.onopentagend=function(){this._updatePosition(1),this._attribs&&(this._cbs.onopentag&&this._cbs.onopentag(this._tagname,this._attribs),this._attribs=null),!this._options.xmlMode&&this._cbs.onclosetag&&this._tagname in s&&this._cbs.onclosetag(this._tagname),this._tagname=""},r.prototype.onclosetag=function(e){if(this._updatePosition(1),this._lowerCaseTagNames&&(e=e.toLowerCase()),!this._stack.length||e in s&&!this._options.xmlMode)this._options.xmlMode||"br"!==e&&"p"!==e||(this.onopentagname(e),this._closeCurrentTag());else{var t=this._stack.lastIndexOf(e);if(t!==-1)if(this._cbs.onclosetag)for(t=this._stack.length-t;t--;)this._cbs.onclosetag(this._stack.pop());else this._stack.length=t;else"p"!==e||this._options.xmlMode||(this.onopentagname(e),this._closeCurrentTag())}},r.prototype.onselfclosingtag=function(){this._options.xmlMode||this._options.recognizeSelfClosing?this._closeCurrentTag():this.onopentagend()},r.prototype._closeCurrentTag=function(){var e=this._tagname;this.onopentagend(),this._stack[this._stack.length-1]===e&&(this._cbs.onclosetag&&this._cbs.onclosetag(e),this._stack.pop())},r.prototype.onattribname=function(e){this._lowerCaseAttributeNames&&(e=e.toLowerCase()),this._attribname=e},r.prototype.onattribdata=function(e){this._attribvalue+=e},r.prototype.onattribend=function(){this._cbs.onattribute&&this._cbs.onattribute(this._attribname,this._attribvalue),this._attribs&&!Object.prototype.hasOwnProperty.call(this._attribs,this._attribname)&&(this._attribs[this._attribname]=this._attribvalue),this._attribname="",this._attribvalue=""},r.prototype._getInstructionName=function(e){var t=e.search(l),n=t<0?e:e.substr(0,t);return this._lowerCaseTagNames&&(n=n.toLowerCase()),n},r.prototype.ondeclaration=function(e){if(this._cbs.onprocessinginstruction){var t=this._getInstructionName(e);this._cbs.onprocessinginstruction("!"+t,"!"+e)}},r.prototype.onprocessinginstruction=function(e){if(this._cbs.onprocessinginstruction){var t=this._getInstructionName(e);this._cbs.onprocessinginstruction("?"+t,"?"+e)}},r.prototype.oncomment=function(e){this._updatePosition(4),this._cbs.oncomment&&this._cbs.oncomment(e),this._cbs.oncommentend&&this._cbs.oncommentend()},r.prototype.oncdata=function(e){this._updatePosition(1),this._options.xmlMode||this._options.recognizeCDATA?(this._cbs.oncdatastart&&this._cbs.oncdatastart(),this._cbs.ontext&&this._cbs.ontext(e),this._cbs.oncdataend&&this._cbs.oncdataend()):this.oncomment("[CDATA["+e+"]]")},r.prototype.onerror=function(e){this._cbs.onerror&&this._cbs.onerror(e)},r.prototype.onend=function(){if(this._cbs.onclosetag)for(var e=this._stack.length;e>0;this._cbs.onclosetag(this._stack[--e]));this._cbs.onend&&this._cbs.onend()},r.prototype.reset=function(){this._cbs.onreset&&this._cbs.onreset(),this._tokenizer.reset(),this._tagname="",this._attribname="",this._attribs=null,this._stack=[],this._cbs.onparserinit&&this._cbs.onparserinit(this)},r.prototype.parseComplete=function(e){this.reset(),this.end(e)},r.prototype.write=function(e){this._tokenizer.write(e)},r.prototype.end=function(e){this._tokenizer.end(e)},r.prototype.pause=function(){this._tokenizer.pause()},r.prototype.resume=function(){this._tokenizer.resume()},r.prototype.parseChunk=r.prototype.write,r.prototype.done=r.prototype.end,t.exports=r},{"./Tokenizer.js":34,events:28,inherits:38}],32:[function(e,t,n){function r(e){this._cbs=e||{}}t.exports=r;var i=e("./").EVENTS;Object.keys(i).forEach(function(e){if(0===i[e])e="on"+e,r.prototype[e]=function(){this._cbs[e]&&this._cbs[e]()};else if(1===i[e])e="on"+e,r.prototype[e]=function(t){this._cbs[e]&&this._cbs[e](t)};else{if(2!==i[e])throw Error("wrong number of arguments");e="on"+e,r.prototype[e]=function(t,n){this._cbs[e]&&this._cbs[e](t,n)}}})},{"./":36}],33:[function(e,t,n){function r(e){a.call(this,new i(this),e)}function i(e){this.scope=e}t.exports=r;var a=e("./WritableStream.js");e("inherits")(r,a),r.prototype.readable=!0;var o=e("../").EVENTS;Object.keys(o).forEach(function(e){if(0===o[e])i.prototype["on"+e]=function(){this.scope.emit(e)};else if(1===o[e])i.prototype["on"+e]=function(t){this.scope.emit(e,t)};else{if(2!==o[e])throw Error("wrong number of arguments!");i.prototype["on"+e]=function(t,n){this.scope.emit(e,t,n)}}})},{"../":36,"./WritableStream.js":35,inherits:38}],34:[function(e,t,n){function r(e){return" "===e||"\n"===e||"\t"===e||"\f"===e||"\r"===e}function i(e,t){return function(n){n===e&&(this._state=t)}}function a(e,t,n){var r=e.toLowerCase();return e===r?function(e){e===r?this._state=t:(this._state=n,this._index--)}:function(i){i===r||i===e?this._state=t:(this._state=n,this._index--)}}function o(e,t){var n=e.toLowerCase();return function(r){r===n||r===e?this._state=t:(this._state=m,this._index--)}}function s(e,t){this._state=f,this._buffer="",this._sectionStart=0,this._index=0,this._bufferOffset=0,this._baseState=f,this._special=me,this._cbs=t,this._running=!0,this._ended=!1,this._xmlMode=!(!e||!e.xmlMode),this._decodeEntities=!(!e||!e.decodeEntities)}t.exports=s;var l=e("entities/lib/decode_codepoint.js"),u=e("entities/maps/entities.json"),c=e("entities/maps/legacy.json"),p=e("entities/maps/xml.json"),h=0,f=h++,d=h++,m=h++,g=h++,y=h++,v=h++,b=h++,w=h++,_=h++,x=h++,A=h++,S=h++,j=h++,E=h++,O=h++,k=h++,T=h++,C=h++,I=h++,D=h++,L=h++,M=h++,R=h++,U=h++,P=h++,q=h++,B=h++,N=h++,z=h++,$=h++,F=h++,V=h++,H=h++,Y=h++,J=h++,W=h++,Q=h++,G=h++,K=h++,X=h++,Z=h++,ee=h++,te=h++,ne=h++,re=h++,ie=h++,ae=h++,oe=h++,se=h++,le=h++,ue=h++,ce=h++,pe=h++,he=h++,fe=h++,de=0,me=de++,ge=de++,ye=de++;s.prototype._stateText=function(e){"<"===e?(this._index>this._sectionStart&&this._cbs.ontext(this._getSection()),this._state=d,this._sectionStart=this._index):this._decodeEntities&&this._special===me&&"&"===e&&(this._index>this._sectionStart&&this._cbs.ontext(this._getSection()),this._baseState=f,this._state=ue,this._sectionStart=this._index)},s.prototype._stateBeforeTagName=function(e){"/"===e?this._state=y:"<"===e?(this._cbs.ontext(this._getSection()),this._sectionStart=this._index):">"===e||this._special!==me||r(e)?this._state=f:"!"===e?(this._state=O,this._sectionStart=this._index+1):"?"===e?(this._state=T,this._sectionStart=this._index+1):(this._state=this._xmlMode||"s"!==e&&"S"!==e?m:F,this._sectionStart=this._index)},s.prototype._stateInTagName=function(e){("/"===e||">"===e||r(e))&&(this._emitToken("onopentagname"),this._state=w,this._index--)},s.prototype._stateBeforeCloseingTagName=function(e){r(e)||(">"===e?this._state=f:this._special!==me?"s"===e||"S"===e?this._state=V:(this._state=f,this._index--):(this._state=v,this._sectionStart=this._index))},s.prototype._stateInCloseingTagName=function(e){(">"===e||r(e))&&(this._emitToken("onclosetag"),this._state=b,this._index--)},s.prototype._stateAfterCloseingTagName=function(e){">"===e&&(this._state=f,this._sectionStart=this._index+1)},s.prototype._stateBeforeAttributeName=function(e){">"===e?(this._cbs.onopentagend(),this._state=f,this._sectionStart=this._index+1):"/"===e?this._state=g:r(e)||(this._state=_,this._sectionStart=this._index)},s.prototype._stateInSelfClosingTag=function(e){">"===e?(this._cbs.onselfclosingtag(),this._state=f,this._sectionStart=this._index+1):r(e)||(this._state=w,this._index--)},s.prototype._stateInAttributeName=function(e){("="===e||"/"===e||">"===e||r(e))&&(this._cbs.onattribname(this._getSection()),this._sectionStart=-1,this._state=x,this._index--)},s.prototype._stateAfterAttributeName=function(e){"="===e?this._state=A:"/"===e||">"===e?(this._cbs.onattribend(),this._state=w,this._index--):r(e)||(this._cbs.onattribend(),this._state=_,this._sectionStart=this._index)},s.prototype._stateBeforeAttributeValue=function(e){'"'===e?(this._state=S,this._sectionStart=this._index+1):"'"===e?(this._state=j,this._sectionStart=this._index+1):r(e)||(this._state=E,this._sectionStart=this._index,this._index--)},s.prototype._stateInAttributeValueDoubleQuotes=function(e){'"'===e?(this._emitToken("onattribdata"),this._cbs.onattribend(),this._state=w):this._decodeEntities&&"&"===e&&(this._emitToken("onattribdata"),this._baseState=this._state,this._state=ue,this._sectionStart=this._index)},s.prototype._stateInAttributeValueSingleQuotes=function(e){"'"===e?(this._emitToken("onattribdata"),this._cbs.onattribend(),this._state=w):this._decodeEntities&&"&"===e&&(this._emitToken("onattribdata"),this._baseState=this._state,this._state=ue,this._sectionStart=this._index)},s.prototype._stateInAttributeValueNoQuotes=function(e){r(e)||">"===e?(this._emitToken("onattribdata"),this._cbs.onattribend(),this._state=w,this._index--):this._decodeEntities&&"&"===e&&(this._emitToken("onattribdata"),this._baseState=this._state,this._state=ue,this._sectionStart=this._index)},s.prototype._stateBeforeDeclaration=function(e){this._state="["===e?M:"-"===e?C:k},s.prototype._stateInDeclaration=function(e){">"===e&&(this._cbs.ondeclaration(this._getSection()),this._state=f,this._sectionStart=this._index+1)},s.prototype._stateInProcessingInstruction=function(e){">"===e&&(this._cbs.onprocessinginstruction(this._getSection()),this._state=f,this._sectionStart=this._index+1)},s.prototype._stateBeforeComment=function(e){"-"===e?(this._state=I,this._sectionStart=this._index+1):this._state=k},s.prototype._stateInComment=function(e){"-"===e&&(this._state=D)},s.prototype._stateAfterComment1=function(e){"-"===e?this._state=L:this._state=I},s.prototype._stateAfterComment2=function(e){">"===e?(this._cbs.oncomment(this._buffer.substring(this._sectionStart,this._index-2)),this._state=f,this._sectionStart=this._index+1):"-"!==e&&(this._state=I)},s.prototype._stateBeforeCdata1=a("C",R,k),s.prototype._stateBeforeCdata2=a("D",U,k),s.prototype._stateBeforeCdata3=a("A",P,k),s.prototype._stateBeforeCdata4=a("T",q,k),s.prototype._stateBeforeCdata5=a("A",B,k),s.prototype._stateBeforeCdata6=function(e){"["===e?(this._state=N,this._sectionStart=this._index+1):(this._state=k,this._index--)},s.prototype._stateInCdata=function(e){"]"===e&&(this._state=z)},s.prototype._stateAfterCdata1=i("]",$),s.prototype._stateAfterCdata2=function(e){">"===e?(this._cbs.oncdata(this._buffer.substring(this._sectionStart,this._index-2)),this._state=f,this._sectionStart=this._index+1):"]"!==e&&(this._state=N)},s.prototype._stateBeforeSpecial=function(e){"c"===e||"C"===e?this._state=H:"t"===e||"T"===e?this._state=te:(this._state=m,this._index--)},s.prototype._stateBeforeSpecialEnd=function(e){this._special!==ge||"c"!==e&&"C"!==e?this._special!==ye||"t"!==e&&"T"!==e?this._state=f:this._state=ae:this._state=G},s.prototype._stateBeforeScript1=o("R",Y),s.prototype._stateBeforeScript2=o("I",J),s.prototype._stateBeforeScript3=o("P",W),s.prototype._stateBeforeScript4=o("T",Q),s.prototype._stateBeforeScript5=function(e){("/"===e||">"===e||r(e))&&(this._special=ge),this._state=m,this._index--},s.prototype._stateAfterScript1=a("R",K,f),s.prototype._stateAfterScript2=a("I",X,f),s.prototype._stateAfterScript3=a("P",Z,f),s.prototype._stateAfterScript4=a("T",ee,f),s.prototype._stateAfterScript5=function(e){
+">"===e||r(e)?(this._special=me,this._state=v,this._sectionStart=this._index-6,this._index--):this._state=f},s.prototype._stateBeforeStyle1=o("Y",ne),s.prototype._stateBeforeStyle2=o("L",re),s.prototype._stateBeforeStyle3=o("E",ie),s.prototype._stateBeforeStyle4=function(e){("/"===e||">"===e||r(e))&&(this._special=ye),this._state=m,this._index--},s.prototype._stateAfterStyle1=a("Y",oe,f),s.prototype._stateAfterStyle2=a("L",se,f),s.prototype._stateAfterStyle3=a("E",le,f),s.prototype._stateAfterStyle4=function(e){">"===e||r(e)?(this._special=me,this._state=v,this._sectionStart=this._index-5,this._index--):this._state=f},s.prototype._stateBeforeEntity=a("#",ce,pe),s.prototype._stateBeforeNumericEntity=a("X",fe,he),s.prototype._parseNamedEntityStrict=function(){if(this._sectionStart+1<this._index){var e=this._buffer.substring(this._sectionStart+1,this._index),t=this._xmlMode?p:u;t.hasOwnProperty(e)&&(this._emitPartial(t[e]),this._sectionStart=this._index+1)}},s.prototype._parseLegacyEntity=function(){var e=this._sectionStart+1,t=this._index-e;for(t>6&&(t=6);t>=2;){var n=this._buffer.substr(e,t);if(c.hasOwnProperty(n))return this._emitPartial(c[n]),void(this._sectionStart+=t+1);t--}},s.prototype._stateInNamedEntity=function(e){";"===e?(this._parseNamedEntityStrict(),this._sectionStart+1<this._index&&!this._xmlMode&&this._parseLegacyEntity(),this._state=this._baseState):(e<"a"||e>"z")&&(e<"A"||e>"Z")&&(e<"0"||e>"9")&&(this._xmlMode||this._sectionStart+1===this._index||(this._baseState!==f?"="!==e&&this._parseNamedEntityStrict():this._parseLegacyEntity()),this._state=this._baseState,this._index--)},s.prototype._decodeNumericEntity=function(e,t){var n=this._sectionStart+e;if(n!==this._index){var r=this._buffer.substring(n,this._index),i=parseInt(r,t);this._emitPartial(l(i)),this._sectionStart=this._index}else this._sectionStart--;this._state=this._baseState},s.prototype._stateInNumericEntity=function(e){";"===e?(this._decodeNumericEntity(2,10),this._sectionStart++):(e<"0"||e>"9")&&(this._xmlMode?this._state=this._baseState:this._decodeNumericEntity(2,10),this._index--)},s.prototype._stateInHexEntity=function(e){";"===e?(this._decodeNumericEntity(3,16),this._sectionStart++):(e<"a"||e>"f")&&(e<"A"||e>"F")&&(e<"0"||e>"9")&&(this._xmlMode?this._state=this._baseState:this._decodeNumericEntity(3,16),this._index--)},s.prototype._cleanup=function(){this._sectionStart<0?(this._buffer="",this._index=0,this._bufferOffset+=this._index):this._running&&(this._state===f?(this._sectionStart!==this._index&&this._cbs.ontext(this._buffer.substr(this._sectionStart)),this._buffer="",this._bufferOffset+=this._index,this._index=0):this._sectionStart===this._index?(this._buffer="",this._bufferOffset+=this._index,this._index=0):(this._buffer=this._buffer.substr(this._sectionStart),this._index-=this._sectionStart,this._bufferOffset+=this._sectionStart),this._sectionStart=0)},s.prototype.write=function(e){this._ended&&this._cbs.onerror(Error(".write() after done!")),this._buffer+=e,this._parse()},s.prototype._parse=function(){for(;this._index<this._buffer.length&&this._running;){var e=this._buffer.charAt(this._index);this._state===f?this._stateText(e):this._state===d?this._stateBeforeTagName(e):this._state===m?this._stateInTagName(e):this._state===y?this._stateBeforeCloseingTagName(e):this._state===v?this._stateInCloseingTagName(e):this._state===b?this._stateAfterCloseingTagName(e):this._state===g?this._stateInSelfClosingTag(e):this._state===w?this._stateBeforeAttributeName(e):this._state===_?this._stateInAttributeName(e):this._state===x?this._stateAfterAttributeName(e):this._state===A?this._stateBeforeAttributeValue(e):this._state===S?this._stateInAttributeValueDoubleQuotes(e):this._state===j?this._stateInAttributeValueSingleQuotes(e):this._state===E?this._stateInAttributeValueNoQuotes(e):this._state===O?this._stateBeforeDeclaration(e):this._state===k?this._stateInDeclaration(e):this._state===T?this._stateInProcessingInstruction(e):this._state===C?this._stateBeforeComment(e):this._state===I?this._stateInComment(e):this._state===D?this._stateAfterComment1(e):this._state===L?this._stateAfterComment2(e):this._state===M?this._stateBeforeCdata1(e):this._state===R?this._stateBeforeCdata2(e):this._state===U?this._stateBeforeCdata3(e):this._state===P?this._stateBeforeCdata4(e):this._state===q?this._stateBeforeCdata5(e):this._state===B?this._stateBeforeCdata6(e):this._state===N?this._stateInCdata(e):this._state===z?this._stateAfterCdata1(e):this._state===$?this._stateAfterCdata2(e):this._state===F?this._stateBeforeSpecial(e):this._state===V?this._stateBeforeSpecialEnd(e):this._state===H?this._stateBeforeScript1(e):this._state===Y?this._stateBeforeScript2(e):this._state===J?this._stateBeforeScript3(e):this._state===W?this._stateBeforeScript4(e):this._state===Q?this._stateBeforeScript5(e):this._state===G?this._stateAfterScript1(e):this._state===K?this._stateAfterScript2(e):this._state===X?this._stateAfterScript3(e):this._state===Z?this._stateAfterScript4(e):this._state===ee?this._stateAfterScript5(e):this._state===te?this._stateBeforeStyle1(e):this._state===ne?this._stateBeforeStyle2(e):this._state===re?this._stateBeforeStyle3(e):this._state===ie?this._stateBeforeStyle4(e):this._state===ae?this._stateAfterStyle1(e):this._state===oe?this._stateAfterStyle2(e):this._state===se?this._stateAfterStyle3(e):this._state===le?this._stateAfterStyle4(e):this._state===ue?this._stateBeforeEntity(e):this._state===ce?this._stateBeforeNumericEntity(e):this._state===pe?this._stateInNamedEntity(e):this._state===he?this._stateInNumericEntity(e):this._state===fe?this._stateInHexEntity(e):this._cbs.onerror(Error("unknown _state"),this._state),this._index++}this._cleanup()},s.prototype.pause=function(){this._running=!1},s.prototype.resume=function(){this._running=!0,this._index<this._buffer.length&&this._parse(),this._ended&&this._finish()},s.prototype.end=function(e){this._ended&&this._cbs.onerror(Error(".end() after done!")),e&&this.write(e),this._ended=!0,this._running&&this._finish()},s.prototype._finish=function(){this._sectionStart<this._index&&this._handleTrailingData(),this._cbs.onend()},s.prototype._handleTrailingData=function(){var e=this._buffer.substr(this._sectionStart);this._state===N||this._state===z||this._state===$?this._cbs.oncdata(e):this._state===I||this._state===D||this._state===L?this._cbs.oncomment(e):this._state!==pe||this._xmlMode?this._state!==he||this._xmlMode?this._state!==fe||this._xmlMode?this._state!==m&&this._state!==w&&this._state!==A&&this._state!==x&&this._state!==_&&this._state!==j&&this._state!==S&&this._state!==E&&this._state!==v&&this._cbs.ontext(e):(this._decodeNumericEntity(3,16),this._sectionStart<this._index&&(this._state=this._baseState,this._handleTrailingData())):(this._decodeNumericEntity(2,10),this._sectionStart<this._index&&(this._state=this._baseState,this._handleTrailingData())):(this._parseLegacyEntity(),this._sectionStart<this._index&&(this._state=this._baseState,this._handleTrailingData()))},s.prototype.reset=function(){s.call(this,{xmlMode:this._xmlMode,decodeEntities:this._decodeEntities},this._cbs)},s.prototype.getAbsoluteIndex=function(){return this._bufferOffset+this._index},s.prototype._getSection=function(){return this._buffer.substring(this._sectionStart,this._index)},s.prototype._emitToken=function(e){this._cbs[e](this._getSection()),this._sectionStart=-1},s.prototype._emitPartial=function(e){this._baseState!==f?this._cbs.onattribdata(e):this._cbs.ontext(e)}},{"entities/lib/decode_codepoint.js":22,"entities/maps/entities.json":25,"entities/maps/legacy.json":26,"entities/maps/xml.json":27}],35:[function(e,t,n){function r(e,t){var n=this._parser=new i(e,t),r=this._decoder=new o;a.call(this,{decodeStrings:!1}),this.once("finish",function(){n.end(r.end())})}t.exports=r;var i=e("./Parser.js"),a=e("stream").Writable||e("readable-stream").Writable,o=e("string_decoder").StringDecoder,s=e("buffer").Buffer;e("inherits")(r,a),a.prototype._write=function(e,t,n){e instanceof s&&(e=this._decoder.write(e)),this._parser.write(e),n()}},{"./Parser.js":31,buffer:5,inherits:38,"readable-stream":3,stream:55,string_decoder:56}],36:[function(e,t,n){function r(e,n){return delete t.exports[e],t.exports[e]=n,n}var i=e("./Parser.js"),a=e("domhandler");t.exports={Parser:i,Tokenizer:e("./Tokenizer.js"),ElementType:e("domelementtype"),DomHandler:a,get FeedHandler(){return r("FeedHandler",e("./FeedHandler.js"))},get Stream(){return r("Stream",e("./Stream.js"))},get WritableStream(){return r("WritableStream",e("./WritableStream.js"))},get ProxyHandler(){return r("ProxyHandler",e("./ProxyHandler.js"))},get DomUtils(){return r("DomUtils",e("domutils"))},get CollectingHandler(){return r("CollectingHandler",e("./CollectingHandler.js"))},DefaultHandler:a,get RssHandler(){return r("RssHandler",this.FeedHandler)},parseDOM:function(e,t){var n=new a(t);return new i(n,t).end(e),n.dom},parseFeed:function(e,n){var r=new t.exports.FeedHandler(n);return new i(r,n).end(e),r.dom},createDomStream:function(e,t,n){var r=new a(e,t,n);return new i(r,t)},EVENTS:{attribute:2,cdatastart:0,cdataend:0,text:1,processinginstruction:2,comment:1,commentend:0,closetag:1,opentag:2,opentagname:1,error:1,end:0}}},{"./CollectingHandler.js":29,"./FeedHandler.js":30,"./Parser.js":31,"./ProxyHandler.js":32,"./Stream.js":33,"./Tokenizer.js":34,"./WritableStream.js":35,domelementtype:9,domhandler:10,domutils:13}],37:[function(e,t,n){n.read=function(e,t,n,r,i){var a,o,s=8*i-r-1,l=(1<<s)-1,u=l>>1,c=-7,p=n?i-1:0,h=n?-1:1,f=e[t+p];for(p+=h,a=f&(1<<-c)-1,f>>=-c,c+=s;c>0;a=256*a+e[t+p],p+=h,c-=8);for(o=a&(1<<-c)-1,a>>=-c,c+=r;c>0;o=256*o+e[t+p],p+=h,c-=8);if(0===a)a=1-u;else{if(a===l)return o?NaN:(f?-1:1)*(1/0);o+=Math.pow(2,r),a-=u}return(f?-1:1)*o*Math.pow(2,a-r)},n.write=function(e,t,n,r,i,a){var o,s,l,u=8*a-i-1,c=(1<<u)-1,p=c>>1,h=23===i?Math.pow(2,-24)-Math.pow(2,-77):0,f=r?0:a-1,d=r?1:-1,m=t<0||0===t&&1/t<0?1:0;for(t=Math.abs(t),isNaN(t)||t===1/0?(s=isNaN(t)?1:0,o=c):(o=Math.floor(Math.log(t)/Math.LN2),t*(l=Math.pow(2,-o))<1&&(o--,l*=2),t+=o+p>=1?h/l:h*Math.pow(2,1-p),t*l>=2&&(o++,l/=2),o+p>=c?(s=0,o=c):o+p>=1?(s=(t*l-1)*Math.pow(2,i),o+=p):(s=t*Math.pow(2,p-1)*Math.pow(2,i),o=0));i>=8;e[n+f]=255&s,f+=d,s/=256,i-=8);for(o=o<<i|s,u+=i;u>0;e[n+f]=255&o,f+=d,o/=256,u-=8);e[n+f-d]|=128*m}},{}],38:[function(e,t,n){"function"==typeof Object.create?t.exports=function(e,t){e.super_=t,e.prototype=Object.create(t.prototype,{constructor:{value:e,enumerable:!1,writable:!0,configurable:!0}})}:t.exports=function(e,t){e.super_=t;var n=function(){};n.prototype=t.prototype,e.prototype=new n,e.prototype.constructor=e}},{}],39:[function(e,t,n){function r(e){return!!e.constructor&&"function"==typeof e.constructor.isBuffer&&e.constructor.isBuffer(e)}function i(e){return"function"==typeof e.readFloatLE&&"function"==typeof e.slice&&r(e.slice(0,0))}t.exports=function(e){return null!=e&&(r(e)||i(e)||!!e._isBuffer)}},{}],40:[function(e,t,n){var r={}.toString;t.exports=Array.isArray||function(e){return"[object Array]"==r.call(e)}},{}],41:[function(e,t,n){(function(e){"use strict";function n(t,n,r,i){if("function"!=typeof t)throw new TypeError('"callback" argument must be a function');var a,o,s=arguments.length;switch(s){case 0:case 1:return e.nextTick(t);case 2:return e.nextTick(function(){t.call(null,n)});case 3:return e.nextTick(function(){t.call(null,n,r)});case 4:return e.nextTick(function(){t.call(null,n,r,i)});default:for(a=new Array(s-1),o=0;o<a.length;)a[o++]=arguments[o];return e.nextTick(function(){t.apply(null,a)})}}!e.version||0===e.version.indexOf("v0.")||0===e.version.indexOf("v1.")&&0!==e.version.indexOf("v1.8.")?t.exports=n:t.exports=e.nextTick}).call(this,e("_process"))},{_process:42}],42:[function(e,t,n){function r(){throw new Error("setTimeout has not been defined")}function i(){throw new Error("clearTimeout has not been defined")}function a(e){if(p===setTimeout)return setTimeout(e,0);if((p===r||!p)&&setTimeout)return p=setTimeout,setTimeout(e,0);try{return p(e,0)}catch(t){try{return p.call(null,e,0)}catch(t){return p.call(this,e,0)}}}function o(e){if(h===clearTimeout)return clearTimeout(e);if((h===i||!h)&&clearTimeout)return h=clearTimeout,clearTimeout(e);try{return h(e)}catch(t){try{return h.call(null,e)}catch(t){return h.call(this,e)}}}function s(){g&&d&&(g=!1,d.length?m=d.concat(m):y=-1,m.length&&l())}function l(){if(!g){var e=a(s);g=!0;for(var t=m.length;t;){for(d=m,m=[];++y<t;)d&&d[y].run();y=-1,t=m.length}d=null,g=!1,o(e)}}function u(e,t){this.fun=e,this.array=t}function c(){}var p,h,f=t.exports={};!function(){try{p="function"==typeof setTimeout?setTimeout:r}catch(e){p=r}try{h="function"==typeof clearTimeout?clearTimeout:i}catch(e){h=i}}();var d,m=[],g=!1,y=-1;f.nextTick=function(e){var t=new Array(arguments.length-1);if(arguments.length>1)for(var n=1;n<arguments.length;n++)t[n-1]=arguments[n];m.push(new u(e,t)),1!==m.length||g||a(l)},u.prototype.run=function(){this.fun.apply(null,this.array)},f.title="browser",f.browser=!0,f.env={},f.argv=[],f.version="",f.versions={},f.on=c,f.addListener=c,f.once=c,f.off=c,f.removeListener=c,f.removeAllListeners=c,f.emit=c,f.binding=function(e){throw new Error("process.binding is not supported")},f.cwd=function(){return"/"},f.chdir=function(e){throw new Error("process.chdir is not supported")},f.umask=function(){return 0}},{}],43:[function(e,t,n){t.exports=e("./lib/_stream_duplex.js")},{"./lib/_stream_duplex.js":44}],44:[function(e,t,n){"use strict";function r(e){return this instanceof r?(u.call(this,e),c.call(this,e),e&&e.readable===!1&&(this.readable=!1),e&&e.writable===!1&&(this.writable=!1),this.allowHalfOpen=!0,e&&e.allowHalfOpen===!1&&(this.allowHalfOpen=!1),void this.once("end",i)):new r(e)}function i(){this.allowHalfOpen||this._writableState.ended||s(a,this)}function a(e){e.end()}var o=Object.keys||function(e){var t=[];for(var n in e)t.push(n);return t};t.exports=r;var s=e("process-nextick-args"),l=e("core-util-is");l.inherits=e("inherits");var u=e("./_stream_readable"),c=e("./_stream_writable");l.inherits(r,u);for(var p=o(c.prototype),h=0;h<p.length;h++){var f=p[h];r.prototype[f]||(r.prototype[f]=c.prototype[f])}},{"./_stream_readable":46,"./_stream_writable":48,"core-util-is":6,inherits:38,"process-nextick-args":41}],45:[function(e,t,n){"use strict";function r(e){return this instanceof r?void i.call(this,e):new r(e)}t.exports=r;var i=e("./_stream_transform"),a=e("core-util-is");a.inherits=e("inherits"),a.inherits(r,i),r.prototype._transform=function(e,t,n){n(null,e)}},{"./_stream_transform":47,"core-util-is":6,inherits:38}],46:[function(e,t,n){(function(n){"use strict";function r(e,t,n){return"function"==typeof e.prependListener?e.prependListener(t,n):void(e._events&&e._events[t]?C(e._events[t])?e._events[t].unshift(n):e._events[t]=[n,e._events[t]]:e.on(t,n))}function i(t,n){N=N||e("./_stream_duplex"),t=t||{},this.objectMode=!!t.objectMode,n instanceof N&&(this.objectMode=this.objectMode||!!t.readableObjectMode);var r=t.highWaterMark,i=this.objectMode?16:16384;this.highWaterMark=r||0===r?r:i,this.highWaterMark=~~this.highWaterMark,this.buffer=new B,this.length=0,this.pipes=null,this.pipesCount=0,this.flowing=null,this.ended=!1,this.endEmitted=!1,this.reading=!1,this.sync=!0,this.needReadable=!1,this.emittedReadable=!1,this.readableListening=!1,this.resumeScheduled=!1,this.defaultEncoding=t.defaultEncoding||"utf8",this.ranOut=!1,this.awaitDrain=0,this.readingMore=!1,this.decoder=null,this.encoding=null,t.encoding&&(q||(q=e("string_decoder/").StringDecoder),this.decoder=new q(t.encoding),this.encoding=t.encoding)}function a(t){return N=N||e("./_stream_duplex"),this instanceof a?(this._readableState=new i(t,this),this.readable=!0,t&&"function"==typeof t.read&&(this._read=t.read),void I.call(this)):new a(t)}function o(e,t,n,r,i){var a=c(t,n);if(a)e.emit("error",a);else if(null===n)t.reading=!1,p(e,t);else if(t.objectMode||n&&n.length>0)if(t.ended&&!i){var o=new Error("stream.push() after EOF");e.emit("error",o)}else if(t.endEmitted&&i){var l=new Error("stream.unshift() after end event");e.emit("error",l)}else{var u;!t.decoder||i||r||(n=t.decoder.write(n),u=!t.objectMode&&0===n.length),i||(t.reading=!1),u||(t.flowing&&0===t.length&&!t.sync?(e.emit("data",n),e.read(0)):(t.length+=t.objectMode?1:n.length,i?t.buffer.unshift(n):t.buffer.push(n),t.needReadable&&h(e))),d(e,t)}else i||(t.reading=!1);return s(t)}function s(e){return!e.ended&&(e.needReadable||e.length<e.highWaterMark||0===e.length)}function l(e){return e>=z?e=z:(e--,e|=e>>>1,e|=e>>>2,e|=e>>>4,e|=e>>>8,e|=e>>>16,e++),e}function u(e,t){return e<=0||0===t.length&&t.ended?0:t.objectMode?1:e!==e?t.flowing&&t.length?t.buffer.head.data.length:t.length:(e>t.highWaterMark&&(t.highWaterMark=l(e)),e<=t.length?e:t.ended?t.length:(t.needReadable=!0,0))}function c(e,t){var n=null;return L.isBuffer(t)||"string"==typeof t||null===t||void 0===t||e.objectMode||(n=new TypeError("Invalid non-string/buffer chunk")),n}function p(e,t){if(!t.ended){if(t.decoder){var n=t.decoder.end();n&&n.length&&(t.buffer.push(n),t.length+=t.objectMode?1:n.length)}t.ended=!0,h(e)}}function h(e){var t=e._readableState;t.needReadable=!1,t.emittedReadable||(P("emitReadable",t.flowing),t.emittedReadable=!0,t.sync?T(f,e):f(e))}function f(e){P("emit readable"),e.emit("readable"),w(e)}function d(e,t){t.readingMore||(t.readingMore=!0,T(m,e,t))}function m(e,t){for(var n=t.length;!t.reading&&!t.flowing&&!t.ended&&t.length<t.highWaterMark&&(P("maybeReadMore read 0"),e.read(0),n!==t.length);)n=t.length;t.readingMore=!1}function g(e){return function(){var t=e._readableState;P("pipeOnDrain",t.awaitDrain),t.awaitDrain&&t.awaitDrain--,0===t.awaitDrain&&D(e,"data")&&(t.flowing=!0,w(e))}}function y(e){P("readable nexttick read 0"),e.read(0)}function v(e,t){t.resumeScheduled||(t.resumeScheduled=!0,T(b,e,t))}function b(e,t){t.reading||(P("resume read 0"),e.read(0)),t.resumeScheduled=!1,t.awaitDrain=0,e.emit("resume"),w(e),t.flowing&&!t.reading&&e.read(0)}function w(e){var t=e._readableState;for(P("flow",t.flowing);t.flowing&&null!==e.read(););}function _(e,t){if(0===t.length)return null;var n;return t.objectMode?n=t.buffer.shift():!e||e>=t.length?(n=t.decoder?t.buffer.join(""):1===t.buffer.length?t.buffer.head.data:t.buffer.concat(t.length),t.buffer.clear()):n=x(e,t.buffer,t.decoder),n}function x(e,t,n){var r;return e<t.head.data.length?(r=t.head.data.slice(0,e),t.head.data=t.head.data.slice(e)):r=e===t.head.data.length?t.shift():n?A(e,t):S(e,t),r}function A(e,t){var n=t.head,r=1,i=n.data;for(e-=i.length;n=n.next;){var a=n.data,o=e>a.length?a.length:e;if(i+=o===a.length?a:a.slice(0,e),e-=o,0===e){o===a.length?(++r,n.next?t.head=n.next:t.head=t.tail=null):(t.head=n,n.data=a.slice(o));break}++r}return t.length-=r,i}function S(e,t){var n=M.allocUnsafe(e),r=t.head,i=1;for(r.data.copy(n),e-=r.data.length;r=r.next;){var a=r.data,o=e>a.length?a.length:e;if(a.copy(n,n.length-e,0,o),e-=o,0===e){o===a.length?(++i,r.next?t.head=r.next:t.head=t.tail=null):(t.head=r,r.data=a.slice(o));break}++i}return t.length-=i,n}function j(e){var t=e._readableState;if(t.length>0)throw new Error('"endReadable()" called on non-empty stream');t.endEmitted||(t.ended=!0,T(E,t,e))}function E(e,t){e.endEmitted||0!==e.length||(e.endEmitted=!0,t.readable=!1,t.emit("end"))}function O(e,t){for(var n=0,r=e.length;n<r;n++)t(e[n],n)}function k(e,t){for(var n=0,r=e.length;n<r;n++)if(e[n]===t)return n;return-1}t.exports=a;var T=e("process-nextick-args"),C=e("isarray");a.ReadableState=i;var I,D=(e("events").EventEmitter,function(e,t){return e.listeners(t).length});!function(){try{I=e("stream")}catch(t){}finally{I||(I=e("events").EventEmitter)}}();var L=e("buffer").Buffer,M=e("buffer-shims"),R=e("core-util-is");R.inherits=e("inherits");var U=e("util"),P=void 0;P=U&&U.debuglog?U.debuglog("stream"):function(){};var q,B=e("./internal/streams/BufferList");R.inherits(a,I);var N,N;a.prototype.push=function(e,t){var n=this._readableState;return n.objectMode||"string"!=typeof e||(t=t||n.defaultEncoding,t!==n.encoding&&(e=M.from(e,t),t="")),o(this,n,e,t,!1)},a.prototype.unshift=function(e){var t=this._readableState;return o(this,t,e,"",!0)},a.prototype.isPaused=function(){return this._readableState.flowing===!1},a.prototype.setEncoding=function(t){return q||(q=e("string_decoder/").StringDecoder),this._readableState.decoder=new q(t),this._readableState.encoding=t,this};var z=8388608;a.prototype.read=function(e){P("read",e),e=parseInt(e,10);var t=this._readableState,n=e;if(0!==e&&(t.emittedReadable=!1),0===e&&t.needReadable&&(t.length>=t.highWaterMark||t.ended))return P("read: emitReadable",t.length,t.ended),0===t.length&&t.ended?j(this):h(this),null;if(e=u(e,t),0===e&&t.ended)return 0===t.length&&j(this),null;var r=t.needReadable;P("need readable",r),(0===t.length||t.length-e<t.highWaterMark)&&(r=!0,P("length less than watermark",r)),t.ended||t.reading?(r=!1,P("reading or ended",r)):r&&(P("do read"),t.reading=!0,t.sync=!0,0===t.length&&(t.needReadable=!0),this._read(t.highWaterMark),t.sync=!1,t.reading||(e=u(n,t)));var i;return i=e>0?_(e,t):null,null===i?(t.needReadable=!0,e=0):t.length-=e,0===t.length&&(t.ended||(t.needReadable=!0),n!==e&&t.ended&&j(this)),null!==i&&this.emit("data",i),i},a.prototype._read=function(e){this.emit("error",new Error("not implemented"))},a.prototype.pipe=function(e,t){function i(e){P("onunpipe"),e===h&&o()}function a(){P("onend"),e.end()}function o(){P("cleanup"),e.removeListener("close",u),e.removeListener("finish",c),e.removeListener("drain",y),e.removeListener("error",l),e.removeListener("unpipe",i),h.removeListener("end",a),h.removeListener("end",o),h.removeListener("data",s),v=!0,!f.awaitDrain||e._writableState&&!e._writableState.needDrain||y()}function s(t){P("ondata"),b=!1;var n=e.write(t);!1!==n||b||((1===f.pipesCount&&f.pipes===e||f.pipesCount>1&&k(f.pipes,e)!==-1)&&!v&&(P("false write response, pause",h._readableState.awaitDrain),h._readableState.awaitDrain++,b=!0),h.pause())}function l(t){P("onerror",t),p(),e.removeListener("error",l),0===D(e,"error")&&e.emit("error",t)}function u(){e.removeListener("finish",c),p()}function c(){P("onfinish"),e.removeListener("close",u),p()}function p(){P("unpipe"),h.unpipe(e)}var h=this,f=this._readableState;switch(f.pipesCount){case 0:f.pipes=e;break;case 1:f.pipes=[f.pipes,e];break;default:f.pipes.push(e)}f.pipesCount+=1,P("pipe count=%d opts=%j",f.pipesCount,t);var d=(!t||t.end!==!1)&&e!==n.stdout&&e!==n.stderr,m=d?a:o;f.endEmitted?T(m):h.once("end",m),e.on("unpipe",i);var y=g(h);e.on("drain",y);var v=!1,b=!1;return h.on("data",s),r(e,"error",l),e.once("close",u),e.once("finish",c),e.emit("pipe",h),f.flowing||(P("pipe resume"),h.resume()),e},a.prototype.unpipe=function(e){var t=this._readableState;if(0===t.pipesCount)return this;if(1===t.pipesCount)return e&&e!==t.pipes?this:(e||(e=t.pipes),t.pipes=null,t.pipesCount=0,t.flowing=!1,e&&e.emit("unpipe",this),this);if(!e){var n=t.pipes,r=t.pipesCount;t.pipes=null,t.pipesCount=0,t.flowing=!1;for(var i=0;i<r;i++)n[i].emit("unpipe",this);return this}var a=k(t.pipes,e);return a===-1?this:(t.pipes.splice(a,1),t.pipesCount-=1,1===t.pipesCount&&(t.pipes=t.pipes[0]),e.emit("unpipe",this),this)},a.prototype.on=function(e,t){var n=I.prototype.on.call(this,e,t);if("data"===e)this._readableState.flowing!==!1&&this.resume();else if("readable"===e){var r=this._readableState;r.endEmitted||r.readableListening||(r.readableListening=r.needReadable=!0,r.emittedReadable=!1,r.reading?r.length&&h(this,r):T(y,this))}return n},a.prototype.addListener=a.prototype.on,a.prototype.resume=function(){var e=this._readableState;return e.flowing||(P("resume"),e.flowing=!0,v(this,e)),this},a.prototype.pause=function(){return P("call pause flowing=%j",this._readableState.flowing),!1!==this._readableState.flowing&&(P("pause"),this._readableState.flowing=!1,this.emit("pause")),this},a.prototype.wrap=function(e){var t=this._readableState,n=!1,r=this;e.on("end",function(){if(P("wrapped end"),t.decoder&&!t.ended){var e=t.decoder.end();e&&e.length&&r.push(e)}r.push(null)}),e.on("data",function(i){if(P("wrapped data"),t.decoder&&(i=t.decoder.write(i)),(!t.objectMode||null!==i&&void 0!==i)&&(t.objectMode||i&&i.length)){var a=r.push(i);a||(n=!0,e.pause())}});for(var i in e)void 0===this[i]&&"function"==typeof e[i]&&(this[i]=function(t){return function(){return e[t].apply(e,arguments)}}(i));var a=["error","close","destroy","pause","resume"];return O(a,function(t){e.on(t,r.emit.bind(r,t))}),r._read=function(t){P("wrapped _read",t),n&&(n=!1,e.resume())},r},a._fromList=_}).call(this,e("_process"))},{"./_stream_duplex":44,"./internal/streams/BufferList":49,_process:42,buffer:5,"buffer-shims":4,"core-util-is":6,events:28,inherits:38,isarray:40,"process-nextick-args":41,"string_decoder/":56,util:3}],47:[function(e,t,n){"use strict";function r(e){this.afterTransform=function(t,n){return i(e,t,n)},this.needTransform=!1,this.transforming=!1,this.writecb=null,this.writechunk=null,this.writeencoding=null}function i(e,t,n){var r=e._transformState;r.transforming=!1;var i=r.writecb;if(!i)return e.emit("error",new Error("no writecb in Transform class"));r.writechunk=null,r.writecb=null,null!==n&&void 0!==n&&e.push(n),i(t);var a=e._readableState;a.reading=!1,(a.needReadable||a.length<a.highWaterMark)&&e._read(a.highWaterMark)}function a(e){if(!(this instanceof a))return new a(e);s.call(this,e),this._transformState=new r(this);var t=this;this._readableState.needReadable=!0,this._readableState.sync=!1,e&&("function"==typeof e.transform&&(this._transform=e.transform),"function"==typeof e.flush&&(this._flush=e.flush)),this.once("prefinish",function(){"function"==typeof this._flush?this._flush(function(e){o(t,e)}):o(t)})}function o(e,t){if(t)return e.emit("error",t);var n=e._writableState,r=e._transformState;if(n.length)throw new Error("Calling transform done when ws.length != 0");if(r.transforming)throw new Error("Calling transform done when still transforming");return e.push(null)}t.exports=a;var s=e("./_stream_duplex"),l=e("core-util-is");l.inherits=e("inherits"),l.inherits(a,s),a.prototype.push=function(e,t){return this._transformState.needTransform=!1,s.prototype.push.call(this,e,t)},a.prototype._transform=function(e,t,n){throw new Error("Not implemented")},a.prototype._write=function(e,t,n){var r=this._transformState;if(r.writecb=n,r.writechunk=e,r.writeencoding=t,!r.transforming){var i=this._readableState;(r.needTransform||i.needReadable||i.length<i.highWaterMark)&&this._read(i.highWaterMark)}},a.prototype._read=function(e){var t=this._transformState;null!==t.writechunk&&t.writecb&&!t.transforming?(t.transforming=!0,this._transform(t.writechunk,t.writeencoding,t.afterTransform)):t.needTransform=!0}},{"./_stream_duplex":44,"core-util-is":6,inherits:38}],48:[function(e,t,n){(function(n){"use strict";function r(){}function i(e,t,n){this.chunk=e,this.encoding=t,this.callback=n,this.next=null}function a(t,n){C=C||e("./_stream_duplex"),t=t||{},this.objectMode=!!t.objectMode,n instanceof C&&(this.objectMode=this.objectMode||!!t.writableObjectMode);var r=t.highWaterMark,i=this.objectMode?16:16384;this.highWaterMark=r||0===r?r:i,this.highWaterMark=~~this.highWaterMark,this.needDrain=!1,this.ending=!1,this.ended=!1,this.finished=!1;var a=t.decodeStrings===!1;this.decodeStrings=!a,this.defaultEncoding=t.defaultEncoding||"utf8",this.length=0,this.writing=!1,this.corked=0,this.sync=!0,this.bufferProcessing=!1,this.onwrite=function(e){d(n,e)},this.writecb=null,this.writelen=0,this.bufferedRequest=null,this.lastBufferedRequest=null,this.pendingcb=0,this.prefinished=!1,this.errorEmitted=!1,this.bufferedRequestCount=0,this.corkedRequestsFree=new x(this)}function o(t){return C=C||e("./_stream_duplex"),this instanceof o||this instanceof C?(this._writableState=new a(t,this),this.writable=!0,t&&("function"==typeof t.write&&(this._write=t.write),"function"==typeof t.writev&&(this._writev=t.writev)),void E.call(this)):new o(t)}function s(e,t){var n=new Error("write after end");e.emit("error",n),A(t,n)}function l(e,t,n,r){var i=!0,a=!1;return null===n?a=new TypeError("May not write null values to stream"):k.isBuffer(n)||"string"==typeof n||void 0===n||t.objectMode||(a=new TypeError("Invalid non-string/buffer chunk")),a&&(e.emit("error",a),A(r,a),i=!1),i}function u(e,t,n){return e.objectMode||e.decodeStrings===!1||"string"!=typeof t||(t=T.from(t,n)),t}function c(e,t,n,r,a){n=u(t,n,r),k.isBuffer(n)&&(r="buffer");var o=t.objectMode?1:n.length;t.length+=o;var s=t.length<t.highWaterMark;if(s||(t.needDrain=!0),t.writing||t.corked){var l=t.lastBufferedRequest;t.lastBufferedRequest=new i(n,r,a),l?l.next=t.lastBufferedRequest:t.bufferedRequest=t.lastBufferedRequest,t.bufferedRequestCount+=1}else p(e,t,!1,o,n,r,a);return s}function p(e,t,n,r,i,a,o){t.writelen=r,t.writecb=o,t.writing=!0,t.sync=!0,n?e._writev(i,t.onwrite):e._write(i,a,t.onwrite),t.sync=!1}function h(e,t,n,r,i){--t.pendingcb,n?A(i,r):i(r),e._writableState.errorEmitted=!0,e.emit("error",r)}function f(e){e.writing=!1,e.writecb=null,e.length-=e.writelen,e.writelen=0}function d(e,t){var n=e._writableState,r=n.sync,i=n.writecb;if(f(n),t)h(e,n,r,t,i);else{var a=v(n);a||n.corked||n.bufferProcessing||!n.bufferedRequest||y(e,n),r?S(m,e,n,a,i):m(e,n,a,i)}}function m(e,t,n,r){n||g(e,t),t.pendingcb--,r(),w(e,t)}function g(e,t){0===t.length&&t.needDrain&&(t.needDrain=!1,e.emit("drain"))}function y(e,t){t.bufferProcessing=!0;var n=t.bufferedRequest;if(e._writev&&n&&n.next){var r=t.bufferedRequestCount,i=new Array(r),a=t.corkedRequestsFree;a.entry=n;for(var o=0;n;)i[o]=n,n=n.next,o+=1;p(e,t,!0,t.length,i,"",a.finish),t.pendingcb++,t.lastBufferedRequest=null,a.next?(t.corkedRequestsFree=a.next,a.next=null):t.corkedRequestsFree=new x(t)}else{for(;n;){var s=n.chunk,l=n.encoding,u=n.callback,c=t.objectMode?1:s.length;if(p(e,t,!1,c,s,l,u),n=n.next,t.writing)break}null===n&&(t.lastBufferedRequest=null)}t.bufferedRequestCount=0,t.bufferedRequest=n,t.bufferProcessing=!1}function v(e){return e.ending&&0===e.length&&null===e.bufferedRequest&&!e.finished&&!e.writing}function b(e,t){t.prefinished||(t.prefinished=!0,e.emit("prefinish"))}function w(e,t){var n=v(t);return n&&(0===t.pendingcb?(b(e,t),t.finished=!0,e.emit("finish")):b(e,t)),n}function _(e,t,n){t.ending=!0,w(e,t),n&&(t.finished?A(n):e.once("finish",n)),t.ended=!0,e.writable=!1}function x(e){var t=this;this.next=null,this.entry=null,this.finish=function(n){var r=t.entry;for(t.entry=null;r;){var i=r.callback;e.pendingcb--,i(n),r=r.next}e.corkedRequestsFree?e.corkedRequestsFree.next=t:e.corkedRequestsFree=t}}t.exports=o;var A=e("process-nextick-args"),S=!n.browser&&["v0.10","v0.9."].indexOf(n.version.slice(0,5))>-1?setImmediate:A;o.WritableState=a;var j=e("core-util-is");j.inherits=e("inherits");var E,O={deprecate:e("util-deprecate")};!function(){try{E=e("stream")}catch(t){}finally{E||(E=e("events").EventEmitter)}}();var k=e("buffer").Buffer,T=e("buffer-shims");j.inherits(o,E);var C;a.prototype.getBuffer=function(){for(var e=this.bufferedRequest,t=[];e;)t.push(e),e=e.next;return t},function(){try{Object.defineProperty(a.prototype,"buffer",{get:O.deprecate(function(){return this.getBuffer()},"_writableState.buffer is deprecated. Use _writableState.getBuffer instead.")})}catch(e){}}();var C;o.prototype.pipe=function(){this.emit("error",new Error("Cannot pipe, not readable"))},o.prototype.write=function(e,t,n){var i=this._writableState,a=!1;return"function"==typeof t&&(n=t,t=null),k.isBuffer(e)?t="buffer":t||(t=i.defaultEncoding),"function"!=typeof n&&(n=r),i.ended?s(this,n):l(this,i,e,n)&&(i.pendingcb++,a=c(this,i,e,t,n)),a},o.prototype.cork=function(){var e=this._writableState;e.corked++},o.prototype.uncork=function(){var e=this._writableState;e.corked&&(e.corked--,e.writing||e.corked||e.finished||e.bufferProcessing||!e.bufferedRequest||y(this,e))},o.prototype.setDefaultEncoding=function(e){if("string"==typeof e&&(e=e.toLowerCase()),!(["hex","utf8","utf-8","ascii","binary","base64","ucs2","ucs-2","utf16le","utf-16le","raw"].indexOf((e+"").toLowerCase())>-1))throw new TypeError("Unknown encoding: "+e);
+return this._writableState.defaultEncoding=e,this},o.prototype._write=function(e,t,n){n(new Error("not implemented"))},o.prototype._writev=null,o.prototype.end=function(e,t,n){var r=this._writableState;"function"==typeof e?(n=e,e=null,t=null):"function"==typeof t&&(n=t,t=null),null!==e&&void 0!==e&&this.write(e,t),r.corked&&(r.corked=1,this.uncork()),r.ending||r.finished||_(this,r,n)}}).call(this,e("_process"))},{"./_stream_duplex":44,_process:42,buffer:5,"buffer-shims":4,"core-util-is":6,events:28,inherits:38,"process-nextick-args":41,"util-deprecate":57}],49:[function(e,t,n){"use strict";function r(){this.head=null,this.tail=null,this.length=0}var i=(e("buffer").Buffer,e("buffer-shims"));t.exports=r,r.prototype.push=function(e){var t={data:e,next:null};this.length>0?this.tail.next=t:this.head=t,this.tail=t,++this.length},r.prototype.unshift=function(e){var t={data:e,next:this.head};0===this.length&&(this.tail=t),this.head=t,++this.length},r.prototype.shift=function(){if(0!==this.length){var e=this.head.data;return 1===this.length?this.head=this.tail=null:this.head=this.head.next,--this.length,e}},r.prototype.clear=function(){this.head=this.tail=null,this.length=0},r.prototype.join=function(e){if(0===this.length)return"";for(var t=this.head,n=""+t.data;t=t.next;)n+=e+t.data;return n},r.prototype.concat=function(e){if(0===this.length)return i.alloc(0);if(1===this.length)return this.head.data;for(var t=i.allocUnsafe(e>>>0),n=this.head,r=0;n;)n.data.copy(t,r),r+=n.data.length,n=n.next;return t}},{buffer:5,"buffer-shims":4}],50:[function(e,t,n){t.exports=e("./lib/_stream_passthrough.js")},{"./lib/_stream_passthrough.js":45}],51:[function(e,t,n){(function(r){var i=function(){try{return e("stream")}catch(t){}}();n=t.exports=e("./lib/_stream_readable.js"),n.Stream=i||n,n.Readable=n,n.Writable=e("./lib/_stream_writable.js"),n.Duplex=e("./lib/_stream_duplex.js"),n.Transform=e("./lib/_stream_transform.js"),n.PassThrough=e("./lib/_stream_passthrough.js"),!r.browser&&"disable"===r.env.READABLE_STREAM&&i&&(t.exports=i)}).call(this,e("_process"))},{"./lib/_stream_duplex.js":44,"./lib/_stream_passthrough.js":45,"./lib/_stream_readable.js":46,"./lib/_stream_transform.js":47,"./lib/_stream_writable.js":48,_process:42}],52:[function(e,t,n){t.exports=e("./lib/_stream_transform.js")},{"./lib/_stream_transform.js":47}],53:[function(e,t,n){t.exports=e("./lib/_stream_writable.js")},{"./lib/_stream_writable.js":48}],54:[function(e,t,n){t.exports=function(e){return e.replace(/[-\\^$*+?.()|[\]{}]/g,"\\$&")}},{}],55:[function(e,t,n){function r(){i.call(this)}t.exports=r;var i=e("events").EventEmitter,a=e("inherits");a(r,i),r.Readable=e("readable-stream/readable.js"),r.Writable=e("readable-stream/writable.js"),r.Duplex=e("readable-stream/duplex.js"),r.Transform=e("readable-stream/transform.js"),r.PassThrough=e("readable-stream/passthrough.js"),r.Stream=r,r.prototype.pipe=function(e,t){function n(t){e.writable&&!1===e.write(t)&&u.pause&&u.pause()}function r(){u.readable&&u.resume&&u.resume()}function a(){c||(c=!0,e.end())}function o(){c||(c=!0,"function"==typeof e.destroy&&e.destroy())}function s(e){if(l(),0===i.listenerCount(this,"error"))throw e}function l(){u.removeListener("data",n),e.removeListener("drain",r),u.removeListener("end",a),u.removeListener("close",o),u.removeListener("error",s),e.removeListener("error",s),u.removeListener("end",l),u.removeListener("close",l),e.removeListener("close",l)}var u=this;u.on("data",n),e.on("drain",r),e._isStdio||t&&t.end===!1||(u.on("end",a),u.on("close",o));var c=!1;return u.on("error",s),e.on("error",s),u.on("end",l),u.on("close",l),e.on("close",l),e.emit("pipe",u),e}},{events:28,inherits:38,"readable-stream/duplex.js":43,"readable-stream/passthrough.js":50,"readable-stream/readable.js":51,"readable-stream/transform.js":52,"readable-stream/writable.js":53}],56:[function(e,t,n){function r(e){if(e&&!l(e))throw new Error("Unknown encoding: "+e)}function i(e){return e.toString(this.encoding)}function a(e){this.charReceived=e.length%2,this.charLength=this.charReceived?2:0}function o(e){this.charReceived=e.length%3,this.charLength=this.charReceived?3:0}var s=e("buffer").Buffer,l=s.isEncoding||function(e){switch(e&&e.toLowerCase()){case"hex":case"utf8":case"utf-8":case"ascii":case"binary":case"base64":case"ucs2":case"ucs-2":case"utf16le":case"utf-16le":case"raw":return!0;default:return!1}},u=n.StringDecoder=function(e){switch(this.encoding=(e||"utf8").toLowerCase().replace(/[-_]/,""),r(e),this.encoding){case"utf8":this.surrogateSize=3;break;case"ucs2":case"utf16le":this.surrogateSize=2,this.detectIncompleteChar=a;break;case"base64":this.surrogateSize=3,this.detectIncompleteChar=o;break;default:return void(this.write=i)}this.charBuffer=new s(6),this.charReceived=0,this.charLength=0};u.prototype.write=function(e){for(var t="";this.charLength;){var n=e.length>=this.charLength-this.charReceived?this.charLength-this.charReceived:e.length;if(e.copy(this.charBuffer,this.charReceived,0,n),this.charReceived+=n,this.charReceived<this.charLength)return"";e=e.slice(n,e.length),t=this.charBuffer.slice(0,this.charLength).toString(this.encoding);var r=t.charCodeAt(t.length-1);if(!(r>=55296&&r<=56319)){if(this.charReceived=this.charLength=0,0===e.length)return t;break}this.charLength+=this.surrogateSize,t=""}this.detectIncompleteChar(e);var i=e.length;this.charLength&&(e.copy(this.charBuffer,0,e.length-this.charReceived,i),i-=this.charReceived),t+=e.toString(this.encoding,0,i);var i=t.length-1,r=t.charCodeAt(i);if(r>=55296&&r<=56319){var a=this.surrogateSize;return this.charLength+=a,this.charReceived+=a,this.charBuffer.copy(this.charBuffer,a,0,a),e.copy(this.charBuffer,0,0,a),t.substring(0,i)}return t},u.prototype.detectIncompleteChar=function(e){for(var t=e.length>=3?3:e.length;t>0;t--){var n=e[e.length-t];if(1==t&&n>>5==6){this.charLength=2;break}if(t<=2&&n>>4==14){this.charLength=3;break}if(t<=3&&n>>3==30){this.charLength=4;break}}this.charReceived=t},u.prototype.end=function(e){var t="";if(e&&e.length&&(t=this.write(e)),this.charReceived){var n=this.charReceived,r=this.charBuffer,i=this.encoding;t+=r.slice(0,n).toString(i)}return t}},{buffer:5}],57:[function(e,t,n){(function(e){function n(e,t){function n(){if(!i){if(r("throwDeprecation"))throw new Error(t);r("traceDeprecation")?console.trace(t):console.warn(t),i=!0}return e.apply(this,arguments)}if(r("noDeprecation"))return e;var i=!1;return n}function r(t){try{if(!e.localStorage)return!1}catch(n){return!1}var r=e.localStorage[t];return null!=r&&"true"===String(r).toLowerCase()}t.exports=n}).call(this,"undefined"!=typeof global?global:"undefined"!=typeof self?self:"undefined"!=typeof window?window:{})},{}],58:[function(e,t,n){function r(){for(var e={},t=0;t<arguments.length;t++){var n=arguments[t];for(var r in n)i.call(n,r)&&(e[r]=n[r])}return e}t.exports=r;var i=Object.prototype.hasOwnProperty},{}]},{},[1])(1)}),function(e){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=e();else if("function"==typeof define&&define.amd)define([],e);else{var t;t="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:this,t.SwaggerClient=e()}}(function(){var t;return function n(e,t,r){function i(o,s){if(!t[o]){if(!e[o]){var l="function"==typeof require&&require;if(!s&&l)return l(o,!0);if(a)return a(o,!0);var u=new Error("Cannot find module '"+o+"'");throw u.code="MODULE_NOT_FOUND",u}var c=t[o]={exports:{}};e[o][0].call(c.exports,function(t){var n=e[o][1][t];return i(n?n:t)},c,c.exports,n,e,t,r)}return t[o].exports}for(var a="function"==typeof require&&require,o=0;o<r.length;o++)i(r[o]);return i}({1:[function(e,t,n){"use strict";var r=e("./lib/auth"),i=e("./lib/helpers"),a=e("./lib/client"),o=function(e,t){return i.log('This is deprecated, use "new SwaggerClient" instead.'),new a(e,t)};Array.prototype.indexOf||(Array.prototype.indexOf=function(e,t){for(var n=t||0,r=this.length;n<r;n++)if(this[n]===e)return n;return-1}),String.prototype.trim||(String.prototype.trim=function(){return this.replace(/^\s+|\s+$/g,"")}),String.prototype.endsWith||(String.prototype.endsWith=function(e){return this.indexOf(e,this.length-e.length)!==-1}),t.exports=a,a.ApiKeyAuthorization=r.ApiKeyAuthorization,a.PasswordAuthorization=r.PasswordAuthorization,a.CookieAuthorization=r.CookieAuthorization,a.SwaggerApi=o,a.SwaggerClient=o,a.SchemaMarkup=e("./lib/schema-markup")},{"./lib/auth":2,"./lib/client":3,"./lib/helpers":4,"./lib/schema-markup":7}],2:[function(e,t,n){"use strict";var r=e("./helpers"),i=e("btoa"),a=e("cookiejar").CookieJar,o={each:e("lodash-compat/collection/each"),includes:e("lodash-compat/collection/includes"),isObject:e("lodash-compat/lang/isObject"),isArray:e("lodash-compat/lang/isArray")},s=t.exports.SwaggerAuthorizations=function(e){this.authz=e||{}};s.prototype.add=function(e,t){if(o.isObject(e))for(var n in e)this.authz[n]=e[n];else"string"==typeof e&&(this.authz[e]=t);return t},s.prototype.remove=function(e){return delete this.authz[e]},s.prototype.apply=function(e,t){var n=!0,r=!t,i=[],a=e.clientAuthorizations||this.authz;return o.each(t,function(e,t){"string"==typeof t&&i.push(t),o.each(e,function(e,t){i.push(t)})}),o.each(a,function(t,a){if(r||o.includes(i,a)){var s=t.apply(e);n=n&&!!s}}),n};var l=t.exports.ApiKeyAuthorization=function(e,t,n){this.name=e,this.value=t,this.type=n};l.prototype.apply=function(e){if("query"===this.type){var t;if(e.url.indexOf("?")>0){t=e.url.substring(e.url.indexOf("?")+1);var n=t.split("&");if(n&&n.length>0)for(var r=0;r<n.length;r++){var i=n[r].split("=");if(i&&i.length>0&&i[0]===this.name)return!1}}return e.url.indexOf("?")>0?e.url=e.url+"&"+this.name+"="+this.value:e.url=e.url+"?"+this.name+"="+this.value,!0}if("header"===this.type)return"undefined"==typeof e.headers[this.name]&&(e.headers[this.name]=this.value),!0};var u=t.exports.CookieAuthorization=function(e){this.cookie=e};u.prototype.apply=function(e){return e.cookieJar=e.cookieJar||new a,e.cookieJar.setCookie(this.cookie),!0};var c=t.exports.PasswordAuthorization=function(e,t){3===arguments.length&&(r.log("PasswordAuthorization: the 'name' argument has been removed, pass only username and password"),e=arguments[1],t=arguments[2]),this.username=e,this.password=t};c.prototype.apply=function(e){return"undefined"==typeof e.headers.Authorization&&(e.headers.Authorization="Basic "+i(this.username+":"+this.password)),!0}},{"./helpers":4,btoa:13,cookiejar:18,"lodash-compat/collection/each":52,"lodash-compat/collection/includes":55,"lodash-compat/lang/isArray":140,"lodash-compat/lang/isObject":144}],3:[function(e,t,n){"use strict";var r={bind:e("lodash-compat/function/bind"),cloneDeep:e("lodash-compat/lang/cloneDeep"),find:e("lodash-compat/collection/find"),forEach:e("lodash-compat/collection/forEach"),indexOf:e("lodash-compat/array/indexOf"),isArray:e("lodash-compat/lang/isArray"),isObject:e("lodash-compat/lang/isObject"),isFunction:e("lodash-compat/lang/isFunction"),isPlainObject:e("lodash-compat/lang/isPlainObject"),isUndefined:e("lodash-compat/lang/isUndefined")},i=e("./auth"),a=e("./helpers"),o=e("./types/model"),s=e("./types/operation"),l=e("./types/operationGroup"),u=e("./resolver"),c=e("./http"),p=e("./spec-converter"),h=e("q"),f=["apis","authorizationScheme","authorizations","basePath","build","buildFrom1_1Spec","buildFrom1_2Spec","buildFromSpec","clientAuthorizations","convertInfo","debug","defaultErrorCallback","defaultSuccessCallback","enableCookies","fail","failure","finish","help","host","idFromOp","info","initialize","isBuilt","isValid","modelPropertyMacro","models","modelsArray","options","parameterMacro","parseUri","progress","resourceCount","sampleModels","selfReflect","setConsolidatedModels","spec","supportedSubmitMethods","swaggerRequestHeaders","tagFromLabel","title","url","useJQuery","jqueryAjaxCache"],d=["apis","asCurl","description","externalDocs","help","label","name","operation","operations","operationsArray","path","tag"],m=["delete","get","head","options","patch","post","put"],g=t.exports=function(e,t){return this.authorizations=null,this.authorizationScheme=null,this.basePath=null,this.debug=!1,this.enableCookies=!1,this.info=null,this.isBuilt=!1,this.isValid=!1,this.modelsArray=[],this.resourceCount=0,this.url=null,this.useJQuery=!1,this.jqueryAjaxCache=!1,this.swaggerObject={},this.deferredClient=void 0,this.clientAuthorizations=new i.SwaggerAuthorizations,"undefined"!=typeof e?this.initialize(e,t):this};g.prototype.initialize=function(e,t){if(this.models={},this.sampleModels={},"string"==typeof e?this.url=e:r.isObject(e)&&(t=e,this.url=t.url),this.url&&this.url.indexOf("http:")===-1&&this.url.indexOf("https:")===-1&&"undefined"!=typeof window&&window&&window.location&&(this.url=window.location.origin+this.url),t=t||{},this.clientAuthorizations.add(t.authorizations),this.swaggerRequestHeaders=t.swaggerRequestHeaders||"application/json;charset=utf-8,*/*",this.defaultSuccessCallback=t.defaultSuccessCallback||null,this.defaultErrorCallback=t.defaultErrorCallback||null,this.modelPropertyMacro=t.modelPropertyMacro||null,this.parameterMacro=t.parameterMacro||null,this.usePromise=t.usePromise||null,this.usePromise&&(this.deferredClient=h.defer()),"function"==typeof t.success&&(this.success=t.success),t.useJQuery&&(this.useJQuery=t.useJQuery),t.jqueryAjaxCache&&(this.jqueryAjaxCache=t.jqueryAjaxCache),t.enableCookies&&(this.enableCookies=t.enableCookies),this.options=t||{},this.supportedSubmitMethods=t.supportedSubmitMethods||[],this.failure=t.failure||function(e){throw e},this.progress=t.progress||function(){},this.spec=r.cloneDeep(t.spec),t.scheme&&(this.scheme=t.scheme),this.usePromise||"function"==typeof t.success)return this.ready=!0,this.build()},g.prototype.build=function(e){if(this.isBuilt)return this;var t=this;this.spec?this.progress("fetching resource list; Please wait."):this.progress("fetching resource list: "+this.url+"; Please wait.");var n={useJQuery:this.useJQuery,jqueryAjaxCache:this.jqueryAjaxCache,url:this.url,method:"get",headers:{accept:this.swaggerRequestHeaders},on:{error:function(e){return"http"!==t.url.substring(0,4)?t.fail("Please specify the protocol for "+t.url):0===e.status?t.fail("Can't read from server. It may not have the appropriate access-control-origin settings."):404===e.status?t.fail("Can't read swagger JSON from "+t.url):t.fail(e.status+" : "+e.statusText+" "+t.url)},response:function(e){var n=e.obj;if(!n)return t.fail("failed to parse JSON/YAML response");if(t.swaggerVersion=n.swaggerVersion,t.swaggerObject=n,n.swagger&&2===parseInt(n.swagger))t.swaggerVersion=n.swagger,(new u).resolve(n,t.url,t.buildFromSpec,t),t.isValid=!0;else{var r=new p;t.oldSwaggerObject=t.swaggerObject,r.setDocumentationLocation(t.url),r.convert(n,t.clientAuthorizations,t.options,function(e){t.swaggerObject=e,(new u).resolve(e,t.url,t.buildFromSpec,t),t.isValid=!0})}}}};if(this.spec)t.swaggerObject=this.spec,setTimeout(function(){(new u).resolve(t.spec,t.url,t.buildFromSpec,t)},10);else{if(this.clientAuthorizations.apply(n),e)return n;(new c).execute(n,this.options)}return this.usePromise?this.deferredClient.promise:this},g.prototype.buildFromSpec=function(e){if(this.isBuilt)return this;this.apis={},this.apisArray=[],this.basePath=e.basePath||"",this.consumes=e.consumes,this.host=e.host||"",this.info=e.info||{},this.produces=e.produces,this.schemes=e.schemes||[],this.securityDefinitions=e.securityDefinitions,this.security=e.security,this.title=e.title||"",e.externalDocs&&(this.externalDocs=e.externalDocs),this.authSchemes=e.securityDefinitions;var t,n={};if(Array.isArray(e.tags))for(n={},t=0;t<e.tags.length;t++){var i=e.tags[t];n[i.name]=i}var u;"string"==typeof this.url?(u=this.parseUri(this.url),"undefined"==typeof this.scheme&&"undefined"==typeof this.schemes||0===this.schemes.length?this.scheme=u.scheme||"http":"undefined"==typeof this.scheme&&(this.scheme=this.schemes[0]||u.scheme),"undefined"!=typeof this.host&&""!==this.host||(this.host=u.host,u.port&&(this.host=this.host+":"+u.port))):"undefined"==typeof this.schemes||0===this.schemes.length?this.scheme="http":"undefined"==typeof this.scheme&&(this.scheme=this.schemes[0]),this.definitions=e.definitions;var c;for(c in this.definitions){var p=new o(c,this.definitions[c],this.models,this.modelPropertyMacro);p&&(this.models[c]=p)}var h=this;h.apis.help=r.bind(h.help,h),r.forEach(e.paths,function(e,t){r.isPlainObject(e)&&r.forEach(m,function(i){var o=e[i];if(!r.isUndefined(o)){if(!r.isPlainObject(o))return void a.log("The '"+i+"' operation for '"+t+"' path is not an Operation Object");var u=o.tags;!r.isUndefined(u)&&r.isArray(u)&&0!==u.length||(u=o.tags=["default"]);var c=h.idFromOp(t,i,o),p=new s(h,o.scheme,c,i,t,o,h.definitions,h.models,h.clientAuthorizations);r.forEach(u,function(e){var t=r.indexOf(f,e)>-1?"_"+e:e,i=r.indexOf(d,e)>-1?"_"+e:e,o=h[t];if(t!==e&&a.log("The '"+e+"' tag conflicts with a SwaggerClient function/property name. Use 'client."+t+"' or 'client.apis."+e+"' instead of 'client."+e+"'."),i!==e&&a.log("The '"+e+"' tag conflicts with a SwaggerClient operation function/property name. Use 'client.apis."+i+"' instead of 'client.apis."+e+"'."),r.indexOf(d,c)>-1&&(a.log("The '"+c+"' operationId conflicts with a SwaggerClient operation function/property name. Use 'client.apis."+i+"._"+c+"' instead of 'client.apis."+i+"."+c+"'."),c="_"+c,p.nickname=c),r.isUndefined(o)){o=h[t]=h.apis[i]={},o.operations={},o.label=i,o.apis={};var s=n[e];r.isUndefined(s)||(o.description=s.description,o.externalDocs=s.externalDocs),h[t].help=r.bind(h.help,o),h.apisArray.push(new l(e,o.description,o.externalDocs,p))}c=h.makeUniqueOperationId(c,h.apis[i]),r.isFunction(o.help)||(o.help=r.bind(h.help,o)),h.apis[i][c]=o[c]=r.bind(p.execute,p),h.apis[i][c].help=o[c].help=r.bind(p.help,p),h.apis[i][c].asCurl=o[c].asCurl=r.bind(p.asCurl,p),o.apis[c]=o.operations[c]=p;var u=r.find(h.apisArray,function(t){return t.tag===e});u&&u.operationsArray.push(p)})}})});var g=[];return r.forEach(Object.keys(n),function(e){var t;for(t in h.apisArray){var n=h.apisArray[t];n&&e===n.name&&(g.push(n),h.apisArray[t]=null)}}),r.forEach(h.apisArray,function(e){e&&g.push(e)}),h.apisArray=g,r.forEach(e.definitions,function(e,t){e.id=t.toLowerCase(),e.name=t,h.modelsArray.push(e)}),this.isBuilt=!0,this.usePromise?(this.isValid=!0,this.isBuilt=!0,this.deferredClient.resolve(this),this.deferredClient.promise):(this.success&&this.success(),this)},g.prototype.makeUniqueOperationId=function(e,t){for(var n=0,i=e;;){var a=!1;if(r.forEach(t.operations,function(e){e.nickname===i&&(a=!0)}),!a)return i;i=e+"_"+n,n++}return e},g.prototype.parseUri=function(e){var t=/^(((([^:\/#\?]+:)?(?:(\/\/)((?:(([^:@\/#\?]+)(?:\:([^:@\/#\?]+))?)@)?(([^:\/#\?\]\[]+|\[[^\/\]@#?]+\])(?:\:([0-9]+))?))?)?)?((\/?(?:[^\/\?#]+\/+)*)([^\?#]*)))?(\?[^#]+)?)(#.*)?/,n=t.exec(e);return{scheme:n[4]?n[4].replace(":",""):void 0,host:n[11],port:n[12],path:n[15]}},g.prototype.help=function(e){var t="";return this instanceof g?r.forEach(this.apis,function(e,n){r.isPlainObject(e)&&(t+="operations for the '"+n+"' tag\n",r.forEach(e.operations,function(e,n){t+=" * "+n+": "+e.summary+"\n"}))}):(this instanceof l||r.isPlainObject(this))&&(t+="operations for the '"+this.label+"' tag\n",r.forEach(this.apis,function(e,n){t+=" * "+n+": "+e.summary+"\n"})),e?t:(a.log(t),t)},g.prototype.tagFromLabel=function(e){return e},g.prototype.idFromOp=function(e,t,n){n&&n.operationId||(n=n||{},n.operationId=t+"_"+e);var r=n.operationId.replace(/[\s!@#$%^&*()_+=\[{\]};:<>|.\/?,\\'""-]/g,"_")||e.substring(1)+"_"+t;return r=r.replace(/((_){2,})/g,"_"),r=r.replace(/^(_)*/g,""),r=r.replace(/([_])*$/g,"")},g.prototype.setHost=function(e){this.host=e,this.apis&&r.forEach(this.apis,function(t){t.operations&&r.forEach(t.operations,function(t){t.host=e})})},g.prototype.setBasePath=function(e){this.basePath=e,this.apis&&r.forEach(this.apis,function(t){t.operations&&r.forEach(t.operations,function(t){t.basePath=e})})},g.prototype.setSchemes=function(e){this.schemes=e,e&&e.length>0&&this.apis&&r.forEach(this.apis,function(t){t.operations&&r.forEach(t.operations,function(t){t.scheme=e[0]})})},g.prototype.fail=function(e){return this.usePromise?(this.deferredClient.reject(e),this.deferredClient.promise):void(this.failure?this.failure(e):this.failure(e))}},{"./auth":2,"./helpers":4,"./http":5,"./resolver":6,"./spec-converter":8,"./types/model":9,"./types/operation":10,"./types/operationGroup":11,"lodash-compat/array/indexOf":49,"lodash-compat/collection/find":53,"lodash-compat/collection/forEach":54,"lodash-compat/function/bind":58,"lodash-compat/lang/cloneDeep":138,"lodash-compat/lang/isArray":140,"lodash-compat/lang/isFunction":142,"lodash-compat/lang/isObject":144,"lodash-compat/lang/isPlainObject":145,"lodash-compat/lang/isUndefined":148,q:157}],4:[function(e,t,n){(function(n){"use strict";var r={isPlainObject:e("lodash-compat/lang/isPlainObject"),indexOf:e("lodash-compat/array/indexOf")};t.exports.__bind=function(e,t){return function(){return e.apply(t,arguments)}};var i=t.exports.log=function(){console&&"test"!==n.env.NODE_ENV&&console.log(Array.prototype.slice.call(arguments)[0])};t.exports.fail=function(e){i(e)};var a=(t.exports.optionHtml=function(e,t){return'<tr><td class="optionName">'+e+":</td><td>"+t+"</td></tr>"},t.exports.resolveSchema=function(e){return r.isPlainObject(e.schema)&&(e=a(e.schema)),e});t.exports.simpleRef=function(e){return"undefined"==typeof e?null:0===e.indexOf("#/definitions/")?e.substring("#/definitions/".length):e}}).call(this,e("_process"))},{_process:12,"lodash-compat/array/indexOf":49,"lodash-compat/lang/isPlainObject":145}],5:[function(t,n,r){"use strict";var i=t("./helpers"),a=t("superagent"),o=t("js-yaml"),s={isObject:t("lodash-compat/lang/isObject"),keys:t("lodash-compat/object/keys")},l=function(){this.type="JQueryHttpClient"},u=function(){this.type="SuperagentHttpClient"},c=n.exports=function(){};c.prototype.execute=function(t,n){var r;r=n&&n.client?n.client:new u(n),r.opts=n||{};var i=!1;if("undefined"!=typeof window&&"undefined"!=typeof window.jQuery&&(i=!0),"options"===t.method.toLowerCase()&&"SuperagentHttpClient"===r.type&&(e("forcing jQuery as OPTIONS are not supported by SuperAgent"),t.useJQuery=!0),this.isInternetExplorer()&&(t.useJQuery===!1||!i))throw new Error("Unsupported configuration! JQuery is required but not available");(t&&t.useJQuery===!0||this.isInternetExplorer()&&i)&&(r=new l(n));var a=t.on.response,o=t.on.error,c=function(e){return n&&n.requestInterceptor&&(e=n.requestInterceptor.apply(e)),e},p=function(e){return n&&n.responseInterceptor&&(e=n.responseInterceptor.apply(e)),a(e)},h=function(e){n&&n.responseInterceptor&&(e=n.responseInterceptor.apply(e)),o(e)};return t.on.error=function(e){h(e)},t.on.response=function(e){p(e)},s.isObject(t)&&s.isObject(t.body)&&t.body.type&&"formData"===t.body.type&&n.useJQuery&&(t.contentType=!1,t.processData=!1,delete t.headers["Content-Type"]),t=c(t)||t,t.beforeSend?t.beforeSend(function(e){r.execute(e||t)}):r.execute(t),t.deferred?t.deferred.promise:t},c.prototype.isInternetExplorer=function(){var e=!1;if("undefined"!=typeof navigator&&navigator.userAgent){var t=navigator.userAgent.toLowerCase();if(t.indexOf("msie")!==-1){var n=parseInt(t.split("msie")[1]);n<=8&&(e=!0)}}return e},l.prototype.execute=function(e){var t=this.jQuery||"undefined"!=typeof window&&window.jQuery,n=e.on,r=e;if("undefined"==typeof t||t===!1)throw new Error("Unsupported configuration! JQuery is required but not available");return e.type=e.method,e.cache=e.jqueryAjaxCache,e.data=e.body,delete e.jqueryAjaxCache,delete e.useJQuery,delete e.body,e.complete=function(e){for(var t={},a=e.getAllResponseHeaders().split("\n"),s=0;s<a.length;s++){var l=a[s].trim();if(0!==l.length){var u=l.indexOf(":");if(u!==-1){var c=l.substring(0,u).trim(),p=l.substring(u+1).trim();t[c]=p}else t[l]=null}}var h={url:r.url,method:r.method,status:e.status,statusText:e.statusText,data:e.responseText,headers:t};try{var f=e.responseJSON||o.safeLoad(e.responseText);h.obj="string"==typeof f?{}:f}catch(d){i.log("unable to parse JSON/YAML content")}if(h.obj=h.obj||null,e.status>=200&&e.status<300)n.response(h);else{if(!(0===e.status||e.status>=400&&e.status<599))return n.response(h);n.error(h)}},t.support.cors=!0,t.ajax(e)},u.prototype.execute=function(e){var t=e.method.toLowerCase();"delete"===t&&(t="del");var n=e.headers||{},r=a[t](e.url);if(e.enableCookies&&r.withCredentials(),e.body)if(s.isObject(e.body)){var l=e.headers["Content-Type"]||"";if(0===l.indexOf("multipart/form-data"))if(delete n["Content-Type"],"[object FormData]"==={}.toString.apply(e.body))for(var u=e.body.keys();;){var c=u.next();if(c.done)break;var p=c.value,h=e.body.get(p);console.log({}.toString.apply(h)),"[object File]"==={}.toString.apply(h)?r.attach(p,h):r.field(p,h)}else{var f;for(var f in e.body){var h=e.body[f];r.field(f,h)}}else s.isObject(e.body)&&(e.body=JSON.stringify(e.body),r.send(e.body))}else r.send(e.body);var d;for(d in n)r.set(d,n[d]);"function"==typeof r.buffer&&r.buffer(),r.end(function(t,n){n=n||{status:0,headers:{error:"no response from server"}};var r,a={url:e.url,method:e.method,headers:n.headers};if(!t&&n.error&&(t=n.error),t&&e.on&&e.on.error){if(a.errObj=t,a.status=n?n.status:500,a.statusText=n?n.text:t.message,n.headers&&n.headers["content-type"]&&n.headers["content-type"].indexOf("application/json")>=0)try{a.obj=JSON.parse(a.statusText)}catch(l){a.obj=null}r=e.on.error}else if(n&&e.on&&e.on.response){var u;if(n.body&&s.keys(n.body).length>0)u=n.body;else try{u=o.safeLoad(n.text),u="string"==typeof u?null:u}catch(l){i.log("cannot parse JSON/YAML content")}a.obj="object"==typeof u?u:null,a.status=n.status,a.statusText=n.text,r=e.on.response}a.data=a.statusText,r&&r(a)})}},{"./helpers":4,"js-yaml":19,"lodash-compat/lang/isObject":144,"lodash-compat/object/keys":149,superagent:158}],6:[function(e,t,n){"use strict";var r=e("./http"),i={isObject:e("lodash-compat/lang/isObject"),cloneDeep:e("lodash-compat/lang/cloneDeep"),isArray:e("lodash-compat/lang/isArray"),isString:e("lodash-compat/lang/isString")},a=t.exports=function(){this.failedUrls=[],this.resolverCache={},this.pendingUrls={}};a.prototype.processAllOf=function(e,t,n,r,i,a){var o,s,l;n["x-resolved-from"]=["#/definitions/"+t];var u=n.allOf;for(u.sort(function(e,t){return e.$ref&&t.$ref?0:e.$ref?-1:1}),o=0;o<u.length;o++)l=u[o],s="/definitions/"+t+"/allOf",this.resolveInline(e,a,l,r,i,s)},a.prototype.resolve=function(e,t,n,a){this.spec=e;var o,s,l=t,u=n,c=a,p={};"function"==typeof t&&(l=null,u=t,c=n);var h=l;this.scope=c||this,this.iteration=this.iteration||0,this.scope.options&&this.scope.options.requestInterceptor&&(p.requestInterceptor=this.scope.options.requestInterceptor),this.scope.options&&this.scope.options.responseInterceptor&&(p.responseInterceptor=this.scope.options.responseInterceptor);var f,d,m,g,y=0,v={},b={},w=[];e.definitions=e.definitions||{};for(f in e.definitions){var _=e.definitions[f];if(_.$ref)this.resolveInline(l,e,_,w,b,_);else{for(g in _.properties)m=_.properties[g],i.isArray(m.allOf)?this.processAllOf(l,f,m,w,b,e):this.resolveTo(l,m,w,"/definitions");_.allOf&&this.processAllOf(l,f,_,w,b,e)}}e.parameters=e.parameters||{};for(f in e.parameters){var x=e.parameters[f];if("body"===x["in"]&&x.schema)if(i.isArray(x.schema.allOf)){for(var A="inline_model",f=A,S=!1,j=0;!S;){if("undefined"==typeof e.definitions[f]){S=!0;break}f=A+"_"+j,j++}e.definitions[f]={allOf:x.schema.allOf},delete x.schema.allOf,x.schema.$ref="#/definitions/"+f,this.processAllOf(l,f,e.definitions[f],w,b,e)}else this.resolveTo(l,x.schema,w,o);x.$ref&&this.resolveInline(l,e,x,w,b,x.$ref)}for(f in e.paths){var E,O,k;d=e.paths[f];for(E in d)if("$ref"===E)o="/paths"+f,this.resolveInline(l,e,d,w,b,o);else{O=d[E];var T=d.parameters||[],C=O.parameters||[];for(s in T){var x=T[s];C.unshift(x)}"parameters"!==E&&i.isObject(O)&&(O.parameters=O.parameters||C);for(s in C){var x=C[s];if(o="/paths"+f+"/"+E+"/parameters","body"===x["in"]&&x.schema)if(i.isArray(x.schema.allOf)){for(var A="inline_model",f=A,S=!1,j=0;!S;){if("undefined"==typeof e.definitions[f]){S=!0;break}f=A+"_"+j,j++}e.definitions[f]={allOf:x.schema.allOf},delete x.schema.allOf,x.schema.$ref="#/definitions/"+f,this.processAllOf(l,f,e.definitions[f],w,b,e)}else this.resolveTo(l,x.schema,w,o);x.$ref&&this.resolveInline(l,e,x,w,b,x.$ref)}for(k in O.responses){var I=O.responses[k];if(o="/paths"+f+"/"+E+"/responses/"+k,i.isObject(I)&&(I.$ref&&this.resolveInline(l,e,I,w,b,o),I.schema)){var D=I;if(i.isArray(D.schema.allOf)){for(var A="inline_model",f=A,S=!1,j=0;!S;){if("undefined"==typeof e.definitions[f]){S=!0;break}f=A+"_"+j,j++}e.definitions[f]={allOf:D.schema.allOf},delete D.schema.allOf,delete D.schema.type,D.schema.$ref="#/definitions/"+f,this.processAllOf(l,f,e.definitions[f],w,b,e)}else"array"===D.schema.type?D.schema.items&&D.schema.items.$ref&&this.resolveInline(l,e,D.schema.items,w,b,o):this.resolveTo(l,I.schema,w,o)}}}d.parameters=[]}var L,M=0,R=[],U=w;for(s=0;s<U.length;s++){var P=U[s];if(l===P.root){if("ref"===P.resolveAs){var q,B=((P.root||"")+"/"+P.key).split("/"),N=[],z="";if(P.key.indexOf("../")>=0){for(var $=0;$<B.length;$++)".."===B[$]?N=N.slice(0,N.length-1):N.push(B[$]);for(q=0;q<N.length;q++)q>0&&(z+="/"),z+=N[q];P.root=z,R.push(P)}else if(L=P.key.split("#"),2===L.length){0!==L[0].indexOf("http:")&&0!==L[0].indexOf("https:")||(P.root=L[0]),o=L[1].split("/");var F,V=e;for(q=0;q<o.length;q++){var H=o[q];if(""!==H){if(V=V[H],"undefined"==typeof V){F=null;break}F=V}}null===F&&R.push(P)}}else if("inline"===P.resolveAs){if(P.key&&P.key.indexOf("#")===-1&&"/"!==P.key.charAt(0)){for(L=P.root.split("/"),o="",s=0;s<L.length-1;s++)o+=L[s]+"/";o+=P.key,P.root=o,P.location=""}R.push(P)}}else R.push(P)}M=R.length;for(var Y={},J=0;J<R.length;J++)!function(e,t,n,a,o){if(e.root&&e.root!==l)if(n.failedUrls.indexOf(e.root)===-1){var s={useJQuery:!1,url:e.root,method:"get",headers:{accept:n.scope.swaggerRequestHeaders||"application/json"},on:{error:function(r){y+=1,console.log("failed url: "+s.url),n.failedUrls.push(s.url),a&&delete a[e.root],b[e.key]={root:e.root,location:e.location},y===M&&n.finish(t,h,w,v,b,u)},response:function(r){var i=r.obj;a&&delete a[e.root],n.resolverCache&&(n.resolverCache[e.root]=i),n.resolveItem(i,e.root,w,v,b,e),y+=1,y===M&&n.finish(t,h,w,v,b,u)}}};c&&c.clientAuthorizations&&c.clientAuthorizations.apply(s),function f(){setTimeout(function(){if(a[s.url])f();else{var e=n.resolverCache[s.url];i.isObject(e)?(s.on.response({obj:e}),1):(a[s.url]=!0,(new r).execute(s,p))}},0)}()}else y+=1,b[e.key]={root:e.root,location:e.location},y===M&&n.finish(t,h,w,v,b,u);else n.resolveItem(t,h,w,v,b,e),y+=1,y===M&&n.finish(t,l,w,v,b,u,!0)}(R[J],e,this,Y,J);0===Object.keys(R).length&&this.finish(e,h,w,v,b,u)},a.prototype.resolveItem=function(e,t,n,r,i,a){var o=a.location,s=e,l=o.split("/");if(""!==o)for(var u=0;u<l.length;u++){var c=l[u];if(c.indexOf("~1")!==-1&&(c=l[u].replace(/~0/g,"~").replace(/~1/g,"/"),"/"!==c.charAt(0)&&(c="/"+c)),"undefined"==typeof s||null===s)break;if(""===c&&u===l.length-1&&l.length>1){s=null;break}c.length>0&&(s=s[c])}var p=a.key;l=a.key.split("/");var h=l[l.length-1];h.indexOf("#")>=0&&(h=h.split("#")[1]),null!==s&&"undefined"!=typeof s?r[p]={name:h,obj:s,key:a.key,root:a.root}:i[p]={root:a.root,location:a.location}},a.prototype.finish=function(e,t,n,r,i,a,o){var s;for(s in n){var l=n[s],u=l.key,c=r[u];if(c)if(e.definitions=e.definitions||{},"ref"===l.resolveAs){if(o!==!0)for(u in c.obj){var p=this.retainRoot(u,c.obj[u],l.root);c.obj[u]=p}e.definitions[c.name]=c.obj,l.obj.$ref="#/definitions/"+c.name}else if("inline"===l.resolveAs){var h=l.obj;h["x-resolved-from"]=[l.key],delete h.$ref;for(u in c.obj){var p=c.obj[u];o!==!0&&(p=this.retainRoot(u,c.obj[u],l.root)),h[u]=p}}}var f=this.countUnresolvedRefs(e);0===f||this.iteration>5?(this.resolveAllOf(e.definitions),this.resolverCache=null,a.call(this.scope,e,i)):(this.iteration+=1,this.resolve(e,t,a,this.scope))},a.prototype.countUnresolvedRefs=function(e){
+var t,n=this.getRefs(e),r=[],i=[];for(t in n)0===t.indexOf("#")?r.push(t.substring(1)):i.push(t);for(t=0;t<r.length;t++)for(var a=r[t],o=a.split("/"),s=e,l=0;l<o.length;l++){var u=o[l];if(""!==u&&(s=s[u],"undefined"==typeof s)){i.push(a);break}}return i.length},a.prototype.getRefs=function(e,t){t=t||e;var n={};for(var r in t)if(t.hasOwnProperty(r)){var a=t[r];if("$ref"===r&&"string"==typeof a)n[a]=null;else if(i.isObject(a)){var o=this.getRefs(a);for(var s in o)n[s]=null}}return n},a.prototype.retainRoot=function(e,t,n){if(i.isObject(t))for(var r in t){var a=t[r];if("$ref"===r&&"string"==typeof a){if(0!==a.indexOf("http:")&&0!==a.indexOf("https:")){var o=!0;if(n){var s=n.slice(-1);if("/"!==s&&0!==a.indexOf("#")&&0!==a.indexOf("http:")&&a.indexOf("https:")){o=!1;var l=n.split("/");l=l.splice(0,l.length-1),n="";for(var u=0;u<l.length;u++)n+=l[u]+"/"}}0!==a.indexOf("#")&&o&&(a="#"+a),a=(n||"")+a,t[r]=a}}else i.isObject(a)&&this.retainRoot(r,a,n)}else i.isString(t)&&"$ref"===e&&t.indexOf("http:")===-1&&t.indexOf("https:")===-1&&(t=n+t);return t},a.prototype.resolveInline=function(e,t,n,r,i,a){var o,s,l,u,c=n.$ref,p=n.$ref,h=!1;if(e=e||"",p){if(0===p.indexOf("../")){for(s=p.split("../"),l=e.split("/"),p="",o=0;o<s.length;o++)""===s[o]?l=l.slice(0,l.length-1):p+=s[o];for(e="",o=0;o<l.length-1;o++)o>0&&(e+="/"),e+=l[o];h=!0}if(p.indexOf("#")>=0)if(0===p.indexOf("/"))u=p.split("#"),s=e.split("//"),l=s[1].split("/"),e=s[0]+"//"+l[0]+u[0],a=u[1];else{if(u=p.split("#"),""!==u[0]){if(l=e.split("/"),l=l.slice(0,l.length-1),!h){e="";for(var f=0;f<l.length;f++)f>0&&(e+="/"),e+=l[f]}e+="/"+p.split("#")[0]}a=u[1]}if(0===p.indexOf("http:")||0===p.indexOf("https:"))p.indexOf("#")>=0?(e=p.split("#")[0],a=p.split("#")[1]):(e=p,a=""),r.push({obj:n,resolveAs:"inline",root:e,key:c,location:a});else if(0===p.indexOf("#"))a=p.split("#")[1],r.push({obj:n,resolveAs:"inline",root:e,key:c,location:a});else if(0===p.indexOf("/")&&p.indexOf("#")===-1){a=p;var d=e.match(/^https?\:\/\/([^\/?#]+)(?:[\/?#]|$)/i);d&&(e=d[0]+p.substring(1),a=""),r.push({obj:n,resolveAs:"inline",root:e,key:c,location:a})}else r.push({obj:n,resolveAs:"inline",root:e,key:c,location:a})}else"array"===n.type&&this.resolveTo(e,n.items,r,a)},a.prototype.resolveTo=function(e,t,n,r){var a,o,s=t.$ref,l=e;if("undefined"!=typeof s&&null!==s){if(s.indexOf("#")>=0){var u=s.split("#");if(u[0]&&0===s.indexOf("/"));else if(!u[0]||0!==u[0].indexOf("http:")&&0!==u[0].indexOf("https:")){if(u[0]&&u[0].length>0){for(a=e.split("/"),l="",o=0;o<a.length-1;o++)l+=a[o]+"/";l+=u[0]}}else l=u[0],s=u[1];r=u[1]}else if(0===s.indexOf("http:")||0===s.indexOf("https:"))l=s,r="";else{for(a=e.split("/"),l="",o=0;o<a.length-1;o++)l+=a[o]+"/";l+=s,r=""}n.push({obj:t,resolveAs:"ref",root:l,key:s,location:r})}else if("array"===t.type){var c=t.items;this.resolveTo(e,c,n,r)}else if(t&&(t.properties||t.additionalProperties)){var p=this.uniqueName("inline_model");t.title&&(p=this.uniqueName(t.title)),delete t.title,this.spec.definitions[p]=i.cloneDeep(t),t.$ref="#/definitions/"+p,delete t.type,delete t.properties}},a.prototype.uniqueName=function(e){for(var t=e,n=0;;){if(!i.isObject(this.spec.definitions[t]))return t;t=e+"_"+n,n++}},a.prototype.resolveAllOf=function(e,t,n){n=n||0,t=t||e;var r;for(var a in t)if(t.hasOwnProperty(a)){var o=t[a];if(null===o)throw new TypeError("Swagger 2.0 does not support null types ("+t+"). See https://github.com/swagger-api/swagger-spec/issues/229.");if("object"==typeof o&&this.resolveAllOf(e,o,n+1),o&&"undefined"!=typeof o.allOf){var s=o.allOf;if(i.isArray(s)){var l=i.cloneDeep(o);delete l.allOf,l["x-composed"]=!0,"undefined"!=typeof o["x-resolved-from"]&&(l["x-resolved-from"]=o["x-resolved-from"]);for(var u=0;u<s.length;u++){var c=s[u],p="self";"undefined"!=typeof c["x-resolved-from"]&&(p=c["x-resolved-from"][0]);for(var h in c)if(l.hasOwnProperty(h))if("properties"===h){var f=c[h];for(r in f){l.properties[r]=i.cloneDeep(f[r]);var d=f[r]["x-resolved-from"];"undefined"!=typeof d&&"self"!==d||(d=p),l.properties[r]["x-resolved-from"]=d}}else if("required"===h){for(var m=l.required.concat(c[h]),g=0;g<m.length;++g)for(var y=g+1;y<m.length;++y)m[g]===m[y]&&m.splice(y--,1);l.required=m}else"x-resolved-from"===h&&l["x-resolved-from"].push(p);else if(l[h]=i.cloneDeep(c[h]),"properties"===h)for(r in l[h])l[h][r]["x-resolved-from"]=p}t[a]=l}}}}},{"./http":5,"lodash-compat/lang/cloneDeep":138,"lodash-compat/lang/isArray":140,"lodash-compat/lang/isObject":144,"lodash-compat/lang/isString":146}],7:[function(e,t,n){"use strict";function r(e,t){return'<tr><td class="optionName">'+e+":</td><td>"+t+"</td></tr>"}function i(e,t){var n;return"integer"===e&&"int32"===t?n="integer":"integer"===e&&"int64"===t?n="long":"integer"===e&&"undefined"==typeof t?n="long":"string"===e&&"date-time"===t?n="date-time":"string"===e&&"date"===t?n="date":"number"===e&&"float"===t?n="float":"number"===e&&"double"===t?n="double":"number"===e&&"undefined"==typeof t?n="double":"boolean"===e?n="boolean":"string"===e&&(n="string"),n}function a(e,t){var n="";return"undefined"!=typeof e.$ref?n+=l.simpleRef(e.$ref):"undefined"==typeof e.type?n+="object":"array"===e.type?t?n+=a(e.items||e.$ref||{}):(n+="Array[",n+=a(e.items||e.$ref||{}),n+="]"):n+="integer"===e.type&&"int32"===e.format?"integer":"integer"===e.type&&"int64"===e.format?"long":"integer"===e.type&&"undefined"==typeof e.format?"long":"string"===e.type&&"date-time"===e.format?"date-time":"string"===e.type&&"date"===e.format?"date":"string"===e.type&&"undefined"==typeof e.format?"string":"number"===e.type&&"float"===e.format?"float":"number"===e.type&&"double"===e.format?"double":"number"===e.type&&"undefined"==typeof e.format?"double":"boolean"===e.type?"boolean":e.$ref?l.simpleRef(e.$ref):e.type,n}function o(e,t,n,r){e=l.resolveSchema(e),"function"!=typeof r&&(r=function(e){return(e||{})["default"]}),n=n||{};var i,a,s=e.type||"object",c=e.format;return u.isUndefined(e.example)?u.isUndefined(e.items)&&u.isArray(e["enum"])&&(a=e["enum"][0]):a=e.example,u.isUndefined(a)&&(e.$ref?(i=t[l.simpleRef(e.$ref)],u.isUndefined(i)||(u.isUndefined(n[i.name])?(n[i.name]=i,a=o(i.definition,t,n,r),delete n[i.name]):a="array"===i.type?[]:{})):u.isUndefined(e["default"])?"string"===s?a="date-time"===c?(new Date).toISOString():"date"===c?(new Date).toISOString().split("T")[0]:"string":"integer"===s?a=0:"number"===s?a=0:"boolean"===s?a=!0:"object"===s?(a={},u.forEach(e.properties,function(e,i){var s=u.cloneDeep(e);s["default"]=r(e),a[i]=o(s,t,n,r)})):"array"===s&&(a=[],u.isArray(e.items)?u.forEach(e.items,function(e){a.push(o(e,t,n,r))}):u.isPlainObject(e.items)?a.push(o(e.items,t,n,r)):u.isUndefined(e.items)?a.push({}):l.log("Array type's 'items' property is not an array or an object, cannot process")):a=e["default"]),a}function s(e,t,n,i){function a(e,t,r){var i,a=t;return e.$ref?(a=e.title||l.simpleRef(e.$ref),i=n[a]):u.isUndefined(t)&&(a=e.title||"Inline Model "+ ++m,i={definition:e}),r!==!0&&(f[a]=u.isUndefined(i)?{}:i.definition),a}function o(e){var t='<span class="propType">',n=e.type||"object";return e.$ref?t+=a(e,l.simpleRef(e.$ref)):"object"===n?t+=u.isUndefined(e.properties)?"object":a(e):"array"===n?(t+="Array[",u.isArray(e.items)?t+=u.map(e.items,a).join(","):u.isPlainObject(e.items)?t+=u.isUndefined(e.items.$ref)?u.isUndefined(e.items.type)||u.indexOf(["array","object"],e.items.type)!==-1?a(e.items):e.items.type:a(e.items,l.simpleRef(e.items.$ref)):(l.log("Array type's 'items' schema is not an array or an object, cannot process"),t+="object"),t+="]"):t+=e.type,t+="</span>"}function s(e,t){var n="",i=e.type||"object",a="array"===i;switch(a&&(i=u.isPlainObject(e.items)&&!u.isUndefined(e.items.type)?e.items.type:"object"),u.isUndefined(e["default"])||(n+=r("Default",e["default"])),i){case"string":e.minLength&&(n+=r("Min. Length",e.minLength)),e.maxLength&&(n+=r("Max. Length",e.maxLength)),e.pattern&&(n+=r("Reg. Exp.",e.pattern));break;case"integer":case"number":e.minimum&&(n+=r("Min. Value",e.minimum)),e.exclusiveMinimum&&(n+=r("Exclusive Min.","true")),e.maximum&&(n+=r("Max. Value",e.maximum)),e.exclusiveMaximum&&(n+=r("Exclusive Max.","true")),e.multipleOf&&(n+=r("Multiple Of",e.multipleOf))}if(a&&(e.minItems&&(n+=r("Min. Items",e.minItems)),e.maxItems&&(n+=r("Max. Items",e.maxItems)),e.uniqueItems&&(n+=r("Unique Items","true")),e.collectionFormat&&(n+=r("Coll. Format",e.collectionFormat))),u.isUndefined(e.items)&&u.isArray(e["enum"])){var o;o="number"===i||"integer"===i?e["enum"].join(", "):'"'+e["enum"].join('", "')+'"',n+=r("Enum",o)}return n.length>0&&(t='<span class="propWrap">'+t+'<table class="optionsWrapper"><tr><th colspan="2">'+i+"</th></tr>"+n+"</table></span>"),t}function c(e,t){var r=e.type||"object",c="array"===e.type,f=p+t+" "+(c?"[":"{")+h;if(t&&d.push(t),c)u.isArray(e.items)?f+="<div>"+u.map(e.items,function(e){var t=e.type||"object";return u.isUndefined(e.$ref)?u.indexOf(["array","object"],t)>-1?"object"===t&&u.isUndefined(e.properties)?"object":a(e):s(e,t):a(e,l.simpleRef(e.$ref))}).join(",</div><div>"):u.isPlainObject(e.items)?f+=u.isUndefined(e.items.$ref)?u.indexOf(["array","object"],e.items.type||"object")>-1?(u.isUndefined(e.items.type)||"object"===e.items.type)&&u.isUndefined(e.items.properties)?"<div>object</div>":"<div>"+a(e.items)+"</div>":"<div>"+s(e.items,e.items.type)+"</div>":"<div>"+a(e.items,l.simpleRef(e.items.$ref))+"</div>":(l.log("Array type's 'items' property is not an array or an object, cannot process"),f+="<div>object</div>");else if(e.$ref)f+="<div>"+a(e,t)+"</div>";else if("object"===r){if(u.isPlainObject(e.properties)){var m=u.map(e.properties,function(t,r){var a,c,p=u.indexOf(e.required,r)>=0,h=u.cloneDeep(t),f=p?"required":"",d='<span class="propName '+f+'">'+r+"</span> (";return h["default"]=i(h),h=l.resolveSchema(h),c=t.description||h.description,u.isUndefined(h.$ref)||(a=n[l.simpleRef(h.$ref)],u.isUndefined(a)||u.indexOf([void 0,"array","object"],a.definition.type)!==-1||(h=l.resolveSchema(a.definition))),d+=o(h),p||(d+=', <span class="propOptKey">optional</span>'),t.readOnly&&(d+=', <span class="propReadOnly">read only</span>'),d+=")",u.isUndefined(c)||(d+=': <span class="propDesc">'+c+"</span>"),h["enum"]&&(d+=' = <span class="propVals">[\''+h["enum"].join("', '")+"']</span>"),"<div"+(t.readOnly?' class="readOnly"':"")+">"+s(h,d)}).join(",</div>");m&&(f+=m+"</div>")}}else f+="<div>"+s(e,r)+"</div>";return f+p+(c?"]":"}")+h}var p='<span class="strong">',h="</span>";if(u.isObject(arguments[0])&&(e=void 0,t=arguments[0],n=arguments[1],i=arguments[2]),n=n||{},t=l.resolveSchema(t),u.isEmpty(t))return p+"Empty"+h;if("string"==typeof t.$ref&&(e=l.simpleRef(t.$ref),t=n[e],"undefined"==typeof t))return p+e+" is not defined!"+h;"string"!=typeof e&&(e=t.title||"Inline Model"),t.definition&&(t=t.definition),"function"!=typeof i&&(i=function(e){return(e||{})["default"]});for(var f={},d=[],m=0,g=c(t,e);u.keys(f).length>0;)u.forEach(f,function(e,t){var n=u.indexOf(d,t)>-1;delete f[t],n||(d.push(t),g+="<br />"+c(e,t))});return g}var l=e("./helpers"),u={isPlainObject:e("lodash-compat/lang/isPlainObject"),isUndefined:e("lodash-compat/lang/isUndefined"),isArray:e("lodash-compat/lang/isArray"),isObject:e("lodash-compat/lang/isObject"),isEmpty:e("lodash-compat/lang/isEmpty"),map:e("lodash-compat/collection/map"),indexOf:e("lodash-compat/array/indexOf"),cloneDeep:e("lodash-compat/lang/cloneDeep"),keys:e("lodash-compat/object/keys"),forEach:e("lodash-compat/collection/forEach")};t.exports.optionHtml=r,t.exports.typeFromJsonSchema=i,t.exports.getStringSignature=a,t.exports.schemaToHTML=s,t.exports.schemaToJSON=o},{"./helpers":4,"lodash-compat/array/indexOf":49,"lodash-compat/collection/forEach":54,"lodash-compat/collection/map":56,"lodash-compat/lang/cloneDeep":138,"lodash-compat/lang/isArray":140,"lodash-compat/lang/isEmpty":141,"lodash-compat/lang/isObject":144,"lodash-compat/lang/isPlainObject":145,"lodash-compat/lang/isUndefined":148,"lodash-compat/object/keys":149}],8:[function(e,t,n){"use strict";var r=e("./http"),i={isObject:e("lodash-compat/lang/isObject")},a=t.exports=function(){this.errors=[],this.warnings=[],this.modelMap={}};a.prototype.setDocumentationLocation=function(e){this.docLocation=e},a.prototype.convert=function(e,t,n,r){if(!e||!Array.isArray(e.apis))return this.finish(r,null);this.clientAuthorizations=t;var i={swagger:"2.0"};i.originalVersion=e.swaggerVersion,this.apiInfo(e,i),this.securityDefinitions(e,i),e.basePath&&this.setDocumentationLocation(e.basePath);var a,o=!1;for(a=0;a<e.apis.length;a++){var s=e.apis[a];Array.isArray(s.operations)&&(o=!0)}o?(this.declaration(e,i),this.finish(r,i)):this.resourceListing(e,i,n,r)},a.prototype.declaration=function(e,t){var n,r,a,o;if(e.apis){0===e.basePath.indexOf("http://")?(a=e.basePath.substring("http://".length),o=a.indexOf("/"),o>0?(t.host=a.substring(0,o),t.basePath=a.substring(o)):(t.host=a,t.basePath="/")):0===e.basePath.indexOf("https://")?(a=e.basePath.substring("https://".length),o=a.indexOf("/"),o>0?(t.host=a.substring(0,o),t.basePath=a.substring(o)):(t.host=a,t.basePath="/")):t.basePath=e.basePath;var s;if(e.authorizations&&(s=e.authorizations),e.consumes&&(t.consumes=e.consumes),e.produces&&(t.produces=e.produces),i.isObject(e))for(n in e.models){var l=e.models[n],u=l.id||n;this.modelMap[u]=n}for(r=0;r<e.apis.length;r++){var c=e.apis[r],p=c.path,h=c.operations;this.operations(p,e.resourcePath,h,s,t)}var f=e.models||{};this.models(f,t)}},a.prototype.models=function(e,t){if(i.isObject(e)){var n;t.definitions=t.definitions||{};for(n in e){var r,a=e[n],o=[],s={properties:{}};for(r in a.properties){var l=a.properties[r],u={};this.dataType(l,u),l.description&&(u.description=l.description),l["enum"]&&(u["enum"]=l["enum"]),"boolean"==typeof l.required&&l.required===!0&&o.push(r),"string"==typeof l.required&&"true"===l.required&&o.push(r),s.properties[r]=u}o.length>0?s.required=o:s.required=a.required,t.definitions[n]=s}}},a.prototype.extractTag=function(e){var t=e||"default";return 0!==t.indexOf("http:")&&0!==t.indexOf("https:")||(t=t.split(["/"]),t=t[t.length-1].substring()),t.endsWith(".json")&&(t=t.substring(0,t.length-".json".length)),t.replace("/","")},a.prototype.operations=function(e,t,n,r,i){if(Array.isArray(n)){var a;i.paths||(i.paths={});var o=i.paths[e]||{},s=this.extractTag(t);i.tags=i.tags||[];var l=!1;for(a=0;a<i.tags.length;a++){var u=i.tags[a];u.name===s&&(l=!0)}for(l||i.tags.push({name:s}),a=0;a<n.length;a++){var c=n[a],p=(c.method||c.httpMethod).toLowerCase(),h={tags:[s]},f=c.authorizations;if(f&&0===Object.keys(f).length&&(f=r),"undefined"!=typeof f){var d;for(var m in f){h.security=h.security||[];var g=f[m];if(g){var y=[];for(var v in g)y.push(g[v].scope);d={},d[m]=y,h.security.push(d)}else d={},d[m]=[],h.security.push(d)}}c.consumes?h.consumes=c.consumes:i.consumes&&(h.consumes=i.consumes),c.produces?h.produces=c.produces:i.produces&&(h.produces=i.produces),c.summary&&(h.summary=c.summary),c.notes&&(h.description=c.notes),c.nickname&&(h.operationId=c.nickname),c.deprecated&&(h.deprecated=c.deprecated),this.authorizations(f,i),this.parameters(h,c.parameters,i),this.responseMessages(h,c,i),o[p]=h}i.paths[e]=o}},a.prototype.responseMessages=function(e,t){if(i.isObject(t)){var n={};this.dataType(t,n),!n.schema&&n.type&&(n={schema:n}),e.responses=e.responses||{};var r=!1;if(Array.isArray(t.responseMessages)){var a,o=t.responseMessages;for(a=0;a<o.length;a++){var s=o[a],l={description:s.message};200===s.code&&(r=!0),s.responseModel&&(l.schema={$ref:"#/definitions/"+s.responseModel}),e.responses[""+s.code]=l}}r?e.responses["default"]=n:e.responses[200]=n}},a.prototype.authorizations=function(e){!i.isObject(e)},a.prototype.parameters=function(e,t){if(Array.isArray(t)){var n;for(n=0;n<t.length;n++){var r=t[n],i={};if(i.name=r.name,i.description=r.description,i.required=r.required,i["in"]=r.paramType,"body"===i["in"]&&(i.name="body"),"form"===i["in"]&&(i["in"]="formData"),r["enum"]&&(i["enum"]=r["enum"]),r.allowMultiple===!0||"true"===r.allowMultiple){var a={};if(this.dataType(r,a),i.type="array",i.items=a,r.allowableValues){var o=r.allowableValues;"LIST"===o.valueType&&(i["enum"]=o.values)}}else this.dataType(r,i);"undefined"!=typeof r.defaultValue&&(i["default"]=r.defaultValue),e.parameters=e.parameters||[],e.parameters.push(i)}}},a.prototype.dataType=function(e,t){if(i.isObject(e)){e.minimum&&(t.minimum=e.minimum),e.maximum&&(t.maximum=e.maximum),e.format&&(t.format=e.format),"undefined"!=typeof e.defaultValue&&(t["default"]=e.defaultValue);var n=this.toJsonSchema(e);n&&(t=t||{},n.type&&(t.type=n.type),n.format&&(t.format=n.format),n.$ref&&(t.schema={$ref:n.$ref}),n.items&&(t.items=n.items))}},a.prototype.toJsonSchema=function(e){if(!e)return"object";var t=e.type||e.dataType||e.responseClass||"",n=t.toLowerCase(),r=(e.format||"").toLowerCase();if(0===n.indexOf("list[")){var i=t.substring(5,t.length-1),a=this.toJsonSchema({type:i});return{type:"array",items:a}}if("int"===n||"integer"===n&&"int32"===r)return{type:"integer",format:"int32"};if("long"===n||"integer"===n&&"int64"===r)return{type:"integer",format:"int64"};if("integer"===n)return{type:"integer",format:"int64"};if("float"===n||"number"===n&&"float"===r)return{type:"number",format:"float"};if("double"===n||"number"===n&&"double"===r)return{type:"number",format:"double"};if("string"===n&&"date-time"===r||"date"===n)return{type:"string",format:"date-time"};if("string"===n)return{type:"string"};if("file"===n)return{type:"file"};if("boolean"===n)return{type:"boolean"};if("boolean"===n)return{type:"boolean"};if("array"===n||"list"===n){if(e.items){var o=this.toJsonSchema(e.items);return{type:"array",items:o}}return{type:"array",items:{type:"object"}}}return e.$ref?{$ref:this.modelMap[e.$ref]?"#/definitions/"+this.modelMap[e.$ref]:e.$ref}:"void"===n||""===n?{}:this.modelMap[e.type]?{$ref:"#/definitions/"+this.modelMap[e.type]}:{type:e.type}},a.prototype.resourceListing=function(e,t,n,i){var a,o=0,s=this,l=e.apis.length,u=t,c={};n&&n.requestInterceptor&&(c.requestInterceptor=n.requestInterceptor),n&&n.responseInterceptor&&(c.responseInterceptor=n.responseInterceptor);var p="application/json";for(n&&n.swaggerRequestHeaders&&(p=n.swaggerRequestHeaders),0===l&&this.finish(i,t),a=0;a<l;a++){var h=e.apis[a],f=h.path,d=this.getAbsolutePath(e.swaggerVersion,this.docLocation,f);h.description&&(t.tags=t.tags||[],t.tags.push({name:this.extractTag(h.path),description:h.description||""}));var m={url:d,headers:{accept:p},on:{},method:"get"};m.on.response=function(e){o+=1;var t=e.obj;t&&s.declaration(t,u),o===l&&s.finish(i,u)},m.on.error=function(e){console.error(e),o+=1,o===l&&s.finish(i,u)},this.clientAuthorizations&&"function"==typeof this.clientAuthorizations.apply&&this.clientAuthorizations.apply(m),(new r).execute(m,c)}},a.prototype.getAbsolutePath=function(e,t,n){if("1.0"===e&&t.endsWith(".json")){var r=t.lastIndexOf("/");r>0&&(t=t.substring(0,r))}var i=t;return 0===n.indexOf("http:")||0===n.indexOf("https:")?i=n:(t.endsWith("/")&&(i=t.substring(0,t.length-1)),i+=n),i=i.replace("{format}","json")},a.prototype.securityDefinitions=function(e,t){if(e.authorizations){var n;for(n in e.authorizations){var r=!1,i={},a=e.authorizations[n];if("apiKey"===a.type)i.type="apiKey",i["in"]=a.passAs,i.name=a.keyname||n,r=!0;else if("basicAuth"===a.type)i.type="basicAuth",r=!0;else if("oauth2"===a.type){var o,s=a.scopes||[],l={};for(o in s){var u=s[o];l[u.scope]=u.description}if(i.type="oauth2",o>0&&(i.scopes=l),a.grantTypes){if(a.grantTypes.implicit){var c=a.grantTypes.implicit;i.flow="implicit",i.authorizationUrl=c.loginEndpoint,r=!0}if(a.grantTypes.authorization_code&&!i.flow){var p=a.grantTypes.authorization_code;i.flow="accessCode",i.authorizationUrl=p.tokenRequestEndpoint.url,i.tokenUrl=p.tokenEndpoint.url,r=!0}}}r&&(t.securityDefinitions=t.securityDefinitions||{},t.securityDefinitions[n]=i)}}},a.prototype.apiInfo=function(e,t){if(e.info){var n=e.info;t.info={},n.contact&&(t.info.contact={},t.info.contact.email=n.contact),n.description&&(t.info.description=n.description),n.title&&(t.info.title=n.title),n.termsOfServiceUrl&&(t.info.termsOfService=n.termsOfServiceUrl),(n.license||n.licenseUrl)&&(t.license={},n.license&&(t.license.name=n.license),n.licenseUrl&&(t.license.url=n.licenseUrl))}else this.warnings.push("missing info section")},a.prototype.finish=function(e,t){e(t)}},{"./http":5,"lodash-compat/lang/isObject":144}],9:[function(e,t,n){"use strict";var r=(e("../helpers").log,{isPlainObject:e("lodash-compat/lang/isPlainObject"),isString:e("lodash-compat/lang/isString")}),i=e("../schema-markup.js"),a=e("js-yaml"),o=t.exports=function(e,t,n,r){return this.definition=t||{},this.isArray="array"===t.type,this.models=n||{},this.name=e||t.title||"Inline Model",this.modelPropertyMacro=r||function(e){return e["default"]},this};o.prototype.createJSONSample=o.prototype.getSampleValue=function(e){return e=e||{},e[this.name]=this,this.examples&&r.isPlainObject(this.examples)&&this.examples["application/json"]?(this.definition.example=this.examples["application/json"],r.isString(this.definition.example)&&(this.definition.example=a.safeLoad(this.definition.example))):this.definition.example||(this.definition.example=this.examples),i.schemaToJSON(this.definition,this.models,e,this.modelPropertyMacro)},o.prototype.getMockSignature=function(){return i.schemaToHTML(this.name,this.definition,this.models,this.modelPropertyMacro)}},{"../helpers":4,"../schema-markup.js":7,"js-yaml":19,"lodash-compat/lang/isPlainObject":145,"lodash-compat/lang/isString":146}],10:[function(e,t,n){"use strict";function r(e,t){if(i.isEmpty(t))return e[0];for(var n=0,r=t.length;n<r;n++)if(e.indexOf(t[n])>-1)return t[n];return e[0]}var i={cloneDeep:e("lodash-compat/lang/cloneDeep"),isUndefined:e("lodash-compat/lang/isUndefined"),isEmpty:e("lodash-compat/lang/isEmpty"),isObject:e("lodash-compat/lang/isObject")},a=e("../helpers"),o=e("./model"),s=e("../http"),l=e("q"),u=t.exports=function(e,t,n,r,i,a,s,l,u){var c=[];if(e=e||{},a=a||{},e&&e.options&&(this.client=e.options.client||null,this.requestInterceptor=e.options.requestInterceptor||null,this.responseInterceptor=e.options.responseInterceptor||null),this.authorizations=a.security,this.basePath=e.basePath||"/",this.clientAuthorizations=u,this.consumes=a.consumes||e.consumes||["application/json"],this.produces=a.produces||e.produces||["application/json"],this.deprecated=a.deprecated,this.description=a.description,this.host=e.host||"localhost",this.method=r||c.push("Operation "+n+" is missing method."),this.models=l||{},this.nickname=n||c.push("Operations must have a nickname."),this.operation=a,this.operations={},this.parameters=null!==a?a.parameters||[]:{},this.parent=e,this.path=i||c.push("Operation "+this.nickname+" is missing path."),this.responses=a.responses||{},this.scheme=t||e.scheme||"http",this.schemes=a.schemes||e.schemes,this.security=a.security||e.security,this.summary=a.summary||"",this.type=null,this.useJQuery=e.useJQuery,this.jqueryAjaxCache=e.jqueryAjaxCache,this.enableCookies=e.enableCookies,this.parameterMacro=e.parameterMacro||function(e,t){return t["default"]},this.inlineModels=[],"/"!==this.basePath&&"/"===this.basePath.slice(-1)&&(this.basePath=this.basePath.slice(0,-1)),"string"==typeof this.deprecated)switch(this.deprecated.toLowerCase()){case"true":case"yes":case"1":this.deprecated=!0;break;case"false":case"no":case"0":case null:this.deprecated=!1;break;default:this.deprecated=Boolean(this.deprecated)}var p,h;if(s){var f;for(f in s)h=new o(f,s[f],this.models,e.modelPropertyMacro),h&&(this.models[f]=h)}else s={};for(p=0;p<this.parameters.length;p++){var d=this.parameters[p];d["default"]=this.parameterMacro(this,d),"array"===d.type&&(d.isList=!0,d.allowMultiple=!0);var m=this.getType(d);if(m&&"boolean"===m.toString().toLowerCase()&&(d.allowableValues={},d.isList=!0,d["enum"]=[!0,!1]),"undefined"!=typeof d["x-example"]){var g=d["x-example"];d["default"]=g}if(d["x-examples"]){var g=d["x-examples"]["default"];"undefined"!=typeof g&&(d["default"]=g)}var y=d["enum"]||d.items&&d.items["enum"];if("undefined"!=typeof y){var v;for(d.allowableValues={},d.allowableValues.values=[],d.allowableValues.descriptiveValues=[],v=0;v<y.length;v++){var b=y[v],w=b===d["default"]||b+""===d["default"];d.allowableValues.values.push(b),d.allowableValues.descriptiveValues.push({value:b+"",isDefault:w})}}"array"===d.type&&(m=[m],"undefined"==typeof d.allowableValues&&(delete d.isList,delete d.allowMultiple)),d.modelSignature={type:m,definitions:this.models},d.signature=this.getModelSignature(m,this.models).toString(),d.sampleJSON=this.getModelSampleJSON(m,this.models),d.responseClassSignature=d.signature}var _,x,A=this.responses;if(A[200]?(x=A[200],_="200"):A[201]?(x=A[201],_="201"):A[202]?(x=A[202],_="202"):A[203]?(x=A[203],_="203"):A[204]?(x=A[204],_="204"):A[205]?(x=A[205],_="205"):A[206]?(x=A[206],_="206"):A["default"]&&(x=A["default"],_="default"),x&&x.schema){var S,j=this.resolveModel(x.schema,s);delete A[_],j?(this.successResponse={},S=this.successResponse[_]=j):x.schema.type&&"object"!==x.schema.type&&"array"!==x.schema.type?(this.successResponse={},S=this.successResponse[_]=x.schema):(this.successResponse={},S=this.successResponse[_]=new o((void 0),x.schema||{},this.models,e.modelPropertyMacro)),S&&(x.description&&(S.description=x.description),x.examples&&(S.examples=x.examples),x.headers&&(S.headers=x.headers)),this.type=x}return c.length>0&&this.resource&&this.resource.api&&this.resource.api.fail&&this.resource.api.fail(c),this};u.prototype.isDefaultArrayItemValue=function(e,t){return t["default"]&&Array.isArray(t["default"])?t["default"].indexOf(e)!==-1:e===t["default"]},u.prototype.getType=function(e){var t,n=e.type,r=e.format,i=!1;"integer"===n&&"int32"===r?t="integer":"integer"===n&&"int64"===r?t="long":"integer"===n?t="integer":"string"===n?t="date-time"===r?"date-time":"date"===r?"date":"string":"number"===n&&"float"===r?t="float":"number"===n&&"double"===r?t="double":"number"===n?t="double":"boolean"===n?t="boolean":"array"===n?(i=!0,e.items&&(t=this.getType(e.items))):"file"===n&&(t="file"),e.$ref&&(t=a.simpleRef(e.$ref));var o=e.schema;if(o){var s=o.$ref;return s?(s=a.simpleRef(s),i?[s]:s):"object"===o.type?this.addInlineModel(o):this.getType(o)}return i?[t]:t},u.prototype.addInlineModel=function(e){var t=this.inlineModels.length,n=this.resolveModel(e,{});return n?(this.inlineModels.push(n),"Inline Model "+t):null},u.prototype.getInlineModel=function(e){if(/^Inline Model \d+$/.test(e)){var t=parseInt(e.substr("Inline Model".length).trim(),10),n=this.inlineModels[t];return n}return null},u.prototype.resolveModel=function(e,t){if("undefined"!=typeof e.$ref){var n=e.$ref;if(0===n.indexOf("#/definitions/")&&(n=n.substring("#/definitions/".length)),t[n])return new o(n,t[n],this.models,this.parent.modelPropertyMacro)}else if(e&&"object"==typeof e&&("object"===e.type||i.isUndefined(e.type)))return new o((void 0),e,this.models,this.parent.modelPropertyMacro);return null},u.prototype.help=function(e){for(var t=this.nickname+": "+this.summary+"\n",n=0;n<this.parameters.length;n++){var r=this.parameters[n],i=r.signature;t+="\n * "+r.name+" ("+i+"): "+r.description}return"undefined"==typeof e&&a.log(t),t},u.prototype.getModelSignature=function(e,t){var n,r;return e instanceof Array&&(r=!0,e=e[0]),"undefined"==typeof e?(e="undefined",n=!0):t[e]?(e=t[e],n=!1):this.getInlineModel(e)?(e=this.getInlineModel(e),n=!1):n=!0,n?r?"Array["+e+"]":e.toString():r?"Array["+e.getMockSignature()+"]":e.getMockSignature()},u.prototype.supportHeaderParams=function(){return!0},u.prototype.supportedSubmitMethods=function(){return this.parent.supportedSubmitMethods},u.prototype.getHeaderParams=function(e){for(var t=this.setContentTypes(e,{}),n=0;n<this.parameters.length;n++){var r=this.parameters[n];if("undefined"!=typeof e[r.name]&&"header"===r["in"]){var i=e[r.name];Array.isArray(i)&&(i=i.toString()),t[r.name]=i}}return t},u.prototype.urlify=function(e){for(var t={},n=this.path.replace(/#.*/,""),r="",i=0;i<this.parameters.length;i++){var a=this.parameters[i];if("undefined"!=typeof e[a.name])if("path"===a["in"]){var o=new RegExp("{"+a.name+"}","gi"),s=e[a.name];s=Array.isArray(s)?this.encodePathCollection(a.collectionFormat,a.name,s):this.encodePathParam(s),n=n.replace(o,s)}else if("query"===a["in"]&&"undefined"!=typeof e[a.name])if(r+=""===r&&n.indexOf("?")<0?"?":"&","undefined"!=typeof a.collectionFormat){var l=e[a.name];r+=Array.isArray(l)?this.encodeQueryCollection(a.collectionFormat,a.name,l):this.encodeQueryKey(a.name)+"="+this.encodeQueryParam(e[a.name])}else r+=this.encodeQueryKey(a.name)+"="+this.encodeQueryParam(e[a.name]);else"formData"===a["in"]&&(t[a.name]=e[a.name])}var u=this.scheme+"://"+this.host;return"/"!==this.basePath&&(u+=this.basePath),u+n+r},u.prototype.getMissingParams=function(e){var t,n=[];for(t=0;t<this.parameters.length;t++){var r=this.parameters[t];r.required===!0&&"undefined"==typeof e[r.name]&&(n=r.name)}return n},u.prototype.getBody=function(e,t,n){for(var r,i,a,o,s={},l=!1,u=0;u<this.parameters.length;u++){var c=this.parameters[u];"undefined"!=typeof t[c.name]?"body"===c["in"]?i=t[c.name]:"formData"===c["in"]&&(s[c.name]={param:c,value:t[c.name]},r=!0):"body"===c["in"]&&(l=!0)}if(l&&"undefined"==typeof i){var p=e["Content-Type"];p&&0===p.indexOf("application/json")&&(i="{}")}var h=!1;if(e["Content-Type"]&&e["Content-Type"].indexOf("multipart/form-data")>=0&&(h=!0),r&&!h){var f="";for(a in s){var c=s[a].param;o=s[a].value,"undefined"!=typeof o&&(Array.isArray(o)?(""!==f&&(f+="&"),f+=this.encodeQueryCollection(c.collectionFormat,a,o)):(""!==f&&(f+="&"),f+=encodeURIComponent(a)+"="+encodeURIComponent(o)))}i=f}else if(h){if("function"==typeof FormData){var d=new FormData;d.type="formData";for(a in s)o=t[a],"undefined"!=typeof o&&("[object File]"==={}.toString.apply(o)?d.append(a,o):"file"===o.type&&o.value?d.append(a,o.value):Array.isArray(o)?d.append(a,this.encodeQueryCollection(c.collectionFormat,a,o)):d.append(a,o));i=d}else{d={};for(a in s)if(o=t[a],Array.isArray(o)){var m,g=c.collectionFormat||"multi";m="ssv"===g?" ":"pipes"===g?"|":"tsv"===g?"\t":",";var y;o.forEach(function(e){y?y+=m:y="",y+=e}),d[a]=y}else d[a]=o;i=d}e["Content-Type"]="multipart/form-data"}return i},u.prototype.getModelSampleJSON=function(e,t){var n,r,a;if(t=t||{},n=e instanceof Array,a=n?e[0]:e,t[a]?r=t[a].createJSONSample():this.getInlineModel(a)&&(r=this.getInlineModel(a).createJSONSample()),r){if(r=n?[r]:r,"string"==typeof r)return r;if(i.isObject(r)){var o=r;if(r instanceof Array&&r.length>0&&(o=r[0]),o.nodeName&&"Node"==typeof o){var s=(new XMLSerializer).serializeToString(o);return this.formatXml(s)}return JSON.stringify(r,null,2)}return r}},u.prototype["do"]=function(e,t,n,r,i){return this.execute(e,t,n,r,i)},u.prototype.execute=function(e,t,n,r,o){var u,c,p,h=e||{},f={};i.isObject(t)&&(f=t,u=n,c=r),this.client&&(f.client=this.client),!f.requestInterceptor&&this.requestInterceptor&&(f.requestInterceptor=this.requestInterceptor),!f.responseInterceptor&&this.responseInterceptor&&(f.responseInterceptor=this.responseInterceptor),"function"==typeof t&&(u=t,c=n),this.parent.usePromise?p=l.defer():(u=u||this.parent.defaultSuccessCallback||a.log,c=c||this.parent.defaultErrorCallback||a.log),"undefined"==typeof f.useJQuery&&(f.useJQuery=this.useJQuery),"undefined"==typeof f.jqueryAjaxCache&&(f.jqueryAjaxCache=this.jqueryAjaxCache),"undefined"==typeof f.enableCookies&&(f.enableCookies=this.enableCookies);var d=this.getMissingParams(h);if(d.length>0){var m="missing required params: "+d;return a.fail(m),this.parent.usePromise?(p.reject(m),p.promise):(c(m,o),{})}var g,y=this.getHeaderParams(h),v=this.setContentTypes(h,f),b={};for(g in y)b[g]=y[g];for(g in v)b[g]=v[g];var w=this.getBody(v,h,f),_=this.urlify(h);if(_.indexOf(".{format}")>0&&b){var x=b.Accept||b.accept;x&&x.indexOf("json")>0?_=_.replace(".{format}",".json"):x&&x.indexOf("xml")>0&&(_=_.replace(".{format}",".xml"))}var A={url:_,method:this.method.toUpperCase(),
+body:w,enableCookies:f.enableCookies,useJQuery:f.useJQuery,jqueryAjaxCache:f.jqueryAjaxCache,deferred:p,headers:b,clientAuthorizations:f.clientAuthorizations,on:{response:function(e){return p?(p.resolve(e),p.promise):u(e,o)},error:function(e){return p?(p.reject(e),p.promise):c(e,o)}}};return this.clientAuthorizations.apply(A,this.operation.security),f.mock===!0?A:(new s).execute(A,f)},u.prototype.setContentTypes=function(e,t){var n,i,o=this.parameters,s=e.parameterContentType||r(this.consumes,["application/json","application/yaml"]),l=t.responseContentType||r(this.produces,["application/json","application/yaml"]),u=[],c=[],p={};for(i=0;i<o.length;i++){var h=o[i];if("formData"===h["in"])"file"===h.type?u.push(h):c.push(h);else if("header"===h["in"]&&t){var f=h.name,d=t[h.name];"undefined"!=typeof t[h.name]&&(p[f]=d)}else"body"===h["in"]&&"undefined"!=typeof e[h.name]&&(n=e[h.name])}var m=n||u.length||c.length;if("post"===this.method||"put"===this.method||"patch"===this.method||("delete"===this.method||"get"===this.method)&&m){if(t.requestContentType&&(s=t.requestContentType),c.length>0){if(s=void 0,t.requestContentType)s=t.requestContentType;else if(u.length>0)s="multipart/form-data";else if(this.consumes&&this.consumes.length>0)for(var g in this.consumes){var y=this.consumes[g];0!==y.indexOf("application/x-www-form-urlencoded")&&0!==y.indexOf("multipart/form-data")||(s=y)}"undefined"==typeof s&&(s="application/x-www-form-urlencoded")}}else s=null;return s&&this.consumes&&this.consumes.indexOf(s)===-1&&a.log("server doesn't consume "+s+", try "+JSON.stringify(this.consumes)),this.matchesAccept(l)||a.log("server can't produce "+l),s&&""!==n||"application/x-www-form-urlencoded"===s?p["Content-Type"]=s:this.consumes&&this.consumes.length>0&&"application/x-www-form-urlencoded"===this.consumes[0]&&(p["Content-Type"]=this.consumes[0]),l&&(p.Accept=l),p},u.prototype.matchesAccept=function(e){return!e||!this.produces||(this.produces.indexOf(e)!==-1||this.produces.indexOf("*/*")!==-1)},u.prototype.asCurl=function(e,t){var n={mock:!0};if("object"==typeof t)for(var r in t)n[r]=t[r];var a=this.execute(e,n);this.clientAuthorizations.apply(a,this.operation.security);var o=[];if(o.push("-X "+this.method.toUpperCase()),"undefined"!=typeof a.headers){var s;for(s in a.headers){var l=a.headers[s];"string"==typeof l&&(l=l.replace(/\'/g,"\\u0027")),o.push("--header '"+s+": "+l+"'")}}var u=!1,c=!1,p=a.headers["Content-Type"];if(p&&0===p.indexOf("application/x-www-form-urlencoded")?u=!0:p&&0===p.indexOf("multipart/form-data")&&(u=!0,c=!0),a.body){var h;if(i.isObject(a.body)){if(c){c=!0;for(var f=0;f<this.parameters.length;f++){var d=this.parameters[f];if("formData"===d["in"]){h||(h="");var m;m="function"==typeof FormData&&a.body instanceof FormData?a.body.get(d.name):a.body[d.name],m&&("file"===d.type?m.name&&(h+="-F "+d.name+'=@"'+m.name+'" '):(h+="-F ",h+=Array.isArray(m)?this.encodeQueryCollection(d.collectionFormat,d.name,m):this.encodeQueryKey(d.name)+"="+m,h+=" "))}}}h||(h=JSON.stringify(a.body))}else h=a.body;h=h.replace(/\'/g,"%27").replace(/\n/g," \\ \n "),u||(h=h.replace(/&/g,"%26")),c?o.push(h):o.push("-d '"+h.replace(/@/g,"%40")+"'")}return"curl "+o.join(" ")+" '"+a.url+"'"},u.prototype.encodePathCollection=function(e,t,n){var r,i="",a="";for(a="ssv"===e?"%20":"tsv"===e?"%09":"pipes"===e?"|":",",r=0;r<n.length;r++)0===r?i=this.encodeQueryParam(n[r]):i+=a+this.encodeQueryParam(n[r]);return i},u.prototype.encodeQueryCollection=function(e,t,n){var r,i="";if(e=e||"default","default"===e||"multi"===e)for(r=0;r<n.length;r++)r>0&&(i+="&"),i+=this.encodeQueryKey(t)+"="+this.encodeQueryParam(n[r]);else{var a="";if("csv"===e)a=",";else if("ssv"===e)a="%20";else if("tsv"===e)a="%09";else if("pipes"===e)a="|";else if("brackets"===e)for(r=0;r<n.length;r++)0!==r&&(i+="&"),i+=this.encodeQueryKey(t)+"[]="+this.encodeQueryParam(n[r]);if(""!==a)for(r=0;r<n.length;r++)0===r?i=this.encodeQueryKey(t)+"="+this.encodeQueryParam(n[r]):i+=a+this.encodeQueryParam(n[r])}return i},u.prototype.encodeQueryKey=function(e){return encodeURIComponent(e).replace("%5B","[").replace("%5D","]").replace("%24","$")},u.prototype.encodeQueryParam=function(e){return encodeURIComponent(e)},u.prototype.encodePathParam=function(e){return encodeURIComponent(e)}},{"../helpers":4,"../http":5,"./model":9,"lodash-compat/lang/cloneDeep":138,"lodash-compat/lang/isEmpty":141,"lodash-compat/lang/isObject":144,"lodash-compat/lang/isUndefined":148,q:157}],11:[function(e,t,n){"use strict";var r=t.exports=function(e,t,n,r){this.description=t,this.externalDocs=n,this.name=e,this.operation=r,this.operationsArray=[],this.path=e,this.tag=e};r.prototype.sort=function(){}},{}],12:[function(e,t,n){function r(){if(!s){s=!0;for(var e,t=o.length;t;){e=o,o=[];for(var n=-1;++n<t;)e[n]();t=o.length}s=!1}}function i(){}var a=t.exports={},o=[],s=!1;a.nextTick=function(e){o.push(e),s||setTimeout(r,0)},a.title="browser",a.browser=!0,a.env={},a.argv=[],a.version="",a.versions={},a.on=i,a.addListener=i,a.once=i,a.off=i,a.removeListener=i,a.removeAllListeners=i,a.emit=i,a.binding=function(e){throw new Error("process.binding is not supported")},a.cwd=function(){return"/"},a.chdir=function(e){throw new Error("process.chdir is not supported")},a.umask=function(){return 0}},{}],13:[function(e,t,n){(function(e){!function(){"use strict";function n(t){var n;return n=t instanceof e?t:new e(t.toString(),"binary"),n.toString("base64")}t.exports=n}()}).call(this,e("buffer").Buffer)},{buffer:14}],14:[function(e,t,n){function r(){return i.TYPED_ARRAY_SUPPORT?2147483647:1073741823}function i(e){return this instanceof i?(this.length=0,this.parent=void 0,"number"==typeof e?a(this,e):"string"==typeof e?o(this,e,arguments.length>1?arguments[1]:"utf8"):s(this,e)):arguments.length>1?new i(e,arguments[1]):new i(e)}function a(e,t){if(e=d(e,t<0?0:0|m(t)),!i.TYPED_ARRAY_SUPPORT)for(var n=0;n<t;n++)e[n]=0;return e}function o(e,t,n){"string"==typeof n&&""!==n||(n="utf8");var r=0|y(t,n);return e=d(e,r),e.write(t,n),e}function s(e,t){if(i.isBuffer(t))return l(e,t);if(Q(t))return u(e,t);if(null==t)throw new TypeError("must start with number, buffer, array or string");if("undefined"!=typeof ArrayBuffer){if(t.buffer instanceof ArrayBuffer)return c(e,t);if(t instanceof ArrayBuffer)return p(e,t)}return t.length?h(e,t):f(e,t)}function l(e,t){var n=0|m(t.length);return e=d(e,n),t.copy(e,0,0,n),e}function u(e,t){var n=0|m(t.length);e=d(e,n);for(var r=0;r<n;r+=1)e[r]=255&t[r];return e}function c(e,t){var n=0|m(t.length);e=d(e,n);for(var r=0;r<n;r+=1)e[r]=255&t[r];return e}function p(e,t){return i.TYPED_ARRAY_SUPPORT?(t.byteLength,e=i._augment(new Uint8Array(t))):e=c(e,new Uint8Array(t)),e}function h(e,t){var n=0|m(t.length);e=d(e,n);for(var r=0;r<n;r+=1)e[r]=255&t[r];return e}function f(e,t){var n,r=0;"Buffer"===t.type&&Q(t.data)&&(n=t.data,r=0|m(n.length)),e=d(e,r);for(var i=0;i<r;i+=1)e[i]=255&n[i];return e}function d(e,t){i.TYPED_ARRAY_SUPPORT?e=i._augment(new Uint8Array(t)):(e.length=t,e._isBuffer=!0);var n=0!==t&&t<=i.poolSize>>>1;return n&&(e.parent=G),e}function m(e){if(e>=r())throw new RangeError("Attempt to allocate Buffer larger than maximum size: 0x"+r().toString(16)+" bytes");return 0|e}function g(e,t){if(!(this instanceof g))return new g(e,t);var n=new i(e,t);return delete n.parent,n}function y(e,t){"string"!=typeof e&&(e=""+e);var n=e.length;if(0===n)return 0;for(var r=!1;;)switch(t){case"ascii":case"binary":case"raw":case"raws":return n;case"utf8":case"utf-8":return $(e).length;case"ucs2":case"ucs-2":case"utf16le":case"utf-16le":return 2*n;case"hex":return n>>>1;case"base64":return H(e).length;default:if(r)return $(e).length;t=(""+t).toLowerCase(),r=!0}}function v(e,t,n){var r=!1;if(t=0|t,n=void 0===n||n===1/0?this.length:0|n,e||(e="utf8"),t<0&&(t=0),n>this.length&&(n=this.length),n<=t)return"";for(;;)switch(e){case"hex":return C(this,t,n);case"utf8":case"utf-8":return E(this,t,n);case"ascii":return k(this,t,n);case"binary":return T(this,t,n);case"base64":return j(this,t,n);case"ucs2":case"ucs-2":case"utf16le":case"utf-16le":return I(this,t,n);default:if(r)throw new TypeError("Unknown encoding: "+e);e=(e+"").toLowerCase(),r=!0}}function b(e,t,n,r){n=Number(n)||0;var i=e.length-n;r?(r=Number(r),r>i&&(r=i)):r=i;var a=t.length;if(a%2!==0)throw new Error("Invalid hex string");r>a/2&&(r=a/2);for(var o=0;o<r;o++){var s=parseInt(t.substr(2*o,2),16);if(isNaN(s))throw new Error("Invalid hex string");e[n+o]=s}return o}function w(e,t,n,r){return Y($(t,e.length-n),e,n,r)}function _(e,t,n,r){return Y(F(t),e,n,r)}function x(e,t,n,r){return _(e,t,n,r)}function A(e,t,n,r){return Y(H(t),e,n,r)}function S(e,t,n,r){return Y(V(t,e.length-n),e,n,r)}function j(e,t,n){return 0===t&&n===e.length?J.fromByteArray(e):J.fromByteArray(e.slice(t,n))}function E(e,t,n){n=Math.min(e.length,n);for(var r=[],i=t;i<n;){var a=e[i],o=null,s=a>239?4:a>223?3:a>191?2:1;if(i+s<=n){var l,u,c,p;switch(s){case 1:a<128&&(o=a);break;case 2:l=e[i+1],128===(192&l)&&(p=(31&a)<<6|63&l,p>127&&(o=p));break;case 3:l=e[i+1],u=e[i+2],128===(192&l)&&128===(192&u)&&(p=(15&a)<<12|(63&l)<<6|63&u,p>2047&&(p<55296||p>57343)&&(o=p));break;case 4:l=e[i+1],u=e[i+2],c=e[i+3],128===(192&l)&&128===(192&u)&&128===(192&c)&&(p=(15&a)<<18|(63&l)<<12|(63&u)<<6|63&c,p>65535&&p<1114112&&(o=p))}}null===o?(o=65533,s=1):o>65535&&(o-=65536,r.push(o>>>10&1023|55296),o=56320|1023&o),r.push(o),i+=s}return O(r)}function O(e){var t=e.length;if(t<=K)return String.fromCharCode.apply(String,e);for(var n="",r=0;r<t;)n+=String.fromCharCode.apply(String,e.slice(r,r+=K));return n}function k(e,t,n){var r="";n=Math.min(e.length,n);for(var i=t;i<n;i++)r+=String.fromCharCode(127&e[i]);return r}function T(e,t,n){var r="";n=Math.min(e.length,n);for(var i=t;i<n;i++)r+=String.fromCharCode(e[i]);return r}function C(e,t,n){var r=e.length;(!t||t<0)&&(t=0),(!n||n<0||n>r)&&(n=r);for(var i="",a=t;a<n;a++)i+=z(e[a]);return i}function I(e,t,n){for(var r=e.slice(t,n),i="",a=0;a<r.length;a+=2)i+=String.fromCharCode(r[a]+256*r[a+1]);return i}function D(e,t,n){if(e%1!==0||e<0)throw new RangeError("offset is not uint");if(e+t>n)throw new RangeError("Trying to access beyond buffer length")}function L(e,t,n,r,a,o){if(!i.isBuffer(e))throw new TypeError("buffer must be a Buffer instance");if(t>a||t<o)throw new RangeError("value is out of bounds");if(n+r>e.length)throw new RangeError("index out of range")}function M(e,t,n,r){t<0&&(t=65535+t+1);for(var i=0,a=Math.min(e.length-n,2);i<a;i++)e[n+i]=(t&255<<8*(r?i:1-i))>>>8*(r?i:1-i)}function R(e,t,n,r){t<0&&(t=4294967295+t+1);for(var i=0,a=Math.min(e.length-n,4);i<a;i++)e[n+i]=t>>>8*(r?i:3-i)&255}function U(e,t,n,r,i,a){if(t>i||t<a)throw new RangeError("value is out of bounds");if(n+r>e.length)throw new RangeError("index out of range");if(n<0)throw new RangeError("index out of range")}function P(e,t,n,r,i){return i||U(e,t,n,4,3.4028234663852886e38,-3.4028234663852886e38),W.write(e,t,n,r,23,4),n+4}function q(e,t,n,r,i){return i||U(e,t,n,8,1.7976931348623157e308,-1.7976931348623157e308),W.write(e,t,n,r,52,8),n+8}function B(e){if(e=N(e).replace(Z,""),e.length<2)return"";for(;e.length%4!==0;)e+="=";return e}function N(e){return e.trim?e.trim():e.replace(/^\s+|\s+$/g,"")}function z(e){return e<16?"0"+e.toString(16):e.toString(16)}function $(e,t){t=t||1/0;for(var n,r=e.length,i=null,a=[],o=0;o<r;o++){if(n=e.charCodeAt(o),n>55295&&n<57344){if(!i){if(n>56319){(t-=3)>-1&&a.push(239,191,189);continue}if(o+1===r){(t-=3)>-1&&a.push(239,191,189);continue}i=n;continue}if(n<56320){(t-=3)>-1&&a.push(239,191,189),i=n;continue}n=i-55296<<10|n-56320|65536}else i&&(t-=3)>-1&&a.push(239,191,189);if(i=null,n<128){if((t-=1)<0)break;a.push(n)}else if(n<2048){if((t-=2)<0)break;a.push(n>>6|192,63&n|128)}else if(n<65536){if((t-=3)<0)break;a.push(n>>12|224,n>>6&63|128,63&n|128)}else{if(!(n<1114112))throw new Error("Invalid code point");if((t-=4)<0)break;a.push(n>>18|240,n>>12&63|128,n>>6&63|128,63&n|128)}}return a}function F(e){for(var t=[],n=0;n<e.length;n++)t.push(255&e.charCodeAt(n));return t}function V(e,t){for(var n,r,i,a=[],o=0;o<e.length&&!((t-=2)<0);o++)n=e.charCodeAt(o),r=n>>8,i=n%256,a.push(i),a.push(r);return a}function H(e){return J.toByteArray(B(e))}function Y(e,t,n,r){for(var i=0;i<r&&!(i+n>=t.length||i>=e.length);i++)t[i+n]=e[i];return i}var J=e("base64-js"),W=e("ieee754"),Q=e("is-array");n.Buffer=i,n.SlowBuffer=g,n.INSPECT_MAX_BYTES=50,i.poolSize=8192;var G={};i.TYPED_ARRAY_SUPPORT=function(){function e(){}try{var t=new Uint8Array(1);return t.foo=function(){return 42},t.constructor=e,42===t.foo()&&t.constructor===e&&"function"==typeof t.subarray&&0===t.subarray(1,1).byteLength}catch(n){return!1}}(),i.isBuffer=function(e){return!(null==e||!e._isBuffer)},i.compare=function(e,t){if(!i.isBuffer(e)||!i.isBuffer(t))throw new TypeError("Arguments must be Buffers");if(e===t)return 0;for(var n=e.length,r=t.length,a=0,o=Math.min(n,r);a<o&&e[a]===t[a];)++a;return a!==o&&(n=e[a],r=t[a]),n<r?-1:r<n?1:0},i.isEncoding=function(e){switch(String(e).toLowerCase()){case"hex":case"utf8":case"utf-8":case"ascii":case"binary":case"base64":case"raw":case"ucs2":case"ucs-2":case"utf16le":case"utf-16le":return!0;default:return!1}},i.concat=function(e,t){if(!Q(e))throw new TypeError("list argument must be an Array of Buffers.");if(0===e.length)return new i(0);var n;if(void 0===t)for(t=0,n=0;n<e.length;n++)t+=e[n].length;var r=new i(t),a=0;for(n=0;n<e.length;n++){var o=e[n];o.copy(r,a),a+=o.length}return r},i.byteLength=y,i.prototype.length=void 0,i.prototype.parent=void 0,i.prototype.toString=function(){var e=0|this.length;return 0===e?"":0===arguments.length?E(this,0,e):v.apply(this,arguments)},i.prototype.equals=function(e){if(!i.isBuffer(e))throw new TypeError("Argument must be a Buffer");return this===e||0===i.compare(this,e)},i.prototype.inspect=function(){var e="",t=n.INSPECT_MAX_BYTES;return this.length>0&&(e=this.toString("hex",0,t).match(/.{2}/g).join(" "),this.length>t&&(e+=" ... ")),"<Buffer "+e+">"},i.prototype.compare=function(e){if(!i.isBuffer(e))throw new TypeError("Argument must be a Buffer");return this===e?0:i.compare(this,e)},i.prototype.indexOf=function(e,t){function n(e,t,n){for(var r=-1,i=0;n+i<e.length;i++)if(e[n+i]===t[r===-1?0:i-r]){if(r===-1&&(r=i),i-r+1===t.length)return n+r}else r=-1;return-1}if(t>2147483647?t=2147483647:t<-2147483648&&(t=-2147483648),t>>=0,0===this.length)return-1;if(t>=this.length)return-1;if(t<0&&(t=Math.max(this.length+t,0)),"string"==typeof e)return 0===e.length?-1:String.prototype.indexOf.call(this,e,t);if(i.isBuffer(e))return n(this,e,t);if("number"==typeof e)return i.TYPED_ARRAY_SUPPORT&&"function"===Uint8Array.prototype.indexOf?Uint8Array.prototype.indexOf.call(this,e,t):n(this,[e],t);throw new TypeError("val must be string, number or Buffer")},i.prototype.get=function(e){return console.log(".get() is deprecated. Access using array indexes instead."),this.readUInt8(e)},i.prototype.set=function(e,t){return console.log(".set() is deprecated. Access using array indexes instead."),this.writeUInt8(e,t)},i.prototype.write=function(e,t,n,r){if(void 0===t)r="utf8",n=this.length,t=0;else if(void 0===n&&"string"==typeof t)r=t,n=this.length,t=0;else if(isFinite(t))t=0|t,isFinite(n)?(n=0|n,void 0===r&&(r="utf8")):(r=n,n=void 0);else{var i=r;r=t,t=0|n,n=i}var a=this.length-t;if((void 0===n||n>a)&&(n=a),e.length>0&&(n<0||t<0)||t>this.length)throw new RangeError("attempt to write outside buffer bounds");r||(r="utf8");for(var o=!1;;)switch(r){case"hex":return b(this,e,t,n);case"utf8":case"utf-8":return w(this,e,t,n);case"ascii":return _(this,e,t,n);case"binary":return x(this,e,t,n);case"base64":return A(this,e,t,n);case"ucs2":case"ucs-2":case"utf16le":case"utf-16le":return S(this,e,t,n);default:if(o)throw new TypeError("Unknown encoding: "+r);r=(""+r).toLowerCase(),o=!0}},i.prototype.toJSON=function(){return{type:"Buffer",data:Array.prototype.slice.call(this._arr||this,0)}};var K=4096;i.prototype.slice=function(e,t){var n=this.length;e=~~e,t=void 0===t?n:~~t,e<0?(e+=n,e<0&&(e=0)):e>n&&(e=n),t<0?(t+=n,t<0&&(t=0)):t>n&&(t=n),t<e&&(t=e);var r;if(i.TYPED_ARRAY_SUPPORT)r=i._augment(this.subarray(e,t));else{var a=t-e;r=new i(a,(void 0));for(var o=0;o<a;o++)r[o]=this[o+e]}return r.length&&(r.parent=this.parent||this),r},i.prototype.readUIntLE=function(e,t,n){e=0|e,t=0|t,n||D(e,t,this.length);for(var r=this[e],i=1,a=0;++a<t&&(i*=256);)r+=this[e+a]*i;return r},i.prototype.readUIntBE=function(e,t,n){e=0|e,t=0|t,n||D(e,t,this.length);for(var r=this[e+--t],i=1;t>0&&(i*=256);)r+=this[e+--t]*i;return r},i.prototype.readUInt8=function(e,t){return t||D(e,1,this.length),this[e]},i.prototype.readUInt16LE=function(e,t){return t||D(e,2,this.length),this[e]|this[e+1]<<8},i.prototype.readUInt16BE=function(e,t){return t||D(e,2,this.length),this[e]<<8|this[e+1]},i.prototype.readUInt32LE=function(e,t){return t||D(e,4,this.length),(this[e]|this[e+1]<<8|this[e+2]<<16)+16777216*this[e+3]},i.prototype.readUInt32BE=function(e,t){return t||D(e,4,this.length),16777216*this[e]+(this[e+1]<<16|this[e+2]<<8|this[e+3])},i.prototype.readIntLE=function(e,t,n){e=0|e,t=0|t,n||D(e,t,this.length);for(var r=this[e],i=1,a=0;++a<t&&(i*=256);)r+=this[e+a]*i;return i*=128,r>=i&&(r-=Math.pow(2,8*t)),r},i.prototype.readIntBE=function(e,t,n){e=0|e,t=0|t,n||D(e,t,this.length);for(var r=t,i=1,a=this[e+--r];r>0&&(i*=256);)a+=this[e+--r]*i;return i*=128,a>=i&&(a-=Math.pow(2,8*t)),a},i.prototype.readInt8=function(e,t){return t||D(e,1,this.length),128&this[e]?(255-this[e]+1)*-1:this[e]},i.prototype.readInt16LE=function(e,t){t||D(e,2,this.length);var n=this[e]|this[e+1]<<8;return 32768&n?4294901760|n:n},i.prototype.readInt16BE=function(e,t){t||D(e,2,this.length);var n=this[e+1]|this[e]<<8;return 32768&n?4294901760|n:n},i.prototype.readInt32LE=function(e,t){return t||D(e,4,this.length),this[e]|this[e+1]<<8|this[e+2]<<16|this[e+3]<<24},i.prototype.readInt32BE=function(e,t){return t||D(e,4,this.length),this[e]<<24|this[e+1]<<16|this[e+2]<<8|this[e+3]},i.prototype.readFloatLE=function(e,t){return t||D(e,4,this.length),W.read(this,e,!0,23,4)},i.prototype.readFloatBE=function(e,t){return t||D(e,4,this.length),W.read(this,e,!1,23,4)},i.prototype.readDoubleLE=function(e,t){return t||D(e,8,this.length),W.read(this,e,!0,52,8)},i.prototype.readDoubleBE=function(e,t){return t||D(e,8,this.length),W.read(this,e,!1,52,8)},i.prototype.writeUIntLE=function(e,t,n,r){e=+e,t=0|t,n=0|n,r||L(this,e,t,n,Math.pow(2,8*n),0);var i=1,a=0;for(this[t]=255&e;++a<n&&(i*=256);)this[t+a]=e/i&255;return t+n},i.prototype.writeUIntBE=function(e,t,n,r){e=+e,t=0|t,n=0|n,r||L(this,e,t,n,Math.pow(2,8*n),0);var i=n-1,a=1;for(this[t+i]=255&e;--i>=0&&(a*=256);)this[t+i]=e/a&255;return t+n},i.prototype.writeUInt8=function(e,t,n){return e=+e,t=0|t,n||L(this,e,t,1,255,0),i.TYPED_ARRAY_SUPPORT||(e=Math.floor(e)),this[t]=e,t+1},i.prototype.writeUInt16LE=function(e,t,n){return e=+e,t=0|t,n||L(this,e,t,2,65535,0),i.TYPED_ARRAY_SUPPORT?(this[t]=e,this[t+1]=e>>>8):M(this,e,t,!0),t+2},i.prototype.writeUInt16BE=function(e,t,n){return e=+e,t=0|t,n||L(this,e,t,2,65535,0),i.TYPED_ARRAY_SUPPORT?(this[t]=e>>>8,this[t+1]=e):M(this,e,t,!1),t+2},i.prototype.writeUInt32LE=function(e,t,n){return e=+e,t=0|t,n||L(this,e,t,4,4294967295,0),i.TYPED_ARRAY_SUPPORT?(this[t+3]=e>>>24,this[t+2]=e>>>16,this[t+1]=e>>>8,this[t]=e):R(this,e,t,!0),t+4},i.prototype.writeUInt32BE=function(e,t,n){return e=+e,t=0|t,n||L(this,e,t,4,4294967295,0),i.TYPED_ARRAY_SUPPORT?(this[t]=e>>>24,this[t+1]=e>>>16,this[t+2]=e>>>8,this[t+3]=e):R(this,e,t,!1),t+4},i.prototype.writeIntLE=function(e,t,n,r){if(e=+e,t=0|t,!r){var i=Math.pow(2,8*n-1);L(this,e,t,n,i-1,-i)}var a=0,o=1,s=e<0?1:0;for(this[t]=255&e;++a<n&&(o*=256);)this[t+a]=(e/o>>0)-s&255;return t+n},i.prototype.writeIntBE=function(e,t,n,r){if(e=+e,t=0|t,!r){var i=Math.pow(2,8*n-1);L(this,e,t,n,i-1,-i)}var a=n-1,o=1,s=e<0?1:0;for(this[t+a]=255&e;--a>=0&&(o*=256);)this[t+a]=(e/o>>0)-s&255;return t+n},i.prototype.writeInt8=function(e,t,n){return e=+e,t=0|t,n||L(this,e,t,1,127,-128),i.TYPED_ARRAY_SUPPORT||(e=Math.floor(e)),e<0&&(e=255+e+1),this[t]=e,t+1},i.prototype.writeInt16LE=function(e,t,n){return e=+e,t=0|t,n||L(this,e,t,2,32767,-32768),i.TYPED_ARRAY_SUPPORT?(this[t]=e,this[t+1]=e>>>8):M(this,e,t,!0),t+2},i.prototype.writeInt16BE=function(e,t,n){return e=+e,t=0|t,n||L(this,e,t,2,32767,-32768),i.TYPED_ARRAY_SUPPORT?(this[t]=e>>>8,this[t+1]=e):M(this,e,t,!1),t+2},i.prototype.writeInt32LE=function(e,t,n){return e=+e,t=0|t,n||L(this,e,t,4,2147483647,-2147483648),i.TYPED_ARRAY_SUPPORT?(this[t]=e,this[t+1]=e>>>8,this[t+2]=e>>>16,this[t+3]=e>>>24):R(this,e,t,!0),t+4},i.prototype.writeInt32BE=function(e,t,n){return e=+e,t=0|t,n||L(this,e,t,4,2147483647,-2147483648),e<0&&(e=4294967295+e+1),i.TYPED_ARRAY_SUPPORT?(this[t]=e>>>24,this[t+1]=e>>>16,this[t+2]=e>>>8,this[t+3]=e):R(this,e,t,!1),t+4},i.prototype.writeFloatLE=function(e,t,n){return P(this,e,t,!0,n)},i.prototype.writeFloatBE=function(e,t,n){return P(this,e,t,!1,n)},i.prototype.writeDoubleLE=function(e,t,n){return q(this,e,t,!0,n)},i.prototype.writeDoubleBE=function(e,t,n){return q(this,e,t,!1,n)},i.prototype.copy=function(e,t,n,r){if(n||(n=0),r||0===r||(r=this.length),t>=e.length&&(t=e.length),t||(t=0),r>0&&r<n&&(r=n),r===n)return 0;if(0===e.length||0===this.length)return 0;if(t<0)throw new RangeError("targetStart out of bounds");if(n<0||n>=this.length)throw new RangeError("sourceStart out of bounds");if(r<0)throw new RangeError("sourceEnd out of bounds");r>this.length&&(r=this.length),e.length-t<r-n&&(r=e.length-t+n);var a,o=r-n;if(this===e&&n<t&&t<r)for(a=o-1;a>=0;a--)e[a+t]=this[a+n];else if(o<1e3||!i.TYPED_ARRAY_SUPPORT)for(a=0;a<o;a++)e[a+t]=this[a+n];else e._set(this.subarray(n,n+o),t);return o},i.prototype.fill=function(e,t,n){if(e||(e=0),t||(t=0),n||(n=this.length),n<t)throw new RangeError("end < start");if(n!==t&&0!==this.length){if(t<0||t>=this.length)throw new RangeError("start out of bounds");if(n<0||n>this.length)throw new RangeError("end out of bounds");var r;if("number"==typeof e)for(r=t;r<n;r++)this[r]=e;else{var i=$(e.toString()),a=i.length;for(r=t;r<n;r++)this[r]=i[r%a]}return this}},i.prototype.toArrayBuffer=function(){if("undefined"!=typeof Uint8Array){if(i.TYPED_ARRAY_SUPPORT)return new i(this).buffer;for(var e=new Uint8Array(this.length),t=0,n=e.length;t<n;t+=1)e[t]=this[t];return e.buffer}throw new TypeError("Buffer.toArrayBuffer not supported in this browser")};var X=i.prototype;i._augment=function(e){return e.constructor=i,e._isBuffer=!0,e._set=e.set,e.get=X.get,e.set=X.set,e.write=X.write,e.toString=X.toString,e.toLocaleString=X.toString,e.toJSON=X.toJSON,e.equals=X.equals,e.compare=X.compare,e.indexOf=X.indexOf,e.copy=X.copy,e.slice=X.slice,e.readUIntLE=X.readUIntLE,e.readUIntBE=X.readUIntBE,e.readUInt8=X.readUInt8,e.readUInt16LE=X.readUInt16LE,e.readUInt16BE=X.readUInt16BE,e.readUInt32LE=X.readUInt32LE,e.readUInt32BE=X.readUInt32BE,e.readIntLE=X.readIntLE,e.readIntBE=X.readIntBE,e.readInt8=X.readInt8,e.readInt16LE=X.readInt16LE,e.readInt16BE=X.readInt16BE,e.readInt32LE=X.readInt32LE,e.readInt32BE=X.readInt32BE,e.readFloatLE=X.readFloatLE,e.readFloatBE=X.readFloatBE,e.readDoubleLE=X.readDoubleLE,e.readDoubleBE=X.readDoubleBE,e.writeUInt8=X.writeUInt8,e.writeUIntLE=X.writeUIntLE,e.writeUIntBE=X.writeUIntBE,e.writeUInt16LE=X.writeUInt16LE,e.writeUInt16BE=X.writeUInt16BE,e.writeUInt32LE=X.writeUInt32LE,e.writeUInt32BE=X.writeUInt32BE,e.writeIntLE=X.writeIntLE,e.writeIntBE=X.writeIntBE,e.writeInt8=X.writeInt8,e.writeInt16LE=X.writeInt16LE,e.writeInt16BE=X.writeInt16BE,e.writeInt32LE=X.writeInt32LE,e.writeInt32BE=X.writeInt32BE,e.writeFloatLE=X.writeFloatLE,e.writeFloatBE=X.writeFloatBE,e.writeDoubleLE=X.writeDoubleLE,e.writeDoubleBE=X.writeDoubleBE,e.fill=X.fill,e.inspect=X.inspect,e.toArrayBuffer=X.toArrayBuffer,e};var Z=/[^+\/0-9A-Za-z-_]/g},{"base64-js":15,ieee754:16,"is-array":17}],15:[function(e,t,n){var r="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";!function(e){"use strict";function t(e){var t=e.charCodeAt(0);return t===o||t===p?62:t===s||t===h?63:t<l?-1:t<l+10?t-l+26+26:t<c+26?t-c:t<u+26?t-u+26:void 0}function n(e){function n(e){u[p++]=e}var r,i,o,s,l,u;if(e.length%4>0)throw new Error("Invalid string. Length must be a multiple of 4");var c=e.length;l="="===e.charAt(c-2)?2:"="===e.charAt(c-1)?1:0,u=new a(3*e.length/4-l),o=l>0?e.length-4:e.length;var p=0;for(r=0,i=0;r<o;r+=4,i+=3)s=t(e.charAt(r))<<18|t(e.charAt(r+1))<<12|t(e.charAt(r+2))<<6|t(e.charAt(r+3)),n((16711680&s)>>16),n((65280&s)>>8),n(255&s);return 2===l?(s=t(e.charAt(r))<<2|t(e.charAt(r+1))>>4,n(255&s)):1===l&&(s=t(e.charAt(r))<<10|t(e.charAt(r+1))<<4|t(e.charAt(r+2))>>2,n(s>>8&255),n(255&s)),u}function i(e){function t(e){return r.charAt(e)}function n(e){return t(e>>18&63)+t(e>>12&63)+t(e>>6&63)+t(63&e)}var i,a,o,s=e.length%3,l="";for(i=0,o=e.length-s;i<o;i+=3)a=(e[i]<<16)+(e[i+1]<<8)+e[i+2],l+=n(a);switch(s){case 1:a=e[e.length-1],l+=t(a>>2),l+=t(a<<4&63),l+="==";break;case 2:a=(e[e.length-2]<<8)+e[e.length-1],l+=t(a>>10),l+=t(a>>4&63),l+=t(a<<2&63),l+="="}return l}var a="undefined"!=typeof Uint8Array?Uint8Array:Array,o="+".charCodeAt(0),s="/".charCodeAt(0),l="0".charCodeAt(0),u="a".charCodeAt(0),c="A".charCodeAt(0),p="-".charCodeAt(0),h="_".charCodeAt(0);e.toByteArray=n,e.fromByteArray=i}("undefined"==typeof n?this.base64js={}:n)},{}],16:[function(e,t,n){n.read=function(e,t,n,r,i){var a,o,s=8*i-r-1,l=(1<<s)-1,u=l>>1,c=-7,p=n?i-1:0,h=n?-1:1,f=e[t+p];for(p+=h,a=f&(1<<-c)-1,f>>=-c,c+=s;c>0;a=256*a+e[t+p],p+=h,c-=8);for(o=a&(1<<-c)-1,a>>=-c,c+=r;c>0;o=256*o+e[t+p],p+=h,c-=8);if(0===a)a=1-u;else{if(a===l)return o?NaN:(f?-1:1)*(1/0);o+=Math.pow(2,r),a-=u}return(f?-1:1)*o*Math.pow(2,a-r)},n.write=function(e,t,n,r,i,a){var o,s,l,u=8*a-i-1,c=(1<<u)-1,p=c>>1,h=23===i?Math.pow(2,-24)-Math.pow(2,-77):0,f=r?0:a-1,d=r?1:-1,m=t<0||0===t&&1/t<0?1:0;for(t=Math.abs(t),isNaN(t)||t===1/0?(s=isNaN(t)?1:0,o=c):(o=Math.floor(Math.log(t)/Math.LN2),t*(l=Math.pow(2,-o))<1&&(o--,l*=2),t+=o+p>=1?h/l:h*Math.pow(2,1-p),t*l>=2&&(o++,l/=2),o+p>=c?(s=0,o=c):o+p>=1?(s=(t*l-1)*Math.pow(2,i),o+=p):(s=t*Math.pow(2,p-1)*Math.pow(2,i),o=0));i>=8;e[n+f]=255&s,f+=d,s/=256,i-=8);for(o=o<<i|s,u+=i;u>0;e[n+f]=255&o,f+=d,o/=256,u-=8);e[n+f-d]|=128*m}},{}],17:[function(e,t,n){var r=Array.isArray,i=Object.prototype.toString;t.exports=r||function(e){return!!e&&"[object Array]"==i.call(e)}},{}],18:[function(e,t,n){!function(){"use strict";function e(t,n,r,i){return this instanceof e?(this.domain=t||void 0,this.path=n||"/",this.secure=!!r,this.script=!!i,this):new e(t,n,r,i)}function t(e,n,r){return e instanceof t?e:this instanceof t?(this.name=null,this.value=null,this.expiration_date=1/0,this.path=String(r||"/"),this.explicit_path=!1,this.domain=n||null,this.explicit_domain=!1,this.secure=!1,this.noscript=!1,e&&this.parse(e,n,r),this):new t(e,n,r)}function r(){var e,n,i;return this instanceof r?(e=Object.create(null),this.setCookie=function(r,a,o){var s,l;if(r=new t(r,a,o),s=r.expiration_date<=Date.now(),void 0!==e[r.name]){for(n=e[r.name],l=0;l<n.length;l+=1)if(i=n[l],i.collidesWith(r))return s?(n.splice(l,1),0===n.length&&delete e[r.name],!1):(n[l]=r,r);return!s&&(n.push(r),r)}return!s&&(e[r.name]=[r],e[r.name])},this.getCookie=function(t,r){var i,a;if(n=e[t])for(a=0;a<n.length;a+=1)if(i=n[a],i.expiration_date<=Date.now())0===n.length&&delete e[i.name];else if(i.matches(r))return i},this.getCookies=function(t){var n,r,i=[];for(n in e)r=this.getCookie(n,t),r&&i.push(r);return i.toString=function(){return i.join(":")},i.toValueString=function(){return i.map(function(e){return e.toValueString()}).join(";")},i},this):new r}n.CookieAccessInfo=e,n.Cookie=t,t.prototype.toString=function(){var e=[this.name+"="+this.value];return this.expiration_date!==1/0&&e.push("expires="+new Date(this.expiration_date).toGMTString()),this.domain&&e.push("domain="+this.domain),this.path&&e.push("path="+this.path),this.secure&&e.push("secure"),this.noscript&&e.push("httponly"),e.join("; ")},t.prototype.toValueString=function(){return this.name+"="+this.value};var i=/[:](?=\s*[a-zA-Z0-9_\-]+\s*[=])/g;t.prototype.parse=function(e,n,r){if(this instanceof t){var i,a=e.split(";").filter(function(e){return!!e}),o=a[0].match(/([^=]+)=([\s\S]*)/),s=o[1],l=o[2];for(this.name=s,this.value=l,i=1;i<a.length;i+=1)switch(o=a[i].match(/([^=]+)(?:=([\s\S]*))?/),s=o[1].trim().toLowerCase(),l=o[2],s){case"httponly":this.noscript=!0;break;case"expires":this.expiration_date=l?Number(Date.parse(l)):1/0;break;case"path":this.path=l?l.trim():"",this.explicit_path=!0;break;case"domain":this.domain=l?l.trim():"",this.explicit_domain=!!this.domain;break;case"secure":this.secure=!0}return this.explicit_path||(this.path=r||"/"),this.explicit_domain||(this.domain=n),this}return(new t).parse(e,n,r)},t.prototype.matches=function(e){return!(this.noscript&&e.script||this.secure&&!e.secure||!this.collidesWith(e))},t.prototype.collidesWith=function(e){if(this.path&&!e.path||this.domain&&!e.domain)return!1;if(this.path&&0!==e.path.indexOf(this.path))return!1;if(this.explicit_path&&0!==e.path.indexOf(this.path))return!1;var t=e.domain&&e.domain.replace(/^[\.]/,""),n=this.domain&&this.domain.replace(/^[\.]/,"");if(n===t)return!0;if(n){if(!this.explicit_domain)return!1;var r=t.indexOf(n);return r!==-1&&r===t.length-n.length}return!0},n.CookieJar=r,r.prototype.setCookies=function(e,n,r){e=Array.isArray(e)?e:e.split(i);var a,o,s=[];for(e=e.map(function(e){return new t(e,n,r)}),a=0;a<e.length;a+=1)o=e[a],this.setCookie(o,n,r)&&s.push(o);return s}}()},{}],19:[function(e,t,n){"use strict";var r=e("./lib/js-yaml.js");t.exports=r},{"./lib/js-yaml.js":20}],20:[function(e,t,n){"use strict";function r(e){return function(){throw new Error("Function "+e+" is deprecated and cannot be used.")}}var i=e("./js-yaml/loader"),a=e("./js-yaml/dumper");t.exports.Type=e("./js-yaml/type"),t.exports.Schema=e("./js-yaml/schema"),t.exports.FAILSAFE_SCHEMA=e("./js-yaml/schema/failsafe"),t.exports.JSON_SCHEMA=e("./js-yaml/schema/json"),t.exports.CORE_SCHEMA=e("./js-yaml/schema/core"),t.exports.DEFAULT_SAFE_SCHEMA=e("./js-yaml/schema/default_safe"),t.exports.DEFAULT_FULL_SCHEMA=e("./js-yaml/schema/default_full"),t.exports.load=i.load,t.exports.loadAll=i.loadAll,t.exports.safeLoad=i.safeLoad,t.exports.safeLoadAll=i.safeLoadAll,t.exports.dump=a.dump,t.exports.safeDump=a.safeDump,t.exports.YAMLException=e("./js-yaml/exception"),t.exports.MINIMAL_SCHEMA=e("./js-yaml/schema/failsafe"),t.exports.SAFE_SCHEMA=e("./js-yaml/schema/default_safe"),t.exports.DEFAULT_SCHEMA=e("./js-yaml/schema/default_full"),t.exports.scan=r("scan"),t.exports.parse=r("parse"),t.exports.compose=r("compose"),t.exports.addConstructor=r("addConstructor")},{"./js-yaml/dumper":22,"./js-yaml/exception":23,"./js-yaml/loader":24,"./js-yaml/schema":26,"./js-yaml/schema/core":27,"./js-yaml/schema/default_full":28,"./js-yaml/schema/default_safe":29,"./js-yaml/schema/failsafe":30,"./js-yaml/schema/json":31,"./js-yaml/type":32}],21:[function(e,t,n){"use strict";function r(e){return"undefined"==typeof e||null===e}function i(e){return"object"==typeof e&&null!==e}function a(e){return Array.isArray(e)?e:r(e)?[]:[e]}function o(e,t){var n,r,i,a;if(t)for(a=Object.keys(t),n=0,r=a.length;n<r;n+=1)i=a[n],e[i]=t[i];return e}function s(e,t){var n,r="";for(n=0;n<t;n+=1)r+=e;return r}function l(e){return 0===e&&Number.NEGATIVE_INFINITY===1/e}t.exports.isNothing=r,t.exports.isObject=i,t.exports.toArray=a,t.exports.repeat=s,t.exports.isNegativeZero=l,t.exports.extend=o},{}],22:[function(e,t,n){"use strict";function r(e,t){var n,r,i,a,o,s,l;if(null===t)return{};for(n={},r=Object.keys(t),i=0,a=r.length;i<a;i+=1)o=r[i],s=String(t[o]),"!!"===o.slice(0,2)&&(o="tag:yaml.org,2002:"+o.slice(2)),l=e.compiledTypeMap[o],l&&R.call(l.styleAliases,s)&&(s=l.styleAliases[s]),n[o]=s;return n}function i(e){var t,n,r;if(t=e.toString(16).toUpperCase(),e<=255)n="x",r=2;else if(e<=65535)n="u",r=4;else{if(!(e<=4294967295))throw new I("code point within a string may not be greater than 0xFFFFFFFF");n="U",r=8}return"\\"+n+C.repeat("0",r-t.length)+t;
+}function a(e){this.schema=e.schema||D,this.indent=Math.max(1,e.indent||2),this.skipInvalid=e.skipInvalid||!1,this.flowLevel=C.isNothing(e.flowLevel)?-1:e.flowLevel,this.styleMap=r(this.schema,e.styles||null),this.sortKeys=e.sortKeys||!1,this.lineWidth=e.lineWidth||80,this.noRefs=e.noRefs||!1,this.noCompatMode=e.noCompatMode||!1,this.implicitTypes=this.schema.compiledImplicit,this.explicitTypes=this.schema.compiledExplicit,this.tag=null,this.result="",this.duplicates=[],this.usedDuplicates=null}function o(e,t){for(var n,r=C.repeat(" ",t),i=0,a=-1,o="",s=e.length;i<s;)a=e.indexOf("\n",i),a===-1?(n=e.slice(i),i=s):(n=e.slice(i,a+1),i=a+1),n.length&&"\n"!==n&&(o+=r),o+=n;return o}function s(e,t){return"\n"+C.repeat(" ",e.indent*t)}function l(e,t){var n,r,i;for(n=0,r=e.implicitTypes.length;n<r;n+=1)if(i=e.implicitTypes[n],i.resolve(t))return!0;return!1}function u(e){return e===q||e===U}function c(e){return 32<=e&&e<=126||161<=e&&e<=55295&&8232!==e&&8233!==e||57344<=e&&e<=65533&&65279!==e||65536<=e&&e<=1114111}function p(e){return c(e)&&65279!==e&&e!==Y&&e!==X&&e!==Z&&e!==te&&e!==re&&e!==W&&e!==z}function h(e){return c(e)&&65279!==e&&!u(e)&&e!==J&&e!==G&&e!==W&&e!==Y&&e!==X&&e!==Z&&e!==te&&e!==re&&e!==z&&e!==F&&e!==H&&e!==B&&e!==ne&&e!==Q&&e!==V&&e!==N&&e!==$&&e!==K&&e!==ee}function f(e,t,n,r,i){var a,o,s=!1,l=!1,f=r!==-1,d=-1,m=h(e.charCodeAt(0))&&!u(e.charCodeAt(e.length-1));if(t)for(a=0;a<e.length;a++){if(o=e.charCodeAt(a),!c(o))return ce;m=m&&p(o)}else{for(a=0;a<e.length;a++){if(o=e.charCodeAt(a),o===P)s=!0,f&&(l=l||a-d-1>r&&" "!==e[d+1],d=a);else if(!c(o))return ce;m=m&&p(o)}l=l||f&&a-d-1>r&&" "!==e[d+1]}return s||l?" "===e[0]&&n>9?ce:l?ue:le:m&&!i(e)?oe:se}function d(e,t,n,r){e.dump=function(){function i(t){return l(e,t)}if(0===t.length)return"''";if(!e.noCompatMode&&ae.indexOf(t)!==-1)return"'"+t+"'";var a=e.indent*Math.max(1,n),s=e.lineWidth===-1?-1:Math.max(Math.min(e.lineWidth,40),e.lineWidth-a),u=r||e.flowLevel>-1&&n>=e.flowLevel;switch(f(t,u,e.indent,s,i)){case oe:return t;case se:return"'"+t.replace(/'/g,"''")+"'";case le:return"|"+m(t,e.indent)+g(o(t,a));case ue:return">"+m(t,e.indent)+g(o(y(t,s),a));case ce:return'"'+b(t,s)+'"';default:throw new I("impossible error: invalid scalar style")}}()}function m(e,t){var n=" "===e[0]?String(t):"",r="\n"===e[e.length-1],i=r&&("\n"===e[e.length-2]||"\n"===e),a=i?"+":r?"":"-";return n+a+"\n"}function g(e){return"\n"===e[e.length-1]?e.slice(0,-1):e}function y(e,t){for(var n,r,i=/(\n+)([^\n]*)/g,a=function(){var n=e.indexOf("\n");return n=n!==-1?n:e.length,i.lastIndex=n,v(e.slice(0,n),t)}(),o="\n"===e[0]||" "===e[0];r=i.exec(e);){var s=r[1],l=r[2];n=" "===l[0],a+=s+(o||n||""===l?"":"\n")+v(l,t),o=n}return a}function v(e,t){if(""===e||" "===e[0])return e;for(var n,r,i=/ [^ ]/g,a=0,o=0,s=0,l="";n=i.exec(e);)s=n.index,s-a>t&&(r=o>a?o:s,l+="\n"+e.slice(a,r),a=r+1),o=s;return l+="\n",l+=e.length-a>t&&o>a?e.slice(a,o)+"\n"+e.slice(o+1):e.slice(a),l.slice(1)}function b(e){for(var t,n,r="",a=0;a<e.length;a++)t=e.charCodeAt(a),n=ie[t],r+=!n&&c(t)?e[a]:n||i(t);return r}function w(e,t,n){var r,i,a="",o=e.tag;for(r=0,i=n.length;r<i;r+=1)j(e,t,n[r],!1,!1)&&(0!==r&&(a+=", "),a+=e.dump);e.tag=o,e.dump="["+a+"]"}function _(e,t,n,r){var i,a,o="",l=e.tag;for(i=0,a=n.length;i<a;i+=1)j(e,t+1,n[i],!0,!0)&&(r&&0===i||(o+=s(e,t)),o+="- "+e.dump);e.tag=l,e.dump=o||"[]"}function x(e,t,n){var r,i,a,o,s,l="",u=e.tag,c=Object.keys(n);for(r=0,i=c.length;r<i;r+=1)s="",0!==r&&(s+=", "),a=c[r],o=n[a],j(e,t,a,!1,!1)&&(e.dump.length>1024&&(s+="? "),s+=e.dump+": ",j(e,t,o,!1,!1)&&(s+=e.dump,l+=s));e.tag=u,e.dump="{"+l+"}"}function A(e,t,n,r){var i,a,o,l,u,c,p="",h=e.tag,f=Object.keys(n);if(e.sortKeys===!0)f.sort();else if("function"==typeof e.sortKeys)f.sort(e.sortKeys);else if(e.sortKeys)throw new I("sortKeys must be a boolean or a function");for(i=0,a=f.length;i<a;i+=1)c="",r&&0===i||(c+=s(e,t)),o=f[i],l=n[o],j(e,t+1,o,!0,!0,!0)&&(u=null!==e.tag&&"?"!==e.tag||e.dump&&e.dump.length>1024,u&&(c+=e.dump&&P===e.dump.charCodeAt(0)?"?":"? "),c+=e.dump,u&&(c+=s(e,t)),j(e,t+1,l,!0,u)&&(c+=e.dump&&P===e.dump.charCodeAt(0)?":":": ",c+=e.dump,p+=c));e.tag=h,e.dump=p||"{}"}function S(e,t,n){var r,i,a,o,s,l;for(i=n?e.explicitTypes:e.implicitTypes,a=0,o=i.length;a<o;a+=1)if(s=i[a],(s.instanceOf||s.predicate)&&(!s.instanceOf||"object"==typeof t&&t instanceof s.instanceOf)&&(!s.predicate||s.predicate(t))){if(e.tag=n?s.tag:"?",s.represent){if(l=e.styleMap[s.tag]||s.defaultStyle,"[object Function]"===M.call(s.represent))r=s.represent(t,l);else{if(!R.call(s.represent,l))throw new I("!<"+s.tag+'> tag resolver accepts not "'+l+'" style');r=s.represent[l](t,l)}e.dump=r}return!0}return!1}function j(e,t,n,r,i,a){e.tag=null,e.dump=n,S(e,n,!1)||S(e,n,!0);var o=M.call(e.dump);r&&(r=e.flowLevel<0||e.flowLevel>t);var s,l,u="[object Object]"===o||"[object Array]"===o;if(u&&(s=e.duplicates.indexOf(n),l=s!==-1),(null!==e.tag&&"?"!==e.tag||l||2!==e.indent&&t>0)&&(i=!1),l&&e.usedDuplicates[s])e.dump="*ref_"+s;else{if(u&&l&&!e.usedDuplicates[s]&&(e.usedDuplicates[s]=!0),"[object Object]"===o)r&&0!==Object.keys(e.dump).length?(A(e,t,e.dump,i),l&&(e.dump="&ref_"+s+e.dump)):(x(e,t,e.dump),l&&(e.dump="&ref_"+s+" "+e.dump));else if("[object Array]"===o)r&&0!==e.dump.length?(_(e,t,e.dump,i),l&&(e.dump="&ref_"+s+e.dump)):(w(e,t,e.dump),l&&(e.dump="&ref_"+s+" "+e.dump));else{if("[object String]"!==o){if(e.skipInvalid)return!1;throw new I("unacceptable kind of an object to dump "+o)}"?"!==e.tag&&d(e,e.dump,t,a)}null!==e.tag&&"?"!==e.tag&&(e.dump="!<"+e.tag+"> "+e.dump)}return!0}function E(e,t){var n,r,i=[],a=[];for(O(e,i,a),n=0,r=a.length;n<r;n+=1)t.duplicates.push(i[a[n]]);t.usedDuplicates=new Array(r)}function O(e,t,n){var r,i,a;if(null!==e&&"object"==typeof e)if(i=t.indexOf(e),i!==-1)n.indexOf(i)===-1&&n.push(i);else if(t.push(e),Array.isArray(e))for(i=0,a=e.length;i<a;i+=1)O(e[i],t,n);else for(r=Object.keys(e),i=0,a=r.length;i<a;i+=1)O(e[r[i]],t,n)}function k(e,t){t=t||{};var n=new a(t);return n.noRefs||E(e,n),j(n,0,e,!0,!0)?n.dump+"\n":""}function T(e,t){return k(e,C.extend({schema:L},t))}var C=e("./common"),I=e("./exception"),D=e("./schema/default_full"),L=e("./schema/default_safe"),M=Object.prototype.toString,R=Object.prototype.hasOwnProperty,U=9,P=10,q=32,B=33,N=34,z=35,$=37,F=38,V=39,H=42,Y=44,J=45,W=58,Q=62,G=63,K=64,X=91,Z=93,ee=96,te=123,ne=124,re=125,ie={};ie[0]="\\0",ie[7]="\\a",ie[8]="\\b",ie[9]="\\t",ie[10]="\\n",ie[11]="\\v",ie[12]="\\f",ie[13]="\\r",ie[27]="\\e",ie[34]='\\"',ie[92]="\\\\",ie[133]="\\N",ie[160]="\\_",ie[8232]="\\L",ie[8233]="\\P";var ae=["y","Y","yes","Yes","YES","on","On","ON","n","N","no","No","NO","off","Off","OFF"],oe=1,se=2,le=3,ue=4,ce=5;t.exports.dump=k,t.exports.safeDump=T},{"./common":21,"./exception":23,"./schema/default_full":28,"./schema/default_safe":29}],23:[function(e,t,n){"use strict";function r(e,t){Error.call(this),Error.captureStackTrace?Error.captureStackTrace(this,this.constructor):this.stack=(new Error).stack||"",this.name="YAMLException",this.reason=e,this.mark=t,this.message=(this.reason||"(unknown reason)")+(this.mark?" "+this.mark.toString():"")}r.prototype=Object.create(Error.prototype),r.prototype.constructor=r,r.prototype.toString=function(e){var t=this.name+": ";return t+=this.reason||"(unknown reason)",!e&&this.mark&&(t+=" "+this.mark.toString()),t},t.exports=r},{}],24:[function(e,t,n){"use strict";function r(e){return 10===e||13===e}function i(e){return 9===e||32===e}function a(e){return 9===e||32===e||10===e||13===e}function o(e){return 44===e||91===e||93===e||123===e||125===e}function s(e){var t;return 48<=e&&e<=57?e-48:(t=32|e,97<=t&&t<=102?t-97+10:-1)}function l(e){return 120===e?2:117===e?4:85===e?8:0}function u(e){return 48<=e&&e<=57?e-48:-1}function c(e){return 48===e?"\0":97===e?"":98===e?"\b":116===e?"\t":9===e?"\t":110===e?"\n":118===e?"\x0B":102===e?"\f":114===e?"\r":101===e?"":32===e?" ":34===e?'"':47===e?"/":92===e?"\\":78===e?"…":95===e?" ":76===e?"\u2028":80===e?"\u2029":""}function p(e){return e<=65535?String.fromCharCode(e):String.fromCharCode((e-65536>>10)+55296,(e-65536&1023)+56320)}function h(e,t){this.input=e,this.filename=t.filename||null,this.schema=t.schema||V,this.onWarning=t.onWarning||null,this.legacy=t.legacy||!1,this.json=t.json||!1,this.listener=t.listener||null,this.implicitTypes=this.schema.compiledImplicit,this.typeMap=this.schema.compiledTypeMap,this.length=e.length,this.position=0,this.line=0,this.lineStart=0,this.lineIndent=0,this.documents=[]}function f(e,t){return new z(t,new $(e.filename,e.input,e.position,e.line,e.position-e.lineStart))}function d(e,t){throw f(e,t)}function m(e,t){e.onWarning&&e.onWarning.call(null,f(e,t))}function g(e,t,n,r){var i,a,o,s;if(t<n){if(s=e.input.slice(t,n),r)for(i=0,a=s.length;i<a;i+=1)o=s.charCodeAt(i),9===o||32<=o&&o<=1114111||d(e,"expected valid JSON character");else Z.test(s)&&d(e,"the stream contains non-printable characters");e.result+=s}}function y(e,t,n,r){var i,a,o,s;for(N.isObject(n)||d(e,"cannot merge mappings; the provided source object is unacceptable"),i=Object.keys(n),o=0,s=i.length;o<s;o+=1)a=i[o],H.call(t,a)||(t[a]=n[a],r[a]=!0)}function v(e,t,n,r,i,a){var o,s;if(i=String(i),null===t&&(t={}),"tag:yaml.org,2002:merge"===r)if(Array.isArray(a))for(o=0,s=a.length;o<s;o+=1)y(e,t,a[o],n);else y(e,t,a,n);else e.json||H.call(n,i)||!H.call(t,i)||d(e,"duplicated mapping key"),t[i]=a,delete n[i];return t}function b(e){var t;t=e.input.charCodeAt(e.position),10===t?e.position++:13===t?(e.position++,10===e.input.charCodeAt(e.position)&&e.position++):d(e,"a line break is expected"),e.line+=1,e.lineStart=e.position}function w(e,t,n){for(var a=0,o=e.input.charCodeAt(e.position);0!==o;){for(;i(o);)o=e.input.charCodeAt(++e.position);if(t&&35===o)do o=e.input.charCodeAt(++e.position);while(10!==o&&13!==o&&0!==o);if(!r(o))break;for(b(e),o=e.input.charCodeAt(e.position),a++,e.lineIndent=0;32===o;)e.lineIndent++,o=e.input.charCodeAt(++e.position)}return n!==-1&&0!==a&&e.lineIndent<n&&m(e,"deficient indentation"),a}function _(e){var t,n=e.position;return t=e.input.charCodeAt(n),!(45!==t&&46!==t||t!==e.input.charCodeAt(n+1)||t!==e.input.charCodeAt(n+2)||(n+=3,t=e.input.charCodeAt(n),0!==t&&!a(t)))}function x(e,t){1===t?e.result+=" ":t>1&&(e.result+=N.repeat("\n",t-1))}function A(e,t,n){var s,l,u,c,p,h,f,d,m,y=e.kind,v=e.result;if(m=e.input.charCodeAt(e.position),a(m)||o(m)||35===m||38===m||42===m||33===m||124===m||62===m||39===m||34===m||37===m||64===m||96===m)return!1;if((63===m||45===m)&&(l=e.input.charCodeAt(e.position+1),a(l)||n&&o(l)))return!1;for(e.kind="scalar",e.result="",u=c=e.position,p=!1;0!==m;){if(58===m){if(l=e.input.charCodeAt(e.position+1),a(l)||n&&o(l))break}else if(35===m){if(s=e.input.charCodeAt(e.position-1),a(s))break}else{if(e.position===e.lineStart&&_(e)||n&&o(m))break;if(r(m)){if(h=e.line,f=e.lineStart,d=e.lineIndent,w(e,!1,-1),e.lineIndent>=t){p=!0,m=e.input.charCodeAt(e.position);continue}e.position=c,e.line=h,e.lineStart=f,e.lineIndent=d;break}}p&&(g(e,u,c,!1),x(e,e.line-h),u=c=e.position,p=!1),i(m)||(c=e.position+1),m=e.input.charCodeAt(++e.position)}return g(e,u,c,!1),!!e.result||(e.kind=y,e.result=v,!1)}function S(e,t){var n,i,a;if(n=e.input.charCodeAt(e.position),39!==n)return!1;for(e.kind="scalar",e.result="",e.position++,i=a=e.position;0!==(n=e.input.charCodeAt(e.position));)if(39===n){if(g(e,i,e.position,!0),n=e.input.charCodeAt(++e.position),39!==n)return!0;i=a=e.position,e.position++}else r(n)?(g(e,i,a,!0),x(e,w(e,!1,t)),i=a=e.position):e.position===e.lineStart&&_(e)?d(e,"unexpected end of the document within a single quoted scalar"):(e.position++,a=e.position);d(e,"unexpected end of the stream within a single quoted scalar")}function j(e,t){var n,i,a,o,u,c;if(c=e.input.charCodeAt(e.position),34!==c)return!1;for(e.kind="scalar",e.result="",e.position++,n=i=e.position;0!==(c=e.input.charCodeAt(e.position));){if(34===c)return g(e,n,e.position,!0),e.position++,!0;if(92===c){if(g(e,n,e.position,!0),c=e.input.charCodeAt(++e.position),r(c))w(e,!1,t);else if(c<256&&ie[c])e.result+=ae[c],e.position++;else if((u=l(c))>0){for(a=u,o=0;a>0;a--)c=e.input.charCodeAt(++e.position),(u=s(c))>=0?o=(o<<4)+u:d(e,"expected hexadecimal character");e.result+=p(o),e.position++}else d(e,"unknown escape sequence");n=i=e.position}else r(c)?(g(e,n,i,!0),x(e,w(e,!1,t)),n=i=e.position):e.position===e.lineStart&&_(e)?d(e,"unexpected end of the document within a double quoted scalar"):(e.position++,i=e.position)}d(e,"unexpected end of the stream within a double quoted scalar")}function E(e,t){var n,r,i,o,s,l,u,c,p,h,f,m=!0,g=e.tag,y=e.anchor,b={};if(f=e.input.charCodeAt(e.position),91===f)o=93,u=!1,r=[];else{if(123!==f)return!1;o=125,u=!0,r={}}for(null!==e.anchor&&(e.anchorMap[e.anchor]=r),f=e.input.charCodeAt(++e.position);0!==f;){if(w(e,!0,t),f=e.input.charCodeAt(e.position),f===o)return e.position++,e.tag=g,e.anchor=y,e.kind=u?"mapping":"sequence",e.result=r,!0;m||d(e,"missed comma between flow collection entries"),p=c=h=null,s=l=!1,63===f&&(i=e.input.charCodeAt(e.position+1),a(i)&&(s=l=!0,e.position++,w(e,!0,t))),n=e.line,L(e,t,Y,!1,!0),p=e.tag,c=e.result,w(e,!0,t),f=e.input.charCodeAt(e.position),!l&&e.line!==n||58!==f||(s=!0,f=e.input.charCodeAt(++e.position),w(e,!0,t),L(e,t,Y,!1,!0),h=e.result),u?v(e,r,b,p,c,h):s?r.push(v(e,null,b,p,c,h)):r.push(c),w(e,!0,t),f=e.input.charCodeAt(e.position),44===f?(m=!0,f=e.input.charCodeAt(++e.position)):m=!1}d(e,"unexpected end of the stream within a flow collection")}function O(e,t){var n,a,o,s,l=G,c=!1,p=!1,h=t,f=0,m=!1;if(s=e.input.charCodeAt(e.position),124===s)a=!1;else{if(62!==s)return!1;a=!0}for(e.kind="scalar",e.result="";0!==s;)if(s=e.input.charCodeAt(++e.position),43===s||45===s)G===l?l=43===s?X:K:d(e,"repeat of a chomping mode identifier");else{if(!((o=u(s))>=0))break;0===o?d(e,"bad explicit indentation width of a block scalar; it cannot be less than one"):p?d(e,"repeat of an indentation width identifier"):(h=t+o-1,p=!0)}if(i(s)){do s=e.input.charCodeAt(++e.position);while(i(s));if(35===s)do s=e.input.charCodeAt(++e.position);while(!r(s)&&0!==s)}for(;0!==s;){for(b(e),e.lineIndent=0,s=e.input.charCodeAt(e.position);(!p||e.lineIndent<h)&&32===s;)e.lineIndent++,s=e.input.charCodeAt(++e.position);if(!p&&e.lineIndent>h&&(h=e.lineIndent),r(s))f++;else{if(e.lineIndent<h){l===X?e.result+=N.repeat("\n",c?1+f:f):l===G&&c&&(e.result+="\n");break}for(a?i(s)?(m=!0,e.result+=N.repeat("\n",c?1+f:f)):m?(m=!1,e.result+=N.repeat("\n",f+1)):0===f?c&&(e.result+=" "):e.result+=N.repeat("\n",f):e.result+=N.repeat("\n",c?1+f:f),c=!0,p=!0,f=0,n=e.position;!r(s)&&0!==s;)s=e.input.charCodeAt(++e.position);g(e,n,e.position,!1)}}return!0}function k(e,t){var n,r,i,o=e.tag,s=e.anchor,l=[],u=!1;for(null!==e.anchor&&(e.anchorMap[e.anchor]=l),i=e.input.charCodeAt(e.position);0!==i&&45===i&&(r=e.input.charCodeAt(e.position+1),a(r));)if(u=!0,e.position++,w(e,!0,-1)&&e.lineIndent<=t)l.push(null),i=e.input.charCodeAt(e.position);else if(n=e.line,L(e,t,W,!1,!0),l.push(e.result),w(e,!0,-1),i=e.input.charCodeAt(e.position),(e.line===n||e.lineIndent>t)&&0!==i)d(e,"bad indentation of a sequence entry");else if(e.lineIndent<t)break;return!!u&&(e.tag=o,e.anchor=s,e.kind="sequence",e.result=l,!0)}function T(e,t,n){var r,o,s,l,u=e.tag,c=e.anchor,p={},h={},f=null,m=null,g=null,y=!1,b=!1;for(null!==e.anchor&&(e.anchorMap[e.anchor]=p),l=e.input.charCodeAt(e.position);0!==l;){if(r=e.input.charCodeAt(e.position+1),s=e.line,63!==l&&58!==l||!a(r)){if(!L(e,n,J,!1,!0))break;if(e.line===s){for(l=e.input.charCodeAt(e.position);i(l);)l=e.input.charCodeAt(++e.position);if(58===l)l=e.input.charCodeAt(++e.position),a(l)||d(e,"a whitespace character is expected after the key-value separator within a block mapping"),y&&(v(e,p,h,f,m,null),f=m=g=null),b=!0,y=!1,o=!1,f=e.tag,m=e.result;else{if(!b)return e.tag=u,e.anchor=c,!0;d(e,"can not read an implicit mapping pair; a colon is missed")}}else{if(!b)return e.tag=u,e.anchor=c,!0;d(e,"can not read a block mapping entry; a multiline key may not be an implicit key")}}else 63===l?(y&&(v(e,p,h,f,m,null),f=m=g=null),b=!0,y=!0,o=!0):y?(y=!1,o=!0):d(e,"incomplete explicit mapping pair; a key node is missed"),e.position+=1,l=r;if((e.line===s||e.lineIndent>t)&&(L(e,t,Q,!0,o)&&(y?m=e.result:g=e.result),y||(v(e,p,h,f,m,g),f=m=g=null),w(e,!0,-1),l=e.input.charCodeAt(e.position)),e.lineIndent>t&&0!==l)d(e,"bad indentation of a mapping entry");else if(e.lineIndent<t)break}return y&&v(e,p,h,f,m,null),b&&(e.tag=u,e.anchor=c,e.kind="mapping",e.result=p),b}function C(e){var t,n,r,i,o=!1,s=!1;if(i=e.input.charCodeAt(e.position),33!==i)return!1;if(null!==e.tag&&d(e,"duplication of a tag property"),i=e.input.charCodeAt(++e.position),60===i?(o=!0,i=e.input.charCodeAt(++e.position)):33===i?(s=!0,n="!!",i=e.input.charCodeAt(++e.position)):n="!",t=e.position,o){do i=e.input.charCodeAt(++e.position);while(0!==i&&62!==i);e.position<e.length?(r=e.input.slice(t,e.position),i=e.input.charCodeAt(++e.position)):d(e,"unexpected end of the stream within a verbatim tag")}else{for(;0!==i&&!a(i);)33===i&&(s?d(e,"tag suffix cannot contain exclamation marks"):(n=e.input.slice(t-1,e.position+1),ne.test(n)||d(e,"named tag handle cannot contain such characters"),s=!0,t=e.position+1)),i=e.input.charCodeAt(++e.position);r=e.input.slice(t,e.position),te.test(r)&&d(e,"tag suffix cannot contain flow indicator characters")}return r&&!re.test(r)&&d(e,"tag name cannot contain such characters: "+r),o?e.tag=r:H.call(e.tagMap,n)?e.tag=e.tagMap[n]+r:"!"===n?e.tag="!"+r:"!!"===n?e.tag="tag:yaml.org,2002:"+r:d(e,'undeclared tag handle "'+n+'"'),!0}function I(e){var t,n;if(n=e.input.charCodeAt(e.position),38!==n)return!1;for(null!==e.anchor&&d(e,"duplication of an anchor property"),n=e.input.charCodeAt(++e.position),t=e.position;0!==n&&!a(n)&&!o(n);)n=e.input.charCodeAt(++e.position);return e.position===t&&d(e,"name of an anchor node must contain at least one character"),e.anchor=e.input.slice(t,e.position),!0}function D(e){var t,n,r;if(r=e.input.charCodeAt(e.position),42!==r)return!1;for(r=e.input.charCodeAt(++e.position),t=e.position;0!==r&&!a(r)&&!o(r);)r=e.input.charCodeAt(++e.position);return e.position===t&&d(e,"name of an alias node must contain at least one character"),n=e.input.slice(t,e.position),e.anchorMap.hasOwnProperty(n)||d(e,'unidentified alias "'+n+'"'),e.result=e.anchorMap[n],w(e,!0,-1),!0}function L(e,t,n,r,i){var a,o,s,l,u,c,p,h,f=1,m=!1,g=!1;if(null!==e.listener&&e.listener("open",e),e.tag=null,e.anchor=null,e.kind=null,e.result=null,a=o=s=Q===n||W===n,r&&w(e,!0,-1)&&(m=!0,e.lineIndent>t?f=1:e.lineIndent===t?f=0:e.lineIndent<t&&(f=-1)),1===f)for(;C(e)||I(e);)w(e,!0,-1)?(m=!0,s=a,e.lineIndent>t?f=1:e.lineIndent===t?f=0:e.lineIndent<t&&(f=-1)):s=!1;if(s&&(s=m||i),1!==f&&Q!==n||(p=Y===n||J===n?t:t+1,h=e.position-e.lineStart,1===f?s&&(k(e,h)||T(e,h,p))||E(e,p)?g=!0:(o&&O(e,p)||S(e,p)||j(e,p)?g=!0:D(e)?(g=!0,null===e.tag&&null===e.anchor||d(e,"alias node should not have any properties")):A(e,p,Y===n)&&(g=!0,null===e.tag&&(e.tag="?")),null!==e.anchor&&(e.anchorMap[e.anchor]=e.result)):0===f&&(g=s&&k(e,h))),null!==e.tag&&"!"!==e.tag)if("?"===e.tag){for(l=0,u=e.implicitTypes.length;l<u;l+=1)if(c=e.implicitTypes[l],c.resolve(e.result)){e.result=c.construct(e.result),e.tag=c.tag,null!==e.anchor&&(e.anchorMap[e.anchor]=e.result);break}}else H.call(e.typeMap,e.tag)?(c=e.typeMap[e.tag],null!==e.result&&c.kind!==e.kind&&d(e,"unacceptable node kind for !<"+e.tag+'> tag; it should be "'+c.kind+'", not "'+e.kind+'"'),c.resolve(e.result)?(e.result=c.construct(e.result),null!==e.anchor&&(e.anchorMap[e.anchor]=e.result)):d(e,"cannot resolve a node with !<"+e.tag+"> explicit tag")):d(e,"unknown tag !<"+e.tag+">");return null!==e.listener&&e.listener("close",e),null!==e.tag||null!==e.anchor||g}function M(e){var t,n,o,s,l=e.position,u=!1;for(e.version=null,e.checkLineBreaks=e.legacy,e.tagMap={},e.anchorMap={};0!==(s=e.input.charCodeAt(e.position))&&(w(e,!0,-1),s=e.input.charCodeAt(e.position),!(e.lineIndent>0||37!==s));){for(u=!0,s=e.input.charCodeAt(++e.position),t=e.position;0!==s&&!a(s);)s=e.input.charCodeAt(++e.position);for(n=e.input.slice(t,e.position),o=[],n.length<1&&d(e,"directive name must not be less than one character in length");0!==s;){for(;i(s);)s=e.input.charCodeAt(++e.position);if(35===s){do s=e.input.charCodeAt(++e.position);while(0!==s&&!r(s));break}if(r(s))break;for(t=e.position;0!==s&&!a(s);)s=e.input.charCodeAt(++e.position);o.push(e.input.slice(t,e.position))}0!==s&&b(e),H.call(se,n)?se[n](e,n,o):m(e,'unknown document directive "'+n+'"')}return w(e,!0,-1),0===e.lineIndent&&45===e.input.charCodeAt(e.position)&&45===e.input.charCodeAt(e.position+1)&&45===e.input.charCodeAt(e.position+2)?(e.position+=3,w(e,!0,-1)):u&&d(e,"directives end mark is expected"),L(e,e.lineIndent-1,Q,!1,!0),w(e,!0,-1),e.checkLineBreaks&&ee.test(e.input.slice(l,e.position))&&m(e,"non-ASCII line breaks are interpreted as content"),e.documents.push(e.result),e.position===e.lineStart&&_(e)?void(46===e.input.charCodeAt(e.position)&&(e.position+=3,w(e,!0,-1))):void(e.position<e.length-1&&d(e,"end of the stream or a document separator is expected"))}function R(e,t){e=String(e),t=t||{},0!==e.length&&(10!==e.charCodeAt(e.length-1)&&13!==e.charCodeAt(e.length-1)&&(e+="\n"),65279===e.charCodeAt(0)&&(e=e.slice(1)));var n=new h(e,t);for(n.input+="\0";32===n.input.charCodeAt(n.position);)n.lineIndent+=1,n.position+=1;for(;n.position<n.length-1;)M(n);return n.documents}function U(e,t,n){var r,i,a=R(e,n);for(r=0,i=a.length;r<i;r+=1)t(a[r])}function P(e,t){var n=R(e,t);if(0!==n.length){if(1===n.length)return n[0];throw new z("expected a single document in the stream, but found more")}}function q(e,t,n){U(e,t,N.extend({schema:F},n))}function B(e,t){return P(e,N.extend({schema:F},t))}for(var N=e("./common"),z=e("./exception"),$=e("./mark"),F=e("./schema/default_safe"),V=e("./schema/default_full"),H=Object.prototype.hasOwnProperty,Y=1,J=2,W=3,Q=4,G=1,K=2,X=3,Z=/[\x00-\x08\x0B\x0C\x0E-\x1F\x7F-\x84\x86-\x9F\uFFFE\uFFFF]|[\uD800-\uDBFF](?![\uDC00-\uDFFF])|(?:[^\uD800-\uDBFF]|^)[\uDC00-\uDFFF]/,ee=/[\x85\u2028\u2029]/,te=/[,\[\]\{\}]/,ne=/^(?:!|!!|![a-z\-]+!)$/i,re=/^(?:!|[^,\[\]\{\}])(?:%[0-9a-f]{2}|[0-9a-z\-#;\/\?:@&=\+\$,_\.!~\*'\(\)\[\]])*$/i,ie=new Array(256),ae=new Array(256),oe=0;oe<256;oe++)ie[oe]=c(oe)?1:0,ae[oe]=c(oe);var se={YAML:function(e,t,n){var r,i,a;null!==e.version&&d(e,"duplication of %YAML directive"),1!==n.length&&d(e,"YAML directive accepts exactly one argument"),r=/^([0-9]+)\.([0-9]+)$/.exec(n[0]),null===r&&d(e,"ill-formed argument of the YAML directive"),i=parseInt(r[1],10),a=parseInt(r[2],10),1!==i&&d(e,"unacceptable YAML version of the document"),e.version=n[0],e.checkLineBreaks=a<2,1!==a&&2!==a&&m(e,"unsupported YAML version of the document")},TAG:function(e,t,n){var r,i;2!==n.length&&d(e,"TAG directive accepts exactly two arguments"),r=n[0],i=n[1],ne.test(r)||d(e,"ill-formed tag handle (first argument) of the TAG directive"),H.call(e.tagMap,r)&&d(e,'there is a previously declared suffix for "'+r+'" tag handle'),re.test(i)||d(e,"ill-formed tag prefix (second argument) of the TAG directive"),e.tagMap[r]=i}};t.exports.loadAll=U,t.exports.load=P,t.exports.safeLoadAll=q,t.exports.safeLoad=B},{"./common":21,"./exception":23,"./mark":25,"./schema/default_full":28,"./schema/default_safe":29}],25:[function(e,t,n){"use strict";function r(e,t,n,r,i){this.name=e,this.buffer=t,this.position=n,this.line=r,this.column=i}var i=e("./common");r.prototype.getSnippet=function(e,t){var n,r,a,o,s;if(!this.buffer)return null;for(e=e||4,t=t||75,n="",r=this.position;r>0&&"\0\r\n…\u2028\u2029".indexOf(this.buffer.charAt(r-1))===-1;)if(r-=1,this.position-r>t/2-1){n=" ... ",r+=5;break}for(a="",o=this.position;o<this.buffer.length&&"\0\r\n…\u2028\u2029".indexOf(this.buffer.charAt(o))===-1;)if(o+=1,o-this.position>t/2-1){a=" ... ",o-=5;break}return s=this.buffer.slice(r,o),i.repeat(" ",e)+n+s+a+"\n"+i.repeat(" ",e+this.position-r+n.length)+"^"},r.prototype.toString=function(e){var t,n="";return this.name&&(n+='in "'+this.name+'" '),n+="at line "+(this.line+1)+", column "+(this.column+1),e||(t=this.getSnippet(),t&&(n+=":\n"+t)),n},t.exports=r},{"./common":21}],26:[function(e,t,n){"use strict";function r(e,t,n){var i=[];return e.include.forEach(function(e){n=r(e,t,n)}),e[t].forEach(function(e){n.forEach(function(t,n){t.tag===e.tag&&i.push(n)}),n.push(e)}),n.filter(function(e,t){return i.indexOf(t)===-1})}function i(){function e(e){r[e.tag]=e}var t,n,r={};for(t=0,n=arguments.length;t<n;t+=1)arguments[t].forEach(e);return r}function a(e){this.include=e.include||[],this.implicit=e.implicit||[],this.explicit=e.explicit||[],this.implicit.forEach(function(e){if(e.loadKind&&"scalar"!==e.loadKind)throw new s("There is a non-scalar type in the implicit list of a schema. Implicit resolving of such types is not supported.")}),this.compiledImplicit=r(this,"implicit",[]),this.compiledExplicit=r(this,"explicit",[]),this.compiledTypeMap=i(this.compiledImplicit,this.compiledExplicit)}var o=e("./common"),s=e("./exception"),l=e("./type");a.DEFAULT=null,a.create=function(){var e,t;switch(arguments.length){case 1:e=a.DEFAULT,t=arguments[0];break;case 2:e=arguments[0],t=arguments[1];break;default:throw new s("Wrong number of arguments for Schema.create function")}if(e=o.toArray(e),t=o.toArray(t),!e.every(function(e){return e instanceof a}))throw new s("Specified list of super schemas (or a single Schema object) contains a non-Schema object.");if(!t.every(function(e){return e instanceof l}))throw new s("Specified list of YAML types (or a single Type object) contains a non-Type object.");return new a({include:e,explicit:t})},t.exports=a},{"./common":21,"./exception":23,"./type":32}],27:[function(e,t,n){"use strict";var r=e("../schema");t.exports=new r({include:[e("./json")]})},{"../schema":26,"./json":31}],28:[function(e,t,n){"use strict";var r=e("../schema");t.exports=r.DEFAULT=new r({include:[e("./default_safe")],explicit:[e("../type/js/undefined"),e("../type/js/regexp"),e("../type/js/function")]})},{"../schema":26,"../type/js/function":37,"../type/js/regexp":38,"../type/js/undefined":39,"./default_safe":29}],29:[function(e,t,n){"use strict";var r=e("../schema");t.exports=new r({include:[e("./core")],implicit:[e("../type/timestamp"),e("../type/merge")],explicit:[e("../type/binary"),e("../type/omap"),e("../type/pairs"),e("../type/set")]})},{"../schema":26,"../type/binary":33,"../type/merge":41,"../type/omap":43,"../type/pairs":44,"../type/set":46,"../type/timestamp":48,"./core":27}],30:[function(e,t,n){"use strict";var r=e("../schema");t.exports=new r({explicit:[e("../type/str"),e("../type/seq"),e("../type/map")]})},{"../schema":26,"../type/map":40,"../type/seq":45,"../type/str":47}],31:[function(e,t,n){"use strict";var r=e("../schema");t.exports=new r({include:[e("./failsafe")],implicit:[e("../type/null"),e("../type/bool"),e("../type/int"),e("../type/float")]})},{"../schema":26,"../type/bool":34,"../type/float":35,"../type/int":36,"../type/null":42,"./failsafe":30}],32:[function(e,t,n){"use strict";function r(e){var t={};return null!==e&&Object.keys(e).forEach(function(n){e[n].forEach(function(e){t[String(e)]=n})}),t}function i(e,t){if(t=t||{},Object.keys(t).forEach(function(t){if(o.indexOf(t)===-1)throw new a('Unknown option "'+t+'" is met in definition of "'+e+'" YAML type.')}),this.tag=e,this.kind=t.kind||null,this.resolve=t.resolve||function(){return!0},this.construct=t.construct||function(e){return e},this.instanceOf=t.instanceOf||null,this.predicate=t.predicate||null,this.represent=t.represent||null,this.defaultStyle=t.defaultStyle||null,this.styleAliases=r(t.styleAliases||null),s.indexOf(this.kind)===-1)throw new a('Unknown kind "'+this.kind+'" is specified for "'+e+'" YAML type.')}var a=e("./exception"),o=["kind","resolve","construct","instanceOf","predicate","represent","defaultStyle","styleAliases"],s=["scalar","sequence","mapping"];t.exports=i},{"./exception":23}],33:[function(e,t,n){"use strict";function r(e){if(null===e)return!1;var t,n,r=0,i=e.length,a=p;for(n=0;n<i;n++)if(t=a.indexOf(e.charAt(n)),!(t>64)){if(t<0)return!1;r+=6}return r%8===0}function i(e){var t,n,r=e.replace(/[\r\n=]/g,""),i=r.length,a=p,o=0,l=[];for(t=0;t<i;t++)t%4===0&&t&&(l.push(o>>16&255),l.push(o>>8&255),l.push(255&o)),o=o<<6|a.indexOf(r.charAt(t));return n=i%4*6,0===n?(l.push(o>>16&255),l.push(o>>8&255),l.push(255&o)):18===n?(l.push(o>>10&255),l.push(o>>2&255)):12===n&&l.push(o>>4&255),s?new s(l):l}function a(e){var t,n,r="",i=0,a=e.length,o=p;for(t=0;t<a;t++)t%3===0&&t&&(r+=o[i>>18&63],r+=o[i>>12&63],r+=o[i>>6&63],r+=o[63&i]),i=(i<<8)+e[t];return n=a%3,0===n?(r+=o[i>>18&63],r+=o[i>>12&63],r+=o[i>>6&63],r+=o[63&i]):2===n?(r+=o[i>>10&63],r+=o[i>>4&63],r+=o[i<<2&63],r+=o[64]):1===n&&(r+=o[i>>2&63],r+=o[i<<4&63],r+=o[64],r+=o[64]),r}function o(e){return s&&s.isBuffer(e)}var s;try{var l=e;s=l("buffer").Buffer}catch(u){}var c=e("../type"),p="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=\n\r";t.exports=new c("tag:yaml.org,2002:binary",{kind:"scalar",resolve:r,construct:i,predicate:o,represent:a})},{"../type":32}],34:[function(e,t,n){"use strict";function r(e){if(null===e)return!1;var t=e.length;return 4===t&&("true"===e||"True"===e||"TRUE"===e)||5===t&&("false"===e||"False"===e||"FALSE"===e)}function i(e){return"true"===e||"True"===e||"TRUE"===e}function a(e){return"[object Boolean]"===Object.prototype.toString.call(e)}var o=e("../type");t.exports=new o("tag:yaml.org,2002:bool",{kind:"scalar",resolve:r,construct:i,predicate:a,represent:{lowercase:function(e){return e?"true":"false"},uppercase:function(e){return e?"TRUE":"FALSE"},camelcase:function(e){return e?"True":"False"}},defaultStyle:"lowercase"})},{"../type":32}],35:[function(e,t,n){"use strict";function r(e){return null!==e&&!!u.test(e)}function i(e){var t,n,r,i;return t=e.replace(/_/g,"").toLowerCase(),n="-"===t[0]?-1:1,i=[],"+-".indexOf(t[0])>=0&&(t=t.slice(1)),".inf"===t?1===n?Number.POSITIVE_INFINITY:Number.NEGATIVE_INFINITY:".nan"===t?NaN:t.indexOf(":")>=0?(t.split(":").forEach(function(e){i.unshift(parseFloat(e,10))}),t=0,r=1,i.forEach(function(e){t+=e*r,r*=60}),n*t):n*parseFloat(t,10)}function a(e,t){var n;if(isNaN(e))switch(t){case"lowercase":return".nan";case"uppercase":return".NAN";case"camelcase":return".NaN"}else if(Number.POSITIVE_INFINITY===e)switch(t){case"lowercase":return".inf";case"uppercase":return".INF";case"camelcase":return".Inf"}else if(Number.NEGATIVE_INFINITY===e)switch(t){case"lowercase":return"-.inf";case"uppercase":return"-.INF";case"camelcase":return"-.Inf"}else if(s.isNegativeZero(e))return"-0.0";return n=e.toString(10),c.test(n)?n.replace("e",".e"):n}function o(e){return"[object Number]"===Object.prototype.toString.call(e)&&(e%1!==0||s.isNegativeZero(e))}var s=e("../common"),l=e("../type"),u=new RegExp("^(?:[-+]?(?:[0-9][0-9_]*)\\.[0-9_]*(?:[eE][-+][0-9]+)?|\\.[0-9_]+(?:[eE][-+][0-9]+)?|[-+]?[0-9][0-9_]*(?::[0-5]?[0-9])+\\.[0-9_]*|[-+]?\\.(?:inf|Inf|INF)|\\.(?:nan|NaN|NAN))$"),c=/^[-+]?[0-9]+e/;t.exports=new l("tag:yaml.org,2002:float",{kind:"scalar",resolve:r,construct:i,predicate:o,represent:a,defaultStyle:"lowercase"})},{"../common":21,"../type":32}],36:[function(e,t,n){"use strict";function r(e){return 48<=e&&e<=57||65<=e&&e<=70||97<=e&&e<=102}function i(e){return 48<=e&&e<=55}function a(e){return 48<=e&&e<=57}function o(e){if(null===e)return!1;var t,n=e.length,o=0,s=!1;if(!n)return!1;if(t=e[o],"-"!==t&&"+"!==t||(t=e[++o]),"0"===t){if(o+1===n)return!0;if(t=e[++o],"b"===t){for(o++;o<n;o++)if(t=e[o],"_"!==t){if("0"!==t&&"1"!==t)return!1;s=!0}return s}if("x"===t){for(o++;o<n;o++)if(t=e[o],"_"!==t){if(!r(e.charCodeAt(o)))return!1;s=!0}return s}for(;o<n;o++)if(t=e[o],"_"!==t){if(!i(e.charCodeAt(o)))return!1;s=!0}return s}for(;o<n;o++)if(t=e[o],"_"!==t){if(":"===t)break;if(!a(e.charCodeAt(o)))return!1;s=!0}return!!s&&(":"!==t||/^(:[0-5]?[0-9])+$/.test(e.slice(o)))}function s(e){var t,n,r=e,i=1,a=[];return r.indexOf("_")!==-1&&(r=r.replace(/_/g,"")),t=r[0],"-"!==t&&"+"!==t||("-"===t&&(i=-1),
+r=r.slice(1),t=r[0]),"0"===r?0:"0"===t?"b"===r[1]?i*parseInt(r.slice(2),2):"x"===r[1]?i*parseInt(r,16):i*parseInt(r,8):r.indexOf(":")!==-1?(r.split(":").forEach(function(e){a.unshift(parseInt(e,10))}),r=0,n=1,a.forEach(function(e){r+=e*n,n*=60}),i*r):i*parseInt(r,10)}function l(e){return"[object Number]"===Object.prototype.toString.call(e)&&e%1===0&&!u.isNegativeZero(e)}var u=e("../common"),c=e("../type");t.exports=new c("tag:yaml.org,2002:int",{kind:"scalar",resolve:o,construct:s,predicate:l,represent:{binary:function(e){return"0b"+e.toString(2)},octal:function(e){return"0"+e.toString(8)},decimal:function(e){return e.toString(10)},hexadecimal:function(e){return"0x"+e.toString(16).toUpperCase()}},defaultStyle:"decimal",styleAliases:{binary:[2,"bin"],octal:[8,"oct"],decimal:[10,"dec"],hexadecimal:[16,"hex"]}})},{"../common":21,"../type":32}],37:[function(e,t,n){"use strict";function r(e){if(null===e)return!1;try{var t="("+e+")",n=s.parse(t,{range:!0});return"Program"===n.type&&1===n.body.length&&"ExpressionStatement"===n.body[0].type&&"FunctionExpression"===n.body[0].expression.type}catch(r){return!1}}function i(e){var t,n="("+e+")",r=s.parse(n,{range:!0}),i=[];if("Program"!==r.type||1!==r.body.length||"ExpressionStatement"!==r.body[0].type||"FunctionExpression"!==r.body[0].expression.type)throw new Error("Failed to resolve function");return r.body[0].expression.params.forEach(function(e){i.push(e.name)}),t=r.body[0].expression.body.range,new Function(i,n.slice(t[0]+1,t[1]-1))}function a(e){return e.toString()}function o(e){return"[object Function]"===Object.prototype.toString.call(e)}var s;try{var l=e;s=l("esprima")}catch(u){"undefined"!=typeof window&&(s=window.esprima)}var c=e("../../type");t.exports=new c("tag:yaml.org,2002:js/function",{kind:"scalar",resolve:r,construct:i,predicate:o,represent:a})},{"../../type":32}],38:[function(e,t,n){"use strict";function r(e){if(null===e)return!1;if(0===e.length)return!1;var t=e,n=/\/([gim]*)$/.exec(e),r="";if("/"===t[0]){if(n&&(r=n[1]),r.length>3)return!1;if("/"!==t[t.length-r.length-1])return!1}return!0}function i(e){var t=e,n=/\/([gim]*)$/.exec(e),r="";return"/"===t[0]&&(n&&(r=n[1]),t=t.slice(1,t.length-r.length-1)),new RegExp(t,r)}function a(e){var t="/"+e.source+"/";return e.global&&(t+="g"),e.multiline&&(t+="m"),e.ignoreCase&&(t+="i"),t}function o(e){return"[object RegExp]"===Object.prototype.toString.call(e)}var s=e("../../type");t.exports=new s("tag:yaml.org,2002:js/regexp",{kind:"scalar",resolve:r,construct:i,predicate:o,represent:a})},{"../../type":32}],39:[function(e,t,n){"use strict";function r(){return!0}function i(){}function a(){return""}function o(e){return"undefined"==typeof e}var s=e("../../type");t.exports=new s("tag:yaml.org,2002:js/undefined",{kind:"scalar",resolve:r,construct:i,predicate:o,represent:a})},{"../../type":32}],40:[function(e,t,n){"use strict";var r=e("../type");t.exports=new r("tag:yaml.org,2002:map",{kind:"mapping",construct:function(e){return null!==e?e:{}}})},{"../type":32}],41:[function(e,t,n){"use strict";function r(e){return"<<"===e||null===e}var i=e("../type");t.exports=new i("tag:yaml.org,2002:merge",{kind:"scalar",resolve:r})},{"../type":32}],42:[function(e,t,n){"use strict";function r(e){if(null===e)return!0;var t=e.length;return 1===t&&"~"===e||4===t&&("null"===e||"Null"===e||"NULL"===e)}function i(){return null}function a(e){return null===e}var o=e("../type");t.exports=new o("tag:yaml.org,2002:null",{kind:"scalar",resolve:r,construct:i,predicate:a,represent:{canonical:function(){return"~"},lowercase:function(){return"null"},uppercase:function(){return"NULL"},camelcase:function(){return"Null"}},defaultStyle:"lowercase"})},{"../type":32}],43:[function(e,t,n){"use strict";function r(e){if(null===e)return!0;var t,n,r,i,a,l=[],u=e;for(t=0,n=u.length;t<n;t+=1){if(r=u[t],a=!1,"[object Object]"!==s.call(r))return!1;for(i in r)if(o.call(r,i)){if(a)return!1;a=!0}if(!a)return!1;if(l.indexOf(i)!==-1)return!1;l.push(i)}return!0}function i(e){return null!==e?e:[]}var a=e("../type"),o=Object.prototype.hasOwnProperty,s=Object.prototype.toString;t.exports=new a("tag:yaml.org,2002:omap",{kind:"sequence",resolve:r,construct:i})},{"../type":32}],44:[function(e,t,n){"use strict";function r(e){if(null===e)return!0;var t,n,r,i,a,s=e;for(a=new Array(s.length),t=0,n=s.length;t<n;t+=1){if(r=s[t],"[object Object]"!==o.call(r))return!1;if(i=Object.keys(r),1!==i.length)return!1;a[t]=[i[0],r[i[0]]]}return!0}function i(e){if(null===e)return[];var t,n,r,i,a,o=e;for(a=new Array(o.length),t=0,n=o.length;t<n;t+=1)r=o[t],i=Object.keys(r),a[t]=[i[0],r[i[0]]];return a}var a=e("../type"),o=Object.prototype.toString;t.exports=new a("tag:yaml.org,2002:pairs",{kind:"sequence",resolve:r,construct:i})},{"../type":32}],45:[function(e,t,n){"use strict";var r=e("../type");t.exports=new r("tag:yaml.org,2002:seq",{kind:"sequence",construct:function(e){return null!==e?e:[]}})},{"../type":32}],46:[function(e,t,n){"use strict";function r(e){if(null===e)return!0;var t,n=e;for(t in n)if(o.call(n,t)&&null!==n[t])return!1;return!0}function i(e){return null!==e?e:{}}var a=e("../type"),o=Object.prototype.hasOwnProperty;t.exports=new a("tag:yaml.org,2002:set",{kind:"mapping",resolve:r,construct:i})},{"../type":32}],47:[function(e,t,n){"use strict";var r=e("../type");t.exports=new r("tag:yaml.org,2002:str",{kind:"scalar",construct:function(e){return null!==e?e:""}})},{"../type":32}],48:[function(e,t,n){"use strict";function r(e){return null!==e&&(null!==s.exec(e)||null!==l.exec(e))}function i(e){var t,n,r,i,a,o,u,c,p,h,f=0,d=null;if(t=s.exec(e),null===t&&(t=l.exec(e)),null===t)throw new Error("Date resolve error");if(n=+t[1],r=+t[2]-1,i=+t[3],!t[4])return new Date(Date.UTC(n,r,i));if(a=+t[4],o=+t[5],u=+t[6],t[7]){for(f=t[7].slice(0,3);f.length<3;)f+="0";f=+f}return t[9]&&(c=+t[10],p=+(t[11]||0),d=6e4*(60*c+p),"-"===t[9]&&(d=-d)),h=new Date(Date.UTC(n,r,i,a,o,u,f)),d&&h.setTime(h.getTime()-d),h}function a(e){return e.toISOString()}var o=e("../type"),s=new RegExp("^([0-9][0-9][0-9][0-9])-([0-9][0-9])-([0-9][0-9])$"),l=new RegExp("^([0-9][0-9][0-9][0-9])-([0-9][0-9]?)-([0-9][0-9]?)(?:[Tt]|[ \\t]+)([0-9][0-9]?):([0-9][0-9]):([0-9][0-9])(?:\\.([0-9]*))?(?:[ \\t]*(Z|([-+])([0-9][0-9]?)(?::([0-9][0-9]))?))?$");t.exports=new o("tag:yaml.org,2002:timestamp",{kind:"scalar",resolve:r,construct:i,instanceOf:Date,represent:a})},{"../type":32}],49:[function(e,t,n){function r(e,t,n){var r=e?e.length:0;if(!r)return-1;if("number"==typeof n)n=n<0?o(r+n,0):n;else if(n){var s=a(e,t);return s<r&&(t===t?t===e[s]:e[s]!==e[s])?s:-1}return i(e,t,n||0)}var i=e("../internal/baseIndexOf"),a=e("../internal/binaryIndex"),o=Math.max;t.exports=r},{"../internal/baseIndexOf":78,"../internal/binaryIndex":92}],50:[function(e,t,n){function r(e){var t=e?e.length:0;return t?e[t-1]:void 0}t.exports=r},{}],51:[function(e,t,n){function r(e){if(l(e)&&!s(e)&&!(e instanceof i)){if(e instanceof a)return e;if(p.call(e,"__chain__")&&p.call(e,"__wrapped__"))return u(e)}return new a(e)}var i=e("../internal/LazyWrapper"),a=e("../internal/LodashWrapper"),o=e("../internal/baseLodash"),s=e("../lang/isArray"),l=e("../internal/isObjectLike"),u=e("../internal/wrapperClone"),c=Object.prototype,p=c.hasOwnProperty;r.prototype=o.prototype,t.exports=r},{"../internal/LazyWrapper":60,"../internal/LodashWrapper":61,"../internal/baseLodash":82,"../internal/isObjectLike":126,"../internal/wrapperClone":137,"../lang/isArray":140}],52:[function(e,t,n){t.exports=e("./forEach")},{"./forEach":54}],53:[function(e,t,n){var r=e("../internal/baseEach"),i=e("../internal/createFind"),a=i(r);t.exports=a},{"../internal/baseEach":71,"../internal/createFind":102}],54:[function(e,t,n){var r=e("../internal/arrayEach"),i=e("../internal/baseEach"),a=e("../internal/createForEach"),o=a(r,i);t.exports=o},{"../internal/arrayEach":63,"../internal/baseEach":71,"../internal/createForEach":103}],55:[function(e,t,n){function r(e,t,n,r){var h=e?a(e):0;return l(h)||(e=c(e),h=e.length),n="number"!=typeof n||r&&s(t,n,r)?0:n<0?p(h+n,0):n||0,"string"==typeof e||!o(e)&&u(e)?n<=h&&e.indexOf(t,n)>-1:!!h&&i(e,t,n)>-1}var i=e("../internal/baseIndexOf"),a=e("../internal/getLength"),o=e("../lang/isArray"),s=e("../internal/isIterateeCall"),l=e("../internal/isLength"),u=e("../lang/isString"),c=e("../object/values"),p=Math.max;t.exports=r},{"../internal/baseIndexOf":78,"../internal/getLength":112,"../internal/isIterateeCall":122,"../internal/isLength":125,"../lang/isArray":140,"../lang/isString":146,"../object/values":152}],56:[function(e,t,n){function r(e,t,n){var r=s(e)?i:o;return t=a(t,n,3),r(e,t)}var i=e("../internal/arrayMap"),a=e("../internal/baseCallback"),o=e("../internal/baseMap"),s=e("../lang/isArray");t.exports=r},{"../internal/arrayMap":64,"../internal/baseCallback":67,"../internal/baseMap":83,"../lang/isArray":140}],57:[function(e,t,n){var r=e("../internal/getNative"),i=r(Date,"now"),a=i||function(){return(new Date).getTime()};t.exports=a},{"../internal/getNative":114}],58:[function(e,t,n){var r=e("../internal/createWrapper"),i=e("../internal/replaceHolders"),a=e("./restParam"),o=1,s=32,l=a(function(e,t,n){var a=o;if(n.length){var u=i(n,l.placeholder);a|=s}return r(e,a,t,n,u)});l.placeholder={},t.exports=l},{"../internal/createWrapper":106,"../internal/replaceHolders":132,"./restParam":59}],59:[function(e,t,n){function r(e,t){if("function"!=typeof e)throw new TypeError(i);return t=a(void 0===t?e.length-1:+t||0,0),function(){for(var n=arguments,r=-1,i=a(n.length-t,0),o=Array(i);++r<i;)o[r]=n[t+r];switch(t){case 0:return e.call(this,o);case 1:return e.call(this,n[0],o);case 2:return e.call(this,n[0],n[1],o)}var s=Array(t+1);for(r=-1;++r<t;)s[r]=n[r];return s[t]=o,e.apply(this,s)}}var i="Expected a function",a=Math.max;t.exports=r},{}],60:[function(e,t,n){function r(e){this.__wrapped__=e,this.__actions__=[],this.__dir__=1,this.__filtered__=!1,this.__iteratees__=[],this.__takeCount__=o,this.__views__=[]}var i=e("./baseCreate"),a=e("./baseLodash"),o=Number.POSITIVE_INFINITY;r.prototype=i(a.prototype),r.prototype.constructor=r,t.exports=r},{"./baseCreate":70,"./baseLodash":82}],61:[function(e,t,n){function r(e,t,n){this.__wrapped__=e,this.__actions__=n||[],this.__chain__=!!t}var i=e("./baseCreate"),a=e("./baseLodash");r.prototype=i(a.prototype),r.prototype.constructor=r,t.exports=r},{"./baseCreate":70,"./baseLodash":82}],62:[function(e,t,n){function r(e,t){var n=-1,r=e.length;for(t||(t=Array(r));++n<r;)t[n]=e[n];return t}t.exports=r},{}],63:[function(e,t,n){function r(e,t){for(var n=-1,r=e.length;++n<r&&t(e[n],n,e)!==!1;);return e}t.exports=r},{}],64:[function(e,t,n){function r(e,t){for(var n=-1,r=e.length,i=Array(r);++n<r;)i[n]=t(e[n],n,e);return i}t.exports=r},{}],65:[function(e,t,n){function r(e,t){for(var n=-1,r=e.length;++n<r;)if(t(e[n],n,e))return!0;return!1}t.exports=r},{}],66:[function(e,t,n){function r(e,t){return null==t?e:i(t,a(t),e)}var i=e("./baseCopy"),a=e("../object/keys");t.exports=r},{"../object/keys":149,"./baseCopy":69}],67:[function(e,t,n){function r(e,t,n){var r=typeof e;return"function"==r?void 0===t?e:o(e,t,n):null==e?s:"object"==r?i(e):void 0===t?l(e):a(e,t)}var i=e("./baseMatches"),a=e("./baseMatchesProperty"),o=e("./bindCallback"),s=e("../utility/identity"),l=e("../utility/property");t.exports=r},{"../utility/identity":154,"../utility/property":156,"./baseMatches":84,"./baseMatchesProperty":85,"./bindCallback":94}],68:[function(e,t,n){function r(e,t,n,m,g,y,v){var w;if(n&&(w=g?n(e,m,g):n(e)),void 0!==w)return w;if(!f(e))return e;var _=p(e);if(_){if(w=l(e),!t)return i(e,w)}else{var A=B.call(e),S=A==b;if(A!=x&&A!=d&&(!S||g))return P[A]?u(e,A,t):g?e:{};if(h(e))return g?e:{};if(w=c(S?{}:e),!t)return o(w,e)}y||(y=[]),v||(v=[]);for(var j=y.length;j--;)if(y[j]==e)return v[j];return y.push(e),v.push(w),(_?a:s)(e,function(i,a){w[a]=r(i,t,n,a,e,y,v)}),w}var i=e("./arrayCopy"),a=e("./arrayEach"),o=e("./baseAssign"),s=e("./baseForOwn"),l=e("./initCloneArray"),u=e("./initCloneByTag"),c=e("./initCloneObject"),p=e("../lang/isArray"),h=e("./isHostObject"),f=e("../lang/isObject"),d="[object Arguments]",m="[object Array]",g="[object Boolean]",y="[object Date]",v="[object Error]",b="[object Function]",w="[object Map]",_="[object Number]",x="[object Object]",A="[object RegExp]",S="[object Set]",j="[object String]",E="[object WeakMap]",O="[object ArrayBuffer]",k="[object Float32Array]",T="[object Float64Array]",C="[object Int8Array]",I="[object Int16Array]",D="[object Int32Array]",L="[object Uint8Array]",M="[object Uint8ClampedArray]",R="[object Uint16Array]",U="[object Uint32Array]",P={};P[d]=P[m]=P[O]=P[g]=P[y]=P[k]=P[T]=P[C]=P[I]=P[D]=P[_]=P[x]=P[A]=P[j]=P[L]=P[M]=P[R]=P[U]=!0,P[v]=P[b]=P[w]=P[S]=P[E]=!1;var q=Object.prototype,B=q.toString;t.exports=r},{"../lang/isArray":140,"../lang/isObject":144,"./arrayCopy":62,"./arrayEach":63,"./baseAssign":66,"./baseForOwn":76,"./initCloneArray":116,"./initCloneByTag":117,"./initCloneObject":118,"./isHostObject":120}],69:[function(e,t,n){function r(e,t,n){n||(n={});for(var r=-1,i=t.length;++r<i;){var a=t[r];n[a]=e[a]}return n}t.exports=r},{}],70:[function(e,t,n){var r=e("../lang/isObject"),i=function(){function e(){}return function(t){if(r(t)){e.prototype=t;var n=new e;e.prototype=void 0}return n||{}}}();t.exports=i},{"../lang/isObject":144}],71:[function(e,t,n){var r=e("./baseForOwn"),i=e("./createBaseEach"),a=i(r);t.exports=a},{"./baseForOwn":76,"./createBaseEach":98}],72:[function(e,t,n){function r(e,t,n,r){var i;return n(e,function(e,n,a){if(t(e,n,a))return i=r?n:e,!1}),i}t.exports=r},{}],73:[function(e,t,n){function r(e,t,n){for(var r=e.length,i=n?r:-1;n?i--:++i<r;)if(t(e[i],i,e))return i;return-1}t.exports=r},{}],74:[function(e,t,n){var r=e("./createBaseFor"),i=r();t.exports=i},{"./createBaseFor":99}],75:[function(e,t,n){function r(e,t){return i(e,t,a)}var i=e("./baseFor"),a=e("../object/keysIn");t.exports=r},{"../object/keysIn":150,"./baseFor":74}],76:[function(e,t,n){function r(e,t){return i(e,t,a)}var i=e("./baseFor"),a=e("../object/keys");t.exports=r},{"../object/keys":149,"./baseFor":74}],77:[function(e,t,n){function r(e,t,n){if(null!=e){e=i(e),void 0!==n&&n in e&&(t=[n]);for(var r=0,a=t.length;null!=e&&r<a;)e=i(e)[t[r++]];return r&&r==a?e:void 0}}var i=e("./toObject");t.exports=r},{"./toObject":135}],78:[function(e,t,n){function r(e,t,n){if(t!==t)return i(e,n);for(var r=n-1,a=e.length;++r<a;)if(e[r]===t)return r;return-1}var i=e("./indexOfNaN");t.exports=r},{"./indexOfNaN":115}],79:[function(e,t,n){function r(e,t,n,s,l,u){return e===t||(null==e||null==t||!a(e)&&!o(t)?e!==e&&t!==t:i(e,t,r,n,s,l,u))}var i=e("./baseIsEqualDeep"),a=e("../lang/isObject"),o=e("./isObjectLike");t.exports=r},{"../lang/isObject":144,"./baseIsEqualDeep":80,"./isObjectLike":126}],80:[function(e,t,n){function r(e,t,n,r,f,g,y){var v=s(e),b=s(t),w=p,_=p;v||(w=m.call(e),w==c?w=h:w!=h&&(v=u(e))),b||(_=m.call(t),_==c?_=h:_!=h&&(b=u(t)));var x=w==h&&!l(e),A=_==h&&!l(t),S=w==_;if(S&&!v&&!x)return a(e,t,w);if(!f){var j=x&&d.call(e,"__wrapped__"),E=A&&d.call(t,"__wrapped__");if(j||E)return n(j?e.value():e,E?t.value():t,r,f,g,y)}if(!S)return!1;g||(g=[]),y||(y=[]);for(var O=g.length;O--;)if(g[O]==e)return y[O]==t;g.push(e),y.push(t);var k=(v?i:o)(e,t,n,r,f,g,y);return g.pop(),y.pop(),k}var i=e("./equalArrays"),a=e("./equalByTag"),o=e("./equalObjects"),s=e("../lang/isArray"),l=e("./isHostObject"),u=e("../lang/isTypedArray"),c="[object Arguments]",p="[object Array]",h="[object Object]",f=Object.prototype,d=f.hasOwnProperty,m=f.toString;t.exports=r},{"../lang/isArray":140,"../lang/isTypedArray":147,"./equalArrays":107,"./equalByTag":108,"./equalObjects":109,"./isHostObject":120}],81:[function(e,t,n){function r(e,t,n){var r=t.length,o=r,s=!n;if(null==e)return!o;for(e=a(e);r--;){var l=t[r];if(s&&l[2]?l[1]!==e[l[0]]:!(l[0]in e))return!1}for(;++r<o;){l=t[r];var u=l[0],c=e[u],p=l[1];if(s&&l[2]){if(void 0===c&&!(u in e))return!1}else{var h=n?n(c,p,u):void 0;if(!(void 0===h?i(p,c,n,!0):h))return!1}}return!0}var i=e("./baseIsEqual"),a=e("./toObject");t.exports=r},{"./baseIsEqual":79,"./toObject":135}],82:[function(e,t,n){function r(){}t.exports=r},{}],83:[function(e,t,n){function r(e,t){var n=-1,r=a(e)?Array(e.length):[];return i(e,function(e,i,a){r[++n]=t(e,i,a)}),r}var i=e("./baseEach"),a=e("./isArrayLike");t.exports=r},{"./baseEach":71,"./isArrayLike":119}],84:[function(e,t,n){function r(e){var t=a(e);if(1==t.length&&t[0][2]){var n=t[0][0],r=t[0][1];return function(e){return null!=e&&(e=o(e),e[n]===r&&(void 0!==r||n in e))}}return function(e){return i(e,t)}}var i=e("./baseIsMatch"),a=e("./getMatchData"),o=e("./toObject");t.exports=r},{"./baseIsMatch":81,"./getMatchData":113,"./toObject":135}],85:[function(e,t,n){function r(e,t){var n=s(e),r=l(e)&&u(t),f=e+"";return e=h(e),function(s){if(null==s)return!1;var l=f;if(s=p(s),(n||!r)&&!(l in s)){if(s=1==e.length?s:i(s,o(e,0,-1)),null==s)return!1;l=c(e),s=p(s)}return s[l]===t?void 0!==t||l in s:a(t,s[l],void 0,!0)}}var i=e("./baseGet"),a=e("./baseIsEqual"),o=e("./baseSlice"),s=e("../lang/isArray"),l=e("./isKey"),u=e("./isStrictComparable"),c=e("../array/last"),p=e("./toObject"),h=e("./toPath");t.exports=r},{"../array/last":50,"../lang/isArray":140,"./baseGet":77,"./baseIsEqual":79,"./baseSlice":89,"./isKey":123,"./isStrictComparable":127,"./toObject":135,"./toPath":136}],86:[function(e,t,n){function r(e){return function(t){return null==t?void 0:i(t)[e]}}var i=e("./toObject");t.exports=r},{"./toObject":135}],87:[function(e,t,n){function r(e){var t=e+"";return e=a(e),function(n){return i(n,e,t)}}var i=e("./baseGet"),a=e("./toPath");t.exports=r},{"./baseGet":77,"./toPath":136}],88:[function(e,t,n){var r=e("../utility/identity"),i=e("./metaMap"),a=i?function(e,t){return i.set(e,t),e}:r;t.exports=a},{"../utility/identity":154,"./metaMap":129}],89:[function(e,t,n){function r(e,t,n){var r=-1,i=e.length;t=null==t?0:+t||0,t<0&&(t=-t>i?0:i+t),n=void 0===n||n>i?i:+n||0,n<0&&(n+=i),i=t>n?0:n-t>>>0,t>>>=0;for(var a=Array(i);++r<i;)a[r]=e[r+t];return a}t.exports=r},{}],90:[function(e,t,n){function r(e){return null==e?"":e+""}t.exports=r},{}],91:[function(e,t,n){function r(e,t){for(var n=-1,r=t.length,i=Array(r);++n<r;)i[n]=e[t[n]];return i}t.exports=r},{}],92:[function(e,t,n){function r(e,t,n){var r=0,o=e?e.length:r;if("number"==typeof t&&t===t&&o<=s){for(;r<o;){var l=r+o>>>1,u=e[l];(n?u<=t:u<t)&&null!==u?r=l+1:o=l}return o}return i(e,t,a,n)}var i=e("./binaryIndexBy"),a=e("../utility/identity"),o=4294967295,s=o>>>1;t.exports=r},{"../utility/identity":154,"./binaryIndexBy":93}],93:[function(e,t,n){function r(e,t,n,r){t=n(t);for(var o=0,l=e?e.length:0,u=t!==t,c=null===t,p=void 0===t;o<l;){var h=i((o+l)/2),f=n(e[h]),d=void 0!==f,m=f===f;if(u)var g=m||r;else g=c?m&&d&&(r||null!=f):p?m&&(r||d):null!=f&&(r?f<=t:f<t);g?o=h+1:l=h}return a(l,s)}var i=Math.floor,a=Math.min,o=4294967295,s=o-1;t.exports=r},{}],94:[function(e,t,n){function r(e,t,n){if("function"!=typeof e)return i;if(void 0===t)return e;switch(n){case 1:return function(n){return e.call(t,n)};case 3:return function(n,r,i){return e.call(t,n,r,i)};case 4:return function(n,r,i,a){return e.call(t,n,r,i,a)};case 5:return function(n,r,i,a,o){return e.call(t,n,r,i,a,o)}}return function(){return e.apply(t,arguments)}}var i=e("../utility/identity");t.exports=r},{"../utility/identity":154}],95:[function(e,t,n){(function(e){function n(e){var t=new r(e.byteLength),n=new i(t);return n.set(new i(e)),t}var r=e.ArrayBuffer,i=e.Uint8Array;t.exports=n}).call(this,"undefined"!=typeof global?global:"undefined"!=typeof self?self:"undefined"!=typeof window?window:{})},{}],96:[function(e,t,n){function r(e,t,n){for(var r=n.length,a=-1,o=i(e.length-r,0),s=-1,l=t.length,u=Array(l+o);++s<l;)u[s]=t[s];for(;++a<r;)u[n[a]]=e[a];for(;o--;)u[s++]=e[a++];return u}var i=Math.max;t.exports=r},{}],97:[function(e,t,n){function r(e,t,n){for(var r=-1,a=n.length,o=-1,s=i(e.length-a,0),l=-1,u=t.length,c=Array(s+u);++o<s;)c[o]=e[o];for(var p=o;++l<u;)c[p+l]=t[l];for(;++r<a;)c[p+n[r]]=e[o++];return c}var i=Math.max;t.exports=r},{}],98:[function(e,t,n){function r(e,t){return function(n,r){var s=n?i(n):0;if(!a(s))return e(n,r);for(var l=t?s:-1,u=o(n);(t?l--:++l<s)&&r(u[l],l,u)!==!1;);return n}}var i=e("./getLength"),a=e("./isLength"),o=e("./toObject");t.exports=r},{"./getLength":112,"./isLength":125,"./toObject":135}],99:[function(e,t,n){function r(e){return function(t,n,r){for(var a=i(t),o=r(t),s=o.length,l=e?s:-1;e?l--:++l<s;){var u=o[l];if(n(a[u],u,a)===!1)break}return t}}var i=e("./toObject");t.exports=r},{"./toObject":135}],100:[function(e,t,n){(function(n){function r(e,t){function r(){var i=this&&this!==n&&this instanceof r?a:e;return i.apply(t,arguments)}var a=i(e);return r}var i=e("./createCtorWrapper");t.exports=r}).call(this,"undefined"!=typeof global?global:"undefined"!=typeof self?self:"undefined"!=typeof window?window:{})},{"./createCtorWrapper":101}],101:[function(e,t,n){function r(e){return function(){var t=arguments;switch(t.length){case 0:return new e;case 1:return new e(t[0]);case 2:return new e(t[0],t[1]);case 3:return new e(t[0],t[1],t[2]);case 4:return new e(t[0],t[1],t[2],t[3]);case 5:return new e(t[0],t[1],t[2],t[3],t[4]);case 6:return new e(t[0],t[1],t[2],t[3],t[4],t[5]);case 7:return new e(t[0],t[1],t[2],t[3],t[4],t[5],t[6])}var n=i(e.prototype),r=e.apply(n,t);return a(r)?r:n}}var i=e("./baseCreate"),a=e("../lang/isObject");t.exports=r},{"../lang/isObject":144,"./baseCreate":70}],102:[function(e,t,n){function r(e,t){return function(n,r,l){if(r=i(r,l,3),s(n)){var u=o(n,r,t);return u>-1?n[u]:void 0}return a(n,r,e)}}var i=e("./baseCallback"),a=e("./baseFind"),o=e("./baseFindIndex"),s=e("../lang/isArray");t.exports=r},{"../lang/isArray":140,"./baseCallback":67,"./baseFind":72,"./baseFindIndex":73}],103:[function(e,t,n){function r(e,t){return function(n,r,o){return"function"==typeof r&&void 0===o&&a(n)?e(n,r):t(n,i(r,o,3))}}var i=e("./bindCallback"),a=e("../lang/isArray");t.exports=r},{"../lang/isArray":140,"./bindCallback":94}],104:[function(e,t,n){(function(n){function r(e,t,_,x,A,S,j,E,O,k){function T(){for(var d=arguments.length,m=d,g=Array(d);m--;)g[m]=arguments[m];if(x&&(g=a(g,x,A)),S&&(g=o(g,S,j)),L||R){var b=T.placeholder,P=c(g,b);if(d-=P.length,d<k){var q=E?i(E):void 0,B=w(k-d,0),N=L?P:void 0,z=L?void 0:P,$=L?g:void 0,F=L?void 0:g;t|=L?y:v,t&=~(L?v:y),M||(t&=~(h|f));var V=[e,t,_,$,N,F,z,q,O,B],H=r.apply(void 0,V);return l(e)&&p(H,V),H.placeholder=b,H}}var Y=I?_:this,J=D?Y[e]:e;return E&&(g=u(g,E)),C&&O<g.length&&(g.length=O),this&&this!==n&&this instanceof T&&(J=U||s(e)),J.apply(Y,g)}var C=t&b,I=t&h,D=t&f,L=t&m,M=t&d,R=t&g,U=D?void 0:s(e);return T}var i=e("./arrayCopy"),a=e("./composeArgs"),o=e("./composeArgsRight"),s=e("./createCtorWrapper"),l=e("./isLaziable"),u=e("./reorder"),c=e("./replaceHolders"),p=e("./setData"),h=1,f=2,d=4,m=8,g=16,y=32,v=64,b=128,w=Math.max;t.exports=r}).call(this,"undefined"!=typeof global?global:"undefined"!=typeof self?self:"undefined"!=typeof window?window:{})},{"./arrayCopy":62,"./composeArgs":96,"./composeArgsRight":97,"./createCtorWrapper":101,"./isLaziable":124,"./reorder":131,"./replaceHolders":132,"./setData":133}],105:[function(e,t,n){(function(n){function r(e,t,r,o){function s(){for(var t=-1,i=arguments.length,a=-1,c=o.length,p=Array(c+i);++a<c;)p[a]=o[a];for(;i--;)p[a++]=arguments[++t];var h=this&&this!==n&&this instanceof s?u:e;return h.apply(l?r:this,p)}var l=t&a,u=i(e);return s}var i=e("./createCtorWrapper"),a=1;t.exports=r}).call(this,"undefined"!=typeof global?global:"undefined"!=typeof self?self:"undefined"!=typeof window?window:{})},{"./createCtorWrapper":101}],106:[function(e,t,n){function r(e,t,n,r,y,v,b,w){var _=t&h;if(!_&&"function"!=typeof e)throw new TypeError(m);var x=r?r.length:0;if(x||(t&=~(f|d),r=y=void 0),x-=y?y.length:0,t&d){var A=r,S=y;r=y=void 0}var j=_?void 0:l(e),E=[e,t,n,r,y,A,S,v,b,w];if(j&&(u(E,j),t=E[1],w=E[9]),E[9]=null==w?_?0:e.length:g(w-x,0)||0,t==p)var O=a(E[0],E[2]);else O=t!=f&&t!=(p|f)||E[4].length?o.apply(void 0,E):s.apply(void 0,E);var k=j?i:c;return k(O,E)}var i=e("./baseSetData"),a=e("./createBindWrapper"),o=e("./createHybridWrapper"),s=e("./createPartialWrapper"),l=e("./getData"),u=e("./mergeData"),c=e("./setData"),p=1,h=2,f=32,d=64,m="Expected a function",g=Math.max;t.exports=r},{"./baseSetData":88,"./createBindWrapper":100,"./createHybridWrapper":104,"./createPartialWrapper":105,"./getData":110,"./mergeData":128,"./setData":133}],107:[function(e,t,n){function r(e,t,n,r,a,o,s){var l=-1,u=e.length,c=t.length;if(u!=c&&!(a&&c>u))return!1;for(;++l<u;){var p=e[l],h=t[l],f=r?r(a?h:p,a?p:h,l):void 0;if(void 0!==f){if(f)continue;return!1}if(a){if(!i(t,function(e){return p===e||n(p,e,r,a,o,s)}))return!1}else if(p!==h&&!n(p,h,r,a,o,s))return!1}return!0}var i=e("./arraySome");t.exports=r},{"./arraySome":65}],108:[function(e,t,n){function r(e,t,n){switch(n){case i:case a:return+e==+t;case o:return e.name==t.name&&e.message==t.message;case s:return e!=+e?t!=+t:e==+t;case l:case u:return e==t+""}return!1}var i="[object Boolean]",a="[object Date]",o="[object Error]",s="[object Number]",l="[object RegExp]",u="[object String]";t.exports=r},{}],109:[function(e,t,n){function r(e,t,n,r,a,s,l){var u=i(e),c=u.length,p=i(t),h=p.length;if(c!=h&&!a)return!1;for(var f=c;f--;){var d=u[f];if(!(a?d in t:o.call(t,d)))return!1}for(var m=a;++f<c;){d=u[f];var g=e[d],y=t[d],v=r?r(a?y:g,a?g:y,d):void 0;if(!(void 0===v?n(g,y,r,a,s,l):v))return!1;m||(m="constructor"==d)}if(!m){var b=e.constructor,w=t.constructor;if(b!=w&&"constructor"in e&&"constructor"in t&&!("function"==typeof b&&b instanceof b&&"function"==typeof w&&w instanceof w))return!1}return!0}var i=e("../object/keys"),a=Object.prototype,o=a.hasOwnProperty;t.exports=r},{"../object/keys":149}],110:[function(e,t,n){var r=e("./metaMap"),i=e("../utility/noop"),a=r?function(e){return r.get(e)}:i;t.exports=a},{"../utility/noop":155,"./metaMap":129}],111:[function(e,t,n){function r(e){for(var t=e.name+"",n=i[t],r=n?n.length:0;r--;){var a=n[r],o=a.func;if(null==o||o==e)return a.name}return t}var i=e("./realNames");t.exports=r},{"./realNames":130}],112:[function(e,t,n){var r=e("./baseProperty"),i=r("length");t.exports=i},{"./baseProperty":86}],113:[function(e,t,n){function r(e){for(var t=a(e),n=t.length;n--;)t[n][2]=i(t[n][1]);return t}var i=e("./isStrictComparable"),a=e("../object/pairs");t.exports=r},{"../object/pairs":151,"./isStrictComparable":127}],114:[function(e,t,n){function r(e,t){var n=null==e?void 0:e[t];return i(n)?n:void 0}var i=e("../lang/isNative");t.exports=r},{"../lang/isNative":143}],115:[function(e,t,n){function r(e,t,n){for(var r=e.length,i=t+(n?0:-1);n?i--:++i<r;){var a=e[i];if(a!==a)return i}return-1}t.exports=r},{}],116:[function(e,t,n){function r(e){var t=e.length,n=new e.constructor(t);return t&&"string"==typeof e[0]&&a.call(e,"index")&&(n.index=e.index,n.input=e.input),n}var i=Object.prototype,a=i.hasOwnProperty;t.exports=r},{}],117:[function(e,t,n){(function(n){function r(e,t,n){var r=e.constructor;switch(t){case c:return i(e);case a:case o:return new r((+e));case p:case h:case f:case d:case m:case g:case y:case v:case b:r instanceof r&&(r=x[t]);var _=e.buffer;return new r(n?i(_):_,e.byteOffset,e.length);case s:case u:return new r(e);case l:var A=new r(e.source,w.exec(e));A.lastIndex=e.lastIndex}return A}var i=e("./bufferClone"),a="[object Boolean]",o="[object Date]",s="[object Number]",l="[object RegExp]",u="[object String]",c="[object ArrayBuffer]",p="[object Float32Array]",h="[object Float64Array]",f="[object Int8Array]",d="[object Int16Array]",m="[object Int32Array]",g="[object Uint8Array]",y="[object Uint8ClampedArray]",v="[object Uint16Array]",b="[object Uint32Array]",w=/\w*$/,_=n.Uint8Array,x={};x[p]=n.Float32Array,x[h]=n.Float64Array,x[f]=n.Int8Array,x[d]=n.Int16Array,x[m]=n.Int32Array,x[g]=_,x[y]=n.Uint8ClampedArray,x[v]=n.Uint16Array,x[b]=n.Uint32Array,t.exports=r}).call(this,"undefined"!=typeof global?global:"undefined"!=typeof self?self:"undefined"!=typeof window?window:{})},{"./bufferClone":95}],118:[function(e,t,n){function r(e){var t=e.constructor;return"function"==typeof t&&t instanceof t||(t=Object),new t}t.exports=r},{}],119:[function(e,t,n){function r(e){return null!=e&&a(i(e))}var i=e("./getLength"),a=e("./isLength");t.exports=r},{"./getLength":112,"./isLength":125}],120:[function(e,t,n){var r=function(){try{Object({toString:0}+"")}catch(e){return function(){return!1}}return function(e){return"function"!=typeof e.toString&&"string"==typeof(e+"")}}();t.exports=r},{}],121:[function(e,t,n){function r(e,t){return e="number"==typeof e||i.test(e)?+e:-1,t=null==t?a:t,e>-1&&e%1==0&&e<t}var i=/^\d+$/,a=9007199254740991;t.exports=r},{}],122:[function(e,t,n){function r(e,t,n){if(!o(n))return!1;var r=typeof t;if("number"==r?i(n)&&a(t,n.length):"string"==r&&t in n){var s=n[t];return e===e?e===s:s!==s}return!1}var i=e("./isArrayLike"),a=e("./isIndex"),o=e("../lang/isObject");t.exports=r},{"../lang/isObject":144,"./isArrayLike":119,"./isIndex":121}],123:[function(e,t,n){function r(e,t){var n=typeof e;if("string"==n&&s.test(e)||"number"==n)return!0;if(i(e))return!1;var r=!o.test(e);return r||null!=t&&e in a(t)}var i=e("../lang/isArray"),a=e("./toObject"),o=/\.|\[(?:[^[\]]*|(["'])(?:(?!\1)[^\n\\]|\\.)*?\1)\]/,s=/^\w*$/;t.exports=r},{"../lang/isArray":140,"./toObject":135}],124:[function(e,t,n){function r(e){var t=o(e),n=s[t];if("function"!=typeof n||!(t in i.prototype))return!1;if(e===n)return!0;var r=a(n);return!!r&&e===r[0]}var i=e("./LazyWrapper"),a=e("./getData"),o=e("./getFuncName"),s=e("../chain/lodash");t.exports=r},{"../chain/lodash":51,"./LazyWrapper":60,"./getData":110,"./getFuncName":111}],125:[function(e,t,n){function r(e){return"number"==typeof e&&e>-1&&e%1==0&&e<=i}var i=9007199254740991;t.exports=r},{}],126:[function(e,t,n){function r(e){return!!e&&"object"==typeof e}t.exports=r},{}],127:[function(e,t,n){function r(e){return e===e&&!i(e)}var i=e("../lang/isObject");t.exports=r},{"../lang/isObject":144}],128:[function(e,t,n){function r(e,t){var n=e[1],r=t[1],m=n|r,g=m<p,y=r==p&&n==c||r==p&&n==h&&e[7].length<=t[8]||r==(p|h)&&n==c;if(!g&&!y)return e;r&l&&(e[2]=t[2],m|=n&l?0:u);var v=t[3];if(v){var b=e[3];e[3]=b?a(b,v,t[4]):i(v),e[4]=b?s(e[3],f):i(t[4])}return v=t[5],v&&(b=e[5],e[5]=b?o(b,v,t[6]):i(v),e[6]=b?s(e[5],f):i(t[6])),v=t[7],v&&(e[7]=i(v)),r&p&&(e[8]=null==e[8]?t[8]:d(e[8],t[8])),null==e[9]&&(e[9]=t[9]),e[0]=t[0],e[1]=m,e}var i=e("./arrayCopy"),a=e("./composeArgs"),o=e("./composeArgsRight"),s=e("./replaceHolders"),l=1,u=4,c=8,p=128,h=256,f="__lodash_placeholder__",d=Math.min;t.exports=r},{"./arrayCopy":62,"./composeArgs":96,"./composeArgsRight":97,"./replaceHolders":132}],129:[function(e,t,n){(function(n){var r=e("./getNative"),i=r(n,"WeakMap"),a=i&&new i;t.exports=a}).call(this,"undefined"!=typeof global?global:"undefined"!=typeof self?self:"undefined"!=typeof window?window:{})},{"./getNative":114}],130:[function(e,t,n){var r={};t.exports=r},{}],131:[function(e,t,n){function r(e,t){for(var n=e.length,r=o(t.length,n),s=i(e);r--;){var l=t[r];e[r]=a(l,n)?s[l]:void 0}return e}var i=e("./arrayCopy"),a=e("./isIndex"),o=Math.min;t.exports=r},{"./arrayCopy":62,"./isIndex":121}],132:[function(e,t,n){function r(e,t){for(var n=-1,r=e.length,a=-1,o=[];++n<r;)e[n]===t&&(e[n]=i,o[++a]=n);return o}var i="__lodash_placeholder__";t.exports=r},{}],133:[function(e,t,n){var r=e("./baseSetData"),i=e("../date/now"),a=150,o=16,s=function(){var e=0,t=0;return function(n,s){var l=i(),u=o-(l-t);if(t=l,u>0){if(++e>=a)return n}else e=0;return r(n,s)}}();t.exports=s},{"../date/now":57,"./baseSetData":88}],134:[function(e,t,n){function r(e){for(var t=u(e),n=t.length,r=n&&e.length,c=!!r&&s(r)&&(a(e)||i(e)||l(e)),h=-1,f=[];++h<n;){var d=t[h];(c&&o(d,r)||p.call(e,d))&&f.push(d)}return f}var i=e("../lang/isArguments"),a=e("../lang/isArray"),o=e("./isIndex"),s=e("./isLength"),l=e("../lang/isString"),u=e("../object/keysIn"),c=Object.prototype,p=c.hasOwnProperty;t.exports=r},{"../lang/isArguments":139,"../lang/isArray":140,"../lang/isString":146,"../object/keysIn":150,
+"./isIndex":121,"./isLength":125}],135:[function(e,t,n){function r(e){if(o.unindexedChars&&a(e)){for(var t=-1,n=e.length,r=Object(e);++t<n;)r[t]=e.charAt(t);return r}return i(e)?e:Object(e)}var i=e("../lang/isObject"),a=e("../lang/isString"),o=e("../support");t.exports=r},{"../lang/isObject":144,"../lang/isString":146,"../support":153}],136:[function(e,t,n){function r(e){if(a(e))return e;var t=[];return i(e).replace(o,function(e,n,r,i){t.push(r?i.replace(s,"$1"):n||e)}),t}var i=e("./baseToString"),a=e("../lang/isArray"),o=/[^.[\]]+|\[(?:(-?\d+(?:\.\d+)?)|(["'])((?:(?!\2)[^\n\\]|\\.)*?)\2)\]/g,s=/\\(\\)?/g;t.exports=r},{"../lang/isArray":140,"./baseToString":90}],137:[function(e,t,n){function r(e){return e instanceof i?e.clone():new a(e.__wrapped__,e.__chain__,o(e.__actions__))}var i=e("./LazyWrapper"),a=e("./LodashWrapper"),o=e("./arrayCopy");t.exports=r},{"./LazyWrapper":60,"./LodashWrapper":61,"./arrayCopy":62}],138:[function(e,t,n){function r(e,t,n){return"function"==typeof t?i(e,!0,a(t,n,3)):i(e,!0)}var i=e("../internal/baseClone"),a=e("../internal/bindCallback");t.exports=r},{"../internal/baseClone":68,"../internal/bindCallback":94}],139:[function(e,t,n){function r(e){return a(e)&&i(e)&&s.call(e,"callee")&&!l.call(e,"callee")}var i=e("../internal/isArrayLike"),a=e("../internal/isObjectLike"),o=Object.prototype,s=o.hasOwnProperty,l=o.propertyIsEnumerable;t.exports=r},{"../internal/isArrayLike":119,"../internal/isObjectLike":126}],140:[function(e,t,n){var r=e("../internal/getNative"),i=e("../internal/isLength"),a=e("../internal/isObjectLike"),o="[object Array]",s=Object.prototype,l=s.toString,u=r(Array,"isArray"),c=u||function(e){return a(e)&&i(e.length)&&l.call(e)==o};t.exports=c},{"../internal/getNative":114,"../internal/isLength":125,"../internal/isObjectLike":126}],141:[function(e,t,n){function r(e){return null==e||(o(e)&&(a(e)||u(e)||i(e)||l(e)&&s(e.splice))?!e.length:!c(e).length)}var i=e("./isArguments"),a=e("./isArray"),o=e("../internal/isArrayLike"),s=e("./isFunction"),l=e("../internal/isObjectLike"),u=e("./isString"),c=e("../object/keys");t.exports=r},{"../internal/isArrayLike":119,"../internal/isObjectLike":126,"../object/keys":149,"./isArguments":139,"./isArray":140,"./isFunction":142,"./isString":146}],142:[function(e,t,n){function r(e){return i(e)&&s.call(e)==a}var i=e("./isObject"),a="[object Function]",o=Object.prototype,s=o.toString;t.exports=r},{"./isObject":144}],143:[function(e,t,n){function r(e){return null!=e&&(i(e)?p.test(u.call(e)):o(e)&&(a(e)?p:s).test(e))}var i=e("./isFunction"),a=e("../internal/isHostObject"),o=e("../internal/isObjectLike"),s=/^\[object .+?Constructor\]$/,l=Object.prototype,u=Function.prototype.toString,c=l.hasOwnProperty,p=RegExp("^"+u.call(c).replace(/[\\^$.*+?()[\]{}|]/g,"\\$&").replace(/hasOwnProperty|(function).*?(?=\\\()| for .+?(?=\\\])/g,"$1.*?")+"$");t.exports=r},{"../internal/isHostObject":120,"../internal/isObjectLike":126,"./isFunction":142}],144:[function(e,t,n){function r(e){var t=typeof e;return!!e&&("object"==t||"function"==t)}t.exports=r},{}],145:[function(e,t,n){function r(e){var t;if(!s(e)||h.call(e)!=u||o(e)||a(e)||!p.call(e,"constructor")&&(t=e.constructor,"function"==typeof t&&!(t instanceof t)))return!1;var n;return l.ownLast?(i(e,function(e,t,r){return n=p.call(r,t),!1}),n!==!1):(i(e,function(e,t){n=t}),void 0===n||p.call(e,n))}var i=e("../internal/baseForIn"),a=e("./isArguments"),o=e("../internal/isHostObject"),s=e("../internal/isObjectLike"),l=e("../support"),u="[object Object]",c=Object.prototype,p=c.hasOwnProperty,h=c.toString;t.exports=r},{"../internal/baseForIn":75,"../internal/isHostObject":120,"../internal/isObjectLike":126,"../support":153,"./isArguments":139}],146:[function(e,t,n){function r(e){return"string"==typeof e||i(e)&&s.call(e)==a}var i=e("../internal/isObjectLike"),a="[object String]",o=Object.prototype,s=o.toString;t.exports=r},{"../internal/isObjectLike":126}],147:[function(e,t,n){function r(e){return a(e)&&i(e.length)&&!!T[I.call(e)]}var i=e("../internal/isLength"),a=e("../internal/isObjectLike"),o="[object Arguments]",s="[object Array]",l="[object Boolean]",u="[object Date]",c="[object Error]",p="[object Function]",h="[object Map]",f="[object Number]",d="[object Object]",m="[object RegExp]",g="[object Set]",y="[object String]",v="[object WeakMap]",b="[object ArrayBuffer]",w="[object Float32Array]",_="[object Float64Array]",x="[object Int8Array]",A="[object Int16Array]",S="[object Int32Array]",j="[object Uint8Array]",E="[object Uint8ClampedArray]",O="[object Uint16Array]",k="[object Uint32Array]",T={};T[w]=T[_]=T[x]=T[A]=T[S]=T[j]=T[E]=T[O]=T[k]=!0,T[o]=T[s]=T[b]=T[l]=T[u]=T[c]=T[p]=T[h]=T[f]=T[d]=T[m]=T[g]=T[y]=T[v]=!1;var C=Object.prototype,I=C.toString;t.exports=r},{"../internal/isLength":125,"../internal/isObjectLike":126}],148:[function(e,t,n){function r(e){return void 0===e}t.exports=r},{}],149:[function(e,t,n){var r=e("../internal/getNative"),i=e("../internal/isArrayLike"),a=e("../lang/isObject"),o=e("../internal/shimKeys"),s=e("../support"),l=r(Object,"keys"),u=l?function(e){var t=null==e?void 0:e.constructor;return"function"==typeof t&&t.prototype===e||("function"==typeof e?s.enumPrototypes:i(e))?o(e):a(e)?l(e):[]}:o;t.exports=u},{"../internal/getNative":114,"../internal/isArrayLike":119,"../internal/shimKeys":134,"../lang/isObject":144,"../support":153}],150:[function(e,t,n){function r(e){if(null==e)return[];c(e)||(e=Object(e));var t=e.length;t=t&&u(t)&&(o(e)||a(e)||p(e))&&t||0;for(var n=e.constructor,r=-1,i=s(n)&&n.prototype||S,f=i===e,d=Array(t),m=t>0,y=h.enumErrorProps&&(e===A||e instanceof Error),v=h.enumPrototypes&&s(e);++r<t;)d[r]=r+"";for(var w in e)v&&"prototype"==w||y&&("message"==w||"name"==w)||m&&l(w,t)||"constructor"==w&&(f||!E.call(e,w))||d.push(w);if(h.nonEnumShadows&&e!==S){var T=e===j?_:e===A?g:O.call(e),C=k[T]||k[b];for(T==b&&(i=S),t=x.length;t--;){w=x[t];var I=C[w];f&&I||(I?!E.call(e,w):e[w]===i[w])||d.push(w)}}return d}var i=e("../internal/arrayEach"),a=e("../lang/isArguments"),o=e("../lang/isArray"),s=e("../lang/isFunction"),l=e("../internal/isIndex"),u=e("../internal/isLength"),c=e("../lang/isObject"),p=e("../lang/isString"),h=e("../support"),f="[object Array]",d="[object Boolean]",m="[object Date]",g="[object Error]",y="[object Function]",v="[object Number]",b="[object Object]",w="[object RegExp]",_="[object String]",x=["constructor","hasOwnProperty","isPrototypeOf","propertyIsEnumerable","toLocaleString","toString","valueOf"],A=Error.prototype,S=Object.prototype,j=String.prototype,E=S.hasOwnProperty,O=S.toString,k={};k[f]=k[m]=k[v]={constructor:!0,toLocaleString:!0,toString:!0,valueOf:!0},k[d]=k[_]={constructor:!0,toString:!0,valueOf:!0},k[g]=k[y]=k[w]={constructor:!0,toString:!0},k[b]={constructor:!0},i(x,function(e){for(var t in k)if(E.call(k,t)){var n=k[t];n[e]=E.call(n,e)}}),t.exports=r},{"../internal/arrayEach":63,"../internal/isIndex":121,"../internal/isLength":125,"../lang/isArguments":139,"../lang/isArray":140,"../lang/isFunction":142,"../lang/isObject":144,"../lang/isString":146,"../support":153}],151:[function(e,t,n){function r(e){e=a(e);for(var t=-1,n=i(e),r=n.length,o=Array(r);++t<r;){var s=n[t];o[t]=[s,e[s]]}return o}var i=e("./keys"),a=e("../internal/toObject");t.exports=r},{"../internal/toObject":135,"./keys":149}],152:[function(e,t,n){function r(e){return i(e,a(e))}var i=e("../internal/baseValues"),a=e("./keys");t.exports=r},{"../internal/baseValues":91,"./keys":149}],153:[function(e,t,n){var r=Array.prototype,i=Error.prototype,a=Object.prototype,o=a.propertyIsEnumerable,s=r.splice,l={};!function(e){var t=function(){this.x=e},n={0:e,length:e},r=[];t.prototype={valueOf:e,y:e};for(var a in new t)r.push(a);l.enumErrorProps=o.call(i,"message")||o.call(i,"name"),l.enumPrototypes=o.call(t,"prototype"),l.nonEnumShadows=!/valueOf/.test(r),l.ownLast="x"!=r[0],l.spliceObjects=(s.call(n,0,1),!n[0]),l.unindexedChars="x"[0]+Object("x")[0]!="xx"}(1,0),t.exports=l},{}],154:[function(e,t,n){function r(e){return e}t.exports=r},{}],155:[function(e,t,n){function r(){}t.exports=r},{}],156:[function(e,t,n){function r(e){return o(e)?i(e):a(e)}var i=e("../internal/baseProperty"),a=e("../internal/basePropertyDeep"),o=e("../internal/isKey");t.exports=r},{"../internal/baseProperty":86,"../internal/basePropertyDeep":87,"../internal/isKey":123}],157:[function(e,n,r){(function(e){!function(e){"use strict";if("function"==typeof bootstrap)bootstrap("promise",e);else if("object"==typeof r&&"object"==typeof n)n.exports=e();else if("function"==typeof t&&t.amd)t(e);else if("undefined"!=typeof ses){if(!ses.ok())return;ses.makeQ=e}else{if("undefined"==typeof window&&"undefined"==typeof self)throw new Error("This environment was not anticipated by Q. Please file a bug.");var i="undefined"!=typeof window?window:self,a=i.Q;i.Q=e(),i.Q.noConflict=function(){return i.Q=a,this}}}(function(){"use strict";function t(e){return function(){return Q.apply(e,arguments)}}function n(e){return e===Object(e)}function r(e){return"[object StopIteration]"===re(e)||e instanceof H}function i(e,t){if($&&t.stack&&"object"==typeof e&&null!==e&&e.stack&&e.stack.indexOf(ie)===-1){for(var n=[],r=t;r;r=r.source)r.stack&&n.unshift(r.stack);n.unshift(e.stack);var i=n.join("\n"+ie+"\n");e.stack=a(i)}}function a(e){for(var t=e.split("\n"),n=[],r=0;r<t.length;++r){var i=t[r];l(i)||o(i)||!i||n.push(i)}return n.join("\n")}function o(e){return e.indexOf("(module.js:")!==-1||e.indexOf("(node.js:")!==-1}function s(e){var t=/at .+ \((.+):(\d+):(?:\d+)\)$/.exec(e);if(t)return[t[1],Number(t[2])];var n=/at ([^ ]+):(\d+):(?:\d+)$/.exec(e);if(n)return[n[1],Number(n[2])];var r=/.*@(.+):(\d+)$/.exec(e);return r?[r[1],Number(r[2])]:void 0}function l(e){var t=s(e);if(!t)return!1;var n=t[0],r=t[1];return n===V&&r>=Y&&r<=ue}function u(){if($)try{throw new Error}catch(e){var t=e.stack.split("\n"),n=t[0].indexOf("@")>0?t[1]:t[2],r=s(n);if(!r)return;return V=r[0],r[1]}}function c(e,t,n){return function(){return"undefined"!=typeof console&&"function"==typeof console.warn&&console.warn(t+" is deprecated, use "+n+" instead.",new Error("").stack),e.apply(e,arguments)}}function p(e){return e instanceof m?e:b(e)?k(e):O(e)}function h(){function e(e){t=e,a.source=e,K(n,function(t,n){p.nextTick(function(){e.promiseDispatch.apply(e,n)})},void 0),n=void 0,r=void 0}var t,n=[],r=[],i=ee(h.prototype),a=ee(m.prototype);if(a.promiseDispatch=function(e,i,a){var o=G(arguments);n?(n.push(o),"when"===i&&a[1]&&r.push(a[1])):p.nextTick(function(){t.promiseDispatch.apply(t,o)})},a.valueOf=function(){if(n)return a;var e=y(t);return v(e)&&(t=e),e},a.inspect=function(){return t?t.inspect():{state:"pending"}},p.longStackSupport&&$)try{throw new Error}catch(o){a.stack=o.stack.substring(o.stack.indexOf("\n")+1)}return i.promise=a,i.resolve=function(n){t||e(p(n))},i.fulfill=function(n){t||e(O(n))},i.reject=function(n){t||e(E(n))},i.notify=function(e){t||K(r,function(t,n){p.nextTick(function(){n(e)})},void 0)},i}function f(e){if("function"!=typeof e)throw new TypeError("resolver must be a function.");var t=h();try{e(t.resolve,t.reject,t.notify)}catch(n){t.reject(n)}return t.promise}function d(e){return f(function(t,n){for(var r=0,i=e.length;r<i;r++)p(e[r]).then(t,n)})}function m(e,t,n){void 0===t&&(t=function(e){return E(new Error("Promise does not support operation: "+e))}),void 0===n&&(n=function(){return{state:"unknown"}});var r=ee(m.prototype);if(r.promiseDispatch=function(n,i,a){var o;try{o=e[i]?e[i].apply(r,a):t.call(r,i,a)}catch(s){o=E(s)}n&&n(o)},r.inspect=n,n){var i=n();"rejected"===i.state&&(r.exception=i.reason),r.valueOf=function(){var e=n();return"pending"===e.state||"rejected"===e.state?r:e.value}}return r}function g(e,t,n,r){return p(e).then(t,n,r)}function y(e){if(v(e)){var t=e.inspect();if("fulfilled"===t.state)return t.value}return e}function v(e){return e instanceof m}function b(e){return n(e)&&"function"==typeof e.then}function w(e){return v(e)&&"pending"===e.inspect().state}function _(e){return!v(e)||"fulfilled"===e.inspect().state}function x(e){return v(e)&&"rejected"===e.inspect().state}function A(){ae.length=0,oe.length=0,le||(le=!0)}function S(t,n){le&&("object"==typeof e&&"function"==typeof e.emit&&p.nextTick.runAfter(function(){X(oe,t)!==-1&&(e.emit("unhandledRejection",n,t),se.push(t))}),oe.push(t),n&&"undefined"!=typeof n.stack?ae.push(n.stack):ae.push("(no stack) "+n))}function j(t){if(le){var n=X(oe,t);n!==-1&&("object"==typeof e&&"function"==typeof e.emit&&p.nextTick.runAfter(function(){var r=X(se,t);r!==-1&&(e.emit("rejectionHandled",ae[n],t),se.splice(r,1))}),oe.splice(n,1),ae.splice(n,1))}}function E(e){var t=m({when:function(t){return t&&j(this),t?t(e):this}},function(){return this},function(){return{state:"rejected",reason:e}});return S(t,e),t}function O(e){return m({when:function(){return e},get:function(t){return e[t]},set:function(t,n){e[t]=n},"delete":function(t){delete e[t]},post:function(t,n){return null===t||void 0===t?e.apply(void 0,n):e[t].apply(e,n)},apply:function(t,n){return e.apply(t,n)},keys:function(){return ne(e)}},void 0,function(){return{state:"fulfilled",value:e}})}function k(e){var t=h();return p.nextTick(function(){try{e.then(t.resolve,t.reject,t.notify)}catch(n){t.reject(n)}}),t.promise}function T(e){return m({isDef:function(){}},function(t,n){return R(e,t,n)},function(){return p(e).inspect()})}function C(e,t,n){return p(e).spread(t,n)}function I(e){return function(){function t(e,t){var o;if("undefined"==typeof StopIteration){try{o=n[e](t)}catch(s){return E(s)}return o.done?p(o.value):g(o.value,i,a)}try{o=n[e](t)}catch(s){return r(s)?p(s.value):E(s)}return g(o,i,a)}var n=e.apply(this,arguments),i=t.bind(t,"next"),a=t.bind(t,"throw");return i()}}function D(e){p.done(p.async(e)())}function L(e){throw new H(e)}function M(e){return function(){return C([this,U(arguments)],function(t,n){return e.apply(t,n)})}}function R(e,t,n){return p(e).dispatch(t,n)}function U(e){return g(e,function(e){var t=0,n=h();return K(e,function(r,i,a){var o;v(i)&&"fulfilled"===(o=i.inspect()).state?e[a]=o.value:(++t,g(i,function(r){e[a]=r,0===--t&&n.resolve(e)},n.reject,function(e){n.notify({index:a,value:e})}))},void 0),0===t&&n.resolve(e),n.promise})}function P(e){if(0===e.length)return p.resolve();var t=p.defer(),n=0;return K(e,function(r,i,a){function o(e){t.resolve(e)}function s(){n--,0===n&&t.reject(new Error("Can't get fulfillment value from any promise, all promises were rejected."))}function l(e){t.notify({index:a,value:e})}var u=e[a];n++,g(u,o,s,l)},void 0),t.promise}function q(e){return g(e,function(e){return e=Z(e,p),g(U(Z(e,function(e){return g(e,J,J)})),function(){return e})})}function B(e){return p(e).allSettled()}function N(e,t){return p(e).then(void 0,void 0,t)}function z(e,t){return p(e).nodeify(t)}var $=!1;try{throw new Error}catch(F){$=!!F.stack}var V,H,Y=u(),J=function(){},W=function(){function t(){for(var e,t;r.next;)r=r.next,e=r.task,r.task=void 0,t=r.domain,t&&(r.domain=void 0,t.enter()),n(e,t);for(;l.length;)e=l.pop(),n(e);a=!1}function n(e,n){try{e()}catch(r){if(s)throw n&&n.exit(),setTimeout(t,0),n&&n.enter(),r;setTimeout(function(){throw r},0)}n&&n.exit()}var r={task:void 0,next:null},i=r,a=!1,o=void 0,s=!1,l=[];if(W=function(t){i=i.next={task:t,domain:s&&e.domain,next:null},a||(a=!0,o())},"object"==typeof e&&"[object process]"===e.toString()&&e.nextTick)s=!0,o=function(){e.nextTick(t)};else if("function"==typeof setImmediate)o="undefined"!=typeof window?setImmediate.bind(window,t):function(){setImmediate(t)};else if("undefined"!=typeof MessageChannel){var u=new MessageChannel;u.port1.onmessage=function(){o=c,u.port1.onmessage=t,t()};var c=function(){u.port2.postMessage(0)};o=function(){setTimeout(t,0),c()}}else o=function(){setTimeout(t,0)};return W.runAfter=function(e){l.push(e),a||(a=!0,o())},W}(),Q=Function.call,G=t(Array.prototype.slice),K=t(Array.prototype.reduce||function(e,t){var n=0,r=this.length;if(1===arguments.length)for(;;){if(n in this){t=this[n++];break}if(++n>=r)throw new TypeError}for(;n<r;n++)n in this&&(t=e(t,this[n],n));return t}),X=t(Array.prototype.indexOf||function(e){for(var t=0;t<this.length;t++)if(this[t]===e)return t;return-1}),Z=t(Array.prototype.map||function(e,t){var n=this,r=[];return K(n,function(i,a,o){r.push(e.call(t,a,o,n))},void 0),r}),ee=Object.create||function(e){function t(){}return t.prototype=e,new t},te=t(Object.prototype.hasOwnProperty),ne=Object.keys||function(e){var t=[];for(var n in e)te(e,n)&&t.push(n);return t},re=t(Object.prototype.toString);H="undefined"!=typeof ReturnValue?ReturnValue:function(e){this.value=e};var ie="From previous event:";p.resolve=p,p.nextTick=W,p.longStackSupport=!1,"object"==typeof e&&e&&e.env&&e.env.Q_DEBUG&&(p.longStackSupport=!0),p.defer=h,h.prototype.makeNodeResolver=function(){var e=this;return function(t,n){t?e.reject(t):arguments.length>2?e.resolve(G(arguments,1)):e.resolve(n)}},p.Promise=f,p.promise=f,f.race=d,f.all=U,f.reject=E,f.resolve=p,p.passByCopy=function(e){return e},m.prototype.passByCopy=function(){return this},p.join=function(e,t){return p(e).join(t)},m.prototype.join=function(e){return p([this,e]).spread(function(e,t){if(e===t)return e;throw new Error("Can't join: not the same: "+e+" "+t)})},p.race=d,m.prototype.race=function(){return this.then(p.race)},p.makePromise=m,m.prototype.toString=function(){return"[object Promise]"},m.prototype.then=function(e,t,n){function r(t){try{return"function"==typeof e?e(t):t}catch(n){return E(n)}}function a(e){if("function"==typeof t){i(e,s);try{return t(e)}catch(n){return E(n)}}return E(e)}function o(e){return"function"==typeof n?n(e):e}var s=this,l=h(),u=!1;return p.nextTick(function(){s.promiseDispatch(function(e){u||(u=!0,l.resolve(r(e)))},"when",[function(e){u||(u=!0,l.resolve(a(e)))}])}),s.promiseDispatch(void 0,"when",[void 0,function(e){var t,n=!1;try{t=o(e)}catch(r){if(n=!0,!p.onerror)throw r;p.onerror(r)}n||l.notify(t)}]),l.promise},p.tap=function(e,t){return p(e).tap(t)},m.prototype.tap=function(e){return e=p(e),this.then(function(t){return e.fcall(t).thenResolve(t)})},p.when=g,m.prototype.thenResolve=function(e){return this.then(function(){return e})},p.thenResolve=function(e,t){return p(e).thenResolve(t)},m.prototype.thenReject=function(e){return this.then(function(){throw e})},p.thenReject=function(e,t){return p(e).thenReject(t)},p.nearer=y,p.isPromise=v,p.isPromiseAlike=b,p.isPending=w,m.prototype.isPending=function(){return"pending"===this.inspect().state},p.isFulfilled=_,m.prototype.isFulfilled=function(){return"fulfilled"===this.inspect().state},p.isRejected=x,m.prototype.isRejected=function(){return"rejected"===this.inspect().state};var ae=[],oe=[],se=[],le=!0;p.resetUnhandledRejections=A,p.getUnhandledReasons=function(){return ae.slice()},p.stopUnhandledRejectionTracking=function(){A(),le=!1},A(),p.reject=E,p.fulfill=O,p.master=T,p.spread=C,m.prototype.spread=function(e,t){return this.all().then(function(t){return e.apply(void 0,t)},t)},p.async=I,p.spawn=D,p["return"]=L,p.promised=M,p.dispatch=R,m.prototype.dispatch=function(e,t){var n=this,r=h();return p.nextTick(function(){n.promiseDispatch(r.resolve,e,t)}),r.promise},p.get=function(e,t){return p(e).dispatch("get",[t])},m.prototype.get=function(e){return this.dispatch("get",[e])},p.set=function(e,t,n){return p(e).dispatch("set",[t,n])},m.prototype.set=function(e,t){return this.dispatch("set",[e,t])},p.del=p["delete"]=function(e,t){return p(e).dispatch("delete",[t])},m.prototype.del=m.prototype["delete"]=function(e){return this.dispatch("delete",[e])},p.mapply=p.post=function(e,t,n){return p(e).dispatch("post",[t,n])},m.prototype.mapply=m.prototype.post=function(e,t){return this.dispatch("post",[e,t])},p.send=p.mcall=p.invoke=function(e,t){return p(e).dispatch("post",[t,G(arguments,2)])},m.prototype.send=m.prototype.mcall=m.prototype.invoke=function(e){return this.dispatch("post",[e,G(arguments,1)])},p.fapply=function(e,t){return p(e).dispatch("apply",[void 0,t])},m.prototype.fapply=function(e){return this.dispatch("apply",[void 0,e])},p["try"]=p.fcall=function(e){return p(e).dispatch("apply",[void 0,G(arguments,1)])},m.prototype.fcall=function(){return this.dispatch("apply",[void 0,G(arguments)])},p.fbind=function(e){var t=p(e),n=G(arguments,1);return function(){return t.dispatch("apply",[this,n.concat(G(arguments))])}},m.prototype.fbind=function(){var e=this,t=G(arguments);return function(){return e.dispatch("apply",[this,t.concat(G(arguments))])}},p.keys=function(e){return p(e).dispatch("keys",[])},m.prototype.keys=function(){return this.dispatch("keys",[])},p.all=U,m.prototype.all=function(){return U(this)},p.any=P,m.prototype.any=function(){return P(this)},p.allResolved=c(q,"allResolved","allSettled"),m.prototype.allResolved=function(){return q(this)},p.allSettled=B,m.prototype.allSettled=function(){return this.then(function(e){return U(Z(e,function(e){function t(){return e.inspect()}return e=p(e),e.then(t,t)}))})},p.fail=p["catch"]=function(e,t){return p(e).then(void 0,t)},m.prototype.fail=m.prototype["catch"]=function(e){return this.then(void 0,e)},p.progress=N,m.prototype.progress=function(e){return this.then(void 0,void 0,e)},p.fin=p["finally"]=function(e,t){return p(e)["finally"](t)},m.prototype.fin=m.prototype["finally"]=function(e){return e=p(e),this.then(function(t){return e.fcall().then(function(){return t})},function(t){return e.fcall().then(function(){throw t})})},p.done=function(e,t,n,r){return p(e).done(t,n,r)},m.prototype.done=function(t,n,r){var a=function(e){p.nextTick(function(){if(i(e,o),!p.onerror)throw e;p.onerror(e)})},o=t||n||r?this.then(t,n,r):this;"object"==typeof e&&e&&e.domain&&(a=e.domain.bind(a)),o.then(void 0,a)},p.timeout=function(e,t,n){return p(e).timeout(t,n)},m.prototype.timeout=function(e,t){var n=h(),r=setTimeout(function(){t&&"string"!=typeof t||(t=new Error(t||"Timed out after "+e+" ms"),t.code="ETIMEDOUT"),n.reject(t)},e);return this.then(function(e){clearTimeout(r),n.resolve(e)},function(e){clearTimeout(r),n.reject(e)},n.notify),n.promise},p.delay=function(e,t){return void 0===t&&(t=e,e=void 0),p(e).delay(t)},m.prototype.delay=function(e){return this.then(function(t){var n=h();return setTimeout(function(){n.resolve(t)},e),n.promise})},p.nfapply=function(e,t){return p(e).nfapply(t)},m.prototype.nfapply=function(e){var t=h(),n=G(e);return n.push(t.makeNodeResolver()),this.fapply(n).fail(t.reject),t.promise},p.nfcall=function(e){var t=G(arguments,1);return p(e).nfapply(t)},m.prototype.nfcall=function(){var e=G(arguments),t=h();return e.push(t.makeNodeResolver()),this.fapply(e).fail(t.reject),t.promise},p.nfbind=p.denodeify=function(e){var t=G(arguments,1);return function(){var n=t.concat(G(arguments)),r=h();return n.push(r.makeNodeResolver()),p(e).fapply(n).fail(r.reject),r.promise}},m.prototype.nfbind=m.prototype.denodeify=function(){var e=G(arguments);return e.unshift(this),p.denodeify.apply(void 0,e)},p.nbind=function(e,t){var n=G(arguments,2);return function(){function r(){return e.apply(t,arguments)}var i=n.concat(G(arguments)),a=h();return i.push(a.makeNodeResolver()),p(r).fapply(i).fail(a.reject),a.promise}},m.prototype.nbind=function(){var e=G(arguments,0);return e.unshift(this),p.nbind.apply(void 0,e)},p.nmapply=p.npost=function(e,t,n){return p(e).npost(t,n)},m.prototype.nmapply=m.prototype.npost=function(e,t){var n=G(t||[]),r=h();return n.push(r.makeNodeResolver()),this.dispatch("post",[e,n]).fail(r.reject),r.promise},p.nsend=p.nmcall=p.ninvoke=function(e,t){var n=G(arguments,2),r=h();return n.push(r.makeNodeResolver()),p(e).dispatch("post",[t,n]).fail(r.reject),r.promise},m.prototype.nsend=m.prototype.nmcall=m.prototype.ninvoke=function(e){var t=G(arguments,1),n=h();return t.push(n.makeNodeResolver()),this.dispatch("post",[e,t]).fail(n.reject),n.promise},p.nodeify=z,m.prototype.nodeify=function(e){return e?void this.then(function(t){p.nextTick(function(){e(null,t)})},function(t){p.nextTick(function(){e(t)})}):this},p.noConflict=function(){throw new Error("Q.noConflict only works when Q is used as a global")};var ue=u();return p})}).call(this,e("_process"))},{_process:12}],158:[function(e,t,n){function r(){}function i(e){var t={}.toString.call(e);switch(t){case"[object File]":case"[object Blob]":case"[object FormData]":return!0;default:return!1}}function a(e){if(!b(e))return e;var t=[];for(var n in e)null!=e[n]&&o(t,n,e[n]);return t.join("&")}function o(e,t,n){return Array.isArray(n)?n.forEach(function(n){o(e,t,n)}):void e.push(encodeURIComponent(t)+"="+encodeURIComponent(n))}function s(e){for(var t,n,r={},i=e.split("&"),a=0,o=i.length;a<o;++a)n=i[a],t=n.split("="),r[decodeURIComponent(t[0])]=decodeURIComponent(t[1]);return r}function l(e){var t,n,r,i,a=e.split(/\r?\n/),o={};a.pop();for(var s=0,l=a.length;s<l;++s)n=a[s],t=n.indexOf(":"),r=n.slice(0,t).toLowerCase(),i=_(n.slice(t+1)),o[r]=i;return o}function u(e){return/[\/+]json\b/.test(e)}function c(e){return e.split(/ *; */).shift()}function p(e){return y(e.split(/ *; */),function(e,t){var n=t.split(/ *= */),r=n.shift(),i=n.shift();return r&&i&&(e[r]=i),e},{})}function h(e,t){t=t||{},this.req=e,this.xhr=this.req.xhr,this.text="HEAD"!=this.req.method&&(""===this.xhr.responseType||"text"===this.xhr.responseType)||"undefined"==typeof this.xhr.responseType?this.xhr.responseText:null,this.statusText=this.req.xhr.statusText,this.setStatusProperties(this.xhr.status),this.header=this.headers=l(this.xhr.getAllResponseHeaders()),this.header["content-type"]=this.xhr.getResponseHeader("content-type"),this.setHeaderProperties(this.header),this.body="HEAD"!=this.req.method?this.parseBody(this.text?this.text:this.xhr.response):null}function f(e,t){var n=this;this._query=this._query||[],this.method=e,this.url=t,this.header={},this._header={},this.on("end",function(){var e=null,t=null;try{t=new h(n)}catch(r){return e=new Error("Parser is unable to parse the response"),e.parse=!0,e.original=r,e.rawResponse=n.xhr&&n.xhr.responseText?n.xhr.responseText:null,e.statusCode=n.xhr&&n.xhr.status?n.xhr.status:null,n.callback(e)}if(n.emit("response",t),e)return n.callback(e,t);if(t.status>=200&&t.status<300)return n.callback(e,t);var i=new Error(t.statusText||"Unsuccessful HTTP response");i.original=e,i.response=t,i.status=t.status,n.callback(i,t)})}function d(e,t){var n=w("DELETE",e);return t&&n.end(t),n}var m,g=e("emitter"),y=e("reduce"),v=e("./request-base"),b=e("./is-object");m="undefined"!=typeof window?window:"undefined"!=typeof self?self:this;var w=t.exports=e("./request").bind(null,f);w.getXHR=function(){if(!(!m.XMLHttpRequest||m.location&&"file:"==m.location.protocol&&m.ActiveXObject))return new XMLHttpRequest;try{return new ActiveXObject("Microsoft.XMLHTTP")}catch(e){}try{return new ActiveXObject("Msxml2.XMLHTTP.6.0")}catch(e){}try{return new ActiveXObject("Msxml2.XMLHTTP.3.0")}catch(e){}try{return new ActiveXObject("Msxml2.XMLHTTP")}catch(e){}return!1};var _="".trim?function(e){return e.trim()}:function(e){return e.replace(/(^\s*|\s*$)/g,"")};w.serializeObject=a,w.parseString=s,w.types={html:"text/html",json:"application/json",xml:"application/xml",urlencoded:"application/x-www-form-urlencoded",form:"application/x-www-form-urlencoded","form-data":"application/x-www-form-urlencoded"},w.serialize={"application/x-www-form-urlencoded":a,"application/json":JSON.stringify},w.parse={"application/x-www-form-urlencoded":s,"application/json":JSON.parse},h.prototype.get=function(e){return this.header[e.toLowerCase()]},h.prototype.setHeaderProperties=function(e){var t=this.header["content-type"]||"";this.type=c(t);var n=p(t);for(var r in n)this[r]=n[r]},h.prototype.parseBody=function(e){var t=w.parse[this.type];return!t&&u(this.type)&&(t=w.parse["application/json"]),t&&e&&(e.length||e instanceof Object)?t(e):null},h.prototype.setStatusProperties=function(e){1223===e&&(e=204);var t=e/100|0;this.status=this.statusCode=e,this.statusType=t,this.info=1==t,this.ok=2==t,this.clientError=4==t,this.serverError=5==t,this.error=(4==t||5==t)&&this.toError(),this.accepted=202==e,this.noContent=204==e,this.badRequest=400==e,this.unauthorized=401==e,this.notAcceptable=406==e,this.notFound=404==e,this.forbidden=403==e},h.prototype.toError=function(){var e=this.req,t=e.method,n=e.url,r="cannot "+t+" "+n+" ("+this.status+")",i=new Error(r);return i.status=this.status,i.method=t,i.url=n,i},w.Response=h,g(f.prototype);for(var x in v)f.prototype[x]=v[x];f.prototype.abort=function(){if(!this.aborted)return this.aborted=!0,this.xhr.abort(),this.clearTimeout(),this.emit("abort"),this},f.prototype.type=function(e){return this.set("Content-Type",w.types[e]||e),this},f.prototype.responseType=function(e){return this._responseType=e,this},f.prototype.accept=function(e){return this.set("Accept",w.types[e]||e),this},f.prototype.auth=function(e,t,n){switch(n||(n={type:"basic"}),n.type){case"basic":var r=btoa(e+":"+t);this.set("Authorization","Basic "+r);break;case"auto":this.username=e,this.password=t}return this},f.prototype.query=function(e){return"string"!=typeof e&&(e=a(e)),e&&this._query.push(e),this},f.prototype.attach=function(e,t,n){return this._getFormData().append(e,t,n||t.name),this},f.prototype._getFormData=function(){return this._formData||(this._formData=new m.FormData),this._formData},f.prototype.send=function(e){var t=b(e),n=this._header["content-type"];if(t&&b(this._data))for(var r in e)this._data[r]=e[r];else"string"==typeof e?(n||this.type("form"),n=this._header["content-type"],"application/x-www-form-urlencoded"==n?this._data=this._data?this._data+"&"+e:e:this._data=(this._data||"")+e):this._data=e;return!t||i(e)?this:(n||this.type("json"),this)},h.prototype.parse=function(e){return m.console&&console.warn("Client-side parse() method has been renamed to serialize(). This method is not compatible with superagent v2.0"),this.serialize(e),this},h.prototype.serialize=function(e){return this._parser=e,this},f.prototype.callback=function(e,t){var n=this._callback;this.clearTimeout(),n(e,t)},f.prototype.crossDomainError=function(){var e=new Error("Request has been terminated\nPossible causes: the network is offline, Origin is not allowed by Access-Control-Allow-Origin, the page is being unloaded, etc.");e.crossDomain=!0,e.status=this.status,e.method=this.method,e.url=this.url,this.callback(e)},f.prototype.timeoutError=function(){var e=this._timeout,t=new Error("timeout of "+e+"ms exceeded");t.timeout=e,this.callback(t)},f.prototype.withCredentials=function(){return this._withCredentials=!0,this},f.prototype.end=function(e){var t=this,n=this.xhr=w.getXHR(),a=this._query.join("&"),o=this._timeout,s=this._formData||this._data;this._callback=e||r,n.onreadystatechange=function(){if(4==n.readyState){var e;try{e=n.status}catch(r){e=0}if(0==e){if(t.timedout)return t.timeoutError();if(t.aborted)return;return t.crossDomainError()}t.emit("end")}};var l=function(e){e.total>0&&(e.percent=e.loaded/e.total*100),e.direction="download",t.emit("progress",e)};this.hasListeners("progress")&&(n.onprogress=l);try{n.upload&&this.hasListeners("progress")&&(n.upload.onprogress=l)}catch(c){}if(o&&!this._timer&&(this._timer=setTimeout(function(){t.timedout=!0,t.abort()},o)),a&&(a=w.serializeObject(a),this.url+=~this.url.indexOf("?")?"&"+a:"?"+a),this.username&&this.password?n.open(this.method,this.url,!0,this.username,this.password):n.open(this.method,this.url,!0),this._withCredentials&&(n.withCredentials=!0),"GET"!=this.method&&"HEAD"!=this.method&&"string"!=typeof s&&!i(s)){var p=this._header["content-type"],h=this._parser||w.serialize[p?p.split(";")[0]:""];!h&&u(p)&&(h=w.serialize["application/json"]),h&&(s=h(s))}for(var f in this.header)null!=this.header[f]&&n.setRequestHeader(f,this.header[f]);return this._responseType&&(n.responseType=this._responseType),this.emit("request",this),n.send("undefined"!=typeof s?s:null),this},w.Request=f,w.get=function(e,t,n){var r=w("GET",e);return"function"==typeof t&&(n=t,t=null),t&&r.query(t),n&&r.end(n),r},w.head=function(e,t,n){var r=w("HEAD",e);return"function"==typeof t&&(n=t,t=null),t&&r.send(t),n&&r.end(n),r},w.del=d,w["delete"]=d,w.patch=function(e,t,n){
+var r=w("PATCH",e);return"function"==typeof t&&(n=t,t=null),t&&r.send(t),n&&r.end(n),r},w.post=function(e,t,n){var r=w("POST",e);return"function"==typeof t&&(n=t,t=null),t&&r.send(t),n&&r.end(n),r},w.put=function(e,t,n){var r=w("PUT",e);return"function"==typeof t&&(n=t,t=null),t&&r.send(t),n&&r.end(n),r}},{"./is-object":159,"./request":161,"./request-base":160,emitter:162,reduce:163}],159:[function(e,t,n){function r(e){return null!=e&&"object"==typeof e}t.exports=r},{}],160:[function(e,t,n){var r=e("./is-object");n.clearTimeout=function(){return this._timeout=0,clearTimeout(this._timer),this},n.parse=function(e){return this._parser=e,this},n.timeout=function(e){return this._timeout=e,this},n.then=function(e,t){return this.end(function(n,r){n?t(n):e(r)})},n.use=function(e){return e(this),this},n.get=function(e){return this._header[e.toLowerCase()]},n.getHeader=n.get,n.set=function(e,t){if(r(e)){for(var n in e)this.set(n,e[n]);return this}return this._header[e.toLowerCase()]=t,this.header[e]=t,this},n.unset=function(e){return delete this._header[e.toLowerCase()],delete this.header[e],this},n.field=function(e,t){return this._getFormData().append(e,t),this}},{"./is-object":159}],161:[function(e,t,n){function r(e,t,n){return"function"==typeof n?new e("GET",t).end(n):2==arguments.length?new e("GET",t):new e(t,n)}t.exports=r},{}],162:[function(e,t,n){function r(e){if(e)return i(e)}function i(e){for(var t in r.prototype)e[t]=r.prototype[t];return e}"undefined"!=typeof t&&(t.exports=r),r.prototype.on=r.prototype.addEventListener=function(e,t){return this._callbacks=this._callbacks||{},(this._callbacks["$"+e]=this._callbacks["$"+e]||[]).push(t),this},r.prototype.once=function(e,t){function n(){this.off(e,n),t.apply(this,arguments)}return n.fn=t,this.on(e,n),this},r.prototype.off=r.prototype.removeListener=r.prototype.removeAllListeners=r.prototype.removeEventListener=function(e,t){if(this._callbacks=this._callbacks||{},0==arguments.length)return this._callbacks={},this;var n=this._callbacks["$"+e];if(!n)return this;if(1==arguments.length)return delete this._callbacks["$"+e],this;for(var r,i=0;i<n.length;i++)if(r=n[i],r===t||r.fn===t){n.splice(i,1);break}return this},r.prototype.emit=function(e){this._callbacks=this._callbacks||{};var t=[].slice.call(arguments,1),n=this._callbacks["$"+e];if(n){n=n.slice(0);for(var r=0,i=n.length;r<i;++r)n[r].apply(this,t)}return this},r.prototype.listeners=function(e){return this._callbacks=this._callbacks||{},this._callbacks["$"+e]||[]},r.prototype.hasListeners=function(e){return!!this.listeners(e).length}},{}],163:[function(e,t,n){t.exports=function(e,t,n){for(var r=0,i=e.length,a=3==arguments.length?n:e[r++];r<i;)a=t.call(null,a,e[r],++r,e);return a}},{}]},{},[1])(1)}),window.SwaggerUi=Backbone.Router.extend({dom_id:"swagger_ui",options:null,api:null,headerView:null,mainView:null,initialize:function(e){e=e||{},"model"!==e.defaultModelRendering&&(e.defaultModelRendering="schema"),e.highlightSizeThreshold||(e.highlightSizeThreshold=1e5),e.dom_id&&(this.dom_id=e.dom_id,delete e.dom_id),e.supportedSubmitMethods||(e.supportedSubmitMethods=["get","put","post","delete","head","options","patch"]),"string"==typeof e.oauth2RedirectUrl&&(window.oAuthRedirectUrl=e.oauth2RedirectUrl),$("#"+this.dom_id).length||$("body").append('<div id="'+this.dom_id+'"></div>'),this.options=e,marked.setOptions({gfm:!0});var t=this;this.options.success=function(){return t.render()},this.options.progress=function(e){return t.showMessage(e)},this.options.failure=function(e){return t.onLoadFailure(e)},this.headerView=new SwaggerUi.Views.HeaderView({el:$("#header")}),this.headerView.on("update-swagger-ui",function(e){return t.updateSwaggerUi(e)}),JSONEditor.defaults.iconlibs.swagger=JSONEditor.AbstractIconLib.extend({mapping:{collapse:"collapse",expand:"expand"},icon_prefix:"swagger-"})},setOption:function(e,t){this.options[e]=t},getOption:function(e){return this.options[e]},updateSwaggerUi:function(e){this.options.url=e.url,this.load()},load:function(){this.mainView&&this.mainView.clear(),this.authView&&this.authView.remove();var e=this.options.url;e&&0!==e.indexOf("http")&&(e=this.buildUrl(window.location.href.toString(),e)),this.api&&(this.options.authorizations=this.api.clientAuthorizations.authz),this.options.url=e,this.headerView.update(e),this.api=new SwaggerClient(this.options)},collapseAll:function(){Docs.collapseEndpointListForResource("")},listAll:function(){Docs.collapseOperationsForResource("")},expandAll:function(){Docs.expandOperationsForResource("")},render:function(){var e;switch(this.showMessage("Finished Loading Resource Information. Rendering Swagger UI..."),this.mainView=new SwaggerUi.Views.MainView({model:this.api,el:$("#"+this.dom_id),swaggerOptions:this.options,router:this}).render(),_.isEmpty(this.api.securityDefinitions)||(e=_.map(this.api.securityDefinitions,function(e,t){var n={};return n[t]=e,n}),this.authView=new SwaggerUi.Views.AuthButtonView({data:SwaggerUi.utils.parseSecurityDefinitions(e),router:this}),$("#auth_container").append(this.authView.render().el)),this.showMessage(),this.options.docExpansion){case"full":this.expandAll();break;case"list":this.listAll()}this.renderGFM(),this.options.onComplete&&this.options.onComplete(this.api,this),setTimeout(Docs.shebang.bind(this),100)},buildUrl:function(e,t){if(0===t.indexOf("/")){var n=e.split("/");return e=n[0]+"//"+n[2],e+t}var r=e.length;return e.indexOf("?")>-1&&(r=Math.min(r,e.indexOf("?"))),e.indexOf("#")>-1&&(r=Math.min(r,e.indexOf("#"))),e=e.substring(0,r),e.indexOf("/",e.length-1)!==-1?e+t:e+"/"+t},showMessage:function(e){void 0===e&&(e="");var t=$("#message-bar");t.removeClass("message-fail"),t.addClass("message-success"),t.text(e),window.SwaggerTranslator&&window.SwaggerTranslator.translate(t)},onLoadFailure:function(e){void 0===e&&(e=""),$("#message-bar").removeClass("message-success"),$("#message-bar").addClass("message-fail");var t=$("#message-bar").text(e);return this.options.onFailure&&this.options.onFailure(e),t},renderGFM:function(){$(".markdown").each(function(){$(this).html(marked($(this).html()))}),$(".propDesc",".model-signature .description").each(function(){$(this).html(marked($(this).html())).addClass("markdown")})}}),window.SwaggerUi.Views={},window.SwaggerUi.Models={},window.SwaggerUi.Collections={},window.SwaggerUi.partials={},window.SwaggerUi.utils={},function(){function e(e){"console"in window&&"function"==typeof window.console.warn&&console.warn(e)}window.authorizations={add:function(){if(e("Using window.authorizations is deprecated. Please use SwaggerUi.api.clientAuthorizations.add()."),"undefined"==typeof window.swaggerUi)throw new TypeError("window.swaggerUi is not defined");window.swaggerUi instanceof SwaggerUi&&window.swaggerUi.api.clientAuthorizations.add.apply(window.swaggerUi.api.clientAuthorizations,arguments)}},window.ApiKeyAuthorization=function(){e("window.ApiKeyAuthorization is deprecated. Please use SwaggerClient.ApiKeyAuthorization."),SwaggerClient.ApiKeyAuthorization.apply(window,arguments)},window.PasswordAuthorization=function(){e("window.PasswordAuthorization is deprecated. Please use SwaggerClient.PasswordAuthorization."),SwaggerClient.PasswordAuthorization.apply(window,arguments)}}(),function(e,t){"function"==typeof define&&define.amd?define(["b"],function(n){return e.SwaggerUi=t(n)}):"object"==typeof exports?module.exports=t(require("b")):e.SwaggerUi=t(e.b)}(this,function(){return SwaggerUi}),window.SwaggerUi.utils={parseSecurityDefinitions:function(e){var t=Object.assign({},window.swaggerUi.api.authSchemes||window.swaggerUi.api.securityDefinitions),n=[],r=[],i=[],a=window.SwaggerUi.utils;return Array.isArray(e)?(e.forEach(function(e){var o={},s={};for(var l in e)if(Array.isArray(e[l])){if(!t[l])continue;if(t[l]=t[l]||{},"oauth2"===t[l].type){s[l]=Object.assign({},t[l]),s[l].scopes=Object.assign({},t[l].scopes);for(var u in s[l].scopes)e[l].indexOf(u)<0&&delete s[l].scopes[u];s[l].scopes=a.parseOauth2Scopes(s[l].scopes),i=_.merge(i,s[l].scopes)}else o[l]=Object.assign({},t[l])}else"oauth2"===e[l].type?(s[l]=Object.assign({},e[l]),s[l].scopes=a.parseOauth2Scopes(s[l].scopes),i=_.merge(i,s[l].scopes)):o[l]=e[l];_.isEmpty(o)||r.push(o),_.isEmpty(s)||n.push(s)}),{auths:r,oauth2:n,scopes:i}):null},parseOauth2Scopes:function(e){var t,n=Object.assign({},e),r=[];for(t in n)r.push({scope:t,description:n[t]});return r},sanitize:function(e){return e=e.replace(/<script\b[^<]*(?:(?!<\/script>)<[^<]*)*<\/script>/gi,""),e=e.replace(/(on\w+="[^"]*")*(on\w+='[^']*')*(on\w+=\w*\(\w*\))*/gi,"")}},SwaggerUi.Models.ApiKeyAuthModel=Backbone.Model.extend({defaults:{"in":"",name:"",title:"",value:""},initialize:function(){this.on("change",this.validate)},validate:function(){var e=!!this.get("value");return this.set("valid",e),e}}),SwaggerUi.Views.ApiKeyAuthView=Backbone.View.extend({events:{"change .input_apiKey_entry":"apiKeyChange"},selectors:{apikeyInput:".input_apiKey_entry"},template:Handlebars.templates.apikey_auth,initialize:function(e){this.options=e||{},this.router=this.options.router},render:function(){return this.$el.html(this.template(this.model.toJSON())),this},apiKeyChange:function(e){var t=$(e.target).val();t&&this.$(this.selectors.apikeyInput).removeClass("error"),this.model.set("value",t)},isValid:function(){return this.model.validate()},highlightInvalid:function(){this.isValid()||this.$(this.selectors.apikeyInput).addClass("error")}}),SwaggerUi.Views.AuthButtonView=Backbone.View.extend({events:{"click .authorize__btn":"authorizeBtnClick"},tpls:{popup:Handlebars.templates.popup,authBtn:Handlebars.templates.auth_button,authBtnOperation:Handlebars.templates.auth_button_operation},initialize:function(e){this.options=e||{},this.options.data=this.options.data||{},this.isOperation=this.options.isOperation,this.model=this.model||{},this.router=this.options.router,this.auths=this.options.data.oauth2.concat(this.options.data.auths)},render:function(){var e=this.isOperation?"authBtnOperation":"authBtn";return this.$authEl=this.renderAuths(this.auths),this.$el.html(this.tpls[e](this.model)),this},authorizeBtnClick:function(e){var t;e.preventDefault(),t={title:"Available authorizations",content:this.$authEl},this.render(),this.popup=new SwaggerUi.Views.PopupView({model:t}),this.popup.render()},renderAuths:function(e){var t=$("<div>"),n=!1;return e.forEach(function(e){var r=new SwaggerUi.Views.AuthView({data:e,router:this.router}),i=r.render().el;t.append(i),r.isLogout&&(n=!0)},this),this.model.isLogout=n,t}}),SwaggerUi.Collections.AuthsCollection=Backbone.Collection.extend({constructor:function(){var e=Array.prototype.slice.call(arguments);e[0]=this.parse(e[0]),Backbone.Collection.apply(this,e)},add:function(e){var t=Array.prototype.slice.call(arguments);Array.isArray(e)?t[0]=_.map(e,function(e){return this.handleOne(e)},this):t[0]=this.handleOne(e),Backbone.Collection.prototype.add.apply(this,t)},handleOne:function(e){var t=e;if(!(e instanceof Backbone.Model))switch(e.type){case"oauth2":t=new SwaggerUi.Models.Oauth2Model(e);break;case"basic":t=new SwaggerUi.Models.BasicAuthModel(e);break;case"apiKey":t=new SwaggerUi.Models.ApiKeyAuthModel(e);break;default:t=new Backbone.Model(e)}return t},isValid:function(){var e=!0;return this.models.forEach(function(t){t.validate()||(e=!1)}),e},isAuthorized:function(){return this.length===this.where({isLogout:!0}).length},isPartiallyAuthorized:function(){return this.where({isLogout:!0}).length>0},parse:function(e){var t=Object.assign({},window.swaggerUi.api.clientAuthorizations.authz);return _.map(e,function(e,n){var r=t[n]&&"basic"===e.type&&t[n].username&&t[n].password;return _.extend(e,{title:n}),(t[n]||r)&&_.extend(e,{isLogout:!0,value:r?void 0:t[n].value,username:r?t[n].username:void 0,password:r?t[n].password:void 0,valid:!0}),e})}}),SwaggerUi.Views.AuthsCollectionView=Backbone.View.extend({initialize:function(e){this.options=e||{},this.options.data=this.options.data||{},this.router=this.options.router,this.collection=new SwaggerUi.Collections.AuthsCollection(e.data),this.$innerEl=$("<div>"),this.authViews=[]},render:function(){return this.collection.each(function(e){this.renderOneAuth(e)},this),this.$el.html(this.$innerEl.html()?this.$innerEl:""),this},renderOneAuth:function(e){var t,n,r,i=e.get("type");"apiKey"===i?r="ApiKeyAuthView":"basic"===i&&0===this.$innerEl.find(".basic_auth_container").length?r="BasicAuthView":"oauth2"===i&&(r="Oauth2View"),r&&(n=new SwaggerUi.Views[r]({model:e,router:this.router}),t=n.render().el,this.authViews.push(n)),this.$innerEl.append(t)},highlightInvalid:function(){this.authViews.forEach(function(e){e.highlightInvalid()},this)}}),SwaggerUi.Views.AuthView=Backbone.View.extend({events:{"click .auth_submit__button":"authorizeClick","click .auth_logout__button":"logoutClick"},tpls:{main:Handlebars.templates.auth_view},selectors:{innerEl:".auth_inner",authBtn:".auth_submit__button"},initialize:function(e){this.options=e||{},e.data=e.data||{},this.router=this.options.router,this.authsCollectionView=new SwaggerUi.Views.AuthsCollectionView({data:e.data}),this.$el.html(this.tpls.main({isLogout:this.authsCollectionView.collection.isAuthorized(),isAuthorized:this.authsCollectionView.collection.isPartiallyAuthorized()})),this.$innerEl=this.$(this.selectors.innerEl),this.isLogout=this.authsCollectionView.collection.isPartiallyAuthorized()},render:function(){return this.$innerEl.html(this.authsCollectionView.render().el),this},authorizeClick:function(e){e.preventDefault(),e.stopPropagation(),this.authsCollectionView.collection.isValid()?this.authorize():this.authsCollectionView.highlightInvalid()},authorize:function(){this.authsCollectionView.collection.forEach(function(e){var t,n,r=e.get("type");"apiKey"===r?(t=new SwaggerClient.ApiKeyAuthorization(e.get("name"),e.get("value"),e.get("in")),this.router.api.clientAuthorizations.add(e.get("title"),t)):"basic"===r?(n=new SwaggerClient.PasswordAuthorization(e.get("username"),e.get("password")),this.router.api.clientAuthorizations.add(e.get("title"),n)):"oauth2"===r&&this.handleOauth2Login(e)},this),this.router.load()},logoutClick:function(e){e.preventDefault(),this.authsCollectionView.collection.forEach(function(e){window.swaggerUi.api.clientAuthorizations.remove(e.get("title"))}),this.router.load()},handleOauth2Login:function(e){var t,n,r,i=window.location,a=location.pathname.substring(0,location.pathname.lastIndexOf("/")),o=i.protocol+"//"+i.host+a+"/o2c.html",s=window.oAuthRedirectUrl||o,l=null,u=_.map(e.get("scopes"),function(e){return e.scope});window.OAuthSchemeKey=e.get("title"),window.enabledScopes=u;var c=e.get("flow");if("oauth2"!==e.get("type")||!c||"implicit"!==c&&"accessCode"!==c){if("oauth2"===e.get("type")&&c&&"application"===c)return n=e.attributes,window.swaggerUi.tokenName=n.tokenName||"access_token",void this.clientCredentialsFlow(u,n.tokenUrl,window.OAuthSchemeKey);if(e.get("grantTypes")){var p=e.get("grantTypes");for(var h in p)p.hasOwnProperty(h)&&"implicit"===h?(n=p[h],r=n.loginEndpoint.url,l=n.loginEndpoint.url+"?response_type=token",window.swaggerUi.tokenName=n.tokenName):p.hasOwnProperty(h)&&"accessCode"===h&&(n=p[h],r=n.tokenRequestEndpoint.url,l=n.tokenRequestEndpoint.url+"?response_type=code",window.swaggerUi.tokenName=n.tokenName)}}else n=e.attributes,l=n.authorizationUrl+"?response_type="+("implicit"===c?"token":"code"),window.swaggerUi.tokenName=n.tokenName||"access_token",window.swaggerUi.tokenUrl="accessCode"===c?n.tokenUrl:null,t=window.OAuthSchemeKey;redirect_uri=s,l+="&redirect_uri="+encodeURIComponent(s),l+="&realm="+encodeURIComponent(realm),l+="&client_id="+encodeURIComponent(clientId),l+="&scope="+encodeURIComponent(u.join(scopeSeparator)),l+="&state="+encodeURIComponent(t);for(var f in additionalQueryStringParams)l+="&"+f+"="+encodeURIComponent(additionalQueryStringParams[f]);window.open(l)},clientCredentialsFlow:function(e,t,n){var r={client_id:clientId,client_secret:clientSecret,scope:e.join(" "),grant_type:"client_credentials"};$.ajax({url:t,type:"POST",data:r,success:function(e){onOAuthComplete(e,n)},error:function(){onOAuthComplete("")}})}}),SwaggerUi.Models.BasicAuthModel=Backbone.Model.extend({defaults:{username:"",password:"",title:"basic"},initialize:function(){this.on("change",this.validate)},validate:function(){var e=!!this.get("password")&&!!this.get("username");return this.set("valid",e),e}}),SwaggerUi.Views.BasicAuthView=Backbone.View.extend({initialize:function(e){this.options=e||{},this.router=this.options.router},events:{"change .auth_input":"inputChange"},selectors:{usernameInput:".basic_auth__username",passwordInput:".basic_auth__password"},cls:{error:"error"},template:Handlebars.templates.basic_auth,render:function(){return $(this.el).html(this.template(this.model.toJSON())),this},inputChange:function(e){var t=$(e.target),n=t.val(),r=t.prop("name");n&&t.removeClass(this.cls.error),this.model.set(r,n)},isValid:function(){return this.model.validate()},highlightInvalid:function(){this.model.get("username")||this.$(this.selectors.usernameInput).addClass(this.cls.error)}}),SwaggerUi.Views.ContentTypeView=Backbone.View.extend({initialize:function(){},render:function(){return this.model.contentTypeId="ct"+Math.random(),$(this.el).html(Handlebars.templates.content_type(this.model)),this}}),SwaggerUi.Views.HeaderView=Backbone.View.extend({events:{"click #show-pet-store-icon":"showPetStore","click #explore":"showCustom","submit #api_selector":"showCustom","keyup #input_baseUrl":"showCustomOnKeyup","keyup #input_apiKey":"showCustomOnKeyup"},initialize:function(){},showPetStore:function(){this.trigger("update-swagger-ui",{url:"http://petstore.swagger.io/v2/swagger.json"})},showCustomOnKeyup:function(e){13===e.keyCode&&this.showCustom()},showCustom:function(e){e&&e.preventDefault(),this.trigger("update-swagger-ui",{url:$("#input_baseUrl").val()})},update:function(e,t,n){void 0===n&&(n=!1),$("#input_baseUrl").val(e),n&&this.trigger("update-swagger-ui",{url:e})}}),SwaggerUi.Views.MainView=Backbone.View.extend({apisSorter:{alpha:function(e,t){return e.name.localeCompare(t.name)}},operationsSorters:{alpha:function(e,t){return e.path.localeCompare(t.path)},method:function(e,t){return e.method.localeCompare(t.method)}},initialize:function(e){var t,n,r,i;if(e=e||{},this.router=e.router,e.swaggerOptions.apisSorter&&(t=e.swaggerOptions.apisSorter,n=_.isFunction(t)?t:this.apisSorter[t],_.isFunction(n)&&this.model.apisArray.sort(n)),e.swaggerOptions.operationsSorter&&(t=e.swaggerOptions.operationsSorter,n=_.isFunction(t)?t:this.operationsSorters[t],_.isFunction(n)))for(r in this.model.apisArray)this.model.apisArray[r].operationsArray.sort(n);this.model.auths=[];for(r in this.model.securityDefinitions)i=this.model.securityDefinitions[r],this.model.auths.push({name:r,type:i.type,value:i});"validatorUrl"in e.swaggerOptions?this.model.validatorUrl=e.swaggerOptions.validatorUrl:this.model.url.indexOf("localhost")>0||this.model.url.indexOf("127.0.0.1")>0?this.model.validatorUrl=null:this.model.validatorUrl="//online.swagger.io/validator";var a;for(a in this.model.definitions)this.model.definitions[a].type||(this.model.definitions[a].type="object")},render:function(){$(this.el).html(Handlebars.templates.main(this.model)),this.info=this.$(".info")[0],this.info&&this.info.addEventListener("click",this.onLinkClick,!0),this.model.securityDefinitions=this.model.securityDefinitions||{};for(var e={},t=0,n=0;n<this.model.apisArray.length;n++){for(var r=this.model.apisArray[n],i=r.name;"undefined"!=typeof e[i];)i=i+"_"+t,t+=1;r.id=sanitizeHtml(i),e[i]=r,this.addResource(r,this.model.auths)}return $(".propWrap").hover(function(){$(".optionsWrapper",$(this)).show()},function(){$(".optionsWrapper",$(this)).hide()}),this},addResource:function(e,t){e.id=e.id.replace(/\s/g,"_"),e.definitions=this.model.definitions;var n=new SwaggerUi.Views.ResourceView({model:e,router:this.router,tagName:"li",id:"resource_"+e.id,className:"resource",auths:t,swaggerOptions:this.options.swaggerOptions});$("#resources",this.el).append(n.render().el)},clear:function(){$(this.el).html("")},onLinkClick:function(e){var t=e.target;"A"===t.tagName&&t.href&&!t.target&&(e.preventDefault(),window.open(t.href,"_blank"))}}),SwaggerUi.Models.Oauth2Model=Backbone.Model.extend({defaults:{scopes:{}},initialize:function(){this.on("change",this.validate)},setScopes:function(e,t){var n=_.extend({},this.attributes),r=_.findIndex(n.scopes,function(t){return t.scope===e});n.scopes[r].checked=t,this.set(n),this.validate()},validate:function(){var e=!1,t=this.get("scopes"),n=_.findIndex(t,function(e){return e.checked===!0});return t.length>0&&n>=0&&(e=!0),0===t.length&&(e=!0),this.set("valid",e),e}}),SwaggerUi.Views.Oauth2View=Backbone.View.extend({events:{"change .oauth-scope":"scopeChange"},template:Handlebars.templates.oauth2,render:function(){return this.$el.html(this.template(this.model.toJSON())),this},scopeChange:function(e){var t=$(e.target).prop("checked"),n=$(e.target).data("scope");this.model.setScopes(n,t)}}),SwaggerUi.Views.OperationView=Backbone.View.extend({invocationUrl:null,events:{"submit .sandbox":"submitOperation","click .submit":"submitOperation","click .response_hider":"hideResponse","click .toggleOperation":"toggleOperationContent","mouseenter .api-ic":"mouseEnter","dblclick .curl":"selectText","change [name=responseContentType]":"showSnippet"},initialize:function(e){return e=e||{},this.router=e.router,this.auths=e.auths,this.parentId=this.model.parentId,this.nickname=this.model.nickname,this.model.encodedParentId=encodeURIComponent(this.parentId),e.swaggerOptions&&(this.model.defaultRendering=e.swaggerOptions.defaultModelRendering,e.swaggerOptions.showRequestHeaders&&(this.model.showRequestHeaders=!0)),this},selectText:function(e){var t,n,r=document,i=e.target.firstChild;r.body.createTextRange?(t=document.body.createTextRange(),t.moveToElementText(i),t.select()):window.getSelection&&(n=window.getSelection(),t=document.createRange(),t.selectNodeContents(i),n.removeAllRanges(),n.addRange(t))},mouseEnter:function(e){var t=$(this.el).find(".content"),n=e.pageX,r=e.pageY,i=$(window).scrollLeft(),a=$(window).scrollTop(),o=i+$(window).width(),s=a+$(window).height(),l=t.width(),u=t.height();n+l>o&&(n=o-l),n<i&&(n=i),r+u>s&&(r=s-u),r<a&&(r=a);var c={};c.top=r,c.left=n,t.css(c)},render:function(){var e,t,n,r,i,a,o,s,l,u,c,p,h,f,d,m,g,y,v,b,w,x,A,S,j,E,O,k,T,C,I,D,L,M,R,U,P,q,B,N,z;if(a=jQuery.inArray(this.model.method,this.model.supportedSubmitMethods())>=0,a||(this.model.isReadOnly=!0),this.model.description=this.model.description||this.model.notes,this.model.oauth=null,m=this.model.authorizations||this.model.security)if(Array.isArray(m))for(l=0,u=m.length;l<u;l++){n=m[l];for(s in n)for(e in this.auths)if(t=this.auths[e],s===t.name&&"oauth2"===t.type){this.model.oauth={},this.model.oauth.scopes=[],A=t.value.scopes;for(o in A)P=A[o],D=n[s].indexOf(o),D>=0&&(y={scope:o,description:P},this.model.oauth.scopes.push(y))}}else for(o in m)if(P=m[o],"oauth2"===o)for(null===this.model.oauth&&(this.model.oauth={}),void 0===this.model.oauth.scopes&&(this.model.oauth.scopes=[]),d=0,c=P.length;d<c;d++)y=P[d],this.model.oauth.scopes.push(y);if("undefined"!=typeof this.model.responses){this.model.responseMessages=[],S=this.model.responses;for(r in S)q=S[r],C=null,I=this.model.responses[r].schema,I&&I.$ref&&(C=I.$ref,C.indexOf("#/definitions/")!==-1&&(C=C.replace(/^.*#\/definitions\//,""))),this.model.responseMessages.push({code:r,message:q.description,responseModel:C,headers:q.headers,schema:I})}if("undefined"==typeof this.model.responseMessages&&(this.model.responseMessages=[]),L=null,B=this.model.produces,N=this.contains(B,"xml"),z=!N||this.contains(B,"json"),this.model.successResponse){R=this.model.successResponse;for(s in R)q=R[s],this.model.successCode=s,"object"==typeof q&&"function"==typeof q.createJSONSample?(this.model.successDescription=q.description,this.model.headers=this.parseResponseHeaders(q.headers),L={sampleJSON:!!z&&JSON.stringify(SwaggerUi.partials.signature.createJSONSample(q),void 0,2),isParam:!1,sampleXML:!!N&&SwaggerUi.partials.signature.createXMLSample(q.name,q.definition,q.models),signature:SwaggerUi.partials.signature.getModelSignature(q.name,q.definition,q.models,q.modelPropertyMacro)}):L={signature:SwaggerUi.partials.signature.getPrimitiveSignature(q)}}else this.model.responseClassSignature&&"string"!==this.model.responseClassSignature&&(L={sampleJSON:this.model.responseSampleJSON,isParam:!1,signature:this.model.responseClassSignature});for($(this.el).html(Handlebars.templates.operation(this.model)),L?(L.defaultRendering=this.model.defaultRendering,T=new SwaggerUi.Views.SignatureView({model:L,router:this.router,tagName:"div"}),$(".model-signature",$(this.el)).append(T.render().el)):(this.model.responseClassSignature="string",$(".model-signature",$(this.el)).html(this.model.type)),i={isParam:!1},i.consumes=this.model.consumes,i.produces=this.model.produces,j=this.model.parameters,g=0,p=j.length;g<p;g++)b=j[g],U=b.type||b.dataType||"","undefined"==typeof U&&(C=b.schema,C&&C.$ref&&(x=C.$ref,U=0===x.indexOf("#/definitions/")?x.substring("#/definitions/".length):x)),U&&"file"===U.toLowerCase()&&(i.consumes||(i.consumes="multipart/form-data")),b.type=U;for(k=new SwaggerUi.Views.ResponseContentTypeView({model:i,router:this.router}),$(".response-content-type",$(this.el)).append(k.render().el),E=this.model.parameters,v=0,h=E.length;v<h;v++)b=E[v],this.addParameter(b,i.consumes);for(O=this.model.responseMessages,w=0,f=O.length;w<f;w++)M=O[w],M.isXML=N,M.isJSON=z,_.isUndefined(M.headers)||(M.headers=this.parseHeadersType(M.headers)),this.addStatusCode(M);if(Array.isArray(this.model.security)){var F=SwaggerUi.utils.parseSecurityDefinitions(this.model.security);F.isLogout=!_.isEmpty(window.swaggerUi.api.clientAuthorizations.authz),this.authView=new SwaggerUi.Views.AuthButtonView({data:F,router:this.router,isOperation:!0,model:{scopes:F.scopes}}),this.$(".authorize-wrapper").append(this.authView.render().el)}return this.showSnippet(),this},parseHeadersType:function(e){var t={string:{"date-time":"dateTime",date:"date"}};return _.forEach(e,function(e){var n;e=e||{},n=t[e.type]&&t[e.type][e.format],_.isUndefined(n)||(e.type=n)}),e},contains:function(e,t){return e.filter(function(e){if(e.indexOf(t)>-1)return!0}).length},parseResponseHeaders:function(e){var t="; ",n=_.clone(e);return _.forEach(n,function(e){var n=[];_.forEach(e,function(e,t){var r=["type","description"];r.indexOf(t.toLowerCase())===-1&&n.push(t+": "+e)}),n.join(t),e.other=n}),n},addParameter:function(e,t){e.consumes=t,e.defaultRendering=this.model.defaultRendering,e.schema&&($.extend(!0,e.schema,this.model.definitions[e.type]),e.schema.definitions=this.model.definitions,e.schema.type||(e.schema.type="object"),e.schema.title||(e.schema.title=" "));var n=new SwaggerUi.Views.ParameterView({model:e,tagName:"tr",readOnly:this.model.isReadOnly,swaggerOptions:this.options.swaggerOptions});$(".operation-params",$(this.el)).append(n.render().el)},addStatusCode:function(e){e.defaultRendering=this.model.defaultRendering;var t=new SwaggerUi.Views.StatusCodeView({model:e,tagName:"tr",router:this.router});$(".operation-status",$(this.el)).append(t.render().el)},submitOperation:function(e){var t,n,r,i,a;if(null!==e&&e.preventDefault(),n=$(".sandbox",$(this.el)),t=!0,n.find("input.required").each(function(){$(this).removeClass("error"),""===jQuery.trim($(this).val())&&($(this).addClass("error"),$(this).wiggle({callback:function(e){return function(){$(e).focus()}}(this)}),t=!1)}),n.find("textarea.required:visible").each(function(){$(this).removeClass("error"),""===jQuery.trim($(this).val())&&($(this).addClass("error"),$(this).wiggle({callback:function(e){return function(){return $(e).focus()}}(this)}),t=!1)}),n.find("select.required").each(function(){$(this).removeClass("error"),this.selectedIndex===-1&&($(this).addClass("error"),$(this).wiggle({callback:function(e){return function(){$(e).focus()}}(this)}),t=!1)}),t){if(i=this.getInputMap(n),r=this.isFileUpload(n),a={parent:this},this.options.swaggerOptions)for(var o in this.options.swaggerOptions)a[o]=this.options.swaggerOptions[o];var s;for(s=0;s<this.model.parameters.length;s++){var l=this.model.parameters[s];if(l.jsonEditor&&l.jsonEditor.isEnabled()){var u=l.jsonEditor.getValue();i[l.name]=JSON.stringify(u)}}return a.responseContentType=$("div select[name=responseContentType]",$(this.el)).val(),a.requestContentType=$("div select[name=parameterContentType]",$(this.el)).val(),$(".response_throbber",$(this.el)).show(),r?($(".request_url",$(this.el)).html("<pre></pre>"),$(".request_url pre",$(this.el)).text(this.invocationUrl),a.useJQuery=!0,i.parameterContentType="multipart/form-data",this.map=i,this.model.execute(i,a,this.showCompleteStatus,this.showErrorStatus,this)):(this.map=i,this.model.execute(i,a,this.showCompleteStatus,this.showErrorStatus,this))}},getInputMap:function(e){var t,n,r,i,a,o,s,l,u,c,p,h;for(t={},n=e.find("input"),r=0,i=n.length;r<i;r++)a=n[r],null!==a.value&&jQuery.trim(a.value).length>0&&(t[a.name]=a.value),"file"===a.type&&(t[a.name]=a.files[0]);for(o=e.find("textarea"),s=0,l=o.length;s<l;s++)a=o[s],u=this.getTextAreaValue(a),null!==u&&jQuery.trim(u).length>0&&(t[a.name]=u);for(c=e.find("select"),p=0,h=c.length;p<h;p++)a=c[p],u=this.getSelectedValue(a),null!==u&&jQuery.trim(u).length>0&&(t[a.name]=u);return t},isFileUpload:function(e){var t,n,r,i,a=!1;for(t=e.find("input"),n=0,r=t.length;n<r;n++)i=t[n],"file"===i.type&&(a=!0);return a},success:function(e,t){t.showCompleteStatus(e)},wrap:function(e){var t,n,r,i,a,o,s;for(r={},n=e.getAllResponseHeaders().split("\r"),a=0,o=n.length;a<o;a++)i=n[a],t=i.match(/^([^:]*?):(.*)$/),t||(t=[]),t.shift(),void 0!==t[0]&&void 0!==t[1]&&(r[t[0].trim()]=t[1].trim());return s={},s.content={},s.content.data=e.responseText,s.headers=r,s.request={},s.request.url=this.invocationUrl,s.status=e.status,s},getSelectedValue:function(e){if(e.multiple){for(var t=[],n=0,r=e.options.length;n<r;n++){var i=e.options[n];i.selected&&t.push(i.value)}return t.length>0?t:null}return e.value},hideResponse:function(e){e&&e.preventDefault(),$(".response",$(this.el)).slideUp(),$(".response_hider",$(this.el)).fadeOut()},showResponse:function(e){var t=JSON.stringify(e,null,"\t").replace(/\n/g,"<br>");$(".response_body",$(this.el)).html(_.escape(t))},showErrorStatus:function(e,t){t.showStatus(e)},showCompleteStatus:function(e,t){t.showStatus(e)},formatXml:function(e){var t,n,r,i,a,o,s,l,u,c,p,h,f;for(p=/(>)(<)(\/*)/g,f=/[ ]*(.*)[ ]+\n/g,t=/(<.+>)(.+\n)/g,e=e.replace(/\r\n/g,"\n").replace(p,"$1\n$2$3").replace(f,"$1\n").replace(t,"$1\n$2"),c=0,r="",l=e.split("\n"),i=0,o="other",h={"single->single":0,"single->closing":-1,"single->opening":0,"single->other":0,"closing->single":0,"closing->closing":-1,"closing->opening":0,"closing->other":0,"opening->single":1,"opening->closing":0,"opening->opening":1,"opening->other":1,"other->single":0,"other->closing":-1,"other->opening":0,"other->other":0},n=function(e){var t,n,a,s,l,u,c;u={single:Boolean(e.match(/<.+\/>/)),closing:Boolean(e.match(/<\/.+>/)),opening:Boolean(e.match(/<[^!?].*>/))},l=function(){var e;e=[];for(a in u)c=u[a],c&&e.push(a);return e}()[0],l=void 0===l?"other":l,t=o+"->"+l,o=l,s="",i+=h[t],s=function(){var e,t,r;for(r=[],n=e=0,t=i;0<=t?e<t:e>t;n=0<=t?++e:--e)r.push(" ");return r}().join(""),"opening->closing"===t?r=r.substr(0,r.length-1)+e+"\n":r+=s+e+"\n"},a=0,s=l.length;a<s;a++)u=l[a],n(u);return r},showStatus:function(e){var t,n;void 0===e.content?(n=e.data,t=e.url):(n=e.content.data,t=e.request.url);var r=e.headers;n=jQuery.trim(n);var i=null;r&&(i=r["Content-Type"]||r["content-type"],i&&(i=i.split(";")[0].trim())),$(".response_body",$(this.el)).removeClass("json"),$(".response_body",$(this.el)).removeClass("xml");var a,o,s=function(e){var t=document.createElement("audio");return!(!t.canPlayType||!t.canPlayType(e).replace(/no/,""))};if(n)if("application/json"===i||/\+json$/.test(i)){var l=null;
+try{l=JSON.stringify(JSON.parse(n),null," ")}catch(u){l="can't parse JSON. Raw result:\n\n"+n}o=$("<code />").text(l),a=$('<pre class="json" />').append(o)}else if("application/xml"===i||/\+xml$/.test(i))o=$("<code />").text(this.formatXml(n)),a=$('<pre class="xml" />').append(o);else if("text/html"===i)o=$("<code />").html(_.escape(n)),a=$('<pre class="xml" />').append(o);else if(/text\/plain/.test(i))o=$("<code />").text(n),a=$('<pre class="plain" />').append(o);else if(/^image\//.test(i))a=$("<img>").attr("src",t);else if(/^audio\//.test(i)&&s(i))a=$("<audio controls>").append($("<source>").attr("src",t).attr("type",i));else if(r["Content-Disposition"]&&/attachment/.test(r["Content-Disposition"])||r["content-disposition"]&&/attachment/.test(r["content-disposition"])||r["Content-Description"]&&/File Transfer/.test(r["Content-Description"])||r["content-description"]&&/File Transfer/.test(r["content-description"]))if("Blob"in window){var c=i||"text/html",p=new Blob([n],{type:c}),h=document.createElement("a"),f=window.URL.createObjectURL(p),d=e.url.substr(e.url.lastIndexOf("/")+1),m=[c,d,f].join(":"),g=r["content-disposition"]||r["Content-Disposition"];if("undefined"!=typeof g){var y=/filename=([^;]*);?/.exec(g);null!==y&&y.length>1&&(m=y[1])}h.setAttribute("href",f),h.setAttribute("download",m),h.innerText="Download "+d,a=$("<div/>").append(h)}else a=$('<pre class="json" />').append("Download headers detected but your browser does not support downloading binary via XHR (Blob).");else r.location||r.Location?window.location=e.url:(o=$("<code />").text(n),a=$('<pre class="json" />').append(o));else o=$("<code />").text("no content"),a=$('<pre class="json" />').append(o);var v=a;$(".request_url",$(this.el)).html("<pre></pre>"),$(".request_url pre",$(this.el)).text(t),$(".response_code",$(this.el)).html("<pre>"+e.status+"</pre>"),$(".response_body",$(this.el)).html(v),$(".response_headers",$(this.el)).html("<pre>"+_.escape(JSON.stringify(e.headers,null," ")).replace(/\n/g,"<br>")+"</pre>"),$(".response",$(this.el)).slideDown(),$(".response_hider",$(this.el)).show(),$(".response_throbber",$(this.el)).hide();var b=this.model.asCurl(this.map,{responseContentType:i});b=b.replace("!","&#33;"),$("div.curl",$(this.el)).html("<pre>"+_.escape(b)+"</pre>");var w=this.options.swaggerOptions;if(w.showRequestHeaders){var x=$(".sandbox",$(this.el)),A=this.getInputMap(x),S=this.model.getHeaderParams(A);delete S["Content-Type"],$(".request_headers",$(this.el)).html("<pre>"+_.escape(JSON.stringify(S,null," ")).replace(/\n/g,"<br>")+"</pre>")}var j=$(".response_body",$(this.el))[0];return w.highlightSizeThreshold&&"undefined"!=typeof e.data&&e.data.length>w.highlightSizeThreshold?j:hljs.highlightBlock(j)},toggleOperationContent:function(e){var t=$("#"+Docs.escapeResourceName(this.parentId+"_"+this.nickname+"_content"));t.is(":visible")?($.bbq.pushState("#/",2),e.preventDefault(),Docs.collapseOperation(t)):Docs.expandOperation(t)},getTextAreaValue:function(e){var t,n,r,i;if(null===e.value||0===jQuery.trim(e.value).length)return null;if(t=this.getParamByName(e.name),t&&t.type&&"array"===t.type.toLowerCase()){for(n=e.value.split("\n"),r=[],i=0;i<n.length;i++)null!==n[i]&&jQuery.trim(n[i]).length>0&&r.push(n[i]);return r.length>0?r:null}return e.value},showSnippet:function(){var e,t=this.$("[name=responseContentType]"),n=this.$(".operation-status .snippet_xml, .response-class .snippet_xml"),r=this.$(".operation-status .snippet_json, .response-class .snippet_json");t.length&&(e=t.val(),e.indexOf("xml")>-1?(n.show(),r.hide()):(r.show(),n.hide()))},getParamByName:function(e){var t;if(this.model.parameters)for(t=0;t<this.model.parameters.length;t++)if(this.model.parameters[t].name===e)return this.model.parameters[t];return null}}),SwaggerUi.Views.ParameterContentTypeView=Backbone.View.extend({initialize:function(){},render:function(){return this.model.parameterContentTypeId="pct"+Math.random(),$(this.el).html(Handlebars.templates.parameter_content_type(this.model)),this}}),SwaggerUi.Views.ParameterView=Backbone.View.extend({events:{"change [name=parameterContentType]":"toggleParameterSnippet"},initialize:function(){Handlebars.registerHelper("isArray",function(e,t){var n=e.type&&e.type.toLowerCase();return"array"===n||e.allowMultiple?t.fn(this):t.inverse(this)})},render:function(){var e,t,n=this.model.type||this.model.dataType,r=this.model.modelSignature.type,i=this.model.modelSignature.definitions,a=this.model.schema||{},o=this.model.consumes||[];if("undefined"==typeof n&&a.$ref){var s=a.$ref;n=0===s.indexOf("#/definitions/")?s.substring("#/definitions/".length):s}this.model.type=n,this.model.paramType=this.model["in"]||this.model.paramType,this.model.isBody="body"===this.model.paramType||"body"===this.model["in"],this.model.isFile=n&&"file"===n.toLowerCase(),"undefined"==typeof this.model["default"]&&(this.model["default"]=this.model.defaultValue),this.model.hasDefault="undefined"!=typeof this.model["default"],this.model.valueId="m"+this.model.name+Math.random(),this.model.allowableValues&&(this.model.isList=!0);var l=this.contains(o,"xml"),u=!l||this.contains(o,"json");e=SwaggerUi.partials.signature.createParameterJSONSample(r,i);var c=this.template();$(this.el).html(c(this.model));var p={sampleJSON:!!u&&e,sampleXML:!(!e||!l)&&SwaggerUi.partials.signature.createXMLSample("",a,i,!0),isParam:!0,signature:SwaggerUi.partials.signature.getParameterModelSignature(r,i),defaultRendering:this.model.defaultRendering};e?(t=new SwaggerUi.Views.SignatureView({model:p,tagName:"div"}),$(".model-signature",$(this.el)).append(t.render().el)):$(".model-signature",$(this.el)).html(this.model.signature);var h=!1;if(this.options.swaggerOptions.jsonEditor&&this.model.isBody&&this.model.schema){var f=$(this.el);this.model.jsonEditor=new JSONEditor($(".editor_holder",f)[0],{schema:this.model.schema,startval:this.model["default"],ajax:!0,disable_properties:!0,disable_edit_json:!0,iconlib:"swagger"}),p.jsonEditor=this.model.jsonEditor,$(".body-textarea",f).hide(),$(".editor_holder",f).show(),$(".parameter-content-type",f).change(function(e){"application/xml"===e.target.value?($(".body-textarea",f).show(),$(".editor_holder",f).hide(),this.model.jsonEditor.disable()):($(".body-textarea",f).hide(),$(".editor_holder",f).show(),this.model.jsonEditor.enable())})}this.model.isBody&&(h=!0);var d={isParam:h};if(d.consumes=this.model.consumes,h){var m=new SwaggerUi.Views.ParameterContentTypeView({model:d});$(".parameter-content-type",$(this.el)).append(m.render().el),this.toggleParameterSnippet()}else{var g=new SwaggerUi.Views.ResponseContentTypeView({model:d});$(".response-content-type",$(this.el)).append(g.render().el),this.toggleResponseSnippet()}return this},contains:function(e,t){return e.filter(function(e){if(e.indexOf(t)>-1)return!0}).length},toggleParameterSnippet:function(){var e=this.$("[name=parameterContentType]").val();this.toggleSnippet(e)},toggleResponseSnippet:function(){var e=this.$("[name=responseContentType]");e.length&&this.toggleSnippet(e.val())},toggleSnippet:function(e){e=e||"",e.indexOf("xml")>-1?(this.$(".snippet_xml").show(),this.$(".snippet_json").hide()):(this.$(".snippet_json").show(),this.$(".snippet_xml").hide())},template:function(){return this.model.isList?Handlebars.templates.param_list:this.options.readOnly?this.model.required?Handlebars.templates.param_readonly_required:Handlebars.templates.param_readonly:this.model.required?Handlebars.templates.param_required:Handlebars.templates.param}}),SwaggerUi.partials.signature=function(){function e(e){var t,i=e.name,a=e.definition,o=e.config,s=e.models,l=e.config.isParam,u=[],c=a.properties,p=a.additionalProperties,h=a.xml,f=b(h);return f&&u.push(f),c||p?(c=c||{},t=_.map(c,function(e,t){var n,i;return l&&e.readOnly?"":(n=e.xml||{},i=r(t,e,s,o),n.attribute?(u.push(i),""):i)}).join(""),p&&(t+="<!-- additional elements allowed -->"),y(i,t,u)):n()}function t(e,t){return y(e,"<!-- Infinite loop $ref:"+t+" -->")}function n(e){return e=e?": "+e:"","<!-- invalid XML"+e+" -->"}function r(r,i,s,l){var u,c,p=_.isObject(i)?i.$ref:null;l=l||{},l.modelsToIgnore=l.modelsToIgnore||[];var h=_.isString(p)?a(p,r,s,l):o(r,i,s,l);if(!h)return n();switch(h.type){case"array":u=w(h);break;case"object":u=e(h);break;case"loop":u=t(h.name,h.config.loopTo);break;default:u=A(h)}return p&&"loop"!==h.type&&(c=l.modelsToIgnore.indexOf(p),c>-1&&l.modelsToIgnore.splice(c,1)),u}function i(e,t,n,r,i){if(arguments.length<4)throw new Error;this.config=i||{},this.config.modelsToIgnore=this.config.modelsToIgnore||[],this.name=v(e,n.xml),this.definition=n,this.models=r,this.type=t}function a(e,t,n,r){var a=u(e),o=n[a]||{},s=o.definition&&o.definition.type?o.definition.type:"object";return t=t||o.name,r.modelsToIgnore.indexOf(e)>-1?(s="loop",r.loopTo=a):r.modelsToIgnore.push(e),o.definition?new i(t,s,o.definition,n,r):null}function o(e,t,n,r){var a=t.type||"object";return t?new i(e,a,t,n,r):null}function s(e,t,n,i){var a='<?xml version="1.0"?>';return p(a+r(e,t,n,{isParam:i}))}var l=function(e){return _.isPlainObject(e.schema)&&(e=l(e.schema)),e},u=function(e){return"undefined"==typeof e?null:0===e.indexOf("#/definitions/")?e.substring("#/definitions/".length):e},c=function(e){if(/^Inline Model \d+$/.test(e)&&this.inlineModels){var t=parseInt(e.substr("Inline Model".length).trim(),10),n=this.inlineModels[t];return n}return null},p=function(e){var t,n,r,i,a,o,s,l,u,c,p,h,f;for(p=/(>)(<)(\/*)/g,f=/[ ]*(.*)[ ]+\n/g,t=/(<.+>)(.+\n)/g,e=e.replace(p,"$1\n$2$3").replace(f,"$1\n").replace(t,"$1\n$2"),c=0,r="",l=e.split("\n"),i=0,o="other",h={"single->single":0,"single->closing":-1,"single->opening":0,"single->other":0,"closing->single":0,"closing->closing":-1,"closing->opening":0,"closing->other":0,"opening->single":1,"opening->closing":0,"opening->opening":1,"opening->other":1,"other->single":0,"other->closing":-1,"other->opening":0,"other->other":0},n=function(e){var t,n,a,s,l,u,c;u={single:Boolean(e.match(/<.+\/>/)),closing:Boolean(e.match(/<\/.+>/)),opening:Boolean(e.match(/<[^!?].*>/))},l=function(){var e;e=[];for(a in u)c=u[a],c&&e.push(a);return e}()[0],l=void 0===l?"other":l,t=o+"->"+l,o=l,s="",i+=h[t],s=function(){var e,t,r;for(r=[],n=e=0,t=i;0<=t?e<t:e>t;n=0<=t?++e:--e)r.push(" ");return r}().join(""),"opening->closing"===t?r=r.substr(0,r.length-1)+e+"\n":r+=s+e+"\n"},a=0,s=l.length;a<s;a++)u=l[a],n(u);return r},h=function(e,t,n,r){function i(e,t,r){var i,a=t;return e.$ref?(a=e.title||u(e.$ref),i=n[u(e.$ref)]):_.isUndefined(t)&&(a=e.title||"Inline Model "+ ++m,i={definition:e}),r!==!0&&(f[a]=_.isUndefined(i)?{}:i.definition),a}function a(e){var t='<span class="propType">',n=e.type||"object";return e.$ref?t+=i(e,u(e.$ref)):"object"===n?t+=_.isUndefined(e.properties)?"object":i(e):"array"===n?(t+="Array[",_.isArray(e.items)?t+=_.map(e.items,i).join(","):_.isPlainObject(e.items)?t+=_.isUndefined(e.items.$ref)?_.isUndefined(e.items.type)||_.indexOf(["array","object"],e.items.type)!==-1?i(e.items):e.items.type:i(e.items,u(e.items.$ref)):(console.log("Array type's 'items' schema is not an array or an object, cannot process"),t+="object"),t+="]"):t+=e.type,t+="</span>"}function o(e,t){var n="",r=e.type||"object",i="array"===r;switch(_.isUndefined(e.description)||(t+=': <span class="propDesc">'+e.description+"</span>"),e["enum"]&&(t+=' = <span class="propVals">[\''+e["enum"].join("', '")+"']</span>"),i&&(r=_.isPlainObject(e.items)&&!_.isUndefined(e.items.type)?e.items.type:"object"),_.isUndefined(e["default"])||(n+=h("Default",e["default"])),r){case"string":e.minLength&&(n+=h("Min. Length",e.minLength)),e.maxLength&&(n+=h("Max. Length",e.maxLength)),e.pattern&&(n+=h("Reg. Exp.",e.pattern));break;case"integer":case"number":e.minimum&&(n+=h("Min. Value",e.minimum)),e.exclusiveMinimum&&(n+=h("Exclusive Min.","true")),e.maximum&&(n+=h("Max. Value",e.maximum)),e.exclusiveMaximum&&(n+=h("Exclusive Max.","true")),e.multipleOf&&(n+=h("Multiple Of",e.multipleOf))}if(i&&(e.minItems&&(n+=h("Min. Items",e.minItems)),e.maxItems&&(n+=h("Max. Items",e.maxItems)),e.uniqueItems&&(n+=h("Unique Items","true")),e.collectionFormat&&(n+=h("Coll. Format",e.collectionFormat))),_.isUndefined(e.items)&&_.isArray(e["enum"])){var a;a="number"===r||"integer"===r?e["enum"].join(", "):'"'+e["enum"].join('", "')+'"',n+=h("Enum",a)}return n.length>0&&(t='<span class="propWrap">'+t+'<table class="optionsWrapper"><tr><th colspan="2">'+r+"</th></tr>"+n+"</table></span>"),t}function s(e,t){var s,h=e.type||"object",f="array"===e.type,m=c+t+" "+(f?"[":"{")+p;return t&&d.push(t),f?_.isArray(e.items)?m+="<div>"+_.map(e.items,function(e){var t=e.type||"object";return _.isUndefined(e.$ref)?_.indexOf(["array","object"],t)>-1?"object"===t&&_.isUndefined(e.properties)?"object":i(e):o(e,t):i(e,u(e.$ref))}).join(",</div><div>"):_.isPlainObject(e.items)?m+=_.isUndefined(e.items.$ref)?_.indexOf(["array","object"],e.items.type||"object")>-1?(_.isUndefined(e.items.type)||"object"===e.items.type)&&_.isUndefined(e.items.properties)?"<div>object</div>":"<div>"+i(e.items)+"</div>":"<div>"+o(e.items,e.items.type)+"</div>":"<div>"+i(e.items,u(e.items.$ref))+"</div>":(console.log("Array type's 'items' property is not an array or an object, cannot process"),m+="<div>object</div>"):e.$ref?m+="<div>"+i(e,t)+"</div>":"object"===h?(_.isPlainObject(e.properties)&&(s=_.map(e.properties,function(t,i){var s,c=_.indexOf(e.required,i)>=0,p=_.cloneDeep(t),h=c?"required":"",f='<span class="propName '+h+'">'+i+"</span> (";return p["default"]=r(p),p=l(p),_.isUndefined(p.$ref)||(s=n[u(p.$ref)],_.isUndefined(s)||_.indexOf([void 0,"array","object"],s.definition.type)!==-1||(p=l(s.definition))),f+=a(p),c||(f+=', <span class="propOptKey">optional</span>'),t.readOnly&&(f+=', <span class="propReadOnly">read only</span>'),f+=")","<div"+(t.readOnly?' class="readOnly"':"")+">"+o(p,f)}).join(",</div>")),s&&(m+=s+"</div>")):m+="<div>"+o(e,h)+"</div>",m+c+(f?"]":"}")+p}var c='<span class="strong">',p="</span>",h=function(e,t){return'<tr><td class="optionName">'+e+":</td><td>"+t+"</td></tr>"};if(_.isObject(arguments[0])&&(e=void 0,t=arguments[0],n=arguments[1],r=arguments[2]),n=n||{},t=l(t),_.isEmpty(t))return c+"Empty"+p;if("string"==typeof t.$ref&&(e=u(t.$ref),t=n[e],"undefined"==typeof t))return c+e+" is not defined!"+p;"string"!=typeof e&&(e=t.title||"Inline Model"),t.definition&&(t=t.definition),"function"!=typeof r&&(r=function(e){return(e||{})["default"]});for(var f={},d=[],m=0,g=s(t,e);_.keys(f).length>0;)_.forEach(f,function(e,t){var n=_.indexOf(d,t)>-1;delete f[t],n||(d.push(t),g+="<br />"+s(e,t))});return g},f=function(e,t,n,r){e=l(e),"function"!=typeof r&&(r=function(e){return(e||{})["default"]}),n=n||{};var i,a,o=e.type||"object",s=e.format;return _.isUndefined(e.example)?_.isUndefined(e.items)&&_.isArray(e["enum"])&&(a=e["enum"][0]):a=e.example,_.isUndefined(a)&&(e.$ref?(i=t[u(e.$ref)],_.isUndefined(i)||(_.isUndefined(n[i.name])?(n[i.name]=i,a=f(i.definition,t,n,r),delete n[i.name]):a="array"===i.type?[]:{})):_.isUndefined(e["default"])?"string"===o?a="date-time"===s?(new Date).toISOString():"date"===s?(new Date).toISOString().split("T")[0]:"string":"integer"===o?a=0:"number"===o?a=0:"boolean"===o?a=!0:"object"===o?(a={},_.forEach(e.properties,function(e,i){var o=_.cloneDeep(e);o["default"]=r(e),a[i]=f(o,t,n,r)})):"array"===o&&(a=[],_.isArray(e.items)?_.forEach(e.items,function(e){a.push(f(e,t,n,r))}):_.isPlainObject(e.items)?a.push(f(e.items,t,n,r)):_.isUndefined(e.items)?a.push({}):console.log("Array type's 'items' property is not an array or an object, cannot process")):a=e["default"]),a},d=function(e,t){return t=t||{},t[e.name]=e,e.examples&&_.isPlainObject(e.examples)&&e.examples["application/json"]?(e.definition.example=e.examples["application/json"],_.isString(e.definition.example)&&(e.definition.example=jsyaml.safeLoad(e.definition.example))):e.definition.example||(e.definition.example=e.examples),f(e.definition,e.models,t,e.modelPropertyMacro)},m=function(e,t){var n,r;return e instanceof Array&&(r=!0,e=e[0]),"undefined"==typeof e?(e="undefined",n=!0):t[e]?(e=t[e],n=!1):c(e)?(e=c(e),n=!1):n=!0,n?r?"Array["+e+"]":e.toString():r?"Array["+h(e.name,e.definition,e.models,e.modelPropertyMacro)+"]":h(e.name,e.definition,e.models,e.modelPropertyMacro)},g=function(e,t){var n,r,i;if(t=t||{},n=e instanceof Array,i=n?e[0]:e,t[i]?r=d(t[i]):c(i)&&(r=d(c(i))),r){if(r=n?[r]:r,"string"==typeof r)return r;if(_.isObject(r)){var a=r;if(r instanceof Array&&r.length>0&&(a=r[0]),a.nodeName&&"Node"==typeof a){var o=(new XMLSerializer).serializeToString(a);return p(o)}return JSON.stringify(r,null,2)}return r}},y=function(e,t,r){var i,a;return r=r||[],a=r.map(function(e){return" "+e.name+'="'+e.value+'"'}).join(""),e?(i=["<",e,a,">",t,"</",e,">"],i.join("")):n("Node name is not provided")},v=function(e,t){var n=e||"";return t=t||{},t.name&&(n=t.name),t.prefix&&(n=t.prefix+":"+n),n},b=function(e){var t="",n="xmlns";return e=e||{},e.namespace?(t=e.namespace,e.prefix&&(n+=":"+e.prefix),{name:n,value:t}):t},w=function(e){var t,i=e.name,a=e.config,o=e.definition,s=e.models,l=o.items,u=o.xml||{},c=b(u),p=[];return l?(t=r(i,l,s,a),c&&p.push(c),u.wrapped&&(t=y(i,t,p)),t):n()},x=function(e){var t,n;switch(e=e||{},n=e.items||{},t=e.type||""){case"object":return"Object is not a primitive";case"array":return"Array["+(n.format||n.type)+"]";default:return e.format||t}},A=function(e){var t,r=e.name,i=e.definition,a={string:{date:new Date(1).toISOString().split("T")[0],"date-time":new Date(1).toISOString(),"default":"string"},integer:{"default":1},number:{"default":1.1},"boolean":{"default":!0}},o=i.type,s=i.format,l=i.xml||{},u=b(l),c=[];return _.keys(a).indexOf(o)<0?n():(t=_.isArray(i["enum"])?i["enum"][0]:i.example||a[o][s]||a[o]["default"],l.attribute?{name:r,value:t}:(u&&c.push(u),y(r,t,c)))};return{getModelSignature:h,createJSONSample:d,getParameterModelSignature:m,createParameterJSONSample:g,createSchemaXML:r,createXMLSample:s,getPrimitiveSignature:x}}(),SwaggerUi.Views.PopupView=Backbone.View.extend({events:{"click .api-popup-cancel":"cancelClick"},template:Handlebars.templates.popup,className:"api-popup-dialog",selectors:{content:".api-popup-content",main:"#swagger-ui-container"},initialize:function(){this.$el.html(this.template(this.model))},render:function(){return this.$(this.selectors.content).append(this.model.content),$(this.selectors.main).first().append(this.el),this.showPopup(),this},showPopup:function(){this.$el.show()},cancelClick:function(){this.remove()}}),SwaggerUi.Views.ResourceView=Backbone.View.extend({initialize:function(e){e=e||{},this.router=e.router,this.auths=e.auths,""===this.model.description&&(this.model.description=null),this.model.description&&(this.model.summary=this.model.description),this.number=0},render:function(){var e={};$(this.el).html(Handlebars.templates.resource(this.model));for(var t=0;t<this.model.operationsArray.length;t++){for(var n=this.model.operationsArray[t],r=0,i=n.nickname;"undefined"!=typeof e[i];)i=i+"_"+r,r+=1;e[i]=n,n.nickname=i,n.parentId=this.model.id,n.definitions=this.model.definitions,this.addOperation(n)}return $(".toggleEndpointList",this.el).click(this.callDocs.bind(this,"toggleEndpointListForResource")),$(".collapseResource",this.el).click(this.callDocs.bind(this,"collapseOperationsForResource")),$(".expandResource",this.el).click(this.callDocs.bind(this,"expandOperationsForResource")),this},addOperation:function(e){e.number=this.number;var t=new SwaggerUi.Views.OperationView({model:e,router:this.router,tagName:"li",className:"endpoint",swaggerOptions:this.options.swaggerOptions,auths:this.auths});$(".endpoints",$(this.el)).append(t.render().el),this.number++},callDocs:function(e,t){t.preventDefault(),Docs[e](t.currentTarget.getAttribute("data-id"))}}),SwaggerUi.Views.ResponseContentTypeView=Backbone.View.extend({initialize:function(){},render:function(){return this.model.responseContentTypeId="rct"+Math.random(),$(this.el).html(Handlebars.templates.response_content_type(this.model)),this}}),SwaggerUi.Views.SignatureView=Backbone.View.extend({events:{"click a.description-link":"switchToDescription","click a.snippet-link":"switchToSnippet","mousedown .snippet_json":"jsonSnippetMouseDown","mousedown .snippet_xml":"xmlSnippetMouseDown"},initialize:function(){},render:function(){return $(this.el).html(Handlebars.templates.signature(this.model)),"model"===this.model.defaultRendering?this.switchToDescription():this.switchToSnippet(),this},switchToDescription:function(e){e&&e.preventDefault(),$(".snippet",$(this.el)).hide(),$(".description",$(this.el)).show(),$(".description-link",$(this.el)).addClass("selected"),$(".snippet-link",$(this.el)).removeClass("selected")},switchToSnippet:function(e){e&&e.preventDefault(),$(".snippet",$(this.el)).show(),$(".description",$(this.el)).hide(),$(".snippet-link",$(this.el)).addClass("selected"),$(".description-link",$(this.el)).removeClass("selected")},snippetToTextArea:function(e){var t=$("textarea",$(this.el.parentNode.parentNode.parentNode));""!==$.trim(t.val())&&t.prop("placeholder")!==t.val()||(t.val(e),this.model.jsonEditor&&this.model.jsonEditor.isEnabled()&&this.model.jsonEditor.setValue(JSON.parse(this.model.sampleJSON)))},jsonSnippetMouseDown:function(e){this.model.isParam&&(e&&e.preventDefault(),this.snippetToTextArea(this.model.sampleJSON))},xmlSnippetMouseDown:function(e){this.model.isParam&&(e&&e.preventDefault(),this.snippetToTextArea(this.model.sampleXML))}}),SwaggerUi.Views.StatusCodeView=Backbone.View.extend({initialize:function(e){this.options=e||{},this.router=this.options.router},render:function(){var e,t,n=this.router.api.models[this.model.responseModel];return $(this.el).html(Handlebars.templates.status_code(this.model)),e=this.router.api.models.hasOwnProperty(this.model.responseModel)?{sampleJSON:JSON.stringify(SwaggerUi.partials.signature.createJSONSample(n),void 0,2),sampleXML:!!this.model.isXML&&SwaggerUi.partials.signature.createXMLSample("",this.model.schema,this.router.api.models),isParam:!1,signature:SwaggerUi.partials.signature.getModelSignature(this.model.responseModel,n,this.router.api.models),defaultRendering:this.model.defaultRendering}:{signature:SwaggerUi.partials.signature.getPrimitiveSignature(this.model.schema)},t=new SwaggerUi.Views.SignatureView({model:e,tagName:"div"}),$(".model-signature",this.$el).append(t.render().el),this}})}).call(this); \ No newline at end of file
diff --git a/ydb/core/viewer/content/index.html b/ydb/core/viewer/content/index.html
index 9ae10f6f6b7..7fb13b7acd4 100644
--- a/ydb/core/viewer/content/index.html
+++ b/ydb/core/viewer/content/index.html
@@ -1,669 +1,669 @@
-<html>
-<head>
-<style>
-table.nodelist td {
- padding: 3px 3px;
- font-size: 16px;
-}
-table.nodelist th {
- padding: 1px 1px;
- text-align: center;
- font-size: 16px;
-}
-table.grouplist td {
- padding: 1px 3px;
- /*font-size: 16px;*/
-}
-table.grouplist th {
- padding: 1px 1px;
- text-align: center;
- /*font-size: 16px;*/
-}
-.nodeblock {
- display: inline-block;
- width: 12px;
- height: 30px;
- background-color: lightgrey;
- border-radius: 3px;
- vertical-align: middle;
- border-color: darkgrey;
- border-width: 1px;
- border-style: solid;
-}
-.nodeblock-small {
- display: inline-block;
- width: 12px;
- height: 30px;
- background-color: lightgrey;
- vertical-align: middle;
-}
-.diskblock {
- border-radius: 5px;
- border-color: #ededed;
- border-style: solid;
- background-color: #eeeeee;
- padding: 0px 2px 0px 2px;
- box-shadow: 0px 0px 5px #eeeeee;
-}
-.groupblock {
- font-size:10px;
- /*border-color: green;
- border-width: 1px;
- border-style: solid;
- border-bottom-left-radius: 3px;
- border-bottom-right-radius: 3px;
- border-top-left-radius: 3px;
- border-top-right-radius: 3px;*/
-}
-.vdiskblock {
- display: inline-block;
- height: 16px;
- font-size: 12px;
- background-color: lightgrey;
- border-color: green;
- border-width: 1px;
- border-style: solid;
- border-bottom-left-radius: 3px;
- border-bottom-right-radius: 3px;
- border-top-left-radius: 3px;
- border-top-right-radius: 3px;
- vertical-align: middle;
- cursor: pointer;
- box-shadow: 2px 2px 2px grey;
-}
-.vdiskblock-wide {
- width: 20px;
-}
-.vdiskblock-narrow {
- width: 14px;
-}
-.vdiskblock-selected {
- border-width: 3px;
-}
-.vdiskblock-small {
- display: inline-block;
- width: 8px;
- height: 12px;
-/* font-size: 12px;*/
- background-color: lightgrey;
- border-color: green;
- border-width: 1px;
- border-style: solid;
- border-bottom-left-radius: 3px;
- border-bottom-right-radius: 3px;
- border-top-left-radius: 3px;
- border-top-right-radius: 3px;
- vertical-align: middle;
- cursor: pointer;
-}
-.pdiskblock {
- width:100%;
- min-width:100px;
- height:18px;
- margin-bottom:0px;
- vertical-align:middle;
- background-color:lightgrey;
- border-color: grey;
- border-width: 1px;
- border-style: solid;
- cursor: pointer;
- box-shadow: 2px 2px 2px grey;
-}
-.tabletblock {
- float: left;
- width: 20px;
- height: 20px;
- border-color: black;
- border-width: 1px;
- border-style: solid;
- border-radius: 3px;
- margin: 3px;
- /*vertical-align: middle;*/
- text-align: center;
- font-size: 10px;
- padding-top: 2px;
- cursor: pointer;
- /*webkit-transition: all 1s ease-in-out;
- -moz-transition: all 1s ease-in-out;
- -o-transition: all 1s ease-in-out;
- -ms-transition: all 1s ease-in-out;
- transition: all 1s ease-in-out;*/
- box-shadow: 2px 2px 2px grey;
-}
-.tabletblock-small {
- float: left;
- width: 10px;
- height: 10px;
- border-color: black;
- border-width: 1px;
- border-style: solid;
- border-radius: 3px;
- margin: 1px;
- /*vertical-align: middle;*/
- text-align: center;
- font-size: 5px;
- padding-top: 1px;
- cursor: pointer;
- /*webkit-transition: all 1s ease-in-out;
- -moz-transition: all 1s ease-in-out;
- -o-transition: all 1s ease-in-out;
- -ms-transition: all 1s ease-in-out;
- transition: all 1s ease-in-out;*/
- box-shadow: 1px 1px 1px grey;
-}
-.tabletblock-extra-small {
- float: left;
- width: 6px;
- height: 6px;
- border-color: darkgrey;
- border-width: 1px;
- border-style: solid;
- border-collapse: collapse;
- border-width: thin;
- /*border-radius: 3px;*/
- margin: 0px;
- /*vertical-align: middle;*/
- /*text-align: center;
- font-size: 5px;*/
- padding-top: 1px;
- cursor: pointer;
- /*webkit-transition: all 1s ease-in-out;
- -moz-transition: all 1s ease-in-out;
- -o-transition: all 1s ease-in-out;
- -ms-transition: all 1s ease-in-out;
- transition: all 1s ease-in-out;*/
- /*box-shadow: 1px 1px 1px grey;*/
-}
-.partitionblock {
- float: left;
- width: 8px;
- height: 8px;
- border-color: grey;
- border-width: 1px;
- border-style: solid;
- border-radius: 2px;
- margin: 1px;
-}
-.partitionblock-small {
- float: left;
- width: 5px;
- height: 5px;
- border-color: grey;
- border-width: 1px;
- border-style: solid;
- border-radius: 1px;
- margin: 1px;
-}
-.tabletgroupblock {
- padding-bottom: 10px;
-}
-.tabletgroupname {
- font-size: 16px;
- font-weight: bold;
- padding-left: 5px;
-}
-.statecontainer {
- font-size: 10px;
-}
-.stateblock {
- display: inline-block;
- width: 24px;
- height: 10px;
- background-color: lightgrey;
- border-color: green;
- border-width: 1px;
- border-style: solid;
- border-bottom-left-radius: 3px;
- border-bottom-right-radius: 3px;
- border-top-left-radius: 3px;
- border-top-right-radius: 3px;
- vertical-align: middle;
- box-shadow: 1px 1px 1px grey;
- margin-right: 5px;
- font-size: 6px;
- text-align: center;
- cursor: default;
-}
-.usageblock {
- display: inline-block;
- width: 156px;
- height: 10px;
- background-color: lightgrey;
- border-color: green;
- border-width: 1px;
- border-style: solid;
- border-bottom-left-radius: 3px;
- border-bottom-right-radius: 3px;
- border-top-left-radius: 3px;
- border-top-right-radius: 3px;
- vertical-align: middle;
- box-shadow: 1px 1px 1px grey;
- margin-right: 5px;
- margin-bottom: 0px;
-}
-.latency-block {
- height: 16px;
- font-size: 11px;
- border-color: green;
- border-width: 1px;
- border-style: solid;
- border-bottom-left-radius: 3px;
- border-bottom-right-radius: 3px;
- border-top-left-radius: 3px;
- border-top-right-radius: 3px;
- text-align: center;
- vertical-align: middle;
- box-shadow: 1px 1px 1px grey;
- padding-left: 3px;
- padding-right: 3px;
-}
-.schema-bad {
- color: red;
-}
-.schema-neutral {
- color: grey;
-}
-.schema-good {
- color: steelblue;
-}
-.proplist td {
- padding: 3px;
-}
-.proplist td:first-child {
- text-align: right;
- font-weight: bold;
-}
-.schema-table th {
- padding: 1px 3px;
-}
-.schema-table td {
- padding: 1px 3px;
-}
-.tablets-table th {
- padding: 1px 3px;
-}
-.tablets-table td {
- padding: 1px 3px;
-}
-.children-table th {
- padding: 1px 3px;
-}
-.children-table td {
- padding: 1px 3px;
-}
-.groupblock > .vdiskblock {
- margin-right: 3px;
-}
-#schema-view td {
- vertical-align: top;
-}
-.totalstorage th {
- padding: 1px 3px;
- text-align: center;
- font-size: 16px;
-}
-.totalstorage td {
- padding: 1px 3px;
- text-align: right;
- font-size: 16px;
-}
-table.tstats > tbody > tr:nth-child(even) {
- background-color: #eee;
-}
-table.tstats > tbody > tr > td {
- font-size: 24px;
- border-right: 1px solid #ccc;
- border-bottom: 1px solid #ccc;
- padding: 3px 5px 3px 3px;
-}
-table.tstats > tbody > tr > td:nth-child(1) {
- font-size: 16px;
- font-weight: bold;
- text-align: right;
- padding-right: 10px;
- padding-top: 10px;
- padding-bottom: 10px;
-}
-table.nstats {
-}
-table.nstats > tbody > tr:nth-child(even) {
- background-color: #eee;
-}
-table.nstats > tbody > tr > td {
- font-size: 24px;
- border-right: 1px solid #ccc;
- border-bottom: 1px solid #ccc;
- padding: 3px 5px 3px 3px;
- width: 90px;
- text-align: right;
- overflow: hidden;
-}
-table.nstats > tbody > tr > th {
- font-size: 16px;
- border-right: 1px solid #ccc;
- /*border-bottom: 1px solid #ccc;*/
- padding: 3px 5px 3px 3px;
- width: 90px;
- text-align: center;
-}
-table.nstats > tbody > tr > td:nth-child(1) {
- font-size: 16px;
- font-weight: bold;
- text-align: right;
- padding-right: 10px;
- padding-top: 10px;
- padding-bottom: 10px;
-}
-td.tcounter {
- text-align: right;
- padding-right: 15px;
- text-shadow:
- -1px -1px 0 #999,
- 1px -1px 0 #999,
- -1px 1px 0 #999,
- 1px 1px 0 #999;
-}
-th.rotate {
- /* Something you can count on */
- height: 130px;
- min-width: 90px;
- white-space: nowrap;
-}
-th.rotate > div {
- transform:
- translate(80px, 43px)
- rotate(330deg);
- width: 30px;
-}
-th.rotate > div > span {
- border-bottom: 1px solid #ccc;
- padding: 8px 0px;
- font-size: 16px;
-}
-table.sqlresult td {
- padding: 1px 3px;
- /*font-size: 16px;*/
-}
-table.sqlresult th {
- padding: 1px 1px;
- text-align: center;
- /*font-size: 16px;*/
-}
-</style>
-<link rel="stylesheet" href="style.min.css" />
-<script src="viewer.js"></script>
-<script src="jstree.min.js"></script>
-</head>
-<body>
-<ul class="nav nav-tabs">
- <li class="active">
- <a href="#overview" data-toggle="tab">Overview</a>
- </li>
- <li>
- <a href="#tablets" data-toggle="tab">Tablets</a>
- </li>
- <li>
- <a href="#storage" data-toggle="tab">Storage</a>
- </li>
- <li>
- <a href="#nodes" data-toggle="tab">Nodes</a>
- </li>
- <li>
- <a href="#schema" data-toggle="tab">Schema</a>
- </li>
-</ul>
-<div class="tab-content" style="padding-top: 10px">
- <div id="overview" class="tab-pane fade in active container">
- <table class="nstats node-stats" style="margin-top: 20px">
- <tr>
- <th style='min-width:120px'></th>
- <th><div><span>Dead</span></div></th>
- <th><div><span>&lt; Minute</span></div></th>
- <th><div><span>&lt; Hour</span></div></th>
- <th><div><span>&lt; Day</span></div></th>
- <th><div><span>Day+</span></div></th>
- </tr>
- <tr>
- <td>Nodes Age</td>
- <td class='tcounter' style='color:black'></td>
- <td class='tcounter' style='color:red'></td>
- <td class='tcounter' style='color:orange'></td>
- <td class='tcounter' style='color:yellow'></td>
- <td class='tcounter' style='color:lightgreen'></td>
- </tr>
- <tr>
- <td>Tablets Age</td>
- <td class='tcounter' style='color:black'></td>
- <td class='tcounter' style='color:red'></td>
- <td class='tcounter' style='color:orange'></td>
- <td class='tcounter' style='color:yellow'></td>
- <td class='tcounter' style='color:lightgreen'></td>
- </tr>
- </table>
- <table class="nstats disk-stats" style="margin-top: 30px">
- <tr>
- <th style='min-width:120px'></th>
- <th><div><span>Grey</span></div></th>
- <th><div><span>Red</span></div></th>
- <th><div><span>Orange</span></div></th>
- <th><div><span>Yellow</span></div></th>
- <th><div><span>Green</span></div></th>
- </tr>
- <tr>
- <td>PDisks</td>
- <td class='tcounter' style='color:grey'></td>
- <td class='tcounter' style='color:red'></td>
- <td class='tcounter' style='color:orange'></td>
- <td class='tcounter' style='color:yellow'></td>
- <td class='tcounter' style='color:lightgreen'></td>
- </tr>
- <tr>
- <td>VDisks</td>
- <td class='tcounter' style='color:grey'></td>
- <td class='tcounter' style='color:red'></td>
- <td class='tcounter' style='color:orange'></td>
- <td class='tcounter' style='color:yellow'></td>
- <td class='tcounter' style='color:lightgreen'></td>
- </tr>
- <tr>
- <td>Groups</td>
- <td class='tcounter' style='color:grey'></td>
- <td class='tcounter' style='color:red'></td>
- <td class='tcounter' style='color:orange'></td>
- <td class='tcounter' style='color:yellow'></td>
- <td class='tcounter' style='color:lightgreen'></td>
- </tr>
- </table>
- <table class="tstats tablet-stats">
- <tr>
- <th class='rotate' style='min-width:120px'></th>
- <th class='rotate'><div><span>Dead</span></div></th>
- <th class='rotate'><div><span>Created</span></div></th>
- <th class='rotate'><div><span>ResolveStateStorage</span></div></th>
- <th class='rotate'><div><span>Lock</span></div></th>
- <th class='rotate'><div><span>Discover</span></div></th>
- <th class='rotate'><div><span>Candidate</span></div></th>
- <th class='rotate'><div><span>BlockBlobStorage</span></div></th>
- <th class='rotate'><div><span>RebuildGraph</span></div></th>
- <th class='rotate'><div><span>WriteZeroEntry</span></div></th>
- <th class='rotate'><div><span>Restored</span></div></th>
- <th class='rotate'><div><span>Active</span></div></th>
- </tr>
- </table>
- </div>
- <table id="tablets" class="tab-pane fade">
- <tr>
- <td>
- <table>
- <tr>
- <td>
- <div style="font-size: 14px;">Group by:</div>
- <form style="font-size: 14px; padding-left:10px; padding-bottom:10px">
- <label class="radio-inline"><input type="radio" name="optgroupradio" checked="checked" onchange="onTabletGroupChange(this);" value="ungrouped">Ungrouped</label>
- <label class="radio-inline"><input type="radio" name="optgroupradio" onchange="onTabletGroupChange(this);" value="type">Type</label>
- <label class="radio-inline"><input type="radio" name="optgroupradio" onchange="onTabletGroupChange(this);" value="state">State</label>
- <label class="radio-inline"><input type="radio" name="optgroupradio" onchange="onTabletGroupChange(this);" value="node">Node</label>
- </form>
- </td>
- <td style="padding-left: 40px">
- <div style="font-size: 14px;">Coloring by:</div>
- <form style="font-size: 14px; padding-left:10px; padding-bottom:10px">
- <label class="radio-inline"><input type="radio" name="optcolorradio" checked="checked" onchange="onTabletColorChange(this);" value="state">State</label>
- <label class="radio-inline"><input type="radio" name="optcolorradio" onchange="onTabletColorChange(this);" value="type">Type</label>
- </form>
- </td>
- <td style="padding-left: 40px">
- <button type="button" class="btn btn-default btn-md" onclick="$('.tabletgroupcontainer').collapse('show');">Expand All</button>
- <button type="button" class="btn btn-default btn-md" onclick="$('.tabletgroupcontainer').collapse('hide');">Collapse All</button>
- </td>
- </tr>
- </table>
- <div id="panel-all-tablets"><img src="throbber.gif" style="padding-left:10px"></div>
- </td>
- </tr>
- </table>
- <div id="storage" class="tab-pane fade">
- <table class="totalstorage" style="margin-top:10px;margin-bottom:15px">
- <thead>
- <tr>
- <th>&nbsp;</th>
- <th>Usage</th>
- <th>Used</th>
- <th>Available</th>
- <th>Total</th>
- </tr>
- </thead>
- <tbody>
- <tr>
- <td>Total</td>
- <td>&nbsp;</td>
- <td>&nbsp;</td>
- <td>&nbsp;</td>
- <td>&nbsp;</td>
- </tr>
- <tr>
- <td>Dynamic</td>
- <td>&nbsp;</td>
- <td>&nbsp;</td>
- <td>&nbsp;</td>
- <td>&nbsp;</td>
- </tr>
- <tr>
- <td>Static</td>
- <td>&nbsp;</td>
- <td>&nbsp;</td>
- <td>&nbsp;</td>
- <td>&nbsp;</td>
- </tr>
- </tbody>
- </table>
- <table class="grouplist" style="margin-bottom:15px">
- <thead>
- <tr>
- <th>Group</th>
- <th>Type</th>
- <th>Erasure</th>
- <th>Latency</th>
+<html>
+<head>
+<style>
+table.nodelist td {
+ padding: 3px 3px;
+ font-size: 16px;
+}
+table.nodelist th {
+ padding: 1px 1px;
+ text-align: center;
+ font-size: 16px;
+}
+table.grouplist td {
+ padding: 1px 3px;
+ /*font-size: 16px;*/
+}
+table.grouplist th {
+ padding: 1px 1px;
+ text-align: center;
+ /*font-size: 16px;*/
+}
+.nodeblock {
+ display: inline-block;
+ width: 12px;
+ height: 30px;
+ background-color: lightgrey;
+ border-radius: 3px;
+ vertical-align: middle;
+ border-color: darkgrey;
+ border-width: 1px;
+ border-style: solid;
+}
+.nodeblock-small {
+ display: inline-block;
+ width: 12px;
+ height: 30px;
+ background-color: lightgrey;
+ vertical-align: middle;
+}
+.diskblock {
+ border-radius: 5px;
+ border-color: #ededed;
+ border-style: solid;
+ background-color: #eeeeee;
+ padding: 0px 2px 0px 2px;
+ box-shadow: 0px 0px 5px #eeeeee;
+}
+.groupblock {
+ font-size:10px;
+ /*border-color: green;
+ border-width: 1px;
+ border-style: solid;
+ border-bottom-left-radius: 3px;
+ border-bottom-right-radius: 3px;
+ border-top-left-radius: 3px;
+ border-top-right-radius: 3px;*/
+}
+.vdiskblock {
+ display: inline-block;
+ height: 16px;
+ font-size: 12px;
+ background-color: lightgrey;
+ border-color: green;
+ border-width: 1px;
+ border-style: solid;
+ border-bottom-left-radius: 3px;
+ border-bottom-right-radius: 3px;
+ border-top-left-radius: 3px;
+ border-top-right-radius: 3px;
+ vertical-align: middle;
+ cursor: pointer;
+ box-shadow: 2px 2px 2px grey;
+}
+.vdiskblock-wide {
+ width: 20px;
+}
+.vdiskblock-narrow {
+ width: 14px;
+}
+.vdiskblock-selected {
+ border-width: 3px;
+}
+.vdiskblock-small {
+ display: inline-block;
+ width: 8px;
+ height: 12px;
+/* font-size: 12px;*/
+ background-color: lightgrey;
+ border-color: green;
+ border-width: 1px;
+ border-style: solid;
+ border-bottom-left-radius: 3px;
+ border-bottom-right-radius: 3px;
+ border-top-left-radius: 3px;
+ border-top-right-radius: 3px;
+ vertical-align: middle;
+ cursor: pointer;
+}
+.pdiskblock {
+ width:100%;
+ min-width:100px;
+ height:18px;
+ margin-bottom:0px;
+ vertical-align:middle;
+ background-color:lightgrey;
+ border-color: grey;
+ border-width: 1px;
+ border-style: solid;
+ cursor: pointer;
+ box-shadow: 2px 2px 2px grey;
+}
+.tabletblock {
+ float: left;
+ width: 20px;
+ height: 20px;
+ border-color: black;
+ border-width: 1px;
+ border-style: solid;
+ border-radius: 3px;
+ margin: 3px;
+ /*vertical-align: middle;*/
+ text-align: center;
+ font-size: 10px;
+ padding-top: 2px;
+ cursor: pointer;
+ /*webkit-transition: all 1s ease-in-out;
+ -moz-transition: all 1s ease-in-out;
+ -o-transition: all 1s ease-in-out;
+ -ms-transition: all 1s ease-in-out;
+ transition: all 1s ease-in-out;*/
+ box-shadow: 2px 2px 2px grey;
+}
+.tabletblock-small {
+ float: left;
+ width: 10px;
+ height: 10px;
+ border-color: black;
+ border-width: 1px;
+ border-style: solid;
+ border-radius: 3px;
+ margin: 1px;
+ /*vertical-align: middle;*/
+ text-align: center;
+ font-size: 5px;
+ padding-top: 1px;
+ cursor: pointer;
+ /*webkit-transition: all 1s ease-in-out;
+ -moz-transition: all 1s ease-in-out;
+ -o-transition: all 1s ease-in-out;
+ -ms-transition: all 1s ease-in-out;
+ transition: all 1s ease-in-out;*/
+ box-shadow: 1px 1px 1px grey;
+}
+.tabletblock-extra-small {
+ float: left;
+ width: 6px;
+ height: 6px;
+ border-color: darkgrey;
+ border-width: 1px;
+ border-style: solid;
+ border-collapse: collapse;
+ border-width: thin;
+ /*border-radius: 3px;*/
+ margin: 0px;
+ /*vertical-align: middle;*/
+ /*text-align: center;
+ font-size: 5px;*/
+ padding-top: 1px;
+ cursor: pointer;
+ /*webkit-transition: all 1s ease-in-out;
+ -moz-transition: all 1s ease-in-out;
+ -o-transition: all 1s ease-in-out;
+ -ms-transition: all 1s ease-in-out;
+ transition: all 1s ease-in-out;*/
+ /*box-shadow: 1px 1px 1px grey;*/
+}
+.partitionblock {
+ float: left;
+ width: 8px;
+ height: 8px;
+ border-color: grey;
+ border-width: 1px;
+ border-style: solid;
+ border-radius: 2px;
+ margin: 1px;
+}
+.partitionblock-small {
+ float: left;
+ width: 5px;
+ height: 5px;
+ border-color: grey;
+ border-width: 1px;
+ border-style: solid;
+ border-radius: 1px;
+ margin: 1px;
+}
+.tabletgroupblock {
+ padding-bottom: 10px;
+}
+.tabletgroupname {
+ font-size: 16px;
+ font-weight: bold;
+ padding-left: 5px;
+}
+.statecontainer {
+ font-size: 10px;
+}
+.stateblock {
+ display: inline-block;
+ width: 24px;
+ height: 10px;
+ background-color: lightgrey;
+ border-color: green;
+ border-width: 1px;
+ border-style: solid;
+ border-bottom-left-radius: 3px;
+ border-bottom-right-radius: 3px;
+ border-top-left-radius: 3px;
+ border-top-right-radius: 3px;
+ vertical-align: middle;
+ box-shadow: 1px 1px 1px grey;
+ margin-right: 5px;
+ font-size: 6px;
+ text-align: center;
+ cursor: default;
+}
+.usageblock {
+ display: inline-block;
+ width: 156px;
+ height: 10px;
+ background-color: lightgrey;
+ border-color: green;
+ border-width: 1px;
+ border-style: solid;
+ border-bottom-left-radius: 3px;
+ border-bottom-right-radius: 3px;
+ border-top-left-radius: 3px;
+ border-top-right-radius: 3px;
+ vertical-align: middle;
+ box-shadow: 1px 1px 1px grey;
+ margin-right: 5px;
+ margin-bottom: 0px;
+}
+.latency-block {
+ height: 16px;
+ font-size: 11px;
+ border-color: green;
+ border-width: 1px;
+ border-style: solid;
+ border-bottom-left-radius: 3px;
+ border-bottom-right-radius: 3px;
+ border-top-left-radius: 3px;
+ border-top-right-radius: 3px;
+ text-align: center;
+ vertical-align: middle;
+ box-shadow: 1px 1px 1px grey;
+ padding-left: 3px;
+ padding-right: 3px;
+}
+.schema-bad {
+ color: red;
+}
+.schema-neutral {
+ color: grey;
+}
+.schema-good {
+ color: steelblue;
+}
+.proplist td {
+ padding: 3px;
+}
+.proplist td:first-child {
+ text-align: right;
+ font-weight: bold;
+}
+.schema-table th {
+ padding: 1px 3px;
+}
+.schema-table td {
+ padding: 1px 3px;
+}
+.tablets-table th {
+ padding: 1px 3px;
+}
+.tablets-table td {
+ padding: 1px 3px;
+}
+.children-table th {
+ padding: 1px 3px;
+}
+.children-table td {
+ padding: 1px 3px;
+}
+.groupblock > .vdiskblock {
+ margin-right: 3px;
+}
+#schema-view td {
+ vertical-align: top;
+}
+.totalstorage th {
+ padding: 1px 3px;
+ text-align: center;
+ font-size: 16px;
+}
+.totalstorage td {
+ padding: 1px 3px;
+ text-align: right;
+ font-size: 16px;
+}
+table.tstats > tbody > tr:nth-child(even) {
+ background-color: #eee;
+}
+table.tstats > tbody > tr > td {
+ font-size: 24px;
+ border-right: 1px solid #ccc;
+ border-bottom: 1px solid #ccc;
+ padding: 3px 5px 3px 3px;
+}
+table.tstats > tbody > tr > td:nth-child(1) {
+ font-size: 16px;
+ font-weight: bold;
+ text-align: right;
+ padding-right: 10px;
+ padding-top: 10px;
+ padding-bottom: 10px;
+}
+table.nstats {
+}
+table.nstats > tbody > tr:nth-child(even) {
+ background-color: #eee;
+}
+table.nstats > tbody > tr > td {
+ font-size: 24px;
+ border-right: 1px solid #ccc;
+ border-bottom: 1px solid #ccc;
+ padding: 3px 5px 3px 3px;
+ width: 90px;
+ text-align: right;
+ overflow: hidden;
+}
+table.nstats > tbody > tr > th {
+ font-size: 16px;
+ border-right: 1px solid #ccc;
+ /*border-bottom: 1px solid #ccc;*/
+ padding: 3px 5px 3px 3px;
+ width: 90px;
+ text-align: center;
+}
+table.nstats > tbody > tr > td:nth-child(1) {
+ font-size: 16px;
+ font-weight: bold;
+ text-align: right;
+ padding-right: 10px;
+ padding-top: 10px;
+ padding-bottom: 10px;
+}
+td.tcounter {
+ text-align: right;
+ padding-right: 15px;
+ text-shadow:
+ -1px -1px 0 #999,
+ 1px -1px 0 #999,
+ -1px 1px 0 #999,
+ 1px 1px 0 #999;
+}
+th.rotate {
+ /* Something you can count on */
+ height: 130px;
+ min-width: 90px;
+ white-space: nowrap;
+}
+th.rotate > div {
+ transform:
+ translate(80px, 43px)
+ rotate(330deg);
+ width: 30px;
+}
+th.rotate > div > span {
+ border-bottom: 1px solid #ccc;
+ padding: 8px 0px;
+ font-size: 16px;
+}
+table.sqlresult td {
+ padding: 1px 3px;
+ /*font-size: 16px;*/
+}
+table.sqlresult th {
+ padding: 1px 1px;
+ text-align: center;
+ /*font-size: 16px;*/
+}
+</style>
+<link rel="stylesheet" href="style.min.css" />
+<script src="viewer.js"></script>
+<script src="jstree.min.js"></script>
+</head>
+<body>
+<ul class="nav nav-tabs">
+ <li class="active">
+ <a href="#overview" data-toggle="tab">Overview</a>
+ </li>
+ <li>
+ <a href="#tablets" data-toggle="tab">Tablets</a>
+ </li>
+ <li>
+ <a href="#storage" data-toggle="tab">Storage</a>
+ </li>
+ <li>
+ <a href="#nodes" data-toggle="tab">Nodes</a>
+ </li>
+ <li>
+ <a href="#schema" data-toggle="tab">Schema</a>
+ </li>
+</ul>
+<div class="tab-content" style="padding-top: 10px">
+ <div id="overview" class="tab-pane fade in active container">
+ <table class="nstats node-stats" style="margin-top: 20px">
+ <tr>
+ <th style='min-width:120px'></th>
+ <th><div><span>Dead</span></div></th>
+ <th><div><span>&lt; Minute</span></div></th>
+ <th><div><span>&lt; Hour</span></div></th>
+ <th><div><span>&lt; Day</span></div></th>
+ <th><div><span>Day+</span></div></th>
+ </tr>
+ <tr>
+ <td>Nodes Age</td>
+ <td class='tcounter' style='color:black'></td>
+ <td class='tcounter' style='color:red'></td>
+ <td class='tcounter' style='color:orange'></td>
+ <td class='tcounter' style='color:yellow'></td>
+ <td class='tcounter' style='color:lightgreen'></td>
+ </tr>
+ <tr>
+ <td>Tablets Age</td>
+ <td class='tcounter' style='color:black'></td>
+ <td class='tcounter' style='color:red'></td>
+ <td class='tcounter' style='color:orange'></td>
+ <td class='tcounter' style='color:yellow'></td>
+ <td class='tcounter' style='color:lightgreen'></td>
+ </tr>
+ </table>
+ <table class="nstats disk-stats" style="margin-top: 30px">
+ <tr>
+ <th style='min-width:120px'></th>
+ <th><div><span>Grey</span></div></th>
+ <th><div><span>Red</span></div></th>
+ <th><div><span>Orange</span></div></th>
+ <th><div><span>Yellow</span></div></th>
+ <th><div><span>Green</span></div></th>
+ </tr>
+ <tr>
+ <td>PDisks</td>
+ <td class='tcounter' style='color:grey'></td>
+ <td class='tcounter' style='color:red'></td>
+ <td class='tcounter' style='color:orange'></td>
+ <td class='tcounter' style='color:yellow'></td>
+ <td class='tcounter' style='color:lightgreen'></td>
+ </tr>
+ <tr>
+ <td>VDisks</td>
+ <td class='tcounter' style='color:grey'></td>
+ <td class='tcounter' style='color:red'></td>
+ <td class='tcounter' style='color:orange'></td>
+ <td class='tcounter' style='color:yellow'></td>
+ <td class='tcounter' style='color:lightgreen'></td>
+ </tr>
+ <tr>
+ <td>Groups</td>
+ <td class='tcounter' style='color:grey'></td>
+ <td class='tcounter' style='color:red'></td>
+ <td class='tcounter' style='color:orange'></td>
+ <td class='tcounter' style='color:yellow'></td>
+ <td class='tcounter' style='color:lightgreen'></td>
+ </tr>
+ </table>
+ <table class="tstats tablet-stats">
+ <tr>
+ <th class='rotate' style='min-width:120px'></th>
+ <th class='rotate'><div><span>Dead</span></div></th>
+ <th class='rotate'><div><span>Created</span></div></th>
+ <th class='rotate'><div><span>ResolveStateStorage</span></div></th>
+ <th class='rotate'><div><span>Lock</span></div></th>
+ <th class='rotate'><div><span>Discover</span></div></th>
+ <th class='rotate'><div><span>Candidate</span></div></th>
+ <th class='rotate'><div><span>BlockBlobStorage</span></div></th>
+ <th class='rotate'><div><span>RebuildGraph</span></div></th>
+ <th class='rotate'><div><span>WriteZeroEntry</span></div></th>
+ <th class='rotate'><div><span>Restored</span></div></th>
+ <th class='rotate'><div><span>Active</span></div></th>
+ </tr>
+ </table>
+ </div>
+ <table id="tablets" class="tab-pane fade">
+ <tr>
+ <td>
+ <table>
+ <tr>
+ <td>
+ <div style="font-size: 14px;">Group by:</div>
+ <form style="font-size: 14px; padding-left:10px; padding-bottom:10px">
+ <label class="radio-inline"><input type="radio" name="optgroupradio" checked="checked" onchange="onTabletGroupChange(this);" value="ungrouped">Ungrouped</label>
+ <label class="radio-inline"><input type="radio" name="optgroupradio" onchange="onTabletGroupChange(this);" value="type">Type</label>
+ <label class="radio-inline"><input type="radio" name="optgroupradio" onchange="onTabletGroupChange(this);" value="state">State</label>
+ <label class="radio-inline"><input type="radio" name="optgroupradio" onchange="onTabletGroupChange(this);" value="node">Node</label>
+ </form>
+ </td>
+ <td style="padding-left: 40px">
+ <div style="font-size: 14px;">Coloring by:</div>
+ <form style="font-size: 14px; padding-left:10px; padding-bottom:10px">
+ <label class="radio-inline"><input type="radio" name="optcolorradio" checked="checked" onchange="onTabletColorChange(this);" value="state">State</label>
+ <label class="radio-inline"><input type="radio" name="optcolorradio" onchange="onTabletColorChange(this);" value="type">Type</label>
+ </form>
+ </td>
+ <td style="padding-left: 40px">
+ <button type="button" class="btn btn-default btn-md" onclick="$('.tabletgroupcontainer').collapse('show');">Expand All</button>
+ <button type="button" class="btn btn-default btn-md" onclick="$('.tabletgroupcontainer').collapse('hide');">Collapse All</button>
+ </td>
+ </tr>
+ </table>
+ <div id="panel-all-tablets"><img src="throbber.gif" style="padding-left:10px"></div>
+ </td>
+ </tr>
+ </table>
+ <div id="storage" class="tab-pane fade">
+ <table class="totalstorage" style="margin-top:10px;margin-bottom:15px">
+ <thead>
+ <tr>
+ <th>&nbsp;</th>
+ <th>Usage</th>
+ <th>Used</th>
+ <th>Available</th>
+ <th>Total</th>
+ </tr>
+ </thead>
+ <tbody>
+ <tr>
+ <td>Total</td>
+ <td>&nbsp;</td>
+ <td>&nbsp;</td>
+ <td>&nbsp;</td>
+ <td>&nbsp;</td>
+ </tr>
+ <tr>
+ <td>Dynamic</td>
+ <td>&nbsp;</td>
+ <td>&nbsp;</td>
+ <td>&nbsp;</td>
+ <td>&nbsp;</td>
+ </tr>
+ <tr>
+ <td>Static</td>
+ <td>&nbsp;</td>
+ <td>&nbsp;</td>
+ <td>&nbsp;</td>
+ <td>&nbsp;</td>
+ </tr>
+ </tbody>
+ </table>
+ <table class="grouplist" style="margin-bottom:15px">
+ <thead>
+ <tr>
+ <th>Group</th>
+ <th>Type</th>
+ <th>Erasure</th>
+ <th>Latency</th>
<th>VDisks</th>
- <th>Usage</th>
- <th style='width:70px'>Delta</th>
- <th style='width:60px'>Used</th>
- <th style='width:60px'>Available</th>
- <th style='width:60px'>Total</th>
- <th>PDisks</th>
- </tr>
- </thead>
- </table>
- </div>
- <table id="nodes" class="nodelist tab-pane fade">
- <thead>
- <tr>
- <th>#</th>
- <th>Node</th>
- <th>Uptime</th>
- <th>CPU</th>
- <th>Network</th>
- <th colspan='99'>Disks</th>
- </tr>
- </thead>
- </table>
- <div id="schema" class="tab-pane fade">
- <table style="width:100%">
- <tr>
- <td style="width:20%; padding:10px">
- <div class="panel panel-default" style="height:650px;overflow:auto">
- <div class="panel-heading">Tree</div>
- <div id="schema-tree" class="panel-body"></div>
- </div>
- </td>
- <td style="padding:10px">
- <div id="panel-tablets" class="panel panel-default" style="height:650px;overflow:auto">
- <div class="panel-heading">Content</div>
- <div class="panel-body"></div>
- </div>
- </td>
- <td style="width:35%; padding:10px">
- <div id="panel-info" class="panel panel-default" style="height:360px;overflow:auto">
- <div class="panel-heading">Info</div>
- <div class="panel-body"></div>
- </div>
- <div id="panel-schema" class="panel panel-default" style="height:270px;overflow:auto">
- <div class="panel-heading">Schema</div>
- <div class="panel-body" style="overflow:auto"></div>
- </div>
- </td>
- </tr>
- <tr>
- <td colspan='3' style="width:100%; padding-left:10px; padding-right:10px">
- <div class="panel-group">
- <div id="panel-sql" class="panel panel-default" style="">
- <div class="panel-heading">Database Query</div>
- <div class="panel-body" style="padding:5px">
- <textarea id="panel-sql-text" rows="10" placeholder="SQL" style="width:100%; resize:none; font-family:Courier New"></textarea>
- <button id="panel-sql-button-run" type="button" class="btn btn-default" style="padding-top:0px; padding-bottom:0px;"><span class="glyphicon glyphicon-play"></span></button>
- </div>
- </div>
- <div id="panel-sql-result" class="panel panel-default" style="display:none">
- <div class="panel-heading">Query Result</div>
- <div class="panel-body" style="padding:5px">
- <table id="sql-result" class="table table-sortable">
- </table>
- </div>
- </div>
- <div id="panel-sql-error" class="panel panel-danger" style="display:none">
- <div class="panel-heading">Query Error</div>
- <div class="panel-body" style="padding:5px">
- <span id="sql-error">
- </span>
- </div>
- </div>
- </div>
- </td>
- </tr>
- </table>
- </div>
-</div>
-<script>
- // making main container wider
- $('.container').toggleClass('container container-fluid');
-
- if (window.location.hash == '') {
- window.location.hash = 'page=overview';
- } else {
- window.location.hash.substr(1).split('&').forEach((o) => { var a = o.split('='); Parameters[a[0]] = decodeURIComponent(a[1]); } );
- if (Parameters.page != undefined) {
- $('.nav-tabs a[href="#' + Parameters.page + '"]').tab('show');
- }
- }
-
- // Change hash for page-reload
- $('.nav-tabs a').on('shown.bs.tab', function (e) {
- Parameters.page = e.target.hash.substr(1);
- window.location.hash = $.param(Parameters);
- })
-
- // start data polling
- main();
-</script>
-</body>
-</html>
+ <th>Usage</th>
+ <th style='width:70px'>Delta</th>
+ <th style='width:60px'>Used</th>
+ <th style='width:60px'>Available</th>
+ <th style='width:60px'>Total</th>
+ <th>PDisks</th>
+ </tr>
+ </thead>
+ </table>
+ </div>
+ <table id="nodes" class="nodelist tab-pane fade">
+ <thead>
+ <tr>
+ <th>#</th>
+ <th>Node</th>
+ <th>Uptime</th>
+ <th>CPU</th>
+ <th>Network</th>
+ <th colspan='99'>Disks</th>
+ </tr>
+ </thead>
+ </table>
+ <div id="schema" class="tab-pane fade">
+ <table style="width:100%">
+ <tr>
+ <td style="width:20%; padding:10px">
+ <div class="panel panel-default" style="height:650px;overflow:auto">
+ <div class="panel-heading">Tree</div>
+ <div id="schema-tree" class="panel-body"></div>
+ </div>
+ </td>
+ <td style="padding:10px">
+ <div id="panel-tablets" class="panel panel-default" style="height:650px;overflow:auto">
+ <div class="panel-heading">Content</div>
+ <div class="panel-body"></div>
+ </div>
+ </td>
+ <td style="width:35%; padding:10px">
+ <div id="panel-info" class="panel panel-default" style="height:360px;overflow:auto">
+ <div class="panel-heading">Info</div>
+ <div class="panel-body"></div>
+ </div>
+ <div id="panel-schema" class="panel panel-default" style="height:270px;overflow:auto">
+ <div class="panel-heading">Schema</div>
+ <div class="panel-body" style="overflow:auto"></div>
+ </div>
+ </td>
+ </tr>
+ <tr>
+ <td colspan='3' style="width:100%; padding-left:10px; padding-right:10px">
+ <div class="panel-group">
+ <div id="panel-sql" class="panel panel-default" style="">
+ <div class="panel-heading">Database Query</div>
+ <div class="panel-body" style="padding:5px">
+ <textarea id="panel-sql-text" rows="10" placeholder="SQL" style="width:100%; resize:none; font-family:Courier New"></textarea>
+ <button id="panel-sql-button-run" type="button" class="btn btn-default" style="padding-top:0px; padding-bottom:0px;"><span class="glyphicon glyphicon-play"></span></button>
+ </div>
+ </div>
+ <div id="panel-sql-result" class="panel panel-default" style="display:none">
+ <div class="panel-heading">Query Result</div>
+ <div class="panel-body" style="padding:5px">
+ <table id="sql-result" class="table table-sortable">
+ </table>
+ </div>
+ </div>
+ <div id="panel-sql-error" class="panel panel-danger" style="display:none">
+ <div class="panel-heading">Query Error</div>
+ <div class="panel-body" style="padding:5px">
+ <span id="sql-error">
+ </span>
+ </div>
+ </div>
+ </div>
+ </td>
+ </tr>
+ </table>
+ </div>
+</div>
+<script>
+ // making main container wider
+ $('.container').toggleClass('container container-fluid');
+
+ if (window.location.hash == '') {
+ window.location.hash = 'page=overview';
+ } else {
+ window.location.hash.substr(1).split('&').forEach((o) => { var a = o.split('='); Parameters[a[0]] = decodeURIComponent(a[1]); } );
+ if (Parameters.page != undefined) {
+ $('.nav-tabs a[href="#' + Parameters.page + '"]').tab('show');
+ }
+ }
+
+ // Change hash for page-reload
+ $('.nav-tabs a').on('shown.bs.tab', function (e) {
+ Parameters.page = e.target.hash.substr(1);
+ window.location.hash = $.param(Parameters);
+ })
+
+ // start data polling
+ main();
+</script>
+</body>
+</html>
diff --git a/ydb/core/viewer/content/jstree.min.js b/ydb/core/viewer/content/jstree.min.js
index ac7a167c7ee..486a0610583 100644
--- a/ydb/core/viewer/content/jstree.min.js
+++ b/ydb/core/viewer/content/jstree.min.js
@@ -1,6 +1,6 @@
-/*! jsTree - v3.3.2 - 2016-08-15 - (MIT) */
-!function(a){"use strict";"function"==typeof define&&define.amd?define(["jquery"],a):"undefined"!=typeof module&&module.exports?module.exports=a(require("jquery")):a(jQuery)}(function(a,b){"use strict";if(!a.jstree){var c=0,d=!1,e=!1,f=!1,g=[],h=a("script:last").attr("src"),i=window.document,j=i.createElement("LI"),k,l;j.setAttribute("role","treeitem"),k=i.createElement("I"),k.className="jstree-icon jstree-ocl",k.setAttribute("role","presentation"),j.appendChild(k),k=i.createElement("A"),k.className="jstree-anchor",k.setAttribute("href","#"),k.setAttribute("tabindex","-1"),l=i.createElement("I"),l.className="jstree-icon jstree-themeicon",l.setAttribute("role","presentation"),k.appendChild(l),j.appendChild(k),k=l=null,a.jstree={version:"3.3.2",defaults:{plugins:[]},plugins:{},path:h&&-1!==h.indexOf("/")?h.replace(/\/[^\/]+$/,""):"",idregex:/[\\:&!^|()\[\]<>@*'+~#";.,=\- \/${}%?`]/g,root:"#"},a.jstree.create=function(b,d){var e=new a.jstree.core(++c),f=d;return d=a.extend(!0,{},a.jstree.defaults,d),f&&f.plugins&&(d.plugins=f.plugins),a.each(d.plugins,function(a,b){"core"!==a&&(e=e.plugin(b,d[b]))}),a(b).data("jstree",e),e.init(b,d),e},a.jstree.destroy=function(){a(".jstree:jstree").jstree("destroy"),a(i).off(".jstree")},a.jstree.core=function(a){this._id=a,this._cnt=0,this._wrk=null,this._data={core:{themes:{name:!1,dots:!1,icons:!1},selected:[],last_error:{},working:!1,worker_queue:[],focused:null}}},a.jstree.reference=function(b){var c=null,d=null;if(!b||!b.id||b.tagName&&b.nodeType||(b=b.id),!d||!d.length)try{d=a(b)}catch(e){}if(!d||!d.length)try{d=a("#"+b.replace(a.jstree.idregex,"\\$&"))}catch(e){}return d&&d.length&&(d=d.closest(".jstree")).length&&(d=d.data("jstree"))?c=d:a(".jstree").each(function(){var d=a(this).data("jstree");return d&&d._model.data[b]?(c=d,!1):void 0}),c},a.fn.jstree=function(c){var d="string"==typeof c,e=Array.prototype.slice.call(arguments,1),f=null;return c!==!0||this.length?(this.each(function(){var g=a.jstree.reference(this),h=d&&g?g[c]:null;return f=d&&h?h.apply(g,e):null,g||d||c!==b&&!a.isPlainObject(c)||a.jstree.create(this,c),(g&&!d||c===!0)&&(f=g||!1),null!==f&&f!==b?!1:void 0}),null!==f&&f!==b?f:this):!1},a.expr.pseudos.jstree=a.expr.createPseudo(function(c){return function(c){return a(c).hasClass("jstree")&&a(c).data("jstree")!==b}}),a.jstree.defaults.core={data:!1,strings:!1,check_callback:!1,error:a.noop,animation:200,multiple:!0,themes:{name:!1,url:!1,dir:!1,dots:!0,icons:!0,stripes:!1,variant:!1,responsive:!1},expand_selected_onload:!0,worker:!0,force_text:!1,dblclick_toggle:!0},a.jstree.core.prototype={plugin:function(b,c){var d=a.jstree.plugins[b];return d?(this._data[b]={},d.prototype=this,new d(c,this)):this},init:function(b,c){this._model={data:{},changed:[],force_full_redraw:!1,redraw_timeout:!1,default_state:{loaded:!0,opened:!1,selected:!1,disabled:!1}},this._model.data[a.jstree.root]={id:a.jstree.root,parent:null,parents:[],children:[],children_d:[],state:{loaded:!1}},this.element=a(b).addClass("jstree jstree-"+this._id),this.settings=c,this._data.core.ready=!1,this._data.core.loaded=!1,this._data.core.rtl="rtl"===this.element.css("direction"),this.element[this._data.core.rtl?"addClass":"removeClass"]("jstree-rtl"),this.element.attr("role","tree"),this.settings.core.multiple&&this.element.attr("aria-multiselectable",!0),this.element.attr("tabindex")||this.element.attr("tabindex","0"),this.bind(),this.trigger("init"),this._data.core.original_container_html=this.element.find(" > ul > li").clone(!0),this._data.core.original_container_html.find("li").addBack().contents().filter(function(){return 3===this.nodeType&&(!this.nodeValue||/^\s+$/.test(this.nodeValue))}).remove(),this.element.html("<ul class='jstree-container-ul jstree-children' role='group'><li id='j"+this._id+"_loading' class='jstree-initial-node jstree-loading jstree-leaf jstree-last' role='tree-item'><i class='jstree-icon jstree-ocl'></i><a class='jstree-anchor' href='#'><i class='jstree-icon jstree-themeicon-hidden'></i>"+this.get_string("Loading ...")+"</a></li></ul>"),this.element.attr("aria-activedescendant","j"+this._id+"_loading"),this._data.core.li_height=this.get_container_ul().children("li").first().height()||24,this.trigger("loading"),this.load_node(a.jstree.root)},destroy:function(a){if(this._wrk)try{window.URL.revokeObjectURL(this._wrk),this._wrk=null}catch(b){}a||this.element.empty(),this.teardown()},teardown:function(){this.unbind(),this.element.removeClass("jstree").removeData("jstree").find("[class^='jstree']").addBack().attr("class",function(){return this.className.replace(/jstree[^ ]*|$/gi,"")}),this.element=null},bind:function(){var b="",c=null,d=0;this.element.on("dblclick.jstree",function(a){if(a.target.tagName&&"input"===a.target.tagName.toLowerCase())return!0;if(i.selection&&i.selection.empty)i.selection.empty();else if(window.getSelection){var b=window.getSelection();try{b.removeAllRanges(),b.collapse()}catch(c){}}}).on("mousedown.jstree",a.proxy(function(a){a.target===this.element[0]&&(a.preventDefault(),d=+new Date)},this)).on("mousedown.jstree",".jstree-ocl",function(a){a.preventDefault()}).on("click.jstree",".jstree-ocl",a.proxy(function(a){this.toggle_node(a.target)},this)).on("dblclick.jstree",".jstree-anchor",a.proxy(function(a){return a.target.tagName&&"input"===a.target.tagName.toLowerCase()?!0:void(this.settings.core.dblclick_toggle&&this.toggle_node(a.target))},this)).on("click.jstree",".jstree-anchor",a.proxy(function(b){b.preventDefault(),b.currentTarget!==i.activeElement&&a(b.currentTarget).focus(),this.activate_node(b.currentTarget,b)},this)).on("keydown.jstree",".jstree-anchor",a.proxy(function(b){if(b.target.tagName&&"input"===b.target.tagName.toLowerCase())return!0;if(32!==b.which&&13!==b.which&&(b.shiftKey||b.ctrlKey||b.altKey||b.metaKey))return!0;var c=null;switch(this._data.core.rtl&&(37===b.which?b.which=39:39===b.which&&(b.which=37)),b.which){case 32:b.ctrlKey&&(b.type="click",a(b.currentTarget).trigger(b));break;case 13:b.type="click",a(b.currentTarget).trigger(b);break;case 37:b.preventDefault(),this.is_open(b.currentTarget)?this.close_node(b.currentTarget):(c=this.get_parent(b.currentTarget),c&&c.id!==a.jstree.root&&this.get_node(c,!0).children(".jstree-anchor").focus());break;case 38:b.preventDefault(),c=this.get_prev_dom(b.currentTarget),c&&c.length&&c.children(".jstree-anchor").focus();break;case 39:b.preventDefault(),this.is_closed(b.currentTarget)?this.open_node(b.currentTarget,function(a){this.get_node(a,!0).children(".jstree-anchor").focus()}):this.is_open(b.currentTarget)&&(c=this.get_node(b.currentTarget,!0).children(".jstree-children")[0],c&&a(this._firstChild(c)).children(".jstree-anchor").focus());break;case 40:b.preventDefault(),c=this.get_next_dom(b.currentTarget),c&&c.length&&c.children(".jstree-anchor").focus();break;case 106:this.open_all();break;case 36:b.preventDefault(),c=this._firstChild(this.get_container_ul()[0]),c&&a(c).children(".jstree-anchor").filter(":visible").focus();break;case 35:b.preventDefault(),this.element.find(".jstree-anchor").filter(":visible").last().focus();break;case 113:b.preventDefault(),this.edit(b.currentTarget)}},this)).on("load_node.jstree",a.proxy(function(b,c){c.status&&(c.node.id!==a.jstree.root||this._data.core.loaded||(this._data.core.loaded=!0,this._firstChild(this.get_container_ul()[0])&&this.element.attr("aria-activedescendant",this._firstChild(this.get_container_ul()[0]).id),this.trigger("loaded")),this._data.core.ready||setTimeout(a.proxy(function(){if(this.element&&!this.get_container_ul().find(".jstree-loading").length){if(this._data.core.ready=!0,this._data.core.selected.length){if(this.settings.core.expand_selected_onload){var b=[],c,d;for(c=0,d=this._data.core.selected.length;d>c;c++)b=b.concat(this._model.data[this._data.core.selected[c]].parents);for(b=a.vakata.array_unique(b),c=0,d=b.length;d>c;c++)this.open_node(b[c],!1,0)}this.trigger("changed",{action:"ready",selected:this._data.core.selected})}this.trigger("ready")}},this),0))},this)).on("keypress.jstree",a.proxy(function(d){if(d.target.tagName&&"input"===d.target.tagName.toLowerCase())return!0;c&&clearTimeout(c),c=setTimeout(function(){b=""},500);var e=String.fromCharCode(d.which).toLowerCase(),f=this.element.find(".jstree-anchor").filter(":visible"),g=f.index(i.activeElement)||0,h=!1;if(b+=e,b.length>1){if(f.slice(g).each(a.proxy(function(c,d){return 0===a(d).text().toLowerCase().indexOf(b)?(a(d).focus(),h=!0,!1):void 0},this)),h)return;if(f.slice(0,g).each(a.proxy(function(c,d){return 0===a(d).text().toLowerCase().indexOf(b)?(a(d).focus(),h=!0,!1):void 0},this)),h)return}if(new RegExp("^"+e.replace(/[-\/\\^$*+?.()|[\]{}]/g,"\\$&")+"+$").test(b)){if(f.slice(g+1).each(a.proxy(function(b,c){return a(c).text().toLowerCase().charAt(0)===e?(a(c).focus(),h=!0,!1):void 0},this)),h)return;if(f.slice(0,g+1).each(a.proxy(function(b,c){return a(c).text().toLowerCase().charAt(0)===e?(a(c).focus(),h=!0,!1):void 0},this)),h)return}},this)).on("init.jstree",a.proxy(function(){var a=this.settings.core.themes;this._data.core.themes.dots=a.dots,this._data.core.themes.stripes=a.stripes,this._data.core.themes.icons=a.icons,this.set_theme(a.name||"default",a.url),this.set_theme_variant(a.variant)},this)).on("loading.jstree",a.proxy(function(){this[this._data.core.themes.dots?"show_dots":"hide_dots"](),this[this._data.core.themes.icons?"show_icons":"hide_icons"](),this[this._data.core.themes.stripes?"show_stripes":"hide_stripes"]()},this)).on("blur.jstree",".jstree-anchor",a.proxy(function(b){this._data.core.focused=null,a(b.currentTarget).filter(".jstree-hovered").mouseleave(),this.element.attr("tabindex","0")},this)).on("focus.jstree",".jstree-anchor",a.proxy(function(b){var c=this.get_node(b.currentTarget);c&&c.id&&(this._data.core.focused=c.id),this.element.find(".jstree-hovered").not(b.currentTarget).mouseleave(),a(b.currentTarget).mouseenter(),this.element.attr("tabindex","-1")},this)).on("focus.jstree",a.proxy(function(){if(+new Date-d>500&&!this._data.core.focused){d=0;var a=this.get_node(this.element.attr("aria-activedescendant"),!0);a&&a.find("> .jstree-anchor").focus()}},this)).on("mouseenter.jstree",".jstree-anchor",a.proxy(function(a){this.hover_node(a.currentTarget)},this)).on("mouseleave.jstree",".jstree-anchor",a.proxy(function(a){this.dehover_node(a.currentTarget)},this))},unbind:function(){this.element.off(".jstree"),a(i).off(".jstree-"+this._id)},trigger:function(a,b){b||(b={}),b.instance=this,this.element.triggerHandler(a.replace(".jstree","")+".jstree",b)},get_container:function(){return this.element},get_container_ul:function(){return this.element.children(".jstree-children").first()},get_string:function(b){var c=this.settings.core.strings;return a.isFunction(c)?c.call(this,b):c&&c[b]?c[b]:b},_firstChild:function(a){a=a?a.firstChild:null;while(null!==a&&1!==a.nodeType)a=a.nextSibling;return a},_nextSibling:function(a){a=a?a.nextSibling:null;while(null!==a&&1!==a.nodeType)a=a.nextSibling;return a},_previousSibling:function(a){a=a?a.previousSibling:null;while(null!==a&&1!==a.nodeType)a=a.previousSibling;return a},get_node:function(b,c){b&&b.id&&(b=b.id);var d;try{if(this._model.data[b])b=this._model.data[b];else if("string"==typeof b&&this._model.data[b.replace(/^#/,"")])b=this._model.data[b.replace(/^#/,"")];else if("string"==typeof b&&(d=a("#"+b.replace(a.jstree.idregex,"\\$&"),this.element)).length&&this._model.data[d.closest(".jstree-node").attr("id")])b=this._model.data[d.closest(".jstree-node").attr("id")];else if((d=a(b,this.element)).length&&this._model.data[d.closest(".jstree-node").attr("id")])b=this._model.data[d.closest(".jstree-node").attr("id")];else{if(!(d=a(b,this.element)).length||!d.hasClass("jstree"))return!1;b=this._model.data[a.jstree.root]}return c&&(b=b.id===a.jstree.root?this.element:a("#"+b.id.replace(a.jstree.idregex,"\\$&"),this.element)),b}catch(e){return!1}},get_path:function(b,c,d){if(b=b.parents?b:this.get_node(b),!b||b.id===a.jstree.root||!b.parents)return!1;var e,f,g=[];for(g.push(d?b.id:b.text),e=0,f=b.parents.length;f>e;e++)g.push(d?b.parents[e]:this.get_text(b.parents[e]));return g=g.reverse().slice(1),c?g.join(c):g},get_next_dom:function(b,c){var d;if(b=this.get_node(b,!0),b[0]===this.element[0]){d=this._firstChild(this.get_container_ul()[0]);while(d&&0===d.offsetHeight)d=this._nextSibling(d);return d?a(d):!1}if(!b||!b.length)return!1;if(c){d=b[0];do d=this._nextSibling(d);while(d&&0===d.offsetHeight);return d?a(d):!1}if(b.hasClass("jstree-open")){d=this._firstChild(b.children(".jstree-children")[0]);while(d&&0===d.offsetHeight)d=this._nextSibling(d);if(null!==d)return a(d)}d=b[0];do d=this._nextSibling(d);while(d&&0===d.offsetHeight);return null!==d?a(d):b.parentsUntil(".jstree",".jstree-node").nextAll(".jstree-node:visible").first()},get_prev_dom:function(b,c){var d;if(b=this.get_node(b,!0),b[0]===this.element[0]){d=this.get_container_ul()[0].lastChild;while(d&&0===d.offsetHeight)d=this._previousSibling(d);return d?a(d):!1}if(!b||!b.length)return!1;if(c){d=b[0];do d=this._previousSibling(d);while(d&&0===d.offsetHeight);return d?a(d):!1}d=b[0];do d=this._previousSibling(d);while(d&&0===d.offsetHeight);if(null!==d){b=a(d);while(b.hasClass("jstree-open"))b=b.children(".jstree-children").first().children(".jstree-node:visible:last");return b}return d=b[0].parentNode.parentNode,d&&d.className&&-1!==d.className.indexOf("jstree-node")?a(d):!1},get_parent:function(b){return b=this.get_node(b),b&&b.id!==a.jstree.root?b.parent:!1},get_children_dom:function(a){return a=this.get_node(a,!0),a[0]===this.element[0]?this.get_container_ul().children(".jstree-node"):a&&a.length?a.children(".jstree-children").children(".jstree-node"):!1},is_parent:function(a){return a=this.get_node(a),a&&(a.state.loaded===!1||a.children.length>0)},is_loaded:function(a){return a=this.get_node(a),a&&a.state.loaded},is_loading:function(a){return a=this.get_node(a),a&&a.state&&a.state.loading},is_open:function(a){return a=this.get_node(a),a&&a.state.opened},is_closed:function(a){return a=this.get_node(a),a&&this.is_parent(a)&&!a.state.opened},is_leaf:function(a){return!this.is_parent(a)},load_node:function(b,c){var d,e,f,g,h;if(a.isArray(b))return this._load_nodes(b.slice(),c),!0;if(b=this.get_node(b),!b)return c&&c.call(this,b,!1),!1;if(b.state.loaded){for(b.state.loaded=!1,f=0,g=b.parents.length;g>f;f++)this._model.data[b.parents[f]].children_d=a.vakata.array_filter(this._model.data[b.parents[f]].children_d,function(c){return-1===a.inArray(c,b.children_d)});for(d=0,e=b.children_d.length;e>d;d++)this._model.data[b.children_d[d]].state.selected&&(h=!0),delete this._model.data[b.children_d[d]];h&&(this._data.core.selected=a.vakata.array_filter(this._data.core.selected,function(c){return-1===a.inArray(c,b.children_d)})),b.children=[],b.children_d=[],h&&this.trigger("changed",{action:"load_node",node:b,selected:this._data.core.selected})}return b.state.failed=!1,b.state.loading=!0,this.get_node(b,!0).addClass("jstree-loading").attr("aria-busy",!0),this._load_node(b,a.proxy(function(a){b=this._model.data[b.id],b.state.loading=!1,b.state.loaded=a,b.state.failed=!b.state.loaded;var d=this.get_node(b,!0),e=0,f=0,g=this._model.data,h=!1;for(e=0,f=b.children.length;f>e;e++)if(g[b.children[e]]&&!g[b.children[e]].state.hidden){h=!0;break}b.state.loaded&&d&&d.length&&(d.removeClass("jstree-closed jstree-open jstree-leaf"),h?"#"!==b.id&&d.addClass(b.state.opened?"jstree-open":"jstree-closed"):d.addClass("jstree-leaf")),d.removeClass("jstree-loading").attr("aria-busy",!1),this.trigger("load_node",{node:b,status:a}),c&&c.call(this,b,a)},this)),!0},_load_nodes:function(a,b,c,d){var e=!0,f=function(){this._load_nodes(a,b,!0)},g=this._model.data,h,i,j=[];for(h=0,i=a.length;i>h;h++)g[a[h]]&&(!g[a[h]].state.loaded&&!g[a[h]].state.failed||!c&&d)&&(this.is_loading(a[h])||this.load_node(a[h],f),e=!1);if(e){for(h=0,i=a.length;i>h;h++)g[a[h]]&&g[a[h]].state.loaded&&j.push(a[h]);b&&!b.done&&(b.call(this,j),b.done=!0)}},load_all:function(b,c){if(b||(b=a.jstree.root),b=this.get_node(b),!b)return!1;var d=[],e=this._model.data,f=e[b.id].children_d,g,h;for(b.state&&!b.state.loaded&&d.push(b.id),g=0,h=f.length;h>g;g++)e[f[g]]&&e[f[g]].state&&!e[f[g]].state.loaded&&d.push(f[g]);d.length?this._load_nodes(d,function(){this.load_all(b,c)}):(c&&c.call(this,b),this.trigger("load_all",{node:b}))},_load_node:function(b,c){var d=this.settings.core.data,e,f=function g(){return 3!==this.nodeType&&8!==this.nodeType};return d?a.isFunction(d)?d.call(this,b,a.proxy(function(d){d===!1?c.call(this,!1):this["string"==typeof d?"_append_html_data":"_append_json_data"](b,"string"==typeof d?a(a.parseHTML(d)).filter(f):d,function(a){c.call(this,a)})},this)):"object"==typeof d?d.url?(d=a.extend(!0,{},d),a.isFunction(d.url)&&(d.url=d.url.call(this,b)),a.isFunction(d.data)&&(d.data=d.data.call(this,b)),a.ajax(d).done(a.proxy(function(d,e,g){var h=g.getResponseHeader("Content-Type");return h&&-1!==h.indexOf("json")||"object"==typeof d?this._append_json_data(b,d,function(a){c.call(this,a)}):h&&-1!==h.indexOf("html")||"string"==typeof d?this._append_html_data(b,a(a.parseHTML(d)).filter(f),function(a){c.call(this,a)}):(this._data.core.last_error={error:"ajax",plugin:"core",id:"core_04",reason:"Could not load node",data:JSON.stringify({id:b.id,xhr:g})},this.settings.core.error.call(this,this._data.core.last_error),c.call(this,!1))},this)).fail(a.proxy(function(a){c.call(this,!1),this._data.core.last_error={error:"ajax",plugin:"core",id:"core_04",reason:"Could not load node",data:JSON.stringify({id:b.id,xhr:a})},this.settings.core.error.call(this,this._data.core.last_error)},this))):(e=a.isArray(d)||a.isPlainObject(d)?JSON.parse(JSON.stringify(d)):d,b.id===a.jstree.root?this._append_json_data(b,e,function(a){c.call(this,a)}):(this._data.core.last_error={error:"nodata",plugin:"core",id:"core_05",reason:"Could not load node",data:JSON.stringify({id:b.id})},this.settings.core.error.call(this,this._data.core.last_error),c.call(this,!1))):"string"==typeof d?b.id===a.jstree.root?this._append_html_data(b,a(a.parseHTML(d)).filter(f),function(a){c.call(this,a)}):(this._data.core.last_error={error:"nodata",plugin:"core",id:"core_06",reason:"Could not load node",data:JSON.stringify({id:b.id})},this.settings.core.error.call(this,this._data.core.last_error),c.call(this,!1)):c.call(this,!1):b.id===a.jstree.root?this._append_html_data(b,this._data.core.original_container_html.clone(!0),function(a){c.call(this,a)}):c.call(this,!1)},_node_changed:function(a){a=this.get_node(a),a&&this._model.changed.push(a.id)},_append_html_data:function(b,c,d){b=this.get_node(b),b.children=[],b.children_d=[];var e=c.is("ul")?c.children():c,f=b.id,g=[],h=[],i=this._model.data,j=i[f],k=this._data.core.selected.length,l,m,n;for(e.each(a.proxy(function(b,c){l=this._parse_model_from_html(a(c),f,j.parents.concat()),l&&(g.push(l),h.push(l),i[l].children_d.length&&(h=h.concat(i[l].children_d)))},this)),j.children=g,j.children_d=h,m=0,n=j.parents.length;n>m;m++)i[j.parents[m]].children_d=i[j.parents[m]].children_d.concat(h);this.trigger("model",{nodes:h,parent:f}),f!==a.jstree.root?(this._node_changed(f),this.redraw()):(this.get_container_ul().children(".jstree-initial-node").remove(),this.redraw(!0)),this._data.core.selected.length!==k&&this.trigger("changed",{action:"model",selected:this._data.core.selected}),d.call(this,!0)},_append_json_data:function(b,c,d,e){if(null!==this.element){b=this.get_node(b),b.children=[],b.children_d=[],c.d&&(c=c.d,"string"==typeof c&&(c=JSON.parse(c))),a.isArray(c)||(c=[c]);var f=null,g={df:this._model.default_state,dat:c,par:b.id,m:this._model.data,t_id:this._id,t_cnt:this._cnt,sel:this._data.core.selected},h=function(a,b){a.data&&(a=a.data);var c=a.dat,d=a.par,e=[],f=[],g=[],h=a.df,i=a.t_id,j=a.t_cnt,k=a.m,l=k[d],m=a.sel,n,o,p,q,r=function(a,c,d){d=d?d.concat():[],c&&d.unshift(c);var e=a.id.toString(),f,i,j,l,m={id:e,text:a.text||"",icon:a.icon!==b?a.icon:!0,parent:c,parents:d,children:a.children||[],children_d:a.children_d||[],data:a.data,state:{},li_attr:{id:!1},a_attr:{href:"#"},original:!1};for(f in h)h.hasOwnProperty(f)&&(m.state[f]=h[f]);if(a&&a.data&&a.data.jstree&&a.data.jstree.icon&&(m.icon=a.data.jstree.icon),(m.icon===b||null===m.icon||""===m.icon)&&(m.icon=!0),a&&a.data&&(m.data=a.data,a.data.jstree))for(f in a.data.jstree)a.data.jstree.hasOwnProperty(f)&&(m.state[f]=a.data.jstree[f]);if(a&&"object"==typeof a.state)for(f in a.state)a.state.hasOwnProperty(f)&&(m.state[f]=a.state[f]);if(a&&"object"==typeof a.li_attr)for(f in a.li_attr)a.li_attr.hasOwnProperty(f)&&(m.li_attr[f]=a.li_attr[f]);if(m.li_attr.id||(m.li_attr.id=e),a&&"object"==typeof a.a_attr)for(f in a.a_attr)a.a_attr.hasOwnProperty(f)&&(m.a_attr[f]=a.a_attr[f]);for(a&&a.children&&a.children===!0&&(m.state.loaded=!1,m.children=[],m.children_d=[]),k[m.id]=m,f=0,i=m.children.length;i>f;f++)j=r(k[m.children[f]],m.id,d),l=k[j],m.children_d.push(j),l.children_d.length&&(m.children_d=m.children_d.concat(l.children_d));return delete a.data,delete a.children,k[m.id].original=a,m.state.selected&&g.push(m.id),m.id},s=function(a,c,d){d=d?d.concat():[],c&&d.unshift(c);var e=!1,f,l,m,n,o;do e="j"+i+"_"+ ++j;while(k[e]);o={id:!1,text:"string"==typeof a?a:"",icon:"object"==typeof a&&a.icon!==b?a.icon:!0,parent:c,parents:d,children:[],children_d:[],data:null,state:{},li_attr:{id:!1},a_attr:{href:"#"},original:!1};for(f in h)h.hasOwnProperty(f)&&(o.state[f]=h[f]);if(a&&a.id&&(o.id=a.id.toString()),a&&a.text&&(o.text=a.text),a&&a.data&&a.data.jstree&&a.data.jstree.icon&&(o.icon=a.data.jstree.icon),(o.icon===b||null===o.icon||""===o.icon)&&(o.icon=!0),a&&a.data&&(o.data=a.data,a.data.jstree))for(f in a.data.jstree)a.data.jstree.hasOwnProperty(f)&&(o.state[f]=a.data.jstree[f]);if(a&&"object"==typeof a.state)for(f in a.state)a.state.hasOwnProperty(f)&&(o.state[f]=a.state[f]);if(a&&"object"==typeof a.li_attr)for(f in a.li_attr)a.li_attr.hasOwnProperty(f)&&(o.li_attr[f]=a.li_attr[f]);if(o.li_attr.id&&!o.id&&(o.id=o.li_attr.id.toString()),o.id||(o.id=e),o.li_attr.id||(o.li_attr.id=o.id),a&&"object"==typeof a.a_attr)for(f in a.a_attr)a.a_attr.hasOwnProperty(f)&&(o.a_attr[f]=a.a_attr[f]);if(a&&a.children&&a.children.length){for(f=0,l=a.children.length;l>f;f++)m=s(a.children[f],o.id,d),n=k[m],o.children.push(m),n.children_d.length&&(o.children_d=o.children_d.concat(n.children_d));o.children_d=o.children_d.concat(o.children)}return a&&a.children&&a.children===!0&&(o.state.loaded=!1,o.children=[],o.children_d=[]),delete a.data,delete a.children,o.original=a,k[o.id]=o,o.state.selected&&g.push(o.id),o.id};if(c.length&&c[0].id!==b&&c[0].parent!==b){for(o=0,p=c.length;p>o;o++)c[o].children||(c[o].children=[]),k[c[o].id.toString()]=c[o];for(o=0,p=c.length;p>o;o++)k[c[o].parent.toString()].children.push(c[o].id.toString()),l.children_d.push(c[o].id.toString());for(o=0,p=l.children.length;p>o;o++)n=r(k[l.children[o]],d,l.parents.concat()),f.push(n),k[n].children_d.length&&(f=f.concat(k[n].children_d));for(o=0,p=l.parents.length;p>o;o++)k[l.parents[o]].children_d=k[l.parents[o]].children_d.concat(f);q={cnt:j,mod:k,sel:m,par:d,dpc:f,add:g}}else{for(o=0,p=c.length;p>o;o++)n=s(c[o],d,l.parents.concat()),n&&(e.push(n),f.push(n),k[n].children_d.length&&(f=f.concat(k[n].children_d)));for(l.children=e,l.children_d=f,o=0,p=l.parents.length;p>o;o++)k[l.parents[o]].children_d=k[l.parents[o]].children_d.concat(f);q={cnt:j,mod:k,sel:m,par:d,dpc:f,add:g}}return"undefined"!=typeof window&&"undefined"!=typeof window.document?q:void postMessage(q)},i=function(b,c){if(null!==this.element){this._cnt=b.cnt;var e,f=this._model.data;for(e in f)f.hasOwnProperty(e)&&f[e].state&&f[e].state.loading&&b.mod[e]&&(b.mod[e].state.loading=!0);if(this._model.data=b.mod,c){var g,h=b.add,i=b.sel,j=this._data.core.selected.slice();if(f=this._model.data,i.length!==j.length||a.vakata.array_unique(i.concat(j)).length!==i.length){for(e=0,g=i.length;g>e;e++)-1===a.inArray(i[e],h)&&-1===a.inArray(i[e],j)&&(f[i[e]].state.selected=!1);for(e=0,g=j.length;g>e;e++)-1===a.inArray(j[e],i)&&(f[j[e]].state.selected=!0)}}b.add.length&&(this._data.core.selected=this._data.core.selected.concat(b.add)),this.trigger("model",{nodes:b.dpc,parent:b.par}),b.par!==a.jstree.root?(this._node_changed(b.par),this.redraw()):this.redraw(!0),b.add.length&&this.trigger("changed",{action:"model",selected:this._data.core.selected}),d.call(this,!0)}};if(this.settings.core.worker&&window.Blob&&window.URL&&window.Worker)try{null===this._wrk&&(this._wrk=window.URL.createObjectURL(new window.Blob(["self.onmessage = "+h.toString()],{type:"text/javascript"}))),!this._data.core.working||e?(this._data.core.working=!0,f=new window.Worker(this._wrk),f.onmessage=a.proxy(function(a){i.call(this,a.data,!0);try{f.terminate(),f=null}catch(b){}this._data.core.worker_queue.length?this._append_json_data.apply(this,this._data.core.worker_queue.shift()):this._data.core.working=!1},this),g.par?f.postMessage(g):this._data.core.worker_queue.length?this._append_json_data.apply(this,this._data.core.worker_queue.shift()):this._data.core.working=!1):this._data.core.worker_queue.push([b,c,d,!0])}catch(j){i.call(this,h(g),!1),this._data.core.worker_queue.length?this._append_json_data.apply(this,this._data.core.worker_queue.shift()):this._data.core.working=!1}else i.call(this,h(g),!1)}},_parse_model_from_html:function(c,d,e){e=e?[].concat(e):[],d&&e.unshift(d);var f,g,h=this._model.data,i={id:!1,text:!1,icon:!0,parent:d,parents:e,children:[],children_d:[],data:null,state:{},li_attr:{id:!1},a_attr:{href:"#"},original:!1},j,k,l;for(j in this._model.default_state)this._model.default_state.hasOwnProperty(j)&&(i.state[j]=this._model.default_state[j]);if(k=a.vakata.attributes(c,!0),a.each(k,function(b,c){return c=a.trim(c),c.length?(i.li_attr[b]=c,void("id"===b&&(i.id=c.toString()))):!0}),k=c.children("a").first(),k.length&&(k=a.vakata.attributes(k,!0),a.each(k,function(b,c){c=a.trim(c),c.length&&(i.a_attr[b]=c)})),k=c.children("a").first().length?c.children("a").first().clone():c.clone(),k.children("ins, i, ul").remove(),k=k.html(),k=a("<div />").html(k),i.text=this.settings.core.force_text?k.text():k.html(),k=c.data(),i.data=k?a.extend(!0,{},k):null,i.state.opened=c.hasClass("jstree-open"),i.state.selected=c.children("a").hasClass("jstree-clicked"),i.state.disabled=c.children("a").hasClass("jstree-disabled"),i.data&&i.data.jstree)for(j in i.data.jstree)i.data.jstree.hasOwnProperty(j)&&(i.state[j]=i.data.jstree[j]);k=c.children("a").children(".jstree-themeicon"),k.length&&(i.icon=k.hasClass("jstree-themeicon-hidden")?!1:k.attr("rel")),i.state.icon!==b&&(i.icon=i.state.icon),(i.icon===b||null===i.icon||""===i.icon)&&(i.icon=!0),k=c.children("ul").children("li");do l="j"+this._id+"_"+ ++this._cnt;while(h[l]);return i.id=i.li_attr.id?i.li_attr.id.toString():l,k.length?(k.each(a.proxy(function(b,c){f=this._parse_model_from_html(a(c),i.id,e),g=this._model.data[f],i.children.push(f),g.children_d.length&&(i.children_d=i.children_d.concat(g.children_d))},this)),i.children_d=i.children_d.concat(i.children)):c.hasClass("jstree-closed")&&(i.state.loaded=!1),i.li_attr["class"]&&(i.li_attr["class"]=i.li_attr["class"].replace("jstree-closed","").replace("jstree-open","")),i.a_attr["class"]&&(i.a_attr["class"]=i.a_attr["class"].replace("jstree-clicked","").replace("jstree-disabled","")),h[i.id]=i,i.state.selected&&this._data.core.selected.push(i.id),i.id},_parse_model_from_flat_json:function(a,c,d){d=d?d.concat():[],c&&d.unshift(c);var e=a.id.toString(),f=this._model.data,g=this._model.default_state,h,i,j,k,l={id:e,text:a.text||"",icon:a.icon!==b?a.icon:!0,parent:c,parents:d,children:a.children||[],children_d:a.children_d||[],data:a.data,state:{},li_attr:{id:!1},a_attr:{href:"#"},original:!1};for(h in g)g.hasOwnProperty(h)&&(l.state[h]=g[h]);if(a&&a.data&&a.data.jstree&&a.data.jstree.icon&&(l.icon=a.data.jstree.icon),(l.icon===b||null===l.icon||""===l.icon)&&(l.icon=!0),a&&a.data&&(l.data=a.data,a.data.jstree))for(h in a.data.jstree)a.data.jstree.hasOwnProperty(h)&&(l.state[h]=a.data.jstree[h]);if(a&&"object"==typeof a.state)for(h in a.state)a.state.hasOwnProperty(h)&&(l.state[h]=a.state[h]);if(a&&"object"==typeof a.li_attr)for(h in a.li_attr)a.li_attr.hasOwnProperty(h)&&(l.li_attr[h]=a.li_attr[h]);if(l.li_attr.id||(l.li_attr.id=e),a&&"object"==typeof a.a_attr)for(h in a.a_attr)a.a_attr.hasOwnProperty(h)&&(l.a_attr[h]=a.a_attr[h]);for(a&&a.children&&a.children===!0&&(l.state.loaded=!1,l.children=[],l.children_d=[]),f[l.id]=l,h=0,i=l.children.length;i>h;h++)j=this._parse_model_from_flat_json(f[l.children[h]],l.id,d),k=f[j],l.children_d.push(j),k.children_d.length&&(l.children_d=l.children_d.concat(k.children_d));return delete a.data,delete a.children,f[l.id].original=a,l.state.selected&&this._data.core.selected.push(l.id),l.id},_parse_model_from_json:function(a,c,d){d=d?d.concat():[],c&&d.unshift(c);var e=!1,f,g,h,i,j=this._model.data,k=this._model.default_state,l;do e="j"+this._id+"_"+ ++this._cnt;while(j[e]);l={id:!1,text:"string"==typeof a?a:"",icon:"object"==typeof a&&a.icon!==b?a.icon:!0,parent:c,parents:d,children:[],children_d:[],data:null,state:{},li_attr:{id:!1},a_attr:{href:"#"},original:!1};for(f in k)k.hasOwnProperty(f)&&(l.state[f]=k[f]);if(a&&a.id&&(l.id=a.id.toString()),a&&a.text&&(l.text=a.text),a&&a.data&&a.data.jstree&&a.data.jstree.icon&&(l.icon=a.data.jstree.icon),(l.icon===b||null===l.icon||""===l.icon)&&(l.icon=!0),a&&a.data&&(l.data=a.data,a.data.jstree))for(f in a.data.jstree)a.data.jstree.hasOwnProperty(f)&&(l.state[f]=a.data.jstree[f]);if(a&&"object"==typeof a.state)for(f in a.state)a.state.hasOwnProperty(f)&&(l.state[f]=a.state[f]);if(a&&"object"==typeof a.li_attr)for(f in a.li_attr)a.li_attr.hasOwnProperty(f)&&(l.li_attr[f]=a.li_attr[f]);if(l.li_attr.id&&!l.id&&(l.id=l.li_attr.id.toString()),l.id||(l.id=e),l.li_attr.id||(l.li_attr.id=l.id),a&&"object"==typeof a.a_attr)for(f in a.a_attr)a.a_attr.hasOwnProperty(f)&&(l.a_attr[f]=a.a_attr[f]);if(a&&a.children&&a.children.length){for(f=0,g=a.children.length;g>f;f++)h=this._parse_model_from_json(a.children[f],l.id,d),i=j[h],l.children.push(h),i.children_d.length&&(l.children_d=l.children_d.concat(i.children_d));l.children_d=l.children_d.concat(l.children)}return a&&a.children&&a.children===!0&&(l.state.loaded=!1,l.children=[],l.children_d=[]),delete a.data,delete a.children,l.original=a,j[l.id]=l,l.state.selected&&this._data.core.selected.push(l.id),l.id},_redraw:function(){var b=this._model.force_full_redraw?this._model.data[a.jstree.root].children.concat([]):this._model.changed.concat([]),c=i.createElement("UL"),d,e,f,g=this._data.core.focused;for(e=0,f=b.length;f>e;e++)d=this.redraw_node(b[e],!0,this._model.force_full_redraw),d&&this._model.force_full_redraw&&c.appendChild(d);this._model.force_full_redraw&&(c.className=this.get_container_ul()[0].className,c.setAttribute("role","group"),this.element.empty().append(c)),null!==g&&(d=this.get_node(g,!0),d&&d.length&&d.children(".jstree-anchor")[0]!==i.activeElement?d.children(".jstree-anchor").focus():this._data.core.focused=null),this._model.force_full_redraw=!1,this._model.changed=[],this.trigger("redraw",{nodes:b})},redraw:function(a){a&&(this._model.force_full_redraw=!0),this._redraw()},draw_children:function(b){var c=this.get_node(b),d=!1,e=!1,f=!1,g=i;if(!c)return!1;if(c.id===a.jstree.root)return this.redraw(!0);if(b=this.get_node(b,!0),!b||!b.length)return!1;if(b.children(".jstree-children").remove(),b=b[0],c.children.length&&c.state.loaded){for(f=g.createElement("UL"),f.setAttribute("role","group"),f.className="jstree-children",d=0,e=c.children.length;e>d;d++)f.appendChild(this.redraw_node(c.children[d],!0,!0));b.appendChild(f)}},redraw_node:function(b,c,d,e){var f=this.get_node(b),g=!1,h=!1,k=!1,l=!1,m=!1,n=!1,o="",p=i,q=this._model.data,r=!1,s=!1,t=null,u=0,v=0,w=!1,x=!1;if(!f)return!1;if(f.id===a.jstree.root)return this.redraw(!0);if(c=c||0===f.children.length,b=i.querySelector?this.element[0].querySelector("#"+(-1!=="0123456789".indexOf(f.id[0])?"\\3"+f.id[0]+" "+f.id.substr(1).replace(a.jstree.idregex,"\\$&"):f.id.replace(a.jstree.idregex,"\\$&"))):i.getElementById(f.id))b=a(b),
-d||(g=b.parent().parent()[0],g===this.element[0]&&(g=null),h=b.index()),c||!f.children.length||b.children(".jstree-children").length||(c=!0),c||(k=b.children(".jstree-children")[0]),r=b.children(".jstree-anchor")[0]===i.activeElement,b.remove();else if(c=!0,!d){if(g=f.parent!==a.jstree.root?a("#"+f.parent.replace(a.jstree.idregex,"\\$&"),this.element)[0]:null,!(null===g||g&&q[f.parent].state.opened))return!1;h=a.inArray(f.id,null===g?q[a.jstree.root].children:q[f.parent].children)}b=j.cloneNode(!0),o="jstree-node ";for(l in f.li_attr)if(f.li_attr.hasOwnProperty(l)){if("id"===l)continue;"class"!==l?b.setAttribute(l,f.li_attr[l]):o+=f.li_attr[l]}for(f.a_attr.id||(f.a_attr.id=f.id+"_anchor"),b.setAttribute("aria-selected",!!f.state.selected),b.setAttribute("aria-level",f.parents.length),b.setAttribute("aria-labelledby",f.a_attr.id),f.state.disabled&&b.setAttribute("aria-disabled",!0),l=0,m=f.children.length;m>l;l++)if(!q[f.children[l]].state.hidden){w=!0;break}if(null!==f.parent&&q[f.parent]&&!f.state.hidden&&(l=a.inArray(f.id,q[f.parent].children),x=f.id,-1!==l))for(l++,m=q[f.parent].children.length;m>l;l++)if(q[q[f.parent].children[l]].state.hidden||(x=q[f.parent].children[l]),x!==f.id)break;f.state.hidden&&(o+=" jstree-hidden"),f.state.loaded&&!w?o+=" jstree-leaf":(o+=f.state.opened&&f.state.loaded?" jstree-open":" jstree-closed",b.setAttribute("aria-expanded",f.state.opened&&f.state.loaded)),x===f.id&&(o+=" jstree-last"),b.id=f.id,b.className=o,o=(f.state.selected?" jstree-clicked":"")+(f.state.disabled?" jstree-disabled":"");for(m in f.a_attr)if(f.a_attr.hasOwnProperty(m)){if("href"===m&&"#"===f.a_attr[m])continue;"class"!==m?b.childNodes[1].setAttribute(m,f.a_attr[m]):o+=" "+f.a_attr[m]}if(o.length&&(b.childNodes[1].className="jstree-anchor "+o),(f.icon&&f.icon!==!0||f.icon===!1)&&(f.icon===!1?b.childNodes[1].childNodes[0].className+=" jstree-themeicon-hidden":-1===f.icon.indexOf("/")&&-1===f.icon.indexOf(".")?b.childNodes[1].childNodes[0].className+=" "+f.icon+" jstree-themeicon-custom":(b.childNodes[1].childNodes[0].style.backgroundImage='url("'+f.icon+'")',b.childNodes[1].childNodes[0].style.backgroundPosition="center center",b.childNodes[1].childNodes[0].style.backgroundSize="auto",b.childNodes[1].childNodes[0].className+=" jstree-themeicon-custom")),this.settings.core.force_text?b.childNodes[1].appendChild(p.createTextNode(f.text)):b.childNodes[1].innerHTML+=f.text,c&&f.children.length&&(f.state.opened||e)&&f.state.loaded){for(n=p.createElement("UL"),n.setAttribute("role","group"),n.className="jstree-children",l=0,m=f.children.length;m>l;l++)n.appendChild(this.redraw_node(f.children[l],c,!0));b.appendChild(n)}if(k&&b.appendChild(k),!d){for(g||(g=this.element[0]),l=0,m=g.childNodes.length;m>l;l++)if(g.childNodes[l]&&g.childNodes[l].className&&-1!==g.childNodes[l].className.indexOf("jstree-children")){t=g.childNodes[l];break}t||(t=p.createElement("UL"),t.setAttribute("role","group"),t.className="jstree-children",g.appendChild(t)),g=t,h<g.childNodes.length?g.insertBefore(b,g.childNodes[h]):g.appendChild(b),r&&(u=this.element[0].scrollTop,v=this.element[0].scrollLeft,b.childNodes[1].focus(),this.element[0].scrollTop=u,this.element[0].scrollLeft=v)}return f.state.opened&&!f.state.loaded&&(f.state.opened=!1,setTimeout(a.proxy(function(){this.open_node(f.id,!1,0)},this),0)),b},open_node:function(c,d,e){var f,g,h,i;if(a.isArray(c)){for(c=c.slice(),f=0,g=c.length;g>f;f++)this.open_node(c[f],d,e);return!0}return c=this.get_node(c),c&&c.id!==a.jstree.root?(e=e===b?this.settings.core.animation:e,this.is_closed(c)?this.is_loaded(c)?(h=this.get_node(c,!0),i=this,h.length&&(e&&h.children(".jstree-children").length&&h.children(".jstree-children").stop(!0,!0),c.children.length&&!this._firstChild(h.children(".jstree-children")[0])&&this.draw_children(c),e?(this.trigger("before_open",{node:c}),h.children(".jstree-children").css("display","none").end().removeClass("jstree-closed").addClass("jstree-open").attr("aria-expanded",!0).children(".jstree-children").stop(!0,!0).slideDown(e,function(){this.style.display="",i.element&&i.trigger("after_open",{node:c})})):(this.trigger("before_open",{node:c}),h[0].className=h[0].className.replace("jstree-closed","jstree-open"),h[0].setAttribute("aria-expanded",!0))),c.state.opened=!0,d&&d.call(this,c,!0),h.length||this.trigger("before_open",{node:c}),this.trigger("open_node",{node:c}),e&&h.length||this.trigger("after_open",{node:c}),!0):this.is_loading(c)?setTimeout(a.proxy(function(){this.open_node(c,d,e)},this),500):void this.load_node(c,function(a,b){return b?this.open_node(a,d,e):d?d.call(this,a,!1):!1}):(d&&d.call(this,c,!1),!1)):!1},_open_to:function(b){if(b=this.get_node(b),!b||b.id===a.jstree.root)return!1;var c,d,e=b.parents;for(c=0,d=e.length;d>c;c+=1)c!==a.jstree.root&&this.open_node(e[c],!1,0);return a("#"+b.id.replace(a.jstree.idregex,"\\$&"),this.element)},close_node:function(c,d){var e,f,g,h;if(a.isArray(c)){for(c=c.slice(),e=0,f=c.length;f>e;e++)this.close_node(c[e],d);return!0}return c=this.get_node(c),c&&c.id!==a.jstree.root?this.is_closed(c)?!1:(d=d===b?this.settings.core.animation:d,g=this,h=this.get_node(c,!0),c.state.opened=!1,this.trigger("close_node",{node:c}),void(h.length?d?h.children(".jstree-children").attr("style","display:block !important").end().removeClass("jstree-open").addClass("jstree-closed").attr("aria-expanded",!1).children(".jstree-children").stop(!0,!0).slideUp(d,function(){this.style.display="",h.children(".jstree-children").remove(),g.element&&g.trigger("after_close",{node:c})}):(h[0].className=h[0].className.replace("jstree-open","jstree-closed"),h.attr("aria-expanded",!1).children(".jstree-children").remove(),this.trigger("after_close",{node:c})):this.trigger("after_close",{node:c}))):!1},toggle_node:function(b){var c,d;if(a.isArray(b)){for(b=b.slice(),c=0,d=b.length;d>c;c++)this.toggle_node(b[c]);return!0}return this.is_closed(b)?this.open_node(b):this.is_open(b)?this.close_node(b):void 0},open_all:function(b,c,d){if(b||(b=a.jstree.root),b=this.get_node(b),!b)return!1;var e=b.id===a.jstree.root?this.get_container_ul():this.get_node(b,!0),f,g,h;if(!e.length){for(f=0,g=b.children_d.length;g>f;f++)this.is_closed(this._model.data[b.children_d[f]])&&(this._model.data[b.children_d[f]].state.opened=!0);return this.trigger("open_all",{node:b})}d=d||e,h=this,e=this.is_closed(b)?e.find(".jstree-closed").addBack():e.find(".jstree-closed"),e.each(function(){h.open_node(this,function(a,b){b&&this.is_parent(a)&&this.open_all(a,c,d)},c||0)}),0===d.find(".jstree-closed").length&&this.trigger("open_all",{node:this.get_node(d)})},close_all:function(b,c){if(b||(b=a.jstree.root),b=this.get_node(b),!b)return!1;var d=b.id===a.jstree.root?this.get_container_ul():this.get_node(b,!0),e=this,f,g;for(d.length&&(d=this.is_open(b)?d.find(".jstree-open").addBack():d.find(".jstree-open"),a(d.get().reverse()).each(function(){e.close_node(this,c||0)})),f=0,g=b.children_d.length;g>f;f++)this._model.data[b.children_d[f]].state.opened=!1;this.trigger("close_all",{node:b})},is_disabled:function(a){return a=this.get_node(a),a&&a.state&&a.state.disabled},enable_node:function(b){var c,d;if(a.isArray(b)){for(b=b.slice(),c=0,d=b.length;d>c;c++)this.enable_node(b[c]);return!0}return b=this.get_node(b),b&&b.id!==a.jstree.root?(b.state.disabled=!1,this.get_node(b,!0).children(".jstree-anchor").removeClass("jstree-disabled").attr("aria-disabled",!1),void this.trigger("enable_node",{node:b})):!1},disable_node:function(b){var c,d;if(a.isArray(b)){for(b=b.slice(),c=0,d=b.length;d>c;c++)this.disable_node(b[c]);return!0}return b=this.get_node(b),b&&b.id!==a.jstree.root?(b.state.disabled=!0,this.get_node(b,!0).children(".jstree-anchor").addClass("jstree-disabled").attr("aria-disabled",!0),void this.trigger("disable_node",{node:b})):!1},is_hidden:function(a){return a=this.get_node(a),a.state.hidden===!0},hide_node:function(b,c){var d,e;if(a.isArray(b)){for(b=b.slice(),d=0,e=b.length;e>d;d++)this.hide_node(b[d],!0);return c||this.redraw(),!0}return b=this.get_node(b),b&&b.id!==a.jstree.root?void(b.state.hidden||(b.state.hidden=!0,this._node_changed(b.parent),c||this.redraw(),this.trigger("hide_node",{node:b}))):!1},show_node:function(b,c){var d,e;if(a.isArray(b)){for(b=b.slice(),d=0,e=b.length;e>d;d++)this.show_node(b[d],!0);return c||this.redraw(),!0}return b=this.get_node(b),b&&b.id!==a.jstree.root?void(b.state.hidden&&(b.state.hidden=!1,this._node_changed(b.parent),c||this.redraw(),this.trigger("show_node",{node:b}))):!1},hide_all:function(b){var c,d=this._model.data,e=[];for(c in d)d.hasOwnProperty(c)&&c!==a.jstree.root&&!d[c].state.hidden&&(d[c].state.hidden=!0,e.push(c));return this._model.force_full_redraw=!0,b||this.redraw(),this.trigger("hide_all",{nodes:e}),e},show_all:function(b){var c,d=this._model.data,e=[];for(c in d)d.hasOwnProperty(c)&&c!==a.jstree.root&&d[c].state.hidden&&(d[c].state.hidden=!1,e.push(c));return this._model.force_full_redraw=!0,b||this.redraw(),this.trigger("show_all",{nodes:e}),e},activate_node:function(a,c){if(this.is_disabled(a))return!1;if(c&&"object"==typeof c||(c={}),this._data.core.last_clicked=this._data.core.last_clicked&&this._data.core.last_clicked.id!==b?this.get_node(this._data.core.last_clicked.id):null,this._data.core.last_clicked&&!this._data.core.last_clicked.state.selected&&(this._data.core.last_clicked=null),!this._data.core.last_clicked&&this._data.core.selected.length&&(this._data.core.last_clicked=this.get_node(this._data.core.selected[this._data.core.selected.length-1])),this.settings.core.multiple&&(c.metaKey||c.ctrlKey||c.shiftKey)&&(!c.shiftKey||this._data.core.last_clicked&&this.get_parent(a)&&this.get_parent(a)===this._data.core.last_clicked.parent))if(c.shiftKey){var d=this.get_node(a).id,e=this._data.core.last_clicked.id,f=this.get_node(this._data.core.last_clicked.parent).children,g=!1,h,i;for(h=0,i=f.length;i>h;h+=1)f[h]===d&&(g=!g),f[h]===e&&(g=!g),this.is_disabled(f[h])||!g&&f[h]!==d&&f[h]!==e?this.deselect_node(f[h],!0,c):this.is_hidden(f[h])||this.select_node(f[h],!0,!1,c);this.trigger("changed",{action:"select_node",node:this.get_node(a),selected:this._data.core.selected,event:c})}else this.is_selected(a)?this.deselect_node(a,!1,c):this.select_node(a,!1,!1,c);else!this.settings.core.multiple&&(c.metaKey||c.ctrlKey||c.shiftKey)&&this.is_selected(a)?this.deselect_node(a,!1,c):(this.deselect_all(!0),this.select_node(a,!1,!1,c),this._data.core.last_clicked=this.get_node(a));this.trigger("activate_node",{node:this.get_node(a),event:c})},hover_node:function(a){if(a=this.get_node(a,!0),!a||!a.length||a.children(".jstree-hovered").length)return!1;var b=this.element.find(".jstree-hovered"),c=this.element;b&&b.length&&this.dehover_node(b),a.children(".jstree-anchor").addClass("jstree-hovered"),this.trigger("hover_node",{node:this.get_node(a)}),setTimeout(function(){c.attr("aria-activedescendant",a[0].id)},0)},dehover_node:function(a){return a=this.get_node(a,!0),a&&a.length&&a.children(".jstree-hovered").length?(a.children(".jstree-anchor").removeClass("jstree-hovered"),void this.trigger("dehover_node",{node:this.get_node(a)})):!1},select_node:function(b,c,d,e){var f,g,h,i;if(a.isArray(b)){for(b=b.slice(),g=0,h=b.length;h>g;g++)this.select_node(b[g],c,d,e);return!0}return b=this.get_node(b),b&&b.id!==a.jstree.root?(f=this.get_node(b,!0),void(b.state.selected||(b.state.selected=!0,this._data.core.selected.push(b.id),d||(f=this._open_to(b)),f&&f.length&&f.attr("aria-selected",!0).children(".jstree-anchor").addClass("jstree-clicked"),this.trigger("select_node",{node:b,selected:this._data.core.selected,event:e}),c||this.trigger("changed",{action:"select_node",node:b,selected:this._data.core.selected,event:e})))):!1},deselect_node:function(b,c,d){var e,f,g;if(a.isArray(b)){for(b=b.slice(),e=0,f=b.length;f>e;e++)this.deselect_node(b[e],c,d);return!0}return b=this.get_node(b),b&&b.id!==a.jstree.root?(g=this.get_node(b,!0),void(b.state.selected&&(b.state.selected=!1,this._data.core.selected=a.vakata.array_remove_item(this._data.core.selected,b.id),g.length&&g.attr("aria-selected",!1).children(".jstree-anchor").removeClass("jstree-clicked"),this.trigger("deselect_node",{node:b,selected:this._data.core.selected,event:d}),c||this.trigger("changed",{action:"deselect_node",node:b,selected:this._data.core.selected,event:d})))):!1},select_all:function(b){var c=this._data.core.selected.concat([]),d,e;for(this._data.core.selected=this._model.data[a.jstree.root].children_d.concat(),d=0,e=this._data.core.selected.length;e>d;d++)this._model.data[this._data.core.selected[d]]&&(this._model.data[this._data.core.selected[d]].state.selected=!0);this.redraw(!0),this.trigger("select_all",{selected:this._data.core.selected}),b||this.trigger("changed",{action:"select_all",selected:this._data.core.selected,old_selection:c})},deselect_all:function(a){var b=this._data.core.selected.concat([]),c,d;for(c=0,d=this._data.core.selected.length;d>c;c++)this._model.data[this._data.core.selected[c]]&&(this._model.data[this._data.core.selected[c]].state.selected=!1);this._data.core.selected=[],this.element.find(".jstree-clicked").removeClass("jstree-clicked").parent().attr("aria-selected",!1),this.trigger("deselect_all",{selected:this._data.core.selected,node:b}),a||this.trigger("changed",{action:"deselect_all",selected:this._data.core.selected,old_selection:b})},is_selected:function(b){return b=this.get_node(b),b&&b.id!==a.jstree.root?b.state.selected:!1},get_selected:function(b){return b?a.map(this._data.core.selected,a.proxy(function(a){return this.get_node(a)},this)):this._data.core.selected.slice()},get_top_selected:function(b){var c=this.get_selected(!0),d={},e,f,g,h;for(e=0,f=c.length;f>e;e++)d[c[e].id]=c[e];for(e=0,f=c.length;f>e;e++)for(g=0,h=c[e].children_d.length;h>g;g++)d[c[e].children_d[g]]&&delete d[c[e].children_d[g]];c=[];for(e in d)d.hasOwnProperty(e)&&c.push(e);return b?a.map(c,a.proxy(function(a){return this.get_node(a)},this)):c},get_bottom_selected:function(b){var c=this.get_selected(!0),d=[],e,f;for(e=0,f=c.length;f>e;e++)c[e].children.length||d.push(c[e].id);return b?a.map(d,a.proxy(function(a){return this.get_node(a)},this)):d},get_state:function(){var b={core:{open:[],scroll:{left:this.element.scrollLeft(),top:this.element.scrollTop()},selected:[]}},c;for(c in this._model.data)this._model.data.hasOwnProperty(c)&&c!==a.jstree.root&&(this._model.data[c].state.opened&&b.core.open.push(c),this._model.data[c].state.selected&&b.core.selected.push(c));return b},set_state:function(c,d){if(c){if(c.core){var e,f,g,h,i;if(c.core.open)return a.isArray(c.core.open)&&c.core.open.length?this._load_nodes(c.core.open,function(a){this.open_node(a,!1,0),delete c.core.open,this.set_state(c,d)}):(delete c.core.open,this.set_state(c,d)),!1;if(c.core.scroll)return c.core.scroll&&c.core.scroll.left!==b&&this.element.scrollLeft(c.core.scroll.left),c.core.scroll&&c.core.scroll.top!==b&&this.element.scrollTop(c.core.scroll.top),delete c.core.scroll,this.set_state(c,d),!1;if(c.core.selected)return h=this,this.deselect_all(),a.each(c.core.selected,function(a,b){h.select_node(b,!1,!0)}),delete c.core.selected,this.set_state(c,d),!1;for(i in c)c.hasOwnProperty(i)&&"core"!==i&&-1===a.inArray(i,this.settings.plugins)&&delete c[i];if(a.isEmptyObject(c.core))return delete c.core,this.set_state(c,d),!1}return a.isEmptyObject(c)?(c=null,d&&d.call(this),this.trigger("set_state"),!1):!0}return!1},refresh:function(b,c){this._data.core.state=c===!0?{}:this.get_state(),c&&a.isFunction(c)&&(this._data.core.state=c.call(this,this._data.core.state)),this._cnt=0,this._model.data={},this._model.data[a.jstree.root]={id:a.jstree.root,parent:null,parents:[],children:[],children_d:[],state:{loaded:!1}},this._data.core.selected=[],this._data.core.last_clicked=null,this._data.core.focused=null;var d=this.get_container_ul()[0].className;b||(this.element.html("<ul class='"+d+"' role='group'><li class='jstree-initial-node jstree-loading jstree-leaf jstree-last' role='treeitem' id='j"+this._id+"_loading'><i class='jstree-icon jstree-ocl'></i><a class='jstree-anchor' href='#'><i class='jstree-icon jstree-themeicon-hidden'></i>"+this.get_string("Loading ...")+"</a></li></ul>"),this.element.attr("aria-activedescendant","j"+this._id+"_loading")),this.load_node(a.jstree.root,function(b,c){c&&(this.get_container_ul()[0].className=d,this._firstChild(this.get_container_ul()[0])&&this.element.attr("aria-activedescendant",this._firstChild(this.get_container_ul()[0]).id),this.set_state(a.extend(!0,{},this._data.core.state),function(){this.trigger("refresh")})),this._data.core.state=null})},refresh_node:function(b){if(b=this.get_node(b),!b||b.id===a.jstree.root)return!1;var c=[],d=[],e=this._data.core.selected.concat([]);d.push(b.id),b.state.opened===!0&&c.push(b.id),this.get_node(b,!0).find(".jstree-open").each(function(){d.push(this.id),c.push(this.id)}),this._load_nodes(d,a.proxy(function(a){this.open_node(c,!1,0),this.select_node(e),this.trigger("refresh_node",{node:b,nodes:a})},this),!1,!0)},set_id:function(b,c){if(b=this.get_node(b),!b||b.id===a.jstree.root)return!1;var d,e,f=this._model.data,g=b.id;for(c=c.toString(),f[b.parent].children[a.inArray(b.id,f[b.parent].children)]=c,d=0,e=b.parents.length;e>d;d++)f[b.parents[d]].children_d[a.inArray(b.id,f[b.parents[d]].children_d)]=c;for(d=0,e=b.children.length;e>d;d++)f[b.children[d]].parent=c;for(d=0,e=b.children_d.length;e>d;d++)f[b.children_d[d]].parents[a.inArray(b.id,f[b.children_d[d]].parents)]=c;return d=a.inArray(b.id,this._data.core.selected),-1!==d&&(this._data.core.selected[d]=c),d=this.get_node(b.id,!0),d&&(d.attr("id",c),this.element.attr("aria-activedescendant")===b.id&&this.element.attr("aria-activedescendant",c)),delete f[b.id],b.id=c,b.li_attr.id=c,f[c]=b,this.trigger("set_id",{node:b,"new":b.id,old:g}),!0},get_text:function(b){return b=this.get_node(b),b&&b.id!==a.jstree.root?b.text:!1},set_text:function(b,c){var d,e;if(a.isArray(b)){for(b=b.slice(),d=0,e=b.length;e>d;d++)this.set_text(b[d],c);return!0}return b=this.get_node(b),b&&b.id!==a.jstree.root?(b.text=c,this.get_node(b,!0).length&&this.redraw_node(b.id),this.trigger("set_text",{obj:b,text:c}),!0):!1},get_json:function(b,c,d){if(b=this.get_node(b||a.jstree.root),!b)return!1;c&&c.flat&&!d&&(d=[]);var e={id:b.id,text:b.text,icon:this.get_icon(b),li_attr:a.extend(!0,{},b.li_attr),a_attr:a.extend(!0,{},b.a_attr),state:{},data:c&&c.no_data?!1:a.extend(!0,{},b.data)},f,g;if(c&&c.flat?e.parent=b.parent:e.children=[],c&&c.no_state)delete e.state;else for(f in b.state)b.state.hasOwnProperty(f)&&(e.state[f]=b.state[f]);if(c&&c.no_li_attr&&delete e.li_attr,c&&c.no_a_attr&&delete e.a_attr,c&&c.no_id&&(delete e.id,e.li_attr&&e.li_attr.id&&delete e.li_attr.id,e.a_attr&&e.a_attr.id&&delete e.a_attr.id),c&&c.flat&&b.id!==a.jstree.root&&d.push(e),!c||!c.no_children)for(f=0,g=b.children.length;g>f;f++)c&&c.flat?this.get_json(b.children[f],c,d):e.children.push(this.get_json(b.children[f],c));return c&&c.flat?d:b.id===a.jstree.root?e.children:e},create_node:function(c,d,e,f,g){if(null===c&&(c=a.jstree.root),c=this.get_node(c),!c)return!1;if(e=e===b?"last":e,!e.toString().match(/^(before|after)$/)&&!g&&!this.is_loaded(c))return this.load_node(c,function(){this.create_node(c,d,e,f,!0)});d||(d={text:this.get_string("New node")}),"string"==typeof d&&(d={text:d}),d.text===b&&(d.text=this.get_string("New node"));var h,i,j,k;switch(c.id===a.jstree.root&&("before"===e&&(e="first"),"after"===e&&(e="last")),e){case"before":h=this.get_node(c.parent),e=a.inArray(c.id,h.children),c=h;break;case"after":h=this.get_node(c.parent),e=a.inArray(c.id,h.children)+1,c=h;break;case"inside":case"first":e=0;break;case"last":e=c.children.length;break;default:e||(e=0)}if(e>c.children.length&&(e=c.children.length),d.id||(d.id=!0),!this.check("create_node",d,c,e))return this.settings.core.error.call(this,this._data.core.last_error),!1;if(d.id===!0&&delete d.id,d=this._parse_model_from_json(d,c.id,c.parents.concat()),!d)return!1;for(h=this.get_node(d),i=[],i.push(d),i=i.concat(h.children_d),this.trigger("model",{nodes:i,parent:c.id}),c.children_d=c.children_d.concat(i),j=0,k=c.parents.length;k>j;j++)this._model.data[c.parents[j]].children_d=this._model.data[c.parents[j]].children_d.concat(i);for(d=h,h=[],j=0,k=c.children.length;k>j;j++)h[j>=e?j+1:j]=c.children[j];return h[e]=d.id,c.children=h,this.redraw_node(c,!0),f&&f.call(this,this.get_node(d)),this.trigger("create_node",{node:this.get_node(d),parent:c.id,position:e}),d.id},rename_node:function(b,c){var d,e,f;if(a.isArray(b)){for(b=b.slice(),d=0,e=b.length;e>d;d++)this.rename_node(b[d],c);return!0}return b=this.get_node(b),b&&b.id!==a.jstree.root?(f=b.text,this.check("rename_node",b,this.get_parent(b),c)?(this.set_text(b,c),this.trigger("rename_node",{node:b,text:c,old:f}),!0):(this.settings.core.error.call(this,this._data.core.last_error),!1)):!1},delete_node:function(b){var c,d,e,f,g,h,i,j,k,l,m,n;if(a.isArray(b)){for(b=b.slice(),c=0,d=b.length;d>c;c++)this.delete_node(b[c]);return!0}if(b=this.get_node(b),!b||b.id===a.jstree.root)return!1;if(e=this.get_node(b.parent),f=a.inArray(b.id,e.children),l=!1,!this.check("delete_node",b,e,f))return this.settings.core.error.call(this,this._data.core.last_error),!1;for(-1!==f&&(e.children=a.vakata.array_remove(e.children,f)),g=b.children_d.concat([]),g.push(b.id),h=0,i=b.parents.length;i>h;h++)this._model.data[b.parents[h]].children_d=a.vakata.array_filter(this._model.data[b.parents[h]].children_d,function(b){return-1===a.inArray(b,g)});for(j=0,k=g.length;k>j;j++)if(this._model.data[g[j]].state.selected){l=!0;break}for(l&&(this._data.core.selected=a.vakata.array_filter(this._data.core.selected,function(b){return-1===a.inArray(b,g)})),this.trigger("delete_node",{node:b,parent:e.id}),l&&this.trigger("changed",{action:"delete_node",node:b,selected:this._data.core.selected,parent:e.id}),j=0,k=g.length;k>j;j++)delete this._model.data[g[j]];return-1!==a.inArray(this._data.core.focused,g)&&(this._data.core.focused=null,m=this.element[0].scrollTop,n=this.element[0].scrollLeft,e.id===a.jstree.root?this._model.data[a.jstree.root].children[0]&&this.get_node(this._model.data[a.jstree.root].children[0],!0).children(".jstree-anchor").focus():this.get_node(e,!0).children(".jstree-anchor").focus(),this.element[0].scrollTop=m,this.element[0].scrollLeft=n),this.redraw_node(e,!0),!0},check:function(b,c,d,e,f){c=c&&c.id?c:this.get_node(c),d=d&&d.id?d:this.get_node(d);var g=b.match(/^move_node|copy_node|create_node$/i)?d:c,h=this.settings.core.check_callback;return"move_node"!==b&&"copy_node"!==b||f&&f.is_multi||c.id!==d.id&&("move_node"!==b||a.inArray(c.id,d.children)!==e)&&-1===a.inArray(d.id,c.children_d)?(g&&g.data&&(g=g.data),g&&g.functions&&(g.functions[b]===!1||g.functions[b]===!0)?(g.functions[b]===!1&&(this._data.core.last_error={error:"check",plugin:"core",id:"core_02",reason:"Node data prevents function: "+b,data:JSON.stringify({chk:b,pos:e,obj:c&&c.id?c.id:!1,par:d&&d.id?d.id:!1})}),g.functions[b]):h===!1||a.isFunction(h)&&h.call(this,b,c,d,e,f)===!1||h&&h[b]===!1?(this._data.core.last_error={error:"check",plugin:"core",id:"core_03",reason:"User config for core.check_callback prevents function: "+b,data:JSON.stringify({chk:b,pos:e,obj:c&&c.id?c.id:!1,par:d&&d.id?d.id:!1})},!1):!0):(this._data.core.last_error={error:"check",plugin:"core",id:"core_01",reason:"Moving parent inside child",data:JSON.stringify({chk:b,pos:e,obj:c&&c.id?c.id:!1,par:d&&d.id?d.id:!1})},!1)},last_error:function(){return this._data.core.last_error},move_node:function(c,d,e,f,g,h,i){var j,k,l,m,n,o,p,q,r,s,t,u,v,w;if(d=this.get_node(d),e=e===b?0:e,!d)return!1;if(!e.toString().match(/^(before|after)$/)&&!g&&!this.is_loaded(d))return this.load_node(d,function(){this.move_node(c,d,e,f,!0,!1,i)});if(a.isArray(c)){if(1!==c.length){for(j=0,k=c.length;k>j;j++)(r=this.move_node(c[j],d,e,f,g,!1,i))&&(d=r,e="after");return this.redraw(),!0}c=c[0]}if(c=c&&c.id?c:this.get_node(c),!c||c.id===a.jstree.root)return!1;if(l=(c.parent||a.jstree.root).toString(),n=e.toString().match(/^(before|after)$/)&&d.id!==a.jstree.root?this.get_node(d.parent):d,o=i?i:this._model.data[c.id]?this:a.jstree.reference(c.id),p=!o||!o._id||this._id!==o._id,m=o&&o._id&&l&&o._model.data[l]&&o._model.data[l].children?a.inArray(c.id,o._model.data[l].children):-1,o&&o._id&&(c=o._model.data[c.id]),p)return(r=this.copy_node(c,d,e,f,g,!1,i))?(o&&o.delete_node(c),r):!1;switch(d.id===a.jstree.root&&("before"===e&&(e="first"),"after"===e&&(e="last")),e){case"before":e=a.inArray(d.id,n.children);break;case"after":e=a.inArray(d.id,n.children)+1;break;case"inside":case"first":e=0;break;case"last":e=n.children.length;break;default:e||(e=0)}if(e>n.children.length&&(e=n.children.length),!this.check("move_node",c,n,e,{core:!0,origin:i,is_multi:o&&o._id&&o._id!==this._id,is_foreign:!o||!o._id}))return this.settings.core.error.call(this,this._data.core.last_error),!1;if(c.parent===n.id){for(q=n.children.concat(),r=a.inArray(c.id,q),-1!==r&&(q=a.vakata.array_remove(q,r),e>r&&e--),r=[],s=0,t=q.length;t>s;s++)r[s>=e?s+1:s]=q[s];r[e]=c.id,n.children=r,this._node_changed(n.id),this.redraw(n.id===a.jstree.root)}else{for(r=c.children_d.concat(),r.push(c.id),s=0,t=c.parents.length;t>s;s++){for(q=[],w=o._model.data[c.parents[s]].children_d,u=0,v=w.length;v>u;u++)-1===a.inArray(w[u],r)&&q.push(w[u]);o._model.data[c.parents[s]].children_d=q}for(o._model.data[l].children=a.vakata.array_remove_item(o._model.data[l].children,c.id),s=0,t=n.parents.length;t>s;s++)this._model.data[n.parents[s]].children_d=this._model.data[n.parents[s]].children_d.concat(r);for(q=[],s=0,t=n.children.length;t>s;s++)q[s>=e?s+1:s]=n.children[s];for(q[e]=c.id,n.children=q,n.children_d.push(c.id),n.children_d=n.children_d.concat(c.children_d),c.parent=n.id,r=n.parents.concat(),r.unshift(n.id),w=c.parents.length,c.parents=r,r=r.concat(),s=0,t=c.children_d.length;t>s;s++)this._model.data[c.children_d[s]].parents=this._model.data[c.children_d[s]].parents.slice(0,-1*w),Array.prototype.push.apply(this._model.data[c.children_d[s]].parents,r);(l===a.jstree.root||n.id===a.jstree.root)&&(this._model.force_full_redraw=!0),this._model.force_full_redraw||(this._node_changed(l),this._node_changed(n.id)),h||this.redraw()}return f&&f.call(this,c,n,e),this.trigger("move_node",{node:c,parent:n.id,position:e,old_parent:l,old_position:m,is_multi:o&&o._id&&o._id!==this._id,is_foreign:!o||!o._id,old_instance:o,new_instance:this}),c.id},copy_node:function(c,d,e,f,g,h,i){var j,k,l,m,n,o,p,q,r,s,t;if(d=this.get_node(d),e=e===b?0:e,!d)return!1;if(!e.toString().match(/^(before|after)$/)&&!g&&!this.is_loaded(d))return this.load_node(d,function(){this.copy_node(c,d,e,f,!0,!1,i)});if(a.isArray(c)){if(1!==c.length){for(j=0,k=c.length;k>j;j++)(m=this.copy_node(c[j],d,e,f,g,!0,i))&&(d=m,e="after");return this.redraw(),!0}c=c[0]}if(c=c&&c.id?c:this.get_node(c),!c||c.id===a.jstree.root)return!1;switch(q=(c.parent||a.jstree.root).toString(),r=e.toString().match(/^(before|after)$/)&&d.id!==a.jstree.root?this.get_node(d.parent):d,s=i?i:this._model.data[c.id]?this:a.jstree.reference(c.id),t=!s||!s._id||this._id!==s._id,s&&s._id&&(c=s._model.data[c.id]),d.id===a.jstree.root&&("before"===e&&(e="first"),"after"===e&&(e="last")),e){case"before":e=a.inArray(d.id,r.children);break;case"after":e=a.inArray(d.id,r.children)+1;break;case"inside":case"first":e=0;break;case"last":e=r.children.length;break;default:e||(e=0)}if(e>r.children.length&&(e=r.children.length),!this.check("copy_node",c,r,e,{core:!0,origin:i,is_multi:s&&s._id&&s._id!==this._id,is_foreign:!s||!s._id}))return this.settings.core.error.call(this,this._data.core.last_error),!1;if(p=s?s.get_json(c,{no_id:!0,no_data:!0,no_state:!0}):c,!p)return!1;if(p.id===!0&&delete p.id,p=this._parse_model_from_json(p,r.id,r.parents.concat()),!p)return!1;for(m=this.get_node(p),c&&c.state&&c.state.loaded===!1&&(m.state.loaded=!1),l=[],l.push(p),l=l.concat(m.children_d),this.trigger("model",{nodes:l,parent:r.id}),n=0,o=r.parents.length;o>n;n++)this._model.data[r.parents[n]].children_d=this._model.data[r.parents[n]].children_d.concat(l);for(l=[],n=0,o=r.children.length;o>n;n++)l[n>=e?n+1:n]=r.children[n];return l[e]=m.id,r.children=l,r.children_d.push(m.id),r.children_d=r.children_d.concat(m.children_d),r.id===a.jstree.root&&(this._model.force_full_redraw=!0),this._model.force_full_redraw||this._node_changed(r.id),h||this.redraw(r.id===a.jstree.root),f&&f.call(this,m,r,e),this.trigger("copy_node",{node:m,original:c,parent:r.id,position:e,old_parent:q,old_position:s&&s._id&&q&&s._model.data[q]&&s._model.data[q].children?a.inArray(c.id,s._model.data[q].children):-1,is_multi:s&&s._id&&s._id!==this._id,is_foreign:!s||!s._id,old_instance:s,new_instance:this}),m.id},cut:function(b){if(b||(b=this._data.core.selected.concat()),a.isArray(b)||(b=[b]),!b.length)return!1;var c=[],g,h,i;for(h=0,i=b.length;i>h;h++)g=this.get_node(b[h]),g&&g.id&&g.id!==a.jstree.root&&c.push(g);return c.length?(d=c,f=this,e="move_node",void this.trigger("cut",{node:b})):!1},copy:function(b){if(b||(b=this._data.core.selected.concat()),a.isArray(b)||(b=[b]),!b.length)return!1;var c=[],g,h,i;for(h=0,i=b.length;i>h;h++)g=this.get_node(b[h]),g&&g.id&&g.id!==a.jstree.root&&c.push(g);return c.length?(d=c,f=this,e="copy_node",void this.trigger("copy",{node:b})):!1},get_buffer:function(){return{mode:e,node:d,inst:f}},can_paste:function(){return e!==!1&&d!==!1},paste:function(a,b){return a=this.get_node(a),a&&e&&e.match(/^(copy_node|move_node)$/)&&d?(this[e](d,a,b,!1,!1,!1,f)&&this.trigger("paste",{parent:a.id,node:d,mode:e}),d=!1,e=!1,void(f=!1)):!1},clear_buffer:function(){d=!1,e=!1,f=!1,this.trigger("clear_buffer")},edit:function(b,c,d){var e,f,g,h,j,k,l,m,n,o=!1;return(b=this.get_node(b))?this.settings.core.check_callback===!1?(this._data.core.last_error={error:"check",plugin:"core",id:"core_07",reason:"Could not edit node because of check_callback"},this.settings.core.error.call(this,this._data.core.last_error),!1):(n=b,c="string"==typeof c?c:b.text,this.set_text(b,""),b=this._open_to(b),n.text=c,e=this._data.core.rtl,f=this.element.width(),this._data.core.focused=n.id,g=b.children(".jstree-anchor").focus(),h=a("<span>"),j=c,k=a("<div />",{css:{position:"absolute",top:"-200px",left:e?"0px":"-1000px",visibility:"hidden"}}).appendTo("body"),l=a("<input />",{value:j,"class":"jstree-rename-input",css:{padding:"0",border:"1px solid silver","box-sizing":"border-box",display:"inline-block",height:this._data.core.li_height+"px",lineHeight:this._data.core.li_height+"px",width:"150px"},blur:a.proxy(function(c){c.stopImmediatePropagation(),c.preventDefault();var e=h.children(".jstree-rename-input"),f=e.val(),i=this.settings.core.force_text,m;""===f&&(f=j),k.remove(),h.replaceWith(g),h.remove(),j=i?j:a("<div></div>").append(a.parseHTML(j)).html(),this.set_text(b,j),m=!!this.rename_node(b,i?a("<div></div>").text(f).text():a("<div></div>").append(a.parseHTML(f)).html()),m||this.set_text(b,j),this._data.core.focused=n.id,setTimeout(a.proxy(function(){var a=this.get_node(n.id,!0);a.length&&(this._data.core.focused=n.id,a.children(".jstree-anchor").focus())},this),0),d&&d.call(this,n,m,o),l=null},this),keydown:function(a){var b=a.which;27===b&&(o=!0,this.value=j),(27===b||13===b||37===b||38===b||39===b||40===b||32===b)&&a.stopImmediatePropagation(),(27===b||13===b)&&(a.preventDefault(),this.blur())},click:function(a){a.stopImmediatePropagation()},mousedown:function(a){a.stopImmediatePropagation()},keyup:function(a){l.width(Math.min(k.text("pW"+this.value).width(),f))},keypress:function(a){return 13===a.which?!1:void 0}}),m={fontFamily:g.css("fontFamily")||"",fontSize:g.css("fontSize")||"",fontWeight:g.css("fontWeight")||"",fontStyle:g.css("fontStyle")||"",fontStretch:g.css("fontStretch")||"",fontVariant:g.css("fontVariant")||"",letterSpacing:g.css("letterSpacing")||"",wordSpacing:g.css("wordSpacing")||""},h.attr("class",g.attr("class")).append(g.contents().clone()).append(l),g.replaceWith(h),k.css(m),l.css(m).width(Math.min(k.text("pW"+l[0].value).width(),f))[0].select(),
-void a(i).one("mousedown.jstree touchstart.jstree dnd_start.vakata",function(b){l&&b.target!==l&&a(l).blur()})):!1},set_theme:function(b,c){if(!b)return!1;if(c===!0){var d=this.settings.core.themes.dir;d||(d=a.jstree.path+"/themes"),c=d+"/"+b+"/style.css"}c&&-1===a.inArray(c,g)&&(a("head").append('<link rel="stylesheet" href="'+c+'" type="text/css" />'),g.push(c)),this._data.core.themes.name&&this.element.removeClass("jstree-"+this._data.core.themes.name),this._data.core.themes.name=b,this.element.addClass("jstree-"+b),this.element[this.settings.core.themes.responsive?"addClass":"removeClass"]("jstree-"+b+"-responsive"),this.trigger("set_theme",{theme:b})},get_theme:function(){return this._data.core.themes.name},set_theme_variant:function(a){this._data.core.themes.variant&&this.element.removeClass("jstree-"+this._data.core.themes.name+"-"+this._data.core.themes.variant),this._data.core.themes.variant=a,a&&this.element.addClass("jstree-"+this._data.core.themes.name+"-"+this._data.core.themes.variant)},get_theme_variant:function(){return this._data.core.themes.variant},show_stripes:function(){this._data.core.themes.stripes=!0,this.get_container_ul().addClass("jstree-striped")},hide_stripes:function(){this._data.core.themes.stripes=!1,this.get_container_ul().removeClass("jstree-striped")},toggle_stripes:function(){this._data.core.themes.stripes?this.hide_stripes():this.show_stripes()},show_dots:function(){this._data.core.themes.dots=!0,this.get_container_ul().removeClass("jstree-no-dots")},hide_dots:function(){this._data.core.themes.dots=!1,this.get_container_ul().addClass("jstree-no-dots")},toggle_dots:function(){this._data.core.themes.dots?this.hide_dots():this.show_dots()},show_icons:function(){this._data.core.themes.icons=!0,this.get_container_ul().removeClass("jstree-no-icons")},hide_icons:function(){this._data.core.themes.icons=!1,this.get_container_ul().addClass("jstree-no-icons")},toggle_icons:function(){this._data.core.themes.icons?this.hide_icons():this.show_icons()},set_icon:function(c,d){var e,f,g,h;if(a.isArray(c)){for(c=c.slice(),e=0,f=c.length;f>e;e++)this.set_icon(c[e],d);return!0}return c=this.get_node(c),c&&c.id!==a.jstree.root?(h=c.icon,c.icon=d===!0||null===d||d===b||""===d?!0:d,g=this.get_node(c,!0).children(".jstree-anchor").children(".jstree-themeicon"),d===!1?this.hide_icon(c):d===!0||null===d||d===b||""===d?(g.removeClass("jstree-themeicon-custom "+h).css("background","").removeAttr("rel"),h===!1&&this.show_icon(c)):-1===d.indexOf("/")&&-1===d.indexOf(".")?(g.removeClass(h).css("background",""),g.addClass(d+" jstree-themeicon-custom").attr("rel",d),h===!1&&this.show_icon(c)):(g.removeClass(h).css("background",""),g.addClass("jstree-themeicon-custom").css("background","url('"+d+"') center center no-repeat").attr("rel",d),h===!1&&this.show_icon(c)),!0):!1},get_icon:function(b){return b=this.get_node(b),b&&b.id!==a.jstree.root?b.icon:!1},hide_icon:function(b){var c,d;if(a.isArray(b)){for(b=b.slice(),c=0,d=b.length;d>c;c++)this.hide_icon(b[c]);return!0}return b=this.get_node(b),b&&b!==a.jstree.root?(b.icon=!1,this.get_node(b,!0).children(".jstree-anchor").children(".jstree-themeicon").addClass("jstree-themeicon-hidden"),!0):!1},show_icon:function(b){var c,d,e;if(a.isArray(b)){for(b=b.slice(),c=0,d=b.length;d>c;c++)this.show_icon(b[c]);return!0}return b=this.get_node(b),b&&b!==a.jstree.root?(e=this.get_node(b,!0),b.icon=e.length?e.children(".jstree-anchor").children(".jstree-themeicon").attr("rel"):!0,b.icon||(b.icon=!0),e.children(".jstree-anchor").children(".jstree-themeicon").removeClass("jstree-themeicon-hidden"),!0):!1}},a.vakata={},a.vakata.attributes=function(b,c){b=a(b)[0];var d=c?{}:[];return b&&b.attributes&&a.each(b.attributes,function(b,e){-1===a.inArray(e.name.toLowerCase(),["style","contenteditable","hasfocus","tabindex"])&&null!==e.value&&""!==a.trim(e.value)&&(c?d[e.name]=e.value:d.push(e.name))}),d},a.vakata.array_unique=function(a){var c=[],d,e,f,g={};for(d=0,f=a.length;f>d;d++)g[a[d]]===b&&(c.push(a[d]),g[a[d]]=!0);return c},a.vakata.array_remove=function(a,b){return a.splice(b,1),a},a.vakata.array_remove_item=function(b,c){var d=a.inArray(c,b);return-1!==d?a.vakata.array_remove(b,d):b},a.vakata.array_filter=function(a,b,c,d,e){if(a.filter)return a.filter(b,c);d=[];for(e in a)~~e+""==e+""&&e>=0&&b.call(c,a[e],+e,a)&&d.push(a[e]);return d},a.jstree.plugins.changed=function(a,b){var c=[];this.trigger=function(a,d){var e,f;if(d||(d={}),"changed"===a.replace(".jstree","")){d.changed={selected:[],deselected:[]};var g={};for(e=0,f=c.length;f>e;e++)g[c[e]]=1;for(e=0,f=d.selected.length;f>e;e++)g[d.selected[e]]?g[d.selected[e]]=2:d.changed.selected.push(d.selected[e]);for(e=0,f=c.length;f>e;e++)1===g[c[e]]&&d.changed.deselected.push(c[e]);c=d.selected.slice()}b.trigger.call(this,a,d)},this.refresh=function(a,d){return c=[],b.refresh.apply(this,arguments)}};var m=i.createElement("I");m.className="jstree-icon jstree-checkbox",m.setAttribute("role","presentation"),a.jstree.defaults.checkbox={visible:!0,three_state:!0,whole_node:!0,keep_selected_style:!0,cascade:"",tie_selection:!0},a.jstree.plugins.checkbox=function(c,d){this.bind=function(){d.bind.call(this),this._data.checkbox.uto=!1,this._data.checkbox.selected=[],this.settings.checkbox.three_state&&(this.settings.checkbox.cascade="up+down+undetermined"),this.element.on("init.jstree",a.proxy(function(){this._data.checkbox.visible=this.settings.checkbox.visible,this.settings.checkbox.keep_selected_style||this.element.addClass("jstree-checkbox-no-clicked"),this.settings.checkbox.tie_selection&&this.element.addClass("jstree-checkbox-selection")},this)).on("loading.jstree",a.proxy(function(){this[this._data.checkbox.visible?"show_checkboxes":"hide_checkboxes"]()},this)),-1!==this.settings.checkbox.cascade.indexOf("undetermined")&&this.element.on("changed.jstree uncheck_node.jstree check_node.jstree uncheck_all.jstree check_all.jstree move_node.jstree copy_node.jstree redraw.jstree open_node.jstree",a.proxy(function(){this._data.checkbox.uto&&clearTimeout(this._data.checkbox.uto),this._data.checkbox.uto=setTimeout(a.proxy(this._undetermined,this),50)},this)),this.settings.checkbox.tie_selection||this.element.on("model.jstree",a.proxy(function(a,b){var c=this._model.data,d=c[b.parent],e=b.nodes,f,g;for(f=0,g=e.length;g>f;f++)c[e[f]].state.checked=c[e[f]].state.checked||c[e[f]].original&&c[e[f]].original.state&&c[e[f]].original.state.checked,c[e[f]].state.checked&&this._data.checkbox.selected.push(e[f])},this)),(-1!==this.settings.checkbox.cascade.indexOf("up")||-1!==this.settings.checkbox.cascade.indexOf("down"))&&this.element.on("model.jstree",a.proxy(function(b,c){var d=this._model.data,e=d[c.parent],f=c.nodes,g=[],h,i,j,k,l,m,n=this.settings.checkbox.cascade,o=this.settings.checkbox.tie_selection;if(-1!==n.indexOf("down"))if(e.state[o?"selected":"checked"]){for(i=0,j=f.length;j>i;i++)d[f[i]].state[o?"selected":"checked"]=!0;this._data[o?"core":"checkbox"].selected=this._data[o?"core":"checkbox"].selected.concat(f)}else for(i=0,j=f.length;j>i;i++)if(d[f[i]].state[o?"selected":"checked"]){for(k=0,l=d[f[i]].children_d.length;l>k;k++)d[d[f[i]].children_d[k]].state[o?"selected":"checked"]=!0;this._data[o?"core":"checkbox"].selected=this._data[o?"core":"checkbox"].selected.concat(d[f[i]].children_d)}if(-1!==n.indexOf("up")){for(i=0,j=e.children_d.length;j>i;i++)d[e.children_d[i]].children.length||g.push(d[e.children_d[i]].parent);for(g=a.vakata.array_unique(g),k=0,l=g.length;l>k;k++){e=d[g[k]];while(e&&e.id!==a.jstree.root){for(h=0,i=0,j=e.children.length;j>i;i++)h+=d[e.children[i]].state[o?"selected":"checked"];if(h!==j)break;e.state[o?"selected":"checked"]=!0,this._data[o?"core":"checkbox"].selected.push(e.id),m=this.get_node(e,!0),m&&m.length&&m.attr("aria-selected",!0).children(".jstree-anchor").addClass(o?"jstree-clicked":"jstree-checked"),e=this.get_node(e.parent)}}}this._data[o?"core":"checkbox"].selected=a.vakata.array_unique(this._data[o?"core":"checkbox"].selected)},this)).on(this.settings.checkbox.tie_selection?"select_node.jstree":"check_node.jstree",a.proxy(function(b,c){var d=c.node,e=this._model.data,f=this.get_node(d.parent),g=this.get_node(d,!0),h,i,j,k,l=this.settings.checkbox.cascade,m=this.settings.checkbox.tie_selection,n={},o=this._data[m?"core":"checkbox"].selected;for(h=0,i=o.length;i>h;h++)n[o[h]]=!0;if(-1!==l.indexOf("down"))for(h=0,i=d.children_d.length;i>h;h++)n[d.children_d[h]]=!0,k=e[d.children_d[h]],k.state[m?"selected":"checked"]=!0,k&&k.original&&k.original.state&&k.original.state.undetermined&&(k.original.state.undetermined=!1);if(-1!==l.indexOf("up"))while(f&&f.id!==a.jstree.root){for(j=0,h=0,i=f.children.length;i>h;h++)j+=e[f.children[h]].state[m?"selected":"checked"];if(j!==i)break;f.state[m?"selected":"checked"]=!0,n[f.id]=!0,k=this.get_node(f,!0),k&&k.length&&k.attr("aria-selected",!0).children(".jstree-anchor").addClass(m?"jstree-clicked":"jstree-checked"),f=this.get_node(f.parent)}o=[];for(h in n)n.hasOwnProperty(h)&&o.push(h);this._data[m?"core":"checkbox"].selected=o,-1!==l.indexOf("down")&&g.length&&g.find(".jstree-anchor").addClass(m?"jstree-clicked":"jstree-checked").parent().attr("aria-selected",!0)},this)).on(this.settings.checkbox.tie_selection?"deselect_all.jstree":"uncheck_all.jstree",a.proxy(function(b,c){var d=this.get_node(a.jstree.root),e=this._model.data,f,g,h;for(f=0,g=d.children_d.length;g>f;f++)h=e[d.children_d[f]],h&&h.original&&h.original.state&&h.original.state.undetermined&&(h.original.state.undetermined=!1)},this)).on(this.settings.checkbox.tie_selection?"deselect_node.jstree":"uncheck_node.jstree",a.proxy(function(b,c){var d=c.node,e=this.get_node(d,!0),f,g,h,i=this.settings.checkbox.cascade,j=this.settings.checkbox.tie_selection,k=this._data[j?"core":"checkbox"].selected,l={};if(d&&d.original&&d.original.state&&d.original.state.undetermined&&(d.original.state.undetermined=!1),-1!==i.indexOf("down"))for(f=0,g=d.children_d.length;g>f;f++)h=this._model.data[d.children_d[f]],h.state[j?"selected":"checked"]=!1,h&&h.original&&h.original.state&&h.original.state.undetermined&&(h.original.state.undetermined=!1);if(-1!==i.indexOf("up"))for(f=0,g=d.parents.length;g>f;f++)h=this._model.data[d.parents[f]],h.state[j?"selected":"checked"]=!1,h&&h.original&&h.original.state&&h.original.state.undetermined&&(h.original.state.undetermined=!1),h=this.get_node(d.parents[f],!0),h&&h.length&&h.attr("aria-selected",!1).children(".jstree-anchor").removeClass(j?"jstree-clicked":"jstree-checked");for(l={},f=0,g=k.length;g>f;f++)-1!==i.indexOf("down")&&-1!==a.inArray(k[f],d.children_d)||-1!==i.indexOf("up")&&-1!==a.inArray(k[f],d.parents)||(l[k[f]]=!0);k=[];for(f in l)l.hasOwnProperty(f)&&k.push(f);this._data[j?"core":"checkbox"].selected=k,-1!==i.indexOf("down")&&e.length&&e.find(".jstree-anchor").removeClass(j?"jstree-clicked":"jstree-checked").parent().attr("aria-selected",!1)},this)),-1!==this.settings.checkbox.cascade.indexOf("up")&&this.element.on("delete_node.jstree",a.proxy(function(b,c){var d=this.get_node(c.parent),e=this._model.data,f,g,h,i,j=this.settings.checkbox.tie_selection;while(d&&d.id!==a.jstree.root&&!d.state[j?"selected":"checked"]){for(h=0,f=0,g=d.children.length;g>f;f++)h+=e[d.children[f]].state[j?"selected":"checked"];if(!(g>0&&h===g))break;d.state[j?"selected":"checked"]=!0,this._data[j?"core":"checkbox"].selected.push(d.id),i=this.get_node(d,!0),i&&i.length&&i.attr("aria-selected",!0).children(".jstree-anchor").addClass(j?"jstree-clicked":"jstree-checked"),d=this.get_node(d.parent)}},this)).on("move_node.jstree",a.proxy(function(b,c){var d=c.is_multi,e=c.old_parent,f=this.get_node(c.parent),g=this._model.data,h,i,j,k,l,m=this.settings.checkbox.tie_selection;if(!d){h=this.get_node(e);while(h&&h.id!==a.jstree.root&&!h.state[m?"selected":"checked"]){for(i=0,j=0,k=h.children.length;k>j;j++)i+=g[h.children[j]].state[m?"selected":"checked"];if(!(k>0&&i===k))break;h.state[m?"selected":"checked"]=!0,this._data[m?"core":"checkbox"].selected.push(h.id),l=this.get_node(h,!0),l&&l.length&&l.attr("aria-selected",!0).children(".jstree-anchor").addClass(m?"jstree-clicked":"jstree-checked"),h=this.get_node(h.parent)}}h=f;while(h&&h.id!==a.jstree.root){for(i=0,j=0,k=h.children.length;k>j;j++)i+=g[h.children[j]].state[m?"selected":"checked"];if(i===k)h.state[m?"selected":"checked"]||(h.state[m?"selected":"checked"]=!0,this._data[m?"core":"checkbox"].selected.push(h.id),l=this.get_node(h,!0),l&&l.length&&l.attr("aria-selected",!0).children(".jstree-anchor").addClass(m?"jstree-clicked":"jstree-checked"));else{if(!h.state[m?"selected":"checked"])break;h.state[m?"selected":"checked"]=!1,this._data[m?"core":"checkbox"].selected=a.vakata.array_remove_item(this._data[m?"core":"checkbox"].selected,h.id),l=this.get_node(h,!0),l&&l.length&&l.attr("aria-selected",!1).children(".jstree-anchor").removeClass(m?"jstree-clicked":"jstree-checked")}h=this.get_node(h.parent)}},this))},this._undetermined=function(){if(null!==this.element){var c,d,e,f,g={},h=this._model.data,i=this.settings.checkbox.tie_selection,j=this._data[i?"core":"checkbox"].selected,k=[],l=this;for(c=0,d=j.length;d>c;c++)if(h[j[c]]&&h[j[c]].parents)for(e=0,f=h[j[c]].parents.length;f>e;e++){if(g[h[j[c]].parents[e]]!==b)break;h[j[c]].parents[e]!==a.jstree.root&&(g[h[j[c]].parents[e]]=!0,k.push(h[j[c]].parents[e]))}for(this.element.find(".jstree-closed").not(":has(.jstree-children)").each(function(){var i=l.get_node(this),j;if(i.state.loaded){for(c=0,d=i.children_d.length;d>c;c++)if(j=h[i.children_d[c]],!j.state.loaded&&j.original&&j.original.state&&j.original.state.undetermined&&j.original.state.undetermined===!0)for(g[j.id]===b&&j.id!==a.jstree.root&&(g[j.id]=!0,k.push(j.id)),e=0,f=j.parents.length;f>e;e++)g[j.parents[e]]===b&&j.parents[e]!==a.jstree.root&&(g[j.parents[e]]=!0,k.push(j.parents[e]))}else if(i.original&&i.original.state&&i.original.state.undetermined&&i.original.state.undetermined===!0)for(g[i.id]===b&&i.id!==a.jstree.root&&(g[i.id]=!0,k.push(i.id)),e=0,f=i.parents.length;f>e;e++)g[i.parents[e]]===b&&i.parents[e]!==a.jstree.root&&(g[i.parents[e]]=!0,k.push(i.parents[e]))}),this.element.find(".jstree-undetermined").removeClass("jstree-undetermined"),c=0,d=k.length;d>c;c++)h[k[c]].state[i?"selected":"checked"]||(j=this.get_node(k[c],!0),j&&j.length&&j.children(".jstree-anchor").children(".jstree-checkbox").addClass("jstree-undetermined"))}},this.redraw_node=function(b,c,e,f){if(b=d.redraw_node.apply(this,arguments)){var g,h,i=null,j=null;for(g=0,h=b.childNodes.length;h>g;g++)if(b.childNodes[g]&&b.childNodes[g].className&&-1!==b.childNodes[g].className.indexOf("jstree-anchor")){i=b.childNodes[g];break}i&&(!this.settings.checkbox.tie_selection&&this._model.data[b.id].state.checked&&(i.className+=" jstree-checked"),j=m.cloneNode(!1),this._model.data[b.id].state.checkbox_disabled&&(j.className+=" jstree-checkbox-disabled"),i.insertBefore(j,i.childNodes[0]))}return e||-1===this.settings.checkbox.cascade.indexOf("undetermined")||(this._data.checkbox.uto&&clearTimeout(this._data.checkbox.uto),this._data.checkbox.uto=setTimeout(a.proxy(this._undetermined,this),50)),b},this.show_checkboxes=function(){this._data.core.themes.checkboxes=!0,this.get_container_ul().removeClass("jstree-no-checkboxes")},this.hide_checkboxes=function(){this._data.core.themes.checkboxes=!1,this.get_container_ul().addClass("jstree-no-checkboxes")},this.toggle_checkboxes=function(){this._data.core.themes.checkboxes?this.hide_checkboxes():this.show_checkboxes()},this.is_undetermined=function(b){b=this.get_node(b);var c=this.settings.checkbox.cascade,d,e,f=this.settings.checkbox.tie_selection,g=this._data[f?"core":"checkbox"].selected,h=this._model.data;if(!b||b.state[f?"selected":"checked"]===!0||-1===c.indexOf("undetermined")||-1===c.indexOf("down")&&-1===c.indexOf("up"))return!1;if(!b.state.loaded&&b.original.state.undetermined===!0)return!0;for(d=0,e=b.children_d.length;e>d;d++)if(-1!==a.inArray(b.children_d[d],g)||!h[b.children_d[d]].state.loaded&&h[b.children_d[d]].original.state.undetermined)return!0;return!1},this.disable_checkbox=function(b){var c,d,e;if(a.isArray(b)){for(b=b.slice(),c=0,d=b.length;d>c;c++)this.disable_checkbox(b[c]);return!0}return b=this.get_node(b),b&&b.id!==a.jstree.root?(e=this.get_node(b,!0),void(b.state.checkbox_disabled||(b.state.checkbox_disabled=!0,e&&e.length&&e.children(".jstree-anchor").children(".jstree-checkbox").addClass("jstree-checkbox-disabled"),this.trigger("disable_checkbox",{node:b})))):!1},this.enable_checkbox=function(b){var c,d,e;if(a.isArray(b)){for(b=b.slice(),c=0,d=b.length;d>c;c++)this.enable_checkbox(b[c]);return!0}return b=this.get_node(b),b&&b.id!==a.jstree.root?(e=this.get_node(b,!0),void(b.state.checkbox_disabled&&(b.state.checkbox_disabled=!1,e&&e.length&&e.children(".jstree-anchor").children(".jstree-checkbox").removeClass("jstree-checkbox-disabled"),this.trigger("enable_checkbox",{node:b})))):!1},this.activate_node=function(b,c){return a(c.target).hasClass("jstree-checkbox-disabled")?!1:(this.settings.checkbox.tie_selection&&(this.settings.checkbox.whole_node||a(c.target).hasClass("jstree-checkbox"))&&(c.ctrlKey=!0),this.settings.checkbox.tie_selection||!this.settings.checkbox.whole_node&&!a(c.target).hasClass("jstree-checkbox")?d.activate_node.call(this,b,c):this.is_disabled(b)?!1:(this.is_checked(b)?this.uncheck_node(b,c):this.check_node(b,c),void this.trigger("activate_node",{node:this.get_node(b)})))},this.check_node=function(b,c){if(this.settings.checkbox.tie_selection)return this.select_node(b,!1,!0,c);var d,e,f,g;if(a.isArray(b)){for(b=b.slice(),e=0,f=b.length;f>e;e++)this.check_node(b[e],c);return!0}return b=this.get_node(b),b&&b.id!==a.jstree.root?(d=this.get_node(b,!0),void(b.state.checked||(b.state.checked=!0,this._data.checkbox.selected.push(b.id),d&&d.length&&d.children(".jstree-anchor").addClass("jstree-checked"),this.trigger("check_node",{node:b,selected:this._data.checkbox.selected,event:c})))):!1},this.uncheck_node=function(b,c){if(this.settings.checkbox.tie_selection)return this.deselect_node(b,!1,c);var d,e,f;if(a.isArray(b)){for(b=b.slice(),d=0,e=b.length;e>d;d++)this.uncheck_node(b[d],c);return!0}return b=this.get_node(b),b&&b.id!==a.jstree.root?(f=this.get_node(b,!0),void(b.state.checked&&(b.state.checked=!1,this._data.checkbox.selected=a.vakata.array_remove_item(this._data.checkbox.selected,b.id),f.length&&f.children(".jstree-anchor").removeClass("jstree-checked"),this.trigger("uncheck_node",{node:b,selected:this._data.checkbox.selected,event:c})))):!1},this.check_all=function(){if(this.settings.checkbox.tie_selection)return this.select_all();var b=this._data.checkbox.selected.concat([]),c,d;for(this._data.checkbox.selected=this._model.data[a.jstree.root].children_d.concat(),c=0,d=this._data.checkbox.selected.length;d>c;c++)this._model.data[this._data.checkbox.selected[c]]&&(this._model.data[this._data.checkbox.selected[c]].state.checked=!0);this.redraw(!0),this.trigger("check_all",{selected:this._data.checkbox.selected})},this.uncheck_all=function(){if(this.settings.checkbox.tie_selection)return this.deselect_all();var a=this._data.checkbox.selected.concat([]),b,c;for(b=0,c=this._data.checkbox.selected.length;c>b;b++)this._model.data[this._data.checkbox.selected[b]]&&(this._model.data[this._data.checkbox.selected[b]].state.checked=!1);this._data.checkbox.selected=[],this.element.find(".jstree-checked").removeClass("jstree-checked"),this.trigger("uncheck_all",{selected:this._data.checkbox.selected,node:a})},this.is_checked=function(b){return this.settings.checkbox.tie_selection?this.is_selected(b):(b=this.get_node(b),b&&b.id!==a.jstree.root?b.state.checked:!1)},this.get_checked=function(b){return this.settings.checkbox.tie_selection?this.get_selected(b):b?a.map(this._data.checkbox.selected,a.proxy(function(a){return this.get_node(a)},this)):this._data.checkbox.selected},this.get_top_checked=function(b){if(this.settings.checkbox.tie_selection)return this.get_top_selected(b);var c=this.get_checked(!0),d={},e,f,g,h;for(e=0,f=c.length;f>e;e++)d[c[e].id]=c[e];for(e=0,f=c.length;f>e;e++)for(g=0,h=c[e].children_d.length;h>g;g++)d[c[e].children_d[g]]&&delete d[c[e].children_d[g]];c=[];for(e in d)d.hasOwnProperty(e)&&c.push(e);return b?a.map(c,a.proxy(function(a){return this.get_node(a)},this)):c},this.get_bottom_checked=function(b){if(this.settings.checkbox.tie_selection)return this.get_bottom_selected(b);var c=this.get_checked(!0),d=[],e,f;for(e=0,f=c.length;f>e;e++)c[e].children.length||d.push(c[e].id);return b?a.map(d,a.proxy(function(a){return this.get_node(a)},this)):d},this.load_node=function(b,c){var e,f,g,h,i,j;if(!a.isArray(b)&&!this.settings.checkbox.tie_selection&&(j=this.get_node(b),j&&j.state.loaded))for(e=0,f=j.children_d.length;f>e;e++)this._model.data[j.children_d[e]].state.checked&&(i=!0,this._data.checkbox.selected=a.vakata.array_remove_item(this._data.checkbox.selected,j.children_d[e]));return d.load_node.apply(this,arguments)},this.get_state=function(){var a=d.get_state.apply(this,arguments);return this.settings.checkbox.tie_selection?a:(a.checkbox=this._data.checkbox.selected.slice(),a)},this.set_state=function(b,c){var e=d.set_state.apply(this,arguments);if(e&&b.checkbox){if(!this.settings.checkbox.tie_selection){this.uncheck_all();var f=this;a.each(b.checkbox,function(a,b){f.check_node(b)})}return delete b.checkbox,this.set_state(b,c),!1}return e},this.refresh=function(a,b){return this.settings.checkbox.tie_selection||(this._data.checkbox.selected=[]),d.refresh.apply(this,arguments)}},a.jstree.defaults.conditionalselect=function(){return!0},a.jstree.plugins.conditionalselect=function(a,b){this.activate_node=function(a,c){this.settings.conditionalselect.call(this,this.get_node(a),c)&&b.activate_node.call(this,a,c)}},a.jstree.defaults.contextmenu={select_node:!0,show_at_node:!0,items:function(b,c){return{create:{separator_before:!1,separator_after:!0,_disabled:!1,label:"Create",action:function(b){var c=a.jstree.reference(b.reference),d=c.get_node(b.reference);c.create_node(d,{},"last",function(a){setTimeout(function(){c.edit(a)},0)})}},rename:{separator_before:!1,separator_after:!1,_disabled:!1,label:"Rename",action:function(b){var c=a.jstree.reference(b.reference),d=c.get_node(b.reference);c.edit(d)}},remove:{separator_before:!1,icon:!1,separator_after:!1,_disabled:!1,label:"Delete",action:function(b){var c=a.jstree.reference(b.reference),d=c.get_node(b.reference);c.is_selected(d)?c.delete_node(c.get_selected()):c.delete_node(d)}},ccp:{separator_before:!0,icon:!1,separator_after:!1,label:"Edit",action:!1,submenu:{cut:{separator_before:!1,separator_after:!1,label:"Cut",action:function(b){var c=a.jstree.reference(b.reference),d=c.get_node(b.reference);c.is_selected(d)?c.cut(c.get_top_selected()):c.cut(d)}},copy:{separator_before:!1,icon:!1,separator_after:!1,label:"Copy",action:function(b){var c=a.jstree.reference(b.reference),d=c.get_node(b.reference);c.is_selected(d)?c.copy(c.get_top_selected()):c.copy(d)}},paste:{separator_before:!1,icon:!1,_disabled:function(b){return!a.jstree.reference(b.reference).can_paste()},separator_after:!1,label:"Paste",action:function(b){var c=a.jstree.reference(b.reference),d=c.get_node(b.reference);c.paste(d)}}}}}}},a.jstree.plugins.contextmenu=function(c,d){this.bind=function(){d.bind.call(this);var b=0,c=null,e,f;this.element.on("contextmenu.jstree",".jstree-anchor",a.proxy(function(a,d){"input"!==a.target.tagName.toLowerCase()&&(a.preventDefault(),b=a.ctrlKey?+new Date:0,(d||c)&&(b=+new Date+1e4),c&&clearTimeout(c),this.is_loading(a.currentTarget)||this.show_contextmenu(a.currentTarget,a.pageX,a.pageY,a))},this)).on("click.jstree",".jstree-anchor",a.proxy(function(c){this._data.contextmenu.visible&&(!b||+new Date-b>250)&&a.vakata.context.hide(),b=0},this)).on("touchstart.jstree",".jstree-anchor",function(b){b.originalEvent&&b.originalEvent.changedTouches&&b.originalEvent.changedTouches[0]&&(e=b.originalEvent.changedTouches[0].clientX,f=b.originalEvent.changedTouches[0].clientY,c=setTimeout(function(){a(b.currentTarget).trigger("contextmenu",!0)},750))}).on("touchmove.vakata.jstree",function(a){c&&a.originalEvent&&a.originalEvent.changedTouches&&a.originalEvent.changedTouches[0]&&(Math.abs(e-a.originalEvent.changedTouches[0].clientX)>50||Math.abs(f-a.originalEvent.changedTouches[0].clientY)>50)&&clearTimeout(c)}).on("touchend.vakata.jstree",function(a){c&&clearTimeout(c)}),a(i).on("context_hide.vakata.jstree",a.proxy(function(b,c){this._data.contextmenu.visible=!1,a(c.reference).removeClass("jstree-context")},this))},this.teardown=function(){this._data.contextmenu.visible&&a.vakata.context.hide(),d.teardown.call(this)},this.show_contextmenu=function(c,d,e,f){if(c=this.get_node(c),!c||c.id===a.jstree.root)return!1;var g=this.settings.contextmenu,h=this.get_node(c,!0),i=h.children(".jstree-anchor"),j=!1,k=!1;(g.show_at_node||d===b||e===b)&&(j=i.offset(),d=j.left,e=j.top+this._data.core.li_height),this.settings.contextmenu.select_node&&!this.is_selected(c)&&this.activate_node(c,f),k=g.items,a.isFunction(k)&&(k=k.call(this,c,a.proxy(function(a){this._show_contextmenu(c,d,e,a)},this))),a.isPlainObject(k)&&this._show_contextmenu(c,d,e,k)},this._show_contextmenu=function(b,c,d,e){var f=this.get_node(b,!0),g=f.children(".jstree-anchor");a(i).one("context_show.vakata.jstree",a.proxy(function(b,c){var d="jstree-contextmenu jstree-"+this.get_theme()+"-contextmenu";a(c.element).addClass(d),g.addClass("jstree-context")},this)),this._data.contextmenu.visible=!0,a.vakata.context.show(g,{x:c,y:d},e),this.trigger("show_contextmenu",{node:b,x:c,y:d})}},function(a){var b=!1,c={element:!1,reference:!1,position_x:0,position_y:0,items:[],html:"",is_visible:!1};a.vakata.context={settings:{hide_onmouseleave:0,icons:!0},_trigger:function(b){a(i).triggerHandler("context_"+b+".vakata",{reference:c.reference,element:c.element,position:{x:c.position_x,y:c.position_y}})},_execute:function(b){return b=c.items[b],b&&(!b._disabled||a.isFunction(b._disabled)&&!b._disabled({item:b,reference:c.reference,element:c.element}))&&b.action?b.action.call(null,{item:b,reference:c.reference,element:c.element,position:{x:c.position_x,y:c.position_y}}):!1},_parse:function(b,d){if(!b)return!1;d||(c.html="",c.items=[]);var e="",f=!1,g;return d&&(e+="<ul>"),a.each(b,function(b,d){return d?(c.items.push(d),!f&&d.separator_before&&(e+="<li class='vakata-context-separator'><a href='#' "+(a.vakata.context.settings.icons?"":'style="margin-left:0px;"')+">&#160;</a></li>"),f=!1,e+="<li class='"+(d._class||"")+(d._disabled===!0||a.isFunction(d._disabled)&&d._disabled({item:d,reference:c.reference,element:c.element})?" vakata-contextmenu-disabled ":"")+"' "+(d.shortcut?" data-shortcut='"+d.shortcut+"' ":"")+">",e+="<a href='#' rel='"+(c.items.length-1)+"' "+(d.title?"title='"+d.title+"'":"")+">",a.vakata.context.settings.icons&&(e+="<i ",d.icon&&(e+=-1!==d.icon.indexOf("/")||-1!==d.icon.indexOf(".")?" style='background:url(\""+d.icon+"\") center center no-repeat' ":" class='"+d.icon+"' "),e+="></i><span class='vakata-contextmenu-sep'>&#160;</span>"),e+=(a.isFunction(d.label)?d.label({item:b,reference:c.reference,element:c.element}):d.label)+(d.shortcut?' <span class="vakata-contextmenu-shortcut vakata-contextmenu-shortcut-'+d.shortcut+'">'+(d.shortcut_label||"")+"</span>":"")+"</a>",d.submenu&&(g=a.vakata.context._parse(d.submenu,!0),g&&(e+=g)),e+="</li>",void(d.separator_after&&(e+="<li class='vakata-context-separator'><a href='#' "+(a.vakata.context.settings.icons?"":'style="margin-left:0px;"')+">&#160;</a></li>",f=!0))):!0}),e=e.replace(/<li class\='vakata-context-separator'\><\/li\>$/,""),d&&(e+="</ul>"),d||(c.html=e,a.vakata.context._trigger("parse")),e.length>10?e:!1},_show_submenu:function(c){if(c=a(c),c.length&&c.children("ul").length){var d=c.children("ul"),e=c.offset().left,f=e+c.outerWidth(),g=c.offset().top,h=d.width(),i=d.height(),j=a(window).width()+a(window).scrollLeft(),k=a(window).height()+a(window).scrollTop();b?c[f-(h+10+c.outerWidth())<0?"addClass":"removeClass"]("vakata-context-left"):c[f+h>j&&e>j-f?"addClass":"removeClass"]("vakata-context-right"),g+i+10>k&&d.css("bottom","-1px"),c.hasClass("vakata-context-right")?h>e&&d.css("margin-right",e-h):h>j-f&&d.css("margin-left",j-f-h),d.show()}},show:function(d,e,f){var g,h,i,j,k,l,m,n,o=!0;switch(c.element&&c.element.length&&c.element.width(""),o){case!e&&!d:return!1;case!!e&&!!d:c.reference=d,c.position_x=e.x,c.position_y=e.y;break;case!e&&!!d:c.reference=d,g=d.offset(),c.position_x=g.left+d.outerHeight(),c.position_y=g.top;break;case!!e&&!d:c.position_x=e.x,c.position_y=e.y}d&&!f&&a(d).data("vakata_contextmenu")&&(f=a(d).data("vakata_contextmenu")),a.vakata.context._parse(f)&&c.element.html(c.html),c.items.length&&(c.element.appendTo("body"),h=c.element,i=c.position_x,j=c.position_y,k=h.width(),l=h.height(),m=a(window).width()+a(window).scrollLeft(),n=a(window).height()+a(window).scrollTop(),b&&(i-=h.outerWidth()-a(d).outerWidth(),i<a(window).scrollLeft()+20&&(i=a(window).scrollLeft()+20)),i+k+20>m&&(i=m-(k+20)),j+l+20>n&&(j=n-(l+20)),c.element.css({left:i,top:j}).show().find("a").first().focus().parent().addClass("vakata-context-hover"),c.is_visible=!0,a.vakata.context._trigger("show"))},hide:function(){c.is_visible&&(c.element.hide().find("ul").hide().end().find(":focus").blur().end().detach(),c.is_visible=!1,a.vakata.context._trigger("hide"))}},a(function(){b="rtl"===a("body").css("direction");var d=!1;c.element=a("<ul class='vakata-context'></ul>"),c.element.on("mouseenter","li",function(b){b.stopImmediatePropagation(),a.contains(this,b.relatedTarget)||(d&&clearTimeout(d),c.element.find(".vakata-context-hover").removeClass("vakata-context-hover").end(),a(this).siblings().find("ul").hide().end().end().parentsUntil(".vakata-context","li").addBack().addClass("vakata-context-hover"),a.vakata.context._show_submenu(this))}).on("mouseleave","li",function(b){a.contains(this,b.relatedTarget)||a(this).find(".vakata-context-hover").addBack().removeClass("vakata-context-hover")}).on("mouseleave",function(b){a(this).find(".vakata-context-hover").removeClass("vakata-context-hover"),a.vakata.context.settings.hide_onmouseleave&&(d=setTimeout(function(b){return function(){a.vakata.context.hide()}}(this),a.vakata.context.settings.hide_onmouseleave))}).on("click","a",function(b){b.preventDefault(),a(this).blur().parent().hasClass("vakata-context-disabled")||a.vakata.context._execute(a(this).attr("rel"))===!1||a.vakata.context.hide()}).on("keydown","a",function(b){var d=null;switch(b.which){case 13:case 32:b.type="mouseup",b.preventDefault(),a(b.currentTarget).trigger(b);break;case 37:c.is_visible&&(c.element.find(".vakata-context-hover").last().closest("li").first().find("ul").hide().find(".vakata-context-hover").removeClass("vakata-context-hover").end().end().children("a").focus(),b.stopImmediatePropagation(),b.preventDefault());break;case 38:c.is_visible&&(d=c.element.find("ul:visible").addBack().last().children(".vakata-context-hover").removeClass("vakata-context-hover").prevAll("li:not(.vakata-context-separator)").first(),d.length||(d=c.element.find("ul:visible").addBack().last().children("li:not(.vakata-context-separator)").last()),d.addClass("vakata-context-hover").children("a").focus(),b.stopImmediatePropagation(),b.preventDefault());break;case 39:c.is_visible&&(c.element.find(".vakata-context-hover").last().children("ul").show().children("li:not(.vakata-context-separator)").removeClass("vakata-context-hover").first().addClass("vakata-context-hover").children("a").focus(),b.stopImmediatePropagation(),b.preventDefault());break;case 40:c.is_visible&&(d=c.element.find("ul:visible").addBack().last().children(".vakata-context-hover").removeClass("vakata-context-hover").nextAll("li:not(.vakata-context-separator)").first(),d.length||(d=c.element.find("ul:visible").addBack().last().children("li:not(.vakata-context-separator)").first()),d.addClass("vakata-context-hover").children("a").focus(),b.stopImmediatePropagation(),
-b.preventDefault());break;case 27:a.vakata.context.hide(),b.preventDefault()}}).on("keydown",function(a){a.preventDefault();var b=c.element.find(".vakata-contextmenu-shortcut-"+a.which).parent();b.parent().not(".vakata-context-disabled")&&b.click()}),a(i).on("mousedown.vakata.jstree",function(b){c.is_visible&&!a.contains(c.element[0],b.target)&&a.vakata.context.hide()}).on("context_show.vakata.jstree",function(a,d){c.element.find("li:has(ul)").children("a").addClass("vakata-context-parent"),b&&c.element.addClass("vakata-context-rtl").css("direction","rtl"),c.element.find("ul").hide().end()})})}(a),a.jstree.defaults.dnd={copy:!0,open_timeout:500,is_draggable:!0,check_while_dragging:!0,always_copy:!1,inside_pos:0,drag_selection:!0,touch:!0,large_drop_target:!1,large_drag_target:!1,use_html5:!1};var n,o;a.jstree.plugins.dnd=function(b,c){this.init=function(a,b){c.init.call(this,a,b),this.settings.dnd.use_html5=this.settings.dnd.use_html5&&"draggable"in i.createElement("span")},this.bind=function(){c.bind.call(this),this.element.on(this.settings.dnd.use_html5?"dragstart.jstree":"mousedown.jstree touchstart.jstree",this.settings.dnd.large_drag_target?".jstree-node":".jstree-anchor",a.proxy(function(b){if(this.settings.dnd.large_drag_target&&a(b.target).closest(".jstree-node")[0]!==b.currentTarget)return!0;if("touchstart"===b.type&&(!this.settings.dnd.touch||"selected"===this.settings.dnd.touch&&!a(b.currentTarget).closest(".jstree-node").children(".jstree-anchor").hasClass("jstree-clicked")))return!0;var c=this.get_node(b.target),d=this.is_selected(c)&&this.settings.dnd.drag_selection?this.get_top_selected().length:1,e=d>1?d+" "+this.get_string("nodes"):this.get_text(b.currentTarget);if(this.settings.core.force_text&&(e=a.vakata.html.escape(e)),c&&c.id&&c.id!==a.jstree.root&&(1===b.which||"touchstart"===b.type||"dragstart"===b.type)&&(this.settings.dnd.is_draggable===!0||a.isFunction(this.settings.dnd.is_draggable)&&this.settings.dnd.is_draggable.call(this,d>1?this.get_top_selected(!0):[c],b))){if(n={jstree:!0,origin:this,obj:this.get_node(c,!0),nodes:d>1?this.get_top_selected():[c.id]},o=b.currentTarget,!this.settings.dnd.use_html5)return this.element.trigger("mousedown.jstree"),a.vakata.dnd.start(b,n,'<div id="jstree-dnd" class="jstree-'+this.get_theme()+" jstree-"+this.get_theme()+"-"+this.get_theme_variant()+" "+(this.settings.core.themes.responsive?" jstree-dnd-responsive":"")+'"><i class="jstree-icon jstree-er"></i>'+e+'<ins class="jstree-copy" style="display:none;">+</ins></div>');a.vakata.dnd._trigger("start",b,{helper:a(),element:o,data:n})}},this)),this.settings.dnd.use_html5&&this.element.on("dragover.jstree",function(b){return b.preventDefault(),a.vakata.dnd._trigger("move",b,{helper:a(),element:o,data:n}),!1}).on("drop.jstree",a.proxy(function(b){return b.preventDefault(),a.vakata.dnd._trigger("stop",b,{helper:a(),element:o,data:n}),!1},this))},this.redraw_node=function(a,b,d,e){if(a=c.redraw_node.apply(this,arguments),a&&this.settings.dnd.use_html5)if(this.settings.dnd.large_drag_target)a.setAttribute("draggable",!0);else{var f,g,h=null;for(f=0,g=a.childNodes.length;g>f;f++)if(a.childNodes[f]&&a.childNodes[f].className&&-1!==a.childNodes[f].className.indexOf("jstree-anchor")){h=a.childNodes[f];break}h&&h.setAttribute("draggable",!0)}return a}},a(function(){var c=!1,d=!1,e=!1,f=!1,g=a('<div id="jstree-marker">&#160;</div>').hide();a(i).on("dnd_start.vakata.jstree",function(a,b){c=!1,e=!1,b&&b.data&&b.data.jstree&&g.appendTo("body")}).on("dnd_move.vakata.jstree",function(h,i){if(f&&(i.event&&"dragover"===i.event.type&&i.event.target===e.target||clearTimeout(f)),i&&i.data&&i.data.jstree&&(!i.event.target.id||"jstree-marker"!==i.event.target.id)){e=i.event;var j=a.jstree.reference(i.event.target),k=!1,l=!1,m=!1,n,o,p,q,r,s,t,u,v,w,x,y,z,A,B,C,D;if(j&&j._data&&j._data.dnd)if(g.attr("class","jstree-"+j.get_theme()+(j.settings.core.themes.responsive?" jstree-dnd-responsive":"")),C=i.data.origin&&(i.data.origin.settings.dnd.always_copy||i.data.origin.settings.dnd.copy&&(i.event.metaKey||i.event.ctrlKey)),i.helper.children().attr("class","jstree-"+j.get_theme()+" jstree-"+j.get_theme()+"-"+j.get_theme_variant()+" "+(j.settings.core.themes.responsive?" jstree-dnd-responsive":"")).find(".jstree-copy").first()[C?"show":"hide"](),i.event.target!==j.element[0]&&i.event.target!==j.get_container_ul()[0]||0!==j.get_container_ul().children().length){if(k=j.settings.dnd.large_drop_target?a(i.event.target).closest(".jstree-node").children(".jstree-anchor"):a(i.event.target).closest(".jstree-anchor"),k&&k.length&&k.parent().is(".jstree-closed, .jstree-open, .jstree-leaf")&&(l=k.offset(),m=(i.event.pageY!==b?i.event.pageY:i.event.originalEvent.pageY)-l.top,q=k.outerHeight(),t=q/3>m?["b","i","a"]:m>q-q/3?["a","i","b"]:m>q/2?["i","a","b"]:["i","b","a"],a.each(t,function(b,e){switch(e){case"b":o=l.left-6,p=l.top,r=j.get_parent(k),s=k.parent().index();break;case"i":A=j.settings.dnd.inside_pos,B=j.get_node(k.parent()),o=l.left-2,p=l.top+q/2+1,r=B.id,s="first"===A?0:"last"===A?B.children.length:Math.min(A,B.children.length);break;case"a":o=l.left-6,p=l.top+q,r=j.get_parent(k),s=k.parent().index()+1}for(u=!0,v=0,w=i.data.nodes.length;w>v;v++)if(x=i.data.origin&&(i.data.origin.settings.dnd.always_copy||i.data.origin.settings.dnd.copy&&(i.event.metaKey||i.event.ctrlKey))?"copy_node":"move_node",y=s,"move_node"===x&&"a"===e&&i.data.origin&&i.data.origin===j&&r===j.get_parent(i.data.nodes[v])&&(z=j.get_node(r),y>a.inArray(i.data.nodes[v],z.children)&&(y-=1)),u=u&&(j&&j.settings&&j.settings.dnd&&j.settings.dnd.check_while_dragging===!1||j.check(x,i.data.origin&&i.data.origin!==j?i.data.origin.get_node(i.data.nodes[v]):i.data.nodes[v],r,y,{dnd:!0,ref:j.get_node(k.parent()),pos:e,origin:i.data.origin,is_multi:i.data.origin&&i.data.origin!==j,is_foreign:!i.data.origin})),!u){j&&j.last_error&&(d=j.last_error());break}return"i"===e&&k.parent().is(".jstree-closed")&&j.settings.dnd.open_timeout&&(f=setTimeout(function(a,b){return function(){a.open_node(b)}}(j,k),j.settings.dnd.open_timeout)),u?(D=j.get_node(r,!0),D.hasClass(".jstree-dnd-parent")||(a(".jstree-dnd-parent").removeClass("jstree-dnd-parent"),D.addClass("jstree-dnd-parent")),c={ins:j,par:r,pos:"i"!==e||"last"!==A||0!==s||j.is_loaded(B)?s:"last"},g.css({left:o+"px",top:p+"px"}).show(),i.helper.find(".jstree-icon").first().removeClass("jstree-er").addClass("jstree-ok"),i.event.originalEvent&&i.event.originalEvent.dataTransfer&&(i.event.originalEvent.dataTransfer.dropEffect=C?"copy":"move"),d={},t=!0,!1):void 0}),t===!0))return}else{for(u=!0,v=0,w=i.data.nodes.length;w>v;v++)if(u=u&&j.check(i.data.origin&&(i.data.origin.settings.dnd.always_copy||i.data.origin.settings.dnd.copy&&(i.event.metaKey||i.event.ctrlKey))?"copy_node":"move_node",i.data.origin&&i.data.origin!==j?i.data.origin.get_node(i.data.nodes[v]):i.data.nodes[v],a.jstree.root,"last",{dnd:!0,ref:j.get_node(a.jstree.root),pos:"i",origin:i.data.origin,is_multi:i.data.origin&&i.data.origin!==j,is_foreign:!i.data.origin}),!u)break;if(u)return c={ins:j,par:a.jstree.root,pos:"last"},g.hide(),i.helper.find(".jstree-icon").first().removeClass("jstree-er").addClass("jstree-ok"),void(i.event.originalEvent&&i.event.originalEvent.dataTransfer&&(i.event.originalEvent.dataTransfer.dropEffect=C?"copy":"move"))}a(".jstree-dnd-parent").removeClass("jstree-dnd-parent"),c=!1,i.helper.find(".jstree-icon").removeClass("jstree-ok").addClass("jstree-er"),i.event.originalEvent&&i.event.originalEvent.dataTransfer&&(i.event.originalEvent.dataTransfer.dropEffect="none"),g.hide()}}).on("dnd_scroll.vakata.jstree",function(a,b){b&&b.data&&b.data.jstree&&(g.hide(),c=!1,e=!1,b.helper.find(".jstree-icon").first().removeClass("jstree-ok").addClass("jstree-er"))}).on("dnd_stop.vakata.jstree",function(b,h){if(a(".jstree-dnd-parent").removeClass("jstree-dnd-parent"),f&&clearTimeout(f),h&&h.data&&h.data.jstree){g.hide().detach();var i,j,k=[];if(c){for(i=0,j=h.data.nodes.length;j>i;i++)k[i]=h.data.origin?h.data.origin.get_node(h.data.nodes[i]):h.data.nodes[i];c.ins[h.data.origin&&(h.data.origin.settings.dnd.always_copy||h.data.origin.settings.dnd.copy&&(h.event.metaKey||h.event.ctrlKey))?"copy_node":"move_node"](k,c.par,c.pos,!1,!1,!1,h.data.origin)}else i=a(h.event.target).closest(".jstree"),i.length&&d&&d.error&&"check"===d.error&&(i=i.jstree(!0),i&&i.settings.core.error.call(this,d));e=!1,c=!1}}).on("keyup.jstree keydown.jstree",function(b,h){h=a.vakata.dnd._get(),h&&h.data&&h.data.jstree&&("keyup"===b.type&&27===b.which?(f&&clearTimeout(f),c=!1,d=!1,e=!1,f=!1,g.hide().detach(),a.vakata.dnd._clean()):(h.helper.find(".jstree-copy").first()[h.data.origin&&(h.data.origin.settings.dnd.always_copy||h.data.origin.settings.dnd.copy&&(b.metaKey||b.ctrlKey))?"show":"hide"](),e&&(e.metaKey=b.metaKey,e.ctrlKey=b.ctrlKey,a.vakata.dnd._trigger("move",e))))})}),function(a){a.vakata.html={div:a("<div />"),escape:function(b){return a.vakata.html.div.text(b).html()},strip:function(b){return a.vakata.html.div.empty().append(a.parseHTML(b)).text()}};var c={element:!1,target:!1,is_down:!1,is_drag:!1,helper:!1,helper_w:0,data:!1,init_x:0,init_y:0,scroll_l:0,scroll_t:0,scroll_e:!1,scroll_i:!1,is_touch:!1};a.vakata.dnd={settings:{scroll_speed:10,scroll_proximity:20,helper_left:5,helper_top:10,threshold:5,threshold_touch:50},_trigger:function(c,d,e){e===b&&(e=a.vakata.dnd._get()),e.event=d,a(i).triggerHandler("dnd_"+c+".vakata",e)},_get:function(){return{data:c.data,element:c.element,helper:c.helper}},_clean:function(){c.helper&&c.helper.remove(),c.scroll_i&&(clearInterval(c.scroll_i),c.scroll_i=!1),c={element:!1,target:!1,is_down:!1,is_drag:!1,helper:!1,helper_w:0,data:!1,init_x:0,init_y:0,scroll_l:0,scroll_t:0,scroll_e:!1,scroll_i:!1,is_touch:!1},a(i).off("mousemove.vakata.jstree touchmove.vakata.jstree",a.vakata.dnd.drag),a(i).off("mouseup.vakata.jstree touchend.vakata.jstree",a.vakata.dnd.stop)},_scroll:function(b){if(!c.scroll_e||!c.scroll_l&&!c.scroll_t)return c.scroll_i&&(clearInterval(c.scroll_i),c.scroll_i=!1),!1;if(!c.scroll_i)return c.scroll_i=setInterval(a.vakata.dnd._scroll,100),!1;if(b===!0)return!1;var d=c.scroll_e.scrollTop(),e=c.scroll_e.scrollLeft();c.scroll_e.scrollTop(d+c.scroll_t*a.vakata.dnd.settings.scroll_speed),c.scroll_e.scrollLeft(e+c.scroll_l*a.vakata.dnd.settings.scroll_speed),(d!==c.scroll_e.scrollTop()||e!==c.scroll_e.scrollLeft())&&a.vakata.dnd._trigger("scroll",c.scroll_e)},start:function(b,d,e){"touchstart"===b.type&&b.originalEvent&&b.originalEvent.changedTouches&&b.originalEvent.changedTouches[0]&&(b.pageX=b.originalEvent.changedTouches[0].pageX,b.pageY=b.originalEvent.changedTouches[0].pageY,b.target=i.elementFromPoint(b.originalEvent.changedTouches[0].pageX-window.pageXOffset,b.originalEvent.changedTouches[0].pageY-window.pageYOffset)),c.is_drag&&a.vakata.dnd.stop({});try{b.currentTarget.unselectable="on",b.currentTarget.onselectstart=function(){return!1},b.currentTarget.style&&(b.currentTarget.style.touchAction="none",b.currentTarget.style.msTouchAction="none",b.currentTarget.style.MozUserSelect="none")}catch(f){}return c.init_x=b.pageX,c.init_y=b.pageY,c.data=d,c.is_down=!0,c.element=b.currentTarget,c.target=b.target,c.is_touch="touchstart"===b.type,e!==!1&&(c.helper=a("<div id='vakata-dnd'></div>").html(e).css({display:"block",margin:"0",padding:"0",position:"absolute",top:"-2000px",lineHeight:"16px",zIndex:"10000"})),a(i).on("mousemove.vakata.jstree touchmove.vakata.jstree",a.vakata.dnd.drag),a(i).on("mouseup.vakata.jstree touchend.vakata.jstree",a.vakata.dnd.stop),!1},drag:function(b){if("touchmove"===b.type&&b.originalEvent&&b.originalEvent.changedTouches&&b.originalEvent.changedTouches[0]&&(b.pageX=b.originalEvent.changedTouches[0].pageX,b.pageY=b.originalEvent.changedTouches[0].pageY,b.target=i.elementFromPoint(b.originalEvent.changedTouches[0].pageX-window.pageXOffset,b.originalEvent.changedTouches[0].pageY-window.pageYOffset)),c.is_down){if(!c.is_drag){if(!(Math.abs(b.pageX-c.init_x)>(c.is_touch?a.vakata.dnd.settings.threshold_touch:a.vakata.dnd.settings.threshold)||Math.abs(b.pageY-c.init_y)>(c.is_touch?a.vakata.dnd.settings.threshold_touch:a.vakata.dnd.settings.threshold)))return;c.helper&&(c.helper.appendTo("body"),c.helper_w=c.helper.outerWidth()),c.is_drag=!0,a(c.target).one("click.vakata",!1),a.vakata.dnd._trigger("start",b)}var d=!1,e=!1,f=!1,g=!1,h=!1,j=!1,k=!1,l=!1,m=!1,n=!1;return c.scroll_t=0,c.scroll_l=0,c.scroll_e=!1,a(a(b.target).parentsUntil("body").addBack().get().reverse()).filter(function(){return/^auto|scroll$/.test(a(this).css("overflow"))&&(this.scrollHeight>this.offsetHeight||this.scrollWidth>this.offsetWidth)}).each(function(){var d=a(this),e=d.offset();return this.scrollHeight>this.offsetHeight&&(e.top+d.height()-b.pageY<a.vakata.dnd.settings.scroll_proximity&&(c.scroll_t=1),b.pageY-e.top<a.vakata.dnd.settings.scroll_proximity&&(c.scroll_t=-1)),this.scrollWidth>this.offsetWidth&&(e.left+d.width()-b.pageX<a.vakata.dnd.settings.scroll_proximity&&(c.scroll_l=1),b.pageX-e.left<a.vakata.dnd.settings.scroll_proximity&&(c.scroll_l=-1)),c.scroll_t||c.scroll_l?(c.scroll_e=a(this),!1):void 0}),c.scroll_e||(d=a(i),e=a(window),f=d.height(),g=e.height(),h=d.width(),j=e.width(),k=d.scrollTop(),l=d.scrollLeft(),f>g&&b.pageY-k<a.vakata.dnd.settings.scroll_proximity&&(c.scroll_t=-1),f>g&&g-(b.pageY-k)<a.vakata.dnd.settings.scroll_proximity&&(c.scroll_t=1),h>j&&b.pageX-l<a.vakata.dnd.settings.scroll_proximity&&(c.scroll_l=-1),h>j&&j-(b.pageX-l)<a.vakata.dnd.settings.scroll_proximity&&(c.scroll_l=1),(c.scroll_t||c.scroll_l)&&(c.scroll_e=d)),c.scroll_e&&a.vakata.dnd._scroll(!0),c.helper&&(m=parseInt(b.pageY+a.vakata.dnd.settings.helper_top,10),n=parseInt(b.pageX+a.vakata.dnd.settings.helper_left,10),f&&m+25>f&&(m=f-50),h&&n+c.helper_w>h&&(n=h-(c.helper_w+2)),c.helper.css({left:n+"px",top:m+"px"})),a.vakata.dnd._trigger("move",b),!1}},stop:function(b){if("touchend"===b.type&&b.originalEvent&&b.originalEvent.changedTouches&&b.originalEvent.changedTouches[0]&&(b.pageX=b.originalEvent.changedTouches[0].pageX,b.pageY=b.originalEvent.changedTouches[0].pageY,b.target=i.elementFromPoint(b.originalEvent.changedTouches[0].pageX-window.pageXOffset,b.originalEvent.changedTouches[0].pageY-window.pageYOffset)),c.is_drag)b.target!==c.target&&a(c.target).off("click.vakata"),a.vakata.dnd._trigger("stop",b);else if("touchend"===b.type&&b.target===c.target){var d=setTimeout(function(){a(b.target).click()},100);a(b.target).one("click",function(){d&&clearTimeout(d)})}return a.vakata.dnd._clean(),!1}}}(a),a.jstree.defaults.massload=null,a.jstree.plugins.massload=function(b,c){this.init=function(a,b){this._data.massload={},c.init.call(this,a,b)},this._load_nodes=function(b,d,e,f){var g=this.settings.massload,h=JSON.stringify(b),i=[],j=this._model.data,k,l,m;if(!e){for(k=0,l=b.length;l>k;k++)(!j[b[k]]||!j[b[k]].state.loaded&&!j[b[k]].state.failed||f)&&(i.push(b[k]),m=this.get_node(b[k],!0),m&&m.length&&m.addClass("jstree-loading").attr("aria-busy",!0));if(this._data.massload={},i.length){if(a.isFunction(g))return g.call(this,i,a.proxy(function(a){var g,h;if(a)for(g in a)a.hasOwnProperty(g)&&(this._data.massload[g]=a[g]);for(g=0,h=b.length;h>g;g++)m=this.get_node(b[g],!0),m&&m.length&&m.removeClass("jstree-loading").attr("aria-busy",!1);c._load_nodes.call(this,b,d,e,f)},this));if("object"==typeof g&&g&&g.url)return g=a.extend(!0,{},g),a.isFunction(g.url)&&(g.url=g.url.call(this,i)),a.isFunction(g.data)&&(g.data=g.data.call(this,i)),a.ajax(g).done(a.proxy(function(a,g,h){var i,j;if(a)for(i in a)a.hasOwnProperty(i)&&(this._data.massload[i]=a[i]);for(i=0,j=b.length;j>i;i++)m=this.get_node(b[i],!0),m&&m.length&&m.removeClass("jstree-loading").attr("aria-busy",!1);c._load_nodes.call(this,b,d,e,f)},this)).fail(a.proxy(function(a){c._load_nodes.call(this,b,d,e,f)},this))}}return c._load_nodes.call(this,b,d,e,f)},this._load_node=function(b,d){var e=this._data.massload[b.id],f=null,g;return e?(f=this["string"==typeof e?"_append_html_data":"_append_json_data"](b,"string"==typeof e?a(a.parseHTML(e)).filter(function(){return 3!==this.nodeType}):e,function(a){d.call(this,a)}),g=this.get_node(b.id,!0),g&&g.length&&g.removeClass("jstree-loading").attr("aria-busy",!1),delete this._data.massload[b.id],f):c._load_node.call(this,b,d)}},a.jstree.defaults.search={ajax:!1,fuzzy:!1,case_sensitive:!1,show_only_matches:!1,show_only_matches_children:!1,close_opened_onclear:!0,search_leaves_only:!1,search_callback:!1},a.jstree.plugins.search=function(c,d){this.bind=function(){d.bind.call(this),this._data.search.str="",this._data.search.dom=a(),this._data.search.res=[],this._data.search.opn=[],this._data.search.som=!1,this._data.search.smc=!1,this._data.search.hdn=[],this.element.on("search.jstree",a.proxy(function(b,c){if(this._data.search.som&&c.res.length){var d=this._model.data,e,f,g=[],h,i;for(e=0,f=c.res.length;f>e;e++)if(d[c.res[e]]&&!d[c.res[e]].state.hidden&&(g.push(c.res[e]),g=g.concat(d[c.res[e]].parents),this._data.search.smc))for(h=0,i=d[c.res[e]].children_d.length;i>h;h++)d[d[c.res[e]].children_d[h]]&&!d[d[c.res[e]].children_d[h]].state.hidden&&g.push(d[c.res[e]].children_d[h]);g=a.vakata.array_remove_item(a.vakata.array_unique(g),a.jstree.root),this._data.search.hdn=this.hide_all(!0),this.show_node(g,!0),this.redraw(!0)}},this)).on("clear_search.jstree",a.proxy(function(a,b){this._data.search.som&&b.res.length&&(this.show_node(this._data.search.hdn,!0),this.redraw(!0))},this))},this.search=function(c,d,e,f,g,h){if(c===!1||""===a.trim(c.toString()))return this.clear_search();f=this.get_node(f),f=f&&f.id?f.id:null,c=c.toString();var i=this.settings.search,j=i.ajax?i.ajax:!1,k=this._model.data,l=null,m=[],n=[],o,p;if(this._data.search.res.length&&!g&&this.clear_search(),e===b&&(e=i.show_only_matches),h===b&&(h=i.show_only_matches_children),!d&&j!==!1)return a.isFunction(j)?j.call(this,c,a.proxy(function(b){b&&b.d&&(b=b.d),this._load_nodes(a.isArray(b)?a.vakata.array_unique(b):[],function(){this.search(c,!0,e,f,g)})},this),f):(j=a.extend({},j),j.data||(j.data={}),j.data.str=c,f&&(j.data.inside=f),a.ajax(j).fail(a.proxy(function(){this._data.core.last_error={error:"ajax",plugin:"search",id:"search_01",reason:"Could not load search parents",data:JSON.stringify(j)},this.settings.core.error.call(this,this._data.core.last_error)},this)).done(a.proxy(function(b){b&&b.d&&(b=b.d),this._load_nodes(a.isArray(b)?a.vakata.array_unique(b):[],function(){this.search(c,!0,e,f,g)})},this)));if(g||(this._data.search.str=c,this._data.search.dom=a(),this._data.search.res=[],this._data.search.opn=[],this._data.search.som=e,this._data.search.smc=h),l=new a.vakata.search(c,!0,{caseSensitive:i.case_sensitive,fuzzy:i.fuzzy}),a.each(k[f?f:a.jstree.root].children_d,function(a,b){var d=k[b];d.text&&!d.state.hidden&&(!i.search_leaves_only||d.state.loaded&&0===d.children.length)&&(i.search_callback&&i.search_callback.call(this,c,d)||!i.search_callback&&l.search(d.text).isMatch)&&(m.push(b),n=n.concat(d.parents))}),m.length){for(n=a.vakata.array_unique(n),o=0,p=n.length;p>o;o++)n[o]!==a.jstree.root&&k[n[o]]&&this.open_node(n[o],null,0)===!0&&this._data.search.opn.push(n[o]);g?(this._data.search.dom=this._data.search.dom.add(a(this.element[0].querySelectorAll("#"+a.map(m,function(b){return-1!=="0123456789".indexOf(b[0])?"\\3"+b[0]+" "+b.substr(1).replace(a.jstree.idregex,"\\$&"):b.replace(a.jstree.idregex,"\\$&")}).join(", #")))),this._data.search.res=a.vakata.array_unique(this._data.search.res.concat(m))):(this._data.search.dom=a(this.element[0].querySelectorAll("#"+a.map(m,function(b){return-1!=="0123456789".indexOf(b[0])?"\\3"+b[0]+" "+b.substr(1).replace(a.jstree.idregex,"\\$&"):b.replace(a.jstree.idregex,"\\$&")}).join(", #"))),this._data.search.res=m),this._data.search.dom.children(".jstree-anchor").addClass("jstree-search")}this.trigger("search",{nodes:this._data.search.dom,str:c,res:this._data.search.res,show_only_matches:e})},this.clear_search=function(){this.settings.search.close_opened_onclear&&this.close_node(this._data.search.opn,0),this.trigger("clear_search",{nodes:this._data.search.dom,str:this._data.search.str,res:this._data.search.res}),this._data.search.res.length&&(this._data.search.dom=a(this.element[0].querySelectorAll("#"+a.map(this._data.search.res,function(b){return-1!=="0123456789".indexOf(b[0])?"\\3"+b[0]+" "+b.substr(1).replace(a.jstree.idregex,"\\$&"):b.replace(a.jstree.idregex,"\\$&")}).join(", #"))),this._data.search.dom.children(".jstree-anchor").removeClass("jstree-search")),this._data.search.str="",this._data.search.res=[],this._data.search.opn=[],this._data.search.dom=a()},this.redraw_node=function(b,c,e,f){if(b=d.redraw_node.apply(this,arguments),b&&-1!==a.inArray(b.id,this._data.search.res)){var g,h,i=null;for(g=0,h=b.childNodes.length;h>g;g++)if(b.childNodes[g]&&b.childNodes[g].className&&-1!==b.childNodes[g].className.indexOf("jstree-anchor")){i=b.childNodes[g];break}i&&(i.className+=" jstree-search")}return b}},function(a){a.vakata.search=function(b,c,d){d=d||{},d=a.extend({},a.vakata.search.defaults,d),d.fuzzy!==!1&&(d.fuzzy=!0),b=d.caseSensitive?b:b.toLowerCase();var e=d.location,f=d.distance,g=d.threshold,h=b.length,i,j,k,l;return h>32&&(d.fuzzy=!1),d.fuzzy&&(i=1<<h-1,j=function(){var a={},c=0;for(c=0;h>c;c++)a[b.charAt(c)]=0;for(c=0;h>c;c++)a[b.charAt(c)]|=1<<h-c-1;return a}(),k=function(a,b){var c=a/h,d=Math.abs(e-b);return f?c+d/f:d?1:c}),l=function(a){if(a=d.caseSensitive?a:a.toLowerCase(),b===a||-1!==a.indexOf(b))return{isMatch:!0,score:0};if(!d.fuzzy)return{isMatch:!1,score:1};var c,f,l=a.length,m=g,n=a.indexOf(b,e),o,p,q=h+l,r,s,t,u,v,w=1,x=[];for(-1!==n&&(m=Math.min(k(0,n),m),n=a.lastIndexOf(b,e+h),-1!==n&&(m=Math.min(k(0,n),m))),n=-1,c=0;h>c;c++){o=0,p=q;while(p>o)k(c,e+p)<=m?o=p:q=p,p=Math.floor((q-o)/2+o);for(q=p,s=Math.max(1,e-p+1),t=Math.min(e+p,l)+h,u=new Array(t+2),u[t+1]=(1<<c)-1,f=t;f>=s;f--)if(v=j[a.charAt(f-1)],0===c?u[f]=(u[f+1]<<1|1)&v:u[f]=(u[f+1]<<1|1)&v|((r[f+1]|r[f])<<1|1)|r[f+1],u[f]&i&&(w=k(c,f-1),m>=w)){if(m=w,n=f-1,x.push(n),!(n>e))break;s=Math.max(1,2*e-n)}if(k(c+1,e)>m)break;r=u}return{isMatch:n>=0,score:w}},c===!0?{search:l}:l(c)},a.vakata.search.defaults={location:0,distance:100,threshold:.6,fuzzy:!1,caseSensitive:!1}}(a),a.jstree.defaults.sort=function(a,b){return this.get_text(a)>this.get_text(b)?1:-1},a.jstree.plugins.sort=function(b,c){this.bind=function(){c.bind.call(this),this.element.on("model.jstree",a.proxy(function(a,b){this.sort(b.parent,!0)},this)).on("rename_node.jstree create_node.jstree",a.proxy(function(a,b){this.sort(b.parent||b.node.parent,!1),this.redraw_node(b.parent||b.node.parent,!0)},this)).on("move_node.jstree copy_node.jstree",a.proxy(function(a,b){this.sort(b.parent,!1),this.redraw_node(b.parent,!0)},this))},this.sort=function(b,c){var d,e;if(b=this.get_node(b),b&&b.children&&b.children.length&&(b.children.sort(a.proxy(this.settings.sort,this)),c))for(d=0,e=b.children_d.length;e>d;d++)this.sort(b.children_d[d],!1)}};var p=!1;a.jstree.defaults.state={key:"jstree",events:"changed.jstree open_node.jstree close_node.jstree check_node.jstree uncheck_node.jstree",ttl:!1,filter:!1},a.jstree.plugins.state=function(b,c){this.bind=function(){c.bind.call(this);var b=a.proxy(function(){this.element.on(this.settings.state.events,a.proxy(function(){p&&clearTimeout(p),p=setTimeout(a.proxy(function(){this.save_state()},this),100)},this)),this.trigger("state_ready")},this);this.element.on("ready.jstree",a.proxy(function(a,c){this.element.one("restore_state.jstree",b),this.restore_state()||b()},this))},this.save_state=function(){var b={state:this.get_state(),ttl:this.settings.state.ttl,sec:+new Date};a.vakata.storage.set(this.settings.state.key,JSON.stringify(b))},this.restore_state=function(){var b=a.vakata.storage.get(this.settings.state.key);if(b)try{b=JSON.parse(b)}catch(c){return!1}return b&&b.ttl&&b.sec&&+new Date-b.sec>b.ttl?!1:(b&&b.state&&(b=b.state),b&&a.isFunction(this.settings.state.filter)&&(b=this.settings.state.filter.call(this,b)),b?(this.element.one("set_state.jstree",function(c,d){d.instance.trigger("restore_state",{state:a.extend(!0,{},b)})}),this.set_state(b),!0):!1)},this.clear_state=function(){return a.vakata.storage.del(this.settings.state.key)}},function(a,b){a.vakata.storage={set:function(a,b){return window.localStorage.setItem(a,b)},get:function(a){return window.localStorage.getItem(a)},del:function(a){return window.localStorage.removeItem(a)}}}(a),a.jstree.defaults.types={"default":{}},a.jstree.defaults.types[a.jstree.root]={},a.jstree.plugins.types=function(c,d){this.init=function(c,e){var f,g;if(e&&e.types&&e.types["default"])for(f in e.types)if("default"!==f&&f!==a.jstree.root&&e.types.hasOwnProperty(f))for(g in e.types["default"])e.types["default"].hasOwnProperty(g)&&e.types[f][g]===b&&(e.types[f][g]=e.types["default"][g]);d.init.call(this,c,e),this._model.data[a.jstree.root].type=a.jstree.root},this.refresh=function(b,c){d.refresh.call(this,b,c),this._model.data[a.jstree.root].type=a.jstree.root},this.bind=function(){this.element.on("model.jstree",a.proxy(function(c,d){var e=this._model.data,f=d.nodes,g=this.settings.types,h,i,j="default",k;for(h=0,i=f.length;i>h;h++){if(j="default",e[f[h]].original&&e[f[h]].original.type&&g[e[f[h]].original.type]&&(j=e[f[h]].original.type),e[f[h]].data&&e[f[h]].data.jstree&&e[f[h]].data.jstree.type&&g[e[f[h]].data.jstree.type]&&(j=e[f[h]].data.jstree.type),e[f[h]].type=j,e[f[h]].icon===!0&&g[j].icon!==b&&(e[f[h]].icon=g[j].icon),g[j].li_attr!==b&&"object"==typeof g[j].li_attr)for(k in g[j].li_attr)if(g[j].li_attr.hasOwnProperty(k)){if("id"===k)continue;e[f[h]].li_attr[k]===b?e[f[h]].li_attr[k]=g[j].li_attr[k]:"class"===k&&(e[f[h]].li_attr["class"]=g[j].li_attr["class"]+" "+e[f[h]].li_attr["class"])}if(g[j].a_attr!==b&&"object"==typeof g[j].a_attr)for(k in g[j].a_attr)if(g[j].a_attr.hasOwnProperty(k)){if("id"===k)continue;e[f[h]].a_attr[k]===b?e[f[h]].a_attr[k]=g[j].a_attr[k]:"href"===k&&"#"===e[f[h]].a_attr[k]?e[f[h]].a_attr.href=g[j].a_attr.href:"class"===k&&(e[f[h]].a_attr["class"]=g[j].a_attr["class"]+" "+e[f[h]].a_attr["class"])}}e[a.jstree.root].type=a.jstree.root},this)),d.bind.call(this)},this.get_json=function(b,c,e){var f,g,h=this._model.data,i=c?a.extend(!0,{},c,{no_id:!1}):{},j=d.get_json.call(this,b,i,e);if(j===!1)return!1;if(a.isArray(j))for(f=0,g=j.length;g>f;f++)j[f].type=j[f].id&&h[j[f].id]&&h[j[f].id].type?h[j[f].id].type:"default",c&&c.no_id&&(delete j[f].id,j[f].li_attr&&j[f].li_attr.id&&delete j[f].li_attr.id,j[f].a_attr&&j[f].a_attr.id&&delete j[f].a_attr.id);else j.type=j.id&&h[j.id]&&h[j.id].type?h[j.id].type:"default",c&&c.no_id&&(j=this._delete_ids(j));return j},this._delete_ids=function(b){if(a.isArray(b)){for(var c=0,d=b.length;d>c;c++)b[c]=this._delete_ids(b[c]);return b}return delete b.id,b.li_attr&&b.li_attr.id&&delete b.li_attr.id,b.a_attr&&b.a_attr.id&&delete b.a_attr.id,b.children&&a.isArray(b.children)&&(b.children=this._delete_ids(b.children)),b},this.check=function(c,e,f,g,h){if(d.check.call(this,c,e,f,g,h)===!1)return!1;e=e&&e.id?e:this.get_node(e),f=f&&f.id?f:this.get_node(f);var i=e&&e.id?h&&h.origin?h.origin:a.jstree.reference(e.id):null,j,k,l,m;switch(i=i&&i._model&&i._model.data?i._model.data:null,c){case"create_node":case"move_node":case"copy_node":if("move_node"!==c||-1===a.inArray(e.id,f.children)){if(j=this.get_rules(f),j.max_children!==b&&-1!==j.max_children&&j.max_children===f.children.length)return this._data.core.last_error={error:"check",plugin:"types",id:"types_01",reason:"max_children prevents function: "+c,data:JSON.stringify({chk:c,pos:g,obj:e&&e.id?e.id:!1,par:f&&f.id?f.id:!1})},!1;if(j.valid_children!==b&&-1!==j.valid_children&&-1===a.inArray(e.type||"default",j.valid_children))return this._data.core.last_error={error:"check",plugin:"types",id:"types_02",reason:"valid_children prevents function: "+c,data:JSON.stringify({chk:c,pos:g,obj:e&&e.id?e.id:!1,par:f&&f.id?f.id:!1})},!1;if(i&&e.children_d&&e.parents){for(k=0,l=0,m=e.children_d.length;m>l;l++)k=Math.max(k,i[e.children_d[l]].parents.length);k=k-e.parents.length+1}(0>=k||k===b)&&(k=1);do{if(j.max_depth!==b&&-1!==j.max_depth&&j.max_depth<k)return this._data.core.last_error={error:"check",plugin:"types",id:"types_03",reason:"max_depth prevents function: "+c,data:JSON.stringify({chk:c,pos:g,obj:e&&e.id?e.id:!1,par:f&&f.id?f.id:!1})},!1;f=this.get_node(f.parent),j=this.get_rules(f),k++}while(f)}}return!0},this.get_rules=function(a){if(a=this.get_node(a),!a)return!1;var c=this.get_type(a,!0);return c.max_depth===b&&(c.max_depth=-1),c.max_children===b&&(c.max_children=-1),c.valid_children===b&&(c.valid_children=-1),c},this.get_type=function(b,c){return b=this.get_node(b),b?c?a.extend({type:b.type},this.settings.types[b.type]):b.type:!1},this.set_type=function(c,d){var e=this._model.data,f,g,h,i,j,k,l,m;if(a.isArray(c)){for(c=c.slice(),g=0,h=c.length;h>g;g++)this.set_type(c[g],d);return!0}if(f=this.settings.types,c=this.get_node(c),!f[d]||!c)return!1;if(l=this.get_node(c,!0),l&&l.length&&(m=l.children(".jstree-anchor")),i=c.type,j=this.get_icon(c),c.type=d,(j===!0||f[i]&&f[i].icon!==b&&j===f[i].icon)&&this.set_icon(c,f[d].icon!==b?f[d].icon:!0),f[i].li_attr!==b&&"object"==typeof f[i].li_attr)for(k in f[i].li_attr)if(f[i].li_attr.hasOwnProperty(k)){if("id"===k)continue;"class"===k?(e[c.id].li_attr["class"]=(e[c.id].li_attr["class"]||"").replace(f[i].li_attr[k],""),l&&l.removeClass(f[i].li_attr[k])):e[c.id].li_attr[k]===f[i].li_attr[k]&&(e[c.id].li_attr[k]=null,l&&l.removeAttr(k))}if(f[i].a_attr!==b&&"object"==typeof f[i].a_attr)for(k in f[i].a_attr)if(f[i].a_attr.hasOwnProperty(k)){if("id"===k)continue;"class"===k?(e[c.id].a_attr["class"]=(e[c.id].a_attr["class"]||"").replace(f[i].a_attr[k],""),m&&m.removeClass(f[i].a_attr[k])):e[c.id].a_attr[k]===f[i].a_attr[k]&&("href"===k?(e[c.id].a_attr[k]="#",m&&m.attr("href","#")):(delete e[c.id].a_attr[k],m&&m.removeAttr(k)))}if(f[d].li_attr!==b&&"object"==typeof f[d].li_attr)for(k in f[d].li_attr)if(f[d].li_attr.hasOwnProperty(k)){if("id"===k)continue;e[c.id].li_attr[k]===b?(e[c.id].li_attr[k]=f[d].li_attr[k],l&&("class"===k?l.addClass(f[d].li_attr[k]):l.attr(k,f[d].li_attr[k]))):"class"===k&&(e[c.id].li_attr["class"]=f[d].li_attr[k]+" "+e[c.id].li_attr["class"],l&&l.addClass(f[d].li_attr[k]))}if(f[d].a_attr!==b&&"object"==typeof f[d].a_attr)for(k in f[d].a_attr)if(f[d].a_attr.hasOwnProperty(k)){if("id"===k)continue;e[c.id].a_attr[k]===b?(e[c.id].a_attr[k]=f[d].a_attr[k],m&&("class"===k?m.addClass(f[d].a_attr[k]):m.attr(k,f[d].a_attr[k]))):"href"===k&&"#"===e[c.id].a_attr[k]?(e[c.id].a_attr.href=f[d].a_attr.href,m&&m.attr("href",f[d].a_attr.href)):"class"===k&&(e[c.id].a_attr["class"]=f[d].a_attr["class"]+" "+e[c.id].a_attr["class"],m&&m.addClass(f[d].a_attr[k]))}return!0}},a.jstree.defaults.unique={case_sensitive:!1,duplicate:function(a,b){return a+" ("+b+")"}},a.jstree.plugins.unique=function(c,d){this.check=function(b,c,e,f,g){if(d.check.call(this,b,c,e,f,g)===!1)return!1;if(c=c&&c.id?c:this.get_node(c),e=e&&e.id?e:this.get_node(e),!e||!e.children)return!0;var h="rename_node"===b?f:c.text,i=[],j=this.settings.unique.case_sensitive,k=this._model.data,l,m;for(l=0,m=e.children.length;m>l;l++)i.push(j?k[e.children[l]].text:k[e.children[l]].text.toLowerCase());switch(j||(h=h.toLowerCase()),b){case"delete_node":return!0;case"rename_node":return l=-1===a.inArray(h,i)||c.text&&c.text[j?"toString":"toLowerCase"]()===h,l||(this._data.core.last_error={error:"check",plugin:"unique",id:"unique_01",reason:"Child with name "+h+" already exists. Preventing: "+b,data:JSON.stringify({chk:b,pos:f,obj:c&&c.id?c.id:!1,par:e&&e.id?e.id:!1})}),l;case"create_node":return l=-1===a.inArray(h,i),l||(this._data.core.last_error={error:"check",plugin:"unique",id:"unique_04",reason:"Child with name "+h+" already exists. Preventing: "+b,data:JSON.stringify({chk:b,pos:f,obj:c&&c.id?c.id:!1,par:e&&e.id?e.id:!1})}),l;case"copy_node":return l=-1===a.inArray(h,i),l||(this._data.core.last_error={error:"check",plugin:"unique",
-id:"unique_02",reason:"Child with name "+h+" already exists. Preventing: "+b,data:JSON.stringify({chk:b,pos:f,obj:c&&c.id?c.id:!1,par:e&&e.id?e.id:!1})}),l;case"move_node":return l=c.parent===e.id&&(!g||!g.is_multi)||-1===a.inArray(h,i),l||(this._data.core.last_error={error:"check",plugin:"unique",id:"unique_03",reason:"Child with name "+h+" already exists. Preventing: "+b,data:JSON.stringify({chk:b,pos:f,obj:c&&c.id?c.id:!1,par:e&&e.id?e.id:!1})}),l}return!0},this.create_node=function(c,e,f,g,h){if(!e||e.text===b){if(null===c&&(c=a.jstree.root),c=this.get_node(c),!c)return d.create_node.call(this,c,e,f,g,h);if(f=f===b?"last":f,!f.toString().match(/^(before|after)$/)&&!h&&!this.is_loaded(c))return d.create_node.call(this,c,e,f,g,h);e||(e={});var i,j,k,l,m,n=this._model.data,o=this.settings.unique.case_sensitive,p=this.settings.unique.duplicate;for(j=i=this.get_string("New node"),k=[],l=0,m=c.children.length;m>l;l++)k.push(o?n[c.children[l]].text:n[c.children[l]].text.toLowerCase());l=1;while(-1!==a.inArray(o?j:j.toLowerCase(),k))j=p.call(this,i,++l).toString();e.text=j}return d.create_node.call(this,c,e,f,g,h)}};var q=i.createElement("DIV");if(q.setAttribute("unselectable","on"),q.setAttribute("role","presentation"),q.className="jstree-wholerow",q.innerHTML="&#160;",a.jstree.plugins.wholerow=function(b,c){this.bind=function(){c.bind.call(this),this.element.on("ready.jstree set_state.jstree",a.proxy(function(){this.hide_dots()},this)).on("init.jstree loading.jstree ready.jstree",a.proxy(function(){this.get_container_ul().addClass("jstree-wholerow-ul")},this)).on("deselect_all.jstree",a.proxy(function(a,b){this.element.find(".jstree-wholerow-clicked").removeClass("jstree-wholerow-clicked")},this)).on("changed.jstree",a.proxy(function(a,b){this.element.find(".jstree-wholerow-clicked").removeClass("jstree-wholerow-clicked");var c=!1,d,e;for(d=0,e=b.selected.length;e>d;d++)c=this.get_node(b.selected[d],!0),c&&c.length&&c.children(".jstree-wholerow").addClass("jstree-wholerow-clicked")},this)).on("open_node.jstree",a.proxy(function(a,b){this.get_node(b.node,!0).find(".jstree-clicked").parent().children(".jstree-wholerow").addClass("jstree-wholerow-clicked")},this)).on("hover_node.jstree dehover_node.jstree",a.proxy(function(a,b){"hover_node"===a.type&&this.is_disabled(b.node)||this.get_node(b.node,!0).children(".jstree-wholerow")["hover_node"===a.type?"addClass":"removeClass"]("jstree-wholerow-hovered")},this)).on("contextmenu.jstree",".jstree-wholerow",a.proxy(function(b){if(this._data.contextmenu){b.preventDefault();var c=a.Event("contextmenu",{metaKey:b.metaKey,ctrlKey:b.ctrlKey,altKey:b.altKey,shiftKey:b.shiftKey,pageX:b.pageX,pageY:b.pageY});a(b.currentTarget).closest(".jstree-node").children(".jstree-anchor").first().trigger(c)}},this)).on("click.jstree",".jstree-wholerow",function(b){b.stopImmediatePropagation();var c=a.Event("click",{metaKey:b.metaKey,ctrlKey:b.ctrlKey,altKey:b.altKey,shiftKey:b.shiftKey});a(b.currentTarget).closest(".jstree-node").children(".jstree-anchor").first().trigger(c).focus()}).on("click.jstree",".jstree-leaf > .jstree-ocl",a.proxy(function(b){b.stopImmediatePropagation();var c=a.Event("click",{metaKey:b.metaKey,ctrlKey:b.ctrlKey,altKey:b.altKey,shiftKey:b.shiftKey});a(b.currentTarget).closest(".jstree-node").children(".jstree-anchor").first().trigger(c).focus()},this)).on("mouseover.jstree",".jstree-wholerow, .jstree-icon",a.proxy(function(a){return a.stopImmediatePropagation(),this.is_disabled(a.currentTarget)||this.hover_node(a.currentTarget),!1},this)).on("mouseleave.jstree",".jstree-node",a.proxy(function(a){this.dehover_node(a.currentTarget)},this))},this.teardown=function(){this.settings.wholerow&&this.element.find(".jstree-wholerow").remove(),c.teardown.call(this)},this.redraw_node=function(b,d,e,f){if(b=c.redraw_node.apply(this,arguments)){var g=q.cloneNode(!0);-1!==a.inArray(b.id,this._data.core.selected)&&(g.className+=" jstree-wholerow-clicked"),this._data.core.focused&&this._data.core.focused===b.id&&(g.className+=" jstree-wholerow-hovered"),b.insertBefore(g,b.childNodes[0])}return b}},i.registerElement&&Object&&Object.create){var r=Object.create(HTMLElement.prototype);r.createdCallback=function(){var b={core:{},plugins:[]},c;for(c in a.jstree.plugins)a.jstree.plugins.hasOwnProperty(c)&&this.attributes[c]&&(b.plugins.push(c),this.getAttribute(c)&&JSON.parse(this.getAttribute(c))&&(b[c]=JSON.parse(this.getAttribute(c))));for(c in a.jstree.defaults.core)a.jstree.defaults.core.hasOwnProperty(c)&&this.attributes[c]&&(b.core[c]=JSON.parse(this.getAttribute(c))||this.getAttribute(c));a(this).jstree(b)};try{i.registerElement("vakata-jstree",{prototype:r})}catch(s){}}}}); \ No newline at end of file
+/*! jsTree - v3.3.2 - 2016-08-15 - (MIT) */
+!function(a){"use strict";"function"==typeof define&&define.amd?define(["jquery"],a):"undefined"!=typeof module&&module.exports?module.exports=a(require("jquery")):a(jQuery)}(function(a,b){"use strict";if(!a.jstree){var c=0,d=!1,e=!1,f=!1,g=[],h=a("script:last").attr("src"),i=window.document,j=i.createElement("LI"),k,l;j.setAttribute("role","treeitem"),k=i.createElement("I"),k.className="jstree-icon jstree-ocl",k.setAttribute("role","presentation"),j.appendChild(k),k=i.createElement("A"),k.className="jstree-anchor",k.setAttribute("href","#"),k.setAttribute("tabindex","-1"),l=i.createElement("I"),l.className="jstree-icon jstree-themeicon",l.setAttribute("role","presentation"),k.appendChild(l),j.appendChild(k),k=l=null,a.jstree={version:"3.3.2",defaults:{plugins:[]},plugins:{},path:h&&-1!==h.indexOf("/")?h.replace(/\/[^\/]+$/,""):"",idregex:/[\\:&!^|()\[\]<>@*'+~#";.,=\- \/${}%?`]/g,root:"#"},a.jstree.create=function(b,d){var e=new a.jstree.core(++c),f=d;return d=a.extend(!0,{},a.jstree.defaults,d),f&&f.plugins&&(d.plugins=f.plugins),a.each(d.plugins,function(a,b){"core"!==a&&(e=e.plugin(b,d[b]))}),a(b).data("jstree",e),e.init(b,d),e},a.jstree.destroy=function(){a(".jstree:jstree").jstree("destroy"),a(i).off(".jstree")},a.jstree.core=function(a){this._id=a,this._cnt=0,this._wrk=null,this._data={core:{themes:{name:!1,dots:!1,icons:!1},selected:[],last_error:{},working:!1,worker_queue:[],focused:null}}},a.jstree.reference=function(b){var c=null,d=null;if(!b||!b.id||b.tagName&&b.nodeType||(b=b.id),!d||!d.length)try{d=a(b)}catch(e){}if(!d||!d.length)try{d=a("#"+b.replace(a.jstree.idregex,"\\$&"))}catch(e){}return d&&d.length&&(d=d.closest(".jstree")).length&&(d=d.data("jstree"))?c=d:a(".jstree").each(function(){var d=a(this).data("jstree");return d&&d._model.data[b]?(c=d,!1):void 0}),c},a.fn.jstree=function(c){var d="string"==typeof c,e=Array.prototype.slice.call(arguments,1),f=null;return c!==!0||this.length?(this.each(function(){var g=a.jstree.reference(this),h=d&&g?g[c]:null;return f=d&&h?h.apply(g,e):null,g||d||c!==b&&!a.isPlainObject(c)||a.jstree.create(this,c),(g&&!d||c===!0)&&(f=g||!1),null!==f&&f!==b?!1:void 0}),null!==f&&f!==b?f:this):!1},a.expr.pseudos.jstree=a.expr.createPseudo(function(c){return function(c){return a(c).hasClass("jstree")&&a(c).data("jstree")!==b}}),a.jstree.defaults.core={data:!1,strings:!1,check_callback:!1,error:a.noop,animation:200,multiple:!0,themes:{name:!1,url:!1,dir:!1,dots:!0,icons:!0,stripes:!1,variant:!1,responsive:!1},expand_selected_onload:!0,worker:!0,force_text:!1,dblclick_toggle:!0},a.jstree.core.prototype={plugin:function(b,c){var d=a.jstree.plugins[b];return d?(this._data[b]={},d.prototype=this,new d(c,this)):this},init:function(b,c){this._model={data:{},changed:[],force_full_redraw:!1,redraw_timeout:!1,default_state:{loaded:!0,opened:!1,selected:!1,disabled:!1}},this._model.data[a.jstree.root]={id:a.jstree.root,parent:null,parents:[],children:[],children_d:[],state:{loaded:!1}},this.element=a(b).addClass("jstree jstree-"+this._id),this.settings=c,this._data.core.ready=!1,this._data.core.loaded=!1,this._data.core.rtl="rtl"===this.element.css("direction"),this.element[this._data.core.rtl?"addClass":"removeClass"]("jstree-rtl"),this.element.attr("role","tree"),this.settings.core.multiple&&this.element.attr("aria-multiselectable",!0),this.element.attr("tabindex")||this.element.attr("tabindex","0"),this.bind(),this.trigger("init"),this._data.core.original_container_html=this.element.find(" > ul > li").clone(!0),this._data.core.original_container_html.find("li").addBack().contents().filter(function(){return 3===this.nodeType&&(!this.nodeValue||/^\s+$/.test(this.nodeValue))}).remove(),this.element.html("<ul class='jstree-container-ul jstree-children' role='group'><li id='j"+this._id+"_loading' class='jstree-initial-node jstree-loading jstree-leaf jstree-last' role='tree-item'><i class='jstree-icon jstree-ocl'></i><a class='jstree-anchor' href='#'><i class='jstree-icon jstree-themeicon-hidden'></i>"+this.get_string("Loading ...")+"</a></li></ul>"),this.element.attr("aria-activedescendant","j"+this._id+"_loading"),this._data.core.li_height=this.get_container_ul().children("li").first().height()||24,this.trigger("loading"),this.load_node(a.jstree.root)},destroy:function(a){if(this._wrk)try{window.URL.revokeObjectURL(this._wrk),this._wrk=null}catch(b){}a||this.element.empty(),this.teardown()},teardown:function(){this.unbind(),this.element.removeClass("jstree").removeData("jstree").find("[class^='jstree']").addBack().attr("class",function(){return this.className.replace(/jstree[^ ]*|$/gi,"")}),this.element=null},bind:function(){var b="",c=null,d=0;this.element.on("dblclick.jstree",function(a){if(a.target.tagName&&"input"===a.target.tagName.toLowerCase())return!0;if(i.selection&&i.selection.empty)i.selection.empty();else if(window.getSelection){var b=window.getSelection();try{b.removeAllRanges(),b.collapse()}catch(c){}}}).on("mousedown.jstree",a.proxy(function(a){a.target===this.element[0]&&(a.preventDefault(),d=+new Date)},this)).on("mousedown.jstree",".jstree-ocl",function(a){a.preventDefault()}).on("click.jstree",".jstree-ocl",a.proxy(function(a){this.toggle_node(a.target)},this)).on("dblclick.jstree",".jstree-anchor",a.proxy(function(a){return a.target.tagName&&"input"===a.target.tagName.toLowerCase()?!0:void(this.settings.core.dblclick_toggle&&this.toggle_node(a.target))},this)).on("click.jstree",".jstree-anchor",a.proxy(function(b){b.preventDefault(),b.currentTarget!==i.activeElement&&a(b.currentTarget).focus(),this.activate_node(b.currentTarget,b)},this)).on("keydown.jstree",".jstree-anchor",a.proxy(function(b){if(b.target.tagName&&"input"===b.target.tagName.toLowerCase())return!0;if(32!==b.which&&13!==b.which&&(b.shiftKey||b.ctrlKey||b.altKey||b.metaKey))return!0;var c=null;switch(this._data.core.rtl&&(37===b.which?b.which=39:39===b.which&&(b.which=37)),b.which){case 32:b.ctrlKey&&(b.type="click",a(b.currentTarget).trigger(b));break;case 13:b.type="click",a(b.currentTarget).trigger(b);break;case 37:b.preventDefault(),this.is_open(b.currentTarget)?this.close_node(b.currentTarget):(c=this.get_parent(b.currentTarget),c&&c.id!==a.jstree.root&&this.get_node(c,!0).children(".jstree-anchor").focus());break;case 38:b.preventDefault(),c=this.get_prev_dom(b.currentTarget),c&&c.length&&c.children(".jstree-anchor").focus();break;case 39:b.preventDefault(),this.is_closed(b.currentTarget)?this.open_node(b.currentTarget,function(a){this.get_node(a,!0).children(".jstree-anchor").focus()}):this.is_open(b.currentTarget)&&(c=this.get_node(b.currentTarget,!0).children(".jstree-children")[0],c&&a(this._firstChild(c)).children(".jstree-anchor").focus());break;case 40:b.preventDefault(),c=this.get_next_dom(b.currentTarget),c&&c.length&&c.children(".jstree-anchor").focus();break;case 106:this.open_all();break;case 36:b.preventDefault(),c=this._firstChild(this.get_container_ul()[0]),c&&a(c).children(".jstree-anchor").filter(":visible").focus();break;case 35:b.preventDefault(),this.element.find(".jstree-anchor").filter(":visible").last().focus();break;case 113:b.preventDefault(),this.edit(b.currentTarget)}},this)).on("load_node.jstree",a.proxy(function(b,c){c.status&&(c.node.id!==a.jstree.root||this._data.core.loaded||(this._data.core.loaded=!0,this._firstChild(this.get_container_ul()[0])&&this.element.attr("aria-activedescendant",this._firstChild(this.get_container_ul()[0]).id),this.trigger("loaded")),this._data.core.ready||setTimeout(a.proxy(function(){if(this.element&&!this.get_container_ul().find(".jstree-loading").length){if(this._data.core.ready=!0,this._data.core.selected.length){if(this.settings.core.expand_selected_onload){var b=[],c,d;for(c=0,d=this._data.core.selected.length;d>c;c++)b=b.concat(this._model.data[this._data.core.selected[c]].parents);for(b=a.vakata.array_unique(b),c=0,d=b.length;d>c;c++)this.open_node(b[c],!1,0)}this.trigger("changed",{action:"ready",selected:this._data.core.selected})}this.trigger("ready")}},this),0))},this)).on("keypress.jstree",a.proxy(function(d){if(d.target.tagName&&"input"===d.target.tagName.toLowerCase())return!0;c&&clearTimeout(c),c=setTimeout(function(){b=""},500);var e=String.fromCharCode(d.which).toLowerCase(),f=this.element.find(".jstree-anchor").filter(":visible"),g=f.index(i.activeElement)||0,h=!1;if(b+=e,b.length>1){if(f.slice(g).each(a.proxy(function(c,d){return 0===a(d).text().toLowerCase().indexOf(b)?(a(d).focus(),h=!0,!1):void 0},this)),h)return;if(f.slice(0,g).each(a.proxy(function(c,d){return 0===a(d).text().toLowerCase().indexOf(b)?(a(d).focus(),h=!0,!1):void 0},this)),h)return}if(new RegExp("^"+e.replace(/[-\/\\^$*+?.()|[\]{}]/g,"\\$&")+"+$").test(b)){if(f.slice(g+1).each(a.proxy(function(b,c){return a(c).text().toLowerCase().charAt(0)===e?(a(c).focus(),h=!0,!1):void 0},this)),h)return;if(f.slice(0,g+1).each(a.proxy(function(b,c){return a(c).text().toLowerCase().charAt(0)===e?(a(c).focus(),h=!0,!1):void 0},this)),h)return}},this)).on("init.jstree",a.proxy(function(){var a=this.settings.core.themes;this._data.core.themes.dots=a.dots,this._data.core.themes.stripes=a.stripes,this._data.core.themes.icons=a.icons,this.set_theme(a.name||"default",a.url),this.set_theme_variant(a.variant)},this)).on("loading.jstree",a.proxy(function(){this[this._data.core.themes.dots?"show_dots":"hide_dots"](),this[this._data.core.themes.icons?"show_icons":"hide_icons"](),this[this._data.core.themes.stripes?"show_stripes":"hide_stripes"]()},this)).on("blur.jstree",".jstree-anchor",a.proxy(function(b){this._data.core.focused=null,a(b.currentTarget).filter(".jstree-hovered").mouseleave(),this.element.attr("tabindex","0")},this)).on("focus.jstree",".jstree-anchor",a.proxy(function(b){var c=this.get_node(b.currentTarget);c&&c.id&&(this._data.core.focused=c.id),this.element.find(".jstree-hovered").not(b.currentTarget).mouseleave(),a(b.currentTarget).mouseenter(),this.element.attr("tabindex","-1")},this)).on("focus.jstree",a.proxy(function(){if(+new Date-d>500&&!this._data.core.focused){d=0;var a=this.get_node(this.element.attr("aria-activedescendant"),!0);a&&a.find("> .jstree-anchor").focus()}},this)).on("mouseenter.jstree",".jstree-anchor",a.proxy(function(a){this.hover_node(a.currentTarget)},this)).on("mouseleave.jstree",".jstree-anchor",a.proxy(function(a){this.dehover_node(a.currentTarget)},this))},unbind:function(){this.element.off(".jstree"),a(i).off(".jstree-"+this._id)},trigger:function(a,b){b||(b={}),b.instance=this,this.element.triggerHandler(a.replace(".jstree","")+".jstree",b)},get_container:function(){return this.element},get_container_ul:function(){return this.element.children(".jstree-children").first()},get_string:function(b){var c=this.settings.core.strings;return a.isFunction(c)?c.call(this,b):c&&c[b]?c[b]:b},_firstChild:function(a){a=a?a.firstChild:null;while(null!==a&&1!==a.nodeType)a=a.nextSibling;return a},_nextSibling:function(a){a=a?a.nextSibling:null;while(null!==a&&1!==a.nodeType)a=a.nextSibling;return a},_previousSibling:function(a){a=a?a.previousSibling:null;while(null!==a&&1!==a.nodeType)a=a.previousSibling;return a},get_node:function(b,c){b&&b.id&&(b=b.id);var d;try{if(this._model.data[b])b=this._model.data[b];else if("string"==typeof b&&this._model.data[b.replace(/^#/,"")])b=this._model.data[b.replace(/^#/,"")];else if("string"==typeof b&&(d=a("#"+b.replace(a.jstree.idregex,"\\$&"),this.element)).length&&this._model.data[d.closest(".jstree-node").attr("id")])b=this._model.data[d.closest(".jstree-node").attr("id")];else if((d=a(b,this.element)).length&&this._model.data[d.closest(".jstree-node").attr("id")])b=this._model.data[d.closest(".jstree-node").attr("id")];else{if(!(d=a(b,this.element)).length||!d.hasClass("jstree"))return!1;b=this._model.data[a.jstree.root]}return c&&(b=b.id===a.jstree.root?this.element:a("#"+b.id.replace(a.jstree.idregex,"\\$&"),this.element)),b}catch(e){return!1}},get_path:function(b,c,d){if(b=b.parents?b:this.get_node(b),!b||b.id===a.jstree.root||!b.parents)return!1;var e,f,g=[];for(g.push(d?b.id:b.text),e=0,f=b.parents.length;f>e;e++)g.push(d?b.parents[e]:this.get_text(b.parents[e]));return g=g.reverse().slice(1),c?g.join(c):g},get_next_dom:function(b,c){var d;if(b=this.get_node(b,!0),b[0]===this.element[0]){d=this._firstChild(this.get_container_ul()[0]);while(d&&0===d.offsetHeight)d=this._nextSibling(d);return d?a(d):!1}if(!b||!b.length)return!1;if(c){d=b[0];do d=this._nextSibling(d);while(d&&0===d.offsetHeight);return d?a(d):!1}if(b.hasClass("jstree-open")){d=this._firstChild(b.children(".jstree-children")[0]);while(d&&0===d.offsetHeight)d=this._nextSibling(d);if(null!==d)return a(d)}d=b[0];do d=this._nextSibling(d);while(d&&0===d.offsetHeight);return null!==d?a(d):b.parentsUntil(".jstree",".jstree-node").nextAll(".jstree-node:visible").first()},get_prev_dom:function(b,c){var d;if(b=this.get_node(b,!0),b[0]===this.element[0]){d=this.get_container_ul()[0].lastChild;while(d&&0===d.offsetHeight)d=this._previousSibling(d);return d?a(d):!1}if(!b||!b.length)return!1;if(c){d=b[0];do d=this._previousSibling(d);while(d&&0===d.offsetHeight);return d?a(d):!1}d=b[0];do d=this._previousSibling(d);while(d&&0===d.offsetHeight);if(null!==d){b=a(d);while(b.hasClass("jstree-open"))b=b.children(".jstree-children").first().children(".jstree-node:visible:last");return b}return d=b[0].parentNode.parentNode,d&&d.className&&-1!==d.className.indexOf("jstree-node")?a(d):!1},get_parent:function(b){return b=this.get_node(b),b&&b.id!==a.jstree.root?b.parent:!1},get_children_dom:function(a){return a=this.get_node(a,!0),a[0]===this.element[0]?this.get_container_ul().children(".jstree-node"):a&&a.length?a.children(".jstree-children").children(".jstree-node"):!1},is_parent:function(a){return a=this.get_node(a),a&&(a.state.loaded===!1||a.children.length>0)},is_loaded:function(a){return a=this.get_node(a),a&&a.state.loaded},is_loading:function(a){return a=this.get_node(a),a&&a.state&&a.state.loading},is_open:function(a){return a=this.get_node(a),a&&a.state.opened},is_closed:function(a){return a=this.get_node(a),a&&this.is_parent(a)&&!a.state.opened},is_leaf:function(a){return!this.is_parent(a)},load_node:function(b,c){var d,e,f,g,h;if(a.isArray(b))return this._load_nodes(b.slice(),c),!0;if(b=this.get_node(b),!b)return c&&c.call(this,b,!1),!1;if(b.state.loaded){for(b.state.loaded=!1,f=0,g=b.parents.length;g>f;f++)this._model.data[b.parents[f]].children_d=a.vakata.array_filter(this._model.data[b.parents[f]].children_d,function(c){return-1===a.inArray(c,b.children_d)});for(d=0,e=b.children_d.length;e>d;d++)this._model.data[b.children_d[d]].state.selected&&(h=!0),delete this._model.data[b.children_d[d]];h&&(this._data.core.selected=a.vakata.array_filter(this._data.core.selected,function(c){return-1===a.inArray(c,b.children_d)})),b.children=[],b.children_d=[],h&&this.trigger("changed",{action:"load_node",node:b,selected:this._data.core.selected})}return b.state.failed=!1,b.state.loading=!0,this.get_node(b,!0).addClass("jstree-loading").attr("aria-busy",!0),this._load_node(b,a.proxy(function(a){b=this._model.data[b.id],b.state.loading=!1,b.state.loaded=a,b.state.failed=!b.state.loaded;var d=this.get_node(b,!0),e=0,f=0,g=this._model.data,h=!1;for(e=0,f=b.children.length;f>e;e++)if(g[b.children[e]]&&!g[b.children[e]].state.hidden){h=!0;break}b.state.loaded&&d&&d.length&&(d.removeClass("jstree-closed jstree-open jstree-leaf"),h?"#"!==b.id&&d.addClass(b.state.opened?"jstree-open":"jstree-closed"):d.addClass("jstree-leaf")),d.removeClass("jstree-loading").attr("aria-busy",!1),this.trigger("load_node",{node:b,status:a}),c&&c.call(this,b,a)},this)),!0},_load_nodes:function(a,b,c,d){var e=!0,f=function(){this._load_nodes(a,b,!0)},g=this._model.data,h,i,j=[];for(h=0,i=a.length;i>h;h++)g[a[h]]&&(!g[a[h]].state.loaded&&!g[a[h]].state.failed||!c&&d)&&(this.is_loading(a[h])||this.load_node(a[h],f),e=!1);if(e){for(h=0,i=a.length;i>h;h++)g[a[h]]&&g[a[h]].state.loaded&&j.push(a[h]);b&&!b.done&&(b.call(this,j),b.done=!0)}},load_all:function(b,c){if(b||(b=a.jstree.root),b=this.get_node(b),!b)return!1;var d=[],e=this._model.data,f=e[b.id].children_d,g,h;for(b.state&&!b.state.loaded&&d.push(b.id),g=0,h=f.length;h>g;g++)e[f[g]]&&e[f[g]].state&&!e[f[g]].state.loaded&&d.push(f[g]);d.length?this._load_nodes(d,function(){this.load_all(b,c)}):(c&&c.call(this,b),this.trigger("load_all",{node:b}))},_load_node:function(b,c){var d=this.settings.core.data,e,f=function g(){return 3!==this.nodeType&&8!==this.nodeType};return d?a.isFunction(d)?d.call(this,b,a.proxy(function(d){d===!1?c.call(this,!1):this["string"==typeof d?"_append_html_data":"_append_json_data"](b,"string"==typeof d?a(a.parseHTML(d)).filter(f):d,function(a){c.call(this,a)})},this)):"object"==typeof d?d.url?(d=a.extend(!0,{},d),a.isFunction(d.url)&&(d.url=d.url.call(this,b)),a.isFunction(d.data)&&(d.data=d.data.call(this,b)),a.ajax(d).done(a.proxy(function(d,e,g){var h=g.getResponseHeader("Content-Type");return h&&-1!==h.indexOf("json")||"object"==typeof d?this._append_json_data(b,d,function(a){c.call(this,a)}):h&&-1!==h.indexOf("html")||"string"==typeof d?this._append_html_data(b,a(a.parseHTML(d)).filter(f),function(a){c.call(this,a)}):(this._data.core.last_error={error:"ajax",plugin:"core",id:"core_04",reason:"Could not load node",data:JSON.stringify({id:b.id,xhr:g})},this.settings.core.error.call(this,this._data.core.last_error),c.call(this,!1))},this)).fail(a.proxy(function(a){c.call(this,!1),this._data.core.last_error={error:"ajax",plugin:"core",id:"core_04",reason:"Could not load node",data:JSON.stringify({id:b.id,xhr:a})},this.settings.core.error.call(this,this._data.core.last_error)},this))):(e=a.isArray(d)||a.isPlainObject(d)?JSON.parse(JSON.stringify(d)):d,b.id===a.jstree.root?this._append_json_data(b,e,function(a){c.call(this,a)}):(this._data.core.last_error={error:"nodata",plugin:"core",id:"core_05",reason:"Could not load node",data:JSON.stringify({id:b.id})},this.settings.core.error.call(this,this._data.core.last_error),c.call(this,!1))):"string"==typeof d?b.id===a.jstree.root?this._append_html_data(b,a(a.parseHTML(d)).filter(f),function(a){c.call(this,a)}):(this._data.core.last_error={error:"nodata",plugin:"core",id:"core_06",reason:"Could not load node",data:JSON.stringify({id:b.id})},this.settings.core.error.call(this,this._data.core.last_error),c.call(this,!1)):c.call(this,!1):b.id===a.jstree.root?this._append_html_data(b,this._data.core.original_container_html.clone(!0),function(a){c.call(this,a)}):c.call(this,!1)},_node_changed:function(a){a=this.get_node(a),a&&this._model.changed.push(a.id)},_append_html_data:function(b,c,d){b=this.get_node(b),b.children=[],b.children_d=[];var e=c.is("ul")?c.children():c,f=b.id,g=[],h=[],i=this._model.data,j=i[f],k=this._data.core.selected.length,l,m,n;for(e.each(a.proxy(function(b,c){l=this._parse_model_from_html(a(c),f,j.parents.concat()),l&&(g.push(l),h.push(l),i[l].children_d.length&&(h=h.concat(i[l].children_d)))},this)),j.children=g,j.children_d=h,m=0,n=j.parents.length;n>m;m++)i[j.parents[m]].children_d=i[j.parents[m]].children_d.concat(h);this.trigger("model",{nodes:h,parent:f}),f!==a.jstree.root?(this._node_changed(f),this.redraw()):(this.get_container_ul().children(".jstree-initial-node").remove(),this.redraw(!0)),this._data.core.selected.length!==k&&this.trigger("changed",{action:"model",selected:this._data.core.selected}),d.call(this,!0)},_append_json_data:function(b,c,d,e){if(null!==this.element){b=this.get_node(b),b.children=[],b.children_d=[],c.d&&(c=c.d,"string"==typeof c&&(c=JSON.parse(c))),a.isArray(c)||(c=[c]);var f=null,g={df:this._model.default_state,dat:c,par:b.id,m:this._model.data,t_id:this._id,t_cnt:this._cnt,sel:this._data.core.selected},h=function(a,b){a.data&&(a=a.data);var c=a.dat,d=a.par,e=[],f=[],g=[],h=a.df,i=a.t_id,j=a.t_cnt,k=a.m,l=k[d],m=a.sel,n,o,p,q,r=function(a,c,d){d=d?d.concat():[],c&&d.unshift(c);var e=a.id.toString(),f,i,j,l,m={id:e,text:a.text||"",icon:a.icon!==b?a.icon:!0,parent:c,parents:d,children:a.children||[],children_d:a.children_d||[],data:a.data,state:{},li_attr:{id:!1},a_attr:{href:"#"},original:!1};for(f in h)h.hasOwnProperty(f)&&(m.state[f]=h[f]);if(a&&a.data&&a.data.jstree&&a.data.jstree.icon&&(m.icon=a.data.jstree.icon),(m.icon===b||null===m.icon||""===m.icon)&&(m.icon=!0),a&&a.data&&(m.data=a.data,a.data.jstree))for(f in a.data.jstree)a.data.jstree.hasOwnProperty(f)&&(m.state[f]=a.data.jstree[f]);if(a&&"object"==typeof a.state)for(f in a.state)a.state.hasOwnProperty(f)&&(m.state[f]=a.state[f]);if(a&&"object"==typeof a.li_attr)for(f in a.li_attr)a.li_attr.hasOwnProperty(f)&&(m.li_attr[f]=a.li_attr[f]);if(m.li_attr.id||(m.li_attr.id=e),a&&"object"==typeof a.a_attr)for(f in a.a_attr)a.a_attr.hasOwnProperty(f)&&(m.a_attr[f]=a.a_attr[f]);for(a&&a.children&&a.children===!0&&(m.state.loaded=!1,m.children=[],m.children_d=[]),k[m.id]=m,f=0,i=m.children.length;i>f;f++)j=r(k[m.children[f]],m.id,d),l=k[j],m.children_d.push(j),l.children_d.length&&(m.children_d=m.children_d.concat(l.children_d));return delete a.data,delete a.children,k[m.id].original=a,m.state.selected&&g.push(m.id),m.id},s=function(a,c,d){d=d?d.concat():[],c&&d.unshift(c);var e=!1,f,l,m,n,o;do e="j"+i+"_"+ ++j;while(k[e]);o={id:!1,text:"string"==typeof a?a:"",icon:"object"==typeof a&&a.icon!==b?a.icon:!0,parent:c,parents:d,children:[],children_d:[],data:null,state:{},li_attr:{id:!1},a_attr:{href:"#"},original:!1};for(f in h)h.hasOwnProperty(f)&&(o.state[f]=h[f]);if(a&&a.id&&(o.id=a.id.toString()),a&&a.text&&(o.text=a.text),a&&a.data&&a.data.jstree&&a.data.jstree.icon&&(o.icon=a.data.jstree.icon),(o.icon===b||null===o.icon||""===o.icon)&&(o.icon=!0),a&&a.data&&(o.data=a.data,a.data.jstree))for(f in a.data.jstree)a.data.jstree.hasOwnProperty(f)&&(o.state[f]=a.data.jstree[f]);if(a&&"object"==typeof a.state)for(f in a.state)a.state.hasOwnProperty(f)&&(o.state[f]=a.state[f]);if(a&&"object"==typeof a.li_attr)for(f in a.li_attr)a.li_attr.hasOwnProperty(f)&&(o.li_attr[f]=a.li_attr[f]);if(o.li_attr.id&&!o.id&&(o.id=o.li_attr.id.toString()),o.id||(o.id=e),o.li_attr.id||(o.li_attr.id=o.id),a&&"object"==typeof a.a_attr)for(f in a.a_attr)a.a_attr.hasOwnProperty(f)&&(o.a_attr[f]=a.a_attr[f]);if(a&&a.children&&a.children.length){for(f=0,l=a.children.length;l>f;f++)m=s(a.children[f],o.id,d),n=k[m],o.children.push(m),n.children_d.length&&(o.children_d=o.children_d.concat(n.children_d));o.children_d=o.children_d.concat(o.children)}return a&&a.children&&a.children===!0&&(o.state.loaded=!1,o.children=[],o.children_d=[]),delete a.data,delete a.children,o.original=a,k[o.id]=o,o.state.selected&&g.push(o.id),o.id};if(c.length&&c[0].id!==b&&c[0].parent!==b){for(o=0,p=c.length;p>o;o++)c[o].children||(c[o].children=[]),k[c[o].id.toString()]=c[o];for(o=0,p=c.length;p>o;o++)k[c[o].parent.toString()].children.push(c[o].id.toString()),l.children_d.push(c[o].id.toString());for(o=0,p=l.children.length;p>o;o++)n=r(k[l.children[o]],d,l.parents.concat()),f.push(n),k[n].children_d.length&&(f=f.concat(k[n].children_d));for(o=0,p=l.parents.length;p>o;o++)k[l.parents[o]].children_d=k[l.parents[o]].children_d.concat(f);q={cnt:j,mod:k,sel:m,par:d,dpc:f,add:g}}else{for(o=0,p=c.length;p>o;o++)n=s(c[o],d,l.parents.concat()),n&&(e.push(n),f.push(n),k[n].children_d.length&&(f=f.concat(k[n].children_d)));for(l.children=e,l.children_d=f,o=0,p=l.parents.length;p>o;o++)k[l.parents[o]].children_d=k[l.parents[o]].children_d.concat(f);q={cnt:j,mod:k,sel:m,par:d,dpc:f,add:g}}return"undefined"!=typeof window&&"undefined"!=typeof window.document?q:void postMessage(q)},i=function(b,c){if(null!==this.element){this._cnt=b.cnt;var e,f=this._model.data;for(e in f)f.hasOwnProperty(e)&&f[e].state&&f[e].state.loading&&b.mod[e]&&(b.mod[e].state.loading=!0);if(this._model.data=b.mod,c){var g,h=b.add,i=b.sel,j=this._data.core.selected.slice();if(f=this._model.data,i.length!==j.length||a.vakata.array_unique(i.concat(j)).length!==i.length){for(e=0,g=i.length;g>e;e++)-1===a.inArray(i[e],h)&&-1===a.inArray(i[e],j)&&(f[i[e]].state.selected=!1);for(e=0,g=j.length;g>e;e++)-1===a.inArray(j[e],i)&&(f[j[e]].state.selected=!0)}}b.add.length&&(this._data.core.selected=this._data.core.selected.concat(b.add)),this.trigger("model",{nodes:b.dpc,parent:b.par}),b.par!==a.jstree.root?(this._node_changed(b.par),this.redraw()):this.redraw(!0),b.add.length&&this.trigger("changed",{action:"model",selected:this._data.core.selected}),d.call(this,!0)}};if(this.settings.core.worker&&window.Blob&&window.URL&&window.Worker)try{null===this._wrk&&(this._wrk=window.URL.createObjectURL(new window.Blob(["self.onmessage = "+h.toString()],{type:"text/javascript"}))),!this._data.core.working||e?(this._data.core.working=!0,f=new window.Worker(this._wrk),f.onmessage=a.proxy(function(a){i.call(this,a.data,!0);try{f.terminate(),f=null}catch(b){}this._data.core.worker_queue.length?this._append_json_data.apply(this,this._data.core.worker_queue.shift()):this._data.core.working=!1},this),g.par?f.postMessage(g):this._data.core.worker_queue.length?this._append_json_data.apply(this,this._data.core.worker_queue.shift()):this._data.core.working=!1):this._data.core.worker_queue.push([b,c,d,!0])}catch(j){i.call(this,h(g),!1),this._data.core.worker_queue.length?this._append_json_data.apply(this,this._data.core.worker_queue.shift()):this._data.core.working=!1}else i.call(this,h(g),!1)}},_parse_model_from_html:function(c,d,e){e=e?[].concat(e):[],d&&e.unshift(d);var f,g,h=this._model.data,i={id:!1,text:!1,icon:!0,parent:d,parents:e,children:[],children_d:[],data:null,state:{},li_attr:{id:!1},a_attr:{href:"#"},original:!1},j,k,l;for(j in this._model.default_state)this._model.default_state.hasOwnProperty(j)&&(i.state[j]=this._model.default_state[j]);if(k=a.vakata.attributes(c,!0),a.each(k,function(b,c){return c=a.trim(c),c.length?(i.li_attr[b]=c,void("id"===b&&(i.id=c.toString()))):!0}),k=c.children("a").first(),k.length&&(k=a.vakata.attributes(k,!0),a.each(k,function(b,c){c=a.trim(c),c.length&&(i.a_attr[b]=c)})),k=c.children("a").first().length?c.children("a").first().clone():c.clone(),k.children("ins, i, ul").remove(),k=k.html(),k=a("<div />").html(k),i.text=this.settings.core.force_text?k.text():k.html(),k=c.data(),i.data=k?a.extend(!0,{},k):null,i.state.opened=c.hasClass("jstree-open"),i.state.selected=c.children("a").hasClass("jstree-clicked"),i.state.disabled=c.children("a").hasClass("jstree-disabled"),i.data&&i.data.jstree)for(j in i.data.jstree)i.data.jstree.hasOwnProperty(j)&&(i.state[j]=i.data.jstree[j]);k=c.children("a").children(".jstree-themeicon"),k.length&&(i.icon=k.hasClass("jstree-themeicon-hidden")?!1:k.attr("rel")),i.state.icon!==b&&(i.icon=i.state.icon),(i.icon===b||null===i.icon||""===i.icon)&&(i.icon=!0),k=c.children("ul").children("li");do l="j"+this._id+"_"+ ++this._cnt;while(h[l]);return i.id=i.li_attr.id?i.li_attr.id.toString():l,k.length?(k.each(a.proxy(function(b,c){f=this._parse_model_from_html(a(c),i.id,e),g=this._model.data[f],i.children.push(f),g.children_d.length&&(i.children_d=i.children_d.concat(g.children_d))},this)),i.children_d=i.children_d.concat(i.children)):c.hasClass("jstree-closed")&&(i.state.loaded=!1),i.li_attr["class"]&&(i.li_attr["class"]=i.li_attr["class"].replace("jstree-closed","").replace("jstree-open","")),i.a_attr["class"]&&(i.a_attr["class"]=i.a_attr["class"].replace("jstree-clicked","").replace("jstree-disabled","")),h[i.id]=i,i.state.selected&&this._data.core.selected.push(i.id),i.id},_parse_model_from_flat_json:function(a,c,d){d=d?d.concat():[],c&&d.unshift(c);var e=a.id.toString(),f=this._model.data,g=this._model.default_state,h,i,j,k,l={id:e,text:a.text||"",icon:a.icon!==b?a.icon:!0,parent:c,parents:d,children:a.children||[],children_d:a.children_d||[],data:a.data,state:{},li_attr:{id:!1},a_attr:{href:"#"},original:!1};for(h in g)g.hasOwnProperty(h)&&(l.state[h]=g[h]);if(a&&a.data&&a.data.jstree&&a.data.jstree.icon&&(l.icon=a.data.jstree.icon),(l.icon===b||null===l.icon||""===l.icon)&&(l.icon=!0),a&&a.data&&(l.data=a.data,a.data.jstree))for(h in a.data.jstree)a.data.jstree.hasOwnProperty(h)&&(l.state[h]=a.data.jstree[h]);if(a&&"object"==typeof a.state)for(h in a.state)a.state.hasOwnProperty(h)&&(l.state[h]=a.state[h]);if(a&&"object"==typeof a.li_attr)for(h in a.li_attr)a.li_attr.hasOwnProperty(h)&&(l.li_attr[h]=a.li_attr[h]);if(l.li_attr.id||(l.li_attr.id=e),a&&"object"==typeof a.a_attr)for(h in a.a_attr)a.a_attr.hasOwnProperty(h)&&(l.a_attr[h]=a.a_attr[h]);for(a&&a.children&&a.children===!0&&(l.state.loaded=!1,l.children=[],l.children_d=[]),f[l.id]=l,h=0,i=l.children.length;i>h;h++)j=this._parse_model_from_flat_json(f[l.children[h]],l.id,d),k=f[j],l.children_d.push(j),k.children_d.length&&(l.children_d=l.children_d.concat(k.children_d));return delete a.data,delete a.children,f[l.id].original=a,l.state.selected&&this._data.core.selected.push(l.id),l.id},_parse_model_from_json:function(a,c,d){d=d?d.concat():[],c&&d.unshift(c);var e=!1,f,g,h,i,j=this._model.data,k=this._model.default_state,l;do e="j"+this._id+"_"+ ++this._cnt;while(j[e]);l={id:!1,text:"string"==typeof a?a:"",icon:"object"==typeof a&&a.icon!==b?a.icon:!0,parent:c,parents:d,children:[],children_d:[],data:null,state:{},li_attr:{id:!1},a_attr:{href:"#"},original:!1};for(f in k)k.hasOwnProperty(f)&&(l.state[f]=k[f]);if(a&&a.id&&(l.id=a.id.toString()),a&&a.text&&(l.text=a.text),a&&a.data&&a.data.jstree&&a.data.jstree.icon&&(l.icon=a.data.jstree.icon),(l.icon===b||null===l.icon||""===l.icon)&&(l.icon=!0),a&&a.data&&(l.data=a.data,a.data.jstree))for(f in a.data.jstree)a.data.jstree.hasOwnProperty(f)&&(l.state[f]=a.data.jstree[f]);if(a&&"object"==typeof a.state)for(f in a.state)a.state.hasOwnProperty(f)&&(l.state[f]=a.state[f]);if(a&&"object"==typeof a.li_attr)for(f in a.li_attr)a.li_attr.hasOwnProperty(f)&&(l.li_attr[f]=a.li_attr[f]);if(l.li_attr.id&&!l.id&&(l.id=l.li_attr.id.toString()),l.id||(l.id=e),l.li_attr.id||(l.li_attr.id=l.id),a&&"object"==typeof a.a_attr)for(f in a.a_attr)a.a_attr.hasOwnProperty(f)&&(l.a_attr[f]=a.a_attr[f]);if(a&&a.children&&a.children.length){for(f=0,g=a.children.length;g>f;f++)h=this._parse_model_from_json(a.children[f],l.id,d),i=j[h],l.children.push(h),i.children_d.length&&(l.children_d=l.children_d.concat(i.children_d));l.children_d=l.children_d.concat(l.children)}return a&&a.children&&a.children===!0&&(l.state.loaded=!1,l.children=[],l.children_d=[]),delete a.data,delete a.children,l.original=a,j[l.id]=l,l.state.selected&&this._data.core.selected.push(l.id),l.id},_redraw:function(){var b=this._model.force_full_redraw?this._model.data[a.jstree.root].children.concat([]):this._model.changed.concat([]),c=i.createElement("UL"),d,e,f,g=this._data.core.focused;for(e=0,f=b.length;f>e;e++)d=this.redraw_node(b[e],!0,this._model.force_full_redraw),d&&this._model.force_full_redraw&&c.appendChild(d);this._model.force_full_redraw&&(c.className=this.get_container_ul()[0].className,c.setAttribute("role","group"),this.element.empty().append(c)),null!==g&&(d=this.get_node(g,!0),d&&d.length&&d.children(".jstree-anchor")[0]!==i.activeElement?d.children(".jstree-anchor").focus():this._data.core.focused=null),this._model.force_full_redraw=!1,this._model.changed=[],this.trigger("redraw",{nodes:b})},redraw:function(a){a&&(this._model.force_full_redraw=!0),this._redraw()},draw_children:function(b){var c=this.get_node(b),d=!1,e=!1,f=!1,g=i;if(!c)return!1;if(c.id===a.jstree.root)return this.redraw(!0);if(b=this.get_node(b,!0),!b||!b.length)return!1;if(b.children(".jstree-children").remove(),b=b[0],c.children.length&&c.state.loaded){for(f=g.createElement("UL"),f.setAttribute("role","group"),f.className="jstree-children",d=0,e=c.children.length;e>d;d++)f.appendChild(this.redraw_node(c.children[d],!0,!0));b.appendChild(f)}},redraw_node:function(b,c,d,e){var f=this.get_node(b),g=!1,h=!1,k=!1,l=!1,m=!1,n=!1,o="",p=i,q=this._model.data,r=!1,s=!1,t=null,u=0,v=0,w=!1,x=!1;if(!f)return!1;if(f.id===a.jstree.root)return this.redraw(!0);if(c=c||0===f.children.length,b=i.querySelector?this.element[0].querySelector("#"+(-1!=="0123456789".indexOf(f.id[0])?"\\3"+f.id[0]+" "+f.id.substr(1).replace(a.jstree.idregex,"\\$&"):f.id.replace(a.jstree.idregex,"\\$&"))):i.getElementById(f.id))b=a(b),
+d||(g=b.parent().parent()[0],g===this.element[0]&&(g=null),h=b.index()),c||!f.children.length||b.children(".jstree-children").length||(c=!0),c||(k=b.children(".jstree-children")[0]),r=b.children(".jstree-anchor")[0]===i.activeElement,b.remove();else if(c=!0,!d){if(g=f.parent!==a.jstree.root?a("#"+f.parent.replace(a.jstree.idregex,"\\$&"),this.element)[0]:null,!(null===g||g&&q[f.parent].state.opened))return!1;h=a.inArray(f.id,null===g?q[a.jstree.root].children:q[f.parent].children)}b=j.cloneNode(!0),o="jstree-node ";for(l in f.li_attr)if(f.li_attr.hasOwnProperty(l)){if("id"===l)continue;"class"!==l?b.setAttribute(l,f.li_attr[l]):o+=f.li_attr[l]}for(f.a_attr.id||(f.a_attr.id=f.id+"_anchor"),b.setAttribute("aria-selected",!!f.state.selected),b.setAttribute("aria-level",f.parents.length),b.setAttribute("aria-labelledby",f.a_attr.id),f.state.disabled&&b.setAttribute("aria-disabled",!0),l=0,m=f.children.length;m>l;l++)if(!q[f.children[l]].state.hidden){w=!0;break}if(null!==f.parent&&q[f.parent]&&!f.state.hidden&&(l=a.inArray(f.id,q[f.parent].children),x=f.id,-1!==l))for(l++,m=q[f.parent].children.length;m>l;l++)if(q[q[f.parent].children[l]].state.hidden||(x=q[f.parent].children[l]),x!==f.id)break;f.state.hidden&&(o+=" jstree-hidden"),f.state.loaded&&!w?o+=" jstree-leaf":(o+=f.state.opened&&f.state.loaded?" jstree-open":" jstree-closed",b.setAttribute("aria-expanded",f.state.opened&&f.state.loaded)),x===f.id&&(o+=" jstree-last"),b.id=f.id,b.className=o,o=(f.state.selected?" jstree-clicked":"")+(f.state.disabled?" jstree-disabled":"");for(m in f.a_attr)if(f.a_attr.hasOwnProperty(m)){if("href"===m&&"#"===f.a_attr[m])continue;"class"!==m?b.childNodes[1].setAttribute(m,f.a_attr[m]):o+=" "+f.a_attr[m]}if(o.length&&(b.childNodes[1].className="jstree-anchor "+o),(f.icon&&f.icon!==!0||f.icon===!1)&&(f.icon===!1?b.childNodes[1].childNodes[0].className+=" jstree-themeicon-hidden":-1===f.icon.indexOf("/")&&-1===f.icon.indexOf(".")?b.childNodes[1].childNodes[0].className+=" "+f.icon+" jstree-themeicon-custom":(b.childNodes[1].childNodes[0].style.backgroundImage='url("'+f.icon+'")',b.childNodes[1].childNodes[0].style.backgroundPosition="center center",b.childNodes[1].childNodes[0].style.backgroundSize="auto",b.childNodes[1].childNodes[0].className+=" jstree-themeicon-custom")),this.settings.core.force_text?b.childNodes[1].appendChild(p.createTextNode(f.text)):b.childNodes[1].innerHTML+=f.text,c&&f.children.length&&(f.state.opened||e)&&f.state.loaded){for(n=p.createElement("UL"),n.setAttribute("role","group"),n.className="jstree-children",l=0,m=f.children.length;m>l;l++)n.appendChild(this.redraw_node(f.children[l],c,!0));b.appendChild(n)}if(k&&b.appendChild(k),!d){for(g||(g=this.element[0]),l=0,m=g.childNodes.length;m>l;l++)if(g.childNodes[l]&&g.childNodes[l].className&&-1!==g.childNodes[l].className.indexOf("jstree-children")){t=g.childNodes[l];break}t||(t=p.createElement("UL"),t.setAttribute("role","group"),t.className="jstree-children",g.appendChild(t)),g=t,h<g.childNodes.length?g.insertBefore(b,g.childNodes[h]):g.appendChild(b),r&&(u=this.element[0].scrollTop,v=this.element[0].scrollLeft,b.childNodes[1].focus(),this.element[0].scrollTop=u,this.element[0].scrollLeft=v)}return f.state.opened&&!f.state.loaded&&(f.state.opened=!1,setTimeout(a.proxy(function(){this.open_node(f.id,!1,0)},this),0)),b},open_node:function(c,d,e){var f,g,h,i;if(a.isArray(c)){for(c=c.slice(),f=0,g=c.length;g>f;f++)this.open_node(c[f],d,e);return!0}return c=this.get_node(c),c&&c.id!==a.jstree.root?(e=e===b?this.settings.core.animation:e,this.is_closed(c)?this.is_loaded(c)?(h=this.get_node(c,!0),i=this,h.length&&(e&&h.children(".jstree-children").length&&h.children(".jstree-children").stop(!0,!0),c.children.length&&!this._firstChild(h.children(".jstree-children")[0])&&this.draw_children(c),e?(this.trigger("before_open",{node:c}),h.children(".jstree-children").css("display","none").end().removeClass("jstree-closed").addClass("jstree-open").attr("aria-expanded",!0).children(".jstree-children").stop(!0,!0).slideDown(e,function(){this.style.display="",i.element&&i.trigger("after_open",{node:c})})):(this.trigger("before_open",{node:c}),h[0].className=h[0].className.replace("jstree-closed","jstree-open"),h[0].setAttribute("aria-expanded",!0))),c.state.opened=!0,d&&d.call(this,c,!0),h.length||this.trigger("before_open",{node:c}),this.trigger("open_node",{node:c}),e&&h.length||this.trigger("after_open",{node:c}),!0):this.is_loading(c)?setTimeout(a.proxy(function(){this.open_node(c,d,e)},this),500):void this.load_node(c,function(a,b){return b?this.open_node(a,d,e):d?d.call(this,a,!1):!1}):(d&&d.call(this,c,!1),!1)):!1},_open_to:function(b){if(b=this.get_node(b),!b||b.id===a.jstree.root)return!1;var c,d,e=b.parents;for(c=0,d=e.length;d>c;c+=1)c!==a.jstree.root&&this.open_node(e[c],!1,0);return a("#"+b.id.replace(a.jstree.idregex,"\\$&"),this.element)},close_node:function(c,d){var e,f,g,h;if(a.isArray(c)){for(c=c.slice(),e=0,f=c.length;f>e;e++)this.close_node(c[e],d);return!0}return c=this.get_node(c),c&&c.id!==a.jstree.root?this.is_closed(c)?!1:(d=d===b?this.settings.core.animation:d,g=this,h=this.get_node(c,!0),c.state.opened=!1,this.trigger("close_node",{node:c}),void(h.length?d?h.children(".jstree-children").attr("style","display:block !important").end().removeClass("jstree-open").addClass("jstree-closed").attr("aria-expanded",!1).children(".jstree-children").stop(!0,!0).slideUp(d,function(){this.style.display="",h.children(".jstree-children").remove(),g.element&&g.trigger("after_close",{node:c})}):(h[0].className=h[0].className.replace("jstree-open","jstree-closed"),h.attr("aria-expanded",!1).children(".jstree-children").remove(),this.trigger("after_close",{node:c})):this.trigger("after_close",{node:c}))):!1},toggle_node:function(b){var c,d;if(a.isArray(b)){for(b=b.slice(),c=0,d=b.length;d>c;c++)this.toggle_node(b[c]);return!0}return this.is_closed(b)?this.open_node(b):this.is_open(b)?this.close_node(b):void 0},open_all:function(b,c,d){if(b||(b=a.jstree.root),b=this.get_node(b),!b)return!1;var e=b.id===a.jstree.root?this.get_container_ul():this.get_node(b,!0),f,g,h;if(!e.length){for(f=0,g=b.children_d.length;g>f;f++)this.is_closed(this._model.data[b.children_d[f]])&&(this._model.data[b.children_d[f]].state.opened=!0);return this.trigger("open_all",{node:b})}d=d||e,h=this,e=this.is_closed(b)?e.find(".jstree-closed").addBack():e.find(".jstree-closed"),e.each(function(){h.open_node(this,function(a,b){b&&this.is_parent(a)&&this.open_all(a,c,d)},c||0)}),0===d.find(".jstree-closed").length&&this.trigger("open_all",{node:this.get_node(d)})},close_all:function(b,c){if(b||(b=a.jstree.root),b=this.get_node(b),!b)return!1;var d=b.id===a.jstree.root?this.get_container_ul():this.get_node(b,!0),e=this,f,g;for(d.length&&(d=this.is_open(b)?d.find(".jstree-open").addBack():d.find(".jstree-open"),a(d.get().reverse()).each(function(){e.close_node(this,c||0)})),f=0,g=b.children_d.length;g>f;f++)this._model.data[b.children_d[f]].state.opened=!1;this.trigger("close_all",{node:b})},is_disabled:function(a){return a=this.get_node(a),a&&a.state&&a.state.disabled},enable_node:function(b){var c,d;if(a.isArray(b)){for(b=b.slice(),c=0,d=b.length;d>c;c++)this.enable_node(b[c]);return!0}return b=this.get_node(b),b&&b.id!==a.jstree.root?(b.state.disabled=!1,this.get_node(b,!0).children(".jstree-anchor").removeClass("jstree-disabled").attr("aria-disabled",!1),void this.trigger("enable_node",{node:b})):!1},disable_node:function(b){var c,d;if(a.isArray(b)){for(b=b.slice(),c=0,d=b.length;d>c;c++)this.disable_node(b[c]);return!0}return b=this.get_node(b),b&&b.id!==a.jstree.root?(b.state.disabled=!0,this.get_node(b,!0).children(".jstree-anchor").addClass("jstree-disabled").attr("aria-disabled",!0),void this.trigger("disable_node",{node:b})):!1},is_hidden:function(a){return a=this.get_node(a),a.state.hidden===!0},hide_node:function(b,c){var d,e;if(a.isArray(b)){for(b=b.slice(),d=0,e=b.length;e>d;d++)this.hide_node(b[d],!0);return c||this.redraw(),!0}return b=this.get_node(b),b&&b.id!==a.jstree.root?void(b.state.hidden||(b.state.hidden=!0,this._node_changed(b.parent),c||this.redraw(),this.trigger("hide_node",{node:b}))):!1},show_node:function(b,c){var d,e;if(a.isArray(b)){for(b=b.slice(),d=0,e=b.length;e>d;d++)this.show_node(b[d],!0);return c||this.redraw(),!0}return b=this.get_node(b),b&&b.id!==a.jstree.root?void(b.state.hidden&&(b.state.hidden=!1,this._node_changed(b.parent),c||this.redraw(),this.trigger("show_node",{node:b}))):!1},hide_all:function(b){var c,d=this._model.data,e=[];for(c in d)d.hasOwnProperty(c)&&c!==a.jstree.root&&!d[c].state.hidden&&(d[c].state.hidden=!0,e.push(c));return this._model.force_full_redraw=!0,b||this.redraw(),this.trigger("hide_all",{nodes:e}),e},show_all:function(b){var c,d=this._model.data,e=[];for(c in d)d.hasOwnProperty(c)&&c!==a.jstree.root&&d[c].state.hidden&&(d[c].state.hidden=!1,e.push(c));return this._model.force_full_redraw=!0,b||this.redraw(),this.trigger("show_all",{nodes:e}),e},activate_node:function(a,c){if(this.is_disabled(a))return!1;if(c&&"object"==typeof c||(c={}),this._data.core.last_clicked=this._data.core.last_clicked&&this._data.core.last_clicked.id!==b?this.get_node(this._data.core.last_clicked.id):null,this._data.core.last_clicked&&!this._data.core.last_clicked.state.selected&&(this._data.core.last_clicked=null),!this._data.core.last_clicked&&this._data.core.selected.length&&(this._data.core.last_clicked=this.get_node(this._data.core.selected[this._data.core.selected.length-1])),this.settings.core.multiple&&(c.metaKey||c.ctrlKey||c.shiftKey)&&(!c.shiftKey||this._data.core.last_clicked&&this.get_parent(a)&&this.get_parent(a)===this._data.core.last_clicked.parent))if(c.shiftKey){var d=this.get_node(a).id,e=this._data.core.last_clicked.id,f=this.get_node(this._data.core.last_clicked.parent).children,g=!1,h,i;for(h=0,i=f.length;i>h;h+=1)f[h]===d&&(g=!g),f[h]===e&&(g=!g),this.is_disabled(f[h])||!g&&f[h]!==d&&f[h]!==e?this.deselect_node(f[h],!0,c):this.is_hidden(f[h])||this.select_node(f[h],!0,!1,c);this.trigger("changed",{action:"select_node",node:this.get_node(a),selected:this._data.core.selected,event:c})}else this.is_selected(a)?this.deselect_node(a,!1,c):this.select_node(a,!1,!1,c);else!this.settings.core.multiple&&(c.metaKey||c.ctrlKey||c.shiftKey)&&this.is_selected(a)?this.deselect_node(a,!1,c):(this.deselect_all(!0),this.select_node(a,!1,!1,c),this._data.core.last_clicked=this.get_node(a));this.trigger("activate_node",{node:this.get_node(a),event:c})},hover_node:function(a){if(a=this.get_node(a,!0),!a||!a.length||a.children(".jstree-hovered").length)return!1;var b=this.element.find(".jstree-hovered"),c=this.element;b&&b.length&&this.dehover_node(b),a.children(".jstree-anchor").addClass("jstree-hovered"),this.trigger("hover_node",{node:this.get_node(a)}),setTimeout(function(){c.attr("aria-activedescendant",a[0].id)},0)},dehover_node:function(a){return a=this.get_node(a,!0),a&&a.length&&a.children(".jstree-hovered").length?(a.children(".jstree-anchor").removeClass("jstree-hovered"),void this.trigger("dehover_node",{node:this.get_node(a)})):!1},select_node:function(b,c,d,e){var f,g,h,i;if(a.isArray(b)){for(b=b.slice(),g=0,h=b.length;h>g;g++)this.select_node(b[g],c,d,e);return!0}return b=this.get_node(b),b&&b.id!==a.jstree.root?(f=this.get_node(b,!0),void(b.state.selected||(b.state.selected=!0,this._data.core.selected.push(b.id),d||(f=this._open_to(b)),f&&f.length&&f.attr("aria-selected",!0).children(".jstree-anchor").addClass("jstree-clicked"),this.trigger("select_node",{node:b,selected:this._data.core.selected,event:e}),c||this.trigger("changed",{action:"select_node",node:b,selected:this._data.core.selected,event:e})))):!1},deselect_node:function(b,c,d){var e,f,g;if(a.isArray(b)){for(b=b.slice(),e=0,f=b.length;f>e;e++)this.deselect_node(b[e],c,d);return!0}return b=this.get_node(b),b&&b.id!==a.jstree.root?(g=this.get_node(b,!0),void(b.state.selected&&(b.state.selected=!1,this._data.core.selected=a.vakata.array_remove_item(this._data.core.selected,b.id),g.length&&g.attr("aria-selected",!1).children(".jstree-anchor").removeClass("jstree-clicked"),this.trigger("deselect_node",{node:b,selected:this._data.core.selected,event:d}),c||this.trigger("changed",{action:"deselect_node",node:b,selected:this._data.core.selected,event:d})))):!1},select_all:function(b){var c=this._data.core.selected.concat([]),d,e;for(this._data.core.selected=this._model.data[a.jstree.root].children_d.concat(),d=0,e=this._data.core.selected.length;e>d;d++)this._model.data[this._data.core.selected[d]]&&(this._model.data[this._data.core.selected[d]].state.selected=!0);this.redraw(!0),this.trigger("select_all",{selected:this._data.core.selected}),b||this.trigger("changed",{action:"select_all",selected:this._data.core.selected,old_selection:c})},deselect_all:function(a){var b=this._data.core.selected.concat([]),c,d;for(c=0,d=this._data.core.selected.length;d>c;c++)this._model.data[this._data.core.selected[c]]&&(this._model.data[this._data.core.selected[c]].state.selected=!1);this._data.core.selected=[],this.element.find(".jstree-clicked").removeClass("jstree-clicked").parent().attr("aria-selected",!1),this.trigger("deselect_all",{selected:this._data.core.selected,node:b}),a||this.trigger("changed",{action:"deselect_all",selected:this._data.core.selected,old_selection:b})},is_selected:function(b){return b=this.get_node(b),b&&b.id!==a.jstree.root?b.state.selected:!1},get_selected:function(b){return b?a.map(this._data.core.selected,a.proxy(function(a){return this.get_node(a)},this)):this._data.core.selected.slice()},get_top_selected:function(b){var c=this.get_selected(!0),d={},e,f,g,h;for(e=0,f=c.length;f>e;e++)d[c[e].id]=c[e];for(e=0,f=c.length;f>e;e++)for(g=0,h=c[e].children_d.length;h>g;g++)d[c[e].children_d[g]]&&delete d[c[e].children_d[g]];c=[];for(e in d)d.hasOwnProperty(e)&&c.push(e);return b?a.map(c,a.proxy(function(a){return this.get_node(a)},this)):c},get_bottom_selected:function(b){var c=this.get_selected(!0),d=[],e,f;for(e=0,f=c.length;f>e;e++)c[e].children.length||d.push(c[e].id);return b?a.map(d,a.proxy(function(a){return this.get_node(a)},this)):d},get_state:function(){var b={core:{open:[],scroll:{left:this.element.scrollLeft(),top:this.element.scrollTop()},selected:[]}},c;for(c in this._model.data)this._model.data.hasOwnProperty(c)&&c!==a.jstree.root&&(this._model.data[c].state.opened&&b.core.open.push(c),this._model.data[c].state.selected&&b.core.selected.push(c));return b},set_state:function(c,d){if(c){if(c.core){var e,f,g,h,i;if(c.core.open)return a.isArray(c.core.open)&&c.core.open.length?this._load_nodes(c.core.open,function(a){this.open_node(a,!1,0),delete c.core.open,this.set_state(c,d)}):(delete c.core.open,this.set_state(c,d)),!1;if(c.core.scroll)return c.core.scroll&&c.core.scroll.left!==b&&this.element.scrollLeft(c.core.scroll.left),c.core.scroll&&c.core.scroll.top!==b&&this.element.scrollTop(c.core.scroll.top),delete c.core.scroll,this.set_state(c,d),!1;if(c.core.selected)return h=this,this.deselect_all(),a.each(c.core.selected,function(a,b){h.select_node(b,!1,!0)}),delete c.core.selected,this.set_state(c,d),!1;for(i in c)c.hasOwnProperty(i)&&"core"!==i&&-1===a.inArray(i,this.settings.plugins)&&delete c[i];if(a.isEmptyObject(c.core))return delete c.core,this.set_state(c,d),!1}return a.isEmptyObject(c)?(c=null,d&&d.call(this),this.trigger("set_state"),!1):!0}return!1},refresh:function(b,c){this._data.core.state=c===!0?{}:this.get_state(),c&&a.isFunction(c)&&(this._data.core.state=c.call(this,this._data.core.state)),this._cnt=0,this._model.data={},this._model.data[a.jstree.root]={id:a.jstree.root,parent:null,parents:[],children:[],children_d:[],state:{loaded:!1}},this._data.core.selected=[],this._data.core.last_clicked=null,this._data.core.focused=null;var d=this.get_container_ul()[0].className;b||(this.element.html("<ul class='"+d+"' role='group'><li class='jstree-initial-node jstree-loading jstree-leaf jstree-last' role='treeitem' id='j"+this._id+"_loading'><i class='jstree-icon jstree-ocl'></i><a class='jstree-anchor' href='#'><i class='jstree-icon jstree-themeicon-hidden'></i>"+this.get_string("Loading ...")+"</a></li></ul>"),this.element.attr("aria-activedescendant","j"+this._id+"_loading")),this.load_node(a.jstree.root,function(b,c){c&&(this.get_container_ul()[0].className=d,this._firstChild(this.get_container_ul()[0])&&this.element.attr("aria-activedescendant",this._firstChild(this.get_container_ul()[0]).id),this.set_state(a.extend(!0,{},this._data.core.state),function(){this.trigger("refresh")})),this._data.core.state=null})},refresh_node:function(b){if(b=this.get_node(b),!b||b.id===a.jstree.root)return!1;var c=[],d=[],e=this._data.core.selected.concat([]);d.push(b.id),b.state.opened===!0&&c.push(b.id),this.get_node(b,!0).find(".jstree-open").each(function(){d.push(this.id),c.push(this.id)}),this._load_nodes(d,a.proxy(function(a){this.open_node(c,!1,0),this.select_node(e),this.trigger("refresh_node",{node:b,nodes:a})},this),!1,!0)},set_id:function(b,c){if(b=this.get_node(b),!b||b.id===a.jstree.root)return!1;var d,e,f=this._model.data,g=b.id;for(c=c.toString(),f[b.parent].children[a.inArray(b.id,f[b.parent].children)]=c,d=0,e=b.parents.length;e>d;d++)f[b.parents[d]].children_d[a.inArray(b.id,f[b.parents[d]].children_d)]=c;for(d=0,e=b.children.length;e>d;d++)f[b.children[d]].parent=c;for(d=0,e=b.children_d.length;e>d;d++)f[b.children_d[d]].parents[a.inArray(b.id,f[b.children_d[d]].parents)]=c;return d=a.inArray(b.id,this._data.core.selected),-1!==d&&(this._data.core.selected[d]=c),d=this.get_node(b.id,!0),d&&(d.attr("id",c),this.element.attr("aria-activedescendant")===b.id&&this.element.attr("aria-activedescendant",c)),delete f[b.id],b.id=c,b.li_attr.id=c,f[c]=b,this.trigger("set_id",{node:b,"new":b.id,old:g}),!0},get_text:function(b){return b=this.get_node(b),b&&b.id!==a.jstree.root?b.text:!1},set_text:function(b,c){var d,e;if(a.isArray(b)){for(b=b.slice(),d=0,e=b.length;e>d;d++)this.set_text(b[d],c);return!0}return b=this.get_node(b),b&&b.id!==a.jstree.root?(b.text=c,this.get_node(b,!0).length&&this.redraw_node(b.id),this.trigger("set_text",{obj:b,text:c}),!0):!1},get_json:function(b,c,d){if(b=this.get_node(b||a.jstree.root),!b)return!1;c&&c.flat&&!d&&(d=[]);var e={id:b.id,text:b.text,icon:this.get_icon(b),li_attr:a.extend(!0,{},b.li_attr),a_attr:a.extend(!0,{},b.a_attr),state:{},data:c&&c.no_data?!1:a.extend(!0,{},b.data)},f,g;if(c&&c.flat?e.parent=b.parent:e.children=[],c&&c.no_state)delete e.state;else for(f in b.state)b.state.hasOwnProperty(f)&&(e.state[f]=b.state[f]);if(c&&c.no_li_attr&&delete e.li_attr,c&&c.no_a_attr&&delete e.a_attr,c&&c.no_id&&(delete e.id,e.li_attr&&e.li_attr.id&&delete e.li_attr.id,e.a_attr&&e.a_attr.id&&delete e.a_attr.id),c&&c.flat&&b.id!==a.jstree.root&&d.push(e),!c||!c.no_children)for(f=0,g=b.children.length;g>f;f++)c&&c.flat?this.get_json(b.children[f],c,d):e.children.push(this.get_json(b.children[f],c));return c&&c.flat?d:b.id===a.jstree.root?e.children:e},create_node:function(c,d,e,f,g){if(null===c&&(c=a.jstree.root),c=this.get_node(c),!c)return!1;if(e=e===b?"last":e,!e.toString().match(/^(before|after)$/)&&!g&&!this.is_loaded(c))return this.load_node(c,function(){this.create_node(c,d,e,f,!0)});d||(d={text:this.get_string("New node")}),"string"==typeof d&&(d={text:d}),d.text===b&&(d.text=this.get_string("New node"));var h,i,j,k;switch(c.id===a.jstree.root&&("before"===e&&(e="first"),"after"===e&&(e="last")),e){case"before":h=this.get_node(c.parent),e=a.inArray(c.id,h.children),c=h;break;case"after":h=this.get_node(c.parent),e=a.inArray(c.id,h.children)+1,c=h;break;case"inside":case"first":e=0;break;case"last":e=c.children.length;break;default:e||(e=0)}if(e>c.children.length&&(e=c.children.length),d.id||(d.id=!0),!this.check("create_node",d,c,e))return this.settings.core.error.call(this,this._data.core.last_error),!1;if(d.id===!0&&delete d.id,d=this._parse_model_from_json(d,c.id,c.parents.concat()),!d)return!1;for(h=this.get_node(d),i=[],i.push(d),i=i.concat(h.children_d),this.trigger("model",{nodes:i,parent:c.id}),c.children_d=c.children_d.concat(i),j=0,k=c.parents.length;k>j;j++)this._model.data[c.parents[j]].children_d=this._model.data[c.parents[j]].children_d.concat(i);for(d=h,h=[],j=0,k=c.children.length;k>j;j++)h[j>=e?j+1:j]=c.children[j];return h[e]=d.id,c.children=h,this.redraw_node(c,!0),f&&f.call(this,this.get_node(d)),this.trigger("create_node",{node:this.get_node(d),parent:c.id,position:e}),d.id},rename_node:function(b,c){var d,e,f;if(a.isArray(b)){for(b=b.slice(),d=0,e=b.length;e>d;d++)this.rename_node(b[d],c);return!0}return b=this.get_node(b),b&&b.id!==a.jstree.root?(f=b.text,this.check("rename_node",b,this.get_parent(b),c)?(this.set_text(b,c),this.trigger("rename_node",{node:b,text:c,old:f}),!0):(this.settings.core.error.call(this,this._data.core.last_error),!1)):!1},delete_node:function(b){var c,d,e,f,g,h,i,j,k,l,m,n;if(a.isArray(b)){for(b=b.slice(),c=0,d=b.length;d>c;c++)this.delete_node(b[c]);return!0}if(b=this.get_node(b),!b||b.id===a.jstree.root)return!1;if(e=this.get_node(b.parent),f=a.inArray(b.id,e.children),l=!1,!this.check("delete_node",b,e,f))return this.settings.core.error.call(this,this._data.core.last_error),!1;for(-1!==f&&(e.children=a.vakata.array_remove(e.children,f)),g=b.children_d.concat([]),g.push(b.id),h=0,i=b.parents.length;i>h;h++)this._model.data[b.parents[h]].children_d=a.vakata.array_filter(this._model.data[b.parents[h]].children_d,function(b){return-1===a.inArray(b,g)});for(j=0,k=g.length;k>j;j++)if(this._model.data[g[j]].state.selected){l=!0;break}for(l&&(this._data.core.selected=a.vakata.array_filter(this._data.core.selected,function(b){return-1===a.inArray(b,g)})),this.trigger("delete_node",{node:b,parent:e.id}),l&&this.trigger("changed",{action:"delete_node",node:b,selected:this._data.core.selected,parent:e.id}),j=0,k=g.length;k>j;j++)delete this._model.data[g[j]];return-1!==a.inArray(this._data.core.focused,g)&&(this._data.core.focused=null,m=this.element[0].scrollTop,n=this.element[0].scrollLeft,e.id===a.jstree.root?this._model.data[a.jstree.root].children[0]&&this.get_node(this._model.data[a.jstree.root].children[0],!0).children(".jstree-anchor").focus():this.get_node(e,!0).children(".jstree-anchor").focus(),this.element[0].scrollTop=m,this.element[0].scrollLeft=n),this.redraw_node(e,!0),!0},check:function(b,c,d,e,f){c=c&&c.id?c:this.get_node(c),d=d&&d.id?d:this.get_node(d);var g=b.match(/^move_node|copy_node|create_node$/i)?d:c,h=this.settings.core.check_callback;return"move_node"!==b&&"copy_node"!==b||f&&f.is_multi||c.id!==d.id&&("move_node"!==b||a.inArray(c.id,d.children)!==e)&&-1===a.inArray(d.id,c.children_d)?(g&&g.data&&(g=g.data),g&&g.functions&&(g.functions[b]===!1||g.functions[b]===!0)?(g.functions[b]===!1&&(this._data.core.last_error={error:"check",plugin:"core",id:"core_02",reason:"Node data prevents function: "+b,data:JSON.stringify({chk:b,pos:e,obj:c&&c.id?c.id:!1,par:d&&d.id?d.id:!1})}),g.functions[b]):h===!1||a.isFunction(h)&&h.call(this,b,c,d,e,f)===!1||h&&h[b]===!1?(this._data.core.last_error={error:"check",plugin:"core",id:"core_03",reason:"User config for core.check_callback prevents function: "+b,data:JSON.stringify({chk:b,pos:e,obj:c&&c.id?c.id:!1,par:d&&d.id?d.id:!1})},!1):!0):(this._data.core.last_error={error:"check",plugin:"core",id:"core_01",reason:"Moving parent inside child",data:JSON.stringify({chk:b,pos:e,obj:c&&c.id?c.id:!1,par:d&&d.id?d.id:!1})},!1)},last_error:function(){return this._data.core.last_error},move_node:function(c,d,e,f,g,h,i){var j,k,l,m,n,o,p,q,r,s,t,u,v,w;if(d=this.get_node(d),e=e===b?0:e,!d)return!1;if(!e.toString().match(/^(before|after)$/)&&!g&&!this.is_loaded(d))return this.load_node(d,function(){this.move_node(c,d,e,f,!0,!1,i)});if(a.isArray(c)){if(1!==c.length){for(j=0,k=c.length;k>j;j++)(r=this.move_node(c[j],d,e,f,g,!1,i))&&(d=r,e="after");return this.redraw(),!0}c=c[0]}if(c=c&&c.id?c:this.get_node(c),!c||c.id===a.jstree.root)return!1;if(l=(c.parent||a.jstree.root).toString(),n=e.toString().match(/^(before|after)$/)&&d.id!==a.jstree.root?this.get_node(d.parent):d,o=i?i:this._model.data[c.id]?this:a.jstree.reference(c.id),p=!o||!o._id||this._id!==o._id,m=o&&o._id&&l&&o._model.data[l]&&o._model.data[l].children?a.inArray(c.id,o._model.data[l].children):-1,o&&o._id&&(c=o._model.data[c.id]),p)return(r=this.copy_node(c,d,e,f,g,!1,i))?(o&&o.delete_node(c),r):!1;switch(d.id===a.jstree.root&&("before"===e&&(e="first"),"after"===e&&(e="last")),e){case"before":e=a.inArray(d.id,n.children);break;case"after":e=a.inArray(d.id,n.children)+1;break;case"inside":case"first":e=0;break;case"last":e=n.children.length;break;default:e||(e=0)}if(e>n.children.length&&(e=n.children.length),!this.check("move_node",c,n,e,{core:!0,origin:i,is_multi:o&&o._id&&o._id!==this._id,is_foreign:!o||!o._id}))return this.settings.core.error.call(this,this._data.core.last_error),!1;if(c.parent===n.id){for(q=n.children.concat(),r=a.inArray(c.id,q),-1!==r&&(q=a.vakata.array_remove(q,r),e>r&&e--),r=[],s=0,t=q.length;t>s;s++)r[s>=e?s+1:s]=q[s];r[e]=c.id,n.children=r,this._node_changed(n.id),this.redraw(n.id===a.jstree.root)}else{for(r=c.children_d.concat(),r.push(c.id),s=0,t=c.parents.length;t>s;s++){for(q=[],w=o._model.data[c.parents[s]].children_d,u=0,v=w.length;v>u;u++)-1===a.inArray(w[u],r)&&q.push(w[u]);o._model.data[c.parents[s]].children_d=q}for(o._model.data[l].children=a.vakata.array_remove_item(o._model.data[l].children,c.id),s=0,t=n.parents.length;t>s;s++)this._model.data[n.parents[s]].children_d=this._model.data[n.parents[s]].children_d.concat(r);for(q=[],s=0,t=n.children.length;t>s;s++)q[s>=e?s+1:s]=n.children[s];for(q[e]=c.id,n.children=q,n.children_d.push(c.id),n.children_d=n.children_d.concat(c.children_d),c.parent=n.id,r=n.parents.concat(),r.unshift(n.id),w=c.parents.length,c.parents=r,r=r.concat(),s=0,t=c.children_d.length;t>s;s++)this._model.data[c.children_d[s]].parents=this._model.data[c.children_d[s]].parents.slice(0,-1*w),Array.prototype.push.apply(this._model.data[c.children_d[s]].parents,r);(l===a.jstree.root||n.id===a.jstree.root)&&(this._model.force_full_redraw=!0),this._model.force_full_redraw||(this._node_changed(l),this._node_changed(n.id)),h||this.redraw()}return f&&f.call(this,c,n,e),this.trigger("move_node",{node:c,parent:n.id,position:e,old_parent:l,old_position:m,is_multi:o&&o._id&&o._id!==this._id,is_foreign:!o||!o._id,old_instance:o,new_instance:this}),c.id},copy_node:function(c,d,e,f,g,h,i){var j,k,l,m,n,o,p,q,r,s,t;if(d=this.get_node(d),e=e===b?0:e,!d)return!1;if(!e.toString().match(/^(before|after)$/)&&!g&&!this.is_loaded(d))return this.load_node(d,function(){this.copy_node(c,d,e,f,!0,!1,i)});if(a.isArray(c)){if(1!==c.length){for(j=0,k=c.length;k>j;j++)(m=this.copy_node(c[j],d,e,f,g,!0,i))&&(d=m,e="after");return this.redraw(),!0}c=c[0]}if(c=c&&c.id?c:this.get_node(c),!c||c.id===a.jstree.root)return!1;switch(q=(c.parent||a.jstree.root).toString(),r=e.toString().match(/^(before|after)$/)&&d.id!==a.jstree.root?this.get_node(d.parent):d,s=i?i:this._model.data[c.id]?this:a.jstree.reference(c.id),t=!s||!s._id||this._id!==s._id,s&&s._id&&(c=s._model.data[c.id]),d.id===a.jstree.root&&("before"===e&&(e="first"),"after"===e&&(e="last")),e){case"before":e=a.inArray(d.id,r.children);break;case"after":e=a.inArray(d.id,r.children)+1;break;case"inside":case"first":e=0;break;case"last":e=r.children.length;break;default:e||(e=0)}if(e>r.children.length&&(e=r.children.length),!this.check("copy_node",c,r,e,{core:!0,origin:i,is_multi:s&&s._id&&s._id!==this._id,is_foreign:!s||!s._id}))return this.settings.core.error.call(this,this._data.core.last_error),!1;if(p=s?s.get_json(c,{no_id:!0,no_data:!0,no_state:!0}):c,!p)return!1;if(p.id===!0&&delete p.id,p=this._parse_model_from_json(p,r.id,r.parents.concat()),!p)return!1;for(m=this.get_node(p),c&&c.state&&c.state.loaded===!1&&(m.state.loaded=!1),l=[],l.push(p),l=l.concat(m.children_d),this.trigger("model",{nodes:l,parent:r.id}),n=0,o=r.parents.length;o>n;n++)this._model.data[r.parents[n]].children_d=this._model.data[r.parents[n]].children_d.concat(l);for(l=[],n=0,o=r.children.length;o>n;n++)l[n>=e?n+1:n]=r.children[n];return l[e]=m.id,r.children=l,r.children_d.push(m.id),r.children_d=r.children_d.concat(m.children_d),r.id===a.jstree.root&&(this._model.force_full_redraw=!0),this._model.force_full_redraw||this._node_changed(r.id),h||this.redraw(r.id===a.jstree.root),f&&f.call(this,m,r,e),this.trigger("copy_node",{node:m,original:c,parent:r.id,position:e,old_parent:q,old_position:s&&s._id&&q&&s._model.data[q]&&s._model.data[q].children?a.inArray(c.id,s._model.data[q].children):-1,is_multi:s&&s._id&&s._id!==this._id,is_foreign:!s||!s._id,old_instance:s,new_instance:this}),m.id},cut:function(b){if(b||(b=this._data.core.selected.concat()),a.isArray(b)||(b=[b]),!b.length)return!1;var c=[],g,h,i;for(h=0,i=b.length;i>h;h++)g=this.get_node(b[h]),g&&g.id&&g.id!==a.jstree.root&&c.push(g);return c.length?(d=c,f=this,e="move_node",void this.trigger("cut",{node:b})):!1},copy:function(b){if(b||(b=this._data.core.selected.concat()),a.isArray(b)||(b=[b]),!b.length)return!1;var c=[],g,h,i;for(h=0,i=b.length;i>h;h++)g=this.get_node(b[h]),g&&g.id&&g.id!==a.jstree.root&&c.push(g);return c.length?(d=c,f=this,e="copy_node",void this.trigger("copy",{node:b})):!1},get_buffer:function(){return{mode:e,node:d,inst:f}},can_paste:function(){return e!==!1&&d!==!1},paste:function(a,b){return a=this.get_node(a),a&&e&&e.match(/^(copy_node|move_node)$/)&&d?(this[e](d,a,b,!1,!1,!1,f)&&this.trigger("paste",{parent:a.id,node:d,mode:e}),d=!1,e=!1,void(f=!1)):!1},clear_buffer:function(){d=!1,e=!1,f=!1,this.trigger("clear_buffer")},edit:function(b,c,d){var e,f,g,h,j,k,l,m,n,o=!1;return(b=this.get_node(b))?this.settings.core.check_callback===!1?(this._data.core.last_error={error:"check",plugin:"core",id:"core_07",reason:"Could not edit node because of check_callback"},this.settings.core.error.call(this,this._data.core.last_error),!1):(n=b,c="string"==typeof c?c:b.text,this.set_text(b,""),b=this._open_to(b),n.text=c,e=this._data.core.rtl,f=this.element.width(),this._data.core.focused=n.id,g=b.children(".jstree-anchor").focus(),h=a("<span>"),j=c,k=a("<div />",{css:{position:"absolute",top:"-200px",left:e?"0px":"-1000px",visibility:"hidden"}}).appendTo("body"),l=a("<input />",{value:j,"class":"jstree-rename-input",css:{padding:"0",border:"1px solid silver","box-sizing":"border-box",display:"inline-block",height:this._data.core.li_height+"px",lineHeight:this._data.core.li_height+"px",width:"150px"},blur:a.proxy(function(c){c.stopImmediatePropagation(),c.preventDefault();var e=h.children(".jstree-rename-input"),f=e.val(),i=this.settings.core.force_text,m;""===f&&(f=j),k.remove(),h.replaceWith(g),h.remove(),j=i?j:a("<div></div>").append(a.parseHTML(j)).html(),this.set_text(b,j),m=!!this.rename_node(b,i?a("<div></div>").text(f).text():a("<div></div>").append(a.parseHTML(f)).html()),m||this.set_text(b,j),this._data.core.focused=n.id,setTimeout(a.proxy(function(){var a=this.get_node(n.id,!0);a.length&&(this._data.core.focused=n.id,a.children(".jstree-anchor").focus())},this),0),d&&d.call(this,n,m,o),l=null},this),keydown:function(a){var b=a.which;27===b&&(o=!0,this.value=j),(27===b||13===b||37===b||38===b||39===b||40===b||32===b)&&a.stopImmediatePropagation(),(27===b||13===b)&&(a.preventDefault(),this.blur())},click:function(a){a.stopImmediatePropagation()},mousedown:function(a){a.stopImmediatePropagation()},keyup:function(a){l.width(Math.min(k.text("pW"+this.value).width(),f))},keypress:function(a){return 13===a.which?!1:void 0}}),m={fontFamily:g.css("fontFamily")||"",fontSize:g.css("fontSize")||"",fontWeight:g.css("fontWeight")||"",fontStyle:g.css("fontStyle")||"",fontStretch:g.css("fontStretch")||"",fontVariant:g.css("fontVariant")||"",letterSpacing:g.css("letterSpacing")||"",wordSpacing:g.css("wordSpacing")||""},h.attr("class",g.attr("class")).append(g.contents().clone()).append(l),g.replaceWith(h),k.css(m),l.css(m).width(Math.min(k.text("pW"+l[0].value).width(),f))[0].select(),
+void a(i).one("mousedown.jstree touchstart.jstree dnd_start.vakata",function(b){l&&b.target!==l&&a(l).blur()})):!1},set_theme:function(b,c){if(!b)return!1;if(c===!0){var d=this.settings.core.themes.dir;d||(d=a.jstree.path+"/themes"),c=d+"/"+b+"/style.css"}c&&-1===a.inArray(c,g)&&(a("head").append('<link rel="stylesheet" href="'+c+'" type="text/css" />'),g.push(c)),this._data.core.themes.name&&this.element.removeClass("jstree-"+this._data.core.themes.name),this._data.core.themes.name=b,this.element.addClass("jstree-"+b),this.element[this.settings.core.themes.responsive?"addClass":"removeClass"]("jstree-"+b+"-responsive"),this.trigger("set_theme",{theme:b})},get_theme:function(){return this._data.core.themes.name},set_theme_variant:function(a){this._data.core.themes.variant&&this.element.removeClass("jstree-"+this._data.core.themes.name+"-"+this._data.core.themes.variant),this._data.core.themes.variant=a,a&&this.element.addClass("jstree-"+this._data.core.themes.name+"-"+this._data.core.themes.variant)},get_theme_variant:function(){return this._data.core.themes.variant},show_stripes:function(){this._data.core.themes.stripes=!0,this.get_container_ul().addClass("jstree-striped")},hide_stripes:function(){this._data.core.themes.stripes=!1,this.get_container_ul().removeClass("jstree-striped")},toggle_stripes:function(){this._data.core.themes.stripes?this.hide_stripes():this.show_stripes()},show_dots:function(){this._data.core.themes.dots=!0,this.get_container_ul().removeClass("jstree-no-dots")},hide_dots:function(){this._data.core.themes.dots=!1,this.get_container_ul().addClass("jstree-no-dots")},toggle_dots:function(){this._data.core.themes.dots?this.hide_dots():this.show_dots()},show_icons:function(){this._data.core.themes.icons=!0,this.get_container_ul().removeClass("jstree-no-icons")},hide_icons:function(){this._data.core.themes.icons=!1,this.get_container_ul().addClass("jstree-no-icons")},toggle_icons:function(){this._data.core.themes.icons?this.hide_icons():this.show_icons()},set_icon:function(c,d){var e,f,g,h;if(a.isArray(c)){for(c=c.slice(),e=0,f=c.length;f>e;e++)this.set_icon(c[e],d);return!0}return c=this.get_node(c),c&&c.id!==a.jstree.root?(h=c.icon,c.icon=d===!0||null===d||d===b||""===d?!0:d,g=this.get_node(c,!0).children(".jstree-anchor").children(".jstree-themeicon"),d===!1?this.hide_icon(c):d===!0||null===d||d===b||""===d?(g.removeClass("jstree-themeicon-custom "+h).css("background","").removeAttr("rel"),h===!1&&this.show_icon(c)):-1===d.indexOf("/")&&-1===d.indexOf(".")?(g.removeClass(h).css("background",""),g.addClass(d+" jstree-themeicon-custom").attr("rel",d),h===!1&&this.show_icon(c)):(g.removeClass(h).css("background",""),g.addClass("jstree-themeicon-custom").css("background","url('"+d+"') center center no-repeat").attr("rel",d),h===!1&&this.show_icon(c)),!0):!1},get_icon:function(b){return b=this.get_node(b),b&&b.id!==a.jstree.root?b.icon:!1},hide_icon:function(b){var c,d;if(a.isArray(b)){for(b=b.slice(),c=0,d=b.length;d>c;c++)this.hide_icon(b[c]);return!0}return b=this.get_node(b),b&&b!==a.jstree.root?(b.icon=!1,this.get_node(b,!0).children(".jstree-anchor").children(".jstree-themeicon").addClass("jstree-themeicon-hidden"),!0):!1},show_icon:function(b){var c,d,e;if(a.isArray(b)){for(b=b.slice(),c=0,d=b.length;d>c;c++)this.show_icon(b[c]);return!0}return b=this.get_node(b),b&&b!==a.jstree.root?(e=this.get_node(b,!0),b.icon=e.length?e.children(".jstree-anchor").children(".jstree-themeicon").attr("rel"):!0,b.icon||(b.icon=!0),e.children(".jstree-anchor").children(".jstree-themeicon").removeClass("jstree-themeicon-hidden"),!0):!1}},a.vakata={},a.vakata.attributes=function(b,c){b=a(b)[0];var d=c?{}:[];return b&&b.attributes&&a.each(b.attributes,function(b,e){-1===a.inArray(e.name.toLowerCase(),["style","contenteditable","hasfocus","tabindex"])&&null!==e.value&&""!==a.trim(e.value)&&(c?d[e.name]=e.value:d.push(e.name))}),d},a.vakata.array_unique=function(a){var c=[],d,e,f,g={};for(d=0,f=a.length;f>d;d++)g[a[d]]===b&&(c.push(a[d]),g[a[d]]=!0);return c},a.vakata.array_remove=function(a,b){return a.splice(b,1),a},a.vakata.array_remove_item=function(b,c){var d=a.inArray(c,b);return-1!==d?a.vakata.array_remove(b,d):b},a.vakata.array_filter=function(a,b,c,d,e){if(a.filter)return a.filter(b,c);d=[];for(e in a)~~e+""==e+""&&e>=0&&b.call(c,a[e],+e,a)&&d.push(a[e]);return d},a.jstree.plugins.changed=function(a,b){var c=[];this.trigger=function(a,d){var e,f;if(d||(d={}),"changed"===a.replace(".jstree","")){d.changed={selected:[],deselected:[]};var g={};for(e=0,f=c.length;f>e;e++)g[c[e]]=1;for(e=0,f=d.selected.length;f>e;e++)g[d.selected[e]]?g[d.selected[e]]=2:d.changed.selected.push(d.selected[e]);for(e=0,f=c.length;f>e;e++)1===g[c[e]]&&d.changed.deselected.push(c[e]);c=d.selected.slice()}b.trigger.call(this,a,d)},this.refresh=function(a,d){return c=[],b.refresh.apply(this,arguments)}};var m=i.createElement("I");m.className="jstree-icon jstree-checkbox",m.setAttribute("role","presentation"),a.jstree.defaults.checkbox={visible:!0,three_state:!0,whole_node:!0,keep_selected_style:!0,cascade:"",tie_selection:!0},a.jstree.plugins.checkbox=function(c,d){this.bind=function(){d.bind.call(this),this._data.checkbox.uto=!1,this._data.checkbox.selected=[],this.settings.checkbox.three_state&&(this.settings.checkbox.cascade="up+down+undetermined"),this.element.on("init.jstree",a.proxy(function(){this._data.checkbox.visible=this.settings.checkbox.visible,this.settings.checkbox.keep_selected_style||this.element.addClass("jstree-checkbox-no-clicked"),this.settings.checkbox.tie_selection&&this.element.addClass("jstree-checkbox-selection")},this)).on("loading.jstree",a.proxy(function(){this[this._data.checkbox.visible?"show_checkboxes":"hide_checkboxes"]()},this)),-1!==this.settings.checkbox.cascade.indexOf("undetermined")&&this.element.on("changed.jstree uncheck_node.jstree check_node.jstree uncheck_all.jstree check_all.jstree move_node.jstree copy_node.jstree redraw.jstree open_node.jstree",a.proxy(function(){this._data.checkbox.uto&&clearTimeout(this._data.checkbox.uto),this._data.checkbox.uto=setTimeout(a.proxy(this._undetermined,this),50)},this)),this.settings.checkbox.tie_selection||this.element.on("model.jstree",a.proxy(function(a,b){var c=this._model.data,d=c[b.parent],e=b.nodes,f,g;for(f=0,g=e.length;g>f;f++)c[e[f]].state.checked=c[e[f]].state.checked||c[e[f]].original&&c[e[f]].original.state&&c[e[f]].original.state.checked,c[e[f]].state.checked&&this._data.checkbox.selected.push(e[f])},this)),(-1!==this.settings.checkbox.cascade.indexOf("up")||-1!==this.settings.checkbox.cascade.indexOf("down"))&&this.element.on("model.jstree",a.proxy(function(b,c){var d=this._model.data,e=d[c.parent],f=c.nodes,g=[],h,i,j,k,l,m,n=this.settings.checkbox.cascade,o=this.settings.checkbox.tie_selection;if(-1!==n.indexOf("down"))if(e.state[o?"selected":"checked"]){for(i=0,j=f.length;j>i;i++)d[f[i]].state[o?"selected":"checked"]=!0;this._data[o?"core":"checkbox"].selected=this._data[o?"core":"checkbox"].selected.concat(f)}else for(i=0,j=f.length;j>i;i++)if(d[f[i]].state[o?"selected":"checked"]){for(k=0,l=d[f[i]].children_d.length;l>k;k++)d[d[f[i]].children_d[k]].state[o?"selected":"checked"]=!0;this._data[o?"core":"checkbox"].selected=this._data[o?"core":"checkbox"].selected.concat(d[f[i]].children_d)}if(-1!==n.indexOf("up")){for(i=0,j=e.children_d.length;j>i;i++)d[e.children_d[i]].children.length||g.push(d[e.children_d[i]].parent);for(g=a.vakata.array_unique(g),k=0,l=g.length;l>k;k++){e=d[g[k]];while(e&&e.id!==a.jstree.root){for(h=0,i=0,j=e.children.length;j>i;i++)h+=d[e.children[i]].state[o?"selected":"checked"];if(h!==j)break;e.state[o?"selected":"checked"]=!0,this._data[o?"core":"checkbox"].selected.push(e.id),m=this.get_node(e,!0),m&&m.length&&m.attr("aria-selected",!0).children(".jstree-anchor").addClass(o?"jstree-clicked":"jstree-checked"),e=this.get_node(e.parent)}}}this._data[o?"core":"checkbox"].selected=a.vakata.array_unique(this._data[o?"core":"checkbox"].selected)},this)).on(this.settings.checkbox.tie_selection?"select_node.jstree":"check_node.jstree",a.proxy(function(b,c){var d=c.node,e=this._model.data,f=this.get_node(d.parent),g=this.get_node(d,!0),h,i,j,k,l=this.settings.checkbox.cascade,m=this.settings.checkbox.tie_selection,n={},o=this._data[m?"core":"checkbox"].selected;for(h=0,i=o.length;i>h;h++)n[o[h]]=!0;if(-1!==l.indexOf("down"))for(h=0,i=d.children_d.length;i>h;h++)n[d.children_d[h]]=!0,k=e[d.children_d[h]],k.state[m?"selected":"checked"]=!0,k&&k.original&&k.original.state&&k.original.state.undetermined&&(k.original.state.undetermined=!1);if(-1!==l.indexOf("up"))while(f&&f.id!==a.jstree.root){for(j=0,h=0,i=f.children.length;i>h;h++)j+=e[f.children[h]].state[m?"selected":"checked"];if(j!==i)break;f.state[m?"selected":"checked"]=!0,n[f.id]=!0,k=this.get_node(f,!0),k&&k.length&&k.attr("aria-selected",!0).children(".jstree-anchor").addClass(m?"jstree-clicked":"jstree-checked"),f=this.get_node(f.parent)}o=[];for(h in n)n.hasOwnProperty(h)&&o.push(h);this._data[m?"core":"checkbox"].selected=o,-1!==l.indexOf("down")&&g.length&&g.find(".jstree-anchor").addClass(m?"jstree-clicked":"jstree-checked").parent().attr("aria-selected",!0)},this)).on(this.settings.checkbox.tie_selection?"deselect_all.jstree":"uncheck_all.jstree",a.proxy(function(b,c){var d=this.get_node(a.jstree.root),e=this._model.data,f,g,h;for(f=0,g=d.children_d.length;g>f;f++)h=e[d.children_d[f]],h&&h.original&&h.original.state&&h.original.state.undetermined&&(h.original.state.undetermined=!1)},this)).on(this.settings.checkbox.tie_selection?"deselect_node.jstree":"uncheck_node.jstree",a.proxy(function(b,c){var d=c.node,e=this.get_node(d,!0),f,g,h,i=this.settings.checkbox.cascade,j=this.settings.checkbox.tie_selection,k=this._data[j?"core":"checkbox"].selected,l={};if(d&&d.original&&d.original.state&&d.original.state.undetermined&&(d.original.state.undetermined=!1),-1!==i.indexOf("down"))for(f=0,g=d.children_d.length;g>f;f++)h=this._model.data[d.children_d[f]],h.state[j?"selected":"checked"]=!1,h&&h.original&&h.original.state&&h.original.state.undetermined&&(h.original.state.undetermined=!1);if(-1!==i.indexOf("up"))for(f=0,g=d.parents.length;g>f;f++)h=this._model.data[d.parents[f]],h.state[j?"selected":"checked"]=!1,h&&h.original&&h.original.state&&h.original.state.undetermined&&(h.original.state.undetermined=!1),h=this.get_node(d.parents[f],!0),h&&h.length&&h.attr("aria-selected",!1).children(".jstree-anchor").removeClass(j?"jstree-clicked":"jstree-checked");for(l={},f=0,g=k.length;g>f;f++)-1!==i.indexOf("down")&&-1!==a.inArray(k[f],d.children_d)||-1!==i.indexOf("up")&&-1!==a.inArray(k[f],d.parents)||(l[k[f]]=!0);k=[];for(f in l)l.hasOwnProperty(f)&&k.push(f);this._data[j?"core":"checkbox"].selected=k,-1!==i.indexOf("down")&&e.length&&e.find(".jstree-anchor").removeClass(j?"jstree-clicked":"jstree-checked").parent().attr("aria-selected",!1)},this)),-1!==this.settings.checkbox.cascade.indexOf("up")&&this.element.on("delete_node.jstree",a.proxy(function(b,c){var d=this.get_node(c.parent),e=this._model.data,f,g,h,i,j=this.settings.checkbox.tie_selection;while(d&&d.id!==a.jstree.root&&!d.state[j?"selected":"checked"]){for(h=0,f=0,g=d.children.length;g>f;f++)h+=e[d.children[f]].state[j?"selected":"checked"];if(!(g>0&&h===g))break;d.state[j?"selected":"checked"]=!0,this._data[j?"core":"checkbox"].selected.push(d.id),i=this.get_node(d,!0),i&&i.length&&i.attr("aria-selected",!0).children(".jstree-anchor").addClass(j?"jstree-clicked":"jstree-checked"),d=this.get_node(d.parent)}},this)).on("move_node.jstree",a.proxy(function(b,c){var d=c.is_multi,e=c.old_parent,f=this.get_node(c.parent),g=this._model.data,h,i,j,k,l,m=this.settings.checkbox.tie_selection;if(!d){h=this.get_node(e);while(h&&h.id!==a.jstree.root&&!h.state[m?"selected":"checked"]){for(i=0,j=0,k=h.children.length;k>j;j++)i+=g[h.children[j]].state[m?"selected":"checked"];if(!(k>0&&i===k))break;h.state[m?"selected":"checked"]=!0,this._data[m?"core":"checkbox"].selected.push(h.id),l=this.get_node(h,!0),l&&l.length&&l.attr("aria-selected",!0).children(".jstree-anchor").addClass(m?"jstree-clicked":"jstree-checked"),h=this.get_node(h.parent)}}h=f;while(h&&h.id!==a.jstree.root){for(i=0,j=0,k=h.children.length;k>j;j++)i+=g[h.children[j]].state[m?"selected":"checked"];if(i===k)h.state[m?"selected":"checked"]||(h.state[m?"selected":"checked"]=!0,this._data[m?"core":"checkbox"].selected.push(h.id),l=this.get_node(h,!0),l&&l.length&&l.attr("aria-selected",!0).children(".jstree-anchor").addClass(m?"jstree-clicked":"jstree-checked"));else{if(!h.state[m?"selected":"checked"])break;h.state[m?"selected":"checked"]=!1,this._data[m?"core":"checkbox"].selected=a.vakata.array_remove_item(this._data[m?"core":"checkbox"].selected,h.id),l=this.get_node(h,!0),l&&l.length&&l.attr("aria-selected",!1).children(".jstree-anchor").removeClass(m?"jstree-clicked":"jstree-checked")}h=this.get_node(h.parent)}},this))},this._undetermined=function(){if(null!==this.element){var c,d,e,f,g={},h=this._model.data,i=this.settings.checkbox.tie_selection,j=this._data[i?"core":"checkbox"].selected,k=[],l=this;for(c=0,d=j.length;d>c;c++)if(h[j[c]]&&h[j[c]].parents)for(e=0,f=h[j[c]].parents.length;f>e;e++){if(g[h[j[c]].parents[e]]!==b)break;h[j[c]].parents[e]!==a.jstree.root&&(g[h[j[c]].parents[e]]=!0,k.push(h[j[c]].parents[e]))}for(this.element.find(".jstree-closed").not(":has(.jstree-children)").each(function(){var i=l.get_node(this),j;if(i.state.loaded){for(c=0,d=i.children_d.length;d>c;c++)if(j=h[i.children_d[c]],!j.state.loaded&&j.original&&j.original.state&&j.original.state.undetermined&&j.original.state.undetermined===!0)for(g[j.id]===b&&j.id!==a.jstree.root&&(g[j.id]=!0,k.push(j.id)),e=0,f=j.parents.length;f>e;e++)g[j.parents[e]]===b&&j.parents[e]!==a.jstree.root&&(g[j.parents[e]]=!0,k.push(j.parents[e]))}else if(i.original&&i.original.state&&i.original.state.undetermined&&i.original.state.undetermined===!0)for(g[i.id]===b&&i.id!==a.jstree.root&&(g[i.id]=!0,k.push(i.id)),e=0,f=i.parents.length;f>e;e++)g[i.parents[e]]===b&&i.parents[e]!==a.jstree.root&&(g[i.parents[e]]=!0,k.push(i.parents[e]))}),this.element.find(".jstree-undetermined").removeClass("jstree-undetermined"),c=0,d=k.length;d>c;c++)h[k[c]].state[i?"selected":"checked"]||(j=this.get_node(k[c],!0),j&&j.length&&j.children(".jstree-anchor").children(".jstree-checkbox").addClass("jstree-undetermined"))}},this.redraw_node=function(b,c,e,f){if(b=d.redraw_node.apply(this,arguments)){var g,h,i=null,j=null;for(g=0,h=b.childNodes.length;h>g;g++)if(b.childNodes[g]&&b.childNodes[g].className&&-1!==b.childNodes[g].className.indexOf("jstree-anchor")){i=b.childNodes[g];break}i&&(!this.settings.checkbox.tie_selection&&this._model.data[b.id].state.checked&&(i.className+=" jstree-checked"),j=m.cloneNode(!1),this._model.data[b.id].state.checkbox_disabled&&(j.className+=" jstree-checkbox-disabled"),i.insertBefore(j,i.childNodes[0]))}return e||-1===this.settings.checkbox.cascade.indexOf("undetermined")||(this._data.checkbox.uto&&clearTimeout(this._data.checkbox.uto),this._data.checkbox.uto=setTimeout(a.proxy(this._undetermined,this),50)),b},this.show_checkboxes=function(){this._data.core.themes.checkboxes=!0,this.get_container_ul().removeClass("jstree-no-checkboxes")},this.hide_checkboxes=function(){this._data.core.themes.checkboxes=!1,this.get_container_ul().addClass("jstree-no-checkboxes")},this.toggle_checkboxes=function(){this._data.core.themes.checkboxes?this.hide_checkboxes():this.show_checkboxes()},this.is_undetermined=function(b){b=this.get_node(b);var c=this.settings.checkbox.cascade,d,e,f=this.settings.checkbox.tie_selection,g=this._data[f?"core":"checkbox"].selected,h=this._model.data;if(!b||b.state[f?"selected":"checked"]===!0||-1===c.indexOf("undetermined")||-1===c.indexOf("down")&&-1===c.indexOf("up"))return!1;if(!b.state.loaded&&b.original.state.undetermined===!0)return!0;for(d=0,e=b.children_d.length;e>d;d++)if(-1!==a.inArray(b.children_d[d],g)||!h[b.children_d[d]].state.loaded&&h[b.children_d[d]].original.state.undetermined)return!0;return!1},this.disable_checkbox=function(b){var c,d,e;if(a.isArray(b)){for(b=b.slice(),c=0,d=b.length;d>c;c++)this.disable_checkbox(b[c]);return!0}return b=this.get_node(b),b&&b.id!==a.jstree.root?(e=this.get_node(b,!0),void(b.state.checkbox_disabled||(b.state.checkbox_disabled=!0,e&&e.length&&e.children(".jstree-anchor").children(".jstree-checkbox").addClass("jstree-checkbox-disabled"),this.trigger("disable_checkbox",{node:b})))):!1},this.enable_checkbox=function(b){var c,d,e;if(a.isArray(b)){for(b=b.slice(),c=0,d=b.length;d>c;c++)this.enable_checkbox(b[c]);return!0}return b=this.get_node(b),b&&b.id!==a.jstree.root?(e=this.get_node(b,!0),void(b.state.checkbox_disabled&&(b.state.checkbox_disabled=!1,e&&e.length&&e.children(".jstree-anchor").children(".jstree-checkbox").removeClass("jstree-checkbox-disabled"),this.trigger("enable_checkbox",{node:b})))):!1},this.activate_node=function(b,c){return a(c.target).hasClass("jstree-checkbox-disabled")?!1:(this.settings.checkbox.tie_selection&&(this.settings.checkbox.whole_node||a(c.target).hasClass("jstree-checkbox"))&&(c.ctrlKey=!0),this.settings.checkbox.tie_selection||!this.settings.checkbox.whole_node&&!a(c.target).hasClass("jstree-checkbox")?d.activate_node.call(this,b,c):this.is_disabled(b)?!1:(this.is_checked(b)?this.uncheck_node(b,c):this.check_node(b,c),void this.trigger("activate_node",{node:this.get_node(b)})))},this.check_node=function(b,c){if(this.settings.checkbox.tie_selection)return this.select_node(b,!1,!0,c);var d,e,f,g;if(a.isArray(b)){for(b=b.slice(),e=0,f=b.length;f>e;e++)this.check_node(b[e],c);return!0}return b=this.get_node(b),b&&b.id!==a.jstree.root?(d=this.get_node(b,!0),void(b.state.checked||(b.state.checked=!0,this._data.checkbox.selected.push(b.id),d&&d.length&&d.children(".jstree-anchor").addClass("jstree-checked"),this.trigger("check_node",{node:b,selected:this._data.checkbox.selected,event:c})))):!1},this.uncheck_node=function(b,c){if(this.settings.checkbox.tie_selection)return this.deselect_node(b,!1,c);var d,e,f;if(a.isArray(b)){for(b=b.slice(),d=0,e=b.length;e>d;d++)this.uncheck_node(b[d],c);return!0}return b=this.get_node(b),b&&b.id!==a.jstree.root?(f=this.get_node(b,!0),void(b.state.checked&&(b.state.checked=!1,this._data.checkbox.selected=a.vakata.array_remove_item(this._data.checkbox.selected,b.id),f.length&&f.children(".jstree-anchor").removeClass("jstree-checked"),this.trigger("uncheck_node",{node:b,selected:this._data.checkbox.selected,event:c})))):!1},this.check_all=function(){if(this.settings.checkbox.tie_selection)return this.select_all();var b=this._data.checkbox.selected.concat([]),c,d;for(this._data.checkbox.selected=this._model.data[a.jstree.root].children_d.concat(),c=0,d=this._data.checkbox.selected.length;d>c;c++)this._model.data[this._data.checkbox.selected[c]]&&(this._model.data[this._data.checkbox.selected[c]].state.checked=!0);this.redraw(!0),this.trigger("check_all",{selected:this._data.checkbox.selected})},this.uncheck_all=function(){if(this.settings.checkbox.tie_selection)return this.deselect_all();var a=this._data.checkbox.selected.concat([]),b,c;for(b=0,c=this._data.checkbox.selected.length;c>b;b++)this._model.data[this._data.checkbox.selected[b]]&&(this._model.data[this._data.checkbox.selected[b]].state.checked=!1);this._data.checkbox.selected=[],this.element.find(".jstree-checked").removeClass("jstree-checked"),this.trigger("uncheck_all",{selected:this._data.checkbox.selected,node:a})},this.is_checked=function(b){return this.settings.checkbox.tie_selection?this.is_selected(b):(b=this.get_node(b),b&&b.id!==a.jstree.root?b.state.checked:!1)},this.get_checked=function(b){return this.settings.checkbox.tie_selection?this.get_selected(b):b?a.map(this._data.checkbox.selected,a.proxy(function(a){return this.get_node(a)},this)):this._data.checkbox.selected},this.get_top_checked=function(b){if(this.settings.checkbox.tie_selection)return this.get_top_selected(b);var c=this.get_checked(!0),d={},e,f,g,h;for(e=0,f=c.length;f>e;e++)d[c[e].id]=c[e];for(e=0,f=c.length;f>e;e++)for(g=0,h=c[e].children_d.length;h>g;g++)d[c[e].children_d[g]]&&delete d[c[e].children_d[g]];c=[];for(e in d)d.hasOwnProperty(e)&&c.push(e);return b?a.map(c,a.proxy(function(a){return this.get_node(a)},this)):c},this.get_bottom_checked=function(b){if(this.settings.checkbox.tie_selection)return this.get_bottom_selected(b);var c=this.get_checked(!0),d=[],e,f;for(e=0,f=c.length;f>e;e++)c[e].children.length||d.push(c[e].id);return b?a.map(d,a.proxy(function(a){return this.get_node(a)},this)):d},this.load_node=function(b,c){var e,f,g,h,i,j;if(!a.isArray(b)&&!this.settings.checkbox.tie_selection&&(j=this.get_node(b),j&&j.state.loaded))for(e=0,f=j.children_d.length;f>e;e++)this._model.data[j.children_d[e]].state.checked&&(i=!0,this._data.checkbox.selected=a.vakata.array_remove_item(this._data.checkbox.selected,j.children_d[e]));return d.load_node.apply(this,arguments)},this.get_state=function(){var a=d.get_state.apply(this,arguments);return this.settings.checkbox.tie_selection?a:(a.checkbox=this._data.checkbox.selected.slice(),a)},this.set_state=function(b,c){var e=d.set_state.apply(this,arguments);if(e&&b.checkbox){if(!this.settings.checkbox.tie_selection){this.uncheck_all();var f=this;a.each(b.checkbox,function(a,b){f.check_node(b)})}return delete b.checkbox,this.set_state(b,c),!1}return e},this.refresh=function(a,b){return this.settings.checkbox.tie_selection||(this._data.checkbox.selected=[]),d.refresh.apply(this,arguments)}},a.jstree.defaults.conditionalselect=function(){return!0},a.jstree.plugins.conditionalselect=function(a,b){this.activate_node=function(a,c){this.settings.conditionalselect.call(this,this.get_node(a),c)&&b.activate_node.call(this,a,c)}},a.jstree.defaults.contextmenu={select_node:!0,show_at_node:!0,items:function(b,c){return{create:{separator_before:!1,separator_after:!0,_disabled:!1,label:"Create",action:function(b){var c=a.jstree.reference(b.reference),d=c.get_node(b.reference);c.create_node(d,{},"last",function(a){setTimeout(function(){c.edit(a)},0)})}},rename:{separator_before:!1,separator_after:!1,_disabled:!1,label:"Rename",action:function(b){var c=a.jstree.reference(b.reference),d=c.get_node(b.reference);c.edit(d)}},remove:{separator_before:!1,icon:!1,separator_after:!1,_disabled:!1,label:"Delete",action:function(b){var c=a.jstree.reference(b.reference),d=c.get_node(b.reference);c.is_selected(d)?c.delete_node(c.get_selected()):c.delete_node(d)}},ccp:{separator_before:!0,icon:!1,separator_after:!1,label:"Edit",action:!1,submenu:{cut:{separator_before:!1,separator_after:!1,label:"Cut",action:function(b){var c=a.jstree.reference(b.reference),d=c.get_node(b.reference);c.is_selected(d)?c.cut(c.get_top_selected()):c.cut(d)}},copy:{separator_before:!1,icon:!1,separator_after:!1,label:"Copy",action:function(b){var c=a.jstree.reference(b.reference),d=c.get_node(b.reference);c.is_selected(d)?c.copy(c.get_top_selected()):c.copy(d)}},paste:{separator_before:!1,icon:!1,_disabled:function(b){return!a.jstree.reference(b.reference).can_paste()},separator_after:!1,label:"Paste",action:function(b){var c=a.jstree.reference(b.reference),d=c.get_node(b.reference);c.paste(d)}}}}}}},a.jstree.plugins.contextmenu=function(c,d){this.bind=function(){d.bind.call(this);var b=0,c=null,e,f;this.element.on("contextmenu.jstree",".jstree-anchor",a.proxy(function(a,d){"input"!==a.target.tagName.toLowerCase()&&(a.preventDefault(),b=a.ctrlKey?+new Date:0,(d||c)&&(b=+new Date+1e4),c&&clearTimeout(c),this.is_loading(a.currentTarget)||this.show_contextmenu(a.currentTarget,a.pageX,a.pageY,a))},this)).on("click.jstree",".jstree-anchor",a.proxy(function(c){this._data.contextmenu.visible&&(!b||+new Date-b>250)&&a.vakata.context.hide(),b=0},this)).on("touchstart.jstree",".jstree-anchor",function(b){b.originalEvent&&b.originalEvent.changedTouches&&b.originalEvent.changedTouches[0]&&(e=b.originalEvent.changedTouches[0].clientX,f=b.originalEvent.changedTouches[0].clientY,c=setTimeout(function(){a(b.currentTarget).trigger("contextmenu",!0)},750))}).on("touchmove.vakata.jstree",function(a){c&&a.originalEvent&&a.originalEvent.changedTouches&&a.originalEvent.changedTouches[0]&&(Math.abs(e-a.originalEvent.changedTouches[0].clientX)>50||Math.abs(f-a.originalEvent.changedTouches[0].clientY)>50)&&clearTimeout(c)}).on("touchend.vakata.jstree",function(a){c&&clearTimeout(c)}),a(i).on("context_hide.vakata.jstree",a.proxy(function(b,c){this._data.contextmenu.visible=!1,a(c.reference).removeClass("jstree-context")},this))},this.teardown=function(){this._data.contextmenu.visible&&a.vakata.context.hide(),d.teardown.call(this)},this.show_contextmenu=function(c,d,e,f){if(c=this.get_node(c),!c||c.id===a.jstree.root)return!1;var g=this.settings.contextmenu,h=this.get_node(c,!0),i=h.children(".jstree-anchor"),j=!1,k=!1;(g.show_at_node||d===b||e===b)&&(j=i.offset(),d=j.left,e=j.top+this._data.core.li_height),this.settings.contextmenu.select_node&&!this.is_selected(c)&&this.activate_node(c,f),k=g.items,a.isFunction(k)&&(k=k.call(this,c,a.proxy(function(a){this._show_contextmenu(c,d,e,a)},this))),a.isPlainObject(k)&&this._show_contextmenu(c,d,e,k)},this._show_contextmenu=function(b,c,d,e){var f=this.get_node(b,!0),g=f.children(".jstree-anchor");a(i).one("context_show.vakata.jstree",a.proxy(function(b,c){var d="jstree-contextmenu jstree-"+this.get_theme()+"-contextmenu";a(c.element).addClass(d),g.addClass("jstree-context")},this)),this._data.contextmenu.visible=!0,a.vakata.context.show(g,{x:c,y:d},e),this.trigger("show_contextmenu",{node:b,x:c,y:d})}},function(a){var b=!1,c={element:!1,reference:!1,position_x:0,position_y:0,items:[],html:"",is_visible:!1};a.vakata.context={settings:{hide_onmouseleave:0,icons:!0},_trigger:function(b){a(i).triggerHandler("context_"+b+".vakata",{reference:c.reference,element:c.element,position:{x:c.position_x,y:c.position_y}})},_execute:function(b){return b=c.items[b],b&&(!b._disabled||a.isFunction(b._disabled)&&!b._disabled({item:b,reference:c.reference,element:c.element}))&&b.action?b.action.call(null,{item:b,reference:c.reference,element:c.element,position:{x:c.position_x,y:c.position_y}}):!1},_parse:function(b,d){if(!b)return!1;d||(c.html="",c.items=[]);var e="",f=!1,g;return d&&(e+="<ul>"),a.each(b,function(b,d){return d?(c.items.push(d),!f&&d.separator_before&&(e+="<li class='vakata-context-separator'><a href='#' "+(a.vakata.context.settings.icons?"":'style="margin-left:0px;"')+">&#160;</a></li>"),f=!1,e+="<li class='"+(d._class||"")+(d._disabled===!0||a.isFunction(d._disabled)&&d._disabled({item:d,reference:c.reference,element:c.element})?" vakata-contextmenu-disabled ":"")+"' "+(d.shortcut?" data-shortcut='"+d.shortcut+"' ":"")+">",e+="<a href='#' rel='"+(c.items.length-1)+"' "+(d.title?"title='"+d.title+"'":"")+">",a.vakata.context.settings.icons&&(e+="<i ",d.icon&&(e+=-1!==d.icon.indexOf("/")||-1!==d.icon.indexOf(".")?" style='background:url(\""+d.icon+"\") center center no-repeat' ":" class='"+d.icon+"' "),e+="></i><span class='vakata-contextmenu-sep'>&#160;</span>"),e+=(a.isFunction(d.label)?d.label({item:b,reference:c.reference,element:c.element}):d.label)+(d.shortcut?' <span class="vakata-contextmenu-shortcut vakata-contextmenu-shortcut-'+d.shortcut+'">'+(d.shortcut_label||"")+"</span>":"")+"</a>",d.submenu&&(g=a.vakata.context._parse(d.submenu,!0),g&&(e+=g)),e+="</li>",void(d.separator_after&&(e+="<li class='vakata-context-separator'><a href='#' "+(a.vakata.context.settings.icons?"":'style="margin-left:0px;"')+">&#160;</a></li>",f=!0))):!0}),e=e.replace(/<li class\='vakata-context-separator'\><\/li\>$/,""),d&&(e+="</ul>"),d||(c.html=e,a.vakata.context._trigger("parse")),e.length>10?e:!1},_show_submenu:function(c){if(c=a(c),c.length&&c.children("ul").length){var d=c.children("ul"),e=c.offset().left,f=e+c.outerWidth(),g=c.offset().top,h=d.width(),i=d.height(),j=a(window).width()+a(window).scrollLeft(),k=a(window).height()+a(window).scrollTop();b?c[f-(h+10+c.outerWidth())<0?"addClass":"removeClass"]("vakata-context-left"):c[f+h>j&&e>j-f?"addClass":"removeClass"]("vakata-context-right"),g+i+10>k&&d.css("bottom","-1px"),c.hasClass("vakata-context-right")?h>e&&d.css("margin-right",e-h):h>j-f&&d.css("margin-left",j-f-h),d.show()}},show:function(d,e,f){var g,h,i,j,k,l,m,n,o=!0;switch(c.element&&c.element.length&&c.element.width(""),o){case!e&&!d:return!1;case!!e&&!!d:c.reference=d,c.position_x=e.x,c.position_y=e.y;break;case!e&&!!d:c.reference=d,g=d.offset(),c.position_x=g.left+d.outerHeight(),c.position_y=g.top;break;case!!e&&!d:c.position_x=e.x,c.position_y=e.y}d&&!f&&a(d).data("vakata_contextmenu")&&(f=a(d).data("vakata_contextmenu")),a.vakata.context._parse(f)&&c.element.html(c.html),c.items.length&&(c.element.appendTo("body"),h=c.element,i=c.position_x,j=c.position_y,k=h.width(),l=h.height(),m=a(window).width()+a(window).scrollLeft(),n=a(window).height()+a(window).scrollTop(),b&&(i-=h.outerWidth()-a(d).outerWidth(),i<a(window).scrollLeft()+20&&(i=a(window).scrollLeft()+20)),i+k+20>m&&(i=m-(k+20)),j+l+20>n&&(j=n-(l+20)),c.element.css({left:i,top:j}).show().find("a").first().focus().parent().addClass("vakata-context-hover"),c.is_visible=!0,a.vakata.context._trigger("show"))},hide:function(){c.is_visible&&(c.element.hide().find("ul").hide().end().find(":focus").blur().end().detach(),c.is_visible=!1,a.vakata.context._trigger("hide"))}},a(function(){b="rtl"===a("body").css("direction");var d=!1;c.element=a("<ul class='vakata-context'></ul>"),c.element.on("mouseenter","li",function(b){b.stopImmediatePropagation(),a.contains(this,b.relatedTarget)||(d&&clearTimeout(d),c.element.find(".vakata-context-hover").removeClass("vakata-context-hover").end(),a(this).siblings().find("ul").hide().end().end().parentsUntil(".vakata-context","li").addBack().addClass("vakata-context-hover"),a.vakata.context._show_submenu(this))}).on("mouseleave","li",function(b){a.contains(this,b.relatedTarget)||a(this).find(".vakata-context-hover").addBack().removeClass("vakata-context-hover")}).on("mouseleave",function(b){a(this).find(".vakata-context-hover").removeClass("vakata-context-hover"),a.vakata.context.settings.hide_onmouseleave&&(d=setTimeout(function(b){return function(){a.vakata.context.hide()}}(this),a.vakata.context.settings.hide_onmouseleave))}).on("click","a",function(b){b.preventDefault(),a(this).blur().parent().hasClass("vakata-context-disabled")||a.vakata.context._execute(a(this).attr("rel"))===!1||a.vakata.context.hide()}).on("keydown","a",function(b){var d=null;switch(b.which){case 13:case 32:b.type="mouseup",b.preventDefault(),a(b.currentTarget).trigger(b);break;case 37:c.is_visible&&(c.element.find(".vakata-context-hover").last().closest("li").first().find("ul").hide().find(".vakata-context-hover").removeClass("vakata-context-hover").end().end().children("a").focus(),b.stopImmediatePropagation(),b.preventDefault());break;case 38:c.is_visible&&(d=c.element.find("ul:visible").addBack().last().children(".vakata-context-hover").removeClass("vakata-context-hover").prevAll("li:not(.vakata-context-separator)").first(),d.length||(d=c.element.find("ul:visible").addBack().last().children("li:not(.vakata-context-separator)").last()),d.addClass("vakata-context-hover").children("a").focus(),b.stopImmediatePropagation(),b.preventDefault());break;case 39:c.is_visible&&(c.element.find(".vakata-context-hover").last().children("ul").show().children("li:not(.vakata-context-separator)").removeClass("vakata-context-hover").first().addClass("vakata-context-hover").children("a").focus(),b.stopImmediatePropagation(),b.preventDefault());break;case 40:c.is_visible&&(d=c.element.find("ul:visible").addBack().last().children(".vakata-context-hover").removeClass("vakata-context-hover").nextAll("li:not(.vakata-context-separator)").first(),d.length||(d=c.element.find("ul:visible").addBack().last().children("li:not(.vakata-context-separator)").first()),d.addClass("vakata-context-hover").children("a").focus(),b.stopImmediatePropagation(),
+b.preventDefault());break;case 27:a.vakata.context.hide(),b.preventDefault()}}).on("keydown",function(a){a.preventDefault();var b=c.element.find(".vakata-contextmenu-shortcut-"+a.which).parent();b.parent().not(".vakata-context-disabled")&&b.click()}),a(i).on("mousedown.vakata.jstree",function(b){c.is_visible&&!a.contains(c.element[0],b.target)&&a.vakata.context.hide()}).on("context_show.vakata.jstree",function(a,d){c.element.find("li:has(ul)").children("a").addClass("vakata-context-parent"),b&&c.element.addClass("vakata-context-rtl").css("direction","rtl"),c.element.find("ul").hide().end()})})}(a),a.jstree.defaults.dnd={copy:!0,open_timeout:500,is_draggable:!0,check_while_dragging:!0,always_copy:!1,inside_pos:0,drag_selection:!0,touch:!0,large_drop_target:!1,large_drag_target:!1,use_html5:!1};var n,o;a.jstree.plugins.dnd=function(b,c){this.init=function(a,b){c.init.call(this,a,b),this.settings.dnd.use_html5=this.settings.dnd.use_html5&&"draggable"in i.createElement("span")},this.bind=function(){c.bind.call(this),this.element.on(this.settings.dnd.use_html5?"dragstart.jstree":"mousedown.jstree touchstart.jstree",this.settings.dnd.large_drag_target?".jstree-node":".jstree-anchor",a.proxy(function(b){if(this.settings.dnd.large_drag_target&&a(b.target).closest(".jstree-node")[0]!==b.currentTarget)return!0;if("touchstart"===b.type&&(!this.settings.dnd.touch||"selected"===this.settings.dnd.touch&&!a(b.currentTarget).closest(".jstree-node").children(".jstree-anchor").hasClass("jstree-clicked")))return!0;var c=this.get_node(b.target),d=this.is_selected(c)&&this.settings.dnd.drag_selection?this.get_top_selected().length:1,e=d>1?d+" "+this.get_string("nodes"):this.get_text(b.currentTarget);if(this.settings.core.force_text&&(e=a.vakata.html.escape(e)),c&&c.id&&c.id!==a.jstree.root&&(1===b.which||"touchstart"===b.type||"dragstart"===b.type)&&(this.settings.dnd.is_draggable===!0||a.isFunction(this.settings.dnd.is_draggable)&&this.settings.dnd.is_draggable.call(this,d>1?this.get_top_selected(!0):[c],b))){if(n={jstree:!0,origin:this,obj:this.get_node(c,!0),nodes:d>1?this.get_top_selected():[c.id]},o=b.currentTarget,!this.settings.dnd.use_html5)return this.element.trigger("mousedown.jstree"),a.vakata.dnd.start(b,n,'<div id="jstree-dnd" class="jstree-'+this.get_theme()+" jstree-"+this.get_theme()+"-"+this.get_theme_variant()+" "+(this.settings.core.themes.responsive?" jstree-dnd-responsive":"")+'"><i class="jstree-icon jstree-er"></i>'+e+'<ins class="jstree-copy" style="display:none;">+</ins></div>');a.vakata.dnd._trigger("start",b,{helper:a(),element:o,data:n})}},this)),this.settings.dnd.use_html5&&this.element.on("dragover.jstree",function(b){return b.preventDefault(),a.vakata.dnd._trigger("move",b,{helper:a(),element:o,data:n}),!1}).on("drop.jstree",a.proxy(function(b){return b.preventDefault(),a.vakata.dnd._trigger("stop",b,{helper:a(),element:o,data:n}),!1},this))},this.redraw_node=function(a,b,d,e){if(a=c.redraw_node.apply(this,arguments),a&&this.settings.dnd.use_html5)if(this.settings.dnd.large_drag_target)a.setAttribute("draggable",!0);else{var f,g,h=null;for(f=0,g=a.childNodes.length;g>f;f++)if(a.childNodes[f]&&a.childNodes[f].className&&-1!==a.childNodes[f].className.indexOf("jstree-anchor")){h=a.childNodes[f];break}h&&h.setAttribute("draggable",!0)}return a}},a(function(){var c=!1,d=!1,e=!1,f=!1,g=a('<div id="jstree-marker">&#160;</div>').hide();a(i).on("dnd_start.vakata.jstree",function(a,b){c=!1,e=!1,b&&b.data&&b.data.jstree&&g.appendTo("body")}).on("dnd_move.vakata.jstree",function(h,i){if(f&&(i.event&&"dragover"===i.event.type&&i.event.target===e.target||clearTimeout(f)),i&&i.data&&i.data.jstree&&(!i.event.target.id||"jstree-marker"!==i.event.target.id)){e=i.event;var j=a.jstree.reference(i.event.target),k=!1,l=!1,m=!1,n,o,p,q,r,s,t,u,v,w,x,y,z,A,B,C,D;if(j&&j._data&&j._data.dnd)if(g.attr("class","jstree-"+j.get_theme()+(j.settings.core.themes.responsive?" jstree-dnd-responsive":"")),C=i.data.origin&&(i.data.origin.settings.dnd.always_copy||i.data.origin.settings.dnd.copy&&(i.event.metaKey||i.event.ctrlKey)),i.helper.children().attr("class","jstree-"+j.get_theme()+" jstree-"+j.get_theme()+"-"+j.get_theme_variant()+" "+(j.settings.core.themes.responsive?" jstree-dnd-responsive":"")).find(".jstree-copy").first()[C?"show":"hide"](),i.event.target!==j.element[0]&&i.event.target!==j.get_container_ul()[0]||0!==j.get_container_ul().children().length){if(k=j.settings.dnd.large_drop_target?a(i.event.target).closest(".jstree-node").children(".jstree-anchor"):a(i.event.target).closest(".jstree-anchor"),k&&k.length&&k.parent().is(".jstree-closed, .jstree-open, .jstree-leaf")&&(l=k.offset(),m=(i.event.pageY!==b?i.event.pageY:i.event.originalEvent.pageY)-l.top,q=k.outerHeight(),t=q/3>m?["b","i","a"]:m>q-q/3?["a","i","b"]:m>q/2?["i","a","b"]:["i","b","a"],a.each(t,function(b,e){switch(e){case"b":o=l.left-6,p=l.top,r=j.get_parent(k),s=k.parent().index();break;case"i":A=j.settings.dnd.inside_pos,B=j.get_node(k.parent()),o=l.left-2,p=l.top+q/2+1,r=B.id,s="first"===A?0:"last"===A?B.children.length:Math.min(A,B.children.length);break;case"a":o=l.left-6,p=l.top+q,r=j.get_parent(k),s=k.parent().index()+1}for(u=!0,v=0,w=i.data.nodes.length;w>v;v++)if(x=i.data.origin&&(i.data.origin.settings.dnd.always_copy||i.data.origin.settings.dnd.copy&&(i.event.metaKey||i.event.ctrlKey))?"copy_node":"move_node",y=s,"move_node"===x&&"a"===e&&i.data.origin&&i.data.origin===j&&r===j.get_parent(i.data.nodes[v])&&(z=j.get_node(r),y>a.inArray(i.data.nodes[v],z.children)&&(y-=1)),u=u&&(j&&j.settings&&j.settings.dnd&&j.settings.dnd.check_while_dragging===!1||j.check(x,i.data.origin&&i.data.origin!==j?i.data.origin.get_node(i.data.nodes[v]):i.data.nodes[v],r,y,{dnd:!0,ref:j.get_node(k.parent()),pos:e,origin:i.data.origin,is_multi:i.data.origin&&i.data.origin!==j,is_foreign:!i.data.origin})),!u){j&&j.last_error&&(d=j.last_error());break}return"i"===e&&k.parent().is(".jstree-closed")&&j.settings.dnd.open_timeout&&(f=setTimeout(function(a,b){return function(){a.open_node(b)}}(j,k),j.settings.dnd.open_timeout)),u?(D=j.get_node(r,!0),D.hasClass(".jstree-dnd-parent")||(a(".jstree-dnd-parent").removeClass("jstree-dnd-parent"),D.addClass("jstree-dnd-parent")),c={ins:j,par:r,pos:"i"!==e||"last"!==A||0!==s||j.is_loaded(B)?s:"last"},g.css({left:o+"px",top:p+"px"}).show(),i.helper.find(".jstree-icon").first().removeClass("jstree-er").addClass("jstree-ok"),i.event.originalEvent&&i.event.originalEvent.dataTransfer&&(i.event.originalEvent.dataTransfer.dropEffect=C?"copy":"move"),d={},t=!0,!1):void 0}),t===!0))return}else{for(u=!0,v=0,w=i.data.nodes.length;w>v;v++)if(u=u&&j.check(i.data.origin&&(i.data.origin.settings.dnd.always_copy||i.data.origin.settings.dnd.copy&&(i.event.metaKey||i.event.ctrlKey))?"copy_node":"move_node",i.data.origin&&i.data.origin!==j?i.data.origin.get_node(i.data.nodes[v]):i.data.nodes[v],a.jstree.root,"last",{dnd:!0,ref:j.get_node(a.jstree.root),pos:"i",origin:i.data.origin,is_multi:i.data.origin&&i.data.origin!==j,is_foreign:!i.data.origin}),!u)break;if(u)return c={ins:j,par:a.jstree.root,pos:"last"},g.hide(),i.helper.find(".jstree-icon").first().removeClass("jstree-er").addClass("jstree-ok"),void(i.event.originalEvent&&i.event.originalEvent.dataTransfer&&(i.event.originalEvent.dataTransfer.dropEffect=C?"copy":"move"))}a(".jstree-dnd-parent").removeClass("jstree-dnd-parent"),c=!1,i.helper.find(".jstree-icon").removeClass("jstree-ok").addClass("jstree-er"),i.event.originalEvent&&i.event.originalEvent.dataTransfer&&(i.event.originalEvent.dataTransfer.dropEffect="none"),g.hide()}}).on("dnd_scroll.vakata.jstree",function(a,b){b&&b.data&&b.data.jstree&&(g.hide(),c=!1,e=!1,b.helper.find(".jstree-icon").first().removeClass("jstree-ok").addClass("jstree-er"))}).on("dnd_stop.vakata.jstree",function(b,h){if(a(".jstree-dnd-parent").removeClass("jstree-dnd-parent"),f&&clearTimeout(f),h&&h.data&&h.data.jstree){g.hide().detach();var i,j,k=[];if(c){for(i=0,j=h.data.nodes.length;j>i;i++)k[i]=h.data.origin?h.data.origin.get_node(h.data.nodes[i]):h.data.nodes[i];c.ins[h.data.origin&&(h.data.origin.settings.dnd.always_copy||h.data.origin.settings.dnd.copy&&(h.event.metaKey||h.event.ctrlKey))?"copy_node":"move_node"](k,c.par,c.pos,!1,!1,!1,h.data.origin)}else i=a(h.event.target).closest(".jstree"),i.length&&d&&d.error&&"check"===d.error&&(i=i.jstree(!0),i&&i.settings.core.error.call(this,d));e=!1,c=!1}}).on("keyup.jstree keydown.jstree",function(b,h){h=a.vakata.dnd._get(),h&&h.data&&h.data.jstree&&("keyup"===b.type&&27===b.which?(f&&clearTimeout(f),c=!1,d=!1,e=!1,f=!1,g.hide().detach(),a.vakata.dnd._clean()):(h.helper.find(".jstree-copy").first()[h.data.origin&&(h.data.origin.settings.dnd.always_copy||h.data.origin.settings.dnd.copy&&(b.metaKey||b.ctrlKey))?"show":"hide"](),e&&(e.metaKey=b.metaKey,e.ctrlKey=b.ctrlKey,a.vakata.dnd._trigger("move",e))))})}),function(a){a.vakata.html={div:a("<div />"),escape:function(b){return a.vakata.html.div.text(b).html()},strip:function(b){return a.vakata.html.div.empty().append(a.parseHTML(b)).text()}};var c={element:!1,target:!1,is_down:!1,is_drag:!1,helper:!1,helper_w:0,data:!1,init_x:0,init_y:0,scroll_l:0,scroll_t:0,scroll_e:!1,scroll_i:!1,is_touch:!1};a.vakata.dnd={settings:{scroll_speed:10,scroll_proximity:20,helper_left:5,helper_top:10,threshold:5,threshold_touch:50},_trigger:function(c,d,e){e===b&&(e=a.vakata.dnd._get()),e.event=d,a(i).triggerHandler("dnd_"+c+".vakata",e)},_get:function(){return{data:c.data,element:c.element,helper:c.helper}},_clean:function(){c.helper&&c.helper.remove(),c.scroll_i&&(clearInterval(c.scroll_i),c.scroll_i=!1),c={element:!1,target:!1,is_down:!1,is_drag:!1,helper:!1,helper_w:0,data:!1,init_x:0,init_y:0,scroll_l:0,scroll_t:0,scroll_e:!1,scroll_i:!1,is_touch:!1},a(i).off("mousemove.vakata.jstree touchmove.vakata.jstree",a.vakata.dnd.drag),a(i).off("mouseup.vakata.jstree touchend.vakata.jstree",a.vakata.dnd.stop)},_scroll:function(b){if(!c.scroll_e||!c.scroll_l&&!c.scroll_t)return c.scroll_i&&(clearInterval(c.scroll_i),c.scroll_i=!1),!1;if(!c.scroll_i)return c.scroll_i=setInterval(a.vakata.dnd._scroll,100),!1;if(b===!0)return!1;var d=c.scroll_e.scrollTop(),e=c.scroll_e.scrollLeft();c.scroll_e.scrollTop(d+c.scroll_t*a.vakata.dnd.settings.scroll_speed),c.scroll_e.scrollLeft(e+c.scroll_l*a.vakata.dnd.settings.scroll_speed),(d!==c.scroll_e.scrollTop()||e!==c.scroll_e.scrollLeft())&&a.vakata.dnd._trigger("scroll",c.scroll_e)},start:function(b,d,e){"touchstart"===b.type&&b.originalEvent&&b.originalEvent.changedTouches&&b.originalEvent.changedTouches[0]&&(b.pageX=b.originalEvent.changedTouches[0].pageX,b.pageY=b.originalEvent.changedTouches[0].pageY,b.target=i.elementFromPoint(b.originalEvent.changedTouches[0].pageX-window.pageXOffset,b.originalEvent.changedTouches[0].pageY-window.pageYOffset)),c.is_drag&&a.vakata.dnd.stop({});try{b.currentTarget.unselectable="on",b.currentTarget.onselectstart=function(){return!1},b.currentTarget.style&&(b.currentTarget.style.touchAction="none",b.currentTarget.style.msTouchAction="none",b.currentTarget.style.MozUserSelect="none")}catch(f){}return c.init_x=b.pageX,c.init_y=b.pageY,c.data=d,c.is_down=!0,c.element=b.currentTarget,c.target=b.target,c.is_touch="touchstart"===b.type,e!==!1&&(c.helper=a("<div id='vakata-dnd'></div>").html(e).css({display:"block",margin:"0",padding:"0",position:"absolute",top:"-2000px",lineHeight:"16px",zIndex:"10000"})),a(i).on("mousemove.vakata.jstree touchmove.vakata.jstree",a.vakata.dnd.drag),a(i).on("mouseup.vakata.jstree touchend.vakata.jstree",a.vakata.dnd.stop),!1},drag:function(b){if("touchmove"===b.type&&b.originalEvent&&b.originalEvent.changedTouches&&b.originalEvent.changedTouches[0]&&(b.pageX=b.originalEvent.changedTouches[0].pageX,b.pageY=b.originalEvent.changedTouches[0].pageY,b.target=i.elementFromPoint(b.originalEvent.changedTouches[0].pageX-window.pageXOffset,b.originalEvent.changedTouches[0].pageY-window.pageYOffset)),c.is_down){if(!c.is_drag){if(!(Math.abs(b.pageX-c.init_x)>(c.is_touch?a.vakata.dnd.settings.threshold_touch:a.vakata.dnd.settings.threshold)||Math.abs(b.pageY-c.init_y)>(c.is_touch?a.vakata.dnd.settings.threshold_touch:a.vakata.dnd.settings.threshold)))return;c.helper&&(c.helper.appendTo("body"),c.helper_w=c.helper.outerWidth()),c.is_drag=!0,a(c.target).one("click.vakata",!1),a.vakata.dnd._trigger("start",b)}var d=!1,e=!1,f=!1,g=!1,h=!1,j=!1,k=!1,l=!1,m=!1,n=!1;return c.scroll_t=0,c.scroll_l=0,c.scroll_e=!1,a(a(b.target).parentsUntil("body").addBack().get().reverse()).filter(function(){return/^auto|scroll$/.test(a(this).css("overflow"))&&(this.scrollHeight>this.offsetHeight||this.scrollWidth>this.offsetWidth)}).each(function(){var d=a(this),e=d.offset();return this.scrollHeight>this.offsetHeight&&(e.top+d.height()-b.pageY<a.vakata.dnd.settings.scroll_proximity&&(c.scroll_t=1),b.pageY-e.top<a.vakata.dnd.settings.scroll_proximity&&(c.scroll_t=-1)),this.scrollWidth>this.offsetWidth&&(e.left+d.width()-b.pageX<a.vakata.dnd.settings.scroll_proximity&&(c.scroll_l=1),b.pageX-e.left<a.vakata.dnd.settings.scroll_proximity&&(c.scroll_l=-1)),c.scroll_t||c.scroll_l?(c.scroll_e=a(this),!1):void 0}),c.scroll_e||(d=a(i),e=a(window),f=d.height(),g=e.height(),h=d.width(),j=e.width(),k=d.scrollTop(),l=d.scrollLeft(),f>g&&b.pageY-k<a.vakata.dnd.settings.scroll_proximity&&(c.scroll_t=-1),f>g&&g-(b.pageY-k)<a.vakata.dnd.settings.scroll_proximity&&(c.scroll_t=1),h>j&&b.pageX-l<a.vakata.dnd.settings.scroll_proximity&&(c.scroll_l=-1),h>j&&j-(b.pageX-l)<a.vakata.dnd.settings.scroll_proximity&&(c.scroll_l=1),(c.scroll_t||c.scroll_l)&&(c.scroll_e=d)),c.scroll_e&&a.vakata.dnd._scroll(!0),c.helper&&(m=parseInt(b.pageY+a.vakata.dnd.settings.helper_top,10),n=parseInt(b.pageX+a.vakata.dnd.settings.helper_left,10),f&&m+25>f&&(m=f-50),h&&n+c.helper_w>h&&(n=h-(c.helper_w+2)),c.helper.css({left:n+"px",top:m+"px"})),a.vakata.dnd._trigger("move",b),!1}},stop:function(b){if("touchend"===b.type&&b.originalEvent&&b.originalEvent.changedTouches&&b.originalEvent.changedTouches[0]&&(b.pageX=b.originalEvent.changedTouches[0].pageX,b.pageY=b.originalEvent.changedTouches[0].pageY,b.target=i.elementFromPoint(b.originalEvent.changedTouches[0].pageX-window.pageXOffset,b.originalEvent.changedTouches[0].pageY-window.pageYOffset)),c.is_drag)b.target!==c.target&&a(c.target).off("click.vakata"),a.vakata.dnd._trigger("stop",b);else if("touchend"===b.type&&b.target===c.target){var d=setTimeout(function(){a(b.target).click()},100);a(b.target).one("click",function(){d&&clearTimeout(d)})}return a.vakata.dnd._clean(),!1}}}(a),a.jstree.defaults.massload=null,a.jstree.plugins.massload=function(b,c){this.init=function(a,b){this._data.massload={},c.init.call(this,a,b)},this._load_nodes=function(b,d,e,f){var g=this.settings.massload,h=JSON.stringify(b),i=[],j=this._model.data,k,l,m;if(!e){for(k=0,l=b.length;l>k;k++)(!j[b[k]]||!j[b[k]].state.loaded&&!j[b[k]].state.failed||f)&&(i.push(b[k]),m=this.get_node(b[k],!0),m&&m.length&&m.addClass("jstree-loading").attr("aria-busy",!0));if(this._data.massload={},i.length){if(a.isFunction(g))return g.call(this,i,a.proxy(function(a){var g,h;if(a)for(g in a)a.hasOwnProperty(g)&&(this._data.massload[g]=a[g]);for(g=0,h=b.length;h>g;g++)m=this.get_node(b[g],!0),m&&m.length&&m.removeClass("jstree-loading").attr("aria-busy",!1);c._load_nodes.call(this,b,d,e,f)},this));if("object"==typeof g&&g&&g.url)return g=a.extend(!0,{},g),a.isFunction(g.url)&&(g.url=g.url.call(this,i)),a.isFunction(g.data)&&(g.data=g.data.call(this,i)),a.ajax(g).done(a.proxy(function(a,g,h){var i,j;if(a)for(i in a)a.hasOwnProperty(i)&&(this._data.massload[i]=a[i]);for(i=0,j=b.length;j>i;i++)m=this.get_node(b[i],!0),m&&m.length&&m.removeClass("jstree-loading").attr("aria-busy",!1);c._load_nodes.call(this,b,d,e,f)},this)).fail(a.proxy(function(a){c._load_nodes.call(this,b,d,e,f)},this))}}return c._load_nodes.call(this,b,d,e,f)},this._load_node=function(b,d){var e=this._data.massload[b.id],f=null,g;return e?(f=this["string"==typeof e?"_append_html_data":"_append_json_data"](b,"string"==typeof e?a(a.parseHTML(e)).filter(function(){return 3!==this.nodeType}):e,function(a){d.call(this,a)}),g=this.get_node(b.id,!0),g&&g.length&&g.removeClass("jstree-loading").attr("aria-busy",!1),delete this._data.massload[b.id],f):c._load_node.call(this,b,d)}},a.jstree.defaults.search={ajax:!1,fuzzy:!1,case_sensitive:!1,show_only_matches:!1,show_only_matches_children:!1,close_opened_onclear:!0,search_leaves_only:!1,search_callback:!1},a.jstree.plugins.search=function(c,d){this.bind=function(){d.bind.call(this),this._data.search.str="",this._data.search.dom=a(),this._data.search.res=[],this._data.search.opn=[],this._data.search.som=!1,this._data.search.smc=!1,this._data.search.hdn=[],this.element.on("search.jstree",a.proxy(function(b,c){if(this._data.search.som&&c.res.length){var d=this._model.data,e,f,g=[],h,i;for(e=0,f=c.res.length;f>e;e++)if(d[c.res[e]]&&!d[c.res[e]].state.hidden&&(g.push(c.res[e]),g=g.concat(d[c.res[e]].parents),this._data.search.smc))for(h=0,i=d[c.res[e]].children_d.length;i>h;h++)d[d[c.res[e]].children_d[h]]&&!d[d[c.res[e]].children_d[h]].state.hidden&&g.push(d[c.res[e]].children_d[h]);g=a.vakata.array_remove_item(a.vakata.array_unique(g),a.jstree.root),this._data.search.hdn=this.hide_all(!0),this.show_node(g,!0),this.redraw(!0)}},this)).on("clear_search.jstree",a.proxy(function(a,b){this._data.search.som&&b.res.length&&(this.show_node(this._data.search.hdn,!0),this.redraw(!0))},this))},this.search=function(c,d,e,f,g,h){if(c===!1||""===a.trim(c.toString()))return this.clear_search();f=this.get_node(f),f=f&&f.id?f.id:null,c=c.toString();var i=this.settings.search,j=i.ajax?i.ajax:!1,k=this._model.data,l=null,m=[],n=[],o,p;if(this._data.search.res.length&&!g&&this.clear_search(),e===b&&(e=i.show_only_matches),h===b&&(h=i.show_only_matches_children),!d&&j!==!1)return a.isFunction(j)?j.call(this,c,a.proxy(function(b){b&&b.d&&(b=b.d),this._load_nodes(a.isArray(b)?a.vakata.array_unique(b):[],function(){this.search(c,!0,e,f,g)})},this),f):(j=a.extend({},j),j.data||(j.data={}),j.data.str=c,f&&(j.data.inside=f),a.ajax(j).fail(a.proxy(function(){this._data.core.last_error={error:"ajax",plugin:"search",id:"search_01",reason:"Could not load search parents",data:JSON.stringify(j)},this.settings.core.error.call(this,this._data.core.last_error)},this)).done(a.proxy(function(b){b&&b.d&&(b=b.d),this._load_nodes(a.isArray(b)?a.vakata.array_unique(b):[],function(){this.search(c,!0,e,f,g)})},this)));if(g||(this._data.search.str=c,this._data.search.dom=a(),this._data.search.res=[],this._data.search.opn=[],this._data.search.som=e,this._data.search.smc=h),l=new a.vakata.search(c,!0,{caseSensitive:i.case_sensitive,fuzzy:i.fuzzy}),a.each(k[f?f:a.jstree.root].children_d,function(a,b){var d=k[b];d.text&&!d.state.hidden&&(!i.search_leaves_only||d.state.loaded&&0===d.children.length)&&(i.search_callback&&i.search_callback.call(this,c,d)||!i.search_callback&&l.search(d.text).isMatch)&&(m.push(b),n=n.concat(d.parents))}),m.length){for(n=a.vakata.array_unique(n),o=0,p=n.length;p>o;o++)n[o]!==a.jstree.root&&k[n[o]]&&this.open_node(n[o],null,0)===!0&&this._data.search.opn.push(n[o]);g?(this._data.search.dom=this._data.search.dom.add(a(this.element[0].querySelectorAll("#"+a.map(m,function(b){return-1!=="0123456789".indexOf(b[0])?"\\3"+b[0]+" "+b.substr(1).replace(a.jstree.idregex,"\\$&"):b.replace(a.jstree.idregex,"\\$&")}).join(", #")))),this._data.search.res=a.vakata.array_unique(this._data.search.res.concat(m))):(this._data.search.dom=a(this.element[0].querySelectorAll("#"+a.map(m,function(b){return-1!=="0123456789".indexOf(b[0])?"\\3"+b[0]+" "+b.substr(1).replace(a.jstree.idregex,"\\$&"):b.replace(a.jstree.idregex,"\\$&")}).join(", #"))),this._data.search.res=m),this._data.search.dom.children(".jstree-anchor").addClass("jstree-search")}this.trigger("search",{nodes:this._data.search.dom,str:c,res:this._data.search.res,show_only_matches:e})},this.clear_search=function(){this.settings.search.close_opened_onclear&&this.close_node(this._data.search.opn,0),this.trigger("clear_search",{nodes:this._data.search.dom,str:this._data.search.str,res:this._data.search.res}),this._data.search.res.length&&(this._data.search.dom=a(this.element[0].querySelectorAll("#"+a.map(this._data.search.res,function(b){return-1!=="0123456789".indexOf(b[0])?"\\3"+b[0]+" "+b.substr(1).replace(a.jstree.idregex,"\\$&"):b.replace(a.jstree.idregex,"\\$&")}).join(", #"))),this._data.search.dom.children(".jstree-anchor").removeClass("jstree-search")),this._data.search.str="",this._data.search.res=[],this._data.search.opn=[],this._data.search.dom=a()},this.redraw_node=function(b,c,e,f){if(b=d.redraw_node.apply(this,arguments),b&&-1!==a.inArray(b.id,this._data.search.res)){var g,h,i=null;for(g=0,h=b.childNodes.length;h>g;g++)if(b.childNodes[g]&&b.childNodes[g].className&&-1!==b.childNodes[g].className.indexOf("jstree-anchor")){i=b.childNodes[g];break}i&&(i.className+=" jstree-search")}return b}},function(a){a.vakata.search=function(b,c,d){d=d||{},d=a.extend({},a.vakata.search.defaults,d),d.fuzzy!==!1&&(d.fuzzy=!0),b=d.caseSensitive?b:b.toLowerCase();var e=d.location,f=d.distance,g=d.threshold,h=b.length,i,j,k,l;return h>32&&(d.fuzzy=!1),d.fuzzy&&(i=1<<h-1,j=function(){var a={},c=0;for(c=0;h>c;c++)a[b.charAt(c)]=0;for(c=0;h>c;c++)a[b.charAt(c)]|=1<<h-c-1;return a}(),k=function(a,b){var c=a/h,d=Math.abs(e-b);return f?c+d/f:d?1:c}),l=function(a){if(a=d.caseSensitive?a:a.toLowerCase(),b===a||-1!==a.indexOf(b))return{isMatch:!0,score:0};if(!d.fuzzy)return{isMatch:!1,score:1};var c,f,l=a.length,m=g,n=a.indexOf(b,e),o,p,q=h+l,r,s,t,u,v,w=1,x=[];for(-1!==n&&(m=Math.min(k(0,n),m),n=a.lastIndexOf(b,e+h),-1!==n&&(m=Math.min(k(0,n),m))),n=-1,c=0;h>c;c++){o=0,p=q;while(p>o)k(c,e+p)<=m?o=p:q=p,p=Math.floor((q-o)/2+o);for(q=p,s=Math.max(1,e-p+1),t=Math.min(e+p,l)+h,u=new Array(t+2),u[t+1]=(1<<c)-1,f=t;f>=s;f--)if(v=j[a.charAt(f-1)],0===c?u[f]=(u[f+1]<<1|1)&v:u[f]=(u[f+1]<<1|1)&v|((r[f+1]|r[f])<<1|1)|r[f+1],u[f]&i&&(w=k(c,f-1),m>=w)){if(m=w,n=f-1,x.push(n),!(n>e))break;s=Math.max(1,2*e-n)}if(k(c+1,e)>m)break;r=u}return{isMatch:n>=0,score:w}},c===!0?{search:l}:l(c)},a.vakata.search.defaults={location:0,distance:100,threshold:.6,fuzzy:!1,caseSensitive:!1}}(a),a.jstree.defaults.sort=function(a,b){return this.get_text(a)>this.get_text(b)?1:-1},a.jstree.plugins.sort=function(b,c){this.bind=function(){c.bind.call(this),this.element.on("model.jstree",a.proxy(function(a,b){this.sort(b.parent,!0)},this)).on("rename_node.jstree create_node.jstree",a.proxy(function(a,b){this.sort(b.parent||b.node.parent,!1),this.redraw_node(b.parent||b.node.parent,!0)},this)).on("move_node.jstree copy_node.jstree",a.proxy(function(a,b){this.sort(b.parent,!1),this.redraw_node(b.parent,!0)},this))},this.sort=function(b,c){var d,e;if(b=this.get_node(b),b&&b.children&&b.children.length&&(b.children.sort(a.proxy(this.settings.sort,this)),c))for(d=0,e=b.children_d.length;e>d;d++)this.sort(b.children_d[d],!1)}};var p=!1;a.jstree.defaults.state={key:"jstree",events:"changed.jstree open_node.jstree close_node.jstree check_node.jstree uncheck_node.jstree",ttl:!1,filter:!1},a.jstree.plugins.state=function(b,c){this.bind=function(){c.bind.call(this);var b=a.proxy(function(){this.element.on(this.settings.state.events,a.proxy(function(){p&&clearTimeout(p),p=setTimeout(a.proxy(function(){this.save_state()},this),100)},this)),this.trigger("state_ready")},this);this.element.on("ready.jstree",a.proxy(function(a,c){this.element.one("restore_state.jstree",b),this.restore_state()||b()},this))},this.save_state=function(){var b={state:this.get_state(),ttl:this.settings.state.ttl,sec:+new Date};a.vakata.storage.set(this.settings.state.key,JSON.stringify(b))},this.restore_state=function(){var b=a.vakata.storage.get(this.settings.state.key);if(b)try{b=JSON.parse(b)}catch(c){return!1}return b&&b.ttl&&b.sec&&+new Date-b.sec>b.ttl?!1:(b&&b.state&&(b=b.state),b&&a.isFunction(this.settings.state.filter)&&(b=this.settings.state.filter.call(this,b)),b?(this.element.one("set_state.jstree",function(c,d){d.instance.trigger("restore_state",{state:a.extend(!0,{},b)})}),this.set_state(b),!0):!1)},this.clear_state=function(){return a.vakata.storage.del(this.settings.state.key)}},function(a,b){a.vakata.storage={set:function(a,b){return window.localStorage.setItem(a,b)},get:function(a){return window.localStorage.getItem(a)},del:function(a){return window.localStorage.removeItem(a)}}}(a),a.jstree.defaults.types={"default":{}},a.jstree.defaults.types[a.jstree.root]={},a.jstree.plugins.types=function(c,d){this.init=function(c,e){var f,g;if(e&&e.types&&e.types["default"])for(f in e.types)if("default"!==f&&f!==a.jstree.root&&e.types.hasOwnProperty(f))for(g in e.types["default"])e.types["default"].hasOwnProperty(g)&&e.types[f][g]===b&&(e.types[f][g]=e.types["default"][g]);d.init.call(this,c,e),this._model.data[a.jstree.root].type=a.jstree.root},this.refresh=function(b,c){d.refresh.call(this,b,c),this._model.data[a.jstree.root].type=a.jstree.root},this.bind=function(){this.element.on("model.jstree",a.proxy(function(c,d){var e=this._model.data,f=d.nodes,g=this.settings.types,h,i,j="default",k;for(h=0,i=f.length;i>h;h++){if(j="default",e[f[h]].original&&e[f[h]].original.type&&g[e[f[h]].original.type]&&(j=e[f[h]].original.type),e[f[h]].data&&e[f[h]].data.jstree&&e[f[h]].data.jstree.type&&g[e[f[h]].data.jstree.type]&&(j=e[f[h]].data.jstree.type),e[f[h]].type=j,e[f[h]].icon===!0&&g[j].icon!==b&&(e[f[h]].icon=g[j].icon),g[j].li_attr!==b&&"object"==typeof g[j].li_attr)for(k in g[j].li_attr)if(g[j].li_attr.hasOwnProperty(k)){if("id"===k)continue;e[f[h]].li_attr[k]===b?e[f[h]].li_attr[k]=g[j].li_attr[k]:"class"===k&&(e[f[h]].li_attr["class"]=g[j].li_attr["class"]+" "+e[f[h]].li_attr["class"])}if(g[j].a_attr!==b&&"object"==typeof g[j].a_attr)for(k in g[j].a_attr)if(g[j].a_attr.hasOwnProperty(k)){if("id"===k)continue;e[f[h]].a_attr[k]===b?e[f[h]].a_attr[k]=g[j].a_attr[k]:"href"===k&&"#"===e[f[h]].a_attr[k]?e[f[h]].a_attr.href=g[j].a_attr.href:"class"===k&&(e[f[h]].a_attr["class"]=g[j].a_attr["class"]+" "+e[f[h]].a_attr["class"])}}e[a.jstree.root].type=a.jstree.root},this)),d.bind.call(this)},this.get_json=function(b,c,e){var f,g,h=this._model.data,i=c?a.extend(!0,{},c,{no_id:!1}):{},j=d.get_json.call(this,b,i,e);if(j===!1)return!1;if(a.isArray(j))for(f=0,g=j.length;g>f;f++)j[f].type=j[f].id&&h[j[f].id]&&h[j[f].id].type?h[j[f].id].type:"default",c&&c.no_id&&(delete j[f].id,j[f].li_attr&&j[f].li_attr.id&&delete j[f].li_attr.id,j[f].a_attr&&j[f].a_attr.id&&delete j[f].a_attr.id);else j.type=j.id&&h[j.id]&&h[j.id].type?h[j.id].type:"default",c&&c.no_id&&(j=this._delete_ids(j));return j},this._delete_ids=function(b){if(a.isArray(b)){for(var c=0,d=b.length;d>c;c++)b[c]=this._delete_ids(b[c]);return b}return delete b.id,b.li_attr&&b.li_attr.id&&delete b.li_attr.id,b.a_attr&&b.a_attr.id&&delete b.a_attr.id,b.children&&a.isArray(b.children)&&(b.children=this._delete_ids(b.children)),b},this.check=function(c,e,f,g,h){if(d.check.call(this,c,e,f,g,h)===!1)return!1;e=e&&e.id?e:this.get_node(e),f=f&&f.id?f:this.get_node(f);var i=e&&e.id?h&&h.origin?h.origin:a.jstree.reference(e.id):null,j,k,l,m;switch(i=i&&i._model&&i._model.data?i._model.data:null,c){case"create_node":case"move_node":case"copy_node":if("move_node"!==c||-1===a.inArray(e.id,f.children)){if(j=this.get_rules(f),j.max_children!==b&&-1!==j.max_children&&j.max_children===f.children.length)return this._data.core.last_error={error:"check",plugin:"types",id:"types_01",reason:"max_children prevents function: "+c,data:JSON.stringify({chk:c,pos:g,obj:e&&e.id?e.id:!1,par:f&&f.id?f.id:!1})},!1;if(j.valid_children!==b&&-1!==j.valid_children&&-1===a.inArray(e.type||"default",j.valid_children))return this._data.core.last_error={error:"check",plugin:"types",id:"types_02",reason:"valid_children prevents function: "+c,data:JSON.stringify({chk:c,pos:g,obj:e&&e.id?e.id:!1,par:f&&f.id?f.id:!1})},!1;if(i&&e.children_d&&e.parents){for(k=0,l=0,m=e.children_d.length;m>l;l++)k=Math.max(k,i[e.children_d[l]].parents.length);k=k-e.parents.length+1}(0>=k||k===b)&&(k=1);do{if(j.max_depth!==b&&-1!==j.max_depth&&j.max_depth<k)return this._data.core.last_error={error:"check",plugin:"types",id:"types_03",reason:"max_depth prevents function: "+c,data:JSON.stringify({chk:c,pos:g,obj:e&&e.id?e.id:!1,par:f&&f.id?f.id:!1})},!1;f=this.get_node(f.parent),j=this.get_rules(f),k++}while(f)}}return!0},this.get_rules=function(a){if(a=this.get_node(a),!a)return!1;var c=this.get_type(a,!0);return c.max_depth===b&&(c.max_depth=-1),c.max_children===b&&(c.max_children=-1),c.valid_children===b&&(c.valid_children=-1),c},this.get_type=function(b,c){return b=this.get_node(b),b?c?a.extend({type:b.type},this.settings.types[b.type]):b.type:!1},this.set_type=function(c,d){var e=this._model.data,f,g,h,i,j,k,l,m;if(a.isArray(c)){for(c=c.slice(),g=0,h=c.length;h>g;g++)this.set_type(c[g],d);return!0}if(f=this.settings.types,c=this.get_node(c),!f[d]||!c)return!1;if(l=this.get_node(c,!0),l&&l.length&&(m=l.children(".jstree-anchor")),i=c.type,j=this.get_icon(c),c.type=d,(j===!0||f[i]&&f[i].icon!==b&&j===f[i].icon)&&this.set_icon(c,f[d].icon!==b?f[d].icon:!0),f[i].li_attr!==b&&"object"==typeof f[i].li_attr)for(k in f[i].li_attr)if(f[i].li_attr.hasOwnProperty(k)){if("id"===k)continue;"class"===k?(e[c.id].li_attr["class"]=(e[c.id].li_attr["class"]||"").replace(f[i].li_attr[k],""),l&&l.removeClass(f[i].li_attr[k])):e[c.id].li_attr[k]===f[i].li_attr[k]&&(e[c.id].li_attr[k]=null,l&&l.removeAttr(k))}if(f[i].a_attr!==b&&"object"==typeof f[i].a_attr)for(k in f[i].a_attr)if(f[i].a_attr.hasOwnProperty(k)){if("id"===k)continue;"class"===k?(e[c.id].a_attr["class"]=(e[c.id].a_attr["class"]||"").replace(f[i].a_attr[k],""),m&&m.removeClass(f[i].a_attr[k])):e[c.id].a_attr[k]===f[i].a_attr[k]&&("href"===k?(e[c.id].a_attr[k]="#",m&&m.attr("href","#")):(delete e[c.id].a_attr[k],m&&m.removeAttr(k)))}if(f[d].li_attr!==b&&"object"==typeof f[d].li_attr)for(k in f[d].li_attr)if(f[d].li_attr.hasOwnProperty(k)){if("id"===k)continue;e[c.id].li_attr[k]===b?(e[c.id].li_attr[k]=f[d].li_attr[k],l&&("class"===k?l.addClass(f[d].li_attr[k]):l.attr(k,f[d].li_attr[k]))):"class"===k&&(e[c.id].li_attr["class"]=f[d].li_attr[k]+" "+e[c.id].li_attr["class"],l&&l.addClass(f[d].li_attr[k]))}if(f[d].a_attr!==b&&"object"==typeof f[d].a_attr)for(k in f[d].a_attr)if(f[d].a_attr.hasOwnProperty(k)){if("id"===k)continue;e[c.id].a_attr[k]===b?(e[c.id].a_attr[k]=f[d].a_attr[k],m&&("class"===k?m.addClass(f[d].a_attr[k]):m.attr(k,f[d].a_attr[k]))):"href"===k&&"#"===e[c.id].a_attr[k]?(e[c.id].a_attr.href=f[d].a_attr.href,m&&m.attr("href",f[d].a_attr.href)):"class"===k&&(e[c.id].a_attr["class"]=f[d].a_attr["class"]+" "+e[c.id].a_attr["class"],m&&m.addClass(f[d].a_attr[k]))}return!0}},a.jstree.defaults.unique={case_sensitive:!1,duplicate:function(a,b){return a+" ("+b+")"}},a.jstree.plugins.unique=function(c,d){this.check=function(b,c,e,f,g){if(d.check.call(this,b,c,e,f,g)===!1)return!1;if(c=c&&c.id?c:this.get_node(c),e=e&&e.id?e:this.get_node(e),!e||!e.children)return!0;var h="rename_node"===b?f:c.text,i=[],j=this.settings.unique.case_sensitive,k=this._model.data,l,m;for(l=0,m=e.children.length;m>l;l++)i.push(j?k[e.children[l]].text:k[e.children[l]].text.toLowerCase());switch(j||(h=h.toLowerCase()),b){case"delete_node":return!0;case"rename_node":return l=-1===a.inArray(h,i)||c.text&&c.text[j?"toString":"toLowerCase"]()===h,l||(this._data.core.last_error={error:"check",plugin:"unique",id:"unique_01",reason:"Child with name "+h+" already exists. Preventing: "+b,data:JSON.stringify({chk:b,pos:f,obj:c&&c.id?c.id:!1,par:e&&e.id?e.id:!1})}),l;case"create_node":return l=-1===a.inArray(h,i),l||(this._data.core.last_error={error:"check",plugin:"unique",id:"unique_04",reason:"Child with name "+h+" already exists. Preventing: "+b,data:JSON.stringify({chk:b,pos:f,obj:c&&c.id?c.id:!1,par:e&&e.id?e.id:!1})}),l;case"copy_node":return l=-1===a.inArray(h,i),l||(this._data.core.last_error={error:"check",plugin:"unique",
+id:"unique_02",reason:"Child with name "+h+" already exists. Preventing: "+b,data:JSON.stringify({chk:b,pos:f,obj:c&&c.id?c.id:!1,par:e&&e.id?e.id:!1})}),l;case"move_node":return l=c.parent===e.id&&(!g||!g.is_multi)||-1===a.inArray(h,i),l||(this._data.core.last_error={error:"check",plugin:"unique",id:"unique_03",reason:"Child with name "+h+" already exists. Preventing: "+b,data:JSON.stringify({chk:b,pos:f,obj:c&&c.id?c.id:!1,par:e&&e.id?e.id:!1})}),l}return!0},this.create_node=function(c,e,f,g,h){if(!e||e.text===b){if(null===c&&(c=a.jstree.root),c=this.get_node(c),!c)return d.create_node.call(this,c,e,f,g,h);if(f=f===b?"last":f,!f.toString().match(/^(before|after)$/)&&!h&&!this.is_loaded(c))return d.create_node.call(this,c,e,f,g,h);e||(e={});var i,j,k,l,m,n=this._model.data,o=this.settings.unique.case_sensitive,p=this.settings.unique.duplicate;for(j=i=this.get_string("New node"),k=[],l=0,m=c.children.length;m>l;l++)k.push(o?n[c.children[l]].text:n[c.children[l]].text.toLowerCase());l=1;while(-1!==a.inArray(o?j:j.toLowerCase(),k))j=p.call(this,i,++l).toString();e.text=j}return d.create_node.call(this,c,e,f,g,h)}};var q=i.createElement("DIV");if(q.setAttribute("unselectable","on"),q.setAttribute("role","presentation"),q.className="jstree-wholerow",q.innerHTML="&#160;",a.jstree.plugins.wholerow=function(b,c){this.bind=function(){c.bind.call(this),this.element.on("ready.jstree set_state.jstree",a.proxy(function(){this.hide_dots()},this)).on("init.jstree loading.jstree ready.jstree",a.proxy(function(){this.get_container_ul().addClass("jstree-wholerow-ul")},this)).on("deselect_all.jstree",a.proxy(function(a,b){this.element.find(".jstree-wholerow-clicked").removeClass("jstree-wholerow-clicked")},this)).on("changed.jstree",a.proxy(function(a,b){this.element.find(".jstree-wholerow-clicked").removeClass("jstree-wholerow-clicked");var c=!1,d,e;for(d=0,e=b.selected.length;e>d;d++)c=this.get_node(b.selected[d],!0),c&&c.length&&c.children(".jstree-wholerow").addClass("jstree-wholerow-clicked")},this)).on("open_node.jstree",a.proxy(function(a,b){this.get_node(b.node,!0).find(".jstree-clicked").parent().children(".jstree-wholerow").addClass("jstree-wholerow-clicked")},this)).on("hover_node.jstree dehover_node.jstree",a.proxy(function(a,b){"hover_node"===a.type&&this.is_disabled(b.node)||this.get_node(b.node,!0).children(".jstree-wholerow")["hover_node"===a.type?"addClass":"removeClass"]("jstree-wholerow-hovered")},this)).on("contextmenu.jstree",".jstree-wholerow",a.proxy(function(b){if(this._data.contextmenu){b.preventDefault();var c=a.Event("contextmenu",{metaKey:b.metaKey,ctrlKey:b.ctrlKey,altKey:b.altKey,shiftKey:b.shiftKey,pageX:b.pageX,pageY:b.pageY});a(b.currentTarget).closest(".jstree-node").children(".jstree-anchor").first().trigger(c)}},this)).on("click.jstree",".jstree-wholerow",function(b){b.stopImmediatePropagation();var c=a.Event("click",{metaKey:b.metaKey,ctrlKey:b.ctrlKey,altKey:b.altKey,shiftKey:b.shiftKey});a(b.currentTarget).closest(".jstree-node").children(".jstree-anchor").first().trigger(c).focus()}).on("click.jstree",".jstree-leaf > .jstree-ocl",a.proxy(function(b){b.stopImmediatePropagation();var c=a.Event("click",{metaKey:b.metaKey,ctrlKey:b.ctrlKey,altKey:b.altKey,shiftKey:b.shiftKey});a(b.currentTarget).closest(".jstree-node").children(".jstree-anchor").first().trigger(c).focus()},this)).on("mouseover.jstree",".jstree-wholerow, .jstree-icon",a.proxy(function(a){return a.stopImmediatePropagation(),this.is_disabled(a.currentTarget)||this.hover_node(a.currentTarget),!1},this)).on("mouseleave.jstree",".jstree-node",a.proxy(function(a){this.dehover_node(a.currentTarget)},this))},this.teardown=function(){this.settings.wholerow&&this.element.find(".jstree-wholerow").remove(),c.teardown.call(this)},this.redraw_node=function(b,d,e,f){if(b=c.redraw_node.apply(this,arguments)){var g=q.cloneNode(!0);-1!==a.inArray(b.id,this._data.core.selected)&&(g.className+=" jstree-wholerow-clicked"),this._data.core.focused&&this._data.core.focused===b.id&&(g.className+=" jstree-wholerow-hovered"),b.insertBefore(g,b.childNodes[0])}return b}},i.registerElement&&Object&&Object.create){var r=Object.create(HTMLElement.prototype);r.createdCallback=function(){var b={core:{},plugins:[]},c;for(c in a.jstree.plugins)a.jstree.plugins.hasOwnProperty(c)&&this.attributes[c]&&(b.plugins.push(c),this.getAttribute(c)&&JSON.parse(this.getAttribute(c))&&(b[c]=JSON.parse(this.getAttribute(c))));for(c in a.jstree.defaults.core)a.jstree.defaults.core.hasOwnProperty(c)&&this.attributes[c]&&(b.core[c]=JSON.parse(this.getAttribute(c))||this.getAttribute(c));a(this).jstree(b)};try{i.registerElement("vakata-jstree",{prototype:r})}catch(s){}}}}); \ No newline at end of file
diff --git a/ydb/core/viewer/content/style.min.css b/ydb/core/viewer/content/style.min.css
index fe9fc3b4991..0de3b7547ab 100644
--- a/ydb/core/viewer/content/style.min.css
+++ b/ydb/core/viewer/content/style.min.css
@@ -1 +1 @@
-.jstree-node,.jstree-children,.jstree-container-ul{display:block;margin:0;padding:0;list-style-type:none;list-style-image:none}.jstree-node{white-space:nowrap}.jstree-anchor{display:inline-block;color:#000;white-space:nowrap;padding:0 4px 0 1px;margin:0;vertical-align:top}.jstree-anchor:focus{outline:0}.jstree-anchor,.jstree-anchor:link,.jstree-anchor:visited,.jstree-anchor:hover,.jstree-anchor:active{text-decoration:none;color:inherit}.jstree-icon{display:inline-block;text-decoration:none;margin:0;padding:0;vertical-align:top;text-align:center}.jstree-icon:empty{display:inline-block;text-decoration:none;margin:0;padding:0;vertical-align:top;text-align:center}.jstree-ocl{cursor:pointer}.jstree-leaf>.jstree-ocl{cursor:default}.jstree .jstree-open>.jstree-children{display:block}.jstree .jstree-closed>.jstree-children,.jstree .jstree-leaf>.jstree-children{display:none}.jstree-anchor>.jstree-themeicon{margin-right:2px}.jstree-no-icons .jstree-themeicon,.jstree-anchor>.jstree-themeicon-hidden{display:none}.jstree-hidden,.jstree-node.jstree-hidden{display:none}.jstree-rtl .jstree-anchor{padding:0 1px 0 4px}.jstree-rtl .jstree-anchor>.jstree-themeicon{margin-left:2px;margin-right:0}.jstree-rtl .jstree-node{margin-left:0}.jstree-rtl .jstree-container-ul>.jstree-node{margin-right:0}.jstree-wholerow-ul{position:relative;display:inline-block;min-width:100%}.jstree-wholerow-ul .jstree-leaf>.jstree-ocl{cursor:pointer}.jstree-wholerow-ul .jstree-anchor,.jstree-wholerow-ul .jstree-icon{position:relative}.jstree-wholerow-ul .jstree-wholerow{width:100%;cursor:pointer;position:absolute;left:0;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.vakata-context{display:none}.vakata-context,.vakata-context ul{margin:0;padding:2px;position:absolute;background:#f5f5f5;border:1px solid #979797;box-shadow:2px 2px 2px #999}.vakata-context ul{list-style:none;left:100%;margin-top:-2.7em;margin-left:-4px}.vakata-context .vakata-context-right ul{left:auto;right:100%;margin-left:auto;margin-right:-4px}.vakata-context li{list-style:none}.vakata-context li>a{display:block;padding:0 2em;text-decoration:none;width:auto;color:#000;white-space:nowrap;line-height:2.4em;text-shadow:1px 1px 0 #fff;border-radius:1px}.vakata-context li>a:hover{position:relative;background-color:#e8eff7;box-shadow:0 0 2px #0a6aa1}.vakata-context li>a.vakata-context-parent{background-image:url(data:image/gif;base64,R0lGODlhCwAHAIAAACgoKP///yH5BAEAAAEALAAAAAALAAcAAAIORI4JlrqN1oMSnmmZDQUAOw==);background-position:right center;background-repeat:no-repeat}.vakata-context li>a:focus{outline:0}.vakata-context .vakata-context-hover>a{position:relative;background-color:#e8eff7;box-shadow:0 0 2px #0a6aa1}.vakata-context .vakata-context-separator>a,.vakata-context .vakata-context-separator>a:hover{background:#fff;border:0;border-top:1px solid #e2e3e3;height:1px;min-height:1px;max-height:1px;padding:0;margin:0 0 0 2.4em;border-left:1px solid #e0e0e0;text-shadow:0 0 0 transparent;box-shadow:0 0 0 transparent;border-radius:0}.vakata-context .vakata-contextmenu-disabled a,.vakata-context .vakata-contextmenu-disabled a:hover{color:silver;background-color:transparent;border:0;box-shadow:0 0 0}.vakata-context li>a>i{text-decoration:none;display:inline-block;width:2.4em;height:2.4em;background:0 0;margin:0 0 0 -2em;vertical-align:top;text-align:center;line-height:2.4em}.vakata-context li>a>i:empty{width:2.4em;line-height:2.4em}.vakata-context li>a .vakata-contextmenu-sep{display:inline-block;width:1px;height:2.4em;background:#fff;margin:0 .5em 0 0;border-left:1px solid #e2e3e3}.vakata-context .vakata-contextmenu-shortcut{font-size:.8em;color:silver;opacity:.5;display:none}.vakata-context-rtl ul{left:auto;right:100%;margin-left:auto;margin-right:-4px}.vakata-context-rtl li>a.vakata-context-parent{background-image:url(data:image/gif;base64,R0lGODlhCwAHAIAAACgoKP///yH5BAEAAAEALAAAAAALAAcAAAINjI+AC7rWHIsPtmoxLAA7);background-position:left center;background-repeat:no-repeat}.vakata-context-rtl .vakata-context-separator>a{margin:0 2.4em 0 0;border-left:0;border-right:1px solid #e2e3e3}.vakata-context-rtl .vakata-context-left ul{right:auto;left:100%;margin-left:-4px;margin-right:auto}.vakata-context-rtl li>a>i{margin:0 -2em 0 0}.vakata-context-rtl li>a .vakata-contextmenu-sep{margin:0 0 0 .5em;border-left-color:#fff;background:#e2e3e3}#jstree-marker{position:absolute;top:0;left:0;margin:-5px 0 0 0;padding:0;border-right:0;border-top:5px solid transparent;border-bottom:5px solid transparent;border-left:5px solid;width:0;height:0;font-size:0;line-height:0}#jstree-dnd{line-height:16px;margin:0;padding:4px}#jstree-dnd .jstree-icon,#jstree-dnd .jstree-copy{display:inline-block;text-decoration:none;margin:0 2px 0 0;padding:0;width:16px;height:16px}#jstree-dnd .jstree-ok{background:green}#jstree-dnd .jstree-er{background:red}#jstree-dnd .jstree-copy{margin:0 2px}.jstree-default .jstree-node,.jstree-default .jstree-icon{background-repeat:no-repeat;background-color:transparent}.jstree-default .jstree-anchor,.jstree-default .jstree-wholerow{transition:background-color .15s,box-shadow .15s}.jstree-default .jstree-hovered{background:#e7f4f9;border-radius:2px;box-shadow:inset 0 0 1px #ccc}.jstree-default .jstree-context{background:#e7f4f9;border-radius:2px;box-shadow:inset 0 0 1px #ccc}.jstree-default .jstree-clicked{background:#beebff;border-radius:2px;box-shadow:inset 0 0 1px #999}.jstree-default .jstree-no-icons .jstree-anchor>.jstree-themeicon{display:none}.jstree-default .jstree-disabled{background:0 0;color:#666}.jstree-default .jstree-disabled.jstree-hovered{background:0 0;box-shadow:none}.jstree-default .jstree-disabled.jstree-clicked{background:#efefef}.jstree-default .jstree-disabled>.jstree-icon{opacity:.8;filter:url("data:image/svg+xml;utf8,<svg xmlns=\'http://www.w3.org/2000/svg\'><filter id=\'jstree-grayscale\'><feColorMatrix type=\'matrix\' values=\'0.3333 0.3333 0.3333 0 0 0.3333 0.3333 0.3333 0 0 0.3333 0.3333 0.3333 0 0 0 0 0 1 0\'/></filter></svg>#jstree-grayscale");filter:gray;-webkit-filter:grayscale(100%)}.jstree-default .jstree-search{font-style:italic;color:#8b0000;font-weight:700}.jstree-default .jstree-no-checkboxes .jstree-checkbox{display:none!important}.jstree-default.jstree-checkbox-no-clicked .jstree-clicked{background:0 0;box-shadow:none}.jstree-default.jstree-checkbox-no-clicked .jstree-clicked.jstree-hovered{background:#e7f4f9}.jstree-default.jstree-checkbox-no-clicked>.jstree-wholerow-ul .jstree-wholerow-clicked{background:0 0}.jstree-default.jstree-checkbox-no-clicked>.jstree-wholerow-ul .jstree-wholerow-clicked.jstree-wholerow-hovered{background:#e7f4f9}.jstree-default>.jstree-striped{min-width:100%;display:inline-block;background:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAAkCAMAAAB/qqA+AAAABlBMVEUAAAAAAAClZ7nPAAAAAnRSTlMNAMM9s3UAAAAXSURBVHjajcEBAQAAAIKg/H/aCQZ70AUBjAATb6YPDgAAAABJRU5ErkJggg==) left top repeat}.jstree-default>.jstree-wholerow-ul .jstree-hovered,.jstree-default>.jstree-wholerow-ul .jstree-clicked{background:0 0;box-shadow:none;border-radius:0}.jstree-default .jstree-wholerow{-moz-box-sizing:border-box;-webkit-box-sizing:border-box;box-sizing:border-box}.jstree-default .jstree-wholerow-hovered{background:#e7f4f9}.jstree-default .jstree-wholerow-clicked{background:#beebff;background:-webkit-linear-gradient(top,#beebff 0,#a8e4ff 100%);background:linear-gradient(to bottom,#beebff 0,#a8e4ff 100%)}.jstree-default .jstree-node{min-height:24px;line-height:24px;margin-left:24px;min-width:24px}.jstree-default .jstree-anchor{line-height:24px;height:24px}.jstree-default .jstree-icon{width:24px;height:24px;line-height:24px}.jstree-default .jstree-icon:empty{width:24px;height:24px;line-height:24px}.jstree-default.jstree-rtl .jstree-node{margin-right:24px}.jstree-default .jstree-wholerow{height:24px}.jstree-default .jstree-node,.jstree-default .jstree-icon{background-image:url(32px.png)}.jstree-default .jstree-node{background-position:-292px -4px;background-repeat:repeat-y}.jstree-default .jstree-last{background:0 0}.jstree-default .jstree-open>.jstree-ocl{background-position:-132px -4px}.jstree-default .jstree-closed>.jstree-ocl{background-position:-100px -4px}.jstree-default .jstree-leaf>.jstree-ocl{background-position:-68px -4px}.jstree-default .jstree-themeicon{background-position:-260px -4px}.jstree-default>.jstree-no-dots .jstree-node,.jstree-default>.jstree-no-dots .jstree-leaf>.jstree-ocl{background:0 0}.jstree-default>.jstree-no-dots .jstree-open>.jstree-ocl{background-position:-36px -4px}.jstree-default>.jstree-no-dots .jstree-closed>.jstree-ocl{background-position:-4px -4px}.jstree-default .jstree-disabled{background:0 0}.jstree-default .jstree-disabled.jstree-hovered{background:0 0}.jstree-default .jstree-disabled.jstree-clicked{background:#efefef}.jstree-default .jstree-checkbox{background-position:-164px -4px}.jstree-default .jstree-checkbox:hover{background-position:-164px -36px}.jstree-default.jstree-checkbox-selection .jstree-clicked>.jstree-checkbox,.jstree-default .jstree-checked>.jstree-checkbox{background-position:-228px -4px}.jstree-default.jstree-checkbox-selection .jstree-clicked>.jstree-checkbox:hover,.jstree-default .jstree-checked>.jstree-checkbox:hover{background-position:-228px -36px}.jstree-default .jstree-anchor>.jstree-undetermined{background-position:-196px -4px}.jstree-default .jstree-anchor>.jstree-undetermined:hover{background-position:-196px -36px}.jstree-default .jstree-checkbox-disabled{opacity:.8;filter:url("data:image/svg+xml;utf8,<svg xmlns=\'http://www.w3.org/2000/svg\'><filter id=\'jstree-grayscale\'><feColorMatrix type=\'matrix\' values=\'0.3333 0.3333 0.3333 0 0 0.3333 0.3333 0.3333 0 0 0.3333 0.3333 0.3333 0 0 0 0 0 1 0\'/></filter></svg>#jstree-grayscale");filter:gray;-webkit-filter:grayscale(100%)}.jstree-default>.jstree-striped{background-size:auto 48px}.jstree-default.jstree-rtl .jstree-node{background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAACAQMAAAB49I5GAAAABlBMVEUAAAAdHRvEkCwcAAAAAXRSTlMAQObYZgAAAAxJREFUCNdjAAMOBgAAGAAJMwQHdQAAAABJRU5ErkJggg==);background-position:100% 1px;background-repeat:repeat-y}.jstree-default.jstree-rtl .jstree-last{background:0 0}.jstree-default.jstree-rtl .jstree-open>.jstree-ocl{background-position:-132px -36px}.jstree-default.jstree-rtl .jstree-closed>.jstree-ocl{background-position:-100px -36px}.jstree-default.jstree-rtl .jstree-leaf>.jstree-ocl{background-position:-68px -36px}.jstree-default.jstree-rtl>.jstree-no-dots .jstree-node,.jstree-default.jstree-rtl>.jstree-no-dots .jstree-leaf>.jstree-ocl{background:0 0}.jstree-default.jstree-rtl>.jstree-no-dots .jstree-open>.jstree-ocl{background-position:-36px -36px}.jstree-default.jstree-rtl>.jstree-no-dots .jstree-closed>.jstree-ocl{background-position:-4px -36px}.jstree-default .jstree-themeicon-custom{background-color:transparent;background-image:none;background-position:0 0}.jstree-default>.jstree-container-ul .jstree-loading>.jstree-ocl{background:url(throbber.gif) center center no-repeat}.jstree-default .jstree-file{background:url(32px.png) -100px -68px no-repeat}.jstree-default .jstree-folder{background:url(32px.png) -260px -4px no-repeat}.jstree-default>.jstree-container-ul>.jstree-node{margin-left:0;margin-right:0}#jstree-dnd.jstree-default{line-height:24px;padding:0 4px}#jstree-dnd.jstree-default .jstree-ok,#jstree-dnd.jstree-default .jstree-er{background-image:url(32px.png);background-repeat:no-repeat;background-color:transparent}#jstree-dnd.jstree-default i{background:0 0;width:24px;height:24px;line-height:24px}#jstree-dnd.jstree-default .jstree-ok{background-position:-4px -68px}#jstree-dnd.jstree-default .jstree-er{background-position:-36px -68px}.jstree-default.jstree-rtl .jstree-node{background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAACAQMAAAB49I5GAAAABlBMVEUAAAAdHRvEkCwcAAAAAXRSTlMAQObYZgAAAAxJREFUCNdjAAMOBgAAGAAJMwQHdQAAAABJRU5ErkJggg==)}.jstree-default.jstree-rtl .jstree-last{background:0 0}.jstree-default-small .jstree-node{min-height:18px;line-height:18px;margin-left:18px;min-width:18px}.jstree-default-small .jstree-anchor{line-height:18px;height:18px}.jstree-default-small .jstree-icon{width:18px;height:18px;line-height:18px}.jstree-default-small .jstree-icon:empty{width:18px;height:18px;line-height:18px}.jstree-default-small.jstree-rtl .jstree-node{margin-right:18px}.jstree-default-small .jstree-wholerow{height:18px}.jstree-default-small .jstree-node,.jstree-default-small .jstree-icon{background-image:url(32px.png)}.jstree-default-small .jstree-node{background-position:-295px -7px;background-repeat:repeat-y}.jstree-default-small .jstree-last{background:0 0}.jstree-default-small .jstree-open>.jstree-ocl{background-position:-135px -7px}.jstree-default-small .jstree-closed>.jstree-ocl{background-position:-103px -7px}.jstree-default-small .jstree-leaf>.jstree-ocl{background-position:-71px -7px}.jstree-default-small .jstree-themeicon{background-position:-263px -7px}.jstree-default-small>.jstree-no-dots .jstree-node,.jstree-default-small>.jstree-no-dots .jstree-leaf>.jstree-ocl{background:0 0}.jstree-default-small>.jstree-no-dots .jstree-open>.jstree-ocl{background-position:-39px -7px}.jstree-default-small>.jstree-no-dots .jstree-closed>.jstree-ocl{background-position:-7px -7px}.jstree-default-small .jstree-disabled{background:0 0}.jstree-default-small .jstree-disabled.jstree-hovered{background:0 0}.jstree-default-small .jstree-disabled.jstree-clicked{background:#efefef}.jstree-default-small .jstree-checkbox{background-position:-167px -7px}.jstree-default-small .jstree-checkbox:hover{background-position:-167px -39px}.jstree-default-small.jstree-checkbox-selection .jstree-clicked>.jstree-checkbox,.jstree-default-small .jstree-checked>.jstree-checkbox{background-position:-231px -7px}.jstree-default-small.jstree-checkbox-selection .jstree-clicked>.jstree-checkbox:hover,.jstree-default-small .jstree-checked>.jstree-checkbox:hover{background-position:-231px -39px}.jstree-default-small .jstree-anchor>.jstree-undetermined{background-position:-199px -7px}.jstree-default-small .jstree-anchor>.jstree-undetermined:hover{background-position:-199px -39px}.jstree-default-small .jstree-checkbox-disabled{opacity:.8;filter:url("data:image/svg+xml;utf8,<svg xmlns=\'http://www.w3.org/2000/svg\'><filter id=\'jstree-grayscale\'><feColorMatrix type=\'matrix\' values=\'0.3333 0.3333 0.3333 0 0 0.3333 0.3333 0.3333 0 0 0.3333 0.3333 0.3333 0 0 0 0 0 1 0\'/></filter></svg>#jstree-grayscale");filter:gray;-webkit-filter:grayscale(100%)}.jstree-default-small>.jstree-striped{background-size:auto 36px}.jstree-default-small.jstree-rtl .jstree-node{background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAACAQMAAAB49I5GAAAABlBMVEUAAAAdHRvEkCwcAAAAAXRSTlMAQObYZgAAAAxJREFUCNdjAAMOBgAAGAAJMwQHdQAAAABJRU5ErkJggg==);background-position:100% 1px;background-repeat:repeat-y}.jstree-default-small.jstree-rtl .jstree-last{background:0 0}.jstree-default-small.jstree-rtl .jstree-open>.jstree-ocl{background-position:-135px -39px}.jstree-default-small.jstree-rtl .jstree-closed>.jstree-ocl{background-position:-103px -39px}.jstree-default-small.jstree-rtl .jstree-leaf>.jstree-ocl{background-position:-71px -39px}.jstree-default-small.jstree-rtl>.jstree-no-dots .jstree-node,.jstree-default-small.jstree-rtl>.jstree-no-dots .jstree-leaf>.jstree-ocl{background:0 0}.jstree-default-small.jstree-rtl>.jstree-no-dots .jstree-open>.jstree-ocl{background-position:-39px -39px}.jstree-default-small.jstree-rtl>.jstree-no-dots .jstree-closed>.jstree-ocl{background-position:-7px -39px}.jstree-default-small .jstree-themeicon-custom{background-color:transparent;background-image:none;background-position:0 0}.jstree-default-small>.jstree-container-ul .jstree-loading>.jstree-ocl{background:url(throbber.gif) center center no-repeat}.jstree-default-small .jstree-file{background:url(32px.png) -103px -71px no-repeat}.jstree-default-small .jstree-folder{background:url(32px.png) -263px -7px no-repeat}.jstree-default-small>.jstree-container-ul>.jstree-node{margin-left:0;margin-right:0}#jstree-dnd.jstree-default-small{line-height:18px;padding:0 4px}#jstree-dnd.jstree-default-small .jstree-ok,#jstree-dnd.jstree-default-small .jstree-er{background-image:url(32px.png);background-repeat:no-repeat;background-color:transparent}#jstree-dnd.jstree-default-small i{background:0 0;width:18px;height:18px;line-height:18px}#jstree-dnd.jstree-default-small .jstree-ok{background-position:-7px -71px}#jstree-dnd.jstree-default-small .jstree-er{background-position:-39px -71px}.jstree-default-small.jstree-rtl .jstree-node{background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABIAAAACAQMAAABv1h6PAAAABlBMVEUAAAAdHRvEkCwcAAAAAXRSTlMAQObYZgAAAAxJREFUCNdjAAMHBgAAiABBI4gz9AAAAABJRU5ErkJggg==)}.jstree-default-small.jstree-rtl .jstree-last{background:0 0}.jstree-default-large .jstree-node{min-height:32px;line-height:32px;margin-left:32px;min-width:32px}.jstree-default-large .jstree-anchor{line-height:32px;height:32px}.jstree-default-large .jstree-icon{width:32px;height:32px;line-height:32px}.jstree-default-large .jstree-icon:empty{width:32px;height:32px;line-height:32px}.jstree-default-large.jstree-rtl .jstree-node{margin-right:32px}.jstree-default-large .jstree-wholerow{height:32px}.jstree-default-large .jstree-node,.jstree-default-large .jstree-icon{background-image:url(32px.png)}.jstree-default-large .jstree-node{background-position:-288px 0;background-repeat:repeat-y}.jstree-default-large .jstree-last{background:0 0}.jstree-default-large .jstree-open>.jstree-ocl{background-position:-128px 0}.jstree-default-large .jstree-closed>.jstree-ocl{background-position:-96px 0}.jstree-default-large .jstree-leaf>.jstree-ocl{background-position:-64px 0}.jstree-default-large .jstree-themeicon{background-position:-256px 0}.jstree-default-large>.jstree-no-dots .jstree-node,.jstree-default-large>.jstree-no-dots .jstree-leaf>.jstree-ocl{background:0 0}.jstree-default-large>.jstree-no-dots .jstree-open>.jstree-ocl{background-position:-32px 0}.jstree-default-large>.jstree-no-dots .jstree-closed>.jstree-ocl{background-position:0 0}.jstree-default-large .jstree-disabled{background:0 0}.jstree-default-large .jstree-disabled.jstree-hovered{background:0 0}.jstree-default-large .jstree-disabled.jstree-clicked{background:#efefef}.jstree-default-large .jstree-checkbox{background-position:-160px 0}.jstree-default-large .jstree-checkbox:hover{background-position:-160px -32px}.jstree-default-large.jstree-checkbox-selection .jstree-clicked>.jstree-checkbox,.jstree-default-large .jstree-checked>.jstree-checkbox{background-position:-224px 0}.jstree-default-large.jstree-checkbox-selection .jstree-clicked>.jstree-checkbox:hover,.jstree-default-large .jstree-checked>.jstree-checkbox:hover{background-position:-224px -32px}.jstree-default-large .jstree-anchor>.jstree-undetermined{background-position:-192px 0}.jstree-default-large .jstree-anchor>.jstree-undetermined:hover{background-position:-192px -32px}.jstree-default-large .jstree-checkbox-disabled{opacity:.8;filter:url("data:image/svg+xml;utf8,<svg xmlns=\'http://www.w3.org/2000/svg\'><filter id=\'jstree-grayscale\'><feColorMatrix type=\'matrix\' values=\'0.3333 0.3333 0.3333 0 0 0.3333 0.3333 0.3333 0 0 0.3333 0.3333 0.3333 0 0 0 0 0 1 0\'/></filter></svg>#jstree-grayscale");filter:gray;-webkit-filter:grayscale(100%)}.jstree-default-large>.jstree-striped{background-size:auto 64px}.jstree-default-large.jstree-rtl .jstree-node{background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAACAQMAAAB49I5GAAAABlBMVEUAAAAdHRvEkCwcAAAAAXRSTlMAQObYZgAAAAxJREFUCNdjAAMOBgAAGAAJMwQHdQAAAABJRU5ErkJggg==);background-position:100% 1px;background-repeat:repeat-y}.jstree-default-large.jstree-rtl .jstree-last{background:0 0}.jstree-default-large.jstree-rtl .jstree-open>.jstree-ocl{background-position:-128px -32px}.jstree-default-large.jstree-rtl .jstree-closed>.jstree-ocl{background-position:-96px -32px}.jstree-default-large.jstree-rtl .jstree-leaf>.jstree-ocl{background-position:-64px -32px}.jstree-default-large.jstree-rtl>.jstree-no-dots .jstree-node,.jstree-default-large.jstree-rtl>.jstree-no-dots .jstree-leaf>.jstree-ocl{background:0 0}.jstree-default-large.jstree-rtl>.jstree-no-dots .jstree-open>.jstree-ocl{background-position:-32px -32px}.jstree-default-large.jstree-rtl>.jstree-no-dots .jstree-closed>.jstree-ocl{background-position:0 -32px}.jstree-default-large .jstree-themeicon-custom{background-color:transparent;background-image:none;background-position:0 0}.jstree-default-large>.jstree-container-ul .jstree-loading>.jstree-ocl{background:url(throbber.gif) center center no-repeat}.jstree-default-large .jstree-file{background:url(32px.png) -96px -64px no-repeat}.jstree-default-large .jstree-folder{background:url(32px.png) -256px 0 no-repeat}.jstree-default-large>.jstree-container-ul>.jstree-node{margin-left:0;margin-right:0}#jstree-dnd.jstree-default-large{line-height:32px;padding:0 4px}#jstree-dnd.jstree-default-large .jstree-ok,#jstree-dnd.jstree-default-large .jstree-er{background-image:url(32px.png);background-repeat:no-repeat;background-color:transparent}#jstree-dnd.jstree-default-large i{background:0 0;width:32px;height:32px;line-height:32px}#jstree-dnd.jstree-default-large .jstree-ok{background-position:0 -64px}#jstree-dnd.jstree-default-large .jstree-er{background-position:-32px -64px}.jstree-default-large.jstree-rtl .jstree-node{background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAACAQMAAAAD0EyKAAAABlBMVEUAAAAdHRvEkCwcAAAAAXRSTlMAQObYZgAAAAxJREFUCNdjgIIGBgABCgCBvVLXcAAAAABJRU5ErkJggg==)}.jstree-default-large.jstree-rtl .jstree-last{background:0 0}@media (max-width:768px){#jstree-dnd.jstree-dnd-responsive{line-height:40px;font-weight:700;font-size:1.1em;text-shadow:1px 1px #fff}#jstree-dnd.jstree-dnd-responsive>i{background:0 0;width:40px;height:40px}#jstree-dnd.jstree-dnd-responsive>.jstree-ok{background-image:url(40px.png);background-position:0 -200px;background-size:120px 240px}#jstree-dnd.jstree-dnd-responsive>.jstree-er{background-image:url(40px.png);background-position:-40px -200px;background-size:120px 240px}#jstree-marker.jstree-dnd-responsive{border-left-width:10px;border-top-width:10px;border-bottom-width:10px;margin-top:-10px}}@media (max-width:768px){.jstree-default-responsive .jstree-icon{background-image:url(40px.png)}.jstree-default-responsive .jstree-node,.jstree-default-responsive .jstree-leaf>.jstree-ocl{background:0 0}.jstree-default-responsive .jstree-node{min-height:40px;line-height:40px;margin-left:40px;min-width:40px;white-space:nowrap}.jstree-default-responsive .jstree-anchor{line-height:40px;height:40px}.jstree-default-responsive .jstree-icon,.jstree-default-responsive .jstree-icon:empty{width:40px;height:40px;line-height:40px}.jstree-default-responsive>.jstree-container-ul>.jstree-node{margin-left:0}.jstree-default-responsive.jstree-rtl .jstree-node{margin-left:0;margin-right:40px;background:0 0}.jstree-default-responsive.jstree-rtl .jstree-container-ul>.jstree-node{margin-right:0}.jstree-default-responsive .jstree-ocl,.jstree-default-responsive .jstree-themeicon,.jstree-default-responsive .jstree-checkbox{background-size:120px 240px}.jstree-default-responsive .jstree-leaf>.jstree-ocl,.jstree-default-responsive.jstree-rtl .jstree-leaf>.jstree-ocl{background:0 0}.jstree-default-responsive .jstree-open>.jstree-ocl{background-position:0 0!important}.jstree-default-responsive .jstree-closed>.jstree-ocl{background-position:0 -40px!important}.jstree-default-responsive.jstree-rtl .jstree-closed>.jstree-ocl{background-position:-40px 0!important}.jstree-default-responsive .jstree-themeicon{background-position:-40px -40px}.jstree-default-responsive .jstree-checkbox,.jstree-default-responsive .jstree-checkbox:hover{background-position:-40px -80px}.jstree-default-responsive.jstree-checkbox-selection .jstree-clicked>.jstree-checkbox,.jstree-default-responsive.jstree-checkbox-selection .jstree-clicked>.jstree-checkbox:hover,.jstree-default-responsive .jstree-checked>.jstree-checkbox,.jstree-default-responsive .jstree-checked>.jstree-checkbox:hover{background-position:0 -80px}.jstree-default-responsive .jstree-anchor>.jstree-undetermined,.jstree-default-responsive .jstree-anchor>.jstree-undetermined:hover{background-position:0 -120px}.jstree-default-responsive .jstree-anchor{font-weight:700;font-size:1.1em;text-shadow:1px 1px #fff}.jstree-default-responsive>.jstree-striped{background:0 0}.jstree-default-responsive .jstree-wholerow{border-top:1px solid rgba(255,255,255,.7);border-bottom:1px solid rgba(64,64,64,.2);background:#ebebeb;height:40px}.jstree-default-responsive .jstree-wholerow-hovered{background:#e7f4f9}.jstree-default-responsive .jstree-wholerow-clicked{background:#beebff}.jstree-default-responsive .jstree-children .jstree-last>.jstree-wholerow{box-shadow:inset 0 -6px 3px -5px #666}.jstree-default-responsive .jstree-children .jstree-open>.jstree-wholerow{box-shadow:inset 0 6px 3px -5px #666;border-top:0}.jstree-default-responsive .jstree-children .jstree-open+.jstree-open{box-shadow:none}.jstree-default-responsive .jstree-node,.jstree-default-responsive .jstree-icon,.jstree-default-responsive .jstree-node>.jstree-ocl,.jstree-default-responsive .jstree-themeicon,.jstree-default-responsive .jstree-checkbox{background-image:url(40px.png);background-size:120px 240px}.jstree-default-responsive .jstree-node{background-position:-80px 0;background-repeat:repeat-y}.jstree-default-responsive .jstree-last{background:0 0}.jstree-default-responsive .jstree-leaf>.jstree-ocl{background-position:-40px -120px}.jstree-default-responsive .jstree-last>.jstree-ocl{background-position:-40px -160px}.jstree-default-responsive .jstree-themeicon-custom{background-color:transparent;background-image:none;background-position:0 0}.jstree-default-responsive .jstree-file{background:url(40px.png) 0 -160px no-repeat;background-size:120px 240px}.jstree-default-responsive .jstree-folder{background:url(40px.png) -40px -40px no-repeat;background-size:120px 240px}.jstree-default-responsive>.jstree-container-ul>.jstree-node{margin-left:0;margin-right:0}} \ No newline at end of file
+.jstree-node,.jstree-children,.jstree-container-ul{display:block;margin:0;padding:0;list-style-type:none;list-style-image:none}.jstree-node{white-space:nowrap}.jstree-anchor{display:inline-block;color:#000;white-space:nowrap;padding:0 4px 0 1px;margin:0;vertical-align:top}.jstree-anchor:focus{outline:0}.jstree-anchor,.jstree-anchor:link,.jstree-anchor:visited,.jstree-anchor:hover,.jstree-anchor:active{text-decoration:none;color:inherit}.jstree-icon{display:inline-block;text-decoration:none;margin:0;padding:0;vertical-align:top;text-align:center}.jstree-icon:empty{display:inline-block;text-decoration:none;margin:0;padding:0;vertical-align:top;text-align:center}.jstree-ocl{cursor:pointer}.jstree-leaf>.jstree-ocl{cursor:default}.jstree .jstree-open>.jstree-children{display:block}.jstree .jstree-closed>.jstree-children,.jstree .jstree-leaf>.jstree-children{display:none}.jstree-anchor>.jstree-themeicon{margin-right:2px}.jstree-no-icons .jstree-themeicon,.jstree-anchor>.jstree-themeicon-hidden{display:none}.jstree-hidden,.jstree-node.jstree-hidden{display:none}.jstree-rtl .jstree-anchor{padding:0 1px 0 4px}.jstree-rtl .jstree-anchor>.jstree-themeicon{margin-left:2px;margin-right:0}.jstree-rtl .jstree-node{margin-left:0}.jstree-rtl .jstree-container-ul>.jstree-node{margin-right:0}.jstree-wholerow-ul{position:relative;display:inline-block;min-width:100%}.jstree-wholerow-ul .jstree-leaf>.jstree-ocl{cursor:pointer}.jstree-wholerow-ul .jstree-anchor,.jstree-wholerow-ul .jstree-icon{position:relative}.jstree-wholerow-ul .jstree-wholerow{width:100%;cursor:pointer;position:absolute;left:0;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.vakata-context{display:none}.vakata-context,.vakata-context ul{margin:0;padding:2px;position:absolute;background:#f5f5f5;border:1px solid #979797;box-shadow:2px 2px 2px #999}.vakata-context ul{list-style:none;left:100%;margin-top:-2.7em;margin-left:-4px}.vakata-context .vakata-context-right ul{left:auto;right:100%;margin-left:auto;margin-right:-4px}.vakata-context li{list-style:none}.vakata-context li>a{display:block;padding:0 2em;text-decoration:none;width:auto;color:#000;white-space:nowrap;line-height:2.4em;text-shadow:1px 1px 0 #fff;border-radius:1px}.vakata-context li>a:hover{position:relative;background-color:#e8eff7;box-shadow:0 0 2px #0a6aa1}.vakata-context li>a.vakata-context-parent{background-image:url(data:image/gif;base64,R0lGODlhCwAHAIAAACgoKP///yH5BAEAAAEALAAAAAALAAcAAAIORI4JlrqN1oMSnmmZDQUAOw==);background-position:right center;background-repeat:no-repeat}.vakata-context li>a:focus{outline:0}.vakata-context .vakata-context-hover>a{position:relative;background-color:#e8eff7;box-shadow:0 0 2px #0a6aa1}.vakata-context .vakata-context-separator>a,.vakata-context .vakata-context-separator>a:hover{background:#fff;border:0;border-top:1px solid #e2e3e3;height:1px;min-height:1px;max-height:1px;padding:0;margin:0 0 0 2.4em;border-left:1px solid #e0e0e0;text-shadow:0 0 0 transparent;box-shadow:0 0 0 transparent;border-radius:0}.vakata-context .vakata-contextmenu-disabled a,.vakata-context .vakata-contextmenu-disabled a:hover{color:silver;background-color:transparent;border:0;box-shadow:0 0 0}.vakata-context li>a>i{text-decoration:none;display:inline-block;width:2.4em;height:2.4em;background:0 0;margin:0 0 0 -2em;vertical-align:top;text-align:center;line-height:2.4em}.vakata-context li>a>i:empty{width:2.4em;line-height:2.4em}.vakata-context li>a .vakata-contextmenu-sep{display:inline-block;width:1px;height:2.4em;background:#fff;margin:0 .5em 0 0;border-left:1px solid #e2e3e3}.vakata-context .vakata-contextmenu-shortcut{font-size:.8em;color:silver;opacity:.5;display:none}.vakata-context-rtl ul{left:auto;right:100%;margin-left:auto;margin-right:-4px}.vakata-context-rtl li>a.vakata-context-parent{background-image:url(data:image/gif;base64,R0lGODlhCwAHAIAAACgoKP///yH5BAEAAAEALAAAAAALAAcAAAINjI+AC7rWHIsPtmoxLAA7);background-position:left center;background-repeat:no-repeat}.vakata-context-rtl .vakata-context-separator>a{margin:0 2.4em 0 0;border-left:0;border-right:1px solid #e2e3e3}.vakata-context-rtl .vakata-context-left ul{right:auto;left:100%;margin-left:-4px;margin-right:auto}.vakata-context-rtl li>a>i{margin:0 -2em 0 0}.vakata-context-rtl li>a .vakata-contextmenu-sep{margin:0 0 0 .5em;border-left-color:#fff;background:#e2e3e3}#jstree-marker{position:absolute;top:0;left:0;margin:-5px 0 0 0;padding:0;border-right:0;border-top:5px solid transparent;border-bottom:5px solid transparent;border-left:5px solid;width:0;height:0;font-size:0;line-height:0}#jstree-dnd{line-height:16px;margin:0;padding:4px}#jstree-dnd .jstree-icon,#jstree-dnd .jstree-copy{display:inline-block;text-decoration:none;margin:0 2px 0 0;padding:0;width:16px;height:16px}#jstree-dnd .jstree-ok{background:green}#jstree-dnd .jstree-er{background:red}#jstree-dnd .jstree-copy{margin:0 2px}.jstree-default .jstree-node,.jstree-default .jstree-icon{background-repeat:no-repeat;background-color:transparent}.jstree-default .jstree-anchor,.jstree-default .jstree-wholerow{transition:background-color .15s,box-shadow .15s}.jstree-default .jstree-hovered{background:#e7f4f9;border-radius:2px;box-shadow:inset 0 0 1px #ccc}.jstree-default .jstree-context{background:#e7f4f9;border-radius:2px;box-shadow:inset 0 0 1px #ccc}.jstree-default .jstree-clicked{background:#beebff;border-radius:2px;box-shadow:inset 0 0 1px #999}.jstree-default .jstree-no-icons .jstree-anchor>.jstree-themeicon{display:none}.jstree-default .jstree-disabled{background:0 0;color:#666}.jstree-default .jstree-disabled.jstree-hovered{background:0 0;box-shadow:none}.jstree-default .jstree-disabled.jstree-clicked{background:#efefef}.jstree-default .jstree-disabled>.jstree-icon{opacity:.8;filter:url("data:image/svg+xml;utf8,<svg xmlns=\'http://www.w3.org/2000/svg\'><filter id=\'jstree-grayscale\'><feColorMatrix type=\'matrix\' values=\'0.3333 0.3333 0.3333 0 0 0.3333 0.3333 0.3333 0 0 0.3333 0.3333 0.3333 0 0 0 0 0 1 0\'/></filter></svg>#jstree-grayscale");filter:gray;-webkit-filter:grayscale(100%)}.jstree-default .jstree-search{font-style:italic;color:#8b0000;font-weight:700}.jstree-default .jstree-no-checkboxes .jstree-checkbox{display:none!important}.jstree-default.jstree-checkbox-no-clicked .jstree-clicked{background:0 0;box-shadow:none}.jstree-default.jstree-checkbox-no-clicked .jstree-clicked.jstree-hovered{background:#e7f4f9}.jstree-default.jstree-checkbox-no-clicked>.jstree-wholerow-ul .jstree-wholerow-clicked{background:0 0}.jstree-default.jstree-checkbox-no-clicked>.jstree-wholerow-ul .jstree-wholerow-clicked.jstree-wholerow-hovered{background:#e7f4f9}.jstree-default>.jstree-striped{min-width:100%;display:inline-block;background:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAAkCAMAAAB/qqA+AAAABlBMVEUAAAAAAAClZ7nPAAAAAnRSTlMNAMM9s3UAAAAXSURBVHjajcEBAQAAAIKg/H/aCQZ70AUBjAATb6YPDgAAAABJRU5ErkJggg==) left top repeat}.jstree-default>.jstree-wholerow-ul .jstree-hovered,.jstree-default>.jstree-wholerow-ul .jstree-clicked{background:0 0;box-shadow:none;border-radius:0}.jstree-default .jstree-wholerow{-moz-box-sizing:border-box;-webkit-box-sizing:border-box;box-sizing:border-box}.jstree-default .jstree-wholerow-hovered{background:#e7f4f9}.jstree-default .jstree-wholerow-clicked{background:#beebff;background:-webkit-linear-gradient(top,#beebff 0,#a8e4ff 100%);background:linear-gradient(to bottom,#beebff 0,#a8e4ff 100%)}.jstree-default .jstree-node{min-height:24px;line-height:24px;margin-left:24px;min-width:24px}.jstree-default .jstree-anchor{line-height:24px;height:24px}.jstree-default .jstree-icon{width:24px;height:24px;line-height:24px}.jstree-default .jstree-icon:empty{width:24px;height:24px;line-height:24px}.jstree-default.jstree-rtl .jstree-node{margin-right:24px}.jstree-default .jstree-wholerow{height:24px}.jstree-default .jstree-node,.jstree-default .jstree-icon{background-image:url(32px.png)}.jstree-default .jstree-node{background-position:-292px -4px;background-repeat:repeat-y}.jstree-default .jstree-last{background:0 0}.jstree-default .jstree-open>.jstree-ocl{background-position:-132px -4px}.jstree-default .jstree-closed>.jstree-ocl{background-position:-100px -4px}.jstree-default .jstree-leaf>.jstree-ocl{background-position:-68px -4px}.jstree-default .jstree-themeicon{background-position:-260px -4px}.jstree-default>.jstree-no-dots .jstree-node,.jstree-default>.jstree-no-dots .jstree-leaf>.jstree-ocl{background:0 0}.jstree-default>.jstree-no-dots .jstree-open>.jstree-ocl{background-position:-36px -4px}.jstree-default>.jstree-no-dots .jstree-closed>.jstree-ocl{background-position:-4px -4px}.jstree-default .jstree-disabled{background:0 0}.jstree-default .jstree-disabled.jstree-hovered{background:0 0}.jstree-default .jstree-disabled.jstree-clicked{background:#efefef}.jstree-default .jstree-checkbox{background-position:-164px -4px}.jstree-default .jstree-checkbox:hover{background-position:-164px -36px}.jstree-default.jstree-checkbox-selection .jstree-clicked>.jstree-checkbox,.jstree-default .jstree-checked>.jstree-checkbox{background-position:-228px -4px}.jstree-default.jstree-checkbox-selection .jstree-clicked>.jstree-checkbox:hover,.jstree-default .jstree-checked>.jstree-checkbox:hover{background-position:-228px -36px}.jstree-default .jstree-anchor>.jstree-undetermined{background-position:-196px -4px}.jstree-default .jstree-anchor>.jstree-undetermined:hover{background-position:-196px -36px}.jstree-default .jstree-checkbox-disabled{opacity:.8;filter:url("data:image/svg+xml;utf8,<svg xmlns=\'http://www.w3.org/2000/svg\'><filter id=\'jstree-grayscale\'><feColorMatrix type=\'matrix\' values=\'0.3333 0.3333 0.3333 0 0 0.3333 0.3333 0.3333 0 0 0.3333 0.3333 0.3333 0 0 0 0 0 1 0\'/></filter></svg>#jstree-grayscale");filter:gray;-webkit-filter:grayscale(100%)}.jstree-default>.jstree-striped{background-size:auto 48px}.jstree-default.jstree-rtl .jstree-node{background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAACAQMAAAB49I5GAAAABlBMVEUAAAAdHRvEkCwcAAAAAXRSTlMAQObYZgAAAAxJREFUCNdjAAMOBgAAGAAJMwQHdQAAAABJRU5ErkJggg==);background-position:100% 1px;background-repeat:repeat-y}.jstree-default.jstree-rtl .jstree-last{background:0 0}.jstree-default.jstree-rtl .jstree-open>.jstree-ocl{background-position:-132px -36px}.jstree-default.jstree-rtl .jstree-closed>.jstree-ocl{background-position:-100px -36px}.jstree-default.jstree-rtl .jstree-leaf>.jstree-ocl{background-position:-68px -36px}.jstree-default.jstree-rtl>.jstree-no-dots .jstree-node,.jstree-default.jstree-rtl>.jstree-no-dots .jstree-leaf>.jstree-ocl{background:0 0}.jstree-default.jstree-rtl>.jstree-no-dots .jstree-open>.jstree-ocl{background-position:-36px -36px}.jstree-default.jstree-rtl>.jstree-no-dots .jstree-closed>.jstree-ocl{background-position:-4px -36px}.jstree-default .jstree-themeicon-custom{background-color:transparent;background-image:none;background-position:0 0}.jstree-default>.jstree-container-ul .jstree-loading>.jstree-ocl{background:url(throbber.gif) center center no-repeat}.jstree-default .jstree-file{background:url(32px.png) -100px -68px no-repeat}.jstree-default .jstree-folder{background:url(32px.png) -260px -4px no-repeat}.jstree-default>.jstree-container-ul>.jstree-node{margin-left:0;margin-right:0}#jstree-dnd.jstree-default{line-height:24px;padding:0 4px}#jstree-dnd.jstree-default .jstree-ok,#jstree-dnd.jstree-default .jstree-er{background-image:url(32px.png);background-repeat:no-repeat;background-color:transparent}#jstree-dnd.jstree-default i{background:0 0;width:24px;height:24px;line-height:24px}#jstree-dnd.jstree-default .jstree-ok{background-position:-4px -68px}#jstree-dnd.jstree-default .jstree-er{background-position:-36px -68px}.jstree-default.jstree-rtl .jstree-node{background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAACAQMAAAB49I5GAAAABlBMVEUAAAAdHRvEkCwcAAAAAXRSTlMAQObYZgAAAAxJREFUCNdjAAMOBgAAGAAJMwQHdQAAAABJRU5ErkJggg==)}.jstree-default.jstree-rtl .jstree-last{background:0 0}.jstree-default-small .jstree-node{min-height:18px;line-height:18px;margin-left:18px;min-width:18px}.jstree-default-small .jstree-anchor{line-height:18px;height:18px}.jstree-default-small .jstree-icon{width:18px;height:18px;line-height:18px}.jstree-default-small .jstree-icon:empty{width:18px;height:18px;line-height:18px}.jstree-default-small.jstree-rtl .jstree-node{margin-right:18px}.jstree-default-small .jstree-wholerow{height:18px}.jstree-default-small .jstree-node,.jstree-default-small .jstree-icon{background-image:url(32px.png)}.jstree-default-small .jstree-node{background-position:-295px -7px;background-repeat:repeat-y}.jstree-default-small .jstree-last{background:0 0}.jstree-default-small .jstree-open>.jstree-ocl{background-position:-135px -7px}.jstree-default-small .jstree-closed>.jstree-ocl{background-position:-103px -7px}.jstree-default-small .jstree-leaf>.jstree-ocl{background-position:-71px -7px}.jstree-default-small .jstree-themeicon{background-position:-263px -7px}.jstree-default-small>.jstree-no-dots .jstree-node,.jstree-default-small>.jstree-no-dots .jstree-leaf>.jstree-ocl{background:0 0}.jstree-default-small>.jstree-no-dots .jstree-open>.jstree-ocl{background-position:-39px -7px}.jstree-default-small>.jstree-no-dots .jstree-closed>.jstree-ocl{background-position:-7px -7px}.jstree-default-small .jstree-disabled{background:0 0}.jstree-default-small .jstree-disabled.jstree-hovered{background:0 0}.jstree-default-small .jstree-disabled.jstree-clicked{background:#efefef}.jstree-default-small .jstree-checkbox{background-position:-167px -7px}.jstree-default-small .jstree-checkbox:hover{background-position:-167px -39px}.jstree-default-small.jstree-checkbox-selection .jstree-clicked>.jstree-checkbox,.jstree-default-small .jstree-checked>.jstree-checkbox{background-position:-231px -7px}.jstree-default-small.jstree-checkbox-selection .jstree-clicked>.jstree-checkbox:hover,.jstree-default-small .jstree-checked>.jstree-checkbox:hover{background-position:-231px -39px}.jstree-default-small .jstree-anchor>.jstree-undetermined{background-position:-199px -7px}.jstree-default-small .jstree-anchor>.jstree-undetermined:hover{background-position:-199px -39px}.jstree-default-small .jstree-checkbox-disabled{opacity:.8;filter:url("data:image/svg+xml;utf8,<svg xmlns=\'http://www.w3.org/2000/svg\'><filter id=\'jstree-grayscale\'><feColorMatrix type=\'matrix\' values=\'0.3333 0.3333 0.3333 0 0 0.3333 0.3333 0.3333 0 0 0.3333 0.3333 0.3333 0 0 0 0 0 1 0\'/></filter></svg>#jstree-grayscale");filter:gray;-webkit-filter:grayscale(100%)}.jstree-default-small>.jstree-striped{background-size:auto 36px}.jstree-default-small.jstree-rtl .jstree-node{background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAACAQMAAAB49I5GAAAABlBMVEUAAAAdHRvEkCwcAAAAAXRSTlMAQObYZgAAAAxJREFUCNdjAAMOBgAAGAAJMwQHdQAAAABJRU5ErkJggg==);background-position:100% 1px;background-repeat:repeat-y}.jstree-default-small.jstree-rtl .jstree-last{background:0 0}.jstree-default-small.jstree-rtl .jstree-open>.jstree-ocl{background-position:-135px -39px}.jstree-default-small.jstree-rtl .jstree-closed>.jstree-ocl{background-position:-103px -39px}.jstree-default-small.jstree-rtl .jstree-leaf>.jstree-ocl{background-position:-71px -39px}.jstree-default-small.jstree-rtl>.jstree-no-dots .jstree-node,.jstree-default-small.jstree-rtl>.jstree-no-dots .jstree-leaf>.jstree-ocl{background:0 0}.jstree-default-small.jstree-rtl>.jstree-no-dots .jstree-open>.jstree-ocl{background-position:-39px -39px}.jstree-default-small.jstree-rtl>.jstree-no-dots .jstree-closed>.jstree-ocl{background-position:-7px -39px}.jstree-default-small .jstree-themeicon-custom{background-color:transparent;background-image:none;background-position:0 0}.jstree-default-small>.jstree-container-ul .jstree-loading>.jstree-ocl{background:url(throbber.gif) center center no-repeat}.jstree-default-small .jstree-file{background:url(32px.png) -103px -71px no-repeat}.jstree-default-small .jstree-folder{background:url(32px.png) -263px -7px no-repeat}.jstree-default-small>.jstree-container-ul>.jstree-node{margin-left:0;margin-right:0}#jstree-dnd.jstree-default-small{line-height:18px;padding:0 4px}#jstree-dnd.jstree-default-small .jstree-ok,#jstree-dnd.jstree-default-small .jstree-er{background-image:url(32px.png);background-repeat:no-repeat;background-color:transparent}#jstree-dnd.jstree-default-small i{background:0 0;width:18px;height:18px;line-height:18px}#jstree-dnd.jstree-default-small .jstree-ok{background-position:-7px -71px}#jstree-dnd.jstree-default-small .jstree-er{background-position:-39px -71px}.jstree-default-small.jstree-rtl .jstree-node{background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABIAAAACAQMAAABv1h6PAAAABlBMVEUAAAAdHRvEkCwcAAAAAXRSTlMAQObYZgAAAAxJREFUCNdjAAMHBgAAiABBI4gz9AAAAABJRU5ErkJggg==)}.jstree-default-small.jstree-rtl .jstree-last{background:0 0}.jstree-default-large .jstree-node{min-height:32px;line-height:32px;margin-left:32px;min-width:32px}.jstree-default-large .jstree-anchor{line-height:32px;height:32px}.jstree-default-large .jstree-icon{width:32px;height:32px;line-height:32px}.jstree-default-large .jstree-icon:empty{width:32px;height:32px;line-height:32px}.jstree-default-large.jstree-rtl .jstree-node{margin-right:32px}.jstree-default-large .jstree-wholerow{height:32px}.jstree-default-large .jstree-node,.jstree-default-large .jstree-icon{background-image:url(32px.png)}.jstree-default-large .jstree-node{background-position:-288px 0;background-repeat:repeat-y}.jstree-default-large .jstree-last{background:0 0}.jstree-default-large .jstree-open>.jstree-ocl{background-position:-128px 0}.jstree-default-large .jstree-closed>.jstree-ocl{background-position:-96px 0}.jstree-default-large .jstree-leaf>.jstree-ocl{background-position:-64px 0}.jstree-default-large .jstree-themeicon{background-position:-256px 0}.jstree-default-large>.jstree-no-dots .jstree-node,.jstree-default-large>.jstree-no-dots .jstree-leaf>.jstree-ocl{background:0 0}.jstree-default-large>.jstree-no-dots .jstree-open>.jstree-ocl{background-position:-32px 0}.jstree-default-large>.jstree-no-dots .jstree-closed>.jstree-ocl{background-position:0 0}.jstree-default-large .jstree-disabled{background:0 0}.jstree-default-large .jstree-disabled.jstree-hovered{background:0 0}.jstree-default-large .jstree-disabled.jstree-clicked{background:#efefef}.jstree-default-large .jstree-checkbox{background-position:-160px 0}.jstree-default-large .jstree-checkbox:hover{background-position:-160px -32px}.jstree-default-large.jstree-checkbox-selection .jstree-clicked>.jstree-checkbox,.jstree-default-large .jstree-checked>.jstree-checkbox{background-position:-224px 0}.jstree-default-large.jstree-checkbox-selection .jstree-clicked>.jstree-checkbox:hover,.jstree-default-large .jstree-checked>.jstree-checkbox:hover{background-position:-224px -32px}.jstree-default-large .jstree-anchor>.jstree-undetermined{background-position:-192px 0}.jstree-default-large .jstree-anchor>.jstree-undetermined:hover{background-position:-192px -32px}.jstree-default-large .jstree-checkbox-disabled{opacity:.8;filter:url("data:image/svg+xml;utf8,<svg xmlns=\'http://www.w3.org/2000/svg\'><filter id=\'jstree-grayscale\'><feColorMatrix type=\'matrix\' values=\'0.3333 0.3333 0.3333 0 0 0.3333 0.3333 0.3333 0 0 0.3333 0.3333 0.3333 0 0 0 0 0 1 0\'/></filter></svg>#jstree-grayscale");filter:gray;-webkit-filter:grayscale(100%)}.jstree-default-large>.jstree-striped{background-size:auto 64px}.jstree-default-large.jstree-rtl .jstree-node{background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAACAQMAAAB49I5GAAAABlBMVEUAAAAdHRvEkCwcAAAAAXRSTlMAQObYZgAAAAxJREFUCNdjAAMOBgAAGAAJMwQHdQAAAABJRU5ErkJggg==);background-position:100% 1px;background-repeat:repeat-y}.jstree-default-large.jstree-rtl .jstree-last{background:0 0}.jstree-default-large.jstree-rtl .jstree-open>.jstree-ocl{background-position:-128px -32px}.jstree-default-large.jstree-rtl .jstree-closed>.jstree-ocl{background-position:-96px -32px}.jstree-default-large.jstree-rtl .jstree-leaf>.jstree-ocl{background-position:-64px -32px}.jstree-default-large.jstree-rtl>.jstree-no-dots .jstree-node,.jstree-default-large.jstree-rtl>.jstree-no-dots .jstree-leaf>.jstree-ocl{background:0 0}.jstree-default-large.jstree-rtl>.jstree-no-dots .jstree-open>.jstree-ocl{background-position:-32px -32px}.jstree-default-large.jstree-rtl>.jstree-no-dots .jstree-closed>.jstree-ocl{background-position:0 -32px}.jstree-default-large .jstree-themeicon-custom{background-color:transparent;background-image:none;background-position:0 0}.jstree-default-large>.jstree-container-ul .jstree-loading>.jstree-ocl{background:url(throbber.gif) center center no-repeat}.jstree-default-large .jstree-file{background:url(32px.png) -96px -64px no-repeat}.jstree-default-large .jstree-folder{background:url(32px.png) -256px 0 no-repeat}.jstree-default-large>.jstree-container-ul>.jstree-node{margin-left:0;margin-right:0}#jstree-dnd.jstree-default-large{line-height:32px;padding:0 4px}#jstree-dnd.jstree-default-large .jstree-ok,#jstree-dnd.jstree-default-large .jstree-er{background-image:url(32px.png);background-repeat:no-repeat;background-color:transparent}#jstree-dnd.jstree-default-large i{background:0 0;width:32px;height:32px;line-height:32px}#jstree-dnd.jstree-default-large .jstree-ok{background-position:0 -64px}#jstree-dnd.jstree-default-large .jstree-er{background-position:-32px -64px}.jstree-default-large.jstree-rtl .jstree-node{background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAACAQMAAAAD0EyKAAAABlBMVEUAAAAdHRvEkCwcAAAAAXRSTlMAQObYZgAAAAxJREFUCNdjgIIGBgABCgCBvVLXcAAAAABJRU5ErkJggg==)}.jstree-default-large.jstree-rtl .jstree-last{background:0 0}@media (max-width:768px){#jstree-dnd.jstree-dnd-responsive{line-height:40px;font-weight:700;font-size:1.1em;text-shadow:1px 1px #fff}#jstree-dnd.jstree-dnd-responsive>i{background:0 0;width:40px;height:40px}#jstree-dnd.jstree-dnd-responsive>.jstree-ok{background-image:url(40px.png);background-position:0 -200px;background-size:120px 240px}#jstree-dnd.jstree-dnd-responsive>.jstree-er{background-image:url(40px.png);background-position:-40px -200px;background-size:120px 240px}#jstree-marker.jstree-dnd-responsive{border-left-width:10px;border-top-width:10px;border-bottom-width:10px;margin-top:-10px}}@media (max-width:768px){.jstree-default-responsive .jstree-icon{background-image:url(40px.png)}.jstree-default-responsive .jstree-node,.jstree-default-responsive .jstree-leaf>.jstree-ocl{background:0 0}.jstree-default-responsive .jstree-node{min-height:40px;line-height:40px;margin-left:40px;min-width:40px;white-space:nowrap}.jstree-default-responsive .jstree-anchor{line-height:40px;height:40px}.jstree-default-responsive .jstree-icon,.jstree-default-responsive .jstree-icon:empty{width:40px;height:40px;line-height:40px}.jstree-default-responsive>.jstree-container-ul>.jstree-node{margin-left:0}.jstree-default-responsive.jstree-rtl .jstree-node{margin-left:0;margin-right:40px;background:0 0}.jstree-default-responsive.jstree-rtl .jstree-container-ul>.jstree-node{margin-right:0}.jstree-default-responsive .jstree-ocl,.jstree-default-responsive .jstree-themeicon,.jstree-default-responsive .jstree-checkbox{background-size:120px 240px}.jstree-default-responsive .jstree-leaf>.jstree-ocl,.jstree-default-responsive.jstree-rtl .jstree-leaf>.jstree-ocl{background:0 0}.jstree-default-responsive .jstree-open>.jstree-ocl{background-position:0 0!important}.jstree-default-responsive .jstree-closed>.jstree-ocl{background-position:0 -40px!important}.jstree-default-responsive.jstree-rtl .jstree-closed>.jstree-ocl{background-position:-40px 0!important}.jstree-default-responsive .jstree-themeicon{background-position:-40px -40px}.jstree-default-responsive .jstree-checkbox,.jstree-default-responsive .jstree-checkbox:hover{background-position:-40px -80px}.jstree-default-responsive.jstree-checkbox-selection .jstree-clicked>.jstree-checkbox,.jstree-default-responsive.jstree-checkbox-selection .jstree-clicked>.jstree-checkbox:hover,.jstree-default-responsive .jstree-checked>.jstree-checkbox,.jstree-default-responsive .jstree-checked>.jstree-checkbox:hover{background-position:0 -80px}.jstree-default-responsive .jstree-anchor>.jstree-undetermined,.jstree-default-responsive .jstree-anchor>.jstree-undetermined:hover{background-position:0 -120px}.jstree-default-responsive .jstree-anchor{font-weight:700;font-size:1.1em;text-shadow:1px 1px #fff}.jstree-default-responsive>.jstree-striped{background:0 0}.jstree-default-responsive .jstree-wholerow{border-top:1px solid rgba(255,255,255,.7);border-bottom:1px solid rgba(64,64,64,.2);background:#ebebeb;height:40px}.jstree-default-responsive .jstree-wholerow-hovered{background:#e7f4f9}.jstree-default-responsive .jstree-wholerow-clicked{background:#beebff}.jstree-default-responsive .jstree-children .jstree-last>.jstree-wholerow{box-shadow:inset 0 -6px 3px -5px #666}.jstree-default-responsive .jstree-children .jstree-open>.jstree-wholerow{box-shadow:inset 0 6px 3px -5px #666;border-top:0}.jstree-default-responsive .jstree-children .jstree-open+.jstree-open{box-shadow:none}.jstree-default-responsive .jstree-node,.jstree-default-responsive .jstree-icon,.jstree-default-responsive .jstree-node>.jstree-ocl,.jstree-default-responsive .jstree-themeicon,.jstree-default-responsive .jstree-checkbox{background-image:url(40px.png);background-size:120px 240px}.jstree-default-responsive .jstree-node{background-position:-80px 0;background-repeat:repeat-y}.jstree-default-responsive .jstree-last{background:0 0}.jstree-default-responsive .jstree-leaf>.jstree-ocl{background-position:-40px -120px}.jstree-default-responsive .jstree-last>.jstree-ocl{background-position:-40px -160px}.jstree-default-responsive .jstree-themeicon-custom{background-color:transparent;background-image:none;background-position:0 0}.jstree-default-responsive .jstree-file{background:url(40px.png) 0 -160px no-repeat;background-size:120px 240px}.jstree-default-responsive .jstree-folder{background:url(40px.png) -40px -40px no-repeat;background-size:120px 240px}.jstree-default-responsive>.jstree-container-ul>.jstree-node{margin-left:0;margin-right:0}} \ No newline at end of file
diff --git a/ydb/core/viewer/content/v2/cpu b/ydb/core/viewer/content/v2/cpu
index b08090aea7c..b1e8fc90b84 100644
--- a/ydb/core/viewer/content/v2/cpu
+++ b/ydb/core/viewer/content/v2/cpu
@@ -1,71 +1,71 @@
-<!DOCTYPE HTML>
-<html>
-<head>
-<link rel="stylesheet" href="https://yastatic.net/bootstrap/3.3.1/css/bootstrap.min.css">
-<script language="javascript" type="text/javascript" src="https://yastatic.net/jquery/2.1.3/jquery.min.js"></script>
-<script language="javascript" type="text/javascript" src="https://yastatic.net/bootstrap/3.3.1/js/bootstrap.min.js"></script>
-<style type="text/css">
-.table-nonfluid { width: auto; }
-.narrow-line50 {line-height: 50%}
-.narrow-line60 {line-height: 60%}
-.narrow-line70 {line-height: 70%}
-.narrow-line80 {line-height: 80%}
-.narrow-line90 {line-height: 90%}
-</style>
-<link rel="stylesheet" href="../style.min.css" />
-<link rel="stylesheet" href="viewer.css" />
-<script src="util.js"></script>
-<script src="pool_block.js"></script>
-<script src="pool_map.js"></script>
-<script src="node_map.js"></script>
-<script src="pdisk.js"></script>
-<script src="vdisk.js"></script>
-<script src="disk_cell.js"></script>
-<script src="disk_map.js"></script>
-<script src="tablet_cell.js"></script>
-<script src="tablet_map.js"></script>
-<script src="node.js"></script>
-<script src="node_group.js"></script>
-<script src="tenant.js"></script>
-<script src="overview.js"></script>
-<script src="cpu_view.js"></script>
-<script src="net_view.js"></script>
-<script src="storage_view.js"></script>
-<script src="node_view.js"></script>
-<script src="tenant_view.js"></script>
-<script src="viewer.js"></script>
-</head>
-<body onload='mainCpu();'>
-<div class='container-fluid'>
-<ul class="nav nav-tabs">
- <li class="nav-item">
- <a class="pseudo-nav-link" href="overview">Overview</a>
- </li>
- <li class="nav-item active">
- <a class="pseudo-nav-link" href="cpu">CPU</a>
- </li>
- <li class="nav-item">
- <a class="pseudo-nav-link" href="network">Network</a>
- </li>
- <li class="nav-item">
- <a class="pseudo-nav-link" href="storage">Storage</a>
- </li>
- <li class="nav-item">
- <a class="pseudo-nav-link" href="nodes">Nodes</a>
- </li>
- <li class="nav-item">
- <a class="pseudo-nav-link" href="tenants">Tenants</a>
- </li>
- <li style="float:right">
- <span id="updateQueueInflight" style="font-size:10px"></span>
- <span id="updateQueueCounter" style="font-weight:bold;font-size:20px;margin-left:40px"></span>
- </li>
-</ul>
-<div class="tab-content" style="padding-top: 10px">
- <div id="cpu" class="tab-pane active">
- <div id="cpu_view" style='font-size: 14px; padding: 10px 0px 10px 0px; display: inline-block'></div>
- </div>
-</div>
-</div>
-</body>
-</html>
+<!DOCTYPE HTML>
+<html>
+<head>
+<link rel="stylesheet" href="https://yastatic.net/bootstrap/3.3.1/css/bootstrap.min.css">
+<script language="javascript" type="text/javascript" src="https://yastatic.net/jquery/2.1.3/jquery.min.js"></script>
+<script language="javascript" type="text/javascript" src="https://yastatic.net/bootstrap/3.3.1/js/bootstrap.min.js"></script>
+<style type="text/css">
+.table-nonfluid { width: auto; }
+.narrow-line50 {line-height: 50%}
+.narrow-line60 {line-height: 60%}
+.narrow-line70 {line-height: 70%}
+.narrow-line80 {line-height: 80%}
+.narrow-line90 {line-height: 90%}
+</style>
+<link rel="stylesheet" href="../style.min.css" />
+<link rel="stylesheet" href="viewer.css" />
+<script src="util.js"></script>
+<script src="pool_block.js"></script>
+<script src="pool_map.js"></script>
+<script src="node_map.js"></script>
+<script src="pdisk.js"></script>
+<script src="vdisk.js"></script>
+<script src="disk_cell.js"></script>
+<script src="disk_map.js"></script>
+<script src="tablet_cell.js"></script>
+<script src="tablet_map.js"></script>
+<script src="node.js"></script>
+<script src="node_group.js"></script>
+<script src="tenant.js"></script>
+<script src="overview.js"></script>
+<script src="cpu_view.js"></script>
+<script src="net_view.js"></script>
+<script src="storage_view.js"></script>
+<script src="node_view.js"></script>
+<script src="tenant_view.js"></script>
+<script src="viewer.js"></script>
+</head>
+<body onload='mainCpu();'>
+<div class='container-fluid'>
+<ul class="nav nav-tabs">
+ <li class="nav-item">
+ <a class="pseudo-nav-link" href="overview">Overview</a>
+ </li>
+ <li class="nav-item active">
+ <a class="pseudo-nav-link" href="cpu">CPU</a>
+ </li>
+ <li class="nav-item">
+ <a class="pseudo-nav-link" href="network">Network</a>
+ </li>
+ <li class="nav-item">
+ <a class="pseudo-nav-link" href="storage">Storage</a>
+ </li>
+ <li class="nav-item">
+ <a class="pseudo-nav-link" href="nodes">Nodes</a>
+ </li>
+ <li class="nav-item">
+ <a class="pseudo-nav-link" href="tenants">Tenants</a>
+ </li>
+ <li style="float:right">
+ <span id="updateQueueInflight" style="font-size:10px"></span>
+ <span id="updateQueueCounter" style="font-weight:bold;font-size:20px;margin-left:40px"></span>
+ </li>
+</ul>
+<div class="tab-content" style="padding-top: 10px">
+ <div id="cpu" class="tab-pane active">
+ <div id="cpu_view" style='font-size: 14px; padding: 10px 0px 10px 0px; display: inline-block'></div>
+ </div>
+</div>
+</div>
+</body>
+</html>
diff --git a/ydb/core/viewer/content/v2/cpu_view.js b/ydb/core/viewer/content/v2/cpu_view.js
index 9fedec0f3c5..e465b418e75 100644
--- a/ydb/core/viewer/content/v2/cpu_view.js
+++ b/ydb/core/viewer/content/v2/cpu_view.js
@@ -1,98 +1,98 @@
-function CpuView(options) {
- Object.assign(this, {
-
- }, options);
- this.nodes = {};
- this.nodesCount = 0;
- this.poolMaps = {};
- this.poolColors = new PoolColors();
- this.nodeMapSettings = {
- maxWidth: 1400,
- maxPlaceSize: 40,
- height: 85
- };
- this.updateQueue = new UpdateQueue({
- onUpdate: this.runSysUpdate.bind(this)
- });
-}
-
-CpuView.prototype.addNode = function(node) {
- node.position = this.nodesCount;
- this.nodes[node.Id] = node;
- this.nodesCount++;
-}
-
-CpuView.prototype.rebuild = function() {
- this.nodeMapSettings.nodes = this.nodesCount;
-}
-
-CpuView.prototype.runSysUpdate = function(update) {
- var nodeId = update.NodeId;
- if (nodeId) {
- var node = this.nodes[nodeId];
- if (node) {
- node.updateSysInfoStatsOnly(update);
- }
- if (node.sysInfo && node.sysInfo.PoolStats) {
- for (var p = 0; p < node.sysInfo.PoolStats.length; ++p) {
- var poolStat = node.sysInfo.PoolStats[p];
- var poolMap = this.poolMaps[poolStat.Name];
- if (poolMap === undefined) {
- poolMap = new NodeMap(this.nodeMapSettings);
- var container = $(this.domElement);
- container.append($('<div>', {class: 'map_overview_header'}).text(poolStat.Name));
- container.append(poolMap.domElement);
- this.poolMaps[poolStat.Name] = poolMap;
- for (var thisNodeId in this.nodes) {
- var thisNode = this.nodes[thisNodeId];
- var title = thisNode.getTooltipText();
- poolMap.setNodeTitle(thisNode.position, title);
- }
- }
- var poolColor = this.poolColors.getPoolColor(poolStat.Usage);
- poolMap.setNodeMap(node.position, poolColor);
- }
- }
- }
-}
-
-CpuView.prototype.onSysInfo = function(data) {
- if (data.SystemStateInfo !== undefined) {
- var deadNodes = {};
- if (!data.since) {
- for (var i in this.nodes) {
- deadNodes[i] = true;
- }
- this.updateQueue.flushUpdateQueue();
- } else {
- data.SystemStateInfo.sort(function(a, b) {
- return Number(b.ChangeTime) - Number(a.ChangeTime);
- });
- }
- for (var idx = 0; idx < data.SystemStateInfo.length; ++idx) {
- var update = data.SystemStateInfo[idx];
- if (!data.since) {
- delete deadNodes[update.NodeId];
- }
- this.updateQueue.enqueue(update);
- }
- for (var i in deadNodes) {
- var node = this.nodes[i];
- if (node) {
- for (var p in this.poolMaps) {
- this.poolMaps[p].setNodeMap(node.position, 'black');
- }
- }
- }
- }
- if (!this.updateQueue.isEmpty()) {
- this.updateQueue.updateDelay = Math.floor(data.refreshTimeout / this.updateQueue.getLength());
- console.log('CpuView.updateQueue length = ' + this.updateQueue.getLength() + ' updateDelay = ' + this.updateQueue.updateDelay);
- } else {
- this.updateQueue.updateDelay = 50;
- }
-}
-
-CpuView.prototype.onDisconnect = function() {
-
-}
+function CpuView(options) {
+ Object.assign(this, {
+
+ }, options);
+ this.nodes = {};
+ this.nodesCount = 0;
+ this.poolMaps = {};
+ this.poolColors = new PoolColors();
+ this.nodeMapSettings = {
+ maxWidth: 1400,
+ maxPlaceSize: 40,
+ height: 85
+ };
+ this.updateQueue = new UpdateQueue({
+ onUpdate: this.runSysUpdate.bind(this)
+ });
+}
+
+CpuView.prototype.addNode = function(node) {
+ node.position = this.nodesCount;
+ this.nodes[node.Id] = node;
+ this.nodesCount++;
+}
+
+CpuView.prototype.rebuild = function() {
+ this.nodeMapSettings.nodes = this.nodesCount;
+}
+
+CpuView.prototype.runSysUpdate = function(update) {
+ var nodeId = update.NodeId;
+ if (nodeId) {
+ var node = this.nodes[nodeId];
+ if (node) {
+ node.updateSysInfoStatsOnly(update);
+ }
+ if (node.sysInfo && node.sysInfo.PoolStats) {
+ for (var p = 0; p < node.sysInfo.PoolStats.length; ++p) {
+ var poolStat = node.sysInfo.PoolStats[p];
+ var poolMap = this.poolMaps[poolStat.Name];
+ if (poolMap === undefined) {
+ poolMap = new NodeMap(this.nodeMapSettings);
+ var container = $(this.domElement);
+ container.append($('<div>', {class: 'map_overview_header'}).text(poolStat.Name));
+ container.append(poolMap.domElement);
+ this.poolMaps[poolStat.Name] = poolMap;
+ for (var thisNodeId in this.nodes) {
+ var thisNode = this.nodes[thisNodeId];
+ var title = thisNode.getTooltipText();
+ poolMap.setNodeTitle(thisNode.position, title);
+ }
+ }
+ var poolColor = this.poolColors.getPoolColor(poolStat.Usage);
+ poolMap.setNodeMap(node.position, poolColor);
+ }
+ }
+ }
+}
+
+CpuView.prototype.onSysInfo = function(data) {
+ if (data.SystemStateInfo !== undefined) {
+ var deadNodes = {};
+ if (!data.since) {
+ for (var i in this.nodes) {
+ deadNodes[i] = true;
+ }
+ this.updateQueue.flushUpdateQueue();
+ } else {
+ data.SystemStateInfo.sort(function(a, b) {
+ return Number(b.ChangeTime) - Number(a.ChangeTime);
+ });
+ }
+ for (var idx = 0; idx < data.SystemStateInfo.length; ++idx) {
+ var update = data.SystemStateInfo[idx];
+ if (!data.since) {
+ delete deadNodes[update.NodeId];
+ }
+ this.updateQueue.enqueue(update);
+ }
+ for (var i in deadNodes) {
+ var node = this.nodes[i];
+ if (node) {
+ for (var p in this.poolMaps) {
+ this.poolMaps[p].setNodeMap(node.position, 'black');
+ }
+ }
+ }
+ }
+ if (!this.updateQueue.isEmpty()) {
+ this.updateQueue.updateDelay = Math.floor(data.refreshTimeout / this.updateQueue.getLength());
+ console.log('CpuView.updateQueue length = ' + this.updateQueue.getLength() + ' updateDelay = ' + this.updateQueue.updateDelay);
+ } else {
+ this.updateQueue.updateDelay = 50;
+ }
+}
+
+CpuView.prototype.onDisconnect = function() {
+
+}
diff --git a/ydb/core/viewer/content/v2/disk_cell.js b/ydb/core/viewer/content/v2/disk_cell.js
index e718aefadf6..15cf85ecafb 100644
--- a/ydb/core/viewer/content/v2/disk_cell.js
+++ b/ydb/core/viewer/content/v2/disk_cell.js
@@ -1,195 +1,195 @@
-function DiskCell(id, options) {
- Object.assign(this, {
- Id: id,
- vDisks: {},
- pDiskClass: DiskCell.prototype.pDiskClass,
- vDiskClass: DiskCell.prototype.vDiskClass,
- vDisksCount: 0
- },
- options);
- this.buildDomElement();
-}
-
-DiskCell.prototype.buildDomElement = function() {
- var cell = $('<div>', {class: 'disk_cell'});
- this.domElement = cell[0];
- this.domElement.object = this;
-}
-
-DiskCell.prototype.buildVDiskPlace = function() {
- var cell = $(this.domElement);
- var vDiskPlace = $('<div>', {class: 'vdisk_place'});
- if (this.pDiskDomElement) {
- vDiskPlace.css('margin-bottom', '3px');
- }
- this.vDiskDomElement = vDiskPlace[0];
- cell.prepend(vDiskPlace);
-}
-
-DiskCell.prototype.buildPDiskPlace = function() {
- var cell = $(this.domElement);
- var pDiskPlace = $('<div>', {class: 'pdisk_place'});
- if (this.vDiskDomElement) {
- pDiskPlace.css('margin-top', '3px');
- }
- this.pDiskDomElement = pDiskPlace[0];
- cell.append(pDiskPlace);
-}
-
-DiskCell.prototype.vDiskClass = 'vdisk-wide';
-DiskCell.prototype.vDiskClasses = 'vdisk-wide vdisk-normal vdisk-narrow';
-DiskCell.prototype.pDiskClasses = 'pdisk-wide pdisk-normal pdisk-narrow';
-DiskCell.prototype.pDiskClass = 'pdisk-narrow';
-DiskCell.prototype.maxVDisks = 0;
-DiskCell.prototype.maxWideVDisks = 5;
-DiskCell.prototype.maxNormalVDisks = 6;
-DiskCell.prototype.maxNarrowPDisks = 10;
-DiskCell.prototype.maxNormalPDisks = 15;
-DiskCell.prototype.totalWidth = 100;
-
-DiskCell.prototype.updatePDiskClasses = function() {
- if (this.pDisk) {
- var pDisk = this.pDisk;
- $(pDisk.domElement).removeClass(this.pDiskClasses).addClass(DiskCell.prototype.pDiskClass);
- }
-}
-
-DiskCell.prototype.updateVDiskClasses = function() {
- for (var vDiskId in this.vDisks) {
- var vDisk = this.vDisks[vDiskId];
- $(vDisk.domElement).removeClass(this.vDiskClasses).addClass(DiskCell.prototype.vDiskClass);
- }
-}
-
-DiskCell.prototype.checkDisksClass = function(vDisks) {
- if (vDisks > DiskCell.prototype.maxVDisks) {
- var oldVDiskClass = DiskCell.prototype.vDiskClass;
- var oldPDiskClass = DiskCell.prototype.pDiskClass;
-
- DiskCell.prototype.maxVDisks = vDisks;
- if (DiskCell.prototype.maxVDisks > this.maxWideVDisks) {
- DiskCell.prototype.vDiskClass = 'vdisk-normal';
- }
- if (DiskCell.prototype.maxVDisks > this.maxNormalVDisks) {
- DiskCell.prototype.vDiskClass = 'vdisk-narrow';
- }
- if (DiskCell.prototype.maxVDisks > this.maxNarrowPDisks) {
- DiskCell.prototype.pDiskClass = 'pdisk-normal';
- DiskCell.prototype.totalWidth = 160;
- }
- if (DiskCell.prototype.maxVDisks > this.maxNormalPDisks) {
- DiskCell.prototype.pDiskClass = 'pdisk-wide';
- DiskCell.prototype.totalWidth = 260;
- }
- if (oldVDiskClass !== DiskCell.prototype.vDiskClass || oldPDiskClass !== DiskCell.prototype.pDiskClass) {
- $('.' + oldVDiskClass).removeClass(oldVDiskClass).addClass(DiskCell.prototype.vDiskClass);
- $('.' + oldPDiskClass).removeClass(oldPDiskClass).addClass(DiskCell.prototype.pDiskClass);
- }
- }
- if (this.pDiskClass !== DiskCell.prototype.pDiskClass) {
- if (this.diskMap) {
- this.diskMap.updatePDiskClasses();
- }
- this.pDiskClass = DiskCell.prototype.pDiskClass;
- }
- if (this.vDiskClass !== DiskCell.prototype.vDiskClass) {
- if (this.diskMap) {
- this.diskMap.updateVDiskClasses();
- }
- this.vDiskClass = DiskCell.prototype.vDiskClass;
- }
-}
-
-DiskCell.prototype.updatePDiskInfo = function(update) {
- var id = getPDiskId(update);
- var pDisk = this.pDisk;
- if (pDisk === undefined) {
- if (!this.pDiskDomElement) {
- this.buildPDiskPlace();
- }
- pDisk = this.pDisk = new PDisk(update, {class: DiskCell.prototype.pDiskClass, diskCell: this});
- this.pDiskDomElement.appendChild(pDisk.domElement);
- }
- //this.allocatedSize = Number(update.TotalSize) - Number(update.AvailableSize);
- pDisk.updatePDiskInfo(update);
- return pDisk;
-}
-
-DiskCell.prototype.updateVDiskInfo = function(update) {
- var id = getVDiskId(update);
- var vDisk = this.vDisks[id];
- if (vDisk === undefined) {
- if (!this.vDiskDomElement) {
- this.buildVDiskPlace();
- }
- vDisk = this.vDisks[id] = new VDisk(update, {class: DiskCell.prototype.vDiskClass, diskCell: this});
- this.vDiskDomElement.appendChild(vDisk.domElement);
- this.vDisksCount = this.vDiskDomElement.childElementCount;
- this.checkDisksClass(this.vDisksCount);
- }
- vDisk.updateVDiskInfo(update);
- return vDisk;
-}
-
-DiskCell.prototype.resizeVDisks = function() {
- if (this.vDisksCount) {
- var minWidth = 5;
- var availWidth = this.totalWidth - minWidth * this.vDisksCount;
- var normalWidth = availWidth / this.vDisksCount;
- if (availWidth > 0) {
- var allocatedSize = 0;
- var known = 0;
- var total = 0;
- var averageSize = 0;
- for (var id in this.vDisks) {
- var vDisk = this.vDisks[id];
- if (vDisk.AllocatedSize) {
- allocatedSize = allocatedSize + Number(vDisk.AllocatedSize);
- known++;
- }
- total++;
- }
- if (known < total && known > 0) {
- averageSize = allocatedSize / known;
- allocatedSize = averageSize * total;
- }
-
- for (var id in this.vDisks) {
- var vDisk = this.vDisks[id];
- var partSize;
- if (vDisk.AllocatedSize) {
- partSize = vDisk.AllocatedSize / (allocatedSize / this.vDisksCount);
- } else {
- if (allocatedSize > 0) {
- partSize = averageSize / (allocatedSize / this.vDisksCount);
- } else {
- partSize = 1;
- }
- }
- var width = Math.floor(normalWidth * partSize + minWidth);
- if (vDisk.width != width) {
- $(vDisk.domElement).css('width', width + 'px');
- }
- vDisk.width = width;
- }
- }
- }
-}
-
-DiskCell.prototype.getUsage = function() {
- if (this.pDisk) {
- return this.pDisk.getUsage();
- } else {
- return 0;
- }
-}
-
-DiskCell.prototype.restoreTooltips = function() {
- for (var id in this.vDisks) {
- var vDisk = this.vDisks[id];
- vDisk.restoreTooltips();
- }
- if (this.pDisk) {
- this.pDisk.restoreTooltips();
- }
-}
+function DiskCell(id, options) {
+ Object.assign(this, {
+ Id: id,
+ vDisks: {},
+ pDiskClass: DiskCell.prototype.pDiskClass,
+ vDiskClass: DiskCell.prototype.vDiskClass,
+ vDisksCount: 0
+ },
+ options);
+ this.buildDomElement();
+}
+
+DiskCell.prototype.buildDomElement = function() {
+ var cell = $('<div>', {class: 'disk_cell'});
+ this.domElement = cell[0];
+ this.domElement.object = this;
+}
+
+DiskCell.prototype.buildVDiskPlace = function() {
+ var cell = $(this.domElement);
+ var vDiskPlace = $('<div>', {class: 'vdisk_place'});
+ if (this.pDiskDomElement) {
+ vDiskPlace.css('margin-bottom', '3px');
+ }
+ this.vDiskDomElement = vDiskPlace[0];
+ cell.prepend(vDiskPlace);
+}
+
+DiskCell.prototype.buildPDiskPlace = function() {
+ var cell = $(this.domElement);
+ var pDiskPlace = $('<div>', {class: 'pdisk_place'});
+ if (this.vDiskDomElement) {
+ pDiskPlace.css('margin-top', '3px');
+ }
+ this.pDiskDomElement = pDiskPlace[0];
+ cell.append(pDiskPlace);
+}
+
+DiskCell.prototype.vDiskClass = 'vdisk-wide';
+DiskCell.prototype.vDiskClasses = 'vdisk-wide vdisk-normal vdisk-narrow';
+DiskCell.prototype.pDiskClasses = 'pdisk-wide pdisk-normal pdisk-narrow';
+DiskCell.prototype.pDiskClass = 'pdisk-narrow';
+DiskCell.prototype.maxVDisks = 0;
+DiskCell.prototype.maxWideVDisks = 5;
+DiskCell.prototype.maxNormalVDisks = 6;
+DiskCell.prototype.maxNarrowPDisks = 10;
+DiskCell.prototype.maxNormalPDisks = 15;
+DiskCell.prototype.totalWidth = 100;
+
+DiskCell.prototype.updatePDiskClasses = function() {
+ if (this.pDisk) {
+ var pDisk = this.pDisk;
+ $(pDisk.domElement).removeClass(this.pDiskClasses).addClass(DiskCell.prototype.pDiskClass);
+ }
+}
+
+DiskCell.prototype.updateVDiskClasses = function() {
+ for (var vDiskId in this.vDisks) {
+ var vDisk = this.vDisks[vDiskId];
+ $(vDisk.domElement).removeClass(this.vDiskClasses).addClass(DiskCell.prototype.vDiskClass);
+ }
+}
+
+DiskCell.prototype.checkDisksClass = function(vDisks) {
+ if (vDisks > DiskCell.prototype.maxVDisks) {
+ var oldVDiskClass = DiskCell.prototype.vDiskClass;
+ var oldPDiskClass = DiskCell.prototype.pDiskClass;
+
+ DiskCell.prototype.maxVDisks = vDisks;
+ if (DiskCell.prototype.maxVDisks > this.maxWideVDisks) {
+ DiskCell.prototype.vDiskClass = 'vdisk-normal';
+ }
+ if (DiskCell.prototype.maxVDisks > this.maxNormalVDisks) {
+ DiskCell.prototype.vDiskClass = 'vdisk-narrow';
+ }
+ if (DiskCell.prototype.maxVDisks > this.maxNarrowPDisks) {
+ DiskCell.prototype.pDiskClass = 'pdisk-normal';
+ DiskCell.prototype.totalWidth = 160;
+ }
+ if (DiskCell.prototype.maxVDisks > this.maxNormalPDisks) {
+ DiskCell.prototype.pDiskClass = 'pdisk-wide';
+ DiskCell.prototype.totalWidth = 260;
+ }
+ if (oldVDiskClass !== DiskCell.prototype.vDiskClass || oldPDiskClass !== DiskCell.prototype.pDiskClass) {
+ $('.' + oldVDiskClass).removeClass(oldVDiskClass).addClass(DiskCell.prototype.vDiskClass);
+ $('.' + oldPDiskClass).removeClass(oldPDiskClass).addClass(DiskCell.prototype.pDiskClass);
+ }
+ }
+ if (this.pDiskClass !== DiskCell.prototype.pDiskClass) {
+ if (this.diskMap) {
+ this.diskMap.updatePDiskClasses();
+ }
+ this.pDiskClass = DiskCell.prototype.pDiskClass;
+ }
+ if (this.vDiskClass !== DiskCell.prototype.vDiskClass) {
+ if (this.diskMap) {
+ this.diskMap.updateVDiskClasses();
+ }
+ this.vDiskClass = DiskCell.prototype.vDiskClass;
+ }
+}
+
+DiskCell.prototype.updatePDiskInfo = function(update) {
+ var id = getPDiskId(update);
+ var pDisk = this.pDisk;
+ if (pDisk === undefined) {
+ if (!this.pDiskDomElement) {
+ this.buildPDiskPlace();
+ }
+ pDisk = this.pDisk = new PDisk(update, {class: DiskCell.prototype.pDiskClass, diskCell: this});
+ this.pDiskDomElement.appendChild(pDisk.domElement);
+ }
+ //this.allocatedSize = Number(update.TotalSize) - Number(update.AvailableSize);
+ pDisk.updatePDiskInfo(update);
+ return pDisk;
+}
+
+DiskCell.prototype.updateVDiskInfo = function(update) {
+ var id = getVDiskId(update);
+ var vDisk = this.vDisks[id];
+ if (vDisk === undefined) {
+ if (!this.vDiskDomElement) {
+ this.buildVDiskPlace();
+ }
+ vDisk = this.vDisks[id] = new VDisk(update, {class: DiskCell.prototype.vDiskClass, diskCell: this});
+ this.vDiskDomElement.appendChild(vDisk.domElement);
+ this.vDisksCount = this.vDiskDomElement.childElementCount;
+ this.checkDisksClass(this.vDisksCount);
+ }
+ vDisk.updateVDiskInfo(update);
+ return vDisk;
+}
+
+DiskCell.prototype.resizeVDisks = function() {
+ if (this.vDisksCount) {
+ var minWidth = 5;
+ var availWidth = this.totalWidth - minWidth * this.vDisksCount;
+ var normalWidth = availWidth / this.vDisksCount;
+ if (availWidth > 0) {
+ var allocatedSize = 0;
+ var known = 0;
+ var total = 0;
+ var averageSize = 0;
+ for (var id in this.vDisks) {
+ var vDisk = this.vDisks[id];
+ if (vDisk.AllocatedSize) {
+ allocatedSize = allocatedSize + Number(vDisk.AllocatedSize);
+ known++;
+ }
+ total++;
+ }
+ if (known < total && known > 0) {
+ averageSize = allocatedSize / known;
+ allocatedSize = averageSize * total;
+ }
+
+ for (var id in this.vDisks) {
+ var vDisk = this.vDisks[id];
+ var partSize;
+ if (vDisk.AllocatedSize) {
+ partSize = vDisk.AllocatedSize / (allocatedSize / this.vDisksCount);
+ } else {
+ if (allocatedSize > 0) {
+ partSize = averageSize / (allocatedSize / this.vDisksCount);
+ } else {
+ partSize = 1;
+ }
+ }
+ var width = Math.floor(normalWidth * partSize + minWidth);
+ if (vDisk.width != width) {
+ $(vDisk.domElement).css('width', width + 'px');
+ }
+ vDisk.width = width;
+ }
+ }
+ }
+}
+
+DiskCell.prototype.getUsage = function() {
+ if (this.pDisk) {
+ return this.pDisk.getUsage();
+ } else {
+ return 0;
+ }
+}
+
+DiskCell.prototype.restoreTooltips = function() {
+ for (var id in this.vDisks) {
+ var vDisk = this.vDisks[id];
+ vDisk.restoreTooltips();
+ }
+ if (this.pDisk) {
+ this.pDisk.restoreTooltips();
+ }
+}
diff --git a/ydb/core/viewer/content/v2/disk_map.js b/ydb/core/viewer/content/v2/disk_map.js
index 46e86248638..968c837d215 100644
--- a/ydb/core/viewer/content/v2/disk_map.js
+++ b/ydb/core/viewer/content/v2/disk_map.js
@@ -1,114 +1,114 @@
-function DiskMap(options) {
- Object.assign(this, {
- cells: {},
- vDisksCount: 0
- },
- options);
- this.buildDomElement();
-}
-
-DiskMap.prototype.buildDomElement = function() {
- var diskRow = $('<div>', {class: 'disk_map'});
- this.domElement = diskRow[0];
- return diskRow[0];
-}
-
-DiskMap.prototype.getDiskCell = function(id, update) {
- var cell = this.cells[id];
- if (cell === undefined) {
- cell = this.cells[id] = new DiskCell(id, {diskMap: this});
- this.domElement.appendChild(cell.domElement);
- }
- if (!cell.path && update.Path) {
- cell.path = update.Path;
- this.sort();
- }
- return cell;
-}
-
-DiskMap.prototype.sort = function() {
- var domElement = this.domElement;
- var children = [];
- for (var i = 0; i < domElement.children.length; ++i) {
- children.push(domElement.children[i]);
- }
- children.sort(function(a, b) {
- return (a.object.path && b.object.path) ? a.object.path.localeCompare(b.object.path) : 0;
- });
- children.forEach(function(obj) {
- domElement.appendChild(obj);
- });
-}
-
-DiskMap.prototype.updatePDiskInfo = function(update) {
- var id;
- if (update.NodeId && update.PDiskId !== undefined) {
- id = getPDiskId(update);
- } else if (update.CellId !== undefined) {
- id = update.CellId;
- }
- if (id !== undefined) {
- var cell = this.getDiskCell(id, update);
- return cell.updatePDiskInfo(update);
- }
-}
-
-DiskMap.prototype.updateVDiskInfo = function(update) {
- var id;
- if (update.NodeId && update.PDiskId !== undefined) {
- id = getPDiskId(update);
- } else if (update.CellId !== undefined) {
- id = update.CellId;
- }
- if (id !== undefined) {
- var cell = this.getDiskCell(id, update);
- var count = cell.vDisksCount;
- var vDisk = cell.updateVDiskInfo(update);
- this.vDisksCount += cell.vDisksCount - count;
- return vDisk;
- }
-}
-
-DiskMap.prototype.updatePDiskClasses = function() {
- for (var cellId in this.cells) {
- var cell = this.cells[cellId];
- cell.updatePDiskClasses();
- }
-}
-
-DiskMap.prototype.updateVDiskClasses = function() {
- for (var cellId in this.cells) {
- var cell = this.cells[cellId];
- cell.updateVDiskClasses();
- }
-}
-
-DiskMap.prototype.resizeVDisks = function() {
- for (var cellId in this.cells) {
- var cell = this.cells[cellId];
- cell.resizeVDisks();
- }
-}
-
-DiskMap.prototype.getUsage = function() {
- var usage = 0;
- for (var cellId in this.cells) {
- var cell = this.cells[cellId];
- if (cell.pDisk) {
- usage = Math.max(usage, cell.pDisk.getUsage());
- }
- }
- return usage;
-}
-
-DiskMap.prototype.restoreTooltips = function() {
- for (var cellId in this.cells) {
- var cell = this.cells[cellId];
- cell.restoreTooltips();
- }
-}
-
-DiskMap.prototype.onShowPDiskToolTip = function(pDisk) {}
-DiskMap.prototype.onHidePDiskToolTip = function(pDisk) {}
-DiskMap.prototype.onShowVDiskToolTip = function(vDisk) {}
-DiskMap.prototype.onHideVDiskToolTip = function(vDisk) {}
+function DiskMap(options) {
+ Object.assign(this, {
+ cells: {},
+ vDisksCount: 0
+ },
+ options);
+ this.buildDomElement();
+}
+
+DiskMap.prototype.buildDomElement = function() {
+ var diskRow = $('<div>', {class: 'disk_map'});
+ this.domElement = diskRow[0];
+ return diskRow[0];
+}
+
+DiskMap.prototype.getDiskCell = function(id, update) {
+ var cell = this.cells[id];
+ if (cell === undefined) {
+ cell = this.cells[id] = new DiskCell(id, {diskMap: this});
+ this.domElement.appendChild(cell.domElement);
+ }
+ if (!cell.path && update.Path) {
+ cell.path = update.Path;
+ this.sort();
+ }
+ return cell;
+}
+
+DiskMap.prototype.sort = function() {
+ var domElement = this.domElement;
+ var children = [];
+ for (var i = 0; i < domElement.children.length; ++i) {
+ children.push(domElement.children[i]);
+ }
+ children.sort(function(a, b) {
+ return (a.object.path && b.object.path) ? a.object.path.localeCompare(b.object.path) : 0;
+ });
+ children.forEach(function(obj) {
+ domElement.appendChild(obj);
+ });
+}
+
+DiskMap.prototype.updatePDiskInfo = function(update) {
+ var id;
+ if (update.NodeId && update.PDiskId !== undefined) {
+ id = getPDiskId(update);
+ } else if (update.CellId !== undefined) {
+ id = update.CellId;
+ }
+ if (id !== undefined) {
+ var cell = this.getDiskCell(id, update);
+ return cell.updatePDiskInfo(update);
+ }
+}
+
+DiskMap.prototype.updateVDiskInfo = function(update) {
+ var id;
+ if (update.NodeId && update.PDiskId !== undefined) {
+ id = getPDiskId(update);
+ } else if (update.CellId !== undefined) {
+ id = update.CellId;
+ }
+ if (id !== undefined) {
+ var cell = this.getDiskCell(id, update);
+ var count = cell.vDisksCount;
+ var vDisk = cell.updateVDiskInfo(update);
+ this.vDisksCount += cell.vDisksCount - count;
+ return vDisk;
+ }
+}
+
+DiskMap.prototype.updatePDiskClasses = function() {
+ for (var cellId in this.cells) {
+ var cell = this.cells[cellId];
+ cell.updatePDiskClasses();
+ }
+}
+
+DiskMap.prototype.updateVDiskClasses = function() {
+ for (var cellId in this.cells) {
+ var cell = this.cells[cellId];
+ cell.updateVDiskClasses();
+ }
+}
+
+DiskMap.prototype.resizeVDisks = function() {
+ for (var cellId in this.cells) {
+ var cell = this.cells[cellId];
+ cell.resizeVDisks();
+ }
+}
+
+DiskMap.prototype.getUsage = function() {
+ var usage = 0;
+ for (var cellId in this.cells) {
+ var cell = this.cells[cellId];
+ if (cell.pDisk) {
+ usage = Math.max(usage, cell.pDisk.getUsage());
+ }
+ }
+ return usage;
+}
+
+DiskMap.prototype.restoreTooltips = function() {
+ for (var cellId in this.cells) {
+ var cell = this.cells[cellId];
+ cell.restoreTooltips();
+ }
+}
+
+DiskMap.prototype.onShowPDiskToolTip = function(pDisk) {}
+DiskMap.prototype.onHidePDiskToolTip = function(pDisk) {}
+DiskMap.prototype.onShowVDiskToolTip = function(vDisk) {}
+DiskMap.prototype.onHideVDiskToolTip = function(vDisk) {}
diff --git a/ydb/core/viewer/content/v2/index.html b/ydb/core/viewer/content/v2/index.html
index 45753f244f6..e6c392206d1 100644
--- a/ydb/core/viewer/content/v2/index.html
+++ b/ydb/core/viewer/content/v2/index.html
@@ -1,7 +1,7 @@
-<html>
-<head>
-<meta http-equiv="Refresh" content="0; url=nodes" />
-</head>
-<body>
-</body>
-</html>
+<html>
+<head>
+<meta http-equiv="Refresh" content="0; url=nodes" />
+</head>
+<body>
+</body>
+</html>
diff --git a/ydb/core/viewer/content/v2/net_view.js b/ydb/core/viewer/content/v2/net_view.js
index b7958c62c51..38a03a78c09 100644
--- a/ydb/core/viewer/content/v2/net_view.js
+++ b/ydb/core/viewer/content/v2/net_view.js
@@ -1,149 +1,149 @@
-function NetView(options) {
- Object.assign(this, {}, options);
- this.nodes = {};
- this.nodesCount = 0;
- this.sourceMap = null;
- this.targetMap = null;
- this.poolColors = new PoolColors([
- {usage: 0.00, R: 144, G: 144, B: 144},
- {usage: 1.00, R: 144, G: 238, B: 144},
- {usage: 2.00, R: 255, G: 255, B: 0},
- {usage: 4.00, R: 255, G: 0, B: 0}
- ]);
- this.nodeMapSettings = {
- maxWidth: 1400,
- maxPlaceSize: 40,
- height: 85
- };
- this.updateQueue = new UpdateQueue({
- onUpdate: this.runNetUpdate.bind(this)
- });
-}
-
-NetView.prototype.addNode = function(node) {
- node.position = this.nodesCount;
- this.nodes[node.Id] = node;
- this.nodesCount++;
-}
-
-NetView.prototype.rebuild = function() {
- if (!this.sourceMap) {
- this.nodeMapSettings.nodes = this.nodesCount;
- this.sourceMap = new NodeMap(this.nodeMapSettings);
- this.targetMap = new NodeMap(this.nodeMapSettings);
- var container = $(this.domElement);
- container.append($('<div>', {class: 'map_overview_header'}).text('Source'));
- container.append(this.sourceMap.domElement);
- container.append($('<div>', {class: 'map_overview_header'}).text('Target'));
- container.append(this.targetMap.domElement);
- for (var nodeId in this.nodes) {
- var node = this.nodes[nodeId];
- var title = node.getTooltipText();
- this.sourceMap.setNodeTitle(node.position, title);
- this.targetMap.setNodeTitle(node.position, title);
- }
- }
-}
-
-NetView.prototype.runNetUpdate = function(update) {
- var nodeId = update.nodeId;
- if (nodeId) {
- var node = this.nodes[nodeId];
- if (update.sourceStatus && this.sourceMap) {
- this.sourceMap.setNodeMap(node.position, this.poolColors.getPoolColor(update.sourceStatus));
- }
- if (update.targetStatus && this.targetMap) {
- this.targetMap.setNodeMap(node.position, this.poolColors.getPoolColor(update.targetStatus));
- }
- }
-}
-
-NetView.prototype.onSysInfo = function(data) {
-}
-
-NetView.prototype.onNodeInfo = function(data) {
- if (data !== undefined) {
- var deadNodes = {};
- var nodes = {};
- if (!data.since) {
- for (var i in this.nodes) {
- deadNodes[i] = true;
- }
- this.updateQueue.flushUpdateQueue();
- }
- for (var sourceNodeId in data) {
- var node = this.nodes[sourceNodeId];
- if (node === undefined) {
- continue;
- }
- var src = nodes[Number(sourceNodeId)] = {
- srcConnectStatus: 0,
- srcConnectCount: 0,
- trgConnectStatus: 0,
- trgConnectCount: 0
- };
- var nodeInfo = data[sourceNodeId];
- if (nodeInfo === null) {
- continue;
- }
- if (nodeInfo.NodeStateInfo) {
- var nodeStateInfo = nodeInfo.NodeStateInfo;
- for (var idx = 0; idx < nodeStateInfo.length; ++idx) {
- var update = nodeStateInfo[idx];
- var targetNodeId = getNodeIdFromPeerName(update.PeerName);
- var node = this.nodes[targetNodeId];
- if (node !== undefined/* && update.Connected*/) {
- var trg = nodes[targetNodeId];
- if (trg === undefined) {
- trg = nodes[targetNodeId] = {
- srcConnectStatus: 0,
- srcConnectCount: 0,
- trgConnectStatus: 0,
- trgConnectCount: 0
- };
- }
- src.srcConnectStatus += update.ConnectStatus;
- src.srcConnectCount++;
- trg.trgConnectStatus += update.ConnectStatus;
- trg.trgConnectCount++;
- }
- }
- }
- if (!data.since) {
- delete deadNodes[sourceNodeId];
- }
- }
- for (var id in nodes) {
- var n = nodes[id];
- var o = {
- nodeId: id
- };
- if (n.srcConnectCount > 0) {
- o.sourceStatus = n.srcConnectStatus / n.srcConnectCount;
- }
- if (n.trgConnectCount > 0) {
- o.targetStatus = n.trgConnectStatus / n.trgConnectCount;
- }
- this.updateQueue.enqueue(o);
- }
- for (var i in deadNodes) {
- var node = this.nodes[i];
- if (node && this.sourceMap) {
- this.sourceMap.setNodeMap(node.position, 'black');
- //this.targetMap.setNodeMap(node.position, 'black');
- }
- }
- }
- if (this.sourceMap) {
- if (!this.updateQueue.isEmpty()) {
- this.updateQueue.updateDelay = Math.floor(data.refreshTimeout / this.updateQueue.getLength());
- console.log('NetView.updateQueue length = ' + this.updateQueue.getLength() + ' updateDelay = ' + this.updateQueue.updateDelay);
- } else {
- this.updateQueue.updateDelay = 50;
- }
- }
-}
-
-NetView.prototype.onDisconnect = function() {
-
-}
+function NetView(options) {
+ Object.assign(this, {}, options);
+ this.nodes = {};
+ this.nodesCount = 0;
+ this.sourceMap = null;
+ this.targetMap = null;
+ this.poolColors = new PoolColors([
+ {usage: 0.00, R: 144, G: 144, B: 144},
+ {usage: 1.00, R: 144, G: 238, B: 144},
+ {usage: 2.00, R: 255, G: 255, B: 0},
+ {usage: 4.00, R: 255, G: 0, B: 0}
+ ]);
+ this.nodeMapSettings = {
+ maxWidth: 1400,
+ maxPlaceSize: 40,
+ height: 85
+ };
+ this.updateQueue = new UpdateQueue({
+ onUpdate: this.runNetUpdate.bind(this)
+ });
+}
+
+NetView.prototype.addNode = function(node) {
+ node.position = this.nodesCount;
+ this.nodes[node.Id] = node;
+ this.nodesCount++;
+}
+
+NetView.prototype.rebuild = function() {
+ if (!this.sourceMap) {
+ this.nodeMapSettings.nodes = this.nodesCount;
+ this.sourceMap = new NodeMap(this.nodeMapSettings);
+ this.targetMap = new NodeMap(this.nodeMapSettings);
+ var container = $(this.domElement);
+ container.append($('<div>', {class: 'map_overview_header'}).text('Source'));
+ container.append(this.sourceMap.domElement);
+ container.append($('<div>', {class: 'map_overview_header'}).text('Target'));
+ container.append(this.targetMap.domElement);
+ for (var nodeId in this.nodes) {
+ var node = this.nodes[nodeId];
+ var title = node.getTooltipText();
+ this.sourceMap.setNodeTitle(node.position, title);
+ this.targetMap.setNodeTitle(node.position, title);
+ }
+ }
+}
+
+NetView.prototype.runNetUpdate = function(update) {
+ var nodeId = update.nodeId;
+ if (nodeId) {
+ var node = this.nodes[nodeId];
+ if (update.sourceStatus && this.sourceMap) {
+ this.sourceMap.setNodeMap(node.position, this.poolColors.getPoolColor(update.sourceStatus));
+ }
+ if (update.targetStatus && this.targetMap) {
+ this.targetMap.setNodeMap(node.position, this.poolColors.getPoolColor(update.targetStatus));
+ }
+ }
+}
+
+NetView.prototype.onSysInfo = function(data) {
+}
+
+NetView.prototype.onNodeInfo = function(data) {
+ if (data !== undefined) {
+ var deadNodes = {};
+ var nodes = {};
+ if (!data.since) {
+ for (var i in this.nodes) {
+ deadNodes[i] = true;
+ }
+ this.updateQueue.flushUpdateQueue();
+ }
+ for (var sourceNodeId in data) {
+ var node = this.nodes[sourceNodeId];
+ if (node === undefined) {
+ continue;
+ }
+ var src = nodes[Number(sourceNodeId)] = {
+ srcConnectStatus: 0,
+ srcConnectCount: 0,
+ trgConnectStatus: 0,
+ trgConnectCount: 0
+ };
+ var nodeInfo = data[sourceNodeId];
+ if (nodeInfo === null) {
+ continue;
+ }
+ if (nodeInfo.NodeStateInfo) {
+ var nodeStateInfo = nodeInfo.NodeStateInfo;
+ for (var idx = 0; idx < nodeStateInfo.length; ++idx) {
+ var update = nodeStateInfo[idx];
+ var targetNodeId = getNodeIdFromPeerName(update.PeerName);
+ var node = this.nodes[targetNodeId];
+ if (node !== undefined/* && update.Connected*/) {
+ var trg = nodes[targetNodeId];
+ if (trg === undefined) {
+ trg = nodes[targetNodeId] = {
+ srcConnectStatus: 0,
+ srcConnectCount: 0,
+ trgConnectStatus: 0,
+ trgConnectCount: 0
+ };
+ }
+ src.srcConnectStatus += update.ConnectStatus;
+ src.srcConnectCount++;
+ trg.trgConnectStatus += update.ConnectStatus;
+ trg.trgConnectCount++;
+ }
+ }
+ }
+ if (!data.since) {
+ delete deadNodes[sourceNodeId];
+ }
+ }
+ for (var id in nodes) {
+ var n = nodes[id];
+ var o = {
+ nodeId: id
+ };
+ if (n.srcConnectCount > 0) {
+ o.sourceStatus = n.srcConnectStatus / n.srcConnectCount;
+ }
+ if (n.trgConnectCount > 0) {
+ o.targetStatus = n.trgConnectStatus / n.trgConnectCount;
+ }
+ this.updateQueue.enqueue(o);
+ }
+ for (var i in deadNodes) {
+ var node = this.nodes[i];
+ if (node && this.sourceMap) {
+ this.sourceMap.setNodeMap(node.position, 'black');
+ //this.targetMap.setNodeMap(node.position, 'black');
+ }
+ }
+ }
+ if (this.sourceMap) {
+ if (!this.updateQueue.isEmpty()) {
+ this.updateQueue.updateDelay = Math.floor(data.refreshTimeout / this.updateQueue.getLength());
+ console.log('NetView.updateQueue length = ' + this.updateQueue.getLength() + ' updateDelay = ' + this.updateQueue.updateDelay);
+ } else {
+ this.updateQueue.updateDelay = 50;
+ }
+ }
+}
+
+NetView.prototype.onDisconnect = function() {
+
+}
diff --git a/ydb/core/viewer/content/v2/network b/ydb/core/viewer/content/v2/network
index 4b671b1ace3..736452e039f 100644
--- a/ydb/core/viewer/content/v2/network
+++ b/ydb/core/viewer/content/v2/network
@@ -1,71 +1,71 @@
-<!DOCTYPE HTML>
-<html>
-<head>
-<link rel="stylesheet" href="https://yastatic.net/bootstrap/3.3.1/css/bootstrap.min.css">
-<script language="javascript" type="text/javascript" src="https://yastatic.net/jquery/2.1.3/jquery.min.js"></script>
-<script language="javascript" type="text/javascript" src="https://yastatic.net/bootstrap/3.3.1/js/bootstrap.min.js"></script>
-<style type="text/css">
-.table-nonfluid { width: auto; }
-.narrow-line50 {line-height: 50%}
-.narrow-line60 {line-height: 60%}
-.narrow-line70 {line-height: 70%}
-.narrow-line80 {line-height: 80%}
-.narrow-line90 {line-height: 90%}
-</style>
-<link rel="stylesheet" href="../style.min.css" />
-<link rel="stylesheet" href="viewer.css" />
-<script src="util.js"></script>
-<script src="pool_block.js"></script>
-<script src="pool_map.js"></script>
-<script src="node_map.js"></script>
-<script src="pdisk.js"></script>
-<script src="vdisk.js"></script>
-<script src="disk_cell.js"></script>
-<script src="disk_map.js"></script>
-<script src="tablet_cell.js"></script>
-<script src="tablet_map.js"></script>
-<script src="node.js"></script>
-<script src="node_group.js"></script>
-<script src="tenant.js"></script>
-<script src="overview.js"></script>
-<script src="cpu_view.js"></script>
-<script src="net_view.js"></script>
-<script src="storage_view.js"></script>
-<script src="node_view.js"></script>
-<script src="tenant_view.js"></script>
-<script src="viewer.js"></script>
-</head>
-<body onload='mainNetwork();'>
-<div class='container-fluid'>
-<ul class="nav nav-tabs">
- <li class="nav-item">
- <a class="pseudo-nav-link" href="overview">Overview</a>
- </li>
- <li class="nav-item">
- <a class="pseudo-nav-link" href="cpu">CPU</a>
- </li>
- <li class="nav-item active">
- <a class="pseudo-nav-link" href="network">Network</a>
- </li>
- <li class="nav-item">
- <a class="pseudo-nav-link" href="storage">Storage</a>
- </li>
- <li class="nav-item">
- <a class="pseudo-nav-link" href="nodes">Nodes</a>
- </li>
- <li class="nav-item">
- <a class="pseudo-nav-link" href="tenants">Tenants</a>
- </li>
- <li style="float:right">
- <span id="updateQueueInflight" style="font-size:10px"></span>
- <span id="updateQueueCounter" style="font-weight:bold;font-size:20px;margin-left:40px"></span>
- </li>
-</ul>
-<div class="tab-content" style="padding-top: 10px">
- <div id="network" class="tab-pane active">
- <div id="net_view" style='font-size: 14px; padding: 10px 0px 10px 0px; display: inline-block'></div>
- </div>
-</div>
-</div>
-</body>
-</html>
+<!DOCTYPE HTML>
+<html>
+<head>
+<link rel="stylesheet" href="https://yastatic.net/bootstrap/3.3.1/css/bootstrap.min.css">
+<script language="javascript" type="text/javascript" src="https://yastatic.net/jquery/2.1.3/jquery.min.js"></script>
+<script language="javascript" type="text/javascript" src="https://yastatic.net/bootstrap/3.3.1/js/bootstrap.min.js"></script>
+<style type="text/css">
+.table-nonfluid { width: auto; }
+.narrow-line50 {line-height: 50%}
+.narrow-line60 {line-height: 60%}
+.narrow-line70 {line-height: 70%}
+.narrow-line80 {line-height: 80%}
+.narrow-line90 {line-height: 90%}
+</style>
+<link rel="stylesheet" href="../style.min.css" />
+<link rel="stylesheet" href="viewer.css" />
+<script src="util.js"></script>
+<script src="pool_block.js"></script>
+<script src="pool_map.js"></script>
+<script src="node_map.js"></script>
+<script src="pdisk.js"></script>
+<script src="vdisk.js"></script>
+<script src="disk_cell.js"></script>
+<script src="disk_map.js"></script>
+<script src="tablet_cell.js"></script>
+<script src="tablet_map.js"></script>
+<script src="node.js"></script>
+<script src="node_group.js"></script>
+<script src="tenant.js"></script>
+<script src="overview.js"></script>
+<script src="cpu_view.js"></script>
+<script src="net_view.js"></script>
+<script src="storage_view.js"></script>
+<script src="node_view.js"></script>
+<script src="tenant_view.js"></script>
+<script src="viewer.js"></script>
+</head>
+<body onload='mainNetwork();'>
+<div class='container-fluid'>
+<ul class="nav nav-tabs">
+ <li class="nav-item">
+ <a class="pseudo-nav-link" href="overview">Overview</a>
+ </li>
+ <li class="nav-item">
+ <a class="pseudo-nav-link" href="cpu">CPU</a>
+ </li>
+ <li class="nav-item active">
+ <a class="pseudo-nav-link" href="network">Network</a>
+ </li>
+ <li class="nav-item">
+ <a class="pseudo-nav-link" href="storage">Storage</a>
+ </li>
+ <li class="nav-item">
+ <a class="pseudo-nav-link" href="nodes">Nodes</a>
+ </li>
+ <li class="nav-item">
+ <a class="pseudo-nav-link" href="tenants">Tenants</a>
+ </li>
+ <li style="float:right">
+ <span id="updateQueueInflight" style="font-size:10px"></span>
+ <span id="updateQueueCounter" style="font-weight:bold;font-size:20px;margin-left:40px"></span>
+ </li>
+</ul>
+<div class="tab-content" style="padding-top: 10px">
+ <div id="network" class="tab-pane active">
+ <div id="net_view" style='font-size: 14px; padding: 10px 0px 10px 0px; display: inline-block'></div>
+ </div>
+</div>
+</div>
+</body>
+</html>
diff --git a/ydb/core/viewer/content/v2/node.js b/ydb/core/viewer/content/v2/node.js
index ec62dd6e8be..422249c57c9 100644
--- a/ydb/core/viewer/content/v2/node.js
+++ b/ydb/core/viewer/content/v2/node.js
@@ -1,889 +1,889 @@
-Node.prototype.directApi = false;
-Node.prototype.timeout = 10000;
-
-function Node(options) {
- Object.assign(this, {
- sysInfo: {},
- nodeInfo: {},
- poolMap: null,
- nodeMap: null,
- diskMap: null,
- directApi: Node.prototype.directApi
- },
- options);
- this.haveDisks = true;
- this.vDiskDeltaUpdates = 0;
- this.refreshInProgress = 0;
- var role = this.PortToRoles[this.Port];
- if (role) {
- this.sysInfo.Roles = [role];
- }
- this.tabletMap = new TabletMap();
- this.poolMap = new PoolMap();
- this.memBlock = new PoolBlock();
- this.diskMap = new DiskMap({node: this});
- this.buildDomElement();
-}
-
-Node.prototype.minSysInfoUpdatePeriod = 2000;
-Node.prototype.minPDiskInfoUpdatePeriod = 10000;
-Node.prototype.minVDiskInfoUpdatePeriod = 10000;
-Node.prototype.minTabletInfoUpdatePeriod = 5000;
-
-Node.prototype.PortToRoles = {
- 15600: 'Server',
- 15601: 'Host',
- 15602: 'Proxy',
- 15603: 'Pusher',
- 15604: 'Storage'
-}
-
-Node.prototype.RoleToMonPort = {
- Default: 8765,
- Storage: 8765,
- Server: 8766,
- Pusher: 8763,
- Proxy: 8764,
- Host: 8762
-}
-
-Node.prototype.buildDomElement = function() {
- var row = $('<tr>');
- row.data('node', this);
- var cellId = $('<td>', {class: 'node_id_place'});
- var nodeIcons = $('<div>', {class: 'node_icons'});
- var nodeId = $('<span>', {class: 'node_id'});
- cellId.append(nodeIcons);
- cellId.append(nodeId);
- nodeId.html(this.Id);
- row.append(cellId);
- var host = $('<td>');
- var hostName = $('<div>');
- var hostLink = $('<a>', {
- 'href': this.getBaseUrl(),
- 'target': '_blank',
- 'data-original-title': this.Address
- });
- hostLink.html(this.getHostName());
- //var hostRoles = $('<span>', {class: 'node_roles'});
- hostName.append(hostLink);
- //hostName.append(hostRoles);
- hostLink.tooltip({html: true});
- host.append(hostName);
- var state = $('<div>', {class: 'statecontainer'});
- var loadAverage = $('<div>', {
- 'class': 'usageblock progress',
- 'data-original-title': 'Load average'
- });
- var loadAverageBar = $('<div>', {
- class: 'progress-bar',
- role: 'progressbar'
- });
- loadAverage.append(loadAverageBar);
- loadAverage.tooltip({html: true});
- state.append(loadAverage);
- host.append(state);
- row.append(host);
- /*var uptime = $('<td>', {class: 'uptime_place'}).hide();
- row.append(uptime);
- var cpu = $('<td>', {class: 'cpu_place'}).hide();
- row.append(cpu);*/
- /*var interconnect = $('<td>', {class: 'interconnect_place'});
- row.append(interconnect);*/
- /*var disks = $('<td>', {class: 'disk_place tablet_place'}).hide();
- row.append(disks);*/
- this.domElement = row[0];
- this.domElementNodeIcons = nodeIcons[0];
- this.domElementHostLink = hostLink[0];
- //this.domElementUpTime = uptime[0];
- //this.domElementRoles = hostRoles[0];
- this.domElementLoadAverageBar = loadAverageBar[0];
-}
-
-Node.prototype.getIcon = function(icon, color) {
- return "<span class='glyphicon glyphicon-" + icon + " node_icon' style='color:" + color + "'></span>";
-}
-
-Node.prototype.updateUpTime = function() {
- if (this.sysInfo !== undefined) {
- if (this.sysInfo.StartTime) {
- var currentTime = getTime();
- var startTime = this.sysInfo.StartTime;
- var upTime = currentTime - startTime;
- $(this.domElementUpTime).text(upTimeToString(upTime));
- }
- }
-}
-
-Node.prototype.updateToolTip = function() {
- var sysInfo = this.sysInfo;
- var tooltip = '<table class="tooltip-table">';
-
- if (sysInfo) {
- if (sysInfo.DataCenter) {
- tooltip += '<tr><td>Datacenter</td><td>' + sysInfo.DataCenter + '</td></tr>';
- }
-
- if (sysInfo.Rack) {
- tooltip += '<tr><td>Rack</td><td>' + sysInfo.Rack + '</td></tr>';
- }
-
- if (sysInfo.Tenants) {
- tooltip += '<tr><td>Tenant</td><td>' + sysInfo.Tenants[0] + '</td></tr>';
- }
- }
-
- if (this.Host) {
- tooltip += '<tr><td>Host</td><td>' + this.Host + '</td></tr>';
- }
-
- if (this.Address) {
- tooltip += '<tr><td>Address</td><td>' + this.Address + '</td></tr>';
- }
-
- if (sysInfo) {
- if (sysInfo.Endpoints !== undefined && sysInfo.Endpoints.length > 0) {
- var endpoints = '';
- sysInfo.Endpoints.forEach(function(item) {
- endpoints += '<tr><td>' + item.Name + '</td><td>' + item.Address + '</td></tr>';
- });
- tooltip += endpoints;
- }
+Node.prototype.directApi = false;
+Node.prototype.timeout = 10000;
+
+function Node(options) {
+ Object.assign(this, {
+ sysInfo: {},
+ nodeInfo: {},
+ poolMap: null,
+ nodeMap: null,
+ diskMap: null,
+ directApi: Node.prototype.directApi
+ },
+ options);
+ this.haveDisks = true;
+ this.vDiskDeltaUpdates = 0;
+ this.refreshInProgress = 0;
+ var role = this.PortToRoles[this.Port];
+ if (role) {
+ this.sysInfo.Roles = [role];
+ }
+ this.tabletMap = new TabletMap();
+ this.poolMap = new PoolMap();
+ this.memBlock = new PoolBlock();
+ this.diskMap = new DiskMap({node: this});
+ this.buildDomElement();
+}
+
+Node.prototype.minSysInfoUpdatePeriod = 2000;
+Node.prototype.minPDiskInfoUpdatePeriod = 10000;
+Node.prototype.minVDiskInfoUpdatePeriod = 10000;
+Node.prototype.minTabletInfoUpdatePeriod = 5000;
+
+Node.prototype.PortToRoles = {
+ 15600: 'Server',
+ 15601: 'Host',
+ 15602: 'Proxy',
+ 15603: 'Pusher',
+ 15604: 'Storage'
+}
+
+Node.prototype.RoleToMonPort = {
+ Default: 8765,
+ Storage: 8765,
+ Server: 8766,
+ Pusher: 8763,
+ Proxy: 8764,
+ Host: 8762
+}
+
+Node.prototype.buildDomElement = function() {
+ var row = $('<tr>');
+ row.data('node', this);
+ var cellId = $('<td>', {class: 'node_id_place'});
+ var nodeIcons = $('<div>', {class: 'node_icons'});
+ var nodeId = $('<span>', {class: 'node_id'});
+ cellId.append(nodeIcons);
+ cellId.append(nodeId);
+ nodeId.html(this.Id);
+ row.append(cellId);
+ var host = $('<td>');
+ var hostName = $('<div>');
+ var hostLink = $('<a>', {
+ 'href': this.getBaseUrl(),
+ 'target': '_blank',
+ 'data-original-title': this.Address
+ });
+ hostLink.html(this.getHostName());
+ //var hostRoles = $('<span>', {class: 'node_roles'});
+ hostName.append(hostLink);
+ //hostName.append(hostRoles);
+ hostLink.tooltip({html: true});
+ host.append(hostName);
+ var state = $('<div>', {class: 'statecontainer'});
+ var loadAverage = $('<div>', {
+ 'class': 'usageblock progress',
+ 'data-original-title': 'Load average'
+ });
+ var loadAverageBar = $('<div>', {
+ class: 'progress-bar',
+ role: 'progressbar'
+ });
+ loadAverage.append(loadAverageBar);
+ loadAverage.tooltip({html: true});
+ state.append(loadAverage);
+ host.append(state);
+ row.append(host);
+ /*var uptime = $('<td>', {class: 'uptime_place'}).hide();
+ row.append(uptime);
+ var cpu = $('<td>', {class: 'cpu_place'}).hide();
+ row.append(cpu);*/
+ /*var interconnect = $('<td>', {class: 'interconnect_place'});
+ row.append(interconnect);*/
+ /*var disks = $('<td>', {class: 'disk_place tablet_place'}).hide();
+ row.append(disks);*/
+ this.domElement = row[0];
+ this.domElementNodeIcons = nodeIcons[0];
+ this.domElementHostLink = hostLink[0];
+ //this.domElementUpTime = uptime[0];
+ //this.domElementRoles = hostRoles[0];
+ this.domElementLoadAverageBar = loadAverageBar[0];
+}
+
+Node.prototype.getIcon = function(icon, color) {
+ return "<span class='glyphicon glyphicon-" + icon + " node_icon' style='color:" + color + "'></span>";
+}
+
+Node.prototype.updateUpTime = function() {
+ if (this.sysInfo !== undefined) {
+ if (this.sysInfo.StartTime) {
+ var currentTime = getTime();
+ var startTime = this.sysInfo.StartTime;
+ var upTime = currentTime - startTime;
+ $(this.domElementUpTime).text(upTimeToString(upTime));
+ }
+ }
+}
+
+Node.prototype.updateToolTip = function() {
+ var sysInfo = this.sysInfo;
+ var tooltip = '<table class="tooltip-table">';
+
+ if (sysInfo) {
+ if (sysInfo.DataCenter) {
+ tooltip += '<tr><td>Datacenter</td><td>' + sysInfo.DataCenter + '</td></tr>';
+ }
+
+ if (sysInfo.Rack) {
+ tooltip += '<tr><td>Rack</td><td>' + sysInfo.Rack + '</td></tr>';
+ }
+
+ if (sysInfo.Tenants) {
+ tooltip += '<tr><td>Tenant</td><td>' + sysInfo.Tenants[0] + '</td></tr>';
+ }
+ }
+
+ if (this.Host) {
+ tooltip += '<tr><td>Host</td><td>' + this.Host + '</td></tr>';
+ }
+
+ if (this.Address) {
+ tooltip += '<tr><td>Address</td><td>' + this.Address + '</td></tr>';
+ }
+
+ if (sysInfo) {
+ if (sysInfo.Endpoints !== undefined && sysInfo.Endpoints.length > 0) {
+ var endpoints = '';
+ sysInfo.Endpoints.forEach(function(item) {
+ endpoints += '<tr><td>' + item.Name + '</td><td>' + item.Address + '</td></tr>';
+ });
+ tooltip += endpoints;
+ }
if (sysInfo.ConfigState !== undefined) {
tooltip += '<tr><td>Configuration</td><td>' + sysInfo.ConfigState + '</td></tr>';
}
- }
- tooltip += '</table>'
- this.domElementHostLink.setAttribute('data-original-title', tooltip);
-}
-
-Node.prototype.getHost = function() {
- if (this.Host) {
- return this.Host;
- }
- if (this.Address) {
- return this.Address;
- }
- return window.location.hostname;
-}
-
-Node.prototype.getEndpoint = function(name) {
- if (this.sysInfo.Endpoints) {
- var endpoint = this.sysInfo.Endpoints.find(function(item) {
- return item.Name === name;
- });
- if (endpoint) {
- return endpoint.Address;
- }
- }
- return undefined;
-}
-
-Node.prototype.getViewerPort = function() {
- var viewerEndpoint = this.getEndpoint('http-mon');
- if (viewerEndpoint) {
- return Number(viewerEndpoint.split(':')[1]);
- }
- var role = this.getRoleName();
- if (role) {
- var port = this.RoleToMonPort[role];
- if (port) {
- return Number(port);
- }
- }
- return 8765;
-}
-
-Node.prototype.getBaseUrl = function() {
- return getBaseUrlForHost(this.getHost() + ':' + this.getViewerPort());
-}
-
-Node.prototype.getViewerUrl = function() {
- return this.getBaseUrl() + 'viewer/';
-}
-
-Node.prototype.getUrlFor = function(url) {
- if (url === 'json/config' || this.directApi) {
- return this.getViewerUrl() + url;
- }
- return url;
-}
-
-Node.prototype.getHostName = function() {
- var host = this.getHost();
- var idx = host.indexOf('.');
- if (idx !== -1) {
- host = host.substr(0, idx);
- }
- return host;
-}
-
-Node.prototype.getDomainName = function() {
- var domain = this.getHost();
- var idx = domain.indexOf('.');
- if (idx !== -1) {
- domain = domain.substr(idx + 1);
- }
- return domain;
-}
-
-Node.prototype.hasRole = function() {
- return this.sysInfo.Roles !== undefined && this.sysInfo.Roles.length > 0;
-}
-
-Node.prototype.getRoleName = function() {
- if (this.hasRole()) {
- return this.sysInfo.Roles.join(',');
- }
- return 'Default';
-}
-
-Node.prototype.getTenantName = function() {
- return this.group.view.getTenantName(this.sysInfo);
-}
-
-Node.prototype.getDC = function() {
- if (this.sysInfo.DataCenter !== undefined) {
- return this.sysInfo.DataCenter;
- }
- return 'Unknown';
-}
-
-Node.prototype.getRackName = function() {
- if (this.sysInfo.Rack !== undefined) {
- return this.sysInfo.Rack;
- }
- return 'Unknown';
-}
-
-Node.prototype.getStatus = function() {
- if (this.sysInfo !== undefined) {
- if (flagToColor(this.sysInfo.SystemState) === green) {
- return 'Good';
- } else {
- return 'Bad';
- }
- }
- return 'Unknown';
-}
-
-Node.prototype.getStatusColor = function() {
- if (this.sysInfo && this.sysInfo.SystemState && !this.disconnected) {
- return flagToColor(this.sysInfo.SystemState);
- } else {
- return black;
- }
-}
-
-Node.prototype.getAge = function() {
- var uptime = this.getUptime();
- if (uptime) {
- if (uptime < 60 * 1000) {
- return 'Less than a minute';
- } else if (uptime < 60 * 60 * 1000) {
- return 'Less than a hour';
- } else if (uptime < 24 * 60 * 60 * 1000) {
- return 'Less than a day';
- } else {
- return 'More than a day';
- }
- }
- return 'Unknown';
-}
-
-Node.prototype.getVersion = function() {
- if (this.sysInfo && this.sysInfo.Version) {
- return this.sysInfo.Version;
- }
- return 'Unknown';
-}
-
-Node.prototype.getAgeColor = function() {
- var uptime = this.getUptime();
- if (uptime) {
- if (uptime < 60 * 1000) {
- return red;
- } else if (uptime < 60 * 60 * 1000) {
- return orange;
- } else if (uptime < 24 * 60 * 60 * 1000) {
- return yellow;
- } else {
- return green;
- }
- }
- return black;
-}
-
-Node.prototype.getLoadAverage = function(index) {
- if (index === undefined) {
- index = 0;
- }
- if (this.sysInfo !== undefined
- && this.sysInfo.LoadAverage !== undefined
- && this.sysInfo.LoadAverage.length > index
- && this.sysInfo.NumberOfCpus !== undefined
- && this.sysInfo.NumberOfCpus !== 0) {
- return this.sysInfo.LoadAverage[index] / this.sysInfo.NumberOfCpus;
- }
- return 0;
-}
-
-Node.prototype.getTooltipText = function() {
- var text = '#' + this.Id + ' ' + this.getHostName();
- if (this.hasRole()) {
- text = text + '<br>' + this.getRoleName();
- }
- return text;
-}
-
-Node.prototype.getUptime = function() {
- if (this.sysInfo !== undefined && this.sysInfo.StartTime !== undefined) {
- var now = getTime();
- var uptime = now - this.sysInfo.StartTime;
- if (uptime < 0) {
- return undefined;
- }
- return uptime;
- }
- return undefined;
-}
-
-Node.prototype.getDiskUsage = function() {
+ }
+ tooltip += '</table>'
+ this.domElementHostLink.setAttribute('data-original-title', tooltip);
+}
+
+Node.prototype.getHost = function() {
+ if (this.Host) {
+ return this.Host;
+ }
+ if (this.Address) {
+ return this.Address;
+ }
+ return window.location.hostname;
+}
+
+Node.prototype.getEndpoint = function(name) {
+ if (this.sysInfo.Endpoints) {
+ var endpoint = this.sysInfo.Endpoints.find(function(item) {
+ return item.Name === name;
+ });
+ if (endpoint) {
+ return endpoint.Address;
+ }
+ }
+ return undefined;
+}
+
+Node.prototype.getViewerPort = function() {
+ var viewerEndpoint = this.getEndpoint('http-mon');
+ if (viewerEndpoint) {
+ return Number(viewerEndpoint.split(':')[1]);
+ }
+ var role = this.getRoleName();
+ if (role) {
+ var port = this.RoleToMonPort[role];
+ if (port) {
+ return Number(port);
+ }
+ }
+ return 8765;
+}
+
+Node.prototype.getBaseUrl = function() {
+ return getBaseUrlForHost(this.getHost() + ':' + this.getViewerPort());
+}
+
+Node.prototype.getViewerUrl = function() {
+ return this.getBaseUrl() + 'viewer/';
+}
+
+Node.prototype.getUrlFor = function(url) {
+ if (url === 'json/config' || this.directApi) {
+ return this.getViewerUrl() + url;
+ }
+ return url;
+}
+
+Node.prototype.getHostName = function() {
+ var host = this.getHost();
+ var idx = host.indexOf('.');
+ if (idx !== -1) {
+ host = host.substr(0, idx);
+ }
+ return host;
+}
+
+Node.prototype.getDomainName = function() {
+ var domain = this.getHost();
+ var idx = domain.indexOf('.');
+ if (idx !== -1) {
+ domain = domain.substr(idx + 1);
+ }
+ return domain;
+}
+
+Node.prototype.hasRole = function() {
+ return this.sysInfo.Roles !== undefined && this.sysInfo.Roles.length > 0;
+}
+
+Node.prototype.getRoleName = function() {
+ if (this.hasRole()) {
+ return this.sysInfo.Roles.join(',');
+ }
+ return 'Default';
+}
+
+Node.prototype.getTenantName = function() {
+ return this.group.view.getTenantName(this.sysInfo);
+}
+
+Node.prototype.getDC = function() {
+ if (this.sysInfo.DataCenter !== undefined) {
+ return this.sysInfo.DataCenter;
+ }
+ return 'Unknown';
+}
+
+Node.prototype.getRackName = function() {
+ if (this.sysInfo.Rack !== undefined) {
+ return this.sysInfo.Rack;
+ }
+ return 'Unknown';
+}
+
+Node.prototype.getStatus = function() {
+ if (this.sysInfo !== undefined) {
+ if (flagToColor(this.sysInfo.SystemState) === green) {
+ return 'Good';
+ } else {
+ return 'Bad';
+ }
+ }
+ return 'Unknown';
+}
+
+Node.prototype.getStatusColor = function() {
+ if (this.sysInfo && this.sysInfo.SystemState && !this.disconnected) {
+ return flagToColor(this.sysInfo.SystemState);
+ } else {
+ return black;
+ }
+}
+
+Node.prototype.getAge = function() {
+ var uptime = this.getUptime();
+ if (uptime) {
+ if (uptime < 60 * 1000) {
+ return 'Less than a minute';
+ } else if (uptime < 60 * 60 * 1000) {
+ return 'Less than a hour';
+ } else if (uptime < 24 * 60 * 60 * 1000) {
+ return 'Less than a day';
+ } else {
+ return 'More than a day';
+ }
+ }
+ return 'Unknown';
+}
+
+Node.prototype.getVersion = function() {
+ if (this.sysInfo && this.sysInfo.Version) {
+ return this.sysInfo.Version;
+ }
+ return 'Unknown';
+}
+
+Node.prototype.getAgeColor = function() {
+ var uptime = this.getUptime();
+ if (uptime) {
+ if (uptime < 60 * 1000) {
+ return red;
+ } else if (uptime < 60 * 60 * 1000) {
+ return orange;
+ } else if (uptime < 24 * 60 * 60 * 1000) {
+ return yellow;
+ } else {
+ return green;
+ }
+ }
+ return black;
+}
+
+Node.prototype.getLoadAverage = function(index) {
+ if (index === undefined) {
+ index = 0;
+ }
+ if (this.sysInfo !== undefined
+ && this.sysInfo.LoadAverage !== undefined
+ && this.sysInfo.LoadAverage.length > index
+ && this.sysInfo.NumberOfCpus !== undefined
+ && this.sysInfo.NumberOfCpus !== 0) {
+ return this.sysInfo.LoadAverage[index] / this.sysInfo.NumberOfCpus;
+ }
+ return 0;
+}
+
+Node.prototype.getTooltipText = function() {
+ var text = '#' + this.Id + ' ' + this.getHostName();
+ if (this.hasRole()) {
+ text = text + '<br>' + this.getRoleName();
+ }
+ return text;
+}
+
+Node.prototype.getUptime = function() {
+ if (this.sysInfo !== undefined && this.sysInfo.StartTime !== undefined) {
+ var now = getTime();
+ var uptime = now - this.sysInfo.StartTime;
+ if (uptime < 0) {
+ return undefined;
+ }
+ return uptime;
+ }
+ return undefined;
+}
+
+Node.prototype.getDiskUsage = function() {
if (this.sysInfo !== undefined && this.sysInfo.MaxDiskUsage !== undefined) {
return this.sysInfo.MaxDiskUsage;
- } else {
- return 0;
- }
-}
-
-Node.prototype.getIdGroup = function() {
- var start = Math.floor(this.Id / 100) * 100;
- if (start === 0) {
- return '1..99';
- } else if (start < 1000) {
- return start + '..' + (start + 99);
- } else {
- start = Math.floor((this.Id - 1000) / 3200) * 3200 + 1000;
- return start + '..' + (start + 3199);
- }
-}
-
-Node.prototype.refreshSysInfo = function() {
- this.refreshInProgress++;
- var request = {
- alive: 1,
- enums: 1,
- node_id: this.Id,
- timeout: Node.prototype.timeout,
- since: this.sysInfoChangeTime
- };
- $.ajax({
- url: this.getUrlFor('json/sysinfo'),
- data: request,
- success: this.onSysInfo.bind(this),
- error: this.onError.bind(this),
- timeout: request.timeout
- });
-}
-
-Node.prototype.refreshNodeInfo = function() {
- var request = {
- merge: 0,
- node_id: this.Id,
- timeout: Node.prototype.timeout,
- since: this.nodeInfoChangeTime
- };
- $.ajax({
- url: this.getUrlFor('json/nodeinfo'),
- data: request,
- success: this.onNodeInfo.bind(this),
- timeout: request.timeout
- });
-}
-
-Node.prototype.refreshTabletInfo = function() {
- var request = {
- alive: 1,
- enums: 1,
- group: 'Type,Leader',
- filter: 'State=Active',
- node_id: this.Id,
- timeout: Node.prototype.timeout
- };
- $.ajax({
- url: this.getUrlFor('json/tabletinfo'),
- data: request,
- success: this.onTabletInfo.bind(this),
- error: this.onError.bind(this),
- timeout: request.timeout
- });
-}
-
-Node.prototype.refreshPDiskInfo = function() {
- var request = {
- enums: 1,
- node_id: this.Id,
- timeout: Node.prototype.timeout,
- since: this.pDiskInfoChangeTime
- };
- this.pDiskSince = this.pDiskInfoChangeTime;
- $.ajax({
- url: this.getUrlFor('json/pdiskinfo'),
- data: request,
- success: this.onPDiskInfo.bind(this),
- timeout: request.timeout
- });
-}
-
-Node.prototype.refreshVDiskInfo = function() {
- var request = {
- enums: 1,
- node_id: this.Id,
- timeout: Node.prototype.timeout,
- since: this.vDiskInfoChangeTime
- };
- $.ajax({
- url: this.getUrlFor('json/vdiskinfo'),
- data: request,
- success: this.onVDiskInfo.bind(this),
- timeout: request.timeout
- });
-}
-
-Node.prototype.refreshConfig = function() {
- $.ajax({
- url: this.getUrlFor('json/config'),
- success: this.onConfig.bind(this),
- error: this.onConfigError.bind(this)
- });
-}
-
-Node.prototype.onSysInfo = function(data) {
- --this.refreshInProgress;
- if (data.SystemStateInfo !== undefined) {
- for (var i in data.SystemStateInfo) {
- var update = data.SystemStateInfo[i];
- if (!this.sysInfoChangeTime || update.ChangeTime < this.sysInfoChangeTime) {
- this.sysInfoChangeTime = update.ChangeTime;
- }
- this.updateSysInfo(update);
- }
- if (data.ResponseTime != 0) {
- this.sysInfoChangeTime = Number(data.ResponseTime);
- }
- } else {
- if (data.Error || !this.sysInfoChangeTime) {
- this.onDisconnect();
- } else {
- if (this.visible) {
- this.updateUpTime();
- }
- }
- }
- this.sysInfoUpdateTime = getTime();
-}
-
-Node.prototype.onTabletInfo = function(data) {
- /*var nodeData = data[this.Id];
- if (nodeData !== undefined && nodeData !== null) {
- var update = nodeData.NodeStateInfo;
- if (update !== undefined) {
- this.updateNodeInfo(update);
- }
- if (nodeData.ResponseTime != 0) {
- this.nodeInfoChangeTime = nodeData.ResponseTime;
- }
- }*/
-
- if (!data.TabletStateInfo) {
- data.TabletStateInfo = [];
- }
- this.tabletMap.updateTabletInfo(data.TabletStateInfo);
-
- if (data.ResponseTime != 0) {
- this.tabletInfoChangeTime = data.ResponseTime;
- }
- this.tabletInfoUpdateTime = getTime();
-}
-
-Node.prototype.onNodeInfo = function(data) {
- var nodeData = data[this.Id];
- if (nodeData !== undefined && nodeData !== null) {
- var update = nodeData.NodeStateInfo;
- if (update !== undefined) {
- this.updateNodeInfo(update);
- }
- if (nodeData.ResponseTime != 0) {
- this.nodeInfoChangeTime = nodeData.ResponseTime;
- }
- }
-}
-
-Node.prototype.onPDiskInfo = function(data) {
- if (data.PDiskStateInfo) {
- this.updatePDiskInfo(data.PDiskStateInfo);
- } else if (this.haveDisks && !this.pDiskSince) {
- //this.haveDisks = false;
- }
-
- if (data.ResponseTime != 0) {
- this.pDiskInfoChangeTime = data.ResponseTime;
- }
- this.pDiskInfoUpdateTime = getTime();
-}
-
-Node.prototype.onVDiskInfo = function(data) {
- if (data.VDiskStateInfo) {
- this.updateVDiskInfo(data.VDiskStateInfo);
- }
- if (this.vDiskDeltaUpdates >= 10) {
- delete this.vDiskInfoChangeTime;
- this.vDiskDeltaUpdates = 0;
- } else if (data.ResponseTime != 0) {
- this.vDiskInfoChangeTime = data.ResponseTime;
- this.vDiskDeltaUpdates++;
- }
- this.vDiskInfoUpdateTime = getTime();
-}
-
-Node.prototype.onConfig = function(data) {
- this.config = data;
- if (this.group) {
- var referenceConfig = this.group.view.getConfig();
- if (referenceConfig) {
- var errors = [];
- for (var name in referenceConfig) {
- if (JSON.stringify(this.config[name]) !== JSON.stringify(referenceConfig[name])) {
- console.error('Config mismatch in ' + name + ' for ' + this.getHost());
- console.log(this.config[name]);
- console.log(referenceConfig[name]);
- errors.push(name);
- }
- }
- if (errors.length > 0) {
- this.domElementNodeIcons.innerHTML = this.getIcon('exclamation-sign', red);
- }
- }
- }
-}
-
-Node.prototype.onConfigError = function() {
- this.config = false;
-}
-
-Node.prototype.getBackgroundColor = function(color) {
- switch (color) {
- case red:
- return '#ffe0e0';
- case yellow:
- return '#ffffe0';
- case orange:
- return '#fff0e0';
- case blue:
- return '#e0e0ff';
- default:
- return null;
- }
-}
-
-Node.prototype.updateSysInfoStatsOnly = function(update) {
- var sysInfo = updateObject(this.sysInfo, update);
- if (sysInfo.SystemState !== undefined) {
- var color = flagToColor(sysInfo.SystemState);
- //this.domElementOverallState.style.backgroundColor = color;
- if (this.color != color) {
- this.domElement.style.backgroundColor = this.getBackgroundColor(color);
- }
- if (sysInfo.StartTime && this.disconnected) {
- var row = $(this.domElement);
- var disks = row.find('.disk_place');
- disks.empty();
- delete this.tabletMap;
- delete this.diskMap;
- this.tabletMap = new TabletMap();
- this.diskMap = new DiskMap({node: this});
- disks.append(this.diskMap.domElement);
- disks.append(this.tabletMap.domElement);
- row.children().css('filter', '');
- this.disconnected = false;
- }
- if (this.group) {
- this.group.view.updateGroup(this);
- this.group.updateNodeState(this);
- }
- this.color = color;
- }
- if (update.Roles !== undefined && update.Roles.length > 0 && !this.fallbackDirectApi) {
- this.directApi = true;
- }
- /*if (sysInfo.Roles !== undefined && sysInfo.Roles.length > 0 && this.domElementRoles.innerHTML.length === 0) {
- this.domElementRoles.innerHTML = sysInfo.Roles.join(',');
- }*/
-}
-
-Node.prototype.updateSysInfo = function(update) {
- this.updateSysInfoStatsOnly(update);
-
- var sysInfo = this.sysInfo;
-
- if (sysInfo.StartTime && this.visible) {
- this.updateUpTime();
- }
-
- /*if (sysInfo.MessageBusState !== undefined) {
- this.domElementMessageBusState.style.backgroundColor = flagToColor(sysInfo.MessageBusState);
- }*/
-
- /*if (sysInfo.GRpcState !== undefined) {
- this.domElementGRpcState.style.backgroundColor = flagToColor(sysInfo.GRpcState);
- }*/
-
- if (sysInfo.LoadAverage !== undefined) {
- var percent = sysInfo.LoadAverage[0] * 100 / sysInfo.NumberOfCpus;
- if (percent > 100) {
- percent = 100;
- }
- var progress = this.domElementLoadAverageBar;
- if (percent < 75) {
- progress.style.backgroundColor = green;
- } else if (percent < 85) {
- progress.style.backgroundColor = yellow;
- } else if (percent < 95) {
- progress.style.backgroundColor = orange;
- } else {
- progress.style.backgroundColor = red;
- }
- progress.style.width = percent + '%';
- progress.parentNode.setAttribute('data-original-title', 'LoadAverage: ' + sysInfo.LoadAverage + '<br/>Cores: ' + sysInfo.NumberOfCpus);
- }
-
- if (sysInfo.PoolStats !== undefined) {
- var poolMap = this.poolMap;
- poolMap.setPoolMap(sysInfo.PoolStats);
- }
-
- if (sysInfo.MemoryUsed !== undefined) {
- var memBlock = this.memBlock;
- var tip = '<html><table class="tooltip-table">';
- memBlock.setText(bytesToGB3(sysInfo.MemoryUsed));
- tip += '<tr><td>MemoryUsed</td><td>' + bytesToGB(sysInfo.MemoryUsed) + '</td></tr>';
- if (sysInfo.MemoryLimit !== undefined) {
- memBlock.setUsage(sysInfo.MemoryUsed / sysInfo.MemoryLimit);
- tip += '<tr><td>MemoryLimit</td><td>' + bytesToGB(sysInfo.MemoryLimit) + '</td></tr>';
- } else {
- //memBlock.setUsage(sysInfo.MemoryUsed / 10000000000);
- //tip += '<tr><td>MemoryLimit</td><td>' + bytesToGB(10000000000) + '</td></tr>';
- }
- tip += '</table></html>';
- memBlock.domElement.setAttribute('data-original-title', tip);
- }
+ } else {
+ return 0;
+ }
+}
+
+Node.prototype.getIdGroup = function() {
+ var start = Math.floor(this.Id / 100) * 100;
+ if (start === 0) {
+ return '1..99';
+ } else if (start < 1000) {
+ return start + '..' + (start + 99);
+ } else {
+ start = Math.floor((this.Id - 1000) / 3200) * 3200 + 1000;
+ return start + '..' + (start + 3199);
+ }
+}
+
+Node.prototype.refreshSysInfo = function() {
+ this.refreshInProgress++;
+ var request = {
+ alive: 1,
+ enums: 1,
+ node_id: this.Id,
+ timeout: Node.prototype.timeout,
+ since: this.sysInfoChangeTime
+ };
+ $.ajax({
+ url: this.getUrlFor('json/sysinfo'),
+ data: request,
+ success: this.onSysInfo.bind(this),
+ error: this.onError.bind(this),
+ timeout: request.timeout
+ });
+}
+
+Node.prototype.refreshNodeInfo = function() {
+ var request = {
+ merge: 0,
+ node_id: this.Id,
+ timeout: Node.prototype.timeout,
+ since: this.nodeInfoChangeTime
+ };
+ $.ajax({
+ url: this.getUrlFor('json/nodeinfo'),
+ data: request,
+ success: this.onNodeInfo.bind(this),
+ timeout: request.timeout
+ });
+}
+
+Node.prototype.refreshTabletInfo = function() {
+ var request = {
+ alive: 1,
+ enums: 1,
+ group: 'Type,Leader',
+ filter: 'State=Active',
+ node_id: this.Id,
+ timeout: Node.prototype.timeout
+ };
+ $.ajax({
+ url: this.getUrlFor('json/tabletinfo'),
+ data: request,
+ success: this.onTabletInfo.bind(this),
+ error: this.onError.bind(this),
+ timeout: request.timeout
+ });
+}
+
+Node.prototype.refreshPDiskInfo = function() {
+ var request = {
+ enums: 1,
+ node_id: this.Id,
+ timeout: Node.prototype.timeout,
+ since: this.pDiskInfoChangeTime
+ };
+ this.pDiskSince = this.pDiskInfoChangeTime;
+ $.ajax({
+ url: this.getUrlFor('json/pdiskinfo'),
+ data: request,
+ success: this.onPDiskInfo.bind(this),
+ timeout: request.timeout
+ });
+}
+
+Node.prototype.refreshVDiskInfo = function() {
+ var request = {
+ enums: 1,
+ node_id: this.Id,
+ timeout: Node.prototype.timeout,
+ since: this.vDiskInfoChangeTime
+ };
+ $.ajax({
+ url: this.getUrlFor('json/vdiskinfo'),
+ data: request,
+ success: this.onVDiskInfo.bind(this),
+ timeout: request.timeout
+ });
+}
+
+Node.prototype.refreshConfig = function() {
+ $.ajax({
+ url: this.getUrlFor('json/config'),
+ success: this.onConfig.bind(this),
+ error: this.onConfigError.bind(this)
+ });
+}
+
+Node.prototype.onSysInfo = function(data) {
+ --this.refreshInProgress;
+ if (data.SystemStateInfo !== undefined) {
+ for (var i in data.SystemStateInfo) {
+ var update = data.SystemStateInfo[i];
+ if (!this.sysInfoChangeTime || update.ChangeTime < this.sysInfoChangeTime) {
+ this.sysInfoChangeTime = update.ChangeTime;
+ }
+ this.updateSysInfo(update);
+ }
+ if (data.ResponseTime != 0) {
+ this.sysInfoChangeTime = Number(data.ResponseTime);
+ }
+ } else {
+ if (data.Error || !this.sysInfoChangeTime) {
+ this.onDisconnect();
+ } else {
+ if (this.visible) {
+ this.updateUpTime();
+ }
+ }
+ }
+ this.sysInfoUpdateTime = getTime();
+}
+
+Node.prototype.onTabletInfo = function(data) {
+ /*var nodeData = data[this.Id];
+ if (nodeData !== undefined && nodeData !== null) {
+ var update = nodeData.NodeStateInfo;
+ if (update !== undefined) {
+ this.updateNodeInfo(update);
+ }
+ if (nodeData.ResponseTime != 0) {
+ this.nodeInfoChangeTime = nodeData.ResponseTime;
+ }
+ }*/
+
+ if (!data.TabletStateInfo) {
+ data.TabletStateInfo = [];
+ }
+ this.tabletMap.updateTabletInfo(data.TabletStateInfo);
+
+ if (data.ResponseTime != 0) {
+ this.tabletInfoChangeTime = data.ResponseTime;
+ }
+ this.tabletInfoUpdateTime = getTime();
+}
+
+Node.prototype.onNodeInfo = function(data) {
+ var nodeData = data[this.Id];
+ if (nodeData !== undefined && nodeData !== null) {
+ var update = nodeData.NodeStateInfo;
+ if (update !== undefined) {
+ this.updateNodeInfo(update);
+ }
+ if (nodeData.ResponseTime != 0) {
+ this.nodeInfoChangeTime = nodeData.ResponseTime;
+ }
+ }
+}
+
+Node.prototype.onPDiskInfo = function(data) {
+ if (data.PDiskStateInfo) {
+ this.updatePDiskInfo(data.PDiskStateInfo);
+ } else if (this.haveDisks && !this.pDiskSince) {
+ //this.haveDisks = false;
+ }
+
+ if (data.ResponseTime != 0) {
+ this.pDiskInfoChangeTime = data.ResponseTime;
+ }
+ this.pDiskInfoUpdateTime = getTime();
+}
+
+Node.prototype.onVDiskInfo = function(data) {
+ if (data.VDiskStateInfo) {
+ this.updateVDiskInfo(data.VDiskStateInfo);
+ }
+ if (this.vDiskDeltaUpdates >= 10) {
+ delete this.vDiskInfoChangeTime;
+ this.vDiskDeltaUpdates = 0;
+ } else if (data.ResponseTime != 0) {
+ this.vDiskInfoChangeTime = data.ResponseTime;
+ this.vDiskDeltaUpdates++;
+ }
+ this.vDiskInfoUpdateTime = getTime();
+}
+
+Node.prototype.onConfig = function(data) {
+ this.config = data;
+ if (this.group) {
+ var referenceConfig = this.group.view.getConfig();
+ if (referenceConfig) {
+ var errors = [];
+ for (var name in referenceConfig) {
+ if (JSON.stringify(this.config[name]) !== JSON.stringify(referenceConfig[name])) {
+ console.error('Config mismatch in ' + name + ' for ' + this.getHost());
+ console.log(this.config[name]);
+ console.log(referenceConfig[name]);
+ errors.push(name);
+ }
+ }
+ if (errors.length > 0) {
+ this.domElementNodeIcons.innerHTML = this.getIcon('exclamation-sign', red);
+ }
+ }
+ }
+}
+
+Node.prototype.onConfigError = function() {
+ this.config = false;
+}
+
+Node.prototype.getBackgroundColor = function(color) {
+ switch (color) {
+ case red:
+ return '#ffe0e0';
+ case yellow:
+ return '#ffffe0';
+ case orange:
+ return '#fff0e0';
+ case blue:
+ return '#e0e0ff';
+ default:
+ return null;
+ }
+}
+
+Node.prototype.updateSysInfoStatsOnly = function(update) {
+ var sysInfo = updateObject(this.sysInfo, update);
+ if (sysInfo.SystemState !== undefined) {
+ var color = flagToColor(sysInfo.SystemState);
+ //this.domElementOverallState.style.backgroundColor = color;
+ if (this.color != color) {
+ this.domElement.style.backgroundColor = this.getBackgroundColor(color);
+ }
+ if (sysInfo.StartTime && this.disconnected) {
+ var row = $(this.domElement);
+ var disks = row.find('.disk_place');
+ disks.empty();
+ delete this.tabletMap;
+ delete this.diskMap;
+ this.tabletMap = new TabletMap();
+ this.diskMap = new DiskMap({node: this});
+ disks.append(this.diskMap.domElement);
+ disks.append(this.tabletMap.domElement);
+ row.children().css('filter', '');
+ this.disconnected = false;
+ }
+ if (this.group) {
+ this.group.view.updateGroup(this);
+ this.group.updateNodeState(this);
+ }
+ this.color = color;
+ }
+ if (update.Roles !== undefined && update.Roles.length > 0 && !this.fallbackDirectApi) {
+ this.directApi = true;
+ }
+ /*if (sysInfo.Roles !== undefined && sysInfo.Roles.length > 0 && this.domElementRoles.innerHTML.length === 0) {
+ this.domElementRoles.innerHTML = sysInfo.Roles.join(',');
+ }*/
+}
+
+Node.prototype.updateSysInfo = function(update) {
+ this.updateSysInfoStatsOnly(update);
+
+ var sysInfo = this.sysInfo;
+
+ if (sysInfo.StartTime && this.visible) {
+ this.updateUpTime();
+ }
+
+ /*if (sysInfo.MessageBusState !== undefined) {
+ this.domElementMessageBusState.style.backgroundColor = flagToColor(sysInfo.MessageBusState);
+ }*/
+
+ /*if (sysInfo.GRpcState !== undefined) {
+ this.domElementGRpcState.style.backgroundColor = flagToColor(sysInfo.GRpcState);
+ }*/
+
+ if (sysInfo.LoadAverage !== undefined) {
+ var percent = sysInfo.LoadAverage[0] * 100 / sysInfo.NumberOfCpus;
+ if (percent > 100) {
+ percent = 100;
+ }
+ var progress = this.domElementLoadAverageBar;
+ if (percent < 75) {
+ progress.style.backgroundColor = green;
+ } else if (percent < 85) {
+ progress.style.backgroundColor = yellow;
+ } else if (percent < 95) {
+ progress.style.backgroundColor = orange;
+ } else {
+ progress.style.backgroundColor = red;
+ }
+ progress.style.width = percent + '%';
+ progress.parentNode.setAttribute('data-original-title', 'LoadAverage: ' + sysInfo.LoadAverage + '<br/>Cores: ' + sysInfo.NumberOfCpus);
+ }
+
+ if (sysInfo.PoolStats !== undefined) {
+ var poolMap = this.poolMap;
+ poolMap.setPoolMap(sysInfo.PoolStats);
+ }
+
+ if (sysInfo.MemoryUsed !== undefined) {
+ var memBlock = this.memBlock;
+ var tip = '<html><table class="tooltip-table">';
+ memBlock.setText(bytesToGB3(sysInfo.MemoryUsed));
+ tip += '<tr><td>MemoryUsed</td><td>' + bytesToGB(sysInfo.MemoryUsed) + '</td></tr>';
+ if (sysInfo.MemoryLimit !== undefined) {
+ memBlock.setUsage(sysInfo.MemoryUsed / sysInfo.MemoryLimit);
+ tip += '<tr><td>MemoryLimit</td><td>' + bytesToGB(sysInfo.MemoryLimit) + '</td></tr>';
+ } else {
+ //memBlock.setUsage(sysInfo.MemoryUsed / 10000000000);
+ //tip += '<tr><td>MemoryLimit</td><td>' + bytesToGB(10000000000) + '</td></tr>';
+ }
+ tip += '</table></html>';
+ memBlock.domElement.setAttribute('data-original-title', tip);
+ }
if (sysInfo.ConfigState === 'Outdated') {
this.domElementNodeIcons.innerHTML = this.getIcon('exclamation-sign', red);
}
-
- this.domElementHostLink.setAttribute('href', this.getBaseUrl());
-}
-
-Node.prototype.onNodeClick = function(clickData) {
- this.nodeView.scrollToNodePosition(clickData.position);
-}
-
-Node.prototype.updateNodeInfo = function(update) {
- var nodeMap = this.nodeMap;
- if (nodeMap === null) {
- nodeMap = new NodeMap({
- nodes: this.nodeView.nodesCount,
- maxWidth: 250,
- onNodeClick: this.onNodeClick.bind(this)
- });
- }
- for (var i = 0; i < update.length; i++) {
- var stateInfo = update[i];
- var peerName = stateInfo.PeerName;
- var id = getNodeIdFromPeerName(peerName);
- var nodeInfo = this.nodeInfo[id];
- if (nodeInfo === undefined
- || nodeInfo.Connected !== stateInfo.Connected
- || nodeInfo.ConnectStatus !== stateInfo.ConnectStatus) {
- if (nodeInfo === undefined) {
- nodeInfo = this.nodeInfo[id] = {};
- }
- nodeInfo = updateObject(nodeInfo, stateInfo);
- var node = this.nodeView.nodes[id];
- if (node !== undefined) {
- var position = node.position;
- if (nodeInfo.Connected === undefined) {
- nodeMap.setNodeMap(position, lightgrey, peerName);
- } else {
- var color;
- if (nodeInfo.Connected) {
- color = 'lightgreen';
- if (nodeInfo.ConnectStatus !== undefined) {
- switch (nodeInfo.ConnectStatus) {
- case 1:
- color = green;
- break;
- case 2:
- color = yellow;
- break;
- case 3:
- color = orange;
- break;
- case 4:
- color = red;
- break;
- }
- }
- nodeMap.setNodeMap(position, color, peerName);
- } else {
- nodeMap.setNodeMap(position, 'red', peerName);
- }
- }
- }
- }
- }
- nodeMap.setNodeMap(this.position, '#009900');
- if (this.nodeMap === null) {
- var interconnectPlace = $(this.domElement).find('.interconnect_place');
- interconnectPlace.empty();
- interconnectPlace.append(nodeMap.domElement);
- this.nodeMap = nodeMap;
- }
-}
-
-Node.prototype.updatePDiskInfo = function(update) {
- var diskMap = this.diskMap;
- if (!diskMap) {
- this.diskMap = diskMap = new DiskMap({node: this});
- }
-
- var nodeId = this.Id;
- update.forEach(function(update) {
- if (!update.NodeId) {
- update.NodeId = nodeId;
- }
- diskMap.updatePDiskInfo(update);
- });
-}
-
-Node.prototype.updateVDiskInfo = function(update) {
- var diskMap = this.diskMap;
- if (!diskMap) {
- this.diskMap = diskMap = new DiskMap({node: this});
- }
-
- var nodeId = this.Id;
- var vDisksCount = diskMap.vDisksCount;
- update.forEach(function(update) {
- if (!update.NodeId) {
- update.NodeId = nodeId;
- }
- diskMap.updateVDiskInfo(update);
- });
-
- if (!this.vDiskInfoChangeTime || vDisksCount != diskMap.vDisksCount) {
- diskMap.resizeVDisks();
- }
-}
-
-Node.prototype.onDisconnect = function() {
- if (this.sysInfo && this.sysInfo.StartTime) {
- delete this.sysInfo.StartTime;
- delete this.sysInfoChangeTime;
- delete this.vDiskInfoChangeTime;
- delete this.pDiskInfoChangeTime;
- this.vDiskDeltaUpdates = 0;
- }
- delete this.config;
- if (!this.disconnected) {
- this.updateSysInfoStatsOnly({SystemState: 'Red'});
- $(this.domElement).children().css('filter', 'grayscale(100%)');
- this.disconnected = true;
- }
-}
-
-Node.prototype.onError = function(jqXHR, textStatus, errorThrown) {
- this.refreshInProgress = 0;
- if (this.directApi) {
- console.log('Fallback to non-direct API for Node#' + this.Id);
- this.directApi = false;
- this.fallbackDirectApi = true;
- } else {
- this.onDisconnect();
- }
-}
-
-Node.prototype.refresh = function() {
- if (this.refreshInProgress === 0) {
- var now = getTime();
- if (!this.sysInfoUpdateTime || now - this.sysInfoUpdateTime > this.minSysInfoUpdatePeriod) {
- this.refreshSysInfo();
- }
- if (!this.tabletInfoUpdateTime || now - this.tabletInfoUpdateTime > this.minTabletInfoUpdatePeriod) {
- this.refreshTabletInfo();
- }
- //this.refreshNodeInfo();
- if (this.haveDisks) {
- if (!this.pDiskInfoUpdateTime || now - this.pDiskInfoUpdateTime > this.minPDiskInfoUpdatePeriod) {
- this.refreshPDiskInfo();
- }
- if (!this.vDiskInfoUpdateTime || now - this.vDiskInfoUpdateTime > this.minVDiskInfoUpdatePeriod) {
- this.refreshVDiskInfo();
- }
- }
- /*if (this.config === undefined && this.sysInfo && this.sysInfo.Host) {
- this.refreshConfig();
- }*/
- }
-}
-
-Node.prototype.appear = function() {
- this.visible = true;
- var row = $(this.domElement);
- var uptime = $('<td>', {class: 'uptime_place'});
- var cpu = $('<td>', {class: 'cpu_place'});
- var mem = $('<td>', {class: 'mem_place'});
- var disks = $('<td>', {class: 'disk_place tablet_place'});
- this.domElementUpTime = uptime[0];
- this.updateToolTip();
- this.updateUpTime();
- if (this.poolMap) {
- this.poolMap.restoreTooltips();
- cpu.append(this.poolMap.domElement);
- }
- if (this.memBlock) {
- this.memBlock.restoreTooltips();
- mem.append(this.memBlock.domElement);
- }
-
- if (this.diskMap) {
- this.diskMap.restoreTooltips();
- this.diskMap.updatePDiskClasses();
- this.diskMap.updateVDiskClasses();
- this.diskMap.resizeVDisks();
- disks.append(this.diskMap.domElement);
- }
- if (this.tabletMap) {
- this.tabletMap.restoreTooltips();
- disks.append(this.tabletMap.domElement);
- }
-
- row.append(uptime);
- row.append(cpu);
- row.append(mem);
- row.append(disks);
- if (this.disconnected) {
- $(this.domElement).children().css('filter', 'grayscale(100%)');
- }
-}
-
-Node.prototype.disappear = function() {
- this.visible = false;
- $(this.domElement).find('.uptime_place').remove();
- $(this.domElement).find('.cpu_place').remove();
- $(this.domElement).find('.mem_place').remove();
- $(this.domElement).find('.disk_place').remove();
- //$(this.domElement).find('.tablet_place').hide();
-}
+
+ this.domElementHostLink.setAttribute('href', this.getBaseUrl());
+}
+
+Node.prototype.onNodeClick = function(clickData) {
+ this.nodeView.scrollToNodePosition(clickData.position);
+}
+
+Node.prototype.updateNodeInfo = function(update) {
+ var nodeMap = this.nodeMap;
+ if (nodeMap === null) {
+ nodeMap = new NodeMap({
+ nodes: this.nodeView.nodesCount,
+ maxWidth: 250,
+ onNodeClick: this.onNodeClick.bind(this)
+ });
+ }
+ for (var i = 0; i < update.length; i++) {
+ var stateInfo = update[i];
+ var peerName = stateInfo.PeerName;
+ var id = getNodeIdFromPeerName(peerName);
+ var nodeInfo = this.nodeInfo[id];
+ if (nodeInfo === undefined
+ || nodeInfo.Connected !== stateInfo.Connected
+ || nodeInfo.ConnectStatus !== stateInfo.ConnectStatus) {
+ if (nodeInfo === undefined) {
+ nodeInfo = this.nodeInfo[id] = {};
+ }
+ nodeInfo = updateObject(nodeInfo, stateInfo);
+ var node = this.nodeView.nodes[id];
+ if (node !== undefined) {
+ var position = node.position;
+ if (nodeInfo.Connected === undefined) {
+ nodeMap.setNodeMap(position, lightgrey, peerName);
+ } else {
+ var color;
+ if (nodeInfo.Connected) {
+ color = 'lightgreen';
+ if (nodeInfo.ConnectStatus !== undefined) {
+ switch (nodeInfo.ConnectStatus) {
+ case 1:
+ color = green;
+ break;
+ case 2:
+ color = yellow;
+ break;
+ case 3:
+ color = orange;
+ break;
+ case 4:
+ color = red;
+ break;
+ }
+ }
+ nodeMap.setNodeMap(position, color, peerName);
+ } else {
+ nodeMap.setNodeMap(position, 'red', peerName);
+ }
+ }
+ }
+ }
+ }
+ nodeMap.setNodeMap(this.position, '#009900');
+ if (this.nodeMap === null) {
+ var interconnectPlace = $(this.domElement).find('.interconnect_place');
+ interconnectPlace.empty();
+ interconnectPlace.append(nodeMap.domElement);
+ this.nodeMap = nodeMap;
+ }
+}
+
+Node.prototype.updatePDiskInfo = function(update) {
+ var diskMap = this.diskMap;
+ if (!diskMap) {
+ this.diskMap = diskMap = new DiskMap({node: this});
+ }
+
+ var nodeId = this.Id;
+ update.forEach(function(update) {
+ if (!update.NodeId) {
+ update.NodeId = nodeId;
+ }
+ diskMap.updatePDiskInfo(update);
+ });
+}
+
+Node.prototype.updateVDiskInfo = function(update) {
+ var diskMap = this.diskMap;
+ if (!diskMap) {
+ this.diskMap = diskMap = new DiskMap({node: this});
+ }
+
+ var nodeId = this.Id;
+ var vDisksCount = diskMap.vDisksCount;
+ update.forEach(function(update) {
+ if (!update.NodeId) {
+ update.NodeId = nodeId;
+ }
+ diskMap.updateVDiskInfo(update);
+ });
+
+ if (!this.vDiskInfoChangeTime || vDisksCount != diskMap.vDisksCount) {
+ diskMap.resizeVDisks();
+ }
+}
+
+Node.prototype.onDisconnect = function() {
+ if (this.sysInfo && this.sysInfo.StartTime) {
+ delete this.sysInfo.StartTime;
+ delete this.sysInfoChangeTime;
+ delete this.vDiskInfoChangeTime;
+ delete this.pDiskInfoChangeTime;
+ this.vDiskDeltaUpdates = 0;
+ }
+ delete this.config;
+ if (!this.disconnected) {
+ this.updateSysInfoStatsOnly({SystemState: 'Red'});
+ $(this.domElement).children().css('filter', 'grayscale(100%)');
+ this.disconnected = true;
+ }
+}
+
+Node.prototype.onError = function(jqXHR, textStatus, errorThrown) {
+ this.refreshInProgress = 0;
+ if (this.directApi) {
+ console.log('Fallback to non-direct API for Node#' + this.Id);
+ this.directApi = false;
+ this.fallbackDirectApi = true;
+ } else {
+ this.onDisconnect();
+ }
+}
+
+Node.prototype.refresh = function() {
+ if (this.refreshInProgress === 0) {
+ var now = getTime();
+ if (!this.sysInfoUpdateTime || now - this.sysInfoUpdateTime > this.minSysInfoUpdatePeriod) {
+ this.refreshSysInfo();
+ }
+ if (!this.tabletInfoUpdateTime || now - this.tabletInfoUpdateTime > this.minTabletInfoUpdatePeriod) {
+ this.refreshTabletInfo();
+ }
+ //this.refreshNodeInfo();
+ if (this.haveDisks) {
+ if (!this.pDiskInfoUpdateTime || now - this.pDiskInfoUpdateTime > this.minPDiskInfoUpdatePeriod) {
+ this.refreshPDiskInfo();
+ }
+ if (!this.vDiskInfoUpdateTime || now - this.vDiskInfoUpdateTime > this.minVDiskInfoUpdatePeriod) {
+ this.refreshVDiskInfo();
+ }
+ }
+ /*if (this.config === undefined && this.sysInfo && this.sysInfo.Host) {
+ this.refreshConfig();
+ }*/
+ }
+}
+
+Node.prototype.appear = function() {
+ this.visible = true;
+ var row = $(this.domElement);
+ var uptime = $('<td>', {class: 'uptime_place'});
+ var cpu = $('<td>', {class: 'cpu_place'});
+ var mem = $('<td>', {class: 'mem_place'});
+ var disks = $('<td>', {class: 'disk_place tablet_place'});
+ this.domElementUpTime = uptime[0];
+ this.updateToolTip();
+ this.updateUpTime();
+ if (this.poolMap) {
+ this.poolMap.restoreTooltips();
+ cpu.append(this.poolMap.domElement);
+ }
+ if (this.memBlock) {
+ this.memBlock.restoreTooltips();
+ mem.append(this.memBlock.domElement);
+ }
+
+ if (this.diskMap) {
+ this.diskMap.restoreTooltips();
+ this.diskMap.updatePDiskClasses();
+ this.diskMap.updateVDiskClasses();
+ this.diskMap.resizeVDisks();
+ disks.append(this.diskMap.domElement);
+ }
+ if (this.tabletMap) {
+ this.tabletMap.restoreTooltips();
+ disks.append(this.tabletMap.domElement);
+ }
+
+ row.append(uptime);
+ row.append(cpu);
+ row.append(mem);
+ row.append(disks);
+ if (this.disconnected) {
+ $(this.domElement).children().css('filter', 'grayscale(100%)');
+ }
+}
+
+Node.prototype.disappear = function() {
+ this.visible = false;
+ $(this.domElement).find('.uptime_place').remove();
+ $(this.domElement).find('.cpu_place').remove();
+ $(this.domElement).find('.mem_place').remove();
+ $(this.domElement).find('.disk_place').remove();
+ //$(this.domElement).find('.tablet_place').hide();
+}
diff --git a/ydb/core/viewer/content/v2/node_group.js b/ydb/core/viewer/content/v2/node_group.js
index 192d9b4b8bd..98c1afe8d7b 100644
--- a/ydb/core/viewer/content/v2/node_group.js
+++ b/ydb/core/viewer/content/v2/node_group.js
@@ -1,217 +1,217 @@
-function NodeGroup(options) {
- Object.assign(this, options);
- this.nodes = {};
- this.nodeState = {};
- this.nodesTotal = 0;
- this.nodesGood = 0;
- this.buildDomElement();
- this.nodeMap = null;
-}
-
-NodeGroup.prototype.disableDoubleClick = function(e) {
- if (e.detail > 1) {
- e.preventDefault();
- }
-}
-
-NodeGroup.prototype.buildDomElement = function() {
- var nodeBlock = $('<div>', {class: 'node_group_block'});
- var nodeGroupHeader = $('<div>', {class: 'node_group_header'});
- var nodeGroupName = $('<div>', {class: 'node_group_header_name'});
- var nodeGroupInfo = $('<div>', {class: 'node_group_header_info'});
- var nodeGroupNodes = $('<div>', {class: 'node_group_header_nodes'});
- nodeGroupName.html(this.name);
- nodeGroupHeader.mousedown(this.disableDoubleClick.bind(this));
- nodeGroupHeader.click(this.toggleContainer.bind(this));
- nodeGroupInfo.html("<img src='throbber.gif'></img>");
- nodeGroupHeader.append(nodeGroupName);
- nodeGroupHeader.append(nodeGroupNodes);
- nodeGroupHeader.append(nodeGroupInfo);
- nodeBlock.append(nodeGroupHeader);
- var nodeGroupContainer = $('<table>', {class: 'nodelist node_group_container'});
- var nodeGroupHead = $('<thead>');
- var nodeGroupRow = $('<tr>');
- nodeGroupRow.append('<th>#</th>');
- nodeGroupRow.append('<th>Node</th>');
- nodeGroupRow.append('<th>Uptime</th>');
- nodeGroupRow.append('<th>CPU</th>');
- nodeGroupRow.append('<th>RAM</th>');
- /*if (nodesCount <= 32) {
- nodeGroupRow.append('<th>Net</th>');
- } else {
- nodeGroupRow.append('<th>Network</th>');
- }*/
- /*nodeGroupRow.append('<th>Net</th>');*/
- nodeGroupRow.append('<th>Disks & Tablets</th>');
- nodeGroupHead.append(nodeGroupRow);
- var nodeGroupBody = $('<tbody>');
- nodeGroupContainer.append(nodeGroupHead);
- nodeGroupContainer.append(nodeGroupBody);
- nodeBlock.append(nodeGroupContainer);
- this.domElement = nodeBlock[0];
- this.domElementGroupHeader = nodeGroupHeader[0];
- this.domElementGroupHeaderNodes = nodeGroupNodes[0];
- this.domElementGroupInfo = nodeGroupInfo[0];
- this.domElementGroupContainer = nodeGroupContainer[0];
- this.domElementGroupContainerBody = nodeGroupBody[0];
- this.domElementGroupContainer.style.display = 'none';
- nodeBlock.data('group', this);
-}
-
-NodeGroup.prototype.toggleContainer = function() {
- var domElement = this.domElementGroupContainer;
- if (domElement.style.display === 'none') {
- domElement.style.display = 'table';
-
- $(this.domElementGroupHeader).addClass('node_group_header_pressed');
- } else {
- $(this.domElementGroupHeader).removeClass('node_group_header_pressed');
- domElement.style.display = 'none';
- }
-}
-
-NodeGroup.prototype.isEmpty = function() {
- return this.nodesTotal === 0;
-}
-
-NodeGroup.prototype.addNode = function(node) {
- if (node.group !== undefined) {
- node.group.removeNode(node);
- }
-
- var point = this.domElementGroupContainerBody.lastChild;
- if (point === null || $(point).data('node').Id < node.Id) {
- this.domElementGroupContainerBody.appendChild(node.domElement);
- } else {
- for(;;) {
- var prev = point.previousSibling;
- if (prev === null) {
- break;
- }
- if ($(prev).data('node').Id < node.Id) {
- break;
- }
- point = prev;
- }
- this.domElementGroupContainerBody.insertBefore(node.domElement, point);
- }
-
- node.group = this;
- this.nodes[node.Id] = node;
- ++this.nodesTotal;
-}
-
-NodeGroup.prototype.removeNode = function(node) {
- this.domElementGroupContainerBody.removeChild(node.domElement);
- var color = node.color;
- if (color === green) {
- --this.nodesGood;
- }
- delete node.group;
- delete this.nodeState[node.groupPosition];
- delete node.groupPosition;
- delete this.nodes[node.Id];
- --this.nodesTotal;
-}
-
-NodeGroup.prototype.updateNodeStateMap = function(node) {
- var color = flagToColor(node.sysInfo.SystemState);
- var position = node.groupPosition;
- if (position !== undefined) {
- var prevColor = this.nodeState[position];
- if (prevColor !== color) {
- this.nodeState[position] = color;
- this.nodeMap.setNodeMap(position, color, node.getTooltipText());
- var n = node.domElement;
- switch (color) {
- case red:
- n.style.backgroundColor = '#ffe0e0';//red;
- break;
- case orange:
- n.style.backgroundColor = '#ffe0d0';//orange;
- break;
- case yellow:
- n.style.backgroundColor = '#ffffe0';//yellow;
- break;
- case green:
- case grey:
- n.style.backgroundColor = null;
- break;
- }
- var updateInfo = false;
- if (prevColor === undefined || prevColor === grey) {
- if (color === green) {
- this.nodesGood++;
- }
- updateInfo = true;
- } else {
- if (color !== prevColor) {
- if (color === green) {
- this.nodesGood++;
- } else if (prevColor === green) {
- this.nodesGood--;
- }
- updateInfo = true;
- }
- }
- return true;
- }
- }
- return false;
-}
-
-NodeGroup.prototype.updateNodeStateInfo = function() {
- this.domElementGroupInfo.innerHTML = this.nodesTotal + ' nodes';
-}
-
-NodeGroup.prototype.updateNodeState = function(node) {
- var updateInfo = this.updateNodeStateMap(node);
- if (updateInfo) {
- this.updateNodeStateInfo();
- }
-}
-
-NodeGroup.prototype.updateHeader = function(checkAlive) {
- var nodeGroupBlock = $(this.domElement);
- var nodeGroupHeaderNodes = $(this.domElementGroupHeaderNodes);
- var nodes = 0;
- var nodeGroupContainer = $(this.domElementGroupContainerBody).children().each(function () {
- var node = $(this).data('node');
- if (node !== undefined) {
- node.groupPosition = nodes;
- ++nodes;
- }
- });
- if (this.nodeMap === null || this.nodeMap.nodes !== nodes) {
- var size = 5;
- if (nodes <= 16) {
- size = 20;
- } else if (nodes <= 72) {
- size = 10;
- }
- var height = 22;
- if (nodes > 512) {
- if (nodes > 1000) {
- size = 3;
- }
- height += Math.floor((nodes - 512) / 512) * size;
- }
- this.nodeMap = new NodeMap({nodes: nodes, height: height, placeSize: size, class: 'node_map'});
- nodeGroupHeaderNodes.empty();
- nodeGroupHeaderNodes.append(this.nodeMap.domElement);
- }
- if (checkAlive) {
- this.nodesGood = 0;
- this.nodeState = {};
- for (var nodeId in this.nodes) {
- var node = this.nodes[nodeId];
- if (node !== undefined) {
- if (node.sysInfo && node.sysInfo.SystemState) {
- this.updateNodeStateMap(node);
- }
- }
- }
- this.updateNodeStateInfo();
- }
-}
-
+function NodeGroup(options) {
+ Object.assign(this, options);
+ this.nodes = {};
+ this.nodeState = {};
+ this.nodesTotal = 0;
+ this.nodesGood = 0;
+ this.buildDomElement();
+ this.nodeMap = null;
+}
+
+NodeGroup.prototype.disableDoubleClick = function(e) {
+ if (e.detail > 1) {
+ e.preventDefault();
+ }
+}
+
+NodeGroup.prototype.buildDomElement = function() {
+ var nodeBlock = $('<div>', {class: 'node_group_block'});
+ var nodeGroupHeader = $('<div>', {class: 'node_group_header'});
+ var nodeGroupName = $('<div>', {class: 'node_group_header_name'});
+ var nodeGroupInfo = $('<div>', {class: 'node_group_header_info'});
+ var nodeGroupNodes = $('<div>', {class: 'node_group_header_nodes'});
+ nodeGroupName.html(this.name);
+ nodeGroupHeader.mousedown(this.disableDoubleClick.bind(this));
+ nodeGroupHeader.click(this.toggleContainer.bind(this));
+ nodeGroupInfo.html("<img src='throbber.gif'></img>");
+ nodeGroupHeader.append(nodeGroupName);
+ nodeGroupHeader.append(nodeGroupNodes);
+ nodeGroupHeader.append(nodeGroupInfo);
+ nodeBlock.append(nodeGroupHeader);
+ var nodeGroupContainer = $('<table>', {class: 'nodelist node_group_container'});
+ var nodeGroupHead = $('<thead>');
+ var nodeGroupRow = $('<tr>');
+ nodeGroupRow.append('<th>#</th>');
+ nodeGroupRow.append('<th>Node</th>');
+ nodeGroupRow.append('<th>Uptime</th>');
+ nodeGroupRow.append('<th>CPU</th>');
+ nodeGroupRow.append('<th>RAM</th>');
+ /*if (nodesCount <= 32) {
+ nodeGroupRow.append('<th>Net</th>');
+ } else {
+ nodeGroupRow.append('<th>Network</th>');
+ }*/
+ /*nodeGroupRow.append('<th>Net</th>');*/
+ nodeGroupRow.append('<th>Disks & Tablets</th>');
+ nodeGroupHead.append(nodeGroupRow);
+ var nodeGroupBody = $('<tbody>');
+ nodeGroupContainer.append(nodeGroupHead);
+ nodeGroupContainer.append(nodeGroupBody);
+ nodeBlock.append(nodeGroupContainer);
+ this.domElement = nodeBlock[0];
+ this.domElementGroupHeader = nodeGroupHeader[0];
+ this.domElementGroupHeaderNodes = nodeGroupNodes[0];
+ this.domElementGroupInfo = nodeGroupInfo[0];
+ this.domElementGroupContainer = nodeGroupContainer[0];
+ this.domElementGroupContainerBody = nodeGroupBody[0];
+ this.domElementGroupContainer.style.display = 'none';
+ nodeBlock.data('group', this);
+}
+
+NodeGroup.prototype.toggleContainer = function() {
+ var domElement = this.domElementGroupContainer;
+ if (domElement.style.display === 'none') {
+ domElement.style.display = 'table';
+
+ $(this.domElementGroupHeader).addClass('node_group_header_pressed');
+ } else {
+ $(this.domElementGroupHeader).removeClass('node_group_header_pressed');
+ domElement.style.display = 'none';
+ }
+}
+
+NodeGroup.prototype.isEmpty = function() {
+ return this.nodesTotal === 0;
+}
+
+NodeGroup.prototype.addNode = function(node) {
+ if (node.group !== undefined) {
+ node.group.removeNode(node);
+ }
+
+ var point = this.domElementGroupContainerBody.lastChild;
+ if (point === null || $(point).data('node').Id < node.Id) {
+ this.domElementGroupContainerBody.appendChild(node.domElement);
+ } else {
+ for(;;) {
+ var prev = point.previousSibling;
+ if (prev === null) {
+ break;
+ }
+ if ($(prev).data('node').Id < node.Id) {
+ break;
+ }
+ point = prev;
+ }
+ this.domElementGroupContainerBody.insertBefore(node.domElement, point);
+ }
+
+ node.group = this;
+ this.nodes[node.Id] = node;
+ ++this.nodesTotal;
+}
+
+NodeGroup.prototype.removeNode = function(node) {
+ this.domElementGroupContainerBody.removeChild(node.domElement);
+ var color = node.color;
+ if (color === green) {
+ --this.nodesGood;
+ }
+ delete node.group;
+ delete this.nodeState[node.groupPosition];
+ delete node.groupPosition;
+ delete this.nodes[node.Id];
+ --this.nodesTotal;
+}
+
+NodeGroup.prototype.updateNodeStateMap = function(node) {
+ var color = flagToColor(node.sysInfo.SystemState);
+ var position = node.groupPosition;
+ if (position !== undefined) {
+ var prevColor = this.nodeState[position];
+ if (prevColor !== color) {
+ this.nodeState[position] = color;
+ this.nodeMap.setNodeMap(position, color, node.getTooltipText());
+ var n = node.domElement;
+ switch (color) {
+ case red:
+ n.style.backgroundColor = '#ffe0e0';//red;
+ break;
+ case orange:
+ n.style.backgroundColor = '#ffe0d0';//orange;
+ break;
+ case yellow:
+ n.style.backgroundColor = '#ffffe0';//yellow;
+ break;
+ case green:
+ case grey:
+ n.style.backgroundColor = null;
+ break;
+ }
+ var updateInfo = false;
+ if (prevColor === undefined || prevColor === grey) {
+ if (color === green) {
+ this.nodesGood++;
+ }
+ updateInfo = true;
+ } else {
+ if (color !== prevColor) {
+ if (color === green) {
+ this.nodesGood++;
+ } else if (prevColor === green) {
+ this.nodesGood--;
+ }
+ updateInfo = true;
+ }
+ }
+ return true;
+ }
+ }
+ return false;
+}
+
+NodeGroup.prototype.updateNodeStateInfo = function() {
+ this.domElementGroupInfo.innerHTML = this.nodesTotal + ' nodes';
+}
+
+NodeGroup.prototype.updateNodeState = function(node) {
+ var updateInfo = this.updateNodeStateMap(node);
+ if (updateInfo) {
+ this.updateNodeStateInfo();
+ }
+}
+
+NodeGroup.prototype.updateHeader = function(checkAlive) {
+ var nodeGroupBlock = $(this.domElement);
+ var nodeGroupHeaderNodes = $(this.domElementGroupHeaderNodes);
+ var nodes = 0;
+ var nodeGroupContainer = $(this.domElementGroupContainerBody).children().each(function () {
+ var node = $(this).data('node');
+ if (node !== undefined) {
+ node.groupPosition = nodes;
+ ++nodes;
+ }
+ });
+ if (this.nodeMap === null || this.nodeMap.nodes !== nodes) {
+ var size = 5;
+ if (nodes <= 16) {
+ size = 20;
+ } else if (nodes <= 72) {
+ size = 10;
+ }
+ var height = 22;
+ if (nodes > 512) {
+ if (nodes > 1000) {
+ size = 3;
+ }
+ height += Math.floor((nodes - 512) / 512) * size;
+ }
+ this.nodeMap = new NodeMap({nodes: nodes, height: height, placeSize: size, class: 'node_map'});
+ nodeGroupHeaderNodes.empty();
+ nodeGroupHeaderNodes.append(this.nodeMap.domElement);
+ }
+ if (checkAlive) {
+ this.nodesGood = 0;
+ this.nodeState = {};
+ for (var nodeId in this.nodes) {
+ var node = this.nodes[nodeId];
+ if (node !== undefined) {
+ if (node.sysInfo && node.sysInfo.SystemState) {
+ this.updateNodeStateMap(node);
+ }
+ }
+ }
+ this.updateNodeStateInfo();
+ }
+}
+
diff --git a/ydb/core/viewer/content/v2/node_map.js b/ydb/core/viewer/content/v2/node_map.js
index 6267001614e..1404e87ef08 100644
--- a/ydb/core/viewer/content/v2/node_map.js
+++ b/ydb/core/viewer/content/v2/node_map.js
@@ -1,113 +1,113 @@
-function NodeMap(options) {
- Object.assign(this, {height: 40, minPlaceSize: 3, maxPlaceSize: 10, maxWidth: 700, class: 'node_map node_map_shadow'}, options);
- if (this.placeSize === undefined) {
- this.placeSize = Math.max(this.minPlaceSize, Math.min(this.maxPlaceSize, this.getMaxPlaceSize()));
- }
- if (this.boxSize === undefined) {
- if (this.boxSpace === undefined) {
- if (this.placeSize > 2) {
- this.boxSpace = 1;
- } else {
- this.boxSpace = 0;
- }
- }
- this.boxSize = this.placeSize - this.boxSpace;
- } else {
- this.boxSpace = this.placeSize - this.boxSize;
- }
- this.map = {};
- this.buildDomElement();
-}
-
-NodeMap.prototype.getMaxPlaceSize = function() {
- return Math.floor(Math.sqrt(this.height * this.maxWidth / this.nodes));
-}
-
-NodeMap.prototype.getWidth = function() {
- var countPerColumn = Math.floor(this.height / this.placeSize);
- return Math.ceil(this.nodes / countPerColumn) * placeSize - this.boxSpace;
-}
-
-NodeMap.prototype.buildDomElement = function() {
- var nodeRow = $('<span>', {class: this.class});
- nodeRow.tooltip({
- html: true,
- placement: 'top',
- offset: '40px'
- });
- var canvas = document.createElement('canvas');
- this.countPerColumn = Math.max(Math.floor(this.height / this.placeSize), 1);
- this.height = canvas.height = this.countPerColumn * this.placeSize - this.boxSpace;
- this.width = canvas.width = Math.ceil(this.nodes / this.countPerColumn) * this.placeSize - this.boxSpace;
- nodeRow.append(canvas);
- var realNodes = Math.ceil(canvas.height / this.placeSize) * Math.ceil(canvas.width / this.placeSize);
- this.domElement = nodeRow[0];
- this.canvas = canvas;
- this.context = canvas.getContext('2d');
- canvas.addEventListener('click', this.onClick.bind(this));
- canvas.addEventListener('mousemove', this.onMouseMove.bind(this));
- var i;
- /*for (i = 0; i < this.nodes; ++i) {
- this.setNodeMap(i, '#e0e0e0');
- }*/
- for (i = this.nodes; i < realNodes; ++i) {
- this.setNodeMap(i, '#c0c0c0');
- }
-}
-
-NodeMap.prototype.setNodeTitle = function(position, title) {
- var p = this.map[position];
- if (p === undefined) {
- p = this.map[position] = {};
- }
- p.title = title;
-}
-
-NodeMap.prototype.setNodeMap = function(position, color, title) {
- var p = this.map[position];
- if (p === undefined) {
- p = this.map[position] = {};
- }
- p.color = color;
- if (title) {
- p.title = title;
- }
- var x = Math.floor(position / this.countPerColumn) * this.placeSize;
- var y = (position % this.countPerColumn) * this.placeSize;
- this.context.fillStyle = color;
- this.context.fillRect(x, y, this.boxSize, this.boxSize);
-}
-
-NodeMap.prototype.getNodeMap = function(position) {
- return this.map[position];
-}
-
-NodeMap.prototype.onClick = function(event) {
- var x = Math.floor((event.offsetX - 1) / this.placeSize);
- var y = Math.floor((event.offsetY - 1) / this.placeSize);
- var position = x * this.countPerColumn + y;
- console.log('Click on node_map position ' + position);
- if (this.onNodeClick) {
- this.onNodeClick({position: position});
- }
-}
-
-NodeMap.prototype.onMouseMove = function(event) {
- var x = Math.floor((event.offsetX - 1) / this.placeSize);
- var y = Math.floor((event.offsetY - 1) / this.placeSize);
- var position = x * this.countPerColumn + y;
- var n = this.map[position];
- if (n !== undefined && n.title) {
- this.domElement.setAttribute('data-original-title', n.title);
- $(this.domElement).tooltip('show');
- var tooltip = this.tooltip;
- if (tooltip === undefined) {
- tooltip = this.tooltip = $('.tooltip');
- }
- var ofs_x = event.offsetX - this.width / 2;
- var ofs_y = event.offsetY;
- tooltip.css('top', parseInt(tooltip.css('top')) + ofs_y + 'px');
- tooltip.css('left', parseInt(tooltip.css('left')) + ofs_x + 'px');
- //console.log('MouseMove on node_map position ' + position);
- }
-}
+function NodeMap(options) {
+ Object.assign(this, {height: 40, minPlaceSize: 3, maxPlaceSize: 10, maxWidth: 700, class: 'node_map node_map_shadow'}, options);
+ if (this.placeSize === undefined) {
+ this.placeSize = Math.max(this.minPlaceSize, Math.min(this.maxPlaceSize, this.getMaxPlaceSize()));
+ }
+ if (this.boxSize === undefined) {
+ if (this.boxSpace === undefined) {
+ if (this.placeSize > 2) {
+ this.boxSpace = 1;
+ } else {
+ this.boxSpace = 0;
+ }
+ }
+ this.boxSize = this.placeSize - this.boxSpace;
+ } else {
+ this.boxSpace = this.placeSize - this.boxSize;
+ }
+ this.map = {};
+ this.buildDomElement();
+}
+
+NodeMap.prototype.getMaxPlaceSize = function() {
+ return Math.floor(Math.sqrt(this.height * this.maxWidth / this.nodes));
+}
+
+NodeMap.prototype.getWidth = function() {
+ var countPerColumn = Math.floor(this.height / this.placeSize);
+ return Math.ceil(this.nodes / countPerColumn) * placeSize - this.boxSpace;
+}
+
+NodeMap.prototype.buildDomElement = function() {
+ var nodeRow = $('<span>', {class: this.class});
+ nodeRow.tooltip({
+ html: true,
+ placement: 'top',
+ offset: '40px'
+ });
+ var canvas = document.createElement('canvas');
+ this.countPerColumn = Math.max(Math.floor(this.height / this.placeSize), 1);
+ this.height = canvas.height = this.countPerColumn * this.placeSize - this.boxSpace;
+ this.width = canvas.width = Math.ceil(this.nodes / this.countPerColumn) * this.placeSize - this.boxSpace;
+ nodeRow.append(canvas);
+ var realNodes = Math.ceil(canvas.height / this.placeSize) * Math.ceil(canvas.width / this.placeSize);
+ this.domElement = nodeRow[0];
+ this.canvas = canvas;
+ this.context = canvas.getContext('2d');
+ canvas.addEventListener('click', this.onClick.bind(this));
+ canvas.addEventListener('mousemove', this.onMouseMove.bind(this));
+ var i;
+ /*for (i = 0; i < this.nodes; ++i) {
+ this.setNodeMap(i, '#e0e0e0');
+ }*/
+ for (i = this.nodes; i < realNodes; ++i) {
+ this.setNodeMap(i, '#c0c0c0');
+ }
+}
+
+NodeMap.prototype.setNodeTitle = function(position, title) {
+ var p = this.map[position];
+ if (p === undefined) {
+ p = this.map[position] = {};
+ }
+ p.title = title;
+}
+
+NodeMap.prototype.setNodeMap = function(position, color, title) {
+ var p = this.map[position];
+ if (p === undefined) {
+ p = this.map[position] = {};
+ }
+ p.color = color;
+ if (title) {
+ p.title = title;
+ }
+ var x = Math.floor(position / this.countPerColumn) * this.placeSize;
+ var y = (position % this.countPerColumn) * this.placeSize;
+ this.context.fillStyle = color;
+ this.context.fillRect(x, y, this.boxSize, this.boxSize);
+}
+
+NodeMap.prototype.getNodeMap = function(position) {
+ return this.map[position];
+}
+
+NodeMap.prototype.onClick = function(event) {
+ var x = Math.floor((event.offsetX - 1) / this.placeSize);
+ var y = Math.floor((event.offsetY - 1) / this.placeSize);
+ var position = x * this.countPerColumn + y;
+ console.log('Click on node_map position ' + position);
+ if (this.onNodeClick) {
+ this.onNodeClick({position: position});
+ }
+}
+
+NodeMap.prototype.onMouseMove = function(event) {
+ var x = Math.floor((event.offsetX - 1) / this.placeSize);
+ var y = Math.floor((event.offsetY - 1) / this.placeSize);
+ var position = x * this.countPerColumn + y;
+ var n = this.map[position];
+ if (n !== undefined && n.title) {
+ this.domElement.setAttribute('data-original-title', n.title);
+ $(this.domElement).tooltip('show');
+ var tooltip = this.tooltip;
+ if (tooltip === undefined) {
+ tooltip = this.tooltip = $('.tooltip');
+ }
+ var ofs_x = event.offsetX - this.width / 2;
+ var ofs_y = event.offsetY;
+ tooltip.css('top', parseInt(tooltip.css('top')) + ofs_y + 'px');
+ tooltip.css('left', parseInt(tooltip.css('left')) + ofs_x + 'px');
+ //console.log('MouseMove on node_map position ' + position);
+ }
+}
diff --git a/ydb/core/viewer/content/v2/node_view.js b/ydb/core/viewer/content/v2/node_view.js
index 866852b5d80..132fb3badb9 100644
--- a/ydb/core/viewer/content/v2/node_view.js
+++ b/ydb/core/viewer/content/v2/node_view.js
@@ -1,263 +1,263 @@
-function NodeView(options) {
- Object.assign(this, {
- nodes: {},
- groups: {},
- visibleNodes: {},
- visibleRefreshTimeout: 1000
- }, options);
- this.nodesCount = Object.keys(this.nodes).length;
- this.refreshViewTimer = null;
- this.isNodeGood = function(node) { return node.sysInfo.SystemState === 'Green'; }
- this.getNodeGroupName = function(node) { return node.getIdGroup(); }
- this.groupOrder = function(prev, next) { return Number(prev.split('..')[0]) < Number(next.split('..')[0]); }
- this.observer = new IntersectionObserver(this.onVisibilityChange.bind(this));
- this.refreshViewInterval = setInterval(this.refreshView.bind(this), this.visibleRefreshTimeout);
-}
-
-NodeView.prototype.groupOrder = function(prev, next) { return prev < next; }
-
-NodeView.prototype.getNodeGroup = function(name) {
- var group = this.groups[name];
- if (group === undefined) {
- group = this.groups[name] = new NodeGroup({name: name, view: this});
- var point = this.domElement.lastChild;
- if (point === null || this.groupOrder($(point).data('group').name, name)) {
- this.domElement.appendChild(group.domElement);
- } else {
- for(;;) {
- var prev = point.previousSibling;
- if (prev === null) {
- break;
- }
- if (this.groupOrder($(prev).data('group').name, name)) {
- break;
- }
- point = prev;
- }
- this.domElement.insertBefore(group.domElement, point);
- }
- }
- return group;
-}
-
-NodeView.prototype.addNode = function(node) {
- node.nodeView = this;
- this.nodes[node.Id] = node;
- this.nodesCount++;
- if (this.observer) {
- this.observer.observe(node.domElement);
- }
-}
-
-NodeView.prototype.removeGroup = function(group) {
- this.domElement.removeChild(group.domElement);
- delete this.groups[group.name];
-}
-
-NodeView.prototype.rebuild = function() {
- for (var i in this.nodes) {
- var node = this.nodes[i];
- var groupName = this.getNodeGroupName(node);
- var group = this.getNodeGroup(groupName);
- group.addNode(node);
- }
- this.rebuildGroupHeaders(true);
- //delete this.lastRefreshOverall;
-}
-
-NodeView.prototype.updateGroup = function(node) {
- var groupName = this.getNodeGroupName(node);
- if (!node.group || node.group.name !== groupName) {
- var oldGroup = node.group;
- var newGroup = this.getNodeGroup(groupName);
- newGroup.addNode(node);
- if (oldGroup.isEmpty()) {
- this.removeGroup(oldGroup);
- } else {
- oldGroup.updateHeader(true);
- }
- newGroup.updateHeader(true);
- }
-}
-
-NodeView.prototype.onVisibilityChange = function(entries) {
- var now = getTime();
- for (var idx = 0; idx < entries.length; ++idx) {
- var entry = entries[idx];
- var node = $(entry.target).data('node');
- if (entry.isIntersecting) {
- if (!node.visible) {
- node.appear();
- this.visibleNodes[node.Id] = true;
- }
- } else {
- node.disappear();
- delete this.visibleNodes[node.Id];
- }
- }
- if (this.refreshViewTimer === null) {
- //this.refreshViewTimer = setTimeout(this.refreshView.bind(this), 10);
- this.refreshView();
- }
-}
-
-NodeView.prototype.onNodeInfo = function(data) {
- if (data.NodeStateInfo !== undefined) {
- for (var i in data.NodeStateInfo) {
- var update = data.NodeStateInfo[i];
- var nodeId = getNodeIdFromPeerName(update.PeerName);
- var node = this.nodes[nodeId];
- if (node && node.sysInfo && !node.sysInfo.Roles) {
- var port = getPortFromPeerName(update.PeerName);
- var role = this.PortToRoles[port];
- if (role) {
- node.sysInfo.Roles = [role];
- }
- if (!node.Port) {
- node.Port = port;
- }
- }
- }
- }
-}
-
-NodeView.prototype.onSysInfo = function(data) {
- if (data.SystemStateInfo !== undefined) {
- var deadNodes = {};
- for (var i in this.nodes) {
- deadNodes[i] = true;
- }
- for (var i in data.SystemStateInfo) {
- var update = data.SystemStateInfo[i];
- if (!this.sysInfoChangeTime || update.ChangeTime < this.sysInfoChangeTime) {
- this.sysInfoChangeTime = update.ChangeTime;
- }
- var nodeId = update.NodeId;
- if (nodeId) {
- var node = this.nodes[nodeId];
- if (node) {
- node.updateSysInfoStatsOnly(update);
- }
- delete deadNodes[nodeId];
- }
- }
- for(var i in deadNodes) {
- var node = this.nodes[i];
- if (node) {
- node.onDisconnect();
- }
- }
-
- if (data.ResponseTime != 0) {
- this.sysInfoChangeTime = data.ResponseTime;
- }
- }
-}
-
-NodeView.prototype.onPDiskInfo = function(data) {
- for (var nodeId in data) {
- var update = data[nodeId];
- if (update.PDiskStateInfo) {
- var node = this.nodes[nodeId];
- if (node) {
- node.onPDiskInfo(update);
- }
- }
- }
-}
-
-NodeView.prototype.onVDiskInfo = function(data) {
- for (var nodeId in data) {
- var update = data[nodeId];
- if (update.VDiskStateInfo) {
- var node = this.nodes[nodeId];
- if (node) {
- node.onVDiskInfo(update);
- }
- }
- }
-}
-
-NodeView.prototype.onDisconnect = function() {
- for (var nodeId in this.nodes) {
- this.nodes[nodeId].onDisconnect();
- }
-}
-
-NodeView.prototype.refreshView = function() {
- this.refreshViewTimer = null;
- var now = getTime();
- var keys = Object.keys(this.visibleNodes);
- if (keys.length > 0) {
- console.log('refreshView: ' + keys);
- var nodeView = this;
- keys.forEach(function(nodeId) {
- var node = nodeView.nodes[nodeId];
- if (!node.visible) {
- delete nodeView.visibleNodes[nodeId];
- } else {
- nodeView.refreshNode(node, now);
- }
- });
- }
-}
-
-NodeView.prototype.isTimeToUpdateNode = function(node, now) {
- return node.visible && (!node.lastUpdate || (node.lastUpdate <= (now - this.visibleRefreshTimeout)));
- //return node.visible;
-}
-
-NodeView.prototype.refreshNode = function(node, now) {
- if (node.visible) {
- if (this.isTimeToUpdateNode(node, now)) {
- node.refresh();
- node.lastUpdate = now;
- }
- }
-}
-
-NodeView.prototype.rebuildGroupHeaders = function(checkAlive) {
- for (var name in this.groups) {
- var group = this.groups[name];
- if (group.isEmpty()) {
- this.removeGroup(group);
- } else {
- group.updateHeader(checkAlive);
- }
- }
-}
-
-NodeView.prototype.getReferenceNode = function() {
- for (var i in this.nodes) {
- return this.nodes[i];
- }
- return null;
-}
-
-NodeView.prototype.getConfig = function() {
- return this.config;
-}
-
-NodeView.prototype.getRootPath = function() {
- var config = this.getConfig();
- if (config) {
- return '/' + config.DomainsConfig.Domain[0].Name;
- }
-}
-
-NodeView.prototype.getTenantName = function(sysInfo) {
- if (sysInfo.Tenants !== undefined && sysInfo.Tenants.length > 0) {
- return sysInfo.Tenants.join(',');
- }
- return this.getRootPath();
-}
-
-NodeView.prototype.scrollToNodePosition = function(position) {
- for (var nodeId in this.nodes) {
- var node = this.nodes[nodeId];
- if (node.position === position) {
- console.log('scroll to node ' + node.Id);
- node.domElement.scrollIntoView();
- }
- }
-}
+function NodeView(options) {
+ Object.assign(this, {
+ nodes: {},
+ groups: {},
+ visibleNodes: {},
+ visibleRefreshTimeout: 1000
+ }, options);
+ this.nodesCount = Object.keys(this.nodes).length;
+ this.refreshViewTimer = null;
+ this.isNodeGood = function(node) { return node.sysInfo.SystemState === 'Green'; }
+ this.getNodeGroupName = function(node) { return node.getIdGroup(); }
+ this.groupOrder = function(prev, next) { return Number(prev.split('..')[0]) < Number(next.split('..')[0]); }
+ this.observer = new IntersectionObserver(this.onVisibilityChange.bind(this));
+ this.refreshViewInterval = setInterval(this.refreshView.bind(this), this.visibleRefreshTimeout);
+}
+
+NodeView.prototype.groupOrder = function(prev, next) { return prev < next; }
+
+NodeView.prototype.getNodeGroup = function(name) {
+ var group = this.groups[name];
+ if (group === undefined) {
+ group = this.groups[name] = new NodeGroup({name: name, view: this});
+ var point = this.domElement.lastChild;
+ if (point === null || this.groupOrder($(point).data('group').name, name)) {
+ this.domElement.appendChild(group.domElement);
+ } else {
+ for(;;) {
+ var prev = point.previousSibling;
+ if (prev === null) {
+ break;
+ }
+ if (this.groupOrder($(prev).data('group').name, name)) {
+ break;
+ }
+ point = prev;
+ }
+ this.domElement.insertBefore(group.domElement, point);
+ }
+ }
+ return group;
+}
+
+NodeView.prototype.addNode = function(node) {
+ node.nodeView = this;
+ this.nodes[node.Id] = node;
+ this.nodesCount++;
+ if (this.observer) {
+ this.observer.observe(node.domElement);
+ }
+}
+
+NodeView.prototype.removeGroup = function(group) {
+ this.domElement.removeChild(group.domElement);
+ delete this.groups[group.name];
+}
+
+NodeView.prototype.rebuild = function() {
+ for (var i in this.nodes) {
+ var node = this.nodes[i];
+ var groupName = this.getNodeGroupName(node);
+ var group = this.getNodeGroup(groupName);
+ group.addNode(node);
+ }
+ this.rebuildGroupHeaders(true);
+ //delete this.lastRefreshOverall;
+}
+
+NodeView.prototype.updateGroup = function(node) {
+ var groupName = this.getNodeGroupName(node);
+ if (!node.group || node.group.name !== groupName) {
+ var oldGroup = node.group;
+ var newGroup = this.getNodeGroup(groupName);
+ newGroup.addNode(node);
+ if (oldGroup.isEmpty()) {
+ this.removeGroup(oldGroup);
+ } else {
+ oldGroup.updateHeader(true);
+ }
+ newGroup.updateHeader(true);
+ }
+}
+
+NodeView.prototype.onVisibilityChange = function(entries) {
+ var now = getTime();
+ for (var idx = 0; idx < entries.length; ++idx) {
+ var entry = entries[idx];
+ var node = $(entry.target).data('node');
+ if (entry.isIntersecting) {
+ if (!node.visible) {
+ node.appear();
+ this.visibleNodes[node.Id] = true;
+ }
+ } else {
+ node.disappear();
+ delete this.visibleNodes[node.Id];
+ }
+ }
+ if (this.refreshViewTimer === null) {
+ //this.refreshViewTimer = setTimeout(this.refreshView.bind(this), 10);
+ this.refreshView();
+ }
+}
+
+NodeView.prototype.onNodeInfo = function(data) {
+ if (data.NodeStateInfo !== undefined) {
+ for (var i in data.NodeStateInfo) {
+ var update = data.NodeStateInfo[i];
+ var nodeId = getNodeIdFromPeerName(update.PeerName);
+ var node = this.nodes[nodeId];
+ if (node && node.sysInfo && !node.sysInfo.Roles) {
+ var port = getPortFromPeerName(update.PeerName);
+ var role = this.PortToRoles[port];
+ if (role) {
+ node.sysInfo.Roles = [role];
+ }
+ if (!node.Port) {
+ node.Port = port;
+ }
+ }
+ }
+ }
+}
+
+NodeView.prototype.onSysInfo = function(data) {
+ if (data.SystemStateInfo !== undefined) {
+ var deadNodes = {};
+ for (var i in this.nodes) {
+ deadNodes[i] = true;
+ }
+ for (var i in data.SystemStateInfo) {
+ var update = data.SystemStateInfo[i];
+ if (!this.sysInfoChangeTime || update.ChangeTime < this.sysInfoChangeTime) {
+ this.sysInfoChangeTime = update.ChangeTime;
+ }
+ var nodeId = update.NodeId;
+ if (nodeId) {
+ var node = this.nodes[nodeId];
+ if (node) {
+ node.updateSysInfoStatsOnly(update);
+ }
+ delete deadNodes[nodeId];
+ }
+ }
+ for(var i in deadNodes) {
+ var node = this.nodes[i];
+ if (node) {
+ node.onDisconnect();
+ }
+ }
+
+ if (data.ResponseTime != 0) {
+ this.sysInfoChangeTime = data.ResponseTime;
+ }
+ }
+}
+
+NodeView.prototype.onPDiskInfo = function(data) {
+ for (var nodeId in data) {
+ var update = data[nodeId];
+ if (update.PDiskStateInfo) {
+ var node = this.nodes[nodeId];
+ if (node) {
+ node.onPDiskInfo(update);
+ }
+ }
+ }
+}
+
+NodeView.prototype.onVDiskInfo = function(data) {
+ for (var nodeId in data) {
+ var update = data[nodeId];
+ if (update.VDiskStateInfo) {
+ var node = this.nodes[nodeId];
+ if (node) {
+ node.onVDiskInfo(update);
+ }
+ }
+ }
+}
+
+NodeView.prototype.onDisconnect = function() {
+ for (var nodeId in this.nodes) {
+ this.nodes[nodeId].onDisconnect();
+ }
+}
+
+NodeView.prototype.refreshView = function() {
+ this.refreshViewTimer = null;
+ var now = getTime();
+ var keys = Object.keys(this.visibleNodes);
+ if (keys.length > 0) {
+ console.log('refreshView: ' + keys);
+ var nodeView = this;
+ keys.forEach(function(nodeId) {
+ var node = nodeView.nodes[nodeId];
+ if (!node.visible) {
+ delete nodeView.visibleNodes[nodeId];
+ } else {
+ nodeView.refreshNode(node, now);
+ }
+ });
+ }
+}
+
+NodeView.prototype.isTimeToUpdateNode = function(node, now) {
+ return node.visible && (!node.lastUpdate || (node.lastUpdate <= (now - this.visibleRefreshTimeout)));
+ //return node.visible;
+}
+
+NodeView.prototype.refreshNode = function(node, now) {
+ if (node.visible) {
+ if (this.isTimeToUpdateNode(node, now)) {
+ node.refresh();
+ node.lastUpdate = now;
+ }
+ }
+}
+
+NodeView.prototype.rebuildGroupHeaders = function(checkAlive) {
+ for (var name in this.groups) {
+ var group = this.groups[name];
+ if (group.isEmpty()) {
+ this.removeGroup(group);
+ } else {
+ group.updateHeader(checkAlive);
+ }
+ }
+}
+
+NodeView.prototype.getReferenceNode = function() {
+ for (var i in this.nodes) {
+ return this.nodes[i];
+ }
+ return null;
+}
+
+NodeView.prototype.getConfig = function() {
+ return this.config;
+}
+
+NodeView.prototype.getRootPath = function() {
+ var config = this.getConfig();
+ if (config) {
+ return '/' + config.DomainsConfig.Domain[0].Name;
+ }
+}
+
+NodeView.prototype.getTenantName = function(sysInfo) {
+ if (sysInfo.Tenants !== undefined && sysInfo.Tenants.length > 0) {
+ return sysInfo.Tenants.join(',');
+ }
+ return this.getRootPath();
+}
+
+NodeView.prototype.scrollToNodePosition = function(position) {
+ for (var nodeId in this.nodes) {
+ var node = this.nodes[nodeId];
+ if (node.position === position) {
+ console.log('scroll to node ' + node.Id);
+ node.domElement.scrollIntoView();
+ }
+ }
+}
diff --git a/ydb/core/viewer/content/v2/nodes b/ydb/core/viewer/content/v2/nodes
index 352990be516..86b82167bfb 100644
--- a/ydb/core/viewer/content/v2/nodes
+++ b/ydb/core/viewer/content/v2/nodes
@@ -1,84 +1,84 @@
-<!DOCTYPE HTML>
-<html>
-<head>
-<link rel="stylesheet" href="https://yastatic.net/bootstrap/3.3.1/css/bootstrap.min.css">
-<script language="javascript" type="text/javascript" src="https://yastatic.net/jquery/2.1.3/jquery.min.js"></script>
-<script language="javascript" type="text/javascript" src="https://yastatic.net/bootstrap/3.3.1/js/bootstrap.min.js"></script>
-<style type="text/css">
-.table-nonfluid { width: auto; }
-.narrow-line50 {line-height: 50%}
-.narrow-line60 {line-height: 60%}
-.narrow-line70 {line-height: 70%}
-.narrow-line80 {line-height: 80%}
-.narrow-line90 {line-height: 90%}
-</style>
-<link rel="stylesheet" href="../style.min.css" />
-<link rel="stylesheet" href="viewer.css" />
-<script src="util.js"></script>
-<script src="pool_block.js"></script>
-<script src="pool_map.js"></script>
-<script src="node_map.js"></script>
-<script src="pdisk.js"></script>
-<script src="vdisk.js"></script>
-<script src="disk_cell.js"></script>
-<script src="disk_map.js"></script>
-<script src="tablet_cell.js"></script>
-<script src="tablet_map.js"></script>
-<script src="node.js"></script>
-<script src="node_group.js"></script>
-<script src="tenant.js"></script>
-<script src="overview.js"></script>
-<script src="cpu_view.js"></script>
-<script src="net_view.js"></script>
-<script src="storage_view.js"></script>
-<script src="node_view.js"></script>
-<script src="tenant_view.js"></script>
-<script src="viewer.js"></script>
-</head>
-<body onload='mainNodes();'>
-<div class='container-fluid'>
-<ul class="nav nav-tabs">
- <li class="nav-item">
- <a class="pseudo-nav-link" href="overview">Overview</a>
- </li>
- <li class="nav-item">
- <a class="pseudo-nav-link" href="cpu">CPU</a>
- </li>
- <li class="nav-item">
- <a class="pseudo-nav-link" href="network">Network</a>
- </li>
- <li class="nav-item">
- <a class="pseudo-nav-link" href="storage">Storage</a>
- </li>
- <li class="nav-item active">
- <a class="pseudo-nav-link" href="nodes">Nodes</a>
- </li>
- <li class="nav-item">
- <a class="pseudo-nav-link" href="tenants">Tenants</a>
- </li>
- <li style="float:right">
- <span id="updateQueueInflight" style="font-size:10px"></span>
- <span id="updateQueueCounter" style="font-weight:bold;font-size:20px;margin-left:40px"></span>
- </li>
-</ul>
-<div class="tab-content" style="padding-top: 10px">
- <div id="nodes" class="tab-pane active">
- <div style="font-size: 14px; padding: 10px 0px 10px 0px">
- <button class="btn btn-default node_group_switch" value="dc" onclick="onNodeGroupChange(this)">DC</button>
- <button class="btn btn-default node_group_switch" value="domain" onclick="onNodeGroupChange(this)">Domain</button>
- <button class="btn btn-default node_group_switch" value="rack" onclick="onNodeGroupChange(this)">Rack</button>
- <button class="btn btn-info node_group_switch" value="id" onclick="onNodeGroupChange(this)">ID</button>
- <button class="btn btn-default node_group_switch" value="host" onclick="onNodeGroupChange(this)">Host</button>
- <button class="btn btn-default node_group_switch" value="role" onclick="onNodeGroupChange(this)">Role</button>
- <button class="btn btn-default node_group_switch" value="tenant" onclick="onNodeGroupChange(this)">Tenant</button>
- <button class="btn btn-default node_group_switch" value="status" onclick="onNodeGroupChange(this)">Status</button>
- <button class="btn btn-default node_group_switch" value="uptime" onclick="onNodeGroupChange(this)">Uptime</button>
- <button class="btn btn-default node_group_switch" value="version" onclick="onNodeGroupChange(this)">Version</button>
- <button class="btn btn-default node_group_switch" value="usage" onclick="onNodeGroupChange(this)">Usage</button>
- </div>
- <div id="nodes_view" style='display: inline-block'></div>
- </div>
-</div>
-</div>
-</body>
-</html>
+<!DOCTYPE HTML>
+<html>
+<head>
+<link rel="stylesheet" href="https://yastatic.net/bootstrap/3.3.1/css/bootstrap.min.css">
+<script language="javascript" type="text/javascript" src="https://yastatic.net/jquery/2.1.3/jquery.min.js"></script>
+<script language="javascript" type="text/javascript" src="https://yastatic.net/bootstrap/3.3.1/js/bootstrap.min.js"></script>
+<style type="text/css">
+.table-nonfluid { width: auto; }
+.narrow-line50 {line-height: 50%}
+.narrow-line60 {line-height: 60%}
+.narrow-line70 {line-height: 70%}
+.narrow-line80 {line-height: 80%}
+.narrow-line90 {line-height: 90%}
+</style>
+<link rel="stylesheet" href="../style.min.css" />
+<link rel="stylesheet" href="viewer.css" />
+<script src="util.js"></script>
+<script src="pool_block.js"></script>
+<script src="pool_map.js"></script>
+<script src="node_map.js"></script>
+<script src="pdisk.js"></script>
+<script src="vdisk.js"></script>
+<script src="disk_cell.js"></script>
+<script src="disk_map.js"></script>
+<script src="tablet_cell.js"></script>
+<script src="tablet_map.js"></script>
+<script src="node.js"></script>
+<script src="node_group.js"></script>
+<script src="tenant.js"></script>
+<script src="overview.js"></script>
+<script src="cpu_view.js"></script>
+<script src="net_view.js"></script>
+<script src="storage_view.js"></script>
+<script src="node_view.js"></script>
+<script src="tenant_view.js"></script>
+<script src="viewer.js"></script>
+</head>
+<body onload='mainNodes();'>
+<div class='container-fluid'>
+<ul class="nav nav-tabs">
+ <li class="nav-item">
+ <a class="pseudo-nav-link" href="overview">Overview</a>
+ </li>
+ <li class="nav-item">
+ <a class="pseudo-nav-link" href="cpu">CPU</a>
+ </li>
+ <li class="nav-item">
+ <a class="pseudo-nav-link" href="network">Network</a>
+ </li>
+ <li class="nav-item">
+ <a class="pseudo-nav-link" href="storage">Storage</a>
+ </li>
+ <li class="nav-item active">
+ <a class="pseudo-nav-link" href="nodes">Nodes</a>
+ </li>
+ <li class="nav-item">
+ <a class="pseudo-nav-link" href="tenants">Tenants</a>
+ </li>
+ <li style="float:right">
+ <span id="updateQueueInflight" style="font-size:10px"></span>
+ <span id="updateQueueCounter" style="font-weight:bold;font-size:20px;margin-left:40px"></span>
+ </li>
+</ul>
+<div class="tab-content" style="padding-top: 10px">
+ <div id="nodes" class="tab-pane active">
+ <div style="font-size: 14px; padding: 10px 0px 10px 0px">
+ <button class="btn btn-default node_group_switch" value="dc" onclick="onNodeGroupChange(this)">DC</button>
+ <button class="btn btn-default node_group_switch" value="domain" onclick="onNodeGroupChange(this)">Domain</button>
+ <button class="btn btn-default node_group_switch" value="rack" onclick="onNodeGroupChange(this)">Rack</button>
+ <button class="btn btn-info node_group_switch" value="id" onclick="onNodeGroupChange(this)">ID</button>
+ <button class="btn btn-default node_group_switch" value="host" onclick="onNodeGroupChange(this)">Host</button>
+ <button class="btn btn-default node_group_switch" value="role" onclick="onNodeGroupChange(this)">Role</button>
+ <button class="btn btn-default node_group_switch" value="tenant" onclick="onNodeGroupChange(this)">Tenant</button>
+ <button class="btn btn-default node_group_switch" value="status" onclick="onNodeGroupChange(this)">Status</button>
+ <button class="btn btn-default node_group_switch" value="uptime" onclick="onNodeGroupChange(this)">Uptime</button>
+ <button class="btn btn-default node_group_switch" value="version" onclick="onNodeGroupChange(this)">Version</button>
+ <button class="btn btn-default node_group_switch" value="usage" onclick="onNodeGroupChange(this)">Usage</button>
+ </div>
+ <div id="nodes_view" style='display: inline-block'></div>
+ </div>
+</div>
+</div>
+</body>
+</html>
diff --git a/ydb/core/viewer/content/v2/overview b/ydb/core/viewer/content/v2/overview
index 4f2d431982a..58f00128459 100644
--- a/ydb/core/viewer/content/v2/overview
+++ b/ydb/core/viewer/content/v2/overview
@@ -1,71 +1,71 @@
-<!DOCTYPE HTML>
-<html>
-<head>
-<link rel="stylesheet" href="https://yastatic.net/bootstrap/3.3.1/css/bootstrap.min.css">
-<script language="javascript" type="text/javascript" src="https://yastatic.net/jquery/2.1.3/jquery.min.js"></script>
-<script language="javascript" type="text/javascript" src="https://yastatic.net/bootstrap/3.3.1/js/bootstrap.min.js"></script>
-<style type="text/css">
-.table-nonfluid { width: auto; }
-.narrow-line50 {line-height: 50%}
-.narrow-line60 {line-height: 60%}
-.narrow-line70 {line-height: 70%}
-.narrow-line80 {line-height: 80%}
-.narrow-line90 {line-height: 90%}
-</style>
-<link rel="stylesheet" href="../style.min.css" />
-<link rel="stylesheet" href="viewer.css" />
-<script src="util.js"></script>
-<script src="pool_block.js"></script>
-<script src="pool_map.js"></script>
-<script src="node_map.js"></script>
-<script src="pdisk.js"></script>
-<script src="vdisk.js"></script>
-<script src="disk_cell.js"></script>
-<script src="disk_map.js"></script>
-<script src="tablet_cell.js"></script>
-<script src="tablet_map.js"></script>
-<script src="node.js"></script>
-<script src="node_group.js"></script>
-<script src="tenant.js"></script>
-<script src="overview.js"></script>
-<script src="cpu_view.js"></script>
-<script src="net_view.js"></script>
-<script src="storage_view.js"></script>
-<script src="node_view.js"></script>
-<script src="tenant_view.js"></script>
-<script src="viewer.js"></script>
-</head>
-<body onload='mainOverview();'>
-<div class='container-fluid'>
-<ul class="nav nav-tabs">
- <li class="nav-item active">
- <a class="pseudo-nav-link" href="overview">Overview</a>
- </li>
- <li class="nav-item">
- <a class="pseudo-nav-link" href="cpu">CPU</a>
- </li>
- <li class="nav-item">
- <a class="pseudo-nav-link" href="network">Network</a>
- </li>
- <li class="nav-item">
- <a class="pseudo-nav-link" href="storage">Storage</a>
- </li>
- <li class="nav-item">
- <a class="pseudo-nav-link" href="nodes">Nodes</a>
- </li>
- <li class="nav-item">
- <a class="pseudo-nav-link" href="tenants">Tenants</a>
- </li>
- <li style="float:right">
- <span id="updateQueueInflight" style="font-size:10px"></span>
- <span id="updateQueueCounter" style="font-weight:bold;font-size:20px;margin-left:40px"></span>
- </li>
-</ul>
-<div class="tab-content" style="padding-top: 10px">
- <div id="overview" class="tab-pane active">
- <div id="overview_view" style='font-size: 14px; padding: 10px 0px 10px 0px; display: inline-block'></div>
- </div>
-</div>
-</div>
-</body>
-</html>
+<!DOCTYPE HTML>
+<html>
+<head>
+<link rel="stylesheet" href="https://yastatic.net/bootstrap/3.3.1/css/bootstrap.min.css">
+<script language="javascript" type="text/javascript" src="https://yastatic.net/jquery/2.1.3/jquery.min.js"></script>
+<script language="javascript" type="text/javascript" src="https://yastatic.net/bootstrap/3.3.1/js/bootstrap.min.js"></script>
+<style type="text/css">
+.table-nonfluid { width: auto; }
+.narrow-line50 {line-height: 50%}
+.narrow-line60 {line-height: 60%}
+.narrow-line70 {line-height: 70%}
+.narrow-line80 {line-height: 80%}
+.narrow-line90 {line-height: 90%}
+</style>
+<link rel="stylesheet" href="../style.min.css" />
+<link rel="stylesheet" href="viewer.css" />
+<script src="util.js"></script>
+<script src="pool_block.js"></script>
+<script src="pool_map.js"></script>
+<script src="node_map.js"></script>
+<script src="pdisk.js"></script>
+<script src="vdisk.js"></script>
+<script src="disk_cell.js"></script>
+<script src="disk_map.js"></script>
+<script src="tablet_cell.js"></script>
+<script src="tablet_map.js"></script>
+<script src="node.js"></script>
+<script src="node_group.js"></script>
+<script src="tenant.js"></script>
+<script src="overview.js"></script>
+<script src="cpu_view.js"></script>
+<script src="net_view.js"></script>
+<script src="storage_view.js"></script>
+<script src="node_view.js"></script>
+<script src="tenant_view.js"></script>
+<script src="viewer.js"></script>
+</head>
+<body onload='mainOverview();'>
+<div class='container-fluid'>
+<ul class="nav nav-tabs">
+ <li class="nav-item active">
+ <a class="pseudo-nav-link" href="overview">Overview</a>
+ </li>
+ <li class="nav-item">
+ <a class="pseudo-nav-link" href="cpu">CPU</a>
+ </li>
+ <li class="nav-item">
+ <a class="pseudo-nav-link" href="network">Network</a>
+ </li>
+ <li class="nav-item">
+ <a class="pseudo-nav-link" href="storage">Storage</a>
+ </li>
+ <li class="nav-item">
+ <a class="pseudo-nav-link" href="nodes">Nodes</a>
+ </li>
+ <li class="nav-item">
+ <a class="pseudo-nav-link" href="tenants">Tenants</a>
+ </li>
+ <li style="float:right">
+ <span id="updateQueueInflight" style="font-size:10px"></span>
+ <span id="updateQueueCounter" style="font-weight:bold;font-size:20px;margin-left:40px"></span>
+ </li>
+</ul>
+<div class="tab-content" style="padding-top: 10px">
+ <div id="overview" class="tab-pane active">
+ <div id="overview_view" style='font-size: 14px; padding: 10px 0px 10px 0px; display: inline-block'></div>
+ </div>
+</div>
+</div>
+</body>
+</html>
diff --git a/ydb/core/viewer/content/v2/overview.js b/ydb/core/viewer/content/v2/overview.js
index 2e49019ab84..d2062108327 100644
--- a/ydb/core/viewer/content/v2/overview.js
+++ b/ydb/core/viewer/content/v2/overview.js
@@ -1,109 +1,109 @@
-function Overview(options) {
- Object.assign(this, {
+function Overview(options) {
+ Object.assign(this, {
+
+ }, options);
+ this.nodes = {};
+ this.nodesCount = 0;
+ this.statusMap = null;
+ this.ageMap = null;
+ this.loadMap = null;
+ this.poolColors = new PoolColors();
+ this.nodeMapSettings = {
+ maxWidth: 1400,
+ maxPlaceSize: 40,
+ height: 85
+ };
+ this.updateQueue = new UpdateQueue({
+ onUpdate: this.runSysUpdate.bind(this)
+ });
+}
+
+Overview.prototype.addNode = function(node) {
+ node.position = this.nodesCount;
+ this.nodes[node.Id] = node;
+ this.nodesCount++;
+}
+
+Overview.prototype.rebuild = function() {
+ if (!this.statusMap) {
+ this.nodeMapSettings.nodes = this.nodesCount;
+ this.statusMap = new NodeMap(this.nodeMapSettings);
+ this.ageMap = new NodeMap(this.nodeMapSettings);
+ this.loadMap = new NodeMap(this.nodeMapSettings);
+ var container = $(this.domElement);
+ container.append($('<div>', {class: 'map_overview_header'}).text('Status'));
+ container.append(this.statusMap.domElement);
+ container.append($('<div>', {class: 'map_overview_header'}).text('Age'));
+ container.append(this.ageMap.domElement);
+ container.append($('<div>', {class: 'map_overview_header'}).text('Load Average'));
+ container.append(this.loadMap.domElement);
+ for (var nodeId in this.nodes) {
+ var node = this.nodes[nodeId];
+ var title = node.getTooltipText();
+ this.statusMap.setNodeTitle(node.position, title);
+ this.ageMap.setNodeTitle(node.position, title);
+ this.loadMap.setNodeTitle(node.position, title);
+ }
+ }
+}
+
+Overview.prototype.runSysUpdate = function(update) {
+ var nodeId = update.NodeId;
+ if (nodeId) {
+ var node = this.nodes[nodeId];
+ if (node) {
+ node.updateSysInfoStatsOnly(update);
+ }
+ var statusColor = node.getStatusColor();
+ this.statusMap.setNodeMap(node.position, statusColor);
+ var ageColor = node.getAgeColor();
+ this.ageMap.setNodeMap(node.position, ageColor);
+ var loadAverage = node.getLoadAverage();
+ if (loadAverage) {
+ var loadColor = this.poolColors.getPoolColor(loadAverage);
+ this.loadMap.setNodeMap(node.position, loadColor);
+ }
+ }
+}
+
+Overview.prototype.onSysInfo = function(data) {
+ if (data.SystemStateInfo !== undefined) {
+ var deadNodes = {};
+ if (!data.since) {
+ for (var i in this.nodes) {
+ deadNodes[i] = true;
+ }
+ this.updateQueue.flushUpdateQueue();
+ } else {
+ data.SystemStateInfo.sort(function(a, b) {
+ return Number(b.ChangeTime) - Number(a.ChangeTime);
+ });
+ }
+ for (var idx = 0; idx < data.SystemStateInfo.length; ++idx) {
+ var update = data.SystemStateInfo[idx];
+ if (!data.since) {
+ delete deadNodes[update.NodeId];
+ }
+ this.updateQueue.enqueue(update);
+ }
+ for (var i in deadNodes) {
+ var node = this.nodes[i];
+ if (node) {
+ this.statusMap.setNodeMap(node.position, 'black');
+ this.ageMap.setNodeMap(node.position, 'black');
+ this.loadMap.setNodeMap(node.position, 'black');
+ }
+ }
+ }
+ if (!this.updateQueue.isEmpty()) {
+ this.updateQueue.updateDelay = Math.floor(data.refreshTimeout / this.updateQueue.getLength());
+ console.log('Overview.updateQueue length = ' + this.updateQueue.getLength() + ' updateDelay = ' + this.updateQueue.updateDelay);
+ } else {
+ this.updateQueue.updateDelay = 50;
+ }
+}
+
+Overview.prototype.onDisconnect = function() {
+
+}
- }, options);
- this.nodes = {};
- this.nodesCount = 0;
- this.statusMap = null;
- this.ageMap = null;
- this.loadMap = null;
- this.poolColors = new PoolColors();
- this.nodeMapSettings = {
- maxWidth: 1400,
- maxPlaceSize: 40,
- height: 85
- };
- this.updateQueue = new UpdateQueue({
- onUpdate: this.runSysUpdate.bind(this)
- });
-}
-
-Overview.prototype.addNode = function(node) {
- node.position = this.nodesCount;
- this.nodes[node.Id] = node;
- this.nodesCount++;
-}
-
-Overview.prototype.rebuild = function() {
- if (!this.statusMap) {
- this.nodeMapSettings.nodes = this.nodesCount;
- this.statusMap = new NodeMap(this.nodeMapSettings);
- this.ageMap = new NodeMap(this.nodeMapSettings);
- this.loadMap = new NodeMap(this.nodeMapSettings);
- var container = $(this.domElement);
- container.append($('<div>', {class: 'map_overview_header'}).text('Status'));
- container.append(this.statusMap.domElement);
- container.append($('<div>', {class: 'map_overview_header'}).text('Age'));
- container.append(this.ageMap.domElement);
- container.append($('<div>', {class: 'map_overview_header'}).text('Load Average'));
- container.append(this.loadMap.domElement);
- for (var nodeId in this.nodes) {
- var node = this.nodes[nodeId];
- var title = node.getTooltipText();
- this.statusMap.setNodeTitle(node.position, title);
- this.ageMap.setNodeTitle(node.position, title);
- this.loadMap.setNodeTitle(node.position, title);
- }
- }
-}
-
-Overview.prototype.runSysUpdate = function(update) {
- var nodeId = update.NodeId;
- if (nodeId) {
- var node = this.nodes[nodeId];
- if (node) {
- node.updateSysInfoStatsOnly(update);
- }
- var statusColor = node.getStatusColor();
- this.statusMap.setNodeMap(node.position, statusColor);
- var ageColor = node.getAgeColor();
- this.ageMap.setNodeMap(node.position, ageColor);
- var loadAverage = node.getLoadAverage();
- if (loadAverage) {
- var loadColor = this.poolColors.getPoolColor(loadAverage);
- this.loadMap.setNodeMap(node.position, loadColor);
- }
- }
-}
-
-Overview.prototype.onSysInfo = function(data) {
- if (data.SystemStateInfo !== undefined) {
- var deadNodes = {};
- if (!data.since) {
- for (var i in this.nodes) {
- deadNodes[i] = true;
- }
- this.updateQueue.flushUpdateQueue();
- } else {
- data.SystemStateInfo.sort(function(a, b) {
- return Number(b.ChangeTime) - Number(a.ChangeTime);
- });
- }
- for (var idx = 0; idx < data.SystemStateInfo.length; ++idx) {
- var update = data.SystemStateInfo[idx];
- if (!data.since) {
- delete deadNodes[update.NodeId];
- }
- this.updateQueue.enqueue(update);
- }
- for (var i in deadNodes) {
- var node = this.nodes[i];
- if (node) {
- this.statusMap.setNodeMap(node.position, 'black');
- this.ageMap.setNodeMap(node.position, 'black');
- this.loadMap.setNodeMap(node.position, 'black');
- }
- }
- }
- if (!this.updateQueue.isEmpty()) {
- this.updateQueue.updateDelay = Math.floor(data.refreshTimeout / this.updateQueue.getLength());
- console.log('Overview.updateQueue length = ' + this.updateQueue.getLength() + ' updateDelay = ' + this.updateQueue.updateDelay);
- } else {
- this.updateQueue.updateDelay = 50;
- }
-}
-
-Overview.prototype.onDisconnect = function() {
-
-}
-
diff --git a/ydb/core/viewer/content/v2/pdisk.js b/ydb/core/viewer/content/v2/pdisk.js
index c44ceb74eb2..80a084a73fc 100644
--- a/ydb/core/viewer/content/v2/pdisk.js
+++ b/ydb/core/viewer/content/v2/pdisk.js
@@ -1,205 +1,205 @@
-function PDisk(update, options) {
- Object.assign(this, update, options);
- this.Id = getPDiskId(this);
- this.buildDomElement();
-}
-
-PDisk.prototype.getPDiskUrl = function() {
- var url;
- if (this.diskCell && this.diskCell.diskMap && this.diskCell.diskMap.node) {
- url = this.diskCell.diskMap.node.getBaseUrl() + 'actors/pdisks/pdisk' + pad9(this.PDiskId);
- } else if (this.Host) {
- url = getBaseUrlForHost(this.Host + ':8765') + 'actors/pdisks/pdisk' + pad9(this.PDiskId);
- }
- return url;
-}
-
-PDisk.prototype.onClick = function() {
- var url = this.getPDiskUrl();
- if (url) {
- window.open(url);
- }
-}
-
-PDisk.prototype.buildDomElement = function() {
- var pDiskElement = $('<div>', {
- class: 'progress pdisk ' + this.class
- });
- var progressBar = $('<div>', {
- 'class': 'progress-bar pdisk_bar',
- 'aria-valuemin': 0,
- 'aria-valuemax': 100
- });
- progressBar.append($('<span>', {class: 'pdisk_bar_value'}));
- pDiskElement.append(progressBar);
- pDiskElement.append($('<div>', {class: 'pdisk_icons'}));
- pDiskElement.tooltip({html: true}).on('show.bs.tooltip', function() {
- this.diskCell.diskMap.onShowPDiskToolTip(this);
- }.bind(this)).on('hide.bs.tooltip', function() {
- this.diskCell.diskMap.onHidePDiskToolTip(this);
- }.bind(this)).click(this.onClick.bind(this));
-
- this.domElement = pDiskElement[0];
- this.updatePDiskInfo();
-}
-
-PDisk.prototype.getIcon = function(icon, color) {
- return "<span class='glyphicon glyphicon-" + icon + " pdisk_icon' style='color:" + color + "'></span>";
-}
-
-PDisk.prototype.getDeviceIcon = function(color) {
- return this.getIcon('save', color);
-}
-
-PDisk.prototype.getRealtimeIcon = function(color) {
- return this.getIcon('fire', color);
-}
-
-PDisk.prototype.getUsage = function() {
- if (this.TotalSize && this.AvailableSize) {
- return 1 - (this.AvailableSize / this.TotalSize);
- } else {
- return 0;
- }
-}
-
-PDisk.prototype.updatePDiskInfo = function(update) {
- if (update) {
- if (update.TotalSize) {
- update.TotalSize = Number(update.TotalSize);
- }
- if (update.AvailableSize) {
- update.AvailableSize = Number(update.AvailableSize);
- }
- Object.assign(this, update);
- if (!update.State) {
- delete this.State;
- }
- }
- var pDisk = $(this.domElement);
- var state = '';
- var html = '';
- var progressBar = pDisk.find('.progress-bar');
- var progressBarValue = progressBar.find('.pdisk_bar_value');
- state = '<table class="tooltip-table"><tr><td>PDisk</td><td>' + this.Id + '</td></tr>';
- if (this.State) {
- state += '<tr><td>State</td><td>' + this.State + '</td></tr>';
- } else {
- state += '<tr><td>State</td><td>not available</td></tr>';
- }
- if (this.Host) {
- state += '<tr><td>Host</td><td style="white-space: nowrap">' + this.Host + '</td></tr>';
- }
- if (this.Path) {
- state += '<tr><td>Path</td><td style="white-space: nowrap">' + this.Path + '</td></tr>';
- }
- if (this.State === 'Normal') {
- pDisk.css('backgroundColor', 'lightblue');
- this.color = green;
- var total = this.TotalSize;
- var avail = this.AvailableSize;
- if (total !== undefined && avail !== undefined) {
- var percent = Math.round((total - avail) * 100 / total);
- var progressClass = '';
- if (percent >= 92) {
- progressClass = 'progress-bar-danger';
- this.color = orange;
- } else if (percent >= 85) {
- progressClass = 'progress-bar-warning';
- this.color = yellow;
- } else {
- progressClass = 'progress-bar-success';
- }
- progressBar.removeClass('progress-bar-danger progress-bar-warning progress-bar-success').addClass(progressClass);
- progressBar.attr('aria-valuenow', percent);
- progressBar.css('width', percent + '%');
- progressBarValue.html(percent + '%');
- if (percent < 8 || percent >= 85) {
- progressBarValue.css('color', '#303030');
- } else {
- progressBarValue.css('color', 'white');
- }
- state += '<tr><td>Available</td><td>' + bytesToGB(avail) + ' of ' + bytesToGB(total) + '</td></tr>';
- if (this.Realtime !== undefined) {
- switch (this.Realtime) {
- case 'Yellow':
- html += this.getRealtimeIcon('yellow');
- state += '<tr><td>Realtime</td><td>Yellow</td></tr>';
- break;
- case 'Orange':
- html += this.getRealtimeIcon('orange');
- state += '<tr><td>Realtime</td><td>Orange</td></tr>';
- break;
- case 'Red':
- html += this.getRealtimeIcon('red');
- state += '<tr><td>Realtime</td><td>Red</td></tr>';
- break;
- }
- }
-
- if (this.Device !== undefined) {
- switch (this.Device) {
- case 'Yellow':
- html += this.getDeviceIcon('yellow');
- state += '<tr><td>Device</td><td>Yellow</td></tr>';
- break;
- case 'Orange':
- html += this.getDeviceIcon('orange');
- state += '<tr><td>Device</td><td>Orange</td></tr>';
- break;
- case 'Red':
- html += this.getDeviceIcon('red');
- state += '<tr><td>Device</td><td>Red</td></tr>';
- break;
- }
- }
- //progressBar.append(html);
- }
- }
- switch (this.State) {
- case 'Initial':
- pDisk.css('background-color', grey);
- this.color = grey;
- break;
- case 'Normal':
- pDisk[0].style.backgroundColor = 'lightblue';
- this.color = green;
- // wtf?
- break;
- case 'InitialFormatRead':
- case 'InitialSysLogRead':
- case 'InitialCommonLogRead':
- pDisk.css('background-color', yellow);
- this.color = yellow;
- break;
- case 'InitialFormatReadError':
- case 'InitialSysLogReadError':
- case 'InitialSysLogParseError':
- case 'InitialCommonLogReadError':
- case 'InitialCommonLogParseError':
- case 'CommonLoggerInitError':
- case 'OpenFileError':
+function PDisk(update, options) {
+ Object.assign(this, update, options);
+ this.Id = getPDiskId(this);
+ this.buildDomElement();
+}
+
+PDisk.prototype.getPDiskUrl = function() {
+ var url;
+ if (this.diskCell && this.diskCell.diskMap && this.diskCell.diskMap.node) {
+ url = this.diskCell.diskMap.node.getBaseUrl() + 'actors/pdisks/pdisk' + pad9(this.PDiskId);
+ } else if (this.Host) {
+ url = getBaseUrlForHost(this.Host + ':8765') + 'actors/pdisks/pdisk' + pad9(this.PDiskId);
+ }
+ return url;
+}
+
+PDisk.prototype.onClick = function() {
+ var url = this.getPDiskUrl();
+ if (url) {
+ window.open(url);
+ }
+}
+
+PDisk.prototype.buildDomElement = function() {
+ var pDiskElement = $('<div>', {
+ class: 'progress pdisk ' + this.class
+ });
+ var progressBar = $('<div>', {
+ 'class': 'progress-bar pdisk_bar',
+ 'aria-valuemin': 0,
+ 'aria-valuemax': 100
+ });
+ progressBar.append($('<span>', {class: 'pdisk_bar_value'}));
+ pDiskElement.append(progressBar);
+ pDiskElement.append($('<div>', {class: 'pdisk_icons'}));
+ pDiskElement.tooltip({html: true}).on('show.bs.tooltip', function() {
+ this.diskCell.diskMap.onShowPDiskToolTip(this);
+ }.bind(this)).on('hide.bs.tooltip', function() {
+ this.diskCell.diskMap.onHidePDiskToolTip(this);
+ }.bind(this)).click(this.onClick.bind(this));
+
+ this.domElement = pDiskElement[0];
+ this.updatePDiskInfo();
+}
+
+PDisk.prototype.getIcon = function(icon, color) {
+ return "<span class='glyphicon glyphicon-" + icon + " pdisk_icon' style='color:" + color + "'></span>";
+}
+
+PDisk.prototype.getDeviceIcon = function(color) {
+ return this.getIcon('save', color);
+}
+
+PDisk.prototype.getRealtimeIcon = function(color) {
+ return this.getIcon('fire', color);
+}
+
+PDisk.prototype.getUsage = function() {
+ if (this.TotalSize && this.AvailableSize) {
+ return 1 - (this.AvailableSize / this.TotalSize);
+ } else {
+ return 0;
+ }
+}
+
+PDisk.prototype.updatePDiskInfo = function(update) {
+ if (update) {
+ if (update.TotalSize) {
+ update.TotalSize = Number(update.TotalSize);
+ }
+ if (update.AvailableSize) {
+ update.AvailableSize = Number(update.AvailableSize);
+ }
+ Object.assign(this, update);
+ if (!update.State) {
+ delete this.State;
+ }
+ }
+ var pDisk = $(this.domElement);
+ var state = '';
+ var html = '';
+ var progressBar = pDisk.find('.progress-bar');
+ var progressBarValue = progressBar.find('.pdisk_bar_value');
+ state = '<table class="tooltip-table"><tr><td>PDisk</td><td>' + this.Id + '</td></tr>';
+ if (this.State) {
+ state += '<tr><td>State</td><td>' + this.State + '</td></tr>';
+ } else {
+ state += '<tr><td>State</td><td>not available</td></tr>';
+ }
+ if (this.Host) {
+ state += '<tr><td>Host</td><td style="white-space: nowrap">' + this.Host + '</td></tr>';
+ }
+ if (this.Path) {
+ state += '<tr><td>Path</td><td style="white-space: nowrap">' + this.Path + '</td></tr>';
+ }
+ if (this.State === 'Normal') {
+ pDisk.css('backgroundColor', 'lightblue');
+ this.color = green;
+ var total = this.TotalSize;
+ var avail = this.AvailableSize;
+ if (total !== undefined && avail !== undefined) {
+ var percent = Math.round((total - avail) * 100 / total);
+ var progressClass = '';
+ if (percent >= 92) {
+ progressClass = 'progress-bar-danger';
+ this.color = orange;
+ } else if (percent >= 85) {
+ progressClass = 'progress-bar-warning';
+ this.color = yellow;
+ } else {
+ progressClass = 'progress-bar-success';
+ }
+ progressBar.removeClass('progress-bar-danger progress-bar-warning progress-bar-success').addClass(progressClass);
+ progressBar.attr('aria-valuenow', percent);
+ progressBar.css('width', percent + '%');
+ progressBarValue.html(percent + '%');
+ if (percent < 8 || percent >= 85) {
+ progressBarValue.css('color', '#303030');
+ } else {
+ progressBarValue.css('color', 'white');
+ }
+ state += '<tr><td>Available</td><td>' + bytesToGB(avail) + ' of ' + bytesToGB(total) + '</td></tr>';
+ if (this.Realtime !== undefined) {
+ switch (this.Realtime) {
+ case 'Yellow':
+ html += this.getRealtimeIcon('yellow');
+ state += '<tr><td>Realtime</td><td>Yellow</td></tr>';
+ break;
+ case 'Orange':
+ html += this.getRealtimeIcon('orange');
+ state += '<tr><td>Realtime</td><td>Orange</td></tr>';
+ break;
+ case 'Red':
+ html += this.getRealtimeIcon('red');
+ state += '<tr><td>Realtime</td><td>Red</td></tr>';
+ break;
+ }
+ }
+
+ if (this.Device !== undefined) {
+ switch (this.Device) {
+ case 'Yellow':
+ html += this.getDeviceIcon('yellow');
+ state += '<tr><td>Device</td><td>Yellow</td></tr>';
+ break;
+ case 'Orange':
+ html += this.getDeviceIcon('orange');
+ state += '<tr><td>Device</td><td>Orange</td></tr>';
+ break;
+ case 'Red':
+ html += this.getDeviceIcon('red');
+ state += '<tr><td>Device</td><td>Red</td></tr>';
+ break;
+ }
+ }
+ //progressBar.append(html);
+ }
+ }
+ switch (this.State) {
+ case 'Initial':
+ pDisk.css('background-color', grey);
+ this.color = grey;
+ break;
+ case 'Normal':
+ pDisk[0].style.backgroundColor = 'lightblue';
+ this.color = green;
+ // wtf?
+ break;
+ case 'InitialFormatRead':
+ case 'InitialSysLogRead':
+ case 'InitialCommonLogRead':
+ pDisk.css('background-color', yellow);
+ this.color = yellow;
+ break;
+ case 'InitialFormatReadError':
+ case 'InitialSysLogReadError':
+ case 'InitialSysLogParseError':
+ case 'InitialCommonLogReadError':
+ case 'InitialCommonLogParseError':
+ case 'CommonLoggerInitError':
+ case 'OpenFileError':
case 'ChunkQuotaError':
case 'DeviceIoError':
- pDisk.css('background-color', red);
- this.color = red;
- break;
- case undefined:
- pDisk.css('background-color', red);
- this.color = red;
- break;
- }
-
- state += '</table>';
- var pDiskIcons = pDisk.find('.pdisk_icons');
- pDiskIcons.html(html);
- pDisk.attr('data-original-title', state);
-}
-
-PDisk.prototype.restoreTooltips = function() {
- $(this.domElement).tooltip({html: true}).on('show.bs.tooltip', function() {
- this.diskCell.diskMap.onShowPDiskToolTip(this);
- }.bind(this)).on('hide.bs.tooltip', function() {
- this.diskCell.diskMap.onHidePDiskToolTip(this);
- }.bind(this));
-}
+ pDisk.css('background-color', red);
+ this.color = red;
+ break;
+ case undefined:
+ pDisk.css('background-color', red);
+ this.color = red;
+ break;
+ }
+
+ state += '</table>';
+ var pDiskIcons = pDisk.find('.pdisk_icons');
+ pDiskIcons.html(html);
+ pDisk.attr('data-original-title', state);
+}
+
+PDisk.prototype.restoreTooltips = function() {
+ $(this.domElement).tooltip({html: true}).on('show.bs.tooltip', function() {
+ this.diskCell.diskMap.onShowPDiskToolTip(this);
+ }.bind(this)).on('hide.bs.tooltip', function() {
+ this.diskCell.diskMap.onHidePDiskToolTip(this);
+ }.bind(this));
+}
diff --git a/ydb/core/viewer/content/v2/pool_block.js b/ydb/core/viewer/content/v2/pool_block.js
index cff01ce1cfd..7086b37abce 100644
--- a/ydb/core/viewer/content/v2/pool_block.js
+++ b/ydb/core/viewer/content/v2/pool_block.js
@@ -1,38 +1,38 @@
-function PoolBlock() {
- this.buildDomElement();
-}
-
-PoolBlock.prototype.poolColors = new PoolColors();
-
-PoolBlock.prototype.buildDomElement = function() {
- var pooldiv = $('<div>', {class: 'pool_block', style: 'width:39px;background-color:#90ee90'});
- var innerdiv = $('<div>', {class: 'pool_div', style: 'height:100%;background-color:' + lightgrey});
- var innerspan = $('<span>', {class: 'pool_span'});
- pooldiv.append(innerdiv);
- pooldiv.append(innerspan);
- this.domElementDiv = innerdiv[0];
- this.domElementSpan = innerspan[0];
- this.domElement = pooldiv[0];
- pooldiv.tooltip({html: true});
-}
-
-PoolBlock.prototype.setText = function(text) {
- $(this.domElementSpan).text(text);
-}
-
-PoolBlock.prototype.setUsage = function(value) {
- var usage = (value * 100).toFixed();
- if (usage < 0) {
- usage = 0;
- }
- if (usage > 100) {
- usage = 100;
- }
- var height = 100 - usage;
- this.domElement.style.backgroundColor = this.poolColors.getPoolColor(value);
- this.domElementDiv.style.height = height + '%';
-}
-
-PoolBlock.prototype.restoreTooltips = function() {
- $(this.domElement).tooltip({html: true});
-}
+function PoolBlock() {
+ this.buildDomElement();
+}
+
+PoolBlock.prototype.poolColors = new PoolColors();
+
+PoolBlock.prototype.buildDomElement = function() {
+ var pooldiv = $('<div>', {class: 'pool_block', style: 'width:39px;background-color:#90ee90'});
+ var innerdiv = $('<div>', {class: 'pool_div', style: 'height:100%;background-color:' + lightgrey});
+ var innerspan = $('<span>', {class: 'pool_span'});
+ pooldiv.append(innerdiv);
+ pooldiv.append(innerspan);
+ this.domElementDiv = innerdiv[0];
+ this.domElementSpan = innerspan[0];
+ this.domElement = pooldiv[0];
+ pooldiv.tooltip({html: true});
+}
+
+PoolBlock.prototype.setText = function(text) {
+ $(this.domElementSpan).text(text);
+}
+
+PoolBlock.prototype.setUsage = function(value) {
+ var usage = (value * 100).toFixed();
+ if (usage < 0) {
+ usage = 0;
+ }
+ if (usage > 100) {
+ usage = 100;
+ }
+ var height = 100 - usage;
+ this.domElement.style.backgroundColor = this.poolColors.getPoolColor(value);
+ this.domElementDiv.style.height = height + '%';
+}
+
+PoolBlock.prototype.restoreTooltips = function() {
+ $(this.domElement).tooltip({html: true});
+}
diff --git a/ydb/core/viewer/content/v2/pool_map.js b/ydb/core/viewer/content/v2/pool_map.js
index 46c500ea288..7fbc8530bd3 100644
--- a/ydb/core/viewer/content/v2/pool_map.js
+++ b/ydb/core/viewer/content/v2/pool_map.js
@@ -1,54 +1,54 @@
-function PoolMap() {
- this.buildDomElement();
-}
-
-PoolMap.prototype.poolColors = new PoolColors();
-
-PoolMap.prototype.buildDomElement = function() {
- this.domElement = $('<div>', {class: 'pool_row'})[0];
-}
-
-PoolMap.prototype.setPoolMap = function(pools) {
- var poolsrow = $(this.domElement);
- var children = poolsrow.find('.pool_cell');
- for (var idx = 0; idx < pools.length; idx++) {
- var cell;
- var pool;
- var inner;
- if (idx >= children.length) {
- cell = $('<div>', {class: 'pool_cell'});
- var pooldiv = $('<div>', {class: 'pool_block'});
- var innerdiv = $('<div>', {style: 'width:100%;height:50%;background-color:' + lightgrey});
- pooldiv.append(innerdiv);
- cell.append(pooldiv);
- poolsrow.append(cell);
- pool = pooldiv[0];
- inner = innerdiv[0];
- cell.tooltip();
- cell = cell[0];
- } else {
- cell = children[idx];
- pool = cell.firstChild;
- inner = pool.firstChild;
- }
- var usage = (pools[idx].Usage * 100).toFixed();
- if (pools[idx].Name !== '') {
- cell.setAttribute('data-original-title', pools[idx].Name + ' ' + usage + '%');
- } else {
- cell.setAttribute('data-original-title', usage + '%');
- }
- if (usage < 0) {
- usage = 0;
- }
- if (usage > 100) {
- usage = 100;
- }
- var height = 100 - usage;
- pool.style.backgroundColor = this.poolColors.getPoolColor(pools[idx].Usage);
- inner.style.height = height + '%';
- }
-}
-
-PoolMap.prototype.restoreTooltips = function() {
- $(this.domElement).find('.pool_cell').tooltip('enable');
-}
+function PoolMap() {
+ this.buildDomElement();
+}
+
+PoolMap.prototype.poolColors = new PoolColors();
+
+PoolMap.prototype.buildDomElement = function() {
+ this.domElement = $('<div>', {class: 'pool_row'})[0];
+}
+
+PoolMap.prototype.setPoolMap = function(pools) {
+ var poolsrow = $(this.domElement);
+ var children = poolsrow.find('.pool_cell');
+ for (var idx = 0; idx < pools.length; idx++) {
+ var cell;
+ var pool;
+ var inner;
+ if (idx >= children.length) {
+ cell = $('<div>', {class: 'pool_cell'});
+ var pooldiv = $('<div>', {class: 'pool_block'});
+ var innerdiv = $('<div>', {style: 'width:100%;height:50%;background-color:' + lightgrey});
+ pooldiv.append(innerdiv);
+ cell.append(pooldiv);
+ poolsrow.append(cell);
+ pool = pooldiv[0];
+ inner = innerdiv[0];
+ cell.tooltip();
+ cell = cell[0];
+ } else {
+ cell = children[idx];
+ pool = cell.firstChild;
+ inner = pool.firstChild;
+ }
+ var usage = (pools[idx].Usage * 100).toFixed();
+ if (pools[idx].Name !== '') {
+ cell.setAttribute('data-original-title', pools[idx].Name + ' ' + usage + '%');
+ } else {
+ cell.setAttribute('data-original-title', usage + '%');
+ }
+ if (usage < 0) {
+ usage = 0;
+ }
+ if (usage > 100) {
+ usage = 100;
+ }
+ var height = 100 - usage;
+ pool.style.backgroundColor = this.poolColors.getPoolColor(pools[idx].Usage);
+ inner.style.height = height + '%';
+ }
+}
+
+PoolMap.prototype.restoreTooltips = function() {
+ $(this.domElement).find('.pool_cell').tooltip('enable');
+}
diff --git a/ydb/core/viewer/content/v2/runner.html b/ydb/core/viewer/content/v2/runner.html
index ed5c5fa9ec9..d70f66a2af1 100644
--- a/ydb/core/viewer/content/v2/runner.html
+++ b/ydb/core/viewer/content/v2/runner.html
@@ -1,191 +1,191 @@
-<html>
-<head>
-<link rel='stylesheet' href='//yandex.st/bootstrap/3.3.1/css/bootstrap.min.css'>
-<link rel="stylesheet" href="../style.min.css" />
-<link rel="stylesheet" href="viewer.css" />
-<script language='javascript' type='text/javascript' src='//yandex.st/jquery/3.1.1/jquery.min.js'></script>
-<script language='javascript' type='text/javascript' src='//yandex.st/bootstrap/3.3.1/js/bootstrap.min.js'></script>
-<script src="../jstree.min.js"></script>
-<script src="util.js"></script>
-<script src="pool_map.js"></script>
-<script src="node_map.js"></script>
-<script src="pdisk.js"></script>
-<script src="vdisk.js"></script>
-<script src="disk_cell.js"></script>
-<script src="disk_map.js"></script>
-<script src="node.js"></script>
-<script src="node_group.js"></script>
-<script src="node_view.js"></script>
-<script src="viewer.js"></script>
-</head>
-<body style='margin-left:20px;margin-top:20px' onload='
- setInterval(updateNodeMap1, 200);
- setInterval(updateNodeMap2, 10);
- setInterval(updateDiskMap3, 500);
- setInterval(updatePoolMap4, 500);
- '>
-<div style='display:flex;flex-direction:column'>
-<div style='display:flex;padding-bottom:10px'>
-<div id='nodecnt1' style='width:100px'></div>
-<div id='nodemap1'></div>
-</div>
-<div style='display:flex;padding-bottom:10px'>
-<div id='nodecnt2' style='width:100px'></div>
-<div id='nodemap2'></div>
-</div>
-<div style='display:flex;padding-bottom:10px'>
-<div id='diskcnt3' style='width:100px'></div>
-<div id='diskmap3'></div>
-</div>
-<div style='display:flex;padding-bottom:10px'>
-<div id='poolcnt4' style='width:100px'></div>
-<div id='poolmap4'></div>
-</div>
-</div>
-
-<div id='diskcell1'></div>
-
-<script>
-var nodenum1 = 1;
-var nodemap1;
-
-var nodenum2 = 1;
-var nodemap2;
-
-var disknum3 = 1;
-var diskmap3;
-
-var poolnum4 = 1;
-var poolmap4;
-
-function updateNodeMap1() {
- var size = 5;
- var space = 1;
- if (nodenum1 <= 16) {
- size = 20;
- } else if (nodenum1 <= 72) {
- size = 10;
- }
- var height = 22;
- if (nodenum1 > 512) {
- if (nodenum1 > 1000) {
- size = 3;
- }
- height += Math.floor((nodenum1 - 512) / 512) * size;
- }
- nodemap1 = new NodeMap({nodes: nodenum1, height: height, placeSize: size, boxSpace: space});
- $('#nodemap1').empty().append(nodemap1.domElement);
- var color;
- for (var i = 0; i < nodenum1; ++i) {
- switch (Math.floor(Math.random() * 4)) {
- case 0:
- color = red;
- break;
- case 1:
- color = green;
- break;
- case 2:
- color = yellow;
- break;
- case 3:
- color = null;
- break;
- }
- if (color) {
- nodemap1.setNodeMap(i, color);
- }
- }
- $('#nodecnt1').html(nodenum1);
- if (nodenum1 < 100) {
- ++nodenum1;
- } else {
- nodenum1 = 1;
- }
-}
-
-function updateNodeMap2() {
- var size = 5;
- if (nodenum2 <= 16) {
- size = 20;
- } else if (nodenum2 <= 72) {
- size = 10;
- }
- var height = 22;
- if (nodenum2 > 512) {
- if (nodenum2 > 1000) {
- size = 3;
- }
- height += Math.floor((nodenum2 - 512) / 512) * size;
- }
- nodemap2 = new NodeMap({nodes: nodenum2, height: height, placeSize: size});
- $('#nodemap2').empty().append(nodemap2.domElement);
- for (var i = 0; i < nodenum2; ++i) {
- nodemap2.setNodeMap(i, 'lightgreen');
- }
- $('#nodecnt2').html(nodenum2);
- if (nodenum2 < 2000) {
- ++nodenum2;
- } else {
- nodenum2 = 1;
- }
-}
-
-function updateDiskMap3() {
- diskmap3 = new DiskCell('1-1');
- $('#diskmap3').empty().append(diskmap3.domElement);
- diskmap3.updatePDiskInfo({
- NodeId: 1,
- PDiskId: 1,
- State: 'Normal',
- TotalSize: 100,
- AvailableSize: 60
- });
- for (var i = 0; i < disknum3; ++i) {
- diskmap3.updateVDiskInfo({
- VDiskId: {
- GroupID: 1,
- Ring: 1,
- Domain: 1,
- VDisk: i
- },
- VDiskState: 'OK',
- Replicated: true,
- AllocatedSize: 3
- });
- }
- diskmap3.resizeVDisks();
- $('#diskcnt3').html(disknum3);
- if (disknum3 < 25) {
- ++disknum3;
- } else {
- DiskCell.prototype.vDiskClass = 'vdisk-wide';
- DiskCell.prototype.pDiskClass = 'pdisk-narrow';
- DiskCell.prototype.maxVDisks = 0;
- DiskCell.prototype.totalWidth = 100;
- disknum3 = 1;
- }
-}
-
-function updatePoolMap4() {
- poolmap4 = new PoolMap();
- $('#poolmap4').empty().append(poolmap4.domElement);
- poolmap4.setPoolMap([
- {
- Name: 'pool1',
- Usage: poolnum4 / 10
- },
- {
- Name: 'pool2',
- Usage: 1 - poolnum4 / 10
- }]);
- $('#poolcnt4').html(poolnum4);
- if (poolnum4 < 10) {
- ++poolnum4;
- } else {
- poolnum4 = 0;
- }
-}
-
-</script>
-
-</body>
+<html>
+<head>
+<link rel='stylesheet' href='//yandex.st/bootstrap/3.3.1/css/bootstrap.min.css'>
+<link rel="stylesheet" href="../style.min.css" />
+<link rel="stylesheet" href="viewer.css" />
+<script language='javascript' type='text/javascript' src='//yandex.st/jquery/3.1.1/jquery.min.js'></script>
+<script language='javascript' type='text/javascript' src='//yandex.st/bootstrap/3.3.1/js/bootstrap.min.js'></script>
+<script src="../jstree.min.js"></script>
+<script src="util.js"></script>
+<script src="pool_map.js"></script>
+<script src="node_map.js"></script>
+<script src="pdisk.js"></script>
+<script src="vdisk.js"></script>
+<script src="disk_cell.js"></script>
+<script src="disk_map.js"></script>
+<script src="node.js"></script>
+<script src="node_group.js"></script>
+<script src="node_view.js"></script>
+<script src="viewer.js"></script>
+</head>
+<body style='margin-left:20px;margin-top:20px' onload='
+ setInterval(updateNodeMap1, 200);
+ setInterval(updateNodeMap2, 10);
+ setInterval(updateDiskMap3, 500);
+ setInterval(updatePoolMap4, 500);
+ '>
+<div style='display:flex;flex-direction:column'>
+<div style='display:flex;padding-bottom:10px'>
+<div id='nodecnt1' style='width:100px'></div>
+<div id='nodemap1'></div>
+</div>
+<div style='display:flex;padding-bottom:10px'>
+<div id='nodecnt2' style='width:100px'></div>
+<div id='nodemap2'></div>
+</div>
+<div style='display:flex;padding-bottom:10px'>
+<div id='diskcnt3' style='width:100px'></div>
+<div id='diskmap3'></div>
+</div>
+<div style='display:flex;padding-bottom:10px'>
+<div id='poolcnt4' style='width:100px'></div>
+<div id='poolmap4'></div>
+</div>
+</div>
+
+<div id='diskcell1'></div>
+
+<script>
+var nodenum1 = 1;
+var nodemap1;
+
+var nodenum2 = 1;
+var nodemap2;
+
+var disknum3 = 1;
+var diskmap3;
+
+var poolnum4 = 1;
+var poolmap4;
+
+function updateNodeMap1() {
+ var size = 5;
+ var space = 1;
+ if (nodenum1 <= 16) {
+ size = 20;
+ } else if (nodenum1 <= 72) {
+ size = 10;
+ }
+ var height = 22;
+ if (nodenum1 > 512) {
+ if (nodenum1 > 1000) {
+ size = 3;
+ }
+ height += Math.floor((nodenum1 - 512) / 512) * size;
+ }
+ nodemap1 = new NodeMap({nodes: nodenum1, height: height, placeSize: size, boxSpace: space});
+ $('#nodemap1').empty().append(nodemap1.domElement);
+ var color;
+ for (var i = 0; i < nodenum1; ++i) {
+ switch (Math.floor(Math.random() * 4)) {
+ case 0:
+ color = red;
+ break;
+ case 1:
+ color = green;
+ break;
+ case 2:
+ color = yellow;
+ break;
+ case 3:
+ color = null;
+ break;
+ }
+ if (color) {
+ nodemap1.setNodeMap(i, color);
+ }
+ }
+ $('#nodecnt1').html(nodenum1);
+ if (nodenum1 < 100) {
+ ++nodenum1;
+ } else {
+ nodenum1 = 1;
+ }
+}
+
+function updateNodeMap2() {
+ var size = 5;
+ if (nodenum2 <= 16) {
+ size = 20;
+ } else if (nodenum2 <= 72) {
+ size = 10;
+ }
+ var height = 22;
+ if (nodenum2 > 512) {
+ if (nodenum2 > 1000) {
+ size = 3;
+ }
+ height += Math.floor((nodenum2 - 512) / 512) * size;
+ }
+ nodemap2 = new NodeMap({nodes: nodenum2, height: height, placeSize: size});
+ $('#nodemap2').empty().append(nodemap2.domElement);
+ for (var i = 0; i < nodenum2; ++i) {
+ nodemap2.setNodeMap(i, 'lightgreen');
+ }
+ $('#nodecnt2').html(nodenum2);
+ if (nodenum2 < 2000) {
+ ++nodenum2;
+ } else {
+ nodenum2 = 1;
+ }
+}
+
+function updateDiskMap3() {
+ diskmap3 = new DiskCell('1-1');
+ $('#diskmap3').empty().append(diskmap3.domElement);
+ diskmap3.updatePDiskInfo({
+ NodeId: 1,
+ PDiskId: 1,
+ State: 'Normal',
+ TotalSize: 100,
+ AvailableSize: 60
+ });
+ for (var i = 0; i < disknum3; ++i) {
+ diskmap3.updateVDiskInfo({
+ VDiskId: {
+ GroupID: 1,
+ Ring: 1,
+ Domain: 1,
+ VDisk: i
+ },
+ VDiskState: 'OK',
+ Replicated: true,
+ AllocatedSize: 3
+ });
+ }
+ diskmap3.resizeVDisks();
+ $('#diskcnt3').html(disknum3);
+ if (disknum3 < 25) {
+ ++disknum3;
+ } else {
+ DiskCell.prototype.vDiskClass = 'vdisk-wide';
+ DiskCell.prototype.pDiskClass = 'pdisk-narrow';
+ DiskCell.prototype.maxVDisks = 0;
+ DiskCell.prototype.totalWidth = 100;
+ disknum3 = 1;
+ }
+}
+
+function updatePoolMap4() {
+ poolmap4 = new PoolMap();
+ $('#poolmap4').empty().append(poolmap4.domElement);
+ poolmap4.setPoolMap([
+ {
+ Name: 'pool1',
+ Usage: poolnum4 / 10
+ },
+ {
+ Name: 'pool2',
+ Usage: 1 - poolnum4 / 10
+ }]);
+ $('#poolcnt4').html(poolnum4);
+ if (poolnum4 < 10) {
+ ++poolnum4;
+ } else {
+ poolnum4 = 0;
+ }
+}
+
+</script>
+
+</body>
diff --git a/ydb/core/viewer/content/v2/stats.js b/ydb/core/viewer/content/v2/stats.js
index cc4cda61875..0b1f78fa2c6 100644
--- a/ydb/core/viewer/content/v2/stats.js
+++ b/ydb/core/viewer/content/v2/stats.js
@@ -1,42 +1,42 @@
-function Stat(options) {
- Object.assign(this,
- options);
- this.buildDomElement();
-}
-
-Stat.prototype.buildDomElement = function() {
- var cell = $('<div>', {class: 'stats_cell'});
- var name = $('<div>', {class: 'stats_name', text: this.name});
- var value = $('<div>', {class: 'stats_value', text: '-'});
- cell.append(name);
- cell.append(value);
- this.domElementValue = value[0];
- this.domElement = cell[0];
-}
-
-Stat.prototype.setValue = function(value) {
- $(this.domElementValue).text(value);
-}
-
-
-function Stats(options) {
- Object.assign(this,
- {
- stats: {}
- },
- options);
- this.buildDomElement();
-}
-
-Stats.prototype.buildDomElement = function() {
- this.domElement = $('<div>', {class: 'stats_container'})[0];
-}
-
-Stats.prototype.addStat = function(name) {
- var stat = this.stats[name];
- if (!stat) {
- stat = this.stats[name] = new Stat({name: name});
- $(this.domElement).append(stat.domElement);
- }
- return stat;
-}
+function Stat(options) {
+ Object.assign(this,
+ options);
+ this.buildDomElement();
+}
+
+Stat.prototype.buildDomElement = function() {
+ var cell = $('<div>', {class: 'stats_cell'});
+ var name = $('<div>', {class: 'stats_name', text: this.name});
+ var value = $('<div>', {class: 'stats_value', text: '-'});
+ cell.append(name);
+ cell.append(value);
+ this.domElementValue = value[0];
+ this.domElement = cell[0];
+}
+
+Stat.prototype.setValue = function(value) {
+ $(this.domElementValue).text(value);
+}
+
+
+function Stats(options) {
+ Object.assign(this,
+ {
+ stats: {}
+ },
+ options);
+ this.buildDomElement();
+}
+
+Stats.prototype.buildDomElement = function() {
+ this.domElement = $('<div>', {class: 'stats_container'})[0];
+}
+
+Stats.prototype.addStat = function(name) {
+ var stat = this.stats[name];
+ if (!stat) {
+ stat = this.stats[name] = new Stat({name: name});
+ $(this.domElement).append(stat.domElement);
+ }
+ return stat;
+}
diff --git a/ydb/core/viewer/content/v2/storage b/ydb/core/viewer/content/v2/storage
index 586b85f4602..a11ac5c3412 100644
--- a/ydb/core/viewer/content/v2/storage
+++ b/ydb/core/viewer/content/v2/storage
@@ -1,119 +1,119 @@
-<!DOCTYPE HTML>
-<html>
-<head>
-<link rel="stylesheet" href="https://yastatic.net/bootstrap/3.3.1/css/bootstrap.min.css">
-<script language="javascript" type="text/javascript" src="https://yastatic.net/jquery/2.1.3/jquery.min.js"></script>
-<script language="javascript" type="text/javascript" src="https://yastatic.net/bootstrap/3.3.1/js/bootstrap.min.js"></script>
-<style type="text/css">
-.table-nonfluid { width: auto; }
-.narrow-line50 {line-height: 50%}
-.narrow-line60 {line-height: 60%}
-.narrow-line70 {line-height: 70%}
-.narrow-line80 {line-height: 80%}
-.narrow-line90 {line-height: 90%}
-</style>
-<link rel="stylesheet" href="../style.min.css" />
-<link rel="stylesheet" href="viewer.css" />
-<script src="util.js"></script>
-<script src="pool_block.js"></script>
-<script src="pool_map.js"></script>
-<script src="node_map.js"></script>
-<script src="pdisk.js"></script>
-<script src="vdisk.js"></script>
-<script src="disk_cell.js"></script>
-<script src="disk_map.js"></script>
-<script src="tablet_cell.js"></script>
-<script src="tablet_map.js"></script>
-<script src="stats.js"></script>
-<script src="node.js"></script>
-<script src="node_group.js"></script>
-<script src="tenant.js"></script>
-<script src="overview.js"></script>
-<script src="cpu_view.js"></script>
-<script src="net_view.js"></script>
-<script src="storage.js"></script>
-<script src="storage_group.js"></script>
-<script src="storage_view.js"></script>
-<script src="node_view.js"></script>
-<script src="tenant_view.js"></script>
-<script src="viewer.js"></script>
-</head>
-<body onload='mainStorage();'>
-<div class='container-fluid'>
-<ul class="nav nav-tabs">
- <li class="nav-item">
- <a class="pseudo-nav-link" href="overview">Overview</a>
- </li>
- <li class="nav-item">
- <a class="pseudo-nav-link" href="cpu">CPU</a>
- </li>
- <li class="nav-item">
- <a class="pseudo-nav-link" href="network">Network</a>
- </li>
- <li class="nav-item active">
- <a class="pseudo-nav-link" href="storage">Storage</a>
- </li>
- <li class="nav-item">
- <a class="pseudo-nav-link" href="nodes">Nodes</a>
- </li>
- <li class="nav-item">
- <a class="pseudo-nav-link" href="tenants">Tenants</a>
- </li>
- <li style="float:right">
- <span id="updateQueueInflight" style="font-size:10px"></span>
- <span id="updateQueueCounter" style="font-weight:bold;font-size:20px;margin-left:40px"></span>
- </li>
-</ul>
-<div class="tab-content" style="padding-top: 10px">
- <div id="storage" class="tab-pane active">
- <div style='display:inline-block;min-width:1000px'>
- <div style='display:flex;flex-direction:row;justify-content:space-between;align-items:flex-end;"'>
- <div id='pacman' class='pacman' style='padding-left:100px'>
- <svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" style="margin:auto;background:#fff;display:block;" width="200px" height="100px" viewBox="0 0 100 100" preserveAspectRatio="xMidYMid">
- <g>
- <circle cx="48.0654" cy="50" r="4" fill="#e15b64">
- <animate attributeName="cx" repeatCount="indefinite" dur="1s" values="95;35" keyTimes="0;1" begin="-0.67s"></animate>
- <animate attributeName="fill-opacity" repeatCount="indefinite" dur="1s" values="0;1;1" keyTimes="0;0.2;1" begin="-0.67s"></animate>
- </circle>
- <circle cx="68.4654" cy="50" r="4" fill="#e15b64">
- <animate attributeName="cx" repeatCount="indefinite" dur="1s" values="95;35" keyTimes="0;1" begin="-0.33s"></animate>
- <animate attributeName="fill-opacity" repeatCount="indefinite" dur="1s" values="0;1;1" keyTimes="0;0.2;1" begin="-0.33s"></animate>
- </circle>
- <circle cx="88.2654" cy="50" r="4" fill="#e15b64">
- <animate attributeName="cx" repeatCount="indefinite" dur="1s" values="95;35" keyTimes="0;1" begin="0s"></animate>
- <animate attributeName="fill-opacity" repeatCount="indefinite" dur="1s" values="0;1;1" keyTimes="0;0.2;1" begin="0s"></animate>
- </circle>
- </g>
- <g transform="translate(-15 0)">
- <path d="M50 50L20 50A30 30 0 0 0 80 50Z" fill="#f8d86a" transform="rotate(90 50 50)"></path>
- <path d="M50 50L20 50A30 30 0 0 0 80 50Z" fill="#f8d86a" transform="rotate(40.1457 50 50)">
- <animateTransform attributeName="transform" type="rotate" repeatCount="indefinite" dur="0.3s" values="0 50 50;45 50 50;0 50 50" keyTimes="0;0.5;1"></animateTransform>
- </path>
- <path d="M50 50L20 50A30 30 0 0 1 80 50Z" fill="#f8d86a" transform="rotate(-40.1457 50 50)">
- <animateTransform attributeName="transform" type="rotate" repeatCount="indefinite" dur="0.3s" values="0 50 50;-45 50 50;0 50 50" keyTimes="0;0.5;1"></animateTransform>
- </path>
- </g>
- </svg>
- </div>
- <div id='stats_placement' style="display:none">
- </div>
- <div id='filter' style='font-size:120%;padding:10px 10px;flex-grow:1;display:none'>
- <label for='vdisk_filter'>Filter</label>
- <input id='vdisk_filter' type='text' size=60 data-original-title=''></input>
- <input id='vdisk_filter_button' type='button' value='apply'></input>
- </div>
- <div id='switches' style="font-size:14px;padding:10px 0px 10px 0px;display:none">
- <button class="btn btn-info storage_group_switch" value="pool" onclick="onStorageGroupChange(this)">Pool</button>
- <button class="btn btn-default storage_group_switch" value="color" onclick="onStorageGroupChange(this)">Color</button>
- <button class="btn btn-default storage_group_switch" value="status" onclick="onStorageGroupChange(this)">Status</button>
- <button class="btn btn-default storage_group_switch" value="usage" onclick="onStorageGroupChange(this)">Usage</button>
- <button class="btn btn-default storage_group_switch" value="missing" onclick="onStorageGroupChange(this)">Missing</button>
- </div>
- </div>
- <div id="storage_view" style='display:inline-block'></div>
- </div>
- </div>
-</div>
-</div>
-</body>
-</html>
+<!DOCTYPE HTML>
+<html>
+<head>
+<link rel="stylesheet" href="https://yastatic.net/bootstrap/3.3.1/css/bootstrap.min.css">
+<script language="javascript" type="text/javascript" src="https://yastatic.net/jquery/2.1.3/jquery.min.js"></script>
+<script language="javascript" type="text/javascript" src="https://yastatic.net/bootstrap/3.3.1/js/bootstrap.min.js"></script>
+<style type="text/css">
+.table-nonfluid { width: auto; }
+.narrow-line50 {line-height: 50%}
+.narrow-line60 {line-height: 60%}
+.narrow-line70 {line-height: 70%}
+.narrow-line80 {line-height: 80%}
+.narrow-line90 {line-height: 90%}
+</style>
+<link rel="stylesheet" href="../style.min.css" />
+<link rel="stylesheet" href="viewer.css" />
+<script src="util.js"></script>
+<script src="pool_block.js"></script>
+<script src="pool_map.js"></script>
+<script src="node_map.js"></script>
+<script src="pdisk.js"></script>
+<script src="vdisk.js"></script>
+<script src="disk_cell.js"></script>
+<script src="disk_map.js"></script>
+<script src="tablet_cell.js"></script>
+<script src="tablet_map.js"></script>
+<script src="stats.js"></script>
+<script src="node.js"></script>
+<script src="node_group.js"></script>
+<script src="tenant.js"></script>
+<script src="overview.js"></script>
+<script src="cpu_view.js"></script>
+<script src="net_view.js"></script>
+<script src="storage.js"></script>
+<script src="storage_group.js"></script>
+<script src="storage_view.js"></script>
+<script src="node_view.js"></script>
+<script src="tenant_view.js"></script>
+<script src="viewer.js"></script>
+</head>
+<body onload='mainStorage();'>
+<div class='container-fluid'>
+<ul class="nav nav-tabs">
+ <li class="nav-item">
+ <a class="pseudo-nav-link" href="overview">Overview</a>
+ </li>
+ <li class="nav-item">
+ <a class="pseudo-nav-link" href="cpu">CPU</a>
+ </li>
+ <li class="nav-item">
+ <a class="pseudo-nav-link" href="network">Network</a>
+ </li>
+ <li class="nav-item active">
+ <a class="pseudo-nav-link" href="storage">Storage</a>
+ </li>
+ <li class="nav-item">
+ <a class="pseudo-nav-link" href="nodes">Nodes</a>
+ </li>
+ <li class="nav-item">
+ <a class="pseudo-nav-link" href="tenants">Tenants</a>
+ </li>
+ <li style="float:right">
+ <span id="updateQueueInflight" style="font-size:10px"></span>
+ <span id="updateQueueCounter" style="font-weight:bold;font-size:20px;margin-left:40px"></span>
+ </li>
+</ul>
+<div class="tab-content" style="padding-top: 10px">
+ <div id="storage" class="tab-pane active">
+ <div style='display:inline-block;min-width:1000px'>
+ <div style='display:flex;flex-direction:row;justify-content:space-between;align-items:flex-end;"'>
+ <div id='pacman' class='pacman' style='padding-left:100px'>
+ <svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" style="margin:auto;background:#fff;display:block;" width="200px" height="100px" viewBox="0 0 100 100" preserveAspectRatio="xMidYMid">
+ <g>
+ <circle cx="48.0654" cy="50" r="4" fill="#e15b64">
+ <animate attributeName="cx" repeatCount="indefinite" dur="1s" values="95;35" keyTimes="0;1" begin="-0.67s"></animate>
+ <animate attributeName="fill-opacity" repeatCount="indefinite" dur="1s" values="0;1;1" keyTimes="0;0.2;1" begin="-0.67s"></animate>
+ </circle>
+ <circle cx="68.4654" cy="50" r="4" fill="#e15b64">
+ <animate attributeName="cx" repeatCount="indefinite" dur="1s" values="95;35" keyTimes="0;1" begin="-0.33s"></animate>
+ <animate attributeName="fill-opacity" repeatCount="indefinite" dur="1s" values="0;1;1" keyTimes="0;0.2;1" begin="-0.33s"></animate>
+ </circle>
+ <circle cx="88.2654" cy="50" r="4" fill="#e15b64">
+ <animate attributeName="cx" repeatCount="indefinite" dur="1s" values="95;35" keyTimes="0;1" begin="0s"></animate>
+ <animate attributeName="fill-opacity" repeatCount="indefinite" dur="1s" values="0;1;1" keyTimes="0;0.2;1" begin="0s"></animate>
+ </circle>
+ </g>
+ <g transform="translate(-15 0)">
+ <path d="M50 50L20 50A30 30 0 0 0 80 50Z" fill="#f8d86a" transform="rotate(90 50 50)"></path>
+ <path d="M50 50L20 50A30 30 0 0 0 80 50Z" fill="#f8d86a" transform="rotate(40.1457 50 50)">
+ <animateTransform attributeName="transform" type="rotate" repeatCount="indefinite" dur="0.3s" values="0 50 50;45 50 50;0 50 50" keyTimes="0;0.5;1"></animateTransform>
+ </path>
+ <path d="M50 50L20 50A30 30 0 0 1 80 50Z" fill="#f8d86a" transform="rotate(-40.1457 50 50)">
+ <animateTransform attributeName="transform" type="rotate" repeatCount="indefinite" dur="0.3s" values="0 50 50;-45 50 50;0 50 50" keyTimes="0;0.5;1"></animateTransform>
+ </path>
+ </g>
+ </svg>
+ </div>
+ <div id='stats_placement' style="display:none">
+ </div>
+ <div id='filter' style='font-size:120%;padding:10px 10px;flex-grow:1;display:none'>
+ <label for='vdisk_filter'>Filter</label>
+ <input id='vdisk_filter' type='text' size=60 data-original-title=''></input>
+ <input id='vdisk_filter_button' type='button' value='apply'></input>
+ </div>
+ <div id='switches' style="font-size:14px;padding:10px 0px 10px 0px;display:none">
+ <button class="btn btn-info storage_group_switch" value="pool" onclick="onStorageGroupChange(this)">Pool</button>
+ <button class="btn btn-default storage_group_switch" value="color" onclick="onStorageGroupChange(this)">Color</button>
+ <button class="btn btn-default storage_group_switch" value="status" onclick="onStorageGroupChange(this)">Status</button>
+ <button class="btn btn-default storage_group_switch" value="usage" onclick="onStorageGroupChange(this)">Usage</button>
+ <button class="btn btn-default storage_group_switch" value="missing" onclick="onStorageGroupChange(this)">Missing</button>
+ </div>
+ </div>
+ <div id="storage_view" style='display:inline-block'></div>
+ </div>
+ </div>
+</div>
+</div>
+</body>
+</html>
diff --git a/ydb/core/viewer/content/v2/storage.js b/ydb/core/viewer/content/v2/storage.js
index 70a9f387dbb..1872e4916d7 100644
--- a/ydb/core/viewer/content/v2/storage.js
+++ b/ydb/core/viewer/content/v2/storage.js
@@ -1,304 +1,304 @@
-function Storage(options) {
- Object.assign(this, {
- Id: options.GroupID,
- sysInfo: {},
- nodeInfo: {},
- poolMap: null,
- nodeMap: null,
- diskMap: null
- },
- options);
- this.buildDomElement();
-}
-
-Storage.prototype.buildDomElement = function() {
- var row = $('<tr>');
- row.data('storage', this);
- var id = $('<span>', {class: 'storage_group_id', text: this.Id});
- this.storageGroupIdDomElement = id[0];
- id.tooltip();
- row.append($('<td>').append(id));
-
- /*
-
- row.append($('<td>', {class: 'storage_units', text: this.AcquiredUnits}));
- row.append($('<td>', {class: 'storage_erasure', text: this.ErasureSpecies}));
- row.append($('<td>', {class: 'storage_latency', text: this.Latency}));
-
- var vdisks = new DiskMap(this.Id + '-vdisks');
- var pdisks = new DiskMap(this.Id + '-pdisks');
-
- for (var numVDisk in this.VDisks) {
- var vDisk = this.VDisks[numVDisk];
- vDisk.CellId = this.Id;
- vdisks.updateVDiskInfo(vDisk);
- }
-
- for (var numPDisk in this.VDisks) {
- var vDisk = this.VDisks[numPDisk];
- var pDisk = vDisk.PDisk;
- if (pDisk) {
- pdisks.updatePDiskInfo(pDisk);
- }
- }
-
- vdisks.resizeVDisks();
-
- var disks = $('<td>', {class: 'storage_vdisks'});
- disks.append(vdisks.domElement);
- row.append(disks);
-
- disks = $('<td>', {class: 'storage_pdisks'});
- disks.append(pdisks.domElement);
- row.append(disks);
-
- */
-
- this.domElement = row[0];
-
- /*var host = $('<td>');
- var hostName = $('<div>');
- var hostLink = $('<a>', {
- 'href': this.getViewerUrl(),
- 'target': '_blank',
- 'data-original-title': this.Address
- });
- hostLink.html(this.getHostName());
- var hostRoles = $('<span>', {class: 'node_roles'});
- hostName.append(hostLink);
- hostName.append(hostRoles);
- hostLink.tooltip({html: true});
- host.append(hostName);
- var state = $('<div>', {class: 'statecontainer'});
- var loadAverage = $('<div>', {
- 'class': 'usageblock progress',
- 'data-original-title': 'Load average'
- });
- var loadAverageBar = $('<div>', {
- class: 'progress-bar',
- role: 'progressbar'
- });
- loadAverage.append(loadAverageBar);
- loadAverage.tooltip({html: true});
- state.append(loadAverage);
- host.append(state);
- row.append(host);
- var uptime = $('<td>', {class: 'uptime_place'});
- row.append(uptime);
- var cpu = $('<td>', {class: 'cpu_place'});
- row.append(cpu);
- var interconnect = $('<td>', {class: 'interconnect_place'});
- row.append(interconnect);
- var disks = $('<td>', {class: 'disk_place'});
- row.append(disks);
- this.domElement = row[0];
- this.domElementNodeIcons = nodeIcons[0];
- this.domElementHostLink = hostLink[0];
- this.domElementUpTime = uptime[0];
- this.domElementRoles = hostRoles[0];
- this.domElementLoadAverageBar = loadAverageBar[0];*/
-}
-
-Storage.prototype.imageManGreen = $('<img src="man-green.png" style="height:26px" data-original-title="<500ms">');
-Storage.prototype.imageManYellow = $('<img src="man-yellow.png" style="height:30px" data-original-title="500ms - 1000ms">');
-Storage.prototype.imageManOrange = $('<img src="man-orange.png" style="height:28px" data-original-title="1000ms - 2000ms">');
-Storage.prototype.imageManRed = $('<img src="man-red.png" style="height:28px" data-original-title=">2000ms">');
-Storage.prototype.spanNone = $('<span>-</span>');
-
-Storage.prototype.getImageFromLatency = function() {
- /*switch (Math.floor(Math.random()*4)) {
- case 0:
- return this.imageManGreen.clone().tooltip();
- case 1:
- return this.imageManYellow.clone().tooltip();
- case 2:
- return this.imageManOrange.clone().tooltip();
- case 3:
- return this.imageManRed.clone().tooltip();
- }*/
- switch (this.Latency) {
- case 'Green':
- return this.imageManGreen.clone().tooltip();
- case 'Yellow':
- return this.imageManYellow.clone().tooltip();
- case 'Orange':
- return this.imageManOrange.clone().tooltip();
- case 'Red':
- return this.imageManRed.clone().tooltip();
- }
- return this.spanNone.clone();
-}
-
-Storage.prototype.appear = function() {
- if (!this.visible) {
- var row = $(this.domElement);
-
- row.append($('<td>', {class: 'storage_erasure', text: this.ErasureSpecies}));
- row.append(this.storageUnits = $('<td>', {class: 'storage_units'}));
- row.append(this.allocatedSize = $('<td>'));
- row.append(this.availableSize = $('<td>'));
- row.append(this.readSpeed = $('<td>'));
- row.append(this.writeSpeed = $('<td>'));
-
- var pDiskOptions = {
- onShowPDiskToolTip: function(pDisk) {
- if (this.enableEvents) {
- var vDisk = this.vDisksByPDisks[pDisk.Id];
- if (vDisk) {
- this.enableEvents = false;
- $(vDisk.domElement).tooltip('show');
- this.enableEvents = true;
- }
- }
- }.bind(this),
- onHidePDiskToolTip: function(pDisk) {
- if (this.enableEvents) {
- var vDisk = this.vDisksByPDisks[pDisk.Id];
- if (vDisk) {
- this.enableEvents = false;
- $(vDisk.domElement).tooltip('hide');
- this.enableEvents = true;
- }
- }
- }.bind(this),
- sort: function() {}
- };
-
- var vDiskOptions = {
- onShowVDiskToolTip: function(vDisk) {
- if (this.enableEvents) {
- var pDisk = this.pDisksByVDisks[vDisk.Id];
- if (pDisk) {
- this.enableEvents = false;
- $(pDisk.domElement).tooltip('show');
- this.enableEvents = true;
- }
- }
- }.bind(this),
- onHideVDiskToolTip: function(vDisk) {
- if (this.enableEvents) {
- var pDisk = this.pDisksByVDisks[vDisk.Id];
- if (pDisk) {
- this.enableEvents = false;
- $(pDisk.domElement).tooltip('hide');
- this.enableEvents = true;
- }
- }
- }.bind(this),
- sort: function() {}
- };
-
- this.enableEvents = true;
-
- this.vDiskMap = new DiskMap(vDiskOptions);
- this.pDiskMap = new DiskMap(pDiskOptions);
-
- this.vDisksByPDisks = {};
- this.pDisksByVDisks = {};
-
- row.append(this.storageLatency = $('<td>', {class: 'storage_latency'}));
-
- var vdisks = $('<td>', {class: 'storage_vdisks'});
- vdisks.append(this.vDiskMap.domElement);
- row.append(vdisks);
-
- var pdisks = $('<td>', {class: 'storage_pdisks'});
- pdisks.append(this.pDiskMap.domElement);
-
- this.update();
-
- row.append(pdisks);
- this.visible = true;
- }
-}
-
-Storage.prototype.disappear = function() {
- if (this.visible) {
- $(this.domElement).find('td').slice(1).remove();
- delete this.vDiskMap;
- delete this.pDiskMap;
- delete this.vDisksByPDisks;
- delete this.pDisksByVDisks;
- this.visible = false;
- }
-}
-
-Storage.prototype.update = function() {
- //var row = $(this.domElement);
- if (this.AcquiredUnits > 0) {
- this.storageUnits.text(this.AcquiredUnits);
- } else {
- this.storageUnits.text('-');
- }
- this.storageLatency.empty().append(this.getImageFromLatency());
-
- var nodes = this.group.view.nodes;
+function Storage(options) {
+ Object.assign(this, {
+ Id: options.GroupID,
+ sysInfo: {},
+ nodeInfo: {},
+ poolMap: null,
+ nodeMap: null,
+ diskMap: null
+ },
+ options);
+ this.buildDomElement();
+}
+
+Storage.prototype.buildDomElement = function() {
+ var row = $('<tr>');
+ row.data('storage', this);
+ var id = $('<span>', {class: 'storage_group_id', text: this.Id});
+ this.storageGroupIdDomElement = id[0];
+ id.tooltip();
+ row.append($('<td>').append(id));
+
+ /*
+
+ row.append($('<td>', {class: 'storage_units', text: this.AcquiredUnits}));
+ row.append($('<td>', {class: 'storage_erasure', text: this.ErasureSpecies}));
+ row.append($('<td>', {class: 'storage_latency', text: this.Latency}));
+
+ var vdisks = new DiskMap(this.Id + '-vdisks');
+ var pdisks = new DiskMap(this.Id + '-pdisks');
+
+ for (var numVDisk in this.VDisks) {
+ var vDisk = this.VDisks[numVDisk];
+ vDisk.CellId = this.Id;
+ vdisks.updateVDiskInfo(vDisk);
+ }
+
+ for (var numPDisk in this.VDisks) {
+ var vDisk = this.VDisks[numPDisk];
+ var pDisk = vDisk.PDisk;
+ if (pDisk) {
+ pdisks.updatePDiskInfo(pDisk);
+ }
+ }
+
+ vdisks.resizeVDisks();
+
+ var disks = $('<td>', {class: 'storage_vdisks'});
+ disks.append(vdisks.domElement);
+ row.append(disks);
+
+ disks = $('<td>', {class: 'storage_pdisks'});
+ disks.append(pdisks.domElement);
+ row.append(disks);
+
+ */
+
+ this.domElement = row[0];
+
+ /*var host = $('<td>');
+ var hostName = $('<div>');
+ var hostLink = $('<a>', {
+ 'href': this.getViewerUrl(),
+ 'target': '_blank',
+ 'data-original-title': this.Address
+ });
+ hostLink.html(this.getHostName());
+ var hostRoles = $('<span>', {class: 'node_roles'});
+ hostName.append(hostLink);
+ hostName.append(hostRoles);
+ hostLink.tooltip({html: true});
+ host.append(hostName);
+ var state = $('<div>', {class: 'statecontainer'});
+ var loadAverage = $('<div>', {
+ 'class': 'usageblock progress',
+ 'data-original-title': 'Load average'
+ });
+ var loadAverageBar = $('<div>', {
+ class: 'progress-bar',
+ role: 'progressbar'
+ });
+ loadAverage.append(loadAverageBar);
+ loadAverage.tooltip({html: true});
+ state.append(loadAverage);
+ host.append(state);
+ row.append(host);
+ var uptime = $('<td>', {class: 'uptime_place'});
+ row.append(uptime);
+ var cpu = $('<td>', {class: 'cpu_place'});
+ row.append(cpu);
+ var interconnect = $('<td>', {class: 'interconnect_place'});
+ row.append(interconnect);
+ var disks = $('<td>', {class: 'disk_place'});
+ row.append(disks);
+ this.domElement = row[0];
+ this.domElementNodeIcons = nodeIcons[0];
+ this.domElementHostLink = hostLink[0];
+ this.domElementUpTime = uptime[0];
+ this.domElementRoles = hostRoles[0];
+ this.domElementLoadAverageBar = loadAverageBar[0];*/
+}
+
+Storage.prototype.imageManGreen = $('<img src="man-green.png" style="height:26px" data-original-title="<500ms">');
+Storage.prototype.imageManYellow = $('<img src="man-yellow.png" style="height:30px" data-original-title="500ms - 1000ms">');
+Storage.prototype.imageManOrange = $('<img src="man-orange.png" style="height:28px" data-original-title="1000ms - 2000ms">');
+Storage.prototype.imageManRed = $('<img src="man-red.png" style="height:28px" data-original-title=">2000ms">');
+Storage.prototype.spanNone = $('<span>-</span>');
+
+Storage.prototype.getImageFromLatency = function() {
+ /*switch (Math.floor(Math.random()*4)) {
+ case 0:
+ return this.imageManGreen.clone().tooltip();
+ case 1:
+ return this.imageManYellow.clone().tooltip();
+ case 2:
+ return this.imageManOrange.clone().tooltip();
+ case 3:
+ return this.imageManRed.clone().tooltip();
+ }*/
+ switch (this.Latency) {
+ case 'Green':
+ return this.imageManGreen.clone().tooltip();
+ case 'Yellow':
+ return this.imageManYellow.clone().tooltip();
+ case 'Orange':
+ return this.imageManOrange.clone().tooltip();
+ case 'Red':
+ return this.imageManRed.clone().tooltip();
+ }
+ return this.spanNone.clone();
+}
+
+Storage.prototype.appear = function() {
+ if (!this.visible) {
+ var row = $(this.domElement);
+
+ row.append($('<td>', {class: 'storage_erasure', text: this.ErasureSpecies}));
+ row.append(this.storageUnits = $('<td>', {class: 'storage_units'}));
+ row.append(this.allocatedSize = $('<td>'));
+ row.append(this.availableSize = $('<td>'));
+ row.append(this.readSpeed = $('<td>'));
+ row.append(this.writeSpeed = $('<td>'));
+
+ var pDiskOptions = {
+ onShowPDiskToolTip: function(pDisk) {
+ if (this.enableEvents) {
+ var vDisk = this.vDisksByPDisks[pDisk.Id];
+ if (vDisk) {
+ this.enableEvents = false;
+ $(vDisk.domElement).tooltip('show');
+ this.enableEvents = true;
+ }
+ }
+ }.bind(this),
+ onHidePDiskToolTip: function(pDisk) {
+ if (this.enableEvents) {
+ var vDisk = this.vDisksByPDisks[pDisk.Id];
+ if (vDisk) {
+ this.enableEvents = false;
+ $(vDisk.domElement).tooltip('hide');
+ this.enableEvents = true;
+ }
+ }
+ }.bind(this),
+ sort: function() {}
+ };
+
+ var vDiskOptions = {
+ onShowVDiskToolTip: function(vDisk) {
+ if (this.enableEvents) {
+ var pDisk = this.pDisksByVDisks[vDisk.Id];
+ if (pDisk) {
+ this.enableEvents = false;
+ $(pDisk.domElement).tooltip('show');
+ this.enableEvents = true;
+ }
+ }
+ }.bind(this),
+ onHideVDiskToolTip: function(vDisk) {
+ if (this.enableEvents) {
+ var pDisk = this.pDisksByVDisks[vDisk.Id];
+ if (pDisk) {
+ this.enableEvents = false;
+ $(pDisk.domElement).tooltip('hide');
+ this.enableEvents = true;
+ }
+ }
+ }.bind(this),
+ sort: function() {}
+ };
+
+ this.enableEvents = true;
+
+ this.vDiskMap = new DiskMap(vDiskOptions);
+ this.pDiskMap = new DiskMap(pDiskOptions);
+
+ this.vDisksByPDisks = {};
+ this.pDisksByVDisks = {};
+
+ row.append(this.storageLatency = $('<td>', {class: 'storage_latency'}));
+
+ var vdisks = $('<td>', {class: 'storage_vdisks'});
+ vdisks.append(this.vDiskMap.domElement);
+ row.append(vdisks);
+
+ var pdisks = $('<td>', {class: 'storage_pdisks'});
+ pdisks.append(this.pDiskMap.domElement);
+
+ this.update();
+
+ row.append(pdisks);
+ this.visible = true;
+ }
+}
+
+Storage.prototype.disappear = function() {
+ if (this.visible) {
+ $(this.domElement).find('td').slice(1).remove();
+ delete this.vDiskMap;
+ delete this.pDiskMap;
+ delete this.vDisksByPDisks;
+ delete this.pDisksByVDisks;
+ this.visible = false;
+ }
+}
+
+Storage.prototype.update = function() {
+ //var row = $(this.domElement);
+ if (this.AcquiredUnits > 0) {
+ this.storageUnits.text(this.AcquiredUnits);
+ } else {
+ this.storageUnits.text('-');
+ }
+ this.storageLatency.empty().append(this.getImageFromLatency());
+
+ var nodes = this.group.view.nodes;
var allocatedSize;
var availableSize;
- var readSpeed = 0;
- var writeSpeed = 0;
-
- for (var numDisk in this.VDisks) {
- var vDisk = this.VDisks[numDisk];
- var pDisk = vDisk.PDisk;
- vDisk.CellId = this.Id;
- vDisk.StoragePoolName = this.StoragePool.Name;
- vDisk = this.vDiskMap.updateVDiskInfo(vDisk);
+ var readSpeed = 0;
+ var writeSpeed = 0;
+
+ for (var numDisk in this.VDisks) {
+ var vDisk = this.VDisks[numDisk];
+ var pDisk = vDisk.PDisk;
+ vDisk.CellId = this.Id;
+ vDisk.StoragePoolName = this.StoragePool.Name;
+ vDisk = this.vDiskMap.updateVDiskInfo(vDisk);
if (vDisk.AllocatedSize !== undefined) {
if (allocatedSize === undefined) {
allocatedSize = 0;
}
- allocatedSize += vDisk.AllocatedSize;
- }
+ allocatedSize += vDisk.AllocatedSize;
+ }
if (vDisk.AvailableSize !== undefined) {
if (availableSize === undefined) {
availableSize = 0;
}
availableSize += vDisk.AvailableSize;
}
- if (vDisk.ReadThroughput) {
- readSpeed += vDisk.ReadThroughput;
- }
- if (vDisk.WriteThroughput) {
- writeSpeed += vDisk.WriteThroughput;
- }
-
- if (!pDisk) {
- pDisk = {NodeId: '?', PDiskId: '?', Id: 'unknown-' + numDisk};
- }
- var node = nodes[pDisk.NodeId];
- if (node) {
- pDisk.Host = node.Host;
- }
- pDisk = this.pDiskMap.updatePDiskInfo(pDisk);
- this.vDisksByPDisks[pDisk.Id] = vDisk;
- this.pDisksByVDisks[vDisk.Id] = pDisk;
- }
-
- this.vDiskMap.resizeVDisks();
-
+ if (vDisk.ReadThroughput) {
+ readSpeed += vDisk.ReadThroughput;
+ }
+ if (vDisk.WriteThroughput) {
+ writeSpeed += vDisk.WriteThroughput;
+ }
+
+ if (!pDisk) {
+ pDisk = {NodeId: '?', PDiskId: '?', Id: 'unknown-' + numDisk};
+ }
+ var node = nodes[pDisk.NodeId];
+ if (node) {
+ pDisk.Host = node.Host;
+ }
+ pDisk = this.pDiskMap.updatePDiskInfo(pDisk);
+ this.vDisksByPDisks[pDisk.Id] = vDisk;
+ this.pDisksByVDisks[vDisk.Id] = pDisk;
+ }
+
+ this.vDiskMap.resizeVDisks();
+
if (allocatedSize === undefined) {
this.allocatedSize.text('-');
} else {
- this.allocatedSize.text(bytesToGB(allocatedSize));
+ this.allocatedSize.text(bytesToGB(allocatedSize));
}
if (availableSize === undefined) {
this.availableSize.text('-');
- } else {
- this.availableSize.text(bytesToGB(availableSize));
- }
- if (readSpeed) {
- this.readSpeed.text(bytesToSpeed(readSpeed));
- } else {
- this.readSpeed.text('-');
- }
- if (writeSpeed) {
- this.writeSpeed.text(bytesToSpeed(writeSpeed));
- } else {
- this.writeSpeed.text('-');
- }
-}
-
+ } else {
+ this.availableSize.text(bytesToGB(availableSize));
+ }
+ if (readSpeed) {
+ this.readSpeed.text(bytesToSpeed(readSpeed));
+ } else {
+ this.readSpeed.text('-');
+ }
+ if (writeSpeed) {
+ this.writeSpeed.text(bytesToSpeed(writeSpeed));
+ } else {
+ this.writeSpeed.text('-');
+ }
+}
+
function isVDiskInErrorState(state) {
if (!state) {
return false;
@@ -314,57 +314,57 @@ function isVDiskInErrorState(state) {
}
}
-Storage.prototype.updateFromStorage = function(update) {
- if (this.GroupGeneration < update.GroupGeneration && this.visible) {
- this.disappear();
- this.VDisks = [];
- this.appear();
- }
- var storage = updateObject(this, update);
- $(this.storageGroupIdDomElement).attr('data-original-title', storage.StoragePool.Name);
- switch (this.Overall) {
- case 'Green':
- this.color = green;
- break;
- case 'Blue':
- this.color = blue;
- break;
- case 'Yellow':
- this.color = yellow;
- //console.log(this);
- break;
- case 'Orange':
- this.color = orange;
- //console.log(this);
- break;
- case 'Red':
- this.color = red;
- //console.log(this);
- break;
- }
- var usage = 0;
- var missingDisks = 0;
- for (var numDisk in this.VDisks) {
- var vDisk = this.VDisks[numDisk];
- if (vDisk) {
- if (vDisk.AllocatedSize) {
- vDisk.AllocatedSize = Number(vDisk.AllocatedSize);
- }
+Storage.prototype.updateFromStorage = function(update) {
+ if (this.GroupGeneration < update.GroupGeneration && this.visible) {
+ this.disappear();
+ this.VDisks = [];
+ this.appear();
+ }
+ var storage = updateObject(this, update);
+ $(this.storageGroupIdDomElement).attr('data-original-title', storage.StoragePool.Name);
+ switch (this.Overall) {
+ case 'Green':
+ this.color = green;
+ break;
+ case 'Blue':
+ this.color = blue;
+ break;
+ case 'Yellow':
+ this.color = yellow;
+ //console.log(this);
+ break;
+ case 'Orange':
+ this.color = orange;
+ //console.log(this);
+ break;
+ case 'Red':
+ this.color = red;
+ //console.log(this);
+ break;
+ }
+ var usage = 0;
+ var missingDisks = 0;
+ for (var numDisk in this.VDisks) {
+ var vDisk = this.VDisks[numDisk];
+ if (vDisk) {
+ if (vDisk.AllocatedSize) {
+ vDisk.AllocatedSize = Number(vDisk.AllocatedSize);
+ }
if (vDisk.AvailableSize) {
vDisk.AvailableSize = Number(vDisk.AvailableSize);
}
// meaingful only if hard disk space division is enabled
//usage = Math.max(usage, vDisk.AllocatedSize / (vDisk.AllocatedSize + vDisk.AvailableSize));
- if (vDisk.ReadThroughput) {
- vDisk.ReadThroughput = Number(vDisk.ReadThroughput);
- }
- if (vDisk.WriteThroughput) {
- vDisk.WriteThroughput = Number(vDisk.WriteThroughput);
- }
- }
-
- var pDisk = vDisk.PDisk;
- if (pDisk) {
+ if (vDisk.ReadThroughput) {
+ vDisk.ReadThroughput = Number(vDisk.ReadThroughput);
+ }
+ if (vDisk.WriteThroughput) {
+ vDisk.WriteThroughput = Number(vDisk.WriteThroughput);
+ }
+ }
+
+ var pDisk = vDisk.PDisk;
+ if (pDisk) {
if (pDisk.TotalSize) {
pDisk.TotalSize = Number(pDisk.TotalSize);
}
@@ -375,56 +375,56 @@ Storage.prototype.updateFromStorage = function(update) {
if (pDisk && pDisk.AvailableSize && pDisk.TotalSize) {
usage = Math.max(usage, 1 - pDisk.AvailableSize / pDisk.TotalSize);
if (!pDisk.State || (vDisk.Replicated === false && !vDisk.DonorMode) || isVDiskInErrorState(vDisk.VDiskState) === true) {
- missingDisks++;
- }
- } else {
- missingDisks++;
- }
- }
- this.usage = usage;
- this.missingDisks = missingDisks;
- if (this.visible) {
- this.update();
- }
-}
-
-Storage.prototype.getColor = function() {
- switch (this.color) {
- case grey:
- return "Grey";
- case green:
- return "Green";
- case blue:
- return "Blue";
- case yellow:
- return "Yellow";
- case orange:
- return "Orange";
- case red:
- return "Red";
- }
-}
-
-Storage.prototype.getTooltipText = function() {
- var text = '#' + this.Id;
- return text;
-}
-
-Storage.prototype.getStatus = function() {
- if (this.color) {
- if (this.color === green) {
- return 'Good';
- } else {
- return 'Bad';
- }
- }
- return 'Unknown';
-}
-
-Storage.prototype.getUsage = function() {
- return this.usage;
-}
-
-Storage.prototype.getMissingDisks = function() {
- return this.missingDisks;
-}
+ missingDisks++;
+ }
+ } else {
+ missingDisks++;
+ }
+ }
+ this.usage = usage;
+ this.missingDisks = missingDisks;
+ if (this.visible) {
+ this.update();
+ }
+}
+
+Storage.prototype.getColor = function() {
+ switch (this.color) {
+ case grey:
+ return "Grey";
+ case green:
+ return "Green";
+ case blue:
+ return "Blue";
+ case yellow:
+ return "Yellow";
+ case orange:
+ return "Orange";
+ case red:
+ return "Red";
+ }
+}
+
+Storage.prototype.getTooltipText = function() {
+ var text = '#' + this.Id;
+ return text;
+}
+
+Storage.prototype.getStatus = function() {
+ if (this.color) {
+ if (this.color === green) {
+ return 'Good';
+ } else {
+ return 'Bad';
+ }
+ }
+ return 'Unknown';
+}
+
+Storage.prototype.getUsage = function() {
+ return this.usage;
+}
+
+Storage.prototype.getMissingDisks = function() {
+ return this.missingDisks;
+}
diff --git a/ydb/core/viewer/content/v2/storage_group.js b/ydb/core/viewer/content/v2/storage_group.js
index ee90c9b1c1d..345e959bd2d 100644
--- a/ydb/core/viewer/content/v2/storage_group.js
+++ b/ydb/core/viewer/content/v2/storage_group.js
@@ -1,244 +1,244 @@
-function StorageGroup(options) {
- Object.assign(this, options);
- this.storage = {};
- this.storageState = {};
- this.storageTotal = 0;
- this.storageGood = 0;
- this.storageAllocatedBytes = 0;
- this.buildDomElement();
- this.nodeMap = null;
-}
-
-StorageGroup.prototype.disableDoubleClick = function(e) {
- if (e.detail > 1) {
- e.preventDefault();
- }
-}
-
-StorageGroup.prototype.buildDomElement = function() {
- var storageBlock = $('<div>', {class: 'storage_group_block'});
- var StorageGroupHeader = $('<div>', {class: 'storage_group_header'});
- var StorageGroupName = $('<div>', {class: 'storage_group_header_name'});
- var StorageGroupInfo = $('<div>', {class: 'storage_group_header_info'});
- var StorageGroupNodes = $('<div>', {class: 'storage_group_header_nodes'});
- StorageGroupName.html(this.name);
- StorageGroupHeader.mousedown(this.disableDoubleClick.bind(this));
- StorageGroupHeader.click(this.toggleContainer.bind(this));
- StorageGroupInfo.html("<img src='throbber.gif'></img>");
- StorageGroupHeader.append(StorageGroupName);
- StorageGroupHeader.append(StorageGroupNodes);
- StorageGroupHeader.append(StorageGroupInfo);
- storageBlock.append(StorageGroupHeader);
- var StorageGroupContainer = $('<table>', {class: 'storagelist storage_group_container'});
- var StorageGroupHead = $('<thead>');
- var StorageGroupRow = $('<tr>');
- StorageGroupRow.append('<th>Group Id</th>');
- StorageGroupRow.append('<th>Erasure</th>');
- StorageGroupRow.append('<th>Units</th>');
- StorageGroupRow.append('<th>Allocated</th>');
- StorageGroupRow.append('<th>Available</th>');
- StorageGroupRow.append('<th>Read</th>');
- StorageGroupRow.append('<th>Write</th>');
- StorageGroupRow.append('<th>Latency</th>');
- StorageGroupRow.append('<th>VDisks</th>');
- StorageGroupRow.append('<th>PDisks</th>');
- StorageGroupHead.append(StorageGroupRow);
- var StorageGroupBody = $('<tbody>');
- StorageGroupContainer.append(StorageGroupHead);
- StorageGroupContainer.append(StorageGroupBody);
- storageBlock.append(StorageGroupContainer);
- this.domElement = storageBlock[0];
- this.domElementGroupHeader = StorageGroupHeader[0];
- this.domElementGroupHeaderNodes = StorageGroupNodes[0];
- this.domElementGroupInfo = StorageGroupInfo[0];
- this.domElementGroupContainer = StorageGroupContainer[0];
- this.domElementGroupContainerBody = StorageGroupBody[0];
- this.domElementGroupContainer.style.display = 'none';
- storageBlock.data('group', this);
-}
-
-StorageGroup.prototype.toggleContainer = function() {
- var domElement = this.domElementGroupContainer;
- if (domElement.style.display === 'none') {
- domElement.style.display = 'table';
- $(this.domElementGroupHeader).addClass('storage_group_header_pressed');
- this.pressed = true;
- } else {
- $(this.domElementGroupHeader).removeClass('storage_group_header_pressed');
- domElement.style.display = 'none';
- this.pressed = false;
- if (this.isEmpty()) {
- this.view.removeGroup(this);
- }
- }
-}
-
-StorageGroup.prototype.isEmpty = function() {
- return this.storageTotal === 0;
-}
-
-StorageGroup.prototype.addStorage = function(storage) {
- if (storage.group !== undefined) {
- storage.group.removeStorage(storage);
- }
-
- var point = this.domElementGroupContainerBody.lastChild;
- if (point === null || $(point).data('storage').Id < storage.Id) {
- this.domElementGroupContainerBody.appendChild(storage.domElement);
- } else {
- for(;;) {
- var prev = point.previousSibling;
- if (prev === null) {
- break;
- }
- if ($(prev).data('storage').Id < storage.Id) {
- break;
- }
- point = prev;
- }
- this.domElementGroupContainerBody.insertBefore(storage.domElement, point);
- }
-
- storage.group = this;
- this.storage[storage.Id] = storage;
- ++this.storageTotal;
-}
-
-StorageGroup.prototype.removeStorage = function(storage) {
- this.domElementGroupContainerBody.removeChild(storage.domElement);
- var color = storage.color;
- if (color === green) {
- --this.storageGood;
- }
- delete storage.group;
- delete this.storageState[storage.groupPosition];
- delete storage.groupPosition;
- delete this.storage[storage.Id];
- --this.storageTotal;
-}
-
-StorageGroup.prototype.updateStorageStateMap = function(storage) {
- var color = storage.color;
- var position = storage.groupPosition;
- if (position !== undefined) {
- var prevColor = this.storageState[position];
- if (prevColor !== color) {
- this.storageState[position] = color;
- this.nodeMap.setNodeMap(position, color, storage.getTooltipText());
- var s = storage.domElement;
- switch (color) {
- case red:
- s.style.backgroundColor = '#ffe0e0';//red;
- break;
- case orange:
- s.style.backgroundColor = '#ffe0d0';//orange;
- break;
- case yellow:
- s.style.backgroundColor = '#ffffe0';//yellow;
- break;
- case blue:
- s.style.backgroundColor = '#e0f0ff';//blue;
- break;
- case green:
- case grey:
- s.style.backgroundColor = null;
- break;
- }
- var updateInfo = false;
- if (prevColor === undefined || prevColor === grey) {
- if (color === green) {
- this.storageGood++;
- }
- updateInfo = true;
- } else {
- if (color !== prevColor) {
- if (color === green) {
- this.storageGood++;
- } else if (prevColor === green) {
- this.storageGood--;
- }
- updateInfo = true;
- }
- }
- return true;
- }
- }
- return false;
-}
-
-StorageGroup.prototype.updateStorageStateInfo = function() {
- this.domElementGroupInfo.innerHTML = this.view.getStorageGroupHeader(this);
-}
-
-StorageGroup.prototype.updateStorageState = function(storage) {
- var updateInfo = this.updateStorageStateMap(storage);
- if (updateInfo) {
- this.updateStorageStateInfo();
- }
-}
-
-StorageGroup.prototype.updateHeader = function(checkAlive) {
- var StorageGroupBlock = $(this.domElement);
- var StorageGroupHeaderNodes = $(this.domElementGroupHeaderNodes);
- var items = 0;
- var StorageGroupContainer = $(this.domElementGroupContainerBody).children().each(function () {
- var storage = $(this).data('storage');
- if (storage !== undefined) {
- storage.groupPosition = items;
- ++items;
- }
- });
- if (this.nodeMap === null || this.nodeMap.nodes !== items) {
- var size = 5;
- if (items <= 16) {
- size = 20;
- } else if (items <= 72) {
- size = 10;
- }
- var height = 22;
- if (items > 512) {
- if (items > 1000) {
- size = 3;
- }
- height += Math.floor((items - 512) / 512) * size;
- }
- this.storageState = {};
- StorageGroupHeaderNodes.empty();
- if (items > 0) {
- this.nodeMap = new NodeMap({nodes: items, height: height, placeSize: size, class: 'node_map'});
- StorageGroupHeaderNodes.append(this.nodeMap.domElement);
- } else {
- this.nodeMap = null;
- }
- }
-
- //this.storageGood = 0;
-
- this.allocatedSizeBytes = 0;
-
- for (var storageId in this.storage) {
- var storage = this.storage[storageId];
- if (storage) {
- this.updateStorageStateMap(storage);
- this.allocatedSizeBytes += storage.allocatedSizeBytes;
- }
- }
-
- this.updateStorageStateInfo();
-
-
- /*if (checkAlive) {
- this.nodesGood = 0;
- this.nodeState = {};
- for (var nodeId in this.nodes) {
- var node = this.nodes[nodeId];
- if (node !== undefined) {
- if (node.sysInfo && node.sysInfo.SystemState) {
- this.updateNodeStateMap(node);
- }
- }
- }
- this.updateNodeStateInfo();
- }*/
-}
-
+function StorageGroup(options) {
+ Object.assign(this, options);
+ this.storage = {};
+ this.storageState = {};
+ this.storageTotal = 0;
+ this.storageGood = 0;
+ this.storageAllocatedBytes = 0;
+ this.buildDomElement();
+ this.nodeMap = null;
+}
+
+StorageGroup.prototype.disableDoubleClick = function(e) {
+ if (e.detail > 1) {
+ e.preventDefault();
+ }
+}
+
+StorageGroup.prototype.buildDomElement = function() {
+ var storageBlock = $('<div>', {class: 'storage_group_block'});
+ var StorageGroupHeader = $('<div>', {class: 'storage_group_header'});
+ var StorageGroupName = $('<div>', {class: 'storage_group_header_name'});
+ var StorageGroupInfo = $('<div>', {class: 'storage_group_header_info'});
+ var StorageGroupNodes = $('<div>', {class: 'storage_group_header_nodes'});
+ StorageGroupName.html(this.name);
+ StorageGroupHeader.mousedown(this.disableDoubleClick.bind(this));
+ StorageGroupHeader.click(this.toggleContainer.bind(this));
+ StorageGroupInfo.html("<img src='throbber.gif'></img>");
+ StorageGroupHeader.append(StorageGroupName);
+ StorageGroupHeader.append(StorageGroupNodes);
+ StorageGroupHeader.append(StorageGroupInfo);
+ storageBlock.append(StorageGroupHeader);
+ var StorageGroupContainer = $('<table>', {class: 'storagelist storage_group_container'});
+ var StorageGroupHead = $('<thead>');
+ var StorageGroupRow = $('<tr>');
+ StorageGroupRow.append('<th>Group Id</th>');
+ StorageGroupRow.append('<th>Erasure</th>');
+ StorageGroupRow.append('<th>Units</th>');
+ StorageGroupRow.append('<th>Allocated</th>');
+ StorageGroupRow.append('<th>Available</th>');
+ StorageGroupRow.append('<th>Read</th>');
+ StorageGroupRow.append('<th>Write</th>');
+ StorageGroupRow.append('<th>Latency</th>');
+ StorageGroupRow.append('<th>VDisks</th>');
+ StorageGroupRow.append('<th>PDisks</th>');
+ StorageGroupHead.append(StorageGroupRow);
+ var StorageGroupBody = $('<tbody>');
+ StorageGroupContainer.append(StorageGroupHead);
+ StorageGroupContainer.append(StorageGroupBody);
+ storageBlock.append(StorageGroupContainer);
+ this.domElement = storageBlock[0];
+ this.domElementGroupHeader = StorageGroupHeader[0];
+ this.domElementGroupHeaderNodes = StorageGroupNodes[0];
+ this.domElementGroupInfo = StorageGroupInfo[0];
+ this.domElementGroupContainer = StorageGroupContainer[0];
+ this.domElementGroupContainerBody = StorageGroupBody[0];
+ this.domElementGroupContainer.style.display = 'none';
+ storageBlock.data('group', this);
+}
+
+StorageGroup.prototype.toggleContainer = function() {
+ var domElement = this.domElementGroupContainer;
+ if (domElement.style.display === 'none') {
+ domElement.style.display = 'table';
+ $(this.domElementGroupHeader).addClass('storage_group_header_pressed');
+ this.pressed = true;
+ } else {
+ $(this.domElementGroupHeader).removeClass('storage_group_header_pressed');
+ domElement.style.display = 'none';
+ this.pressed = false;
+ if (this.isEmpty()) {
+ this.view.removeGroup(this);
+ }
+ }
+}
+
+StorageGroup.prototype.isEmpty = function() {
+ return this.storageTotal === 0;
+}
+
+StorageGroup.prototype.addStorage = function(storage) {
+ if (storage.group !== undefined) {
+ storage.group.removeStorage(storage);
+ }
+
+ var point = this.domElementGroupContainerBody.lastChild;
+ if (point === null || $(point).data('storage').Id < storage.Id) {
+ this.domElementGroupContainerBody.appendChild(storage.domElement);
+ } else {
+ for(;;) {
+ var prev = point.previousSibling;
+ if (prev === null) {
+ break;
+ }
+ if ($(prev).data('storage').Id < storage.Id) {
+ break;
+ }
+ point = prev;
+ }
+ this.domElementGroupContainerBody.insertBefore(storage.domElement, point);
+ }
+
+ storage.group = this;
+ this.storage[storage.Id] = storage;
+ ++this.storageTotal;
+}
+
+StorageGroup.prototype.removeStorage = function(storage) {
+ this.domElementGroupContainerBody.removeChild(storage.domElement);
+ var color = storage.color;
+ if (color === green) {
+ --this.storageGood;
+ }
+ delete storage.group;
+ delete this.storageState[storage.groupPosition];
+ delete storage.groupPosition;
+ delete this.storage[storage.Id];
+ --this.storageTotal;
+}
+
+StorageGroup.prototype.updateStorageStateMap = function(storage) {
+ var color = storage.color;
+ var position = storage.groupPosition;
+ if (position !== undefined) {
+ var prevColor = this.storageState[position];
+ if (prevColor !== color) {
+ this.storageState[position] = color;
+ this.nodeMap.setNodeMap(position, color, storage.getTooltipText());
+ var s = storage.domElement;
+ switch (color) {
+ case red:
+ s.style.backgroundColor = '#ffe0e0';//red;
+ break;
+ case orange:
+ s.style.backgroundColor = '#ffe0d0';//orange;
+ break;
+ case yellow:
+ s.style.backgroundColor = '#ffffe0';//yellow;
+ break;
+ case blue:
+ s.style.backgroundColor = '#e0f0ff';//blue;
+ break;
+ case green:
+ case grey:
+ s.style.backgroundColor = null;
+ break;
+ }
+ var updateInfo = false;
+ if (prevColor === undefined || prevColor === grey) {
+ if (color === green) {
+ this.storageGood++;
+ }
+ updateInfo = true;
+ } else {
+ if (color !== prevColor) {
+ if (color === green) {
+ this.storageGood++;
+ } else if (prevColor === green) {
+ this.storageGood--;
+ }
+ updateInfo = true;
+ }
+ }
+ return true;
+ }
+ }
+ return false;
+}
+
+StorageGroup.prototype.updateStorageStateInfo = function() {
+ this.domElementGroupInfo.innerHTML = this.view.getStorageGroupHeader(this);
+}
+
+StorageGroup.prototype.updateStorageState = function(storage) {
+ var updateInfo = this.updateStorageStateMap(storage);
+ if (updateInfo) {
+ this.updateStorageStateInfo();
+ }
+}
+
+StorageGroup.prototype.updateHeader = function(checkAlive) {
+ var StorageGroupBlock = $(this.domElement);
+ var StorageGroupHeaderNodes = $(this.domElementGroupHeaderNodes);
+ var items = 0;
+ var StorageGroupContainer = $(this.domElementGroupContainerBody).children().each(function () {
+ var storage = $(this).data('storage');
+ if (storage !== undefined) {
+ storage.groupPosition = items;
+ ++items;
+ }
+ });
+ if (this.nodeMap === null || this.nodeMap.nodes !== items) {
+ var size = 5;
+ if (items <= 16) {
+ size = 20;
+ } else if (items <= 72) {
+ size = 10;
+ }
+ var height = 22;
+ if (items > 512) {
+ if (items > 1000) {
+ size = 3;
+ }
+ height += Math.floor((items - 512) / 512) * size;
+ }
+ this.storageState = {};
+ StorageGroupHeaderNodes.empty();
+ if (items > 0) {
+ this.nodeMap = new NodeMap({nodes: items, height: height, placeSize: size, class: 'node_map'});
+ StorageGroupHeaderNodes.append(this.nodeMap.domElement);
+ } else {
+ this.nodeMap = null;
+ }
+ }
+
+ //this.storageGood = 0;
+
+ this.allocatedSizeBytes = 0;
+
+ for (var storageId in this.storage) {
+ var storage = this.storage[storageId];
+ if (storage) {
+ this.updateStorageStateMap(storage);
+ this.allocatedSizeBytes += storage.allocatedSizeBytes;
+ }
+ }
+
+ this.updateStorageStateInfo();
+
+
+ /*if (checkAlive) {
+ this.nodesGood = 0;
+ this.nodeState = {};
+ for (var nodeId in this.nodes) {
+ var node = this.nodes[nodeId];
+ if (node !== undefined) {
+ if (node.sysInfo && node.sysInfo.SystemState) {
+ this.updateNodeStateMap(node);
+ }
+ }
+ }
+ this.updateNodeStateInfo();
+ }*/
+}
+
diff --git a/ydb/core/viewer/content/v2/storage_view.js b/ydb/core/viewer/content/v2/storage_view.js
index 3a7e0e2e016..b4fe4b6a458 100644
--- a/ydb/core/viewer/content/v2/storage_view.js
+++ b/ydb/core/viewer/content/v2/storage_view.js
@@ -1,268 +1,268 @@
-function StorageView(options) {
- Object.assign(this, {
- nodes: {},
- groups: {}
- }, options);
- this.storage = {};
- this.storagePools = {};
+function StorageView(options) {
+ Object.assign(this, {
+ nodes: {},
+ groups: {}
+ }, options);
+ this.storage = {};
+ this.storagePools = {};
this.observer = new IntersectionObserver(this.onVisibilityChange.bind(this), {rootMargin: '50%'});
- this.getStorageGroupName = function(storage) { return storage.StoragePool.Name; }
- this.getStorageGroupHeader = function(storageGroup) { return bytesToGB0(storageGroup.allocatedSizeBytes) + ' / ' + storageGroup.storageTotal + ' groups'; }
- this.groupOrder = function(prev, next) { return prev < next; }
-
- DiskCell.prototype.maxWideVDisks = 99;
- DiskCell.prototype.maxNormalVDisks = 99;
- DiskCell.prototype.maxNarrowPDisks = 99;
- DiskCell.prototype.maxNormalPDisks = 99;
- DiskCell.prototype.totalWidth = 200;
- DiskCell.prototype.pDiskClass = 'pdisk-extra-narrow';
-
- this.stats = new Stats();
- this.statPools = this.stats.addStat('Pools');
- this.statGroups = this.stats.addStat('Groups');
- this.statVDisks = this.stats.addStat('VDisks');
- this.statPDisks = this.stats.addStat('PDisks');
- this.statTotalSize = this.stats.addStat('Total');
- this.statAllocatedSize = this.stats.addStat('Used');
- $('#stats_placement').append(this.stats.domElement);
- //$(this.stats.domElement).insertBefore(this.domElement);
-}
-
-StorageView.prototype.getStorageGroup = function(name) {
- var group = this.groups[name];
- if (group === undefined) {
- group = this.groups[name] = new StorageGroup({name: name, view: this});
- var point = this.domElement.lastElementChild;
- if (point === null || this.groupOrder($(point).data('group').name, name)) {
- this.domElement.appendChild(group.domElement);
- } else {
- for(;;) {
- var prev = point.previousSibling;
- if (prev === null) {
- break;
- }
- if (this.groupOrder($(prev).data('group').name, name)) {
- break;
- }
- point = prev;
- }
- this.domElement.insertBefore(group.domElement, point);
- }
- }
- return group;
-}
-
-StorageView.prototype.addNode = function(node) {
- this.nodes[node.Id] = node;
-}
-
-StorageView.prototype.removeGroup = function(group) {
- this.domElement.removeChild(group.domElement);
- delete this.groups[group.name];
-}
-
-StorageView.prototype.rebuild = function() {
- for (var i in this.storage) {
- var storage = this.storage[i];
- var groupName = this.getStorageGroupName(storage);
- var group = this.getStorageGroup(groupName);
- group.addStorage(storage);
- }
- this.rebuildGroupHeaders(true);
- //delete this.lastRefreshOverall;
-}
-
-StorageView.prototype.updateGroup = function(storage) {
- var groupName = this.getStorageGroupName(storage);
- if (!storage.group || storage.group.name !== groupName) {
- var newGroup = this.getStorageGroup(groupName);
- var oldGroup = storage.group;
- newGroup.addStorage(storage);
- if (oldGroup) {
- if (oldGroup.isEmpty()) {
- if (oldGroup.pressed) {
- oldGroup.updateHeader(true);
- } else {
- this.removeGroup(oldGroup);
- }
- } else {
- //oldGroup.updateHeader(true);
- }
- oldGroup.updateStorageState(storage);
- }
- //newGroup.updateHeader(true);
- } else {
- storage.group.updateStorageState(storage);
- }
-}
-
-StorageView.prototype.removeFromGroup = function(storage) {
- var oldGroup = storage.group;
- if (oldGroup) {
- oldGroup.removeStorage(storage);
- if (oldGroup.isEmpty()) {
- if (oldGroup.pressed) {
- oldGroup.updateHeader(true);
- } else {
- this.removeGroup(oldGroup);
- }
- } else {
- //oldGroup.updateHeader(true);
- }
- }
-}
-
-StorageView.prototype.onDisconnect = function() {
-// TODO
-}
-
-StorageView.prototype.rebuildGroupHeaders = function(checkAlive) {
- for (var name in this.groups) {
- var group = this.groups[name];
- if (group.isEmpty()) {
- this.removeGroup(group);
- } else {
- group.updateHeader(checkAlive);
- }
- }
-}
-
-var FilterVDisk = null;
-
-StorageView.prototype.onChangeFilter = function() {
- var newFilter = $('#vdisk_filter').val();
- try {
- if (newFilter != '') {
- FilterVDisk = Function('return(function(vdisk){with(vdisk){return (' + newFilter + ');}})');
- } else {
- FilterVDisk = null;
- }
- viewer.manuallyRefreshOverall();
- } catch (error) {
- FilterVDisk = null;
- }
-}
-
-StorageView.prototype.onChangeFilterButton = function() {}
-
-StorageView.prototype.onStorage = function(update) {
-// console.log('StorageView.onStorage()');
- var pools = {};
- var groups = {};
- var vDisks = 0;
- var pPiskSeen = {};
- var pDisks = 0;
- var totalSize = 0;
- var allocatedSize = 0;
- var filterVDisk = null;
- if (FilterVDisk) {
- try {
- filterVDisk = FilterVDisk();
- } catch (error) {
- filterVDisk = null;
- }
- }
- for (var numPool in update.StoragePools) {
- var storagePool = update.StoragePools[numPool];
- if (storagePool.Name) {
- storagePool = this.storagePools[storagePool.Name] = storagePool;
- for (var numGroup in storagePool.Groups) {
- var storageGroup = storagePool.Groups[numGroup];
- if (storageGroup.GroupID !== undefined) {
- var matched = true;
- try {
- if (filterVDisk && storageGroup.VDisks.findIndex(filterVDisk) == -1) {
- matched = false;
- }
- } catch (error) {
- matched = false;
- }
- var storage = this.storage[storageGroup.GroupID];
- if (!matched) {
- if (storage) {
- this.removeFromGroup(storage);
- if (this.observer) {
- this.observer.unobserve(storage.domElement);
- }
- delete this.storage[storageGroup.GroupID];
- }
- continue;
- }
- pools[storagePool.Name] = true;
- groups[storageGroup.GroupID] = true;
- if (!storage) {
- storageGroup.StoragePool = storagePool;
- storage = this.storage[storageGroup.GroupID] = new Storage(storageGroup);
- if (this.observer) {
- this.observer.observe(storage.domElement);
- }
- }
- storage.updateFromStorage(storageGroup);
- var allocatedSizeGroup = 0;
- vDisks += storageGroup.VDisks.length;
- for (var vDiskNum in storageGroup.VDisks) {
- var vDisk = storageGroup.VDisks[vDiskNum];
- if (vDisk && vDisk.AllocatedSize) {
- allocatedSizeGroup += Number(vDisk.AllocatedSize);
- }
-
- var pDisk = vDisk.PDisk;
- if (pDisk) {
- var pDiskId = pDisk.NodeId + '-' + pDisk.PDiskId;
- if (!pPiskSeen[pDiskId]) {
- pPiskSeen[pDiskId] = true;
- pDisks++;
- if (pDisk.TotalSize && pDisk.TotalSize && pDisk.AvailableSize) {
- var ts = Number(pDisk.TotalSize);
- totalSize += ts;
- allocatedSize += ts - Number(pDisk.AvailableSize);
- }
- }
- }
- }
- storage.allocatedSizeBytes = allocatedSizeGroup;
- this.updateGroup(storage);
- }
- }
- }
- }
- this.rebuildGroupHeaders();
- this.statPools.setValue(Object.keys(pools).length);
- this.statGroups.setValue(Object.keys(groups).length);
- this.statVDisks.setValue(vDisks);
- this.statPDisks.setValue(pDisks);
- this.statAllocatedSize.setValue(bytesToGB(allocatedSize));
- this.statTotalSize.setValue(bytesToGB(totalSize));
- if (!this.first) {
- $('#pacman').remove();
- $('#stats_placement').show();
- $('#filter').show();
- $('#vdisk_filter_button').on('click',this.onChangeFilter.bind(this));
- $('#vdisk_filter').on('keyup', function(event) {
- // Number 13 is the "Enter" key on the keyboard
- if (event.keyCode === 13) {
- // Cancel the default action, if needed
- event.preventDefault();
- // Trigger the button element with a click
- this.onChangeFilter();
- }
- }.bind(this)).tooltip({html: true}).attr('data-original-title', 'DiskSpace=="Yellow"<br>!Replicated<br>NodeId==46 && PDisk.PDiskId==1001<br>VDiskId.GroupID==2181038480<br>');
- $('#switches').show();
- this.first = true;
- }
-}
-
-StorageView.prototype.onVisibilityChange = function(entries) {
- var now = getTime();
- for (var idx = 0; idx < entries.length; ++idx) {
- var entry = entries[idx];
- var storage = $(entry.target).data('storage');
- if (entry.isIntersecting) {
- if (!storage.visible) {
- storage.appear();
- }
- } else {
- storage.disappear();
- }
- }
-}
+ this.getStorageGroupName = function(storage) { return storage.StoragePool.Name; }
+ this.getStorageGroupHeader = function(storageGroup) { return bytesToGB0(storageGroup.allocatedSizeBytes) + ' / ' + storageGroup.storageTotal + ' groups'; }
+ this.groupOrder = function(prev, next) { return prev < next; }
+
+ DiskCell.prototype.maxWideVDisks = 99;
+ DiskCell.prototype.maxNormalVDisks = 99;
+ DiskCell.prototype.maxNarrowPDisks = 99;
+ DiskCell.prototype.maxNormalPDisks = 99;
+ DiskCell.prototype.totalWidth = 200;
+ DiskCell.prototype.pDiskClass = 'pdisk-extra-narrow';
+
+ this.stats = new Stats();
+ this.statPools = this.stats.addStat('Pools');
+ this.statGroups = this.stats.addStat('Groups');
+ this.statVDisks = this.stats.addStat('VDisks');
+ this.statPDisks = this.stats.addStat('PDisks');
+ this.statTotalSize = this.stats.addStat('Total');
+ this.statAllocatedSize = this.stats.addStat('Used');
+ $('#stats_placement').append(this.stats.domElement);
+ //$(this.stats.domElement).insertBefore(this.domElement);
+}
+
+StorageView.prototype.getStorageGroup = function(name) {
+ var group = this.groups[name];
+ if (group === undefined) {
+ group = this.groups[name] = new StorageGroup({name: name, view: this});
+ var point = this.domElement.lastElementChild;
+ if (point === null || this.groupOrder($(point).data('group').name, name)) {
+ this.domElement.appendChild(group.domElement);
+ } else {
+ for(;;) {
+ var prev = point.previousSibling;
+ if (prev === null) {
+ break;
+ }
+ if (this.groupOrder($(prev).data('group').name, name)) {
+ break;
+ }
+ point = prev;
+ }
+ this.domElement.insertBefore(group.domElement, point);
+ }
+ }
+ return group;
+}
+
+StorageView.prototype.addNode = function(node) {
+ this.nodes[node.Id] = node;
+}
+
+StorageView.prototype.removeGroup = function(group) {
+ this.domElement.removeChild(group.domElement);
+ delete this.groups[group.name];
+}
+
+StorageView.prototype.rebuild = function() {
+ for (var i in this.storage) {
+ var storage = this.storage[i];
+ var groupName = this.getStorageGroupName(storage);
+ var group = this.getStorageGroup(groupName);
+ group.addStorage(storage);
+ }
+ this.rebuildGroupHeaders(true);
+ //delete this.lastRefreshOverall;
+}
+
+StorageView.prototype.updateGroup = function(storage) {
+ var groupName = this.getStorageGroupName(storage);
+ if (!storage.group || storage.group.name !== groupName) {
+ var newGroup = this.getStorageGroup(groupName);
+ var oldGroup = storage.group;
+ newGroup.addStorage(storage);
+ if (oldGroup) {
+ if (oldGroup.isEmpty()) {
+ if (oldGroup.pressed) {
+ oldGroup.updateHeader(true);
+ } else {
+ this.removeGroup(oldGroup);
+ }
+ } else {
+ //oldGroup.updateHeader(true);
+ }
+ oldGroup.updateStorageState(storage);
+ }
+ //newGroup.updateHeader(true);
+ } else {
+ storage.group.updateStorageState(storage);
+ }
+}
+
+StorageView.prototype.removeFromGroup = function(storage) {
+ var oldGroup = storage.group;
+ if (oldGroup) {
+ oldGroup.removeStorage(storage);
+ if (oldGroup.isEmpty()) {
+ if (oldGroup.pressed) {
+ oldGroup.updateHeader(true);
+ } else {
+ this.removeGroup(oldGroup);
+ }
+ } else {
+ //oldGroup.updateHeader(true);
+ }
+ }
+}
+
+StorageView.prototype.onDisconnect = function() {
+// TODO
+}
+
+StorageView.prototype.rebuildGroupHeaders = function(checkAlive) {
+ for (var name in this.groups) {
+ var group = this.groups[name];
+ if (group.isEmpty()) {
+ this.removeGroup(group);
+ } else {
+ group.updateHeader(checkAlive);
+ }
+ }
+}
+
+var FilterVDisk = null;
+
+StorageView.prototype.onChangeFilter = function() {
+ var newFilter = $('#vdisk_filter').val();
+ try {
+ if (newFilter != '') {
+ FilterVDisk = Function('return(function(vdisk){with(vdisk){return (' + newFilter + ');}})');
+ } else {
+ FilterVDisk = null;
+ }
+ viewer.manuallyRefreshOverall();
+ } catch (error) {
+ FilterVDisk = null;
+ }
+}
+
+StorageView.prototype.onChangeFilterButton = function() {}
+
+StorageView.prototype.onStorage = function(update) {
+// console.log('StorageView.onStorage()');
+ var pools = {};
+ var groups = {};
+ var vDisks = 0;
+ var pPiskSeen = {};
+ var pDisks = 0;
+ var totalSize = 0;
+ var allocatedSize = 0;
+ var filterVDisk = null;
+ if (FilterVDisk) {
+ try {
+ filterVDisk = FilterVDisk();
+ } catch (error) {
+ filterVDisk = null;
+ }
+ }
+ for (var numPool in update.StoragePools) {
+ var storagePool = update.StoragePools[numPool];
+ if (storagePool.Name) {
+ storagePool = this.storagePools[storagePool.Name] = storagePool;
+ for (var numGroup in storagePool.Groups) {
+ var storageGroup = storagePool.Groups[numGroup];
+ if (storageGroup.GroupID !== undefined) {
+ var matched = true;
+ try {
+ if (filterVDisk && storageGroup.VDisks.findIndex(filterVDisk) == -1) {
+ matched = false;
+ }
+ } catch (error) {
+ matched = false;
+ }
+ var storage = this.storage[storageGroup.GroupID];
+ if (!matched) {
+ if (storage) {
+ this.removeFromGroup(storage);
+ if (this.observer) {
+ this.observer.unobserve(storage.domElement);
+ }
+ delete this.storage[storageGroup.GroupID];
+ }
+ continue;
+ }
+ pools[storagePool.Name] = true;
+ groups[storageGroup.GroupID] = true;
+ if (!storage) {
+ storageGroup.StoragePool = storagePool;
+ storage = this.storage[storageGroup.GroupID] = new Storage(storageGroup);
+ if (this.observer) {
+ this.observer.observe(storage.domElement);
+ }
+ }
+ storage.updateFromStorage(storageGroup);
+ var allocatedSizeGroup = 0;
+ vDisks += storageGroup.VDisks.length;
+ for (var vDiskNum in storageGroup.VDisks) {
+ var vDisk = storageGroup.VDisks[vDiskNum];
+ if (vDisk && vDisk.AllocatedSize) {
+ allocatedSizeGroup += Number(vDisk.AllocatedSize);
+ }
+
+ var pDisk = vDisk.PDisk;
+ if (pDisk) {
+ var pDiskId = pDisk.NodeId + '-' + pDisk.PDiskId;
+ if (!pPiskSeen[pDiskId]) {
+ pPiskSeen[pDiskId] = true;
+ pDisks++;
+ if (pDisk.TotalSize && pDisk.TotalSize && pDisk.AvailableSize) {
+ var ts = Number(pDisk.TotalSize);
+ totalSize += ts;
+ allocatedSize += ts - Number(pDisk.AvailableSize);
+ }
+ }
+ }
+ }
+ storage.allocatedSizeBytes = allocatedSizeGroup;
+ this.updateGroup(storage);
+ }
+ }
+ }
+ }
+ this.rebuildGroupHeaders();
+ this.statPools.setValue(Object.keys(pools).length);
+ this.statGroups.setValue(Object.keys(groups).length);
+ this.statVDisks.setValue(vDisks);
+ this.statPDisks.setValue(pDisks);
+ this.statAllocatedSize.setValue(bytesToGB(allocatedSize));
+ this.statTotalSize.setValue(bytesToGB(totalSize));
+ if (!this.first) {
+ $('#pacman').remove();
+ $('#stats_placement').show();
+ $('#filter').show();
+ $('#vdisk_filter_button').on('click',this.onChangeFilter.bind(this));
+ $('#vdisk_filter').on('keyup', function(event) {
+ // Number 13 is the "Enter" key on the keyboard
+ if (event.keyCode === 13) {
+ // Cancel the default action, if needed
+ event.preventDefault();
+ // Trigger the button element with a click
+ this.onChangeFilter();
+ }
+ }.bind(this)).tooltip({html: true}).attr('data-original-title', 'DiskSpace=="Yellow"<br>!Replicated<br>NodeId==46 && PDisk.PDiskId==1001<br>VDiskId.GroupID==2181038480<br>');
+ $('#switches').show();
+ this.first = true;
+ }
+}
+
+StorageView.prototype.onVisibilityChange = function(entries) {
+ var now = getTime();
+ for (var idx = 0; idx < entries.length; ++idx) {
+ var entry = entries[idx];
+ var storage = $(entry.target).data('storage');
+ if (entry.isIntersecting) {
+ if (!storage.visible) {
+ storage.appear();
+ }
+ } else {
+ storage.disappear();
+ }
+ }
+}
diff --git a/ydb/core/viewer/content/v2/tablet_cell.js b/ydb/core/viewer/content/v2/tablet_cell.js
index f43fbe619e2..4129ba9dd94 100644
--- a/ydb/core/viewer/content/v2/tablet_cell.js
+++ b/ydb/core/viewer/content/v2/tablet_cell.js
@@ -1,91 +1,91 @@
-function TabletCell(options) {
- Object.assign(this, options);
- this.Count = 0;
- this.buildDomElement();
-}
-
-TabletCell.prototype.tabletTypes = {
- 'Coordinator': 'C',
- 'Mediator': 'M',
- 'DataShard': 'DS',
- 'Hive': 'H',
- 'BSController': 'BS',
- 'SchemeShard': 'SS',
- 'Console': 'CN',
- 'NodeBroker': 'NB',
- 'TenantSlotBroker': 'TSB',
- 'Cms': 'CMS',
- 'TxAllocator': 'TA',
- 'Kesus': 'K',
- 'RTMRPartition': 'RP',
- 'KeyValue': 'KV',
- 'PersQueue': 'PQ',
- 'PersQueueReadBalancer': 'PB',
- 'BlockStorePartition': 'BP',
- 'BlockStoreVolume': 'BV',
+function TabletCell(options) {
+ Object.assign(this, options);
+ this.Count = 0;
+ this.buildDomElement();
+}
+
+TabletCell.prototype.tabletTypes = {
+ 'Coordinator': 'C',
+ 'Mediator': 'M',
+ 'DataShard': 'DS',
+ 'Hive': 'H',
+ 'BSController': 'BS',
+ 'SchemeShard': 'SS',
+ 'Console': 'CN',
+ 'NodeBroker': 'NB',
+ 'TenantSlotBroker': 'TSB',
+ 'Cms': 'CMS',
+ 'TxAllocator': 'TA',
+ 'Kesus': 'K',
+ 'RTMRPartition': 'RP',
+ 'KeyValue': 'KV',
+ 'PersQueue': 'PQ',
+ 'PersQueueReadBalancer': 'PB',
+ 'BlockStorePartition': 'BP',
+ 'BlockStoreVolume': 'BV',
'SequenceShard': 'S',
'ReplicationController': 'RC',
-};
-
-TabletCell.prototype.getTabletType = function() {
- var t = this.tabletTypes[this.Type];
- if (t) {
- return t;
- }
- return this.Type.substr(0, 2);
-}
-
-TabletCell.prototype.buildDomElement = function() {
- var tablet = $('<div>', {class: 'tablet'});
- if (this.Leader) {
- tablet.css('background-color', green);
- } else {
- tablet.css('background-color', lightblue);
- }
- tablet.append($('<div>', {class: 'tablet_label', text: this.type = this.getTabletType()}));
- var counter = $('<div>', {class: 'tablet_counter'});
- tablet.append(counter);
- this.domElementCounter = counter[0];
- var tooltip = this.Type;
- if (!this.Leader) {
+};
+
+TabletCell.prototype.getTabletType = function() {
+ var t = this.tabletTypes[this.Type];
+ if (t) {
+ return t;
+ }
+ return this.Type.substr(0, 2);
+}
+
+TabletCell.prototype.buildDomElement = function() {
+ var tablet = $('<div>', {class: 'tablet'});
+ if (this.Leader) {
+ tablet.css('background-color', green);
+ } else {
+ tablet.css('background-color', lightblue);
+ }
+ tablet.append($('<div>', {class: 'tablet_label', text: this.type = this.getTabletType()}));
+ var counter = $('<div>', {class: 'tablet_counter'});
+ tablet.append(counter);
+ this.domElementCounter = counter[0];
+ var tooltip = this.Type;
+ if (!this.Leader) {
tooltip += ' (follower)';
- }
- tablet.attr('data-original-title', tooltip);
- tablet.tooltip({html: true});
- return this.domElement = tablet[0];
-}
-
-TabletCell.prototype.setCount = function(count) {
- if (this.Count !== count) {
- var width = 0;
- if (this.Count === 1) {
- $(this.domElementCounter).show();
- }
- if (count === 1) {
- $(this.domElementCounter).hide();
- width = 20;
- } else if (count < 10) {
- width = 27;
- } else if (count < 100) {
- width = 34;
- } else if (count < 1000) {
- width = 41;
- } else {
- width = 48;
- }
- $(this.domElementCounter).text(count);
- if (this.type.length === 2) {
- width += 7;
- }
- if (this.type.length === 3) {
- width += 14;
- }
- this.Count = count;
- $(this.domElement).css('width', width + 'px');
- }
-}
-
-TabletCell.prototype.restoreTooltips = function() {
- $(this.domElement).tooltip({html: true});
-}
-
+ }
+ tablet.attr('data-original-title', tooltip);
+ tablet.tooltip({html: true});
+ return this.domElement = tablet[0];
+}
+
+TabletCell.prototype.setCount = function(count) {
+ if (this.Count !== count) {
+ var width = 0;
+ if (this.Count === 1) {
+ $(this.domElementCounter).show();
+ }
+ if (count === 1) {
+ $(this.domElementCounter).hide();
+ width = 20;
+ } else if (count < 10) {
+ width = 27;
+ } else if (count < 100) {
+ width = 34;
+ } else if (count < 1000) {
+ width = 41;
+ } else {
+ width = 48;
+ }
+ $(this.domElementCounter).text(count);
+ if (this.type.length === 2) {
+ width += 7;
+ }
+ if (this.type.length === 3) {
+ width += 14;
+ }
+ this.Count = count;
+ $(this.domElement).css('width', width + 'px');
+ }
+}
+
+TabletCell.prototype.restoreTooltips = function() {
+ $(this.domElement).tooltip({html: true});
+}
+
diff --git a/ydb/core/viewer/content/v2/tablet_map.js b/ydb/core/viewer/content/v2/tablet_map.js
index 953656522e2..03affb34184 100644
--- a/ydb/core/viewer/content/v2/tablet_map.js
+++ b/ydb/core/viewer/content/v2/tablet_map.js
@@ -1,45 +1,45 @@
-function TabletMap(options) {
- Object.assign(this, {
- cells: {}
- },
- options);
- this.buildDomElement();
-}
-
-TabletMap.prototype.buildDomElement = function() {
- var tabletRow = $('<div>', {class: 'tablet_map'});
- this.domElement = tabletRow[0];
- return tabletRow[0];
-}
-
-TabletMap.prototype.getCell = function(type, up) {
- var cell = this.cells[type];
- if (!cell) {
- cell = this.cells[type] = new TabletCell(up);
- $(this.domElement).append(cell.domElement);
- }
- return cell;
-}
-
-TabletMap.prototype.updateTabletInfo = function(update) {
- var seenTypes = {};
- for (var idx in update) {
- var up = update[idx];
- var type = up.Type + '-' + up.Leader;
- seenTypes[type] = true;
- var cell = this.getCell(type, up);
- cell.setCount(up.Count);
- }
- for (var t in this.cells) {
- if (!seenTypes[t]) {
- $(this.cells[t].domElement).remove();
- delete this.cells[t];
- }
- }
-}
-
-TabletMap.prototype.restoreTooltips = function() {
- for (var t in this.cells) {
- this.cells[t].restoreTooltips();
- }
-}
+function TabletMap(options) {
+ Object.assign(this, {
+ cells: {}
+ },
+ options);
+ this.buildDomElement();
+}
+
+TabletMap.prototype.buildDomElement = function() {
+ var tabletRow = $('<div>', {class: 'tablet_map'});
+ this.domElement = tabletRow[0];
+ return tabletRow[0];
+}
+
+TabletMap.prototype.getCell = function(type, up) {
+ var cell = this.cells[type];
+ if (!cell) {
+ cell = this.cells[type] = new TabletCell(up);
+ $(this.domElement).append(cell.domElement);
+ }
+ return cell;
+}
+
+TabletMap.prototype.updateTabletInfo = function(update) {
+ var seenTypes = {};
+ for (var idx in update) {
+ var up = update[idx];
+ var type = up.Type + '-' + up.Leader;
+ seenTypes[type] = true;
+ var cell = this.getCell(type, up);
+ cell.setCount(up.Count);
+ }
+ for (var t in this.cells) {
+ if (!seenTypes[t]) {
+ $(this.cells[t].domElement).remove();
+ delete this.cells[t];
+ }
+ }
+}
+
+TabletMap.prototype.restoreTooltips = function() {
+ for (var t in this.cells) {
+ this.cells[t].restoreTooltips();
+ }
+}
diff --git a/ydb/core/viewer/content/v2/tenant.js b/ydb/core/viewer/content/v2/tenant.js
index ba10c6c2787..0c39091ce74 100644
--- a/ydb/core/viewer/content/v2/tenant.js
+++ b/ydb/core/viewer/content/v2/tenant.js
@@ -1,231 +1,231 @@
-function Tenant(options) {
- Object.assign(this, {
- nodes: {},
- nodeCount: 0
- },
- options);
- this.buildDomElement();
-}
-
-Tenant.prototype.buildDomElement = function() {
- var row = $('<tr>');
- row.data('tenant', this);
-
- var cellName = $('<td>', {class: 'tenant_name_place'});
- this.domElementName = cellName[0];
- row.append(this.domElementName);
-
- var cellCompute = $('<td>', {class: 'tenant_nodes_compute'});
- this.domElementCompute = cellCompute[0];
- row.append(this.domElementCompute);
-
- var cellStorage = $('<td>', {class: 'tenant_nodes_storage'});
- this.domElementStorage = cellStorage[0];
- row.append(this.domElementStorage);
-
- var cellNodes = $('<td>', {class: 'tenant_nodes_place'});
- this.domElementNodes = cellNodes[0];
- row.append(this.domElementNodes);
-
- var cellCpu = $('<td>', {class: 'tenant_cpu_place'});
- this.poolMap = new PoolMap();
- this.domElementCpu = cellCpu[0];
- this.domElementCpu.appendChild(this.poolMap.domElement);
- row.append(this.domElementCpu);
-
- var cellTablets = $('<td>', {class: 'tenant_tablets_place'});
- this.domElementTablets = cellTablets[0];
- row.append(this.domElementTablets);
-
- var cellMetricsCpu = $('<td>', {class: 'tenant_metrics_cpu_place'});
- this.domElementMetricsCpu = cellMetricsCpu[0];
- row.append(this.domElementMetricsCpu);
-
- var cellMetricsMemory = $('<td>', {class: 'tenant_metrics_memory_place'});
- this.domElementMetricsMemory = cellMetricsMemory[0];
- row.append(this.domElementMetricsMemory);
-
- var cellMetricsNetwork = $('<td>', {class: 'tenant_metrics_network_place'});
- this.domElementMetricsNetwork = cellMetricsNetwork[0];
- row.append(this.domElementMetricsNetwork);
-
- var cellMetricsStorage = $('<td>', {class: 'tenant_metrics_storage_place'});
- this.domElementMetricsStorage = cellMetricsStorage[0];
- row.append(this.domElementMetricsStorage);
-
- this.domElement = row[0];
-}
-
-Tenant.prototype.mergePoolStats = function(total, stats) {
- stats.forEach(function(item) {
- var totalItem = total[item.Name];
- var threads = item.Threads;
- if (threads === undefined) {
- threads = 1;
- }
- if (totalItem === undefined) {
- total[item.Name] = {
- TotalUsage: item.Usage,
- Threads: threads,
- Counter: 1
- }
- } else {
- totalItem.TotalUsage += item.Usage * threads;
- totalItem.Threads += threads;
- totalItem.Counter++;
- }
- });
-}
-
-Tenant.prototype.getTotalPoolStats = function() {
- var totalStats = {};
- for (var nodeId in this.nodes) {
- var node = this.nodes[nodeId];
- if (node && node.PoolStats) {
- this.mergePoolStats(totalStats, node.PoolStats);
- }
- }
- var result = [];
- for (var key in totalStats) {
- var stats = totalStats[key];
- result.push({
- Name: key,
- Usage: stats.TotalUsage / stats.Threads,
- Threads: stats.Threads
- });
- }
- return result;
-}
-
-Tenant.prototype.getTotalPoolUsage = function(totalStats, name) {
- for (var i = 0; i < totalStats.length; ++i) {
- var poolStats = totalStats[i];
- if (poolStats.Name === name) {
- return poolStats.Usage * poolStats.Threads;
- }
- }
- return 0;
-}
-
-Tenant.prototype.updateSysInfo = function(update) {
- var nodeInfo = this.nodes[update.NodeId];
- if (nodeInfo === undefined) {
- nodeInfo = this.nodes[update.NodeId] = {};
- //this.nodeCount++;
- //this.domElementNodes.innerHTML = this.nodeCount;
- }
-
- if (update.PoolStats !== undefined) {
- var totalPoolStats = this.getTotalPoolStats();
- this.poolMap.setPoolMap(totalPoolStats);
- var userPoolStats = this.getTotalPoolUsage(totalPoolStats, 'User');
- this.domElementMetricsCpu.innerHTML = userPoolStats.toFixed(1);
- }
-
- if (this.name === undefined) {
- this.domElementName.innerHTML = this.name = this.tenantView.getTenantName(update);
- }
- updateObject(nodeInfo, update);
-}
-
-Tenant.prototype.getMetricsValueCPU = function(value) {
- return (value / 1000000).toFixed(1);
-}
-
-Tenant.prototype.getMetricsValueMemory = function(value) {
- return bytesToSize(value);
-}
-
-Tenant.prototype.getMetricsValueNetwork = function(value) {
- return bytesToSize(value);
-}
-
-Tenant.prototype.getMetricsValueStorage = function(value) {
- return bytesToSize(value);
-}
-
-Tenant.prototype.updateTenantInfo = function(update) {
- if (update.State) {
- this.state = update.State;
- }
-
- if (this.name === undefined) {
- if (update.Name) {
- this.name = update.Name;
- } else {
- this.name = update.ShardId + ':' + update.PathId;
- }
- this.domElementName.innerHTML = this.name;
- }
-
- if (update.Resources) {
- var resources = {};
- update.Resources.Required.forEach(function(item) {
- var resource = resources[item.Type];
- if (!resource) {
- resource = resources[item.Type] = {
- required: 0,
- allocated: 0
- };
- }
- resource.required += Number(item.Count);
- });
- update.Resources.Allocated.forEach(function(item) {
- var resource = resources[item.Type];
- if (!resource) {
- resource = resources[item.Type] = {
- required: 0,
- allocated: 0
- };
- }
- resource.allocated += Number(item.Count);
- });
- var compute = resources['compute'];
- if (compute) {
- this.domElementCompute.innerHTML = getPartValuesText(compute.allocated, compute.required);
- }
- var storage = resources['storage'];
- if (storage) {
- this.domElementStorage.innerHTML = getPartValuesText(storage.allocated, storage.required);
- }
- }
-
- if (update.NodeIds) {
- if (update.AliveNodes) {
- this.aliveNodes = update.AliveNodes;
- } else {
- this.aliveNodes = 0;
- }
- this.domElementNodes.innerHTML = this.aliveNodes;
- }
-
- if (update.StateStats) {
- var aliveTablets = 0;
- var totalTablets = 0;
- for (var i = 0; i < update.StateStats.length; ++i) {
- if (update.StateStats[i].VolatileState === 'TABLET_VOLATILE_STATE_RUNNING') {
- aliveTablets += update.StateStats[i].Count;
- }
- totalTablets += update.StateStats[i].Count;
- }
- this.domElementTablets.innerHTML = getPartValuesText(aliveTablets, totalTablets);
- }
-
- if (update.Metrics) {
- /*if (update.Metrics.CPU) {
- this.domElementMetricsCpu.innerHTML = this.getMetricsValueCPU(update.Metrics.CPU);
- }*/
-
- if (update.Metrics.Memory) {
- this.domElementMetricsMemory.innerHTML = this.getMetricsValueMemory(update.Metrics.Memory);
- }
-
- if (update.Metrics.Network) {
- this.domElementMetricsNetwork.innerHTML = this.getMetricsValueNetwork(update.Metrics.Network);
- }
-
- if (update.Metrics.Storage) {
- this.domElementMetricsStorage.innerHTML = this.getMetricsValueStorage(update.Metrics.Storage);
- }
- }
-}
+function Tenant(options) {
+ Object.assign(this, {
+ nodes: {},
+ nodeCount: 0
+ },
+ options);
+ this.buildDomElement();
+}
+
+Tenant.prototype.buildDomElement = function() {
+ var row = $('<tr>');
+ row.data('tenant', this);
+
+ var cellName = $('<td>', {class: 'tenant_name_place'});
+ this.domElementName = cellName[0];
+ row.append(this.domElementName);
+
+ var cellCompute = $('<td>', {class: 'tenant_nodes_compute'});
+ this.domElementCompute = cellCompute[0];
+ row.append(this.domElementCompute);
+
+ var cellStorage = $('<td>', {class: 'tenant_nodes_storage'});
+ this.domElementStorage = cellStorage[0];
+ row.append(this.domElementStorage);
+
+ var cellNodes = $('<td>', {class: 'tenant_nodes_place'});
+ this.domElementNodes = cellNodes[0];
+ row.append(this.domElementNodes);
+
+ var cellCpu = $('<td>', {class: 'tenant_cpu_place'});
+ this.poolMap = new PoolMap();
+ this.domElementCpu = cellCpu[0];
+ this.domElementCpu.appendChild(this.poolMap.domElement);
+ row.append(this.domElementCpu);
+
+ var cellTablets = $('<td>', {class: 'tenant_tablets_place'});
+ this.domElementTablets = cellTablets[0];
+ row.append(this.domElementTablets);
+
+ var cellMetricsCpu = $('<td>', {class: 'tenant_metrics_cpu_place'});
+ this.domElementMetricsCpu = cellMetricsCpu[0];
+ row.append(this.domElementMetricsCpu);
+
+ var cellMetricsMemory = $('<td>', {class: 'tenant_metrics_memory_place'});
+ this.domElementMetricsMemory = cellMetricsMemory[0];
+ row.append(this.domElementMetricsMemory);
+
+ var cellMetricsNetwork = $('<td>', {class: 'tenant_metrics_network_place'});
+ this.domElementMetricsNetwork = cellMetricsNetwork[0];
+ row.append(this.domElementMetricsNetwork);
+
+ var cellMetricsStorage = $('<td>', {class: 'tenant_metrics_storage_place'});
+ this.domElementMetricsStorage = cellMetricsStorage[0];
+ row.append(this.domElementMetricsStorage);
+
+ this.domElement = row[0];
+}
+
+Tenant.prototype.mergePoolStats = function(total, stats) {
+ stats.forEach(function(item) {
+ var totalItem = total[item.Name];
+ var threads = item.Threads;
+ if (threads === undefined) {
+ threads = 1;
+ }
+ if (totalItem === undefined) {
+ total[item.Name] = {
+ TotalUsage: item.Usage,
+ Threads: threads,
+ Counter: 1
+ }
+ } else {
+ totalItem.TotalUsage += item.Usage * threads;
+ totalItem.Threads += threads;
+ totalItem.Counter++;
+ }
+ });
+}
+
+Tenant.prototype.getTotalPoolStats = function() {
+ var totalStats = {};
+ for (var nodeId in this.nodes) {
+ var node = this.nodes[nodeId];
+ if (node && node.PoolStats) {
+ this.mergePoolStats(totalStats, node.PoolStats);
+ }
+ }
+ var result = [];
+ for (var key in totalStats) {
+ var stats = totalStats[key];
+ result.push({
+ Name: key,
+ Usage: stats.TotalUsage / stats.Threads,
+ Threads: stats.Threads
+ });
+ }
+ return result;
+}
+
+Tenant.prototype.getTotalPoolUsage = function(totalStats, name) {
+ for (var i = 0; i < totalStats.length; ++i) {
+ var poolStats = totalStats[i];
+ if (poolStats.Name === name) {
+ return poolStats.Usage * poolStats.Threads;
+ }
+ }
+ return 0;
+}
+
+Tenant.prototype.updateSysInfo = function(update) {
+ var nodeInfo = this.nodes[update.NodeId];
+ if (nodeInfo === undefined) {
+ nodeInfo = this.nodes[update.NodeId] = {};
+ //this.nodeCount++;
+ //this.domElementNodes.innerHTML = this.nodeCount;
+ }
+
+ if (update.PoolStats !== undefined) {
+ var totalPoolStats = this.getTotalPoolStats();
+ this.poolMap.setPoolMap(totalPoolStats);
+ var userPoolStats = this.getTotalPoolUsage(totalPoolStats, 'User');
+ this.domElementMetricsCpu.innerHTML = userPoolStats.toFixed(1);
+ }
+
+ if (this.name === undefined) {
+ this.domElementName.innerHTML = this.name = this.tenantView.getTenantName(update);
+ }
+ updateObject(nodeInfo, update);
+}
+
+Tenant.prototype.getMetricsValueCPU = function(value) {
+ return (value / 1000000).toFixed(1);
+}
+
+Tenant.prototype.getMetricsValueMemory = function(value) {
+ return bytesToSize(value);
+}
+
+Tenant.prototype.getMetricsValueNetwork = function(value) {
+ return bytesToSize(value);
+}
+
+Tenant.prototype.getMetricsValueStorage = function(value) {
+ return bytesToSize(value);
+}
+
+Tenant.prototype.updateTenantInfo = function(update) {
+ if (update.State) {
+ this.state = update.State;
+ }
+
+ if (this.name === undefined) {
+ if (update.Name) {
+ this.name = update.Name;
+ } else {
+ this.name = update.ShardId + ':' + update.PathId;
+ }
+ this.domElementName.innerHTML = this.name;
+ }
+
+ if (update.Resources) {
+ var resources = {};
+ update.Resources.Required.forEach(function(item) {
+ var resource = resources[item.Type];
+ if (!resource) {
+ resource = resources[item.Type] = {
+ required: 0,
+ allocated: 0
+ };
+ }
+ resource.required += Number(item.Count);
+ });
+ update.Resources.Allocated.forEach(function(item) {
+ var resource = resources[item.Type];
+ if (!resource) {
+ resource = resources[item.Type] = {
+ required: 0,
+ allocated: 0
+ };
+ }
+ resource.allocated += Number(item.Count);
+ });
+ var compute = resources['compute'];
+ if (compute) {
+ this.domElementCompute.innerHTML = getPartValuesText(compute.allocated, compute.required);
+ }
+ var storage = resources['storage'];
+ if (storage) {
+ this.domElementStorage.innerHTML = getPartValuesText(storage.allocated, storage.required);
+ }
+ }
+
+ if (update.NodeIds) {
+ if (update.AliveNodes) {
+ this.aliveNodes = update.AliveNodes;
+ } else {
+ this.aliveNodes = 0;
+ }
+ this.domElementNodes.innerHTML = this.aliveNodes;
+ }
+
+ if (update.StateStats) {
+ var aliveTablets = 0;
+ var totalTablets = 0;
+ for (var i = 0; i < update.StateStats.length; ++i) {
+ if (update.StateStats[i].VolatileState === 'TABLET_VOLATILE_STATE_RUNNING') {
+ aliveTablets += update.StateStats[i].Count;
+ }
+ totalTablets += update.StateStats[i].Count;
+ }
+ this.domElementTablets.innerHTML = getPartValuesText(aliveTablets, totalTablets);
+ }
+
+ if (update.Metrics) {
+ /*if (update.Metrics.CPU) {
+ this.domElementMetricsCpu.innerHTML = this.getMetricsValueCPU(update.Metrics.CPU);
+ }*/
+
+ if (update.Metrics.Memory) {
+ this.domElementMetricsMemory.innerHTML = this.getMetricsValueMemory(update.Metrics.Memory);
+ }
+
+ if (update.Metrics.Network) {
+ this.domElementMetricsNetwork.innerHTML = this.getMetricsValueNetwork(update.Metrics.Network);
+ }
+
+ if (update.Metrics.Storage) {
+ this.domElementMetricsStorage.innerHTML = this.getMetricsValueStorage(update.Metrics.Storage);
+ }
+ }
+}
diff --git a/ydb/core/viewer/content/v2/tenant_view.js b/ydb/core/viewer/content/v2/tenant_view.js
index 785a710d478..b3bd52e4ec9 100644
--- a/ydb/core/viewer/content/v2/tenant_view.js
+++ b/ydb/core/viewer/content/v2/tenant_view.js
@@ -1,137 +1,137 @@
-function TenantView(options) {
- Object.assign(this, {
- visibleRefreshTimeout: 1000,
- overallRefreshTimeout: 30000,
- tenants: {}
- }, options);
- this.refreshViewInterval = setInterval(this.refreshView.bind(this), this.visibleRefreshTimeout);
- this.buildDomElement();
- this.refreshOverall();
-}
-
-TenantView.prototype.buildDomElement = function() {
- var tenantsContainer = $('<table>', {class: 'tenantlist tenant_container'});
- var tenantsHead = $('<thead>');
- var tenantsRow = $('<tr>');
- tenantsRow.append('<th style="text-align:left">Name</th>');
- tenantsRow.append('<th style="text-align:right">Compute</th>');
- tenantsRow.append('<th style="text-align:right">Storage</th>');
- tenantsRow.append('<th style="text-align:right">Nodes</th>');
- tenantsRow.append('<th>CPU</th>');
- tenantsRow.append('<th style="text-align:right">Tablets</th>');
- tenantsRow.append('<th style="text-align:right">CPU</th>');
- tenantsRow.append('<th style="text-align:right">Memory</th>');
- tenantsRow.append('<th style="text-align:right">Network</th>');
- tenantsRow.append('<th style="text-align:right">Storage</th>');
- tenantsHead.append(tenantsRow);
- var tenantsBody = $('<tbody>');
- tenantsContainer.append(tenantsHead);
- tenantsContainer.append(tenantsBody);
- this.domElementTenantsContainer = tenantsContainer[0];
- this.domElementTenantsBody = tenantsBody[0];
- this.domElement.appendChild(this.domElementTenantsContainer);
-}
-
-TenantView.prototype.onSysInfo = function(data) {
- if (data.SystemStateInfo !== undefined) {
- for (var i in data.SystemStateInfo) {
- var update = data.SystemStateInfo[i];
- var tenantName = this.getTenantName(update);
- //console.log('Tenant ' + tenantName);
- var tenant = this.tenants[tenantName];
- if (tenant) {
- tenant.updateSysInfo(update);
- } else {
- tenant = this.tenants[tenantName] = new Tenant();
- tenant.tenantView = this;
- tenant.updateSysInfo(update);
- this.domElementTenantsBody.appendChild(tenant.domElement);
- }
- }
- if (data.ResponseTime != 0) {
- this.sysInfoChangeTime = data.ResponseTime;
- }
- } else {
- if (!this.sysInfoChangeTime) {
- this.onDisconnect();
- }
- }
-}
-
-TenantView.prototype.onTenantInfo = function(data) {
- if (data.TenantInfo) {
- for (var i = 0; i < data.TenantInfo.length; ++i) {
- var update = data.TenantInfo[i];
- var tenantName = update.Name ? update.Name : update.ShardId + ':' + update.PathId;
- console.log('Tenant ' + tenantName);
- var tenant = this.tenants[tenantName];
- if (tenant) {
- tenant.updateTenantInfo(update);
- } else {
- tenant = this.tenants[tenantName] = new Tenant();
- tenant.updateTenantInfo(update);
- this.domElementTenantsBody.appendChild(tenant.domElement);
- }
- }
- }
-}
-
-TenantView.prototype.onDisconnect = function() {
-// TODO
-}
-
-TenantView.prototype.refreshOverall = function() {
- this.lastRefreshOverall = getTime();
- var request = {
- alive: 0,
- enums: 1,
- timeout: 10000,
- since: this.sysInfoChangeTime
- };
- $.ajax({
- url: 'json/tenantinfo',
- data: request,
- success: this.onTenantInfo.bind(this),
- error: this.onDisconnect.bind(this)
- });
-}
-
-TenantView.prototype.isTimeToRefreshOverall = function() {
- return (!this.lastRefreshOverall || (this.lastRefreshOverall <= (getTime() - this.overallRefreshTimeout)));
-}
-
-TenantView.prototype.refreshView = function() {
- this.refreshViewTimer = null;
- if (this.isTimeToRefreshOverall()) {
- console.log('refreshOverall (tenants)');
- this.refreshOverall();
- } else {
- /*console.log('refreshView: ' + Object.keys(this.visibleNodes));
- for (var nodeId in this.visibleNodes) {
- var node = this.nodes[nodeId];
- if (!node.visible) {
- delete this.visibleNodes[nodeId];
- } else {
- this.refreshNode(node);
- }
- }*/
- }
-}
-
-TenantView.prototype.getConfig = function() {
- return this.config;
-}
-
-TenantView.prototype.getRootPath = function() {
- var config = this.getConfig();
- if (config) {
- return '/' + config.DomainsConfig.Domain[0].Name;
- }
-}
-
-TenantView.prototype.getTenantName = function(sysInfo) {
- if (sysInfo.Tenants !== undefined && sysInfo.Tenants.length > 0) {
- return sysInfo.Tenants.join(',');
- }
- return this.getRootPath();
-}
+function TenantView(options) {
+ Object.assign(this, {
+ visibleRefreshTimeout: 1000,
+ overallRefreshTimeout: 30000,
+ tenants: {}
+ }, options);
+ this.refreshViewInterval = setInterval(this.refreshView.bind(this), this.visibleRefreshTimeout);
+ this.buildDomElement();
+ this.refreshOverall();
+}
+
+TenantView.prototype.buildDomElement = function() {
+ var tenantsContainer = $('<table>', {class: 'tenantlist tenant_container'});
+ var tenantsHead = $('<thead>');
+ var tenantsRow = $('<tr>');
+ tenantsRow.append('<th style="text-align:left">Name</th>');
+ tenantsRow.append('<th style="text-align:right">Compute</th>');
+ tenantsRow.append('<th style="text-align:right">Storage</th>');
+ tenantsRow.append('<th style="text-align:right">Nodes</th>');
+ tenantsRow.append('<th>CPU</th>');
+ tenantsRow.append('<th style="text-align:right">Tablets</th>');
+ tenantsRow.append('<th style="text-align:right">CPU</th>');
+ tenantsRow.append('<th style="text-align:right">Memory</th>');
+ tenantsRow.append('<th style="text-align:right">Network</th>');
+ tenantsRow.append('<th style="text-align:right">Storage</th>');
+ tenantsHead.append(tenantsRow);
+ var tenantsBody = $('<tbody>');
+ tenantsContainer.append(tenantsHead);
+ tenantsContainer.append(tenantsBody);
+ this.domElementTenantsContainer = tenantsContainer[0];
+ this.domElementTenantsBody = tenantsBody[0];
+ this.domElement.appendChild(this.domElementTenantsContainer);
+}
+
+TenantView.prototype.onSysInfo = function(data) {
+ if (data.SystemStateInfo !== undefined) {
+ for (var i in data.SystemStateInfo) {
+ var update = data.SystemStateInfo[i];
+ var tenantName = this.getTenantName(update);
+ //console.log('Tenant ' + tenantName);
+ var tenant = this.tenants[tenantName];
+ if (tenant) {
+ tenant.updateSysInfo(update);
+ } else {
+ tenant = this.tenants[tenantName] = new Tenant();
+ tenant.tenantView = this;
+ tenant.updateSysInfo(update);
+ this.domElementTenantsBody.appendChild(tenant.domElement);
+ }
+ }
+ if (data.ResponseTime != 0) {
+ this.sysInfoChangeTime = data.ResponseTime;
+ }
+ } else {
+ if (!this.sysInfoChangeTime) {
+ this.onDisconnect();
+ }
+ }
+}
+
+TenantView.prototype.onTenantInfo = function(data) {
+ if (data.TenantInfo) {
+ for (var i = 0; i < data.TenantInfo.length; ++i) {
+ var update = data.TenantInfo[i];
+ var tenantName = update.Name ? update.Name : update.ShardId + ':' + update.PathId;
+ console.log('Tenant ' + tenantName);
+ var tenant = this.tenants[tenantName];
+ if (tenant) {
+ tenant.updateTenantInfo(update);
+ } else {
+ tenant = this.tenants[tenantName] = new Tenant();
+ tenant.updateTenantInfo(update);
+ this.domElementTenantsBody.appendChild(tenant.domElement);
+ }
+ }
+ }
+}
+
+TenantView.prototype.onDisconnect = function() {
+// TODO
+}
+
+TenantView.prototype.refreshOverall = function() {
+ this.lastRefreshOverall = getTime();
+ var request = {
+ alive: 0,
+ enums: 1,
+ timeout: 10000,
+ since: this.sysInfoChangeTime
+ };
+ $.ajax({
+ url: 'json/tenantinfo',
+ data: request,
+ success: this.onTenantInfo.bind(this),
+ error: this.onDisconnect.bind(this)
+ });
+}
+
+TenantView.prototype.isTimeToRefreshOverall = function() {
+ return (!this.lastRefreshOverall || (this.lastRefreshOverall <= (getTime() - this.overallRefreshTimeout)));
+}
+
+TenantView.prototype.refreshView = function() {
+ this.refreshViewTimer = null;
+ if (this.isTimeToRefreshOverall()) {
+ console.log('refreshOverall (tenants)');
+ this.refreshOverall();
+ } else {
+ /*console.log('refreshView: ' + Object.keys(this.visibleNodes));
+ for (var nodeId in this.visibleNodes) {
+ var node = this.nodes[nodeId];
+ if (!node.visible) {
+ delete this.visibleNodes[nodeId];
+ } else {
+ this.refreshNode(node);
+ }
+ }*/
+ }
+}
+
+TenantView.prototype.getConfig = function() {
+ return this.config;
+}
+
+TenantView.prototype.getRootPath = function() {
+ var config = this.getConfig();
+ if (config) {
+ return '/' + config.DomainsConfig.Domain[0].Name;
+ }
+}
+
+TenantView.prototype.getTenantName = function(sysInfo) {
+ if (sysInfo.Tenants !== undefined && sysInfo.Tenants.length > 0) {
+ return sysInfo.Tenants.join(',');
+ }
+ return this.getRootPath();
+}
diff --git a/ydb/core/viewer/content/v2/tenants b/ydb/core/viewer/content/v2/tenants
index 19c8d562381..d2f74b05297 100644
--- a/ydb/core/viewer/content/v2/tenants
+++ b/ydb/core/viewer/content/v2/tenants
@@ -1,71 +1,71 @@
-<!DOCTYPE HTML>
-<html>
-<head>
-<link rel="stylesheet" href="https://yastatic.net/bootstrap/3.3.1/css/bootstrap.min.css">
-<script language="javascript" type="text/javascript" src="https://yastatic.net/jquery/2.1.3/jquery.min.js"></script>
-<script language="javascript" type="text/javascript" src="https://yastatic.net/bootstrap/3.3.1/js/bootstrap.min.js"></script>
-<style type="text/css">
-.table-nonfluid { width: auto; }
-.narrow-line50 {line-height: 50%}
-.narrow-line60 {line-height: 60%}
-.narrow-line70 {line-height: 70%}
-.narrow-line80 {line-height: 80%}
-.narrow-line90 {line-height: 90%}
-</style>
-<link rel="stylesheet" href="../style.min.css" />
-<link rel="stylesheet" href="viewer.css" />
-<script src="util.js"></script>
-<script src="pool_block.js"></script>
-<script src="pool_map.js"></script>
-<script src="node_map.js"></script>
-<script src="pdisk.js"></script>
-<script src="vdisk.js"></script>
-<script src="disk_cell.js"></script>
-<script src="disk_map.js"></script>
-<script src="tablet_cell.js"></script>
-<script src="tablet_map.js"></script>
-<script src="node.js"></script>
-<script src="node_group.js"></script>
-<script src="tenant.js"></script>
-<script src="overview.js"></script>
-<script src="cpu_view.js"></script>
-<script src="net_view.js"></script>
-<script src="storage_view.js"></script>
-<script src="node_view.js"></script>
-<script src="tenant_view.js"></script>
-<script src="viewer.js"></script>
-</head>
-<body onload='mainTenants();'>
-<div class='container-fluid'>
-<ul class="nav nav-tabs">
- <li class="nav-item">
- <a class="pseudo-nav-link" href="overview">Overview</a>
- </li>
- <li class="nav-item">
- <a class="pseudo-nav-link" href="cpu">CPU</a>
- </li>
- <li class="nav-item">
- <a class="pseudo-nav-link" href="network">Network</a>
- </li>
- <li class="nav-item">
- <a class="pseudo-nav-link" href="storage">Storage</a>
- </li>
- <li class="nav-item">
- <a class="pseudo-nav-link" href="nodes">Nodes</a>
- </li>
- <li class="nav-item active">
- <a class="pseudo-nav-link" href="tenants">Tenants</a>
- </li>
- <li style="float:right">
- <span id="updateQueueInflight" style="font-size:10px"></span>
- <span id="updateQueueCounter" style="font-weight:bold;font-size:20px;margin-left:40px"></span>
- </li>
-</ul>
-<div class="tab-content" style="padding-top: 10px">
- <div id="tenants" class="tab-pane active">
- <div id="tenants_view" style='display: inline-block'></div>
- </div>
-</div>
-</div>
-</body>
-</html>
+<!DOCTYPE HTML>
+<html>
+<head>
+<link rel="stylesheet" href="https://yastatic.net/bootstrap/3.3.1/css/bootstrap.min.css">
+<script language="javascript" type="text/javascript" src="https://yastatic.net/jquery/2.1.3/jquery.min.js"></script>
+<script language="javascript" type="text/javascript" src="https://yastatic.net/bootstrap/3.3.1/js/bootstrap.min.js"></script>
+<style type="text/css">
+.table-nonfluid { width: auto; }
+.narrow-line50 {line-height: 50%}
+.narrow-line60 {line-height: 60%}
+.narrow-line70 {line-height: 70%}
+.narrow-line80 {line-height: 80%}
+.narrow-line90 {line-height: 90%}
+</style>
+<link rel="stylesheet" href="../style.min.css" />
+<link rel="stylesheet" href="viewer.css" />
+<script src="util.js"></script>
+<script src="pool_block.js"></script>
+<script src="pool_map.js"></script>
+<script src="node_map.js"></script>
+<script src="pdisk.js"></script>
+<script src="vdisk.js"></script>
+<script src="disk_cell.js"></script>
+<script src="disk_map.js"></script>
+<script src="tablet_cell.js"></script>
+<script src="tablet_map.js"></script>
+<script src="node.js"></script>
+<script src="node_group.js"></script>
+<script src="tenant.js"></script>
+<script src="overview.js"></script>
+<script src="cpu_view.js"></script>
+<script src="net_view.js"></script>
+<script src="storage_view.js"></script>
+<script src="node_view.js"></script>
+<script src="tenant_view.js"></script>
+<script src="viewer.js"></script>
+</head>
+<body onload='mainTenants();'>
+<div class='container-fluid'>
+<ul class="nav nav-tabs">
+ <li class="nav-item">
+ <a class="pseudo-nav-link" href="overview">Overview</a>
+ </li>
+ <li class="nav-item">
+ <a class="pseudo-nav-link" href="cpu">CPU</a>
+ </li>
+ <li class="nav-item">
+ <a class="pseudo-nav-link" href="network">Network</a>
+ </li>
+ <li class="nav-item">
+ <a class="pseudo-nav-link" href="storage">Storage</a>
+ </li>
+ <li class="nav-item">
+ <a class="pseudo-nav-link" href="nodes">Nodes</a>
+ </li>
+ <li class="nav-item active">
+ <a class="pseudo-nav-link" href="tenants">Tenants</a>
+ </li>
+ <li style="float:right">
+ <span id="updateQueueInflight" style="font-size:10px"></span>
+ <span id="updateQueueCounter" style="font-weight:bold;font-size:20px;margin-left:40px"></span>
+ </li>
+</ul>
+<div class="tab-content" style="padding-top: 10px">
+ <div id="tenants" class="tab-pane active">
+ <div id="tenants_view" style='display: inline-block'></div>
+ </div>
+</div>
+</div>
+</body>
+</html>
diff --git a/ydb/core/viewer/content/v2/util.js b/ydb/core/viewer/content/v2/util.js
index 7e0d4a625ce..c3a6766094a 100644
--- a/ydb/core/viewer/content/v2/util.js
+++ b/ydb/core/viewer/content/v2/util.js
@@ -1,296 +1,296 @@
-var grey = "grey";
-var green = "lightgreen";
-var blue = "#6495ED"; // #4169E1 #4682B4
-var lightblue = "lightblue";
-var yellow = "yellow";
-var orange = "orange";
-var red = "red";
-var black = "black";
-var lightgrey = "#F7F7F7";
-
-function pad2(val) {
- if (val < 10) {
- return "0" + val;
- } else {
- return val;
- }
-}
-
-function pad4(val) {
- var len = String(val).length;
- for (var i = len; i < 4; i++) {
- val = "0" + val;
- }
- return val;
-}
-
-function pad9(val) {
- var len = String(val).length;
- for (var i = len; i < 9; i++) {
- val = "0" + val;
- }
- return val;
-}
-
-function upTimeToString(upTime) {
- var seconds = Math.floor(upTime / 1000);
- if (seconds < 60) {
- return seconds + "s";
- } else {
- var minutes = Math.floor(seconds / 60);
- seconds = seconds % 60;
- if (minutes < 60) {
- return minutes + ":" + pad2(seconds);
- } else {
- var hours = Math.floor(minutes / 60);
- minutes = minutes % 60;
- if (hours < 24) {
- return hours + ":" + pad2(minutes) + ":" + pad2(seconds);
- } else {
- var days = Math.floor(hours / 24);
- hours = hours % 24;
- return days + "d " + pad2(hours) + ":" + pad2(minutes) + ":" + pad2(seconds);
- }
- }
- }
-}
-
-
-var sizes = ["", "K", "M", "G", "T", "P", "E"];
-var base = 1000;
-
-function bytesToSize(bytes) {
- if (isNaN(bytes)) {
- return "";
- }
- if (bytes < base)
- return String(bytes);
- var i = parseInt(Math.floor(Math.log(bytes) / Math.log(base)));
- if (i >= sizes.length) {
- i = sizes.length - 1;
- }
- var val = bytes / Math.pow(base, i);
- if (val > 999) {
- val = val / base;
- i++;
- }
- return val.toPrecision(3) + sizes[i];
-}
-
-function bytesToSpeed(bytes) {
- return bytesToMB(bytes) + '/s';
-}
-
-function bytesToGB(bytes) {
- if (isNaN(bytes)) {
- return "";
- }
- var val = bytes / 1000000000;
- if (val < 10) {
- return val.toFixed(2) + sizes[3];
- } else if (val < 100) {
- return val.toFixed(1) + sizes[3];
- } else {
- return val.toFixed() + sizes[3];
- }
-}
-
-function bytesToGB3(bytes) {
- if (isNaN(bytes)) {
- return "";
- }
- var val = bytes / 1000000000;
- if (val < 10) {
- return val.toFixed(1) + sizes[3];
- } else {
- return val.toFixed() + sizes[3];
- }
-}
-
-function bytesToGB0(bytes) {
- if (isNaN(bytes)) {
- return "";
- }
- var val = bytes / 1000000000;
- return val.toFixed() + sizes[3];
-}
-
-function bytesToMB(bytes) {
- if (isNaN(bytes)) {
- return "";
- }
- var val = bytes / 1000000;
- if (val < 10) {
- return val.toFixed(2) + sizes[2];
- } else if (val < 100) {
- return val.toFixed(1) + sizes[2];
- } else {
- return val.toFixed() + sizes[2];
- }
-}
-
-function valueToNumber(value) {
- return Number(value).toLocaleString();
-}
-function asNumber(num) {
- return (num === undefined || num === null) ? 0 : Number(num);
-}
-
-function getTime() {
- return new Date().getTime();
-}
-
-function updateObject(target, source) {
- return Object.assign(target, source);
-}
-
-function getPDiskId(info) {
- return info.NodeId + '-' + info.PDiskId;
-}
-
-function getVDiskId(info) {
- var vDiskId = info.VDiskId;
- return vDiskId.GroupID + '-' + vDiskId.GroupGeneration + '-' + vDiskId.Ring + '-' + vDiskId.Domain + '-' + vDiskId.VDisk;
-}
-
-function getNodeIdFromPeerName(peerName) {
- return Number(peerName.split(':', 1)[0]);
-}
-
-function getPortFromPeerName(peerName) {
- return Number(peerName.split(':', 3)[2]);
-}
-
-function getPartValuesText(part, total) {
- if (part === total) {
- return total;
- } else {
- return part + ' / ' + total;
- }
-}
-
-function flagToColor(flag) {
- switch (flag) {
- case 'Green':
- return green;
- case 'Blue':
- return blue;
- case 'Yellow':
- return yellow;
- case 'Orange':
- return orange;
- case 'Red':
- return red;
- default:
- return grey;
- }
-}
-
-function isBastionProxy(hostname) {
- return hostname === 'ydb.bastion.cloud.yandex-team.ru';
-}
-
-function isViewerProxy(hostname) {
- return hostname === 'viewer.ydb.yandex-team.ru';
-}
-
-function getBaseUrlForHost(host) {
- var hostname = window.location.hostname;
- if (isBastionProxy(hostname)) {
- return 'https://ydb.bastion.cloud.yandex-team.ru/' + host + '/';
- } else if (isViewerProxy(hostname)) {
- return 'https://viewer.ydb.yandex-team.ru/' + host + '/';
- } else {
- return 'http://' + host + '/';
- }
-}
-
-function mapValue(min, max, value) {
- return Math.floor(min + (max - min + 1) * value);
-}
-
-function mapColor(minColor, maxColor, value) {
- var minR = parseInt(minColor.substr(1, 2), 16);
- var minG = parseInt(minColor.substr(3, 2), 16);
- var minB = parseInt(minColor.substr(5, 2), 16);
- var maxR = parseInt(maxColor.substr(1, 2), 16);
- var maxG = parseInt(maxColor.substr(3, 2), 16);
- var maxB = parseInt(maxColor.substr(5, 2), 16);
- return '#'
- + pad2(Number(mapValue(minR, maxR, value)).toString(16))
- + pad2(Number(mapValue(minG, maxG, value)).toString(16))
- + pad2(Number(mapValue(minB, maxB, value)).toString(16));
-}
-
-function PoolColors(colors) {
- if (colors === undefined) {
- this.colors = [
- {usage: 0.00, R: 144, G: 238, B: 144},
- {usage: 0.75, R: 255, G: 255, B: 0},
- {usage: 1.00, R: 255, G: 0, B: 0}
- ];
- } else {
- this.colors = colors;
- }
-}
-
-PoolColors.prototype.getPoolColor = function(usage) {
- usage = Number(usage);
- var idx = 1;
- var len = this.colors.length - 1;
- for (idx = 1; idx < len && usage > this.colors[idx].usage; idx++);
- var a = this.colors[idx - 1];
- var b = this.colors[idx];
- usage = Math.max(usage, a.usage);
- usage = Math.min(usage, b.usage);
- var R = a.R + ((usage - a.usage) / (b.usage - a.usage)) * (b.R - a.R);
- var G = a.G + ((usage - a.usage) / (b.usage - a.usage)) * (b.G - a.G);
- var B = a.B + ((usage - a.usage) / (b.usage - a.usage)) * (b.B - a.B);
- return 'rgb(' + R.toFixed() + ',' + G.toFixed() + ',' + B.toFixed() + ')';
-}
-
-//code.iamkate.com
-function Queue(){var a=[],b=0;this.getLength=function(){return a.length-b};this.isEmpty=function(){return 0==a.length};this.enqueue=function(b){a.push(b)};this.dequeue=function(){if(0!=a.length){var c=a[b];2*++b>=a.length&&(a=a.slice(b),b=0);return c}};this.peek=function(){return 0<a.length?a[b]:void 0}};
-
-function UpdateQueue(options) {
- Object.assign(this, {}, options);
- this.updateQueue = new Queue();
- this.updateDelay = 0;
- this.runUpdateQueue();
-}
-
-UpdateQueue.prototype.enqueue = function(item) {
- if (this.updateDelay === 0) {
- this.onUpdate(item);
- } else {
- this.updateQueue.enqueue(item);
- }
-}
-
-UpdateQueue.prototype.isEmpty = function() {
- return this.updateQueue.isEmpty();
-}
-
-UpdateQueue.prototype.getLength = function() {
- return this.updateQueue.getLength();
-}
-
-UpdateQueue.prototype.runUpdateQueue = function() {
- if (!this.updateQueue.isEmpty()) {
- var update = this.updateQueue.dequeue();
- this.onUpdate(update);
- if (this.updateQueue.isEmpty()) {
- console.log('done updateQueue');
- } else {
- setTimeout(this.runUpdateQueue.bind(this), this.updateDelay);
- return;
- }
- }
- setTimeout(this.runUpdateQueue.bind(this), 100);
-}
-
-UpdateQueue.prototype.flushUpdateQueue = function() {
- while (!this.updateQueue.isEmpty()) {
- this.onUpdate(this.updateQueue.dequeue());
- }
-}
+var grey = "grey";
+var green = "lightgreen";
+var blue = "#6495ED"; // #4169E1 #4682B4
+var lightblue = "lightblue";
+var yellow = "yellow";
+var orange = "orange";
+var red = "red";
+var black = "black";
+var lightgrey = "#F7F7F7";
+
+function pad2(val) {
+ if (val < 10) {
+ return "0" + val;
+ } else {
+ return val;
+ }
+}
+
+function pad4(val) {
+ var len = String(val).length;
+ for (var i = len; i < 4; i++) {
+ val = "0" + val;
+ }
+ return val;
+}
+
+function pad9(val) {
+ var len = String(val).length;
+ for (var i = len; i < 9; i++) {
+ val = "0" + val;
+ }
+ return val;
+}
+
+function upTimeToString(upTime) {
+ var seconds = Math.floor(upTime / 1000);
+ if (seconds < 60) {
+ return seconds + "s";
+ } else {
+ var minutes = Math.floor(seconds / 60);
+ seconds = seconds % 60;
+ if (minutes < 60) {
+ return minutes + ":" + pad2(seconds);
+ } else {
+ var hours = Math.floor(minutes / 60);
+ minutes = minutes % 60;
+ if (hours < 24) {
+ return hours + ":" + pad2(minutes) + ":" + pad2(seconds);
+ } else {
+ var days = Math.floor(hours / 24);
+ hours = hours % 24;
+ return days + "d " + pad2(hours) + ":" + pad2(minutes) + ":" + pad2(seconds);
+ }
+ }
+ }
+}
+
+
+var sizes = ["", "K", "M", "G", "T", "P", "E"];
+var base = 1000;
+
+function bytesToSize(bytes) {
+ if (isNaN(bytes)) {
+ return "";
+ }
+ if (bytes < base)
+ return String(bytes);
+ var i = parseInt(Math.floor(Math.log(bytes) / Math.log(base)));
+ if (i >= sizes.length) {
+ i = sizes.length - 1;
+ }
+ var val = bytes / Math.pow(base, i);
+ if (val > 999) {
+ val = val / base;
+ i++;
+ }
+ return val.toPrecision(3) + sizes[i];
+}
+
+function bytesToSpeed(bytes) {
+ return bytesToMB(bytes) + '/s';
+}
+
+function bytesToGB(bytes) {
+ if (isNaN(bytes)) {
+ return "";
+ }
+ var val = bytes / 1000000000;
+ if (val < 10) {
+ return val.toFixed(2) + sizes[3];
+ } else if (val < 100) {
+ return val.toFixed(1) + sizes[3];
+ } else {
+ return val.toFixed() + sizes[3];
+ }
+}
+
+function bytesToGB3(bytes) {
+ if (isNaN(bytes)) {
+ return "";
+ }
+ var val = bytes / 1000000000;
+ if (val < 10) {
+ return val.toFixed(1) + sizes[3];
+ } else {
+ return val.toFixed() + sizes[3];
+ }
+}
+
+function bytesToGB0(bytes) {
+ if (isNaN(bytes)) {
+ return "";
+ }
+ var val = bytes / 1000000000;
+ return val.toFixed() + sizes[3];
+}
+
+function bytesToMB(bytes) {
+ if (isNaN(bytes)) {
+ return "";
+ }
+ var val = bytes / 1000000;
+ if (val < 10) {
+ return val.toFixed(2) + sizes[2];
+ } else if (val < 100) {
+ return val.toFixed(1) + sizes[2];
+ } else {
+ return val.toFixed() + sizes[2];
+ }
+}
+
+function valueToNumber(value) {
+ return Number(value).toLocaleString();
+}
+function asNumber(num) {
+ return (num === undefined || num === null) ? 0 : Number(num);
+}
+
+function getTime() {
+ return new Date().getTime();
+}
+
+function updateObject(target, source) {
+ return Object.assign(target, source);
+}
+
+function getPDiskId(info) {
+ return info.NodeId + '-' + info.PDiskId;
+}
+
+function getVDiskId(info) {
+ var vDiskId = info.VDiskId;
+ return vDiskId.GroupID + '-' + vDiskId.GroupGeneration + '-' + vDiskId.Ring + '-' + vDiskId.Domain + '-' + vDiskId.VDisk;
+}
+
+function getNodeIdFromPeerName(peerName) {
+ return Number(peerName.split(':', 1)[0]);
+}
+
+function getPortFromPeerName(peerName) {
+ return Number(peerName.split(':', 3)[2]);
+}
+
+function getPartValuesText(part, total) {
+ if (part === total) {
+ return total;
+ } else {
+ return part + ' / ' + total;
+ }
+}
+
+function flagToColor(flag) {
+ switch (flag) {
+ case 'Green':
+ return green;
+ case 'Blue':
+ return blue;
+ case 'Yellow':
+ return yellow;
+ case 'Orange':
+ return orange;
+ case 'Red':
+ return red;
+ default:
+ return grey;
+ }
+}
+
+function isBastionProxy(hostname) {
+ return hostname === 'ydb.bastion.cloud.yandex-team.ru';
+}
+
+function isViewerProxy(hostname) {
+ return hostname === 'viewer.ydb.yandex-team.ru';
+}
+
+function getBaseUrlForHost(host) {
+ var hostname = window.location.hostname;
+ if (isBastionProxy(hostname)) {
+ return 'https://ydb.bastion.cloud.yandex-team.ru/' + host + '/';
+ } else if (isViewerProxy(hostname)) {
+ return 'https://viewer.ydb.yandex-team.ru/' + host + '/';
+ } else {
+ return 'http://' + host + '/';
+ }
+}
+
+function mapValue(min, max, value) {
+ return Math.floor(min + (max - min + 1) * value);
+}
+
+function mapColor(minColor, maxColor, value) {
+ var minR = parseInt(minColor.substr(1, 2), 16);
+ var minG = parseInt(minColor.substr(3, 2), 16);
+ var minB = parseInt(minColor.substr(5, 2), 16);
+ var maxR = parseInt(maxColor.substr(1, 2), 16);
+ var maxG = parseInt(maxColor.substr(3, 2), 16);
+ var maxB = parseInt(maxColor.substr(5, 2), 16);
+ return '#'
+ + pad2(Number(mapValue(minR, maxR, value)).toString(16))
+ + pad2(Number(mapValue(minG, maxG, value)).toString(16))
+ + pad2(Number(mapValue(minB, maxB, value)).toString(16));
+}
+
+function PoolColors(colors) {
+ if (colors === undefined) {
+ this.colors = [
+ {usage: 0.00, R: 144, G: 238, B: 144},
+ {usage: 0.75, R: 255, G: 255, B: 0},
+ {usage: 1.00, R: 255, G: 0, B: 0}
+ ];
+ } else {
+ this.colors = colors;
+ }
+}
+
+PoolColors.prototype.getPoolColor = function(usage) {
+ usage = Number(usage);
+ var idx = 1;
+ var len = this.colors.length - 1;
+ for (idx = 1; idx < len && usage > this.colors[idx].usage; idx++);
+ var a = this.colors[idx - 1];
+ var b = this.colors[idx];
+ usage = Math.max(usage, a.usage);
+ usage = Math.min(usage, b.usage);
+ var R = a.R + ((usage - a.usage) / (b.usage - a.usage)) * (b.R - a.R);
+ var G = a.G + ((usage - a.usage) / (b.usage - a.usage)) * (b.G - a.G);
+ var B = a.B + ((usage - a.usage) / (b.usage - a.usage)) * (b.B - a.B);
+ return 'rgb(' + R.toFixed() + ',' + G.toFixed() + ',' + B.toFixed() + ')';
+}
+
+//code.iamkate.com
+function Queue(){var a=[],b=0;this.getLength=function(){return a.length-b};this.isEmpty=function(){return 0==a.length};this.enqueue=function(b){a.push(b)};this.dequeue=function(){if(0!=a.length){var c=a[b];2*++b>=a.length&&(a=a.slice(b),b=0);return c}};this.peek=function(){return 0<a.length?a[b]:void 0}};
+
+function UpdateQueue(options) {
+ Object.assign(this, {}, options);
+ this.updateQueue = new Queue();
+ this.updateDelay = 0;
+ this.runUpdateQueue();
+}
+
+UpdateQueue.prototype.enqueue = function(item) {
+ if (this.updateDelay === 0) {
+ this.onUpdate(item);
+ } else {
+ this.updateQueue.enqueue(item);
+ }
+}
+
+UpdateQueue.prototype.isEmpty = function() {
+ return this.updateQueue.isEmpty();
+}
+
+UpdateQueue.prototype.getLength = function() {
+ return this.updateQueue.getLength();
+}
+
+UpdateQueue.prototype.runUpdateQueue = function() {
+ if (!this.updateQueue.isEmpty()) {
+ var update = this.updateQueue.dequeue();
+ this.onUpdate(update);
+ if (this.updateQueue.isEmpty()) {
+ console.log('done updateQueue');
+ } else {
+ setTimeout(this.runUpdateQueue.bind(this), this.updateDelay);
+ return;
+ }
+ }
+ setTimeout(this.runUpdateQueue.bind(this), 100);
+}
+
+UpdateQueue.prototype.flushUpdateQueue = function() {
+ while (!this.updateQueue.isEmpty()) {
+ this.onUpdate(this.updateQueue.dequeue());
+ }
+}
diff --git a/ydb/core/viewer/content/v2/vdisk.js b/ydb/core/viewer/content/v2/vdisk.js
index 6683769629e..6a3e1af417b 100644
--- a/ydb/core/viewer/content/v2/vdisk.js
+++ b/ydb/core/viewer/content/v2/vdisk.js
@@ -1,194 +1,194 @@
-function VDisk(update, options) {
- Object.assign(this, update, options);
- this.Id = getVDiskId(this);
- this.buildDomElement();
-}
-
-VDisk.prototype.getVDiskUrl = function() {
- var url;
- if (this.diskCell && this.diskCell.diskMap && this.diskCell.diskMap.node) {
- url = this.diskCell.diskMap.node.getBaseUrl() + 'actors/vdisks/vdisk' + pad9(this.PDiskId) + "_" + pad9(this.VDiskSlotId);
- } else if (this.PDisk && this.PDisk.Host) {
- url = getBaseUrlForHost(this.PDisk.Host + ':8765') + 'actors/vdisks/vdisk' + pad9(this.PDisk.PDiskId) + "_" + pad9(this.VDiskSlotId);
- }
- return url;
-}
-
-VDisk.prototype.onClick = function() {
- var url = this.getVDiskUrl();
- if (url) {
- window.open(url);
- }
-}
-
-VDisk.prototype.buildDomElement = function() {
- var vDiskElement = $('<div>', {class: 'vdisk ' + this.class});
- vDiskElement.tooltip({html: true}).on('show.bs.tooltip', function() {
- this.diskCell.diskMap.onShowVDiskToolTip(this);
- }.bind(this)).on('hide.bs.tooltip', function() {
- this.diskCell.diskMap.onHideVDiskToolTip(this);
- }.bind(this)).click(this.onClick.bind(this));
- this.domElement = vDiskElement[0];
- this.updateVDiskInfo();
-}
-
-VDisk.prototype.stateSeverity = {
- Initial: 3,
- LocalRecoveryError: 5,
- SyncGuidRecoveryError: 5,
- SyncGuidRecovery: 3,
- PDiskError: 5,
- OK: 1
-};
-
-VDisk.prototype.colorSeverity = {
- Grey: 0,
- Green: 1,
- Blue: 2,
- Yellow: 3,
- Orange: 4,
- Red: 5
-};
-
+function VDisk(update, options) {
+ Object.assign(this, update, options);
+ this.Id = getVDiskId(this);
+ this.buildDomElement();
+}
+
+VDisk.prototype.getVDiskUrl = function() {
+ var url;
+ if (this.diskCell && this.diskCell.diskMap && this.diskCell.diskMap.node) {
+ url = this.diskCell.diskMap.node.getBaseUrl() + 'actors/vdisks/vdisk' + pad9(this.PDiskId) + "_" + pad9(this.VDiskSlotId);
+ } else if (this.PDisk && this.PDisk.Host) {
+ url = getBaseUrlForHost(this.PDisk.Host + ':8765') + 'actors/vdisks/vdisk' + pad9(this.PDisk.PDiskId) + "_" + pad9(this.VDiskSlotId);
+ }
+ return url;
+}
+
+VDisk.prototype.onClick = function() {
+ var url = this.getVDiskUrl();
+ if (url) {
+ window.open(url);
+ }
+}
+
+VDisk.prototype.buildDomElement = function() {
+ var vDiskElement = $('<div>', {class: 'vdisk ' + this.class});
+ vDiskElement.tooltip({html: true}).on('show.bs.tooltip', function() {
+ this.diskCell.diskMap.onShowVDiskToolTip(this);
+ }.bind(this)).on('hide.bs.tooltip', function() {
+ this.diskCell.diskMap.onHideVDiskToolTip(this);
+ }.bind(this)).click(this.onClick.bind(this));
+ this.domElement = vDiskElement[0];
+ this.updateVDiskInfo();
+}
+
+VDisk.prototype.stateSeverity = {
+ Initial: 3,
+ LocalRecoveryError: 5,
+ SyncGuidRecoveryError: 5,
+ SyncGuidRecovery: 3,
+ PDiskError: 5,
+ OK: 1
+};
+
+VDisk.prototype.colorSeverity = {
+ Grey: 0,
+ Green: 1,
+ Blue: 2,
+ Yellow: 3,
+ Orange: 4,
+ Red: 5
+};
+
VDisk.prototype.getStateSeverity = function() {
var sev = this.stateSeverity[this.VDiskState];
- if (sev === undefined) {
- sev = 0;
- }
- return sev;
-}
-
+ if (sev === undefined) {
+ sev = 0;
+ }
+ return sev;
+}
+
VDisk.prototype.isErrorState = function() {
return this.getStateSeverity() === 5;
}
-VDisk.prototype.getColorSeverity = function(color) {
- var sev = this.colorSeverity[color];
- if (sev === undefined) {
- sev = 0;
- }
- return sev;
-}
-
-VDisk.prototype.updateVDiskInfo = function(update) {
- if (update) {
- if (update.AllocatedSize) {
- update.AllocatedSize = Number(update.AllocatedSize);
- }
- if (update.ReadThroughput) {
- update.ReadThroughput = Number(update.ReadThroughput);
- }
- if (update.WriteThroughput) {
- update.WriteThroughput = Number(update.WriteThroughput);
- }
- Object.assign(this, update);
- if (!update.VDiskState) {
- delete this.VDiskState;
- }
- }
- var vDisk = $(this.domElement);
- var state;
- var severity = 0;
-
- state = '<table class="tooltip-table"><tr><td>VDisk</td><td>' + this.Id + '</td></tr>';
- if (this.VDiskState) {
- state += '<tr><td>State</td><td>' + this.VDiskState + '</td></tr>';
+VDisk.prototype.getColorSeverity = function(color) {
+ var sev = this.colorSeverity[color];
+ if (sev === undefined) {
+ sev = 0;
+ }
+ return sev;
+}
+
+VDisk.prototype.updateVDiskInfo = function(update) {
+ if (update) {
+ if (update.AllocatedSize) {
+ update.AllocatedSize = Number(update.AllocatedSize);
+ }
+ if (update.ReadThroughput) {
+ update.ReadThroughput = Number(update.ReadThroughput);
+ }
+ if (update.WriteThroughput) {
+ update.WriteThroughput = Number(update.WriteThroughput);
+ }
+ Object.assign(this, update);
+ if (!update.VDiskState) {
+ delete this.VDiskState;
+ }
+ }
+ var vDisk = $(this.domElement);
+ var state;
+ var severity = 0;
+
+ state = '<table class="tooltip-table"><tr><td>VDisk</td><td>' + this.Id + '</td></tr>';
+ if (this.VDiskState) {
+ state += '<tr><td>State</td><td>' + this.VDiskState + '</td></tr>';
severity = this.getStateSeverity();
- } else {
- state += '<tr><td>State</td><td>not available</td></tr>';
- }
-
- if (this.StoragePoolName) {
- state += '<tr><td>StoragePool</td><td style="white-space: nowrap">' + this.StoragePoolName + '</td></tr>';
- }
- var rank = this.SatisfactionRank;
- if (rank) {
- if (rank.FreshRank) {
- if (rank.FreshRank.Flag !== 'Green') {
- state += '<tr><td>Fresh</td><td>' + rank.FreshRank.Flag + '</td></tr>';
- severity = Math.max(severity, Math.min(4, this.getColorSeverity(rank.FreshRank.Flag)));
- }
- }
- if (rank.LevelRank) {
- if (rank.LevelRank.Flag !== 'Green') {
- state += '<tr><td>Level</td><td>' + rank.LevelRank.Flag + '</td></tr>';
- severity = Math.max(severity, Math.min(4, this.getColorSeverity(rank.LevelRank.Flag)));
- }
- }
- if (rank.FreshRank.RankPercent) {
- state += '<tr><td>Fresh</td><td>' + rank.FreshRank.RankPercent + '%</td></tr>';
- }
- if (rank.LevelRank.RankPercent) {
- state += '<tr><td>Level</td><td>' + rank.LevelRank.RankPercent + '%</td></tr>';
- }
- }
- if (this.DiskSpace && this.DiskSpace !== 'Green') {
- state += '<tr><td>Space</td><td>' + this.DiskSpace + '</td></tr>';
+ } else {
+ state += '<tr><td>State</td><td>not available</td></tr>';
+ }
+
+ if (this.StoragePoolName) {
+ state += '<tr><td>StoragePool</td><td style="white-space: nowrap">' + this.StoragePoolName + '</td></tr>';
+ }
+ var rank = this.SatisfactionRank;
+ if (rank) {
+ if (rank.FreshRank) {
+ if (rank.FreshRank.Flag !== 'Green') {
+ state += '<tr><td>Fresh</td><td>' + rank.FreshRank.Flag + '</td></tr>';
+ severity = Math.max(severity, Math.min(4, this.getColorSeverity(rank.FreshRank.Flag)));
+ }
+ }
+ if (rank.LevelRank) {
+ if (rank.LevelRank.Flag !== 'Green') {
+ state += '<tr><td>Level</td><td>' + rank.LevelRank.Flag + '</td></tr>';
+ severity = Math.max(severity, Math.min(4, this.getColorSeverity(rank.LevelRank.Flag)));
+ }
+ }
+ if (rank.FreshRank.RankPercent) {
+ state += '<tr><td>Fresh</td><td>' + rank.FreshRank.RankPercent + '%</td></tr>';
+ }
+ if (rank.LevelRank.RankPercent) {
+ state += '<tr><td>Level</td><td>' + rank.LevelRank.RankPercent + '%</td></tr>';
+ }
+ }
+ if (this.DiskSpace && this.DiskSpace !== 'Green') {
+ state += '<tr><td>Space</td><td>' + this.DiskSpace + '</td></tr>';
severity = Math.max(severity, this.getColorSeverity(this.DiskSpace));
- }
- if (this.FrontQueues && this.FrontQueues !== 'Green') {
- state += '<tr><td>FronQueues</td><td>' + this.FrontQueues + '</td></tr>';
+ }
+ if (this.FrontQueues && this.FrontQueues !== 'Green') {
+ state += '<tr><td>FronQueues</td><td>' + this.FrontQueues + '</td></tr>';
severity = Math.max(severity, Math.min(4, this.getColorSeverity(this.FrontQueues)));
- }
+ }
dash = false;
if (this.DonorMode === true) {
state += '<tr><td>Donor</td><td>YES</td></tr>';
dash = true;
} else if (!this.Replicated) {
- state += '<tr><td>Replicated</td><td>NO</td></tr>';
- if (severity === 1) {
- severity = 2;
- }
- }
-
- var color = grey;
- switch (severity) {
- case 0:
- color = grey;
- break;
- case 1:
- color = green;
- break;
- case 2:
- color = blue;
- break;
- case 3:
- color = yellow;
- break;
- case 4:
- color = orange;
- break;
- case 5:
- color = red;
- break;
- }
-
- if (this.UnsyncedVDisks > 0) {
- state += '<tr><td>UnsyncVDisks</td><td>' + this.UnsyncedVDisks + '</td></tr>';
- }
- if (this.AllocatedSize) {
- state += '<tr><td>Allocated</td><td>' + bytesToGB(this.AllocatedSize) + '</td></tr>';
- }
- if (this.ReadThroughput) {
- state += '<tr><td>Read</td><td>' + bytesToSpeed(this.ReadThroughput) + '</td></tr>';
- }
- if (this.WriteThroughput) {
- state += '<tr><td>Write</td><td>' + bytesToSpeed(this.WriteThroughput) + '</td></tr>';
- }
- state += '</table>';
+ state += '<tr><td>Replicated</td><td>NO</td></tr>';
+ if (severity === 1) {
+ severity = 2;
+ }
+ }
+
+ var color = grey;
+ switch (severity) {
+ case 0:
+ color = grey;
+ break;
+ case 1:
+ color = green;
+ break;
+ case 2:
+ color = blue;
+ break;
+ case 3:
+ color = yellow;
+ break;
+ case 4:
+ color = orange;
+ break;
+ case 5:
+ color = red;
+ break;
+ }
+
+ if (this.UnsyncedVDisks > 0) {
+ state += '<tr><td>UnsyncVDisks</td><td>' + this.UnsyncedVDisks + '</td></tr>';
+ }
+ if (this.AllocatedSize) {
+ state += '<tr><td>Allocated</td><td>' + bytesToGB(this.AllocatedSize) + '</td></tr>';
+ }
+ if (this.ReadThroughput) {
+ state += '<tr><td>Read</td><td>' + bytesToSpeed(this.ReadThroughput) + '</td></tr>';
+ }
+ if (this.WriteThroughput) {
+ state += '<tr><td>Write</td><td>' + bytesToSpeed(this.WriteThroughput) + '</td></tr>';
+ }
+ state += '</table>';
if (dash) {
background = 'linear-gradient(45deg, forestgreen, forestgreen 8px, transparent 8px, transparent 100%)';
vDisk.css('background', background);
}
- vDisk.css('background-color', color);
- vDisk.attr('data-original-title', state);
- this.color = color;
-}
-
-VDisk.prototype.restoreTooltips = function() {
- $(this.domElement).tooltip({html: true}).on('show.bs.tooltip', function() {
- this.diskCell.diskMap.onShowVDiskToolTip(this);
- }.bind(this)).on('hide.bs.tooltip', function() {
- this.diskCell.diskMap.onHideVDiskToolTip(this);
- }.bind(this));
-}
+ vDisk.css('background-color', color);
+ vDisk.attr('data-original-title', state);
+ this.color = color;
+}
+
+VDisk.prototype.restoreTooltips = function() {
+ $(this.domElement).tooltip({html: true}).on('show.bs.tooltip', function() {
+ this.diskCell.diskMap.onShowVDiskToolTip(this);
+ }.bind(this)).on('hide.bs.tooltip', function() {
+ this.diskCell.diskMap.onHideVDiskToolTip(this);
+ }.bind(this));
+}
diff --git a/ydb/core/viewer/content/v2/viewer.css b/ydb/core/viewer/content/v2/viewer.css
index 10409042f33..4bbba73c9e8 100644
--- a/ydb/core/viewer/content/v2/viewer.css
+++ b/ydb/core/viewer/content/v2/viewer.css
@@ -1,965 +1,965 @@
-@media screen and (max-width: 1440px) {
- body {
- zoom: 80%
- }
-}
-.pseudo-nav-link {
- font-weight: bold;
-}
-table.nodelist > tbody > tr {
- height: 48px;
-}
-table.nodelist > tbody > tr:nth-child(odd) {
- background-color: #f0f0f0;
-}
-table.nodelist > thead > tr > th {
- padding: 1px 5px;
- text-align: center;
- font-size: 17px;
-}
-table.nodelist > tbody > tr > td {
- font-size: 16px;
- padding-top: 1px;
- padding-bottom: 2px;
- padding-left: 5px;
- padding-right: 5px;
-}
-table.nodelist > thead > tr > th:nth-child(1) {
- width: 84px;
-}
-table.nodelist > thead > tr > th:nth-child(2) {
- width: 200px;
-}
-table.nodelist > thead > tr > th:nth-child(3) {
- width: 95px;
-}
-table.nodelist > thead > tr > th:nth-child(4) {
- width: 80px;
-}
-table.nodelist > thead > tr > th:nth-child(5) {
- width: 52px;
-}
-table.nodelist > tbody > tr > td:nth-child(1) {
- font-weight: bold;
- font-size: 22px;
- text-align: right;
-}
-table.nodelist > tbody > tr > td:nth-child(2) a {
- font-weight: bold;
-}
-table.nodelist > tbody > tr > td:nth-child(3) {
- font-weight: 500;
- text-align: right;
-}
-table.nodelist > tbody > tr > td:nth-child(6) {
- padding-top: 1px;
-}
-table.storagelist > tbody > tr {
- height: 41px;
-}
-table.storagelist > tbody > tr:nth-child(odd) {
- background-color: #f0f0f0;
-}
-table.storagelist > thead > tr > th {
- padding: 1px 5px;
- text-align: center;
- font-size: 17px;
-}
-table.storagelist > tbody > tr > td {
- font-size: 16px;
- padding-top: 1px;
- padding-bottom: 2px;
- padding-left: 5px;
- padding-right: 5px;
- height: 41px;
-}
-table.storagelist > thead > tr > th:nth-child(1) {
- width: 100px;
-}
-table.storagelist > thead > tr > th:nth-child(2) {
- width: 90px;
-}
-table.storagelist > thead > tr > th:nth-child(3) {
- text-align: right;
- width: 60px;
-}
-table.storagelist > thead > tr > th:nth-child(4) {
- text-align: right;
- width: 90px;
-}
-table.storagelist > thead > tr > th:nth-child(5) {
- text-align: right;
- width: 90px;
-}
-table.storagelist > thead > tr > th:nth-child(6) {
- text-align: right;
- width: 90px;
-}
-table.storagelist > thead > tr > th:nth-child(7) {
- text-align: right;
- width: 90px;
-}
-table.storagelist > thead > tr > th:nth-child(8) {
- width: 75px;
-}
-table.storagelist > thead > tr > th:nth-child(9) {
- width: 270px;
-}
-table.storagelist > thead > tr > th:nth-child(10) {
- width: 800px;
-}
-
-table.storagelist > tbody > tr > td:nth-child(1) {
- font-weight: bold;
- font-size: 16px;
-}
-table.storagelist > tbody > tr > td:nth-child(2) {
- text-align: right;
- white-space: nowrap
-}
-table.storagelist > tbody > tr > td:nth-child(3) {
- text-align: right;
-}
-table.storagelist > tbody > tr > td:nth-child(4) {
- text-align: right;
-}
-table.storagelist > tbody > tr > td:nth-child(5) {
- text-align: right;
-}
-table.storagelist > tbody > tr > td:nth-child(6) {
- text-align: right;
-}
-table.storagelist > tbody > tr > td:nth-child(7) {
- text-align: right;
-}
-
-table.grouplist td {
- padding: 1px 3px;
- /*font-size: 16px;*/
-}
-/*table.nodelist > tbody > tr > td:nth-child(6) {
- padding: 1px 0px;
-}*/
-table.grouplist th {
- padding: 1px 1px;
- text-align: center;
- /*font-size: 16px;*/
-}
-table.tenantlist > tbody > tr:nth-child(odd) {
- background-color: #f0f0f0;
-}
-table.tenantlist > tbody > tr {
- height: 36px;
-}
-table.tenantlist > thead > tr > th {
- padding: 1px 5px;
- text-align: center;
- font-size: 17px;
-}
-table.tenantlist > tbody > tr > td {
- font-size: 16px;
- padding-left: 5px;
- padding-right: 5px;
- padding-top: 2px;
- padding-bottom: 2px;
- height: 32px;
-}
-table.tenantlist > thead > tr > th:nth-child(1) {
- min-width: 160px;
-}
-table.tenantlist > thead > tr > th:nth-child(2) {
- min-width: 80px;
-}
-table.tenantlist > thead > tr > th:nth-child(3) {
- width: 80px;
-}
-table.tenantlist > thead > tr > th:nth-child(4) {
- width: 80px;
-}
-table.tenantlist > tbody > tr > td:nth-child(2) {
- text-align: right;
-}
-table.tenantlist > tbody > tr > td:nth-child(3) {
- text-align: right;
-}
-table.tenantlist > tbody > tr > td:nth-child(4) {
- text-align: right;
-}
-table.tenantlist > tbody > tr > td:nth-child(5) {
- text-align: right;
-}
-table.tenantlist > tbody > tr > td:nth-child(6) {
- text-align: right;
-}
-table.tenantlist > tbody > tr > td:nth-child(7) {
- text-align: right;
-}
-table.tenantlist > tbody > tr > td:nth-child(8) {
- text-align: right;
-}
-table.tenantlist > tbody > tr > td:nth-child(9) {
- text-align: right;
-}
-table.tenantlist > tbody > tr > td:nth-child(10) {
- text-align: right;
-}
-.nodeblock {
- display: inline-block;
- width: 12px;
- height: 30px;
- background-color: #f7f7f7;
- border-radius: 3px;
- vertical-align: middle;
- border-color: darkgrey;
- border-width: 1px;
- border-style: solid;
-}
-.pool_cell {
- padding: 1px;
-}
-.pool_block {
- position: relative;
- left: 0px;
- top: 0px;
- width: 12px;
- height: 30px;
- background-color: white;
- border-radius: 3px;
- vertical-align: middle;
- border-color: darkgrey;
- border-width: 1px;
- border-style: solid;
- padding: 1px;
- box-shadow: 2px 2px 2px grey;
-}
-.pool_div {
- width: 100%;
-}
-div.pool_block > div {
- /*transition: height 1s ease;*/
-}
-.pool_span {
- position: absolute;
- left: -1px;
- top: 5px;
- font-size: 14px;
- width: 100%;
- text-align: right;
- padding-left: 3px;
- padding-right: 3px;
-}
-.nodeblock-small {
- display: inline-block;
- width: 12px;
- height: 30px;
- background-color: lightgrey;
- vertical-align: middle;
-}
-.diskblock {
- border-radius: 5px;
- border-color: #ededed;
- border-style: solid;
- background-color: #eeeeee;
- padding: 0px 2px 0px 2px;
- box-shadow: 0px 0px 5px #eeeeee;
-}
-.groupblock {
- font-size:10px;
- /*border-color: green;
- border-width: 1px;
- border-style: solid;
- border-bottom-left-radius: 3px;
- border-bottom-right-radius: 3px;
- border-top-left-radius: 3px;
- border-top-right-radius: 3px;*/
-}
-.vdiskblock {
- display: inline-block;
- height: 16px;
- font-size: 12px;
- background-color: lightgrey;
- border-color: green;
- border-width: 1px;
- border-style: solid;
- border-bottom-left-radius: 3px;
- border-bottom-right-radius: 3px;
- border-top-left-radius: 3px;
- border-top-right-radius: 3px;
- vertical-align: middle;
- cursor: pointer;
- box-shadow: 2px 2px 2px grey;
-}
-.vdiskblock-wide {
- width: 20px;
-}
-.vdiskblock-normal {
- width: 14px;
-}
-.vdiskblock-narrow {
- width: 10px;
-}
-.vdiskblock-selected {
- border-width: 3px;
-}
-.vdiskblock-small {
- display: inline-block;
- width: 8px;
- height: 12px;
-/* font-size: 12px;*/
- background-color: lightgrey;
- border-color: green;
- border-width: 1px;
- border-style: solid;
- border-bottom-left-radius: 3px;
- border-bottom-right-radius: 3px;
- border-top-left-radius: 3px;
- border-top-right-radius: 3px;
- vertical-align: middle;
- cursor: pointer;
-}
-.pdiskblock {
- width:100%;
- min-width:100px;
- height:18px;
- margin-bottom:0px;
- vertical-align:middle;
- background-color:lightgrey;
- border-color: grey;
- border-width: 1px;
- border-style: solid;
- cursor: pointer;
- box-shadow: 2px 2px 2px grey;
-}
-.tablet_map {
- display: flex;
- flex-direction: row;
- min-width: 100px;
- margin-top: 8px;
-}
-.tablet_cell {
- display: flex;
- flex-direction: column;
-}
-/*
-.tablet_label {
- text-align: left;
- font-size: 16px;
- position: relative;
- left: 3px;
- top: -1px;
- z-index: 2;
-}
-.tablet_counter {
- text-align: right;
- font-size: 12px;
- z-index: 1;
- position: relative;
- bottom: 5px;
- right: 2px;
-}*/
-.tablet_label {
- text-align: left;
- font-size: 12px;
-}
-.tablet_counter {
- text-align: right;
- font-size: 12px;
-}
-.tablet {
- display: flex;
- flex-direction: row;
- justify-content: space-evenly;
- float: left;
- width: 22px;
- height: 22px;
- color: black;
- border-color: #909090;
- border-width: 1px;
- border-style: solid;
- border-radius: 3px;
- margin: 3px;
- text-align: center;
- padding-top: 2px;
- /*cursor: pointer;*/
- box-shadow: 2px 2px 2px grey;
-}
-.partitionblock {
- float: left;
- width: 8px;
- height: 8px;
- border-color: grey;
- border-width: 1px;
- border-style: solid;
- border-radius: 2px;
- margin: 1px;
-}
-.partitionblock-small {
- float: left;
- width: 5px;
- height: 5px;
- border-color: grey;
- border-width: 1px;
- border-style: solid;
- border-radius: 1px;
- margin: 1px;
-}
-.tabletgroupblock {
- padding-bottom: 10px;
-}
-.tabletgroupname {
- font-size: 16px;
- font-weight: bold;
- padding-left: 5px;
-}
-.statecontainer {
- font-size: 10px;
-}
-.stateblock {
- display: inline-block;
- width: 20px;
- height: 10px;
- background-color: lightgrey;
- border-color: green;
- border-width: 1px;
- border-style: solid;
- border-bottom-left-radius: 3px;
- border-bottom-right-radius: 3px;
- border-top-left-radius: 3px;
- border-top-right-radius: 3px;
- vertical-align: middle;
- box-shadow: 2px 2px 2px grey;
- margin-right: 5px;
- font-size: 6px;
- text-align: center;
- cursor: default;
-}
-.usageblock {
- display: inline-block;
- width: 100%;
- min-width: 130px;
- height: 10px;
- background-color: lightgrey;
- border-color: green;
- border-width: 1px;
- border-style: solid;
- border-bottom-left-radius: 3px;
- border-bottom-right-radius: 3px;
- border-top-left-radius: 3px;
- border-top-right-radius: 3px;
- vertical-align: middle;
- box-shadow: 2px 2px 2px grey;
- margin-right: 5px;
- margin-bottom: 0px;
-}
-.latency-block {
- height: 16px;
- width: 80px;
- font-size: 11px;
- border-color: green;
- border-width: 1px;
- border-style: solid;
- border-bottom-left-radius: 3px;
- border-bottom-right-radius: 3px;
- border-top-left-radius: 3px;
- border-top-right-radius: 3px;
- text-align: center;
- vertical-align: middle;
- box-shadow: 1px 1px 1px grey;
- padding-left: 3px;
- padding-right: 3px;
-}
-.schema-bad {
- color: red;
-}
-.schema-neutral {
- color: grey;
-}
-.schema-good {
- color: steelblue;
-}
-.proplist td {
- padding: 3px;
-}
-.proplist td:first-child {
- text-align: right;
- font-weight: bold;
-}
-.schema-table th {
- padding: 1px 3px;
-}
-.schema-table td {
- padding: 1px 3px;
-}
-.tablets-table th {
- padding: 1px 3px;
-}
-.tablets-table td {
- padding: 1px 3px;
-}
-.children-table th {
- padding: 1px 3px;
-}
-.children-table td {
- padding: 1px 3px;
-}
-.groupblock > .vdiskblock {
- margin-right: 3px;
-}
-#schema-view td {
- vertical-align: top;
-}
-.totalstorage td:first-child {
- padding: 1px 3px;
- text-align: right;
- font-size: 16px;
-}
-.totalstorage td:nth-child(2) {
- padding: 1px 10px;
- text-align: right;
- font-size: 16px;
- font-weight: bold;
-}
-table.tstats > tbody > tr:nth-child(even) {
- background-color: #eee;
-}
-table.tstats > tbody > tr > td {
- font-size: 24px;
- border-right: 1px solid #ccc;
- border-bottom: 1px solid #ccc;
- padding: 3px 5px 3px 3px;
-}
-table.tstats > tbody > tr > td:nth-child(1) {
- font-size: 16px;
- font-weight: bold;
- text-align: right;
- padding-right: 10px;
- padding-top: 10px;
- padding-bottom: 10px;
-}
-table.nstats {
-}
-table.nstats > tbody > tr:nth-child(even) {
- background-color: #eee;
-}
-table.nstats > tbody > tr > td {
- font-size: 24px;
- border-right: 1px solid #ccc;
- border-bottom: 1px solid #ccc;
- padding: 3px 5px 3px 3px;
- width: 90px;
- text-align: right;
- overflow: hidden;
-}
-table.nstats > tbody > tr > th {
- font-size: 16px;
- border-right: 1px solid #ccc;
- /*border-bottom: 1px solid #ccc;*/
- padding: 3px 5px 3px 3px;
- width: 90px;
- text-align: center;
-}
-table.nstats > tbody > tr > td:nth-child(1) {
- font-size: 16px;
- font-weight: bold;
- text-align: right;
- padding-right: 10px;
- padding-top: 10px;
- padding-bottom: 10px;
-}
-td.tcounter {
- text-align: right;
- padding-right: 15px;
- text-shadow:
- -1px -1px 0 #999,
- 1px -1px 0 #999,
- -1px 1px 0 #999,
- 1px 1px 0 #999;
-}
-th.rotate {
- /* Something you can count on */
- height: 130px;
- min-width: 90px;
- white-space: nowrap;
-}
-th.rotate > div {
- transform:
- translate(80px, 43px)
- rotate(330deg);
- width: 30px;
-}
-th.rotate > div > span {
- border-bottom: 1px solid #ccc;
- padding: 8px 0px;
- font-size: 16px;
-}
-table.sqlresult td {
- padding: 1px 3px;
- /*font-size: 16px;*/
-}
-table.sqlresult th {
- padding: 1px 1px;
- text-align: center;
- /*font-size: 16px;*/
-}
-span.node_roles {
- float: right;
- height: 100%;
- font-weight: bold;
- font-size: 10px;
- padding-top: 6px;
- padding-right: 8px;
- padding-left: 8px;
-}
-.pool_row {
- display: flex;
- flex-direction: row;
-}
-.node_group_block {
- display: flex;
- flex-direction: column;
- margin-top: 10px;
-}
-.node_group_header {
- /*font-size: 20px;*/
- font-size: 16px;
- font-weight: bold;
- color: #1d4856;
- background-color: #bde8f6;
- /*background-color: #eeffff;*/
- /*background-color: #aeefff;*/
- padding: 5px 15px 5px 15px;
- border: 1px solid #6d98a6;
- border-radius: 10px;
- display: flex;
- flex-direction: row;
- box-shadow: 2px 2px 2px grey;
- min-height: 40px;
- min-width: 1500px;
- justify-content: space-between;
- cursor: pointer;
-}
-.node_group_header_pressed {
- background-color: #b5e0ee;
- margin-left: 1px;
- margin-top: 1px;
- box-shadow: 1px 1px 2px grey;
-}
-.node_group_header_name {
- padding-right: 20px;
- /*font-size: 24px;*/
- font-size: 20px;
- align-self: center;
- /*margin-left: 7px;*/
- /*margin-right: 300px;*/
- margin-top: 2px;
- /*width: 200px;*/
- white-space: nowrap;
-}
-.node_group_header_nodes {
- display: flex;
- flex-direction: row;
- justify-content: flex-end;
- align-items: center;
- margin-left: auto;
- margin-right: 5px;
-}
-.node_group_header_info {
- padding-left: 20px;
- align-self: center;
- text-align: right;
- /*margin-right: 7px;*/
- /*margin-left: auto;*/
- margin-top: 2px;
- min-width: 190px;
-}
-.node_group_container {
- margin: 10px 10px 20px 10px;
-}
-.node_row {
- display: flex;
-}
-.node_cell {
- width: 12px;
- height: 30px;
- background-color: #f7f7f7;
- border-radius: 3px;
- vertical-align: middle;
- border-color: darkgrey;
- border-width: 1px;
- border-style: solid;
- margin-left: 1px;
- margin-right: 1px;
-}
-.node_map {
- display: flex;
- /*border-radius: 0px;*/
- border: 2px solid #bbbbbb;
- border-radius: 3px;
- background-color: #aaaaaa;
- padding: 0px 0px 0px 0px;
-}
-.node_map_shadow {
- box-shadow: 2px 2px 2px grey;
-}
-.storage_group_block {
- display: flex;
- flex-direction: column;
- margin-top: 10px;
-}
-.storage_group_header {
- /*font-size: 20px;*/
- font-size: 16px;
- font-weight: bold;
- color: #1d4856;
- background-color: #bde8f6;
- /*background-color: #eeffff;*/
- /*background-color: #aeefff;*/
- padding: 5px 15px 5px 15px;
- border: 1px solid #6d98a6;
- border-radius: 10px;
- display: flex;
- flex-direction: row;
- box-shadow: 2px 2px 2px grey;
- min-height: 40px;
- min-width: 1500px;
- justify-content: space-between;
- cursor: pointer;
-}
-.storage_group_header_pressed {
- background-color: #b5e0ee;
- margin-left: 1px;
- margin-top: 1px;
- box-shadow: 1px 1px 2px grey;
-}
-.storage_group_header_name {
- padding-right: 20px;
- /*font-size: 24px;*/
- font-size: 20px;
- align-self: center;
- /*margin-left: 7px;*/
- /*margin-right: 300px;*/
- margin-top: 2px;
- /*width: 200px;*/
- white-space: nowrap;
-}
-.storage_group_header_nodes {
- display: flex;
- flex-direction: row;
- justify-content: flex-end;
- align-items: center;
- margin-left: auto;
- margin-right: 5px;
-}
-.storage_group_header_info {
- padding-left: 20px;
- align-self: center;
- text-align: right;
- /*margin-right: 7px;*/
- /*margin-left: auto;*/
- margin-top: 2px;
- min-width: 190px;
-}
-.storage_group_container {
- margin: 10px 10px 20px 10px;
-}
-.storage_vdisks {
- width: 270px;
-}
-.storage_erasure {
- text-align: center;
-}
-.storage_latency {
- text-align: center;
-}
-.disk_row {
- display: flex;
- flex-direction: row;
-}
-.disk_block {
- display: flex;
- flex-direction: column;
-}
-.pdisk_block {
- display: flex;
-}
-.vdisk_block {
- display: flex;
- flex-direction: row;
-}
-.pdisk {
- min-width: 80px;
- height: 18px;
- margin-bottom: 0px;
- margin-left: 3px;
- margin-right: 3px;
- background-color: lightgrey;
- border-color: grey;
- border-width: 1px;
- border-style: solid;
- cursor: pointer;
- box-shadow: 2px 2px 2px grey;
- position: relative;
-}
-.pdisk-wide {
- width: 300px;
-}
-.pdisk-normal {
- width: 180px;
-}
-.pdisk-narrow {
- width: 120px;
-}
-.pdisk-extra-narrow {
- width: 80px;
-}
-.pdisk_bar {
- font-size: 10px;
- vertical-align: middle;
-}
-.pdisk_bar_value {
- position: absolute;
- top: -1px;
- left: 5px;
-}
-.pdisk_icons {
- position: absolute;
- top: 1px;
- right: 1px;
- font-size: 12px;
-}
-.pdisk_icon {
- text-shadow: 0 0 1px black;
- margin-right: 2px;
-}
-.vdisk {
- height: 16px;
- font-size: 12px;
- background-color: lightgrey;
- border-color: green;
- border-width: 1px;
- border-style: solid;
- border-radius: 3px;
- cursor: pointer;
- box-shadow: 2px 2px 2px grey;
-}
-.vdisk-wide {
- width: 20px;
- margin-left: 2px;
- margin-right: 2px;
-}
-.vdisk-normal {
- width: 16px;
- margin-left: 1px;
- margin-right: 1px;
-}
-.vdisk-narrow {
- width: 10px;
- margin-left: 1px;
- margin-right: 1px;
-}
-.vdisk-selected {
- border-width: 3px;
-}
-.tooltip-inner {
- text-align: left;
- max-width: 500px;
-}
-.tooltip-table > tbody > tr > td:nth-child(1) {
- text-align: right;
- padding-right: 5px;
-}
-.node_group_switch {
- width: 80px;
- height: 32px;
-}
-.storage_group_switch {
- width: 80px;
- height: 32px;
-}
-.nav-link {
- font-weight: bold;
-}
-.progress-bar {
- transition: initial;
-}
-.disk_map {
- display: flex;
- flex-direction: row;
-}
-.disk_cell {
- display: flex;
- flex-direction: column;
- justify-content: flex-end;
- margin-left: 1px;
- margin-right: 1px;
-}
-.disks_place {
- display: flex;
- flex-direction: column;
- height: 37px;
- justify-content: flex-end;
-}
-.vdisk_place {
- display: flex;
- flex-direction: row;
- justify-content: space-around;
-}
-.pdisk_place {
- display: flex;
- flex-direction: row;
-}
-.node_id_place {
- position: relative;
-}
-.node_id {
- margin-top: 1px;
-}
-.node_icons {
- position: absolute;
- top: 1px;
- left: 1px;
- font-size: 18px;
-}
-.node_icon {
- /*text-shadow: 0 0 1px black;*/
- margin-left: 2px;
-}
-.uptime_place {
- contain: paint;
- white-space: nowrap
-}
-.mem_place {
-}
-.tenant_container {
- margin: 10px 10px 20px 10px;
-}
-.map_overview_header {
- margin-top: 10px;
- font-weight: bold;
-}
-.disk_place {
- display: flex;
- flex-direction: row;
-}
-.stats_container {
- display: flex;
- flex-direction: row;
- height: 53px;
- margin-top: 10px;
- margin-bottom: 10px;
-}
-.stats_cell {
- margin-left: 10px;
- margin-right: 10px;
- font-weight: bold;
- font-size: 18px;
-}
-.stats_name {
- text-align: right;
- /*border-color: lightblue;*/
- border-color: orange;
- border-bottom-style: solid;
-}
-.stats_value {
- text-align: right;
-}
+@media screen and (max-width: 1440px) {
+ body {
+ zoom: 80%
+ }
+}
+.pseudo-nav-link {
+ font-weight: bold;
+}
+table.nodelist > tbody > tr {
+ height: 48px;
+}
+table.nodelist > tbody > tr:nth-child(odd) {
+ background-color: #f0f0f0;
+}
+table.nodelist > thead > tr > th {
+ padding: 1px 5px;
+ text-align: center;
+ font-size: 17px;
+}
+table.nodelist > tbody > tr > td {
+ font-size: 16px;
+ padding-top: 1px;
+ padding-bottom: 2px;
+ padding-left: 5px;
+ padding-right: 5px;
+}
+table.nodelist > thead > tr > th:nth-child(1) {
+ width: 84px;
+}
+table.nodelist > thead > tr > th:nth-child(2) {
+ width: 200px;
+}
+table.nodelist > thead > tr > th:nth-child(3) {
+ width: 95px;
+}
+table.nodelist > thead > tr > th:nth-child(4) {
+ width: 80px;
+}
+table.nodelist > thead > tr > th:nth-child(5) {
+ width: 52px;
+}
+table.nodelist > tbody > tr > td:nth-child(1) {
+ font-weight: bold;
+ font-size: 22px;
+ text-align: right;
+}
+table.nodelist > tbody > tr > td:nth-child(2) a {
+ font-weight: bold;
+}
+table.nodelist > tbody > tr > td:nth-child(3) {
+ font-weight: 500;
+ text-align: right;
+}
+table.nodelist > tbody > tr > td:nth-child(6) {
+ padding-top: 1px;
+}
+table.storagelist > tbody > tr {
+ height: 41px;
+}
+table.storagelist > tbody > tr:nth-child(odd) {
+ background-color: #f0f0f0;
+}
+table.storagelist > thead > tr > th {
+ padding: 1px 5px;
+ text-align: center;
+ font-size: 17px;
+}
+table.storagelist > tbody > tr > td {
+ font-size: 16px;
+ padding-top: 1px;
+ padding-bottom: 2px;
+ padding-left: 5px;
+ padding-right: 5px;
+ height: 41px;
+}
+table.storagelist > thead > tr > th:nth-child(1) {
+ width: 100px;
+}
+table.storagelist > thead > tr > th:nth-child(2) {
+ width: 90px;
+}
+table.storagelist > thead > tr > th:nth-child(3) {
+ text-align: right;
+ width: 60px;
+}
+table.storagelist > thead > tr > th:nth-child(4) {
+ text-align: right;
+ width: 90px;
+}
+table.storagelist > thead > tr > th:nth-child(5) {
+ text-align: right;
+ width: 90px;
+}
+table.storagelist > thead > tr > th:nth-child(6) {
+ text-align: right;
+ width: 90px;
+}
+table.storagelist > thead > tr > th:nth-child(7) {
+ text-align: right;
+ width: 90px;
+}
+table.storagelist > thead > tr > th:nth-child(8) {
+ width: 75px;
+}
+table.storagelist > thead > tr > th:nth-child(9) {
+ width: 270px;
+}
+table.storagelist > thead > tr > th:nth-child(10) {
+ width: 800px;
+}
+
+table.storagelist > tbody > tr > td:nth-child(1) {
+ font-weight: bold;
+ font-size: 16px;
+}
+table.storagelist > tbody > tr > td:nth-child(2) {
+ text-align: right;
+ white-space: nowrap
+}
+table.storagelist > tbody > tr > td:nth-child(3) {
+ text-align: right;
+}
+table.storagelist > tbody > tr > td:nth-child(4) {
+ text-align: right;
+}
+table.storagelist > tbody > tr > td:nth-child(5) {
+ text-align: right;
+}
+table.storagelist > tbody > tr > td:nth-child(6) {
+ text-align: right;
+}
+table.storagelist > tbody > tr > td:nth-child(7) {
+ text-align: right;
+}
+
+table.grouplist td {
+ padding: 1px 3px;
+ /*font-size: 16px;*/
+}
+/*table.nodelist > tbody > tr > td:nth-child(6) {
+ padding: 1px 0px;
+}*/
+table.grouplist th {
+ padding: 1px 1px;
+ text-align: center;
+ /*font-size: 16px;*/
+}
+table.tenantlist > tbody > tr:nth-child(odd) {
+ background-color: #f0f0f0;
+}
+table.tenantlist > tbody > tr {
+ height: 36px;
+}
+table.tenantlist > thead > tr > th {
+ padding: 1px 5px;
+ text-align: center;
+ font-size: 17px;
+}
+table.tenantlist > tbody > tr > td {
+ font-size: 16px;
+ padding-left: 5px;
+ padding-right: 5px;
+ padding-top: 2px;
+ padding-bottom: 2px;
+ height: 32px;
+}
+table.tenantlist > thead > tr > th:nth-child(1) {
+ min-width: 160px;
+}
+table.tenantlist > thead > tr > th:nth-child(2) {
+ min-width: 80px;
+}
+table.tenantlist > thead > tr > th:nth-child(3) {
+ width: 80px;
+}
+table.tenantlist > thead > tr > th:nth-child(4) {
+ width: 80px;
+}
+table.tenantlist > tbody > tr > td:nth-child(2) {
+ text-align: right;
+}
+table.tenantlist > tbody > tr > td:nth-child(3) {
+ text-align: right;
+}
+table.tenantlist > tbody > tr > td:nth-child(4) {
+ text-align: right;
+}
+table.tenantlist > tbody > tr > td:nth-child(5) {
+ text-align: right;
+}
+table.tenantlist > tbody > tr > td:nth-child(6) {
+ text-align: right;
+}
+table.tenantlist > tbody > tr > td:nth-child(7) {
+ text-align: right;
+}
+table.tenantlist > tbody > tr > td:nth-child(8) {
+ text-align: right;
+}
+table.tenantlist > tbody > tr > td:nth-child(9) {
+ text-align: right;
+}
+table.tenantlist > tbody > tr > td:nth-child(10) {
+ text-align: right;
+}
+.nodeblock {
+ display: inline-block;
+ width: 12px;
+ height: 30px;
+ background-color: #f7f7f7;
+ border-radius: 3px;
+ vertical-align: middle;
+ border-color: darkgrey;
+ border-width: 1px;
+ border-style: solid;
+}
+.pool_cell {
+ padding: 1px;
+}
+.pool_block {
+ position: relative;
+ left: 0px;
+ top: 0px;
+ width: 12px;
+ height: 30px;
+ background-color: white;
+ border-radius: 3px;
+ vertical-align: middle;
+ border-color: darkgrey;
+ border-width: 1px;
+ border-style: solid;
+ padding: 1px;
+ box-shadow: 2px 2px 2px grey;
+}
+.pool_div {
+ width: 100%;
+}
+div.pool_block > div {
+ /*transition: height 1s ease;*/
+}
+.pool_span {
+ position: absolute;
+ left: -1px;
+ top: 5px;
+ font-size: 14px;
+ width: 100%;
+ text-align: right;
+ padding-left: 3px;
+ padding-right: 3px;
+}
+.nodeblock-small {
+ display: inline-block;
+ width: 12px;
+ height: 30px;
+ background-color: lightgrey;
+ vertical-align: middle;
+}
+.diskblock {
+ border-radius: 5px;
+ border-color: #ededed;
+ border-style: solid;
+ background-color: #eeeeee;
+ padding: 0px 2px 0px 2px;
+ box-shadow: 0px 0px 5px #eeeeee;
+}
+.groupblock {
+ font-size:10px;
+ /*border-color: green;
+ border-width: 1px;
+ border-style: solid;
+ border-bottom-left-radius: 3px;
+ border-bottom-right-radius: 3px;
+ border-top-left-radius: 3px;
+ border-top-right-radius: 3px;*/
+}
+.vdiskblock {
+ display: inline-block;
+ height: 16px;
+ font-size: 12px;
+ background-color: lightgrey;
+ border-color: green;
+ border-width: 1px;
+ border-style: solid;
+ border-bottom-left-radius: 3px;
+ border-bottom-right-radius: 3px;
+ border-top-left-radius: 3px;
+ border-top-right-radius: 3px;
+ vertical-align: middle;
+ cursor: pointer;
+ box-shadow: 2px 2px 2px grey;
+}
+.vdiskblock-wide {
+ width: 20px;
+}
+.vdiskblock-normal {
+ width: 14px;
+}
+.vdiskblock-narrow {
+ width: 10px;
+}
+.vdiskblock-selected {
+ border-width: 3px;
+}
+.vdiskblock-small {
+ display: inline-block;
+ width: 8px;
+ height: 12px;
+/* font-size: 12px;*/
+ background-color: lightgrey;
+ border-color: green;
+ border-width: 1px;
+ border-style: solid;
+ border-bottom-left-radius: 3px;
+ border-bottom-right-radius: 3px;
+ border-top-left-radius: 3px;
+ border-top-right-radius: 3px;
+ vertical-align: middle;
+ cursor: pointer;
+}
+.pdiskblock {
+ width:100%;
+ min-width:100px;
+ height:18px;
+ margin-bottom:0px;
+ vertical-align:middle;
+ background-color:lightgrey;
+ border-color: grey;
+ border-width: 1px;
+ border-style: solid;
+ cursor: pointer;
+ box-shadow: 2px 2px 2px grey;
+}
+.tablet_map {
+ display: flex;
+ flex-direction: row;
+ min-width: 100px;
+ margin-top: 8px;
+}
+.tablet_cell {
+ display: flex;
+ flex-direction: column;
+}
+/*
+.tablet_label {
+ text-align: left;
+ font-size: 16px;
+ position: relative;
+ left: 3px;
+ top: -1px;
+ z-index: 2;
+}
+.tablet_counter {
+ text-align: right;
+ font-size: 12px;
+ z-index: 1;
+ position: relative;
+ bottom: 5px;
+ right: 2px;
+}*/
+.tablet_label {
+ text-align: left;
+ font-size: 12px;
+}
+.tablet_counter {
+ text-align: right;
+ font-size: 12px;
+}
+.tablet {
+ display: flex;
+ flex-direction: row;
+ justify-content: space-evenly;
+ float: left;
+ width: 22px;
+ height: 22px;
+ color: black;
+ border-color: #909090;
+ border-width: 1px;
+ border-style: solid;
+ border-radius: 3px;
+ margin: 3px;
+ text-align: center;
+ padding-top: 2px;
+ /*cursor: pointer;*/
+ box-shadow: 2px 2px 2px grey;
+}
+.partitionblock {
+ float: left;
+ width: 8px;
+ height: 8px;
+ border-color: grey;
+ border-width: 1px;
+ border-style: solid;
+ border-radius: 2px;
+ margin: 1px;
+}
+.partitionblock-small {
+ float: left;
+ width: 5px;
+ height: 5px;
+ border-color: grey;
+ border-width: 1px;
+ border-style: solid;
+ border-radius: 1px;
+ margin: 1px;
+}
+.tabletgroupblock {
+ padding-bottom: 10px;
+}
+.tabletgroupname {
+ font-size: 16px;
+ font-weight: bold;
+ padding-left: 5px;
+}
+.statecontainer {
+ font-size: 10px;
+}
+.stateblock {
+ display: inline-block;
+ width: 20px;
+ height: 10px;
+ background-color: lightgrey;
+ border-color: green;
+ border-width: 1px;
+ border-style: solid;
+ border-bottom-left-radius: 3px;
+ border-bottom-right-radius: 3px;
+ border-top-left-radius: 3px;
+ border-top-right-radius: 3px;
+ vertical-align: middle;
+ box-shadow: 2px 2px 2px grey;
+ margin-right: 5px;
+ font-size: 6px;
+ text-align: center;
+ cursor: default;
+}
+.usageblock {
+ display: inline-block;
+ width: 100%;
+ min-width: 130px;
+ height: 10px;
+ background-color: lightgrey;
+ border-color: green;
+ border-width: 1px;
+ border-style: solid;
+ border-bottom-left-radius: 3px;
+ border-bottom-right-radius: 3px;
+ border-top-left-radius: 3px;
+ border-top-right-radius: 3px;
+ vertical-align: middle;
+ box-shadow: 2px 2px 2px grey;
+ margin-right: 5px;
+ margin-bottom: 0px;
+}
+.latency-block {
+ height: 16px;
+ width: 80px;
+ font-size: 11px;
+ border-color: green;
+ border-width: 1px;
+ border-style: solid;
+ border-bottom-left-radius: 3px;
+ border-bottom-right-radius: 3px;
+ border-top-left-radius: 3px;
+ border-top-right-radius: 3px;
+ text-align: center;
+ vertical-align: middle;
+ box-shadow: 1px 1px 1px grey;
+ padding-left: 3px;
+ padding-right: 3px;
+}
+.schema-bad {
+ color: red;
+}
+.schema-neutral {
+ color: grey;
+}
+.schema-good {
+ color: steelblue;
+}
+.proplist td {
+ padding: 3px;
+}
+.proplist td:first-child {
+ text-align: right;
+ font-weight: bold;
+}
+.schema-table th {
+ padding: 1px 3px;
+}
+.schema-table td {
+ padding: 1px 3px;
+}
+.tablets-table th {
+ padding: 1px 3px;
+}
+.tablets-table td {
+ padding: 1px 3px;
+}
+.children-table th {
+ padding: 1px 3px;
+}
+.children-table td {
+ padding: 1px 3px;
+}
+.groupblock > .vdiskblock {
+ margin-right: 3px;
+}
+#schema-view td {
+ vertical-align: top;
+}
+.totalstorage td:first-child {
+ padding: 1px 3px;
+ text-align: right;
+ font-size: 16px;
+}
+.totalstorage td:nth-child(2) {
+ padding: 1px 10px;
+ text-align: right;
+ font-size: 16px;
+ font-weight: bold;
+}
+table.tstats > tbody > tr:nth-child(even) {
+ background-color: #eee;
+}
+table.tstats > tbody > tr > td {
+ font-size: 24px;
+ border-right: 1px solid #ccc;
+ border-bottom: 1px solid #ccc;
+ padding: 3px 5px 3px 3px;
+}
+table.tstats > tbody > tr > td:nth-child(1) {
+ font-size: 16px;
+ font-weight: bold;
+ text-align: right;
+ padding-right: 10px;
+ padding-top: 10px;
+ padding-bottom: 10px;
+}
+table.nstats {
+}
+table.nstats > tbody > tr:nth-child(even) {
+ background-color: #eee;
+}
+table.nstats > tbody > tr > td {
+ font-size: 24px;
+ border-right: 1px solid #ccc;
+ border-bottom: 1px solid #ccc;
+ padding: 3px 5px 3px 3px;
+ width: 90px;
+ text-align: right;
+ overflow: hidden;
+}
+table.nstats > tbody > tr > th {
+ font-size: 16px;
+ border-right: 1px solid #ccc;
+ /*border-bottom: 1px solid #ccc;*/
+ padding: 3px 5px 3px 3px;
+ width: 90px;
+ text-align: center;
+}
+table.nstats > tbody > tr > td:nth-child(1) {
+ font-size: 16px;
+ font-weight: bold;
+ text-align: right;
+ padding-right: 10px;
+ padding-top: 10px;
+ padding-bottom: 10px;
+}
+td.tcounter {
+ text-align: right;
+ padding-right: 15px;
+ text-shadow:
+ -1px -1px 0 #999,
+ 1px -1px 0 #999,
+ -1px 1px 0 #999,
+ 1px 1px 0 #999;
+}
+th.rotate {
+ /* Something you can count on */
+ height: 130px;
+ min-width: 90px;
+ white-space: nowrap;
+}
+th.rotate > div {
+ transform:
+ translate(80px, 43px)
+ rotate(330deg);
+ width: 30px;
+}
+th.rotate > div > span {
+ border-bottom: 1px solid #ccc;
+ padding: 8px 0px;
+ font-size: 16px;
+}
+table.sqlresult td {
+ padding: 1px 3px;
+ /*font-size: 16px;*/
+}
+table.sqlresult th {
+ padding: 1px 1px;
+ text-align: center;
+ /*font-size: 16px;*/
+}
+span.node_roles {
+ float: right;
+ height: 100%;
+ font-weight: bold;
+ font-size: 10px;
+ padding-top: 6px;
+ padding-right: 8px;
+ padding-left: 8px;
+}
+.pool_row {
+ display: flex;
+ flex-direction: row;
+}
+.node_group_block {
+ display: flex;
+ flex-direction: column;
+ margin-top: 10px;
+}
+.node_group_header {
+ /*font-size: 20px;*/
+ font-size: 16px;
+ font-weight: bold;
+ color: #1d4856;
+ background-color: #bde8f6;
+ /*background-color: #eeffff;*/
+ /*background-color: #aeefff;*/
+ padding: 5px 15px 5px 15px;
+ border: 1px solid #6d98a6;
+ border-radius: 10px;
+ display: flex;
+ flex-direction: row;
+ box-shadow: 2px 2px 2px grey;
+ min-height: 40px;
+ min-width: 1500px;
+ justify-content: space-between;
+ cursor: pointer;
+}
+.node_group_header_pressed {
+ background-color: #b5e0ee;
+ margin-left: 1px;
+ margin-top: 1px;
+ box-shadow: 1px 1px 2px grey;
+}
+.node_group_header_name {
+ padding-right: 20px;
+ /*font-size: 24px;*/
+ font-size: 20px;
+ align-self: center;
+ /*margin-left: 7px;*/
+ /*margin-right: 300px;*/
+ margin-top: 2px;
+ /*width: 200px;*/
+ white-space: nowrap;
+}
+.node_group_header_nodes {
+ display: flex;
+ flex-direction: row;
+ justify-content: flex-end;
+ align-items: center;
+ margin-left: auto;
+ margin-right: 5px;
+}
+.node_group_header_info {
+ padding-left: 20px;
+ align-self: center;
+ text-align: right;
+ /*margin-right: 7px;*/
+ /*margin-left: auto;*/
+ margin-top: 2px;
+ min-width: 190px;
+}
+.node_group_container {
+ margin: 10px 10px 20px 10px;
+}
+.node_row {
+ display: flex;
+}
+.node_cell {
+ width: 12px;
+ height: 30px;
+ background-color: #f7f7f7;
+ border-radius: 3px;
+ vertical-align: middle;
+ border-color: darkgrey;
+ border-width: 1px;
+ border-style: solid;
+ margin-left: 1px;
+ margin-right: 1px;
+}
+.node_map {
+ display: flex;
+ /*border-radius: 0px;*/
+ border: 2px solid #bbbbbb;
+ border-radius: 3px;
+ background-color: #aaaaaa;
+ padding: 0px 0px 0px 0px;
+}
+.node_map_shadow {
+ box-shadow: 2px 2px 2px grey;
+}
+.storage_group_block {
+ display: flex;
+ flex-direction: column;
+ margin-top: 10px;
+}
+.storage_group_header {
+ /*font-size: 20px;*/
+ font-size: 16px;
+ font-weight: bold;
+ color: #1d4856;
+ background-color: #bde8f6;
+ /*background-color: #eeffff;*/
+ /*background-color: #aeefff;*/
+ padding: 5px 15px 5px 15px;
+ border: 1px solid #6d98a6;
+ border-radius: 10px;
+ display: flex;
+ flex-direction: row;
+ box-shadow: 2px 2px 2px grey;
+ min-height: 40px;
+ min-width: 1500px;
+ justify-content: space-between;
+ cursor: pointer;
+}
+.storage_group_header_pressed {
+ background-color: #b5e0ee;
+ margin-left: 1px;
+ margin-top: 1px;
+ box-shadow: 1px 1px 2px grey;
+}
+.storage_group_header_name {
+ padding-right: 20px;
+ /*font-size: 24px;*/
+ font-size: 20px;
+ align-self: center;
+ /*margin-left: 7px;*/
+ /*margin-right: 300px;*/
+ margin-top: 2px;
+ /*width: 200px;*/
+ white-space: nowrap;
+}
+.storage_group_header_nodes {
+ display: flex;
+ flex-direction: row;
+ justify-content: flex-end;
+ align-items: center;
+ margin-left: auto;
+ margin-right: 5px;
+}
+.storage_group_header_info {
+ padding-left: 20px;
+ align-self: center;
+ text-align: right;
+ /*margin-right: 7px;*/
+ /*margin-left: auto;*/
+ margin-top: 2px;
+ min-width: 190px;
+}
+.storage_group_container {
+ margin: 10px 10px 20px 10px;
+}
+.storage_vdisks {
+ width: 270px;
+}
+.storage_erasure {
+ text-align: center;
+}
+.storage_latency {
+ text-align: center;
+}
+.disk_row {
+ display: flex;
+ flex-direction: row;
+}
+.disk_block {
+ display: flex;
+ flex-direction: column;
+}
+.pdisk_block {
+ display: flex;
+}
+.vdisk_block {
+ display: flex;
+ flex-direction: row;
+}
+.pdisk {
+ min-width: 80px;
+ height: 18px;
+ margin-bottom: 0px;
+ margin-left: 3px;
+ margin-right: 3px;
+ background-color: lightgrey;
+ border-color: grey;
+ border-width: 1px;
+ border-style: solid;
+ cursor: pointer;
+ box-shadow: 2px 2px 2px grey;
+ position: relative;
+}
+.pdisk-wide {
+ width: 300px;
+}
+.pdisk-normal {
+ width: 180px;
+}
+.pdisk-narrow {
+ width: 120px;
+}
+.pdisk-extra-narrow {
+ width: 80px;
+}
+.pdisk_bar {
+ font-size: 10px;
+ vertical-align: middle;
+}
+.pdisk_bar_value {
+ position: absolute;
+ top: -1px;
+ left: 5px;
+}
+.pdisk_icons {
+ position: absolute;
+ top: 1px;
+ right: 1px;
+ font-size: 12px;
+}
+.pdisk_icon {
+ text-shadow: 0 0 1px black;
+ margin-right: 2px;
+}
+.vdisk {
+ height: 16px;
+ font-size: 12px;
+ background-color: lightgrey;
+ border-color: green;
+ border-width: 1px;
+ border-style: solid;
+ border-radius: 3px;
+ cursor: pointer;
+ box-shadow: 2px 2px 2px grey;
+}
+.vdisk-wide {
+ width: 20px;
+ margin-left: 2px;
+ margin-right: 2px;
+}
+.vdisk-normal {
+ width: 16px;
+ margin-left: 1px;
+ margin-right: 1px;
+}
+.vdisk-narrow {
+ width: 10px;
+ margin-left: 1px;
+ margin-right: 1px;
+}
+.vdisk-selected {
+ border-width: 3px;
+}
+.tooltip-inner {
+ text-align: left;
+ max-width: 500px;
+}
+.tooltip-table > tbody > tr > td:nth-child(1) {
+ text-align: right;
+ padding-right: 5px;
+}
+.node_group_switch {
+ width: 80px;
+ height: 32px;
+}
+.storage_group_switch {
+ width: 80px;
+ height: 32px;
+}
+.nav-link {
+ font-weight: bold;
+}
+.progress-bar {
+ transition: initial;
+}
+.disk_map {
+ display: flex;
+ flex-direction: row;
+}
+.disk_cell {
+ display: flex;
+ flex-direction: column;
+ justify-content: flex-end;
+ margin-left: 1px;
+ margin-right: 1px;
+}
+.disks_place {
+ display: flex;
+ flex-direction: column;
+ height: 37px;
+ justify-content: flex-end;
+}
+.vdisk_place {
+ display: flex;
+ flex-direction: row;
+ justify-content: space-around;
+}
+.pdisk_place {
+ display: flex;
+ flex-direction: row;
+}
+.node_id_place {
+ position: relative;
+}
+.node_id {
+ margin-top: 1px;
+}
+.node_icons {
+ position: absolute;
+ top: 1px;
+ left: 1px;
+ font-size: 18px;
+}
+.node_icon {
+ /*text-shadow: 0 0 1px black;*/
+ margin-left: 2px;
+}
+.uptime_place {
+ contain: paint;
+ white-space: nowrap
+}
+.mem_place {
+}
+.tenant_container {
+ margin: 10px 10px 20px 10px;
+}
+.map_overview_header {
+ margin-top: 10px;
+ font-weight: bold;
+}
+.disk_place {
+ display: flex;
+ flex-direction: row;
+}
+.stats_container {
+ display: flex;
+ flex-direction: row;
+ height: 53px;
+ margin-top: 10px;
+ margin-bottom: 10px;
+}
+.stats_cell {
+ margin-left: 10px;
+ margin-right: 10px;
+ font-weight: bold;
+ font-size: 18px;
+}
+.stats_name {
+ text-align: right;
+ /*border-color: lightblue;*/
+ border-color: orange;
+ border-bottom-style: solid;
+}
+.stats_value {
+ text-align: right;
+}
diff --git a/ydb/core/viewer/content/v2/viewer.js b/ydb/core/viewer/content/v2/viewer.js
index 81684c7d6fb..74686cbdbf9 100644
--- a/ydb/core/viewer/content/v2/viewer.js
+++ b/ydb/core/viewer/content/v2/viewer.js
@@ -1,709 +1,709 @@
-var Parameters = {};
-
-function ViewerNodes(options) {
- Object.assign(this, {
- overallRefreshTimeout: 60000,
- maxDiffRequests: 10
- }, options);
- this.nodeView = null;
- this.netView = null;
- this.sysInfoRequestNum = 0;
- this.nodeInfoRequestNum = 0;
- $.ajax({
- url: "json/config",
- success: this.onConfig.bind(this)
- });
-}
-
-ViewerNodes.prototype.onConfig = function(data) {
- this.config = data;
- $.ajax({
- url: "json/nodelist",
- success: this.onNodeList.bind(this),
- error: this.onNodeList.bind(this)
- });
-}
-
-ViewerNodes.prototype.onNodeList = function(nlist) {
- if (this.nodeView === null) {
- this.nodeView = new NodeView({
- domElement: $('#nodes_view')[0],
- config: this.config
- });
- }
- if (nlist) {
- var nlen = nlist.length;
- for (var i = 0; i < nlen; i++) {
- var node = new Node(nlist[i]);
- this.nodeView.addNode(node);
- }
- this.nodeView.rebuild();
- }
- this.refreshOverall();
- this.refreshOverallInterval = setInterval(this.refreshOverall.bind(this), this.overallRefreshTimeout);
-}
-
-ViewerNodes.prototype.onSysInfo = function(data) {
- data.since = this.sysInfoChangeTime;
- data.refreshTimeout = this.overallRefreshTimeout;
- this.nodeView.onSysInfo(data);
- if (data.ResponseTime != 0) {
- this.sysInfoChangeTime = data.ResponseTime;
- }
-}
-
-ViewerNodes.prototype.onNodeInfo = function(data) {
- data.since = this.nodeInfoChangeTime;
- data.refreshTimeout = this.overallRefreshTimeout;
- //this.netView.onNodeInfo(data);
- if (data.ResponseTime != 0) {
- this.nodeInfoChangeTime = data.ResponseTime;
- }
-}
-
-ViewerNodes.prototype.onPDiskInfo = function(data) {
- this.nodeView.onPDiskInfo(data);
-}
-
-ViewerNodes.prototype.onVDiskInfo = function(data) {
- this.nodeView.onVDiskInfo(data);
-}
-
-ViewerNodes.prototype.onDisconnect = function() {
- this.nodeView.onDisconnect();
-}
-
-ViewerNodes.prototype.refreshPDiskInfo = function() {
-// console.log('refreshOverall (pdiskinfo)');
- var request = {
- alive: 0,
- enums: 1,
- merge: 0,
- timeout: 10000
- };
- $.ajax({
- url: 'json/pdiskinfo',
- data: request,
- success: this.onPDiskInfo.bind(this)
- });
-}
-
-ViewerNodes.prototype.refreshVDiskInfo = function() {
-// console.log('refreshOverall (vdiskinfo)');
- var request = {
- alive: 0,
- enums: 1,
- merge: 0,
- timeout: 10000
- };
- $.ajax({
- url: 'json/vdiskinfo',
- data: request,
- success: this.onVDiskInfo.bind(this)
- });
-}
-
-ViewerNodes.prototype.refreshSysInfo = function() {
-// console.log('refreshOverall (sysinfo)');
- if (++this.sysInfoRequestNum >= this.maxDiffRequests) {
- this.sysInfoRequestNum = 0;
- delete this.sysInfoChangeTime;
- }
-
- var request = {
- alive: 0,
- enums: 1,
- timeout: 10000
- };
- $.ajax({
- url: 'json/sysinfo',
- data: request,
- success: this.onSysInfo.bind(this),
- error: this.onDisconnect.bind(this)
- });
-}
-
-ViewerNodes.prototype.refreshNodeInfo = function() {
-// console.log('refreshOverall (nodeinfo)');
- if (++this.nodeInfoRequestNum >= this.maxDiffRequests) {
- this.nodeInfoRequestNum = 0;
- delete this.nodeInfoChangeTime;
- }
-
- var request = {
- alive: 0,
- enums: 0,
- merge: 0,
- timeout: 10000/*,
- since: this.nodeInfoChangeTime*/
- };
- $.ajax({
- url: 'json/nodeinfo',
- data: request,
- success: this.onNodeInfo.bind(this)
- });
-}
-
-ViewerNodes.prototype.refreshOverall = function() {
- this.refreshSysInfo();
- //this.refreshNodeInfo();
+var Parameters = {};
+
+function ViewerNodes(options) {
+ Object.assign(this, {
+ overallRefreshTimeout: 60000,
+ maxDiffRequests: 10
+ }, options);
+ this.nodeView = null;
+ this.netView = null;
+ this.sysInfoRequestNum = 0;
+ this.nodeInfoRequestNum = 0;
+ $.ajax({
+ url: "json/config",
+ success: this.onConfig.bind(this)
+ });
+}
+
+ViewerNodes.prototype.onConfig = function(data) {
+ this.config = data;
+ $.ajax({
+ url: "json/nodelist",
+ success: this.onNodeList.bind(this),
+ error: this.onNodeList.bind(this)
+ });
+}
+
+ViewerNodes.prototype.onNodeList = function(nlist) {
+ if (this.nodeView === null) {
+ this.nodeView = new NodeView({
+ domElement: $('#nodes_view')[0],
+ config: this.config
+ });
+ }
+ if (nlist) {
+ var nlen = nlist.length;
+ for (var i = 0; i < nlen; i++) {
+ var node = new Node(nlist[i]);
+ this.nodeView.addNode(node);
+ }
+ this.nodeView.rebuild();
+ }
+ this.refreshOverall();
+ this.refreshOverallInterval = setInterval(this.refreshOverall.bind(this), this.overallRefreshTimeout);
+}
+
+ViewerNodes.prototype.onSysInfo = function(data) {
+ data.since = this.sysInfoChangeTime;
+ data.refreshTimeout = this.overallRefreshTimeout;
+ this.nodeView.onSysInfo(data);
+ if (data.ResponseTime != 0) {
+ this.sysInfoChangeTime = data.ResponseTime;
+ }
+}
+
+ViewerNodes.prototype.onNodeInfo = function(data) {
+ data.since = this.nodeInfoChangeTime;
+ data.refreshTimeout = this.overallRefreshTimeout;
+ //this.netView.onNodeInfo(data);
+ if (data.ResponseTime != 0) {
+ this.nodeInfoChangeTime = data.ResponseTime;
+ }
+}
+
+ViewerNodes.prototype.onPDiskInfo = function(data) {
+ this.nodeView.onPDiskInfo(data);
+}
+
+ViewerNodes.prototype.onVDiskInfo = function(data) {
+ this.nodeView.onVDiskInfo(data);
+}
+
+ViewerNodes.prototype.onDisconnect = function() {
+ this.nodeView.onDisconnect();
+}
+
+ViewerNodes.prototype.refreshPDiskInfo = function() {
+// console.log('refreshOverall (pdiskinfo)');
+ var request = {
+ alive: 0,
+ enums: 1,
+ merge: 0,
+ timeout: 10000
+ };
+ $.ajax({
+ url: 'json/pdiskinfo',
+ data: request,
+ success: this.onPDiskInfo.bind(this)
+ });
+}
+
+ViewerNodes.prototype.refreshVDiskInfo = function() {
+// console.log('refreshOverall (vdiskinfo)');
+ var request = {
+ alive: 0,
+ enums: 1,
+ merge: 0,
+ timeout: 10000
+ };
+ $.ajax({
+ url: 'json/vdiskinfo',
+ data: request,
+ success: this.onVDiskInfo.bind(this)
+ });
+}
+
+ViewerNodes.prototype.refreshSysInfo = function() {
+// console.log('refreshOverall (sysinfo)');
+ if (++this.sysInfoRequestNum >= this.maxDiffRequests) {
+ this.sysInfoRequestNum = 0;
+ delete this.sysInfoChangeTime;
+ }
+
+ var request = {
+ alive: 0,
+ enums: 1,
+ timeout: 10000
+ };
+ $.ajax({
+ url: 'json/sysinfo',
+ data: request,
+ success: this.onSysInfo.bind(this),
+ error: this.onDisconnect.bind(this)
+ });
+}
+
+ViewerNodes.prototype.refreshNodeInfo = function() {
+// console.log('refreshOverall (nodeinfo)');
+ if (++this.nodeInfoRequestNum >= this.maxDiffRequests) {
+ this.nodeInfoRequestNum = 0;
+ delete this.nodeInfoChangeTime;
+ }
+
+ var request = {
+ alive: 0,
+ enums: 0,
+ merge: 0,
+ timeout: 10000/*,
+ since: this.nodeInfoChangeTime*/
+ };
+ $.ajax({
+ url: 'json/nodeinfo',
+ data: request,
+ success: this.onNodeInfo.bind(this)
+ });
+}
+
+ViewerNodes.prototype.refreshOverall = function() {
+ this.refreshSysInfo();
+ //this.refreshNodeInfo();
//this.refreshPDiskInfo();
//this.refreshVDiskInfo();
-}
-
-ViewerNodes.prototype.onNodeGroupChange = function(obj) {
- $(obj).parent().find('.btn-info').removeClass('btn-info').addClass('btn-default');
- $(obj).data('original', $(obj).html());
- $(obj).html('<img src="throbber.gif">');
- delete this.nodeView.groupOrder;
- switch (obj.value) {
- case 'dc':
- this.nodeView.getNodeGroupName = function(node) { return node.getDC(); }
- break;
- case 'domain':
- this.nodeView.getNodeGroupName = function(node) { return node.getDomainName(); }
- break;
- case 'rack':
- this.nodeView.getNodeGroupName = function(node) { return node.getRackName(); }
- break;
- case 'host':
- this.nodeView.getNodeGroupName = function(node) { return node.getHostName(); }
- break;
- case 'id':
- this.nodeView.getNodeGroupName = function(node) { return node.getIdGroup(); }
- this.nodeView.groupOrder = function(prev, next) { return Number(prev.split('..')[0]) < Number(next.split('..')[0]); }
- break;
- case 'role':
- this.nodeView.getNodeGroupName = function(node) { return node.getRoleName(); }
- break;
- case 'tenant':
- this.nodeView.getNodeGroupName = function(node) { return node.getTenantName(); }
- break;
- case 'status':
- this.nodeView.getNodeGroupName = function(node) { return node.getStatus(); }
- break;
- case 'uptime':
- this.nodeView.getNodeGroupName = function(node) { return node.getAge(); }
- break;
- case 'version':
- this.nodeView.getNodeGroupName = function(node) { return node.getVersion(); }
- break;
- case 'usage':
- this.nodeView.getNodeGroupName = function(node) { return Math.floor((node.getDiskUsage() * 100 + 0.5) / 5) * 5 + '%'; }
- this.nodeView.groupOrder = function(prev, next) { return Number(prev.substring(0, prev.length - 1)) > Number(next.substring(0, next.length - 1)); }
- break;
- }
- this.nodeView.rebuild();
- $(obj).html($(obj).data('original'));
- $(obj).removeClass('btn-default').addClass('btn-info');
-}
-
-
-
-
-function ViewerOverview(options) {
- Object.assign(this, {
- overallRefreshTimeout: 10000,
- maxDiffRequests: 10
- }, options);
- this.overview = null;
- this.sysInfoRequestNum = 0;
- this.nodeInfoRequestNum = 0;
- $.ajax({
- url: "json/config",
- success: this.onConfig.bind(this)
- });
-}
-
-ViewerOverview.prototype.onConfig = function(data) {
- this.config = data;
- $.ajax({
- url: "json/nodelist",
- success: this.onNodeList.bind(this),
- error: this.onNodeList.bind(this)
- });
-}
-
-ViewerOverview.prototype.onNodeList = function(nlist) {
- if (this.overview === null) {
- this.overview = new Overview({
- domElement: $('#overview_view')[0],
- config: this.config
- });
- }
- if (nlist) {
- var nlen = nlist.length;
- for (var i = 0; i < nlen; i++) {
- var node = new Node(nlist[i]);
- this.overview.addNode(node);
- }
- this.overview.rebuild();
- }
- this.refreshOverall();
- this.refreshOverallInterval = setInterval(this.refreshOverall.bind(this), this.overallRefreshTimeout);
-}
-
-ViewerOverview.prototype.onSysInfo = function(data) {
- data.since = this.sysInfoChangeTime;
- data.refreshTimeout = this.overallRefreshTimeout;
- this.overview.onSysInfo(data);
- if (data.ResponseTime != 0) {
- this.sysInfoChangeTime = data.ResponseTime;
- }
-}
-
-ViewerOverview.prototype.onDisconnect = function() {
- this.overview.onDisconnect();
-}
-
-ViewerOverview.prototype.refreshSysInfo = function() {
-// console.log('refreshOverall (sysinfo)');
- if (++this.sysInfoRequestNum >= this.maxDiffRequests) {
- this.sysInfoRequestNum = 0;
- delete this.sysInfoChangeTime;
- }
-
- var request = {
- alive: 0,
- enums: 1,
- timeout: 10000,
- since: this.sysInfoChangeTime
- };
- $.ajax({
- url: 'json/sysinfo',
- data: request,
- success: this.onSysInfo.bind(this),
- error: this.onDisconnect.bind(this)
- });
-}
-
-ViewerOverview.prototype.refreshOverall = function() {
- this.refreshSysInfo();
-}
-
-
-
-
-function ViewerCpu(options) {
- Object.assign(this, {
- overallRefreshTimeout: 10000,
- maxDiffRequests: 10
- }, options);
- this.cpuView = null;
- this.sysInfoRequestNum = 0;
- this.nodeInfoRequestNum = 0;
- $.ajax({
- url: "json/config",
- success: this.onConfig.bind(this)
- });
-}
-
-ViewerCpu.prototype.onConfig = function(data) {
- this.config = data;
- $.ajax({
- url: "json/nodelist",
- success: this.onNodeList.bind(this),
- error: this.onNodeList.bind(this)
- });
-}
-
-ViewerCpu.prototype.onNodeList = function(nlist) {
- if (this.cpuView === null) {
- this.cpuView = new CpuView({
- domElement: $('#cpu_view')[0],
- config: this.config
- });
- }
- if (nlist) {
- var nlen = nlist.length;
- for (var i = 0; i < nlen; i++) {
- var node = new Node(nlist[i]);
- this.cpuView.addNode(node);
- }
- this.cpuView.rebuild();
- }
- this.refreshOverall();
- this.refreshOverallInterval = setInterval(this.refreshOverall.bind(this), this.overallRefreshTimeout);
-}
-
-ViewerCpu.prototype.onSysInfo = function(data) {
- data.since = this.sysInfoChangeTime;
- data.refreshTimeout = this.overallRefreshTimeout;
- this.cpuView.onSysInfo(data);
- if (data.ResponseTime != 0) {
- this.sysInfoChangeTime = data.ResponseTime;
- }
-}
-
-ViewerCpu.prototype.onDisconnect = function() {
- this.cpuView.onDisconnect();
-}
-
-ViewerCpu.prototype.refreshSysInfo = function() {
-// console.log('refreshOverall (sysinfo)');
- if (++this.sysInfoRequestNum >= this.maxDiffRequests) {
- this.sysInfoRequestNum = 0;
- delete this.sysInfoChangeTime;
- }
-
- var request = {
- alive: 0,
- enums: 1,
- timeout: 10000,
- since: this.sysInfoChangeTime
- };
- $.ajax({
- url: 'json/sysinfo',
- data: request,
- success: this.onSysInfo.bind(this),
- error: this.onDisconnect.bind(this)
- });
-}
-
-ViewerCpu.prototype.refreshOverall = function() {
- this.refreshSysInfo();
-}
-
-
-
-
-function ViewerStorage(options) {
- Object.assign(this, {
- overallRefreshTimeout: 10000,
- maxDiffRequests: 10
- }, options);
- this.storageView = null;
- this.sysInfoRequestNum = 0;
- this.nodeInfoRequestNum = 0;
- $.ajax({
- url: "json/config",
- success: this.onConfig.bind(this)
- });
-}
-
-ViewerStorage.prototype.onConfig = function(data) {
- this.config = data;
- $.ajax({
- url: "json/nodelist",
- success: this.onNodeList.bind(this),
- error: this.onNodeList.bind(this)
- });
-}
-
-ViewerStorage.prototype.onNodeList = function(nlist) {
- if (this.storageView === null) {
- this.storageView = new StorageView({
- domElement: $('#storage_view')[0],
- config: this.config
- });
- }
- if (nlist) {
- var nlen = nlist.length;
- for (var i = 0; i < nlen; i++) {
- var node = new Node(nlist[i]);
- this.storageView.addNode(node);
- }
- this.storageView.rebuild();
- }
- this.refreshOverall();
- this.refreshOverallInterval = setInterval(this.refreshOverall.bind(this), this.overallRefreshTimeout);
-}
-
-ViewerStorage.prototype.onStorage = function(data) {
- this.storageView.onStorage(data);
-}
-
-ViewerStorage.prototype.onDisconnect = function() {
- this.storageView.onDisconnect();
-}
-
-ViewerStorage.prototype.refreshStorage = function() {
-// console.log('refreshOverall (storage)');
- var request = {
- timeout: 10000
- };
- $.ajax({
- url: 'json/storage',
- data: request,
- success: this.onStorage.bind(this)
- });
-}
-
-ViewerStorage.prototype.refreshOverall = function() {
- this.refreshStorage();
-}
-
-ViewerStorage.prototype.manuallyRefreshOverall = function() {
- clearInterval(this.refreshOverallInterval);
- this.refreshOverallInterval = setInterval(this.refreshOverall.bind(this), this.overallRefreshTimeout);
- this.refreshOverall();
-}
-
-var colorsOrder = ['Red', 'Orange', 'Yellow', 'Blue', 'Green', 'Grey'];
-
-ViewerStorage.prototype.onStorageGroupChange = function(obj) {
- $(obj).parent().find('.btn-info').removeClass('btn-info').addClass('btn-default');
- $(obj).data('original', $(obj).html());
- $(obj).html('<img src="throbber.gif">');
- switch (obj.value) {
- case 'pool':
- this.storageView.getStorageGroupName = function(storage) { return storage.StoragePool.Name; }
- this.storageView.getStorageGroupHeader = function(storageGroup) { return bytesToGB0(storageGroup.allocatedSizeBytes) + ' / ' + storageGroup.storageTotal + ' groups'; }
- this.storageView.groupOrder = function(prev, next) { return prev < next; }
- break;
- case 'color':
- this.storageView.getStorageGroupName = function(storage) { return storage.getColor(); }
- this.storageView.getStorageGroupHeader = function(storageGroup) { return storageGroup.storageTotal + ' groups'; }
- this.storageView.groupOrder = function(prev, next) { return colorsOrder.indexOf(prev) < colorsOrder.indexOf(next); }
- break;
- case 'status':
- this.storageView.getStorageGroupName = function(storage) { return storage.getStatus(); }
- this.storageView.getStorageGroupHeader = function(storageGroup) { return storageGroup.storageTotal + ' groups'; }
- this.storageView.groupOrder = function(prev, next) { return prev < next; }
- break;
- case 'usage':
- this.storageView.getStorageGroupName = function(storage) { return Math.floor((storage.getUsage() * 100 + 0.5) / 5) * 5 + '%'; }
- this.storageView.getStorageGroupHeader = function(storageGroup) { return storageGroup.storageTotal + ' groups'; }
- this.storageView.groupOrder = function(prev, next) { return Number(prev.substring(0, prev.length - 1)) > Number(next.substring(0, next.length - 1)); }
- break;
- case 'missing':
- this.storageView.getStorageGroupName = function(storage) { var md = storage.getMissingDisks(); return md === 0 ? "Complete" : '-' + md; }
- this.storageView.getStorageGroupHeader = function(storageGroup) { return storageGroup.storageTotal + ' groups'; }
- this.storageView.groupOrder = function(prev, next) { return prev < next; }
- break;
- }
- this.storageView.rebuild();
- $(obj).html($(obj).data('original'));
- $(obj).removeClass('btn-default').addClass('btn-info');
-}
-
-
-function ViewerTenants(options) {
- Object.assign(this, {
- overallRefreshTimeout: 30000,
- maxDiffRequests: 10
- }, options);
- this.tenantView = null;
- this.sysInfoRequestNum = 0;
- this.nodeInfoRequestNum = 0;
- $.ajax({
- url: "json/config",
- success: this.onConfig.bind(this)
- });
-}
-
-ViewerTenants.prototype.onConfig = function(data) {
- this.config = data;
- $.ajax({
- url: "json/nodelist",
- success: this.onNodeList.bind(this),
- error: this.onNodeList.bind(this)
- });
-}
-
-ViewerTenants.prototype.onNodeList = function(nlist) {
- if (this.tenantView === null) {
- this.tenantView = new TenantView({
- domElement: $('#tenants_view')[0],
- config: this.config
- });
- }
- if (nlist) {
- var nlen = nlist.length;
- for (var i = 0; i < nlen; i++) {
- var node = new Node(nlist[i]);
-// this.nodeView.addNode(node);
- }
- }
- this.refreshOverall();
- this.refreshOverallInterval = setInterval(this.refreshOverall.bind(this), this.overallRefreshTimeout);
-}
-
-ViewerTenants.prototype.onSysInfo = function(data) {
- data.since = this.sysInfoChangeTime;
- data.refreshTimeout = this.overallRefreshTimeout;
- this.tenantView.onSysInfo(data);
- if (data.ResponseTime != 0) {
- this.sysInfoChangeTime = data.ResponseTime;
- }
-}
-
-ViewerTenants.prototype.onDisconnect = function() {
- this.tenantView.onDisconnect();
-}
-
-ViewerTenants.prototype.refreshSysInfo = function() {
-// console.log('refreshOverall (sysinfo)');
- if (++this.sysInfoRequestNum >= this.maxDiffRequests) {
- this.sysInfoRequestNum = 0;
- delete this.sysInfoChangeTime;
- }
-
- var request = {
- alive: 0,
- enums: 1,
- timeout: 10000,
- since: this.sysInfoChangeTime
- };
- $.ajax({
- url: 'json/sysinfo',
- data: request,
- success: this.onSysInfo.bind(this),
- error: this.onDisconnect.bind(this)
- });
-}
-
-ViewerTenants.prototype.refreshOverall = function() {
- this.refreshSysInfo();
-}
-
-
-function ViewerNetwork(options) {
- Object.assign(this, {
- overallRefreshTimeout: 30000,
- maxDiffRequests: 10
- }, options);
- this.netView = null;
- this.sysInfoRequestNum = 0;
- this.nodeInfoRequestNum = 0;
- $.ajax({
- url: "json/config",
- success: this.onConfig.bind(this)
- });
-}
-
-ViewerNetwork.prototype.onConfig = function(data) {
- this.config = data;
- $.ajax({
- url: "json/nodelist",
- success: this.onNodeList.bind(this),
- error: this.onNodeList.bind(this)
- });
-}
-
-ViewerNetwork.prototype.onNodeList = function(nlist) {
- if (this.netView === null) {
- this.netView = new NetView({
- domElement: $('#net_view')[0],
- config: this.config
- });
- }
- if (nlist) {
- var nlen = nlist.length;
- for (var i = 0; i < nlen; i++) {
- var node = new Node(nlist[i]);
- this.netView.addNode(node);
- }
- this.netView.rebuild();
- }
- this.refreshOverall();
- this.refreshOverallInterval = setInterval(this.refreshOverall.bind(this), this.overallRefreshTimeout);
-}
-
-ViewerNetwork.prototype.onSysInfo = function(data) {
- data.since = this.sysInfoChangeTime;
- data.refreshTimeout = this.overallRefreshTimeout;
- this.netView.onSysInfo(data);
- if (data.ResponseTime != 0) {
- this.sysInfoChangeTime = data.ResponseTime;
- }
-}
-
-ViewerNetwork.prototype.onNodeInfo = function(data) {
- data.since = this.nodeInfoChangeTime;
- data.refreshTimeout = this.overallRefreshTimeout;
- this.netView.onNodeInfo(data);
- if (data.ResponseTime != 0) {
- this.nodeInfoChangeTime = data.ResponseTime;
- }
-}
-
-
-ViewerNetwork.prototype.onDisconnect = function() {
- this.netView.onDisconnect();
-}
-
-ViewerNetwork.prototype.refreshSysInfo = function() {
-// console.log('refreshOverall (sysinfo)');
- if (++this.sysInfoRequestNum >= this.maxDiffRequests) {
- this.sysInfoRequestNum = 0;
- delete this.sysInfoChangeTime;
- }
-
- var request = {
- alive: 0,
- enums: 1,
- timeout: 10000,
- since: this.sysInfoChangeTime
- };
- $.ajax({
- url: 'json/sysinfo',
- data: request,
- success: this.onSysInfo.bind(this),
- error: this.onDisconnect.bind(this)
- });
-}
-
-ViewerNetwork.prototype.refreshNodeInfo = function() {
-// console.log('refreshOverall (nodeinfo)');
- if (++this.nodeInfoRequestNum >= this.maxDiffRequests) {
- this.nodeInfoRequestNum = 0;
- delete this.nodeInfoChangeTime;
- }
-
- var request = {
- alive: 0,
- enums: 0,
- merge: 0,
- timeout: 10000/*,
- since: this.nodeInfoChangeTime*/
- };
- $.ajax({
- url: 'json/nodeinfo',
- data: request,
- success: this.onNodeInfo.bind(this)
- });
-}
-
-ViewerNetwork.prototype.refreshOverall = function() {
- this.refreshSysInfo();
- this.refreshNodeInfo();
-}
-
-
-
-var viewer = null;
-
-function onNodeGroupChange(obj) {
- viewer.onNodeGroupChange(obj);
- return false;
-}
-
-function onStorageGroupChange(obj) {
- viewer.onStorageGroupChange(obj);
- return false;
-}
-
-function mainNodes() {
- viewer = new ViewerNodes();
-}
-
-function mainOverview() {
- viewer = new ViewerOverview();
-}
-
-function mainCpu() {
- viewer = new ViewerCpu();
-}
-
-function mainStorage() {
- viewer = new ViewerStorage();
-}
-
-function mainTenants() {
- viewer = new ViewerTenants();
-}
-
-function mainNetwork() {
- viewer = new ViewerNetwork();
-}
+}
+
+ViewerNodes.prototype.onNodeGroupChange = function(obj) {
+ $(obj).parent().find('.btn-info').removeClass('btn-info').addClass('btn-default');
+ $(obj).data('original', $(obj).html());
+ $(obj).html('<img src="throbber.gif">');
+ delete this.nodeView.groupOrder;
+ switch (obj.value) {
+ case 'dc':
+ this.nodeView.getNodeGroupName = function(node) { return node.getDC(); }
+ break;
+ case 'domain':
+ this.nodeView.getNodeGroupName = function(node) { return node.getDomainName(); }
+ break;
+ case 'rack':
+ this.nodeView.getNodeGroupName = function(node) { return node.getRackName(); }
+ break;
+ case 'host':
+ this.nodeView.getNodeGroupName = function(node) { return node.getHostName(); }
+ break;
+ case 'id':
+ this.nodeView.getNodeGroupName = function(node) { return node.getIdGroup(); }
+ this.nodeView.groupOrder = function(prev, next) { return Number(prev.split('..')[0]) < Number(next.split('..')[0]); }
+ break;
+ case 'role':
+ this.nodeView.getNodeGroupName = function(node) { return node.getRoleName(); }
+ break;
+ case 'tenant':
+ this.nodeView.getNodeGroupName = function(node) { return node.getTenantName(); }
+ break;
+ case 'status':
+ this.nodeView.getNodeGroupName = function(node) { return node.getStatus(); }
+ break;
+ case 'uptime':
+ this.nodeView.getNodeGroupName = function(node) { return node.getAge(); }
+ break;
+ case 'version':
+ this.nodeView.getNodeGroupName = function(node) { return node.getVersion(); }
+ break;
+ case 'usage':
+ this.nodeView.getNodeGroupName = function(node) { return Math.floor((node.getDiskUsage() * 100 + 0.5) / 5) * 5 + '%'; }
+ this.nodeView.groupOrder = function(prev, next) { return Number(prev.substring(0, prev.length - 1)) > Number(next.substring(0, next.length - 1)); }
+ break;
+ }
+ this.nodeView.rebuild();
+ $(obj).html($(obj).data('original'));
+ $(obj).removeClass('btn-default').addClass('btn-info');
+}
+
+
+
+
+function ViewerOverview(options) {
+ Object.assign(this, {
+ overallRefreshTimeout: 10000,
+ maxDiffRequests: 10
+ }, options);
+ this.overview = null;
+ this.sysInfoRequestNum = 0;
+ this.nodeInfoRequestNum = 0;
+ $.ajax({
+ url: "json/config",
+ success: this.onConfig.bind(this)
+ });
+}
+
+ViewerOverview.prototype.onConfig = function(data) {
+ this.config = data;
+ $.ajax({
+ url: "json/nodelist",
+ success: this.onNodeList.bind(this),
+ error: this.onNodeList.bind(this)
+ });
+}
+
+ViewerOverview.prototype.onNodeList = function(nlist) {
+ if (this.overview === null) {
+ this.overview = new Overview({
+ domElement: $('#overview_view')[0],
+ config: this.config
+ });
+ }
+ if (nlist) {
+ var nlen = nlist.length;
+ for (var i = 0; i < nlen; i++) {
+ var node = new Node(nlist[i]);
+ this.overview.addNode(node);
+ }
+ this.overview.rebuild();
+ }
+ this.refreshOverall();
+ this.refreshOverallInterval = setInterval(this.refreshOverall.bind(this), this.overallRefreshTimeout);
+}
+
+ViewerOverview.prototype.onSysInfo = function(data) {
+ data.since = this.sysInfoChangeTime;
+ data.refreshTimeout = this.overallRefreshTimeout;
+ this.overview.onSysInfo(data);
+ if (data.ResponseTime != 0) {
+ this.sysInfoChangeTime = data.ResponseTime;
+ }
+}
+
+ViewerOverview.prototype.onDisconnect = function() {
+ this.overview.onDisconnect();
+}
+
+ViewerOverview.prototype.refreshSysInfo = function() {
+// console.log('refreshOverall (sysinfo)');
+ if (++this.sysInfoRequestNum >= this.maxDiffRequests) {
+ this.sysInfoRequestNum = 0;
+ delete this.sysInfoChangeTime;
+ }
+
+ var request = {
+ alive: 0,
+ enums: 1,
+ timeout: 10000,
+ since: this.sysInfoChangeTime
+ };
+ $.ajax({
+ url: 'json/sysinfo',
+ data: request,
+ success: this.onSysInfo.bind(this),
+ error: this.onDisconnect.bind(this)
+ });
+}
+
+ViewerOverview.prototype.refreshOverall = function() {
+ this.refreshSysInfo();
+}
+
+
+
+
+function ViewerCpu(options) {
+ Object.assign(this, {
+ overallRefreshTimeout: 10000,
+ maxDiffRequests: 10
+ }, options);
+ this.cpuView = null;
+ this.sysInfoRequestNum = 0;
+ this.nodeInfoRequestNum = 0;
+ $.ajax({
+ url: "json/config",
+ success: this.onConfig.bind(this)
+ });
+}
+
+ViewerCpu.prototype.onConfig = function(data) {
+ this.config = data;
+ $.ajax({
+ url: "json/nodelist",
+ success: this.onNodeList.bind(this),
+ error: this.onNodeList.bind(this)
+ });
+}
+
+ViewerCpu.prototype.onNodeList = function(nlist) {
+ if (this.cpuView === null) {
+ this.cpuView = new CpuView({
+ domElement: $('#cpu_view')[0],
+ config: this.config
+ });
+ }
+ if (nlist) {
+ var nlen = nlist.length;
+ for (var i = 0; i < nlen; i++) {
+ var node = new Node(nlist[i]);
+ this.cpuView.addNode(node);
+ }
+ this.cpuView.rebuild();
+ }
+ this.refreshOverall();
+ this.refreshOverallInterval = setInterval(this.refreshOverall.bind(this), this.overallRefreshTimeout);
+}
+
+ViewerCpu.prototype.onSysInfo = function(data) {
+ data.since = this.sysInfoChangeTime;
+ data.refreshTimeout = this.overallRefreshTimeout;
+ this.cpuView.onSysInfo(data);
+ if (data.ResponseTime != 0) {
+ this.sysInfoChangeTime = data.ResponseTime;
+ }
+}
+
+ViewerCpu.prototype.onDisconnect = function() {
+ this.cpuView.onDisconnect();
+}
+
+ViewerCpu.prototype.refreshSysInfo = function() {
+// console.log('refreshOverall (sysinfo)');
+ if (++this.sysInfoRequestNum >= this.maxDiffRequests) {
+ this.sysInfoRequestNum = 0;
+ delete this.sysInfoChangeTime;
+ }
+
+ var request = {
+ alive: 0,
+ enums: 1,
+ timeout: 10000,
+ since: this.sysInfoChangeTime
+ };
+ $.ajax({
+ url: 'json/sysinfo',
+ data: request,
+ success: this.onSysInfo.bind(this),
+ error: this.onDisconnect.bind(this)
+ });
+}
+
+ViewerCpu.prototype.refreshOverall = function() {
+ this.refreshSysInfo();
+}
+
+
+
+
+function ViewerStorage(options) {
+ Object.assign(this, {
+ overallRefreshTimeout: 10000,
+ maxDiffRequests: 10
+ }, options);
+ this.storageView = null;
+ this.sysInfoRequestNum = 0;
+ this.nodeInfoRequestNum = 0;
+ $.ajax({
+ url: "json/config",
+ success: this.onConfig.bind(this)
+ });
+}
+
+ViewerStorage.prototype.onConfig = function(data) {
+ this.config = data;
+ $.ajax({
+ url: "json/nodelist",
+ success: this.onNodeList.bind(this),
+ error: this.onNodeList.bind(this)
+ });
+}
+
+ViewerStorage.prototype.onNodeList = function(nlist) {
+ if (this.storageView === null) {
+ this.storageView = new StorageView({
+ domElement: $('#storage_view')[0],
+ config: this.config
+ });
+ }
+ if (nlist) {
+ var nlen = nlist.length;
+ for (var i = 0; i < nlen; i++) {
+ var node = new Node(nlist[i]);
+ this.storageView.addNode(node);
+ }
+ this.storageView.rebuild();
+ }
+ this.refreshOverall();
+ this.refreshOverallInterval = setInterval(this.refreshOverall.bind(this), this.overallRefreshTimeout);
+}
+
+ViewerStorage.prototype.onStorage = function(data) {
+ this.storageView.onStorage(data);
+}
+
+ViewerStorage.prototype.onDisconnect = function() {
+ this.storageView.onDisconnect();
+}
+
+ViewerStorage.prototype.refreshStorage = function() {
+// console.log('refreshOverall (storage)');
+ var request = {
+ timeout: 10000
+ };
+ $.ajax({
+ url: 'json/storage',
+ data: request,
+ success: this.onStorage.bind(this)
+ });
+}
+
+ViewerStorage.prototype.refreshOverall = function() {
+ this.refreshStorage();
+}
+
+ViewerStorage.prototype.manuallyRefreshOverall = function() {
+ clearInterval(this.refreshOverallInterval);
+ this.refreshOverallInterval = setInterval(this.refreshOverall.bind(this), this.overallRefreshTimeout);
+ this.refreshOverall();
+}
+
+var colorsOrder = ['Red', 'Orange', 'Yellow', 'Blue', 'Green', 'Grey'];
+
+ViewerStorage.prototype.onStorageGroupChange = function(obj) {
+ $(obj).parent().find('.btn-info').removeClass('btn-info').addClass('btn-default');
+ $(obj).data('original', $(obj).html());
+ $(obj).html('<img src="throbber.gif">');
+ switch (obj.value) {
+ case 'pool':
+ this.storageView.getStorageGroupName = function(storage) { return storage.StoragePool.Name; }
+ this.storageView.getStorageGroupHeader = function(storageGroup) { return bytesToGB0(storageGroup.allocatedSizeBytes) + ' / ' + storageGroup.storageTotal + ' groups'; }
+ this.storageView.groupOrder = function(prev, next) { return prev < next; }
+ break;
+ case 'color':
+ this.storageView.getStorageGroupName = function(storage) { return storage.getColor(); }
+ this.storageView.getStorageGroupHeader = function(storageGroup) { return storageGroup.storageTotal + ' groups'; }
+ this.storageView.groupOrder = function(prev, next) { return colorsOrder.indexOf(prev) < colorsOrder.indexOf(next); }
+ break;
+ case 'status':
+ this.storageView.getStorageGroupName = function(storage) { return storage.getStatus(); }
+ this.storageView.getStorageGroupHeader = function(storageGroup) { return storageGroup.storageTotal + ' groups'; }
+ this.storageView.groupOrder = function(prev, next) { return prev < next; }
+ break;
+ case 'usage':
+ this.storageView.getStorageGroupName = function(storage) { return Math.floor((storage.getUsage() * 100 + 0.5) / 5) * 5 + '%'; }
+ this.storageView.getStorageGroupHeader = function(storageGroup) { return storageGroup.storageTotal + ' groups'; }
+ this.storageView.groupOrder = function(prev, next) { return Number(prev.substring(0, prev.length - 1)) > Number(next.substring(0, next.length - 1)); }
+ break;
+ case 'missing':
+ this.storageView.getStorageGroupName = function(storage) { var md = storage.getMissingDisks(); return md === 0 ? "Complete" : '-' + md; }
+ this.storageView.getStorageGroupHeader = function(storageGroup) { return storageGroup.storageTotal + ' groups'; }
+ this.storageView.groupOrder = function(prev, next) { return prev < next; }
+ break;
+ }
+ this.storageView.rebuild();
+ $(obj).html($(obj).data('original'));
+ $(obj).removeClass('btn-default').addClass('btn-info');
+}
+
+
+function ViewerTenants(options) {
+ Object.assign(this, {
+ overallRefreshTimeout: 30000,
+ maxDiffRequests: 10
+ }, options);
+ this.tenantView = null;
+ this.sysInfoRequestNum = 0;
+ this.nodeInfoRequestNum = 0;
+ $.ajax({
+ url: "json/config",
+ success: this.onConfig.bind(this)
+ });
+}
+
+ViewerTenants.prototype.onConfig = function(data) {
+ this.config = data;
+ $.ajax({
+ url: "json/nodelist",
+ success: this.onNodeList.bind(this),
+ error: this.onNodeList.bind(this)
+ });
+}
+
+ViewerTenants.prototype.onNodeList = function(nlist) {
+ if (this.tenantView === null) {
+ this.tenantView = new TenantView({
+ domElement: $('#tenants_view')[0],
+ config: this.config
+ });
+ }
+ if (nlist) {
+ var nlen = nlist.length;
+ for (var i = 0; i < nlen; i++) {
+ var node = new Node(nlist[i]);
+// this.nodeView.addNode(node);
+ }
+ }
+ this.refreshOverall();
+ this.refreshOverallInterval = setInterval(this.refreshOverall.bind(this), this.overallRefreshTimeout);
+}
+
+ViewerTenants.prototype.onSysInfo = function(data) {
+ data.since = this.sysInfoChangeTime;
+ data.refreshTimeout = this.overallRefreshTimeout;
+ this.tenantView.onSysInfo(data);
+ if (data.ResponseTime != 0) {
+ this.sysInfoChangeTime = data.ResponseTime;
+ }
+}
+
+ViewerTenants.prototype.onDisconnect = function() {
+ this.tenantView.onDisconnect();
+}
+
+ViewerTenants.prototype.refreshSysInfo = function() {
+// console.log('refreshOverall (sysinfo)');
+ if (++this.sysInfoRequestNum >= this.maxDiffRequests) {
+ this.sysInfoRequestNum = 0;
+ delete this.sysInfoChangeTime;
+ }
+
+ var request = {
+ alive: 0,
+ enums: 1,
+ timeout: 10000,
+ since: this.sysInfoChangeTime
+ };
+ $.ajax({
+ url: 'json/sysinfo',
+ data: request,
+ success: this.onSysInfo.bind(this),
+ error: this.onDisconnect.bind(this)
+ });
+}
+
+ViewerTenants.prototype.refreshOverall = function() {
+ this.refreshSysInfo();
+}
+
+
+function ViewerNetwork(options) {
+ Object.assign(this, {
+ overallRefreshTimeout: 30000,
+ maxDiffRequests: 10
+ }, options);
+ this.netView = null;
+ this.sysInfoRequestNum = 0;
+ this.nodeInfoRequestNum = 0;
+ $.ajax({
+ url: "json/config",
+ success: this.onConfig.bind(this)
+ });
+}
+
+ViewerNetwork.prototype.onConfig = function(data) {
+ this.config = data;
+ $.ajax({
+ url: "json/nodelist",
+ success: this.onNodeList.bind(this),
+ error: this.onNodeList.bind(this)
+ });
+}
+
+ViewerNetwork.prototype.onNodeList = function(nlist) {
+ if (this.netView === null) {
+ this.netView = new NetView({
+ domElement: $('#net_view')[0],
+ config: this.config
+ });
+ }
+ if (nlist) {
+ var nlen = nlist.length;
+ for (var i = 0; i < nlen; i++) {
+ var node = new Node(nlist[i]);
+ this.netView.addNode(node);
+ }
+ this.netView.rebuild();
+ }
+ this.refreshOverall();
+ this.refreshOverallInterval = setInterval(this.refreshOverall.bind(this), this.overallRefreshTimeout);
+}
+
+ViewerNetwork.prototype.onSysInfo = function(data) {
+ data.since = this.sysInfoChangeTime;
+ data.refreshTimeout = this.overallRefreshTimeout;
+ this.netView.onSysInfo(data);
+ if (data.ResponseTime != 0) {
+ this.sysInfoChangeTime = data.ResponseTime;
+ }
+}
+
+ViewerNetwork.prototype.onNodeInfo = function(data) {
+ data.since = this.nodeInfoChangeTime;
+ data.refreshTimeout = this.overallRefreshTimeout;
+ this.netView.onNodeInfo(data);
+ if (data.ResponseTime != 0) {
+ this.nodeInfoChangeTime = data.ResponseTime;
+ }
+}
+
+
+ViewerNetwork.prototype.onDisconnect = function() {
+ this.netView.onDisconnect();
+}
+
+ViewerNetwork.prototype.refreshSysInfo = function() {
+// console.log('refreshOverall (sysinfo)');
+ if (++this.sysInfoRequestNum >= this.maxDiffRequests) {
+ this.sysInfoRequestNum = 0;
+ delete this.sysInfoChangeTime;
+ }
+
+ var request = {
+ alive: 0,
+ enums: 1,
+ timeout: 10000,
+ since: this.sysInfoChangeTime
+ };
+ $.ajax({
+ url: 'json/sysinfo',
+ data: request,
+ success: this.onSysInfo.bind(this),
+ error: this.onDisconnect.bind(this)
+ });
+}
+
+ViewerNetwork.prototype.refreshNodeInfo = function() {
+// console.log('refreshOverall (nodeinfo)');
+ if (++this.nodeInfoRequestNum >= this.maxDiffRequests) {
+ this.nodeInfoRequestNum = 0;
+ delete this.nodeInfoChangeTime;
+ }
+
+ var request = {
+ alive: 0,
+ enums: 0,
+ merge: 0,
+ timeout: 10000/*,
+ since: this.nodeInfoChangeTime*/
+ };
+ $.ajax({
+ url: 'json/nodeinfo',
+ data: request,
+ success: this.onNodeInfo.bind(this)
+ });
+}
+
+ViewerNetwork.prototype.refreshOverall = function() {
+ this.refreshSysInfo();
+ this.refreshNodeInfo();
+}
+
+
+
+var viewer = null;
+
+function onNodeGroupChange(obj) {
+ viewer.onNodeGroupChange(obj);
+ return false;
+}
+
+function onStorageGroupChange(obj) {
+ viewer.onStorageGroupChange(obj);
+ return false;
+}
+
+function mainNodes() {
+ viewer = new ViewerNodes();
+}
+
+function mainOverview() {
+ viewer = new ViewerOverview();
+}
+
+function mainCpu() {
+ viewer = new ViewerCpu();
+}
+
+function mainStorage() {
+ viewer = new ViewerStorage();
+}
+
+function mainTenants() {
+ viewer = new ViewerTenants();
+}
+
+function mainNetwork() {
+ viewer = new ViewerNetwork();
+}
diff --git a/ydb/core/viewer/content/viewer.js b/ydb/core/viewer/content/viewer.js
index ecd1dd89cbb..1108f42278c 100644
--- a/ydb/core/viewer/content/viewer.js
+++ b/ydb/core/viewer/content/viewer.js
@@ -1,974 +1,974 @@
-'use strict';
-
-var Nodes = {};
-var NodesCount = 0;
-var Groups = {};
-var Tablets = {};
-var TabletsCount = 0;
-var newtablets = [];
-var newtablets_running = false;
-var tabletblock_class = "tabletblock";
-var grey = "grey";
-var green = "lightgreen";
-var blue = "#6495ED"; // #4169E1 #4682B4
-var yellow = "yellow";
-var orange = "orange";
-var red = "red";
-var TabletRequest = { request: 0, alive: 1, enums: 1, filter: "(State!=Deleted)" };
-var PDiskRequest = { request: 0, alive: 1, enums: 1 };
-var VDiskRequest = { request: 0, alive: 1, enums: 1 };
-var BSGroupRequest = { request: 0, alive: 1, enums: 1 };
-var SysRequest = { request: 0, alive: 1, enums: 1 };
-var NodeRequest = { request: 0, alive: 1, merge: 0 };
-var VDisksDone = false;
-var VDiskColors = {
- Initial: grey,
- LocalRecoveryError: red,
- SyncGuidRecoveryError: red,
- SyncGuidRecovery: yellow,
- OK: green
-};
-var DefaultRefreshTimeout = 500;
-var refreshTimeoutBSGroup = function() { return DefaultRefreshTimeout + 1200; }
-var refreshTimeoutPDisk = function() { return DefaultRefreshTimeout + 1500; }
-var refreshTimeoutVDisk = function() { return DefaultRefreshTimeout + 2300; }
-var refreshTimeoutNode = function() { return DefaultRefreshTimeout + 500; }
-var refreshTimeoutTablet = function() { return DefaultRefreshTimeout + 700; }
-var refreshTimeoutSys = function() { return DefaultRefreshTimeout + 800; }
-var refreshTimeoutHive = function() { return DefaultRefreshTimeout + 2100; }
-var StatsAnimateStop = {opacity: 1};
-var StatsAnimateStart = {opacity: 0.5};
-var StatsAnimateDuration = 10000;
-var Parameters = {};
-var SchemaTabletElements = {};
-var VDiskBlockWidthClass = "vdiskblock-wide";
-var MaxWideVDisks = 4;
-
-function getPDiskCell(node, pDiskId, pDiskData) {
- if (node.PDisks === undefined) {
- node.PDisks = {};
- }
- var pDisk = node.PDisks[pDiskId];
- if (pDisk === undefined) {
- pDisk = node.PDisks[pDiskId] = {};
- }
-
- var pDiskCell = pDisk.CellDomElement;
- if (pDiskCell === undefined) {
- if (pDiskData === undefined)
- return null;
- pDiskCell = document.createElement("td");
- pDiskCell.innerHTML = "<div class='diskblock'><table style='width:100%'><tr class='vdiskspart'></tr><tr><td class='pdiskspart' style='padding: 2px 1px 1px 1px' colspan='99'></td></tr></table></div>";
- pDiskCell.PDiskId = pDiskId;
- var path = pDiskData.Path;
- pDiskCell.PDiskPath = path;
-
- var insertPoint = node.DomElement.lastChild;
- while (insertPoint !== null) {
- if (insertPoint.PDiskId === undefined || path >= insertPoint.PDiskPath) {
- break;
- }
- insertPoint = insertPoint.previousSibling;
- }
- insertPoint = insertPoint.nextSibling;
- node.DomElement.insertBefore(pDiskCell, insertPoint);
- pDisk.CellDomElement = pDiskCell;
- }
- return pDiskCell;
-}
-
-function getPDiskPart(node, pDiskId, pDiskData) {
- var pDiskPart = node.PDisks[pDiskId].DomElement;
- if (pDiskPart === undefined) {
- var pDiskCell = getPDiskCell(node, pDiskId, pDiskData);
- //pDiskPart = $(pDiskCell).find("td.pdiskspart").get(0);
- pDiskPart = pDiskCell.firstChild.firstChild.firstChild.firstChild.nextSibling.firstChild;
- node.PDisks[pDiskId].DomElement = pDiskPart;
- }
- return pDiskPart;
-}
-
-function initPDiskElement(parentDomElement, pDisk, pDiskId) {
- var childNodes = parentDomElement.childNodes;
- var pDiskElement = undefined;
- for (var i = 0; i < childNodes.length; i++) {
- if (childNodes[i].PDiskId === pDiskId) {
- pDiskElement = childNodes[i];
- break;
- }
- }
-
- if (pDiskElement === undefined && pDisk.DomElement !== undefined) {
- pDiskElement = document.createElement("div");
- pDiskElement.PDiskId = pDiskId;
- pDiskElement.style.padding = "0px 4px 0px 4px";
- pDiskElement.style.float = "left";
- pDiskElement.style.width = "80px";
- var pDiskChild = pDisk.DomElement.firstChild.cloneNode(true);
- pDiskChild.style.minWidth = "30px";
- pDiskChild.title = getNodeHost(pDisk.NodeId) + " " + pDiskChild.title;
- pDiskElement.appendChild(pDiskChild);
- if (pDisk.ClonedElements === undefined) {
- pDisk.ClonedElements = [];
- }
- pDisk.ClonedElements.push(pDiskChild);
- pDiskElement.PDisk = pDisk;
- pDiskElement.addEventListener("click", onPDiskClick, false);
- var insertPoint = parentDomElement.lastChild;
- while (insertPoint !== null) {
- if (insertPoint.PDiskId === undefined || pDiskId >= insertPoint.PDiskId) {
- break;
- }
- insertPoint = insertPoint.previousSibling;
- }
- if (insertPoint !== null) {
- insertPoint = insertPoint.nextSibling;
- }
- parentDomElement.insertBefore(pDiskElement, insertPoint);
- }
-}
-
-function getVDiskPart(nodeId, pDiskId, vDiskId) {
- var node = Nodes[nodeId];
- if (node.VDisks === undefined) {
- node.VDisks = {};
- }
- var vDisk = node.VDisks[vDiskId];
- if (vDisk === undefined) {
- vDisk = node.VDisks[vDiskId] = {};
- }
- var vDiskPart = node.VDisks[vDiskId].DomElement;
- if (vDiskPart === undefined) {
- var pDiskCell = getPDiskCell(node, pDiskId);
- if (pDiskCell === null)
- return null;
- var vDiskRow = pDiskCell.firstChild.firstChild.firstChild.firstChild;
- if (vDiskRow.children.length > MaxWideVDisks && VDiskBlockWidthClass !== "vdiskblock-narrow") {
- VDiskBlockWidthClass = "vdiskblock-narrow";
- $(".vdiskblock-wide").removeClass("vdiskblock-wide").addClass("vdiskblock-narrow");
- }
- vDiskPart = vDiskRow[vDiskId];
- if (vDiskPart === undefined) {
- vDiskPart = document.createElement("td");
- vDiskPart.style.textAlign = 'center';
- vDiskPart.style.fontSize = '12px';
- vDiskPart.style.padding = "1px 1px";
- vDiskRow[vDiskId] = vDiskPart;
- var insertPoint = vDiskRow.lastChild;
- while (insertPoint !== null) {
- if (insertPoint.VDiskId === undefined || vDiskId >= insertPoint.VDiskId) {
- break;
- }
- insertPoint = insertPoint.previousSibling;
- }
- if (insertPoint !== null)
- insertPoint = insertPoint.nextSibling;
- vDiskRow.insertBefore(vDiskPart, insertPoint);
- }
- node.VDisks[vDiskId].DomElement = vDiskPart;
- }
- return vDiskPart;
-}
-
-function getVDiskId(nodeId, vDiskId, pDiskId, vSlotId) {
- return nodeId + "-" + pDiskId + "-" + vSlotId;
-}
-
-function getErasureInfo(erasure) {
- switch (erasure) {
+'use strict';
+
+var Nodes = {};
+var NodesCount = 0;
+var Groups = {};
+var Tablets = {};
+var TabletsCount = 0;
+var newtablets = [];
+var newtablets_running = false;
+var tabletblock_class = "tabletblock";
+var grey = "grey";
+var green = "lightgreen";
+var blue = "#6495ED"; // #4169E1 #4682B4
+var yellow = "yellow";
+var orange = "orange";
+var red = "red";
+var TabletRequest = { request: 0, alive: 1, enums: 1, filter: "(State!=Deleted)" };
+var PDiskRequest = { request: 0, alive: 1, enums: 1 };
+var VDiskRequest = { request: 0, alive: 1, enums: 1 };
+var BSGroupRequest = { request: 0, alive: 1, enums: 1 };
+var SysRequest = { request: 0, alive: 1, enums: 1 };
+var NodeRequest = { request: 0, alive: 1, merge: 0 };
+var VDisksDone = false;
+var VDiskColors = {
+ Initial: grey,
+ LocalRecoveryError: red,
+ SyncGuidRecoveryError: red,
+ SyncGuidRecovery: yellow,
+ OK: green
+};
+var DefaultRefreshTimeout = 500;
+var refreshTimeoutBSGroup = function() { return DefaultRefreshTimeout + 1200; }
+var refreshTimeoutPDisk = function() { return DefaultRefreshTimeout + 1500; }
+var refreshTimeoutVDisk = function() { return DefaultRefreshTimeout + 2300; }
+var refreshTimeoutNode = function() { return DefaultRefreshTimeout + 500; }
+var refreshTimeoutTablet = function() { return DefaultRefreshTimeout + 700; }
+var refreshTimeoutSys = function() { return DefaultRefreshTimeout + 800; }
+var refreshTimeoutHive = function() { return DefaultRefreshTimeout + 2100; }
+var StatsAnimateStop = {opacity: 1};
+var StatsAnimateStart = {opacity: 0.5};
+var StatsAnimateDuration = 10000;
+var Parameters = {};
+var SchemaTabletElements = {};
+var VDiskBlockWidthClass = "vdiskblock-wide";
+var MaxWideVDisks = 4;
+
+function getPDiskCell(node, pDiskId, pDiskData) {
+ if (node.PDisks === undefined) {
+ node.PDisks = {};
+ }
+ var pDisk = node.PDisks[pDiskId];
+ if (pDisk === undefined) {
+ pDisk = node.PDisks[pDiskId] = {};
+ }
+
+ var pDiskCell = pDisk.CellDomElement;
+ if (pDiskCell === undefined) {
+ if (pDiskData === undefined)
+ return null;
+ pDiskCell = document.createElement("td");
+ pDiskCell.innerHTML = "<div class='diskblock'><table style='width:100%'><tr class='vdiskspart'></tr><tr><td class='pdiskspart' style='padding: 2px 1px 1px 1px' colspan='99'></td></tr></table></div>";
+ pDiskCell.PDiskId = pDiskId;
+ var path = pDiskData.Path;
+ pDiskCell.PDiskPath = path;
+
+ var insertPoint = node.DomElement.lastChild;
+ while (insertPoint !== null) {
+ if (insertPoint.PDiskId === undefined || path >= insertPoint.PDiskPath) {
+ break;
+ }
+ insertPoint = insertPoint.previousSibling;
+ }
+ insertPoint = insertPoint.nextSibling;
+ node.DomElement.insertBefore(pDiskCell, insertPoint);
+ pDisk.CellDomElement = pDiskCell;
+ }
+ return pDiskCell;
+}
+
+function getPDiskPart(node, pDiskId, pDiskData) {
+ var pDiskPart = node.PDisks[pDiskId].DomElement;
+ if (pDiskPart === undefined) {
+ var pDiskCell = getPDiskCell(node, pDiskId, pDiskData);
+ //pDiskPart = $(pDiskCell).find("td.pdiskspart").get(0);
+ pDiskPart = pDiskCell.firstChild.firstChild.firstChild.firstChild.nextSibling.firstChild;
+ node.PDisks[pDiskId].DomElement = pDiskPart;
+ }
+ return pDiskPart;
+}
+
+function initPDiskElement(parentDomElement, pDisk, pDiskId) {
+ var childNodes = parentDomElement.childNodes;
+ var pDiskElement = undefined;
+ for (var i = 0; i < childNodes.length; i++) {
+ if (childNodes[i].PDiskId === pDiskId) {
+ pDiskElement = childNodes[i];
+ break;
+ }
+ }
+
+ if (pDiskElement === undefined && pDisk.DomElement !== undefined) {
+ pDiskElement = document.createElement("div");
+ pDiskElement.PDiskId = pDiskId;
+ pDiskElement.style.padding = "0px 4px 0px 4px";
+ pDiskElement.style.float = "left";
+ pDiskElement.style.width = "80px";
+ var pDiskChild = pDisk.DomElement.firstChild.cloneNode(true);
+ pDiskChild.style.minWidth = "30px";
+ pDiskChild.title = getNodeHost(pDisk.NodeId) + " " + pDiskChild.title;
+ pDiskElement.appendChild(pDiskChild);
+ if (pDisk.ClonedElements === undefined) {
+ pDisk.ClonedElements = [];
+ }
+ pDisk.ClonedElements.push(pDiskChild);
+ pDiskElement.PDisk = pDisk;
+ pDiskElement.addEventListener("click", onPDiskClick, false);
+ var insertPoint = parentDomElement.lastChild;
+ while (insertPoint !== null) {
+ if (insertPoint.PDiskId === undefined || pDiskId >= insertPoint.PDiskId) {
+ break;
+ }
+ insertPoint = insertPoint.previousSibling;
+ }
+ if (insertPoint !== null) {
+ insertPoint = insertPoint.nextSibling;
+ }
+ parentDomElement.insertBefore(pDiskElement, insertPoint);
+ }
+}
+
+function getVDiskPart(nodeId, pDiskId, vDiskId) {
+ var node = Nodes[nodeId];
+ if (node.VDisks === undefined) {
+ node.VDisks = {};
+ }
+ var vDisk = node.VDisks[vDiskId];
+ if (vDisk === undefined) {
+ vDisk = node.VDisks[vDiskId] = {};
+ }
+ var vDiskPart = node.VDisks[vDiskId].DomElement;
+ if (vDiskPart === undefined) {
+ var pDiskCell = getPDiskCell(node, pDiskId);
+ if (pDiskCell === null)
+ return null;
+ var vDiskRow = pDiskCell.firstChild.firstChild.firstChild.firstChild;
+ if (vDiskRow.children.length > MaxWideVDisks && VDiskBlockWidthClass !== "vdiskblock-narrow") {
+ VDiskBlockWidthClass = "vdiskblock-narrow";
+ $(".vdiskblock-wide").removeClass("vdiskblock-wide").addClass("vdiskblock-narrow");
+ }
+ vDiskPart = vDiskRow[vDiskId];
+ if (vDiskPart === undefined) {
+ vDiskPart = document.createElement("td");
+ vDiskPart.style.textAlign = 'center';
+ vDiskPart.style.fontSize = '12px';
+ vDiskPart.style.padding = "1px 1px";
+ vDiskRow[vDiskId] = vDiskPart;
+ var insertPoint = vDiskRow.lastChild;
+ while (insertPoint !== null) {
+ if (insertPoint.VDiskId === undefined || vDiskId >= insertPoint.VDiskId) {
+ break;
+ }
+ insertPoint = insertPoint.previousSibling;
+ }
+ if (insertPoint !== null)
+ insertPoint = insertPoint.nextSibling;
+ vDiskRow.insertBefore(vDiskPart, insertPoint);
+ }
+ node.VDisks[vDiskId].DomElement = vDiskPart;
+ }
+ return vDiskPart;
+}
+
+function getVDiskId(nodeId, vDiskId, pDiskId, vSlotId) {
+ return nodeId + "-" + pDiskId + "-" + vSlotId;
+}
+
+function getErasureInfo(erasure) {
+ switch (erasure) {
case 0: // min, total
- case 'none':
- return {Name: "None", Min: 1, Total: 1};
- case 1:
- case 'mirror-3':
- return {Name: "Mirror 3+1", Min: 3, Total: 4};
- case 2:
- case 'block-3-1':
- return {Name: "Block 3+1", Min: 4, Total: 5};
- case 3:
- case 'stripe-3-1':
- return {Name: "Stripe 3+1", Min: 4, Total: 5};
- case 4:
- case 'block-4-2':
- return {Name: "Block 4+2", Min: 6, Total: 8};
- case 5:
- case 'block-3-2':
- return {Name: "Block 3+2", Min: 5, Total: 7};
- case 6:
- case 'stripe-4-2':
- return {Name: "Stripe 4+2", Min: 6, Total: 8};
- case 7:
- case 'stripe-3-2':
- return {Name: "Stripe 3+2", Min: 5, Total: 7};
- case 8:
- case 'mirror-3-2':
- return {Name: "Mirror 3+2", Min: 3, Total: 5};
- case 9:
- case 'mirror-3-dc':
- return {Name: "Mirror 3 DC", Min: 3, Total: 5};
- default:
- return {Name: "Unknown", Min: 1, Total: 1};
- }
-}
-
-function getErasureText(erasure) {
- return getErasureInfo(erasure).Name;
-}
-
-function getGroupInfo(groupId, erasureSpecies) {
- var group = Groups[groupId];
- if (group === undefined) {
- group = Groups[groupId] = {};
- group.GroupID = groupId;
- group.VDisks = {};
- if (erasureSpecies !== undefined) {
- group.ErasureSpecies = erasureSpecies;
- }
- }
- return group;
-}
-
-function getVDiskIdKey(vDiskId) {
- return vDiskId.Ring + "-" + vDiskId.Domain + "-" + vDiskId.VDisk;
-}
-
-function getGroupVDiskInfo(vDisk) {
- var vDiskId = vDisk.VDiskId;
- var group = getGroupInfo(vDisk.VDiskId.GroupID);
- var vDiskInfo = group.VDisks[getVDiskIdKey(vDiskId)];
- if (vDiskInfo === undefined) {
- vDiskInfo = group.VDisks[getVDiskIdKey(vDiskId)] = {};
- }
- return vDiskInfo;
-}
-
-function setGroupVDiskInfo(vDisk) {
- var group = getGroupInfo(vDisk.VDiskId.GroupID, vDisk.ErasureSpecies);
- group.VDisks[getVDiskIdKey(vDisk.VDiskId)] = vDisk;
-}
-
-function getNodeHost(nodeId) {
- var node = Nodes[nodeId];
- if (node !== undefined) {
- if (node.Host !== undefined) {
- return node.Host;
- } else {
- return node.Address;
- }
- } else {
- return nodeId;
- }
-}
-
-function getNodeHostWithPort(nodeId, type, def) {
- var node = Nodes[nodeId];
- if (node !== undefined) {
- var host;
- if (node.Host !== undefined) {
- host = node.Host;
- } else {
- host = node.Address;
- }
- var address = undefined;
- if (node.SysInfo && node.SysInfo.Endpoints) {
- var endpoint = node.SysInfo.Endpoints.find(function (item) { return item.Name === type; });
- if (endpoint !== undefined) {
- address = endpoint.Address;
- }
- }
- if (address === undefined) {
- address = def;
- }
- if (address === undefined) {
- address = ':8765';
- }
- return host + address;
- } else {
- return undefined;
- }
-}
-
-function getBaseUrl(nodeId) {
- if (window.location.hostname === 'viewer.ydb.yandex-team.ru') {
- var nodeHost = getNodeHostWithPort(nodeId, 'http-mon', ':8765');
- return window.location.protocol + '//viewer.ydb.yandex-team.ru/' + nodeHost
- } else if (window.location.hostname.indexOf('.bastion.') !== -1){
- var host = getNodeHost(nodeId);
- host = host.replace('cloud.yandex.net', 'ydb.bastion.cloud.yandex-team.ru');
- host = host.replace('cloud-preprod.yandex.net', 'ydb.bastion.cloud.yandex-team.ru');
- host = host.replace('cloud-df.yandex.net', 'ydb.bastion.cloud.yandex-team.ru');
- return window.location.protocol + "//" + host;
- } else {
- return window.location.protocol + "//" + getNodeHost(nodeId) + ":" + window.location.port;
- }
-}
-
-function getCliMbUrl(url) {
- if (window.location.hostname === "kikimr.viewer.yandex-team.ru") {
- return "/" + window.location.pathname.split('/')[1] + "/CLI_MB" + url;
- } else {
- return "/CLI_MB" + url;
- }
-}
-
-function getVDiskUrl(vDisk) {
- return getBaseUrl(vDisk.NodeId) + "/actors/vdisks/vdisk" + pad9(vDisk.PDiskId) + "_" + pad9(vDisk.VDiskSlotId);
-}
-
-function getPDiskUrl(pDisk) {
- return getBaseUrl(pDisk.NodeId) + "/actors/pdisks/pdisk" + pad9(pDisk.PDiskId);
-}
-
-function getViewerUrl(nodeId) {
- return getBaseUrl(nodeId) + "/viewer/#nodes";
-}
-
-function getVDiskColor(state) {
- var color = VDiskColors[state];
- if (color === undefined) {
- color = grey;
- }
- return color;
-}
-
-function onVDiskClick() {
- window.open(getVDiskUrl(this.VDisk));
-}
-
-function onVDiskEnter() {
- var groupId = this.VDisk.VDiskId.GroupID;
- var group = Groups[groupId];
- if (group !== undefined) {
- for (var vDiskId in group.VDisks) {
- var vDisk = group.VDisks[vDiskId];
- $(vDisk.DomElement).addClass('vdiskblock-selected');
- }
- }
-}
-
-function onVDiskLeave() {
- var groupId = this.VDisk.VDiskId.GroupID;
- var group = Groups[groupId];
- if (group !== undefined) {
- for (var vDiskId in group.VDisks) {
- var vDisk = group.VDisks[vDiskId];
- $(vDisk.DomElement).removeClass('vdiskblock-selected');
- }
- }
-}
-
-function setVDiskBlock(cell, vDisk) {
- var state = " ";
- var color = getVDiskColor(vDisk.VDiskState);
- state += vDisk.VDiskState;
- var rank = vDisk.SatisfactionRank;
- if (!vDisk.Replicated) {
- state += " !Replicated";
- if (color === green) {
- color = blue;
- }
- }
- if (rank !== undefined) {
- if (rank.FreshRank.Flag === "Yellow" || rank.LevelRank.Flag === "Yellow" || vDisk.DiskSpace === "Yellow") {
- if (rank.FreshRank.Flag === "Yellow")
- state += " Fresh:yellow";
- if (rank.LevelRank.Flag === "Yellow")
- state += " Level:yellow";
- if (vDisk.DiskSpace === "Yellow")
- state += " Space:yellow";
- color = yellow;
- }
- if (rank.FreshRank.Flag === "Orange" || rank.LevelRank.Flag === "Orange" || vDisk.DiskSpace === "Orange") {
- if (rank.FreshRank.Flag === "Orange")
- state += " Fresh:orange";
- if (rank.LevelRank.Flag === "Orange")
- state += " Level:orange";
- if (vDisk.DiskSpace === "Orange")
- state += " Space:orange";
- color = orange;
- }
- if (rank.FreshRank.Flag === "Red" || rank.LevelRank.Flag === "Red" || vDisk.DiskSpace === "Red") {
- if (rank.FreshRank.Flag === "Red")
- state += " Fresh:red";
- if (rank.LevelRank.Flag === "Red")
- state += " Level:red";
- if (vDisk.DiskSpace === "Red")
- state += " Space:red";
- color = red;
- }
- if (rank.FreshRank.RankPercent !== undefined) {
- state += " Fresh:" + rank.FreshRank.RankPercent + "%";
- }
- if (rank.LevelRank.RankPercent !== undefined) {
- state += " Level:" + rank.LevelRank.RankPercent + "%";
- }
- }
- if (vDisk.UnsyncedVDisks > 0) {
- state += " UnsyncVDisks:" + vDisk.UnsyncedVDisks;
- }
- var div = cell.firstChild;
- if (div === null) {
- div = document.createElement("div");
- div.className = "vdiskblock " + VDiskBlockWidthClass;
- cell.appendChild(div);
- var vdisk = getGroupVDiskInfo(vDisk);
- vdisk.DomElement = div;
- div.addEventListener("click", onVDiskClick, false);
- div.addEventListener("mouseover", onVDiskEnter, false);
- div.addEventListener("mouseout", onVDiskLeave, false);
- }
- vDisk.Color = color;
- div.style.backgroundColor = color;
- div.VDisk = vDisk;
- var vDiskTextId = getVDiskId(vDisk.NodeId, vDisk.VDiskId, vDisk.PDiskId, vDisk.VDiskSlotId);
- div.title = vDiskTextId + state;
- var vDiskIdKey = getVDiskIdKey(vDisk.VDiskId);
-
- var group = getGroupInfo(vDisk.VDiskId.GroupID);
- var groupVDisk = group.VDisks[vDiskIdKey];
- var vDiskGroupElement = groupVDisk.GroupDomElement;
- if (vDiskGroupElement !== undefined) {
- var vDiskGroupElementNew = div.cloneNode(true);
- vDiskGroupElementNew.VDisk = vDisk;
- vDiskGroupElementNew.addEventListener("click", onVDiskClick, false);
- group.DomElement.replaceChild(vDiskGroupElementNew, vDiskGroupElement);
- groupVDisk.GroupDomElement = vDiskGroupElementNew;
- }
-
- return color;
-}
-
-function onVDiskInfo(vDisksInfo) {
- var vDiskStateInfo = null;
- var refreshTimeout = refreshTimeoutVDisk();
- if (vDisksInfo !== undefined && vDisksInfo !== null && typeof vDisksInfo === "object") {
- if (vDisksInfo.VDiskStateInfo !== undefined) {
- vDiskStateInfo = vDisksInfo.VDiskStateInfo;
- if (vDiskStateInfo !== null) {
- if (VDiskRequest.since === undefined && !VDisksDone) {
- refreshBSGroupInfo();
- VDisksDone = true;
- }
- for (var i in vDiskStateInfo) {
- var vDisk = vDiskStateInfo[i];
- if (vDisk.VDiskId === undefined || vDisk.PDiskId === undefined) {
- continue;
- }
-
- var vDiskId = getVDiskId(vDisk.NodeId, vDisk.VDiskId, vDisk.PDiskId, vDisk.VDiskSlotId);
- var vDiskCell = getVDiskPart(vDisk.NodeId, vDisk.PDiskId, vDiskId);
- if (vDiskCell === null)
- continue;
- var vDiskInfo = getGroupVDiskInfo(vDisk);
- for (var prop in vDisk) {
- vDiskInfo[prop] = vDisk[prop];
- }
- setVDiskBlock(vDiskCell, vDiskInfo);
- }
- if (++VDiskRequest.request > 60) {
- VDiskRequest.request = 0;
- delete VDiskRequest.since;
- } else {
- VDiskRequest.since = vDisksInfo.ResponseTime;
- }
- }
- }
- } else {
- VDiskRequest.request = 0;
- delete VDiskRequest.since;
- }
- setTimeout(refreshVDiskInfo, refreshTimeout);
- refreshVDiskStats();
-}
-
-function getSizesProgressBarHtml(used, total, width) {
- var html = "<div class='progress' style='margin-bottom:1px";
- if (width === undefined)
- width = "200px";
- html += ";width:" + width;
- html += "'><div class='progress-bar ";
- var percent = total > 0 ? ((used * 100 / total).toPrecision(3)) : 0;
- if (percent >= 90) {
- html += "progress-bar-danger";
- } else
- if (percent >= 75) {
- html += "progress-bar-warning";
- } else {
- html += "progress-bar-success";
- }
- html += "' role='progressbar' aria-valuenow='";
- html += percent;
- html += "' aria-valuemin='0' aria-valuemax='100' style='width:" + percent + "%;font-size:10px'><span>" + percent + "%</span></div></div>";
- return html;
-}
-
-function asNumber(num) {
- return (num === undefined || num === null) ? 0 : Number(num);
-}
-
-function getLatencyText(latency) {
- if (latency === undefined) {
- return "";
- }
- switch (latency) {
- case 'Grey': return "";
- case 'Green': return "<500ms";
- case 'Yellow': return "500..1000ms";
- case 'Orange': return "1000..2000ms";
- case 'Red': return ">2000ms";
- }
- return "";
-}
-
-function getLatencyColor(latency) {
- switch (latency) {
- case 'Grey': return grey;
- case 'Green': return green;
- case 'Yellow': return yellow;
- case 'Orange': return orange;
- case 'Red': return red;
- }
- return "black";
-}
-
-function updateBytesValue(element, bytes, delta) {
- if (delta !== undefined) {
- var deltaText = "";
- if (element.ValueLast !== undefined) {
- var diff = bytes - element.ValueLast;
- element.ValueLast = bytes;
- element.ValueAccum += diff;
- element.ValueCount++;
- var avgDiff = element.ValueAccum / element.ValueCount;
- if (avgDiff !== 0) {
- if (avgDiff < 0) {
- deltaText = "<span style=''>-" +bytesToSize(-avgDiff) + "</span>";
- } else {
- deltaText = "<span style=''>+" +bytesToSize(avgDiff) + "</span>";
- }
- }
- if (element.ValueCount >= 20) {
- element.ValueAccum /= 2;
- element.ValueCount /= 2;
- }
- } else {
- element.ValueOriginal = bytes;
- element.ValueLast = bytes;
- element.ValueAccum = 0;
- element.ValueCount = 0;
- }
- delta.innerHTML = deltaText;
- }
- element.innerHTML = bytesToSize(bytes);
-}
-
-function onBSGroupInfo(bsGroupInfo) {
- var bsGroupStateInfo = null;
- var refreshTimeout = refreshTimeoutBSGroup();
- if (bsGroupInfo !== undefined && bsGroupInfo !== null && typeof bsGroupInfo === "object") {
- if (bsGroupInfo.BSGroupStateInfo !== undefined) {
- bsGroupStateInfo = bsGroupInfo.BSGroupStateInfo;
- if (bsGroupStateInfo !== null) {
- for (var i in bsGroupStateInfo) {
- var newGroup = bsGroupStateInfo[i];
- var group = getGroupInfo(newGroup.GroupID, newGroup.ErasureSpecies);
-
- for (var prop in newGroup) {
- group[prop] = newGroup[prop];
- }
- }
- }
- }
- if (++BSGroupRequest.request > 6) {
- BSGroupRequest.request = 0;
- delete BSGroupRequest.since;
- } else {
- BSGroupRequest.since = bsGroupInfo.ResponseTime;
- }
- } else {
- $("#storage").find(".grouplist").find("tr:has(> td)").remove();
- Groups = {};
- BSGroupRequest.request = 0;
- delete BSGroupRequest.since;
- }
-
- var groupsView = $("#storage").find(".grouplist").get(0);
- var staticTotal = 0;
- var staticUsed = 0;
- var staticAvailable = 0;
- var staticPDisks = {};
- var dynamicTotal = 0;
- var dynamicUsed = 0;
- var dynamicAvailable = 0;
- var dynamicPDisks = {};
- var totalTotal = 0;
- var totalUsed = 0;
- var totalAvailable = 0;
- var totalPDisks = {};
- for (var groupId in Groups) {
- var group = Groups[groupId];
- if (group.ErasureSpecies === undefined)
- continue;
- var groupLatency;
- var groupUsage;
- var groupDelta;
- var groupUsed;
- var groupAvailable;
- var groupTotal;
- var groupPDisks;
-
- if (group.DomElement === undefined) {
- var groupRow = groupsView.insertRow();
- var groupIdElement = groupRow.insertCell(-1);
- groupIdElement.style.textAlign = "right";
- groupIdElement.innerHTML = group.GroupID;
- var groupTypeElement = groupRow.insertCell(-1);
- groupTypeElement.innerHTML = group.GroupID & 0x80000000 ? "Dynamic" : "Static";
- var groupErasureElement = groupRow.insertCell(-1);
- groupErasureElement.innerHTML = getErasureText(group.ErasureSpecies);
- groupLatency = document.createElement("div");
- groupLatency.className = "latency-block";
- groupRow.insertCell(-1).appendChild(groupLatency);
- var groupCell = groupRow.insertCell(-1);
- var groupElement = document.createElement("div");
- groupUsage = document.createElement("div");
- groupRow.insertCell(-1).appendChild(groupUsage);
- groupDelta = document.createElement("div");
- groupDelta.style.textAlign = "right";
- groupRow.insertCell(-1).appendChild(groupDelta);
- groupUsed = document.createElement("div");
- groupUsed.style.textAlign = "right";
- groupRow.insertCell(-1).appendChild(groupUsed);
- groupAvailable = document.createElement("div");
- groupAvailable.style.textAlign = "right";
- groupRow.insertCell(-1).appendChild(groupAvailable);
- groupTotal = document.createElement("div");
- groupTotal.style.textAlign = "right";
- groupRow.insertCell(-1).appendChild(groupTotal);
- groupPDisks = document.createElement("div");
- groupRow.insertCell(-1).appendChild(groupPDisks);
- groupElement.className = "groupblock";
- groupCell.appendChild(groupElement);
- group.DomElement = groupElement;
- } else {
- groupLatency = group.DomElement.parentNode.previousSibling.firstChild;
- groupUsage = group.DomElement.parentNode.nextSibling.firstChild;
- groupDelta = groupUsage.parentNode.nextSibling.firstChild;
- groupUsed = groupDelta.parentNode.nextSibling.firstChild;
- groupAvailable = groupUsed.parentNode.nextSibling.firstChild;
- groupTotal = groupAvailable.parentNode.nextSibling.firstChild;
- groupPDisks = groupTotal.parentNode.nextSibling.firstChild;
- }
-
- groupLatency.innerHTML = getLatencyText(group.Latency);
- groupLatency.style.backgroundColor = getLatencyColor(group.Latency);
-
- var total = 0;
- var used = 0;
- var available = 0;
- var groupPDisksMask = {};
-
- for (var vDiskIdIdx in group.VDiskIds) {
- var vDiskId = group.VDiskIds[vDiskIdIdx];
- var vDiskIdKey = getVDiskIdKey(vDiskId);
- var groupVDisk = group.VDisks[vDiskIdKey];
- if (groupVDisk === undefined) {
- groupVDisk = group.VDisks[vDiskIdKey] = {};
- }
- var vDiskGroupElement = groupVDisk.GroupDomElement;
- if (vDiskGroupElement === undefined) {
- var vDiskElement = groupVDisk.DomElement;
- if (vDiskElement !== undefined) {
- vDiskGroupElement = vDiskElement.cloneNode(true);
- vDiskGroupElement.VDisk = groupVDisk;
- vDiskGroupElement.addEventListener("click", onVDiskClick, false);
- } else {
- vDiskGroupElement = document.createElement("div");
- vDiskGroupElement.className = "vdiskblock " + VDiskBlockWidthClass;
- vDiskGroupElement.style.backgroundColor = "grey";
- }
- group.DomElement.appendChild(vDiskGroupElement);
- groupVDisk.GroupDomElement = vDiskGroupElement;
- }
- used += asNumber(groupVDisk.AllocatedSize);
- if (groupVDisk.NodeId !== undefined && groupVDisk.PDiskId !== undefined) {
- var node = Nodes[groupVDisk.NodeId];
- if (node.PDisks !== undefined) {
- var pDisk = node.PDisks[groupVDisk.PDiskId];
- if (pDisk !== undefined) {
- var key = String(groupVDisk.NodeId) + "-" + String(groupVDisk.PDiskId);
- initPDiskElement(groupPDisks, pDisk, key);
- if (pDisk.AvailableSize !== undefined && pDisk.TotalSize !== undefined) {
- if (groupPDisksMask[key] === undefined) {
- total += asNumber(pDisk.TotalSize);
- available += asNumber(pDisk.AvailableSize);
- }
- groupPDisksMask[key] = true;
- if (totalPDisks[key] === undefined) {
- totalTotal += asNumber(pDisk.TotalSize);
- totalAvailable += asNumber(pDisk.AvailableSize);
- totalPDisks[key] = true;
- }
- if (group.GroupID & 0x80000000) {
- if (dynamicPDisks[key] === undefined) {
- dynamicTotal += asNumber(pDisk.TotalSize);
- dynamicAvailable += asNumber(pDisk.AvailableSize);
- dynamicPDisks[key] = true;
- }
- } else {
- if (staticPDisks[key] === undefined) {
- staticTotal += asNumber(pDisk.TotalSize);
- staticAvailable += asNumber(pDisk.AvailableSize);
- staticPDisks[key] = true;
- }
- }
- }
- }
- }
- }
- }
- totalUsed += used;
- if (group.GroupID & 0x80000000) {
- dynamicUsed += used;
- } else {
- staticUsed += used;
- }
-
- if (total !== 0) {
- groupUsage.innerHTML = getSizesProgressBarHtml(used, used + available);
- updateBytesValue(groupUsed, used, groupDelta);
- updateBytesValue(groupAvailable, available);
- updateBytesValue(groupTotal, total);
- }
- }
- var totalStorageElement = $("#storage").find(".totalstorage").get(0);
- var totalElement = totalStorageElement.firstElementChild.nextElementSibling.firstElementChild.firstElementChild.nextElementSibling;
- var dynamicElement = totalElement.parentNode.nextElementSibling.firstElementChild.nextElementSibling;
- var staticElement = dynamicElement.parentNode.nextElementSibling.firstElementChild.nextElementSibling;
-
- totalElement.innerHTML = getSizesProgressBarHtml(totalUsed, totalTotal);
- totalElement = totalElement.nextElementSibling
- totalElement.innerHTML = bytesToSize(totalUsed);
- totalElement = totalElement.nextElementSibling
- totalElement.innerHTML = bytesToSize(totalAvailable);
- totalElement = totalElement.nextElementSibling
- totalElement.innerHTML = bytesToSize(totalTotal);
- dynamicElement.innerHTML = getSizesProgressBarHtml(dynamicUsed, dynamicTotal);
- dynamicElement = dynamicElement.nextElementSibling;
- dynamicElement.innerHTML = bytesToSize(dynamicUsed);
- dynamicElement = dynamicElement.nextElementSibling;
- dynamicElement.innerHTML = bytesToSize(dynamicAvailable);
- dynamicElement = dynamicElement.nextElementSibling;
- dynamicElement.innerHTML = bytesToSize(dynamicTotal);
- staticElement.innerHTML = getSizesProgressBarHtml(staticUsed, staticTotal);
- staticElement = staticElement.nextElementSibling;
- staticElement.innerHTML = bytesToSize(staticUsed);
- staticElement = staticElement.nextElementSibling;
- staticElement.innerHTML = bytesToSize(staticAvailable);
- staticElement = staticElement.nextElementSibling;
- staticElement.innerHTML = bytesToSize(staticTotal);
-
- setTimeout(refreshBSGroupInfo, refreshTimeout);
- refreshBSGroupStats();
-}
-
-function onPDiskClick() {
- window.open(getPDiskUrl(this.PDisk));
-}
-
-function getPDiskIcon(icon, color) {
- return "<span class='glyphicon glyphicon-" + icon + "' style='color:" + color + ";text-shadow: 0 0 1px black;margin-right:2px;'></span>"
-}
-
-function getPDiskDeviceIcon(color) {
- return getPDiskIcon("save", color);
-}
-
-function getPDiskRealtimeIcon(color) {
- return getPDiskIcon("fire", color);
-}
-
-function onPDiskInfo(pDisksInfo) {
- var pDiskStateInfo = null;
- var refreshTimeout = refreshTimeoutPDisk();
- if (pDisksInfo !== undefined && pDisksInfo !== null && typeof pDisksInfo === "object") {
- if (pDisksInfo.PDiskStateInfo !== undefined) {
- pDiskStateInfo = pDisksInfo.PDiskStateInfo;
- }
- if (pDiskStateInfo !== null) {
- for (var idx in pDiskStateInfo) {
- var pDiskInfo = pDiskStateInfo[idx];
- var node = Nodes[pDiskInfo.NodeId];
- if (node.PDisks === undefined) {
- node.PDisks = {};
- }
- var pDisk = node.PDisks[pDiskInfo.PDiskId];
- if (pDisk === undefined) {
- pDisk = node.PDisks[pDiskInfo.PDiskId] = pDiskInfo;
- } else {
- for (var j in pDiskInfo) {
- pDisk[j] = pDiskInfo[j];
- }
- }
- var pDiskBlock = pDisk.BlockDomElement;
- if (pDiskBlock === undefined) {
- var pDiskCell = getPDiskPart(node, pDisk.PDiskId, pDisk);
- pDiskBlock = pDiskCell.firstChild;
- if (pDiskBlock === null) {
- pDiskBlock = document.createElement("div");
- pDiskBlock.className = 'progress pdiskblock';
- pDiskBlock.PDisk = pDisk;
- pDiskBlock.addEventListener("click", onPDiskClick, false);
- pDiskBlock.style.position = 'relative';
- pDiskCell.appendChild(pDiskBlock);
- pDisk.BlockDomElement = pDiskBlock;
- }
- }
-
- var state = "";
- if (pDisk.State === 'Normal') {
- pDiskBlock.style.backgroundColor = "lightblue";
- state = "Normal";
- pDisk.Color = green;
- var total = pDisk.TotalSize;
- var avail = pDisk.AvailableSize;
- if (total !== undefined && avail !== undefined) {
- var percent = ((total - avail) * 100 / total).toPrecision(3);
- var html = "<div class='progress-bar ";
- if (percent >= 90) {
- html += "progress-bar-danger";
- pDisk.Color = orange;
- } else
- if (percent >= 75) {
- html += "progress-bar-warning";
- pDisk.Color = yellow;
- } else {
- html += "progress-bar-success";
- }
-
- html += "' role='progressbar' aria-valuenow='";
- html += percent;
- html += "' aria-valuemin='0' aria-valuemax='100' style='width:" + percent + "%;font-size:10px;vertical-align:middle;padding-left:3px'>" + percent
- + "%</div><div style='position:absolute;top:1px;right:1px;font-size:12px'>";
-
- state += " (Available " + bytesToSize(avail) + " of " + bytesToSize(total) + ")";
-
- if (pDisk.Realtime !== undefined) {
- switch (pDisk.Realtime) {
- case 'Yellow':
- if (pDisk.Color !== orange) {
- pDisk.Color = yellow;
- }
- html += getPDiskRealtimeIcon("yellow");
- state += " Realtime:yellow";
- break;
- case 'Orange':
- if (pDisk.Color !== red) {
- pDisk.Color = orange;
- }
- html += getPDiskRealtimeIcon("orange");
- state += " Realtime:orange";
- break;
- case 'Red':
- pDisk.Color = red;
- html += getPDiskRealtimeIcon("red");
- state += " Realtime:red";
- break;
- }
- }
-
- if (pDisk.Device !== undefined) {
- switch (pDisk.Device) {
- case 'Yellow':
- if (pDisk.Color !== orange && pDisk.Color !== red) {
- pDisk.Color = yellow;
- }
- html += getPDiskDeviceIcon("yellow");
- state += " Device:yellow";
- break;
- case 'Orange':
- pDisk.Color = orange;
- html += getPDiskDeviceIcon("orange");
- state += " Device:orange";
- break;
- case 'Red':
- pDisk.Color = red;
- html += getPDiskDeviceIcon("red");
- state += " Device:red";
- break;
- }
- }
-
- html += "</div>";
- pDiskBlock.innerHTML = html;
- if (pDisk.ClonedElements !== undefined) {
- for (var i = 0; i < pDisk.ClonedElements.length; i++) {
- pDisk.ClonedElements[i].innerHTML = html;
- }
- }
- }
- } else {
- switch (pDisk.State) {
- case 'Initial':
- pDiskBlock.style.backgroundColor = grey;
- pDisk.Color = grey;
- state = pDisk.State;
- break;
- case 'Normal':
- pDisk.Color = green;
- // wtf?
- break;
- case 'InitialFormatRead':
- case 'InitialSysLogRead':
- case 'InitialCommonLogRead':
- pDiskBlock.style.backgroundColor = yellow;
- pDisk.Color = yellow;
- state = pDisk.State;
- break;
- case 'InitialFormatReadError':
- case 'InitialSysLogReadError':
- case 'InitialSysLogParseError':
- case 'InitialCommonLogReadError':
- case 'InitialCommonLogParseError':
- case 'CommonLoggerInitError':
- case 'OpenFileError':
- pDiskBlock.style.backgroundColor = red;
- pDisk.Color = red;
- state = pDisk.State;
- break;
- }
- }
- pDiskBlock.title = pDisk.Path + " " + state;
- if (pDisk.ClonedElements !== undefined) {
- var title = getNodeHost(pDiskInfo.NodeId) + " " + pDisk.Path + " " + state;
- for (var i = 0; i < pDisk.ClonedElements.length; i++) {
- pDisk.ClonedElements[i].title = title;
- }
- }
- }
- }
- if (++PDiskRequest.request > 60) {
- PDiskRequest.request = 0;
- delete PDiskRequest.since;
- } else {
- PDiskRequest.since = pDisksInfo.ResponseTime;
- }
- } else {
- PDiskRequest.request = 0;
- delete PDiskRequest.since;
- }
- setTimeout(refreshPDiskInfo, refreshTimeout);
- refreshPDiskStats();
-}
-
-function pad2(val) {
- if (val < 10) {
- return "0" + val;
- } else {
- return val;
- }
-}
-
+ case 'none':
+ return {Name: "None", Min: 1, Total: 1};
+ case 1:
+ case 'mirror-3':
+ return {Name: "Mirror 3+1", Min: 3, Total: 4};
+ case 2:
+ case 'block-3-1':
+ return {Name: "Block 3+1", Min: 4, Total: 5};
+ case 3:
+ case 'stripe-3-1':
+ return {Name: "Stripe 3+1", Min: 4, Total: 5};
+ case 4:
+ case 'block-4-2':
+ return {Name: "Block 4+2", Min: 6, Total: 8};
+ case 5:
+ case 'block-3-2':
+ return {Name: "Block 3+2", Min: 5, Total: 7};
+ case 6:
+ case 'stripe-4-2':
+ return {Name: "Stripe 4+2", Min: 6, Total: 8};
+ case 7:
+ case 'stripe-3-2':
+ return {Name: "Stripe 3+2", Min: 5, Total: 7};
+ case 8:
+ case 'mirror-3-2':
+ return {Name: "Mirror 3+2", Min: 3, Total: 5};
+ case 9:
+ case 'mirror-3-dc':
+ return {Name: "Mirror 3 DC", Min: 3, Total: 5};
+ default:
+ return {Name: "Unknown", Min: 1, Total: 1};
+ }
+}
+
+function getErasureText(erasure) {
+ return getErasureInfo(erasure).Name;
+}
+
+function getGroupInfo(groupId, erasureSpecies) {
+ var group = Groups[groupId];
+ if (group === undefined) {
+ group = Groups[groupId] = {};
+ group.GroupID = groupId;
+ group.VDisks = {};
+ if (erasureSpecies !== undefined) {
+ group.ErasureSpecies = erasureSpecies;
+ }
+ }
+ return group;
+}
+
+function getVDiskIdKey(vDiskId) {
+ return vDiskId.Ring + "-" + vDiskId.Domain + "-" + vDiskId.VDisk;
+}
+
+function getGroupVDiskInfo(vDisk) {
+ var vDiskId = vDisk.VDiskId;
+ var group = getGroupInfo(vDisk.VDiskId.GroupID);
+ var vDiskInfo = group.VDisks[getVDiskIdKey(vDiskId)];
+ if (vDiskInfo === undefined) {
+ vDiskInfo = group.VDisks[getVDiskIdKey(vDiskId)] = {};
+ }
+ return vDiskInfo;
+}
+
+function setGroupVDiskInfo(vDisk) {
+ var group = getGroupInfo(vDisk.VDiskId.GroupID, vDisk.ErasureSpecies);
+ group.VDisks[getVDiskIdKey(vDisk.VDiskId)] = vDisk;
+}
+
+function getNodeHost(nodeId) {
+ var node = Nodes[nodeId];
+ if (node !== undefined) {
+ if (node.Host !== undefined) {
+ return node.Host;
+ } else {
+ return node.Address;
+ }
+ } else {
+ return nodeId;
+ }
+}
+
+function getNodeHostWithPort(nodeId, type, def) {
+ var node = Nodes[nodeId];
+ if (node !== undefined) {
+ var host;
+ if (node.Host !== undefined) {
+ host = node.Host;
+ } else {
+ host = node.Address;
+ }
+ var address = undefined;
+ if (node.SysInfo && node.SysInfo.Endpoints) {
+ var endpoint = node.SysInfo.Endpoints.find(function (item) { return item.Name === type; });
+ if (endpoint !== undefined) {
+ address = endpoint.Address;
+ }
+ }
+ if (address === undefined) {
+ address = def;
+ }
+ if (address === undefined) {
+ address = ':8765';
+ }
+ return host + address;
+ } else {
+ return undefined;
+ }
+}
+
+function getBaseUrl(nodeId) {
+ if (window.location.hostname === 'viewer.ydb.yandex-team.ru') {
+ var nodeHost = getNodeHostWithPort(nodeId, 'http-mon', ':8765');
+ return window.location.protocol + '//viewer.ydb.yandex-team.ru/' + nodeHost
+ } else if (window.location.hostname.indexOf('.bastion.') !== -1){
+ var host = getNodeHost(nodeId);
+ host = host.replace('cloud.yandex.net', 'ydb.bastion.cloud.yandex-team.ru');
+ host = host.replace('cloud-preprod.yandex.net', 'ydb.bastion.cloud.yandex-team.ru');
+ host = host.replace('cloud-df.yandex.net', 'ydb.bastion.cloud.yandex-team.ru');
+ return window.location.protocol + "//" + host;
+ } else {
+ return window.location.protocol + "//" + getNodeHost(nodeId) + ":" + window.location.port;
+ }
+}
+
+function getCliMbUrl(url) {
+ if (window.location.hostname === "kikimr.viewer.yandex-team.ru") {
+ return "/" + window.location.pathname.split('/')[1] + "/CLI_MB" + url;
+ } else {
+ return "/CLI_MB" + url;
+ }
+}
+
+function getVDiskUrl(vDisk) {
+ return getBaseUrl(vDisk.NodeId) + "/actors/vdisks/vdisk" + pad9(vDisk.PDiskId) + "_" + pad9(vDisk.VDiskSlotId);
+}
+
+function getPDiskUrl(pDisk) {
+ return getBaseUrl(pDisk.NodeId) + "/actors/pdisks/pdisk" + pad9(pDisk.PDiskId);
+}
+
+function getViewerUrl(nodeId) {
+ return getBaseUrl(nodeId) + "/viewer/#nodes";
+}
+
+function getVDiskColor(state) {
+ var color = VDiskColors[state];
+ if (color === undefined) {
+ color = grey;
+ }
+ return color;
+}
+
+function onVDiskClick() {
+ window.open(getVDiskUrl(this.VDisk));
+}
+
+function onVDiskEnter() {
+ var groupId = this.VDisk.VDiskId.GroupID;
+ var group = Groups[groupId];
+ if (group !== undefined) {
+ for (var vDiskId in group.VDisks) {
+ var vDisk = group.VDisks[vDiskId];
+ $(vDisk.DomElement).addClass('vdiskblock-selected');
+ }
+ }
+}
+
+function onVDiskLeave() {
+ var groupId = this.VDisk.VDiskId.GroupID;
+ var group = Groups[groupId];
+ if (group !== undefined) {
+ for (var vDiskId in group.VDisks) {
+ var vDisk = group.VDisks[vDiskId];
+ $(vDisk.DomElement).removeClass('vdiskblock-selected');
+ }
+ }
+}
+
+function setVDiskBlock(cell, vDisk) {
+ var state = " ";
+ var color = getVDiskColor(vDisk.VDiskState);
+ state += vDisk.VDiskState;
+ var rank = vDisk.SatisfactionRank;
+ if (!vDisk.Replicated) {
+ state += " !Replicated";
+ if (color === green) {
+ color = blue;
+ }
+ }
+ if (rank !== undefined) {
+ if (rank.FreshRank.Flag === "Yellow" || rank.LevelRank.Flag === "Yellow" || vDisk.DiskSpace === "Yellow") {
+ if (rank.FreshRank.Flag === "Yellow")
+ state += " Fresh:yellow";
+ if (rank.LevelRank.Flag === "Yellow")
+ state += " Level:yellow";
+ if (vDisk.DiskSpace === "Yellow")
+ state += " Space:yellow";
+ color = yellow;
+ }
+ if (rank.FreshRank.Flag === "Orange" || rank.LevelRank.Flag === "Orange" || vDisk.DiskSpace === "Orange") {
+ if (rank.FreshRank.Flag === "Orange")
+ state += " Fresh:orange";
+ if (rank.LevelRank.Flag === "Orange")
+ state += " Level:orange";
+ if (vDisk.DiskSpace === "Orange")
+ state += " Space:orange";
+ color = orange;
+ }
+ if (rank.FreshRank.Flag === "Red" || rank.LevelRank.Flag === "Red" || vDisk.DiskSpace === "Red") {
+ if (rank.FreshRank.Flag === "Red")
+ state += " Fresh:red";
+ if (rank.LevelRank.Flag === "Red")
+ state += " Level:red";
+ if (vDisk.DiskSpace === "Red")
+ state += " Space:red";
+ color = red;
+ }
+ if (rank.FreshRank.RankPercent !== undefined) {
+ state += " Fresh:" + rank.FreshRank.RankPercent + "%";
+ }
+ if (rank.LevelRank.RankPercent !== undefined) {
+ state += " Level:" + rank.LevelRank.RankPercent + "%";
+ }
+ }
+ if (vDisk.UnsyncedVDisks > 0) {
+ state += " UnsyncVDisks:" + vDisk.UnsyncedVDisks;
+ }
+ var div = cell.firstChild;
+ if (div === null) {
+ div = document.createElement("div");
+ div.className = "vdiskblock " + VDiskBlockWidthClass;
+ cell.appendChild(div);
+ var vdisk = getGroupVDiskInfo(vDisk);
+ vdisk.DomElement = div;
+ div.addEventListener("click", onVDiskClick, false);
+ div.addEventListener("mouseover", onVDiskEnter, false);
+ div.addEventListener("mouseout", onVDiskLeave, false);
+ }
+ vDisk.Color = color;
+ div.style.backgroundColor = color;
+ div.VDisk = vDisk;
+ var vDiskTextId = getVDiskId(vDisk.NodeId, vDisk.VDiskId, vDisk.PDiskId, vDisk.VDiskSlotId);
+ div.title = vDiskTextId + state;
+ var vDiskIdKey = getVDiskIdKey(vDisk.VDiskId);
+
+ var group = getGroupInfo(vDisk.VDiskId.GroupID);
+ var groupVDisk = group.VDisks[vDiskIdKey];
+ var vDiskGroupElement = groupVDisk.GroupDomElement;
+ if (vDiskGroupElement !== undefined) {
+ var vDiskGroupElementNew = div.cloneNode(true);
+ vDiskGroupElementNew.VDisk = vDisk;
+ vDiskGroupElementNew.addEventListener("click", onVDiskClick, false);
+ group.DomElement.replaceChild(vDiskGroupElementNew, vDiskGroupElement);
+ groupVDisk.GroupDomElement = vDiskGroupElementNew;
+ }
+
+ return color;
+}
+
+function onVDiskInfo(vDisksInfo) {
+ var vDiskStateInfo = null;
+ var refreshTimeout = refreshTimeoutVDisk();
+ if (vDisksInfo !== undefined && vDisksInfo !== null && typeof vDisksInfo === "object") {
+ if (vDisksInfo.VDiskStateInfo !== undefined) {
+ vDiskStateInfo = vDisksInfo.VDiskStateInfo;
+ if (vDiskStateInfo !== null) {
+ if (VDiskRequest.since === undefined && !VDisksDone) {
+ refreshBSGroupInfo();
+ VDisksDone = true;
+ }
+ for (var i in vDiskStateInfo) {
+ var vDisk = vDiskStateInfo[i];
+ if (vDisk.VDiskId === undefined || vDisk.PDiskId === undefined) {
+ continue;
+ }
+
+ var vDiskId = getVDiskId(vDisk.NodeId, vDisk.VDiskId, vDisk.PDiskId, vDisk.VDiskSlotId);
+ var vDiskCell = getVDiskPart(vDisk.NodeId, vDisk.PDiskId, vDiskId);
+ if (vDiskCell === null)
+ continue;
+ var vDiskInfo = getGroupVDiskInfo(vDisk);
+ for (var prop in vDisk) {
+ vDiskInfo[prop] = vDisk[prop];
+ }
+ setVDiskBlock(vDiskCell, vDiskInfo);
+ }
+ if (++VDiskRequest.request > 60) {
+ VDiskRequest.request = 0;
+ delete VDiskRequest.since;
+ } else {
+ VDiskRequest.since = vDisksInfo.ResponseTime;
+ }
+ }
+ }
+ } else {
+ VDiskRequest.request = 0;
+ delete VDiskRequest.since;
+ }
+ setTimeout(refreshVDiskInfo, refreshTimeout);
+ refreshVDiskStats();
+}
+
+function getSizesProgressBarHtml(used, total, width) {
+ var html = "<div class='progress' style='margin-bottom:1px";
+ if (width === undefined)
+ width = "200px";
+ html += ";width:" + width;
+ html += "'><div class='progress-bar ";
+ var percent = total > 0 ? ((used * 100 / total).toPrecision(3)) : 0;
+ if (percent >= 90) {
+ html += "progress-bar-danger";
+ } else
+ if (percent >= 75) {
+ html += "progress-bar-warning";
+ } else {
+ html += "progress-bar-success";
+ }
+ html += "' role='progressbar' aria-valuenow='";
+ html += percent;
+ html += "' aria-valuemin='0' aria-valuemax='100' style='width:" + percent + "%;font-size:10px'><span>" + percent + "%</span></div></div>";
+ return html;
+}
+
+function asNumber(num) {
+ return (num === undefined || num === null) ? 0 : Number(num);
+}
+
+function getLatencyText(latency) {
+ if (latency === undefined) {
+ return "";
+ }
+ switch (latency) {
+ case 'Grey': return "";
+ case 'Green': return "<500ms";
+ case 'Yellow': return "500..1000ms";
+ case 'Orange': return "1000..2000ms";
+ case 'Red': return ">2000ms";
+ }
+ return "";
+}
+
+function getLatencyColor(latency) {
+ switch (latency) {
+ case 'Grey': return grey;
+ case 'Green': return green;
+ case 'Yellow': return yellow;
+ case 'Orange': return orange;
+ case 'Red': return red;
+ }
+ return "black";
+}
+
+function updateBytesValue(element, bytes, delta) {
+ if (delta !== undefined) {
+ var deltaText = "";
+ if (element.ValueLast !== undefined) {
+ var diff = bytes - element.ValueLast;
+ element.ValueLast = bytes;
+ element.ValueAccum += diff;
+ element.ValueCount++;
+ var avgDiff = element.ValueAccum / element.ValueCount;
+ if (avgDiff !== 0) {
+ if (avgDiff < 0) {
+ deltaText = "<span style=''>-" +bytesToSize(-avgDiff) + "</span>";
+ } else {
+ deltaText = "<span style=''>+" +bytesToSize(avgDiff) + "</span>";
+ }
+ }
+ if (element.ValueCount >= 20) {
+ element.ValueAccum /= 2;
+ element.ValueCount /= 2;
+ }
+ } else {
+ element.ValueOriginal = bytes;
+ element.ValueLast = bytes;
+ element.ValueAccum = 0;
+ element.ValueCount = 0;
+ }
+ delta.innerHTML = deltaText;
+ }
+ element.innerHTML = bytesToSize(bytes);
+}
+
+function onBSGroupInfo(bsGroupInfo) {
+ var bsGroupStateInfo = null;
+ var refreshTimeout = refreshTimeoutBSGroup();
+ if (bsGroupInfo !== undefined && bsGroupInfo !== null && typeof bsGroupInfo === "object") {
+ if (bsGroupInfo.BSGroupStateInfo !== undefined) {
+ bsGroupStateInfo = bsGroupInfo.BSGroupStateInfo;
+ if (bsGroupStateInfo !== null) {
+ for (var i in bsGroupStateInfo) {
+ var newGroup = bsGroupStateInfo[i];
+ var group = getGroupInfo(newGroup.GroupID, newGroup.ErasureSpecies);
+
+ for (var prop in newGroup) {
+ group[prop] = newGroup[prop];
+ }
+ }
+ }
+ }
+ if (++BSGroupRequest.request > 6) {
+ BSGroupRequest.request = 0;
+ delete BSGroupRequest.since;
+ } else {
+ BSGroupRequest.since = bsGroupInfo.ResponseTime;
+ }
+ } else {
+ $("#storage").find(".grouplist").find("tr:has(> td)").remove();
+ Groups = {};
+ BSGroupRequest.request = 0;
+ delete BSGroupRequest.since;
+ }
+
+ var groupsView = $("#storage").find(".grouplist").get(0);
+ var staticTotal = 0;
+ var staticUsed = 0;
+ var staticAvailable = 0;
+ var staticPDisks = {};
+ var dynamicTotal = 0;
+ var dynamicUsed = 0;
+ var dynamicAvailable = 0;
+ var dynamicPDisks = {};
+ var totalTotal = 0;
+ var totalUsed = 0;
+ var totalAvailable = 0;
+ var totalPDisks = {};
+ for (var groupId in Groups) {
+ var group = Groups[groupId];
+ if (group.ErasureSpecies === undefined)
+ continue;
+ var groupLatency;
+ var groupUsage;
+ var groupDelta;
+ var groupUsed;
+ var groupAvailable;
+ var groupTotal;
+ var groupPDisks;
+
+ if (group.DomElement === undefined) {
+ var groupRow = groupsView.insertRow();
+ var groupIdElement = groupRow.insertCell(-1);
+ groupIdElement.style.textAlign = "right";
+ groupIdElement.innerHTML = group.GroupID;
+ var groupTypeElement = groupRow.insertCell(-1);
+ groupTypeElement.innerHTML = group.GroupID & 0x80000000 ? "Dynamic" : "Static";
+ var groupErasureElement = groupRow.insertCell(-1);
+ groupErasureElement.innerHTML = getErasureText(group.ErasureSpecies);
+ groupLatency = document.createElement("div");
+ groupLatency.className = "latency-block";
+ groupRow.insertCell(-1).appendChild(groupLatency);
+ var groupCell = groupRow.insertCell(-1);
+ var groupElement = document.createElement("div");
+ groupUsage = document.createElement("div");
+ groupRow.insertCell(-1).appendChild(groupUsage);
+ groupDelta = document.createElement("div");
+ groupDelta.style.textAlign = "right";
+ groupRow.insertCell(-1).appendChild(groupDelta);
+ groupUsed = document.createElement("div");
+ groupUsed.style.textAlign = "right";
+ groupRow.insertCell(-1).appendChild(groupUsed);
+ groupAvailable = document.createElement("div");
+ groupAvailable.style.textAlign = "right";
+ groupRow.insertCell(-1).appendChild(groupAvailable);
+ groupTotal = document.createElement("div");
+ groupTotal.style.textAlign = "right";
+ groupRow.insertCell(-1).appendChild(groupTotal);
+ groupPDisks = document.createElement("div");
+ groupRow.insertCell(-1).appendChild(groupPDisks);
+ groupElement.className = "groupblock";
+ groupCell.appendChild(groupElement);
+ group.DomElement = groupElement;
+ } else {
+ groupLatency = group.DomElement.parentNode.previousSibling.firstChild;
+ groupUsage = group.DomElement.parentNode.nextSibling.firstChild;
+ groupDelta = groupUsage.parentNode.nextSibling.firstChild;
+ groupUsed = groupDelta.parentNode.nextSibling.firstChild;
+ groupAvailable = groupUsed.parentNode.nextSibling.firstChild;
+ groupTotal = groupAvailable.parentNode.nextSibling.firstChild;
+ groupPDisks = groupTotal.parentNode.nextSibling.firstChild;
+ }
+
+ groupLatency.innerHTML = getLatencyText(group.Latency);
+ groupLatency.style.backgroundColor = getLatencyColor(group.Latency);
+
+ var total = 0;
+ var used = 0;
+ var available = 0;
+ var groupPDisksMask = {};
+
+ for (var vDiskIdIdx in group.VDiskIds) {
+ var vDiskId = group.VDiskIds[vDiskIdIdx];
+ var vDiskIdKey = getVDiskIdKey(vDiskId);
+ var groupVDisk = group.VDisks[vDiskIdKey];
+ if (groupVDisk === undefined) {
+ groupVDisk = group.VDisks[vDiskIdKey] = {};
+ }
+ var vDiskGroupElement = groupVDisk.GroupDomElement;
+ if (vDiskGroupElement === undefined) {
+ var vDiskElement = groupVDisk.DomElement;
+ if (vDiskElement !== undefined) {
+ vDiskGroupElement = vDiskElement.cloneNode(true);
+ vDiskGroupElement.VDisk = groupVDisk;
+ vDiskGroupElement.addEventListener("click", onVDiskClick, false);
+ } else {
+ vDiskGroupElement = document.createElement("div");
+ vDiskGroupElement.className = "vdiskblock " + VDiskBlockWidthClass;
+ vDiskGroupElement.style.backgroundColor = "grey";
+ }
+ group.DomElement.appendChild(vDiskGroupElement);
+ groupVDisk.GroupDomElement = vDiskGroupElement;
+ }
+ used += asNumber(groupVDisk.AllocatedSize);
+ if (groupVDisk.NodeId !== undefined && groupVDisk.PDiskId !== undefined) {
+ var node = Nodes[groupVDisk.NodeId];
+ if (node.PDisks !== undefined) {
+ var pDisk = node.PDisks[groupVDisk.PDiskId];
+ if (pDisk !== undefined) {
+ var key = String(groupVDisk.NodeId) + "-" + String(groupVDisk.PDiskId);
+ initPDiskElement(groupPDisks, pDisk, key);
+ if (pDisk.AvailableSize !== undefined && pDisk.TotalSize !== undefined) {
+ if (groupPDisksMask[key] === undefined) {
+ total += asNumber(pDisk.TotalSize);
+ available += asNumber(pDisk.AvailableSize);
+ }
+ groupPDisksMask[key] = true;
+ if (totalPDisks[key] === undefined) {
+ totalTotal += asNumber(pDisk.TotalSize);
+ totalAvailable += asNumber(pDisk.AvailableSize);
+ totalPDisks[key] = true;
+ }
+ if (group.GroupID & 0x80000000) {
+ if (dynamicPDisks[key] === undefined) {
+ dynamicTotal += asNumber(pDisk.TotalSize);
+ dynamicAvailable += asNumber(pDisk.AvailableSize);
+ dynamicPDisks[key] = true;
+ }
+ } else {
+ if (staticPDisks[key] === undefined) {
+ staticTotal += asNumber(pDisk.TotalSize);
+ staticAvailable += asNumber(pDisk.AvailableSize);
+ staticPDisks[key] = true;
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ totalUsed += used;
+ if (group.GroupID & 0x80000000) {
+ dynamicUsed += used;
+ } else {
+ staticUsed += used;
+ }
+
+ if (total !== 0) {
+ groupUsage.innerHTML = getSizesProgressBarHtml(used, used + available);
+ updateBytesValue(groupUsed, used, groupDelta);
+ updateBytesValue(groupAvailable, available);
+ updateBytesValue(groupTotal, total);
+ }
+ }
+ var totalStorageElement = $("#storage").find(".totalstorage").get(0);
+ var totalElement = totalStorageElement.firstElementChild.nextElementSibling.firstElementChild.firstElementChild.nextElementSibling;
+ var dynamicElement = totalElement.parentNode.nextElementSibling.firstElementChild.nextElementSibling;
+ var staticElement = dynamicElement.parentNode.nextElementSibling.firstElementChild.nextElementSibling;
+
+ totalElement.innerHTML = getSizesProgressBarHtml(totalUsed, totalTotal);
+ totalElement = totalElement.nextElementSibling
+ totalElement.innerHTML = bytesToSize(totalUsed);
+ totalElement = totalElement.nextElementSibling
+ totalElement.innerHTML = bytesToSize(totalAvailable);
+ totalElement = totalElement.nextElementSibling
+ totalElement.innerHTML = bytesToSize(totalTotal);
+ dynamicElement.innerHTML = getSizesProgressBarHtml(dynamicUsed, dynamicTotal);
+ dynamicElement = dynamicElement.nextElementSibling;
+ dynamicElement.innerHTML = bytesToSize(dynamicUsed);
+ dynamicElement = dynamicElement.nextElementSibling;
+ dynamicElement.innerHTML = bytesToSize(dynamicAvailable);
+ dynamicElement = dynamicElement.nextElementSibling;
+ dynamicElement.innerHTML = bytesToSize(dynamicTotal);
+ staticElement.innerHTML = getSizesProgressBarHtml(staticUsed, staticTotal);
+ staticElement = staticElement.nextElementSibling;
+ staticElement.innerHTML = bytesToSize(staticUsed);
+ staticElement = staticElement.nextElementSibling;
+ staticElement.innerHTML = bytesToSize(staticAvailable);
+ staticElement = staticElement.nextElementSibling;
+ staticElement.innerHTML = bytesToSize(staticTotal);
+
+ setTimeout(refreshBSGroupInfo, refreshTimeout);
+ refreshBSGroupStats();
+}
+
+function onPDiskClick() {
+ window.open(getPDiskUrl(this.PDisk));
+}
+
+function getPDiskIcon(icon, color) {
+ return "<span class='glyphicon glyphicon-" + icon + "' style='color:" + color + ";text-shadow: 0 0 1px black;margin-right:2px;'></span>"
+}
+
+function getPDiskDeviceIcon(color) {
+ return getPDiskIcon("save", color);
+}
+
+function getPDiskRealtimeIcon(color) {
+ return getPDiskIcon("fire", color);
+}
+
+function onPDiskInfo(pDisksInfo) {
+ var pDiskStateInfo = null;
+ var refreshTimeout = refreshTimeoutPDisk();
+ if (pDisksInfo !== undefined && pDisksInfo !== null && typeof pDisksInfo === "object") {
+ if (pDisksInfo.PDiskStateInfo !== undefined) {
+ pDiskStateInfo = pDisksInfo.PDiskStateInfo;
+ }
+ if (pDiskStateInfo !== null) {
+ for (var idx in pDiskStateInfo) {
+ var pDiskInfo = pDiskStateInfo[idx];
+ var node = Nodes[pDiskInfo.NodeId];
+ if (node.PDisks === undefined) {
+ node.PDisks = {};
+ }
+ var pDisk = node.PDisks[pDiskInfo.PDiskId];
+ if (pDisk === undefined) {
+ pDisk = node.PDisks[pDiskInfo.PDiskId] = pDiskInfo;
+ } else {
+ for (var j in pDiskInfo) {
+ pDisk[j] = pDiskInfo[j];
+ }
+ }
+ var pDiskBlock = pDisk.BlockDomElement;
+ if (pDiskBlock === undefined) {
+ var pDiskCell = getPDiskPart(node, pDisk.PDiskId, pDisk);
+ pDiskBlock = pDiskCell.firstChild;
+ if (pDiskBlock === null) {
+ pDiskBlock = document.createElement("div");
+ pDiskBlock.className = 'progress pdiskblock';
+ pDiskBlock.PDisk = pDisk;
+ pDiskBlock.addEventListener("click", onPDiskClick, false);
+ pDiskBlock.style.position = 'relative';
+ pDiskCell.appendChild(pDiskBlock);
+ pDisk.BlockDomElement = pDiskBlock;
+ }
+ }
+
+ var state = "";
+ if (pDisk.State === 'Normal') {
+ pDiskBlock.style.backgroundColor = "lightblue";
+ state = "Normal";
+ pDisk.Color = green;
+ var total = pDisk.TotalSize;
+ var avail = pDisk.AvailableSize;
+ if (total !== undefined && avail !== undefined) {
+ var percent = ((total - avail) * 100 / total).toPrecision(3);
+ var html = "<div class='progress-bar ";
+ if (percent >= 90) {
+ html += "progress-bar-danger";
+ pDisk.Color = orange;
+ } else
+ if (percent >= 75) {
+ html += "progress-bar-warning";
+ pDisk.Color = yellow;
+ } else {
+ html += "progress-bar-success";
+ }
+
+ html += "' role='progressbar' aria-valuenow='";
+ html += percent;
+ html += "' aria-valuemin='0' aria-valuemax='100' style='width:" + percent + "%;font-size:10px;vertical-align:middle;padding-left:3px'>" + percent
+ + "%</div><div style='position:absolute;top:1px;right:1px;font-size:12px'>";
+
+ state += " (Available " + bytesToSize(avail) + " of " + bytesToSize(total) + ")";
+
+ if (pDisk.Realtime !== undefined) {
+ switch (pDisk.Realtime) {
+ case 'Yellow':
+ if (pDisk.Color !== orange) {
+ pDisk.Color = yellow;
+ }
+ html += getPDiskRealtimeIcon("yellow");
+ state += " Realtime:yellow";
+ break;
+ case 'Orange':
+ if (pDisk.Color !== red) {
+ pDisk.Color = orange;
+ }
+ html += getPDiskRealtimeIcon("orange");
+ state += " Realtime:orange";
+ break;
+ case 'Red':
+ pDisk.Color = red;
+ html += getPDiskRealtimeIcon("red");
+ state += " Realtime:red";
+ break;
+ }
+ }
+
+ if (pDisk.Device !== undefined) {
+ switch (pDisk.Device) {
+ case 'Yellow':
+ if (pDisk.Color !== orange && pDisk.Color !== red) {
+ pDisk.Color = yellow;
+ }
+ html += getPDiskDeviceIcon("yellow");
+ state += " Device:yellow";
+ break;
+ case 'Orange':
+ pDisk.Color = orange;
+ html += getPDiskDeviceIcon("orange");
+ state += " Device:orange";
+ break;
+ case 'Red':
+ pDisk.Color = red;
+ html += getPDiskDeviceIcon("red");
+ state += " Device:red";
+ break;
+ }
+ }
+
+ html += "</div>";
+ pDiskBlock.innerHTML = html;
+ if (pDisk.ClonedElements !== undefined) {
+ for (var i = 0; i < pDisk.ClonedElements.length; i++) {
+ pDisk.ClonedElements[i].innerHTML = html;
+ }
+ }
+ }
+ } else {
+ switch (pDisk.State) {
+ case 'Initial':
+ pDiskBlock.style.backgroundColor = grey;
+ pDisk.Color = grey;
+ state = pDisk.State;
+ break;
+ case 'Normal':
+ pDisk.Color = green;
+ // wtf?
+ break;
+ case 'InitialFormatRead':
+ case 'InitialSysLogRead':
+ case 'InitialCommonLogRead':
+ pDiskBlock.style.backgroundColor = yellow;
+ pDisk.Color = yellow;
+ state = pDisk.State;
+ break;
+ case 'InitialFormatReadError':
+ case 'InitialSysLogReadError':
+ case 'InitialSysLogParseError':
+ case 'InitialCommonLogReadError':
+ case 'InitialCommonLogParseError':
+ case 'CommonLoggerInitError':
+ case 'OpenFileError':
+ pDiskBlock.style.backgroundColor = red;
+ pDisk.Color = red;
+ state = pDisk.State;
+ break;
+ }
+ }
+ pDiskBlock.title = pDisk.Path + " " + state;
+ if (pDisk.ClonedElements !== undefined) {
+ var title = getNodeHost(pDiskInfo.NodeId) + " " + pDisk.Path + " " + state;
+ for (var i = 0; i < pDisk.ClonedElements.length; i++) {
+ pDisk.ClonedElements[i].title = title;
+ }
+ }
+ }
+ }
+ if (++PDiskRequest.request > 60) {
+ PDiskRequest.request = 0;
+ delete PDiskRequest.since;
+ } else {
+ PDiskRequest.since = pDisksInfo.ResponseTime;
+ }
+ } else {
+ PDiskRequest.request = 0;
+ delete PDiskRequest.since;
+ }
+ setTimeout(refreshPDiskInfo, refreshTimeout);
+ refreshPDiskStats();
+}
+
+function pad2(val) {
+ if (val < 10) {
+ return "0" + val;
+ } else {
+ return val;
+ }
+}
+
function pad4(val) {
var len = String(val).length;
for (var i = len; i < 4; i++) {
@@ -977,521 +977,521 @@ function pad4(val) {
return val;
}
-function pad9(val) {
- var len = String(val).length;
- for (var i = len; i < 9; i++) {
- val = "0" + val;
- }
- return val;
-}
-
-function upTimeToString(upTime) {
- var seconds = Math.floor(upTime / 1000);
- if (seconds < 60) {
- return seconds + "s";
- } else {
- var minutes = Math.floor(seconds / 60);
- seconds = seconds % 60;
- if (minutes < 60) {
- return minutes + ":" + pad2(seconds);
- } else {
- var hours = Math.floor(minutes / 60);
- minutes = minutes % 60;
- if (hours < 24) {
- return hours + ":" + pad2(minutes) + ":" + pad2(seconds);
- } else {
- var days = Math.floor(hours / 24);
- hours = hours % 24;
- return days + "d " + pad2(hours) + ":" + pad2(minutes) + ":" + pad2(seconds);
- }
- }
- }
-}
-
-function onDisconnectNode(node) {
- var cell = node.DomElement.cells[2];
- cell.innerHTML = "<span class='glyphicon glyphicon-eye-close'></span>";
- var cells = node.DomElement.cells.length;
- for (var i = cells - 1; i >= 5; i--) {
- node.DomElement.deleteCell(i);
- }
- for (var id in Nodes) {
- if (node.NodeStateInfo !== undefined && node.NodeStateInfo[id] !== undefined) {
- delete node.NodeStateInfo[id].Connected;
- }
- setInterconnectMap(node, id, "lightgrey");
- setPoolsMap(node, []);
- }
- var block = node.DomElement.cells[1].firstChild.nextSibling.firstChild;
- block.style.backgroundColor = "lightgrey";
- block = block.nextSibling;
- block.style.backgroundColor = "lightgrey";
- block = block.nextSibling;
- var progress = block.firstChild;
- progress.style.backgroundColor = "lightgrey";
- progress.style.width = '0%';
- delete node.SysInfo;
- delete node.PDisks;
- delete node.VDisks;
-}
-
-function flagToColor(flag) {
- switch (flag) {
- case 'Green':
- return green;
- case 'Yellow':
- return yellow;
- case 'Orange':
- return orange;
- case 'Red':
- return red;
- default:
- return grey;
- }
-}
-
-function onSysInfo(sysInfo) {
- var cell;
- var ssInfo;
- var refreshTimeout = refreshTimeoutSys();
- if (sysInfo !== undefined && sysInfo !== null && typeof sysInfo === "object") {
- if (SysRequest.since === undefined) {
- for (var nodeId in Nodes) {
- delete Nodes[nodeId].SysInfo;
- }
- }
-
- if (sysInfo.SystemStateInfo !== undefined) {
- for (var idx in sysInfo.SystemStateInfo) {
- ssInfo = sysInfo.SystemStateInfo[idx];
- cell = Nodes[ssInfo.NodeId].DomElement.cells[2];
- Nodes[ssInfo.NodeId].SysInfo = ssInfo;
- }
- }
- if (++SysRequest.request > 10) {
- SysRequest.request = 0;
- delete SysRequest.since;
- } else {
- if (sysInfo.ResponseTime !== undefined && Number(sysInfo.ResponseTime) > 0)
- SysRequest.since = sysInfo.ResponseTime;
- }
- } else {
- SysRequest.request = 0;
- delete SysRequest.since;
- for (var nodeId in Nodes) {
- delete Nodes[nodeId].SysInfo;
- }
- }
- var goodNodes = 0;
- var totalNodes = 0;
- var currentTime = new Date().valueOf();
- for (var nodeId in Nodes) {
- var node = Nodes[nodeId];
- ssInfo = node.SysInfo;
- if (ssInfo !== undefined) {
- cell = node.DomElement.cells[2];
- var startTime = ssInfo.StartTime;
- var upTime = currentTime - startTime;
- cell.innerHTML = upTimeToString(upTime);
- var block = node.DomElement.cells[1].firstChild.nextSibling.firstChild;
- if (ssInfo.SystemState !== undefined) {
- block.style.backgroundColor = flagToColor(ssInfo.SystemState);
- }
- block = block.nextSibling;
- if (ssInfo.MessageBusState !== undefined) {
- block.style.backgroundColor = flagToColor(ssInfo.MessageBusState);
- }
- block = block.nextSibling;
- if (ssInfo.LoadAverage !== undefined) {
- var percent = ssInfo.LoadAverage[0] * 100 / ssInfo.NumberOfCpus;
- if (percent > 100) {
- percent = 100;
- }
- var progress = block.firstChild;
- if (percent < 75) {
- progress.style.backgroundColor = green;
- } else if (percent < 85) {
- progress.style.backgroundColor = yellow;
- } else if (percent < 95) {
- progress.style.backgroundColor = orange;
- } else {
- progress.style.backgroundColor = red;
- }
- progress.style.width = percent + '%';
- block.title = "LoadAverage: " + ssInfo.LoadAverage + " / " + ssInfo.NumberOfCpus;
- }
- if (ssInfo.PoolStats !== undefined) {
- setPoolsMap(node, ssInfo.PoolStats);
- }
- goodNodes++;
- } else {
- onDisconnectNode(node);
- }
- totalNodes++;
- }
- refreshNodeStats();
- setTimeout(refreshSysInfo, refreshTimeout);
-}
-
-var NodeStatsDomElement = null;
-
-function refreshNodeStats() {
- var nodeStats = [0, 0, 0, 0, 0];
- var currentTime = new Date().valueOf();
- for (var id in Nodes) {
- var node = Nodes[id];
- var sysInfo = node.SysInfo;
- if (sysInfo === undefined) {
- nodeStats[0]++;
- } else {
- var startTime = sysInfo.StartTime;
- var upTime = currentTime - startTime;
- if (upTime < 60 * 1000) {
- nodeStats[1]++;
- } else if (upTime < 60 * 60 * 1000) {
- nodeStats[2]++;
- } else if (upTime < 24 * 60 * 60 * 1000) {
- nodeStats[3]++;
- } else {
- nodeStats[4]++;
- }
- }
- }
- if (NodeStatsDomElement === null) {
- NodeStatsDomElement = $("#overview").find(".node-stats").get(0);
- /*// target color is lightgreen #90ee90
- var max_i = nodeStats.length - 1;
- for (var i = 0; i < nodeStats.length; ++i) {
- NodeStatsDomElement.rows[1].cells[i + 1].style.color =
- "rgb(" + Math.floor(i * 0x90 / max_i)
- + "," + Math.floor(i * 0xee / max_i)
- + "," + Math.floor(i * 0x90 / max_i) + ")";
- }*/
- }
- var nodesRow = NodeStatsDomElement.rows[1];
- for (var i = 0; i < nodeStats.length; ++i) {
- var value = nodeStats[i];
- var cell = nodesRow.cells[i + 1];
- if (value === 0) {
- cell.innerHTML = "";
- $(cell).stop().css(StatsAnimateStop);
- } else {
- cell.innerHTML = value;
- $(cell).stop().css(StatsAnimateStop).animate(StatsAnimateStart, StatsAnimateDuration);
- }
- }
-}
-
-function updateStatsCell(cell, value) {
- if (value === 0) {
- cell.innerHTML = "";
- $(cell).stop().css(StatsAnimateStop);
- } else {
- cell.innerHTML = value;
- $(cell).stop().css(StatsAnimateStop).animate(StatsAnimateStart, StatsAnimateDuration);
- }
-}
-
-var DiskStatsDomElement = null;
-
-function refreshVDiskStats() {
- var vDiskStats = {Grey: 0, Red: 0, Orange: 0, Yellow: 0, Green: 0};
- for (var idGroup in Groups) {
- var group = Groups[idGroup];
- for (var idVDisk in group.VDisks) {
- switch (group.VDisks[idVDisk].Color) {
- case red:
- vDiskStats.Red++;
- break;
- case orange:
- vDiskStats.Orange++;
- break;
- case yellow:
- vDiskStats.Yellow++;
- break;
- case green:
- vDiskStats.Green++;
- break;
- default:
- vDiskStats.Grey++;
- break;
- }
- }
- }
- if (DiskStatsDomElement === null) {
- DiskStatsDomElement = $("#overview").find(".disk-stats").get(0);
- }
- var vDiskRow = DiskStatsDomElement.rows[2];
- updateStatsCell(vDiskRow.cells[1], vDiskStats.Grey);
- updateStatsCell(vDiskRow.cells[2], vDiskStats.Red);
- updateStatsCell(vDiskRow.cells[3], vDiskStats.Orange);
- updateStatsCell(vDiskRow.cells[4], vDiskStats.Yellow);
- updateStatsCell(vDiskRow.cells[5], vDiskStats.Green);
-}
-
-function refreshPDiskStats() {
- var pDiskStats = {Grey: 0, Red: 0, Orange: 0, Yellow: 0, Green: 0};
- for (var idNode in Nodes) {
- var node = Nodes[idNode];
- for (var idPDisk in node.PDisks) {
- switch (node.PDisks[idPDisk].Color) {
- case red:
- pDiskStats.Red++;
- break;
- case orange:
- pDiskStats.Orange++;
- break;
- case yellow:
- pDiskStats.Yellow++;
- break;
- case green:
- pDiskStats.Green++;
- break;
- default:
- pDiskStats.Grey++;
- break;
- }
- }
- }
- if (DiskStatsDomElement === null) {
- DiskStatsDomElement = $("#overview").find(".disk-stats").get(0);
- }
- var pDiskRow = DiskStatsDomElement.rows[1];
- updateStatsCell(pDiskRow.cells[1], pDiskStats.Grey);
- updateStatsCell(pDiskRow.cells[2], pDiskStats.Red);
- updateStatsCell(pDiskRow.cells[3], pDiskStats.Orange);
- updateStatsCell(pDiskRow.cells[4], pDiskStats.Yellow);
- updateStatsCell(pDiskRow.cells[5], pDiskStats.Green);
-}
-
-function refreshBSGroupStats() {
- var bsGroupStats = {Grey: 0, Red: 0, Orange: 0, Yellow: 0, Green: 0};
- for (var idGroup in Groups) {
- var group = Groups[idGroup];
- var vDiskStats = {Grey: 0, Green: 0};
- for (var idVDisk in group.VDisks) {
- switch (group.VDisks[idVDisk].Color) {
- case green:
- vDiskStats.Green++;
- break;
- default:
- vDiskStats.Grey++;
- break;
- }
- }
- var erasureInfo = getErasureInfo(group.ErasureSpecies);
- if (vDiskStats.Green >= erasureInfo.Total) {
- bsGroupStats.Green++;
- } else if (vDiskStats.Green > erasureInfo.Min) {
- bsGroupStats.Yellow++;
- } else if (vDiskStats.Green === erasureInfo.Min) {
- bsGroupStats.Orange++;
- } else if (vDiskStats.Green > 0) {
- bsGroupStats.Red++;
- } else {
- bsGroupStats.Grey++;
- }
- }
- if (DiskStatsDomElement === null) {
- DiskStatsDomElement = $("#overview").find(".disk-stats").get(0);
- }
- var bsGroupRow = DiskStatsDomElement.rows[3];
- updateStatsCell(bsGroupRow.cells[1], bsGroupStats.Grey);
- updateStatsCell(bsGroupRow.cells[2], bsGroupStats.Red);
- updateStatsCell(bsGroupRow.cells[3], bsGroupStats.Orange);
- updateStatsCell(bsGroupRow.cells[4], bsGroupStats.Yellow);
- updateStatsCell(bsGroupRow.cells[5], bsGroupStats.Green);
-}
-
-// temporary constants - to be computed dynamically
-var warningOutputQueueSize = 200; // waiting for colorful flags from Interconnect
-var errorOutputQueueSize = 500;
-var minColorComponent = 0x90;
-var maxColorComponent = 0xee;
-var rangeColorComponent = maxColorComponent - minColorComponent + 1;
-
-function onNodeInfo(nodeInfo) {
- var nodeStateInfo = null;
- if (NodeRequest.since === undefined) {
- for (var i in Nodes) {
- delete Nodes[i].NodeStateInfo;
- }
- }
- if (++NodeRequest.request > 20) {
- NodeRequest.request = 0;
- }
- delete NodeRequest.since;
- if (nodeInfo !== undefined && nodeInfo !== null && typeof nodeInfo === "object") {
- for (var nodeId in nodeInfo) {
- var node = Nodes[nodeId];
- if (node === undefined)
- continue;
- nodeStateInfo = nodeInfo[nodeId];
- if (nodeStateInfo === null) {
- onDisconnectNode(node);
- } else {
- nodeStateInfo = nodeStateInfo.NodeStateInfo;
- if (node.NodeStateInfo === undefined) {
- node.NodeStateInfo = {};
- }
- for (var i in nodeStateInfo) {
- var stateInfo = nodeStateInfo[i];
- var peerName = stateInfo.PeerName;
- var id = Number(peerName.split(':')[0]);
- var ni = node.NodeStateInfo[id];
- if (ni === undefined
- || ni.Connected !== stateInfo.Connected
- || ni.OutputQueueSize !== stateInfo.OutputQueueSize
- || ni.ConnectStatus !== stateInfo.ConnectStatus) {
- ni = node.NodeStateInfo[id] = stateInfo;
- if (stateInfo.Connected === undefined) {
- setInterconnectMap(node, id, "lightgrey"/*, getNodeHost(id)*/);
- } else {
- var interconnectColor;
- if (stateInfo.Connected) {
- //var title = getNodeHost(id) + " Connected";
- if (ni.OutputQueueSize !== undefined) {
- //title += ", Queue Size " + bytesToSize(ni.OutputQueueSize);
- var r, g, b;
- if (ni.OutputQueueSize <= warningOutputQueueSize) {
- r = minColorComponent + (ni.OutputQueueSize / warningOutputQueueSize * rangeColorComponent);
- g = maxColorComponent;
- b = minColorComponent;
- } else {
- var qs = ni.OutputQueueSize - warningOutputQueueSize;
- var rqs = errorOutputQueueSize - warningOutputQueueSize;
- if (qs > rqs) {
- qs = rqs;
- }
- r = maxColorComponent;
- g = maxColorComponent - (qs / rqs * rangeColorComponent);
- b = minColorComponent;
- }
- interconnectColor = "rgb(" + Math.floor(r) + "," + Math.floor(g) + "," + Math.floor(b) + ")";
- } else {
- interconnectColor = "lightgreen";
- }
- if (ni.ConnectStatus !== undefined) {
- switch (ni.ConnectStatus) {
- case 1:
- interconnectColor = green;
- break;
- case 2:
- interconnectColor = yellow;
- break;
- case 3:
- interconnectColor = orange;
- break;
- case 4:
- interconnectColor = red;
- break;
- }
- }
- setInterconnectMap(node, id, interconnectColor/*, title*/);
- } else {
- setInterconnectMap(node, id, "red"/*, getNodeHost(id) + " Disconnected"*/);
- }
- }
- }
- }
- if (NodeRequest.request !== 0
- && (NodeRequest.since === undefined
- || NodeRequest.since > nodeInfo[nodeId].ResponseTime)) {
- NodeRequest.since = nodeInfo[nodeId].ResponseTime;
- }
- }
- }
- } else {
- // NodeInfoChangeTime = null;
- }
- setTimeout(refreshNodeInfo, refreshTimeoutNode());
-}
-
-function clearNodeInfo(nodeId) {
- return;
- /*var row = nodelist[nodeId - 1].DomElement;
- var cell = row.cells[3];
- var n = nodelist.length;
- for (var i = 0; i < n; i++) {
- getNodeCell(cell, i + 1).innerHTML = getNodeBlock(nodelist[i].Host, "lightgrey");
- }
- while (row.cells.length > 4) {
- row.removeChild(row.cells[4]);
- }*/
-}
-
-function tabletStateToColor(state) {
- switch (state) {
- case "Created": return "grey";
- case "ResolveStateStorage": return "lightgrey";
- case "Candidate": return "lightgrey";
- case "BlockBlobStorage": return "lightgrey";
- case "RebuildGraph": return "yellow";
- case "WriteZeroEntry": return "yellow";
- case "Restored": return "yellow";
- case "Discover": return "orange";
- case "Lock": return "lightblue";
- case "Dead": return "black";
- case "Active": return "lightgreen";
- }
- return "brown";
-}
-
-function tabletToColor(tablet) {
- return tabletStateToColor(tablet.State);
-}
-
-function tabletToString(tablet) {
- return tablet.State;
-}
-
-function tabletTypeToString(type) {
- switch(type) {
- case "OldTxProxy":
- return "TxProxy";
- }
- return type;
-}
-
-function tabletTypeToSymbol(type) {
- switch(type) {
- case "SchemeShard":
- return "SS";
- case "DataShard":
- return "DS";
- case "Hive":
- return "H";
- case "Coordinator":
- return "C";
- case "Mediator":
- return "M";
- case "OldTxProxy":
- case "TxProxy":
- return "P";
- case "BSController":
- return "BS";
- case "Dummy":
- return "DY";
- case "JobRunner":
- return "JR";
- case "RTMRPartition":
- return "RP";
- case "KeyValue":
- return "KV";
- case "PersQueue":
- return "PQ";
- case "PersQueueReadBalancer":
- return "PB";
- case "NodeBroker":
- return "NB";
- case "TxAllocator":
- return "TA";
+function pad9(val) {
+ var len = String(val).length;
+ for (var i = len; i < 9; i++) {
+ val = "0" + val;
+ }
+ return val;
+}
+
+function upTimeToString(upTime) {
+ var seconds = Math.floor(upTime / 1000);
+ if (seconds < 60) {
+ return seconds + "s";
+ } else {
+ var minutes = Math.floor(seconds / 60);
+ seconds = seconds % 60;
+ if (minutes < 60) {
+ return minutes + ":" + pad2(seconds);
+ } else {
+ var hours = Math.floor(minutes / 60);
+ minutes = minutes % 60;
+ if (hours < 24) {
+ return hours + ":" + pad2(minutes) + ":" + pad2(seconds);
+ } else {
+ var days = Math.floor(hours / 24);
+ hours = hours % 24;
+ return days + "d " + pad2(hours) + ":" + pad2(minutes) + ":" + pad2(seconds);
+ }
+ }
+ }
+}
+
+function onDisconnectNode(node) {
+ var cell = node.DomElement.cells[2];
+ cell.innerHTML = "<span class='glyphicon glyphicon-eye-close'></span>";
+ var cells = node.DomElement.cells.length;
+ for (var i = cells - 1; i >= 5; i--) {
+ node.DomElement.deleteCell(i);
+ }
+ for (var id in Nodes) {
+ if (node.NodeStateInfo !== undefined && node.NodeStateInfo[id] !== undefined) {
+ delete node.NodeStateInfo[id].Connected;
+ }
+ setInterconnectMap(node, id, "lightgrey");
+ setPoolsMap(node, []);
+ }
+ var block = node.DomElement.cells[1].firstChild.nextSibling.firstChild;
+ block.style.backgroundColor = "lightgrey";
+ block = block.nextSibling;
+ block.style.backgroundColor = "lightgrey";
+ block = block.nextSibling;
+ var progress = block.firstChild;
+ progress.style.backgroundColor = "lightgrey";
+ progress.style.width = '0%';
+ delete node.SysInfo;
+ delete node.PDisks;
+ delete node.VDisks;
+}
+
+function flagToColor(flag) {
+ switch (flag) {
+ case 'Green':
+ return green;
+ case 'Yellow':
+ return yellow;
+ case 'Orange':
+ return orange;
+ case 'Red':
+ return red;
+ default:
+ return grey;
+ }
+}
+
+function onSysInfo(sysInfo) {
+ var cell;
+ var ssInfo;
+ var refreshTimeout = refreshTimeoutSys();
+ if (sysInfo !== undefined && sysInfo !== null && typeof sysInfo === "object") {
+ if (SysRequest.since === undefined) {
+ for (var nodeId in Nodes) {
+ delete Nodes[nodeId].SysInfo;
+ }
+ }
+
+ if (sysInfo.SystemStateInfo !== undefined) {
+ for (var idx in sysInfo.SystemStateInfo) {
+ ssInfo = sysInfo.SystemStateInfo[idx];
+ cell = Nodes[ssInfo.NodeId].DomElement.cells[2];
+ Nodes[ssInfo.NodeId].SysInfo = ssInfo;
+ }
+ }
+ if (++SysRequest.request > 10) {
+ SysRequest.request = 0;
+ delete SysRequest.since;
+ } else {
+ if (sysInfo.ResponseTime !== undefined && Number(sysInfo.ResponseTime) > 0)
+ SysRequest.since = sysInfo.ResponseTime;
+ }
+ } else {
+ SysRequest.request = 0;
+ delete SysRequest.since;
+ for (var nodeId in Nodes) {
+ delete Nodes[nodeId].SysInfo;
+ }
+ }
+ var goodNodes = 0;
+ var totalNodes = 0;
+ var currentTime = new Date().valueOf();
+ for (var nodeId in Nodes) {
+ var node = Nodes[nodeId];
+ ssInfo = node.SysInfo;
+ if (ssInfo !== undefined) {
+ cell = node.DomElement.cells[2];
+ var startTime = ssInfo.StartTime;
+ var upTime = currentTime - startTime;
+ cell.innerHTML = upTimeToString(upTime);
+ var block = node.DomElement.cells[1].firstChild.nextSibling.firstChild;
+ if (ssInfo.SystemState !== undefined) {
+ block.style.backgroundColor = flagToColor(ssInfo.SystemState);
+ }
+ block = block.nextSibling;
+ if (ssInfo.MessageBusState !== undefined) {
+ block.style.backgroundColor = flagToColor(ssInfo.MessageBusState);
+ }
+ block = block.nextSibling;
+ if (ssInfo.LoadAverage !== undefined) {
+ var percent = ssInfo.LoadAverage[0] * 100 / ssInfo.NumberOfCpus;
+ if (percent > 100) {
+ percent = 100;
+ }
+ var progress = block.firstChild;
+ if (percent < 75) {
+ progress.style.backgroundColor = green;
+ } else if (percent < 85) {
+ progress.style.backgroundColor = yellow;
+ } else if (percent < 95) {
+ progress.style.backgroundColor = orange;
+ } else {
+ progress.style.backgroundColor = red;
+ }
+ progress.style.width = percent + '%';
+ block.title = "LoadAverage: " + ssInfo.LoadAverage + " / " + ssInfo.NumberOfCpus;
+ }
+ if (ssInfo.PoolStats !== undefined) {
+ setPoolsMap(node, ssInfo.PoolStats);
+ }
+ goodNodes++;
+ } else {
+ onDisconnectNode(node);
+ }
+ totalNodes++;
+ }
+ refreshNodeStats();
+ setTimeout(refreshSysInfo, refreshTimeout);
+}
+
+var NodeStatsDomElement = null;
+
+function refreshNodeStats() {
+ var nodeStats = [0, 0, 0, 0, 0];
+ var currentTime = new Date().valueOf();
+ for (var id in Nodes) {
+ var node = Nodes[id];
+ var sysInfo = node.SysInfo;
+ if (sysInfo === undefined) {
+ nodeStats[0]++;
+ } else {
+ var startTime = sysInfo.StartTime;
+ var upTime = currentTime - startTime;
+ if (upTime < 60 * 1000) {
+ nodeStats[1]++;
+ } else if (upTime < 60 * 60 * 1000) {
+ nodeStats[2]++;
+ } else if (upTime < 24 * 60 * 60 * 1000) {
+ nodeStats[3]++;
+ } else {
+ nodeStats[4]++;
+ }
+ }
+ }
+ if (NodeStatsDomElement === null) {
+ NodeStatsDomElement = $("#overview").find(".node-stats").get(0);
+ /*// target color is lightgreen #90ee90
+ var max_i = nodeStats.length - 1;
+ for (var i = 0; i < nodeStats.length; ++i) {
+ NodeStatsDomElement.rows[1].cells[i + 1].style.color =
+ "rgb(" + Math.floor(i * 0x90 / max_i)
+ + "," + Math.floor(i * 0xee / max_i)
+ + "," + Math.floor(i * 0x90 / max_i) + ")";
+ }*/
+ }
+ var nodesRow = NodeStatsDomElement.rows[1];
+ for (var i = 0; i < nodeStats.length; ++i) {
+ var value = nodeStats[i];
+ var cell = nodesRow.cells[i + 1];
+ if (value === 0) {
+ cell.innerHTML = "";
+ $(cell).stop().css(StatsAnimateStop);
+ } else {
+ cell.innerHTML = value;
+ $(cell).stop().css(StatsAnimateStop).animate(StatsAnimateStart, StatsAnimateDuration);
+ }
+ }
+}
+
+function updateStatsCell(cell, value) {
+ if (value === 0) {
+ cell.innerHTML = "";
+ $(cell).stop().css(StatsAnimateStop);
+ } else {
+ cell.innerHTML = value;
+ $(cell).stop().css(StatsAnimateStop).animate(StatsAnimateStart, StatsAnimateDuration);
+ }
+}
+
+var DiskStatsDomElement = null;
+
+function refreshVDiskStats() {
+ var vDiskStats = {Grey: 0, Red: 0, Orange: 0, Yellow: 0, Green: 0};
+ for (var idGroup in Groups) {
+ var group = Groups[idGroup];
+ for (var idVDisk in group.VDisks) {
+ switch (group.VDisks[idVDisk].Color) {
+ case red:
+ vDiskStats.Red++;
+ break;
+ case orange:
+ vDiskStats.Orange++;
+ break;
+ case yellow:
+ vDiskStats.Yellow++;
+ break;
+ case green:
+ vDiskStats.Green++;
+ break;
+ default:
+ vDiskStats.Grey++;
+ break;
+ }
+ }
+ }
+ if (DiskStatsDomElement === null) {
+ DiskStatsDomElement = $("#overview").find(".disk-stats").get(0);
+ }
+ var vDiskRow = DiskStatsDomElement.rows[2];
+ updateStatsCell(vDiskRow.cells[1], vDiskStats.Grey);
+ updateStatsCell(vDiskRow.cells[2], vDiskStats.Red);
+ updateStatsCell(vDiskRow.cells[3], vDiskStats.Orange);
+ updateStatsCell(vDiskRow.cells[4], vDiskStats.Yellow);
+ updateStatsCell(vDiskRow.cells[5], vDiskStats.Green);
+}
+
+function refreshPDiskStats() {
+ var pDiskStats = {Grey: 0, Red: 0, Orange: 0, Yellow: 0, Green: 0};
+ for (var idNode in Nodes) {
+ var node = Nodes[idNode];
+ for (var idPDisk in node.PDisks) {
+ switch (node.PDisks[idPDisk].Color) {
+ case red:
+ pDiskStats.Red++;
+ break;
+ case orange:
+ pDiskStats.Orange++;
+ break;
+ case yellow:
+ pDiskStats.Yellow++;
+ break;
+ case green:
+ pDiskStats.Green++;
+ break;
+ default:
+ pDiskStats.Grey++;
+ break;
+ }
+ }
+ }
+ if (DiskStatsDomElement === null) {
+ DiskStatsDomElement = $("#overview").find(".disk-stats").get(0);
+ }
+ var pDiskRow = DiskStatsDomElement.rows[1];
+ updateStatsCell(pDiskRow.cells[1], pDiskStats.Grey);
+ updateStatsCell(pDiskRow.cells[2], pDiskStats.Red);
+ updateStatsCell(pDiskRow.cells[3], pDiskStats.Orange);
+ updateStatsCell(pDiskRow.cells[4], pDiskStats.Yellow);
+ updateStatsCell(pDiskRow.cells[5], pDiskStats.Green);
+}
+
+function refreshBSGroupStats() {
+ var bsGroupStats = {Grey: 0, Red: 0, Orange: 0, Yellow: 0, Green: 0};
+ for (var idGroup in Groups) {
+ var group = Groups[idGroup];
+ var vDiskStats = {Grey: 0, Green: 0};
+ for (var idVDisk in group.VDisks) {
+ switch (group.VDisks[idVDisk].Color) {
+ case green:
+ vDiskStats.Green++;
+ break;
+ default:
+ vDiskStats.Grey++;
+ break;
+ }
+ }
+ var erasureInfo = getErasureInfo(group.ErasureSpecies);
+ if (vDiskStats.Green >= erasureInfo.Total) {
+ bsGroupStats.Green++;
+ } else if (vDiskStats.Green > erasureInfo.Min) {
+ bsGroupStats.Yellow++;
+ } else if (vDiskStats.Green === erasureInfo.Min) {
+ bsGroupStats.Orange++;
+ } else if (vDiskStats.Green > 0) {
+ bsGroupStats.Red++;
+ } else {
+ bsGroupStats.Grey++;
+ }
+ }
+ if (DiskStatsDomElement === null) {
+ DiskStatsDomElement = $("#overview").find(".disk-stats").get(0);
+ }
+ var bsGroupRow = DiskStatsDomElement.rows[3];
+ updateStatsCell(bsGroupRow.cells[1], bsGroupStats.Grey);
+ updateStatsCell(bsGroupRow.cells[2], bsGroupStats.Red);
+ updateStatsCell(bsGroupRow.cells[3], bsGroupStats.Orange);
+ updateStatsCell(bsGroupRow.cells[4], bsGroupStats.Yellow);
+ updateStatsCell(bsGroupRow.cells[5], bsGroupStats.Green);
+}
+
+// temporary constants - to be computed dynamically
+var warningOutputQueueSize = 200; // waiting for colorful flags from Interconnect
+var errorOutputQueueSize = 500;
+var minColorComponent = 0x90;
+var maxColorComponent = 0xee;
+var rangeColorComponent = maxColorComponent - minColorComponent + 1;
+
+function onNodeInfo(nodeInfo) {
+ var nodeStateInfo = null;
+ if (NodeRequest.since === undefined) {
+ for (var i in Nodes) {
+ delete Nodes[i].NodeStateInfo;
+ }
+ }
+ if (++NodeRequest.request > 20) {
+ NodeRequest.request = 0;
+ }
+ delete NodeRequest.since;
+ if (nodeInfo !== undefined && nodeInfo !== null && typeof nodeInfo === "object") {
+ for (var nodeId in nodeInfo) {
+ var node = Nodes[nodeId];
+ if (node === undefined)
+ continue;
+ nodeStateInfo = nodeInfo[nodeId];
+ if (nodeStateInfo === null) {
+ onDisconnectNode(node);
+ } else {
+ nodeStateInfo = nodeStateInfo.NodeStateInfo;
+ if (node.NodeStateInfo === undefined) {
+ node.NodeStateInfo = {};
+ }
+ for (var i in nodeStateInfo) {
+ var stateInfo = nodeStateInfo[i];
+ var peerName = stateInfo.PeerName;
+ var id = Number(peerName.split(':')[0]);
+ var ni = node.NodeStateInfo[id];
+ if (ni === undefined
+ || ni.Connected !== stateInfo.Connected
+ || ni.OutputQueueSize !== stateInfo.OutputQueueSize
+ || ni.ConnectStatus !== stateInfo.ConnectStatus) {
+ ni = node.NodeStateInfo[id] = stateInfo;
+ if (stateInfo.Connected === undefined) {
+ setInterconnectMap(node, id, "lightgrey"/*, getNodeHost(id)*/);
+ } else {
+ var interconnectColor;
+ if (stateInfo.Connected) {
+ //var title = getNodeHost(id) + " Connected";
+ if (ni.OutputQueueSize !== undefined) {
+ //title += ", Queue Size " + bytesToSize(ni.OutputQueueSize);
+ var r, g, b;
+ if (ni.OutputQueueSize <= warningOutputQueueSize) {
+ r = minColorComponent + (ni.OutputQueueSize / warningOutputQueueSize * rangeColorComponent);
+ g = maxColorComponent;
+ b = minColorComponent;
+ } else {
+ var qs = ni.OutputQueueSize - warningOutputQueueSize;
+ var rqs = errorOutputQueueSize - warningOutputQueueSize;
+ if (qs > rqs) {
+ qs = rqs;
+ }
+ r = maxColorComponent;
+ g = maxColorComponent - (qs / rqs * rangeColorComponent);
+ b = minColorComponent;
+ }
+ interconnectColor = "rgb(" + Math.floor(r) + "," + Math.floor(g) + "," + Math.floor(b) + ")";
+ } else {
+ interconnectColor = "lightgreen";
+ }
+ if (ni.ConnectStatus !== undefined) {
+ switch (ni.ConnectStatus) {
+ case 1:
+ interconnectColor = green;
+ break;
+ case 2:
+ interconnectColor = yellow;
+ break;
+ case 3:
+ interconnectColor = orange;
+ break;
+ case 4:
+ interconnectColor = red;
+ break;
+ }
+ }
+ setInterconnectMap(node, id, interconnectColor/*, title*/);
+ } else {
+ setInterconnectMap(node, id, "red"/*, getNodeHost(id) + " Disconnected"*/);
+ }
+ }
+ }
+ }
+ if (NodeRequest.request !== 0
+ && (NodeRequest.since === undefined
+ || NodeRequest.since > nodeInfo[nodeId].ResponseTime)) {
+ NodeRequest.since = nodeInfo[nodeId].ResponseTime;
+ }
+ }
+ }
+ } else {
+ // NodeInfoChangeTime = null;
+ }
+ setTimeout(refreshNodeInfo, refreshTimeoutNode());
+}
+
+function clearNodeInfo(nodeId) {
+ return;
+ /*var row = nodelist[nodeId - 1].DomElement;
+ var cell = row.cells[3];
+ var n = nodelist.length;
+ for (var i = 0; i < n; i++) {
+ getNodeCell(cell, i + 1).innerHTML = getNodeBlock(nodelist[i].Host, "lightgrey");
+ }
+ while (row.cells.length > 4) {
+ row.removeChild(row.cells[4]);
+ }*/
+}
+
+function tabletStateToColor(state) {
+ switch (state) {
+ case "Created": return "grey";
+ case "ResolveStateStorage": return "lightgrey";
+ case "Candidate": return "lightgrey";
+ case "BlockBlobStorage": return "lightgrey";
+ case "RebuildGraph": return "yellow";
+ case "WriteZeroEntry": return "yellow";
+ case "Restored": return "yellow";
+ case "Discover": return "orange";
+ case "Lock": return "lightblue";
+ case "Dead": return "black";
+ case "Active": return "lightgreen";
+ }
+ return "brown";
+}
+
+function tabletToColor(tablet) {
+ return tabletStateToColor(tablet.State);
+}
+
+function tabletToString(tablet) {
+ return tablet.State;
+}
+
+function tabletTypeToString(type) {
+ switch(type) {
+ case "OldTxProxy":
+ return "TxProxy";
+ }
+ return type;
+}
+
+function tabletTypeToSymbol(type) {
+ switch(type) {
+ case "SchemeShard":
+ return "SS";
+ case "DataShard":
+ return "DS";
+ case "Hive":
+ return "H";
+ case "Coordinator":
+ return "C";
+ case "Mediator":
+ return "M";
+ case "OldTxProxy":
+ case "TxProxy":
+ return "P";
+ case "BSController":
+ return "BS";
+ case "Dummy":
+ return "DY";
+ case "JobRunner":
+ return "JR";
+ case "RTMRPartition":
+ return "RP";
+ case "KeyValue":
+ return "KV";
+ case "PersQueue":
+ return "PQ";
+ case "PersQueueReadBalancer":
+ return "PB";
+ case "NodeBroker":
+ return "NB";
+ case "TxAllocator":
+ return "TA";
case "Cms":
- return "CM";
- case "BlockStorePartition":
- return "BP";
- case "BlockStoreVolume":
- return "BV";
+ return "CM";
+ case "BlockStorePartition":
+ return "BP";
+ case "BlockStoreVolume":
+ return "BV";
case "Console":
return "CN";
case "TenantSlotBroker":
@@ -1506,724 +1506,724 @@ function tabletTypeToSymbol(type) {
return "S";
case "ReplicationController":
return "RC";
- }
- return "XX";
-}
-
-function tabletTypeToColor(type) {
- switch(type) {
- case "SchemeShard":
- return "yellow";
- case "DataShard":
- return "#00BFFF";
- case "Hive":
- return "orange";
- case "Coordinator":
- return "#4682B4";
- case "Mediator":
- return "brown";
- case "OldTxProxy":
- case "TxProxy":
- case "TxAllocator":
- return "#DDA0DD";
- case "BSController":
- return "cyan";
- case "Dummy":
- return "grey";
- case "JobRunner":
- return "lightgrey";
- case "RTMRPartition":
- case "NodeBroker":
- return "maroon";
- case "KeyValue":
+ }
+ return "XX";
+}
+
+function tabletTypeToColor(type) {
+ switch(type) {
+ case "SchemeShard":
+ return "yellow";
+ case "DataShard":
+ return "#00BFFF";
+ case "Hive":
+ return "orange";
+ case "Coordinator":
+ return "#4682B4";
+ case "Mediator":
+ return "brown";
+ case "OldTxProxy":
+ case "TxProxy":
+ case "TxAllocator":
+ return "#DDA0DD";
+ case "BSController":
+ return "cyan";
+ case "Dummy":
+ return "grey";
+ case "JobRunner":
+ return "lightgrey";
+ case "RTMRPartition":
+ case "NodeBroker":
+ return "maroon";
+ case "KeyValue":
case "Cms":
- return "pink";
- case "PersQueue":
- return "darksalmon";
- case "PersQueueReadBalancer":
- return "darkmagenta";
- case "BlockStorePartition":
- return "#B0E0E6";
- case "BlockStoreVolume":
- return "#B0C4DE";
+ return "pink";
+ case "PersQueue":
+ return "darksalmon";
+ case "PersQueueReadBalancer":
+ return "darkmagenta";
+ case "BlockStorePartition":
+ return "#B0E0E6";
+ case "BlockStoreVolume":
+ return "#B0C4DE";
case "Console":
return "SlateBlue";
case "TenantSlotBroker":
return "SlateGray";
- default:
- return "white";
- }
-}
-
-function tabletTypeToTextColor(type) {
- switch(type) {
- case "SchemeShard":
- case "BSController":
- case "BlockStorePartition":
- return "black";
- default:
- return "white";
- }
-}
-
-function updateTablets() {
- if (Object.keys(Tablets).length < 200000) {
- if (!newtablets_running) {
- newtablets_running = true;
- runUpdateTablets();
- }
- } else {
- newtablets = [];
- $("#panel-all-tablets").html("<i>Too many tablets to display</i>");
- }
-}
-
-var TabletGroups = {};
-var TabletGroupingFunction = function(tablet) { return "Tablets"; }
-var TabletColoringFunction = function(tablet) {
- return {
- backgroundColor: tabletToColor(tablet),
- color: tablet.State === "Dead" ? "white" : "black"
- };
-}
-
-function onTabletColorChange(obj) {
- switch (obj.value) {
- case "state":
- TabletColoringFunction = function(tablet) {
- return {
- backgroundColor: tabletToColor(tablet),
- color: tablet.State === "Dead" ? "white" : "black"
- };
- }
- break;
- case "type":
- TabletColoringFunction = function(tablet) {
- return {
- backgroundColor: tabletTypeToColor(tablet.Type),
- color: tabletTypeToTextColor(tablet.Type)
- };
- }
- break;
- }
- for (var id in Tablets) {
- newtablets.push(Tablets[id]);
- }
- updateTablets();
-}
-
-function onTabletGroupChange(obj) {
- switch (obj.value) {
- case "ungrouped":
- TabletGroupingFunction = function(tablet) { return "Tablets"; }
- break;
- case "type":
- TabletGroupingFunction = function(tablet) { return tabletTypeToString(tablet.Type); }
- break;
- case "state":
- TabletGroupingFunction = function(tablet) { return tabletToString(tablet); }
- break;
- case "node":
- TabletGroupingFunction = function(tablet) {
- if (tablet.NodeId !== undefined && tablet.NodeId !== 0) {
- return tablet.NodeId + " " + getNodeHost(tablet.NodeId);
- } else {
- return "Unassigned";
- }
- }
- break;
- }
- for (var id in Tablets) {
- newtablets.push(Tablets[id]);
- }
- updateTablets();
-}
-
-function getInsertPanel(panelTablets, groupValue) {
- if (groupValue !== null) {
- var tabletGroup = TabletGroups[groupValue];
- if (tabletGroup === undefined) {
- var id = Object.keys(TabletGroups).length;
- tabletGroup = TabletGroups[groupValue] = {};
- var tabletGroupElement = document.createElement("div");
- tabletGroupElement.className = "tabletgroupblock";
- tabletGroupElement.setAttribute("group-value", groupValue);
-
- var tabletGroupLabelElement = $("<button/>", {
- "type": "button",
- "class": "tabletgroupname btn btn-info collapsed",
- "style": "padding-top:3px; padding-bottom:3px; padding-right:5px; margin-bottom:5px",
- "data-toggle": "collapse",
- "data-target": "#tabletgroupcontainer" + id
- }).html(groupValue).get(0);
-
- tabletGroupElement.appendChild(tabletGroupLabelElement);
-
- var tabletGroupContainerElement = document.createElement("div");
- tabletGroupContainerElement.id = "tabletgroupcontainer" + id;
- tabletGroupContainerElement.className = "tabletgroupcontainer collapse";
- tabletGroupElement.appendChild(tabletGroupContainerElement);
- tabletGroup.DomElement = tabletGroupContainerElement;
-
- var tabletGroupClearFixElement = document.createElement("div");
- tabletGroupClearFixElement.style.clear = "both";
- tabletGroupElement.appendChild(tabletGroupClearFixElement);
-
- for (var child = panelTablets.firstChild; child !== null; child = child.nextSibling)
- if (groupValue < child.firstChild.innerHTML) {
- panelTablets.insertBefore(tabletGroupElement, child);
- break;
- }
-
- if (child === null) {
- panelTablets.appendChild(tabletGroupElement);
- }
- }
- return tabletGroup.DomElement;
- } else {
- return panelTablets;
- }
-}
-
-function clearEmptyGroups() {
- $("#panel-all-tablets").find(".tabletgroupblock").each(function() {
- //var container = $(this).find(".tabletgroupcontainer").get(0);
- var jthis = $(this);
- var length = jthis.find(".tabletgroupcontainer").children().length;
- var groupValue = this.getAttribute("group-value");
- //var length = container.children.length;
- if (length === 0) {
- delete TabletGroups[groupValue];
- this.parentNode.removeChild(this);
- } else {
- jthis.find(".tabletgroupname").html(groupValue + " (" + length + ")");
- }
- });
-}
-
-function getTabletInsertPoint(panelTablets, tabletElement, tabletType) {
- var tabletTypesDomElements = panelTablets.TabletTypesDomElements;
- if (tabletTypesDomElements === undefined) {
- tabletTypesDomElements = panelTablets.TabletTypesDomElements = [];
- }
- var len = tabletTypesDomElements.length;
- for (var idx = 0; idx < len; idx++) {
- var tabletTypeDomElement = tabletTypesDomElements[idx];
- if (tabletType < tabletTypeDomElement.Type) {
- tabletElement.TopOrderElement = true;
- tabletTypesDomElements.splice(idx, 0, {
- Type: tabletType,
- DomElement: tabletElement
- });
- return tabletTypeDomElement.DomElement;
- }
- if (tabletType === tabletTypeDomElement.Type) {
- if (idx + 1 < len) {
- var nextTabletTypeDomElement = tabletTypesDomElements[idx + 1];
- return nextTabletTypeDomElement.DomElement;
- } else {
- return null;
- }
- }
- }
- tabletElement.TopOrderElement = true;
- tabletTypesDomElements.push({
- Type: tabletType,
- DomElement: tabletElement
- });
- return null;
-}
-
-function insertTablet(panelTablets, tabletElement, tabletType) {
- if (tabletType !== undefined) {
- if (tabletElement.TopOrderElement) {
- var panel = tabletElement.parentElement;
- var types = panel.TabletTypesDomElements;
- var next = tabletElement.nextSibling;
- var len = types.length;
- var idx = 0;
- for (; idx < len; idx++) {
- if (types[idx].Type === tabletType)
- break;
- }
- if (idx < len) {
- if (next !== null) {
- var nextType = next.Tablet.Type;
- if (nextType !== tabletType)
- next = null;
- }
- if (next !== null) {
- types[idx].DomElement = next;
- next.TopOrderElement = true;
- } else {
- types.splice(idx, 1);
- }
- }
- tabletElement.TopOrderElement = false;
- }
- var tabletElementInsertPoint = getTabletInsertPoint(panelTablets, tabletElement, tabletType);
- if (tabletElementInsertPoint === null || tabletElementInsertPoint.parentNode !== panelTablets) {
- panelTablets.appendChild(tabletElement);
- } else {
- panelTablets.insertBefore(tabletElement, tabletElementInsertPoint);
- }
- return;
- }
- panelTablets.appendChild(tabletElement);
-}
-
-function removeTablet(panelTablets, tabletElement, tabletType) {
- panelTablets.removeChild(tabletElement);
-}
-
-function onTabletClick() {
- var url = "tablet?id=" + this.Tablet.TabletId + "&type=" + this.Tablet.Type;
- window.open(url);
-}
-
-function runUpdateTablets() {
- var panelAllTablets = $("#panel-all-tablets").get(0);
- var panelSchema = $("#panel-schema").find(".panel-body");
- var panelTablets = $("#panel-tablets").find(".panel-body");
-
- if (panelAllTablets.firstChild !== null && panelAllTablets.firstChild.nodeName === "IMG") {
- panelAllTablets.removeChild(panelAllTablets.firstChild);
- }
-
- var maxupdates = 100;
- while (newtablets.length > 0 && maxupdates-- > 0) {
- var tablet = newtablets[0];
- newtablets.shift();
- var tabobj = Tablets[tablet.TabletId];
- if (tabobj !== undefined) {
- tablet = tabobj;
- }
- if (tablet.State === "Deleted") {
- var tabletElement = tablet.DomElement;
- if (tabletElement !== undefined) {
- if (tabletElement.parentElement !== null) {
- removeTablet(tabletElement.parentElement, tabletElement, tablet.Type);
- }
- }
- delete Tablets[tablet.TabletId];
- continue;
- }
-
- var tabletElement = tablet.DomElement;
- if (tabletElement === undefined) {
- if (tablet.State === undefined)
- continue;
- tabletElement = document.createElement("div");
- tabletElement.className = tabletblock_class;
- if (TabletsCount < 50000) {
- tabletElement.innerHTML = tabletTypeToSymbol(tablet.Type);
- }
- tabletElement.addEventListener("click", onTabletClick, false);
- tabletElement.Tablet = tablet;
- tablet.DomElement = tabletElement;
- }
- var groupValue = TabletGroupingFunction(tablet);
- if (tablet.State === undefined) {
- if (tabletElement.parentElement !== null) {
- removeTablet(tabletElement.parentElement, tabletElement, tablet.Type);
- }
- continue;
- } else if (tablet.GroupValue === undefined || tablet.GroupValue !== groupValue) {
- insertTablet(getInsertPanel(panelAllTablets, groupValue), tabletElement, tablet.Type);
- tablet.GroupValue = groupValue;
- }
-
- var tabletStyle = TabletColoringFunction(tablet);
- var title;
- if (TabletsCount < 50000) {
- title = tabletTypeToString(tablet.Type) + " " + tablet.TabletId + " " + tabletToString(tablet) + " on node " + tablet.NodeId + " (" + getNodeHost(tablet.NodeId) + ")";
- tabletElement.title = title;
- }
- $(tabletElement).css(tabletStyle);
-
- var clonedTabletElement = SchemaTabletElements[tablet.TabletId];
- if (clonedTabletElement !== undefined) {
- if (clonedTabletElement === null) {
- addTreeNodeTablet(tablet);
- } else {
- if (TabletsCount < 50000) {
- clonedTabletElement.title = title;
- }
- $(clonedTabletElement).css(tabletStyle);
- }
- }
-
- /*panelSchema.find("div[tabletid='" + tablet.TabletId + "']").css(tabletStyle);
- var panelTabletElement = panelTablets.find("div[tabletid='" + tablet.TabletId + "']").get(0);
- if (panelTabletElement !== undefined) {
- panelTabletElement.title = title;
- panelTabletElement.style = tabletStyle;
- }*/
- }
- clearEmptyGroups();
- if (newtablets.length > 0) {
- setTimeout(runUpdateTablets, 0);
- } else {
- newtablets_running = false;
- }
-}
-
-function getTabletTypeFromHiveTabletType(type) {
- switch(type) {
- case 1:
- case 16:
- return "SchemeShard";
- case 2:
- case 18:
- return "DataShard";
- case 3:
- case 14:
- return "Hive";
- case 4:
- case 13:
- return "Coordinator";
- case 5:
- return "Mediator";
- case 6:
- case 17:
- return "TxProxy";
- case 7:
- case 15:
- return "BSController";
- case 8:
- return "Dummy";
- case 9:
- case 19:
- return "JobRunnerPoolManager";
- case 10:
- return "RTMRPartition";
- case 11:
- case 12:
- return "KeyValue";
- case 20:
- return "PersQueue";
+ default:
+ return "white";
+ }
+}
+
+function tabletTypeToTextColor(type) {
+ switch(type) {
+ case "SchemeShard":
+ case "BSController":
+ case "BlockStorePartition":
+ return "black";
+ default:
+ return "white";
+ }
+}
+
+function updateTablets() {
+ if (Object.keys(Tablets).length < 200000) {
+ if (!newtablets_running) {
+ newtablets_running = true;
+ runUpdateTablets();
+ }
+ } else {
+ newtablets = [];
+ $("#panel-all-tablets").html("<i>Too many tablets to display</i>");
+ }
+}
+
+var TabletGroups = {};
+var TabletGroupingFunction = function(tablet) { return "Tablets"; }
+var TabletColoringFunction = function(tablet) {
+ return {
+ backgroundColor: tabletToColor(tablet),
+ color: tablet.State === "Dead" ? "white" : "black"
+ };
+}
+
+function onTabletColorChange(obj) {
+ switch (obj.value) {
+ case "state":
+ TabletColoringFunction = function(tablet) {
+ return {
+ backgroundColor: tabletToColor(tablet),
+ color: tablet.State === "Dead" ? "white" : "black"
+ };
+ }
+ break;
+ case "type":
+ TabletColoringFunction = function(tablet) {
+ return {
+ backgroundColor: tabletTypeToColor(tablet.Type),
+ color: tabletTypeToTextColor(tablet.Type)
+ };
+ }
+ break;
+ }
+ for (var id in Tablets) {
+ newtablets.push(Tablets[id]);
+ }
+ updateTablets();
+}
+
+function onTabletGroupChange(obj) {
+ switch (obj.value) {
+ case "ungrouped":
+ TabletGroupingFunction = function(tablet) { return "Tablets"; }
+ break;
+ case "type":
+ TabletGroupingFunction = function(tablet) { return tabletTypeToString(tablet.Type); }
+ break;
+ case "state":
+ TabletGroupingFunction = function(tablet) { return tabletToString(tablet); }
+ break;
+ case "node":
+ TabletGroupingFunction = function(tablet) {
+ if (tablet.NodeId !== undefined && tablet.NodeId !== 0) {
+ return tablet.NodeId + " " + getNodeHost(tablet.NodeId);
+ } else {
+ return "Unassigned";
+ }
+ }
+ break;
+ }
+ for (var id in Tablets) {
+ newtablets.push(Tablets[id]);
+ }
+ updateTablets();
+}
+
+function getInsertPanel(panelTablets, groupValue) {
+ if (groupValue !== null) {
+ var tabletGroup = TabletGroups[groupValue];
+ if (tabletGroup === undefined) {
+ var id = Object.keys(TabletGroups).length;
+ tabletGroup = TabletGroups[groupValue] = {};
+ var tabletGroupElement = document.createElement("div");
+ tabletGroupElement.className = "tabletgroupblock";
+ tabletGroupElement.setAttribute("group-value", groupValue);
+
+ var tabletGroupLabelElement = $("<button/>", {
+ "type": "button",
+ "class": "tabletgroupname btn btn-info collapsed",
+ "style": "padding-top:3px; padding-bottom:3px; padding-right:5px; margin-bottom:5px",
+ "data-toggle": "collapse",
+ "data-target": "#tabletgroupcontainer" + id
+ }).html(groupValue).get(0);
+
+ tabletGroupElement.appendChild(tabletGroupLabelElement);
+
+ var tabletGroupContainerElement = document.createElement("div");
+ tabletGroupContainerElement.id = "tabletgroupcontainer" + id;
+ tabletGroupContainerElement.className = "tabletgroupcontainer collapse";
+ tabletGroupElement.appendChild(tabletGroupContainerElement);
+ tabletGroup.DomElement = tabletGroupContainerElement;
+
+ var tabletGroupClearFixElement = document.createElement("div");
+ tabletGroupClearFixElement.style.clear = "both";
+ tabletGroupElement.appendChild(tabletGroupClearFixElement);
+
+ for (var child = panelTablets.firstChild; child !== null; child = child.nextSibling)
+ if (groupValue < child.firstChild.innerHTML) {
+ panelTablets.insertBefore(tabletGroupElement, child);
+ break;
+ }
+
+ if (child === null) {
+ panelTablets.appendChild(tabletGroupElement);
+ }
+ }
+ return tabletGroup.DomElement;
+ } else {
+ return panelTablets;
+ }
+}
+
+function clearEmptyGroups() {
+ $("#panel-all-tablets").find(".tabletgroupblock").each(function() {
+ //var container = $(this).find(".tabletgroupcontainer").get(0);
+ var jthis = $(this);
+ var length = jthis.find(".tabletgroupcontainer").children().length;
+ var groupValue = this.getAttribute("group-value");
+ //var length = container.children.length;
+ if (length === 0) {
+ delete TabletGroups[groupValue];
+ this.parentNode.removeChild(this);
+ } else {
+ jthis.find(".tabletgroupname").html(groupValue + " (" + length + ")");
+ }
+ });
+}
+
+function getTabletInsertPoint(panelTablets, tabletElement, tabletType) {
+ var tabletTypesDomElements = panelTablets.TabletTypesDomElements;
+ if (tabletTypesDomElements === undefined) {
+ tabletTypesDomElements = panelTablets.TabletTypesDomElements = [];
+ }
+ var len = tabletTypesDomElements.length;
+ for (var idx = 0; idx < len; idx++) {
+ var tabletTypeDomElement = tabletTypesDomElements[idx];
+ if (tabletType < tabletTypeDomElement.Type) {
+ tabletElement.TopOrderElement = true;
+ tabletTypesDomElements.splice(idx, 0, {
+ Type: tabletType,
+ DomElement: tabletElement
+ });
+ return tabletTypeDomElement.DomElement;
+ }
+ if (tabletType === tabletTypeDomElement.Type) {
+ if (idx + 1 < len) {
+ var nextTabletTypeDomElement = tabletTypesDomElements[idx + 1];
+ return nextTabletTypeDomElement.DomElement;
+ } else {
+ return null;
+ }
+ }
+ }
+ tabletElement.TopOrderElement = true;
+ tabletTypesDomElements.push({
+ Type: tabletType,
+ DomElement: tabletElement
+ });
+ return null;
+}
+
+function insertTablet(panelTablets, tabletElement, tabletType) {
+ if (tabletType !== undefined) {
+ if (tabletElement.TopOrderElement) {
+ var panel = tabletElement.parentElement;
+ var types = panel.TabletTypesDomElements;
+ var next = tabletElement.nextSibling;
+ var len = types.length;
+ var idx = 0;
+ for (; idx < len; idx++) {
+ if (types[idx].Type === tabletType)
+ break;
+ }
+ if (idx < len) {
+ if (next !== null) {
+ var nextType = next.Tablet.Type;
+ if (nextType !== tabletType)
+ next = null;
+ }
+ if (next !== null) {
+ types[idx].DomElement = next;
+ next.TopOrderElement = true;
+ } else {
+ types.splice(idx, 1);
+ }
+ }
+ tabletElement.TopOrderElement = false;
+ }
+ var tabletElementInsertPoint = getTabletInsertPoint(panelTablets, tabletElement, tabletType);
+ if (tabletElementInsertPoint === null || tabletElementInsertPoint.parentNode !== panelTablets) {
+ panelTablets.appendChild(tabletElement);
+ } else {
+ panelTablets.insertBefore(tabletElement, tabletElementInsertPoint);
+ }
+ return;
+ }
+ panelTablets.appendChild(tabletElement);
+}
+
+function removeTablet(panelTablets, tabletElement, tabletType) {
+ panelTablets.removeChild(tabletElement);
+}
+
+function onTabletClick() {
+ var url = "tablet?id=" + this.Tablet.TabletId + "&type=" + this.Tablet.Type;
+ window.open(url);
+}
+
+function runUpdateTablets() {
+ var panelAllTablets = $("#panel-all-tablets").get(0);
+ var panelSchema = $("#panel-schema").find(".panel-body");
+ var panelTablets = $("#panel-tablets").find(".panel-body");
+
+ if (panelAllTablets.firstChild !== null && panelAllTablets.firstChild.nodeName === "IMG") {
+ panelAllTablets.removeChild(panelAllTablets.firstChild);
+ }
+
+ var maxupdates = 100;
+ while (newtablets.length > 0 && maxupdates-- > 0) {
+ var tablet = newtablets[0];
+ newtablets.shift();
+ var tabobj = Tablets[tablet.TabletId];
+ if (tabobj !== undefined) {
+ tablet = tabobj;
+ }
+ if (tablet.State === "Deleted") {
+ var tabletElement = tablet.DomElement;
+ if (tabletElement !== undefined) {
+ if (tabletElement.parentElement !== null) {
+ removeTablet(tabletElement.parentElement, tabletElement, tablet.Type);
+ }
+ }
+ delete Tablets[tablet.TabletId];
+ continue;
+ }
+
+ var tabletElement = tablet.DomElement;
+ if (tabletElement === undefined) {
+ if (tablet.State === undefined)
+ continue;
+ tabletElement = document.createElement("div");
+ tabletElement.className = tabletblock_class;
+ if (TabletsCount < 50000) {
+ tabletElement.innerHTML = tabletTypeToSymbol(tablet.Type);
+ }
+ tabletElement.addEventListener("click", onTabletClick, false);
+ tabletElement.Tablet = tablet;
+ tablet.DomElement = tabletElement;
+ }
+ var groupValue = TabletGroupingFunction(tablet);
+ if (tablet.State === undefined) {
+ if (tabletElement.parentElement !== null) {
+ removeTablet(tabletElement.parentElement, tabletElement, tablet.Type);
+ }
+ continue;
+ } else if (tablet.GroupValue === undefined || tablet.GroupValue !== groupValue) {
+ insertTablet(getInsertPanel(panelAllTablets, groupValue), tabletElement, tablet.Type);
+ tablet.GroupValue = groupValue;
+ }
+
+ var tabletStyle = TabletColoringFunction(tablet);
+ var title;
+ if (TabletsCount < 50000) {
+ title = tabletTypeToString(tablet.Type) + " " + tablet.TabletId + " " + tabletToString(tablet) + " on node " + tablet.NodeId + " (" + getNodeHost(tablet.NodeId) + ")";
+ tabletElement.title = title;
+ }
+ $(tabletElement).css(tabletStyle);
+
+ var clonedTabletElement = SchemaTabletElements[tablet.TabletId];
+ if (clonedTabletElement !== undefined) {
+ if (clonedTabletElement === null) {
+ addTreeNodeTablet(tablet);
+ } else {
+ if (TabletsCount < 50000) {
+ clonedTabletElement.title = title;
+ }
+ $(clonedTabletElement).css(tabletStyle);
+ }
+ }
+
+ /*panelSchema.find("div[tabletid='" + tablet.TabletId + "']").css(tabletStyle);
+ var panelTabletElement = panelTablets.find("div[tabletid='" + tablet.TabletId + "']").get(0);
+ if (panelTabletElement !== undefined) {
+ panelTabletElement.title = title;
+ panelTabletElement.style = tabletStyle;
+ }*/
+ }
+ clearEmptyGroups();
+ if (newtablets.length > 0) {
+ setTimeout(runUpdateTablets, 0);
+ } else {
+ newtablets_running = false;
+ }
+}
+
+function getTabletTypeFromHiveTabletType(type) {
+ switch(type) {
+ case 1:
+ case 16:
+ return "SchemeShard";
+ case 2:
+ case 18:
+ return "DataShard";
+ case 3:
+ case 14:
+ return "Hive";
+ case 4:
+ case 13:
+ return "Coordinator";
+ case 5:
+ return "Mediator";
+ case 6:
+ case 17:
+ return "TxProxy";
+ case 7:
+ case 15:
+ return "BSController";
+ case 8:
+ return "Dummy";
+ case 9:
+ case 19:
+ return "JobRunnerPoolManager";
+ case 10:
+ return "RTMRPartition";
+ case 11:
+ case 12:
+ return "KeyValue";
+ case 20:
+ return "PersQueue";
case 34:
return "OlapShard";
case 35:
return "ColumnShard";
- }
- return type;
-}
-
-var HivesScheduled = {};
-
-function onHiveInfo(result, hiveId) {
- if (result !== null) {
- var tablets = result.Tablets;
- if (tablets !== undefined) {
- for (var idx in tablets) {
- var tabletInfo = tablets[idx];
- var tablet = Tablets[tabletInfo.TabletID];
- if (tablet === undefined) {
- tablet = {
-
- TabletId: tabletInfo.TabletID,
- Type: getTabletTypeFromHiveTabletType(tabletInfo.TabletType),
- NodeId: tabletInfo.NodeID,
- ChangeTime: "0",
- ChannelGroupIDs: [],
- FromHive: true,
- State: "Dead"
- };
- Tablets[tabletInfo.TabletID] = tablet;
- newtablets.push(tablet);
- }
- }
- }
- updateTablets();
- }
- setTimeout(function() { refreshHiveInfo(hiveId); }, refreshTimeoutHive());
-}
-
-function refreshHiveInfo(id) {
- $.ajax({
- url: "json/hiveinfo?hive_id=" + id,
- success: function(result) { onHiveInfo(result, id); },
- error: function() { onHiveInfo(null, id); }
- });
-}
-
-function onNewTabletAvailable(tabletInfo) {
- if (tabletInfo.Type === "Hive") { // Hive
- if (HivesScheduled[tabletInfo.TabletId] === undefined) {
- HivesScheduled[tabletInfo.TabletId] = true;
- refreshHiveInfo(tabletInfo.TabletId);
- }
- }
-}
-
-var TabletStatsTypes = {};
-var TabletStatsDomElement = null;
-
-var TabletStates = ["Created", "ResolveStateStorage", "Candidate", "BlockBlobStorage", "RebuildGraph", "WriteZeroEntry",
- "Restored", "Discover", "Lock", "Dead", "Active"];
-var TabletStatesPositions = {Dead: 0, Created: 1, ResolveStateStorage: 2, Lock: 3, Discover: 4, Candidate: 5,
- BlockBlobStorage: 6, RebuildGraph: 7, WriteZeroEntry: 8, Restored: 9, Active: 10};
-
-function tabletStateToPosition(state) {
- return TabletStatesPositions[state];
-}
-
-function refreshTabletStats() {
- var TabletStats = {};
- for (var type in TabletStatsTypes) {
- TabletStats[type] = {};
- }
- var tabletAge = [0, 0, 0, 0, 0];
- var currentTime = new Date().valueOf();
- for (var id in Tablets) {
- var tablet = Tablets[id];
- var type = tablet.Type;
- if (type === undefined || type === "undefined")
- continue;
- var stats = TabletStats[type];
- if (stats === undefined) {
- stats = TabletStats[type] = {};
- }
- var state = tablet.State;
- var num = stats[state];
- if (num === undefined) {
- stats[state] = 1;
- } else {
- stats[state] = num + 1;
- }
- if (tablet.State === "Dead") {
- tabletAge[0]++;
- } else {
- var upTime = currentTime - tablet.ChangeTime;
- if (upTime < 60 * 1000) {
- tabletAge[1]++;
- } else if (upTime < 60 * 60 * 1000) {
- tabletAge[2]++;
- } else if (upTime < 24 * 60 * 60 * 1000) {
- tabletAge[3]++;
- } else {
- tabletAge[4]++;
- }
- }
- }
- if (TabletStatsDomElement === null) {
- TabletStatsDomElement = $("#overview").find(".tablet-stats").get(0);
- }
- for (var type in TabletStats) {
- var tabletStatType = TabletStatsTypes[type];
- if (tabletStatType === undefined) {
- tabletStatType = TabletStatsTypes[type] = {};
- var tabletStatsRowDomElement = TabletStatsDomElement.insertRow(-1);
- var header = tabletStatsRowDomElement.insertCell(-1);
- //header.style = "font-weight:bold;text-align:right";
- header.innerHTML = tabletTypeToString(type);
- for (var i = 0; i < TabletStates.length; i++) {
- var cell = tabletStatsRowDomElement.insertCell(-1);
- cell.className = "tcounter";
- }
- for (var i = 0; i < TabletStates.length; i++) {
- var state = TabletStates[i];
- tabletStatsRowDomElement.cells[tabletStateToPosition(state) + 1].style.color = tabletStateToColor(state);
- }
-
- tabletStatType.DomElement = tabletStatsRowDomElement;
- }
- var tabletStatRowDomElement = tabletStatType.DomElement;
- var cells = tabletStatRowDomElement.cells;
- var states = TabletStats[type];
- for (var i = 0; i < TabletStates.length; i++) {
- var state = TabletStates[i];
- var cell = cells[tabletStateToPosition(state) + 1];
- var cnt = states[state];
- if (cnt === undefined) {
- cell.innerHTML = "";
- $(cell).stop().css(StatsAnimateStop);
- } else {
- cell.innerHTML = cnt;
- $(cell).stop().css(StatsAnimateStop).animate(StatsAnimateStart, StatsAnimateDuration);
- }
- }
- }
-
- if (NodeStatsDomElement !== null) {
- var tabletsRow = NodeStatsDomElement.rows[2];
- for (var i = 0; i < tabletAge.length; ++i) {
- var value = tabletAge[i];
- var cell = tabletsRow.cells[i + 1];
- if (value === 0) {
- cell.innerHTML = "";
- $(cell).stop().css(StatsAnimateStop)
- } else {
- cell.innerHTML = value;
- $(cell).stop().css(StatsAnimateStop).animate(StatsAnimateStart, StatsAnimateDuration);
- }
- }
- }
-}
-
-var enums = {}
-
-function fromEnums(a) {
- var b = enums[a];
- if (b === undefined) {
- return enums[a] = String(a);
- } else {
- return b;
- }
-}
-
-function onTabletInfo(result) {
- var tabletStateInfo = null;
- var refreshTimeout = refreshTimeoutTablet();
- var tabLen;
- if (result !== undefined && result !== null && typeof result === "object") {
- if (result.TabletStateInfo !== undefined) {
- tabletStateInfo = result.TabletStateInfo;
- }
-
- if (tabletStateInfo !== null && tabletStateInfo.length > 1000) {
- if (tabletStateInfo.length > 5000) {
- DefaultRefreshTimeout = 5000;
- } else {
- DefaultRefreshTimeout = 1000;
- }
- }
-
- if (tabletStateInfo !== null) {
- if (tabletStateInfo.length >= 8000) {
- if (tabletStateInfo.length >= 50000) {
- tabletblock_class = "tabletblock-extra-small";
- } else {
- tabletblock_class = "tabletblock-small";
- }
- }
- for(var idx in tabletStateInfo) {
- var tabletInfo = tabletStateInfo[idx];
- var tablet = Tablets[tabletInfo.TabletId];
- if (tablet === undefined) {
- if (tabletInfo.State === "Deleted") {
- continue;
- }
- tabletInfo.State = fromEnums(tabletInfo.State);
- tabletInfo.Type = fromEnums(tabletInfo.Type);
- tablet = Tablets[tabletInfo.TabletId] = tabletInfo;
- newtablets.push(tabletInfo);
- if (tabletInfo.State === "Active") {
- onNewTabletAvailable(tabletInfo);
- }
- } else {
- if (Number(tablet.ChangeTime) < Number(tabletInfo.ChangeTime)) {
- if (tablet.State !== tabletInfo.State
- || tablet.NodeId !== tabletInfo.NodeId) {
- newtablets.push(tabletInfo);
- }
-
- tabletInfo.DomElement = tablet.DomElement;
- tabletInfo.GroupValue = tablet.GroupValue;
- tabletInfo.State = fromEnums(tabletInfo.State);
- tabletInfo.Type = fromEnums(tabletInfo.Type);
- Tablets[tabletInfo.TabletId] = tabletInfo;
-
- if (tabletInfo.State === "Active") {
- onNewTabletAvailable(tabletInfo);
- }
- }
- }
- if (TabletRequest.since === undefined) {
- tablet.Touched = true;
- }
- }
- }
- if (TabletRequest.since === undefined) {
- for (var id in Tablets) {
- var tab = Tablets[id];
- if (!tab.Touched && tab.FromHive === undefined) {
- delete tab.State;
- newtablets.push(tab);
- delete Tablets[id];
- }
- }
- }
- if (++TabletRequest.request > 60) {
- TabletRequest.request = 0;
- delete TabletRequest.since;
- } else {
- TabletRequest.since = result.ResponseTime;
- }
- } else {
- for (var id in Tablets) {
- delete Tablets[id].State;
- newtablets.push(Tablets[id]);
- delete Tablets[id];
- }
- TabletRequest.request = 0;
- delete TabletRequest.since;
- }
- TabletsCount = Object.keys(Tablets).length;
- if (newtablets.length > 0) {
- updateTablets();
- }
- refreshTabletStats();
- setTimeout(refreshTabletInfo, refreshTimeout);
-}
-
-function refreshSysInfo() {
- $.ajax({
- url: "json/sysinfo",
- data: SysRequest,
- success: onSysInfo,
- error: function() { onSysInfo(null); }
- });
-}
-
-function refreshNodeInfo() {
- $.ajax({
- url: "json/nodeinfo",
- data: NodeRequest,
- success: onNodeInfo,
- error: function() { onNodeInfo(null); }
- });
-}
-
-function refreshPDiskInfo() {
- $.ajax({
- url: "json/pdiskinfo",
- data: PDiskRequest,
- success: onPDiskInfo,
- error: function() { onPDiskInfo(null); }
- });
-}
-
-function refreshTabletInfo() {
- $.ajax({
- url: "json/tabletinfo",
- data: TabletRequest,
- success: onTabletInfo,
- error: function() { onTabletInfo(null); }
- });
-}
-
-function refreshVDiskInfo() {
- $.ajax({
- url: "json/vdiskinfo",
- data: VDiskRequest,
- success: onVDiskInfo,
- error: function() { onVDiskInfo(null); }
- });
-}
-
-function refreshBSGroupInfo() {
- $.ajax({
- url: "json/bsgroupinfo",
- data: BSGroupRequest,
- success: onBSGroupInfo,
- error: function() { onBSGroupInfo(null); }
- });
-}
-
-var InterconnectHeight = 36;
-
+ }
+ return type;
+}
+
+var HivesScheduled = {};
+
+function onHiveInfo(result, hiveId) {
+ if (result !== null) {
+ var tablets = result.Tablets;
+ if (tablets !== undefined) {
+ for (var idx in tablets) {
+ var tabletInfo = tablets[idx];
+ var tablet = Tablets[tabletInfo.TabletID];
+ if (tablet === undefined) {
+ tablet = {
+
+ TabletId: tabletInfo.TabletID,
+ Type: getTabletTypeFromHiveTabletType(tabletInfo.TabletType),
+ NodeId: tabletInfo.NodeID,
+ ChangeTime: "0",
+ ChannelGroupIDs: [],
+ FromHive: true,
+ State: "Dead"
+ };
+ Tablets[tabletInfo.TabletID] = tablet;
+ newtablets.push(tablet);
+ }
+ }
+ }
+ updateTablets();
+ }
+ setTimeout(function() { refreshHiveInfo(hiveId); }, refreshTimeoutHive());
+}
+
+function refreshHiveInfo(id) {
+ $.ajax({
+ url: "json/hiveinfo?hive_id=" + id,
+ success: function(result) { onHiveInfo(result, id); },
+ error: function() { onHiveInfo(null, id); }
+ });
+}
+
+function onNewTabletAvailable(tabletInfo) {
+ if (tabletInfo.Type === "Hive") { // Hive
+ if (HivesScheduled[tabletInfo.TabletId] === undefined) {
+ HivesScheduled[tabletInfo.TabletId] = true;
+ refreshHiveInfo(tabletInfo.TabletId);
+ }
+ }
+}
+
+var TabletStatsTypes = {};
+var TabletStatsDomElement = null;
+
+var TabletStates = ["Created", "ResolveStateStorage", "Candidate", "BlockBlobStorage", "RebuildGraph", "WriteZeroEntry",
+ "Restored", "Discover", "Lock", "Dead", "Active"];
+var TabletStatesPositions = {Dead: 0, Created: 1, ResolveStateStorage: 2, Lock: 3, Discover: 4, Candidate: 5,
+ BlockBlobStorage: 6, RebuildGraph: 7, WriteZeroEntry: 8, Restored: 9, Active: 10};
+
+function tabletStateToPosition(state) {
+ return TabletStatesPositions[state];
+}
+
+function refreshTabletStats() {
+ var TabletStats = {};
+ for (var type in TabletStatsTypes) {
+ TabletStats[type] = {};
+ }
+ var tabletAge = [0, 0, 0, 0, 0];
+ var currentTime = new Date().valueOf();
+ for (var id in Tablets) {
+ var tablet = Tablets[id];
+ var type = tablet.Type;
+ if (type === undefined || type === "undefined")
+ continue;
+ var stats = TabletStats[type];
+ if (stats === undefined) {
+ stats = TabletStats[type] = {};
+ }
+ var state = tablet.State;
+ var num = stats[state];
+ if (num === undefined) {
+ stats[state] = 1;
+ } else {
+ stats[state] = num + 1;
+ }
+ if (tablet.State === "Dead") {
+ tabletAge[0]++;
+ } else {
+ var upTime = currentTime - tablet.ChangeTime;
+ if (upTime < 60 * 1000) {
+ tabletAge[1]++;
+ } else if (upTime < 60 * 60 * 1000) {
+ tabletAge[2]++;
+ } else if (upTime < 24 * 60 * 60 * 1000) {
+ tabletAge[3]++;
+ } else {
+ tabletAge[4]++;
+ }
+ }
+ }
+ if (TabletStatsDomElement === null) {
+ TabletStatsDomElement = $("#overview").find(".tablet-stats").get(0);
+ }
+ for (var type in TabletStats) {
+ var tabletStatType = TabletStatsTypes[type];
+ if (tabletStatType === undefined) {
+ tabletStatType = TabletStatsTypes[type] = {};
+ var tabletStatsRowDomElement = TabletStatsDomElement.insertRow(-1);
+ var header = tabletStatsRowDomElement.insertCell(-1);
+ //header.style = "font-weight:bold;text-align:right";
+ header.innerHTML = tabletTypeToString(type);
+ for (var i = 0; i < TabletStates.length; i++) {
+ var cell = tabletStatsRowDomElement.insertCell(-1);
+ cell.className = "tcounter";
+ }
+ for (var i = 0; i < TabletStates.length; i++) {
+ var state = TabletStates[i];
+ tabletStatsRowDomElement.cells[tabletStateToPosition(state) + 1].style.color = tabletStateToColor(state);
+ }
+
+ tabletStatType.DomElement = tabletStatsRowDomElement;
+ }
+ var tabletStatRowDomElement = tabletStatType.DomElement;
+ var cells = tabletStatRowDomElement.cells;
+ var states = TabletStats[type];
+ for (var i = 0; i < TabletStates.length; i++) {
+ var state = TabletStates[i];
+ var cell = cells[tabletStateToPosition(state) + 1];
+ var cnt = states[state];
+ if (cnt === undefined) {
+ cell.innerHTML = "";
+ $(cell).stop().css(StatsAnimateStop);
+ } else {
+ cell.innerHTML = cnt;
+ $(cell).stop().css(StatsAnimateStop).animate(StatsAnimateStart, StatsAnimateDuration);
+ }
+ }
+ }
+
+ if (NodeStatsDomElement !== null) {
+ var tabletsRow = NodeStatsDomElement.rows[2];
+ for (var i = 0; i < tabletAge.length; ++i) {
+ var value = tabletAge[i];
+ var cell = tabletsRow.cells[i + 1];
+ if (value === 0) {
+ cell.innerHTML = "";
+ $(cell).stop().css(StatsAnimateStop)
+ } else {
+ cell.innerHTML = value;
+ $(cell).stop().css(StatsAnimateStop).animate(StatsAnimateStart, StatsAnimateDuration);
+ }
+ }
+ }
+}
+
+var enums = {}
+
+function fromEnums(a) {
+ var b = enums[a];
+ if (b === undefined) {
+ return enums[a] = String(a);
+ } else {
+ return b;
+ }
+}
+
+function onTabletInfo(result) {
+ var tabletStateInfo = null;
+ var refreshTimeout = refreshTimeoutTablet();
+ var tabLen;
+ if (result !== undefined && result !== null && typeof result === "object") {
+ if (result.TabletStateInfo !== undefined) {
+ tabletStateInfo = result.TabletStateInfo;
+ }
+
+ if (tabletStateInfo !== null && tabletStateInfo.length > 1000) {
+ if (tabletStateInfo.length > 5000) {
+ DefaultRefreshTimeout = 5000;
+ } else {
+ DefaultRefreshTimeout = 1000;
+ }
+ }
+
+ if (tabletStateInfo !== null) {
+ if (tabletStateInfo.length >= 8000) {
+ if (tabletStateInfo.length >= 50000) {
+ tabletblock_class = "tabletblock-extra-small";
+ } else {
+ tabletblock_class = "tabletblock-small";
+ }
+ }
+ for(var idx in tabletStateInfo) {
+ var tabletInfo = tabletStateInfo[idx];
+ var tablet = Tablets[tabletInfo.TabletId];
+ if (tablet === undefined) {
+ if (tabletInfo.State === "Deleted") {
+ continue;
+ }
+ tabletInfo.State = fromEnums(tabletInfo.State);
+ tabletInfo.Type = fromEnums(tabletInfo.Type);
+ tablet = Tablets[tabletInfo.TabletId] = tabletInfo;
+ newtablets.push(tabletInfo);
+ if (tabletInfo.State === "Active") {
+ onNewTabletAvailable(tabletInfo);
+ }
+ } else {
+ if (Number(tablet.ChangeTime) < Number(tabletInfo.ChangeTime)) {
+ if (tablet.State !== tabletInfo.State
+ || tablet.NodeId !== tabletInfo.NodeId) {
+ newtablets.push(tabletInfo);
+ }
+
+ tabletInfo.DomElement = tablet.DomElement;
+ tabletInfo.GroupValue = tablet.GroupValue;
+ tabletInfo.State = fromEnums(tabletInfo.State);
+ tabletInfo.Type = fromEnums(tabletInfo.Type);
+ Tablets[tabletInfo.TabletId] = tabletInfo;
+
+ if (tabletInfo.State === "Active") {
+ onNewTabletAvailable(tabletInfo);
+ }
+ }
+ }
+ if (TabletRequest.since === undefined) {
+ tablet.Touched = true;
+ }
+ }
+ }
+ if (TabletRequest.since === undefined) {
+ for (var id in Tablets) {
+ var tab = Tablets[id];
+ if (!tab.Touched && tab.FromHive === undefined) {
+ delete tab.State;
+ newtablets.push(tab);
+ delete Tablets[id];
+ }
+ }
+ }
+ if (++TabletRequest.request > 60) {
+ TabletRequest.request = 0;
+ delete TabletRequest.since;
+ } else {
+ TabletRequest.since = result.ResponseTime;
+ }
+ } else {
+ for (var id in Tablets) {
+ delete Tablets[id].State;
+ newtablets.push(Tablets[id]);
+ delete Tablets[id];
+ }
+ TabletRequest.request = 0;
+ delete TabletRequest.since;
+ }
+ TabletsCount = Object.keys(Tablets).length;
+ if (newtablets.length > 0) {
+ updateTablets();
+ }
+ refreshTabletStats();
+ setTimeout(refreshTabletInfo, refreshTimeout);
+}
+
+function refreshSysInfo() {
+ $.ajax({
+ url: "json/sysinfo",
+ data: SysRequest,
+ success: onSysInfo,
+ error: function() { onSysInfo(null); }
+ });
+}
+
+function refreshNodeInfo() {
+ $.ajax({
+ url: "json/nodeinfo",
+ data: NodeRequest,
+ success: onNodeInfo,
+ error: function() { onNodeInfo(null); }
+ });
+}
+
+function refreshPDiskInfo() {
+ $.ajax({
+ url: "json/pdiskinfo",
+ data: PDiskRequest,
+ success: onPDiskInfo,
+ error: function() { onPDiskInfo(null); }
+ });
+}
+
+function refreshTabletInfo() {
+ $.ajax({
+ url: "json/tabletinfo",
+ data: TabletRequest,
+ success: onTabletInfo,
+ error: function() { onTabletInfo(null); }
+ });
+}
+
+function refreshVDiskInfo() {
+ $.ajax({
+ url: "json/vdiskinfo",
+ data: VDiskRequest,
+ success: onVDiskInfo,
+ error: function() { onVDiskInfo(null); }
+ });
+}
+
+function refreshBSGroupInfo() {
+ $.ajax({
+ url: "json/bsgroupinfo",
+ data: BSGroupRequest,
+ success: onBSGroupInfo,
+ error: function() { onBSGroupInfo(null); }
+ });
+}
+
+var InterconnectHeight = 36;
+
function getInterconnectUrl(node, peerNode) {
return getBaseUrl(node) + "/actors/interconnect/peer" + pad4(peerNode);
}
@@ -2232,246 +2232,246 @@ function onInterconnectClick() {
window.open(getInterconnectUrl(this.NodeId, this.PeerNodeId));
}
-function buildInterconnectMap(node, interconnect) {
- if (NodesCount >= 64) {
- var canvas = document.createElement("canvas");
- canvas.width = NodesCount;
- canvas.height = InterconnectHeight;
- canvas.style.verticalAlign = "middle";
- interconnect.appendChild(canvas);
- var context = canvas.getContext("2d");
- context.translate(0.5, 0.5);
- //context.lineWidth = 0.5;
- context.fillStyle = "lightgrey";
- context.fillRect(0, 0, NodesCount, InterconnectHeight - 1);
- node.InterconnectCellDomElement = context;
- } else {
- var table = document.createElement("table");
- interconnect.appendChild(table);
- var interconnectrow = table.insertRow(-1);
- node.InterconnectCellDomElement = {};
- for (var j in Nodes) {
- var interconnectcell = interconnectrow.insertCell(-1);
- var interconnectdiv = document.createElement("div");
- if (NodesCount >= 128) {
- interconnectdiv.className = "nodeblocks";
- interconnectdiv.style.width = "1px";
- interconnectcell.style.padding = "0px";
- } else if (NodesCount >= 64) {
- interconnectdiv.className = "nodeblock";
- interconnectdiv.style.width = "3px";
- interconnectdiv.style.boxShadow = "1px 1px 0px grey";
- interconnectcell.style.padding = "1px";
- } else if (NodesCount >= 32) {
- interconnectdiv.className = "nodeblock";
- interconnectdiv.style.width = "6px";
- interconnectdiv.style.boxShadow = "1px 1px 1px grey";
- interconnectcell.style.padding = "1px";
- } else {
- interconnectdiv.className = "nodeblock";
- interconnectdiv.style.width = "12px";
- interconnectdiv.style.boxShadow = "1px 1px 1px grey";
- interconnectcell.style.padding = "1px";
- }
- interconnectdiv.title = getNodeHost(j);
+function buildInterconnectMap(node, interconnect) {
+ if (NodesCount >= 64) {
+ var canvas = document.createElement("canvas");
+ canvas.width = NodesCount;
+ canvas.height = InterconnectHeight;
+ canvas.style.verticalAlign = "middle";
+ interconnect.appendChild(canvas);
+ var context = canvas.getContext("2d");
+ context.translate(0.5, 0.5);
+ //context.lineWidth = 0.5;
+ context.fillStyle = "lightgrey";
+ context.fillRect(0, 0, NodesCount, InterconnectHeight - 1);
+ node.InterconnectCellDomElement = context;
+ } else {
+ var table = document.createElement("table");
+ interconnect.appendChild(table);
+ var interconnectrow = table.insertRow(-1);
+ node.InterconnectCellDomElement = {};
+ for (var j in Nodes) {
+ var interconnectcell = interconnectrow.insertCell(-1);
+ var interconnectdiv = document.createElement("div");
+ if (NodesCount >= 128) {
+ interconnectdiv.className = "nodeblocks";
+ interconnectdiv.style.width = "1px";
+ interconnectcell.style.padding = "0px";
+ } else if (NodesCount >= 64) {
+ interconnectdiv.className = "nodeblock";
+ interconnectdiv.style.width = "3px";
+ interconnectdiv.style.boxShadow = "1px 1px 0px grey";
+ interconnectcell.style.padding = "1px";
+ } else if (NodesCount >= 32) {
+ interconnectdiv.className = "nodeblock";
+ interconnectdiv.style.width = "6px";
+ interconnectdiv.style.boxShadow = "1px 1px 1px grey";
+ interconnectcell.style.padding = "1px";
+ } else {
+ interconnectdiv.className = "nodeblock";
+ interconnectdiv.style.width = "12px";
+ interconnectdiv.style.boxShadow = "1px 1px 1px grey";
+ interconnectcell.style.padding = "1px";
+ }
+ interconnectdiv.title = getNodeHost(j);
interconnectdiv.NodeId = node.Id;
interconnectdiv.PeerNodeId = j;
interconnectdiv.addEventListener("click", onInterconnectClick, false);
- interconnectcell.appendChild(interconnectdiv);
- node.InterconnectCellDomElement[j] = interconnectdiv;
- }
- }
-}
-
-function setInterconnectMap(node, id, color, title) {
- if (node.InterconnectCellDomElement[1] !== undefined) {
- var div = node.InterconnectCellDomElement[id];
- div.style.backgroundColor = color;
- if (title !== undefined) {
- div.title = title;
- }
- } else {
- var context = node.InterconnectCellDomElement;
- context.strokeStyle = color;
- context.beginPath();
- context.moveTo(id - 1, 0);
- context.lineTo(id - 1, InterconnectHeight - 1);
- context.stroke();
- }
-}
-
-function buildPoolsMap(node, pools) {
- var table = document.createElement("table");
- pools.appendChild(table);
- var poolsrow = table.insertRow(-1);
- node.PoolsCellDomElement = poolsrow;
-}
-/*
-var PoolColors = [
- {usage: 0, R: 144, G: 238, B: 144},
- {usage: 50, R: 255, G: 255, B: 0},
- {usage: 75, R: 255, G: 165, B: 0},
- {usage: 100, R: 255, G: 0, B: 0}
- ];
-*/
-
-var PoolColors = [
- {usage: 0, R: 144, G: 238, B: 144},
- {usage: 75, R: 255, G: 255, B: 0},
- {usage: 100, R: 255, G: 0, B: 0}
- ];
-
-function getPoolColor(usage) {
- var idx = 1;
- for (var idx = 1; idx < PoolColors.length && usage > PoolColors[idx].usage; idx++);
- var a = PoolColors[idx - 1];
- var b = PoolColors[idx];
- var R = a.R + ((usage - a.usage) / (b.usage - a.usage)) * (b.R - a.R);
- var G = a.G + ((usage - a.usage) / (b.usage - a.usage)) * (b.G - a.G);
- var B = a.B + ((usage - a.usage) / (b.usage - a.usage)) * (b.B - a.B);
- return "rgb(" + R.toFixed() + "," + G.toFixed() + "," + B.toFixed() + ")";
-}
-
-function setPoolsMap(node, pools) {
- var poolsrow = node.PoolsCellDomElement;
- var cells = poolsrow.cells;
- while (cells.length > pools.length) {
- poolsrow.deleteCell(cells.length - 1);
- }
- for (var idx = 0; idx < pools.length; idx++) {
- var cell;
- var pool;
- var inner;
- if (idx >= cells.length) {
- cell = poolsrow.insertCell(idx);
- cell.style.padding = "1px";
- var pooldiv = document.createElement("div");
- pooldiv.className = "nodeblock";
- pooldiv.style.width = "12px";
- pooldiv.style.boxShadow = "1px 1px 1px grey";
- pooldiv.style.padding = "1px";
- pooldiv.style.backgroundColor = "white";
- var innerdiv = document.createElement("div");
- innerdiv.style.width = "100%";
- innerdiv.style.height = "50%";
- //innerdiv.style.backgroundColor = 'white';
- innerdiv.style.backgroundColor = '#f7f7f7';
- pooldiv.appendChild(innerdiv);
- cell.appendChild(pooldiv);
- pool = pooldiv;
- inner = innerdiv;
- } else {
- cell = cells[idx];
- pool = cell.firstChild;
- inner = pool.firstChild;
- }
- var usage = (pools[idx].Usage * 100).toFixed();
- //usage = 20 * idx + 15;
- if (pools[idx].Name !== "") {
- cell.title = pools[idx].Name + " " + usage + "%";
- } else {
- cell.title = usage + "%";
- }
- if (usage < 0) {
- usage = 0;
- }
- if (usage > 100) {
- usage = 100;
- }
- var height = 100 - usage;
- pool.style.backgroundColor = getPoolColor(usage);
- inner.style.height = height + "%";
- }
-}
-
-function onNodeList(nlist) {
- if (nlist !== null && NodesCount === 0) {
- if (nlist.length >= 128) {
- tabletblock_class = "tabletblock-small";
- }
- var htmlNodelist = $(".nodelist").get(0);
- var nlen = nlist.length;
- for (var i = 0; i < nlen; i++) {
- Nodes[nlist[i].Id] = nlist[i];
- }
- NodesCount = nlen;
- for (var i in Nodes) {
- var node = Nodes[i];
- var row = node.DomElement;
- if (row === undefined) {
- row = htmlNodelist.insertRow(-1);
- node.DomElement = row;
- row.insertCell(0).innerHTML = node.Id;
- var host = row.insertCell(1);
- host.innerHTML = "<div><a href='" + getViewerUrl(i) + "'>" + node.Host + "</a></div>" +
- "<div class='statecontainer'><div class='stateblock' title='Overall'></div>" +
- "<div class='stateblock' title='MessageBus' style='text-align:center'>MB</div>" +
- "<div class='usageblock progress' title='LoadAverage'><div class='progress-bar' role='progressbar'></div></div></div>";
- host.title = node.Address + ":" + node.Port;
- row.insertCell(2).style.textAlign = "right"; // uptime
- var cpu = row.insertCell(3);
- buildPoolsMap(node, cpu);
- var interconnect = row.insertCell(4); // interconnect status
- buildInterconnectMap(node, interconnect);
- }
- }
- // first run only
- refreshSysInfo();
- refreshNodeInfo();
- refreshPDiskInfo();
- refreshVDiskInfo();
- refreshTabletInfo();
- }
- if (nlist === null) {
- for (var i in Nodes) {
- //clearSysInfo(i, null);
- //clearNodeInfo(i, null);
- }
- }
-
- setTimeout(function(){$.ajax({
- url: "json/nodelist",
- success: function(result) { onNodeList(result); },
- error: function() { onNodeList(null); }
- });}, 120000);
-}
-
-function concatPaths(parent, child) {
- if (parent === "/") {
- return parent + child;
- } else {
- return parent + "/" + child;
- }
-}
-
-var OpeningPath = null;
-
-function onTreeDataComplete(result, obj, cb) {
- if (result !== null && result.PathDescription) {
- var children = [];
- if (result.PathDescription.Children) {
- var clen = result.PathDescription.Children.length;
- for (var i = 0; i < clen; i++) {
- var child = {};
- child.id = concatPaths(result.Path, result.PathDescription.Children[i].Name);
- child.parent = result.Path;
- child.text = result.PathDescription.Children[i].Name;
- switch (result.PathDescription.Children[i].PathType) {
+ interconnectcell.appendChild(interconnectdiv);
+ node.InterconnectCellDomElement[j] = interconnectdiv;
+ }
+ }
+}
+
+function setInterconnectMap(node, id, color, title) {
+ if (node.InterconnectCellDomElement[1] !== undefined) {
+ var div = node.InterconnectCellDomElement[id];
+ div.style.backgroundColor = color;
+ if (title !== undefined) {
+ div.title = title;
+ }
+ } else {
+ var context = node.InterconnectCellDomElement;
+ context.strokeStyle = color;
+ context.beginPath();
+ context.moveTo(id - 1, 0);
+ context.lineTo(id - 1, InterconnectHeight - 1);
+ context.stroke();
+ }
+}
+
+function buildPoolsMap(node, pools) {
+ var table = document.createElement("table");
+ pools.appendChild(table);
+ var poolsrow = table.insertRow(-1);
+ node.PoolsCellDomElement = poolsrow;
+}
+/*
+var PoolColors = [
+ {usage: 0, R: 144, G: 238, B: 144},
+ {usage: 50, R: 255, G: 255, B: 0},
+ {usage: 75, R: 255, G: 165, B: 0},
+ {usage: 100, R: 255, G: 0, B: 0}
+ ];
+*/
+
+var PoolColors = [
+ {usage: 0, R: 144, G: 238, B: 144},
+ {usage: 75, R: 255, G: 255, B: 0},
+ {usage: 100, R: 255, G: 0, B: 0}
+ ];
+
+function getPoolColor(usage) {
+ var idx = 1;
+ for (var idx = 1; idx < PoolColors.length && usage > PoolColors[idx].usage; idx++);
+ var a = PoolColors[idx - 1];
+ var b = PoolColors[idx];
+ var R = a.R + ((usage - a.usage) / (b.usage - a.usage)) * (b.R - a.R);
+ var G = a.G + ((usage - a.usage) / (b.usage - a.usage)) * (b.G - a.G);
+ var B = a.B + ((usage - a.usage) / (b.usage - a.usage)) * (b.B - a.B);
+ return "rgb(" + R.toFixed() + "," + G.toFixed() + "," + B.toFixed() + ")";
+}
+
+function setPoolsMap(node, pools) {
+ var poolsrow = node.PoolsCellDomElement;
+ var cells = poolsrow.cells;
+ while (cells.length > pools.length) {
+ poolsrow.deleteCell(cells.length - 1);
+ }
+ for (var idx = 0; idx < pools.length; idx++) {
+ var cell;
+ var pool;
+ var inner;
+ if (idx >= cells.length) {
+ cell = poolsrow.insertCell(idx);
+ cell.style.padding = "1px";
+ var pooldiv = document.createElement("div");
+ pooldiv.className = "nodeblock";
+ pooldiv.style.width = "12px";
+ pooldiv.style.boxShadow = "1px 1px 1px grey";
+ pooldiv.style.padding = "1px";
+ pooldiv.style.backgroundColor = "white";
+ var innerdiv = document.createElement("div");
+ innerdiv.style.width = "100%";
+ innerdiv.style.height = "50%";
+ //innerdiv.style.backgroundColor = 'white';
+ innerdiv.style.backgroundColor = '#f7f7f7';
+ pooldiv.appendChild(innerdiv);
+ cell.appendChild(pooldiv);
+ pool = pooldiv;
+ inner = innerdiv;
+ } else {
+ cell = cells[idx];
+ pool = cell.firstChild;
+ inner = pool.firstChild;
+ }
+ var usage = (pools[idx].Usage * 100).toFixed();
+ //usage = 20 * idx + 15;
+ if (pools[idx].Name !== "") {
+ cell.title = pools[idx].Name + " " + usage + "%";
+ } else {
+ cell.title = usage + "%";
+ }
+ if (usage < 0) {
+ usage = 0;
+ }
+ if (usage > 100) {
+ usage = 100;
+ }
+ var height = 100 - usage;
+ pool.style.backgroundColor = getPoolColor(usage);
+ inner.style.height = height + "%";
+ }
+}
+
+function onNodeList(nlist) {
+ if (nlist !== null && NodesCount === 0) {
+ if (nlist.length >= 128) {
+ tabletblock_class = "tabletblock-small";
+ }
+ var htmlNodelist = $(".nodelist").get(0);
+ var nlen = nlist.length;
+ for (var i = 0; i < nlen; i++) {
+ Nodes[nlist[i].Id] = nlist[i];
+ }
+ NodesCount = nlen;
+ for (var i in Nodes) {
+ var node = Nodes[i];
+ var row = node.DomElement;
+ if (row === undefined) {
+ row = htmlNodelist.insertRow(-1);
+ node.DomElement = row;
+ row.insertCell(0).innerHTML = node.Id;
+ var host = row.insertCell(1);
+ host.innerHTML = "<div><a href='" + getViewerUrl(i) + "'>" + node.Host + "</a></div>" +
+ "<div class='statecontainer'><div class='stateblock' title='Overall'></div>" +
+ "<div class='stateblock' title='MessageBus' style='text-align:center'>MB</div>" +
+ "<div class='usageblock progress' title='LoadAverage'><div class='progress-bar' role='progressbar'></div></div></div>";
+ host.title = node.Address + ":" + node.Port;
+ row.insertCell(2).style.textAlign = "right"; // uptime
+ var cpu = row.insertCell(3);
+ buildPoolsMap(node, cpu);
+ var interconnect = row.insertCell(4); // interconnect status
+ buildInterconnectMap(node, interconnect);
+ }
+ }
+ // first run only
+ refreshSysInfo();
+ refreshNodeInfo();
+ refreshPDiskInfo();
+ refreshVDiskInfo();
+ refreshTabletInfo();
+ }
+ if (nlist === null) {
+ for (var i in Nodes) {
+ //clearSysInfo(i, null);
+ //clearNodeInfo(i, null);
+ }
+ }
+
+ setTimeout(function(){$.ajax({
+ url: "json/nodelist",
+ success: function(result) { onNodeList(result); },
+ error: function() { onNodeList(null); }
+ });}, 120000);
+}
+
+function concatPaths(parent, child) {
+ if (parent === "/") {
+ return parent + child;
+ } else {
+ return parent + "/" + child;
+ }
+}
+
+var OpeningPath = null;
+
+function onTreeDataComplete(result, obj, cb) {
+ if (result !== null && result.PathDescription) {
+ var children = [];
+ if (result.PathDescription.Children) {
+ var clen = result.PathDescription.Children.length;
+ for (var i = 0; i < clen; i++) {
+ var child = {};
+ child.id = concatPaths(result.Path, result.PathDescription.Children[i].Name);
+ child.parent = result.Path;
+ child.text = result.PathDescription.Children[i].Name;
+ switch (result.PathDescription.Children[i].PathType) {
case 1: // Directory
- child.children = true;
- child.icon = "glyphicon glyphicon-folder-close schema-good";
- break;
+ child.children = true;
+ child.icon = "glyphicon glyphicon-folder-close schema-good";
+ break;
case 2: // Table
child.children = true;
- child.icon = "glyphicon glyphicon-list schema-good";
- break;
+ child.icon = "glyphicon glyphicon-list schema-good";
+ break;
case 3: // PQ Group
- child.icon = "glyphicon glyphicon-sort-by-alphabet schema-good";
- break;
+ child.icon = "glyphicon glyphicon-sort-by-alphabet schema-good";
+ break;
case 4: // SubDomain
- child.children = true;
- child.icon = "glyphicon glyphicon-tasks schema-good";
- break;
+ child.children = true;
+ child.icon = "glyphicon glyphicon-tasks schema-good";
+ break;
case 10: // ExtSubDomain
child.children = true;
child.icon = "glyphicon glyphicon-asterisk schema-good";
@@ -2480,11 +2480,11 @@ function onTreeDataComplete(result, obj, cb) {
child.children = true;
child.icon = "glyphicon glyphicon-list schema-good";
break;
- }
- child.data = function(obj1, cb1) { onTreeData(obj1, cb1); };
- children.push(child);
- }
- obj.describe = result;
+ }
+ child.data = function(obj1, cb1) { onTreeData(obj1, cb1); };
+ children.push(child);
+ }
+ obj.describe = result;
} else if (result.PathDescription.Table) {
if (result.PathDescription.Table.TableIndexes) {
var ilen = result.PathDescription.Table.TableIndexes.length;
@@ -2514,80 +2514,80 @@ function onTreeDataComplete(result, obj, cb) {
}
obj.describe = result;
}
- }
- cb.call(this, children);
- } else {
- cb.call(this, null);
- }
-
- if (OpeningPath !== null && OpeningPath.startsWith(obj.id)) {
- var pos = obj.id.length;
- if (OpeningPath[pos] === '/') {
- pos++;
- }
- var idx = OpeningPath.substr(pos).indexOf('/');
- if (idx === -1) {
- $("#schema-tree").jstree('select_node', OpeningPath);
- OpeningPath = null;
- } else {
- var openNode = OpeningPath.substr(0, pos + idx);
- $("#schema-tree").jstree('open_node', openNode);
- }
- }
-}
-
-var schemaGoodTablets = 0;
-var schemaTotalTablets = 0;
-
-function addTreeNodeTablet(tablet) {
- var panelTablets = $("#panel-tablets").find(".panel-body").get(0);
- var id = tablet.TabletId;
- if (tablet.DomElement !== undefined) {
- var clonedTablet = tablet.DomElement.cloneNode(true);
- clonedTablet.Tablet = tablet;
- clonedTablet.addEventListener("click", onTabletClick, false);
- panelTablets.appendChild(clonedTablet);
- SchemaTabletElements[id] = clonedTablet;
- }
- if (tablet.State === "Active") {
- schemaGoodTablets++;
- }
- $("#schema-tablets").html(Math.trunc(schemaGoodTablets*100/schemaTotalTablets) + "% (" + schemaGoodTablets + "/" + schemaTotalTablets + ")")
-}
-
-function onTreeNodeTabletsComplete() {
- var panelTablets = $("#panel-tablets").find(".panel-body").get(0);
- while (panelTablets.firstChild)
- panelTablets.removeChild(panelTablets.firstChild);
- schemaGoodTablets = 0;
- schemaTotalTablets = 0;
- for (var id in SchemaTabletElements) {
- var tablet = Tablets[id];
- if (tablet !== undefined) {
- if (tablet.DomElement !== undefined) {
- var clonedTablet = tablet.DomElement.cloneNode(true);
- clonedTablet.addEventListener("click", onTabletClick, false);
- clonedTablet.Tablet = tablet;
- panelTablets.appendChild(clonedTablet);
- SchemaTabletElements[id] = clonedTablet;
- if (tablet.State === "Active") {
- schemaGoodTablets++;
- }
- }
- }
- schemaTotalTablets++;
- }
- $("#schema-tablets").html(Math.trunc(schemaGoodTablets*100/schemaTotalTablets) + "% (" + schemaGoodTablets + "/" + schemaTotalTablets + ")")
-}
-
-function schemaPathTypeToString(pathType) {
- switch (pathType) {
- case 1:
- return "Directory";
- case 2:
- return "Table";
- case 3:
- return "PersQueueGroup";
+ }
+ cb.call(this, children);
+ } else {
+ cb.call(this, null);
+ }
+
+ if (OpeningPath !== null && OpeningPath.startsWith(obj.id)) {
+ var pos = obj.id.length;
+ if (OpeningPath[pos] === '/') {
+ pos++;
+ }
+ var idx = OpeningPath.substr(pos).indexOf('/');
+ if (idx === -1) {
+ $("#schema-tree").jstree('select_node', OpeningPath);
+ OpeningPath = null;
+ } else {
+ var openNode = OpeningPath.substr(0, pos + idx);
+ $("#schema-tree").jstree('open_node', openNode);
+ }
+ }
+}
+
+var schemaGoodTablets = 0;
+var schemaTotalTablets = 0;
+
+function addTreeNodeTablet(tablet) {
+ var panelTablets = $("#panel-tablets").find(".panel-body").get(0);
+ var id = tablet.TabletId;
+ if (tablet.DomElement !== undefined) {
+ var clonedTablet = tablet.DomElement.cloneNode(true);
+ clonedTablet.Tablet = tablet;
+ clonedTablet.addEventListener("click", onTabletClick, false);
+ panelTablets.appendChild(clonedTablet);
+ SchemaTabletElements[id] = clonedTablet;
+ }
+ if (tablet.State === "Active") {
+ schemaGoodTablets++;
+ }
+ $("#schema-tablets").html(Math.trunc(schemaGoodTablets*100/schemaTotalTablets) + "% (" + schemaGoodTablets + "/" + schemaTotalTablets + ")")
+}
+
+function onTreeNodeTabletsComplete() {
+ var panelTablets = $("#panel-tablets").find(".panel-body").get(0);
+ while (panelTablets.firstChild)
+ panelTablets.removeChild(panelTablets.firstChild);
+ schemaGoodTablets = 0;
+ schemaTotalTablets = 0;
+ for (var id in SchemaTabletElements) {
+ var tablet = Tablets[id];
+ if (tablet !== undefined) {
+ if (tablet.DomElement !== undefined) {
+ var clonedTablet = tablet.DomElement.cloneNode(true);
+ clonedTablet.addEventListener("click", onTabletClick, false);
+ clonedTablet.Tablet = tablet;
+ panelTablets.appendChild(clonedTablet);
+ SchemaTabletElements[id] = clonedTablet;
+ if (tablet.State === "Active") {
+ schemaGoodTablets++;
+ }
+ }
+ }
+ schemaTotalTablets++;
+ }
+ $("#schema-tablets").html(Math.trunc(schemaGoodTablets*100/schemaTotalTablets) + "% (" + schemaGoodTablets + "/" + schemaTotalTablets + ")")
+}
+
+function schemaPathTypeToString(pathType) {
+ switch (pathType) {
+ case 1:
+ return "Directory";
+ case 2:
+ return "Table";
+ case 3:
+ return "PersQueueGroup";
case 7:
return "Kesus";
case 10:
@@ -2596,159 +2596,159 @@ function schemaPathTypeToString(pathType) {
return "Sequence";
case 16:
return "Replication";
- }
-}
-
-function getCounter(counters, name) {
- var result = $.grep(counters, function(e){ return e.Name === name; });
- if (result.length > 0) {
- return Number(result[0].Value);
- } else {
- return 0;
- }
-}
-
-function onTreeNodeChildrenDataSizeComplete(dataSizeCell, result) {
- if (result === null) {
- dataSizeCell.innerHTML = "";
- return;
- }
- var dataSize = 0;
+ }
+}
+
+function getCounter(counters, name) {
+ var result = $.grep(counters, function(e){ return e.Name === name; });
+ if (result.length > 0) {
+ return Number(result[0].Value);
+ } else {
+ return 0;
+ }
+}
+
+function onTreeNodeChildrenDataSizeComplete(dataSizeCell, result) {
+ if (result === null) {
+ dataSizeCell.innerHTML = "";
+ return;
+ }
+ var dataSize = 0;
dataSize += getCounter(result.TabletCounters.ExecutorCounters.SimpleCounters, "LogRedoMemory");
dataSize += getCounter(result.TabletCounters.ExecutorCounters.SimpleCounters, "DbIndexBytes");
dataSize += getCounter(result.TabletCounters.ExecutorCounters.SimpleCounters, "DbDataBytes");
- dataSize += getCounter(result.TabletCounters.AppCounters.SimpleCounters, "KV/RecordBytes");
- dataSize += getCounter(result.TabletCounters.AppCounters.SimpleCounters, "KV/TrashBytes");
- dataSizeCell.innerHTML = bytesToSize(dataSize);
-}
-
-function onTreeNodeChildrenComplete(path, children) {
- var panelTablets = $("#panel-tablets").find(".panel-body").get(0);
- panelTablets.innerHTML = "<table class='children-table'><tr><th>Name</th><th>Type</th><th>Size</th></tr></table>";
- var tableElement = panelTablets.firstChild;
- for (var idx in children) {
- var child = children[idx];
- var row = tableElement.insertRow(-1);
- row.insertCell(-1).innerHTML = child.Name;
- row.insertCell(-1).innerHTML = schemaPathTypeToString(child.PathType);
- var dataSizeCell = row.insertCell(-1);
- if (child.PathType === 2 || child.PathType === 3) {
- dataSizeCell.innerHTML = "<img src='throbber.gif'></img>";
- (function(cell){
- $.ajax({
- url: "json/tabletcounters?path=" + path + "/" + child.Name,
- success: function(result) { onTreeNodeChildrenDataSizeComplete(cell, result); }
- });
- })(dataSizeCell);
- } else {
- dataSizeCell.innerHTML = "";
- }
- }
-}
-
-var sizes = ["", "K", "M", "G", "T", "P", "E"];
-
-function bytesToSize(bytes) {
- if (isNaN(bytes)) {
- return "";
- }
- if (bytes < 1024)
- return String(bytes);
- var i = parseInt(Math.floor(Math.log(bytes) / Math.log(1024)));
- if (i >= sizes.length) {
- i = sizes.length - 1;
- }
- var val = bytes / Math.pow(1024, i);
- if (val > 999) {
- val = val / 1024;
- i++;
- }
- return val.toPrecision(3) + sizes[i];
-}
-
-function valueToNumber(value) {
- return Number(value).toLocaleString();
-}
-
-function onTopicNodeComplete(result, obj) {
- if (result === null)
- return;
- var panelSchema = $("#panel-schema").find(".panel-body").get(0);
- panelSchema.innerHTML = "<table class='proplist'><table>";
- var tab = $(panelSchema).find("table").get(0);
+ dataSize += getCounter(result.TabletCounters.AppCounters.SimpleCounters, "KV/RecordBytes");
+ dataSize += getCounter(result.TabletCounters.AppCounters.SimpleCounters, "KV/TrashBytes");
+ dataSizeCell.innerHTML = bytesToSize(dataSize);
+}
+
+function onTreeNodeChildrenComplete(path, children) {
+ var panelTablets = $("#panel-tablets").find(".panel-body").get(0);
+ panelTablets.innerHTML = "<table class='children-table'><tr><th>Name</th><th>Type</th><th>Size</th></tr></table>";
+ var tableElement = panelTablets.firstChild;
+ for (var idx in children) {
+ var child = children[idx];
+ var row = tableElement.insertRow(-1);
+ row.insertCell(-1).innerHTML = child.Name;
+ row.insertCell(-1).innerHTML = schemaPathTypeToString(child.PathType);
+ var dataSizeCell = row.insertCell(-1);
+ if (child.PathType === 2 || child.PathType === 3) {
+ dataSizeCell.innerHTML = "<img src='throbber.gif'></img>";
+ (function(cell){
+ $.ajax({
+ url: "json/tabletcounters?path=" + path + "/" + child.Name,
+ success: function(result) { onTreeNodeChildrenDataSizeComplete(cell, result); }
+ });
+ })(dataSizeCell);
+ } else {
+ dataSizeCell.innerHTML = "";
+ }
+ }
+}
+
+var sizes = ["", "K", "M", "G", "T", "P", "E"];
+
+function bytesToSize(bytes) {
+ if (isNaN(bytes)) {
+ return "";
+ }
+ if (bytes < 1024)
+ return String(bytes);
+ var i = parseInt(Math.floor(Math.log(bytes) / Math.log(1024)));
+ if (i >= sizes.length) {
+ i = sizes.length - 1;
+ }
+ var val = bytes / Math.pow(1024, i);
+ if (val > 999) {
+ val = val / 1024;
+ i++;
+ }
+ return val.toPrecision(3) + sizes[i];
+}
+
+function valueToNumber(value) {
+ return Number(value).toLocaleString();
+}
+
+function onTopicNodeComplete(result, obj) {
+ if (result === null)
+ return;
+ var panelSchema = $("#panel-schema").find(".panel-body").get(0);
+ panelSchema.innerHTML = "<table class='proplist'><table>";
+ var tab = $(panelSchema).find("table").get(0);
for (var i = 0; i < result.LabeledCountersByGroup.length; ++i) {
var labeledCountersByGroup = result.LabeledCountersByGroup[i];
- var row = tab.insertRow();
+ var row = tab.insertRow();
row.insertCell(-1).innerHTML = labeledCountersByGroup.Group;
for (var idx = 0; idx < labeledCountersByGroup.LabeledCounter.length; ++idx) {
var row = tab.insertRow();
row.insertCell(-1).innerHTML = labeledCountersByGroup.LabeledCounter[idx].Name;
row.insertCell(-1).innerHTML = labeledCountersByGroup.LabeledCounter[idx].Value;
}
- }
-}
-
-function onTreeNodeComplete(result, obj) {
- if (result === null)
- return;
- var panelInfo = $("#panel-info").find(".panel-body").get(0);
- var panelSchema = $("#panel-schema").find(".panel-body").get(0);
- var panelTablets = $("#panel-tablets").find(".panel-body").get(0);
- panelInfo.innerHTML = "<table class='proplist'><table>";
- var tab = $(panelInfo).find("table").get(0);
- var row;
- var name;
- var value;
- if (result.Path !== undefined) {
- row = tab.insertRow();
- name = row.insertCell(-1);
- value = row.insertCell(-1);
- name.innerHTML = "Path";
- value.innerHTML = result.Path;
- Parameters.path = result.Path;
- window.location.hash = $.param(Parameters);
- }
-
- panelSchema.innerHTML = "";
- panelTablets.innerHTML = "";
- var dataSize = null;
- SchemaTabletElements = {};
- if (result.PathDescription !== undefined) {
- var table = result.PathDescription.Table;
- if (table !== undefined) {
- var schemaHtml = "<table class='schema-table'><tr><th>&#128273;</th><th>Id</th><th>Type</th><th>Name</th></tr>";
- var colLen = table.Columns.length;
- var column;
- var key;
- for (var i = 0; i < colLen; i++) {
- column = table.Columns[i];
- if (table.KeyColumnIds.find(function(n){return n === column.Id;}) !== undefined) {
- key = "&#10003;";
- } else {
- key = "&nbsp;"
- }
- schemaHtml += "<tr><td>" + key + "</td><td>" + column.Id + "</td><td>" + column.Type + "</td><td>" + column.Name + "</td></tr>";
- }
- schemaHtml += "</table>";
- panelSchema.innerHTML = schemaHtml;
+ }
+}
+
+function onTreeNodeComplete(result, obj) {
+ if (result === null)
+ return;
+ var panelInfo = $("#panel-info").find(".panel-body").get(0);
+ var panelSchema = $("#panel-schema").find(".panel-body").get(0);
+ var panelTablets = $("#panel-tablets").find(".panel-body").get(0);
+ panelInfo.innerHTML = "<table class='proplist'><table>";
+ var tab = $(panelInfo).find("table").get(0);
+ var row;
+ var name;
+ var value;
+ if (result.Path !== undefined) {
+ row = tab.insertRow();
+ name = row.insertCell(-1);
+ value = row.insertCell(-1);
+ name.innerHTML = "Path";
+ value.innerHTML = result.Path;
+ Parameters.path = result.Path;
+ window.location.hash = $.param(Parameters);
+ }
+
+ panelSchema.innerHTML = "";
+ panelTablets.innerHTML = "";
+ var dataSize = null;
+ SchemaTabletElements = {};
+ if (result.PathDescription !== undefined) {
+ var table = result.PathDescription.Table;
+ if (table !== undefined) {
+ var schemaHtml = "<table class='schema-table'><tr><th>&#128273;</th><th>Id</th><th>Type</th><th>Name</th></tr>";
+ var colLen = table.Columns.length;
+ var column;
+ var key;
+ for (var i = 0; i < colLen; i++) {
+ column = table.Columns[i];
+ if (table.KeyColumnIds.find(function(n){return n === column.Id;}) !== undefined) {
+ key = "&#10003;";
+ } else {
+ key = "&nbsp;"
+ }
+ schemaHtml += "<tr><td>" + key + "</td><td>" + column.Id + "</td><td>" + column.Type + "</td><td>" + column.Name + "</td></tr>";
+ }
+ schemaHtml += "</table>";
+ panelSchema.innerHTML = schemaHtml;
var indexes = table.TableIndexes;
- if (indexes !== undefined) {
- var ilen = indexes.length;
- var schemaHtml = "<br><table class='schema-table'><tr><th>IndexName</th><th>Columns</th></tr>";
- for (var i = 0; i < ilen; i++) {
- schemaHtml += "<tr><td>" + indexes[i].Name + "</td><td>";
- var jlen = indexes[i].KeyColumnNames.length;
- for (var j = 0; j < jlen; j++) {
- schemaHtml += indexes[i].KeyColumnNames[j];
- if (j < jlen - 1) {
- schemaHtml += ", ";
- }
+ if (indexes !== undefined) {
+ var ilen = indexes.length;
+ var schemaHtml = "<br><table class='schema-table'><tr><th>IndexName</th><th>Columns</th></tr>";
+ for (var i = 0; i < ilen; i++) {
+ schemaHtml += "<tr><td>" + indexes[i].Name + "</td><td>";
+ var jlen = indexes[i].KeyColumnNames.length;
+ for (var j = 0; j < jlen; j++) {
+ schemaHtml += indexes[i].KeyColumnNames[j];
+ if (j < jlen - 1) {
+ schemaHtml += ", ";
+ }
}
- schemaHtml += "</td></tr>"
+ schemaHtml += "</td></tr>"
}
- schemaHtml += "</table>";
- panelSchema.innerHTML += schemaHtml;
+ schemaHtml += "</table>";
+ panelSchema.innerHTML += schemaHtml;
}
var cdcStreams = table.CdcStreams;
@@ -2765,63 +2765,63 @@ function onTreeNodeComplete(result, obj) {
panelSchema.innerHTML += schemaHtml;
}
}
-
- var tabLen;
- var tablet;
- var partitions = result.PathDescription.TablePartitions;
- if (partitions !== undefined) {
- tabLen = partitions.length;
- for (var j = 0; j < tabLen; j++) {
- tablet = String(partitions[j].DatashardId);
- SchemaTabletElements[tablet] = null;
- }
- }
- var pqgroup = result.PathDescription.PersQueueGroup;
- if (pqgroup !== undefined) {
- var pqpartitions = result.PathDescription.PersQueueGroup.Partitions;
- if (pqpartitions !== undefined) {
- panelSchema.innerHTML = "";
- $.ajax({
- url: "json/topicinfo?path=" + obj.id,
- success: function(result) { onTopicNodeComplete(result, obj); }
- });
- var partElement;
- tabLen = pqpartitions.length;
- for (var k = 0; k < tabLen; k++) {
- tablet = String(pqpartitions[k].TabletId);
- SchemaTabletElements[tablet] = null;
- }
- }
- if (pqgroup.BalancerTabletID !== undefined) {
- SchemaTabletElements[pqgroup.BalancerTabletID] = null;
- }
- }
+
+ var tabLen;
+ var tablet;
+ var partitions = result.PathDescription.TablePartitions;
+ if (partitions !== undefined) {
+ tabLen = partitions.length;
+ for (var j = 0; j < tabLen; j++) {
+ tablet = String(partitions[j].DatashardId);
+ SchemaTabletElements[tablet] = null;
+ }
+ }
+ var pqgroup = result.PathDescription.PersQueueGroup;
+ if (pqgroup !== undefined) {
+ var pqpartitions = result.PathDescription.PersQueueGroup.Partitions;
+ if (pqpartitions !== undefined) {
+ panelSchema.innerHTML = "";
+ $.ajax({
+ url: "json/topicinfo?path=" + obj.id,
+ success: function(result) { onTopicNodeComplete(result, obj); }
+ });
+ var partElement;
+ tabLen = pqpartitions.length;
+ for (var k = 0; k < tabLen; k++) {
+ tablet = String(pqpartitions[k].TabletId);
+ SchemaTabletElements[tablet] = null;
+ }
+ }
+ if (pqgroup.BalancerTabletID !== undefined) {
+ SchemaTabletElements[pqgroup.BalancerTabletID] = null;
+ }
+ }
if (result.PathDescription.Self.PathType === 4 || result.PathDescription.Self.PathType === 10) {
var subdomain = result.PathDescription.DomainDescription;
- if (subdomain !== undefined) {
- var params = subdomain.ProcessingParams;
- if (params !== undefined) {
- if (params.Coordinators !== undefined) {
- tabLen = params.Coordinators.length;
- for (var k = 0; k < tabLen; k++) {
- tablet = String(params.Coordinators[k]);
- SchemaTabletElements[tablet] = null;
- }
- }
- if (params.Mediators !== undefined) {
- tabLen = params.Mediators.length;
- for (var k = 0; k < tabLen; k++) {
- tablet = String(params.Mediators[k]);
- SchemaTabletElements[tablet] = null;
- }
- }
+ if (subdomain !== undefined) {
+ var params = subdomain.ProcessingParams;
+ if (params !== undefined) {
+ if (params.Coordinators !== undefined) {
+ tabLen = params.Coordinators.length;
+ for (var k = 0; k < tabLen; k++) {
+ tablet = String(params.Coordinators[k]);
+ SchemaTabletElements[tablet] = null;
+ }
+ }
+ if (params.Mediators !== undefined) {
+ tabLen = params.Mediators.length;
+ for (var k = 0; k < tabLen; k++) {
+ tablet = String(params.Mediators[k]);
+ SchemaTabletElements[tablet] = null;
+ }
+ }
if (params.SchemeShard !== undefined) {
tablet = String(params.SchemeShard);
SchemaTabletElements[tablet] = null;
}
- }
- }
- }
+ }
+ }
+ }
if (result.PathDescription.Self.PathType === 12) {
var olapStore = result.PathDescription.OlapStoreDescription;
if (olapStore !== undefined) {
@@ -2841,8 +2841,8 @@ function onTreeNodeComplete(result, obj) {
}
}
}
- }
-
+ }
+
if (result.PathDescription.Self.PathType === 7) {
tablet = String(result.PathDescription.Kesus.KesusTabletId);
SchemaTabletElements[tablet] = null;
@@ -2890,98 +2890,98 @@ function onTreeNodeComplete(result, obj) {
value.innerHTML = String(result.PathDescription.Kesus.Config.attach_consistency_mode);
}
- if (Object.keys(SchemaTabletElements).length !== 0) {
- panelTablets.innerHTML = "<img src='throbber.gif'></img>";
- row = tab.insertRow();
- name = row.insertCell(-1);
- value = row.insertCell(-1);
- name.innerHTML = "Tablets";
- value.innerHTML = Object.keys(SchemaTabletElements).length;
- value.id = "schema-tablets";
- onTreeNodeTabletsComplete();
- }
-
+ if (Object.keys(SchemaTabletElements).length !== 0) {
+ panelTablets.innerHTML = "<img src='throbber.gif'></img>";
+ row = tab.insertRow();
+ name = row.insertCell(-1);
+ value = row.insertCell(-1);
+ name.innerHTML = "Tablets";
+ value.innerHTML = Object.keys(SchemaTabletElements).length;
+ value.id = "schema-tablets";
+ onTreeNodeTabletsComplete();
+ }
+
if (result.PathDescription !== undefined && result.PathDescription.Children !== undefined
&& result.PathDescription.Self.PathType !== 4 && result.PathDescription.Self.PathType !== 12) {
- onTreeNodeChildrenComplete(result.Path, result.PathDescription.Children);
- }
-
- if (result.PathDescription.TablePartitions !== undefined) {
- row = tab.insertRow();
- name = row.insertCell(-1);
- value = row.insertCell(-1);
- name.innerHTML = "Partitions";
- value.innerHTML = result.PathDescription.TablePartitions.length;
- }
-
- if (result.PathDescription.TabletMetrics !== undefined) {
- var metrics = result.PathDescription.TabletMetrics;
- if (metrics.CPU && Number(metrics.CPU)) {
- row = tab.insertRow(-1);
- row.insertCell(-1).innerHTML = "CPU";
- row.insertCell(-1).innerHTML = (metrics.CPU / 10000).toFixed(2) + "%"; // 1sec (1000000uS) per 1sec = 100%
- }
- if (metrics.Memory && Number(metrics.Memory)) {
- row = tab.insertRow(-1);
- row.insertCell(-1).innerHTML = "Memory";
- row.insertCell(-1).innerHTML = bytesToSize(metrics.Memory);
- }
- if (metrics.Network && Number(metrics.Network)) {
- row = tab.insertRow(-1);
- row.insertCell(-1).innerHTML = "Network";
- row.insertCell(-1).innerHTML = bytesToSize(metrics.Network) + "/s";
- }
- if (metrics.ReadThroughput && Number(metrics.ReadThroughput)) {
- row = tab.insertRow(-1);
- row.insertCell(-1).innerHTML = "Read";
- row.insertCell(-1).innerHTML = bytesToSize(metrics.ReadThroughput) + "/s";
- }
- if (metrics.WriteThroughput && Number(metrics.WriteThroughput)) {
- row = tab.insertRow(-1);
- row.insertCell(-1).innerHTML = "Write";
- row.insertCell(-1).innerHTML = bytesToSize(metrics.WriteThroughput) + "/s";
- }
- }
-
- if (result.PathDescription.Self.PathType === 2 || result.PathDescription.Self.PathType === 3) {
- row = tab.insertRow(-1);
- row.insertCell(-1).innerHTML = "Data Size";
- var dataSizeCell = row.insertCell(-1);
- if (result.PathDescription.TabletMetrics !== undefined && result.PathDescription.TabletMetrics.Storage !== undefined) {
- dataSizeCell.innerHTML = bytesToSize(result.PathDescription.TabletMetrics.Storage);
- } else {
- dataSizeCell.innerHTML = "<img src='throbber.gif'></img>";
- (function(cell){
- $.ajax({
- url: "json/tabletcounters?path=" + obj.id,
- success: function(result) { onTreeNodeChildrenDataSizeComplete(cell, result); }
- });
- })(dataSizeCell);
- }
- }
-
- if (result.PathDescription.TableStats !== undefined) {
- var stats = result.PathDescription.TableStats;
- if (stats.DataSize && Number(stats.DataSize)) {
- row = tab.insertRow(-1);
- row.insertCell(-1).innerHTML = "Size";
- row.insertCell(-1).innerHTML = bytesToSize(stats.DataSize);
- }
- if (stats.RowCount && Number(stats.RowCount)) {
- row = tab.insertRow(-1);
- row.insertCell(-1).innerHTML = "Rows";
- row.insertCell(-1).innerHTML = valueToNumber(stats.RowCount);
- }
- if (stats.LastAccessTime && Number(stats.LastAccessTime)) {
- row = tab.insertRow(-1);
- row.insertCell(-1).innerHTML = "Last Access";
- row.insertCell(-1).innerHTML = (new Date(Number(stats.LastAccessTime))).toISOString();
- }
- if (stats.LastUpdateTime && Number(stats.LastUpdateTime)) {
- row = tab.insertRow(-1);
- row.insertCell(-1).innerHTML = "Last Update";
- row.insertCell(-1).innerHTML = (new Date(Number(stats.LastUpdateTime))).toISOString();
- }
+ onTreeNodeChildrenComplete(result.Path, result.PathDescription.Children);
+ }
+
+ if (result.PathDescription.TablePartitions !== undefined) {
+ row = tab.insertRow();
+ name = row.insertCell(-1);
+ value = row.insertCell(-1);
+ name.innerHTML = "Partitions";
+ value.innerHTML = result.PathDescription.TablePartitions.length;
+ }
+
+ if (result.PathDescription.TabletMetrics !== undefined) {
+ var metrics = result.PathDescription.TabletMetrics;
+ if (metrics.CPU && Number(metrics.CPU)) {
+ row = tab.insertRow(-1);
+ row.insertCell(-1).innerHTML = "CPU";
+ row.insertCell(-1).innerHTML = (metrics.CPU / 10000).toFixed(2) + "%"; // 1sec (1000000uS) per 1sec = 100%
+ }
+ if (metrics.Memory && Number(metrics.Memory)) {
+ row = tab.insertRow(-1);
+ row.insertCell(-1).innerHTML = "Memory";
+ row.insertCell(-1).innerHTML = bytesToSize(metrics.Memory);
+ }
+ if (metrics.Network && Number(metrics.Network)) {
+ row = tab.insertRow(-1);
+ row.insertCell(-1).innerHTML = "Network";
+ row.insertCell(-1).innerHTML = bytesToSize(metrics.Network) + "/s";
+ }
+ if (metrics.ReadThroughput && Number(metrics.ReadThroughput)) {
+ row = tab.insertRow(-1);
+ row.insertCell(-1).innerHTML = "Read";
+ row.insertCell(-1).innerHTML = bytesToSize(metrics.ReadThroughput) + "/s";
+ }
+ if (metrics.WriteThroughput && Number(metrics.WriteThroughput)) {
+ row = tab.insertRow(-1);
+ row.insertCell(-1).innerHTML = "Write";
+ row.insertCell(-1).innerHTML = bytesToSize(metrics.WriteThroughput) + "/s";
+ }
+ }
+
+ if (result.PathDescription.Self.PathType === 2 || result.PathDescription.Self.PathType === 3) {
+ row = tab.insertRow(-1);
+ row.insertCell(-1).innerHTML = "Data Size";
+ var dataSizeCell = row.insertCell(-1);
+ if (result.PathDescription.TabletMetrics !== undefined && result.PathDescription.TabletMetrics.Storage !== undefined) {
+ dataSizeCell.innerHTML = bytesToSize(result.PathDescription.TabletMetrics.Storage);
+ } else {
+ dataSizeCell.innerHTML = "<img src='throbber.gif'></img>";
+ (function(cell){
+ $.ajax({
+ url: "json/tabletcounters?path=" + obj.id,
+ success: function(result) { onTreeNodeChildrenDataSizeComplete(cell, result); }
+ });
+ })(dataSizeCell);
+ }
+ }
+
+ if (result.PathDescription.TableStats !== undefined) {
+ var stats = result.PathDescription.TableStats;
+ if (stats.DataSize && Number(stats.DataSize)) {
+ row = tab.insertRow(-1);
+ row.insertCell(-1).innerHTML = "Size";
+ row.insertCell(-1).innerHTML = bytesToSize(stats.DataSize);
+ }
+ if (stats.RowCount && Number(stats.RowCount)) {
+ row = tab.insertRow(-1);
+ row.insertCell(-1).innerHTML = "Rows";
+ row.insertCell(-1).innerHTML = valueToNumber(stats.RowCount);
+ }
+ if (stats.LastAccessTime && Number(stats.LastAccessTime)) {
+ row = tab.insertRow(-1);
+ row.insertCell(-1).innerHTML = "Last Access";
+ row.insertCell(-1).innerHTML = (new Date(Number(stats.LastAccessTime))).toISOString();
+ }
+ if (stats.LastUpdateTime && Number(stats.LastUpdateTime)) {
+ row = tab.insertRow(-1);
+ row.insertCell(-1).innerHTML = "Last Update";
+ row.insertCell(-1).innerHTML = (new Date(Number(stats.LastUpdateTime))).toISOString();
+ }
if (stats.ImmediateTxCompleted && Number(stats.ImmediateTxCompleted)) {
row = tab.insertRow(-1);
row.insertCell(-1).innerHTML = "Immediate Tx Completed";
@@ -3038,58 +3038,58 @@ function onTreeNodeComplete(result, obj) {
row.insertCell(-1).innerHTML = "Range Read Rows";
row.insertCell(-1).innerHTML = valueToNumber(stats.RangeReadRows);
}
- }
-
- if (result.PathDescription.PersQueueGroup !== undefined) {
- row = tab.insertRow();
- name = row.insertCell(-1);
- value = row.insertCell(-1);
- name.innerHTML = "Partitions";
+ }
+
+ if (result.PathDescription.PersQueueGroup !== undefined) {
+ row = tab.insertRow();
+ name = row.insertCell(-1);
+ value = row.insertCell(-1);
+ name.innerHTML = "Partitions";
value.innerHTML = result.PathDescription.PersQueueGroup.TotalGroupCount;
-
- var partitionConfig = result.PathDescription.PersQueueGroup.PQTabletConfig.PartitionConfig;
-
- row = tab.insertRow();
- name = row.insertCell(-1);
- value = row.insertCell(-1);
- name.innerHTML = "Max Count";
- value.innerHTML = partitionConfig.MaxCountInPartition;
-
- row = tab.insertRow();
- name = row.insertCell(-1);
- value = row.insertCell(-1);
- name.innerHTML = "Max Size";
- value.innerHTML = bytesToSize(partitionConfig.MaxSizeInPartition);
- value.title = partitionConfig.MaxSizeInPartition;
-
- if (partitionConfig.ImportantClientId !== undefined) {
- row = tab.insertRow();
- name = row.insertCell(-1);
- value = row.insertCell(-1);
- name.innerHTML = "Important Client Id";
- value.innerHTML = partitionConfig.ImportantClientId;
- }
-
- row = tab.insertRow();
- name = row.insertCell(-1);
- value = row.insertCell(-1);
- name.innerHTML = "Life Time";
- value.innerHTML = partitionConfig.LifetimeSeconds + " seconds";
- }
+
+ var partitionConfig = result.PathDescription.PersQueueGroup.PQTabletConfig.PartitionConfig;
+
+ row = tab.insertRow();
+ name = row.insertCell(-1);
+ value = row.insertCell(-1);
+ name.innerHTML = "Max Count";
+ value.innerHTML = partitionConfig.MaxCountInPartition;
+
+ row = tab.insertRow();
+ name = row.insertCell(-1);
+ value = row.insertCell(-1);
+ name.innerHTML = "Max Size";
+ value.innerHTML = bytesToSize(partitionConfig.MaxSizeInPartition);
+ value.title = partitionConfig.MaxSizeInPartition;
+
+ if (partitionConfig.ImportantClientId !== undefined) {
+ row = tab.insertRow();
+ name = row.insertCell(-1);
+ value = row.insertCell(-1);
+ name.innerHTML = "Important Client Id";
+ value.innerHTML = partitionConfig.ImportantClientId;
+ }
+
+ row = tab.insertRow();
+ name = row.insertCell(-1);
+ value = row.insertCell(-1);
+ name.innerHTML = "Life Time";
+ value.innerHTML = partitionConfig.LifetimeSeconds + " seconds";
+ }
if ((result.PathDescription.Self.PathType === 10 || result.PathDescription.Self.PathType === 4) && result.PathDescription.DomainDescription !== undefined) {
if (result.PathDescription.DomainDescription.ProcessingParams !== undefined) {
if (result.PathDescription.DomainDescription.ProcessingParams.Version !== undefined) {
- row = tab.insertRow();
+ row = tab.insertRow();
row.insertCell(-1).innerHTML = "SubdomainVersion";
row.insertCell(-1).innerHTML = result.PathDescription.DomainDescription.ProcessingParams.Version;
- }
+ }
if (result.PathDescription.DomainDescription.ProcessingParams.PlanResolution !== undefined) {
- row = tab.insertRow();
- row.insertCell(-1).innerHTML = "Plan Resolution";
+ row = tab.insertRow();
+ row.insertCell(-1).innerHTML = "Plan Resolution";
row.insertCell(-1).innerHTML = result.PathDescription.DomainDescription.ProcessingParams.PlanResolution + "ms";
- }
- }
+ }
+ }
if (result.PathDescription.DomainDescription.DomainKey !== undefined) {
row = tab.insertRow();
row.insertCell(-1).innerHTML = "DomainKey";
@@ -3120,9 +3120,9 @@ function onTreeNodeComplete(result, obj) {
}
}
- }
-
- if (result.PathDescription.BackupProgress !== undefined) {
+ }
+
+ if (result.PathDescription.BackupProgress !== undefined) {
row = tab.insertRow();
name = row.insertCell(-1);
value = row.insertCell(-1);
@@ -3136,9 +3136,9 @@ function onTreeNodeComplete(result, obj) {
}
var backupResultList = result.PathDescription.LastBackupResult;
- if (backupResultList !== undefined && backupResultList.length > 0) {
+ if (backupResultList !== undefined && backupResultList.length > 0) {
var backupResult = backupResultList[backupResultList.length - 1];
- if (backupResult.CompleteTimeStamp !== undefined) {
+ if (backupResult.CompleteTimeStamp !== undefined) {
row = tab.insertRow();
name = row.insertCell(-1);
value = row.insertCell(-1);
@@ -3148,7 +3148,7 @@ function onTreeNodeComplete(result, obj) {
value.innerHTML = dateObj.toLocaleString();
}
- if (backupResult.ErrorCount !== undefined) {
+ if (backupResult.ErrorCount !== undefined) {
row = tab.insertRow();
name = row.insertCell(-1);
value = row.insertCell(-1);
@@ -3156,105 +3156,105 @@ function onTreeNodeComplete(result, obj) {
value.innerHTML = backupResult.ErrorCount;
}
}
-}
-
-function onTreeNodeSelected(e, data) {
- var obj = data.node;
- $.ajax({
- url: "json/describe?path=" + obj.id,
- success: function(result) { onTreeNodeComplete(result, obj); }
- });
-}
-
-function onTreeData(obj, cb) {
- if (obj.id === "#") {
- cb.call(this, {
- id: "/",
- parent: "#",
- text: "/",
- children: true,
- icon: "glyphicon glyphicon-cloud schema-good",
- data: function (obj1, cb1) { onTreeData(obj1, cb1); }
- });
- } else {
- $.ajax({
- url: "json/describe?path=" + obj.id,
- success: function(result) { onTreeDataComplete(result, obj, cb); },
- error: function(result) { cb.call(this, null); }
- });
- }
-}
-
-function onExecSqlResult(result) {
- $("#panel-sql-button-run").html("<span class='glyphicon glyphicon-play'></span>");
- $("#panel-sql-result").show();
- $("#panel-sql-error").hide();
- var table = $("#sql-result")[0];
- $("#sql-result th").remove();
- $("#sql-result tr").remove();
- var header = table.createTHead();
- var header_row = header.insertRow(0);
- if (result.length > 0) {
- for (var prop in result[0]) {
- var cell = document.createElement("TH");
- header_row.appendChild(cell);
- cell.innerHTML = prop;
- }
- }
- for (var idx = 0; idx < result.length; ++idx) {
- var row = table.insertRow(-1);
- for (var prop in result[idx]) {
- var cell = document.createElement("TD");
- row.appendChild(cell);
- cell.innerHTML = result[idx][prop];
- }
- }
-}
-
-function onExecSqlError(result) {
- $("#panel-sql-button-run").html("<span class='glyphicon glyphicon-play'></span>");
- $("#panel-sql-result").hide();
- $("#panel-sql-error").show();
- var text = "?";
- if (result !== null) {
- if (result.responseText !== undefined) {
- text = result.responseText;
- // TODO(xenoxeno): return only ErrorReason part
- }
- }
- $("#sql-error").text(text);
-}
-
-function onExecSql() {
- var sql = $("#panel-sql-text").val();
- $("#panel-sql-button-run").html("<img src='throbber.gif'></img>");
- $.ajax({
- type: "POST",
- url: 'json/query',
- data: JSON.stringify({
- query: sql
- }),
- contentType: "application/json; charset=utf-8",
- dataType: "json",
- success: onExecSqlResult,
- error: onExecSqlError
- });
-}
-
-function main() {
- $.ajax({
- url: "json/nodelist",
- success: function(result) { onNodeList(result); },
- error: function() { onNodeList(null); }
- });
- $(function () { $('#schema-tree').jstree({ core: { data: function (obj, cb) { onTreeData(obj, cb); } } }); });
- $("#schema-tree").on("select_node.jstree", function(e, data) { onTreeNodeSelected(e, data); });
- $("#panel-sql-button-run").on("click", onExecSql);
-
- if (Parameters.path !== undefined) {
- $("#schema-tree").on('loaded.jstree', function() {
- OpeningPath = Parameters.path;
- $("#schema-tree").jstree('open_node', '/');
- });
- }
-}
+}
+
+function onTreeNodeSelected(e, data) {
+ var obj = data.node;
+ $.ajax({
+ url: "json/describe?path=" + obj.id,
+ success: function(result) { onTreeNodeComplete(result, obj); }
+ });
+}
+
+function onTreeData(obj, cb) {
+ if (obj.id === "#") {
+ cb.call(this, {
+ id: "/",
+ parent: "#",
+ text: "/",
+ children: true,
+ icon: "glyphicon glyphicon-cloud schema-good",
+ data: function (obj1, cb1) { onTreeData(obj1, cb1); }
+ });
+ } else {
+ $.ajax({
+ url: "json/describe?path=" + obj.id,
+ success: function(result) { onTreeDataComplete(result, obj, cb); },
+ error: function(result) { cb.call(this, null); }
+ });
+ }
+}
+
+function onExecSqlResult(result) {
+ $("#panel-sql-button-run").html("<span class='glyphicon glyphicon-play'></span>");
+ $("#panel-sql-result").show();
+ $("#panel-sql-error").hide();
+ var table = $("#sql-result")[0];
+ $("#sql-result th").remove();
+ $("#sql-result tr").remove();
+ var header = table.createTHead();
+ var header_row = header.insertRow(0);
+ if (result.length > 0) {
+ for (var prop in result[0]) {
+ var cell = document.createElement("TH");
+ header_row.appendChild(cell);
+ cell.innerHTML = prop;
+ }
+ }
+ for (var idx = 0; idx < result.length; ++idx) {
+ var row = table.insertRow(-1);
+ for (var prop in result[idx]) {
+ var cell = document.createElement("TD");
+ row.appendChild(cell);
+ cell.innerHTML = result[idx][prop];
+ }
+ }
+}
+
+function onExecSqlError(result) {
+ $("#panel-sql-button-run").html("<span class='glyphicon glyphicon-play'></span>");
+ $("#panel-sql-result").hide();
+ $("#panel-sql-error").show();
+ var text = "?";
+ if (result !== null) {
+ if (result.responseText !== undefined) {
+ text = result.responseText;
+ // TODO(xenoxeno): return only ErrorReason part
+ }
+ }
+ $("#sql-error").text(text);
+}
+
+function onExecSql() {
+ var sql = $("#panel-sql-text").val();
+ $("#panel-sql-button-run").html("<img src='throbber.gif'></img>");
+ $.ajax({
+ type: "POST",
+ url: 'json/query',
+ data: JSON.stringify({
+ query: sql
+ }),
+ contentType: "application/json; charset=utf-8",
+ dataType: "json",
+ success: onExecSqlResult,
+ error: onExecSqlError
+ });
+}
+
+function main() {
+ $.ajax({
+ url: "json/nodelist",
+ success: function(result) { onNodeList(result); },
+ error: function() { onNodeList(null); }
+ });
+ $(function () { $('#schema-tree').jstree({ core: { data: function (obj, cb) { onTreeData(obj, cb); } } }); });
+ $("#schema-tree").on("select_node.jstree", function(e, data) { onTreeNodeSelected(e, data); });
+ $("#panel-sql-button-run").on("click", onExecSql);
+
+ if (Parameters.path !== undefined) {
+ $("#schema-tree").on('loaded.jstree', function() {
+ OpeningPath = Parameters.path;
+ $("#schema-tree").jstree('open_node', '/');
+ });
+ }
+}
diff --git a/ydb/core/viewer/counters_hosts.h b/ydb/core/viewer/counters_hosts.h
index 0dc900ac8fb..6a7bdcfb3de 100644
--- a/ydb/core/viewer/counters_hosts.h
+++ b/ydb/core/viewer/counters_hosts.h
@@ -1,157 +1,157 @@
-#pragma once
-#include <library/cpp/actors/core/actor_bootstrapped.h>
-#include <library/cpp/actors/core/interconnect.h>
-#include <library/cpp/actors/core/mon.h>
-#include <library/cpp/actors/interconnect/interconnect.h>
+#pragma once
+#include <library/cpp/actors/core/actor_bootstrapped.h>
+#include <library/cpp/actors/core/interconnect.h>
+#include <library/cpp/actors/core/mon.h>
+#include <library/cpp/actors/interconnect/interconnect.h>
#include <library/cpp/json/json_writer.h>
#include <ydb/core/protos/services.pb.h>
#include <ydb/core/node_whiteboard/node_whiteboard.h>
-#include "viewer.h"
-
-namespace NKikimr {
-namespace NViewer {
-
-using namespace NActors;
-using namespace NNodeWhiteboard;
-
-class TCountersHostsList : public TActorBootstrapped<TCountersHostsList> {
- NMon::TEvHttpInfo::TPtr Event;
- THolder<TEvInterconnect::TEvNodesInfo> NodesInfo;
- TMap<TNodeId, THolder<TEvWhiteboard::TEvSystemStateResponse>> NodesResponses;
- ui32 NodesRequested = 0;
- ui32 NodesReceived = 0;
- bool StaticNodesOnly = false;
- bool DynamicNodesOnly = false;
-
-public:
- static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
- return NKikimrServices::TActivity::VIEWER_HANDLER;
- }
-
- TCountersHostsList(IViewer*, NMon::TEvHttpInfo::TPtr& ev)
- : Event(ev)
- {}
-
- void Bootstrap(const TActorContext& ctx) {
- const auto& params(Event->Get()->Request.GetParams());
- StaticNodesOnly = FromStringWithDefault<bool>(params.Get("static_only"), StaticNodesOnly);
- DynamicNodesOnly = FromStringWithDefault<bool>(params.Get("dynamic_only"), DynamicNodesOnly);
+#include "viewer.h"
+
+namespace NKikimr {
+namespace NViewer {
+
+using namespace NActors;
+using namespace NNodeWhiteboard;
+
+class TCountersHostsList : public TActorBootstrapped<TCountersHostsList> {
+ NMon::TEvHttpInfo::TPtr Event;
+ THolder<TEvInterconnect::TEvNodesInfo> NodesInfo;
+ TMap<TNodeId, THolder<TEvWhiteboard::TEvSystemStateResponse>> NodesResponses;
+ ui32 NodesRequested = 0;
+ ui32 NodesReceived = 0;
+ bool StaticNodesOnly = false;
+ bool DynamicNodesOnly = false;
+
+public:
+ static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
+ return NKikimrServices::TActivity::VIEWER_HANDLER;
+ }
+
+ TCountersHostsList(IViewer*, NMon::TEvHttpInfo::TPtr& ev)
+ : Event(ev)
+ {}
+
+ void Bootstrap(const TActorContext& ctx) {
+ const auto& params(Event->Get()->Request.GetParams());
+ StaticNodesOnly = FromStringWithDefault<bool>(params.Get("static_only"), StaticNodesOnly);
+ DynamicNodesOnly = FromStringWithDefault<bool>(params.Get("dynamic_only"), DynamicNodesOnly);
const TActorId nameserviceId = GetNameserviceActorId();
- ctx.Send(nameserviceId, new TEvInterconnect::TEvListNodes());
- ctx.Schedule(TDuration::Seconds(10), new TEvents::TEvWakeup());
- Become(&TThis::StateRequestedList);
- }
-
- STFUNC(StateRequestedList) {
- switch (ev->GetTypeRewrite()) {
- HFunc(TEvInterconnect::TEvNodesInfo, Handle);
- CFunc(TEvents::TSystem::Wakeup, Timeout);
- }
- }
-
- STFUNC(StateRequestedSysInfo) {
- switch (ev->GetTypeRewrite()) {
- HFunc(TEvWhiteboard::TEvSystemStateResponse, Handle);
- HFunc(TEvents::TEvUndelivered, Undelivered);
- HFunc(TEvInterconnect::TEvNodeDisconnected, Disconnected);
- CFunc(TEvents::TSystem::Wakeup, Timeout);
- }
- }
-
- void SendRequest(ui32 nodeId, const TActorContext& ctx) {
+ ctx.Send(nameserviceId, new TEvInterconnect::TEvListNodes());
+ ctx.Schedule(TDuration::Seconds(10), new TEvents::TEvWakeup());
+ Become(&TThis::StateRequestedList);
+ }
+
+ STFUNC(StateRequestedList) {
+ switch (ev->GetTypeRewrite()) {
+ HFunc(TEvInterconnect::TEvNodesInfo, Handle);
+ CFunc(TEvents::TSystem::Wakeup, Timeout);
+ }
+ }
+
+ STFUNC(StateRequestedSysInfo) {
+ switch (ev->GetTypeRewrite()) {
+ HFunc(TEvWhiteboard::TEvSystemStateResponse, Handle);
+ HFunc(TEvents::TEvUndelivered, Undelivered);
+ HFunc(TEvInterconnect::TEvNodeDisconnected, Disconnected);
+ CFunc(TEvents::TSystem::Wakeup, Timeout);
+ }
+ }
+
+ void SendRequest(ui32 nodeId, const TActorContext& ctx) {
TActorId whiteboardServiceId = MakeNodeWhiteboardServiceId(nodeId);
THolder<TEvWhiteboard::TEvSystemStateRequest> request = MakeHolder<TEvWhiteboard::TEvSystemStateRequest>();
- ctx.Send(whiteboardServiceId, request.Release(), IEventHandle::FlagTrackDelivery | IEventHandle::FlagSubscribeOnSession, nodeId);
- ++NodesRequested;
- }
-
- void NodeStateInfoReceived(const TActorContext& ctx) {
- ++NodesReceived;
- if (NodesRequested == NodesReceived) {
- ReplyAndDie(ctx);
- }
- }
-
- void Handle(TEvInterconnect::TEvNodesInfo::TPtr& ev, const TActorContext& ctx) {
- NodesInfo = ev->Release();
- ui32 minAllowedNodeId = std::numeric_limits<ui32>::min();
- ui32 maxAllowedNodeId = std::numeric_limits<ui32>::max();
- TIntrusivePtr<TDynamicNameserviceConfig> dynamicNameserviceConfig = AppData()->DynamicNameserviceConfig;
- if (dynamicNameserviceConfig) {
- if (StaticNodesOnly) {
- maxAllowedNodeId = dynamicNameserviceConfig->MaxStaticNodeId;
- }
- if (DynamicNodesOnly) {
- minAllowedNodeId = dynamicNameserviceConfig->MaxStaticNodeId + 1;
- }
- }
- for (const auto& nodeInfo : NodesInfo->Nodes) {
- if (nodeInfo.NodeId >= minAllowedNodeId && nodeInfo.NodeId <= maxAllowedNodeId) {
- SendRequest(nodeInfo.NodeId, ctx);
- }
- }
- Become(&TThis::StateRequestedSysInfo);
- }
-
- void Handle(TEvWhiteboard::TEvSystemStateResponse::TPtr& ev, const TActorContext& ctx) {
- ui64 nodeId = ev.Get()->Cookie;
- NodesResponses[nodeId] = ev->Release();
- NodeStateInfoReceived(ctx);
- }
-
- void Undelivered(TEvents::TEvUndelivered::TPtr& ev, const TActorContext& ctx) {
- ui32 nodeId = ev.Get()->Cookie;
- if (NodesResponses.emplace(nodeId, nullptr).second) {
- NodeStateInfoReceived(ctx);
- }
- }
-
- void Disconnected(TEvInterconnect::TEvNodeDisconnected::TPtr& ev, const TActorContext& ctx) {
- ui32 nodeId = ev->Get()->NodeId;
- if (NodesResponses.emplace(nodeId, nullptr).second) {
- NodeStateInfoReceived(ctx);
- }
- }
-
- void ReplyAndDie(const TActorContext& ctx) {
- TStringStream text;
- for (const auto& [nodeId, sysInfo] : NodesResponses) {
- if (sysInfo) {
- const auto& record(sysInfo->Record);
- if (record.SystemStateInfoSize() > 0) {
- const auto& state(record.GetSystemStateInfo(0));
- TString host = state.GetHost();
- if (host.empty()) {
- const TEvInterconnect::TNodeInfo* nodeInfo = NodesInfo->GetNodeInfo(nodeId);
- if (nodeInfo != nullptr) {
- host = nodeInfo->Host;
- }
- }
- if (!host.empty()) {
- TString port;
- for (const auto& endpoint : state.GetEndpoints()) {
- if (endpoint.GetName() == "http-mon") {
- port = endpoint.GetAddress();
- break;
- }
- }
- if (port.empty()) {
- port = ":8765";
- }
- host += port;
- text << host << Endl;
- }
- }
- }
- }
- ctx.Send(Event->Sender, new NMon::TEvHttpInfoRes(HTTPOKTEXT + text.Str(), 0, NMon::IEvHttpInfoRes::EContentType::Custom));
- Die(ctx);
- }
-
- void Timeout(const TActorContext &ctx) {
- ReplyAndDie(ctx);
- }
-};
-
-}
-}
+ ctx.Send(whiteboardServiceId, request.Release(), IEventHandle::FlagTrackDelivery | IEventHandle::FlagSubscribeOnSession, nodeId);
+ ++NodesRequested;
+ }
+
+ void NodeStateInfoReceived(const TActorContext& ctx) {
+ ++NodesReceived;
+ if (NodesRequested == NodesReceived) {
+ ReplyAndDie(ctx);
+ }
+ }
+
+ void Handle(TEvInterconnect::TEvNodesInfo::TPtr& ev, const TActorContext& ctx) {
+ NodesInfo = ev->Release();
+ ui32 minAllowedNodeId = std::numeric_limits<ui32>::min();
+ ui32 maxAllowedNodeId = std::numeric_limits<ui32>::max();
+ TIntrusivePtr<TDynamicNameserviceConfig> dynamicNameserviceConfig = AppData()->DynamicNameserviceConfig;
+ if (dynamicNameserviceConfig) {
+ if (StaticNodesOnly) {
+ maxAllowedNodeId = dynamicNameserviceConfig->MaxStaticNodeId;
+ }
+ if (DynamicNodesOnly) {
+ minAllowedNodeId = dynamicNameserviceConfig->MaxStaticNodeId + 1;
+ }
+ }
+ for (const auto& nodeInfo : NodesInfo->Nodes) {
+ if (nodeInfo.NodeId >= minAllowedNodeId && nodeInfo.NodeId <= maxAllowedNodeId) {
+ SendRequest(nodeInfo.NodeId, ctx);
+ }
+ }
+ Become(&TThis::StateRequestedSysInfo);
+ }
+
+ void Handle(TEvWhiteboard::TEvSystemStateResponse::TPtr& ev, const TActorContext& ctx) {
+ ui64 nodeId = ev.Get()->Cookie;
+ NodesResponses[nodeId] = ev->Release();
+ NodeStateInfoReceived(ctx);
+ }
+
+ void Undelivered(TEvents::TEvUndelivered::TPtr& ev, const TActorContext& ctx) {
+ ui32 nodeId = ev.Get()->Cookie;
+ if (NodesResponses.emplace(nodeId, nullptr).second) {
+ NodeStateInfoReceived(ctx);
+ }
+ }
+
+ void Disconnected(TEvInterconnect::TEvNodeDisconnected::TPtr& ev, const TActorContext& ctx) {
+ ui32 nodeId = ev->Get()->NodeId;
+ if (NodesResponses.emplace(nodeId, nullptr).second) {
+ NodeStateInfoReceived(ctx);
+ }
+ }
+
+ void ReplyAndDie(const TActorContext& ctx) {
+ TStringStream text;
+ for (const auto& [nodeId, sysInfo] : NodesResponses) {
+ if (sysInfo) {
+ const auto& record(sysInfo->Record);
+ if (record.SystemStateInfoSize() > 0) {
+ const auto& state(record.GetSystemStateInfo(0));
+ TString host = state.GetHost();
+ if (host.empty()) {
+ const TEvInterconnect::TNodeInfo* nodeInfo = NodesInfo->GetNodeInfo(nodeId);
+ if (nodeInfo != nullptr) {
+ host = nodeInfo->Host;
+ }
+ }
+ if (!host.empty()) {
+ TString port;
+ for (const auto& endpoint : state.GetEndpoints()) {
+ if (endpoint.GetName() == "http-mon") {
+ port = endpoint.GetAddress();
+ break;
+ }
+ }
+ if (port.empty()) {
+ port = ":8765";
+ }
+ host += port;
+ text << host << Endl;
+ }
+ }
+ }
+ }
+ ctx.Send(Event->Sender, new NMon::TEvHttpInfoRes(HTTPOKTEXT + text.Str(), 0, NMon::IEvHttpInfoRes::EContentType::Custom));
+ Die(ctx);
+ }
+
+ void Timeout(const TActorContext &ctx) {
+ ReplyAndDie(ctx);
+ }
+};
+
+}
+}
diff --git a/ydb/core/viewer/json/json.cpp b/ydb/core/viewer/json/json.cpp
index 93b59b3b6e4..51d7c9a32d0 100644
--- a/ydb/core/viewer/json/json.cpp
+++ b/ydb/core/viewer/json/json.cpp
@@ -1,488 +1,488 @@
-#include <unordered_set>
+#include <unordered_set>
#include <library/cpp/string_utils/base64/base64.h>
-#include <util/string/escape.h>
-#include <util/string/printf.h>
-#include <util/charset/utf8.h>
-#include <util/stream/str.h>
-#include "json.h"
-
-void TProtoToJson::EscapeJsonString(IOutputStream& os, const TString& s) {
- const char* b = s.begin();
- const char* e = s.end();
- const char* p = b;
- while (p < e) {
- size_t len = 1;
- RECODE_RESULT result = GetUTF8CharLen(
- len,
- reinterpret_cast<const unsigned char*>(p),
- reinterpret_cast<const unsigned char*>(e)
- );
- if (result == RECODE_OK && len != 1) {
- len = std::min<decltype(len)>(len, e - p);
- os.Write(p, len);
- p += len;
- } else {
- char c = *p;
- if (c < '\x20') {
- os << Sprintf("\\u%04x", int(c));
- } else if (c == '"') {
- os << "\\\"";
- } else if (c == '\\') {
- os << "\\\\";
- } else {
- os << c;
- }
- ++p;
- }
- }
-}
-
-TString TProtoToJson::EscapeJsonString(const TString& s) {
- TStringStream str;
- EscapeJsonString(str, s);
+#include <util/string/escape.h>
+#include <util/string/printf.h>
+#include <util/charset/utf8.h>
+#include <util/stream/str.h>
+#include "json.h"
+
+void TProtoToJson::EscapeJsonString(IOutputStream& os, const TString& s) {
+ const char* b = s.begin();
+ const char* e = s.end();
+ const char* p = b;
+ while (p < e) {
+ size_t len = 1;
+ RECODE_RESULT result = GetUTF8CharLen(
+ len,
+ reinterpret_cast<const unsigned char*>(p),
+ reinterpret_cast<const unsigned char*>(e)
+ );
+ if (result == RECODE_OK && len != 1) {
+ len = std::min<decltype(len)>(len, e - p);
+ os.Write(p, len);
+ p += len;
+ } else {
+ char c = *p;
+ if (c < '\x20') {
+ os << Sprintf("\\u%04x", int(c));
+ } else if (c == '"') {
+ os << "\\\"";
+ } else if (c == '\\') {
+ os << "\\\\";
+ } else {
+ os << c;
+ }
+ ++p;
+ }
+ }
+}
+
+TString TProtoToJson::EscapeJsonString(const TString& s) {
+ TStringStream str;
+ EscapeJsonString(str, s);
return str.Str();
-}
-
-void TProtoToJson::ProtoToJson(IOutputStream& to, const ::google::protobuf::EnumValueDescriptor* descriptor, const TJsonSettings& jsonSettings) {
- if (jsonSettings.EnumAsNumbers) {
- to << descriptor->number();
- } else {
- const ::google::protobuf::EnumValueDescriptor* trueDescriptor = descriptor->type()->FindValueByNumber(descriptor->number());
- if (trueDescriptor == nullptr) {
- to << descriptor->number();
- } else {
- to << '"';
- EscapeJsonString(to, trueDescriptor->name());
- to << '"';
- }
- }
-}
-
-void TProtoToJson::ProtoToJson(IOutputStream& to, const ::google::protobuf::Message& protoFrom, const TJsonSettings& jsonSettings) {
- to << '{';
- ProtoToJsonInline(to, protoFrom, jsonSettings);
- to << '}';
-}
-
-void TProtoToJson::ProtoToJsonInline(IOutputStream& to, const ::google::protobuf::Message& protoFrom, const TJsonSettings& jsonSettings) {
- // TODO: get rid of "copy-paste"
- using namespace ::google::protobuf;
- const Reflection& reflectionFrom = *protoFrom.GetReflection();
- const Descriptor& descriptorFrom = *protoFrom.GetDescriptor();
- bool hasAnyField = false;
- int fieldCount = descriptorFrom.field_count();
- for (int idxField = 0; idxField < fieldCount; ++idxField) {
- const FieldDescriptor* fieldFrom = descriptorFrom.field(idxField);
- auto ir = jsonSettings.FieldRemapper.find(fieldFrom);
- if (ir != jsonSettings.FieldRemapper.end()) {
- TStringStream remapTo;
- ir->second(remapTo, protoFrom, jsonSettings);
- if (remapTo.Size() > 0) {
- if (hasAnyField) {
- to << ',';
- }
- to << remapTo.Str();
- hasAnyField = true;
- }
- } else {
- if (fieldFrom->is_repeated()) {
- if (!jsonSettings.EmptyRepeated && reflectionFrom.FieldSize(protoFrom, fieldFrom) == 0) {
- continue;
- }
- } else {
- if (!reflectionFrom.HasField(protoFrom, fieldFrom)) {
- continue;
- }
- }
- if (hasAnyField) {
- to << ',';
- }
- hasAnyField = true;
- TString name;
- if (jsonSettings.NameGenerator) {
- name = jsonSettings.NameGenerator(*fieldFrom);
- } else {
- name = fieldFrom->name();
- }
- to << '"' << name << "\":";
- FieldDescriptor::CppType type = fieldFrom->cpp_type();
- if (fieldFrom->is_repeated()) {
- int size = reflectionFrom.FieldSize(protoFrom, fieldFrom);
- if (fieldFrom->is_map()) {
- const FieldDescriptor* keyDescriptor = nullptr;
- const FieldDescriptor* valueDescriptor = nullptr;
- FieldDescriptor::CppType keyType;
- FieldDescriptor::CppType valueType;
- const Reflection* itemReflection = nullptr;
- to << '{';
- for (int i = 0; i < size; ++i) {
- const Message& item = reflectionFrom.GetRepeatedMessage(protoFrom, fieldFrom, i);
- if (i == 0) {
- itemReflection = item.GetReflection();
- std::vector<const FieldDescriptor*> fields;
- itemReflection->ListFields(item, &fields);
- if (fields.size() == 2) {
- keyDescriptor = fields[0];
- valueDescriptor = fields[1];
- keyType = keyDescriptor->cpp_type();
- valueType = valueDescriptor->cpp_type();
- } else {
- break;
- }
- } else {
- to << ',';
- }
- to << '"';
- switch (keyType) {
- case FieldDescriptor::CPPTYPE_INT32:
- to << itemReflection->GetInt32(item, keyDescriptor);
- break;
- case FieldDescriptor::CPPTYPE_INT64:
- to << itemReflection->GetInt64(item, keyDescriptor);
- break;
- case FieldDescriptor::CPPTYPE_UINT32:
- to << itemReflection->GetUInt32(item, keyDescriptor);
- break;
- case FieldDescriptor::CPPTYPE_UINT64:
- to << itemReflection->GetUInt64(item, keyDescriptor);
- break;
- case FieldDescriptor::CPPTYPE_DOUBLE:
- {
- double value = itemReflection->GetDouble(item, keyDescriptor);
- if (isnan(value)) {
- to << jsonSettings.NaN;
- } else {
- to << value;
- }
- }
- break;
- case FieldDescriptor::CPPTYPE_FLOAT:
- {
- float value = itemReflection->GetFloat(item, keyDescriptor);
- if (isnan(value)) {
- to << jsonSettings.NaN;
- } else {
- to << value;
- }
- }
- break;
- case FieldDescriptor::CPPTYPE_BOOL:
- to << (itemReflection->GetBool(item, keyDescriptor) ? "true" : "false");
- break;
- case FieldDescriptor::CPPTYPE_ENUM:
- to << itemReflection->GetEnum(item, keyDescriptor)->name();
- break;
- case FieldDescriptor::CPPTYPE_STRING:
- if (fieldFrom->type() == FieldDescriptor::TYPE_BYTES) {
- to << Base64Encode(itemReflection->GetString(item, keyDescriptor));
- } else {
- EscapeJsonString(to, itemReflection->GetString(item, keyDescriptor));
- }
- break;
- default:
- to << "null";
- break;
- }
- to << '"';
- to << ':';
- switch (valueType) {
- case FieldDescriptor::CPPTYPE_INT32:
- to << itemReflection->GetInt32(item, valueDescriptor);
- break;
- case FieldDescriptor::CPPTYPE_INT64:
- if (jsonSettings.UI64AsString) {
- to << '"';
- to << itemReflection->GetInt64(item, valueDescriptor);
- to << '"';
- } else {
- to << itemReflection->GetInt64(item, valueDescriptor);
- }
- break;
- case FieldDescriptor::CPPTYPE_UINT32:
- to << itemReflection->GetUInt32(item, valueDescriptor);
- break;
- case FieldDescriptor::CPPTYPE_UINT64:
- if (jsonSettings.UI64AsString) {
- to << '"';
- to << itemReflection->GetUInt64(item, valueDescriptor);
- to << '"';
- } else {
- to << itemReflection->GetUInt64(item, valueDescriptor);
- }
- break;
- case FieldDescriptor::CPPTYPE_DOUBLE:
- {
- double value = itemReflection->GetDouble(item, valueDescriptor);
- if (isnan(value)) {
- to << jsonSettings.NaN;
- } else {
- to << value;
- }
- }
- break;
- case FieldDescriptor::CPPTYPE_FLOAT:
- {
- float value = itemReflection->GetFloat(item, valueDescriptor);
- if (isnan(value)) {
- to << jsonSettings.NaN;
- } else {
- to << value;
- }
- }
- break;
- case FieldDescriptor::CPPTYPE_BOOL:
- to << (itemReflection->GetBool(item, valueDescriptor) ? "true" : "false");
- break;
- case FieldDescriptor::CPPTYPE_ENUM:
- ProtoToJson(to, itemReflection->GetEnum(item, valueDescriptor), jsonSettings);
- break;
- case FieldDescriptor::CPPTYPE_STRING:
- to << '"';
- if (fieldFrom->type() == FieldDescriptor::TYPE_BYTES) {
- to << Base64Encode(itemReflection->GetString(item, valueDescriptor));
- } else {
- EscapeJsonString(to, itemReflection->GetString(item, valueDescriptor));
- }
- to << '"';
- break;
- case FieldDescriptor::CPPTYPE_MESSAGE:
- ProtoToJson(to, itemReflection->GetMessage(item, valueDescriptor), jsonSettings);
- break;
- }
- }
- to << '}';
- } else {
- to << '[';
- for (int i = 0; i < size; ++i) {
- if (i != 0) {
- to << ',';
- }
- switch (type) {
- case FieldDescriptor::CPPTYPE_INT32:
- to << reflectionFrom.GetRepeatedInt32(protoFrom, fieldFrom, i);
- break;
- case FieldDescriptor::CPPTYPE_INT64:
- // JavaScript could not handle large numbers (bigger than 2^53)
- if (jsonSettings.UI64AsString) {
- to << '"';
- to << reflectionFrom.GetRepeatedInt64(protoFrom, fieldFrom, i);
- to << '"';
- } else {
- to << reflectionFrom.GetRepeatedInt64(protoFrom, fieldFrom, i);
- }
- break;
- case FieldDescriptor::CPPTYPE_UINT32:
- to << reflectionFrom.GetRepeatedUInt32(protoFrom, fieldFrom, i);
- break;
- case FieldDescriptor::CPPTYPE_UINT64:
- if (jsonSettings.UI64AsString) {
- to << '"';
- to << reflectionFrom.GetRepeatedUInt64(protoFrom, fieldFrom, i);
- to << '"';
- } else {
- to << reflectionFrom.GetRepeatedUInt64(protoFrom, fieldFrom, i);
- }
- break;
- case FieldDescriptor::CPPTYPE_DOUBLE:
- {
- double value = reflectionFrom.GetRepeatedDouble(protoFrom, fieldFrom, i);
- if (isnan(value)) {
- to << jsonSettings.NaN;
- } else {
- to << value;
- }
- }
- break;
- case FieldDescriptor::CPPTYPE_FLOAT:
- {
- float value = reflectionFrom.GetRepeatedFloat(protoFrom, fieldFrom, i);
- if (isnan(value)) {
- to << jsonSettings.NaN;
- } else {
- to << value;
- }
- }
- break;
- case FieldDescriptor::CPPTYPE_BOOL:
- to << (reflectionFrom.GetRepeatedBool(protoFrom, fieldFrom, i) ? "true" : "false");
- break;
- case FieldDescriptor::CPPTYPE_ENUM:
- ProtoToJson(to, reflectionFrom.GetRepeatedEnum(protoFrom, fieldFrom, i), jsonSettings);
- break;
- case FieldDescriptor::CPPTYPE_STRING:
- to << '"';
- if (fieldFrom->type() == FieldDescriptor::TYPE_BYTES) {
- to << Base64Encode(reflectionFrom.GetRepeatedString(protoFrom, fieldFrom, i));
- } else {
- EscapeJsonString(to, reflectionFrom.GetRepeatedString(protoFrom, fieldFrom, i));
- }
- to << '"';
- break;
- case FieldDescriptor::CPPTYPE_MESSAGE:
- ProtoToJson(to, reflectionFrom.GetRepeatedMessage(protoFrom, fieldFrom, i), jsonSettings);
- break;
- }
- }
- to << ']';
- }
- } else {
- switch (type) {
- case FieldDescriptor::CPPTYPE_INT32:
- to << reflectionFrom.GetInt32(protoFrom, fieldFrom);
- break;
- case FieldDescriptor::CPPTYPE_INT64:
- if (jsonSettings.UI64AsString) {
- to << '"';
- to << reflectionFrom.GetInt64(protoFrom, fieldFrom);
- to << '"';
- } else {
- to << reflectionFrom.GetInt64(protoFrom, fieldFrom);
- }
- break;
- case FieldDescriptor::CPPTYPE_UINT32:
- to << reflectionFrom.GetUInt32(protoFrom, fieldFrom);
- break;
- case FieldDescriptor::CPPTYPE_UINT64:
- if (jsonSettings.UI64AsString) {
- to << '"';
- to << reflectionFrom.GetUInt64(protoFrom, fieldFrom);
- to << '"';
- } else {
- to << reflectionFrom.GetUInt64(protoFrom, fieldFrom);
- }
- break;
- case FieldDescriptor::CPPTYPE_DOUBLE:
- {
- double value = reflectionFrom.GetDouble(protoFrom, fieldFrom);
- if (isnan(value)) {
- to << jsonSettings.NaN;
- } else {
- to << value;
- }
- }
- break;
- case FieldDescriptor::CPPTYPE_FLOAT:
- {
- float value = reflectionFrom.GetFloat(protoFrom, fieldFrom);
- if (isnan(value)) {
- to << jsonSettings.NaN;
- } else {
- to << value;
- }
- }
- break;
- case FieldDescriptor::CPPTYPE_BOOL:
- to << (reflectionFrom.GetBool(protoFrom, fieldFrom) ? "true" : "false");
- break;
- case FieldDescriptor::CPPTYPE_ENUM:
- ProtoToJson(to, reflectionFrom.GetEnum(protoFrom, fieldFrom), jsonSettings);
- break;
- case FieldDescriptor::CPPTYPE_STRING:
- to << '"';
- if (fieldFrom->type() == FieldDescriptor::TYPE_BYTES) {
- to << Base64Encode(reflectionFrom.GetString(protoFrom, fieldFrom));
- } else {
- EscapeJsonString(to, reflectionFrom.GetString(protoFrom, fieldFrom));
- }
- to << '"';
- break;
- case FieldDescriptor::CPPTYPE_MESSAGE:
- ProtoToJson(to, reflectionFrom.GetMessage(protoFrom, fieldFrom), jsonSettings);
- break;
- }
- }
- }
- }
-}
-
-void TProtoToJson::ProtoToJsonSchema(IOutputStream& to, const TJsonSettings& jsonSettings, const ::google::protobuf::Descriptor* descriptor, std::unordered_set<const ::google::protobuf::Descriptor*>& descriptors) {
- using namespace ::google::protobuf;
- if (descriptor == nullptr) {
- return;
- }
- to << '{';
- to << "\"type\":\"object\",";
- to << "\"title\":\"";
- EscapeJsonString(to, descriptor->name());
- to << '"';
- int fields = descriptor->field_count();
- if (fields > 0) {
- to << ",\"properties\":{";
- int oneofFields = descriptor->oneof_decl_count();
- for (int idx = 0; idx < oneofFields; ++idx) {
- const OneofDescriptor* fieldDescriptor = descriptor->oneof_decl(idx);
- if (idx != 0) {
- to << ',';
- }
- to << '"';
- //TString name;
- if (jsonSettings.NameGenerator) {
- // TODO
- }
- EscapeJsonString(to, fieldDescriptor->name());
- to << "\":";
- to << "{\"type\":\"oneOf\"}";
- }
- for (int idx = 0; idx < fields; ++idx) {
- const FieldDescriptor* fieldDescriptor = descriptor->field(idx);
- if (idx != 0 || oneofFields != 0) {
- to << ',';
- }
- to << '"';
- TString name;
- if (jsonSettings.NameGenerator) {
- name = jsonSettings.NameGenerator(*fieldDescriptor);
- } else {
- name = fieldDescriptor->name();
- }
- EscapeJsonString(to, name);
- to << "\":";
- if (fieldDescriptor->is_repeated()) {
- to << "{\"type\":\"array\",\"items\":";
- }
- if (fieldDescriptor->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) {
- if (descriptors.insert(descriptor).second) {
- ProtoToJsonSchema(to, jsonSettings, fieldDescriptor->message_type(), descriptors);
- } else {
- to << "{}";
- }
- } else {
- to << "{\"type\":\"";
- switch (fieldDescriptor->cpp_type()) {
- case FieldDescriptor::CPPTYPE_INT32:
- case FieldDescriptor::CPPTYPE_UINT32:
- case FieldDescriptor::CPPTYPE_ENUM:
- to << "integer";
- break;
- case FieldDescriptor::CPPTYPE_STRING:
- case FieldDescriptor::CPPTYPE_INT64:
- case FieldDescriptor::CPPTYPE_UINT64:
- to << "string"; // because of JS compatibility (JavaScript could not handle large numbers (bigger than 2^53))
- break;
- case FieldDescriptor::CPPTYPE_FLOAT:
- case FieldDescriptor::CPPTYPE_DOUBLE:
- to << "number";
- break;
- case FieldDescriptor::CPPTYPE_BOOL:
- to << "boolean";
- break;
- case FieldDescriptor::CPPTYPE_MESSAGE:
- to << "object";
- break;
- };
- to << '"';
- to << '}';
- }
- if (fieldDescriptor->is_repeated()) {
- to << '}';
- }
- }
- to << '}';
- }
- to << '}';
-}
-
-void TProtoToJson::ProtoToJsonSchema(IOutputStream& to, const TJsonSettings& jsonSettings, const ::google::protobuf::Descriptor* descriptor) {
- std::unordered_set<const ::google::protobuf::Descriptor*> descriptors;
- ProtoToJsonSchema(to, jsonSettings, descriptor, descriptors);
-}
+}
+
+void TProtoToJson::ProtoToJson(IOutputStream& to, const ::google::protobuf::EnumValueDescriptor* descriptor, const TJsonSettings& jsonSettings) {
+ if (jsonSettings.EnumAsNumbers) {
+ to << descriptor->number();
+ } else {
+ const ::google::protobuf::EnumValueDescriptor* trueDescriptor = descriptor->type()->FindValueByNumber(descriptor->number());
+ if (trueDescriptor == nullptr) {
+ to << descriptor->number();
+ } else {
+ to << '"';
+ EscapeJsonString(to, trueDescriptor->name());
+ to << '"';
+ }
+ }
+}
+
+void TProtoToJson::ProtoToJson(IOutputStream& to, const ::google::protobuf::Message& protoFrom, const TJsonSettings& jsonSettings) {
+ to << '{';
+ ProtoToJsonInline(to, protoFrom, jsonSettings);
+ to << '}';
+}
+
+void TProtoToJson::ProtoToJsonInline(IOutputStream& to, const ::google::protobuf::Message& protoFrom, const TJsonSettings& jsonSettings) {
+ // TODO: get rid of "copy-paste"
+ using namespace ::google::protobuf;
+ const Reflection& reflectionFrom = *protoFrom.GetReflection();
+ const Descriptor& descriptorFrom = *protoFrom.GetDescriptor();
+ bool hasAnyField = false;
+ int fieldCount = descriptorFrom.field_count();
+ for (int idxField = 0; idxField < fieldCount; ++idxField) {
+ const FieldDescriptor* fieldFrom = descriptorFrom.field(idxField);
+ auto ir = jsonSettings.FieldRemapper.find(fieldFrom);
+ if (ir != jsonSettings.FieldRemapper.end()) {
+ TStringStream remapTo;
+ ir->second(remapTo, protoFrom, jsonSettings);
+ if (remapTo.Size() > 0) {
+ if (hasAnyField) {
+ to << ',';
+ }
+ to << remapTo.Str();
+ hasAnyField = true;
+ }
+ } else {
+ if (fieldFrom->is_repeated()) {
+ if (!jsonSettings.EmptyRepeated && reflectionFrom.FieldSize(protoFrom, fieldFrom) == 0) {
+ continue;
+ }
+ } else {
+ if (!reflectionFrom.HasField(protoFrom, fieldFrom)) {
+ continue;
+ }
+ }
+ if (hasAnyField) {
+ to << ',';
+ }
+ hasAnyField = true;
+ TString name;
+ if (jsonSettings.NameGenerator) {
+ name = jsonSettings.NameGenerator(*fieldFrom);
+ } else {
+ name = fieldFrom->name();
+ }
+ to << '"' << name << "\":";
+ FieldDescriptor::CppType type = fieldFrom->cpp_type();
+ if (fieldFrom->is_repeated()) {
+ int size = reflectionFrom.FieldSize(protoFrom, fieldFrom);
+ if (fieldFrom->is_map()) {
+ const FieldDescriptor* keyDescriptor = nullptr;
+ const FieldDescriptor* valueDescriptor = nullptr;
+ FieldDescriptor::CppType keyType;
+ FieldDescriptor::CppType valueType;
+ const Reflection* itemReflection = nullptr;
+ to << '{';
+ for (int i = 0; i < size; ++i) {
+ const Message& item = reflectionFrom.GetRepeatedMessage(protoFrom, fieldFrom, i);
+ if (i == 0) {
+ itemReflection = item.GetReflection();
+ std::vector<const FieldDescriptor*> fields;
+ itemReflection->ListFields(item, &fields);
+ if (fields.size() == 2) {
+ keyDescriptor = fields[0];
+ valueDescriptor = fields[1];
+ keyType = keyDescriptor->cpp_type();
+ valueType = valueDescriptor->cpp_type();
+ } else {
+ break;
+ }
+ } else {
+ to << ',';
+ }
+ to << '"';
+ switch (keyType) {
+ case FieldDescriptor::CPPTYPE_INT32:
+ to << itemReflection->GetInt32(item, keyDescriptor);
+ break;
+ case FieldDescriptor::CPPTYPE_INT64:
+ to << itemReflection->GetInt64(item, keyDescriptor);
+ break;
+ case FieldDescriptor::CPPTYPE_UINT32:
+ to << itemReflection->GetUInt32(item, keyDescriptor);
+ break;
+ case FieldDescriptor::CPPTYPE_UINT64:
+ to << itemReflection->GetUInt64(item, keyDescriptor);
+ break;
+ case FieldDescriptor::CPPTYPE_DOUBLE:
+ {
+ double value = itemReflection->GetDouble(item, keyDescriptor);
+ if (isnan(value)) {
+ to << jsonSettings.NaN;
+ } else {
+ to << value;
+ }
+ }
+ break;
+ case FieldDescriptor::CPPTYPE_FLOAT:
+ {
+ float value = itemReflection->GetFloat(item, keyDescriptor);
+ if (isnan(value)) {
+ to << jsonSettings.NaN;
+ } else {
+ to << value;
+ }
+ }
+ break;
+ case FieldDescriptor::CPPTYPE_BOOL:
+ to << (itemReflection->GetBool(item, keyDescriptor) ? "true" : "false");
+ break;
+ case FieldDescriptor::CPPTYPE_ENUM:
+ to << itemReflection->GetEnum(item, keyDescriptor)->name();
+ break;
+ case FieldDescriptor::CPPTYPE_STRING:
+ if (fieldFrom->type() == FieldDescriptor::TYPE_BYTES) {
+ to << Base64Encode(itemReflection->GetString(item, keyDescriptor));
+ } else {
+ EscapeJsonString(to, itemReflection->GetString(item, keyDescriptor));
+ }
+ break;
+ default:
+ to << "null";
+ break;
+ }
+ to << '"';
+ to << ':';
+ switch (valueType) {
+ case FieldDescriptor::CPPTYPE_INT32:
+ to << itemReflection->GetInt32(item, valueDescriptor);
+ break;
+ case FieldDescriptor::CPPTYPE_INT64:
+ if (jsonSettings.UI64AsString) {
+ to << '"';
+ to << itemReflection->GetInt64(item, valueDescriptor);
+ to << '"';
+ } else {
+ to << itemReflection->GetInt64(item, valueDescriptor);
+ }
+ break;
+ case FieldDescriptor::CPPTYPE_UINT32:
+ to << itemReflection->GetUInt32(item, valueDescriptor);
+ break;
+ case FieldDescriptor::CPPTYPE_UINT64:
+ if (jsonSettings.UI64AsString) {
+ to << '"';
+ to << itemReflection->GetUInt64(item, valueDescriptor);
+ to << '"';
+ } else {
+ to << itemReflection->GetUInt64(item, valueDescriptor);
+ }
+ break;
+ case FieldDescriptor::CPPTYPE_DOUBLE:
+ {
+ double value = itemReflection->GetDouble(item, valueDescriptor);
+ if (isnan(value)) {
+ to << jsonSettings.NaN;
+ } else {
+ to << value;
+ }
+ }
+ break;
+ case FieldDescriptor::CPPTYPE_FLOAT:
+ {
+ float value = itemReflection->GetFloat(item, valueDescriptor);
+ if (isnan(value)) {
+ to << jsonSettings.NaN;
+ } else {
+ to << value;
+ }
+ }
+ break;
+ case FieldDescriptor::CPPTYPE_BOOL:
+ to << (itemReflection->GetBool(item, valueDescriptor) ? "true" : "false");
+ break;
+ case FieldDescriptor::CPPTYPE_ENUM:
+ ProtoToJson(to, itemReflection->GetEnum(item, valueDescriptor), jsonSettings);
+ break;
+ case FieldDescriptor::CPPTYPE_STRING:
+ to << '"';
+ if (fieldFrom->type() == FieldDescriptor::TYPE_BYTES) {
+ to << Base64Encode(itemReflection->GetString(item, valueDescriptor));
+ } else {
+ EscapeJsonString(to, itemReflection->GetString(item, valueDescriptor));
+ }
+ to << '"';
+ break;
+ case FieldDescriptor::CPPTYPE_MESSAGE:
+ ProtoToJson(to, itemReflection->GetMessage(item, valueDescriptor), jsonSettings);
+ break;
+ }
+ }
+ to << '}';
+ } else {
+ to << '[';
+ for (int i = 0; i < size; ++i) {
+ if (i != 0) {
+ to << ',';
+ }
+ switch (type) {
+ case FieldDescriptor::CPPTYPE_INT32:
+ to << reflectionFrom.GetRepeatedInt32(protoFrom, fieldFrom, i);
+ break;
+ case FieldDescriptor::CPPTYPE_INT64:
+ // JavaScript could not handle large numbers (bigger than 2^53)
+ if (jsonSettings.UI64AsString) {
+ to << '"';
+ to << reflectionFrom.GetRepeatedInt64(protoFrom, fieldFrom, i);
+ to << '"';
+ } else {
+ to << reflectionFrom.GetRepeatedInt64(protoFrom, fieldFrom, i);
+ }
+ break;
+ case FieldDescriptor::CPPTYPE_UINT32:
+ to << reflectionFrom.GetRepeatedUInt32(protoFrom, fieldFrom, i);
+ break;
+ case FieldDescriptor::CPPTYPE_UINT64:
+ if (jsonSettings.UI64AsString) {
+ to << '"';
+ to << reflectionFrom.GetRepeatedUInt64(protoFrom, fieldFrom, i);
+ to << '"';
+ } else {
+ to << reflectionFrom.GetRepeatedUInt64(protoFrom, fieldFrom, i);
+ }
+ break;
+ case FieldDescriptor::CPPTYPE_DOUBLE:
+ {
+ double value = reflectionFrom.GetRepeatedDouble(protoFrom, fieldFrom, i);
+ if (isnan(value)) {
+ to << jsonSettings.NaN;
+ } else {
+ to << value;
+ }
+ }
+ break;
+ case FieldDescriptor::CPPTYPE_FLOAT:
+ {
+ float value = reflectionFrom.GetRepeatedFloat(protoFrom, fieldFrom, i);
+ if (isnan(value)) {
+ to << jsonSettings.NaN;
+ } else {
+ to << value;
+ }
+ }
+ break;
+ case FieldDescriptor::CPPTYPE_BOOL:
+ to << (reflectionFrom.GetRepeatedBool(protoFrom, fieldFrom, i) ? "true" : "false");
+ break;
+ case FieldDescriptor::CPPTYPE_ENUM:
+ ProtoToJson(to, reflectionFrom.GetRepeatedEnum(protoFrom, fieldFrom, i), jsonSettings);
+ break;
+ case FieldDescriptor::CPPTYPE_STRING:
+ to << '"';
+ if (fieldFrom->type() == FieldDescriptor::TYPE_BYTES) {
+ to << Base64Encode(reflectionFrom.GetRepeatedString(protoFrom, fieldFrom, i));
+ } else {
+ EscapeJsonString(to, reflectionFrom.GetRepeatedString(protoFrom, fieldFrom, i));
+ }
+ to << '"';
+ break;
+ case FieldDescriptor::CPPTYPE_MESSAGE:
+ ProtoToJson(to, reflectionFrom.GetRepeatedMessage(protoFrom, fieldFrom, i), jsonSettings);
+ break;
+ }
+ }
+ to << ']';
+ }
+ } else {
+ switch (type) {
+ case FieldDescriptor::CPPTYPE_INT32:
+ to << reflectionFrom.GetInt32(protoFrom, fieldFrom);
+ break;
+ case FieldDescriptor::CPPTYPE_INT64:
+ if (jsonSettings.UI64AsString) {
+ to << '"';
+ to << reflectionFrom.GetInt64(protoFrom, fieldFrom);
+ to << '"';
+ } else {
+ to << reflectionFrom.GetInt64(protoFrom, fieldFrom);
+ }
+ break;
+ case FieldDescriptor::CPPTYPE_UINT32:
+ to << reflectionFrom.GetUInt32(protoFrom, fieldFrom);
+ break;
+ case FieldDescriptor::CPPTYPE_UINT64:
+ if (jsonSettings.UI64AsString) {
+ to << '"';
+ to << reflectionFrom.GetUInt64(protoFrom, fieldFrom);
+ to << '"';
+ } else {
+ to << reflectionFrom.GetUInt64(protoFrom, fieldFrom);
+ }
+ break;
+ case FieldDescriptor::CPPTYPE_DOUBLE:
+ {
+ double value = reflectionFrom.GetDouble(protoFrom, fieldFrom);
+ if (isnan(value)) {
+ to << jsonSettings.NaN;
+ } else {
+ to << value;
+ }
+ }
+ break;
+ case FieldDescriptor::CPPTYPE_FLOAT:
+ {
+ float value = reflectionFrom.GetFloat(protoFrom, fieldFrom);
+ if (isnan(value)) {
+ to << jsonSettings.NaN;
+ } else {
+ to << value;
+ }
+ }
+ break;
+ case FieldDescriptor::CPPTYPE_BOOL:
+ to << (reflectionFrom.GetBool(protoFrom, fieldFrom) ? "true" : "false");
+ break;
+ case FieldDescriptor::CPPTYPE_ENUM:
+ ProtoToJson(to, reflectionFrom.GetEnum(protoFrom, fieldFrom), jsonSettings);
+ break;
+ case FieldDescriptor::CPPTYPE_STRING:
+ to << '"';
+ if (fieldFrom->type() == FieldDescriptor::TYPE_BYTES) {
+ to << Base64Encode(reflectionFrom.GetString(protoFrom, fieldFrom));
+ } else {
+ EscapeJsonString(to, reflectionFrom.GetString(protoFrom, fieldFrom));
+ }
+ to << '"';
+ break;
+ case FieldDescriptor::CPPTYPE_MESSAGE:
+ ProtoToJson(to, reflectionFrom.GetMessage(protoFrom, fieldFrom), jsonSettings);
+ break;
+ }
+ }
+ }
+ }
+}
+
+void TProtoToJson::ProtoToJsonSchema(IOutputStream& to, const TJsonSettings& jsonSettings, const ::google::protobuf::Descriptor* descriptor, std::unordered_set<const ::google::protobuf::Descriptor*>& descriptors) {
+ using namespace ::google::protobuf;
+ if (descriptor == nullptr) {
+ return;
+ }
+ to << '{';
+ to << "\"type\":\"object\",";
+ to << "\"title\":\"";
+ EscapeJsonString(to, descriptor->name());
+ to << '"';
+ int fields = descriptor->field_count();
+ if (fields > 0) {
+ to << ",\"properties\":{";
+ int oneofFields = descriptor->oneof_decl_count();
+ for (int idx = 0; idx < oneofFields; ++idx) {
+ const OneofDescriptor* fieldDescriptor = descriptor->oneof_decl(idx);
+ if (idx != 0) {
+ to << ',';
+ }
+ to << '"';
+ //TString name;
+ if (jsonSettings.NameGenerator) {
+ // TODO
+ }
+ EscapeJsonString(to, fieldDescriptor->name());
+ to << "\":";
+ to << "{\"type\":\"oneOf\"}";
+ }
+ for (int idx = 0; idx < fields; ++idx) {
+ const FieldDescriptor* fieldDescriptor = descriptor->field(idx);
+ if (idx != 0 || oneofFields != 0) {
+ to << ',';
+ }
+ to << '"';
+ TString name;
+ if (jsonSettings.NameGenerator) {
+ name = jsonSettings.NameGenerator(*fieldDescriptor);
+ } else {
+ name = fieldDescriptor->name();
+ }
+ EscapeJsonString(to, name);
+ to << "\":";
+ if (fieldDescriptor->is_repeated()) {
+ to << "{\"type\":\"array\",\"items\":";
+ }
+ if (fieldDescriptor->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) {
+ if (descriptors.insert(descriptor).second) {
+ ProtoToJsonSchema(to, jsonSettings, fieldDescriptor->message_type(), descriptors);
+ } else {
+ to << "{}";
+ }
+ } else {
+ to << "{\"type\":\"";
+ switch (fieldDescriptor->cpp_type()) {
+ case FieldDescriptor::CPPTYPE_INT32:
+ case FieldDescriptor::CPPTYPE_UINT32:
+ case FieldDescriptor::CPPTYPE_ENUM:
+ to << "integer";
+ break;
+ case FieldDescriptor::CPPTYPE_STRING:
+ case FieldDescriptor::CPPTYPE_INT64:
+ case FieldDescriptor::CPPTYPE_UINT64:
+ to << "string"; // because of JS compatibility (JavaScript could not handle large numbers (bigger than 2^53))
+ break;
+ case FieldDescriptor::CPPTYPE_FLOAT:
+ case FieldDescriptor::CPPTYPE_DOUBLE:
+ to << "number";
+ break;
+ case FieldDescriptor::CPPTYPE_BOOL:
+ to << "boolean";
+ break;
+ case FieldDescriptor::CPPTYPE_MESSAGE:
+ to << "object";
+ break;
+ };
+ to << '"';
+ to << '}';
+ }
+ if (fieldDescriptor->is_repeated()) {
+ to << '}';
+ }
+ }
+ to << '}';
+ }
+ to << '}';
+}
+
+void TProtoToJson::ProtoToJsonSchema(IOutputStream& to, const TJsonSettings& jsonSettings, const ::google::protobuf::Descriptor* descriptor) {
+ std::unordered_set<const ::google::protobuf::Descriptor*> descriptors;
+ ProtoToJsonSchema(to, jsonSettings, descriptor, descriptors);
+}
diff --git a/ydb/core/viewer/json/json.h b/ydb/core/viewer/json/json.h
index 5b211e3207d..01e3b85e2d9 100644
--- a/ydb/core/viewer/json/json.h
+++ b/ydb/core/viewer/json/json.h
@@ -1,36 +1,36 @@
-#pragma once
-#include <unordered_map>
-#include <unordered_set>
+#pragma once
+#include <unordered_map>
+#include <unordered_set>
#include <google/protobuf/message.h>
#include <util/stream/output.h>
-
-struct TJsonSettings {
- using TMapperKey = const ::google::protobuf::FieldDescriptor*;
+
+struct TJsonSettings {
+ using TMapperKey = const ::google::protobuf::FieldDescriptor*;
using TMapperValue = std::function<void(IOutputStream&, const ::google::protobuf::Message&, const TJsonSettings&)>;
- using TNameGenerator = std::function<TString(const google::protobuf::FieldDescriptor&)>;
- bool UI64AsString = true; // JavaScript could not handle large numbers (bigger than 2^53)
- bool EnumAsNumbers = true;
- bool EmptyRepeated = false;
- TString NaN = "null";
- std::unordered_map<TMapperKey, TMapperValue> FieldRemapper;
- TNameGenerator NameGenerator = {};
-};
-
-class TProtoToJson {
-public:
- static void EscapeJsonString(IOutputStream& os, const TString& s);
- static TString EscapeJsonString(const TString& s);
- static void ProtoToJson(IOutputStream& to, const ::google::protobuf::Message& protoFrom, const TJsonSettings& jsonSettings = TJsonSettings());
- static void ProtoToJsonInline(IOutputStream& to, const ::google::protobuf::Message& protoFrom, const TJsonSettings& jsonSettings = TJsonSettings());
- static void ProtoToJsonSchema(IOutputStream& to, const TJsonSettings& jsonSettings, const ::google::protobuf::Descriptor* descriptor);
-
- static void ProtoToJson(IOutputStream& to, const ::google::protobuf::EnumValueDescriptor* descriptor, const TJsonSettings& jsonSettings = TJsonSettings());
-
- template <typename ProtoType>
- static void ProtoToJsonSchema(IOutputStream& to, const TJsonSettings& jsonSettings = TJsonSettings()) {
- ProtoToJsonSchema(to, jsonSettings, ProtoType::descriptor());
- }
-
-protected:
- static void ProtoToJsonSchema(IOutputStream& to, const TJsonSettings& jsonSettings, const ::google::protobuf::Descriptor* descriptor, std::unordered_set<const ::google::protobuf::Descriptor*>& descriptors);
-};
+ using TNameGenerator = std::function<TString(const google::protobuf::FieldDescriptor&)>;
+ bool UI64AsString = true; // JavaScript could not handle large numbers (bigger than 2^53)
+ bool EnumAsNumbers = true;
+ bool EmptyRepeated = false;
+ TString NaN = "null";
+ std::unordered_map<TMapperKey, TMapperValue> FieldRemapper;
+ TNameGenerator NameGenerator = {};
+};
+
+class TProtoToJson {
+public:
+ static void EscapeJsonString(IOutputStream& os, const TString& s);
+ static TString EscapeJsonString(const TString& s);
+ static void ProtoToJson(IOutputStream& to, const ::google::protobuf::Message& protoFrom, const TJsonSettings& jsonSettings = TJsonSettings());
+ static void ProtoToJsonInline(IOutputStream& to, const ::google::protobuf::Message& protoFrom, const TJsonSettings& jsonSettings = TJsonSettings());
+ static void ProtoToJsonSchema(IOutputStream& to, const TJsonSettings& jsonSettings, const ::google::protobuf::Descriptor* descriptor);
+
+ static void ProtoToJson(IOutputStream& to, const ::google::protobuf::EnumValueDescriptor* descriptor, const TJsonSettings& jsonSettings = TJsonSettings());
+
+ template <typename ProtoType>
+ static void ProtoToJsonSchema(IOutputStream& to, const TJsonSettings& jsonSettings = TJsonSettings()) {
+ ProtoToJsonSchema(to, jsonSettings, ProtoType::descriptor());
+ }
+
+protected:
+ static void ProtoToJsonSchema(IOutputStream& to, const TJsonSettings& jsonSettings, const ::google::protobuf::Descriptor* descriptor, std::unordered_set<const ::google::protobuf::Descriptor*>& descriptors);
+};
diff --git a/ydb/core/viewer/json/json_ut.cpp b/ydb/core/viewer/json/json_ut.cpp
index a479ea94e60..fa3825bcaf3 100644
--- a/ydb/core/viewer/json/json_ut.cpp
+++ b/ydb/core/viewer/json/json_ut.cpp
@@ -1,47 +1,47 @@
#include <library/cpp/testing/unittest/registar.h>
#include <library/cpp/testing/unittest/tests_data.h>
-#include "json.h"
+#include "json.h"
#include <ydb/core/viewer/protos/viewer.pb.h>
-
-Y_UNIT_TEST_SUITE(Json) {
- Y_UNIT_TEST(BasicRendering) {
- NKikimrViewer::TMetaTableInfo protoMessage;
- TJsonSettings settings;
- {
- TStringStream stream;
- TProtoToJson::ProtoToJson(stream, protoMessage, settings);
- UNIT_ASSERT_VALUES_EQUAL(stream.Str(), "{}");
- }
- protoMessage.SetTaskId("taskId");
- protoMessage.SetUnique(true);
- protoMessage.SetMaxRecords(1234);
- protoMessage.SetMinTimestamp(1234);
- protoMessage.AddSrcTables("table1");
- protoMessage.AddSrcTables("table2");
- protoMessage.MutableSchema()->Add()->SetName("name1");
- protoMessage.MutableSchema()->Add()->SetName("name2");
- {
- TStringStream stream;
- TProtoToJson::ProtoToJson(stream, protoMessage, settings);
- UNIT_ASSERT_VALUES_EQUAL(stream.Str(), "{\"Schema\":[{\"Name\":\"name1\"},{\"Name\":\"name2\"}],\"MinTimestamp\":\"1234\",\"MaxRecords\":1234,\"Unique\":true,\"TaskId\":\"taskId\",\"SrcTables\":[\"table1\",\"table2\"]}");
- }
- settings.UI64AsString = false;
- {
- TStringStream stream;
- TProtoToJson::ProtoToJson(stream, protoMessage, settings);
- UNIT_ASSERT_VALUES_EQUAL(stream.Str(), "{\"Schema\":[{\"Name\":\"name1\"},{\"Name\":\"name2\"}],\"MinTimestamp\":1234,\"MaxRecords\":1234,\"Unique\":true,\"TaskId\":\"taskId\",\"SrcTables\":[\"table1\",\"table2\"]}");
- }
- protoMessage.ClearSrcTables();
- {
- TStringStream stream;
- TProtoToJson::ProtoToJson(stream, protoMessage, settings);
- UNIT_ASSERT_VALUES_EQUAL(stream.Str(), "{\"Schema\":[{\"Name\":\"name1\"},{\"Name\":\"name2\"}],\"MinTimestamp\":1234,\"MaxRecords\":1234,\"Unique\":true,\"TaskId\":\"taskId\"}");
- }
- settings.EmptyRepeated = true;
- {
- TStringStream stream;
- TProtoToJson::ProtoToJson(stream, protoMessage, settings);
- UNIT_ASSERT_VALUES_EQUAL(stream.Str(), "{\"Schema\":[{\"Name\":\"name1\"},{\"Name\":\"name2\"}],\"MinTimestamp\":1234,\"MaxRecords\":1234,\"Unique\":true,\"TaskId\":\"taskId\",\"Attrs\":{},\"SrcTables\":[]}");
- }
- }
-}
+
+Y_UNIT_TEST_SUITE(Json) {
+ Y_UNIT_TEST(BasicRendering) {
+ NKikimrViewer::TMetaTableInfo protoMessage;
+ TJsonSettings settings;
+ {
+ TStringStream stream;
+ TProtoToJson::ProtoToJson(stream, protoMessage, settings);
+ UNIT_ASSERT_VALUES_EQUAL(stream.Str(), "{}");
+ }
+ protoMessage.SetTaskId("taskId");
+ protoMessage.SetUnique(true);
+ protoMessage.SetMaxRecords(1234);
+ protoMessage.SetMinTimestamp(1234);
+ protoMessage.AddSrcTables("table1");
+ protoMessage.AddSrcTables("table2");
+ protoMessage.MutableSchema()->Add()->SetName("name1");
+ protoMessage.MutableSchema()->Add()->SetName("name2");
+ {
+ TStringStream stream;
+ TProtoToJson::ProtoToJson(stream, protoMessage, settings);
+ UNIT_ASSERT_VALUES_EQUAL(stream.Str(), "{\"Schema\":[{\"Name\":\"name1\"},{\"Name\":\"name2\"}],\"MinTimestamp\":\"1234\",\"MaxRecords\":1234,\"Unique\":true,\"TaskId\":\"taskId\",\"SrcTables\":[\"table1\",\"table2\"]}");
+ }
+ settings.UI64AsString = false;
+ {
+ TStringStream stream;
+ TProtoToJson::ProtoToJson(stream, protoMessage, settings);
+ UNIT_ASSERT_VALUES_EQUAL(stream.Str(), "{\"Schema\":[{\"Name\":\"name1\"},{\"Name\":\"name2\"}],\"MinTimestamp\":1234,\"MaxRecords\":1234,\"Unique\":true,\"TaskId\":\"taskId\",\"SrcTables\":[\"table1\",\"table2\"]}");
+ }
+ protoMessage.ClearSrcTables();
+ {
+ TStringStream stream;
+ TProtoToJson::ProtoToJson(stream, protoMessage, settings);
+ UNIT_ASSERT_VALUES_EQUAL(stream.Str(), "{\"Schema\":[{\"Name\":\"name1\"},{\"Name\":\"name2\"}],\"MinTimestamp\":1234,\"MaxRecords\":1234,\"Unique\":true,\"TaskId\":\"taskId\"}");
+ }
+ settings.EmptyRepeated = true;
+ {
+ TStringStream stream;
+ TProtoToJson::ProtoToJson(stream, protoMessage, settings);
+ UNIT_ASSERT_VALUES_EQUAL(stream.Str(), "{\"Schema\":[{\"Name\":\"name1\"},{\"Name\":\"name2\"}],\"MinTimestamp\":1234,\"MaxRecords\":1234,\"Unique\":true,\"TaskId\":\"taskId\",\"Attrs\":{},\"SrcTables\":[]}");
+ }
+ }
+}
diff --git a/ydb/core/viewer/json/ut/ya.make b/ydb/core/viewer/json/ut/ya.make
index 8c917423818..4aab7bbdd87 100644
--- a/ydb/core/viewer/json/ut/ya.make
+++ b/ydb/core/viewer/json/ut/ya.make
@@ -1,16 +1,16 @@
UNITTEST_FOR(ydb/core/viewer/json)
-
+
OWNER(
xenoxeno
g:kikimr
)
-
-PEERDIR(
+
+PEERDIR(
ydb/core/viewer/protos
-)
-
-SRCS(
- json_ut.cpp
-)
-
-END()
+)
+
+SRCS(
+ json_ut.cpp
+)
+
+END()
diff --git a/ydb/core/viewer/json/ya.make b/ydb/core/viewer/json/ya.make
index e4807fa53c6..d09b3d19545 100644
--- a/ydb/core/viewer/json/ya.make
+++ b/ydb/core/viewer/json/ya.make
@@ -1,23 +1,23 @@
RECURSE_FOR_TESTS(
ut
)
-
-LIBRARY()
-
-OWNER(
- xenoxeno
- g:kikimr
-)
-
-SRCS(
- json.cpp
- json.h
-)
-
-PEERDIR(
- contrib/libs/protobuf
+
+LIBRARY()
+
+OWNER(
+ xenoxeno
+ g:kikimr
+)
+
+SRCS(
+ json.cpp
+ json.h
+)
+
+PEERDIR(
+ contrib/libs/protobuf
library/cpp/string_utils/base64
ydb/core/viewer/protos
-)
-
-END()
+)
+
+END()
diff --git a/ydb/core/viewer/json_browse.h b/ydb/core/viewer/json_browse.h
index 109810072af..cba672826ee 100644
--- a/ydb/core/viewer/json_browse.h
+++ b/ydb/core/viewer/json_browse.h
@@ -1,4 +1,4 @@
-#pragma once
+#pragma once
#include <library/cpp/actors/core/actor_bootstrapped.h>
#include <library/cpp/actors/core/mon.h>
#include <ydb/core/base/tablet.h>
@@ -7,244 +7,244 @@
#include <ydb/core/tx/schemeshard/schemeshard.h>
#include <ydb/core/tx/tx_proxy/proxy.h>
#include <ydb/core/viewer/protos/viewer.pb.h>
-#include "browse.h"
-#include "browse_db.h"
-#include "browse_pq.h"
+#include "browse.h"
+#include "browse_db.h"
+#include "browse_pq.h"
#include <ydb/core/viewer/json/json.h>
-#include "viewer.h"
-#include "wb_aggregate.h"
-
-namespace std {
-
-template <>
+#include "viewer.h"
+#include "wb_aggregate.h"
+
+namespace std {
+
+template <>
struct hash<NActors::TActorId> {
size_t operator ()(const NActors::TActorId& actorId) const {
return actorId.Hash();
}
};
-
-}
-
-namespace NKikimr {
-namespace NViewer {
-
-using namespace NActors;
-
-class TJsonBrowse : public TActorBootstrapped<TJsonBrowse> {
- using TBase = TActorBootstrapped<TJsonBrowse>;
- IViewer* Viewer;
- NMon::TEvHttpInfo::TPtr Event;
- TJsonSettings JsonSettings;
+
+}
+
+namespace NKikimr {
+namespace NViewer {
+
+using namespace NActors;
+
+class TJsonBrowse : public TActorBootstrapped<TJsonBrowse> {
+ using TBase = TActorBootstrapped<TJsonBrowse>;
+ IViewer* Viewer;
+ NMon::TEvHttpInfo::TPtr Event;
+ TJsonSettings JsonSettings;
ui32 Timeout = 0;
bool Recursive = false;
-
- struct TPathStateInfo {
- TString Name;
- TString Path;
+
+ struct TPathStateInfo {
+ TString Name;
+ TString Path;
TActorId BrowseActorId;
- NKikimrViewer::TBrowseInfo BrowseInfo;
-
+ NKikimrViewer::TBrowseInfo BrowseInfo;
+
TPathStateInfo(const TString& name, const TString& path, const TActorId& browseActorId)
- : Name(name)
- , Path(path)
- , BrowseActorId(browseActorId)
- {}
-
- operator const TString&() const {
- return Path;
- }
+ : Name(name)
+ , Path(path)
+ , BrowseActorId(browseActorId)
+ {}
+
+ operator const TString&() const {
+ return Path;
+ }
bool operator== (const TString& otherPath) const {
return Path == otherPath;
}
- };
-
+ };
+
TVector<TPathStateInfo> Paths;
-
+
using TBrowseRequestKey = std::tuple<TActorId, TTabletId, ui32>;
- std::unordered_multiset<TBrowseRequestKey> BrowseRequestsInFlight;
- ui32 Responses = 0;
-
-public:
+ std::unordered_multiset<TBrowseRequestKey> BrowseRequestsInFlight;
+ ui32 Responses = 0;
+
+public:
static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
return NKikimrServices::TActivity::VIEWER_HANDLER;
- }
-
- TJsonBrowse(IViewer *viewer, NMon::TEvHttpInfo::TPtr &ev)
- : Viewer(viewer)
- , Event(ev)
- {}
-
- void ParsePath(const TString& path, const TActorContext& ctx) {
- size_t prevpos = 0;
- size_t pos = 0;
- size_t len = path.size();
- while (pos < len) {
- if (path[pos] == '/') {
- TString n = path.substr(prevpos, pos - prevpos);
- TString p = path.substr(0, pos);
- if (n.empty() && p.empty()) {
- n = p = "/";
- }
+ }
+
+ TJsonBrowse(IViewer *viewer, NMon::TEvHttpInfo::TPtr &ev)
+ : Viewer(viewer)
+ , Event(ev)
+ {}
+
+ void ParsePath(const TString& path, const TActorContext& ctx) {
+ size_t prevpos = 0;
+ size_t pos = 0;
+ size_t len = path.size();
+ while (pos < len) {
+ if (path[pos] == '/') {
+ TString n = path.substr(prevpos, pos - prevpos);
+ TString p = path.substr(0, pos);
+ if (n.empty() && p.empty()) {
+ n = p = "/";
+ }
Paths.emplace_back(n, p, ctx.RegisterWithSameMailbox(new TBrowse(Viewer, ctx.SelfID, p, Event->Get()->UserToken)));
- ++pos;
- prevpos = pos;
- } else {
- ++pos;
- }
- }
- if (pos != prevpos) {
- TString n = path.substr(prevpos, pos - prevpos);
- TString p = path.substr(0, pos);
+ ++pos;
+ prevpos = pos;
+ } else {
+ ++pos;
+ }
+ }
+ if (pos != prevpos) {
+ TString n = path.substr(prevpos, pos - prevpos);
+ TString p = path.substr(0, pos);
Paths.emplace_back(n, p, ctx.RegisterWithSameMailbox(new TBrowse(Viewer, ctx.SelfID, p, Event->Get()->UserToken)));
- }
- }
-
- void Bootstrap(const TActorContext& ctx) {
+ }
+ }
+
+ void Bootstrap(const TActorContext& ctx) {
const auto& params(Event->Get()->Request.GetParams());
- JsonSettings.EnumAsNumbers = !FromStringWithDefault<bool>(params.Get("enums"), true);
- JsonSettings.UI64AsString = !FromStringWithDefault<bool>(params.Get("ui64"), false);
- Timeout = FromStringWithDefault<ui32>(params.Get("timeout"), 10000);
- Recursive = FromStringWithDefault(params.Get("recursive"), false);
- TString path = params.Get("path");
- if (Recursive) {
- ParsePath(path, ctx);
- } else {
+ JsonSettings.EnumAsNumbers = !FromStringWithDefault<bool>(params.Get("enums"), true);
+ JsonSettings.UI64AsString = !FromStringWithDefault<bool>(params.Get("ui64"), false);
+ Timeout = FromStringWithDefault<ui32>(params.Get("timeout"), 10000);
+ Recursive = FromStringWithDefault(params.Get("recursive"), false);
+ TString path = params.Get("path");
+ if (Recursive) {
+ ParsePath(path, ctx);
+ } else {
Paths.emplace_back(path, path, ctx.RegisterWithSameMailbox(new TBrowse(Viewer, ctx.SelfID, path, Event->Get()->UserToken)));
- }
- Become(&TThis::StateWait, ctx, TDuration::MilliSeconds(Timeout), new TEvents::TEvWakeup());
- }
-
- STFUNC(StateWait) {
- switch (ev->GetTypeRewrite()) {
+ }
+ Become(&TThis::StateWait, ctx, TDuration::MilliSeconds(Timeout), new TEvents::TEvWakeup());
+ }
+
+ STFUNC(StateWait) {
+ switch (ev->GetTypeRewrite()) {
HFunc(NViewerEvents::TEvBrowseResponse, Handle);
- HFunc(NViewerEvents::TEvBrowseRequestSent, Handle);
- HFunc(NViewerEvents::TEvBrowseRequestCompleted, Handle);
- HFunc(NMon::TEvHttpInfoRes, Handle);
- CFunc(TEvents::TSystem::Wakeup, HandleTimeout);
- }
- }
-
+ HFunc(NViewerEvents::TEvBrowseRequestSent, Handle);
+ HFunc(NViewerEvents::TEvBrowseRequestCompleted, Handle);
+ HFunc(NMon::TEvHttpInfoRes, Handle);
+ CFunc(TEvents::TSystem::Wakeup, HandleTimeout);
+ }
+ }
+
void Handle(NViewerEvents::TEvBrowseResponse::TPtr &ev, const TActorContext &ctx) {
NViewerEvents::TEvBrowseResponse& event(*ev->Get());
- if (!event.Error.empty()) {
- ctx.Send(Event->Sender, new NMon::TEvHttpInfoRes(event.Error, 0, NMon::IEvHttpInfoRes::EContentType::Custom));
- return Die(ctx);
- }
- auto it = std::find(Paths.begin(), Paths.end(), event.BrowseInfo.GetPath());
- if (it != Paths.end()) {
- it->BrowseInfo.MergeFrom(event.BrowseInfo);
+ if (!event.Error.empty()) {
+ ctx.Send(Event->Sender, new NMon::TEvHttpInfoRes(event.Error, 0, NMon::IEvHttpInfoRes::EContentType::Custom));
+ return Die(ctx);
+ }
+ auto it = std::find(Paths.begin(), Paths.end(), event.BrowseInfo.GetPath());
+ if (it != Paths.end()) {
+ it->BrowseInfo.MergeFrom(event.BrowseInfo);
it->BrowseActorId = TActorId();
- }
- // TODO: error handling?
- ++Responses;
- if (Responses == Paths.size()) {
- ReplyAndDie(ctx);
- }
- }
-
- void Handle(NViewerEvents::TEvBrowseRequestSent::TPtr& ev, const TActorContext&) {
- NViewerEvents::TEvBrowseRequestSent& event(*ev->Get());
- BrowseRequestsInFlight.emplace(event.Actor, event.Tablet, event.Event);
- }
-
- void Handle(NViewerEvents::TEvBrowseRequestCompleted::TPtr& ev, const TActorContext&) {
- NViewerEvents::TEvBrowseRequestCompleted& event(*ev->Get());
- auto it = BrowseRequestsInFlight.find({event.Actor, event.Tablet, event.Event});
- if (it != BrowseRequestsInFlight.end()) {
- // we could not delete by key, it could be many items with the same key
- BrowseRequestsInFlight.erase(it);
- }
- BrowseRequestsInFlight.emplace(event.Actor, event.Tablet, event.Event);
- }
-
- void Handle(NMon::TEvHttpInfoRes::TPtr &ev, const TActorContext &ctx) {
- ctx.ExecutorThread.Send(ev->Forward(Event->Sender));
- Die(ctx);
- }
-
- void ReplyAndDie(const TActorContext &ctx) {
- TStringStream json;
- if (!Paths.empty()) {
- NKikimrViewer::TBrowseInfo browseInfo;
- auto pi = Paths.begin();
- browseInfo.MergeFrom(pi->BrowseInfo);
- if (Recursive) {
- browseInfo.SetPath(Paths.back().BrowseInfo.GetPath());
- browseInfo.SetName("/");
- }
- NKikimrViewer::TBrowseInfo* pBrowseInfo = &browseInfo;
- ++pi;
- while (pi != Paths.end()) {
- TString name = pi->Name;
- for (NKikimrViewer::TBrowseInfo& child : *pBrowseInfo->MutableChildren()) {
- if (child.GetName() == name) {
- pBrowseInfo = &child;
- pBrowseInfo->MergeFrom(pi->BrowseInfo);
- pBrowseInfo->ClearPath();
- break;
- }
- }
- ++pi;
- }
- TProtoToJson::ProtoToJson(json, browseInfo, JsonSettings);
- }
- ctx.Send(Event->Sender, new NMon::TEvHttpInfoRes(Viewer->GetHTTPOKJSON() + json.Str(), 0, NMon::IEvHttpInfoRes::EContentType::Custom));
- Die(ctx);
- }
-
- void HandleTimeout(const TActorContext &ctx) {
- for (auto& pathInfo : Paths) {
- if (pathInfo.BrowseActorId) {
- ctx.Send(pathInfo.BrowseActorId, new TEvents::TEvPoisonPill());
- }
- }
- TStringStream result;
- result << Viewer->GetHTTPGATEWAYTIMEOUT();
- RenderPendingRequests(result);
- ctx.Send(Event->Sender, new NMon::TEvHttpInfoRes(result.Str(), 0, NMon::IEvHttpInfoRes::EContentType::Custom));
- Die(ctx);
- }
-
- void RenderPendingRequests(IOutputStream& html) {
- for (const auto& request : BrowseRequestsInFlight) {
- html << request << Endl;
- }
- }
-};
-
-template <>
-struct TJsonRequestSchema<TJsonBrowse> {
+ }
+ // TODO: error handling?
+ ++Responses;
+ if (Responses == Paths.size()) {
+ ReplyAndDie(ctx);
+ }
+ }
+
+ void Handle(NViewerEvents::TEvBrowseRequestSent::TPtr& ev, const TActorContext&) {
+ NViewerEvents::TEvBrowseRequestSent& event(*ev->Get());
+ BrowseRequestsInFlight.emplace(event.Actor, event.Tablet, event.Event);
+ }
+
+ void Handle(NViewerEvents::TEvBrowseRequestCompleted::TPtr& ev, const TActorContext&) {
+ NViewerEvents::TEvBrowseRequestCompleted& event(*ev->Get());
+ auto it = BrowseRequestsInFlight.find({event.Actor, event.Tablet, event.Event});
+ if (it != BrowseRequestsInFlight.end()) {
+ // we could not delete by key, it could be many items with the same key
+ BrowseRequestsInFlight.erase(it);
+ }
+ BrowseRequestsInFlight.emplace(event.Actor, event.Tablet, event.Event);
+ }
+
+ void Handle(NMon::TEvHttpInfoRes::TPtr &ev, const TActorContext &ctx) {
+ ctx.ExecutorThread.Send(ev->Forward(Event->Sender));
+ Die(ctx);
+ }
+
+ void ReplyAndDie(const TActorContext &ctx) {
+ TStringStream json;
+ if (!Paths.empty()) {
+ NKikimrViewer::TBrowseInfo browseInfo;
+ auto pi = Paths.begin();
+ browseInfo.MergeFrom(pi->BrowseInfo);
+ if (Recursive) {
+ browseInfo.SetPath(Paths.back().BrowseInfo.GetPath());
+ browseInfo.SetName("/");
+ }
+ NKikimrViewer::TBrowseInfo* pBrowseInfo = &browseInfo;
+ ++pi;
+ while (pi != Paths.end()) {
+ TString name = pi->Name;
+ for (NKikimrViewer::TBrowseInfo& child : *pBrowseInfo->MutableChildren()) {
+ if (child.GetName() == name) {
+ pBrowseInfo = &child;
+ pBrowseInfo->MergeFrom(pi->BrowseInfo);
+ pBrowseInfo->ClearPath();
+ break;
+ }
+ }
+ ++pi;
+ }
+ TProtoToJson::ProtoToJson(json, browseInfo, JsonSettings);
+ }
+ ctx.Send(Event->Sender, new NMon::TEvHttpInfoRes(Viewer->GetHTTPOKJSON() + json.Str(), 0, NMon::IEvHttpInfoRes::EContentType::Custom));
+ Die(ctx);
+ }
+
+ void HandleTimeout(const TActorContext &ctx) {
+ for (auto& pathInfo : Paths) {
+ if (pathInfo.BrowseActorId) {
+ ctx.Send(pathInfo.BrowseActorId, new TEvents::TEvPoisonPill());
+ }
+ }
+ TStringStream result;
+ result << Viewer->GetHTTPGATEWAYTIMEOUT();
+ RenderPendingRequests(result);
+ ctx.Send(Event->Sender, new NMon::TEvHttpInfoRes(result.Str(), 0, NMon::IEvHttpInfoRes::EContentType::Custom));
+ Die(ctx);
+ }
+
+ void RenderPendingRequests(IOutputStream& html) {
+ for (const auto& request : BrowseRequestsInFlight) {
+ html << request << Endl;
+ }
+ }
+};
+
+template <>
+struct TJsonRequestSchema<TJsonBrowse> {
static TString GetSchema() {
- TStringStream stream;
- TProtoToJson::ProtoToJsonSchema<NKikimrViewer::TBrowseInfo>(stream);
- return stream.Str();
- }
-};
-
-template <>
-struct TJsonRequestParameters<TJsonBrowse> {
+ TStringStream stream;
+ TProtoToJson::ProtoToJsonSchema<NKikimrViewer::TBrowseInfo>(stream);
+ return stream.Str();
+ }
+};
+
+template <>
+struct TJsonRequestParameters<TJsonBrowse> {
static TString GetParameters() {
- return R"___([{"name":"path","in":"query","description":"schema path","required":true,"type":"string"},
- {"name":"enums","in":"query","description":"convert enums to strings","required":false,"type":"boolean"},
- {"name":"ui64","in":"query","description":"return ui64 as number","required":false,"type":"boolean"},
- {"name":"timeout","in":"query","description":"timeout in ms","required":false,"type":"integer"}])___";
- }
-};
-
-template <>
-struct TJsonRequestSummary<TJsonBrowse> {
+ return R"___([{"name":"path","in":"query","description":"schema path","required":true,"type":"string"},
+ {"name":"enums","in":"query","description":"convert enums to strings","required":false,"type":"boolean"},
+ {"name":"ui64","in":"query","description":"return ui64 as number","required":false,"type":"boolean"},
+ {"name":"timeout","in":"query","description":"timeout in ms","required":false,"type":"integer"}])___";
+ }
+};
+
+template <>
+struct TJsonRequestSummary<TJsonBrowse> {
static TString GetSummary() {
- return "\"Schema information\"";
- }
-};
-
-template <>
-struct TJsonRequestDescription<TJsonBrowse> {
+ return "\"Schema information\"";
+ }
+};
+
+template <>
+struct TJsonRequestDescription<TJsonBrowse> {
static TString GetDescription() {
- return "\"Returns brief information about schema object\"";
- }
-};
-
-}
-}
+ return "\"Returns brief information about schema object\"";
+ }
+};
+
+}
+}
diff --git a/ydb/core/viewer/json_bscontrollerinfo.h b/ydb/core/viewer/json_bscontrollerinfo.h
index d5c43561465..5df47ed5531 100644
--- a/ydb/core/viewer/json_bscontrollerinfo.h
+++ b/ydb/core/viewer/json_bscontrollerinfo.h
@@ -1,109 +1,109 @@
-#pragma once
+#pragma once
#include <library/cpp/actors/core/actor_bootstrapped.h>
#include <library/cpp/actors/core/interconnect.h>
#include <library/cpp/actors/core/mon.h>
#include <ydb/core/blobstorage/base/blobstorage_events.h>
#include <ydb/core/base/tablet_pipe.h>
#include <ydb/core/protos/services.pb.h>
-#include "viewer.h"
-#include "json_pipe_req.h"
+#include "viewer.h"
+#include "json_pipe_req.h"
#include <ydb/core/viewer/json/json.h>
-
-namespace NKikimr {
-namespace NViewer {
-
-using namespace NActors;
-
-class TJsonBSControllerInfo : public TViewerPipeClient<TJsonBSControllerInfo> {
- using TBase = TViewerPipeClient<TJsonBSControllerInfo>;
- IViewer* Viewer;
- NMon::TEvHttpInfo::TPtr Event;
- TAutoPtr<TEvBlobStorage::TEvResponseControllerInfo> ControllerInfo;
- TJsonSettings JsonSettings;
+
+namespace NKikimr {
+namespace NViewer {
+
+using namespace NActors;
+
+class TJsonBSControllerInfo : public TViewerPipeClient<TJsonBSControllerInfo> {
+ using TBase = TViewerPipeClient<TJsonBSControllerInfo>;
+ IViewer* Viewer;
+ NMon::TEvHttpInfo::TPtr Event;
+ TAutoPtr<TEvBlobStorage::TEvResponseControllerInfo> ControllerInfo;
+ TJsonSettings JsonSettings;
ui32 Timeout = 0;
-
-public:
+
+public:
static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
return NKikimrServices::TActivity::VIEWER_HANDLER;
- }
-
- TJsonBSControllerInfo(IViewer* viewer, NMon::TEvHttpInfo::TPtr &ev)
- : Viewer(viewer)
- , Event(ev)
- {}
-
- void Bootstrap(const TActorContext& ctx) {
+ }
+
+ TJsonBSControllerInfo(IViewer* viewer, NMon::TEvHttpInfo::TPtr &ev)
+ : Viewer(viewer)
+ , Event(ev)
+ {}
+
+ void Bootstrap(const TActorContext& ctx) {
const auto& params(Event->Get()->Request.GetParams());
- JsonSettings.EnumAsNumbers = !FromStringWithDefault<bool>(params.Get("enums"), false);
- JsonSettings.UI64AsString = !FromStringWithDefault<bool>(params.Get("ui64"), false);
- Timeout = FromStringWithDefault<ui32>(params.Get("timeout"), 10000);
- InitConfig(params);
- RequestBSControllerInfo();
- Become(&TThis::StateRequestedInfo, ctx, TDuration::MilliSeconds(Timeout), new TEvents::TEvWakeup());
- }
-
- STATEFN(StateRequestedInfo) {
- switch (ev->GetTypeRewrite()) {
- hFunc(TEvBlobStorage::TEvResponseControllerInfo, Handle);
- hFunc(TEvTabletPipe::TEvClientConnected, TBase::Handle);
- cFunc(TEvents::TSystem::Wakeup, HandleTimeout);
- }
- }
-
- void Handle(TEvBlobStorage::TEvResponseControllerInfo::TPtr& ev) {
- ControllerInfo = ev->Release();
- RequestDone();
- }
-
- void ReplyAndPassAway() {
- TStringStream json;
- if (ControllerInfo != nullptr) {
- TProtoToJson::ProtoToJson(json, ControllerInfo->Record);
- } else {
- json << "null";
- }
- Send(Event->Sender, new NMon::TEvHttpInfoRes(Viewer->GetHTTPOKJSON() + json.Str(), 0, NMon::IEvHttpInfoRes::EContentType::Custom));
- PassAway();
- }
-
- void HandleTimeout() {
- Send(Event->Sender, new NMon::TEvHttpInfoRes(Viewer->GetHTTPGATEWAYTIMEOUT(), 0, NMon::IEvHttpInfoRes::EContentType::Custom));
- PassAway();
- }
-};
-
-template <>
-struct TJsonRequestSchema<TJsonBSControllerInfo> {
+ JsonSettings.EnumAsNumbers = !FromStringWithDefault<bool>(params.Get("enums"), false);
+ JsonSettings.UI64AsString = !FromStringWithDefault<bool>(params.Get("ui64"), false);
+ Timeout = FromStringWithDefault<ui32>(params.Get("timeout"), 10000);
+ InitConfig(params);
+ RequestBSControllerInfo();
+ Become(&TThis::StateRequestedInfo, ctx, TDuration::MilliSeconds(Timeout), new TEvents::TEvWakeup());
+ }
+
+ STATEFN(StateRequestedInfo) {
+ switch (ev->GetTypeRewrite()) {
+ hFunc(TEvBlobStorage::TEvResponseControllerInfo, Handle);
+ hFunc(TEvTabletPipe::TEvClientConnected, TBase::Handle);
+ cFunc(TEvents::TSystem::Wakeup, HandleTimeout);
+ }
+ }
+
+ void Handle(TEvBlobStorage::TEvResponseControllerInfo::TPtr& ev) {
+ ControllerInfo = ev->Release();
+ RequestDone();
+ }
+
+ void ReplyAndPassAway() {
+ TStringStream json;
+ if (ControllerInfo != nullptr) {
+ TProtoToJson::ProtoToJson(json, ControllerInfo->Record);
+ } else {
+ json << "null";
+ }
+ Send(Event->Sender, new NMon::TEvHttpInfoRes(Viewer->GetHTTPOKJSON() + json.Str(), 0, NMon::IEvHttpInfoRes::EContentType::Custom));
+ PassAway();
+ }
+
+ void HandleTimeout() {
+ Send(Event->Sender, new NMon::TEvHttpInfoRes(Viewer->GetHTTPGATEWAYTIMEOUT(), 0, NMon::IEvHttpInfoRes::EContentType::Custom));
+ PassAway();
+ }
+};
+
+template <>
+struct TJsonRequestSchema<TJsonBSControllerInfo> {
static TString GetSchema() {
- TStringStream stream;
- TProtoToJson::ProtoToJsonSchema<TEvBlobStorage::TEvResponseControllerInfo::ProtoRecordType>(stream);
- return stream.Str();
- }
-};
-
-template <>
-struct TJsonRequestParameters<TJsonBSControllerInfo> {
+ TStringStream stream;
+ TProtoToJson::ProtoToJsonSchema<TEvBlobStorage::TEvResponseControllerInfo::ProtoRecordType>(stream);
+ return stream.Str();
+ }
+};
+
+template <>
+struct TJsonRequestParameters<TJsonBSControllerInfo> {
static TString GetParameters() {
- return R"___([{"name":"controller_id","in":"query","description":"storage controller identifier (tablet id)","required":true,"type":"string"},
- {"name":"enums","in":"query","description":"convert enums to strings","required":false,"type":"boolean"},
- {"name":"ui64","in":"query","description":"return ui64 as number","required":false,"type":"boolean"},
- {"name":"timeout","in":"query","description":"timeout in ms","required":false,"type":"integer"}])___";
- }
-};
-
-template <>
-struct TJsonRequestSummary<TJsonBSControllerInfo> {
+ return R"___([{"name":"controller_id","in":"query","description":"storage controller identifier (tablet id)","required":true,"type":"string"},
+ {"name":"enums","in":"query","description":"convert enums to strings","required":false,"type":"boolean"},
+ {"name":"ui64","in":"query","description":"return ui64 as number","required":false,"type":"boolean"},
+ {"name":"timeout","in":"query","description":"timeout in ms","required":false,"type":"integer"}])___";
+ }
+};
+
+template <>
+struct TJsonRequestSummary<TJsonBSControllerInfo> {
static TString GetSummary() {
- return "\"Storage controller information\"";
- }
-};
-
-template <>
-struct TJsonRequestDescription<TJsonBSControllerInfo> {
+ return "\"Storage controller information\"";
+ }
+};
+
+template <>
+struct TJsonRequestDescription<TJsonBSControllerInfo> {
static TString GetDescription() {
- return "\"Returns information about storage controller\"";
- }
-};
-
-}
-}
+ return "\"Returns information about storage controller\"";
+ }
+};
+
+}
+}
diff --git a/ydb/core/viewer/json_bsgroupinfo.h b/ydb/core/viewer/json_bsgroupinfo.h
index b69b3639724..7a95f443b7c 100644
--- a/ydb/core/viewer/json_bsgroupinfo.h
+++ b/ydb/core/viewer/json_bsgroupinfo.h
@@ -1,72 +1,72 @@
-#pragma once
+#pragma once
#include <library/cpp/actors/core/actor_bootstrapped.h>
#include <library/cpp/actors/core/interconnect.h>
#include <library/cpp/actors/core/mon.h>
#include <ydb/core/protos/services.pb.h>
#include <ydb/core/node_whiteboard/node_whiteboard.h>
-#include "wb_merge.h"
-#include "json_wb_req.h"
-
-namespace NKikimr {
-namespace NViewer {
-
-template <>
-struct TWhiteboardInfo<TEvWhiteboard::TEvBSGroupStateResponse> {
- using TResponseType = TEvWhiteboard::TEvBSGroupStateResponse;
- using TElementType = NKikimrWhiteboard::TBSGroupStateInfo;
- using TElementKeyType = ui32;
-
- static constexpr bool StaticNodesOnly = true;
-
- static ::google::protobuf::RepeatedPtrField<TElementType>* GetElementsField(TResponseType* response) {
- return response->Record.MutableBSGroupStateInfo();
- }
-
- static ui32 GetElementKey(const TElementType& type) {
- return type.GetGroupID();
- }
-
- static TString GetDefaultMergeField() {
- return "GroupID";
- }
-
- static void InitMerger() {
- const auto* field = NKikimrWhiteboard::TBSGroupStateInfo::descriptor()->FindFieldByName("Latency");
- TWhiteboardMergerBase::FieldMerger[field] = &TWhiteboardMergerBase::ProtoMaximizeEnumField;
- }
-
- static THolder<TResponseType> MergeResponses(TMap<ui32, THolder<TResponseType>>& responses, const TString& fields = GetDefaultMergeField()) {
- if (fields == GetDefaultMergeField()) {
- return TWhiteboardMerger<TResponseType>::MergeResponsesElementKey(responses);
- } else {
- return TWhiteboardMerger<TResponseType>::MergeResponses(responses, fields);
- }
- }
-};
-
-template <>
-struct TWhiteboardMergerComparator<NKikimrWhiteboard::TBSGroupStateInfo> {
- bool operator ()(const NKikimrWhiteboard::TBSGroupStateInfo& a, const NKikimrWhiteboard::TBSGroupStateInfo& b) const {
- return std::make_tuple(a.GetGroupGeneration(), a.VDiskIdsSize(), a.GetChangeTime())
- < std::make_tuple(b.GetGroupGeneration(), b.VDiskIdsSize(), b.GetChangeTime());
- }
-};
-
-using TJsonBSGroupInfo = TJsonWhiteboardRequest<TEvWhiteboard::TEvBSGroupStateRequest, TEvWhiteboard::TEvBSGroupStateResponse>;
-
-template <>
-struct TJsonRequestSummary<TJsonBSGroupInfo> {
+#include "wb_merge.h"
+#include "json_wb_req.h"
+
+namespace NKikimr {
+namespace NViewer {
+
+template <>
+struct TWhiteboardInfo<TEvWhiteboard::TEvBSGroupStateResponse> {
+ using TResponseType = TEvWhiteboard::TEvBSGroupStateResponse;
+ using TElementType = NKikimrWhiteboard::TBSGroupStateInfo;
+ using TElementKeyType = ui32;
+
+ static constexpr bool StaticNodesOnly = true;
+
+ static ::google::protobuf::RepeatedPtrField<TElementType>* GetElementsField(TResponseType* response) {
+ return response->Record.MutableBSGroupStateInfo();
+ }
+
+ static ui32 GetElementKey(const TElementType& type) {
+ return type.GetGroupID();
+ }
+
+ static TString GetDefaultMergeField() {
+ return "GroupID";
+ }
+
+ static void InitMerger() {
+ const auto* field = NKikimrWhiteboard::TBSGroupStateInfo::descriptor()->FindFieldByName("Latency");
+ TWhiteboardMergerBase::FieldMerger[field] = &TWhiteboardMergerBase::ProtoMaximizeEnumField;
+ }
+
+ static THolder<TResponseType> MergeResponses(TMap<ui32, THolder<TResponseType>>& responses, const TString& fields = GetDefaultMergeField()) {
+ if (fields == GetDefaultMergeField()) {
+ return TWhiteboardMerger<TResponseType>::MergeResponsesElementKey(responses);
+ } else {
+ return TWhiteboardMerger<TResponseType>::MergeResponses(responses, fields);
+ }
+ }
+};
+
+template <>
+struct TWhiteboardMergerComparator<NKikimrWhiteboard::TBSGroupStateInfo> {
+ bool operator ()(const NKikimrWhiteboard::TBSGroupStateInfo& a, const NKikimrWhiteboard::TBSGroupStateInfo& b) const {
+ return std::make_tuple(a.GetGroupGeneration(), a.VDiskIdsSize(), a.GetChangeTime())
+ < std::make_tuple(b.GetGroupGeneration(), b.VDiskIdsSize(), b.GetChangeTime());
+ }
+};
+
+using TJsonBSGroupInfo = TJsonWhiteboardRequest<TEvWhiteboard::TEvBSGroupStateRequest, TEvWhiteboard::TEvBSGroupStateResponse>;
+
+template <>
+struct TJsonRequestSummary<TJsonBSGroupInfo> {
static TString GetSummary() {
- return "\"Storage groups information\"";
- }
-};
-
-template <>
-struct TJsonRequestDescription<TJsonBSGroupInfo> {
+ return "\"Storage groups information\"";
+ }
+};
+
+template <>
+struct TJsonRequestDescription<TJsonBSGroupInfo> {
static TString GetDescription() {
- return "\"Returns information about storage groups\"";
- }
-};
-
-}
-}
+ return "\"Returns information about storage groups\"";
+ }
+};
+
+}
+}
diff --git a/ydb/core/viewer/json_cluster.h b/ydb/core/viewer/json_cluster.h
index 97f3dc35521..36b5362a452 100644
--- a/ydb/core/viewer/json_cluster.h
+++ b/ydb/core/viewer/json_cluster.h
@@ -1,4 +1,4 @@
-#pragma once
+#pragma once
#include <library/cpp/actors/core/actor_bootstrapped.h>
#include <library/cpp/actors/core/interconnect.h>
#include <library/cpp/actors/core/mon.h>
@@ -6,432 +6,432 @@
#include <ydb/core/tx/schemeshard/schemeshard.h>
#include <ydb/core/tx/tx_proxy/proxy.h>
#include <ydb/core/viewer/json/json.h>
-#include "viewer.h"
-
-namespace NKikimr {
-namespace NViewer {
-
-using namespace NActors;
-using namespace NNodeWhiteboard;
-using ::google::protobuf::FieldDescriptor;
-
-class TJsonCluster : public TActorBootstrapped<TJsonCluster> {
- using TThis = TJsonCluster;
- using TBase = TActorBootstrapped<TJsonCluster>;
- IViewer* Viewer;
+#include "viewer.h"
+
+namespace NKikimr {
+namespace NViewer {
+
+using namespace NActors;
+using namespace NNodeWhiteboard;
+using ::google::protobuf::FieldDescriptor;
+
+class TJsonCluster : public TActorBootstrapped<TJsonCluster> {
+ using TThis = TJsonCluster;
+ using TBase = TActorBootstrapped<TJsonCluster>;
+ IViewer* Viewer;
TActorId Initiator;
- ui32 Requested;
- ui32 Received;
- NMon::TEvHttpInfo::TPtr Event;
- THolder<TEvInterconnect::TEvNodesInfo> NodesInfo;
- TMap<TNodeId, THolder<TEvWhiteboard::TEvSystemStateResponse>> SystemInfo;
- TMap<TNodeId, THolder<TEvWhiteboard::TEvVDiskStateResponse>> VDiskInfo;
- TMap<TNodeId, THolder<TEvWhiteboard::TEvPDiskStateResponse>> PDiskInfo;
- TMap<TNodeId, THolder<TEvWhiteboard::TEvBSGroupStateResponse>> BSGroupInfo;
- TMap<TNodeId, THolder<TEvWhiteboard::TEvTabletStateResponse>> TabletInfo;
+ ui32 Requested;
+ ui32 Received;
+ NMon::TEvHttpInfo::TPtr Event;
+ THolder<TEvInterconnect::TEvNodesInfo> NodesInfo;
+ TMap<TNodeId, THolder<TEvWhiteboard::TEvSystemStateResponse>> SystemInfo;
+ TMap<TNodeId, THolder<TEvWhiteboard::TEvVDiskStateResponse>> VDiskInfo;
+ TMap<TNodeId, THolder<TEvWhiteboard::TEvPDiskStateResponse>> PDiskInfo;
+ TMap<TNodeId, THolder<TEvWhiteboard::TEvBSGroupStateResponse>> BSGroupInfo;
+ TMap<TNodeId, THolder<TEvWhiteboard::TEvTabletStateResponse>> TabletInfo;
THolder<NSchemeShard::TEvSchemeShard::TEvDescribeSchemeResult> DescribeResult;
- TSet<TNodeId> NodesAlive;
- TJsonSettings JsonSettings;
- ui32 Timeout;
- bool Tablets = false;
-
-public:
+ TSet<TNodeId> NodesAlive;
+ TJsonSettings JsonSettings;
+ ui32 Timeout;
+ bool Tablets = false;
+
+public:
static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
return NKikimrServices::TActivity::VIEWER_HANDLER;
- }
-
- TJsonCluster(IViewer* viewer, NMon::TEvHttpInfo::TPtr& ev)
- : Viewer(viewer)
- , Initiator(ev->Sender)
- , Requested(0)
- , Received(0)
- , Event(ev)
- {
- const auto& params(Event->Get()->Request.GetParams());
- JsonSettings.EnumAsNumbers = !FromStringWithDefault<bool>(params.Get("enums"), true);
- JsonSettings.UI64AsString = !FromStringWithDefault<bool>(params.Get("ui64"), false);
- Tablets = FromStringWithDefault<bool>(params.Get("tablets"), false);
- Timeout = FromStringWithDefault<ui32>(params.Get("timeout"), 10000);
- }
-
- void Bootstrap(const TActorContext& ctx) {
+ }
+
+ TJsonCluster(IViewer* viewer, NMon::TEvHttpInfo::TPtr& ev)
+ : Viewer(viewer)
+ , Initiator(ev->Sender)
+ , Requested(0)
+ , Received(0)
+ , Event(ev)
+ {
+ const auto& params(Event->Get()->Request.GetParams());
+ JsonSettings.EnumAsNumbers = !FromStringWithDefault<bool>(params.Get("enums"), true);
+ JsonSettings.UI64AsString = !FromStringWithDefault<bool>(params.Get("ui64"), false);
+ Tablets = FromStringWithDefault<bool>(params.Get("tablets"), false);
+ Timeout = FromStringWithDefault<ui32>(params.Get("timeout"), 10000);
+ }
+
+ void Bootstrap(const TActorContext& ctx) {
const TActorId nameserviceId = GetNameserviceActorId();
- ctx.Send(nameserviceId, new TEvInterconnect::TEvListNodes());
- TBase::Become(&TThis::StateRequestedBrowse);
- ctx.Schedule(TDuration::MilliSeconds(Timeout), new TEvents::TEvWakeup());
- }
-
- void Die(const TActorContext& ctx) override {
- if (NodesInfo != nullptr) {
- for (const auto& ni : NodesInfo->Nodes) {
+ ctx.Send(nameserviceId, new TEvInterconnect::TEvListNodes());
+ TBase::Become(&TThis::StateRequestedBrowse);
+ ctx.Schedule(TDuration::MilliSeconds(Timeout), new TEvents::TEvWakeup());
+ }
+
+ void Die(const TActorContext& ctx) override {
+ if (NodesInfo != nullptr) {
+ for (const auto& ni : NodesInfo->Nodes) {
ctx.Send(TActivationContext::InterconnectProxy(ni.NodeId), new TEvents::TEvUnsubscribe());
- }
- }
- TBase::Die(ctx);
- }
-
- void SendRequest(ui32 nodeId, const TActorContext& ctx) {
+ }
+ }
+ TBase::Die(ctx);
+ }
+
+ void SendRequest(ui32 nodeId, const TActorContext& ctx) {
TActorId whiteboardServiceId = MakeNodeWhiteboardServiceId(nodeId);
- ctx.Send(whiteboardServiceId, new TEvWhiteboard::TEvSystemStateRequest(), IEventHandle::FlagTrackDelivery | IEventHandle::FlagSubscribeOnSession, nodeId);
- ++Requested;
- ctx.Send(whiteboardServiceId, new TEvWhiteboard::TEvVDiskStateRequest(), IEventHandle::FlagTrackDelivery | IEventHandle::FlagSubscribeOnSession, nodeId);
- ++Requested;
- ctx.Send(whiteboardServiceId, new TEvWhiteboard::TEvPDiskStateRequest(), IEventHandle::FlagTrackDelivery | IEventHandle::FlagSubscribeOnSession, nodeId);
- ++Requested;
- ctx.Send(whiteboardServiceId, new TEvWhiteboard::TEvBSGroupStateRequest(), IEventHandle::FlagTrackDelivery | IEventHandle::FlagSubscribeOnSession, nodeId);
- ++Requested;
- if (Tablets) {
- ctx.Send(whiteboardServiceId, new TEvWhiteboard::TEvTabletStateRequest(), IEventHandle::FlagTrackDelivery | IEventHandle::FlagSubscribeOnSession, nodeId);
- ++Requested;
- }
- }
-
- void HandleBrowse(TEvInterconnect::TEvNodesInfo::TPtr& ev, const TActorContext& ctx) {
- if (Tablets) {
+ ctx.Send(whiteboardServiceId, new TEvWhiteboard::TEvSystemStateRequest(), IEventHandle::FlagTrackDelivery | IEventHandle::FlagSubscribeOnSession, nodeId);
+ ++Requested;
+ ctx.Send(whiteboardServiceId, new TEvWhiteboard::TEvVDiskStateRequest(), IEventHandle::FlagTrackDelivery | IEventHandle::FlagSubscribeOnSession, nodeId);
+ ++Requested;
+ ctx.Send(whiteboardServiceId, new TEvWhiteboard::TEvPDiskStateRequest(), IEventHandle::FlagTrackDelivery | IEventHandle::FlagSubscribeOnSession, nodeId);
+ ++Requested;
+ ctx.Send(whiteboardServiceId, new TEvWhiteboard::TEvBSGroupStateRequest(), IEventHandle::FlagTrackDelivery | IEventHandle::FlagSubscribeOnSession, nodeId);
+ ++Requested;
+ if (Tablets) {
+ ctx.Send(whiteboardServiceId, new TEvWhiteboard::TEvTabletStateRequest(), IEventHandle::FlagTrackDelivery | IEventHandle::FlagSubscribeOnSession, nodeId);
+ ++Requested;
+ }
+ }
+
+ void HandleBrowse(TEvInterconnect::TEvNodesInfo::TPtr& ev, const TActorContext& ctx) {
+ if (Tablets) {
THolder<TEvTxUserProxy::TEvNavigate> request = MakeHolder<TEvTxUserProxy::TEvNavigate>();
- if (!Event->Get()->UserToken.empty()) {
- request->Record.SetUserToken(Event->Get()->UserToken);
- }
- TIntrusivePtr<TDomainsInfo> domains = AppData(ctx)->DomainsInfo;
- TIntrusivePtr<TDomainsInfo::TDomain> domain = domains->Domains.begin()->second;
- TString domainPath = "/" + domain->Name;
+ if (!Event->Get()->UserToken.empty()) {
+ request->Record.SetUserToken(Event->Get()->UserToken);
+ }
+ TIntrusivePtr<TDomainsInfo> domains = AppData(ctx)->DomainsInfo;
+ TIntrusivePtr<TDomainsInfo::TDomain> domain = domains->Domains.begin()->second;
+ TString domainPath = "/" + domain->Name;
NKikimrSchemeOp::TDescribePath* record = request->Record.MutableDescribePath();
- record->SetPath(domainPath);
- record->MutableOptions()->SetReturnPartitioningInfo(false);
- record->MutableOptions()->SetReturnPartitionConfig(false);
- record->MutableOptions()->SetReturnChildren(false);
+ record->SetPath(domainPath);
+ record->MutableOptions()->SetReturnPartitioningInfo(false);
+ record->MutableOptions()->SetReturnPartitionConfig(false);
+ record->MutableOptions()->SetReturnChildren(false);
TActorId txproxy = MakeTxProxyID();
- ctx.Send(txproxy, request.Release());
- ++Requested;
- }
-
- NodesInfo = ev->Release();
- for (const auto& ni : NodesInfo->Nodes) {
- SendRequest(ni.NodeId, ctx);
- }
- if (Requested > 0) {
- TBase::Become(&TThis::StateRequestedNodeInfo);
- } else {
- ReplyAndDie(ctx);
- }
- }
-
- void Undelivered(TEvents::TEvUndelivered::TPtr &ev, const TActorContext &ctx) {
- ui32 nodeId = ev.Get()->Cookie;
- switch (ev->Get()->SourceType) {
- case TEvWhiteboard::EvSystemStateRequest:
- if (VDiskInfo.emplace(nodeId, nullptr).second) {
- RequestDone(ctx);
- }
- break;
- case TEvWhiteboard::EvVDiskStateRequest:
- if (VDiskInfo.emplace(nodeId, nullptr).second) {
- RequestDone(ctx);
- }
- break;
- case TEvWhiteboard::EvPDiskStateRequest:
- if (PDiskInfo.emplace(nodeId, nullptr).second) {
- RequestDone(ctx);
- }
- break;
- case TEvWhiteboard::EvBSGroupStateRequest:
- if (BSGroupInfo.emplace(nodeId, nullptr).second) {
- RequestDone(ctx);
- }
- break;
- case TEvWhiteboard::EvTabletStateRequest:
- if (TabletInfo.emplace(nodeId, nullptr).second) {
- RequestDone(ctx);
- }
- break;
- }
- }
-
- void Disconnected(TEvInterconnect::TEvNodeDisconnected::TPtr &ev, const TActorContext &ctx) {
- ui32 nodeId = ev->Get()->NodeId;
- if (SystemInfo.emplace(nodeId, nullptr).second) {
- RequestDone(ctx);
- }
- if (VDiskInfo.emplace(nodeId, nullptr).second) {
- RequestDone(ctx);
- }
- if (PDiskInfo.emplace(nodeId, nullptr).second) {
- RequestDone(ctx);
- }
- if (BSGroupInfo.emplace(nodeId, nullptr).second) {
- RequestDone(ctx);
- }
- if (Tablets) {
- if (TabletInfo.emplace(nodeId, nullptr).second) {
- RequestDone(ctx);
- }
- }
- }
-
- void Handle(TEvWhiteboard::TEvSystemStateResponse::TPtr& ev, const TActorContext& ctx) {
- ui64 nodeId = ev.Get()->Cookie;
- SystemInfo[nodeId] = ev->Release();
- NodesAlive.insert(nodeId);
- RequestDone(ctx);
- }
-
- void Handle(TEvWhiteboard::TEvVDiskStateResponse::TPtr& ev, const TActorContext& ctx) {
- ui64 nodeId = ev.Get()->Cookie;
- VDiskInfo[nodeId] = ev->Release();
- NodesAlive.insert(nodeId);
- RequestDone(ctx);
- }
-
- void Handle(TEvWhiteboard::TEvPDiskStateResponse::TPtr& ev, const TActorContext& ctx) {
- ui64 nodeId = ev.Get()->Cookie;
- PDiskInfo[nodeId] = ev->Release();
- NodesAlive.insert(nodeId);
- RequestDone(ctx);
- }
-
- void Handle(TEvWhiteboard::TEvBSGroupStateResponse::TPtr& ev, const TActorContext& ctx) {
- ui64 nodeId = ev.Get()->Cookie;
- BSGroupInfo[nodeId] = ev->Release();
- NodesAlive.insert(nodeId);
- RequestDone(ctx);
- }
-
- void Handle(TEvWhiteboard::TEvTabletStateResponse::TPtr& ev, const TActorContext& ctx) {
- ui64 nodeId = ev.Get()->Cookie;
- TabletInfo[nodeId] = ev->Release();
- NodesAlive.insert(nodeId);
- RequestDone(ctx);
- }
-
+ ctx.Send(txproxy, request.Release());
+ ++Requested;
+ }
+
+ NodesInfo = ev->Release();
+ for (const auto& ni : NodesInfo->Nodes) {
+ SendRequest(ni.NodeId, ctx);
+ }
+ if (Requested > 0) {
+ TBase::Become(&TThis::StateRequestedNodeInfo);
+ } else {
+ ReplyAndDie(ctx);
+ }
+ }
+
+ void Undelivered(TEvents::TEvUndelivered::TPtr &ev, const TActorContext &ctx) {
+ ui32 nodeId = ev.Get()->Cookie;
+ switch (ev->Get()->SourceType) {
+ case TEvWhiteboard::EvSystemStateRequest:
+ if (VDiskInfo.emplace(nodeId, nullptr).second) {
+ RequestDone(ctx);
+ }
+ break;
+ case TEvWhiteboard::EvVDiskStateRequest:
+ if (VDiskInfo.emplace(nodeId, nullptr).second) {
+ RequestDone(ctx);
+ }
+ break;
+ case TEvWhiteboard::EvPDiskStateRequest:
+ if (PDiskInfo.emplace(nodeId, nullptr).second) {
+ RequestDone(ctx);
+ }
+ break;
+ case TEvWhiteboard::EvBSGroupStateRequest:
+ if (BSGroupInfo.emplace(nodeId, nullptr).second) {
+ RequestDone(ctx);
+ }
+ break;
+ case TEvWhiteboard::EvTabletStateRequest:
+ if (TabletInfo.emplace(nodeId, nullptr).second) {
+ RequestDone(ctx);
+ }
+ break;
+ }
+ }
+
+ void Disconnected(TEvInterconnect::TEvNodeDisconnected::TPtr &ev, const TActorContext &ctx) {
+ ui32 nodeId = ev->Get()->NodeId;
+ if (SystemInfo.emplace(nodeId, nullptr).second) {
+ RequestDone(ctx);
+ }
+ if (VDiskInfo.emplace(nodeId, nullptr).second) {
+ RequestDone(ctx);
+ }
+ if (PDiskInfo.emplace(nodeId, nullptr).second) {
+ RequestDone(ctx);
+ }
+ if (BSGroupInfo.emplace(nodeId, nullptr).second) {
+ RequestDone(ctx);
+ }
+ if (Tablets) {
+ if (TabletInfo.emplace(nodeId, nullptr).second) {
+ RequestDone(ctx);
+ }
+ }
+ }
+
+ void Handle(TEvWhiteboard::TEvSystemStateResponse::TPtr& ev, const TActorContext& ctx) {
+ ui64 nodeId = ev.Get()->Cookie;
+ SystemInfo[nodeId] = ev->Release();
+ NodesAlive.insert(nodeId);
+ RequestDone(ctx);
+ }
+
+ void Handle(TEvWhiteboard::TEvVDiskStateResponse::TPtr& ev, const TActorContext& ctx) {
+ ui64 nodeId = ev.Get()->Cookie;
+ VDiskInfo[nodeId] = ev->Release();
+ NodesAlive.insert(nodeId);
+ RequestDone(ctx);
+ }
+
+ void Handle(TEvWhiteboard::TEvPDiskStateResponse::TPtr& ev, const TActorContext& ctx) {
+ ui64 nodeId = ev.Get()->Cookie;
+ PDiskInfo[nodeId] = ev->Release();
+ NodesAlive.insert(nodeId);
+ RequestDone(ctx);
+ }
+
+ void Handle(TEvWhiteboard::TEvBSGroupStateResponse::TPtr& ev, const TActorContext& ctx) {
+ ui64 nodeId = ev.Get()->Cookie;
+ BSGroupInfo[nodeId] = ev->Release();
+ NodesAlive.insert(nodeId);
+ RequestDone(ctx);
+ }
+
+ void Handle(TEvWhiteboard::TEvTabletStateResponse::TPtr& ev, const TActorContext& ctx) {
+ ui64 nodeId = ev.Get()->Cookie;
+ TabletInfo[nodeId] = ev->Release();
+ NodesAlive.insert(nodeId);
+ RequestDone(ctx);
+ }
+
void Handle(NSchemeShard::TEvSchemeShard::TEvDescribeSchemeResult::TPtr& ev, const TActorContext &ctx) {
if (ev->Get()->GetRecord().GetStatus() == NKikimrScheme::StatusSuccess) {
- DescribeResult = ev->Release();
- }
- RequestDone(ctx);
- }
-
- void RequestDone(const TActorContext& ctx) {
- ++Received;
- if (Received == Requested) {
- ReplyAndDie(ctx);
- }
- }
-
- void Handle(TEvTabletPipe::TEvClientConnected::TPtr& ev, const TActorContext& ctx) {
- if (ev->Get()->Status != NKikimrProto::OK) {
- RequestDone(ctx);
- }
- }
-
- STFUNC(StateRequestedBrowse) {
- switch (ev->GetTypeRewrite()) {
- HFunc(TEvInterconnect::TEvNodesInfo, HandleBrowse);
- CFunc(TEvents::TSystem::Wakeup, HandleTimeout);
- }
- }
-
- STFUNC(StateRequestedNodeInfo) {
- switch (ev->GetTypeRewrite()) {
- HFunc(TEvWhiteboard::TEvSystemStateResponse, Handle);
- HFunc(TEvWhiteboard::TEvVDiskStateResponse, Handle);
- HFunc(TEvWhiteboard::TEvPDiskStateResponse, Handle);
- HFunc(TEvWhiteboard::TEvBSGroupStateResponse, Handle);
- HFunc(TEvWhiteboard::TEvTabletStateResponse, Handle);
+ DescribeResult = ev->Release();
+ }
+ RequestDone(ctx);
+ }
+
+ void RequestDone(const TActorContext& ctx) {
+ ++Received;
+ if (Received == Requested) {
+ ReplyAndDie(ctx);
+ }
+ }
+
+ void Handle(TEvTabletPipe::TEvClientConnected::TPtr& ev, const TActorContext& ctx) {
+ if (ev->Get()->Status != NKikimrProto::OK) {
+ RequestDone(ctx);
+ }
+ }
+
+ STFUNC(StateRequestedBrowse) {
+ switch (ev->GetTypeRewrite()) {
+ HFunc(TEvInterconnect::TEvNodesInfo, HandleBrowse);
+ CFunc(TEvents::TSystem::Wakeup, HandleTimeout);
+ }
+ }
+
+ STFUNC(StateRequestedNodeInfo) {
+ switch (ev->GetTypeRewrite()) {
+ HFunc(TEvWhiteboard::TEvSystemStateResponse, Handle);
+ HFunc(TEvWhiteboard::TEvVDiskStateResponse, Handle);
+ HFunc(TEvWhiteboard::TEvPDiskStateResponse, Handle);
+ HFunc(TEvWhiteboard::TEvBSGroupStateResponse, Handle);
+ HFunc(TEvWhiteboard::TEvTabletStateResponse, Handle);
HFunc(NSchemeShard::TEvSchemeShard::TEvDescribeSchemeResult, Handle);
- HFunc(TEvents::TEvUndelivered, Undelivered);
- HFunc(TEvInterconnect::TEvNodeDisconnected, Disconnected);
- HFunc(TEvTabletPipe::TEvClientConnected, Handle);
- CFunc(TEvents::TSystem::Wakeup, HandleTimeout);
- }
- }
-
- THolder<TEvWhiteboard::TEvBSGroupStateResponse> MergedBSGroupInfo;
- THolder<TEvWhiteboard::TEvVDiskStateResponse> MergedVDiskInfo;
- THolder<TEvWhiteboard::TEvPDiskStateResponse> MergedPDiskInfo;
- THolder<TEvWhiteboard::TEvTabletStateResponse> MergedTabletInfo;
+ HFunc(TEvents::TEvUndelivered, Undelivered);
+ HFunc(TEvInterconnect::TEvNodeDisconnected, Disconnected);
+ HFunc(TEvTabletPipe::TEvClientConnected, Handle);
+ CFunc(TEvents::TSystem::Wakeup, HandleTimeout);
+ }
+ }
+
+ THolder<TEvWhiteboard::TEvBSGroupStateResponse> MergedBSGroupInfo;
+ THolder<TEvWhiteboard::TEvVDiskStateResponse> MergedVDiskInfo;
+ THolder<TEvWhiteboard::TEvPDiskStateResponse> MergedPDiskInfo;
+ THolder<TEvWhiteboard::TEvTabletStateResponse> MergedTabletInfo;
TMap<NKikimrBlobStorage::TVDiskID, const NKikimrWhiteboard::TVDiskStateInfo&> VDisksIndex;
TMap<std::pair<ui32, ui32>, const NKikimrWhiteboard::TPDiskStateInfo&> PDisksIndex;
-
- void ReplyAndDie(const TActorContext& ctx) {
- TStringStream json;
- MergedBSGroupInfo = MergeWhiteboardResponses(BSGroupInfo, TWhiteboardInfo<TEvWhiteboard::TEvBSGroupStateResponse>::GetDefaultMergeField());
- MergedVDiskInfo = MergeWhiteboardResponses(VDiskInfo, TWhiteboardInfo<TEvWhiteboard::TEvVDiskStateResponse>::GetDefaultMergeField());
- MergedPDiskInfo = MergeWhiteboardResponses(PDiskInfo, TWhiteboardInfo<TEvWhiteboard::TEvPDiskStateResponse>::GetDefaultMergeField());
-
- THashSet<TTabletId> tablets;
-
- if (Tablets) {
- MergedTabletInfo = MergeWhiteboardResponses(TabletInfo, TWhiteboardInfo<TEvWhiteboard::TEvTabletStateResponse>::GetDefaultMergeField());
- TIntrusivePtr<TDomainsInfo> domains = AppData(ctx)->DomainsInfo;
- TIntrusivePtr<TDomainsInfo::TDomain> domain = domains->Domains.begin()->second;
- ui32 hiveDomain = domains->GetHiveDomainUid(domain->DefaultHiveUid);
- ui64 defaultStateStorageGroup = domains->GetDefaultStateStorageGroup(hiveDomain);
- tablets.emplace(MakeBSControllerID(defaultStateStorageGroup));
- tablets.emplace(MakeConsoleID(defaultStateStorageGroup));
- tablets.emplace(domain->SchemeRoot);
- tablets.emplace(domains->GetHive(domain->DefaultHiveUid));
- for (TTabletId id : domain->Coordinators) {
- tablets.emplace(id);
- }
- for (TTabletId id : domain->Mediators) {
- tablets.emplace(id);
- }
- for (TTabletId id : domain->TxAllocators) {
- tablets.emplace(id);
- }
-
- if (DescribeResult) {
+
+ void ReplyAndDie(const TActorContext& ctx) {
+ TStringStream json;
+ MergedBSGroupInfo = MergeWhiteboardResponses(BSGroupInfo, TWhiteboardInfo<TEvWhiteboard::TEvBSGroupStateResponse>::GetDefaultMergeField());
+ MergedVDiskInfo = MergeWhiteboardResponses(VDiskInfo, TWhiteboardInfo<TEvWhiteboard::TEvVDiskStateResponse>::GetDefaultMergeField());
+ MergedPDiskInfo = MergeWhiteboardResponses(PDiskInfo, TWhiteboardInfo<TEvWhiteboard::TEvPDiskStateResponse>::GetDefaultMergeField());
+
+ THashSet<TTabletId> tablets;
+
+ if (Tablets) {
+ MergedTabletInfo = MergeWhiteboardResponses(TabletInfo, TWhiteboardInfo<TEvWhiteboard::TEvTabletStateResponse>::GetDefaultMergeField());
+ TIntrusivePtr<TDomainsInfo> domains = AppData(ctx)->DomainsInfo;
+ TIntrusivePtr<TDomainsInfo::TDomain> domain = domains->Domains.begin()->second;
+ ui32 hiveDomain = domains->GetHiveDomainUid(domain->DefaultHiveUid);
+ ui64 defaultStateStorageGroup = domains->GetDefaultStateStorageGroup(hiveDomain);
+ tablets.emplace(MakeBSControllerID(defaultStateStorageGroup));
+ tablets.emplace(MakeConsoleID(defaultStateStorageGroup));
+ tablets.emplace(domain->SchemeRoot);
+ tablets.emplace(domains->GetHive(domain->DefaultHiveUid));
+ for (TTabletId id : domain->Coordinators) {
+ tablets.emplace(id);
+ }
+ for (TTabletId id : domain->Mediators) {
+ tablets.emplace(id);
+ }
+ for (TTabletId id : domain->TxAllocators) {
+ tablets.emplace(id);
+ }
+
+ if (DescribeResult) {
const NKikimrSchemeOp::TPathDescription& pathDescription(DescribeResult->GetRecord().GetPathDescription());
- if (pathDescription.HasDomainDescription()) {
- const NKikimrSubDomains::TDomainDescription& domainDescription(pathDescription.GetDomainDescription());
- for (TTabletId tabletId : domainDescription.GetProcessingParams().GetCoordinators()) {
- tablets.emplace(tabletId);
- }
- for (TTabletId tabletId : domainDescription.GetProcessingParams().GetMediators()) {
- tablets.emplace(tabletId);
- }
- if (domainDescription.HasDomainKey()) {
- if (domainDescription.GetDomainKey().HasSchemeShard()) {
- tablets.emplace(domainDescription.GetDomainKey().GetSchemeShard());
- }
- }
- }
- }
- }
-
- ui64 totalStorageSize = 0;
- ui64 availableStorageSize = 0;
-
- for (auto& element : *TWhiteboardInfo<TEvWhiteboard::TEvPDiskStateResponse>::GetElementsField(MergedPDiskInfo.Get())) {
- if (element.HasTotalSize() && element.HasAvailableSize()) {
- totalStorageSize += element.GetTotalSize();
- availableStorageSize += element.GetAvailableSize();
- }
- element.SetStateFlag(GetWhiteboardFlag(GetPDiskStateFlag(element)));
- element.SetOverall(GetWhiteboardFlag(GetPDiskOverallFlag(element)));
- PDisksIndex.emplace(TWhiteboardInfo<TEvWhiteboard::TEvPDiskStateResponse>::GetElementKey(element), element);
- }
- for (auto& element : *TWhiteboardInfo<TEvWhiteboard::TEvVDiskStateResponse>::GetElementsField(MergedVDiskInfo.Get())) {
- element.SetOverall(GetWhiteboardFlag(GetVDiskOverallFlag(element)));
- VDisksIndex.emplace(TWhiteboardInfo<TEvWhiteboard::TEvVDiskStateResponse>::GetElementKey(element), element);
- }
- NKikimrViewer::EFlag flag = NKikimrViewer::Grey;
- for (const auto& element : *TWhiteboardInfo<TEvWhiteboard::TEvBSGroupStateResponse>::GetElementsField(MergedBSGroupInfo.Get())) {
- flag = Max(flag, GetBSGroupOverallFlag(element, VDisksIndex, PDisksIndex));
- }
- ui32 numberOfCpus = 0;
- double loadAverage = 0;
+ if (pathDescription.HasDomainDescription()) {
+ const NKikimrSubDomains::TDomainDescription& domainDescription(pathDescription.GetDomainDescription());
+ for (TTabletId tabletId : domainDescription.GetProcessingParams().GetCoordinators()) {
+ tablets.emplace(tabletId);
+ }
+ for (TTabletId tabletId : domainDescription.GetProcessingParams().GetMediators()) {
+ tablets.emplace(tabletId);
+ }
+ if (domainDescription.HasDomainKey()) {
+ if (domainDescription.GetDomainKey().HasSchemeShard()) {
+ tablets.emplace(domainDescription.GetDomainKey().GetSchemeShard());
+ }
+ }
+ }
+ }
+ }
+
+ ui64 totalStorageSize = 0;
+ ui64 availableStorageSize = 0;
+
+ for (auto& element : *TWhiteboardInfo<TEvWhiteboard::TEvPDiskStateResponse>::GetElementsField(MergedPDiskInfo.Get())) {
+ if (element.HasTotalSize() && element.HasAvailableSize()) {
+ totalStorageSize += element.GetTotalSize();
+ availableStorageSize += element.GetAvailableSize();
+ }
+ element.SetStateFlag(GetWhiteboardFlag(GetPDiskStateFlag(element)));
+ element.SetOverall(GetWhiteboardFlag(GetPDiskOverallFlag(element)));
+ PDisksIndex.emplace(TWhiteboardInfo<TEvWhiteboard::TEvPDiskStateResponse>::GetElementKey(element), element);
+ }
+ for (auto& element : *TWhiteboardInfo<TEvWhiteboard::TEvVDiskStateResponse>::GetElementsField(MergedVDiskInfo.Get())) {
+ element.SetOverall(GetWhiteboardFlag(GetVDiskOverallFlag(element)));
+ VDisksIndex.emplace(TWhiteboardInfo<TEvWhiteboard::TEvVDiskStateResponse>::GetElementKey(element), element);
+ }
+ NKikimrViewer::EFlag flag = NKikimrViewer::Grey;
+ for (const auto& element : *TWhiteboardInfo<TEvWhiteboard::TEvBSGroupStateResponse>::GetElementsField(MergedBSGroupInfo.Get())) {
+ flag = Max(flag, GetBSGroupOverallFlag(element, VDisksIndex, PDisksIndex));
+ }
+ ui32 numberOfCpus = 0;
+ double loadAverage = 0;
THashSet<TString> dataCenters;
THashSet<TString> versions;
- THashSet<TString> hosts;
- THashMap<TString, int> names;
- for (const auto& pr : SystemInfo) {
- if (pr.second != nullptr) {
- const NKikimrWhiteboard::TSystemStateInfo& systemState = pr.second->Record.GetSystemStateInfo(0);
- if (systemState.HasNumberOfCpus() && (!systemState.HasHost() || hosts.emplace(systemState.GetHost()).second)) {
- numberOfCpus += systemState.GetNumberOfCpus();
- if (systemState.LoadAverageSize() > 0) {
- loadAverage += systemState.GetLoadAverage(0);
- }
- }
- if (systemState.HasDataCenter()) {
- dataCenters.insert(systemState.GetDataCenter());
- }
- if (systemState.HasVersion()) {
- versions.insert(systemState.GetVersion());
- }
- if (systemState.HasClusterName()) {
- names[systemState.GetClusterName()]++;
- }
- }
- }
-
- NKikimrViewer::TClusterInfo pbCluster;
-
- if (Tablets) {
- std::unordered_set<std::pair<ui64, ui64>> tenants; /// group by tenantid (TDomainKey)
- for (const NKikimrWhiteboard::TTabletStateInfo& tabletInfo : MergedTabletInfo->Record.GetTabletStateInfo()) {
- if (tablets.contains(tabletInfo.GetTabletId())) {
- NKikimrWhiteboard::TTabletStateInfo* tablet = pbCluster.AddSystemTablets();
- tablet->CopyFrom(tabletInfo);
- auto tabletFlag = GetWhiteboardFlag(GetFlagFromTabletState(tablet->GetState()));
- tablet->SetOverall(tabletFlag);
- flag = Max(flag, GetViewerFlag(tabletFlag));
- }
- std::pair<ui64, ui64> tenantId = {0, 0};
- if (tabletInfo.HasTenantId()) {
- tenantId = {tabletInfo.GetTenantId().GetSchemeShard(), tabletInfo.GetTenantId().GetPathId()};
- }
- tenants.emplace(tenantId);
- }
- pbCluster.SetTablets(MergedTabletInfo->Record.TabletStateInfoSize());
- pbCluster.SetTenants(tenants.size());
- }
-
- pbCluster.SetOverall(flag);
- if (NodesInfo != nullptr) {
- pbCluster.SetNodesTotal(NodesInfo->Nodes.size());
- pbCluster.SetNodesAlive(NodesAlive.size());
- }
- pbCluster.SetNumberOfCpus(numberOfCpus);
- pbCluster.SetLoadAverage(loadAverage);
- pbCluster.SetStorageTotal(totalStorageSize);
- pbCluster.SetStorageUsed(totalStorageSize - availableStorageSize);
- pbCluster.SetHosts(hosts.size());
- for (const TString& dc : dataCenters) {
- pbCluster.AddDataCenters(dc);
- }
- for (const TString& version : versions) {
- pbCluster.AddVersions(version);
- }
- auto itMax = std::max_element(names.begin(), names.end(), [](const auto& a, const auto& b) {
- return a.second < b.second;
- });
- if (itMax != names.end()) {
- pbCluster.SetName(itMax->first);
- }
- TProtoToJson::ProtoToJson(json, pbCluster, JsonSettings);
- ctx.Send(Initiator, new NMon::TEvHttpInfoRes(Viewer->GetHTTPOKJSON() + json.Str(), 0, NMon::IEvHttpInfoRes::EContentType::Custom));
- Die(ctx);
- }
-
- void HandleTimeout(const TActorContext& ctx) {
- ReplyAndDie(ctx);
- }
-};
-
-template <>
-struct TJsonRequestSchema<TJsonCluster> {
+ THashSet<TString> hosts;
+ THashMap<TString, int> names;
+ for (const auto& pr : SystemInfo) {
+ if (pr.second != nullptr) {
+ const NKikimrWhiteboard::TSystemStateInfo& systemState = pr.second->Record.GetSystemStateInfo(0);
+ if (systemState.HasNumberOfCpus() && (!systemState.HasHost() || hosts.emplace(systemState.GetHost()).second)) {
+ numberOfCpus += systemState.GetNumberOfCpus();
+ if (systemState.LoadAverageSize() > 0) {
+ loadAverage += systemState.GetLoadAverage(0);
+ }
+ }
+ if (systemState.HasDataCenter()) {
+ dataCenters.insert(systemState.GetDataCenter());
+ }
+ if (systemState.HasVersion()) {
+ versions.insert(systemState.GetVersion());
+ }
+ if (systemState.HasClusterName()) {
+ names[systemState.GetClusterName()]++;
+ }
+ }
+ }
+
+ NKikimrViewer::TClusterInfo pbCluster;
+
+ if (Tablets) {
+ std::unordered_set<std::pair<ui64, ui64>> tenants; /// group by tenantid (TDomainKey)
+ for (const NKikimrWhiteboard::TTabletStateInfo& tabletInfo : MergedTabletInfo->Record.GetTabletStateInfo()) {
+ if (tablets.contains(tabletInfo.GetTabletId())) {
+ NKikimrWhiteboard::TTabletStateInfo* tablet = pbCluster.AddSystemTablets();
+ tablet->CopyFrom(tabletInfo);
+ auto tabletFlag = GetWhiteboardFlag(GetFlagFromTabletState(tablet->GetState()));
+ tablet->SetOverall(tabletFlag);
+ flag = Max(flag, GetViewerFlag(tabletFlag));
+ }
+ std::pair<ui64, ui64> tenantId = {0, 0};
+ if (tabletInfo.HasTenantId()) {
+ tenantId = {tabletInfo.GetTenantId().GetSchemeShard(), tabletInfo.GetTenantId().GetPathId()};
+ }
+ tenants.emplace(tenantId);
+ }
+ pbCluster.SetTablets(MergedTabletInfo->Record.TabletStateInfoSize());
+ pbCluster.SetTenants(tenants.size());
+ }
+
+ pbCluster.SetOverall(flag);
+ if (NodesInfo != nullptr) {
+ pbCluster.SetNodesTotal(NodesInfo->Nodes.size());
+ pbCluster.SetNodesAlive(NodesAlive.size());
+ }
+ pbCluster.SetNumberOfCpus(numberOfCpus);
+ pbCluster.SetLoadAverage(loadAverage);
+ pbCluster.SetStorageTotal(totalStorageSize);
+ pbCluster.SetStorageUsed(totalStorageSize - availableStorageSize);
+ pbCluster.SetHosts(hosts.size());
+ for (const TString& dc : dataCenters) {
+ pbCluster.AddDataCenters(dc);
+ }
+ for (const TString& version : versions) {
+ pbCluster.AddVersions(version);
+ }
+ auto itMax = std::max_element(names.begin(), names.end(), [](const auto& a, const auto& b) {
+ return a.second < b.second;
+ });
+ if (itMax != names.end()) {
+ pbCluster.SetName(itMax->first);
+ }
+ TProtoToJson::ProtoToJson(json, pbCluster, JsonSettings);
+ ctx.Send(Initiator, new NMon::TEvHttpInfoRes(Viewer->GetHTTPOKJSON() + json.Str(), 0, NMon::IEvHttpInfoRes::EContentType::Custom));
+ Die(ctx);
+ }
+
+ void HandleTimeout(const TActorContext& ctx) {
+ ReplyAndDie(ctx);
+ }
+};
+
+template <>
+struct TJsonRequestSchema<TJsonCluster> {
static TString GetSchema() {
- TStringStream stream;
- TProtoToJson::ProtoToJsonSchema<NKikimrViewer::TClusterInfo>(stream);
- return stream.Str();
- }
-};
-
-template <>
-struct TJsonRequestParameters<TJsonCluster> {
+ TStringStream stream;
+ TProtoToJson::ProtoToJsonSchema<NKikimrViewer::TClusterInfo>(stream);
+ return stream.Str();
+ }
+};
+
+template <>
+struct TJsonRequestParameters<TJsonCluster> {
static TString GetParameters() {
- return R"___([{"name":"enums","in":"query","description":"convert enums to strings","required":false,"type":"boolean"},
- {"name":"tablets","in":"query","description":"return system tablets state","required":false,"type":"boolean"},
- {"name":"ui64","in":"query","description":"return ui64 as number","required":false,"type":"boolean"},
- {"name":"timeout","in":"query","description":"timeout in ms","required":false,"type":"integer"}])___";
- }
-};
-
-template <>
-struct TJsonRequestSummary<TJsonCluster> {
+ return R"___([{"name":"enums","in":"query","description":"convert enums to strings","required":false,"type":"boolean"},
+ {"name":"tablets","in":"query","description":"return system tablets state","required":false,"type":"boolean"},
+ {"name":"ui64","in":"query","description":"return ui64 as number","required":false,"type":"boolean"},
+ {"name":"timeout","in":"query","description":"timeout in ms","required":false,"type":"integer"}])___";
+ }
+};
+
+template <>
+struct TJsonRequestSummary<TJsonCluster> {
static TString GetSummary() {
- return "\"Cluster information\"";
- }
-};
-
-template <>
-struct TJsonRequestDescription<TJsonCluster> {
+ return "\"Cluster information\"";
+ }
+};
+
+template <>
+struct TJsonRequestDescription<TJsonCluster> {
static TString GetDescription() {
- return "\"Returns information about cluster\"";
- }
-};
-
-}
-}
+ return "\"Returns information about cluster\"";
+ }
+};
+
+}
+}
diff --git a/ydb/core/viewer/json_compute.h b/ydb/core/viewer/json_compute.h
index 6d2c491d969..980b8bfc1ec 100644
--- a/ydb/core/viewer/json_compute.h
+++ b/ydb/core/viewer/json_compute.h
@@ -1,4 +1,4 @@
-#pragma once
+#pragma once
#include <library/cpp/actors/core/actor_bootstrapped.h>
#include <library/cpp/actors/core/mon.h>
#include <library/cpp/actors/core/interconnect.h>
@@ -12,384 +12,384 @@
#include <ydb/core/tx/tx_proxy/proxy.h>
#include <ydb/core/viewer/protos/viewer.pb.h>
#include <ydb/core/viewer/json/json.h>
-#include "viewer.h"
-#include "json_pipe_req.h"
-#include "wb_aggregate.h"
-#include "wb_merge.h"
-
-namespace NKikimr {
-namespace NViewer {
-
-using namespace NActors;
-
-class TJsonCompute : public TViewerPipeClient<TJsonCompute> {
- using TBase = TViewerPipeClient<TJsonCompute>;
- IViewer* Viewer;
- THashMap<TString, NKikimrViewer::TTenant> TenantByPath;
- THashMap<TPathId, NKikimrViewer::TTenant> TenantBySubDomainKey;
- THashMap<TPathId, TTabletId> HiveBySubDomainKey;
- THashMap<TString, THolder<NSchemeCache::TSchemeCacheNavigate>> NavigateResult;
- THashMap<TTabletId, THolder<TEvHive::TEvResponseHiveDomainStats>> HiveDomainStats;
- THashMap<TTabletId, THolder<TEvHive::TEvResponseHiveNodeStats>> HiveNodeStats;
- NMon::TEvHttpInfo::TPtr Event;
- THashSet<TNodeId> NodeIds;
- THashMap<TNodeId, THolder<TEvWhiteboard::TEvSystemStateResponse>> NodeSysInfo;
- TMap<TNodeId, THolder<TEvWhiteboard::TEvTabletStateResponse>> NodeTabletInfo;
- THolder<TEvInterconnect::TEvNodesInfo> NodesInfo;
- TJsonSettings JsonSettings;
+#include "viewer.h"
+#include "json_pipe_req.h"
+#include "wb_aggregate.h"
+#include "wb_merge.h"
+
+namespace NKikimr {
+namespace NViewer {
+
+using namespace NActors;
+
+class TJsonCompute : public TViewerPipeClient<TJsonCompute> {
+ using TBase = TViewerPipeClient<TJsonCompute>;
+ IViewer* Viewer;
+ THashMap<TString, NKikimrViewer::TTenant> TenantByPath;
+ THashMap<TPathId, NKikimrViewer::TTenant> TenantBySubDomainKey;
+ THashMap<TPathId, TTabletId> HiveBySubDomainKey;
+ THashMap<TString, THolder<NSchemeCache::TSchemeCacheNavigate>> NavigateResult;
+ THashMap<TTabletId, THolder<TEvHive::TEvResponseHiveDomainStats>> HiveDomainStats;
+ THashMap<TTabletId, THolder<TEvHive::TEvResponseHiveNodeStats>> HiveNodeStats;
+ NMon::TEvHttpInfo::TPtr Event;
+ THashSet<TNodeId> NodeIds;
+ THashMap<TNodeId, THolder<TEvWhiteboard::TEvSystemStateResponse>> NodeSysInfo;
+ TMap<TNodeId, THolder<TEvWhiteboard::TEvTabletStateResponse>> NodeTabletInfo;
+ THolder<TEvInterconnect::TEvNodesInfo> NodesInfo;
+ TJsonSettings JsonSettings;
ui32 Timeout = 0;
- TString User;
- TString Path;
- TPathId FilterSubDomain;
- bool Tablets = true;
- TTabletId RootHiveId = 0;
- bool RootHiveRequested = false;
- NKikimrViewer::TComputeInfo Result;
-
-public:
- static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
- return NKikimrServices::TActivity::VIEWER_HANDLER;
- }
-
- TJsonCompute(IViewer* viewer, NMon::TEvHttpInfo::TPtr& ev)
- : Viewer(viewer)
- , Event(ev)
- {}
-
- TString GetDomainId(TPathId pathId) {
- return TStringBuilder() << pathId.OwnerId << '-' << pathId.LocalPathId;
- }
-
- void Bootstrap(const TActorContext& ) {
- const auto& params(Event->Get()->Request.GetParams());
- JsonSettings.EnumAsNumbers = !FromStringWithDefault<bool>(params.Get("enums"), true);
- JsonSettings.UI64AsString = !FromStringWithDefault<bool>(params.Get("ui64"), false);
- InitConfig(params);
- Timeout = FromStringWithDefault<ui32>(params.Get("timeout"), 10000);
- Tablets = FromStringWithDefault<bool>(params.Get("tablets"), Tablets);
- Path = params.Get("path");
-
- SendRequest(GetNameserviceActorId(), new TEvInterconnect::TEvListNodes());
-
- TIntrusivePtr<TDomainsInfo> domains = AppData()->DomainsInfo;
- TIntrusivePtr<TDomainsInfo::TDomain> domain = domains->Domains.begin()->second;
-
- RequestConsoleListTenants();
-
- TString domainPath = "/" + domain->Name;
- if (Path.empty() || domainPath == Path) {
- NKikimrViewer::TTenant& tenant = TenantByPath[domainPath];
- tenant.SetName(domainPath);
- tenant.SetState(Ydb::Cms::GetDatabaseStatusResult::RUNNING);
- tenant.SetType(NKikimrViewer::Domain);
- RequestSchemeCacheNavigate(domainPath);
- }
- RootHiveId = domains->GetHive(domain->DefaultHiveUid);
- if (Requests == 0) {
- ReplyAndPassAway();
- }
-
- Become(&TThis::StateRequested, TDuration::MilliSeconds(Timeout), new TEvents::TEvWakeup());
- }
-
- void PassAway() override {
+ TString User;
+ TString Path;
+ TPathId FilterSubDomain;
+ bool Tablets = true;
+ TTabletId RootHiveId = 0;
+ bool RootHiveRequested = false;
+ NKikimrViewer::TComputeInfo Result;
+
+public:
+ static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
+ return NKikimrServices::TActivity::VIEWER_HANDLER;
+ }
+
+ TJsonCompute(IViewer* viewer, NMon::TEvHttpInfo::TPtr& ev)
+ : Viewer(viewer)
+ , Event(ev)
+ {}
+
+ TString GetDomainId(TPathId pathId) {
+ return TStringBuilder() << pathId.OwnerId << '-' << pathId.LocalPathId;
+ }
+
+ void Bootstrap(const TActorContext& ) {
+ const auto& params(Event->Get()->Request.GetParams());
+ JsonSettings.EnumAsNumbers = !FromStringWithDefault<bool>(params.Get("enums"), true);
+ JsonSettings.UI64AsString = !FromStringWithDefault<bool>(params.Get("ui64"), false);
+ InitConfig(params);
+ Timeout = FromStringWithDefault<ui32>(params.Get("timeout"), 10000);
+ Tablets = FromStringWithDefault<bool>(params.Get("tablets"), Tablets);
+ Path = params.Get("path");
+
+ SendRequest(GetNameserviceActorId(), new TEvInterconnect::TEvListNodes());
+
+ TIntrusivePtr<TDomainsInfo> domains = AppData()->DomainsInfo;
+ TIntrusivePtr<TDomainsInfo::TDomain> domain = domains->Domains.begin()->second;
+
+ RequestConsoleListTenants();
+
+ TString domainPath = "/" + domain->Name;
+ if (Path.empty() || domainPath == Path) {
+ NKikimrViewer::TTenant& tenant = TenantByPath[domainPath];
+ tenant.SetName(domainPath);
+ tenant.SetState(Ydb::Cms::GetDatabaseStatusResult::RUNNING);
+ tenant.SetType(NKikimrViewer::Domain);
+ RequestSchemeCacheNavigate(domainPath);
+ }
+ RootHiveId = domains->GetHive(domain->DefaultHiveUid);
+ if (Requests == 0) {
+ ReplyAndPassAway();
+ }
+
+ Become(&TThis::StateRequested, TDuration::MilliSeconds(Timeout), new TEvents::TEvWakeup());
+ }
+
+ void PassAway() override {
for (const TNodeId nodeId : NodeIds) {
- Send(TActivationContext::InterconnectProxy(nodeId), new TEvents::TEvUnsubscribe);
+ Send(TActivationContext::InterconnectProxy(nodeId), new TEvents::TEvUnsubscribe);
+ }
+ TBase::PassAway();
+ }
+
+ STATEFN(StateRequested) {
+ switch (ev->GetTypeRewrite()) {
+ hFunc(TEvInterconnect::TEvNodesInfo, Handle);
+ hFunc(NConsole::TEvConsole::TEvListTenantsResponse, Handle);
+ hFunc(TEvTxProxySchemeCache::TEvNavigateKeySetResult, Handle);
+ hFunc(TEvHive::TEvResponseHiveDomainStats, Handle);
+ hFunc(TEvHive::TEvResponseHiveNodeStats, Handle);
+ hFunc(TEvWhiteboard::TEvSystemStateResponse, Handle);
+ hFunc(TEvWhiteboard::TEvTabletStateResponse, Handle);
+ hFunc(TEvents::TEvUndelivered, Undelivered);
+ hFunc(TEvInterconnect::TEvNodeDisconnected, Disconnected);
+ hFunc(TEvTabletPipe::TEvClientConnected, TBase::Handle);
+ cFunc(TEvents::TSystem::Wakeup, HandleTimeout);
+ }
+ }
+
+ void Handle(TEvInterconnect::TEvNodesInfo::TPtr &ev) {
+ NodesInfo = ev->Release();
+ RequestDone();
+ }
+
+ void Handle(NConsole::TEvConsole::TEvListTenantsResponse::TPtr& ev) {
+ Ydb::Cms::ListDatabasesResult listTenantsResult;
+ ev->Get()->Record.GetResponse().operation().result().UnpackTo(&listTenantsResult);
+ for (const TString& path : listTenantsResult.paths()) {
+ if (!Path.empty() && path != Path) {
+ continue;
+ }
+ TenantByPath[path];
+ RequestSchemeCacheNavigate(path);
+ }
+ RequestDone();
+ }
+
+ void Handle(TEvHive::TEvResponseHiveDomainStats::TPtr& ev) {
+ for (const NKikimrHive::THiveDomainStats& hiveStat : ev->Get()->Record.GetDomainStats()) {
+ TPathId subDomainKey({hiveStat.GetShardId(), hiveStat.GetPathId()});
+ if (FilterSubDomain && FilterSubDomain != subDomainKey) {
+ continue;
+ }
+ NKikimrViewer::TTenant& tenant = TenantBySubDomainKey[subDomainKey];
+ if (ev->Cookie != HiveBySubDomainKey[subDomainKey]) {
+ continue; // we avoid overwrite of tenant stats by root stats
+ }
+ tenant.SetId(GetDomainId({hiveStat.GetShardId(), hiveStat.GetPathId()}));
+ tenant.MutableStateStats()->CopyFrom(hiveStat.GetStateStats());
+ tenant.MutableMetrics()->CopyFrom(hiveStat.GetMetrics());
+ tenant.MutableNodeIds()->CopyFrom(hiveStat.GetNodeIds());
+ tenant.SetAliveNodes(hiveStat.GetAliveNodes());
+
+ for (TNodeId nodeId : hiveStat.GetNodeIds()) {
+ if (NodeIds.insert(nodeId).second) {
+ TActorId whiteboardServiceId = MakeNodeWhiteboardServiceId(nodeId);
+ THolder<NNodeWhiteboard::TEvWhiteboard::TEvSystemStateRequest> request = MakeHolder<NNodeWhiteboard::TEvWhiteboard::TEvSystemStateRequest>();
+ SendRequest(whiteboardServiceId, request.Release(), IEventHandle::FlagTrackDelivery | IEventHandle::FlagSubscribeOnSession, nodeId);
+ if (Tablets) {
+ THolder<NNodeWhiteboard::TEvWhiteboard::TEvTabletStateRequest> request = MakeHolder<NNodeWhiteboard::TEvWhiteboard::TEvTabletStateRequest>();
+ SendRequest(whiteboardServiceId, request.Release(), IEventHandle::FlagTrackDelivery | IEventHandle::FlagSubscribeOnSession, nodeId);
+ }
+ }
+ }
+ }
+ HiveDomainStats[ev->Cookie] = std::move(ev->Release());
+ RequestDone();
+ }
+
+ void Handle(TEvHive::TEvResponseHiveNodeStats::TPtr& ev) {
+ HiveNodeStats[ev->Cookie] = std::move(ev->Release());
+ RequestDone();
+ }
+
+ void Handle(TEvTxProxySchemeCache::TEvNavigateKeySetResult::TPtr& ev) {
+ if (ev->Get()->Request->ResultSet.size() == 1 && ev->Get()->Request->ResultSet.begin()->Status == NSchemeCache::TSchemeCacheNavigate::EStatus::Ok) {
+ auto domainInfo = ev->Get()->Request->ResultSet.begin()->DomainInfo;
+ ui64 hiveId = domainInfo->Params.GetHive();
+ if (hiveId) {
+ RequestHiveDomainStats(hiveId);
+ RequestHiveNodeStats(hiveId);
+ HiveBySubDomainKey[domainInfo->DomainKey] = hiveId;
+ } else {
+ if (!RootHiveRequested) {
+ RequestHiveDomainStats(RootHiveId);
+ RequestHiveNodeStats(RootHiveId);
+ RootHiveRequested = true;
+ }
+ HiveBySubDomainKey[domainInfo->DomainKey] = RootHiveId;
+ }
+ if (domainInfo->ResourcesDomainKey != domainInfo->DomainKey) {
+ TenantBySubDomainKey[domainInfo->ResourcesDomainKey].SetType(NKikimrViewer::Shared);
+ TenantBySubDomainKey[domainInfo->DomainKey].SetType(NKikimrViewer::Serverless);
+ TenantBySubDomainKey[domainInfo->DomainKey].SetResourceId(GetDomainId(domainInfo->ResourcesDomainKey));
+ }
+
+ TString path = CanonizePath(ev->Get()->Request->ResultSet.begin()->Path);
+ NavigateResult[path] = std::move(ev->Get()->Request);
+ if (Path && Path == path) {
+ FilterSubDomain = domainInfo->DomainKey;
+ }
+ }
+ RequestDone();
+ }
+
+ void Handle(NNodeWhiteboard::TEvWhiteboard::TEvSystemStateResponse::TPtr& ev) {
+ ui32 nodeId = ev.Get()->Cookie;
+ NodeSysInfo[nodeId] = ev->Release();
+ RequestDone();
+ }
+
+ void Handle(NNodeWhiteboard::TEvWhiteboard::TEvTabletStateResponse::TPtr& ev) {
+ ui32 nodeId = ev.Get()->Cookie;
+ NodeTabletInfo[nodeId] = ev->Release();
+ RequestDone();
+ }
+
+ void Undelivered(TEvents::TEvUndelivered::TPtr& ev) {
+ ui32 nodeId = ev.Get()->Cookie;
+ if (ev->Get()->SourceType == NNodeWhiteboard::TEvWhiteboard::EvSystemStateRequest) {
+ if (NodeSysInfo.emplace(nodeId, nullptr).second) {
+ RequestDone();
+ }
+ }
+ if (ev->Get()->SourceType == NNodeWhiteboard::TEvWhiteboard::EvTabletStateRequest) {
+ if (NodeTabletInfo.emplace(nodeId, nullptr).second) {
+ RequestDone();
+ }
+ }
+ }
+
+ void Disconnected(TEvInterconnect::TEvNodeDisconnected::TPtr& ev) {
+ ui32 nodeId = ev->Get()->NodeId;
+ if (NodeSysInfo.emplace(nodeId, nullptr).second) {
+ RequestDone();
+ }
+ if (NodeTabletInfo.emplace(nodeId, nullptr).second) {
+ RequestDone();
+ }
+ }
+
+ void ReplyAndPassAway() {
+ THashMap<TNodeId, TVector<const NKikimrWhiteboard::TTabletStateInfo*>> tabletInfoIndex;
+ THolder<TEvWhiteboard::TEvTabletStateResponse> tabletInfo = MergeWhiteboardResponses(NodeTabletInfo);
+ for (const auto& info : tabletInfo->Record.GetTabletStateInfo()) {
+ tabletInfoIndex[info.GetNodeId()].emplace_back(&info);
+ }
+ THashMap<TNodeId, const NKikimrHive::THiveNodeStats*> hiveNodeStatsIndex;
+ auto itRootHiveNodeStats = HiveNodeStats.find(RootHiveId);
+ if (itRootHiveNodeStats != HiveNodeStats.end()) {
+ for (const auto& stats : itRootHiveNodeStats->second->Record.GetNodeStats()) {
+ hiveNodeStatsIndex[stats.GetNodeId()] = &stats;
+ }
+ }
+ for (const auto& prStats : HiveNodeStats) {
+ if (prStats.first != RootHiveId) {
+ for (const auto& stats : prStats.second->Record.GetNodeStats()) {
+ hiveNodeStatsIndex[stats.GetNodeId()] = &stats;
+ }
+ }
+ }
+ for (const std::pair<const TString, NKikimrViewer::TTenant>& prTenant : TenantByPath) {
+ const TString& path = prTenant.first;
+ NKikimrViewer::TComputeTenantInfo& computeTenantInfo = *Result.AddTenants();
+ computeTenantInfo.SetName(path);
+ auto itNavigate = NavigateResult.find(path);
+ if (itNavigate != NavigateResult.end()) {
+ NSchemeCache::TSchemeCacheNavigate::TEntry entry = itNavigate->second->ResultSet.front();
+ TPathId subDomainKey(entry.DomainInfo->DomainKey);
+ const NKikimrViewer::TTenant& tenantBySubDomainKey(TenantBySubDomainKey[subDomainKey]);
+ for (TNodeId nodeId : tenantBySubDomainKey.GetNodeIds()) {
+ NKikimrViewer::TComputeNodeInfo& computeNodeInfo = *computeTenantInfo.AddNodes();
+ computeNodeInfo.SetNodeId(nodeId);
+ auto itSysInfo = NodeSysInfo.find(nodeId);
+ if (itSysInfo != NodeSysInfo.end()) {
+ if (itSysInfo->second != nullptr && itSysInfo->second->Record.SystemStateInfoSize() == 1) {
+ const NKikimrWhiteboard::TSystemStateInfo& sysInfo = itSysInfo->second->Record.GetSystemStateInfo(0);
+ if (sysInfo.HasStartTime()) {
+ computeNodeInfo.SetStartTime(sysInfo.GetStartTime());
+ }
+ if (sysInfo.HasChangeTime()) {
+ computeNodeInfo.SetChangeTime(sysInfo.GetChangeTime());
+ }
+ computeNodeInfo.MutableSystemLocation()->MergeFrom(sysInfo.GetSystemLocation());
+ computeNodeInfo.MutableLoadAverage()->MergeFrom(sysInfo.GetLoadAverage());
+ if (sysInfo.HasNumberOfCpus()) {
+ computeNodeInfo.SetNumberOfCpus(sysInfo.GetNumberOfCpus());
+ }
+ // TODO(xenoxeno)
+ if (sysInfo.HasSystemState()) {
+ computeNodeInfo.SetOverall(GetViewerFlag(sysInfo.GetSystemState()));
+ }
+ if (sysInfo.HasNodeId()) {
+ computeNodeInfo.SetNodeId(sysInfo.GetNodeId());
+ }
+ if (sysInfo.HasDataCenter()) {
+ computeNodeInfo.SetDataCenter(sysInfo.GetDataCenter());
+ }
+ if (sysInfo.HasRack()) {
+ computeNodeInfo.SetRack(sysInfo.GetRack());
+ }
+ if (sysInfo.HasHost()) {
+ computeNodeInfo.SetHost(sysInfo.GetHost());
+ }
+ if (sysInfo.HasVersion()) {
+ computeNodeInfo.SetVersion(sysInfo.GetVersion());
+ }
+ if (sysInfo.HasMemoryUsed()) {
+ computeNodeInfo.SetMemoryUsed(sysInfo.GetMemoryUsed());
+ }
+ if (sysInfo.HasMemoryLimit()) {
+ computeNodeInfo.SetMemoryLimit(sysInfo.GetMemoryLimit());
+ }
+ computeNodeInfo.MutablePoolStats()->MergeFrom(sysInfo.GetPoolStats());
+ computeNodeInfo.MutableEndpoints()->MergeFrom(sysInfo.GetEndpoints());
+ computeNodeInfo.MutableRoles()->MergeFrom(sysInfo.GetRoles());
+
+ }
+ }
+ auto itTabletInfo = tabletInfoIndex.find(nodeId);
+ if (itTabletInfo != tabletInfoIndex.end()) {
+ THashMap<std::pair<NKikimrTabletBase::TTabletTypes::EType, NKikimrViewer::EFlag>, NKikimrViewer::TTabletStateInfo> tablets;
+ for (const auto* pTabletInfo : itTabletInfo->second) {
+ const auto& tabletInfo = *pTabletInfo;
+ if (tabletInfo.GetState() != NKikimrWhiteboard::TTabletStateInfo::Deleted) {
+ NKikimrViewer::EFlag state = GetFlagFromTabletState(tabletInfo.GetState());
+ auto& tablet = tablets[std::make_pair(tabletInfo.GetType(), state)];
+ tablet.SetCount(tablet.GetCount() + 1);
+ }
+ }
+ for (const auto& [prTypeState, tabletInfo] : tablets) {
+ NKikimrViewer::TTabletStateInfo& tablet = *computeNodeInfo.AddTablets();
+ tablet.MergeFrom(tabletInfo);
+ tablet.SetType(NKikimrTabletBase::TTabletTypes::EType_Name(prTypeState.first));
+ tablet.SetState(prTypeState.second);
+ }
+ }
+ auto itHiveNodeStats = hiveNodeStatsIndex.find(nodeId);
+ if (itHiveNodeStats != hiveNodeStatsIndex.end()) {
+ computeNodeInfo.MutableMetrics()->CopyFrom(itHiveNodeStats->second->GetMetrics());
+ }
+ }
+ }
+
+ // TODO(xenoxeno)
+ computeTenantInfo.SetOverall(NKikimrViewer::EFlag::Green);
}
- TBase::PassAway();
- }
-
- STATEFN(StateRequested) {
- switch (ev->GetTypeRewrite()) {
- hFunc(TEvInterconnect::TEvNodesInfo, Handle);
- hFunc(NConsole::TEvConsole::TEvListTenantsResponse, Handle);
- hFunc(TEvTxProxySchemeCache::TEvNavigateKeySetResult, Handle);
- hFunc(TEvHive::TEvResponseHiveDomainStats, Handle);
- hFunc(TEvHive::TEvResponseHiveNodeStats, Handle);
- hFunc(TEvWhiteboard::TEvSystemStateResponse, Handle);
- hFunc(TEvWhiteboard::TEvTabletStateResponse, Handle);
- hFunc(TEvents::TEvUndelivered, Undelivered);
- hFunc(TEvInterconnect::TEvNodeDisconnected, Disconnected);
- hFunc(TEvTabletPipe::TEvClientConnected, TBase::Handle);
- cFunc(TEvents::TSystem::Wakeup, HandleTimeout);
- }
- }
-
- void Handle(TEvInterconnect::TEvNodesInfo::TPtr &ev) {
- NodesInfo = ev->Release();
- RequestDone();
- }
-
- void Handle(NConsole::TEvConsole::TEvListTenantsResponse::TPtr& ev) {
- Ydb::Cms::ListDatabasesResult listTenantsResult;
- ev->Get()->Record.GetResponse().operation().result().UnpackTo(&listTenantsResult);
- for (const TString& path : listTenantsResult.paths()) {
- if (!Path.empty() && path != Path) {
- continue;
- }
- TenantByPath[path];
- RequestSchemeCacheNavigate(path);
- }
- RequestDone();
- }
-
- void Handle(TEvHive::TEvResponseHiveDomainStats::TPtr& ev) {
- for (const NKikimrHive::THiveDomainStats& hiveStat : ev->Get()->Record.GetDomainStats()) {
- TPathId subDomainKey({hiveStat.GetShardId(), hiveStat.GetPathId()});
- if (FilterSubDomain && FilterSubDomain != subDomainKey) {
- continue;
- }
- NKikimrViewer::TTenant& tenant = TenantBySubDomainKey[subDomainKey];
- if (ev->Cookie != HiveBySubDomainKey[subDomainKey]) {
- continue; // we avoid overwrite of tenant stats by root stats
- }
- tenant.SetId(GetDomainId({hiveStat.GetShardId(), hiveStat.GetPathId()}));
- tenant.MutableStateStats()->CopyFrom(hiveStat.GetStateStats());
- tenant.MutableMetrics()->CopyFrom(hiveStat.GetMetrics());
- tenant.MutableNodeIds()->CopyFrom(hiveStat.GetNodeIds());
- tenant.SetAliveNodes(hiveStat.GetAliveNodes());
-
- for (TNodeId nodeId : hiveStat.GetNodeIds()) {
- if (NodeIds.insert(nodeId).second) {
- TActorId whiteboardServiceId = MakeNodeWhiteboardServiceId(nodeId);
- THolder<NNodeWhiteboard::TEvWhiteboard::TEvSystemStateRequest> request = MakeHolder<NNodeWhiteboard::TEvWhiteboard::TEvSystemStateRequest>();
- SendRequest(whiteboardServiceId, request.Release(), IEventHandle::FlagTrackDelivery | IEventHandle::FlagSubscribeOnSession, nodeId);
- if (Tablets) {
- THolder<NNodeWhiteboard::TEvWhiteboard::TEvTabletStateRequest> request = MakeHolder<NNodeWhiteboard::TEvWhiteboard::TEvTabletStateRequest>();
- SendRequest(whiteboardServiceId, request.Release(), IEventHandle::FlagTrackDelivery | IEventHandle::FlagSubscribeOnSession, nodeId);
- }
- }
- }
- }
- HiveDomainStats[ev->Cookie] = std::move(ev->Release());
- RequestDone();
- }
-
- void Handle(TEvHive::TEvResponseHiveNodeStats::TPtr& ev) {
- HiveNodeStats[ev->Cookie] = std::move(ev->Release());
- RequestDone();
- }
-
- void Handle(TEvTxProxySchemeCache::TEvNavigateKeySetResult::TPtr& ev) {
- if (ev->Get()->Request->ResultSet.size() == 1 && ev->Get()->Request->ResultSet.begin()->Status == NSchemeCache::TSchemeCacheNavigate::EStatus::Ok) {
- auto domainInfo = ev->Get()->Request->ResultSet.begin()->DomainInfo;
- ui64 hiveId = domainInfo->Params.GetHive();
- if (hiveId) {
- RequestHiveDomainStats(hiveId);
- RequestHiveNodeStats(hiveId);
- HiveBySubDomainKey[domainInfo->DomainKey] = hiveId;
- } else {
- if (!RootHiveRequested) {
- RequestHiveDomainStats(RootHiveId);
- RequestHiveNodeStats(RootHiveId);
- RootHiveRequested = true;
- }
- HiveBySubDomainKey[domainInfo->DomainKey] = RootHiveId;
- }
- if (domainInfo->ResourcesDomainKey != domainInfo->DomainKey) {
- TenantBySubDomainKey[domainInfo->ResourcesDomainKey].SetType(NKikimrViewer::Shared);
- TenantBySubDomainKey[domainInfo->DomainKey].SetType(NKikimrViewer::Serverless);
- TenantBySubDomainKey[domainInfo->DomainKey].SetResourceId(GetDomainId(domainInfo->ResourcesDomainKey));
- }
-
- TString path = CanonizePath(ev->Get()->Request->ResultSet.begin()->Path);
- NavigateResult[path] = std::move(ev->Get()->Request);
- if (Path && Path == path) {
- FilterSubDomain = domainInfo->DomainKey;
- }
- }
- RequestDone();
- }
-
- void Handle(NNodeWhiteboard::TEvWhiteboard::TEvSystemStateResponse::TPtr& ev) {
- ui32 nodeId = ev.Get()->Cookie;
- NodeSysInfo[nodeId] = ev->Release();
- RequestDone();
- }
-
- void Handle(NNodeWhiteboard::TEvWhiteboard::TEvTabletStateResponse::TPtr& ev) {
- ui32 nodeId = ev.Get()->Cookie;
- NodeTabletInfo[nodeId] = ev->Release();
- RequestDone();
- }
-
- void Undelivered(TEvents::TEvUndelivered::TPtr& ev) {
- ui32 nodeId = ev.Get()->Cookie;
- if (ev->Get()->SourceType == NNodeWhiteboard::TEvWhiteboard::EvSystemStateRequest) {
- if (NodeSysInfo.emplace(nodeId, nullptr).second) {
- RequestDone();
- }
- }
- if (ev->Get()->SourceType == NNodeWhiteboard::TEvWhiteboard::EvTabletStateRequest) {
- if (NodeTabletInfo.emplace(nodeId, nullptr).second) {
- RequestDone();
- }
- }
- }
-
- void Disconnected(TEvInterconnect::TEvNodeDisconnected::TPtr& ev) {
- ui32 nodeId = ev->Get()->NodeId;
- if (NodeSysInfo.emplace(nodeId, nullptr).second) {
- RequestDone();
- }
- if (NodeTabletInfo.emplace(nodeId, nullptr).second) {
- RequestDone();
- }
- }
-
- void ReplyAndPassAway() {
- THashMap<TNodeId, TVector<const NKikimrWhiteboard::TTabletStateInfo*>> tabletInfoIndex;
- THolder<TEvWhiteboard::TEvTabletStateResponse> tabletInfo = MergeWhiteboardResponses(NodeTabletInfo);
- for (const auto& info : tabletInfo->Record.GetTabletStateInfo()) {
- tabletInfoIndex[info.GetNodeId()].emplace_back(&info);
- }
- THashMap<TNodeId, const NKikimrHive::THiveNodeStats*> hiveNodeStatsIndex;
- auto itRootHiveNodeStats = HiveNodeStats.find(RootHiveId);
- if (itRootHiveNodeStats != HiveNodeStats.end()) {
- for (const auto& stats : itRootHiveNodeStats->second->Record.GetNodeStats()) {
- hiveNodeStatsIndex[stats.GetNodeId()] = &stats;
- }
- }
- for (const auto& prStats : HiveNodeStats) {
- if (prStats.first != RootHiveId) {
- for (const auto& stats : prStats.second->Record.GetNodeStats()) {
- hiveNodeStatsIndex[stats.GetNodeId()] = &stats;
- }
- }
- }
- for (const std::pair<const TString, NKikimrViewer::TTenant>& prTenant : TenantByPath) {
- const TString& path = prTenant.first;
- NKikimrViewer::TComputeTenantInfo& computeTenantInfo = *Result.AddTenants();
- computeTenantInfo.SetName(path);
- auto itNavigate = NavigateResult.find(path);
- if (itNavigate != NavigateResult.end()) {
- NSchemeCache::TSchemeCacheNavigate::TEntry entry = itNavigate->second->ResultSet.front();
- TPathId subDomainKey(entry.DomainInfo->DomainKey);
- const NKikimrViewer::TTenant& tenantBySubDomainKey(TenantBySubDomainKey[subDomainKey]);
- for (TNodeId nodeId : tenantBySubDomainKey.GetNodeIds()) {
- NKikimrViewer::TComputeNodeInfo& computeNodeInfo = *computeTenantInfo.AddNodes();
- computeNodeInfo.SetNodeId(nodeId);
- auto itSysInfo = NodeSysInfo.find(nodeId);
- if (itSysInfo != NodeSysInfo.end()) {
- if (itSysInfo->second != nullptr && itSysInfo->second->Record.SystemStateInfoSize() == 1) {
- const NKikimrWhiteboard::TSystemStateInfo& sysInfo = itSysInfo->second->Record.GetSystemStateInfo(0);
- if (sysInfo.HasStartTime()) {
- computeNodeInfo.SetStartTime(sysInfo.GetStartTime());
- }
- if (sysInfo.HasChangeTime()) {
- computeNodeInfo.SetChangeTime(sysInfo.GetChangeTime());
- }
- computeNodeInfo.MutableSystemLocation()->MergeFrom(sysInfo.GetSystemLocation());
- computeNodeInfo.MutableLoadAverage()->MergeFrom(sysInfo.GetLoadAverage());
- if (sysInfo.HasNumberOfCpus()) {
- computeNodeInfo.SetNumberOfCpus(sysInfo.GetNumberOfCpus());
- }
- // TODO(xenoxeno)
- if (sysInfo.HasSystemState()) {
- computeNodeInfo.SetOverall(GetViewerFlag(sysInfo.GetSystemState()));
- }
- if (sysInfo.HasNodeId()) {
- computeNodeInfo.SetNodeId(sysInfo.GetNodeId());
- }
- if (sysInfo.HasDataCenter()) {
- computeNodeInfo.SetDataCenter(sysInfo.GetDataCenter());
- }
- if (sysInfo.HasRack()) {
- computeNodeInfo.SetRack(sysInfo.GetRack());
- }
- if (sysInfo.HasHost()) {
- computeNodeInfo.SetHost(sysInfo.GetHost());
- }
- if (sysInfo.HasVersion()) {
- computeNodeInfo.SetVersion(sysInfo.GetVersion());
- }
- if (sysInfo.HasMemoryUsed()) {
- computeNodeInfo.SetMemoryUsed(sysInfo.GetMemoryUsed());
- }
- if (sysInfo.HasMemoryLimit()) {
- computeNodeInfo.SetMemoryLimit(sysInfo.GetMemoryLimit());
- }
- computeNodeInfo.MutablePoolStats()->MergeFrom(sysInfo.GetPoolStats());
- computeNodeInfo.MutableEndpoints()->MergeFrom(sysInfo.GetEndpoints());
- computeNodeInfo.MutableRoles()->MergeFrom(sysInfo.GetRoles());
-
- }
- }
- auto itTabletInfo = tabletInfoIndex.find(nodeId);
- if (itTabletInfo != tabletInfoIndex.end()) {
- THashMap<std::pair<NKikimrTabletBase::TTabletTypes::EType, NKikimrViewer::EFlag>, NKikimrViewer::TTabletStateInfo> tablets;
- for (const auto* pTabletInfo : itTabletInfo->second) {
- const auto& tabletInfo = *pTabletInfo;
- if (tabletInfo.GetState() != NKikimrWhiteboard::TTabletStateInfo::Deleted) {
- NKikimrViewer::EFlag state = GetFlagFromTabletState(tabletInfo.GetState());
- auto& tablet = tablets[std::make_pair(tabletInfo.GetType(), state)];
- tablet.SetCount(tablet.GetCount() + 1);
- }
- }
- for (const auto& [prTypeState, tabletInfo] : tablets) {
- NKikimrViewer::TTabletStateInfo& tablet = *computeNodeInfo.AddTablets();
- tablet.MergeFrom(tabletInfo);
- tablet.SetType(NKikimrTabletBase::TTabletTypes::EType_Name(prTypeState.first));
- tablet.SetState(prTypeState.second);
- }
- }
- auto itHiveNodeStats = hiveNodeStatsIndex.find(nodeId);
- if (itHiveNodeStats != hiveNodeStatsIndex.end()) {
- computeNodeInfo.MutableMetrics()->CopyFrom(itHiveNodeStats->second->GetMetrics());
- }
- }
- }
-
- // TODO(xenoxeno)
- computeTenantInfo.SetOverall(NKikimrViewer::EFlag::Green);
- }
-
- // TODO(xenoxeno)
- Result.SetOverall(NKikimrViewer::EFlag::Green);
- TStringStream json;
- TProtoToJson::ProtoToJson(json, Result, JsonSettings);
- Send(Event->Sender, new NMon::TEvHttpInfoRes(Viewer->GetHTTPOKJSON() + json.Str(), 0, NMon::IEvHttpInfoRes::EContentType::Custom));
- PassAway();
- }
-
- void HandleTimeout() {
- Result.AddErrors("Timeout occurred");
- ReplyAndPassAway();
- }
-};
-
-template <>
-struct TJsonRequestSchema<TJsonCompute> {
- static TString GetSchema() {
- TStringStream stream;
- TProtoToJson::ProtoToJsonSchema<NKikimrViewer::TNetInfo>(stream);
- return stream.Str();
- }
-};
-
-template <>
-struct TJsonRequestParameters<TJsonCompute> {
- static TString GetParameters() {
- return R"___([{"name":"path","in":"query","description":"schema path","required":false,"type":"string"},
- {"name":"enums","in":"query","description":"convert enums to strings","required":false,"type":"boolean"},
- {"name":"ui64","in":"query","description":"return ui64 as number","required":false,"type":"boolean"},
- {"name":"timeout","in":"query","description":"timeout in ms","required":false,"type":"integer"}])___";
- }
-};
-
-template <>
-struct TJsonRequestSummary<TJsonCompute> {
- static TString GetSummary() {
- return "\"Database compute information\"";
- }
-};
-
-template <>
-struct TJsonRequestDescription<TJsonCompute> {
- static TString GetDescription() {
- return "\"Returns information about compute layer of database\"";
- }
-};
-
-}
-}
+
+ // TODO(xenoxeno)
+ Result.SetOverall(NKikimrViewer::EFlag::Green);
+ TStringStream json;
+ TProtoToJson::ProtoToJson(json, Result, JsonSettings);
+ Send(Event->Sender, new NMon::TEvHttpInfoRes(Viewer->GetHTTPOKJSON() + json.Str(), 0, NMon::IEvHttpInfoRes::EContentType::Custom));
+ PassAway();
+ }
+
+ void HandleTimeout() {
+ Result.AddErrors("Timeout occurred");
+ ReplyAndPassAway();
+ }
+};
+
+template <>
+struct TJsonRequestSchema<TJsonCompute> {
+ static TString GetSchema() {
+ TStringStream stream;
+ TProtoToJson::ProtoToJsonSchema<NKikimrViewer::TNetInfo>(stream);
+ return stream.Str();
+ }
+};
+
+template <>
+struct TJsonRequestParameters<TJsonCompute> {
+ static TString GetParameters() {
+ return R"___([{"name":"path","in":"query","description":"schema path","required":false,"type":"string"},
+ {"name":"enums","in":"query","description":"convert enums to strings","required":false,"type":"boolean"},
+ {"name":"ui64","in":"query","description":"return ui64 as number","required":false,"type":"boolean"},
+ {"name":"timeout","in":"query","description":"timeout in ms","required":false,"type":"integer"}])___";
+ }
+};
+
+template <>
+struct TJsonRequestSummary<TJsonCompute> {
+ static TString GetSummary() {
+ return "\"Database compute information\"";
+ }
+};
+
+template <>
+struct TJsonRequestDescription<TJsonCompute> {
+ static TString GetDescription() {
+ return "\"Returns information about compute layer of database\"";
+ }
+};
+
+}
+}
diff --git a/ydb/core/viewer/json_config.h b/ydb/core/viewer/json_config.h
index 220ef6efe9d..7e501d5afbf 100644
--- a/ydb/core/viewer/json_config.h
+++ b/ydb/core/viewer/json_config.h
@@ -1,67 +1,67 @@
-#pragma once
+#pragma once
#include <library/cpp/actors/core/actor_bootstrapped.h>
#include <library/cpp/actors/core/interconnect.h>
#include <library/cpp/actors/core/mon.h>
#include <ydb/core/base/hive.h>
#include <ydb/core/base/tablet_pipe.h>
#include <ydb/core/protos/services.pb.h>
-#include "viewer.h"
-
-namespace NKikimr {
-namespace NViewer {
-
-using namespace NActors;
-
-class TJsonConfig : public TActorBootstrapped<TJsonConfig> {
- using TBase = TActorBootstrapped<TJsonConfig>;
- IViewer* Viewer;
- NMon::TEvHttpInfo::TPtr Event;
-
-public:
+#include "viewer.h"
+
+namespace NKikimr {
+namespace NViewer {
+
+using namespace NActors;
+
+class TJsonConfig : public TActorBootstrapped<TJsonConfig> {
+ using TBase = TActorBootstrapped<TJsonConfig>;
+ IViewer* Viewer;
+ NMon::TEvHttpInfo::TPtr Event;
+
+public:
static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
return NKikimrServices::TActivity::VIEWER_HANDLER;
- }
-
+ }
+
TJsonConfig(IViewer *viewer, NMon::TEvHttpInfo::TPtr &ev)
- : Viewer(viewer)
- , Event(ev)
- {}
-
- void Bootstrap(const TActorContext& ctx) {
- const TKikimrRunConfig& kikimrRunConfig = Viewer->GetKikimrRunConfig();
- TStringStream json;
- auto config = kikimrRunConfig.AppConfig;
- config.MutableNameserviceConfig()->ClearClusterUUID();
- config.MutableNameserviceConfig()->ClearAcceptUUID();
- config.ClearAuthConfig();
- TProtoToJson::ProtoToJson(json, config);
- ctx.Send(Event->Sender, new NMon::TEvHttpInfoRes(Viewer->GetHTTPOKJSON() + json.Str(), 0, NMon::IEvHttpInfoRes::EContentType::Custom));
- Die(ctx);
- }
-};
-
-template <>
-struct TJsonRequestSchema<TJsonConfig> {
+ : Viewer(viewer)
+ , Event(ev)
+ {}
+
+ void Bootstrap(const TActorContext& ctx) {
+ const TKikimrRunConfig& kikimrRunConfig = Viewer->GetKikimrRunConfig();
+ TStringStream json;
+ auto config = kikimrRunConfig.AppConfig;
+ config.MutableNameserviceConfig()->ClearClusterUUID();
+ config.MutableNameserviceConfig()->ClearAcceptUUID();
+ config.ClearAuthConfig();
+ TProtoToJson::ProtoToJson(json, config);
+ ctx.Send(Event->Sender, new NMon::TEvHttpInfoRes(Viewer->GetHTTPOKJSON() + json.Str(), 0, NMon::IEvHttpInfoRes::EContentType::Custom));
+ Die(ctx);
+ }
+};
+
+template <>
+struct TJsonRequestSchema<TJsonConfig> {
static TString GetSchema() {
- TStringStream stream;
- TProtoToJson::ProtoToJsonSchema<NKikimrConfig::TAppConfig>(stream);
- return stream.Str();
- }
-};
-
-template <>
-struct TJsonRequestSummary<TJsonConfig> {
+ TStringStream stream;
+ TProtoToJson::ProtoToJsonSchema<NKikimrConfig::TAppConfig>(stream);
+ return stream.Str();
+ }
+};
+
+template <>
+struct TJsonRequestSummary<TJsonConfig> {
static TString GetSummary() {
- return "\"Configuration\"";
- }
-};
-
-template <>
-struct TJsonRequestDescription<TJsonConfig> {
+ return "\"Configuration\"";
+ }
+};
+
+template <>
+struct TJsonRequestDescription<TJsonConfig> {
static TString GetDescription() {
- return "\"Returns configuration\"";
- }
-};
-
-}
-}
+ return "\"Returns configuration\"";
+ }
+};
+
+}
+}
diff --git a/ydb/core/viewer/json_content.h b/ydb/core/viewer/json_content.h
index c8b4eebb160..79b230f1288 100644
--- a/ydb/core/viewer/json_content.h
+++ b/ydb/core/viewer/json_content.h
@@ -1,40 +1,40 @@
-#pragma once
-#include <unordered_map>
+#pragma once
+#include <unordered_map>
#include <library/cpp/actors/core/actor_bootstrapped.h>
#include <library/cpp/actors/core/interconnect.h>
#include <library/cpp/actors/core/mon.h>
#include <ydb/core/node_whiteboard/node_whiteboard.h>
-#include "viewer.h"
-#include "browse.h"
-
-namespace NKikimr {
-namespace NViewer {
-
-using namespace NActors;
-using ::google::protobuf::FieldDescriptor;
-
-class TJsonContent : public TActorBootstrapped<TJsonContent> {
- using TThis = TJsonContent;
- using TBase = TActorBootstrapped<TJsonContent>;
+#include "viewer.h"
+#include "browse.h"
+
+namespace NKikimr {
+namespace NViewer {
+
+using namespace NActors;
+using ::google::protobuf::FieldDescriptor;
+
+class TJsonContent : public TActorBootstrapped<TJsonContent> {
+ using TThis = TJsonContent;
+ using TBase = TActorBootstrapped<TJsonContent>;
IViewer* Viewer;
TActorId Initiator;
- NMon::TEvHttpInfo::TPtr Event;
-
+ NMon::TEvHttpInfo::TPtr Event;
+
IViewer::TContentRequestContext ContentRequestContext;
TInstant BrowseStarted;
-public:
+public:
static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
return NKikimrServices::TActivity::VIEWER_HANDLER;
- }
-
+ }
+
TJsonContent(IViewer* viewer, NMon::TEvHttpInfo::TPtr& ev)
: Viewer(viewer)
, Initiator(ev->Sender)
- , Event(ev)
- {}
-
+ , Event(ev)
+ {}
+
STFUNC(StateWaitingBrowse) {
switch (ev->GetTypeRewrite()) {
HFunc(NViewerEvents::TEvBrowseResponse, HandleBrowseResponse);
@@ -45,9 +45,9 @@ public:
public:
void Bootstrap(const TActorContext& ctx) {
BuildRequestContext(&Event->Get()->Request, ContentRequestContext);
- if (!Event->Get()->UserToken.empty()) {
- ContentRequestContext.UserToken = Event->Get()->UserToken;
- }
+ if (!Event->Get()->UserToken.empty()) {
+ ContentRequestContext.UserToken = Event->Get()->UserToken;
+ }
BrowseStarted = ctx.Now();
ctx.RegisterWithSameMailbox(new TBrowse(Viewer, ctx.SelfID, ContentRequestContext.Path, Event->Get()->UserToken));
@@ -64,8 +64,8 @@ private:
IViewer::TContentRequestContext& reqCtx) {
if (!httpRequest) {
return;
- }
-
+ }
+
const auto& params = httpRequest->GetParams();
auto post = httpRequest->GetPostContent();
@@ -85,19 +85,19 @@ private:
reqCtx.Offset = FromStringWithDefault<ui32>(params.Get("offset"), reqCtx.Offset);
reqCtx.Key = post;
- if (params.Has("key")) {
+ if (params.Has("key")) {
reqCtx.Key = params.Get("key");
- }
+ }
reqCtx.Path = params.Get("path");
- }
-
+ }
+
void HandleBrowseResponse(NViewerEvents::TEvBrowseResponse::TPtr &ev, const TActorContext &ctx) {
NViewerEvents::TEvBrowseResponse& event = *ev->Get();
if (!event.Error.empty()) {
return SendErrorReplyAndDie(event.Error, ctx);
- }
+ }
auto type = event.BrowseInfo.GetType();
auto contentHandler = Viewer->GetContentHandler(type);
@@ -119,12 +119,12 @@ private:
// spawn content retrieval actor
ctx.RegisterWithSameMailbox(contentHandler(Initiator, ContentRequestContext));
Die(ctx);
- }
-
+ }
+
void HandleBrowseTimeout(const TActorContext& ctx) {
- return SendErrorReplyAndDie(Viewer->GetHTTPGATEWAYTIMEOUT(), ctx);
- }
-
+ return SendErrorReplyAndDie(Viewer->GetHTTPGATEWAYTIMEOUT(), ctx);
+ }
+
void SendErrorReplyAndDie(const TString& error, const TActorContext& ctx) {
ctx.Send(
Initiator,
@@ -133,37 +133,37 @@ private:
0,
NMon::IEvHttpInfoRes::EContentType::Custom));
- Die(ctx);
- }
-};
-
-template <>
-struct TJsonRequestParameters<TJsonContent> {
- static TString GetParameters() {
- return R"___([{"name":"path","in":"query","description":"schema path","required":true,"type":"string"},
- {"name":"enums","in":"query","description":"convert enums to strings","required":false,"type":"boolean"},
- {"name":"ui64","in":"query","description":"return ui64 as number","required":false,"type":"boolean"},
- {"name":"key","in":"query","description":"key for positioning","required":false,"type":"string"},
- {"name":"limit","in":"query","description":"rows limit","required":false,"type":"integer"},
- {"name":"offset","in":"query","description":"offset in rows","required":false,"type":"integer"},
- {"name":"timeout","in":"query","description":"timeout in ms","required":false,"type":"integer"}])___";
- }
-};
-
-template <>
-struct TJsonRequestSummary<TJsonContent> {
- static TString GetSummary() {
- return "\"Schema content preview\"";
- }
-};
-
-template <>
-struct TJsonRequestDescription<TJsonContent> {
- static TString GetDescription() {
- return "\"Return schema preview\"";
- }
-};
-
-
-}
-}
+ Die(ctx);
+ }
+};
+
+template <>
+struct TJsonRequestParameters<TJsonContent> {
+ static TString GetParameters() {
+ return R"___([{"name":"path","in":"query","description":"schema path","required":true,"type":"string"},
+ {"name":"enums","in":"query","description":"convert enums to strings","required":false,"type":"boolean"},
+ {"name":"ui64","in":"query","description":"return ui64 as number","required":false,"type":"boolean"},
+ {"name":"key","in":"query","description":"key for positioning","required":false,"type":"string"},
+ {"name":"limit","in":"query","description":"rows limit","required":false,"type":"integer"},
+ {"name":"offset","in":"query","description":"offset in rows","required":false,"type":"integer"},
+ {"name":"timeout","in":"query","description":"timeout in ms","required":false,"type":"integer"}])___";
+ }
+};
+
+template <>
+struct TJsonRequestSummary<TJsonContent> {
+ static TString GetSummary() {
+ return "\"Schema content preview\"";
+ }
+};
+
+template <>
+struct TJsonRequestDescription<TJsonContent> {
+ static TString GetDescription() {
+ return "\"Return schema preview\"";
+ }
+};
+
+
+}
+}
diff --git a/ydb/core/viewer/json_counters.h b/ydb/core/viewer/json_counters.h
index 80b80ea7068..cac1e0885c4 100644
--- a/ydb/core/viewer/json_counters.h
+++ b/ydb/core/viewer/json_counters.h
@@ -1,435 +1,435 @@
-#pragma once
-#include <unordered_map>
+#pragma once
+#include <unordered_map>
#include <library/cpp/actors/core/actor_bootstrapped.h>
#include <library/cpp/actors/core/interconnect.h>
#include <library/cpp/actors/core/mon.h>
#include <ydb/core/node_whiteboard/node_whiteboard.h>
-#include "viewer.h"
-#include "json_tabletinfo.h"
-
-namespace NKikimr {
-namespace NViewer {
-
-using namespace NActors;
-using ::google::protobuf::FieldDescriptor;
-
-class TJsonCounters : public TActorBootstrapped<TJsonCounters> {
- using TThis = TJsonCounters;
- using TBase = TActorBootstrapped<TJsonCounters>;
- IViewer* Viewer;
+#include "viewer.h"
+#include "json_tabletinfo.h"
+
+namespace NKikimr {
+namespace NViewer {
+
+using namespace NActors;
+using ::google::protobuf::FieldDescriptor;
+
+class TJsonCounters : public TActorBootstrapped<TJsonCounters> {
+ using TThis = TJsonCounters;
+ using TBase = TActorBootstrapped<TJsonCounters>;
+ IViewer* Viewer;
TActorId Initiator;
- ui32 Requested;
- ui32 Received;
- THolder<TEvInterconnect::TEvNodesInfo> NodesInfo;
+ ui32 Requested;
+ ui32 Received;
+ THolder<TEvInterconnect::TEvNodesInfo> NodesInfo;
TMap<ui32, THolder<TEvWhiteboard::TEvVDiskStateResponse>> VDiskInfo;
TMap<ui32, THolder<TEvWhiteboard::TEvPDiskStateResponse>> PDiskInfo;
TMap<ui32, THolder<TEvWhiteboard::TEvTabletStateResponse>> TabletInfo;
TMap<ui32, THolder<TEvWhiteboard::TEvBSGroupStateResponse>> BSGroupInfo;
-
-public:
+
+public:
static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
return NKikimrServices::TActivity::VIEWER_HANDLER;
- }
-
- TJsonCounters(IViewer* viewer, NMon::TEvHttpInfo::TPtr& ev)
- : Viewer(viewer)
- , Initiator(ev->Sender)
- , Requested(0)
- , Received(0)
- {}
-
- void Bootstrap(const TActorContext& ctx) {
+ }
+
+ TJsonCounters(IViewer* viewer, NMon::TEvHttpInfo::TPtr& ev)
+ : Viewer(viewer)
+ , Initiator(ev->Sender)
+ , Requested(0)
+ , Received(0)
+ {}
+
+ void Bootstrap(const TActorContext& ctx) {
const TActorId nameserviceId = GetNameserviceActorId();
- ctx.Send(nameserviceId, new TEvInterconnect::TEvListNodes());
- TBase::Become(&TThis::StateRequestedBrowse);
- ctx.Schedule(TDuration::Seconds(60), new TEvents::TEvWakeup());
- }
-
- void Die(const TActorContext& ctx) override {
- if (NodesInfo != nullptr) {
- for (const auto& ni : NodesInfo->Nodes) {
+ ctx.Send(nameserviceId, new TEvInterconnect::TEvListNodes());
+ TBase::Become(&TThis::StateRequestedBrowse);
+ ctx.Schedule(TDuration::Seconds(60), new TEvents::TEvWakeup());
+ }
+
+ void Die(const TActorContext& ctx) override {
+ if (NodesInfo != nullptr) {
+ for (const auto& ni : NodesInfo->Nodes) {
ctx.Send(TActivationContext::InterconnectProxy(ni.NodeId), new TEvents::TEvUnsubscribe());
- }
- }
- TBase::Die(ctx);
- }
-
- void SendRequest(ui32 nodeId, const TActorContext& ctx) {
+ }
+ }
+ TBase::Die(ctx);
+ }
+
+ void SendRequest(ui32 nodeId, const TActorContext& ctx) {
TActorId whiteboardServiceId = MakeNodeWhiteboardServiceId(nodeId);
- ctx.Send(whiteboardServiceId, new TEvWhiteboard::TEvVDiskStateRequest(), IEventHandle::FlagTrackDelivery | IEventHandle::FlagSubscribeOnSession, nodeId);
- ++Requested;
- ctx.Send(whiteboardServiceId, new TEvWhiteboard::TEvPDiskStateRequest(), IEventHandle::FlagTrackDelivery | IEventHandle::FlagSubscribeOnSession, nodeId);
- ++Requested;
- ctx.Send(whiteboardServiceId, new TEvWhiteboard::TEvTabletStateRequest(), IEventHandle::FlagTrackDelivery | IEventHandle::FlagSubscribeOnSession, nodeId);
- ++Requested;
- ctx.Send(whiteboardServiceId, new TEvWhiteboard::TEvBSGroupStateRequest(), IEventHandle::FlagTrackDelivery | IEventHandle::FlagSubscribeOnSession, nodeId);
- ++Requested;
- }
-
- void HandleBrowse(TEvInterconnect::TEvNodesInfo::TPtr& ev, const TActorContext& ctx) {
- NodesInfo = ev->Release();
- for (const auto& ni : NodesInfo->Nodes) {
- SendRequest(ni.NodeId, ctx);
- }
- if (Requested > 0) {
- TBase::Become(&TThis::StateRequestedNodeInfo);
- } else {
- ReplyAndDie(ctx);
- }
- }
-
- void Undelivered(TEvents::TEvUndelivered::TPtr &ev, const TActorContext &ctx) {
- ui32 nodeId = ev.Get()->Cookie;
- switch (ev->Get()->SourceType) {
- case TEvWhiteboard::EvVDiskStateRequest:
- if (VDiskInfo.emplace(nodeId, nullptr).second) {
- NodeStateInfoReceived(ctx);
- }
- break;
- case TEvWhiteboard::EvPDiskStateRequest:
- if (PDiskInfo.emplace(nodeId, nullptr).second) {
- NodeStateInfoReceived(ctx);
- }
- break;
- case TEvWhiteboard::EvTabletStateRequest:
- if (TabletInfo.emplace(nodeId, nullptr).second) {
- NodeStateInfoReceived(ctx);
- }
- break;
- case TEvWhiteboard::EvBSGroupStateRequest:
- if (BSGroupInfo.emplace(nodeId, nullptr).second) {
- NodeStateInfoReceived(ctx);
- }
- break;
- }
- }
-
- void Disconnected(TEvInterconnect::TEvNodeDisconnected::TPtr &ev, const TActorContext &ctx) {
- ui32 nodeId = ev->Get()->NodeId;
- if (VDiskInfo.emplace(nodeId, nullptr).second) {
- NodeStateInfoReceived(ctx);
- }
- if (PDiskInfo.emplace(nodeId, nullptr).second) {
- NodeStateInfoReceived(ctx);
- }
- if (TabletInfo.emplace(nodeId, nullptr).second) {
- NodeStateInfoReceived(ctx);
- }
- if (BSGroupInfo.emplace(nodeId, nullptr).second) {
- NodeStateInfoReceived(ctx);
- }
- }
-
- void Handle(TEvWhiteboard::TEvVDiskStateResponse::TPtr& ev, const TActorContext& ctx) {
- ui64 nodeId = ev.Get()->Cookie;
- VDiskInfo[nodeId] = ev->Release();
- NodeStateInfoReceived(ctx);
- }
-
- void Handle(TEvWhiteboard::TEvPDiskStateResponse::TPtr& ev, const TActorContext& ctx) {
- ui64 nodeId = ev.Get()->Cookie;
- PDiskInfo[nodeId] = ev->Release();
- NodeStateInfoReceived(ctx);
- }
-
- void Handle(TEvWhiteboard::TEvTabletStateResponse::TPtr& ev, const TActorContext& ctx) {
- ui64 nodeId = ev.Get()->Cookie;
- TabletInfo[nodeId] = ev->Release();
- NodeStateInfoReceived(ctx);
- }
-
- void Handle(TEvWhiteboard::TEvBSGroupStateResponse::TPtr& ev, const TActorContext& ctx) {
- ui64 nodeId = ev.Get()->Cookie;
- BSGroupInfo[nodeId] = ev->Release();
- NodeStateInfoReceived(ctx);
- }
-
- void NodeStateInfoReceived(const TActorContext& ctx) {
- ++Received;
- if (Received == Requested) {
- ReplyAndDie(ctx);
- }
- }
-
- STFUNC(StateRequestedBrowse) {
- switch (ev->GetTypeRewrite()) {
- HFunc(TEvInterconnect::TEvNodesInfo, HandleBrowse);
- CFunc(TEvents::TSystem::Wakeup, Timeout);
- }
- }
-
- STFUNC(StateRequestedNodeInfo) {
- switch (ev->GetTypeRewrite()) {
- HFunc(TEvWhiteboard::TEvVDiskStateResponse, Handle);
- HFunc(TEvWhiteboard::TEvPDiskStateResponse, Handle);
- HFunc(TEvWhiteboard::TEvTabletStateResponse, Handle);
- HFunc(TEvWhiteboard::TEvBSGroupStateResponse, Handle);
- HFunc(TEvents::TEvUndelivered, Undelivered);
- HFunc(TEvInterconnect::TEvNodeDisconnected, Disconnected);
- CFunc(TEvents::TSystem::Wakeup, Timeout);
- }
- }
-
- template <typename ResponseType>
- void RenderStats(TStringStream& json,
- THolder<ResponseType>& response,
+ ctx.Send(whiteboardServiceId, new TEvWhiteboard::TEvVDiskStateRequest(), IEventHandle::FlagTrackDelivery | IEventHandle::FlagSubscribeOnSession, nodeId);
+ ++Requested;
+ ctx.Send(whiteboardServiceId, new TEvWhiteboard::TEvPDiskStateRequest(), IEventHandle::FlagTrackDelivery | IEventHandle::FlagSubscribeOnSession, nodeId);
+ ++Requested;
+ ctx.Send(whiteboardServiceId, new TEvWhiteboard::TEvTabletStateRequest(), IEventHandle::FlagTrackDelivery | IEventHandle::FlagSubscribeOnSession, nodeId);
+ ++Requested;
+ ctx.Send(whiteboardServiceId, new TEvWhiteboard::TEvBSGroupStateRequest(), IEventHandle::FlagTrackDelivery | IEventHandle::FlagSubscribeOnSession, nodeId);
+ ++Requested;
+ }
+
+ void HandleBrowse(TEvInterconnect::TEvNodesInfo::TPtr& ev, const TActorContext& ctx) {
+ NodesInfo = ev->Release();
+ for (const auto& ni : NodesInfo->Nodes) {
+ SendRequest(ni.NodeId, ctx);
+ }
+ if (Requested > 0) {
+ TBase::Become(&TThis::StateRequestedNodeInfo);
+ } else {
+ ReplyAndDie(ctx);
+ }
+ }
+
+ void Undelivered(TEvents::TEvUndelivered::TPtr &ev, const TActorContext &ctx) {
+ ui32 nodeId = ev.Get()->Cookie;
+ switch (ev->Get()->SourceType) {
+ case TEvWhiteboard::EvVDiskStateRequest:
+ if (VDiskInfo.emplace(nodeId, nullptr).second) {
+ NodeStateInfoReceived(ctx);
+ }
+ break;
+ case TEvWhiteboard::EvPDiskStateRequest:
+ if (PDiskInfo.emplace(nodeId, nullptr).second) {
+ NodeStateInfoReceived(ctx);
+ }
+ break;
+ case TEvWhiteboard::EvTabletStateRequest:
+ if (TabletInfo.emplace(nodeId, nullptr).second) {
+ NodeStateInfoReceived(ctx);
+ }
+ break;
+ case TEvWhiteboard::EvBSGroupStateRequest:
+ if (BSGroupInfo.emplace(nodeId, nullptr).second) {
+ NodeStateInfoReceived(ctx);
+ }
+ break;
+ }
+ }
+
+ void Disconnected(TEvInterconnect::TEvNodeDisconnected::TPtr &ev, const TActorContext &ctx) {
+ ui32 nodeId = ev->Get()->NodeId;
+ if (VDiskInfo.emplace(nodeId, nullptr).second) {
+ NodeStateInfoReceived(ctx);
+ }
+ if (PDiskInfo.emplace(nodeId, nullptr).second) {
+ NodeStateInfoReceived(ctx);
+ }
+ if (TabletInfo.emplace(nodeId, nullptr).second) {
+ NodeStateInfoReceived(ctx);
+ }
+ if (BSGroupInfo.emplace(nodeId, nullptr).second) {
+ NodeStateInfoReceived(ctx);
+ }
+ }
+
+ void Handle(TEvWhiteboard::TEvVDiskStateResponse::TPtr& ev, const TActorContext& ctx) {
+ ui64 nodeId = ev.Get()->Cookie;
+ VDiskInfo[nodeId] = ev->Release();
+ NodeStateInfoReceived(ctx);
+ }
+
+ void Handle(TEvWhiteboard::TEvPDiskStateResponse::TPtr& ev, const TActorContext& ctx) {
+ ui64 nodeId = ev.Get()->Cookie;
+ PDiskInfo[nodeId] = ev->Release();
+ NodeStateInfoReceived(ctx);
+ }
+
+ void Handle(TEvWhiteboard::TEvTabletStateResponse::TPtr& ev, const TActorContext& ctx) {
+ ui64 nodeId = ev.Get()->Cookie;
+ TabletInfo[nodeId] = ev->Release();
+ NodeStateInfoReceived(ctx);
+ }
+
+ void Handle(TEvWhiteboard::TEvBSGroupStateResponse::TPtr& ev, const TActorContext& ctx) {
+ ui64 nodeId = ev.Get()->Cookie;
+ BSGroupInfo[nodeId] = ev->Release();
+ NodeStateInfoReceived(ctx);
+ }
+
+ void NodeStateInfoReceived(const TActorContext& ctx) {
+ ++Received;
+ if (Received == Requested) {
+ ReplyAndDie(ctx);
+ }
+ }
+
+ STFUNC(StateRequestedBrowse) {
+ switch (ev->GetTypeRewrite()) {
+ HFunc(TEvInterconnect::TEvNodesInfo, HandleBrowse);
+ CFunc(TEvents::TSystem::Wakeup, Timeout);
+ }
+ }
+
+ STFUNC(StateRequestedNodeInfo) {
+ switch (ev->GetTypeRewrite()) {
+ HFunc(TEvWhiteboard::TEvVDiskStateResponse, Handle);
+ HFunc(TEvWhiteboard::TEvPDiskStateResponse, Handle);
+ HFunc(TEvWhiteboard::TEvTabletStateResponse, Handle);
+ HFunc(TEvWhiteboard::TEvBSGroupStateResponse, Handle);
+ HFunc(TEvents::TEvUndelivered, Undelivered);
+ HFunc(TEvInterconnect::TEvNodeDisconnected, Disconnected);
+ CFunc(TEvents::TSystem::Wakeup, Timeout);
+ }
+ }
+
+ template <typename ResponseType>
+ void RenderStats(TStringStream& json,
+ THolder<ResponseType>& response,
const TEvInterconnect::TNodeInfo& nodeInfo,
const TString& subsystem,
const TVector<const FieldDescriptor*>& groupFields) {
-
- THolder<ResponseType> groupedResponse = TWhiteboardGrouper<ResponseType>::GroupResponse(response, groupFields, true);
- auto* stateInfo = TWhiteboardInfo<ResponseType>::GetElementsField(groupedResponse.Get());
- TStringBuf host(nodeInfo.Host);
- size_t pos = host.find('.');
+
+ THolder<ResponseType> groupedResponse = TWhiteboardGrouper<ResponseType>::GroupResponse(response, groupFields, true);
+ auto* stateInfo = TWhiteboardInfo<ResponseType>::GetElementsField(groupedResponse.Get());
+ TStringBuf host(nodeInfo.Host);
+ size_t pos = host.find('.');
if (pos != TString::npos) {
- host = host.substr(0, pos);
- }
- for (typename TWhiteboardInfo<ResponseType>::TElementType& info : *stateInfo) {
- const Reflection& reflectionFrom = *info.GetReflection();
- json << ",{\"labels\":{";
- if (nodeInfo.NodeId != 0) {
- json << "\"node\":" << nodeInfo.NodeId << ",";
- }
- json << "\"host\":\"" << host << "\",";
- if (nodeInfo.Port != 0) {
- json << "\"port\":" << nodeInfo.Port << ",";
- }
- json << "\"subsystem\":\"" << subsystem << "\",";
- json << "\"" << groupFields.front()->name() << "\":\"";
- json << reflectionFrom.GetEnum(info, groupFields.front())->name();
- json << "\"";
- json << "},\"value\":";
- json << info.GetCount();
- json << '}';
- }
- }
-
- void RenderStats(TStringStream& json,
- THolder<TEvWhiteboard::TEvVDiskStateResponse>& response,
+ host = host.substr(0, pos);
+ }
+ for (typename TWhiteboardInfo<ResponseType>::TElementType& info : *stateInfo) {
+ const Reflection& reflectionFrom = *info.GetReflection();
+ json << ",{\"labels\":{";
+ if (nodeInfo.NodeId != 0) {
+ json << "\"node\":" << nodeInfo.NodeId << ",";
+ }
+ json << "\"host\":\"" << host << "\",";
+ if (nodeInfo.Port != 0) {
+ json << "\"port\":" << nodeInfo.Port << ",";
+ }
+ json << "\"subsystem\":\"" << subsystem << "\",";
+ json << "\"" << groupFields.front()->name() << "\":\"";
+ json << reflectionFrom.GetEnum(info, groupFields.front())->name();
+ json << "\"";
+ json << "},\"value\":";
+ json << info.GetCount();
+ json << '}';
+ }
+ }
+
+ void RenderStats(TStringStream& json,
+ THolder<TEvWhiteboard::TEvVDiskStateResponse>& response,
const TEvInterconnect::TNodeInfo& nodeInfo) {
- if (response == nullptr)
- return;
+ if (response == nullptr)
+ return;
static TVector<const FieldDescriptor*> groupFields
- = TWhiteboardGrouper<TEvWhiteboard::TEvVDiskStateResponse>::GetProtoFields("VDiskState");
- RenderStats(json, response, nodeInfo, "VDisk", groupFields);
- }
-
- void RenderStats(TStringStream& json,
- THolder<TEvWhiteboard::TEvPDiskStateResponse>& response,
+ = TWhiteboardGrouper<TEvWhiteboard::TEvVDiskStateResponse>::GetProtoFields("VDiskState");
+ RenderStats(json, response, nodeInfo, "VDisk", groupFields);
+ }
+
+ void RenderStats(TStringStream& json,
+ THolder<TEvWhiteboard::TEvPDiskStateResponse>& response,
const TEvInterconnect::TNodeInfo& nodeInfo) {
- if (response == nullptr)
- return;
+ if (response == nullptr)
+ return;
static TVector<const FieldDescriptor*> groupFields
- = TWhiteboardGrouper<TEvWhiteboard::TEvPDiskStateResponse>::GetProtoFields("State");
- RenderStats(json, response, nodeInfo, "PDisk", groupFields);
- }
-
- void RenderStats(TStringStream& json,
- THolder<TEvWhiteboard::TEvTabletStateResponse>& response,
+ = TWhiteboardGrouper<TEvWhiteboard::TEvPDiskStateResponse>::GetProtoFields("State");
+ RenderStats(json, response, nodeInfo, "PDisk", groupFields);
+ }
+
+ void RenderStats(TStringStream& json,
+ THolder<TEvWhiteboard::TEvTabletStateResponse>& response,
const TEvInterconnect::TNodeInfo& nodeInfo) {
- if (response == nullptr)
- return;
+ if (response == nullptr)
+ return;
static TVector<const FieldDescriptor*> groupFields
- = TWhiteboardGrouper<TEvWhiteboard::TEvTabletStateResponse>::GetProtoFields("State");
- RenderStats(json, response, nodeInfo, "Tablet", groupFields);
- }
-
- void ReplyAndDie(const TActorContext& ctx) {
- TStringStream json;
-
- json << '{';
- json << "\"sensors\":[";
-
- Sort(NodesInfo->Nodes, [](
+ = TWhiteboardGrouper<TEvWhiteboard::TEvTabletStateResponse>::GetProtoFields("State");
+ RenderStats(json, response, nodeInfo, "Tablet", groupFields);
+ }
+
+ void ReplyAndDie(const TActorContext& ctx) {
+ TStringStream json;
+
+ json << '{';
+ json << "\"sensors\":[";
+
+ Sort(NodesInfo->Nodes, [](
const TEvInterconnect::TNodeInfo& a,
const TEvInterconnect::TNodeInfo& b) -> bool {
- return a.NodeId < b.NodeId;
- });
-
- ui32 nodesResponded = 0;
- for (const std::pair<const ui32, THolder<TEvWhiteboard::TEvVDiskStateResponse>>& value : VDiskInfo) {
- if (value.second != nullptr) {
- ++nodesResponded;
- }
- }
-
- json << "{\"labels\":{";
- json << "\"subsystem\":\"Viewer\",";
- json << "\"host\":\"cluster\",";
- json << "\"sensor\":\"NodesResponded\"";
- json << "},\"value\":" << nodesResponded;
- json << '}';
-
- THolder<TEvWhiteboard::TEvTabletStateResponse> mergedTabletInfo = MergeWhiteboardResponses(TabletInfo, TWhiteboardInfo<TEvWhiteboard::TEvTabletStateResponse>::GetDefaultMergeField());
- TabletInfo.clear();
- for (const auto& tabletInfo : mergedTabletInfo->Record.GetTabletStateInfo()) {
- if (!tabletInfo.HasNodeId()) {
- continue;
- }
- auto it = TabletInfo.find(tabletInfo.GetNodeId());
- if (it == TabletInfo.end()) {
- it = TabletInfo.emplace(tabletInfo.GetNodeId(), new TEvWhiteboard::TEvTabletStateResponse).first;
- }
- it->second->Record.AddTabletStateInfo()->CopyFrom(tabletInfo);
- }
-
- std::array<int, 20> pDiskUserSpaceHistogram = {};
-
- auto itVDiskInfo = VDiskInfo.begin();
- auto itPDiskInfo = PDiskInfo.begin();
- auto itTabletInfo = TabletInfo.begin();
-
- for (const auto& nodeInfo : NodesInfo->Nodes) {
- while (itVDiskInfo != VDiskInfo.end() && itVDiskInfo->first < nodeInfo.NodeId)
- ++itVDiskInfo;
- if (itVDiskInfo != VDiskInfo.end() && itVDiskInfo->first == nodeInfo.NodeId && itVDiskInfo->second) {
- RenderStats(json, itVDiskInfo->second, nodeInfo);
- }
- while (itPDiskInfo != PDiskInfo.end() && itPDiskInfo->first < nodeInfo.NodeId)
- ++itPDiskInfo;
- if (itPDiskInfo != PDiskInfo.end() && itPDiskInfo->first == nodeInfo.NodeId && itPDiskInfo->second) {
- RenderStats(json, itPDiskInfo->second, nodeInfo);
- auto* stateInfo = TWhiteboardInfo<TEvWhiteboard::TEvPDiskStateResponse>::GetElementsField(itPDiskInfo->second.Get());
- for (const typename TWhiteboardInfo<TEvWhiteboard::TEvPDiskStateResponse>::TElementType& info : *stateInfo) {
- if (info.GetTotalSize() > 0 && info.GetAvailableSize() > 0) {
- ++pDiskUserSpaceHistogram[std::min((info.GetTotalSize() - info.GetAvailableSize()) * pDiskUserSpaceHistogram.size() / info.GetTotalSize(), pDiskUserSpaceHistogram.size() - 1)];
- }
- }
- }
- while (itTabletInfo != TabletInfo.end() && itTabletInfo->first < nodeInfo.NodeId)
- ++itTabletInfo;
- if (itTabletInfo != TabletInfo.end() && itTabletInfo->first == nodeInfo.NodeId && itTabletInfo->second) {
- RenderStats(json, itTabletInfo->second, nodeInfo);
- }
- }
-
+ return a.NodeId < b.NodeId;
+ });
+
+ ui32 nodesResponded = 0;
+ for (const std::pair<const ui32, THolder<TEvWhiteboard::TEvVDiskStateResponse>>& value : VDiskInfo) {
+ if (value.second != nullptr) {
+ ++nodesResponded;
+ }
+ }
+
+ json << "{\"labels\":{";
+ json << "\"subsystem\":\"Viewer\",";
+ json << "\"host\":\"cluster\",";
+ json << "\"sensor\":\"NodesResponded\"";
+ json << "},\"value\":" << nodesResponded;
+ json << '}';
+
+ THolder<TEvWhiteboard::TEvTabletStateResponse> mergedTabletInfo = MergeWhiteboardResponses(TabletInfo, TWhiteboardInfo<TEvWhiteboard::TEvTabletStateResponse>::GetDefaultMergeField());
+ TabletInfo.clear();
+ for (const auto& tabletInfo : mergedTabletInfo->Record.GetTabletStateInfo()) {
+ if (!tabletInfo.HasNodeId()) {
+ continue;
+ }
+ auto it = TabletInfo.find(tabletInfo.GetNodeId());
+ if (it == TabletInfo.end()) {
+ it = TabletInfo.emplace(tabletInfo.GetNodeId(), new TEvWhiteboard::TEvTabletStateResponse).first;
+ }
+ it->second->Record.AddTabletStateInfo()->CopyFrom(tabletInfo);
+ }
+
+ std::array<int, 20> pDiskUserSpaceHistogram = {};
+
+ auto itVDiskInfo = VDiskInfo.begin();
+ auto itPDiskInfo = PDiskInfo.begin();
+ auto itTabletInfo = TabletInfo.begin();
+
+ for (const auto& nodeInfo : NodesInfo->Nodes) {
+ while (itVDiskInfo != VDiskInfo.end() && itVDiskInfo->first < nodeInfo.NodeId)
+ ++itVDiskInfo;
+ if (itVDiskInfo != VDiskInfo.end() && itVDiskInfo->first == nodeInfo.NodeId && itVDiskInfo->second) {
+ RenderStats(json, itVDiskInfo->second, nodeInfo);
+ }
+ while (itPDiskInfo != PDiskInfo.end() && itPDiskInfo->first < nodeInfo.NodeId)
+ ++itPDiskInfo;
+ if (itPDiskInfo != PDiskInfo.end() && itPDiskInfo->first == nodeInfo.NodeId && itPDiskInfo->second) {
+ RenderStats(json, itPDiskInfo->second, nodeInfo);
+ auto* stateInfo = TWhiteboardInfo<TEvWhiteboard::TEvPDiskStateResponse>::GetElementsField(itPDiskInfo->second.Get());
+ for (const typename TWhiteboardInfo<TEvWhiteboard::TEvPDiskStateResponse>::TElementType& info : *stateInfo) {
+ if (info.GetTotalSize() > 0 && info.GetAvailableSize() > 0) {
+ ++pDiskUserSpaceHistogram[std::min((info.GetTotalSize() - info.GetAvailableSize()) * pDiskUserSpaceHistogram.size() / info.GetTotalSize(), pDiskUserSpaceHistogram.size() - 1)];
+ }
+ }
+ }
+ while (itTabletInfo != TabletInfo.end() && itTabletInfo->first < nodeInfo.NodeId)
+ ++itTabletInfo;
+ if (itTabletInfo != TabletInfo.end() && itTabletInfo->first == nodeInfo.NodeId && itTabletInfo->second) {
+ RenderStats(json, itTabletInfo->second, nodeInfo);
+ }
+ }
+
static TEvInterconnect::TNodeInfo totals(0, "", "cluster", "", 0, TNodeLocation());
-
- for (size_t p = 0; p < pDiskUserSpaceHistogram.size(); ++p) {
- json << ",{\"labels\":{";
- json << "\"bin\":\"" << ((p + 1) * 100 / pDiskUserSpaceHistogram.size()) << "%\",";
- json << "\"subsystem\":\"PDisk\",";
- json << "\"host\":\"cluster\",";
- json << "\"sensor\":\"UsedSpace\"";
- json << "},\"value\":";
- json << pDiskUserSpaceHistogram[p];
- json << '}';
- }
-
- THolder<TEvWhiteboard::TEvVDiskStateResponse> mergedVDiskInfo = MergeWhiteboardResponses(VDiskInfo, TWhiteboardInfo<TEvWhiteboard::TEvVDiskStateResponse>::GetDefaultMergeField());
- RenderStats(json, mergedVDiskInfo, totals);
- THolder<TEvWhiteboard::TEvPDiskStateResponse> mergedPDiskInfo = MergeWhiteboardResponses(PDiskInfo, TWhiteboardInfo<TEvWhiteboard::TEvPDiskStateResponse>::GetDefaultMergeField());
- RenderStats(json, mergedPDiskInfo, totals);
- RenderStats(json, mergedTabletInfo, totals);
- THolder<TEvWhiteboard::TEvBSGroupStateResponse> mergedBSGroupInfo = MergeWhiteboardResponses(BSGroupInfo, TWhiteboardInfo<TEvWhiteboard::TEvBSGroupStateResponse>::GetDefaultMergeField());
-
- std::array<int, 9> bsGroupUnavaiableHistogram = {};
- std::array<int, 9> bsGroupGreenHistogram = {};
- std::array<int, 9> bsGroupNotGreenHistogram = {};
- std::unordered_map<ui64, int> bsGroupVDisks;
- std::unordered_map<ui64, int> bsGroupGreenVDisks;
- std::unordered_map<ui64, int> bsGroupNotGreenVDisks;
- {
- auto* stateInfo = TWhiteboardInfo<TEvWhiteboard::TEvBSGroupStateResponse>::GetElementsField(mergedBSGroupInfo.Get());
- for (const typename TWhiteboardInfo<TEvWhiteboard::TEvBSGroupStateResponse>::TElementType& info : *stateInfo) {
- bsGroupVDisks[info.GetGroupID()] = info.VDiskIdsSize();
- }
- }
- {
- auto* stateInfo = TWhiteboardInfo<TEvWhiteboard::TEvVDiskStateResponse>::GetElementsField(mergedVDiskInfo.Get());
- for (const typename TWhiteboardInfo<TEvWhiteboard::TEvVDiskStateResponse>::TElementType& info : *stateInfo) {
- auto groupId = info.GetVDiskId().GetGroupID();
- bsGroupVDisks[groupId]--;
- auto flag = GetVDiskOverallFlag(info);
- if (flag == NKikimrViewer::EFlag::Green && info.GetReplicated()) {
- bsGroupGreenVDisks[groupId]++;
- } else {
- bsGroupNotGreenVDisks[groupId]++;
- }
- }
- }
- {
- for (auto it = bsGroupVDisks.begin(); it != bsGroupVDisks.end(); ++it) {
- int idx = it->second;
- if (idx < 0) {
- idx = 0;
- }
- if (idx >= (int)bsGroupUnavaiableHistogram.size()) {
- idx = bsGroupUnavaiableHistogram.size() - 1;
- }
- bsGroupUnavaiableHistogram[idx]++;
- }
- }
- {
- for (auto it = bsGroupGreenVDisks.begin(); it != bsGroupGreenVDisks.end(); ++it) {
- int idx = it->second;
- if (idx < 0) {
- idx = 0;
- }
- if (idx >= (int)bsGroupGreenHistogram.size()) {
- idx = bsGroupGreenHistogram.size() - 1;
- }
- bsGroupGreenHistogram[idx]++;
- }
- }
- {
- for (auto it = bsGroupNotGreenVDisks.begin(); it != bsGroupNotGreenVDisks.end(); ++it) {
- int idx = it->second;
- if (idx < 0) {
- idx = 0;
- }
- if (idx >= (int)bsGroupNotGreenHistogram.size()) {
- idx = bsGroupNotGreenHistogram.size() - 1;
- }
- bsGroupNotGreenHistogram[idx]++;
- }
- }
-
- for (size_t p = 0; p < bsGroupUnavaiableHistogram.size(); ++p) {
- json << ",{\"labels\":{";
- json << "\"bin\":\"" << p << "\",";
- json << "\"subsystem\":\"BSGroups\",";
- json << "\"host\":\"cluster\",";
- json << "\"sensor\":\"UnavailableVDisks\"";
- json << "},\"value\":";
- json << bsGroupUnavaiableHistogram[p];
- json << '}';
- }
-
- for (size_t p = 0; p < bsGroupGreenHistogram.size(); ++p) {
- json << ",{\"labels\":{";
- json << "\"bin\":\"" << p << "\",";
- json << "\"subsystem\":\"BSGroups\",";
- json << "\"host\":\"cluster\",";
- json << "\"sensor\":\"GreenVDisks\"";
- json << "},\"value\":";
- json << bsGroupGreenHistogram[p];
- json << '}';
- }
-
- for (size_t p = 0; p < bsGroupNotGreenHistogram.size(); ++p) {
- json << ",{\"labels\":{";
- json << "\"bin\":\"" << p << "\",";
- json << "\"subsystem\":\"BSGroups\",";
- json << "\"host\":\"cluster\",";
- json << "\"sensor\":\"NotGreenVDisks\"";
- json << "},\"value\":";
- json << bsGroupNotGreenHistogram[p];
- json << '}';
- }
-
- json << ']';
- json << '}';
-
- ctx.Send(Initiator, new NMon::TEvHttpInfoRes(Viewer->GetHTTPOKJSON() + json.Str(), 0, NMon::IEvHttpInfoRes::EContentType::Custom));
- Die(ctx);
- }
-
- void Timeout(const TActorContext& ctx) {
- ctx.Send(Initiator, new NMon::TEvHttpInfoRes(Viewer->GetHTTPGATEWAYTIMEOUT(), 0, NMon::IEvHttpInfoRes::EContentType::Custom));
+
+ for (size_t p = 0; p < pDiskUserSpaceHistogram.size(); ++p) {
+ json << ",{\"labels\":{";
+ json << "\"bin\":\"" << ((p + 1) * 100 / pDiskUserSpaceHistogram.size()) << "%\",";
+ json << "\"subsystem\":\"PDisk\",";
+ json << "\"host\":\"cluster\",";
+ json << "\"sensor\":\"UsedSpace\"";
+ json << "},\"value\":";
+ json << pDiskUserSpaceHistogram[p];
+ json << '}';
+ }
+
+ THolder<TEvWhiteboard::TEvVDiskStateResponse> mergedVDiskInfo = MergeWhiteboardResponses(VDiskInfo, TWhiteboardInfo<TEvWhiteboard::TEvVDiskStateResponse>::GetDefaultMergeField());
+ RenderStats(json, mergedVDiskInfo, totals);
+ THolder<TEvWhiteboard::TEvPDiskStateResponse> mergedPDiskInfo = MergeWhiteboardResponses(PDiskInfo, TWhiteboardInfo<TEvWhiteboard::TEvPDiskStateResponse>::GetDefaultMergeField());
+ RenderStats(json, mergedPDiskInfo, totals);
+ RenderStats(json, mergedTabletInfo, totals);
+ THolder<TEvWhiteboard::TEvBSGroupStateResponse> mergedBSGroupInfo = MergeWhiteboardResponses(BSGroupInfo, TWhiteboardInfo<TEvWhiteboard::TEvBSGroupStateResponse>::GetDefaultMergeField());
+
+ std::array<int, 9> bsGroupUnavaiableHistogram = {};
+ std::array<int, 9> bsGroupGreenHistogram = {};
+ std::array<int, 9> bsGroupNotGreenHistogram = {};
+ std::unordered_map<ui64, int> bsGroupVDisks;
+ std::unordered_map<ui64, int> bsGroupGreenVDisks;
+ std::unordered_map<ui64, int> bsGroupNotGreenVDisks;
+ {
+ auto* stateInfo = TWhiteboardInfo<TEvWhiteboard::TEvBSGroupStateResponse>::GetElementsField(mergedBSGroupInfo.Get());
+ for (const typename TWhiteboardInfo<TEvWhiteboard::TEvBSGroupStateResponse>::TElementType& info : *stateInfo) {
+ bsGroupVDisks[info.GetGroupID()] = info.VDiskIdsSize();
+ }
+ }
+ {
+ auto* stateInfo = TWhiteboardInfo<TEvWhiteboard::TEvVDiskStateResponse>::GetElementsField(mergedVDiskInfo.Get());
+ for (const typename TWhiteboardInfo<TEvWhiteboard::TEvVDiskStateResponse>::TElementType& info : *stateInfo) {
+ auto groupId = info.GetVDiskId().GetGroupID();
+ bsGroupVDisks[groupId]--;
+ auto flag = GetVDiskOverallFlag(info);
+ if (flag == NKikimrViewer::EFlag::Green && info.GetReplicated()) {
+ bsGroupGreenVDisks[groupId]++;
+ } else {
+ bsGroupNotGreenVDisks[groupId]++;
+ }
+ }
+ }
+ {
+ for (auto it = bsGroupVDisks.begin(); it != bsGroupVDisks.end(); ++it) {
+ int idx = it->second;
+ if (idx < 0) {
+ idx = 0;
+ }
+ if (idx >= (int)bsGroupUnavaiableHistogram.size()) {
+ idx = bsGroupUnavaiableHistogram.size() - 1;
+ }
+ bsGroupUnavaiableHistogram[idx]++;
+ }
+ }
+ {
+ for (auto it = bsGroupGreenVDisks.begin(); it != bsGroupGreenVDisks.end(); ++it) {
+ int idx = it->second;
+ if (idx < 0) {
+ idx = 0;
+ }
+ if (idx >= (int)bsGroupGreenHistogram.size()) {
+ idx = bsGroupGreenHistogram.size() - 1;
+ }
+ bsGroupGreenHistogram[idx]++;
+ }
+ }
+ {
+ for (auto it = bsGroupNotGreenVDisks.begin(); it != bsGroupNotGreenVDisks.end(); ++it) {
+ int idx = it->second;
+ if (idx < 0) {
+ idx = 0;
+ }
+ if (idx >= (int)bsGroupNotGreenHistogram.size()) {
+ idx = bsGroupNotGreenHistogram.size() - 1;
+ }
+ bsGroupNotGreenHistogram[idx]++;
+ }
+ }
+
+ for (size_t p = 0; p < bsGroupUnavaiableHistogram.size(); ++p) {
+ json << ",{\"labels\":{";
+ json << "\"bin\":\"" << p << "\",";
+ json << "\"subsystem\":\"BSGroups\",";
+ json << "\"host\":\"cluster\",";
+ json << "\"sensor\":\"UnavailableVDisks\"";
+ json << "},\"value\":";
+ json << bsGroupUnavaiableHistogram[p];
+ json << '}';
+ }
+
+ for (size_t p = 0; p < bsGroupGreenHistogram.size(); ++p) {
+ json << ",{\"labels\":{";
+ json << "\"bin\":\"" << p << "\",";
+ json << "\"subsystem\":\"BSGroups\",";
+ json << "\"host\":\"cluster\",";
+ json << "\"sensor\":\"GreenVDisks\"";
+ json << "},\"value\":";
+ json << bsGroupGreenHistogram[p];
+ json << '}';
+ }
+
+ for (size_t p = 0; p < bsGroupNotGreenHistogram.size(); ++p) {
+ json << ",{\"labels\":{";
+ json << "\"bin\":\"" << p << "\",";
+ json << "\"subsystem\":\"BSGroups\",";
+ json << "\"host\":\"cluster\",";
+ json << "\"sensor\":\"NotGreenVDisks\"";
+ json << "},\"value\":";
+ json << bsGroupNotGreenHistogram[p];
+ json << '}';
+ }
+
+ json << ']';
+ json << '}';
+
+ ctx.Send(Initiator, new NMon::TEvHttpInfoRes(Viewer->GetHTTPOKJSON() + json.Str(), 0, NMon::IEvHttpInfoRes::EContentType::Custom));
Die(ctx);
- }
-};
-
-}
-}
+ }
+
+ void Timeout(const TActorContext& ctx) {
+ ctx.Send(Initiator, new NMon::TEvHttpInfoRes(Viewer->GetHTTPGATEWAYTIMEOUT(), 0, NMon::IEvHttpInfoRes::EContentType::Custom));
+ Die(ctx);
+ }
+};
+
+}
+}
diff --git a/ydb/core/viewer/json_describe.h b/ydb/core/viewer/json_describe.h
index ef4d7bbdd5c..05ef441f8f6 100644
--- a/ydb/core/viewer/json_describe.h
+++ b/ydb/core/viewer/json_describe.h
@@ -1,157 +1,157 @@
-#pragma once
+#pragma once
#include <library/cpp/actors/core/actor_bootstrapped.h>
#include <library/cpp/actors/core/mon.h>
#include <ydb/core/base/tablet_pipe.h>
#include <ydb/core/protos/services.pb.h>
#include <ydb/core/tx/schemeshard/schemeshard.h>
#include <ydb/core/tx/tx_proxy/proxy.h>
-#include "viewer.h"
-#include "json_pipe_req.h"
-
-namespace NKikimr {
-namespace NViewer {
-
-using namespace NActors;
+#include "viewer.h"
+#include "json_pipe_req.h"
+
+namespace NKikimr {
+namespace NViewer {
+
+using namespace NActors;
using NSchemeShard::TEvSchemeShard;
-
-class TJsonDescribe : public TViewerPipeClient<TJsonDescribe> {
- using TBase = TViewerPipeClient<TJsonDescribe>;
- IViewer* Viewer;
- NMon::TEvHttpInfo::TPtr Event;
+
+class TJsonDescribe : public TViewerPipeClient<TJsonDescribe> {
+ using TBase = TViewerPipeClient<TJsonDescribe>;
+ IViewer* Viewer;
+ NMon::TEvHttpInfo::TPtr Event;
TAutoPtr<TEvSchemeShard::TEvDescribeSchemeResult> DescribeResult;
- TJsonSettings JsonSettings;
+ TJsonSettings JsonSettings;
ui32 Timeout = 0;
-
-public:
+
+public:
static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
return NKikimrServices::TActivity::VIEWER_HANDLER;
- }
-
- TJsonDescribe(IViewer* viewer, NMon::TEvHttpInfo::TPtr &ev)
- : Viewer(viewer)
- , Event(ev)
- {}
-
+ }
+
+ TJsonDescribe(IViewer* viewer, NMon::TEvHttpInfo::TPtr &ev)
+ : Viewer(viewer)
+ , Event(ev)
+ {}
+
void FillParams(NKikimrSchemeOp::TDescribePath* record, const TCgiParameters& params) {
- if (params.Has("path")) {
- record->SetPath(params.Get("path"));
- }
- if (params.Has("path_id")) {
- record->SetPathId(FromStringWithDefault<ui64>(params.Get("path_id")));
- }
- if (params.Has("schemeshard_id")) {
- record->SetSchemeshardId(FromStringWithDefault<ui64>(params.Get("schemeshard_id")));
- }
- record->MutableOptions()->SetBackupInfo(FromStringWithDefault<bool>(params.Get("backup"), true));
- record->MutableOptions()->SetShowPrivateTable(FromStringWithDefault<bool>(params.Get("private"), true));
- record->MutableOptions()->SetReturnChildren(FromStringWithDefault<bool>(params.Get("children"), true));
- record->MutableOptions()->SetReturnBoundaries(FromStringWithDefault<bool>(params.Get("boundaries"), false));
- record->MutableOptions()->SetReturnPartitionConfig(FromStringWithDefault<bool>(params.Get("partition_config"), true));
- record->MutableOptions()->SetReturnPartitionStats(FromStringWithDefault<bool>(params.Get("partition_stats"), false));
- record->MutableOptions()->SetReturnPartitioningInfo(FromStringWithDefault<bool>(params.Get("partitioning_info"), true));
- }
-
- void Bootstrap() {
- const auto& params(Event->Get()->Request.GetParams());
- JsonSettings.EnumAsNumbers = !FromStringWithDefault<bool>(params.Get("enums"), false);
- JsonSettings.UI64AsString = !FromStringWithDefault<bool>(params.Get("ui64"), false);
- Timeout = FromStringWithDefault<ui32>(params.Get("timeout"), 10000);
- InitConfig(params);
-
- if (params.Has("schemeshard_id")) {
+ if (params.Has("path")) {
+ record->SetPath(params.Get("path"));
+ }
+ if (params.Has("path_id")) {
+ record->SetPathId(FromStringWithDefault<ui64>(params.Get("path_id")));
+ }
+ if (params.Has("schemeshard_id")) {
+ record->SetSchemeshardId(FromStringWithDefault<ui64>(params.Get("schemeshard_id")));
+ }
+ record->MutableOptions()->SetBackupInfo(FromStringWithDefault<bool>(params.Get("backup"), true));
+ record->MutableOptions()->SetShowPrivateTable(FromStringWithDefault<bool>(params.Get("private"), true));
+ record->MutableOptions()->SetReturnChildren(FromStringWithDefault<bool>(params.Get("children"), true));
+ record->MutableOptions()->SetReturnBoundaries(FromStringWithDefault<bool>(params.Get("boundaries"), false));
+ record->MutableOptions()->SetReturnPartitionConfig(FromStringWithDefault<bool>(params.Get("partition_config"), true));
+ record->MutableOptions()->SetReturnPartitionStats(FromStringWithDefault<bool>(params.Get("partition_stats"), false));
+ record->MutableOptions()->SetReturnPartitioningInfo(FromStringWithDefault<bool>(params.Get("partitioning_info"), true));
+ }
+
+ void Bootstrap() {
+ const auto& params(Event->Get()->Request.GetParams());
+ JsonSettings.EnumAsNumbers = !FromStringWithDefault<bool>(params.Get("enums"), false);
+ JsonSettings.UI64AsString = !FromStringWithDefault<bool>(params.Get("ui64"), false);
+ Timeout = FromStringWithDefault<ui32>(params.Get("timeout"), 10000);
+ InitConfig(params);
+
+ if (params.Has("schemeshard_id")) {
THolder<TEvSchemeShard::TEvDescribeScheme> request = MakeHolder<TEvSchemeShard::TEvDescribeScheme>();
- FillParams(&request->Record, params);
- ui64 schemeShardId = FromStringWithDefault<ui64>(params.Get("schemeshard_id"));
- SendRequestToPipe(ConnectTabletPipe(schemeShardId), request.Release());
- } else {
- THolder<TEvTxUserProxy::TEvNavigate> request = MakeHolder<TEvTxUserProxy::TEvNavigate>();
- FillParams(request->Record.MutableDescribePath(), params);
- request->Record.SetUserToken(Event->Get()->UserToken);
- SendRequest(MakeTxProxyID(), request.Release());
- }
- Become(&TThis::StateRequestedDescribe, TDuration::MilliSeconds(Timeout), new TEvents::TEvWakeup());
- }
-
- STATEFN(StateRequestedDescribe) {
- switch (ev->GetTypeRewrite()) {
- hFunc(TEvSchemeShard::TEvDescribeSchemeResult, Handle);
- hFunc(TEvTabletPipe::TEvClientConnected, TBase::Handle);
- cFunc(TEvents::TSystem::Wakeup, HandleTimeout);
- }
- }
-
- void Handle(TEvSchemeShard::TEvDescribeSchemeResult::TPtr& ev) {
- DescribeResult = ev->Release();
- RequestDone();
- }
-
- void ReplyAndPassAway() {
- TStringStream json;
- TString headers = Viewer->GetHTTPOKJSON();
- if (DescribeResult != nullptr) {
- TProtoToJson::ProtoToJson(json, DescribeResult->GetRecord(), JsonSettings);
- switch (DescribeResult->GetRecord().GetStatus()) {
+ FillParams(&request->Record, params);
+ ui64 schemeShardId = FromStringWithDefault<ui64>(params.Get("schemeshard_id"));
+ SendRequestToPipe(ConnectTabletPipe(schemeShardId), request.Release());
+ } else {
+ THolder<TEvTxUserProxy::TEvNavigate> request = MakeHolder<TEvTxUserProxy::TEvNavigate>();
+ FillParams(request->Record.MutableDescribePath(), params);
+ request->Record.SetUserToken(Event->Get()->UserToken);
+ SendRequest(MakeTxProxyID(), request.Release());
+ }
+ Become(&TThis::StateRequestedDescribe, TDuration::MilliSeconds(Timeout), new TEvents::TEvWakeup());
+ }
+
+ STATEFN(StateRequestedDescribe) {
+ switch (ev->GetTypeRewrite()) {
+ hFunc(TEvSchemeShard::TEvDescribeSchemeResult, Handle);
+ hFunc(TEvTabletPipe::TEvClientConnected, TBase::Handle);
+ cFunc(TEvents::TSystem::Wakeup, HandleTimeout);
+ }
+ }
+
+ void Handle(TEvSchemeShard::TEvDescribeSchemeResult::TPtr& ev) {
+ DescribeResult = ev->Release();
+ RequestDone();
+ }
+
+ void ReplyAndPassAway() {
+ TStringStream json;
+ TString headers = Viewer->GetHTTPOKJSON();
+ if (DescribeResult != nullptr) {
+ TProtoToJson::ProtoToJson(json, DescribeResult->GetRecord(), JsonSettings);
+ switch (DescribeResult->GetRecord().GetStatus()) {
case NKikimrScheme::StatusAccessDenied:
- headers = HTTPFORBIDDENJSON;
- break;
- default:
- break;
- }
- } else {
- json << "null";
- }
-
- Send(Event->Sender, new NMon::TEvHttpInfoRes(headers + json.Str(), 0, NMon::IEvHttpInfoRes::EContentType::Custom));
- PassAway();
- }
-
- void HandleTimeout() {
- Send(Event->Sender, new NMon::TEvHttpInfoRes(Viewer->GetHTTPGATEWAYTIMEOUT(), 0, NMon::IEvHttpInfoRes::EContentType::Custom));
- PassAway();
- }
-};
-
-template <>
-struct TJsonRequestSchema<TJsonDescribe> {
+ headers = HTTPFORBIDDENJSON;
+ break;
+ default:
+ break;
+ }
+ } else {
+ json << "null";
+ }
+
+ Send(Event->Sender, new NMon::TEvHttpInfoRes(headers + json.Str(), 0, NMon::IEvHttpInfoRes::EContentType::Custom));
+ PassAway();
+ }
+
+ void HandleTimeout() {
+ Send(Event->Sender, new NMon::TEvHttpInfoRes(Viewer->GetHTTPGATEWAYTIMEOUT(), 0, NMon::IEvHttpInfoRes::EContentType::Custom));
+ PassAway();
+ }
+};
+
+template <>
+struct TJsonRequestSchema<TJsonDescribe> {
static TString GetSchema() {
- TStringStream stream;
+ TStringStream stream;
TProtoToJson::ProtoToJsonSchema<NSchemeShard::TEvSchemeShard::TEvDescribeSchemeResult::ProtoRecordType>(stream);
- return stream.Str();
- }
-};
-
-template <>
-struct TJsonRequestParameters<TJsonDescribe> {
+ return stream.Str();
+ }
+};
+
+template <>
+struct TJsonRequestParameters<TJsonDescribe> {
static TString GetParameters() {
- return R"___([{"name":"path","in":"query","description":"schema path","required":false,"type":"string"},
- {"name":"schemeshard_id","in":"query","description":"schemeshard identifier (tablet id)","required":false,"type":"integer"},
- {"name":"path_id","in":"query","description":"path id","required":false,"type":"integer"},
- {"name":"enums","in":"query","description":"convert enums to strings","required":false,"type":"boolean"},
- {"name":"ui64","in":"query","description":"return ui64 as number","required":false,"type":"boolean"},
- {"name":"backup","in":"query","description":"return backup information","required":false,"type":"boolean","default":true},
- {"name":"private","in":"query","description":"return private tables","required":false,"type":"boolean","default":true},
- {"name":"children","in":"query","description":"return children","required":false,"type":"boolean","default":true},
- {"name":"boundaries","in":"query","description":"return boundaries","required":false,"type":"boolean","default":false},
- {"name":"partition_config","in":"query","description":"return partition configuration","required":false,"type":"boolean","default":true},
- {"name":"partition_stats","in":"query","description":"return partitions statistics","required":false,"type":"boolean","default":false},
- {"name":"partitioning_info","in":"query","description":"return partitioning information","required":false,"type":"boolean","default":true},
- {"name":"timeout","in":"query","description":"timeout in ms","required":false,"type":"integer"}])___";
- }
-};
-
-template <>
-struct TJsonRequestSummary<TJsonDescribe> {
+ return R"___([{"name":"path","in":"query","description":"schema path","required":false,"type":"string"},
+ {"name":"schemeshard_id","in":"query","description":"schemeshard identifier (tablet id)","required":false,"type":"integer"},
+ {"name":"path_id","in":"query","description":"path id","required":false,"type":"integer"},
+ {"name":"enums","in":"query","description":"convert enums to strings","required":false,"type":"boolean"},
+ {"name":"ui64","in":"query","description":"return ui64 as number","required":false,"type":"boolean"},
+ {"name":"backup","in":"query","description":"return backup information","required":false,"type":"boolean","default":true},
+ {"name":"private","in":"query","description":"return private tables","required":false,"type":"boolean","default":true},
+ {"name":"children","in":"query","description":"return children","required":false,"type":"boolean","default":true},
+ {"name":"boundaries","in":"query","description":"return boundaries","required":false,"type":"boolean","default":false},
+ {"name":"partition_config","in":"query","description":"return partition configuration","required":false,"type":"boolean","default":true},
+ {"name":"partition_stats","in":"query","description":"return partitions statistics","required":false,"type":"boolean","default":false},
+ {"name":"partitioning_info","in":"query","description":"return partitioning information","required":false,"type":"boolean","default":true},
+ {"name":"timeout","in":"query","description":"timeout in ms","required":false,"type":"integer"}])___";
+ }
+};
+
+template <>
+struct TJsonRequestSummary<TJsonDescribe> {
static TString GetSummary() {
- return "\"Schema detailed information\"";
- }
-};
-
-template <>
-struct TJsonRequestDescription<TJsonDescribe> {
+ return "\"Schema detailed information\"";
+ }
+};
+
+template <>
+struct TJsonRequestDescription<TJsonDescribe> {
static TString GetDescription() {
- return "\"Returns detailed information about schema object\"";
- }
-};
-
-}
-}
+ return "\"Returns detailed information about schema object\"";
+ }
+};
+
+}
+}
diff --git a/ydb/core/viewer/json_healthcheck.h b/ydb/core/viewer/json_healthcheck.h
index 2ce3f78d6d1..2419c5b8b11 100644
--- a/ydb/core/viewer/json_healthcheck.h
+++ b/ydb/core/viewer/json_healthcheck.h
@@ -1,117 +1,117 @@
-#pragma once
-#include <library/cpp/actors/core/actor_bootstrapped.h>
-#include <library/cpp/actors/core/interconnect.h>
-#include <library/cpp/actors/core/mon.h>
+#pragma once
+#include <library/cpp/actors/core/actor_bootstrapped.h>
+#include <library/cpp/actors/core/interconnect.h>
+#include <library/cpp/actors/core/mon.h>
#include <ydb/core/blobstorage/base/blobstorage_events.h>
#include <ydb/core/base/tablet_pipe.h>
#include <ydb/core/protos/services.pb.h>
-#include "viewer.h"
+#include "viewer.h"
#include <ydb/core/viewer/json/json.h>
#include <ydb/core/health_check/health_check.h>
#include <ydb/core/util/proto_duration.h>
-
-namespace NKikimr {
-namespace NViewer {
-
-using namespace NActors;
-
-class TJsonHealthCheck : public TActorBootstrapped<TJsonHealthCheck> {
- static const bool WithRetry = false;
- using TBase = TActorBootstrapped<TJsonHealthCheck>;
- IViewer* Viewer;
- NMon::TEvHttpInfo::TPtr Event;
- TJsonSettings JsonSettings;
+
+namespace NKikimr {
+namespace NViewer {
+
+using namespace NActors;
+
+class TJsonHealthCheck : public TActorBootstrapped<TJsonHealthCheck> {
+ static const bool WithRetry = false;
+ using TBase = TActorBootstrapped<TJsonHealthCheck>;
+ IViewer* Viewer;
+ NMon::TEvHttpInfo::TPtr Event;
+ TJsonSettings JsonSettings;
ui32 Timeout = 0;
-
-public:
- static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
- return NKikimrServices::TActivity::VIEWER_HANDLER;
- }
-
- TJsonHealthCheck(IViewer* viewer, NMon::TEvHttpInfo::TPtr& ev)
- : Viewer(viewer)
- , Event(ev)
- {}
-
- void Bootstrap() {
- const auto& params(Event->Get()->Request.GetParams());
- JsonSettings.EnumAsNumbers = !FromStringWithDefault<bool>(params.Get("enums"), true);
- JsonSettings.UI64AsString = !FromStringWithDefault<bool>(params.Get("ui64"), false);
- Timeout = FromStringWithDefault<ui32>(params.Get("timeout"), 10000);
- THolder<NHealthCheck::TEvSelfCheckRequest> request = MakeHolder<NHealthCheck::TEvSelfCheckRequest>();
- request->Database = params.Get("tenant");
- request->Request.set_return_verbose_status(FromStringWithDefault<bool>(params.Get("verbose"), false));
- request->Request.set_maximum_level(FromStringWithDefault<ui32>(params.Get("max_level"), 0));
- SetDuration(TDuration::MilliSeconds(Timeout), *request->Request.mutable_operation_params()->mutable_operation_timeout());
- if (params.Has("min_status")) {
- Ydb::Monitoring::StatusFlag::Status minStatus;
- if (Ydb::Monitoring::StatusFlag_Status_Parse(params.Get("min_status"), &minStatus)) {
- request->Request.set_minimum_status(minStatus);
- } else {
- Send(Event->Sender, new NMon::TEvHttpInfoRes(HTTPBADREQUEST, 0, NMon::IEvHttpInfoRes::EContentType::Custom));
- return PassAway();
- }
- }
- Send(NHealthCheck::MakeHealthCheckID(), request.Release());
- Timeout += Timeout * 20 / 100; // we prefer to wait for more (+20%) verbose timeout status from HC
- Become(&TThis::StateRequestedInfo, TDuration::MilliSeconds(Timeout), new TEvents::TEvWakeup());
- }
-
- STATEFN(StateRequestedInfo) {
- switch (ev->GetTypeRewrite()) {
- hFunc(NHealthCheck::TEvSelfCheckResult, Handle);
- cFunc(TEvents::TSystem::Wakeup, HandleTimeout);
- }
- }
-
- void Handle(NHealthCheck::TEvSelfCheckResult::TPtr& ev) {
- TStringStream json;
- TProtoToJson::ProtoToJson(json, ev->Get()->Result, JsonSettings);
- Send(Event->Sender, new NMon::TEvHttpInfoRes(Viewer->GetHTTPOKJSON() + json.Str(), 0, NMon::IEvHttpInfoRes::EContentType::Custom));
- PassAway();
- }
-
- void HandleTimeout() {
- Send(Event->Sender, new NMon::TEvHttpInfoRes(Viewer->GetHTTPGATEWAYTIMEOUT(), 0, NMon::IEvHttpInfoRes::EContentType::Custom));
- PassAway();
- }
-};
-
-template <>
-struct TJsonRequestSchema<TJsonHealthCheck> {
- static TString GetSchema() {
- TStringStream stream;
- TProtoToJson::ProtoToJsonSchema<Ydb::Monitoring::SelfCheckResult>(stream);
- return stream.Str();
- }
-};
-
-template <>
-struct TJsonRequestParameters<TJsonHealthCheck> {
- static TString GetParameters() {
- return R"___([{"name":"enums","in":"query","description":"convert enums to strings","required":false,"type":"boolean"},
- {"name":"ui64","in":"query","description":"return ui64 as number","required":false,"type":"boolean"},
- {"name":"timeout","in":"query","description":"timeout in ms","required":false,"type":"integer"},
- {"name":"tenant","in":"query","description":"path to database","required":false,"type":"string"},
- {"name":"verbose","in":"query","description":"return verbose status","required":false,"type":"boolean"},
- {"name":"max_level","in":"query","description":"max depth of issues to return","required":false,"type":"integer"},
- {"name":"min_status","in":"query","description":"min status of issues to return","required":false,"type":"string"}])___";
- }
-};
-
-template <>
-struct TJsonRequestSummary<TJsonHealthCheck> {
- static TString GetSummary() {
- return "\"Self-check result\"";
- }
-};
-
-template <>
-struct TJsonRequestDescription<TJsonHealthCheck> {
- static TString GetDescription() {
- return "\"Performs self-check and returns result\"";
- }
-};
-
-}
-}
+
+public:
+ static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
+ return NKikimrServices::TActivity::VIEWER_HANDLER;
+ }
+
+ TJsonHealthCheck(IViewer* viewer, NMon::TEvHttpInfo::TPtr& ev)
+ : Viewer(viewer)
+ , Event(ev)
+ {}
+
+ void Bootstrap() {
+ const auto& params(Event->Get()->Request.GetParams());
+ JsonSettings.EnumAsNumbers = !FromStringWithDefault<bool>(params.Get("enums"), true);
+ JsonSettings.UI64AsString = !FromStringWithDefault<bool>(params.Get("ui64"), false);
+ Timeout = FromStringWithDefault<ui32>(params.Get("timeout"), 10000);
+ THolder<NHealthCheck::TEvSelfCheckRequest> request = MakeHolder<NHealthCheck::TEvSelfCheckRequest>();
+ request->Database = params.Get("tenant");
+ request->Request.set_return_verbose_status(FromStringWithDefault<bool>(params.Get("verbose"), false));
+ request->Request.set_maximum_level(FromStringWithDefault<ui32>(params.Get("max_level"), 0));
+ SetDuration(TDuration::MilliSeconds(Timeout), *request->Request.mutable_operation_params()->mutable_operation_timeout());
+ if (params.Has("min_status")) {
+ Ydb::Monitoring::StatusFlag::Status minStatus;
+ if (Ydb::Monitoring::StatusFlag_Status_Parse(params.Get("min_status"), &minStatus)) {
+ request->Request.set_minimum_status(minStatus);
+ } else {
+ Send(Event->Sender, new NMon::TEvHttpInfoRes(HTTPBADREQUEST, 0, NMon::IEvHttpInfoRes::EContentType::Custom));
+ return PassAway();
+ }
+ }
+ Send(NHealthCheck::MakeHealthCheckID(), request.Release());
+ Timeout += Timeout * 20 / 100; // we prefer to wait for more (+20%) verbose timeout status from HC
+ Become(&TThis::StateRequestedInfo, TDuration::MilliSeconds(Timeout), new TEvents::TEvWakeup());
+ }
+
+ STATEFN(StateRequestedInfo) {
+ switch (ev->GetTypeRewrite()) {
+ hFunc(NHealthCheck::TEvSelfCheckResult, Handle);
+ cFunc(TEvents::TSystem::Wakeup, HandleTimeout);
+ }
+ }
+
+ void Handle(NHealthCheck::TEvSelfCheckResult::TPtr& ev) {
+ TStringStream json;
+ TProtoToJson::ProtoToJson(json, ev->Get()->Result, JsonSettings);
+ Send(Event->Sender, new NMon::TEvHttpInfoRes(Viewer->GetHTTPOKJSON() + json.Str(), 0, NMon::IEvHttpInfoRes::EContentType::Custom));
+ PassAway();
+ }
+
+ void HandleTimeout() {
+ Send(Event->Sender, new NMon::TEvHttpInfoRes(Viewer->GetHTTPGATEWAYTIMEOUT(), 0, NMon::IEvHttpInfoRes::EContentType::Custom));
+ PassAway();
+ }
+};
+
+template <>
+struct TJsonRequestSchema<TJsonHealthCheck> {
+ static TString GetSchema() {
+ TStringStream stream;
+ TProtoToJson::ProtoToJsonSchema<Ydb::Monitoring::SelfCheckResult>(stream);
+ return stream.Str();
+ }
+};
+
+template <>
+struct TJsonRequestParameters<TJsonHealthCheck> {
+ static TString GetParameters() {
+ return R"___([{"name":"enums","in":"query","description":"convert enums to strings","required":false,"type":"boolean"},
+ {"name":"ui64","in":"query","description":"return ui64 as number","required":false,"type":"boolean"},
+ {"name":"timeout","in":"query","description":"timeout in ms","required":false,"type":"integer"},
+ {"name":"tenant","in":"query","description":"path to database","required":false,"type":"string"},
+ {"name":"verbose","in":"query","description":"return verbose status","required":false,"type":"boolean"},
+ {"name":"max_level","in":"query","description":"max depth of issues to return","required":false,"type":"integer"},
+ {"name":"min_status","in":"query","description":"min status of issues to return","required":false,"type":"string"}])___";
+ }
+};
+
+template <>
+struct TJsonRequestSummary<TJsonHealthCheck> {
+ static TString GetSummary() {
+ return "\"Self-check result\"";
+ }
+};
+
+template <>
+struct TJsonRequestDescription<TJsonHealthCheck> {
+ static TString GetDescription() {
+ return "\"Performs self-check and returns result\"";
+ }
+};
+
+}
+}
diff --git a/ydb/core/viewer/json_hiveinfo.h b/ydb/core/viewer/json_hiveinfo.h
index 0da8c5ed50c..f4d04ddfaf6 100644
--- a/ydb/core/viewer/json_hiveinfo.h
+++ b/ydb/core/viewer/json_hiveinfo.h
@@ -1,142 +1,142 @@
-#pragma once
+#pragma once
#include <library/cpp/actors/core/actor_bootstrapped.h>
#include <library/cpp/actors/core/interconnect.h>
#include <library/cpp/actors/core/mon.h>
#include <ydb/core/base/hive.h>
#include <ydb/core/base/tablet_pipe.h>
#include <ydb/core/protos/services.pb.h>
-#include "viewer.h"
-#include "json_pipe_req.h"
+#include "viewer.h"
+#include "json_pipe_req.h"
#include <ydb/core/viewer/json/json.h>
-
-namespace NKikimr {
-namespace NViewer {
-
-using namespace NActors;
-
-class TJsonHiveInfo : public TViewerPipeClient<TJsonHiveInfo> {
- using TBase = TViewerPipeClient<TJsonHiveInfo>;
- IViewer* Viewer;
- NMon::TEvHttpInfo::TPtr Event;
- TAutoPtr<TEvHive::TEvResponseHiveInfo> HiveInfo;
- TJsonSettings JsonSettings;
+
+namespace NKikimr {
+namespace NViewer {
+
+using namespace NActors;
+
+class TJsonHiveInfo : public TViewerPipeClient<TJsonHiveInfo> {
+ using TBase = TViewerPipeClient<TJsonHiveInfo>;
+ IViewer* Viewer;
+ NMon::TEvHttpInfo::TPtr Event;
+ TAutoPtr<TEvHive::TEvResponseHiveInfo> HiveInfo;
+ TJsonSettings JsonSettings;
ui32 Timeout = 0;
- TNodeId NodeId = 0;
-
-public:
+ TNodeId NodeId = 0;
+
+public:
static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
return NKikimrServices::TActivity::VIEWER_HANDLER;
- }
-
- TJsonHiveInfo(IViewer* viewer, NMon::TEvHttpInfo::TPtr &ev)
- : Viewer(viewer)
- , Event(ev)
- {}
-
- void Bootstrap() {
+ }
+
+ TJsonHiveInfo(IViewer* viewer, NMon::TEvHttpInfo::TPtr &ev)
+ : Viewer(viewer)
+ , Event(ev)
+ {}
+
+ void Bootstrap() {
const auto& params(Event->Get()->Request.GetParams());
- ui64 hiveId = FromStringWithDefault<ui64>(params.Get("hive_id"), 0);
- JsonSettings.EnumAsNumbers = !FromStringWithDefault<bool>(params.Get("enums"), false);
- JsonSettings.UI64AsString = !FromStringWithDefault<bool>(params.Get("ui64"), false);
- Timeout = FromStringWithDefault<ui32>(params.Get("timeout"), 10000);
- NodeId = FromStringWithDefault<TNodeId>(params.Get("node"), 0);
- InitConfig(params);
- if (hiveId != 0 ) {
- TAutoPtr<TEvHive::TEvRequestHiveInfo> request = new TEvHive::TEvRequestHiveInfo();
- if (params.Has("tablet_id")) {
- request->Record.SetTabletID(FromStringWithDefault<ui64>(params.Get("tablet_id"), 0));
- }
- if (params.Has("tablet_type")) {
- request->Record.SetTabletType(static_cast<TTabletTypes::EType>(FromStringWithDefault<ui32>(params.Get("tablet_type"), 0)));
- }
+ ui64 hiveId = FromStringWithDefault<ui64>(params.Get("hive_id"), 0);
+ JsonSettings.EnumAsNumbers = !FromStringWithDefault<bool>(params.Get("enums"), false);
+ JsonSettings.UI64AsString = !FromStringWithDefault<bool>(params.Get("ui64"), false);
+ Timeout = FromStringWithDefault<ui32>(params.Get("timeout"), 10000);
+ NodeId = FromStringWithDefault<TNodeId>(params.Get("node"), 0);
+ InitConfig(params);
+ if (hiveId != 0 ) {
+ TAutoPtr<TEvHive::TEvRequestHiveInfo> request = new TEvHive::TEvRequestHiveInfo();
+ if (params.Has("tablet_id")) {
+ request->Record.SetTabletID(FromStringWithDefault<ui64>(params.Get("tablet_id"), 0));
+ }
+ if (params.Has("tablet_type")) {
+ request->Record.SetTabletType(static_cast<TTabletTypes::EType>(FromStringWithDefault<ui32>(params.Get("tablet_type"), 0)));
+ }
if (FromStringWithDefault(params.Get("followers"), false)) {
request->Record.SetReturnFollowers(true);
- }
- if (FromStringWithDefault(params.Get("metrics"), false)) {
- request->Record.SetReturnMetrics(true);
- }
- SendRequestToPipe(ConnectTabletPipe(hiveId), request.Release());
- Become(&TThis::StateRequestedInfo, TDuration::MilliSeconds(Timeout), new TEvents::TEvWakeup());
- } else {
- ReplyAndPassAway();
- }
- }
-
- STATEFN(StateRequestedInfo) {
- switch (ev->GetTypeRewrite()) {
- hFunc(TEvHive::TEvResponseHiveInfo, Handle);
- hFunc(TEvTabletPipe::TEvClientConnected, TBase::Handle);
- cFunc(TEvents::TSystem::Wakeup, HandleTimeout);
- }
- }
-
- void Handle(TEvHive::TEvResponseHiveInfo::TPtr& ev) {
- HiveInfo = ev->Release();
- RequestDone();
- }
-
- void ReplyAndPassAway() {
- TStringStream json;
- if (HiveInfo != nullptr) {
- if (NodeId != 0) {
- for (auto itRecord = HiveInfo->Record.MutableTablets()->begin(); itRecord != HiveInfo->Record.MutableTablets()->end();) {
- if (itRecord->GetNodeID() != NodeId) {
- itRecord = HiveInfo->Record.MutableTablets()->erase(itRecord);
- } else {
- ++itRecord;
- }
- }
- }
- TProtoToJson::ProtoToJson(json, HiveInfo->Record, JsonSettings);
- } else {
- json << "null";
- }
- Send(Event->Sender, new NMon::TEvHttpInfoRes(Viewer->GetHTTPOKJSON() + json.Str(), 0, NMon::IEvHttpInfoRes::EContentType::Custom));
- PassAway();
- }
-
- void HandleTimeout() {
- Send(Event->Sender, new NMon::TEvHttpInfoRes(Viewer->GetHTTPGATEWAYTIMEOUT(), 0, NMon::IEvHttpInfoRes::EContentType::Custom));
- PassAway();
- }
-};
-
-template <>
-struct TJsonRequestSchema<TJsonHiveInfo> {
+ }
+ if (FromStringWithDefault(params.Get("metrics"), false)) {
+ request->Record.SetReturnMetrics(true);
+ }
+ SendRequestToPipe(ConnectTabletPipe(hiveId), request.Release());
+ Become(&TThis::StateRequestedInfo, TDuration::MilliSeconds(Timeout), new TEvents::TEvWakeup());
+ } else {
+ ReplyAndPassAway();
+ }
+ }
+
+ STATEFN(StateRequestedInfo) {
+ switch (ev->GetTypeRewrite()) {
+ hFunc(TEvHive::TEvResponseHiveInfo, Handle);
+ hFunc(TEvTabletPipe::TEvClientConnected, TBase::Handle);
+ cFunc(TEvents::TSystem::Wakeup, HandleTimeout);
+ }
+ }
+
+ void Handle(TEvHive::TEvResponseHiveInfo::TPtr& ev) {
+ HiveInfo = ev->Release();
+ RequestDone();
+ }
+
+ void ReplyAndPassAway() {
+ TStringStream json;
+ if (HiveInfo != nullptr) {
+ if (NodeId != 0) {
+ for (auto itRecord = HiveInfo->Record.MutableTablets()->begin(); itRecord != HiveInfo->Record.MutableTablets()->end();) {
+ if (itRecord->GetNodeID() != NodeId) {
+ itRecord = HiveInfo->Record.MutableTablets()->erase(itRecord);
+ } else {
+ ++itRecord;
+ }
+ }
+ }
+ TProtoToJson::ProtoToJson(json, HiveInfo->Record, JsonSettings);
+ } else {
+ json << "null";
+ }
+ Send(Event->Sender, new NMon::TEvHttpInfoRes(Viewer->GetHTTPOKJSON() + json.Str(), 0, NMon::IEvHttpInfoRes::EContentType::Custom));
+ PassAway();
+ }
+
+ void HandleTimeout() {
+ Send(Event->Sender, new NMon::TEvHttpInfoRes(Viewer->GetHTTPGATEWAYTIMEOUT(), 0, NMon::IEvHttpInfoRes::EContentType::Custom));
+ PassAway();
+ }
+};
+
+template <>
+struct TJsonRequestSchema<TJsonHiveInfo> {
static TString GetSchema() {
- TStringStream stream;
- TProtoToJson::ProtoToJsonSchema<TEvHive::TEvResponseHiveInfo::ProtoRecordType>(stream);
- return stream.Str();
- }
-};
-
-template <>
-struct TJsonRequestParameters<TJsonHiveInfo> {
+ TStringStream stream;
+ TProtoToJson::ProtoToJsonSchema<TEvHive::TEvResponseHiveInfo::ProtoRecordType>(stream);
+ return stream.Str();
+ }
+};
+
+template <>
+struct TJsonRequestParameters<TJsonHiveInfo> {
static TString GetParameters() {
- return R"___([{"name":"hive_id","in":"query","description":"hive identifier (tablet id)","required":true,"type":"string"},
- {"name":"tablet_id","in":"query","description":"tablet id filter","required":false,"type":"string"},
- {"name":"tablet_type","in":"query","description":"tablet type filter","required":false,"type":"string"},
- {"name":"followers","in":"query","description":"return followers","required":false,"type":"boolean"},
- {"name":"metrics","in":"query","description":"return tablet metrics","required":false,"type":"boolean"},
- {"name":"enums","in":"query","description":"convert enums to strings","required":false,"type":"boolean"},
- {"name":"ui64","in":"query","description":"return ui64 as number","required":false,"type":"boolean"},
- {"name":"timeout","in":"query","description":"timeout in ms","required":false,"type":"integer"}])___";
- }
-};
-
-template <>
-struct TJsonRequestSummary<TJsonHiveInfo> {
+ return R"___([{"name":"hive_id","in":"query","description":"hive identifier (tablet id)","required":true,"type":"string"},
+ {"name":"tablet_id","in":"query","description":"tablet id filter","required":false,"type":"string"},
+ {"name":"tablet_type","in":"query","description":"tablet type filter","required":false,"type":"string"},
+ {"name":"followers","in":"query","description":"return followers","required":false,"type":"boolean"},
+ {"name":"metrics","in":"query","description":"return tablet metrics","required":false,"type":"boolean"},
+ {"name":"enums","in":"query","description":"convert enums to strings","required":false,"type":"boolean"},
+ {"name":"ui64","in":"query","description":"return ui64 as number","required":false,"type":"boolean"},
+ {"name":"timeout","in":"query","description":"timeout in ms","required":false,"type":"integer"}])___";
+ }
+};
+
+template <>
+struct TJsonRequestSummary<TJsonHiveInfo> {
static TString GetSummary() {
- return "\"Hive information\"";
- }
-};
-
-template <>
-struct TJsonRequestDescription<TJsonHiveInfo> {
+ return "\"Hive information\"";
+ }
+};
+
+template <>
+struct TJsonRequestDescription<TJsonHiveInfo> {
static TString GetDescription() {
- return "\"Returns information about tablets from Hive\"";
- }
-};
-
-}
-}
+ return "\"Returns information about tablets from Hive\"";
+ }
+};
+
+}
+}
diff --git a/ydb/core/viewer/json_hivestats.h b/ydb/core/viewer/json_hivestats.h
index eca8f3d4c0a..7f24693d635 100644
--- a/ydb/core/viewer/json_hivestats.h
+++ b/ydb/core/viewer/json_hivestats.h
@@ -1,118 +1,118 @@
-#pragma once
+#pragma once
#include <library/cpp/actors/core/actor_bootstrapped.h>
#include <library/cpp/actors/core/interconnect.h>
#include <library/cpp/actors/core/mon.h>
#include <ydb/core/base/hive.h>
#include <ydb/core/base/tablet_pipe.h>
#include <ydb/core/protos/services.pb.h>
-#include "viewer.h"
-#include "json_pipe_req.h"
+#include "viewer.h"
+#include "json_pipe_req.h"
#include <ydb/core/viewer/json/json.h>
-
-namespace NKikimr {
-namespace NViewer {
-
-using namespace NActors;
-
-class TJsonHiveStats : public TViewerPipeClient<TJsonHiveStats> {
- using TBase = TViewerPipeClient<TJsonHiveStats>;
- IViewer* Viewer;
- NMon::TEvHttpInfo::TPtr Event;
- TAutoPtr<TEvHive::TEvResponseHiveDomainStats> HiveStats;
- TJsonSettings JsonSettings;
+
+namespace NKikimr {
+namespace NViewer {
+
+using namespace NActors;
+
+class TJsonHiveStats : public TViewerPipeClient<TJsonHiveStats> {
+ using TBase = TViewerPipeClient<TJsonHiveStats>;
+ IViewer* Viewer;
+ NMon::TEvHttpInfo::TPtr Event;
+ TAutoPtr<TEvHive::TEvResponseHiveDomainStats> HiveStats;
+ TJsonSettings JsonSettings;
ui32 Timeout = 0;
-
-public:
+
+public:
static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
return NKikimrServices::TActivity::VIEWER_HANDLER;
- }
-
- TJsonHiveStats(IViewer* viewer, NMon::TEvHttpInfo::TPtr &ev)
- : Viewer(viewer)
- , Event(ev)
- {}
-
- void Bootstrap() {
+ }
+
+ TJsonHiveStats(IViewer* viewer, NMon::TEvHttpInfo::TPtr &ev)
+ : Viewer(viewer)
+ , Event(ev)
+ {}
+
+ void Bootstrap() {
const auto& params(Event->Get()->Request.GetParams());
- ui64 hiveId = FromStringWithDefault<ui64>(params.Get("hive_id"), 0);
- JsonSettings.EnumAsNumbers = !FromStringWithDefault<bool>(params.Get("enums"), true);
- JsonSettings.UI64AsString = !FromStringWithDefault<bool>(params.Get("ui64"), false);
- Timeout = FromStringWithDefault<ui32>(params.Get("timeout"), 10000);
- InitConfig(params);
- if (hiveId != 0 ) {
+ ui64 hiveId = FromStringWithDefault<ui64>(params.Get("hive_id"), 0);
+ JsonSettings.EnumAsNumbers = !FromStringWithDefault<bool>(params.Get("enums"), true);
+ JsonSettings.UI64AsString = !FromStringWithDefault<bool>(params.Get("ui64"), false);
+ Timeout = FromStringWithDefault<ui32>(params.Get("timeout"), 10000);
+ InitConfig(params);
+ if (hiveId != 0 ) {
THolder<TEvHive::TEvRequestHiveDomainStats> request = MakeHolder<TEvHive::TEvRequestHiveDomainStats>();
request->Record.SetReturnFollowers(FromStringWithDefault(params.Get("followers"), false));
- request->Record.SetReturnMetrics(FromStringWithDefault(params.Get("metrics"), true));
- SendRequestToPipe(ConnectTabletPipe(hiveId), request.Release());
- Become(&TThis::StateRequestedInfo, TDuration::MilliSeconds(Timeout), new TEvents::TEvWakeup());
- } else {
- ReplyAndPassAway();
- }
- }
-
- STATEFN(StateRequestedInfo) {
- switch (ev->GetTypeRewrite()) {
- hFunc(TEvHive::TEvResponseHiveDomainStats, Handle);
- cFunc(TEvents::TSystem::Wakeup, HandleTimeout);
- }
- }
-
- void Handle(TEvHive::TEvResponseHiveDomainStats::TPtr& ev) {
- HiveStats = ev->Release();
- RequestDone();
- }
-
- void ReplyAndPassAway() {
- TStringStream json;
- if (HiveStats != nullptr) {
- TProtoToJson::ProtoToJson(json, HiveStats->Record, JsonSettings);
- } else {
- json << "null";
- }
- Send(Event->Sender, new NMon::TEvHttpInfoRes(Viewer->GetHTTPOKJSON() + json.Str(), 0, NMon::IEvHttpInfoRes::EContentType::Custom));
- PassAway();
- }
-
- void HandleTimeout() {
- Send(Event->Sender, new NMon::TEvHttpInfoRes(Viewer->GetHTTPGATEWAYTIMEOUT(), 0, NMon::IEvHttpInfoRes::EContentType::Custom));
- PassAway();
- }
-};
-
-template <>
-struct TJsonRequestSchema<TJsonHiveStats> {
+ request->Record.SetReturnMetrics(FromStringWithDefault(params.Get("metrics"), true));
+ SendRequestToPipe(ConnectTabletPipe(hiveId), request.Release());
+ Become(&TThis::StateRequestedInfo, TDuration::MilliSeconds(Timeout), new TEvents::TEvWakeup());
+ } else {
+ ReplyAndPassAway();
+ }
+ }
+
+ STATEFN(StateRequestedInfo) {
+ switch (ev->GetTypeRewrite()) {
+ hFunc(TEvHive::TEvResponseHiveDomainStats, Handle);
+ cFunc(TEvents::TSystem::Wakeup, HandleTimeout);
+ }
+ }
+
+ void Handle(TEvHive::TEvResponseHiveDomainStats::TPtr& ev) {
+ HiveStats = ev->Release();
+ RequestDone();
+ }
+
+ void ReplyAndPassAway() {
+ TStringStream json;
+ if (HiveStats != nullptr) {
+ TProtoToJson::ProtoToJson(json, HiveStats->Record, JsonSettings);
+ } else {
+ json << "null";
+ }
+ Send(Event->Sender, new NMon::TEvHttpInfoRes(Viewer->GetHTTPOKJSON() + json.Str(), 0, NMon::IEvHttpInfoRes::EContentType::Custom));
+ PassAway();
+ }
+
+ void HandleTimeout() {
+ Send(Event->Sender, new NMon::TEvHttpInfoRes(Viewer->GetHTTPGATEWAYTIMEOUT(), 0, NMon::IEvHttpInfoRes::EContentType::Custom));
+ PassAway();
+ }
+};
+
+template <>
+struct TJsonRequestSchema<TJsonHiveStats> {
static TString GetSchema() {
- TStringStream stream;
- TProtoToJson::ProtoToJsonSchema<TEvHive::TEvResponseHiveDomainStats::ProtoRecordType>(stream);
- return stream.Str();
- }
-};
-
-template <>
-struct TJsonRequestParameters<TJsonHiveStats> {
+ TStringStream stream;
+ TProtoToJson::ProtoToJsonSchema<TEvHive::TEvResponseHiveDomainStats::ProtoRecordType>(stream);
+ return stream.Str();
+ }
+};
+
+template <>
+struct TJsonRequestParameters<TJsonHiveStats> {
static TString GetParameters() {
- return R"___([{"name":"hive_id","in":"query","description":"hive identifier (tablet id)","required":true,"type":"string"},
- {"name":"followers","in":"query","description":"return followers","required":false,"type":"boolean"},
- {"name":"metrics","in":"query","description":"return tablet metrics","required":false,"type":"boolean"},
- {"name":"enums","in":"query","description":"convert enums to strings","required":false,"type":"boolean"},
- {"name":"ui64","in":"query","description":"return ui64 as number","required":false,"type":"boolean"},
- {"name":"timeout","in":"query","description":"timeout in ms","required":false,"type":"integer"}])___";
- }
-};
-
-template <>
-struct TJsonRequestSummary<TJsonHiveStats> {
+ return R"___([{"name":"hive_id","in":"query","description":"hive identifier (tablet id)","required":true,"type":"string"},
+ {"name":"followers","in":"query","description":"return followers","required":false,"type":"boolean"},
+ {"name":"metrics","in":"query","description":"return tablet metrics","required":false,"type":"boolean"},
+ {"name":"enums","in":"query","description":"convert enums to strings","required":false,"type":"boolean"},
+ {"name":"ui64","in":"query","description":"return ui64 as number","required":false,"type":"boolean"},
+ {"name":"timeout","in":"query","description":"timeout in ms","required":false,"type":"integer"}])___";
+ }
+};
+
+template <>
+struct TJsonRequestSummary<TJsonHiveStats> {
static TString GetSummary() {
- return "\"Hive statistics\"";
- }
-};
-
-template <>
-struct TJsonRequestDescription<TJsonHiveStats> {
+ return "\"Hive statistics\"";
+ }
+};
+
+template <>
+struct TJsonRequestDescription<TJsonHiveStats> {
static TString GetDescription() {
- return "\"Returns information about Hive statistics\"";
- }
-};
-
-}
-}
+ return "\"Returns information about Hive statistics\"";
+ }
+};
+
+}
+}
diff --git a/ydb/core/viewer/json_hotkeys.h b/ydb/core/viewer/json_hotkeys.h
index 0b4008b5274..290e385a9bc 100644
--- a/ydb/core/viewer/json_hotkeys.h
+++ b/ydb/core/viewer/json_hotkeys.h
@@ -20,7 +20,7 @@ using NSchemeShard::TEvSchemeShard;
class TJsonHotkeys : public TViewerPipeClient<TJsonHotkeys> {
static const bool WithRetry = false;
using TBase = TViewerPipeClient<TJsonHotkeys>;
- IViewer* Viewer;
+ IViewer* Viewer;
NMon::TEvHttpInfo::TPtr Event;
TAutoPtr<TEvSchemeShard::TEvDescribeSchemeResult> DescribeResult;
ui32 Timeout = 0;
@@ -41,9 +41,9 @@ public:
return NKikimrServices::TActivity::VIEWER_HANDLER;
}
- TJsonHotkeys(IViewer* viewer, NMon::TEvHttpInfo::TPtr &ev)
- : Viewer(viewer)
- , Event(ev)
+ TJsonHotkeys(IViewer* viewer, NMon::TEvHttpInfo::TPtr &ev)
+ : Viewer(viewer)
+ , Event(ev)
{}
void FillParams(NKikimrSchemeOp::TDescribePath* record, const TCgiParameters& params) {
@@ -53,7 +53,7 @@ public:
record->MutableOptions()->SetReturnPartitionStats(true);
}
- void Bootstrap() {
+ void Bootstrap() {
const auto& params(Event->Get()->Request.GetParams());
Timeout = FromStringWithDefault<ui32>(params.Get("timeout"), 10000);
Limit = FromStringWithDefault<ui32>(params.Get("limit"), 10);
@@ -64,21 +64,21 @@ public:
THolder<TEvTxUserProxy::TEvNavigate> request = MakeHolder<TEvTxUserProxy::TEvNavigate>();
FillParams(request->Record.MutableDescribePath(), params);
request->Record.SetUserToken(Event->Get()->UserToken);
- SendRequest(MakeTxProxyID(), request.Release());
+ SendRequest(MakeTxProxyID(), request.Release());
- Become(&TThis::StateRequestedDescribe, TDuration::MilliSeconds(Timeout), new TEvents::TEvWakeup());
+ Become(&TThis::StateRequestedDescribe, TDuration::MilliSeconds(Timeout), new TEvents::TEvWakeup());
}
- STATEFN(StateRequestedDescribe) {
+ STATEFN(StateRequestedDescribe) {
switch (ev->GetTypeRewrite()) {
- hFunc(TEvSchemeShard::TEvDescribeSchemeResult, Handle);
- hFunc(TEvDataShard::TEvGetDataHistogramResponse, Handle);
- hFunc(TEvTabletPipe::TEvClientConnected, TBase::Handle);
- cFunc(TEvents::TSystem::Wakeup, HandleTimeout);
+ hFunc(TEvSchemeShard::TEvDescribeSchemeResult, Handle);
+ hFunc(TEvDataShard::TEvGetDataHistogramResponse, Handle);
+ hFunc(TEvTabletPipe::TEvClientConnected, TBase::Handle);
+ cFunc(TEvents::TSystem::Wakeup, HandleTimeout);
}
}
- void Handle(TEvSchemeShard::TEvDescribeSchemeResult::TPtr& ev) {
+ void Handle(TEvSchemeShard::TEvDescribeSchemeResult::TPtr& ev) {
DescribeResult = ev->Release();
const auto& pathDescription = DescribeResult->GetRecord().GetPathDescription();
const auto& partitions = pathDescription.GetTablePartitions();
@@ -90,20 +90,20 @@ public:
}
Sort(tabletsOrder, std::greater<std::pair<ui64, int>>());
- ui32 tablets = (ui32) std::max(1, (int) std::ceil(PollingFactor * tabletsOrder.size()));
+ ui32 tablets = (ui32) std::max(1, (int) std::ceil(PollingFactor * tabletsOrder.size()));
- for (ui32 i = 0; i < tablets; ++i) {
+ for (ui32 i = 0; i < tablets; ++i) {
THolder<TEvDataShard::TEvGetDataHistogramRequest> request = MakeHolder<TEvDataShard::TEvGetDataHistogramRequest>();
if (EnableSampling) {
request->Record.SetCollectKeySampleMs(30000); // 30 sec
}
request->Record.SetActualData(true);
ui64 datashardId = partitions.Get(tabletsOrder[i].second).GetDatashardId();
- SendRequestToPipe(ConnectTabletPipe(datashardId), request.Release());
+ SendRequestToPipe(ConnectTabletPipe(datashardId), request.Release());
}
}
- void Handle(TEvDataShard::TEvGetDataHistogramResponse::TPtr& ev) {
+ void Handle(TEvDataShard::TEvGetDataHistogramResponse::TPtr& ev) {
const auto& rec = ev->Get()->Record;
for (const auto& i: rec.GetTableHistograms()) {
for (const auto& item: i.GetKeyAccessSample().GetItems()) {
@@ -115,7 +115,7 @@ public:
}
}
- RequestDone();
+ RequestDone();
}
NJson::TJsonValue BuildResponse() {
@@ -136,8 +136,8 @@ public:
return root;
}
- void ReplyAndPassAway() {
- TString headers = Viewer->GetHTTPOKJSON();
+ void ReplyAndPassAway() {
+ TString headers = Viewer->GetHTTPOKJSON();
if (DescribeResult != nullptr) {
switch (DescribeResult->GetRecord().GetStatus()) {
case NKikimrScheme::StatusAccessDenied:
@@ -150,15 +150,15 @@ public:
NJson::TJsonValue root = BuildResponse();
TString json = NJson::WriteJson(root, false);
- Send(Event->Sender, new NMon::TEvHttpInfoRes(headers + json, 0, NMon::IEvHttpInfoRes::EContentType::Custom));
- PassAway();
+ Send(Event->Sender, new NMon::TEvHttpInfoRes(headers + json, 0, NMon::IEvHttpInfoRes::EContentType::Custom));
+ PassAway();
}
- void HandleTimeout() {
- Send(Event->Sender, new NMon::TEvHttpInfoRes(Viewer->GetHTTPGATEWAYTIMEOUT(), 0, NMon::IEvHttpInfoRes::EContentType::Custom));
- PassAway();
+ void HandleTimeout() {
+ Send(Event->Sender, new NMon::TEvHttpInfoRes(Viewer->GetHTTPGATEWAYTIMEOUT(), 0, NMon::IEvHttpInfoRes::EContentType::Custom));
+ PassAway();
}
};
-
+
}
}
diff --git a/ydb/core/viewer/json_labeledcounters.h b/ydb/core/viewer/json_labeledcounters.h
index 1fb8362f059..6fce18b32b2 100644
--- a/ydb/core/viewer/json_labeledcounters.h
+++ b/ydb/core/viewer/json_labeledcounters.h
@@ -1,4 +1,4 @@
-#pragma once
+#pragma once
#include <library/cpp/actors/core/actor_bootstrapped.h>
#include <library/cpp/actors/core/mon.h>
#include <ydb/core/base/tablet_pipe.h>
@@ -6,44 +6,44 @@
#include <ydb/core/tablet/tablet_counters_aggregator.h>
#include <ydb/core/tx/tx_proxy/proxy.h>
#include <ydb/core/util/wildcard.h>
-#include "viewer.h"
-
-namespace NKikimr {
-namespace NViewer {
-
-using namespace NActors;
-
-class TJsonLabeledCounters : public TActorBootstrapped<TJsonLabeledCounters> {
- using TBase = TActorBootstrapped<TJsonLabeledCounters>;
- IViewer* Viewer;
- NMon::TEvHttpInfo::TPtr Event;
- NKikimrTabletCountersAggregator::TEvTabletLabeledCountersResponse LabeledCountersResult;
- TJsonSettings JsonSettings;
- TString Groups;
- TString GroupNames;
+#include "viewer.h"
+
+namespace NKikimr {
+namespace NViewer {
+
+using namespace NActors;
+
+class TJsonLabeledCounters : public TActorBootstrapped<TJsonLabeledCounters> {
+ using TBase = TActorBootstrapped<TJsonLabeledCounters>;
+ IViewer* Viewer;
+ NMon::TEvHttpInfo::TPtr Event;
+ NKikimrTabletCountersAggregator::TEvTabletLabeledCountersResponse LabeledCountersResult;
+ TJsonSettings JsonSettings;
+ TString Groups;
+ TString GroupNames;
TString Topic;
TString Consumer;
TString DC;
- TVector<TString> Counters;
- ui32 Version = 1;
+ TVector<TString> Counters;
+ ui32 Version = 1;
ui32 Timeout = 0;
-
-public:
+
+public:
static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
return NKikimrServices::TActivity::VIEWER_HANDLER;
- }
-
- TJsonLabeledCounters(IViewer* viewer, NMon::TEvHttpInfo::TPtr &ev)
- : Viewer(viewer)
- , Event(ev)
- {}
-
- void Bootstrap(const TActorContext& ctx) {
+ }
+
+ TJsonLabeledCounters(IViewer* viewer, NMon::TEvHttpInfo::TPtr &ev)
+ : Viewer(viewer)
+ , Event(ev)
+ {}
+
+ void Bootstrap(const TActorContext& ctx) {
const auto& params(Event->Get()->Request.GetParams());
- JsonSettings.EnumAsNumbers = !FromStringWithDefault<bool>(params.Get("enums"), false);
- JsonSettings.UI64AsString = !FromStringWithDefault<bool>(params.Get("ui64"), false);
- Timeout = FromStringWithDefault<ui32>(params.Get("timeout"), 10000);
- Groups = params.Get("group");
+ JsonSettings.EnumAsNumbers = !FromStringWithDefault<bool>(params.Get("enums"), false);
+ JsonSettings.UI64AsString = !FromStringWithDefault<bool>(params.Get("ui64"), false);
+ Timeout = FromStringWithDefault<ui32>(params.Get("timeout"), 10000);
+ Groups = params.Get("group");
Topic = NPersQueue::ConvertNewTopicName(params.Get("topic"));
if (Topic.empty())
Topic = "*";
@@ -51,10 +51,10 @@ public:
DC = params.Get("dc");
if (DC.empty())
DC = "*";
- GroupNames = params.Get("group_names");
- Split(params.Get("counters"), ",", Counters);
- Version = FromStringWithDefault<ui32>(params.Get("version"), Version);
- Sort(Counters);
+ GroupNames = params.Get("group_names");
+ Split(params.Get("counters"), ",", Counters);
+ Version = FromStringWithDefault<ui32>(params.Get("version"), Version);
+ Sort(Counters);
if (Version >= 3) {
TString topic = "rt3." + DC + "--" + Topic;
if (!Consumer.empty()) {
@@ -67,124 +67,124 @@ public:
}
}
CreateClusterLabeledCountersAggregator(ctx.SelfID, TTabletTypes::PERSQUEUE, ctx, Version, Version >= 2 ? Groups : TString());
- Become(&TThis::StateRequestedTopicInfo, ctx, TDuration::MilliSeconds(Timeout), new TEvents::TEvWakeup());
- }
-
- void Die(const TActorContext& ctx) override {
- TBase::Die(ctx);
- }
-
- STFUNC(StateRequestedTopicInfo) {
- switch (ev->GetTypeRewrite()) {
- HFunc(TEvTabletCounters::TEvTabletLabeledCountersResponse, Handle);
- CFunc(TEvents::TSystem::Wakeup, HandleTimeout);
- }
- }
-
- void Handle(TEvTabletCounters::TEvTabletLabeledCountersResponse::TPtr &ev, const TActorContext &ctx) {
- if (Version == 1) {
- for (ui32 i = 0; i < ev->Get()->Record.LabeledCountersByGroupSize(); ++i) {
- auto& uc = *ev->Get()->Record.MutableLabeledCountersByGroup(i);
- if (!Groups.empty() && !IsMatchesWildcards(uc.GetGroup(), Groups)) {
- continue;
- }
- if (!GroupNames.empty() && !IsMatchesWildcard(uc.GetGroupNames(), GroupNames)) {
- continue;
- }
- if (Counters.empty()) {
- LabeledCountersResult.AddLabeledCountersByGroup()->Swap(&uc);
- } else {
- auto& lc = *LabeledCountersResult.AddLabeledCountersByGroup();
- lc.SetGroup(uc.GetGroup());
- lc.SetGroupNames(uc.GetGroupNames());
- for (auto& c : *uc.MutableLabeledCounter()) {
- if (BinarySearch(Counters.begin(), Counters.end(), c.GetName())) {
- lc.AddLabeledCounter()->Swap(&c);
- }
- }
- }
- }
+ Become(&TThis::StateRequestedTopicInfo, ctx, TDuration::MilliSeconds(Timeout), new TEvents::TEvWakeup());
+ }
+
+ void Die(const TActorContext& ctx) override {
+ TBase::Die(ctx);
+ }
+
+ STFUNC(StateRequestedTopicInfo) {
+ switch (ev->GetTypeRewrite()) {
+ HFunc(TEvTabletCounters::TEvTabletLabeledCountersResponse, Handle);
+ CFunc(TEvents::TSystem::Wakeup, HandleTimeout);
+ }
+ }
+
+ void Handle(TEvTabletCounters::TEvTabletLabeledCountersResponse::TPtr &ev, const TActorContext &ctx) {
+ if (Version == 1) {
+ for (ui32 i = 0; i < ev->Get()->Record.LabeledCountersByGroupSize(); ++i) {
+ auto& uc = *ev->Get()->Record.MutableLabeledCountersByGroup(i);
+ if (!Groups.empty() && !IsMatchesWildcards(uc.GetGroup(), Groups)) {
+ continue;
+ }
+ if (!GroupNames.empty() && !IsMatchesWildcard(uc.GetGroupNames(), GroupNames)) {
+ continue;
+ }
+ if (Counters.empty()) {
+ LabeledCountersResult.AddLabeledCountersByGroup()->Swap(&uc);
+ } else {
+ auto& lc = *LabeledCountersResult.AddLabeledCountersByGroup();
+ lc.SetGroup(uc.GetGroup());
+ lc.SetGroupNames(uc.GetGroupNames());
+ for (auto& c : *uc.MutableLabeledCounter()) {
+ if (BinarySearch(Counters.begin(), Counters.end(), c.GetName())) {
+ lc.AddLabeledCounter()->Swap(&c);
+ }
+ }
+ }
+ }
} else if (Version >= 2) {
- const NKikimrTabletCountersAggregator::TEvTabletLabeledCountersResponse& source(ev->Get()->Record);
- TVector<TMaybe<ui32>> counterNamesMapping;
- counterNamesMapping.reserve(source.CounterNamesSize());
- for (const TString& counterName : source.GetCounterNames()) {
- if (Counters.empty() || BinarySearch(Counters.begin(), Counters.end(), counterName)) {
- counterNamesMapping.push_back(LabeledCountersResult.CounterNamesSize());
- LabeledCountersResult.AddCounterNames(counterName);
- } else {
- counterNamesMapping.push_back(Nothing());
- }
- }
- for (ui32 i = 0; i < ev->Get()->Record.LabeledCountersByGroupSize(); ++i) {
- auto& uc = *ev->Get()->Record.MutableLabeledCountersByGroup(i);
- auto& lc = *LabeledCountersResult.AddLabeledCountersByGroup();
- lc.SetGroup(uc.GetGroup());
- for (auto& c : *uc.MutableLabeledCounter()) {
- ui32 nameId = c.GetNameId();
- if (counterNamesMapping[c.GetNameId()].Defined()) {
- nameId = counterNamesMapping[c.GetNameId()].GetRef();
- auto* lci = lc.AddLabeledCounter();
- lci->SetValue(c.GetValue());
- lci->SetNameId(nameId);
- }
- }
- }
- }
- ReplyAndDie(ctx);
- }
-
- void ReplyAndDie(const TActorContext &ctx) {
- TStringStream json;
- TProtoToJson::ProtoToJson(json, LabeledCountersResult, JsonSettings);
- ctx.Send(Event->Sender, new NMon::TEvHttpInfoRes(Viewer->GetHTTPOKJSON() + json.Str(), 0, NMon::IEvHttpInfoRes::EContentType::Custom));
- Die(ctx);
- }
-
- void HandleTimeout(const TActorContext &ctx) {
- ctx.Send(Event->Sender, new NMon::TEvHttpInfoRes(Viewer->GetHTTPGATEWAYTIMEOUT(), 0, NMon::IEvHttpInfoRes::EContentType::Custom));
- Die(ctx);
- }
-};
-
-template <>
-struct TJsonRequestSchema<TJsonLabeledCounters> {
- static TString GetSchema() {
- TStringStream stream;
- TProtoToJson::ProtoToJsonSchema<TEvTabletCounters::TEvTabletLabeledCountersResponse::ProtoRecordType>(stream);
- return stream.Str();
- }
-};
-
-template <>
-struct TJsonRequestParameters<TJsonLabeledCounters> {
- static TString GetParameters() {
- return R"___([{"name":"group","in":"query","description":"group name","required":false,"type":"string"},
- {"name":"dc","in":"query","description":"datacenter name","required":false,"type":"string", "default":"*"},
- {"name":"topic","in":"query","description":"topic name","required":false,"type":"string", "default":"*"},
- {"name":"consumer","in":"query","description":"consumer name","required":false,"type":"string", "default":""},
- {"name":"group_names","in":"query","description":"group names","required":false,"type":"string"},
- {"name":"counters","in":"query","description":"counters names","required":false,"type":"string"},
- {"name":"enums","in":"query","description":"convert enums to strings","required":false,"type":"boolean","default":false},
- {"name":"all","in":"query","description":"return information about all topics and clients","required":false,"type":"boolean","default":false},
- {"name":"ui64","in":"query","description":"return ui64 as number","required":false,"type":"boolean","default":false},
- {"name":"timeout","in":"query","description":"timeout in ms","required":false,"type":"integer","default":10000}])___";
- }
-};
-
-template <>
-struct TJsonRequestSummary<TJsonLabeledCounters> {
- static TString GetSummary() {
- return "\"Labeled counters info\"";
- }
-};
-
-template <>
-struct TJsonRequestDescription<TJsonLabeledCounters> {
- static TString GetDescription() {
- return "\"Returns information about labeled counters\"";
- }
-};
-
-}
-}
+ const NKikimrTabletCountersAggregator::TEvTabletLabeledCountersResponse& source(ev->Get()->Record);
+ TVector<TMaybe<ui32>> counterNamesMapping;
+ counterNamesMapping.reserve(source.CounterNamesSize());
+ for (const TString& counterName : source.GetCounterNames()) {
+ if (Counters.empty() || BinarySearch(Counters.begin(), Counters.end(), counterName)) {
+ counterNamesMapping.push_back(LabeledCountersResult.CounterNamesSize());
+ LabeledCountersResult.AddCounterNames(counterName);
+ } else {
+ counterNamesMapping.push_back(Nothing());
+ }
+ }
+ for (ui32 i = 0; i < ev->Get()->Record.LabeledCountersByGroupSize(); ++i) {
+ auto& uc = *ev->Get()->Record.MutableLabeledCountersByGroup(i);
+ auto& lc = *LabeledCountersResult.AddLabeledCountersByGroup();
+ lc.SetGroup(uc.GetGroup());
+ for (auto& c : *uc.MutableLabeledCounter()) {
+ ui32 nameId = c.GetNameId();
+ if (counterNamesMapping[c.GetNameId()].Defined()) {
+ nameId = counterNamesMapping[c.GetNameId()].GetRef();
+ auto* lci = lc.AddLabeledCounter();
+ lci->SetValue(c.GetValue());
+ lci->SetNameId(nameId);
+ }
+ }
+ }
+ }
+ ReplyAndDie(ctx);
+ }
+
+ void ReplyAndDie(const TActorContext &ctx) {
+ TStringStream json;
+ TProtoToJson::ProtoToJson(json, LabeledCountersResult, JsonSettings);
+ ctx.Send(Event->Sender, new NMon::TEvHttpInfoRes(Viewer->GetHTTPOKJSON() + json.Str(), 0, NMon::IEvHttpInfoRes::EContentType::Custom));
+ Die(ctx);
+ }
+
+ void HandleTimeout(const TActorContext &ctx) {
+ ctx.Send(Event->Sender, new NMon::TEvHttpInfoRes(Viewer->GetHTTPGATEWAYTIMEOUT(), 0, NMon::IEvHttpInfoRes::EContentType::Custom));
+ Die(ctx);
+ }
+};
+
+template <>
+struct TJsonRequestSchema<TJsonLabeledCounters> {
+ static TString GetSchema() {
+ TStringStream stream;
+ TProtoToJson::ProtoToJsonSchema<TEvTabletCounters::TEvTabletLabeledCountersResponse::ProtoRecordType>(stream);
+ return stream.Str();
+ }
+};
+
+template <>
+struct TJsonRequestParameters<TJsonLabeledCounters> {
+ static TString GetParameters() {
+ return R"___([{"name":"group","in":"query","description":"group name","required":false,"type":"string"},
+ {"name":"dc","in":"query","description":"datacenter name","required":false,"type":"string", "default":"*"},
+ {"name":"topic","in":"query","description":"topic name","required":false,"type":"string", "default":"*"},
+ {"name":"consumer","in":"query","description":"consumer name","required":false,"type":"string", "default":""},
+ {"name":"group_names","in":"query","description":"group names","required":false,"type":"string"},
+ {"name":"counters","in":"query","description":"counters names","required":false,"type":"string"},
+ {"name":"enums","in":"query","description":"convert enums to strings","required":false,"type":"boolean","default":false},
+ {"name":"all","in":"query","description":"return information about all topics and clients","required":false,"type":"boolean","default":false},
+ {"name":"ui64","in":"query","description":"return ui64 as number","required":false,"type":"boolean","default":false},
+ {"name":"timeout","in":"query","description":"timeout in ms","required":false,"type":"integer","default":10000}])___";
+ }
+};
+
+template <>
+struct TJsonRequestSummary<TJsonLabeledCounters> {
+ static TString GetSummary() {
+ return "\"Labeled counters info\"";
+ }
+};
+
+template <>
+struct TJsonRequestDescription<TJsonLabeledCounters> {
+ static TString GetDescription() {
+ return "\"Returns information about labeled counters\"";
+ }
+};
+
+}
+}
diff --git a/ydb/core/viewer/json_metainfo.h b/ydb/core/viewer/json_metainfo.h
index 6a512f12199..54064d74037 100644
--- a/ydb/core/viewer/json_metainfo.h
+++ b/ydb/core/viewer/json_metainfo.h
@@ -1,6 +1,6 @@
-#pragma once
-#include <unordered_map>
-#include <unordered_set>
+#pragma once
+#include <unordered_map>
+#include <unordered_set>
#include <library/cpp/actors/core/actor_bootstrapped.h>
#include <library/cpp/actors/core/mon.h>
#include <ydb/core/base/appdata.h>
@@ -14,154 +14,154 @@
#include <ydb/core/tx/schemeshard/schemeshard.h>
#include <ydb/core/tx/tx_proxy/proxy.h>
#include <ydb/core/viewer/protos/viewer.pb.h>
-#include "browse.h"
+#include "browse.h"
#include <ydb/core/viewer/json/json.h>
-#include "viewer.h"
-#include "wb_aggregate.h"
-
-namespace NKikimr {
-namespace NViewer {
-
-using namespace NActors;
-
-class TJsonMetaInfo : public TActorBootstrapped<TJsonMetaInfo> {
- using TBase = TActorBootstrapped<TJsonMetaInfo>;
- IViewer* Viewer;
- NMon::TEvHttpInfo::TPtr Event;
- TJsonSettings JsonSettings;
+#include "viewer.h"
+#include "wb_aggregate.h"
+
+namespace NKikimr {
+namespace NViewer {
+
+using namespace NActors;
+
+class TJsonMetaInfo : public TActorBootstrapped<TJsonMetaInfo> {
+ using TBase = TActorBootstrapped<TJsonMetaInfo>;
+ IViewer* Viewer;
+ NMon::TEvHttpInfo::TPtr Event;
+ TJsonSettings JsonSettings;
ui32 Timeout = 0;
bool Counters = false;
- NKikimrViewer::TMetaInfo MetaInfo;
+ NKikimrViewer::TMetaInfo MetaInfo;
TActorId BrowseActorID;
using TBrowseRequestKey = std::tuple<TActorId, TTabletId, ui32>;
- std::unordered_multiset<TBrowseRequestKey> BrowseRequestsInFlight;
-
-public:
+ std::unordered_multiset<TBrowseRequestKey> BrowseRequestsInFlight;
+
+public:
static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
return NKikimrServices::TActivity::VIEWER_HANDLER;
- }
-
- TJsonMetaInfo(IViewer *viewer, NMon::TEvHttpInfo::TPtr &ev)
- : Viewer(viewer)
- , Event(ev)
- {}
-
- void Bootstrap(const TActorContext& ctx) {
+ }
+
+ TJsonMetaInfo(IViewer *viewer, NMon::TEvHttpInfo::TPtr &ev)
+ : Viewer(viewer)
+ , Event(ev)
+ {}
+
+ void Bootstrap(const TActorContext& ctx) {
const auto& params(Event->Get()->Request.GetParams());
- JsonSettings.EnumAsNumbers = !FromStringWithDefault<bool>(params.Get("enums"), true);
- JsonSettings.UI64AsString = !FromStringWithDefault<bool>(params.Get("ui64"), false);
- Timeout = FromStringWithDefault<ui32>(params.Get("timeout"), 10000);
- Counters = FromStringWithDefault(params.Get("counters"), false);
- TString path = params.Get("path");
+ JsonSettings.EnumAsNumbers = !FromStringWithDefault<bool>(params.Get("enums"), true);
+ JsonSettings.UI64AsString = !FromStringWithDefault<bool>(params.Get("ui64"), false);
+ Timeout = FromStringWithDefault<ui32>(params.Get("timeout"), 10000);
+ Counters = FromStringWithDefault(params.Get("counters"), false);
+ TString path = params.Get("path");
BrowseActorID = ctx.RegisterWithSameMailbox(new TBrowse(Viewer, ctx.SelfID, path, Event->Get()->UserToken));
- Become(&TThis::StateWait, ctx, TDuration::MilliSeconds(Timeout), new TEvents::TEvWakeup());
- }
-
- void Die(const TActorContext& ctx) override {
- ctx.Send(BrowseActorID, new TEvents::TEvPoisonPill());
- TBase::Die(ctx);
- }
-
- STFUNC(StateWait) {
- switch (ev->GetTypeRewrite()) {
+ Become(&TThis::StateWait, ctx, TDuration::MilliSeconds(Timeout), new TEvents::TEvWakeup());
+ }
+
+ void Die(const TActorContext& ctx) override {
+ ctx.Send(BrowseActorID, new TEvents::TEvPoisonPill());
+ TBase::Die(ctx);
+ }
+
+ STFUNC(StateWait) {
+ switch (ev->GetTypeRewrite()) {
HFunc(NViewerEvents::TEvBrowseResponse, Handle);
- HFunc(NViewerEvents::TEvBrowseRequestSent, Handle);
- HFunc(NViewerEvents::TEvBrowseRequestCompleted, Handle);
- HFunc(NMon::TEvHttpInfoRes, Handle);
- CFunc(TEvents::TSystem::Wakeup, HandleTimeout);
- }
- }
-
- void Handle(NMon::TEvHttpInfoRes::TPtr &ev, const TActorContext &ctx) {
- ctx.ExecutorThread.Send(ev->Forward(Event->Sender));
- Die(ctx);
- }
-
+ HFunc(NViewerEvents::TEvBrowseRequestSent, Handle);
+ HFunc(NViewerEvents::TEvBrowseRequestCompleted, Handle);
+ HFunc(NMon::TEvHttpInfoRes, Handle);
+ CFunc(TEvents::TSystem::Wakeup, HandleTimeout);
+ }
+ }
+
+ void Handle(NMon::TEvHttpInfoRes::TPtr &ev, const TActorContext &ctx) {
+ ctx.ExecutorThread.Send(ev->Forward(Event->Sender));
+ Die(ctx);
+ }
+
void Handle(NViewerEvents::TEvBrowseResponse::TPtr &ev, const TActorContext &ctx) {
NViewerEvents::TEvBrowseResponse& event(*ev->Get());
- if (!event.Error.empty()) {
- ctx.Send(Event->Sender, new NMon::TEvHttpInfoRes(event.Error, 0, NMon::IEvHttpInfoRes::EContentType::Custom));
- return Die(ctx);
- }
- MetaInfo.MergeFrom(event.MetaInfo);
- if (!Counters) {
- // TODO(xenoxeno): it could be a little bit more effective
- MetaInfo.ClearCounters();
- }
- ReplyAndDie(ctx);
- }
-
- void Handle(NViewerEvents::TEvBrowseRequestSent::TPtr& ev, const TActorContext&) {
- NViewerEvents::TEvBrowseRequestSent& event(*ev->Get());
- BrowseRequestsInFlight.emplace(event.Actor, event.Tablet, event.Event);
- }
-
- void Handle(NViewerEvents::TEvBrowseRequestCompleted::TPtr& ev, const TActorContext&) {
- NViewerEvents::TEvBrowseRequestCompleted& event(*ev->Get());
- auto it = BrowseRequestsInFlight.find({event.Actor, event.Tablet, event.Event});
- if (it != BrowseRequestsInFlight.end()) {
- // we could not delete by key, it could be many items with the same key
- BrowseRequestsInFlight.erase(it);
- }
- BrowseRequestsInFlight.emplace(event.Actor, event.Tablet, event.Event);
- }
-
- void ReplyAndDie(const TActorContext &ctx) {
- TStringStream json;
- TProtoToJson::ProtoToJson(json, MetaInfo, JsonSettings);
- ctx.Send(Event->Sender, new NMon::TEvHttpInfoRes(Viewer->GetHTTPOKJSON() + json.Str(), 0, NMon::IEvHttpInfoRes::EContentType::Custom));
- Die(ctx);
- }
-
- void HandleTimeout(const TActorContext &ctx) {
- TStringStream result;
- result << Viewer->GetHTTPGATEWAYTIMEOUT();
- RenderPendingRequests(result);
- ctx.Send(Event->Sender, new NMon::TEvHttpInfoRes(result.Str(), 0, NMon::IEvHttpInfoRes::EContentType::Custom));
- Die(ctx);
- }
-
- void RenderPendingRequests(IOutputStream& html) {
- for (const auto& request : BrowseRequestsInFlight) {
- html << request << Endl;
- }
- }
-};
-
-template <>
-struct TJsonRequestSchema<TJsonMetaInfo> {
+ if (!event.Error.empty()) {
+ ctx.Send(Event->Sender, new NMon::TEvHttpInfoRes(event.Error, 0, NMon::IEvHttpInfoRes::EContentType::Custom));
+ return Die(ctx);
+ }
+ MetaInfo.MergeFrom(event.MetaInfo);
+ if (!Counters) {
+ // TODO(xenoxeno): it could be a little bit more effective
+ MetaInfo.ClearCounters();
+ }
+ ReplyAndDie(ctx);
+ }
+
+ void Handle(NViewerEvents::TEvBrowseRequestSent::TPtr& ev, const TActorContext&) {
+ NViewerEvents::TEvBrowseRequestSent& event(*ev->Get());
+ BrowseRequestsInFlight.emplace(event.Actor, event.Tablet, event.Event);
+ }
+
+ void Handle(NViewerEvents::TEvBrowseRequestCompleted::TPtr& ev, const TActorContext&) {
+ NViewerEvents::TEvBrowseRequestCompleted& event(*ev->Get());
+ auto it = BrowseRequestsInFlight.find({event.Actor, event.Tablet, event.Event});
+ if (it != BrowseRequestsInFlight.end()) {
+ // we could not delete by key, it could be many items with the same key
+ BrowseRequestsInFlight.erase(it);
+ }
+ BrowseRequestsInFlight.emplace(event.Actor, event.Tablet, event.Event);
+ }
+
+ void ReplyAndDie(const TActorContext &ctx) {
+ TStringStream json;
+ TProtoToJson::ProtoToJson(json, MetaInfo, JsonSettings);
+ ctx.Send(Event->Sender, new NMon::TEvHttpInfoRes(Viewer->GetHTTPOKJSON() + json.Str(), 0, NMon::IEvHttpInfoRes::EContentType::Custom));
+ Die(ctx);
+ }
+
+ void HandleTimeout(const TActorContext &ctx) {
+ TStringStream result;
+ result << Viewer->GetHTTPGATEWAYTIMEOUT();
+ RenderPendingRequests(result);
+ ctx.Send(Event->Sender, new NMon::TEvHttpInfoRes(result.Str(), 0, NMon::IEvHttpInfoRes::EContentType::Custom));
+ Die(ctx);
+ }
+
+ void RenderPendingRequests(IOutputStream& html) {
+ for (const auto& request : BrowseRequestsInFlight) {
+ html << request << Endl;
+ }
+ }
+};
+
+template <>
+struct TJsonRequestSchema<TJsonMetaInfo> {
static TString GetSchema() {
- TStringStream stream;
- TProtoToJson::ProtoToJsonSchema<NKikimrViewer::TMetaInfo>(stream);
- return stream.Str();
- }
-};
-
-template <>
-struct TJsonRequestParameters<TJsonMetaInfo> {
+ TStringStream stream;
+ TProtoToJson::ProtoToJsonSchema<NKikimrViewer::TMetaInfo>(stream);
+ return stream.Str();
+ }
+};
+
+template <>
+struct TJsonRequestParameters<TJsonMetaInfo> {
static TString GetParameters() {
- return R"___([{"name":"path","in":"query","description":"schema path","required":false,"type":"string"},
- {"name":"tablet_id","in":"query","description":"tablet identifier","required":false,"type":"integer"},
- {"name":"enums","in":"query","description":"convert enums to strings","required":false,"type":"boolean"},
- {"name":"counters","in":"query","description":"return tablet counters","required":false,"type":"boolean"},
- {"name":"ui64","in":"query","description":"return ui64 as number","required":false,"type":"boolean"},
- {"name":"timeout","in":"query","description":"timeout in ms","required":false,"type":"integer"}])___";
- }
-};
-
-template <>
-struct TJsonRequestSummary<TJsonMetaInfo> {
+ return R"___([{"name":"path","in":"query","description":"schema path","required":false,"type":"string"},
+ {"name":"tablet_id","in":"query","description":"tablet identifier","required":false,"type":"integer"},
+ {"name":"enums","in":"query","description":"convert enums to strings","required":false,"type":"boolean"},
+ {"name":"counters","in":"query","description":"return tablet counters","required":false,"type":"boolean"},
+ {"name":"ui64","in":"query","description":"return ui64 as number","required":false,"type":"boolean"},
+ {"name":"timeout","in":"query","description":"timeout in ms","required":false,"type":"integer"}])___";
+ }
+};
+
+template <>
+struct TJsonRequestSummary<TJsonMetaInfo> {
static TString GetSummary() {
- return "\"Schema meta information\"";
- }
-};
-
-template <>
-struct TJsonRequestDescription<TJsonMetaInfo> {
+ return "\"Schema meta information\"";
+ }
+};
+
+template <>
+struct TJsonRequestDescription<TJsonMetaInfo> {
static TString GetDescription() {
- return "\"Returns meta information about schema path\"";
- }
-};
-
-}
-}
+ return "\"Returns meta information about schema path\"";
+ }
+};
+
+}
+}
diff --git a/ydb/core/viewer/json_netinfo.h b/ydb/core/viewer/json_netinfo.h
index defcd32dc64..3d7c3835a0a 100644
--- a/ydb/core/viewer/json_netinfo.h
+++ b/ydb/core/viewer/json_netinfo.h
@@ -1,4 +1,4 @@
-#pragma once
+#pragma once
#include <library/cpp/actors/core/actor_bootstrapped.h>
#include <library/cpp/actors/core/mon.h>
#include <library/cpp/actors/core/interconnect.h>
@@ -12,327 +12,327 @@
#include <ydb/core/tx/tx_proxy/proxy.h>
#include <ydb/core/viewer/protos/viewer.pb.h>
#include <ydb/core/viewer/json/json.h>
-#include "viewer.h"
-#include "json_pipe_req.h"
-#include "wb_aggregate.h"
-#include "wb_merge.h"
-
-namespace NKikimr {
-namespace NViewer {
-
-using namespace NActors;
-
-class TJsonNetInfo : public TViewerPipeClient<TJsonNetInfo> {
- using TBase = TViewerPipeClient<TJsonNetInfo>;
- IViewer* Viewer;
- std::unordered_map<TString, NKikimrViewer::TTenant> TenantByPath;
- std::unordered_map<TPathId, NKikimrViewer::TTenant> TenantBySubDomainKey;
- std::unordered_map<TString, std::unique_ptr<TEvTxProxySchemeCache::TEvNavigateKeySetResult>> NavigateResult;
- std::unique_ptr<TEvHive::TEvResponseHiveDomainStats> HiveStats;
- NMon::TEvHttpInfo::TPtr Event;
- std::vector<TNodeId> NodeIds;
- std::unordered_map<TNodeId, std::unique_ptr<TEvWhiteboard::TEvSystemStateResponse>> NodeSysInfo;
- std::unordered_map<TNodeId, std::unique_ptr<TEvWhiteboard::TEvNodeStateResponse>> NodeNetInfo;
- std::unique_ptr<TEvInterconnect::TEvNodesInfo> NodesInfo;
- TJsonSettings JsonSettings;
+#include "viewer.h"
+#include "json_pipe_req.h"
+#include "wb_aggregate.h"
+#include "wb_merge.h"
+
+namespace NKikimr {
+namespace NViewer {
+
+using namespace NActors;
+
+class TJsonNetInfo : public TViewerPipeClient<TJsonNetInfo> {
+ using TBase = TViewerPipeClient<TJsonNetInfo>;
+ IViewer* Viewer;
+ std::unordered_map<TString, NKikimrViewer::TTenant> TenantByPath;
+ std::unordered_map<TPathId, NKikimrViewer::TTenant> TenantBySubDomainKey;
+ std::unordered_map<TString, std::unique_ptr<TEvTxProxySchemeCache::TEvNavigateKeySetResult>> NavigateResult;
+ std::unique_ptr<TEvHive::TEvResponseHiveDomainStats> HiveStats;
+ NMon::TEvHttpInfo::TPtr Event;
+ std::vector<TNodeId> NodeIds;
+ std::unordered_map<TNodeId, std::unique_ptr<TEvWhiteboard::TEvSystemStateResponse>> NodeSysInfo;
+ std::unordered_map<TNodeId, std::unique_ptr<TEvWhiteboard::TEvNodeStateResponse>> NodeNetInfo;
+ std::unique_ptr<TEvInterconnect::TEvNodesInfo> NodesInfo;
+ TJsonSettings JsonSettings;
ui32 Timeout = 0;
- TString User;
- TString Path;
-
-public:
- static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
- return NKikimrServices::TActivity::VIEWER_HANDLER;
- }
-
- TJsonNetInfo(IViewer* viewer, NMon::TEvHttpInfo::TPtr& ev)
- : Viewer(viewer)
- , Event(ev)
- {}
-
- void Bootstrap() {
- const auto& params(Event->Get()->Request.GetParams());
- JsonSettings.EnumAsNumbers = !FromStringWithDefault<bool>(params.Get("enums"), true);
- JsonSettings.UI64AsString = !FromStringWithDefault<bool>(params.Get("ui64"), false);
- InitConfig(params);
- Timeout = FromStringWithDefault<ui32>(params.Get("timeout"), 10000);
- Path = params.Get("path");
-
- SendRequest(GetNameserviceActorId(), new TEvInterconnect::TEvListNodes());
-
- TIntrusivePtr<TDomainsInfo> domains = AppData()->DomainsInfo;
- TIntrusivePtr<TDomainsInfo::TDomain> domain = domains->Domains.begin()->second;
- auto group = domains->GetDefaultStateStorageGroup(domain->DomainUid);
- ui64 consoleId = MakeConsoleID(group);
-
- if (consoleId != 0) {
- RequestConsoleListTenants();
- }
-
- ui64 hiveId = domains->GetHive(domain->DefaultHiveUid);
- if (hiveId != 0) {
- RequestHiveDomainStats(hiveId);
- }
-
- TString domainPath = "/" + domain->Name;
- if (Path.empty() || domainPath == Path) {
- NKikimrViewer::TTenant& tenant = TenantByPath[domainPath];
- tenant.SetName(domainPath);
- tenant.SetState(Ydb::Cms::GetDatabaseStatusResult::State::GetDatabaseStatusResult_State_RUNNING);
- RequestSchemeCacheNavigate(domainPath);
- }
-
- Become(&TThis::StateWork, TDuration::MilliSeconds(Timeout), new TEvents::TEvWakeup());
- }
-
- void PassAway() override {
+ TString User;
+ TString Path;
+
+public:
+ static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
+ return NKikimrServices::TActivity::VIEWER_HANDLER;
+ }
+
+ TJsonNetInfo(IViewer* viewer, NMon::TEvHttpInfo::TPtr& ev)
+ : Viewer(viewer)
+ , Event(ev)
+ {}
+
+ void Bootstrap() {
+ const auto& params(Event->Get()->Request.GetParams());
+ JsonSettings.EnumAsNumbers = !FromStringWithDefault<bool>(params.Get("enums"), true);
+ JsonSettings.UI64AsString = !FromStringWithDefault<bool>(params.Get("ui64"), false);
+ InitConfig(params);
+ Timeout = FromStringWithDefault<ui32>(params.Get("timeout"), 10000);
+ Path = params.Get("path");
+
+ SendRequest(GetNameserviceActorId(), new TEvInterconnect::TEvListNodes());
+
+ TIntrusivePtr<TDomainsInfo> domains = AppData()->DomainsInfo;
+ TIntrusivePtr<TDomainsInfo::TDomain> domain = domains->Domains.begin()->second;
+ auto group = domains->GetDefaultStateStorageGroup(domain->DomainUid);
+ ui64 consoleId = MakeConsoleID(group);
+
+ if (consoleId != 0) {
+ RequestConsoleListTenants();
+ }
+
+ ui64 hiveId = domains->GetHive(domain->DefaultHiveUid);
+ if (hiveId != 0) {
+ RequestHiveDomainStats(hiveId);
+ }
+
+ TString domainPath = "/" + domain->Name;
+ if (Path.empty() || domainPath == Path) {
+ NKikimrViewer::TTenant& tenant = TenantByPath[domainPath];
+ tenant.SetName(domainPath);
+ tenant.SetState(Ydb::Cms::GetDatabaseStatusResult::State::GetDatabaseStatusResult_State_RUNNING);
+ RequestSchemeCacheNavigate(domainPath);
+ }
+
+ Become(&TThis::StateWork, TDuration::MilliSeconds(Timeout), new TEvents::TEvWakeup());
+ }
+
+ void PassAway() override {
for (const TNodeId nodeId : NodeIds) {
- Send(TActivationContext::InterconnectProxy(nodeId), new TEvents::TEvUnsubscribe());
+ Send(TActivationContext::InterconnectProxy(nodeId), new TEvents::TEvUnsubscribe());
+ }
+ TBase::PassAway();
+ }
+
+ STATEFN(StateWork) {
+ switch (ev->GetTypeRewrite()) {
+ hFunc(TEvInterconnect::TEvNodesInfo, Handle);
+ hFunc(NConsole::TEvConsole::TEvListTenantsResponse, Handle);
+ hFunc(TEvHive::TEvResponseHiveDomainStats, Handle);
+ hFunc(TEvTxProxySchemeCache::TEvNavigateKeySetResult, Handle);
+ hFunc(TEvWhiteboard::TEvSystemStateResponse, Handle);
+ hFunc(TEvWhiteboard::TEvNodeStateResponse, Handle);
+ hFunc(TEvents::TEvUndelivered, Undelivered);
+ hFunc(TEvInterconnect::TEvNodeDisconnected, Disconnected);
+ hFunc(TEvTabletPipe::TEvClientConnected, TBase::Handle);
+ cFunc(TEvents::TSystem::Wakeup, HandleTimeout);
}
- TBase::PassAway();
- }
-
- STATEFN(StateWork) {
- switch (ev->GetTypeRewrite()) {
- hFunc(TEvInterconnect::TEvNodesInfo, Handle);
- hFunc(NConsole::TEvConsole::TEvListTenantsResponse, Handle);
- hFunc(TEvHive::TEvResponseHiveDomainStats, Handle);
- hFunc(TEvTxProxySchemeCache::TEvNavigateKeySetResult, Handle);
- hFunc(TEvWhiteboard::TEvSystemStateResponse, Handle);
- hFunc(TEvWhiteboard::TEvNodeStateResponse, Handle);
- hFunc(TEvents::TEvUndelivered, Undelivered);
- hFunc(TEvInterconnect::TEvNodeDisconnected, Disconnected);
- hFunc(TEvTabletPipe::TEvClientConnected, TBase::Handle);
- cFunc(TEvents::TSystem::Wakeup, HandleTimeout);
- }
- }
-
- void Handle(TEvInterconnect::TEvNodesInfo::TPtr& ev) {
- NodesInfo.reset(ev->Release().Release());
- RequestDone();
- }
-
- void Handle(NConsole::TEvConsole::TEvListTenantsResponse::TPtr& ev) {
- Ydb::Cms::ListDatabasesResult listTenantsResult;
- ev->Get()->Record.GetResponse().operation().result().UnpackTo(&listTenantsResult);
- for (const TString& path : listTenantsResult.paths()) {
- if (!Path.empty() && path != Path) {
- continue;
- }
- TenantByPath[path];
- RequestSchemeCacheNavigate(path);
- }
- RequestDone();
- }
-
- void Handle(TEvHive::TEvResponseHiveDomainStats::TPtr& ev) {
- HiveStats.reset(ev->Release().Release());
- for (const NKikimrHive::THiveDomainStats& hiveStat : HiveStats->Record.GetDomainStats()) {
- TPathId subDomainKey(hiveStat.GetShardId(), hiveStat.GetPathId());
- NKikimrViewer::TTenant& tenant = TenantBySubDomainKey[subDomainKey];
- tenant.SetId(TStringBuilder() << hiveStat.GetShardId() << '-' << hiveStat.GetPathId());
- tenant.MutableNodeIds()->MergeFrom(hiveStat.GetNodeIds());
- for (TNodeId nodeId : hiveStat.GetNodeIds()) {
- NodeIds.emplace_back(nodeId);
- }
- }
- for (TNodeId nodeId : NodeIds) {
+ }
+
+ void Handle(TEvInterconnect::TEvNodesInfo::TPtr& ev) {
+ NodesInfo.reset(ev->Release().Release());
+ RequestDone();
+ }
+
+ void Handle(NConsole::TEvConsole::TEvListTenantsResponse::TPtr& ev) {
+ Ydb::Cms::ListDatabasesResult listTenantsResult;
+ ev->Get()->Record.GetResponse().operation().result().UnpackTo(&listTenantsResult);
+ for (const TString& path : listTenantsResult.paths()) {
+ if (!Path.empty() && path != Path) {
+ continue;
+ }
+ TenantByPath[path];
+ RequestSchemeCacheNavigate(path);
+ }
+ RequestDone();
+ }
+
+ void Handle(TEvHive::TEvResponseHiveDomainStats::TPtr& ev) {
+ HiveStats.reset(ev->Release().Release());
+ for (const NKikimrHive::THiveDomainStats& hiveStat : HiveStats->Record.GetDomainStats()) {
+ TPathId subDomainKey(hiveStat.GetShardId(), hiveStat.GetPathId());
+ NKikimrViewer::TTenant& tenant = TenantBySubDomainKey[subDomainKey];
+ tenant.SetId(TStringBuilder() << hiveStat.GetShardId() << '-' << hiveStat.GetPathId());
+ tenant.MutableNodeIds()->MergeFrom(hiveStat.GetNodeIds());
+ for (TNodeId nodeId : hiveStat.GetNodeIds()) {
+ NodeIds.emplace_back(nodeId);
+ }
+ }
+ for (TNodeId nodeId : NodeIds) {
TActorId whiteboardServiceId = MakeNodeWhiteboardServiceId(nodeId);
- SendRequest(
- whiteboardServiceId,
- new NNodeWhiteboard::TEvWhiteboard::TEvSystemStateRequest(),
- IEventHandle::FlagTrackDelivery | IEventHandle::FlagSubscribeOnSession,
- nodeId);
- SendRequest(
- whiteboardServiceId,
- new NNodeWhiteboard::TEvWhiteboard::TEvNodeStateRequest(),
- IEventHandle::FlagTrackDelivery | IEventHandle::FlagSubscribeOnSession,
- nodeId);
-
- }
- RequestDone();
- }
-
- void Handle(TEvTxProxySchemeCache::TEvNavigateKeySetResult::TPtr& ev) {
- if (ev->Get()->Request->ResultSet.size() == 1 && ev->Get()->Request->ResultSet.begin()->Status == NSchemeCache::TSchemeCacheNavigate::EStatus::Ok) {
- TString path = CanonizePath(ev->Get()->Request->ResultSet.begin()->Path);
- NavigateResult[path].reset(ev->Release().Release());
- }
- RequestDone();
- }
-
- void Handle(NNodeWhiteboard::TEvWhiteboard::TEvSystemStateResponse::TPtr& ev) {
- ui32 nodeId = ev.Get()->Cookie;
- NodeSysInfo[nodeId].reset(ev->Release().Release());
- RequestDone();
- }
-
- void Handle(NNodeWhiteboard::TEvWhiteboard::TEvNodeStateResponse::TPtr& ev) {
- ui32 nodeId = ev.Get()->Cookie;
- NodeNetInfo[nodeId].reset(ev->Release().Release());
- RequestDone();
- }
-
- void Undelivered(TEvents::TEvUndelivered::TPtr &ev) {
- ui32 nodeId = ev.Get()->Cookie;
- if (ev->Get()->SourceType == NNodeWhiteboard::TEvWhiteboard::EvSystemStateRequest) {
- if (NodeSysInfo.emplace(nodeId, nullptr).second) {
- RequestDone();
- }
- }
- if (ev->Get()->SourceType == NNodeWhiteboard::TEvWhiteboard::EvNodeStateRequest) {
- if (NodeNetInfo.emplace(nodeId, nullptr).second) {
- RequestDone();
- }
- }
- }
-
- void Disconnected(TEvInterconnect::TEvNodeDisconnected::TPtr &ev) {
- ui32 nodeId = ev->Get()->NodeId;
- if (NodeSysInfo.emplace(nodeId, nullptr).second) {
- RequestDone();
- }
- if (NodeNetInfo.emplace(nodeId, nullptr).second) {
- RequestDone();
- }
- }
-
- void ReplyAndPassAway() {
- THashMap<TNodeId, const TEvInterconnect::TNodeInfo*> nodeInfoIndex;
- if (NodesInfo) {
- for (const TEvInterconnect::TNodeInfo& nodeInfo : NodesInfo->Nodes) {
- nodeInfoIndex[nodeInfo.NodeId] = &nodeInfo;
- }
- }
- TIntrusivePtr<TDynamicNameserviceConfig> dynamicNameserviceConfig = AppData()->DynamicNameserviceConfig;
- NKikimrViewer::TNetInfo result;
- for (const std::pair<const TString, NKikimrViewer::TTenant>& prTenant : TenantByPath) {
- const TString& path = prTenant.first;
- //const NKikimrViewer::TTenant& tenantByPath(prTenant.second);
- NKikimrViewer::TNetTenantInfo& netTenantInfo = *result.AddTenants();
- netTenantInfo.SetName(path);
- auto itNavigate = NavigateResult.find(path);
- if (itNavigate != NavigateResult.end()) {
- auto domainInfo = itNavigate->second->Request->ResultSet.begin()->DomainInfo;
- TPathId subDomainKey(domainInfo->DomainKey);
- const NKikimrViewer::TTenant& tenantBySubDomainKey(TenantBySubDomainKey[subDomainKey]);
- for (TNodeId nodeId : tenantBySubDomainKey.GetNodeIds()) {
- NKikimrViewer::TNetNodeInfo& netNodeInfo = *netTenantInfo.AddNodes();
- netNodeInfo.SetNodeId(nodeId);
- auto itSysInfo = NodeSysInfo.find(nodeId);
- if (itSysInfo != NodeSysInfo.end()) {
- if (itSysInfo->second != nullptr && itSysInfo->second->Record.SystemStateInfoSize() == 1) {
- const NKikimrWhiteboard::TSystemStateInfo& sysInfo = itSysInfo->second->Record.GetSystemStateInfo(0);
- if (sysInfo.HasDataCenter()) {
- netNodeInfo.SetDataCenter(sysInfo.GetDataCenter());
- }
- if (sysInfo.HasRack()) {
- netNodeInfo.SetRack(sysInfo.GetRack());
- }
- }
- }
- if (dynamicNameserviceConfig) {
- netNodeInfo.SetNodeType(nodeId <= dynamicNameserviceConfig->MaxStaticNodeId ? NKikimrViewer::ENodeType::Static : NKikimrViewer::ENodeType::Dynamic);
- }
- auto itNodeInfo = nodeInfoIndex.find(nodeId);
- if (itNodeInfo != nodeInfoIndex.end()) {
- netNodeInfo.SetHost(itNodeInfo->second->Host);
- netNodeInfo.SetPort(itNodeInfo->second->Port);
- }
- auto itNetInfo = NodeNetInfo.find(nodeId);
- if (itNetInfo != NodeNetInfo.end()) {
- if (itNetInfo->second != nullptr) {
- for (const NKikimrWhiteboard::TNodeStateInfo& netInfo : itNetInfo->second->Record.GetNodeStateInfo()) {
- TString peerName(netInfo.GetPeerName());
- TNodeId nodeId = FromStringWithDefault<TNodeId>(TStringBuf(peerName).Before(':'));
- if (nodeInfoIndex.find(nodeId) == nodeInfoIndex.end()) {
- continue;
- }
- NKikimrViewer::TNetNodePeerInfo& netNodePeerInfo = *netNodeInfo.AddPeers();
- netNodePeerInfo.SetNodeId(nodeId);
- netNodePeerInfo.SetPeerName(peerName);
- netNodePeerInfo.SetConnected(netInfo.GetConnected());
- netNodePeerInfo.SetConnectStatus(GetViewerFlag(netInfo.GetConnectStatus()));
- netNodePeerInfo.SetChangeTime(netInfo.GetChangeTime());
- if (dynamicNameserviceConfig) {
- netNodePeerInfo.SetNodeType(nodeId <= dynamicNameserviceConfig->MaxStaticNodeId ? NKikimrViewer::ENodeType::Static : NKikimrViewer::ENodeType::Dynamic);
- }
- auto itSysInfo = NodeSysInfo.find(nodeId);
- if (itSysInfo != NodeSysInfo.end()) {
- if (itSysInfo->second != nullptr && itSysInfo->second->Record.SystemStateInfoSize() == 1) {
- const NKikimrWhiteboard::TSystemStateInfo& sysInfo = itSysInfo->second->Record.GetSystemStateInfo(0);
- if (sysInfo.HasDataCenter()) {
- netNodePeerInfo.SetDataCenter(sysInfo.GetDataCenter());
- }
- if (sysInfo.HasRack()) {
- netNodePeerInfo.SetRack(sysInfo.GetRack());
- }
- }
- }
- auto itNodeInfo = nodeInfoIndex.find(nodeId);
- if (itNodeInfo != nodeInfoIndex.end()) {
- netNodePeerInfo.SetHost(itNodeInfo->second->Host);
- netNodePeerInfo.SetPort(itNodeInfo->second->Port);
- }
- }
- }
- }
-
- // TODO(xenoxeno)
- netNodeInfo.SetOverall(NKikimrViewer::EFlag::Green);
- }
- }
-
- // TODO(xenoxeno)
- netTenantInfo.SetOverall(NKikimrViewer::EFlag::Green);
- }
-
- // TODO(xenoxeno)
- result.SetOverall(NKikimrViewer::EFlag::Green);
- TStringStream json;
- TProtoToJson::ProtoToJson(json, result, JsonSettings);
- Send(Event->Sender, new NMon::TEvHttpInfoRes(Viewer->GetHTTPOKJSON() + json.Str(), 0, NMon::IEvHttpInfoRes::EContentType::Custom));
- PassAway();
- }
-
- void HandleTimeout() {
- Send(Event->Sender, new NMon::TEvHttpInfoRes(Viewer->GetHTTPGATEWAYTIMEOUT(), 0, NMon::IEvHttpInfoRes::EContentType::Custom));
- PassAway();
- }
-};
-
-template <>
-struct TJsonRequestSchema<TJsonNetInfo> {
- static TString GetSchema() {
- TStringStream stream;
- TProtoToJson::ProtoToJsonSchema<NKikimrViewer::TNetInfo>(stream);
- return stream.Str();
- }
-};
-
-template <>
-struct TJsonRequestParameters<TJsonNetInfo> {
- static TString GetParameters() {
- return R"___([{"name":"path","in":"query","description":"schema path","required":false,"type":"string"},
- {"name":"hive_id","in":"query","description":"hive identifier (tablet id)","required":false,"type":"string"},
- {"name":"enums","in":"query","description":"convert enums to strings","required":false,"type":"boolean"},
- {"name":"ui64","in":"query","description":"return ui64 as number","required":false,"type":"boolean"},
- {"name":"timeout","in":"query","description":"timeout in ms","required":false,"type":"integer"}])___";
- }
-};
-
-template <>
-struct TJsonRequestSummary<TJsonNetInfo> {
- static TString GetSummary() {
- return "\"Network information\"";
- }
-};
-
-template <>
-struct TJsonRequestDescription<TJsonNetInfo> {
- static TString GetDescription() {
- return "\"Returns network information\"";
- }
-};
-
-}
-}
+ SendRequest(
+ whiteboardServiceId,
+ new NNodeWhiteboard::TEvWhiteboard::TEvSystemStateRequest(),
+ IEventHandle::FlagTrackDelivery | IEventHandle::FlagSubscribeOnSession,
+ nodeId);
+ SendRequest(
+ whiteboardServiceId,
+ new NNodeWhiteboard::TEvWhiteboard::TEvNodeStateRequest(),
+ IEventHandle::FlagTrackDelivery | IEventHandle::FlagSubscribeOnSession,
+ nodeId);
+
+ }
+ RequestDone();
+ }
+
+ void Handle(TEvTxProxySchemeCache::TEvNavigateKeySetResult::TPtr& ev) {
+ if (ev->Get()->Request->ResultSet.size() == 1 && ev->Get()->Request->ResultSet.begin()->Status == NSchemeCache::TSchemeCacheNavigate::EStatus::Ok) {
+ TString path = CanonizePath(ev->Get()->Request->ResultSet.begin()->Path);
+ NavigateResult[path].reset(ev->Release().Release());
+ }
+ RequestDone();
+ }
+
+ void Handle(NNodeWhiteboard::TEvWhiteboard::TEvSystemStateResponse::TPtr& ev) {
+ ui32 nodeId = ev.Get()->Cookie;
+ NodeSysInfo[nodeId].reset(ev->Release().Release());
+ RequestDone();
+ }
+
+ void Handle(NNodeWhiteboard::TEvWhiteboard::TEvNodeStateResponse::TPtr& ev) {
+ ui32 nodeId = ev.Get()->Cookie;
+ NodeNetInfo[nodeId].reset(ev->Release().Release());
+ RequestDone();
+ }
+
+ void Undelivered(TEvents::TEvUndelivered::TPtr &ev) {
+ ui32 nodeId = ev.Get()->Cookie;
+ if (ev->Get()->SourceType == NNodeWhiteboard::TEvWhiteboard::EvSystemStateRequest) {
+ if (NodeSysInfo.emplace(nodeId, nullptr).second) {
+ RequestDone();
+ }
+ }
+ if (ev->Get()->SourceType == NNodeWhiteboard::TEvWhiteboard::EvNodeStateRequest) {
+ if (NodeNetInfo.emplace(nodeId, nullptr).second) {
+ RequestDone();
+ }
+ }
+ }
+
+ void Disconnected(TEvInterconnect::TEvNodeDisconnected::TPtr &ev) {
+ ui32 nodeId = ev->Get()->NodeId;
+ if (NodeSysInfo.emplace(nodeId, nullptr).second) {
+ RequestDone();
+ }
+ if (NodeNetInfo.emplace(nodeId, nullptr).second) {
+ RequestDone();
+ }
+ }
+
+ void ReplyAndPassAway() {
+ THashMap<TNodeId, const TEvInterconnect::TNodeInfo*> nodeInfoIndex;
+ if (NodesInfo) {
+ for (const TEvInterconnect::TNodeInfo& nodeInfo : NodesInfo->Nodes) {
+ nodeInfoIndex[nodeInfo.NodeId] = &nodeInfo;
+ }
+ }
+ TIntrusivePtr<TDynamicNameserviceConfig> dynamicNameserviceConfig = AppData()->DynamicNameserviceConfig;
+ NKikimrViewer::TNetInfo result;
+ for (const std::pair<const TString, NKikimrViewer::TTenant>& prTenant : TenantByPath) {
+ const TString& path = prTenant.first;
+ //const NKikimrViewer::TTenant& tenantByPath(prTenant.second);
+ NKikimrViewer::TNetTenantInfo& netTenantInfo = *result.AddTenants();
+ netTenantInfo.SetName(path);
+ auto itNavigate = NavigateResult.find(path);
+ if (itNavigate != NavigateResult.end()) {
+ auto domainInfo = itNavigate->second->Request->ResultSet.begin()->DomainInfo;
+ TPathId subDomainKey(domainInfo->DomainKey);
+ const NKikimrViewer::TTenant& tenantBySubDomainKey(TenantBySubDomainKey[subDomainKey]);
+ for (TNodeId nodeId : tenantBySubDomainKey.GetNodeIds()) {
+ NKikimrViewer::TNetNodeInfo& netNodeInfo = *netTenantInfo.AddNodes();
+ netNodeInfo.SetNodeId(nodeId);
+ auto itSysInfo = NodeSysInfo.find(nodeId);
+ if (itSysInfo != NodeSysInfo.end()) {
+ if (itSysInfo->second != nullptr && itSysInfo->second->Record.SystemStateInfoSize() == 1) {
+ const NKikimrWhiteboard::TSystemStateInfo& sysInfo = itSysInfo->second->Record.GetSystemStateInfo(0);
+ if (sysInfo.HasDataCenter()) {
+ netNodeInfo.SetDataCenter(sysInfo.GetDataCenter());
+ }
+ if (sysInfo.HasRack()) {
+ netNodeInfo.SetRack(sysInfo.GetRack());
+ }
+ }
+ }
+ if (dynamicNameserviceConfig) {
+ netNodeInfo.SetNodeType(nodeId <= dynamicNameserviceConfig->MaxStaticNodeId ? NKikimrViewer::ENodeType::Static : NKikimrViewer::ENodeType::Dynamic);
+ }
+ auto itNodeInfo = nodeInfoIndex.find(nodeId);
+ if (itNodeInfo != nodeInfoIndex.end()) {
+ netNodeInfo.SetHost(itNodeInfo->second->Host);
+ netNodeInfo.SetPort(itNodeInfo->second->Port);
+ }
+ auto itNetInfo = NodeNetInfo.find(nodeId);
+ if (itNetInfo != NodeNetInfo.end()) {
+ if (itNetInfo->second != nullptr) {
+ for (const NKikimrWhiteboard::TNodeStateInfo& netInfo : itNetInfo->second->Record.GetNodeStateInfo()) {
+ TString peerName(netInfo.GetPeerName());
+ TNodeId nodeId = FromStringWithDefault<TNodeId>(TStringBuf(peerName).Before(':'));
+ if (nodeInfoIndex.find(nodeId) == nodeInfoIndex.end()) {
+ continue;
+ }
+ NKikimrViewer::TNetNodePeerInfo& netNodePeerInfo = *netNodeInfo.AddPeers();
+ netNodePeerInfo.SetNodeId(nodeId);
+ netNodePeerInfo.SetPeerName(peerName);
+ netNodePeerInfo.SetConnected(netInfo.GetConnected());
+ netNodePeerInfo.SetConnectStatus(GetViewerFlag(netInfo.GetConnectStatus()));
+ netNodePeerInfo.SetChangeTime(netInfo.GetChangeTime());
+ if (dynamicNameserviceConfig) {
+ netNodePeerInfo.SetNodeType(nodeId <= dynamicNameserviceConfig->MaxStaticNodeId ? NKikimrViewer::ENodeType::Static : NKikimrViewer::ENodeType::Dynamic);
+ }
+ auto itSysInfo = NodeSysInfo.find(nodeId);
+ if (itSysInfo != NodeSysInfo.end()) {
+ if (itSysInfo->second != nullptr && itSysInfo->second->Record.SystemStateInfoSize() == 1) {
+ const NKikimrWhiteboard::TSystemStateInfo& sysInfo = itSysInfo->second->Record.GetSystemStateInfo(0);
+ if (sysInfo.HasDataCenter()) {
+ netNodePeerInfo.SetDataCenter(sysInfo.GetDataCenter());
+ }
+ if (sysInfo.HasRack()) {
+ netNodePeerInfo.SetRack(sysInfo.GetRack());
+ }
+ }
+ }
+ auto itNodeInfo = nodeInfoIndex.find(nodeId);
+ if (itNodeInfo != nodeInfoIndex.end()) {
+ netNodePeerInfo.SetHost(itNodeInfo->second->Host);
+ netNodePeerInfo.SetPort(itNodeInfo->second->Port);
+ }
+ }
+ }
+ }
+
+ // TODO(xenoxeno)
+ netNodeInfo.SetOverall(NKikimrViewer::EFlag::Green);
+ }
+ }
+
+ // TODO(xenoxeno)
+ netTenantInfo.SetOverall(NKikimrViewer::EFlag::Green);
+ }
+
+ // TODO(xenoxeno)
+ result.SetOverall(NKikimrViewer::EFlag::Green);
+ TStringStream json;
+ TProtoToJson::ProtoToJson(json, result, JsonSettings);
+ Send(Event->Sender, new NMon::TEvHttpInfoRes(Viewer->GetHTTPOKJSON() + json.Str(), 0, NMon::IEvHttpInfoRes::EContentType::Custom));
+ PassAway();
+ }
+
+ void HandleTimeout() {
+ Send(Event->Sender, new NMon::TEvHttpInfoRes(Viewer->GetHTTPGATEWAYTIMEOUT(), 0, NMon::IEvHttpInfoRes::EContentType::Custom));
+ PassAway();
+ }
+};
+
+template <>
+struct TJsonRequestSchema<TJsonNetInfo> {
+ static TString GetSchema() {
+ TStringStream stream;
+ TProtoToJson::ProtoToJsonSchema<NKikimrViewer::TNetInfo>(stream);
+ return stream.Str();
+ }
+};
+
+template <>
+struct TJsonRequestParameters<TJsonNetInfo> {
+ static TString GetParameters() {
+ return R"___([{"name":"path","in":"query","description":"schema path","required":false,"type":"string"},
+ {"name":"hive_id","in":"query","description":"hive identifier (tablet id)","required":false,"type":"string"},
+ {"name":"enums","in":"query","description":"convert enums to strings","required":false,"type":"boolean"},
+ {"name":"ui64","in":"query","description":"return ui64 as number","required":false,"type":"boolean"},
+ {"name":"timeout","in":"query","description":"timeout in ms","required":false,"type":"integer"}])___";
+ }
+};
+
+template <>
+struct TJsonRequestSummary<TJsonNetInfo> {
+ static TString GetSummary() {
+ return "\"Network information\"";
+ }
+};
+
+template <>
+struct TJsonRequestDescription<TJsonNetInfo> {
+ static TString GetDescription() {
+ return "\"Returns network information\"";
+ }
+};
+
+}
+}
diff --git a/ydb/core/viewer/json_nodeinfo.h b/ydb/core/viewer/json_nodeinfo.h
index a2832a5c9b7..60245326fa6 100644
--- a/ydb/core/viewer/json_nodeinfo.h
+++ b/ydb/core/viewer/json_nodeinfo.h
@@ -1,62 +1,62 @@
-#pragma once
+#pragma once
#include <library/cpp/actors/core/actor_bootstrapped.h>
#include <library/cpp/actors/core/interconnect.h>
#include <library/cpp/actors/core/mon.h>
#include <ydb/core/protos/services.pb.h>
#include <ydb/core/node_whiteboard/node_whiteboard.h>
-#include "wb_merge.h"
-#include "json_wb_req.h"
-
-namespace NKikimr {
-namespace NViewer {
-
-template <>
+#include "wb_merge.h"
+#include "json_wb_req.h"
+
+namespace NKikimr {
+namespace NViewer {
+
+template <>
struct TWhiteboardInfo<TEvWhiteboard::TEvNodeStateResponse> {
using TResponseType = TEvWhiteboard::TEvNodeStateResponse;
- using TElementType = NKikimrWhiteboard::TNodeStateInfo;
+ using TElementType = NKikimrWhiteboard::TNodeStateInfo;
using TElementKeyType = TString;
-
- static constexpr bool StaticNodesOnly = false;
-
- static ::google::protobuf::RepeatedPtrField<TElementType>* GetElementsField(TResponseType* response) {
- return response->Record.MutableNodeStateInfo();
- }
-
+
+ static constexpr bool StaticNodesOnly = false;
+
+ static ::google::protobuf::RepeatedPtrField<TElementType>* GetElementsField(TResponseType* response) {
+ return response->Record.MutableNodeStateInfo();
+ }
+
static const TString& GetElementKey(const TElementType& type) {
- return type.GetPeerName();
- }
-
- static TString GetDefaultMergeField() {
- return "PeerName";
- }
-
- static THolder<TResponseType> MergeResponses(TMap<ui32, THolder<TResponseType>>& responses, const TString& fields = GetDefaultMergeField()) {
- return TWhiteboardMerger<TResponseType>::MergeResponses(responses, fields);
- }
-
- static void InitMerger() {
- const auto* field = NKikimrWhiteboard::TNodeStateInfo::descriptor()->FindFieldByName("ConnectStatus");
- TWhiteboardMergerBase::FieldMerger[field] = &TWhiteboardMergerBase::ProtoMaximizeEnumField;
- field = NKikimrWhiteboard::TNodeStateInfo::descriptor()->FindFieldByName("Connected");
- TWhiteboardMergerBase::FieldMerger[field] = &TWhiteboardMergerBase::ProtoMaximizeBoolField;
- }
-};
-
+ return type.GetPeerName();
+ }
+
+ static TString GetDefaultMergeField() {
+ return "PeerName";
+ }
+
+ static THolder<TResponseType> MergeResponses(TMap<ui32, THolder<TResponseType>>& responses, const TString& fields = GetDefaultMergeField()) {
+ return TWhiteboardMerger<TResponseType>::MergeResponses(responses, fields);
+ }
+
+ static void InitMerger() {
+ const auto* field = NKikimrWhiteboard::TNodeStateInfo::descriptor()->FindFieldByName("ConnectStatus");
+ TWhiteboardMergerBase::FieldMerger[field] = &TWhiteboardMergerBase::ProtoMaximizeEnumField;
+ field = NKikimrWhiteboard::TNodeStateInfo::descriptor()->FindFieldByName("Connected");
+ TWhiteboardMergerBase::FieldMerger[field] = &TWhiteboardMergerBase::ProtoMaximizeBoolField;
+ }
+};
+
using TJsonNodeInfo = TJsonWhiteboardRequest<TEvWhiteboard::TEvNodeStateRequest, TEvWhiteboard::TEvNodeStateResponse>;
-
-template <>
-struct TJsonRequestSummary<TJsonNodeInfo> {
+
+template <>
+struct TJsonRequestSummary<TJsonNodeInfo> {
static TString GetSummary() {
- return "\"Interconnect information\"";
- }
-};
-
-template <>
-struct TJsonRequestDescription<TJsonNodeInfo> {
+ return "\"Interconnect information\"";
+ }
+};
+
+template <>
+struct TJsonRequestDescription<TJsonNodeInfo> {
static TString GetDescription() {
- return "\"Returns information about node connections\"";
- }
-};
-
-}
-}
+ return "\"Returns information about node connections\"";
+ }
+};
+
+}
+}
diff --git a/ydb/core/viewer/json_nodelist.h b/ydb/core/viewer/json_nodelist.h
index 252b5c8128e..504ed152d8d 100644
--- a/ydb/core/viewer/json_nodelist.h
+++ b/ydb/core/viewer/json_nodelist.h
@@ -1,69 +1,69 @@
-#pragma once
+#pragma once
#include <library/cpp/actors/core/actor_bootstrapped.h>
#include <library/cpp/actors/core/interconnect.h>
#include <library/cpp/actors/core/mon.h>
#include <library/cpp/actors/interconnect/interconnect.h>
#include <library/cpp/json/json_writer.h>
#include <ydb/core/protos/services.pb.h>
-#include "viewer.h"
-
-namespace NKikimr {
-namespace NViewer {
-
-using namespace NActors;
-
-class TJsonNodeList : public TActorBootstrapped<TJsonNodeList> {
- IViewer* Viewer;
- NMon::TEvHttpInfo::TPtr Event;
- TAutoPtr<TEvInterconnect::TEvNodesInfo> NodesInfo;
-
-public:
+#include "viewer.h"
+
+namespace NKikimr {
+namespace NViewer {
+
+using namespace NActors;
+
+class TJsonNodeList : public TActorBootstrapped<TJsonNodeList> {
+ IViewer* Viewer;
+ NMon::TEvHttpInfo::TPtr Event;
+ TAutoPtr<TEvInterconnect::TEvNodesInfo> NodesInfo;
+
+public:
static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
return NKikimrServices::TActivity::VIEWER_HANDLER;
- }
-
- TJsonNodeList(IViewer* viewer, NMon::TEvHttpInfo::TPtr &ev)
- : Viewer(viewer)
- , Event(ev)
- {}
-
- void Bootstrap(const TActorContext& ctx) {
+ }
+
+ TJsonNodeList(IViewer* viewer, NMon::TEvHttpInfo::TPtr &ev)
+ : Viewer(viewer)
+ , Event(ev)
+ {}
+
+ void Bootstrap(const TActorContext& ctx) {
const TActorId nameserviceId = GetNameserviceActorId();
- ctx.Send(nameserviceId, new TEvInterconnect::TEvListNodes());
- ctx.Schedule(TDuration::Seconds(10), new TEvents::TEvWakeup());
- Become(&TThis::StateRequestedBrowse);
- }
-
- STFUNC(StateRequestedBrowse) {
- switch (ev->GetTypeRewrite()) {
- HFunc(TEvInterconnect::TEvNodesInfo, Handle);
- CFunc(TEvents::TSystem::Wakeup, Timeout);
- }
- }
-
- void Handle(TEvInterconnect::TEvNodesInfo::TPtr &ev, const TActorContext &ctx) {
- NodesInfo = ev->Release();
- ReplyAndDie(ctx);
- }
-
- void ReplyAndDie(const TActorContext &ctx) {
- NJson::TJsonValue json;
- json.SetType(NJson::EJsonValueType::JSON_ARRAY);
- if (NodesInfo != nullptr) {
- for (auto it = NodesInfo->Nodes.begin(); it != NodesInfo->Nodes.end(); ++it) {
- const TEvInterconnect::TNodeInfo& nodeInfo = *it;
- NJson::TJsonValue& jsonNodeInfo = json.AppendValue(NJson::TJsonValue());
- jsonNodeInfo["Id"] = nodeInfo.NodeId;
- if (!nodeInfo.Host.empty()) {
- jsonNodeInfo["Host"] = nodeInfo.Host;
- }
- if (!nodeInfo.ResolveHost.empty()) {
- jsonNodeInfo["ResolveHost"] = nodeInfo.ResolveHost;
- }
- jsonNodeInfo["Address"] = nodeInfo.Address;
- jsonNodeInfo["Port"] = nodeInfo.Port;
+ ctx.Send(nameserviceId, new TEvInterconnect::TEvListNodes());
+ ctx.Schedule(TDuration::Seconds(10), new TEvents::TEvWakeup());
+ Become(&TThis::StateRequestedBrowse);
+ }
+
+ STFUNC(StateRequestedBrowse) {
+ switch (ev->GetTypeRewrite()) {
+ HFunc(TEvInterconnect::TEvNodesInfo, Handle);
+ CFunc(TEvents::TSystem::Wakeup, Timeout);
+ }
+ }
+
+ void Handle(TEvInterconnect::TEvNodesInfo::TPtr &ev, const TActorContext &ctx) {
+ NodesInfo = ev->Release();
+ ReplyAndDie(ctx);
+ }
+
+ void ReplyAndDie(const TActorContext &ctx) {
+ NJson::TJsonValue json;
+ json.SetType(NJson::EJsonValueType::JSON_ARRAY);
+ if (NodesInfo != nullptr) {
+ for (auto it = NodesInfo->Nodes.begin(); it != NodesInfo->Nodes.end(); ++it) {
+ const TEvInterconnect::TNodeInfo& nodeInfo = *it;
+ NJson::TJsonValue& jsonNodeInfo = json.AppendValue(NJson::TJsonValue());
+ jsonNodeInfo["Id"] = nodeInfo.NodeId;
+ if (!nodeInfo.Host.empty()) {
+ jsonNodeInfo["Host"] = nodeInfo.Host;
+ }
+ if (!nodeInfo.ResolveHost.empty()) {
+ jsonNodeInfo["ResolveHost"] = nodeInfo.ResolveHost;
+ }
+ jsonNodeInfo["Address"] = nodeInfo.Address;
+ jsonNodeInfo["Port"] = nodeInfo.Port;
if (nodeInfo.Location != TNodeLocation()) {
- NJson::TJsonValue& jsonPhysicalLocation = jsonNodeInfo["PhysicalLocation"];
+ NJson::TJsonValue& jsonPhysicalLocation = jsonNodeInfo["PhysicalLocation"];
const auto& x = nodeInfo.Location.GetLegacyValue();
jsonPhysicalLocation["DataCenter"] = x.DataCenter;
jsonPhysicalLocation["Room"] = x.Room;
@@ -71,38 +71,38 @@ public:
jsonPhysicalLocation["Body"] = x.Body;
jsonPhysicalLocation["DataCenterId"] = nodeInfo.Location.GetDataCenterId();
jsonPhysicalLocation["Location"] = nodeInfo.Location.ToString();
- }
- }
- }
- ctx.Send(Event->Sender, new NMon::TEvHttpInfoRes(Viewer->GetHTTPOKJSON() + NJson::WriteJson(json, false), 0, NMon::IEvHttpInfoRes::EContentType::Custom));
- Die(ctx);
- }
-
- void Timeout(const TActorContext &ctx) {
- ReplyAndDie(ctx);
- }
-};
-
-template <>
-struct TJsonRequestSchema<TJsonNodeList> {
+ }
+ }
+ }
+ ctx.Send(Event->Sender, new NMon::TEvHttpInfoRes(Viewer->GetHTTPOKJSON() + NJson::WriteJson(json, false), 0, NMon::IEvHttpInfoRes::EContentType::Custom));
+ Die(ctx);
+ }
+
+ void Timeout(const TActorContext &ctx) {
+ ReplyAndDie(ctx);
+ }
+};
+
+template <>
+struct TJsonRequestSchema<TJsonNodeList> {
static TString GetSchema() {
- return R"___({"type":"array","title":"TEvNodeListResponse","items":{"type":"object","title":"TNodeInfo","properties":{"Id":{"type":"integer"},"Host":{"type":"string"},"Address":{"type":"string"},"Port":{"type":"integer"}},"required":["Id","Address","Port"]}})___";
- }
-};
-
-template <>
-struct TJsonRequestSummary<TJsonNodeList> {
+ return R"___({"type":"array","title":"TEvNodeListResponse","items":{"type":"object","title":"TNodeInfo","properties":{"Id":{"type":"integer"},"Host":{"type":"string"},"Address":{"type":"string"},"Port":{"type":"integer"}},"required":["Id","Address","Port"]}})___";
+ }
+};
+
+template <>
+struct TJsonRequestSummary<TJsonNodeList> {
static TString GetSummary() {
- return "\"Nodes list\"";
- }
-};
-
-template <>
-struct TJsonRequestDescription<TJsonNodeList> {
+ return "\"Nodes list\"";
+ }
+};
+
+template <>
+struct TJsonRequestDescription<TJsonNodeList> {
static TString GetDescription() {
- return "\"Returns list of nodes\"";
- }
-};
-
-}
-}
+ return "\"Returns list of nodes\"";
+ }
+};
+
+}
+}
diff --git a/ydb/core/viewer/json_nodes.h b/ydb/core/viewer/json_nodes.h
index c5335f14ae3..bfc0bae0e2a 100644
--- a/ydb/core/viewer/json_nodes.h
+++ b/ydb/core/viewer/json_nodes.h
@@ -1,368 +1,368 @@
-#pragma once
-#include <unordered_map>
-#include <library/cpp/actors/core/actor_bootstrapped.h>
-#include <library/cpp/actors/core/interconnect.h>
-#include <library/cpp/actors/core/mon.h>
+#pragma once
+#include <unordered_map>
+#include <library/cpp/actors/core/actor_bootstrapped.h>
+#include <library/cpp/actors/core/interconnect.h>
+#include <library/cpp/actors/core/mon.h>
#include <ydb/core/node_whiteboard/node_whiteboard.h>
#include <ydb/core/viewer/json/json.h>
#include <ydb/core/protos/node_whiteboard.pb.h>
#include <ydb/core/viewer/protos/viewer.pb.h>
-#include "viewer.h"
-#include "json_pipe_req.h"
-#include "json_sysinfo.h"
-#include "json_pdiskinfo.h"
-
-namespace NKikimr {
-namespace NViewer {
-
-using namespace NActors;
-using namespace NNodeWhiteboard;
-using ::google::protobuf::FieldDescriptor;
-
-class TJsonNodes : public TViewerPipeClient<TJsonNodes> {
- using TThis = TJsonNodes;
- using TBase = TViewerPipeClient<TJsonNodes>;
- using TNodeId = ui32;
- using TPDiskId = std::pair<TNodeId, ui32>;
- IViewer* Viewer;
- TActorId Initiator;
- NMon::TEvHttpInfo::TPtr Event;
- std::unique_ptr<TEvInterconnect::TEvNodesInfo> NodesInfo;
- std::unordered_map<TNodeId, THolder<TEvWhiteboard::TEvPDiskStateResponse>> PDiskInfo;
- std::unordered_map<TNodeId, THolder<TEvWhiteboard::TEvSystemStateResponse>> SysInfo;
+#include "viewer.h"
+#include "json_pipe_req.h"
+#include "json_sysinfo.h"
+#include "json_pdiskinfo.h"
+
+namespace NKikimr {
+namespace NViewer {
+
+using namespace NActors;
+using namespace NNodeWhiteboard;
+using ::google::protobuf::FieldDescriptor;
+
+class TJsonNodes : public TViewerPipeClient<TJsonNodes> {
+ using TThis = TJsonNodes;
+ using TBase = TViewerPipeClient<TJsonNodes>;
+ using TNodeId = ui32;
+ using TPDiskId = std::pair<TNodeId, ui32>;
+ IViewer* Viewer;
+ TActorId Initiator;
+ NMon::TEvHttpInfo::TPtr Event;
+ std::unique_ptr<TEvInterconnect::TEvNodesInfo> NodesInfo;
+ std::unordered_map<TNodeId, THolder<TEvWhiteboard::TEvPDiskStateResponse>> PDiskInfo;
+ std::unordered_map<TNodeId, THolder<TEvWhiteboard::TEvSystemStateResponse>> SysInfo;
std::unordered_map<TString, THolder<NSchemeShard::TEvSchemeShard::TEvDescribeSchemeResult>> DescribeResult;
- std::unique_ptr<TEvBlobStorage::TEvControllerConfigResponse> BaseConfig;
- TJsonSettings JsonSettings;
+ std::unique_ptr<TEvBlobStorage::TEvControllerConfigResponse> BaseConfig;
+ TJsonSettings JsonSettings;
ui32 Timeout = 0;
- TString FilterTenant;
- std::vector<TNodeId> FilterNodeIds;
- std::unordered_set<TNodeId> NodeIds;
-
- enum class EWith {
- Everything,
- MissingDisks,
- SpaceProblems,
- };
-
- EWith With = EWith::Everything;
-
-public:
- static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
- return NKikimrServices::TActivity::VIEWER_HANDLER;
- }
-
- TJsonNodes(IViewer* viewer, NMon::TEvHttpInfo::TPtr& ev)
- : Viewer(viewer)
- , Initiator(ev->Sender)
- , Event(std::move(ev))
- {
- const auto& params(Event->Get()->Request.GetParams());
- JsonSettings.EnumAsNumbers = !FromStringWithDefault<bool>(params.Get("enums"), true);
- JsonSettings.UI64AsString = !FromStringWithDefault<bool>(params.Get("ui64"), false);
- InitConfig(params);
- Timeout = FromStringWithDefault<ui32>(params.Get("timeout"), 10000);
- FilterTenant = params.Get("tenant");
- TString filterStoragePool = params.Get("pool");
- SplitIds(params.Get("node_id"), ',', FilterNodeIds);
- if (params.Get("with") == "missing") {
- With = EWith::MissingDisks;
- } if (params.Get("with") == "space") {
- With = EWith::SpaceProblems;
- }
- }
-
- void Bootstrap() {
- TIntrusivePtr<TDomainsInfo> domains = AppData()->DomainsInfo;
-
- if (!FilterTenant.empty()) {
- SendNavigate(FilterTenant);
- }
- std::replace(FilterNodeIds.begin(), FilterNodeIds.end(), (ui32)0, TlsActivationContext->ActorSystem()->NodeId);
- if (FilterNodeIds.empty()) {
- SendRequest(GetNameserviceActorId(), new TEvInterconnect::TEvListNodes());
- } else {
- for (ui32 nodeId : FilterNodeIds) {
- SendNodeRequest(nodeId);
- }
- if (Requests == 0) {
- ReplyAndPassAway();
- return;
- }
- }
-
- RequestBSControllerConfig();
-
- TBase::Become(&TThis::StateWork, TDuration::MilliSeconds(Timeout), new TEvents::TEvWakeup());
- }
-
- void SendNavigate(const TString& path) {
- TAutoPtr<TEvTxUserProxy::TEvNavigate> request(new TEvTxUserProxy::TEvNavigate());
- if (!Event->Get()->UserToken.empty()) {
- request->Record.SetUserToken(Event->Get()->UserToken);
- }
+ TString FilterTenant;
+ std::vector<TNodeId> FilterNodeIds;
+ std::unordered_set<TNodeId> NodeIds;
+
+ enum class EWith {
+ Everything,
+ MissingDisks,
+ SpaceProblems,
+ };
+
+ EWith With = EWith::Everything;
+
+public:
+ static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
+ return NKikimrServices::TActivity::VIEWER_HANDLER;
+ }
+
+ TJsonNodes(IViewer* viewer, NMon::TEvHttpInfo::TPtr& ev)
+ : Viewer(viewer)
+ , Initiator(ev->Sender)
+ , Event(std::move(ev))
+ {
+ const auto& params(Event->Get()->Request.GetParams());
+ JsonSettings.EnumAsNumbers = !FromStringWithDefault<bool>(params.Get("enums"), true);
+ JsonSettings.UI64AsString = !FromStringWithDefault<bool>(params.Get("ui64"), false);
+ InitConfig(params);
+ Timeout = FromStringWithDefault<ui32>(params.Get("timeout"), 10000);
+ FilterTenant = params.Get("tenant");
+ TString filterStoragePool = params.Get("pool");
+ SplitIds(params.Get("node_id"), ',', FilterNodeIds);
+ if (params.Get("with") == "missing") {
+ With = EWith::MissingDisks;
+ } if (params.Get("with") == "space") {
+ With = EWith::SpaceProblems;
+ }
+ }
+
+ void Bootstrap() {
+ TIntrusivePtr<TDomainsInfo> domains = AppData()->DomainsInfo;
+
+ if (!FilterTenant.empty()) {
+ SendNavigate(FilterTenant);
+ }
+ std::replace(FilterNodeIds.begin(), FilterNodeIds.end(), (ui32)0, TlsActivationContext->ActorSystem()->NodeId);
+ if (FilterNodeIds.empty()) {
+ SendRequest(GetNameserviceActorId(), new TEvInterconnect::TEvListNodes());
+ } else {
+ for (ui32 nodeId : FilterNodeIds) {
+ SendNodeRequest(nodeId);
+ }
+ if (Requests == 0) {
+ ReplyAndPassAway();
+ return;
+ }
+ }
+
+ RequestBSControllerConfig();
+
+ TBase::Become(&TThis::StateWork, TDuration::MilliSeconds(Timeout), new TEvents::TEvWakeup());
+ }
+
+ void SendNavigate(const TString& path) {
+ TAutoPtr<TEvTxUserProxy::TEvNavigate> request(new TEvTxUserProxy::TEvNavigate());
+ if (!Event->Get()->UserToken.empty()) {
+ request->Record.SetUserToken(Event->Get()->UserToken);
+ }
NKikimrSchemeOp::TDescribePath* record = request->Record.MutableDescribePath();
- record->SetPath(path);
- request->Record.SetUserToken(Event->Get()->UserToken);
- TActorId txproxy = MakeTxProxyID();
- Send(txproxy, request.Release());
- ++Requests;
- }
-
- void PassAway() override {
- for (const TNodeId nodeId : NodeIds) {
- Send(TActivationContext::InterconnectProxy(nodeId), new TEvents::TEvUnsubscribe());
- }
- TBase::PassAway();
- }
-
- void SendNodeRequest(ui32 nodeId) {
- if (NodeIds.insert(nodeId).second) {
- TActorId whiteboardServiceId = MakeNodeWhiteboardServiceId(nodeId);
- SendRequest(whiteboardServiceId, new TEvWhiteboard::TEvSystemStateRequest(), IEventHandle::FlagTrackDelivery | IEventHandle::FlagSubscribeOnSession, nodeId);
- SendRequest(whiteboardServiceId, new TEvWhiteboard::TEvPDiskStateRequest(), IEventHandle::FlagTrackDelivery | IEventHandle::FlagSubscribeOnSession, nodeId);
- }
- }
-
- void Handle(TEvBlobStorage::TEvControllerSelectGroupsResult::TPtr& ev) {
- for (const auto& matchingGroups : ev->Get()->Record.GetMatchingGroups()) {
- for (const auto& group : matchingGroups.GetGroups()) {
- TString storagePoolName = group.GetStoragePoolName();
- Y_UNUSED(storagePoolName);
- //StoragePoolInfo[storagePoolName].Groups.emplace(ToString(group.GetGroupID()));
- }
- }
- RequestDone();
- }
-
- void Handle(TEvBlobStorage::TEvControllerConfigResponse::TPtr& ev) {
- const NKikimrBlobStorage::TEvControllerConfigResponse& pbRecord(ev->Get()->Record);
-
- if (pbRecord.HasResponse() && pbRecord.GetResponse().StatusSize() > 0) {
- const NKikimrBlobStorage::TConfigResponse::TStatus& pbStatus(pbRecord.GetResponse().GetStatus(0));
- if (pbStatus.HasBaseConfig()) {
- BaseConfig.reset(ev->Release().Release());
- }
- }
- RequestDone();
- }
-
- void Handle(TEvInterconnect::TEvNodesInfo::TPtr& ev) {
- ui32 maxAllowedNodeId = std::numeric_limits<ui32>::max();
- TIntrusivePtr<TDynamicNameserviceConfig> dynamicNameserviceConfig = AppData()->DynamicNameserviceConfig;
- if (dynamicNameserviceConfig) {
- maxAllowedNodeId = dynamicNameserviceConfig->MaxStaticNodeId;
- }
- NodesInfo.reset(ev->Release().Release());
- for (const auto& ni : NodesInfo->Nodes) {
- if (ni.NodeId <= maxAllowedNodeId) {
- SendNodeRequest(ni.NodeId);
- }
- }
- RequestDone();
- }
-
+ record->SetPath(path);
+ request->Record.SetUserToken(Event->Get()->UserToken);
+ TActorId txproxy = MakeTxProxyID();
+ Send(txproxy, request.Release());
+ ++Requests;
+ }
+
+ void PassAway() override {
+ for (const TNodeId nodeId : NodeIds) {
+ Send(TActivationContext::InterconnectProxy(nodeId), new TEvents::TEvUnsubscribe());
+ }
+ TBase::PassAway();
+ }
+
+ void SendNodeRequest(ui32 nodeId) {
+ if (NodeIds.insert(nodeId).second) {
+ TActorId whiteboardServiceId = MakeNodeWhiteboardServiceId(nodeId);
+ SendRequest(whiteboardServiceId, new TEvWhiteboard::TEvSystemStateRequest(), IEventHandle::FlagTrackDelivery | IEventHandle::FlagSubscribeOnSession, nodeId);
+ SendRequest(whiteboardServiceId, new TEvWhiteboard::TEvPDiskStateRequest(), IEventHandle::FlagTrackDelivery | IEventHandle::FlagSubscribeOnSession, nodeId);
+ }
+ }
+
+ void Handle(TEvBlobStorage::TEvControllerSelectGroupsResult::TPtr& ev) {
+ for (const auto& matchingGroups : ev->Get()->Record.GetMatchingGroups()) {
+ for (const auto& group : matchingGroups.GetGroups()) {
+ TString storagePoolName = group.GetStoragePoolName();
+ Y_UNUSED(storagePoolName);
+ //StoragePoolInfo[storagePoolName].Groups.emplace(ToString(group.GetGroupID()));
+ }
+ }
+ RequestDone();
+ }
+
+ void Handle(TEvBlobStorage::TEvControllerConfigResponse::TPtr& ev) {
+ const NKikimrBlobStorage::TEvControllerConfigResponse& pbRecord(ev->Get()->Record);
+
+ if (pbRecord.HasResponse() && pbRecord.GetResponse().StatusSize() > 0) {
+ const NKikimrBlobStorage::TConfigResponse::TStatus& pbStatus(pbRecord.GetResponse().GetStatus(0));
+ if (pbStatus.HasBaseConfig()) {
+ BaseConfig.reset(ev->Release().Release());
+ }
+ }
+ RequestDone();
+ }
+
+ void Handle(TEvInterconnect::TEvNodesInfo::TPtr& ev) {
+ ui32 maxAllowedNodeId = std::numeric_limits<ui32>::max();
+ TIntrusivePtr<TDynamicNameserviceConfig> dynamicNameserviceConfig = AppData()->DynamicNameserviceConfig;
+ if (dynamicNameserviceConfig) {
+ maxAllowedNodeId = dynamicNameserviceConfig->MaxStaticNodeId;
+ }
+ NodesInfo.reset(ev->Release().Release());
+ for (const auto& ni : NodesInfo->Nodes) {
+ if (ni.NodeId <= maxAllowedNodeId) {
+ SendNodeRequest(ni.NodeId);
+ }
+ }
+ RequestDone();
+ }
+
void Handle(NSchemeShard::TEvSchemeShard::TEvDescribeSchemeResult::TPtr& ev) {
- TString path = ev->Get()->GetRecord().GetPath();
-
+ TString path = ev->Get()->GetRecord().GetPath();
+
const NKikimrSchemeOp::TPathDescription& pathDescription = ev->Get()->GetRecord().GetPathDescription();
- TTabletId hiveId = pathDescription.GetDomainDescription().GetProcessingParams().GetHive();
- if (hiveId != 0) {
- RequestHiveStorageStats(hiveId);
- }
-
- for (const auto& storagePool : ev->Get()->GetRecord().GetPathDescription().GetDomainDescription().GetStoragePools()) {
- TString storagePoolName = storagePool.GetName();
- THolder<TEvBlobStorage::TEvControllerSelectGroups> request = MakeHolder<TEvBlobStorage::TEvControllerSelectGroups>();
- request->Record.SetReturnAllMatchingGroups(true);
- request->Record.AddGroupParameters()->MutableStoragePoolSpecifier()->SetName(storagePoolName);
- RequestBSControllerSelectGroups(std::move(request));
- }
-
- DescribeResult[path] = ev->Release();
- RequestDone();
- }
-
- void Undelivered(TEvents::TEvUndelivered::TPtr& ev) {
- ui32 nodeId = ev.Get()->Cookie;
- switch (ev->Get()->SourceType) {
- case TEvWhiteboard::EvSystemStateRequest:
- if (SysInfo.emplace(nodeId, nullptr).second) {
- RequestDone();
- }
- break;
- case TEvWhiteboard::EvPDiskStateRequest:
- if (PDiskInfo.emplace(nodeId, nullptr).second) {
- RequestDone();
- }
- break;
- }
- }
-
- void Disconnected(TEvInterconnect::TEvNodeDisconnected::TPtr& ev) {
- ui32 nodeId = ev->Get()->NodeId;
- if (SysInfo.emplace(nodeId, nullptr).second) {
- RequestDone();
- }
- if (PDiskInfo.emplace(nodeId, nullptr).second) {
- RequestDone();
- }
- }
-
- void Handle(TEvWhiteboard::TEvSystemStateResponse::TPtr& ev) {
- ui64 nodeId = ev.Get()->Cookie;
- SysInfo[nodeId] = ev->Release();
- RequestDone();
- }
-
- void Handle(TEvWhiteboard::TEvPDiskStateResponse::TPtr& ev) {
- ui64 nodeId = ev.Get()->Cookie;
- PDiskInfo[nodeId] = ev->Release();
- RequestDone();
- }
-
- STATEFN(StateWork) {
- switch (ev->GetTypeRewrite()) {
- hFunc(TEvInterconnect::TEvNodesInfo, Handle);
- hFunc(TEvWhiteboard::TEvSystemStateResponse, Handle);
- hFunc(TEvWhiteboard::TEvPDiskStateResponse, Handle);
+ TTabletId hiveId = pathDescription.GetDomainDescription().GetProcessingParams().GetHive();
+ if (hiveId != 0) {
+ RequestHiveStorageStats(hiveId);
+ }
+
+ for (const auto& storagePool : ev->Get()->GetRecord().GetPathDescription().GetDomainDescription().GetStoragePools()) {
+ TString storagePoolName = storagePool.GetName();
+ THolder<TEvBlobStorage::TEvControllerSelectGroups> request = MakeHolder<TEvBlobStorage::TEvControllerSelectGroups>();
+ request->Record.SetReturnAllMatchingGroups(true);
+ request->Record.AddGroupParameters()->MutableStoragePoolSpecifier()->SetName(storagePoolName);
+ RequestBSControllerSelectGroups(std::move(request));
+ }
+
+ DescribeResult[path] = ev->Release();
+ RequestDone();
+ }
+
+ void Undelivered(TEvents::TEvUndelivered::TPtr& ev) {
+ ui32 nodeId = ev.Get()->Cookie;
+ switch (ev->Get()->SourceType) {
+ case TEvWhiteboard::EvSystemStateRequest:
+ if (SysInfo.emplace(nodeId, nullptr).second) {
+ RequestDone();
+ }
+ break;
+ case TEvWhiteboard::EvPDiskStateRequest:
+ if (PDiskInfo.emplace(nodeId, nullptr).second) {
+ RequestDone();
+ }
+ break;
+ }
+ }
+
+ void Disconnected(TEvInterconnect::TEvNodeDisconnected::TPtr& ev) {
+ ui32 nodeId = ev->Get()->NodeId;
+ if (SysInfo.emplace(nodeId, nullptr).second) {
+ RequestDone();
+ }
+ if (PDiskInfo.emplace(nodeId, nullptr).second) {
+ RequestDone();
+ }
+ }
+
+ void Handle(TEvWhiteboard::TEvSystemStateResponse::TPtr& ev) {
+ ui64 nodeId = ev.Get()->Cookie;
+ SysInfo[nodeId] = ev->Release();
+ RequestDone();
+ }
+
+ void Handle(TEvWhiteboard::TEvPDiskStateResponse::TPtr& ev) {
+ ui64 nodeId = ev.Get()->Cookie;
+ PDiskInfo[nodeId] = ev->Release();
+ RequestDone();
+ }
+
+ STATEFN(StateWork) {
+ switch (ev->GetTypeRewrite()) {
+ hFunc(TEvInterconnect::TEvNodesInfo, Handle);
+ hFunc(TEvWhiteboard::TEvSystemStateResponse, Handle);
+ hFunc(TEvWhiteboard::TEvPDiskStateResponse, Handle);
hFunc(NSchemeShard::TEvSchemeShard::TEvDescribeSchemeResult, Handle);
- hFunc(TEvBlobStorage::TEvControllerSelectGroupsResult, Handle);
- hFunc(TEvBlobStorage::TEvControllerConfigResponse, Handle);
- hFunc(TEvents::TEvUndelivered, Undelivered);
- hFunc(TEvInterconnect::TEvNodeDisconnected, Disconnected);
- hFunc(TEvTabletPipe::TEvClientConnected, TBase::Handle);
- cFunc(TEvents::TSystem::Wakeup, HandleTimeout);
- }
- }
-
- void ReplyAndPassAway() {
- NKikimrViewer::TNodesInfo nodesInfo;
- std::unordered_map<TNodeId, NKikimrViewer::TNodeInfo*> nodeIndex;
- std::unordered_map<TPDiskId, NKikimrWhiteboard::TPDiskStateInfo*> pDiskIndex;
-
- std::function<NKikimrViewer::TNodeInfo&(TNodeId)> getNode = [&nodesInfo, &nodeIndex](TNodeId nodeId) -> NKikimrViewer::TNodeInfo& {
- auto itNode = nodeIndex.find(nodeId);
- if (itNode != nodeIndex.end()) {
- return *(itNode->second);
- }
- NKikimrViewer::TNodeInfo& nodeInfo = *nodesInfo.AddNodes();
- nodeInfo.SetNodeId(nodeId);
- nodeIndex.emplace(nodeId, &nodeInfo);
- return nodeInfo;
- };
-
- std::function<NKikimrWhiteboard::TPDiskStateInfo&(TPDiskId)> getPDisk = [&getNode, &pDiskIndex](TPDiskId pDiskId) -> NKikimrWhiteboard::TPDiskStateInfo& {
- auto itPDisk = pDiskIndex.find(pDiskId);
- if (itPDisk != pDiskIndex.end()) {
- return *(itPDisk->second);
- }
- NKikimrViewer::TNodeInfo& nodeInfo = getNode(pDiskId.first);
- NKikimrWhiteboard::TPDiskStateInfo& pDiskInfo = *nodeInfo.AddPDisks();
- pDiskInfo.SetPDiskId(pDiskId.second);
- pDiskIndex.emplace(pDiskId, &pDiskInfo);
- return pDiskInfo;
- };
-
- if (BaseConfig) {
- const NKikimrBlobStorage::TEvControllerConfigResponse& pbRecord(BaseConfig->Record);
- const NKikimrBlobStorage::TConfigResponse::TStatus& pbStatus(pbRecord.GetResponse().GetStatus(0));
- const NKikimrBlobStorage::TBaseConfig& pbConfig(pbStatus.GetBaseConfig());
- for (const NKikimrBlobStorage::TBaseConfig::TPDisk& pDisk : pbConfig.GetPDisk()) {
- TPDiskId pDiskId(pDisk.GetNodeId(), pDisk.GetPDiskId());
- NKikimrWhiteboard::TPDiskStateInfo& pDiskInfo = getPDisk(pDiskId);
- pDiskInfo.SetPath(pDisk.GetPath());
- pDiskInfo.SetGuid(pDisk.GetGuid());
- pDiskInfo.SetCategory(static_cast<ui64>(pDisk.GetType()));
- pDiskInfo.SetTotalSize(pDisk.GetPDiskMetrics().GetTotalSize());
- pDiskInfo.SetAvailableSize(pDisk.GetPDiskMetrics().GetAvailableSize());
- }
- }
-
- for (TNodeId nodeId : NodeIds) {
- NKikimrViewer::TNodeInfo& nodeInfo = getNode(nodeId);
- auto itSystemState = SysInfo.find(nodeId);
- if (itSystemState != SysInfo.end() && itSystemState->second) {
- *nodeInfo.MutableSystemState() = itSystemState->second->Record.GetSystemStateInfo(0);
- }
- auto itPDiskState = PDiskInfo.find(nodeId);
- if (itPDiskState != PDiskInfo.end() && itPDiskState->second) {
- for (const auto& protoPDiskInfo : itPDiskState->second->Record.GetPDiskStateInfo()) {
- NKikimrWhiteboard::TPDiskStateInfo& pDiskInfo = getPDisk({nodeId, protoPDiskInfo.GetPDiskId()});
- pDiskInfo.MergeFrom(protoPDiskInfo);
- }
- }
- }
-
- if (With == EWith::MissingDisks) {
- for (auto itNode = nodesInfo.MutableNodes()->begin(); itNode != nodesInfo.MutableNodes()->end();) {
- size_t disksNormal = 0;
- for (const NKikimrWhiteboard::TPDiskStateInfo& pDiskInfo : itNode->GetPDisks()) {
- if (pDiskInfo.GetState() == NKikimrBlobStorage::TPDiskState::Normal) {
- ++disksNormal;
- }
- }
- if (itNode->PDisksSize() == disksNormal) {
- itNode = nodesInfo.MutableNodes()->erase(itNode);
- } else {
- ++itNode;
- }
- }
- }
-
- if (With == EWith::SpaceProblems) {
- for (auto itNode = nodesInfo.MutableNodes()->begin(); itNode != nodesInfo.MutableNodes()->end();) {
- if (itNode->GetSystemState().GetMaxDiskUsage() < 85) {
- itNode = nodesInfo.MutableNodes()->erase(itNode);
- } else {
- ++itNode;
- }
- }
- }
-
- TStringStream json;
- TProtoToJson::ProtoToJson(json, nodesInfo, JsonSettings);
- Send(Initiator, new NMon::TEvHttpInfoRes(Viewer->GetHTTPOKJSON() + json.Str(), 0, NMon::IEvHttpInfoRes::EContentType::Custom));
- PassAway();
- }
-
- void HandleTimeout() {
- ReplyAndPassAway();
- }
-};
-
-template <>
-struct TJsonRequestSchema<TJsonNodes> {
- static TString GetSchema() {
- TStringStream stream;
- TProtoToJson::ProtoToJsonSchema<NKikimrViewer::TNodesInfo>(stream);
- return stream.Str();
- }
-};
-
-template <>
-struct TJsonRequestParameters<TJsonNodes> {
- static TString GetParameters() {
- return R"___([{"name":"enums","in":"query","description":"convert enums to strings","required":false,"type":"boolean"},
- {"name":"ui64","in":"query","description":"return ui64 as numbers","required":false,"type":"boolean"},
- {"name":"tenant","in":"query","description":"tenant filter","required":false,"type":"string"},
- {"name":"with","in":"query","description":"filter groups by missing or space","required":false,"type":"string"},
- {"name":"timeout","in":"query","description":"timeout in ms","required":false,"type":"integer"}])___";
- }
-};
-
-template <>
-struct TJsonRequestSummary<TJsonNodes> {
- static TString GetSummary() {
- return "\"Storage nodes info\"";
- }
-};
-
-template <>
-struct TJsonRequestDescription<TJsonNodes> {
- static TString GetDescription() {
- return "\"Storage state by physicall nodes\"";
- }
-};
-
-}
-}
+ hFunc(TEvBlobStorage::TEvControllerSelectGroupsResult, Handle);
+ hFunc(TEvBlobStorage::TEvControllerConfigResponse, Handle);
+ hFunc(TEvents::TEvUndelivered, Undelivered);
+ hFunc(TEvInterconnect::TEvNodeDisconnected, Disconnected);
+ hFunc(TEvTabletPipe::TEvClientConnected, TBase::Handle);
+ cFunc(TEvents::TSystem::Wakeup, HandleTimeout);
+ }
+ }
+
+ void ReplyAndPassAway() {
+ NKikimrViewer::TNodesInfo nodesInfo;
+ std::unordered_map<TNodeId, NKikimrViewer::TNodeInfo*> nodeIndex;
+ std::unordered_map<TPDiskId, NKikimrWhiteboard::TPDiskStateInfo*> pDiskIndex;
+
+ std::function<NKikimrViewer::TNodeInfo&(TNodeId)> getNode = [&nodesInfo, &nodeIndex](TNodeId nodeId) -> NKikimrViewer::TNodeInfo& {
+ auto itNode = nodeIndex.find(nodeId);
+ if (itNode != nodeIndex.end()) {
+ return *(itNode->second);
+ }
+ NKikimrViewer::TNodeInfo& nodeInfo = *nodesInfo.AddNodes();
+ nodeInfo.SetNodeId(nodeId);
+ nodeIndex.emplace(nodeId, &nodeInfo);
+ return nodeInfo;
+ };
+
+ std::function<NKikimrWhiteboard::TPDiskStateInfo&(TPDiskId)> getPDisk = [&getNode, &pDiskIndex](TPDiskId pDiskId) -> NKikimrWhiteboard::TPDiskStateInfo& {
+ auto itPDisk = pDiskIndex.find(pDiskId);
+ if (itPDisk != pDiskIndex.end()) {
+ return *(itPDisk->second);
+ }
+ NKikimrViewer::TNodeInfo& nodeInfo = getNode(pDiskId.first);
+ NKikimrWhiteboard::TPDiskStateInfo& pDiskInfo = *nodeInfo.AddPDisks();
+ pDiskInfo.SetPDiskId(pDiskId.second);
+ pDiskIndex.emplace(pDiskId, &pDiskInfo);
+ return pDiskInfo;
+ };
+
+ if (BaseConfig) {
+ const NKikimrBlobStorage::TEvControllerConfigResponse& pbRecord(BaseConfig->Record);
+ const NKikimrBlobStorage::TConfigResponse::TStatus& pbStatus(pbRecord.GetResponse().GetStatus(0));
+ const NKikimrBlobStorage::TBaseConfig& pbConfig(pbStatus.GetBaseConfig());
+ for (const NKikimrBlobStorage::TBaseConfig::TPDisk& pDisk : pbConfig.GetPDisk()) {
+ TPDiskId pDiskId(pDisk.GetNodeId(), pDisk.GetPDiskId());
+ NKikimrWhiteboard::TPDiskStateInfo& pDiskInfo = getPDisk(pDiskId);
+ pDiskInfo.SetPath(pDisk.GetPath());
+ pDiskInfo.SetGuid(pDisk.GetGuid());
+ pDiskInfo.SetCategory(static_cast<ui64>(pDisk.GetType()));
+ pDiskInfo.SetTotalSize(pDisk.GetPDiskMetrics().GetTotalSize());
+ pDiskInfo.SetAvailableSize(pDisk.GetPDiskMetrics().GetAvailableSize());
+ }
+ }
+
+ for (TNodeId nodeId : NodeIds) {
+ NKikimrViewer::TNodeInfo& nodeInfo = getNode(nodeId);
+ auto itSystemState = SysInfo.find(nodeId);
+ if (itSystemState != SysInfo.end() && itSystemState->second) {
+ *nodeInfo.MutableSystemState() = itSystemState->second->Record.GetSystemStateInfo(0);
+ }
+ auto itPDiskState = PDiskInfo.find(nodeId);
+ if (itPDiskState != PDiskInfo.end() && itPDiskState->second) {
+ for (const auto& protoPDiskInfo : itPDiskState->second->Record.GetPDiskStateInfo()) {
+ NKikimrWhiteboard::TPDiskStateInfo& pDiskInfo = getPDisk({nodeId, protoPDiskInfo.GetPDiskId()});
+ pDiskInfo.MergeFrom(protoPDiskInfo);
+ }
+ }
+ }
+
+ if (With == EWith::MissingDisks) {
+ for (auto itNode = nodesInfo.MutableNodes()->begin(); itNode != nodesInfo.MutableNodes()->end();) {
+ size_t disksNormal = 0;
+ for (const NKikimrWhiteboard::TPDiskStateInfo& pDiskInfo : itNode->GetPDisks()) {
+ if (pDiskInfo.GetState() == NKikimrBlobStorage::TPDiskState::Normal) {
+ ++disksNormal;
+ }
+ }
+ if (itNode->PDisksSize() == disksNormal) {
+ itNode = nodesInfo.MutableNodes()->erase(itNode);
+ } else {
+ ++itNode;
+ }
+ }
+ }
+
+ if (With == EWith::SpaceProblems) {
+ for (auto itNode = nodesInfo.MutableNodes()->begin(); itNode != nodesInfo.MutableNodes()->end();) {
+ if (itNode->GetSystemState().GetMaxDiskUsage() < 85) {
+ itNode = nodesInfo.MutableNodes()->erase(itNode);
+ } else {
+ ++itNode;
+ }
+ }
+ }
+
+ TStringStream json;
+ TProtoToJson::ProtoToJson(json, nodesInfo, JsonSettings);
+ Send(Initiator, new NMon::TEvHttpInfoRes(Viewer->GetHTTPOKJSON() + json.Str(), 0, NMon::IEvHttpInfoRes::EContentType::Custom));
+ PassAway();
+ }
+
+ void HandleTimeout() {
+ ReplyAndPassAway();
+ }
+};
+
+template <>
+struct TJsonRequestSchema<TJsonNodes> {
+ static TString GetSchema() {
+ TStringStream stream;
+ TProtoToJson::ProtoToJsonSchema<NKikimrViewer::TNodesInfo>(stream);
+ return stream.Str();
+ }
+};
+
+template <>
+struct TJsonRequestParameters<TJsonNodes> {
+ static TString GetParameters() {
+ return R"___([{"name":"enums","in":"query","description":"convert enums to strings","required":false,"type":"boolean"},
+ {"name":"ui64","in":"query","description":"return ui64 as numbers","required":false,"type":"boolean"},
+ {"name":"tenant","in":"query","description":"tenant filter","required":false,"type":"string"},
+ {"name":"with","in":"query","description":"filter groups by missing or space","required":false,"type":"string"},
+ {"name":"timeout","in":"query","description":"timeout in ms","required":false,"type":"integer"}])___";
+ }
+};
+
+template <>
+struct TJsonRequestSummary<TJsonNodes> {
+ static TString GetSummary() {
+ return "\"Storage nodes info\"";
+ }
+};
+
+template <>
+struct TJsonRequestDescription<TJsonNodes> {
+ static TString GetDescription() {
+ return "\"Storage state by physicall nodes\"";
+ }
+};
+
+}
+}
diff --git a/ydb/core/viewer/json_pdiskinfo.h b/ydb/core/viewer/json_pdiskinfo.h
index bc19b548a33..881c108e513 100644
--- a/ydb/core/viewer/json_pdiskinfo.h
+++ b/ydb/core/viewer/json_pdiskinfo.h
@@ -1,58 +1,58 @@
-#pragma once
+#pragma once
#include <library/cpp/actors/core/actor_bootstrapped.h>
#include <library/cpp/actors/core/interconnect.h>
#include <library/cpp/actors/core/mon.h>
#include <ydb/core/protos/services.pb.h>
#include <ydb/core/node_whiteboard/node_whiteboard.h>
-#include "json_wb_req.h"
-
-namespace NKikimr {
-namespace NViewer {
-
-template <>
-struct TWhiteboardInfo<TEvWhiteboard::TEvPDiskStateResponse> {
- using TResponseType = TEvWhiteboard::TEvPDiskStateResponse;
- using TElementType = NKikimrWhiteboard::TPDiskStateInfo;
- using TElementKeyType = std::pair<ui32, ui32>;
-
- static constexpr bool StaticNodesOnly = true;
-
- static ::google::protobuf::RepeatedPtrField<TElementType>* GetElementsField(TResponseType* response) {
- return response->Record.MutablePDiskStateInfo();
- }
-
- static std::pair<ui32, ui32> GetElementKey(const TElementType& type) {
- return std::make_pair(type.GetNodeId(), type.GetPDiskId());
- }
-
- static TString GetDefaultMergeField() {
- return "NodeId,PDiskId";
- }
-
- static THolder<TResponseType> MergeResponses(TMap<ui32, THolder<TResponseType>>& responses, const TString& fields = GetDefaultMergeField()) {
- if (fields == GetDefaultMergeField()) {
- return TWhiteboardMerger<TResponseType>::MergeResponsesElementKey(responses);
- } else {
- return TWhiteboardMerger<TResponseType>::MergeResponses(responses, fields);
- }
- }
-};
-
-using TJsonPDiskInfo = TJsonWhiteboardRequest<TEvWhiteboard::TEvPDiskStateRequest, TEvWhiteboard::TEvPDiskStateResponse>;
-
-template <>
-struct TJsonRequestSummary<TJsonPDiskInfo> {
+#include "json_wb_req.h"
+
+namespace NKikimr {
+namespace NViewer {
+
+template <>
+struct TWhiteboardInfo<TEvWhiteboard::TEvPDiskStateResponse> {
+ using TResponseType = TEvWhiteboard::TEvPDiskStateResponse;
+ using TElementType = NKikimrWhiteboard::TPDiskStateInfo;
+ using TElementKeyType = std::pair<ui32, ui32>;
+
+ static constexpr bool StaticNodesOnly = true;
+
+ static ::google::protobuf::RepeatedPtrField<TElementType>* GetElementsField(TResponseType* response) {
+ return response->Record.MutablePDiskStateInfo();
+ }
+
+ static std::pair<ui32, ui32> GetElementKey(const TElementType& type) {
+ return std::make_pair(type.GetNodeId(), type.GetPDiskId());
+ }
+
+ static TString GetDefaultMergeField() {
+ return "NodeId,PDiskId";
+ }
+
+ static THolder<TResponseType> MergeResponses(TMap<ui32, THolder<TResponseType>>& responses, const TString& fields = GetDefaultMergeField()) {
+ if (fields == GetDefaultMergeField()) {
+ return TWhiteboardMerger<TResponseType>::MergeResponsesElementKey(responses);
+ } else {
+ return TWhiteboardMerger<TResponseType>::MergeResponses(responses, fields);
+ }
+ }
+};
+
+using TJsonPDiskInfo = TJsonWhiteboardRequest<TEvWhiteboard::TEvPDiskStateRequest, TEvWhiteboard::TEvPDiskStateResponse>;
+
+template <>
+struct TJsonRequestSummary<TJsonPDiskInfo> {
static TString GetSummary() {
- return "\"PDisk information\"";
- }
-};
-
-template <>
-struct TJsonRequestDescription<TJsonPDiskInfo> {
+ return "\"PDisk information\"";
+ }
+};
+
+template <>
+struct TJsonRequestDescription<TJsonPDiskInfo> {
static TString GetDescription() {
- return "\"Returns PDisk information\"";
- }
-};
-
-}
-}
+ return "\"Returns PDisk information\"";
+ }
+};
+
+}
+}
diff --git a/ydb/core/viewer/json_pipe_req.h b/ydb/core/viewer/json_pipe_req.h
index fec5280e566..d41b2a93d4f 100644
--- a/ydb/core/viewer/json_pipe_req.h
+++ b/ydb/core/viewer/json_pipe_req.h
@@ -1,227 +1,227 @@
-#pragma once
-
-#include <library/cpp/actors/core/actor.h>
-#include <library/cpp/actors/core/actor_bootstrapped.h>
+#pragma once
+
+#include <library/cpp/actors/core/actor.h>
+#include <library/cpp/actors/core/actor_bootstrapped.h>
#include <ydb/core/base/tablet_pipe.h>
#include <ydb/core/cms/console/console.h>
#include <ydb/core/base/hive.h>
#include <ydb/core/blobstorage/base/blobstorage_events.h>
-#include <ydb/core/tx/scheme_cache/scheme_cache.h>
-#include <ydb/core/tx/schemeshard/schemeshard.h>
-#include "viewer.h"
-
-namespace NKikimr {
-namespace NViewer {
-
-using namespace NKikimr;
-using namespace NSchemeCache;
-
-template <typename TDerived>
-class TViewerPipeClient : public TActorBootstrapped<TDerived> {
-protected:
- using TBase = TActorBootstrapped<TDerived>;
+#include <ydb/core/tx/scheme_cache/scheme_cache.h>
+#include <ydb/core/tx/schemeshard/schemeshard.h>
+#include "viewer.h"
+
+namespace NKikimr {
+namespace NViewer {
+
+using namespace NKikimr;
+using namespace NSchemeCache;
+
+template <typename TDerived>
+class TViewerPipeClient : public TActorBootstrapped<TDerived> {
+protected:
+ using TBase = TActorBootstrapped<TDerived>;
bool Followers = true;
- bool Metrics = true;
- bool WithRetry = true;
- ui32 Requests = 0;
- static constexpr ui32 MaxRequestsInFlight = 50;
-
- struct TPipeInfo {
- TActorId PipeClient;
- ui32 Requests = 0;
- };
-
- std::unordered_map<TTabletId, TPipeInfo> PipeInfo;
-
- struct TDelayedRequest {
- std::unique_ptr<IEventHandle> Event;
- };
-
- std::deque<TDelayedRequest> DelayedRequests;
-
- NTabletPipe::TClientConfig GetPipeClientConfig() {
- NTabletPipe::TClientConfig clientConfig;
- if (WithRetry) {
- clientConfig.RetryPolicy = {.RetryLimitCount = 3};
- }
- return clientConfig;
- }
-
- TActorId ConnectTabletPipe(TTabletId tabletId) {
- TPipeInfo& pipeInfo = PipeInfo[tabletId];
- if (!pipeInfo.PipeClient) {
- auto pipe = NTabletPipe::CreateClient(TBase::SelfId(), tabletId, GetPipeClientConfig());
- pipeInfo.PipeClient = TBase::RegisterWithSameMailbox(pipe);
- }
- pipeInfo.Requests++;
- return pipeInfo.PipeClient;
- }
-
- void SendEvent(std::unique_ptr<IEventHandle> event) {
- if (DelayedRequests.empty() && Requests < MaxRequestsInFlight) {
- TActivationContext::Send(event.release());
- ++Requests;
- } else {
- DelayedRequests.push_back({
- .Event = std::move(event),
- });
- }
- }
-
- void SendRequest(const TActorId& recipient, IEventBase* ev, ui32 flags = 0, ui64 cookie = 0) {
- SendEvent(std::make_unique<IEventHandle>(recipient, TBase::SelfId(), ev, flags, cookie));
- }
-
- void SendRequestToPipe(const TActorId& pipe, IEventBase* ev, ui64 cookie = 0) {
- std::unique_ptr<IEventHandle> event = std::make_unique<IEventHandle>(pipe, TBase::SelfId(), ev, 0/*flags*/, cookie);
- event->Rewrite(TEvTabletPipe::EvSend, pipe);
- SendEvent(std::move(event));
- }
-
- void SendDelayedRequests() {
- while (!DelayedRequests.empty() && Requests < MaxRequestsInFlight) {
- auto& request(DelayedRequests.front());
- TActivationContext::Send(request.Event.release());
- ++Requests;
- DelayedRequests.pop_front();
- }
- }
-
- void RequestHiveDomainStats(TTabletId hiveId) {
- TActorId pipeClient = ConnectTabletPipe(hiveId);
- THolder<TEvHive::TEvRequestHiveDomainStats> request = MakeHolder<TEvHive::TEvRequestHiveDomainStats>();
+ bool Metrics = true;
+ bool WithRetry = true;
+ ui32 Requests = 0;
+ static constexpr ui32 MaxRequestsInFlight = 50;
+
+ struct TPipeInfo {
+ TActorId PipeClient;
+ ui32 Requests = 0;
+ };
+
+ std::unordered_map<TTabletId, TPipeInfo> PipeInfo;
+
+ struct TDelayedRequest {
+ std::unique_ptr<IEventHandle> Event;
+ };
+
+ std::deque<TDelayedRequest> DelayedRequests;
+
+ NTabletPipe::TClientConfig GetPipeClientConfig() {
+ NTabletPipe::TClientConfig clientConfig;
+ if (WithRetry) {
+ clientConfig.RetryPolicy = {.RetryLimitCount = 3};
+ }
+ return clientConfig;
+ }
+
+ TActorId ConnectTabletPipe(TTabletId tabletId) {
+ TPipeInfo& pipeInfo = PipeInfo[tabletId];
+ if (!pipeInfo.PipeClient) {
+ auto pipe = NTabletPipe::CreateClient(TBase::SelfId(), tabletId, GetPipeClientConfig());
+ pipeInfo.PipeClient = TBase::RegisterWithSameMailbox(pipe);
+ }
+ pipeInfo.Requests++;
+ return pipeInfo.PipeClient;
+ }
+
+ void SendEvent(std::unique_ptr<IEventHandle> event) {
+ if (DelayedRequests.empty() && Requests < MaxRequestsInFlight) {
+ TActivationContext::Send(event.release());
+ ++Requests;
+ } else {
+ DelayedRequests.push_back({
+ .Event = std::move(event),
+ });
+ }
+ }
+
+ void SendRequest(const TActorId& recipient, IEventBase* ev, ui32 flags = 0, ui64 cookie = 0) {
+ SendEvent(std::make_unique<IEventHandle>(recipient, TBase::SelfId(), ev, flags, cookie));
+ }
+
+ void SendRequestToPipe(const TActorId& pipe, IEventBase* ev, ui64 cookie = 0) {
+ std::unique_ptr<IEventHandle> event = std::make_unique<IEventHandle>(pipe, TBase::SelfId(), ev, 0/*flags*/, cookie);
+ event->Rewrite(TEvTabletPipe::EvSend, pipe);
+ SendEvent(std::move(event));
+ }
+
+ void SendDelayedRequests() {
+ while (!DelayedRequests.empty() && Requests < MaxRequestsInFlight) {
+ auto& request(DelayedRequests.front());
+ TActivationContext::Send(request.Event.release());
+ ++Requests;
+ DelayedRequests.pop_front();
+ }
+ }
+
+ void RequestHiveDomainStats(TTabletId hiveId) {
+ TActorId pipeClient = ConnectTabletPipe(hiveId);
+ THolder<TEvHive::TEvRequestHiveDomainStats> request = MakeHolder<TEvHive::TEvRequestHiveDomainStats>();
request->Record.SetReturnFollowers(Followers);
- request->Record.SetReturnMetrics(Metrics);
- SendRequestToPipe(pipeClient, request.Release(), hiveId);
- }
-
- void RequestHiveNodeStats(TTabletId hiveId) {
- TActorId pipeClient = ConnectTabletPipe(hiveId);
- THolder<TEvHive::TEvRequestHiveNodeStats> request = MakeHolder<TEvHive::TEvRequestHiveNodeStats>();
- request->Record.SetReturnMetrics(Metrics);
- SendRequestToPipe(pipeClient, request.Release(), hiveId);
- }
-
- void RequestHiveStorageStats(TTabletId hiveId) {
- TActorId pipeClient = ConnectTabletPipe(hiveId);
- THolder<TEvHive::TEvRequestHiveStorageStats> request = MakeHolder<TEvHive::TEvRequestHiveStorageStats>();
- SendRequestToPipe(pipeClient, request.Release(), hiveId);
- }
-
- TTabletId GetConsoleId() {
- TIntrusivePtr<TDomainsInfo> domains = AppData()->DomainsInfo;
- TIntrusivePtr<TDomainsInfo::TDomain> domain = domains->Domains.begin()->second;
- auto group = domains->GetDefaultStateStorageGroup(domain->DomainUid);
- return MakeConsoleID(group);
- }
-
- void RequestConsoleListTenants() {
- TActorId pipeClient = ConnectTabletPipe(GetConsoleId());
- THolder<NConsole::TEvConsole::TEvListTenantsRequest> request = MakeHolder<NConsole::TEvConsole::TEvListTenantsRequest>();
- SendRequestToPipe(pipeClient, request.Release());
- }
-
- void RequestConsoleGetTenantStatus(const TString& path) {
- TActorId pipeClient = ConnectTabletPipe(GetConsoleId());
- THolder<NConsole::TEvConsole::TEvGetTenantStatusRequest> request = MakeHolder<NConsole::TEvConsole::TEvGetTenantStatusRequest>();
- request->Record.MutableRequest()->set_path(path);
- SendRequestToPipe(pipeClient, request.Release());
- }
-
- TTabletId GetBSControllerId() {
- TIntrusivePtr<TDomainsInfo> domains = AppData()->DomainsInfo;
- TIntrusivePtr<TDomainsInfo::TDomain> domain = domains->Domains.begin()->second;
- ui32 stateStorageGroup = domains->GetDefaultStateStorageGroup(domain->DomainUid);
- return MakeBSControllerID(stateStorageGroup);
- }
-
- void RequestBSControllerConfig() {
- TActorId pipeClient = ConnectTabletPipe(GetBSControllerId());
- THolder<TEvBlobStorage::TEvControllerConfigRequest> request = MakeHolder<TEvBlobStorage::TEvControllerConfigRequest>();
- request->Record.MutableRequest()->AddCommand()->MutableQueryBaseConfig();
- SendRequestToPipe(pipeClient, request.Release());
- }
-
- void RequestBSControllerInfo() {
- TActorId pipeClient = ConnectTabletPipe(GetBSControllerId());
- THolder<TEvBlobStorage::TEvRequestControllerInfo> request = MakeHolder<TEvBlobStorage::TEvRequestControllerInfo>();
- SendRequestToPipe(pipeClient, request.Release());
- }
-
- void RequestBSControllerSelectGroups(THolder<TEvBlobStorage::TEvControllerSelectGroups> request) {
- TActorId pipeClient = ConnectTabletPipe(GetBSControllerId());
- SendRequestToPipe(pipeClient, request.Release());
- }
-
- void RequestSchemeCacheNavigate(const TString& path) {
- THolder<NSchemeCache::TSchemeCacheNavigate> request = MakeHolder<NSchemeCache::TSchemeCacheNavigate>();
- NSchemeCache::TSchemeCacheNavigate::TEntry entry;
- entry.Path = SplitPath(path);
- entry.RedirectRequired = false;
- entry.Operation = NSchemeCache::TSchemeCacheNavigate::EOp::OpPath;
- request->ResultSet.emplace_back(entry);
- SendRequest(MakeSchemeCacheID(), new TEvTxProxySchemeCache::TEvNavigateKeySet(request.Release()));
- }
-
- void RequestSchemeCacheNavigate(const TPathId& pathId) {
- THolder<NSchemeCache::TSchemeCacheNavigate> request = MakeHolder<NSchemeCache::TSchemeCacheNavigate>();
- NSchemeCache::TSchemeCacheNavigate::TEntry entry;
- entry.TableId.PathId = pathId;
- entry.RequestType = NSchemeCache::TSchemeCacheNavigate::TEntry::ERequestType::ByTableId;
- entry.RedirectRequired = false;
- entry.Operation = NSchemeCache::TSchemeCacheNavigate::EOp::OpPath;
- request->ResultSet.emplace_back(entry);
- SendRequest(MakeSchemeCacheID(), new TEvTxProxySchemeCache::TEvNavigateKeySet(request.Release()));
- }
-
- void InitConfig(const TCgiParameters& params) {
+ request->Record.SetReturnMetrics(Metrics);
+ SendRequestToPipe(pipeClient, request.Release(), hiveId);
+ }
+
+ void RequestHiveNodeStats(TTabletId hiveId) {
+ TActorId pipeClient = ConnectTabletPipe(hiveId);
+ THolder<TEvHive::TEvRequestHiveNodeStats> request = MakeHolder<TEvHive::TEvRequestHiveNodeStats>();
+ request->Record.SetReturnMetrics(Metrics);
+ SendRequestToPipe(pipeClient, request.Release(), hiveId);
+ }
+
+ void RequestHiveStorageStats(TTabletId hiveId) {
+ TActorId pipeClient = ConnectTabletPipe(hiveId);
+ THolder<TEvHive::TEvRequestHiveStorageStats> request = MakeHolder<TEvHive::TEvRequestHiveStorageStats>();
+ SendRequestToPipe(pipeClient, request.Release(), hiveId);
+ }
+
+ TTabletId GetConsoleId() {
+ TIntrusivePtr<TDomainsInfo> domains = AppData()->DomainsInfo;
+ TIntrusivePtr<TDomainsInfo::TDomain> domain = domains->Domains.begin()->second;
+ auto group = domains->GetDefaultStateStorageGroup(domain->DomainUid);
+ return MakeConsoleID(group);
+ }
+
+ void RequestConsoleListTenants() {
+ TActorId pipeClient = ConnectTabletPipe(GetConsoleId());
+ THolder<NConsole::TEvConsole::TEvListTenantsRequest> request = MakeHolder<NConsole::TEvConsole::TEvListTenantsRequest>();
+ SendRequestToPipe(pipeClient, request.Release());
+ }
+
+ void RequestConsoleGetTenantStatus(const TString& path) {
+ TActorId pipeClient = ConnectTabletPipe(GetConsoleId());
+ THolder<NConsole::TEvConsole::TEvGetTenantStatusRequest> request = MakeHolder<NConsole::TEvConsole::TEvGetTenantStatusRequest>();
+ request->Record.MutableRequest()->set_path(path);
+ SendRequestToPipe(pipeClient, request.Release());
+ }
+
+ TTabletId GetBSControllerId() {
+ TIntrusivePtr<TDomainsInfo> domains = AppData()->DomainsInfo;
+ TIntrusivePtr<TDomainsInfo::TDomain> domain = domains->Domains.begin()->second;
+ ui32 stateStorageGroup = domains->GetDefaultStateStorageGroup(domain->DomainUid);
+ return MakeBSControllerID(stateStorageGroup);
+ }
+
+ void RequestBSControllerConfig() {
+ TActorId pipeClient = ConnectTabletPipe(GetBSControllerId());
+ THolder<TEvBlobStorage::TEvControllerConfigRequest> request = MakeHolder<TEvBlobStorage::TEvControllerConfigRequest>();
+ request->Record.MutableRequest()->AddCommand()->MutableQueryBaseConfig();
+ SendRequestToPipe(pipeClient, request.Release());
+ }
+
+ void RequestBSControllerInfo() {
+ TActorId pipeClient = ConnectTabletPipe(GetBSControllerId());
+ THolder<TEvBlobStorage::TEvRequestControllerInfo> request = MakeHolder<TEvBlobStorage::TEvRequestControllerInfo>();
+ SendRequestToPipe(pipeClient, request.Release());
+ }
+
+ void RequestBSControllerSelectGroups(THolder<TEvBlobStorage::TEvControllerSelectGroups> request) {
+ TActorId pipeClient = ConnectTabletPipe(GetBSControllerId());
+ SendRequestToPipe(pipeClient, request.Release());
+ }
+
+ void RequestSchemeCacheNavigate(const TString& path) {
+ THolder<NSchemeCache::TSchemeCacheNavigate> request = MakeHolder<NSchemeCache::TSchemeCacheNavigate>();
+ NSchemeCache::TSchemeCacheNavigate::TEntry entry;
+ entry.Path = SplitPath(path);
+ entry.RedirectRequired = false;
+ entry.Operation = NSchemeCache::TSchemeCacheNavigate::EOp::OpPath;
+ request->ResultSet.emplace_back(entry);
+ SendRequest(MakeSchemeCacheID(), new TEvTxProxySchemeCache::TEvNavigateKeySet(request.Release()));
+ }
+
+ void RequestSchemeCacheNavigate(const TPathId& pathId) {
+ THolder<NSchemeCache::TSchemeCacheNavigate> request = MakeHolder<NSchemeCache::TSchemeCacheNavigate>();
+ NSchemeCache::TSchemeCacheNavigate::TEntry entry;
+ entry.TableId.PathId = pathId;
+ entry.RequestType = NSchemeCache::TSchemeCacheNavigate::TEntry::ERequestType::ByTableId;
+ entry.RedirectRequired = false;
+ entry.Operation = NSchemeCache::TSchemeCacheNavigate::EOp::OpPath;
+ request->ResultSet.emplace_back(entry);
+ SendRequest(MakeSchemeCacheID(), new TEvTxProxySchemeCache::TEvNavigateKeySet(request.Release()));
+ }
+
+ void InitConfig(const TCgiParameters& params) {
Followers = FromStringWithDefault(params.Get("followers"), Followers);
- Metrics = FromStringWithDefault(params.Get("metrics"), Metrics);
- WithRetry = FromStringWithDefault(params.Get("with_retry"), WithRetry);
- }
-
- void ClosePipes() {
- for (const auto& [tabletId, pipeInfo] : PipeInfo) {
- if (pipeInfo.PipeClient) {
- NTabletPipe::CloseClient(TBase::SelfId(), pipeInfo.PipeClient);
- }
- }
- PipeInfo.clear();
- }
-
- ui32 FailPipeConnect(TTabletId tabletId) {
- auto itPipeInfo = PipeInfo.find(tabletId);
- if (itPipeInfo != PipeInfo.end()) {
- ui32 requests = itPipeInfo->second.Requests;
- NTabletPipe::CloseClient(TBase::SelfId(), itPipeInfo->second.PipeClient);
- PipeInfo.erase(itPipeInfo);
- return requests;
- }
- return 0;
- }
-
- void RequestDone(ui32 requests = 1) {
- Requests -= requests;
- if (!DelayedRequests.empty()) {
- SendDelayedRequests();
- }
- if (Requests == 0) {
- static_cast<TDerived*>(this)->ReplyAndPassAway();
- }
- }
-
- void Handle(TEvTabletPipe::TEvClientConnected::TPtr& ev) {
- if (ev->Get()->Status != NKikimrProto::OK) {
- ui32 requests = FailPipeConnect(ev->Get()->TabletId);
- RequestDone(requests);
- }
- }
-
- void PassAway() override {
- ClosePipes();
- TBase::PassAway();
- }
-};
-
-}
-}
+ Metrics = FromStringWithDefault(params.Get("metrics"), Metrics);
+ WithRetry = FromStringWithDefault(params.Get("with_retry"), WithRetry);
+ }
+
+ void ClosePipes() {
+ for (const auto& [tabletId, pipeInfo] : PipeInfo) {
+ if (pipeInfo.PipeClient) {
+ NTabletPipe::CloseClient(TBase::SelfId(), pipeInfo.PipeClient);
+ }
+ }
+ PipeInfo.clear();
+ }
+
+ ui32 FailPipeConnect(TTabletId tabletId) {
+ auto itPipeInfo = PipeInfo.find(tabletId);
+ if (itPipeInfo != PipeInfo.end()) {
+ ui32 requests = itPipeInfo->second.Requests;
+ NTabletPipe::CloseClient(TBase::SelfId(), itPipeInfo->second.PipeClient);
+ PipeInfo.erase(itPipeInfo);
+ return requests;
+ }
+ return 0;
+ }
+
+ void RequestDone(ui32 requests = 1) {
+ Requests -= requests;
+ if (!DelayedRequests.empty()) {
+ SendDelayedRequests();
+ }
+ if (Requests == 0) {
+ static_cast<TDerived*>(this)->ReplyAndPassAway();
+ }
+ }
+
+ void Handle(TEvTabletPipe::TEvClientConnected::TPtr& ev) {
+ if (ev->Get()->Status != NKikimrProto::OK) {
+ ui32 requests = FailPipeConnect(ev->Get()->TabletId);
+ RequestDone(requests);
+ }
+ }
+
+ void PassAway() override {
+ ClosePipes();
+ TBase::PassAway();
+ }
+};
+
+}
+}
diff --git a/ydb/core/viewer/json_pqconsumerinfo.h b/ydb/core/viewer/json_pqconsumerinfo.h
index d3249fbe14d..b98dfc26323 100644
--- a/ydb/core/viewer/json_pqconsumerinfo.h
+++ b/ydb/core/viewer/json_pqconsumerinfo.h
@@ -16,7 +16,7 @@ using namespace NActors;
class TJsonPQConsumerInfo : public TActorBootstrapped<TJsonPQConsumerInfo> {
using TBase = TActorBootstrapped<TJsonPQConsumerInfo>;
- IViewer* Viewer;
+ IViewer* Viewer;
NMon::TEvHttpInfo::TPtr Event;
NKikimrClient::TResponse Result;
TJsonSettings JsonSettings;
@@ -25,17 +25,17 @@ class TJsonPQConsumerInfo : public TActorBootstrapped<TJsonPQConsumerInfo> {
TString DC;
ui32 Version = 0;
ui32 Timeout = 0;
- ui32 Requests = 0;
- ui32 Responses = 0;
+ ui32 Requests = 0;
+ ui32 Responses = 0;
public:
static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
return NKikimrServices::TActivity::VIEWER_HANDLER;
}
- TJsonPQConsumerInfo(IViewer* viewer, NMon::TEvHttpInfo::TPtr &ev)
- : Viewer(viewer)
- , Event(ev)
+ TJsonPQConsumerInfo(IViewer* viewer, NMon::TEvHttpInfo::TPtr &ev)
+ : Viewer(viewer)
+ , Event(ev)
{}
void Bootstrap(const TActorContext& ctx) {
@@ -56,21 +56,21 @@ public:
if (pos != TString::npos) {
Topic = Topic.substr(pos + 1);
}
- }
- {
- NKikimrClient::TPersQueueRequest request;
- request.MutableMetaRequest()->MutableCmdGetPartitionStatus()->SetClientId(Client);
- request.MutableMetaRequest()->MutableCmdGetPartitionStatus()->AddTopicRequest()->SetTopic(Topic);
+ }
+ {
+ NKikimrClient::TPersQueueRequest request;
+ request.MutableMetaRequest()->MutableCmdGetPartitionStatus()->SetClientId(Client);
+ request.MutableMetaRequest()->MutableCmdGetPartitionStatus()->AddTopicRequest()->SetTopic(Topic);
ctx.Register(NMsgBusProxy::CreateActorServerPersQueue(ctx.SelfID, request, NMsgBusProxy::CreatePersQueueMetaCacheV2Id(), nullptr));
- ++Requests;
- }
- {
- NKikimrClient::TPersQueueRequest request;
- request.MutableMetaRequest()->MutableCmdGetReadSessionsInfo()->SetClientId(Client);
- request.MutableMetaRequest()->MutableCmdGetReadSessionsInfo()->AddTopic(Topic);
+ ++Requests;
+ }
+ {
+ NKikimrClient::TPersQueueRequest request;
+ request.MutableMetaRequest()->MutableCmdGetReadSessionsInfo()->SetClientId(Client);
+ request.MutableMetaRequest()->MutableCmdGetReadSessionsInfo()->AddTopic(Topic);
ctx.Register(NMsgBusProxy::CreateActorServerPersQueue(ctx.SelfID, request, NMsgBusProxy::CreatePersQueueMetaCacheV2Id(), nullptr));
- ++Requests;
- }
+ ++Requests;
+ }
Become(&TThis::StateRequestedTopicInfo, ctx, TDuration::MilliSeconds(Timeout), new TEvents::TEvWakeup());
}
@@ -86,21 +86,21 @@ public:
}
void Handle(TEvPersQueue::TEvResponse::TPtr &ev, const TActorContext &ctx) {
- Result.MergeFrom(ev->Get()->Record);
- if (++Responses == Requests) {
- ReplyAndDie(ctx);
- }
+ Result.MergeFrom(ev->Get()->Record);
+ if (++Responses == Requests) {
+ ReplyAndDie(ctx);
+ }
}
void ReplyAndDie(const TActorContext &ctx) {
TStringStream json;
- TProtoToJson::ProtoToJson(json, Result.GetMetaResponse(), JsonSettings);
- ctx.Send(Event->Sender, new NMon::TEvHttpInfoRes(Viewer->GetHTTPOKJSON() + json.Str(), 0, NMon::IEvHttpInfoRes::EContentType::Custom));
+ TProtoToJson::ProtoToJson(json, Result.GetMetaResponse(), JsonSettings);
+ ctx.Send(Event->Sender, new NMon::TEvHttpInfoRes(Viewer->GetHTTPOKJSON() + json.Str(), 0, NMon::IEvHttpInfoRes::EContentType::Custom));
Die(ctx);
}
void HandleTimeout(const TActorContext &ctx) {
- ctx.Send(Event->Sender, new NMon::TEvHttpInfoRes(Viewer->GetHTTPGATEWAYTIMEOUT(), 0, NMon::IEvHttpInfoRes::EContentType::Custom));
+ ctx.Send(Event->Sender, new NMon::TEvHttpInfoRes(Viewer->GetHTTPGATEWAYTIMEOUT(), 0, NMon::IEvHttpInfoRes::EContentType::Custom));
Die(ctx);
}
};
@@ -109,7 +109,7 @@ template <>
struct TJsonRequestSchema<TJsonPQConsumerInfo> {
static TString GetSchema() {
TStringStream stream;
- TProtoToJson::ProtoToJsonSchema<NKikimrClient::TPersQueueMetaResponse>(stream);
+ TProtoToJson::ProtoToJsonSchema<NKikimrClient::TPersQueueMetaResponse>(stream);
return stream.Str();
}
};
@@ -117,27 +117,27 @@ struct TJsonRequestSchema<TJsonPQConsumerInfo> {
template <>
struct TJsonRequestParameters<TJsonPQConsumerInfo> {
static TString GetParameters() {
- return R"___([{"name":"topic","in":"query","description":"topic name","required":true,"type":"string"},
- {"name":"dc","in":"query","description":"dc name (required with version >= 3)","required":false,"type":"string", "default":""},
- {"name":"version","in":"query","description":"query version","required":false,"type":"integer", "default":"0"},
- {"name":"client","in":"query","description":"client name","required":true,"type":"string"},
- {"name":"enums","in":"query","description":"convert enums to strings","required":false,"type":"boolean","default":false},
- {"name":"ui64","in":"query","description":"return ui64 as number","required":false,"type":"boolean","default":false},
- {"name":"timeout","in":"query","description":"timeout in ms","required":false,"type":"integer","default":10000}])___";
+ return R"___([{"name":"topic","in":"query","description":"topic name","required":true,"type":"string"},
+ {"name":"dc","in":"query","description":"dc name (required with version >= 3)","required":false,"type":"string", "default":""},
+ {"name":"version","in":"query","description":"query version","required":false,"type":"integer", "default":"0"},
+ {"name":"client","in":"query","description":"client name","required":true,"type":"string"},
+ {"name":"enums","in":"query","description":"convert enums to strings","required":false,"type":"boolean","default":false},
+ {"name":"ui64","in":"query","description":"return ui64 as number","required":false,"type":"boolean","default":false},
+ {"name":"timeout","in":"query","description":"timeout in ms","required":false,"type":"integer","default":10000}])___";
}
};
template <>
struct TJsonRequestSummary<TJsonPQConsumerInfo> {
static TString GetSummary() {
- return "\"Consumer-topic metrics\"";
+ return "\"Consumer-topic metrics\"";
}
};
template <>
struct TJsonRequestDescription<TJsonPQConsumerInfo> {
static TString GetDescription() {
- return "\"Returns consumer-topic metrics\"";
+ return "\"Returns consumer-topic metrics\"";
}
};
diff --git a/ydb/core/viewer/json_query.h b/ydb/core/viewer/json_query.h
index b91ec17ba5d..600d8088e10 100644
--- a/ydb/core/viewer/json_query.h
+++ b/ydb/core/viewer/json_query.h
@@ -1,6 +1,6 @@
-#pragma once
+#pragma once
#include "viewer.h"
-#include <unordered_map>
+#include <unordered_map>
#include <library/cpp/actors/core/actor_bootstrapped.h>
#include <library/cpp/actors/core/interconnect.h>
#include <library/cpp/actors/core/mon.h>
@@ -12,248 +12,248 @@
#include <ydb/core/viewer/json/json.h>
#include <ydb/public/lib/deprecated/kicli/kicli.h>
#include <ydb/public/sdk/cpp/client/ydb_result/result.h>
-
-namespace NKikimr {
-namespace NViewer {
-
-using namespace NActors;
-using ::google::protobuf::FieldDescriptor;
-
-class TJsonQuery : public TActorBootstrapped<TJsonQuery> {
- using TThis = TJsonQuery;
- using TBase = TActorBootstrapped<TJsonQuery>;
- IViewer* Viewer;
- TJsonSettings JsonSettings;
+
+namespace NKikimr {
+namespace NViewer {
+
+using namespace NActors;
+using ::google::protobuf::FieldDescriptor;
+
+class TJsonQuery : public TActorBootstrapped<TJsonQuery> {
+ using TThis = TJsonQuery;
+ using TBase = TActorBootstrapped<TJsonQuery>;
+ IViewer* Viewer;
+ TJsonSettings JsonSettings;
TActorId Initiator;
- NMon::TEvHttpInfo::TPtr Event;
+ NMon::TEvHttpInfo::TPtr Event;
ui32 Timeout = 0;
- TVector<Ydb::ResultSet> ResultSets;
- TString Action;
+ TVector<Ydb::ResultSet> ResultSets;
+ TString Action;
TString Stats;
-
-public:
+
+public:
static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
return NKikimrServices::TActivity::VIEWER_HANDLER;
- }
-
- TJsonQuery(IViewer* viewer, NMon::TEvHttpInfo::TPtr& ev)
- : Viewer(viewer)
- , Initiator(ev->Sender)
- , Event(ev)
- {}
-
- STFUNC(StateWork) {
- switch (ev->GetTypeRewrite()) {
- HFunc(NKqp::TEvKqp::TEvQueryResponse, HandleReply);
- HFunc(NKqp::TEvKqp::TEvProcessResponse, HandleReply);
- HFunc(NKqp::TEvKqp::TEvAbortExecution, HandleReply);
- HFunc(NKqp::TEvKqpExecuter::TEvStreamData, HandleReply);
- HFunc(NKqp::TEvKqpExecuter::TEvStreamProfile, HandleReply);
- HFunc(NKqp::TEvKqpExecuter::TEvExecuterProgress, HandleReply);
-
- CFunc(TEvents::TSystem::Wakeup, HandleTimeout);
-
- default: {
- Cerr << "Unexpected event received in TJsonQuery::StateWork: " << ev->GetTypeRewrite() << Endl;
- }
- }
- }
-
- void Bootstrap(const TActorContext& ctx) {
+ }
+
+ TJsonQuery(IViewer* viewer, NMon::TEvHttpInfo::TPtr& ev)
+ : Viewer(viewer)
+ , Initiator(ev->Sender)
+ , Event(ev)
+ {}
+
+ STFUNC(StateWork) {
+ switch (ev->GetTypeRewrite()) {
+ HFunc(NKqp::TEvKqp::TEvQueryResponse, HandleReply);
+ HFunc(NKqp::TEvKqp::TEvProcessResponse, HandleReply);
+ HFunc(NKqp::TEvKqp::TEvAbortExecution, HandleReply);
+ HFunc(NKqp::TEvKqpExecuter::TEvStreamData, HandleReply);
+ HFunc(NKqp::TEvKqpExecuter::TEvStreamProfile, HandleReply);
+ HFunc(NKqp::TEvKqpExecuter::TEvExecuterProgress, HandleReply);
+
+ CFunc(TEvents::TSystem::Wakeup, HandleTimeout);
+
+ default: {
+ Cerr << "Unexpected event received in TJsonQuery::StateWork: " << ev->GetTypeRewrite() << Endl;
+ }
+ }
+ }
+
+ void Bootstrap(const TActorContext& ctx) {
const auto& params(Event->Get()->Request.GetParams());
- auto event = MakeHolder<NKqp::TEvKqp::TEvQueryRequest>();
- JsonSettings.EnumAsNumbers = !FromStringWithDefault<bool>(params.Get("enums"), false);
- JsonSettings.UI64AsString = !FromStringWithDefault<bool>(params.Get("ui64"), false);
- Timeout = FromStringWithDefault<ui32>(params.Get("timeout"), 60000);
- TString query = params.Get("query");
- TString database = params.Get("database");
+ auto event = MakeHolder<NKqp::TEvKqp::TEvQueryRequest>();
+ JsonSettings.EnumAsNumbers = !FromStringWithDefault<bool>(params.Get("enums"), false);
+ JsonSettings.UI64AsString = !FromStringWithDefault<bool>(params.Get("ui64"), false);
+ Timeout = FromStringWithDefault<ui32>(params.Get("timeout"), 60000);
+ TString query = params.Get("query");
+ TString database = params.Get("database");
Stats = params.Get("stats");
- Action = params.Get("action");
+ Action = params.Get("action");
if (query.empty() && Event->Get()->Request.GetMethod() == HTTP_METHOD_POST) {
TStringBuf content = Event->Get()->Request.GetPostContent();
const THttpHeaders& headers = Event->Get()->Request.GetHeaders();
- auto itContentType = FindIf(headers, [](const auto& header) { return header.Name() == "Content-Type"; });
- if (itContentType != headers.end()) {
- TStringBuf contentTypeHeader = itContentType->Value();
- TStringBuf contentType = contentTypeHeader.NextTok(';');
- if (contentType == "application/json") {
- static NJson::TJsonReaderConfig JsonConfig;
- NJson::TJsonValue requestData;
- bool success = NJson::ReadJsonTree(content, &JsonConfig, &requestData);
- if (success) {
- query = requestData["query"].GetStringSafe({});
- database = requestData["database"].GetStringSafe({});
+ auto itContentType = FindIf(headers, [](const auto& header) { return header.Name() == "Content-Type"; });
+ if (itContentType != headers.end()) {
+ TStringBuf contentTypeHeader = itContentType->Value();
+ TStringBuf contentType = contentTypeHeader.NextTok(';');
+ if (contentType == "application/json") {
+ static NJson::TJsonReaderConfig JsonConfig;
+ NJson::TJsonValue requestData;
+ bool success = NJson::ReadJsonTree(content, &JsonConfig, &requestData);
+ if (success) {
+ query = requestData["query"].GetStringSafe({});
+ database = requestData["database"].GetStringSafe({});
Stats = requestData["stats"].GetStringSafe({});
- Action = requestData["action"].GetStringSafe({});
- }
- }
- }
- }
- if (query.empty()) {
- ReplyAndDie(HTTPBADREQUEST, ctx);
- return;
- }
- NKikimrKqp::TQueryRequest& request = *event->Record.MutableRequest();
- request.SetQuery(query);
+ Action = requestData["action"].GetStringSafe({});
+ }
+ }
+ }
+ }
+ if (query.empty()) {
+ ReplyAndDie(HTTPBADREQUEST, ctx);
+ return;
+ }
+ NKikimrKqp::TQueryRequest& request = *event->Record.MutableRequest();
+ request.SetQuery(query);
if (Action.empty() || Action == "execute-script" || Action == "execute") {
- request.SetAction(NKikimrKqp::QUERY_ACTION_EXECUTE);
+ request.SetAction(NKikimrKqp::QUERY_ACTION_EXECUTE);
request.SetType(NKikimrKqp::QUERY_TYPE_SQL_SCRIPT);
request.SetKeepSession(false);
- } else if (Action == "execute-scan") {
- request.SetAction(NKikimrKqp::QUERY_ACTION_EXECUTE);
- request.SetType(NKikimrKqp::QUERY_TYPE_SQL_SCAN);
- request.SetKeepSession(false);
- } else if (Action == "explain" || Action == "explain-ast") {
- request.SetAction(NKikimrKqp::QUERY_ACTION_EXPLAIN);
- request.SetType(NKikimrKqp::QUERY_TYPE_SQL_DML);
- }
+ } else if (Action == "execute-scan") {
+ request.SetAction(NKikimrKqp::QUERY_ACTION_EXECUTE);
+ request.SetType(NKikimrKqp::QUERY_TYPE_SQL_SCAN);
+ request.SetKeepSession(false);
+ } else if (Action == "explain" || Action == "explain-ast") {
+ request.SetAction(NKikimrKqp::QUERY_ACTION_EXPLAIN);
+ request.SetType(NKikimrKqp::QUERY_TYPE_SQL_DML);
+ }
if (Stats == "profile") {
request.SetStatsMode(NYql::NDqProto::DQ_STATS_MODE_PROFILE);
}
- if (database) {
- request.SetDatabase(database);
- }
- if (!Event->Get()->UserToken.empty()) {
- event->Record.SetUserToken(Event->Get()->UserToken);
- }
- ActorIdToProto(SelfId(), event->Record.MutableRequestActorId());
+ if (database) {
+ request.SetDatabase(database);
+ }
+ if (!Event->Get()->UserToken.empty()) {
+ event->Record.SetUserToken(Event->Get()->UserToken);
+ }
+ ActorIdToProto(SelfId(), event->Record.MutableRequestActorId());
ctx.Send(NKqp::MakeKqpProxyID(ctx.SelfID.NodeId()), event.Release());
-
- Become(&TThis::StateWork, ctx, TDuration::MilliSeconds(Timeout), new TEvents::TEvWakeup());
- }
-
-private:
- static NJson::TJsonValue ColumnPrimitiveValueToJsonValue(NYdb::TValueParser& valueParser) {
- switch (valueParser.GetPrimitiveType()) {
- case NYdb::EPrimitiveType::Bool:
- return valueParser.GetBool();
- case NYdb::EPrimitiveType::Int8:
- return valueParser.GetInt8();
- case NYdb::EPrimitiveType::Uint8:
- return valueParser.GetUint8();
- case NYdb::EPrimitiveType::Int16:
- return valueParser.GetInt16();
- case NYdb::EPrimitiveType::Uint16:
- return valueParser.GetUint16();
- case NYdb::EPrimitiveType::Int32:
- return valueParser.GetInt32();
- case NYdb::EPrimitiveType::Uint32:
- return valueParser.GetUint32();
- case NYdb::EPrimitiveType::Int64:
- return TStringBuilder() << valueParser.GetInt64();
- case NYdb::EPrimitiveType::Uint64:
- return TStringBuilder() << valueParser.GetUint64();
- case NYdb::EPrimitiveType::Float:
- return valueParser.GetFloat();
- case NYdb::EPrimitiveType::Double:
- return valueParser.GetDouble();
- case NYdb::EPrimitiveType::Utf8:
- return valueParser.GetUtf8();
- case NYdb::EPrimitiveType::Date:
- return valueParser.GetDate().ToString();
- case NYdb::EPrimitiveType::Datetime:
- return valueParser.GetDatetime().ToString();
- case NYdb::EPrimitiveType::Timestamp:
- return valueParser.GetTimestamp().ToString();
- case NYdb::EPrimitiveType::Interval:
- return TStringBuilder() << valueParser.GetInterval();
- case NYdb::EPrimitiveType::TzDate:
- return valueParser.GetTzDate();
- case NYdb::EPrimitiveType::TzDatetime:
- return valueParser.GetTzDatetime();
- case NYdb::EPrimitiveType::TzTimestamp:
- return valueParser.GetTzTimestamp();
- case NYdb::EPrimitiveType::String:
- return Base64Encode(valueParser.GetString());
- case NYdb::EPrimitiveType::Yson:
- return valueParser.GetYson();
- case NYdb::EPrimitiveType::Json:
- return valueParser.GetJson();
- case NYdb::EPrimitiveType::JsonDocument:
- return valueParser.GetJsonDocument();
- case NYdb::EPrimitiveType::DyNumber:
- return valueParser.GetDyNumber();
- case NYdb::EPrimitiveType::Uuid:
- return "<uuid not implemented>";
- }
- }
-
- static NJson::TJsonValue ColumnValueToJsonValue(NYdb::TValueParser& valueParser) {
- switch (valueParser.GetKind()) {
- case NYdb::TTypeParser::ETypeKind::Primitive:
- return ColumnPrimitiveValueToJsonValue(valueParser);
-
- case NYdb::TTypeParser::ETypeKind::Optional:
- valueParser.OpenOptional();
+
+ Become(&TThis::StateWork, ctx, TDuration::MilliSeconds(Timeout), new TEvents::TEvWakeup());
+ }
+
+private:
+ static NJson::TJsonValue ColumnPrimitiveValueToJsonValue(NYdb::TValueParser& valueParser) {
+ switch (valueParser.GetPrimitiveType()) {
+ case NYdb::EPrimitiveType::Bool:
+ return valueParser.GetBool();
+ case NYdb::EPrimitiveType::Int8:
+ return valueParser.GetInt8();
+ case NYdb::EPrimitiveType::Uint8:
+ return valueParser.GetUint8();
+ case NYdb::EPrimitiveType::Int16:
+ return valueParser.GetInt16();
+ case NYdb::EPrimitiveType::Uint16:
+ return valueParser.GetUint16();
+ case NYdb::EPrimitiveType::Int32:
+ return valueParser.GetInt32();
+ case NYdb::EPrimitiveType::Uint32:
+ return valueParser.GetUint32();
+ case NYdb::EPrimitiveType::Int64:
+ return TStringBuilder() << valueParser.GetInt64();
+ case NYdb::EPrimitiveType::Uint64:
+ return TStringBuilder() << valueParser.GetUint64();
+ case NYdb::EPrimitiveType::Float:
+ return valueParser.GetFloat();
+ case NYdb::EPrimitiveType::Double:
+ return valueParser.GetDouble();
+ case NYdb::EPrimitiveType::Utf8:
+ return valueParser.GetUtf8();
+ case NYdb::EPrimitiveType::Date:
+ return valueParser.GetDate().ToString();
+ case NYdb::EPrimitiveType::Datetime:
+ return valueParser.GetDatetime().ToString();
+ case NYdb::EPrimitiveType::Timestamp:
+ return valueParser.GetTimestamp().ToString();
+ case NYdb::EPrimitiveType::Interval:
+ return TStringBuilder() << valueParser.GetInterval();
+ case NYdb::EPrimitiveType::TzDate:
+ return valueParser.GetTzDate();
+ case NYdb::EPrimitiveType::TzDatetime:
+ return valueParser.GetTzDatetime();
+ case NYdb::EPrimitiveType::TzTimestamp:
+ return valueParser.GetTzTimestamp();
+ case NYdb::EPrimitiveType::String:
+ return Base64Encode(valueParser.GetString());
+ case NYdb::EPrimitiveType::Yson:
+ return valueParser.GetYson();
+ case NYdb::EPrimitiveType::Json:
+ return valueParser.GetJson();
+ case NYdb::EPrimitiveType::JsonDocument:
+ return valueParser.GetJsonDocument();
+ case NYdb::EPrimitiveType::DyNumber:
+ return valueParser.GetDyNumber();
+ case NYdb::EPrimitiveType::Uuid:
+ return "<uuid not implemented>";
+ }
+ }
+
+ static NJson::TJsonValue ColumnValueToJsonValue(NYdb::TValueParser& valueParser) {
+ switch (valueParser.GetKind()) {
+ case NYdb::TTypeParser::ETypeKind::Primitive:
+ return ColumnPrimitiveValueToJsonValue(valueParser);
+
+ case NYdb::TTypeParser::ETypeKind::Optional:
+ valueParser.OpenOptional();
if (valueParser.IsNull()) {
return NJson::JSON_NULL;
}
switch(valueParser.GetKind()) {
case NYdb::TTypeParser::ETypeKind::Primitive:
- return ColumnPrimitiveValueToJsonValue(valueParser);
+ return ColumnPrimitiveValueToJsonValue(valueParser);
case NYdb::TTypeParser::ETypeKind::Decimal:
return valueParser.GetDecimal().ToString();
default:
return NJson::JSON_UNDEFINED;
- }
-
- default:
- return NJson::JSON_UNDEFINED;
- }
- }
-
- void HandleReply(NKqp::TEvKqp::TEvQueryResponse::TPtr& ev, const TActorContext& ctx) {
- TStringBuilder out;
- NKikimrKqp::TEvQueryResponse& record = ev->Get()->Record.GetRef();
+ }
+
+ default:
+ return NJson::JSON_UNDEFINED;
+ }
+ }
+
+ void HandleReply(NKqp::TEvKqp::TEvQueryResponse::TPtr& ev, const TActorContext& ctx) {
+ TStringBuilder out;
+ NKikimrKqp::TEvQueryResponse& record = ev->Get()->Record.GetRef();
if (record.GetYdbStatus() == Ydb::StatusIds::SUCCESS) {
- const auto& response = record.GetResponse();
- out << Viewer->GetHTTPOKJSON();
+ const auto& response = record.GetResponse();
+ out << Viewer->GetHTTPOKJSON();
if (!Stats.empty()) {
out << "{\"result\":";
}
if (response.ResultsSize() > 0) {
- const auto &result = response.GetResults();
- if (result.empty()) {
- out << "[]";
- } else {
- const auto &first = *result.begin();
-
- if (first.HasType() && first.HasValue()) {
- auto value = NClient::TValue::Create(first.GetValue(), first.GetType());
- auto data = value["Data"];
- if (data.HaveValue()) {
- out << data.GetValueText<NClient::TFormatJSON>({JsonSettings.UI64AsString});
- } else {
- out << "[]";
- }
- } else {
- out << "[]";
- }
- }
- } else if (ResultSets.size() > 0) {
+ const auto &result = response.GetResults();
+ if (result.empty()) {
+ out << "[]";
+ } else {
+ const auto &first = *result.begin();
+
+ if (first.HasType() && first.HasValue()) {
+ auto value = NClient::TValue::Create(first.GetValue(), first.GetType());
+ auto data = value["Data"];
+ if (data.HaveValue()) {
+ out << data.GetValueText<NClient::TFormatJSON>({JsonSettings.UI64AsString});
+ } else {
+ out << "[]";
+ }
+ } else {
+ out << "[]";
+ }
+ }
+ } else if (ResultSets.size() > 0) {
out << "[";
bool comma = false;
- for (auto it = ResultSets.begin(); it != ResultSets.end(); ++it) {
- NYdb::TResultSet resultSet(*it);
- const auto& columnsMeta = resultSet.GetColumnsMeta();
- NYdb::TResultSetParser rsParser(resultSet);
- while (rsParser.TryNextRow()) {
+ for (auto it = ResultSets.begin(); it != ResultSets.end(); ++it) {
+ NYdb::TResultSet resultSet(*it);
+ const auto& columnsMeta = resultSet.GetColumnsMeta();
+ NYdb::TResultSetParser rsParser(resultSet);
+ while (rsParser.TryNextRow()) {
if (comma) {
out << ",";
}
out << "{";
- for (size_t columnNum = 0; columnNum < columnsMeta.size(); ++columnNum) {
- const NYdb::TColumn& columnMeta = columnsMeta[columnNum];
+ for (size_t columnNum = 0; columnNum < columnsMeta.size(); ++columnNum) {
+ const NYdb::TColumn& columnMeta = columnsMeta[columnNum];
out << "\"" << TProtoToJson::EscapeJsonString(columnMeta.Name) << "\":";
out << NJson::WriteJson(ColumnValueToJsonValue(rsParser.ColumnParser(columnNum)), false);
if (columnNum + 1 < columnsMeta.size()) {
out << ",";
}
- }
+ }
out << "}";
comma = true;
- }
- }
+ }
+ }
out << ']';
} else if (response.HasQueryPlan()) {
if (Action == "explain-ast") {
@@ -261,101 +261,101 @@ private:
} else {
out << response.GetQueryPlan();
}
- }
+ }
if (!Stats.empty()) {
out << ",\"stats\":";
TStringStream json;
TProtoToJson::ProtoToJson(json, response.GetQueryStats(), JsonSettings);
out << json.Str() << "}";
}
- } else {
- out << "HTTP/1.1 400 Bad Request\r\nContent-Type: text/plain\r\nConnection: Close\r\n\r\n";
+ } else {
+ out << "HTTP/1.1 400 Bad Request\r\nContent-Type: text/plain\r\nConnection: Close\r\n\r\n";
TStringBuilder err;
for (const auto& queryIssue : record.GetResponse().GetQueryIssues()) {
if (!err.empty()) {
err << '\n';
- }
+ }
if (queryIssue.has_position()) {
err << queryIssue.position().row() << ':' << queryIssue.position().column() << ' ';
}
err << queryIssue.message();
- }
+ }
out << err;
- out << "\r\n";
- }
-
- ReplyAndDie(out, ctx);
- }
-
- void HandleReply(NKqp::TEvKqp::TEvProcessResponse::TPtr& ev, const TActorContext& ctx) {
- Y_UNUSED(ev);
- Y_UNUSED(ctx);
- }
-
- void HandleReply(NKqp::TEvKqp::TEvAbortExecution::TPtr& ev, const TActorContext& ctx) {
- Y_UNUSED(ev);
- Y_UNUSED(ctx);
- }
-
- void HandleReply(NKqp::TEvKqpExecuter::TEvStreamData::TPtr& ev, const TActorContext& ctx) {
- const NKikimrKqp::TEvExecuterStreamData& data(ev->Get()->Record);
-
- ResultSets.emplace_back();
- ResultSets.back() = std::move(data.GetResultSet());
-
- THolder<NKqp::TEvKqpExecuter::TEvStreamDataAck> ack = MakeHolder<NKqp::TEvKqpExecuter::TEvStreamDataAck>();
- ack->Record.SetSeqNo(ev->Get()->Record.GetSeqNo());
- ctx.Send(ev->Sender, ack.Release());
- }
-
- void HandleReply(NKqp::TEvKqpExecuter::TEvStreamProfile::TPtr& ev, const TActorContext& ctx) {
- Y_UNUSED(ev);
- Y_UNUSED(ctx);
- }
-
- void HandleReply(NKqp::TEvKqpExecuter::TEvExecuterProgress::TPtr& ev, const TActorContext& ctx) {
- Y_UNUSED(ev);
- Y_UNUSED(ctx);
- }
-
- void HandleTimeout(const TActorContext& ctx) {
- ReplyAndDie(Viewer->GetHTTPGATEWAYTIMEOUT(), ctx);
- }
-
- void ReplyAndDie(TString data, const TActorContext& ctx) {
- ctx.Send(Initiator, new NMon::TEvHttpInfoRes(std::move(data), 0, NMon::IEvHttpInfoRes::EContentType::Custom));
- Die(ctx);
- }
-};
-
-template <>
-struct TJsonRequestParameters<TJsonQuery> {
- static TString GetParameters() {
- return R"___([{"name":"ui64","in":"query","description":"return ui64 as number","required":false,"type":"boolean"},
- {"name":"query","in":"query","description":"query text","required":true,"type":"string"},
- {"name":"database","in":"query","description":"database name","required":false,"type":"string"},
- {"name":"stats","in":"query","description":"return stats (profile)","required":false,"type":"string"},
- {"name":"action","in":"query","description":"execute method (execute-scan, execute-script, explain, explain-ast)","required":false,"type":"string"},
- {"name":"timeout","in":"query","description":"timeout in ms","required":false,"type":"integer"}])___";
- }
-};
-
-template <>
-struct TJsonRequestSummary<TJsonQuery> {
- static TString GetSummary() {
- return "\"Execute query\"";
- }
-};
-
-template <>
-struct TJsonRequestDescription<TJsonQuery> {
- static TString GetDescription() {
- return "\"Executes database query\"";
- }
-};
-
-
-}
-}
+ out << "\r\n";
+ }
+
+ ReplyAndDie(out, ctx);
+ }
+
+ void HandleReply(NKqp::TEvKqp::TEvProcessResponse::TPtr& ev, const TActorContext& ctx) {
+ Y_UNUSED(ev);
+ Y_UNUSED(ctx);
+ }
+
+ void HandleReply(NKqp::TEvKqp::TEvAbortExecution::TPtr& ev, const TActorContext& ctx) {
+ Y_UNUSED(ev);
+ Y_UNUSED(ctx);
+ }
+
+ void HandleReply(NKqp::TEvKqpExecuter::TEvStreamData::TPtr& ev, const TActorContext& ctx) {
+ const NKikimrKqp::TEvExecuterStreamData& data(ev->Get()->Record);
+
+ ResultSets.emplace_back();
+ ResultSets.back() = std::move(data.GetResultSet());
+
+ THolder<NKqp::TEvKqpExecuter::TEvStreamDataAck> ack = MakeHolder<NKqp::TEvKqpExecuter::TEvStreamDataAck>();
+ ack->Record.SetSeqNo(ev->Get()->Record.GetSeqNo());
+ ctx.Send(ev->Sender, ack.Release());
+ }
+
+ void HandleReply(NKqp::TEvKqpExecuter::TEvStreamProfile::TPtr& ev, const TActorContext& ctx) {
+ Y_UNUSED(ev);
+ Y_UNUSED(ctx);
+ }
+
+ void HandleReply(NKqp::TEvKqpExecuter::TEvExecuterProgress::TPtr& ev, const TActorContext& ctx) {
+ Y_UNUSED(ev);
+ Y_UNUSED(ctx);
+ }
+
+ void HandleTimeout(const TActorContext& ctx) {
+ ReplyAndDie(Viewer->GetHTTPGATEWAYTIMEOUT(), ctx);
+ }
+
+ void ReplyAndDie(TString data, const TActorContext& ctx) {
+ ctx.Send(Initiator, new NMon::TEvHttpInfoRes(std::move(data), 0, NMon::IEvHttpInfoRes::EContentType::Custom));
+ Die(ctx);
+ }
+};
+
+template <>
+struct TJsonRequestParameters<TJsonQuery> {
+ static TString GetParameters() {
+ return R"___([{"name":"ui64","in":"query","description":"return ui64 as number","required":false,"type":"boolean"},
+ {"name":"query","in":"query","description":"query text","required":true,"type":"string"},
+ {"name":"database","in":"query","description":"database name","required":false,"type":"string"},
+ {"name":"stats","in":"query","description":"return stats (profile)","required":false,"type":"string"},
+ {"name":"action","in":"query","description":"execute method (execute-scan, execute-script, explain, explain-ast)","required":false,"type":"string"},
+ {"name":"timeout","in":"query","description":"timeout in ms","required":false,"type":"integer"}])___";
+ }
+};
+
+template <>
+struct TJsonRequestSummary<TJsonQuery> {
+ static TString GetSummary() {
+ return "\"Execute query\"";
+ }
+};
+
+template <>
+struct TJsonRequestDescription<TJsonQuery> {
+ static TString GetDescription() {
+ return "\"Executes database query\"";
+ }
+};
+
+
+}
+}
diff --git a/ydb/core/viewer/json_storage.h b/ydb/core/viewer/json_storage.h
index 52ea0f99aab..76e5d2f5e8b 100644
--- a/ydb/core/viewer/json_storage.h
+++ b/ydb/core/viewer/json_storage.h
@@ -1,5 +1,5 @@
-#pragma once
-#include <unordered_map>
+#pragma once
+#include <unordered_map>
#include <library/cpp/actors/core/actor_bootstrapped.h>
#include <library/cpp/actors/core/interconnect.h>
#include <library/cpp/actors/core/mon.h>
@@ -7,600 +7,600 @@
#include <ydb/core/viewer/json/json.h>
#include <ydb/core/protos/node_whiteboard.pb.h>
#include <ydb/core/viewer/protos/viewer.pb.h>
-#include "viewer.h"
-#include "json_pipe_req.h"
-#include "json_vdiskinfo.h"
-#include "json_pdiskinfo.h"
-
-namespace NKikimr {
-namespace NViewer {
-
-using namespace NActors;
-using namespace NNodeWhiteboard;
-
-using ::google::protobuf::FieldDescriptor;
-
-class TJsonStorage : public TViewerPipeClient<TJsonStorage> {
- using TThis = TJsonStorage;
- using TBase = TViewerPipeClient<TJsonStorage>;
- using TNodeId = ui32;
- IViewer* Viewer;
+#include "viewer.h"
+#include "json_pipe_req.h"
+#include "json_vdiskinfo.h"
+#include "json_pdiskinfo.h"
+
+namespace NKikimr {
+namespace NViewer {
+
+using namespace NActors;
+using namespace NNodeWhiteboard;
+
+using ::google::protobuf::FieldDescriptor;
+
+class TJsonStorage : public TViewerPipeClient<TJsonStorage> {
+ using TThis = TJsonStorage;
+ using TBase = TViewerPipeClient<TJsonStorage>;
+ using TNodeId = ui32;
+ IViewer* Viewer;
TActorId Initiator;
- NMon::TEvHttpInfo::TPtr Event;
- THolder<TEvInterconnect::TEvNodesInfo> NodesInfo;
+ NMon::TEvHttpInfo::TPtr Event;
+ THolder<TEvInterconnect::TEvNodesInfo> NodesInfo;
TMap<ui32, THolder<TEvWhiteboard::TEvVDiskStateResponse>> VDiskInfo;
TMap<ui32, THolder<TEvWhiteboard::TEvPDiskStateResponse>> PDiskInfo;
TMap<ui32, THolder<TEvWhiteboard::TEvBSGroupStateResponse>> BSGroupInfo;
THashMap<TString, THolder<NSchemeShard::TEvSchemeShard::TEvDescribeSchemeResult>> DescribeResult;
- THashMap<TTabletId, THolder<TEvHive::TEvResponseHiveStorageStats>> HiveStorageStats;
- THolder<TEvBlobStorage::TEvControllerConfigResponse> BaseConfig;
-
- struct TStoragePoolInfo {
- TString Kind;
- TSet<TString> Groups;
- NKikimrViewer::EFlag Overall = NKikimrViewer::EFlag::Grey;
- };
-
- THashMap<TString, TStoragePoolInfo> StoragePoolInfo;
- TJsonSettings JsonSettings;
+ THashMap<TTabletId, THolder<TEvHive::TEvResponseHiveStorageStats>> HiveStorageStats;
+ THolder<TEvBlobStorage::TEvControllerConfigResponse> BaseConfig;
+
+ struct TStoragePoolInfo {
+ TString Kind;
+ TSet<TString> Groups;
+ NKikimrViewer::EFlag Overall = NKikimrViewer::EFlag::Grey;
+ };
+
+ THashMap<TString, TStoragePoolInfo> StoragePoolInfo;
+ TJsonSettings JsonSettings;
ui32 Timeout = 0;
- TString FilterTenant;
- THashSet<TString> FilterStoragePools;
- TVector<TString> FilterGroupIds;
- TVector<ui32> FilterNodeIds;
- std::unordered_set<TNodeId> NodeIds;
- bool NeedGroups = true;
- bool NeedDisks = true;
-
- enum class EWith {
- Everything,
- MissingDisks,
- SpaceProblems,
- };
-
- EWith With = EWith::Everything;
-
-public:
+ TString FilterTenant;
+ THashSet<TString> FilterStoragePools;
+ TVector<TString> FilterGroupIds;
+ TVector<ui32> FilterNodeIds;
+ std::unordered_set<TNodeId> NodeIds;
+ bool NeedGroups = true;
+ bool NeedDisks = true;
+
+ enum class EWith {
+ Everything,
+ MissingDisks,
+ SpaceProblems,
+ };
+
+ EWith With = EWith::Everything;
+
+public:
static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
return NKikimrServices::TActivity::VIEWER_HANDLER;
- }
-
- TJsonStorage(IViewer* viewer, NMon::TEvHttpInfo::TPtr& ev)
- : Viewer(viewer)
- , Initiator(ev->Sender)
- , Event(std::move(ev))
- {
- const auto& params(Event->Get()->Request.GetParams());
- JsonSettings.EnumAsNumbers = !FromStringWithDefault<bool>(params.Get("enums"), true);
- JsonSettings.UI64AsString = !FromStringWithDefault<bool>(params.Get("ui64"), false);
- InitConfig(params);
- Timeout = FromStringWithDefault<ui32>(params.Get("timeout"), 10000);
- FilterTenant = params.Get("tenant");
- TString filterStoragePool = params.Get("pool");
- if (!filterStoragePool.empty()) {
- FilterStoragePools.emplace(filterStoragePool);
- }
- SplitIds(params.Get("node_id"), ',', FilterNodeIds);
- SplitIds(params.Get("group_id"), ',', FilterGroupIds);
- Sort(FilterGroupIds);
- NeedGroups = FromStringWithDefault<bool>(params.Get("need_groups"), true);
- NeedDisks = FromStringWithDefault<bool>(params.Get("need_disks"), NeedGroups);
- NeedGroups = Max(NeedGroups, NeedDisks);
- if (params.Get("with") == "missing") {
- With = EWith::MissingDisks;
- } if (params.Get("with") == "space") {
- With = EWith::SpaceProblems;
- }
- }
-
- void Bootstrap() {
- TIntrusivePtr<TDomainsInfo> domains = AppData()->DomainsInfo;
-
- if (FilterTenant.empty()) {
- RequestConsoleListTenants();
- } else {
- RequestSchemeCacheNavigate(FilterTenant);
- }
- std::replace(FilterNodeIds.begin(), FilterNodeIds.end(), (ui32)0, TlsActivationContext->ExecutorThread.ActorSystem->NodeId);
- if (FilterNodeIds.empty()) {
- SendRequest(GetNameserviceActorId(), new TEvInterconnect::TEvListNodes());
- } else {
- for (ui32 nodeId : FilterNodeIds) {
- SendNodeRequests(nodeId);
- }
- if (Requests == 0) {
- ReplyAndPassAway();
- return;
- }
- }
-
- TIntrusivePtr<TDomainsInfo::TDomain> domain = domains->Domains.begin()->second;
- ui64 hiveId = domains->GetHive(domain->DefaultHiveUid);
- if (hiveId != 0) {
- RequestHiveStorageStats(hiveId);
- }
-
- RequestBSControllerConfig();
-
- TBase::Become(&TThis::StateWork, TDuration::MilliSeconds(Timeout), new TEvents::TEvWakeup());
- }
-
- void PassAway() override {
- for (const TNodeId nodeId : NodeIds) {
- Send(TActivationContext::InterconnectProxy(nodeId), new TEvents::TEvUnsubscribe());
- }
- TBase::PassAway();
- }
-
- void SendNodeRequests(ui32 nodeId) {
- if (NodeIds.insert(nodeId).second) {
- TActorId whiteboardServiceId = MakeNodeWhiteboardServiceId(nodeId);
- SendRequest(whiteboardServiceId, new TEvWhiteboard::TEvVDiskStateRequest(), IEventHandle::FlagTrackDelivery | IEventHandle::FlagSubscribeOnSession, nodeId);
- SendRequest(whiteboardServiceId, new TEvWhiteboard::TEvPDiskStateRequest(), IEventHandle::FlagTrackDelivery | IEventHandle::FlagSubscribeOnSession, nodeId);
- SendRequest(whiteboardServiceId, new TEvWhiteboard::TEvBSGroupStateRequest(), IEventHandle::FlagTrackDelivery | IEventHandle::FlagSubscribeOnSession, nodeId);
- }
- }
-
- void Handle(TEvBlobStorage::TEvControllerSelectGroupsResult::TPtr& ev) {
- for (const auto& matchingGroups : ev->Get()->Record.GetMatchingGroups()) {
- for (const auto& group : matchingGroups.GetGroups()) {
- TString storagePoolName = group.GetStoragePoolName();
- StoragePoolInfo[storagePoolName].Groups.emplace(ToString(group.GetGroupID()));
- }
- }
- RequestDone();
- }
-
- void Handle(TEvBlobStorage::TEvControllerConfigResponse::TPtr& ev) {
- const NKikimrBlobStorage::TEvControllerConfigResponse& pbRecord(ev->Get()->Record);
-
- if (pbRecord.HasResponse() && pbRecord.GetResponse().StatusSize() > 0) {
- const NKikimrBlobStorage::TConfigResponse::TStatus& pbStatus(pbRecord.GetResponse().GetStatus(0));
- if (pbStatus.HasBaseConfig()) {
- BaseConfig = ev->Release();
- }
- }
- RequestDone();
- }
-
- void Handle(NConsole::TEvConsole::TEvListTenantsResponse::TPtr& ev) {
- Ydb::Cms::ListDatabasesResult listTenantsResult;
- ev->Get()->Record.GetResponse().operation().result().UnpackTo(&listTenantsResult);
- for (const TString& path : listTenantsResult.paths()) {
- RequestSchemeCacheNavigate(path);
- }
- RequestDone();
- }
-
- void Handle(TEvInterconnect::TEvNodesInfo::TPtr& ev) {
- ui32 maxAllowedNodeId = std::numeric_limits<ui32>::max();
- TIntrusivePtr<TDynamicNameserviceConfig> dynamicNameserviceConfig = AppData()->DynamicNameserviceConfig;
- if (dynamicNameserviceConfig) {
- maxAllowedNodeId = dynamicNameserviceConfig->MaxStaticNodeId;
- }
- NodesInfo = ev->Release();
- for (const auto& ni : NodesInfo->Nodes) {
- if (ni.NodeId <= maxAllowedNodeId) {
- SendNodeRequests(ni.NodeId);
- }
- }
- RequestDone();
- }
-
- void Handle(TEvTxProxySchemeCache::TEvNavigateKeySetResult::TPtr& ev) {
- if (ev->Get()->Request->ResultSet.size() == 1 && ev->Get()->Request->ResultSet.begin()->Status == NSchemeCache::TSchemeCacheNavigate::EStatus::Ok) {
- TString path = CanonizePath(ev->Get()->Request->ResultSet.begin()->Path);
- TIntrusiveConstPtr<TSchemeCacheNavigate::TDomainDescription> domainDescription = ev->Get()->Request->ResultSet.begin()->DomainDescription;
- TIntrusiveConstPtr<NSchemeCache::TDomainInfo> domainInfo = ev->Get()->Request->ResultSet.begin()->DomainInfo;
-
- if (domainInfo != nullptr && domainDescription != nullptr) {
- TTabletId hiveId = domainInfo->Params.GetHive();
- if (hiveId != 0) {
- RequestHiveStorageStats(hiveId);
- }
-
- for (const auto& storagePool : domainDescription->Description.GetStoragePools()) {
- TString storagePoolName = storagePool.GetName();
- if (!FilterTenant.empty()) {
- FilterStoragePools.emplace(storagePoolName);
- }
- StoragePoolInfo[storagePoolName].Kind = storagePool.GetKind();
- THolder<TEvBlobStorage::TEvControllerSelectGroups> request = MakeHolder<TEvBlobStorage::TEvControllerSelectGroups>();
- request->Record.SetReturnAllMatchingGroups(true);
- request->Record.AddGroupParameters()->MutableStoragePoolSpecifier()->SetName(storagePoolName);
- RequestBSControllerSelectGroups(std::move(request));
- }
- }
- }
- RequestDone();
- }
-
- void Handle(TEvHive::TEvResponseHiveStorageStats::TPtr& ev) {
- HiveStorageStats[ev->Cookie] = ev->Release();
- RequestDone();
- }
-
- void Undelivered(TEvents::TEvUndelivered::TPtr& ev) {
- ui32 nodeId = ev.Get()->Cookie;
- switch (ev->Get()->SourceType) {
- case TEvWhiteboard::EvVDiskStateRequest:
- if (VDiskInfo.emplace(nodeId, nullptr).second) {
- RequestDone();
- }
- break;
- case TEvWhiteboard::EvPDiskStateRequest:
- if (PDiskInfo.emplace(nodeId, nullptr).second) {
- RequestDone();
- }
- break;
- case TEvWhiteboard::EvBSGroupStateRequest:
- if (BSGroupInfo.emplace(nodeId, nullptr).second) {
- RequestDone();
- }
- break;
- }
- }
-
- void Disconnected(TEvInterconnect::TEvNodeDisconnected::TPtr& ev) {
- ui32 nodeId = ev->Get()->NodeId;
- if (VDiskInfo.emplace(nodeId, nullptr).second) {
- RequestDone();
- }
- if (PDiskInfo.emplace(nodeId, nullptr).second) {
- RequestDone();
- }
- if (BSGroupInfo.emplace(nodeId, nullptr).second) {
- RequestDone();
- }
- }
-
- void Handle(TEvWhiteboard::TEvVDiskStateResponse::TPtr& ev) {
- ui64 nodeId = ev.Get()->Cookie;
- VDiskInfo[nodeId] = ev->Release();
- RequestDone();
- }
-
- void Handle(TEvWhiteboard::TEvPDiskStateResponse::TPtr& ev) {
- ui64 nodeId = ev.Get()->Cookie;
- PDiskInfo[nodeId] = ev->Release();
- RequestDone();
- }
-
- void Handle(TEvWhiteboard::TEvBSGroupStateResponse::TPtr& ev) {
- for (const auto& info : ev->Get()->Record.GetBSGroupStateInfo()) {
- TString storagePoolName = info.GetStoragePoolName();
- if (storagePoolName.empty()) {
- continue;
- }
- StoragePoolInfo[storagePoolName].Groups.emplace(ToString(info.GetGroupID()));
- }
- ui64 nodeId = ev.Get()->Cookie;
- BSGroupInfo[nodeId] = ev->Release();
- RequestDone();
- }
-
- STATEFN(StateWork) {
- switch (ev->GetTypeRewrite()) {
- hFunc(TEvInterconnect::TEvNodesInfo, Handle);
- hFunc(TEvWhiteboard::TEvVDiskStateResponse, Handle);
- hFunc(TEvWhiteboard::TEvPDiskStateResponse, Handle);
- hFunc(TEvWhiteboard::TEvBSGroupStateResponse, Handle);
- hFunc(NConsole::TEvConsole::TEvListTenantsResponse, Handle);
- hFunc(TEvTxProxySchemeCache::TEvNavigateKeySetResult, Handle);
- hFunc(TEvBlobStorage::TEvControllerSelectGroupsResult, Handle);
- hFunc(TEvBlobStorage::TEvControllerConfigResponse, Handle);
- hFunc(TEvHive::TEvResponseHiveStorageStats, Handle);
- hFunc(TEvents::TEvUndelivered, Undelivered);
- hFunc(TEvInterconnect::TEvNodeDisconnected, Disconnected);
- hFunc(TEvTabletPipe::TEvClientConnected, TBase::Handle);
- cFunc(TEvents::TSystem::Wakeup, HandleTimeout);
- }
- }
-
- NKikimrViewer::TStorageInfo StorageInfo;
- THolder<TEvWhiteboard::TEvBSGroupStateResponse> MergedBSGroupInfo;
- THolder<TEvWhiteboard::TEvVDiskStateResponse> MergedVDiskInfo;
- THolder<TEvWhiteboard::TEvPDiskStateResponse> MergedPDiskInfo;
- TMap<TString, const NKikimrWhiteboard::TBSGroupStateInfo&> BSGroupIndex;
- TMap<TString, NKikimrHive::THiveStorageGroupStats> BSGroupHiveIndex;
+ }
+
+ TJsonStorage(IViewer* viewer, NMon::TEvHttpInfo::TPtr& ev)
+ : Viewer(viewer)
+ , Initiator(ev->Sender)
+ , Event(std::move(ev))
+ {
+ const auto& params(Event->Get()->Request.GetParams());
+ JsonSettings.EnumAsNumbers = !FromStringWithDefault<bool>(params.Get("enums"), true);
+ JsonSettings.UI64AsString = !FromStringWithDefault<bool>(params.Get("ui64"), false);
+ InitConfig(params);
+ Timeout = FromStringWithDefault<ui32>(params.Get("timeout"), 10000);
+ FilterTenant = params.Get("tenant");
+ TString filterStoragePool = params.Get("pool");
+ if (!filterStoragePool.empty()) {
+ FilterStoragePools.emplace(filterStoragePool);
+ }
+ SplitIds(params.Get("node_id"), ',', FilterNodeIds);
+ SplitIds(params.Get("group_id"), ',', FilterGroupIds);
+ Sort(FilterGroupIds);
+ NeedGroups = FromStringWithDefault<bool>(params.Get("need_groups"), true);
+ NeedDisks = FromStringWithDefault<bool>(params.Get("need_disks"), NeedGroups);
+ NeedGroups = Max(NeedGroups, NeedDisks);
+ if (params.Get("with") == "missing") {
+ With = EWith::MissingDisks;
+ } if (params.Get("with") == "space") {
+ With = EWith::SpaceProblems;
+ }
+ }
+
+ void Bootstrap() {
+ TIntrusivePtr<TDomainsInfo> domains = AppData()->DomainsInfo;
+
+ if (FilterTenant.empty()) {
+ RequestConsoleListTenants();
+ } else {
+ RequestSchemeCacheNavigate(FilterTenant);
+ }
+ std::replace(FilterNodeIds.begin(), FilterNodeIds.end(), (ui32)0, TlsActivationContext->ExecutorThread.ActorSystem->NodeId);
+ if (FilterNodeIds.empty()) {
+ SendRequest(GetNameserviceActorId(), new TEvInterconnect::TEvListNodes());
+ } else {
+ for (ui32 nodeId : FilterNodeIds) {
+ SendNodeRequests(nodeId);
+ }
+ if (Requests == 0) {
+ ReplyAndPassAway();
+ return;
+ }
+ }
+
+ TIntrusivePtr<TDomainsInfo::TDomain> domain = domains->Domains.begin()->second;
+ ui64 hiveId = domains->GetHive(domain->DefaultHiveUid);
+ if (hiveId != 0) {
+ RequestHiveStorageStats(hiveId);
+ }
+
+ RequestBSControllerConfig();
+
+ TBase::Become(&TThis::StateWork, TDuration::MilliSeconds(Timeout), new TEvents::TEvWakeup());
+ }
+
+ void PassAway() override {
+ for (const TNodeId nodeId : NodeIds) {
+ Send(TActivationContext::InterconnectProxy(nodeId), new TEvents::TEvUnsubscribe());
+ }
+ TBase::PassAway();
+ }
+
+ void SendNodeRequests(ui32 nodeId) {
+ if (NodeIds.insert(nodeId).second) {
+ TActorId whiteboardServiceId = MakeNodeWhiteboardServiceId(nodeId);
+ SendRequest(whiteboardServiceId, new TEvWhiteboard::TEvVDiskStateRequest(), IEventHandle::FlagTrackDelivery | IEventHandle::FlagSubscribeOnSession, nodeId);
+ SendRequest(whiteboardServiceId, new TEvWhiteboard::TEvPDiskStateRequest(), IEventHandle::FlagTrackDelivery | IEventHandle::FlagSubscribeOnSession, nodeId);
+ SendRequest(whiteboardServiceId, new TEvWhiteboard::TEvBSGroupStateRequest(), IEventHandle::FlagTrackDelivery | IEventHandle::FlagSubscribeOnSession, nodeId);
+ }
+ }
+
+ void Handle(TEvBlobStorage::TEvControllerSelectGroupsResult::TPtr& ev) {
+ for (const auto& matchingGroups : ev->Get()->Record.GetMatchingGroups()) {
+ for (const auto& group : matchingGroups.GetGroups()) {
+ TString storagePoolName = group.GetStoragePoolName();
+ StoragePoolInfo[storagePoolName].Groups.emplace(ToString(group.GetGroupID()));
+ }
+ }
+ RequestDone();
+ }
+
+ void Handle(TEvBlobStorage::TEvControllerConfigResponse::TPtr& ev) {
+ const NKikimrBlobStorage::TEvControllerConfigResponse& pbRecord(ev->Get()->Record);
+
+ if (pbRecord.HasResponse() && pbRecord.GetResponse().StatusSize() > 0) {
+ const NKikimrBlobStorage::TConfigResponse::TStatus& pbStatus(pbRecord.GetResponse().GetStatus(0));
+ if (pbStatus.HasBaseConfig()) {
+ BaseConfig = ev->Release();
+ }
+ }
+ RequestDone();
+ }
+
+ void Handle(NConsole::TEvConsole::TEvListTenantsResponse::TPtr& ev) {
+ Ydb::Cms::ListDatabasesResult listTenantsResult;
+ ev->Get()->Record.GetResponse().operation().result().UnpackTo(&listTenantsResult);
+ for (const TString& path : listTenantsResult.paths()) {
+ RequestSchemeCacheNavigate(path);
+ }
+ RequestDone();
+ }
+
+ void Handle(TEvInterconnect::TEvNodesInfo::TPtr& ev) {
+ ui32 maxAllowedNodeId = std::numeric_limits<ui32>::max();
+ TIntrusivePtr<TDynamicNameserviceConfig> dynamicNameserviceConfig = AppData()->DynamicNameserviceConfig;
+ if (dynamicNameserviceConfig) {
+ maxAllowedNodeId = dynamicNameserviceConfig->MaxStaticNodeId;
+ }
+ NodesInfo = ev->Release();
+ for (const auto& ni : NodesInfo->Nodes) {
+ if (ni.NodeId <= maxAllowedNodeId) {
+ SendNodeRequests(ni.NodeId);
+ }
+ }
+ RequestDone();
+ }
+
+ void Handle(TEvTxProxySchemeCache::TEvNavigateKeySetResult::TPtr& ev) {
+ if (ev->Get()->Request->ResultSet.size() == 1 && ev->Get()->Request->ResultSet.begin()->Status == NSchemeCache::TSchemeCacheNavigate::EStatus::Ok) {
+ TString path = CanonizePath(ev->Get()->Request->ResultSet.begin()->Path);
+ TIntrusiveConstPtr<TSchemeCacheNavigate::TDomainDescription> domainDescription = ev->Get()->Request->ResultSet.begin()->DomainDescription;
+ TIntrusiveConstPtr<NSchemeCache::TDomainInfo> domainInfo = ev->Get()->Request->ResultSet.begin()->DomainInfo;
+
+ if (domainInfo != nullptr && domainDescription != nullptr) {
+ TTabletId hiveId = domainInfo->Params.GetHive();
+ if (hiveId != 0) {
+ RequestHiveStorageStats(hiveId);
+ }
+
+ for (const auto& storagePool : domainDescription->Description.GetStoragePools()) {
+ TString storagePoolName = storagePool.GetName();
+ if (!FilterTenant.empty()) {
+ FilterStoragePools.emplace(storagePoolName);
+ }
+ StoragePoolInfo[storagePoolName].Kind = storagePool.GetKind();
+ THolder<TEvBlobStorage::TEvControllerSelectGroups> request = MakeHolder<TEvBlobStorage::TEvControllerSelectGroups>();
+ request->Record.SetReturnAllMatchingGroups(true);
+ request->Record.AddGroupParameters()->MutableStoragePoolSpecifier()->SetName(storagePoolName);
+ RequestBSControllerSelectGroups(std::move(request));
+ }
+ }
+ }
+ RequestDone();
+ }
+
+ void Handle(TEvHive::TEvResponseHiveStorageStats::TPtr& ev) {
+ HiveStorageStats[ev->Cookie] = ev->Release();
+ RequestDone();
+ }
+
+ void Undelivered(TEvents::TEvUndelivered::TPtr& ev) {
+ ui32 nodeId = ev.Get()->Cookie;
+ switch (ev->Get()->SourceType) {
+ case TEvWhiteboard::EvVDiskStateRequest:
+ if (VDiskInfo.emplace(nodeId, nullptr).second) {
+ RequestDone();
+ }
+ break;
+ case TEvWhiteboard::EvPDiskStateRequest:
+ if (PDiskInfo.emplace(nodeId, nullptr).second) {
+ RequestDone();
+ }
+ break;
+ case TEvWhiteboard::EvBSGroupStateRequest:
+ if (BSGroupInfo.emplace(nodeId, nullptr).second) {
+ RequestDone();
+ }
+ break;
+ }
+ }
+
+ void Disconnected(TEvInterconnect::TEvNodeDisconnected::TPtr& ev) {
+ ui32 nodeId = ev->Get()->NodeId;
+ if (VDiskInfo.emplace(nodeId, nullptr).second) {
+ RequestDone();
+ }
+ if (PDiskInfo.emplace(nodeId, nullptr).second) {
+ RequestDone();
+ }
+ if (BSGroupInfo.emplace(nodeId, nullptr).second) {
+ RequestDone();
+ }
+ }
+
+ void Handle(TEvWhiteboard::TEvVDiskStateResponse::TPtr& ev) {
+ ui64 nodeId = ev.Get()->Cookie;
+ VDiskInfo[nodeId] = ev->Release();
+ RequestDone();
+ }
+
+ void Handle(TEvWhiteboard::TEvPDiskStateResponse::TPtr& ev) {
+ ui64 nodeId = ev.Get()->Cookie;
+ PDiskInfo[nodeId] = ev->Release();
+ RequestDone();
+ }
+
+ void Handle(TEvWhiteboard::TEvBSGroupStateResponse::TPtr& ev) {
+ for (const auto& info : ev->Get()->Record.GetBSGroupStateInfo()) {
+ TString storagePoolName = info.GetStoragePoolName();
+ if (storagePoolName.empty()) {
+ continue;
+ }
+ StoragePoolInfo[storagePoolName].Groups.emplace(ToString(info.GetGroupID()));
+ }
+ ui64 nodeId = ev.Get()->Cookie;
+ BSGroupInfo[nodeId] = ev->Release();
+ RequestDone();
+ }
+
+ STATEFN(StateWork) {
+ switch (ev->GetTypeRewrite()) {
+ hFunc(TEvInterconnect::TEvNodesInfo, Handle);
+ hFunc(TEvWhiteboard::TEvVDiskStateResponse, Handle);
+ hFunc(TEvWhiteboard::TEvPDiskStateResponse, Handle);
+ hFunc(TEvWhiteboard::TEvBSGroupStateResponse, Handle);
+ hFunc(NConsole::TEvConsole::TEvListTenantsResponse, Handle);
+ hFunc(TEvTxProxySchemeCache::TEvNavigateKeySetResult, Handle);
+ hFunc(TEvBlobStorage::TEvControllerSelectGroupsResult, Handle);
+ hFunc(TEvBlobStorage::TEvControllerConfigResponse, Handle);
+ hFunc(TEvHive::TEvResponseHiveStorageStats, Handle);
+ hFunc(TEvents::TEvUndelivered, Undelivered);
+ hFunc(TEvInterconnect::TEvNodeDisconnected, Disconnected);
+ hFunc(TEvTabletPipe::TEvClientConnected, TBase::Handle);
+ cFunc(TEvents::TSystem::Wakeup, HandleTimeout);
+ }
+ }
+
+ NKikimrViewer::TStorageInfo StorageInfo;
+ THolder<TEvWhiteboard::TEvBSGroupStateResponse> MergedBSGroupInfo;
+ THolder<TEvWhiteboard::TEvVDiskStateResponse> MergedVDiskInfo;
+ THolder<TEvWhiteboard::TEvPDiskStateResponse> MergedPDiskInfo;
+ TMap<TString, const NKikimrWhiteboard::TBSGroupStateInfo&> BSGroupIndex;
+ TMap<TString, NKikimrHive::THiveStorageGroupStats> BSGroupHiveIndex;
TMap<NKikimrBlobStorage::TVDiskID, const NKikimrWhiteboard::TVDiskStateInfo&> VDisksIndex;
TMap<std::pair<ui32, ui32>, const NKikimrWhiteboard::TPDiskStateInfo&> PDisksIndex;
- TMap<TString, TString> BSGroupOverall;
- THashSet<TString> BSGroupWithMissingDisks;
- THashSet<TString> BSGroupWithSpaceProblems;
- TMap<NKikimrBlobStorage::TVDiskID, TString> VDisksOverall;
- TMap<std::pair<ui32, ui32>, TString> PDisksOverall;
-
- TList<NKikimrWhiteboard::TPDiskStateInfo> PDisksAppended;
- TList<NKikimrWhiteboard::TVDiskStateInfo> VDisksAppended;
-
- void RemapGroup(IOutputStream& json,
- const ::google::protobuf::Message& protoFrom,
- const TJsonSettings& jsonSettings) {
- const auto& info = static_cast<const NKikimrViewer::TStorageGroupInfo&>(protoFrom);
- TString groupId = info.GetGroupId();
- auto ib = BSGroupIndex.find(groupId);
- if (ib != BSGroupIndex.end()) {
- TProtoToJson::ProtoToJsonInline(json, ib->second, jsonSettings);
- if (auto ih = BSGroupHiveIndex.find(groupId); ih != BSGroupHiveIndex.end()) {
- json << ',';
- TProtoToJson::ProtoToJsonInline(json, ih->second, jsonSettings);
- }
- if (auto io = BSGroupOverall.find(groupId); io != BSGroupOverall.end()) {
- json << ",\"Overall\":\"" << io->second << "\"";
- }
- }
- }
-
+ TMap<TString, TString> BSGroupOverall;
+ THashSet<TString> BSGroupWithMissingDisks;
+ THashSet<TString> BSGroupWithSpaceProblems;
+ TMap<NKikimrBlobStorage::TVDiskID, TString> VDisksOverall;
+ TMap<std::pair<ui32, ui32>, TString> PDisksOverall;
+
+ TList<NKikimrWhiteboard::TPDiskStateInfo> PDisksAppended;
+ TList<NKikimrWhiteboard::TVDiskStateInfo> VDisksAppended;
+
+ void RemapGroup(IOutputStream& json,
+ const ::google::protobuf::Message& protoFrom,
+ const TJsonSettings& jsonSettings) {
+ const auto& info = static_cast<const NKikimrViewer::TStorageGroupInfo&>(protoFrom);
+ TString groupId = info.GetGroupId();
+ auto ib = BSGroupIndex.find(groupId);
+ if (ib != BSGroupIndex.end()) {
+ TProtoToJson::ProtoToJsonInline(json, ib->second, jsonSettings);
+ if (auto ih = BSGroupHiveIndex.find(groupId); ih != BSGroupHiveIndex.end()) {
+ json << ',';
+ TProtoToJson::ProtoToJsonInline(json, ih->second, jsonSettings);
+ }
+ if (auto io = BSGroupOverall.find(groupId); io != BSGroupOverall.end()) {
+ json << ",\"Overall\":\"" << io->second << "\"";
+ }
+ }
+ }
+
void RemapVDisks(IOutputStream& json,
- const ::google::protobuf::Message& protoFrom,
- const TJsonSettings& jsonSettings) {
- NKikimrWhiteboard::EFlag diskSpace = NKikimrWhiteboard::Grey;
- json << "\"VDisks\":[";
- const auto& info = static_cast<const NKikimrWhiteboard::TBSGroupStateInfo&>(protoFrom);
- const auto& vDiskIds = info.GetVDiskIds();
- for (auto iv = vDiskIds.begin(); iv != vDiskIds.end(); ++iv) {
- if (iv != vDiskIds.begin()) {
- json << ',';
- }
- const NKikimrBlobStorage::TVDiskID& vDiskId = *iv;
- auto ie = VDisksIndex.find(vDiskId);
- if (ie != VDisksIndex.end()) {
- json << '{';
- TProtoToJson::ProtoToJsonInline(json, ie->second, jsonSettings);
- if (auto io = VDisksOverall.find(vDiskId); io != VDisksOverall.end()) {
- json << ",\"Overall\":\"" << io->second << "\"";
- }
- json << '}';
- diskSpace = std::max(diskSpace, ie->second.GetDiskSpace());
- } else {
- json << "{\"VDiskId\":";
- TProtoToJson::ProtoToJson(json, vDiskId, jsonSettings);
- json << "}";
- }
- }
- json << ']';
- if (diskSpace != NKikimrWhiteboard::Grey) {
- json << ",\"DiskSpace\":\"";
- json << NKikimrWhiteboard::EFlag_Name(diskSpace);
- json << "\"";
- }
- }
-
+ const ::google::protobuf::Message& protoFrom,
+ const TJsonSettings& jsonSettings) {
+ NKikimrWhiteboard::EFlag diskSpace = NKikimrWhiteboard::Grey;
+ json << "\"VDisks\":[";
+ const auto& info = static_cast<const NKikimrWhiteboard::TBSGroupStateInfo&>(protoFrom);
+ const auto& vDiskIds = info.GetVDiskIds();
+ for (auto iv = vDiskIds.begin(); iv != vDiskIds.end(); ++iv) {
+ if (iv != vDiskIds.begin()) {
+ json << ',';
+ }
+ const NKikimrBlobStorage::TVDiskID& vDiskId = *iv;
+ auto ie = VDisksIndex.find(vDiskId);
+ if (ie != VDisksIndex.end()) {
+ json << '{';
+ TProtoToJson::ProtoToJsonInline(json, ie->second, jsonSettings);
+ if (auto io = VDisksOverall.find(vDiskId); io != VDisksOverall.end()) {
+ json << ",\"Overall\":\"" << io->second << "\"";
+ }
+ json << '}';
+ diskSpace = std::max(diskSpace, ie->second.GetDiskSpace());
+ } else {
+ json << "{\"VDiskId\":";
+ TProtoToJson::ProtoToJson(json, vDiskId, jsonSettings);
+ json << "}";
+ }
+ }
+ json << ']';
+ if (diskSpace != NKikimrWhiteboard::Grey) {
+ json << ",\"DiskSpace\":\"";
+ json << NKikimrWhiteboard::EFlag_Name(diskSpace);
+ json << "\"";
+ }
+ }
+
void RemapPDisk(IOutputStream& json,
- const ::google::protobuf::Message& protoFrom,
- const TJsonSettings& jsonSettings) {
- json << "\"PDisk\":";
- const auto& info = static_cast<const NKikimrWhiteboard::TVDiskStateInfo&>(protoFrom);
- ui32 nodeId = info.GetNodeId();
- ui32 pDiskId = info.GetPDiskId();
- auto ie = PDisksIndex.find(std::make_pair(nodeId, pDiskId));
- if (ie != PDisksIndex.end()) {
- TProtoToJson::ProtoToJson(json, ie->second, jsonSettings);
- if (auto io = PDisksOverall.find(std::make_pair(nodeId, pDiskId)); io != PDisksOverall.end()) {
- json << ",\"Overall\":\"" << io->second << "\"";
- }
- } else {
- json << "{\"PDiskId\":" << pDiskId << ",\"NodeId\":" << nodeId << "}";
- }
- }
-
- void ReplyAndPassAway() {
- TStringStream json;
- MergedBSGroupInfo = MergeWhiteboardResponses(BSGroupInfo, TWhiteboardInfo<TEvWhiteboard::TEvBSGroupStateResponse>::GetDefaultMergeField());
- MergedVDiskInfo = MergeWhiteboardResponses(VDiskInfo, TWhiteboardInfo<TEvWhiteboard::TEvVDiskStateResponse>::GetDefaultMergeField());
- MergedPDiskInfo = MergeWhiteboardResponses(PDiskInfo, TWhiteboardInfo<TEvWhiteboard::TEvPDiskStateResponse>::GetDefaultMergeField());
- for (auto& element : *TWhiteboardInfo<TEvWhiteboard::TEvPDiskStateResponse>::GetElementsField(MergedPDiskInfo.Get())) {
- element.SetStateFlag(GetWhiteboardFlag(GetPDiskStateFlag(element)));
- auto overall = NKikimrViewer::EFlag_Name(GetPDiskOverallFlag(element));
- auto key = TWhiteboardInfo<TEvWhiteboard::TEvPDiskStateResponse>::GetElementKey(element);
- element.ClearOverall();
- PDisksOverall.emplace(key, overall);
- PDisksIndex.emplace(key, element);
- }
- for (auto& element : *TWhiteboardInfo<TEvWhiteboard::TEvVDiskStateResponse>::GetElementsField(MergedVDiskInfo.Get())) {
- auto overall = NKikimrViewer::EFlag_Name(GetVDiskOverallFlag(element));
- auto key = TWhiteboardInfo<TEvWhiteboard::TEvVDiskStateResponse>::GetElementKey(element);
- element.ClearOverall();
- element.ClearStoragePoolName();
- VDisksOverall.emplace(key, overall);
- VDisksIndex.emplace(key, element);
- }
- for (auto& element : *TWhiteboardInfo<TEvWhiteboard::TEvBSGroupStateResponse>::GetElementsField(MergedBSGroupInfo.Get())) {
- auto state = GetBSGroupOverallState(element, VDisksIndex, PDisksIndex);
- auto key = ToString(TWhiteboardInfo<TEvWhiteboard::TEvBSGroupStateResponse>::GetElementKey(element));
- if (state.MissingDisks > 0) {
- BSGroupWithMissingDisks.insert(key);
- }
- if (state.SpaceProblems > 0) {
- BSGroupWithSpaceProblems.insert(key);
- }
- auto& sp = StoragePoolInfo[element.GetStoragePoolName()];
- sp.Overall = Max(sp.Overall, state.Overall);
- element.ClearOverall();
- element.ClearNodeId();
- element.ClearStoragePoolName();
- BSGroupOverall.emplace(key, NKikimrViewer::EFlag_Name(state.Overall));
- BSGroupIndex.emplace(key, element);
- }
-
- if (BaseConfig) {
- const NKikimrBlobStorage::TEvControllerConfigResponse& pbRecord(BaseConfig->Record);
- const NKikimrBlobStorage::TConfigResponse::TStatus& pbStatus(pbRecord.GetResponse().GetStatus(0));
- const NKikimrBlobStorage::TBaseConfig& pbConfig(pbStatus.GetBaseConfig());
- for (const NKikimrBlobStorage::TBaseConfig::TPDisk& pDisk : pbConfig.GetPDisk()) {
- std::pair<ui32, ui32> pDiskKey(pDisk.GetNodeId(), pDisk.GetPDiskId());
- auto itPDisk = PDisksIndex.find(pDiskKey);
- if (itPDisk == PDisksIndex.end()) {
- PDisksAppended.emplace_back();
- NKikimrWhiteboard::TPDiskStateInfo& pbPDisk = PDisksAppended.back();
- itPDisk = PDisksIndex.emplace(pDiskKey, pbPDisk).first;
- pbPDisk.SetNodeId(pDisk.GetNodeId());
- pbPDisk.SetPDiskId(pDisk.GetPDiskId());
- pbPDisk.SetPath(pDisk.GetPath());
- pbPDisk.SetGuid(pDisk.GetGuid());
- pbPDisk.SetCategory(static_cast<ui64>(pDisk.GetType()));
- pbPDisk.SetTotalSize(pDisk.GetPDiskMetrics().GetTotalSize());
- pbPDisk.SetAvailableSize(pDisk.GetPDiskMetrics().GetAvailableSize());
- }
- }
- for (const NKikimrBlobStorage::TBaseConfig::TVSlot& vDisk : pbConfig.GetVSlot()) {
- NKikimrBlobStorage::TVDiskID vDiskKey;
- vDiskKey.SetGroupID(vDisk.GetGroupId());
- vDiskKey.SetGroupGeneration(vDisk.GetGroupGeneration());
- vDiskKey.SetRing(vDisk.GetFailRealmIdx());
- vDiskKey.SetDomain(vDisk.GetFailDomainIdx());
- vDiskKey.SetVDisk(vDisk.GetVDiskIdx());
-
- auto itVDisk = VDisksIndex.find(vDiskKey);
- if (itVDisk == VDisksIndex.end()) {
- VDisksAppended.emplace_back();
- NKikimrWhiteboard::TVDiskStateInfo& pbVDisk = VDisksAppended.back();
- itVDisk = VDisksIndex.emplace(vDiskKey, pbVDisk).first;
- pbVDisk.MutableVDiskId()->CopyFrom(vDiskKey);
- pbVDisk.SetNodeId(vDisk.GetVSlotId().GetNodeId());
- pbVDisk.SetPDiskId(vDisk.GetVSlotId().GetPDiskId());
- pbVDisk.SetAllocatedSize(vDisk.GetVDiskMetrics().GetAllocatedSize());
- }
- }
- }
-
- for (const auto& [hiveId, hiveStats] : HiveStorageStats) {
- for (auto& pbPool : *hiveStats->Record.MutablePools()) {
- for (auto& pbGroup : *pbPool.MutableGroups()) {
- TString groupId = ToString(pbGroup.GetGroupID());
- NKikimrHive::THiveStorageGroupStats& stats = BSGroupHiveIndex[groupId];
- stats.SetAcquiredUnits(stats.GetAcquiredUnits() + pbGroup.GetAcquiredUnits());
- stats.SetAcquiredIOPS(stats.GetAcquiredIOPS() + pbGroup.GetAcquiredIOPS());
- stats.SetAcquiredThroughput(stats.GetAcquiredThroughput() + pbGroup.GetAcquiredThroughput());
- stats.SetAcquiredSize(stats.GetAcquiredSize() + pbGroup.GetAcquiredSize());
- stats.SetMaximumIOPS(stats.GetMaximumIOPS() + pbGroup.GetMaximumIOPS());
- stats.SetMaximumThroughput(stats.GetMaximumThroughput() + pbGroup.GetMaximumThroughput());
- stats.SetMaximumSize(stats.GetMaximumSize() + pbGroup.GetMaximumSize());
- }
- }
- }
- for (const auto& [poolName, poolInfo] : StoragePoolInfo) {
- if (!FilterStoragePools.empty() && FilterStoragePools.count(poolName) == 0) {
- continue;
- }
- NKikimrViewer::TStoragePoolInfo* pool = StorageInfo.AddStoragePools();
- for (TString groupId : poolInfo.Groups) {
- if (!FilterGroupIds.empty() && !BinarySearch(FilterGroupIds.begin(), FilterGroupIds.end(), groupId)) {
- continue;
- }
- switch (With) {
- case EWith::MissingDisks:
- if (BSGroupWithMissingDisks.count(groupId) == 0) {
- continue;
- }
- break;
- case EWith::SpaceProblems:
- if (BSGroupWithSpaceProblems.count(groupId) == 0) {
- continue;
- }
- break;
- case EWith::Everything:
- break;
- }
- pool->AddGroups()->SetGroupId(groupId);
- auto itHiveGroup = BSGroupHiveIndex.find(groupId);
- if (itHiveGroup != BSGroupHiveIndex.end()) {
- pool->SetAcquiredUnits(pool->GetAcquiredUnits() + itHiveGroup->second.GetAcquiredUnits());
- pool->SetAcquiredIOPS(pool->GetAcquiredIOPS() + itHiveGroup->second.GetAcquiredIOPS());
- pool->SetAcquiredThroughput(pool->GetAcquiredThroughput() + itHiveGroup->second.GetAcquiredThroughput());
- pool->SetAcquiredSize(pool->GetAcquiredSize() + itHiveGroup->second.GetAcquiredSize());
- pool->SetMaximumIOPS(pool->GetMaximumIOPS() + itHiveGroup->second.GetMaximumIOPS());
- pool->SetMaximumThroughput(pool->GetMaximumThroughput() + itHiveGroup->second.GetMaximumThroughput());
- pool->SetMaximumSize(pool->GetMaximumSize() + itHiveGroup->second.GetMaximumSize());
- }
- }
- if (pool->GroupsSize() == 0) {
- StorageInfo.MutableStoragePools()->RemoveLast();
- continue;
- }
- if (!poolName.empty()) {
- pool->SetName(poolName);
- }
- if (!poolInfo.Kind.empty()) {
- pool->SetKind(poolInfo.Kind);
- }
- pool->SetOverall(poolInfo.Overall);
- }
-
- const FieldDescriptor* field;
- if (NeedGroups) {
- field = NKikimrViewer::TStorageGroupInfo::descriptor()->FindFieldByName("GroupId");
- JsonSettings.FieldRemapper[field] = [this](
- IOutputStream& json,
- const ::google::protobuf::Message& protoFrom,
- const TJsonSettings& jsonSettings) -> void {
- RemapGroup(json, protoFrom, jsonSettings);
- };
- }
- if (NeedDisks) {
- field = NKikimrWhiteboard::TBSGroupStateInfo::descriptor()->FindFieldByName("VDiskIds");
- JsonSettings.FieldRemapper[field] = [this](
- IOutputStream& json,
- const ::google::protobuf::Message& protoFrom,
- const TJsonSettings& jsonSettings) -> void {
- RemapVDisks(json, protoFrom, jsonSettings);
- };
- field = NKikimrWhiteboard::TVDiskStateInfo::descriptor()->FindFieldByName("PDiskId");
- JsonSettings.FieldRemapper[field] = [this](
- IOutputStream& json,
- const ::google::protobuf::Message& protoFrom,
- const TJsonSettings& jsonSettings) -> void {
- RemapPDisk(json, protoFrom, jsonSettings);
- };
- }
- TProtoToJson::ProtoToJson(json, StorageInfo, JsonSettings);
- Send(Initiator, new NMon::TEvHttpInfoRes(Viewer->GetHTTPOKJSON() + json.Str(), 0, NMon::IEvHttpInfoRes::EContentType::Custom));
- PassAway();
- }
-
- void HandleTimeout() {
- ReplyAndPassAway();
- }
-};
-
-template <>
-struct TJsonRequestSchema<TJsonStorage> {
+ const ::google::protobuf::Message& protoFrom,
+ const TJsonSettings& jsonSettings) {
+ json << "\"PDisk\":";
+ const auto& info = static_cast<const NKikimrWhiteboard::TVDiskStateInfo&>(protoFrom);
+ ui32 nodeId = info.GetNodeId();
+ ui32 pDiskId = info.GetPDiskId();
+ auto ie = PDisksIndex.find(std::make_pair(nodeId, pDiskId));
+ if (ie != PDisksIndex.end()) {
+ TProtoToJson::ProtoToJson(json, ie->second, jsonSettings);
+ if (auto io = PDisksOverall.find(std::make_pair(nodeId, pDiskId)); io != PDisksOverall.end()) {
+ json << ",\"Overall\":\"" << io->second << "\"";
+ }
+ } else {
+ json << "{\"PDiskId\":" << pDiskId << ",\"NodeId\":" << nodeId << "}";
+ }
+ }
+
+ void ReplyAndPassAway() {
+ TStringStream json;
+ MergedBSGroupInfo = MergeWhiteboardResponses(BSGroupInfo, TWhiteboardInfo<TEvWhiteboard::TEvBSGroupStateResponse>::GetDefaultMergeField());
+ MergedVDiskInfo = MergeWhiteboardResponses(VDiskInfo, TWhiteboardInfo<TEvWhiteboard::TEvVDiskStateResponse>::GetDefaultMergeField());
+ MergedPDiskInfo = MergeWhiteboardResponses(PDiskInfo, TWhiteboardInfo<TEvWhiteboard::TEvPDiskStateResponse>::GetDefaultMergeField());
+ for (auto& element : *TWhiteboardInfo<TEvWhiteboard::TEvPDiskStateResponse>::GetElementsField(MergedPDiskInfo.Get())) {
+ element.SetStateFlag(GetWhiteboardFlag(GetPDiskStateFlag(element)));
+ auto overall = NKikimrViewer::EFlag_Name(GetPDiskOverallFlag(element));
+ auto key = TWhiteboardInfo<TEvWhiteboard::TEvPDiskStateResponse>::GetElementKey(element);
+ element.ClearOverall();
+ PDisksOverall.emplace(key, overall);
+ PDisksIndex.emplace(key, element);
+ }
+ for (auto& element : *TWhiteboardInfo<TEvWhiteboard::TEvVDiskStateResponse>::GetElementsField(MergedVDiskInfo.Get())) {
+ auto overall = NKikimrViewer::EFlag_Name(GetVDiskOverallFlag(element));
+ auto key = TWhiteboardInfo<TEvWhiteboard::TEvVDiskStateResponse>::GetElementKey(element);
+ element.ClearOverall();
+ element.ClearStoragePoolName();
+ VDisksOverall.emplace(key, overall);
+ VDisksIndex.emplace(key, element);
+ }
+ for (auto& element : *TWhiteboardInfo<TEvWhiteboard::TEvBSGroupStateResponse>::GetElementsField(MergedBSGroupInfo.Get())) {
+ auto state = GetBSGroupOverallState(element, VDisksIndex, PDisksIndex);
+ auto key = ToString(TWhiteboardInfo<TEvWhiteboard::TEvBSGroupStateResponse>::GetElementKey(element));
+ if (state.MissingDisks > 0) {
+ BSGroupWithMissingDisks.insert(key);
+ }
+ if (state.SpaceProblems > 0) {
+ BSGroupWithSpaceProblems.insert(key);
+ }
+ auto& sp = StoragePoolInfo[element.GetStoragePoolName()];
+ sp.Overall = Max(sp.Overall, state.Overall);
+ element.ClearOverall();
+ element.ClearNodeId();
+ element.ClearStoragePoolName();
+ BSGroupOverall.emplace(key, NKikimrViewer::EFlag_Name(state.Overall));
+ BSGroupIndex.emplace(key, element);
+ }
+
+ if (BaseConfig) {
+ const NKikimrBlobStorage::TEvControllerConfigResponse& pbRecord(BaseConfig->Record);
+ const NKikimrBlobStorage::TConfigResponse::TStatus& pbStatus(pbRecord.GetResponse().GetStatus(0));
+ const NKikimrBlobStorage::TBaseConfig& pbConfig(pbStatus.GetBaseConfig());
+ for (const NKikimrBlobStorage::TBaseConfig::TPDisk& pDisk : pbConfig.GetPDisk()) {
+ std::pair<ui32, ui32> pDiskKey(pDisk.GetNodeId(), pDisk.GetPDiskId());
+ auto itPDisk = PDisksIndex.find(pDiskKey);
+ if (itPDisk == PDisksIndex.end()) {
+ PDisksAppended.emplace_back();
+ NKikimrWhiteboard::TPDiskStateInfo& pbPDisk = PDisksAppended.back();
+ itPDisk = PDisksIndex.emplace(pDiskKey, pbPDisk).first;
+ pbPDisk.SetNodeId(pDisk.GetNodeId());
+ pbPDisk.SetPDiskId(pDisk.GetPDiskId());
+ pbPDisk.SetPath(pDisk.GetPath());
+ pbPDisk.SetGuid(pDisk.GetGuid());
+ pbPDisk.SetCategory(static_cast<ui64>(pDisk.GetType()));
+ pbPDisk.SetTotalSize(pDisk.GetPDiskMetrics().GetTotalSize());
+ pbPDisk.SetAvailableSize(pDisk.GetPDiskMetrics().GetAvailableSize());
+ }
+ }
+ for (const NKikimrBlobStorage::TBaseConfig::TVSlot& vDisk : pbConfig.GetVSlot()) {
+ NKikimrBlobStorage::TVDiskID vDiskKey;
+ vDiskKey.SetGroupID(vDisk.GetGroupId());
+ vDiskKey.SetGroupGeneration(vDisk.GetGroupGeneration());
+ vDiskKey.SetRing(vDisk.GetFailRealmIdx());
+ vDiskKey.SetDomain(vDisk.GetFailDomainIdx());
+ vDiskKey.SetVDisk(vDisk.GetVDiskIdx());
+
+ auto itVDisk = VDisksIndex.find(vDiskKey);
+ if (itVDisk == VDisksIndex.end()) {
+ VDisksAppended.emplace_back();
+ NKikimrWhiteboard::TVDiskStateInfo& pbVDisk = VDisksAppended.back();
+ itVDisk = VDisksIndex.emplace(vDiskKey, pbVDisk).first;
+ pbVDisk.MutableVDiskId()->CopyFrom(vDiskKey);
+ pbVDisk.SetNodeId(vDisk.GetVSlotId().GetNodeId());
+ pbVDisk.SetPDiskId(vDisk.GetVSlotId().GetPDiskId());
+ pbVDisk.SetAllocatedSize(vDisk.GetVDiskMetrics().GetAllocatedSize());
+ }
+ }
+ }
+
+ for (const auto& [hiveId, hiveStats] : HiveStorageStats) {
+ for (auto& pbPool : *hiveStats->Record.MutablePools()) {
+ for (auto& pbGroup : *pbPool.MutableGroups()) {
+ TString groupId = ToString(pbGroup.GetGroupID());
+ NKikimrHive::THiveStorageGroupStats& stats = BSGroupHiveIndex[groupId];
+ stats.SetAcquiredUnits(stats.GetAcquiredUnits() + pbGroup.GetAcquiredUnits());
+ stats.SetAcquiredIOPS(stats.GetAcquiredIOPS() + pbGroup.GetAcquiredIOPS());
+ stats.SetAcquiredThroughput(stats.GetAcquiredThroughput() + pbGroup.GetAcquiredThroughput());
+ stats.SetAcquiredSize(stats.GetAcquiredSize() + pbGroup.GetAcquiredSize());
+ stats.SetMaximumIOPS(stats.GetMaximumIOPS() + pbGroup.GetMaximumIOPS());
+ stats.SetMaximumThroughput(stats.GetMaximumThroughput() + pbGroup.GetMaximumThroughput());
+ stats.SetMaximumSize(stats.GetMaximumSize() + pbGroup.GetMaximumSize());
+ }
+ }
+ }
+ for (const auto& [poolName, poolInfo] : StoragePoolInfo) {
+ if (!FilterStoragePools.empty() && FilterStoragePools.count(poolName) == 0) {
+ continue;
+ }
+ NKikimrViewer::TStoragePoolInfo* pool = StorageInfo.AddStoragePools();
+ for (TString groupId : poolInfo.Groups) {
+ if (!FilterGroupIds.empty() && !BinarySearch(FilterGroupIds.begin(), FilterGroupIds.end(), groupId)) {
+ continue;
+ }
+ switch (With) {
+ case EWith::MissingDisks:
+ if (BSGroupWithMissingDisks.count(groupId) == 0) {
+ continue;
+ }
+ break;
+ case EWith::SpaceProblems:
+ if (BSGroupWithSpaceProblems.count(groupId) == 0) {
+ continue;
+ }
+ break;
+ case EWith::Everything:
+ break;
+ }
+ pool->AddGroups()->SetGroupId(groupId);
+ auto itHiveGroup = BSGroupHiveIndex.find(groupId);
+ if (itHiveGroup != BSGroupHiveIndex.end()) {
+ pool->SetAcquiredUnits(pool->GetAcquiredUnits() + itHiveGroup->second.GetAcquiredUnits());
+ pool->SetAcquiredIOPS(pool->GetAcquiredIOPS() + itHiveGroup->second.GetAcquiredIOPS());
+ pool->SetAcquiredThroughput(pool->GetAcquiredThroughput() + itHiveGroup->second.GetAcquiredThroughput());
+ pool->SetAcquiredSize(pool->GetAcquiredSize() + itHiveGroup->second.GetAcquiredSize());
+ pool->SetMaximumIOPS(pool->GetMaximumIOPS() + itHiveGroup->second.GetMaximumIOPS());
+ pool->SetMaximumThroughput(pool->GetMaximumThroughput() + itHiveGroup->second.GetMaximumThroughput());
+ pool->SetMaximumSize(pool->GetMaximumSize() + itHiveGroup->second.GetMaximumSize());
+ }
+ }
+ if (pool->GroupsSize() == 0) {
+ StorageInfo.MutableStoragePools()->RemoveLast();
+ continue;
+ }
+ if (!poolName.empty()) {
+ pool->SetName(poolName);
+ }
+ if (!poolInfo.Kind.empty()) {
+ pool->SetKind(poolInfo.Kind);
+ }
+ pool->SetOverall(poolInfo.Overall);
+ }
+
+ const FieldDescriptor* field;
+ if (NeedGroups) {
+ field = NKikimrViewer::TStorageGroupInfo::descriptor()->FindFieldByName("GroupId");
+ JsonSettings.FieldRemapper[field] = [this](
+ IOutputStream& json,
+ const ::google::protobuf::Message& protoFrom,
+ const TJsonSettings& jsonSettings) -> void {
+ RemapGroup(json, protoFrom, jsonSettings);
+ };
+ }
+ if (NeedDisks) {
+ field = NKikimrWhiteboard::TBSGroupStateInfo::descriptor()->FindFieldByName("VDiskIds");
+ JsonSettings.FieldRemapper[field] = [this](
+ IOutputStream& json,
+ const ::google::protobuf::Message& protoFrom,
+ const TJsonSettings& jsonSettings) -> void {
+ RemapVDisks(json, protoFrom, jsonSettings);
+ };
+ field = NKikimrWhiteboard::TVDiskStateInfo::descriptor()->FindFieldByName("PDiskId");
+ JsonSettings.FieldRemapper[field] = [this](
+ IOutputStream& json,
+ const ::google::protobuf::Message& protoFrom,
+ const TJsonSettings& jsonSettings) -> void {
+ RemapPDisk(json, protoFrom, jsonSettings);
+ };
+ }
+ TProtoToJson::ProtoToJson(json, StorageInfo, JsonSettings);
+ Send(Initiator, new NMon::TEvHttpInfoRes(Viewer->GetHTTPOKJSON() + json.Str(), 0, NMon::IEvHttpInfoRes::EContentType::Custom));
+ PassAway();
+ }
+
+ void HandleTimeout() {
+ ReplyAndPassAway();
+ }
+};
+
+template <>
+struct TJsonRequestSchema<TJsonStorage> {
static TString GetSchema() {
- TStringStream stream;
- TProtoToJson::ProtoToJsonSchema<NKikimrViewer::TStorageInfo>(stream);
- return stream.Str();
- }
-};
-
-template <>
-struct TJsonRequestParameters<TJsonStorage> {
+ TStringStream stream;
+ TProtoToJson::ProtoToJsonSchema<NKikimrViewer::TStorageInfo>(stream);
+ return stream.Str();
+ }
+};
+
+template <>
+struct TJsonRequestParameters<TJsonStorage> {
static TString GetParameters() {
- return R"___([{"name":"enums","in":"query","description":"convert enums to strings","required":false,"type":"boolean"},
- {"name":"ui64","in":"query","description":"return ui64 as number","required":false,"type":"boolean"},
- {"name":"tenant","in":"query","description":"tenant name","required":false,"type":"string"},
- {"name":"pool","in":"query","description":"storage pool name","required":false,"type":"string"},
- {"name":"group_id","in":"query","description":"group id","required":false,"type":"integer"},
- {"name":"need_groups","in":"query","description":"return groups information","required":false,"type":"boolean","default":true},
- {"name":"need_disks","in":"query","description":"return disks information","required":false,"type":"boolean","default":true},
- {"name":"with","in":"query","description":"filter groups by missing or space","required":false,"type":"string"},
- {"name":"timeout","in":"query","description":"timeout in ms","required":false,"type":"integer"}])___";
- }
-};
-
-template <>
-struct TJsonRequestSummary<TJsonStorage> {
+ return R"___([{"name":"enums","in":"query","description":"convert enums to strings","required":false,"type":"boolean"},
+ {"name":"ui64","in":"query","description":"return ui64 as number","required":false,"type":"boolean"},
+ {"name":"tenant","in":"query","description":"tenant name","required":false,"type":"string"},
+ {"name":"pool","in":"query","description":"storage pool name","required":false,"type":"string"},
+ {"name":"group_id","in":"query","description":"group id","required":false,"type":"integer"},
+ {"name":"need_groups","in":"query","description":"return groups information","required":false,"type":"boolean","default":true},
+ {"name":"need_disks","in":"query","description":"return disks information","required":false,"type":"boolean","default":true},
+ {"name":"with","in":"query","description":"filter groups by missing or space","required":false,"type":"string"},
+ {"name":"timeout","in":"query","description":"timeout in ms","required":false,"type":"integer"}])___";
+ }
+};
+
+template <>
+struct TJsonRequestSummary<TJsonStorage> {
static TString GetSummary() {
- return "\"Storage information\"";
- }
-};
-
-template <>
-struct TJsonRequestDescription<TJsonStorage> {
+ return "\"Storage information\"";
+ }
+};
+
+template <>
+struct TJsonRequestDescription<TJsonStorage> {
static TString GetDescription() {
- return "\"Returns information about storage\"";
- }
-};
-
-}
-}
+ return "\"Returns information about storage\"";
+ }
+};
+
+}
+}
diff --git a/ydb/core/viewer/json_sysinfo.h b/ydb/core/viewer/json_sysinfo.h
index 32f5cd1bebb..05a477c2df2 100644
--- a/ydb/core/viewer/json_sysinfo.h
+++ b/ydb/core/viewer/json_sysinfo.h
@@ -1,72 +1,72 @@
-#pragma once
+#pragma once
#include <library/cpp/actors/core/actor_bootstrapped.h>
#include <library/cpp/actors/core/interconnect.h>
#include <library/cpp/actors/core/mon.h>
#include <ydb/core/protos/services.pb.h>
#include <ydb/core/node_whiteboard/node_whiteboard.h>
-#include "json_wb_req.h"
-
-namespace NKikimr {
-namespace NViewer {
-
-template <>
-class TWhiteboardMerger<TEvWhiteboard::TEvSystemStateResponse> {
-public:
- static THolder<TEvWhiteboard::TEvSystemStateResponse> MergeResponses(TMap<ui32, THolder<TEvWhiteboard::TEvSystemStateResponse>>& responses, const TString&) {
+#include "json_wb_req.h"
+
+namespace NKikimr {
+namespace NViewer {
+
+template <>
+class TWhiteboardMerger<TEvWhiteboard::TEvSystemStateResponse> {
+public:
+ static THolder<TEvWhiteboard::TEvSystemStateResponse> MergeResponses(TMap<ui32, THolder<TEvWhiteboard::TEvSystemStateResponse>>& responses, const TString&) {
THolder<TEvWhiteboard::TEvSystemStateResponse> result = MakeHolder<TEvWhiteboard::TEvSystemStateResponse>();
- ui64 minResponseTime = 0;
- auto* field = result->Record.MutableSystemStateInfo();
- field->Reserve(responses.size());
- for (auto it = responses.begin(); it != responses.end(); ++it) {
- if (it->second != nullptr && it->second->Record.SystemStateInfoSize() > 0) {
- auto* element = field->Add();
- element->Swap(it->second->Record.MutableSystemStateInfo(0));
- element->SetNodeId(it->first);
- if (minResponseTime == 0 || it->second->Record.GetResponseTime() < minResponseTime) {
- minResponseTime = it->second->Record.GetResponseTime();
- }
- }
- }
- result->Record.SetResponseTime(minResponseTime);
- return result;
- }
-};
-
-template <>
-struct TWhiteboardInfo<TEvWhiteboard::TEvSystemStateResponse> {
- using TResponseType = TEvWhiteboard::TEvSystemStateResponse;
- using TElementType = NKikimrWhiteboard::TSystemStateInfo;
-
- static constexpr bool StaticNodesOnly = false;
-
- static ::google::protobuf::RepeatedPtrField<TElementType>* GetElementsField(TResponseType* response) {
- return response->Record.MutableSystemStateInfo();
- }
-
- static TString GetDefaultMergeField() {
- return "NodeId";
- }
-
- static THolder<TResponseType> MergeResponses(TMap<ui32, THolder<TResponseType>>& responses, const TString& fields = GetDefaultMergeField()) {
- return TWhiteboardMerger<TResponseType>::MergeResponses(responses, fields);
- }
-};
-
-using TJsonSysInfo = TJsonWhiteboardRequest<TEvWhiteboard::TEvSystemStateRequest, TEvWhiteboard::TEvSystemStateResponse>;
-
-template <>
-struct TJsonRequestSummary<TJsonSysInfo> {
+ ui64 minResponseTime = 0;
+ auto* field = result->Record.MutableSystemStateInfo();
+ field->Reserve(responses.size());
+ for (auto it = responses.begin(); it != responses.end(); ++it) {
+ if (it->second != nullptr && it->second->Record.SystemStateInfoSize() > 0) {
+ auto* element = field->Add();
+ element->Swap(it->second->Record.MutableSystemStateInfo(0));
+ element->SetNodeId(it->first);
+ if (minResponseTime == 0 || it->second->Record.GetResponseTime() < minResponseTime) {
+ minResponseTime = it->second->Record.GetResponseTime();
+ }
+ }
+ }
+ result->Record.SetResponseTime(minResponseTime);
+ return result;
+ }
+};
+
+template <>
+struct TWhiteboardInfo<TEvWhiteboard::TEvSystemStateResponse> {
+ using TResponseType = TEvWhiteboard::TEvSystemStateResponse;
+ using TElementType = NKikimrWhiteboard::TSystemStateInfo;
+
+ static constexpr bool StaticNodesOnly = false;
+
+ static ::google::protobuf::RepeatedPtrField<TElementType>* GetElementsField(TResponseType* response) {
+ return response->Record.MutableSystemStateInfo();
+ }
+
+ static TString GetDefaultMergeField() {
+ return "NodeId";
+ }
+
+ static THolder<TResponseType> MergeResponses(TMap<ui32, THolder<TResponseType>>& responses, const TString& fields = GetDefaultMergeField()) {
+ return TWhiteboardMerger<TResponseType>::MergeResponses(responses, fields);
+ }
+};
+
+using TJsonSysInfo = TJsonWhiteboardRequest<TEvWhiteboard::TEvSystemStateRequest, TEvWhiteboard::TEvSystemStateResponse>;
+
+template <>
+struct TJsonRequestSummary<TJsonSysInfo> {
static TString GetSummary() {
- return "\"System information\"";
- }
-};
-
-template <>
-struct TJsonRequestDescription<TJsonSysInfo> {
+ return "\"System information\"";
+ }
+};
+
+template <>
+struct TJsonRequestDescription<TJsonSysInfo> {
static TString GetDescription() {
- return "\"Returns system information\"";
- }
-};
-
-}
-}
+ return "\"Returns system information\"";
+ }
+};
+
+}
+}
diff --git a/ydb/core/viewer/json_tabletcounters.h b/ydb/core/viewer/json_tabletcounters.h
index 935431e6b4c..7f399104410 100644
--- a/ydb/core/viewer/json_tabletcounters.h
+++ b/ydb/core/viewer/json_tabletcounters.h
@@ -1,4 +1,4 @@
-#pragma once
+#pragma once
#include <library/cpp/actors/core/actor_bootstrapped.h>
#include <library/cpp/actors/core/mon.h>
#include <ydb/core/base/tablet.h>
@@ -7,200 +7,200 @@
#include <ydb/core/tx/schemeshard/schemeshard.h>
#include <ydb/core/tx/tx_proxy/proxy.h>
#include <ydb/core/viewer/json/json.h>
-#include "viewer.h"
-#include "wb_aggregate.h"
-
-namespace NKikimr {
-namespace NViewer {
-
-using namespace NActors;
-
-class TJsonTabletCounters : public TActorBootstrapped<TJsonTabletCounters> {
- static const bool WithRetry = false;
- using TBase = TActorBootstrapped<TJsonTabletCounters>;
- IViewer* Viewer;
- NMon::TEvHttpInfo::TPtr Event;
+#include "viewer.h"
+#include "wb_aggregate.h"
+
+namespace NKikimr {
+namespace NViewer {
+
+using namespace NActors;
+
+class TJsonTabletCounters : public TActorBootstrapped<TJsonTabletCounters> {
+ static const bool WithRetry = false;
+ using TBase = TActorBootstrapped<TJsonTabletCounters>;
+ IViewer* Viewer;
+ NMon::TEvHttpInfo::TPtr Event;
TVector<TActorId> PipeClients;
TVector<ui64> Tablets;
TMap<TTabletId, THolder<TEvTablet::TEvGetCountersResponse>> Results;
THolder<NSchemeShard::TEvSchemeShard::TEvDescribeSchemeResult> DescribeResult;
- TJsonSettings JsonSettings;
+ TJsonSettings JsonSettings;
ui32 Timeout = 0;
bool Aggregate = false;
-
-public:
+
+public:
static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
return NKikimrServices::TActivity::VIEWER_HANDLER;
- }
-
- TJsonTabletCounters(IViewer* viewer, NMon::TEvHttpInfo::TPtr &ev)
- : Viewer(viewer)
- , Event(ev)
- {}
-
- static NTabletPipe::TClientConfig InitPipeClientConfig() {
- NTabletPipe::TClientConfig clientConfig;
- if (WithRetry) {
- clientConfig.RetryPolicy = NTabletPipe::TClientRetryPolicy::WithRetries();
- }
- return clientConfig;
- }
-
- static const NTabletPipe::TClientConfig& GetPipeClientConfig() {
- static NTabletPipe::TClientConfig clientConfig = InitPipeClientConfig();
- return clientConfig;
- }
-
- void Bootstrap(const TActorContext& ctx) {
+ }
+
+ TJsonTabletCounters(IViewer* viewer, NMon::TEvHttpInfo::TPtr &ev)
+ : Viewer(viewer)
+ , Event(ev)
+ {}
+
+ static NTabletPipe::TClientConfig InitPipeClientConfig() {
+ NTabletPipe::TClientConfig clientConfig;
+ if (WithRetry) {
+ clientConfig.RetryPolicy = NTabletPipe::TClientRetryPolicy::WithRetries();
+ }
+ return clientConfig;
+ }
+
+ static const NTabletPipe::TClientConfig& GetPipeClientConfig() {
+ static NTabletPipe::TClientConfig clientConfig = InitPipeClientConfig();
+ return clientConfig;
+ }
+
+ void Bootstrap(const TActorContext& ctx) {
const auto& params(Event->Get()->Request.GetParams());
- JsonSettings.EnumAsNumbers = !FromStringWithDefault<bool>(params.Get("enums"), false);
- JsonSettings.UI64AsString = !FromStringWithDefault<bool>(params.Get("ui64"), false);
- Timeout = FromStringWithDefault<ui32>(params.Get("timeout"), 10000);
- Aggregate = FromStringWithDefault<bool>(params.Get("aggregate"), true);
- if (params.Has("path")) {
- THolder<TEvTxUserProxy::TEvNavigate> request(new TEvTxUserProxy::TEvNavigate());
- if (!Event->Get()->UserToken.empty()) {
- request->Record.SetUserToken(Event->Get()->UserToken);
- }
+ JsonSettings.EnumAsNumbers = !FromStringWithDefault<bool>(params.Get("enums"), false);
+ JsonSettings.UI64AsString = !FromStringWithDefault<bool>(params.Get("ui64"), false);
+ Timeout = FromStringWithDefault<ui32>(params.Get("timeout"), 10000);
+ Aggregate = FromStringWithDefault<bool>(params.Get("aggregate"), true);
+ if (params.Has("path")) {
+ THolder<TEvTxUserProxy::TEvNavigate> request(new TEvTxUserProxy::TEvNavigate());
+ if (!Event->Get()->UserToken.empty()) {
+ request->Record.SetUserToken(Event->Get()->UserToken);
+ }
NKikimrSchemeOp::TDescribePath* record = request->Record.MutableDescribePath();
- record->SetPath(params.Get("path"));
+ record->SetPath(params.Get("path"));
TActorId txproxy = MakeTxProxyID();
ctx.Send(txproxy, request.Release());
- Become(&TThis::StateRequestedDescribe, ctx, TDuration::MilliSeconds(Timeout), new TEvents::TEvWakeup());
+ Become(&TThis::StateRequestedDescribe, ctx, TDuration::MilliSeconds(Timeout), new TEvents::TEvWakeup());
} else if (params.Has("tablet_id")) {
- TTabletId tabletId = FromStringWithDefault<TTabletId>(params.Get("tablet_id"), 0);
- if (tabletId != 0) {
- Tablets.emplace_back(tabletId);
+ TTabletId tabletId = FromStringWithDefault<TTabletId>(params.Get("tablet_id"), 0);
+ if (tabletId != 0) {
+ Tablets.emplace_back(tabletId);
TActorId PipeClient = ctx.RegisterWithSameMailbox(NTabletPipe::CreateClient(ctx.SelfID, tabletId, GetPipeClientConfig()));
- NTabletPipe::SendData(ctx, PipeClient, new TEvTablet::TEvGetCounters(), tabletId);
- PipeClients.emplace_back(PipeClient);
- Become(&TThis::StateRequestedGetCounters, ctx, TDuration::MilliSeconds(Timeout), new TEvents::TEvWakeup());
- }
+ NTabletPipe::SendData(ctx, PipeClient, new TEvTablet::TEvGetCounters(), tabletId);
+ PipeClients.emplace_back(PipeClient);
+ Become(&TThis::StateRequestedGetCounters, ctx, TDuration::MilliSeconds(Timeout), new TEvents::TEvWakeup());
+ }
if (PipeClients.empty()) {
ReplyAndDie(ctx);
}
- }
- }
-
- void Die(const TActorContext& ctx) override {
+ }
+ }
+
+ void Die(const TActorContext& ctx) override {
for (const TActorId& pipeClient : PipeClients) {
- NTabletPipe::CloseClient(ctx, pipeClient);
- }
- TBase::Die(ctx);
- }
-
- STFUNC(StateRequestedDescribe) {
- switch (ev->GetTypeRewrite()) {
+ NTabletPipe::CloseClient(ctx, pipeClient);
+ }
+ TBase::Die(ctx);
+ }
+
+ STFUNC(StateRequestedDescribe) {
+ switch (ev->GetTypeRewrite()) {
HFunc(NSchemeShard::TEvSchemeShard::TEvDescribeSchemeResult, Handle);
- CFunc(TEvents::TSystem::Wakeup, HandleTimeout);
- }
- }
-
- STFUNC(StateRequestedGetCounters) {
- switch (ev->GetTypeRewrite()) {
- HFunc(TEvTablet::TEvGetCountersResponse, Handle);
- CFunc(TEvents::TSystem::Wakeup, HandleTimeout);
- }
- }
-
+ CFunc(TEvents::TSystem::Wakeup, HandleTimeout);
+ }
+ }
+
+ STFUNC(StateRequestedGetCounters) {
+ switch (ev->GetTypeRewrite()) {
+ HFunc(TEvTablet::TEvGetCountersResponse, Handle);
+ CFunc(TEvents::TSystem::Wakeup, HandleTimeout);
+ }
+ }
+
void Handle(NSchemeShard::TEvSchemeShard::TEvDescribeSchemeResult::TPtr &ev, const TActorContext &ctx) {
- DescribeResult = ev->Release();
+ DescribeResult = ev->Release();
if (DescribeResult->GetRecord().GetStatus() == NKikimrScheme::EStatus::StatusSuccess) {
- Tablets.reserve(DescribeResult->GetRecord().GetPathDescription().TablePartitionsSize());
- for (const auto& partition : DescribeResult->GetRecord().GetPathDescription().GetTablePartitions()) {
- Tablets.emplace_back(partition.GetDatashardId());
- }
- Tablets.reserve(DescribeResult->GetRecord().GetPathDescription().GetPersQueueGroup().PartitionsSize());
- for (const auto& partition : DescribeResult->GetRecord().GetPathDescription().GetPersQueueGroup().GetPartitions()) {
- Tablets.emplace_back(partition.GetTabletId());
- }
- Sort(Tablets);
- Tablets.erase(std::unique(Tablets.begin(), Tablets.end()), Tablets.end());
- }
- for (auto tabletId : Tablets) {
+ Tablets.reserve(DescribeResult->GetRecord().GetPathDescription().TablePartitionsSize());
+ for (const auto& partition : DescribeResult->GetRecord().GetPathDescription().GetTablePartitions()) {
+ Tablets.emplace_back(partition.GetDatashardId());
+ }
+ Tablets.reserve(DescribeResult->GetRecord().GetPathDescription().GetPersQueueGroup().PartitionsSize());
+ for (const auto& partition : DescribeResult->GetRecord().GetPathDescription().GetPersQueueGroup().GetPartitions()) {
+ Tablets.emplace_back(partition.GetTabletId());
+ }
+ Sort(Tablets);
+ Tablets.erase(std::unique(Tablets.begin(), Tablets.end()), Tablets.end());
+ }
+ for (auto tabletId : Tablets) {
TActorId PipeClient = ctx.RegisterWithSameMailbox(NTabletPipe::CreateClient(ctx.SelfID, tabletId, GetPipeClientConfig()));
- NTabletPipe::SendData(ctx, PipeClient, new TEvTablet::TEvGetCounters(), tabletId);
- PipeClients.emplace_back(PipeClient);
- }
- if (Tablets.empty()) {
- ReplyAndDie(ctx);
- }
- Become(&TThis::StateRequestedGetCounters);
- }
-
- void Handle(TEvTablet::TEvGetCountersResponse::TPtr &ev, const TActorContext &ctx) {
- Results.emplace(ev->Cookie, ev->Release());
- if (Results.size() == Tablets.size()) {
- ReplyAndDie(ctx);
- }
- }
-
- void ReplyAndDie(const TActorContext &ctx) {
- TStringStream json;
- if (!Results.empty()) {
- if (Aggregate) {
- THolder<TEvTablet::TEvGetCountersResponse> response = AggregateWhiteboardResponses(Results);
- TProtoToJson::ProtoToJson(json, response->Record, JsonSettings);
- } else {
- json << '{';
- for (auto it = Results.begin(); it != Results.end(); ++it) {
- if (it != Results.begin()) {
- json << ',';
- }
- json << '"' << it->first << "\":";
- TProtoToJson::ProtoToJson(json, it->second->Record, JsonSettings);
- }
- json << '}';
- }
- } else {
- json << "null";
- }
- ctx.Send(Event->Sender, new NMon::TEvHttpInfoRes(Viewer->GetHTTPOKJSON() + json.Str(), 0, NMon::IEvHttpInfoRes::EContentType::Custom));
- Die(ctx);
- }
-
- void HandleTimeout(const TActorContext &ctx) {
- ctx.Send(Event->Sender, new NMon::TEvHttpInfoRes(Viewer->GetHTTPGATEWAYTIMEOUT(), 0, NMon::IEvHttpInfoRes::EContentType::Custom));
- Die(ctx);
- }
-};
-
-template <>
-struct TJsonRequestSchema<TJsonTabletCounters> {
+ NTabletPipe::SendData(ctx, PipeClient, new TEvTablet::TEvGetCounters(), tabletId);
+ PipeClients.emplace_back(PipeClient);
+ }
+ if (Tablets.empty()) {
+ ReplyAndDie(ctx);
+ }
+ Become(&TThis::StateRequestedGetCounters);
+ }
+
+ void Handle(TEvTablet::TEvGetCountersResponse::TPtr &ev, const TActorContext &ctx) {
+ Results.emplace(ev->Cookie, ev->Release());
+ if (Results.size() == Tablets.size()) {
+ ReplyAndDie(ctx);
+ }
+ }
+
+ void ReplyAndDie(const TActorContext &ctx) {
+ TStringStream json;
+ if (!Results.empty()) {
+ if (Aggregate) {
+ THolder<TEvTablet::TEvGetCountersResponse> response = AggregateWhiteboardResponses(Results);
+ TProtoToJson::ProtoToJson(json, response->Record, JsonSettings);
+ } else {
+ json << '{';
+ for (auto it = Results.begin(); it != Results.end(); ++it) {
+ if (it != Results.begin()) {
+ json << ',';
+ }
+ json << '"' << it->first << "\":";
+ TProtoToJson::ProtoToJson(json, it->second->Record, JsonSettings);
+ }
+ json << '}';
+ }
+ } else {
+ json << "null";
+ }
+ ctx.Send(Event->Sender, new NMon::TEvHttpInfoRes(Viewer->GetHTTPOKJSON() + json.Str(), 0, NMon::IEvHttpInfoRes::EContentType::Custom));
+ Die(ctx);
+ }
+
+ void HandleTimeout(const TActorContext &ctx) {
+ ctx.Send(Event->Sender, new NMon::TEvHttpInfoRes(Viewer->GetHTTPGATEWAYTIMEOUT(), 0, NMon::IEvHttpInfoRes::EContentType::Custom));
+ Die(ctx);
+ }
+};
+
+template <>
+struct TJsonRequestSchema<TJsonTabletCounters> {
static TString GetSchema() {
- TStringStream stream;
- TProtoToJson::ProtoToJsonSchema<TEvTablet::TEvGetCountersResponse::ProtoRecordType>(stream);
- return stream.Str();
- }
-};
-
-template <>
-struct TJsonRequestParameters<TJsonTabletCounters> {
+ TStringStream stream;
+ TProtoToJson::ProtoToJsonSchema<TEvTablet::TEvGetCountersResponse::ProtoRecordType>(stream);
+ return stream.Str();
+ }
+};
+
+template <>
+struct TJsonRequestParameters<TJsonTabletCounters> {
static TString GetParameters() {
- return R"___([{"name":"path","in":"query","description":"schema path","required":false,"type":"string"},
- {"name":"tablet_id","in":"query","description":"tablet identifier","required":false,"type":"integer"},
- {"name":"enums","in":"query","description":"convert enums to strings","required":false,"type":"boolean"},
- {"name":"aggregate","in":"query","description":"aggregate tablet counters","required":false,"type":"boolean"},
- {"name":"ui64","in":"query","description":"return ui64 as number","required":false,"type":"boolean"},
- {"name":"timeout","in":"query","description":"timeout in ms","required":false,"type":"integer"}])___";
- }
-};
-
-template <>
-struct TJsonRequestSummary<TJsonTabletCounters> {
+ return R"___([{"name":"path","in":"query","description":"schema path","required":false,"type":"string"},
+ {"name":"tablet_id","in":"query","description":"tablet identifier","required":false,"type":"integer"},
+ {"name":"enums","in":"query","description":"convert enums to strings","required":false,"type":"boolean"},
+ {"name":"aggregate","in":"query","description":"aggregate tablet counters","required":false,"type":"boolean"},
+ {"name":"ui64","in":"query","description":"return ui64 as number","required":false,"type":"boolean"},
+ {"name":"timeout","in":"query","description":"timeout in ms","required":false,"type":"integer"}])___";
+ }
+};
+
+template <>
+struct TJsonRequestSummary<TJsonTabletCounters> {
static TString GetSummary() {
- return "\"Tablet counters information\"";
- }
-};
-
-template <>
-struct TJsonRequestDescription<TJsonTabletCounters> {
+ return "\"Tablet counters information\"";
+ }
+};
+
+template <>
+struct TJsonRequestDescription<TJsonTabletCounters> {
static TString GetDescription() {
- return "\"Returns information about tablet counters\"";
- }
-};
-
-}
-}
+ return "\"Returns information about tablet counters\"";
+ }
+};
+
+}
+}
diff --git a/ydb/core/viewer/json_tabletinfo.h b/ydb/core/viewer/json_tabletinfo.h
index 01ac26b9ca0..32546865a15 100644
--- a/ydb/core/viewer/json_tabletinfo.h
+++ b/ydb/core/viewer/json_tabletinfo.h
@@ -1,4 +1,4 @@
-#pragma once
+#pragma once
#include <library/cpp/actors/core/actor_bootstrapped.h>
#include <library/cpp/actors/core/interconnect.h>
#include <library/cpp/actors/core/mon.h>
@@ -7,185 +7,185 @@
#include <ydb/core/tx/tx_proxy/proxy.h>
#include <ydb/core/node_whiteboard/node_whiteboard.h>
#include <ydb/core/base/tablet_pipe.h>
-#include "json_pipe_req.h"
-#include "json_wb_req.h"
-
-namespace NKikimr {
-namespace NViewer {
-
-template <>
-struct TWhiteboardInfo<TEvWhiteboard::TEvTabletStateResponse> {
- using TResponseType = TEvWhiteboard::TEvTabletStateResponse;
- using TElementType = NKikimrWhiteboard::TTabletStateInfo;
- using TElementKeyType = std::pair<ui64, ui32>;
-
- static constexpr bool StaticNodesOnly = false;
-
- static ::google::protobuf::RepeatedPtrField<TElementType>* GetElementsField(TResponseType* response) {
- return response->Record.MutableTabletStateInfo();
- }
-
- static std::pair<ui64, ui32> GetElementKey(const TElementType& type) {
+#include "json_pipe_req.h"
+#include "json_wb_req.h"
+
+namespace NKikimr {
+namespace NViewer {
+
+template <>
+struct TWhiteboardInfo<TEvWhiteboard::TEvTabletStateResponse> {
+ using TResponseType = TEvWhiteboard::TEvTabletStateResponse;
+ using TElementType = NKikimrWhiteboard::TTabletStateInfo;
+ using TElementKeyType = std::pair<ui64, ui32>;
+
+ static constexpr bool StaticNodesOnly = false;
+
+ static ::google::protobuf::RepeatedPtrField<TElementType>* GetElementsField(TResponseType* response) {
+ return response->Record.MutableTabletStateInfo();
+ }
+
+ static std::pair<ui64, ui32> GetElementKey(const TElementType& type) {
return std::pair<ui64, ui32>(type.GetTabletId(), type.GetFollowerId());
- }
-
- static TString GetDefaultMergeField() {
+ }
+
+ static TString GetDefaultMergeField() {
return "TabletId,FollowerId";
- }
-
- static THolder<TResponseType> MergeResponses(TMap<ui32, THolder<TResponseType>>& responses, const TString& fields = GetDefaultMergeField()) {
- if (fields == GetDefaultMergeField()) {
- return TWhiteboardMerger<TResponseType>::MergeResponsesElementKey(responses);
- } else {
- return TWhiteboardMerger<TResponseType>::MergeResponses(responses, fields);
- }
- }
-};
-
-template <>
+ }
+
+ static THolder<TResponseType> MergeResponses(TMap<ui32, THolder<TResponseType>>& responses, const TString& fields = GetDefaultMergeField()) {
+ if (fields == GetDefaultMergeField()) {
+ return TWhiteboardMerger<TResponseType>::MergeResponsesElementKey(responses);
+ } else {
+ return TWhiteboardMerger<TResponseType>::MergeResponses(responses, fields);
+ }
+ }
+};
+
+template <>
struct TWhiteboardMergerComparator<NKikimrWhiteboard::TTabletStateInfo> {
- bool operator ()(const NKikimrWhiteboard::TTabletStateInfo& a, const NKikimrWhiteboard::TTabletStateInfo& b) const {
- return std::make_tuple(a.GetGeneration(), a.GetChangeTime()) < std::make_tuple(b.GetGeneration(), b.GetChangeTime());
- }
-};
-
-class TJsonTabletInfo : public TJsonWhiteboardRequest<TEvWhiteboard::TEvTabletStateRequest, TEvWhiteboard::TEvTabletStateResponse> {
- static const bool WithRetry = false;
- using TBase = TJsonWhiteboardRequest<TEvWhiteboard::TEvTabletStateRequest, TEvWhiteboard::TEvTabletStateResponse>;
- using TThis = TJsonTabletInfo;
+ bool operator ()(const NKikimrWhiteboard::TTabletStateInfo& a, const NKikimrWhiteboard::TTabletStateInfo& b) const {
+ return std::make_tuple(a.GetGeneration(), a.GetChangeTime()) < std::make_tuple(b.GetGeneration(), b.GetChangeTime());
+ }
+};
+
+class TJsonTabletInfo : public TJsonWhiteboardRequest<TEvWhiteboard::TEvTabletStateRequest, TEvWhiteboard::TEvTabletStateResponse> {
+ static const bool WithRetry = false;
+ using TBase = TJsonWhiteboardRequest<TEvWhiteboard::TEvTabletStateRequest, TEvWhiteboard::TEvTabletStateResponse>;
+ using TThis = TJsonTabletInfo;
TVector<ui64> Tablets;
-public:
- TJsonTabletInfo(IViewer *viewer, NMon::TEvHttpInfo::TPtr &ev)
- : TJsonWhiteboardRequest(viewer, ev)
- {}
-
- static NTabletPipe::TClientConfig InitPipeClientConfig() {
- NTabletPipe::TClientConfig clientConfig;
- if (WithRetry) {
- clientConfig.RetryPolicy = NTabletPipe::TClientRetryPolicy::WithRetries();
- }
- return clientConfig;
- }
-
- static const NTabletPipe::TClientConfig& GetPipeClientConfig() {
- static NTabletPipe::TClientConfig clientConfig = InitPipeClientConfig();
- return clientConfig;
- }
-
- void Bootstrap() override {
+public:
+ TJsonTabletInfo(IViewer *viewer, NMon::TEvHttpInfo::TPtr &ev)
+ : TJsonWhiteboardRequest(viewer, ev)
+ {}
+
+ static NTabletPipe::TClientConfig InitPipeClientConfig() {
+ NTabletPipe::TClientConfig clientConfig;
+ if (WithRetry) {
+ clientConfig.RetryPolicy = NTabletPipe::TClientRetryPolicy::WithRetries();
+ }
+ return clientConfig;
+ }
+
+ static const NTabletPipe::TClientConfig& GetPipeClientConfig() {
+ static NTabletPipe::TClientConfig clientConfig = InitPipeClientConfig();
+ return clientConfig;
+ }
+
+ void Bootstrap() override {
const auto& params(Event->Get()->Request.GetParams());
- Timeout = FromStringWithDefault<ui32>(params.Get("timeout"), 10000);
- if (params.Has("path")) {
- THolder<TEvTxUserProxy::TEvNavigate> request(new TEvTxUserProxy::TEvNavigate());
- if (!Event->Get()->UserToken.empty()) {
- request->Record.SetUserToken(Event->Get()->UserToken);
- }
+ Timeout = FromStringWithDefault<ui32>(params.Get("timeout"), 10000);
+ if (params.Has("path")) {
+ THolder<TEvTxUserProxy::TEvNavigate> request(new TEvTxUserProxy::TEvNavigate());
+ if (!Event->Get()->UserToken.empty()) {
+ request->Record.SetUserToken(Event->Get()->UserToken);
+ }
NKikimrSchemeOp::TDescribePath* record = request->Record.MutableDescribePath();
- record->SetPath(params.Get("path"));
+ record->SetPath(params.Get("path"));
TActorId txproxy = MakeTxProxyID();
- TBase::Send(txproxy, request.Release());
- Become(&TThis::StateRequestedDescribe, TDuration::MilliSeconds(Timeout), new TEvents::TEvWakeup());
+ TBase::Send(txproxy, request.Release());
+ Become(&TThis::StateRequestedDescribe, TDuration::MilliSeconds(Timeout), new TEvents::TEvWakeup());
} else {
- TBase::Bootstrap();
- }
- }
-
- void Handle(NSchemeShard::TEvSchemeShard::TEvDescribeSchemeResult::TPtr &ev) {
+ TBase::Bootstrap();
+ }
+ }
+
+ void Handle(NSchemeShard::TEvSchemeShard::TEvDescribeSchemeResult::TPtr &ev) {
THolder<NSchemeShard::TEvSchemeShard::TEvDescribeSchemeResult> describeResult = ev->Release();
if (describeResult->GetRecord().GetStatus() == NKikimrScheme::EStatus::StatusSuccess) {
- Tablets.reserve(describeResult->GetRecord().GetPathDescription().TablePartitionsSize());
- for (const auto& partition : describeResult->GetRecord().GetPathDescription().GetTablePartitions()) {
- Tablets.emplace_back(partition.GetDatashardId());
- }
- Tablets.reserve(describeResult->GetRecord().GetPathDescription().GetPersQueueGroup().PartitionsSize());
- for (const auto& partition : describeResult->GetRecord().GetPathDescription().GetPersQueueGroup().GetPartitions()) {
- Tablets.emplace_back(partition.GetTabletId());
- }
- Sort(Tablets);
- Tablets.erase(std::unique(Tablets.begin(), Tablets.end()), Tablets.end());
- }
- if (Tablets.empty()) {
- ReplyAndPassAway();
- }
- TBase::Bootstrap();
- }
-
- virtual void FilterResponse(THolder<TEvWhiteboard::TEvTabletStateResponse>& response) override {
- if (!Tablets.empty()) {
- if (response != nullptr) {
- TAutoPtr<TEvWhiteboard::TEvTabletStateResponse> result = new TEvWhiteboard::TEvTabletStateResponse();
- for (const NKikimrWhiteboard::TTabletStateInfo& info : response->Record.GetTabletStateInfo()) {
- if (BinarySearch(Tablets.begin(), Tablets.end(), info.GetTabletId())) {
- result->Record.MutableTabletStateInfo()->Add()->CopyFrom(info);
- }
- }
- result->Record.SetResponseTime(response->Record.GetResponseTime());
- response = result;
- }
- }
- if (response != nullptr) {
- for (NKikimrWhiteboard::TTabletStateInfo& info : *response->Record.MutableTabletStateInfo()) {
- info.SetOverall(GetWhiteboardFlag(GetFlagFromTabletState(info.GetState())));
- }
- }
- TBase::FilterResponse(response);
- }
-
- STATEFN(StateRequestedDescribe) {
- switch (ev->GetTypeRewrite()) {
- hFunc(NSchemeShard::TEvSchemeShard::TEvDescribeSchemeResult, Handle);
- cFunc(TEvents::TSystem::Wakeup, HandleTimeout);
- }
- }
-
- void PassAway() override {
- TBase::PassAway();
- }
-};
-
-template <>
-struct TJsonRequestParameters<TJsonTabletInfo> {
+ Tablets.reserve(describeResult->GetRecord().GetPathDescription().TablePartitionsSize());
+ for (const auto& partition : describeResult->GetRecord().GetPathDescription().GetTablePartitions()) {
+ Tablets.emplace_back(partition.GetDatashardId());
+ }
+ Tablets.reserve(describeResult->GetRecord().GetPathDescription().GetPersQueueGroup().PartitionsSize());
+ for (const auto& partition : describeResult->GetRecord().GetPathDescription().GetPersQueueGroup().GetPartitions()) {
+ Tablets.emplace_back(partition.GetTabletId());
+ }
+ Sort(Tablets);
+ Tablets.erase(std::unique(Tablets.begin(), Tablets.end()), Tablets.end());
+ }
+ if (Tablets.empty()) {
+ ReplyAndPassAway();
+ }
+ TBase::Bootstrap();
+ }
+
+ virtual void FilterResponse(THolder<TEvWhiteboard::TEvTabletStateResponse>& response) override {
+ if (!Tablets.empty()) {
+ if (response != nullptr) {
+ TAutoPtr<TEvWhiteboard::TEvTabletStateResponse> result = new TEvWhiteboard::TEvTabletStateResponse();
+ for (const NKikimrWhiteboard::TTabletStateInfo& info : response->Record.GetTabletStateInfo()) {
+ if (BinarySearch(Tablets.begin(), Tablets.end(), info.GetTabletId())) {
+ result->Record.MutableTabletStateInfo()->Add()->CopyFrom(info);
+ }
+ }
+ result->Record.SetResponseTime(response->Record.GetResponseTime());
+ response = result;
+ }
+ }
+ if (response != nullptr) {
+ for (NKikimrWhiteboard::TTabletStateInfo& info : *response->Record.MutableTabletStateInfo()) {
+ info.SetOverall(GetWhiteboardFlag(GetFlagFromTabletState(info.GetState())));
+ }
+ }
+ TBase::FilterResponse(response);
+ }
+
+ STATEFN(StateRequestedDescribe) {
+ switch (ev->GetTypeRewrite()) {
+ hFunc(NSchemeShard::TEvSchemeShard::TEvDescribeSchemeResult, Handle);
+ cFunc(TEvents::TSystem::Wakeup, HandleTimeout);
+ }
+ }
+
+ void PassAway() override {
+ TBase::PassAway();
+ }
+};
+
+template <>
+struct TJsonRequestParameters<TJsonTabletInfo> {
static TString GetParameters() {
- return R"___([{"name":"node_id","in":"query","description":"node identifier","required":false,"type":"integer"},)___"
- R"___({"name":"path","in":"query","description":"schema path","required":false,"type":"string"},)___"
- R"___({"name":"merge","in":"query","description":"merge information from nodes","required":false,"type":"boolean"},)___"
- R"___({"name":"group","in":"query","description":"group information by field","required":false,"type":"string"},)___"
- R"___({"name":"all","in":"query","description":"return all possible key combinations (for enums only)","required":false,"type":"boolean"},)___"
- R"___({"name":"filter","in":"query","description":"filter information by field","required":false,"type":"string"},)___"
- R"___({"name":"alive","in":"query","description":"request from alive (connected) nodes only","required":false,"type":"boolean"},)___"
- R"___({"name":"enums","in":"query","description":"convert enums to strings","required":false,"type":"boolean"},)___"
- R"___({"name":"ui64","in":"query","description":"return ui64 as number","required":false,"type":"boolean"},)___"
- R"___({"name":"timeout","in":"query","description":"timeout in ms","required":false,"type":"integer"},)___"
- R"___({"name":"retries","in":"query","description":"number of retries","required":false,"type":"integer"},)___"
- R"___({"name":"retry_period","in":"query","description":"retry period in ms","required":false,"type":"integer","default":500},)___"
- R"___({"name":"static","in":"query","description":"request from static nodes only","required":false,"type":"boolean"},)___"
- R"___({"name":"since","in":"query","description":"filter by update time","required":false,"type":"string"}])___";
- }
-};
-
-template <>
-struct TJsonRequestSchema<TJsonTabletInfo> {
+ return R"___([{"name":"node_id","in":"query","description":"node identifier","required":false,"type":"integer"},)___"
+ R"___({"name":"path","in":"query","description":"schema path","required":false,"type":"string"},)___"
+ R"___({"name":"merge","in":"query","description":"merge information from nodes","required":false,"type":"boolean"},)___"
+ R"___({"name":"group","in":"query","description":"group information by field","required":false,"type":"string"},)___"
+ R"___({"name":"all","in":"query","description":"return all possible key combinations (for enums only)","required":false,"type":"boolean"},)___"
+ R"___({"name":"filter","in":"query","description":"filter information by field","required":false,"type":"string"},)___"
+ R"___({"name":"alive","in":"query","description":"request from alive (connected) nodes only","required":false,"type":"boolean"},)___"
+ R"___({"name":"enums","in":"query","description":"convert enums to strings","required":false,"type":"boolean"},)___"
+ R"___({"name":"ui64","in":"query","description":"return ui64 as number","required":false,"type":"boolean"},)___"
+ R"___({"name":"timeout","in":"query","description":"timeout in ms","required":false,"type":"integer"},)___"
+ R"___({"name":"retries","in":"query","description":"number of retries","required":false,"type":"integer"},)___"
+ R"___({"name":"retry_period","in":"query","description":"retry period in ms","required":false,"type":"integer","default":500},)___"
+ R"___({"name":"static","in":"query","description":"request from static nodes only","required":false,"type":"boolean"},)___"
+ R"___({"name":"since","in":"query","description":"filter by update time","required":false,"type":"string"}])___";
+ }
+};
+
+template <>
+struct TJsonRequestSchema<TJsonTabletInfo> {
static TString GetSchema() {
- TStringStream stream;
- TProtoToJson::ProtoToJsonSchema<NKikimrWhiteboard::TEvTabletStateResponse>(stream);
- return stream.Str();
- }
-};
-
-template <>
-struct TJsonRequestSummary<TJsonTabletInfo> {
+ TStringStream stream;
+ TProtoToJson::ProtoToJsonSchema<NKikimrWhiteboard::TEvTabletStateResponse>(stream);
+ return stream.Str();
+ }
+};
+
+template <>
+struct TJsonRequestSummary<TJsonTabletInfo> {
static TString GetSummary() {
- return "\"Информация о таблетках\"";
- }
-};
-
-template <>
-struct TJsonRequestDescription<TJsonTabletInfo> {
+ return "\"Информация о таблетках\"";
+ }
+};
+
+template <>
+struct TJsonRequestDescription<TJsonTabletInfo> {
static TString GetDescription() {
- return "\"Возвращает информацию о статусе таблеток в кластере\"";
- }
-};
-
-}
-}
+ return "\"Возвращает информацию о статусе таблеток в кластере\"";
+ }
+};
+
+}
+}
diff --git a/ydb/core/viewer/json_tenantinfo.h b/ydb/core/viewer/json_tenantinfo.h
index 8607a7b6d39..749422ba396 100644
--- a/ydb/core/viewer/json_tenantinfo.h
+++ b/ydb/core/viewer/json_tenantinfo.h
@@ -1,4 +1,4 @@
-#pragma once
+#pragma once
#include <library/cpp/actors/core/actor_bootstrapped.h>
#include <library/cpp/actors/core/mon.h>
#include <ydb/core/base/tablet.h>
@@ -11,539 +11,539 @@
#include <ydb/core/tx/tx_proxy/proxy.h>
#include <ydb/core/viewer/protos/viewer.pb.h>
#include <ydb/core/viewer/json/json.h>
-#include "viewer.h"
-#include "json_pipe_req.h"
-#include "wb_aggregate.h"
-#include "wb_merge.h"
-
-namespace NKikimr {
-namespace NViewer {
-
-using namespace NActors;
-
-class TJsonTenantInfo : public TViewerPipeClient<TJsonTenantInfo> {
- using TBase = TViewerPipeClient<TJsonTenantInfo>;
- IViewer* Viewer;
- THashMap<TString, NKikimrViewer::TTenant> TenantByPath;
- THashMap<TPathId, NKikimrViewer::TTenant> TenantBySubDomainKey;
+#include "viewer.h"
+#include "json_pipe_req.h"
+#include "wb_aggregate.h"
+#include "wb_merge.h"
+
+namespace NKikimr {
+namespace NViewer {
+
+using namespace NActors;
+
+class TJsonTenantInfo : public TViewerPipeClient<TJsonTenantInfo> {
+ using TBase = TViewerPipeClient<TJsonTenantInfo>;
+ IViewer* Viewer;
+ THashMap<TString, NKikimrViewer::TTenant> TenantByPath;
+ THashMap<TPathId, NKikimrViewer::TTenant> TenantBySubDomainKey;
THashMap<TString, THolder<NSchemeCache::TSchemeCacheNavigate>> NavigateResult;
- THashMap<TTabletId, THolder<TEvHive::TEvResponseHiveDomainStats>> HiveDomainStats;
- THashMap<TTabletId, THolder<TEvHive::TEvResponseHiveStorageStats>> HiveStorageStats;
- NMon::TEvHttpInfo::TPtr Event;
- THashSet<TNodeId> NodeIds;
- TMap<TNodeId, THolder<TEvWhiteboard::TEvSystemStateResponse>> NodeSysInfo;
- TMap<TNodeId, THolder<TEvWhiteboard::TEvTabletStateResponse>> NodeTabletInfo;
- TJsonSettings JsonSettings;
+ THashMap<TTabletId, THolder<TEvHive::TEvResponseHiveDomainStats>> HiveDomainStats;
+ THashMap<TTabletId, THolder<TEvHive::TEvResponseHiveStorageStats>> HiveStorageStats;
+ NMon::TEvHttpInfo::TPtr Event;
+ THashSet<TNodeId> NodeIds;
+ TMap<TNodeId, THolder<TEvWhiteboard::TEvSystemStateResponse>> NodeSysInfo;
+ TMap<TNodeId, THolder<TEvWhiteboard::TEvTabletStateResponse>> NodeTabletInfo;
+ TJsonSettings JsonSettings;
ui32 Timeout = 0;
- TString User;
- TString Path;
- bool Tablets = false;
- bool Storage = false;
- bool Nodes = false;
- TTabletId RootHiveId = 0;
- TString RootId; // id of root domain (tenant)
- NKikimrViewer::TTenantInfo Result;
-
-public:
+ TString User;
+ TString Path;
+ bool Tablets = false;
+ bool Storage = false;
+ bool Nodes = false;
+ TTabletId RootHiveId = 0;
+ TString RootId; // id of root domain (tenant)
+ NKikimrViewer::TTenantInfo Result;
+
+public:
static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
return NKikimrServices::TActivity::VIEWER_HANDLER;
- }
-
- TJsonTenantInfo(IViewer* viewer, NMon::TEvHttpInfo::TPtr& ev)
- : Viewer(viewer)
- , Event(ev)
- {}
-
- TString GetDomainId(TPathId pathId) {
- return TStringBuilder() << pathId.OwnerId << '-' << pathId.LocalPathId;
- }
-
- void Bootstrap() {
+ }
+
+ TJsonTenantInfo(IViewer* viewer, NMon::TEvHttpInfo::TPtr& ev)
+ : Viewer(viewer)
+ , Event(ev)
+ {}
+
+ TString GetDomainId(TPathId pathId) {
+ return TStringBuilder() << pathId.OwnerId << '-' << pathId.LocalPathId;
+ }
+
+ void Bootstrap() {
const auto& params(Event->Get()->Request.GetParams());
- JsonSettings.EnumAsNumbers = !FromStringWithDefault<bool>(params.Get("enums"), true);
- JsonSettings.UI64AsString = !FromStringWithDefault<bool>(params.Get("ui64"), false);
+ JsonSettings.EnumAsNumbers = !FromStringWithDefault<bool>(params.Get("enums"), true);
+ JsonSettings.UI64AsString = !FromStringWithDefault<bool>(params.Get("ui64"), false);
Followers = false;
- Metrics = true;
- InitConfig(params);
- Timeout = FromStringWithDefault<ui32>(params.Get("timeout"), 10000);
- Tablets = FromStringWithDefault<bool>(params.Get("tablets"), Tablets);
- Storage = FromStringWithDefault<bool>(params.Get("storage"), Storage);
- Nodes = FromStringWithDefault<bool>(params.Get("nodes"), Nodes);
- User = params.Get("user");
- Path = params.Get("path");
-
- TIntrusivePtr<TDomainsInfo> domains = AppData()->DomainsInfo;
- TIntrusivePtr<TDomainsInfo::TDomain> domain = domains->Domains.begin()->second;
-
- RequestConsoleListTenants();
-
- TString domainPath = "/" + domain->Name;
- if (Path.empty() || domainPath == Path) {
- TPathId subDomainKey(domain->SchemeRoot, 1);
- NKikimrViewer::TTenant& tenant = TenantBySubDomainKey[subDomainKey];
- tenant.SetId(GetDomainId(subDomainKey));
- tenant.SetState(Ydb::Cms::GetDatabaseStatusResult::RUNNING);
- tenant.SetType(NKikimrViewer::Domain);
- RequestSchemeCacheNavigate(domainPath);
- }
- RootId = GetDomainId({domain->SchemeRoot, 1});
- RootHiveId = domains->GetHive(domain->DefaultHiveUid);
- RequestHiveDomainStats(RootHiveId);
- if (Storage) {
- RequestHiveStorageStats(RootHiveId);
- }
-
- if (Requests == 0) {
- ReplyAndPassAway();
- }
-
- Become(&TThis::StateRequested, TDuration::MilliSeconds(Timeout), new TEvents::TEvWakeup());
- }
-
- void PassAway() override {
+ Metrics = true;
+ InitConfig(params);
+ Timeout = FromStringWithDefault<ui32>(params.Get("timeout"), 10000);
+ Tablets = FromStringWithDefault<bool>(params.Get("tablets"), Tablets);
+ Storage = FromStringWithDefault<bool>(params.Get("storage"), Storage);
+ Nodes = FromStringWithDefault<bool>(params.Get("nodes"), Nodes);
+ User = params.Get("user");
+ Path = params.Get("path");
+
+ TIntrusivePtr<TDomainsInfo> domains = AppData()->DomainsInfo;
+ TIntrusivePtr<TDomainsInfo::TDomain> domain = domains->Domains.begin()->second;
+
+ RequestConsoleListTenants();
+
+ TString domainPath = "/" + domain->Name;
+ if (Path.empty() || domainPath == Path) {
+ TPathId subDomainKey(domain->SchemeRoot, 1);
+ NKikimrViewer::TTenant& tenant = TenantBySubDomainKey[subDomainKey];
+ tenant.SetId(GetDomainId(subDomainKey));
+ tenant.SetState(Ydb::Cms::GetDatabaseStatusResult::RUNNING);
+ tenant.SetType(NKikimrViewer::Domain);
+ RequestSchemeCacheNavigate(domainPath);
+ }
+ RootId = GetDomainId({domain->SchemeRoot, 1});
+ RootHiveId = domains->GetHive(domain->DefaultHiveUid);
+ RequestHiveDomainStats(RootHiveId);
+ if (Storage) {
+ RequestHiveStorageStats(RootHiveId);
+ }
+
+ if (Requests == 0) {
+ ReplyAndPassAway();
+ }
+
+ Become(&TThis::StateRequested, TDuration::MilliSeconds(Timeout), new TEvents::TEvWakeup());
+ }
+
+ void PassAway() override {
for (const TNodeId nodeId : NodeIds) {
- Send(TActivationContext::InterconnectProxy(nodeId), new TEvents::TEvUnsubscribe());
- };
- TBase::PassAway();
- }
-
- STATEFN(StateRequested) {
- switch (ev->GetTypeRewrite()) {
- hFunc(NConsole::TEvConsole::TEvListTenantsResponse, Handle);
- hFunc(NConsole::TEvConsole::TEvGetTenantStatusResponse, Handle);
- hFunc(TEvHive::TEvResponseHiveDomainStats, Handle);
- hFunc(TEvHive::TEvResponseHiveStorageStats, Handle);
- hFunc(TEvTxProxySchemeCache::TEvNavigateKeySetResult, Handle);
- hFunc(TEvWhiteboard::TEvSystemStateResponse, Handle);
- hFunc(TEvWhiteboard::TEvTabletStateResponse, Handle);
- hFunc(TEvents::TEvUndelivered, Undelivered);
- hFunc(TEvInterconnect::TEvNodeDisconnected, Disconnected);
- hFunc(TEvTabletPipe::TEvClientConnected, TBase::Handle);
- cFunc(TEvents::TSystem::Wakeup, HandleTimeout);
- }
- }
-
- void Handle(NConsole::TEvConsole::TEvListTenantsResponse::TPtr& ev) {
+ Send(TActivationContext::InterconnectProxy(nodeId), new TEvents::TEvUnsubscribe());
+ };
+ TBase::PassAway();
+ }
+
+ STATEFN(StateRequested) {
+ switch (ev->GetTypeRewrite()) {
+ hFunc(NConsole::TEvConsole::TEvListTenantsResponse, Handle);
+ hFunc(NConsole::TEvConsole::TEvGetTenantStatusResponse, Handle);
+ hFunc(TEvHive::TEvResponseHiveDomainStats, Handle);
+ hFunc(TEvHive::TEvResponseHiveStorageStats, Handle);
+ hFunc(TEvTxProxySchemeCache::TEvNavigateKeySetResult, Handle);
+ hFunc(TEvWhiteboard::TEvSystemStateResponse, Handle);
+ hFunc(TEvWhiteboard::TEvTabletStateResponse, Handle);
+ hFunc(TEvents::TEvUndelivered, Undelivered);
+ hFunc(TEvInterconnect::TEvNodeDisconnected, Disconnected);
+ hFunc(TEvTabletPipe::TEvClientConnected, TBase::Handle);
+ cFunc(TEvents::TSystem::Wakeup, HandleTimeout);
+ }
+ }
+
+ void Handle(NConsole::TEvConsole::TEvListTenantsResponse::TPtr& ev) {
Ydb::Cms::ListDatabasesResult listTenantsResult;
ev->Get()->Record.GetResponse().operation().result().UnpackTo(&listTenantsResult);
- for (const TString& path : listTenantsResult.paths()) {
- if (!Path.empty() && path != Path) {
- continue;
- }
- RequestConsoleGetTenantStatus(path);
- RequestSchemeCacheNavigate(path);
- }
- RequestDone();
- }
-
- void Handle(NConsole::TEvConsole::TEvGetTenantStatusResponse::TPtr& ev) {
+ for (const TString& path : listTenantsResult.paths()) {
+ if (!Path.empty() && path != Path) {
+ continue;
+ }
+ RequestConsoleGetTenantStatus(path);
+ RequestSchemeCacheNavigate(path);
+ }
+ RequestDone();
+ }
+
+ void Handle(NConsole::TEvConsole::TEvGetTenantStatusResponse::TPtr& ev) {
Ydb::Cms::GetDatabaseStatusResult getTenantStatusResult;
ev->Get()->Record.GetResponse().operation().result().UnpackTo(&getTenantStatusResult);
- TString path = getTenantStatusResult.path();
- NKikimrViewer::TTenant& tenant = TenantByPath[path];
- tenant.SetName(path);
- tenant.SetState(getTenantStatusResult.state());
- for (const Ydb::Cms::StorageUnits& unit : getTenantStatusResult.allocated_resources().storage_units()) {
- NKikimrViewer::TTenantResource& resource = *tenant.MutableResources()->AddAllocated();
- resource.SetType("storage");
- resource.SetKind(unit.unit_kind());
- resource.SetCount(unit.count());
- }
- for (const Ydb::Cms::StorageUnits& unit : getTenantStatusResult.required_resources().storage_units()) {
- NKikimrViewer::TTenantResource& resource = *tenant.MutableResources()->AddRequired();
- resource.SetType("storage");
- resource.SetKind(unit.unit_kind());
- resource.SetCount(unit.count());
- }
- for (const Ydb::Cms::ComputationalUnits& unit : getTenantStatusResult.allocated_resources().computational_units()) {
- NKikimrViewer::TTenantResource& resource = *tenant.MutableResources()->AddAllocated();
- resource.SetType("compute");
- resource.SetZone(unit.availability_zone());
- resource.SetKind(unit.unit_kind());
- resource.SetCount(unit.count());
- }
- for (const Ydb::Cms::ComputationalUnits& unit : getTenantStatusResult.required_resources().computational_units()) {
- NKikimrViewer::TTenantResource& resource = *tenant.MutableResources()->AddRequired();
- resource.SetType("compute");
- resource.SetZone(unit.availability_zone());
- resource.SetKind(unit.unit_kind());
- resource.SetCount(unit.count());
- }
-
- RequestDone();
- }
-
- void Handle(TEvHive::TEvResponseHiveDomainStats::TPtr& ev) {
- for (const NKikimrHive::THiveDomainStats& hiveStat : ev->Get()->Record.GetDomainStats()) {
- TPathId subDomainKey({hiveStat.GetShardId(), hiveStat.GetPathId()});
- NKikimrViewer::TTenant& tenant = TenantBySubDomainKey[subDomainKey];
- tenant.SetId(GetDomainId({hiveStat.GetShardId(), hiveStat.GetPathId()}));
- if (ev->Cookie != RootHiveId || tenant.GetId() == RootId) {
- if (!tenant.HasMetrics()) {
- tenant.MutableMetrics()->CopyFrom(hiveStat.GetMetrics());
- }
- if (tenant.StateStatsSize() == 0) {
- tenant.MutableStateStats()->CopyFrom(hiveStat.GetStateStats());
- }
- if (tenant.NodeIdsSize() == 0) {
- tenant.MutableNodeIds()->CopyFrom(hiveStat.GetNodeIds());
- }
- if (tenant.GetAliveNodes() == 0) {
- tenant.SetAliveNodes(hiveStat.GetAliveNodes());
- }
- }
- for (TNodeId nodeId : hiveStat.GetNodeIds()) {
- if (NodeIds.insert(nodeId).second) {
- TActorId whiteboardServiceId = MakeNodeWhiteboardServiceId(nodeId);
- THolder<NNodeWhiteboard::TEvWhiteboard::TEvSystemStateRequest> request = MakeHolder<NNodeWhiteboard::TEvWhiteboard::TEvSystemStateRequest>();
- SendRequest(whiteboardServiceId, request.Release(), IEventHandle::FlagTrackDelivery | IEventHandle::FlagSubscribeOnSession, nodeId);
- if (Tablets) {
- THolder<NNodeWhiteboard::TEvWhiteboard::TEvTabletStateRequest> request = MakeHolder<NNodeWhiteboard::TEvWhiteboard::TEvTabletStateRequest>();
- SendRequest(whiteboardServiceId, request.Release(), IEventHandle::FlagTrackDelivery | IEventHandle::FlagSubscribeOnSession, nodeId);
- }
- }
- }
- }
- HiveDomainStats[ev->Cookie] = std::move(ev->Release());
- RequestDone();
- }
-
- void Handle(TEvHive::TEvResponseHiveStorageStats::TPtr& ev) {
- HiveStorageStats[ev->Cookie] = std::move(ev->Release());
- RequestDone();
- }
-
- void Handle(TEvTxProxySchemeCache::TEvNavigateKeySetResult::TPtr& ev) {
- if (ev->Get()->Request->ResultSet.size() == 1 && ev->Get()->Request->ResultSet.begin()->Status == NSchemeCache::TSchemeCacheNavigate::EStatus::Ok) {
- auto domainInfo = ev->Get()->Request->ResultSet.begin()->DomainInfo;
- TTabletId hiveId = domainInfo->Params.GetHive();
- if (hiveId) {
- RequestHiveDomainStats(hiveId);
- if (Storage) {
- RequestHiveStorageStats(hiveId);
- }
- }
- NKikimrViewer::TTenant& tenant = TenantBySubDomainKey[domainInfo->DomainKey];
- if (domainInfo->ResourcesDomainKey != domainInfo->DomainKey) {
- NKikimrViewer::TTenant& sharedTenant = TenantBySubDomainKey[domainInfo->ResourcesDomainKey];
- if (sharedTenant.GetType() != NKikimrViewer::Shared) {
- sharedTenant.SetType(NKikimrViewer::Shared);
- RequestSchemeCacheNavigate(domainInfo->ResourcesDomainKey);
- }
- tenant.SetType(NKikimrViewer::Serverless);
- tenant.SetResourceId(GetDomainId(domainInfo->ResourcesDomainKey));
- }
- TString id = GetDomainId(domainInfo->DomainKey);
- TString path = CanonizePath(ev->Get()->Request->ResultSet.begin()->Path);
- tenant.SetId(id);
- tenant.SetName(path);
- if (tenant.GetType() == NKikimrViewer::UnknownTenantType) {
- tenant.SetType(NKikimrViewer::Dedicated);
- }
- NavigateResult[id] = std::move(ev->Get()->Request);
- }
- RequestDone();
- }
-
- void Handle(NNodeWhiteboard::TEvWhiteboard::TEvSystemStateResponse::TPtr& ev) {
- ui32 nodeId = ev.Get()->Cookie;
- NodeSysInfo[nodeId] = ev->Release();
- RequestDone();
- }
-
- void Handle(NNodeWhiteboard::TEvWhiteboard::TEvTabletStateResponse::TPtr& ev) {
- ui32 nodeId = ev.Get()->Cookie;
- NodeTabletInfo[nodeId] = ev->Release();
- RequestDone();
- }
-
- void Undelivered(TEvents::TEvUndelivered::TPtr &ev) {
- ui32 nodeId = ev.Get()->Cookie;
- if (ev->Get()->SourceType == NNodeWhiteboard::TEvWhiteboard::EvSystemStateRequest) {
- if (NodeSysInfo.emplace(nodeId, nullptr).second) {
- RequestDone();
- }
- }
- if (ev->Get()->SourceType == NNodeWhiteboard::TEvWhiteboard::EvTabletStateRequest) {
- if (NodeTabletInfo.emplace(nodeId, nullptr).second) {
- RequestDone();
- }
- }
- }
-
- void Disconnected(TEvInterconnect::TEvNodeDisconnected::TPtr &ev) {
- ui32 nodeId = ev->Get()->NodeId;
- if (NodeSysInfo.emplace(nodeId, nullptr).second) {
- RequestDone();
- }
- if (NodeTabletInfo.emplace(nodeId, nullptr).second) {
- RequestDone();
- }
- }
-
- void ReplyAndPassAway() {
- TIntrusivePtr<TDomainsInfo> domains = AppData()->DomainsInfo;
- TIntrusivePtr<TDomainsInfo::TDomain> domain = domains->Domains.begin()->second;
- THolder<TEvWhiteboard::TEvTabletStateResponse> tabletInfo;
- THashMap<TTabletId, const NKikimrWhiteboard::TTabletStateInfo*> tabletInfoIndex;
- if (Tablets) {
- tabletInfo = MergeWhiteboardResponses(NodeTabletInfo);
- for (const auto& info : tabletInfo->Record.GetTabletStateInfo()) {
- tabletInfoIndex[info.GetTabletId()] = &info;
- }
- }
- for (const std::pair<const TPathId, NKikimrViewer::TTenant>& prTenant : TenantBySubDomainKey) {
- const TPathId& subDomainKey(prTenant.first);
- const NKikimrViewer::TTenant& tenantBySubDomainKey(prTenant.second);
- TString id(GetDomainId(subDomainKey));
- NKikimrViewer::EFlag overall = NKikimrViewer::EFlag::Grey;
- auto itNavigate = NavigateResult.find(id);
- if (itNavigate != NavigateResult.end()) {
- NSchemeCache::TSchemeCacheNavigate::TEntry entry = itNavigate->second->ResultSet.front();
- TString path = CanonizePath(entry.Path);
- if (Path && Path != path) {
- continue;
- }
- std::unordered_set<TString> users;
- if (entry.SecurityObject) {
- users.emplace(entry.SecurityObject->GetOwnerSID());
- for (const NACLibProto::TACE& ace : entry.SecurityObject->GetACL().GetACE()) {
- if (ace.GetAccessType() == (ui32)NACLib::EAccessType::Allow) {
- users.emplace(ace.GetSID());
- }
- }
- }
- if (!User.empty() && users.count(User) == 0) {
- continue;
- }
- NKikimrViewer::TTenant& tenant = *Result.AddTenantInfo();
- auto itTenantByPath = TenantByPath.find(path);
- if (itTenantByPath != TenantByPath.end()) {
- tenant = std::move(itTenantByPath->second);
- TenantByPath.erase(itTenantByPath);
- }
- tenant.MergeFrom(tenantBySubDomainKey);
- if (!tenant.GetId()) {
- tenant.SetId(GetDomainId(subDomainKey));
+ TString path = getTenantStatusResult.path();
+ NKikimrViewer::TTenant& tenant = TenantByPath[path];
+ tenant.SetName(path);
+ tenant.SetState(getTenantStatusResult.state());
+ for (const Ydb::Cms::StorageUnits& unit : getTenantStatusResult.allocated_resources().storage_units()) {
+ NKikimrViewer::TTenantResource& resource = *tenant.MutableResources()->AddAllocated();
+ resource.SetType("storage");
+ resource.SetKind(unit.unit_kind());
+ resource.SetCount(unit.count());
+ }
+ for (const Ydb::Cms::StorageUnits& unit : getTenantStatusResult.required_resources().storage_units()) {
+ NKikimrViewer::TTenantResource& resource = *tenant.MutableResources()->AddRequired();
+ resource.SetType("storage");
+ resource.SetKind(unit.unit_kind());
+ resource.SetCount(unit.count());
+ }
+ for (const Ydb::Cms::ComputationalUnits& unit : getTenantStatusResult.allocated_resources().computational_units()) {
+ NKikimrViewer::TTenantResource& resource = *tenant.MutableResources()->AddAllocated();
+ resource.SetType("compute");
+ resource.SetZone(unit.availability_zone());
+ resource.SetKind(unit.unit_kind());
+ resource.SetCount(unit.count());
+ }
+ for (const Ydb::Cms::ComputationalUnits& unit : getTenantStatusResult.required_resources().computational_units()) {
+ NKikimrViewer::TTenantResource& resource = *tenant.MutableResources()->AddRequired();
+ resource.SetType("compute");
+ resource.SetZone(unit.availability_zone());
+ resource.SetKind(unit.unit_kind());
+ resource.SetCount(unit.count());
+ }
+
+ RequestDone();
+ }
+
+ void Handle(TEvHive::TEvResponseHiveDomainStats::TPtr& ev) {
+ for (const NKikimrHive::THiveDomainStats& hiveStat : ev->Get()->Record.GetDomainStats()) {
+ TPathId subDomainKey({hiveStat.GetShardId(), hiveStat.GetPathId()});
+ NKikimrViewer::TTenant& tenant = TenantBySubDomainKey[subDomainKey];
+ tenant.SetId(GetDomainId({hiveStat.GetShardId(), hiveStat.GetPathId()}));
+ if (ev->Cookie != RootHiveId || tenant.GetId() == RootId) {
+ if (!tenant.HasMetrics()) {
+ tenant.MutableMetrics()->CopyFrom(hiveStat.GetMetrics());
+ }
+ if (tenant.StateStatsSize() == 0) {
+ tenant.MutableStateStats()->CopyFrom(hiveStat.GetStateStats());
+ }
+ if (tenant.NodeIdsSize() == 0) {
+ tenant.MutableNodeIds()->CopyFrom(hiveStat.GetNodeIds());
+ }
+ if (tenant.GetAliveNodes() == 0) {
+ tenant.SetAliveNodes(hiveStat.GetAliveNodes());
+ }
+ }
+ for (TNodeId nodeId : hiveStat.GetNodeIds()) {
+ if (NodeIds.insert(nodeId).second) {
+ TActorId whiteboardServiceId = MakeNodeWhiteboardServiceId(nodeId);
+ THolder<NNodeWhiteboard::TEvWhiteboard::TEvSystemStateRequest> request = MakeHolder<NNodeWhiteboard::TEvWhiteboard::TEvSystemStateRequest>();
+ SendRequest(whiteboardServiceId, request.Release(), IEventHandle::FlagTrackDelivery | IEventHandle::FlagSubscribeOnSession, nodeId);
+ if (Tablets) {
+ THolder<NNodeWhiteboard::TEvWhiteboard::TEvTabletStateRequest> request = MakeHolder<NNodeWhiteboard::TEvWhiteboard::TEvTabletStateRequest>();
+ SendRequest(whiteboardServiceId, request.Release(), IEventHandle::FlagTrackDelivery | IEventHandle::FlagSubscribeOnSession, nodeId);
+ }
+ }
+ }
+ }
+ HiveDomainStats[ev->Cookie] = std::move(ev->Release());
+ RequestDone();
+ }
+
+ void Handle(TEvHive::TEvResponseHiveStorageStats::TPtr& ev) {
+ HiveStorageStats[ev->Cookie] = std::move(ev->Release());
+ RequestDone();
+ }
+
+ void Handle(TEvTxProxySchemeCache::TEvNavigateKeySetResult::TPtr& ev) {
+ if (ev->Get()->Request->ResultSet.size() == 1 && ev->Get()->Request->ResultSet.begin()->Status == NSchemeCache::TSchemeCacheNavigate::EStatus::Ok) {
+ auto domainInfo = ev->Get()->Request->ResultSet.begin()->DomainInfo;
+ TTabletId hiveId = domainInfo->Params.GetHive();
+ if (hiveId) {
+ RequestHiveDomainStats(hiveId);
+ if (Storage) {
+ RequestHiveStorageStats(hiveId);
+ }
+ }
+ NKikimrViewer::TTenant& tenant = TenantBySubDomainKey[domainInfo->DomainKey];
+ if (domainInfo->ResourcesDomainKey != domainInfo->DomainKey) {
+ NKikimrViewer::TTenant& sharedTenant = TenantBySubDomainKey[domainInfo->ResourcesDomainKey];
+ if (sharedTenant.GetType() != NKikimrViewer::Shared) {
+ sharedTenant.SetType(NKikimrViewer::Shared);
+ RequestSchemeCacheNavigate(domainInfo->ResourcesDomainKey);
+ }
+ tenant.SetType(NKikimrViewer::Serverless);
+ tenant.SetResourceId(GetDomainId(domainInfo->ResourcesDomainKey));
+ }
+ TString id = GetDomainId(domainInfo->DomainKey);
+ TString path = CanonizePath(ev->Get()->Request->ResultSet.begin()->Path);
+ tenant.SetId(id);
+ tenant.SetName(path);
+ if (tenant.GetType() == NKikimrViewer::UnknownTenantType) {
+ tenant.SetType(NKikimrViewer::Dedicated);
+ }
+ NavigateResult[id] = std::move(ev->Get()->Request);
+ }
+ RequestDone();
+ }
+
+ void Handle(NNodeWhiteboard::TEvWhiteboard::TEvSystemStateResponse::TPtr& ev) {
+ ui32 nodeId = ev.Get()->Cookie;
+ NodeSysInfo[nodeId] = ev->Release();
+ RequestDone();
+ }
+
+ void Handle(NNodeWhiteboard::TEvWhiteboard::TEvTabletStateResponse::TPtr& ev) {
+ ui32 nodeId = ev.Get()->Cookie;
+ NodeTabletInfo[nodeId] = ev->Release();
+ RequestDone();
+ }
+
+ void Undelivered(TEvents::TEvUndelivered::TPtr &ev) {
+ ui32 nodeId = ev.Get()->Cookie;
+ if (ev->Get()->SourceType == NNodeWhiteboard::TEvWhiteboard::EvSystemStateRequest) {
+ if (NodeSysInfo.emplace(nodeId, nullptr).second) {
+ RequestDone();
+ }
+ }
+ if (ev->Get()->SourceType == NNodeWhiteboard::TEvWhiteboard::EvTabletStateRequest) {
+ if (NodeTabletInfo.emplace(nodeId, nullptr).second) {
+ RequestDone();
+ }
+ }
+ }
+
+ void Disconnected(TEvInterconnect::TEvNodeDisconnected::TPtr &ev) {
+ ui32 nodeId = ev->Get()->NodeId;
+ if (NodeSysInfo.emplace(nodeId, nullptr).second) {
+ RequestDone();
+ }
+ if (NodeTabletInfo.emplace(nodeId, nullptr).second) {
+ RequestDone();
+ }
+ }
+
+ void ReplyAndPassAway() {
+ TIntrusivePtr<TDomainsInfo> domains = AppData()->DomainsInfo;
+ TIntrusivePtr<TDomainsInfo::TDomain> domain = domains->Domains.begin()->second;
+ THolder<TEvWhiteboard::TEvTabletStateResponse> tabletInfo;
+ THashMap<TTabletId, const NKikimrWhiteboard::TTabletStateInfo*> tabletInfoIndex;
+ if (Tablets) {
+ tabletInfo = MergeWhiteboardResponses(NodeTabletInfo);
+ for (const auto& info : tabletInfo->Record.GetTabletStateInfo()) {
+ tabletInfoIndex[info.GetTabletId()] = &info;
+ }
+ }
+ for (const std::pair<const TPathId, NKikimrViewer::TTenant>& prTenant : TenantBySubDomainKey) {
+ const TPathId& subDomainKey(prTenant.first);
+ const NKikimrViewer::TTenant& tenantBySubDomainKey(prTenant.second);
+ TString id(GetDomainId(subDomainKey));
+ NKikimrViewer::EFlag overall = NKikimrViewer::EFlag::Grey;
+ auto itNavigate = NavigateResult.find(id);
+ if (itNavigate != NavigateResult.end()) {
+ NSchemeCache::TSchemeCacheNavigate::TEntry entry = itNavigate->second->ResultSet.front();
+ TString path = CanonizePath(entry.Path);
+ if (Path && Path != path) {
+ continue;
+ }
+ std::unordered_set<TString> users;
+ if (entry.SecurityObject) {
+ users.emplace(entry.SecurityObject->GetOwnerSID());
+ for (const NACLibProto::TACE& ace : entry.SecurityObject->GetACL().GetACE()) {
+ if (ace.GetAccessType() == (ui32)NACLib::EAccessType::Allow) {
+ users.emplace(ace.GetSID());
+ }
+ }
+ }
+ if (!User.empty() && users.count(User) == 0) {
+ continue;
}
- if (tenant.GetType() == NKikimrViewer::UnknownTenantType) {
- tenant.SetType(NKikimrViewer::Dedicated);
- }
- tenant.SetCreateTime(TInstant::MicroSeconds(entry.CreateStep).MilliSeconds());
- if (entry.SecurityObject) {
- tenant.SetOwner(entry.SecurityObject->GetOwnerSID());
- }
- for (const TString& user : users) {
- tenant.AddUsers(user);
- }
- for (const auto& userAttribute : entry.Attributes) {
- tenant.MutableUserAttributes()->insert({userAttribute.first, userAttribute.second});
- }
- TStackVec<TTabletId, 64> tablets;
- for (TTabletId tabletId : entry.DomainInfo->Params.GetCoordinators()) {
- tablets.emplace_back(tabletId);
- }
- for (TTabletId tabletId : entry.DomainInfo->Params.GetMediators()) {
- tablets.emplace_back(tabletId);
- }
- if (entry.DomainInfo->Params.HasSchemeShard()) {
- tablets.emplace_back(entry.DomainInfo->Params.GetSchemeShard());
- } else {
- tablets.emplace_back(domain->SchemeRoot);
-
- ui32 hiveDomain = domains->GetHiveDomainUid(domain->DefaultHiveUid);
- ui64 defaultStateStorageGroup = domains->GetDefaultStateStorageGroup(hiveDomain);
- tablets.emplace_back(MakeBSControllerID(defaultStateStorageGroup));
- tablets.emplace_back(MakeConsoleID(defaultStateStorageGroup));
- }
- TTabletId hiveId = domains->GetHive(domain->DefaultHiveUid);
- if (entry.DomainInfo->Params.HasHive()) {
- hiveId = entry.DomainInfo->Params.GetHive();
- } else {
- if (tenant.GetType() == NKikimrViewer::Serverless) {
- auto itResourceNavigate = NavigateResult.find(tenant.GetResourceId());
- if (itResourceNavigate != NavigateResult.end()) {
- NSchemeCache::TSchemeCacheNavigate::TEntry entry = itResourceNavigate->second->ResultSet.front();
- if (entry.DomainInfo->Params.HasHive()) {
- hiveId = entry.DomainInfo->Params.GetHive();
- }
- }
- }
- }
- tablets.emplace_back(hiveId);
-
- if (Storage) {
- auto itHiveStorageStats = HiveStorageStats.find(hiveId);
- if (itHiveStorageStats != HiveStorageStats.end()) {
- const NKikimrHive::TEvResponseHiveStorageStats& record = itHiveStorageStats->second.Get()->Record;
- uint64 storageAllocatedSize = 0;
- uint64 storageMinAvailableSize = std::numeric_limits<ui64>::max();
- uint64 storageGroups = 0;
- for (const NKikimrHive::THiveStoragePoolStats& poolStat : record.GetPools()) {
- for (const NKikimrHive::THiveStorageGroupStats& groupStat : poolStat.GetGroups()) {
- storageAllocatedSize += groupStat.GetAllocatedSize();
- storageMinAvailableSize = std::min(storageMinAvailableSize, groupStat.GetAvailableSize());
- ++storageGroups;
- }
- }
- tenant.SetStorageAllocatedSize(storageAllocatedSize);
- tenant.SetStorageMinAvailableSize(storageMinAvailableSize);
- tenant.SetStorageGroups(storageGroups);
- }
- }
-
- for (TTabletId tabletId : tablets) {
- auto it = tabletInfoIndex.find(tabletId);
- if (it != tabletInfoIndex.end()) {
- NKikimrWhiteboard::TTabletStateInfo* tabletInfo = tenant.AddSystemTablets();
- tabletInfo->CopyFrom(*it->second);
- NKikimrViewer::EFlag flag = GetFlagFromTabletState(tabletInfo->GetState());
- tabletInfo->SetOverall(GetWhiteboardFlag(flag));
- overall = Max(overall, flag);
- }
- }
-
- THashSet<TNodeId> tenantNodes;
-
- for (TNodeId nodeId : tenant.GetNodeIds()) {
- auto itNodeInfo = NodeSysInfo.find(nodeId);
- if (itNodeInfo != NodeSysInfo.end()) {
- if (itNodeInfo->second != nullptr && itNodeInfo->second->Record.SystemStateInfoSize() == 1) {
- const auto& nodeInfo = itNodeInfo->second->Record.GetSystemStateInfo(0);
- if (Nodes) {
- tenant.AddNodes()->CopyFrom(nodeInfo);
- }
- for (const auto& poolStat : nodeInfo.GetPoolStats()) {
- TString poolName = poolStat.GetName();
- NKikimrWhiteboard::TSystemStateInfo_TPoolStats* targetPoolStat = nullptr;
- for (NKikimrWhiteboard::TSystemStateInfo_TPoolStats& ps : *tenant.MutablePoolStats()) {
- if (ps.GetName() == poolName) {
- targetPoolStat = &ps;
- break;
- }
- }
- if (targetPoolStat == nullptr) {
- targetPoolStat = tenant.AddPoolStats();
- targetPoolStat->SetName(poolName);
- }
- double poolUsage = targetPoolStat->GetUsage() * targetPoolStat->GetThreads();
- poolUsage += poolStat.GetUsage() * poolStat.GetThreads();
- ui32 poolThreads = targetPoolStat->GetThreads() + poolStat.GetThreads();
- if (poolThreads != 0) {
- double threadUsage = poolUsage / poolThreads;
- targetPoolStat->SetUsage(threadUsage);
- targetPoolStat->SetThreads(poolThreads);
- }
- tenant.SetCoresUsed(tenant.GetCoresUsed() + poolStat.GetUsage() * poolStat.GetThreads());
- }
- if (nodeInfo.HasMemoryUsed()) {
- tenant.SetMemoryUsed(tenant.GetMemoryUsed() + nodeInfo.GetMemoryUsed());
- }
- if (nodeInfo.HasMemoryLimit()) {
- tenant.SetMemoryLimit(tenant.GetMemoryLimit() + nodeInfo.GetMemoryLimit());
- }
- overall = Max(overall, GetViewerFlag(nodeInfo.GetSystemState()));
- }
- }
- tenantNodes.emplace(nodeId);
- }
-
- if (tenant.GetType() == NKikimrViewer::Serverless) {
- tenant.SetStorageAllocatedSize(tenant.GetMetrics().GetStorage());
- tenant.SetMemoryUsed(tenant.GetMetrics().GetMemory());
- tenant.ClearMemoryLimit();
- tenant.SetCoresUsed(static_cast<double>(tenant.GetMetrics().GetCPU()) / 1000000);
- }
-
- {
- THashMap<std::pair<NKikimrTabletBase::TTabletTypes::EType, NKikimrViewer::EFlag>, NKikimrViewer::TTabletStateInfo> tablets;
-
- if (Tablets && tabletInfo) {
- for (const auto& pbTablet : tabletInfo->Record.GetTabletStateInfo()) {
- if (tenantNodes.count(pbTablet.GetNodeId()) > 0) {
- NKikimrViewer::EFlag state = GetFlagFromTabletState(pbTablet.GetState());
- auto& tablet = tablets[std::make_pair(pbTablet.GetType(), state)];
- tablet.SetCount(tablet.GetCount() + 1);
- }
- }
- }
- for (const auto& [prTypeState, tabletInfo] : tablets) {
- NKikimrViewer::TTabletStateInfo& tablet = *tenant.AddTablets();
- tablet.MergeFrom(tabletInfo);
- tablet.SetType(NKikimrTabletBase::TTabletTypes::EType_Name(prTypeState.first));
- tablet.SetState(prTypeState.second);
- }
- }
-
- // TODO(xenoxeno): include tenant's storage stats
-
-
-
- tenant.SetOverall(overall);
- }
- }
- for (const std::pair<const TString, NKikimrViewer::TTenant>& prTenant : TenantByPath) {
- const TString& path(prTenant.first);
- if (Path && Path != path) {
- continue;
- }
- if (!User.empty()) {
- continue;
- }
- const NKikimrViewer::TTenant& tenantByPath(prTenant.second);
- NKikimrViewer::EFlag overall = NKikimrViewer::EFlag::Red;
- NKikimrViewer::TTenant& tenant = *Result.AddTenantInfo();
- tenant.MergeFrom(tenantByPath);
- tenant.SetName(path);
- tenant.SetOverall(overall);
- }
- TStringStream json;
- TProtoToJson::ProtoToJson(json, Result, JsonSettings);
- Send(Event->Sender, new NMon::TEvHttpInfoRes(Viewer->GetHTTPOKJSON() + json.Str(), 0, NMon::IEvHttpInfoRes::EContentType::Custom));
- PassAway();
- }
-
- void HandleTimeout() {
- Result.AddErrors("Timeout occurred");
- ReplyAndPassAway();
- }
-};
-
-template <>
-struct TJsonRequestSchema<TJsonTenantInfo> {
- static TString GetSchema() {
- TStringStream stream;
- TProtoToJson::ProtoToJsonSchema<NKikimrViewer::TTenantInfo>(stream);
- return stream.Str();
- }
-};
-
-template <>
-struct TJsonRequestParameters<TJsonTenantInfo> {
- static TString GetParameters() {
- return R"___([{"name":"path","in":"query","description":"schema path","required":false,"type":"string"},
- {"name":"followers","in":"query","description":"return followers","required":false,"type":"boolean"},
- {"name":"metrics","in":"query","description":"return tablet metrics","required":false,"type":"boolean"},
- {"name":"enums","in":"query","description":"convert enums to strings","required":false,"type":"boolean"},
- {"name":"tablets","in":"query","description":"return system tablets","required":false,"type":"boolean"},
- {"name":"ui64","in":"query","description":"return ui64 as number","required":false,"type":"boolean"},
- {"name":"timeout","in":"query","description":"timeout in ms","required":false,"type":"integer"}])___";
- }
-};
-
-template <>
-struct TJsonRequestSummary<TJsonTenantInfo> {
- static TString GetSummary() {
- return "\"Tenant info (detailed)\"";
- }
-};
-
-template <>
-struct TJsonRequestDescription<TJsonTenantInfo> {
- static TString GetDescription() {
- return "\"Returns information about tenants\"";
- }
-};
-
-}
-}
+ NKikimrViewer::TTenant& tenant = *Result.AddTenantInfo();
+ auto itTenantByPath = TenantByPath.find(path);
+ if (itTenantByPath != TenantByPath.end()) {
+ tenant = std::move(itTenantByPath->second);
+ TenantByPath.erase(itTenantByPath);
+ }
+ tenant.MergeFrom(tenantBySubDomainKey);
+ if (!tenant.GetId()) {
+ tenant.SetId(GetDomainId(subDomainKey));
+ }
+ if (tenant.GetType() == NKikimrViewer::UnknownTenantType) {
+ tenant.SetType(NKikimrViewer::Dedicated);
+ }
+ tenant.SetCreateTime(TInstant::MicroSeconds(entry.CreateStep).MilliSeconds());
+ if (entry.SecurityObject) {
+ tenant.SetOwner(entry.SecurityObject->GetOwnerSID());
+ }
+ for (const TString& user : users) {
+ tenant.AddUsers(user);
+ }
+ for (const auto& userAttribute : entry.Attributes) {
+ tenant.MutableUserAttributes()->insert({userAttribute.first, userAttribute.second});
+ }
+ TStackVec<TTabletId, 64> tablets;
+ for (TTabletId tabletId : entry.DomainInfo->Params.GetCoordinators()) {
+ tablets.emplace_back(tabletId);
+ }
+ for (TTabletId tabletId : entry.DomainInfo->Params.GetMediators()) {
+ tablets.emplace_back(tabletId);
+ }
+ if (entry.DomainInfo->Params.HasSchemeShard()) {
+ tablets.emplace_back(entry.DomainInfo->Params.GetSchemeShard());
+ } else {
+ tablets.emplace_back(domain->SchemeRoot);
+
+ ui32 hiveDomain = domains->GetHiveDomainUid(domain->DefaultHiveUid);
+ ui64 defaultStateStorageGroup = domains->GetDefaultStateStorageGroup(hiveDomain);
+ tablets.emplace_back(MakeBSControllerID(defaultStateStorageGroup));
+ tablets.emplace_back(MakeConsoleID(defaultStateStorageGroup));
+ }
+ TTabletId hiveId = domains->GetHive(domain->DefaultHiveUid);
+ if (entry.DomainInfo->Params.HasHive()) {
+ hiveId = entry.DomainInfo->Params.GetHive();
+ } else {
+ if (tenant.GetType() == NKikimrViewer::Serverless) {
+ auto itResourceNavigate = NavigateResult.find(tenant.GetResourceId());
+ if (itResourceNavigate != NavigateResult.end()) {
+ NSchemeCache::TSchemeCacheNavigate::TEntry entry = itResourceNavigate->second->ResultSet.front();
+ if (entry.DomainInfo->Params.HasHive()) {
+ hiveId = entry.DomainInfo->Params.GetHive();
+ }
+ }
+ }
+ }
+ tablets.emplace_back(hiveId);
+
+ if (Storage) {
+ auto itHiveStorageStats = HiveStorageStats.find(hiveId);
+ if (itHiveStorageStats != HiveStorageStats.end()) {
+ const NKikimrHive::TEvResponseHiveStorageStats& record = itHiveStorageStats->second.Get()->Record;
+ uint64 storageAllocatedSize = 0;
+ uint64 storageMinAvailableSize = std::numeric_limits<ui64>::max();
+ uint64 storageGroups = 0;
+ for (const NKikimrHive::THiveStoragePoolStats& poolStat : record.GetPools()) {
+ for (const NKikimrHive::THiveStorageGroupStats& groupStat : poolStat.GetGroups()) {
+ storageAllocatedSize += groupStat.GetAllocatedSize();
+ storageMinAvailableSize = std::min(storageMinAvailableSize, groupStat.GetAvailableSize());
+ ++storageGroups;
+ }
+ }
+ tenant.SetStorageAllocatedSize(storageAllocatedSize);
+ tenant.SetStorageMinAvailableSize(storageMinAvailableSize);
+ tenant.SetStorageGroups(storageGroups);
+ }
+ }
+
+ for (TTabletId tabletId : tablets) {
+ auto it = tabletInfoIndex.find(tabletId);
+ if (it != tabletInfoIndex.end()) {
+ NKikimrWhiteboard::TTabletStateInfo* tabletInfo = tenant.AddSystemTablets();
+ tabletInfo->CopyFrom(*it->second);
+ NKikimrViewer::EFlag flag = GetFlagFromTabletState(tabletInfo->GetState());
+ tabletInfo->SetOverall(GetWhiteboardFlag(flag));
+ overall = Max(overall, flag);
+ }
+ }
+
+ THashSet<TNodeId> tenantNodes;
+
+ for (TNodeId nodeId : tenant.GetNodeIds()) {
+ auto itNodeInfo = NodeSysInfo.find(nodeId);
+ if (itNodeInfo != NodeSysInfo.end()) {
+ if (itNodeInfo->second != nullptr && itNodeInfo->second->Record.SystemStateInfoSize() == 1) {
+ const auto& nodeInfo = itNodeInfo->second->Record.GetSystemStateInfo(0);
+ if (Nodes) {
+ tenant.AddNodes()->CopyFrom(nodeInfo);
+ }
+ for (const auto& poolStat : nodeInfo.GetPoolStats()) {
+ TString poolName = poolStat.GetName();
+ NKikimrWhiteboard::TSystemStateInfo_TPoolStats* targetPoolStat = nullptr;
+ for (NKikimrWhiteboard::TSystemStateInfo_TPoolStats& ps : *tenant.MutablePoolStats()) {
+ if (ps.GetName() == poolName) {
+ targetPoolStat = &ps;
+ break;
+ }
+ }
+ if (targetPoolStat == nullptr) {
+ targetPoolStat = tenant.AddPoolStats();
+ targetPoolStat->SetName(poolName);
+ }
+ double poolUsage = targetPoolStat->GetUsage() * targetPoolStat->GetThreads();
+ poolUsage += poolStat.GetUsage() * poolStat.GetThreads();
+ ui32 poolThreads = targetPoolStat->GetThreads() + poolStat.GetThreads();
+ if (poolThreads != 0) {
+ double threadUsage = poolUsage / poolThreads;
+ targetPoolStat->SetUsage(threadUsage);
+ targetPoolStat->SetThreads(poolThreads);
+ }
+ tenant.SetCoresUsed(tenant.GetCoresUsed() + poolStat.GetUsage() * poolStat.GetThreads());
+ }
+ if (nodeInfo.HasMemoryUsed()) {
+ tenant.SetMemoryUsed(tenant.GetMemoryUsed() + nodeInfo.GetMemoryUsed());
+ }
+ if (nodeInfo.HasMemoryLimit()) {
+ tenant.SetMemoryLimit(tenant.GetMemoryLimit() + nodeInfo.GetMemoryLimit());
+ }
+ overall = Max(overall, GetViewerFlag(nodeInfo.GetSystemState()));
+ }
+ }
+ tenantNodes.emplace(nodeId);
+ }
+
+ if (tenant.GetType() == NKikimrViewer::Serverless) {
+ tenant.SetStorageAllocatedSize(tenant.GetMetrics().GetStorage());
+ tenant.SetMemoryUsed(tenant.GetMetrics().GetMemory());
+ tenant.ClearMemoryLimit();
+ tenant.SetCoresUsed(static_cast<double>(tenant.GetMetrics().GetCPU()) / 1000000);
+ }
+
+ {
+ THashMap<std::pair<NKikimrTabletBase::TTabletTypes::EType, NKikimrViewer::EFlag>, NKikimrViewer::TTabletStateInfo> tablets;
+
+ if (Tablets && tabletInfo) {
+ for (const auto& pbTablet : tabletInfo->Record.GetTabletStateInfo()) {
+ if (tenantNodes.count(pbTablet.GetNodeId()) > 0) {
+ NKikimrViewer::EFlag state = GetFlagFromTabletState(pbTablet.GetState());
+ auto& tablet = tablets[std::make_pair(pbTablet.GetType(), state)];
+ tablet.SetCount(tablet.GetCount() + 1);
+ }
+ }
+ }
+ for (const auto& [prTypeState, tabletInfo] : tablets) {
+ NKikimrViewer::TTabletStateInfo& tablet = *tenant.AddTablets();
+ tablet.MergeFrom(tabletInfo);
+ tablet.SetType(NKikimrTabletBase::TTabletTypes::EType_Name(prTypeState.first));
+ tablet.SetState(prTypeState.second);
+ }
+ }
+
+ // TODO(xenoxeno): include tenant's storage stats
+
+
+
+ tenant.SetOverall(overall);
+ }
+ }
+ for (const std::pair<const TString, NKikimrViewer::TTenant>& prTenant : TenantByPath) {
+ const TString& path(prTenant.first);
+ if (Path && Path != path) {
+ continue;
+ }
+ if (!User.empty()) {
+ continue;
+ }
+ const NKikimrViewer::TTenant& tenantByPath(prTenant.second);
+ NKikimrViewer::EFlag overall = NKikimrViewer::EFlag::Red;
+ NKikimrViewer::TTenant& tenant = *Result.AddTenantInfo();
+ tenant.MergeFrom(tenantByPath);
+ tenant.SetName(path);
+ tenant.SetOverall(overall);
+ }
+ TStringStream json;
+ TProtoToJson::ProtoToJson(json, Result, JsonSettings);
+ Send(Event->Sender, new NMon::TEvHttpInfoRes(Viewer->GetHTTPOKJSON() + json.Str(), 0, NMon::IEvHttpInfoRes::EContentType::Custom));
+ PassAway();
+ }
+
+ void HandleTimeout() {
+ Result.AddErrors("Timeout occurred");
+ ReplyAndPassAway();
+ }
+};
+
+template <>
+struct TJsonRequestSchema<TJsonTenantInfo> {
+ static TString GetSchema() {
+ TStringStream stream;
+ TProtoToJson::ProtoToJsonSchema<NKikimrViewer::TTenantInfo>(stream);
+ return stream.Str();
+ }
+};
+
+template <>
+struct TJsonRequestParameters<TJsonTenantInfo> {
+ static TString GetParameters() {
+ return R"___([{"name":"path","in":"query","description":"schema path","required":false,"type":"string"},
+ {"name":"followers","in":"query","description":"return followers","required":false,"type":"boolean"},
+ {"name":"metrics","in":"query","description":"return tablet metrics","required":false,"type":"boolean"},
+ {"name":"enums","in":"query","description":"convert enums to strings","required":false,"type":"boolean"},
+ {"name":"tablets","in":"query","description":"return system tablets","required":false,"type":"boolean"},
+ {"name":"ui64","in":"query","description":"return ui64 as number","required":false,"type":"boolean"},
+ {"name":"timeout","in":"query","description":"timeout in ms","required":false,"type":"integer"}])___";
+ }
+};
+
+template <>
+struct TJsonRequestSummary<TJsonTenantInfo> {
+ static TString GetSummary() {
+ return "\"Tenant info (detailed)\"";
+ }
+};
+
+template <>
+struct TJsonRequestDescription<TJsonTenantInfo> {
+ static TString GetDescription() {
+ return "\"Returns information about tenants\"";
+ }
+};
+
+}
+}
diff --git a/ydb/core/viewer/json_tenants.h b/ydb/core/viewer/json_tenants.h
index 711e756b158..762d5e3b436 100644
--- a/ydb/core/viewer/json_tenants.h
+++ b/ydb/core/viewer/json_tenants.h
@@ -1,4 +1,4 @@
-#pragma once
+#pragma once
#include <library/cpp/actors/core/actor_bootstrapped.h>
#include <library/cpp/actors/core/mon.h>
#include <ydb/core/base/tablet.h>
@@ -6,132 +6,132 @@
#include <ydb/core/protos/services.pb.h>
#include <ydb/core/cms/console/console.h>
#include <ydb/core/viewer/json/json.h>
-#include "viewer.h"
-#include "json_pipe_req.h"
-#include "wb_aggregate.h"
-
-namespace NKikimr {
-namespace NViewer {
-
-using namespace NActors;
-
-class TJsonTenants : public TViewerPipeClient<TJsonTenants> {
- using TBase = TViewerPipeClient<TJsonTenants>;
- IViewer* Viewer;
- NKikimrViewer::TTenants Result;
- NMon::TEvHttpInfo::TPtr Event;
- TJsonSettings JsonSettings;
+#include "viewer.h"
+#include "json_pipe_req.h"
+#include "wb_aggregate.h"
+
+namespace NKikimr {
+namespace NViewer {
+
+using namespace NActors;
+
+class TJsonTenants : public TViewerPipeClient<TJsonTenants> {
+ using TBase = TViewerPipeClient<TJsonTenants>;
+ IViewer* Viewer;
+ NKikimrViewer::TTenants Result;
+ NMon::TEvHttpInfo::TPtr Event;
+ TJsonSettings JsonSettings;
ui32 Timeout = 0;
- bool State = true;
- THashMap<TString, NKikimrViewer::TTenant*> TenantIndex;
-
-public:
+ bool State = true;
+ THashMap<TString, NKikimrViewer::TTenant*> TenantIndex;
+
+public:
static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
return NKikimrServices::TActivity::VIEWER_HANDLER;
- }
-
- TJsonTenants(IViewer* viewer, NMon::TEvHttpInfo::TPtr &ev)
- : Viewer(viewer)
- , Event(ev)
- {}
-
- void Bootstrap() {
+ }
+
+ TJsonTenants(IViewer* viewer, NMon::TEvHttpInfo::TPtr &ev)
+ : Viewer(viewer)
+ , Event(ev)
+ {}
+
+ void Bootstrap() {
const auto& params(Event->Get()->Request.GetParams());
- JsonSettings.EnumAsNumbers = !FromStringWithDefault<bool>(params.Get("enums"), true);
- JsonSettings.UI64AsString = !FromStringWithDefault<bool>(params.Get("ui64"), false);
- InitConfig(params);
- Timeout = FromStringWithDefault<ui32>(params.Get("timeout"), 10000);
- State = FromStringWithDefault<bool>(params.Get("state"), true);
- TIntrusivePtr<TDomainsInfo> domains = AppData()->DomainsInfo;
- TIntrusivePtr<TDomainsInfo::TDomain> domain = domains->Domains.begin()->second;
- NKikimrViewer::TTenant& tenant = *Result.AddTenants();
- tenant.SetName("/" + domain->Name);
- if (State) {
- tenant.SetState(Ydb::Cms::GetDatabaseStatusResult::State::GetDatabaseStatusResult_State_RUNNING);
- }
- RequestConsoleListTenants();
- Become(&TThis::StateWork, TDuration::MilliSeconds(Timeout), new TEvents::TEvWakeup());
- }
-
- STATEFN(StateWork) {
- switch (ev->GetTypeRewrite()) {
- hFunc(NConsole::TEvConsole::TEvListTenantsResponse, Handle);
- hFunc(NConsole::TEvConsole::TEvGetTenantStatusResponse, Handle);
- hFunc(TEvTabletPipe::TEvClientConnected, TBase::Handle);
- cFunc(TEvents::TSystem::Wakeup, HandleTimeout);
- }
- }
-
- void Handle(NConsole::TEvConsole::TEvListTenantsResponse::TPtr& ev) {
+ JsonSettings.EnumAsNumbers = !FromStringWithDefault<bool>(params.Get("enums"), true);
+ JsonSettings.UI64AsString = !FromStringWithDefault<bool>(params.Get("ui64"), false);
+ InitConfig(params);
+ Timeout = FromStringWithDefault<ui32>(params.Get("timeout"), 10000);
+ State = FromStringWithDefault<bool>(params.Get("state"), true);
+ TIntrusivePtr<TDomainsInfo> domains = AppData()->DomainsInfo;
+ TIntrusivePtr<TDomainsInfo::TDomain> domain = domains->Domains.begin()->second;
+ NKikimrViewer::TTenant& tenant = *Result.AddTenants();
+ tenant.SetName("/" + domain->Name);
+ if (State) {
+ tenant.SetState(Ydb::Cms::GetDatabaseStatusResult::State::GetDatabaseStatusResult_State_RUNNING);
+ }
+ RequestConsoleListTenants();
+ Become(&TThis::StateWork, TDuration::MilliSeconds(Timeout), new TEvents::TEvWakeup());
+ }
+
+ STATEFN(StateWork) {
+ switch (ev->GetTypeRewrite()) {
+ hFunc(NConsole::TEvConsole::TEvListTenantsResponse, Handle);
+ hFunc(NConsole::TEvConsole::TEvGetTenantStatusResponse, Handle);
+ hFunc(TEvTabletPipe::TEvClientConnected, TBase::Handle);
+ cFunc(TEvents::TSystem::Wakeup, HandleTimeout);
+ }
+ }
+
+ void Handle(NConsole::TEvConsole::TEvListTenantsResponse::TPtr& ev) {
Ydb::Cms::ListDatabasesResult listTenantsResult;
ev->Get()->Record.GetResponse().operation().result().UnpackTo(&listTenantsResult);
- for (const TString& path : listTenantsResult.paths()) {
- NKikimrViewer::TTenant& tenant = *Result.AddTenants();
- tenant.SetName(path);
- TenantIndex[path] = &tenant;
- if (State) {
- RequestConsoleGetTenantStatus(path);
- }
- }
- RequestDone();
- }
-
- void Handle(NConsole::TEvConsole::TEvGetTenantStatusResponse::TPtr& ev) {
+ for (const TString& path : listTenantsResult.paths()) {
+ NKikimrViewer::TTenant& tenant = *Result.AddTenants();
+ tenant.SetName(path);
+ TenantIndex[path] = &tenant;
+ if (State) {
+ RequestConsoleGetTenantStatus(path);
+ }
+ }
+ RequestDone();
+ }
+
+ void Handle(NConsole::TEvConsole::TEvGetTenantStatusResponse::TPtr& ev) {
Ydb::Cms::GetDatabaseStatusResult getTenantStatusResult;
ev->Get()->Record.GetResponse().operation().result().UnpackTo(&getTenantStatusResult);
- auto itTenant = TenantIndex.find(getTenantStatusResult.path());
- if (itTenant != TenantIndex.end()) {
- NKikimrViewer::TTenant& tenant = *itTenant->second;
- tenant.SetState(getTenantStatusResult.state());
- }
- RequestDone();
- }
-
- void ReplyAndPassAway() {
- TStringStream json;
- TProtoToJson::ProtoToJson(json, Result, JsonSettings);
- Send(Event->Sender, new NMon::TEvHttpInfoRes(Viewer->GetHTTPOKJSON() + json.Str(), 0, NMon::IEvHttpInfoRes::EContentType::Custom));
- PassAway();
- }
-
- void HandleTimeout() {
- Send(Event->Sender, new NMon::TEvHttpInfoRes(Viewer->GetHTTPGATEWAYTIMEOUT(), 0, NMon::IEvHttpInfoRes::EContentType::Custom));
- PassAway();
- }
-};
-
-template <>
-struct TJsonRequestSchema<TJsonTenants> {
- static TString GetSchema() {
- TStringStream stream;
- TProtoToJson::ProtoToJsonSchema<NConsole::TEvConsole::TEvListTenantsResponse::ProtoRecordType>(stream);
- return stream.Str();
- }
-};
-
-template <>
-struct TJsonRequestParameters<TJsonTenants> {
- static TString GetParameters() {
- return R"___([{"name":"enums","in":"query","description":"convert enums to strings","required":false,"type":"boolean"},
- {"name":"ui64","in":"query","description":"return ui64 as number","required":false,"type":"boolean"},
- {"name":"state","in":"query","description":"return tenant state","required":false,"type":"boolean","default":true},
- {"name":"timeout","in":"query","description":"timeout in ms","required":false,"type":"integer"}])___";
- }
-};
-
-template <>
-struct TJsonRequestSummary<TJsonTenants> {
- static TString GetSummary() {
- return "\"Tenant info (brief)\"";
- }
-};
-
-template <>
-struct TJsonRequestDescription<TJsonTenants> {
- static TString GetDescription() {
- return "\"Returns list of tenants\"";
- }
-};
-
-}
-}
+ auto itTenant = TenantIndex.find(getTenantStatusResult.path());
+ if (itTenant != TenantIndex.end()) {
+ NKikimrViewer::TTenant& tenant = *itTenant->second;
+ tenant.SetState(getTenantStatusResult.state());
+ }
+ RequestDone();
+ }
+
+ void ReplyAndPassAway() {
+ TStringStream json;
+ TProtoToJson::ProtoToJson(json, Result, JsonSettings);
+ Send(Event->Sender, new NMon::TEvHttpInfoRes(Viewer->GetHTTPOKJSON() + json.Str(), 0, NMon::IEvHttpInfoRes::EContentType::Custom));
+ PassAway();
+ }
+
+ void HandleTimeout() {
+ Send(Event->Sender, new NMon::TEvHttpInfoRes(Viewer->GetHTTPGATEWAYTIMEOUT(), 0, NMon::IEvHttpInfoRes::EContentType::Custom));
+ PassAway();
+ }
+};
+
+template <>
+struct TJsonRequestSchema<TJsonTenants> {
+ static TString GetSchema() {
+ TStringStream stream;
+ TProtoToJson::ProtoToJsonSchema<NConsole::TEvConsole::TEvListTenantsResponse::ProtoRecordType>(stream);
+ return stream.Str();
+ }
+};
+
+template <>
+struct TJsonRequestParameters<TJsonTenants> {
+ static TString GetParameters() {
+ return R"___([{"name":"enums","in":"query","description":"convert enums to strings","required":false,"type":"boolean"},
+ {"name":"ui64","in":"query","description":"return ui64 as number","required":false,"type":"boolean"},
+ {"name":"state","in":"query","description":"return tenant state","required":false,"type":"boolean","default":true},
+ {"name":"timeout","in":"query","description":"timeout in ms","required":false,"type":"integer"}])___";
+ }
+};
+
+template <>
+struct TJsonRequestSummary<TJsonTenants> {
+ static TString GetSummary() {
+ return "\"Tenant info (brief)\"";
+ }
+};
+
+template <>
+struct TJsonRequestDescription<TJsonTenants> {
+ static TString GetDescription() {
+ return "\"Returns list of tenants\"";
+ }
+};
+
+}
+}
diff --git a/ydb/core/viewer/json_topicinfo.h b/ydb/core/viewer/json_topicinfo.h
index 2610de61fee..cbf42ee7279 100644
--- a/ydb/core/viewer/json_topicinfo.h
+++ b/ydb/core/viewer/json_topicinfo.h
@@ -14,13 +14,13 @@ using namespace NActors;
class TJsonTopicInfo : public TActorBootstrapped<TJsonTopicInfo> {
using TBase = TActorBootstrapped<TJsonTopicInfo>;
- IViewer* Viewer;
+ IViewer* Viewer;
NMon::TEvHttpInfo::TPtr Event;
NKikimrTabletCountersAggregator::TEvTabletLabeledCountersResponse TopicInfoResult;
TJsonSettings JsonSettings;
TString Topic;
TString Client;
- TString GroupNames;
+ TString GroupNames;
bool ShowAll = false;
ui32 Timeout = 0;
@@ -29,9 +29,9 @@ public:
return NKikimrServices::TActivity::VIEWER_HANDLER;
}
- TJsonTopicInfo(IViewer* viewer, NMon::TEvHttpInfo::TPtr &ev)
- : Viewer(viewer)
- , Event(ev)
+ TJsonTopicInfo(IViewer* viewer, NMon::TEvHttpInfo::TPtr &ev)
+ : Viewer(viewer)
+ , Event(ev)
{}
void Bootstrap(const TActorContext& ctx) {
@@ -41,7 +41,7 @@ public:
Timeout = FromStringWithDefault<ui32>(params.Get("timeout"), 10000);
Topic = params.Get("path");
Client = params.Has("client") ? params.Get("client") : "total";
- GroupNames = params.Get("group_names");
+ GroupNames = params.Get("group_names");
ShowAll = FromStringWithDefault<bool>(params.Get("all"), false);
size_t pos = Topic.rfind('/');
if (pos != TString::npos)
@@ -64,15 +64,15 @@ public:
}
void Handle(TEvTabletCounters::TEvTabletLabeledCountersResponse::TPtr &ev, const TActorContext &ctx) {
- TString groupPrefix = Client + "/";
- TString groupSuffix = "/" + Topic;
+ TString groupPrefix = Client + "/";
+ TString groupSuffix = "/" + Topic;
for (ui32 i = 0; i < ev->Get()->Record.LabeledCountersByGroupSize(); ++i) {
const auto& uc = ev->Get()->Record.GetLabeledCountersByGroup(i);
- const TString& group(uc.GetGroup());
- if (ShowAll
- || (group.StartsWith(groupPrefix) && group.EndsWith(groupSuffix))
- || uc.GetGroup() == Topic
- || uc.GetGroupNames() == GroupNames) {
+ const TString& group(uc.GetGroup());
+ if (ShowAll
+ || (group.StartsWith(groupPrefix) && group.EndsWith(groupSuffix))
+ || uc.GetGroup() == Topic
+ || uc.GetGroupNames() == GroupNames) {
TopicInfoResult.AddLabeledCountersByGroup()->CopyFrom(uc);
}
}
@@ -81,13 +81,13 @@ public:
void ReplyAndDie(const TActorContext &ctx) {
TStringStream json;
- TProtoToJson::ProtoToJson(json, TopicInfoResult, JsonSettings);
- ctx.Send(Event->Sender, new NMon::TEvHttpInfoRes(Viewer->GetHTTPOKJSON() + json.Str(), 0, NMon::IEvHttpInfoRes::EContentType::Custom));
+ TProtoToJson::ProtoToJson(json, TopicInfoResult, JsonSettings);
+ ctx.Send(Event->Sender, new NMon::TEvHttpInfoRes(Viewer->GetHTTPOKJSON() + json.Str(), 0, NMon::IEvHttpInfoRes::EContentType::Custom));
Die(ctx);
}
void HandleTimeout(const TActorContext &ctx) {
- ctx.Send(Event->Sender, new NMon::TEvHttpInfoRes(Viewer->GetHTTPGATEWAYTIMEOUT(), 0, NMon::IEvHttpInfoRes::EContentType::Custom));
+ ctx.Send(Event->Sender, new NMon::TEvHttpInfoRes(Viewer->GetHTTPGATEWAYTIMEOUT(), 0, NMon::IEvHttpInfoRes::EContentType::Custom));
Die(ctx);
}
};
@@ -96,7 +96,7 @@ template <>
struct TJsonRequestSchema<TJsonTopicInfo> {
static TString GetSchema() {
TStringStream stream;
- TProtoToJson::ProtoToJsonSchema<TEvTabletCounters::TEvTabletLabeledCountersResponse::ProtoRecordType>(stream);
+ TProtoToJson::ProtoToJsonSchema<TEvTabletCounters::TEvTabletLabeledCountersResponse::ProtoRecordType>(stream);
return stream.Str();
}
};
@@ -104,26 +104,26 @@ struct TJsonRequestSchema<TJsonTopicInfo> {
template <>
struct TJsonRequestParameters<TJsonTopicInfo> {
static TString GetParameters() {
- return R"___([{"name":"path","in":"query","description":"schema path","required":true,"type":"string"},
- {"name":"client","in":"query","description":"client name","required":false,"type":"string","default":"total"},
- {"name":"enums","in":"query","description":"convert enums to strings","required":false,"type":"boolean"},
- {"name":"all","in":"query","description":"return all topics and all clients","required":false,"type":"boolean","default":false},
- {"name":"ui64","in":"query","description":"return ui64 as number","required":false,"type":"boolean"},
- {"name":"timeout","in":"query","description":"timeout in ms","required":false,"type":"integer",default:10000}])___";
+ return R"___([{"name":"path","in":"query","description":"schema path","required":true,"type":"string"},
+ {"name":"client","in":"query","description":"client name","required":false,"type":"string","default":"total"},
+ {"name":"enums","in":"query","description":"convert enums to strings","required":false,"type":"boolean"},
+ {"name":"all","in":"query","description":"return all topics and all clients","required":false,"type":"boolean","default":false},
+ {"name":"ui64","in":"query","description":"return ui64 as number","required":false,"type":"boolean"},
+ {"name":"timeout","in":"query","description":"timeout in ms","required":false,"type":"integer",default:10000}])___";
}
};
template <>
struct TJsonRequestSummary<TJsonTopicInfo> {
static TString GetSummary() {
- return "\"PQ topic information\"";
+ return "\"PQ topic information\"";
}
};
template <>
struct TJsonRequestDescription<TJsonTopicInfo> {
static TString GetDescription() {
- return "\"Information about PQ topic\"";
+ return "\"Information about PQ topic\"";
}
};
diff --git a/ydb/core/viewer/json_vdiskinfo.h b/ydb/core/viewer/json_vdiskinfo.h
index f394c419cef..db681f044b5 100644
--- a/ydb/core/viewer/json_vdiskinfo.h
+++ b/ydb/core/viewer/json_vdiskinfo.h
@@ -1,95 +1,95 @@
-#pragma once
+#pragma once
#include <library/cpp/actors/core/actor_bootstrapped.h>
#include <library/cpp/actors/core/interconnect.h>
#include <library/cpp/actors/core/mon.h>
#include <ydb/core/protos/services.pb.h>
#include <ydb/core/node_whiteboard/node_whiteboard.h>
#include <ydb/core/util/tuples.h>
-#include "json_wb_req.h"
-
-namespace std {
-
-template <>
-struct equal_to<NKikimrBlobStorage::TVDiskID> {
- static decltype(auto) make_tuple(const NKikimrBlobStorage::TVDiskID& id) {
- return std::make_tuple(
- id.GetGroupID(),
- id.GetGroupGeneration(),
- id.GetRing(),
- id.GetDomain(),
- id.GetVDisk()
- );
- }
-
- bool operator ()(const NKikimrBlobStorage::TVDiskID& a, const NKikimrBlobStorage::TVDiskID& b) const {
- return make_tuple(a) == make_tuple(b);
- }
-};
-
-template <>
-struct less<NKikimrBlobStorage::TVDiskID> {
- bool operator ()(const NKikimrBlobStorage::TVDiskID& a, const NKikimrBlobStorage::TVDiskID& b) const {
- return equal_to<NKikimrBlobStorage::TVDiskID>::make_tuple(a) < equal_to<NKikimrBlobStorage::TVDiskID>::make_tuple(b);
- }
-};
-
-template <>
-struct hash<NKikimrBlobStorage::TVDiskID> {
- size_t operator ()(const NKikimrBlobStorage::TVDiskID& a) const {
- auto tp = equal_to<NKikimrBlobStorage::TVDiskID>::make_tuple(a);
- return hash<decltype(tp)>()(tp);
- }
-};
-
-}
-
-namespace NKikimr {
-namespace NViewer {
-
-template <>
-struct TWhiteboardInfo<TEvWhiteboard::TEvVDiskStateResponse> {
- using TResponseType = TEvWhiteboard::TEvVDiskStateResponse;
- using TElementType = NKikimrWhiteboard::TVDiskStateInfo;
- using TElementKeyType = NKikimrBlobStorage::TVDiskID;
-
- static constexpr bool StaticNodesOnly = true;
-
- static ::google::protobuf::RepeatedPtrField<TElementType>* GetElementsField(TResponseType* response) {
- return response->Record.MutableVDiskStateInfo();
- }
-
- static const NKikimrBlobStorage::TVDiskID& GetElementKey(const TElementType& type) {
- return type.GetVDiskId();
- }
-
- static TString GetDefaultMergeField() {
- return "VDiskId";
- }
-
- static THolder<TResponseType> MergeResponses(TMap<ui32, THolder<TResponseType>>& responses, const TString& fields = GetDefaultMergeField()) {
- if (fields == GetDefaultMergeField()) {
- return TWhiteboardMerger<TResponseType>::MergeResponsesElementKey(responses);
- } else {
- return TWhiteboardMerger<TResponseType>::MergeResponses(responses, fields);
- }
- }
-};
-
-using TJsonVDiskInfo = TJsonWhiteboardRequest<TEvWhiteboard::TEvVDiskStateRequest, TEvWhiteboard::TEvVDiskStateResponse>;
-
-template <>
-struct TJsonRequestSummary<TJsonVDiskInfo> {
+#include "json_wb_req.h"
+
+namespace std {
+
+template <>
+struct equal_to<NKikimrBlobStorage::TVDiskID> {
+ static decltype(auto) make_tuple(const NKikimrBlobStorage::TVDiskID& id) {
+ return std::make_tuple(
+ id.GetGroupID(),
+ id.GetGroupGeneration(),
+ id.GetRing(),
+ id.GetDomain(),
+ id.GetVDisk()
+ );
+ }
+
+ bool operator ()(const NKikimrBlobStorage::TVDiskID& a, const NKikimrBlobStorage::TVDiskID& b) const {
+ return make_tuple(a) == make_tuple(b);
+ }
+};
+
+template <>
+struct less<NKikimrBlobStorage::TVDiskID> {
+ bool operator ()(const NKikimrBlobStorage::TVDiskID& a, const NKikimrBlobStorage::TVDiskID& b) const {
+ return equal_to<NKikimrBlobStorage::TVDiskID>::make_tuple(a) < equal_to<NKikimrBlobStorage::TVDiskID>::make_tuple(b);
+ }
+};
+
+template <>
+struct hash<NKikimrBlobStorage::TVDiskID> {
+ size_t operator ()(const NKikimrBlobStorage::TVDiskID& a) const {
+ auto tp = equal_to<NKikimrBlobStorage::TVDiskID>::make_tuple(a);
+ return hash<decltype(tp)>()(tp);
+ }
+};
+
+}
+
+namespace NKikimr {
+namespace NViewer {
+
+template <>
+struct TWhiteboardInfo<TEvWhiteboard::TEvVDiskStateResponse> {
+ using TResponseType = TEvWhiteboard::TEvVDiskStateResponse;
+ using TElementType = NKikimrWhiteboard::TVDiskStateInfo;
+ using TElementKeyType = NKikimrBlobStorage::TVDiskID;
+
+ static constexpr bool StaticNodesOnly = true;
+
+ static ::google::protobuf::RepeatedPtrField<TElementType>* GetElementsField(TResponseType* response) {
+ return response->Record.MutableVDiskStateInfo();
+ }
+
+ static const NKikimrBlobStorage::TVDiskID& GetElementKey(const TElementType& type) {
+ return type.GetVDiskId();
+ }
+
+ static TString GetDefaultMergeField() {
+ return "VDiskId";
+ }
+
+ static THolder<TResponseType> MergeResponses(TMap<ui32, THolder<TResponseType>>& responses, const TString& fields = GetDefaultMergeField()) {
+ if (fields == GetDefaultMergeField()) {
+ return TWhiteboardMerger<TResponseType>::MergeResponsesElementKey(responses);
+ } else {
+ return TWhiteboardMerger<TResponseType>::MergeResponses(responses, fields);
+ }
+ }
+};
+
+using TJsonVDiskInfo = TJsonWhiteboardRequest<TEvWhiteboard::TEvVDiskStateRequest, TEvWhiteboard::TEvVDiskStateResponse>;
+
+template <>
+struct TJsonRequestSummary<TJsonVDiskInfo> {
static TString GetSummary() {
- return "\"VDisk information\"";
- }
-};
-
-template <>
-struct TJsonRequestDescription<TJsonVDiskInfo> {
+ return "\"VDisk information\"";
+ }
+};
+
+template <>
+struct TJsonRequestDescription<TJsonVDiskInfo> {
static TString GetDescription() {
- return "\"VDisk information\"";
- }
-};
-
-}
-}
+ return "\"VDisk information\"";
+ }
+};
+
+}
+}
diff --git a/ydb/core/viewer/json_wb_req.h b/ydb/core/viewer/json_wb_req.h
index 392a85e2e43..f04c85688f4 100644
--- a/ydb/core/viewer/json_wb_req.h
+++ b/ydb/core/viewer/json_wb_req.h
@@ -1,394 +1,394 @@
-#pragma once
+#pragma once
#include <library/cpp/actors/core/actor_bootstrapped.h>
#include <library/cpp/actors/core/interconnect.h>
#include <library/cpp/actors/core/mon.h>
#include <ydb/core/protos/services.pb.h>
#include <ydb/core/node_whiteboard/node_whiteboard.h>
#include <ydb/core/viewer/json/json.h>
-#include "viewer.h"
-#include "json_pipe_req.h"
-#include "wb_merge.h"
-#include "wb_group.h"
-#include "wb_filter.h"
-
-namespace NKikimr {
-namespace NViewer {
-
-using namespace NActors;
-using namespace NNodeWhiteboard;
-
-struct TEvPrivate {
- enum EEv {
- EvRetryNodeRequest = EventSpaceBegin(NActors::TEvents::ES_PRIVATE),
- EvEnd
- };
-
- static_assert(EvEnd < EventSpaceEnd(NActors::TEvents::ES_PRIVATE), "expect EvEnd < EventSpaceEnd(TEvents::ES_PRIVATE)");
-
- struct TEvRetryNodeRequest : NActors::TEventLocal<TEvRetryNodeRequest, EvRetryNodeRequest> {
- TNodeId NodeId;
-
- TEvRetryNodeRequest(TNodeId nodeId)
- : NodeId(nodeId)
- {}
- };
-};
-
-template <typename RequestType, typename ResponseType>
-class TJsonWhiteboardRequest : public TViewerPipeClient<TJsonWhiteboardRequest<RequestType, ResponseType>> {
-protected:
- using TThis = TJsonWhiteboardRequest<RequestType, ResponseType>;
- using TBase = TViewerPipeClient<TThis>;
- IViewer* Viewer;
+#include "viewer.h"
+#include "json_pipe_req.h"
+#include "wb_merge.h"
+#include "wb_group.h"
+#include "wb_filter.h"
+
+namespace NKikimr {
+namespace NViewer {
+
+using namespace NActors;
+using namespace NNodeWhiteboard;
+
+struct TEvPrivate {
+ enum EEv {
+ EvRetryNodeRequest = EventSpaceBegin(NActors::TEvents::ES_PRIVATE),
+ EvEnd
+ };
+
+ static_assert(EvEnd < EventSpaceEnd(NActors::TEvents::ES_PRIVATE), "expect EvEnd < EventSpaceEnd(TEvents::ES_PRIVATE)");
+
+ struct TEvRetryNodeRequest : NActors::TEventLocal<TEvRetryNodeRequest, EvRetryNodeRequest> {
+ TNodeId NodeId;
+
+ TEvRetryNodeRequest(TNodeId nodeId)
+ : NodeId(nodeId)
+ {}
+ };
+};
+
+template <typename RequestType, typename ResponseType>
+class TJsonWhiteboardRequest : public TViewerPipeClient<TJsonWhiteboardRequest<RequestType, ResponseType>> {
+protected:
+ using TThis = TJsonWhiteboardRequest<RequestType, ResponseType>;
+ using TBase = TViewerPipeClient<TThis>;
+ IViewer* Viewer;
TActorId Initiator;
- NMon::TEvHttpInfo::TPtr Event;
- std::vector<TNodeId> FilterNodeIds;
- ui64 ChangedSince;
- bool AliveOnly = false;
- std::unordered_set<TNodeId> NodeIds;
- TMap<TNodeId, THolder<ResponseType>> PerNodeStateInfo; // map instead of unordered_map only for sorting reason
- std::unordered_map<TNodeId, TString> NodeErrors;
- TInstant NodesRequestedTime;
+ NMon::TEvHttpInfo::TPtr Event;
+ std::vector<TNodeId> FilterNodeIds;
+ ui64 ChangedSince;
+ bool AliveOnly = false;
+ std::unordered_set<TNodeId> NodeIds;
+ TMap<TNodeId, THolder<ResponseType>> PerNodeStateInfo; // map instead of unordered_map only for sorting reason
+ std::unordered_map<TNodeId, TString> NodeErrors;
+ TInstant NodesRequestedTime;
TString GroupFields;
TString FilterFields;
- TString MergeFields;
- TJsonSettings JsonSettings;
+ TString MergeFields;
+ TJsonSettings JsonSettings;
bool AllEnums = false;
ui32 Timeout = 0;
ui32 Retries = 0;
- std::unordered_map<TNodeId, ui32> NodeRetries;
- bool StaticNodesOnly = TWhiteboardInfo<ResponseType>::StaticNodesOnly;
- TDuration RetryPeriod = TDuration::MilliSeconds(500);
-
-public:
+ std::unordered_map<TNodeId, ui32> NodeRetries;
+ bool StaticNodesOnly = TWhiteboardInfo<ResponseType>::StaticNodesOnly;
+ TDuration RetryPeriod = TDuration::MilliSeconds(500);
+
+public:
static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
return NKikimrServices::TActivity::VIEWER_HANDLER;
- }
-
- TJsonWhiteboardRequest(IViewer* viewer, NMon::TEvHttpInfo::TPtr& ev)
- : Viewer(viewer)
- , Initiator(ev->Sender)
- , Event(ev)
- {}
-
- THolder<RequestType> BuildRequest(TNodeId nodeId) {
- Y_UNUSED(nodeId);
+ }
+
+ TJsonWhiteboardRequest(IViewer* viewer, NMon::TEvHttpInfo::TPtr& ev)
+ : Viewer(viewer)
+ , Initiator(ev->Sender)
+ , Event(ev)
+ {}
+
+ THolder<RequestType> BuildRequest(TNodeId nodeId) {
+ Y_UNUSED(nodeId);
THolder<RequestType> request = MakeHolder<RequestType>();
- if (ChangedSince != 0) {
- request->Record.SetChangedSince(ChangedSince);
- }
- return request;
- }
-
- void SendNodeRequest(TNodeId nodeId) {
+ if (ChangedSince != 0) {
+ request->Record.SetChangedSince(ChangedSince);
+ }
+ return request;
+ }
+
+ void SendNodeRequest(TNodeId nodeId) {
TActorId whiteboardServiceId = MakeNodeWhiteboardServiceId(nodeId);
- THolder<RequestType> request = BuildRequest(nodeId);
- TBase::SendRequest(whiteboardServiceId, request.Release(), IEventHandle::FlagTrackDelivery | IEventHandle::FlagSubscribeOnSession, nodeId);
- NodeIds.insert(nodeId);
- }
-
- void SendNodeRequest(const std::vector<TNodeId> nodeIds) {
- for (TNodeId nodeId : nodeIds) {
- SendNodeRequest(nodeId);
- }
- }
-
- void PassAway() override {
- for (const TNodeId nodeId : NodeIds) {
- TBase::Send(TActivationContext::InterconnectProxy(nodeId), new TEvents::TEvUnsubscribe());
- }
- TBase::PassAway();
- }
-
- virtual void Bootstrap() {
+ THolder<RequestType> request = BuildRequest(nodeId);
+ TBase::SendRequest(whiteboardServiceId, request.Release(), IEventHandle::FlagTrackDelivery | IEventHandle::FlagSubscribeOnSession, nodeId);
+ NodeIds.insert(nodeId);
+ }
+
+ void SendNodeRequest(const std::vector<TNodeId> nodeIds) {
+ for (TNodeId nodeId : nodeIds) {
+ SendNodeRequest(nodeId);
+ }
+ }
+
+ void PassAway() override {
+ for (const TNodeId nodeId : NodeIds) {
+ TBase::Send(TActivationContext::InterconnectProxy(nodeId), new TEvents::TEvUnsubscribe());
+ }
+ TBase::PassAway();
+ }
+
+ virtual void Bootstrap() {
const auto& params(Event->Get()->Request.GetParams());
- TBase::InitConfig(params);
- SplitIds(params.Get("node_id"), ',', FilterNodeIds);
- std::replace(FilterNodeIds.begin(), FilterNodeIds.end(), (ui32)0, TlsActivationContext->ActorSystem()->NodeId);
- {
- TString merge = params.Get("merge");
- if (merge.empty() || merge == "1" || merge == "true") {
- MergeFields = TWhiteboardInfo<ResponseType>::GetDefaultMergeField();
- } else if (merge == "0" || merge == "false") {
- MergeFields.clear();
- } else {
- MergeFields = merge;
- }
- }
- ChangedSince = FromStringWithDefault<ui64>(params.Get("since"), 0);
- AliveOnly = FromStringWithDefault<bool>(params.Get("alive"), AliveOnly);
- GroupFields = params.Get("group");
- FilterFields = params.Get("filter");
- JsonSettings.EnumAsNumbers = !FromStringWithDefault<bool>(params.Get("enums"), false);
- JsonSettings.UI64AsString = !FromStringWithDefault<bool>(params.Get("ui64"), false);
- JsonSettings.EmptyRepeated = FromStringWithDefault<bool>(params.Get("empty_repeated"), false);
- AllEnums = FromStringWithDefault<bool>(params.Get("all"), false);
- Timeout = FromStringWithDefault<ui32>(params.Get("timeout"), 10000);
- Retries = FromStringWithDefault<ui32>(params.Get("retries"), 0);
- RetryPeriod = TDuration::MilliSeconds(FromStringWithDefault<ui32>(params.Get("retry_period"), RetryPeriod.MilliSeconds()));
- StaticNodesOnly = FromStringWithDefault<bool>(params.Get("static"), StaticNodesOnly);
- if (FilterNodeIds.empty()) {
- if (AliveOnly) {
- static const TActorId whiteboardServiceId = MakeNodeWhiteboardServiceId(TBase::SelfId().NodeId());
- TBase::SendRequest(whiteboardServiceId, new TEvWhiteboard::TEvNodeStateRequest());
- } else {
+ TBase::InitConfig(params);
+ SplitIds(params.Get("node_id"), ',', FilterNodeIds);
+ std::replace(FilterNodeIds.begin(), FilterNodeIds.end(), (ui32)0, TlsActivationContext->ActorSystem()->NodeId);
+ {
+ TString merge = params.Get("merge");
+ if (merge.empty() || merge == "1" || merge == "true") {
+ MergeFields = TWhiteboardInfo<ResponseType>::GetDefaultMergeField();
+ } else if (merge == "0" || merge == "false") {
+ MergeFields.clear();
+ } else {
+ MergeFields = merge;
+ }
+ }
+ ChangedSince = FromStringWithDefault<ui64>(params.Get("since"), 0);
+ AliveOnly = FromStringWithDefault<bool>(params.Get("alive"), AliveOnly);
+ GroupFields = params.Get("group");
+ FilterFields = params.Get("filter");
+ JsonSettings.EnumAsNumbers = !FromStringWithDefault<bool>(params.Get("enums"), false);
+ JsonSettings.UI64AsString = !FromStringWithDefault<bool>(params.Get("ui64"), false);
+ JsonSettings.EmptyRepeated = FromStringWithDefault<bool>(params.Get("empty_repeated"), false);
+ AllEnums = FromStringWithDefault<bool>(params.Get("all"), false);
+ Timeout = FromStringWithDefault<ui32>(params.Get("timeout"), 10000);
+ Retries = FromStringWithDefault<ui32>(params.Get("retries"), 0);
+ RetryPeriod = TDuration::MilliSeconds(FromStringWithDefault<ui32>(params.Get("retry_period"), RetryPeriod.MilliSeconds()));
+ StaticNodesOnly = FromStringWithDefault<bool>(params.Get("static"), StaticNodesOnly);
+ if (FilterNodeIds.empty()) {
+ if (AliveOnly) {
+ static const TActorId whiteboardServiceId = MakeNodeWhiteboardServiceId(TBase::SelfId().NodeId());
+ TBase::SendRequest(whiteboardServiceId, new TEvWhiteboard::TEvNodeStateRequest());
+ } else {
const TActorId nameserviceId = GetNameserviceActorId();
- TBase::Send(nameserviceId, new TEvInterconnect::TEvListNodes());
- }
- TBase::Become(&TThis::StateRequestedBrowse);
- } else {
- NodesRequestedTime = AppData()->TimeProvider->Now();
- SendNodeRequest(FilterNodeIds);
- TBase::Become(&TThis::StateRequestedNodeInfo);
- }
- TBase::Schedule(TDuration::MilliSeconds(Timeout), new TEvents::TEvWakeup());
- }
-
- STATEFN(StateRequestedBrowse) {
- switch (ev->GetTypeRewrite()) {
- hFunc(TEvInterconnect::TEvNodesInfo, HandleBrowse);
- hFunc(TEvPrivate::TEvRetryNodeRequest, HandleRetryNode);
- hFunc(TEvWhiteboard::TEvNodeStateResponse, HandleBrowse);
- cFunc(TEvents::TSystem::Wakeup, HandleTimeout);
- }
- }
-
- STATEFN(StateRequestedNodeInfo) {
- switch (ev->GetTypeRewrite()) {
- hFunc(ResponseType, HandleNodeInfo);
- hFunc(TEvPrivate::TEvRetryNodeRequest, HandleRetryNode);
- hFunc(TEvents::TEvUndelivered, Undelivered);
- hFunc(TEvInterconnect::TEvNodeDisconnected, Disconnected);
- cFunc(TEvents::TSystem::Wakeup, HandleTimeout);
- }
- }
-
- void HandleBrowse(TEvInterconnect::TEvNodesInfo::TPtr& ev) {
- ui32 maxAllowedNodeId = std::numeric_limits<ui32>::max();
- if (StaticNodesOnly) {
- TIntrusivePtr<TDynamicNameserviceConfig> dynamicNameserviceConfig = AppData()->DynamicNameserviceConfig;
- if (dynamicNameserviceConfig) {
- maxAllowedNodeId = dynamicNameserviceConfig->MaxStaticNodeId;
- }
- }
- NodesRequestedTime = AppData()->TimeProvider->Now();
- const TEvInterconnect::TEvNodesInfo* nodesInfo = ev->Get();
- for (const auto& ni : nodesInfo->Nodes) {
- if (ni.NodeId <= maxAllowedNodeId) {
- SendNodeRequest(ni.NodeId);
- }
- }
- if (TBase::Requests > 0) {
- TBase::Become(&TThis::StateRequestedNodeInfo);
- } else {
- ReplyAndPassAway();
- }
- }
-
- static TNodeId GetNodeIdFromPeerName(const TString& peerName) {
+ TBase::Send(nameserviceId, new TEvInterconnect::TEvListNodes());
+ }
+ TBase::Become(&TThis::StateRequestedBrowse);
+ } else {
+ NodesRequestedTime = AppData()->TimeProvider->Now();
+ SendNodeRequest(FilterNodeIds);
+ TBase::Become(&TThis::StateRequestedNodeInfo);
+ }
+ TBase::Schedule(TDuration::MilliSeconds(Timeout), new TEvents::TEvWakeup());
+ }
+
+ STATEFN(StateRequestedBrowse) {
+ switch (ev->GetTypeRewrite()) {
+ hFunc(TEvInterconnect::TEvNodesInfo, HandleBrowse);
+ hFunc(TEvPrivate::TEvRetryNodeRequest, HandleRetryNode);
+ hFunc(TEvWhiteboard::TEvNodeStateResponse, HandleBrowse);
+ cFunc(TEvents::TSystem::Wakeup, HandleTimeout);
+ }
+ }
+
+ STATEFN(StateRequestedNodeInfo) {
+ switch (ev->GetTypeRewrite()) {
+ hFunc(ResponseType, HandleNodeInfo);
+ hFunc(TEvPrivate::TEvRetryNodeRequest, HandleRetryNode);
+ hFunc(TEvents::TEvUndelivered, Undelivered);
+ hFunc(TEvInterconnect::TEvNodeDisconnected, Disconnected);
+ cFunc(TEvents::TSystem::Wakeup, HandleTimeout);
+ }
+ }
+
+ void HandleBrowse(TEvInterconnect::TEvNodesInfo::TPtr& ev) {
+ ui32 maxAllowedNodeId = std::numeric_limits<ui32>::max();
+ if (StaticNodesOnly) {
+ TIntrusivePtr<TDynamicNameserviceConfig> dynamicNameserviceConfig = AppData()->DynamicNameserviceConfig;
+ if (dynamicNameserviceConfig) {
+ maxAllowedNodeId = dynamicNameserviceConfig->MaxStaticNodeId;
+ }
+ }
+ NodesRequestedTime = AppData()->TimeProvider->Now();
+ const TEvInterconnect::TEvNodesInfo* nodesInfo = ev->Get();
+ for (const auto& ni : nodesInfo->Nodes) {
+ if (ni.NodeId <= maxAllowedNodeId) {
+ SendNodeRequest(ni.NodeId);
+ }
+ }
+ if (TBase::Requests > 0) {
+ TBase::Become(&TThis::StateRequestedNodeInfo);
+ } else {
+ ReplyAndPassAway();
+ }
+ }
+
+ static TNodeId GetNodeIdFromPeerName(const TString& peerName) {
TString::size_type colonPos = peerName.find(':');
if (colonPos != TString::npos) {
- return FromStringWithDefault<TNodeId>(peerName.substr(0, colonPos), 0);
- }
- return 0;
- }
-
- void HandleBrowse(TEvWhiteboard::TEvNodeStateResponse::TPtr& ev) {
- TNodeId maxAllowedNodeId = std::numeric_limits<TNodeId>::max();
- if (StaticNodesOnly) {
- TIntrusivePtr<TDynamicNameserviceConfig> dynamicNameserviceConfig = AppData()->DynamicNameserviceConfig;
- if (dynamicNameserviceConfig) {
- maxAllowedNodeId = dynamicNameserviceConfig->MaxStaticNodeId;
- }
- }
- NodesRequestedTime = AppData()->TimeProvider->Now();
+ return FromStringWithDefault<TNodeId>(peerName.substr(0, colonPos), 0);
+ }
+ return 0;
+ }
+
+ void HandleBrowse(TEvWhiteboard::TEvNodeStateResponse::TPtr& ev) {
+ TNodeId maxAllowedNodeId = std::numeric_limits<TNodeId>::max();
+ if (StaticNodesOnly) {
+ TIntrusivePtr<TDynamicNameserviceConfig> dynamicNameserviceConfig = AppData()->DynamicNameserviceConfig;
+ if (dynamicNameserviceConfig) {
+ maxAllowedNodeId = dynamicNameserviceConfig->MaxStaticNodeId;
+ }
+ }
+ NodesRequestedTime = AppData()->TimeProvider->Now();
const TEvWhiteboard::TEvNodeStateResponse* nodesInfo = ev->Get();
- for (const auto& ni : nodesInfo->Record.GetNodeStateInfo()) {
- if (ni.GetConnected()) {
- TNodeId nodeId = GetNodeIdFromPeerName(ni.GetPeerName());
- if (nodeId != 0 && nodeId <= maxAllowedNodeId) {
- SendNodeRequest(nodeId);
- }
- }
- }
- SendNodeRequest(TBase::SelfId().NodeId());
- if (TBase::Requests > 0) {
- TBase::Become(&TThis::StateRequestedNodeInfo);
- } else {
- ReplyAndPassAway();
- }
- }
-
- bool RetryRequest(TNodeId nodeId) {
- if (Retries) {
- if (++NodeRetries[nodeId] <= Retries) {
- TBase::Schedule(RetryPeriod, new TEvPrivate::TEvRetryNodeRequest(nodeId));
- return true;
- }
- }
- return false;
- }
-
- void Undelivered(TEvents::TEvUndelivered::TPtr& ev) {
- static const TString error = "Undelivered";
- TNodeId nodeId = ev.Get()->Cookie;
- if (PerNodeStateInfo.emplace(nodeId, nullptr).second) {
- NodeErrors[nodeId] = error;
- if (!RetryRequest(nodeId)) {
- TBase::RequestDone();
- }
- } else {
- if (NodeErrors[nodeId] == error) {
- if (!RetryRequest(nodeId)) {
- TBase::RequestDone();
- }
- }
- }
- }
-
- void Disconnected(TEvInterconnect::TEvNodeDisconnected::TPtr& ev) {
- static const TString error = "Node disconnected";
- TNodeId nodeId = ev->Get()->NodeId;
- if (PerNodeStateInfo.emplace(nodeId, nullptr).second) {
- NodeErrors[nodeId] = error;
- if (!RetryRequest(nodeId)) {
- TBase::RequestDone();
- }
- } else {
- if (NodeErrors[nodeId] == error) {
- if (!RetryRequest(nodeId)) {
- TBase::RequestDone();
- }
- }
- }
- }
-
- template <typename ResponseRecordType>
- void UpdateDuration(ResponseRecordType& record) {
- record.SetResponseDuration((AppData()->TimeProvider->Now() - NodesRequestedTime).MicroSeconds());
- }
-
- void HandleNodeInfo(typename ResponseType::TPtr& ev) {
- UpdateDuration(ev->Get()->Record);
- ui64 nodeId = ev.Get()->Cookie;
- PerNodeStateInfo[nodeId] = ev->Release();
- NodeErrors.erase(nodeId);
- TBase::RequestDone();
- }
-
- void HandleRetryNode(TEvPrivate::TEvRetryNodeRequest::TPtr& ev) {
- SendNodeRequest(ev->Get()->NodeId);
- TBase::RequestDone(); // previous, failed one
- }
-
- void HandleTimeout() {
- //ctx.Send(Initiator, new NMon::TEvHttpInfoRes(GetHTTPGATEWAYTIMEOUT(), 0, NMon::IEvHttpInfoRes::EContentType::Custom));
- //Die(ctx);
- ReplyAndPassAway();
- }
-
- virtual void FilterResponse(THolder<ResponseType>& response) {
- if (response != nullptr) {
- if (!FilterFields.empty()) {
- response = FilterWhiteboardResponses(response, FilterFields);
- }
- }
- if (response != nullptr) {
- if (!GroupFields.empty()) {
- response = GroupWhiteboardResponses(response, GroupFields, AllEnums);
- }
- }
- }
-
- void RenderResponse(TStringStream& json, const THolder<ResponseType>& response) {
- if (response != nullptr) {
- TProtoToJson::ProtoToJson(json, response->Record, JsonSettings);
- } else {
- json << "null";
- }
- }
-
- void ReplyAndPassAway() {
- try {
- TStringStream json;
- if (!MergeFields.empty()) {
- ui32 errors = 0;
- TString error;
- if (!FilterNodeIds.empty()) {
- for (TNodeId nodeId : FilterNodeIds) {
- auto it = NodeErrors.find(nodeId);
- if (it != NodeErrors.end()) {
- if (error.empty()) {
- error = it->second;
- }
- errors++;
- }
- }
- }
- if (errors > 0 && errors == FilterNodeIds.size()) {
- json << "{\"Error\":\"" << TProtoToJson::EscapeJsonString(error) << "\"}";
- } else {
- THolder<ResponseType> response = MergeWhiteboardResponses(PerNodeStateInfo, MergeFields); // PerNodeStateInfo will be invalidated
- FilterResponse(response);
- RenderResponse(json, response);
- }
- } else {
- json << '{';
- for (auto it = PerNodeStateInfo.begin(); it != PerNodeStateInfo.end(); ++it) {
- if (it != PerNodeStateInfo.begin()) {
- json << ',';
- }
- json << '"' << it->first << "\":";
- THolder<ResponseType>& response = it->second;
- if (response) {
- FilterResponse(response);
- RenderResponse(json, response);
- } else {
- auto itNodeError = NodeErrors.find(it->first);
- if (itNodeError != NodeErrors.end()) {
- json << "{\"Error\":\"" << TProtoToJson::EscapeJsonString(itNodeError->second) << "\"}";
- } else {
- json << "null";
- }
- }
- }
- json << '}';
- }
- TBase::Send(Initiator, new NMon::TEvHttpInfoRes(Viewer->GetHTTPOKJSON() + json.Str(), 0, NMon::IEvHttpInfoRes::EContentType::Custom));
- } catch (const std::exception& e) {
- TBase::Send(Initiator, new NMon::TEvHttpInfoRes(TString("HTTP/1.1 400 Bad Request\r\n\r\n") + e.what(), 0, NMon::IEvHttpInfoRes::EContentType::Custom));
- }
- PassAway();
- }
-};
-
-template <typename RequestType, typename ResponseType>
-struct TJsonRequestParameters<TJsonWhiteboardRequest<RequestType, ResponseType>> {
+ for (const auto& ni : nodesInfo->Record.GetNodeStateInfo()) {
+ if (ni.GetConnected()) {
+ TNodeId nodeId = GetNodeIdFromPeerName(ni.GetPeerName());
+ if (nodeId != 0 && nodeId <= maxAllowedNodeId) {
+ SendNodeRequest(nodeId);
+ }
+ }
+ }
+ SendNodeRequest(TBase::SelfId().NodeId());
+ if (TBase::Requests > 0) {
+ TBase::Become(&TThis::StateRequestedNodeInfo);
+ } else {
+ ReplyAndPassAway();
+ }
+ }
+
+ bool RetryRequest(TNodeId nodeId) {
+ if (Retries) {
+ if (++NodeRetries[nodeId] <= Retries) {
+ TBase::Schedule(RetryPeriod, new TEvPrivate::TEvRetryNodeRequest(nodeId));
+ return true;
+ }
+ }
+ return false;
+ }
+
+ void Undelivered(TEvents::TEvUndelivered::TPtr& ev) {
+ static const TString error = "Undelivered";
+ TNodeId nodeId = ev.Get()->Cookie;
+ if (PerNodeStateInfo.emplace(nodeId, nullptr).second) {
+ NodeErrors[nodeId] = error;
+ if (!RetryRequest(nodeId)) {
+ TBase::RequestDone();
+ }
+ } else {
+ if (NodeErrors[nodeId] == error) {
+ if (!RetryRequest(nodeId)) {
+ TBase::RequestDone();
+ }
+ }
+ }
+ }
+
+ void Disconnected(TEvInterconnect::TEvNodeDisconnected::TPtr& ev) {
+ static const TString error = "Node disconnected";
+ TNodeId nodeId = ev->Get()->NodeId;
+ if (PerNodeStateInfo.emplace(nodeId, nullptr).second) {
+ NodeErrors[nodeId] = error;
+ if (!RetryRequest(nodeId)) {
+ TBase::RequestDone();
+ }
+ } else {
+ if (NodeErrors[nodeId] == error) {
+ if (!RetryRequest(nodeId)) {
+ TBase::RequestDone();
+ }
+ }
+ }
+ }
+
+ template <typename ResponseRecordType>
+ void UpdateDuration(ResponseRecordType& record) {
+ record.SetResponseDuration((AppData()->TimeProvider->Now() - NodesRequestedTime).MicroSeconds());
+ }
+
+ void HandleNodeInfo(typename ResponseType::TPtr& ev) {
+ UpdateDuration(ev->Get()->Record);
+ ui64 nodeId = ev.Get()->Cookie;
+ PerNodeStateInfo[nodeId] = ev->Release();
+ NodeErrors.erase(nodeId);
+ TBase::RequestDone();
+ }
+
+ void HandleRetryNode(TEvPrivate::TEvRetryNodeRequest::TPtr& ev) {
+ SendNodeRequest(ev->Get()->NodeId);
+ TBase::RequestDone(); // previous, failed one
+ }
+
+ void HandleTimeout() {
+ //ctx.Send(Initiator, new NMon::TEvHttpInfoRes(GetHTTPGATEWAYTIMEOUT(), 0, NMon::IEvHttpInfoRes::EContentType::Custom));
+ //Die(ctx);
+ ReplyAndPassAway();
+ }
+
+ virtual void FilterResponse(THolder<ResponseType>& response) {
+ if (response != nullptr) {
+ if (!FilterFields.empty()) {
+ response = FilterWhiteboardResponses(response, FilterFields);
+ }
+ }
+ if (response != nullptr) {
+ if (!GroupFields.empty()) {
+ response = GroupWhiteboardResponses(response, GroupFields, AllEnums);
+ }
+ }
+ }
+
+ void RenderResponse(TStringStream& json, const THolder<ResponseType>& response) {
+ if (response != nullptr) {
+ TProtoToJson::ProtoToJson(json, response->Record, JsonSettings);
+ } else {
+ json << "null";
+ }
+ }
+
+ void ReplyAndPassAway() {
+ try {
+ TStringStream json;
+ if (!MergeFields.empty()) {
+ ui32 errors = 0;
+ TString error;
+ if (!FilterNodeIds.empty()) {
+ for (TNodeId nodeId : FilterNodeIds) {
+ auto it = NodeErrors.find(nodeId);
+ if (it != NodeErrors.end()) {
+ if (error.empty()) {
+ error = it->second;
+ }
+ errors++;
+ }
+ }
+ }
+ if (errors > 0 && errors == FilterNodeIds.size()) {
+ json << "{\"Error\":\"" << TProtoToJson::EscapeJsonString(error) << "\"}";
+ } else {
+ THolder<ResponseType> response = MergeWhiteboardResponses(PerNodeStateInfo, MergeFields); // PerNodeStateInfo will be invalidated
+ FilterResponse(response);
+ RenderResponse(json, response);
+ }
+ } else {
+ json << '{';
+ for (auto it = PerNodeStateInfo.begin(); it != PerNodeStateInfo.end(); ++it) {
+ if (it != PerNodeStateInfo.begin()) {
+ json << ',';
+ }
+ json << '"' << it->first << "\":";
+ THolder<ResponseType>& response = it->second;
+ if (response) {
+ FilterResponse(response);
+ RenderResponse(json, response);
+ } else {
+ auto itNodeError = NodeErrors.find(it->first);
+ if (itNodeError != NodeErrors.end()) {
+ json << "{\"Error\":\"" << TProtoToJson::EscapeJsonString(itNodeError->second) << "\"}";
+ } else {
+ json << "null";
+ }
+ }
+ }
+ json << '}';
+ }
+ TBase::Send(Initiator, new NMon::TEvHttpInfoRes(Viewer->GetHTTPOKJSON() + json.Str(), 0, NMon::IEvHttpInfoRes::EContentType::Custom));
+ } catch (const std::exception& e) {
+ TBase::Send(Initiator, new NMon::TEvHttpInfoRes(TString("HTTP/1.1 400 Bad Request\r\n\r\n") + e.what(), 0, NMon::IEvHttpInfoRes::EContentType::Custom));
+ }
+ PassAway();
+ }
+};
+
+template <typename RequestType, typename ResponseType>
+struct TJsonRequestParameters<TJsonWhiteboardRequest<RequestType, ResponseType>> {
static TString GetParameters() {
- return R"___([{"name":"node_id","in":"query","description":"node identifier","required":false,"type":"integer"},)___"
- R"___({"name":"merge","in":"query","description":"merge information from nodes","required":false,"type":"boolean"},)___"
- R"___({"name":"group","in":"query","description":"group information by field","required":false,"type":"string"},)___"
- R"___({"name":"all","in":"query","description":"return all possible key combinations (for enums only)","required":false,"type":"boolean"},)___"
- R"___({"name":"filter","in":"query","description":"filter information by field","required":false,"type":"string"},)___"
- R"___({"name":"alive","in":"query","description":"request from alive (connected) nodes only","required":false,"type":"boolean"},)___"
- R"___({"name":"enums","in":"query","description":"convert enums to strings","required":false,"type":"boolean"},)___"
- R"___({"name":"ui64","in":"query","description":"return ui64 as number","required":false,"type":"boolean"},)___"
- R"___({"name":"timeout","in":"query","description":"timeout in ms","required":false,"type":"integer"},)___"
- R"___({"name":"retries","in":"query","description":"number of retries","required":false,"type":"integer"},)___"
- R"___({"name":"retry_period","in":"query","description":"retry period in ms","required":false,"type":"integer","default":500},)___"
- R"___({"name":"static","in":"query","description":"request from static nodes only","required":false,"type":"boolean"},)___"
- R"___({"name":"since","in":"query","description":"filter by update time","required":false,"type":"string"}])___";
- }
-};
-
-template <typename RequestType, typename ResponseType>
-struct TJsonRequestSchema<TJsonWhiteboardRequest<RequestType, ResponseType>> {
+ return R"___([{"name":"node_id","in":"query","description":"node identifier","required":false,"type":"integer"},)___"
+ R"___({"name":"merge","in":"query","description":"merge information from nodes","required":false,"type":"boolean"},)___"
+ R"___({"name":"group","in":"query","description":"group information by field","required":false,"type":"string"},)___"
+ R"___({"name":"all","in":"query","description":"return all possible key combinations (for enums only)","required":false,"type":"boolean"},)___"
+ R"___({"name":"filter","in":"query","description":"filter information by field","required":false,"type":"string"},)___"
+ R"___({"name":"alive","in":"query","description":"request from alive (connected) nodes only","required":false,"type":"boolean"},)___"
+ R"___({"name":"enums","in":"query","description":"convert enums to strings","required":false,"type":"boolean"},)___"
+ R"___({"name":"ui64","in":"query","description":"return ui64 as number","required":false,"type":"boolean"},)___"
+ R"___({"name":"timeout","in":"query","description":"timeout in ms","required":false,"type":"integer"},)___"
+ R"___({"name":"retries","in":"query","description":"number of retries","required":false,"type":"integer"},)___"
+ R"___({"name":"retry_period","in":"query","description":"retry period in ms","required":false,"type":"integer","default":500},)___"
+ R"___({"name":"static","in":"query","description":"request from static nodes only","required":false,"type":"boolean"},)___"
+ R"___({"name":"since","in":"query","description":"filter by update time","required":false,"type":"string"}])___";
+ }
+};
+
+template <typename RequestType, typename ResponseType>
+struct TJsonRequestSchema<TJsonWhiteboardRequest<RequestType, ResponseType>> {
static TString GetSchema() {
- TStringStream stream;
- TProtoToJson::ProtoToJsonSchema<typename ResponseType::ProtoRecordType>(stream);
- return stream.Str();
- }
-};
-
-}
-}
+ TStringStream stream;
+ TProtoToJson::ProtoToJsonSchema<typename ResponseType::ProtoRecordType>(stream);
+ return stream.Str();
+ }
+};
+
+}
+}
diff --git a/ydb/core/viewer/json_whoami.h b/ydb/core/viewer/json_whoami.h
index 20148c062eb..b490a6930fc 100644
--- a/ydb/core/viewer/json_whoami.h
+++ b/ydb/core/viewer/json_whoami.h
@@ -1,84 +1,84 @@
-#pragma once
+#pragma once
#include <library/cpp/actors/core/actor_bootstrapped.h>
#include <library/cpp/actors/core/mon.h>
#include <ydb/core/base/tablet_pipe.h>
#include <ydb/core/protos/services.pb.h>
#include <ydb/core/tx/schemeshard/schemeshard.h>
#include <ydb/core/tx/tx_proxy/proxy.h>
-#include "viewer.h"
-
-namespace NKikimr {
-namespace NViewer {
-
-using namespace NActors;
-
-class TJsonWhoAmI : public TActorBootstrapped<TJsonWhoAmI> {
- IViewer* Viewer;
- TJsonSettings JsonSettings;
- NMon::TEvHttpInfo::TPtr Event;
-
-public:
+#include "viewer.h"
+
+namespace NKikimr {
+namespace NViewer {
+
+using namespace NActors;
+
+class TJsonWhoAmI : public TActorBootstrapped<TJsonWhoAmI> {
+ IViewer* Viewer;
+ TJsonSettings JsonSettings;
+ NMon::TEvHttpInfo::TPtr Event;
+
+public:
static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
return NKikimrServices::TActivity::VIEWER_HANDLER;
- }
-
- TJsonWhoAmI(IViewer* viewer, NMon::TEvHttpInfo::TPtr& ev)
- : Viewer(viewer)
- , Event(ev)
- {}
-
- void Bootstrap(const TActorContext& ctx) {
+ }
+
+ TJsonWhoAmI(IViewer* viewer, NMon::TEvHttpInfo::TPtr& ev)
+ : Viewer(viewer)
+ , Event(ev)
+ {}
+
+ void Bootstrap(const TActorContext& ctx) {
const auto& params(Event->Get()->Request.GetParams());
- JsonSettings.EnumAsNumbers = !FromStringWithDefault<bool>(params.Get("enums"), false);
- JsonSettings.UI64AsString = !FromStringWithDefault<bool>(params.Get("ui64"), false);
- ReplyAndDie(ctx);
- }
-
- void ReplyAndDie(const TActorContext &ctx) {
- NACLibProto::TUserToken userToken;
+ JsonSettings.EnumAsNumbers = !FromStringWithDefault<bool>(params.Get("enums"), false);
+ JsonSettings.UI64AsString = !FromStringWithDefault<bool>(params.Get("ui64"), false);
+ ReplyAndDie(ctx);
+ }
+
+ void ReplyAndDie(const TActorContext &ctx) {
+ NACLibProto::TUserToken userToken;
Y_PROTOBUF_SUPPRESS_NODISCARD userToken.ParseFromString(Event->Get()->UserToken);
- TStringStream json;
- TProtoToJson::ProtoToJson(json, userToken, JsonSettings);
- ctx.Send(Event->Sender, new NMon::TEvHttpInfoRes(Viewer->GetHTTPOKJSON() + json.Str(), 0, NMon::IEvHttpInfoRes::EContentType::Custom));
- Die(ctx);
- }
-
- void HandleTimeout(const TActorContext &ctx) {
- ctx.Send(Event->Sender, new NMon::TEvHttpInfoRes(Viewer->GetHTTPGATEWAYTIMEOUT(), 0, NMon::IEvHttpInfoRes::EContentType::Custom));
- Die(ctx);
- }
-};
-
-template <>
-struct TJsonRequestSchema<TJsonWhoAmI> {
- static TString GetSchema() {
- TStringStream stream;
- TProtoToJson::ProtoToJsonSchema<NACLibProto::TUserToken>(stream);
- return stream.Str();
- }
-};
-
-template <>
-struct TJsonRequestParameters<TJsonWhoAmI> {
- static TString GetParameters() {
- return R"___([{"name":"enums","in":"query","description":"convert enums to strings","required":false,"type":"boolean"},
- {"name":"ui64","in":"query","description":"return ui64 as numbers","required":false,"type":"boolean"}])___";
- }
-};
-
-template <>
-struct TJsonRequestSummary<TJsonWhoAmI> {
- static TString GetSummary() {
- return "\"Information about current user\"";
- }
-};
-
-template <>
-struct TJsonRequestDescription<TJsonWhoAmI> {
- static TString GetDescription() {
- return "\"Returns information about user token\"";
- }
-};
-
-}
-}
+ TStringStream json;
+ TProtoToJson::ProtoToJson(json, userToken, JsonSettings);
+ ctx.Send(Event->Sender, new NMon::TEvHttpInfoRes(Viewer->GetHTTPOKJSON() + json.Str(), 0, NMon::IEvHttpInfoRes::EContentType::Custom));
+ Die(ctx);
+ }
+
+ void HandleTimeout(const TActorContext &ctx) {
+ ctx.Send(Event->Sender, new NMon::TEvHttpInfoRes(Viewer->GetHTTPGATEWAYTIMEOUT(), 0, NMon::IEvHttpInfoRes::EContentType::Custom));
+ Die(ctx);
+ }
+};
+
+template <>
+struct TJsonRequestSchema<TJsonWhoAmI> {
+ static TString GetSchema() {
+ TStringStream stream;
+ TProtoToJson::ProtoToJsonSchema<NACLibProto::TUserToken>(stream);
+ return stream.Str();
+ }
+};
+
+template <>
+struct TJsonRequestParameters<TJsonWhoAmI> {
+ static TString GetParameters() {
+ return R"___([{"name":"enums","in":"query","description":"convert enums to strings","required":false,"type":"boolean"},
+ {"name":"ui64","in":"query","description":"return ui64 as numbers","required":false,"type":"boolean"}])___";
+ }
+};
+
+template <>
+struct TJsonRequestSummary<TJsonWhoAmI> {
+ static TString GetSummary() {
+ return "\"Information about current user\"";
+ }
+};
+
+template <>
+struct TJsonRequestDescription<TJsonWhoAmI> {
+ static TString GetDescription() {
+ return "\"Returns information about user token\"";
+ }
+};
+
+}
+}
diff --git a/ydb/core/viewer/protos/viewer.proto b/ydb/core/viewer/protos/viewer.proto
index d3e0c078b50..9f6c822a89f 100644
--- a/ydb/core/viewer/protos/viewer.proto
+++ b/ydb/core/viewer/protos/viewer.proto
@@ -1,4 +1,4 @@
-syntax = "proto3";
+syntax = "proto3";
import "ydb/core/protos/tablet_counters.proto";
import "ydb/core/protos/node_whiteboard.proto";
@@ -6,19 +6,19 @@ import "ydb/core/protos/flat_scheme_op.proto";
import "ydb/core/protos/tablet.proto";
import "ydb/core/protos/hive.proto";
import "ydb/public/api/protos/ydb_cms.proto";
-
-package NKikimrViewer;
-option java_package = "ru.yandex.kikimr.proto";
-
-enum EObjectType {
- Unknown = 0;
- Root = 1;
- Directory = 2;
- Table = 3;
- Topic = 4;
- Consumers = 5;
- Operations = 6;
- Consumer = 7;
+
+package NKikimrViewer;
+option java_package = "ru.yandex.kikimr.proto";
+
+enum EObjectType {
+ Unknown = 0;
+ Root = 1;
+ Directory = 2;
+ Table = 3;
+ Topic = 4;
+ Consumers = 5;
+ Operations = 6;
+ Consumer = 7;
RtmrTables = 8;
RtmrOperations = 9; // flat list of operations
RtmrTable = 10;
@@ -29,63 +29,63 @@ enum EObjectType {
BlockStoreVolume = 15;
Kesus = 16;
SolomonVolume = 17;
- SubDomain = 18;
+ SubDomain = 18;
FileStore = 19;
CdcStream = 20;
Sequence = 21;
Replication = 22;
-}
-
-message TBrowseInfo {
- EObjectType Type = 1;
- string Path = 2;
- string Name = 3;
- bool Final = 4;
- repeated TBrowseInfo Children = 5;
-}
-
-message TBackupInfo {
+}
+
+message TBrowseInfo {
+ EObjectType Type = 1;
+ string Path = 2;
+ string Name = 3;
+ bool Final = 4;
+ repeated TBrowseInfo Children = 5;
+}
+
+message TBackupInfo {
NKikimrSchemeOp.TBackupProgress Progress = 1;
repeated NKikimrSchemeOp.TLastBackupResult LastResults = 2;
-}
-
-message TResources {
- uint64 CPU = 1;
- uint64 Memory = 2;
- uint64 Network = 3;
- uint64 Storage = 5;
- uint64 ReadThroughput = 6;
- uint64 WriteThroughput = 7;
-}
-
-message TMetaCommonInfo {
- message TACE {
- string AccessType = 1;
- repeated string AccessRights = 2;
- string Subject = 3;
- repeated string InheritanceType = 4;
- string AccessRule = 5;
- }
-
- EObjectType Type = 1;
- string Path = 2;
- uint64 DataSize = 3;
- uint32 Tablets = 4;
- uint32 Partitions = 5;
- string Owner = 6;
- uint64 MemorySize = 7;
- uint64 RowCount = 8;
- uint64 CreateTime = 9;
- uint64 AccessTime = 10;
- uint64 UpdateTime = 11;
- repeated string ErasureSpecies = 12;
- repeated string VDiskKind = 13;
- repeated string PDiskKind = 14;
- repeated uint32 Nodes = 15;
- repeated uint32 Disks = 16;
- repeated TACE ACL = 17;
- TBackupInfo Backup = 18;
- TResources Resources = 19;
+}
+
+message TResources {
+ uint64 CPU = 1;
+ uint64 Memory = 2;
+ uint64 Network = 3;
+ uint64 Storage = 5;
+ uint64 ReadThroughput = 6;
+ uint64 WriteThroughput = 7;
+}
+
+message TMetaCommonInfo {
+ message TACE {
+ string AccessType = 1;
+ repeated string AccessRights = 2;
+ string Subject = 3;
+ repeated string InheritanceType = 4;
+ string AccessRule = 5;
+ }
+
+ EObjectType Type = 1;
+ string Path = 2;
+ uint64 DataSize = 3;
+ uint32 Tablets = 4;
+ uint32 Partitions = 5;
+ string Owner = 6;
+ uint64 MemorySize = 7;
+ uint64 RowCount = 8;
+ uint64 CreateTime = 9;
+ uint64 AccessTime = 10;
+ uint64 UpdateTime = 11;
+ repeated string ErasureSpecies = 12;
+ repeated string VDiskKind = 13;
+ repeated string PDiskKind = 14;
+ repeated uint32 Nodes = 15;
+ repeated uint32 Disks = 16;
+ repeated TACE ACL = 17;
+ TBackupInfo Backup = 18;
+ TResources Resources = 19;
// RTMR-specific table stats
uint64 DistinctKeysCount = 20;
@@ -108,16 +108,16 @@ message TMetaCommonInfo {
uint64 RowReads = 36;
uint64 RangeReads = 37;
uint64 RangeReadRows = 38;
-}
-
-message TMetaColumnInfo {
- string Name = 1;
- string Type = 2;
- bool Key = 3;
-}
-
-message TMetaTableInfo {
- repeated TMetaColumnInfo Schema = 1;
+}
+
+message TMetaColumnInfo {
+ string Name = 1;
+ string Type = 2;
+ bool Key = 3;
+}
+
+message TMetaTableInfo {
+ repeated TMetaColumnInfo Schema = 1;
// RTMR-specific table information
/// Lifetime in seconds
@@ -135,47 +135,47 @@ message TMetaTableInfo {
// RTMR-specific view information
repeated string SrcTables = 8;
-}
-
-message TMetaTopicLagInfo {
- uint64 WriteTime = 1;
- uint64 CreateTime = 2;
- uint64 Messages = 3;
- uint64 Size = 4;
-}
-
-message TMetaTopicConsumerInfo {
- string Name = 1;
- TMetaTopicLagInfo CommittedLags = 2;
- TMetaTopicLagInfo LastReadLags = 3;
- //map<string, TMetaTopicInfo> Topics = 4;
- repeated TMetaTopicInfo Topics = 4;
-}
-
-message TMetaTopicPartitionInfo {
- int32 Partition = 1;
- TMetaTopicLagInfo CommittedLags = 2;
- TMetaTopicLagInfo LastReadLags = 3;
-}
-
-message TMetaTopicPartitionConfig {
- uint64 MaxCountInPartition = 1;
- uint64 MaxSizeInPartition = 2;
- uint64 LifetimeSeconds = 3;
-}
-
-message TMetaTopicInfo {
- string Name = 1;
- TMetaTopicLagInfo CommittedLags = 2;
- TMetaTopicLagInfo LastReadLags = 3;
- uint64 PartitionLifeTime = 4;
- uint64 PartitionInitTime = 5;
- TMetaTopicPartitionConfig PartitionConfig = 6;
-
- repeated TMetaTopicConsumerInfo Consumers = 9;
- repeated TMetaTopicPartitionInfo Partitions = 10;
-}
-
+}
+
+message TMetaTopicLagInfo {
+ uint64 WriteTime = 1;
+ uint64 CreateTime = 2;
+ uint64 Messages = 3;
+ uint64 Size = 4;
+}
+
+message TMetaTopicConsumerInfo {
+ string Name = 1;
+ TMetaTopicLagInfo CommittedLags = 2;
+ TMetaTopicLagInfo LastReadLags = 3;
+ //map<string, TMetaTopicInfo> Topics = 4;
+ repeated TMetaTopicInfo Topics = 4;
+}
+
+message TMetaTopicPartitionInfo {
+ int32 Partition = 1;
+ TMetaTopicLagInfo CommittedLags = 2;
+ TMetaTopicLagInfo LastReadLags = 3;
+}
+
+message TMetaTopicPartitionConfig {
+ uint64 MaxCountInPartition = 1;
+ uint64 MaxSizeInPartition = 2;
+ uint64 LifetimeSeconds = 3;
+}
+
+message TMetaTopicInfo {
+ string Name = 1;
+ TMetaTopicLagInfo CommittedLags = 2;
+ TMetaTopicLagInfo LastReadLags = 3;
+ uint64 PartitionLifeTime = 4;
+ uint64 PartitionInitTime = 5;
+ TMetaTopicPartitionConfig PartitionConfig = 6;
+
+ repeated TMetaTopicConsumerInfo Consumers = 9;
+ repeated TMetaTopicPartitionInfo Partitions = 10;
+}
+
message TMetaRtmrOperationInfo {
message TSettings {
// Options passed to the operation instance
@@ -270,211 +270,211 @@ message TMetaRtmrTaskInfo {
repeated string Operations = 4;
}
-message TMetaInfo {
- TMetaCommonInfo Common = 1;
- TMetaTableInfo Table = 2;
- TMetaTopicInfo Topic = 3;
- TMetaTopicConsumerInfo Consumer = 4;
- NKikimrTabletBase.TTabletCounters Counters = 9;
+message TMetaInfo {
+ TMetaCommonInfo Common = 1;
+ TMetaTableInfo Table = 2;
+ TMetaTopicInfo Topic = 3;
+ TMetaTopicConsumerInfo Consumer = 4;
+ NKikimrTabletBase.TTabletCounters Counters = 9;
TMetaRtmrOperationInfo RtmrOperation = 10;
TMetaRtmrTaskInfo RtmrTask = 11;
-}
-
-message TTenantResource {
- string Type = 1;
- string Zone = 2;
- string Kind = 3;
- uint32 Count = 4;
-}
-
-message TTenantResources {
- repeated TTenantResource Required = 1;
- repeated TTenantResource Allocated = 2;
-}
-
-enum EFlag {
- Grey = 0;
- Green = 1;
- Blue = 2;
- Yellow = 3;
- Orange = 4;
- Red = 5;
-}
-
-message TClusterInfo {
- string Name = 1;
- EFlag Overall = 2;
- uint32 NodesTotal = 10;
- uint32 NodesAlive = 11;
- uint32 NumberOfCpus = 20;
- double LoadAverage = 21;
- uint64 MemoryTotal = 30;
- uint64 MemoryUsed = 31;
- uint64 StorageTotal = 40;
- uint64 StorageUsed = 41;
- repeated string DataCenters = 42;
- repeated string Versions = 43;
- repeated NKikimrWhiteboard.TTabletStateInfo SystemTablets = 16;
- uint64 Hosts = 44;
- uint64 Tenants = 45;
- uint64 Tablets = 46;
-}
-
-enum ETenantType {
- UnknownTenantType = 0;
- Domain = 1;
- Dedicated = 2;
- Shared = 3;
- Serverless = 4;
-}
-
-message TTenant {
- string Name = 1;
- string Id = 2;
- ETenantType Type = 3;
+}
+
+message TTenantResource {
+ string Type = 1;
+ string Zone = 2;
+ string Kind = 3;
+ uint32 Count = 4;
+}
+
+message TTenantResources {
+ repeated TTenantResource Required = 1;
+ repeated TTenantResource Allocated = 2;
+}
+
+enum EFlag {
+ Grey = 0;
+ Green = 1;
+ Blue = 2;
+ Yellow = 3;
+ Orange = 4;
+ Red = 5;
+}
+
+message TClusterInfo {
+ string Name = 1;
+ EFlag Overall = 2;
+ uint32 NodesTotal = 10;
+ uint32 NodesAlive = 11;
+ uint32 NumberOfCpus = 20;
+ double LoadAverage = 21;
+ uint64 MemoryTotal = 30;
+ uint64 MemoryUsed = 31;
+ uint64 StorageTotal = 40;
+ uint64 StorageUsed = 41;
+ repeated string DataCenters = 42;
+ repeated string Versions = 43;
+ repeated NKikimrWhiteboard.TTabletStateInfo SystemTablets = 16;
+ uint64 Hosts = 44;
+ uint64 Tenants = 45;
+ uint64 Tablets = 46;
+}
+
+enum ETenantType {
+ UnknownTenantType = 0;
+ Domain = 1;
+ Dedicated = 2;
+ Shared = 3;
+ Serverless = 4;
+}
+
+message TTenant {
+ string Name = 1;
+ string Id = 2;
+ ETenantType Type = 3;
Ydb.Cms.GetDatabaseStatusResult.State State = 4;
- repeated NKikimrHive.THiveDomainStatsStateCount StateStats = 5;
- NKikimrTabletBase.TMetrics Metrics = 6;
- repeated uint32 NodeIds = 7;
- uint32 AliveNodes = 8;
- TTenantResources Resources = 9;
- uint64 CreateTime = 10;
- string Owner = 11;
- repeated string Users = 12;
- repeated NKikimrWhiteboard.TSystemStateInfo.TPoolStats PoolStats = 13;
- map<string, string> UserAttributes = 14;
- EFlag Overall = 15;
- repeated NKikimrWhiteboard.TTabletStateInfo SystemTablets = 16;
- string ResourceId = 32;
- repeated TTabletStateInfo Tablets = 33;
- uint64 StorageAllocatedSize = 34;
- uint64 StorageMinAvailableSize = 35;
- repeated NKikimrWhiteboard.TSystemStateInfo Nodes = 36;
- uint64 MemoryUsed = 37;
- uint64 MemoryLimit = 38;
- double CoresUsed = 39;
- uint64 StorageGroups = 40;
-}
-
-message TTenants {
- repeated TTenant Tenants = 1;
-}
-
-message TTenantInfo {
- repeated TTenant TenantInfo = 1;
- repeated string Errors = 2;
-}
-
-message TStorageGroupInfo {
- string GroupId = 1;
-}
-
-message TStoragePoolInfo {
- EFlag Overall = 1;
- string Name = 2;
- string Kind = 3;
- repeated TStorageGroupInfo Groups = 4;
- uint64 AcquiredUnits = 5;
- float AcquiredIOPS = 6;
- uint64 AcquiredThroughput = 7;
- uint64 AcquiredSize = 8;
- float MaximumIOPS = 9;
- uint64 MaximumThroughput = 10;
- uint64 MaximumSize = 11;
-}
-
-message TStorageInfo {
- EFlag Overall = 1;
- repeated TStoragePoolInfo StoragePools = 2;
-}
-
-message TNodeInfo {
- uint32 NodeId = 1;
- NKikimrWhiteboard.TSystemStateInfo SystemState = 2;
- repeated NKikimrWhiteboard.TPDiskStateInfo PDisks = 3;
-}
-
-message TNodesInfo {
- EFlag Overall = 1;
- repeated TNodeInfo Nodes = 2;
-}
-
-enum ENodeType {
- UnknownNodeType = 0;
- Static = 1;
- Dynamic = 2;
-}
-
-message TNetNodePeerInfo {
- uint32 NodeId = 1;
- string PeerName = 2;
- bool Connected = 3;
- EFlag ConnectStatus = 4;
- uint64 ChangeTime = 5;
- ENodeType NodeType = 6;
- string DataCenter = 7;
- string Rack = 8;
- string Host = 9;
- uint32 Port = 10;
-}
-
-message TNetNodeInfo {
- uint32 NodeId = 1;
- EFlag Overall = 2;
- repeated TNetNodePeerInfo Peers = 3;
- ENodeType NodeType = 4;
- string DataCenter = 5;
- string Rack = 6;
- string Host = 7;
- uint32 Port = 8;
-}
-
-message TNetTenantInfo {
- EFlag Overall = 1;
- string Name = 2;
- repeated TNetNodeInfo Nodes = 5;
-}
-
-message TNetInfo {
- EFlag Overall = 1;
- repeated TNetTenantInfo Tenants = 2;
-}
-
-message TTabletStateInfo {
- string Type = 1;
- EFlag State = 2;
- uint32 Count = 3;
-}
-
-message TComputeNodeInfo {
- uint64 StartTime = 1;
- uint64 ChangeTime = 2;
+ repeated NKikimrHive.THiveDomainStatsStateCount StateStats = 5;
+ NKikimrTabletBase.TMetrics Metrics = 6;
+ repeated uint32 NodeIds = 7;
+ uint32 AliveNodes = 8;
+ TTenantResources Resources = 9;
+ uint64 CreateTime = 10;
+ string Owner = 11;
+ repeated string Users = 12;
+ repeated NKikimrWhiteboard.TSystemStateInfo.TPoolStats PoolStats = 13;
+ map<string, string> UserAttributes = 14;
+ EFlag Overall = 15;
+ repeated NKikimrWhiteboard.TTabletStateInfo SystemTablets = 16;
+ string ResourceId = 32;
+ repeated TTabletStateInfo Tablets = 33;
+ uint64 StorageAllocatedSize = 34;
+ uint64 StorageMinAvailableSize = 35;
+ repeated NKikimrWhiteboard.TSystemStateInfo Nodes = 36;
+ uint64 MemoryUsed = 37;
+ uint64 MemoryLimit = 38;
+ double CoresUsed = 39;
+ uint64 StorageGroups = 40;
+}
+
+message TTenants {
+ repeated TTenant Tenants = 1;
+}
+
+message TTenantInfo {
+ repeated TTenant TenantInfo = 1;
+ repeated string Errors = 2;
+}
+
+message TStorageGroupInfo {
+ string GroupId = 1;
+}
+
+message TStoragePoolInfo {
+ EFlag Overall = 1;
+ string Name = 2;
+ string Kind = 3;
+ repeated TStorageGroupInfo Groups = 4;
+ uint64 AcquiredUnits = 5;
+ float AcquiredIOPS = 6;
+ uint64 AcquiredThroughput = 7;
+ uint64 AcquiredSize = 8;
+ float MaximumIOPS = 9;
+ uint64 MaximumThroughput = 10;
+ uint64 MaximumSize = 11;
+}
+
+message TStorageInfo {
+ EFlag Overall = 1;
+ repeated TStoragePoolInfo StoragePools = 2;
+}
+
+message TNodeInfo {
+ uint32 NodeId = 1;
+ NKikimrWhiteboard.TSystemStateInfo SystemState = 2;
+ repeated NKikimrWhiteboard.TPDiskStateInfo PDisks = 3;
+}
+
+message TNodesInfo {
+ EFlag Overall = 1;
+ repeated TNodeInfo Nodes = 2;
+}
+
+enum ENodeType {
+ UnknownNodeType = 0;
+ Static = 1;
+ Dynamic = 2;
+}
+
+message TNetNodePeerInfo {
+ uint32 NodeId = 1;
+ string PeerName = 2;
+ bool Connected = 3;
+ EFlag ConnectStatus = 4;
+ uint64 ChangeTime = 5;
+ ENodeType NodeType = 6;
+ string DataCenter = 7;
+ string Rack = 8;
+ string Host = 9;
+ uint32 Port = 10;
+}
+
+message TNetNodeInfo {
+ uint32 NodeId = 1;
+ EFlag Overall = 2;
+ repeated TNetNodePeerInfo Peers = 3;
+ ENodeType NodeType = 4;
+ string DataCenter = 5;
+ string Rack = 6;
+ string Host = 7;
+ uint32 Port = 8;
+}
+
+message TNetTenantInfo {
+ EFlag Overall = 1;
+ string Name = 2;
+ repeated TNetNodeInfo Nodes = 5;
+}
+
+message TNetInfo {
+ EFlag Overall = 1;
+ repeated TNetTenantInfo Tenants = 2;
+}
+
+message TTabletStateInfo {
+ string Type = 1;
+ EFlag State = 2;
+ uint32 Count = 3;
+}
+
+message TComputeNodeInfo {
+ uint64 StartTime = 1;
+ uint64 ChangeTime = 2;
NKikimrWhiteboard.TSystemStateInfo.TLegacyNodeLocation SystemLocation = 3;
- repeated double LoadAverage = 4;
- uint32 NumberOfCpus = 5;
- EFlag Overall = 6;
- uint32 NodeId = 9;
- string DataCenter = 16;
- string Rack = 18;
- string Host = 19;
- string Version = 20;
- repeated NKikimrWhiteboard.TSystemStateInfo.TPoolStats PoolStats = 21;
- repeated NKikimrWhiteboard.TSystemStateInfo.TEndpoint Endpoints = 22;
- repeated string Roles = 23;
- optional uint64 MemoryUsed = 26;
- optional uint64 MemoryLimit = 27;
- NKikimrTabletBase.TMetrics Metrics = 32;
- repeated TTabletStateInfo Tablets = 33;
-}
-
-message TComputeTenantInfo {
- EFlag Overall = 1;
- string Name = 2;
- repeated TComputeNodeInfo Nodes = 5;
-}
-
-message TComputeInfo {
- EFlag Overall = 1;
- repeated TComputeTenantInfo Tenants = 2;
- repeated string Errors = 3;
-}
+ repeated double LoadAverage = 4;
+ uint32 NumberOfCpus = 5;
+ EFlag Overall = 6;
+ uint32 NodeId = 9;
+ string DataCenter = 16;
+ string Rack = 18;
+ string Host = 19;
+ string Version = 20;
+ repeated NKikimrWhiteboard.TSystemStateInfo.TPoolStats PoolStats = 21;
+ repeated NKikimrWhiteboard.TSystemStateInfo.TEndpoint Endpoints = 22;
+ repeated string Roles = 23;
+ optional uint64 MemoryUsed = 26;
+ optional uint64 MemoryLimit = 27;
+ NKikimrTabletBase.TMetrics Metrics = 32;
+ repeated TTabletStateInfo Tablets = 33;
+}
+
+message TComputeTenantInfo {
+ EFlag Overall = 1;
+ string Name = 2;
+ repeated TComputeNodeInfo Nodes = 5;
+}
+
+message TComputeInfo {
+ EFlag Overall = 1;
+ repeated TComputeTenantInfo Tenants = 2;
+ repeated string Errors = 3;
+}
diff --git a/ydb/core/viewer/protos/ya.make b/ydb/core/viewer/protos/ya.make
index b220403582b..295cf0b934a 100644
--- a/ydb/core/viewer/protos/ya.make
+++ b/ydb/core/viewer/protos/ya.make
@@ -1,18 +1,18 @@
-PROTO_LIBRARY()
-
+PROTO_LIBRARY()
+
OWNER(
xenoxeno
g:kikimr
)
-
-SRCS(
- viewer.proto
-)
-
-PEERDIR(
+
+SRCS(
+ viewer.proto
+)
+
+PEERDIR(
ydb/core/protos
-)
-
+)
+
EXCLUDE_TAGS(GO_PROTO)
-END()
+END()
diff --git a/ydb/core/viewer/ut/ya.make b/ydb/core/viewer/ut/ya.make
index 979e4d96f2d..18657a1f660 100644
--- a/ydb/core/viewer/ut/ya.make
+++ b/ydb/core/viewer/ut/ya.make
@@ -1,21 +1,21 @@
UNITTEST_FOR(ydb/core/viewer)
-OWNER(g:kikimr)
-
-FORK_SUBTESTS()
-
-TIMEOUT(600)
-
-SIZE(MEDIUM)
-
+OWNER(g:kikimr)
+
+FORK_SUBTESTS()
+
+TIMEOUT(600)
+
+SIZE(MEDIUM)
+
YQL_LAST_ABI_VERSION()
-
-SRCS(
- viewer_ut.cpp
-)
-
+
+SRCS(
+ viewer_ut.cpp
+)
+
PEERDIR(
ydb/core/testlib
)
-END()
+END()
diff --git a/ydb/core/viewer/viewer.cpp b/ydb/core/viewer/viewer.cpp
index 9ce296a32ef..f1124115bf7 100644
--- a/ydb/core/viewer/viewer.cpp
+++ b/ydb/core/viewer/viewer.cpp
@@ -1,97 +1,97 @@
-
+
#include <library/cpp/actors/core/actor_bootstrapped.h>
#include <ydb/core/mon/mon.h>
#include <library/cpp/actors/core/mon.h>
#include <ydb/core/base/appdata.h>
#include <library/cpp/monlib/service/pages/templates.h>
#include <library/cpp/actors/core/interconnect.h>
-#include <util/generic/algorithm.h>
+#include <util/generic/algorithm.h>
#include <ydb/core/base/path.h>
#include <ydb/core/base/tablet_types.h>
#include <ydb/core/node_whiteboard/node_whiteboard.h>
#include <ydb/core/base/statestorage.h>
#include <library/cpp/mime/types/mime.h>
-#include <util/system/fstat.h>
-#include <util/stream/file.h>
-#include "viewer.h"
+#include <util/system/fstat.h>
+#include <util/stream/file.h>
+#include "viewer.h"
#include <ydb/core/viewer/json/json.h>
#include <ydb/core/util/wildcard.h>
-#include "json_nodelist.h"
-#include "json_nodeinfo.h"
-#include "json_vdiskinfo.h"
-#include "json_pdiskinfo.h"
-#include "json_describe.h"
+#include "json_nodelist.h"
+#include "json_nodeinfo.h"
+#include "json_vdiskinfo.h"
+#include "json_pdiskinfo.h"
+#include "json_describe.h"
#include "json_hotkeys.h"
-#include "json_sysinfo.h"
-#include "json_tabletinfo.h"
-#include "json_hiveinfo.h"
-#include "json_bsgroupinfo.h"
-#include "json_bscontrollerinfo.h"
-#include "json_config.h"
-#include "json_counters.h"
+#include "json_sysinfo.h"
+#include "json_tabletinfo.h"
+#include "json_hiveinfo.h"
+#include "json_bsgroupinfo.h"
+#include "json_bscontrollerinfo.h"
+#include "json_config.h"
+#include "json_counters.h"
#include "json_topicinfo.h"
#include "json_pqconsumerinfo.h"
-#include "json_tabletcounters.h"
-#include "json_storage.h"
-#include "json_metainfo.h"
-#include "json_browse.h"
-#include "json_cluster.h"
-#include "json_content.h"
-#include "json_labeledcounters.h"
-#include "json_tenants.h"
-#include "json_hivestats.h"
-#include "json_tenantinfo.h"
-#include "json_whoami.h"
-#include "json_query.h"
-#include "json_netinfo.h"
-#include "json_compute.h"
-#include "counters_hosts.h"
-#include "json_healthcheck.h"
-#include "json_nodes.h"
-
-namespace NKikimr {
-namespace NViewer {
-
-using namespace NNodeWhiteboard;
-
-class TJsonHandlerBase {
-public:
- virtual ~TJsonHandlerBase() = default;
- virtual IActor* CreateRequestActor(IViewer* viewer, NMon::TEvHttpInfo::TPtr& event) = 0;
+#include "json_tabletcounters.h"
+#include "json_storage.h"
+#include "json_metainfo.h"
+#include "json_browse.h"
+#include "json_cluster.h"
+#include "json_content.h"
+#include "json_labeledcounters.h"
+#include "json_tenants.h"
+#include "json_hivestats.h"
+#include "json_tenantinfo.h"
+#include "json_whoami.h"
+#include "json_query.h"
+#include "json_netinfo.h"
+#include "json_compute.h"
+#include "counters_hosts.h"
+#include "json_healthcheck.h"
+#include "json_nodes.h"
+
+namespace NKikimr {
+namespace NViewer {
+
+using namespace NNodeWhiteboard;
+
+class TJsonHandlerBase {
+public:
+ virtual ~TJsonHandlerBase() = default;
+ virtual IActor* CreateRequestActor(IViewer* viewer, NMon::TEvHttpInfo::TPtr& event) = 0;
virtual TString GetResponseJsonSchema() = 0;
virtual TString GetRequestSummary() { return TString(); }
virtual TString GetRequestDescription() { return TString(); }
virtual TString GetRequestParameters() { return TString(); }
-};
-
-template <typename ActorRequestType>
-class TJsonHandler : public TJsonHandlerBase {
-public:
- IActor* CreateRequestActor(IViewer* viewer, NMon::TEvHttpInfo::TPtr& event) override {
- return new ActorRequestType(viewer, event);
- }
-
+};
+
+template <typename ActorRequestType>
+class TJsonHandler : public TJsonHandlerBase {
+public:
+ IActor* CreateRequestActor(IViewer* viewer, NMon::TEvHttpInfo::TPtr& event) override {
+ return new ActorRequestType(viewer, event);
+ }
+
TString GetResponseJsonSchema() override {
static TString jsonSchema = TJsonRequestSchema<ActorRequestType>::GetSchema();
- return jsonSchema;
- }
-
+ return jsonSchema;
+ }
+
TString GetRequestSummary() override {
static TString jsonSummary = TJsonRequestSummary<ActorRequestType>::GetSummary();
- return jsonSummary;
- }
-
+ return jsonSummary;
+ }
+
TString GetRequestDescription() override {
static TString jsonDescription = TJsonRequestDescription<ActorRequestType>::GetDescription();
- return jsonDescription;
- }
-
+ return jsonDescription;
+ }
+
TString GetRequestParameters() override {
static TString jsonParameters = TJsonRequestParameters<ActorRequestType>::GetParameters();
- return jsonParameters;
- }
-};
-
+ return jsonParameters;
+ }
+};
+
void SetupPQVirtualHandlers(IViewer* viewer) {
viewer->RegisterVirtualHandler(
NKikimrViewer::EObjectType::Root,
@@ -123,111 +123,111 @@ void SetupDBVirtualHandlers(IViewer* viewer) {
});
}
-class TViewer : public TActorBootstrapped<TViewer>, public IViewer {
-public:
+class TViewer : public TActorBootstrapped<TViewer>, public IViewer {
+public:
static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
return NKikimrServices::TActivity::TABLET_MONITORING_PROXY;
- }
-
+ }
+
TViewer(const TKikimrRunConfig &kikimrRunConfig)
- : KikimrRunConfig(kikimrRunConfig)
+ : KikimrRunConfig(kikimrRunConfig)
{}
-
- void Bootstrap(const TActorContext &ctx) {
- Become(&TThis::StateWork);
- NActors::TMon* mon = AppData(ctx)->Mon;
- if (mon) {
- const auto& protoAllowedSIDs = KikimrRunConfig.AppConfig.GetDomainsConfig().GetSecurityConfig().GetViewerAllowedSIDs();
- TVector<TString> allowedSIDs;
- for (const auto& sid : protoAllowedSIDs) {
- allowedSIDs.emplace_back(sid);
- }
- mon->RegisterActorPage({
- .Title = "Viewer (classic)",
- .RelPath = "viewer",
- .ActorSystem = ctx.ExecutorThread.ActorSystem,
- .ActorId = ctx.SelfID,
- .UseAuth = true,
- .AllowedSIDs = allowedSIDs,
- });
- mon->RegisterActorPage({
- .Title = "Viewer",
- .RelPath = "viewer/v2",
- .ActorSystem = ctx.ExecutorThread.ActorSystem,
- .ActorId = ctx.SelfID,
- });
- mon->RegisterActorPage({
- .Title = "Monitoring",
- .RelPath = "monitoring",
- .ActorSystem = ctx.ExecutorThread.ActorSystem,
- .ActorId = ctx.SelfID,
- .UseAuth = false,
- });
- mon->RegisterActorPage({
- .RelPath = "counters/hosts",
- .ActorSystem = ctx.ExecutorThread.ActorSystem,
- .ActorId = ctx.SelfID,
- .UseAuth = false,
- });
- auto whiteboardServiceId = NNodeWhiteboard::MakeNodeWhiteboardServiceId(ctx.SelfID.NodeId());
- ctx.Send(whiteboardServiceId, new NNodeWhiteboard::TEvWhiteboard::TEvSystemStateAddEndpoint("http-mon", Sprintf(":%d", mon->GetListenPort())));
-
- TWhiteboardInfo<TEvWhiteboard::TEvNodeStateResponse>::InitMerger();
- TWhiteboardInfo<TEvWhiteboard::TEvBSGroupStateResponse>::InitMerger();
-
- JsonHandlers["/json/nodelist"] = new TJsonHandler<TJsonNodeList>;
- JsonHandlers["/json/nodeinfo"] = new TJsonHandler<TJsonNodeInfo>;
- JsonHandlers["/json/vdiskinfo"] = new TJsonHandler<TJsonVDiskInfo>;
- JsonHandlers["/json/pdiskinfo"] = new TJsonHandler<TJsonPDiskInfo>;
- JsonHandlers["/json/describe"] = new TJsonHandler<TJsonDescribe>;
+
+ void Bootstrap(const TActorContext &ctx) {
+ Become(&TThis::StateWork);
+ NActors::TMon* mon = AppData(ctx)->Mon;
+ if (mon) {
+ const auto& protoAllowedSIDs = KikimrRunConfig.AppConfig.GetDomainsConfig().GetSecurityConfig().GetViewerAllowedSIDs();
+ TVector<TString> allowedSIDs;
+ for (const auto& sid : protoAllowedSIDs) {
+ allowedSIDs.emplace_back(sid);
+ }
+ mon->RegisterActorPage({
+ .Title = "Viewer (classic)",
+ .RelPath = "viewer",
+ .ActorSystem = ctx.ExecutorThread.ActorSystem,
+ .ActorId = ctx.SelfID,
+ .UseAuth = true,
+ .AllowedSIDs = allowedSIDs,
+ });
+ mon->RegisterActorPage({
+ .Title = "Viewer",
+ .RelPath = "viewer/v2",
+ .ActorSystem = ctx.ExecutorThread.ActorSystem,
+ .ActorId = ctx.SelfID,
+ });
+ mon->RegisterActorPage({
+ .Title = "Monitoring",
+ .RelPath = "monitoring",
+ .ActorSystem = ctx.ExecutorThread.ActorSystem,
+ .ActorId = ctx.SelfID,
+ .UseAuth = false,
+ });
+ mon->RegisterActorPage({
+ .RelPath = "counters/hosts",
+ .ActorSystem = ctx.ExecutorThread.ActorSystem,
+ .ActorId = ctx.SelfID,
+ .UseAuth = false,
+ });
+ auto whiteboardServiceId = NNodeWhiteboard::MakeNodeWhiteboardServiceId(ctx.SelfID.NodeId());
+ ctx.Send(whiteboardServiceId, new NNodeWhiteboard::TEvWhiteboard::TEvSystemStateAddEndpoint("http-mon", Sprintf(":%d", mon->GetListenPort())));
+
+ TWhiteboardInfo<TEvWhiteboard::TEvNodeStateResponse>::InitMerger();
+ TWhiteboardInfo<TEvWhiteboard::TEvBSGroupStateResponse>::InitMerger();
+
+ JsonHandlers["/json/nodelist"] = new TJsonHandler<TJsonNodeList>;
+ JsonHandlers["/json/nodeinfo"] = new TJsonHandler<TJsonNodeInfo>;
+ JsonHandlers["/json/vdiskinfo"] = new TJsonHandler<TJsonVDiskInfo>;
+ JsonHandlers["/json/pdiskinfo"] = new TJsonHandler<TJsonPDiskInfo>;
+ JsonHandlers["/json/describe"] = new TJsonHandler<TJsonDescribe>;
JsonHandlers["/json/hotkeys"] = new TJsonHandler<TJsonHotkeys>;
- JsonHandlers["/json/sysinfo"] = new TJsonHandler<TJsonSysInfo>;
- JsonHandlers["/json/tabletinfo"] = new TJsonHandler<TJsonTabletInfo>;
- JsonHandlers["/json/hiveinfo"] = new TJsonHandler<TJsonHiveInfo>;
- JsonHandlers["/json/bsgroupinfo"] = new TJsonHandler<TJsonBSGroupInfo>;
- JsonHandlers["/json/bscontrollerinfo"] = new TJsonHandler<TJsonBSControllerInfo>;
- JsonHandlers["/json/config"] = new TJsonHandler<TJsonConfig>;
- JsonHandlers["/json/counters"] = new TJsonHandler<TJsonCounters>;
+ JsonHandlers["/json/sysinfo"] = new TJsonHandler<TJsonSysInfo>;
+ JsonHandlers["/json/tabletinfo"] = new TJsonHandler<TJsonTabletInfo>;
+ JsonHandlers["/json/hiveinfo"] = new TJsonHandler<TJsonHiveInfo>;
+ JsonHandlers["/json/bsgroupinfo"] = new TJsonHandler<TJsonBSGroupInfo>;
+ JsonHandlers["/json/bscontrollerinfo"] = new TJsonHandler<TJsonBSControllerInfo>;
+ JsonHandlers["/json/config"] = new TJsonHandler<TJsonConfig>;
+ JsonHandlers["/json/counters"] = new TJsonHandler<TJsonCounters>;
JsonHandlers["/json/topicinfo"] = new TJsonHandler<TJsonTopicInfo>;
JsonHandlers["/json/pqconsumerinfo"] = new TJsonHandler<TJsonPQConsumerInfo>;
- JsonHandlers["/json/tabletcounters"] = new TJsonHandler<TJsonTabletCounters>;
- JsonHandlers["/json/storage"] = new TJsonHandler<TJsonStorage>;
- JsonHandlers["/json/metainfo"] = new TJsonHandler<TJsonMetaInfo>;
- JsonHandlers["/json/browse"] = new TJsonHandler<TJsonBrowse>;
- JsonHandlers["/json/cluster"] = new TJsonHandler<TJsonCluster>;
- JsonHandlers["/json/content"] = new TJsonHandler<TJsonContent>;
- JsonHandlers["/json/labeledcounters"] = new TJsonHandler<TJsonLabeledCounters>;
- JsonHandlers["/json/tenants"] = new TJsonHandler<TJsonTenants>;
- JsonHandlers["/json/hivestats"] = new TJsonHandler<TJsonHiveStats>;
- JsonHandlers["/json/tenantinfo"] = new TJsonHandler<TJsonTenantInfo>;
- JsonHandlers["/json/whoami"] = new TJsonHandler<TJsonWhoAmI>;
- JsonHandlers["/json/query"] = new TJsonHandler<TJsonQuery>;
- JsonHandlers["/json/netinfo"] = new TJsonHandler<TJsonNetInfo>;
- JsonHandlers["/json/compute"] = new TJsonHandler<TJsonCompute>;
- JsonHandlers["/json/healthcheck"] = new TJsonHandler<TJsonHealthCheck>;
- JsonHandlers["/json/nodes"] = new TJsonHandler<TJsonNodes>;
- }
- }
-
- const TKikimrRunConfig& GetKikimrRunConfig() const override {
- return KikimrRunConfig;
- }
-
+ JsonHandlers["/json/tabletcounters"] = new TJsonHandler<TJsonTabletCounters>;
+ JsonHandlers["/json/storage"] = new TJsonHandler<TJsonStorage>;
+ JsonHandlers["/json/metainfo"] = new TJsonHandler<TJsonMetaInfo>;
+ JsonHandlers["/json/browse"] = new TJsonHandler<TJsonBrowse>;
+ JsonHandlers["/json/cluster"] = new TJsonHandler<TJsonCluster>;
+ JsonHandlers["/json/content"] = new TJsonHandler<TJsonContent>;
+ JsonHandlers["/json/labeledcounters"] = new TJsonHandler<TJsonLabeledCounters>;
+ JsonHandlers["/json/tenants"] = new TJsonHandler<TJsonTenants>;
+ JsonHandlers["/json/hivestats"] = new TJsonHandler<TJsonHiveStats>;
+ JsonHandlers["/json/tenantinfo"] = new TJsonHandler<TJsonTenantInfo>;
+ JsonHandlers["/json/whoami"] = new TJsonHandler<TJsonWhoAmI>;
+ JsonHandlers["/json/query"] = new TJsonHandler<TJsonQuery>;
+ JsonHandlers["/json/netinfo"] = new TJsonHandler<TJsonNetInfo>;
+ JsonHandlers["/json/compute"] = new TJsonHandler<TJsonCompute>;
+ JsonHandlers["/json/healthcheck"] = new TJsonHandler<TJsonHealthCheck>;
+ JsonHandlers["/json/nodes"] = new TJsonHandler<TJsonNodes>;
+ }
+ }
+
+ const TKikimrRunConfig& GetKikimrRunConfig() const override {
+ return KikimrRunConfig;
+ }
+
void RegisterVirtualHandler(
- NKikimrViewer::EObjectType parentObjectType,
- TVirtualHandlerType handler) override {
- VirtualHandlersByParentType.insert(std::make_pair(parentObjectType, TVirtualHandler(handler)));
- }
-
+ NKikimrViewer::EObjectType parentObjectType,
+ TVirtualHandlerType handler) override {
+ VirtualHandlersByParentType.insert(std::make_pair(parentObjectType, TVirtualHandler(handler)));
+ }
+
TVector<const TVirtualHandler*> GetVirtualHandlers(NKikimrViewer::EObjectType type, const TString&/* path*/) const override {
TVector<const TVirtualHandler*> handlers;
- auto its = VirtualHandlersByParentType.equal_range(type);
- for (auto it = its.first; it != its.second; ++it) {
- handlers.push_back(&it->second);
- }
- return handlers;
- }
-
+ auto its = VirtualHandlersByParentType.equal_range(type);
+ for (auto it = its.first; it != its.second; ++it) {
+ handlers.push_back(&it->second);
+ }
+ return handlers;
+ }
+
TContentHandler GetContentHandler(NKikimrViewer::EObjectType objectType) const override {
auto rec = ContentHandlers.find(objectType);
return (rec != ContentHandlers.end()) ? rec->second : (TContentHandler)nullptr;
@@ -241,224 +241,224 @@ public:
}
}
-private:
+private:
THashMap<TString, TAutoPtr<TJsonHandlerBase>> JsonHandlers;
- const TKikimrRunConfig KikimrRunConfig;
- std::unordered_multimap<NKikimrViewer::EObjectType, TVirtualHandler> VirtualHandlersByParentType;
+ const TKikimrRunConfig KikimrRunConfig;
+ std::unordered_multimap<NKikimrViewer::EObjectType, TVirtualHandler> VirtualHandlersByParentType;
std::unordered_map<NKikimrViewer::EObjectType, TContentHandler> ContentHandlers;
-
- STFUNC(StateWork) {
- switch (ev->GetTypeRewrite()) {
- HFunc(NMon::TEvHttpInfo, Handle);
- }
- }
-
+
+ STFUNC(StateWork) {
+ switch (ev->GetTypeRewrite()) {
+ HFunc(NMon::TEvHttpInfo, Handle);
+ }
+ }
+
TString GetSwaggerJson(NMon::TEvHttpInfo::TPtr &ev) {
- TStringStream json;
+ TStringStream json;
TString basepath = ev->Get()->Request.GetParams().Get("basepath");
- if (basepath.empty()) {
- basepath = "/viewer";
- } else {
+ if (basepath.empty()) {
+ basepath = "/viewer";
+ } else {
if (basepath.EndsWith("/api/")) {
- basepath = basepath.substr(0, basepath.size() - 5);
- }
- }
+ basepath = basepath.substr(0, basepath.size() - 5);
+ }
+ }
TString protocol = ev->Get()->Request.GetParams().Get("protocol");
- if (protocol.empty()) {
- protocol = "http";
- }
-
- json << R"___({"swagger":"2.0",
- "info": {
- "version": "1.0.0",
- "title": "YDB Viewer",
- "description": "YDB API for external introspection"
- },)___";
- json << "\"basePath\": \"" << basepath << "\",";
- json << "\"schemes\": [\"" << protocol << "\"],";
- json << R"___("consumes": ["application/json"],
- "produces": ["application/json"],
- "paths": {)___";
-
- for (auto itJson = JsonHandlers.begin(); itJson != JsonHandlers.end(); ++itJson) {
- if (itJson != JsonHandlers.begin()) {
- json << ',';
- }
+ if (protocol.empty()) {
+ protocol = "http";
+ }
+
+ json << R"___({"swagger":"2.0",
+ "info": {
+ "version": "1.0.0",
+ "title": "YDB Viewer",
+ "description": "YDB API for external introspection"
+ },)___";
+ json << "\"basePath\": \"" << basepath << "\",";
+ json << "\"schemes\": [\"" << protocol << "\"],";
+ json << R"___("consumes": ["application/json"],
+ "produces": ["application/json"],
+ "paths": {)___";
+
+ for (auto itJson = JsonHandlers.begin(); itJson != JsonHandlers.end(); ++itJson) {
+ if (itJson != JsonHandlers.begin()) {
+ json << ',';
+ }
TString name = itJson->first;
- json << '"' << name << '"' << ":{";
- json << "\"get\":{";
- json << "\"tags\":[\"viewer\"],";
- json << "\"produces\":[\"application/json\"],";
+ json << '"' << name << '"' << ":{";
+ json << "\"get\":{";
+ json << "\"tags\":[\"viewer\"],";
+ json << "\"produces\":[\"application/json\"],";
TString summary = itJson->second->GetRequestSummary();
- if (!summary.empty()) {
- json << "\"summary\":" << summary << ',';
- }
+ if (!summary.empty()) {
+ json << "\"summary\":" << summary << ',';
+ }
TString description = itJson->second->GetRequestDescription();
- if (!description.empty()) {
- json << "\"description\":" << description << ',';
- }
+ if (!description.empty()) {
+ json << "\"description\":" << description << ',';
+ }
TString parameters = itJson->second->GetRequestParameters();
- if (!parameters.empty()) {
- json << "\"parameters\":" << parameters << ',';
- }
- json << "\"responses\":{";
- json << "\"200\":{";
+ if (!parameters.empty()) {
+ json << "\"parameters\":" << parameters << ',';
+ }
+ json << "\"responses\":{";
+ json << "\"200\":{";
TString schema = itJson->second->GetResponseJsonSchema();
- if (!schema.empty()) {
- json << "\"schema\":" << schema;
- }
- json << "}";
- json << "}";
- json << "}";
- json << "}";
- }
-
- json << R"___(},"definitions":{)___";
-
- json << R"___(}})___";
-
- return json.Str();
- }
-
- bool ReplyWithSwaggerJson(NMon::TEvHttpInfo::TPtr &ev, const TActorContext &ctx) {
+ if (!schema.empty()) {
+ json << "\"schema\":" << schema;
+ }
+ json << "}";
+ json << "}";
+ json << "}";
+ json << "}";
+ }
+
+ json << R"___(},"definitions":{)___";
+
+ json << R"___(}})___";
+
+ return json.Str();
+ }
+
+ bool ReplyWithSwaggerJson(NMon::TEvHttpInfo::TPtr &ev, const TActorContext &ctx) {
TString json(GetSwaggerJson(ev));
- TStringStream response;
- response << "HTTP/1.1 200 Ok\r\n";
- response << "Content-Type: application/json\r\n";
+ TStringStream response;
+ response << "HTTP/1.1 200 Ok\r\n";
+ response << "Content-Type: application/json\r\n";
response << "Content-Length: " << json.size() << "\r\n";
- response << "\r\n";
+ response << "\r\n";
response.Write(json.data(), json.size());
- ctx.Send(ev->Sender, new NMon::TEvHttpInfoRes(response.Str(), 0, NMon::IEvHttpInfoRes::EContentType::Custom));
- return true;
- }
-
+ ctx.Send(ev->Sender, new NMon::TEvHttpInfoRes(response.Str(), 0, NMon::IEvHttpInfoRes::EContentType::Custom));
+ return true;
+ }
+
bool ReplyWithFile(NMon::TEvHttpInfo::TPtr &ev, const TActorContext &ctx, const TString& name) {
- if (name == "/api/viewer.json") {
- return ReplyWithSwaggerJson(ev, ctx);
- }
- TString filename("content" + name);
+ if (name == "/api/viewer.json") {
+ return ReplyWithSwaggerJson(ev, ctx);
+ }
+ TString filename("content" + name);
TString blob;
TString type;
- TFileStat fstat(filename);
- if (fstat.IsFile()) {
+ TFileStat fstat(filename);
+ if (fstat.IsFile()) {
blob = TUnbufferedFileInput(filename).ReadAll();
- if (!blob.empty()) {
- type = mimetypeByExt(filename.c_str());
- }
- }
+ if (!blob.empty()) {
+ type = mimetypeByExt(filename.c_str());
+ }
+ }
if (blob.empty()) {
- filename = TString("viewer") + name;
- if (NResource::FindExact(filename, &blob)) {
- type = mimetypeByExt(filename.c_str());
- } else {
- filename = name;
- if (NResource::FindExact(filename, &blob)) {
- type = mimetypeByExt(filename.c_str());
- }
- }
- }
+ filename = TString("viewer") + name;
+ if (NResource::FindExact(filename, &blob)) {
+ type = mimetypeByExt(filename.c_str());
+ } else {
+ filename = name;
+ if (NResource::FindExact(filename, &blob)) {
+ type = mimetypeByExt(filename.c_str());
+ }
+ }
+ }
if (!blob.empty()) {
- if (name == "/index.html" || name == "/v2/index.html") { // we send root's index in such format that it could be embedded into existing web interface
+ if (name == "/index.html" || name == "/v2/index.html") { // we send root's index in such format that it could be embedded into existing web interface
ctx.Send(ev->Sender, new NMon::TEvHttpInfoRes(TString(static_cast<const char*>(blob.data()), blob.size())));
- } else {
- TStringStream response;
- response << "HTTP/1.1 200 Ok\r\n";
- response << "Content-Type: " << type << "\r\n";
+ } else {
+ TStringStream response;
+ response << "HTTP/1.1 200 Ok\r\n";
+ response << "Content-Type: " << type << "\r\n";
response << "Content-Length: " << blob.size() << "\r\n";
- response << "\r\n";
+ response << "\r\n";
response.Write(blob.data(), blob.size());
- ctx.Send(ev->Sender, new NMon::TEvHttpInfoRes(response.Str(), 0, NMon::IEvHttpInfoRes::EContentType::Custom));
- }
+ ctx.Send(ev->Sender, new NMon::TEvHttpInfoRes(response.Str(), 0, NMon::IEvHttpInfoRes::EContentType::Custom));
+ }
return true;
- }
- return false;
- }
-
- void Handle(NMon::TEvHttpInfo::TPtr &ev, const TActorContext &ctx) {
- NMon::TEvHttpInfo* msg = ev->Get();
- if (msg->Request.GetMethod() == HTTP_METHOD_OPTIONS) {
- TString url(msg->Request.GetPathInfo());
- TString type = mimetypeByExt(url.c_str());
- if (type.empty()) {
- type = "application/json";
- }
- TString allowOrigin = KikimrRunConfig.AppConfig.GetMonitoringConfig().GetAllowOrigin();
- if (allowOrigin) {
- ctx.Send(ev->Sender, new NMon::TEvHttpInfoRes(
- "HTTP/1.1 204 No Content\r\n"
- "Access-Control-Allow-Origin: " + allowOrigin + "\r\n"
- "Access-Control-Allow-Credentials: true\r\n"
- "Access-Control-Allow-Headers: Content-Type,Authorization,Origin,Accept\r\n"
- "Access-Control-Allow-Methods: OPTIONS, GET, POST\r\n"
- "Allow: OPTIONS, GET, POST\r\n"
- "Content-Type: " + type + "\r\n"
- "Connection: Keep-Alive\r\n\r\n", 0, NMon::IEvHttpInfoRes::EContentType::Custom));
- } else {
- ctx.Send(ev->Sender, new NMon::TEvHttpInfoRes(
- "HTTP/1.1 204 No Content\r\n"
- "Allow: OPTIONS, GET, POST\r\n"
- "Content-Type: " + type + "\r\n"
- "Connection: Keep-Alive\r\n\r\n", 0, NMon::IEvHttpInfoRes::EContentType::Custom));
- }
- return;
- }
+ }
+ return false;
+ }
+
+ void Handle(NMon::TEvHttpInfo::TPtr &ev, const TActorContext &ctx) {
+ NMon::TEvHttpInfo* msg = ev->Get();
+ if (msg->Request.GetMethod() == HTTP_METHOD_OPTIONS) {
+ TString url(msg->Request.GetPathInfo());
+ TString type = mimetypeByExt(url.c_str());
+ if (type.empty()) {
+ type = "application/json";
+ }
+ TString allowOrigin = KikimrRunConfig.AppConfig.GetMonitoringConfig().GetAllowOrigin();
+ if (allowOrigin) {
+ ctx.Send(ev->Sender, new NMon::TEvHttpInfoRes(
+ "HTTP/1.1 204 No Content\r\n"
+ "Access-Control-Allow-Origin: " + allowOrigin + "\r\n"
+ "Access-Control-Allow-Credentials: true\r\n"
+ "Access-Control-Allow-Headers: Content-Type,Authorization,Origin,Accept\r\n"
+ "Access-Control-Allow-Methods: OPTIONS, GET, POST\r\n"
+ "Allow: OPTIONS, GET, POST\r\n"
+ "Content-Type: " + type + "\r\n"
+ "Connection: Keep-Alive\r\n\r\n", 0, NMon::IEvHttpInfoRes::EContentType::Custom));
+ } else {
+ ctx.Send(ev->Sender, new NMon::TEvHttpInfoRes(
+ "HTTP/1.1 204 No Content\r\n"
+ "Allow: OPTIONS, GET, POST\r\n"
+ "Content-Type: " + type + "\r\n"
+ "Connection: Keep-Alive\r\n\r\n", 0, NMon::IEvHttpInfoRes::EContentType::Custom));
+ }
+ return;
+ }
if (msg->Request.GetPathInfo().StartsWith("/json/")) {
auto itJson = JsonHandlers.find(msg->Request.GetPathInfo());
- if (itJson != JsonHandlers.end()) {
- try {
- ctx.ExecutorThread.RegisterActor(itJson->second->CreateRequestActor(this, ev));
- }
- catch (const std::exception& e) {
+ if (itJson != JsonHandlers.end()) {
+ try {
+ ctx.ExecutorThread.RegisterActor(itJson->second->CreateRequestActor(this, ev));
+ }
+ catch (const std::exception& e) {
ctx.Send(ev->Sender, new NMon::TEvHttpInfoRes(TString("HTTP/1.1 400 Bad Request\r\n\r\n") + e.what(), 0, NMon::IEvHttpInfoRes::EContentType::Custom));
- return;
- }
- } else {
- ctx.Send(ev->Sender, new NMon::TEvHttpInfoRes(NMonitoring::HTTPNOTFOUND));
- }
- return;
- }
- TString filename(msg->Request.GetPage()->Path + msg->Request.GetPathInfo());
- if (filename.StartsWith("counters/hosts")) {
- ctx.ExecutorThread.RegisterActor(new TCountersHostsList(this, ev));
- return;
- }
- // TODO: check path validity
- // TODO: cache
+ return;
+ }
+ } else {
+ ctx.Send(ev->Sender, new NMon::TEvHttpInfoRes(NMonitoring::HTTPNOTFOUND));
+ }
+ return;
+ }
+ TString filename(msg->Request.GetPage()->Path + msg->Request.GetPathInfo());
+ if (filename.StartsWith("counters/hosts")) {
+ ctx.ExecutorThread.RegisterActor(new TCountersHostsList(this, ev));
+ return;
+ }
+ // TODO: check path validity
+ // TODO: cache
if (msg->Request.GetPathInfo().StartsWith('/')) {
- if (filename.StartsWith("viewer")) {
+ if (filename.StartsWith("viewer")) {
filename.erase(0, 6);
- }
- if (IsMatchesWildcard(filename, "monitoring*/resources/js/*")
- || IsMatchesWildcard(filename, "monitoring*/resources/css/*")
- || IsMatchesWildcard(filename, "monitoring*/resources/assets/fonts/*")
- || IsMatchesWildcard(filename, "monitoring*/resources/favicon.png")) {
- auto resPos = filename.find("/resources/");
- if (resPos != TString::npos) {
- filename = "monitoring" + filename.substr(resPos);
- }
- } else if (filename.StartsWith("monitoring") && filename != "monitoring/index.html") {
- filename = "monitoring/index.html";
- }
- if (filename.EndsWith('/')) {
- filename += "index.html";
- }
- if (ReplyWithFile(ev, ctx, filename)) {
- return;
- }
- }
+ }
+ if (IsMatchesWildcard(filename, "monitoring*/resources/js/*")
+ || IsMatchesWildcard(filename, "monitoring*/resources/css/*")
+ || IsMatchesWildcard(filename, "monitoring*/resources/assets/fonts/*")
+ || IsMatchesWildcard(filename, "monitoring*/resources/favicon.png")) {
+ auto resPos = filename.find("/resources/");
+ if (resPos != TString::npos) {
+ filename = "monitoring" + filename.substr(resPos);
+ }
+ } else if (filename.StartsWith("monitoring") && filename != "monitoring/index.html") {
+ filename = "monitoring/index.html";
+ }
+ if (filename.EndsWith('/')) {
+ filename += "index.html";
+ }
+ if (ReplyWithFile(ev, ctx, filename)) {
+ return;
+ }
+ }
if (msg->Request.GetPathInfo() == "/tablet") {
ui64 id = FromStringWithDefault<ui64>(ev->Get()->Request.GetParams().Get("id"), 0);
- ctx.Send(ev->Sender, new NMon::TEvHttpInfoRes("HTTP/1.1 302 Found\r\nLocation: ../tablets?TabletID=" + ToString(id) + "\r\n\r\n", 0, NMon::IEvHttpInfoRes::EContentType::Custom));
- return;
- }
+ ctx.Send(ev->Sender, new NMon::TEvHttpInfoRes("HTTP/1.1 302 Found\r\nLocation: ../tablets?TabletID=" + ToString(id) + "\r\n\r\n", 0, NMon::IEvHttpInfoRes::EContentType::Custom));
+ return;
+ }
if (msg->Request.GetPathInfo().empty()) {
ctx.Send(ev->Sender, new NMon::TEvHttpInfoRes("HTTP/1.1 302 Found\r\nLocation: " + SplitPath(msg->Request.GetPage()->Path).back() + "/\r\n\r\n", 0, NMon::IEvHttpInfoRes::EContentType::Custom));
- return;
- }
- ctx.Send(ev->Sender, new NMon::TEvHttpInfoRes(NMonitoring::HTTPNOTFOUND));
- }
-};
-
+ return;
+ }
+ ctx.Send(ev->Sender, new NMon::TEvHttpInfoRes(NMonitoring::HTTPNOTFOUND));
+ }
+};
+
TString IViewer::TContentRequestContext::Dump() const
{
auto typeToString = [] (int type) -> TString {
@@ -469,7 +469,7 @@ TString IViewer::TContentRequestContext::Dump() const
return TStringBuilder() << "unknown (" << type << ")";
}
};
-
+
TStringBuilder result;
result << "Path = " << Path << Endl;
result << "Name = " << ObjectName << Endl;
@@ -486,100 +486,100 @@ TString IViewer::TContentRequestContext::Dump() const
return result;
}
-ui32 CurrentMonitoringPort = 8765;
-
+ui32 CurrentMonitoringPort = 8765;
+
IActor* CreateViewer(const TKikimrRunConfig &kikimrRunConfig) {
- CurrentMonitoringPort = kikimrRunConfig.AppConfig.GetMonitoringConfig().GetMonitoringPort();
+ CurrentMonitoringPort = kikimrRunConfig.AppConfig.GetMonitoringConfig().GetMonitoringPort();
return new TViewer(kikimrRunConfig);
-}
-
-TString IViewer::GetHTTPOKJSON() {
- const auto& kikimrRunConfig = GetKikimrRunConfig();
- TString allowOrigin = kikimrRunConfig.AppConfig.GetMonitoringConfig().GetAllowOrigin();
- if (allowOrigin) {
- return TStringBuilder()
- << "HTTP/1.1 200 Ok\r\n"
- << "Access-Control-Allow-Origin: " << allowOrigin << "\r\n"
- << "Access-Control-Allow-Credentials: true\r\n"
- << "Access-Control-Allow-Headers: Content-Type,Authorization,Origin,Accept\r\n"
- << "Access-Control-Allow-Methods: OPTIONS, GET, POST\r\n"
- << "Content-Type: application/json; charset=utf-8\r\n"
- << "Connection: Close\r\n"
- << "X-Worker-Name: " << FQDNHostName() << ":" << CurrentMonitoringPort << "\r\n"
- << "\r\n";
- } else {
- return TStringBuilder()
- << "HTTP/1.1 200 Ok\r\n"
- << "Content-Type: application/json; charset=utf-8\r\n"
- << "Connection: Close\r\n"
- << "X-Worker-Name: " << FQDNHostName() << ":" << CurrentMonitoringPort << "\r\n"
- << "\r\n";
- }
-}
-
-TString IViewer::GetHTTPGATEWAYTIMEOUT() {
- return TStringBuilder()
- << "HTTP/1.1 504 Gateway Time-out\r\nConnection: Close\r\n"
- << "X-Worker-Name: " << FQDNHostName() << ":" << CurrentMonitoringPort << "\r\n"
- << "\r\nGateway Time-out\r\n";
-}
-
-NKikimrViewer::EFlag GetFlagFromTabletState(NKikimrWhiteboard::TTabletStateInfo::ETabletState state) {
- NKikimrViewer::EFlag flag = NKikimrViewer::EFlag::Grey;
- switch (state) {
- case NKikimrWhiteboard::TTabletStateInfo::Created:
- case NKikimrWhiteboard::TTabletStateInfo::ResolveStateStorage:
- case NKikimrWhiteboard::TTabletStateInfo::Candidate:
- case NKikimrWhiteboard::TTabletStateInfo::BlockBlobStorage:
- case NKikimrWhiteboard::TTabletStateInfo::WriteZeroEntry:
- case NKikimrWhiteboard::TTabletStateInfo::Restored:
- case NKikimrWhiteboard::TTabletStateInfo::Discover:
- case NKikimrWhiteboard::TTabletStateInfo::Lock:
- case NKikimrWhiteboard::TTabletStateInfo::Dead:
- flag = NKikimrViewer::EFlag::Red;
- break;
- case NKikimrWhiteboard::TTabletStateInfo::RebuildGraph:
- flag = NKikimrViewer::EFlag::Orange;
- break;
+}
+
+TString IViewer::GetHTTPOKJSON() {
+ const auto& kikimrRunConfig = GetKikimrRunConfig();
+ TString allowOrigin = kikimrRunConfig.AppConfig.GetMonitoringConfig().GetAllowOrigin();
+ if (allowOrigin) {
+ return TStringBuilder()
+ << "HTTP/1.1 200 Ok\r\n"
+ << "Access-Control-Allow-Origin: " << allowOrigin << "\r\n"
+ << "Access-Control-Allow-Credentials: true\r\n"
+ << "Access-Control-Allow-Headers: Content-Type,Authorization,Origin,Accept\r\n"
+ << "Access-Control-Allow-Methods: OPTIONS, GET, POST\r\n"
+ << "Content-Type: application/json; charset=utf-8\r\n"
+ << "Connection: Close\r\n"
+ << "X-Worker-Name: " << FQDNHostName() << ":" << CurrentMonitoringPort << "\r\n"
+ << "\r\n";
+ } else {
+ return TStringBuilder()
+ << "HTTP/1.1 200 Ok\r\n"
+ << "Content-Type: application/json; charset=utf-8\r\n"
+ << "Connection: Close\r\n"
+ << "X-Worker-Name: " << FQDNHostName() << ":" << CurrentMonitoringPort << "\r\n"
+ << "\r\n";
+ }
+}
+
+TString IViewer::GetHTTPGATEWAYTIMEOUT() {
+ return TStringBuilder()
+ << "HTTP/1.1 504 Gateway Time-out\r\nConnection: Close\r\n"
+ << "X-Worker-Name: " << FQDNHostName() << ":" << CurrentMonitoringPort << "\r\n"
+ << "\r\nGateway Time-out\r\n";
+}
+
+NKikimrViewer::EFlag GetFlagFromTabletState(NKikimrWhiteboard::TTabletStateInfo::ETabletState state) {
+ NKikimrViewer::EFlag flag = NKikimrViewer::EFlag::Grey;
+ switch (state) {
+ case NKikimrWhiteboard::TTabletStateInfo::Created:
+ case NKikimrWhiteboard::TTabletStateInfo::ResolveStateStorage:
+ case NKikimrWhiteboard::TTabletStateInfo::Candidate:
+ case NKikimrWhiteboard::TTabletStateInfo::BlockBlobStorage:
+ case NKikimrWhiteboard::TTabletStateInfo::WriteZeroEntry:
+ case NKikimrWhiteboard::TTabletStateInfo::Restored:
+ case NKikimrWhiteboard::TTabletStateInfo::Discover:
+ case NKikimrWhiteboard::TTabletStateInfo::Lock:
+ case NKikimrWhiteboard::TTabletStateInfo::Dead:
+ flag = NKikimrViewer::EFlag::Red;
+ break;
+ case NKikimrWhiteboard::TTabletStateInfo::RebuildGraph:
+ flag = NKikimrViewer::EFlag::Orange;
+ break;
case NKikimrWhiteboard::TTabletStateInfo::ResolveLeader:
- flag = NKikimrViewer::EFlag::Yellow;
- break;
- case NKikimrWhiteboard::TTabletStateInfo::Deleted:
- case NKikimrWhiteboard::TTabletStateInfo::Active:
- flag = NKikimrViewer::EFlag::Green;
- break;
- default:
- break;
- }
- return flag;
-}
-
-NKikimrViewer::EFlag GetFlagFromUsage(double usage) {
- NKikimrViewer::EFlag flag = NKikimrViewer::EFlag::Grey;
- if (usage >= 0.94) {
- flag = NKikimrViewer::EFlag::Red;
- } else if (usage >= 0.92) {
- flag = NKikimrViewer::EFlag::Orange;
- } else if (usage >= 0.85) {
- flag = NKikimrViewer::EFlag::Yellow;
- } else {
- flag = NKikimrViewer::EFlag::Green;
- }
- return flag;
-}
-
-NKikimrViewer::EFlag GetPDiskStateFlag(const NKikimrWhiteboard::TPDiskStateInfo& info) {
- NKikimrViewer::EFlag flag = NKikimrViewer::EFlag::Grey;
- switch (info.GetState()) {
+ flag = NKikimrViewer::EFlag::Yellow;
+ break;
+ case NKikimrWhiteboard::TTabletStateInfo::Deleted:
+ case NKikimrWhiteboard::TTabletStateInfo::Active:
+ flag = NKikimrViewer::EFlag::Green;
+ break;
+ default:
+ break;
+ }
+ return flag;
+}
+
+NKikimrViewer::EFlag GetFlagFromUsage(double usage) {
+ NKikimrViewer::EFlag flag = NKikimrViewer::EFlag::Grey;
+ if (usage >= 0.94) {
+ flag = NKikimrViewer::EFlag::Red;
+ } else if (usage >= 0.92) {
+ flag = NKikimrViewer::EFlag::Orange;
+ } else if (usage >= 0.85) {
+ flag = NKikimrViewer::EFlag::Yellow;
+ } else {
+ flag = NKikimrViewer::EFlag::Green;
+ }
+ return flag;
+}
+
+NKikimrViewer::EFlag GetPDiskStateFlag(const NKikimrWhiteboard::TPDiskStateInfo& info) {
+ NKikimrViewer::EFlag flag = NKikimrViewer::EFlag::Grey;
+ switch (info.GetState()) {
case NKikimrBlobStorage::TPDiskState::Normal:
- flag = NKikimrViewer::EFlag::Green;
- break;
+ flag = NKikimrViewer::EFlag::Green;
+ break;
case NKikimrBlobStorage::TPDiskState::Initial:
case NKikimrBlobStorage::TPDiskState::InitialFormatRead:
case NKikimrBlobStorage::TPDiskState::InitialSysLogRead:
case NKikimrBlobStorage::TPDiskState::InitialCommonLogRead:
- flag = NKikimrViewer::EFlag::Yellow;
- break;
+ flag = NKikimrViewer::EFlag::Yellow;
+ break;
case NKikimrBlobStorage::TPDiskState::InitialFormatReadError:
case NKikimrBlobStorage::TPDiskState::InitialSysLogReadError:
case NKikimrBlobStorage::TPDiskState::InitialSysLogParseError:
@@ -587,207 +587,207 @@ NKikimrViewer::EFlag GetPDiskStateFlag(const NKikimrWhiteboard::TPDiskStateInfo&
case NKikimrBlobStorage::TPDiskState::InitialCommonLogParseError:
case NKikimrBlobStorage::TPDiskState::CommonLoggerInitError:
case NKikimrBlobStorage::TPDiskState::OpenFileError:
- flag = NKikimrViewer::EFlag::Red;
- break;
- default:
- flag = NKikimrViewer::EFlag::Red;
- break;
- }
- return flag;
-}
-
-NKikimrViewer::EFlag GetPDiskOverallFlag(const NKikimrWhiteboard::TPDiskStateInfo& info) {
- NKikimrViewer::EFlag flag = NKikimrViewer::EFlag::Grey;
- flag = Max(flag, GetPDiskStateFlag(info));
- if (info.HasDevice()) {
- flag = Max(flag, Min(NKikimrViewer::EFlag::Orange, GetViewerFlag(info.GetDevice())));
- }
- if (info.HasRealtime()) {
- flag = Max(flag, Min(NKikimrViewer::EFlag::Orange, GetViewerFlag(info.GetRealtime())));
- }
- if (info.HasAvailableSize() && info.GetTotalSize() != 0) {
- double avail = (double)info.GetAvailableSize() / info.GetTotalSize();
- if (avail <= 0.06) {
- flag = Max(flag, NKikimrViewer::EFlag::Red);
- } else if (avail <= 0.08) {
- flag = Max(flag, NKikimrViewer::EFlag::Orange);
- } else if (avail <= 0.15) {
- flag = Max(flag, NKikimrViewer::EFlag::Yellow);
- }
- }
- return flag;
-}
-
-NKikimrViewer::EFlag GetVDiskOverallFlag(const NKikimrWhiteboard::TVDiskStateInfo& info) {
- NKikimrViewer::EFlag flag = NKikimrViewer::EFlag::Grey;
- switch (info.GetVDiskState()) {
- case NKikimrWhiteboard::EVDiskState::Initial:
- case NKikimrWhiteboard::EVDiskState::SyncGuidRecovery:
- flag = NKikimrViewer::EFlag::Yellow;
- break;
- case NKikimrWhiteboard::EVDiskState::LocalRecoveryError:
- case NKikimrWhiteboard::EVDiskState::SyncGuidRecoveryError:
- case NKikimrWhiteboard::EVDiskState::PDiskError:
- flag = NKikimrViewer::EFlag::Red;
- break;
- case NKikimrWhiteboard::EVDiskState::OK:
- flag = NKikimrViewer::EFlag::Green;
- break;
- default:
- flag = NKikimrViewer::EFlag::Red;
- break;
- }
- if (info.HasDiskSpace()) {
- flag = Max(flag, GetViewerFlag(info.GetDiskSpace()));
- }
- if (info.HasSatisfactionRank()
- && info.GetSatisfactionRank().HasFreshRank()
- && info.GetSatisfactionRank().GetFreshRank().HasFlag()) {
- flag = Max(flag, Min(NKikimrViewer::EFlag::Orange, GetViewerFlag(info.GetSatisfactionRank().GetFreshRank().GetFlag())));
- }
- if (info.HasSatisfactionRank()
- && info.GetSatisfactionRank().HasLevelRank()
- && info.GetSatisfactionRank().GetLevelRank().HasFlag()) {
- flag = Max(flag, Min(NKikimrViewer::EFlag::Orange, GetViewerFlag(info.GetSatisfactionRank().GetLevelRank().GetFlag())));
- }
- if (info.HasFrontQueues()) {
- flag = Max(flag, Min(NKikimrViewer::EFlag::Orange, GetViewerFlag(info.GetFrontQueues())));
- }
- if (info.HasReplicated() && !info.GetReplicated()) {
- flag = Max(flag, NKikimrViewer::EFlag::Blue);
- }
- return flag;
-}
-
-TBSGroupState GetBSGroupOverallStateWithoutLatency(
- const NKikimrWhiteboard::TBSGroupStateInfo& info,
- const TMap<NKikimrBlobStorage::TVDiskID, const NKikimrWhiteboard::TVDiskStateInfo&>& vDisksIndex,
- const TMap<std::pair<ui32, ui32>, const NKikimrWhiteboard::TPDiskStateInfo&>& pDisksIndex) {
-
- TBSGroupState groupState;
- groupState.Overall = NKikimrViewer::EFlag::Grey;
-
- const auto& vDiskIds = info.GetVDiskIds();
- std::unordered_map<ui32, ui32> failedRings;
- std::unordered_map<ui32, ui32> failedDomains;
- TVector<NKikimrViewer::EFlag> vDiskFlags;
- vDiskFlags.reserve(vDiskIds.size());
- for (auto iv = vDiskIds.begin(); iv != vDiskIds.end(); ++iv) {
- const NKikimrBlobStorage::TVDiskID& vDiskId = *iv;
- NKikimrViewer::EFlag flag = NKikimrViewer::EFlag::Grey;
- auto ie = vDisksIndex.find(vDiskId);
- if (ie != vDisksIndex.end()) {
- auto pDiskId = std::make_pair(ie->second.GetNodeId(), ie->second.GetPDiskId());
- auto ip = pDisksIndex.find(pDiskId);
- if (ip != pDisksIndex.end()) {
- const NKikimrWhiteboard::TPDiskStateInfo& pDiskInfo(ip->second);
- flag = Max(flag, GetPDiskOverallFlag(pDiskInfo));
- } else {
- flag = NKikimrViewer::EFlag::Red;
- }
- const NKikimrWhiteboard::TVDiskStateInfo& vDiskInfo(ie->second);
- flag = Max(flag, GetVDiskOverallFlag(vDiskInfo));
- if (vDiskInfo.GetDiskSpace() > NKikimrWhiteboard::EFlag::Green) {
- groupState.SpaceProblems++;
- }
- } else {
- flag = NKikimrViewer::EFlag::Red;
- }
- vDiskFlags.push_back(flag);
- if (flag == NKikimrViewer::EFlag::Red || flag == NKikimrViewer::EFlag::Blue) {
- groupState.MissingDisks++;
- ++failedRings[vDiskId.GetRing()];
- ++failedDomains[vDiskId.GetDomain()];
- }
- groupState.Overall = Max(groupState.Overall, flag);
- }
-
- groupState.Overall = Min(groupState.Overall, NKikimrViewer::EFlag::Yellow); // without failed rings we only allow to raise group status up to Blue/Yellow
- TString erasure = info.GetErasureSpecies();
- if (erasure == TErasureType::ErasureSpeciesName(TErasureType::ErasureNone)) {
- if (!failedDomains.empty()) {
- groupState.Overall = NKikimrViewer::EFlag::Red;
- }
- } else if (erasure == TErasureType::ErasureSpeciesName(TErasureType::ErasureMirror3dc)) {
- if (failedRings.size() > 2) {
- groupState.Overall = NKikimrViewer::EFlag::Red;
- } else if (failedRings.size() == 2) { // TODO: check for 1 ring - 1 domain rule
- groupState.Overall = NKikimrViewer::EFlag::Orange;
- } else if (failedRings.size() > 0) {
- groupState.Overall = Min(groupState.Overall, NKikimrViewer::EFlag::Yellow);
- }
- } else if (erasure == TErasureType::ErasureSpeciesName(TErasureType::Erasure4Plus2Block)) {
- if (failedDomains.size() > 2) {
- groupState.Overall = NKikimrViewer::EFlag::Red;
- } else if (failedDomains.size() > 1) {
- groupState.Overall = NKikimrViewer::EFlag::Orange;
- } else if (failedDomains.size() > 0) {
- groupState.Overall = Min(groupState.Overall, NKikimrViewer::EFlag::Yellow);
- }
- }
- return groupState;
-}
-
-NKikimrViewer::EFlag GetBSGroupOverallFlagWithoutLatency(
- const NKikimrWhiteboard::TBSGroupStateInfo& info,
- const TMap<NKikimrBlobStorage::TVDiskID, const NKikimrWhiteboard::TVDiskStateInfo&>& vDisksIndex,
- const TMap<std::pair<ui32, ui32>, const NKikimrWhiteboard::TPDiskStateInfo&>& pDisksIndex) {
- return GetBSGroupOverallStateWithoutLatency(info, vDisksIndex, pDisksIndex).Overall;
-}
-
-TBSGroupState GetBSGroupOverallState(
- const NKikimrWhiteboard::TBSGroupStateInfo& info,
- const TMap<NKikimrBlobStorage::TVDiskID, const NKikimrWhiteboard::TVDiskStateInfo&>& vDisksIndex,
- const TMap<std::pair<ui32, ui32>, const NKikimrWhiteboard::TPDiskStateInfo&>& pDisksIndex) {
- TBSGroupState state = GetBSGroupOverallStateWithoutLatency(info, vDisksIndex, pDisksIndex);
- if (info.HasLatency()) {
- state.Overall = Max(state.Overall, Min(NKikimrViewer::EFlag::Yellow, GetViewerFlag(info.GetLatency())));
- }
- return state;
-}
-
-NKikimrViewer::EFlag GetBSGroupOverallFlag(
- const NKikimrWhiteboard::TBSGroupStateInfo& info,
- const TMap<NKikimrBlobStorage::TVDiskID, const NKikimrWhiteboard::TVDiskStateInfo&>& vDisksIndex,
- const TMap<std::pair<ui32, ui32>, const NKikimrWhiteboard::TPDiskStateInfo&>& pDisksIndex) {
- return GetBSGroupOverallState(info, vDisksIndex, pDisksIndex).Overall;
-}
-
-NKikimrWhiteboard::EFlag GetWhiteboardFlag(NKikimrViewer::EFlag flag) {
- switch (flag) {
- case NKikimrViewer::EFlag::Grey:
- case NKikimrViewer::EFlag::EFlag_INT_MIN_SENTINEL_DO_NOT_USE_:
- case NKikimrViewer::EFlag::EFlag_INT_MAX_SENTINEL_DO_NOT_USE_:
- return NKikimrWhiteboard::EFlag::Grey;
- case NKikimrViewer::EFlag::Green:
- return NKikimrWhiteboard::EFlag::Green;
- case NKikimrViewer::EFlag::Blue:
- return NKikimrWhiteboard::EFlag::Green;
- case NKikimrViewer::EFlag::Yellow:
- return NKikimrWhiteboard::EFlag::Yellow;
- case NKikimrViewer::EFlag::Orange:
- return NKikimrWhiteboard::EFlag::Orange;
- case NKikimrViewer::EFlag::Red:
- return NKikimrWhiteboard::EFlag::Red;
- }
-}
-
-NKikimrViewer::EFlag GetViewerFlag(NKikimrWhiteboard::EFlag flag) {
- switch (flag) {
- case NKikimrWhiteboard::EFlag::Grey:
- return NKikimrViewer::EFlag::Grey;
- case NKikimrWhiteboard::EFlag::Green:
- return NKikimrViewer::EFlag::Green;
- case NKikimrWhiteboard::EFlag::Yellow:
- return NKikimrViewer::EFlag::Yellow;
- case NKikimrWhiteboard::EFlag::Orange:
- return NKikimrViewer::EFlag::Orange;
- case NKikimrWhiteboard::EFlag::Red:
- return NKikimrViewer::EFlag::Red;
- }
- return static_cast<NKikimrViewer::EFlag>((int)flag);
-}
-
-
-} // NNodeTabletMonitor
-} // NKikimr
+ flag = NKikimrViewer::EFlag::Red;
+ break;
+ default:
+ flag = NKikimrViewer::EFlag::Red;
+ break;
+ }
+ return flag;
+}
+
+NKikimrViewer::EFlag GetPDiskOverallFlag(const NKikimrWhiteboard::TPDiskStateInfo& info) {
+ NKikimrViewer::EFlag flag = NKikimrViewer::EFlag::Grey;
+ flag = Max(flag, GetPDiskStateFlag(info));
+ if (info.HasDevice()) {
+ flag = Max(flag, Min(NKikimrViewer::EFlag::Orange, GetViewerFlag(info.GetDevice())));
+ }
+ if (info.HasRealtime()) {
+ flag = Max(flag, Min(NKikimrViewer::EFlag::Orange, GetViewerFlag(info.GetRealtime())));
+ }
+ if (info.HasAvailableSize() && info.GetTotalSize() != 0) {
+ double avail = (double)info.GetAvailableSize() / info.GetTotalSize();
+ if (avail <= 0.06) {
+ flag = Max(flag, NKikimrViewer::EFlag::Red);
+ } else if (avail <= 0.08) {
+ flag = Max(flag, NKikimrViewer::EFlag::Orange);
+ } else if (avail <= 0.15) {
+ flag = Max(flag, NKikimrViewer::EFlag::Yellow);
+ }
+ }
+ return flag;
+}
+
+NKikimrViewer::EFlag GetVDiskOverallFlag(const NKikimrWhiteboard::TVDiskStateInfo& info) {
+ NKikimrViewer::EFlag flag = NKikimrViewer::EFlag::Grey;
+ switch (info.GetVDiskState()) {
+ case NKikimrWhiteboard::EVDiskState::Initial:
+ case NKikimrWhiteboard::EVDiskState::SyncGuidRecovery:
+ flag = NKikimrViewer::EFlag::Yellow;
+ break;
+ case NKikimrWhiteboard::EVDiskState::LocalRecoveryError:
+ case NKikimrWhiteboard::EVDiskState::SyncGuidRecoveryError:
+ case NKikimrWhiteboard::EVDiskState::PDiskError:
+ flag = NKikimrViewer::EFlag::Red;
+ break;
+ case NKikimrWhiteboard::EVDiskState::OK:
+ flag = NKikimrViewer::EFlag::Green;
+ break;
+ default:
+ flag = NKikimrViewer::EFlag::Red;
+ break;
+ }
+ if (info.HasDiskSpace()) {
+ flag = Max(flag, GetViewerFlag(info.GetDiskSpace()));
+ }
+ if (info.HasSatisfactionRank()
+ && info.GetSatisfactionRank().HasFreshRank()
+ && info.GetSatisfactionRank().GetFreshRank().HasFlag()) {
+ flag = Max(flag, Min(NKikimrViewer::EFlag::Orange, GetViewerFlag(info.GetSatisfactionRank().GetFreshRank().GetFlag())));
+ }
+ if (info.HasSatisfactionRank()
+ && info.GetSatisfactionRank().HasLevelRank()
+ && info.GetSatisfactionRank().GetLevelRank().HasFlag()) {
+ flag = Max(flag, Min(NKikimrViewer::EFlag::Orange, GetViewerFlag(info.GetSatisfactionRank().GetLevelRank().GetFlag())));
+ }
+ if (info.HasFrontQueues()) {
+ flag = Max(flag, Min(NKikimrViewer::EFlag::Orange, GetViewerFlag(info.GetFrontQueues())));
+ }
+ if (info.HasReplicated() && !info.GetReplicated()) {
+ flag = Max(flag, NKikimrViewer::EFlag::Blue);
+ }
+ return flag;
+}
+
+TBSGroupState GetBSGroupOverallStateWithoutLatency(
+ const NKikimrWhiteboard::TBSGroupStateInfo& info,
+ const TMap<NKikimrBlobStorage::TVDiskID, const NKikimrWhiteboard::TVDiskStateInfo&>& vDisksIndex,
+ const TMap<std::pair<ui32, ui32>, const NKikimrWhiteboard::TPDiskStateInfo&>& pDisksIndex) {
+
+ TBSGroupState groupState;
+ groupState.Overall = NKikimrViewer::EFlag::Grey;
+
+ const auto& vDiskIds = info.GetVDiskIds();
+ std::unordered_map<ui32, ui32> failedRings;
+ std::unordered_map<ui32, ui32> failedDomains;
+ TVector<NKikimrViewer::EFlag> vDiskFlags;
+ vDiskFlags.reserve(vDiskIds.size());
+ for (auto iv = vDiskIds.begin(); iv != vDiskIds.end(); ++iv) {
+ const NKikimrBlobStorage::TVDiskID& vDiskId = *iv;
+ NKikimrViewer::EFlag flag = NKikimrViewer::EFlag::Grey;
+ auto ie = vDisksIndex.find(vDiskId);
+ if (ie != vDisksIndex.end()) {
+ auto pDiskId = std::make_pair(ie->second.GetNodeId(), ie->second.GetPDiskId());
+ auto ip = pDisksIndex.find(pDiskId);
+ if (ip != pDisksIndex.end()) {
+ const NKikimrWhiteboard::TPDiskStateInfo& pDiskInfo(ip->second);
+ flag = Max(flag, GetPDiskOverallFlag(pDiskInfo));
+ } else {
+ flag = NKikimrViewer::EFlag::Red;
+ }
+ const NKikimrWhiteboard::TVDiskStateInfo& vDiskInfo(ie->second);
+ flag = Max(flag, GetVDiskOverallFlag(vDiskInfo));
+ if (vDiskInfo.GetDiskSpace() > NKikimrWhiteboard::EFlag::Green) {
+ groupState.SpaceProblems++;
+ }
+ } else {
+ flag = NKikimrViewer::EFlag::Red;
+ }
+ vDiskFlags.push_back(flag);
+ if (flag == NKikimrViewer::EFlag::Red || flag == NKikimrViewer::EFlag::Blue) {
+ groupState.MissingDisks++;
+ ++failedRings[vDiskId.GetRing()];
+ ++failedDomains[vDiskId.GetDomain()];
+ }
+ groupState.Overall = Max(groupState.Overall, flag);
+ }
+
+ groupState.Overall = Min(groupState.Overall, NKikimrViewer::EFlag::Yellow); // without failed rings we only allow to raise group status up to Blue/Yellow
+ TString erasure = info.GetErasureSpecies();
+ if (erasure == TErasureType::ErasureSpeciesName(TErasureType::ErasureNone)) {
+ if (!failedDomains.empty()) {
+ groupState.Overall = NKikimrViewer::EFlag::Red;
+ }
+ } else if (erasure == TErasureType::ErasureSpeciesName(TErasureType::ErasureMirror3dc)) {
+ if (failedRings.size() > 2) {
+ groupState.Overall = NKikimrViewer::EFlag::Red;
+ } else if (failedRings.size() == 2) { // TODO: check for 1 ring - 1 domain rule
+ groupState.Overall = NKikimrViewer::EFlag::Orange;
+ } else if (failedRings.size() > 0) {
+ groupState.Overall = Min(groupState.Overall, NKikimrViewer::EFlag::Yellow);
+ }
+ } else if (erasure == TErasureType::ErasureSpeciesName(TErasureType::Erasure4Plus2Block)) {
+ if (failedDomains.size() > 2) {
+ groupState.Overall = NKikimrViewer::EFlag::Red;
+ } else if (failedDomains.size() > 1) {
+ groupState.Overall = NKikimrViewer::EFlag::Orange;
+ } else if (failedDomains.size() > 0) {
+ groupState.Overall = Min(groupState.Overall, NKikimrViewer::EFlag::Yellow);
+ }
+ }
+ return groupState;
+}
+
+NKikimrViewer::EFlag GetBSGroupOverallFlagWithoutLatency(
+ const NKikimrWhiteboard::TBSGroupStateInfo& info,
+ const TMap<NKikimrBlobStorage::TVDiskID, const NKikimrWhiteboard::TVDiskStateInfo&>& vDisksIndex,
+ const TMap<std::pair<ui32, ui32>, const NKikimrWhiteboard::TPDiskStateInfo&>& pDisksIndex) {
+ return GetBSGroupOverallStateWithoutLatency(info, vDisksIndex, pDisksIndex).Overall;
+}
+
+TBSGroupState GetBSGroupOverallState(
+ const NKikimrWhiteboard::TBSGroupStateInfo& info,
+ const TMap<NKikimrBlobStorage::TVDiskID, const NKikimrWhiteboard::TVDiskStateInfo&>& vDisksIndex,
+ const TMap<std::pair<ui32, ui32>, const NKikimrWhiteboard::TPDiskStateInfo&>& pDisksIndex) {
+ TBSGroupState state = GetBSGroupOverallStateWithoutLatency(info, vDisksIndex, pDisksIndex);
+ if (info.HasLatency()) {
+ state.Overall = Max(state.Overall, Min(NKikimrViewer::EFlag::Yellow, GetViewerFlag(info.GetLatency())));
+ }
+ return state;
+}
+
+NKikimrViewer::EFlag GetBSGroupOverallFlag(
+ const NKikimrWhiteboard::TBSGroupStateInfo& info,
+ const TMap<NKikimrBlobStorage::TVDiskID, const NKikimrWhiteboard::TVDiskStateInfo&>& vDisksIndex,
+ const TMap<std::pair<ui32, ui32>, const NKikimrWhiteboard::TPDiskStateInfo&>& pDisksIndex) {
+ return GetBSGroupOverallState(info, vDisksIndex, pDisksIndex).Overall;
+}
+
+NKikimrWhiteboard::EFlag GetWhiteboardFlag(NKikimrViewer::EFlag flag) {
+ switch (flag) {
+ case NKikimrViewer::EFlag::Grey:
+ case NKikimrViewer::EFlag::EFlag_INT_MIN_SENTINEL_DO_NOT_USE_:
+ case NKikimrViewer::EFlag::EFlag_INT_MAX_SENTINEL_DO_NOT_USE_:
+ return NKikimrWhiteboard::EFlag::Grey;
+ case NKikimrViewer::EFlag::Green:
+ return NKikimrWhiteboard::EFlag::Green;
+ case NKikimrViewer::EFlag::Blue:
+ return NKikimrWhiteboard::EFlag::Green;
+ case NKikimrViewer::EFlag::Yellow:
+ return NKikimrWhiteboard::EFlag::Yellow;
+ case NKikimrViewer::EFlag::Orange:
+ return NKikimrWhiteboard::EFlag::Orange;
+ case NKikimrViewer::EFlag::Red:
+ return NKikimrWhiteboard::EFlag::Red;
+ }
+}
+
+NKikimrViewer::EFlag GetViewerFlag(NKikimrWhiteboard::EFlag flag) {
+ switch (flag) {
+ case NKikimrWhiteboard::EFlag::Grey:
+ return NKikimrViewer::EFlag::Grey;
+ case NKikimrWhiteboard::EFlag::Green:
+ return NKikimrViewer::EFlag::Green;
+ case NKikimrWhiteboard::EFlag::Yellow:
+ return NKikimrViewer::EFlag::Yellow;
+ case NKikimrWhiteboard::EFlag::Orange:
+ return NKikimrViewer::EFlag::Orange;
+ case NKikimrWhiteboard::EFlag::Red:
+ return NKikimrViewer::EFlag::Red;
+ }
+ return static_cast<NKikimrViewer::EFlag>((int)flag);
+}
+
+
+} // NNodeTabletMonitor
+} // NKikimr
diff --git a/ydb/core/viewer/viewer.h b/ydb/core/viewer/viewer.h
index 8e245b74622..ab34762e3ed 100644
--- a/ydb/core/viewer/viewer.h
+++ b/ydb/core/viewer/viewer.h
@@ -1,5 +1,5 @@
-#pragma once
-
+#pragma once
+
#include <ydb/core/viewer/json/json.h>
#include <ydb/core/tablet/defs.h>
@@ -8,82 +8,82 @@
#include <library/cpp/actors/core/event.h>
#include <ydb/core/driver_lib/run/config.h>
#include <ydb/core/viewer/protos/viewer.pb.h>
-#include <util/system/hostname.h>
-
-namespace NKikimr {
-namespace NViewer {
-
+#include <util/system/hostname.h>
+
+namespace NKikimr {
+namespace NViewer {
+
inline TActorId MakeViewerID(ui32 node = 0) {
- char x[12] = {'v','i','e','w','e','r'};
+ char x[12] = {'v','i','e','w','e','r'};
return TActorId(node, TStringBuf(x, 12));
-}
-
+}
+
IActor* CreateViewer(const TKikimrRunConfig &kikimrRunConfig);
-
-class IViewer {
-public:
- struct TBrowseContext {
- struct TPathEntry {
- NKikimrViewer::EObjectType Type;
- TString Name;
- };
-
- TString Path;
+
+class IViewer {
+public:
+ struct TBrowseContext {
+ struct TPathEntry {
+ NKikimrViewer::EObjectType Type;
+ TString Name;
+ };
+
+ TString Path;
TVector<TPathEntry> Paths;
TActorId Owner;
- TString UserToken;
-
+ TString UserToken;
+
TBrowseContext(const TActorId owner, const TString& userToken)
- : Owner(owner)
- , UserToken(userToken)
- {}
-
- const TString& GetMyName() const {
- static TString emptyName;
- if (Paths.empty()) {
- return emptyName;
- }
- return Paths.back().Name;
- }
-
- NKikimrViewer::EObjectType GetMyType() const {
- if (Paths.empty()) {
- return NKikimrViewer::EObjectType::Unknown;
- }
- return Paths.back().Type;
- }
-
- const TString& GetParentName() const {
- static TString emptyName;
- if (Paths.size() < 2) {
- return emptyName;
- }
- return (Paths.rbegin() + 1)->Name;
- }
-
- NKikimrViewer::EObjectType GetParentType() const {
- if (Paths.size() < 2) {
- return NKikimrViewer::EObjectType::Unknown;
- }
- return (Paths.rbegin() + 1)->Type;
- }
- };
-
+ : Owner(owner)
+ , UserToken(userToken)
+ {}
+
+ const TString& GetMyName() const {
+ static TString emptyName;
+ if (Paths.empty()) {
+ return emptyName;
+ }
+ return Paths.back().Name;
+ }
+
+ NKikimrViewer::EObjectType GetMyType() const {
+ if (Paths.empty()) {
+ return NKikimrViewer::EObjectType::Unknown;
+ }
+ return Paths.back().Type;
+ }
+
+ const TString& GetParentName() const {
+ static TString emptyName;
+ if (Paths.size() < 2) {
+ return emptyName;
+ }
+ return (Paths.rbegin() + 1)->Name;
+ }
+
+ NKikimrViewer::EObjectType GetParentType() const {
+ if (Paths.size() < 2) {
+ return NKikimrViewer::EObjectType::Unknown;
+ }
+ return (Paths.rbegin() + 1)->Type;
+ }
+ };
+
using TVirtualHandlerType = std::function<IActor*(const TActorId& owner, const TBrowseContext& context)>;
-
- struct TVirtualHandler {
- IViewer::TVirtualHandlerType BrowseHandler = nullptr;
-
- TVirtualHandler(IViewer::TVirtualHandlerType browseHandler)
- : BrowseHandler(browseHandler)
- {}
- };
-
+
+ struct TVirtualHandler {
+ IViewer::TVirtualHandlerType BrowseHandler = nullptr;
+
+ TVirtualHandler(IViewer::TVirtualHandlerType browseHandler)
+ : BrowseHandler(browseHandler)
+ {}
+ };
+
struct TContentRequestContext {
// request settings
TJsonSettings JsonSettings;
TDuration Timeout = TDuration::MilliSeconds(10000);
- TString UserToken;
+ TString UserToken;
// filter
ui32 Limit = 50;
@@ -102,9 +102,9 @@ public:
using TContentHandler = std::function<IActor*(const TActorId&, const TContentRequestContext&)>;
- virtual const TKikimrRunConfig& GetKikimrRunConfig() const = 0;
+ virtual const TKikimrRunConfig& GetKikimrRunConfig() const = 0;
virtual TVector<const TVirtualHandler*> GetVirtualHandlers(NKikimrViewer::EObjectType type, const TString& path) const = 0;
- virtual void RegisterVirtualHandler(NKikimrViewer::EObjectType parentObjectType, TVirtualHandlerType handler) = 0;
+ virtual void RegisterVirtualHandler(NKikimrViewer::EObjectType parentObjectType, TVirtualHandlerType handler) = 0;
// returns nullptr if no such handler
virtual TContentHandler GetContentHandler(NKikimrViewer::EObjectType objectType) const = 0;
@@ -112,98 +112,98 @@ public:
virtual void RegisterContentHandler(
NKikimrViewer::EObjectType objectType,
const TContentHandler& handler) = 0;
-
- TString GetHTTPOKJSON();
- TString GetHTTPGATEWAYTIMEOUT();
-};
-
+
+ TString GetHTTPOKJSON();
+ TString GetHTTPGATEWAYTIMEOUT();
+};
+
void SetupPQVirtualHandlers(IViewer* viewer);
void SetupDBVirtualHandlers(IViewer* viewer);
void SetupKqpContentHandler(IViewer* viewer);
-template <typename RequestType>
-struct TJsonRequestSchema {
+template <typename RequestType>
+struct TJsonRequestSchema {
static TString GetSchema() { return TString(); }
-};
-
-template <typename RequestType>
-struct TJsonRequestSummary {
+};
+
+template <typename RequestType>
+struct TJsonRequestSummary {
static TString GetSummary() { return TString(); }
-};
-
-template <typename RequestType>
-struct TJsonRequestDescription {
+};
+
+template <typename RequestType>
+struct TJsonRequestDescription {
static TString GetDescription() { return TString(); }
-};
-
-template <typename RequestType>
-struct TJsonRequestParameters {
+};
+
+template <typename RequestType>
+struct TJsonRequestParameters {
static TString GetParameters() { return TString(); }
-};
-
-static const char HTTPOKJSON[] = "HTTP/1.1 200 Ok\r\nAccess-Control-Allow-Origin: *\r\nContent-Type: application/json; charset=utf-8\r\nConnection: Close\r\n\r\n";
-static const char HTTPOKTEXT[] = "HTTP/1.1 200 Ok\r\nAccess-Control-Allow-Origin: *\r\nContent-Type: text/plain; charset=utf-8\r\nConnection: Close\r\n\r\n";
-static const char HTTPFORBIDDENJSON[] = "HTTP/1.1 403 Ok\r\nAccess-Control-Allow-Origin: *\r\nContent-Type: application/json; charset=utf-8\r\nConnection: Close\r\n\r\n";
-static const char HTTPGATEWAYTIMEOUT[] = "HTTP/1.1 504 Gateway Time-out\r\nConnection: Close\r\n\r\nGateway Time-out\r\n";
-static const char HTTPBADREQUEST[] = "HTTP/1.1 400 Bad Request\r\nConnection: Close\r\n\r\nBad Request\r\n";
-static const char HTTPBADREQUEST_HEADERS[] = "HTTP/1.1 400 Bad Request\r\nConnection: Close\r\n\r\n";
-
-template <typename ValueType>
-void SplitIds(TStringBuf source, char delim, TVector<ValueType>& values) {
- for (TStringBuf value = source.NextTok(delim); !value.empty(); value = source.NextTok(delim)) {
- if (value == ".") {
- values.emplace_back(ValueType());
- } else {
- values.emplace_back(FromStringWithDefault<ValueType>(value, ValueType()));
- }
- }
-}
-
-template <typename ValueType>
-void SplitIds(TStringBuf source, char delim, std::vector<ValueType>& values) {
- for (TStringBuf value = source.NextTok(delim); !value.empty(); value = source.NextTok(delim)) {
- if (value == ".") {
- values.emplace_back(ValueType());
- } else {
- values.emplace_back(FromStringWithDefault<ValueType>(value, ValueType()));
- }
- }
-}
-
-TString GetHTTPOKJSON();
-TString GetHTTPGATEWAYTIMEOUT();
-NKikimrViewer::EFlag GetFlagFromTabletState(NKikimrWhiteboard::TTabletStateInfo::ETabletState state);
-NKikimrViewer::EFlag GetPDiskStateFlag(const NKikimrWhiteboard::TPDiskStateInfo& info);
-NKikimrViewer::EFlag GetPDiskOverallFlag(const NKikimrWhiteboard::TPDiskStateInfo& info);
-NKikimrViewer::EFlag GetVDiskOverallFlag(const NKikimrWhiteboard::TVDiskStateInfo& info);
-
-struct TBSGroupState {
- NKikimrViewer::EFlag Overall;
- ui32 MissingDisks = 0;
- ui32 SpaceProblems = 0;
-};
-
-NKikimrViewer::EFlag GetBSGroupOverallFlagWithoutLatency(
- const NKikimrWhiteboard::TBSGroupStateInfo& info,
- const TMap<NKikimrBlobStorage::TVDiskID, const NKikimrWhiteboard::TVDiskStateInfo&>& vDisksIndex,
- const TMap<std::pair<ui32, ui32>, const NKikimrWhiteboard::TPDiskStateInfo&>& pDisksIndex);
-TBSGroupState GetBSGroupOverallStateWithoutLatency(
- const NKikimrWhiteboard::TBSGroupStateInfo& info,
- const TMap<NKikimrBlobStorage::TVDiskID, const NKikimrWhiteboard::TVDiskStateInfo&>& vDisksIndex,
- const TMap<std::pair<ui32, ui32>, const NKikimrWhiteboard::TPDiskStateInfo&>& pDisksIndex);
-NKikimrViewer::EFlag GetBSGroupOverallFlag(
- const NKikimrWhiteboard::TBSGroupStateInfo& info,
- const TMap<NKikimrBlobStorage::TVDiskID, const NKikimrWhiteboard::TVDiskStateInfo&>& vDisksIndex,
- const TMap<std::pair<ui32, ui32>, const NKikimrWhiteboard::TPDiskStateInfo&>& pDisksIndex);
-TBSGroupState GetBSGroupOverallState(
- const NKikimrWhiteboard::TBSGroupStateInfo& info,
- const TMap<NKikimrBlobStorage::TVDiskID, const NKikimrWhiteboard::TVDiskStateInfo&>& vDisksIndex,
- const TMap<std::pair<ui32, ui32>, const NKikimrWhiteboard::TPDiskStateInfo&>& pDisksIndex);
-
-NKikimrViewer::EFlag GetFlagFromUsage(double usage);
-
-NKikimrWhiteboard::EFlag GetWhiteboardFlag(NKikimrViewer::EFlag flag);
-NKikimrViewer::EFlag GetViewerFlag(NKikimrWhiteboard::EFlag flag);
-
-} // NViewer
-} // NKikimr
+};
+
+static const char HTTPOKJSON[] = "HTTP/1.1 200 Ok\r\nAccess-Control-Allow-Origin: *\r\nContent-Type: application/json; charset=utf-8\r\nConnection: Close\r\n\r\n";
+static const char HTTPOKTEXT[] = "HTTP/1.1 200 Ok\r\nAccess-Control-Allow-Origin: *\r\nContent-Type: text/plain; charset=utf-8\r\nConnection: Close\r\n\r\n";
+static const char HTTPFORBIDDENJSON[] = "HTTP/1.1 403 Ok\r\nAccess-Control-Allow-Origin: *\r\nContent-Type: application/json; charset=utf-8\r\nConnection: Close\r\n\r\n";
+static const char HTTPGATEWAYTIMEOUT[] = "HTTP/1.1 504 Gateway Time-out\r\nConnection: Close\r\n\r\nGateway Time-out\r\n";
+static const char HTTPBADREQUEST[] = "HTTP/1.1 400 Bad Request\r\nConnection: Close\r\n\r\nBad Request\r\n";
+static const char HTTPBADREQUEST_HEADERS[] = "HTTP/1.1 400 Bad Request\r\nConnection: Close\r\n\r\n";
+
+template <typename ValueType>
+void SplitIds(TStringBuf source, char delim, TVector<ValueType>& values) {
+ for (TStringBuf value = source.NextTok(delim); !value.empty(); value = source.NextTok(delim)) {
+ if (value == ".") {
+ values.emplace_back(ValueType());
+ } else {
+ values.emplace_back(FromStringWithDefault<ValueType>(value, ValueType()));
+ }
+ }
+}
+
+template <typename ValueType>
+void SplitIds(TStringBuf source, char delim, std::vector<ValueType>& values) {
+ for (TStringBuf value = source.NextTok(delim); !value.empty(); value = source.NextTok(delim)) {
+ if (value == ".") {
+ values.emplace_back(ValueType());
+ } else {
+ values.emplace_back(FromStringWithDefault<ValueType>(value, ValueType()));
+ }
+ }
+}
+
+TString GetHTTPOKJSON();
+TString GetHTTPGATEWAYTIMEOUT();
+NKikimrViewer::EFlag GetFlagFromTabletState(NKikimrWhiteboard::TTabletStateInfo::ETabletState state);
+NKikimrViewer::EFlag GetPDiskStateFlag(const NKikimrWhiteboard::TPDiskStateInfo& info);
+NKikimrViewer::EFlag GetPDiskOverallFlag(const NKikimrWhiteboard::TPDiskStateInfo& info);
+NKikimrViewer::EFlag GetVDiskOverallFlag(const NKikimrWhiteboard::TVDiskStateInfo& info);
+
+struct TBSGroupState {
+ NKikimrViewer::EFlag Overall;
+ ui32 MissingDisks = 0;
+ ui32 SpaceProblems = 0;
+};
+
+NKikimrViewer::EFlag GetBSGroupOverallFlagWithoutLatency(
+ const NKikimrWhiteboard::TBSGroupStateInfo& info,
+ const TMap<NKikimrBlobStorage::TVDiskID, const NKikimrWhiteboard::TVDiskStateInfo&>& vDisksIndex,
+ const TMap<std::pair<ui32, ui32>, const NKikimrWhiteboard::TPDiskStateInfo&>& pDisksIndex);
+TBSGroupState GetBSGroupOverallStateWithoutLatency(
+ const NKikimrWhiteboard::TBSGroupStateInfo& info,
+ const TMap<NKikimrBlobStorage::TVDiskID, const NKikimrWhiteboard::TVDiskStateInfo&>& vDisksIndex,
+ const TMap<std::pair<ui32, ui32>, const NKikimrWhiteboard::TPDiskStateInfo&>& pDisksIndex);
+NKikimrViewer::EFlag GetBSGroupOverallFlag(
+ const NKikimrWhiteboard::TBSGroupStateInfo& info,
+ const TMap<NKikimrBlobStorage::TVDiskID, const NKikimrWhiteboard::TVDiskStateInfo&>& vDisksIndex,
+ const TMap<std::pair<ui32, ui32>, const NKikimrWhiteboard::TPDiskStateInfo&>& pDisksIndex);
+TBSGroupState GetBSGroupOverallState(
+ const NKikimrWhiteboard::TBSGroupStateInfo& info,
+ const TMap<NKikimrBlobStorage::TVDiskID, const NKikimrWhiteboard::TVDiskStateInfo&>& vDisksIndex,
+ const TMap<std::pair<ui32, ui32>, const NKikimrWhiteboard::TPDiskStateInfo&>& pDisksIndex);
+
+NKikimrViewer::EFlag GetFlagFromUsage(double usage);
+
+NKikimrWhiteboard::EFlag GetWhiteboardFlag(NKikimrViewer::EFlag flag);
+NKikimrViewer::EFlag GetViewerFlag(NKikimrWhiteboard::EFlag flag);
+
+} // NViewer
+} // NKikimr
diff --git a/ydb/core/viewer/viewer_ut.cpp b/ydb/core/viewer/viewer_ut.cpp
index 3e4e7df1f25..020239e8a5f 100644
--- a/ydb/core/viewer/viewer_ut.cpp
+++ b/ydb/core/viewer/viewer_ut.cpp
@@ -1,88 +1,88 @@
-#include <library/cpp/testing/unittest/registar.h>
-#include <library/cpp/testing/unittest/tests_data.h>
-#include <library/cpp/actors/interconnect/interconnect.h>
-#include <util/stream/null.h>
+#include <library/cpp/testing/unittest/registar.h>
+#include <library/cpp/testing/unittest/tests_data.h>
+#include <library/cpp/actors/interconnect/interconnect.h>
+#include <util/stream/null.h>
#include <ydb/core/viewer/protos/viewer.pb.h>
-#include "json_tabletinfo.h"
-#include "json_vdiskinfo.h"
-#include "json_pdiskinfo.h"
-
-using namespace NKikimr;
-using namespace NViewer;
-using namespace NKikimrWhiteboard;
-
-#ifdef NDEBUG
-#define Ctest Cnull
-#else
-#define Ctest Cerr
-#endif
-
-Y_UNIT_TEST_SUITE(Viewer) {
- Y_UNIT_TEST(TabletMerging) {
- TMap<ui32, THolder<TEvWhiteboard::TEvTabletStateResponse>> nodesData;
- for (ui32 nodeId = 1; nodeId <= 1000; ++nodeId) {
- THolder<TEvWhiteboard::TEvTabletStateResponse>& nodeData = nodesData[nodeId] = MakeHolder<TEvWhiteboard::TEvTabletStateResponse>();
- nodeData->Record.MutableTabletStateInfo()->Reserve(10000);
- for (ui32 tabletId = 1; tabletId <= 10000; ++tabletId) {
- NKikimrWhiteboard::TTabletStateInfo* tabletData = nodeData->Record.AddTabletStateInfo();
- tabletData->SetTabletId(tabletId);
+#include "json_tabletinfo.h"
+#include "json_vdiskinfo.h"
+#include "json_pdiskinfo.h"
+
+using namespace NKikimr;
+using namespace NViewer;
+using namespace NKikimrWhiteboard;
+
+#ifdef NDEBUG
+#define Ctest Cnull
+#else
+#define Ctest Cerr
+#endif
+
+Y_UNIT_TEST_SUITE(Viewer) {
+ Y_UNIT_TEST(TabletMerging) {
+ TMap<ui32, THolder<TEvWhiteboard::TEvTabletStateResponse>> nodesData;
+ for (ui32 nodeId = 1; nodeId <= 1000; ++nodeId) {
+ THolder<TEvWhiteboard::TEvTabletStateResponse>& nodeData = nodesData[nodeId] = MakeHolder<TEvWhiteboard::TEvTabletStateResponse>();
+ nodeData->Record.MutableTabletStateInfo()->Reserve(10000);
+ for (ui32 tabletId = 1; tabletId <= 10000; ++tabletId) {
+ NKikimrWhiteboard::TTabletStateInfo* tabletData = nodeData->Record.AddTabletStateInfo();
+ tabletData->SetTabletId(tabletId);
tabletData->SetLeader(true);
- tabletData->SetGeneration(13);
- tabletData->SetChangeTime(TInstant::Now().MilliSeconds());
- }
- }
- Ctest << "Data has built" << Endl;
- THPTimer timer;
- THolder<TEvWhiteboard::TEvTabletStateResponse> result = MergeWhiteboardResponses(nodesData);
- Ctest << "Merge = " << timer.Passed() << Endl;
- UNIT_ASSERT_LT(timer.Passed(), 10);
- UNIT_ASSERT_VALUES_EQUAL(result->Record.TabletStateInfoSize(), 10000);
- Ctest << "Data has merged" << Endl;
- }
-
- Y_UNIT_TEST(VDiskMerging) {
- TMap<ui32, THolder<TEvWhiteboard::TEvVDiskStateResponse>> nodesData;
- for (ui32 nodeId = 1; nodeId <= 1000; ++nodeId) {
- THolder<TEvWhiteboard::TEvVDiskStateResponse>& nodeData = nodesData[nodeId] = MakeHolder<TEvWhiteboard::TEvVDiskStateResponse>();
- nodeData->Record.MutableVDiskStateInfo()->Reserve(10);
- for (ui32 vDiskId = 1; vDiskId <= 1000; ++vDiskId) {
- NKikimrWhiteboard::TVDiskStateInfo* vDiskData = nodeData->Record.AddVDiskStateInfo();
- vDiskData->MutableVDiskId()->SetDomain(vDiskId);
- vDiskData->MutableVDiskId()->SetGroupGeneration(vDiskId);
- vDiskData->MutableVDiskId()->SetGroupID(vDiskId);
- vDiskData->MutableVDiskId()->SetRing(vDiskId);
- vDiskData->MutableVDiskId()->SetVDisk(vDiskId);
- vDiskData->SetAllocatedSize(10);
- vDiskData->SetChangeTime(TInstant::Now().MilliSeconds());
- }
- }
- Ctest << "Data has built" << Endl;
- THPTimer timer;
- THolder<TEvWhiteboard::TEvVDiskStateResponse> result = MergeWhiteboardResponses(nodesData);
- Ctest << "Merge = " << timer.Passed() << Endl;
- UNIT_ASSERT_LT(timer.Passed(), 10);
- UNIT_ASSERT_VALUES_EQUAL(result->Record.VDiskStateInfoSize(), 1000);
- Ctest << "Data has merged" << Endl;
- }
-
- Y_UNIT_TEST(PDiskMerging) {
- TMap<ui32, THolder<TEvWhiteboard::TEvPDiskStateResponse>> nodesData;
- for (ui32 nodeId = 1; nodeId <= 1000; ++nodeId) {
- THolder<TEvWhiteboard::TEvPDiskStateResponse>& nodeData = nodesData[nodeId] = MakeHolder<TEvWhiteboard::TEvPDiskStateResponse>();
- nodeData->Record.MutablePDiskStateInfo()->Reserve(10);
- for (ui32 pDiskId = 1; pDiskId <= 100; ++pDiskId) {
- NKikimrWhiteboard::TPDiskStateInfo* pDiskData = nodeData->Record.AddPDiskStateInfo();
- pDiskData->SetPDiskId(pDiskId);
- pDiskData->SetAvailableSize(100);
- pDiskData->SetChangeTime(TInstant::Now().MilliSeconds());
- }
- }
- Ctest << "Data has built" << Endl;
- THPTimer timer;
- THolder<TEvWhiteboard::TEvPDiskStateResponse> result = MergeWhiteboardResponses(nodesData);
- Ctest << "Merge = " << timer.Passed() << Endl;
- UNIT_ASSERT_LT(timer.Passed(), 10);
- UNIT_ASSERT_VALUES_EQUAL(result->Record.PDiskStateInfoSize(), 100000);
- Ctest << "Data has merged" << Endl;
- }
-}
+ tabletData->SetGeneration(13);
+ tabletData->SetChangeTime(TInstant::Now().MilliSeconds());
+ }
+ }
+ Ctest << "Data has built" << Endl;
+ THPTimer timer;
+ THolder<TEvWhiteboard::TEvTabletStateResponse> result = MergeWhiteboardResponses(nodesData);
+ Ctest << "Merge = " << timer.Passed() << Endl;
+ UNIT_ASSERT_LT(timer.Passed(), 10);
+ UNIT_ASSERT_VALUES_EQUAL(result->Record.TabletStateInfoSize(), 10000);
+ Ctest << "Data has merged" << Endl;
+ }
+
+ Y_UNIT_TEST(VDiskMerging) {
+ TMap<ui32, THolder<TEvWhiteboard::TEvVDiskStateResponse>> nodesData;
+ for (ui32 nodeId = 1; nodeId <= 1000; ++nodeId) {
+ THolder<TEvWhiteboard::TEvVDiskStateResponse>& nodeData = nodesData[nodeId] = MakeHolder<TEvWhiteboard::TEvVDiskStateResponse>();
+ nodeData->Record.MutableVDiskStateInfo()->Reserve(10);
+ for (ui32 vDiskId = 1; vDiskId <= 1000; ++vDiskId) {
+ NKikimrWhiteboard::TVDiskStateInfo* vDiskData = nodeData->Record.AddVDiskStateInfo();
+ vDiskData->MutableVDiskId()->SetDomain(vDiskId);
+ vDiskData->MutableVDiskId()->SetGroupGeneration(vDiskId);
+ vDiskData->MutableVDiskId()->SetGroupID(vDiskId);
+ vDiskData->MutableVDiskId()->SetRing(vDiskId);
+ vDiskData->MutableVDiskId()->SetVDisk(vDiskId);
+ vDiskData->SetAllocatedSize(10);
+ vDiskData->SetChangeTime(TInstant::Now().MilliSeconds());
+ }
+ }
+ Ctest << "Data has built" << Endl;
+ THPTimer timer;
+ THolder<TEvWhiteboard::TEvVDiskStateResponse> result = MergeWhiteboardResponses(nodesData);
+ Ctest << "Merge = " << timer.Passed() << Endl;
+ UNIT_ASSERT_LT(timer.Passed(), 10);
+ UNIT_ASSERT_VALUES_EQUAL(result->Record.VDiskStateInfoSize(), 1000);
+ Ctest << "Data has merged" << Endl;
+ }
+
+ Y_UNIT_TEST(PDiskMerging) {
+ TMap<ui32, THolder<TEvWhiteboard::TEvPDiskStateResponse>> nodesData;
+ for (ui32 nodeId = 1; nodeId <= 1000; ++nodeId) {
+ THolder<TEvWhiteboard::TEvPDiskStateResponse>& nodeData = nodesData[nodeId] = MakeHolder<TEvWhiteboard::TEvPDiskStateResponse>();
+ nodeData->Record.MutablePDiskStateInfo()->Reserve(10);
+ for (ui32 pDiskId = 1; pDiskId <= 100; ++pDiskId) {
+ NKikimrWhiteboard::TPDiskStateInfo* pDiskData = nodeData->Record.AddPDiskStateInfo();
+ pDiskData->SetPDiskId(pDiskId);
+ pDiskData->SetAvailableSize(100);
+ pDiskData->SetChangeTime(TInstant::Now().MilliSeconds());
+ }
+ }
+ Ctest << "Data has built" << Endl;
+ THPTimer timer;
+ THolder<TEvWhiteboard::TEvPDiskStateResponse> result = MergeWhiteboardResponses(nodesData);
+ Ctest << "Merge = " << timer.Passed() << Endl;
+ UNIT_ASSERT_LT(timer.Passed(), 10);
+ UNIT_ASSERT_VALUES_EQUAL(result->Record.PDiskStateInfoSize(), 100000);
+ Ctest << "Data has merged" << Endl;
+ }
+}
diff --git a/ydb/core/viewer/wb_aggregate.cpp b/ydb/core/viewer/wb_aggregate.cpp
index cc0089cd669..7f3d56d64b7 100644
--- a/ydb/core/viewer/wb_aggregate.cpp
+++ b/ydb/core/viewer/wb_aggregate.cpp
@@ -1,180 +1,180 @@
-#include "wb_aggregate.h"
-
-namespace NKikimr {
-namespace NViewer {
-
-void AggregateMessage(::google::protobuf::Message& protoTo, const ::google::protobuf::Message& protoFrom) {
- const Reflection& reflectionFrom = *protoFrom.GetReflection();
- const Reflection& reflectionTo = *protoTo.GetReflection();
- const Descriptor& descriptorTo = *protoTo.GetDescriptor();
- std::vector<const FieldDescriptor*> fields;
- reflectionFrom.ListFields(protoFrom, &fields);
- for (auto it = fields.begin(); it != fields.end(); ++it) {
- const FieldDescriptor* fieldFrom = *it;
- const FieldDescriptor* fieldTo = descriptorTo.FindFieldByNumber(fieldFrom->number());
- FieldDescriptor::CppType type = fieldFrom->cpp_type();
- if (fieldFrom->is_repeated()) {
- int fromSize = reflectionFrom.FieldSize(protoFrom, fieldFrom);
- int toSize = std::min(reflectionTo.FieldSize(protoTo, fieldTo), fromSize);
-
- for (int i = 0; i < toSize; ++i) {
- switch (type) {
- case FieldDescriptor::CPPTYPE_INT32:
- reflectionTo.SetRepeatedInt32(&protoTo, fieldTo, i,
- reflectionTo.GetRepeatedInt32(protoTo, fieldTo, i) +
- reflectionFrom.GetRepeatedInt32(protoFrom, fieldFrom, i));
- break;
- case FieldDescriptor::CPPTYPE_INT64:
- reflectionTo.SetRepeatedInt64(&protoTo, fieldTo, i,
- reflectionTo.GetRepeatedInt64(protoTo, fieldTo, i) +
- reflectionFrom.GetRepeatedInt64(protoFrom, fieldFrom, i));
- break;
- case FieldDescriptor::CPPTYPE_UINT32:
- reflectionTo.SetRepeatedUInt32(&protoTo, fieldTo, i,
- reflectionTo.GetRepeatedUInt32(protoTo, fieldTo, i) +
- reflectionFrom.GetRepeatedUInt32(protoFrom, fieldFrom, i));
- break;
- case FieldDescriptor::CPPTYPE_UINT64:
- reflectionTo.SetRepeatedUInt64(&protoTo, fieldTo, i,
- reflectionTo.GetRepeatedUInt64(protoTo, fieldTo, i) +
- reflectionFrom.GetRepeatedUInt64(protoFrom, fieldFrom, i));
- break;
- case FieldDescriptor::CPPTYPE_DOUBLE:
- reflectionTo.SetRepeatedDouble(&protoTo, fieldTo, i,
- reflectionTo.GetRepeatedDouble(protoTo, fieldTo, i) +
- reflectionFrom.GetRepeatedDouble(protoFrom, fieldFrom, i));
- break;
- case FieldDescriptor::CPPTYPE_FLOAT:
- reflectionTo.SetRepeatedFloat(&protoTo, fieldTo, i,
- reflectionTo.GetRepeatedFloat(protoTo, fieldTo, i) +
- reflectionFrom.GetRepeatedFloat(protoFrom, fieldFrom, i));
- break;
- case FieldDescriptor::CPPTYPE_BOOL:
- reflectionTo.SetRepeatedBool(&protoTo, fieldTo, i, reflectionFrom.GetRepeatedBool(protoFrom, fieldFrom, i));
- break;
- case FieldDescriptor::CPPTYPE_ENUM:
- reflectionTo.SetRepeatedEnum(&protoTo, fieldTo, i, reflectionFrom.GetRepeatedEnum(protoFrom, fieldFrom, i));
- break;
- case FieldDescriptor::CPPTYPE_STRING:
- reflectionTo.SetRepeatedString(&protoTo, fieldTo, i, reflectionFrom.GetRepeatedString(protoFrom, fieldFrom, i));
- break;
- case FieldDescriptor::CPPTYPE_MESSAGE:
- AggregateMessage(*reflectionTo.MutableRepeatedMessage(&protoTo, fieldTo, i), reflectionFrom.GetRepeatedMessage(protoFrom, fieldFrom, i));
- break;
- }
- }
- for (int i = toSize; i < fromSize; ++i) {
- switch (type) {
- case FieldDescriptor::CPPTYPE_INT32:
- reflectionTo.AddInt32(&protoTo, fieldTo, reflectionFrom.GetRepeatedInt32(protoFrom, fieldFrom, i));
- break;
- case FieldDescriptor::CPPTYPE_INT64:
- reflectionTo.AddInt64(&protoTo, fieldTo, reflectionFrom.GetRepeatedInt64(protoFrom, fieldFrom, i));
- break;
- case FieldDescriptor::CPPTYPE_UINT32:
- reflectionTo.AddUInt32(&protoTo, fieldTo, reflectionFrom.GetRepeatedUInt32(protoFrom, fieldFrom, i));
- break;
- case FieldDescriptor::CPPTYPE_UINT64:
- reflectionTo.AddUInt64(&protoTo, fieldTo, reflectionFrom.GetRepeatedUInt64(protoFrom, fieldFrom, i));
- break;
- case FieldDescriptor::CPPTYPE_DOUBLE:
- reflectionTo.AddDouble(&protoTo, fieldTo, reflectionFrom.GetRepeatedDouble(protoFrom, fieldFrom, i));
- break;
- case FieldDescriptor::CPPTYPE_FLOAT:
- reflectionTo.AddFloat(&protoTo, fieldTo, reflectionFrom.GetRepeatedFloat(protoFrom, fieldFrom, i));
- break;
- case FieldDescriptor::CPPTYPE_BOOL:
- reflectionTo.AddBool(&protoTo, fieldTo, reflectionFrom.GetRepeatedBool(protoFrom, fieldFrom, i));
- break;
- case FieldDescriptor::CPPTYPE_ENUM:
- reflectionTo.AddEnum(&protoTo, fieldTo, reflectionFrom.GetRepeatedEnum(protoFrom, fieldFrom, i));
- break;
- case FieldDescriptor::CPPTYPE_STRING:
- reflectionTo.AddString(&protoTo, fieldTo, reflectionFrom.GetRepeatedString(protoFrom, fieldFrom, i));
- break;
- case FieldDescriptor::CPPTYPE_MESSAGE:
- reflectionTo.AddMessage(&protoTo, fieldTo)->CopyFrom(reflectionFrom.GetRepeatedMessage(protoFrom, fieldFrom, i));
- break;
- }
- }
- } else {
- switch (type) {
- case FieldDescriptor::CPPTYPE_INT32:
- if (reflectionTo.HasField(protoTo, fieldTo)) {
- reflectionTo.SetInt32(&protoTo, fieldTo,
- reflectionFrom.GetInt32(protoTo, fieldTo) +
- reflectionFrom.GetInt32(protoFrom, fieldFrom));
- } else {
- reflectionTo.SetInt32(&protoTo, fieldTo,
- reflectionFrom.GetInt32(protoFrom, fieldFrom));
- }
- break;
- case FieldDescriptor::CPPTYPE_INT64:
- if (reflectionTo.HasField(protoTo, fieldTo)) {
- reflectionTo.SetInt64(&protoTo, fieldTo,
- reflectionFrom.GetInt64(protoTo, fieldTo) +
- reflectionFrom.GetInt64(protoFrom, fieldFrom));
- } else {
- reflectionTo.SetInt64(&protoTo, fieldTo,
- reflectionFrom.GetInt64(protoFrom, fieldFrom));
- }
- break;
- case FieldDescriptor::CPPTYPE_UINT32:
- if (reflectionTo.HasField(protoTo, fieldTo)) {
- reflectionTo.SetUInt32(&protoTo, fieldTo,
- reflectionFrom.GetUInt32(protoTo, fieldTo) +
- reflectionFrom.GetUInt32(protoFrom, fieldFrom));
- } else {
- reflectionTo.SetUInt32(&protoTo, fieldTo,
- reflectionFrom.GetUInt32(protoFrom, fieldFrom));
- }
- break;
- case FieldDescriptor::CPPTYPE_UINT64:
- if (reflectionTo.HasField(protoTo, fieldTo)) {
- reflectionTo.SetUInt64(&protoTo, fieldTo,
- reflectionFrom.GetUInt64(protoTo, fieldTo) +
- reflectionFrom.GetUInt64(protoFrom, fieldFrom));
- } else {
- reflectionTo.SetUInt64(&protoTo, fieldTo,
- reflectionFrom.GetUInt64(protoFrom, fieldFrom));
- }
- break;
- case FieldDescriptor::CPPTYPE_DOUBLE:
- if (reflectionTo.HasField(protoTo, fieldTo)) {
- reflectionTo.SetDouble(&protoTo, fieldTo,
- reflectionFrom.GetDouble(protoTo, fieldTo) +
- reflectionFrom.GetDouble(protoFrom, fieldFrom));
- } else {
- reflectionTo.SetDouble(&protoTo, fieldTo,
- reflectionFrom.GetDouble(protoFrom, fieldFrom));
- }
- break;
- case FieldDescriptor::CPPTYPE_FLOAT:
- if (reflectionTo.HasField(protoTo, fieldTo)) {
- reflectionTo.SetFloat(&protoTo, fieldTo,
- reflectionFrom.GetFloat(protoTo, fieldTo) +
- reflectionFrom.GetFloat(protoFrom, fieldFrom));
- } else {
- reflectionTo.SetFloat(&protoTo, fieldTo,
- reflectionFrom.GetFloat(protoFrom, fieldFrom));
- }
- break;
- case FieldDescriptor::CPPTYPE_BOOL:
- reflectionTo.SetBool(&protoTo, fieldTo, reflectionFrom.GetBool(protoFrom, fieldFrom));
- break;
- case FieldDescriptor::CPPTYPE_ENUM:
- reflectionTo.SetEnum(&protoTo, fieldTo, reflectionFrom.GetEnum(protoFrom, fieldFrom));
- break;
- case FieldDescriptor::CPPTYPE_STRING:
- reflectionTo.SetString(&protoTo, fieldTo, reflectionFrom.GetString(protoFrom, fieldFrom));
- break;
- case FieldDescriptor::CPPTYPE_MESSAGE:
- AggregateMessage(*reflectionTo.MutableMessage(&protoTo, fieldTo), reflectionFrom.GetMessage(protoFrom, fieldFrom));
- break;
- }
- }
- }
-}
-
-}
-}
+#include "wb_aggregate.h"
+
+namespace NKikimr {
+namespace NViewer {
+
+void AggregateMessage(::google::protobuf::Message& protoTo, const ::google::protobuf::Message& protoFrom) {
+ const Reflection& reflectionFrom = *protoFrom.GetReflection();
+ const Reflection& reflectionTo = *protoTo.GetReflection();
+ const Descriptor& descriptorTo = *protoTo.GetDescriptor();
+ std::vector<const FieldDescriptor*> fields;
+ reflectionFrom.ListFields(protoFrom, &fields);
+ for (auto it = fields.begin(); it != fields.end(); ++it) {
+ const FieldDescriptor* fieldFrom = *it;
+ const FieldDescriptor* fieldTo = descriptorTo.FindFieldByNumber(fieldFrom->number());
+ FieldDescriptor::CppType type = fieldFrom->cpp_type();
+ if (fieldFrom->is_repeated()) {
+ int fromSize = reflectionFrom.FieldSize(protoFrom, fieldFrom);
+ int toSize = std::min(reflectionTo.FieldSize(protoTo, fieldTo), fromSize);
+
+ for (int i = 0; i < toSize; ++i) {
+ switch (type) {
+ case FieldDescriptor::CPPTYPE_INT32:
+ reflectionTo.SetRepeatedInt32(&protoTo, fieldTo, i,
+ reflectionTo.GetRepeatedInt32(protoTo, fieldTo, i) +
+ reflectionFrom.GetRepeatedInt32(protoFrom, fieldFrom, i));
+ break;
+ case FieldDescriptor::CPPTYPE_INT64:
+ reflectionTo.SetRepeatedInt64(&protoTo, fieldTo, i,
+ reflectionTo.GetRepeatedInt64(protoTo, fieldTo, i) +
+ reflectionFrom.GetRepeatedInt64(protoFrom, fieldFrom, i));
+ break;
+ case FieldDescriptor::CPPTYPE_UINT32:
+ reflectionTo.SetRepeatedUInt32(&protoTo, fieldTo, i,
+ reflectionTo.GetRepeatedUInt32(protoTo, fieldTo, i) +
+ reflectionFrom.GetRepeatedUInt32(protoFrom, fieldFrom, i));
+ break;
+ case FieldDescriptor::CPPTYPE_UINT64:
+ reflectionTo.SetRepeatedUInt64(&protoTo, fieldTo, i,
+ reflectionTo.GetRepeatedUInt64(protoTo, fieldTo, i) +
+ reflectionFrom.GetRepeatedUInt64(protoFrom, fieldFrom, i));
+ break;
+ case FieldDescriptor::CPPTYPE_DOUBLE:
+ reflectionTo.SetRepeatedDouble(&protoTo, fieldTo, i,
+ reflectionTo.GetRepeatedDouble(protoTo, fieldTo, i) +
+ reflectionFrom.GetRepeatedDouble(protoFrom, fieldFrom, i));
+ break;
+ case FieldDescriptor::CPPTYPE_FLOAT:
+ reflectionTo.SetRepeatedFloat(&protoTo, fieldTo, i,
+ reflectionTo.GetRepeatedFloat(protoTo, fieldTo, i) +
+ reflectionFrom.GetRepeatedFloat(protoFrom, fieldFrom, i));
+ break;
+ case FieldDescriptor::CPPTYPE_BOOL:
+ reflectionTo.SetRepeatedBool(&protoTo, fieldTo, i, reflectionFrom.GetRepeatedBool(protoFrom, fieldFrom, i));
+ break;
+ case FieldDescriptor::CPPTYPE_ENUM:
+ reflectionTo.SetRepeatedEnum(&protoTo, fieldTo, i, reflectionFrom.GetRepeatedEnum(protoFrom, fieldFrom, i));
+ break;
+ case FieldDescriptor::CPPTYPE_STRING:
+ reflectionTo.SetRepeatedString(&protoTo, fieldTo, i, reflectionFrom.GetRepeatedString(protoFrom, fieldFrom, i));
+ break;
+ case FieldDescriptor::CPPTYPE_MESSAGE:
+ AggregateMessage(*reflectionTo.MutableRepeatedMessage(&protoTo, fieldTo, i), reflectionFrom.GetRepeatedMessage(protoFrom, fieldFrom, i));
+ break;
+ }
+ }
+ for (int i = toSize; i < fromSize; ++i) {
+ switch (type) {
+ case FieldDescriptor::CPPTYPE_INT32:
+ reflectionTo.AddInt32(&protoTo, fieldTo, reflectionFrom.GetRepeatedInt32(protoFrom, fieldFrom, i));
+ break;
+ case FieldDescriptor::CPPTYPE_INT64:
+ reflectionTo.AddInt64(&protoTo, fieldTo, reflectionFrom.GetRepeatedInt64(protoFrom, fieldFrom, i));
+ break;
+ case FieldDescriptor::CPPTYPE_UINT32:
+ reflectionTo.AddUInt32(&protoTo, fieldTo, reflectionFrom.GetRepeatedUInt32(protoFrom, fieldFrom, i));
+ break;
+ case FieldDescriptor::CPPTYPE_UINT64:
+ reflectionTo.AddUInt64(&protoTo, fieldTo, reflectionFrom.GetRepeatedUInt64(protoFrom, fieldFrom, i));
+ break;
+ case FieldDescriptor::CPPTYPE_DOUBLE:
+ reflectionTo.AddDouble(&protoTo, fieldTo, reflectionFrom.GetRepeatedDouble(protoFrom, fieldFrom, i));
+ break;
+ case FieldDescriptor::CPPTYPE_FLOAT:
+ reflectionTo.AddFloat(&protoTo, fieldTo, reflectionFrom.GetRepeatedFloat(protoFrom, fieldFrom, i));
+ break;
+ case FieldDescriptor::CPPTYPE_BOOL:
+ reflectionTo.AddBool(&protoTo, fieldTo, reflectionFrom.GetRepeatedBool(protoFrom, fieldFrom, i));
+ break;
+ case FieldDescriptor::CPPTYPE_ENUM:
+ reflectionTo.AddEnum(&protoTo, fieldTo, reflectionFrom.GetRepeatedEnum(protoFrom, fieldFrom, i));
+ break;
+ case FieldDescriptor::CPPTYPE_STRING:
+ reflectionTo.AddString(&protoTo, fieldTo, reflectionFrom.GetRepeatedString(protoFrom, fieldFrom, i));
+ break;
+ case FieldDescriptor::CPPTYPE_MESSAGE:
+ reflectionTo.AddMessage(&protoTo, fieldTo)->CopyFrom(reflectionFrom.GetRepeatedMessage(protoFrom, fieldFrom, i));
+ break;
+ }
+ }
+ } else {
+ switch (type) {
+ case FieldDescriptor::CPPTYPE_INT32:
+ if (reflectionTo.HasField(protoTo, fieldTo)) {
+ reflectionTo.SetInt32(&protoTo, fieldTo,
+ reflectionFrom.GetInt32(protoTo, fieldTo) +
+ reflectionFrom.GetInt32(protoFrom, fieldFrom));
+ } else {
+ reflectionTo.SetInt32(&protoTo, fieldTo,
+ reflectionFrom.GetInt32(protoFrom, fieldFrom));
+ }
+ break;
+ case FieldDescriptor::CPPTYPE_INT64:
+ if (reflectionTo.HasField(protoTo, fieldTo)) {
+ reflectionTo.SetInt64(&protoTo, fieldTo,
+ reflectionFrom.GetInt64(protoTo, fieldTo) +
+ reflectionFrom.GetInt64(protoFrom, fieldFrom));
+ } else {
+ reflectionTo.SetInt64(&protoTo, fieldTo,
+ reflectionFrom.GetInt64(protoFrom, fieldFrom));
+ }
+ break;
+ case FieldDescriptor::CPPTYPE_UINT32:
+ if (reflectionTo.HasField(protoTo, fieldTo)) {
+ reflectionTo.SetUInt32(&protoTo, fieldTo,
+ reflectionFrom.GetUInt32(protoTo, fieldTo) +
+ reflectionFrom.GetUInt32(protoFrom, fieldFrom));
+ } else {
+ reflectionTo.SetUInt32(&protoTo, fieldTo,
+ reflectionFrom.GetUInt32(protoFrom, fieldFrom));
+ }
+ break;
+ case FieldDescriptor::CPPTYPE_UINT64:
+ if (reflectionTo.HasField(protoTo, fieldTo)) {
+ reflectionTo.SetUInt64(&protoTo, fieldTo,
+ reflectionFrom.GetUInt64(protoTo, fieldTo) +
+ reflectionFrom.GetUInt64(protoFrom, fieldFrom));
+ } else {
+ reflectionTo.SetUInt64(&protoTo, fieldTo,
+ reflectionFrom.GetUInt64(protoFrom, fieldFrom));
+ }
+ break;
+ case FieldDescriptor::CPPTYPE_DOUBLE:
+ if (reflectionTo.HasField(protoTo, fieldTo)) {
+ reflectionTo.SetDouble(&protoTo, fieldTo,
+ reflectionFrom.GetDouble(protoTo, fieldTo) +
+ reflectionFrom.GetDouble(protoFrom, fieldFrom));
+ } else {
+ reflectionTo.SetDouble(&protoTo, fieldTo,
+ reflectionFrom.GetDouble(protoFrom, fieldFrom));
+ }
+ break;
+ case FieldDescriptor::CPPTYPE_FLOAT:
+ if (reflectionTo.HasField(protoTo, fieldTo)) {
+ reflectionTo.SetFloat(&protoTo, fieldTo,
+ reflectionFrom.GetFloat(protoTo, fieldTo) +
+ reflectionFrom.GetFloat(protoFrom, fieldFrom));
+ } else {
+ reflectionTo.SetFloat(&protoTo, fieldTo,
+ reflectionFrom.GetFloat(protoFrom, fieldFrom));
+ }
+ break;
+ case FieldDescriptor::CPPTYPE_BOOL:
+ reflectionTo.SetBool(&protoTo, fieldTo, reflectionFrom.GetBool(protoFrom, fieldFrom));
+ break;
+ case FieldDescriptor::CPPTYPE_ENUM:
+ reflectionTo.SetEnum(&protoTo, fieldTo, reflectionFrom.GetEnum(protoFrom, fieldFrom));
+ break;
+ case FieldDescriptor::CPPTYPE_STRING:
+ reflectionTo.SetString(&protoTo, fieldTo, reflectionFrom.GetString(protoFrom, fieldFrom));
+ break;
+ case FieldDescriptor::CPPTYPE_MESSAGE:
+ AggregateMessage(*reflectionTo.MutableMessage(&protoTo, fieldTo), reflectionFrom.GetMessage(protoFrom, fieldFrom));
+ break;
+ }
+ }
+ }
+}
+
+}
+}
diff --git a/ydb/core/viewer/wb_aggregate.h b/ydb/core/viewer/wb_aggregate.h
index c865433d8c8..7d09f1565f6 100644
--- a/ydb/core/viewer/wb_aggregate.h
+++ b/ydb/core/viewer/wb_aggregate.h
@@ -1,49 +1,49 @@
-#pragma once
-#include <util/string/vector.h>
+#pragma once
+#include <util/string/vector.h>
#include <ydb/core/node_whiteboard/node_whiteboard.h>
-
-namespace NKikimr {
-namespace NViewer {
-
-using namespace NNodeWhiteboard;
-using namespace ::google::protobuf;
-
-template <typename ResponseType>
-struct TWhiteboardInfo;
-
-void AggregateMessage(::google::protobuf::Message& protoTo, const ::google::protobuf::Message& protoFrom);
-
-template <typename ResponseType>
-class TWhiteboardAggregator {
-public:
- using TResponseType = ResponseType;
-
+
+namespace NKikimr {
+namespace NViewer {
+
+using namespace NNodeWhiteboard;
+using namespace ::google::protobuf;
+
+template <typename ResponseType>
+struct TWhiteboardInfo;
+
+void AggregateMessage(::google::protobuf::Message& protoTo, const ::google::protobuf::Message& protoFrom);
+
+template <typename ResponseType>
+class TWhiteboardAggregator {
+public:
+ using TResponseType = ResponseType;
+
static THolder<TResponseType> AggregateResponses(TVector<THolder<TResponseType>>& responses) {
THolder<TResponseType> result = MakeHolder<TResponseType>();
- for (const auto& response : responses) {
- AggregateMessage(result->Record, response->Record);
- }
- return result;
- }
-
+ for (const auto& response : responses) {
+ AggregateMessage(result->Record, response->Record);
+ }
+ return result;
+ }
+
static THolder<TResponseType> AggregateResponses(TMap<TTabletId, THolder<TResponseType>>& responses) {
THolder<TResponseType> result = MakeHolder<TResponseType>();
- for (const auto& response : responses) {
- AggregateMessage(result->Record, response.second->Record);
- }
- return result;
- }
-};
-
-template <typename ResponseType>
+ for (const auto& response : responses) {
+ AggregateMessage(result->Record, response.second->Record);
+ }
+ return result;
+ }
+};
+
+template <typename ResponseType>
THolder<ResponseType> AggregateWhiteboardResponses(TVector<THolder<ResponseType>>& responses) {
- return TWhiteboardAggregator<ResponseType>::AggregateResponses(responses);
-}
-
-template <typename ResponseType>
+ return TWhiteboardAggregator<ResponseType>::AggregateResponses(responses);
+}
+
+template <typename ResponseType>
THolder<ResponseType> AggregateWhiteboardResponses(TMap<TTabletId, THolder<ResponseType>>& responses) {
- return TWhiteboardAggregator<ResponseType>::AggregateResponses(responses);
-}
-
-}
-}
+ return TWhiteboardAggregator<ResponseType>::AggregateResponses(responses);
+}
+
+}
+}
diff --git a/ydb/core/viewer/wb_filter.cpp b/ydb/core/viewer/wb_filter.cpp
index 1e9432b09cb..d7899f5edfb 100644
--- a/ydb/core/viewer/wb_filter.cpp
+++ b/ydb/core/viewer/wb_filter.cpp
@@ -1,100 +1,100 @@
-#include "wb_filter.h"
-
-namespace NKikimr {
-namespace NViewer {
-
-template <>
-i32 TFieldProtoValueExtractor<i32>::ExtractValue(const Reflection& reflection, const Message& element) const {
- return reflection.GetInt32(element, Field);
-}
-
-template <>
-ui32 TFieldProtoValueExtractor<ui32>::ExtractValue(const Reflection& reflection, const Message& element) const {
- return reflection.GetUInt32(element, Field);
-}
-
-template <>
-i64 TFieldProtoValueExtractor<i64>::ExtractValue(const Reflection& reflection, const Message& element) const {
- return reflection.GetInt64(element, Field);
-}
-
-template <>
-ui64 TFieldProtoValueExtractor<ui64>::ExtractValue(const Reflection& reflection, const Message& element) const {
- return reflection.GetUInt64(element, Field);
-}
-
-template <>
-double TFieldProtoValueExtractor<double>::ExtractValue(const Reflection& reflection, const Message& element) const {
- return reflection.GetDouble(element, Field);
-}
-
-template <>
-float TFieldProtoValueExtractor<float>::ExtractValue(const Reflection& reflection, const Message& element) const {
- return reflection.GetFloat(element, Field);
-}
-
-template <>
-bool TFieldProtoValueExtractor<bool>::ExtractValue(const Reflection& reflection, const Message& element) const {
- return reflection.GetBool(element, Field);
-}
-
-template <>
+#include "wb_filter.h"
+
+namespace NKikimr {
+namespace NViewer {
+
+template <>
+i32 TFieldProtoValueExtractor<i32>::ExtractValue(const Reflection& reflection, const Message& element) const {
+ return reflection.GetInt32(element, Field);
+}
+
+template <>
+ui32 TFieldProtoValueExtractor<ui32>::ExtractValue(const Reflection& reflection, const Message& element) const {
+ return reflection.GetUInt32(element, Field);
+}
+
+template <>
+i64 TFieldProtoValueExtractor<i64>::ExtractValue(const Reflection& reflection, const Message& element) const {
+ return reflection.GetInt64(element, Field);
+}
+
+template <>
+ui64 TFieldProtoValueExtractor<ui64>::ExtractValue(const Reflection& reflection, const Message& element) const {
+ return reflection.GetUInt64(element, Field);
+}
+
+template <>
+double TFieldProtoValueExtractor<double>::ExtractValue(const Reflection& reflection, const Message& element) const {
+ return reflection.GetDouble(element, Field);
+}
+
+template <>
+float TFieldProtoValueExtractor<float>::ExtractValue(const Reflection& reflection, const Message& element) const {
+ return reflection.GetFloat(element, Field);
+}
+
+template <>
+bool TFieldProtoValueExtractor<bool>::ExtractValue(const Reflection& reflection, const Message& element) const {
+ return reflection.GetBool(element, Field);
+}
+
+template <>
TString TFieldProtoValueExtractor<TString>::ExtractValue(const Reflection& reflection, const Message& element) const {
- return reflection.GetString(element, Field);
-}
-
-template <>
-TEnumValue TFieldProtoValueExtractor<TEnumValue>::ExtractValue(const Reflection& reflection, const Message& element) const {
- return reflection.GetEnum(element, Field);
-}
-
-template <>
-TMessageValue TFieldProtoValueExtractor<TMessageValue>::ExtractValue(const Reflection& parentReflection, const Message& element) const {
- const Message& message = parentReflection.GetMessage(element, Field);
- const Reflection& reflection = *message.GetReflection();
- const Descriptor& descriptor = *message.GetDescriptor();
- int fieldCount = descriptor.field_count();
- TStringBuilder result;
- for (int idxField = 0; idxField < fieldCount; ++idxField) {
- const FieldDescriptor* field = descriptor.field(idxField);
- if (!result.empty()) {
- result << '-';
- }
- switch (field->cpp_type()) {
- case FieldDescriptor::CPPTYPE_INT32:
- result << reflection.GetInt32(message, field);
- break;
- case FieldDescriptor::CPPTYPE_INT64:
- result << reflection.GetInt64(message, field);
- break;
- case FieldDescriptor::CPPTYPE_UINT32:
- result << reflection.GetUInt32(message, field);
- break;
- case FieldDescriptor::CPPTYPE_UINT64:
- result << reflection.GetUInt64(message, field);
- break;
- case FieldDescriptor::CPPTYPE_DOUBLE:
- result << reflection.GetDouble(message, field);
- break;
- case FieldDescriptor::CPPTYPE_FLOAT:
- result << reflection.GetFloat(message, field);
- break;
- case FieldDescriptor::CPPTYPE_BOOL:
- result << reflection.GetBool(message, field);
- break;
- case FieldDescriptor::CPPTYPE_ENUM:
- result << reflection.GetEnum(message, field)->number();
- break;
- case FieldDescriptor::CPPTYPE_STRING:
- result << reflection.GetString(message, field);
- break;
- case FieldDescriptor::CPPTYPE_MESSAGE:
- result << ExtractValue(reflection, message).Value;
- break;
- }
- }
- return result;
-}
-
-}
-}
+ return reflection.GetString(element, Field);
+}
+
+template <>
+TEnumValue TFieldProtoValueExtractor<TEnumValue>::ExtractValue(const Reflection& reflection, const Message& element) const {
+ return reflection.GetEnum(element, Field);
+}
+
+template <>
+TMessageValue TFieldProtoValueExtractor<TMessageValue>::ExtractValue(const Reflection& parentReflection, const Message& element) const {
+ const Message& message = parentReflection.GetMessage(element, Field);
+ const Reflection& reflection = *message.GetReflection();
+ const Descriptor& descriptor = *message.GetDescriptor();
+ int fieldCount = descriptor.field_count();
+ TStringBuilder result;
+ for (int idxField = 0; idxField < fieldCount; ++idxField) {
+ const FieldDescriptor* field = descriptor.field(idxField);
+ if (!result.empty()) {
+ result << '-';
+ }
+ switch (field->cpp_type()) {
+ case FieldDescriptor::CPPTYPE_INT32:
+ result << reflection.GetInt32(message, field);
+ break;
+ case FieldDescriptor::CPPTYPE_INT64:
+ result << reflection.GetInt64(message, field);
+ break;
+ case FieldDescriptor::CPPTYPE_UINT32:
+ result << reflection.GetUInt32(message, field);
+ break;
+ case FieldDescriptor::CPPTYPE_UINT64:
+ result << reflection.GetUInt64(message, field);
+ break;
+ case FieldDescriptor::CPPTYPE_DOUBLE:
+ result << reflection.GetDouble(message, field);
+ break;
+ case FieldDescriptor::CPPTYPE_FLOAT:
+ result << reflection.GetFloat(message, field);
+ break;
+ case FieldDescriptor::CPPTYPE_BOOL:
+ result << reflection.GetBool(message, field);
+ break;
+ case FieldDescriptor::CPPTYPE_ENUM:
+ result << reflection.GetEnum(message, field)->number();
+ break;
+ case FieldDescriptor::CPPTYPE_STRING:
+ result << reflection.GetString(message, field);
+ break;
+ case FieldDescriptor::CPPTYPE_MESSAGE:
+ result << ExtractValue(reflection, message).Value;
+ break;
+ }
+ }
+ return result;
+}
+
+}
+}
diff --git a/ydb/core/viewer/wb_filter.h b/ydb/core/viewer/wb_filter.h
index 85bf1ea1665..99c279b4fa1 100644
--- a/ydb/core/viewer/wb_filter.h
+++ b/ydb/core/viewer/wb_filter.h
@@ -1,555 +1,555 @@
-#pragma once
-#include <util/string/vector.h>
+#pragma once
+#include <util/string/vector.h>
#include <ydb/core/node_whiteboard/node_whiteboard.h>
#include <util/string/split.h>
-
-namespace NKikimr {
-namespace NViewer {
-
-using namespace NNodeWhiteboard;
-using namespace ::google::protobuf;
-
-template <typename ResponseType>
-struct TWhiteboardInfo;
-
-struct TEnumValue {
+
+namespace NKikimr {
+namespace NViewer {
+
+using namespace NNodeWhiteboard;
+using namespace ::google::protobuf;
+
+template <typename ResponseType>
+struct TWhiteboardInfo;
+
+struct TEnumValue {
TString Name;
- int Value;
-
+ int Value;
+
TEnumValue(const TString& string) {
- if (!TryFromString<int>(string, Value)) {
- Name = string;
- }
- }
-
- TEnumValue(const EnumValueDescriptor* descriptor)
- : Name(descriptor->name())
- , Value(descriptor->number())
- {}
-
- bool operator ==(const TEnumValue& value) const {
- if (!Name.empty() && !value.Name.empty()) {
- return Name == value.Name;
- }
- return Value == value.Value;
- }
-
- bool operator !=(const TEnumValue& value) const {
- if (!Name.empty() && !value.Name.empty()) {
- return Name != value.Name;
- }
- return Value != value.Value;
- }
-
- bool operator <(const TEnumValue& value) const {
- if (!Name.empty() && !value.Name.empty()) {
- return Name < value.Name;
- }
- return Value < value.Value;
- }
-
- bool operator <=(const TEnumValue& value) const {
- if (!Name.empty() && !value.Name.empty()) {
- return Name <= value.Name;
- }
- return Value <= value.Value;
- }
-
- bool operator >(const TEnumValue& value) const {
- if (!Name.empty() && !value.Name.empty()) {
- return Name > value.Name;
- }
- return Value > value.Value;
- }
-
- bool operator >=(const TEnumValue& value) const {
- if (!Name.empty() && !value.Name.empty()) {
- return Name >= value.Name;
- }
- return Value >= value.Value;
- }
-};
-
-struct TMessageValue {
- TString Value;
-
- TMessageValue(const TString& value)
- : Value(value)
- {}
-
- bool operator ==(const TMessageValue& value) const {
- return Value == value.Value;
- }
-
- bool operator !=(const TMessageValue& value) const {
- return Value != value.Value;
- }
-
- bool operator <(const TMessageValue& value) const {
- return Value < value.Value;
- }
-};
-
-template <typename CppType>
-class TFieldProtoValueExtractor {
-public:
- TFieldProtoValueExtractor(const FieldDescriptor* field)
- : Field(field)
- {}
-
- CppType ExtractValue(const Reflection& reflection, const Message& element) const;
-
-protected:
- const FieldDescriptor* Field;
-};
-
-template <typename ResponseType>
-class TWhiteboardFilter {
-public:
- using TResponseType = typename TWhiteboardInfo<ResponseType>::TResponseType;
- using TElementType = typename TWhiteboardInfo<ResponseType>::TElementType;
-
- class IFieldProtoFilter {
- public:
- virtual ~IFieldProtoFilter() = default;
- virtual bool CheckFilter(const TElementType& element) const = 0;
- };
-
- template <typename CppType>
- class TFieldProtoFilterEqValue : public IFieldProtoFilter, public TFieldProtoValueExtractor<CppType> {
- public:
- TFieldProtoFilterEqValue(const FieldDescriptor* field, CppType value)
- : TFieldProtoValueExtractor<CppType>(field)
- , Value(value)
- {}
-
- bool CheckFilter(const TElementType& element) const override {
- return TFieldProtoValueExtractor<CppType>::ExtractValue(*element.GetReflection(), element) == Value;
- }
-
- protected:
- CppType Value;
- };
-
- template <typename CppType>
- class TFieldProtoFilterInValue : public IFieldProtoFilter, public TFieldProtoValueExtractor<CppType> {
- public:
- TFieldProtoFilterInValue(const FieldDescriptor* field, const TVector<CppType>& values)
- : TFieldProtoValueExtractor<CppType>(field)
- , Values(values.begin(), values.end())
- {}
-
- bool CheckFilter(const TElementType& element) const override {
- auto value = TFieldProtoValueExtractor<CppType>::ExtractValue(*element.GetReflection(), element);
- return Values.count(value) != 0;
- }
-
- protected:
- TSet<CppType> Values;
- };
-
- template <typename CppType>
- class TFieldProtoFilterNeValue : public IFieldProtoFilter, public TFieldProtoValueExtractor<CppType> {
- public:
- TFieldProtoFilterNeValue(const FieldDescriptor* field, CppType value)
- : TFieldProtoValueExtractor<CppType>(field)
- , Value(value)
- {}
-
- bool CheckFilter(const TElementType& element) const override {
- return TFieldProtoValueExtractor<CppType>::ExtractValue(*element.GetReflection(), element) != Value;
- }
-
- protected:
- CppType Value;
- };
-
- template <typename CppType>
- class TFieldProtoFilterLtValue : public IFieldProtoFilter, public TFieldProtoValueExtractor<CppType> {
- public:
- TFieldProtoFilterLtValue(const FieldDescriptor* field, CppType value)
- : TFieldProtoValueExtractor<CppType>(field)
- , Value(value)
- {}
-
- bool CheckFilter(const TElementType& element) const override {
- return TFieldProtoValueExtractor<CppType>::ExtractValue(*element.GetReflection(), element) < Value;
- }
-
- protected:
- CppType Value;
- };
-
- template <typename CppType>
- class TFieldProtoFilterLeValue : public IFieldProtoFilter, public TFieldProtoValueExtractor<CppType> {
- public:
- TFieldProtoFilterLeValue(const FieldDescriptor* field, CppType value)
- : TFieldProtoValueExtractor<CppType>(field)
- , Value(value)
- {}
-
- bool CheckFilter(const TElementType& element) const override {
- return TFieldProtoValueExtractor<CppType>::ExtractValue(*element.GetReflection(), element) <= Value;
- }
-
- protected:
- CppType Value;
- };
-
- template <typename CppType>
- class TFieldProtoFilterGtValue : public IFieldProtoFilter, public TFieldProtoValueExtractor<CppType> {
- public:
- TFieldProtoFilterGtValue(const FieldDescriptor* field, CppType value)
- : TFieldProtoValueExtractor<CppType>(field)
- , Value(value)
- {}
-
- bool CheckFilter(const TElementType& element) const override {
- return TFieldProtoValueExtractor<CppType>::ExtractValue(*element.GetReflection(), element) > Value;
- }
-
- protected:
- CppType Value;
- };
-
- template <typename CppType>
- class TFieldProtoFilterGeValue : public IFieldProtoFilter, public TFieldProtoValueExtractor<CppType> {
- public:
- TFieldProtoFilterGeValue(const FieldDescriptor* field, CppType value)
- : TFieldProtoValueExtractor<CppType>(field)
- , Value(value)
- {}
-
- bool CheckFilter(const TElementType& element) const override {
- return TFieldProtoValueExtractor<CppType>::ExtractValue(*element.GetReflection(), element) >= Value;
- }
-
- protected:
- CppType Value;
- };
-
+ if (!TryFromString<int>(string, Value)) {
+ Name = string;
+ }
+ }
+
+ TEnumValue(const EnumValueDescriptor* descriptor)
+ : Name(descriptor->name())
+ , Value(descriptor->number())
+ {}
+
+ bool operator ==(const TEnumValue& value) const {
+ if (!Name.empty() && !value.Name.empty()) {
+ return Name == value.Name;
+ }
+ return Value == value.Value;
+ }
+
+ bool operator !=(const TEnumValue& value) const {
+ if (!Name.empty() && !value.Name.empty()) {
+ return Name != value.Name;
+ }
+ return Value != value.Value;
+ }
+
+ bool operator <(const TEnumValue& value) const {
+ if (!Name.empty() && !value.Name.empty()) {
+ return Name < value.Name;
+ }
+ return Value < value.Value;
+ }
+
+ bool operator <=(const TEnumValue& value) const {
+ if (!Name.empty() && !value.Name.empty()) {
+ return Name <= value.Name;
+ }
+ return Value <= value.Value;
+ }
+
+ bool operator >(const TEnumValue& value) const {
+ if (!Name.empty() && !value.Name.empty()) {
+ return Name > value.Name;
+ }
+ return Value > value.Value;
+ }
+
+ bool operator >=(const TEnumValue& value) const {
+ if (!Name.empty() && !value.Name.empty()) {
+ return Name >= value.Name;
+ }
+ return Value >= value.Value;
+ }
+};
+
+struct TMessageValue {
+ TString Value;
+
+ TMessageValue(const TString& value)
+ : Value(value)
+ {}
+
+ bool operator ==(const TMessageValue& value) const {
+ return Value == value.Value;
+ }
+
+ bool operator !=(const TMessageValue& value) const {
+ return Value != value.Value;
+ }
+
+ bool operator <(const TMessageValue& value) const {
+ return Value < value.Value;
+ }
+};
+
+template <typename CppType>
+class TFieldProtoValueExtractor {
+public:
+ TFieldProtoValueExtractor(const FieldDescriptor* field)
+ : Field(field)
+ {}
+
+ CppType ExtractValue(const Reflection& reflection, const Message& element) const;
+
+protected:
+ const FieldDescriptor* Field;
+};
+
+template <typename ResponseType>
+class TWhiteboardFilter {
+public:
+ using TResponseType = typename TWhiteboardInfo<ResponseType>::TResponseType;
+ using TElementType = typename TWhiteboardInfo<ResponseType>::TElementType;
+
+ class IFieldProtoFilter {
+ public:
+ virtual ~IFieldProtoFilter() = default;
+ virtual bool CheckFilter(const TElementType& element) const = 0;
+ };
+
+ template <typename CppType>
+ class TFieldProtoFilterEqValue : public IFieldProtoFilter, public TFieldProtoValueExtractor<CppType> {
+ public:
+ TFieldProtoFilterEqValue(const FieldDescriptor* field, CppType value)
+ : TFieldProtoValueExtractor<CppType>(field)
+ , Value(value)
+ {}
+
+ bool CheckFilter(const TElementType& element) const override {
+ return TFieldProtoValueExtractor<CppType>::ExtractValue(*element.GetReflection(), element) == Value;
+ }
+
+ protected:
+ CppType Value;
+ };
+
+ template <typename CppType>
+ class TFieldProtoFilterInValue : public IFieldProtoFilter, public TFieldProtoValueExtractor<CppType> {
+ public:
+ TFieldProtoFilterInValue(const FieldDescriptor* field, const TVector<CppType>& values)
+ : TFieldProtoValueExtractor<CppType>(field)
+ , Values(values.begin(), values.end())
+ {}
+
+ bool CheckFilter(const TElementType& element) const override {
+ auto value = TFieldProtoValueExtractor<CppType>::ExtractValue(*element.GetReflection(), element);
+ return Values.count(value) != 0;
+ }
+
+ protected:
+ TSet<CppType> Values;
+ };
+
+ template <typename CppType>
+ class TFieldProtoFilterNeValue : public IFieldProtoFilter, public TFieldProtoValueExtractor<CppType> {
+ public:
+ TFieldProtoFilterNeValue(const FieldDescriptor* field, CppType value)
+ : TFieldProtoValueExtractor<CppType>(field)
+ , Value(value)
+ {}
+
+ bool CheckFilter(const TElementType& element) const override {
+ return TFieldProtoValueExtractor<CppType>::ExtractValue(*element.GetReflection(), element) != Value;
+ }
+
+ protected:
+ CppType Value;
+ };
+
+ template <typename CppType>
+ class TFieldProtoFilterLtValue : public IFieldProtoFilter, public TFieldProtoValueExtractor<CppType> {
+ public:
+ TFieldProtoFilterLtValue(const FieldDescriptor* field, CppType value)
+ : TFieldProtoValueExtractor<CppType>(field)
+ , Value(value)
+ {}
+
+ bool CheckFilter(const TElementType& element) const override {
+ return TFieldProtoValueExtractor<CppType>::ExtractValue(*element.GetReflection(), element) < Value;
+ }
+
+ protected:
+ CppType Value;
+ };
+
+ template <typename CppType>
+ class TFieldProtoFilterLeValue : public IFieldProtoFilter, public TFieldProtoValueExtractor<CppType> {
+ public:
+ TFieldProtoFilterLeValue(const FieldDescriptor* field, CppType value)
+ : TFieldProtoValueExtractor<CppType>(field)
+ , Value(value)
+ {}
+
+ bool CheckFilter(const TElementType& element) const override {
+ return TFieldProtoValueExtractor<CppType>::ExtractValue(*element.GetReflection(), element) <= Value;
+ }
+
+ protected:
+ CppType Value;
+ };
+
+ template <typename CppType>
+ class TFieldProtoFilterGtValue : public IFieldProtoFilter, public TFieldProtoValueExtractor<CppType> {
+ public:
+ TFieldProtoFilterGtValue(const FieldDescriptor* field, CppType value)
+ : TFieldProtoValueExtractor<CppType>(field)
+ , Value(value)
+ {}
+
+ bool CheckFilter(const TElementType& element) const override {
+ return TFieldProtoValueExtractor<CppType>::ExtractValue(*element.GetReflection(), element) > Value;
+ }
+
+ protected:
+ CppType Value;
+ };
+
+ template <typename CppType>
+ class TFieldProtoFilterGeValue : public IFieldProtoFilter, public TFieldProtoValueExtractor<CppType> {
+ public:
+ TFieldProtoFilterGeValue(const FieldDescriptor* field, CppType value)
+ : TFieldProtoValueExtractor<CppType>(field)
+ , Value(value)
+ {}
+
+ bool CheckFilter(const TElementType& element) const override {
+ return TFieldProtoValueExtractor<CppType>::ExtractValue(*element.GetReflection(), element) >= Value;
+ }
+
+ protected:
+ CppType Value;
+ };
+
static THolder<ResponseType> FilterResponse(THolder<TResponseType>& source, const TVector<THolder<IFieldProtoFilter>>& filters) {
THolder<TResponseType> result = MakeHolder<TResponseType>();
- auto* field = TWhiteboardInfo<ResponseType>::GetElementsField(result.Get());
- auto* sourceField = TWhiteboardInfo<ResponseType>::GetElementsField(source.Get());
- field->Reserve(sourceField->size());
- for (TElementType& info : *sourceField) {
- size_t cnt = 0;
- for (const THolder<IFieldProtoFilter>& filter : filters) {
- if (!filter->CheckFilter(info))
- break;
- ++cnt;
- }
- if (cnt == filters.size()) {
- // TODO: swap already allocated element of repeatedptr field
- auto* element = field->Add();
- element->Swap(&info);
- }
- }
- result->Record.SetResponseTime(source->Record.GetResponseTime());
- return result;
- }
-
- template <typename Type>
- static TVector<Type> FromStringWithDefaultArray(const TVector<TString>& values) {
- TVector<Type> result;
- for (const TString& value : values) {
- result.emplace_back(FromStringWithDefault<Type>(value));
- }
- return result;
- }
-
- template <typename Type>
- static TVector<Type> ConvertStringArray(const TVector<TString>& values) {
- TVector<Type> result;
- for (const TString& value : values) {
- result.emplace_back(value);
- }
- return result;
- }
-
+ auto* field = TWhiteboardInfo<ResponseType>::GetElementsField(result.Get());
+ auto* sourceField = TWhiteboardInfo<ResponseType>::GetElementsField(source.Get());
+ field->Reserve(sourceField->size());
+ for (TElementType& info : *sourceField) {
+ size_t cnt = 0;
+ for (const THolder<IFieldProtoFilter>& filter : filters) {
+ if (!filter->CheckFilter(info))
+ break;
+ ++cnt;
+ }
+ if (cnt == filters.size()) {
+ // TODO: swap already allocated element of repeatedptr field
+ auto* element = field->Add();
+ element->Swap(&info);
+ }
+ }
+ result->Record.SetResponseTime(source->Record.GetResponseTime());
+ return result;
+ }
+
+ template <typename Type>
+ static TVector<Type> FromStringWithDefaultArray(const TVector<TString>& values) {
+ TVector<Type> result;
+ for (const TString& value : values) {
+ result.emplace_back(FromStringWithDefault<Type>(value));
+ }
+ return result;
+ }
+
+ template <typename Type>
+ static TVector<Type> ConvertStringArray(const TVector<TString>& values) {
+ TVector<Type> result;
+ for (const TString& value : values) {
+ result.emplace_back(value);
+ }
+ return result;
+ }
+
static TVector<THolder<IFieldProtoFilter>> GetProtoFilters(TString filters) {
- // TODO: convert to StringBuf operations?
- const Descriptor& descriptor = *TElementType::descriptor();
+ // TODO: convert to StringBuf operations?
+ const Descriptor& descriptor = *TElementType::descriptor();
TVector<TString> requestedFilters;
TVector<THolder<IFieldProtoFilter>> foundFilters;
if (filters.StartsWith('(') && filters.EndsWith(')')) {
- filters = filters.substr(1, filters.size() - 2);
- }
- StringSplitter(filters).Split(';').SkipEmpty().Collect(&requestedFilters);
+ filters = filters.substr(1, filters.size() - 2);
+ }
+ StringSplitter(filters).Split(';').SkipEmpty().Collect(&requestedFilters);
for (const TString& str : requestedFilters) {
- size_t opFirstPos = str.find_first_of("!><=");
- // TODO: replace with error reporting
+ size_t opFirstPos = str.find_first_of("!><=");
+ // TODO: replace with error reporting
//Y_VERIFY(opPos != TString::npos);
- THolder<IFieldProtoFilter> filter;
+ THolder<IFieldProtoFilter> filter;
TString field = str.substr(0, opFirstPos);
- size_t opEndPos = str.find_first_not_of("!><=", opFirstPos);
- if (opEndPos != TString::npos) {
- TString op = str.substr(opFirstPos, opEndPos - opFirstPos);
- TString value = str.substr(opEndPos);
- // TODO: replace with error reporting
- //Y_VERIFY(op == "=");
- const FieldDescriptor* fieldDescriptor = descriptor.FindFieldByName(field);
- if (fieldDescriptor != nullptr) {
- if (op == "=" || op == "==") {
- if (value.StartsWith('[') && value.EndsWith(']')) {
- TVector<TString> values;
- StringSplitter(value.substr(1, value.size() - 2)).Split(',').SkipEmpty().Collect(&values);
- switch (fieldDescriptor->cpp_type()) {
- case FieldDescriptor::CPPTYPE_INT32:
+ size_t opEndPos = str.find_first_not_of("!><=", opFirstPos);
+ if (opEndPos != TString::npos) {
+ TString op = str.substr(opFirstPos, opEndPos - opFirstPos);
+ TString value = str.substr(opEndPos);
+ // TODO: replace with error reporting
+ //Y_VERIFY(op == "=");
+ const FieldDescriptor* fieldDescriptor = descriptor.FindFieldByName(field);
+ if (fieldDescriptor != nullptr) {
+ if (op == "=" || op == "==") {
+ if (value.StartsWith('[') && value.EndsWith(']')) {
+ TVector<TString> values;
+ StringSplitter(value.substr(1, value.size() - 2)).Split(',').SkipEmpty().Collect(&values);
+ switch (fieldDescriptor->cpp_type()) {
+ case FieldDescriptor::CPPTYPE_INT32:
filter = MakeHolder<TFieldProtoFilterInValue<i32>>(fieldDescriptor, FromStringWithDefaultArray<i32>(values));
- break;
- case FieldDescriptor::CPPTYPE_INT64:
+ break;
+ case FieldDescriptor::CPPTYPE_INT64:
filter = MakeHolder<TFieldProtoFilterInValue<i64>>(fieldDescriptor, FromStringWithDefaultArray<i64>(values));
- break;
- case FieldDescriptor::CPPTYPE_UINT32:
+ break;
+ case FieldDescriptor::CPPTYPE_UINT32:
filter = MakeHolder<TFieldProtoFilterInValue<ui32>>(fieldDescriptor, FromStringWithDefaultArray<ui32>(values));
- break;
- case FieldDescriptor::CPPTYPE_UINT64:
+ break;
+ case FieldDescriptor::CPPTYPE_UINT64:
filter = MakeHolder<TFieldProtoFilterInValue<ui64>>(fieldDescriptor, FromStringWithDefaultArray<ui64>(values));
- break;
- case FieldDescriptor::CPPTYPE_DOUBLE:
+ break;
+ case FieldDescriptor::CPPTYPE_DOUBLE:
filter = MakeHolder<TFieldProtoFilterInValue<double>>(fieldDescriptor, FromStringWithDefaultArray<double>(values));
- break;
- case FieldDescriptor::CPPTYPE_FLOAT:
+ break;
+ case FieldDescriptor::CPPTYPE_FLOAT:
filter = MakeHolder<TFieldProtoFilterInValue<float>>(fieldDescriptor, FromStringWithDefaultArray<float>(values));
- break;
- case FieldDescriptor::CPPTYPE_BOOL:
+ break;
+ case FieldDescriptor::CPPTYPE_BOOL:
filter = MakeHolder<TFieldProtoFilterInValue<bool>>(fieldDescriptor, FromStringWithDefaultArray<bool>(values));
- break;
- case FieldDescriptor::CPPTYPE_ENUM:
+ break;
+ case FieldDescriptor::CPPTYPE_ENUM:
filter = MakeHolder<TFieldProtoFilterInValue<TEnumValue>>(fieldDescriptor, ConvertStringArray<TEnumValue>(values));
- break;
- case FieldDescriptor::CPPTYPE_STRING:
+ break;
+ case FieldDescriptor::CPPTYPE_STRING:
filter = MakeHolder<TFieldProtoFilterInValue<TString>>(fieldDescriptor, values);
- break;
- case FieldDescriptor::CPPTYPE_MESSAGE:
+ break;
+ case FieldDescriptor::CPPTYPE_MESSAGE:
filter = MakeHolder<TFieldProtoFilterInValue<TMessageValue>>(fieldDescriptor, ConvertStringArray<TMessageValue>(values));
- break;
- default:
- break;
- }
- } else {
- switch (fieldDescriptor->cpp_type()) {
- case FieldDescriptor::CPPTYPE_INT32:
+ break;
+ default:
+ break;
+ }
+ } else {
+ switch (fieldDescriptor->cpp_type()) {
+ case FieldDescriptor::CPPTYPE_INT32:
filter = MakeHolder<TFieldProtoFilterEqValue<i32>>(fieldDescriptor, FromStringWithDefault<i32>(value));
- break;
- case FieldDescriptor::CPPTYPE_INT64:
+ break;
+ case FieldDescriptor::CPPTYPE_INT64:
filter = MakeHolder<TFieldProtoFilterEqValue<i64>>(fieldDescriptor, FromStringWithDefault<i64>(value));
- break;
- case FieldDescriptor::CPPTYPE_UINT32:
+ break;
+ case FieldDescriptor::CPPTYPE_UINT32:
filter = MakeHolder<TFieldProtoFilterEqValue<ui32>>(fieldDescriptor, FromStringWithDefault<ui32>(value));
- break;
- case FieldDescriptor::CPPTYPE_UINT64:
+ break;
+ case FieldDescriptor::CPPTYPE_UINT64:
filter = MakeHolder<TFieldProtoFilterEqValue<ui64>>(fieldDescriptor, FromStringWithDefault<ui64>(value));
- break;
- case FieldDescriptor::CPPTYPE_DOUBLE:
+ break;
+ case FieldDescriptor::CPPTYPE_DOUBLE:
filter = MakeHolder<TFieldProtoFilterEqValue<double>>(fieldDescriptor, FromStringWithDefault<double>(value));
- break;
- case FieldDescriptor::CPPTYPE_FLOAT:
+ break;
+ case FieldDescriptor::CPPTYPE_FLOAT:
filter = MakeHolder<TFieldProtoFilterEqValue<float>>(fieldDescriptor, FromStringWithDefault<float>(value));
- break;
- case FieldDescriptor::CPPTYPE_BOOL:
+ break;
+ case FieldDescriptor::CPPTYPE_BOOL:
filter = MakeHolder<TFieldProtoFilterEqValue<bool>>(fieldDescriptor, FromStringWithDefault<bool>(value));
- break;
- case FieldDescriptor::CPPTYPE_ENUM:
+ break;
+ case FieldDescriptor::CPPTYPE_ENUM:
filter = MakeHolder<TFieldProtoFilterEqValue<TEnumValue>>(fieldDescriptor, TEnumValue(value));
- break;
- case FieldDescriptor::CPPTYPE_STRING:
+ break;
+ case FieldDescriptor::CPPTYPE_STRING:
filter = MakeHolder<TFieldProtoFilterEqValue<TString>>(fieldDescriptor, value);
- break;
- case FieldDescriptor::CPPTYPE_MESSAGE:
+ break;
+ case FieldDescriptor::CPPTYPE_MESSAGE:
filter = MakeHolder<TFieldProtoFilterEqValue<TMessageValue>>(fieldDescriptor, TMessageValue(value));
- break;
- default:
- break;
- }
- }
- } else if (op == "<>" || op == "!=") {
- switch (fieldDescriptor->cpp_type()) {
- case FieldDescriptor::CPPTYPE_INT32:
+ break;
+ default:
+ break;
+ }
+ }
+ } else if (op == "<>" || op == "!=") {
+ switch (fieldDescriptor->cpp_type()) {
+ case FieldDescriptor::CPPTYPE_INT32:
filter = MakeHolder<TFieldProtoFilterNeValue<i32>>(fieldDescriptor, FromStringWithDefault<i32>(value));
- break;
- case FieldDescriptor::CPPTYPE_INT64:
+ break;
+ case FieldDescriptor::CPPTYPE_INT64:
filter = MakeHolder<TFieldProtoFilterNeValue<i64>>(fieldDescriptor, FromStringWithDefault<i64>(value));
- break;
- case FieldDescriptor::CPPTYPE_UINT32:
+ break;
+ case FieldDescriptor::CPPTYPE_UINT32:
filter = MakeHolder<TFieldProtoFilterNeValue<ui32>>(fieldDescriptor, FromStringWithDefault<ui32>(value));
- break;
- case FieldDescriptor::CPPTYPE_UINT64:
+ break;
+ case FieldDescriptor::CPPTYPE_UINT64:
filter = MakeHolder<TFieldProtoFilterNeValue<ui64>>(fieldDescriptor, FromStringWithDefault<ui64>(value));
- break;
- case FieldDescriptor::CPPTYPE_DOUBLE:
+ break;
+ case FieldDescriptor::CPPTYPE_DOUBLE:
filter = MakeHolder<TFieldProtoFilterNeValue<double>>(fieldDescriptor, FromStringWithDefault<double>(value));
- break;
- case FieldDescriptor::CPPTYPE_FLOAT:
+ break;
+ case FieldDescriptor::CPPTYPE_FLOAT:
filter = MakeHolder<TFieldProtoFilterNeValue<float>>(fieldDescriptor, FromStringWithDefault<float>(value));
- break;
- case FieldDescriptor::CPPTYPE_BOOL:
+ break;
+ case FieldDescriptor::CPPTYPE_BOOL:
filter = MakeHolder<TFieldProtoFilterNeValue<bool>>(fieldDescriptor, FromStringWithDefault<bool>(value));
- break;
- case FieldDescriptor::CPPTYPE_ENUM:
+ break;
+ case FieldDescriptor::CPPTYPE_ENUM:
filter = MakeHolder<TFieldProtoFilterNeValue<TEnumValue>>(fieldDescriptor, TEnumValue(value));
- break;
- case FieldDescriptor::CPPTYPE_STRING:
+ break;
+ case FieldDescriptor::CPPTYPE_STRING:
filter = MakeHolder<TFieldProtoFilterNeValue<TString>>(fieldDescriptor, value);
- break;
- case FieldDescriptor::CPPTYPE_MESSAGE:
+ break;
+ case FieldDescriptor::CPPTYPE_MESSAGE:
filter = MakeHolder<TFieldProtoFilterNeValue<TMessageValue>>(fieldDescriptor, TMessageValue(value));
- break;
- default:
- break;
- }
- } else if (op == "<") {
- switch (fieldDescriptor->cpp_type()) {
- case FieldDescriptor::CPPTYPE_INT32:
+ break;
+ default:
+ break;
+ }
+ } else if (op == "<") {
+ switch (fieldDescriptor->cpp_type()) {
+ case FieldDescriptor::CPPTYPE_INT32:
filter = MakeHolder<TFieldProtoFilterLtValue<i32>>(fieldDescriptor, FromStringWithDefault<i32>(value));
- break;
- case FieldDescriptor::CPPTYPE_INT64:
+ break;
+ case FieldDescriptor::CPPTYPE_INT64:
filter = MakeHolder<TFieldProtoFilterLtValue<i64>>(fieldDescriptor, FromStringWithDefault<i64>(value));
- break;
- case FieldDescriptor::CPPTYPE_UINT32:
+ break;
+ case FieldDescriptor::CPPTYPE_UINT32:
filter = MakeHolder<TFieldProtoFilterLtValue<ui32>>(fieldDescriptor, FromStringWithDefault<ui32>(value));
- break;
- case FieldDescriptor::CPPTYPE_UINT64:
+ break;
+ case FieldDescriptor::CPPTYPE_UINT64:
filter = MakeHolder<TFieldProtoFilterLtValue<ui64>>(fieldDescriptor, FromStringWithDefault<ui64>(value));
- break;
- case FieldDescriptor::CPPTYPE_DOUBLE:
+ break;
+ case FieldDescriptor::CPPTYPE_DOUBLE:
filter = MakeHolder<TFieldProtoFilterLtValue<double>>(fieldDescriptor, FromStringWithDefault<double>(value));
- break;
- case FieldDescriptor::CPPTYPE_FLOAT:
+ break;
+ case FieldDescriptor::CPPTYPE_FLOAT:
filter = MakeHolder<TFieldProtoFilterLtValue<float>>(fieldDescriptor, FromStringWithDefault<float>(value));
- break;
- case FieldDescriptor::CPPTYPE_BOOL:
+ break;
+ case FieldDescriptor::CPPTYPE_BOOL:
filter = MakeHolder<TFieldProtoFilterLtValue<bool>>(fieldDescriptor, FromStringWithDefault<bool>(value));
- break;
- case FieldDescriptor::CPPTYPE_ENUM:
+ break;
+ case FieldDescriptor::CPPTYPE_ENUM:
filter = MakeHolder<TFieldProtoFilterLtValue<TEnumValue>>(fieldDescriptor, TEnumValue(value));
- break;
- case FieldDescriptor::CPPTYPE_STRING:
+ break;
+ case FieldDescriptor::CPPTYPE_STRING:
filter = MakeHolder<TFieldProtoFilterLtValue<TString>>(fieldDescriptor, value);
- break;
- default:
- break;
- }
- } else if (op == ">") {
- switch (fieldDescriptor->cpp_type()) {
- case FieldDescriptor::CPPTYPE_INT32:
+ break;
+ default:
+ break;
+ }
+ } else if (op == ">") {
+ switch (fieldDescriptor->cpp_type()) {
+ case FieldDescriptor::CPPTYPE_INT32:
filter = MakeHolder<TFieldProtoFilterGtValue<i32>>(fieldDescriptor, FromStringWithDefault<i32>(value));
- break;
- case FieldDescriptor::CPPTYPE_INT64:
+ break;
+ case FieldDescriptor::CPPTYPE_INT64:
filter = MakeHolder<TFieldProtoFilterGtValue<i64>>(fieldDescriptor, FromStringWithDefault<i64>(value));
- break;
- case FieldDescriptor::CPPTYPE_UINT32:
+ break;
+ case FieldDescriptor::CPPTYPE_UINT32:
filter = MakeHolder<TFieldProtoFilterGtValue<ui32>>(fieldDescriptor, FromStringWithDefault<ui32>(value));
- break;
- case FieldDescriptor::CPPTYPE_UINT64:
+ break;
+ case FieldDescriptor::CPPTYPE_UINT64:
filter = MakeHolder<TFieldProtoFilterGtValue<ui64>>(fieldDescriptor, FromStringWithDefault<ui64>(value));
- break;
- case FieldDescriptor::CPPTYPE_DOUBLE:
+ break;
+ case FieldDescriptor::CPPTYPE_DOUBLE:
filter = MakeHolder<TFieldProtoFilterGtValue<double>>(fieldDescriptor, FromStringWithDefault<double>(value));
- break;
- case FieldDescriptor::CPPTYPE_FLOAT:
+ break;
+ case FieldDescriptor::CPPTYPE_FLOAT:
filter = MakeHolder<TFieldProtoFilterGtValue<float>>(fieldDescriptor, FromStringWithDefault<float>(value));
- break;
- case FieldDescriptor::CPPTYPE_BOOL:
+ break;
+ case FieldDescriptor::CPPTYPE_BOOL:
filter = MakeHolder<TFieldProtoFilterGtValue<bool>>(fieldDescriptor, FromStringWithDefault<bool>(value));
- break;
- case FieldDescriptor::CPPTYPE_ENUM:
+ break;
+ case FieldDescriptor::CPPTYPE_ENUM:
filter = MakeHolder<TFieldProtoFilterGtValue<TEnumValue>>(fieldDescriptor, TEnumValue(value));
- break;
- case FieldDescriptor::CPPTYPE_STRING:
+ break;
+ case FieldDescriptor::CPPTYPE_STRING:
filter = MakeHolder<TFieldProtoFilterGtValue<TString>>(fieldDescriptor, value);
- break;
- default:
- break;
- }
- } else if (op == "<=") {
- switch (fieldDescriptor->cpp_type()) {
- case FieldDescriptor::CPPTYPE_INT32:
+ break;
+ default:
+ break;
+ }
+ } else if (op == "<=") {
+ switch (fieldDescriptor->cpp_type()) {
+ case FieldDescriptor::CPPTYPE_INT32:
filter = MakeHolder<TFieldProtoFilterLeValue<i32>>(fieldDescriptor, FromStringWithDefault<i32>(value));
- break;
- case FieldDescriptor::CPPTYPE_INT64:
+ break;
+ case FieldDescriptor::CPPTYPE_INT64:
filter = MakeHolder<TFieldProtoFilterLeValue<i64>>(fieldDescriptor, FromStringWithDefault<i64>(value));
- break;
- case FieldDescriptor::CPPTYPE_UINT32:
+ break;
+ case FieldDescriptor::CPPTYPE_UINT32:
filter = MakeHolder<TFieldProtoFilterLeValue<ui32>>(fieldDescriptor, FromStringWithDefault<ui32>(value));
- break;
- case FieldDescriptor::CPPTYPE_UINT64:
+ break;
+ case FieldDescriptor::CPPTYPE_UINT64:
filter = MakeHolder<TFieldProtoFilterLeValue<ui64>>(fieldDescriptor, FromStringWithDefault<ui64>(value));
- break;
- case FieldDescriptor::CPPTYPE_DOUBLE:
+ break;
+ case FieldDescriptor::CPPTYPE_DOUBLE:
filter = MakeHolder<TFieldProtoFilterLeValue<double>>(fieldDescriptor, FromStringWithDefault<double>(value));
- break;
- case FieldDescriptor::CPPTYPE_FLOAT:
+ break;
+ case FieldDescriptor::CPPTYPE_FLOAT:
filter = MakeHolder<TFieldProtoFilterLeValue<float>>(fieldDescriptor, FromStringWithDefault<float>(value));
- break;
- case FieldDescriptor::CPPTYPE_BOOL:
+ break;
+ case FieldDescriptor::CPPTYPE_BOOL:
filter = MakeHolder<TFieldProtoFilterLeValue<bool>>(fieldDescriptor, FromStringWithDefault<bool>(value));
- break;
- case FieldDescriptor::CPPTYPE_ENUM:
+ break;
+ case FieldDescriptor::CPPTYPE_ENUM:
filter = MakeHolder<TFieldProtoFilterLeValue<TEnumValue>>(fieldDescriptor, TEnumValue(value));
- break;
- case FieldDescriptor::CPPTYPE_STRING:
+ break;
+ case FieldDescriptor::CPPTYPE_STRING:
filter = MakeHolder<TFieldProtoFilterLeValue<TString>>(fieldDescriptor, value);
- break;
- default:
- break;
- }
- } else if (op == ">=") {
- switch (fieldDescriptor->cpp_type()) {
- case FieldDescriptor::CPPTYPE_INT32:
+ break;
+ default:
+ break;
+ }
+ } else if (op == ">=") {
+ switch (fieldDescriptor->cpp_type()) {
+ case FieldDescriptor::CPPTYPE_INT32:
filter = MakeHolder<TFieldProtoFilterGeValue<i32>>(fieldDescriptor, FromStringWithDefault<i32>(value));
- break;
- case FieldDescriptor::CPPTYPE_INT64:
+ break;
+ case FieldDescriptor::CPPTYPE_INT64:
filter = MakeHolder<TFieldProtoFilterGeValue<i64>>(fieldDescriptor, FromStringWithDefault<i64>(value));
- break;
- case FieldDescriptor::CPPTYPE_UINT32:
+ break;
+ case FieldDescriptor::CPPTYPE_UINT32:
filter = MakeHolder<TFieldProtoFilterGeValue<ui32>>(fieldDescriptor, FromStringWithDefault<ui32>(value));
- break;
- case FieldDescriptor::CPPTYPE_UINT64:
+ break;
+ case FieldDescriptor::CPPTYPE_UINT64:
filter = MakeHolder<TFieldProtoFilterGeValue<ui64>>(fieldDescriptor, FromStringWithDefault<ui64>(value));
- break;
- case FieldDescriptor::CPPTYPE_DOUBLE:
+ break;
+ case FieldDescriptor::CPPTYPE_DOUBLE:
filter = MakeHolder<TFieldProtoFilterGeValue<double>>(fieldDescriptor, FromStringWithDefault<double>(value));
- break;
- case FieldDescriptor::CPPTYPE_FLOAT:
+ break;
+ case FieldDescriptor::CPPTYPE_FLOAT:
filter = MakeHolder<TFieldProtoFilterGeValue<float>>(fieldDescriptor, FromStringWithDefault<float>(value));
- break;
- case FieldDescriptor::CPPTYPE_BOOL:
+ break;
+ case FieldDescriptor::CPPTYPE_BOOL:
filter = MakeHolder<TFieldProtoFilterGeValue<bool>>(fieldDescriptor, FromStringWithDefault<bool>(value));
- break;
- case FieldDescriptor::CPPTYPE_ENUM:
+ break;
+ case FieldDescriptor::CPPTYPE_ENUM:
filter = MakeHolder<TFieldProtoFilterGeValue<TEnumValue>>(fieldDescriptor, TEnumValue(value));
- break;
- case FieldDescriptor::CPPTYPE_STRING:
+ break;
+ case FieldDescriptor::CPPTYPE_STRING:
filter = MakeHolder<TFieldProtoFilterGeValue<TString>>(fieldDescriptor, value);
- break;
- default:
- break;
- }
- }
- }
- if (filter == nullptr) {
- throw yexception() << "invalid filter specified";
- }
- // TODO: replace with error reporting
- //Y_VERIFY(filter != nullptr);
- foundFilters.emplace_back(std::move(filter));
- }
- }
- // TODO: replace with error reporting
- //Y_VERIFY(requestedFilters.size() == foundFilters.size());
- return foundFilters;
- }
-};
-
-template <typename ResponseType>
+ break;
+ default:
+ break;
+ }
+ }
+ }
+ if (filter == nullptr) {
+ throw yexception() << "invalid filter specified";
+ }
+ // TODO: replace with error reporting
+ //Y_VERIFY(filter != nullptr);
+ foundFilters.emplace_back(std::move(filter));
+ }
+ }
+ // TODO: replace with error reporting
+ //Y_VERIFY(requestedFilters.size() == foundFilters.size());
+ return foundFilters;
+ }
+};
+
+template <typename ResponseType>
THolder<ResponseType> FilterWhiteboardResponses(THolder<ResponseType>& response, const TString& filters) {
TVector<THolder<typename TWhiteboardFilter<ResponseType>::IFieldProtoFilter>> filterFilters =
- TWhiteboardFilter<ResponseType>::GetProtoFilters(filters);
- return TWhiteboardFilter<ResponseType>::FilterResponse(response, filterFilters);
-}
-
-}
-}
+ TWhiteboardFilter<ResponseType>::GetProtoFilters(filters);
+ return TWhiteboardFilter<ResponseType>::FilterResponse(response, filterFilters);
+}
+
+}
+}
diff --git a/ydb/core/viewer/wb_group.h b/ydb/core/viewer/wb_group.h
index 2251e3ec8c1..9735d8f29ec 100644
--- a/ydb/core/viewer/wb_group.h
+++ b/ydb/core/viewer/wb_group.h
@@ -1,175 +1,175 @@
-#pragma once
-#include <util/string/vector.h>
+#pragma once
+#include <util/string/vector.h>
#include <ydb/core/node_whiteboard/node_whiteboard.h>
#include <util/string/split.h>
-
-namespace NKikimr {
-namespace NViewer {
-
-using namespace NNodeWhiteboard;
-using namespace ::google::protobuf;
-
-template <typename ResponseType>
-struct TWhiteboardInfo;
-
-template <typename ResponseType>
-class TWhiteboardGrouper {
-public:
- using TResponseType = typename TWhiteboardInfo<ResponseType>::TResponseType;
- using TElementType = typename TWhiteboardInfo<ResponseType>::TElementType;
- using TElementsFieldType = typename ::google::protobuf::RepeatedPtrField<TElementType>;
-
- class TFieldProtoValue {
- public:
- TFieldProtoValue(TElementType& element, const FieldDescriptor* field)
- : Element(element)
- , Field(field)
- {}
-
- bool operator ==(const TFieldProtoValue& value) const {
- Y_VERIFY(Field == value.Field);
- const Reflection& reflection = *Element.GetReflection();
- if (!reflection.HasField(Element, Field) || !reflection.HasField(value.Element, value.Field)) {
- return false;
- }
- switch(Field->cpp_type()) {
- case FieldDescriptor::CPPTYPE_INT32:
- return reflection.GetInt32(Element, Field) == reflection.GetInt32(value.Element, value.Field);
- case FieldDescriptor::CPPTYPE_INT64:
- return reflection.GetInt64(Element, Field) == reflection.GetInt64(value.Element, value.Field);
- case FieldDescriptor::CPPTYPE_UINT32:
- return reflection.GetUInt32(Element, Field) == reflection.GetUInt32(value.Element, value.Field);
- case FieldDescriptor::CPPTYPE_UINT64:
- return reflection.GetUInt64(Element, Field) == reflection.GetUInt64(value.Element, value.Field);
- case FieldDescriptor::CPPTYPE_DOUBLE:
- return reflection.GetDouble(Element, Field) == reflection.GetDouble(value.Element, value.Field);
- case FieldDescriptor::CPPTYPE_FLOAT:
- return reflection.GetFloat(Element, Field) == reflection.GetFloat(value.Element, value.Field);
- case FieldDescriptor::CPPTYPE_BOOL:
- return reflection.GetBool(Element, Field) == reflection.GetBool(value.Element, value.Field);
- case FieldDescriptor::CPPTYPE_ENUM:
- return reflection.GetEnum(Element, Field)->number() == reflection.GetEnum(value.Element, value.Field)->number();
- case FieldDescriptor::CPPTYPE_STRING:
- return reflection.GetString(Element, Field) == reflection.GetString(value.Element, value.Field);
- default:
- return false;
- }
- }
-
- bool operator <(const TFieldProtoValue& value) const {
- Y_VERIFY(Field == value.Field);
- const Reflection& reflection = *Element.GetReflection();
- if (!reflection.HasField(Element, Field) || !reflection.HasField(value.Element, value.Field)) {
- return false;
- }
- switch(Field->cpp_type()) {
- case FieldDescriptor::CPPTYPE_INT32:
- return reflection.GetInt32(Element, Field) < reflection.GetInt32(value.Element, value.Field);
- case FieldDescriptor::CPPTYPE_INT64:
- return reflection.GetInt64(Element, Field) < reflection.GetInt64(value.Element, value.Field);
- case FieldDescriptor::CPPTYPE_UINT32:
- return reflection.GetUInt32(Element, Field) < reflection.GetUInt32(value.Element, value.Field);
- case FieldDescriptor::CPPTYPE_UINT64:
- return reflection.GetUInt64(Element, Field) < reflection.GetUInt64(value.Element, value.Field);
- case FieldDescriptor::CPPTYPE_DOUBLE:
- return reflection.GetDouble(Element, Field) < reflection.GetDouble(value.Element, value.Field);
- case FieldDescriptor::CPPTYPE_FLOAT:
- return reflection.GetFloat(Element, Field) < reflection.GetFloat(value.Element, value.Field);
- case FieldDescriptor::CPPTYPE_BOOL:
- return reflection.GetBool(Element, Field) < reflection.GetBool(value.Element, value.Field);
- case FieldDescriptor::CPPTYPE_ENUM:
- return reflection.GetEnum(Element, Field)->number() < reflection.GetEnum(value.Element, value.Field)->number();
- case FieldDescriptor::CPPTYPE_STRING:
- return reflection.GetString(Element, Field) < reflection.GetString(value.Element, value.Field);
- default:
- return false;
- }
- }
-
- TFieldProtoValue& operator =(const TFieldProtoValue& value) {
- Y_VERIFY(Field == value.Field);
- const Reflection& reflection = *Element.GetReflection();
- switch(Field->cpp_type()) {
- case FieldDescriptor::CPPTYPE_INT32:
- reflection.SetInt32(&Element, Field, reflection.GetInt32(value.Element, value.Field));
- break;
- case FieldDescriptor::CPPTYPE_INT64:
- reflection.SetInt64(&Element, Field, reflection.GetInt64(value.Element, value.Field));
- break;
- case FieldDescriptor::CPPTYPE_UINT32:
- reflection.SetUInt32(&Element, Field, reflection.GetUInt32(value.Element, value.Field));
- break;
- case FieldDescriptor::CPPTYPE_UINT64:
- reflection.SetUInt64(&Element, Field, reflection.GetUInt64(value.Element, value.Field));
- break;
- case FieldDescriptor::CPPTYPE_DOUBLE:
- reflection.SetDouble(&Element, Field, reflection.GetDouble(value.Element, value.Field));
- break;
- case FieldDescriptor::CPPTYPE_FLOAT:
- reflection.SetFloat(&Element, Field, reflection.GetFloat(value.Element, value.Field));
- break;
- case FieldDescriptor::CPPTYPE_BOOL:
- reflection.SetBool(&Element, Field, reflection.GetBool(value.Element, value.Field));
- break;
- case FieldDescriptor::CPPTYPE_ENUM:
- reflection.SetEnum(&Element, Field, reflection.GetEnum(value.Element, value.Field));
- break;
- case FieldDescriptor::CPPTYPE_STRING:
- reflection.SetString(&Element, Field, reflection.GetString(value.Element, value.Field));
- break;
- default:
- break;
- }
- return *this;
- }
-
- TFieldProtoValue& operator =(const EnumValueDescriptor* descriptor) {
- const Reflection& reflection = *Element.GetReflection();
- reflection.SetEnum(&Element, Field, descriptor);
- return *this;
- }
-
- protected:
- TElementType& Element;
- const FieldDescriptor* Field;
- };
-
- class TPartProtoKeyEnum {
- public:
+
+namespace NKikimr {
+namespace NViewer {
+
+using namespace NNodeWhiteboard;
+using namespace ::google::protobuf;
+
+template <typename ResponseType>
+struct TWhiteboardInfo;
+
+template <typename ResponseType>
+class TWhiteboardGrouper {
+public:
+ using TResponseType = typename TWhiteboardInfo<ResponseType>::TResponseType;
+ using TElementType = typename TWhiteboardInfo<ResponseType>::TElementType;
+ using TElementsFieldType = typename ::google::protobuf::RepeatedPtrField<TElementType>;
+
+ class TFieldProtoValue {
+ public:
+ TFieldProtoValue(TElementType& element, const FieldDescriptor* field)
+ : Element(element)
+ , Field(field)
+ {}
+
+ bool operator ==(const TFieldProtoValue& value) const {
+ Y_VERIFY(Field == value.Field);
+ const Reflection& reflection = *Element.GetReflection();
+ if (!reflection.HasField(Element, Field) || !reflection.HasField(value.Element, value.Field)) {
+ return false;
+ }
+ switch(Field->cpp_type()) {
+ case FieldDescriptor::CPPTYPE_INT32:
+ return reflection.GetInt32(Element, Field) == reflection.GetInt32(value.Element, value.Field);
+ case FieldDescriptor::CPPTYPE_INT64:
+ return reflection.GetInt64(Element, Field) == reflection.GetInt64(value.Element, value.Field);
+ case FieldDescriptor::CPPTYPE_UINT32:
+ return reflection.GetUInt32(Element, Field) == reflection.GetUInt32(value.Element, value.Field);
+ case FieldDescriptor::CPPTYPE_UINT64:
+ return reflection.GetUInt64(Element, Field) == reflection.GetUInt64(value.Element, value.Field);
+ case FieldDescriptor::CPPTYPE_DOUBLE:
+ return reflection.GetDouble(Element, Field) == reflection.GetDouble(value.Element, value.Field);
+ case FieldDescriptor::CPPTYPE_FLOAT:
+ return reflection.GetFloat(Element, Field) == reflection.GetFloat(value.Element, value.Field);
+ case FieldDescriptor::CPPTYPE_BOOL:
+ return reflection.GetBool(Element, Field) == reflection.GetBool(value.Element, value.Field);
+ case FieldDescriptor::CPPTYPE_ENUM:
+ return reflection.GetEnum(Element, Field)->number() == reflection.GetEnum(value.Element, value.Field)->number();
+ case FieldDescriptor::CPPTYPE_STRING:
+ return reflection.GetString(Element, Field) == reflection.GetString(value.Element, value.Field);
+ default:
+ return false;
+ }
+ }
+
+ bool operator <(const TFieldProtoValue& value) const {
+ Y_VERIFY(Field == value.Field);
+ const Reflection& reflection = *Element.GetReflection();
+ if (!reflection.HasField(Element, Field) || !reflection.HasField(value.Element, value.Field)) {
+ return false;
+ }
+ switch(Field->cpp_type()) {
+ case FieldDescriptor::CPPTYPE_INT32:
+ return reflection.GetInt32(Element, Field) < reflection.GetInt32(value.Element, value.Field);
+ case FieldDescriptor::CPPTYPE_INT64:
+ return reflection.GetInt64(Element, Field) < reflection.GetInt64(value.Element, value.Field);
+ case FieldDescriptor::CPPTYPE_UINT32:
+ return reflection.GetUInt32(Element, Field) < reflection.GetUInt32(value.Element, value.Field);
+ case FieldDescriptor::CPPTYPE_UINT64:
+ return reflection.GetUInt64(Element, Field) < reflection.GetUInt64(value.Element, value.Field);
+ case FieldDescriptor::CPPTYPE_DOUBLE:
+ return reflection.GetDouble(Element, Field) < reflection.GetDouble(value.Element, value.Field);
+ case FieldDescriptor::CPPTYPE_FLOAT:
+ return reflection.GetFloat(Element, Field) < reflection.GetFloat(value.Element, value.Field);
+ case FieldDescriptor::CPPTYPE_BOOL:
+ return reflection.GetBool(Element, Field) < reflection.GetBool(value.Element, value.Field);
+ case FieldDescriptor::CPPTYPE_ENUM:
+ return reflection.GetEnum(Element, Field)->number() < reflection.GetEnum(value.Element, value.Field)->number();
+ case FieldDescriptor::CPPTYPE_STRING:
+ return reflection.GetString(Element, Field) < reflection.GetString(value.Element, value.Field);
+ default:
+ return false;
+ }
+ }
+
+ TFieldProtoValue& operator =(const TFieldProtoValue& value) {
+ Y_VERIFY(Field == value.Field);
+ const Reflection& reflection = *Element.GetReflection();
+ switch(Field->cpp_type()) {
+ case FieldDescriptor::CPPTYPE_INT32:
+ reflection.SetInt32(&Element, Field, reflection.GetInt32(value.Element, value.Field));
+ break;
+ case FieldDescriptor::CPPTYPE_INT64:
+ reflection.SetInt64(&Element, Field, reflection.GetInt64(value.Element, value.Field));
+ break;
+ case FieldDescriptor::CPPTYPE_UINT32:
+ reflection.SetUInt32(&Element, Field, reflection.GetUInt32(value.Element, value.Field));
+ break;
+ case FieldDescriptor::CPPTYPE_UINT64:
+ reflection.SetUInt64(&Element, Field, reflection.GetUInt64(value.Element, value.Field));
+ break;
+ case FieldDescriptor::CPPTYPE_DOUBLE:
+ reflection.SetDouble(&Element, Field, reflection.GetDouble(value.Element, value.Field));
+ break;
+ case FieldDescriptor::CPPTYPE_FLOAT:
+ reflection.SetFloat(&Element, Field, reflection.GetFloat(value.Element, value.Field));
+ break;
+ case FieldDescriptor::CPPTYPE_BOOL:
+ reflection.SetBool(&Element, Field, reflection.GetBool(value.Element, value.Field));
+ break;
+ case FieldDescriptor::CPPTYPE_ENUM:
+ reflection.SetEnum(&Element, Field, reflection.GetEnum(value.Element, value.Field));
+ break;
+ case FieldDescriptor::CPPTYPE_STRING:
+ reflection.SetString(&Element, Field, reflection.GetString(value.Element, value.Field));
+ break;
+ default:
+ break;
+ }
+ return *this;
+ }
+
+ TFieldProtoValue& operator =(const EnumValueDescriptor* descriptor) {
+ const Reflection& reflection = *Element.GetReflection();
+ reflection.SetEnum(&Element, Field, descriptor);
+ return *this;
+ }
+
+ protected:
+ TElementType& Element;
+ const FieldDescriptor* Field;
+ };
+
+ class TPartProtoKeyEnum {
+ public:
TPartProtoKeyEnum(const TVector<const FieldDescriptor*>& fields)
- {
- for (const FieldDescriptor* field : fields) {
- const EnumDescriptor* enumDescriptor = field->enum_type();
- Fields.push_back(enumDescriptor);
- Values.push_back(enumDescriptor->value(0));
- }
- }
-
- bool operator ++() {
- for (int p = Fields.size() - 1; p >= 0; --p) {
- int index = Values[p]->index();
- if (++index >= Fields[p]->value_count()) {
- index = 0;
- }
- Values[p] = Fields[p]->value(index);
- if (index == 0)
- continue;
- return true;
- }
- return false;
- }
-
+ {
+ for (const FieldDescriptor* field : fields) {
+ const EnumDescriptor* enumDescriptor = field->enum_type();
+ Fields.push_back(enumDescriptor);
+ Values.push_back(enumDescriptor->value(0));
+ }
+ }
+
+ bool operator ++() {
+ for (int p = Fields.size() - 1; p >= 0; --p) {
+ int index = Values[p]->index();
+ if (++index >= Fields[p]->value_count()) {
+ index = 0;
+ }
+ Values[p] = Fields[p]->value(index);
+ if (index == 0)
+ continue;
+ return true;
+ }
+ return false;
+ }
+
TVector<const EnumDescriptor*> Fields;
TVector<const EnumValueDescriptor*> Values;
- };
-
- class TPartProtoKey {
- public:
+ };
+
+ class TPartProtoKey {
+ public:
TPartProtoKey(TElementType& element, const TVector<const FieldDescriptor*>& fields)
- : Element(element)
- , Fields(fields)
- {}
-
+ : Element(element)
+ , Fields(fields)
+ {}
+
TPartProtoKey(const TPartProtoKey& other)
: Element(other.Element)
, Fields(other.Fields)
@@ -177,131 +177,131 @@ public:
*this = other;
}
- bool operator ==(const TPartProtoKey& other) const {
- Y_VERIFY(Fields == other.Fields);
- for (const FieldDescriptor* field : Fields) {
- if (TFieldProtoValue(Element, field) == TFieldProtoValue(other.Element, field)) {
- continue;
- }
- return false;
- }
- return true;
- }
-
- bool operator <(const TPartProtoKey& other) const {
- Y_VERIFY(Fields == other.Fields);
- for (const FieldDescriptor* field : Fields) {
- if (TFieldProtoValue(Element, field) < TFieldProtoValue(other.Element, field)) {
- return true;
- }
- if (TFieldProtoValue(Element, field) == TFieldProtoValue(other.Element, field)) {
- continue;
- }
- return false;
- }
- return false;
- }
-
- TPartProtoKey& operator =(const TPartProtoKey& other) {
- Y_VERIFY(Fields == other.Fields);
- for (const FieldDescriptor* field : Fields) {
- TFieldProtoValue(Element, field) = TFieldProtoValue(other.Element, field);
- }
- return *this;
- }
-
- TPartProtoKey& operator =(const TPartProtoKeyEnum& other) {
- Y_VERIFY(Fields.size() == other.Fields.size());
- for (size_t i = 0; i < Fields.size(); ++i) {
- TFieldProtoValue(Element, Fields[i]) = other.Values[i];
- }
- return *this;
- }
-
- bool Exists() const {
- const Reflection& reflection = *Element.GetReflection();
- for (const FieldDescriptor* field : Fields) {
- if (!reflection.HasField(Element, field)) {
- return false;
- }
- }
- return true;
- }
-
- protected:
- TElementType& Element;
+ bool operator ==(const TPartProtoKey& other) const {
+ Y_VERIFY(Fields == other.Fields);
+ for (const FieldDescriptor* field : Fields) {
+ if (TFieldProtoValue(Element, field) == TFieldProtoValue(other.Element, field)) {
+ continue;
+ }
+ return false;
+ }
+ return true;
+ }
+
+ bool operator <(const TPartProtoKey& other) const {
+ Y_VERIFY(Fields == other.Fields);
+ for (const FieldDescriptor* field : Fields) {
+ if (TFieldProtoValue(Element, field) < TFieldProtoValue(other.Element, field)) {
+ return true;
+ }
+ if (TFieldProtoValue(Element, field) == TFieldProtoValue(other.Element, field)) {
+ continue;
+ }
+ return false;
+ }
+ return false;
+ }
+
+ TPartProtoKey& operator =(const TPartProtoKey& other) {
+ Y_VERIFY(Fields == other.Fields);
+ for (const FieldDescriptor* field : Fields) {
+ TFieldProtoValue(Element, field) = TFieldProtoValue(other.Element, field);
+ }
+ return *this;
+ }
+
+ TPartProtoKey& operator =(const TPartProtoKeyEnum& other) {
+ Y_VERIFY(Fields.size() == other.Fields.size());
+ for (size_t i = 0; i < Fields.size(); ++i) {
+ TFieldProtoValue(Element, Fields[i]) = other.Values[i];
+ }
+ return *this;
+ }
+
+ bool Exists() const {
+ const Reflection& reflection = *Element.GetReflection();
+ for (const FieldDescriptor* field : Fields) {
+ if (!reflection.HasField(Element, field)) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ protected:
+ TElementType& Element;
const TVector<const FieldDescriptor*>& Fields;
- };
-
+ };
+
static bool IsEnum(const TVector<const FieldDescriptor*>& fields) {
- for (const FieldDescriptor* field : fields) {
- if (field->cpp_type() != FieldDescriptor::CPPTYPE_ENUM) {
- return false;
- }
- }
- return true;
- }
-
+ for (const FieldDescriptor* field : fields) {
+ if (field->cpp_type() != FieldDescriptor::CPPTYPE_ENUM) {
+ return false;
+ }
+ }
+ return true;
+ }
+
static THolder<ResponseType> GroupResponse(THolder<TResponseType>& source, const TVector<const FieldDescriptor*>& groupFields, bool allEnums = false) {
THolder<TResponseType> result = MakeHolder<TResponseType>();
- TElementsFieldType* field = TWhiteboardInfo<ResponseType>::GetElementsField(result.Get());
- bool allKeys = allEnums && IsEnum(groupFields);
+ TElementsFieldType* field = TWhiteboardInfo<ResponseType>::GetElementsField(result.Get());
+ bool allKeys = allEnums && IsEnum(groupFields);
TMap<TPartProtoKey, ui32> counters;
TMap<TPartProtoKey, TElementType*> elements;
- if (allKeys) {
- TPartProtoKeyEnum keyEnum(groupFields);
- do {
- auto* element = field->Add();
- TPartProtoKey key(*element, groupFields);
- key = keyEnum;
- element->SetCount(0);
- elements.emplace(key, element);
- } while (++keyEnum);
- }
- auto* sourceField = TWhiteboardInfo<ResponseType>::GetElementsField(source.Get());
- for (TElementType& info : *sourceField) {
- TPartProtoKey key(info, groupFields);
- if (key.Exists()) {
- counters[key]++;
- }
- }
- for (const auto& pr : counters) {
- if (pr.second != 0) {
- if (allKeys) {
- elements[pr.first]->SetCount(pr.second);
- } else {
- auto* element = field->Add();
- TPartProtoKey(*element, groupFields) = pr.first;
- element->SetCount(pr.second);
- }
- }
- }
- result->Record.SetResponseTime(source->Record.GetResponseTime());
- return result;
- }
-
+ if (allKeys) {
+ TPartProtoKeyEnum keyEnum(groupFields);
+ do {
+ auto* element = field->Add();
+ TPartProtoKey key(*element, groupFields);
+ key = keyEnum;
+ element->SetCount(0);
+ elements.emplace(key, element);
+ } while (++keyEnum);
+ }
+ auto* sourceField = TWhiteboardInfo<ResponseType>::GetElementsField(source.Get());
+ for (TElementType& info : *sourceField) {
+ TPartProtoKey key(info, groupFields);
+ if (key.Exists()) {
+ counters[key]++;
+ }
+ }
+ for (const auto& pr : counters) {
+ if (pr.second != 0) {
+ if (allKeys) {
+ elements[pr.first]->SetCount(pr.second);
+ } else {
+ auto* element = field->Add();
+ TPartProtoKey(*element, groupFields) = pr.first;
+ element->SetCount(pr.second);
+ }
+ }
+ }
+ result->Record.SetResponseTime(source->Record.GetResponseTime());
+ return result;
+ }
+
static TVector<const FieldDescriptor*> GetProtoFields(const TString& fields) {
- const Descriptor& descriptor = *TElementType::descriptor();
+ const Descriptor& descriptor = *TElementType::descriptor();
TVector<TString> requestedFields;
TVector<const FieldDescriptor*> foundFields;
StringSplitter(fields).Split(',').SkipEmpty().Collect(&requestedFields);
for (const TString& str : requestedFields) {
- const FieldDescriptor* fieldDescriptor = descriptor.FindFieldByName(str);
- if (fieldDescriptor != nullptr) {
- foundFields.push_back(fieldDescriptor);
- }
- }
- // TODO: replace with error reporting
- //Y_VERIFY(requestedFields.size() == foundFields.size());
- return foundFields;
- }
-};
-
-template <typename ResponseType>
+ const FieldDescriptor* fieldDescriptor = descriptor.FindFieldByName(str);
+ if (fieldDescriptor != nullptr) {
+ foundFields.push_back(fieldDescriptor);
+ }
+ }
+ // TODO: replace with error reporting
+ //Y_VERIFY(requestedFields.size() == foundFields.size());
+ return foundFields;
+ }
+};
+
+template <typename ResponseType>
THolder<ResponseType> GroupWhiteboardResponses(THolder<ResponseType>& response, const TString& fields, bool allEnums = false) {
TVector<const FieldDescriptor*> groupFields = TWhiteboardGrouper<ResponseType>::GetProtoFields(fields);
- return TWhiteboardGrouper<ResponseType>::GroupResponse(response, groupFields, allEnums);
-}
-
-}
-}
+ return TWhiteboardGrouper<ResponseType>::GroupResponse(response, groupFields, allEnums);
+}
+
+}
+}
diff --git a/ydb/core/viewer/wb_merge.cpp b/ydb/core/viewer/wb_merge.cpp
index 2192324549a..cca5dc1d9de 100644
--- a/ydb/core/viewer/wb_merge.cpp
+++ b/ydb/core/viewer/wb_merge.cpp
@@ -1,219 +1,219 @@
-#include "wb_merge.h"
-
-namespace NKikimr {
-namespace NViewer {
-
-using namespace NNodeWhiteboard;
-using namespace ::google::protobuf;
-
-std::unordered_map<TWhiteboardMergerBase::TMergerKey, TWhiteboardMergerBase::TMergerValue> TWhiteboardMergerBase::FieldMerger;
-
-void TWhiteboardMergerBase::ProtoMaximizeEnumField(
- const ::google::protobuf::Reflection& reflectionTo,
- const ::google::protobuf::Reflection& reflectionFrom,
- ::google::protobuf::Message& protoTo,
- const ::google::protobuf::Message& protoFrom,
- const ::google::protobuf::FieldDescriptor* field) {
- bool has = reflectionTo.HasField(protoTo, field);
- auto val = reflectionFrom.GetEnum(protoFrom, field);
- if (!has || reflectionTo.GetEnum(protoTo, field)->number() < val->number()) {
- reflectionTo.SetEnum(&protoTo, field, val);
- }
-}
-
-void TWhiteboardMergerBase::ProtoMaximizeBoolField(
- const ::google::protobuf::Reflection& reflectionTo,
- const ::google::protobuf::Reflection& reflectionFrom,
- ::google::protobuf::Message& protoTo,
- const ::google::protobuf::Message& protoFrom,
- const ::google::protobuf::FieldDescriptor* field) {
- bool has = reflectionTo.HasField(protoTo, field);
- auto val = reflectionFrom.GetBool(protoFrom, field);
- if (!has || reflectionTo.GetBool(protoTo, field) < val) {
- reflectionTo.SetBool(&protoTo, field, val);
- }
-}
-
-void TWhiteboardMergerBase::ProtoMerge(google::protobuf::Message& protoTo, const google::protobuf::Message& protoFrom) {
- using namespace ::google::protobuf;
- const Descriptor& descriptor = *protoTo.GetDescriptor();
- const Reflection& reflectionTo = *protoTo.GetReflection();
- const Reflection& reflectionFrom = *protoFrom.GetReflection();
- int fieldCount = descriptor.field_count();
- for (int index = 0; index < fieldCount; ++index) {
- const FieldDescriptor* field = descriptor.field(index);
- auto it = FieldMerger.find(field);
- if (it != FieldMerger.end()) {
- it->second(reflectionTo, reflectionFrom, protoTo, protoFrom, field);
- continue;
- }
- if (field->is_repeated()) {
- FieldDescriptor::CppType type = field->cpp_type();
- int size = reflectionFrom.FieldSize(protoFrom, field);
- if (size != 0 && reflectionTo.FieldSize(protoTo, field) != size) {
- reflectionTo.ClearField(&protoTo, field);
- for (int i = 0; i < size; ++i) {
- switch (type) {
- case FieldDescriptor::CPPTYPE_INT32:
- reflectionTo.AddInt32(&protoTo, field, reflectionFrom.GetRepeatedInt32(protoFrom, field, i));
- break;
- case FieldDescriptor::CPPTYPE_INT64:
- reflectionTo.AddInt64(&protoTo, field, reflectionFrom.GetRepeatedInt64(protoFrom, field, i));
- break;
- case FieldDescriptor::CPPTYPE_UINT32:
- reflectionTo.AddUInt32(&protoTo, field, reflectionFrom.GetRepeatedUInt32(protoFrom, field, i));
- break;
- case FieldDescriptor::CPPTYPE_UINT64:
- reflectionTo.AddUInt64(&protoTo, field, reflectionFrom.GetRepeatedUInt64(protoFrom, field, i));
- break;
- case FieldDescriptor::CPPTYPE_DOUBLE:
- reflectionTo.AddDouble(&protoTo, field, reflectionFrom.GetRepeatedDouble(protoFrom, field, i));
- break;
- case FieldDescriptor::CPPTYPE_FLOAT:
- reflectionTo.AddFloat(&protoTo, field, reflectionFrom.GetRepeatedFloat(protoFrom, field, i));
- break;
- case FieldDescriptor::CPPTYPE_BOOL:
- reflectionTo.AddBool(&protoTo, field, reflectionFrom.GetRepeatedBool(protoFrom, field, i));
- break;
- case FieldDescriptor::CPPTYPE_ENUM:
- reflectionTo.AddEnum(&protoTo, field, reflectionFrom.GetRepeatedEnum(protoFrom, field, i));
- break;
- case FieldDescriptor::CPPTYPE_STRING:
- reflectionTo.AddString(&protoTo, field, reflectionFrom.GetRepeatedString(protoFrom, field, i));
- break;
- case FieldDescriptor::CPPTYPE_MESSAGE:
- reflectionTo.AddMessage(&protoTo, field)->CopyFrom(reflectionFrom.GetRepeatedMessage(protoFrom, field, i));
- break;
- }
- }
- } else {
- for (int i = 0; i < size; ++i) {
- switch (type) {
- case FieldDescriptor::CPPTYPE_INT32: {
- auto val = reflectionFrom.GetRepeatedInt32(protoFrom, field, i);
- if (val != reflectionTo.GetRepeatedInt32(protoTo, field, i)) {
- reflectionTo.SetRepeatedInt32(&protoTo, field, i, val);
- }
- break;
- }
- case FieldDescriptor::CPPTYPE_INT64: {
- auto val = reflectionFrom.GetRepeatedInt64(protoFrom, field, i);
- if (val != reflectionTo.GetRepeatedInt64(protoTo, field, i)) {
- reflectionTo.SetRepeatedInt64(&protoTo, field, i, val);
- }
- break;
- }
- case FieldDescriptor::CPPTYPE_UINT32: {
- auto val = reflectionFrom.GetRepeatedUInt32(protoFrom, field, i);
- if (val != reflectionTo.GetRepeatedUInt32(protoTo, field, i)) {
- reflectionTo.SetRepeatedUInt32(&protoTo, field, i, val);
- }
- break;
- }
- case FieldDescriptor::CPPTYPE_UINT64: {
- auto val = reflectionFrom.GetRepeatedUInt64(protoFrom, field, i);
- if (val != reflectionTo.GetRepeatedUInt64(protoTo, field, i)) {
- reflectionTo.SetRepeatedUInt64(&protoTo, field, i, val);
- }
- break;
- }
- case FieldDescriptor::CPPTYPE_DOUBLE: {
- auto val = reflectionFrom.GetRepeatedDouble(protoFrom, field, i);
- if (val != reflectionTo.GetRepeatedDouble(protoTo, field, i)) {
- reflectionTo.SetRepeatedDouble(&protoTo, field, i, val);
- }
- break;
- }
- case FieldDescriptor::CPPTYPE_FLOAT: {
- auto val = reflectionFrom.GetRepeatedFloat(protoFrom, field, i);
- if (val != reflectionTo.GetRepeatedFloat(protoTo, field, i)) {
- reflectionTo.SetRepeatedFloat(&protoTo, field, i, val);
- }
- break;
- }
- case FieldDescriptor::CPPTYPE_BOOL: {
- auto val = reflectionFrom.GetRepeatedBool(protoFrom, field, i);
- if (val != reflectionTo.GetRepeatedBool(protoTo, field, i)) {
- reflectionTo.SetRepeatedBool(&protoTo, field, i, val);
- }
- break;
- }
- case FieldDescriptor::CPPTYPE_ENUM: {
- auto val = reflectionFrom.GetRepeatedEnum(protoFrom, field, i);
- if (val->number() != reflectionTo.GetRepeatedEnum(protoTo, field, i)->number()) {
- reflectionTo.SetRepeatedEnum(&protoTo, field, i, val);
- }
- break;
- }
- case FieldDescriptor::CPPTYPE_STRING: {
- auto val = reflectionFrom.GetRepeatedString(protoFrom, field, i);
- if (val != reflectionTo.GetRepeatedString(protoTo, field, i)) {
- reflectionTo.SetRepeatedString(&protoTo, field, i, val);
- }
- break;
- }
- case FieldDescriptor::CPPTYPE_MESSAGE:
- ProtoMerge(*reflectionTo.MutableRepeatedMessage(&protoTo, field, i), reflectionFrom.GetRepeatedMessage(protoFrom, field, i));
- break;
- }
- }
- }
- } else {
- if (reflectionFrom.HasField(protoFrom, field)) {
- FieldDescriptor::CppType type = field->cpp_type();
- switch (type) {
- case FieldDescriptor::CPPTYPE_INT32: {
- ProtoMergeField(reflectionTo, reflectionFrom, protoTo, protoFrom, field, &Reflection::GetInt32, &Reflection::SetInt32);
- break;
- }
- case FieldDescriptor::CPPTYPE_INT64: {
- ProtoMergeField(reflectionTo, reflectionFrom, protoTo, protoFrom, field, &Reflection::GetInt64, &Reflection::SetInt64);
- break;
- }
- case FieldDescriptor::CPPTYPE_UINT32: {
- ProtoMergeField(reflectionTo, reflectionFrom, protoTo, protoFrom, field, &Reflection::GetUInt32, &Reflection::SetUInt32);
- break;
- }
- case FieldDescriptor::CPPTYPE_UINT64: {
- ProtoMergeField(reflectionTo, reflectionFrom, protoTo, protoFrom, field, &Reflection::GetUInt64, &Reflection::SetUInt64);
- break;
- }
- case FieldDescriptor::CPPTYPE_DOUBLE: {
- ProtoMergeField(reflectionTo, reflectionFrom, protoTo, protoFrom, field, &Reflection::GetDouble, &Reflection::SetDouble);
- break;
- }
- case FieldDescriptor::CPPTYPE_FLOAT: {
- ProtoMergeField(reflectionTo, reflectionFrom, protoTo, protoFrom, field, &Reflection::GetFloat, &Reflection::SetFloat);
- break;
- }
- case FieldDescriptor::CPPTYPE_BOOL: {
- ProtoMergeField(reflectionTo, reflectionFrom, protoTo, protoFrom, field, &Reflection::GetBool, &Reflection::SetBool);
- break;
- }
- case FieldDescriptor::CPPTYPE_ENUM: {
- bool has = reflectionTo.HasField(protoTo, field);
- auto val = reflectionFrom.GetEnum(protoFrom, field);
- if (!has || reflectionTo.GetEnum(protoTo, field)->number() != val->number()) {
- reflectionTo.SetEnum(&protoTo, field, val);
- }
- break;
- }
- case FieldDescriptor::CPPTYPE_STRING: {
- bool has = reflectionTo.HasField(protoTo, field);
- auto val = reflectionFrom.GetString(protoFrom, field);
- if (!has || reflectionTo.GetString(protoTo, field) != val) {
- reflectionTo.SetString(&protoTo, field, val);
- }
- break;
- }
- case FieldDescriptor::CPPTYPE_MESSAGE:
- ProtoMerge(*reflectionTo.MutableMessage(&protoTo, field), reflectionFrom.GetMessage(protoFrom, field));
- break;
- }
- }
- }
- }
-}
-
-}
-}
+#include "wb_merge.h"
+
+namespace NKikimr {
+namespace NViewer {
+
+using namespace NNodeWhiteboard;
+using namespace ::google::protobuf;
+
+std::unordered_map<TWhiteboardMergerBase::TMergerKey, TWhiteboardMergerBase::TMergerValue> TWhiteboardMergerBase::FieldMerger;
+
+void TWhiteboardMergerBase::ProtoMaximizeEnumField(
+ const ::google::protobuf::Reflection& reflectionTo,
+ const ::google::protobuf::Reflection& reflectionFrom,
+ ::google::protobuf::Message& protoTo,
+ const ::google::protobuf::Message& protoFrom,
+ const ::google::protobuf::FieldDescriptor* field) {
+ bool has = reflectionTo.HasField(protoTo, field);
+ auto val = reflectionFrom.GetEnum(protoFrom, field);
+ if (!has || reflectionTo.GetEnum(protoTo, field)->number() < val->number()) {
+ reflectionTo.SetEnum(&protoTo, field, val);
+ }
+}
+
+void TWhiteboardMergerBase::ProtoMaximizeBoolField(
+ const ::google::protobuf::Reflection& reflectionTo,
+ const ::google::protobuf::Reflection& reflectionFrom,
+ ::google::protobuf::Message& protoTo,
+ const ::google::protobuf::Message& protoFrom,
+ const ::google::protobuf::FieldDescriptor* field) {
+ bool has = reflectionTo.HasField(protoTo, field);
+ auto val = reflectionFrom.GetBool(protoFrom, field);
+ if (!has || reflectionTo.GetBool(protoTo, field) < val) {
+ reflectionTo.SetBool(&protoTo, field, val);
+ }
+}
+
+void TWhiteboardMergerBase::ProtoMerge(google::protobuf::Message& protoTo, const google::protobuf::Message& protoFrom) {
+ using namespace ::google::protobuf;
+ const Descriptor& descriptor = *protoTo.GetDescriptor();
+ const Reflection& reflectionTo = *protoTo.GetReflection();
+ const Reflection& reflectionFrom = *protoFrom.GetReflection();
+ int fieldCount = descriptor.field_count();
+ for (int index = 0; index < fieldCount; ++index) {
+ const FieldDescriptor* field = descriptor.field(index);
+ auto it = FieldMerger.find(field);
+ if (it != FieldMerger.end()) {
+ it->second(reflectionTo, reflectionFrom, protoTo, protoFrom, field);
+ continue;
+ }
+ if (field->is_repeated()) {
+ FieldDescriptor::CppType type = field->cpp_type();
+ int size = reflectionFrom.FieldSize(protoFrom, field);
+ if (size != 0 && reflectionTo.FieldSize(protoTo, field) != size) {
+ reflectionTo.ClearField(&protoTo, field);
+ for (int i = 0; i < size; ++i) {
+ switch (type) {
+ case FieldDescriptor::CPPTYPE_INT32:
+ reflectionTo.AddInt32(&protoTo, field, reflectionFrom.GetRepeatedInt32(protoFrom, field, i));
+ break;
+ case FieldDescriptor::CPPTYPE_INT64:
+ reflectionTo.AddInt64(&protoTo, field, reflectionFrom.GetRepeatedInt64(protoFrom, field, i));
+ break;
+ case FieldDescriptor::CPPTYPE_UINT32:
+ reflectionTo.AddUInt32(&protoTo, field, reflectionFrom.GetRepeatedUInt32(protoFrom, field, i));
+ break;
+ case FieldDescriptor::CPPTYPE_UINT64:
+ reflectionTo.AddUInt64(&protoTo, field, reflectionFrom.GetRepeatedUInt64(protoFrom, field, i));
+ break;
+ case FieldDescriptor::CPPTYPE_DOUBLE:
+ reflectionTo.AddDouble(&protoTo, field, reflectionFrom.GetRepeatedDouble(protoFrom, field, i));
+ break;
+ case FieldDescriptor::CPPTYPE_FLOAT:
+ reflectionTo.AddFloat(&protoTo, field, reflectionFrom.GetRepeatedFloat(protoFrom, field, i));
+ break;
+ case FieldDescriptor::CPPTYPE_BOOL:
+ reflectionTo.AddBool(&protoTo, field, reflectionFrom.GetRepeatedBool(protoFrom, field, i));
+ break;
+ case FieldDescriptor::CPPTYPE_ENUM:
+ reflectionTo.AddEnum(&protoTo, field, reflectionFrom.GetRepeatedEnum(protoFrom, field, i));
+ break;
+ case FieldDescriptor::CPPTYPE_STRING:
+ reflectionTo.AddString(&protoTo, field, reflectionFrom.GetRepeatedString(protoFrom, field, i));
+ break;
+ case FieldDescriptor::CPPTYPE_MESSAGE:
+ reflectionTo.AddMessage(&protoTo, field)->CopyFrom(reflectionFrom.GetRepeatedMessage(protoFrom, field, i));
+ break;
+ }
+ }
+ } else {
+ for (int i = 0; i < size; ++i) {
+ switch (type) {
+ case FieldDescriptor::CPPTYPE_INT32: {
+ auto val = reflectionFrom.GetRepeatedInt32(protoFrom, field, i);
+ if (val != reflectionTo.GetRepeatedInt32(protoTo, field, i)) {
+ reflectionTo.SetRepeatedInt32(&protoTo, field, i, val);
+ }
+ break;
+ }
+ case FieldDescriptor::CPPTYPE_INT64: {
+ auto val = reflectionFrom.GetRepeatedInt64(protoFrom, field, i);
+ if (val != reflectionTo.GetRepeatedInt64(protoTo, field, i)) {
+ reflectionTo.SetRepeatedInt64(&protoTo, field, i, val);
+ }
+ break;
+ }
+ case FieldDescriptor::CPPTYPE_UINT32: {
+ auto val = reflectionFrom.GetRepeatedUInt32(protoFrom, field, i);
+ if (val != reflectionTo.GetRepeatedUInt32(protoTo, field, i)) {
+ reflectionTo.SetRepeatedUInt32(&protoTo, field, i, val);
+ }
+ break;
+ }
+ case FieldDescriptor::CPPTYPE_UINT64: {
+ auto val = reflectionFrom.GetRepeatedUInt64(protoFrom, field, i);
+ if (val != reflectionTo.GetRepeatedUInt64(protoTo, field, i)) {
+ reflectionTo.SetRepeatedUInt64(&protoTo, field, i, val);
+ }
+ break;
+ }
+ case FieldDescriptor::CPPTYPE_DOUBLE: {
+ auto val = reflectionFrom.GetRepeatedDouble(protoFrom, field, i);
+ if (val != reflectionTo.GetRepeatedDouble(protoTo, field, i)) {
+ reflectionTo.SetRepeatedDouble(&protoTo, field, i, val);
+ }
+ break;
+ }
+ case FieldDescriptor::CPPTYPE_FLOAT: {
+ auto val = reflectionFrom.GetRepeatedFloat(protoFrom, field, i);
+ if (val != reflectionTo.GetRepeatedFloat(protoTo, field, i)) {
+ reflectionTo.SetRepeatedFloat(&protoTo, field, i, val);
+ }
+ break;
+ }
+ case FieldDescriptor::CPPTYPE_BOOL: {
+ auto val = reflectionFrom.GetRepeatedBool(protoFrom, field, i);
+ if (val != reflectionTo.GetRepeatedBool(protoTo, field, i)) {
+ reflectionTo.SetRepeatedBool(&protoTo, field, i, val);
+ }
+ break;
+ }
+ case FieldDescriptor::CPPTYPE_ENUM: {
+ auto val = reflectionFrom.GetRepeatedEnum(protoFrom, field, i);
+ if (val->number() != reflectionTo.GetRepeatedEnum(protoTo, field, i)->number()) {
+ reflectionTo.SetRepeatedEnum(&protoTo, field, i, val);
+ }
+ break;
+ }
+ case FieldDescriptor::CPPTYPE_STRING: {
+ auto val = reflectionFrom.GetRepeatedString(protoFrom, field, i);
+ if (val != reflectionTo.GetRepeatedString(protoTo, field, i)) {
+ reflectionTo.SetRepeatedString(&protoTo, field, i, val);
+ }
+ break;
+ }
+ case FieldDescriptor::CPPTYPE_MESSAGE:
+ ProtoMerge(*reflectionTo.MutableRepeatedMessage(&protoTo, field, i), reflectionFrom.GetRepeatedMessage(protoFrom, field, i));
+ break;
+ }
+ }
+ }
+ } else {
+ if (reflectionFrom.HasField(protoFrom, field)) {
+ FieldDescriptor::CppType type = field->cpp_type();
+ switch (type) {
+ case FieldDescriptor::CPPTYPE_INT32: {
+ ProtoMergeField(reflectionTo, reflectionFrom, protoTo, protoFrom, field, &Reflection::GetInt32, &Reflection::SetInt32);
+ break;
+ }
+ case FieldDescriptor::CPPTYPE_INT64: {
+ ProtoMergeField(reflectionTo, reflectionFrom, protoTo, protoFrom, field, &Reflection::GetInt64, &Reflection::SetInt64);
+ break;
+ }
+ case FieldDescriptor::CPPTYPE_UINT32: {
+ ProtoMergeField(reflectionTo, reflectionFrom, protoTo, protoFrom, field, &Reflection::GetUInt32, &Reflection::SetUInt32);
+ break;
+ }
+ case FieldDescriptor::CPPTYPE_UINT64: {
+ ProtoMergeField(reflectionTo, reflectionFrom, protoTo, protoFrom, field, &Reflection::GetUInt64, &Reflection::SetUInt64);
+ break;
+ }
+ case FieldDescriptor::CPPTYPE_DOUBLE: {
+ ProtoMergeField(reflectionTo, reflectionFrom, protoTo, protoFrom, field, &Reflection::GetDouble, &Reflection::SetDouble);
+ break;
+ }
+ case FieldDescriptor::CPPTYPE_FLOAT: {
+ ProtoMergeField(reflectionTo, reflectionFrom, protoTo, protoFrom, field, &Reflection::GetFloat, &Reflection::SetFloat);
+ break;
+ }
+ case FieldDescriptor::CPPTYPE_BOOL: {
+ ProtoMergeField(reflectionTo, reflectionFrom, protoTo, protoFrom, field, &Reflection::GetBool, &Reflection::SetBool);
+ break;
+ }
+ case FieldDescriptor::CPPTYPE_ENUM: {
+ bool has = reflectionTo.HasField(protoTo, field);
+ auto val = reflectionFrom.GetEnum(protoFrom, field);
+ if (!has || reflectionTo.GetEnum(protoTo, field)->number() != val->number()) {
+ reflectionTo.SetEnum(&protoTo, field, val);
+ }
+ break;
+ }
+ case FieldDescriptor::CPPTYPE_STRING: {
+ bool has = reflectionTo.HasField(protoTo, field);
+ auto val = reflectionFrom.GetString(protoFrom, field);
+ if (!has || reflectionTo.GetString(protoTo, field) != val) {
+ reflectionTo.SetString(&protoTo, field, val);
+ }
+ break;
+ }
+ case FieldDescriptor::CPPTYPE_MESSAGE:
+ ProtoMerge(*reflectionTo.MutableMessage(&protoTo, field), reflectionFrom.GetMessage(protoFrom, field));
+ break;
+ }
+ }
+ }
+ }
+}
+
+}
+}
diff --git a/ydb/core/viewer/wb_merge.h b/ydb/core/viewer/wb_merge.h
index 06cbeac2747..27fd3c8f677 100644
--- a/ydb/core/viewer/wb_merge.h
+++ b/ydb/core/viewer/wb_merge.h
@@ -1,213 +1,213 @@
-#pragma once
-#include <unordered_map>
-#include <util/string/vector.h>
+#pragma once
+#include <unordered_map>
+#include <util/string/vector.h>
#include <ydb/core/node_whiteboard/node_whiteboard.h>
-#include "wb_filter.h"
-#include "wb_group.h"
-
-namespace NKikimr {
-namespace NViewer {
-
-using namespace NNodeWhiteboard;
-using namespace ::google::protobuf;
-
-struct TWhiteboardDefaultInfo {
-};
-
-template <typename ResponseType>
-struct TWhiteboardInfo;
-
-template <typename ResponseType>
+#include "wb_filter.h"
+#include "wb_group.h"
+
+namespace NKikimr {
+namespace NViewer {
+
+using namespace NNodeWhiteboard;
+using namespace ::google::protobuf;
+
+struct TWhiteboardDefaultInfo {
+};
+
+template <typename ResponseType>
+struct TWhiteboardInfo;
+
+template <typename ResponseType>
struct TWhiteboardMergerComparator {
- bool operator ()(const ResponseType& a, const ResponseType& b) const {
- return a.GetChangeTime() < b.GetChangeTime();
- }
-};
-
-class TWhiteboardMergerBase {
-public:
- using TMergerKey = const ::google::protobuf::FieldDescriptor*;
- using TMergerValue = std::function<void(
- const ::google::protobuf::Reflection& reflectionTo,
- const ::google::protobuf::Reflection& reflectionFrom,
- ::google::protobuf::Message& protoTo,
- const ::google::protobuf::Message& protoFrom,
- const ::google::protobuf::FieldDescriptor* field)>;
- static std::unordered_map<TMergerKey, TMergerValue> FieldMerger;
-
- template <typename PropertyType>
- static void ProtoMergeField(
- const ::google::protobuf::Reflection& reflectionTo,
- const ::google::protobuf::Reflection& reflectionFrom,
- ::google::protobuf::Message& protoTo,
- const ::google::protobuf::Message& protoFrom,
- const ::google::protobuf::FieldDescriptor* field,
- PropertyType (::google::protobuf::Reflection::* getter)(const ::google::protobuf::Message&, const ::google::protobuf::FieldDescriptor*) const,
- void (::google::protobuf::Reflection::* setter)(::google::protobuf::Message*, const ::google::protobuf::FieldDescriptor*, PropertyType) const
- ) {
- bool has = reflectionTo.HasField(protoTo, field);
- PropertyType newVal = (reflectionFrom.*getter)(protoFrom, field);
- if (!has) {
- (reflectionTo.*setter)(&protoTo, field, newVal);
- } else {
- PropertyType oldVal = (reflectionTo.*getter)(protoTo, field);
- if (oldVal != newVal) {
- (reflectionTo.*setter)(&protoTo, field, newVal);
- }
- }
- }
-
- static void ProtoMaximizeEnumField(
- const ::google::protobuf::Reflection& reflectionTo,
- const ::google::protobuf::Reflection& reflectionFrom,
- ::google::protobuf::Message& protoTo,
- const ::google::protobuf::Message& protoFrom,
- const ::google::protobuf::FieldDescriptor* field);
-
- static void ProtoMaximizeBoolField(
- const ::google::protobuf::Reflection& reflectionTo,
- const ::google::protobuf::Reflection& reflectionFrom,
- ::google::protobuf::Message& protoTo,
- const ::google::protobuf::Message& protoFrom,
- const ::google::protobuf::FieldDescriptor* field);
-
- static void ProtoMerge(::google::protobuf::Message& protoTo, const ::google::protobuf::Message& protoFrom);
-};
-
-template <typename ResponseType>
-class TWhiteboardMerger : public TWhiteboardMergerBase {
-public:
- using TResponseType = typename TWhiteboardInfo<ResponseType>::TResponseType;
- using TElementType = typename TWhiteboardInfo<ResponseType>::TElementType;
- using TElementKeyType = typename TWhiteboardInfo<ResponseType>::TElementKeyType;
-
- static TString GetFieldString(const Reflection& reflection, const Message& message, const FieldDescriptor* fieldDescriptor) {
- switch (fieldDescriptor->cpp_type()) {
- case FieldDescriptor::CPPTYPE_INT32:
- return ToString(TFieldProtoValueExtractor<i32>(fieldDescriptor).ExtractValue(reflection, message));
- case FieldDescriptor::CPPTYPE_INT64:
- return ToString(TFieldProtoValueExtractor<i64>(fieldDescriptor).ExtractValue(reflection, message));
- case FieldDescriptor::CPPTYPE_UINT32:
- return ToString(TFieldProtoValueExtractor<ui32>(fieldDescriptor).ExtractValue(reflection, message));
- case FieldDescriptor::CPPTYPE_UINT64:
- return ToString(TFieldProtoValueExtractor<ui64>(fieldDescriptor).ExtractValue(reflection, message));
- case FieldDescriptor::CPPTYPE_DOUBLE:
- return ToString(TFieldProtoValueExtractor<double>(fieldDescriptor).ExtractValue(reflection, message));
- case FieldDescriptor::CPPTYPE_FLOAT:
- return ToString(TFieldProtoValueExtractor<float>(fieldDescriptor).ExtractValue(reflection, message));
- case FieldDescriptor::CPPTYPE_BOOL:
- return ToString(TFieldProtoValueExtractor<bool>(fieldDescriptor).ExtractValue(reflection, message));
- case FieldDescriptor::CPPTYPE_ENUM:
- return TFieldProtoValueExtractor<TEnumValue>(fieldDescriptor).ExtractValue(reflection, message).Name;
- case FieldDescriptor::CPPTYPE_STRING:
- return TFieldProtoValueExtractor<TString>(fieldDescriptor).ExtractValue(reflection, message);
- case FieldDescriptor::CPPTYPE_MESSAGE: {
- const Message& subMessage = reflection.GetMessage(message, fieldDescriptor);
- const Reflection& subReflection = *subMessage.GetReflection();
- TVector<const FieldDescriptor*> subFields;
- subReflection.ListFields(subMessage, &subFields);
- return "{" + GetDynamicKey(subReflection, subMessage, subFields) + "}";
- }
- default:
- return "undefined";
- }
- }
-
- static TString GetDynamicKey(const Reflection& reflection, const Message& message, const TVector<const FieldDescriptor*>& fields) {
- TString key;
- for (const FieldDescriptor* field : fields) {
- if (!key.empty()) {
- key += '-';
- }
- key += GetFieldString(reflection, message, field);
- }
- return key;
- }
-
- struct TDynamicMergeKey {
- TVector<const FieldDescriptor*> MergeFields;
- using KeyType = TString;
-
- TDynamicMergeKey(const TString& fields)
- : MergeFields(TWhiteboardGrouper<TResponseType>::GetProtoFields(fields))
- {
- }
-
- TString GetKey(TElementType& info) const {
- return GetDynamicKey(*info.GetReflection(), info, MergeFields);
- }
- };
-
- template <typename ElementKeyType>
- struct TStaticMergeKey {
- using KeyType = ElementKeyType;
-
- ElementKeyType GetKey(TElementType& info) const {
- return TWhiteboardInfo<ResponseType>::GetElementKey(info);
- }
- };
-
- template <typename MergeKey>
- static THolder<TResponseType> MergeResponsesBase(TMap<ui32, THolder<TResponseType>>& responses, const MergeKey& mergeKey) {
- std::unordered_map<typename MergeKey::KeyType, TElementType*> mergedData;
- ui64 minResponseTime = 0;
- ui32 maxResponseDuration = 0;
- TWhiteboardMergerComparator<TElementType> comparator;
- for (auto it = responses.begin(); it != responses.end(); ++it) {
- if (it->second != nullptr) {
- auto* stateInfo = TWhiteboardInfo<ResponseType>::GetElementsField(it->second.Get());
- for (TElementType& info : *stateInfo) {
- if (!info.HasNodeId()) {
- info.SetNodeId(it->first);
- }
- auto key = mergeKey.GetKey(info);
- auto inserted = mergedData.emplace(key, &info);
- if (!inserted.second) {
- if (comparator(*inserted.first->second, info)) {
- inserted.first->second = &info;
- }
- }
- }
- if (minResponseTime == 0 || it->second->Record.GetResponseTime() < minResponseTime) {
- minResponseTime = it->second->Record.GetResponseTime();
- }
- if (maxResponseDuration == 0 || it->second->Record.GetResponseDuration() > maxResponseDuration) {
- maxResponseDuration = it->second->Record.GetResponseDuration();
- }
- }
- }
-
+ bool operator ()(const ResponseType& a, const ResponseType& b) const {
+ return a.GetChangeTime() < b.GetChangeTime();
+ }
+};
+
+class TWhiteboardMergerBase {
+public:
+ using TMergerKey = const ::google::protobuf::FieldDescriptor*;
+ using TMergerValue = std::function<void(
+ const ::google::protobuf::Reflection& reflectionTo,
+ const ::google::protobuf::Reflection& reflectionFrom,
+ ::google::protobuf::Message& protoTo,
+ const ::google::protobuf::Message& protoFrom,
+ const ::google::protobuf::FieldDescriptor* field)>;
+ static std::unordered_map<TMergerKey, TMergerValue> FieldMerger;
+
+ template <typename PropertyType>
+ static void ProtoMergeField(
+ const ::google::protobuf::Reflection& reflectionTo,
+ const ::google::protobuf::Reflection& reflectionFrom,
+ ::google::protobuf::Message& protoTo,
+ const ::google::protobuf::Message& protoFrom,
+ const ::google::protobuf::FieldDescriptor* field,
+ PropertyType (::google::protobuf::Reflection::* getter)(const ::google::protobuf::Message&, const ::google::protobuf::FieldDescriptor*) const,
+ void (::google::protobuf::Reflection::* setter)(::google::protobuf::Message*, const ::google::protobuf::FieldDescriptor*, PropertyType) const
+ ) {
+ bool has = reflectionTo.HasField(protoTo, field);
+ PropertyType newVal = (reflectionFrom.*getter)(protoFrom, field);
+ if (!has) {
+ (reflectionTo.*setter)(&protoTo, field, newVal);
+ } else {
+ PropertyType oldVal = (reflectionTo.*getter)(protoTo, field);
+ if (oldVal != newVal) {
+ (reflectionTo.*setter)(&protoTo, field, newVal);
+ }
+ }
+ }
+
+ static void ProtoMaximizeEnumField(
+ const ::google::protobuf::Reflection& reflectionTo,
+ const ::google::protobuf::Reflection& reflectionFrom,
+ ::google::protobuf::Message& protoTo,
+ const ::google::protobuf::Message& protoFrom,
+ const ::google::protobuf::FieldDescriptor* field);
+
+ static void ProtoMaximizeBoolField(
+ const ::google::protobuf::Reflection& reflectionTo,
+ const ::google::protobuf::Reflection& reflectionFrom,
+ ::google::protobuf::Message& protoTo,
+ const ::google::protobuf::Message& protoFrom,
+ const ::google::protobuf::FieldDescriptor* field);
+
+ static void ProtoMerge(::google::protobuf::Message& protoTo, const ::google::protobuf::Message& protoFrom);
+};
+
+template <typename ResponseType>
+class TWhiteboardMerger : public TWhiteboardMergerBase {
+public:
+ using TResponseType = typename TWhiteboardInfo<ResponseType>::TResponseType;
+ using TElementType = typename TWhiteboardInfo<ResponseType>::TElementType;
+ using TElementKeyType = typename TWhiteboardInfo<ResponseType>::TElementKeyType;
+
+ static TString GetFieldString(const Reflection& reflection, const Message& message, const FieldDescriptor* fieldDescriptor) {
+ switch (fieldDescriptor->cpp_type()) {
+ case FieldDescriptor::CPPTYPE_INT32:
+ return ToString(TFieldProtoValueExtractor<i32>(fieldDescriptor).ExtractValue(reflection, message));
+ case FieldDescriptor::CPPTYPE_INT64:
+ return ToString(TFieldProtoValueExtractor<i64>(fieldDescriptor).ExtractValue(reflection, message));
+ case FieldDescriptor::CPPTYPE_UINT32:
+ return ToString(TFieldProtoValueExtractor<ui32>(fieldDescriptor).ExtractValue(reflection, message));
+ case FieldDescriptor::CPPTYPE_UINT64:
+ return ToString(TFieldProtoValueExtractor<ui64>(fieldDescriptor).ExtractValue(reflection, message));
+ case FieldDescriptor::CPPTYPE_DOUBLE:
+ return ToString(TFieldProtoValueExtractor<double>(fieldDescriptor).ExtractValue(reflection, message));
+ case FieldDescriptor::CPPTYPE_FLOAT:
+ return ToString(TFieldProtoValueExtractor<float>(fieldDescriptor).ExtractValue(reflection, message));
+ case FieldDescriptor::CPPTYPE_BOOL:
+ return ToString(TFieldProtoValueExtractor<bool>(fieldDescriptor).ExtractValue(reflection, message));
+ case FieldDescriptor::CPPTYPE_ENUM:
+ return TFieldProtoValueExtractor<TEnumValue>(fieldDescriptor).ExtractValue(reflection, message).Name;
+ case FieldDescriptor::CPPTYPE_STRING:
+ return TFieldProtoValueExtractor<TString>(fieldDescriptor).ExtractValue(reflection, message);
+ case FieldDescriptor::CPPTYPE_MESSAGE: {
+ const Message& subMessage = reflection.GetMessage(message, fieldDescriptor);
+ const Reflection& subReflection = *subMessage.GetReflection();
+ TVector<const FieldDescriptor*> subFields;
+ subReflection.ListFields(subMessage, &subFields);
+ return "{" + GetDynamicKey(subReflection, subMessage, subFields) + "}";
+ }
+ default:
+ return "undefined";
+ }
+ }
+
+ static TString GetDynamicKey(const Reflection& reflection, const Message& message, const TVector<const FieldDescriptor*>& fields) {
+ TString key;
+ for (const FieldDescriptor* field : fields) {
+ if (!key.empty()) {
+ key += '-';
+ }
+ key += GetFieldString(reflection, message, field);
+ }
+ return key;
+ }
+
+ struct TDynamicMergeKey {
+ TVector<const FieldDescriptor*> MergeFields;
+ using KeyType = TString;
+
+ TDynamicMergeKey(const TString& fields)
+ : MergeFields(TWhiteboardGrouper<TResponseType>::GetProtoFields(fields))
+ {
+ }
+
+ TString GetKey(TElementType& info) const {
+ return GetDynamicKey(*info.GetReflection(), info, MergeFields);
+ }
+ };
+
+ template <typename ElementKeyType>
+ struct TStaticMergeKey {
+ using KeyType = ElementKeyType;
+
+ ElementKeyType GetKey(TElementType& info) const {
+ return TWhiteboardInfo<ResponseType>::GetElementKey(info);
+ }
+ };
+
+ template <typename MergeKey>
+ static THolder<TResponseType> MergeResponsesBase(TMap<ui32, THolder<TResponseType>>& responses, const MergeKey& mergeKey) {
+ std::unordered_map<typename MergeKey::KeyType, TElementType*> mergedData;
+ ui64 minResponseTime = 0;
+ ui32 maxResponseDuration = 0;
+ TWhiteboardMergerComparator<TElementType> comparator;
+ for (auto it = responses.begin(); it != responses.end(); ++it) {
+ if (it->second != nullptr) {
+ auto* stateInfo = TWhiteboardInfo<ResponseType>::GetElementsField(it->second.Get());
+ for (TElementType& info : *stateInfo) {
+ if (!info.HasNodeId()) {
+ info.SetNodeId(it->first);
+ }
+ auto key = mergeKey.GetKey(info);
+ auto inserted = mergedData.emplace(key, &info);
+ if (!inserted.second) {
+ if (comparator(*inserted.first->second, info)) {
+ inserted.first->second = &info;
+ }
+ }
+ }
+ if (minResponseTime == 0 || it->second->Record.GetResponseTime() < minResponseTime) {
+ minResponseTime = it->second->Record.GetResponseTime();
+ }
+ if (maxResponseDuration == 0 || it->second->Record.GetResponseDuration() > maxResponseDuration) {
+ maxResponseDuration = it->second->Record.GetResponseDuration();
+ }
+ }
+ }
+
THolder<TResponseType> result = MakeHolder<TResponseType>();
- auto* field = TWhiteboardInfo<ResponseType>::GetElementsField(result.Get());
- field->Reserve(mergedData.size());
- for (auto it = mergedData.begin(); it != mergedData.end(); ++it) {
- auto* element = field->Add();
- element->Swap(it->second);
- }
- if (minResponseTime) {
- result->Record.SetResponseTime(minResponseTime);
- }
- if (maxResponseDuration) {
- result->Record.SetResponseDuration(maxResponseDuration);
- }
- return result;
- }
-
- static THolder<TResponseType> MergeResponsesElementKey(TMap<ui32, THolder<TResponseType>>& responses) {
- TStaticMergeKey<typename TWhiteboardInfo<ResponseType>::TElementKeyType> mergeKey;
- return MergeResponsesBase(responses, mergeKey);
- }
-
- static THolder<TResponseType> MergeResponses(TMap<ui32, THolder<TResponseType>>& responses, const TString& fields) {
- TDynamicMergeKey mergeKey(fields);
- return MergeResponsesBase(responses, mergeKey);
- }
-};
-
-template <typename ResponseType>
-THolder<ResponseType> MergeWhiteboardResponses(TMap<ui32, THolder<ResponseType>>& responses, const TString& fields = TWhiteboardInfo<ResponseType>::GetDefaultMergeField()) {
- return TWhiteboardInfo<ResponseType>::MergeResponses(responses, fields);
-}
-
-}
-}
+ auto* field = TWhiteboardInfo<ResponseType>::GetElementsField(result.Get());
+ field->Reserve(mergedData.size());
+ for (auto it = mergedData.begin(); it != mergedData.end(); ++it) {
+ auto* element = field->Add();
+ element->Swap(it->second);
+ }
+ if (minResponseTime) {
+ result->Record.SetResponseTime(minResponseTime);
+ }
+ if (maxResponseDuration) {
+ result->Record.SetResponseDuration(maxResponseDuration);
+ }
+ return result;
+ }
+
+ static THolder<TResponseType> MergeResponsesElementKey(TMap<ui32, THolder<TResponseType>>& responses) {
+ TStaticMergeKey<typename TWhiteboardInfo<ResponseType>::TElementKeyType> mergeKey;
+ return MergeResponsesBase(responses, mergeKey);
+ }
+
+ static THolder<TResponseType> MergeResponses(TMap<ui32, THolder<TResponseType>>& responses, const TString& fields) {
+ TDynamicMergeKey mergeKey(fields);
+ return MergeResponsesBase(responses, mergeKey);
+ }
+};
+
+template <typename ResponseType>
+THolder<ResponseType> MergeWhiteboardResponses(TMap<ui32, THolder<ResponseType>>& responses, const TString& fields = TWhiteboardInfo<ResponseType>::GetDefaultMergeField()) {
+ return TWhiteboardInfo<ResponseType>::MergeResponses(responses, fields);
+}
+
+}
+}
diff --git a/ydb/core/viewer/ya.make b/ydb/core/viewer/ya.make
index d28dfa3ea50..214e3b67269 100644
--- a/ydb/core/viewer/ya.make
+++ b/ydb/core/viewer/ya.make
@@ -2,65 +2,65 @@ RECURSE_FOR_TESTS(
ut
)
-LIBRARY()
-
-OWNER(
- xenoxeno
+LIBRARY()
+
+OWNER(
+ xenoxeno
g:kikimr
-)
-
-SRCS(
- browse_db.h
- browse_pq.h
- browse.h
- counters_hosts.h
- json_browse.h
- json_bscontrollerinfo.h
- json_bsgroupinfo.h
- json_cluster.h
- json_compute.h
- json_config.h
- json_content.h
- json_counters.h
- json_describe.h
- json_healthcheck.h
- json_hiveinfo.h
+)
+
+SRCS(
+ browse_db.h
+ browse_pq.h
+ browse.h
+ counters_hosts.h
+ json_browse.h
+ json_bscontrollerinfo.h
+ json_bsgroupinfo.h
+ json_cluster.h
+ json_compute.h
+ json_config.h
+ json_content.h
+ json_counters.h
+ json_describe.h
+ json_healthcheck.h
+ json_hiveinfo.h
json_hotkeys.h
- json_labeledcounters.h
- json_metainfo.h
- json_netinfo.h
- json_nodeinfo.h
- json_nodelist.h
- json_nodes.h
- json_pdiskinfo.h
- json_query.h
- json_storage.h
- json_sysinfo.h
- json_tabletcounters.h
- json_tabletinfo.h
- json_tenants.h
- json_tenantinfo.h
+ json_labeledcounters.h
+ json_metainfo.h
+ json_netinfo.h
+ json_nodeinfo.h
+ json_nodelist.h
+ json_nodes.h
+ json_pdiskinfo.h
+ json_query.h
+ json_storage.h
+ json_sysinfo.h
+ json_tabletcounters.h
+ json_tabletinfo.h
+ json_tenants.h
+ json_tenantinfo.h
json_topicinfo.h
json_pqconsumerinfo.h
- json_vdiskinfo.h
- json_wb_req.h
- json_whoami.h
- viewer.cpp
- viewer.h
- wb_aggregate.cpp
- wb_aggregate.h
- wb_filter.cpp
- wb_filter.h
- wb_group.h
- wb_merge.cpp
- wb_merge.h
-)
-
-RESOURCE(
- monitoring/index.html monitoring/index.html
+ json_vdiskinfo.h
+ json_wb_req.h
+ json_whoami.h
+ viewer.cpp
+ viewer.h
+ wb_aggregate.cpp
+ wb_aggregate.h
+ wb_filter.cpp
+ wb_filter.h
+ wb_group.h
+ wb_merge.cpp
+ wb_merge.h
+)
+
+RESOURCE(
+ monitoring/index.html monitoring/index.html
monitoring/resources/assets/fonts/codicon.59002d8c.ttf monitoring/resources/assets/fonts/codicon.59002d8c.ttf
- monitoring/resources/css/main.css monitoring/resources/css/main.css
- monitoring/resources/css/vendors.css monitoring/resources/css/vendors.css
+ monitoring/resources/css/main.css monitoring/resources/css/main.css
+ monitoring/resources/css/vendors.css monitoring/resources/css/vendors.css
monitoring/resources/editor.worker.js monitoring/resources/editor.worker.js
monitoring/resources/favicon.png monitoring/resources/favicon.png
monitoring/resources/js/10.js monitoring/resources/js/10.js
@@ -75,111 +75,111 @@ RESOURCE(
monitoring/resources/js/html2canvas.js monitoring/resources/js/html2canvas.js
monitoring/resources/js/html2canvas.js.LICENSE.txt monitoring/resources/js/html2canvas.js.LICENSE.txt
monitoring/resources/js/html2canvas.js.map monitoring/resources/js/html2canvas.js.map
- monitoring/resources/js/main.js monitoring/resources/js/main.js
+ monitoring/resources/js/main.js monitoring/resources/js/main.js
monitoring/resources/js/main.js.LICENSE.txt monitoring/resources/js/main.js.LICENSE.txt
monitoring/resources/js/main.js.map monitoring/resources/js/main.js.map
- monitoring/resources/js/runtime.js monitoring/resources/js/runtime.js
+ monitoring/resources/js/runtime.js monitoring/resources/js/runtime.js
monitoring/resources/js/sanitize-html.js monitoring/resources/js/sanitize-html.js
monitoring/resources/js/sanitize-html.js.LICENSE.txt monitoring/resources/js/sanitize-html.js.LICENSE.txt
monitoring/resources/js/sanitize-html.js.map monitoring/resources/js/sanitize-html.js.map
- monitoring/resources/js/vendors.js monitoring/resources/js/vendors.js
+ monitoring/resources/js/vendors.js monitoring/resources/js/vendors.js
monitoring/resources/js/vendors.js.LICENSE.txt monitoring/resources/js/vendors.js.LICENSE.txt
monitoring/resources/js/vendors.js.map monitoring/resources/js/vendors.js.map
monitoring/resources/manifest.json monitoring/resources/manifest.json
- content/index.html viewer/index.html
- content/viewer.js viewer/viewer.js
- content/jstree.min.js viewer/jstree.min.js
- content/style.min.css viewer/style.min.css
- content/throbber.gif viewer/throbber.gif
- content/32px.png viewer/32px.png
- content/40px.png viewer/40px.png
- content/v2/cpu viewer/v2/cpu
- content/v2/cpu_view.js viewer/v2/cpu_view.js
- content/v2/disk_cell.js viewer/v2/disk_cell.js
- content/v2/disk_map.js viewer/v2/disk_map.js
- content/v2/index.html viewer/v2/index.html
- content/v2/man-green.png viewer/v2/man-green.png
- content/v2/man-orange.png viewer/v2/man-orange.png
- content/v2/man-red.png viewer/v2/man-red.png
- content/v2/man-yellow.png viewer/v2/man-yellow.png
- content/v2/net_view.js viewer/v2/net_view.js
- content/v2/network viewer/v2/network
- content/v2/node_group.js viewer/v2/node_group.js
- content/v2/node.js viewer/v2/node.js
- content/v2/node_map.js viewer/v2/node_map.js
- content/v2/nodes viewer/v2/nodes
- content/v2/node_view.js viewer/v2/node_view.js
- content/v2/overview viewer/v2/overview
- content/v2/overview.js viewer/v2/overview.js
- content/v2/pdisk.js viewer/v2/pdisk.js
- content/v2/pool_block.js viewer/v2/pool_block.js
- content/v2/pool_map.js viewer/v2/pool_map.js
- content/v2/runner.html viewer/v2/runner.html
- content/v2/stats.js viewer/v2/stats.js
- content/v2/storage viewer/v2/storage
- content/v2/storage_group.js viewer/v2/storage_group.js
- content/v2/storage.js viewer/v2/storage.js
- content/v2/storage_view.js viewer/v2/storage_view.js
- content/v2/tablet_cell.js viewer/v2/tablet_cell.js
- content/v2/tablet_map.js viewer/v2/tablet_map.js
- content/v2/tenant.js viewer/v2/tenant.js
- content/v2/tenants viewer/v2/tenants
- content/v2/tenant_view.js viewer/v2/tenant_view.js
- content/v2/throbber.gif viewer/v2/throbber.gif
- content/v2/util.js viewer/v2/util.js
- content/v2/vdisk.js viewer/v2/vdisk.js
- content/v2/viewer.css viewer/v2/viewer.css
- content/v2/viewer.js viewer/v2/viewer.js
- content/api/css/print.css viewer/api/css/print.css
- content/api/css/reset.css viewer/api/css/reset.css
- content/api/css/screen.css viewer/api/css/screen.css
- content/api/css/style.css viewer/api/css/style.css
- content/api/css/typography.css viewer/api/css/typography.css
- content/api/fonts/DroidSans-Bold.ttf viewer/api/fonts/DroidSans-Bold.ttf
- content/api/fonts/DroidSans.ttf viewer/api/fonts/DroidSans.ttf
- content/api/images/collapse.gif viewer/api/images/collapse.gif
- content/api/images/expand.gif viewer/api/images/expand.gif
- content/api/images/explorer_icons.png viewer/api/images/explorer_icons.png
- content/api/images/favicon-16x16.png viewer/api/images/favicon-16x16.png
- content/api/images/favicon-32x32.png viewer/api/images/favicon-32x32.png
- content/api/images/favicon.ico viewer/api/images/favicon.ico
- content/api/images/logo_small.png viewer/api/images/logo_small.png
- content/api/images/throbber.gif viewer/api/images/throbber.gif
- content/api/index.html viewer/api/index.html
- content/api/lang/ca.js viewer/api/lang/ca.js
- content/api/lang/en.js viewer/api/lang/en.js
- content/api/lang/es.js viewer/api/lang/es.js
- content/api/lang/fr.js viewer/api/lang/fr.js
- content/api/lang/geo.js viewer/api/lang/geo.js
- content/api/lang/it.js viewer/api/lang/it.js
- content/api/lang/ja.js viewer/api/lang/ja.js
- content/api/lang/ko-kr.js viewer/api/lang/ko-kr.js
- content/api/lang/pl.js viewer/api/lang/pl.js
- content/api/lang/pt.js viewer/api/lang/pt.js
- content/api/lang/ru.js viewer/api/lang/ru.js
- content/api/lang/tr.js viewer/api/lang/tr.js
- content/api/lang/translator.js viewer/api/lang/translator.js
- content/api/lang/zh-cn.js viewer/api/lang/zh-cn.js
- content/api/lib/backbone-min.js viewer/api/lib/backbone-min.js
- content/api/lib/es5-shim.js viewer/api/lib/es5-shim.js
- content/api/lib/handlebars-4.0.5.js viewer/api/lib/handlebars-4.0.5.js
- content/api/lib/highlight.9.1.0.pack.js viewer/api/lib/highlight.9.1.0.pack.js
- content/api/lib/highlight.9.1.0.pack_extended.js viewer/api/lib/highlight.9.1.0.pack_extended.js
- content/api/lib/jquery-1.8.0.min.js viewer/api/lib/jquery-1.8.0.min.js
- content/api/lib/jquery.ba-bbq.min.js viewer/api/lib/jquery.ba-bbq.min.js
- content/api/lib/jquery.slideto.min.js viewer/api/lib/jquery.slideto.min.js
- content/api/lib/jquery.wiggle.min.js viewer/api/lib/jquery.wiggle.min.js
- content/api/lib/js-yaml.min.js viewer/api/lib/js-yaml.min.js
- content/api/lib/jsoneditor.min.js viewer/api/lib/jsoneditor.min.js
- content/api/lib/lodash.min.js viewer/api/lib/lodash.min.js
- content/api/lib/marked.js viewer/api/lib/marked.js
- content/api/lib/object-assign-pollyfill.js viewer/api/lib/object-assign-pollyfill.js
- content/api/lib/sanitize-html.min.js viewer/api/lib/sanitize-html.min.js
- content/api/lib/swagger-oauth.js viewer/api/lib/swagger-oauth.js
- content/api/swagger-ui.min.js viewer/api/swagger-ui.min.js
-)
-
-PEERDIR(
+ content/index.html viewer/index.html
+ content/viewer.js viewer/viewer.js
+ content/jstree.min.js viewer/jstree.min.js
+ content/style.min.css viewer/style.min.css
+ content/throbber.gif viewer/throbber.gif
+ content/32px.png viewer/32px.png
+ content/40px.png viewer/40px.png
+ content/v2/cpu viewer/v2/cpu
+ content/v2/cpu_view.js viewer/v2/cpu_view.js
+ content/v2/disk_cell.js viewer/v2/disk_cell.js
+ content/v2/disk_map.js viewer/v2/disk_map.js
+ content/v2/index.html viewer/v2/index.html
+ content/v2/man-green.png viewer/v2/man-green.png
+ content/v2/man-orange.png viewer/v2/man-orange.png
+ content/v2/man-red.png viewer/v2/man-red.png
+ content/v2/man-yellow.png viewer/v2/man-yellow.png
+ content/v2/net_view.js viewer/v2/net_view.js
+ content/v2/network viewer/v2/network
+ content/v2/node_group.js viewer/v2/node_group.js
+ content/v2/node.js viewer/v2/node.js
+ content/v2/node_map.js viewer/v2/node_map.js
+ content/v2/nodes viewer/v2/nodes
+ content/v2/node_view.js viewer/v2/node_view.js
+ content/v2/overview viewer/v2/overview
+ content/v2/overview.js viewer/v2/overview.js
+ content/v2/pdisk.js viewer/v2/pdisk.js
+ content/v2/pool_block.js viewer/v2/pool_block.js
+ content/v2/pool_map.js viewer/v2/pool_map.js
+ content/v2/runner.html viewer/v2/runner.html
+ content/v2/stats.js viewer/v2/stats.js
+ content/v2/storage viewer/v2/storage
+ content/v2/storage_group.js viewer/v2/storage_group.js
+ content/v2/storage.js viewer/v2/storage.js
+ content/v2/storage_view.js viewer/v2/storage_view.js
+ content/v2/tablet_cell.js viewer/v2/tablet_cell.js
+ content/v2/tablet_map.js viewer/v2/tablet_map.js
+ content/v2/tenant.js viewer/v2/tenant.js
+ content/v2/tenants viewer/v2/tenants
+ content/v2/tenant_view.js viewer/v2/tenant_view.js
+ content/v2/throbber.gif viewer/v2/throbber.gif
+ content/v2/util.js viewer/v2/util.js
+ content/v2/vdisk.js viewer/v2/vdisk.js
+ content/v2/viewer.css viewer/v2/viewer.css
+ content/v2/viewer.js viewer/v2/viewer.js
+ content/api/css/print.css viewer/api/css/print.css
+ content/api/css/reset.css viewer/api/css/reset.css
+ content/api/css/screen.css viewer/api/css/screen.css
+ content/api/css/style.css viewer/api/css/style.css
+ content/api/css/typography.css viewer/api/css/typography.css
+ content/api/fonts/DroidSans-Bold.ttf viewer/api/fonts/DroidSans-Bold.ttf
+ content/api/fonts/DroidSans.ttf viewer/api/fonts/DroidSans.ttf
+ content/api/images/collapse.gif viewer/api/images/collapse.gif
+ content/api/images/expand.gif viewer/api/images/expand.gif
+ content/api/images/explorer_icons.png viewer/api/images/explorer_icons.png
+ content/api/images/favicon-16x16.png viewer/api/images/favicon-16x16.png
+ content/api/images/favicon-32x32.png viewer/api/images/favicon-32x32.png
+ content/api/images/favicon.ico viewer/api/images/favicon.ico
+ content/api/images/logo_small.png viewer/api/images/logo_small.png
+ content/api/images/throbber.gif viewer/api/images/throbber.gif
+ content/api/index.html viewer/api/index.html
+ content/api/lang/ca.js viewer/api/lang/ca.js
+ content/api/lang/en.js viewer/api/lang/en.js
+ content/api/lang/es.js viewer/api/lang/es.js
+ content/api/lang/fr.js viewer/api/lang/fr.js
+ content/api/lang/geo.js viewer/api/lang/geo.js
+ content/api/lang/it.js viewer/api/lang/it.js
+ content/api/lang/ja.js viewer/api/lang/ja.js
+ content/api/lang/ko-kr.js viewer/api/lang/ko-kr.js
+ content/api/lang/pl.js viewer/api/lang/pl.js
+ content/api/lang/pt.js viewer/api/lang/pt.js
+ content/api/lang/ru.js viewer/api/lang/ru.js
+ content/api/lang/tr.js viewer/api/lang/tr.js
+ content/api/lang/translator.js viewer/api/lang/translator.js
+ content/api/lang/zh-cn.js viewer/api/lang/zh-cn.js
+ content/api/lib/backbone-min.js viewer/api/lib/backbone-min.js
+ content/api/lib/es5-shim.js viewer/api/lib/es5-shim.js
+ content/api/lib/handlebars-4.0.5.js viewer/api/lib/handlebars-4.0.5.js
+ content/api/lib/highlight.9.1.0.pack.js viewer/api/lib/highlight.9.1.0.pack.js
+ content/api/lib/highlight.9.1.0.pack_extended.js viewer/api/lib/highlight.9.1.0.pack_extended.js
+ content/api/lib/jquery-1.8.0.min.js viewer/api/lib/jquery-1.8.0.min.js
+ content/api/lib/jquery.ba-bbq.min.js viewer/api/lib/jquery.ba-bbq.min.js
+ content/api/lib/jquery.slideto.min.js viewer/api/lib/jquery.slideto.min.js
+ content/api/lib/jquery.wiggle.min.js viewer/api/lib/jquery.wiggle.min.js
+ content/api/lib/js-yaml.min.js viewer/api/lib/js-yaml.min.js
+ content/api/lib/jsoneditor.min.js viewer/api/lib/jsoneditor.min.js
+ content/api/lib/lodash.min.js viewer/api/lib/lodash.min.js
+ content/api/lib/marked.js viewer/api/lib/marked.js
+ content/api/lib/object-assign-pollyfill.js viewer/api/lib/object-assign-pollyfill.js
+ content/api/lib/sanitize-html.min.js viewer/api/lib/sanitize-html.min.js
+ content/api/lib/swagger-oauth.js viewer/api/lib/swagger-oauth.js
+ content/api/swagger-ui.min.js viewer/api/swagger-ui.min.js
+)
+
+PEERDIR(
library/cpp/actors/core
library/cpp/archive
library/cpp/mime/types
@@ -197,8 +197,8 @@ PEERDIR(
ydb/library/persqueue/topic_parser
ydb/public/api/protos
ydb/public/lib/deprecated/kicli
-)
-
+)
+
YQL_LAST_ABI_VERSION()
-END()
+END()
diff --git a/ydb/core/ydb_convert/table_description.cpp b/ydb/core/ydb_convert/table_description.cpp
index 337085effba..0d10bb8450b 100644
--- a/ydb/core/ydb_convert/table_description.cpp
+++ b/ydb/core/ydb_convert/table_description.cpp
@@ -363,16 +363,16 @@ void FillTableStats(Ydb::Table::DescribeTableResult& out,
}
ui64 modificationTimeMs = in.GetTableStats().GetLastUpdateTime();
- if (modificationTimeMs) {
- auto modificationTime = MillisecToProtoTimeStamp(modificationTimeMs);
- stats->mutable_modification_time()->CopyFrom(modificationTime);
- }
+ if (modificationTimeMs) {
+ auto modificationTime = MillisecToProtoTimeStamp(modificationTimeMs);
+ stats->mutable_modification_time()->CopyFrom(modificationTime);
+ }
ui64 creationTimeMs = in.GetSelf().GetCreateStep();
- if (creationTimeMs) {
- auto creationTime = MillisecToProtoTimeStamp(creationTimeMs);
- stats->mutable_creation_time()->CopyFrom(creationTime);
- }
+ if (creationTimeMs) {
+ auto creationTime = MillisecToProtoTimeStamp(creationTimeMs);
+ stats->mutable_creation_time()->CopyFrom(creationTime);
+ }
}
static bool IsDefaultFamily(const NKikimrSchemeOp::TFamilyDescription& family) {
diff --git a/ydb/core/ydb_convert/ydb_convert.cpp b/ydb/core/ydb_convert/ydb_convert.cpp
index cf7bc8f0579..11c804cff50 100644
--- a/ydb/core/ydb_convert/ydb_convert.cpp
+++ b/ydb/core/ydb_convert/ydb_convert.cpp
@@ -710,12 +710,12 @@ const THashMap<TString, TACLAttrs> AccessMap_ = {
{ "ydb.tables.read", TACLAttrs(EAccessRights::SelectRow | EAccessRights::ReadAttributes) },
{ "ydb.generic.read", EAccessRights::GenericRead },
{ "ydb.generic.write", EAccessRights::GenericWrite },
- { "ydb.generic.use", EAccessRights::GenericUse },
- { "ydb.generic.manage", EAccessRights::GenericManage },
+ { "ydb.generic.use", EAccessRights::GenericUse },
+ { "ydb.generic.manage", EAccessRights::GenericManage },
{ "ydb.generic.full", EAccessRights::GenericFull },
- { "ydb.database.create", EAccessRights::CreateDatabase },
- { "ydb.database.drop", EAccessRights::DropDatabase },
- { "ydb.access.grant", EAccessRights::GrantAccessRights },
+ { "ydb.database.create", EAccessRights::CreateDatabase },
+ { "ydb.database.drop", EAccessRights::DropDatabase },
+ { "ydb.access.grant", EAccessRights::GrantAccessRights },
{ "ydb.deprecated.select_row", EAccessRights::SelectRow },
{ "ydb.deprecated.update_row", EAccessRights::UpdateRow },
{ "ydb.deprecated.erase_row", EAccessRights::EraseRow },
diff --git a/ydb/core/ymq/actor/action.h b/ydb/core/ymq/actor/action.h
index 37ea6791a79..1801c98d68f 100644
--- a/ydb/core/ymq/actor/action.h
+++ b/ydb/core/ymq/actor/action.h
@@ -446,7 +446,7 @@ private:
STATEFN(WaitAuthCheckMessages) {
switch (ev->GetTypeRewrite()) {
hFunc(TEvTxProxySchemeCache::TEvNavigateKeySetResult, HandleSchemeCacheResponse);
- hFunc(TEvTicketParser::TEvAuthorizeTicketResult, HandleTicketParserResponse);
+ hFunc(TEvTicketParser::TEvAuthorizeTicketResult, HandleTicketParserResponse);
hFunc(TEvWakeup, HandleWakeup);
}
}
@@ -482,7 +482,7 @@ private:
}
void RequestTicketParser() {
- this->Send(MakeTicketParserID(), new TEvTicketParser::TEvAuthorizeTicket(SecurityToken_));
+ this->Send(MakeTicketParserID(), new TEvTicketParser::TEvAuthorizeTicket(SecurityToken_));
}
bool IsACLProtectedAccount(const TString& accountName) const {
@@ -599,8 +599,8 @@ private:
OnAuthCheckMessage();
}
- void HandleTicketParserResponse(TEvTicketParser::TEvAuthorizeTicketResult::TPtr& ev) {
- const TEvTicketParser::TEvAuthorizeTicketResult& result(*ev->Get());
+ void HandleTicketParserResponse(TEvTicketParser::TEvAuthorizeTicketResult::TPtr& ev) {
+ const TEvTicketParser::TEvAuthorizeTicketResult& result(*ev->Get());
if (!result.Error.empty()) {
RLOG_SQS_ERROR("Got ticket parser error: " << result.Error << ". " << Action_ << " was rejected");
MakeError(MutableErrorDesc(), NErrors::ACCESS_DENIED);
diff --git a/ydb/core/ymq/actor/executor.cpp b/ydb/core/ymq/actor/executor.cpp
index 16c14bf0569..e17dc68fe95 100644
--- a/ydb/core/ymq/actor/executor.cpp
+++ b/ydb/core/ymq/actor/executor.cpp
@@ -443,7 +443,7 @@ void TMiniKqlExecutionActor::PassAway() {
void TMiniKqlExecutionActor::WaitForCompletion(bool retry) {
const ui64 schemeShardId = ResponseEvent_->Get()->Record.GetSchemeShardTabletId();
NTabletPipe::TClientConfig clientConfig;
- clientConfig.RetryPolicy = {.RetryLimitCount = 5, .MinRetryTime = TDuration::MilliSeconds(100), .DoFirstRetryInstantly = !retry};
+ clientConfig.RetryPolicy = {.RetryLimitCount = 5, .MinRetryTime = TDuration::MilliSeconds(100), .DoFirstRetryInstantly = !retry};
TabletPipeClient_ = RegisterWithSameMailbox(NTabletPipe::CreateClient(SelfId(), schemeShardId, clientConfig));
TAutoPtr<NSchemeShard::TEvSchemeShard::TEvNotifyTxCompletion> request(new NSchemeShard::TEvSchemeShard::TEvNotifyTxCompletion());
diff --git a/ydb/core/ymq/actor/schema.cpp b/ydb/core/ymq/actor/schema.cpp
index efa85a8185d..20e84581fe5 100644
--- a/ydb/core/ymq/actor/schema.cpp
+++ b/ydb/core/ymq/actor/schema.cpp
@@ -566,7 +566,7 @@ private:
void CreatePipe(bool retry) {
NTabletPipe::TClientConfig clientConfig;
- clientConfig.RetryPolicy = {.RetryLimitCount = 5, .MinRetryTime = TDuration::MilliSeconds(100), .DoFirstRetryInstantly = !retry};
+ clientConfig.RetryPolicy = {.RetryLimitCount = 5, .MinRetryTime = TDuration::MilliSeconds(100), .DoFirstRetryInstantly = !retry};
PipeClient = this->Register(NTabletPipe::CreateClient(this->SelfId(), QuoterTabletId, clientConfig));
RLOG_SQS_TRACE("Created pipe client to Kesus: " << PipeClient);
}
diff --git a/ydb/core/ymq/actor/service.cpp b/ydb/core/ymq/actor/service.cpp
index f6d29f20014..34c9a4ae46b 100644
--- a/ydb/core/ymq/actor/service.cpp
+++ b/ydb/core/ymq/actor/service.cpp
@@ -98,7 +98,7 @@ struct TSqsService::TQueueInfo : public TAtomicRefCount<TQueueInfo> {
NTabletPipe::TClientConfig cfg;
cfg.AllowFollower = false;
cfg.CheckAliveness = true;
- cfg.RetryPolicy = {.RetryLimitCount = 3, .MinRetryTime = TDuration::MilliSeconds(100), .DoFirstRetryInstantly = firstTime};
+ cfg.RetryPolicy = {.RetryLimitCount = 3, .MinRetryTime = TDuration::MilliSeconds(100), .DoFirstRetryInstantly = firstTime};
PipeClient_ = TActivationContext::Register(NTabletPipe::CreateClient(SelfId(), LeaderTabletId_, cfg));
LOG_SQS_DEBUG("Connect to leader tablet [" << LeaderTabletId_ << "] for queue [" << UserName_ << "/" << QueueName_ << "]. Pipe client actor: " << PipeClient_);
}
diff --git a/ydb/core/yql_testlib/yql_testlib.cpp b/ydb/core/yql_testlib/yql_testlib.cpp
index 8670e4e5b4f..35838c40f6a 100644
--- a/ydb/core/yql_testlib/yql_testlib.cpp
+++ b/ydb/core/yql_testlib/yql_testlib.cpp
@@ -183,7 +183,7 @@ void TYqlServer::Initialize() {
for (ui32 nodeIdx = 0; nodeIdx < GetSettings().NodeCount; ++nodeIdx) {
SetupDomainLocalService(nodeIdx);
- SetupProxies(nodeIdx);
+ SetupProxies(nodeIdx);
}
SetupLogging();
}
diff --git a/ydb/library/aclib/aclib.cpp b/ydb/library/aclib/aclib.cpp
index fe771dd08f1..946497ea303 100644
--- a/ydb/library/aclib/aclib.cpp
+++ b/ydb/library/aclib/aclib.cpp
@@ -1,268 +1,268 @@
-#include "aclib.h"
-#include <util/stream/str.h>
-#include <util/string/vector.h>
+#include "aclib.h"
+#include <util/stream/str.h>
+#include <util/string/vector.h>
#include <algorithm>
#include <util/string/split.h>
#include <library/cpp/protobuf/util/is_equal.h>
-
-namespace NACLib {
-
-std::pair<ui32, ui32>& operator |=(std::pair<ui32, ui32>& a, const std::pair<ui32, ui32>& b) {
- a.first |= b.first;
- a.second |= b.second;
- return a;
-}
-
-void TUserToken::SetGroupSIDs(const TVector<TString>& groupSIDs) {
- auto& hashTable = *MutableGroupSIDs();
- auto& hashBuckets = *hashTable.MutableBuckets();
- int size(groupSIDs.size()); // we targeting for load factor ~1.0
- hashBuckets.Reserve(size);
- for (int i = 0; i < size; ++i) {
- hashBuckets.Add();
- }
- for (const TSID& sid : groupSIDs) {
- int index = hash<TSID>()(sid) % size;
- hashBuckets.Mutable(index)->AddValues(sid);
- }
-}
-
-TUserToken::TUserToken(TUserToken::TUserTokenInitFields fields) {
- if (!fields.OriginalUserToken.empty()) {
- SetOriginalUserToken(fields.OriginalUserToken);
- }
- SetUserSID(fields.UserSID);
- SetGroupSIDs(fields.GroupSIDs);
- if (fields.AuthType) {
- SetAuthType(fields.AuthType);
- }
-}
-
-TUserToken::TUserToken(const TString& originalUserToken, const TSID& userSID, const TVector<TSID>& groupSIDs) {
- if (!originalUserToken.empty()) {
- SetOriginalUserToken(originalUserToken);
- }
- SetUserSID(userSID);
- SetGroupSIDs(groupSIDs);
-}
-
-TUserToken::TUserToken(const TSID& userSID, const TVector<TSID>& groupSIDs)
- : TUserToken(TString(), userSID, groupSIDs)
-{}
-
-TUserToken::TUserToken(const TVector<TSID>& userAndGroupSIDs)
- : TUserToken(TString(), GetUserFromVector(userAndGroupSIDs), GetGroupsFromVector(userAndGroupSIDs))
-{}
-
-TUserToken::TUserToken(const NACLibProto::TUserToken& token)
- :NACLibProto::TUserToken(token)
-{}
-
-TUserToken::TUserToken(NACLibProto::TUserToken&& token) {
- Swap(&token);
-}
-
+
+namespace NACLib {
+
+std::pair<ui32, ui32>& operator |=(std::pair<ui32, ui32>& a, const std::pair<ui32, ui32>& b) {
+ a.first |= b.first;
+ a.second |= b.second;
+ return a;
+}
+
+void TUserToken::SetGroupSIDs(const TVector<TString>& groupSIDs) {
+ auto& hashTable = *MutableGroupSIDs();
+ auto& hashBuckets = *hashTable.MutableBuckets();
+ int size(groupSIDs.size()); // we targeting for load factor ~1.0
+ hashBuckets.Reserve(size);
+ for (int i = 0; i < size; ++i) {
+ hashBuckets.Add();
+ }
+ for (const TSID& sid : groupSIDs) {
+ int index = hash<TSID>()(sid) % size;
+ hashBuckets.Mutable(index)->AddValues(sid);
+ }
+}
+
+TUserToken::TUserToken(TUserToken::TUserTokenInitFields fields) {
+ if (!fields.OriginalUserToken.empty()) {
+ SetOriginalUserToken(fields.OriginalUserToken);
+ }
+ SetUserSID(fields.UserSID);
+ SetGroupSIDs(fields.GroupSIDs);
+ if (fields.AuthType) {
+ SetAuthType(fields.AuthType);
+ }
+}
+
+TUserToken::TUserToken(const TString& originalUserToken, const TSID& userSID, const TVector<TSID>& groupSIDs) {
+ if (!originalUserToken.empty()) {
+ SetOriginalUserToken(originalUserToken);
+ }
+ SetUserSID(userSID);
+ SetGroupSIDs(groupSIDs);
+}
+
+TUserToken::TUserToken(const TSID& userSID, const TVector<TSID>& groupSIDs)
+ : TUserToken(TString(), userSID, groupSIDs)
+{}
+
+TUserToken::TUserToken(const TVector<TSID>& userAndGroupSIDs)
+ : TUserToken(TString(), GetUserFromVector(userAndGroupSIDs), GetGroupsFromVector(userAndGroupSIDs))
+{}
+
+TUserToken::TUserToken(const NACLibProto::TUserToken& token)
+ :NACLibProto::TUserToken(token)
+{}
+
+TUserToken::TUserToken(NACLibProto::TUserToken&& token) {
+ Swap(&token);
+}
+
TUserToken::TUserToken(const TString& token) {
- Y_VERIFY(ParseFromString(token));
-}
-
-bool TUserToken::IsExist(const TSID& someSID) const {
- if (NACLibProto::TUserToken::GetUserSID() == someSID)
- return true;
- const auto& hashTable(NACLibProto::TUserToken::GetGroupSIDs());
- if (hashTable.BucketsSize() > 0) {
- int index = hash<TSID>()(someSID) % hashTable.BucketsSize();
- const auto& hashBucket(hashTable.GetBuckets(index).GetValues());
- for (const TSID& sid : hashBucket) {
- if (sid == someSID)
- return true;
- }
- }
- return false;
-}
-
-TSID TUserToken::GetUserSID() const {
- return NACLibProto::TUserToken::GetUserSID();
-}
-
+ Y_VERIFY(ParseFromString(token));
+}
+
+bool TUserToken::IsExist(const TSID& someSID) const {
+ if (NACLibProto::TUserToken::GetUserSID() == someSID)
+ return true;
+ const auto& hashTable(NACLibProto::TUserToken::GetGroupSIDs());
+ if (hashTable.BucketsSize() > 0) {
+ int index = hash<TSID>()(someSID) % hashTable.BucketsSize();
+ const auto& hashBucket(hashTable.GetBuckets(index).GetValues());
+ for (const TSID& sid : hashBucket) {
+ if (sid == someSID)
+ return true;
+ }
+ }
+ return false;
+}
+
+TSID TUserToken::GetUserSID() const {
+ return NACLibProto::TUserToken::GetUserSID();
+}
+
TVector<TSID> TUserToken::GetGroupSIDs() const {
TVector<TSID> groupSIDs;
- for (const auto& bucket : NACLibProto::TUserToken::GetGroupSIDs().GetBuckets()) {
- for (const TString& value : bucket.GetValues()) {
- groupSIDs.emplace_back(value);
- }
- }
- return groupSIDs;
-}
-
-TString TUserToken::GetOriginalUserToken() const {
- return NACLibProto::TUserToken::GetOriginalUserToken();
-}
-
+ for (const auto& bucket : NACLibProto::TUserToken::GetGroupSIDs().GetBuckets()) {
+ for (const TString& value : bucket.GetValues()) {
+ groupSIDs.emplace_back(value);
+ }
+ }
+ return groupSIDs;
+}
+
+TString TUserToken::GetOriginalUserToken() const {
+ return NACLibProto::TUserToken::GetOriginalUserToken();
+}
+
TString TUserToken::SerializeAsString() const {
- return NACLibProto::TUserToken::SerializeAsString();
-}
-
-TSID TUserToken::GetUserFromVector(const TVector<TSID>& userAndGroupSIDs) {
- return userAndGroupSIDs.empty() ? TSID() : userAndGroupSIDs.front();
-}
-
-TVector<TSID> TUserToken::GetGroupsFromVector(const TVector<TSID>& userAndGroupSIDs) {
- return (userAndGroupSIDs.size() < 2) ? TVector<TSID>() : TVector<TSID>(std::next(userAndGroupSIDs.begin()), userAndGroupSIDs.end());
-}
-
-void TUserToken::AddGroupSID(const TSID& groupSID) {
- if (NACLibProto::TUserToken::GetGroupSIDs().BucketsSize() == 0) {
- MutableGroupSIDs()->AddBuckets();
- }
- int index = hash<TSID>()(groupSID) % NACLibProto::TUserToken::GetGroupSIDs().BucketsSize();
- auto& bucket = *MutableGroupSIDs()->MutableBuckets(index);
- for (const TString& value : bucket.GetValues()) {
- if (value == groupSID) {
- return;
- }
- }
- bucket.AddValues(groupSID);
-}
-
-TSecurityObject::TSecurityObject(const NACLibProto::TSecurityObject& protoSecObj, bool isContainer)
- : NACLibProto::TSecurityObject(protoSecObj)
- , IsContainer(isContainer)
-{}
-
-TSecurityObject::TSecurityObject(const TSID& owner, bool isContainer)
- : IsContainer(isContainer)
-{
- SetOwnerSID(owner);
-}
-
-ui32 TSecurityObject::GetEffectiveAccessRights(const TUserToken& user) const {
- if (HasOwnerSID() && user.IsExist(GetOwnerSID()))
- return EAccessRights::GenericFull; // the owner always have access
- ui32 deniedAccessRights = EAccessRights::NoAccess;
- ui32 allowedAccessRights = EAccessRights::NoAccess;
- if (HasACL()) {
- for (const NACLibProto::TACE& ace : GetACL().GetACE()) {
- if ((ace.GetInheritanceType() & EInheritanceType::InheritOnly) == 0) {
- if (user.IsExist(ace.GetSID())) {
- switch(static_cast<EAccessType>(ace.GetAccessType())) {
- case EAccessType::Deny:
- deniedAccessRights |= ace.GetAccessRight();
- break;
- case EAccessType::Allow:
- allowedAccessRights |= ace.GetAccessRight();
- break;
- }
- }
- }
- }
- }
- return allowedAccessRights & (~deniedAccessRights);
-}
-
-bool TSecurityObject::CheckAccess(ui32 access, const TUserToken& user) const {
- if (HasOwnerSID() && user.IsExist(GetOwnerSID()))
- return true; // the owner always have access
- if (HasACL()) {
- ui32 accessRightsLeft = access;
- for (const NACLibProto::TACE& ace : GetACL().GetACE()) {
- if ((ace.GetInheritanceType() & EInheritanceType::InheritOnly) == 0) {
- if (user.IsExist(ace.GetSID())) {
- switch(static_cast<EAccessType>(ace.GetAccessType())) {
- case EAccessType::Deny:
- if (access && ace.GetAccessRight() != 0)
+ return NACLibProto::TUserToken::SerializeAsString();
+}
+
+TSID TUserToken::GetUserFromVector(const TVector<TSID>& userAndGroupSIDs) {
+ return userAndGroupSIDs.empty() ? TSID() : userAndGroupSIDs.front();
+}
+
+TVector<TSID> TUserToken::GetGroupsFromVector(const TVector<TSID>& userAndGroupSIDs) {
+ return (userAndGroupSIDs.size() < 2) ? TVector<TSID>() : TVector<TSID>(std::next(userAndGroupSIDs.begin()), userAndGroupSIDs.end());
+}
+
+void TUserToken::AddGroupSID(const TSID& groupSID) {
+ if (NACLibProto::TUserToken::GetGroupSIDs().BucketsSize() == 0) {
+ MutableGroupSIDs()->AddBuckets();
+ }
+ int index = hash<TSID>()(groupSID) % NACLibProto::TUserToken::GetGroupSIDs().BucketsSize();
+ auto& bucket = *MutableGroupSIDs()->MutableBuckets(index);
+ for (const TString& value : bucket.GetValues()) {
+ if (value == groupSID) {
+ return;
+ }
+ }
+ bucket.AddValues(groupSID);
+}
+
+TSecurityObject::TSecurityObject(const NACLibProto::TSecurityObject& protoSecObj, bool isContainer)
+ : NACLibProto::TSecurityObject(protoSecObj)
+ , IsContainer(isContainer)
+{}
+
+TSecurityObject::TSecurityObject(const TSID& owner, bool isContainer)
+ : IsContainer(isContainer)
+{
+ SetOwnerSID(owner);
+}
+
+ui32 TSecurityObject::GetEffectiveAccessRights(const TUserToken& user) const {
+ if (HasOwnerSID() && user.IsExist(GetOwnerSID()))
+ return EAccessRights::GenericFull; // the owner always have access
+ ui32 deniedAccessRights = EAccessRights::NoAccess;
+ ui32 allowedAccessRights = EAccessRights::NoAccess;
+ if (HasACL()) {
+ for (const NACLibProto::TACE& ace : GetACL().GetACE()) {
+ if ((ace.GetInheritanceType() & EInheritanceType::InheritOnly) == 0) {
+ if (user.IsExist(ace.GetSID())) {
+ switch(static_cast<EAccessType>(ace.GetAccessType())) {
+ case EAccessType::Deny:
+ deniedAccessRights |= ace.GetAccessRight();
+ break;
+ case EAccessType::Allow:
+ allowedAccessRights |= ace.GetAccessRight();
+ break;
+ }
+ }
+ }
+ }
+ }
+ return allowedAccessRights & (~deniedAccessRights);
+}
+
+bool TSecurityObject::CheckAccess(ui32 access, const TUserToken& user) const {
+ if (HasOwnerSID() && user.IsExist(GetOwnerSID()))
+ return true; // the owner always have access
+ if (HasACL()) {
+ ui32 accessRightsLeft = access;
+ for (const NACLibProto::TACE& ace : GetACL().GetACE()) {
+ if ((ace.GetInheritanceType() & EInheritanceType::InheritOnly) == 0) {
+ if (user.IsExist(ace.GetSID())) {
+ switch(static_cast<EAccessType>(ace.GetAccessType())) {
+ case EAccessType::Deny:
+ if (access && ace.GetAccessRight() != 0)
return false; // deny entries have precedence over allow entries
- break;
- case EAccessType::Allow:
- accessRightsLeft &= ~(accessRightsLeft & ace.GetAccessRight()); // some rights allowed
- break;
- }
- if (accessRightsLeft == 0) // all rights has been allowed
- return true;
- }
- }
- }
- }
- return false; // empty ACL is always-deny ACL
-}
-
-bool TSecurityObject::CheckGrantAccess(const NACLibProto::TDiffACL& diffACL, const TUserToken& user) const Y_NO_SANITIZE("undefined") {
- ui32 effectiveAccess = GetEffectiveAccessRights(user);
- NACLibProto::TACL copyACL = GetACL();
- std::pair<ui32, ui32> modifiedAccess = static_cast<TACL&>(copyACL).ApplyDiff(diffACL);
- return ((modifiedAccess.first & effectiveAccess) == modifiedAccess.first)
- && ((modifiedAccess.second & effectiveAccess) == modifiedAccess.second);
-}
-
-TSecurityObject TSecurityObject::MergeWithParent(const NACLibProto::TSecurityObject& parent) const {
- TSecurityObject result(NACLibProto::TSecurityObject(), IsContainer);
- if (HasOwnerSID()) {
- result.SetOwnerSID(GetOwnerSID());
- }
- auto inheritance = IsContainer ? EInheritanceType::InheritContainer : EInheritanceType::InheritObject;
- if (parent.HasACL()) {
- for (const NACLibProto::TACE& ace : parent.GetACL().GetACE()) {
- if (static_cast<EAccessType>(ace.GetAccessType()) == EAccessType::Deny
- && ((ace.GetInheritanceType() & inheritance) != 0)) {
- NACLibProto::TACE& resultACE(*result.MutableACL()->AddACE());
- resultACE.CopyFrom(ace);
- resultACE.SetInherited(true);
- resultACE.SetInheritanceType(resultACE.GetInheritanceType() & ~EInheritanceType::InheritOnly);
- }
- }
- }
- {
- for (const NACLibProto::TACE& ace : GetACL().GetACE()) {
- if (static_cast<EAccessType>(ace.GetAccessType()) == EAccessType::Deny) {
- result.MutableACL()->AddACE()->CopyFrom(ace);
- }
- }
- }
- if (parent.HasACL()) {
- for (const NACLibProto::TACE& ace : parent.GetACL().GetACE()) {
- if (static_cast<EAccessType>(ace.GetAccessType()) != EAccessType::Deny
- && (ace.GetInheritanceType() & inheritance) != 0) {
- NACLibProto::TACE& resultACE(*result.MutableACL()->AddACE());
- resultACE.CopyFrom(ace);
- resultACE.SetInherited(true);
- resultACE.SetInheritanceType(resultACE.GetInheritanceType() & ~EInheritanceType::InheritOnly);
- }
- }
- }
- {
- for (const NACLibProto::TACE& ace : GetACL().GetACE()) {
- if (static_cast<EAccessType>(ace.GetAccessType()) != EAccessType::Deny) {
- result.MutableACL()->AddACE()->CopyFrom(ace);
- }
- }
- }
- return result;
-}
-
-void TSecurityObject::AddAccess(NACLib::EAccessType type, ui32 access, const NACLib::TSID& sid, ui32 inheritance) Y_NO_SANITIZE("undefined") {
- static_cast<TACL*>(MutableACL())->AddAccess(type, access, sid, inheritance);
-}
-
-void TSecurityObject::RemoveAccess(NACLib::EAccessType type, ui32 access, const NACLib::TSID& sid, ui32 inheritance) Y_NO_SANITIZE("undefined") {
- static_cast<TACL*>(MutableACL())->RemoveAccess(type, access, sid, inheritance);
-}
-
-void TSecurityObject::ClearAccess() Y_NO_SANITIZE("undefined") {
- static_cast<TACL*>(MutableACL())->ClearAccess();
-}
-
-NACLibProto::TACL TSecurityObject::GetImmediateACL() const Y_NO_SANITIZE("undefined") {
- return static_cast<const TACL&>(GetACL()).GetImmediateACL();
-}
-
-TSecurityObject::TSecurityObject()
- : IsContainer(false)
-{}
-
-TInstant TSecurityObject::GetExpireTime() const {
- return TInstant::MilliSeconds(static_cast<const NACLibProto::TSecurityObject&>(*this).GetExpireTime());
-}
-
+ break;
+ case EAccessType::Allow:
+ accessRightsLeft &= ~(accessRightsLeft & ace.GetAccessRight()); // some rights allowed
+ break;
+ }
+ if (accessRightsLeft == 0) // all rights has been allowed
+ return true;
+ }
+ }
+ }
+ }
+ return false; // empty ACL is always-deny ACL
+}
+
+bool TSecurityObject::CheckGrantAccess(const NACLibProto::TDiffACL& diffACL, const TUserToken& user) const Y_NO_SANITIZE("undefined") {
+ ui32 effectiveAccess = GetEffectiveAccessRights(user);
+ NACLibProto::TACL copyACL = GetACL();
+ std::pair<ui32, ui32> modifiedAccess = static_cast<TACL&>(copyACL).ApplyDiff(diffACL);
+ return ((modifiedAccess.first & effectiveAccess) == modifiedAccess.first)
+ && ((modifiedAccess.second & effectiveAccess) == modifiedAccess.second);
+}
+
+TSecurityObject TSecurityObject::MergeWithParent(const NACLibProto::TSecurityObject& parent) const {
+ TSecurityObject result(NACLibProto::TSecurityObject(), IsContainer);
+ if (HasOwnerSID()) {
+ result.SetOwnerSID(GetOwnerSID());
+ }
+ auto inheritance = IsContainer ? EInheritanceType::InheritContainer : EInheritanceType::InheritObject;
+ if (parent.HasACL()) {
+ for (const NACLibProto::TACE& ace : parent.GetACL().GetACE()) {
+ if (static_cast<EAccessType>(ace.GetAccessType()) == EAccessType::Deny
+ && ((ace.GetInheritanceType() & inheritance) != 0)) {
+ NACLibProto::TACE& resultACE(*result.MutableACL()->AddACE());
+ resultACE.CopyFrom(ace);
+ resultACE.SetInherited(true);
+ resultACE.SetInheritanceType(resultACE.GetInheritanceType() & ~EInheritanceType::InheritOnly);
+ }
+ }
+ }
+ {
+ for (const NACLibProto::TACE& ace : GetACL().GetACE()) {
+ if (static_cast<EAccessType>(ace.GetAccessType()) == EAccessType::Deny) {
+ result.MutableACL()->AddACE()->CopyFrom(ace);
+ }
+ }
+ }
+ if (parent.HasACL()) {
+ for (const NACLibProto::TACE& ace : parent.GetACL().GetACE()) {
+ if (static_cast<EAccessType>(ace.GetAccessType()) != EAccessType::Deny
+ && (ace.GetInheritanceType() & inheritance) != 0) {
+ NACLibProto::TACE& resultACE(*result.MutableACL()->AddACE());
+ resultACE.CopyFrom(ace);
+ resultACE.SetInherited(true);
+ resultACE.SetInheritanceType(resultACE.GetInheritanceType() & ~EInheritanceType::InheritOnly);
+ }
+ }
+ }
+ {
+ for (const NACLibProto::TACE& ace : GetACL().GetACE()) {
+ if (static_cast<EAccessType>(ace.GetAccessType()) != EAccessType::Deny) {
+ result.MutableACL()->AddACE()->CopyFrom(ace);
+ }
+ }
+ }
+ return result;
+}
+
+void TSecurityObject::AddAccess(NACLib::EAccessType type, ui32 access, const NACLib::TSID& sid, ui32 inheritance) Y_NO_SANITIZE("undefined") {
+ static_cast<TACL*>(MutableACL())->AddAccess(type, access, sid, inheritance);
+}
+
+void TSecurityObject::RemoveAccess(NACLib::EAccessType type, ui32 access, const NACLib::TSID& sid, ui32 inheritance) Y_NO_SANITIZE("undefined") {
+ static_cast<TACL*>(MutableACL())->RemoveAccess(type, access, sid, inheritance);
+}
+
+void TSecurityObject::ClearAccess() Y_NO_SANITIZE("undefined") {
+ static_cast<TACL*>(MutableACL())->ClearAccess();
+}
+
+NACLibProto::TACL TSecurityObject::GetImmediateACL() const Y_NO_SANITIZE("undefined") {
+ return static_cast<const TACL&>(GetACL()).GetImmediateACL();
+}
+
+TSecurityObject::TSecurityObject()
+ : IsContainer(false)
+{}
+
+TInstant TSecurityObject::GetExpireTime() const {
+ return TInstant::MilliSeconds(static_cast<const NACLibProto::TSecurityObject&>(*this).GetExpireTime());
+}
+
TString TSecurityObject::ToString() const Y_NO_SANITIZE("undefined") {
return static_cast<const TACL&>(GetACL()).ToString();
}
@@ -271,10 +271,10 @@ void TSecurityObject::FromString(const TString& string) Y_NO_SANITIZE("undefined
static_cast<TACL*>(MutableACL())->FromString(string);
}
-void TSecurityObject::ApplyDiff(const NACLibProto::TDiffACL& diffACL) Y_NO_SANITIZE("undefined") {
- static_cast<TACL*>(MutableACL())->ApplyDiff(diffACL);
-}
-
+void TSecurityObject::ApplyDiff(const NACLibProto::TDiffACL& diffACL) Y_NO_SANITIZE("undefined") {
+ static_cast<TACL*>(MutableACL())->ApplyDiff(diffACL);
+}
+
bool TSecurityObject::operator ==(const NACLib::TSecurityObject& rhs) const {
return IsContainer == rhs.IsContainer && NProtoBuf::IsEqual(*this, rhs);
}
@@ -283,471 +283,471 @@ bool TSecurityObject::operator !=(const NACLib::TSecurityObject& rhs) const {
return !(*this == rhs);
}
-std::pair<ui32, ui32> TACL::AddAccess(NACLib::EAccessType type, ui32 access, const NACLib::TSID& sid, ui32 inheritance) Y_NO_SANITIZE("undefined") {
- for (int i = 0; i < static_cast<int>(ACESize()); ++i) {
- const NACLibProto::TACE& ace(GetACE(i));
- if (ace.GetSID() == sid) {
- if (ace.GetAccessType() == static_cast<ui32>(type)
- && ace.GetAccessRight() == access
- && ace.GetInheritanceType() == inheritance) {
- return {};
- }
- }
- }
- NACLibProto::TACE* ace(AddACE());
- ace->SetAccessType(static_cast<ui32>(type));
- ace->SetAccessRight(access);
- ace->SetSID(sid);
- ace->SetInheritanceType(inheritance);
- SortACL();
- switch (type) {
- case NACLib::EAccessType::Allow:
- return std::pair<ui32, ui32>(access, NACLib::EAccessRights::NoAccess);
- case NACLib::EAccessType::Deny:
- return std::pair<ui32, ui32>(NACLib::EAccessRights::NoAccess, access);
- }
- return {};
-}
-
-std::pair<ui32, ui32> TACL::RemoveAccess(NACLib::EAccessType type, ui32 access, const NACLib::TSID& sid, ui32 inheritance) {
- NACLibProto::TACE filterACE;
- filterACE.SetAccessType(static_cast<ui32>(type));
- filterACE.SetAccessRight(static_cast<ui32>(access));
- filterACE.SetSID(sid);
- filterACE.SetInheritanceType(static_cast<ui32>(inheritance));
- return RemoveAccess(filterACE);
-}
-
-std::pair<ui32, ui32> TACL::ClearAccess() {
- NACLibProto::TACE filterACE;
- return RemoveAccess(filterACE);
-}
-
-std::pair<ui32, ui32> TACL::RemoveAccess(const NACLibProto::TACE& filter) {
- std::pair<ui32, ui32> modified = {};
+std::pair<ui32, ui32> TACL::AddAccess(NACLib::EAccessType type, ui32 access, const NACLib::TSID& sid, ui32 inheritance) Y_NO_SANITIZE("undefined") {
+ for (int i = 0; i < static_cast<int>(ACESize()); ++i) {
+ const NACLibProto::TACE& ace(GetACE(i));
+ if (ace.GetSID() == sid) {
+ if (ace.GetAccessType() == static_cast<ui32>(type)
+ && ace.GetAccessRight() == access
+ && ace.GetInheritanceType() == inheritance) {
+ return {};
+ }
+ }
+ }
+ NACLibProto::TACE* ace(AddACE());
+ ace->SetAccessType(static_cast<ui32>(type));
+ ace->SetAccessRight(access);
+ ace->SetSID(sid);
+ ace->SetInheritanceType(inheritance);
+ SortACL();
+ switch (type) {
+ case NACLib::EAccessType::Allow:
+ return std::pair<ui32, ui32>(access, NACLib::EAccessRights::NoAccess);
+ case NACLib::EAccessType::Deny:
+ return std::pair<ui32, ui32>(NACLib::EAccessRights::NoAccess, access);
+ }
+ return {};
+}
+
+std::pair<ui32, ui32> TACL::RemoveAccess(NACLib::EAccessType type, ui32 access, const NACLib::TSID& sid, ui32 inheritance) {
+ NACLibProto::TACE filterACE;
+ filterACE.SetAccessType(static_cast<ui32>(type));
+ filterACE.SetAccessRight(static_cast<ui32>(access));
+ filterACE.SetSID(sid);
+ filterACE.SetInheritanceType(static_cast<ui32>(inheritance));
+ return RemoveAccess(filterACE);
+}
+
+std::pair<ui32, ui32> TACL::ClearAccess() {
+ NACLibProto::TACE filterACE;
+ return RemoveAccess(filterACE);
+}
+
+std::pair<ui32, ui32> TACL::RemoveAccess(const NACLibProto::TACE& filter) {
+ std::pair<ui32, ui32> modified = {};
auto* ACL = MutableACE();
- auto matchACE = [&filter](const NACLibProto::TACE& ace) {
- if (filter.HasAccessType() && ace.GetAccessType() != filter.GetAccessType()) {
- return false;
- }
- if (filter.HasAccessRight() && ace.GetAccessRight() != filter.GetAccessRight()) {
- return false;
- }
- if (filter.HasSID() && ace.GetSID() != filter.GetSID()) {
- return false;
- }
- if (filter.HasInheritanceType() && ace.GetInheritanceType() != filter.GetInheritanceType()) {
- return false;
- }
- return true;
+ auto matchACE = [&filter](const NACLibProto::TACE& ace) {
+ if (filter.HasAccessType() && ace.GetAccessType() != filter.GetAccessType()) {
+ return false;
+ }
+ if (filter.HasAccessRight() && ace.GetAccessRight() != filter.GetAccessRight()) {
+ return false;
+ }
+ if (filter.HasSID() && ace.GetSID() != filter.GetSID()) {
+ return false;
+ }
+ if (filter.HasInheritanceType() && ace.GetInheritanceType() != filter.GetInheritanceType()) {
+ return false;
+ }
+ return true;
};
- auto newEnd = std::remove_if(ACL->begin(), ACL->end(), std::move(matchACE));
+ auto newEnd = std::remove_if(ACL->begin(), ACL->end(), std::move(matchACE));
while (newEnd != ACL->end()) {
- switch (static_cast<NACLib::EAccessType>(ACL->rbegin()->GetAccessType())) {
- case NACLib::EAccessType::Allow:
- modified |= std::pair<ui32, ui32>(ACL->rbegin()->GetAccessRight(), NACLib::EAccessRights::NoAccess);
- break;
- case NACLib::EAccessType::Deny:
- modified |= std::pair<ui32, ui32>(NACLib::EAccessRights::NoAccess, ACL->rbegin()->GetAccessRight());
- break;
- }
+ switch (static_cast<NACLib::EAccessType>(ACL->rbegin()->GetAccessType())) {
+ case NACLib::EAccessType::Allow:
+ modified |= std::pair<ui32, ui32>(ACL->rbegin()->GetAccessRight(), NACLib::EAccessRights::NoAccess);
+ break;
+ case NACLib::EAccessType::Deny:
+ modified |= std::pair<ui32, ui32>(NACLib::EAccessRights::NoAccess, ACL->rbegin()->GetAccessRight());
+ break;
+ }
ACL->RemoveLast();
- }
- return modified;
-}
-
-void TACL::SortACL() {
- Sort(*(MutableACE()), [](const NACLibProto::TACE& a, const NACLibProto::TACE& b) -> bool { return a.GetAccessType() < b.GetAccessType(); });
-}
-
+ }
+ return modified;
+}
+
+void TACL::SortACL() {
+ Sort(*(MutableACE()), [](const NACLibProto::TACE& a, const NACLibProto::TACE& b) -> bool { return a.GetAccessType() < b.GetAccessType(); });
+}
+
TACL::TACL(const TString& string) {
- Y_VERIFY(ParseFromString(string));
-}
-
-std::pair<ui32, ui32> TACL::ApplyDiff(const NACLibProto::TDiffACL& diffACL) Y_NO_SANITIZE("undefined") {
- std::pair<ui32, ui32> modified = {};
- for (const NACLibProto::TDiffACE& diffACE : diffACL.GetDiffACE()) {
- const NACLibProto::TACE& ace = diffACE.GetACE();
- switch (static_cast<EDiffType>(diffACE.GetDiffType())) {
- case EDiffType::Add:
- modified |= AddAccess(static_cast<NACLib::EAccessType>(ace.GetAccessType()), ace.GetAccessRight(), ace.GetSID(), ace.GetInheritanceType());
- break;
- case EDiffType::Remove:
- modified |= RemoveAccess(ace);
- break;
- }
- }
- return modified;
-}
-
-NACLibProto::TACL TACL::GetImmediateACL() const {
- NACLibProto::TACL immediateACL;
- for (const NACLibProto::TACE& ace : GetACE()) {
- if (!ace.GetInherited()) {
- immediateACL.AddACE()->CopyFrom(ace);
- }
- }
- return immediateACL;
-}
-
+ Y_VERIFY(ParseFromString(string));
+}
+
+std::pair<ui32, ui32> TACL::ApplyDiff(const NACLibProto::TDiffACL& diffACL) Y_NO_SANITIZE("undefined") {
+ std::pair<ui32, ui32> modified = {};
+ for (const NACLibProto::TDiffACE& diffACE : diffACL.GetDiffACE()) {
+ const NACLibProto::TACE& ace = diffACE.GetACE();
+ switch (static_cast<EDiffType>(diffACE.GetDiffType())) {
+ case EDiffType::Add:
+ modified |= AddAccess(static_cast<NACLib::EAccessType>(ace.GetAccessType()), ace.GetAccessRight(), ace.GetSID(), ace.GetInheritanceType());
+ break;
+ case EDiffType::Remove:
+ modified |= RemoveAccess(ace);
+ break;
+ }
+ }
+ return modified;
+}
+
+NACLibProto::TACL TACL::GetImmediateACL() const {
+ NACLibProto::TACL immediateACL;
+ for (const NACLibProto::TACE& ace : GetACE()) {
+ if (!ace.GetInherited()) {
+ immediateACL.AddACE()->CopyFrom(ace);
+ }
+ }
+ return immediateACL;
+}
+
TString TACL::ToString(const NACLibProto::TACE& ace) {
- TStringStream str;
- switch (static_cast<EAccessType>(ace.GetAccessType())) {
- case EAccessType::Allow:
- str << '+';
- break;
- case EAccessType::Deny:
- str << '-';
- break;
- default:
- str << '?';
- break;
- }
- auto ar = ace.GetAccessRight();
- switch (ar) {
- case EAccessRights::GenericRead:
- str << 'R';
- break;
- case EAccessRights::GenericWrite:
- str << 'W';
- break;
- case EAccessRights::GenericFull:
- str << 'F';
- break;
- case EAccessRights::GenericManage:
- str << 'M';
- break;
- case EAccessRights::GenericUse:
- str << 'U';
- break;
- default: {
+ TStringStream str;
+ switch (static_cast<EAccessType>(ace.GetAccessType())) {
+ case EAccessType::Allow:
+ str << '+';
+ break;
+ case EAccessType::Deny:
+ str << '-';
+ break;
+ default:
+ str << '?';
+ break;
+ }
+ auto ar = ace.GetAccessRight();
+ switch (ar) {
+ case EAccessRights::GenericRead:
+ str << 'R';
+ break;
+ case EAccessRights::GenericWrite:
+ str << 'W';
+ break;
+ case EAccessRights::GenericFull:
+ str << 'F';
+ break;
+ case EAccessRights::GenericManage:
+ str << 'M';
+ break;
+ case EAccessRights::GenericUse:
+ str << 'U';
+ break;
+ default: {
TVector<TStringBuf> rights;
- if (ar & EAccessRights::SelectRow)
- rights.emplace_back("SR");
- if (ar & EAccessRights::UpdateRow)
- rights.emplace_back("UR");
- if (ar & EAccessRights::EraseRow)
- rights.emplace_back("ER");
- if (ar & EAccessRights::ReadAttributes)
- rights.emplace_back("RA");
- if (ar & EAccessRights::WriteAttributes)
- rights.emplace_back("WA");
- if (ar & EAccessRights::CreateDirectory)
- rights.emplace_back("CD");
- if (ar & EAccessRights::CreateTable)
- rights.emplace_back("CT");
- if (ar & EAccessRights::CreateQueue)
- rights.emplace_back("CQ");
- if (ar & EAccessRights::RemoveSchema)
- rights.emplace_back("RS");
- if (ar & EAccessRights::DescribeSchema)
- rights.emplace_back("DS");
- if (ar & EAccessRights::AlterSchema)
- rights.emplace_back("AS");
- if (ar & EAccessRights::CreateDatabase)
- rights.emplace_back("CDB");
- if (ar & EAccessRights::DropDatabase)
- rights.emplace_back("DDB");
- if (ar & EAccessRights::GrantAccessRights)
- rights.emplace_back("GAR");
- if (ar & EAccessRights::WriteUserAttributes)
- rights.emplace_back("WUA");
+ if (ar & EAccessRights::SelectRow)
+ rights.emplace_back("SR");
+ if (ar & EAccessRights::UpdateRow)
+ rights.emplace_back("UR");
+ if (ar & EAccessRights::EraseRow)
+ rights.emplace_back("ER");
+ if (ar & EAccessRights::ReadAttributes)
+ rights.emplace_back("RA");
+ if (ar & EAccessRights::WriteAttributes)
+ rights.emplace_back("WA");
+ if (ar & EAccessRights::CreateDirectory)
+ rights.emplace_back("CD");
+ if (ar & EAccessRights::CreateTable)
+ rights.emplace_back("CT");
+ if (ar & EAccessRights::CreateQueue)
+ rights.emplace_back("CQ");
+ if (ar & EAccessRights::RemoveSchema)
+ rights.emplace_back("RS");
+ if (ar & EAccessRights::DescribeSchema)
+ rights.emplace_back("DS");
+ if (ar & EAccessRights::AlterSchema)
+ rights.emplace_back("AS");
+ if (ar & EAccessRights::CreateDatabase)
+ rights.emplace_back("CDB");
+ if (ar & EAccessRights::DropDatabase)
+ rights.emplace_back("DDB");
+ if (ar & EAccessRights::GrantAccessRights)
+ rights.emplace_back("GAR");
+ if (ar & EAccessRights::WriteUserAttributes)
+ rights.emplace_back("WUA");
if (ar & EAccessRights::ConnectDatabase)
rights.emplace_back("ConnDB");
- str << '(';
- for (auto jt = rights.begin(); jt != rights.end(); ++jt) {
- if (jt != rights.begin()) {
- str << '|';
- }
- str << *jt;
- }
- str << ')';
- break;
- }
- }
- str << ':';
- str << ace.GetSID();
- auto inh = ace.GetInheritanceType();
- if (inh != (EInheritanceType::InheritContainer | EInheritanceType::InheritObject)) {
- str << ':';
+ str << '(';
+ for (auto jt = rights.begin(); jt != rights.end(); ++jt) {
+ if (jt != rights.begin()) {
+ str << '|';
+ }
+ str << *jt;
+ }
+ str << ')';
+ break;
+ }
+ }
+ str << ':';
+ str << ace.GetSID();
+ auto inh = ace.GetInheritanceType();
+ if (inh != (EInheritanceType::InheritContainer | EInheritanceType::InheritObject)) {
+ str << ':';
if (inh == EInheritanceType::InheritNone)
str << '-';
- if (inh & EInheritanceType::InheritContainer)
- str << 'C';
- if (inh & EInheritanceType::InheritObject)
- str << 'O';
- if (inh & EInheritanceType::InheritOnly)
- str << '+';
- }
- return str.Str();
-}
-
+ if (inh & EInheritanceType::InheritContainer)
+ str << 'C';
+ if (inh & EInheritanceType::InheritObject)
+ str << 'O';
+ if (inh & EInheritanceType::InheritOnly)
+ str << '+';
+ }
+ return str.Str();
+}
+
TString TACL::ToString() const {
- TStringStream str;
- bool inherited = false;
- const auto& acl = GetACE();
- for (auto it = acl.begin(); it != acl.end(); ++it) {
- const NACLibProto::TACE& ace = *it;
- if (it != acl.begin()) {
- str << ';';
- }
- if (inherited != ace.GetInherited()) {
- if (inherited) {
- str << '}';
- } else {
- str << '{';
- }
- inherited = ace.GetInherited();
- }
- str << ToString(ace);
- }
- if (inherited) {
- str << '}';
- }
- return str.Str();
-}
-
-ui32 TACL::SpecialRightsFromString(const TString& string) {
- TVector<TString> rights;
- ui32 result = 0;
+ TStringStream str;
+ bool inherited = false;
+ const auto& acl = GetACE();
+ for (auto it = acl.begin(); it != acl.end(); ++it) {
+ const NACLibProto::TACE& ace = *it;
+ if (it != acl.begin()) {
+ str << ';';
+ }
+ if (inherited != ace.GetInherited()) {
+ if (inherited) {
+ str << '}';
+ } else {
+ str << '{';
+ }
+ inherited = ace.GetInherited();
+ }
+ str << ToString(ace);
+ }
+ if (inherited) {
+ str << '}';
+ }
+ return str.Str();
+}
+
+ui32 TACL::SpecialRightsFromString(const TString& string) {
+ TVector<TString> rights;
+ ui32 result = 0;
StringSplitter(string).Split('|').SkipEmpty().Collect(&rights);
- for (const TString& r : rights) {
- if (r == "SR")
- result |= EAccessRights::SelectRow;
- if (r == "UR")
- result |= EAccessRights::UpdateRow;
- if (r == "ER")
- result |= EAccessRights::EraseRow;
- if (r == "RA")
- result |= EAccessRights::ReadAttributes;
- if (r == "WA")
- result |= EAccessRights::WriteAttributes;
- if (r == "CD")
- result |= EAccessRights::CreateDirectory;
- if (r == "CT")
- result |= EAccessRights::CreateTable;
- if (r == "CQ")
- result |= EAccessRights::CreateQueue;
- if (r == "RS")
- result |= EAccessRights::RemoveSchema;
- if (r == "DS")
- result |= EAccessRights::DescribeSchema;
- if (r == "AS")
- result |= EAccessRights::AlterSchema;
- if (r == "CDB")
- result |= EAccessRights::CreateDatabase;
- if (r == "DDB")
- result |= EAccessRights::DropDatabase;
- if (r == "GAR")
- result |= EAccessRights::GrantAccessRights;
+ for (const TString& r : rights) {
+ if (r == "SR")
+ result |= EAccessRights::SelectRow;
+ if (r == "UR")
+ result |= EAccessRights::UpdateRow;
+ if (r == "ER")
+ result |= EAccessRights::EraseRow;
+ if (r == "RA")
+ result |= EAccessRights::ReadAttributes;
+ if (r == "WA")
+ result |= EAccessRights::WriteAttributes;
+ if (r == "CD")
+ result |= EAccessRights::CreateDirectory;
+ if (r == "CT")
+ result |= EAccessRights::CreateTable;
+ if (r == "CQ")
+ result |= EAccessRights::CreateQueue;
+ if (r == "RS")
+ result |= EAccessRights::RemoveSchema;
+ if (r == "DS")
+ result |= EAccessRights::DescribeSchema;
+ if (r == "AS")
+ result |= EAccessRights::AlterSchema;
+ if (r == "CDB")
+ result |= EAccessRights::CreateDatabase;
+ if (r == "DDB")
+ result |= EAccessRights::DropDatabase;
+ if (r == "GAR")
+ result |= EAccessRights::GrantAccessRights;
if (r == "ConnDB")
result |= EAccessRights::ConnectDatabase;
- }
- return result;
-}
-
+ }
+ return result;
+}
+
void TACL::FromString(NACLibProto::TACE& ace, const TString& string) {
- auto it = string.begin();
- switch (*it) {
- case '+':
- ace.SetAccessType(static_cast<ui32>(EAccessType::Allow));
- break;
- case '-':
- ace.SetAccessType(static_cast<ui32>(EAccessType::Deny));
- break;
- case '*':
- break;
- default:
- throw yexception() << "Invalid access type";
- }
- ++it;
- if (it == string.end()) {
- throw yexception() << "Invalid acl - no access rights";
- }
- switch (*it) {
- case 'R':
- ace.SetAccessRight(EAccessRights::GenericRead);
- break;
- case 'W':
- ace.SetAccessRight(EAccessRights::GenericWrite);
- break;
- case 'F':
- ace.SetAccessRight(EAccessRights::GenericFull);
- break;
- case 'M':
- ace.SetAccessRight(EAccessRights::GenericManage);
- break;
- case 'U':
- ace.SetAccessRight(EAccessRights::GenericUse);
- break;
- case '(': {
- ++it;
- TString specialRights = string.substr(it - string.begin(), string.find(')', it - string.begin()) - (it - string.begin()));
- ace.SetAccessRight(SpecialRightsFromString(specialRights));
- it = it + specialRights.size();
- break;
- }
- case '*':
- break;
- default:
- // TODO: more access rights
- throw yexception() << "Invalid access rights";
- }
- ++it;
- if (it == string.end()) {
- throw yexception() << "Invalid acl - no security id";
- }
- if (*it != ':') {
- throw yexception() << "Invalid acl - invalid format";
- }
- ++it;
- if (it == string.end()) {
- throw yexception() << "Invalid acl - no security id";
- }
- auto start_pos = it - string.begin();
- auto end_pos = string.find(':', start_pos);
+ auto it = string.begin();
+ switch (*it) {
+ case '+':
+ ace.SetAccessType(static_cast<ui32>(EAccessType::Allow));
+ break;
+ case '-':
+ ace.SetAccessType(static_cast<ui32>(EAccessType::Deny));
+ break;
+ case '*':
+ break;
+ default:
+ throw yexception() << "Invalid access type";
+ }
+ ++it;
+ if (it == string.end()) {
+ throw yexception() << "Invalid acl - no access rights";
+ }
+ switch (*it) {
+ case 'R':
+ ace.SetAccessRight(EAccessRights::GenericRead);
+ break;
+ case 'W':
+ ace.SetAccessRight(EAccessRights::GenericWrite);
+ break;
+ case 'F':
+ ace.SetAccessRight(EAccessRights::GenericFull);
+ break;
+ case 'M':
+ ace.SetAccessRight(EAccessRights::GenericManage);
+ break;
+ case 'U':
+ ace.SetAccessRight(EAccessRights::GenericUse);
+ break;
+ case '(': {
+ ++it;
+ TString specialRights = string.substr(it - string.begin(), string.find(')', it - string.begin()) - (it - string.begin()));
+ ace.SetAccessRight(SpecialRightsFromString(specialRights));
+ it = it + specialRights.size();
+ break;
+ }
+ case '*':
+ break;
+ default:
+ // TODO: more access rights
+ throw yexception() << "Invalid access rights";
+ }
+ ++it;
+ if (it == string.end()) {
+ throw yexception() << "Invalid acl - no security id";
+ }
+ if (*it != ':') {
+ throw yexception() << "Invalid acl - invalid format";
+ }
+ ++it;
+ if (it == string.end()) {
+ throw yexception() << "Invalid acl - no security id";
+ }
+ auto start_pos = it - string.begin();
+ auto end_pos = string.find(':', start_pos);
ace.SetSID(string.substr(start_pos, end_pos == TString::npos ? end_pos : end_pos - start_pos));
- if (end_pos == TString::npos) {
- ace.SetInheritanceType(EInheritanceType::InheritContainer | EInheritanceType::InheritObject);
- return;
- }
- ui32 inheritanceType = 0;
- if (string[end_pos] == ':') {
- while (++end_pos < string.size()) {
- switch(string[end_pos]) {
+ if (end_pos == TString::npos) {
+ ace.SetInheritanceType(EInheritanceType::InheritContainer | EInheritanceType::InheritObject);
+ return;
+ }
+ ui32 inheritanceType = 0;
+ if (string[end_pos] == ':') {
+ while (++end_pos < string.size()) {
+ switch(string[end_pos]) {
case '-':
inheritanceType |= EInheritanceType::InheritNone;
break;
- case 'C':
- inheritanceType |= EInheritanceType::InheritContainer;
- break;
- case 'O':
- inheritanceType |= EInheritanceType::InheritObject;
- break;
- case '+':
- inheritanceType |= EInheritanceType::InheritOnly;
- break;
- default:
- throw yexception() << "Invalid acl - invalid inheritance flags";
- }
- }
- ace.SetInheritanceType(inheritanceType);
- }
-}
-
+ case 'C':
+ inheritanceType |= EInheritanceType::InheritContainer;
+ break;
+ case 'O':
+ inheritanceType |= EInheritanceType::InheritObject;
+ break;
+ case '+':
+ inheritanceType |= EInheritanceType::InheritOnly;
+ break;
+ default:
+ throw yexception() << "Invalid acl - invalid inheritance flags";
+ }
+ }
+ ace.SetInheritanceType(inheritanceType);
+ }
+}
+
void TACL::FromString(const TString& string) {
- auto& acl = *MutableACE();
- acl.Clear();
- for (auto it = string.begin(); it != string.end(); ++it) {
- auto& ace = *acl.Add();
- auto start_pos = it - string.begin();
- auto end_pos = string.find(';', start_pos);
+ auto& acl = *MutableACE();
+ acl.Clear();
+ for (auto it = string.begin(); it != string.end(); ++it) {
+ auto& ace = *acl.Add();
+ auto start_pos = it - string.begin();
+ auto end_pos = string.find(';', start_pos);
FromString(ace, string.substr(start_pos, end_pos == TString::npos ? end_pos : end_pos - start_pos));
if (end_pos == TString::npos)
- break;
+ break;
it = string.begin() + end_pos;
- }
-}
-
+ }
+}
+
TDiffACL::TDiffACL(const TString& string) {
- Y_VERIFY(ParseFromString(string));
-}
-
-void TDiffACL::AddAccess(EAccessType type, ui32 access, const TSID& sid, ui32 inheritance) {
- NACLibProto::TDiffACE* diffACE(AddDiffACE());
- diffACE->SetDiffType(static_cast<ui32>(EDiffType::Add));
- NACLibProto::TACE* ace(diffACE->MutableACE());
- ace->SetAccessType(static_cast<ui32>(type));
- ace->SetAccessRight(access);
- ace->SetSID(sid);
- ace->SetInheritanceType(inheritance);
-}
-
-void TDiffACL::RemoveAccess(NACLib::EAccessType type, ui32 access, const NACLib::TSID& sid, ui32 inheritance) {
- NACLibProto::TDiffACE* diffACE(AddDiffACE());
- diffACE->SetDiffType(static_cast<ui32>(EDiffType::Remove));
- NACLibProto::TACE* ace(diffACE->MutableACE());
- ace->SetAccessType(static_cast<ui32>(type));
- ace->SetAccessRight(access);
- ace->SetSID(sid);
- ace->SetInheritanceType(inheritance);
-}
-
-void TDiffACL::AddAccess(const NACLibProto::TACE& access) {
- NACLibProto::TDiffACE* diffACE(AddDiffACE());
- diffACE->SetDiffType(static_cast<ui32>(EDiffType::Add));
- NACLibProto::TACE* ace(diffACE->MutableACE());
- ace->CopyFrom(access);
-}
-
-void TDiffACL::RemoveAccess(const NACLibProto::TACE& access) {
- NACLibProto::TDiffACE* diffACE(AddDiffACE());
- diffACE->SetDiffType(static_cast<ui32>(EDiffType::Remove));
- NACLibProto::TACE* ace(diffACE->MutableACE());
- ace->CopyFrom(access);
-}
-
+ Y_VERIFY(ParseFromString(string));
+}
+
+void TDiffACL::AddAccess(EAccessType type, ui32 access, const TSID& sid, ui32 inheritance) {
+ NACLibProto::TDiffACE* diffACE(AddDiffACE());
+ diffACE->SetDiffType(static_cast<ui32>(EDiffType::Add));
+ NACLibProto::TACE* ace(diffACE->MutableACE());
+ ace->SetAccessType(static_cast<ui32>(type));
+ ace->SetAccessRight(access);
+ ace->SetSID(sid);
+ ace->SetInheritanceType(inheritance);
+}
+
+void TDiffACL::RemoveAccess(NACLib::EAccessType type, ui32 access, const NACLib::TSID& sid, ui32 inheritance) {
+ NACLibProto::TDiffACE* diffACE(AddDiffACE());
+ diffACE->SetDiffType(static_cast<ui32>(EDiffType::Remove));
+ NACLibProto::TACE* ace(diffACE->MutableACE());
+ ace->SetAccessType(static_cast<ui32>(type));
+ ace->SetAccessRight(access);
+ ace->SetSID(sid);
+ ace->SetInheritanceType(inheritance);
+}
+
+void TDiffACL::AddAccess(const NACLibProto::TACE& access) {
+ NACLibProto::TDiffACE* diffACE(AddDiffACE());
+ diffACE->SetDiffType(static_cast<ui32>(EDiffType::Add));
+ NACLibProto::TACE* ace(diffACE->MutableACE());
+ ace->CopyFrom(access);
+}
+
+void TDiffACL::RemoveAccess(const NACLibProto::TACE& access) {
+ NACLibProto::TDiffACE* diffACE(AddDiffACE());
+ diffACE->SetDiffType(static_cast<ui32>(EDiffType::Remove));
+ NACLibProto::TACE* ace(diffACE->MutableACE());
+ ace->CopyFrom(access);
+}
+
void TDiffACL::ClearAccess() {
NACLibProto::TDiffACE* diffACE(AddDiffACE());
- diffACE->SetDiffType(static_cast<ui32>(EDiffType::Remove));
+ diffACE->SetDiffType(static_cast<ui32>(EDiffType::Remove));
}
void TDiffACL::ClearAccessForSid(const NACLib::TSID& sid) {
NACLibProto::TDiffACE* diffACE(AddDiffACE());
- diffACE->SetDiffType(static_cast<ui32>(EDiffType::Remove));
+ diffACE->SetDiffType(static_cast<ui32>(EDiffType::Remove));
diffACE->MutableACE()->SetSID(sid);
}
-TString AccessRightsToString(ui32 accessRights) {
- switch (accessRights) {
- case EAccessRights::GenericFull: return "Full";
- case EAccessRights::GenericWrite: return "Write";
- case EAccessRights::GenericRead: return "Read";
- case EAccessRights::GenericManage: return "Manage";
- case EAccessRights::GenericUse: return "Use";
- }
+TString AccessRightsToString(ui32 accessRights) {
+ switch (accessRights) {
+ case EAccessRights::GenericFull: return "Full";
+ case EAccessRights::GenericWrite: return "Write";
+ case EAccessRights::GenericRead: return "Read";
+ case EAccessRights::GenericManage: return "Manage";
+ case EAccessRights::GenericUse: return "Use";
+ }
TVector<TStringBuf> rights;
- if (accessRights & EAccessRights::SelectRow)
- rights.emplace_back("SelectRow");
- if (accessRights & EAccessRights::UpdateRow)
- rights.emplace_back("UpdateRow");
- if (accessRights & EAccessRights::EraseRow)
- rights.emplace_back("EraseRow");
- if (accessRights & EAccessRights::ReadAttributes)
- rights.emplace_back("ReadAttributes");
- if (accessRights & EAccessRights::WriteAttributes)
- rights.emplace_back("WriteAttributes");
- if (accessRights & EAccessRights::CreateDirectory)
- rights.emplace_back("CreateDirectory");
- if (accessRights & EAccessRights::CreateTable)
- rights.emplace_back("CreateTable");
- if (accessRights & EAccessRights::CreateQueue)
- rights.emplace_back("CreateQueue");
- if (accessRights & EAccessRights::RemoveSchema)
- rights.emplace_back("RemoveSchema");
- if (accessRights & EAccessRights::DescribeSchema)
- rights.emplace_back("DescribeSchema");
- if (accessRights & EAccessRights::AlterSchema)
- rights.emplace_back("AlterSchema");
- if (accessRights & EAccessRights::CreateDatabase)
- rights.emplace_back("CreateDatabase");
- if (accessRights & EAccessRights::DropDatabase)
- rights.emplace_back("DropDatabase");
- if (accessRights & EAccessRights::GrantAccessRights)
- rights.emplace_back("GrantAccessRights");
+ if (accessRights & EAccessRights::SelectRow)
+ rights.emplace_back("SelectRow");
+ if (accessRights & EAccessRights::UpdateRow)
+ rights.emplace_back("UpdateRow");
+ if (accessRights & EAccessRights::EraseRow)
+ rights.emplace_back("EraseRow");
+ if (accessRights & EAccessRights::ReadAttributes)
+ rights.emplace_back("ReadAttributes");
+ if (accessRights & EAccessRights::WriteAttributes)
+ rights.emplace_back("WriteAttributes");
+ if (accessRights & EAccessRights::CreateDirectory)
+ rights.emplace_back("CreateDirectory");
+ if (accessRights & EAccessRights::CreateTable)
+ rights.emplace_back("CreateTable");
+ if (accessRights & EAccessRights::CreateQueue)
+ rights.emplace_back("CreateQueue");
+ if (accessRights & EAccessRights::RemoveSchema)
+ rights.emplace_back("RemoveSchema");
+ if (accessRights & EAccessRights::DescribeSchema)
+ rights.emplace_back("DescribeSchema");
+ if (accessRights & EAccessRights::AlterSchema)
+ rights.emplace_back("AlterSchema");
+ if (accessRights & EAccessRights::CreateDatabase)
+ rights.emplace_back("CreateDatabase");
+ if (accessRights & EAccessRights::DropDatabase)
+ rights.emplace_back("DropDatabase");
+ if (accessRights & EAccessRights::GrantAccessRights)
+ rights.emplace_back("GrantAccessRights");
if (accessRights & EAccessRights::WriteUserAttributes)
rights.emplace_back("WriteUserAttributes");
if (accessRights & EAccessRights::ConnectDatabase)
rights.emplace_back("ConnectDatabase");
- TString result;
- for (auto it = rights.begin(); it != rights.end(); ++it) {
- if (it != rights.begin()) {
- result += '|';
- }
- result += *it;
- }
- return result;
-}
-
-}
+ TString result;
+ for (auto it = rights.begin(); it != rights.end(); ++it) {
+ if (it != rights.begin()) {
+ result += '|';
+ }
+ result += *it;
+ }
+ return result;
+}
+
+}
diff --git a/ydb/library/aclib/aclib.h b/ydb/library/aclib/aclib.h
index 7bc93fa0b99..655ca4b6693 100644
--- a/ydb/library/aclib/aclib.h
+++ b/ydb/library/aclib/aclib.h
@@ -1,159 +1,159 @@
-#pragma once
-#include <util/generic/vector.h>
-#include <util/generic/hash_set.h>
-#include <util/datetime/base.h>
+#pragma once
+#include <util/generic/vector.h>
+#include <util/generic/hash_set.h>
+#include <util/datetime/base.h>
#include <ydb/library/aclib/protos/aclib.pb.h>
-
-namespace NACLib {
-
-#define BUILTIN_ACL_DOMAIN "builtin"
-#define BUILTIN_ACL_ROOT "root@" BUILTIN_ACL_DOMAIN
+
+namespace NACLib {
+
+#define BUILTIN_ACL_DOMAIN "builtin"
+#define BUILTIN_ACL_ROOT "root@" BUILTIN_ACL_DOMAIN
#define BUILTIN_ERROR_DOMAIN "error"
-
-enum EAccessRights : ui32 { // bitmask
- NoAccess = 0x00000000,
- SelectRow = 0x00000001, // select row from table
- UpdateRow = 0x00000002, // update row in table
- EraseRow = 0x00000004, // erase row from table
- ReadAttributes = 0x00000008, // read attributes / ACL
- WriteAttributes = 0x00000010, // modify attributes / ACL
- CreateDirectory = 0x00000020, // create subdirectory
- CreateTable = 0x00000040, // create table
- CreateQueue = 0x00000080, // create queue
- RemoveSchema = 0x00000100, // remove object
- DescribeSchema = 0x00000200, // describe schema object
- AlterSchema = 0x00000400, // modify schema
- CreateDatabase = 0x00000800, // create database
- DropDatabase = 0x00001000, // drop database
- GrantAccessRights = 0x00002000, // grant access rights (only own access rights)
+
+enum EAccessRights : ui32 { // bitmask
+ NoAccess = 0x00000000,
+ SelectRow = 0x00000001, // select row from table
+ UpdateRow = 0x00000002, // update row in table
+ EraseRow = 0x00000004, // erase row from table
+ ReadAttributes = 0x00000008, // read attributes / ACL
+ WriteAttributes = 0x00000010, // modify attributes / ACL
+ CreateDirectory = 0x00000020, // create subdirectory
+ CreateTable = 0x00000040, // create table
+ CreateQueue = 0x00000080, // create queue
+ RemoveSchema = 0x00000100, // remove object
+ DescribeSchema = 0x00000200, // describe schema object
+ AlterSchema = 0x00000400, // modify schema
+ CreateDatabase = 0x00000800, // create database
+ DropDatabase = 0x00001000, // drop database
+ GrantAccessRights = 0x00002000, // grant access rights (only own access rights)
WriteUserAttributes = 0x00004000, // modify user attributes / KV
ConnectDatabase = 0x00008000, // any type of request to DB
ReadStream = 0x00010000, // reading streams
WriteStream = 0x00020000, // writing streams
ReadTopic = 0x00040000, // reading topics
WritTopic = 0x00080000, // writing topics
-
+
GenericRead = SelectRow | ReadAttributes | DescribeSchema,
GenericWrite = UpdateRow | EraseRow | WriteAttributes | CreateDirectory | CreateTable | CreateQueue | RemoveSchema | AlterSchema | WriteUserAttributes,
- GenericUse = GenericRead | GenericWrite | GrantAccessRights,
+ GenericUse = GenericRead | GenericWrite | GrantAccessRights,
GenericManage = CreateDatabase | DropDatabase,
- GenericFull = GenericUse | GenericManage,
-};
-
-TString AccessRightsToString(ui32 accessRights);
-
-enum class EAccessType : ui32 {
- Deny,
- Allow,
-};
-
-enum EInheritanceType : ui32 { // bitmask
+ GenericFull = GenericUse | GenericManage,
+};
+
+TString AccessRightsToString(ui32 accessRights);
+
+enum class EAccessType : ui32 {
+ Deny,
+ Allow,
+};
+
+enum EInheritanceType : ui32 { // bitmask
InheritNone = 0x00,
- InheritObject = 0x01, // this ACE will inherit on child objects
- InheritContainer = 0x02, // this ACE will inherit on child containers
- InheritOnly = 0x04, // this ACE will not be used for access checking but for inheritance only
-};
-
-enum class EDiffType : ui32 {
- Add,
- Remove,
-};
-
+ InheritObject = 0x01, // this ACE will inherit on child objects
+ InheritContainer = 0x02, // this ACE will inherit on child containers
+ InheritOnly = 0x04, // this ACE will not be used for access checking but for inheritance only
+};
+
+enum class EDiffType : ui32 {
+ Add,
+ Remove,
+};
+
using TSID = TString;
-
-class TUserToken : protected NACLibProto::TUserToken, public TThrRefBase {
-public:
- struct TUserTokenInitFields {
- TString OriginalUserToken;
- TString UserSID;
- TVector<TString> GroupSIDs;
- TString AuthType;
- };
-
- TUserToken(TUserTokenInitFields fields);
- TUserToken(const TVector<TSID>& userAndGroupSIDs);
+
+class TUserToken : protected NACLibProto::TUserToken, public TThrRefBase {
+public:
+ struct TUserTokenInitFields {
+ TString OriginalUserToken;
+ TString UserSID;
+ TVector<TString> GroupSIDs;
+ TString AuthType;
+ };
+
+ TUserToken(TUserTokenInitFields fields);
+ TUserToken(const TVector<TSID>& userAndGroupSIDs);
TUserToken(const TSID& userSID, const TVector<TSID>& groupSIDs);
- TUserToken(const TString& originalUserToken, const TSID& userSID, const TVector<TSID>& groupSIDs);
- TUserToken(const NACLibProto::TUserToken& token);
- TUserToken(NACLibProto::TUserToken&& token);
+ TUserToken(const TString& originalUserToken, const TSID& userSID, const TVector<TSID>& groupSIDs);
+ TUserToken(const NACLibProto::TUserToken& token);
+ TUserToken(NACLibProto::TUserToken&& token);
TUserToken(const TString& token);
- bool IsExist(const TSID& someSID) const; // check for presence of SID specified in the token
- TSID GetUserSID() const;
+ bool IsExist(const TSID& someSID) const; // check for presence of SID specified in the token
+ TSID GetUserSID() const;
TVector<TSID> GetGroupSIDs() const;
- TString GetOriginalUserToken() const;
+ TString GetOriginalUserToken() const;
TString SerializeAsString() const;
- void AddGroupSID(const TSID& groupSID);
+ void AddGroupSID(const TSID& groupSID);
using NACLibProto::TUserToken::ShortDebugString;
-
-protected:
- static TSID GetUserFromVector(const TVector<TSID>& userAndGroupSIDs);
- static TVector<TSID> GetGroupsFromVector(const TVector<TSID>& userAndGroupSIDs);
- void SetGroupSIDs(const TVector<TString>& groupSIDs);
-};
-
-class TACL : public NACLibProto::TACL {
-public:
- TACL() = default;
+
+protected:
+ static TSID GetUserFromVector(const TVector<TSID>& userAndGroupSIDs);
+ static TVector<TSID> GetGroupsFromVector(const TVector<TSID>& userAndGroupSIDs);
+ void SetGroupSIDs(const TVector<TString>& groupSIDs);
+};
+
+class TACL : public NACLibProto::TACL {
+public:
+ TACL() = default;
TACL(const TString& string); // proto format
- std::pair<ui32, ui32> AddAccess(EAccessType type, ui32 access, const TSID& sid, ui32 inheritance = InheritObject | InheritContainer);
- std::pair<ui32, ui32> RemoveAccess(NACLib::EAccessType type, ui32 access, const NACLib::TSID& sid, ui32 inheritance = InheritObject | InheritContainer);
- std::pair<ui32, ui32> RemoveAccess(const NACLibProto::TACE& filter);
- std::pair<ui32, ui32> ClearAccess();
- std::pair<ui32, ui32> ApplyDiff(const NACLibProto::TDiffACL& diffACL);
- NACLibProto::TACL GetImmediateACL() const;
+ std::pair<ui32, ui32> AddAccess(EAccessType type, ui32 access, const TSID& sid, ui32 inheritance = InheritObject | InheritContainer);
+ std::pair<ui32, ui32> RemoveAccess(NACLib::EAccessType type, ui32 access, const NACLib::TSID& sid, ui32 inheritance = InheritObject | InheritContainer);
+ std::pair<ui32, ui32> RemoveAccess(const NACLibProto::TACE& filter);
+ std::pair<ui32, ui32> ClearAccess();
+ std::pair<ui32, ui32> ApplyDiff(const NACLibProto::TDiffACL& diffACL);
+ NACLibProto::TACL GetImmediateACL() const;
TString ToString() const; // simple text format
void FromString(const TString& string); // simple text format
static TString ToString(const NACLibProto::TACE& ace);
static void FromString(NACLibProto::TACE& ace, const TString& string);
-
-protected:
- static ui32 SpecialRightsFromString(const TString& string);
-
- void SortACL();
-};
-
-class TDiffACL : public NACLibProto::TDiffACL {
-public:
- TDiffACL() = default;
+
+protected:
+ static ui32 SpecialRightsFromString(const TString& string);
+
+ void SortACL();
+};
+
+class TDiffACL : public NACLibProto::TDiffACL {
+public:
+ TDiffACL() = default;
TDiffACL(const TString& string);
- void AddAccess(EAccessType type, ui32 access, const TSID& sid, ui32 inheritance = InheritObject | InheritContainer);
- void RemoveAccess(NACLib::EAccessType type, ui32 access, const NACLib::TSID& sid, ui32 inheritance = InheritObject | InheritContainer);
- void AddAccess(const NACLibProto::TACE& access);
- void RemoveAccess(const NACLibProto::TACE& access);
+ void AddAccess(EAccessType type, ui32 access, const TSID& sid, ui32 inheritance = InheritObject | InheritContainer);
+ void RemoveAccess(NACLib::EAccessType type, ui32 access, const NACLib::TSID& sid, ui32 inheritance = InheritObject | InheritContainer);
+ void AddAccess(const NACLibProto::TACE& access);
+ void RemoveAccess(const NACLibProto::TACE& access);
void ClearAccess();
void ClearAccessForSid(const NACLib::TSID& sid);
-};
-
-class TSecurityObject : public NACLibProto::TSecurityObject {
-public:
- static_assert(sizeof(TACL) == sizeof(NACLibProto::TACL), "TACL class should be empty to cast from proto type");
-
- TSecurityObject(const NACLibProto::TSecurityObject& protoSecObj, bool isContainer); // creating from existing object
- TSecurityObject(const TSID& owner, bool isContainer); // creating new object
- TSecurityObject(); // creating new object for ACL manipulation only
- bool CheckAccess(ui32 access, const TUserToken& user) const; // check for access requested
- bool CheckGrantAccess(const NACLibProto::TDiffACL& diffACL, const TUserToken& user) const; // check for valid diffACL
- ui32 GetEffectiveAccessRights(const TUserToken& user) const;
- TSecurityObject MergeWithParent(const NACLibProto::TSecurityObject& parent) const; // returns effective ACL as result of merging parent with this
- NACLibProto::TACL GetImmediateACL() const;
- void AddAccess(EAccessType type, ui32 access, const TSID& sid, ui32 inheritance = InheritObject | InheritContainer);
- void RemoveAccess(NACLib::EAccessType type, ui32 access, const NACLib::TSID& sid, ui32 inheritance = InheritObject | InheritContainer);
- void ApplyDiff(const NACLibProto::TDiffACL& diffACL);
+};
+
+class TSecurityObject : public NACLibProto::TSecurityObject {
+public:
+ static_assert(sizeof(TACL) == sizeof(NACLibProto::TACL), "TACL class should be empty to cast from proto type");
+
+ TSecurityObject(const NACLibProto::TSecurityObject& protoSecObj, bool isContainer); // creating from existing object
+ TSecurityObject(const TSID& owner, bool isContainer); // creating new object
+ TSecurityObject(); // creating new object for ACL manipulation only
+ bool CheckAccess(ui32 access, const TUserToken& user) const; // check for access requested
+ bool CheckGrantAccess(const NACLibProto::TDiffACL& diffACL, const TUserToken& user) const; // check for valid diffACL
+ ui32 GetEffectiveAccessRights(const TUserToken& user) const;
+ TSecurityObject MergeWithParent(const NACLibProto::TSecurityObject& parent) const; // returns effective ACL as result of merging parent with this
+ NACLibProto::TACL GetImmediateACL() const;
+ void AddAccess(EAccessType type, ui32 access, const TSID& sid, ui32 inheritance = InheritObject | InheritContainer);
+ void RemoveAccess(NACLib::EAccessType type, ui32 access, const NACLib::TSID& sid, ui32 inheritance = InheritObject | InheritContainer);
+ void ApplyDiff(const NACLibProto::TDiffACL& diffACL);
void ClearAccess();
- TInstant GetExpireTime() const;
+ TInstant GetExpireTime() const;
TString ToString() const; // simple text format
void FromString(const TString& string); // simple text format
bool operator == (const TSecurityObject& rhs) const;
bool operator != (const TSecurityObject& rhs) const;
-
-protected:
- bool IsContainer;
-};
-
-
-
-
-
-
-}
+
+protected:
+ bool IsContainer;
+};
+
+
+
+
+
+
+}
diff --git a/ydb/library/aclib/aclib_ut.cpp b/ydb/library/aclib/aclib_ut.cpp
index 5dcd5275439..c5828f86244 100644
--- a/ydb/library/aclib/aclib_ut.cpp
+++ b/ydb/library/aclib/aclib_ut.cpp
@@ -1,9 +1,9 @@
#include <library/cpp/testing/unittest/registar.h>
#include <library/cpp/string_utils/base64/base64.h>
-#include "aclib.h"
-
-using namespace NACLib;
-
+#include "aclib.h"
+
+using namespace NACLib;
+
Y_UNIT_TEST_SUITE(ACLib) {
static const TString James = "james@bookstore";
static const TVector<TString> JamesGroups = {"Humans", "Administrators"};
@@ -11,147 +11,147 @@ Y_UNIT_TEST_SUITE(ACLib) {
static const TVector<TString> CatGroups = {"Animals", "Cats", "Readers"};
static const TString Dog = "dog@bookstore";
static const TVector<TString> DogGroups = {"Animals", "Dogs", "Writers"};
-
+
Y_UNIT_TEST(TestUsers) {
- TSecurityObject rootACL(James, true);
-
- rootACL.AddAccess(EAccessType::Allow, EAccessRights::GenericRead, Cat, EInheritanceType::InheritContainer);
- rootACL.AddAccess(EAccessType::Allow, EAccessRights::GenericFull, Dog, EInheritanceType::InheritContainer);
-
+ TSecurityObject rootACL(James, true);
+
+ rootACL.AddAccess(EAccessType::Allow, EAccessRights::GenericRead, Cat, EInheritanceType::InheritContainer);
+ rootACL.AddAccess(EAccessType::Allow, EAccessRights::GenericFull, Dog, EInheritanceType::InheritContainer);
+
TUserToken jamesToken(James, TVector<TSID>());
TUserToken catToken(Cat, TVector<TSID>());
TUserToken dogToken(Dog, TVector<TSID>());
-
- UNIT_ASSERT(rootACL.CheckAccess(EAccessRights::SelectRow, jamesToken) == true);
- UNIT_ASSERT(rootACL.CheckAccess(EAccessRights::SelectRow, catToken) == true);
- UNIT_ASSERT(rootACL.CheckAccess(EAccessRights::SelectRow, dogToken) == true);
- UNIT_ASSERT(rootACL.CheckAccess(EAccessRights::UpdateRow, jamesToken) == true);
- UNIT_ASSERT(rootACL.CheckAccess(EAccessRights::UpdateRow, catToken) == false);
- UNIT_ASSERT(rootACL.CheckAccess(EAccessRights::UpdateRow, dogToken) == true);
-
- TSecurityObject dogFilesACL(Dog, true);
- TSecurityObject effectiveDogFilesACL(dogFilesACL.MergeWithParent(rootACL));
- UNIT_ASSERT(effectiveDogFilesACL.CheckAccess(EAccessRights::SelectRow, jamesToken) == false);
- UNIT_ASSERT(effectiveDogFilesACL.CheckAccess(EAccessRights::SelectRow, catToken) == true);
- UNIT_ASSERT(effectiveDogFilesACL.CheckAccess(EAccessRights::SelectRow, dogToken) == true);
- UNIT_ASSERT(effectiveDogFilesACL.CheckAccess(EAccessRights::UpdateRow, jamesToken) == false);
- UNIT_ASSERT(effectiveDogFilesACL.CheckAccess(EAccessRights::UpdateRow, catToken) == false);
- UNIT_ASSERT(effectiveDogFilesACL.CheckAccess(EAccessRights::UpdateRow, dogToken) == true);
-
- TSecurityObject catFilesACL(Cat, true);
- TSecurityObject effectiveCatFilesACL(catFilesACL.MergeWithParent(rootACL));
- UNIT_ASSERT(effectiveCatFilesACL.CheckAccess(EAccessRights::SelectRow, jamesToken) == false);
- UNIT_ASSERT(effectiveCatFilesACL.CheckAccess(EAccessRights::SelectRow, catToken) == true);
- UNIT_ASSERT(effectiveCatFilesACL.CheckAccess(EAccessRights::SelectRow, dogToken) == true);
- UNIT_ASSERT(effectiveCatFilesACL.CheckAccess(EAccessRights::UpdateRow, jamesToken) == false);
- UNIT_ASSERT(effectiveCatFilesACL.CheckAccess(EAccessRights::UpdateRow, catToken) == true);
- UNIT_ASSERT(effectiveCatFilesACL.CheckAccess(EAccessRights::UpdateRow, dogToken) == true);
-
- TSecurityObject dogFileACL(Dog, true);
- TSecurityObject effectiveDogFileACL(dogFileACL.MergeWithParent(dogFilesACL));
- UNIT_ASSERT(effectiveDogFileACL.CheckAccess(EAccessRights::SelectRow, jamesToken) == false);
- UNIT_ASSERT(effectiveDogFileACL.CheckAccess(EAccessRights::SelectRow, catToken) == false);
- UNIT_ASSERT(effectiveDogFileACL.CheckAccess(EAccessRights::SelectRow, dogToken) == true);
- UNIT_ASSERT(effectiveDogFileACL.CheckAccess(EAccessRights::UpdateRow, jamesToken) == false);
- UNIT_ASSERT(effectiveDogFileACL.CheckAccess(EAccessRights::UpdateRow, catToken) == false);
- UNIT_ASSERT(effectiveDogFileACL.CheckAccess(EAccessRights::UpdateRow, dogToken) == true);
-
- TSecurityObject catFileACL(Cat, true);
- TSecurityObject effectiveCatFileACL(catFileACL.MergeWithParent(catFilesACL));
- UNIT_ASSERT(effectiveCatFileACL.CheckAccess(EAccessRights::SelectRow, jamesToken) == false);
- UNIT_ASSERT(effectiveCatFileACL.CheckAccess(EAccessRights::SelectRow, catToken) == true);
- UNIT_ASSERT(effectiveCatFileACL.CheckAccess(EAccessRights::SelectRow, dogToken) == false);
- UNIT_ASSERT(effectiveCatFileACL.CheckAccess(EAccessRights::UpdateRow, jamesToken) == false);
- UNIT_ASSERT(effectiveCatFileACL.CheckAccess(EAccessRights::UpdateRow, catToken) == true);
- UNIT_ASSERT(effectiveCatFileACL.CheckAccess(EAccessRights::UpdateRow, dogToken) == false);
- }
-
+
+ UNIT_ASSERT(rootACL.CheckAccess(EAccessRights::SelectRow, jamesToken) == true);
+ UNIT_ASSERT(rootACL.CheckAccess(EAccessRights::SelectRow, catToken) == true);
+ UNIT_ASSERT(rootACL.CheckAccess(EAccessRights::SelectRow, dogToken) == true);
+ UNIT_ASSERT(rootACL.CheckAccess(EAccessRights::UpdateRow, jamesToken) == true);
+ UNIT_ASSERT(rootACL.CheckAccess(EAccessRights::UpdateRow, catToken) == false);
+ UNIT_ASSERT(rootACL.CheckAccess(EAccessRights::UpdateRow, dogToken) == true);
+
+ TSecurityObject dogFilesACL(Dog, true);
+ TSecurityObject effectiveDogFilesACL(dogFilesACL.MergeWithParent(rootACL));
+ UNIT_ASSERT(effectiveDogFilesACL.CheckAccess(EAccessRights::SelectRow, jamesToken) == false);
+ UNIT_ASSERT(effectiveDogFilesACL.CheckAccess(EAccessRights::SelectRow, catToken) == true);
+ UNIT_ASSERT(effectiveDogFilesACL.CheckAccess(EAccessRights::SelectRow, dogToken) == true);
+ UNIT_ASSERT(effectiveDogFilesACL.CheckAccess(EAccessRights::UpdateRow, jamesToken) == false);
+ UNIT_ASSERT(effectiveDogFilesACL.CheckAccess(EAccessRights::UpdateRow, catToken) == false);
+ UNIT_ASSERT(effectiveDogFilesACL.CheckAccess(EAccessRights::UpdateRow, dogToken) == true);
+
+ TSecurityObject catFilesACL(Cat, true);
+ TSecurityObject effectiveCatFilesACL(catFilesACL.MergeWithParent(rootACL));
+ UNIT_ASSERT(effectiveCatFilesACL.CheckAccess(EAccessRights::SelectRow, jamesToken) == false);
+ UNIT_ASSERT(effectiveCatFilesACL.CheckAccess(EAccessRights::SelectRow, catToken) == true);
+ UNIT_ASSERT(effectiveCatFilesACL.CheckAccess(EAccessRights::SelectRow, dogToken) == true);
+ UNIT_ASSERT(effectiveCatFilesACL.CheckAccess(EAccessRights::UpdateRow, jamesToken) == false);
+ UNIT_ASSERT(effectiveCatFilesACL.CheckAccess(EAccessRights::UpdateRow, catToken) == true);
+ UNIT_ASSERT(effectiveCatFilesACL.CheckAccess(EAccessRights::UpdateRow, dogToken) == true);
+
+ TSecurityObject dogFileACL(Dog, true);
+ TSecurityObject effectiveDogFileACL(dogFileACL.MergeWithParent(dogFilesACL));
+ UNIT_ASSERT(effectiveDogFileACL.CheckAccess(EAccessRights::SelectRow, jamesToken) == false);
+ UNIT_ASSERT(effectiveDogFileACL.CheckAccess(EAccessRights::SelectRow, catToken) == false);
+ UNIT_ASSERT(effectiveDogFileACL.CheckAccess(EAccessRights::SelectRow, dogToken) == true);
+ UNIT_ASSERT(effectiveDogFileACL.CheckAccess(EAccessRights::UpdateRow, jamesToken) == false);
+ UNIT_ASSERT(effectiveDogFileACL.CheckAccess(EAccessRights::UpdateRow, catToken) == false);
+ UNIT_ASSERT(effectiveDogFileACL.CheckAccess(EAccessRights::UpdateRow, dogToken) == true);
+
+ TSecurityObject catFileACL(Cat, true);
+ TSecurityObject effectiveCatFileACL(catFileACL.MergeWithParent(catFilesACL));
+ UNIT_ASSERT(effectiveCatFileACL.CheckAccess(EAccessRights::SelectRow, jamesToken) == false);
+ UNIT_ASSERT(effectiveCatFileACL.CheckAccess(EAccessRights::SelectRow, catToken) == true);
+ UNIT_ASSERT(effectiveCatFileACL.CheckAccess(EAccessRights::SelectRow, dogToken) == false);
+ UNIT_ASSERT(effectiveCatFileACL.CheckAccess(EAccessRights::UpdateRow, jamesToken) == false);
+ UNIT_ASSERT(effectiveCatFileACL.CheckAccess(EAccessRights::UpdateRow, catToken) == true);
+ UNIT_ASSERT(effectiveCatFileACL.CheckAccess(EAccessRights::UpdateRow, dogToken) == false);
+ }
+
Y_UNIT_TEST(TestGroups) {
- TSecurityObject rootACL(James, true);
-
- rootACL.AddAccess(EAccessType::Allow, EAccessRights::GenericRead, "Readers", EInheritanceType::InheritContainer | EInheritanceType::InheritObject);
- rootACL.AddAccess(EAccessType::Allow, EAccessRights::GenericFull, "Writers", EInheritanceType::InheritContainer | EInheritanceType::InheritObject);
-
- TUserToken jamesToken(James, JamesGroups);
- TUserToken catToken(Cat, CatGroups);
- TUserToken dogToken(Dog, DogGroups);
-
- UNIT_ASSERT(rootACL.CheckAccess(EAccessRights::SelectRow, jamesToken) == true); // owner
- UNIT_ASSERT(rootACL.CheckAccess(EAccessRights::SelectRow, catToken) == true); // readers
- UNIT_ASSERT(rootACL.CheckAccess(EAccessRights::SelectRow, dogToken) == true); // writers
- UNIT_ASSERT(rootACL.CheckAccess(EAccessRights::UpdateRow, jamesToken) == true); // owner
- UNIT_ASSERT(rootACL.CheckAccess(EAccessRights::UpdateRow, catToken) == false); // readers
- UNIT_ASSERT(rootACL.CheckAccess(EAccessRights::UpdateRow, dogToken) == true); // writers
-
- TSecurityObject dogFilesACL(Dog, true);
- TSecurityObject effectiveDogFilesACL(dogFilesACL.MergeWithParent(rootACL));
- UNIT_ASSERT(effectiveDogFilesACL.CheckAccess(EAccessRights::SelectRow, jamesToken) == false);
- UNIT_ASSERT(effectiveDogFilesACL.CheckAccess(EAccessRights::SelectRow, catToken) == true);
- UNIT_ASSERT(effectiveDogFilesACL.CheckAccess(EAccessRights::SelectRow, dogToken) == true);
- UNIT_ASSERT(effectiveDogFilesACL.CheckAccess(EAccessRights::UpdateRow, jamesToken) == false);
- UNIT_ASSERT(effectiveDogFilesACL.CheckAccess(EAccessRights::UpdateRow, catToken) == false);
- UNIT_ASSERT(effectiveDogFilesACL.CheckAccess(EAccessRights::UpdateRow, dogToken) == true);
-
- TSecurityObject catFilesACL(Cat, true);
- TSecurityObject effectiveCatFilesACL(catFilesACL.MergeWithParent(rootACL));
- UNIT_ASSERT(effectiveCatFilesACL.CheckAccess(EAccessRights::SelectRow, jamesToken) == false);
- UNIT_ASSERT(effectiveCatFilesACL.CheckAccess(EAccessRights::SelectRow, catToken) == true);
- UNIT_ASSERT(effectiveCatFilesACL.CheckAccess(EAccessRights::SelectRow, dogToken) == true);
- UNIT_ASSERT(effectiveCatFilesACL.CheckAccess(EAccessRights::UpdateRow, jamesToken) == false);
- UNIT_ASSERT(effectiveCatFilesACL.CheckAccess(EAccessRights::UpdateRow, catToken) == true);
- UNIT_ASSERT(effectiveCatFilesACL.CheckAccess(EAccessRights::UpdateRow, dogToken) == true);
-
- TSecurityObject dogFileACL(Dog, true);
- TSecurityObject effectiveDogFileACL(dogFileACL.MergeWithParent(dogFilesACL));
- UNIT_ASSERT(effectiveDogFileACL.CheckAccess(EAccessRights::SelectRow, jamesToken) == false);
- UNIT_ASSERT(effectiveDogFileACL.CheckAccess(EAccessRights::SelectRow, catToken) == false);
- UNIT_ASSERT(effectiveDogFileACL.CheckAccess(EAccessRights::SelectRow, dogToken) == true);
- UNIT_ASSERT(effectiveDogFileACL.CheckAccess(EAccessRights::UpdateRow, jamesToken) == false);
- UNIT_ASSERT(effectiveDogFileACL.CheckAccess(EAccessRights::UpdateRow, catToken) == false);
- UNIT_ASSERT(effectiveDogFileACL.CheckAccess(EAccessRights::UpdateRow, dogToken) == true);
-
- TSecurityObject catFileACL(Cat, true);
- TSecurityObject effectiveCatFileACL(catFileACL.MergeWithParent(catFilesACL));
- UNIT_ASSERT(effectiveCatFileACL.CheckAccess(EAccessRights::SelectRow, jamesToken) == false);
- UNIT_ASSERT(effectiveCatFileACL.CheckAccess(EAccessRights::SelectRow, catToken) == true);
- UNIT_ASSERT(effectiveCatFileACL.CheckAccess(EAccessRights::SelectRow, dogToken) == false);
- UNIT_ASSERT(effectiveCatFileACL.CheckAccess(EAccessRights::UpdateRow, jamesToken) == false);
- UNIT_ASSERT(effectiveCatFileACL.CheckAccess(EAccessRights::UpdateRow, catToken) == true);
- UNIT_ASSERT(effectiveCatFileACL.CheckAccess(EAccessRights::UpdateRow, dogToken) == false);
-
- TSecurityObject raceFilesACL("Root", true);
- raceFilesACL.AddAccess(EAccessType::Allow, EAccessRights::GenericRead, "Animals", EInheritanceType::InheritContainer | EInheritanceType::InheritObject);
- raceFilesACL.AddAccess(EAccessType::Allow, EAccessRights::GenericRead, "Humans", EInheritanceType::InheritContainer | EInheritanceType::InheritObject);
- TSecurityObject effectiveRaceFilesACL(raceFilesACL.MergeWithParent(rootACL));
-
- TSecurityObject humanFilesACL("SomeHuman", true);
- humanFilesACL.AddAccess(EAccessType::Allow, EAccessRights::GenericFull, "Humans", EInheritanceType::InheritContainer | EInheritanceType::InheritObject);
- humanFilesACL.AddAccess(EAccessType::Deny, EAccessRights::GenericFull, "Animals", EInheritanceType::InheritContainer | EInheritanceType::InheritObject);
- TSecurityObject effectiveHumanFilesACL(humanFilesACL.MergeWithParent(raceFilesACL));
- UNIT_ASSERT(effectiveHumanFilesACL.CheckAccess(EAccessRights::SelectRow, jamesToken) == true);
- UNIT_ASSERT(effectiveHumanFilesACL.CheckAccess(EAccessRights::SelectRow, catToken) == false);
- UNIT_ASSERT(effectiveHumanFilesACL.CheckAccess(EAccessRights::SelectRow, dogToken) == false);
- UNIT_ASSERT(effectiveHumanFilesACL.CheckAccess(EAccessRights::UpdateRow, jamesToken) == true);
- UNIT_ASSERT(effectiveHumanFilesACL.CheckAccess(EAccessRights::UpdateRow, catToken) == false);
- UNIT_ASSERT(effectiveHumanFilesACL.CheckAccess(EAccessRights::UpdateRow, dogToken) == false);
-
- TSecurityObject animalFilesACL("SomeAnimal", true);
- animalFilesACL.AddAccess(EAccessType::Allow, EAccessRights::GenericFull, "Animals", EInheritanceType::InheritContainer | EInheritanceType::InheritObject);
- animalFilesACL.AddAccess(EAccessType::Deny, EAccessRights::GenericFull, "Humans", EInheritanceType::InheritContainer | EInheritanceType::InheritObject);
- TSecurityObject effectiveAnimalFilesACL(animalFilesACL.MergeWithParent(raceFilesACL));
-
- UNIT_ASSERT(effectiveAnimalFilesACL.CheckAccess(EAccessRights::SelectRow, jamesToken) == false);
- UNIT_ASSERT(effectiveAnimalFilesACL.CheckAccess(EAccessRights::SelectRow, catToken) == true);
- UNIT_ASSERT(effectiveAnimalFilesACL.CheckAccess(EAccessRights::SelectRow, dogToken) == true);
- UNIT_ASSERT(effectiveAnimalFilesACL.CheckAccess(EAccessRights::UpdateRow, jamesToken) == false);
- UNIT_ASSERT(effectiveAnimalFilesACL.CheckAccess(EAccessRights::UpdateRow, catToken) == true);
- UNIT_ASSERT(effectiveAnimalFilesACL.CheckAccess(EAccessRights::UpdateRow, dogToken) == true);
- }
+ TSecurityObject rootACL(James, true);
+
+ rootACL.AddAccess(EAccessType::Allow, EAccessRights::GenericRead, "Readers", EInheritanceType::InheritContainer | EInheritanceType::InheritObject);
+ rootACL.AddAccess(EAccessType::Allow, EAccessRights::GenericFull, "Writers", EInheritanceType::InheritContainer | EInheritanceType::InheritObject);
+
+ TUserToken jamesToken(James, JamesGroups);
+ TUserToken catToken(Cat, CatGroups);
+ TUserToken dogToken(Dog, DogGroups);
+
+ UNIT_ASSERT(rootACL.CheckAccess(EAccessRights::SelectRow, jamesToken) == true); // owner
+ UNIT_ASSERT(rootACL.CheckAccess(EAccessRights::SelectRow, catToken) == true); // readers
+ UNIT_ASSERT(rootACL.CheckAccess(EAccessRights::SelectRow, dogToken) == true); // writers
+ UNIT_ASSERT(rootACL.CheckAccess(EAccessRights::UpdateRow, jamesToken) == true); // owner
+ UNIT_ASSERT(rootACL.CheckAccess(EAccessRights::UpdateRow, catToken) == false); // readers
+ UNIT_ASSERT(rootACL.CheckAccess(EAccessRights::UpdateRow, dogToken) == true); // writers
+
+ TSecurityObject dogFilesACL(Dog, true);
+ TSecurityObject effectiveDogFilesACL(dogFilesACL.MergeWithParent(rootACL));
+ UNIT_ASSERT(effectiveDogFilesACL.CheckAccess(EAccessRights::SelectRow, jamesToken) == false);
+ UNIT_ASSERT(effectiveDogFilesACL.CheckAccess(EAccessRights::SelectRow, catToken) == true);
+ UNIT_ASSERT(effectiveDogFilesACL.CheckAccess(EAccessRights::SelectRow, dogToken) == true);
+ UNIT_ASSERT(effectiveDogFilesACL.CheckAccess(EAccessRights::UpdateRow, jamesToken) == false);
+ UNIT_ASSERT(effectiveDogFilesACL.CheckAccess(EAccessRights::UpdateRow, catToken) == false);
+ UNIT_ASSERT(effectiveDogFilesACL.CheckAccess(EAccessRights::UpdateRow, dogToken) == true);
+
+ TSecurityObject catFilesACL(Cat, true);
+ TSecurityObject effectiveCatFilesACL(catFilesACL.MergeWithParent(rootACL));
+ UNIT_ASSERT(effectiveCatFilesACL.CheckAccess(EAccessRights::SelectRow, jamesToken) == false);
+ UNIT_ASSERT(effectiveCatFilesACL.CheckAccess(EAccessRights::SelectRow, catToken) == true);
+ UNIT_ASSERT(effectiveCatFilesACL.CheckAccess(EAccessRights::SelectRow, dogToken) == true);
+ UNIT_ASSERT(effectiveCatFilesACL.CheckAccess(EAccessRights::UpdateRow, jamesToken) == false);
+ UNIT_ASSERT(effectiveCatFilesACL.CheckAccess(EAccessRights::UpdateRow, catToken) == true);
+ UNIT_ASSERT(effectiveCatFilesACL.CheckAccess(EAccessRights::UpdateRow, dogToken) == true);
+
+ TSecurityObject dogFileACL(Dog, true);
+ TSecurityObject effectiveDogFileACL(dogFileACL.MergeWithParent(dogFilesACL));
+ UNIT_ASSERT(effectiveDogFileACL.CheckAccess(EAccessRights::SelectRow, jamesToken) == false);
+ UNIT_ASSERT(effectiveDogFileACL.CheckAccess(EAccessRights::SelectRow, catToken) == false);
+ UNIT_ASSERT(effectiveDogFileACL.CheckAccess(EAccessRights::SelectRow, dogToken) == true);
+ UNIT_ASSERT(effectiveDogFileACL.CheckAccess(EAccessRights::UpdateRow, jamesToken) == false);
+ UNIT_ASSERT(effectiveDogFileACL.CheckAccess(EAccessRights::UpdateRow, catToken) == false);
+ UNIT_ASSERT(effectiveDogFileACL.CheckAccess(EAccessRights::UpdateRow, dogToken) == true);
+
+ TSecurityObject catFileACL(Cat, true);
+ TSecurityObject effectiveCatFileACL(catFileACL.MergeWithParent(catFilesACL));
+ UNIT_ASSERT(effectiveCatFileACL.CheckAccess(EAccessRights::SelectRow, jamesToken) == false);
+ UNIT_ASSERT(effectiveCatFileACL.CheckAccess(EAccessRights::SelectRow, catToken) == true);
+ UNIT_ASSERT(effectiveCatFileACL.CheckAccess(EAccessRights::SelectRow, dogToken) == false);
+ UNIT_ASSERT(effectiveCatFileACL.CheckAccess(EAccessRights::UpdateRow, jamesToken) == false);
+ UNIT_ASSERT(effectiveCatFileACL.CheckAccess(EAccessRights::UpdateRow, catToken) == true);
+ UNIT_ASSERT(effectiveCatFileACL.CheckAccess(EAccessRights::UpdateRow, dogToken) == false);
+
+ TSecurityObject raceFilesACL("Root", true);
+ raceFilesACL.AddAccess(EAccessType::Allow, EAccessRights::GenericRead, "Animals", EInheritanceType::InheritContainer | EInheritanceType::InheritObject);
+ raceFilesACL.AddAccess(EAccessType::Allow, EAccessRights::GenericRead, "Humans", EInheritanceType::InheritContainer | EInheritanceType::InheritObject);
+ TSecurityObject effectiveRaceFilesACL(raceFilesACL.MergeWithParent(rootACL));
+
+ TSecurityObject humanFilesACL("SomeHuman", true);
+ humanFilesACL.AddAccess(EAccessType::Allow, EAccessRights::GenericFull, "Humans", EInheritanceType::InheritContainer | EInheritanceType::InheritObject);
+ humanFilesACL.AddAccess(EAccessType::Deny, EAccessRights::GenericFull, "Animals", EInheritanceType::InheritContainer | EInheritanceType::InheritObject);
+ TSecurityObject effectiveHumanFilesACL(humanFilesACL.MergeWithParent(raceFilesACL));
+ UNIT_ASSERT(effectiveHumanFilesACL.CheckAccess(EAccessRights::SelectRow, jamesToken) == true);
+ UNIT_ASSERT(effectiveHumanFilesACL.CheckAccess(EAccessRights::SelectRow, catToken) == false);
+ UNIT_ASSERT(effectiveHumanFilesACL.CheckAccess(EAccessRights::SelectRow, dogToken) == false);
+ UNIT_ASSERT(effectiveHumanFilesACL.CheckAccess(EAccessRights::UpdateRow, jamesToken) == true);
+ UNIT_ASSERT(effectiveHumanFilesACL.CheckAccess(EAccessRights::UpdateRow, catToken) == false);
+ UNIT_ASSERT(effectiveHumanFilesACL.CheckAccess(EAccessRights::UpdateRow, dogToken) == false);
+
+ TSecurityObject animalFilesACL("SomeAnimal", true);
+ animalFilesACL.AddAccess(EAccessType::Allow, EAccessRights::GenericFull, "Animals", EInheritanceType::InheritContainer | EInheritanceType::InheritObject);
+ animalFilesACL.AddAccess(EAccessType::Deny, EAccessRights::GenericFull, "Humans", EInheritanceType::InheritContainer | EInheritanceType::InheritObject);
+ TSecurityObject effectiveAnimalFilesACL(animalFilesACL.MergeWithParent(raceFilesACL));
+
+ UNIT_ASSERT(effectiveAnimalFilesACL.CheckAccess(EAccessRights::SelectRow, jamesToken) == false);
+ UNIT_ASSERT(effectiveAnimalFilesACL.CheckAccess(EAccessRights::SelectRow, catToken) == true);
+ UNIT_ASSERT(effectiveAnimalFilesACL.CheckAccess(EAccessRights::SelectRow, dogToken) == true);
+ UNIT_ASSERT(effectiveAnimalFilesACL.CheckAccess(EAccessRights::UpdateRow, jamesToken) == false);
+ UNIT_ASSERT(effectiveAnimalFilesACL.CheckAccess(EAccessRights::UpdateRow, catToken) == true);
+ UNIT_ASSERT(effectiveAnimalFilesACL.CheckAccess(EAccessRights::UpdateRow, dogToken) == true);
+ }
Y_UNIT_TEST(TestDiffACL) {
TUserToken jamesToken(James, TVector<TSID>());
TUserToken catToken(Cat, TVector<TSID>());
- TUserToken dogToken(Dog, TVector<TSID>());
+ TUserToken dogToken(Dog, TVector<TSID>());
TSecurityObject objACL(James, true /* container */);
TDiffACL addAccessDiff;
@@ -159,10 +159,10 @@ Y_UNIT_TEST_SUITE(ACLib) {
addAccessDiff.AddAccess(EAccessType::Allow, EAccessRights::UpdateRow, Cat, EInheritanceType::InheritContainer);
addAccessDiff.AddAccess(EAccessType::Allow, EAccessRights::SelectRow, Cat, EInheritanceType::InheritContainer);
addAccessDiff.AddAccess(EAccessType::Allow, EAccessRights::AlterSchema, Cat, EInheritanceType::InheritContainer);
- addAccessDiff.AddAccess(EAccessType::Allow, EAccessRights::CreateQueue, Dog, EInheritanceType::InheritContainer);
- addAccessDiff.AddAccess(EAccessType::Allow, EAccessRights::UpdateRow, Dog, EInheritanceType::InheritContainer);
- addAccessDiff.AddAccess(EAccessType::Allow, EAccessRights::SelectRow, Dog, EInheritanceType::InheritContainer);
- addAccessDiff.AddAccess(EAccessType::Allow, EAccessRights::AlterSchema, Dog, EInheritanceType::InheritContainer);
+ addAccessDiff.AddAccess(EAccessType::Allow, EAccessRights::CreateQueue, Dog, EInheritanceType::InheritContainer);
+ addAccessDiff.AddAccess(EAccessType::Allow, EAccessRights::UpdateRow, Dog, EInheritanceType::InheritContainer);
+ addAccessDiff.AddAccess(EAccessType::Allow, EAccessRights::SelectRow, Dog, EInheritanceType::InheritContainer);
+ addAccessDiff.AddAccess(EAccessType::Allow, EAccessRights::AlterSchema, Dog, EInheritanceType::InheritContainer);
objACL.ApplyDiff(addAccessDiff);
UNIT_ASSERT(objACL.CheckAccess(EAccessRights::CreateQueue, catToken) == true);
@@ -196,97 +196,97 @@ Y_UNIT_TEST_SUITE(ACLib) {
UNIT_ASSERT(objACL.CheckAccess(EAccessRights::AlterSchema, catToken) == false);
UNIT_ASSERT(objACL.CheckAccess(EAccessRights::ReadAttributes, catToken) == false);
UNIT_ASSERT(objACL.CheckAccess(EAccessRights::WriteAttributes, catToken) == false);
-
- UNIT_ASSERT(objACL.CheckAccess(EAccessRights::CreateQueue, dogToken) == true);
- UNIT_ASSERT(objACL.CheckAccess(EAccessRights::UpdateRow, dogToken) == true);
- UNIT_ASSERT(objACL.CheckAccess(EAccessRights::SelectRow, dogToken) == true);
- UNIT_ASSERT(objACL.CheckAccess(EAccessRights::AlterSchema, dogToken) == true);
-
- TDiffACL removeAccessDiff3;
- removeAccessDiff3.ClearAccessForSid(Dog);
- objACL.ApplyDiff(removeAccessDiff3);
-
- UNIT_ASSERT(objACL.CheckAccess(EAccessRights::CreateQueue, dogToken) == false);
- UNIT_ASSERT(objACL.CheckAccess(EAccessRights::UpdateRow, dogToken) == false);
- UNIT_ASSERT(objACL.CheckAccess(EAccessRights::SelectRow, dogToken) == false);
- UNIT_ASSERT(objACL.CheckAccess(EAccessRights::AlterSchema, dogToken) == false);
+
+ UNIT_ASSERT(objACL.CheckAccess(EAccessRights::CreateQueue, dogToken) == true);
+ UNIT_ASSERT(objACL.CheckAccess(EAccessRights::UpdateRow, dogToken) == true);
+ UNIT_ASSERT(objACL.CheckAccess(EAccessRights::SelectRow, dogToken) == true);
+ UNIT_ASSERT(objACL.CheckAccess(EAccessRights::AlterSchema, dogToken) == true);
+
+ TDiffACL removeAccessDiff3;
+ removeAccessDiff3.ClearAccessForSid(Dog);
+ objACL.ApplyDiff(removeAccessDiff3);
+
+ UNIT_ASSERT(objACL.CheckAccess(EAccessRights::CreateQueue, dogToken) == false);
+ UNIT_ASSERT(objACL.CheckAccess(EAccessRights::UpdateRow, dogToken) == false);
+ UNIT_ASSERT(objACL.CheckAccess(EAccessRights::SelectRow, dogToken) == false);
+ UNIT_ASSERT(objACL.CheckAccess(EAccessRights::AlterSchema, dogToken) == false);
+ }
+
+ Y_UNIT_TEST(TestInhertACL) {
+ TSecurityObject objParent(James, true /* container */);
+
+ objParent.AddAccess(EAccessType::Allow, EAccessRights::CreateQueue, Cat, EInheritanceType::InheritContainer);
+ objParent.AddAccess(EAccessType::Allow, EAccessRights::UpdateRow, Cat, EInheritanceType::InheritContainer);
+ objParent.AddAccess(EAccessType::Allow, EAccessRights::SelectRow, Cat, EInheritanceType::InheritContainer);
+
+ TSecurityObject objChild(James, true /* container */);
+
+ objChild.AddAccess(EAccessType::Allow, EAccessRights::CreateTable, Cat, EInheritanceType::InheritContainer);
+ objChild.AddAccess(EAccessType::Allow, EAccessRights::RemoveSchema, Cat, EInheritanceType::InheritContainer);
+
+ objChild = objChild.MergeWithParent(objParent);
+
+ UNIT_ASSERT(objChild.GetACL().ACESize() == 5);
+ UNIT_ASSERT(objChild.GetImmediateACL().ACESize() == 2);
}
-
- Y_UNIT_TEST(TestInhertACL) {
- TSecurityObject objParent(James, true /* container */);
-
- objParent.AddAccess(EAccessType::Allow, EAccessRights::CreateQueue, Cat, EInheritanceType::InheritContainer);
- objParent.AddAccess(EAccessType::Allow, EAccessRights::UpdateRow, Cat, EInheritanceType::InheritContainer);
- objParent.AddAccess(EAccessType::Allow, EAccessRights::SelectRow, Cat, EInheritanceType::InheritContainer);
-
- TSecurityObject objChild(James, true /* container */);
-
- objChild.AddAccess(EAccessType::Allow, EAccessRights::CreateTable, Cat, EInheritanceType::InheritContainer);
- objChild.AddAccess(EAccessType::Allow, EAccessRights::RemoveSchema, Cat, EInheritanceType::InheritContainer);
-
- objChild = objChild.MergeWithParent(objParent);
-
- UNIT_ASSERT(objChild.GetACL().ACESize() == 5);
- UNIT_ASSERT(objChild.GetImmediateACL().ACESize() == 2);
- }
-
- Y_UNIT_TEST(TestGrantACL) {
- TSecurityObject objACL(James, true /* container */);
- TUserToken catToken(Cat, TVector<TSID>());
-
- objACL.AddAccess(EAccessType::Allow, EAccessRights::CreateQueue, Cat, EInheritanceType::InheritContainer);
- objACL.AddAccess(EAccessType::Allow, EAccessRights::UpdateRow, Cat, EInheritanceType::InheritContainer);
- objACL.AddAccess(EAccessType::Allow, EAccessRights::SelectRow, Cat, EInheritanceType::InheritContainer);
- objACL.AddAccess(EAccessType::Allow, EAccessRights::GrantAccessRights, Cat, EInheritanceType::InheritContainer);
-
- TDiffACL addAccessDiff;
- addAccessDiff.AddAccess(EAccessType::Allow, EAccessRights::CreateQueue, Cat, EInheritanceType::InheritContainer);
- addAccessDiff.AddAccess(EAccessType::Allow, EAccessRights::UpdateRow, Cat, EInheritanceType::InheritContainer);
- addAccessDiff.AddAccess(EAccessType::Allow, EAccessRights::SelectRow, Cat, EInheritanceType::InheritContainer);
-
- UNIT_ASSERT_EQUAL(objACL.CheckGrantAccess(addAccessDiff, catToken), true);
-
- addAccessDiff.AddAccess(EAccessType::Allow, EAccessRights::AlterSchema, Cat, EInheritanceType::InheritContainer);
-
- UNIT_ASSERT_EQUAL(objACL.CheckGrantAccess(addAccessDiff, catToken), false);
- }
-
- Y_UNIT_TEST(TestClearAccess) {
- TSecurityObject objACL(James, true /* container */);
- TUserToken catToken(Cat, TVector<TSID>());
-
- objACL.AddAccess(EAccessType::Allow, EAccessRights::CreateQueue, Cat);
-
- TDiffACL accessDiff;
- accessDiff.ClearAccess();
- accessDiff.AddAccess(EAccessType::Allow, EAccessRights::UpdateRow, Cat);
- accessDiff.AddAccess(EAccessType::Allow, EAccessRights::SelectRow, Cat);
- objACL.ApplyDiff(accessDiff);
-
- UNIT_ASSERT_EQUAL(objACL.CheckAccess(EAccessRights::CreateQueue, catToken), false);
- UNIT_ASSERT_EQUAL(objACL.CheckAccess(EAccessRights::UpdateRow, catToken), true);
- UNIT_ASSERT_EQUAL(objACL.CheckAccess(EAccessRights::SelectRow, catToken), true);
- }
-
- Y_UNIT_TEST(TestStrings) {
- TACL objACL;
-
- objACL.AddAccess(EAccessType::Allow, EAccessRights::CreateQueue | EAccessRights::UpdateRow | EAccessRights::SelectRow, Cat, EInheritanceType::InheritContainer);
-
- TString str = objACL.ToString();
- NACLibProto::TACE newACE;
- TACL::FromString(newACE, str);
- UNIT_ASSERT_EQUAL(newACE.GetAccessType(), (ui32)EAccessType::Allow);
- UNIT_ASSERT_EQUAL(newACE.GetAccessRight(), EAccessRights::CreateQueue | EAccessRights::UpdateRow | EAccessRights::SelectRow);
- UNIT_ASSERT_EQUAL(newACE.GetInheritanceType(), EInheritanceType::InheritContainer);
- }
-
- Y_UNIT_TEST(CheckACL) {
- TString ACL = "CiEIARD/DxoYcm9ib3QtcWxvdWQta2lraW1yQHN0YWZmIAMKGggBEP8PGhFyb2JvdC1xbG91ZEBzdGFmZiADCiEIARD/DxoYcm9ib3QtcWxvdWQtY2xpZW50QHN0YWZmIAMKFwgBEP8PGg54ZW5veGVub0BzdGFmZiAD";
- TSecurityObject securityObject("owner@builtin", false);
+
+ Y_UNIT_TEST(TestGrantACL) {
+ TSecurityObject objACL(James, true /* container */);
+ TUserToken catToken(Cat, TVector<TSID>());
+
+ objACL.AddAccess(EAccessType::Allow, EAccessRights::CreateQueue, Cat, EInheritanceType::InheritContainer);
+ objACL.AddAccess(EAccessType::Allow, EAccessRights::UpdateRow, Cat, EInheritanceType::InheritContainer);
+ objACL.AddAccess(EAccessType::Allow, EAccessRights::SelectRow, Cat, EInheritanceType::InheritContainer);
+ objACL.AddAccess(EAccessType::Allow, EAccessRights::GrantAccessRights, Cat, EInheritanceType::InheritContainer);
+
+ TDiffACL addAccessDiff;
+ addAccessDiff.AddAccess(EAccessType::Allow, EAccessRights::CreateQueue, Cat, EInheritanceType::InheritContainer);
+ addAccessDiff.AddAccess(EAccessType::Allow, EAccessRights::UpdateRow, Cat, EInheritanceType::InheritContainer);
+ addAccessDiff.AddAccess(EAccessType::Allow, EAccessRights::SelectRow, Cat, EInheritanceType::InheritContainer);
+
+ UNIT_ASSERT_EQUAL(objACL.CheckGrantAccess(addAccessDiff, catToken), true);
+
+ addAccessDiff.AddAccess(EAccessType::Allow, EAccessRights::AlterSchema, Cat, EInheritanceType::InheritContainer);
+
+ UNIT_ASSERT_EQUAL(objACL.CheckGrantAccess(addAccessDiff, catToken), false);
+ }
+
+ Y_UNIT_TEST(TestClearAccess) {
+ TSecurityObject objACL(James, true /* container */);
+ TUserToken catToken(Cat, TVector<TSID>());
+
+ objACL.AddAccess(EAccessType::Allow, EAccessRights::CreateQueue, Cat);
+
+ TDiffACL accessDiff;
+ accessDiff.ClearAccess();
+ accessDiff.AddAccess(EAccessType::Allow, EAccessRights::UpdateRow, Cat);
+ accessDiff.AddAccess(EAccessType::Allow, EAccessRights::SelectRow, Cat);
+ objACL.ApplyDiff(accessDiff);
+
+ UNIT_ASSERT_EQUAL(objACL.CheckAccess(EAccessRights::CreateQueue, catToken), false);
+ UNIT_ASSERT_EQUAL(objACL.CheckAccess(EAccessRights::UpdateRow, catToken), true);
+ UNIT_ASSERT_EQUAL(objACL.CheckAccess(EAccessRights::SelectRow, catToken), true);
+ }
+
+ Y_UNIT_TEST(TestStrings) {
+ TACL objACL;
+
+ objACL.AddAccess(EAccessType::Allow, EAccessRights::CreateQueue | EAccessRights::UpdateRow | EAccessRights::SelectRow, Cat, EInheritanceType::InheritContainer);
+
+ TString str = objACL.ToString();
+ NACLibProto::TACE newACE;
+ TACL::FromString(newACE, str);
+ UNIT_ASSERT_EQUAL(newACE.GetAccessType(), (ui32)EAccessType::Allow);
+ UNIT_ASSERT_EQUAL(newACE.GetAccessRight(), EAccessRights::CreateQueue | EAccessRights::UpdateRow | EAccessRights::SelectRow);
+ UNIT_ASSERT_EQUAL(newACE.GetInheritanceType(), EInheritanceType::InheritContainer);
+ }
+
+ Y_UNIT_TEST(CheckACL) {
+ TString ACL = "CiEIARD/DxoYcm9ib3QtcWxvdWQta2lraW1yQHN0YWZmIAMKGggBEP8PGhFyb2JvdC1xbG91ZEBzdGFmZiADCiEIARD/DxoYcm9ib3QtcWxvdWQtY2xpZW50QHN0YWZmIAMKFwgBEP8PGg54ZW5veGVub0BzdGFmZiAD";
+ TSecurityObject securityObject("owner@builtin", false);
Y_PROTOBUF_SUPPRESS_NODISCARD securityObject.MutableACL()->ParseFromString(Base64Decode(ACL));
- TUserToken user("xenoxeno@staff", {});
- ui32 access = EAccessRights::DescribeSchema;
- UNIT_ASSERT(securityObject.CheckAccess(access, user));
- }
-}
+ TUserToken user("xenoxeno@staff", {});
+ ui32 access = EAccessRights::DescribeSchema;
+ UNIT_ASSERT(securityObject.CheckAccess(access, user));
+ }
+}
diff --git a/ydb/library/aclib/protos/aclib.proto b/ydb/library/aclib/protos/aclib.proto
index b5ba3c2f28f..4978977d54f 100644
--- a/ydb/library/aclib/protos/aclib.proto
+++ b/ydb/library/aclib/protos/aclib.proto
@@ -1,46 +1,46 @@
-package NACLibProto;
-
+package NACLibProto;
+
option go_package = "a.yandex-team.ru/ydb/library/aclib/protos;aclibpb";
-message TACE {
- optional uint32 AccessType = 1;
- optional uint32 AccessRight = 2;
- optional string SID = 3;
- optional uint32 InheritanceType = 4;
- optional bool Inherited = 5; // runtime only
-}
-
-message TACL {
- // deny entries should precede allow entries
- repeated TACE ACE = 1;
-}
-
-message TProtoHashBucket {
- repeated string Values = 1;
-}
-
-message TProtoHashTable {
- repeated TProtoHashBucket Buckets = 2;
-}
-
-message TUserToken {
- optional string UserSID = 1;
- optional TProtoHashTable GroupSIDs = 2;
- optional string OriginalUserToken = 3;
- optional string AuthType = 4;
-}
-
-message TSecurityObject {
- optional string OwnerSID = 1;
- optional TACL ACL = 2;
- optional uint64 ExpireTime = 3; // ms
-}
-
-message TDiffACE {
- optional uint32 DiffType = 1;
- optional TACE ACE = 2;
-}
-
-message TDiffACL {
- repeated TDiffACE DiffACE = 1;
-}
+message TACE {
+ optional uint32 AccessType = 1;
+ optional uint32 AccessRight = 2;
+ optional string SID = 3;
+ optional uint32 InheritanceType = 4;
+ optional bool Inherited = 5; // runtime only
+}
+
+message TACL {
+ // deny entries should precede allow entries
+ repeated TACE ACE = 1;
+}
+
+message TProtoHashBucket {
+ repeated string Values = 1;
+}
+
+message TProtoHashTable {
+ repeated TProtoHashBucket Buckets = 2;
+}
+
+message TUserToken {
+ optional string UserSID = 1;
+ optional TProtoHashTable GroupSIDs = 2;
+ optional string OriginalUserToken = 3;
+ optional string AuthType = 4;
+}
+
+message TSecurityObject {
+ optional string OwnerSID = 1;
+ optional TACL ACL = 2;
+ optional uint64 ExpireTime = 3; // ms
+}
+
+message TDiffACE {
+ optional uint32 DiffType = 1;
+ optional TACE ACE = 2;
+}
+
+message TDiffACL {
+ repeated TDiffACE DiffACE = 1;
+}
diff --git a/ydb/library/aclib/protos/ya.make b/ydb/library/aclib/protos/ya.make
index d13065aad99..59135589cc5 100644
--- a/ydb/library/aclib/protos/ya.make
+++ b/ydb/library/aclib/protos/ya.make
@@ -7,8 +7,8 @@ OWNER(
INCLUDE_TAGS(GO_PROTO)
-SRCS(
- aclib.proto
-)
+SRCS(
+ aclib.proto
+)
-END()
+END()
diff --git a/ydb/library/aclib/ut/ya.make b/ydb/library/aclib/ut/ya.make
index 1cdaa22e135..9af204045d0 100644
--- a/ydb/library/aclib/ut/ya.make
+++ b/ydb/library/aclib/ut/ya.make
@@ -1,11 +1,11 @@
-UNITTEST_FOR(ydb/library/aclib)
-
+UNITTEST_FOR(ydb/library/aclib)
+
OWNER(xenoxeno g:kikimr)
-
-PEERDIR()
-
-SRCS(
- aclib_ut.cpp
-)
-
-END()
+
+PEERDIR()
+
+SRCS(
+ aclib_ut.cpp
+)
+
+END()
diff --git a/ydb/library/aclib/ya.make b/ydb/library/aclib/ya.make
index 0a81539cfd3..a0c1da4c76c 100644
--- a/ydb/library/aclib/ya.make
+++ b/ydb/library/aclib/ya.make
@@ -1,22 +1,22 @@
-LIBRARY()
+LIBRARY()
-PEERDIR(
- contrib/libs/protobuf
+PEERDIR(
+ contrib/libs/protobuf
library/cpp/protobuf/util
ydb/library/aclib/protos
-)
+)
OWNER(
xenoxeno
g:kikimr
)
-SRCS(
- aclib.cpp
- aclib.h
-)
+SRCS(
+ aclib.cpp
+ aclib.h
+)
-END()
+END()
RECURSE_FOR_TESTS(
ut
diff --git a/ydb/library/binary_json/ut/ya.make b/ydb/library/binary_json/ut/ya.make
index a8c974ce8d9..1d4cf353111 100644
--- a/ydb/library/binary_json/ut/ya.make
+++ b/ydb/library/binary_json/ut/ya.make
@@ -1,4 +1,4 @@
-UNITTEST_FOR(ydb/library/binary_json)
+UNITTEST_FOR(ydb/library/binary_json)
OWNER(g:kikimr)
diff --git a/ydb/library/dynumber/ut/ya.make b/ydb/library/dynumber/ut/ya.make
index d9daefcc8fd..2f82007ccdd 100644
--- a/ydb/library/dynumber/ut/ya.make
+++ b/ydb/library/dynumber/ut/ya.make
@@ -1,4 +1,4 @@
-UNITTEST_FOR(ydb/library/dynumber)
+UNITTEST_FOR(ydb/library/dynumber)
OWNER(g:kikimr)
diff --git a/ydb/library/keys/ut/ya.make b/ydb/library/keys/ut/ya.make
index 1560c674ed1..d5b3cb51366 100644
--- a/ydb/library/keys/ut/ya.make
+++ b/ydb/library/keys/ut/ya.make
@@ -1,4 +1,4 @@
-UNITTEST_FOR(ydb/library/keys)
+UNITTEST_FOR(ydb/library/keys)
OWNER(cthulhu g:kikimr)
FORK_SUBTESTS()
diff --git a/ydb/library/login/login.cpp b/ydb/library/login/login.cpp
index e62a7a15ea0..b6fbc3c8f63 100644
--- a/ydb/library/login/login.cpp
+++ b/ydb/library/login/login.cpp
@@ -1,565 +1,565 @@
-#undef __STDC_FORMAT_MACROS
-#include <contrib/libs/jwt-cpp/jwt.h>
-#include <library/cpp/digest/argonish/argon2.h>
-#include <library/cpp/string_utils/base64/base64.h>
-#include <library/cpp/json/json_value.h>
-#include <library/cpp/json/json_reader.h>
-#include <library/cpp/json/json_writer.h>
-#include <openssl/rsa.h>
-#include <openssl/pem.h>
-#include <openssl/rand.h>
-
+#undef __STDC_FORMAT_MACROS
+#include <contrib/libs/jwt-cpp/jwt.h>
+#include <library/cpp/digest/argonish/argon2.h>
+#include <library/cpp/string_utils/base64/base64.h>
+#include <library/cpp/json/json_value.h>
+#include <library/cpp/json/json_reader.h>
+#include <library/cpp/json/json_writer.h>
+#include <openssl/rsa.h>
+#include <openssl/pem.h>
+#include <openssl/rand.h>
+
#include <util/generic/singleton.h>
-#include <util/string/cast.h>
-#include <util/string/hex.h>
-
-#include <deque>
-
-#include "login.h"
-
-namespace NLogin {
-
-struct TLoginProvider::TImpl {
-
- THolder<NArgonish::IArgon2Base> ArgonHasher;
-
- TImpl() {
+#include <util/string/cast.h>
+#include <util/string/hex.h>
+
+#include <deque>
+
+#include "login.h"
+
+namespace NLogin {
+
+struct TLoginProvider::TImpl {
+
+ THolder<NArgonish::IArgon2Base> ArgonHasher;
+
+ TImpl() {
ArgonHasher = Default<NArgonish::TArgon2Factory>().Create(
- NArgonish::EArgon2Type::Argon2id, // Mixed version of Argon2
- 2, // 2-pass computation
- (1<<11), // 2 mebibytes memory usage (in KiB)
- 1 // number of threads and lanes
- );
- }
- void GenerateKeyPair(TString& publicKey, TString& privateKey);
- TString GenerateHash(const TString& password);
- bool VerifyHash(const TString& password, const TString& hash);
-};
-
-TLoginProvider::TLoginProvider()
- : Impl(new TImpl())
-{}
-
-TLoginProvider::~TLoginProvider()
-{}
-
-bool TLoginProvider::CheckAllowedName(const TString& name) {
- return name.find_first_not_of("abcdefghijklmnopqrstuvwxyz0123456789") == std::string::npos;
-}
-
-TLoginProvider::TBasicResponse TLoginProvider::CreateUser(const TCreateUserRequest& request) {
- TBasicResponse response;
-
- if (!CheckAllowedName(request.User)) {
- response.Error = "Name is not allowed";
- return response;
- }
- auto itUserCreate = Sids.emplace(request.User, TSidRecord{.Type = NLoginProto::ESidType::USER});
- if (!itUserCreate.second) {
- if (itUserCreate.first->second.Type == ESidType::USER) {
- response.Error = "User already exists";
- } else {
- response.Error = "Account already exists";
- }
- return response;
- }
-
- TSidRecord& user = itUserCreate.first->second;
- user.Name = request.User;
- user.Hash = Impl->GenerateHash(request.Password);
-
- return response;
-}
-
-TLoginProvider::TBasicResponse TLoginProvider::ModifyUser(const TModifyUserRequest& request) {
- TBasicResponse response;
-
- auto itUserModify = Sids.find(request.User);
- if (itUserModify == Sids.end() || itUserModify->second.Type != ESidType::USER) {
- response.Error = "User not found";
- return response;
- }
-
- TSidRecord& user = itUserModify->second;
- user.Hash = Impl->GenerateHash(request.Password);
-
- return response;
-}
-
-TLoginProvider::TRemoveUserResponse TLoginProvider::RemoveUser(const TRemoveUserRequest& request) {
- TRemoveUserResponse response;
-
- auto itUserModify = Sids.find(request.User);
- if (itUserModify == Sids.end() || itUserModify->second.Type != ESidType::USER) {
- response.Error = "User not found";
- return response;
- }
-
- auto itChildToParentIndex = ChildToParentIndex.find(request.User);
- if (itChildToParentIndex != ChildToParentIndex.end()) {
- for (const TString& parent : itChildToParentIndex->second) {
- auto itGroup = Sids.find(parent);
- if (itGroup != Sids.end()) {
- response.TouchedGroups.emplace_back(itGroup->first);
- itGroup->second.Members.erase(request.User);
- }
- }
- ChildToParentIndex.erase(itChildToParentIndex);
- }
-
- Sids.erase(itUserModify);
-
- return response;
-}
-
-TLoginProvider::TBasicResponse TLoginProvider::CreateGroup(const TCreateGroupRequest& request) {
- TBasicResponse response;
-
- if (!CheckAllowedName(request.Group)) {
- response.Error = "Name is not allowed";
- return response;
- }
- auto itGroupCreate = Sids.emplace(request.Group, TSidRecord{.Type = ESidType::GROUP});
- if (!itGroupCreate.second) {
- if (itGroupCreate.first->second.Type == ESidType::GROUP) {
- response.Error = "Group already exists";
- } else {
- response.Error = "Account already exists";
- }
- return response;
- }
-
- TSidRecord& group = itGroupCreate.first->second;
- group.Name = request.Group;
-
- return response;
-}
-
-TLoginProvider::TBasicResponse TLoginProvider::AddGroupMembership(const TAddGroupMembershipRequest& request) {
- TBasicResponse response;
-
- auto itGroupModify = Sids.find(request.Group);
- if (itGroupModify == Sids.end() || itGroupModify->second.Type != ESidType::GROUP) {
- response.Error = "Group not found";
- return response;
- }
-
- if (Sids.count(request.Member) == 0) {
- response.Error = "Member account not found";
- return response;
- }
-
- TSidRecord& group = itGroupModify->second;
- group.Members.insert(request.Member);
-
- ChildToParentIndex[request.Member].insert(request.Group);
-
- return response;
-}
-
-TLoginProvider::TBasicResponse TLoginProvider::RemoveGroupMembership(const TRemoveGroupMembershipRequest& request) {
- TBasicResponse response;
-
- auto itGroupModify = Sids.find(request.Group);
- if (itGroupModify == Sids.end() || itGroupModify->second.Type != ESidType::GROUP) {
- response.Error = "Group not found";
- return response;
- }
-
- TSidRecord& group = itGroupModify->second;
- group.Members.erase(request.Member);
-
- ChildToParentIndex[request.Member].erase(request.Group);
-
- return response;
-}
-
-TLoginProvider::TRemoveGroupResponse TLoginProvider::RemoveGroup(const TRemoveGroupRequest& request) {
- TRemoveGroupResponse response;
-
- auto itGroupModify = Sids.find(request.Group);
- if (itGroupModify == Sids.end() || itGroupModify->second.Type != ESidType::GROUP) {
- response.Error = "Group not found";
- return response;
- }
-
- auto itChildToParentIndex = ChildToParentIndex.find(request.Group);
- if (itChildToParentIndex != ChildToParentIndex.end()) {
- for (const TString& parent : itChildToParentIndex->second) {
- auto itGroup = Sids.find(parent);
- if (itGroup != Sids.end()) {
- response.TouchedGroups.emplace_back(itGroup->first);
- itGroup->second.Members.erase(request.Group);
- }
- }
- ChildToParentIndex.erase(itChildToParentIndex);
- }
-
- for (const TString& member : itGroupModify->second.Members) {
- ChildToParentIndex[member].erase(request.Group);
- }
-
- Sids.erase(itGroupModify);
-
- return response;
-}
-
-std::vector<TString> TLoginProvider::GetGroupsMembership(const TString& member) {
- std::vector<TString> groups;
- std::unordered_set<TString> visited;
- std::deque<TString> queue;
- queue.push_back(member);
- while (!queue.empty()) {
- TString member = queue.front();
- queue.pop_front();
- auto itChildToParentIndex = ChildToParentIndex.find(member);
- if (itChildToParentIndex != ChildToParentIndex.end()) {
- for (const TString& parent : itChildToParentIndex->second) {
- if (visited.insert(parent).second) {
- queue.push_back(parent);
- groups.push_back(parent);
- }
- }
- }
- }
- return groups;
-}
-
-TLoginProvider::TLoginUserResponse TLoginProvider::LoginUser(const TLoginUserRequest& request) {
- TLoginUserResponse response;
- auto itUser = Sids.find(request.User);
- if (itUser == Sids.end() || itUser->second.Type != ESidType::USER) {
- response.Error = "Invalid user";
- return response;
- }
-
- if (!Impl->VerifyHash(request.Password, itUser->second.Hash)) {
- response.Error = "Invalid password";
- return response;
- }
-
- if (Keys.empty() || Keys.back().PrivateKey.empty()) {
- response.Error = "No key to generate token";
- return response;
- }
-
- const TKeyRecord& key = Keys.back();
-
- auto keyId = ToString(key.KeyId);
- const auto& publicKey = key.PublicKey;
- const auto& privateKey = key.PrivateKey;
-
- // encode jwt
- auto now = std::chrono::system_clock::now();
- auto expires_at = now + MAX_TOKEN_EXPIRE_TIME;
- if (request.Options.ExpiresAfter != std::chrono::system_clock::duration::zero()) {
- expires_at = std::min(expires_at, now + request.Options.ExpiresAfter);
- }
- auto algorithm = jwt::algorithm::ps256(publicKey, privateKey);
-
- auto token = jwt::create()
- .set_key_id(keyId)
- .set_subject(request.User)
- .set_issued_at(now)
- .set_expires_at(expires_at);
- if (!Audience.empty()) {
- token.set_audience(Audience);
- }
-
- if (request.Options.WithUserGroups) {
- auto groups = GetGroupsMembership(request.User);
- token.set_payload_claim(GROUPS_CLAIM_NAME, jwt::claim(picojson::value(std::vector<picojson::value>(groups.begin(), groups.end()))));
- }
-
- auto encoded_token = token.sign(algorithm);
-
- response.Token = TString(encoded_token);
-
- return response;
-}
-
-std::deque<TLoginProvider::TKeyRecord>::iterator TLoginProvider::FindKeyIterator(ui64 keyId) {
- if (!Keys.empty() && keyId >= Keys.front().KeyId && keyId <= Keys.back().KeyId) {
- auto it = std::next(Keys.begin(), keyId - Keys.front().KeyId);
- if (it->KeyId == keyId) {
- return it;
- }
- }
- return Keys.end();
-}
-
-const TLoginProvider::TKeyRecord* TLoginProvider::FindKey(ui64 keyId) {
- auto it = FindKeyIterator(keyId);
- if (it != Keys.end()) {
- return &(*it);
- }
- return nullptr;
-}
-
-TLoginProvider::TValidateTokenResponse TLoginProvider::ValidateToken(const TValidateTokenRequest& request) {
- TLoginProvider::TValidateTokenResponse response;
- try {
- jwt::decoded_jwt decoded_token = jwt::decode(request.Token);
- if (Audience) {
- // we check audience manually because we wan't this error instead of wrong key id in case of databases mismatch
- auto audience = decoded_token.get_audience();
- if (audience.empty() || TString(*audience.begin()) != Audience) {
- response.Error = "Wrong audience";
- return response;
- }
- }
- auto keyId = FromStringWithDefault<ui64>(decoded_token.get_key_id());
- const TKeyRecord* key = FindKey(keyId);
- if (key != nullptr) {
- auto verifier = jwt::verify()
- .allow_algorithm(jwt::algorithm::ps256(key->PublicKey));
- if (Audience) {
- verifier.with_audience({Audience});
- }
- verifier.verify(decoded_token);
- response.User = decoded_token.get_subject();
- response.ExpiresAt = decoded_token.get_expires_at();
- if (decoded_token.has_payload_claim(GROUPS_CLAIM_NAME)) {
- const jwt::claim& groups = decoded_token.get_payload_claim(GROUPS_CLAIM_NAME);
- if (groups.get_type() == jwt::claim::type::array) {
- const picojson::array& array = groups.as_array();
- std::vector<TString> groups;
- groups.resize(array.size());
- for (size_t i = 0; i < array.size(); ++i) {
- groups[i] = array[i].get<std::string>();
- }
- response.Groups = groups;
- }
- }
- if (!Sids.empty()) {
- auto itUser = Sids.find(TString(decoded_token.get_subject()));
- if (itUser == Sids.end()) {
- response.Error = "Token is valid, but subject wasn't found";
- }
- }
- } else {
- if (Keys.empty()) {
- response.Error = "Security state is empty";
- response.ErrorRetryable = true;
- } else if (keyId < Keys.front().KeyId) {
+ NArgonish::EArgon2Type::Argon2id, // Mixed version of Argon2
+ 2, // 2-pass computation
+ (1<<11), // 2 mebibytes memory usage (in KiB)
+ 1 // number of threads and lanes
+ );
+ }
+ void GenerateKeyPair(TString& publicKey, TString& privateKey);
+ TString GenerateHash(const TString& password);
+ bool VerifyHash(const TString& password, const TString& hash);
+};
+
+TLoginProvider::TLoginProvider()
+ : Impl(new TImpl())
+{}
+
+TLoginProvider::~TLoginProvider()
+{}
+
+bool TLoginProvider::CheckAllowedName(const TString& name) {
+ return name.find_first_not_of("abcdefghijklmnopqrstuvwxyz0123456789") == std::string::npos;
+}
+
+TLoginProvider::TBasicResponse TLoginProvider::CreateUser(const TCreateUserRequest& request) {
+ TBasicResponse response;
+
+ if (!CheckAllowedName(request.User)) {
+ response.Error = "Name is not allowed";
+ return response;
+ }
+ auto itUserCreate = Sids.emplace(request.User, TSidRecord{.Type = NLoginProto::ESidType::USER});
+ if (!itUserCreate.second) {
+ if (itUserCreate.first->second.Type == ESidType::USER) {
+ response.Error = "User already exists";
+ } else {
+ response.Error = "Account already exists";
+ }
+ return response;
+ }
+
+ TSidRecord& user = itUserCreate.first->second;
+ user.Name = request.User;
+ user.Hash = Impl->GenerateHash(request.Password);
+
+ return response;
+}
+
+TLoginProvider::TBasicResponse TLoginProvider::ModifyUser(const TModifyUserRequest& request) {
+ TBasicResponse response;
+
+ auto itUserModify = Sids.find(request.User);
+ if (itUserModify == Sids.end() || itUserModify->second.Type != ESidType::USER) {
+ response.Error = "User not found";
+ return response;
+ }
+
+ TSidRecord& user = itUserModify->second;
+ user.Hash = Impl->GenerateHash(request.Password);
+
+ return response;
+}
+
+TLoginProvider::TRemoveUserResponse TLoginProvider::RemoveUser(const TRemoveUserRequest& request) {
+ TRemoveUserResponse response;
+
+ auto itUserModify = Sids.find(request.User);
+ if (itUserModify == Sids.end() || itUserModify->second.Type != ESidType::USER) {
+ response.Error = "User not found";
+ return response;
+ }
+
+ auto itChildToParentIndex = ChildToParentIndex.find(request.User);
+ if (itChildToParentIndex != ChildToParentIndex.end()) {
+ for (const TString& parent : itChildToParentIndex->second) {
+ auto itGroup = Sids.find(parent);
+ if (itGroup != Sids.end()) {
+ response.TouchedGroups.emplace_back(itGroup->first);
+ itGroup->second.Members.erase(request.User);
+ }
+ }
+ ChildToParentIndex.erase(itChildToParentIndex);
+ }
+
+ Sids.erase(itUserModify);
+
+ return response;
+}
+
+TLoginProvider::TBasicResponse TLoginProvider::CreateGroup(const TCreateGroupRequest& request) {
+ TBasicResponse response;
+
+ if (!CheckAllowedName(request.Group)) {
+ response.Error = "Name is not allowed";
+ return response;
+ }
+ auto itGroupCreate = Sids.emplace(request.Group, TSidRecord{.Type = ESidType::GROUP});
+ if (!itGroupCreate.second) {
+ if (itGroupCreate.first->second.Type == ESidType::GROUP) {
+ response.Error = "Group already exists";
+ } else {
+ response.Error = "Account already exists";
+ }
+ return response;
+ }
+
+ TSidRecord& group = itGroupCreate.first->second;
+ group.Name = request.Group;
+
+ return response;
+}
+
+TLoginProvider::TBasicResponse TLoginProvider::AddGroupMembership(const TAddGroupMembershipRequest& request) {
+ TBasicResponse response;
+
+ auto itGroupModify = Sids.find(request.Group);
+ if (itGroupModify == Sids.end() || itGroupModify->second.Type != ESidType::GROUP) {
+ response.Error = "Group not found";
+ return response;
+ }
+
+ if (Sids.count(request.Member) == 0) {
+ response.Error = "Member account not found";
+ return response;
+ }
+
+ TSidRecord& group = itGroupModify->second;
+ group.Members.insert(request.Member);
+
+ ChildToParentIndex[request.Member].insert(request.Group);
+
+ return response;
+}
+
+TLoginProvider::TBasicResponse TLoginProvider::RemoveGroupMembership(const TRemoveGroupMembershipRequest& request) {
+ TBasicResponse response;
+
+ auto itGroupModify = Sids.find(request.Group);
+ if (itGroupModify == Sids.end() || itGroupModify->second.Type != ESidType::GROUP) {
+ response.Error = "Group not found";
+ return response;
+ }
+
+ TSidRecord& group = itGroupModify->second;
+ group.Members.erase(request.Member);
+
+ ChildToParentIndex[request.Member].erase(request.Group);
+
+ return response;
+}
+
+TLoginProvider::TRemoveGroupResponse TLoginProvider::RemoveGroup(const TRemoveGroupRequest& request) {
+ TRemoveGroupResponse response;
+
+ auto itGroupModify = Sids.find(request.Group);
+ if (itGroupModify == Sids.end() || itGroupModify->second.Type != ESidType::GROUP) {
+ response.Error = "Group not found";
+ return response;
+ }
+
+ auto itChildToParentIndex = ChildToParentIndex.find(request.Group);
+ if (itChildToParentIndex != ChildToParentIndex.end()) {
+ for (const TString& parent : itChildToParentIndex->second) {
+ auto itGroup = Sids.find(parent);
+ if (itGroup != Sids.end()) {
+ response.TouchedGroups.emplace_back(itGroup->first);
+ itGroup->second.Members.erase(request.Group);
+ }
+ }
+ ChildToParentIndex.erase(itChildToParentIndex);
+ }
+
+ for (const TString& member : itGroupModify->second.Members) {
+ ChildToParentIndex[member].erase(request.Group);
+ }
+
+ Sids.erase(itGroupModify);
+
+ return response;
+}
+
+std::vector<TString> TLoginProvider::GetGroupsMembership(const TString& member) {
+ std::vector<TString> groups;
+ std::unordered_set<TString> visited;
+ std::deque<TString> queue;
+ queue.push_back(member);
+ while (!queue.empty()) {
+ TString member = queue.front();
+ queue.pop_front();
+ auto itChildToParentIndex = ChildToParentIndex.find(member);
+ if (itChildToParentIndex != ChildToParentIndex.end()) {
+ for (const TString& parent : itChildToParentIndex->second) {
+ if (visited.insert(parent).second) {
+ queue.push_back(parent);
+ groups.push_back(parent);
+ }
+ }
+ }
+ }
+ return groups;
+}
+
+TLoginProvider::TLoginUserResponse TLoginProvider::LoginUser(const TLoginUserRequest& request) {
+ TLoginUserResponse response;
+ auto itUser = Sids.find(request.User);
+ if (itUser == Sids.end() || itUser->second.Type != ESidType::USER) {
+ response.Error = "Invalid user";
+ return response;
+ }
+
+ if (!Impl->VerifyHash(request.Password, itUser->second.Hash)) {
+ response.Error = "Invalid password";
+ return response;
+ }
+
+ if (Keys.empty() || Keys.back().PrivateKey.empty()) {
+ response.Error = "No key to generate token";
+ return response;
+ }
+
+ const TKeyRecord& key = Keys.back();
+
+ auto keyId = ToString(key.KeyId);
+ const auto& publicKey = key.PublicKey;
+ const auto& privateKey = key.PrivateKey;
+
+ // encode jwt
+ auto now = std::chrono::system_clock::now();
+ auto expires_at = now + MAX_TOKEN_EXPIRE_TIME;
+ if (request.Options.ExpiresAfter != std::chrono::system_clock::duration::zero()) {
+ expires_at = std::min(expires_at, now + request.Options.ExpiresAfter);
+ }
+ auto algorithm = jwt::algorithm::ps256(publicKey, privateKey);
+
+ auto token = jwt::create()
+ .set_key_id(keyId)
+ .set_subject(request.User)
+ .set_issued_at(now)
+ .set_expires_at(expires_at);
+ if (!Audience.empty()) {
+ token.set_audience(Audience);
+ }
+
+ if (request.Options.WithUserGroups) {
+ auto groups = GetGroupsMembership(request.User);
+ token.set_payload_claim(GROUPS_CLAIM_NAME, jwt::claim(picojson::value(std::vector<picojson::value>(groups.begin(), groups.end()))));
+ }
+
+ auto encoded_token = token.sign(algorithm);
+
+ response.Token = TString(encoded_token);
+
+ return response;
+}
+
+std::deque<TLoginProvider::TKeyRecord>::iterator TLoginProvider::FindKeyIterator(ui64 keyId) {
+ if (!Keys.empty() && keyId >= Keys.front().KeyId && keyId <= Keys.back().KeyId) {
+ auto it = std::next(Keys.begin(), keyId - Keys.front().KeyId);
+ if (it->KeyId == keyId) {
+ return it;
+ }
+ }
+ return Keys.end();
+}
+
+const TLoginProvider::TKeyRecord* TLoginProvider::FindKey(ui64 keyId) {
+ auto it = FindKeyIterator(keyId);
+ if (it != Keys.end()) {
+ return &(*it);
+ }
+ return nullptr;
+}
+
+TLoginProvider::TValidateTokenResponse TLoginProvider::ValidateToken(const TValidateTokenRequest& request) {
+ TLoginProvider::TValidateTokenResponse response;
+ try {
+ jwt::decoded_jwt decoded_token = jwt::decode(request.Token);
+ if (Audience) {
+ // we check audience manually because we wan't this error instead of wrong key id in case of databases mismatch
+ auto audience = decoded_token.get_audience();
+ if (audience.empty() || TString(*audience.begin()) != Audience) {
+ response.Error = "Wrong audience";
+ return response;
+ }
+ }
+ auto keyId = FromStringWithDefault<ui64>(decoded_token.get_key_id());
+ const TKeyRecord* key = FindKey(keyId);
+ if (key != nullptr) {
+ auto verifier = jwt::verify()
+ .allow_algorithm(jwt::algorithm::ps256(key->PublicKey));
+ if (Audience) {
+ verifier.with_audience({Audience});
+ }
+ verifier.verify(decoded_token);
+ response.User = decoded_token.get_subject();
+ response.ExpiresAt = decoded_token.get_expires_at();
+ if (decoded_token.has_payload_claim(GROUPS_CLAIM_NAME)) {
+ const jwt::claim& groups = decoded_token.get_payload_claim(GROUPS_CLAIM_NAME);
+ if (groups.get_type() == jwt::claim::type::array) {
+ const picojson::array& array = groups.as_array();
+ std::vector<TString> groups;
+ groups.resize(array.size());
+ for (size_t i = 0; i < array.size(); ++i) {
+ groups[i] = array[i].get<std::string>();
+ }
+ response.Groups = groups;
+ }
+ }
+ if (!Sids.empty()) {
+ auto itUser = Sids.find(TString(decoded_token.get_subject()));
+ if (itUser == Sids.end()) {
+ response.Error = "Token is valid, but subject wasn't found";
+ }
+ }
+ } else {
+ if (Keys.empty()) {
+ response.Error = "Security state is empty";
+ response.ErrorRetryable = true;
+ } else if (keyId < Keys.front().KeyId) {
response.Error = "The key of this token has expired";
- } else if (keyId > Keys.back().KeyId) {
- response.Error = "The key of this token is not available yet";
- response.ErrorRetryable = true;
- } else {
- response.Error = "Key not found";
- }
- }
- } catch (const jwt::token_verification_exception& e) {
- response.Error = e.what(); // invalid token signature
- } catch (const std::invalid_argument& e) {
- response.Error = "Token is not in correct format";
- response.TokenUnrecognized = true;
- } catch (const std::runtime_error& e) {
- response.Error = "Base64 decoding failed or invalid json";
- response.TokenUnrecognized = true;
- } catch (const std::exception& e) {
- response.Error = e.what();
- }
- return response;
-}
-
-TString TLoginProvider::GetTokenAudience(const TString& token) {
- try {
- jwt::decoded_jwt decoded_token = jwt::decode(token);
- auto audience = decoded_token.get_audience();
- if (!audience.empty()) {
- return TString(*audience.begin());
- }
- }
- catch (...) {
- }
- return {};
-}
-
-std::chrono::system_clock::time_point TLoginProvider::GetTokenExpiresAt(const TString& token) {
- try {
- jwt::decoded_jwt decoded_token = jwt::decode(token);
- return decoded_token.get_expires_at();
- }
- catch (...) {
- }
- return {};
-}
-
-bool TLoginProvider::IsItTimeToRotateKeys() const {
+ } else if (keyId > Keys.back().KeyId) {
+ response.Error = "The key of this token is not available yet";
+ response.ErrorRetryable = true;
+ } else {
+ response.Error = "Key not found";
+ }
+ }
+ } catch (const jwt::token_verification_exception& e) {
+ response.Error = e.what(); // invalid token signature
+ } catch (const std::invalid_argument& e) {
+ response.Error = "Token is not in correct format";
+ response.TokenUnrecognized = true;
+ } catch (const std::runtime_error& e) {
+ response.Error = "Base64 decoding failed or invalid json";
+ response.TokenUnrecognized = true;
+ } catch (const std::exception& e) {
+ response.Error = e.what();
+ }
+ return response;
+}
+
+TString TLoginProvider::GetTokenAudience(const TString& token) {
+ try {
+ jwt::decoded_jwt decoded_token = jwt::decode(token);
+ auto audience = decoded_token.get_audience();
+ if (!audience.empty()) {
+ return TString(*audience.begin());
+ }
+ }
+ catch (...) {
+ }
+ return {};
+}
+
+std::chrono::system_clock::time_point TLoginProvider::GetTokenExpiresAt(const TString& token) {
+ try {
+ jwt::decoded_jwt decoded_token = jwt::decode(token);
+ return decoded_token.get_expires_at();
+ }
+ catch (...) {
+ }
+ return {};
+}
+
+bool TLoginProvider::IsItTimeToRotateKeys() const {
return Keys.empty()
- || Keys.back().PrivateKey.empty()
- || KeysRotationTime + KEYS_ROTATION_PERIOD < std::chrono::system_clock::now();
-}
-
-void TLoginProvider::RotateKeys() {
- std::vector<ui64> keysExpired;
- std::vector<ui64> keysAdded;
- RotateKeys(keysExpired, keysAdded);
-}
-
-void TLoginProvider::RotateKeys(std::vector<ui64>& keysExpired, std::vector<ui64>& keysAdded) {
- TString publicKey;
- TString privateKey;
- Impl->GenerateKeyPair(publicKey, privateKey);
- ui64 newKeyId;
- if (Keys.empty()) {
- newKeyId = 1;
- } else {
- newKeyId = Keys.back().KeyId + 1;
- }
- auto now = std::chrono::system_clock::now();
- Keys.push_back({
- .KeyId = newKeyId,
- .PublicKey = publicKey,
- .PrivateKey = privateKey,
- .ExpiresAt = now + KEY_EXPIRE_TIME,
- });
- keysAdded.push_back(newKeyId);
- while (Keys.size() > MAX_SERVER_KEYS || (!Keys.empty() && Keys.front().ExpiresAt <= now)) {
- ui64 oldKeyId = Keys.front().KeyId;
- Keys.pop_front();
- keysExpired.push_back(oldKeyId);
- }
- KeysRotationTime = now;
-}
-
-void TLoginProvider::TImpl::GenerateKeyPair(TString& publicKey, TString& privateKey) {
- static constexpr int bits = 2048;
- publicKey.clear();
- privateKey.clear();
- BIGNUM* bne = BN_new();
- int ret = BN_set_word(bne, RSA_F4);
- if (ret == 1) {
- RSA* r = RSA_new();
- ret = RSA_generate_key_ex(r, bits, bne, nullptr);
- if (ret == 1) {
- BIO* bioPublic = BIO_new(BIO_s_mem());
- ret = PEM_write_bio_RSA_PUBKEY(bioPublic, r);
- if (ret == 1) {
- BIO* bioPrivate = BIO_new(BIO_s_mem());
- ret = PEM_write_bio_RSAPrivateKey(bioPrivate, r, nullptr, nullptr, 0, nullptr, nullptr);
- size_t privateSize = BIO_pending(bioPrivate);
- size_t publicSize = BIO_pending(bioPublic);
- privateKey.resize(privateSize);
- publicKey.resize(publicSize);
- BIO_read(bioPrivate, &privateKey[0], privateSize);
- BIO_read(bioPublic, &publicKey[0], publicSize);
- BIO_free(bioPrivate);
- }
- BIO_free(bioPublic);
- }
- RSA_free(r);
- }
- BN_free(bne);
-}
-
-TString TLoginProvider::TImpl::GenerateHash(const TString& password) {
- char salt[SALT_SIZE];
- char hash[HASH_SIZE];
- RAND_bytes(reinterpret_cast<unsigned char*>(salt), SALT_SIZE);
- ArgonHasher->Hash(
- reinterpret_cast<const ui8*>(password.data()),
- password.size(),
- reinterpret_cast<ui8*>(salt),
- SALT_SIZE,
- reinterpret_cast<ui8*>(hash),
- HASH_SIZE);
- NJson::TJsonValue json;
- json["type"] = "argon2id";
- json["salt"] = Base64Encode(TStringBuf(salt, SALT_SIZE));
- json["hash"] = Base64Encode(TStringBuf(hash, HASH_SIZE));
- return NJson::WriteJson(json, false);
-}
-
-bool TLoginProvider::TImpl::VerifyHash(const TString& password, const TString& hashJson) {
- NJson::TJsonValue json;
- if (!NJson::ReadJsonTree(hashJson, &json)) {
- return false;
- }
- TString type = json["type"].GetStringRobust();
- if (type != "argon2id") {
- return false;
- }
- TString salt = Base64Decode(json["salt"].GetStringRobust());
- TString hash = Base64Decode(json["hash"].GetStringRobust());
- return ArgonHasher->Verify(
- reinterpret_cast<const ui8*>(password.data()),
- password.size(),
- reinterpret_cast<const ui8*>(salt.data()),
- salt.size(),
- reinterpret_cast<const ui8*>(hash.data()),
- hash.size());
-}
-
-NLoginProto::TSecurityState TLoginProvider::GetSecurityState() const {
- NLoginProto::TSecurityState state;
- state.SetAudience(Audience);
- {
- auto& pbPublicKeys = *state.MutablePublicKeys();
- pbPublicKeys.Clear();
- for (const TKeyRecord& key : Keys) {
- NLoginProto::TPublicKey& publicKey = *pbPublicKeys.Add();
- publicKey.SetKeyId(key.KeyId);
- publicKey.SetKeyDataPEM(key.PublicKey);
- publicKey.SetExpiresAt(std::chrono::duration_cast<std::chrono::milliseconds>(key.ExpiresAt.time_since_epoch()).count());
- // no private key here
- }
- }
- {
- auto& pbSids = *state.MutableSids();
- pbSids.Clear();
- for (const auto& [sidName, sidInfo] : Sids) {
- NLoginProto::TSid& sid = *pbSids.Add();
- sid.SetType(sidInfo.Type);
- sid.SetName(sidInfo.Name);
- for (const auto& subSid : sidInfo.Members) {
- sid.AddMembers(subSid);
- }
- // no user hash here
- }
- }
- return state;
-}
-
-void TLoginProvider::UpdateSecurityState(const NLoginProto::TSecurityState& state) {
- Audience = state.GetAudience();
- {
- auto now = std::chrono::system_clock::now();
- while (Keys.size() > MAX_CLIENT_KEYS || (!Keys.empty() && Keys.front().ExpiresAt <= now)) {
- Keys.pop_front();
- }
-
- if (!Keys.empty() && state.PublicKeysSize() != 0) {
- auto keyId = state.GetPublicKeys(0).GetKeyId();
- auto itKey = FindKeyIterator(keyId);
- Keys.erase(itKey, Keys.end()); // erase tail which we are going to reinsert later
- }
-
- for (const auto& pbPublicKey : state.GetPublicKeys()) {
- Y_VERIFY(Keys.empty() || pbPublicKey.GetKeyId() == Keys.back().KeyId + 1);
- Keys.push_back({
- .KeyId = pbPublicKey.GetKeyId(),
- .PublicKey = pbPublicKey.GetKeyDataPEM(),
- .ExpiresAt = std::chrono::system_clock::time_point(std::chrono::milliseconds(pbPublicKey.GetExpiresAt())),
- });
- }
- }
- {
- Sids.clear();
- ChildToParentIndex.clear();
- for (const auto& pbSid : state.GetSids()) {
- TSidRecord& sid = Sids[pbSid.GetName()];
- sid.Type = pbSid.GetType();
- sid.Name = pbSid.GetName();
- sid.Hash = pbSid.GetHash();
- for (const auto& pbSubSid : pbSid.GetMembers()) {
- sid.Members.emplace(pbSubSid);
- ChildToParentIndex[pbSubSid].emplace(sid.Name);
- }
- }
- }
-}
-
-}
+ || Keys.back().PrivateKey.empty()
+ || KeysRotationTime + KEYS_ROTATION_PERIOD < std::chrono::system_clock::now();
+}
+
+void TLoginProvider::RotateKeys() {
+ std::vector<ui64> keysExpired;
+ std::vector<ui64> keysAdded;
+ RotateKeys(keysExpired, keysAdded);
+}
+
+void TLoginProvider::RotateKeys(std::vector<ui64>& keysExpired, std::vector<ui64>& keysAdded) {
+ TString publicKey;
+ TString privateKey;
+ Impl->GenerateKeyPair(publicKey, privateKey);
+ ui64 newKeyId;
+ if (Keys.empty()) {
+ newKeyId = 1;
+ } else {
+ newKeyId = Keys.back().KeyId + 1;
+ }
+ auto now = std::chrono::system_clock::now();
+ Keys.push_back({
+ .KeyId = newKeyId,
+ .PublicKey = publicKey,
+ .PrivateKey = privateKey,
+ .ExpiresAt = now + KEY_EXPIRE_TIME,
+ });
+ keysAdded.push_back(newKeyId);
+ while (Keys.size() > MAX_SERVER_KEYS || (!Keys.empty() && Keys.front().ExpiresAt <= now)) {
+ ui64 oldKeyId = Keys.front().KeyId;
+ Keys.pop_front();
+ keysExpired.push_back(oldKeyId);
+ }
+ KeysRotationTime = now;
+}
+
+void TLoginProvider::TImpl::GenerateKeyPair(TString& publicKey, TString& privateKey) {
+ static constexpr int bits = 2048;
+ publicKey.clear();
+ privateKey.clear();
+ BIGNUM* bne = BN_new();
+ int ret = BN_set_word(bne, RSA_F4);
+ if (ret == 1) {
+ RSA* r = RSA_new();
+ ret = RSA_generate_key_ex(r, bits, bne, nullptr);
+ if (ret == 1) {
+ BIO* bioPublic = BIO_new(BIO_s_mem());
+ ret = PEM_write_bio_RSA_PUBKEY(bioPublic, r);
+ if (ret == 1) {
+ BIO* bioPrivate = BIO_new(BIO_s_mem());
+ ret = PEM_write_bio_RSAPrivateKey(bioPrivate, r, nullptr, nullptr, 0, nullptr, nullptr);
+ size_t privateSize = BIO_pending(bioPrivate);
+ size_t publicSize = BIO_pending(bioPublic);
+ privateKey.resize(privateSize);
+ publicKey.resize(publicSize);
+ BIO_read(bioPrivate, &privateKey[0], privateSize);
+ BIO_read(bioPublic, &publicKey[0], publicSize);
+ BIO_free(bioPrivate);
+ }
+ BIO_free(bioPublic);
+ }
+ RSA_free(r);
+ }
+ BN_free(bne);
+}
+
+TString TLoginProvider::TImpl::GenerateHash(const TString& password) {
+ char salt[SALT_SIZE];
+ char hash[HASH_SIZE];
+ RAND_bytes(reinterpret_cast<unsigned char*>(salt), SALT_SIZE);
+ ArgonHasher->Hash(
+ reinterpret_cast<const ui8*>(password.data()),
+ password.size(),
+ reinterpret_cast<ui8*>(salt),
+ SALT_SIZE,
+ reinterpret_cast<ui8*>(hash),
+ HASH_SIZE);
+ NJson::TJsonValue json;
+ json["type"] = "argon2id";
+ json["salt"] = Base64Encode(TStringBuf(salt, SALT_SIZE));
+ json["hash"] = Base64Encode(TStringBuf(hash, HASH_SIZE));
+ return NJson::WriteJson(json, false);
+}
+
+bool TLoginProvider::TImpl::VerifyHash(const TString& password, const TString& hashJson) {
+ NJson::TJsonValue json;
+ if (!NJson::ReadJsonTree(hashJson, &json)) {
+ return false;
+ }
+ TString type = json["type"].GetStringRobust();
+ if (type != "argon2id") {
+ return false;
+ }
+ TString salt = Base64Decode(json["salt"].GetStringRobust());
+ TString hash = Base64Decode(json["hash"].GetStringRobust());
+ return ArgonHasher->Verify(
+ reinterpret_cast<const ui8*>(password.data()),
+ password.size(),
+ reinterpret_cast<const ui8*>(salt.data()),
+ salt.size(),
+ reinterpret_cast<const ui8*>(hash.data()),
+ hash.size());
+}
+
+NLoginProto::TSecurityState TLoginProvider::GetSecurityState() const {
+ NLoginProto::TSecurityState state;
+ state.SetAudience(Audience);
+ {
+ auto& pbPublicKeys = *state.MutablePublicKeys();
+ pbPublicKeys.Clear();
+ for (const TKeyRecord& key : Keys) {
+ NLoginProto::TPublicKey& publicKey = *pbPublicKeys.Add();
+ publicKey.SetKeyId(key.KeyId);
+ publicKey.SetKeyDataPEM(key.PublicKey);
+ publicKey.SetExpiresAt(std::chrono::duration_cast<std::chrono::milliseconds>(key.ExpiresAt.time_since_epoch()).count());
+ // no private key here
+ }
+ }
+ {
+ auto& pbSids = *state.MutableSids();
+ pbSids.Clear();
+ for (const auto& [sidName, sidInfo] : Sids) {
+ NLoginProto::TSid& sid = *pbSids.Add();
+ sid.SetType(sidInfo.Type);
+ sid.SetName(sidInfo.Name);
+ for (const auto& subSid : sidInfo.Members) {
+ sid.AddMembers(subSid);
+ }
+ // no user hash here
+ }
+ }
+ return state;
+}
+
+void TLoginProvider::UpdateSecurityState(const NLoginProto::TSecurityState& state) {
+ Audience = state.GetAudience();
+ {
+ auto now = std::chrono::system_clock::now();
+ while (Keys.size() > MAX_CLIENT_KEYS || (!Keys.empty() && Keys.front().ExpiresAt <= now)) {
+ Keys.pop_front();
+ }
+
+ if (!Keys.empty() && state.PublicKeysSize() != 0) {
+ auto keyId = state.GetPublicKeys(0).GetKeyId();
+ auto itKey = FindKeyIterator(keyId);
+ Keys.erase(itKey, Keys.end()); // erase tail which we are going to reinsert later
+ }
+
+ for (const auto& pbPublicKey : state.GetPublicKeys()) {
+ Y_VERIFY(Keys.empty() || pbPublicKey.GetKeyId() == Keys.back().KeyId + 1);
+ Keys.push_back({
+ .KeyId = pbPublicKey.GetKeyId(),
+ .PublicKey = pbPublicKey.GetKeyDataPEM(),
+ .ExpiresAt = std::chrono::system_clock::time_point(std::chrono::milliseconds(pbPublicKey.GetExpiresAt())),
+ });
+ }
+ }
+ {
+ Sids.clear();
+ ChildToParentIndex.clear();
+ for (const auto& pbSid : state.GetSids()) {
+ TSidRecord& sid = Sids[pbSid.GetName()];
+ sid.Type = pbSid.GetType();
+ sid.Name = pbSid.GetName();
+ sid.Hash = pbSid.GetHash();
+ for (const auto& pbSubSid : pbSid.GetMembers()) {
+ sid.Members.emplace(pbSubSid);
+ ChildToParentIndex[pbSubSid].emplace(sid.Name);
+ }
+ }
+ }
+}
+
+}
diff --git a/ydb/library/login/login.h b/ydb/library/login/login.h
index d0c5d9009ca..c56f5a22883 100644
--- a/ydb/library/login/login.h
+++ b/ydb/library/login/login.h
@@ -1,162 +1,162 @@
-#pragma once
-#include <optional>
-#include <map>
-#include <unordered_map>
-#include <unordered_set>
-#include <vector>
-#include <deque>
-#include <util/generic/string.h>
+#pragma once
+#include <optional>
+#include <map>
+#include <unordered_map>
+#include <unordered_set>
+#include <vector>
+#include <deque>
+#include <util/generic/string.h>
#include <ydb/library/login/protos/login.pb.h>
-
-namespace NLogin {
-
-using NLoginProto::ESidType;
-
-class TLoginProvider {
-public:
- static constexpr size_t MAX_SERVER_KEYS = 1000;
- static constexpr size_t MAX_CLIENT_KEYS = 100000;
- static constexpr auto KEYS_ROTATION_PERIOD = std::chrono::hours(6);
- static constexpr auto KEY_EXPIRE_TIME = std::chrono::hours(24);
-
- static constexpr size_t SALT_SIZE = 16;
- static constexpr size_t HASH_SIZE = 32;
-
- static constexpr const char* GROUPS_CLAIM_NAME = "https://ydb.tech/groups";
- static constexpr auto MAX_TOKEN_EXPIRE_TIME = std::chrono::hours(12);
-
- struct TBasicRequest {};
-
- struct TBasicResponse {
- TString Error;
- };
-
- struct TLoginUserRequest : TBasicRequest {
- struct TOptions {
- bool WithUserGroups = false;
- std::chrono::system_clock::duration ExpiresAfter = std::chrono::system_clock::duration::zero();
- };
-
- TString User;
- TString Password;
- TOptions Options;
- };
-
- struct TLoginUserResponse : TBasicResponse {
- TString Token;
- };
-
- struct TValidateTokenRequest : TBasicRequest {
- TString Token;
- };
-
- struct TValidateTokenResponse : TBasicResponse {
- bool TokenUnrecognized = false;
- bool ErrorRetryable = false;
- TString User;
- std::optional<std::vector<TString>> Groups;
- std::chrono::system_clock::time_point ExpiresAt;
- };
-
- struct TCreateUserRequest : TBasicRequest {
- TString User;
- TString Password;
- };
-
- struct TModifyUserRequest : TBasicRequest {
- TString User;
- TString Password;
- };
-
- struct TRemoveUserRequest : TBasicRequest {
- TString User;
- };
-
- struct TRemoveUserResponse : TBasicResponse {
- std::vector<TString> TouchedGroups;
- };
-
- struct TCreateGroupRequest : TBasicRequest {
- TString Group;
- };
-
- struct TAddGroupMembershipRequest : TBasicRequest {
- TString Group;
- TString Member;
- };
-
- struct TRemoveGroupMembershipRequest : TBasicRequest {
- TString Group;
- TString Member;
- };
-
- struct TRemoveGroupRequest : TBasicRequest {
- TString Group;
- };
-
- struct TRemoveGroupResponse : TBasicResponse {
- std::vector<TString> TouchedGroups;
- };
-
- struct TKeyRecord {
- ui64 KeyId;
- TString PublicKey;
- TString PrivateKey;
- std::chrono::system_clock::time_point ExpiresAt;
- };
-
- std::deque<TKeyRecord> Keys; // it's always ordered by KeyId
- std::chrono::time_point<std::chrono::system_clock> KeysRotationTime;
-
- struct TSidRecord {
- ESidType::SidType Type = ESidType::UNKNOWN;
- TString Name;
- TString Hash;
- std::unordered_set<TString> Members;
- };
-
- // our current audience (database name)
- TString Audience;
-
- // all users and theirs hashs
- std::unordered_map<TString, TSidRecord> Sids;
-
- // index for fast traversal
- std::unordered_map<TString, std::unordered_set<TString>> ChildToParentIndex;
-
- // servers duty to call this method periodically (and publish PublicKeys after that)
- const TKeyRecord* FindKey(ui64 keyId);
- void RotateKeys();
- void RotateKeys(std::vector<ui64>& keysExpired, std::vector<ui64>& keysAdded);
- bool IsItTimeToRotateKeys() const;
- NLoginProto::TSecurityState GetSecurityState() const;
- void UpdateSecurityState(const NLoginProto::TSecurityState& state);
-
- TLoginUserResponse LoginUser(const TLoginUserRequest& request);
- TValidateTokenResponse ValidateToken(const TValidateTokenRequest& request);
-
- TBasicResponse CreateUser(const TCreateUserRequest& request);
- TBasicResponse ModifyUser(const TModifyUserRequest& request);
- TRemoveUserResponse RemoveUser(const TRemoveUserRequest& request);
-
- TBasicResponse CreateGroup(const TCreateGroupRequest& request);
- TBasicResponse AddGroupMembership(const TAddGroupMembershipRequest& request);
- TBasicResponse RemoveGroupMembership(const TRemoveGroupMembershipRequest& request);
- TRemoveGroupResponse RemoveGroup(const TRemoveGroupRequest& request);
-
- TLoginProvider();
- ~TLoginProvider();
-
- std::vector<TString> GetGroupsMembership(const TString& member);
- static TString GetTokenAudience(const TString& token);
- static std::chrono::system_clock::time_point GetTokenExpiresAt(const TString& token);
-
-private:
- std::deque<TKeyRecord>::iterator FindKeyIterator(ui64 keyId);
- static bool CheckAllowedName(const TString& name);
-
- struct TImpl;
- THolder<TImpl> Impl;
-};
-
-}
+
+namespace NLogin {
+
+using NLoginProto::ESidType;
+
+class TLoginProvider {
+public:
+ static constexpr size_t MAX_SERVER_KEYS = 1000;
+ static constexpr size_t MAX_CLIENT_KEYS = 100000;
+ static constexpr auto KEYS_ROTATION_PERIOD = std::chrono::hours(6);
+ static constexpr auto KEY_EXPIRE_TIME = std::chrono::hours(24);
+
+ static constexpr size_t SALT_SIZE = 16;
+ static constexpr size_t HASH_SIZE = 32;
+
+ static constexpr const char* GROUPS_CLAIM_NAME = "https://ydb.tech/groups";
+ static constexpr auto MAX_TOKEN_EXPIRE_TIME = std::chrono::hours(12);
+
+ struct TBasicRequest {};
+
+ struct TBasicResponse {
+ TString Error;
+ };
+
+ struct TLoginUserRequest : TBasicRequest {
+ struct TOptions {
+ bool WithUserGroups = false;
+ std::chrono::system_clock::duration ExpiresAfter = std::chrono::system_clock::duration::zero();
+ };
+
+ TString User;
+ TString Password;
+ TOptions Options;
+ };
+
+ struct TLoginUserResponse : TBasicResponse {
+ TString Token;
+ };
+
+ struct TValidateTokenRequest : TBasicRequest {
+ TString Token;
+ };
+
+ struct TValidateTokenResponse : TBasicResponse {
+ bool TokenUnrecognized = false;
+ bool ErrorRetryable = false;
+ TString User;
+ std::optional<std::vector<TString>> Groups;
+ std::chrono::system_clock::time_point ExpiresAt;
+ };
+
+ struct TCreateUserRequest : TBasicRequest {
+ TString User;
+ TString Password;
+ };
+
+ struct TModifyUserRequest : TBasicRequest {
+ TString User;
+ TString Password;
+ };
+
+ struct TRemoveUserRequest : TBasicRequest {
+ TString User;
+ };
+
+ struct TRemoveUserResponse : TBasicResponse {
+ std::vector<TString> TouchedGroups;
+ };
+
+ struct TCreateGroupRequest : TBasicRequest {
+ TString Group;
+ };
+
+ struct TAddGroupMembershipRequest : TBasicRequest {
+ TString Group;
+ TString Member;
+ };
+
+ struct TRemoveGroupMembershipRequest : TBasicRequest {
+ TString Group;
+ TString Member;
+ };
+
+ struct TRemoveGroupRequest : TBasicRequest {
+ TString Group;
+ };
+
+ struct TRemoveGroupResponse : TBasicResponse {
+ std::vector<TString> TouchedGroups;
+ };
+
+ struct TKeyRecord {
+ ui64 KeyId;
+ TString PublicKey;
+ TString PrivateKey;
+ std::chrono::system_clock::time_point ExpiresAt;
+ };
+
+ std::deque<TKeyRecord> Keys; // it's always ordered by KeyId
+ std::chrono::time_point<std::chrono::system_clock> KeysRotationTime;
+
+ struct TSidRecord {
+ ESidType::SidType Type = ESidType::UNKNOWN;
+ TString Name;
+ TString Hash;
+ std::unordered_set<TString> Members;
+ };
+
+ // our current audience (database name)
+ TString Audience;
+
+ // all users and theirs hashs
+ std::unordered_map<TString, TSidRecord> Sids;
+
+ // index for fast traversal
+ std::unordered_map<TString, std::unordered_set<TString>> ChildToParentIndex;
+
+ // servers duty to call this method periodically (and publish PublicKeys after that)
+ const TKeyRecord* FindKey(ui64 keyId);
+ void RotateKeys();
+ void RotateKeys(std::vector<ui64>& keysExpired, std::vector<ui64>& keysAdded);
+ bool IsItTimeToRotateKeys() const;
+ NLoginProto::TSecurityState GetSecurityState() const;
+ void UpdateSecurityState(const NLoginProto::TSecurityState& state);
+
+ TLoginUserResponse LoginUser(const TLoginUserRequest& request);
+ TValidateTokenResponse ValidateToken(const TValidateTokenRequest& request);
+
+ TBasicResponse CreateUser(const TCreateUserRequest& request);
+ TBasicResponse ModifyUser(const TModifyUserRequest& request);
+ TRemoveUserResponse RemoveUser(const TRemoveUserRequest& request);
+
+ TBasicResponse CreateGroup(const TCreateGroupRequest& request);
+ TBasicResponse AddGroupMembership(const TAddGroupMembershipRequest& request);
+ TBasicResponse RemoveGroupMembership(const TRemoveGroupMembershipRequest& request);
+ TRemoveGroupResponse RemoveGroup(const TRemoveGroupRequest& request);
+
+ TLoginProvider();
+ ~TLoginProvider();
+
+ std::vector<TString> GetGroupsMembership(const TString& member);
+ static TString GetTokenAudience(const TString& token);
+ static std::chrono::system_clock::time_point GetTokenExpiresAt(const TString& token);
+
+private:
+ std::deque<TKeyRecord>::iterator FindKeyIterator(ui64 keyId);
+ static bool CheckAllowedName(const TString& name);
+
+ struct TImpl;
+ THolder<TImpl> Impl;
+};
+
+}
diff --git a/ydb/library/login/login_ut.cpp b/ydb/library/login/login_ut.cpp
index d42ffde22ff..7f1fa0d6d6b 100644
--- a/ydb/library/login/login_ut.cpp
+++ b/ydb/library/login/login_ut.cpp
@@ -1,202 +1,202 @@
-#include <library/cpp/testing/unittest/registar.h>
-#include <util/generic/algorithm.h>
-#include "login.h"
-
-using namespace NLogin;
-
-Y_UNIT_TEST_SUITE(Login) {
- void none() {}
-
- Y_UNIT_TEST(TestSuccessfulLogin1) {
- TLoginProvider provider;
- provider.Audience = "test_audience1";
- provider.RotateKeys();
- TLoginProvider::TCreateUserRequest request1;
- request1.User = "user1";
- request1.Password = "password1";
- auto response1 = provider.CreateUser(request1);
- UNIT_ASSERT(!response1.Error);
- TLoginProvider::TLoginUserRequest request2;
- request2.User = request1.User;
- request2.Password = request1.Password;
- auto response2 = provider.LoginUser(request2);
- UNIT_ASSERT_VALUES_EQUAL(response2.Error, "");
- TLoginProvider::TValidateTokenRequest request3;
- request3.Token = response2.Token;
- auto response3 = provider.ValidateToken(request3);
- UNIT_ASSERT_VALUES_EQUAL(response3.Error, "");
- UNIT_ASSERT(response3.User == request1.User);
- }
-
- Y_UNIT_TEST(TestFailedLogin1) {
- TLoginProvider provider;
- provider.RotateKeys();
- TLoginProvider::TCreateUserRequest request1;
- request1.User = "user1";
- request1.Password = "password1";
- auto response1 = provider.CreateUser(request1);
- UNIT_ASSERT(!response1.Error);
- TLoginProvider::TLoginUserRequest request2;
- request2.User = request1.User;
- request2.Password = "wrong password";
- auto response2 = provider.LoginUser(request2);
- UNIT_ASSERT(response2.Error == "Invalid password");
- }
-
- Y_UNIT_TEST(TestFailedLogin2) {
- TLoginProvider provider;
- provider.RotateKeys();
- TLoginProvider::TCreateUserRequest request1;
- request1.User = "user1";
- request1.Password = "password1";
- auto response1 = provider.CreateUser(request1);
- UNIT_ASSERT(!response1.Error);
- TLoginProvider::TLoginUserRequest request2;
- request2.User = "wrong user";
- request2.Password = request1.Password;
- auto response2 = provider.LoginUser(request2);
- UNIT_ASSERT(response2.Error == "Invalid user");
- }
-
- Y_UNIT_TEST(TestFailedLogin3) {
- TLoginProvider provider;
- provider.Audience = "test_audience1";
- provider.RotateKeys();
- TLoginProvider::TCreateUserRequest request1;
- request1.User = "user1";
- request1.Password = "password1";
- auto response1 = provider.CreateUser(request1);
- UNIT_ASSERT(!response1.Error);
- TLoginProvider::TLoginUserRequest request2;
- request2.User = request1.User;
- request2.Password = request1.Password;
- auto response2 = provider.LoginUser(request2);
- UNIT_ASSERT(response2.Error.empty());
- TLoginProvider::TValidateTokenRequest request3;
- request3.Token = response2.Token;
- provider.Audience = "test_audience2";
- auto response3 = provider.ValidateToken(request3);
- UNIT_ASSERT_VALUES_EQUAL(response3.Error, "Wrong audience");
- }
-
- Y_UNIT_TEST(TestGroups) {
- TLoginProvider provider;
- provider.Audience = "test_audience1";
- provider.RotateKeys();
- {
- auto response1 = provider.CreateUser({.User = "user1"});
- UNIT_ASSERT(!response1.Error);
- }
- {
- auto response1 = provider.CreateGroup({.Group = "group1"});
- UNIT_ASSERT(!response1.Error);
- }
- {
- auto response1 = provider.CreateGroup({.Group = "group1"});
- UNIT_ASSERT(response1.Error == "Group already exists");
- }
- {
- auto response1 = provider.CreateGroup({.Group = "group2"});
- UNIT_ASSERT(!response1.Error);
- }
- {
- auto response1 = provider.CreateGroup({.Group = "group3"});
- UNIT_ASSERT(!response1.Error);
- }
- {
- auto response1 = provider.CreateGroup({.Group = "group4"});
- UNIT_ASSERT(!response1.Error);
- }
- {
- auto response1 = provider.CreateGroup({.Group = "group5"});
- UNIT_ASSERT(!response1.Error);
- }
- {
- auto response1 = provider.AddGroupMembership({.Group = "group1", .Member = "group2"});
- UNIT_ASSERT(!response1.Error);
- }
- {
- auto response1 = provider.AddGroupMembership({.Group = "group1", .Member = "group3"});
- UNIT_ASSERT(!response1.Error);
- }
- {
- auto response1 = provider.AddGroupMembership({.Group = "group2", .Member = "group4"});
- UNIT_ASSERT(!response1.Error);
- }
- {
- auto response1 = provider.AddGroupMembership({.Group = "group3", .Member = "group5"});
- UNIT_ASSERT(!response1.Error);
- }
- {
- auto response1 = provider.AddGroupMembership({.Group = "group4", .Member = "user1"});
- UNIT_ASSERT(!response1.Error);
- }
- {
- auto groups = provider.GetGroupsMembership("user1");
- UNIT_ASSERT(groups.size() == 3);
- UNIT_ASSERT(Count(groups, "group1") == 1);
- UNIT_ASSERT(Count(groups, "group2") == 1);
- UNIT_ASSERT(Count(groups, "group4") == 1);
- }
- {
- auto response1 = provider.AddGroupMembership({.Group = "group5", .Member = "user1"});
- UNIT_ASSERT(!response1.Error);
- }
- {
- auto groups = provider.GetGroupsMembership("user1");
- UNIT_ASSERT(groups.size() == 5);
- UNIT_ASSERT(Count(groups, "group1") == 1);
- UNIT_ASSERT(Count(groups, "group2") == 1);
- UNIT_ASSERT(Count(groups, "group3") == 1);
- UNIT_ASSERT(Count(groups, "group4") == 1);
- UNIT_ASSERT(Count(groups, "group5") == 1);
- }
- {
- auto response1 = provider.RemoveGroupMembership({.Group = "group2", .Member = "group4"});
- UNIT_ASSERT(!response1.Error);
- }
- {
- auto groups = provider.GetGroupsMembership("user1");
- UNIT_ASSERT(groups.size() == 4);
- UNIT_ASSERT(Count(groups, "group1") == 1);
- UNIT_ASSERT(Count(groups, "group3") == 1);
- UNIT_ASSERT(Count(groups, "group4") == 1);
- UNIT_ASSERT(Count(groups, "group5") == 1);
- }
- {
- auto response1 = provider.RemoveUser({.User = "user1"});
- UNIT_ASSERT(!response1.Error);
- }
- {
- auto groups = provider.GetGroupsMembership("user1");
- UNIT_ASSERT(groups.empty());
- }
- }
-
- Y_UNIT_TEST(TestTokenWithGroups) {
- TLoginProvider provider;
- provider.Audience = "test_audience1";
- provider.RotateKeys();
- {
- auto response1 = provider.CreateUser({.User = "user1", .Password = "password1"});
- UNIT_ASSERT(!response1.Error);
- }
- {
- auto response1 = provider.CreateGroup({.Group = "group1"});
- UNIT_ASSERT(!response1.Error);
- }
- {
- auto response1 = provider.AddGroupMembership({.Group = "group1", .Member = "user1"});
- UNIT_ASSERT(!response1.Error);
- }
- {
- auto response1 = provider.LoginUser({.User = "user1", .Password = "password1", .Options = {.WithUserGroups = true}});
- UNIT_ASSERT(!response1.Error);
- auto response2 = provider.ValidateToken({.Token = response1.Token});
- UNIT_ASSERT(!response2.Error);
- UNIT_ASSERT(response2.Groups);
- UNIT_ASSERT(response2.Groups.value().size() == 1);
- UNIT_ASSERT(response2.Groups.value()[0] == "group1");
- }
- }
-}
+#include <library/cpp/testing/unittest/registar.h>
+#include <util/generic/algorithm.h>
+#include "login.h"
+
+using namespace NLogin;
+
+Y_UNIT_TEST_SUITE(Login) {
+ void none() {}
+
+ Y_UNIT_TEST(TestSuccessfulLogin1) {
+ TLoginProvider provider;
+ provider.Audience = "test_audience1";
+ provider.RotateKeys();
+ TLoginProvider::TCreateUserRequest request1;
+ request1.User = "user1";
+ request1.Password = "password1";
+ auto response1 = provider.CreateUser(request1);
+ UNIT_ASSERT(!response1.Error);
+ TLoginProvider::TLoginUserRequest request2;
+ request2.User = request1.User;
+ request2.Password = request1.Password;
+ auto response2 = provider.LoginUser(request2);
+ UNIT_ASSERT_VALUES_EQUAL(response2.Error, "");
+ TLoginProvider::TValidateTokenRequest request3;
+ request3.Token = response2.Token;
+ auto response3 = provider.ValidateToken(request3);
+ UNIT_ASSERT_VALUES_EQUAL(response3.Error, "");
+ UNIT_ASSERT(response3.User == request1.User);
+ }
+
+ Y_UNIT_TEST(TestFailedLogin1) {
+ TLoginProvider provider;
+ provider.RotateKeys();
+ TLoginProvider::TCreateUserRequest request1;
+ request1.User = "user1";
+ request1.Password = "password1";
+ auto response1 = provider.CreateUser(request1);
+ UNIT_ASSERT(!response1.Error);
+ TLoginProvider::TLoginUserRequest request2;
+ request2.User = request1.User;
+ request2.Password = "wrong password";
+ auto response2 = provider.LoginUser(request2);
+ UNIT_ASSERT(response2.Error == "Invalid password");
+ }
+
+ Y_UNIT_TEST(TestFailedLogin2) {
+ TLoginProvider provider;
+ provider.RotateKeys();
+ TLoginProvider::TCreateUserRequest request1;
+ request1.User = "user1";
+ request1.Password = "password1";
+ auto response1 = provider.CreateUser(request1);
+ UNIT_ASSERT(!response1.Error);
+ TLoginProvider::TLoginUserRequest request2;
+ request2.User = "wrong user";
+ request2.Password = request1.Password;
+ auto response2 = provider.LoginUser(request2);
+ UNIT_ASSERT(response2.Error == "Invalid user");
+ }
+
+ Y_UNIT_TEST(TestFailedLogin3) {
+ TLoginProvider provider;
+ provider.Audience = "test_audience1";
+ provider.RotateKeys();
+ TLoginProvider::TCreateUserRequest request1;
+ request1.User = "user1";
+ request1.Password = "password1";
+ auto response1 = provider.CreateUser(request1);
+ UNIT_ASSERT(!response1.Error);
+ TLoginProvider::TLoginUserRequest request2;
+ request2.User = request1.User;
+ request2.Password = request1.Password;
+ auto response2 = provider.LoginUser(request2);
+ UNIT_ASSERT(response2.Error.empty());
+ TLoginProvider::TValidateTokenRequest request3;
+ request3.Token = response2.Token;
+ provider.Audience = "test_audience2";
+ auto response3 = provider.ValidateToken(request3);
+ UNIT_ASSERT_VALUES_EQUAL(response3.Error, "Wrong audience");
+ }
+
+ Y_UNIT_TEST(TestGroups) {
+ TLoginProvider provider;
+ provider.Audience = "test_audience1";
+ provider.RotateKeys();
+ {
+ auto response1 = provider.CreateUser({.User = "user1"});
+ UNIT_ASSERT(!response1.Error);
+ }
+ {
+ auto response1 = provider.CreateGroup({.Group = "group1"});
+ UNIT_ASSERT(!response1.Error);
+ }
+ {
+ auto response1 = provider.CreateGroup({.Group = "group1"});
+ UNIT_ASSERT(response1.Error == "Group already exists");
+ }
+ {
+ auto response1 = provider.CreateGroup({.Group = "group2"});
+ UNIT_ASSERT(!response1.Error);
+ }
+ {
+ auto response1 = provider.CreateGroup({.Group = "group3"});
+ UNIT_ASSERT(!response1.Error);
+ }
+ {
+ auto response1 = provider.CreateGroup({.Group = "group4"});
+ UNIT_ASSERT(!response1.Error);
+ }
+ {
+ auto response1 = provider.CreateGroup({.Group = "group5"});
+ UNIT_ASSERT(!response1.Error);
+ }
+ {
+ auto response1 = provider.AddGroupMembership({.Group = "group1", .Member = "group2"});
+ UNIT_ASSERT(!response1.Error);
+ }
+ {
+ auto response1 = provider.AddGroupMembership({.Group = "group1", .Member = "group3"});
+ UNIT_ASSERT(!response1.Error);
+ }
+ {
+ auto response1 = provider.AddGroupMembership({.Group = "group2", .Member = "group4"});
+ UNIT_ASSERT(!response1.Error);
+ }
+ {
+ auto response1 = provider.AddGroupMembership({.Group = "group3", .Member = "group5"});
+ UNIT_ASSERT(!response1.Error);
+ }
+ {
+ auto response1 = provider.AddGroupMembership({.Group = "group4", .Member = "user1"});
+ UNIT_ASSERT(!response1.Error);
+ }
+ {
+ auto groups = provider.GetGroupsMembership("user1");
+ UNIT_ASSERT(groups.size() == 3);
+ UNIT_ASSERT(Count(groups, "group1") == 1);
+ UNIT_ASSERT(Count(groups, "group2") == 1);
+ UNIT_ASSERT(Count(groups, "group4") == 1);
+ }
+ {
+ auto response1 = provider.AddGroupMembership({.Group = "group5", .Member = "user1"});
+ UNIT_ASSERT(!response1.Error);
+ }
+ {
+ auto groups = provider.GetGroupsMembership("user1");
+ UNIT_ASSERT(groups.size() == 5);
+ UNIT_ASSERT(Count(groups, "group1") == 1);
+ UNIT_ASSERT(Count(groups, "group2") == 1);
+ UNIT_ASSERT(Count(groups, "group3") == 1);
+ UNIT_ASSERT(Count(groups, "group4") == 1);
+ UNIT_ASSERT(Count(groups, "group5") == 1);
+ }
+ {
+ auto response1 = provider.RemoveGroupMembership({.Group = "group2", .Member = "group4"});
+ UNIT_ASSERT(!response1.Error);
+ }
+ {
+ auto groups = provider.GetGroupsMembership("user1");
+ UNIT_ASSERT(groups.size() == 4);
+ UNIT_ASSERT(Count(groups, "group1") == 1);
+ UNIT_ASSERT(Count(groups, "group3") == 1);
+ UNIT_ASSERT(Count(groups, "group4") == 1);
+ UNIT_ASSERT(Count(groups, "group5") == 1);
+ }
+ {
+ auto response1 = provider.RemoveUser({.User = "user1"});
+ UNIT_ASSERT(!response1.Error);
+ }
+ {
+ auto groups = provider.GetGroupsMembership("user1");
+ UNIT_ASSERT(groups.empty());
+ }
+ }
+
+ Y_UNIT_TEST(TestTokenWithGroups) {
+ TLoginProvider provider;
+ provider.Audience = "test_audience1";
+ provider.RotateKeys();
+ {
+ auto response1 = provider.CreateUser({.User = "user1", .Password = "password1"});
+ UNIT_ASSERT(!response1.Error);
+ }
+ {
+ auto response1 = provider.CreateGroup({.Group = "group1"});
+ UNIT_ASSERT(!response1.Error);
+ }
+ {
+ auto response1 = provider.AddGroupMembership({.Group = "group1", .Member = "user1"});
+ UNIT_ASSERT(!response1.Error);
+ }
+ {
+ auto response1 = provider.LoginUser({.User = "user1", .Password = "password1", .Options = {.WithUserGroups = true}});
+ UNIT_ASSERT(!response1.Error);
+ auto response2 = provider.ValidateToken({.Token = response1.Token});
+ UNIT_ASSERT(!response2.Error);
+ UNIT_ASSERT(response2.Groups);
+ UNIT_ASSERT(response2.Groups.value().size() == 1);
+ UNIT_ASSERT(response2.Groups.value()[0] == "group1");
+ }
+ }
+}
diff --git a/ydb/library/login/protos/login.proto b/ydb/library/login/protos/login.proto
index 9c32495e200..a23c7ca461d 100644
--- a/ydb/library/login/protos/login.proto
+++ b/ydb/library/login/protos/login.proto
@@ -1,32 +1,32 @@
-syntax = "proto3";
-package NLoginProto;
-
-message TPublicKey {
- uint64 KeyId = 1; // sorted monotonic
- oneof KeyData {
- string KeyDataPEM = 2;
- }
- uint64 ExpiresAt = 9; // milliseconds
-}
-
-message ESidType {
- enum SidType {
- UNKNOWN = 0;
- USER = 1;
- GROUP = 2;
- }
-}
-
-message TSid {
- string Name = 1;
- ESidType.SidType Type = 2;
- string Hash = 3;
- repeated string Members = 4;
-}
-
-message TSecurityState {
- repeated TPublicKey PublicKeys = 1;
- repeated TSid Sids = 2;
- string Audience = 3;
-}
-
+syntax = "proto3";
+package NLoginProto;
+
+message TPublicKey {
+ uint64 KeyId = 1; // sorted monotonic
+ oneof KeyData {
+ string KeyDataPEM = 2;
+ }
+ uint64 ExpiresAt = 9; // milliseconds
+}
+
+message ESidType {
+ enum SidType {
+ UNKNOWN = 0;
+ USER = 1;
+ GROUP = 2;
+ }
+}
+
+message TSid {
+ string Name = 1;
+ ESidType.SidType Type = 2;
+ string Hash = 3;
+ repeated string Members = 4;
+}
+
+message TSecurityState {
+ repeated TPublicKey PublicKeys = 1;
+ repeated TSid Sids = 2;
+ string Audience = 3;
+}
+
diff --git a/ydb/library/login/protos/ya.make b/ydb/library/login/protos/ya.make
index 8c7da1af3dd..be87e2fd195 100644
--- a/ydb/library/login/protos/ya.make
+++ b/ydb/library/login/protos/ya.make
@@ -1,14 +1,14 @@
-PROTO_LIBRARY()
-
+PROTO_LIBRARY()
+
OWNER(
xenoxeno
g:kikimr
)
EXCLUDE_TAGS(GO_PROTO)
-
-SRCS(
- login.proto
-)
-
-END()
+
+SRCS(
+ login.proto
+)
+
+END()
diff --git a/ydb/library/login/ut/ya.make b/ydb/library/login/ut/ya.make
index 34d229504f7..af785460313 100644
--- a/ydb/library/login/ut/ya.make
+++ b/ydb/library/login/ut/ya.make
@@ -1,11 +1,11 @@
-UNITTEST_FOR(ydb/library/login)
-
-OWNER(xenoxeno g:kikimr)
-
-PEERDIR()
-
-SRCS(
- login_ut.cpp
-)
-
-END()
+UNITTEST_FOR(ydb/library/login)
+
+OWNER(xenoxeno g:kikimr)
+
+PEERDIR()
+
+SRCS(
+ login_ut.cpp
+)
+
+END()
diff --git a/ydb/library/login/ya.make b/ydb/library/login/ya.make
index ca6f94bdff7..356dca4d54f 100644
--- a/ydb/library/login/ya.make
+++ b/ydb/library/login/ya.make
@@ -1,24 +1,24 @@
-LIBRARY()
-
-PEERDIR(
+LIBRARY()
+
+PEERDIR(
contrib/libs/jwt-cpp
- contrib/libs/protobuf
- library/cpp/digest/argonish
- library/cpp/string_utils/base64
+ contrib/libs/protobuf
+ library/cpp/digest/argonish
+ library/cpp/string_utils/base64
ydb/library/login/protos
-)
-
+)
+
OWNER(
xenoxeno
g:kikimr
)
-
-SRCS(
- login.cpp
- login.h
-)
-END()
+SRCS(
+ login.cpp
+ login.h
+)
+
+END()
RECURSE_FOR_TESTS(
ut
diff --git a/ydb/library/mkql_proto/protos/minikql.proto b/ydb/library/mkql_proto/protos/minikql.proto
index c232a55f315..2a4243855c0 100644
--- a/ydb/library/mkql_proto/protos/minikql.proto
+++ b/ydb/library/mkql_proto/protos/minikql.proto
@@ -113,8 +113,8 @@ message TResult {
optional TType Type = 1;
optional TValue Value = 2;
}
-
-message TParams {
- optional TType Type = 1;
- optional TValue Value = 2;
-}
+
+message TParams {
+ optional TType Type = 1;
+ optional TValue Value = 2;
+}
diff --git a/ydb/library/mkql_proto/ut/ya.make b/ydb/library/mkql_proto/ut/ya.make
index e407e9457ec..3edb42746e1 100644
--- a/ydb/library/mkql_proto/ut/ya.make
+++ b/ydb/library/mkql_proto/ut/ya.make
@@ -1,4 +1,4 @@
-UNITTEST_FOR(ydb/library/mkql_proto)
+UNITTEST_FOR(ydb/library/mkql_proto)
OWNER(g:kikimr)
diff --git a/ydb/library/persqueue/topic_parser/ut/ya.make b/ydb/library/persqueue/topic_parser/ut/ya.make
index 048eb63036b..74fdbf0bcd9 100644
--- a/ydb/library/persqueue/topic_parser/ut/ya.make
+++ b/ydb/library/persqueue/topic_parser/ut/ya.make
@@ -1,4 +1,4 @@
-UNITTEST_FOR(ydb/library/persqueue/topic_parser)
+UNITTEST_FOR(ydb/library/persqueue/topic_parser)
OWNER(
komels
diff --git a/ydb/library/security/util.h b/ydb/library/security/util.h
index 53054d38d28..7f6d9791a2d 100644
--- a/ydb/library/security/util.h
+++ b/ydb/library/security/util.h
@@ -1,20 +1,20 @@
#pragma once
#include <util/generic/fwd.h>
-#include <util/datetime/base.h>
+#include <util/datetime/base.h>
namespace NKikimr {
TString MaskTicket(TStringBuf token);
TString MaskTicket(const TString& token);
-
- // copy-pasted from <robot/library/utils/time_convert.h>
- template<typename Rep, typename Period>
- constexpr ui64 ToMicroseconds(std::chrono::duration<Rep, Period> value) {
- return std::chrono::duration_cast<std::chrono::microseconds>(value).count();
- }
-
- template<typename Clock, typename Duration>
- constexpr TInstant ToInstant(std::chrono::time_point<Clock, Duration> value) {
- return TInstant::MicroSeconds(ToMicroseconds(value.time_since_epoch()));
- }
+
+ // copy-pasted from <robot/library/utils/time_convert.h>
+ template<typename Rep, typename Period>
+ constexpr ui64 ToMicroseconds(std::chrono::duration<Rep, Period> value) {
+ return std::chrono::duration_cast<std::chrono::microseconds>(value).count();
+ }
+
+ template<typename Clock, typename Duration>
+ constexpr TInstant ToInstant(std::chrono::time_point<Clock, Duration> value) {
+ return TInstant::MicroSeconds(ToMicroseconds(value.time_since_epoch()));
+ }
}
diff --git a/ydb/library/yql/minikql/mkql_node.cpp b/ydb/library/yql/minikql/mkql_node.cpp
index efc78d100c2..4c6f3e45ad4 100644
--- a/ydb/library/yql/minikql/mkql_node.cpp
+++ b/ydb/library/yql/minikql/mkql_node.cpp
@@ -35,7 +35,7 @@ TTypeEnvironment::TTypeEnvironment(TScopedAlloc& alloc)
Ui32 = TDataType::Create(NUdf::TDataType<ui32>::Id, *this);
Ui64 = TDataType::Create(NUdf::TDataType<ui64>::Id, *this);
AnyType = TAnyType::Create(TypeOfType, *this);
- EmptyStruct = TStructLiteral::Create(0, nullptr, TStructType::Create(0, nullptr, *this), *this);
+ EmptyStruct = TStructLiteral::Create(0, nullptr, TStructType::Create(0, nullptr, *this), *this);
EmptyTuple = TTupleLiteral::Create(0, nullptr, TTupleType::Create(0, nullptr, *this), *this);
ListOfVoid = TListLiteral::Create(nullptr, 0, TListType::Create(Void->GetGenericType(), *this), *this);
}
@@ -54,7 +54,7 @@ void TTypeEnvironment::ClearCookies() const {
TypeOfEmptyDict->SetCookie(0);
EmptyDict->SetCookie(0);
EmptyStruct->SetCookie(0);
- ListOfVoid->SetCookie(0);
+ ListOfVoid->SetCookie(0);
AnyType->SetCookie(0);
EmptyTuple->SetCookie(0);
}
@@ -492,10 +492,10 @@ TStructType* TStructType::Create(const std::pair<TString, TType*>* members, ui32
}
}
- return ::new(env.Allocate<TStructType>()) TStructType(membersCount, allocatedMembers, env);
+ return ::new(env.Allocate<TStructType>()) TStructType(membersCount, allocatedMembers, env);
}
-TStructType* TStructType::Create(ui32 membersCount, const TStructMember* members, const TTypeEnvironment& env) {
+TStructType* TStructType::Create(ui32 membersCount, const TStructMember* members, const TTypeEnvironment& env) {
std::pair<TInternName, TType*>* allocatedMembers = nullptr;
if (membersCount) {
allocatedMembers = static_cast<std::pair<TInternName, TType*>*>(env.AllocateBuffer(membersCount * sizeof(*allocatedMembers)));
@@ -504,14 +504,14 @@ TStructType* TStructType::Create(ui32 membersCount, const TStructMember* members
}
}
- return ::new(env.Allocate<TStructType>()) TStructType(membersCount, allocatedMembers, env);
+ return ::new(env.Allocate<TStructType>()) TStructType(membersCount, allocatedMembers, env);
}
bool TStructType::IsSameType(const TStructType& typeToCompare) const {
if (this == &typeToCompare)
return true;
- if (MembersCount != typeToCompare.MembersCount)
+ if (MembersCount != typeToCompare.MembersCount)
return false;
for (size_t index = 0; index < MembersCount; ++index) {
@@ -528,7 +528,7 @@ bool TStructType::IsConvertableTo(const TStructType& typeToCompare, bool ignoreT
if (this == &typeToCompare)
return true;
- if (MembersCount != typeToCompare.MembersCount)
+ if (MembersCount != typeToCompare.MembersCount)
return false;
for (size_t index = 0; index < MembersCount; ++index) {
@@ -579,7 +579,7 @@ TNode* TStructType::DoCloneOnCallableWrite(const TTypeEnvironment& env) const {
}
}
- return ::new(env.Allocate<TStructType>()) TStructType(MembersCount, allocatedMembers, env, false);
+ return ::new(env.Allocate<TStructType>()) TStructType(MembersCount, allocatedMembers, env, false);
}
void TStructType::DoFreeze(const TTypeEnvironment& env) {
@@ -719,20 +719,20 @@ bool TStructLiteral::Equals(const TStructLiteral& nodeToCompare) const {
return true;
}
-TListType::TListType(TType* itemType, const TTypeEnvironment& env, bool validate)
+TListType::TListType(TType* itemType, const TTypeEnvironment& env, bool validate)
: TType(EKind::List, env.GetTypeOfType())
- , Data(itemType)
+ , Data(itemType)
, IndexDictKey(env.GetUi64())
{
Y_UNUSED(validate);
}
-TListType* TListType::Create(TType* itemType, const TTypeEnvironment& env) {
- return ::new(env.Allocate<TListType>()) TListType(itemType, env);
+TListType* TListType::Create(TType* itemType, const TTypeEnvironment& env) {
+ return ::new(env.Allocate<TListType>()) TListType(itemType, env);
}
bool TListType::IsSameType(const TListType& typeToCompare) const {
- return GetItemType()->IsSameType(*typeToCompare.GetItemType());
+ return GetItemType()->IsSameType(*typeToCompare.GetItemType());
}
bool TListType::IsConvertableTo(const TListType& typeToCompare, bool ignoreTagged) const {
@@ -744,7 +744,7 @@ void TListType::DoUpdateLinks(const THashMap<TNode*, TNode*>& links) {
if (itemTypeIt != links.end()) {
TNode* newNode = itemTypeIt->second;
Y_VERIFY_DEBUG(GetItemType()->Equals(*newNode));
- Data = static_cast<TType*>(newNode);
+ Data = static_cast<TType*>(newNode);
}
}
@@ -971,19 +971,19 @@ void TFlowType::DoFreeze(const TTypeEnvironment& env) {
Y_UNUSED(env);
}
-TOptionalType::TOptionalType(TType* itemType, const TTypeEnvironment& env, bool validate)
+TOptionalType::TOptionalType(TType* itemType, const TTypeEnvironment& env, bool validate)
: TType(EKind::Optional, env.GetTypeOfType())
- , Data(itemType)
+ , Data(itemType)
{
Y_UNUSED(validate);
}
-TOptionalType* TOptionalType::Create(TType* itemType, const TTypeEnvironment& env) {
- return ::new(env.Allocate<TOptionalType>()) TOptionalType(itemType, env);
+TOptionalType* TOptionalType::Create(TType* itemType, const TTypeEnvironment& env) {
+ return ::new(env.Allocate<TOptionalType>()) TOptionalType(itemType, env);
}
bool TOptionalType::IsSameType(const TOptionalType& typeToCompare) const {
- return GetItemType()->IsSameType(*typeToCompare.GetItemType());
+ return GetItemType()->IsSameType(*typeToCompare.GetItemType());
}
bool TOptionalType::IsConvertableTo(const TOptionalType& typeToCompare, bool ignoreTagged) const {
@@ -995,7 +995,7 @@ void TOptionalType::DoUpdateLinks(const THashMap<TNode*, TNode*>& links) {
if (itemTypeIt != links.end()) {
TNode* newNode = itemTypeIt->second;
Y_VERIFY_DEBUG(GetItemType()->Equals(*newNode));
- Data = static_cast<TType*>(newNode);
+ Data = static_cast<TType*>(newNode);
}
}
@@ -1130,12 +1130,12 @@ bool TOptionalLiteral::Equals(const TOptionalLiteral& nodeToCompare) const {
return !Item.GetNode() || Item.GetNode()->Equals(*nodeToCompare.Item.GetNode());
}
-TDictType* TDictType::Create(TType* keyType, TType* payloadType, const TTypeEnvironment& env) {
- return ::new(env.Allocate<TDictType>()) TDictType(keyType, payloadType, env);
+TDictType* TDictType::Create(TType* keyType, TType* payloadType, const TTypeEnvironment& env) {
+ return ::new(env.Allocate<TDictType>()) TDictType(keyType, payloadType, env);
}
bool TDictType::IsSameType(const TDictType& typeToCompare) const {
- return KeyType->IsSameType(*typeToCompare.KeyType)
+ return KeyType->IsSameType(*typeToCompare.KeyType)
&& PayloadType->IsSameType(*typeToCompare.PayloadType);
}
@@ -1176,7 +1176,7 @@ void TDictType::DoFreeze(const TTypeEnvironment& env) {
Y_UNUSED(env);
}
-TDictType::TDictType(TType* keyType, TType* payloadType, const TTypeEnvironment& env, bool validate)
+TDictType::TDictType(TType* keyType, TType* payloadType, const TTypeEnvironment& env, bool validate)
: TType(EKind::Dict, env.GetTypeOfType())
, KeyType(keyType)
, PayloadType(payloadType)
@@ -1320,7 +1320,7 @@ bool TDictLiteral::Equals(const TDictLiteral& nodeToCompare) const {
}
TCallableType::TCallableType(const TInternName &name, TType* returnType, ui32 argumentsCount,
- TType **arguments, TNode* payload, const TTypeEnvironment& env)
+ TType **arguments, TNode* payload, const TTypeEnvironment& env)
: TType(EKind::Callable, env.GetTypeOfType())
, IsMergeDisabled0(false)
, ArgumentsCount(argumentsCount)
@@ -1333,32 +1333,32 @@ TCallableType::TCallableType(const TInternName &name, TType* returnType, ui32 ar
}
TCallableType* TCallableType::Create(const TString& name, TType* returnType,
- ui32 argumentsCount, TType** arguments, TNode* payload, const TTypeEnvironment& env) {
+ ui32 argumentsCount, TType** arguments, TNode* payload, const TTypeEnvironment& env) {
auto internedName = env.InternName(name);
- TType** allocatedArguments = nullptr;
+ TType** allocatedArguments = nullptr;
if (argumentsCount) {
- allocatedArguments = static_cast<TType**>(env.AllocateBuffer(argumentsCount * sizeof(*allocatedArguments)));
+ allocatedArguments = static_cast<TType**>(env.AllocateBuffer(argumentsCount * sizeof(*allocatedArguments)));
for (ui32 i = 0; i < argumentsCount; ++i) {
allocatedArguments[i] = arguments[i];
}
}
- return ::new(env.Allocate<TCallableType>()) TCallableType(internedName, returnType, argumentsCount,
+ return ::new(env.Allocate<TCallableType>()) TCallableType(internedName, returnType, argumentsCount,
allocatedArguments, payload, env);
}
-TCallableType* TCallableType::Create(TType* returnType, const TStringBuf& name, ui32 argumentsCount,
- TType** arguments, TNode* payload, const TTypeEnvironment& env) {
+TCallableType* TCallableType::Create(TType* returnType, const TStringBuf& name, ui32 argumentsCount,
+ TType** arguments, TNode* payload, const TTypeEnvironment& env) {
auto internedName = env.InternName(name);
- TType** allocatedArguments = nullptr;
+ TType** allocatedArguments = nullptr;
if (argumentsCount) {
- allocatedArguments = static_cast<TType**>(env.AllocateBuffer(argumentsCount * sizeof(*allocatedArguments)));
+ allocatedArguments = static_cast<TType**>(env.AllocateBuffer(argumentsCount * sizeof(*allocatedArguments)));
for (ui32 i = 0; i < argumentsCount; ++i) {
allocatedArguments[i] = arguments[i];
}
}
- return ::new(env.Allocate<TCallableType>()) TCallableType(internedName, returnType, argumentsCount,
+ return ::new(env.Allocate<TCallableType>()) TCallableType(internedName, returnType, argumentsCount,
allocatedArguments, payload, env);
}
@@ -1366,7 +1366,7 @@ bool TCallableType::IsSameType(const TCallableType& typeToCompare) const {
if (this == &typeToCompare)
return true;
- if (Name != typeToCompare.Name || IsMergeDisabled0 != typeToCompare.IsMergeDisabled0)
+ if (Name != typeToCompare.Name || IsMergeDisabled0 != typeToCompare.IsMergeDisabled0)
return false;
if (ArgumentsCount != typeToCompare.ArgumentsCount)
@@ -1376,9 +1376,9 @@ bool TCallableType::IsSameType(const TCallableType& typeToCompare) const {
return false;
for (size_t index = 0; index < ArgumentsCount; ++index) {
- const auto arg = Arguments[index];
- const auto otherArg = typeToCompare.Arguments[index];
- if (!arg->IsSameType(*otherArg))
+ const auto arg = Arguments[index];
+ const auto otherArg = typeToCompare.Arguments[index];
+ if (!arg->IsSameType(*otherArg))
return false;
}
@@ -1397,7 +1397,7 @@ bool TCallableType::IsConvertableTo(const TCallableType& typeToCompare, bool ign
if (this == &typeToCompare)
return true;
- if (IsMergeDisabled0 != typeToCompare.IsMergeDisabled0)
+ if (IsMergeDisabled0 != typeToCompare.IsMergeDisabled0)
return false;
if (ArgumentsCount != typeToCompare.ArgumentsCount)
@@ -1409,8 +1409,8 @@ bool TCallableType::IsConvertableTo(const TCallableType& typeToCompare, bool ign
return false;
for (size_t index = 0; index < ArgumentsCount; ++index) {
- const auto arg = Arguments[index];
- const auto otherArg = typeToCompare.Arguments[index];
+ const auto arg = Arguments[index];
+ const auto otherArg = typeToCompare.Arguments[index];
if (!arg->IsConvertableTo(*otherArg, ignoreTagged))
return false;
}
@@ -1426,7 +1426,7 @@ void TCallableType::SetOptionalArgumentsCount(ui32 count) {
ArgumentsCount << " arguments");
OptionalArgs = count;
for (ui32 index = ArgumentsCount - OptionalArgs; index < ArgumentsCount; ++index) {
- MKQL_ENSURE(Arguments[index]->IsOptional(), "Optional argument #" << (index + 1) << " must be an optional");
+ MKQL_ENSURE(Arguments[index]->IsOptional(), "Optional argument #" << (index + 1) << " must be an optional");
}
}
@@ -1440,11 +1440,11 @@ void TCallableType::DoUpdateLinks(const THashMap<TNode*, TNode*>& links) {
for (ui32 i = 0; i < ArgumentsCount; ++i) {
auto& arg = Arguments[i];
- auto argIt = links.find(arg);
+ auto argIt = links.find(arg);
if (argIt != links.end()) {
TNode* newNode = argIt->second;
Y_VERIFY_DEBUG(arg->Equals(*newNode));
- arg = static_cast<TType*>(newNode);
+ arg = static_cast<TType*>(newNode);
}
}
@@ -1476,9 +1476,9 @@ TNode* TCallableType::DoCloneOnCallableWrite(const TTypeEnvironment& env) const
if (!needClone)
return const_cast<TCallableType*>(this);
- TType** allocatedArguments = nullptr;
+ TType** allocatedArguments = nullptr;
if (ArgumentsCount) {
- allocatedArguments = static_cast<TType**>(env.AllocateBuffer(ArgumentsCount * sizeof(*allocatedArguments)));
+ allocatedArguments = static_cast<TType**>(env.AllocateBuffer(ArgumentsCount * sizeof(*allocatedArguments)));
for (ui32 i = 0; i < ArgumentsCount; ++i) {
allocatedArguments[i] = Arguments[i];
auto newArgNode = (TNode*)Arguments[i]->GetCookie();
@@ -1517,7 +1517,7 @@ TCallable::TCallable(ui32 inputsCount, TRuntimeNode* inputs, TCallableType* type
for (size_t index = 0; index < inputsCount; ++index) {
auto& node = Inputs[index];
const auto argType = type->GetArgumentType(index);
- MKQL_ENSURE(node.GetStaticType()->IsSameType(*argType), "Wrong type of input");
+ MKQL_ENSURE(node.GetStaticType()->IsSameType(*argType), "Wrong type of input");
node.Freeze();
}
@@ -1663,7 +1663,7 @@ void TCallable::SetResult(TRuntimeNode result, const TTypeEnvironment& env) {
MKQL_ENSURE(!Result.GetNode(), "result is already set");
MKQL_ENSURE(result.GetStaticType()->IsSameType(*GetType()->GetReturnType()),
- "incorrect result type of function " << GetType()->GetName()
+ "incorrect result type of function " << GetType()->GetName()
<< ", left: " << PrintNode(result.GetStaticType(), true)
<< ", right: " << PrintNode(GetType()->GetReturnType(), true));
@@ -1794,7 +1794,7 @@ bool TAny::Equals(const TAny& nodeToCompare) const {
return Item.GetNode()->Equals(*nodeToCompare.Item.GetNode());
}
-TTupleType::TTupleType(ui32 elementsCount, TType** elements, const TTypeEnvironment& env, bool validate)
+TTupleType::TTupleType(ui32 elementsCount, TType** elements, const TTypeEnvironment& env, bool validate)
: TType(EKind::Tuple, env.GetTypeOfType())
, ElementsCount(elementsCount)
, Elements(elements)
@@ -1803,7 +1803,7 @@ TTupleType::TTupleType(ui32 elementsCount, TType** elements, const TTypeEnvironm
return;
}
-TTupleType* TTupleType::Create(ui32 elementsCount, TType* const* elements, const TTypeEnvironment& env) {
+TTupleType* TTupleType::Create(ui32 elementsCount, TType* const* elements, const TTypeEnvironment& env) {
TType** allocatedElements = nullptr;
if (elementsCount) {
allocatedElements = static_cast<TType**>(env.AllocateBuffer(elementsCount * sizeof(*allocatedElements)));
@@ -1812,14 +1812,14 @@ TTupleType* TTupleType::Create(ui32 elementsCount, TType* const* elements, const
}
}
- return ::new(env.Allocate<TTupleType>()) TTupleType(elementsCount, allocatedElements, env);
+ return ::new(env.Allocate<TTupleType>()) TTupleType(elementsCount, allocatedElements, env);
}
bool TTupleType::IsSameType(const TTupleType& typeToCompare) const {
if (this == &typeToCompare)
return true;
- if (ElementsCount != typeToCompare.ElementsCount)
+ if (ElementsCount != typeToCompare.ElementsCount)
return false;
for (size_t index = 0; index < ElementsCount; ++index) {
@@ -1834,7 +1834,7 @@ bool TTupleType::IsConvertableTo(const TTupleType& typeToCompare, bool ignoreTag
if (this == &typeToCompare)
return true;
- if (ElementsCount != typeToCompare.ElementsCount)
+ if (ElementsCount != typeToCompare.ElementsCount)
return false;
for (size_t index = 0; index < ElementsCount; ++index) {
@@ -1881,7 +1881,7 @@ TNode* TTupleType::DoCloneOnCallableWrite(const TTypeEnvironment& env) const {
}
}
- return ::new(env.Allocate<TTupleType>()) TTupleType(ElementsCount, allocatedElements, env, false);
+ return ::new(env.Allocate<TTupleType>()) TTupleType(ElementsCount, allocatedElements, env, false);
}
void TTupleType::DoFreeze(const TTypeEnvironment& env) {
diff --git a/ydb/library/yql/minikql/mkql_node.h b/ydb/library/yql/minikql/mkql_node.h
index 633903de6ba..ee74455ea69 100644
--- a/ydb/library/yql/minikql/mkql_node.h
+++ b/ydb/library/yql/minikql/mkql_node.h
@@ -58,7 +58,7 @@ struct TRuntimeNode {
~TRuntimeNode() {}
- TType* GetRuntimeType() const;
+ TType* GetRuntimeType() const;
TType* GetStaticType() const;
@@ -421,8 +421,8 @@ public:
return EmptyStruct;
}
- TListLiteral* GetListOfVoid() const {
- return ListOfVoid;
+ TListLiteral* GetListOfVoid() const {
+ return ListOfVoid;
}
TAnyType* GetAnyType() const {
@@ -490,7 +490,7 @@ private:
TAnyType* AnyType;
TStructLiteral* EmptyStruct;
TTupleLiteral* EmptyTuple;
- TListLiteral* ListOfVoid;
+ TListLiteral* ListOfVoid;
};
template <>
@@ -611,7 +611,7 @@ class TStructType : public TType {
friend class TType;
public:
static TStructType* Create(const std::pair<TString, TType*>* members, ui32 membersCount, const TTypeEnvironment& env);
- static TStructType* Create(ui32 membersCount, const TStructMember* members, const TTypeEnvironment& env);
+ static TStructType* Create(ui32 membersCount, const TStructMember* members, const TTypeEnvironment& env);
using TType::IsSameType;
bool IsSameType(const TStructType& typeToCompare) const;
@@ -686,7 +686,7 @@ private:
class TListType : public TType {
friend class TType;
public:
- static TListType* Create(TType* itemType, const TTypeEnvironment& env);
+ static TListType* Create(TType* itemType, const TTypeEnvironment& env);
using TType::IsSameType;
bool IsSameType(const TListType& typeToCompare) const;
@@ -695,7 +695,7 @@ public:
bool IsConvertableTo(const TListType& typeToCompare, bool ignoreTagged = false) const;
TType* GetItemType() const {
- return Data;
+ return Data;
}
TDataType* IndexDictKeyType() const {
@@ -703,14 +703,14 @@ public:
}
private:
- TListType(TType* itemType, const TTypeEnvironment& env, bool validate = true);
+ TListType(TType* itemType, const TTypeEnvironment& env, bool validate = true);
void DoUpdateLinks(const THashMap<TNode*, TNode*>& links);
TNode* DoCloneOnCallableWrite(const TTypeEnvironment& env) const;
void DoFreeze(const TTypeEnvironment& env);
private:
- TType* Data;
+ TType* Data;
TDataType* IndexDictKey;
};
@@ -800,7 +800,7 @@ private:
class TOptionalType : public TType {
friend class TType;
public:
- static TOptionalType* Create(TType* itemType, const TTypeEnvironment& env);
+ static TOptionalType* Create(TType* itemType, const TTypeEnvironment& env);
using TType::IsSameType;
bool IsSameType(const TOptionalType& typeToCompare) const;
@@ -809,18 +809,18 @@ public:
bool IsConvertableTo(const TOptionalType& typeToCompare, bool ignoreTagged = false) const;
TType* GetItemType() const {
- return Data;
+ return Data;
}
private:
- TOptionalType(TType* itemType, const TTypeEnvironment& env, bool validate = true);
+ TOptionalType(TType* itemType, const TTypeEnvironment& env, bool validate = true);
void DoUpdateLinks(const THashMap<TNode*, TNode*>& links);
TNode* DoCloneOnCallableWrite(const TTypeEnvironment& env) const;
void DoFreeze(const TTypeEnvironment& env);
private:
- TType* Data;
+ TType* Data;
};
class TOptionalLiteral : public TNode {
@@ -859,7 +859,7 @@ private:
class TDictType : public TType {
friend class TType;
public:
- static TDictType* Create(TType* keyType, TType* payloadType, const TTypeEnvironment& env);
+ static TDictType* Create(TType* keyType, TType* payloadType, const TTypeEnvironment& env);
using TType::IsSameType;
bool IsSameType(const TDictType& typeToCompare) const;
@@ -878,7 +878,7 @@ public:
static void EnsureValidDictKey(TType* keyType);
private:
- TDictType(TType* keyType, TType* payloadType, const TTypeEnvironment& env, bool validate = true);
+ TDictType(TType* keyType, TType* payloadType, const TTypeEnvironment& env, bool validate = true);
void DoUpdateLinks(const THashMap<TNode*, TNode*>& links);
TNode* DoCloneOnCallableWrite(const TTypeEnvironment& env) const;
@@ -924,9 +924,9 @@ class TCallableType : public TType {
friend class TType;
public:
static TCallableType* Create(const TString& name, TType* returnType, ui32 argumentsCount,
- TType** arguments, TNode* payload, const TTypeEnvironment& env);
- static TCallableType* Create(TType* returnType, const TStringBuf& name, ui32 argumentsCount,
- TType** arguments, TNode* payload, const TTypeEnvironment& env);
+ TType** arguments, TNode* payload, const TTypeEnvironment& env);
+ static TCallableType* Create(TType* returnType, const TStringBuf& name, ui32 argumentsCount,
+ TType** arguments, TNode* payload, const TTypeEnvironment& env);
void SetOptionalArgumentsCount(ui32 count);
ui32 GetOptionalArgumentsCount() const {
return OptionalArgs;
@@ -954,7 +954,7 @@ public:
return ArgumentsCount;
}
- TType* GetArgumentType(ui32 index) const {
+ TType* GetArgumentType(ui32 index) const {
Y_VERIFY_DEBUG(index < ArgumentsCount);
return Arguments[index];
}
@@ -973,7 +973,7 @@ public:
private:
TCallableType(const TInternName& name, TType* returnType, ui32 argumentsCount, TType** arguments,
- TNode* payload, const TTypeEnvironment& env);
+ TNode* payload, const TTypeEnvironment& env);
void DoUpdateLinks(const THashMap<TNode*, TNode*>& links);
TNode* DoCloneOnCallableWrite(const TTypeEnvironment& env) const;
@@ -984,7 +984,7 @@ private:
ui32 ArgumentsCount;
TInternName Name;
TType* ReturnType;
- TType** Arguments;
+ TType** Arguments;
TNode* Payload;
ui32 OptionalArgs;
};
@@ -1119,7 +1119,7 @@ private:
class TTupleType : public TType {
friend class TType;
public:
- static TTupleType* Create(ui32 elementsCount, TType* const* elements, const TTypeEnvironment& env);
+ static TTupleType* Create(ui32 elementsCount, TType* const* elements, const TTypeEnvironment& env);
using TType::IsSameType;
bool IsSameType(const TTupleType& typeToCompare) const;
@@ -1137,7 +1137,7 @@ public:
}
private:
- TTupleType(ui32 elemntsCount, TType** elements, const TTypeEnvironment& env, bool validate = true);
+ TTupleType(ui32 elemntsCount, TType** elements, const TTypeEnvironment& env, bool validate = true);
void DoUpdateLinks(const THashMap<TNode*, TNode*>& links);
TNode* DoCloneOnCallableWrite(const TTypeEnvironment& env) const;
@@ -1363,8 +1363,8 @@ inline bool TRuntimeNode::operator==(const TRuntimeNode& other) const {
return IsImmediate() == other.IsImmediate() && GetNode()->Equals(*other.GetNode());
}
-inline TType* TRuntimeNode::GetRuntimeType() const {
- return GetNode()->GetGenericType();
+inline TType* TRuntimeNode::GetRuntimeType() const {
+ return GetNode()->GetGenericType();
}
bool IsNumericType(NUdf::TDataTypeId typeId);
diff --git a/ydb/library/yql/minikql/mkql_node_builder.cpp b/ydb/library/yql/minikql/mkql_node_builder.cpp
index acbbc02c59d..34466b89446 100644
--- a/ydb/library/yql/minikql/mkql_node_builder.cpp
+++ b/ydb/library/yql/minikql/mkql_node_builder.cpp
@@ -56,17 +56,17 @@ TDataLiteral* BuildDataLiteral(const NUdf::TStringRef& data, NUdf::TDataTypeId t
}
TOptionalLiteral* BuildOptionalLiteral(TRuntimeNode value, const TTypeEnvironment& env) {
- auto type = TOptionalType::Create(value.GetStaticType(), env);
+ auto type = TOptionalType::Create(value.GetStaticType(), env);
return TOptionalLiteral::Create(value, type, env);
}
-TOptionalLiteral* BuildEmptyOptionalLiteral(TType *itemType, const TTypeEnvironment& env) {
- auto type = TOptionalType::Create(itemType, env);
+TOptionalLiteral* BuildEmptyOptionalLiteral(TType *itemType, const TTypeEnvironment& env) {
+ auto type = TOptionalType::Create(itemType, env);
return TOptionalLiteral::Create(type, env);
}
TOptionalLiteral* BuildEmptyOptionalDataLiteral(NUdf::TDataTypeId schemeType, const TTypeEnvironment& env) {
- return BuildEmptyOptionalLiteral(TDataType::Create(schemeType, env), env);
+ return BuildEmptyOptionalLiteral(TDataType::Create(schemeType, env), env);
}
TType* UnpackOptional(TRuntimeNode data, bool& isOptional) {
@@ -94,7 +94,7 @@ TDataType* UnpackOptionalData(TType* type, bool& isOptional) {
return static_cast<TDataType*>(unpackedType);
}
-TStructTypeBuilder::TStructTypeBuilder(const TTypeEnvironment& env)
+TStructTypeBuilder::TStructTypeBuilder(const TTypeEnvironment& env)
: Env(&env)
{
}
@@ -113,7 +113,7 @@ TStructType* TStructTypeBuilder::Build() {
return Env->GetEmptyStruct()->GetType();
Sort(Members.begin(), Members.end());
- return TStructType::Create(Members.size(), Members.data(), *Env);
+ return TStructType::Create(Members.size(), Members.data(), *Env);
}
void TStructTypeBuilder::FillIndexes() {
@@ -129,7 +129,7 @@ void TStructTypeBuilder::Clear() {
Members.clear();
}
-TStructLiteralBuilder::TStructLiteralBuilder(const TTypeEnvironment& env)
+TStructLiteralBuilder::TStructLiteralBuilder(const TTypeEnvironment& env)
: Env(&env)
{
}
@@ -169,7 +169,7 @@ TStructLiteral* TStructLiteralBuilder::Build() {
sortedValues[i] = Values[sortedIndicies[i].second];
}
- auto type = TStructType::Create(sortedMembers.size(), sortedMembers.data(), *Env);
+ auto type = TStructType::Create(sortedMembers.size(), sortedMembers.data(), *Env);
return TStructLiteral::Create(sortedValues.size(), sortedValues.data(), type, *Env);
}
@@ -177,7 +177,7 @@ void TStructLiteralBuilder::Clear() {
Members.clear();
}
-TListLiteralBuilder::TListLiteralBuilder(const TTypeEnvironment& env, TType* type)
+TListLiteralBuilder::TListLiteralBuilder(const TTypeEnvironment& env, TType* type)
: Env(&env)
, Type(type)
{}
@@ -188,7 +188,7 @@ TListLiteralBuilder& TListLiteralBuilder::Add(TRuntimeNode item) {
}
TListLiteral* TListLiteralBuilder::Build() {
- auto type = TListType::Create(Type, *Env);
+ auto type = TListType::Create(Type, *Env);
return TListLiteral::Create(Items.data(), Items.size(), type, *Env);
}
@@ -196,7 +196,7 @@ void TListLiteralBuilder::Clear() {
Items.clear();
}
-TDictLiteralBuilder::TDictLiteralBuilder(const TTypeEnvironment& env, TType* keyType, TType* payloadType)
+TDictLiteralBuilder::TDictLiteralBuilder(const TTypeEnvironment& env, TType* keyType, TType* payloadType)
: Env(&env)
, KeyType(keyType)
, PayloadType(payloadType)
@@ -213,7 +213,7 @@ TDictLiteralBuilder& TDictLiteralBuilder::Add(TRuntimeNode key, TRuntimeNode pay
}
TDictLiteral* TDictLiteralBuilder::Build() {
- auto type = TDictType::Create(KeyType, PayloadType, *Env);
+ auto type = TDictType::Create(KeyType, PayloadType, *Env);
return TDictLiteral::Create(Items.size(), Items.data(), type, *Env);
}
@@ -221,7 +221,7 @@ void TDictLiteralBuilder::Clear() {
Items.clear();
}
-TCallableTypeBuilder::TCallableTypeBuilder(const TTypeEnvironment& env, const TStringBuf& name, TType* returnType)
+TCallableTypeBuilder::TCallableTypeBuilder(const TTypeEnvironment& env, const TStringBuf& name, TType* returnType)
: Env(&env)
, Name(Env->InternName(name))
, ReturnType(returnType)
@@ -235,7 +235,7 @@ void TCallableTypeBuilder::Reserve(ui32 size) {
ArgFlags.reserve(size);
}
-TCallableTypeBuilder& TCallableTypeBuilder::Add(TType *type) {
+TCallableTypeBuilder& TCallableTypeBuilder::Add(TType *type) {
Arguments.push_back(type);
ArgNames.emplace_back();
ArgFlags.emplace_back();
@@ -287,7 +287,7 @@ void TCallableTypeBuilder::Clear() {
FuncPayload = TStringBuf();
}
-TCallableBuilder::TCallableBuilder(const TTypeEnvironment& env, const TStringBuf& name, TType* returnType, bool disableMerge)
+TCallableBuilder::TCallableBuilder(const TTypeEnvironment& env, const TStringBuf& name, TType* returnType, bool disableMerge)
: Env(&env)
, Name(Env->InternName(name))
, ReturnType(returnType)
@@ -303,9 +303,9 @@ void TCallableBuilder::Reserve(ui32 size) {
ArgFlags.reserve(size);
}
-TCallableBuilder& TCallableBuilder::Add(TRuntimeNode input) {
+TCallableBuilder& TCallableBuilder::Add(TRuntimeNode input) {
TType* inputType = input.GetStaticType();
- Arguments.push_back(inputType);
+ Arguments.push_back(inputType);
Inputs.push_back(input);
ArgNames.emplace_back();
ArgFlags.emplace_back();
diff --git a/ydb/library/yql/minikql/mkql_node_builder.h b/ydb/library/yql/minikql/mkql_node_builder.h
index 35cb2b8347e..46a43dc3529 100644
--- a/ydb/library/yql/minikql/mkql_node_builder.h
+++ b/ydb/library/yql/minikql/mkql_node_builder.h
@@ -16,7 +16,7 @@ inline TDataLiteral* BuildDataLiteral(const NUdf::TUnboxedValuePod& value, NUdf:
}
TOptionalLiteral* BuildOptionalLiteral(TRuntimeNode value, const TTypeEnvironment& env);
-TOptionalLiteral* BuildEmptyOptionalLiteral(TType* itemType, const TTypeEnvironment& env);
+TOptionalLiteral* BuildEmptyOptionalLiteral(TType* itemType, const TTypeEnvironment& env);
TOptionalLiteral* BuildEmptyOptionalDataLiteral(NUdf::TDataTypeId schemeType, const TTypeEnvironment& env);
TType* UnpackOptional(TRuntimeNode data, bool& isOptional);
TType* UnpackOptional(TType* type, bool& isOptional);
@@ -25,7 +25,7 @@ TDataType* UnpackOptionalData(TType* type, bool& isOptional);
class TStructTypeBuilder {
public:
- TStructTypeBuilder(const TTypeEnvironment& env);
+ TStructTypeBuilder(const TTypeEnvironment& env);
TStructTypeBuilder(const TStructTypeBuilder&) = default;
TStructTypeBuilder& operator=(const TStructTypeBuilder&) = default;
void Reserve(ui32 size);
@@ -41,7 +41,7 @@ private:
class TListLiteralBuilder {
public:
- TListLiteralBuilder(const TTypeEnvironment& env, TType* type);
+ TListLiteralBuilder(const TTypeEnvironment& env, TType* type);
TListLiteralBuilder(const TListLiteralBuilder&) = default;
TListLiteralBuilder& operator=(const TListLiteralBuilder&) = default;
TListLiteralBuilder& Add(TRuntimeNode item);
@@ -56,7 +56,7 @@ private:
class TStructLiteralBuilder {
public:
- TStructLiteralBuilder(const TTypeEnvironment& env);
+ TStructLiteralBuilder(const TTypeEnvironment& env);
TStructLiteralBuilder(const TStructLiteralBuilder&) = default;
TStructLiteralBuilder& operator=(const TStructLiteralBuilder&) = default;
void Reserve(ui32 size);
@@ -72,7 +72,7 @@ private:
class TDictLiteralBuilder {
public:
- TDictLiteralBuilder(const TTypeEnvironment& env, TType* keyType, TType* payloadType);
+ TDictLiteralBuilder(const TTypeEnvironment& env, TType* keyType, TType* payloadType);
TDictLiteralBuilder(const TDictLiteralBuilder&) = default;
TDictLiteralBuilder& operator=(const TDictLiteralBuilder&) = default;
void Reserve(ui32 size);
@@ -89,11 +89,11 @@ private:
class TCallableTypeBuilder {
public:
- TCallableTypeBuilder(const TTypeEnvironment& env, const TStringBuf& name, TType* returnType);
+ TCallableTypeBuilder(const TTypeEnvironment& env, const TStringBuf& name, TType* returnType);
TCallableTypeBuilder(const TCallableTypeBuilder&) = default;
TCallableTypeBuilder& operator=(const TCallableTypeBuilder&) = default;
void Reserve(ui32 size);
- TCallableTypeBuilder& Add(TType* time);
+ TCallableTypeBuilder& Add(TType* time);
TCallableTypeBuilder& SetArgumentName(const TStringBuf& name);
TCallableTypeBuilder& SetArgumentFlags(ui64 flags);
TCallableTypeBuilder& SetOptionalArgs(ui32 count);
@@ -116,11 +116,11 @@ private:
class TCallableBuilder {
public:
TCallableBuilder(const TTypeEnvironment& env, const TStringBuf& name, TType* returnType,
- bool disableMerge = false);
+ bool disableMerge = false);
TCallableBuilder(const TCallableBuilder&) = default;
TCallableBuilder& operator=(const TCallableBuilder&) = default;
void Reserve(ui32 size);
- TCallableBuilder& Add(TRuntimeNode input);
+ TCallableBuilder& Add(TRuntimeNode input);
TCallableBuilder& SetArgumentName(const TStringBuf& name);
TCallableBuilder& SetArgumentFlags(ui64 flags);
TCallableBuilder& SetOptionalArgs(ui32 count);
diff --git a/ydb/library/yql/minikql/mkql_node_builder_ut.cpp b/ydb/library/yql/minikql/mkql_node_builder_ut.cpp
index 783b1f98027..df310d00b90 100644
--- a/ydb/library/yql/minikql/mkql_node_builder_ut.cpp
+++ b/ydb/library/yql/minikql/mkql_node_builder_ut.cpp
@@ -57,8 +57,8 @@ Y_UNIT_TEST_SUITE(TMiniKQLNodeBuilderTest) {
TScopedAlloc alloc;
TTypeEnvironment env(alloc);
auto callableType = TCallableTypeBuilder(env, "func", TDataType::Create(NUdf::TDataType<ui32>::Id, env))
- .Add(env.GetVoid()->GetType())
- .Add(env.GetTypeOfVoid())
+ .Add(env.GetVoid()->GetType())
+ .Add(env.GetTypeOfVoid())
.Build();
UNIT_ASSERT_EQUAL(callableType->GetKind(), TType::EKind::Callable);
@@ -149,13 +149,13 @@ Y_UNIT_TEST_SUITE(TMiniKQLNodeBuilderTest) {
auto callable2 = TCallableBuilder(env, "func2", TDataType::Create(NUdf::TDataType<ui32>::Id, env))
.Add(TRuntimeNode(callable1, false))
- .Add(TRuntimeNode(env.GetVoid(), true))
+ .Add(TRuntimeNode(env.GetVoid(), true))
.Build();
UNIT_ASSERT_EQUAL(callable2->GetType()->GetKind(), TType::EKind::Callable);
UNIT_ASSERT_EQUAL(callable2->GetType()->GetArgumentsCount(), 2);
- UNIT_ASSERT_EQUAL(callable2->GetType()->GetArgumentType(0)->GetKind(), TType::EKind::Data);
- UNIT_ASSERT_EQUAL(callable2->GetType()->GetArgumentType(1)->GetKind(), TType::EKind::Void);
+ UNIT_ASSERT_EQUAL(callable2->GetType()->GetArgumentType(0)->GetKind(), TType::EKind::Data);
+ UNIT_ASSERT_EQUAL(callable2->GetType()->GetArgumentType(1)->GetKind(), TType::EKind::Void);
UNIT_ASSERT_EQUAL(callable2->GetInputsCount(), 2);
}
diff --git a/ydb/library/yql/minikql/mkql_node_cast_ut.cpp b/ydb/library/yql/minikql/mkql_node_cast_ut.cpp
index d029b919c70..0ae19fa5e45 100644
--- a/ydb/library/yql/minikql/mkql_node_cast_ut.cpp
+++ b/ydb/library/yql/minikql/mkql_node_cast_ut.cpp
@@ -35,7 +35,7 @@ class TMiniKQLNodeCast: public TTestBase
TCallableType* ctype = TCallableType::Create(
"callable", dataNode.GetStaticType(),
- 0, nullptr, nullptr, Env);
+ 0, nullptr, nullptr, Env);
TCallable* callable = TCallable::Create(dataNode, ctype, Env);
diff --git a/ydb/library/yql/minikql/mkql_node_printer.cpp b/ydb/library/yql/minikql/mkql_node_printer.cpp
index 9ed3c76cac9..f7515a30050 100644
--- a/ydb/library/yql/minikql/mkql_node_printer.cpp
+++ b/ydb/library/yql/minikql/mkql_node_printer.cpp
@@ -85,7 +85,7 @@ namespace {
void Visit(TStructType& node) override {
WriteIndentation();
- Out << "Type (Struct) with " << node.GetMembersCount() << " members {";
+ Out << "Type (Struct) with " << node.GetMembersCount() << " members {";
WriteNewline();
{
@@ -113,7 +113,7 @@ namespace {
void Visit(TListType& node) override {
WriteIndentation();
- Out << "Type (List) {";
+ Out << "Type (List) {";
WriteNewline();
{
@@ -221,7 +221,7 @@ namespace {
void Visit(TOptionalType& node) override {
WriteIndentation();
- Out << "Type (Optional) {";
+ Out << "Type (Optional) {";
WriteNewline();
{
@@ -247,7 +247,7 @@ namespace {
void Visit(TDictType& node) override {
WriteIndentation();
- Out << "Type (Dict) {";
+ Out << "Type (Dict) {";
WriteNewline();
{
@@ -292,7 +292,7 @@ namespace {
{
TIndentScope scope(this);
WriteIndentation();
- Out << "Return type";
+ Out << "Return type";
if (node.IsMergeDisabled())
Out << ", merge disabled";
if (node.GetOptionalArgumentsCount() != 0)
@@ -311,12 +311,12 @@ namespace {
for (ui32 index = 0; index < node.GetArgumentsCount(); ++index) {
WriteIndentation();
const auto& type = node.GetArgumentType(index);
- Out << "Argument #" << index << " : {";
+ Out << "Argument #" << index << " : {";
WriteNewline();
{
TIndentScope scope2(this);
- type->Accept(*this);
+ type->Accept(*this);
}
WriteIndentation();
@@ -354,14 +354,14 @@ namespace {
void Visit(TTupleType& node) override {
WriteIndentation();
- Out << "Type (Tuple) with " << node.GetElementsCount() << " elements {";
+ Out << "Type (Tuple) with " << node.GetElementsCount() << " elements {";
WriteNewline();
{
TIndentScope scope(this);
for (ui32 index = 0; index < node.GetElementsCount(); ++index) {
WriteIndentation();
- Out << "#" << index << " : {";
+ Out << "#" << index << " : {";
WriteNewline();
{
@@ -499,7 +499,7 @@ namespace {
void Visit(TStructLiteral& node) override {
WriteIndentation();
- Out << "Struct {";
+ Out << "Struct {";
WriteNewline();
{
@@ -712,7 +712,7 @@ namespace {
void Visit(TTupleLiteral& node) override {
WriteIndentation();
- Out << "Tuple {";
+ Out << "Tuple {";
WriteNewline();
{
diff --git a/ydb/library/yql/minikql/mkql_node_printer_ut.cpp b/ydb/library/yql/minikql/mkql_node_printer_ut.cpp
index 6cb65723801..ec8c5d1afe7 100644
--- a/ydb/library/yql/minikql/mkql_node_printer_ut.cpp
+++ b/ydb/library/yql/minikql/mkql_node_printer_ut.cpp
@@ -13,10 +13,10 @@ namespace {
TDataType* dtype1 = TDataType::Create(NUdf::TDataType<ui32>::Id, env);
TDataType* dtype2 = TDataType::Create(NUdf::TDataType<char*>::Id, env);
TVector<TType*> callableTypes;
- callableTypes.push_back(env.GetVoid()->GetGenericType());
- TCallableType* ctype1 = TCallableType::Create("ret data", dtype1, callableTypes.size(), callableTypes.data(), nullptr, env);
- TListType* ltype1 = TListType::Create(dtype1, env);
- TOptionalType* otype1 = TOptionalType::Create(dtype1, env);
+ callableTypes.push_back(env.GetVoid()->GetGenericType());
+ TCallableType* ctype1 = TCallableType::Create("ret data", dtype1, callableTypes.size(), callableTypes.data(), nullptr, env);
+ TListType* ltype1 = TListType::Create(dtype1, env);
+ TOptionalType* otype1 = TOptionalType::Create(dtype1, env);
structBuilder.Add("01", TRuntimeNode(env.GetTypeOfType(), true));
structBuilder.Add("02", TRuntimeNode(env.GetTypeOfVoid(), true));
structBuilder.Add("03", TRuntimeNode(dtype1, true));
@@ -24,14 +24,14 @@ namespace {
structBuilder.Add("12", TRuntimeNode(env.GetEmptyStruct()->GetType(), true));
TVector<std::pair<TString, TType*>> smallMembers;
smallMembers.push_back(std::make_pair("Embedded member", env.GetVoid()->GetGenericType()));
- structBuilder.Add("13", TRuntimeNode(TStructType::Create(smallMembers.data(), smallMembers.size(), env), true));
- structBuilder.Add("14", TRuntimeNode(TListType::Create(dtype1, env), true));
- structBuilder.Add("15", TRuntimeNode(TOptionalType::Create(dtype2, env), true));
- structBuilder.Add("16", TRuntimeNode(TDictType::Create(dtype1, dtype2, env), true));
+ structBuilder.Add("13", TRuntimeNode(TStructType::Create(smallMembers.data(), smallMembers.size(), env), true));
+ structBuilder.Add("14", TRuntimeNode(TListType::Create(dtype1, env), true));
+ structBuilder.Add("15", TRuntimeNode(TOptionalType::Create(dtype2, env), true));
+ structBuilder.Add("16", TRuntimeNode(TDictType::Create(dtype1, dtype2, env), true));
TVector<TType*> smallTypes;
- smallTypes.push_back(dtype1);
+ smallTypes.push_back(dtype1);
structBuilder.Add("17", TRuntimeNode(TCallableType::Create("My callable",
- dtype2, smallTypes.size(), smallTypes.data(), nullptr, env), true));
+ dtype2, smallTypes.size(), smallTypes.data(), nullptr, env), true));
structBuilder.Add("18", TRuntimeNode(env.GetVoid(), true));
ui32 u = 345;
structBuilder.Add("19", TRuntimeNode(TDataLiteral::Create(NUdf::TUnboxedValuePod(u), dtype1, env), true));
@@ -45,7 +45,7 @@ namespace {
structBuilder.Add("28", TRuntimeNode(TOptionalLiteral::Create(otype1, env), true));
structBuilder.Add("29", TRuntimeNode(TOptionalLiteral::Create(litems[0], otype1, env), true));
- auto ditype1 = TDictType::Create(dtype1, dtype2, env);
+ auto ditype1 = TDictType::Create(dtype1, dtype2, env);
TVector<std::pair<TRuntimeNode, TRuntimeNode>> ditems;
ditems.push_back(std::make_pair(TRuntimeNode(TDataLiteral::Create(NUdf::TUnboxedValuePod((ui32)456), dtype1, env), true),
TRuntimeNode(TDataLiteral::Create(NUdf::TUnboxedValuePod::Embedded("aaaa"), dtype2, env), true)));
@@ -61,13 +61,13 @@ namespace {
anyWithData->SetItem(TRuntimeNode(env.GetVoid(), true));
structBuilder.Add("34", TRuntimeNode(anyWithData, true));
structBuilder.Add("35", TRuntimeNode(TCallableType::Create("My callable 2",
- dtype2, callableArgs.size(), smallTypes.data(), env.GetVoid(), env), true));
+ dtype2, callableArgs.size(), smallTypes.data(), env.GetVoid(), env), true));
TVector<TType*> tupleTypes;
tupleTypes.push_back(dtype1);
TVector<TRuntimeNode> tupleValues;
tupleValues.push_back(TRuntimeNode(TDataLiteral::Create(NUdf::TUnboxedValuePod((ui32)456), dtype1, env), true));
- auto tupleType = TTupleType::Create(tupleTypes.size(), tupleTypes.data(), env);
+ auto tupleType = TTupleType::Create(tupleTypes.size(), tupleTypes.data(), env);
structBuilder.Add("36", TRuntimeNode(tupleType, true));
structBuilder.Add("37", TRuntimeNode(TTupleLiteral::Create(tupleValues.size(), tupleValues.data(), tupleType, env), true));
structBuilder.Add("38", TRuntimeNode(TResourceType::Create("myres", env), true));
@@ -100,7 +100,7 @@ Y_UNIT_TEST_SUITE(TMiniKQLNodePrinterTest) {
TScopedAlloc alloc;
TTypeEnvironment env(alloc);
TDataType* dtype1 = TDataType::Create(NUdf::TDataType<ui32>::Id, env);
- TCallableType* ctype1 = TCallableType::Create("ctype1", dtype1, 0, nullptr, nullptr, env);
+ TCallableType* ctype1 = TCallableType::Create("ctype1", dtype1, 0, nullptr, nullptr, env);
TCallable* c1 = TCallable::Create(0, nullptr, ctype1, env);
TRuntimeNode r1(c1, false);
auto s1 = SerializeRuntimeNode(r1, env);
diff --git a/ydb/library/yql/minikql/mkql_node_serialization.cpp b/ydb/library/yql/minikql/mkql_node_serialization.cpp
index 67016c2a1cb..e314f38cd61 100644
--- a/ydb/library/yql/minikql/mkql_node_serialization.cpp
+++ b/ydb/library/yql/minikql/mkql_node_serialization.cpp
@@ -161,7 +161,7 @@ namespace {
return;
}
- Owner.Write(TypeMarker | (char)TType::EKind::Struct);
+ Owner.Write(TypeMarker | (char)TType::EKind::Struct);
Owner.WriteVar32(node.GetMembersCount());
for (ui32 i = node.GetMembersCount(); i-- > 0;) {
auto memberType = node.GetMemberType(i);
@@ -178,7 +178,7 @@ namespace {
return;
}
- Owner.Write(TypeMarker | (char)TType::EKind::List);
+ Owner.Write(TypeMarker | (char)TType::EKind::List);
auto itemType = node.GetItemType();
Owner.AddChildNode(*itemType);
IsProcessed0 = false;
@@ -243,7 +243,7 @@ namespace {
return;
}
- Owner.Write(TypeMarker | (char)TType::EKind::Optional);
+ Owner.Write(TypeMarker | (char)TType::EKind::Optional);
auto itemType = node.GetItemType();
Owner.AddChildNode(*itemType);
IsProcessed0 = false;
@@ -256,7 +256,7 @@ namespace {
return;
}
- Owner.Write(TypeMarker | (char)TType::EKind::Dict);
+ Owner.Write(TypeMarker | (char)TType::EKind::Dict);
auto keyType = node.GetKeyType();
auto payloadType = node.GetPayloadType();
Owner.AddChildNode(*payloadType);
@@ -271,7 +271,7 @@ namespace {
return;
}
- Owner.Write(TypeMarker | (char)TType::EKind::Callable
+ Owner.Write(TypeMarker | (char)TType::EKind::Callable
| (node.IsMergeDisabled() ? UserMarker2 : 0) | (node.GetPayload() ? UserMarker3 : 0));
Owner.WriteVar32(node.GetArgumentsCount());
auto returnType = node.GetReturnType();
@@ -281,7 +281,7 @@ namespace {
for (ui32 i = node.GetArgumentsCount(); i-- > 0;) {
auto argumentType = node.GetArgumentType(i);
- Owner.AddChildNode(*argumentType);
+ Owner.AddChildNode(*argumentType);
}
Owner.AddChildNode(*returnType);
@@ -301,7 +301,7 @@ namespace {
return;
}
- Owner.Write(TypeMarker | (char)TType::EKind::Tuple);
+ Owner.Write(TypeMarker | (char)TType::EKind::Tuple);
Owner.WriteVar32(node.GetElementsCount());
for (ui32 i = node.GetElementsCount(); i-- > 0;) {
auto elementType = node.GetElementType(i);
@@ -1270,7 +1270,7 @@ namespace {
members[i].Name = ReadName();
}
- auto node = TStructType::Create(membersCount, members.data(), Env);
+ auto node = TStructType::Create(membersCount, members.data(), Env);
Nodes.push_back(node);
return node;
}
@@ -1286,7 +1286,7 @@ namespace {
elements[i] = elementType;
}
- auto node = TTupleType::Create(elementsCount, elements.data(), Env);
+ auto node = TTupleType::Create(elementsCount, elements.data(), Env);
Nodes.push_back(node);
return node;
}
@@ -1297,7 +1297,7 @@ namespace {
ThrowCorrupted();
auto itemType = static_cast<TType*>(itemTypeNode);
- auto node = TListType::Create(itemType, Env);
+ auto node = TListType::Create(itemType, Env);
Nodes.push_back(node);
return node;
}
@@ -1371,7 +1371,7 @@ namespace {
ThrowCorrupted();
auto itemType = static_cast<TType*>(itemTypeNode);
- auto node = TOptionalType::Create(itemType, Env);
+ auto node = TOptionalType::Create(itemType, Env);
Nodes.push_back(node);
return node;
}
@@ -1396,7 +1396,7 @@ namespace {
ThrowCorrupted();
auto payloadType = static_cast<TType*>(payloadTypeNode);
- auto node = TDictType::Create(keyType, payloadType, Env);
+ auto node = TDictType::Create(keyType, payloadType, Env);
Nodes.push_back(node);
return node;
}
@@ -1417,14 +1417,14 @@ namespace {
ThrowCorrupted();
auto returnType = static_cast<TType*>(returnTypeNode);
- TStackVec<TType*> arguments(argumentsCount);
+ TStackVec<TType*> arguments(argumentsCount);
for (ui32 i = 0; i < argumentsCount; ++i) {
auto argumentTypeNode = PopNode();
if (argumentTypeNode->GetType()->GetKind() != TType::EKind::Type)
ThrowCorrupted();
auto argumentType = static_cast<TType*>(argumentTypeNode);
- arguments[i] = argumentType;
+ arguments[i] = argumentType;
}
TNode* payload = nullptr;
@@ -1434,7 +1434,7 @@ namespace {
auto name = ReadName();
const ui32 optArgsCount = ReadVar32();
- auto node = TCallableType::Create(returnType, name, argumentsCount, arguments.data(), payload, Env);
+ auto node = TCallableType::Create(returnType, name, argumentsCount, arguments.data(), payload, Env);
if (isMergeDisabled)
node->DisableMerge();
node->SetOptionalArgumentsCount(optArgsCount);
diff --git a/ydb/library/yql/minikql/mkql_node_ut.cpp b/ydb/library/yql/minikql/mkql_node_ut.cpp
index f96116ebabd..16126272462 100644
--- a/ydb/library/yql/minikql/mkql_node_ut.cpp
+++ b/ydb/library/yql/minikql/mkql_node_ut.cpp
@@ -74,7 +74,7 @@ Y_UNIT_TEST_SUITE(TMiniKQLNodeTest) {
TVector<std::pair<TString, TType*>> s1members;
s1members.push_back(std::make_pair("aaa", env.GetVoid()->GetGenericType()));
- TStructType* s1 = TStructType::Create(s1members.data(), s1members.size(), env);
+ TStructType* s1 = TStructType::Create(s1members.data(), s1members.size(), env);
UNIT_ASSERT_EQUAL(s1->GetMembersCount(), 1);
UNIT_ASSERT_EQUAL(s1->GetMemberName(0), "aaa");
UNIT_ASSERT_EQUAL(s1->GetMemberType(0)->GetKind(), TType::EKind::Void);
@@ -82,7 +82,7 @@ Y_UNIT_TEST_SUITE(TMiniKQLNodeTest) {
TVector<std::pair<TString, TType*>> s2members;
s2members.push_back(std::make_pair("bbb", env.GetEmptyStruct()->GetGenericType()));
s2members.push_back(std::make_pair("ccc", env.GetTypeOfVoid()));
- TStructType* s2 = TStructType::Create(s2members.data(), s2members.size(), env);
+ TStructType* s2 = TStructType::Create(s2members.data(), s2members.size(), env);
UNIT_ASSERT_EQUAL(s2->GetMembersCount(), 2);
UNIT_ASSERT_EQUAL(s2->GetMemberName(0), "bbb");
UNIT_ASSERT_EQUAL(s2->GetMemberType(0)->GetKind(), TType::EKind::Struct);
@@ -91,20 +91,20 @@ Y_UNIT_TEST_SUITE(TMiniKQLNodeTest) {
TVector<std::pair<TString, TType*>> s3members;
s3members.push_back(std::make_pair("", env.GetEmptyStruct()->GetGenericType()));
- UNIT_ASSERT_EXCEPTION(TStructType::Create(s3members.data(), s3members.size(), env), yexception);
+ UNIT_ASSERT_EXCEPTION(TStructType::Create(s3members.data(), s3members.size(), env), yexception);
- TStructType* s2cloned = TStructType::Create(s2members.data(), s2members.size(), env);
+ TStructType* s2cloned = TStructType::Create(s2members.data(), s2members.size(), env);
UNIT_ASSERT(s2cloned->IsSameType(*s2cloned));
UNIT_ASSERT(s2cloned->IsSameType(*s2));
UNIT_ASSERT(!s2cloned->IsSameType(*s1));
Reverse(s2members.begin(), s2members.end());
- UNIT_ASSERT_EXCEPTION(TStructType::Create(s2members.data(), s2members.size(), env), yexception);
+ UNIT_ASSERT_EXCEPTION(TStructType::Create(s2members.data(), s2members.size(), env), yexception);
TVector<std::pair<TString, TType*>> duplicatedMembers;
- duplicatedMembers.push_back(std::make_pair("aaa", env.GetEmptyStruct()->GetGenericType()));
- duplicatedMembers.push_back(std::make_pair("aaa", env.GetTypeOfVoid()));
- UNIT_ASSERT_EXCEPTION(TStructType::Create(duplicatedMembers.data(), duplicatedMembers.size(), env), yexception);
+ duplicatedMembers.push_back(std::make_pair("aaa", env.GetEmptyStruct()->GetGenericType()));
+ duplicatedMembers.push_back(std::make_pair("aaa", env.GetTypeOfVoid()));
+ UNIT_ASSERT_EXCEPTION(TStructType::Create(duplicatedMembers.data(), duplicatedMembers.size(), env), yexception);
}
Y_UNIT_TEST(TestStructLiteral) {
@@ -116,7 +116,7 @@ Y_UNIT_TEST_SUITE(TMiniKQLNodeTest) {
TVector<std::pair<TString, TType*>> s1members;
s1members.push_back(std::make_pair("aaa", env.GetVoid()->GetGenericType()));
- TStructType* s1type = TStructType::Create(s1members.data(), s1members.size(), env);
+ TStructType* s1type = TStructType::Create(s1members.data(), s1members.size(), env);
TVector<TRuntimeNode> s1values;
s1values.push_back(TRuntimeNode(env.GetVoid(), true));
@@ -128,12 +128,12 @@ Y_UNIT_TEST_SUITE(TMiniKQLNodeTest) {
TVector<std::pair<TString, TType*>> s2members;
s2members.push_back(std::make_pair("aaa", env.GetEmptyTuple()->GetGenericType()));
- TStructType* s2type = TStructType::Create(s2members.data(), s2members.size(), env);
+ TStructType* s2type = TStructType::Create(s2members.data(), s2members.size(), env);
UNIT_ASSERT_EXCEPTION(TStructLiteral::Create(s1values.size(), s1values.data(), s2type, env), yexception);
- TStructType* s1typeDyn = TStructType::Create(s1members.data(), s1members.size(), env);
+ TStructType* s1typeDyn = TStructType::Create(s1members.data(), s1members.size(), env);
TVector<TRuntimeNode> s1DynValues;
- TCallableType* ctype = TCallableType::Create("c1", env.GetVoid()->GetGenericType(),
+ TCallableType* ctype = TCallableType::Create("c1", env.GetVoid()->GetGenericType(),
0, nullptr, nullptr, env);
s1DynValues.push_back(TRuntimeNode(TCallable::Create(0, nullptr, ctype, env), false));
UNIT_ASSERT_NO_EXCEPTION(TStructLiteral::Create(s1DynValues.size(), s1DynValues.data(), s1typeDyn, env));
@@ -143,10 +143,10 @@ Y_UNIT_TEST_SUITE(TMiniKQLNodeTest) {
Y_UNIT_TEST(TestListType) {
TScopedAlloc alloc;
TTypeEnvironment env(alloc);
- TListType* list1type = TListType::Create(env.GetVoid()->GetGenericType(), env);
+ TListType* list1type = TListType::Create(env.GetVoid()->GetGenericType(), env);
UNIT_ASSERT_EQUAL(list1type->GetKind(), TType::EKind::List);
TListType* list2type = TListType::Create(env.GetEmptyTuple()->GetGenericType(), env);
- TListType* list1typeCloned = TListType::Create(env.GetVoid()->GetGenericType(), env);
+ TListType* list1typeCloned = TListType::Create(env.GetVoid()->GetGenericType(), env);
UNIT_ASSERT(list1type->IsSameType(*list1typeCloned));
UNIT_ASSERT(!list1type->IsSameType(*list2type));
}
@@ -166,8 +166,8 @@ Y_UNIT_TEST_SUITE(TMiniKQLNodeTest) {
TScopedAlloc alloc;
TTypeEnvironment env(alloc);
TDataType* dtype1 = TDataType::Create(NUdf::TDataType<char*>::Id, env);
- TListType* list1type = TListType::Create(env.GetVoid()->GetGenericType(), env);
- TListType* list2type = TListType::Create(dtype1, env);
+ TListType* list1type = TListType::Create(env.GetVoid()->GetGenericType(), env);
+ TListType* list2type = TListType::Create(dtype1, env);
UNIT_ASSERT_NO_EXCEPTION(TListLiteral::Create(nullptr, 0, list1type, env));
@@ -187,11 +187,11 @@ Y_UNIT_TEST_SUITE(TMiniKQLNodeTest) {
UNIT_ASSERT_EXCEPTION(TListLiteral::Create(someItems.data(), someItems.size(), list1type, env), yexception);
- TListType* list2typeDyn = TListType::Create(dtype1, env);
+ TListType* list2typeDyn = TListType::Create(dtype1, env);
UNIT_ASSERT_NO_EXCEPTION(TListLiteral::Create(someItems.data(), someItems.size(), list2typeDyn, env));
TVector<TRuntimeNode> someDynItems;
- TCallableType* ctype = TCallableType::Create("c1", dtype1, 0, nullptr, nullptr, env);
+ TCallableType* ctype = TCallableType::Create("c1", dtype1, 0, nullptr, nullptr, env);
someDynItems.push_back(TRuntimeNode(TCallable::Create(0, nullptr, ctype, env), false));
UNIT_ASSERT_NO_EXCEPTION(TListLiteral::Create(someDynItems.data(), someDynItems.size(), list2typeDyn, env));
@@ -200,10 +200,10 @@ Y_UNIT_TEST_SUITE(TMiniKQLNodeTest) {
Y_UNIT_TEST(TestOptionalType) {
TScopedAlloc alloc;
TTypeEnvironment env(alloc);
- TOptionalType* opt1type = TOptionalType::Create(env.GetVoid()->GetGenericType(), env);
+ TOptionalType* opt1type = TOptionalType::Create(env.GetVoid()->GetGenericType(), env);
UNIT_ASSERT_EQUAL(opt1type->GetKind(), TType::EKind::Optional);
TOptionalType* opt2type = TOptionalType::Create(env.GetEmptyTuple()->GetGenericType(), env);
- TOptionalType* opt1typeCloned = TOptionalType::Create(env.GetVoid()->GetGenericType(), env);
+ TOptionalType* opt1typeCloned = TOptionalType::Create(env.GetVoid()->GetGenericType(), env);
UNIT_ASSERT(opt1type->IsSameType(*opt1typeCloned));
UNIT_ASSERT(!opt1type->IsSameType(*opt2type));
}
@@ -212,8 +212,8 @@ Y_UNIT_TEST_SUITE(TMiniKQLNodeTest) {
TScopedAlloc alloc;
TTypeEnvironment env(alloc);
TDataType* dtype1 = TDataType::Create(NUdf::TDataType<char*>::Id, env);
- TOptionalType* opt1type = TOptionalType::Create(env.GetVoid()->GetGenericType(), env);
- TOptionalType* opt2type = TOptionalType::Create(dtype1, env);
+ TOptionalType* opt1type = TOptionalType::Create(env.GetVoid()->GetGenericType(), env);
+ TOptionalType* opt2type = TOptionalType::Create(dtype1, env);
TOptionalLiteral* emptyOpt = TOptionalLiteral::Create(opt1type, env);
UNIT_ASSERT(!emptyOpt->HasItem());
@@ -229,10 +229,10 @@ Y_UNIT_TEST_SUITE(TMiniKQLNodeTest) {
UNIT_ASSERT_EXCEPTION(TOptionalLiteral::Create(item1, opt1type, env), yexception);
- auto opt2typeDyn = TOptionalType::Create(dtype1, env);
+ auto opt2typeDyn = TOptionalType::Create(dtype1, env);
UNIT_ASSERT_NO_EXCEPTION(TOptionalLiteral::Create(item1, opt2typeDyn, env));
- TCallableType* ctype = TCallableType::Create("c1", dtype1, 0, nullptr, nullptr, env);
+ TCallableType* ctype = TCallableType::Create("c1", dtype1, 0, nullptr, nullptr, env);
auto dynItem = TRuntimeNode(TCallable::Create(0, nullptr, ctype, env), false);
UNIT_ASSERT_NO_EXCEPTION(TOptionalLiteral::Create(dynItem, opt2typeDyn, env));
@@ -242,10 +242,10 @@ Y_UNIT_TEST_SUITE(TMiniKQLNodeTest) {
TScopedAlloc alloc;
TTypeEnvironment env(alloc);
TDataType* dtype1 = TDataType::Create(NUdf::TDataType<ui32>::Id, env);
- TDictType* dictType1 = TDictType::Create(dtype1, env.GetVoid()->GetGenericType(), env);
+ TDictType* dictType1 = TDictType::Create(dtype1, env.GetVoid()->GetGenericType(), env);
UNIT_ASSERT_EQUAL(dictType1->GetKind(), TType::EKind::Dict);
- TDictType* dictType2 = TDictType::Create(dtype1, env.GetEmptyStruct()->GetGenericType(), env);
- TDictType* dictType1Cloned = TDictType::Create(dtype1, env.GetVoid()->GetGenericType(), env);
+ TDictType* dictType2 = TDictType::Create(dtype1, env.GetEmptyStruct()->GetGenericType(), env);
+ TDictType* dictType1Cloned = TDictType::Create(dtype1, env.GetVoid()->GetGenericType(), env);
UNIT_ASSERT(dictType1->IsSameType(*dictType1Cloned));
UNIT_ASSERT(!dictType1->IsSameType(*dictType2));
}
@@ -254,7 +254,7 @@ Y_UNIT_TEST_SUITE(TMiniKQLNodeTest) {
TScopedAlloc alloc;
TTypeEnvironment env(alloc);
TCallableType* ctype1 = TCallableType::Create("c1", env.GetTypeOfVoid(),
- 0, nullptr, nullptr, env);
+ 0, nullptr, nullptr, env);
UNIT_ASSERT_EQUAL(ctype1->GetKind(), TType::EKind::Callable);
UNIT_ASSERT_EQUAL(ctype1->GetName(), "c1");
UNIT_ASSERT_EQUAL(ctype1->GetArgumentsCount(), 0);
@@ -262,36 +262,36 @@ Y_UNIT_TEST_SUITE(TMiniKQLNodeTest) {
TVector<TType*> types;
types.push_back(env.GetVoid()->GetGenericType());
- types.push_back(env.GetEmptyStruct()->GetGenericType());
- TCallableType* ctype2 = TCallableType::Create("c2", env.GetVoid()->GetGenericType(), types.size(), types.data(), nullptr, env);
+ types.push_back(env.GetEmptyStruct()->GetGenericType());
+ TCallableType* ctype2 = TCallableType::Create("c2", env.GetVoid()->GetGenericType(), types.size(), types.data(), nullptr, env);
UNIT_ASSERT_EQUAL(ctype2->GetName(), "c2");
UNIT_ASSERT_EQUAL(ctype2->GetReturnType()->GetKind(), TType::EKind::Void);
UNIT_ASSERT_EQUAL(ctype2->GetArgumentsCount(), 2);
UNIT_ASSERT_EQUAL(ctype2->GetArgumentType(0)->GetKind(), TType::EKind::Void);
- UNIT_ASSERT_EQUAL(ctype2->GetArgumentType(1)->GetKind(), TType::EKind::Struct);
+ UNIT_ASSERT_EQUAL(ctype2->GetArgumentType(1)->GetKind(), TType::EKind::Struct);
- TCallableType* ctype2Cloned = TCallableType::Create("c2", env.GetVoid()->GetGenericType(), types.size(), types.data(), nullptr, env);
+ TCallableType* ctype2Cloned = TCallableType::Create("c2", env.GetVoid()->GetGenericType(), types.size(), types.data(), nullptr, env);
UNIT_ASSERT(ctype2->IsSameType(*ctype2));
UNIT_ASSERT(ctype2->IsSameType(*ctype2Cloned));
UNIT_ASSERT(!ctype2->IsSameType(*ctype1));
TVector<TType*> types2;
- types2.push_back(env.GetEmptyStruct()->GetGenericType());
+ types2.push_back(env.GetEmptyStruct()->GetGenericType());
types2.push_back(env.GetVoid()->GetGenericType());
- TCallableType* ctype2rev = TCallableType::Create("c2", env.GetVoid()->GetGenericType(), types2.size(), types2.data(), nullptr, env);
+ TCallableType* ctype2rev = TCallableType::Create("c2", env.GetVoid()->GetGenericType(), types2.size(), types2.data(), nullptr, env);
UNIT_ASSERT(!ctype2->IsSameType(*ctype2rev));
TVector<TType*> types3;
types3.push_back(env.GetVoid()->GetGenericType());
- types3.push_back(env.GetEmptyStruct()->GetGenericType());
- TCallableType* ctype2withPayload1 = TCallableType::Create("c2", env.GetVoid()->GetGenericType(), types.size(), types.data(), env.GetEmptyStruct(), env);
+ types3.push_back(env.GetEmptyStruct()->GetGenericType());
+ TCallableType* ctype2withPayload1 = TCallableType::Create("c2", env.GetVoid()->GetGenericType(), types.size(), types.data(), env.GetEmptyStruct(), env);
UNIT_ASSERT(!ctype2withPayload1->IsSameType(*ctype2));
- TCallableType* ctype2withPayload2 = TCallableType::Create("c2", env.GetVoid()->GetGenericType(), types.size(), types.data(), env.GetListOfVoid(), env);
+ TCallableType* ctype2withPayload2 = TCallableType::Create("c2", env.GetVoid()->GetGenericType(), types.size(), types.data(), env.GetListOfVoid(), env);
UNIT_ASSERT(!ctype2withPayload2->IsSameType(*ctype2withPayload1));
- TCallableType* ctype2withPayload2clone = TCallableType::Create("c2", env.GetVoid()->GetGenericType(), types.size(), types.data(), env.GetListOfVoid(), env);
+ TCallableType* ctype2withPayload2clone = TCallableType::Create("c2", env.GetVoid()->GetGenericType(), types.size(), types.data(), env.GetListOfVoid(), env);
UNIT_ASSERT(ctype2withPayload2clone->IsSameType(*ctype2withPayload2));
- TCallableType* ctype2optArg = TCallableType::Create("c2", env.GetVoid()->GetGenericType(), types.size(), types.data(), nullptr, env);
+ TCallableType* ctype2optArg = TCallableType::Create("c2", env.GetVoid()->GetGenericType(), types.size(), types.data(), nullptr, env);
ctype2optArg->SetOptionalArgumentsCount(0);
UNIT_ASSERT(ctype2optArg->IsSameType(*ctype2));
@@ -308,8 +308,8 @@ Y_UNIT_TEST_SUITE(TMiniKQLNodeTest) {
TTypeEnvironment env(alloc);
TDataType* dtype1 = TDataType::Create(NUdf::TDataType<char*>::Id, env);
TDataType* dtype2 = TDataType::Create(NUdf::TDataType<ui32>::Id, env);
- TDictType* dict1Type = TDictType::Create(dtype1, env.GetVoid()->GetGenericType(), env);
- TDictType* dict2Type = TDictType::Create(dtype1, dtype2, env);
+ TDictType* dict1Type = TDictType::Create(dtype1, env.GetVoid()->GetGenericType(), env);
+ TDictType* dict2Type = TDictType::Create(dtype1, dtype2, env);
TVector<std::pair<TRuntimeNode, TRuntimeNode>> emptyItems;
UNIT_ASSERT_NO_EXCEPTION(TDictLiteral::Create(emptyItems.size(), emptyItems.data(), dict1Type, env));
@@ -337,11 +337,11 @@ Y_UNIT_TEST_SUITE(TMiniKQLNodeTest) {
UNIT_ASSERT_EXCEPTION(TDictLiteral::Create(someItems.size(), someItems.data(), dict1Type, env), yexception);
- TDictType* dict2TypeDyn = TDictType::Create(dtype1, dtype2, env);
+ TDictType* dict2TypeDyn = TDictType::Create(dtype1, dtype2, env);
UNIT_ASSERT_NO_EXCEPTION(TDictLiteral::Create(someItems.size(), someItems.data(), dict2TypeDyn, env));
TVector<std::pair<TRuntimeNode, TRuntimeNode>> someDynItems;
- TCallableType* ctype = TCallableType::Create("c1", dtype1, 0, nullptr, nullptr, env);
+ TCallableType* ctype = TCallableType::Create("c1", dtype1, 0, nullptr, nullptr, env);
someDynItems.push_back(std::make_pair(
TRuntimeNode(TCallable::Create(0, nullptr, ctype, env), false),
TRuntimeNode(TDataLiteral::Create(NUdf::TUnboxedValuePod((ui32)123), dtype2, env), true)));
@@ -353,7 +353,7 @@ Y_UNIT_TEST_SUITE(TMiniKQLNodeTest) {
TScopedAlloc alloc;
TTypeEnvironment env(alloc);
TCallableType* ctype1 = TCallableType::Create("c1", env.GetTypeOfVoid(),
- 0, nullptr, nullptr, env);
+ 0, nullptr, nullptr, env);
TCallable* c1 = TCallable::Create(0, nullptr, ctype1, env);
UNIT_ASSERT_EQUAL(c1->GetInputsCount(), 0);
UNIT_ASSERT(!c1->HasResult());
@@ -363,15 +363,15 @@ Y_UNIT_TEST_SUITE(TMiniKQLNodeTest) {
TVector<TType*> ctype2args;
TDataType* dtype1 = TDataType::Create(NUdf::TDataType<char*>::Id, env);
- ctype2args.push_back(dtype1);
- ctype2args.push_back(dtype1);
- TCallableType* ctype2 = TCallableType::Create("c2", env.GetTypeOfVoid(), ctype2args.size(), ctype2args.data(), nullptr, env);
- TCallableType* ctype2cloned = TCallableType::Create("c2", env.GetTypeOfVoid(), ctype2args.size(), ctype2args.data(), nullptr, env);
+ ctype2args.push_back(dtype1);
+ ctype2args.push_back(dtype1);
+ TCallableType* ctype2 = TCallableType::Create("c2", env.GetTypeOfVoid(), ctype2args.size(), ctype2args.data(), nullptr, env);
+ TCallableType* ctype2cloned = TCallableType::Create("c2", env.GetTypeOfVoid(), ctype2args.size(), ctype2args.data(), nullptr, env);
UNIT_ASSERT(ctype2cloned->IsSameType(*ctype2));
UNIT_ASSERT(!ctype2cloned->IsSameType(*ctype1));
- TCallableType* ctype3 = TCallableType::Create("c1", dtype1, 0, nullptr, nullptr, env);
+ TCallableType* ctype3 = TCallableType::Create("c1", dtype1, 0, nullptr, nullptr, env);
TVector<TRuntimeNode> c2args;
c2args.push_back(TRuntimeNode(TDataLiteral::Create(
@@ -447,19 +447,19 @@ Y_UNIT_TEST_SUITE(TMiniKQLNodeTest) {
TVector<TType*> t1elems;
t1elems.push_back(env.GetVoid()->GetGenericType());
- TTupleType* t1 = TTupleType::Create(t1elems.size(), t1elems.data(), env);
+ TTupleType* t1 = TTupleType::Create(t1elems.size(), t1elems.data(), env);
UNIT_ASSERT_EQUAL(t1->GetElementsCount(), 1);
UNIT_ASSERT_EQUAL(t1->GetElementType(0)->GetKind(), TType::EKind::Void);
TVector<TType*> t2elems;
t2elems.push_back(env.GetEmptyStruct()->GetGenericType());
t2elems.push_back(env.GetTypeOfVoid());
- TTupleType* t2 = TTupleType::Create(t2elems.size(), t2elems.data(), env);
+ TTupleType* t2 = TTupleType::Create(t2elems.size(), t2elems.data(), env);
UNIT_ASSERT_EQUAL(t2->GetElementsCount(), 2);
UNIT_ASSERT_EQUAL(t2->GetElementType(0)->GetKind(), TType::EKind::Struct);
UNIT_ASSERT_EQUAL(t2->GetElementType(1)->GetKind(), TType::EKind::Void);
- TTupleType* t2cloned = TTupleType::Create(t2elems.size(), t2elems.data(), env);
+ TTupleType* t2cloned = TTupleType::Create(t2elems.size(), t2elems.data(), env);
UNIT_ASSERT(t2cloned->IsSameType(*t2cloned));
UNIT_ASSERT(t2cloned->IsSameType(*t2));
UNIT_ASSERT(!t2cloned->IsSameType(*t1));
@@ -474,7 +474,7 @@ Y_UNIT_TEST_SUITE(TMiniKQLNodeTest) {
TVector<TType*> t1elems;
t1elems.push_back(env.GetVoid()->GetGenericType());
- TTupleType* t1type = TTupleType::Create(t1elems.size(), t1elems.data(), env);
+ TTupleType* t1type = TTupleType::Create(t1elems.size(), t1elems.data(), env);
TVector<TRuntimeNode> t1values;
t1values.push_back(TRuntimeNode(env.GetVoid(), true));
@@ -486,12 +486,12 @@ Y_UNIT_TEST_SUITE(TMiniKQLNodeTest) {
TVector<TType*> t2elems;
t2elems.push_back(env.GetEmptyStruct()->GetGenericType());
- TTupleType* t2type = TTupleType::Create(t2elems.size(), t2elems.data(), env);
+ TTupleType* t2type = TTupleType::Create(t2elems.size(), t2elems.data(), env);
UNIT_ASSERT_EXCEPTION(TTupleLiteral::Create(t1values.size(), t1values.data(), t2type, env), yexception);
- TTupleType* t1typeDyn = TTupleType::Create(t1elems.size(), t1elems.data(), env);
+ TTupleType* t1typeDyn = TTupleType::Create(t1elems.size(), t1elems.data(), env);
TVector<TRuntimeNode> t1DynValues;
- TCallableType* ctype = TCallableType::Create("c1", env.GetVoid()->GetGenericType(),
+ TCallableType* ctype = TCallableType::Create("c1", env.GetVoid()->GetGenericType(),
0, nullptr, nullptr, env);
t1DynValues.push_back(TRuntimeNode(TCallable::Create(0, nullptr, ctype, env), false));
UNIT_ASSERT_NO_EXCEPTION(TTupleLiteral::Create(t1DynValues.size(), t1DynValues.data(), t1typeDyn, env));
diff --git a/ydb/library/yql/minikql/mkql_opt_literal.cpp b/ydb/library/yql/minikql/mkql_opt_literal.cpp
index c68c96965ac..832a87ea80c 100644
--- a/ydb/library/yql/minikql/mkql_opt_literal.cpp
+++ b/ydb/library/yql/minikql/mkql_opt_literal.cpp
@@ -196,7 +196,7 @@ TRuntimeNode OptimizeMap(TCallable& callable, const TTypeEnvironment& env) {
auto listType = static_cast<TListType*>(returnType);
auto newItemInput = callable.GetInput(2);
if (listType->GetItemType()->IsVoid() && newItemInput.HasValue()) {
- return TRuntimeNode(env.GetListOfVoid(), true);
+ return TRuntimeNode(env.GetListOfVoid(), true);
}
return TRuntimeNode(&callable, false);
diff --git a/ydb/library/yql/minikql/mkql_program_builder.cpp b/ydb/library/yql/minikql/mkql_program_builder.cpp
index 263aa8101f3..47ae6e4c8fc 100644
--- a/ydb/library/yql/minikql/mkql_program_builder.cpp
+++ b/ydb/library/yql/minikql/mkql_program_builder.cpp
@@ -367,7 +367,7 @@ TRuntimeNode TProgramBuilder::AddMember(TRuntimeNode structObj, const std::strin
MKQL_ENSURE(oldType->IsStruct(), "Expected struct");
const auto& oldTypeDetailed = static_cast<const TStructType&>(*oldType);
- TStructTypeBuilder newTypeBuilder(Env);
+ TStructTypeBuilder newTypeBuilder(Env);
newTypeBuilder.Reserve(oldTypeDetailed.GetMembersCount() + 1);
for (ui32 i = 0, e = oldTypeDetailed.GetMembersCount(); i < e; ++i) {
newTypeBuilder.Add(oldTypeDetailed.GetMemberName(i), oldTypeDetailed.GetMemberType(i));
@@ -423,7 +423,7 @@ TRuntimeNode TProgramBuilder::RemoveMember(TRuntimeNode structObj, const std::st
TRuntimeNode TProgramBuilder::Zip(const TArrayRef<const TRuntimeNode>& lists) {
if (lists.empty()) {
- return NewEmptyList(Env.GetEmptyTuple()->GetGenericType());
+ return NewEmptyList(Env.GetEmptyTuple()->GetGenericType());
}
std::vector<TType*> tupleTypes;
@@ -439,7 +439,7 @@ TRuntimeNode TProgramBuilder::Zip(const TArrayRef<const TRuntimeNode>& lists) {
tupleTypes.push_back(itemType);
}
- auto returnType = TListType::Create(TTupleType::Create(tupleTypes.size(), tupleTypes.data(), Env), Env);
+ auto returnType = TListType::Create(TTupleType::Create(tupleTypes.size(), tupleTypes.data(), Env), Env);
TCallableBuilder callableBuilder(Env, __func__, returnType);
for (auto& list : lists) {
callableBuilder.Add(list);
@@ -450,7 +450,7 @@ TRuntimeNode TProgramBuilder::Zip(const TArrayRef<const TRuntimeNode>& lists) {
TRuntimeNode TProgramBuilder::ZipAll(const TArrayRef<const TRuntimeNode>& lists) {
if (lists.empty()) {
- return NewEmptyList(Env.GetEmptyTuple()->GetGenericType());
+ return NewEmptyList(Env.GetEmptyTuple()->GetGenericType());
}
std::vector<TType*> tupleTypes;
@@ -463,10 +463,10 @@ TRuntimeNode TProgramBuilder::ZipAll(const TArrayRef<const TRuntimeNode>& lists)
AS_TYPE(TListType, list.GetStaticType());
auto itemType = static_cast<const TListType&>(*list.GetStaticType()).GetItemType();
- tupleTypes.push_back(TOptionalType::Create(itemType, Env));
+ tupleTypes.push_back(TOptionalType::Create(itemType, Env));
}
- auto returnType = TListType::Create(TTupleType::Create(tupleTypes.size(), tupleTypes.data(), Env), Env);
+ auto returnType = TListType::Create(TTupleType::Create(tupleTypes.size(), tupleTypes.data(), Env), Env);
TCallableBuilder callableBuilder(Env, __func__, returnType);
for (auto& list : lists) {
callableBuilder.Add(list);
@@ -1902,7 +1902,7 @@ TRuntimeNode TProgramBuilder::NewDecimalLiteral(NYql::NDecimal::TInt128 data, ui
}
TRuntimeNode TProgramBuilder::NewOptional(TRuntimeNode data) {
- auto type = TOptionalType::Create(data.GetStaticType(), Env);
+ auto type = TOptionalType::Create(data.GetStaticType(), Env);
return TRuntimeNode(TOptionalLiteral::Create(data, type, Env), true);
}
@@ -1915,8 +1915,8 @@ TRuntimeNode TProgramBuilder::NewVoid() {
return TRuntimeNode(Env.GetVoid(), true);
}
-TRuntimeNode TProgramBuilder::NewEmptyListOfVoid() {
- return TRuntimeNode(Env.GetListOfVoid(), true);
+TRuntimeNode TProgramBuilder::NewEmptyListOfVoid() {
+ return TRuntimeNode(Env.GetListOfVoid(), true);
}
TRuntimeNode TProgramBuilder::NewEmptyOptional(TType* optionalType) {
@@ -1941,7 +1941,7 @@ TType* TProgramBuilder::NewStructType(TType* baseStructType, const std::string_v
MKQL_ENSURE(baseStructType->IsStruct(), "Expected struct type");
const auto& detailedBaseStructType = static_cast<const TStructType&>(*baseStructType);
- TStructTypeBuilder builder(Env);
+ TStructTypeBuilder builder(Env);
builder.Reserve(detailedBaseStructType.GetMembersCount() + 1);
for (ui32 i = 0, e = detailedBaseStructType.GetMembersCount(); i < e; ++i) {
builder.Add(detailedBaseStructType.GetMemberName(i), detailedBaseStructType.GetMemberType(i));
@@ -1952,7 +1952,7 @@ TType* TProgramBuilder::NewStructType(TType* baseStructType, const std::string_v
}
TType* TProgramBuilder::NewStructType(const TArrayRef<const std::pair<std::string_view, TType*>>& memberTypes) {
- TStructTypeBuilder builder(Env);
+ TStructTypeBuilder builder(Env);
builder.Reserve(memberTypes.size());
for (auto& x : memberTypes) {
builder.Add(x.first, x.second);
@@ -1970,7 +1970,7 @@ TRuntimeNode TProgramBuilder::NewStruct(const TArrayRef<const std::pair<std::str
return NewEmptyStruct();
}
- TStructLiteralBuilder builder(Env);
+ TStructLiteralBuilder builder(Env);
for (auto x : members) {
builder.Add(x.first, x.second);
}
@@ -1996,13 +1996,13 @@ TRuntimeNode TProgramBuilder::NewStruct(TType* structType, const TArrayRef<const
return TRuntimeNode(TStructLiteral::Create(values.size(), values.data(), detailedStructType, Env), true);
}
-TRuntimeNode TProgramBuilder::NewEmptyList(TType* itemType) {
- TListLiteralBuilder builder(Env, itemType);
+TRuntimeNode TProgramBuilder::NewEmptyList(TType* itemType) {
+ TListLiteralBuilder builder(Env, itemType);
return TRuntimeNode(builder.Build(), true);
}
TRuntimeNode TProgramBuilder::NewList(TType* itemType, const TArrayRef<const TRuntimeNode>& items) {
- TListLiteralBuilder builder(Env, itemType);
+ TListLiteralBuilder builder(Env, itemType);
for (auto item : items) {
builder.Add(item);
}
@@ -2019,11 +2019,11 @@ TType* TProgramBuilder::NewDecimalType(ui8 precision, ui8 scale) {
}
TType* TProgramBuilder::NewOptionalType(TType* itemType) {
- return TOptionalType::Create(itemType, Env);
+ return TOptionalType::Create(itemType, Env);
}
-TType* TProgramBuilder::NewListType(TType* itemType) {
- return TListType::Create(itemType, Env);
+TType* TProgramBuilder::NewListType(TType* itemType) {
+ return TListType::Create(itemType, Env);
}
TType* TProgramBuilder::NewStreamType(TType* itemType) {
@@ -2047,7 +2047,7 @@ TType* TProgramBuilder::NewTaggedType(TType* baseType, const std::string_view& t
}
TType* TProgramBuilder::NewDictType(TType* keyType, TType* payloadType, bool multi) {
- return TDictType::Create(keyType, multi ? NewListType(payloadType) : payloadType, Env);
+ return TDictType::Create(keyType, multi ? NewListType(payloadType) : payloadType, Env);
}
TRuntimeNode TProgramBuilder::NewDict(TType* dictType, const TArrayRef<const std::pair<TRuntimeNode, TRuntimeNode>>& items) {
@@ -2065,7 +2065,7 @@ TType* TProgramBuilder::NewEmptyTupleType() {
}
TType* TProgramBuilder::NewTupleType(const TArrayRef<TType* const>& elements) {
- return TTupleType::Create(elements.size(), elements.data(), Env);
+ return TTupleType::Create(elements.size(), elements.data(), Env);
}
TType* TProgramBuilder::NewArrayType(const TArrayRef<TType* const>& elements) {
@@ -3059,7 +3059,7 @@ TRuntimeNode TProgramBuilder::UnaryDataFunction(TRuntimeNode data, const std::st
} else if (flags & TDataFunctionFlags::HasStringResult) {
resultType = TDataType::Create(NUdf::TDataType<char*>::Id, Env);
} else if (flags & TDataFunctionFlags::HasOptionalResult) {
- resultType = TOptionalType::Create(type, Env);
+ resultType = TOptionalType::Create(type, Env);
} else {
resultType = type;
}
@@ -3094,7 +3094,7 @@ TRuntimeNode TProgramBuilder::ToDict(TRuntimeNode list, bool multi, const TUnary
auto payload = payloadSelector(itemArg);
auto payloadType = payload.GetStaticType();
if (multi) {
- payloadType = TListType::Create(payloadType, Env);
+ payloadType = TListType::Create(payloadType, Env);
}
auto dictType = TDictType::Create(keyType, payloadType, Env);
@@ -3815,9 +3815,9 @@ TRuntimeNode TProgramBuilder::Apply(TRuntimeNode callableNode, const TArrayRef<c
MKQL_ENSURE(usedArgs >= callableType->GetArgumentsCount() - callableType->GetOptionalArgumentsCount(), "Too few arguments");
for (ui32 i = 0; i < usedArgs; i++) {
- TType* argType = callableType->GetArgumentType(i);
+ TType* argType = callableType->GetArgumentType(i);
TRuntimeNode arg = args[i];
- MKQL_ENSURE(arg.GetStaticType()->IsConvertableTo(*argType),
+ MKQL_ENSURE(arg.GetStaticType()->IsConvertableTo(*argType),
"Argument type mismatch for argument " << i << ": runtime " << argType->GetKindAsStr()
<< " with static " << arg.GetStaticType()->GetKindAsStr());
}
@@ -4157,14 +4157,14 @@ TRuntimeNode TProgramBuilder::ListIf(TRuntimeNode predicate, TRuntimeNode item)
}
TRuntimeNode TProgramBuilder::AsList(TRuntimeNode item) {
- TListLiteralBuilder builder(Env, item.GetStaticType());
+ TListLiteralBuilder builder(Env, item.GetStaticType());
builder.Add(item);
return TRuntimeNode(builder.Build(), true);
}
TRuntimeNode TProgramBuilder::AsList(const TArrayRef<const TRuntimeNode>& items) {
MKQL_ENSURE(!items.empty(), "required not empty list of items");
- TListLiteralBuilder builder(Env, items[0].GetStaticType());
+ TListLiteralBuilder builder(Env, items[0].GetStaticType());
for (auto item : items) {
builder.Add(item);
}
diff --git a/ydb/library/yql/minikql/mkql_program_builder.h b/ydb/library/yql/minikql/mkql_program_builder.h
index 94b0d4d84f7..10f1ad7ccf1 100644
--- a/ydb/library/yql/minikql/mkql_program_builder.h
+++ b/ydb/library/yql/minikql/mkql_program_builder.h
@@ -168,9 +168,9 @@ public:
TRuntimeNode NewStruct(const TArrayRef<const std::pair<std::string_view, TRuntimeNode>>& members);
TRuntimeNode NewStruct(TType* structType, const TArrayRef<const std::pair<std::string_view, TRuntimeNode>>& members);
- TType* NewListType(TType* itemType);
- TRuntimeNode NewEmptyList(TType* itemType);
- TRuntimeNode NewEmptyListOfVoid();
+ TType* NewListType(TType* itemType);
+ TRuntimeNode NewEmptyList(TType* itemType);
+ TRuntimeNode NewEmptyListOfVoid();
TRuntimeNode NewList(TType* itemType, const TArrayRef<const TRuntimeNode>& items);
TType* NewDictType(TType* keyType, TType* payloadType, bool multi);
diff --git a/ydb/library/yql/minikql/mkql_type_builder.cpp b/ydb/library/yql/minikql/mkql_type_builder.cpp
index 50e94845552..4aecb564bf7 100644
--- a/ydb/library/yql/minikql/mkql_type_builder.cpp
+++ b/ydb/library/yql/minikql/mkql_type_builder.cpp
@@ -86,7 +86,7 @@ public:
NUdf::TType* Build() const override {
return NMiniKQL::TOptionalType::Create(
const_cast<NMiniKQL::TType*>(ItemType_),
- Parent_.Env());
+ Parent_.Env());
}
private:
@@ -124,7 +124,7 @@ public:
NUdf::TType* Build() const override {
return NMiniKQL::TListType::Create(
- const_cast<NMiniKQL::TType*>(ItemType_), Parent_.Env());
+ const_cast<NMiniKQL::TType*>(ItemType_), Parent_.Env());
}
private:
@@ -223,7 +223,7 @@ public:
NUdf::TType* Build() const override {
return NMiniKQL::TDictType::Create(
const_cast<NMiniKQL::TType*>(KeyType_),
- const_cast<NMiniKQL::TType*>(ValueType_), Parent_.Env());
+ const_cast<NMiniKQL::TType*>(ValueType_), Parent_.Env());
}
private:
@@ -304,7 +304,7 @@ public:
const NMiniKQL::TFunctionTypeInfoBuilder& parent,
ui32 itemsCount)
: Parent_(parent)
- , StructBuilder_(Parent_.Env())
+ , StructBuilder_(Parent_.Env())
{
StructBuilder_.Reserve(itemsCount);
}
@@ -420,7 +420,7 @@ public:
NUdf::TType* Build() const override {
return NMiniKQL::TTupleType::Create(
- ElementTypes_.size(), ElementTypes_.data(),
+ ElementTypes_.size(), ElementTypes_.data(),
Parent_.Env());
}
@@ -502,13 +502,13 @@ public:
NUdf::ICallableTypeBuilder& Arg(NUdf::TDataTypeId typeId) override {
auto type = NMiniKQL::TDataType::Create(typeId, Env_);
- ArgsTypes_.push_back(type);
+ ArgsTypes_.push_back(type);
return *this;
}
NUdf::ICallableTypeBuilder& Arg(const NUdf::TType* type) override {
- auto mkqlType = const_cast<NMiniKQL::TType*>(static_cast<const NMiniKQL::TType*>(type));
- ArgsTypes_.push_back(mkqlType);
+ auto mkqlType = const_cast<NMiniKQL::TType*>(static_cast<const NMiniKQL::TType*>(type));
+ ArgsTypes_.push_back(mkqlType);
return *this;
}
@@ -516,7 +516,7 @@ public:
const NUdf::ITypeBuilder& typeBuilder) override
{
auto type = static_cast<NMiniKQL::TType*>(typeBuilder.Build());
- ArgsTypes_.push_back(type);
+ ArgsTypes_.push_back(type);
return *this;
}
@@ -531,8 +531,8 @@ public:
NMiniKQL::TNode* payload = nullptr;
auto callableType = NMiniKQL::TCallableType::Create(
- UdfName, ReturnType_,
- ArgsTypes_.size(), const_cast<NMiniKQL::TType**>(ArgsTypes_.data()),
+ UdfName, ReturnType_,
+ ArgsTypes_.size(), const_cast<NMiniKQL::TType**>(ArgsTypes_.data()),
payload, Env_);
callableType->SetOptionalArgumentsCount(OptionalArgs_);
return callableType;
diff --git a/ydb/library/yql/providers/common/mkql/yql_type_mkql.cpp b/ydb/library/yql/providers/common/mkql/yql_type_mkql.cpp
index b2adddae6d4..4ba0e6d7402 100644
--- a/ydb/library/yql/providers/common/mkql/yql_type_mkql.cpp
+++ b/ydb/library/yql/providers/common/mkql/yql_type_mkql.cpp
@@ -52,7 +52,7 @@ NKikimr::NMiniKQL::TType* BuildType(const TTypeAnnotationNode& annotation, NKiki
if (!itemType) {
return nullptr;
}
- return pgmBuilder.NewListType(itemType);
+ return pgmBuilder.NewListType(itemType);
}
case ETypeAnnotationKind::Optional: {
diff --git a/ydb/library/yql/providers/common/schema/mkql/yql_mkql_schema.cpp b/ydb/library/yql/providers/common/schema/mkql/yql_mkql_schema.cpp
index 701b1120125..0a341057146 100644
--- a/ydb/library/yql/providers/common/schema/mkql/yql_mkql_schema.cpp
+++ b/ydb/library/yql/providers/common/schema/mkql/yql_mkql_schema.cpp
@@ -242,12 +242,12 @@ struct TRuntimeTypeLoader {
TMaybe<TType> LoadStructType(const TVector<std::pair<TString, TType>>& members, ui32 /*level*/) {
auto structType = Builder.NewEmptyStructType();
for (auto& member : members) {
- structType = Builder.NewStructType(structType, member.first, member.second);
+ structType = Builder.NewStructType(structType, member.first, member.second);
}
return structType;
}
TMaybe<TType> LoadListType(TType itemType, ui32 /*level*/) {
- return Builder.NewListType(itemType);
+ return Builder.NewListType(itemType);
}
TMaybe<TType> LoadStreamType(TType itemType, ui32 /*level*/) {
return Builder.NewStreamType(itemType);
@@ -256,7 +256,7 @@ struct TRuntimeTypeLoader {
return Builder.NewOptionalType(itemType);
}
TMaybe<TType> LoadTupleType(const TVector<TType>& elements, ui32 /*level*/) {
- return Builder.NewTupleType(elements);
+ return Builder.NewTupleType(elements);
}
TMaybe<TType> LoadDictType(TType keyType, TType valType, ui32 /*level*/) {
return Builder.NewDictType(keyType, valType, false);
diff --git a/ydb/library/yql/public/issue/protos/issue_message.proto b/ydb/library/yql/public/issue/protos/issue_message.proto
index 8e6dcc00828..d581a5d8f07 100644
--- a/ydb/library/yql/public/issue/protos/issue_message.proto
+++ b/ydb/library/yql/public/issue/protos/issue_message.proto
@@ -13,5 +13,5 @@ message IssueMessage {
optional Position end_position = 3;
optional uint32 issue_code = 4;
optional uint32 severity = 5;
- repeated IssueMessage issues = 6;
+ repeated IssueMessage issues = 6;
}
diff --git a/ydb/library/yql/public/issue/yql_issue_message.cpp b/ydb/library/yql/public/issue/yql_issue_message.cpp
index 527c4abd6d5..f9d512ca5a9 100644
--- a/ydb/library/yql/public/issue/yql_issue_message.cpp
+++ b/ydb/library/yql/public/issue/yql_issue_message.cpp
@@ -33,7 +33,7 @@ TIssue IssueFromMessage(const TIssueMessage& issueMessage) {
issue = TIssue(message.message());
}
- for (const auto& subMessage : message.issues()) {
+ for (const auto& subMessage : message.issues()) {
auto subIssue = new TIssue();
issue.AddSubIssue(subIssue);
queue.push_front(std::make_pair(subIssue, &subMessage));
diff --git a/ydb/library/yql/public/udf/udf_type_builder.h b/ydb/library/yql/public/udf/udf_type_builder.h
index eee0af7bcae..8bfc73a449d 100644
--- a/ydb/library/yql/public/udf/udf_type_builder.h
+++ b/ydb/library/yql/public/udf/udf_type_builder.h
@@ -46,8 +46,8 @@ template <typename... TArgs>
struct TTuple;
template <const char* Tag>
-struct TResource {};
-
+struct TResource {};
+
template <typename... TArgs>
struct TVariant;
@@ -757,11 +757,11 @@ struct TTypeBuilderHelper<TDecimalDataType<Precision, Scale>> {
template <const char* Tag>
struct TTypeBuilderHelper<TResource<Tag>> {
- static TType* Build(const IFunctionTypeInfoBuilder& builder) {
+ static TType* Build(const IFunctionTypeInfoBuilder& builder) {
return builder.Resource(TStringRef(Tag, std::strlen(Tag)));
- }
-};
-
+ }
+};
+
template <typename T>
struct TTypeBuilderHelper<TListType<T>> {
static TType* Build(const IFunctionTypeInfoBuilder& builder) {
diff --git a/ydb/library/yql/udfs/common/stat/stat_udf.cpp b/ydb/library/yql/udfs/common/stat/stat_udf.cpp
index 321f02a079f..64c2bb4a698 100644
--- a/ydb/library/yql/udfs/common/stat/stat_udf.cpp
+++ b/ydb/library/yql/udfs/common/stat/stat_udf.cpp
@@ -1,3 +1,3 @@
-#include "static/stat_udf.h"
-
-REGISTER_MODULES(TStatModule)
+#include "static/stat_udf.h"
+
+REGISTER_MODULES(TStatModule)
diff --git a/ydb/library/yql/udfs/common/stat/stat_udf_ut.cpp b/ydb/library/yql/udfs/common/stat/stat_udf_ut.cpp
index 91c0ef6a9c2..d6da83539e5 100644
--- a/ydb/library/yql/udfs/common/stat/stat_udf_ut.cpp
+++ b/ydb/library/yql/udfs/common/stat/stat_udf_ut.cpp
@@ -4,17 +4,17 @@
#include <ydb/library/yql/minikql/computation/mkql_computation_node.h>
#include <ydb/library/yql/minikql/comp_nodes/mkql_factories.h>
#include <ydb/library/yql/minikql/invoke_builtins/mkql_builtins.h>
-#include <util/random/random.h>
+#include <util/random/random.h>
#include <util/system/sanitizers.h>
#include <array>
-
+
namespace NYql {
using namespace NKikimr::NMiniKQL;
namespace NUdf {
extern NUdf::TUniquePtr<NUdf::IUdfModule> CreateStatModule();
}
-
+
Y_UNIT_TEST_SUITE(TUDFStatTest) {
Y_UNIT_TEST(SimplePercentile) {
auto mutableFunctionRegistry = CreateFunctionRegistry(CreateBuiltinRegistry())->Clone();
@@ -28,27 +28,27 @@ using namespace NKikimr::NMiniKQL;
auto udfTDigest_Create = pgmBuilder.Udf("Stat.TDigest_Create");
auto udfTDigest_AddValue = pgmBuilder.Udf("Stat.TDigest_AddValue");
auto udfTDigest_GetPercentile = pgmBuilder.Udf("Stat.TDigest_GetPercentile");
-
+
TRuntimeNode pgmDigest;
{
auto param1 = pgmBuilder.NewDataLiteral<double>(0.0);
TVector<TRuntimeNode> params = {param1};
pgmDigest = pgmBuilder.Apply(udfTDigest_Create, params);
}
-
+
for (int n = 1; n < 10; n += 1) {
auto param2 = pgmBuilder.NewDataLiteral((double)n);
TVector<TRuntimeNode> params = {pgmDigest, param2};
pgmDigest = pgmBuilder.Apply(udfTDigest_AddValue, params);
}
-
+
TRuntimeNode pgmReturn;
{
auto param2 = pgmBuilder.NewDataLiteral<double>(0.9);
TVector<TRuntimeNode> params = {pgmDigest, param2};
pgmReturn = pgmBuilder.Apply(udfTDigest_GetPercentile, params);
}
-
+
TExploringNodeVisitor explorer;
explorer.Walk(pgmReturn.GetNode(), env);
TComputationPatternOpts opts(alloc.Ref(), env, GetBuiltinFactory(), mutableFunctionRegistry.Get(),
@@ -78,21 +78,21 @@ using namespace NKikimr::NMiniKQL;
TVector<TRuntimeNode> params = {param1};
pgmDigest = pgmBuilder.Apply(udfTDigest_Create, params);
}
-
+
TVector<double> vals = {800, 20, 150};
for (auto val : vals) {
auto param2 = pgmBuilder.NewDataLiteral(val);
TVector<TRuntimeNode> params = {pgmDigest, param2};
pgmDigest = pgmBuilder.Apply(udfTDigest_AddValue, params);
}
-
+
TRuntimeNode pgmReturn;
{
auto param2 = pgmBuilder.NewDataLiteral<double>(0.5);
TVector<TRuntimeNode> params = {pgmDigest, param2};
pgmReturn = pgmBuilder.Apply(udfTDigest_GetPercentile, params);
}
-
+
TExploringNodeVisitor explorer;
explorer.Walk(pgmReturn.GetNode(), env);
TComputationPatternOpts opts(alloc.Ref(), env, GetBuiltinFactory(), mutableFunctionRegistry.Get(),
@@ -103,7 +103,7 @@ using namespace NKikimr::NMiniKQL;
Cerr << value.Get<double>() << Endl;
//~ UNIT_ASSERT_DOUBLES_EQUAL(value.Get<double>(), 9.0, 0.001);
}
-
+
Y_UNIT_TEST(SerializedPercentile) {
auto mutableFunctionRegistry = CreateFunctionRegistry(CreateBuiltinRegistry())->Clone();
auto randomProvider = CreateDeterministicRandomProvider(1);
@@ -200,7 +200,7 @@ using namespace NKikimr::NMiniKQL;
}
pgmSerializedDataVector.push_back(pgmSerializedData);
}
-
+
TRuntimeNode pgmDigest;
for (size_t i = 0; i < pgmSerializedDataVector.size(); ++i) {
TRuntimeNode pgmDigest2;
@@ -215,14 +215,14 @@ using namespace NKikimr::NMiniKQL;
pgmDigest = pgmBuilder.Apply(udfTDigest_Merge, params);
}
}
-
+
TRuntimeNode pgmReturn;
{
auto param2 = pgmBuilder.NewDataLiteral<double>(0.9);
TVector<TRuntimeNode> params = {pgmDigest, param2};
pgmReturn = pgmBuilder.Apply(udfTDigest_GetPercentile, params);
}
-
+
TExploringNodeVisitor explorer;
explorer.Walk(pgmReturn.GetNode(), env);
TComputationPatternOpts opts(alloc.Ref(), env, GetBuiltinFactory(), mutableFunctionRegistry.Get(),
@@ -232,11 +232,11 @@ using namespace NKikimr::NMiniKQL;
auto value = graph->GetValue();
UNIT_ASSERT_DOUBLES_EQUAL(value.Get<double>(), 8.95, 0.001);
}
-
+
static double GetParetoRandomNumber(double a) {
return 1 / pow(RandomNumber<double>(), double(1) / a);
}
-
+
Y_UNIT_TEST(BigPercentile) {
auto mutableFunctionRegistry = CreateFunctionRegistry(CreateBuiltinRegistry())->Clone();
auto randomProvider = CreateDeterministicRandomProvider(1);
@@ -260,7 +260,7 @@ using namespace NKikimr::NMiniKQL;
double randomNumber = GetParetoRandomNumber(10);
randomNumbers1.push_back(randomNumber);
randomNumbers2.push_back(pgmBuilder.NewDataLiteral(randomNumber));
- }
+ }
TRuntimeNode bigList = pgmBuilder.AsList(randomNumbers2);
auto pgmDigest =
pgmBuilder.Fold1(bigList,
@@ -283,7 +283,7 @@ using namespace NKikimr::NMiniKQL;
args[1] = param2;
return pgmBuilder.Apply(udfTDigest_GetPercentile, args);
});
-
+
TExploringNodeVisitor explorer;
explorer.Walk(pgmReturn.GetNode(), env);
TComputationPatternOpts opts(alloc.Ref(), env, GetBuiltinFactory(), mutableFunctionRegistry.Get(),
@@ -300,7 +300,7 @@ using namespace NKikimr::NMiniKQL;
double p = (index - 0.5) / double(randomNumbers1.size());
UNIT_ASSERT_DOUBLES_EQUAL(p, PERCENTILE, THRESHOLD);
}
-
+
Y_UNIT_TEST(CentroidPrecision) {
auto mutableFunctionRegistry = CreateFunctionRegistry(CreateBuiltinRegistry())->Clone();
auto randomProvider = CreateDeterministicRandomProvider(1);
@@ -347,7 +347,7 @@ using namespace NKikimr::NMiniKQL;
args[1] = param2;
return pgmBuilder.Apply(udfTDigest_GetPercentile, args);
});
-
+
TExploringNodeVisitor explorer;
explorer.Walk(pgmReturn.GetNode(), env);
TComputationPatternOpts opts(alloc.Ref(), env, GetBuiltinFactory(), mutableFunctionRegistry.Get(),
@@ -359,5 +359,5 @@ using namespace NKikimr::NMiniKQL;
double digestValue = value.Get<double>();
UNIT_ASSERT_EQUAL(digestValue, majorityValue);
}
- }
-}
+ }
+}
diff --git a/ydb/library/yql/udfs/common/stat/static/stat_udf.h b/ydb/library/yql/udfs/common/stat/static/stat_udf.h
index 201a8bd3755..6eb6203051a 100644
--- a/ydb/library/yql/udfs/common/stat/static/stat_udf.h
+++ b/ydb/library/yql/udfs/common/stat/static/stat_udf.h
@@ -1,15 +1,15 @@
-#pragma once
+#pragma once
#include <ydb/library/yql/public/udf/udf_helpers.h>
#include <ydb/library/yql/public/udf/udf_value_builder.h>
-#include "tdigest.h"
-
+#include "tdigest.h"
+
using namespace NYql;
-using namespace NUdf;
-
-namespace {
+using namespace NUdf;
+
+namespace {
extern const char DigestResourceName[] = "Stat.TDigestResource";
-
+
typedef TBoxedResource<TDigest, DigestResourceName> TDigestResource;
typedef TRefCountedPtr<TDigestResource> TDigestResourcePtr;
@@ -20,7 +20,7 @@ namespace {
if (delta == 0 || K / delta < 1) {
UdfTerminate((TStringBuilder() << Pos_ << " Invalid combination of delta/K values").data());
}
-
+
return TUnboxedValuePod(new TDigestResource(delta, K, args[0].Get<double>()));
}
@@ -31,38 +31,38 @@ namespace {
resource->Get()->AddValue(args[1].Get<double>());
return TUnboxedValuePod(resource);
}
-
+
SIMPLE_UDF(TTDigest_GetPercentile, double(TResource<DigestResourceName>, double)) {
Y_UNUSED(valueBuilder);
TDigestResource::Validate(args[0]);
return TUnboxedValuePod(static_cast<TDigestResource*>(args[0].AsBoxed().Get())->Get()->GetPercentile(args[1].Get<double>()));
}
-
+
SIMPLE_UDF(TTDigest_Serialize, char*(TResource<DigestResourceName>)) {
TDigestResource::Validate(args[0]);
return valueBuilder->NewString(static_cast<TDigestResource*>(args[0].AsBoxed().Get())->Get()->Serialize());
}
-
+
SIMPLE_UDF(TTDigest_Deserialize, TResource<DigestResourceName>(char*)) {
Y_UNUSED(valueBuilder);
return TUnboxedValuePod(new TDigestResource(TString(args[0].AsStringRef())));
}
-
+
SIMPLE_UDF(TTDigest_Merge, TResource<DigestResourceName>(TResource<DigestResourceName>, TResource<DigestResourceName>)) {
Y_UNUSED(valueBuilder);
TDigestResource::Validate(args[0]);
TDigestResource::Validate(args[1]);
return TUnboxedValuePod(new TDigestResource(static_cast<TDigestResource*>(args[0].AsBoxed().Get())->Get(), static_cast<TDigestResource*>(args[1].AsBoxed().Get())->Get()));
}
-
+
/*
- *
- * TODO: Memory tracking
- *
- *
- *
- */
-
+ *
+ * TODO: Memory tracking
+ *
+ *
+ *
+ */
+
SIMPLE_MODULE(TStatModule,
TTDigest_Create,
TTDigest_AddValue,
@@ -70,5 +70,5 @@ namespace {
TTDigest_Serialize,
TTDigest_Deserialize,
TTDigest_Merge)
-
-}
+
+}
diff --git a/ydb/library/yql/udfs/common/stat/static/static_udf.cpp b/ydb/library/yql/udfs/common/stat/static/static_udf.cpp
index 101b5394a28..3cb1d88a1c8 100644
--- a/ydb/library/yql/udfs/common/stat/static/static_udf.cpp
+++ b/ydb/library/yql/udfs/common/stat/static/static_udf.cpp
@@ -1,10 +1,10 @@
-#include "stat_udf.h"
-
+#include "stat_udf.h"
+
namespace NYql {
namespace NUdf {
NUdf::TUniquePtr<NUdf::IUdfModule> CreateStatModule() {
return new TStatModule();
}
-
+
}
-}
+}
diff --git a/ydb/library/yql/udfs/common/stat/static/tdigest.cpp b/ydb/library/yql/udfs/common/stat/static/tdigest.cpp
index a243258afcb..b8668eb27b0 100644
--- a/ydb/library/yql/udfs/common/stat/static/tdigest.cpp
+++ b/ydb/library/yql/udfs/common/stat/static/tdigest.cpp
@@ -1,78 +1,78 @@
-#include "tdigest.h"
+#include "tdigest.h"
#include <ydb/library/yql/udfs/common/stat/static/tdigest.pb.h>
-#include <cmath>
-
-// TODO: rewrite to https://github.com/tdunning/t-digest/blob/master/src/main/java/com/tdunning/math/stats/MergingDigest.java
-
-TDigest::TDigest(double delta, double k)
- : N(0)
- , Delta(delta)
- , K(k)
+#include <cmath>
+
+// TODO: rewrite to https://github.com/tdunning/t-digest/blob/master/src/main/java/com/tdunning/math/stats/MergingDigest.java
+
+TDigest::TDigest(double delta, double k)
+ : N(0)
+ , Delta(delta)
+ , K(k)
{
}
-
-TDigest::TDigest(double delta, double k, double firstValue)
- : TDigest(delta, k)
-{
- AddValue(firstValue);
-}
-
+
+TDigest::TDigest(double delta, double k, double firstValue)
+ : TDigest(delta, k)
+{
+ AddValue(firstValue);
+}
+
TDigest::TDigest(const TString& serializedDigest)
- : N(0)
-{
- NTDigest::TDigest digest;
+ : N(0)
+{
+ NTDigest::TDigest digest;
Y_VERIFY(digest.ParseFromString(serializedDigest));
- Delta = digest.GetDelta();
- K = digest.GetK();
- for (int i = 0; i < digest.centroids_size(); ++i) {
- const NTDigest::TDigest::TCentroid& centroid = digest.centroids(i);
+ Delta = digest.GetDelta();
+ K = digest.GetK();
+ for (int i = 0; i < digest.centroids_size(); ++i) {
+ const NTDigest::TDigest::TCentroid& centroid = digest.centroids(i);
Update(centroid.GetMean(), centroid.GetWeight());
- }
-}
-
+ }
+}
+
TDigest::TDigest(const TDigest* digest1, const TDigest* digest2)
- : N(0)
- , Delta(std::min(digest1->Delta, digest2->Delta))
- , K(std::max(digest1->K, digest2->K))
-{
+ : N(0)
+ , Delta(std::min(digest1->Delta, digest2->Delta))
+ , K(std::max(digest1->K, digest2->K))
+{
Add(*digest1);
Add(*digest2);
-}
-
+}
+
void TDigest::Add(const TDigest& otherDigest) {
for (auto& it : otherDigest.Centroids)
Update(it.Mean, it.Count);
for (auto& it : otherDigest.Unmerged)
Update(it.Mean, it.Count);
-}
-
+}
+
TDigest TDigest::operator+(const TDigest& other) {
- TDigest T(Delta, K);
+ TDigest T(Delta, K);
T.Add(*this);
T.Add(other);
- return T;
-}
-
+ return T;
+}
+
TDigest& TDigest::operator+=(const TDigest& other) {
Add(other);
- return *this;
-}
-
+ return *this;
+}
+
void TDigest::AddCentroid(const TCentroid& centroid) {
Unmerged.push_back(centroid);
N += centroid.Count;
-}
-
+}
+
double TDigest::GetThreshold(double q) {
return 4 * N * Delta * q * (1 - q);
-}
-
+}
+
void TDigest::MergeCentroid(TVector<TCentroid>& merged, double& sum, const TCentroid& centroid) {
if (merged.empty()) {
merged.push_back(centroid);
sum += centroid.Count;
return;
- }
+ }
// Use quantile that has the tightest k
double q1 = (sum - merged.back().Count * 0.5) / N;
double q2 = (sum + centroid.Count * 0.5) / N;
@@ -80,23 +80,23 @@ void TDigest::MergeCentroid(TVector<TCentroid>& merged, double& sum, const TCent
double k2 = GetThreshold(q2);
if (k > k2) {
k = k2;
- }
+ }
if (merged.back().Count + centroid.Count <= k) {
merged.back().Update(centroid.Mean, centroid.Count);
} else {
merged.push_back(centroid);
- }
+ }
sum += centroid.Count;
-}
-
-void TDigest::Update(double x, double w) {
+}
+
+void TDigest::Update(double x, double w) {
AddCentroid(TCentroid(x, w));
if (Unmerged.size() >= K / Delta) {
- Compress();
- }
-}
-
-void TDigest::Compress() {
+ Compress();
+ }
+}
+
+void TDigest::Compress() {
if (Unmerged.empty())
return;
// Merge Centroids and Unmerged into Merged
@@ -111,31 +111,31 @@ void TDigest::Compress() {
} else {
MergeCentroid(Merged, sum, *j++);
}
- }
+ }
while (i != Centroids.end()) {
MergeCentroid(Merged, sum, *i++);
- }
+ }
while (j != Unmerged.end()) {
MergeCentroid(Merged, sum, *j++);
}
swap(Centroids, Merged);
Unmerged.clear();
-}
-
-void TDigest::Clear() {
- Centroids.clear();
+}
+
+void TDigest::Clear() {
+ Centroids.clear();
Unmerged.clear();
- N = 0;
-}
-
-void TDigest::AddValue(double value) {
- Update(value, 1);
-}
-
-double TDigest::GetPercentile(double percentile) {
+ N = 0;
+}
+
+void TDigest::AddValue(double value) {
+ Update(value, 1);
+}
+
+double TDigest::GetPercentile(double percentile) {
Compress();
- if (Centroids.empty())
- return 0.0;
+ if (Centroids.empty())
+ return 0.0;
// This algorithm uses C=1/2 with 0.5 optimized away
// See https://en.wikipedia.org/wiki/Percentile#First_Variant.2C
double x = percentile * N;
@@ -147,23 +147,23 @@ double TDigest::GetPercentile(double percentile) {
if (x <= current_x) {
double k = (x - prev_x) / (current_x - prev_x);
return prev_mean + k * (C.Mean - prev_mean);
- }
+ }
sum += C.Count;
prev_x = current_x;
prev_mean = C.Mean;
- }
+ }
return Centroids.back().Mean;
-}
-
+}
+
TString TDigest::Serialize() {
Compress();
- NTDigest::TDigest digest;
- digest.SetDelta(Delta);
- digest.SetK(K);
- for (const auto& it : Centroids) {
- NTDigest::TDigest::TCentroid* centroid = digest.AddCentroids();
+ NTDigest::TDigest digest;
+ digest.SetDelta(Delta);
+ digest.SetK(K);
+ for (const auto& it : Centroids) {
+ NTDigest::TDigest::TCentroid* centroid = digest.AddCentroids();
centroid->SetMean(it.Mean);
centroid->SetWeight(it.Count);
- }
- return digest.SerializeAsString();
-}
+ }
+ return digest.SerializeAsString();
+}
diff --git a/ydb/library/yql/udfs/common/stat/static/tdigest.h b/ydb/library/yql/udfs/common/stat/static/tdigest.h
index 316287b1393..acec0a02645 100644
--- a/ydb/library/yql/udfs/common/stat/static/tdigest.h
+++ b/ydb/library/yql/udfs/common/stat/static/tdigest.h
@@ -1,14 +1,14 @@
-#pragma once
-
-#include <util/generic/map.h>
-#include <util/generic/list.h>
-#include <util/generic/vector.h>
-
-class TDigest {
- struct TCentroid {
- double Mean;
- double Count;
-
+#pragma once
+
+#include <util/generic/map.h>
+#include <util/generic/list.h>
+#include <util/generic/vector.h>
+
+class TDigest {
+ struct TCentroid {
+ double Mean;
+ double Count;
+
TCentroid()
: Mean(0)
, Count(0)
@@ -19,44 +19,44 @@ class TDigest {
, Count(weight)
{
}
-
+
bool operator<(const TCentroid& centroid) const {
return Mean < centroid.Mean;
}
-
- void Update(double x, double weight) {
- Count += weight;
- Mean += weight * (x - Mean) / Count;
- }
- };
-
+
+ void Update(double x, double weight) {
+ Count += weight;
+ Mean += weight * (x - Mean) / Count;
+ }
+ };
+
TVector<TCentroid> Centroids;
TVector<TCentroid> Unmerged;
TVector<TCentroid> Merged;
typedef TVector<TCentroid>::iterator iter_t;
- double N;
- double Delta;
- double K;
-
+ double N;
+ double Delta;
+ double K;
+
void Add(const TDigest& otherDigest);
- void AddCentroid(const TCentroid& centroid);
- double GetThreshold(double q);
-
+ void AddCentroid(const TCentroid& centroid);
+ double GetThreshold(double q);
+
void MergeCentroid(TVector<TCentroid>& merged, double& sum, const TCentroid& centroid);
-protected:
- void Update(double x, double w = 1.0);
-
-public:
- TDigest(double delta = 0.01, double k = 25);
- TDigest(double delta, double k, double firstValue);
+protected:
+ void Update(double x, double w = 1.0);
+
+public:
+ TDigest(double delta = 0.01, double k = 25);
+ TDigest(double delta, double k, double firstValue);
TDigest(const TString& serializedDigest);
- TDigest(const TDigest* digest1, const TDigest* digest2); // merge
+ TDigest(const TDigest* digest1, const TDigest* digest2); // merge
TString Serialize();
TDigest operator+(const TDigest& other);
TDigest& operator+=(const TDigest& other);
- void AddValue(double value);
- void Compress();
- void Clear();
- double GetPercentile(double percentile);
-};
+ void AddValue(double value);
+ void Compress();
+ void Clear();
+ double GetPercentile(double percentile);
+};
diff --git a/ydb/library/yql/udfs/common/stat/static/tdigest.proto b/ydb/library/yql/udfs/common/stat/static/tdigest.proto
index fbe2dda52f7..4a2db3e638c 100644
--- a/ydb/library/yql/udfs/common/stat/static/tdigest.proto
+++ b/ydb/library/yql/udfs/common/stat/static/tdigest.proto
@@ -1,11 +1,11 @@
-package NTDigest;
-
-message TDigest {
- optional double Delta = 1;
- optional double K = 2;
- message TCentroid {
- optional double Mean = 1;
- optional double Weight = 2;
- }
- repeated TCentroid Centroids = 3;
-}
+package NTDigest;
+
+message TDigest {
+ optional double Delta = 1;
+ optional double K = 2;
+ message TCentroid {
+ optional double Mean = 1;
+ optional double Weight = 2;
+ }
+ repeated TCentroid Centroids = 3;
+}
diff --git a/ydb/library/yql/udfs/common/stat/static/ya.make b/ydb/library/yql/udfs/common/stat/static/ya.make
index 277882619dd..507033930d7 100644
--- a/ydb/library/yql/udfs/common/stat/static/ya.make
+++ b/ydb/library/yql/udfs/common/stat/static/ya.make
@@ -1,4 +1,4 @@
-LIBRARY()
+LIBRARY()
YQL_ABI_VERSION(
2
@@ -11,19 +11,19 @@ OWNER(
g:yql
g:yql_ydb_core
)
-
-SRCS(
- tdigest.proto
- static_udf.cpp
- stat_udf.h
- tdigest.h
- tdigest.cpp
-)
-
-PEERDIR(
- contrib/libs/protobuf
- util/draft
+
+SRCS(
+ tdigest.proto
+ static_udf.cpp
+ stat_udf.h
+ tdigest.h
+ tdigest.cpp
+)
+
+PEERDIR(
+ contrib/libs/protobuf
+ util/draft
ydb/library/yql/public/udf
-)
-
-END()
+)
+
+END()
diff --git a/ydb/library/yql/udfs/common/stat/ut/ya.make b/ydb/library/yql/udfs/common/stat/ut/ya.make
index 59f5a2652f7..e477adbda66 100644
--- a/ydb/library/yql/udfs/common/stat/ut/ya.make
+++ b/ydb/library/yql/udfs/common/stat/ut/ya.make
@@ -1,22 +1,22 @@
UNITTEST_FOR(ydb/library/yql/udfs/common/stat/static)
-OWNER(xenoxeno)
-
-SRCS(
- ../stat_udf_ut.cpp
-)
-
-PEERDIR(
+OWNER(xenoxeno)
+
+SRCS(
+ ../stat_udf_ut.cpp
+)
+
+PEERDIR(
ydb/library/yql/minikql
ydb/library/yql/minikql/comp_nodes
ydb/library/yql/minikql/computation
ydb/library/yql/public/udf/service/exception_policy
-)
-
+)
+
YQL_LAST_ABI_VERSION()
TIMEOUT(300)
SIZE(MEDIUM)
-END()
+END()
diff --git a/ydb/library/yql/udfs/common/stat/ya.make b/ydb/library/yql/udfs/common/stat/ya.make
index c7d6f33f4ec..0c72374c78a 100644
--- a/ydb/library/yql/udfs/common/stat/ya.make
+++ b/ydb/library/yql/udfs/common/stat/ya.make
@@ -1,5 +1,5 @@
YQL_UDF(stat_udf)
-
+
YQL_ABI_VERSION(
2
9
@@ -7,16 +7,16 @@ YQL_ABI_VERSION(
)
OWNER(xenoxeno g:yql g:yql_ydb_core)
-
-SRCS(
- stat_udf.cpp
-)
-
-PEERDIR(
+
+SRCS(
+ stat_udf.cpp
+)
+
+PEERDIR(
ydb/library/yql/udfs/common/stat/static
-)
-
-END()
+)
+
+END()
RECURSE_FOR_TESTS(
ut
diff --git a/ydb/public/api/grpc/ya.make b/ydb/public/api/grpc/ya.make
index 7e518972b18..24173a0264d 100644
--- a/ydb/public/api/grpc/ya.make
+++ b/ydb/public/api/grpc/ya.make
@@ -12,12 +12,12 @@ OWNER(
)
SRCS(
- ydb_auth_v1.proto
+ ydb_auth_v1.proto
ydb_coordination_v1.proto
ydb_discovery_v1.proto
ydb_export_v1.proto
ydb_import_v1.proto
- ydb_monitoring_v1.proto
+ ydb_monitoring_v1.proto
ydb_operation_v1.proto
ydb_cms_v1.proto
ydb_rate_limiter_v1.proto
diff --git a/ydb/public/api/grpc/ydb_auth_v1.proto b/ydb/public/api/grpc/ydb_auth_v1.proto
index b1508037b06..fe45d0662bc 100644
--- a/ydb/public/api/grpc/ydb_auth_v1.proto
+++ b/ydb/public/api/grpc/ydb_auth_v1.proto
@@ -1,11 +1,11 @@
-syntax = "proto3";
-
-package Ydb.Auth.V1;
-option java_package = "com.yandex.ydb.auth.v1";
-
+syntax = "proto3";
+
+package Ydb.Auth.V1;
+option java_package = "com.yandex.ydb.auth.v1";
+
import "ydb/public/api/protos/ydb_auth.proto";
-
-service AuthService {
- // Perform login using built-in auth system
- rpc Login(Auth.LoginRequest) returns (Auth.LoginResponse);
-}
+
+service AuthService {
+ // Perform login using built-in auth system
+ rpc Login(Auth.LoginRequest) returns (Auth.LoginResponse);
+}
diff --git a/ydb/public/api/grpc/ydb_monitoring_v1.proto b/ydb/public/api/grpc/ydb_monitoring_v1.proto
index 3fbc3ede521..36f739c8a26 100644
--- a/ydb/public/api/grpc/ydb_monitoring_v1.proto
+++ b/ydb/public/api/grpc/ydb_monitoring_v1.proto
@@ -1,11 +1,11 @@
-syntax = "proto3";
-
-package Ydb.Monitoring.V1;
-option java_package = "com.yandex.ydb.monitoring.v1";
-
+syntax = "proto3";
+
+package Ydb.Monitoring.V1;
+option java_package = "com.yandex.ydb.monitoring.v1";
+
import "ydb/public/api/protos/ydb_monitoring.proto";
-
-service MonitoringService {
- // Gets the health status of the database.
- rpc SelfCheck(Monitoring.SelfCheckRequest) returns (Monitoring.SelfCheckResponse);
-}
+
+service MonitoringService {
+ // Gets the health status of the database.
+ rpc SelfCheck(Monitoring.SelfCheckRequest) returns (Monitoring.SelfCheckResponse);
+}
diff --git a/ydb/public/api/protos/ya.make b/ydb/public/api/protos/ya.make
index 797b9d960ec..8a156403a3d 100644
--- a/ydb/public/api/protos/ya.make
+++ b/ydb/public/api/protos/ya.make
@@ -21,7 +21,7 @@ SRCS(
draft/ydb_logstore.proto
draft/yq_private.proto
persqueue_error_codes_v1.proto
- ydb_auth.proto
+ ydb_auth.proto
ydb_persqueue_v1.proto
ydb_persqueue_cluster_discovery.proto
ydb_clickhouse_internal.proto
@@ -34,7 +34,7 @@ SRCS(
ydb_formats.proto
ydb_import.proto
ydb_issue_message.proto
- ydb_monitoring.proto
+ ydb_monitoring.proto
ydb_operation.proto
ydb_query_stats.proto
ydb_rate_limiter.proto
diff --git a/ydb/public/api/protos/ydb_auth.proto b/ydb/public/api/protos/ydb_auth.proto
index 9326f79b520..458b0bc3a66 100644
--- a/ydb/public/api/protos/ydb_auth.proto
+++ b/ydb/public/api/protos/ydb_auth.proto
@@ -1,22 +1,22 @@
-syntax = "proto3";
-option cc_enable_arenas = true;
-
-package Ydb.Auth;
-option java_package = "com.yandex.ydb.auth";
-
+syntax = "proto3";
+option cc_enable_arenas = true;
+
+package Ydb.Auth;
+option java_package = "com.yandex.ydb.auth";
+
import "ydb/public/api/protos/ydb_operation.proto";
-
-message LoginRequest {
- Ydb.Operations.OperationParams operation_params = 1;
- string user = 2;
- string password = 3;
-}
-
-message LoginResponse {
- // After successfull completion must contain LoginResult.
- Ydb.Operations.Operation operation = 1;
-}
-
-message LoginResult {
- string token = 1;
-}
+
+message LoginRequest {
+ Ydb.Operations.OperationParams operation_params = 1;
+ string user = 2;
+ string password = 3;
+}
+
+message LoginResponse {
+ // After successfull completion must contain LoginResult.
+ Ydb.Operations.Operation operation = 1;
+}
+
+message LoginResult {
+ string token = 1;
+}
diff --git a/ydb/public/api/protos/ydb_issue_message.proto b/ydb/public/api/protos/ydb_issue_message.proto
index a997e9393a7..1c294d7c593 100644
--- a/ydb/public/api/protos/ydb_issue_message.proto
+++ b/ydb/public/api/protos/ydb_issue_message.proto
@@ -22,5 +22,5 @@ message IssueMessage {
// WARNING = 2;
// INFO = 3;
uint32 severity = 5;
- repeated IssueMessage issues = 6;
+ repeated IssueMessage issues = 6;
}
diff --git a/ydb/public/api/protos/ydb_monitoring.proto b/ydb/public/api/protos/ydb_monitoring.proto
index d0aa69e3d63..85917cc0cf3 100644
--- a/ydb/public/api/protos/ydb_monitoring.proto
+++ b/ydb/public/api/protos/ydb_monitoring.proto
@@ -1,190 +1,190 @@
-syntax = "proto3";
-option cc_enable_arenas = true;
-
-package Ydb.Monitoring;
-option java_package = "com.yandex.ydb.monitoring";
-option java_outer_classname = "MonitoringProtos";
-
+syntax = "proto3";
+option cc_enable_arenas = true;
+
+package Ydb.Monitoring;
+option java_package = "com.yandex.ydb.monitoring";
+option java_outer_classname = "MonitoringProtos";
+
import "ydb/public/api/protos/ydb_operation.proto";
-
-message StatusFlag {
- // Describes the general state of a component.
- // From GREEN to RED, where GREEN is good, and RED is bad.
- // GREY means that the corresponding status is unknown.
- enum Status {
- UNSPECIFIED = 0;
- GREY = 1;
- GREEN = 2;
- BLUE = 3;
- YELLOW = 4;
- ORANGE = 5;
- RED = 6;
- }
-}
-
-message SelfCheckRequest {
- Ydb.Operations.OperationParams operation_params = 1; // basic operation params, including timeout
- bool return_verbose_status = 2; // return detailed info about components checked with their statuses
- StatusFlag.Status minimum_status = 3; // minimum status of issues to return
- uint32 maximum_level = 4; // maximum level of issues to return
-}
-
-message SelfCheckResponse {
- // After successfull completion must contain SelfCheckResult.
- Ydb.Operations.Operation operation = 1;
-}
-
-message SelfCheck {
- // Describes the result of self-check performed.
- enum Result {
- UNSPECIFIED = 0;
- GOOD = 1;
- DEGRADED = 2;
- MAINTENANCE_REQUIRED = 3;
- EMERGENCY = 4;
- }
-}
-
-message StoragePDiskStatus {
- string id = 1;
- StatusFlag.Status overall = 2;
-}
-
-message StorageVDiskStatus {
- string id = 1;
- StatusFlag.Status overall = 2;
- StatusFlag.Status vdisk_status = 3;
- StoragePDiskStatus pdisk = 4;
-}
-
-message StorageGroupStatus {
- string id = 1;
- StatusFlag.Status overall = 2;
- repeated StorageVDiskStatus vdisks = 3;
-}
-
-message StoragePoolStatus {
- string id = 1;
- StatusFlag.Status overall = 2;
- repeated StorageGroupStatus groups = 3;
-}
-
-message StorageStatus {
- StatusFlag.Status overall = 1;
- repeated StoragePoolStatus pools = 2;
-}
-
-// Describes the state of a tablet group.
-message ComputeTabletStatus {
- StatusFlag.Status overall = 1;
- string type = 2;
- string state = 3;
- uint32 count = 4;
- repeated string id = 5;
-}
-
-message ThreadPoolStatus {
- StatusFlag.Status overall = 1;
- string name = 2;
- float usage = 3;
-}
-
-message LoadAverageStatus {
- StatusFlag.Status overall = 1;
- float load = 2;
- uint32 cores = 3;
-}
-
-message ComputeNodeStatus {
- string id = 1;
- StatusFlag.Status overall = 2;
- repeated ComputeTabletStatus tablets = 3;
- repeated ThreadPoolStatus pools = 4;
- LoadAverageStatus load = 5;
-}
-
-message ComputeStatus {
- StatusFlag.Status overall = 1;
- repeated ComputeNodeStatus nodes = 2;
- repeated ComputeTabletStatus tablets = 3;
-}
-
-message LocationNode {
- uint32 id = 1;
- string host = 2;
- uint32 port = 3;
-}
-
-message LocationStoragePDisk {
- string id = 1;
- string path = 2;
-}
-
-message LocationStorageVDisk {
- string id = 1;
- LocationStoragePDisk pdisk = 2;
-}
-
-message LocationStorageGroup {
- string id = 1;
- LocationStorageVDisk vdisk = 2;
-}
-
-message LocationStoragePool {
- string name = 1;
- LocationStorageGroup group = 2;
-}
-
-message LocationStorage {
- LocationNode node = 1;
- LocationStoragePool pool = 2;
-}
-
-message LocationComputePool {
- string name = 1;
-}
-
-message LocationComputeTablet {
- string type = 1;
- repeated string id = 2;
- uint32 count = 3;
-}
-
-message LocationCompute {
- LocationNode node = 1;
- LocationComputePool pool = 2;
- LocationComputeTablet tablet = 3;
-}
-
-message LocationDatabase {
- string name = 1;
-}
-
-message Location {
- LocationStorage storage = 1;
- LocationCompute compute = 2;
- LocationDatabase database = 3;
-}
-
-message IssueLog {
- string id = 1;
- StatusFlag.Status status = 2;
- string message = 3;
- Location location = 4;
- repeated string reason = 5;
- string type = 6;
- uint32 level = 7;
-}
-
-message DatabaseStatus {
- string name = 1;
- StatusFlag.Status overall = 2;
- StorageStatus storage = 3;
- ComputeStatus compute = 4;
-}
-
-message SelfCheckResult {
- SelfCheck.Result self_check_result = 1;
- repeated IssueLog issue_log = 2;
- repeated DatabaseStatus database_status = 3;
-}
+
+message StatusFlag {
+ // Describes the general state of a component.
+ // From GREEN to RED, where GREEN is good, and RED is bad.
+ // GREY means that the corresponding status is unknown.
+ enum Status {
+ UNSPECIFIED = 0;
+ GREY = 1;
+ GREEN = 2;
+ BLUE = 3;
+ YELLOW = 4;
+ ORANGE = 5;
+ RED = 6;
+ }
+}
+
+message SelfCheckRequest {
+ Ydb.Operations.OperationParams operation_params = 1; // basic operation params, including timeout
+ bool return_verbose_status = 2; // return detailed info about components checked with their statuses
+ StatusFlag.Status minimum_status = 3; // minimum status of issues to return
+ uint32 maximum_level = 4; // maximum level of issues to return
+}
+
+message SelfCheckResponse {
+ // After successfull completion must contain SelfCheckResult.
+ Ydb.Operations.Operation operation = 1;
+}
+
+message SelfCheck {
+ // Describes the result of self-check performed.
+ enum Result {
+ UNSPECIFIED = 0;
+ GOOD = 1;
+ DEGRADED = 2;
+ MAINTENANCE_REQUIRED = 3;
+ EMERGENCY = 4;
+ }
+}
+
+message StoragePDiskStatus {
+ string id = 1;
+ StatusFlag.Status overall = 2;
+}
+
+message StorageVDiskStatus {
+ string id = 1;
+ StatusFlag.Status overall = 2;
+ StatusFlag.Status vdisk_status = 3;
+ StoragePDiskStatus pdisk = 4;
+}
+
+message StorageGroupStatus {
+ string id = 1;
+ StatusFlag.Status overall = 2;
+ repeated StorageVDiskStatus vdisks = 3;
+}
+
+message StoragePoolStatus {
+ string id = 1;
+ StatusFlag.Status overall = 2;
+ repeated StorageGroupStatus groups = 3;
+}
+
+message StorageStatus {
+ StatusFlag.Status overall = 1;
+ repeated StoragePoolStatus pools = 2;
+}
+
+// Describes the state of a tablet group.
+message ComputeTabletStatus {
+ StatusFlag.Status overall = 1;
+ string type = 2;
+ string state = 3;
+ uint32 count = 4;
+ repeated string id = 5;
+}
+
+message ThreadPoolStatus {
+ StatusFlag.Status overall = 1;
+ string name = 2;
+ float usage = 3;
+}
+
+message LoadAverageStatus {
+ StatusFlag.Status overall = 1;
+ float load = 2;
+ uint32 cores = 3;
+}
+
+message ComputeNodeStatus {
+ string id = 1;
+ StatusFlag.Status overall = 2;
+ repeated ComputeTabletStatus tablets = 3;
+ repeated ThreadPoolStatus pools = 4;
+ LoadAverageStatus load = 5;
+}
+
+message ComputeStatus {
+ StatusFlag.Status overall = 1;
+ repeated ComputeNodeStatus nodes = 2;
+ repeated ComputeTabletStatus tablets = 3;
+}
+
+message LocationNode {
+ uint32 id = 1;
+ string host = 2;
+ uint32 port = 3;
+}
+
+message LocationStoragePDisk {
+ string id = 1;
+ string path = 2;
+}
+
+message LocationStorageVDisk {
+ string id = 1;
+ LocationStoragePDisk pdisk = 2;
+}
+
+message LocationStorageGroup {
+ string id = 1;
+ LocationStorageVDisk vdisk = 2;
+}
+
+message LocationStoragePool {
+ string name = 1;
+ LocationStorageGroup group = 2;
+}
+
+message LocationStorage {
+ LocationNode node = 1;
+ LocationStoragePool pool = 2;
+}
+
+message LocationComputePool {
+ string name = 1;
+}
+
+message LocationComputeTablet {
+ string type = 1;
+ repeated string id = 2;
+ uint32 count = 3;
+}
+
+message LocationCompute {
+ LocationNode node = 1;
+ LocationComputePool pool = 2;
+ LocationComputeTablet tablet = 3;
+}
+
+message LocationDatabase {
+ string name = 1;
+}
+
+message Location {
+ LocationStorage storage = 1;
+ LocationCompute compute = 2;
+ LocationDatabase database = 3;
+}
+
+message IssueLog {
+ string id = 1;
+ StatusFlag.Status status = 2;
+ string message = 3;
+ Location location = 4;
+ repeated string reason = 5;
+ string type = 6;
+ uint32 level = 7;
+}
+
+message DatabaseStatus {
+ string name = 1;
+ StatusFlag.Status overall = 2;
+ StorageStatus storage = 3;
+ ComputeStatus compute = 4;
+}
+
+message SelfCheckResult {
+ SelfCheck.Result self_check_result = 1;
+ repeated IssueLog issue_log = 2;
+ repeated DatabaseStatus database_status = 3;
+}
diff --git a/ydb/public/api/ya.make b/ydb/public/api/ya.make
index 70545c88abe..657da8cacc8 100644
--- a/ydb/public/api/ya.make
+++ b/ydb/public/api/ya.make
@@ -1,6 +1,6 @@
OWNER(g:kikimr)
-
-RECURSE(
+
+RECURSE(
grpc
protos
-)
+)
diff --git a/ydb/public/lib/base/msgbus.h b/ydb/public/lib/base/msgbus.h
index 1f37fe9e8f0..f11bd9771f1 100644
--- a/ydb/public/lib/base/msgbus.h
+++ b/ydb/public/lib/base/msgbus.h
@@ -33,44 +33,44 @@ enum {
MTYPE_CLIENT_DATASHARD_SET_CONFIG = 10418, // deprecated
MTYPE_CLIENT_DESTROY_JOB = 10419, // deprecated
MTYPE_CLIENT_COMPACTION_BROKER_SET_CONFIG = 10420, // deprecated
- MTYPE_CLIENT_OLD_HIVE_CREATE_TABLET = 10421, // deprecated
- MTYPE_CLIENT_HIVE_CREATE_TABLET_RESULT = 10422, // deprecated
- MTYPE_CLIENT_OLD_LOCAL_ENUMERATE_TABLETS = 10423, // deprecated
- MTYPE_CLIENT_LOCAL_ENUMERATE_TABLETS_RESULT = 10424, // deprecated
- MTYPE_CLIENT_OLD_KEYVALUE = 10425, // deprecated
- MTYPE_CLIENT_KEYVALUE_RESPONSE = 10426, // deprecated
- MTYPE_CLIENT_MESSAGE_BUS_TRACE = 10427,
- MTYPE_CLIENT_MESSAGE_BUS_TRACE_STATUS = 10428,
- MTYPE_CLIENT_TABLET_KILL_REQUEST = 10429,
- MTYPE_CLIENT_TABLET_STATE_REQUEST = 10430,
+ MTYPE_CLIENT_OLD_HIVE_CREATE_TABLET = 10421, // deprecated
+ MTYPE_CLIENT_HIVE_CREATE_TABLET_RESULT = 10422, // deprecated
+ MTYPE_CLIENT_OLD_LOCAL_ENUMERATE_TABLETS = 10423, // deprecated
+ MTYPE_CLIENT_LOCAL_ENUMERATE_TABLETS_RESULT = 10424, // deprecated
+ MTYPE_CLIENT_OLD_KEYVALUE = 10425, // deprecated
+ MTYPE_CLIENT_KEYVALUE_RESPONSE = 10426, // deprecated
+ MTYPE_CLIENT_MESSAGE_BUS_TRACE = 10427,
+ MTYPE_CLIENT_MESSAGE_BUS_TRACE_STATUS = 10428,
+ MTYPE_CLIENT_TABLET_KILL_REQUEST = 10429,
+ MTYPE_CLIENT_TABLET_STATE_REQUEST = 10430,
MTYPE_CLIENT_LOCAL_MINIKQL = 10431,
- MTYPE_CLIENT_FLAT_TX_REQUEST = 10432,
- MTYPE_CLIENT_FLAT_TX_STATUS_REQUEST = 10434,
- MTYPE_CLIENT_OLD_FLAT_DESCRIBE_REQUEST = 10435, // deprecated
+ MTYPE_CLIENT_FLAT_TX_REQUEST = 10432,
+ MTYPE_CLIENT_FLAT_TX_STATUS_REQUEST = 10434,
+ MTYPE_CLIENT_OLD_FLAT_DESCRIBE_REQUEST = 10435, // deprecated
MTYPE_CLIENT_OLD_FLAT_DESCRIBE_RESPONSE = 10436, // deprecated
MTYPE_CLIENT_CREATE_TABLET = 10437,
MTYPE_CLIENT_LOAD_REQUEST = 10438,
MTYPE_CLIENT_LOAD_RESPONSE = 10439,
MTYPE_CLIENT_DIRECT_REQUEST_JOB_EXECUTION_STATUS = 10440, // deprecated
MTYPE_CLIENT_PERSQUEUE = 10441,
- MTYPE_CLIENT_DB_SCHEMA = 10443,
- MTYPE_CLIENT_DB_OPERATION = 10444,
- MTYPE_CLIENT_DB_RESPONSE = 10445,
- MTYPE_CLIENT_HIVE_CREATE_TABLET = 10446,
- MTYPE_CLIENT_LOCAL_ENUMERATE_TABLETS = 10447,
- MTYPE_CLIENT_KEYVALUE = 10448,
- MTYPE_CLIENT_DB_BATCH = 10449,
- MTYPE_CLIENT_FLAT_DESCRIBE_REQUEST = 10450,
+ MTYPE_CLIENT_DB_SCHEMA = 10443,
+ MTYPE_CLIENT_DB_OPERATION = 10444,
+ MTYPE_CLIENT_DB_RESPONSE = 10445,
+ MTYPE_CLIENT_HIVE_CREATE_TABLET = 10446,
+ MTYPE_CLIENT_LOCAL_ENUMERATE_TABLETS = 10447,
+ MTYPE_CLIENT_KEYVALUE = 10448,
+ MTYPE_CLIENT_DB_BATCH = 10449,
+ MTYPE_CLIENT_FLAT_DESCRIBE_REQUEST = 10450,
MTYPE_CLIENT_LOCAL_SCHEME_TX = 10453,
MTYPE_CLIENT_GET_REQUEST = 10454,
MTYPE_CLIENT_GET_RESPONSE = 10455,
- MTYPE_CLIENT_DB_QUERY = 10456,
+ MTYPE_CLIENT_DB_QUERY = 10456,
MTYPE_CLIENT_TABLET_COUNTERS_REQUEST = 10457,
MTYPE_CLIENT_CANCEL_BACKUP = 10458,
MTYPE_CLIENT_BLOB_STORAGE_CONFIG_REQUEST = 10459,
- MTYPE_CLIENT_DRAIN_NODE = 10460,
- MTYPE_CLIENT_FILL_NODE = 10461,
- MTYPE_CLIENT_RESOLVE_NODE = 10462,
+ MTYPE_CLIENT_DRAIN_NODE = 10460,
+ MTYPE_CLIENT_FILL_NODE = 10461,
+ MTYPE_CLIENT_RESOLVE_NODE = 10462,
MTYPE_CLIENT_NODE_REGISTRATION_REQUEST = 10463,
MTYPE_CLIENT_NODE_REGISTRATION_RESPONSE = 10464,
MTYPE_CLIENT_CMS_REQUEST = 10465,
@@ -79,7 +79,7 @@ enum {
MTYPE_CLIENT_CHOOSE_PROXY = 10468,
MTYPE_CLIENT_SQS_REQUEST = 10469,
MTYPE_CLIENT_SQS_RESPONSE = 10470,
- MTYPE_CLIENT_WHOAMI = 10471,
+ MTYPE_CLIENT_WHOAMI = 10471,
MTYPE_CLIENT_STREAM_REQUEST = 10472,
MTYPE_CLIENT_S3_LISTING_REQUEST = 10474,
MTYPE_CLIENT_S3_LISTING_RESPONSE = 10475,
@@ -91,10 +91,10 @@ enum {
MTYPE_CLIENT_TEST_SHARD_CONTROL = 10481,
};
-template <typename InstanceType, class TBufferRecord, int MType>
-struct TBusMessage : NBus::TBusBufferMessage<TBufferRecord, MType> { NBus::TBusBufferBase* New() override { return new InstanceType; } };
+template <typename InstanceType, class TBufferRecord, int MType>
+struct TBusMessage : NBus::TBusBufferMessage<TBufferRecord, MType> { NBus::TBusBufferBase* New() override { return new InstanceType; } };
-// we had to define structs instead of typedef because we need to create real C++ type, so we could use RTTI names later in protocol registration
+// we had to define structs instead of typedef because we need to create real C++ type, so we could use RTTI names later in protocol registration
struct TBusRequest : TBusMessage<TBusRequest, NKikimrClient::TRequest, MTYPE_CLIENT_REQUEST> {};
struct TBusResponse : TBusMessage<TBusResponse, NKikimrClient::TResponse, MTYPE_CLIENT_RESPONSE> {};
struct TBusFakeConfigDummy : TBusMessage<TBusFakeConfigDummy, NKikimrClient::TFakeConfigDummy, MTYPE_CLIENT_FAKE_CONFIGDUMMY> {};
@@ -133,9 +133,9 @@ struct TBusDbOperation : TBusMessage<TBusDbOperation, NKikimrClient::TJSON, MTYP
struct TBusDbResponse : TBusMessage<TBusDbResponse, NKikimrClient::TJSON, MTYPE_CLIENT_DB_RESPONSE> {};
struct TBusDbBatch : TBusMessage<TBusDbBatch, NKikimrClient::TJSON, MTYPE_CLIENT_DB_BATCH> {};
struct TBusBlobStorageConfigRequest : TBusMessage<TBusBlobStorageConfigRequest, NKikimrClient::TBlobStorageConfigRequest, MTYPE_CLIENT_BLOB_STORAGE_CONFIG_REQUEST> {};
-struct TBusDrainNode : TBusMessage<TBusDrainNode, NKikimrClient::TDrainNodeRequest, MTYPE_CLIENT_DRAIN_NODE> {};
-struct TBusFillNode : TBusMessage<TBusFillNode, NKikimrClient::TFillNodeRequest, MTYPE_CLIENT_FILL_NODE> {};
-struct TBusResolveNode : TBusMessage<TBusResolveNode, NKikimrClient::TResolveNodeRequest, MTYPE_CLIENT_RESOLVE_NODE> {};
+struct TBusDrainNode : TBusMessage<TBusDrainNode, NKikimrClient::TDrainNodeRequest, MTYPE_CLIENT_DRAIN_NODE> {};
+struct TBusFillNode : TBusMessage<TBusFillNode, NKikimrClient::TFillNodeRequest, MTYPE_CLIENT_FILL_NODE> {};
+struct TBusResolveNode : TBusMessage<TBusResolveNode, NKikimrClient::TResolveNodeRequest, MTYPE_CLIENT_RESOLVE_NODE> {};
struct TBusNodeRegistrationRequest : TBusMessage<TBusNodeRegistrationRequest, NKikimrClient::TNodeRegistrationRequest, MTYPE_CLIENT_NODE_REGISTRATION_REQUEST> {};
struct TBusNodeRegistrationResponse : TBusMessage<TBusNodeRegistrationResponse, NKikimrClient::TNodeRegistrationResponse, MTYPE_CLIENT_NODE_REGISTRATION_RESPONSE> {};
struct TBusCmsRequest : TBusMessage<TBusCmsRequest, NKikimrClient::TCmsRequest, MTYPE_CLIENT_CMS_REQUEST> {};
@@ -143,7 +143,7 @@ struct TBusCmsResponse : TBusMessage<TBusCmsResponse, NKikimrClient::TCmsRespons
struct TBusChooseProxy : TBusMessage<TBusChooseProxy, NKikimrClient::TChooseProxyRequest, MTYPE_CLIENT_CHOOSE_PROXY> {};
struct TBusSqsRequest : TBusMessage<TBusSqsRequest, NKikimrClient::TSqsRequest, MTYPE_CLIENT_SQS_REQUEST> {};
struct TBusSqsResponse : TBusMessage<TBusSqsResponse, NKikimrClient::TSqsResponse, MTYPE_CLIENT_SQS_RESPONSE> {};
-struct TBusWhoAmI : TBusMessage<TBusWhoAmI, NKikimrClient::TWhoAmI, MTYPE_CLIENT_WHOAMI> {};
+struct TBusWhoAmI : TBusMessage<TBusWhoAmI, NKikimrClient::TWhoAmI, MTYPE_CLIENT_WHOAMI> {};
struct TBusStreamRequest : TBusMessage<TBusStreamRequest, NKikimrClient::TRequest, MTYPE_CLIENT_STREAM_REQUEST> {};
struct TBusS3ListingRequest : TBusMessage<TBusS3ListingRequest, NKikimrClient::TS3ListingRequest, MTYPE_CLIENT_S3_LISTING_REQUEST> {};
struct TBusS3ListingResponse : TBusMessage<TBusS3ListingResponse, NKikimrClient::TS3ListingResponse, MTYPE_CLIENT_S3_LISTING_RESPONSE> {};
@@ -151,44 +151,44 @@ struct TBusInterconnectDebug : TBusMessage<TBusInterconnectDebug, NKikimrClient:
struct TBusConsoleRequest : TBusMessage<TBusConsoleRequest, NKikimrClient::TConsoleRequest, MTYPE_CLIENT_CONSOLE_REQUEST> {};
struct TBusConsoleResponse : TBusMessage<TBusConsoleResponse, NKikimrClient::TConsoleResponse, MTYPE_CLIENT_CONSOLE_RESPONSE> {};
struct TBusTestShardControlRequest : TBusMessage<TBusTestShardControlRequest, NKikimrClient::TTestShardControlRequest, MTYPE_CLIENT_TEST_SHARD_CONTROL> {};
-
+
class TBusResponseStatus : public TBusResponse {
public:
TBusResponseStatus(EResponseStatus status, const TString& text = TString())
{
Record.SetStatus(status);
if (text) {
- Record.SetErrorReason(text);
+ Record.SetErrorReason(text);
}
}
};
class TProtocol : public NBus::TBusBufferProtocol {
-protected:
+protected:
THashMap<TString, NBus::TBusBufferBase*> NameToType;
-
+
public:
static TString TrimMessageName(const TString& name) {
- std::size_t pos = name.rfind(':');
+ std::size_t pos = name.rfind(':');
if (pos != TString::npos && pos + 5 <= name.size() && name.substr(pos + 1, 4) == "TBus")
- return name.substr(pos + 5); // removing leading 'TBus' letters
- return name;
- }
-
- template <typename BusMessageType>
- void RegisterType(BusMessageType* message) {
- NameToType[TrimMessageName(TypeName<BusMessageType>())] = message;
- NBus::TBusBufferProtocol::RegisterType(message);
- }
-
+ return name.substr(pos + 5); // removing leading 'TBus' letters
+ return name;
+ }
+
+ template <typename BusMessageType>
+ void RegisterType(BusMessageType* message) {
+ NameToType[TrimMessageName(TypeName<BusMessageType>())] = message;
+ NBus::TBusBufferProtocol::RegisterType(message);
+ }
+
TAutoPtr<NBus::TBusBufferBase> NewMessage(const TString& name) const {
- auto it = NameToType.find(name);
- if (it != NameToType.end()) {
- return it->second->New();
- }
- return nullptr;
- }
-
+ auto it = NameToType.find(name);
+ if (it != NameToType.end()) {
+ return it->second->New();
+ }
+ return nullptr;
+ }
+
TProtocol(int port)
: NBus::TBusBufferProtocol("CLI_MB", port)
{
@@ -199,46 +199,46 @@ public:
RegisterType(new TBusBSAdm);
RegisterType(new TBusTypesRequest);
RegisterType(new TBusTypesResponse);
- RegisterType(new TBusMessageBusTraceRequest);
- RegisterType(new TBusMessageBusTraceStatus);
+ RegisterType(new TBusMessageBusTraceRequest);
+ RegisterType(new TBusMessageBusTraceStatus);
RegisterType(new TBusHiveCreateTablet);
- RegisterType(new TBusOldHiveCreateTablet);
+ RegisterType(new TBusOldHiveCreateTablet);
RegisterType(new TBusHiveCreateTabletResult);
RegisterType(new TBusLocalEnumerateTablets);
- RegisterType(new TBusOldLocalEnumerateTablets);
+ RegisterType(new TBusOldLocalEnumerateTablets);
RegisterType(new TBusLocalEnumerateTabletsResult);
RegisterType(new TBusKeyValue);
- RegisterType(new TBusOldKeyValue);
+ RegisterType(new TBusOldKeyValue);
RegisterType(new TBusKeyValueResponse);
RegisterType(new TBusPersQueue);
- RegisterType(new TBusTabletKillRequest);
- RegisterType(new TBusTabletStateRequest);
+ RegisterType(new TBusTabletKillRequest);
+ RegisterType(new TBusTabletStateRequest);
RegisterType(new TBusTabletCountersRequest);
RegisterType(new TBusTabletLocalMKQL);
RegisterType(new TBusTabletLocalSchemeTx);
RegisterType(new TBusSchemeOperation);
RegisterType(new TBusSchemeOperationStatus);
RegisterType(new TBusSchemeDescribe);
- RegisterType(new TBusOldFlatDescribeRequest);
+ RegisterType(new TBusOldFlatDescribeRequest);
RegisterType(new TBusOldFlatDescribeResponse);
RegisterType(new TBusBsTestLoadRequest);
RegisterType(new TBusBsTestLoadResponse);
RegisterType(new TBusBsGetRequest);
RegisterType(new TBusBsGetResponse);
- RegisterType(new TBusDbSchema);
- RegisterType(new TBusDbOperation);
- RegisterType(new TBusDbResponse);
- RegisterType(new TBusDbBatch);
+ RegisterType(new TBusDbSchema);
+ RegisterType(new TBusDbOperation);
+ RegisterType(new TBusDbResponse);
+ RegisterType(new TBusDbBatch);
RegisterType(new TBusBlobStorageConfigRequest);
- RegisterType(new TBusDrainNode);
- RegisterType(new TBusFillNode);
- RegisterType(new TBusResolveNode);
+ RegisterType(new TBusDrainNode);
+ RegisterType(new TBusFillNode);
+ RegisterType(new TBusResolveNode);
RegisterType(new TBusNodeRegistrationRequest);
RegisterType(new TBusNodeRegistrationResponse);
RegisterType(new TBusCmsRequest);
RegisterType(new TBusCmsResponse);
RegisterType(new TBusChooseProxy);
- RegisterType(new TBusWhoAmI);
+ RegisterType(new TBusWhoAmI);
RegisterType(new TBusStreamRequest);
RegisterType(new TBusS3ListingRequest);
RegisterType(new TBusS3ListingResponse);
@@ -248,7 +248,7 @@ public:
RegisterType(new TBusTestShardControlRequest);
}
- const static ui32 DefaultPort = 2134;
+ const static ui32 DefaultPort = 2134;
};
class IMessageBusServer {
diff --git a/ydb/public/lib/deprecated/client/grpc_client.cpp b/ydb/public/lib/deprecated/client/grpc_client.cpp
index 984f3cb58d1..dbf808ef752 100644
--- a/ydb/public/lib/deprecated/client/grpc_client.cpp
+++ b/ydb/public/lib/deprecated/client/grpc_client.cpp
@@ -296,17 +296,17 @@ namespace NKikimr {
};
TGRpcClient::TGRpcClient(const TGRpcClientConfig& config)
- : Config(config)
- , Impl(new TImpl(Config))
+ : Config(config)
+ , Impl(new TImpl(Config))
{}
TGRpcClient::~TGRpcClient()
{}
- const TGRpcClientConfig& TGRpcClient::GetConfig() const {
- return Config;
- }
-
+ const TGRpcClientConfig& TGRpcClient::GetConfig() const {
+ return Config;
+ }
+
grpc_connectivity_state TGRpcClient::GetNetworkStatus() const {
return Impl->GetNetworkStatus();
}
@@ -342,11 +342,11 @@ namespace NKikimr {
IMPL_REQUEST(DbSchema, TJSON, TJSON)
IMPL_REQUEST(DbOperation, TJSON, TJSON)
IMPL_REQUEST(DbBatch, TJSON, TJSON)
- IMPL_REQUEST(ChooseProxy, TChooseProxyRequest, TResponse)
+ IMPL_REQUEST(ChooseProxy, TChooseProxyRequest, TResponse)
IMPL_REQUEST(ConsoleRequest, TConsoleRequest, TConsoleResponse)
- IMPL_REQUEST(WhoAmI, TWhoAmI, TResponse)
- IMPL_REQUEST(FillNode, TFillNodeRequest, TResponse)
- IMPL_REQUEST(DrainNode, TDrainNodeRequest, TResponse)
+ IMPL_REQUEST(WhoAmI, TWhoAmI, TResponse)
+ IMPL_REQUEST(FillNode, TFillNodeRequest, TResponse)
+ IMPL_REQUEST(DrainNode, TDrainNodeRequest, TResponse)
} // NGRpcProxy
} // NKikimr
diff --git a/ydb/public/lib/deprecated/client/grpc_client.h b/ydb/public/lib/deprecated/client/grpc_client.h
index eefc3c907d4..b0483a2646f 100644
--- a/ydb/public/lib/deprecated/client/grpc_client.h
+++ b/ydb/public/lib/deprecated/client/grpc_client.h
@@ -29,20 +29,20 @@ namespace NKikimr {
using TFinishCallback = std::function<void (const TGrpcError*)>;
class TGRpcClient {
- TGRpcClientConfig Config;
+ TGRpcClientConfig Config;
class TImpl;
THolder<TImpl> Impl;
public:
TGRpcClient(const TGRpcClientConfig& config);
~TGRpcClient();
- const TGRpcClientConfig& GetConfig() const;
+ const TGRpcClientConfig& GetConfig() const;
grpc_connectivity_state GetNetworkStatus() const;
// MiniKQL request, TResponseCallback callback (const NKikimrClient::DML& request)
void Request(const NKikimrClient::TRequest& request, TResponseCallback callback);
- // ChooseProxy request
- void ChooseProxy(const NKikimrClient::TChooseProxyRequest& request, TResponseCallback callback);
+ // ChooseProxy request
+ void ChooseProxy(const NKikimrClient::TChooseProxyRequest& request, TResponseCallback callback);
// Stream request
void StreamRequest(const NKikimrClient::TRequest& request, TSimpleCallback<NKikimrClient::TResponse> process, TFinishCallback finish);
@@ -125,10 +125,10 @@ namespace NKikimr {
void DbSchema(const NKikimrClient::TJSON& request, TJSONCallback callback);
void DbOperation(const NKikimrClient::TJSON& request, TJSONCallback callback);
void DbBatch(const NKikimrClient::TJSON& request, TJSONCallback callback);
-
- void WhoAmI(const NKikimrClient::TWhoAmI& request, TResponseCallback callback);
- void FillNode(const NKikimrClient::TFillNodeRequest& request, TResponseCallback callback);
- void DrainNode(const NKikimrClient::TDrainNodeRequest& request, TResponseCallback callback);
+
+ void WhoAmI(const NKikimrClient::TWhoAmI& request, TResponseCallback callback);
+ void FillNode(const NKikimrClient::TFillNodeRequest& request, TResponseCallback callback);
+ void DrainNode(const NKikimrClient::TDrainNodeRequest& request, TResponseCallback callback);
};
} // NGRpcProxy
diff --git a/ydb/public/lib/deprecated/client/msgbus_client.cpp b/ydb/public/lib/deprecated/client/msgbus_client.cpp
index e59587077f3..4d5f2427ebd 100644
--- a/ydb/public/lib/deprecated/client/msgbus_client.cpp
+++ b/ydb/public/lib/deprecated/client/msgbus_client.cpp
@@ -5,34 +5,34 @@ namespace NKikimr {
namespace NMsgBusProxy {
void TMsgBusClientConfig::CrackAddress(const TString& address, TString& hostname, ui32& port) {
- size_t first_colon_pos = address.find(':');
+ size_t first_colon_pos = address.find(':');
if (first_colon_pos != TString::npos) {
- size_t last_colon_pos = address.rfind(':');
- if (last_colon_pos == first_colon_pos) {
- // only one colon, simple case
- port = FromString<ui32>(address.substr(first_colon_pos + 1));
- hostname = address.substr(0, first_colon_pos);
- } else {
- // ipv6?
- size_t closing_bracket_pos = address.rfind(']');
+ size_t last_colon_pos = address.rfind(':');
+ if (last_colon_pos == first_colon_pos) {
+ // only one colon, simple case
+ port = FromString<ui32>(address.substr(first_colon_pos + 1));
+ hostname = address.substr(0, first_colon_pos);
+ } else {
+ // ipv6?
+ size_t closing_bracket_pos = address.rfind(']');
if (closing_bracket_pos == TString::npos || closing_bracket_pos > last_colon_pos) {
- // whole address is ipv6 host
- hostname = address;
- } else {
- port = FromString<ui32>(address.substr(last_colon_pos + 1));
- hostname = address.substr(0, last_colon_pos);
- }
+ // whole address is ipv6 host
+ hostname = address;
+ } else {
+ port = FromString<ui32>(address.substr(last_colon_pos + 1));
+ hostname = address.substr(0, last_colon_pos);
+ }
if (hostname.StartsWith('[') && hostname.EndsWith(']')) {
- hostname = hostname.substr(1, hostname.size() - 2);
- }
- }
- } else {
- hostname = address;
- }
-}
-
-
-
+ hostname = hostname.substr(1, hostname.size() - 2);
+ }
+ }
+ } else {
+ hostname = address;
+ }
+}
+
+
+
struct TMessageCookie
{
virtual void Signal(TAutoPtr<NBus::TBusMessage>& msg, NBus::EMessageStatus errorStatus, TAutoPtr<NBus::TBusMessage> reply) = 0;
@@ -63,43 +63,43 @@ struct TSyncMessageCookie : public TMessageCookie {
};
-template <typename CallbackType>
+template <typename CallbackType>
struct TAsyncMessageCookie : public TMessageCookie {
- CallbackType Callback;
- void* Data;
+ CallbackType Callback;
+ void* Data;
- explicit TAsyncMessageCookie(CallbackType callback, void* data)
+ explicit TAsyncMessageCookie(CallbackType callback, void* data)
: Callback(callback)
- , Data(data)
+ , Data(data)
{}
- void Signal(TAutoPtr<NBus::TBusMessage>& msg, NBus::EMessageStatus errorStatus, TAutoPtr<NBus::TBusMessage> reply) override;
+ void Signal(TAutoPtr<NBus::TBusMessage>& msg, NBus::EMessageStatus errorStatus, TAutoPtr<NBus::TBusMessage> reply) override;
};
-template <>
-void TAsyncMessageCookie<TMsgBusClient::TOnCall>::Signal(TAutoPtr<NBus::TBusMessage>& msg, NBus::EMessageStatus errorStatus, TAutoPtr<NBus::TBusMessage> reply) {
- msg->Data = Data;
- Callback(errorStatus, reply);
- delete this; // we must cleanup cookie after use
-}
-
-template <>
-void TAsyncMessageCookie<TMsgBusClient::TOnCallWithRequest>::Signal(TAutoPtr<NBus::TBusMessage>& msg, NBus::EMessageStatus errorStatus, TAutoPtr<NBus::TBusMessage> reply) {
- msg->Data = Data;
- Callback(errorStatus, msg, reply);
- delete this; // we must cleanup cookie after use
-}
-
-
+template <>
+void TAsyncMessageCookie<TMsgBusClient::TOnCall>::Signal(TAutoPtr<NBus::TBusMessage>& msg, NBus::EMessageStatus errorStatus, TAutoPtr<NBus::TBusMessage> reply) {
+ msg->Data = Data;
+ Callback(errorStatus, reply);
+ delete this; // we must cleanup cookie after use
+}
+
+template <>
+void TAsyncMessageCookie<TMsgBusClient::TOnCallWithRequest>::Signal(TAutoPtr<NBus::TBusMessage>& msg, NBus::EMessageStatus errorStatus, TAutoPtr<NBus::TBusMessage> reply) {
+ msg->Data = Data;
+ Callback(errorStatus, msg, reply);
+ delete this; // we must cleanup cookie after use
+}
+
+
TMsgBusClientConfig::TMsgBusClientConfig()
: Ip("localhost")
, Port(NMsgBusProxy::TProtocol::DefaultPort)
, UseCompression(false)
-{}
+{}
void TMsgBusClientConfig::ConfigureLastGetopt(NLastGetopt::TOpts &opts, const TString& prefix) {
- BusSessionConfig.ConfigureLastGetopt(opts, prefix);
- BusQueueConfig.ConfigureLastGetopt(opts, prefix);
+ BusSessionConfig.ConfigureLastGetopt(opts, prefix);
+ BusQueueConfig.ConfigureLastGetopt(opts, prefix);
}
TMsgBusClient::TMsgBusClient(const TMsgBusClientConfig &config)
@@ -146,7 +146,7 @@ NBus::EMessageStatus TMsgBusClient::SyncCall(TAutoPtr<NBus::TBusMessage> msg, TA
}
NBus::EMessageStatus TMsgBusClient::AsyncCall(TAutoPtr<NBus::TBusMessage> msg, TOnCall callback) {
- TAutoPtr<TMessageCookie> cookie(new TAsyncMessageCookie<TOnCall>(callback, msg->Data));
+ TAutoPtr<TMessageCookie> cookie(new TAsyncMessageCookie<TOnCall>(callback, msg->Data));
msg->Data = cookie.Get();
if (Config.UseCompression) {
@@ -165,26 +165,26 @@ NBus::EMessageStatus TMsgBusClient::AsyncCall(TAutoPtr<NBus::TBusMessage> msg, T
return status;
}
-NBus::EMessageStatus TMsgBusClient::AsyncCall(TAutoPtr<NBus::TBusMessage> msg, TOnCallWithRequest callback) {
- TAutoPtr<TMessageCookie> cookie(new TAsyncMessageCookie<TOnCallWithRequest>(callback, msg->Data));
- msg->Data = cookie.Get();
+NBus::EMessageStatus TMsgBusClient::AsyncCall(TAutoPtr<NBus::TBusMessage> msg, TOnCallWithRequest callback) {
+ TAutoPtr<TMessageCookie> cookie(new TAsyncMessageCookie<TOnCallWithRequest>(callback, msg->Data));
+ msg->Data = cookie.Get();
if (Config.UseCompression) {
msg->SetCompressed(true);
msg->SetCompressedResponse(true);
}
- NBus::EMessageStatus status = Session->SendMessage(msg.Get(), NetAddr.Get(), false);
-
- if (status == NBus::MESSAGE_OK) {
- // would be destructed in onresult/onerror
+ NBus::EMessageStatus status = Session->SendMessage(msg.Get(), NetAddr.Get(), false);
+
+ if (status == NBus::MESSAGE_OK) {
+ // would be destructed in onresult/onerror
Y_UNUSED(cookie.Release());
Y_UNUSED(msg.Release());
- }
-
- return status;
-}
-
+ }
+
+ return status;
+}
+
void TMsgBusClient::OnResult(TAutoPtr<NBus::TBusMessage> pMessage, NBus::EMessageStatus status, TAutoPtr<NBus::TBusMessage> pReply) {
static_cast<TMessageCookie*>(pMessage->Data)->Signal(pMessage, status, pReply);
}
@@ -200,10 +200,10 @@ void TMsgBusClient::OnError(TAutoPtr<NBus::TBusMessage> pMessage, NBus::EMessage
OnResult(pMessage, status, TAutoPtr<NBus::TBusMessage>());
}
-const TMsgBusClientConfig& TMsgBusClient::GetConfig() {
- return Config;
-}
-
+const TMsgBusClientConfig& TMsgBusClient::GetConfig() {
+ return Config;
+}
+
EDataReqStatusExcerpt ExtractDataRequestStatus(const NKikimrClient::TResponse *record) {
if (!record)
return EDataReqStatusExcerpt::Unknown;
diff --git a/ydb/public/lib/deprecated/client/msgbus_client.h b/ydb/public/lib/deprecated/client/msgbus_client.h
index 004de1ece68..7d721946d8d 100644
--- a/ydb/public/lib/deprecated/client/msgbus_client.h
+++ b/ydb/public/lib/deprecated/client/msgbus_client.h
@@ -25,19 +25,19 @@ private:
public:
typedef std::function<void (NBus::EMessageStatus status, TAutoPtr<NBus::TBusMessage> reply)> TOnCall;
- typedef std::function<void (NBus::EMessageStatus status,
- TAutoPtr<NBus::TBusMessage> message,
- TAutoPtr<NBus::TBusMessage> reply)> TOnCallWithRequest;
+ typedef std::function<void (NBus::EMessageStatus status,
+ TAutoPtr<NBus::TBusMessage> message,
+ TAutoPtr<NBus::TBusMessage> reply)> TOnCallWithRequest;
TMsgBusClient(const TMsgBusClientConfig &config);
~TMsgBusClient();
NBus::EMessageStatus SyncCall(TAutoPtr<NBus::TBusMessage> msg, TAutoPtr<NBus::TBusMessage> &reply);
NBus::EMessageStatus AsyncCall(TAutoPtr<NBus::TBusMessage> msg, TOnCall callback);
- NBus::EMessageStatus AsyncCall(TAutoPtr<NBus::TBusMessage> msg, TOnCallWithRequest callback);
+ NBus::EMessageStatus AsyncCall(TAutoPtr<NBus::TBusMessage> msg, TOnCallWithRequest callback);
void Init();
void Shutdown();
- const TMsgBusClientConfig& GetConfig();
+ const TMsgBusClientConfig& GetConfig();
};
EDataReqStatusExcerpt ExtractDataRequestStatus(const NKikimrClient::TResponse *response);
diff --git a/ydb/public/lib/deprecated/client/msgbus_player.cpp b/ydb/public/lib/deprecated/client/msgbus_player.cpp
index 6d0ccb09c15..befa19f73a1 100644
--- a/ydb/public/lib/deprecated/client/msgbus_player.cpp
+++ b/ydb/public/lib/deprecated/client/msgbus_player.cpp
@@ -1,158 +1,158 @@
-#include "msgbus_player.h"
-#include <util/system/sem.h>
-#include <util/system/fstat.h>
-#include <util/stream/file.h>
-#include <util/random/random.h>
+#include "msgbus_player.h"
+#include <util/system/sem.h>
+#include <util/system/fstat.h>
+#include <util/stream/file.h>
+#include <util/random/random.h>
#include <util/string/printf.h>
-#include <util/system/condvar.h>
-
-namespace NKikimr {
-namespace NMessageBusTracer {
-
-class TDarwinFastSemaphore : public TSemaphore {
-public:
- TDarwinFastSemaphore(ui32 maxCount)
- : TSemaphore(GenerateUniqueName().c_str(), maxCount)
- {}
-
-protected:
+#include <util/system/condvar.h>
+
+namespace NKikimr {
+namespace NMessageBusTracer {
+
+class TDarwinFastSemaphore : public TSemaphore {
+public:
+ TDarwinFastSemaphore(ui32 maxCount)
+ : TSemaphore(GenerateUniqueName().c_str(), maxCount)
+ {}
+
+protected:
static TString GenerateUniqueName() {
- ui64 number = TInstant::Now().MicroSeconds();
- return Sprintf("darwin-sem-%" PRIu64, number);
- }
-};
-
-#if defined(_darwin_)
-typedef TDarwinFastSemaphore TUniversalFastSemaphore;
-#else
-typedef TFastSemaphore TUniversalFastSemaphore;
-#endif
-
-class TAutoSemaphore : public TUniversalFastSemaphore {
-protected:
- ui32 MaxCount;
-public:
- TAutoSemaphore(ui32 count) : TUniversalFastSemaphore(count), MaxCount(count) {}
- ~TAutoSemaphore() {
- // waiting for async pending work to be done
- for( ui32 i = 0; i < MaxCount; ++i)
- Acquire();
- }
-};
-
-template <typename TType> class TInFlightMonitor {
-public:
- TInFlightMonitor(ui32 maxInFlight)
- : MaxInFlight(maxInFlight)
- , ComputedMaxInFlight(0)
- {
+ ui64 number = TInstant::Now().MicroSeconds();
+ return Sprintf("darwin-sem-%" PRIu64, number);
+ }
+};
+
+#if defined(_darwin_)
+typedef TDarwinFastSemaphore TUniversalFastSemaphore;
+#else
+typedef TFastSemaphore TUniversalFastSemaphore;
+#endif
+
+class TAutoSemaphore : public TUniversalFastSemaphore {
+protected:
+ ui32 MaxCount;
+public:
+ TAutoSemaphore(ui32 count) : TUniversalFastSemaphore(count), MaxCount(count) {}
+ ~TAutoSemaphore() {
+ // waiting for async pending work to be done
+ for( ui32 i = 0; i < MaxCount; ++i)
+ Acquire();
+ }
+};
+
+template <typename TType> class TInFlightMonitor {
+public:
+ TInFlightMonitor(ui32 maxInFlight)
+ : MaxInFlight(maxInFlight)
+ , ComputedMaxInFlight(0)
+ {
Y_VERIFY(maxInFlight > 0);
- }
-
- void Start(TType item) {
- MaxInFlight.Acquire();
- auto guard = Guard(InFlightLock);
+ }
+
+ void Start(TType item) {
+ MaxInFlight.Acquire();
+ auto guard = Guard(InFlightLock);
Y_UNUSED(guard);
- InFlight.insert(item);
- ComputedMaxInFlight = std::max(ComputedMaxInFlight, static_cast<ui32>(InFlight.size()));
- }
-
- void Finish(TType item) {
- {
- auto guard = Guard(InFlightLock);
+ InFlight.insert(item);
+ ComputedMaxInFlight = std::max(ComputedMaxInFlight, static_cast<ui32>(InFlight.size()));
+ }
+
+ void Finish(TType item) {
+ {
+ auto guard = Guard(InFlightLock);
Y_UNUSED(guard);
- InFlight.erase(item);
- InFlightFinished.Signal();
- }
- MaxInFlight.Release();
- }
-
- bool WaitForFinish(TType item) {
- auto guard = Guard(InFlightLock);
+ InFlight.erase(item);
+ InFlightFinished.Signal();
+ }
+ MaxInFlight.Release();
+ }
+
+ bool WaitForFinish(TType item) {
+ auto guard = Guard(InFlightLock);
Y_UNUSED(guard);
- while(InFlight.count(item) != 0) {
- InFlightFinished.WaitI(InFlightLock);
- }
- return true;
- }
-
- ui32 GetComputedMaxInFlight() const {
- return ComputedMaxInFlight;
- }
-
-protected:
+ while(InFlight.count(item) != 0) {
+ InFlightFinished.WaitI(InFlightLock);
+ }
+ return true;
+ }
+
+ ui32 GetComputedMaxInFlight() const {
+ return ComputedMaxInFlight;
+ }
+
+protected:
THashSet<TType> InFlight;
- TMutex InFlightLock;
- TCondVar InFlightFinished;
- TAutoSemaphore MaxInFlight;
- ui32 ComputedMaxInFlight;
-};
-
-TMsgBusPlayer::TMsgBusPlayer(TMsgBusPlayer::TMsgBusClient &msgBusClient)
- : MsgBusClient(msgBusClient)
-{}
-
+ TMutex InFlightLock;
+ TCondVar InFlightFinished;
+ TAutoSemaphore MaxInFlight;
+ ui32 ComputedMaxInFlight;
+};
+
+TMsgBusPlayer::TMsgBusPlayer(TMsgBusPlayer::TMsgBusClient &msgBusClient)
+ : MsgBusClient(msgBusClient)
+{}
+
TString DumpMessageHeader(const NBus::TBusHeader& messageHeader) {
return Sprintf("Message Id=%lx,Time=%s,Size=%d,Type=%x", messageHeader.Id, TInstant::MicroSeconds(messageHeader.SendTime).ToString().c_str(), messageHeader.Size, messageHeader.Type);
-}
-
+}
+
ui32 TMsgBusPlayer::PlayTrace(const TString &traceFile, ui32 maxInFlight, std::function<void(int)> progressReporter) {
- using NBus::TBusKey;
+ using NBus::TBusKey;
TAutoPtr<IInputStream> stream = new TUnbufferedFileInput(traceFile);
- i64 fileLength = GetFileLength(traceFile);
- i64 filePos = 0;
- int lastPercent = -1;
- NMsgBusProxy::TProtocol protocol(NMsgBusProxy::TProtocol::DefaultPort);
- TInFlightMonitor<TBusKey> monitor(maxInFlight);
- TBuffer messageBuffer;
- for(;;) {
- TBusKey replyKey;
- size_t read = stream->Load(&replyKey, sizeof(replyKey));
- if (read != sizeof(replyKey)) {
- if (read != 0)
- ythrow yexception() << "Error reading message replay id";
- break; // looks like end of the file
- }
- filePos += read;
- messageBuffer.Resize(sizeof(NBus::TBusHeader));
- read = stream->Load(messageBuffer.Data(), sizeof(NBus::TBusHeader));
- if (read != sizeof(NBus::TBusHeader))
- ythrow yexception() << "Error reading message header";
- filePos += read;
+ i64 fileLength = GetFileLength(traceFile);
+ i64 filePos = 0;
+ int lastPercent = -1;
+ NMsgBusProxy::TProtocol protocol(NMsgBusProxy::TProtocol::DefaultPort);
+ TInFlightMonitor<TBusKey> monitor(maxInFlight);
+ TBuffer messageBuffer;
+ for(;;) {
+ TBusKey replyKey;
+ size_t read = stream->Load(&replyKey, sizeof(replyKey));
+ if (read != sizeof(replyKey)) {
+ if (read != 0)
+ ythrow yexception() << "Error reading message replay id";
+ break; // looks like end of the file
+ }
+ filePos += read;
+ messageBuffer.Resize(sizeof(NBus::TBusHeader));
+ read = stream->Load(messageBuffer.Data(), sizeof(NBus::TBusHeader));
+ if (read != sizeof(NBus::TBusHeader))
+ ythrow yexception() << "Error reading message header";
+ filePos += read;
NBus::TBusHeader messageHeader(::TArrayRef<char>(messageBuffer.Data(), messageBuffer.Size()));
- messageBuffer.Resize(messageHeader.Size - sizeof(NBus::TBusHeader));
- if (!messageBuffer.Empty()) {
- read = stream->Load(messageBuffer.Data(), messageBuffer.Size());
- if (read != messageBuffer.Size())
- ythrow yexception() << "Error reading message content";
- filePos += read;
- }
- if (replyKey == YBUS_KEYINVALID) {
+ messageBuffer.Resize(messageHeader.Size - sizeof(NBus::TBusHeader));
+ if (!messageBuffer.Empty()) {
+ read = stream->Load(messageBuffer.Data(), messageBuffer.Size());
+ if (read != messageBuffer.Size())
+ ythrow yexception() << "Error reading message content";
+ filePos += read;
+ }
+ if (replyKey == YBUS_KEYINVALID) {
TAutoPtr<NBus::TBusMessage> request = protocol.Deserialize(messageHeader.Type, ::TArrayRef<char>(messageBuffer.Data(), messageBuffer.Size()));
- if (request == nullptr)
- ythrow yexception() << "Error deserializing message (" << DumpMessageHeader(messageHeader) << ")";
- TBusKey requestKey = messageHeader.Id;
- monitor.Start(requestKey);
- NBus::EMessageStatus status = MsgBusClient.AsyncCall(request, [&,requestKey](NBus::EMessageStatus, TAutoPtr<NBus::TBusMessage>){ monitor.Finish(requestKey); });
- if (status != NBus::MESSAGE_OK) {
- monitor.Finish(requestKey);
- ythrow yexception() << NBus::MessageStatusDescription(status) << " (" << DumpMessageHeader(messageHeader) << ")";
- }
- } else {
- monitor.WaitForFinish(replyKey);
- }
- if (progressReporter) {
- int currentPercent = filePos * 100 / fileLength;
- if (currentPercent != lastPercent) {
- progressReporter(currentPercent);
- lastPercent = currentPercent;
- }
- }
- }
- return monitor.GetComputedMaxInFlight();
-}
-
-
-
-}
-}
+ if (request == nullptr)
+ ythrow yexception() << "Error deserializing message (" << DumpMessageHeader(messageHeader) << ")";
+ TBusKey requestKey = messageHeader.Id;
+ monitor.Start(requestKey);
+ NBus::EMessageStatus status = MsgBusClient.AsyncCall(request, [&,requestKey](NBus::EMessageStatus, TAutoPtr<NBus::TBusMessage>){ monitor.Finish(requestKey); });
+ if (status != NBus::MESSAGE_OK) {
+ monitor.Finish(requestKey);
+ ythrow yexception() << NBus::MessageStatusDescription(status) << " (" << DumpMessageHeader(messageHeader) << ")";
+ }
+ } else {
+ monitor.WaitForFinish(replyKey);
+ }
+ if (progressReporter) {
+ int currentPercent = filePos * 100 / fileLength;
+ if (currentPercent != lastPercent) {
+ progressReporter(currentPercent);
+ lastPercent = currentPercent;
+ }
+ }
+ }
+ return monitor.GetComputedMaxInFlight();
+}
+
+
+
+}
+}
diff --git a/ydb/public/lib/deprecated/client/msgbus_player.h b/ydb/public/lib/deprecated/client/msgbus_player.h
index 1870a190e7c..0126a4a3595 100644
--- a/ydb/public/lib/deprecated/client/msgbus_player.h
+++ b/ydb/public/lib/deprecated/client/msgbus_player.h
@@ -1,18 +1,18 @@
-#pragma once
-#include "msgbus_client.h"
-
-namespace NKikimr {
-namespace NMessageBusTracer {
-
-
-class TMsgBusPlayer {
-protected:
- using TMsgBusClient = NMsgBusProxy::TMsgBusClient;
- TMsgBusClient &MsgBusClient;
-public:
- TMsgBusPlayer(TMsgBusClient &msgBusClient);
+#pragma once
+#include "msgbus_client.h"
+
+namespace NKikimr {
+namespace NMessageBusTracer {
+
+
+class TMsgBusPlayer {
+protected:
+ using TMsgBusClient = NMsgBusProxy::TMsgBusClient;
+ TMsgBusClient &MsgBusClient;
+public:
+ TMsgBusPlayer(TMsgBusClient &msgBusClient);
ui32 PlayTrace(const TString &traceFile, ui32 maxInFlight = 1000, std::function<void(int)> progressReporter = std::function<void(int)>());
-};
-
-}
-}
+};
+
+}
+}
diff --git a/ydb/public/lib/deprecated/kicli/cpp_ut.cpp b/ydb/public/lib/deprecated/kicli/cpp_ut.cpp
index 8663bf3f49b..cb7dc3ed6d9 100644
--- a/ydb/public/lib/deprecated/kicli/cpp_ut.cpp
+++ b/ydb/public/lib/deprecated/kicli/cpp_ut.cpp
@@ -8,12 +8,12 @@
#include <util/string/subst.h>
#include <util/system/valgrind.h>
-#include "kicli.h"
-
-using namespace NKikimr;
-
+#include "kicli.h"
+
+using namespace NKikimr;
+
namespace {
-
+
Tests::TServer StartupKikimr(NMsgBusProxy::TMsgBusClientConfig& clientConfig,
const TAutoPtr<TLogBackend> logBackend = {})
{
@@ -28,7 +28,7 @@ Tests::TServer StartupKikimr(NMsgBusProxy::TMsgBusClientConfig& clientConfig,
clientConfig = Client.GetClientConfig();
return Server;
}
-
+
Tests::TServer StartupKikimr(NGRpcProxy::TGRpcClientConfig& clientConfig,
const TAutoPtr<TLogBackend> logBackend = {},
const NKikimrConfig::TAppConfig &config = {})
@@ -49,7 +49,7 @@ Tests::TServer StartupKikimr(NGRpcProxy::TGRpcClientConfig& clientConfig,
Tests::TClient Client(settings);
Client.InitRootScheme();
- clientConfig.Locator = "[::1]:" + ToString(grpcPort);
+ clientConfig.Locator = "[::1]:" + ToString(grpcPort);
return Server;
}
@@ -88,17 +88,17 @@ bool HasChild(const NKikimr::NClient::TSchemaObject& obj, const char * path) {
Y_UNIT_TEST_SUITE(ClientLibSchema) {
static void RootExists(NClient::TKikimr& kikimr) {
- auto root = kikimr.GetSchemaRoot();
- auto children = root.GetChildren();
- // all root elements exists regardless of whether they have been initialized or not
- //UNIT_ASSERT(children.empty());
- }
-
+ auto root = kikimr.GetSchemaRoot();
+ auto children = root.GetChildren();
+ // all root elements exists regardless of whether they have been initialized or not
+ //UNIT_ASSERT(children.empty());
+ }
+
Y_UNIT_TEST(RootExists) {
- NMsgBusProxy::TMsgBusClientConfig clientConfig;
- Tests::TServer server = StartupKikimr(clientConfig);
- NClient::TKikimr kikimr(clientConfig);
-
+ NMsgBusProxy::TMsgBusClientConfig clientConfig;
+ Tests::TServer server = StartupKikimr(clientConfig);
+ NClient::TKikimr kikimr(clientConfig);
+
RootExists(kikimr);
}
@@ -111,16 +111,16 @@ Y_UNIT_TEST_SUITE(ClientLibSchema) {
}
static void RootDcExists(NClient::TKikimr& kikimr) {
- auto root = kikimr.GetSchemaRoot();
- auto children = root.GetChildren();
- UNIT_ASSERT(std::find_if(children.begin(), children.end(), [](const NClient::TSchemaObject& s) -> bool { return s.GetPath() == "/dc-1"; }) != children.end());
- }
-
+ auto root = kikimr.GetSchemaRoot();
+ auto children = root.GetChildren();
+ UNIT_ASSERT(std::find_if(children.begin(), children.end(), [](const NClient::TSchemaObject& s) -> bool { return s.GetPath() == "/dc-1"; }) != children.end());
+ }
+
Y_UNIT_TEST(RootDcExists) {
- NMsgBusProxy::TMsgBusClientConfig clientConfig;
- Tests::TServer server = StartupKikimr(clientConfig);
- NClient::TKikimr kikimr(clientConfig);
-
+ NMsgBusProxy::TMsgBusClientConfig clientConfig;
+ Tests::TServer server = StartupKikimr(clientConfig);
+ NClient::TKikimr kikimr(clientConfig);
+
RootDcExists(kikimr);
}
@@ -133,19 +133,19 @@ Y_UNIT_TEST_SUITE(ClientLibSchema) {
}
static void RootDcStartsEmpty(NClient::TKikimr& kikimr) {
- auto root = kikimr.GetSchemaRoot();
- auto dc = kikimr.GetSchemaRoot("dc-1");
- UNIT_ASSERT(dc.GetPath() == "/dc-1");
- auto children = root.GetChildren();
- UNIT_ASSERT(std::find_if(children.begin(), children.end(), [](const NClient::TSchemaObject& s) -> bool { return s.GetPath() == "/dc-1"; }) != children.end());
- UNIT_ASSERT(dc.GetChildren().empty());
- }
-
+ auto root = kikimr.GetSchemaRoot();
+ auto dc = kikimr.GetSchemaRoot("dc-1");
+ UNIT_ASSERT(dc.GetPath() == "/dc-1");
+ auto children = root.GetChildren();
+ UNIT_ASSERT(std::find_if(children.begin(), children.end(), [](const NClient::TSchemaObject& s) -> bool { return s.GetPath() == "/dc-1"; }) != children.end());
+ UNIT_ASSERT(dc.GetChildren().empty());
+ }
+
Y_UNIT_TEST(RootDcStartsEmpty) {
- NMsgBusProxy::TMsgBusClientConfig clientConfig;
- Tests::TServer server = StartupKikimr(clientConfig);
- NClient::TKikimr kikimr(clientConfig);
-
+ NMsgBusProxy::TMsgBusClientConfig clientConfig;
+ Tests::TServer server = StartupKikimr(clientConfig);
+ NClient::TKikimr kikimr(clientConfig);
+
RootDcStartsEmpty(kikimr);
}
@@ -158,7 +158,7 @@ Y_UNIT_TEST_SUITE(ClientLibSchema) {
}
static void CreateTable(NClient::TKikimr& kikimr) {
- auto dc = kikimr.GetSchemaRoot("dc-1");
+ auto dc = kikimr.GetSchemaRoot("dc-1");
auto animals = dc.CreateTable("Animals", {
NClient::TKeyColumn("Id", NClient::TType::Uint64),
NClient::TColumn("Species", NClient::TType::Utf8),
@@ -167,7 +167,7 @@ Y_UNIT_TEST_SUITE(ClientLibSchema) {
NClient::TColumn("MiscY", NClient::TType::Yson),
NClient::TColumn("MiscJ", NClient::TType::Json)
});
- auto children = dc.GetChildren();
+ auto children = dc.GetChildren();
UNIT_ASSERT(HasChild(dc, "/dc-1/Animals"));
UNIT_ASSERT(animals.IsTable());
@@ -204,13 +204,13 @@ Y_UNIT_TEST_SUITE(ClientLibSchema) {
NClient::TColumn("Species", NClient::TType::Utf8)
});
#endif
- }
-
+ }
+
Y_UNIT_TEST(CreateTable) {
- NMsgBusProxy::TMsgBusClientConfig clientConfig;
- Tests::TServer server = StartupKikimr(clientConfig);
- NClient::TKikimr kikimr(clientConfig);
-
+ NMsgBusProxy::TMsgBusClientConfig clientConfig;
+ Tests::TServer server = StartupKikimr(clientConfig);
+ NClient::TKikimr kikimr(clientConfig);
+
CreateTable(kikimr);
}
@@ -223,8 +223,8 @@ Y_UNIT_TEST_SUITE(ClientLibSchema) {
}
static void MkDir(NClient::TKikimr& kikimr) {
- auto dc = kikimr.GetSchemaRoot("dc-1");
- auto zoo = dc.MakeDirectory("Zoo");
+ auto dc = kikimr.GetSchemaRoot("dc-1");
+ auto zoo = dc.MakeDirectory("Zoo");
auto animals = zoo.CreateTable("Animals", {
NClient::TKeyColumn("Id", NClient::TType::Uint64),
NClient::TColumn("Name", NClient::TType::Utf8)
@@ -251,13 +251,13 @@ Y_UNIT_TEST_SUITE(ClientLibSchema) {
UNIT_FAIL("Unexpected CreateTable success");
} catch (const yexception& ) {
}
- }
-
+ }
+
Y_UNIT_TEST(MkDir) {
- NMsgBusProxy::TMsgBusClientConfig clientConfig;
- Tests::TServer server = StartupKikimr(clientConfig);
- NClient::TKikimr kikimr(clientConfig);
-
+ NMsgBusProxy::TMsgBusClientConfig clientConfig;
+ Tests::TServer server = StartupKikimr(clientConfig);
+ NClient::TKikimr kikimr(clientConfig);
+
MkDir(kikimr);
}
@@ -270,9 +270,9 @@ Y_UNIT_TEST_SUITE(ClientLibSchema) {
}
static void CreatePartitionedTable(NClient::TKikimr& kikimr) {
- auto dc = kikimr.GetSchemaRoot("dc-1");
- auto zoo = dc.MakeDirectory("Zoo");
- auto animals = zoo.CreateTable("Animals", {
+ auto dc = kikimr.GetSchemaRoot("dc-1");
+ auto zoo = dc.MakeDirectory("Zoo");
+ auto animals = zoo.CreateTable("Animals", {
NClient::TKeyPartitioningColumn("Id", NClient::TType::Uint64, 4),
NClient::TColumn("Species", NClient::TType::Utf8),
NClient::TColumn("Name", NClient::TType::Utf8),
@@ -280,7 +280,7 @@ Y_UNIT_TEST_SUITE(ClientLibSchema) {
});
UNIT_ASSERT(zoo.IsDirectory());
UNIT_ASSERT(animals.IsTable());
-
+
UNIT_ASSERT_VALUES_EQUAL(zoo.GetChild("Animals").GetStats().PartitionsCount, 4);
}
@@ -430,156 +430,156 @@ Y_UNIT_TEST_SUITE(ClientLib) {
TTestEnvironment env;
NClient::TKikimr& kikimr = env.Kikimr;
- auto query = kikimr.Query(
- "("
- "(let row '('('Id (Uint64 '1))))"
- "(let myUpd '("
+ auto query = kikimr.Query(
+ "("
+ "(let row '('('Id (Uint64 '1))))"
+ "(let myUpd '("
" '('Species (Utf8 '\"Rat\"))"
" '('Name (Utf8 '\"Dobby\"))"
- " '('Weight (Int64 '350))))"
- "(let pgmReturn (AsList"
- " (UpdateRow '/dc-1/Zoo/Animals row myUpd)"
- "))"
- "(return pgmReturn)"
- ")");
- auto result = query.SyncPrepare().GetQuery().SyncExecute();
- auto value = result.GetValue();
- UNIT_ASSERT(value.IsNull());
- }
-
+ " '('Weight (Int64 '350))))"
+ "(let pgmReturn (AsList"
+ " (UpdateRow '/dc-1/Zoo/Animals row myUpd)"
+ "))"
+ "(return pgmReturn)"
+ ")");
+ auto result = query.SyncPrepare().GetQuery().SyncExecute();
+ auto value = result.GetValue();
+ UNIT_ASSERT(value.IsNull());
+ }
+
Y_UNIT_TEST(Test7) {
TTestEnvironment env;
NClient::TKikimr& kikimr = env.Kikimr;
-
- {
- auto query = kikimr.Query(
- "("
- "(let row '('('Id (Uint64 '1))))"
- "(let myUpd '("
+
+ {
+ auto query = kikimr.Query(
+ "("
+ "(let row '('('Id (Uint64 '1))))"
+ "(let myUpd '("
" '('Species (Utf8 '\"Rat\"))"
" '('Name (Utf8 '\"Dobby\"))"
- " '('Weight (Int64 '350))))"
- "(let pgmReturn (AsList"
- " (UpdateRow '/dc-1/Zoo/Animals row myUpd)"
- "))"
- "(return pgmReturn)"
- ")");
- auto result = query.SyncPrepare().GetQuery().SyncExecute();
- }
-
- {
- auto query = kikimr.Query(
- "("
- "(let row '('('Id (Uint64 '1))))"
- "(let select '('Species 'Name 'Weight))"
- "(let pgmReturn (AsList"
- " (SetResult 'myRes (SelectRow '/dc-1/Zoo/Animals row select))"
- "))"
- "(return pgmReturn)"
- ")");
- auto result = query.SyncExecute();
- auto value = result.GetValue();
- UNIT_ASSERT(!value["myRes"].IsNull());
+ " '('Weight (Int64 '350))))"
+ "(let pgmReturn (AsList"
+ " (UpdateRow '/dc-1/Zoo/Animals row myUpd)"
+ "))"
+ "(return pgmReturn)"
+ ")");
+ auto result = query.SyncPrepare().GetQuery().SyncExecute();
+ }
+
+ {
+ auto query = kikimr.Query(
+ "("
+ "(let row '('('Id (Uint64 '1))))"
+ "(let select '('Species 'Name 'Weight))"
+ "(let pgmReturn (AsList"
+ " (SetResult 'myRes (SelectRow '/dc-1/Zoo/Animals row select))"
+ "))"
+ "(return pgmReturn)"
+ ")");
+ auto result = query.SyncExecute();
+ auto value = result.GetValue();
+ UNIT_ASSERT(!value["myRes"].IsNull());
UNIT_ASSERT_VALUES_EQUAL((TString)value["myRes"]["Species"], "Rat");
UNIT_ASSERT_VALUES_EQUAL((TString)value["myRes"]["Name"], "Dobby");
- }
- }
-
+ }
+ }
+
Y_UNIT_TEST(Test8) {
TTestEnvironment env;
NClient::TKikimr& kikimr = env.Kikimr;
-
- {
- auto query = kikimr.Query(
- "("
- "(let row '('('Id (Uint64 '1))))"
- "(let myUpd '("
+
+ {
+ auto query = kikimr.Query(
+ "("
+ "(let row '('('Id (Uint64 '1))))"
+ "(let myUpd '("
" '('Species (Utf8 '\"Rat\"))"
" '('Name (Utf8 '\"Dobby\"))"
- " '('Weight (Int64 '350))))"
- "(let pgmReturn (AsList"
- " (UpdateRow '/dc-1/Zoo/Animals row myUpd)"
- "))"
- "(return pgmReturn)"
- ")");
- auto result = query.AsyncPrepare().GetValue(TDuration::Max()).GetQuery().AsyncExecute().GetValue(TDuration::Max());
- }
-
- {
- auto query = kikimr.Query(
- "("
- "(let row '('('Id (Uint64 '1))))"
- "(let select '('Species 'Name 'Weight))"
- "(let pgmReturn (AsList"
- " (SetResult 'myRes (SelectRow '/dc-1/Zoo/Animals row select))"
- "))"
- "(return pgmReturn)"
- ")");
- auto result = query.AsyncPrepare().GetValue(TDuration::Max()).GetQuery().AsyncExecute().GetValue(TDuration::Max());
- auto value = result.GetValue();
- UNIT_ASSERT(!value["myRes"].IsNull());
+ " '('Weight (Int64 '350))))"
+ "(let pgmReturn (AsList"
+ " (UpdateRow '/dc-1/Zoo/Animals row myUpd)"
+ "))"
+ "(return pgmReturn)"
+ ")");
+ auto result = query.AsyncPrepare().GetValue(TDuration::Max()).GetQuery().AsyncExecute().GetValue(TDuration::Max());
+ }
+
+ {
+ auto query = kikimr.Query(
+ "("
+ "(let row '('('Id (Uint64 '1))))"
+ "(let select '('Species 'Name 'Weight))"
+ "(let pgmReturn (AsList"
+ " (SetResult 'myRes (SelectRow '/dc-1/Zoo/Animals row select))"
+ "))"
+ "(return pgmReturn)"
+ ")");
+ auto result = query.AsyncPrepare().GetValue(TDuration::Max()).GetQuery().AsyncExecute().GetValue(TDuration::Max());
+ auto value = result.GetValue();
+ UNIT_ASSERT(!value["myRes"].IsNull());
UNIT_ASSERT_VALUES_EQUAL((TString)value["myRes"]["Species"], "Rat");
UNIT_ASSERT_VALUES_EQUAL((TString)value["myRes"]["Name"], "Dobby");
- }
- }
-
+ }
+ }
+
Y_UNIT_TEST(Test9) {
TTestEnvironment env;
NClient::TKikimr& kikimr = env.Kikimr;
-
- {
- auto result = kikimr.Query(
- "("
- "(let row '('('Id (Uint64 '1))))"
- "(let myUpd '("
+
+ {
+ auto result = kikimr.Query(
+ "("
+ "(let row '('('Id (Uint64 '1))))"
+ "(let myUpd '("
" '('Species (Utf8 '\"Rat\"))"
" '('Name (Utf8 '\"Dobby\"))"
- " '('Weight (Int64 '350))))"
- "(let pgmReturn (AsList"
- " (UpdateRow '/dc-1/Zoo/Animals row myUpd)"
- "))"
- "(return pgmReturn)"
- ")").SyncPrepare().GetQuery().SyncExecute();
- }
-
- {
- auto result = kikimr.Query(
- "("
- "(let row '('('Id (Uint64 '2))))"
- "(let myUpd '("
+ " '('Weight (Int64 '350))))"
+ "(let pgmReturn (AsList"
+ " (UpdateRow '/dc-1/Zoo/Animals row myUpd)"
+ "))"
+ "(return pgmReturn)"
+ ")").SyncPrepare().GetQuery().SyncExecute();
+ }
+
+ {
+ auto result = kikimr.Query(
+ "("
+ "(let row '('('Id (Uint64 '2))))"
+ "(let myUpd '("
" '('Species (Utf8 '\"Rat\"))"
" '('Name (Utf8 '\"Korzhik\"))"
- " '('Weight (Int64 '500))))"
- "(let pgmReturn (AsList"
- " (UpdateRow '/dc-1/Zoo/Animals row myUpd)"
- "))"
- "(return pgmReturn)"
- ")").SyncPrepare().GetQuery().SyncExecute();
- }
-
- auto query = kikimr.Query(
- "("
- "(let range '('IncFrom '('Id (Uint64 '1) (Void))))"
- "(let select '('Species 'Name 'Weight))"
- "(let options '())"
- "(let pgmReturn (AsList"
- " (SetResult 'myRes (Member (SelectRange '/dc-1/Zoo/Animals range select options) 'List))"
- "))"
- "(return pgmReturn)"
- ")");
- auto result = query.SyncPrepare().GetQuery().SyncExecute();
+ " '('Weight (Int64 '500))))"
+ "(let pgmReturn (AsList"
+ " (UpdateRow '/dc-1/Zoo/Animals row myUpd)"
+ "))"
+ "(return pgmReturn)"
+ ")").SyncPrepare().GetQuery().SyncExecute();
+ }
+
+ auto query = kikimr.Query(
+ "("
+ "(let range '('IncFrom '('Id (Uint64 '1) (Void))))"
+ "(let select '('Species 'Name 'Weight))"
+ "(let options '())"
+ "(let pgmReturn (AsList"
+ " (SetResult 'myRes (Member (SelectRange '/dc-1/Zoo/Animals range select options) 'List))"
+ "))"
+ "(return pgmReturn)"
+ ")");
+ auto result = query.SyncPrepare().GetQuery().SyncExecute();
auto readResult = result.GetValue();
-
+
UNIT_ASSERT_VALUES_EQUAL((TString)readResult["myRes"][0]["Species"], "Rat");
UNIT_ASSERT_VALUES_EQUAL((TString)readResult["myRes"][0]["Name"], "Dobby");
UNIT_ASSERT_VALUES_EQUAL((i64)readResult["myRes"][0]["Weight"], 350);
UNIT_ASSERT_VALUES_EQUAL((TString)readResult["myRes"][1]["Species"], "Rat");
UNIT_ASSERT_VALUES_EQUAL((TString)readResult["myRes"][1]["Name"], "Korzhik");
UNIT_ASSERT_VALUES_EQUAL((i64)readResult["myRes"][1]["Weight"], 500);
- }
-
+ }
+
Y_UNIT_TEST(Test10) {
- using namespace NClient;
+ using namespace NClient;
TTestEnvironment env({
NClient::TKeyColumn("Id", NClient::TType::Uint64),
NClient::TColumn("Species", NClient::TType::Utf8),
@@ -588,59 +588,59 @@ Y_UNIT_TEST_SUITE(ClientLib) {
NClient::TColumn("Weight", NClient::TType::Int64)
});
NClient::TKikimr& kikimr = env.Kikimr;
-
- auto updateQuery = kikimr.Query(
- "("
+
+ auto updateQuery = kikimr.Query(
+ "("
"(let id (Parameter 'ID (DataType 'Uint64)))"
- "(let row '('('Id id)))"
+ "(let row '('('Id id)))"
"(let sp (Parameter 'SPECIES (DataType 'Utf8)))"
"(let nm (Parameter 'NAME (DataType 'Utf8)))"
"(let ds (Parameter 'DESCRIPTION (DataType 'Utf8)))"
"(let wt (Parameter 'WEIGHT (DataType 'Int64)))"
- "(let myUpd '("
- " '('Species sp)"
- " '('Name nm)"
- " '('Description ds)"
- " '('Weight wt)))"
- "(let pgmReturn (AsList"
- " (UpdateRow '/dc-1/Zoo/Animals row myUpd)"
- "))"
- "(return pgmReturn)"
- ")").SyncPrepare().GetQuery();
- auto selectQuery = kikimr.Query(
- "("
+ "(let myUpd '("
+ " '('Species sp)"
+ " '('Name nm)"
+ " '('Description ds)"
+ " '('Weight wt)))"
+ "(let pgmReturn (AsList"
+ " (UpdateRow '/dc-1/Zoo/Animals row myUpd)"
+ "))"
+ "(return pgmReturn)"
+ ")").SyncPrepare().GetQuery();
+ auto selectQuery = kikimr.Query(
+ "("
"(let il (Parameter 'ITEMSLIMIT (DataType 'Uint64)))"
"(let bl (Parameter 'BYTESLIMIT (DataType 'Uint64)))"
- "(let range '('IncFrom '('Id (Uint64 '1) (Void))))"
- "(let select '('Species 'Name 'Weight 'Description))"
+ "(let range '('IncFrom '('Id (Uint64 '1) (Void))))"
+ "(let select '('Species 'Name 'Weight 'Description))"
"(let options '('('ItemsLimit il) '('BytesLimit bl)))"
- "(let pgmReturn (AsList"
- " (SetResult 'myRes (Member (SelectRange '/dc-1/Zoo/Animals range select options) 'List))"
- "))"
- "(return pgmReturn)"
- ")").SyncPrepare().GetQuery();
-
- updateQuery.SyncExecute(
- TParameter("ID", (ui64)1),
- TParameter("SPECIES", "Rat"),
- TParameter("NAME", "Dobby"),
+ "(let pgmReturn (AsList"
+ " (SetResult 'myRes (Member (SelectRange '/dc-1/Zoo/Animals range select options) 'List))"
+ "))"
+ "(return pgmReturn)"
+ ")").SyncPrepare().GetQuery();
+
+ updateQuery.SyncExecute(
+ TParameter("ID", (ui64)1),
+ TParameter("SPECIES", "Rat"),
+ TParameter("NAME", "Dobby"),
TParameter("DESCRIPTION", "A test for \"double quotes\""),
- TParameter("WEIGHT", (i64)350)
- );
- updateQuery.SyncExecute(
- TParameter("ID", (ui64)2),
- TParameter("SPECIES", "Rat"),
- TParameter("NAME", "Korzhik"),
+ TParameter("WEIGHT", (i64)350)
+ );
+ updateQuery.SyncExecute(
+ TParameter("ID", (ui64)2),
+ TParameter("SPECIES", "Rat"),
+ TParameter("NAME", "Korzhik"),
TParameter("DESCRIPTION", "A test for 'single quotes'"),
- TParameter("WEIGHT", (i64)500)
- );
-
+ TParameter("WEIGHT", (i64)500)
+ );
+
auto result = selectQuery.SyncExecute(
TParameter("ITEMSLIMIT", (ui64)10),
TParameter("BYTESLIMIT", (ui64)10000)
);
- auto value = result.GetValue();
-
+ auto value = result.GetValue();
+
UNIT_ASSERT_VALUES_EQUAL(value["myRes"].Size(), 2);
UNIT_ASSERT_VALUES_EQUAL((TString)value["myRes"][0]["Species"], "Rat");
UNIT_ASSERT_VALUES_EQUAL((TString)value["myRes"][0]["Name"], "Dobby");
@@ -650,145 +650,145 @@ Y_UNIT_TEST_SUITE(ClientLib) {
UNIT_ASSERT_VALUES_EQUAL((TString)value["myRes"][1]["Name"], "Korzhik");
UNIT_ASSERT_VALUES_EQUAL((TString)value["myRes"][1]["Description"], "A test for 'single quotes'");
UNIT_ASSERT_VALUES_EQUAL((i64)value["myRes"][1]["Weight"], 500);
- }
-
+ }
+
Y_UNIT_TEST(Test11) {
- using namespace NClient;
+ using namespace NClient;
TTestEnvironment env;
NClient::TKikimr& kikimr = env.Kikimr;
-
- auto updateQuery = kikimr.Query(
- "("
+
+ auto updateQuery = kikimr.Query(
+ "("
"(let id (Parameter 'ID (DataType 'Uint64)))"
- "(let row '('('Id id)))"
+ "(let row '('('Id id)))"
"(let sp (Parameter 'SPECIES (DataType 'Utf8)))"
"(let nm (Parameter 'NAME (DataType 'Utf8)))"
"(let wt (Parameter 'WEIGHT (DataType 'Int64)))"
- "(let myUpd '("
- " '('Species sp)"
- " '('Name nm)"
- " '('Weight wt)))"
- "(let pgmReturn (AsList"
- " (UpdateRow '/dc-1/Zoo/Animals row myUpd)"
- "))"
- "(return pgmReturn)"
- ")").SyncPrepare().GetQuery();
- auto selectQuery = kikimr.Query(
- "("
- "(let range '('IncFrom '('Id (Uint64 '1) (Void))))"
- "(let select '('Species 'Name 'Weight))"
- "(let options '())"
- "(let pgmReturn (AsList"
- " (SetResult 'myRes (Member (SelectRange '/dc-1/Zoo/Animals range select options) 'List))"
- "))"
- "(return pgmReturn)"
- ")").SyncPrepare().GetQuery();
-
- updateQuery.SyncExecute(
- TParameter("ID", (ui64)1),
- TParameter("SPECIES", "Rat"),
- TParameter("NAME", "Dobby"),
- TParameter("WEIGHT", (i64)350)
- );
- updateQuery.SyncExecute(
- TParameter("ID", (ui64)2),
- TParameter("SPECIES", "Rat"),
- TParameter("NAME", "Korzhik"),
- TParameter("WEIGHT", (i64)500)
- );
-
- auto result = selectQuery.SyncExecute();
- auto value = result.GetValue();
-
- UNIT_ASSERT_VALUES_EQUAL(value.GetTypeText<TFormatCxx>(),
+ "(let myUpd '("
+ " '('Species sp)"
+ " '('Name nm)"
+ " '('Weight wt)))"
+ "(let pgmReturn (AsList"
+ " (UpdateRow '/dc-1/Zoo/Animals row myUpd)"
+ "))"
+ "(return pgmReturn)"
+ ")").SyncPrepare().GetQuery();
+ auto selectQuery = kikimr.Query(
+ "("
+ "(let range '('IncFrom '('Id (Uint64 '1) (Void))))"
+ "(let select '('Species 'Name 'Weight))"
+ "(let options '())"
+ "(let pgmReturn (AsList"
+ " (SetResult 'myRes (Member (SelectRange '/dc-1/Zoo/Animals range select options) 'List))"
+ "))"
+ "(return pgmReturn)"
+ ")").SyncPrepare().GetQuery();
+
+ updateQuery.SyncExecute(
+ TParameter("ID", (ui64)1),
+ TParameter("SPECIES", "Rat"),
+ TParameter("NAME", "Dobby"),
+ TParameter("WEIGHT", (i64)350)
+ );
+ updateQuery.SyncExecute(
+ TParameter("ID", (ui64)2),
+ TParameter("SPECIES", "Rat"),
+ TParameter("NAME", "Korzhik"),
+ TParameter("WEIGHT", (i64)500)
+ );
+
+ auto result = selectQuery.SyncExecute();
+ auto value = result.GetValue();
+
+ UNIT_ASSERT_VALUES_EQUAL(value.GetTypeText<TFormatCxx>(),
"struct{optional<list<struct{optional<Utf8> Name;optional<Utf8> Species;optional<Int64> Weight;}>> myRes;}");
- UNIT_ASSERT_VALUES_EQUAL(value.GetValueText<TFormatJSON>(),
- "{\"myRes\": [{\"Name\": \"Dobby\", \"Species\": \"Rat\", \"Weight\": 350}, {\"Name\": \"Korzhik\", \"Species\": \"Rat\", \"Weight\": 500}]}");
- UNIT_ASSERT_VALUES_EQUAL(value.GetValueText<TFormatRowset>(),
- "myRes\n"
- "Name\tSpecies\tWeight\n"
- "Dobby\tRat\t350\n"
- "Korzhik\tRat\t500\n\n");
- }
-
+ UNIT_ASSERT_VALUES_EQUAL(value.GetValueText<TFormatJSON>(),
+ "{\"myRes\": [{\"Name\": \"Dobby\", \"Species\": \"Rat\", \"Weight\": 350}, {\"Name\": \"Korzhik\", \"Species\": \"Rat\", \"Weight\": 500}]}");
+ UNIT_ASSERT_VALUES_EQUAL(value.GetValueText<TFormatRowset>(),
+ "myRes\n"
+ "Name\tSpecies\tWeight\n"
+ "Dobby\tRat\t350\n"
+ "Korzhik\tRat\t500\n\n");
+ }
+
Y_UNIT_TEST(Test12) {
TTestEnvironment env;
NClient::TKikimr& kikimr = env.Kikimr;
-
- auto query = kikimr.Query(
- "("
- "(let row '('('Id (Uint64 '1))))"
- "(leg myUpd '("
+
+ auto query = kikimr.Query(
+ "("
+ "(let row '('('Id (Uint64 '1))))"
+ "(leg myUpd '("
" '('Species (Utf8 '\"Rat\"))"
" '('Name (Utf8 '\"Dobby\"))"
- " '('Weight (Int64 '350))))"
- "(let pgmReturn (AsList"
- " (UpdateRow '/dc-1/Zoo/Animals row myUpd)"
- "))"
- "(return pgmReturn)"
- ")");
- auto result = query.SyncExecute();
- auto status = result.GetStatus();
- UNIT_ASSERT(status == NMsgBusProxy::MSTATUS_ERROR);
- auto error = result.GetError();
- UNIT_ASSERT(error.Permanent());
+ " '('Weight (Int64 '350))))"
+ "(let pgmReturn (AsList"
+ " (UpdateRow '/dc-1/Zoo/Animals row myUpd)"
+ "))"
+ "(return pgmReturn)"
+ ")");
+ auto result = query.SyncExecute();
+ auto status = result.GetStatus();
+ UNIT_ASSERT(status == NMsgBusProxy::MSTATUS_ERROR);
+ auto error = result.GetError();
+ UNIT_ASSERT(error.Permanent());
UNIT_ASSERT_VALUES_EQUAL(error.GetCode(), "MP-0128");
UNIT_ASSERT_STRING_CONTAINS(error.GetMessage(), "<main>:1:34: Error: expected either let, return or import");
- }
-
+ }
+
Y_UNIT_TEST(Test13) {
TTestEnvironment env;
NClient::TKikimr& kikimr = env.Kikimr;
-
- auto query = kikimr.Query(
- "("
- "(let row '('('Id (Uint64 '1))))"
- "(let myUpd '("
+
+ auto query = kikimr.Query(
+ "("
+ "(let row '('('Id (Uint64 '1))))"
+ "(let myUpd '("
" '('Species (Utf8 '\"Rat\"))"
" '('Name (Utf8 '\"Dobby\"))"
" '('Weight (Utf8 '350))))"
- "(let pgmReturn (AsList"
+ "(let pgmReturn (AsList"
" (UpdateRow '('/dc-1/Zoo/Animals '0 '0:0) row myUpd)"
- "))"
- "(return pgmReturn)"
- ")");
- auto result = query.SyncExecute();
- auto status = result.GetStatus();
- UNIT_ASSERT(status == NMsgBusProxy::MSTATUS_ERROR);
- auto error = result.GetError();
- UNIT_ASSERT(error.Permanent());
+ "))"
+ "(return pgmReturn)"
+ ")");
+ auto result = query.SyncExecute();
+ auto status = result.GetStatus();
+ UNIT_ASSERT(status == NMsgBusProxy::MSTATUS_ERROR);
+ auto error = result.GetError();
+ UNIT_ASSERT(error.Permanent());
UNIT_ASSERT_VALUES_EQUAL(error.GetCode(), "MP-0128");
UNIT_ASSERT_STRING_CONTAINS(error.GetMessage(), "Mismatch of column type expectedType = 3 actual type = 4608");
- }
-
+ }
+
Y_UNIT_TEST(Test14) {
TTestEnvironment env;
NClient::TKikimr& kikimr = env.Kikimr;
-
- auto query = kikimr.Query(
- "("
- "(let row '('('Id (Uint64 '1))))"
- "(let myUpd '("
+
+ auto query = kikimr.Query(
+ "("
+ "(let row '('('Id (Uint64 '1))))"
+ "(let myUpd '("
" '('Species (Utf8 '\"Rat\"))"
- " '('Name (Int64 '\"Dobby\"))"
+ " '('Name (Int64 '\"Dobby\"))"
" '('Weight (Utf8 '350))))"
- "(let pgmReturn (AsList"
- " (UpdateRow '/dc-1/Zoo/Animals row myUpd)"
- "))"
- "(return pgmReturn)"
- ")");
- auto result = query.SyncExecute();
- auto status = result.GetStatus();
- UNIT_ASSERT(status == NMsgBusProxy::MSTATUS_ERROR);
- auto error = result.GetError();
- UNIT_ASSERT(error.Permanent());
+ "(let pgmReturn (AsList"
+ " (UpdateRow '/dc-1/Zoo/Animals row myUpd)"
+ "))"
+ "(return pgmReturn)"
+ ")");
+ auto result = query.SyncExecute();
+ auto status = result.GetStatus();
+ UNIT_ASSERT(status == NMsgBusProxy::MSTATUS_ERROR);
+ auto error = result.GetError();
+ UNIT_ASSERT(error.Permanent());
UNIT_ASSERT_VALUES_EQUAL(error.GetCode(), "MP-0128");
UNIT_ASSERT_VALUES_EQUAL(error.GetMessage(), "<main>:1:142: Error: At function: AsList\n"
" <main>:1:77: Error: At function: UpdateRow\n"
" <main>:1:84: Error: At function: Int64\n"
" <main>:1:91: Error: Bad atom format for type: Int64, value: \"Dobby\"\n");
- }
-
+ }
+
Y_UNIT_TEST(Test15) {
TTestEnvironment env({
NClient::TKeyPartitioningColumn("Id", NClient::TType::Uint64, 4),
@@ -797,54 +797,54 @@ Y_UNIT_TEST_SUITE(ClientLib) {
NClient::TColumn("Weight", NClient::TType::Int64)
});
NClient::TKikimr& kikimr = env.Kikimr;
-
- {
- auto result = kikimr.Query(
- "("
- "(let row '('('Id (Uint64 '1))))"
- "(let myUpd '("
+
+ {
+ auto result = kikimr.Query(
+ "("
+ "(let row '('('Id (Uint64 '1))))"
+ "(let myUpd '("
" '('Species (Utf8 '\"Rat\"))"
" '('Name (Utf8 '\"Dobby\"))"
- " '('Weight (Int64 '350))))"
- "(let pgmReturn (AsList"
- " (UpdateRow '/dc-1/Zoo/Animals row myUpd)"
- "))"
- "(return pgmReturn)"
- ")").SyncPrepare().GetQuery().SyncExecute();
- }
-
- {
- auto result = kikimr.Query(
- "("
- "(let row '('('Id (Uint64 '2))))"
- "(let myUpd '("
+ " '('Weight (Int64 '350))))"
+ "(let pgmReturn (AsList"
+ " (UpdateRow '/dc-1/Zoo/Animals row myUpd)"
+ "))"
+ "(return pgmReturn)"
+ ")").SyncPrepare().GetQuery().SyncExecute();
+ }
+
+ {
+ auto result = kikimr.Query(
+ "("
+ "(let row '('('Id (Uint64 '2))))"
+ "(let myUpd '("
" '('Species (Utf8 '\"Rat\"))"
" '('Name (Utf8 '\"Korzhik\"))"
- " '('Weight (Int64 '500))))"
- "(let pgmReturn (AsList"
- " (UpdateRow '/dc-1/Zoo/Animals row myUpd)"
- "))"
- "(return pgmReturn)"
- ")").SyncPrepare().GetQuery().SyncExecute();
- }
-
- auto query = kikimr.Query(
- "("
- "(let range '('IncFrom '('Id (Uint64 '1) (Void))))"
- "(let select '('Species 'Name 'Weight))"
- "(let options '())"
- "(let pgmReturn (AsList"
- " (SetResult 'myRes (Member (SelectRange '/dc-1/Zoo/Animals range select options) 'List))"
- "))"
- "(return pgmReturn)"
- ")");
- auto result = query.SyncExecute();
-
-
- UNIT_ASSERT_EQUAL(result.GetStatus(), NMsgBusProxy::MSTATUS_OK);
-
- auto value = result.GetValue();
-
+ " '('Weight (Int64 '500))))"
+ "(let pgmReturn (AsList"
+ " (UpdateRow '/dc-1/Zoo/Animals row myUpd)"
+ "))"
+ "(return pgmReturn)"
+ ")").SyncPrepare().GetQuery().SyncExecute();
+ }
+
+ auto query = kikimr.Query(
+ "("
+ "(let range '('IncFrom '('Id (Uint64 '1) (Void))))"
+ "(let select '('Species 'Name 'Weight))"
+ "(let options '())"
+ "(let pgmReturn (AsList"
+ " (SetResult 'myRes (Member (SelectRange '/dc-1/Zoo/Animals range select options) 'List))"
+ "))"
+ "(return pgmReturn)"
+ ")");
+ auto result = query.SyncExecute();
+
+
+ UNIT_ASSERT_EQUAL(result.GetStatus(), NMsgBusProxy::MSTATUS_OK);
+
+ auto value = result.GetValue();
+
UNIT_ASSERT_VALUES_EQUAL(value["myRes"].Size(), 2);
UNIT_ASSERT_VALUES_EQUAL((TString)value["myRes"][0]["Species"], "Rat");
UNIT_ASSERT_VALUES_EQUAL((TString)value["myRes"][0]["Name"], "Dobby");
@@ -852,10 +852,10 @@ Y_UNIT_TEST_SUITE(ClientLib) {
UNIT_ASSERT_VALUES_EQUAL((TString)value["myRes"][1]["Species"], "Rat");
UNIT_ASSERT_VALUES_EQUAL((TString)value["myRes"][1]["Name"], "Korzhik");
UNIT_ASSERT_VALUES_EQUAL((i64)value["myRes"][1]["Weight"], 500);
- }
-
+ }
+
Y_UNIT_TEST(Test16) {
- using namespace NClient;
+ using namespace NClient;
TTestEnvironment env({
TKeyPartitioningColumn("Id", NClient::TType::Uint64, 4),
TColumn("Species", NClient::TType::String),
@@ -863,70 +863,70 @@ Y_UNIT_TEST_SUITE(ClientLib) {
TColumn("Weight", NClient::TType::Int64)
});
NClient::TKikimr& kikimr = env.Kikimr;
-
- {
- auto result = kikimr.Query(
- "("
- "(let row '('('Id (Uint64 '1))))"
+
+ {
+ auto result = kikimr.Query(
+ "("
+ "(let row '('('Id (Uint64 '1))))"
"(let s (Parameter 'SPECIES (DataType 'String)))"
"(let n (Parameter 'NAME (DataType 'String)))"
"(let w (Parameter 'WEIGHT (DataType 'Int64)))"
- "(let myUpd '("
- " '('Species s)"
- " '('Name n)"
- " '('Weight w)))"
- "(let pgmReturn (AsList"
- " (UpdateRow '/dc-1/Zoo/Animals row myUpd)"
- "))"
- "(return pgmReturn)"
- ")").SyncPrepare().GetQuery().SyncExecute(
+ "(let myUpd '("
+ " '('Species s)"
+ " '('Name n)"
+ " '('Weight w)))"
+ "(let pgmReturn (AsList"
+ " (UpdateRow '/dc-1/Zoo/Animals row myUpd)"
+ "))"
+ "(return pgmReturn)"
+ ")").SyncPrepare().GetQuery().SyncExecute(
TParameterValue<TString, NScheme::NTypeIds::String>("SPECIES", "Rat"),
TParameterValue<TString, NScheme::NTypeIds::String>("NAME", "Dobby"),
- TParameter("WEIGHT", (i64)350)
- );
- UNIT_ASSERT_EQUAL(result.GetStatus(), NMsgBusProxy::MSTATUS_OK);
- }
-
- {
- auto result = kikimr.Query(
- "("
- "(let row '('('Id (Uint64 '2))))"
+ TParameter("WEIGHT", (i64)350)
+ );
+ UNIT_ASSERT_EQUAL(result.GetStatus(), NMsgBusProxy::MSTATUS_OK);
+ }
+
+ {
+ auto result = kikimr.Query(
+ "("
+ "(let row '('('Id (Uint64 '2))))"
"(let s (Parameter 'SPECIES (DataType 'String)))"
"(let n (Parameter 'NAME (DataType 'String)))"
"(let w (Parameter 'WEIGHT (DataType 'Int64)))"
- "(let myUpd '("
- " '('Species s)"
- " '('Name n)"
- " '('Weight w)))"
- "(let pgmReturn (AsList"
- " (UpdateRow '/dc-1/Zoo/Animals row myUpd)"
- "))"
- "(return pgmReturn)"
- ")").SyncPrepare().GetQuery().SyncExecute(
+ "(let myUpd '("
+ " '('Species s)"
+ " '('Name n)"
+ " '('Weight w)))"
+ "(let pgmReturn (AsList"
+ " (UpdateRow '/dc-1/Zoo/Animals row myUpd)"
+ "))"
+ "(return pgmReturn)"
+ ")").SyncPrepare().GetQuery().SyncExecute(
TParameterValue<TString, NScheme::NTypeIds::String>("SPECIES", "Rat"),
TParameterValue<TString, NScheme::NTypeIds::String>("NAME", "Korzhik"),
- TParameter("WEIGHT", (i64)500)
- );
- UNIT_ASSERT_EQUAL(result.GetStatus(), NMsgBusProxy::MSTATUS_OK);
- }
-
- auto query = kikimr.Query(
- "("
- "(let range '('IncFrom '('Id (Uint64 '1) (Void))))"
- "(let select '('Species 'Name 'Weight))"
- "(let options '())"
- "(let pgmReturn (AsList"
- " (SetResult 'myRes (Member (SelectRange '/dc-1/Zoo/Animals range select options) 'List))"
- "))"
- "(return pgmReturn)"
- ")");
- auto result = query.SyncExecute();
-
-
- UNIT_ASSERT_EQUAL(result.GetStatus(), NMsgBusProxy::MSTATUS_OK);
-
- auto value = result.GetValue();
-
+ TParameter("WEIGHT", (i64)500)
+ );
+ UNIT_ASSERT_EQUAL(result.GetStatus(), NMsgBusProxy::MSTATUS_OK);
+ }
+
+ auto query = kikimr.Query(
+ "("
+ "(let range '('IncFrom '('Id (Uint64 '1) (Void))))"
+ "(let select '('Species 'Name 'Weight))"
+ "(let options '())"
+ "(let pgmReturn (AsList"
+ " (SetResult 'myRes (Member (SelectRange '/dc-1/Zoo/Animals range select options) 'List))"
+ "))"
+ "(return pgmReturn)"
+ ")");
+ auto result = query.SyncExecute();
+
+
+ UNIT_ASSERT_EQUAL(result.GetStatus(), NMsgBusProxy::MSTATUS_OK);
+
+ auto value = result.GetValue();
+
UNIT_ASSERT_VALUES_EQUAL(value["myRes"].Size(), 2);
UNIT_ASSERT_VALUES_EQUAL((TString)value["myRes"][0]["Species"], "Rat");
UNIT_ASSERT_VALUES_EQUAL((TString)value["myRes"][0]["Name"], "Dobby");
@@ -934,51 +934,51 @@ Y_UNIT_TEST_SUITE(ClientLib) {
UNIT_ASSERT_VALUES_EQUAL((TString)value["myRes"][1]["Species"], "Rat");
UNIT_ASSERT_VALUES_EQUAL((TString)value["myRes"][1]["Name"], "Korzhik");
UNIT_ASSERT_VALUES_EQUAL((i64)value["myRes"][1]["Weight"], 500);
- }
-
- struct TGenericParameterType {
+ }
+
+ struct TGenericParameterType {
TGenericParameterType(const TString& name, const NKikimrMiniKQL::TParams& parameter)
- : Name(name)
- , Parameter(parameter)
- {
- }
- void StoreType(NKikimrMiniKQL::TStructType& type) const {
- auto& member = *type.AddMember();
- member.SetName(Name);
- member.MutableType()->CopyFrom(Parameter.GetType());
- }
- void StoreValue(NKikimrMiniKQL::TValue& value) const {
- value.CopyFrom(Parameter.GetValue());
- }
- private:
+ : Name(name)
+ , Parameter(parameter)
+ {
+ }
+ void StoreType(NKikimrMiniKQL::TStructType& type) const {
+ auto& member = *type.AddMember();
+ member.SetName(Name);
+ member.MutableType()->CopyFrom(Parameter.GetType());
+ }
+ void StoreValue(NKikimrMiniKQL::TValue& value) const {
+ value.CopyFrom(Parameter.GetValue());
+ }
+ private:
TString Name;
- NKikimrMiniKQL::TParams Parameter;
- };
-
- NKikimrMiniKQL::TParams CreateShardRangeStruct() {
- NKikimrMiniKQL::TParams shardRange;
- {
- //set type
- shardRange.MutableType()->SetKind(NKikimrMiniKQL::ETypeKind::Struct);
- auto begin = shardRange.MutableType()->MutableStruct()->AddMember();
- begin->SetName("Begin");
- begin->MutableType()->SetKind(NKikimrMiniKQL::ETypeKind::Data);
+ NKikimrMiniKQL::TParams Parameter;
+ };
+
+ NKikimrMiniKQL::TParams CreateShardRangeStruct() {
+ NKikimrMiniKQL::TParams shardRange;
+ {
+ //set type
+ shardRange.MutableType()->SetKind(NKikimrMiniKQL::ETypeKind::Struct);
+ auto begin = shardRange.MutableType()->MutableStruct()->AddMember();
+ begin->SetName("Begin");
+ begin->MutableType()->SetKind(NKikimrMiniKQL::ETypeKind::Data);
begin->MutableType()->MutableData()->SetScheme(NScheme::NTypeIds::Uint32);
- auto end = shardRange.MutableType()->MutableStruct()->AddMember();
- end->SetName("End");
- end->MutableType()->SetKind(NKikimrMiniKQL::ETypeKind::Data);
+ auto end = shardRange.MutableType()->MutableStruct()->AddMember();
+ end->SetName("End");
+ end->MutableType()->SetKind(NKikimrMiniKQL::ETypeKind::Data);
end->MutableType()->MutableData()->SetScheme(NScheme::NTypeIds::Uint32);
- }
- {
- //set value
- shardRange.MutableValue()->AddStruct()->SetUint32(1);
- shardRange.MutableValue()->AddStruct()->SetUint32(2);
- }
- return shardRange;
- }
-
+ }
+ {
+ //set value
+ shardRange.MutableValue()->AddStruct()->SetUint32(1);
+ shardRange.MutableValue()->AddStruct()->SetUint32(2);
+ }
+ return shardRange;
+ }
+
Y_UNIT_TEST(Test17) {
- using namespace NClient;
+ using namespace NClient;
TTestEnvironment env({
TKeyPartitioningColumn("Id", NClient::TType::Uint64, 4),
TColumn("Species", NClient::TType::String),
@@ -986,422 +986,422 @@ Y_UNIT_TEST_SUITE(ClientLib) {
TColumn("Weight", NClient::TType::Int64)
});
NClient::TKikimr& kikimr = env.Kikimr;
-
- {
- auto result = kikimr.Query(
- "("
- "(let row '('('Id (Uint64 '1))))"
+
+ {
+ auto result = kikimr.Query(
+ "("
+ "(let row '('('Id (Uint64 '1))))"
"(let s (Parameter 'SPECIES (DataType 'String)))"
"(let n (Parameter 'NAME (DataType 'String)))"
"(let w (Parameter 'WEIGHT (DataType 'Int64)))"
- "(let myUpd '("
- " '('Species s)"
- " '('Name n)"
- " '('Weight w)))"
- "(let pgmReturn (AsList"
- " (UpdateRow '/dc-1/Zoo/Animals row myUpd)"
- "))"
- "(return pgmReturn)"
- ")").SyncPrepare().GetQuery().SyncExecute(
- TGenericParameterType("Shard", CreateShardRangeStruct())
- );
- UNIT_ASSERT_EQUAL(result.GetStatus(), NMsgBusProxy::MSTATUS_ERROR);
- }
- }
-
+ "(let myUpd '("
+ " '('Species s)"
+ " '('Name n)"
+ " '('Weight w)))"
+ "(let pgmReturn (AsList"
+ " (UpdateRow '/dc-1/Zoo/Animals row myUpd)"
+ "))"
+ "(return pgmReturn)"
+ ")").SyncPrepare().GetQuery().SyncExecute(
+ TGenericParameterType("Shard", CreateShardRangeStruct())
+ );
+ UNIT_ASSERT_EQUAL(result.GetStatus(), NMsgBusProxy::MSTATUS_ERROR);
+ }
+ }
+
Y_UNIT_TEST(Test18) {
- using namespace NClient;
+ using namespace NClient;
TTestEnvironment env;
NClient::TKikimr& kikimr = env.Kikimr;
-
- auto updateQuery = kikimr.Query(
- "(\n"
+
+ auto updateQuery = kikimr.Query(
+ "(\n"
"(let id (Parameter 'ID (DataType 'Uint64)))\n"
- "(let row '('('Id id)))\n"
+ "(let row '('('Id id)))\n"
"(let an_type (StructType '('SPECIES (DataType 'Utf8)) '('NAME (DataType 'Utf8)) '('WEIGHT (DataType 'Int64))))\n"
- "(let an (Parameter 'ANIMAL an_type))\n"
- "(let sp (Member an 'SPECIES))\n"
- "(let nm (Member an 'NAME))\n"
- "(let wt (Member an 'WEIGHT))\n"
- "(let myUpd '(\n"
- " '('Species sp)\n"
- " '('Name nm)\n"
- " '('Weight wt)))\n"
- "(let pgmReturn (AsList\n"
- " (UpdateRow '/dc-1/Zoo/Animals row myUpd)\n"
- "))\n"
- "(return pgmReturn)\n"
- ")\n").SyncPrepare().GetQuery();
-
-
- updateQuery.SyncExecute(
- TParameter("ID", (ui64)1),
- TParameter("ANIMAL", TStruct(
- TParameter("SPECIES", "Rat"),
- TParameter("NAME", "Dobby"),
- TParameter("WEIGHT", (i64)350)
- ))
- );
-
- updateQuery.SyncExecute(
- TParameter("ID", (ui64)2),
- TParameter("ANIMAL", TStruct(
- TParameter("SPECIES", "Rat"),
- TParameter("NAME", "Korzhik"),
- TParameter("WEIGHT", (i64)500)
- ))
- );
-
- auto selectQuery = kikimr.Query(
- "("
- "(let range '('IncFrom '('Id (Uint64 '1) (Void))))"
- "(let select '('Species 'Name 'Weight))"
- "(let options '())"
- "(let pgmReturn (AsList"
- " (SetResult 'myRes (Member (SelectRange '/dc-1/Zoo/Animals range select options) 'List))"
- "))"
- "(return pgmReturn)"
- ")").SyncPrepare().GetQuery();
-
- auto result = selectQuery.SyncExecute();
- auto value = result.GetValue();
-
+ "(let an (Parameter 'ANIMAL an_type))\n"
+ "(let sp (Member an 'SPECIES))\n"
+ "(let nm (Member an 'NAME))\n"
+ "(let wt (Member an 'WEIGHT))\n"
+ "(let myUpd '(\n"
+ " '('Species sp)\n"
+ " '('Name nm)\n"
+ " '('Weight wt)))\n"
+ "(let pgmReturn (AsList\n"
+ " (UpdateRow '/dc-1/Zoo/Animals row myUpd)\n"
+ "))\n"
+ "(return pgmReturn)\n"
+ ")\n").SyncPrepare().GetQuery();
+
+
+ updateQuery.SyncExecute(
+ TParameter("ID", (ui64)1),
+ TParameter("ANIMAL", TStruct(
+ TParameter("SPECIES", "Rat"),
+ TParameter("NAME", "Dobby"),
+ TParameter("WEIGHT", (i64)350)
+ ))
+ );
+
+ updateQuery.SyncExecute(
+ TParameter("ID", (ui64)2),
+ TParameter("ANIMAL", TStruct(
+ TParameter("SPECIES", "Rat"),
+ TParameter("NAME", "Korzhik"),
+ TParameter("WEIGHT", (i64)500)
+ ))
+ );
+
+ auto selectQuery = kikimr.Query(
+ "("
+ "(let range '('IncFrom '('Id (Uint64 '1) (Void))))"
+ "(let select '('Species 'Name 'Weight))"
+ "(let options '())"
+ "(let pgmReturn (AsList"
+ " (SetResult 'myRes (Member (SelectRange '/dc-1/Zoo/Animals range select options) 'List))"
+ "))"
+ "(return pgmReturn)"
+ ")").SyncPrepare().GetQuery();
+
+ auto result = selectQuery.SyncExecute();
+ auto value = result.GetValue();
+
UNIT_ASSERT_VALUES_EQUAL(value.GetValueText<TFormatJSON>(),
- "{\"myRes\": [{\"Name\": \"Dobby\", \"Species\": \"Rat\", \"Weight\": 350}, {\"Name\": \"Korzhik\", \"Species\": \"Rat\", \"Weight\": 500}]}");
- }
-
+ "{\"myRes\": [{\"Name\": \"Dobby\", \"Species\": \"Rat\", \"Weight\": 350}, {\"Name\": \"Korzhik\", \"Species\": \"Rat\", \"Weight\": 500}]}");
+ }
+
Y_UNIT_TEST(Test19) {
- using namespace NClient;
+ using namespace NClient;
TTestEnvironment env;
NClient::TKikimr& kikimr = env.Kikimr;
-
- auto updateQuery = kikimr.Query(
- "(\n"
+
+ auto updateQuery = kikimr.Query(
+ "(\n"
"(let id (Parameter 'ID (DataType 'Uint64)))\n"
- "(let row '('('Id id)))\n"
+ "(let row '('('Id id)))\n"
"(let an_type (StructType '('SPECIES (DataType 'Utf8)) '('NAME (DataType 'Utf8)) '('WEIGHT (DataType 'Int64))))\n"
- "(let an (Parameter 'ANIMAL an_type))\n"
- "(let sp (Member an 'SPECIES))\n"
- "(let nm (Member an 'NAME))\n"
- "(let wt (Member an 'WEIGHT))\n"
- "(let myUpd '(\n"
- " '('Species sp)\n"
- " '('Name nm)\n"
- " '('Weight wt)))\n"
- "(let pgmReturn (AsList\n"
- " (UpdateRow '/dc-1/Zoo/Animals row myUpd)\n"
- "))\n"
- "(return pgmReturn)\n"
- ")\n").SyncPrepare().GetQuery();
-
- TParameters parameters;
-
- parameters["ID"] = (ui64)1;
- parameters["ANIMAL"]["SPECIES"] = "Rat";
- parameters["ANIMAL"]["NAME"] = "Dobby";
- parameters["ANIMAL"]["WEIGHT"] = (i64)350;
-
- updateQuery.SyncExecute(parameters);
-
- parameters["ID"] = (ui64)2;
- parameters["ANIMAL"]["NAME"] = "Korzhik";
- parameters["ANIMAL"]["WEIGHT"] = (i64)500;
-
- updateQuery.SyncExecute(parameters);
-
- auto selectQuery = kikimr.Query(
- "("
- "(let range '('IncFrom '('Id (Uint64 '1) (Void))))"
- "(let select '('Species 'Name 'Weight))"
- "(let options '())"
- "(let pgmReturn (AsList"
- " (SetResult 'myRes (Member (SelectRange '/dc-1/Zoo/Animals range select options) 'List))"
- "))"
- "(return pgmReturn)"
- ")").SyncPrepare().GetQuery();
-
- auto result = selectQuery.SyncExecute();
- auto value = result.GetValue();
-
+ "(let an (Parameter 'ANIMAL an_type))\n"
+ "(let sp (Member an 'SPECIES))\n"
+ "(let nm (Member an 'NAME))\n"
+ "(let wt (Member an 'WEIGHT))\n"
+ "(let myUpd '(\n"
+ " '('Species sp)\n"
+ " '('Name nm)\n"
+ " '('Weight wt)))\n"
+ "(let pgmReturn (AsList\n"
+ " (UpdateRow '/dc-1/Zoo/Animals row myUpd)\n"
+ "))\n"
+ "(return pgmReturn)\n"
+ ")\n").SyncPrepare().GetQuery();
+
+ TParameters parameters;
+
+ parameters["ID"] = (ui64)1;
+ parameters["ANIMAL"]["SPECIES"] = "Rat";
+ parameters["ANIMAL"]["NAME"] = "Dobby";
+ parameters["ANIMAL"]["WEIGHT"] = (i64)350;
+
+ updateQuery.SyncExecute(parameters);
+
+ parameters["ID"] = (ui64)2;
+ parameters["ANIMAL"]["NAME"] = "Korzhik";
+ parameters["ANIMAL"]["WEIGHT"] = (i64)500;
+
+ updateQuery.SyncExecute(parameters);
+
+ auto selectQuery = kikimr.Query(
+ "("
+ "(let range '('IncFrom '('Id (Uint64 '1) (Void))))"
+ "(let select '('Species 'Name 'Weight))"
+ "(let options '())"
+ "(let pgmReturn (AsList"
+ " (SetResult 'myRes (Member (SelectRange '/dc-1/Zoo/Animals range select options) 'List))"
+ "))"
+ "(return pgmReturn)"
+ ")").SyncPrepare().GetQuery();
+
+ auto result = selectQuery.SyncExecute();
+ auto value = result.GetValue();
+
UNIT_ASSERT_VALUES_EQUAL(value.GetValueText<TFormatJSON>(),
- "{\"myRes\": [{\"Name\": \"Dobby\", \"Species\": \"Rat\", \"Weight\": 350}, {\"Name\": \"Korzhik\", \"Species\": \"Rat\", \"Weight\": 500}]}");
- }
-
+ "{\"myRes\": [{\"Name\": \"Dobby\", \"Species\": \"Rat\", \"Weight\": 350}, {\"Name\": \"Korzhik\", \"Species\": \"Rat\", \"Weight\": 500}]}");
+ }
+
Y_UNIT_TEST(Test20) {
- using namespace NClient;
+ using namespace NClient;
TTestEnvironment env;
NClient::TKikimr& kikimr = env.Kikimr;
-
- auto updateQuery = kikimr.Query(R"___(
- (
+
+ auto updateQuery = kikimr.Query(R"___(
+ (
(let id (Parameter 'ID (DataType 'Uint64)))
- (let row '('('Id id)))
+ (let row '('('Id id)))
(let an_type (StructType '('SPECIES (DataType 'Utf8)) '('NAME (DataType 'Utf8)) '('WEIGHT (DataType 'Int64))))
- (let an_opt_type (OptionalType an_type))
- (let an_opt (Parameter 'ANIMAL an_opt_type))
- (let ret
- (AsList
- (Coalesce
- (Map an_opt
- (lambda '(an) (
- block '(
- (let sp (Member an 'SPECIES))
- (let nm (Member an 'NAME))
- (let wt (Member an 'WEIGHT))
- (let myUpd '(
- '('Species sp)
- '('Name nm)
- '('Weight wt)))
- (return (UpdateRow '/dc-1/Zoo/Animals row myUpd))
- )
- ))
- )
- (Void)
- )
- )
- )
- (return ret)
- )
- )___").SyncPrepare().GetQuery();
-
- updateQuery.SyncExecute(
- TParameter("ID", (ui64)1),
- TParameter("ANIMAL", TOptional(
- TStruct(
- TParameter("SPECIES", "Rat"),
- TParameter("NAME", "Dobby"),
- TParameter("WEIGHT", (i64)350)
- )))
- );
-
- updateQuery.SyncExecute(
- TParameter("ID", (ui64)1),
- TParameter("ANIMAL", TEmptyOptional(
- TStruct(
+ (let an_opt_type (OptionalType an_type))
+ (let an_opt (Parameter 'ANIMAL an_opt_type))
+ (let ret
+ (AsList
+ (Coalesce
+ (Map an_opt
+ (lambda '(an) (
+ block '(
+ (let sp (Member an 'SPECIES))
+ (let nm (Member an 'NAME))
+ (let wt (Member an 'WEIGHT))
+ (let myUpd '(
+ '('Species sp)
+ '('Name nm)
+ '('Weight wt)))
+ (return (UpdateRow '/dc-1/Zoo/Animals row myUpd))
+ )
+ ))
+ )
+ (Void)
+ )
+ )
+ )
+ (return ret)
+ )
+ )___").SyncPrepare().GetQuery();
+
+ updateQuery.SyncExecute(
+ TParameter("ID", (ui64)1),
+ TParameter("ANIMAL", TOptional(
+ TStruct(
+ TParameter("SPECIES", "Rat"),
+ TParameter("NAME", "Dobby"),
+ TParameter("WEIGHT", (i64)350)
+ )))
+ );
+
+ updateQuery.SyncExecute(
+ TParameter("ID", (ui64)1),
+ TParameter("ANIMAL", TEmptyOptional(
+ TStruct(
TParameter("SPECIES", TString()),
TParameter("NAME", TString()),
- TParameter("WEIGHT", i64())
- )))
- );
-
- updateQuery.SyncExecute(
- TParameter("ID", (ui64)2),
- TParameter("ANIMAL", TOptional(
- TStruct(
- TParameter("SPECIES", "Rat"),
- TParameter("NAME", "Korzhik"),
- TParameter("WEIGHT", (i64)500)
- )))
- );
-
- auto selectQuery = kikimr.Query(
- "("
- "(let range '('IncFrom '('Id (Uint64 '1) (Void))))"
- "(let select '('Species 'Name 'Weight))"
- "(let options '())"
- "(let pgmReturn (AsList"
- " (SetResult 'myRes (Member (SelectRange '/dc-1/Zoo/Animals range select options) 'List))"
- "))"
- "(return pgmReturn)"
- ")").SyncPrepare().GetQuery();
-
- auto result = selectQuery.SyncExecute();
- auto value = result.GetValue();
+ TParameter("WEIGHT", i64())
+ )))
+ );
+
+ updateQuery.SyncExecute(
+ TParameter("ID", (ui64)2),
+ TParameter("ANIMAL", TOptional(
+ TStruct(
+ TParameter("SPECIES", "Rat"),
+ TParameter("NAME", "Korzhik"),
+ TParameter("WEIGHT", (i64)500)
+ )))
+ );
+
+ auto selectQuery = kikimr.Query(
+ "("
+ "(let range '('IncFrom '('Id (Uint64 '1) (Void))))"
+ "(let select '('Species 'Name 'Weight))"
+ "(let options '())"
+ "(let pgmReturn (AsList"
+ " (SetResult 'myRes (Member (SelectRange '/dc-1/Zoo/Animals range select options) 'List))"
+ "))"
+ "(return pgmReturn)"
+ ")").SyncPrepare().GetQuery();
+
+ auto result = selectQuery.SyncExecute();
+ auto value = result.GetValue();
UNIT_ASSERT_VALUES_EQUAL(value.GetValueText<TFormatJSON>(),
- "{\"myRes\": [{\"Name\": \"Dobby\", \"Species\": \"Rat\", \"Weight\": 350}, {\"Name\": \"Korzhik\", \"Species\": \"Rat\", \"Weight\": 500}]}");
- }
-
+ "{\"myRes\": [{\"Name\": \"Dobby\", \"Species\": \"Rat\", \"Weight\": 350}, {\"Name\": \"Korzhik\", \"Species\": \"Rat\", \"Weight\": 500}]}");
+ }
+
Y_UNIT_TEST(Test21) {
- using namespace NClient;
+ using namespace NClient;
TTestEnvironment env;
NClient::TKikimr& kikimr = env.Kikimr;
-
- auto updateQuery = kikimr.Query(R"___(
- (
+
+ auto updateQuery = kikimr.Query(R"___(
+ (
(let id (Parameter 'ID (DataType 'Uint64)))
- (let row '('('Id id)))
+ (let row '('('Id id)))
(let an_type (StructType '('SPECIES (DataType 'Utf8)) '('NAME (DataType 'Utf8)) '('WEIGHT (DataType 'Int64))))
- (let an_opt_type (OptionalType an_type))
- (let an_opt (Parameter 'ANIMAL an_opt_type))
- (let ret
- (AsList
- (Coalesce
- (Map an_opt
- (lambda '(an) (
- block '(
- (let sp (Member an 'SPECIES))
- (let nm (Member an 'NAME))
- (let wt (Member an 'WEIGHT))
- (let myUpd '(
- '('Species sp)
- '('Name nm)
- '('Weight wt)))
- (return (UpdateRow '/dc-1/Zoo/Animals row myUpd))
- )
- ))
- )
- (Void)
- )
- )
- )
- (return ret)
- )
- )___").SyncPrepare().GetQuery();
-
- TParameters parameters;
-
- parameters["ID"] = (ui64)1;
- parameters["ANIMAL"].Optional()["SPECIES"] = "Rat";
- parameters["ANIMAL"].Optional()["NAME"] = "Dobby";
- parameters["ANIMAL"].Optional()["WEIGHT"] = (i64)350;
-
- updateQuery.SyncExecute(parameters);
-
- parameters["ID"] = (ui64)2;
- parameters["ANIMAL"].Optional()["NAME"] = "Korzhik";
- parameters["ANIMAL"].Optional()["WEIGHT"] = (i64)500;
-
- updateQuery.SyncExecute(parameters);
-
- auto selectQuery = kikimr.Query(
- "("
- "(let range '('IncFrom '('Id (Uint64 '1) (Void))))"
- "(let select '('Species 'Name 'Weight))"
- "(let options '())"
- "(let pgmReturn (AsList"
- " (SetResult 'myRes (Member (SelectRange '/dc-1/Zoo/Animals range select options) 'List))"
- "))"
- "(return pgmReturn)"
- ")").SyncPrepare().GetQuery();
-
- auto result = selectQuery.SyncExecute();
- auto value = result.GetValue();
-
+ (let an_opt_type (OptionalType an_type))
+ (let an_opt (Parameter 'ANIMAL an_opt_type))
+ (let ret
+ (AsList
+ (Coalesce
+ (Map an_opt
+ (lambda '(an) (
+ block '(
+ (let sp (Member an 'SPECIES))
+ (let nm (Member an 'NAME))
+ (let wt (Member an 'WEIGHT))
+ (let myUpd '(
+ '('Species sp)
+ '('Name nm)
+ '('Weight wt)))
+ (return (UpdateRow '/dc-1/Zoo/Animals row myUpd))
+ )
+ ))
+ )
+ (Void)
+ )
+ )
+ )
+ (return ret)
+ )
+ )___").SyncPrepare().GetQuery();
+
+ TParameters parameters;
+
+ parameters["ID"] = (ui64)1;
+ parameters["ANIMAL"].Optional()["SPECIES"] = "Rat";
+ parameters["ANIMAL"].Optional()["NAME"] = "Dobby";
+ parameters["ANIMAL"].Optional()["WEIGHT"] = (i64)350;
+
+ updateQuery.SyncExecute(parameters);
+
+ parameters["ID"] = (ui64)2;
+ parameters["ANIMAL"].Optional()["NAME"] = "Korzhik";
+ parameters["ANIMAL"].Optional()["WEIGHT"] = (i64)500;
+
+ updateQuery.SyncExecute(parameters);
+
+ auto selectQuery = kikimr.Query(
+ "("
+ "(let range '('IncFrom '('Id (Uint64 '1) (Void))))"
+ "(let select '('Species 'Name 'Weight))"
+ "(let options '())"
+ "(let pgmReturn (AsList"
+ " (SetResult 'myRes (Member (SelectRange '/dc-1/Zoo/Animals range select options) 'List))"
+ "))"
+ "(return pgmReturn)"
+ ")").SyncPrepare().GetQuery();
+
+ auto result = selectQuery.SyncExecute();
+ auto value = result.GetValue();
+
UNIT_ASSERT_VALUES_EQUAL(value.GetValueText<TFormatJSON>(),
- "{\"myRes\": [{\"Name\": \"Dobby\", \"Species\": \"Rat\", \"Weight\": 350}, {\"Name\": \"Korzhik\", \"Species\": \"Rat\", \"Weight\": 500}]}");
- }
-
+ "{\"myRes\": [{\"Name\": \"Dobby\", \"Species\": \"Rat\", \"Weight\": 350}, {\"Name\": \"Korzhik\", \"Species\": \"Rat\", \"Weight\": 500}]}");
+ }
+
Y_UNIT_TEST(Test22) {
- using namespace NClient;
+ using namespace NClient;
TTestEnvironment env;
NClient::TKikimr& kikimr = env.Kikimr;
-
- auto updateQuery = kikimr.Query(R"___(
- (
+
+ auto updateQuery = kikimr.Query(R"___(
+ (
(let an_type (StructType '('ID (DataType 'Uint64)) '('SPECIES (DataType 'Utf8)) '('NAME (DataType 'Utf8)) '('WEIGHT (DataType 'Int64))))
- (let an_lst_type (ListType an_type))
- (let an_lst (Parameter 'ANIMALS an_lst_type))
- (let ret
- (Map an_lst
- (lambda '(an) (
- block '(
- (let id (Member an 'ID))
- (let row '('('Id id)))
- (let sp (Member an 'SPECIES))
- (let nm (Member an 'NAME))
- (let wt (Member an 'WEIGHT))
- (let myUpd '(
- '('Species sp)
- '('Name nm)
- '('Weight wt)))
- (return (UpdateRow '/dc-1/Zoo/Animals row myUpd))
- )
- ))
- )
- )
- (return ret)
- )
- )___").SyncPrepare().GetQuery();
-
- TParameters parameters;
-
- {
- auto animal = parameters["ANIMALS"].AddListItem();
- animal["ID"] = (ui64)1;
- animal["SPECIES"] = "Rat";
- animal["NAME"] = "Dobby";
- animal["WEIGHT"] = (i64)350;
- }
-
-
-
- {
- auto animal = parameters["ANIMALS"].AddListItem();
- animal["ID"] = (ui64)2;
- animal["SPECIES"] = "Rat";
- animal["NAME"] = "Korzhik";
- animal["WEIGHT"] = (i64)500;
- }
-
- updateQuery.SyncExecute(parameters);
-
- auto selectQuery = kikimr.Query(
- "("
- "(let range '('IncFrom '('Id (Uint64 '1) (Void))))"
- "(let select '('Species 'Name 'Weight))"
- "(let options '())"
- "(let pgmReturn (AsList"
- " (SetResult 'myRes (Member (SelectRange '/dc-1/Zoo/Animals range select options) 'List))"
- "))"
- "(return pgmReturn)"
- ")").SyncPrepare().GetQuery();
-
- auto result = selectQuery.SyncExecute();
- auto value = result.GetValue();
-
+ (let an_lst_type (ListType an_type))
+ (let an_lst (Parameter 'ANIMALS an_lst_type))
+ (let ret
+ (Map an_lst
+ (lambda '(an) (
+ block '(
+ (let id (Member an 'ID))
+ (let row '('('Id id)))
+ (let sp (Member an 'SPECIES))
+ (let nm (Member an 'NAME))
+ (let wt (Member an 'WEIGHT))
+ (let myUpd '(
+ '('Species sp)
+ '('Name nm)
+ '('Weight wt)))
+ (return (UpdateRow '/dc-1/Zoo/Animals row myUpd))
+ )
+ ))
+ )
+ )
+ (return ret)
+ )
+ )___").SyncPrepare().GetQuery();
+
+ TParameters parameters;
+
+ {
+ auto animal = parameters["ANIMALS"].AddListItem();
+ animal["ID"] = (ui64)1;
+ animal["SPECIES"] = "Rat";
+ animal["NAME"] = "Dobby";
+ animal["WEIGHT"] = (i64)350;
+ }
+
+
+
+ {
+ auto animal = parameters["ANIMALS"].AddListItem();
+ animal["ID"] = (ui64)2;
+ animal["SPECIES"] = "Rat";
+ animal["NAME"] = "Korzhik";
+ animal["WEIGHT"] = (i64)500;
+ }
+
+ updateQuery.SyncExecute(parameters);
+
+ auto selectQuery = kikimr.Query(
+ "("
+ "(let range '('IncFrom '('Id (Uint64 '1) (Void))))"
+ "(let select '('Species 'Name 'Weight))"
+ "(let options '())"
+ "(let pgmReturn (AsList"
+ " (SetResult 'myRes (Member (SelectRange '/dc-1/Zoo/Animals range select options) 'List))"
+ "))"
+ "(return pgmReturn)"
+ ")").SyncPrepare().GetQuery();
+
+ auto result = selectQuery.SyncExecute();
+ auto value = result.GetValue();
+
UNIT_ASSERT_VALUES_EQUAL(value.GetValueText<TFormatJSON>(),
- "{\"myRes\": [{\"Name\": \"Dobby\", \"Species\": \"Rat\", \"Weight\": 350}, {\"Name\": \"Korzhik\", \"Species\": \"Rat\", \"Weight\": 500}]}");
- }
-
+ "{\"myRes\": [{\"Name\": \"Dobby\", \"Species\": \"Rat\", \"Weight\": 350}, {\"Name\": \"Korzhik\", \"Species\": \"Rat\", \"Weight\": 500}]}");
+ }
+
Y_UNIT_TEST(Test24) {
TTestEnvironment env;
NClient::TKikimr& kikimr = env.Kikimr;
-
- auto query = kikimr.Query(
- "("
- "(let row '('('Id (Uint64 '1))))"
- "(let myUpd '("
+
+ auto query = kikimr.Query(
+ "("
+ "(let row '('('Id (Uint64 '1))))"
+ "(let myUpd '("
" '('Species (Utf8 '\"Rat\"))"
" '('Name (Utf8 '\"Dobby\"))"
- " '('Weight (Int64 '350))))"
- "(let pgmReturn (AsList"
- " (UpdateRow '/dc-1/Zoo/Animals row myUpd)"
- "))"
- "(return pgmReturn)"
- ")");
- auto result = query.SyncPrepare().GetQuery().SyncExecute();
- auto value = result.GetValue();
- UNIT_ASSERT(value.IsNull());
- }
-
+ " '('Weight (Int64 '350))))"
+ "(let pgmReturn (AsList"
+ " (UpdateRow '/dc-1/Zoo/Animals row myUpd)"
+ "))"
+ "(return pgmReturn)"
+ ")");
+ auto result = query.SyncPrepare().GetQuery().SyncExecute();
+ auto value = result.GetValue();
+ UNIT_ASSERT(value.IsNull());
+ }
+
Y_UNIT_TEST(Test25) {
TTestEnvironment env;
NClient::TKikimr& kikimr = env.Kikimr;
-
- auto query = kikimr.Query(
- "("
- "(let row '('('Id (Uint64 '1))))"
- "(let myUpd '("
+
+ auto query = kikimr.Query(
+ "("
+ "(let row '('('Id (Uint64 '1))))"
+ "(let myUpd '("
" '('Species (Utf8 '\"Rat\"))"
" '('Name (Utf8 '\"Dobby\"))"
- " '('Weight (Int64 '350))))"
- "(let pgmReturn (AsList"
- " (UpdateRow '/dc-1/Zoo/Animals row myUpd)"
- "))"
- "(return pgmReturn)"
- ")");
- auto unbindedQuery = query.SyncPrepare().GetQuery().Unbind();
- auto result = kikimr.Query(unbindedQuery).SyncExecute();
- auto value = result.GetValue();
- UNIT_ASSERT(value.IsNull());
- }
-
+ " '('Weight (Int64 '350))))"
+ "(let pgmReturn (AsList"
+ " (UpdateRow '/dc-1/Zoo/Animals row myUpd)"
+ "))"
+ "(return pgmReturn)"
+ ")");
+ auto unbindedQuery = query.SyncPrepare().GetQuery().Unbind();
+ auto result = kikimr.Query(unbindedQuery).SyncExecute();
+ auto value = result.GetValue();
+ UNIT_ASSERT(value.IsNull());
+ }
+
Y_UNIT_TEST(SameTableDifferentColumns) {
using namespace NClient;
NMsgBusProxy::TMsgBusClientConfig clientConfig;
Tests::TServer server = StartupKikimr(clientConfig);
NClient::TKikimr kikimr(clientConfig);
-
+
auto dc = kikimr.GetSchemaRoot("dc-1");
auto example = dc.MakeDirectory("deduper");
example.CreateTable("Groups", {
@@ -1618,371 +1618,371 @@ Y_UNIT_TEST_SUITE(ClientLib) {
Y_UNIT_TEST(TypicalCase1) {
- using namespace NClient;
- NMsgBusProxy::TMsgBusClientConfig clientConfig;
- Tests::TServer server = StartupKikimr(clientConfig);
- NClient::TKikimr kikimr(clientConfig);
-
- auto dc = kikimr.GetSchemaRoot("dc-1");
- auto example = dc.MakeDirectory("Example");
+ using namespace NClient;
+ NMsgBusProxy::TMsgBusClientConfig clientConfig;
+ Tests::TServer server = StartupKikimr(clientConfig);
+ NClient::TKikimr kikimr(clientConfig);
+
+ auto dc = kikimr.GetSchemaRoot("dc-1");
+ auto example = dc.MakeDirectory("Example");
example.CreateTable("Table1", {TKeyColumn("Hash", NClient::TType::Uint64), TColumn("Data", NClient::TType::Utf8)});
example.CreateTable("Table2", {TKeyColumn("Hash", NClient::TType::Uint64), TColumn("Data", NClient::TType::Utf8)});
example.CreateTable("Table3", {TKeyColumn("Hash", NClient::TType::Uint64), TColumn("Data", NClient::TType::Utf8)});
- auto query = kikimr.Query(R"___(
- # Check 3 tables and write if none of 3 rows already exists
- (
+ auto query = kikimr.Query(R"___(
+ # Check 3 tables and write if none of 3 rows already exists
+ (
(let h1 (Parameter 'H1_PARAM (DataType 'Uint64)))
(let h2 (Parameter 'H2_PARAM (DataType 'Uint64)))
(let h3 (Parameter 'H3_PARAM (DataType 'Uint64)))
- (let row1 '('('Hash h1)))
- (let row2 '('('Hash h2)))
- (let row3 '('('Hash h3)))
- (let select '('Hash))
- (let res1 (SelectRow '/dc-1/Example/Table1 row1 select))
- (let res2 (SelectRow '/dc-1/Example/Table2 row2 select))
- (let res3 (SelectRow '/dc-1/Example/Table3 row3 select))
- (let keyH1Exists (Exists res1))
- (let keyH2Exists (Exists res2))
- (let keyH3Exists (Exists res3))
- (let anyExists (Or keyH1Exists (Or keyH2Exists keyH3Exists)))
- (let pgmReturn (If anyExists
+ (let row1 '('('Hash h1)))
+ (let row2 '('('Hash h2)))
+ (let row3 '('('Hash h3)))
+ (let select '('Hash))
+ (let res1 (SelectRow '/dc-1/Example/Table1 row1 select))
+ (let res2 (SelectRow '/dc-1/Example/Table2 row2 select))
+ (let res3 (SelectRow '/dc-1/Example/Table3 row3 select))
+ (let keyH1Exists (Exists res1))
+ (let keyH2Exists (Exists res2))
+ (let keyH3Exists (Exists res3))
+ (let anyExists (Or keyH1Exists (Or keyH2Exists keyH3Exists)))
+ (let pgmReturn (If anyExists
(block '(
- (let list (List (ListType (VoidType))))
- (let list (Append list (SetResult 'anyExists anyExists)))
- (return list)
+ (let list (List (ListType (VoidType))))
+ (let list (Append list (SetResult 'anyExists anyExists)))
+ (return list)
))
(block '(
- (let list (List (ListType (VoidType))))
- (let list (Append list (UpdateRow '/dc-1/Example/Table1 row1 '())))
- (let list (Append list (UpdateRow '/dc-1/Example/Table2 row2 '())))
- (let list (Append list (UpdateRow '/dc-1/Example/Table3 row3 '())))
- (let list (Append list (SetResult 'anyExists anyExists)))
- (return list)
+ (let list (List (ListType (VoidType))))
+ (let list (Append list (UpdateRow '/dc-1/Example/Table1 row1 '())))
+ (let list (Append list (UpdateRow '/dc-1/Example/Table2 row2 '())))
+ (let list (Append list (UpdateRow '/dc-1/Example/Table3 row3 '())))
+ (let list (Append list (SetResult 'anyExists anyExists)))
+ (return list)
))
- ))
- (return pgmReturn)
- )
- )___").SyncPrepare().GetQuery();
+ ))
+ (return pgmReturn)
+ )
+ )___").SyncPrepare().GetQuery();
THashSet<ui64> values_h1;
THashSet<ui64> values_h2;
THashSet<ui64> values_h3;
- for (ui64 cnt = 0; cnt < 10; ++cnt) {
- ui64 H1 = 100 + cnt;
- ui64 H2 = 200 - cnt * 2;
- ui64 H3 = 300 - cnt * 3;
- bool expectedResult = (values_h1.count(H1) != 0) || (values_h2.count(H2) != 0) || (values_h3.count(H3) != 0);
- auto result = query.SyncExecute(
- TParameter("H1_PARAM", H1),
- TParameter("H2_PARAM", H2),
- TParameter("H3_PARAM", H3)
- );
-
- UNIT_ASSERT_EQUAL(result.GetStatus(), NMsgBusProxy::MSTATUS_OK);
-
- auto valueResult = result.GetValue();
- bool gotResult = valueResult["anyExists"];
-
+ for (ui64 cnt = 0; cnt < 10; ++cnt) {
+ ui64 H1 = 100 + cnt;
+ ui64 H2 = 200 - cnt * 2;
+ ui64 H3 = 300 - cnt * 3;
+ bool expectedResult = (values_h1.count(H1) != 0) || (values_h2.count(H2) != 0) || (values_h3.count(H3) != 0);
+ auto result = query.SyncExecute(
+ TParameter("H1_PARAM", H1),
+ TParameter("H2_PARAM", H2),
+ TParameter("H3_PARAM", H3)
+ );
+
+ UNIT_ASSERT_EQUAL(result.GetStatus(), NMsgBusProxy::MSTATUS_OK);
+
+ auto valueResult = result.GetValue();
+ bool gotResult = valueResult["anyExists"];
+
UNIT_ASSERT_VALUES_EQUAL(gotResult, expectedResult);
-
- if (!gotResult) {
- values_h1.insert(H1);
- values_h2.insert(H2);
- values_h3.insert(H3);
- }
- }
- }
-
+
+ if (!gotResult) {
+ values_h1.insert(H1);
+ values_h2.insert(H2);
+ values_h3.insert(H3);
+ }
+ }
+ }
+
Y_UNIT_TEST(TypicalCase2) {
- using namespace NClient;
- NMsgBusProxy::TMsgBusClientConfig clientConfig;
- Tests::TServer server = StartupKikimr(clientConfig);
- NClient::TKikimr kikimr(clientConfig);
-
- auto dc = kikimr.GetSchemaRoot("dc-1");
- auto example = dc.MakeDirectory("Example");
-
+ using namespace NClient;
+ NMsgBusProxy::TMsgBusClientConfig clientConfig;
+ Tests::TServer server = StartupKikimr(clientConfig);
+ NClient::TKikimr kikimr(clientConfig);
+
+ auto dc = kikimr.GetSchemaRoot("dc-1");
+ auto example = dc.MakeDirectory("Example");
+
example.CreateTable("Table1", {TKeyColumn("Hash", NClient::TType::Uint64), TColumn("Version", NClient::TType::Uint64), TColumn("Data", NClient::TType::Utf8)});
example.CreateTable("Table2", {TKeyColumn("Hash", NClient::TType::Uint64), TColumn("Version", NClient::TType::Uint64), TColumn("Data", NClient::TType::Utf8)});
example.CreateTable("Table3", {TKeyColumn("Hash", NClient::TType::Uint64), TColumn("Version", NClient::TType::Uint64), TColumn("Data", NClient::TType::Utf8)});
-
- auto readQuery = kikimr.Query(R"___(
- (
+
+ auto readQuery = kikimr.Query(R"___(
+ (
(let h1 (Parameter 'H1_PARAM (DataType 'Uint64)))
(let h2 (Parameter 'H2_PARAM (DataType 'Uint64)))
(let h3 (Parameter 'H3_PARAM (DataType 'Uint64)))
-
- # Read data and versions from the DB
- (let row1 '('('Hash h1)))
- (let row2 '('('Hash h2)))
- (let row3 '('('Hash h3)))
- (let select '('Hash 'Version 'Data))
- (let res1 (SelectRow '/dc-1/Example/Table1 row1 select))
- (let res2 (SelectRow '/dc-1/Example/Table2 row2 select))
- (let res3 (SelectRow '/dc-1/Example/Table3 row3 select))
-
- (let pgmReturn (List (ListType (VoidType))))
- (let pgmReturn (Append pgmReturn (SetResult 'H1 res1)))
- (let pgmReturn (Append pgmReturn (SetResult 'H2 res2)))
- (let pgmReturn (Append pgmReturn (SetResult 'H3 res3)))
-
- (return pgmReturn)
- )
- )___").SyncPrepare().GetQuery();
-
- auto updateQuery = kikimr.Query(R"___(
+
+ # Read data and versions from the DB
+ (let row1 '('('Hash h1)))
+ (let row2 '('('Hash h2)))
+ (let row3 '('('Hash h3)))
+ (let select '('Hash 'Version 'Data))
+ (let res1 (SelectRow '/dc-1/Example/Table1 row1 select))
+ (let res2 (SelectRow '/dc-1/Example/Table2 row2 select))
+ (let res3 (SelectRow '/dc-1/Example/Table3 row3 select))
+
+ (let pgmReturn (List (ListType (VoidType))))
+ (let pgmReturn (Append pgmReturn (SetResult 'H1 res1)))
+ (let pgmReturn (Append pgmReturn (SetResult 'H2 res2)))
+ (let pgmReturn (Append pgmReturn (SetResult 'H3 res3)))
+
+ (return pgmReturn)
+ )
+ )___").SyncPrepare().GetQuery();
+
+ auto updateQuery = kikimr.Query(R"___(
# Check 3 tables and write if none of 3 row versions have changed since they were read
- (
- # Helper function to extract column value and substitute non-existing
- # row or NULL value with the provided default value
- (let ExtractVal (lambda '(res name defaultVal) (block '(
- (let e1 (IfPresent res
- (lambda '(r) (block '(
- (return (Member r name))
- )))
+ (
+ # Helper function to extract column value and substitute non-existing
+ # row or NULL value with the provided default value
+ (let ExtractVal (lambda '(res name defaultVal) (block '(
+ (let e1 (IfPresent res
+ (lambda '(r) (block '(
+ (return (Member r name))
+ )))
(block '(
- (return (Just defaultVal))
+ (return (Just defaultVal))
))
- ))
- (let e2 (Coalesce e1 defaultVal))
- (return e2)
- ))
- ))
-
+ ))
+ (let e2 (Coalesce e1 defaultVal))
+ (return e2)
+ ))
+ ))
+
(let h1 (Parameter 'H1_PARAM (DataType 'Uint64)))
(let h2 (Parameter 'H2_PARAM (DataType 'Uint64)))
(let h3 (Parameter 'H3_PARAM (DataType 'Uint64)))
-
+
(let d1 (Parameter 'D1_PARAM (DataType 'Utf8)))
(let d2 (Parameter 'D2_PARAM (DataType 'Utf8)))
(let d3 (Parameter 'D3_PARAM (DataType 'Utf8)))
-
- # Read versions from the DB
- (let row1 '('('Hash h1)))
- (let row2 '('('Hash h2)))
- (let row3 '('('Hash h3)))
- (let select '('Version))
- (let res1 (SelectRow '/dc-1/Example/Table1 row1 select))
- (let res2 (SelectRow '/dc-1/Example/Table2 row2 select))
- (let res3 (SelectRow '/dc-1/Example/Table3 row3 select))
- (let rv1 (Apply ExtractVal res1 'Version (Uint64 '0)))
- (let rv2 (Apply ExtractVal res2 'Version (Uint64 '0)))
- (let rv3 (Apply ExtractVal res3 'Version (Uint64 '0)))
-
- # Get old versions from the parameters
+
+ # Read versions from the DB
+ (let row1 '('('Hash h1)))
+ (let row2 '('('Hash h2)))
+ (let row3 '('('Hash h3)))
+ (let select '('Version))
+ (let res1 (SelectRow '/dc-1/Example/Table1 row1 select))
+ (let res2 (SelectRow '/dc-1/Example/Table2 row2 select))
+ (let res3 (SelectRow '/dc-1/Example/Table3 row3 select))
+ (let rv1 (Apply ExtractVal res1 'Version (Uint64 '0)))
+ (let rv2 (Apply ExtractVal res2 'Version (Uint64 '0)))
+ (let rv3 (Apply ExtractVal res3 'Version (Uint64 '0)))
+
+ # Get old versions from the parameters
(let v1 (Parameter 'V1_PARAM (DataType 'Uint64)))
(let v2 (Parameter 'V2_PARAM (DataType 'Uint64)))
(let v3 (Parameter 'V3_PARAM (DataType 'Uint64)))
- (let v1 (Coalesce v1 (Uint64 '0)))
- (let v2 (Coalesce v2 (Uint64 '0)))
- (let v3 (Coalesce v3 (Uint64 '0)))
-
- ### Check versions ###
- (let predicate (Bool 'True))
+ (let v1 (Coalesce v1 (Uint64 '0)))
+ (let v2 (Coalesce v2 (Uint64 '0)))
+ (let v3 (Coalesce v3 (Uint64 '0)))
+
+ ### Check versions ###
+ (let predicate (Bool 'True))
(let predicate (And predicate (Equal rv1 v1)))
(let predicate (And predicate (Equal rv2 v2)))
(let predicate (And predicate (Equal rv2 v3)))
-
-
- ### If versions are not changed -- do writes ###
- (let pgmReturn (If predicate
+
+
+ ### If versions are not changed -- do writes ###
+ (let pgmReturn (If predicate
(block '(
- (let list (List (ListType (VoidType))))
- (let list (Append list (UpdateRow '/dc-1/Example/Table1 row1 '('('Version (Increment v1))'('Data d1)))))
- (let list (Append list (UpdateRow '/dc-1/Example/Table2 row2 '('('Version (Increment v2))'('Data d2)))))
- (let list (Append list (UpdateRow '/dc-1/Example/Table3 row3 '('('Version (Increment v3))'('Data d3)))))
+ (let list (List (ListType (VoidType))))
+ (let list (Append list (UpdateRow '/dc-1/Example/Table1 row1 '('('Version (Increment v1))'('Data d1)))))
+ (let list (Append list (UpdateRow '/dc-1/Example/Table2 row2 '('('Version (Increment v2))'('Data d2)))))
+ (let list (Append list (UpdateRow '/dc-1/Example/Table3 row3 '('('Version (Increment v3))'('Data d3)))))
(let list (Append list (SetResult 'myRes (Utf8 '"Updated"))))
- (return list)
+ (return list)
))
(block '(
- (let emptyList (List (ListType (VoidType))))
+ (let emptyList (List (ListType (VoidType))))
(let emptyList (Append emptyList (SetResult 'myRes (Utf8 '"Version mismatch"))))
- (return emptyList)
+ (return emptyList)
))
- ))
- ######
-
- ## Output some debug values
- (let pgmReturn (Append pgmReturn (SetResult 'rv1 rv1)))
- (let pgmReturn (Append pgmReturn (SetResult 'v1 v1)))
-
- (return pgmReturn)
- )
- )___").SyncPrepare().GetQuery();
-
- for (ui64 cnt = 0; cnt < 10; ++cnt) {
- ui64 H1 = 100 + cnt;
- ui64 H2 = 200 - cnt * 2;
- ui64 H3 = 300 - cnt * 3;
- auto result = readQuery.SyncExecute(
- TParameter("H1_PARAM", H1),
- TParameter("H2_PARAM", H2),
- TParameter("H3_PARAM", H3)
- );
- auto valueResult = result.GetValue();
- auto V1 = valueResult["H1"]["Version"];
- auto V2 = valueResult["H2"]["Version"];
- auto V3 = valueResult["H3"]["Version"];
- result = updateQuery.SyncExecute(
- TParameter("H1_PARAM", H1),
- TParameter("H2_PARAM", H2),
- TParameter("H3_PARAM", H3),
- TParameter("V1_PARAM", V1.IsNull() ? (ui64)0 : V1),
- TParameter("V2_PARAM", V2.IsNull() ? (ui64)0 : V2),
- TParameter("V3_PARAM", V3.IsNull() ? (ui64)0 : V3),
- TParameter("D1_PARAM", "data" + ToString(H1)),
- TParameter("D2_PARAM", "data" + ToString(H2)),
- TParameter("D3_PARAM", "data" + ToString(H3))
- );
- UNIT_ASSERT_EQUAL(result.GetStatus(), NMsgBusProxy::MSTATUS_OK);
- }
- }
-
+ ))
+ ######
+
+ ## Output some debug values
+ (let pgmReturn (Append pgmReturn (SetResult 'rv1 rv1)))
+ (let pgmReturn (Append pgmReturn (SetResult 'v1 v1)))
+
+ (return pgmReturn)
+ )
+ )___").SyncPrepare().GetQuery();
+
+ for (ui64 cnt = 0; cnt < 10; ++cnt) {
+ ui64 H1 = 100 + cnt;
+ ui64 H2 = 200 - cnt * 2;
+ ui64 H3 = 300 - cnt * 3;
+ auto result = readQuery.SyncExecute(
+ TParameter("H1_PARAM", H1),
+ TParameter("H2_PARAM", H2),
+ TParameter("H3_PARAM", H3)
+ );
+ auto valueResult = result.GetValue();
+ auto V1 = valueResult["H1"]["Version"];
+ auto V2 = valueResult["H2"]["Version"];
+ auto V3 = valueResult["H3"]["Version"];
+ result = updateQuery.SyncExecute(
+ TParameter("H1_PARAM", H1),
+ TParameter("H2_PARAM", H2),
+ TParameter("H3_PARAM", H3),
+ TParameter("V1_PARAM", V1.IsNull() ? (ui64)0 : V1),
+ TParameter("V2_PARAM", V2.IsNull() ? (ui64)0 : V2),
+ TParameter("V3_PARAM", V3.IsNull() ? (ui64)0 : V3),
+ TParameter("D1_PARAM", "data" + ToString(H1)),
+ TParameter("D2_PARAM", "data" + ToString(H2)),
+ TParameter("D3_PARAM", "data" + ToString(H3))
+ );
+ UNIT_ASSERT_EQUAL(result.GetStatus(), NMsgBusProxy::MSTATUS_OK);
+ }
+ }
+
Y_UNIT_TEST(TypicalCase2A) {
- using namespace NClient;
- NMsgBusProxy::TMsgBusClientConfig clientConfig;
- Tests::TServer server = StartupKikimr(clientConfig);
- NClient::TKikimr kikimr(clientConfig);
-
- auto dc = kikimr.GetSchemaRoot("dc-1");
- auto example = dc.MakeDirectory("Example");
-
+ using namespace NClient;
+ NMsgBusProxy::TMsgBusClientConfig clientConfig;
+ Tests::TServer server = StartupKikimr(clientConfig);
+ NClient::TKikimr kikimr(clientConfig);
+
+ auto dc = kikimr.GetSchemaRoot("dc-1");
+ auto example = dc.MakeDirectory("Example");
+
example.CreateTable("Table1", {TKeyColumn("Hash", NClient::TType::Uint64), TColumn("Version", NClient::TType::Uint64), TColumn("Data", NClient::TType::String)});
example.CreateTable("Table2", {TKeyColumn("Hash", NClient::TType::Uint64), TColumn("Version", NClient::TType::Uint64), TColumn("Data", NClient::TType::String)});
example.CreateTable("Table3", {TKeyColumn("Hash", NClient::TType::Uint64), TColumn("Version", NClient::TType::Uint64), TColumn("Data", NClient::TType::String)});
-
- auto readQuery = kikimr.Query(R"___(
- (
+
+ auto readQuery = kikimr.Query(R"___(
+ (
(let h1 (Parameter 'H1_PARAM (DataType 'Uint64)))
(let h2 (Parameter 'H2_PARAM (DataType 'Uint64)))
(let h3 (Parameter 'H3_PARAM (DataType 'Uint64)))
-
- # Read data and versions from the DB
- (let row1 '('('Hash h1)))
- (let row2 '('('Hash h2)))
- (let row3 '('('Hash h3)))
- (let select '('Hash 'Version 'Data))
- (let res1 (SelectRow '/dc-1/Example/Table1 row1 select))
- (let res2 (SelectRow '/dc-1/Example/Table2 row2 select))
- (let res3 (SelectRow '/dc-1/Example/Table3 row3 select))
-
- (let pgmReturn (List (ListType (VoidType))))
- (let pgmReturn (Append pgmReturn (SetResult 'H1 res1)))
- (let pgmReturn (Append pgmReturn (SetResult 'H2 res2)))
- (let pgmReturn (Append pgmReturn (SetResult 'H3 res3)))
-
- (return pgmReturn)
- )
- )___").SyncPrepare().GetQuery();
-
- auto updateQuery = kikimr.Query(R"___(
- # Check 3 tables and write iff none of 3 row versions have changed since they were read
- (
- # Helper function to extract column value and substitute non-existing
- # row or NULL value with the provided default value
- (let ExtractVal (lambda '(res name defaultVal) (block '(
- (let e1 (IfPresent res
- (lambda '(r) (block '(
- (return (Member r name))
- )))
+
+ # Read data and versions from the DB
+ (let row1 '('('Hash h1)))
+ (let row2 '('('Hash h2)))
+ (let row3 '('('Hash h3)))
+ (let select '('Hash 'Version 'Data))
+ (let res1 (SelectRow '/dc-1/Example/Table1 row1 select))
+ (let res2 (SelectRow '/dc-1/Example/Table2 row2 select))
+ (let res3 (SelectRow '/dc-1/Example/Table3 row3 select))
+
+ (let pgmReturn (List (ListType (VoidType))))
+ (let pgmReturn (Append pgmReturn (SetResult 'H1 res1)))
+ (let pgmReturn (Append pgmReturn (SetResult 'H2 res2)))
+ (let pgmReturn (Append pgmReturn (SetResult 'H3 res3)))
+
+ (return pgmReturn)
+ )
+ )___").SyncPrepare().GetQuery();
+
+ auto updateQuery = kikimr.Query(R"___(
+ # Check 3 tables and write iff none of 3 row versions have changed since they were read
+ (
+ # Helper function to extract column value and substitute non-existing
+ # row or NULL value with the provided default value
+ (let ExtractVal (lambda '(res name defaultVal) (block '(
+ (let e1 (IfPresent res
+ (lambda '(r) (block '(
+ (return (Member r name))
+ )))
(block '(
- (return (Just defaultVal))
+ (return (Just defaultVal))
))
- ))
- (let e2 (Coalesce e1 defaultVal))
- (return e2)
- ))
- ))
-
+ ))
+ (let e2 (Coalesce e1 defaultVal))
+ (return e2)
+ ))
+ ))
+
(let h1 (Parameter 'H1_PARAM (DataType 'Uint64)))
(let h2 (Parameter 'H2_PARAM (DataType 'Uint64)))
(let h3 (Parameter 'H3_PARAM (DataType 'Uint64)))
-
+
(let d1 (Parameter 'D1_PARAM (DataType 'String)))
(let d2 (Parameter 'D2_PARAM (DataType 'String)))
(let d3 (Parameter 'D3_PARAM (DataType 'String)))
-
- # Read versions from the DB
- (let row1 '('('Hash h1)))
- (let row2 '('('Hash h2)))
- (let row3 '('('Hash h3)))
- (let select '('Version))
- (let res1 (SelectRow '/dc-1/Example/Table1 row1 select))
- (let res2 (SelectRow '/dc-1/Example/Table2 row2 select))
- (let res3 (SelectRow '/dc-1/Example/Table3 row3 select))
- (let rv1 (Apply ExtractVal res1 'Version (Uint64 '0)))
- (let rv2 (Apply ExtractVal res2 'Version (Uint64 '0)))
- (let rv3 (Apply ExtractVal res3 'Version (Uint64 '0)))
-
- # Get old versions from the parameters
+
+ # Read versions from the DB
+ (let row1 '('('Hash h1)))
+ (let row2 '('('Hash h2)))
+ (let row3 '('('Hash h3)))
+ (let select '('Version))
+ (let res1 (SelectRow '/dc-1/Example/Table1 row1 select))
+ (let res2 (SelectRow '/dc-1/Example/Table2 row2 select))
+ (let res3 (SelectRow '/dc-1/Example/Table3 row3 select))
+ (let rv1 (Apply ExtractVal res1 'Version (Uint64 '0)))
+ (let rv2 (Apply ExtractVal res2 'Version (Uint64 '0)))
+ (let rv3 (Apply ExtractVal res3 'Version (Uint64 '0)))
+
+ # Get old versions from the parameters
(let v1 (Parameter 'V1_PARAM (DataType 'Uint64)))
(let v2 (Parameter 'V2_PARAM (DataType 'Uint64)))
(let v3 (Parameter 'V3_PARAM (DataType 'Uint64)))
- (let v1 (Coalesce v1 (Uint64 '0)))
- (let v2 (Coalesce v2 (Uint64 '0)))
- (let v3 (Coalesce v3 (Uint64 '0)))
-
- ### Check versions ###
- (let predicate (Bool 'True))
+ (let v1 (Coalesce v1 (Uint64 '0)))
+ (let v2 (Coalesce v2 (Uint64 '0)))
+ (let v3 (Coalesce v3 (Uint64 '0)))
+
+ ### Check versions ###
+ (let predicate (Bool 'True))
(let predicate (And predicate (Equal rv1 v1)))
(let predicate (And predicate (Equal rv2 v2)))
(let predicate (And predicate (Equal rv2 v3)))
-
-
- ### If versions are not changed -- do writes ###
- (let pgmReturn (If predicate
+
+
+ ### If versions are not changed -- do writes ###
+ (let pgmReturn (If predicate
(block '(
- (let list (List (ListType (VoidType))))
- (let list (Append list (UpdateRow '/dc-1/Example/Table1 row1 '('('Version (Increment v1))'('Data d1)))))
- (let list (Append list (UpdateRow '/dc-1/Example/Table2 row2 '('('Version (Increment v2))'('Data d2)))))
- (let list (Append list (UpdateRow '/dc-1/Example/Table3 row3 '('('Version (Increment v3))'('Data d3)))))
+ (let list (List (ListType (VoidType))))
+ (let list (Append list (UpdateRow '/dc-1/Example/Table1 row1 '('('Version (Increment v1))'('Data d1)))))
+ (let list (Append list (UpdateRow '/dc-1/Example/Table2 row2 '('('Version (Increment v2))'('Data d2)))))
+ (let list (Append list (UpdateRow '/dc-1/Example/Table3 row3 '('('Version (Increment v3))'('Data d3)))))
(let list (Append list (SetResult 'myRes (Utf8 '"Updated"))))
- (return list)
+ (return list)
))
(block '(
- (let emptyList (List (ListType (VoidType))))
+ (let emptyList (List (ListType (VoidType))))
(let emptyList (Append emptyList (SetResult 'myRes (Utf8 '"Version mismatch"))))
- (return emptyList)
+ (return emptyList)
))
- ))
- ######
-
- ## Output some debug values
- (let pgmReturn (Append pgmReturn (SetResult 'rv1 rv1)))
- (let pgmReturn (Append pgmReturn (SetResult 'v1 v1)))
-
- (return pgmReturn)
- )
- )___").SyncPrepare().GetQuery();
-
- for (ui64 cnt = 0; cnt < 10; ++cnt) {
- ui64 H1 = 100 + cnt;
- ui64 H2 = 200 - cnt * 2;
- ui64 H3 = 300 - cnt * 3;
- auto result = readQuery.SyncExecute(
- TParameter("H1_PARAM", H1),
- TParameter("H2_PARAM", H2),
- TParameter("H3_PARAM", H3)
- );
- UNIT_ASSERT_EQUAL(result.GetStatus(), NMsgBusProxy::MSTATUS_OK);
- auto valueResult = result.GetValue();
- auto V1 = valueResult["H1"]["Version"];
- auto V2 = valueResult["H2"]["Version"];
- auto V3 = valueResult["H3"]["Version"];
- result = updateQuery.SyncExecute(
- TParameter("H1_PARAM", H1),
- TParameter("H2_PARAM", H2),
- TParameter("H3_PARAM", H3),
- TParameter("V1_PARAM", V1.IsNull() ? (ui64)0 : V1),
- TParameter("V2_PARAM", V2.IsNull() ? (ui64)0 : V2),
- TParameter("V3_PARAM", V3.IsNull() ? (ui64)0 : V3),
+ ))
+ ######
+
+ ## Output some debug values
+ (let pgmReturn (Append pgmReturn (SetResult 'rv1 rv1)))
+ (let pgmReturn (Append pgmReturn (SetResult 'v1 v1)))
+
+ (return pgmReturn)
+ )
+ )___").SyncPrepare().GetQuery();
+
+ for (ui64 cnt = 0; cnt < 10; ++cnt) {
+ ui64 H1 = 100 + cnt;
+ ui64 H2 = 200 - cnt * 2;
+ ui64 H3 = 300 - cnt * 3;
+ auto result = readQuery.SyncExecute(
+ TParameter("H1_PARAM", H1),
+ TParameter("H2_PARAM", H2),
+ TParameter("H3_PARAM", H3)
+ );
+ UNIT_ASSERT_EQUAL(result.GetStatus(), NMsgBusProxy::MSTATUS_OK);
+ auto valueResult = result.GetValue();
+ auto V1 = valueResult["H1"]["Version"];
+ auto V2 = valueResult["H2"]["Version"];
+ auto V3 = valueResult["H3"]["Version"];
+ result = updateQuery.SyncExecute(
+ TParameter("H1_PARAM", H1),
+ TParameter("H2_PARAM", H2),
+ TParameter("H3_PARAM", H3),
+ TParameter("V1_PARAM", V1.IsNull() ? (ui64)0 : V1),
+ TParameter("V2_PARAM", V2.IsNull() ? (ui64)0 : V2),
+ TParameter("V3_PARAM", V3.IsNull() ? (ui64)0 : V3),
TParameterValue<TString, NScheme::NTypeIds::String>("D1_PARAM", "data" + ToString(H1)),
TParameterValue<TString, NScheme::NTypeIds::String>("D2_PARAM", "data" + ToString(H2)),
TParameterValue<TString, NScheme::NTypeIds::String>("D3_PARAM", "data" + ToString(H3))
- );
- UNIT_ASSERT_EQUAL(result.GetStatus(), NMsgBusProxy::MSTATUS_OK);
- }
- }
-
+ );
+ UNIT_ASSERT_EQUAL(result.GetStatus(), NMsgBusProxy::MSTATUS_OK);
+ }
+ }
+
Y_UNIT_TEST(TestParameterTypes) {
using namespace NClient;
NMsgBusProxy::TMsgBusClientConfig clientConfig;
@@ -2045,97 +2045,97 @@ Y_UNIT_TEST_SUITE(ClientLib) {
}
// Y_UNIT_TEST(Wrongdoing1) {
-// using namespace NClient;
+// using namespace NClient;
// TString type = R"___(
-// Kind: 6
-// Struct {
-// Member {
-// Name: "r1"
-// Type {
-// Kind: 3
-// Optional {
-// Item {
-// Kind: 4
-// List {
-// Item {
-// Kind: 3
-// Optional {
-// Item {
-// Kind: 6
-// Struct {
-// Member {
-// Name: "GroupSimHash"
-// Type {
-// Kind: 3
-// Optional {
-// Item {
-// Kind: 2
-// Data {
-// Scheme: 4
-// }
-// }
-// }
-// }
-// }
-// }
-// }
-// }
-// }
-// }
-// }
-// }
-// }
-// }
-// Member {
-// Name: "r2"
-// Type {
-// Kind: 3
-// Optional {
-// Item {
-// Kind: 4
-// List {
-// Item {
-// Kind: 4
-// List {
-// Item {
-// Kind: 6
-// Struct {
-// Member {
-// Name: "GroupSimHash"
-// Type {
-// Kind: 3
-// Optional {
-// Item {
-// Kind: 2
-// Data {
-// Scheme: 4
-// }
-// }
-// }
-// }
-// }
-// }
-// }
-// }
-// }
-// }
-// }
-// }
-// }
-// }
-// }
-// )___";
-// NKikimrMiniKQL::TValue minikqlValue;
-// NKikimrMiniKQL::TType minikqlType;
-// bool parseOk = ::google::protobuf::TextFormat::ParseFromString(type, &minikqlType);
-// UNIT_ASSERT(parseOk);
-// TValue value = TValue::Create(minikqlValue, minikqlType);
-
-// //int i = 0;
-// auto result = (ui64)value["r2"]["GroupSimHash"];
-// Y_UNUSED(result);
-// }
-}
+// Kind: 6
+// Struct {
+// Member {
+// Name: "r1"
+// Type {
+// Kind: 3
+// Optional {
+// Item {
+// Kind: 4
+// List {
+// Item {
+// Kind: 3
+// Optional {
+// Item {
+// Kind: 6
+// Struct {
+// Member {
+// Name: "GroupSimHash"
+// Type {
+// Kind: 3
+// Optional {
+// Item {
+// Kind: 2
+// Data {
+// Scheme: 4
+// }
+// }
+// }
+// }
+// }
+// }
+// }
+// }
+// }
+// }
+// }
+// }
+// }
+// }
+// Member {
+// Name: "r2"
+// Type {
+// Kind: 3
+// Optional {
+// Item {
+// Kind: 4
+// List {
+// Item {
+// Kind: 4
+// List {
+// Item {
+// Kind: 6
+// Struct {
+// Member {
+// Name: "GroupSimHash"
+// Type {
+// Kind: 3
+// Optional {
+// Item {
+// Kind: 2
+// Data {
+// Scheme: 4
+// }
+// }
+// }
+// }
+// }
+// }
+// }
+// }
+// }
+// }
+// }
+// }
+// }
+// }
+// }
+// )___";
+// NKikimrMiniKQL::TValue minikqlValue;
+// NKikimrMiniKQL::TType minikqlType;
+// bool parseOk = ::google::protobuf::TextFormat::ParseFromString(type, &minikqlType);
+// UNIT_ASSERT(parseOk);
+// TValue value = TValue::Create(minikqlValue, minikqlType);
+
+// //int i = 0;
+// auto result = (ui64)value["r2"]["GroupSimHash"];
+// Y_UNUSED(result);
+// }
+}
NKikimrTxUserProxy::TKeyRange MakeRange(const TVector<TString> from, const TVector<TString> to,
bool fromInclusive, bool toInclusive)
diff --git a/ydb/public/lib/deprecated/kicli/error.cpp b/ydb/public/lib/deprecated/kicli/error.cpp
index 92aa144bf86..473a981f607 100644
--- a/ydb/public/lib/deprecated/kicli/error.cpp
+++ b/ydb/public/lib/deprecated/kicli/error.cpp
@@ -1,339 +1,339 @@
-#include "kicli.h"
+#include "kicli.h"
#include <ydb/library/yql/public/issue/yql_issue.h>
#include <ydb/library/yql/public/issue/yql_issue_message.h>
#include <ydb/public/lib/base/defs.h>
#include <ydb/public/lib/deprecated/client/msgbus_client.h>
#include <ydb/core/protos/minikql_engine.pb.h>
-
-namespace NKikimr {
-namespace NClient {
-
-bool TError::Success() const {
- switch(Facility) {
- case EFacility::FacilityMessageBus:
- switch (Code) {
- case NBus::MESSAGE_OK:
- return true;
- default:
- break;
- };
- break;
- case EFacility::FacilityMsgBusProxy:
- switch (Code) {
- case NMsgBusProxy::MSTATUS_INPROGRESS:
- case NMsgBusProxy::MSTATUS_OK:
- return true;
- default:
- break;
- };
- break;
- case EFacility::FacilityExecutionEngine:
+
+namespace NKikimr {
+namespace NClient {
+
+bool TError::Success() const {
+ switch(Facility) {
+ case EFacility::FacilityMessageBus:
+ switch (Code) {
+ case NBus::MESSAGE_OK:
+ return true;
+ default:
+ break;
+ };
+ break;
+ case EFacility::FacilityMsgBusProxy:
+ switch (Code) {
+ case NMsgBusProxy::MSTATUS_INPROGRESS:
+ case NMsgBusProxy::MSTATUS_OK:
+ return true;
+ default:
+ break;
+ };
+ break;
+ case EFacility::FacilityExecutionEngine:
switch (Code) {
case NKikimrMiniKQLEngine::Ok:
- return true;
- default:
- break;
- };
- break;
- case EFacility::FacilityTxProxy:
- switch (Code) {
+ return true;
+ default:
+ break;
+ };
+ break;
+ case EFacility::FacilityTxProxy:
+ switch (Code) {
case NTxProxy::TResultStatus::EStatus::ExecComplete:
case NTxProxy::TResultStatus::EStatus::ExecAlready:
case NTxProxy::TResultStatus::EStatus::ExecInProgress:
case NTxProxy::TResultStatus::EStatus::ExecResponseData:
- return true;
- default:
- break;
- };
- break;
- };
- return false;
-}
-
-bool TError::Permanent() const {
- switch(Facility) {
- case EFacility::FacilityMessageBus:
- switch (Code) {
- case NBus::MESSAGE_BUSY:
- case NBus::MESSAGE_TIMEOUT:
- return false;
- default:
- break;
- };
- break;
- case EFacility::FacilityMsgBusProxy:
- switch (Code) {
- case NMsgBusProxy::MSTATUS_INPROGRESS:
- case NMsgBusProxy::MSTATUS_NOTREADY:
- case NMsgBusProxy::MSTATUS_TIMEOUT:
- case NMsgBusProxy::MSTATUS_REJECTED:
- return false;
- default:
- break;
- };
- break;
- case EFacility::FacilityExecutionEngine:
+ return true;
+ default:
+ break;
+ };
+ break;
+ };
+ return false;
+}
+
+bool TError::Permanent() const {
+ switch(Facility) {
+ case EFacility::FacilityMessageBus:
+ switch (Code) {
+ case NBus::MESSAGE_BUSY:
+ case NBus::MESSAGE_TIMEOUT:
+ return false;
+ default:
+ break;
+ };
+ break;
+ case EFacility::FacilityMsgBusProxy:
+ switch (Code) {
+ case NMsgBusProxy::MSTATUS_INPROGRESS:
+ case NMsgBusProxy::MSTATUS_NOTREADY:
+ case NMsgBusProxy::MSTATUS_TIMEOUT:
+ case NMsgBusProxy::MSTATUS_REJECTED:
+ return false;
+ default:
+ break;
+ };
+ break;
+ case EFacility::FacilityExecutionEngine:
switch (Code) {
case NKikimrMiniKQLEngine::SnapshotNotReady:
- return false;
- default:
- break;
- };
- break;
- case EFacility::FacilityTxProxy:
- switch (Code) {
+ return false;
+ default:
+ break;
+ };
+ break;
+ case EFacility::FacilityTxProxy:
+ switch (Code) {
case NTxProxy::TResultStatus::EStatus::ExecTimeout:
case NTxProxy::TResultStatus::EStatus::ExecInProgress:
case NTxProxy::TResultStatus::EStatus::ProxyShardTryLater:
case NTxProxy::TResultStatus::EStatus::ProxyShardOverloaded:
case NTxProxy::TResultStatus::EStatus::ProxyShardNotAvailable:
- return false;
- default:
- break;
- };
- break;
- };
+ return false;
+ default:
+ break;
+ };
+ break;
+ };
return Error();
-}
-
-bool TError::Timeout() const {
- switch(Facility) {
- case EFacility::FacilityMessageBus:
- switch (Code) {
- case NBus::MESSAGE_TIMEOUT:
- return true;
- default:
- break;
- };
- break;
- case EFacility::FacilityMsgBusProxy:
- switch (Code) {
- case NMsgBusProxy::MSTATUS_TIMEOUT:
- return true;
- default:
- break;
- };
- break;
- case EFacility::FacilityExecutionEngine:
- break;
- case EFacility::FacilityTxProxy:
- switch (Code) {
+}
+
+bool TError::Timeout() const {
+ switch(Facility) {
+ case EFacility::FacilityMessageBus:
+ switch (Code) {
+ case NBus::MESSAGE_TIMEOUT:
+ return true;
+ default:
+ break;
+ };
+ break;
+ case EFacility::FacilityMsgBusProxy:
+ switch (Code) {
+ case NMsgBusProxy::MSTATUS_TIMEOUT:
+ return true;
+ default:
+ break;
+ };
+ break;
+ case EFacility::FacilityExecutionEngine:
+ break;
+ case EFacility::FacilityTxProxy:
+ switch (Code) {
case NTxProxy::TResultStatus::EStatus::ExecTimeout:
- return true;
- default:
- break;
- };
- break;
- };
- return false;
-}
-
-bool TError::Rejected() const {
- switch(Facility) {
- case EFacility::FacilityMessageBus:
- switch (Code) {
- case NBus::MESSAGE_BUSY:
- return true;
- default:
- break;
- };
- break;
- case EFacility::FacilityMsgBusProxy:
- switch (Code) {
- case NMsgBusProxy::MSTATUS_NOTREADY:
- case NMsgBusProxy::MSTATUS_REJECTED:
- return true;
- default:
- break;
- };
- break;
- case EFacility::FacilityExecutionEngine:
- break;
- case EFacility::FacilityTxProxy:
- switch (Code) {
+ return true;
+ default:
+ break;
+ };
+ break;
+ };
+ return false;
+}
+
+bool TError::Rejected() const {
+ switch(Facility) {
+ case EFacility::FacilityMessageBus:
+ switch (Code) {
+ case NBus::MESSAGE_BUSY:
+ return true;
+ default:
+ break;
+ };
+ break;
+ case EFacility::FacilityMsgBusProxy:
+ switch (Code) {
+ case NMsgBusProxy::MSTATUS_NOTREADY:
+ case NMsgBusProxy::MSTATUS_REJECTED:
+ return true;
+ default:
+ break;
+ };
+ break;
+ case EFacility::FacilityExecutionEngine:
+ break;
+ case EFacility::FacilityTxProxy:
+ switch (Code) {
case NTxProxy::TResultStatus::EStatus::ProxyShardTryLater:
case NTxProxy::TResultStatus::EStatus::ProxyShardOverloaded:
case NTxProxy::TResultStatus::EStatus::ProxyShardNotAvailable:
case NTxProxy::TResultStatus::EStatus::CoordinatorDeclined:
case NTxProxy::TResultStatus::EStatus::CoordinatorAborted:
case NTxProxy::TResultStatus::EStatus::CoordinatorOutdated:
- return true;
- default:
- break;
- };
- break;
- };
- return false;
-}
-
+ return true;
+ default:
+ break;
+ };
+ break;
+ };
+ return false;
+}
+
TString TError::GetCode() const {
- switch(Facility) {
- case EFacility::FacilityMessageBus:
- return Sprintf("MB-%04" PRIu16, Code);
- case EFacility::FacilityExecutionEngine:
- return Sprintf("EE-%04" PRIu16, Code);
- case EFacility::FacilityTxProxy:
- return Sprintf("TX-%04" PRIu16, Code);
- case EFacility::FacilityMsgBusProxy:
- return Sprintf("MP-%04" PRIu16, Code);
- }
+ switch(Facility) {
+ case EFacility::FacilityMessageBus:
+ return Sprintf("MB-%04" PRIu16, Code);
+ case EFacility::FacilityExecutionEngine:
+ return Sprintf("EE-%04" PRIu16, Code);
+ case EFacility::FacilityTxProxy:
+ return Sprintf("TX-%04" PRIu16, Code);
+ case EFacility::FacilityMsgBusProxy:
+ return Sprintf("MP-%04" PRIu16, Code);
+ }
return TString();
-}
-
+}
+
TString TError::GetMessage() const {
- if (!Message.empty())
- return Message;
- switch(Facility) {
- case EFacility::FacilityMessageBus:
- return NBus::MessageStatusDescription((NBus::EMessageStatus)Code);
- case EFacility::FacilityExecutionEngine:
+ if (!Message.empty())
+ return Message;
+ switch(Facility) {
+ case EFacility::FacilityMessageBus:
+ return NBus::MessageStatusDescription((NBus::EMessageStatus)Code);
+ case EFacility::FacilityExecutionEngine:
switch (Code) {
case NKikimrMiniKQLEngine::Unknown:
- return "Status unknown, not filled probably";
+ return "Status unknown, not filled probably";
case NKikimrMiniKQLEngine::Ok:
- return "Success";
+ return "Success";
case NKikimrMiniKQLEngine::SchemeChanged:
- return "Scheme or partitioning was changed b/w compilation and preparation";
+ return "Scheme or partitioning was changed b/w compilation and preparation";
case NKikimrMiniKQLEngine::IsReadonly:
- return "Update requested in read-only operation";
+ return "Update requested in read-only operation";
case NKikimrMiniKQLEngine::KeyError:
- return "Something wrong in data keys";
+ return "Something wrong in data keys";
case NKikimrMiniKQLEngine::ProgramError:
- return "Malformed program";
+ return "Malformed program";
case NKikimrMiniKQLEngine::TooManyShards:
- return "Too many datashards affected by program";
+ return "Too many datashards affected by program";
case NKikimrMiniKQLEngine::TooManyData:
- return "Too much data affected by program";
+ return "Too much data affected by program";
case NKikimrMiniKQLEngine::SnapshotNotExist:
- return "Requested snapshot not exist";
+ return "Requested snapshot not exist";
case NKikimrMiniKQLEngine::SnapshotNotReady:
- return "Snapshot not online";
+ return "Snapshot not online";
case NKikimrMiniKQLEngine::TooManyRS:
- return "Too many data transfers between datashards in the program";
- }
- break;
- case EFacility::FacilityTxProxy:
- switch (Code) {
+ return "Too many data transfers between datashards in the program";
+ }
+ break;
+ case EFacility::FacilityTxProxy:
+ switch (Code) {
case NTxProxy::TResultStatus::EStatus::Unknown:
- return "Status unknown, must not be seen";
+ return "Status unknown, must not be seen";
case NTxProxy::TResultStatus::EStatus::WrongRequest:
- return "Not recognized or erroneous request, see error description fields for possible details";
+ return "Not recognized or erroneous request, see error description fields for possible details";
case NTxProxy::TResultStatus::EStatus::EmptyAffectedSet:
- return "Program must touch at least one shard but touches none";
+ return "Program must touch at least one shard but touches none";
case NTxProxy::TResultStatus::EStatus::NotImplemented:
- return "Not yet implemented feature requested";
+ return "Not yet implemented feature requested";
case NTxProxy::TResultStatus::EStatus::ResolveError:
- return "Some keys not resolved, see UnresolvedKeys for details";
+ return "Some keys not resolved, see UnresolvedKeys for details";
case NTxProxy::TResultStatus::EStatus::AccessDenied:
- return "Access denied";
+ return "Access denied";
case NTxProxy::TResultStatus::EStatus::ProxyNotReady:
return "Transaction proxy not ready for handling requests, try later. Most known case is temporary lack of txid-s";
case NTxProxy::TResultStatus::EStatus::ProxyAccepted:
- return "Request accepted by proxy. Transitional status";
+ return "Request accepted by proxy. Transitional status";
case NTxProxy::TResultStatus::EStatus::ProxyResolved:
- return "Request keys resolved to datashards. Transitional status";
+ return "Request keys resolved to datashards. Transitional status";
case NTxProxy::TResultStatus::EStatus::ProxyPrepared:
- return "Request fragmets prepared on datashards. Transitional status";
+ return "Request fragmets prepared on datashards. Transitional status";
case NTxProxy::TResultStatus::EStatus::ProxyShardNotAvailable:
- return "One or more of affected datashards not available, request execution cancelled";
+ return "One or more of affected datashards not available, request execution cancelled";
case NTxProxy::TResultStatus::EStatus::ProxyShardTryLater:
- return "One or more of affected datashards are starting, try again";
+ return "One or more of affected datashards are starting, try again";
case NTxProxy::TResultStatus::EStatus::ProxyShardOverloaded:
- return "One or more of affected datashards are overloaded, try again";
+ return "One or more of affected datashards are overloaded, try again";
case NTxProxy::TResultStatus::EStatus::CoordinatorDeclined:
- return "Coordinator declines to plan transaction, try again";
+ return "Coordinator declines to plan transaction, try again";
case NTxProxy::TResultStatus::EStatus::CoordinatorOutdated:
- return "Coordinator was not able to plan transaction due to timing restrictions, try again";
+ return "Coordinator was not able to plan transaction due to timing restrictions, try again";
case NTxProxy::TResultStatus::EStatus::CoordinatorAborted:
- return "Transaction aborted by coordinator";
+ return "Transaction aborted by coordinator";
case NTxProxy::TResultStatus::EStatus::CoordinatorPlanned:
- return "Transaction planned for execution by coordinator. Transitional status";
+ return "Transaction planned for execution by coordinator. Transitional status";
case NTxProxy::TResultStatus::EStatus::CoordinatorUnknown:
- return "Could not reach coordinator or coordinator pipe dropped before confirmation. Transaction status unknown";
+ return "Could not reach coordinator or coordinator pipe dropped before confirmation. Transaction status unknown";
case NTxProxy::TResultStatus::EStatus::ExecComplete:
- return "Success";
+ return "Success";
case NTxProxy::TResultStatus::EStatus::ExecAlready:
- return "Requested operation already applied";
+ return "Requested operation already applied";
case NTxProxy::TResultStatus::EStatus::ExecAborted:
- return "Request aborted, particular meaning depends on context";
+ return "Request aborted, particular meaning depends on context";
case NTxProxy::TResultStatus::EStatus::ExecTimeout:
- return "Proxy got no execution reply in timeout period";
+ return "Proxy got no execution reply in timeout period";
case NTxProxy::TResultStatus::EStatus::ExecError:
- return "Execution failed";
+ return "Execution failed";
case NTxProxy::TResultStatus::EStatus::ExecInProgress:
- return "Request accepted and now runs";
+ return "Request accepted and now runs";
case NTxProxy::TResultStatus::EStatus::ExecResultUnavailable:
return "Execution result unavailable.";
- };
- break;
- case EFacility::FacilityMsgBusProxy:
- return NMsgBusProxy::ToCString((NMsgBusProxy::EResponseStatus)Code);
- }
- return "";
-}
-
-void TError::Throw() const {
- if (Error())
- throw yexception() << GetCode() << " " << GetMessage();
-}
-
-TError::TError(const TResult& result)
- : Facility(EFacility::FacilityMessageBus)
- , Code(NBus::MESSAGE_OK)
+ };
+ break;
+ case EFacility::FacilityMsgBusProxy:
+ return NMsgBusProxy::ToCString((NMsgBusProxy::EResponseStatus)Code);
+ }
+ return "";
+}
+
+void TError::Throw() const {
+ if (Error())
+ throw yexception() << GetCode() << " " << GetMessage();
+}
+
+TError::TError(const TResult& result)
+ : Facility(EFacility::FacilityMessageBus)
+ , Code(NBus::MESSAGE_OK)
, YdbStatus(Ydb::StatusIds::STATUS_CODE_UNSPECIFIED)
-{
- if (result.TransportStatus != NBus::MESSAGE_OK) {
- Facility = EFacility::FacilityMessageBus;
- Code = result.TransportStatus;
+{
+ if (result.TransportStatus != NBus::MESSAGE_OK) {
+ Facility = EFacility::FacilityMessageBus;
+ Code = result.TransportStatus;
Message = result.TransportErrorMessage;
- } else {
- if (result.Reply->GetHeader()->Type == NMsgBusProxy::MTYPE_CLIENT_RESPONSE) {
+ } else {
+ if (result.Reply->GetHeader()->Type == NMsgBusProxy::MTYPE_CLIENT_RESPONSE) {
const NKikimrClient::TResponse& response = result.GetResult<NKikimrClient::TResponse>();
- if (response.HasExecutionEngineStatus()
+ if (response.HasExecutionEngineStatus()
&& response.GetExecutionEngineStatus() != NKikimrMiniKQLEngine::Ok
&& response.GetExecutionEngineStatus() != NKikimrMiniKQLEngine::Unknown) {
- Facility = EFacility::FacilityExecutionEngine;
- Code = response.GetExecutionEngineStatus();
- } else
- if (response.HasProxyErrorCode()
+ Facility = EFacility::FacilityExecutionEngine;
+ Code = response.GetExecutionEngineStatus();
+ } else
+ if (response.HasProxyErrorCode()
&& (NTxProxy::TResultStatus::EStatus)response.GetProxyErrorCode() != NTxProxy::TResultStatus::EStatus::ExecComplete
&& (NTxProxy::TResultStatus::EStatus)response.GetProxyErrorCode() != NTxProxy::TResultStatus::EStatus::Unknown) {
- Facility = EFacility::FacilityTxProxy;
- Code = response.GetProxyErrorCode();
- } else
- if (response.GetStatus() != NMsgBusProxy::MSTATUS_OK) {
- Facility = EFacility::FacilityMsgBusProxy;
- Code = response.GetStatus();
- }
- if (response.HasErrorReason()) {
- Message = response.GetErrorReason();
- }
- if (response.HasDataShardErrors()) {
- Message = response.GetDataShardErrors();
- }
- if (response.HasMiniKQLCompileResults() && response.GetMiniKQLCompileResults().ProgramCompileErrorsSize() > 0) {
+ Facility = EFacility::FacilityTxProxy;
+ Code = response.GetProxyErrorCode();
+ } else
+ if (response.GetStatus() != NMsgBusProxy::MSTATUS_OK) {
+ Facility = EFacility::FacilityMsgBusProxy;
+ Code = response.GetStatus();
+ }
+ if (response.HasErrorReason()) {
+ Message = response.GetErrorReason();
+ }
+ if (response.HasDataShardErrors()) {
+ Message = response.GetDataShardErrors();
+ }
+ if (response.HasMiniKQLCompileResults() && response.GetMiniKQLCompileResults().ProgramCompileErrorsSize() > 0) {
NYql::TIssues issues;
NYql::IssuesFromMessage(response.GetMiniKQLCompileResults().GetProgramCompileErrors(), issues);
TStringStream message;
issues.PrintTo(message);
Message = message.Str();
- }
- if (response.HasMiniKQLErrors()) {
- if (!Message.empty())
- Message += '\n';
- Message += response.GetMiniKQLErrors();
- }
- }
- }
-}
-
-TError::EFacility TError::GetFacility() const {
- return Facility;
-}
-
+ }
+ if (response.HasMiniKQLErrors()) {
+ if (!Message.empty())
+ Message += '\n';
+ Message += response.GetMiniKQLErrors();
+ }
+ }
+ }
+}
+
+TError::EFacility TError::GetFacility() const {
+ return Facility;
+}
+
Ydb::StatusIds::StatusCode TError::GetYdbStatus() const {
return YdbStatus;
-}
+}
-}
+}
}
diff --git a/ydb/public/lib/deprecated/kicli/kicli.h b/ydb/public/lib/deprecated/kicli/kicli.h
index 0a16649ad56..9dc472d2314 100644
--- a/ydb/public/lib/deprecated/kicli/kicli.h
+++ b/ydb/public/lib/deprecated/kicli/kicli.h
@@ -1,4 +1,4 @@
-#pragma once
+#pragma once
#include <ydb/core/protos/kqp.pb.h>
#include <ydb/core/protos/msgbus.pb.h>
@@ -8,7 +8,7 @@
#include <ydb/public/lib/base/msgbus_status.h>
#include <ydb/public/lib/scheme_types/scheme_type_id.h>
#include <ydb/public/lib/value/value.h>
-
+
#include <library/cpp/actors/core/interconnect.h>
#include <library/cpp/messagebus/message_status.h>
#include <library/cpp/messagebus/message.h>
@@ -28,37 +28,37 @@ namespace NBus {
class TBusBufferMessage;
}
-namespace NKikimr {
+namespace NKikimr {
namespace NMsgBusProxy {
class TMsgBusClient;
}
-namespace NClient {
-
-class TResult;
-class TQueryResult;
-class TPrepareResult;
-class TSchemaObject;
-class TQuery;
-class TTextQuery;
-class TPreparedQuery;
-class TUnbindedQuery;
-class TRetryQueue;
-class TKikimr;
-
+namespace NClient {
+
+class TResult;
+class TQueryResult;
+class TPrepareResult;
+class TSchemaObject;
+class TQuery;
+class TTextQuery;
+class TPreparedQuery;
+class TUnbindedQuery;
+class TRetryQueue;
+class TKikimr;
+
using TTablePartitionConfig = NKikimrSchemeOp::TPartitionConfig;
using TModifyScheme = NKikimrSchemeOp::TModifyScheme;
-class TType {
-public:
- static const TType Int64;
- static const TType Uint64;
- static const TType Int32;
- static const TType Uint32;
- static const TType Double;
- static const TType Float;
- static const TType Bool;
+class TType {
+public:
+ static const TType Int64;
+ static const TType Uint64;
+ static const TType Int32;
+ static const TType Uint32;
+ static const TType Double;
+ static const TType Float;
+ static const TType Bool;
static const TType Utf8;
static const TType String;
static const TType String4k;
@@ -67,311 +67,311 @@ public:
static const TType Json;
static const TType JsonDocument;
static const TType Timestamp;
-
+
const TString& GetName() const;
- ui16 GetId() const;
-
+ ui16 GetId() const;
+
TType(const TString& typeName, ui16 typeId);
- TType(ui16 typeId);
-
-protected:
+ TType(ui16 typeId);
+
+protected:
TString TypeName;
- ui16 TypeId;
-};
-
-class TColumn {
- friend class TSchemaObject;
-public:
+ ui16 TypeId;
+};
+
+class TColumn {
+ friend class TSchemaObject;
+public:
TString Name;
TType Type;
bool Key;
ui32 Partitions;
-
- // generic column of a table, used in schema operations
+
+ // generic column of a table, used in schema operations
TColumn(const TString& name, const TType& type);
-
-protected:
+
+protected:
TColumn(const TString& name, const TType& type, bool key, ui32 partitions);
-};
-
-class TKeyColumn : public TColumn {
-public:
- // column which automatically will be added to table key
+};
+
+class TKeyColumn : public TColumn {
+public:
+ // column which automatically will be added to table key
TKeyColumn(const TString& name, const TType& type);
-
-protected:
+
+protected:
TKeyColumn(const TString& name, const TType& type, ui32 partitions);
-};
-
-class TKeyPartitioningColumn : public TKeyColumn {
-public:
- // uniform partitioning column, the type should be either Uint64 or Uint32
- // the column should be first in a create table's list
+};
+
+class TKeyPartitioningColumn : public TKeyColumn {
+public:
+ // uniform partitioning column, the type should be either Uint64 or Uint32
+ // the column should be first in a create table's list
TKeyPartitioningColumn(const TString& name, const TType& type, ui32 partitions);
-};
-
-template <typename MemberType>
-class TStructMemberValue {
-public:
+};
+
+template <typename MemberType>
+class TStructMemberValue {
+public:
TString Name;
- MemberType Value;
-
+ MemberType Value;
+
explicit TStructMemberValue(const TString& name, MemberType value)
- : Name(name)
- , Value(value)
- {}
-
- void StoreType(NKikimrMiniKQL::TStructType& type) const {
- auto& member = *type.AddMember();
- member.SetName(Name);
- auto& memberType = *member.MutableType();
- Value.StoreType(memberType);
- }
-
- void StoreValue(NKikimrMiniKQL::TValue& value) const {
- auto& structValue = *value.AddStruct();
- Value.StoreValue(structValue);
- }
-};
-
-template <typename... MemberTypes>
-class TStructValue {
-public:
- std::tuple<MemberTypes...> Members;
-
- TStructValue(MemberTypes... members)
- : Members(members...)
- {}
-
- void StoreType(NKikimrMiniKQL::TType& type) const {
- type.SetKind(NKikimrMiniKQL::ETypeKind::Struct);
- auto& structType = *type.MutableStruct();
+ : Name(name)
+ , Value(value)
+ {}
+
+ void StoreType(NKikimrMiniKQL::TStructType& type) const {
+ auto& member = *type.AddMember();
+ member.SetName(Name);
+ auto& memberType = *member.MutableType();
+ Value.StoreType(memberType);
+ }
+
+ void StoreValue(NKikimrMiniKQL::TValue& value) const {
+ auto& structValue = *value.AddStruct();
+ Value.StoreValue(structValue);
+ }
+};
+
+template <typename... MemberTypes>
+class TStructValue {
+public:
+ std::tuple<MemberTypes...> Members;
+
+ TStructValue(MemberTypes... members)
+ : Members(members...)
+ {}
+
+ void StoreType(NKikimrMiniKQL::TType& type) const {
+ type.SetKind(NKikimrMiniKQL::ETypeKind::Struct);
+ auto& structType = *type.MutableStruct();
StoreMembersTypes(structType, std::make_index_sequence<sizeof...(MemberTypes)>());
- }
-
- void StoreValue(NKikimrMiniKQL::TValue& value) const {
+ }
+
+ void StoreValue(NKikimrMiniKQL::TValue& value) const {
StoreMembersValues(value, std::make_index_sequence<sizeof...(MemberTypes)>());
- }
-
-protected:
- static void StoreMemberType(NKikimrMiniKQL::TStructType&) {}
- static void StoreMemberValue(NKikimrMiniKQL::TValue&) {}
-
- template <typename MemberType, typename... OtherMemberTypes>
- static void StoreMemberType(NKikimrMiniKQL::TStructType& type, const MemberType& member, OtherMemberTypes... others) {
- member.StoreType(type);
- StoreMemberType(type, others...);
- }
-
- template <typename MemberType, typename... OtherMemberTypes>
- static void StoreMemberValue(NKikimrMiniKQL::TValue& value, const MemberType& member, OtherMemberTypes... others) {
- member.StoreValue(value);
- StoreMemberValue(value, others...);
- }
-
- template <std::size_t... N>
+ }
+
+protected:
+ static void StoreMemberType(NKikimrMiniKQL::TStructType&) {}
+ static void StoreMemberValue(NKikimrMiniKQL::TValue&) {}
+
+ template <typename MemberType, typename... OtherMemberTypes>
+ static void StoreMemberType(NKikimrMiniKQL::TStructType& type, const MemberType& member, OtherMemberTypes... others) {
+ member.StoreType(type);
+ StoreMemberType(type, others...);
+ }
+
+ template <typename MemberType, typename... OtherMemberTypes>
+ static void StoreMemberValue(NKikimrMiniKQL::TValue& value, const MemberType& member, OtherMemberTypes... others) {
+ member.StoreValue(value);
+ StoreMemberValue(value, others...);
+ }
+
+ template <std::size_t... N>
void StoreMembersTypes(NKikimrMiniKQL::TStructType& type, std::index_sequence<N...>) const {
- StoreMemberType(type, std::get<N>(Members)...);
- }
-
- template <std::size_t... N>
+ StoreMemberType(type, std::get<N>(Members)...);
+ }
+
+ template <std::size_t... N>
void StoreMembersValues(NKikimrMiniKQL::TValue& value, std::index_sequence<N...>) const {
- StoreMemberValue(value, std::get<N>(Members)...);
- }
-};
-
-template <typename ValueType, bool HaveValue = true>
-class TOptionalValue {
-public:
- ValueType Value;
-
- TOptionalValue(ValueType value)
- : Value(value)
- {}
-
- void StoreType(NKikimrMiniKQL::TType& type) const {
- type.SetKind(NKikimrMiniKQL::ETypeKind::Optional);
- auto& optionalType = *type.MutableOptional()->MutableItem();
- Value.StoreType(optionalType);
- }
-
- void StoreValue(NKikimrMiniKQL::TValue& value) const {
- auto& optionalValue = *value.MutableOptional();
- if (HaveValue) {
- Value.StoreValue(optionalValue);
- }
- }
-};
-
-// for compatibility
+ StoreMemberValue(value, std::get<N>(Members)...);
+ }
+};
+
+template <typename ValueType, bool HaveValue = true>
+class TOptionalValue {
+public:
+ ValueType Value;
+
+ TOptionalValue(ValueType value)
+ : Value(value)
+ {}
+
+ void StoreType(NKikimrMiniKQL::TType& type) const {
+ type.SetKind(NKikimrMiniKQL::ETypeKind::Optional);
+ auto& optionalType = *type.MutableOptional()->MutableItem();
+ Value.StoreType(optionalType);
+ }
+
+ void StoreValue(NKikimrMiniKQL::TValue& value) const {
+ auto& optionalValue = *value.MutableOptional();
+ if (HaveValue) {
+ Value.StoreValue(optionalValue);
+ }
+ }
+};
+
+// for compatibility
template <typename ParameterType, NScheme::TTypeId SchemeType = SchemeMapper<ParameterType>::SchemeType>
-class TParameterValue : public TStructMemberValue<TDataValue<ParameterType, SchemeType>> {
-public:
+class TParameterValue : public TStructMemberValue<TDataValue<ParameterType, SchemeType>> {
+public:
TParameterValue(const TString& name, ParameterType parameter)
- : TStructMemberValue<TDataValue<ParameterType, SchemeType>>(name, TDataValue<ParameterType, SchemeType>(parameter))
- {}
-};
-
-template <typename DataType>
-TDataValue<DataType> TData(DataType value) {
- return TDataValue<DataType>(value);
-}
-
-template <typename MemberType>
+ : TStructMemberValue<TDataValue<ParameterType, SchemeType>>(name, TDataValue<ParameterType, SchemeType>(parameter))
+ {}
+};
+
+template <typename DataType>
+TDataValue<DataType> TData(DataType value) {
+ return TDataValue<DataType>(value);
+}
+
+template <typename MemberType>
TStructMemberValue<MemberType> TStructMember(const TString& name, MemberType value) {
- return TStructMemberValue<MemberType>(name, value);
-}
-
-template <typename... MemberTypes>
-TStructValue<MemberTypes...> TStruct(MemberTypes... members) {
- return TStructValue<MemberTypes...>(members...);
-}
-
-template <typename ValueType>
-TOptionalValue<ValueType> TOptional(ValueType value) {
- return TOptionalValue<ValueType>(value);
-}
-
-template <typename ValueType>
-TOptionalValue<ValueType, false> TEmptyOptional(ValueType value = ValueType()) {
- return TOptionalValue<ValueType, false>(value);
-}
-
-// syntax helpers
-// TParameter(name, value) = TStructMemberValue(name, TDataValue(value))
-
-template <typename ParameterType>
+ return TStructMemberValue<MemberType>(name, value);
+}
+
+template <typename... MemberTypes>
+TStructValue<MemberTypes...> TStruct(MemberTypes... members) {
+ return TStructValue<MemberTypes...>(members...);
+}
+
+template <typename ValueType>
+TOptionalValue<ValueType> TOptional(ValueType value) {
+ return TOptionalValue<ValueType>(value);
+}
+
+template <typename ValueType>
+TOptionalValue<ValueType, false> TEmptyOptional(ValueType value = ValueType()) {
+ return TOptionalValue<ValueType, false>(value);
+}
+
+// syntax helpers
+// TParameter(name, value) = TStructMemberValue(name, TDataValue(value))
+
+template <typename ParameterType>
TParameterValue<ParameterType, SchemeMapper<ParameterType>::SchemeType> TParameter(const TString& name, ParameterType value) {
- return TParameterValue<ParameterType, SchemeMapper<ParameterType>::SchemeType>(name, value);
-}
-
-template <typename... MemberTypes>
+ return TParameterValue<ParameterType, SchemeMapper<ParameterType>::SchemeType>(name, value);
+}
+
+template <typename... MemberTypes>
TStructMemberValue<TStructValue<MemberTypes...>> TParameter(const TString& name, TStructValue<MemberTypes...> value) {
- return TStructMemberValue<TStructValue<MemberTypes...>>(name, value);
-}
-
-template <typename ValueType, bool HaveValue>
+ return TStructMemberValue<TStructValue<MemberTypes...>>(name, value);
+}
+
+template <typename ValueType, bool HaveValue>
TStructMemberValue<TOptionalValue<ValueType, HaveValue>> TParameter(const TString& name, TOptionalValue<ValueType, HaveValue> value) {
- return TStructMemberValue<TOptionalValue<ValueType, HaveValue>>(name, value);
-}
-
-
-class TParameters : public NKikimrMiniKQL::TParams, public TWriteValue {
- friend class TTextQuery;
- friend class TPreparedQuery;
-public:
- TParameters() : TWriteValue(*MutableValue(), *MutableType()) {}
-};
-
-class TError {
- friend class TResult;
-public:
- enum class EFacility : ui16 {
- FacilityMessageBus,
- FacilityExecutionEngine,
- FacilityTxProxy,
+ return TStructMemberValue<TOptionalValue<ValueType, HaveValue>>(name, value);
+}
+
+
+class TParameters : public NKikimrMiniKQL::TParams, public TWriteValue {
+ friend class TTextQuery;
+ friend class TPreparedQuery;
+public:
+ TParameters() : TWriteValue(*MutableValue(), *MutableType()) {}
+};
+
+class TError {
+ friend class TResult;
+public:
+ enum class EFacility : ui16 {
+ FacilityMessageBus,
+ FacilityExecutionEngine,
+ FacilityTxProxy,
FacilityMsgBusProxy,
- };
-
+ };
+
TError() = default;
TError(TError&&) = default;
TError(const TError&) = default;
TError& operator = (TError&&) = default;
TError& operator = (const TError&) = default;
- bool Success() const;
- bool Error() const { return !Success(); }
- bool Permanent() const;
- bool Temporary() const { return !Permanent(); }
- bool Timeout() const;
- bool Rejected() const;
+ bool Success() const;
+ bool Error() const { return !Success(); }
+ bool Permanent() const;
+ bool Temporary() const { return !Permanent(); }
+ bool Timeout() const;
+ bool Rejected() const;
TString GetCode() const;
TString GetMessage() const;
- void Throw() const;
- EFacility GetFacility() const;
+ void Throw() const;
+ EFacility GetFacility() const;
// Returns YDB status
Ydb::StatusIds::StatusCode GetYdbStatus() const;
-
-protected:
- TError(const TResult& result);
- NMsgBusProxy::EResponseStatus GetMsgBusProxyStatus() const;
-
+
+protected:
+ TError(const TResult& result);
+ NMsgBusProxy::EResponseStatus GetMsgBusProxyStatus() const;
+
TString Message;
- EFacility Facility;
- ui16 Code;
+ EFacility Facility;
+ ui16 Code;
Ydb::StatusIds::StatusCode YdbStatus;
-};
-
+};
+
/// Owns query result data
-class TResult {
- // generic polymorphic result of server request
- // supports many different run-time conversions with error checking
- friend class TKikimr;
- friend class TSchemaObject;
- friend class TError;
- friend class TRetryQueue;
-public:
+class TResult {
+ // generic polymorphic result of server request
+ // supports many different run-time conversions with error checking
+ friend class TKikimr;
+ friend class TSchemaObject;
+ friend class TError;
+ friend class TRetryQueue;
+public:
TResult(TResult&&) = default;
TResult(const TResult&) = default;
TResult& operator = (TResult&&) = default;
TResult& operator = (const TResult&) = default;
- // status of the operation
- NMsgBusProxy::EResponseStatus GetStatus() const;
- // detailed error of the operation
- TError GetError() const;
- // mostly for internal use
- ui16 GetType() const;
- template <typename T>
- const T& GetResult() const; // protobuf record
-
- template <typename T>
- bool HaveResponse() const { // msgbus event
- return Reply.Get()->GetHeader()->Type == T::MessageType;
- }
-
- template <typename T>
- const T& GetResponse() const { // msgbus event
- Y_VERIFY(HaveResponse<T>());
- return *static_cast<T*>(Reply.Get());
- }
-
+ // status of the operation
+ NMsgBusProxy::EResponseStatus GetStatus() const;
+ // detailed error of the operation
+ TError GetError() const;
+ // mostly for internal use
+ ui16 GetType() const;
+ template <typename T>
+ const T& GetResult() const; // protobuf record
+
+ template <typename T>
+ bool HaveResponse() const { // msgbus event
+ return Reply.Get()->GetHeader()->Type == T::MessageType;
+ }
+
+ template <typename T>
+ const T& GetResponse() const { // msgbus event
+ Y_VERIFY(HaveResponse<T>());
+ return *static_cast<T*>(Reply.Get());
+ }
+
NBus::EMessageStatus GetTransportStatus() const {
return TransportStatus;
}
-protected:
- TResult(NBus::EMessageStatus transportStatus);
+protected:
+ TResult(NBus::EMessageStatus transportStatus);
TResult(NBus::EMessageStatus transportStatus, const TString& message);
- TResult(TAutoPtr<NBus::TBusMessage> reply);
-
- NBus::EMessageStatus TransportStatus;
+ TResult(TAutoPtr<NBus::TBusMessage> reply);
+
+ NBus::EMessageStatus TransportStatus;
TString TransportErrorMessage;
TAtomicSharedPtr<NBus::TBusMessage> Reply;
-};
-
-class TQueryResult : public TResult {
- friend class TKikimr;
+};
+
+class TQueryResult : public TResult {
+ friend class TKikimr;
friend class TTextQuery;
friend class TPreparedQuery;
-public:
+public:
TQueryResult(TQueryResult&&) = default;
TQueryResult(const TQueryResult&) = default;
TQueryResult& operator = (TQueryResult&&) = default;
TQueryResult& operator = (const TQueryResult&) = default;
- // two different ways are available to get content of the query result:
+ // two different ways are available to get content of the query result:
// (1) it could be converted to use with minikql_result_lib @sa NResultLib::ConvertResult
- // (2) or used with built-in TValue class
- TValue GetValue() const;
- // (1) strict and detailed
- // (2) easy
-
-protected:
- TQueryResult(const TResult& result);
-};
-
+ // (2) or used with built-in TValue class
+ TValue GetValue() const;
+ // (1) strict and detailed
+ // (2) easy
+
+protected:
+ TQueryResult(const TResult& result);
+};
+
class TReadTableResult : public TResult {
friend class TTableStream;
public:
@@ -399,170 +399,170 @@ protected:
mutable bool Parsed = false;
};
-class TPrepareResult : public TResult {
- friend class TKikimr;
+class TPrepareResult : public TResult {
+ friend class TKikimr;
friend class TTextQuery;
-public:
+public:
TPrepareResult(TPrepareResult&&) = default;
TPrepareResult(const TPrepareResult&) = default;
TPrepareResult& operator = (TPrepareResult&&) = default;
TPrepareResult& operator = (const TPrepareResult&) = default;
- TPreparedQuery GetQuery() const;
-
-protected:
- TPrepareResult(const TResult& result, const TQuery& query);
-
- const TQuery* Query;
-};
-
-class TQuery {
- // base class for KiKiMR DB query
- friend class TKikimr;
- friend class TTextQuery;
- friend class TPreparedQuery;
-public:
- TQuery(TQuery&&) = default;
+ TPreparedQuery GetQuery() const;
+
+protected:
+ TPrepareResult(const TResult& result, const TQuery& query);
+
+ const TQuery* Query;
+};
+
+class TQuery {
+ // base class for KiKiMR DB query
+ friend class TKikimr;
+ friend class TTextQuery;
+ friend class TPreparedQuery;
+public:
+ TQuery(TQuery&&) = default;
TQuery& operator = (TQuery&&) = default;
TQuery& operator = (const TQuery&) = delete;
-
- template <typename... ParametersType> static void StoreParameters(NKikimrMiniKQL::TParams& params, const ParametersType&... parameters) {
- TStructValue<ParametersType...> structValue(parameters...);
- auto& type = *params.MutableType();
- auto& value = *params.MutableValue();
- structValue.StoreType(type);
- structValue.StoreValue(value);
- }
-
+
+ template <typename... ParametersType> static void StoreParameters(NKikimrMiniKQL::TParams& params, const ParametersType&... parameters) {
+ TStructValue<ParametersType...> structValue(parameters...);
+ auto& type = *params.MutableType();
+ auto& value = *params.MutableValue();
+ structValue.StoreType(type);
+ structValue.StoreValue(value);
+ }
+
static void ParseTextParameters(NKikimrMiniKQL::TParams& params, const TString& parameters);
-protected:
+protected:
TQuery(const TQuery&) = default;
- TQuery(TKikimr& kikimr);
-
- TKikimr* Kikimr;
-};
-
-class TTextQuery : public TQuery {
- // text representation of KiKiMR DB query
- // could be prepared (compiled) to use later, or run directly in text
- friend class TKikimr;
-public:
- TTextQuery(TTextQuery&&) = default;
+ TQuery(TKikimr& kikimr);
+
+ TKikimr* Kikimr;
+};
+
+class TTextQuery : public TQuery {
+ // text representation of KiKiMR DB query
+ // could be prepared (compiled) to use later, or run directly in text
+ friend class TKikimr;
+public:
+ TTextQuery(TTextQuery&&) = default;
TTextQuery& operator = (TTextQuery&&) = default;
TTextQuery(const TTextQuery&) = delete;
TTextQuery& operator = (const TTextQuery&) = delete;
-
- // prepare query using round-trip to server
- TPrepareResult SyncPrepare() const;
- NThreading::TFuture<TPrepareResult> AsyncPrepare() const;
-
- // directly execute query on the server (also one round-trip)
- template <typename... ParametersType>
- TQueryResult SyncExecute(const ParametersType&... parameters) const {
- NKikimrMiniKQL::TParams params;
- StoreParameters(params, parameters...);
- return SyncExecute(params);
- }
-
- template <typename... ParametersType>
- NThreading::TFuture<TQueryResult> AsyncExecute(const ParametersType&... parameters) const {
- NKikimrMiniKQL::TParams params;
- StoreParameters(params, parameters...);
- return AsyncExecute(params);
- }
-
- TQueryResult SyncExecute(const TParameters& parameters) const {
- return SyncExecute((const NKikimrMiniKQL::TParams&)parameters);
- }
-
- NThreading::TFuture<TQueryResult> AsyncExecute(const TParameters& parameters) const {
- return AsyncExecute((const NKikimrMiniKQL::TParams&)parameters);
- }
-
+
+ // prepare query using round-trip to server
+ TPrepareResult SyncPrepare() const;
+ NThreading::TFuture<TPrepareResult> AsyncPrepare() const;
+
+ // directly execute query on the server (also one round-trip)
+ template <typename... ParametersType>
+ TQueryResult SyncExecute(const ParametersType&... parameters) const {
+ NKikimrMiniKQL::TParams params;
+ StoreParameters(params, parameters...);
+ return SyncExecute(params);
+ }
+
+ template <typename... ParametersType>
+ NThreading::TFuture<TQueryResult> AsyncExecute(const ParametersType&... parameters) const {
+ NKikimrMiniKQL::TParams params;
+ StoreParameters(params, parameters...);
+ return AsyncExecute(params);
+ }
+
+ TQueryResult SyncExecute(const TParameters& parameters) const {
+ return SyncExecute((const NKikimrMiniKQL::TParams&)parameters);
+ }
+
+ NThreading::TFuture<TQueryResult> AsyncExecute(const TParameters& parameters) const {
+ return AsyncExecute((const NKikimrMiniKQL::TParams&)parameters);
+ }
+
TQueryResult SyncExecute(const TString& parameters) const;
NThreading::TFuture<TQueryResult> AsyncExecute(const TString& parameters) const;
-
- TQueryResult SyncExecute(const NKikimrMiniKQL::TParams& parameters) const;
- NThreading::TFuture<TQueryResult> AsyncExecute(const NKikimrMiniKQL::TParams& parameters) const;
-
+
+ TQueryResult SyncExecute(const NKikimrMiniKQL::TParams& parameters) const;
+ NThreading::TFuture<TQueryResult> AsyncExecute(const NKikimrMiniKQL::TParams& parameters) const;
+
protected:
TTextQuery(TKikimr& kikimr, const TString& program);
TString TextProgram;
-};
-
-class TUnbindedQuery {
- friend class TKikimr;
- friend class TPreparedQuery;
-public:
- TUnbindedQuery(TUnbindedQuery&&) = default;
+};
+
+class TUnbindedQuery {
+ friend class TKikimr;
+ friend class TPreparedQuery;
+public:
+ TUnbindedQuery(TUnbindedQuery&&) = default;
TUnbindedQuery& operator = (TUnbindedQuery&&) = default;
TUnbindedQuery(const TUnbindedQuery&) = delete;
TUnbindedQuery& operator = (const TUnbindedQuery&) = delete;
-
-protected:
+
+protected:
TUnbindedQuery(const TString& program);
-
+
TString CompiledProgram;
-};
-
-class TPreparedQuery : public TQuery {
- // binary (compiled) representation of KiKiMR DB query
- // could be stored for use later
- friend class TKikimr;
- friend class TPrepareResult;
-public:
- TPreparedQuery(TPreparedQuery&&) = default;
+};
+
+class TPreparedQuery : public TQuery {
+ // binary (compiled) representation of KiKiMR DB query
+ // could be stored for use later
+ friend class TKikimr;
+ friend class TPrepareResult;
+public:
+ TPreparedQuery(TPreparedQuery&&) = default;
TPreparedQuery& operator = (TPreparedQuery&&) = default;
TPreparedQuery(const TPreparedQuery&) = delete;
TPreparedQuery& operator = (const TPreparedQuery&) = delete;
-
- // execute query on the server (also one round-trip)
- template <typename... ParametersType>
- TQueryResult SyncExecute(const ParametersType&... parameters) const {
- NKikimrMiniKQL::TParams params;
- StoreParameters(params, parameters...);
- return SyncExecute(params);
- }
-
- template <typename... ParametersType>
- NThreading::TFuture<TQueryResult> AsyncExecute(const ParametersType&... parameters) const {
- NKikimrMiniKQL::TParams params;
- StoreParameters(params, parameters...);
- return AsyncExecute(params);
- }
-
- TQueryResult SyncExecute(const TParameters& parameters) const {
- return SyncExecute((const NKikimrMiniKQL::TParams&)parameters);
- }
-
- NThreading::TFuture<TQueryResult> AsyncExecute(const TParameters& parameters) const {
- return AsyncExecute((const NKikimrMiniKQL::TParams&)parameters);
- }
-
+
+ // execute query on the server (also one round-trip)
+ template <typename... ParametersType>
+ TQueryResult SyncExecute(const ParametersType&... parameters) const {
+ NKikimrMiniKQL::TParams params;
+ StoreParameters(params, parameters...);
+ return SyncExecute(params);
+ }
+
+ template <typename... ParametersType>
+ NThreading::TFuture<TQueryResult> AsyncExecute(const ParametersType&... parameters) const {
+ NKikimrMiniKQL::TParams params;
+ StoreParameters(params, parameters...);
+ return AsyncExecute(params);
+ }
+
+ TQueryResult SyncExecute(const TParameters& parameters) const {
+ return SyncExecute((const NKikimrMiniKQL::TParams&)parameters);
+ }
+
+ NThreading::TFuture<TQueryResult> AsyncExecute(const TParameters& parameters) const {
+ return AsyncExecute((const NKikimrMiniKQL::TParams&)parameters);
+ }
+
TQueryResult SyncExecute(const TString& parameters) const;
NThreading::TFuture<TQueryResult> AsyncExecute(const TString& parameters) const;
-
+
TQueryResult SyncExecute(const NKikimrMiniKQL::TParams& parameters) const;
NThreading::TFuture<TQueryResult> AsyncExecute(const NKikimrMiniKQL::TParams& parameters) const;
- TUnbindedQuery Unbind() const;
-
-protected:
+ TUnbindedQuery Unbind() const;
+
+protected:
TPreparedQuery(const TQuery& textQuery, const TString& program);
-
+
TString CompiledProgram;
-};
-
-struct TSchemaObjectStats {
- ui32 PartitionsCount;
-};
-
-class TSchemaObject {
- // KiKiMR DB schema object, used for schema construction and initialization
- friend class TKikimr;
-public:
+};
+
+struct TSchemaObjectStats {
+ ui32 PartitionsCount;
+};
+
+class TSchemaObject {
+ // KiKiMR DB schema object, used for schema construction and initialization
+ friend class TKikimr;
+public:
/// @sa NKikimrSchemeOp::EPathType
enum class EPathType : ui32 {
Unknown = 0,
@@ -595,27 +595,27 @@ public:
TString GetPath() const;
TVector<TSchemaObject> GetChildren() const;
TVector<TColumn> GetColumns() const;
- TSchemaObjectStats GetStats() const;
-
+ TSchemaObjectStats GetStats() const;
+
EPathType GetPathType() const { return PathType; }
bool IsDirectory() const { return PathType == EPathType::Directory; }
bool IsTable() const { return PathType == EPathType::Table; }
bool IsPersQueueGroup() const { return PathType == EPathType::PersQueueGroup; }
-protected:
+protected:
TSchemaObject(TKikimr& kikimr, const TString& path, const TString& name, ui64 pathId = 0,
EPathType pathType = EPathType::Unknown);
-
+
TSchemaObject DoCreateTable(const TString& name, const TVector<TColumn>& columns,
const TTablePartitionConfig* partitionConfig);
- TKikimr& Kikimr;
+ TKikimr& Kikimr;
TString Path;
TString Name;
ui64 PathId;
EPathType PathType;
-};
-
+};
+
class TRegistrationResult : public TResult {
friend class TNodeRegistrant;
public:
@@ -703,7 +703,7 @@ private:
TKikimr* Kikimr;
};
-struct TRetryPolicy {
+struct TRetryPolicy {
ui32 RetryLimitCount;
TDuration MinRetryTime;
TDuration MaxRetryTime;
@@ -719,77 +719,77 @@ struct TRetryPolicy {
{}
};
-struct TConnectionPolicy {
- TRetryPolicy RetryPolicy;
- bool ChooseProxy; // use to switch from primary connection endpoint to any available proxy upon first connection (balancer strategy)
-
- TConnectionPolicy()
- : RetryPolicy(2, TDuration::MilliSeconds(500), TDuration::Seconds(1), 2, true)
- , ChooseProxy(false)
- {}
-
- TConnectionPolicy(const TRetryPolicy& retryPolicy)
- : RetryPolicy(retryPolicy)
- , ChooseProxy(false)
- {}
-};
-
-class TKikimr {
- friend class TQuery;
- friend class TTextQuery;
- friend class TPreparedQuery;
- friend class TSchemaObject;
+struct TConnectionPolicy {
+ TRetryPolicy RetryPolicy;
+ bool ChooseProxy; // use to switch from primary connection endpoint to any available proxy upon first connection (balancer strategy)
+
+ TConnectionPolicy()
+ : RetryPolicy(2, TDuration::MilliSeconds(500), TDuration::Seconds(1), 2, true)
+ , ChooseProxy(false)
+ {}
+
+ TConnectionPolicy(const TRetryPolicy& retryPolicy)
+ : RetryPolicy(retryPolicy)
+ , ChooseProxy(false)
+ {}
+};
+
+class TKikimr {
+ friend class TQuery;
+ friend class TTextQuery;
+ friend class TPreparedQuery;
+ friend class TSchemaObject;
friend class TNodeRegistrant;
friend class TNodeConfigurator;
- class TImpl;
- class TMsgBusImpl;
- class TGRpcImpl;
- class TRetryQueue;
-public:
- static ui32 POLLING_TIMEOUT; // Polling timeout used during long-polling of long datashard/schemeshard commands = 10000;
- static bool DUMP_REQUESTS; // Dump all request and responds to stderr = false;
-
- // primary interface class to KiKiMR, producer of Queries and SchemaObjects
- // the only, who handles MsgBus interface
- TKikimr(const NMsgBusProxy::TMsgBusClientConfig& clientConfig, const TConnectionPolicy& policy = TConnectionPolicy());
- TKikimr(const NGRpcProxy::TGRpcClientConfig& clientConfig, const TConnectionPolicy& policy = TConnectionPolicy());
- TKikimr(TKikimr&& kikimr);
+ class TImpl;
+ class TMsgBusImpl;
+ class TGRpcImpl;
+ class TRetryQueue;
+public:
+ static ui32 POLLING_TIMEOUT; // Polling timeout used during long-polling of long datashard/schemeshard commands = 10000;
+ static bool DUMP_REQUESTS; // Dump all request and responds to stderr = false;
+
+ // primary interface class to KiKiMR, producer of Queries and SchemaObjects
+ // the only, who handles MsgBus interface
+ TKikimr(const NMsgBusProxy::TMsgBusClientConfig& clientConfig, const TConnectionPolicy& policy = TConnectionPolicy());
+ TKikimr(const NGRpcProxy::TGRpcClientConfig& clientConfig, const TConnectionPolicy& policy = TConnectionPolicy());
+ TKikimr(TKikimr&& kikimr);
~TKikimr();
TSchemaObject GetSchemaRoot(const TString& name = TString());
TSchemaObject GetSchemaObject(const TString& name);
TTextQuery Query(const TString& program);
- TPreparedQuery Query(const TUnbindedQuery& query);
- // sets security token
+ TPreparedQuery Query(const TUnbindedQuery& query);
+ // sets security token
void SetSecurityToken(const TString& securityToken);
- TString GetCurrentLocation() const;
-
+ TString GetCurrentLocation() const;
+
TNodeRegistrant GetNodeRegistrant();
TNodeConfigurator GetNodeConfigurator();
- // execute arbitrary message bus request
- template <typename RecordType, int MessageType>
- NThreading::TFuture<TResult> ExecuteRequest(NBus::TBusBufferMessage<RecordType, MessageType>* request) {
- PrepareRequest(request->Record);
- DumpRequest(request->Record);
- return ExecuteRequest(TAutoPtr<NBus::TBusMessage>(request));
- }
-
+ // execute arbitrary message bus request
+ template <typename RecordType, int MessageType>
+ NThreading::TFuture<TResult> ExecuteRequest(NBus::TBusBufferMessage<RecordType, MessageType>* request) {
+ PrepareRequest(request->Record);
+ DumpRequest(request->Record);
+ return ExecuteRequest(TAutoPtr<NBus::TBusMessage>(request));
+ }
+
// execute general message bus request
NThreading::TFuture<TResult> ExecuteRequest(TAutoPtr<NBus::TBusMessage> request);
-protected:
- NThreading::TFuture<TQueryResult> ExecuteQuery(const TTextQuery& query, const NKikimrMiniKQL::TParams& parameters);
+protected:
+ NThreading::TFuture<TQueryResult> ExecuteQuery(const TTextQuery& query, const NKikimrMiniKQL::TParams& parameters);
NThreading::TFuture<TQueryResult> ExecuteQuery(const TTextQuery& query, const TString& parameters);
- NThreading::TFuture<TQueryResult> ExecuteQuery(const TPreparedQuery& query, const NKikimrMiniKQL::TParams& parameters);
+ NThreading::TFuture<TQueryResult> ExecuteQuery(const TPreparedQuery& query, const NKikimrMiniKQL::TParams& parameters);
NThreading::TFuture<TQueryResult> ExecuteQuery(const TPreparedQuery& query, const TString& parameters);
- NThreading::TFuture<TPrepareResult> PrepareQuery(const TTextQuery& query);
- NThreading::TFuture<TResult> DescribeObject(const TSchemaObject& object);
+ NThreading::TFuture<TPrepareResult> PrepareQuery(const TTextQuery& query);
+ NThreading::TFuture<TResult> DescribeObject(const TSchemaObject& object);
NThreading::TFuture<TResult> ModifySchema(const TModifyScheme& schema);
NThreading::TFuture<TResult> MakeDirectory(const TSchemaObject& object, const TString& name);
NThreading::TFuture<TResult> CreateTable(TSchemaObject& object, const TString& name, const TVector<TColumn>& columns,
const TTablePartitionConfig* partitionConfig);
- NBus::EMessageStatus ExecuteRequestInternal(NThreading::TPromise<TResult> promise, TAutoPtr<NBus::TBusMessage> request);
+ NBus::EMessageStatus ExecuteRequestInternal(NThreading::TPromise<TResult> promise, TAutoPtr<NBus::TBusMessage> request);
NThreading::TFuture<TResult> RegisterNode(const TString& domainPath, const TString& host, ui16 port,
const TString& address, const TString& resolveHost,
const NActors::TNodeLocation& location,
@@ -800,32 +800,32 @@ protected:
const TString &nodeType,
const TString& domain,
const TString& token = TString());
-
- template <typename T> static void DumpRequest(const T& pb) {
- if (DUMP_REQUESTS) {
+
+ template <typename T> static void DumpRequest(const T& pb) {
+ if (DUMP_REQUESTS) {
TString res;
- ::google::protobuf::TextFormat::PrintToString(pb, &res);
- Cerr << "<-- " << TypeName<T>() << Endl << res << Endl;
- }
- }
-
- template <typename T> static void DumpResponse(const T& pb) {
- if (DUMP_REQUESTS) {
+ ::google::protobuf::TextFormat::PrintToString(pb, &res);
+ Cerr << "<-- " << TypeName<T>() << Endl << res << Endl;
+ }
+ }
+
+ template <typename T> static void DumpResponse(const T& pb) {
+ if (DUMP_REQUESTS) {
TString res;
- ::google::protobuf::TextFormat::PrintToString(pb, &res);
- Cerr << "--> " << TypeName<T>() << Endl << res << Endl;
- }
- }
-
- template <typename T>
- void PrepareRequest(T&) const {}
-
- void PrepareRequest(NKikimrClient::TRequest& request) const {
- if (!SecurityToken.empty()) {
- request.SetSecurityToken(SecurityToken);
- }
- }
-
+ ::google::protobuf::TextFormat::PrintToString(pb, &res);
+ Cerr << "--> " << TypeName<T>() << Endl << res << Endl;
+ }
+ }
+
+ template <typename T>
+ void PrepareRequest(T&) const {}
+
+ void PrepareRequest(NKikimrClient::TRequest& request) const {
+ if (!SecurityToken.empty()) {
+ request.SetSecurityToken(SecurityToken);
+ }
+ }
+
void PrepareRequest(NKikimrClient::TCmsRequest& request) const {
if (!SecurityToken.empty()) {
request.SetSecurityToken(SecurityToken);
@@ -844,18 +844,18 @@ protected:
}
}
- void PrepareRequest(NKikimrClient::TSchemeOperation& request) const {
- if (!SecurityToken.empty()) {
- request.SetSecurityToken(SecurityToken);
- }
- }
-
- void PrepareRequest(NKikimrClient::TWhoAmI& request) const {
- if (!SecurityToken.empty()) {
- request.SetSecurityToken(SecurityToken);
- }
- }
-
+ void PrepareRequest(NKikimrClient::TSchemeOperation& request) const {
+ if (!SecurityToken.empty()) {
+ request.SetSecurityToken(SecurityToken);
+ }
+ }
+
+ void PrepareRequest(NKikimrClient::TWhoAmI& request) const {
+ if (!SecurityToken.empty()) {
+ request.SetSecurityToken(SecurityToken);
+ }
+ }
+
void PrepareRequest(NKikimrClient::TLocalMKQL& request) const {
if (!SecurityToken.empty()) {
request.SetSecurityToken(SecurityToken);
@@ -869,8 +869,8 @@ protected:
}
TString SecurityToken;
- THolder<TImpl> Impl;
-};
-
-} // NClient
-} // NKikimr
+ THolder<TImpl> Impl;
+};
+
+} // NClient
+} // NKikimr
diff --git a/ydb/public/lib/deprecated/kicli/kikimr.cpp b/ydb/public/lib/deprecated/kicli/kikimr.cpp
index febb55f4fad..4156d72d4b3 100644
--- a/ydb/public/lib/deprecated/kicli/kikimr.cpp
+++ b/ydb/public/lib/deprecated/kicli/kikimr.cpp
@@ -1,14 +1,14 @@
-#include "kicli.h"
-
+#include "kicli.h"
+
#include <ydb/public/lib/deprecated/client/msgbus_client.h>
-#include <util/string/builder.h>
-
-namespace NKikimr {
-namespace NClient {
-
-ui32 TKikimr::POLLING_TIMEOUT = 10000;
-bool TKikimr::DUMP_REQUESTS = false;
-
+#include <util/string/builder.h>
+
+namespace NKikimr {
+namespace NClient {
+
+ui32 TKikimr::POLLING_TIMEOUT = 10000;
+bool TKikimr::DUMP_REQUESTS = false;
+
namespace {
struct TRetryState {
@@ -31,250 +31,250 @@ struct TRetryState {
}
-class TKikimr::TRetryQueue {
-protected:
- struct TQueueItem {
- TInstant Time;
- NThreading::TPromise<TResult> Promise;
- TAutoPtr<NBus::TBusMessage> Request;
-
- TQueueItem(TInstant time, NThreading::TPromise<TResult> promise, TAutoPtr<NBus::TBusMessage> request)
- : Time(time)
- , Promise(promise)
- , Request(request)
- {}
-
- bool operator <(const TQueueItem& other) const {
- return Time > other.Time;
- }
- };
-
- TKikimr::TImpl& Kikimr;
- volatile bool TimeToQuit;
- TMutex QueueMutex;
+class TKikimr::TRetryQueue {
+protected:
+ struct TQueueItem {
+ TInstant Time;
+ NThreading::TPromise<TResult> Promise;
+ TAutoPtr<NBus::TBusMessage> Request;
+
+ TQueueItem(TInstant time, NThreading::TPromise<TResult> promise, TAutoPtr<NBus::TBusMessage> request)
+ : Time(time)
+ , Promise(promise)
+ , Request(request)
+ {}
+
+ bool operator <(const TQueueItem& other) const {
+ return Time > other.Time;
+ }
+ };
+
+ TKikimr::TImpl& Kikimr;
+ volatile bool TimeToQuit;
+ TMutex QueueMutex;
TPriorityQueue<TQueueItem> Queue;
- TCondVar CondVar;
- TThread QueueThread;
-
-public:
- explicit TRetryQueue(TKikimr::TImpl& kikimr);
- ~TRetryQueue();
- void RetryQueueThread();
- void QueueRequest(NThreading::TPromise<TResult> promise, TAutoPtr<NBus::TBusMessage> request, TDuration wait);
- static void* StaticRetryQueueThread(void*);
-};
-
-class TKikimr::TImpl {
-protected:
- TConnectionPolicy ConnectionPolicy;
- TKikimr::TRetryQueue RetryQueue;
- TString MasterLocation;
- using TCleanupCallback = std::function<void()>;
- TCleanupCallback Cleanup;
-public:
- TImpl(const TConnectionPolicy& policy)
- : ConnectionPolicy(policy)
- , RetryQueue(*this)
- {}
-
+ TCondVar CondVar;
+ TThread QueueThread;
+
+public:
+ explicit TRetryQueue(TKikimr::TImpl& kikimr);
+ ~TRetryQueue();
+ void RetryQueueThread();
+ void QueueRequest(NThreading::TPromise<TResult> promise, TAutoPtr<NBus::TBusMessage> request, TDuration wait);
+ static void* StaticRetryQueueThread(void*);
+};
+
+class TKikimr::TImpl {
+protected:
+ TConnectionPolicy ConnectionPolicy;
+ TKikimr::TRetryQueue RetryQueue;
+ TString MasterLocation;
+ using TCleanupCallback = std::function<void()>;
+ TCleanupCallback Cleanup;
+public:
+ TImpl(const TConnectionPolicy& policy)
+ : ConnectionPolicy(policy)
+ , RetryQueue(*this)
+ {}
+
void OnCall(NBus::EMessageStatus status, const TString& transportErrMessage, NThreading::TPromise<TResult> promise, TAutoPtr<NBus::TBusMessage> request, TAutoPtr<NBus::TBusMessage> reply) {
- if (status != NBus::MESSAGE_OK) {
+ if (status != NBus::MESSAGE_OK) {
promise.SetValue(TResult(status, transportErrMessage));
- }
- if (status == NBus::MESSAGE_OK) {
- switch (reply->GetHeader()->Type) {
- case NMsgBusProxy::MTYPE_CLIENT_RESPONSE: {
- const NKikimrClient::TResponse& response = static_cast<NMsgBusProxy::TBusResponse*>(reply.Get())->Record;
- DumpResponse(response);
- switch (response.GetStatus()) {
- case NMsgBusProxy::MSTATUS_INPROGRESS: {
- if (response.HasFlatTxId()) {
- // long polling in progress
- TAutoPtr<NMsgBusProxy::TBusSchemeOperationStatus> statusRequest = new NMsgBusProxy::TBusSchemeOperationStatus();
- statusRequest->Record.MutableFlatTxId()->CopyFrom(response.GetFlatTxId());
- statusRequest->Record.MutablePollOptions()->SetTimeout(POLLING_TIMEOUT);
- auto status = ExecuteRequest(promise, statusRequest.Release());
- if (status != NBus::MESSAGE_OK) {
- // retry failed - set error value and leaving
- promise.SetValue(TResult(status));
- } else {
- // continue polling, cleanup Data for current request
- delete reinterpret_cast<TRetryState*>(request->Data);
- return;
- }
- }
- break;
- }
- case NMsgBusProxy::MSTATUS_REJECTED: {
- // request was rejected (overloaded?) - retrying
- TRetryState* retryState = reinterpret_cast<TRetryState*>(request->Data);
- TDuration wait;
- if (retryState->IsAllowedToRetry(wait, ConnectionPolicy.RetryPolicy)) {
- RetryQueue.QueueRequest(promise, request, wait);
- return;
- }
- break;
- }
- }
- break;
- }
- }
- }
- if (!promise.HasValue()) {
- promise.SetValue(TResult(reply));
- }
- delete reinterpret_cast<TRetryState*>(request->Data);
- }
-
- NThreading::TFuture<TResult> InternalExecute(TAutoPtr<NBus::TBusMessage> request) {
- request->Data = new TRetryState();
- auto promise = NThreading::NewPromise<TResult>();
- auto status = ExecuteRequest(promise, request);
- if (status != NBus::MESSAGE_OK)
- promise.SetValue(TResult(status));
- return promise.GetFuture();
- }
-
- NThreading::TFuture<TResult> Execute(TAutoPtr<NBus::TBusMessage> request) {
- if (ConnectionPolicy.ChooseProxy && MasterLocation.empty()) {
- MasterLocation = GetCurrentLocation();
- return Execute(new NMsgBusProxy::TBusChooseProxy).Apply([this, request](const NThreading::TFuture<TResult>& future) -> NThreading::TFuture<TResult> {
- const TResult& value(future.GetValue());
- if (value.GetError().Success()) {
- const NKikimrClient::TResponse& response = value.GetResult<NKikimrClient::TResponse>();
- TString newLocation = response.GetProxyName();
- if (!newLocation.empty() && newLocation != MasterLocation) {
- Cleanup = SwitchToLocation(response.GetProxyName());
- }
- }
- return InternalExecute(request);
- });
- }
- return InternalExecute(request);
- }
-
- virtual ~TImpl() = default;
- virtual NBus::EMessageStatus ExecuteRequest(NThreading::TPromise<TResult> promise, TAutoPtr<NBus::TBusMessage> request) = 0;
- virtual TString GetCurrentLocation() const = 0;
- virtual TCleanupCallback SwitchToLocation(const TString& location) = 0;
-};
-
-class TKikimr::TMsgBusImpl : public TKikimr::TImpl {
- TAutoPtr<NMsgBusProxy::TMsgBusClient> MsgBusClient;
-public:
- TMsgBusImpl(const NMsgBusProxy::TMsgBusClientConfig& clientConfig, const TConnectionPolicy& policy)
- : TImpl(policy)
- , MsgBusClient(new NMsgBusProxy::TMsgBusClient(clientConfig))
- {
- MsgBusClient->Init();
- }
-
- virtual NBus::EMessageStatus ExecuteRequest(NThreading::TPromise<TResult> promise, TAutoPtr<NBus::TBusMessage> request) override {
- return MsgBusClient->AsyncCall(request.Release(), [this, promise](
- NBus::EMessageStatus status,
- TAutoPtr<NBus::TBusMessage> request,
- TAutoPtr<NBus::TBusMessage> reply) mutable -> void {
+ }
+ if (status == NBus::MESSAGE_OK) {
+ switch (reply->GetHeader()->Type) {
+ case NMsgBusProxy::MTYPE_CLIENT_RESPONSE: {
+ const NKikimrClient::TResponse& response = static_cast<NMsgBusProxy::TBusResponse*>(reply.Get())->Record;
+ DumpResponse(response);
+ switch (response.GetStatus()) {
+ case NMsgBusProxy::MSTATUS_INPROGRESS: {
+ if (response.HasFlatTxId()) {
+ // long polling in progress
+ TAutoPtr<NMsgBusProxy::TBusSchemeOperationStatus> statusRequest = new NMsgBusProxy::TBusSchemeOperationStatus();
+ statusRequest->Record.MutableFlatTxId()->CopyFrom(response.GetFlatTxId());
+ statusRequest->Record.MutablePollOptions()->SetTimeout(POLLING_TIMEOUT);
+ auto status = ExecuteRequest(promise, statusRequest.Release());
+ if (status != NBus::MESSAGE_OK) {
+ // retry failed - set error value and leaving
+ promise.SetValue(TResult(status));
+ } else {
+ // continue polling, cleanup Data for current request
+ delete reinterpret_cast<TRetryState*>(request->Data);
+ return;
+ }
+ }
+ break;
+ }
+ case NMsgBusProxy::MSTATUS_REJECTED: {
+ // request was rejected (overloaded?) - retrying
+ TRetryState* retryState = reinterpret_cast<TRetryState*>(request->Data);
+ TDuration wait;
+ if (retryState->IsAllowedToRetry(wait, ConnectionPolicy.RetryPolicy)) {
+ RetryQueue.QueueRequest(promise, request, wait);
+ return;
+ }
+ break;
+ }
+ }
+ break;
+ }
+ }
+ }
+ if (!promise.HasValue()) {
+ promise.SetValue(TResult(reply));
+ }
+ delete reinterpret_cast<TRetryState*>(request->Data);
+ }
+
+ NThreading::TFuture<TResult> InternalExecute(TAutoPtr<NBus::TBusMessage> request) {
+ request->Data = new TRetryState();
+ auto promise = NThreading::NewPromise<TResult>();
+ auto status = ExecuteRequest(promise, request);
+ if (status != NBus::MESSAGE_OK)
+ promise.SetValue(TResult(status));
+ return promise.GetFuture();
+ }
+
+ NThreading::TFuture<TResult> Execute(TAutoPtr<NBus::TBusMessage> request) {
+ if (ConnectionPolicy.ChooseProxy && MasterLocation.empty()) {
+ MasterLocation = GetCurrentLocation();
+ return Execute(new NMsgBusProxy::TBusChooseProxy).Apply([this, request](const NThreading::TFuture<TResult>& future) -> NThreading::TFuture<TResult> {
+ const TResult& value(future.GetValue());
+ if (value.GetError().Success()) {
+ const NKikimrClient::TResponse& response = value.GetResult<NKikimrClient::TResponse>();
+ TString newLocation = response.GetProxyName();
+ if (!newLocation.empty() && newLocation != MasterLocation) {
+ Cleanup = SwitchToLocation(response.GetProxyName());
+ }
+ }
+ return InternalExecute(request);
+ });
+ }
+ return InternalExecute(request);
+ }
+
+ virtual ~TImpl() = default;
+ virtual NBus::EMessageStatus ExecuteRequest(NThreading::TPromise<TResult> promise, TAutoPtr<NBus::TBusMessage> request) = 0;
+ virtual TString GetCurrentLocation() const = 0;
+ virtual TCleanupCallback SwitchToLocation(const TString& location) = 0;
+};
+
+class TKikimr::TMsgBusImpl : public TKikimr::TImpl {
+ TAutoPtr<NMsgBusProxy::TMsgBusClient> MsgBusClient;
+public:
+ TMsgBusImpl(const NMsgBusProxy::TMsgBusClientConfig& clientConfig, const TConnectionPolicy& policy)
+ : TImpl(policy)
+ , MsgBusClient(new NMsgBusProxy::TMsgBusClient(clientConfig))
+ {
+ MsgBusClient->Init();
+ }
+
+ virtual NBus::EMessageStatus ExecuteRequest(NThreading::TPromise<TResult> promise, TAutoPtr<NBus::TBusMessage> request) override {
+ return MsgBusClient->AsyncCall(request.Release(), [this, promise](
+ NBus::EMessageStatus status,
+ TAutoPtr<NBus::TBusMessage> request,
+ TAutoPtr<NBus::TBusMessage> reply) mutable -> void {
OnCall(status, "", promise, request, reply);
- });
- }
-
- virtual TString GetCurrentLocation() const override {
- return MsgBusClient->GetConfig().Ip;
- }
-
- virtual TCleanupCallback SwitchToLocation(const TString& location) override {
- NMsgBusProxy::TMsgBusClientConfig config(MsgBusClient->GetConfig());
- if (config.Ip == location) {
- return TCleanupCallback();
- }
- config.Ip = location;
- TAutoPtr<NMsgBusProxy::TMsgBusClient> msgBusClient = new NMsgBusProxy::TMsgBusClient(config);
- msgBusClient->Init();
- msgBusClient.Swap(MsgBusClient);
- // we cleanup later to avoid dead lock because we are still inside callback of current client
- return [msgBusClient]() {};
- }
-};
-
-class TKikimr::TGRpcImpl : public TKikimr::TImpl {
- TAutoPtr<NGRpcProxy::TGRpcClient> GRpcClient;
-public:
- TGRpcImpl(const NGRpcProxy::TGRpcClientConfig& clientConfig, const TConnectionPolicy& policy)
- : TImpl(policy)
- , GRpcClient(new NGRpcProxy::TGRpcClient(clientConfig))
- {}
-
- template <typename RequestType, typename ResponseType = NMsgBusProxy::TBusResponse>
- NBus::EMessageStatus ExecuteGRpcRequest(
- void (NGRpcProxy::TGRpcClient::* func)(const typename RequestType::RecordType&, NGRpcProxy::TCallback<typename ResponseType::RecordType>),
- NThreading::TPromise<TResult> promise,
- TAutoPtr<NBus::TBusMessage> request) {
- RequestType* x = static_cast<RequestType*>(request.Get());
- const auto& proto = x->Record;
- auto callback = [this, request, promise](
+ });
+ }
+
+ virtual TString GetCurrentLocation() const override {
+ return MsgBusClient->GetConfig().Ip;
+ }
+
+ virtual TCleanupCallback SwitchToLocation(const TString& location) override {
+ NMsgBusProxy::TMsgBusClientConfig config(MsgBusClient->GetConfig());
+ if (config.Ip == location) {
+ return TCleanupCallback();
+ }
+ config.Ip = location;
+ TAutoPtr<NMsgBusProxy::TMsgBusClient> msgBusClient = new NMsgBusProxy::TMsgBusClient(config);
+ msgBusClient->Init();
+ msgBusClient.Swap(MsgBusClient);
+ // we cleanup later to avoid dead lock because we are still inside callback of current client
+ return [msgBusClient]() {};
+ }
+};
+
+class TKikimr::TGRpcImpl : public TKikimr::TImpl {
+ TAutoPtr<NGRpcProxy::TGRpcClient> GRpcClient;
+public:
+ TGRpcImpl(const NGRpcProxy::TGRpcClientConfig& clientConfig, const TConnectionPolicy& policy)
+ : TImpl(policy)
+ , GRpcClient(new NGRpcProxy::TGRpcClient(clientConfig))
+ {}
+
+ template <typename RequestType, typename ResponseType = NMsgBusProxy::TBusResponse>
+ NBus::EMessageStatus ExecuteGRpcRequest(
+ void (NGRpcProxy::TGRpcClient::* func)(const typename RequestType::RecordType&, NGRpcProxy::TCallback<typename ResponseType::RecordType>),
+ NThreading::TPromise<TResult> promise,
+ TAutoPtr<NBus::TBusMessage> request) {
+ RequestType* x = static_cast<RequestType*>(request.Get());
+ const auto& proto = x->Record;
+ auto callback = [this, request, promise](
const NGRpcProxy::TGrpcError* error,
- const typename ResponseType::RecordType& proto) {
- if (error) {
+ const typename ResponseType::RecordType& proto) {
+ if (error) {
OnCall(MapGrpcStatus(error->second), error->first, promise, request, nullptr);
- } else {
- auto reply = new ResponseType;
- reply->Record = proto;
+ } else {
+ auto reply = new ResponseType;
+ reply->Record = proto;
OnCall(NBus::MESSAGE_OK, "", promise, request, reply);
- }
- };
- (GRpcClient.Get()->*func)(proto, std::move(callback));
- return NBus::MESSAGE_OK;
- }
-
- virtual NBus::EMessageStatus ExecuteRequest(NThreading::TPromise<TResult> promise, TAutoPtr<NBus::TBusMessage> request) override {
- const ui32 type = request->GetHeader()->Type;
- switch(type) {
- case NMsgBusProxy::MTYPE_CLIENT_REQUEST:
- return ExecuteGRpcRequest<NMsgBusProxy::TBusRequest>(&NGRpcProxy::TGRpcClient::Request, promise, request);
- case NMsgBusProxy::MTYPE_CLIENT_FLAT_TX_REQUEST:
- return ExecuteGRpcRequest<NMsgBusProxy::TBusSchemeOperation>(&NGRpcProxy::TGRpcClient::SchemeOperation, promise, request);
- case NMsgBusProxy::MTYPE_CLIENT_FLAT_TX_STATUS_REQUEST:
- return ExecuteGRpcRequest<NMsgBusProxy::TBusSchemeOperationStatus>(&NGRpcProxy::TGRpcClient::SchemeOperationStatus, promise, request);
- case NMsgBusProxy::MTYPE_CLIENT_FLAT_DESCRIBE_REQUEST:
- return ExecuteGRpcRequest<NMsgBusProxy::TBusSchemeDescribe>(&NGRpcProxy::TGRpcClient::SchemeDescribe, promise, request);
- case NMsgBusProxy::MTYPE_CLIENT_PERSQUEUE:
- return ExecuteGRpcRequest<NMsgBusProxy::TBusPersQueue>(&NGRpcProxy::TGRpcClient::PersQueueRequest, promise, request);
- case NMsgBusProxy::MTYPE_CLIENT_SCHEME_INITROOT:
- return ExecuteGRpcRequest<NMsgBusProxy::TBusSchemeInitRoot>(&NGRpcProxy::TGRpcClient::SchemeInitRoot, promise, request);
- case NMsgBusProxy::MTYPE_CLIENT_BSADM:
- return ExecuteGRpcRequest<NMsgBusProxy::TBusBSAdm>(&NGRpcProxy::TGRpcClient::BSAdm, promise, request);
- case NMsgBusProxy::MTYPE_CLIENT_BLOB_STORAGE_CONFIG_REQUEST:
- return ExecuteGRpcRequest<NMsgBusProxy::TBusBlobStorageConfigRequest>(&NGRpcProxy::TGRpcClient::BlobStorageConfig, promise, request);
- case NMsgBusProxy::MTYPE_CLIENT_HIVE_CREATE_TABLET:
- return ExecuteGRpcRequest<NMsgBusProxy::TBusHiveCreateTablet>(&NGRpcProxy::TGRpcClient::HiveCreateTablet, promise, request);
- case NMsgBusProxy::MTYPE_CLIENT_LOCAL_ENUMERATE_TABLETS:
- return ExecuteGRpcRequest<NMsgBusProxy::TBusLocalEnumerateTablets>(&NGRpcProxy::TGRpcClient::LocalEnumerateTablets, promise, request);
- case NMsgBusProxy::MTYPE_CLIENT_KEYVALUE:
- return ExecuteGRpcRequest<NMsgBusProxy::TBusKeyValue>(&NGRpcProxy::TGRpcClient::KeyValue, promise, request);
- case NMsgBusProxy::MTYPE_CLIENT_LOCAL_MINIKQL:
- return ExecuteGRpcRequest<NMsgBusProxy::TBusTabletLocalMKQL>(&NGRpcProxy::TGRpcClient::LocalMKQL, promise, request);
- case NMsgBusProxy::MTYPE_CLIENT_LOCAL_SCHEME_TX:
- return ExecuteGRpcRequest<NMsgBusProxy::TBusTabletLocalSchemeTx>(&NGRpcProxy::TGRpcClient::LocalSchemeTx, promise, request);
- case NMsgBusProxy::MTYPE_CLIENT_TABLET_KILL_REQUEST:
- return ExecuteGRpcRequest<NMsgBusProxy::TBusTabletKillRequest>(&NGRpcProxy::TGRpcClient::TabletKillRequest, promise, request);
- case NMsgBusProxy::MTYPE_CLIENT_TABLET_STATE_REQUEST:
- return ExecuteGRpcRequest<NMsgBusProxy::TBusTabletStateRequest>(&NGRpcProxy::TGRpcClient::TabletStateRequest, promise, request);
- case NMsgBusProxy::MTYPE_CLIENT_LOAD_REQUEST:
- return ExecuteGRpcRequest<NMsgBusProxy::TBusBsTestLoadRequest>(&NGRpcProxy::TGRpcClient::BlobStorageLoadRequest, promise, request);
- case NMsgBusProxy::MTYPE_CLIENT_GET_REQUEST:
- return ExecuteGRpcRequest<NMsgBusProxy::TBusBsGetRequest>(&NGRpcProxy::TGRpcClient::BlobStorageGetRequest, promise, request);
- case NMsgBusProxy::MTYPE_CLIENT_DB_SCHEMA:
- return ExecuteGRpcRequest<NMsgBusProxy::TBusDbSchema, NMsgBusProxy::TBusDbResponse>(&NGRpcProxy::TGRpcClient::DbSchema, promise, request);
- case NMsgBusProxy::MTYPE_CLIENT_DB_OPERATION:
- return ExecuteGRpcRequest<NMsgBusProxy::TBusDbOperation, NMsgBusProxy::TBusDbResponse>(&NGRpcProxy::TGRpcClient::DbOperation, promise, request);
- case NMsgBusProxy::MTYPE_CLIENT_DB_BATCH:
- return ExecuteGRpcRequest<NMsgBusProxy::TBusDbBatch, NMsgBusProxy::TBusDbResponse>(&NGRpcProxy::TGRpcClient::DbBatch, promise, request);
- case NMsgBusProxy::MTYPE_CLIENT_NODE_REGISTRATION_REQUEST:
- return ExecuteGRpcRequest<NMsgBusProxy::TBusNodeRegistrationRequest, NMsgBusProxy::TBusNodeRegistrationResponse>(&NGRpcProxy::TGRpcClient::RegisterNode, promise, request);
- case NMsgBusProxy::MTYPE_CLIENT_CMS_REQUEST:
- return ExecuteGRpcRequest<NMsgBusProxy::TBusCmsRequest, NMsgBusProxy::TBusCmsResponse>(&NGRpcProxy::TGRpcClient::CmsRequest, promise, request);
- case NMsgBusProxy::MTYPE_CLIENT_CHOOSE_PROXY:
- return ExecuteGRpcRequest<NMsgBusProxy::TBusChooseProxy>(&NGRpcProxy::TGRpcClient::ChooseProxy, promise, request);
+ }
+ };
+ (GRpcClient.Get()->*func)(proto, std::move(callback));
+ return NBus::MESSAGE_OK;
+ }
+
+ virtual NBus::EMessageStatus ExecuteRequest(NThreading::TPromise<TResult> promise, TAutoPtr<NBus::TBusMessage> request) override {
+ const ui32 type = request->GetHeader()->Type;
+ switch(type) {
+ case NMsgBusProxy::MTYPE_CLIENT_REQUEST:
+ return ExecuteGRpcRequest<NMsgBusProxy::TBusRequest>(&NGRpcProxy::TGRpcClient::Request, promise, request);
+ case NMsgBusProxy::MTYPE_CLIENT_FLAT_TX_REQUEST:
+ return ExecuteGRpcRequest<NMsgBusProxy::TBusSchemeOperation>(&NGRpcProxy::TGRpcClient::SchemeOperation, promise, request);
+ case NMsgBusProxy::MTYPE_CLIENT_FLAT_TX_STATUS_REQUEST:
+ return ExecuteGRpcRequest<NMsgBusProxy::TBusSchemeOperationStatus>(&NGRpcProxy::TGRpcClient::SchemeOperationStatus, promise, request);
+ case NMsgBusProxy::MTYPE_CLIENT_FLAT_DESCRIBE_REQUEST:
+ return ExecuteGRpcRequest<NMsgBusProxy::TBusSchemeDescribe>(&NGRpcProxy::TGRpcClient::SchemeDescribe, promise, request);
+ case NMsgBusProxy::MTYPE_CLIENT_PERSQUEUE:
+ return ExecuteGRpcRequest<NMsgBusProxy::TBusPersQueue>(&NGRpcProxy::TGRpcClient::PersQueueRequest, promise, request);
+ case NMsgBusProxy::MTYPE_CLIENT_SCHEME_INITROOT:
+ return ExecuteGRpcRequest<NMsgBusProxy::TBusSchemeInitRoot>(&NGRpcProxy::TGRpcClient::SchemeInitRoot, promise, request);
+ case NMsgBusProxy::MTYPE_CLIENT_BSADM:
+ return ExecuteGRpcRequest<NMsgBusProxy::TBusBSAdm>(&NGRpcProxy::TGRpcClient::BSAdm, promise, request);
+ case NMsgBusProxy::MTYPE_CLIENT_BLOB_STORAGE_CONFIG_REQUEST:
+ return ExecuteGRpcRequest<NMsgBusProxy::TBusBlobStorageConfigRequest>(&NGRpcProxy::TGRpcClient::BlobStorageConfig, promise, request);
+ case NMsgBusProxy::MTYPE_CLIENT_HIVE_CREATE_TABLET:
+ return ExecuteGRpcRequest<NMsgBusProxy::TBusHiveCreateTablet>(&NGRpcProxy::TGRpcClient::HiveCreateTablet, promise, request);
+ case NMsgBusProxy::MTYPE_CLIENT_LOCAL_ENUMERATE_TABLETS:
+ return ExecuteGRpcRequest<NMsgBusProxy::TBusLocalEnumerateTablets>(&NGRpcProxy::TGRpcClient::LocalEnumerateTablets, promise, request);
+ case NMsgBusProxy::MTYPE_CLIENT_KEYVALUE:
+ return ExecuteGRpcRequest<NMsgBusProxy::TBusKeyValue>(&NGRpcProxy::TGRpcClient::KeyValue, promise, request);
+ case NMsgBusProxy::MTYPE_CLIENT_LOCAL_MINIKQL:
+ return ExecuteGRpcRequest<NMsgBusProxy::TBusTabletLocalMKQL>(&NGRpcProxy::TGRpcClient::LocalMKQL, promise, request);
+ case NMsgBusProxy::MTYPE_CLIENT_LOCAL_SCHEME_TX:
+ return ExecuteGRpcRequest<NMsgBusProxy::TBusTabletLocalSchemeTx>(&NGRpcProxy::TGRpcClient::LocalSchemeTx, promise, request);
+ case NMsgBusProxy::MTYPE_CLIENT_TABLET_KILL_REQUEST:
+ return ExecuteGRpcRequest<NMsgBusProxy::TBusTabletKillRequest>(&NGRpcProxy::TGRpcClient::TabletKillRequest, promise, request);
+ case NMsgBusProxy::MTYPE_CLIENT_TABLET_STATE_REQUEST:
+ return ExecuteGRpcRequest<NMsgBusProxy::TBusTabletStateRequest>(&NGRpcProxy::TGRpcClient::TabletStateRequest, promise, request);
+ case NMsgBusProxy::MTYPE_CLIENT_LOAD_REQUEST:
+ return ExecuteGRpcRequest<NMsgBusProxy::TBusBsTestLoadRequest>(&NGRpcProxy::TGRpcClient::BlobStorageLoadRequest, promise, request);
+ case NMsgBusProxy::MTYPE_CLIENT_GET_REQUEST:
+ return ExecuteGRpcRequest<NMsgBusProxy::TBusBsGetRequest>(&NGRpcProxy::TGRpcClient::BlobStorageGetRequest, promise, request);
+ case NMsgBusProxy::MTYPE_CLIENT_DB_SCHEMA:
+ return ExecuteGRpcRequest<NMsgBusProxy::TBusDbSchema, NMsgBusProxy::TBusDbResponse>(&NGRpcProxy::TGRpcClient::DbSchema, promise, request);
+ case NMsgBusProxy::MTYPE_CLIENT_DB_OPERATION:
+ return ExecuteGRpcRequest<NMsgBusProxy::TBusDbOperation, NMsgBusProxy::TBusDbResponse>(&NGRpcProxy::TGRpcClient::DbOperation, promise, request);
+ case NMsgBusProxy::MTYPE_CLIENT_DB_BATCH:
+ return ExecuteGRpcRequest<NMsgBusProxy::TBusDbBatch, NMsgBusProxy::TBusDbResponse>(&NGRpcProxy::TGRpcClient::DbBatch, promise, request);
+ case NMsgBusProxy::MTYPE_CLIENT_NODE_REGISTRATION_REQUEST:
+ return ExecuteGRpcRequest<NMsgBusProxy::TBusNodeRegistrationRequest, NMsgBusProxy::TBusNodeRegistrationResponse>(&NGRpcProxy::TGRpcClient::RegisterNode, promise, request);
+ case NMsgBusProxy::MTYPE_CLIENT_CMS_REQUEST:
+ return ExecuteGRpcRequest<NMsgBusProxy::TBusCmsRequest, NMsgBusProxy::TBusCmsResponse>(&NGRpcProxy::TGRpcClient::CmsRequest, promise, request);
+ case NMsgBusProxy::MTYPE_CLIENT_CHOOSE_PROXY:
+ return ExecuteGRpcRequest<NMsgBusProxy::TBusChooseProxy>(&NGRpcProxy::TGRpcClient::ChooseProxy, promise, request);
case NMsgBusProxy::MTYPE_CLIENT_SQS_REQUEST:
return ExecuteGRpcRequest<NMsgBusProxy::TBusSqsRequest, NMsgBusProxy::TBusSqsResponse>(&NGRpcProxy::TGRpcClient::SqsRequest, promise, request);
case NMsgBusProxy::MTYPE_CLIENT_S3_LISTING_REQUEST:
@@ -283,53 +283,53 @@ public:
return ExecuteGRpcRequest<NMsgBusProxy::TBusInterconnectDebug>(&NGRpcProxy::TGRpcClient::InterconnectDebug, promise, request);
case NMsgBusProxy::MTYPE_CLIENT_CONSOLE_REQUEST:
return ExecuteGRpcRequest<NMsgBusProxy::TBusConsoleRequest, NMsgBusProxy::TBusConsoleResponse>(&NGRpcProxy::TGRpcClient::ConsoleRequest, promise, request);
- case NMsgBusProxy::MTYPE_CLIENT_WHOAMI:
- return ExecuteGRpcRequest<NMsgBusProxy::TBusWhoAmI, NMsgBusProxy::TBusResponse>(&NGRpcProxy::TGRpcClient::WhoAmI, promise, request);
- case NMsgBusProxy::MTYPE_CLIENT_RESOLVE_NODE:
- return ExecuteGRpcRequest<NMsgBusProxy::TBusResolveNode, NMsgBusProxy::TBusResponse>(&NGRpcProxy::TGRpcClient::ResolveNode, promise, request);
- case NMsgBusProxy::MTYPE_CLIENT_DRAIN_NODE:
- return ExecuteGRpcRequest<NMsgBusProxy::TBusDrainNode, NMsgBusProxy::TBusResponse>(&NGRpcProxy::TGRpcClient::DrainNode, promise, request);
- case NMsgBusProxy::MTYPE_CLIENT_FILL_NODE:
- return ExecuteGRpcRequest<NMsgBusProxy::TBusFillNode, NMsgBusProxy::TBusResponse>(&NGRpcProxy::TGRpcClient::FillNode, promise, request);
- default:
+ case NMsgBusProxy::MTYPE_CLIENT_WHOAMI:
+ return ExecuteGRpcRequest<NMsgBusProxy::TBusWhoAmI, NMsgBusProxy::TBusResponse>(&NGRpcProxy::TGRpcClient::WhoAmI, promise, request);
+ case NMsgBusProxy::MTYPE_CLIENT_RESOLVE_NODE:
+ return ExecuteGRpcRequest<NMsgBusProxy::TBusResolveNode, NMsgBusProxy::TBusResponse>(&NGRpcProxy::TGRpcClient::ResolveNode, promise, request);
+ case NMsgBusProxy::MTYPE_CLIENT_DRAIN_NODE:
+ return ExecuteGRpcRequest<NMsgBusProxy::TBusDrainNode, NMsgBusProxy::TBusResponse>(&NGRpcProxy::TGRpcClient::DrainNode, promise, request);
+ case NMsgBusProxy::MTYPE_CLIENT_FILL_NODE:
+ return ExecuteGRpcRequest<NMsgBusProxy::TBusFillNode, NMsgBusProxy::TBusResponse>(&NGRpcProxy::TGRpcClient::FillNode, promise, request);
+ default:
Y_FAIL("%s", (TStringBuilder() << "unexpected message type# " << type).data());
- }
- }
-
- virtual TString GetCurrentLocation() const override {
- TString host;
- ui32 port;
- NMsgBusProxy::TMsgBusClientConfig::CrackAddress(GRpcClient->GetConfig().Locator, host, port);
- return host;
- }
-
- static bool IsIPv6(const TString& host) {
- return host.find_first_not_of(":0123456789abcdef") == TString::npos;
- }
-
- static TString EscapeIPv6(const TString& host) {
- if (IsIPv6(host)) {
- return TStringBuilder() << '[' << host << ']';
- } else {
- return host;
- }
- }
-
- virtual TCleanupCallback SwitchToLocation(const TString& location) override {
- NGRpcProxy::TGRpcClientConfig config(GRpcClient->GetConfig());
- TString hostname;
- ui32 port;
- NMsgBusProxy::TMsgBusClientConfig::CrackAddress(config.Locator, hostname, port);
- TString newLocation = TStringBuilder() << EscapeIPv6(location) << ':' << port;
- if (newLocation == config.Locator) {
- return TCleanupCallback();
- }
- config.Locator = newLocation;
- TAutoPtr<NGRpcProxy::TGRpcClient> gRpcClient = new NGRpcProxy::TGRpcClient(config);
- gRpcClient.Swap(GRpcClient);
- // we cleanup later to avoid dead lock because we are still inside callback of current client
- return [gRpcClient]() {};
- }
+ }
+ }
+
+ virtual TString GetCurrentLocation() const override {
+ TString host;
+ ui32 port;
+ NMsgBusProxy::TMsgBusClientConfig::CrackAddress(GRpcClient->GetConfig().Locator, host, port);
+ return host;
+ }
+
+ static bool IsIPv6(const TString& host) {
+ return host.find_first_not_of(":0123456789abcdef") == TString::npos;
+ }
+
+ static TString EscapeIPv6(const TString& host) {
+ if (IsIPv6(host)) {
+ return TStringBuilder() << '[' << host << ']';
+ } else {
+ return host;
+ }
+ }
+
+ virtual TCleanupCallback SwitchToLocation(const TString& location) override {
+ NGRpcProxy::TGRpcClientConfig config(GRpcClient->GetConfig());
+ TString hostname;
+ ui32 port;
+ NMsgBusProxy::TMsgBusClientConfig::CrackAddress(config.Locator, hostname, port);
+ TString newLocation = TStringBuilder() << EscapeIPv6(location) << ':' << port;
+ if (newLocation == config.Locator) {
+ return TCleanupCallback();
+ }
+ config.Locator = newLocation;
+ TAutoPtr<NGRpcProxy::TGRpcClient> gRpcClient = new NGRpcProxy::TGRpcClient(config);
+ gRpcClient.Swap(GRpcClient);
+ // we cleanup later to avoid dead lock because we are still inside callback of current client
+ return [gRpcClient]() {};
+ }
private:
static NBus::EMessageStatus MapGrpcStatus(int status) {
switch (status) {
@@ -343,168 +343,168 @@ private:
return NBus::MESSAGE_CONNECT_FAILED;
}
}
-};
-
-TKikimr::TRetryQueue::TRetryQueue(TKikimr::TImpl& kikimr)
- : Kikimr(kikimr)
- , TimeToQuit(false)
- , QueueThread(&TRetryQueue::StaticRetryQueueThread, this)
-{}
-
-TKikimr::TRetryQueue::~TRetryQueue() {
- AtomicStore(&TimeToQuit, true);
- if (QueueThread.Running()) {
- CondVar.Signal();
- QueueThread.Join();
- }
-}
-
-void TKikimr::TRetryQueue::RetryQueueThread() {
- while (!AtomicLoad(&TimeToQuit)) {
- TGuard<TMutex> lock(QueueMutex);
- TInstant now = TInstant::Now();
- TInstant time;
- if (!Queue.empty()) {
- time = Queue.top().Time;
- } else {
- time = TInstant::Max();
- }
- if (time < now || !CondVar.WaitD(*lock.GetMutex(), time)) {
- if (!Queue.empty()) {
- TQueueItem& item = const_cast<TQueueItem&>(Queue.top());
- auto status = Kikimr.ExecuteRequest(item.Promise, item.Request.Release());
- if (status != NBus::MESSAGE_OK) {
- item.Promise.SetValue(TResult(status));
- }
- Queue.pop();
- }
- }
- }
-}
-
-void* TKikimr::TRetryQueue::StaticRetryQueueThread(void* param) {
- static_cast<TRetryQueue*>(param)->RetryQueueThread();
- return nullptr;
-}
-
-void TKikimr::TRetryQueue::QueueRequest(NThreading::TPromise<TResult> promise, TAutoPtr<NBus::TBusMessage> request, TDuration wait) {
- {
- TGuard<TMutex> lock(QueueMutex);
- Queue.emplace(TInstant::Now() + wait, promise, request);
- if (!QueueThread.Running()) {
- QueueThread.Start();
- }
- }
- CondVar.Signal();
-}
-
-TKikimr::TKikimr(const NMsgBusProxy::TMsgBusClientConfig& clientConfig, const TConnectionPolicy& policy)
- : Impl(new TMsgBusImpl(clientConfig, policy))
-{}
-
-TKikimr::TKikimr(const NGRpcProxy::TGRpcClientConfig& clientConfig, const TConnectionPolicy& policy)
- : Impl(new TGRpcImpl(clientConfig, policy))
-{}
-
-TString TKikimr::GetCurrentLocation() const {
- return Impl->GetCurrentLocation();
-}
-
-TKikimr::~TKikimr() = default;
-
-TTextQuery TKikimr::Query(const TString& program) {
- return TTextQuery(*this, program);
-}
-
-TSchemaObject TKikimr::GetSchemaRoot(const TString& name) {
+};
+
+TKikimr::TRetryQueue::TRetryQueue(TKikimr::TImpl& kikimr)
+ : Kikimr(kikimr)
+ , TimeToQuit(false)
+ , QueueThread(&TRetryQueue::StaticRetryQueueThread, this)
+{}
+
+TKikimr::TRetryQueue::~TRetryQueue() {
+ AtomicStore(&TimeToQuit, true);
+ if (QueueThread.Running()) {
+ CondVar.Signal();
+ QueueThread.Join();
+ }
+}
+
+void TKikimr::TRetryQueue::RetryQueueThread() {
+ while (!AtomicLoad(&TimeToQuit)) {
+ TGuard<TMutex> lock(QueueMutex);
+ TInstant now = TInstant::Now();
+ TInstant time;
+ if (!Queue.empty()) {
+ time = Queue.top().Time;
+ } else {
+ time = TInstant::Max();
+ }
+ if (time < now || !CondVar.WaitD(*lock.GetMutex(), time)) {
+ if (!Queue.empty()) {
+ TQueueItem& item = const_cast<TQueueItem&>(Queue.top());
+ auto status = Kikimr.ExecuteRequest(item.Promise, item.Request.Release());
+ if (status != NBus::MESSAGE_OK) {
+ item.Promise.SetValue(TResult(status));
+ }
+ Queue.pop();
+ }
+ }
+ }
+}
+
+void* TKikimr::TRetryQueue::StaticRetryQueueThread(void* param) {
+ static_cast<TRetryQueue*>(param)->RetryQueueThread();
+ return nullptr;
+}
+
+void TKikimr::TRetryQueue::QueueRequest(NThreading::TPromise<TResult> promise, TAutoPtr<NBus::TBusMessage> request, TDuration wait) {
+ {
+ TGuard<TMutex> lock(QueueMutex);
+ Queue.emplace(TInstant::Now() + wait, promise, request);
+ if (!QueueThread.Running()) {
+ QueueThread.Start();
+ }
+ }
+ CondVar.Signal();
+}
+
+TKikimr::TKikimr(const NMsgBusProxy::TMsgBusClientConfig& clientConfig, const TConnectionPolicy& policy)
+ : Impl(new TMsgBusImpl(clientConfig, policy))
+{}
+
+TKikimr::TKikimr(const NGRpcProxy::TGRpcClientConfig& clientConfig, const TConnectionPolicy& policy)
+ : Impl(new TGRpcImpl(clientConfig, policy))
+{}
+
+TString TKikimr::GetCurrentLocation() const {
+ return Impl->GetCurrentLocation();
+}
+
+TKikimr::~TKikimr() = default;
+
+TTextQuery TKikimr::Query(const TString& program) {
+ return TTextQuery(*this, program);
+}
+
+TSchemaObject TKikimr::GetSchemaRoot(const TString& name) {
return TSchemaObject(*this, "/", name, 0, TSchemaObject::EPathType::SubDomain);
-}
-
-TSchemaObject TKikimr::GetSchemaObject(const TString& name) {
- auto pos = name.rfind('/');
- TString pathObj(name.substr(0, pos));
- TString nameObj(pos != TString::npos ? name.substr(pos + 1) : "");
+}
+
+TSchemaObject TKikimr::GetSchemaObject(const TString& name) {
+ auto pos = name.rfind('/');
+ TString pathObj(name.substr(0, pos));
+ TString nameObj(pos != TString::npos ? name.substr(pos + 1) : "");
return TSchemaObject(*this, pathObj, nameObj, 0, TSchemaObject::EPathType::Unknown);
-}
-
-NThreading::TFuture<TResult> TKikimr::ExecuteRequest(TAutoPtr<NBus::TBusMessage> request) {
- return Impl->Execute(request);
-}
-
-NThreading::TFuture<TQueryResult> TKikimr::ExecuteQuery(const TTextQuery& query, const NKikimrMiniKQL::TParams& parameters) {
- TAutoPtr<NMsgBusProxy::TBusRequest> request(new NMsgBusProxy::TBusRequest());
- auto* mkqlTx = request->Record.MutableTransaction()->MutableMiniKQLTransaction();
- mkqlTx->SetFlatMKQL(true);
- mkqlTx->SetMode(NKikimrTxUserProxy::TMiniKQLTransaction::COMPILE_AND_EXEC);
- mkqlTx->MutableProgram()->SetText(query.TextProgram);
- mkqlTx->MutableParams()->MutableProto()->CopyFrom(parameters);
- auto future = ExecuteRequest(request.Release());
- return future.Apply([](const NThreading::TFuture<TResult>& result) -> TQueryResult {
- return TQueryResult(result.GetValue(TDuration::Max()));
- });
-}
-
+}
+
+NThreading::TFuture<TResult> TKikimr::ExecuteRequest(TAutoPtr<NBus::TBusMessage> request) {
+ return Impl->Execute(request);
+}
+
+NThreading::TFuture<TQueryResult> TKikimr::ExecuteQuery(const TTextQuery& query, const NKikimrMiniKQL::TParams& parameters) {
+ TAutoPtr<NMsgBusProxy::TBusRequest> request(new NMsgBusProxy::TBusRequest());
+ auto* mkqlTx = request->Record.MutableTransaction()->MutableMiniKQLTransaction();
+ mkqlTx->SetFlatMKQL(true);
+ mkqlTx->SetMode(NKikimrTxUserProxy::TMiniKQLTransaction::COMPILE_AND_EXEC);
+ mkqlTx->MutableProgram()->SetText(query.TextProgram);
+ mkqlTx->MutableParams()->MutableProto()->CopyFrom(parameters);
+ auto future = ExecuteRequest(request.Release());
+ return future.Apply([](const NThreading::TFuture<TResult>& result) -> TQueryResult {
+ return TQueryResult(result.GetValue(TDuration::Max()));
+ });
+}
+
NThreading::TFuture<TQueryResult> TKikimr::ExecuteQuery(const TTextQuery& query, const TString& parameters) {
- TAutoPtr<NMsgBusProxy::TBusRequest> request(new NMsgBusProxy::TBusRequest());
- auto* mkqlTx = request->Record.MutableTransaction()->MutableMiniKQLTransaction();
- mkqlTx->SetFlatMKQL(true);
- mkqlTx->SetMode(NKikimrTxUserProxy::TMiniKQLTransaction::COMPILE_AND_EXEC);
- mkqlTx->MutableProgram()->SetText(query.TextProgram);
- if (!parameters.empty())
- mkqlTx->MutableParams()->SetText(parameters);
- auto future = ExecuteRequest(request.Release());
- return future.Apply([](const NThreading::TFuture<TResult>& result) -> TQueryResult {
- return TQueryResult(result.GetValue(TDuration::Max()));
- });
-}
-
-NThreading::TFuture<TQueryResult> TKikimr::ExecuteQuery(const TPreparedQuery& query, const NKikimrMiniKQL::TParams& parameters) {
- TAutoPtr<NMsgBusProxy::TBusRequest> request(new NMsgBusProxy::TBusRequest());
- auto* mkqlTx = request->Record.MutableTransaction()->MutableMiniKQLTransaction();
- mkqlTx->SetFlatMKQL(true);
- mkqlTx->SetMode(NKikimrTxUserProxy::TMiniKQLTransaction::COMPILE_AND_EXEC);
- mkqlTx->MutableProgram()->SetBin(query.CompiledProgram);
- if (parameters.HasType() && parameters.GetType().HasKind()) {
- mkqlTx->MutableParams()->MutableProto()->CopyFrom(parameters);
- }
- auto future = ExecuteRequest(request.Release());
- return future.Apply([](const NThreading::TFuture<TResult>& result) -> TQueryResult {
- return TQueryResult(result.GetValue(TDuration::Max()));
- });
-}
-
+ TAutoPtr<NMsgBusProxy::TBusRequest> request(new NMsgBusProxy::TBusRequest());
+ auto* mkqlTx = request->Record.MutableTransaction()->MutableMiniKQLTransaction();
+ mkqlTx->SetFlatMKQL(true);
+ mkqlTx->SetMode(NKikimrTxUserProxy::TMiniKQLTransaction::COMPILE_AND_EXEC);
+ mkqlTx->MutableProgram()->SetText(query.TextProgram);
+ if (!parameters.empty())
+ mkqlTx->MutableParams()->SetText(parameters);
+ auto future = ExecuteRequest(request.Release());
+ return future.Apply([](const NThreading::TFuture<TResult>& result) -> TQueryResult {
+ return TQueryResult(result.GetValue(TDuration::Max()));
+ });
+}
+
+NThreading::TFuture<TQueryResult> TKikimr::ExecuteQuery(const TPreparedQuery& query, const NKikimrMiniKQL::TParams& parameters) {
+ TAutoPtr<NMsgBusProxy::TBusRequest> request(new NMsgBusProxy::TBusRequest());
+ auto* mkqlTx = request->Record.MutableTransaction()->MutableMiniKQLTransaction();
+ mkqlTx->SetFlatMKQL(true);
+ mkqlTx->SetMode(NKikimrTxUserProxy::TMiniKQLTransaction::COMPILE_AND_EXEC);
+ mkqlTx->MutableProgram()->SetBin(query.CompiledProgram);
+ if (parameters.HasType() && parameters.GetType().HasKind()) {
+ mkqlTx->MutableParams()->MutableProto()->CopyFrom(parameters);
+ }
+ auto future = ExecuteRequest(request.Release());
+ return future.Apply([](const NThreading::TFuture<TResult>& result) -> TQueryResult {
+ return TQueryResult(result.GetValue(TDuration::Max()));
+ });
+}
+
NThreading::TFuture<TQueryResult> TKikimr::ExecuteQuery(const TPreparedQuery& query, const TString& parameters) {
- TAutoPtr<NMsgBusProxy::TBusRequest> request(new NMsgBusProxy::TBusRequest());
- auto* mkqlTx = request->Record.MutableTransaction()->MutableMiniKQLTransaction();
- mkqlTx->SetFlatMKQL(true);
- mkqlTx->SetMode(NKikimrTxUserProxy::TMiniKQLTransaction::COMPILE_AND_EXEC);
- mkqlTx->MutableProgram()->SetBin(query.CompiledProgram);
- if (!parameters.empty())
- mkqlTx->MutableParams()->SetText(parameters);
- auto future = ExecuteRequest(request.Release());
- return future.Apply([](const NThreading::TFuture<TResult>& result) -> TQueryResult {
- return TQueryResult(result.GetValue(TDuration::Max()));
- });
-}
-
-NThreading::TFuture<TPrepareResult> TKikimr::PrepareQuery(const TTextQuery& query) {
- TAutoPtr<NMsgBusProxy::TBusRequest> request(new NMsgBusProxy::TBusRequest());
- auto* mkqlTx = request->Record.MutableTransaction()->MutableMiniKQLTransaction();
- mkqlTx->SetFlatMKQL(true);
- mkqlTx->SetMode(NKikimrTxUserProxy::TMiniKQLTransaction::COMPILE);
- mkqlTx->MutableProgram()->SetText(query.TextProgram);
- auto future = ExecuteRequest(request.Release());
+ TAutoPtr<NMsgBusProxy::TBusRequest> request(new NMsgBusProxy::TBusRequest());
+ auto* mkqlTx = request->Record.MutableTransaction()->MutableMiniKQLTransaction();
+ mkqlTx->SetFlatMKQL(true);
+ mkqlTx->SetMode(NKikimrTxUserProxy::TMiniKQLTransaction::COMPILE_AND_EXEC);
+ mkqlTx->MutableProgram()->SetBin(query.CompiledProgram);
+ if (!parameters.empty())
+ mkqlTx->MutableParams()->SetText(parameters);
+ auto future = ExecuteRequest(request.Release());
+ return future.Apply([](const NThreading::TFuture<TResult>& result) -> TQueryResult {
+ return TQueryResult(result.GetValue(TDuration::Max()));
+ });
+}
+
+NThreading::TFuture<TPrepareResult> TKikimr::PrepareQuery(const TTextQuery& query) {
+ TAutoPtr<NMsgBusProxy::TBusRequest> request(new NMsgBusProxy::TBusRequest());
+ auto* mkqlTx = request->Record.MutableTransaction()->MutableMiniKQLTransaction();
+ mkqlTx->SetFlatMKQL(true);
+ mkqlTx->SetMode(NKikimrTxUserProxy::TMiniKQLTransaction::COMPILE);
+ mkqlTx->MutableProgram()->SetText(query.TextProgram);
+ auto future = ExecuteRequest(request.Release());
return future.Apply([&query](const NThreading::TFuture<TResult>& result) -> TPrepareResult {
- return TPrepareResult(result.GetValue(TDuration::Max()), query);
- });
-}
-
-NThreading::TFuture<TResult> TKikimr::DescribeObject(const TSchemaObject& object) {
+ return TPrepareResult(result.GetValue(TDuration::Max()), query);
+ });
+}
+
+NThreading::TFuture<TResult> TKikimr::DescribeObject(const TSchemaObject& object) {
TAutoPtr<NMsgBusProxy::TBusSchemeDescribe> request(new NMsgBusProxy::TBusSchemeDescribe());
- request->Record.SetPath(object.GetPath());
- return ExecuteRequest(request.Release());
-}
-
+ request->Record.SetPath(object.GetPath());
+ return ExecuteRequest(request.Release());
+}
+
NThreading::TFuture<TResult> TKikimr::ModifySchema(const TModifyScheme& schema) {
TAutoPtr<NMsgBusProxy::TBusSchemeOperation> request(new NMsgBusProxy::TBusSchemeOperation());
request->Record.MutablePollOptions()->SetTimeout(POLLING_TIMEOUT);
@@ -514,56 +514,56 @@ NThreading::TFuture<TResult> TKikimr::ModifySchema(const TModifyScheme& schema)
NThreading::TFuture<TResult> TKikimr::MakeDirectory(const TSchemaObject& object, const TString& name) {
TAutoPtr<NMsgBusProxy::TBusSchemeOperation> request(new NMsgBusProxy::TBusSchemeOperation());
- request->Record.MutablePollOptions()->SetTimeout(POLLING_TIMEOUT);
- auto* modifyScheme = request->Record.MutableTransaction()->MutableModifyScheme();
- modifyScheme->SetWorkingDir(object.GetPath());
+ request->Record.MutablePollOptions()->SetTimeout(POLLING_TIMEOUT);
+ auto* modifyScheme = request->Record.MutableTransaction()->MutableModifyScheme();
+ modifyScheme->SetWorkingDir(object.GetPath());
modifyScheme->SetOperationType(NKikimrSchemeOp::ESchemeOpMkDir);
- auto* makeDirectory = modifyScheme->MutableMkDir();
- makeDirectory->SetName(name);
- return ExecuteRequest(request.Release());
-}
-
+ auto* makeDirectory = modifyScheme->MutableMkDir();
+ makeDirectory->SetName(name);
+ return ExecuteRequest(request.Release());
+}
+
NThreading::TFuture<TResult> TKikimr::CreateTable(TSchemaObject& object, const TString& name, const TVector<TColumn>& columns,
const TTablePartitionConfig* partitionConfig)
{
TAutoPtr<NMsgBusProxy::TBusSchemeOperation> request(new NMsgBusProxy::TBusSchemeOperation());
- request->Record.MutablePollOptions()->SetTimeout(POLLING_TIMEOUT);
- auto* modifyScheme = request->Record.MutableTransaction()->MutableModifyScheme();
- modifyScheme->SetWorkingDir(object.GetPath());
+ request->Record.MutablePollOptions()->SetTimeout(POLLING_TIMEOUT);
+ auto* modifyScheme = request->Record.MutableTransaction()->MutableModifyScheme();
+ modifyScheme->SetWorkingDir(object.GetPath());
modifyScheme->SetOperationType(NKikimrSchemeOp::ESchemeOpCreateTable);
- auto* createTable = modifyScheme->MutableCreateTable();
- createTable->SetName(name);
- for (const TColumn& column : columns) {
- auto* col = createTable->AddColumns();
- col->SetName(column.Name);
- col->SetType(column.Type.GetName());
- if (column.Key) {
- createTable->AddKeyColumnNames(column.Name);
- if (column.Partitions != 0) {
- Y_ASSERT(!createTable->HasUniformPartitionsCount());
- createTable->SetUniformPartitionsCount(column.Partitions);
- }
- }
- }
+ auto* createTable = modifyScheme->MutableCreateTable();
+ createTable->SetName(name);
+ for (const TColumn& column : columns) {
+ auto* col = createTable->AddColumns();
+ col->SetName(column.Name);
+ col->SetType(column.Type.GetName());
+ if (column.Key) {
+ createTable->AddKeyColumnNames(column.Name);
+ if (column.Partitions != 0) {
+ Y_ASSERT(!createTable->HasUniformPartitionsCount());
+ createTable->SetUniformPartitionsCount(column.Partitions);
+ }
+ }
+ }
if (partitionConfig) {
createTable->MutablePartitionConfig()->CopyFrom(*partitionConfig);
}
- return ExecuteRequest(request.Release());
-}
-
+ return ExecuteRequest(request.Release());
+}
+
void TKikimr::SetSecurityToken(const TString& securityToken) {
- SecurityToken = securityToken;
-}
-
-TPreparedQuery TKikimr::Query(const TUnbindedQuery& query) {
- return TPreparedQuery(TQuery(*this), query.CompiledProgram);
-}
-
-TKikimr::TKikimr(TKikimr&& kikimr)
- : SecurityToken(std::move(kikimr.SecurityToken))
- , Impl(std::move(kikimr.Impl))
-{}
-
+ SecurityToken = securityToken;
+}
+
+TPreparedQuery TKikimr::Query(const TUnbindedQuery& query) {
+ return TPreparedQuery(TQuery(*this), query.CompiledProgram);
+}
+
+TKikimr::TKikimr(TKikimr&& kikimr)
+ : SecurityToken(std::move(kikimr.SecurityToken))
+ , Impl(std::move(kikimr.Impl))
+{}
+
TNodeRegistrant TKikimr::GetNodeRegistrant()
{
return TNodeRegistrant(*this);
diff --git a/ydb/public/lib/deprecated/kicli/query.cpp b/ydb/public/lib/deprecated/kicli/query.cpp
index 65484db3891..c614b5b3fdb 100644
--- a/ydb/public/lib/deprecated/kicli/query.cpp
+++ b/ydb/public/lib/deprecated/kicli/query.cpp
@@ -1,76 +1,76 @@
-#include "kicli.h"
-
-namespace NKikimr {
-namespace NClient {
-
-TQuery::TQuery(TKikimr& kikimr)
- : Kikimr(&kikimr)
-{}
-
+#include "kicli.h"
+
+namespace NKikimr {
+namespace NClient {
+
+TQuery::TQuery(TKikimr& kikimr)
+ : Kikimr(&kikimr)
+{}
+
void TQuery::ParseTextParameters(NKikimrMiniKQL::TParams& params, const TString& parameters) {
- if (!parameters.empty()) {
- bool ok = ::google::protobuf::TextFormat::ParseFromString(parameters, &params);
+ if (!parameters.empty()) {
+ bool ok = ::google::protobuf::TextFormat::ParseFromString(parameters, &params);
Y_VERIFY(ok);
- }
-}
-
+ }
+}
+
TTextQuery::TTextQuery(TKikimr& kikimr, const TString& program)
- : TQuery(kikimr)
- , TextProgram(program)
-{}
-
-TPrepareResult TTextQuery::SyncPrepare() const {
- return AsyncPrepare().GetValue(TDuration::Max());
-}
-
-NThreading::TFuture<TPrepareResult> TTextQuery::AsyncPrepare() const {
- return Kikimr->PrepareQuery(*this);
-}
-
-TQueryResult TTextQuery::SyncExecute(const NKikimrMiniKQL::TParams& parameters) const {
- return AsyncExecute(parameters).GetValue(TDuration::Max());
-}
-
+ : TQuery(kikimr)
+ , TextProgram(program)
+{}
+
+TPrepareResult TTextQuery::SyncPrepare() const {
+ return AsyncPrepare().GetValue(TDuration::Max());
+}
+
+NThreading::TFuture<TPrepareResult> TTextQuery::AsyncPrepare() const {
+ return Kikimr->PrepareQuery(*this);
+}
+
+TQueryResult TTextQuery::SyncExecute(const NKikimrMiniKQL::TParams& parameters) const {
+ return AsyncExecute(parameters).GetValue(TDuration::Max());
+}
+
TQueryResult TTextQuery::SyncExecute(const TString& parameters) const {
- return AsyncExecute(parameters).GetValue(TDuration::Max());
-}
-
-NThreading::TFuture<TQueryResult> TTextQuery::AsyncExecute(const NKikimrMiniKQL::TParams& parameters) const {
- return Kikimr->ExecuteQuery(*this, parameters);
-}
-
+ return AsyncExecute(parameters).GetValue(TDuration::Max());
+}
+
+NThreading::TFuture<TQueryResult> TTextQuery::AsyncExecute(const NKikimrMiniKQL::TParams& parameters) const {
+ return Kikimr->ExecuteQuery(*this, parameters);
+}
+
NThreading::TFuture<TQueryResult> TTextQuery::AsyncExecute(const TString& parameters) const {
- return Kikimr->ExecuteQuery(*this, parameters);
-}
-
+ return Kikimr->ExecuteQuery(*this, parameters);
+}
+
TPreparedQuery::TPreparedQuery(const TQuery& textQuery, const TString& program)
- : TQuery(textQuery)
- , CompiledProgram(program)
-{}
-
-TQueryResult TPreparedQuery::SyncExecute(const NKikimrMiniKQL::TParams& parameters) const {
- return AsyncExecute(parameters).GetValue(TDuration::Max());
-}
-
+ : TQuery(textQuery)
+ , CompiledProgram(program)
+{}
+
+TQueryResult TPreparedQuery::SyncExecute(const NKikimrMiniKQL::TParams& parameters) const {
+ return AsyncExecute(parameters).GetValue(TDuration::Max());
+}
+
TQueryResult TPreparedQuery::SyncExecute(const TString& parameters) const {
- return AsyncExecute(parameters).GetValue(TDuration::Max());
-}
-
-NThreading::TFuture<TQueryResult> TPreparedQuery::AsyncExecute(const NKikimrMiniKQL::TParams& parameters) const {
- return Kikimr->ExecuteQuery(*this, parameters);
-}
-
+ return AsyncExecute(parameters).GetValue(TDuration::Max());
+}
+
+NThreading::TFuture<TQueryResult> TPreparedQuery::AsyncExecute(const NKikimrMiniKQL::TParams& parameters) const {
+ return Kikimr->ExecuteQuery(*this, parameters);
+}
+
NThreading::TFuture<TQueryResult> TPreparedQuery::AsyncExecute(const TString& parameters) const {
- return Kikimr->ExecuteQuery(*this, parameters);
-}
-
+ return Kikimr->ExecuteQuery(*this, parameters);
+}
+
TUnbindedQuery::TUnbindedQuery(const TString& program)
- : CompiledProgram(program)
-{}
-
-TUnbindedQuery TPreparedQuery::Unbind() const {
- return TUnbindedQuery(CompiledProgram);
-}
-
-}
-}
+ : CompiledProgram(program)
+{}
+
+TUnbindedQuery TPreparedQuery::Unbind() const {
+ return TUnbindedQuery(CompiledProgram);
+}
+
+}
+}
diff --git a/ydb/public/lib/deprecated/kicli/result.cpp b/ydb/public/lib/deprecated/kicli/result.cpp
index 6ceb733b3e3..0f86ba4340a 100644
--- a/ydb/public/lib/deprecated/kicli/result.cpp
+++ b/ydb/public/lib/deprecated/kicli/result.cpp
@@ -1,91 +1,91 @@
-#include "kicli.h"
-
+#include "kicli.h"
+
#include <ydb/public/lib/deprecated/client/msgbus_client.h>
#include <ydb/library/yql/public/decimal/yql_decimal.h>
#include <util/generic/ymath.h>
-namespace NKikimr {
-namespace NClient {
-
-TResult::TResult(NBus::EMessageStatus transportStatus)
- : TransportStatus(transportStatus)
-{}
-
+namespace NKikimr {
+namespace NClient {
+
+TResult::TResult(NBus::EMessageStatus transportStatus)
+ : TransportStatus(transportStatus)
+{}
+
TResult::TResult(NBus::EMessageStatus transportStatus, const TString& message)
: TransportStatus(transportStatus)
, TransportErrorMessage(message)
{}
-TResult::TResult(TAutoPtr<NBus::TBusMessage> reply)
- : TransportStatus(NBus::MESSAGE_OK)
+TResult::TResult(TAutoPtr<NBus::TBusMessage> reply)
+ : TransportStatus(NBus::MESSAGE_OK)
, Reply(reply.Release())
-{}
-
-ui16 TResult::GetType() const {
- return Reply == nullptr ? 0 : Reply.Get()->GetHeader()->Type;
-}
-
+{}
+
+ui16 TResult::GetType() const {
+ return Reply == nullptr ? 0 : Reply.Get()->GetHeader()->Type;
+}
+
template <> const NKikimrClient::TResponse& TResult::GetResult<NKikimrClient::TResponse>() const {
Y_VERIFY(GetType() == NMsgBusProxy::MTYPE_CLIENT_RESPONSE, "Unexpected response type: %d", GetType());
- return static_cast<NMsgBusProxy::TBusResponse*>(Reply.Get())->Record;
-}
-
+ return static_cast<NMsgBusProxy::TBusResponse*>(Reply.Get())->Record;
+}
+
template <> const NKikimrClient::TBsTestLoadResponse& TResult::GetResult<NKikimrClient::TBsTestLoadResponse>() const {
Y_VERIFY(GetType() == NMsgBusProxy::MTYPE_CLIENT_LOAD_RESPONSE, "Unexpected response type: %d", GetType());
return static_cast<NMsgBusProxy::TBusBsTestLoadResponse*>(Reply.Get())->Record;
}
-NMsgBusProxy::EResponseStatus TResult::GetStatus() const {
- if (TransportStatus != NBus::MESSAGE_OK) {
- switch (TransportStatus) {
- case NBus::MESSAGE_CONNECT_FAILED:
- case NBus::MESSAGE_SERVICE_UNKNOWN:
- case NBus::MESSAGE_DESERIALIZE_ERROR:
- case NBus::MESSAGE_HEADER_CORRUPTED:
- case NBus::MESSAGE_DECOMPRESS_ERROR:
- case NBus::MESSAGE_MESSAGE_TOO_LARGE:
- case NBus::MESSAGE_REPLY_FAILED:
- case NBus::MESSAGE_DELIVERY_FAILED:
- case NBus::MESSAGE_INVALID_VERSION:
- case NBus::MESSAGE_SERVICE_TOOMANY:
- return NMsgBusProxy::MSTATUS_ERROR;
- case NBus::MESSAGE_TIMEOUT:
- return NMsgBusProxy::MSTATUS_TIMEOUT;
- case NBus::MESSAGE_UNKNOWN:
- return NMsgBusProxy::MSTATUS_UNKNOWN;
- case NBus::MESSAGE_BUSY:
+NMsgBusProxy::EResponseStatus TResult::GetStatus() const {
+ if (TransportStatus != NBus::MESSAGE_OK) {
+ switch (TransportStatus) {
+ case NBus::MESSAGE_CONNECT_FAILED:
+ case NBus::MESSAGE_SERVICE_UNKNOWN:
+ case NBus::MESSAGE_DESERIALIZE_ERROR:
+ case NBus::MESSAGE_HEADER_CORRUPTED:
+ case NBus::MESSAGE_DECOMPRESS_ERROR:
+ case NBus::MESSAGE_MESSAGE_TOO_LARGE:
+ case NBus::MESSAGE_REPLY_FAILED:
+ case NBus::MESSAGE_DELIVERY_FAILED:
+ case NBus::MESSAGE_INVALID_VERSION:
+ case NBus::MESSAGE_SERVICE_TOOMANY:
+ return NMsgBusProxy::MSTATUS_ERROR;
+ case NBus::MESSAGE_TIMEOUT:
+ return NMsgBusProxy::MSTATUS_TIMEOUT;
+ case NBus::MESSAGE_UNKNOWN:
+ return NMsgBusProxy::MSTATUS_UNKNOWN;
+ case NBus::MESSAGE_BUSY:
return NMsgBusProxy::MSTATUS_REJECTED;
- case NBus::MESSAGE_SHUTDOWN:
- return NMsgBusProxy::MSTATUS_NOTREADY;
- case NBus::MESSAGE_OK:
- return NMsgBusProxy::MSTATUS_OK;
- default:
- return NMsgBusProxy::MSTATUS_INTERNALERROR;
- };
- } else
+ case NBus::MESSAGE_SHUTDOWN:
+ return NMsgBusProxy::MSTATUS_NOTREADY;
+ case NBus::MESSAGE_OK:
+ return NMsgBusProxy::MSTATUS_OK;
+ default:
+ return NMsgBusProxy::MSTATUS_INTERNALERROR;
+ };
+ } else
if (GetType() == NMsgBusProxy::MTYPE_CLIENT_RESPONSE) {
return static_cast<NMsgBusProxy::EResponseStatus>(GetResult<NKikimrClient::TResponse>().GetStatus());
} else
- return NMsgBusProxy::MSTATUS_INTERNALERROR;
-}
-
-TError TResult::GetError() const {
- return TError(*this);
-}
-
-TQueryResult::TQueryResult(const TResult& result)
- : TResult(result)
-{}
-
-TValue TQueryResult::GetValue() const {
+ return NMsgBusProxy::MSTATUS_INTERNALERROR;
+}
+
+TError TResult::GetError() const {
+ return TError(*this);
+}
+
+TQueryResult::TQueryResult(const TResult& result)
+ : TResult(result)
+{}
+
+TValue TQueryResult::GetValue() const {
const NKikimrClient::TResponse& response = GetResult<NKikimrClient::TResponse>();
Y_VERIFY(response.HasExecutionEngineEvaluatedResponse());
- const auto& result = response.GetExecutionEngineEvaluatedResponse();
- // TODO: type caching
- return TValue::Create(result.GetValue(), result.GetType());
-}
-
+ const auto& result = response.GetExecutionEngineEvaluatedResponse();
+ // TODO: type caching
+ return TValue::Create(result.GetValue(), result.GetType());
+}
+
TReadTableResult::TReadTableResult(const TResult& result)
: TResult(result)
{}
@@ -281,12 +281,12 @@ template <> TString TReadTableResult::GetValueText<TFormatCSV>(const TFormatCSV
/// @warning It's mistake to store Query as a row pointer here. TQuery could be a tmp object.
/// TPrepareResult result = kikimr.Query(some).SyncPrepare();
/// TPreparedQuery query = result.GetQuery(); //< error here. Query is obsolete.
-TPrepareResult::TPrepareResult(const TResult& result, const TQuery& query)
- : TResult(result)
- , Query(&query)
-{}
-
-TPreparedQuery TPrepareResult::GetQuery() const {
+TPrepareResult::TPrepareResult(const TResult& result, const TQuery& query)
+ : TResult(result)
+ , Query(&query)
+{}
+
+TPreparedQuery TPrepareResult::GetQuery() const {
const NKikimrClient::TResponse& response = GetResult<NKikimrClient::TResponse>();
Y_VERIFY(response.HasMiniKQLCompileResults());
const auto& compileResult = response.GetMiniKQLCompileResults();
@@ -297,7 +297,7 @@ TPreparedQuery TPrepareResult::GetQuery() const {
(compileResult.ProgramCompileErrorsSize() ? compileResult.GetProgramCompileErrors(0).message().data() : "")
);
return TPreparedQuery(*Query, compileResult.GetCompiledProgram());
-}
-
+}
+
}
}
diff --git a/ydb/public/lib/deprecated/kicli/schema.cpp b/ydb/public/lib/deprecated/kicli/schema.cpp
index e3eedde47fe..d1ee0384f8b 100644
--- a/ydb/public/lib/deprecated/kicli/schema.cpp
+++ b/ydb/public/lib/deprecated/kicli/schema.cpp
@@ -1,45 +1,45 @@
-#include "kicli.h"
+#include "kicli.h"
#include <ydb/public/lib/deprecated/client/msgbus_client.h>
-
-namespace NKikimr {
-namespace NClient {
-
+
+namespace NKikimr {
+namespace NClient {
+
TColumn::TColumn(const TString& name, const TType& type)
- : Name(name)
- , Type(type)
- , Key(false)
- , Partitions(0)
-{}
-
+ : Name(name)
+ , Type(type)
+ , Key(false)
+ , Partitions(0)
+{}
+
TColumn::TColumn(const TString& name, const TType& type, bool key, ui32 partitions)
- : Name(name)
- , Type(type)
- , Key(key)
- , Partitions(partitions)
-{}
-
+ : Name(name)
+ , Type(type)
+ , Key(key)
+ , Partitions(partitions)
+{}
+
TKeyColumn::TKeyColumn(const TString& name, const TType& type)
- : TColumn(name, type, true, 0)
-{}
-
+ : TColumn(name, type, true, 0)
+{}
+
TKeyColumn::TKeyColumn(const TString& name, const TType& type, ui32 partitions)
- : TColumn(name, type, true, partitions)
-{}
-
+ : TColumn(name, type, true, partitions)
+{}
+
TKeyPartitioningColumn::TKeyPartitioningColumn(const TString& name, const TType& type, ui32 partitions)
- : TKeyColumn(name, type, partitions)
-{}
-
+ : TKeyColumn(name, type, partitions)
+{}
+
TType::TType(const TString& typeName, NScheme::TTypeId typeId)
- : TypeName(typeName)
- , TypeId(typeId)
-{}
-
-TType::TType(NScheme::TTypeId typeId)
+ : TypeName(typeName)
+ , TypeId(typeId)
+{}
+
+TType::TType(NScheme::TTypeId typeId)
: TypeName(NScheme::TypeName(typeId))
, TypeId(typeId)
{}
-
+
const TType TType::Int64(NScheme::NTypeIds::Int64);
const TType TType::Uint64(NScheme::NTypeIds::Uint64);
const TType TType::Int32(NScheme::NTypeIds::Int32);
@@ -55,28 +55,28 @@ const TType TType::Yson(NScheme::NTypeIds::Yson);
const TType TType::Json(NScheme::NTypeIds::Json);
const TType TType::JsonDocument(NScheme::NTypeIds::JsonDocument);
const TType TType::Timestamp(NScheme::NTypeIds::Timestamp);
-
+
const TString& TType::GetName() const {
- return TypeName;
-}
-
-ui16 TType::GetId() const {
- return TypeId;
-}
-
+ return TypeName;
+}
+
+ui16 TType::GetId() const {
+ return TypeId;
+}
+
TSchemaObject::TSchemaObject(TKikimr& kikimr, const TString& path, const TString& name, ui64 pathId, EPathType pathType)
- : Kikimr(kikimr)
+ : Kikimr(kikimr)
, Path(path.EndsWith('/') ? path + name : path + "/" + name)
- , Name(name)
+ , Name(name)
, PathId(pathId)
, PathType(pathType)
-{
+{
static_assert((ui32)NKikimrSchemeOp::EPathTypeDir == (ui32)EPathType::Directory, "EPathType::Directory");
static_assert((ui32)NKikimrSchemeOp::EPathTypeTable == (ui32)EPathType::Table, "EPathType::Table");
static_assert((ui32)NKikimrSchemeOp::EPathTypePersQueueGroup == (ui32)EPathType::PersQueueGroup, "EPathType::PersQueueGroup");
static_assert((ui32)NKikimrSchemeOp::EPathTypeSubDomain == (ui32)EPathType::SubDomain, "EPathType::SubDomain");
-}
-
+}
+
void TSchemaObject::ModifySchema(const TModifyScheme& schema) {
NThreading::TFuture<TResult> future = Kikimr.ModifySchema(schema);
TResult result = future.GetValue(TDuration::Max());
@@ -132,16 +132,16 @@ void TSchemaObject::Drop() {
}
TSchemaObject TSchemaObject::MakeDirectory(const TString& name) {
- NThreading::TFuture<TResult> future = Kikimr.MakeDirectory(*this, name);
- TResult result = future.GetValue(TDuration::Max());
- result.GetError().Throw();
+ NThreading::TFuture<TResult> future = Kikimr.MakeDirectory(*this, name);
+ TResult result = future.GetValue(TDuration::Max());
+ result.GetError().Throw();
const NKikimrClient::TResponse& response = result.GetResult<NKikimrClient::TResponse>();
ui64 pathId = response.GetFlatTxId().GetPathId();
Y_VERIFY(pathId);
return TSchemaObject(Kikimr, Path, name, pathId, EPathType::Directory);
-}
-
+}
+
TSchemaObject TSchemaObject::CreateTable(const TString& name, const TVector<TColumn>& columns) {
return DoCreateTable(name, columns, nullptr);
}
@@ -156,24 +156,24 @@ TSchemaObject TSchemaObject::DoCreateTable(const TString& name, const TVector<TC
const TTablePartitionConfig* partitionConfig)
{
NThreading::TFuture<TResult> future = Kikimr.CreateTable(*this, name, columns, partitionConfig);
- TResult result = future.GetValue(TDuration::Max());
- result.GetError().Throw();
+ TResult result = future.GetValue(TDuration::Max());
+ result.GetError().Throw();
const NKikimrClient::TResponse& response = result.GetResult<NKikimrClient::TResponse>();
ui64 pathId = response.GetFlatTxId().GetPathId();
Y_VERIFY(pathId);
return TSchemaObject(Kikimr, Path, name, pathId, EPathType::Table);
-}
-
+}
+
TSchemaObject TSchemaObject::GetChild(const TString& name) const {
- auto children = GetChildren();
- auto child = FindIf(children.begin(), children.end(), [&](const TSchemaObject& c) { return c.GetName() == name; });
- if (child == children.end()) {
- throw yexception() << "Schema object '" << name << "' not found";
- }
- return *child;
-}
-
+ auto children = GetChildren();
+ auto child = FindIf(children.begin(), children.end(), [&](const TSchemaObject& c) { return c.GetName() == name; });
+ if (child == children.end()) {
+ throw yexception() << "Schema object '" << name << "' not found";
+ }
+ return *child;
+}
+
static TSchemaObject::EPathType GetType(const NKikimrSchemeOp::TDirEntry& entry) {
switch (entry.GetPathType()) {
case NKikimrSchemeOp::EPathTypeDir:
@@ -212,24 +212,24 @@ static TSchemaObject::EPathType GetType(const NKikimrSchemeOp::TDirEntry& entry)
}
TVector<TSchemaObject> TSchemaObject::GetChildren() const {
- NThreading::TFuture<TResult> future = Kikimr.DescribeObject(*this);
- TResult result = future.GetValue(TDuration::Max());
- result.GetError().Throw();
+ NThreading::TFuture<TResult> future = Kikimr.DescribeObject(*this);
+ TResult result = future.GetValue(TDuration::Max());
+ result.GetError().Throw();
const NKikimrClient::TResponse& objects = result.GetResult<NKikimrClient::TResponse>();
TVector<TSchemaObject> children;
- children.reserve(objects.GetPathDescription().ChildrenSize());
- for (const auto& child : objects.GetPathDescription().GetChildren()) {
+ children.reserve(objects.GetPathDescription().ChildrenSize());
+ for (const auto& child : objects.GetPathDescription().GetChildren()) {
children.push_back(TSchemaObject(Kikimr, Path, child.GetName(), child.GetPathId(), GetType(child)));
- }
- return children;
-}
-
+ }
+ return children;
+}
+
TVector<TColumn> TSchemaObject::GetColumns() const {
- NThreading::TFuture<TResult> future = Kikimr.DescribeObject(*this);
- TResult result = future.GetValue(TDuration::Max());
- result.GetError().Throw();
+ NThreading::TFuture<TResult> future = Kikimr.DescribeObject(*this);
+ TResult result = future.GetValue(TDuration::Max());
+ result.GetError().Throw();
const NKikimrClient::TResponse& objects = result.GetResult<NKikimrClient::TResponse>();
- Y_VERIFY(objects.GetPathDescription().HasTable());
+ Y_VERIFY(objects.GetPathDescription().HasTable());
const auto& table = objects.GetPathDescription().GetTable();
TMap<ui32, NKikimrSchemeOp::TColumnDescription> columnsMap;
@@ -244,33 +244,33 @@ TVector<TColumn> TSchemaObject::GetColumns() const {
Y_VERIFY(column);
columns.push_back(TKeyColumn(column->GetName(), TType(column->GetType(), column->GetTypeId())));
columnsMap.erase(keyColumnId);
- }
+ }
for (const auto& pair : columnsMap) {
auto& column = pair.second;
columns.push_back(TColumn(column.GetName(), TType(column.GetType(), column.GetTypeId())));
}
- return columns;
-}
-
-TSchemaObjectStats TSchemaObject::GetStats() const {
- NThreading::TFuture<TResult> future = Kikimr.DescribeObject(*this);
- TResult result = future.GetValue(TDuration::Max());
- result.GetError().Throw();
+ return columns;
+}
+
+TSchemaObjectStats TSchemaObject::GetStats() const {
+ NThreading::TFuture<TResult> future = Kikimr.DescribeObject(*this);
+ TResult result = future.GetValue(TDuration::Max());
+ result.GetError().Throw();
const NKikimrClient::TResponse& objects = result.GetResult<NKikimrClient::TResponse>();
- Y_VERIFY(objects.GetPathDescription().HasTable());
- TSchemaObjectStats stats;
- stats.PartitionsCount = objects.GetPathDescription().TablePartitionsSize();
- return stats;
-}
-
+ Y_VERIFY(objects.GetPathDescription().HasTable());
+ TSchemaObjectStats stats;
+ stats.PartitionsCount = objects.GetPathDescription().TablePartitionsSize();
+ return stats;
+}
+
TString TSchemaObject::GetPath() const {
- return Path;
-}
-
+ return Path;
+}
+
TString TSchemaObject::GetName() const {
- return Name;
-}
-
-}
-}
+ return Name;
+}
+
+}
+}
diff --git a/ydb/public/lib/deprecated/kicli/ut/ya.make b/ydb/public/lib/deprecated/kicli/ut/ya.make
index b9d6c5d59ca..ce45125f076 100644
--- a/ydb/public/lib/deprecated/kicli/ut/ya.make
+++ b/ydb/public/lib/deprecated/kicli/ut/ya.make
@@ -1,26 +1,26 @@
UNITTEST_FOR(ydb/public/lib/deprecated/kicli)
-
+
OWNER(
xenoxeno
g:kikimr
)
-
+
TIMEOUT(600)
SIZE(MEDIUM)
FORK_SUBTESTS()
-PEERDIR(
+PEERDIR(
ydb/core/client
ydb/core/testlib
ydb/public/lib/deprecated/kicli
-)
-
+)
+
YQL_LAST_ABI_VERSION()
-SRCS(
- cpp_ut.cpp
-)
-
-END()
+SRCS(
+ cpp_ut.cpp
+)
+
+END()
diff --git a/ydb/public/lib/deprecated/kicli/ya.make b/ydb/public/lib/deprecated/kicli/ya.make
index aac87124a7d..d9aa54bc4cd 100644
--- a/ydb/public/lib/deprecated/kicli/ya.make
+++ b/ydb/public/lib/deprecated/kicli/ya.make
@@ -1,5 +1,5 @@
-LIBRARY()
-
+LIBRARY()
+
# See documentation
# https://wiki.yandex-team.ru/kikimr/techdoc/db/cxxapi/
@@ -7,19 +7,19 @@ OWNER(
xenoxeno
g:kikimr
)
-
-SRCS(
+
+SRCS(
configurator.cpp
dynamic_node.cpp
error.cpp
- kicli.h
- kikimr.cpp
- query.cpp
- result.cpp
- schema.cpp
-)
-
-PEERDIR(
+ kicli.h
+ kikimr.cpp
+ query.cpp
+ result.cpp
+ schema.cpp
+)
+
+PEERDIR(
contrib/libs/grpc
library/cpp/actors/core
library/cpp/threading/future
@@ -34,9 +34,9 @@ PEERDIR(
ydb/public/lib/value
ydb/library/yql/public/decimal
ydb/library/yql/public/issue
-)
-
-END()
+)
+
+END()
RECURSE_FOR_TESTS(
ut
diff --git a/ydb/public/lib/json_value/ydb_json_value.cpp b/ydb/public/lib/json_value/ydb_json_value.cpp
index 48b85c011fe..af126501a73 100644
--- a/ydb/public/lib/json_value/ydb_json_value.cpp
+++ b/ydb/public/lib/json_value/ydb_json_value.cpp
@@ -798,10 +798,10 @@ TValue JsonToYdbValue(const TString& jsonString, const TType& type, EBinaryStrin
TStringBuilder() << "Exception while parsing string \"" << jsonString << "\" as json: " << e.what());
}
return JsonToYdbValue(jsonValue, type, encoding);
-}
+}
TValue JsonToYdbValue(const NJson::TJsonValue& jsonValue, const TType& type, EBinaryStringEncoding encoding) {
- TValueBuilder builder;
+ TValueBuilder builder;
TTypeParser typeParser(type);
TJsonToYdbConverter converter(builder, jsonValue, typeParser, encoding);
diff --git a/ydb/public/lib/value/value.cpp b/ydb/public/lib/value/value.cpp
index 1f0c6197599..0ed8b826895 100644
--- a/ydb/public/lib/value/value.cpp
+++ b/ydb/public/lib/value/value.cpp
@@ -6,38 +6,38 @@
#include <util/charset/utf8.h>
#include <util/string/cast.h>
-#include <util/string/escape.h>
+#include <util/string/escape.h>
#include <util/string/printf.h>
-
-namespace NKikimr {
-namespace NClient {
-
-const NKikimrMiniKQL::TValue TValue::Null;
-
-TValue::TValue(NKikimrMiniKQL::TValue& value, NKikimrMiniKQL::TType& type)
- : Type(type)
- , Value(value)
-{}
-
-TValue TValue::Create(const NKikimrMiniKQL::TValue& value, const NKikimrMiniKQL::TType& type) {
- return TValue(const_cast<NKikimrMiniKQL::TValue&>(value), const_cast<NKikimrMiniKQL::TType&>(type));
-}
-
+
+namespace NKikimr {
+namespace NClient {
+
+const NKikimrMiniKQL::TValue TValue::Null;
+
+TValue::TValue(NKikimrMiniKQL::TValue& value, NKikimrMiniKQL::TType& type)
+ : Type(type)
+ , Value(value)
+{}
+
+TValue TValue::Create(const NKikimrMiniKQL::TValue& value, const NKikimrMiniKQL::TType& type) {
+ return TValue(const_cast<NKikimrMiniKQL::TValue&>(value), const_cast<NKikimrMiniKQL::TType&>(type));
+}
+
TValue TValue::Create(const NKikimrMiniKQL::TResult& result) {
return TValue::Create(result.GetValue(), result.GetType());
}
-bool TValue::HaveValue() const {
- return !IsNull();
-}
-
-bool TValue::IsNull() const {
- if (&Value == &Null)
- return true;
- return Value.ByteSize() == 0;
-}
-
-TValue TValue::operator [](const char* name) const {
+bool TValue::HaveValue() const {
+ return !IsNull();
+}
+
+bool TValue::IsNull() const {
+ if (&Value == &Null)
+ return true;
+ return Value.ByteSize() == 0;
+}
+
+TValue TValue::operator [](const char* name) const {
return this->operator [](TStringBuf(name));
}
@@ -56,117 +56,117 @@ int TValue::GetMemberIndex(TStringBuf name) const {
}
TValue TValue::operator [](const TStringBuf name) const {
- // TODO: add support for Dict
- Y_ASSERT(Type.HasStruct());
- const auto& structField = Type.GetStruct();
- size_t size = structField.MemberSize();
- for (size_t n = 0; n < size; ++n) {
- const auto& memberField = structField.GetMember(n);
- if (memberField.GetName() == name) {
- if (!HaveValue()) {
- return TValue::Create(Null, memberField.GetType()).EatOptional();
- }
- Y_ASSERT(Value.StructSize() > n);
- return TValue::Create(Value.GetStruct(n), memberField.GetType()).EatOptional();
- }
- }
- ythrow yexception() << "Unknown Struct member name: " << name;
-}
-
-TValue TValue::operator [](int index) const {
- Y_ASSERT(Type.HasList() || Type.HasTuple() || Type.HasStruct());
- if (Type.HasList()) {
- Y_ASSERT(Value.ListSize() > (size_t)index);
- return TValue::Create(Value.GetList(index), Type.GetList().GetItem()).EatOptional();
- } else if (Type.HasTuple()) {
- Y_ASSERT(Value.TupleSize() > (size_t)index);
- return TValue::Create(Value.GetTuple(index), Type.GetTuple().GetElement(index)).EatOptional();
- } else {
- Y_ASSERT(Value.StructSize() > (size_t)index);
- return TValue::Create(Value.GetStruct(index), Type.GetStruct().GetMember(index).GetType()).EatOptional();
- }
-}
-
+ // TODO: add support for Dict
+ Y_ASSERT(Type.HasStruct());
+ const auto& structField = Type.GetStruct();
+ size_t size = structField.MemberSize();
+ for (size_t n = 0; n < size; ++n) {
+ const auto& memberField = structField.GetMember(n);
+ if (memberField.GetName() == name) {
+ if (!HaveValue()) {
+ return TValue::Create(Null, memberField.GetType()).EatOptional();
+ }
+ Y_ASSERT(Value.StructSize() > n);
+ return TValue::Create(Value.GetStruct(n), memberField.GetType()).EatOptional();
+ }
+ }
+ ythrow yexception() << "Unknown Struct member name: " << name;
+}
+
+TValue TValue::operator [](int index) const {
+ Y_ASSERT(Type.HasList() || Type.HasTuple() || Type.HasStruct());
+ if (Type.HasList()) {
+ Y_ASSERT(Value.ListSize() > (size_t)index);
+ return TValue::Create(Value.GetList(index), Type.GetList().GetItem()).EatOptional();
+ } else if (Type.HasTuple()) {
+ Y_ASSERT(Value.TupleSize() > (size_t)index);
+ return TValue::Create(Value.GetTuple(index), Type.GetTuple().GetElement(index)).EatOptional();
+ } else {
+ Y_ASSERT(Value.StructSize() > (size_t)index);
+ return TValue::Create(Value.GetStruct(index), Type.GetStruct().GetMember(index).GetType()).EatOptional();
+ }
+}
+
TString TValue::GetMemberName(int index) const {
- Y_ASSERT(Type.HasStruct());
- const auto& structField = Type.GetStruct();
- size_t size = structField.MemberSize();
- Y_ASSERT((size_t)index < size);
- return structField.GetMember(index).GetName();
-}
-
+ Y_ASSERT(Type.HasStruct());
+ const auto& structField = Type.GetStruct();
+ size_t size = structField.MemberSize();
+ Y_ASSERT((size_t)index < size);
+ return structField.GetMember(index).GetName();
+}
+
TVector<TString> TValue::GetMembersNames() const {
- Y_ASSERT(Type.HasStruct());
- const auto& structField = Type.GetStruct();
- size_t size = structField.MemberSize();
+ Y_ASSERT(Type.HasStruct());
+ const auto& structField = Type.GetStruct();
+ size_t size = structField.MemberSize();
TVector<TString> members;
- members.reserve(size);
- for (int index = 0; (size_t)index < size; ++index) {
- members.emplace_back(structField.GetMember(index).GetName());
- }
- return members;
-}
-
-TWriteValue TWriteValue::Create(NKikimrMiniKQL::TValue& value, NKikimrMiniKQL::TType& type) {
- return TWriteValue(value, type);
-}
-
-TWriteValue::TWriteValue(NKikimrMiniKQL::TValue& value, NKikimrMiniKQL::TType& type)
- : TValue(value, type)
-{}
-
-TWriteValue TWriteValue::operator [](const char* name) {
+ members.reserve(size);
+ for (int index = 0; (size_t)index < size; ++index) {
+ members.emplace_back(structField.GetMember(index).GetName());
+ }
+ return members;
+}
+
+TWriteValue TWriteValue::Create(NKikimrMiniKQL::TValue& value, NKikimrMiniKQL::TType& type) {
+ return TWriteValue(value, type);
+}
+
+TWriteValue::TWriteValue(NKikimrMiniKQL::TValue& value, NKikimrMiniKQL::TType& type)
+ : TValue(value, type)
+{}
+
+TWriteValue TWriteValue::operator [](const char* name) {
return this->operator [](TStringBuf(name));
}
TWriteValue TWriteValue::operator [](const TStringBuf name) {
- Y_ASSERT(!Type.HasList() && !Type.HasTuple() && !Type.HasDict());
- Type.SetKind(NKikimrMiniKQL::ETypeKind::Struct);
- auto& structField = *Type.MutableStruct();
- size_t size = structField.MemberSize();
- for (size_t n = 0; n < size; ++n) {
- auto& memberField = *structField.MutableMember(n);
- if (memberField.GetName() == name) {
- if (Value.StructSize() <= n) {
- auto& str = *Value.MutableStruct();
- str.Reserve(n + 1);
- while (Value.StructSize() <= n) {
- str.Add();
- }
- }
- return TWriteValue::Create(*Value.MutableStruct(n), *memberField.MutableType());
- }
- }
- auto& memberField = *structField.AddMember();
+ Y_ASSERT(!Type.HasList() && !Type.HasTuple() && !Type.HasDict());
+ Type.SetKind(NKikimrMiniKQL::ETypeKind::Struct);
+ auto& structField = *Type.MutableStruct();
+ size_t size = structField.MemberSize();
+ for (size_t n = 0; n < size; ++n) {
+ auto& memberField = *structField.MutableMember(n);
+ if (memberField.GetName() == name) {
+ if (Value.StructSize() <= n) {
+ auto& str = *Value.MutableStruct();
+ str.Reserve(n + 1);
+ while (Value.StructSize() <= n) {
+ str.Add();
+ }
+ }
+ return TWriteValue::Create(*Value.MutableStruct(n), *memberField.MutableType());
+ }
+ }
+ auto& memberField = *structField.AddMember();
memberField.SetName(TString(name));
- return TWriteValue::Create(*Value.AddStruct(), *memberField.MutableType());
-}
-
-TWriteValue TWriteValue::operator [](int index) {
- Y_ASSERT(!Type.HasDict() && !Type.HasStruct());
- if (!Type.HasTuple()) {
- Type.SetKind(NKikimrMiniKQL::ETypeKind::List);
- NKikimrMiniKQL::TType* type = Type.MutableList()->MutableItem();
- NKikimrMiniKQL::TValue* value = Value.MutableList(index);
- return TWriteValue::Create(*value, *type);
- } else {
- Type.SetKind(NKikimrMiniKQL::ETypeKind::Tuple);
- NKikimrMiniKQL::TType* type = Type.MutableTuple()->MutableElement(index);
- NKikimrMiniKQL::TValue* value = Value.MutableTuple(index);
- return TWriteValue::Create(*value, *type);
- }
-}
-
-TWriteValue TWriteValue::Optional() {
- Type.SetKind(NKikimrMiniKQL::ETypeKind::Optional);
- return TWriteValue::Create(*Value.MutableOptional(), *Type.MutableOptional()->MutableItem());
-}
-
-TWriteValue TWriteValue::AddListItem() {
- Type.SetKind(NKikimrMiniKQL::ETypeKind::List);
- return TWriteValue::Create(*Value.AddList(), *Type.MutableList()->MutableItem());
-}
-
+ return TWriteValue::Create(*Value.AddStruct(), *memberField.MutableType());
+}
+
+TWriteValue TWriteValue::operator [](int index) {
+ Y_ASSERT(!Type.HasDict() && !Type.HasStruct());
+ if (!Type.HasTuple()) {
+ Type.SetKind(NKikimrMiniKQL::ETypeKind::List);
+ NKikimrMiniKQL::TType* type = Type.MutableList()->MutableItem();
+ NKikimrMiniKQL::TValue* value = Value.MutableList(index);
+ return TWriteValue::Create(*value, *type);
+ } else {
+ Type.SetKind(NKikimrMiniKQL::ETypeKind::Tuple);
+ NKikimrMiniKQL::TType* type = Type.MutableTuple()->MutableElement(index);
+ NKikimrMiniKQL::TValue* value = Value.MutableTuple(index);
+ return TWriteValue::Create(*value, *type);
+ }
+}
+
+TWriteValue TWriteValue::Optional() {
+ Type.SetKind(NKikimrMiniKQL::ETypeKind::Optional);
+ return TWriteValue::Create(*Value.MutableOptional(), *Type.MutableOptional()->MutableItem());
+}
+
+TWriteValue TWriteValue::AddListItem() {
+ Type.SetKind(NKikimrMiniKQL::ETypeKind::List);
+ return TWriteValue::Create(*Value.AddList(), *Type.MutableList()->MutableItem());
+}
+
TWriteValue TWriteValue::AddTupleItem() {
Type.SetKind(NKikimrMiniKQL::ETypeKind::Tuple);
NKikimrMiniKQL::TType* type = Type.MutableTuple()->AddElement();
@@ -174,11 +174,11 @@ TWriteValue TWriteValue::AddTupleItem() {
return TWriteValue::Create(*value, *type);
}
-TWriteValue& TWriteValue::Void() {
- Type.SetKind(NKikimrMiniKQL::ETypeKind::Void);
- return *this;
-}
-
+TWriteValue& TWriteValue::Void() {
+ Type.SetKind(NKikimrMiniKQL::ETypeKind::Void);
+ return *this;
+}
+
TWriteValue& TWriteValue::Bytes(const char* value) {
Type.SetKind(NKikimrMiniKQL::ETypeKind::Data);
Type.MutableData()->SetScheme(NScheme::NTypeIds::String);
@@ -249,13 +249,13 @@ TWriteValue& TWriteValue::Interval(i64 value) {
return *this;
}
-TWriteValue& TWriteValue::operator =(bool value) {
- Type.SetKind(NKikimrMiniKQL::ETypeKind::Data);
+TWriteValue& TWriteValue::operator =(bool value) {
+ Type.SetKind(NKikimrMiniKQL::ETypeKind::Data);
Type.MutableData()->SetScheme(NScheme::NTypeIds::Bool);
- Value.SetBool(value);
- return *this;
-}
-
+ Value.SetBool(value);
+ return *this;
+}
+
TWriteValue& TWriteValue::operator =(ui8 value) {
Type.SetKind(NKikimrMiniKQL::ETypeKind::Data);
Type.MutableData()->SetScheme(NScheme::NTypeIds::Uint8);
@@ -284,62 +284,62 @@ TWriteValue& TWriteValue::operator =(i16 value) {
return *this;
}
-TWriteValue& TWriteValue::operator =(ui64 value) {
- Type.SetKind(NKikimrMiniKQL::ETypeKind::Data);
+TWriteValue& TWriteValue::operator =(ui64 value) {
+ Type.SetKind(NKikimrMiniKQL::ETypeKind::Data);
Type.MutableData()->SetScheme(NScheme::NTypeIds::Uint64);
- Value.SetUint64(value);
- return *this;
-}
-
-TWriteValue& TWriteValue::operator =(i64 value) {
- Type.SetKind(NKikimrMiniKQL::ETypeKind::Data);
+ Value.SetUint64(value);
+ return *this;
+}
+
+TWriteValue& TWriteValue::operator =(i64 value) {
+ Type.SetKind(NKikimrMiniKQL::ETypeKind::Data);
Type.MutableData()->SetScheme(NScheme::NTypeIds::Int64);
- Value.SetInt64(value);
- return *this;
-}
-
-TWriteValue& TWriteValue::operator =(ui32 value) {
- Type.SetKind(NKikimrMiniKQL::ETypeKind::Data);
+ Value.SetInt64(value);
+ return *this;
+}
+
+TWriteValue& TWriteValue::operator =(ui32 value) {
+ Type.SetKind(NKikimrMiniKQL::ETypeKind::Data);
Type.MutableData()->SetScheme(NScheme::NTypeIds::Uint32);
- Value.SetUint32(value);
- return *this;
-}
-
-TWriteValue& TWriteValue::operator =(i32 value) {
- Type.SetKind(NKikimrMiniKQL::ETypeKind::Data);
+ Value.SetUint32(value);
+ return *this;
+}
+
+TWriteValue& TWriteValue::operator =(i32 value) {
+ Type.SetKind(NKikimrMiniKQL::ETypeKind::Data);
Type.MutableData()->SetScheme(NScheme::NTypeIds::Int32);
- Value.SetInt32(value);
- return *this;
-}
-
-TWriteValue& TWriteValue::operator =(double value) {
- Type.SetKind(NKikimrMiniKQL::ETypeKind::Data);
+ Value.SetInt32(value);
+ return *this;
+}
+
+TWriteValue& TWriteValue::operator =(double value) {
+ Type.SetKind(NKikimrMiniKQL::ETypeKind::Data);
Type.MutableData()->SetScheme(NScheme::NTypeIds::Double);
- Value.SetDouble(value);
- return *this;
-}
-
-TWriteValue& TWriteValue::operator =(float value) {
- Type.SetKind(NKikimrMiniKQL::ETypeKind::Data);
+ Value.SetDouble(value);
+ return *this;
+}
+
+TWriteValue& TWriteValue::operator =(float value) {
+ Type.SetKind(NKikimrMiniKQL::ETypeKind::Data);
Type.MutableData()->SetScheme(NScheme::NTypeIds::Float);
- Value.SetFloat(value);
- return *this;
-}
-
+ Value.SetFloat(value);
+ return *this;
+}
+
TWriteValue& TWriteValue::operator =(const TString& value) {
- Type.SetKind(NKikimrMiniKQL::ETypeKind::Data);
+ Type.SetKind(NKikimrMiniKQL::ETypeKind::Data);
Type.MutableData()->SetScheme(NScheme::NTypeIds::Utf8);
- Value.SetText(value);
- return *this;
-}
-
-TWriteValue& TWriteValue::operator =(const char* value) {
- Type.SetKind(NKikimrMiniKQL::ETypeKind::Data);
+ Value.SetText(value);
+ return *this;
+}
+
+TWriteValue& TWriteValue::operator =(const char* value) {
+ Type.SetKind(NKikimrMiniKQL::ETypeKind::Data);
Type.MutableData()->SetScheme(NScheme::NTypeIds::Utf8);
- Value.SetText(value);
- return *this;
-}
-
+ Value.SetText(value);
+ return *this;
+}
+
TWriteValue& TWriteValue::operator =(const TValue& value) {
Type.CopyFrom(value.GetType());
Value.CopyFrom(value.GetValue());
@@ -358,50 +358,50 @@ ui32 TWriteValue::GetBytesSize() const {
return GetValueBytesSize() + GetTypeBytesSize();
}
-size_t TValue::Size() const {
- if (Type.HasList())
- return Value.ListSize();
- if (Type.HasTuple())
- return Value.TupleSize();
+size_t TValue::Size() const {
+ if (Type.HasList())
+ return Value.ListSize();
+ if (Type.HasTuple())
+ return Value.TupleSize();
if (Type.HasStruct())
return Value.StructSize();
- return 0;
-}
-
+ return 0;
+}
+
NScheme::TTypeId TValue::GetDataType() const {
- // TODO: support for complex types
- Y_ASSERT(Type.GetKind() == NKikimrMiniKQL::ETypeKind::Data);
- return Type.GetData().GetScheme();
-}
-
+ // TODO: support for complex types
+ Y_ASSERT(Type.GetKind() == NKikimrMiniKQL::ETypeKind::Data);
+ return Type.GetData().GetScheme();
+}
+
TString TValue::GetDataText() const {
- Y_ASSERT(Type.GetKind() == NKikimrMiniKQL::ETypeKind::Data);
- switch (Type.GetData().GetScheme()) {
+ Y_ASSERT(Type.GetKind() == NKikimrMiniKQL::ETypeKind::Data);
+ switch (Type.GetData().GetScheme()) {
case NScheme::NTypeIds::Bool:
- return Value.GetBool() ? "true" : "false";
+ return Value.GetBool() ? "true" : "false";
case NScheme::NTypeIds::Uint64:
- return ToString(Value.GetUint64());
+ return ToString(Value.GetUint64());
case NScheme::NTypeIds::Int64:
- return ToString(Value.GetInt64());
+ return ToString(Value.GetInt64());
case NScheme::NTypeIds::Uint32:
- case NScheme::NTypeIds::Uint16:
- case NScheme::NTypeIds::Uint8:
- return ToString(Value.GetUint32());
+ case NScheme::NTypeIds::Uint16:
+ case NScheme::NTypeIds::Uint8:
+ return ToString(Value.GetUint32());
case NScheme::NTypeIds::Int32:
- case NScheme::NTypeIds::Int16:
- case NScheme::NTypeIds::Int8:
- return ToString(Value.GetInt32());
+ case NScheme::NTypeIds::Int16:
+ case NScheme::NTypeIds::Int8:
+ return ToString(Value.GetInt32());
case NScheme::NTypeIds::Double:
- return ToString(Value.GetDouble());
+ return ToString(Value.GetDouble());
case NScheme::NTypeIds::Float:
- return ToString(Value.GetFloat());
+ return ToString(Value.GetFloat());
case NScheme::NTypeIds::Utf8:
case NScheme::NTypeIds::Json:
- return Value.GetText();
+ return Value.GetText();
case NScheme::NTypeIds::String:
case NScheme::NTypeIds::String4k:
case NScheme::NTypeIds::String2m:
- return Value.GetBytes();
+ return Value.GetBytes();
case NScheme::NTypeIds::Decimal:
{
NYql::NDecimal::TInt128 val;
@@ -412,112 +412,112 @@ TString TValue::GetDataText() const {
Type.GetData().GetDecimalParams().GetPrecision(),
Type.GetData().GetDecimalParams().GetScale());
}
- case NScheme::NTypeIds::Date:
- case NScheme::NTypeIds::Datetime:
- return ToString(Value.GetUint32());
- case NScheme::NTypeIds::Timestamp:
+ case NScheme::NTypeIds::Date:
+ case NScheme::NTypeIds::Datetime:
+ return ToString(Value.GetUint32());
+ case NScheme::NTypeIds::Timestamp:
return ToString(Value.GetUint64());
- case NScheme::NTypeIds::Interval:
+ case NScheme::NTypeIds::Interval:
return ToString(Value.GetInt64());
case NScheme::NTypeIds::JsonDocument:
return "\"<JsonDocument>\"";
- }
+ }
return TStringBuilder() << "\"<unknown type " << Type.GetData().GetScheme() << ">\"";
-}
-
+}
+
template <> TString TValue::GetTypeText<TFormatCxx>(const TFormatCxx& format) const {
- switch(Type.GetKind()) {
- case NKikimrMiniKQL::ETypeKind::Void:
- return "void";
- case NKikimrMiniKQL::ETypeKind::Data:
+ switch(Type.GetKind()) {
+ case NKikimrMiniKQL::ETypeKind::Void:
+ return "void";
+ case NKikimrMiniKQL::ETypeKind::Data:
return NScheme::TypeName(GetDataType());
- case NKikimrMiniKQL::ETypeKind::Optional:
- return "optional<" + TValue::Create(Null, Type.GetOptional().GetItem()).GetTypeText<TFormatCxx>(format) + ">";
- case NKikimrMiniKQL::ETypeKind::List:
- return "list<" + TValue::Create(Null, Type.GetList().GetItem()).GetTypeText<TFormatCxx>(format) + ">";
- case NKikimrMiniKQL::ETypeKind::Tuple:
- {
+ case NKikimrMiniKQL::ETypeKind::Optional:
+ return "optional<" + TValue::Create(Null, Type.GetOptional().GetItem()).GetTypeText<TFormatCxx>(format) + ">";
+ case NKikimrMiniKQL::ETypeKind::List:
+ return "list<" + TValue::Create(Null, Type.GetList().GetItem()).GetTypeText<TFormatCxx>(format) + ">";
+ case NKikimrMiniKQL::ETypeKind::Tuple:
+ {
TString typeName = "tuple<";
- const auto& element = Type.GetTuple().GetElement();
- for (auto it = element.begin(); it != element.end(); ++it) {
- if (it != element.begin())
- typeName += ',';
- typeName += TValue::Create(Null, *it).GetTypeText<TFormatCxx>(format);
- }
- typeName += ">";
- return typeName;
- }
- case NKikimrMiniKQL::ETypeKind::Struct:
- {
+ const auto& element = Type.GetTuple().GetElement();
+ for (auto it = element.begin(); it != element.end(); ++it) {
+ if (it != element.begin())
+ typeName += ',';
+ typeName += TValue::Create(Null, *it).GetTypeText<TFormatCxx>(format);
+ }
+ typeName += ">";
+ return typeName;
+ }
+ case NKikimrMiniKQL::ETypeKind::Struct:
+ {
TString typeName = "struct{";
- const auto& member = Type.GetStruct().GetMember();
- for (auto it = member.begin(); it != member.end(); ++it) {
- typeName += TValue::Create(Null, it->GetType()).GetTypeText<TFormatCxx>(format);
- typeName += ' ';
- typeName += it->GetName();
- typeName += ';';
- }
- typeName += "}";
- return typeName;
- }
- case NKikimrMiniKQL::ETypeKind::Dict:
- return "dict<" + TValue::Create(Null, Type.GetDict().GetKey()).GetTypeText<TFormatCxx>(format) + "," + TValue::Create(Null, Type.GetDict().GetPayload()).GetTypeText<TFormatCxx>(format) + ">";
- default:
- return "<unknown>";
- }
-}
-
-TString EscapeJsonUTF8(const TString& s) {
+ const auto& member = Type.GetStruct().GetMember();
+ for (auto it = member.begin(); it != member.end(); ++it) {
+ typeName += TValue::Create(Null, it->GetType()).GetTypeText<TFormatCxx>(format);
+ typeName += ' ';
+ typeName += it->GetName();
+ typeName += ';';
+ }
+ typeName += "}";
+ return typeName;
+ }
+ case NKikimrMiniKQL::ETypeKind::Dict:
+ return "dict<" + TValue::Create(Null, Type.GetDict().GetKey()).GetTypeText<TFormatCxx>(format) + "," + TValue::Create(Null, Type.GetDict().GetPayload()).GetTypeText<TFormatCxx>(format) + ">";
+ default:
+ return "<unknown>";
+ }
+}
+
+TString EscapeJsonUTF8(const TString& s) {
+ TString result;
+ result.reserve(s.size());
+ const char* b = s.begin();
+ const char* e = s.end();
+ const char* p = b;
+ while (p < e) {
+ size_t len = 1;
+ RECODE_RESULT res = GetUTF8CharLen(
+ len,
+ reinterpret_cast<const unsigned char*>(p),
+ reinterpret_cast<const unsigned char*>(e)
+ );
+ if (res == RECODE_OK && len != 1) {
+ len = std::min<decltype(len)>(len, e - p);
+ result.append(p, len);
+ p += len;
+ } else {
+ char c = *p;
+ if (c < '\x20') {
+ result.append(Sprintf("\\u%04x", int(c)));
+ } else if (c == '"') {
+ result.append("\\\"");
+ } else if (c == '\\') {
+ result.append("\\\\");
+ } else {
+ result.append(c);
+ }
+ ++p;
+ }
+ }
+ return result;
+}
+
+TString EscapeJsonASCII(const TString& s) {
TString result;
- result.reserve(s.size());
- const char* b = s.begin();
- const char* e = s.end();
- const char* p = b;
- while (p < e) {
- size_t len = 1;
- RECODE_RESULT res = GetUTF8CharLen(
- len,
- reinterpret_cast<const unsigned char*>(p),
- reinterpret_cast<const unsigned char*>(e)
- );
- if (res == RECODE_OK && len != 1) {
- len = std::min<decltype(len)>(len, e - p);
- result.append(p, len);
- p += len;
- } else {
- char c = *p;
- if (c < '\x20') {
- result.append(Sprintf("\\u%04x", int(c)));
- } else if (c == '"') {
- result.append("\\\"");
- } else if (c == '\\') {
- result.append("\\\\");
- } else {
- result.append(c);
- }
- ++p;
- }
- }
- return result;
-}
-
-TString EscapeJsonASCII(const TString& s) {
- TString result;
- result.reserve(s.size());
- for (char c : s) {
- if (c < '\x20' || c > '\x7f') /*c is signed type, check for >0x7f is not necessary*/ {
- result.append(Sprintf("\\u%04x", static_cast<unsigned int>(c)));
- } else if (c == '"') {
- result.append("\\\"");
- } else if (c == '\\') {
- result.append("\\\\");
- } else {
- result.append(c);
- }
- }
- return result;
-}
-
+ result.reserve(s.size());
+ for (char c : s) {
+ if (c < '\x20' || c > '\x7f') /*c is signed type, check for >0x7f is not necessary*/ {
+ result.append(Sprintf("\\u%04x", static_cast<unsigned int>(c)));
+ } else if (c == '"') {
+ result.append("\\\"");
+ } else if (c == '\\') {
+ result.append("\\\\");
+ } else {
+ result.append(c);
+ }
+ }
+ return result;
+}
+
TString TFormatCSV::EscapeString(const TString& s) {
TString result;
result.reserve(s.size());
@@ -578,205 +578,205 @@ TString PrintCsvHeader(const NKikimrMiniKQL::TType& type,
}
template <> TString TValue::GetValueText<TFormatJSON>(const TFormatJSON& format) const {
- switch(Type.GetKind()) {
- case NKikimrMiniKQL::ETypeKind::Void:
- return "null";
- case NKikimrMiniKQL::ETypeKind::Data: {
- switch (Type.GetData().GetScheme()) {
+ switch(Type.GetKind()) {
+ case NKikimrMiniKQL::ETypeKind::Void:
+ return "null";
+ case NKikimrMiniKQL::ETypeKind::Data: {
+ switch (Type.GetData().GetScheme()) {
case NScheme::NTypeIds::Utf8:
- return "\"" + EscapeJsonUTF8(GetDataText()) + "\"";
+ return "\"" + EscapeJsonUTF8(GetDataText()) + "\"";
case NScheme::NTypeIds::String:
case NScheme::NTypeIds::String4k:
case NScheme::NTypeIds::String2m:
- if (format.BinaryAsBase64) {
- return "\"" + Base64Encode(GetDataText()) + "\"";
- } else {
- return "\"" + EscapeJsonASCII(GetDataText()) + "\"";
- }
- case NScheme::NTypeIds::Uint64:
- case NScheme::NTypeIds::Int64:
+ if (format.BinaryAsBase64) {
+ return "\"" + Base64Encode(GetDataText()) + "\"";
+ } else {
+ return "\"" + EscapeJsonASCII(GetDataText()) + "\"";
+ }
+ case NScheme::NTypeIds::Uint64:
+ case NScheme::NTypeIds::Int64:
case NScheme::NTypeIds::Timestamp:
case NScheme::NTypeIds::Interval:
- return format.UI64AsString ? ("\"" + GetDataText() + "\"") : GetDataText();
- default:
- return GetDataText();
- }
- }
- case NKikimrMiniKQL::ETypeKind::Optional: {
- if (Value.HasOptional()) {
- return TValue::Create(Value.GetOptional(), Type.GetOptional().GetItem()).GetValueText<TFormatJSON>(format);
- } else {
- return "null";
- }
- }
- case NKikimrMiniKQL::ETypeKind::List:
- {
+ return format.UI64AsString ? ("\"" + GetDataText() + "\"") : GetDataText();
+ default:
+ return GetDataText();
+ }
+ }
+ case NKikimrMiniKQL::ETypeKind::Optional: {
+ if (Value.HasOptional()) {
+ return TValue::Create(Value.GetOptional(), Type.GetOptional().GetItem()).GetValueText<TFormatJSON>(format);
+ } else {
+ return "null";
+ }
+ }
+ case NKikimrMiniKQL::ETypeKind::List:
+ {
TString valueText = "[";
- const auto& list = Value.GetList();
- const auto& type = Type.GetList().GetItem();
- for (auto it = list.begin(); it != list.end(); ++it) {
- if (it != list.begin())
- valueText += ", ";
- valueText += TValue::Create(*it, type).GetValueText<TFormatJSON>(format);
- }
- valueText += ']';
- return valueText;
- }
- case NKikimrMiniKQL::ETypeKind::Tuple:
- {
+ const auto& list = Value.GetList();
+ const auto& type = Type.GetList().GetItem();
+ for (auto it = list.begin(); it != list.end(); ++it) {
+ if (it != list.begin())
+ valueText += ", ";
+ valueText += TValue::Create(*it, type).GetValueText<TFormatJSON>(format);
+ }
+ valueText += ']';
+ return valueText;
+ }
+ case NKikimrMiniKQL::ETypeKind::Tuple:
+ {
TString valueText = "[";
- const auto& tuple = Value.GetTuple();
- const auto& type = Type.GetTuple().GetElement();
- size_t maxElements = type.size();
- for (size_t element = 0; element < maxElements; ++element) {
- if (element != 0)
- valueText += ", ";
- valueText += TValue::Create(tuple.Get(element), type.Get(element)).GetValueText<TFormatJSON>(format);
- }
- valueText += ']';
- return valueText;
- }
- case NKikimrMiniKQL::ETypeKind::Struct:
- {
+ const auto& tuple = Value.GetTuple();
+ const auto& type = Type.GetTuple().GetElement();
+ size_t maxElements = type.size();
+ for (size_t element = 0; element < maxElements; ++element) {
+ if (element != 0)
+ valueText += ", ";
+ valueText += TValue::Create(tuple.Get(element), type.Get(element)).GetValueText<TFormatJSON>(format);
+ }
+ valueText += ']';
+ return valueText;
+ }
+ case NKikimrMiniKQL::ETypeKind::Struct:
+ {
TString valueText = "{";
- const auto& str = Value.GetStruct();
- const auto& type = Type.GetStruct().GetMember();
- size_t maxElements = type.size();
- for (size_t element = 0; element < maxElements; ++element) {
- if (element != 0)
- valueText += ", ";
- valueText += '"';
- valueText += type.Get(element).GetName();
- valueText += "\": ";
- valueText += TValue::Create(str.Get(element), type.Get(element).GetType()).GetValueText<TFormatJSON>(format);
- }
- valueText += '}';
- return valueText;
- }
- case NKikimrMiniKQL::ETypeKind::Dict:
- {
+ const auto& str = Value.GetStruct();
+ const auto& type = Type.GetStruct().GetMember();
+ size_t maxElements = type.size();
+ for (size_t element = 0; element < maxElements; ++element) {
+ if (element != 0)
+ valueText += ", ";
+ valueText += '"';
+ valueText += type.Get(element).GetName();
+ valueText += "\": ";
+ valueText += TValue::Create(str.Get(element), type.Get(element).GetType()).GetValueText<TFormatJSON>(format);
+ }
+ valueText += '}';
+ return valueText;
+ }
+ case NKikimrMiniKQL::ETypeKind::Dict:
+ {
TString valueText = "{";
- const auto& dict = Value.GetDict();
- const auto& type = Type.GetDict();
- for (auto it = dict.begin(); it != dict.end(); ++it) {
- if (it != dict.begin())
- valueText += ", ";
- valueText += "\"Key\": ";
- valueText += TValue::Create(it->GetKey(), type.GetKey()).GetValueText<TFormatJSON>(format);
- valueText += ", ";
- valueText += "\"Payload\": ";
- valueText += TValue::Create(it->GetPayload(), type.GetPayload()).GetValueText<TFormatJSON>(format);
- }
- valueText += '}';
- return valueText;
- }
- default:
- // TODO
- return "null";
- }
-}
-
+ const auto& dict = Value.GetDict();
+ const auto& type = Type.GetDict();
+ for (auto it = dict.begin(); it != dict.end(); ++it) {
+ if (it != dict.begin())
+ valueText += ", ";
+ valueText += "\"Key\": ";
+ valueText += TValue::Create(it->GetKey(), type.GetKey()).GetValueText<TFormatJSON>(format);
+ valueText += ", ";
+ valueText += "\"Payload\": ";
+ valueText += TValue::Create(it->GetPayload(), type.GetPayload()).GetValueText<TFormatJSON>(format);
+ }
+ valueText += '}';
+ return valueText;
+ }
+ default:
+ // TODO
+ return "null";
+ }
+}
+
template <> TString TValue::GetValueText<TFormatRowset>(const TFormatRowset& format) const {
- if (HaveValue()) {
- switch(Type.GetKind()) {
- case NKikimrMiniKQL::ETypeKind::Void:
- return "<void>";
- case NKikimrMiniKQL::ETypeKind::Data:
- return GetDataText();
- case NKikimrMiniKQL::ETypeKind::Optional:
- return TValue::Create(Value.GetOptional(), Type.GetOptional().GetItem()).GetValueText<TFormatRowset>(format);
- case NKikimrMiniKQL::ETypeKind::List:
- {
+ if (HaveValue()) {
+ switch(Type.GetKind()) {
+ case NKikimrMiniKQL::ETypeKind::Void:
+ return "<void>";
+ case NKikimrMiniKQL::ETypeKind::Data:
+ return GetDataText();
+ case NKikimrMiniKQL::ETypeKind::Optional:
+ return TValue::Create(Value.GetOptional(), Type.GetOptional().GetItem()).GetValueText<TFormatRowset>(format);
+ case NKikimrMiniKQL::ETypeKind::List:
+ {
TString valueText;
- if (Type.GetList().GetItem().GetKind() == NKikimrMiniKQL::ETypeKind::Struct) {
- const auto& list_type = Type.GetList();
- const auto& type = list_type.GetItem().GetStruct().GetMember();
- size_t maxElements = type.size();
- for (size_t element = 0; element < maxElements; ++element) {
- if (element != 0)
- valueText += "\t"; // TODO: alignment
- valueText += type.Get(element).GetName();
- }
- valueText += "\n";
- size_t maxItems = Value.ListSize();
- for (size_t items = 0; items < maxItems; ++items) {
- const auto& list = Value.GetList(items);
- const auto& str = list.GetStruct();
- for (size_t element = 0; element < maxElements; ++element) {
- if (element != 0)
- valueText += "\t"; // TODO: alignment
- valueText += TValue::Create(str.Get(element), type.Get(element).GetType()).GetValueText<TFormatRowset>(format);
- }
- valueText += "\n";
- }
- } else {
- const auto& list = Value.GetList();
- const auto& type = Type.GetList().GetItem();
- for (auto it = list.begin(); it != list.end(); ++it) {
- valueText += TValue::Create(*it, type).GetValueText<TFormatRowset>(format);
- valueText += "\n";
- }
- }
- return valueText;
- }
- case NKikimrMiniKQL::ETypeKind::Tuple:
- {
+ if (Type.GetList().GetItem().GetKind() == NKikimrMiniKQL::ETypeKind::Struct) {
+ const auto& list_type = Type.GetList();
+ const auto& type = list_type.GetItem().GetStruct().GetMember();
+ size_t maxElements = type.size();
+ for (size_t element = 0; element < maxElements; ++element) {
+ if (element != 0)
+ valueText += "\t"; // TODO: alignment
+ valueText += type.Get(element).GetName();
+ }
+ valueText += "\n";
+ size_t maxItems = Value.ListSize();
+ for (size_t items = 0; items < maxItems; ++items) {
+ const auto& list = Value.GetList(items);
+ const auto& str = list.GetStruct();
+ for (size_t element = 0; element < maxElements; ++element) {
+ if (element != 0)
+ valueText += "\t"; // TODO: alignment
+ valueText += TValue::Create(str.Get(element), type.Get(element).GetType()).GetValueText<TFormatRowset>(format);
+ }
+ valueText += "\n";
+ }
+ } else {
+ const auto& list = Value.GetList();
+ const auto& type = Type.GetList().GetItem();
+ for (auto it = list.begin(); it != list.end(); ++it) {
+ valueText += TValue::Create(*it, type).GetValueText<TFormatRowset>(format);
+ valueText += "\n";
+ }
+ }
+ return valueText;
+ }
+ case NKikimrMiniKQL::ETypeKind::Tuple:
+ {
TString valueText = "[";
- const auto& tuple = Value.GetTuple();
- const auto& type = Type.GetTuple().GetElement();
- size_t maxElements = type.size();
- for (size_t element = 0; element < maxElements; ++element) {
- if (element != 0)
- valueText += ", ";
- valueText += TValue::Create(tuple.Get(element), type.Get(element)).GetValueText<TFormatRowset>(format);
- }
- valueText += ']';
- return valueText;
- }
- case NKikimrMiniKQL::ETypeKind::Struct:
- {
+ const auto& tuple = Value.GetTuple();
+ const auto& type = Type.GetTuple().GetElement();
+ size_t maxElements = type.size();
+ for (size_t element = 0; element < maxElements; ++element) {
+ if (element != 0)
+ valueText += ", ";
+ valueText += TValue::Create(tuple.Get(element), type.Get(element)).GetValueText<TFormatRowset>(format);
+ }
+ valueText += ']';
+ return valueText;
+ }
+ case NKikimrMiniKQL::ETypeKind::Struct:
+ {
TString valueText = "";
- const auto& str = Value.GetStruct();
- const auto& type = Type.GetStruct().GetMember();
- size_t maxElements = type.size();
- for (size_t element = 0; element < maxElements; ++element) {
- if (element != 0)
- valueText += "\t"; // TODO: alignment
- valueText += type.Get(element).GetName();
- }
- valueText += "\n";
- for (size_t element = 0; element < maxElements; ++element) {
- if (element != 0)
- valueText += "\t"; // TODO: alignment
- valueText += TValue::Create(str.Get(element), type.Get(element).GetType()).GetValueText<TFormatRowset>(format);
- }
- valueText += "\n";
- return valueText;
- }
- case NKikimrMiniKQL::ETypeKind::Dict:
- {
+ const auto& str = Value.GetStruct();
+ const auto& type = Type.GetStruct().GetMember();
+ size_t maxElements = type.size();
+ for (size_t element = 0; element < maxElements; ++element) {
+ if (element != 0)
+ valueText += "\t"; // TODO: alignment
+ valueText += type.Get(element).GetName();
+ }
+ valueText += "\n";
+ for (size_t element = 0; element < maxElements; ++element) {
+ if (element != 0)
+ valueText += "\t"; // TODO: alignment
+ valueText += TValue::Create(str.Get(element), type.Get(element).GetType()).GetValueText<TFormatRowset>(format);
+ }
+ valueText += "\n";
+ return valueText;
+ }
+ case NKikimrMiniKQL::ETypeKind::Dict:
+ {
TString valueText = "";
- const auto& dict = Value.GetDict();
- const auto& type = Type.GetDict();
- valueText += "Key";
- valueText += "\t"; // TODO: alignment
- valueText += "Payload";
- valueText += "\n";
- for (auto it = dict.begin(); it != dict.end(); ++it) {
- valueText += TValue::Create(it->GetKey(), type.GetKey()).GetValueText<TFormatRowset>(format);
- valueText += "\t"; // TODO: alignment
- valueText += TValue::Create(it->GetPayload(), type.GetPayload()).GetValueText<TFormatRowset>(format);
- valueText += "\n";
- }
- return valueText;
- }
- default:
- return "<unknown>";
- }
- }
- return "<null>";
-}
-
+ const auto& dict = Value.GetDict();
+ const auto& type = Type.GetDict();
+ valueText += "Key";
+ valueText += "\t"; // TODO: alignment
+ valueText += "Payload";
+ valueText += "\n";
+ for (auto it = dict.begin(); it != dict.end(); ++it) {
+ valueText += TValue::Create(it->GetKey(), type.GetKey()).GetValueText<TFormatRowset>(format);
+ valueText += "\t"; // TODO: alignment
+ valueText += TValue::Create(it->GetPayload(), type.GetPayload()).GetValueText<TFormatRowset>(format);
+ valueText += "\n";
+ }
+ return valueText;
+ }
+ default:
+ return "<unknown>";
+ }
+ }
+ return "<null>";
+}
+
template <> TString TValue::GetValueText<TFormatCSV>(const TFormatCSV &format) const {
if (format.PrintHeader) {
auto hdr = PrintCsvHeader(Type, format) + "\n";
@@ -867,54 +867,54 @@ template <> TString TValue::GetValueText<TFormatCSV>(const TFormatCSV &format) c
}
}
-TValue TValue::EatOptional() const {
- if (Type.HasOptional() && (Value.HasOptional() || !HaveValue()))
- return TValue::Create(Value.HasOptional() ? Value.GetOptional() : Null, Type.GetOptional().GetItem()).EatOptional();
- return *this;
-}
-
-TValue::operator ui64() const {
+TValue TValue::EatOptional() const {
+ if (Type.HasOptional() && (Value.HasOptional() || !HaveValue()))
+ return TValue::Create(Value.HasOptional() ? Value.GetOptional() : Null, Type.GetOptional().GetItem()).EatOptional();
+ return *this;
+}
+
+TValue::operator ui64() const {
Y_ASSERT(Type.GetData().GetScheme() == NScheme::NTypeIds::Uint64);
- Y_ASSERT(Value.HasUint64());
- return Value.GetUint64();
-}
-
-TValue::operator i64() const {
+ Y_ASSERT(Value.HasUint64());
+ return Value.GetUint64();
+}
+
+TValue::operator i64() const {
Y_ASSERT(Type.GetData().GetScheme() == NScheme::NTypeIds::Int64);
- Y_ASSERT(Value.HasInt64());
- return Value.GetInt64();
-}
-
-TValue::operator ui32() const {
+ Y_ASSERT(Value.HasInt64());
+ return Value.GetInt64();
+}
+
+TValue::operator ui32() const {
Y_ASSERT(Type.GetData().GetScheme() == NScheme::NTypeIds::Uint32);
- Y_ASSERT(Value.HasUint32());
- return Value.GetUint32();
-}
-
-TValue::operator i32() const {
+ Y_ASSERT(Value.HasUint32());
+ return Value.GetUint32();
+}
+
+TValue::operator i32() const {
Y_ASSERT(Type.GetData().GetScheme() == NScheme::NTypeIds::Int32);
- Y_ASSERT(Value.HasInt32());
- return Value.GetInt32();
-}
-
-TValue::operator double() const {
+ Y_ASSERT(Value.HasInt32());
+ return Value.GetInt32();
+}
+
+TValue::operator double() const {
Y_ASSERT(Type.GetData().GetScheme() == NScheme::NTypeIds::Double);
- Y_ASSERT(Value.HasDouble());
- return Value.GetDouble();
-}
-
-TValue::operator float() const {
+ Y_ASSERT(Value.HasDouble());
+ return Value.GetDouble();
+}
+
+TValue::operator float() const {
Y_ASSERT(Type.GetData().GetScheme() == NScheme::NTypeIds::Float);
- Y_ASSERT(Value.HasFloat());
- return Value.GetFloat();
-}
-
-TValue::operator bool() const {
+ Y_ASSERT(Value.HasFloat());
+ return Value.GetFloat();
+}
+
+TValue::operator bool() const {
Y_ASSERT(Type.GetData().GetScheme() == NScheme::NTypeIds::Bool);
- Y_ASSERT(Value.HasBool());
- return Value.GetBool();
-}
-
+ Y_ASSERT(Value.HasBool());
+ return Value.GetBool();
+}
+
TValue::operator ui8() const {
Y_ASSERT(Type.GetData().GetScheme() == NScheme::NTypeIds::Uint8);
Y_ASSERT(Value.HasUint32());
@@ -946,13 +946,13 @@ TValue::operator TString() const {
|| Type.GetData().GetScheme() == NScheme::NTypeIds::String2m
|| Type.GetData().GetScheme() == NScheme::NTypeIds::Yson
|| Type.GetData().GetScheme() == NScheme::NTypeIds::Json
- );
- Y_ASSERT(Value.HasText() || Value.HasBytes());
+ );
+ Y_ASSERT(Value.HasText() || Value.HasBytes());
return (Type.GetData().GetScheme() == NScheme::NTypeIds::Utf8
|| Type.GetData().GetScheme() == NScheme::NTypeIds::Json)
? Value.GetText() : Value.GetBytes();
-}
-
-
-}
-}
+}
+
+
+}
+}
diff --git a/ydb/public/lib/value/value.h b/ydb/public/lib/value/value.h
index 0ed803bfa5f..8ae368ac027 100644
--- a/ydb/public/lib/value/value.h
+++ b/ydb/public/lib/value/value.h
@@ -200,20 +200,20 @@ protected:
TWriteValue(NKikimrMiniKQL::TValue& value, NKikimrMiniKQL::TType& type);
};
-struct TFormatCxx {};
-
-struct TFormatJSON {
- bool UI64AsString;
- bool BinaryAsBase64;
-
- TFormatJSON(bool ui64AsString = false, bool binaryAsBase64 = false)
- : UI64AsString(ui64AsString)
- , BinaryAsBase64(binaryAsBase64)
- {}
-};
-
-struct TFormatRowset {};
-struct TFormatCSV {
+struct TFormatCxx {};
+
+struct TFormatJSON {
+ bool UI64AsString;
+ bool BinaryAsBase64;
+
+ TFormatJSON(bool ui64AsString = false, bool binaryAsBase64 = false)
+ : UI64AsString(ui64AsString)
+ , BinaryAsBase64(binaryAsBase64)
+ {}
+};
+
+struct TFormatRowset {};
+struct TFormatCSV {
TFormatCSV(TString delim = ",", bool printHeader = false)
: Delim(delim)
, PrintHeader(printHeader)
diff --git a/ydb/public/lib/ydb_cli/common/command.cpp b/ydb/public/lib/ydb_cli/common/command.cpp
index 94c9ad2a0bf..ce7334d7388 100644
--- a/ydb/public/lib/ydb_cli/common/command.cpp
+++ b/ydb/public/lib/ydb_cli/common/command.cpp
@@ -1,12 +1,12 @@
#include "command.h"
#include "normalize_path.h"
-
+
namespace NYdb {
namespace NConsoleClient {
-
-bool TClientCommand::TIME_REQUESTS = false; // measure time of requests
-bool TClientCommand::PROGRESS_REQUESTS = false; // display progress of long requests
-
+
+bool TClientCommand::TIME_REQUESTS = false; // measure time of requests
+bool TClientCommand::PROGRESS_REQUESTS = false; // display progress of long requests
+
namespace {
TString FormatOption(const NLastGetopt::TOpt* option, const NColorizer::TColors& colors) {
using namespace NLastGetopt;
@@ -86,79 +86,79 @@ namespace {
}
TClientCommand::TClientCommand(const TString& name, const std::initializer_list<TString>& aliases, const TString& description)
- : Name(name)
- , Aliases(aliases)
- , Description(description)
- , Parent(nullptr)
- , Opts(NLastGetopt::TOpts::Default())
+ : Name(name)
+ , Aliases(aliases)
+ , Description(description)
+ , Parent(nullptr)
+ , Opts(NLastGetopt::TOpts::Default())
{
HideOption("svnrevision");
Opts.AddHelpOption('h');
ChangeOptionDescription("help", "Print usage");
Opts.SetWrap(Max(Opts.Wrap_, static_cast<ui32>(TermWidth())));
}
-
-
-TClientCommand::TOptsParseOneLevelResult::TOptsParseOneLevelResult(const NLastGetopt::TOpts* options, int argc, char** argv) {
- int _argc = 1;
- int levels = 1;
-
- while (levels > 0 && _argc < argc) {
- if (argv[_argc][0] == '-') {
- const NLastGetopt::TOpt* opt = nullptr;
- TStringBuf optName(argv[_argc]);
- auto eqPos = optName.find('=');
- optName = optName.substr(0, eqPos);
- if (optName.StartsWith("--")) {
- opt = options->FindLongOption(optName.substr(2));
- } else {
- opt = options->FindCharOption(optName[1]);
- }
- if (opt != nullptr && opt->GetHasArg() != NLastGetopt::NO_ARGUMENT) {
- if (eqPos == TStringBuf::npos) {
- ++_argc;
- }
- }
- } else {
- --levels;
- }
- ++_argc;
- }
- Init(options, _argc, const_cast<const char**>(argv));
-}
-
-void TClientCommand::Config(TConfig& config) {
- config.Opts = &Opts;
+
+
+TClientCommand::TOptsParseOneLevelResult::TOptsParseOneLevelResult(const NLastGetopt::TOpts* options, int argc, char** argv) {
+ int _argc = 1;
+ int levels = 1;
+
+ while (levels > 0 && _argc < argc) {
+ if (argv[_argc][0] == '-') {
+ const NLastGetopt::TOpt* opt = nullptr;
+ TStringBuf optName(argv[_argc]);
+ auto eqPos = optName.find('=');
+ optName = optName.substr(0, eqPos);
+ if (optName.StartsWith("--")) {
+ opt = options->FindLongOption(optName.substr(2));
+ } else {
+ opt = options->FindCharOption(optName[1]);
+ }
+ if (opt != nullptr && opt->GetHasArg() != NLastGetopt::NO_ARGUMENT) {
+ if (eqPos == TStringBuf::npos) {
+ ++_argc;
+ }
+ }
+ } else {
+ --levels;
+ }
+ ++_argc;
+ }
+ Init(options, _argc, const_cast<const char**>(argv));
+}
+
+void TClientCommand::Config(TConfig& config) {
+ config.Opts = &Opts;
TStringStream stream;
NColorizer::TColors colors = NColorizer::AutoColors(Cout);
stream << Endl << Endl
<< colors.BoldColor() << "Description" << colors.OldColor() << ": " << Description << Endl << Endl;
PrintParentOptions(stream, config, colors);
config.Opts->SetCmdLineDescr(stream.Str());
-}
-
-void TClientCommand::Parse(TConfig& config) {
- Y_UNUSED(config);
-}
-
-int TClientCommand::Run(TConfig& config) {
- Y_UNUSED(config);
- // TODO: invalid usage ? error? help?
+}
+
+void TClientCommand::Parse(TConfig& config) {
+ Y_UNUSED(config);
+}
+
+int TClientCommand::Run(TConfig& config) {
+ Y_UNUSED(config);
+ // TODO: invalid usage ? error? help?
return EXIT_FAILURE;
-}
-
-int TClientCommand::Process(TConfig& config) {
+}
+
+int TClientCommand::Process(TConfig& config) {
config.ArgsSettings.Reset(new TConfig::TArgSettings());
- config.Opts = &Opts;
- Config(config);
+ config.Opts = &Opts;
+ Config(config);
config.CheckParamsCount();
SetCustomUsage(config);
- NLastGetopt::TOptsParseResult parseResult(config.Opts, config.ArgC, config.ArgV);
- config.ParseResult = &parseResult;
- Parse(config);
- return Run(config);
-}
-
+ NLastGetopt::TOptsParseResult parseResult(config.Opts, config.ArgC, config.ArgV);
+ config.ParseResult = &parseResult;
+ Parse(config);
+ return Run(config);
+}
+
void TClientCommand::SetCustomUsage(TConfig& config) {
// command1 [global options...] command2 ... lastCommand [options...]
TStringBuilder fullName;
@@ -203,21 +203,21 @@ void TClientCommand::SetFreeArgTitle(size_t pos, const TString& title, const TSt
TString TClientCommand::Ends2Prefix(const std::basic_string<bool>& ends) {
TString prefix;
- if (!ends.empty()) {
- for (auto it = ends.begin();;) {
- bool s = *it;
- ++it;
- if (it == ends.end()) {
- prefix += s ? "└─ " : "├─ ";
- break;
- } else {
- prefix += s ? " " : "│ ";
- }
- }
- }
- return prefix;
-}
-
+ if (!ends.empty()) {
+ for (auto it = ends.begin();;) {
+ bool s = *it;
+ ++it;
+ if (it == ends.end()) {
+ prefix += s ? "└─ " : "├─ ";
+ break;
+ } else {
+ prefix += s ? " " : "│ ";
+ }
+ }
+ }
+ return prefix;
+}
+
void TClientCommand::RenderCommandsDescription(
TStringStream& stream,
const NColorizer::TColors& colors,
@@ -247,31 +247,31 @@ void TClientCommand::RenderCommandsDescription(
}
TClientCommandTree::TClientCommandTree(const TString& name, const std::initializer_list<TString>& aliases, const TString& description)
- : TClientCommand(name, aliases, description)
- , SelectedCommand(nullptr)
+ : TClientCommand(name, aliases, description)
+ , SelectedCommand(nullptr)
{
Args[0] = "<subcommand>";
}
-
+
void TClientCommandTree::AddCommand(std::unique_ptr<TClientCommand> command) {
for (const TString& a : command->Aliases) {
- Aliases[a] = command->Name;
- }
- command->Parent = this;
+ Aliases[a] = command->Name;
+ }
+ command->Parent = this;
SubCommands[command->Name] = std::move(command);
-}
-
-void TClientCommandTree::Config(TConfig& config) {
- TClientCommand::Config(config);
+}
+
+void TClientCommandTree::Config(TConfig& config) {
+ TClientCommand::Config(config);
SetFreeArgs(config);
TString commands;
- for (auto it = SubCommands.begin(); it != SubCommands.end(); ++it) {
- if (!commands.empty())
- commands += ',';
- commands += it->first;
- }
+ for (auto it = SubCommands.begin(); it != SubCommands.end(); ++it) {
+ if (!commands.empty())
+ commands += ',';
+ commands += it->first;
+ }
SetFreeArgTitle(0, "<subcommand>", commands);
- TStringStream stream;
+ TStringStream stream;
NColorizer::TColors colors = NColorizer::AutoColors(Cout);
stream << Endl << Endl
<< colors.BoldColor() << "Description" << colors.OldColor() << ": " << Description << Endl << Endl
@@ -279,55 +279,55 @@ void TClientCommandTree::Config(TConfig& config) {
RenderCommandsDescription(stream, colors);
stream << Endl;
PrintParentOptions(stream, config, colors);
- config.Opts->SetCmdLineDescr(stream.Str());
-}
-
-void TClientCommandTree::Parse(TConfig& config) {
- TClientCommand::Parse(config);
+ config.Opts->SetCmdLineDescr(stream.Str());
+}
+
+void TClientCommandTree::Parse(TConfig& config) {
+ TClientCommand::Parse(config);
TString cmd = config.ParseResult->GetFreeArgs().at(0);
- config.Tokens.push_back(cmd);
- size_t count = config.ParseResult->GetFreeArgsPos();
- config.ArgC -= count;
- config.ArgV += count;
- {
- auto it = Aliases.find(cmd);
- if (it != Aliases.end())
- cmd = it->second;
- }
- auto it = SubCommands.find(cmd);
- if (it == SubCommands.end()) {
- if (IsNumber(cmd))
- it = SubCommands.find("#");
- if (it == SubCommands.end())
- it = SubCommands.find("*");
- }
- if (it != SubCommands.end()) {
+ config.Tokens.push_back(cmd);
+ size_t count = config.ParseResult->GetFreeArgsPos();
+ config.ArgC -= count;
+ config.ArgV += count;
+ {
+ auto it = Aliases.find(cmd);
+ if (it != Aliases.end())
+ cmd = it->second;
+ }
+ auto it = SubCommands.find(cmd);
+ if (it == SubCommands.end()) {
+ if (IsNumber(cmd))
+ it = SubCommands.find("#");
+ if (it == SubCommands.end())
+ it = SubCommands.find("*");
+ }
+ if (it != SubCommands.end()) {
SelectedCommand = it->second.get();
- } else {
- throw yexception() << "Invalid command '" << cmd << "'";
- }
-}
-
-int TClientCommandTree::Run(TConfig& config) {
- if (SelectedCommand) {
- return SelectedCommand->Process(config);
- }
- throw yexception() << "Error";
-}
-
-int TClientCommandTree::Process(TConfig& config) {
+ } else {
+ throw yexception() << "Invalid command '" << cmd << "'";
+ }
+}
+
+int TClientCommandTree::Run(TConfig& config) {
+ if (SelectedCommand) {
+ return SelectedCommand->Process(config);
+ }
+ throw yexception() << "Error";
+}
+
+int TClientCommandTree::Process(TConfig& config) {
config.ArgsSettings.Reset(new TConfig::TArgSettings());
- config.Opts = &Opts;
- Config(config);
+ config.Opts = &Opts;
+ Config(config);
config.CheckParamsCount();
SetCustomUsage(config);
- TOptsParseOneLevelResult parseResult(config.Opts, config.ArgC, config.ArgV);
- config.ParseResult = &parseResult;
- Parse(config);
+ TOptsParseOneLevelResult parseResult(config.Opts, config.ArgC, config.ArgV);
+ config.ParseResult = &parseResult;
+ Parse(config);
config.ParentCommands.push_back({ Name, HasOptionsToShow() ? &Opts : nullptr });
- return Run(config);
-}
-
+ return Run(config);
+}
+
void TClientCommandTree::SetFreeArgs(TConfig& config) {
config.SetFreeArgsMin(1);
}
@@ -336,23 +336,23 @@ bool TClientCommandTree::HasOptionsToShow() {
for (auto opt : Opts.Opts_) {
if (!NeedToHideOption(opt.Get())) {
return true;
- }
- }
+ }
+ }
return false;
-}
-
+}
+
void TClientCommandTree::RenderCommandsDescription(
TStringStream& stream,
const NColorizer::TColors& colors,
const std::basic_string<bool>& ends
) {
TClientCommand::RenderCommandsDescription(stream, colors, ends);
- for (auto it = SubCommands.begin(); it != SubCommands.end(); ++it) {
- bool lastCommand = (std::next(it) == SubCommands.end());
+ for (auto it = SubCommands.begin(); it != SubCommands.end(); ++it) {
+ bool lastCommand = (std::next(it) == SubCommands.end());
it->second->RenderCommandsDescription(stream, colors, ends + lastCommand);
- }
-}
-
+ }
+}
+
void TCommandWithPath::ParsePath(const TClientCommand::TConfig& config, const size_t argPos, bool isPathOptional) {
if (config.ParseResult->GetFreeArgCount() < argPos + 1 && isPathOptional) {
if (isPathOptional) {
@@ -371,7 +371,7 @@ void TCommandWithPath::AdjustPath(const TClientCommand::TConfig& config) {
}
NConsoleClient::AdjustPath(Path, config);
-}
+}
void TCommandWithStreamName::ParseStreamName(const TClientCommand::TConfig &config, const size_t argPos) {
StreamName = config.ParseResult->GetFreeArgs()[argPos];
diff --git a/ydb/public/lib/ydb_cli/common/command.h b/ydb/public/lib/ydb_cli/common/command.h
index a6bcaec8f1d..441206cdf7b 100644
--- a/ydb/public/lib/ydb_cli/common/command.h
+++ b/ydb/public/lib/ydb_cli/common/command.h
@@ -83,8 +83,8 @@ public:
bool IsVerbose = false;
bool EnableSsl = false;
- bool JsonUi64AsText = false;
- bool JsonBinaryAsBase64 = false;
+ bool JsonUi64AsText = false;
+ bool JsonBinaryAsBase64 = false;
ui64 TabletId; // admin tablet #
ui32 NodeId; // admin node #
diff --git a/ydb/public/sdk/cpp/client/ydb_proto/accessor.h b/ydb/public/sdk/cpp/client/ydb_proto/accessor.h
index 8dfa1ac8e61..be0165d74bb 100644
--- a/ydb/public/sdk/cpp/client/ydb_proto/accessor.h
+++ b/ydb/public/sdk/cpp/client/ydb_proto/accessor.h
@@ -35,8 +35,8 @@ public:
static const Ydb::TableStats::QueryStats& GetProto(const NTable::TQueryStats& queryStats);
static const Ydb::Table::DescribeTableResult& GetProto(const NTable::TTableDescription& tableDescription);
static const Ydb::PersQueue::V1::DescribeTopicResult& GetProto(const NYdb::NPersQueue::TDescribeTopicResult& topicDescription);
-
- static NTable::TQueryStats FromProto(const Ydb::TableStats::QueryStats& queryStats);
+
+ static NTable::TQueryStats FromProto(const Ydb::TableStats::QueryStats& queryStats);
static NTable::TTableDescription FromProto(const Ydb::Table::CreateTableRequest& request);
static NTable::TIndexDescription FromProto(const Ydb::Table::TableIndex& tableIndex);
static NTable::TIndexDescription FromProto(const Ydb::Table::TableIndexDescription& tableIndexDesc);
diff --git a/ydb/public/sdk/cpp/client/ydb_types/credentials/credentials.h b/ydb/public/sdk/cpp/client/ydb_types/credentials/credentials.h
index 3790fe3cfb9..75b86933ce3 100644
--- a/ydb/public/sdk/cpp/client/ydb_types/credentials/credentials.h
+++ b/ydb/public/sdk/cpp/client/ydb_types/credentials/credentials.h
@@ -33,11 +33,11 @@ using TCredentialsProviderFactoryPtr = std::shared_ptr<ICredentialsProviderFacto
std::shared_ptr<ICredentialsProviderFactory> CreateInsecureCredentialsProviderFactory();
std::shared_ptr<ICredentialsProviderFactory> CreateOAuthCredentialsProviderFactory(const TStringType& token);
-struct TLoginCredentialsParams {
- TString User;
- TString Password;
-};
-
-std::shared_ptr<ICredentialsProviderFactory> CreateLoginCredentialsProviderFactory(TLoginCredentialsParams params);
-
+struct TLoginCredentialsParams {
+ TString User;
+ TString Password;
+};
+
+std::shared_ptr<ICredentialsProviderFactory> CreateLoginCredentialsProviderFactory(TLoginCredentialsParams params);
+
} // namespace NYdb
diff --git a/ydb/public/sdk/cpp/client/ydb_types/credentials/login.cpp b/ydb/public/sdk/cpp/client/ydb_types/credentials/login.cpp
index a1e5cb13fe8..ff251ad79e7 100644
--- a/ydb/public/sdk/cpp/client/ydb_types/credentials/login.cpp
+++ b/ydb/public/sdk/cpp/client/ydb_types/credentials/login.cpp
@@ -1,217 +1,217 @@
-#include "credentials.h"
-#define INCLUDE_YDB_INTERNAL_H
+#include "credentials.h"
+#define INCLUDE_YDB_INTERNAL_H
#include <ydb/public/sdk/cpp/client/impl/ydb_internal/plain_status/status.h>
#include <ydb/public/sdk/cpp/client/impl/ydb_internal/grpc_connections/grpc_connections.h>
#include <ydb/public/sdk/cpp/client/ydb_types/core_facility/core_facility.h>
#include <ydb/public/api/grpc/ydb_auth_v1.grpc.pb.h>
-#include <ydb/library/login/login.h>
-#include <ydb/library/security/util.h>
-#include <util/string/cast.h>
-
-namespace NYdb {
-
-class TLoginCredentialsProvider : public ICredentialsProvider {
-public:
- TLoginCredentialsProvider(std::weak_ptr<ICoreFacility> facility, TLoginCredentialsParams params);
- virtual TStringType GetAuthInfo() const override;
- virtual bool IsValid() const override;
-
-private:
- void PrepareToken();
- void RequestToken();
- bool IsOk() const;
- void ParseToken();
- TString GetToken() const;
- TString GetError() const;
- TString GetTokenOrError() const;
-
- enum class EState {
- Empty,
- Requesting,
- Done,
- };
-
- std::weak_ptr<ICoreFacility> Facility_;
- TLoginCredentialsParams Params_;
- EState State_ = EState::Empty;
- std::mutex Mutex_;
- std::condition_variable Notify_;
- std::atomic<ui64> TokenReceived_ = 1;
- std::atomic<ui64> TokenParsed_ = 0;
- std::optional<TString> Token_;
- std::optional<TString> Error_;
- TInstant TokenExpireAt_;
- TInstant TokenRequestAt_;
- TPlainStatus Status_;
- Ydb::Auth::LoginResponse Response_;
-};
-
-TLoginCredentialsProvider::TLoginCredentialsProvider(std::weak_ptr<ICoreFacility> facility, TLoginCredentialsParams params)
- : Facility_(facility)
- , Params_(std::move(params))
-{
- auto strongFacility = facility.lock();
- if (strongFacility) {
- auto periodicTask = [facility, this](NYql::TIssues&&, EStatus status) -> bool {
- if (status != EStatus::SUCCESS) {
- return false;
- }
-
- auto strongFacility = facility.lock();
- if (!strongFacility) {
- return false;
- }
-
- if (!TokenRequestAt_) {
- return true;
- }
-
- if (TInstant::Now() >= TokenRequestAt_) {
- RequestToken();
- }
-
- return true;
- };
- strongFacility->AddPeriodicTask(std::move(periodicTask), TDuration::Minutes(1));
- }
-}
-
-bool TLoginCredentialsProvider::IsValid() const {
- return true;
-}
-
-TStringType TLoginCredentialsProvider::GetAuthInfo() const {
- if (TokenParsed_ == TokenReceived_) {
- return GetTokenOrError();
- } else {
- const_cast<TLoginCredentialsProvider*>(this)->PrepareToken(); // will block here
- return GetTokenOrError();
- }
-}
-
-void TLoginCredentialsProvider::RequestToken() {
- auto strongFacility = Facility_.lock();
- if (strongFacility) {
- TokenRequestAt_ = {};
-
- auto responseCb = [facility = Facility_, this](Ydb::Auth::LoginResponse* resp, TPlainStatus status) {
- auto strongFacility = facility.lock();
- if (strongFacility) {
- std::lock_guard<std::mutex> lock(Mutex_);
- Status_ = std::move(status);
- if (resp != nullptr) {
- Response_ = std::move(*resp);
- }
- State_ = EState::Done;
- TokenReceived_++;
- }
- Notify_.notify_all();
- };
-
- Ydb::Auth::LoginRequest request;
- request.set_user(Params_.User);
- request.set_password(Params_.Password);
-
- TGRpcConnectionsImpl::RunOnDiscoveryEndpoint<Ydb::Auth::V1::AuthService, Ydb::Auth::LoginRequest, Ydb::Auth::LoginResponse>(
- strongFacility, std::move(request), std::move(responseCb), &Ydb::Auth::V1::AuthService::Stub::AsyncLogin,
- TRpcRequestSettings(), /*TODO*/TDuration::Seconds(60));
- }
-}
-
-void TLoginCredentialsProvider::PrepareToken() {
- std::unique_lock<std::mutex> lock(Mutex_);
- switch (State_) {
- case EState::Empty:
- State_ = EState::Requesting;
- RequestToken();
- [[fallthrough]];
- case EState::Requesting:
- Notify_.wait(lock, [&]{
- return State_ == EState::Done;
- });
- [[fallthrough]];
- case EState::Done:
- ParseToken();
- break;
- }
-}
-
-bool TLoginCredentialsProvider::IsOk() const {
- return State_ == EState::Done
- && Status_.Ok()
- && Response_.operation().status() == Ydb::StatusIds::SUCCESS;
-}
-
-void TLoginCredentialsProvider::ParseToken() { // works under mutex
- if (TokenParsed_ != TokenReceived_) {
- if (IsOk()) {
- Token_ = GetToken();
- Error_.reset();
- TInstant now = TInstant::Now();
- TokenExpireAt_ = NKikimr::ToInstant(NLogin::TLoginProvider::GetTokenExpiresAt(Token_.value()));
- TokenRequestAt_ = now + TDuration::Minutes((TokenExpireAt_ - now).Minutes() / 2);
- } else {
- Token_.reset();
- Error_ = GetError();
- }
- TokenParsed_ = TokenReceived_.load();
- }
-}
-
-TString TLoginCredentialsProvider::GetToken() const {
- Ydb::Auth::LoginResult result;
- Response_.operation().result().UnpackTo(&result);
- return result.token();
-}
-
-TString TLoginCredentialsProvider::GetError() const {
- if (Response_.operation().issues_size() > 0) {
- return Response_.operation().issues(0).message();
- } else {
- return Ydb::StatusIds_StatusCode_Name(Response_.operation().status());
- }
-}
-
-TString TLoginCredentialsProvider::GetTokenOrError() const {
- if (Token_) {
- return Token_.value();
- }
- if (Error_) {
- ythrow yexception() << Error_.value();
- }
- ythrow yexception() << "Wrong state of credentials provider";
-}
-
-class TLoginCredentialsProviderFactory : public ICredentialsProviderFactory {
-public:
- TLoginCredentialsProviderFactory(TLoginCredentialsParams params);
- virtual std::shared_ptr<ICredentialsProvider> CreateProvider() const override;
- virtual std::shared_ptr<ICredentialsProvider> CreateProvider(std::weak_ptr<ICoreFacility> facility) const override;
- virtual TStringType GetClientIdentity() const override;
-
-private:
- TLoginCredentialsParams Params_;
-};
-
-TLoginCredentialsProviderFactory::TLoginCredentialsProviderFactory(TLoginCredentialsParams params)
- : Params_(std::move(params))
-{
-}
-
-std::shared_ptr<ICredentialsProvider> TLoginCredentialsProviderFactory::CreateProvider() const {
- ythrow yexception() << "Not supported";
-}
-
-std::shared_ptr<ICredentialsProvider> TLoginCredentialsProviderFactory::CreateProvider(std::weak_ptr<ICoreFacility> facility) const {
- return std::make_shared<TLoginCredentialsProvider>(std::move(facility), Params_);
-}
-
-TStringType TLoginCredentialsProviderFactory::GetClientIdentity() const {
- return "YDB_LOGIN_PROVIDER" + ToString((ui64)this);
-}
-
-std::shared_ptr<ICredentialsProviderFactory> CreateLoginCredentialsProviderFactory(TLoginCredentialsParams params) {
- return std::make_shared<TLoginCredentialsProviderFactory>(std::move(params));
-}
-
-} // namespace NYdb
+#include <ydb/library/login/login.h>
+#include <ydb/library/security/util.h>
+#include <util/string/cast.h>
+
+namespace NYdb {
+
+class TLoginCredentialsProvider : public ICredentialsProvider {
+public:
+ TLoginCredentialsProvider(std::weak_ptr<ICoreFacility> facility, TLoginCredentialsParams params);
+ virtual TStringType GetAuthInfo() const override;
+ virtual bool IsValid() const override;
+
+private:
+ void PrepareToken();
+ void RequestToken();
+ bool IsOk() const;
+ void ParseToken();
+ TString GetToken() const;
+ TString GetError() const;
+ TString GetTokenOrError() const;
+
+ enum class EState {
+ Empty,
+ Requesting,
+ Done,
+ };
+
+ std::weak_ptr<ICoreFacility> Facility_;
+ TLoginCredentialsParams Params_;
+ EState State_ = EState::Empty;
+ std::mutex Mutex_;
+ std::condition_variable Notify_;
+ std::atomic<ui64> TokenReceived_ = 1;
+ std::atomic<ui64> TokenParsed_ = 0;
+ std::optional<TString> Token_;
+ std::optional<TString> Error_;
+ TInstant TokenExpireAt_;
+ TInstant TokenRequestAt_;
+ TPlainStatus Status_;
+ Ydb::Auth::LoginResponse Response_;
+};
+
+TLoginCredentialsProvider::TLoginCredentialsProvider(std::weak_ptr<ICoreFacility> facility, TLoginCredentialsParams params)
+ : Facility_(facility)
+ , Params_(std::move(params))
+{
+ auto strongFacility = facility.lock();
+ if (strongFacility) {
+ auto periodicTask = [facility, this](NYql::TIssues&&, EStatus status) -> bool {
+ if (status != EStatus::SUCCESS) {
+ return false;
+ }
+
+ auto strongFacility = facility.lock();
+ if (!strongFacility) {
+ return false;
+ }
+
+ if (!TokenRequestAt_) {
+ return true;
+ }
+
+ if (TInstant::Now() >= TokenRequestAt_) {
+ RequestToken();
+ }
+
+ return true;
+ };
+ strongFacility->AddPeriodicTask(std::move(periodicTask), TDuration::Minutes(1));
+ }
+}
+
+bool TLoginCredentialsProvider::IsValid() const {
+ return true;
+}
+
+TStringType TLoginCredentialsProvider::GetAuthInfo() const {
+ if (TokenParsed_ == TokenReceived_) {
+ return GetTokenOrError();
+ } else {
+ const_cast<TLoginCredentialsProvider*>(this)->PrepareToken(); // will block here
+ return GetTokenOrError();
+ }
+}
+
+void TLoginCredentialsProvider::RequestToken() {
+ auto strongFacility = Facility_.lock();
+ if (strongFacility) {
+ TokenRequestAt_ = {};
+
+ auto responseCb = [facility = Facility_, this](Ydb::Auth::LoginResponse* resp, TPlainStatus status) {
+ auto strongFacility = facility.lock();
+ if (strongFacility) {
+ std::lock_guard<std::mutex> lock(Mutex_);
+ Status_ = std::move(status);
+ if (resp != nullptr) {
+ Response_ = std::move(*resp);
+ }
+ State_ = EState::Done;
+ TokenReceived_++;
+ }
+ Notify_.notify_all();
+ };
+
+ Ydb::Auth::LoginRequest request;
+ request.set_user(Params_.User);
+ request.set_password(Params_.Password);
+
+ TGRpcConnectionsImpl::RunOnDiscoveryEndpoint<Ydb::Auth::V1::AuthService, Ydb::Auth::LoginRequest, Ydb::Auth::LoginResponse>(
+ strongFacility, std::move(request), std::move(responseCb), &Ydb::Auth::V1::AuthService::Stub::AsyncLogin,
+ TRpcRequestSettings(), /*TODO*/TDuration::Seconds(60));
+ }
+}
+
+void TLoginCredentialsProvider::PrepareToken() {
+ std::unique_lock<std::mutex> lock(Mutex_);
+ switch (State_) {
+ case EState::Empty:
+ State_ = EState::Requesting;
+ RequestToken();
+ [[fallthrough]];
+ case EState::Requesting:
+ Notify_.wait(lock, [&]{
+ return State_ == EState::Done;
+ });
+ [[fallthrough]];
+ case EState::Done:
+ ParseToken();
+ break;
+ }
+}
+
+bool TLoginCredentialsProvider::IsOk() const {
+ return State_ == EState::Done
+ && Status_.Ok()
+ && Response_.operation().status() == Ydb::StatusIds::SUCCESS;
+}
+
+void TLoginCredentialsProvider::ParseToken() { // works under mutex
+ if (TokenParsed_ != TokenReceived_) {
+ if (IsOk()) {
+ Token_ = GetToken();
+ Error_.reset();
+ TInstant now = TInstant::Now();
+ TokenExpireAt_ = NKikimr::ToInstant(NLogin::TLoginProvider::GetTokenExpiresAt(Token_.value()));
+ TokenRequestAt_ = now + TDuration::Minutes((TokenExpireAt_ - now).Minutes() / 2);
+ } else {
+ Token_.reset();
+ Error_ = GetError();
+ }
+ TokenParsed_ = TokenReceived_.load();
+ }
+}
+
+TString TLoginCredentialsProvider::GetToken() const {
+ Ydb::Auth::LoginResult result;
+ Response_.operation().result().UnpackTo(&result);
+ return result.token();
+}
+
+TString TLoginCredentialsProvider::GetError() const {
+ if (Response_.operation().issues_size() > 0) {
+ return Response_.operation().issues(0).message();
+ } else {
+ return Ydb::StatusIds_StatusCode_Name(Response_.operation().status());
+ }
+}
+
+TString TLoginCredentialsProvider::GetTokenOrError() const {
+ if (Token_) {
+ return Token_.value();
+ }
+ if (Error_) {
+ ythrow yexception() << Error_.value();
+ }
+ ythrow yexception() << "Wrong state of credentials provider";
+}
+
+class TLoginCredentialsProviderFactory : public ICredentialsProviderFactory {
+public:
+ TLoginCredentialsProviderFactory(TLoginCredentialsParams params);
+ virtual std::shared_ptr<ICredentialsProvider> CreateProvider() const override;
+ virtual std::shared_ptr<ICredentialsProvider> CreateProvider(std::weak_ptr<ICoreFacility> facility) const override;
+ virtual TStringType GetClientIdentity() const override;
+
+private:
+ TLoginCredentialsParams Params_;
+};
+
+TLoginCredentialsProviderFactory::TLoginCredentialsProviderFactory(TLoginCredentialsParams params)
+ : Params_(std::move(params))
+{
+}
+
+std::shared_ptr<ICredentialsProvider> TLoginCredentialsProviderFactory::CreateProvider() const {
+ ythrow yexception() << "Not supported";
+}
+
+std::shared_ptr<ICredentialsProvider> TLoginCredentialsProviderFactory::CreateProvider(std::weak_ptr<ICoreFacility> facility) const {
+ return std::make_shared<TLoginCredentialsProvider>(std::move(facility), Params_);
+}
+
+TStringType TLoginCredentialsProviderFactory::GetClientIdentity() const {
+ return "YDB_LOGIN_PROVIDER" + ToString((ui64)this);
+}
+
+std::shared_ptr<ICredentialsProviderFactory> CreateLoginCredentialsProviderFactory(TLoginCredentialsParams params) {
+ return std::make_shared<TLoginCredentialsProviderFactory>(std::move(params));
+}
+
+} // namespace NYdb
diff --git a/ydb/public/sdk/cpp/client/ydb_types/credentials/ya.make b/ydb/public/sdk/cpp/client/ydb_types/credentials/ya.make
index 633110be223..c58b2112f8a 100644
--- a/ydb/public/sdk/cpp/client/ydb_types/credentials/ya.make
+++ b/ydb/public/sdk/cpp/client/ydb_types/credentials/ya.make
@@ -4,11 +4,11 @@ OWNER(g:kikimr)
SRCS(
credentials.cpp
- login.cpp
+ login.cpp
)
PEERDIR(
- ydb/library/login
+ ydb/library/login
ydb/public/api/grpc
ydb/public/sdk/cpp/client/ydb_types/status
ydb/library/yql/public/issue
diff --git a/ydb/services/auth/grpc_service.cpp b/ydb/services/auth/grpc_service.cpp
index 27ffe6c2fe3..2729530449f 100644
--- a/ydb/services/auth/grpc_service.cpp
+++ b/ydb/services/auth/grpc_service.cpp
@@ -1,65 +1,65 @@
-#include "grpc_service.h"
-
+#include "grpc_service.h"
+
#include <ydb/core/grpc_services/grpc_helper.h>
#include <ydb/core/grpc_services/rpc_calls.h>
-
-namespace NKikimr {
-namespace NGRpcService {
-
-static TString GetSdkBuildInfo(NGrpc::IRequestContextBase* reqCtx) {
- const auto& res = reqCtx->GetPeerMetaValues(NYdb::YDB_SDK_BUILD_INFO_HEADER);
- if (res.empty()) {
- return {};
- }
- return TString{res[0]};
-}
-
-TGRpcAuthService::TGRpcAuthService(NActors::TActorSystem* system,
- TIntrusivePtr<NMonitoring::TDynamicCounters> counters,
- NActors::TActorId id)
- : ActorSystem_(system)
- , Counters_(counters)
- , GRpcRequestProxyId_(id)
-{
-}
-
-void TGRpcAuthService::InitService(grpc::ServerCompletionQueue* cq, NGrpc::TLoggerPtr logger) {
- CQ_ = cq;
- SetupIncomingRequests(std::move(logger));
-}
-
-void TGRpcAuthService::SetGlobalLimiterHandle(NGrpc::TGlobalLimiter* limiter) {
- Limiter_ = limiter;
-}
-
-bool TGRpcAuthService::IncRequest() {
- return Limiter_->Inc();
-}
-
-void TGRpcAuthService::DecRequest() {
- Limiter_->Dec();
- Y_ASSERT(Limiter_->GetCurrentInFlight() >= 0);
-}
-
-void TGRpcAuthService::SetupIncomingRequests(NGrpc::TLoggerPtr logger) {
- auto getCounterBlock = CreateCounterCb(Counters_, ActorSystem_);
-#ifdef ADD_REQUEST
-#error ADD_REQUEST macro already defined
-#endif
-#define ADD_REQUEST(NAME, IN, OUT, ACTION) \
- MakeIntrusive<TGRpcRequest<Ydb::Auth::IN, Ydb::Auth::OUT, TGRpcAuthService>>(this, &Service_, CQ_, \
- [this](NGrpc::IRequestContextBase* reqCtx) { \
- NGRpcService::ReportGrpcReqToMon(*ActorSystem_, reqCtx->GetPeer(), GetSdkBuildInfo(reqCtx)); \
- ACTION; \
- }, &Ydb::Auth::V1::AuthService::AsyncService::Request ## NAME, \
- #NAME, logger, getCounterBlock("login", #NAME))->Run();
-
- ADD_REQUEST(Login, LoginRequest, LoginResponse, {
- ActorSystem_->Send(GRpcRequestProxyId_, new TEvLoginRequest(reqCtx));
- })
-
-#undef ADD_REQUEST
-}
-
-} // namespace NGRpcService
-} // namespace NKikimr
+
+namespace NKikimr {
+namespace NGRpcService {
+
+static TString GetSdkBuildInfo(NGrpc::IRequestContextBase* reqCtx) {
+ const auto& res = reqCtx->GetPeerMetaValues(NYdb::YDB_SDK_BUILD_INFO_HEADER);
+ if (res.empty()) {
+ return {};
+ }
+ return TString{res[0]};
+}
+
+TGRpcAuthService::TGRpcAuthService(NActors::TActorSystem* system,
+ TIntrusivePtr<NMonitoring::TDynamicCounters> counters,
+ NActors::TActorId id)
+ : ActorSystem_(system)
+ , Counters_(counters)
+ , GRpcRequestProxyId_(id)
+{
+}
+
+void TGRpcAuthService::InitService(grpc::ServerCompletionQueue* cq, NGrpc::TLoggerPtr logger) {
+ CQ_ = cq;
+ SetupIncomingRequests(std::move(logger));
+}
+
+void TGRpcAuthService::SetGlobalLimiterHandle(NGrpc::TGlobalLimiter* limiter) {
+ Limiter_ = limiter;
+}
+
+bool TGRpcAuthService::IncRequest() {
+ return Limiter_->Inc();
+}
+
+void TGRpcAuthService::DecRequest() {
+ Limiter_->Dec();
+ Y_ASSERT(Limiter_->GetCurrentInFlight() >= 0);
+}
+
+void TGRpcAuthService::SetupIncomingRequests(NGrpc::TLoggerPtr logger) {
+ auto getCounterBlock = CreateCounterCb(Counters_, ActorSystem_);
+#ifdef ADD_REQUEST
+#error ADD_REQUEST macro already defined
+#endif
+#define ADD_REQUEST(NAME, IN, OUT, ACTION) \
+ MakeIntrusive<TGRpcRequest<Ydb::Auth::IN, Ydb::Auth::OUT, TGRpcAuthService>>(this, &Service_, CQ_, \
+ [this](NGrpc::IRequestContextBase* reqCtx) { \
+ NGRpcService::ReportGrpcReqToMon(*ActorSystem_, reqCtx->GetPeer(), GetSdkBuildInfo(reqCtx)); \
+ ACTION; \
+ }, &Ydb::Auth::V1::AuthService::AsyncService::Request ## NAME, \
+ #NAME, logger, getCounterBlock("login", #NAME))->Run();
+
+ ADD_REQUEST(Login, LoginRequest, LoginResponse, {
+ ActorSystem_->Send(GRpcRequestProxyId_, new TEvLoginRequest(reqCtx));
+ })
+
+#undef ADD_REQUEST
+}
+
+} // namespace NGRpcService
+} // namespace NKikimr
diff --git a/ydb/services/auth/grpc_service.h b/ydb/services/auth/grpc_service.h
index d2e68a364ba..706621df6df 100644
--- a/ydb/services/auth/grpc_service.h
+++ b/ydb/services/auth/grpc_service.h
@@ -1,36 +1,36 @@
-#pragma once
-
-#include <library/cpp/actors/core/actorsystem.h>
+#pragma once
+
+#include <library/cpp/actors/core/actorsystem.h>
#include <library/cpp/grpc/server/grpc_server.h>
#include <ydb/public/api/grpc/ydb_auth_v1.grpc.pb.h>
-
-
-namespace NKikimr {
-namespace NGRpcService {
-
- class TGRpcAuthService : public NGrpc::TGrpcServiceBase<Ydb::Auth::V1::AuthService>
- {
- public:
- TGRpcAuthService(NActors::TActorSystem* system,
- TIntrusivePtr<NMonitoring::TDynamicCounters> counters,
- NActors::TActorId id);
-
- void InitService(grpc::ServerCompletionQueue* cq, NGrpc::TLoggerPtr logger) override;
- void SetGlobalLimiterHandle(NGrpc::TGlobalLimiter* limiter) override;
-
- bool IncRequest();
- void DecRequest();
-
- private:
- void SetupIncomingRequests(NGrpc::TLoggerPtr logger);
-
- NActors::TActorSystem* ActorSystem_;
+
+
+namespace NKikimr {
+namespace NGRpcService {
+
+ class TGRpcAuthService : public NGrpc::TGrpcServiceBase<Ydb::Auth::V1::AuthService>
+ {
+ public:
+ TGRpcAuthService(NActors::TActorSystem* system,
+ TIntrusivePtr<NMonitoring::TDynamicCounters> counters,
+ NActors::TActorId id);
+
+ void InitService(grpc::ServerCompletionQueue* cq, NGrpc::TLoggerPtr logger) override;
+ void SetGlobalLimiterHandle(NGrpc::TGlobalLimiter* limiter) override;
+
+ bool IncRequest();
+ void DecRequest();
+
+ private:
+ void SetupIncomingRequests(NGrpc::TLoggerPtr logger);
+
+ NActors::TActorSystem* ActorSystem_;
grpc::ServerCompletionQueue* CQ_ = nullptr;
-
- TIntrusivePtr<NMonitoring::TDynamicCounters> Counters_;
- NActors::TActorId GRpcRequestProxyId_;
+
+ TIntrusivePtr<NMonitoring::TDynamicCounters> Counters_;
+ NActors::TActorId GRpcRequestProxyId_;
NGrpc::TGlobalLimiter* Limiter_ = nullptr;
- };
-
-} // namespace NGRpcService
-} // namespace NKikimr
+ };
+
+} // namespace NGRpcService
+} // namespace NKikimr
diff --git a/ydb/services/auth/ya.make b/ydb/services/auth/ya.make
index 33c85b072f4..1bc2af518e5 100644
--- a/ydb/services/auth/ya.make
+++ b/ydb/services/auth/ya.make
@@ -1,19 +1,19 @@
-LIBRARY()
-
-OWNER(g:kikimr)
-
-SRCS(
- grpc_service.cpp
-)
-
-PEERDIR(
- library/cpp/grpc/server
+LIBRARY()
+
+OWNER(g:kikimr)
+
+SRCS(
+ grpc_service.cpp
+)
+
+PEERDIR(
+ library/cpp/grpc/server
library/cpp/lwtrace
ydb/core/grpc_services
ydb/core/protos
ydb/library/login
ydb/public/api/grpc
ydb/public/lib/operation_id
-)
-
-END()
+)
+
+END()
diff --git a/ydb/services/cms/cms_ut.cpp b/ydb/services/cms/cms_ut.cpp
index 5ba7e048e2d..7d5234715e0 100644
--- a/ydb/services/cms/cms_ut.cpp
+++ b/ydb/services/cms/cms_ut.cpp
@@ -31,16 +31,16 @@ namespace NKikimr {
using namespace Tests;
using namespace NYdb;
-struct TCmsTestSettings : TKikimrTestSettings {
- static constexpr bool PrecreatePools = false;
-};
-
-struct TCmsTestSettingsWithAuth : TCmsTestSettings {
- static constexpr bool AUTH = true;
-};
-
-using TKikimrWithGrpcAndRootSchema = NYdb::TBasicKikimrWithGrpcAndRootSchema<TCmsTestSettings>;
-
+struct TCmsTestSettings : TKikimrTestSettings {
+ static constexpr bool PrecreatePools = false;
+};
+
+struct TCmsTestSettingsWithAuth : TCmsTestSettings {
+ static constexpr bool AUTH = true;
+};
+
+using TKikimrWithGrpcAndRootSchema = NYdb::TBasicKikimrWithGrpcAndRootSchema<TCmsTestSettings>;
+
static Ydb::StatusIds::StatusCode WaitForOperationStatus(std::shared_ptr<grpc::Channel> channel, const TString& opId, const TString &token = "") {
std::unique_ptr<Ydb::Operation::V1::OperationService::Stub> stub;
stub = Ydb::Operation::V1::OperationService::NewStub(channel);
@@ -130,7 +130,7 @@ static void SetSyncOperation(TRequest& req) {
static void doSimpleTenantsTest(bool sync) {
TKikimrWithGrpcAndRootSchema server;
-
+
server.Server_->GetRuntime()->SetLogPriority(NKikimrServices::CMS_TENANTS, NLog::PRI_TRACE);
ui16 grpc = server.GetPort();
@@ -284,8 +284,8 @@ static void doSimpleTenantsTest(bool sync) {
}
}
-template <typename TTestSettings>
-void CheckCreateDatabase(NYdb::TBasicKikimrWithGrpcAndRootSchema<TTestSettings> &server,
+template <typename TTestSettings>
+void CheckCreateDatabase(NYdb::TBasicKikimrWithGrpcAndRootSchema<TTestSettings> &server,
std::shared_ptr<grpc::Channel> channel,
const TString &path,
bool disableTx = false,
@@ -317,7 +317,7 @@ void CheckCreateDatabase(NYdb::TBasicKikimrWithGrpcAndRootSchema<TTestSettings>
}
{
auto status = WaitForOperationStatus(channel, id, token);
- UNIT_ASSERT_VALUES_EQUAL(status, Ydb::StatusIds::SUCCESS);
+ UNIT_ASSERT_VALUES_EQUAL(status, Ydb::StatusIds::SUCCESS);
}
if (runNode) {
@@ -367,7 +367,7 @@ Y_UNIT_TEST_SUITE(TGRpcCmsTest) {
}
Y_UNIT_TEST(AuthTokenTest) {
- NYdb::TBasicKikimrWithGrpcAndRootSchema<TCmsTestSettingsWithAuth> server;
+ NYdb::TBasicKikimrWithGrpcAndRootSchema<TCmsTestSettingsWithAuth> server;
server.Server_->GetRuntime()->SetLogPriority(NKikimrServices::CMS_TENANTS, NLog::PRI_TRACE);
ui16 grpc = server.GetPort();
TString id;
@@ -410,9 +410,9 @@ Y_UNIT_TEST_SUITE(TGRpcCmsTest) {
UNIT_ASSERT(response.operation().ready());
UNIT_ASSERT(response.operation().status() == Ydb::StatusIds::SUCCESS);
- // In testing env we have pools kinds test, ssd, hdd, hdd1, hdd2 all with
+ // In testing env we have pools kinds test, ssd, hdd, hdd1, hdd2 all with
// none erasure and ROT disk.
- THashSet<TString> poolKinds = {{TString("test"), TString("ssd"), TString("hdd"), TString("hdd1"), TString("hdd2")}};
+ THashSet<TString> poolKinds = {{TString("test"), TString("ssd"), TString("hdd"), TString("hdd1"), TString("hdd2")}};
Ydb::Cms::DescribeDatabaseOptionsResult result;
auto res = response.operation().result().UnpackTo(&result);
UNIT_ASSERT(res);
diff --git a/ydb/services/datastreams/put_records_actor.h b/ydb/services/datastreams/put_records_actor.h
index 62133dd61bc..8f06a99157f 100644
--- a/ydb/services/datastreams/put_records_actor.h
+++ b/ydb/services/datastreams/put_records_actor.h
@@ -55,13 +55,13 @@ namespace NKikimr::NDataStreams::V1 {
void Bootstrap(const NActors::TActorContext& ctx) {
NTabletPipe::TClientConfig clientConfig;
- clientConfig.RetryPolicy = {
- .RetryLimitCount = 6,
- .MinRetryTime = TDuration::MilliSeconds(10),
- .MaxRetryTime = TDuration::MilliSeconds(100),
- .BackoffMultiplier = 2,
- .DoFirstRetryInstantly = true
- };
+ clientConfig.RetryPolicy = {
+ .RetryLimitCount = 6,
+ .MinRetryTime = TDuration::MilliSeconds(10),
+ .MaxRetryTime = TDuration::MilliSeconds(100),
+ .BackoffMultiplier = 2,
+ .DoFirstRetryInstantly = true
+ };
PipeClient = ctx.RegisterWithSameMailbox(NTabletPipe::CreateClient(ctx.SelfID, TabletId, clientConfig));
SendWriteRequest(ctx);
diff --git a/ydb/services/monitoring/grpc_service.cpp b/ydb/services/monitoring/grpc_service.cpp
index b3a42433cef..d09fe4f3a4f 100644
--- a/ydb/services/monitoring/grpc_service.cpp
+++ b/ydb/services/monitoring/grpc_service.cpp
@@ -1,65 +1,65 @@
-#include "grpc_service.h"
-
+#include "grpc_service.h"
+
#include <ydb/core/grpc_services/grpc_helper.h>
#include <ydb/core/grpc_services/rpc_calls.h>
-
-namespace NKikimr {
-namespace NGRpcService {
-
+
+namespace NKikimr {
+namespace NGRpcService {
+
static TString GetSdkBuildInfo(NGrpc::IRequestContextBase* reqCtx) {
- const auto& res = reqCtx->GetPeerMetaValues(NYdb::YDB_SDK_BUILD_INFO_HEADER);
- if (res.empty()) {
- return {};
- }
+ const auto& res = reqCtx->GetPeerMetaValues(NYdb::YDB_SDK_BUILD_INFO_HEADER);
+ if (res.empty()) {
+ return {};
+ }
return TString{res[0]};
-}
-
-TGRpcMonitoringService::TGRpcMonitoringService(NActors::TActorSystem* system,
- TIntrusivePtr<NMonitoring::TDynamicCounters> counters,
+}
+
+TGRpcMonitoringService::TGRpcMonitoringService(NActors::TActorSystem* system,
+ TIntrusivePtr<NMonitoring::TDynamicCounters> counters,
NActors::TActorId id)
- : ActorSystem_(system)
- , Counters_(counters)
- , GRpcRequestProxyId_(id)
-{
-}
-
+ : ActorSystem_(system)
+ , Counters_(counters)
+ , GRpcRequestProxyId_(id)
+{
+}
+
void TGRpcMonitoringService::InitService(grpc::ServerCompletionQueue* cq, NGrpc::TLoggerPtr logger) {
- CQ_ = cq;
+ CQ_ = cq;
SetupIncomingRequests(std::move(logger));
-}
-
+}
+
void TGRpcMonitoringService::SetGlobalLimiterHandle(NGrpc::TGlobalLimiter* limiter) {
- Limiter_ = limiter;
-}
-
-bool TGRpcMonitoringService::IncRequest() {
- return Limiter_->Inc();
-}
-
-void TGRpcMonitoringService::DecRequest() {
- Limiter_->Dec();
- Y_ASSERT(Limiter_->GetCurrentInFlight() >= 0);
-}
-
+ Limiter_ = limiter;
+}
+
+bool TGRpcMonitoringService::IncRequest() {
+ return Limiter_->Inc();
+}
+
+void TGRpcMonitoringService::DecRequest() {
+ Limiter_->Dec();
+ Y_ASSERT(Limiter_->GetCurrentInFlight() >= 0);
+}
+
void TGRpcMonitoringService::SetupIncomingRequests(NGrpc::TLoggerPtr logger) {
- auto getCounterBlock = CreateCounterCb(Counters_, ActorSystem_);
-#ifdef ADD_REQUEST
-#error ADD_REQUEST macro already defined
-#endif
-#define ADD_REQUEST(NAME, IN, OUT, ACTION) \
- MakeIntrusive<TGRpcRequest<Ydb::Monitoring::IN, Ydb::Monitoring::OUT, TGRpcMonitoringService>>(this, &Service_, CQ_, \
+ auto getCounterBlock = CreateCounterCb(Counters_, ActorSystem_);
+#ifdef ADD_REQUEST
+#error ADD_REQUEST macro already defined
+#endif
+#define ADD_REQUEST(NAME, IN, OUT, ACTION) \
+ MakeIntrusive<TGRpcRequest<Ydb::Monitoring::IN, Ydb::Monitoring::OUT, TGRpcMonitoringService>>(this, &Service_, CQ_, \
[this](NGrpc::IRequestContextBase* reqCtx) { \
- NGRpcService::ReportGrpcReqToMon(*ActorSystem_, reqCtx->GetPeer(), GetSdkBuildInfo(reqCtx)); \
- ACTION; \
- }, &Ydb::Monitoring::V1::MonitoringService::AsyncService::Request ## NAME, \
+ NGRpcService::ReportGrpcReqToMon(*ActorSystem_, reqCtx->GetPeer(), GetSdkBuildInfo(reqCtx)); \
+ ACTION; \
+ }, &Ydb::Monitoring::V1::MonitoringService::AsyncService::Request ## NAME, \
#NAME, logger, getCounterBlock("monitoring", #NAME))->Run();
-
- ADD_REQUEST(SelfCheck, SelfCheckRequest, SelfCheckResponse, {
- ActorSystem_->Send(GRpcRequestProxyId_, new TEvSelfCheckRequest(reqCtx));
- })
-
-#undef ADD_REQUEST
-}
-
-} // namespace NGRpcService
-} // namespace NKikimr
+
+ ADD_REQUEST(SelfCheck, SelfCheckRequest, SelfCheckResponse, {
+ ActorSystem_->Send(GRpcRequestProxyId_, new TEvSelfCheckRequest(reqCtx));
+ })
+
+#undef ADD_REQUEST
+}
+
+} // namespace NGRpcService
+} // namespace NKikimr
diff --git a/ydb/services/monitoring/grpc_service.h b/ydb/services/monitoring/grpc_service.h
index 259500d1013..3c324424fdd 100644
--- a/ydb/services/monitoring/grpc_service.h
+++ b/ydb/services/monitoring/grpc_service.h
@@ -1,37 +1,37 @@
-#pragma once
-
-#include <library/cpp/actors/core/actorsystem.h>
-
+#pragma once
+
+#include <library/cpp/actors/core/actorsystem.h>
+
#include <ydb/public/api/grpc/ydb_monitoring_v1.grpc.pb.h>
-
+
#include <library/cpp/grpc/server/grpc_server.h>
-
-namespace NKikimr {
-namespace NGRpcService {
-
+
+namespace NKikimr {
+namespace NGRpcService {
+
class TGRpcMonitoringService : public NGrpc::TGrpcServiceBase<Ydb::Monitoring::V1::MonitoringService>
- {
- public:
- TGRpcMonitoringService(NActors::TActorSystem* system,
- TIntrusivePtr<NMonitoring::TDynamicCounters> counters,
+ {
+ public:
+ TGRpcMonitoringService(NActors::TActorSystem* system,
+ TIntrusivePtr<NMonitoring::TDynamicCounters> counters,
NActors::TActorId id);
-
+
void InitService(grpc::ServerCompletionQueue* cq, NGrpc::TLoggerPtr logger) override;
void SetGlobalLimiterHandle(NGrpc::TGlobalLimiter* limiter) override;
-
- bool IncRequest();
- void DecRequest();
-
- private:
+
+ bool IncRequest();
+ void DecRequest();
+
+ private:
void SetupIncomingRequests(NGrpc::TLoggerPtr logger);
-
- NActors::TActorSystem* ActorSystem_;
+
+ NActors::TActorSystem* ActorSystem_;
grpc::ServerCompletionQueue* CQ_ = nullptr;
-
- TIntrusivePtr<NMonitoring::TDynamicCounters> Counters_;
+
+ TIntrusivePtr<NMonitoring::TDynamicCounters> Counters_;
NActors::TActorId GRpcRequestProxyId_;
NGrpc::TGlobalLimiter* Limiter_ = nullptr;
- };
-
-} // namespace NGRpcService
-} // namespace NKikimr
+ };
+
+} // namespace NGRpcService
+} // namespace NKikimr
diff --git a/ydb/services/monitoring/ya.make b/ydb/services/monitoring/ya.make
index 26f74788863..563c9895fb3 100644
--- a/ydb/services/monitoring/ya.make
+++ b/ydb/services/monitoring/ya.make
@@ -1,17 +1,17 @@
-LIBRARY()
-
-OWNER(g:kikimr)
-
-SRCS(
- grpc_service.cpp
-)
-
-PEERDIR(
+LIBRARY()
+
+OWNER(g:kikimr)
+
+SRCS(
+ grpc_service.cpp
+)
+
+PEERDIR(
library/cpp/grpc/server
ydb/core/grpc_services
ydb/core/protos
ydb/public/api/grpc
ydb/public/lib/operation_id
-)
-
-END()
+)
+
+END()
diff --git a/ydb/services/persqueue_v1/grpc_pq_read_actor.cpp b/ydb/services/persqueue_v1/grpc_pq_read_actor.cpp
index 87ef763587f..654edfcfcd4 100644
--- a/ydb/services/persqueue_v1/grpc_pq_read_actor.cpp
+++ b/ydb/services/persqueue_v1/grpc_pq_read_actor.cpp
@@ -38,13 +38,13 @@ using namespace PersQueue::V1;
//11 tries = 10,23 seconds, then each try for 5 seconds , so 21 retries will take near 1 min
-static const NTabletPipe::TClientRetryPolicy RetryPolicyForPipes = {
- .RetryLimitCount = 21,
- .MinRetryTime = TDuration::MilliSeconds(10),
- .MaxRetryTime = TDuration::Seconds(5),
- .BackoffMultiplier = 2,
- .DoFirstRetryInstantly = true
-};
+static const NTabletPipe::TClientRetryPolicy RetryPolicyForPipes = {
+ .RetryLimitCount = 21,
+ .MinRetryTime = TDuration::MilliSeconds(10),
+ .MaxRetryTime = TDuration::Seconds(5),
+ .BackoffMultiplier = 2,
+ .DoFirstRetryInstantly = true
+};
static const ui64 MAX_INFLY_BYTES = 25 * 1024 * 1024;
static const ui32 MAX_INFLY_READS = 10;
@@ -1863,13 +1863,13 @@ void TPartitionActor::Handle(const TEvPQProxy::TEvRestartPipe::TPtr&, const TAct
Y_VERIFY(!PipeClient);
NTabletPipe::TClientConfig clientConfig;
- clientConfig.RetryPolicy = {
- .RetryLimitCount = 6,
- .MinRetryTime = TDuration::MilliSeconds(10),
- .MaxRetryTime = TDuration::MilliSeconds(100),
- .BackoffMultiplier = 2,
- .DoFirstRetryInstantly = true
- };
+ clientConfig.RetryPolicy = {
+ .RetryLimitCount = 6,
+ .MinRetryTime = TDuration::MilliSeconds(10),
+ .MaxRetryTime = TDuration::MilliSeconds(100),
+ .BackoffMultiplier = 2,
+ .DoFirstRetryInstantly = true
+ };
PipeClient = ctx.RegisterWithSameMailbox(NTabletPipe::CreateClient(ctx.SelfID, TabletID, clientConfig));
Y_VERIFY(TabletID);
@@ -2307,13 +2307,13 @@ void TPartitionActor::InitLockPartition(const TActorContext& ctx) {
Y_VERIFY(!PipeClient);
FirstInit = false;
NTabletPipe::TClientConfig clientConfig;
- clientConfig.RetryPolicy = {
- .RetryLimitCount = 6,
- .MinRetryTime = TDuration::MilliSeconds(10),
- .MaxRetryTime = TDuration::MilliSeconds(100),
- .BackoffMultiplier = 2,
- .DoFirstRetryInstantly = true
- };
+ clientConfig.RetryPolicy = {
+ .RetryLimitCount = 6,
+ .MinRetryTime = TDuration::MilliSeconds(10),
+ .MaxRetryTime = TDuration::MilliSeconds(100),
+ .BackoffMultiplier = 2,
+ .DoFirstRetryInstantly = true
+ };
PipeClient = ctx.RegisterWithSameMailbox(NTabletPipe::CreateClient(ctx.SelfID, TabletID, clientConfig));
NKikimrClient::TPersQueueRequest request;
diff --git a/ydb/services/persqueue_v1/grpc_pq_write_actor.cpp b/ydb/services/persqueue_v1/grpc_pq_write_actor.cpp
index 6ab3b6f56d0..3038cc82a61 100644
--- a/ydb/services/persqueue_v1/grpc_pq_write_actor.cpp
+++ b/ydb/services/persqueue_v1/grpc_pq_write_actor.cpp
@@ -558,13 +558,13 @@ void TWriteSessionActor::RequestNextPartition(const TActorContext& ctx) {
Y_VERIFY(!PipeToBalancer);
Y_VERIFY(BalancerTabletId);
NTabletPipe::TClientConfig clientConfig;
- clientConfig.RetryPolicy = {
- .RetryLimitCount = 6,
- .MinRetryTime = TDuration::MilliSeconds(10),
- .MaxRetryTime = TDuration::MilliSeconds(100),
- .BackoffMultiplier = 2,
- .DoFirstRetryInstantly = true
- };
+ clientConfig.RetryPolicy = {
+ .RetryLimitCount = 6,
+ .MinRetryTime = TDuration::MilliSeconds(10),
+ .MaxRetryTime = TDuration::MilliSeconds(100),
+ .BackoffMultiplier = 2,
+ .DoFirstRetryInstantly = true
+ };
PipeToBalancer = ctx.RegisterWithSameMailbox(NTabletPipe::CreateClient(ctx.SelfID, BalancerTabletId, clientConfig));
NTabletPipe::SendData(ctx, PipeToBalancer, x.Release());
diff --git a/ydb/services/persqueue_v1/persqueue_ut.cpp b/ydb/services/persqueue_v1/persqueue_ut.cpp
index 33560497a2d..3bc9b217285 100644
--- a/ydb/services/persqueue_v1/persqueue_ut.cpp
+++ b/ydb/services/persqueue_v1/persqueue_ut.cpp
@@ -1151,25 +1151,25 @@ namespace {
server.AnnoyingClient->GrantConsumerAccess("user1", "user2@" BUILTIN_ACL_DOMAIN);
server.AnnoyingClient->GrantConsumerAccess("user1", "user3@" BUILTIN_ACL_DOMAIN);
- server.AnnoyingClient->GrantConsumerAccess("user1", "1@" BUILTIN_ACL_DOMAIN);
- server.AnnoyingClient->GrantConsumerAccess("user2", "2@" BUILTIN_ACL_DOMAIN);
- server.AnnoyingClient->GrantConsumerAccess("user5", "1@" BUILTIN_ACL_DOMAIN);
- server.AnnoyingClient->GrantConsumerAccess("user5", "2@" BUILTIN_ACL_DOMAIN);
+ server.AnnoyingClient->GrantConsumerAccess("user1", "1@" BUILTIN_ACL_DOMAIN);
+ server.AnnoyingClient->GrantConsumerAccess("user2", "2@" BUILTIN_ACL_DOMAIN);
+ server.AnnoyingClient->GrantConsumerAccess("user5", "1@" BUILTIN_ACL_DOMAIN);
+ server.AnnoyingClient->GrantConsumerAccess("user5", "2@" BUILTIN_ACL_DOMAIN);
Cerr << "=== Create writer\n";
TPQDataWriter writer("source1", server);
server.CleverServer->GetRuntime()->GetAppData().PQConfig.SetRequireCredentialsInNewProtocol(true);
NACLib::TDiffACL acl;
- acl.AddAccess(NACLib::EAccessType::Allow, NACLib::SelectRow, "1@" BUILTIN_ACL_DOMAIN);
- acl.AddAccess(NACLib::EAccessType::Allow, NACLib::SelectRow, "2@" BUILTIN_ACL_DOMAIN);
+ acl.AddAccess(NACLib::EAccessType::Allow, NACLib::SelectRow, "1@" BUILTIN_ACL_DOMAIN);
+ acl.AddAccess(NACLib::EAccessType::Allow, NACLib::SelectRow, "2@" BUILTIN_ACL_DOMAIN);
acl.AddAccess(NACLib::EAccessType::Allow, NACLib::SelectRow, "user1@" BUILTIN_ACL_DOMAIN);
acl.AddAccess(NACLib::EAccessType::Allow, NACLib::SelectRow, "user2@" BUILTIN_ACL_DOMAIN);
server.AnnoyingClient->ModifyACL("/Root/PQ", topic2, acl.SerializeAsString());
WaitACLModification();
- auto ticket1 = "1@" BUILTIN_ACL_DOMAIN;
- auto ticket2 = "2@" BUILTIN_ACL_DOMAIN;
+ auto ticket1 = "1@" BUILTIN_ACL_DOMAIN;
+ auto ticket2 = "2@" BUILTIN_ACL_DOMAIN;
Cerr << "=== Writer - do reads\n";
writer.Read(shortTopic2Name, "user1", ticket1, false, false, true);
diff --git a/ydb/services/ydb/ydb_common_ut.h b/ydb/services/ydb/ydb_common_ut.h
index 46fa7919723..c067928c785 100644
--- a/ydb/services/ydb/ydb_common_ut.h
+++ b/ydb/services/ydb/ydb_common_ut.h
@@ -20,31 +20,31 @@ namespace NYdb {
using namespace Tests;
using namespace NYdb;
-struct TKikimrTestSettings {
- static constexpr bool SSL = false;
- static constexpr bool AUTH = false;
- static constexpr bool PrecreatePools = true;
+struct TKikimrTestSettings {
+ static constexpr bool SSL = false;
+ static constexpr bool AUTH = false;
+ static constexpr bool PrecreatePools = true;
static constexpr bool EnableSystemViews = true;
-};
-
-struct TKikimrTestWithAuth : TKikimrTestSettings {
- static constexpr bool AUTH = true;
-};
-
-struct TKikimrTestWithAuthAndSsl : TKikimrTestWithAuth {
- static constexpr bool SSL = true;
-};
-
+};
+
+struct TKikimrTestWithAuth : TKikimrTestSettings {
+ static constexpr bool AUTH = true;
+};
+
+struct TKikimrTestWithAuthAndSsl : TKikimrTestWithAuth {
+ static constexpr bool SSL = true;
+};
+
struct TKikimrTestNoSystemViews : TKikimrTestSettings {
static constexpr bool EnableSystemViews = false;
};
-template <typename TestSettings = TKikimrTestSettings>
-class TBasicKikimrWithGrpcAndRootSchema {
+template <typename TestSettings = TKikimrTestSettings>
+class TBasicKikimrWithGrpcAndRootSchema {
public:
- TBasicKikimrWithGrpcAndRootSchema(
- NKikimrConfig::TAppConfig appConfig = {},
- const TVector<NKikimrKqp::TKqpSetting>& kqpSettings = {},
+ TBasicKikimrWithGrpcAndRootSchema(
+ NKikimrConfig::TAppConfig appConfig = {},
+ const TVector<NKikimrKqp::TKqpSetting>& kqpSettings = {},
TAutoPtr<TLogBackend> logBackend = {},
bool enableYq = false,
TAppPrepare::TFnReg udfFrFactory = nullptr,
@@ -57,17 +57,17 @@ public:
ServerSettings->SetLogBackend(logBackend);
ServerSettings->SetDomainName("Root");
ServerSettings->SetDynamicNodeCount(2);
- if (TestSettings::PrecreatePools) {
- ServerSettings->AddStoragePool("ssd");
- ServerSettings->AddStoragePool("hdd");
- ServerSettings->AddStoragePool("hdd1");
- ServerSettings->AddStoragePool("hdd2");
- } else {
- ServerSettings->AddStoragePoolType("ssd");
- ServerSettings->AddStoragePoolType("hdd");
- ServerSettings->AddStoragePoolType("hdd1");
- ServerSettings->AddStoragePoolType("hdd2");
- }
+ if (TestSettings::PrecreatePools) {
+ ServerSettings->AddStoragePool("ssd");
+ ServerSettings->AddStoragePool("hdd");
+ ServerSettings->AddStoragePool("hdd1");
+ ServerSettings->AddStoragePool("hdd2");
+ } else {
+ ServerSettings->AddStoragePoolType("ssd");
+ ServerSettings->AddStoragePoolType("hdd");
+ ServerSettings->AddStoragePoolType("hdd1");
+ ServerSettings->AddStoragePoolType("hdd2");
+ }
ServerSettings->SetAppConfig(appConfig);
ServerSettings->AuthConfig = appConfig.GetAuthConfig();
ServerSettings->FeatureFlags = appConfig.GetFeatureFlags();
@@ -106,11 +106,11 @@ public:
}
NGrpc::TServerOptions grpcOption;
- if (TestSettings::AUTH) {
+ if (TestSettings::AUTH) {
grpcOption.SetUseAuth(true);
}
grpcOption.SetPort(grpc);
- if (TestSettings::SSL) {
+ if (TestSettings::SSL) {
NGrpc::TSslData sslData{NYdbSslTestData::ServerCrt,
NYdbSslTestData::ServerKey,
NYdbSslTestData::CaCrt};
@@ -125,7 +125,7 @@ public:
annoyingClient.InitRootScheme("Root");
GRpcPort_ = grpc;
}
-
+
ui16 GetPort() {
return GRpcPort_;
}
@@ -305,9 +305,9 @@ struct TTestOlap {
}
};
-using TKikimrWithGrpcAndRootSchema = TBasicKikimrWithGrpcAndRootSchema<TKikimrTestSettings>;
-using TKikimrWithGrpcAndRootSchemaWithAuth = TBasicKikimrWithGrpcAndRootSchema<TKikimrTestWithAuth>;
-using TKikimrWithGrpcAndRootSchemaWithAuthAndSsl = TBasicKikimrWithGrpcAndRootSchema<TKikimrTestWithAuthAndSsl>;
+using TKikimrWithGrpcAndRootSchema = TBasicKikimrWithGrpcAndRootSchema<TKikimrTestSettings>;
+using TKikimrWithGrpcAndRootSchemaWithAuth = TBasicKikimrWithGrpcAndRootSchema<TKikimrTestWithAuth>;
+using TKikimrWithGrpcAndRootSchemaWithAuthAndSsl = TBasicKikimrWithGrpcAndRootSchema<TKikimrTestWithAuthAndSsl>;
using TKikimrWithGrpcAndRootSchemaNoSystemViews = TBasicKikimrWithGrpcAndRootSchema<TKikimrTestNoSystemViews>;
-
+
}
diff --git a/ydb/services/ydb/ydb_coordination_ut.cpp b/ydb/services/ydb/ydb_coordination_ut.cpp
index 8b2f92daf6f..54c973a7e85 100644
--- a/ydb/services/ydb/ydb_coordination_ut.cpp
+++ b/ydb/services/ydb/ydb_coordination_ut.cpp
@@ -34,9 +34,9 @@ struct TClientContext {
NYdb::NCoordination::TClient Client;
NYdb::NScheme::TSchemeClient SchemeClient;
- template <typename Config>
+ template <typename Config>
TClientContext(
- TBasicKikimrWithGrpcAndRootSchema<Config>& server,
+ TBasicKikimrWithGrpcAndRootSchema<Config>& server,
const TString& token = { },
bool secure = false)
: Location(TStringBuilder() << "localhost:" << server.GetPort())
@@ -623,15 +623,15 @@ Y_UNIT_TEST_SUITE(TGRpcNewCoordinationClient) {
}
Y_UNIT_TEST_SUITE(TGRpcNewCoordinationClientAuth) {
- struct WithSslAndAuth : TKikimrTestSettings {
- static constexpr bool SSL = true;
- static constexpr bool AUTH = true;
- };
-
- using TKikimrWithGrpcAndRootSchema = NYdb::TBasicKikimrWithGrpcAndRootSchema<WithSslAndAuth>;
-
+ struct WithSslAndAuth : TKikimrTestSettings {
+ static constexpr bool SSL = true;
+ static constexpr bool AUTH = true;
+ };
+
+ using TKikimrWithGrpcAndRootSchema = NYdb::TBasicKikimrWithGrpcAndRootSchema<WithSslAndAuth>;
+
Y_UNIT_TEST(OwnersAndPermissions) {
- TKikimrWithGrpcAndRootSchema server;
+ TKikimrWithGrpcAndRootSchema server;
// Use root and allow users write permissions
{
diff --git a/ydb/services/ydb/ydb_table_ut.cpp b/ydb/services/ydb/ydb_table_ut.cpp
index 8f231567132..4861c06b92e 100644
--- a/ydb/services/ydb/ydb_table_ut.cpp
+++ b/ydb/services/ydb/ydb_table_ut.cpp
@@ -47,7 +47,7 @@ void EnsureTablePartitions(NYdb::NTable::TTableClient& client, TString table, ui
}
static void MultiTenantSDK(bool asyncDiscovery) {
- TKikimrWithGrpcAndRootSchemaWithAuthAndSsl server;
+ TKikimrWithGrpcAndRootSchemaWithAuthAndSsl server;
ui16 grpc = server.GetPort();
TString location = TStringBuilder() << "localhost:" << grpc;
@@ -901,7 +901,7 @@ Y_UNIT_TEST_SUITE(YdbYqlClient) {
}
Y_UNIT_TEST(SecurityTokenAuth) {
- TKikimrWithGrpcAndRootSchemaWithAuthAndSsl server;
+ TKikimrWithGrpcAndRootSchemaWithAuthAndSsl server;
ui16 grpc = server.GetPort();
TString location = TStringBuilder() << "localhost:" << grpc;
auto connection = NYdb::TDriver(
@@ -1211,7 +1211,7 @@ Y_UNIT_TEST_SUITE(YdbYqlClient) {
entry.SetComponent(NKikimrServices::EServiceKikimr_Name(NKikimrServices::KQP_YQL));
entry.SetLevel(NActors::NLog::PRI_DEBUG);
- TKikimrWithGrpcAndRootSchema server(appConfig, {}, logBackend);
+ TKikimrWithGrpcAndRootSchema server(appConfig, {}, logBackend);
server.Server_->GetRuntime()->SetLogPriority(NKikimrServices::GRPC_SERVER, NActors::NLog::PRI_DEBUG);
server.Server_->GetRuntime()->SetLogPriority(NKikimrServices::KQP_PROXY, NActors::NLog::PRI_DEBUG);
@@ -1274,7 +1274,7 @@ Y_UNIT_TEST_SUITE(YdbYqlClient) {
TAutoPtr<TLogBackend> logBackend(new TStreamLogBackend(&logStream));
{
- TKikimrWithGrpcAndRootSchema server({}, {}, logBackend);
+ TKikimrWithGrpcAndRootSchema server({}, {}, logBackend);
server.Server_->GetRuntime()->SetLogPriority(NKikimrServices::GRPC_SERVER, NActors::NLog::PRI_DEBUG);
diff --git a/ydb/services/ydb/ydb_ut.cpp b/ydb/services/ydb/ydb_ut.cpp
index fbb73e26cde..2d370630799 100644
--- a/ydb/services/ydb/ydb_ut.cpp
+++ b/ydb/services/ydb/ydb_ut.cpp
@@ -109,12 +109,12 @@ static Ydb::StatusIds::StatusCode WaitForStatus(std::shared_ptr<grpc::Channel> c
return response.operation().status();
}
-struct TKikimrTestSettings {
- static constexpr bool SSL = false;
- static constexpr bool AUTH = false;
- static constexpr bool PrecreatePools = true;
-};
-
+struct TKikimrTestSettings {
+ static constexpr bool SSL = false;
+ static constexpr bool AUTH = false;
+ static constexpr bool PrecreatePools = true;
+};
+
Y_UNIT_TEST_SUITE(TGRpcClientLowTest) {
Y_UNIT_TEST(SimpleRequest) {
TKikimrWithGrpcAndRootSchema server;
@@ -208,9 +208,9 @@ Y_UNIT_TEST_SUITE(TGRpcClientLowTest) {
return std::make_pair(status, gStatus);
};
- UNIT_ASSERT_VALUES_EQUAL(doTest("/Root"), std::make_pair(Ydb::StatusIds::SUCCESS, 0));
- UNIT_ASSERT_VALUES_EQUAL(doTest("/blabla"), std::make_pair(Ydb::StatusIds::STATUS_CODE_UNSPECIFIED, 16));
- UNIT_ASSERT_VALUES_EQUAL(doTest("blabla"), std::make_pair(Ydb::StatusIds::STATUS_CODE_UNSPECIFIED, 16));
+ UNIT_ASSERT_VALUES_EQUAL(doTest("/Root"), std::make_pair(Ydb::StatusIds::SUCCESS, 0));
+ UNIT_ASSERT_VALUES_EQUAL(doTest("/blabla"), std::make_pair(Ydb::StatusIds::STATUS_CODE_UNSPECIFIED, 16));
+ UNIT_ASSERT_VALUES_EQUAL(doTest("blabla"), std::make_pair(Ydb::StatusIds::STATUS_CODE_UNSPECIFIED, 16));
}
Y_UNIT_TEST(GrpcRequestProxyWithoutToken) {
@@ -257,7 +257,7 @@ Y_UNIT_TEST_SUITE(TGRpcClientLowTest) {
Y_UNIT_TEST(BiStreamPing) {
NKikimrConfig::TAppConfig appConfig;
appConfig.MutableDomainsConfig()->MutableSecurityConfig()->SetEnforceUserTokenRequirement(true);
- TKikimrWithGrpcAndRootSchemaWithAuth server(appConfig);
+ TKikimrWithGrpcAndRootSchemaWithAuth server(appConfig);
ui16 grpc = server.GetPort();
TString location = TStringBuilder() << "localhost:" << grpc;
@@ -535,7 +535,7 @@ Y_UNIT_TEST_SUITE(TGRpcNewClient) {
}
Y_UNIT_TEST(TestAuth) {
- TKikimrWithGrpcAndRootSchemaWithAuthAndSsl server;
+ TKikimrWithGrpcAndRootSchemaWithAuthAndSsl server;
ui16 grpc = server.GetPort();
TString location = TStringBuilder() << "localhost:" << grpc;
@@ -3152,7 +3152,7 @@ tx_meta {
setting.SetValue("2");
settings.push_back(setting);
- TKikimrWithGrpcAndRootSchema server(NKikimrConfig::TAppConfig(), settings);
+ TKikimrWithGrpcAndRootSchema server(NKikimrConfig::TAppConfig(), settings);
ui16 grpc = server.GetPort();
std::shared_ptr<grpc::Channel> channel;
diff --git a/ydb/tests/library/harness/kikimr_runner.py b/ydb/tests/library/harness/kikimr_runner.py
index 75716879172..251f485b5db 100644
--- a/ydb/tests/library/harness/kikimr_runner.py
+++ b/ydb/tests/library/harness/kikimr_runner.py
@@ -247,7 +247,7 @@ class KiKiMR(kikimr_cluster_interface.KiKiMRClusterInterface):
server = 'grpc://{server}:{port}'.format(server=self.server, port=self.nodes[1].port)
full_command = [self.__configurator.binary_path]
if connect_to_server:
- full_command += ["--server={server}".format(server=server)]
+ full_command += ["--server={server}".format(server=server)]
full_command += cmd
logger.debug("Executing command = {}".format(full_command))
@@ -495,7 +495,7 @@ class KiKiMR(kikimr_cluster_interface.KiKiMRClusterInterface):
cmd.DefineStoragePool.Kind = kind
cmd.DefineStoragePool.ErasureSpecies = str(erasure)
cmd.DefineStoragePool.VDiskKind = "Default"
- cmd.DefineStoragePool.NumGroups = 2
+ cmd.DefineStoragePool.NumGroups = 2
pdisk_filter = cmd.DefineStoragePool.PDiskFilter.add()
pdisk_filter.Property.add().Type = 0